diff -Nru openjdk-17-17.0.7+7~us1/bin/jib.sh openjdk-17-17.0.8+7/bin/jib.sh --- openjdk-17-17.0.7+7~us1/bin/jib.sh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/bin/jib.sh 2023-07-05 07:11:54.000000000 +0000 @@ -128,6 +128,15 @@ exit 1 fi fi + # Want to check the filetype using file, to see if we got served a HTML error page. + # This is sensitive to the filename containing a specific string, but good enough. + file "${installed_jib_script}.gz" | grep "gzip compressed data" > /dev/null + if [ $? -ne 0 ]; then + echo "Warning: ${installed_jib_script}.gz is not a gzip file." + echo "If you are behind a proxy you may need to configure exceptions using no_proxy." + echo "The download URL was: ${jib_url}" + exit 1 + fi echo "Extracting JIB bootstrap script" rm -f "${installed_jib_script}" gunzip "${installed_jib_script}.gz" diff -Nru openjdk-17-17.0.7+7~us1/debian/changelog openjdk-17-17.0.8+7/debian/changelog --- openjdk-17-17.0.7+7~us1/debian/changelog 2023-05-06 10:03:41.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/changelog 2023-07-20 09:09:31.000000000 +0000 @@ -1,72 +1,131 @@ -openjdk-17 (17.0.7+7~us1-0ubuntu1~23.04) lunar-security; urgency=medium +openjdk-17 (17.0.8+7-1~23.04) lunar-security; urgency=high * Upload to Ubuntu 23.04. + * d/t/jtreg-autopkgtest.{sh,in}: JDK-8232153 - set NSS_DEFAULT_DB_TYPE + to let sun/security/pkcs11/Secmod/AddTrustedCert.java pass. + * d/p/exclude-broken-tests.patch: disable pkcs11 tests failing with + NSS 3.91. + * d/t/problems-armhf.txt: disable armf tests - + java/util/Random/RandomTestBsi1999.java (deadlock in CI), + java/net/httpclient/ManyRequestsLegacy.java (SSL request timeout). + * Enable jtreg tests for bionic and focal. + + -- Vladimir Petko Thu, 20 Jul 2023 21:09:31 +1200 + +openjdk-17 (17.0.8+7-1) unstable; urgency=high + + * OpenJDK 17.0.8 release, build 7. + - CVE-2023-22006, CVE-2023-22036, CVE-2023-22041, CVE-2023-22044, + CVE-2023-22045, CVE-2023-22049, CVE-2023-25193. + - Release notes: + https://www.oracle.com/java/technologies/javase/17-0-8-relnotes.html#R17_0_8 + + * Don't run the tests on powerpc, hangs on the buildd. + * Refresh patches. + + -- Matthias Klose Wed, 19 Jul 2023 08:29:02 +0200 + +openjdk-17 (17.0.8~6-5) unstable; urgency=medium + + * Revert back to the riscv64 hotspot patch to v7. + + -- Matthias Klose Wed, 12 Jul 2023 14:33:08 +0200 + +openjdk-17 (17.0.8~6-4) unstable; urgency=medium + + [ Matthias Klose ] + * Update the riscv64 hotspot patch to v9. + * Run the hotspot tests on riscv64. + * Link with --no-as-needed. Closes: #1031521. + * d/rules: Remove EXTRA_.*FLAGS_JDK macros. + * Fix FTCBFS: Add libffi-dev:native to B-D (Helmut Grohne). + + [ Vladimir Petko ] + * Disable runtime/jni/nativeStack/TestNativeStack.java for armhf pending + upstream fix. + + -- Matthias Klose Mon, 10 Jul 2023 16:41:54 +0200 + +openjdk-17 (17.0.8~6-3) unstable; urgency=medium + + [ Vladimir Petko ] + * Use libtestng7-java as jtreg6 dependency as TestNG 7.x is required + at runtime. + * Regenerate the control file. + + -- Matthias Klose Sat, 01 Jul 2023 09:19:52 +0200 + +openjdk-17 (17.0.8~6-2) unstable; urgency=medium + + * Provide versioned java-runtime, java-runtime-headless, java-sdk + and java-sdk-headless virtual packages (Emmanuel Bourg). Closes: #1023869. + * Install jhsb binary and man page on riscv64. + * Bump standards version. + + -- Matthias Klose Thu, 29 Jun 2023 07:23:06 +0200 + +openjdk-17 (17.0.8~6-1) experimental; urgency=medium + + * OpenJDK 17.0.8 early access, build 6. + * Bump debhelper version to 11. + + -- Matthias Klose Tue, 27 Jun 2023 12:05:37 +0200 + +openjdk-17 (17.0.7+7-2) unstable; urgency=medium + + [ Vladimir Petko ] + * d/rules: backport testng selection logic. + + [ Matthias Klose ] + * Apply the backport patch for 8276799 (RISC-V Hotspot). + * Build both JREs (hotspot and zero) on riscv64. - -- Vladimir Petko Sat, 06 May 2023 12:03:41 +0200 + -- Matthias Klose Mon, 26 Jun 2023 15:58:27 +0200 -openjdk-17 (17.0.7+7~us1-0ubuntu1) mantic; urgency=medium +openjdk-17 (17.0.7+7-1) unstable; urgency=high * OpenJDK 17.0.7 release, build 7. - CVE-2023-21930, CVE-2023-21937, CVE-2023-21938, CVE-2023-21939, CVE-2023-21954, CVE-2023-21967, CVE-2023-21968. - Release notes: https://mail.openjdk.org/pipermail/jdk-updates-dev/2023-April/021899.html - * d/rules: update jquery to 3.6.1. - * d/p/*: refresh patches. - * d/rules: pack external debug symbols with build-id, do not pack duplicate - symbols, do not strip JVM shared libraries (LP: #2012326, LP: #2016739). - * d/p/system-pcsclite.diff: disable built-in pcsclite version assertion. - * d/rules: always use jtreg6. - * d/rules: only compile google tests when with_check is enabled, disable them - for bullseye and jammy. - - -- Vladimir Petko Thu, 20 Apr 2023 08:28:30 +1200 - -openjdk-17 (17.0.6+10-1ubuntu3) lunar; urgency=medium + [ Vladimir Petko ] + * Refresh patches. + * debian/copyright: Convert to machine readable format. + * Update watch file. + * Update tag and version handling in the rules file. + * debian/JB-jre-headless.postinst.in: trigger ca-certificates-java after + the JRE is set up. * d/control: add jtreg6 dependencies, regenerate control. - * d/t/{jdk,hotspot,jaxp,lantools}: run tier1 and tier2 jtreg tests only, - add test options from OpenJDK makefile. - * d/t/*: fix test environment: add missing -nativepath (LP: #2001563). - * d/t/jdk: provide dbus session for the window manager (LP: #2001576). - * d/p/build_gtest.patch: build OpenJDK with the system googletest - (LP: #2012316). + * d/rules: only compile google tests when with_check is enabled, disable them + for bullseye and jammy. + * d/rules: always use jtreg6. + * d/p/exclude-broken-tests.patch: add OpenJDK 17 failures. * d/p/*: add patches for jtreg tests: - disable-thumb-assertion.patch: fix JDK-8305481. - update-assertion-for-armhf.patch: fix JDK-8305480. - misalign-pointer-for-armhf.patch: packaging-specific patch to fix test - failure introduced by d/p/m68k-support.diff. + - failure introduced by d/p/m68k-support.diff. - log-generated-classes-test.patch: workaround JDK-8166162. - update-permission-test.patch: add security permissions for testng 7. - ldap-timeout-test-use-ip.patch, test-use-ip-address.patch: Ubuntu-specific - patches to workaround missing DNS resolver on the build machines. + - patches to workaround missing DNS resolver on the build machines. - exclude_broken_tests.patch: quarantine failing tests. - * d/rules: package external debug symbols (LP: #2015835). - * drop d/p/{jaw-classpath.diff, jaw-optional.diff}: the atk wrapper is disabled - and these patches cause class data sharing tests to fail (LP: #2016194). - * d/p/exclude-broken-tests.patch: add OpenJDK 17 failures. + * d/t/{jdk,hotspot,jaxp,lantools}: run tier1 and tier2 jtreg tests only, + * add test options from OpenJDK Makefile, patch problem list to exclude + architecture-specific failing tests. + * d/t/*: fix test environment: add missing -nativepath (LP: #2001563). + * d/t/jdk: provide dbus session for the window manager (LP: #2001576). * d/t/jtreg-autopkgtest.in: pass JTREG home to locate junit.jar, regenerate - d/t/jtreg-autopkgtest.sh (LP: #2016206). - - -- Vladimir Petko Mon, 27 Mar 2023 11:41:46 +1300 - -openjdk-17 (17.0.6+10-1ubuntu2) lunar; urgency=medium - - * d/p: drop obsolete patches (LP: #2011653). - - workaround_expand_exec_shield_cs_limit.diff: obsoleted by - hotspot-disable-exec-shield-workaround.diff. - - generated-headers.patch: include is already added by openjdk makefile. - * d/copyright, d/watch: implement uscan repackaging (LP: #2011749). - * d/rules: use --with-debug-symbols=none (LP: #2003820). - - -- Vladimir Petko Thu, 16 Mar 2023 15:04:36 +1300 - -openjdk-17 (17.0.6+10-1ubuntu1) lunar; urgency=medium - - * debian/JB-jre-headless.postinst.in: trigger ca-certificates-java after jre - is set up. + * d/t/jtreg-autopkgtest.sh (LP: #2016206). + * d/rules: pack external debug symbols with build-id, do not strip JVM shared + libraries (LP: #2012326, LP: #2016739). + * drop d/p/{jaw-classpath.diff, jaw-optional.diff}: the atk wrapper is + disabled and these patches cause class data sharing tests to fail. + LP: #2016194. - -- Vladimir Petko Wed, 01 Mar 2023 15:11:45 +1300 + -- Matthias Klose Tue, 06 Jun 2023 13:36:52 +0200 openjdk-17 (17.0.6+10-1) unstable; urgency=high diff -Nru openjdk-17-17.0.7+7~us1/debian/compat openjdk-17-17.0.8+7/debian/compat --- openjdk-17-17.0.7+7~us1/debian/compat 2023-03-16 22:04:55.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/compat 2023-06-27 10:43:51.000000000 +0000 @@ -1 +1 @@ -9 +11 diff -Nru openjdk-17-17.0.7+7~us1/debian/control openjdk-17-17.0.8+7/debian/control --- openjdk-17-17.0.7+7~us1/debian/control 2023-05-06 10:03:41.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/control 2023-07-20 09:09:31.000000000 +0000 @@ -1,25 +1,24 @@ Source: openjdk-17 Section: java Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: OpenJDK Team +Maintainer: OpenJDK Team Uploaders: Matthias Klose Build-Depends: debhelper (>= 11), m4, lsb-release, zip, unzip, sharutils, gawk, cpio, pkg-config, procps, wdiff, fastjar (>= 2:0.96-0ubuntu2), time, strip-nondeterminism, debugedit (>= 4.16), - jtreg6 (>= 6+1-0~) , libtestng7-java , xvfb , xauth , xfonts-base , libgl1-mesa-dri [!x32] , xfwm4 , x11-xkb-utils , dbus-x11 , libasmtools-java , googletest , google-mock , xvfb , + jtreg6 (>= 6+1-0~) , libtestng7-java , xvfb , xauth , xfonts-base , libgl1-mesa-dri [!x32] , xfwm4 , x11-xkb-utils , dbus-x11 , googletest , google-mock , xvfb , libasmtools-java , autoconf, automake, autotools-dev, ant, ant-optional, g++-12 , openjdk-17-jdk-headless:native | openjdk-16-jdk-headless:native, libxtst-dev, libxi-dev, libxt-dev, libxaw7-dev, libxrender-dev, libcups2-dev, libasound2-dev, liblcms2-dev, libfreetype6-dev (>= 2.2.1), libxinerama-dev, libkrb5-dev, xsltproc, libpcsclite-dev, libxrandr-dev, libelf-dev, libfontconfig1-dev, libgtk2.0-0 | libgtk-3-0, libharfbuzz-dev, - libffi-dev, + libffi-dev, libffi-dev:native, zlib1g-dev:native, zlib1g-dev, libattr1-dev, libpng-dev, libjpeg-dev, libgif-dev, libnss3-dev (>= 2:3.17.1), openjdk-17-jdk-headless , Build-Depends-Indep: graphviz, pandoc, Rules-Requires-Root: no -Standards-Version: 4.5.1 +Standards-Version: 4.6.2 Homepage: https://openjdk.java.net/ Vcs-Browser: https://salsa.debian.org/openjdk-team/openjdk/tree/openjdk-17 Vcs-Git: https://salsa.debian.org/openjdk-team/openjdk.git -b openjdk-17 @@ -31,7 +30,7 @@ Depends: openjdk-17-jre-headless (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Suggests: openjdk-17-demo, openjdk-17-source -Provides: java-sdk-headless, java2-sdk-headless, +Provides: java-sdk-headless (= ${vm:Version}), java2-sdk-headless, java5-sdk-headless, java6-sdk-headless, java7-sdk-headless, java8-sdk-headless, java9-sdk-headless, java10-sdk-headless, @@ -57,7 +56,7 @@ Suggests: libnss-mdns, fonts-dejavu-extra, fonts-ipafont-gothic, fonts-ipafont-mincho, fonts-wqy-microhei | fonts-wqy-zenhei, fonts-indic, -Provides: java-runtime-headless, java2-runtime-headless, +Provides: java-runtime-headless (= ${vm:Version}), java2-runtime-headless, java5-runtime-headless, java6-runtime-headless, java7-runtime-headless, java8-runtime-headless, java9-runtime-headless, java10-runtime-headless, @@ -81,7 +80,7 @@ ${shlibs:Depends}, ${misc:Depends} Recommends: libxt-dev Suggests: openjdk-17-demo, openjdk-17-source, visualvm -Provides: java-sdk, java2-sdk, java5-sdk, java6-sdk, +Provides: java-sdk (= ${vm:Version}), java2-sdk, java5-sdk, java6-sdk, java7-sdk, java8-sdk, java9-sdk, java10-sdk, java11-sdk, java12-sdk, java13-sdk, java14-sdk, java15-sdk, java16-sdk, java17-sdk, java-compiler @@ -97,7 +96,7 @@ ${xandsound:Depends}, ${dlopenjre:Depends}, ${shlibs:Depends}, ${misc:Depends} Recommends: ${dlopenjre:Recommends}, ${bridge:Recommends}, fonts-dejavu-extra -Provides: java-runtime, java2-runtime, +Provides: java-runtime (= ${vm:Version}), java2-runtime, java5-runtime, java6-runtime, java7-runtime, java8-runtime, java9-runtime, java10-runtime, @@ -168,7 +167,7 @@ This package contains the debugging symbols. Package: openjdk-17-jre-zero -Architecture: amd64 i386 arm64 armhf ppc64 ppc64el s390x +Architecture: amd64 i386 arm64 armhf ppc64 ppc64el riscv64 s390x Multi-Arch: same Priority: optional Pre-Depends: ${dpkg:Depends} diff -Nru openjdk-17-17.0.7+7~us1/debian/control.in openjdk-17-17.0.8+7/debian/control.in --- openjdk-17-17.0.7+7~us1/debian/control.in 2023-05-06 10:03:41.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/control.in 2023-06-28 07:29:30.000000000 +0000 @@ -1,8 +1,7 @@ Source: @basename@ Section: java Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: OpenJDK Team +Maintainer: OpenJDK Team Uploaders: Matthias Klose Build-Depends: @bd_debhelper@ m4, lsb-release, zip, unzip, @@ -19,7 +18,7 @@ @bd_cross@ Build-Depends-Indep: graphviz, pandoc, Rules-Requires-Root: no -Standards-Version: 4.5.1 +Standards-Version: 4.6.2 Homepage: https://openjdk.java.net/ Vcs-Browser: https://salsa.debian.org/openjdk-team/openjdk/tree/openjdk-17 Vcs-Git: https://salsa.debian.org/openjdk-team/openjdk.git -b openjdk-17 @@ -31,7 +30,7 @@ Depends: @basename@-jre-headless (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Suggests: @basename@-demo, @basename@-source -Provides: java-sdk-headless, java2-sdk-headless, +Provides: java-sdk-headless (= ${vm:Version}), java2-sdk-headless, java5-sdk-headless, java6-sdk-headless, java7-sdk-headless, java8-sdk-headless, java9-sdk-headless, java10-sdk-headless, @@ -57,7 +56,7 @@ Suggests: libnss-mdns, @core_fonts@, @cjk_fonts@ -Provides: java-runtime-headless, java2-runtime-headless, +Provides: java-runtime-headless (= ${vm:Version}), java2-runtime-headless, java5-runtime-headless, java6-runtime-headless, java7-runtime-headless, java8-runtime-headless, java9-runtime-headless, java10-runtime-headless, @@ -81,7 +80,7 @@ ${shlibs:Depends}, ${misc:Depends} Recommends: libxt-dev Suggests: @basename@-demo, @basename@-source, visualvm -Provides: java-sdk, java2-sdk, java5-sdk, java6-sdk, +Provides: java-sdk (= ${vm:Version}), java2-sdk, java5-sdk, java6-sdk, java7-sdk, java8-sdk, java9-sdk, java10-sdk, java11-sdk, java12-sdk, java13-sdk, java14-sdk, java15-sdk, java16-sdk, java17-sdk, java-compiler @@ -97,7 +96,7 @@ ${xandsound:Depends}, ${dlopenjre:Depends}, ${shlibs:Depends}, ${misc:Depends} Recommends: ${dlopenjre:Recommends}, ${bridge:Recommends}, @core_fonts@ -Provides: java-runtime, java2-runtime, +Provides: java-runtime (= ${vm:Version}), java2-runtime, java5-runtime, java6-runtime, java7-runtime, java8-runtime, java9-runtime, java10-runtime, diff -Nru openjdk-17-17.0.7+7~us1/debian/copyright openjdk-17-17.0.8+7/debian/copyright --- openjdk-17-17.0.7+7~us1/debian/copyright 2023-03-26 22:36:50.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/copyright 2023-06-09 08:41:16.000000000 +0000 @@ -4,6 +4,7 @@ .gitattributes src/java.desktop/share/native/liblcms/cms*.c src/java.desktop/share/native/liblcms/lcms2*.h + src/java.desktop/share/native/liblcms/*.txt src/java.base/share/native/libzip/zlib/* src/java.desktop/share/native/libsplashscreen/giflib/* src/java.desktop/share/native/libsplashscreen/libpng/* @@ -20,55 +21,1303 @@ src/java.desktop/share/native/libjavajpeg/jv* src/java.desktop/share/native/libjavajpeg/ju* src/java.desktop/share/native/libjavajpeg/README -Comment: Exclude bundled library sources, Github Actions and git attributes. - -This package was debianized by Matthias Klose on -Wed, 08 Aug 2007 15:55:39 +0200. - -It was downloaded from - https://github.com/openjdk/jdk17u - ------------------------------------------------------------------------------- -Upstream Authors: - -OpenJDK: - Sun Microsystems, Inc. - Oracle and/or its affiliates. - -Packaging: - Matthias Klose - ------------------------------------------------------------------------------- -Copyright: - -OpenJDK: - Copyright © 1996-2007 Sun Microsystems, Inc. - Copyright © 1996-2023 Oracle and/or its affiliates. - For third party copyrights see below (copies from the third party readme). - Portions Copyright © 1993-2014 IBM Corp. - Portions Copyright © 1997 Eastman Kodak Company. - Portions Copyright © 1999-2005 The Apache Software Foundation. - -Java Access Bridge: - Portions Copyright © 2002-2007 Bill Haneman - Portions Copyright © 2002-2007 Louise Miller - Portions Copyright © 2002-2007 Gergõ Érdi - Portions Copyright © 2002-2007 Laszlo (Laca) Peter - Portions Copyright © 2002-2007 Jeff Cai - Portions Copyright © 2002-2007 George Kraft IV - Portions Copyright © 2002-2007 Padraig O'Briain - Portions Copyright © 2002-2007 Darren Kenny - -Packaging: - Copyright © 2007-2023 Canonical Ltd. - ------------------------------------------------------------------------------- -License: - -NOTE: the combined work which includes the upstream components below -carries forward the OpenJDK Assembly Exception (text included below). - -Packaging: +Source: https://github.com/openjdk/jdk17u +Comment: + ------------------------------------------------------------------------------ + This package was debianized by Matthias Klose on + Wed, 08 Aug 2007 15:55:39 +0200. + ------------------------------------------------------------------------------ + Upstream Authors: + OpenJDK: + Sun Microsystems, Inc. + Oracle and/or its affiliates. + Packaging: + Matthias Klose + ------------------------------------------------------------------------------ + +Files: * +Copyright: + OpenJDK: + Copyright © 1996-2007 Sun Microsystems, Inc. + Copyright © 1996-2023 Oracle and/or its affiliates. + For third party copyrights see below (copies from the third party readme). + Portions Copyright © 1993-2014 IBM Corp. + Portions Copyright © 1997 Eastman Kodak Company. + Portions Copyright © 1999-2005 The Apache Software Foundation. + Java Access Bridge: + Portions Copyright © 2002-2007 Bill Haneman + Portions Copyright © 2002-2007 Louise Miller + Portions Copyright © 2002-2007 Gergõ Érdi + Portions Copyright © 2002-2007 Laszlo (Laca) Peter + Portions Copyright © 2002-2007 Jeff Cai + Portions Copyright © 2002-2007 George Kraft IV + Portions Copyright © 2002-2007 Padraig O'Briain + Portions Copyright © 2002-2007 Darren Kenny + ------------------------------------------------------------------------------ +License: GPL with the Classpath exception + NOTE: the combined work which includes the upstream components below + carries forward the OpenJDK Assembly Exception (text included below). + . + OpenJDK: + OpenJDK is licensed under the GPL v2 with exceptions, + see `/usr/share/common-licenses/GPL-2'. + The exceptions are: + - "CLASSPATH" EXCEPTION TO THE GPL + - OPENJDK ASSEMBLY EXCEPTION + Various third party code in OpenJDK is licensed under different licenses. + . + Java Access Bridge: + Java Access Bridge is licensed under the LGPL v2. + See `/usr/share/common-licenses/LGPL-2'. + . + A Note About License Headers + ---------------------------- + . + Some sources downloaded from openjdk.java.net do not display the GPL + license header. Instances are: + . + - The files in openjdk/j2se/src/share/classes/javax/xml/stream/ seem to + comprise the BEA-StAX source code + . + http://ftpna2.bea.com/pub/downloads/jsr173.jar + . + with some Sun-specific modifications. We're assuming that Sun is + bundling BEA-StAX under the terms of the Apache License 2.0 and + that the modifications are owned by Sun. + . + - We are assuming that these files are owned by Sun: + openjdk/j2se/src/share/classes/**/resources/*.properties + . + The downloaded sources include a script that inserts proprietary + license headers into the source files it generates. The script + itself is GPL'd so we patched them to emit the GPL header. The + file is: + openjdk/j2se/make/java/nio/genExceptions.sh + . + ------------------------------------------------------------------------------ + "CLASSPATH" EXCEPTION TO THE GPL + . + Certain source files distributed by Sun Microsystems, Inc. are subject to + the following clarification and special exception to the GPL, but only where + Sun has expressly included in the particular source file's header the words + "Sun designates this particular file as subject to the "Classpath" exception + as provided by Sun in the LICENSE file that accompanied this code." + . + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + . + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. + . + ------------------------------------------------------------------------------ + OPENJDK ASSEMBLY EXCEPTION + . + The OpenJDK source code made available by Sun at openjdk.java.net and + openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the + GNU General Public License version 2 + only ("GPL2"), with the following clarification and special exception. + . + Linking this OpenJDK Code statically or dynamically with other code + is making a combined work based on this library. Thus, the terms + and conditions of GPL2 cover the whole combination. + . + As a special exception, Sun gives you permission to link this + OpenJDK Code with certain code licensed by Sun as indicated at + http://openjdk.java.net/legal/exception-modules-2007-05-08.html + ("Designated Exception Modules") to produce an executable, + regardless of the license terms of the Designated Exception Modules, + and to copy and distribute the resulting executable under GPL2, + provided that the Designated Exception Modules continue to be + governed by the licenses under which they were offered by Sun. + . + As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to + build an executable that includes those portions of necessary code that Sun + could not provide under GPL2 (or that Sun has provided under GPL2 with the + Classpath exception). If you modify or add to the OpenJDK code, that new + GPL2 code may still be combined with Designated Exception Modules if the + new code is made subject to this exception by its copyright holder. + . + ------------------------------------------------------------------------------ + OpenJDK Trademark Notice + Version 1.1, 2008/3/10 + . + OpenJDK (the "Name") is a trademark of Sun Microsystems, Inc. (the "Owner"). + Owner permits any person obtaining a copy of this software (the "Software") + which is based on original software retrieved from one of the following + websites: http://download.java.net/openjdk, http://hg.openjdk.java.net/jdk6, + or http://openjdk.java.net (each a "Website", with the original software made + available by the Owner on a Website being known as the "Website Software") to + use the Name in package names and version strings of the Software subject to + the following conditions: + . + - The Software is a substantially complete implementation of the OpenJDK + development kit or runtime environment code made available by Owner on a + Website, and the vast majority of the Software code is identical to the + upstream Website Software; + . + - No permission is hereby granted to use the Name in any other manner, + unless such use constitutes "fair use." + . + - The Owner makes no warranties of any kind respecting the Name and all + representations and warranties, including any implied warranty of + merchantability, fitness for a particular purpose or non-infringement + are hereby disclaimed; and + . + - This notice and the following legend are included in all copies of the + Software or portions of it: + . + OpenJDK is a trademark or registered trademark of Sun Microsystems, + Inc. in the United States and other countries. + . + The Name may also be used in connection with descriptions of the Software that + constitute "fair use," such as "derived from the OpenJDK code base" or "based + on the OpenJDK source code." + . + Owner intends to revise this Notice as necessary in order to meet the needs of + the OpenJDK Community. Please send questions or comments about this Notice to + Sun Microsystems at openjdk-tm@sun.com. Revisions to this Notice will be + announced on the public mailing list announce@openjdk.java.net, to which you + may subscribe by visiting http://mail.openjdk.java.net. The latest version of + this Notice may be found at http://openjdk.java.net/legal. + . + ------------------------------------------------------------------------------ + . + The contents of the jdk/src/share/native/sun/security/ec/impl/ directory are + licensed under the LGPL-2.1. See `/usr/share/common-licenses/LGPL-2-1'. + . + ------------------------------------------------------------------------------ + The following licenses for third party code are taken from + openjdk/THIRD_PARTY_README + ------------------------------------------------------------------------------ + . + DO NOT TRANSLATE OR LOCALIZE. + ----------------------------- + . + %% This notice is provided with respect to ASM Bytecode Manipulation + Framework v5.0, which may be included with JRE 8, and JDK 8, and + OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright (c) 2000-2011 France Télécom + 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. Neither the name of the copyright holders 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. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to BSDiff v4.3, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright 2003-2005 Colin Percival + All rights reserved + . + Redistribution and use in source and binary forms, with or without + modification, are permitted providing that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to CodeViewer 1.0, which may be + included with JDK 8. + . + --- begin of LICENSE --- + . + Copyright 1999 by CoolServlets.com. + . + Any errors or suggested improvements to this class can be reported as + instructed on CoolServlets.com. We hope you enjoy this program... your + comments will encourage further development! This software is distributed + under the terms of the BSD License. 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. + . + Neither name of CoolServlets.com 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 COOLSERVLETS.COM 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 AUTHOR 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 Cryptix AES 3.2.0, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of 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 CUP Parser Generator for + Java 0.10k, which may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian + . + 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. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Document Object Model (DOM) Level 2 + & 3, which may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of 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. + . + 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. + . + 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. + . + ____________________________________ + . + 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. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------- + . + %% This notice is provided with respect to Dynalink v0.5, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright (c) 2009-2013, Attila Szegedi + . + 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 Attila + Szegedi 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 HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------- + . + %% This notice is provided with respect to Elliptic Curve Cryptography, which + may be included with JRE 8, JDK 8, and OpenJDK 8. + . + You are receiving a copy of the Elliptic Curve Cryptography library in source + form with the JDK 8 and OpenJDK 8 source distributions, and as object code in + the JRE 8 & JDK 8 runtimes. + . + In the case of the JRE 8 & JDK 8 runtimes, the terms of the Oracle license do + NOT apply to the Elliptic Curve Cryptography library; it is licensed under the + following license, separately from Oracle's JDK & JRE. If you do not wish to + install the Elliptic Curve Cryptography library, you may delete the library + named libsunec.so (on Solaris and Linux systems) or sunec.dll (on Windows + systems) from the JRE bin directory reserved for native libraries. + . + . + --- begin of LICENSE --- + . + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + . + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + . + [This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + . + Preamble + . + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General Public + Licenses are intended to guarantee your freedom to share and change + free software--to make sure the software is free for all its users. + . + This license, the Lesser General Public License, applies to some + specially designated software packages--typically libraries--of the + Free Software Foundation and other authors who decide to use it. You + can use it too, but we suggest you first think carefully about whether + this license or the ordinary General Public License is the better + strategy to use in any particular case, based on the explanations below. + . + When we speak of free software, we are referring to freedom of use, + not price. Our General Public Licenses are designed to make sure that + you have the freedom to distribute copies of free software (and charge + for this service if you wish); that you receive source code or can get + it if you want it; that you can change the software and use pieces of + it in new free programs; and that you are informed that you can do + these things. + . + To protect your rights, we need to make restrictions that forbid + distributors to deny you these rights or to ask you to surrender these + rights. These restrictions translate to certain responsibilities for + you if you distribute copies of the library or if you modify it. + . + For example, if you distribute copies of the library, whether gratis + or for a fee, you must give the recipients all the rights that we gave + you. You must make sure that they, too, receive or can get the source + code. If you link other code with the library, you must provide + complete object files to the recipients, so that they can relink them + with the library after making changes to the library and recompiling + it. And you must show them these terms so they know their rights. + . + We protect your rights with a two-step method: (1) we copyright the + library, and (2) we offer you this license, which gives you legal + permission to copy, distribute and/or modify the library. + . + To protect each distributor, we want to make it very clear that + there is no warranty for the free library. Also, if the library is + modified by someone else and passed on, the recipients should know + that what they have is not the original version, so that the original + author's reputation will not be affected by problems that might be + introduced by others. + . + Finally, software patents pose a constant threat to the existence of + any free program. We wish to make sure that a company cannot + effectively restrict the users of a free program by obtaining a + restrictive license from a patent holder. Therefore, we insist that + any patent license obtained for a version of the library must be + consistent with the full freedom of use specified in this license. + . + Most GNU software, including some libraries, is covered by the + ordinary GNU General Public License. This license, the GNU Lesser + General Public License, applies to certain designated libraries, and + is quite different from the ordinary General Public License. We use + this license for certain libraries in order to permit linking those + libraries into non-free programs. + . + When a program is linked with a library, whether statically or using + a shared library, the combination of the two is legally speaking a + combined work, a derivative of the original library. The ordinary + General Public License therefore permits such linking only if the + entire combination fits its criteria of freedom. The Lesser General + Public License permits more lax criteria for linking other code with + the library. + . + We call this license the "Lesser" General Public License because it + does Less to protect the user's freedom than the ordinary General + Public License. It also provides other free software developers Less + of an advantage over competing non-free programs. These disadvantages + are the reason we use the ordinary General Public License for many + libraries. However, the Lesser license provides advantages in certain + special circumstances. + . + For example, on rare occasions, there may be a special need to + encourage the widest possible use of a certain library, so that it becomes + a de-facto standard. To achieve this, non-free programs must be + allowed to use the library. A more frequent case is that a free + library does the same job as widely used non-free libraries. In this + case, there is little to gain by limiting the free library to free + software only, so we use the Lesser General Public License. + . + In other cases, permission to use a particular library in non-free + programs enables a greater number of people to use a large body of + free software. For example, permission to use the GNU C Library in + non-free programs enables many more people to use the whole GNU + operating system, as well as its variant, the GNU/Linux operating + system. + . + Although the Lesser General Public License is Less protective of the + users' freedom, it does ensure that the user of a program that is + linked with the Library has the freedom and the wherewithal to run + that program using a modified version of the Library. + . + The precise terms and conditions for copying, distribution and + modification follow. Pay close attention to the difference between a + "work based on the library" and a "work that uses the library". The + former contains code derived from the library, whereas the latter must + be combined with the library in order to run. + . + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + . + 0. This License Agreement applies to any software library or other + program which contains a notice placed by the copyright holder or + other authorized party saying it may be distributed under the terms of + this Lesser General Public License (also called "this License"). + Each licensee is addressed as "you". + . + A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables. + . + The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or translated + straightforwardly into another language. (Hereinafter, translation is + included without limitation in the term "modification".) + . + "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code means + all the source code for all modules it contains, plus any associated + interface definition files, plus the scripts used to control compilation + and installation of the library. + . + Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of + running a program using the Library is not restricted, and output from + such a program is covered only if its contents constitute a work based + on the Library (independent of the use of the Library in a tool for + writing it). Whether that is true depends on what the Library does + and what the program that uses the Library does. + . + 1. You may copy and distribute verbatim copies of the Library's + complete source code as you receive it, in any medium, provided that + you conspicuously and appropriately publish on each copy an + appropriate copyright notice and disclaimer of warranty; keep intact + all the notices that refer to this License and to the absence of any + warranty; and distribute a copy of this License along with the + Library. + . + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange for a + fee. + . + 2. You may modify your copy or copies of the Library or any portion + of it, thus forming a work based on the Library, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + . + a) The modified work must itself be a software library. + . + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + . + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + . + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + . + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + . + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Library, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Library, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it. + . + Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Library. + . + In addition, mere aggregation of another work not based on the Library + with the Library (or with a work based on the Library) on a volume of + a storage or distribution medium does not bring the other work under + the scope of this License. + . + 3. You may opt to apply the terms of the ordinary GNU General Public + License instead of this License to a given copy of the Library. To do + this, you must alter all the notices that refer to this License, so + that they refer to the ordinary GNU General Public License, version 2, + instead of to this License. (If a newer version than version 2 of the + ordinary GNU General Public License has appeared, then you can specify + that version instead if you wish.) Do not make any other change in + these notices. + . + Once this change is made in a given copy, it is irreversible for + that copy, so the ordinary GNU General Public License applies to all + subsequent copies and derivative works made from that copy. + . + This option is useful when you wish to copy part of the code of + the Library into a program that is not a library. + . + 4. You may copy and distribute the Library (or a portion or + derivative of it, under Section 2) in object code or executable form + under the terms of Sections 1 and 2 above provided that you accompany + it with the complete corresponding machine-readable source code, which + must be distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange. + . + If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy the + source code from the same place satisfies the requirement to + distribute the source code, even though third parties are not + compelled to copy the source along with the object code. + . + 5. A program that contains no derivative of any portion of the + Library, but is designed to work with the Library by being compiled or + linked with it, is called a "work that uses the Library". Such a + work, in isolation, is not a derivative work of the Library, and + therefore falls outside the scope of this License. + . + However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because it + contains portions of the Library), rather than a "work that uses the + library". The executable is therefore covered by this License. + Section 6 states terms for distribution of such executables. + . + When a "work that uses the Library" uses material from a header file + that is part of the Library, the object code for the work may be a + derivative work of the Library even though the source code is not. + Whether this is true is especially significant if the work can be + linked without the Library, or if the work is itself a library. The + threshold for this to be true is not precisely defined by law. + . + If such an object file uses only numerical parameters, data + structure layouts and accessors, and small macros and small inline + functions (ten lines or less in length), then the use of the object + file is unrestricted, regardless of whether it is legally a derivative + work. (Executables containing this object code plus portions of the + Library will still fall under Section 6.) + . + Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section 6. + Any executables containing that work also fall under Section 6, + whether or not they are linked directly with the Library itself. + . + 6. As an exception to the Sections above, you may also combine or + link a "work that uses the Library" with the Library to produce a + work containing portions of the Library, and distribute that work + under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications. + . + You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered by + this License. You must supply a copy of this License. If the work + during execution displays copyright notices, you must include the + copyright notice for the Library among them, as well as a reference + directing the user to the copy of this License. Also, you must do one + of these things: + . + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + . + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + . + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + . + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + . + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + . + For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special exception, + the materials to be distributed need not include anything that is + normally distributed (in either source or binary form) with the major + components (compiler, kernel, and so on) of the operating system on + which the executable runs, unless that component itself accompanies + the executable. + . + It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you cannot + use both them and the Library together in an executable that you + distribute. + . + 7. You may place library facilities that are a work based on the + Library side-by-side in a single library together with other library + facilities not covered by this License, and distribute such a combined + library, provided that the separate distribution of the work based on + the Library and of the other library facilities is otherwise + permitted, and provided that you do these two things: + . + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + . + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + . + 8. You may not copy, modify, sublicense, link with, or distribute + the Library except as expressly provided under this License. Any + attempt otherwise to copy, modify, sublicense, link with, or + distribute the Library is void, and will automatically terminate your + rights under this License. However, parties who have received copies, + or rights, from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + . + 9. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Library or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Library (or any work based on the + Library), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying + the Library or works based on it. + . + 10. Each time you redistribute the Library (or any work based on the + Library), the recipient automatically receives a license from the + original licensor to copy, distribute, link with or modify the Library + subject to these terms and conditions. You may not impose any further + restrictions on the recipients' exercise of the rights granted herein. + You are not responsible for enforcing compliance by third parties with + this License. + . + 11. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Library at all. For example, if a patent + license would not permit royalty-free redistribution of the Library by + all those who receive copies directly or indirectly through you, then + the only way you could satisfy both it and this License would be to + refrain entirely from distribution of the Library. + . + If any portion of this section is held invalid or unenforceable under any + particular circumstance, the balance of the section is intended to apply, + and the section as a whole is intended to apply in other circumstances. + . + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is willing + to distribute software through any other system and a licensee cannot + impose that choice. + . + This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License. + . + 12. If the distribution and/or use of the Library is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Library under this License may add + an explicit geographical distribution limitation excluding those countries, + so that distribution is permitted only in or among countries not thus + excluded. In such case, this License incorporates the limitation as if + written in the body of this License. + . + 13. The Free Software Foundation may publish revised and/or new + versions of the Lesser General Public License from time to time. + Such new versions will be similar in spirit to the present version, + but may differ in detail to address new problems or concerns. + . + Each version is given a distinguishing version number. If the Library + specifies a version number of this License which applies to it and + "any later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Library does not specify a + license version number, you may choose any version ever published by + the Free Software Foundation. + . + 14. If you wish to incorporate parts of the Library into other free + programs whose distribution conditions are incompatible with these, + write to the author to ask for permission. For software which is + copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free status + of all derivatives of our free software and of promoting the sharing + and reuse of software generally. + . + NO WARRANTY + . + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR + OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE + LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME + THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + . + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. + . + END OF TERMS AND CONDITIONS + . + How to Apply These Terms to Your New Libraries + . + If you develop a new library, and you want it to be of the greatest + possible use to the public, we recommend making it free software that + everyone can redistribute and change. You can do so by permitting + redistribution under these terms (or, alternatively, under the terms of the + ordinary General Public License). + . + To apply these terms, attach the following notices to the library. It is + safest to attach them to the start of each source file to most effectively + convey the exclusion of warranty; and each file should have at least the + "copyright" line and a pointer to where the full notice is found. + . + + Copyright (C) + . + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + . + Also add information on how to contact you by electronic and paper mail. + . + You should also get your employer (if you work as a programmer) or your + school, if any, to sign a "copyright disclaimer" for the library, if + necessary. Here is a sample; alter the names: + . + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + . + , 1 April 1990 + Ty Coon, President of Vice + . + That's all there is to it! + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to ECMAScript Language + Specification ECMA-262 Edition 5.1 which may be included with + JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright notice + Copyright © 2011 Ecma International + Ecma International + Rue du Rhone 114 + CH-1204 Geneva + Tel: +41 22 849 6000 + Fax: +41 22 849 6001 + Web: http://www.ecma-international.org + . + This document and possible 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 Ecma International, except as + needed for the purpose of developing any document or deliverable produced by + Ecma International (in which case the rules applied to copyrights must be + followed) or as required to translate it into languages other than English. The + limited permissions granted above are perpetual and will not be revoked by Ecma + International or its successors or assigns. This document and the information + contained herein is provided on an "AS IS" basis and ECMA INTERNATIONAL + 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." Software License + . + All Software contained in this document ("Software)" is protected by copyright + and is being made available under the "BSD License", included below. This + Software may be subject to third party rights (rights from parties other than + Ecma International), including patent rights, and no licenses under such third + party rights are granted under this license even if the third party concerned is + a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS + AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR + INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO + IMPLEMENT ECMA INTERNATIONAL STANDARDS*. 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. Neither the name of the authors nor Ecma International may be used to endorse + or promote products derived from this software without specific prior written + permission. + . + THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "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 ECMA INTERNATIONAL 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 library which is included + with the Nashorn technology. + . + --- begin of 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 Joni library which is included + with the Nashorn technology. + . + --- begin of LICENSE --- + 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 --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to FontConfig 2.5, which may be + included with JRE 8, JDK 8, and OpenJDK 8 source distributions on + Linux and Solaris. + . + --- begin of LICENSE --- + . + Copyright © 2001,2003 Keith Packard + . + 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, and that + the name of Keith Packard not be used in advertising or publicity pertaining + to distribution of the software without specific, written prior permission. + Keith Packard makes no representations about the suitability of this software + for any purpose. It is provided "as is" without express or implied warranty. + . + KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KEITH + PACKARD 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. + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to IAIK PKCS#11 Wrapper, + which may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + IAIK PKCS#11 Wrapper 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 ICU4C 4.0.1 and ICU4J 4.4, which + may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright (c) 1995-2010 International Business Machines Corporation and others + . + 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, and/or sell copies of the + Software, and to permit persons to whom the Software is furnished to do so, + provided that the above copyright notice(s) and this permission notice appear + in all copies of the Software and that both the above copyright notice(s) and + this permission notice appear in supporting documentation. + . + 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 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 THIS 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 this Software without prior written authorization of the copyright holder. + All trademarks and registered trademarks mentioned herein are the property of + their respective owners. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to IJG JPEG 6b, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + This software is copyright (C) 1991-1998, Thomas G. Lane. + All Rights Reserved except as specified below. + . + Permission is hereby granted to use, copy, modify, and distribute this + software (or portions thereof) for any purpose, without fee, subject to these + conditions: + (1) If any part of the source code for this software is distributed, then this + README file must be included, with this copyright and no-warranty notice + unaltered; and any additions, deletions, or changes to the original files + must be clearly indicated in accompanying documentation. + (2) If only executable code is distributed, then the accompanying + documentation must state that "this software is based in part on the work of + the Independent JPEG Group". + (3) Permission for use of this software is granted only if the user accepts + full responsibility for any undesirable consequences; the authors accept + NO LIABILITY for damages of any kind. + . + These conditions apply to any software derived from or based on the IJG code, + not just to the unmodified library. If you use our work, you ought to + acknowledge us. + . + Permission is NOT granted for the use of any IJG author's name or company name + in advertising or publicity relating to this software or products derived from + it. This software may be referred to only as "the Independent JPEG Group's + software". + . + We specifically permit and encourage the use of this software as the basis of + commercial products, provided that all warranty or liability claims are + assumed by the product vendor. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Joni v1.1.9, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + 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 --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to JOpt-Simple v3.0, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright (c) 2004-2009 Paul R. Holser, Jr. + . 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 @@ -76,10 +1325,10 @@ 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 @@ -87,2464 +1336,1185 @@ 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. - -OpenJDK: - OpenJDK is licensed under the GPL v2 with exceptions, - see `/usr/share/common-licenses/GPL-2'. - The exceptions are: - - "CLASSPATH" EXCEPTION TO THE GPL - - OPENJDK ASSEMBLY EXCEPTION - Various third party code in OpenJDK is licensed under different licenses. - -Java Access Bridge: - Java Access Bridge is licensed under the LGPL v2. - See `/usr/share/common-licenses/LGPL-2'. - -A Note About License Headers ----------------------------- - -Some sources downloaded from openjdk.java.net do not display the GPL -license header. Instances are: - - - The files in openjdk/j2se/src/share/classes/javax/xml/stream/ seem to - comprise the BEA-StAX source code - - http://ftpna2.bea.com/pub/downloads/jsr173.jar - - with some Sun-specific modifications. We're assuming that Sun is - bundling BEA-StAX under the terms of the Apache License 2.0 and - that the modifications are owned by Sun. - - - We are assuming that these files are owned by Sun: - openjdk/j2se/src/share/classes/**/resources/*.properties - -The downloaded sources include a script that inserts proprietary -license headers into the source files it generates. The script -itself is GPL'd so we patched them to emit the GPL header. The -file is: - openjdk/j2se/make/java/nio/genExceptions.sh - ------------------------------------------------------------------------------- -"CLASSPATH" EXCEPTION TO THE GPL - -Certain source files distributed by Sun Microsystems, Inc. are subject to -the following clarification and special exception to the GPL, but only where -Sun has expressly included in the particular source file's header the words -"Sun designates this particular file as subject to the "Classpath" exception -as provided by Sun in the LICENSE file that accompanied this code." - - Linking this library statically or dynamically with other modules is making - a combined work based on this library. Thus, the terms and conditions of - the GNU General Public License cover the whole combination. - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent modules, - and to copy and distribute the resulting executable under terms of your - choice, provided that you also meet, for each linked independent module, - the terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. If - you modify this library, you may extend this exception to your version of - the library, but you are not obligated to do so. If you do not wish to do - so, delete this exception statement from your version. - ------------------------------------------------------------------------------- -OPENJDK ASSEMBLY EXCEPTION - -The OpenJDK source code made available by Sun at openjdk.java.net and -openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the -GNU General Public License version 2 -only ("GPL2"), with the following clarification and special exception. - - Linking this OpenJDK Code statically or dynamically with other code - is making a combined work based on this library. Thus, the terms - and conditions of GPL2 cover the whole combination. - - As a special exception, Sun gives you permission to link this - OpenJDK Code with certain code licensed by Sun as indicated at - http://openjdk.java.net/legal/exception-modules-2007-05-08.html - ("Designated Exception Modules") to produce an executable, - regardless of the license terms of the Designated Exception Modules, - and to copy and distribute the resulting executable under GPL2, - provided that the Designated Exception Modules continue to be - governed by the licenses under which they were offered by Sun. - -As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to -build an executable that includes those portions of necessary code that Sun -could not provide under GPL2 (or that Sun has provided under GPL2 with the -Classpath exception). If you modify or add to the OpenJDK code, that new -GPL2 code may still be combined with Designated Exception Modules if the -new code is made subject to this exception by its copyright holder. - ------------------------------------------------------------------------------- -OpenJDK Trademark Notice -Version 1.1, 2008/3/10 - -OpenJDK (the "Name") is a trademark of Sun Microsystems, Inc. (the "Owner"). -Owner permits any person obtaining a copy of this software (the "Software") -which is based on original software retrieved from one of the following -websites: http://download.java.net/openjdk, http://hg.openjdk.java.net/jdk6, -or http://openjdk.java.net (each a "Website", with the original software made -available by the Owner on a Website being known as the "Website Software") to -use the Name in package names and version strings of the Software subject to -the following conditions: - - - The Software is a substantially complete implementation of the OpenJDK - development kit or runtime environment code made available by Owner on a - Website, and the vast majority of the Software code is identical to the - upstream Website Software; - - - No permission is hereby granted to use the Name in any other manner, - unless such use constitutes "fair use." - - - The Owner makes no warranties of any kind respecting the Name and all - representations and warranties, including any implied warranty of - merchantability, fitness for a particular purpose or non-infringement - are hereby disclaimed; and - - - This notice and the following legend are included in all copies of the - Software or portions of it: - - OpenJDK is a trademark or registered trademark of Sun Microsystems, - Inc. in the United States and other countries. - -The Name may also be used in connection with descriptions of the Software that -constitute "fair use," such as "derived from the OpenJDK code base" or "based -on the OpenJDK source code." - -Owner intends to revise this Notice as necessary in order to meet the needs of -the OpenJDK Community. Please send questions or comments about this Notice to -Sun Microsystems at openjdk-tm@sun.com. Revisions to this Notice will be -announced on the public mailing list announce@openjdk.java.net, to which you -may subscribe by visiting http://mail.openjdk.java.net. The latest version of -this Notice may be found at http://openjdk.java.net/legal. - ------------------------------------------------------------------------------- - -The contents of the jdk/src/share/native/sun/security/ec/impl/ directory are -licensed under the LGPL-2.1. See `/usr/share/common-licenses/LGPL-2-1'. - ------------------------------------------------------------------------------- -The following licenses for third party code are taken from -openjdk/THIRD_PARTY_README ------------------------------------------------------------------------------- - -DO NOT TRANSLATE OR LOCALIZE. ------------------------------ - -%% This notice is provided with respect to ASM Bytecode Manipulation -Framework v5.0, which may be included with JRE 8, and JDK 8, and -OpenJDK 8. - ---- begin of LICENSE --- - -Copyright (c) 2000-2011 France Télécom -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. Neither the name of the copyright holders 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. - ---- end of LICENSE --- - --------------------------------------------------------------------------------- - -%% This notice is provided with respect to BSDiff v4.3, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Copyright 2003-2005 Colin Percival -All rights reserved - -Redistribution and use in source and binary forms, with or without -modification, are permitted providing that the following conditions -are met: -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to CodeViewer 1.0, which may be -included with JDK 8. - ---- begin of LICENSE --- - -Copyright 1999 by CoolServlets.com. - -Any errors or suggested improvements to this class can be reported as -instructed on CoolServlets.com. We hope you enjoy this program... your -comments will encourage further development! This software is distributed -under the terms of the BSD License. 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. - -Neither name of CoolServlets.com 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 COOLSERVLETS.COM 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 AUTHOR 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 Cryptix AES 3.2.0, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of 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. - + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Kerberos functionality, which + which may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + (C) Copyright IBM Corp. 1999 All Rights Reserved. + Copyright 1997 The Open Group Research Institute. All rights reserved. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Kerberos functionality from + FundsXpress, INC., which may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright (C) 1998 by the FundsXpress, INC. + . + All rights reserved. + . + Export of this software from the United States of America may require + a specific license from the United States Government. It is the + responsibility of any person or organization contemplating export to + obtain such a license before exporting. + . + WITHIN THAT CONSTRAINT, 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 that copyright notice and + this permission notice appear in supporting documentation, and that + the name of FundsXpress. not be used in advertising or publicity pertaining + to distribution of the software without specific, written prior + permission. FundsXpress makes no representations about the suitability of + this software for any purpose. It is provided "as is" without express + or implied warranty. + . + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Kronos OpenGL headers, which may be + included with JDK 8 and OpenJDK 8 source distributions. + . + --- begin of LICENSE --- + . + Copyright (c) 2007 The Khronos Group Inc. + . + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and/or associated documentation files (the "Materials"), to + deal in the Materials without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Materials, and to permit persons to whom the Materials are + 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 Materials. + . + THE MATERIALS 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. 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 MATERIALS OR THE USE OR OTHER DEALINGS IN THE + MATERIALS. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------- + . + %% Lucida is a registered trademark or trademark of Bigelow & Holmes in the + U.S. and other countries. + . + ------------------------------------------------------------------------------- + . + %% This notice is provided with respect to Mesa 3D Graphics Library v4.1, + which may be included with JRE 8, JDK 8, and OpenJDK 8 source distributions. + . + --- begin of LICENSE --- + . + Mesa 3-D graphics library + Version: 4.1 + . + Copyright (C) 1999-2002 Brian Paul 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 + BRIAN PAUL 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 Mozilla Network Security + Services (NSS), which is supplied with the JDK test suite in the OpenJDK + source code repository. It is licensed under Mozilla Public License (MPL), + version 2.0. + . + The NSS libraries are supplied in executable form, built from unmodified + NSS source code labeled with the "NSS_3.13.1_RTM" release tag. + . + The NSS source code is available in the OpenJDK source code repository at: + jdk/test/sun/security/pkcs11/nss/src + . + The NSS libraries are available in the OpenJDK source code repository at: + jdk/test/sun/security/pkcs11/nss/lib + . + --- begin of LICENSE --- + . + 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 http://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 PC/SC Lite for Suse Linux v.1.1.1, + which may be included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. + . + --- begin of LICENSE --- + . + Copyright (c) 1999-2004 David Corcoran + Copyright (c) 1999-2004 Ludovic Rousseau + All rights reserved. + . + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + . + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -THIS SOFTWARE IS PROVIDED BY THE 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 CUP Parser Generator for -Java 0.10k, which may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian - -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. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Document Object Model (DOM) Level 2 -& 3, which may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of 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. - - 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. - -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. - -____________________________________ - -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. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Dynalink v0.5, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Copyright (c) 2009-2013, Attila Szegedi - -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 Attila -Szegedi 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 HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Elliptic Curve Cryptography, which -may be included with JRE 8, JDK 8, and OpenJDK 8. - -You are receiving a copy of the Elliptic Curve Cryptography library in source -form with the JDK 8 and OpenJDK 8 source distributions, and as object code in -the JRE 8 & JDK 8 runtimes. - -In the case of the JRE 8 & JDK 8 runtimes, the terms of the Oracle license do -NOT apply to the Elliptic Curve Cryptography library; it is licensed under the -following license, separately from Oracle's JDK & JRE. If you do not wish to -install the Elliptic Curve Cryptography library, you may delete the library -named libsunec.so (on Solaris and Linux systems) or sunec.dll (on Windows -systems) from the JRE bin directory reserved for native libraries. - - ---- begin of LICENSE --- - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by: + David Corcoran + http://www.linuxnet.com (MUSCLE) + 4. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + . + Changes to this license can be made only by the copyright author with + explicit written consent. + . + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to PorterStemmer v4, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + See: http://tartarus.org/~martin/PorterStemmer + . + The software is completely free for any purpose, unless notes at the head of + the program text indicates otherwise (which is rare). In any case, the notes + about licensing are never more restrictive than the BSD License. + . + In every case where the software is not written by me (Martin Porter), this + licensing arrangement has been endorsed by the contributor, and it is + therefore unnecessary to ask the contributor again to confirm it. + . + I have not asked any contributors (or their employers, if they have them) for + proofs that they have the right to distribute their software in this way. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Relax NG Object/Parser v.20050510, + which may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright (c) Kohsuke Kawaguchi + . + 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 --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to RelaxNGCC v1.12, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Copyright (c) 2000-2003 Daisuke Okajima and Kohsuke Kawaguchi. + 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 Daisuke Okajima + and Kohsuke Kawaguchi (http://relaxngcc.sf.net/)." + . + Alternately, this acknowledgment may appear in the software itself, if and + wherever such third-party acknowledgments normally appear. + . + 4. The names of the copyright holders must not be used to endorse or promote + products derived from this software without prior written permission. For + written permission, please contact the copyright holders. + . + 5. Products derived from this software may not be called "RELAXNGCC", nor may + "RELAXNGCC" appear in their name, without prior written permission of the + copyright holders. + . + 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 APACHE + SOFTWARE FOUNDATION OR ITS 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 SAX 2.0.1, which may be included + with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + SAX is free! + . + In fact, it's not possible to own a license to SAX, since it's been placed in + the public domain. + . + No Warranty + . + Because SAX is released to the public domain, there is no warranty for the + design or for the software implementation, to the extent permitted by + applicable law. Except when otherwise stated in writing the copyright holders + and/or other parties provide SAX "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied warranties + of merchantability and fitness for a particular purpose. The entire risk as + to the quality and performance of SAX is with you. Should SAX prove + defective, you assume the cost of all necessary servicing, repair or + correction. + . + In no event unless required by applicable law or agreed to in writing will + any copyright holder, or any other party who may modify and/or redistribute + SAX, be liable to you for damages, including any general, special, incidental + or consequential damages arising out of the use or inability to use SAX + (including but not limited to loss of data or data being rendered inaccurate + or losses sustained by you or third parties or a failure of the SAX to + operate with any other programs), even if such holder or other party has been + advised of the possibility of such damages. + . + Copyright Disclaimers + . + This page includes statements to that effect by David Megginson, who would + have been able to claim copyright for the original work. SAX 1.0 + . + Version 1.0 of the Simple API for XML (SAX), created collectively by the + membership of the XML-DEV mailing list, is hereby released into the public + domain. + . + No one owns SAX: you may use it freely in both commercial and non-commercial + applications, bundle it with your software distribution, include it on a + CD-ROM, list the source code in a book, mirror the documentation at your own + web site, or use it in any other way you see fit. + . + David Megginson, sax@megginson.com + 1998-05-11 + . + SAX 2.0 + . + I hereby abandon any property rights to SAX 2.0 (the Simple API for XML), and + release all of the SAX 2.0 source code, compiled code, and documentation + contained in this distribution into the Public Domain. SAX comes with NO + WARRANTY or guarantee of fitness for any purpose. + . + David Megginson, david@megginson.com + 2000-05-05 + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to SoftFloat version 2b, which may be + included with JRE 8, JDK 8, and OpenJDK 8 on Linux/ARM. + . + --- begin of LICENSE --- + . + Use of any of this software is governed by the terms of the license below: + . + SoftFloat was written by me, John R. Hauser. This work was made possible in + part by the International Computer Science Institute, located at Suite 600, + 1947 Center Street, Berkeley, California 94704. Funding was partially + provided by the National Science Foundation under grant MIP-9311980. The + original version of this code was written as part of a project to build + a fixed-point vector processor in collaboration with the University of + California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. + . + THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort + has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT + TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO + PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL + LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO + FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER + SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, + COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE + SOFTWARE. + . + Derivative works are acceptable, even for commercial purposes, provided + that the minimal documentation requirements stated in the source code are + satisfied. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Sparkle 1.5, + which may be included with JRE 8 on Mac OS X. + . + --- begin of LICENSE --- + . + Copyright (c) 2012 Sparkle.org and Andy Matuschak + . + 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 --- + . + ------------------------------------------------------------------------------ + . + %% Portions licensed from Taligent, Inc. + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Thai Dictionary, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of 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 --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Unicode 6.2.0 & CLDR 21.0.1 + which may be included with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + Unicode Terms of Use + . + For the general privacy policy governing access to this site, see the Unicode + Privacy Policy. For trademark usage, see the Unicode® Consortium Name and + Trademark Usage Policy. + . + A. Unicode Copyright. + 1. Copyright © 1991-2013 Unicode, Inc. All rights reserved. + . + 2. 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. + . + 3. Any person is hereby authorized, without fee, to view, use, reproduce, + and distribute all documents and files solely for informational + purposes in the creation of products supporting the Unicode Standard, + subject to the Terms and Conditions herein. + . + 4. Further specifications of rights and restrictions pertaining to the use + of the particular set of data files known as the "Unicode Character + Database" can be found in Exhibit 1. + . + 5. 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 online + code charts carry specific restrictions. All other files, including + online documentation of the core specification for Unicode 6.0 and + later, are covered under these general Terms of Use. + . + 6. No license is granted to "mirror" the Unicode website where a fee is + charged for access to the "mirror" site. + . + 7. Modification is not permitted with respect to this document. All copies + of this document must be verbatim. + . + B. 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. + . + C. Warranties and Disclaimers. + 1. 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 may make improvements and/or + changes in the product(s) and/or program(s) described in this + publication and/or website at any time. + . + 2. 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. + . + 3. EXCEPT AS PROVIDED IN SECTION C.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 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. + . + D. Waiver of Damages. In no event shall Unicode or its licensors be liable for + any special, incidental, indirect or consequential damages of any kind, or + any damages whatsoever, whether or not Unicode 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. + . + E.Trademarks & Logos. + 1. 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. + . + 2. 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. + . + 3. All third party trademarks referenced herein are the property of their + respective owners. + . + Miscellaneous. + 1. Jurisdiction and Venue. This server is operated from a location in the + State of California, United States of America. Unicode makes no + representation that the materials are appropriate for use in other + locations. If you access this server from other locations, you are + responsible for compliance with local laws. This Agreement, all use of + this site and any claims and damages resulting from use of this site 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 site 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. + . + 2. Modification by Unicode. Unicode shall have the right to modify this + Agreement at any time by posting it to this site. The user may not + assign any part of this Agreement without Unicode’s prior written + consent. + . + 3. 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. + . + 4. Severability. If any provision of this Agreement is declared invalid or + unenforceable, the remaining provisions of this Agreement shall remain + in effect. + . + 5. Entire Agreement. This Agreement constitutes the entire agreement + between the parties. + . + EXHIBIT 1 + UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE + . + Unicode Data Files include all data files under the directories + http://www.unicode.org/Public/, http://www.unicode.org/reports/, and + http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF + online code charts under the directory http://www.unicode.org/Public/. + Software includes any source code published in the Unicode Standard or under + the directories http://www.unicode.org/Public/, + http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/. + . + 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-2012 Unicode, Inc. All rights reserved. Distributed under the + Terms of Use in http://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 (a) the above + copyright notice(s) and this permission notice appear with all copies of the + Data Files or Software, (b) both the above copyright notice(s) and this + permission notice appear in associated documentation, and (c) there is clear + notice in each modified Data File or in the Software as well as in the + documentation associated with the Data File(s) or Software that the data or + software has been modified. + . + 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. + . + Unicode and the Unicode logo are trademarks of Unicode, Inc. in the United + States and other countries. All third party trademarks referenced herein are + the property of their respective owners. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to UPX v3.01, which may be included + with JRE 8 on Windows. + . + --- begin of LICENSE --- + . + Use of any of this software is governed by the terms of the license below: + . + . + ooooo ooo ooooooooo. ooooooo ooooo + `888' `8' `888 `Y88. `8888 d8' + 888 8 888 .d88' Y888..8P + 888 8 888ooo88P' `8888' + 888 8 888 .8PY888. + `88. .8' 888 d8' `888b + `YbodP' o888o o888o o88888o + . + . + The Ultimate Packer for eXecutables + Copyright (c) 1996-2000 Markus Oberhumer & Laszlo Molnar + http://wildsau.idv.uni-linz.ac.at/mfx/upx.html + http://www.nexus.hu/upx + http://upx.tsx.org + . + . + PLEASE CAREFULLY READ THIS LICENSE AGREEMENT, ESPECIALLY IF YOU PLAN + TO MODIFY THE UPX SOURCE CODE OR USE A MODIFIED UPX VERSION. + . + . + ABSTRACT + ======== + . + UPX and UCL are copyrighted software distributed under the terms + of the GNU General Public License (hereinafter the "GPL"). + . + The stub which is imbedded in each UPX compressed program is part + of UPX and UCL, and contains code that is under our copyright. The + terms of the GNU General Public License still apply as compressing + a program is a special form of linking with our stub. + . + As a special exception we grant the free usage of UPX for all + executables, including commercial programs. + See below for details and restrictions. + . + . + COPYRIGHT + ========= + . + UPX and UCL are copyrighted software. All rights remain with the authors. + . + UPX is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer + UPX is Copyright (C) 1996-2000 Laszlo Molnar + . + UCL is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer + . + . + GNU GENERAL PUBLIC LICENSE + ========================== + . + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + . + UPX and UCL are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to ECMAScript Language -Specification ECMA-262 Edition 5.1 which may be included with -JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Copyright notice -Copyright © 2011 Ecma International -Ecma International -Rue du Rhone 114 -CH-1204 Geneva -Tel: +41 22 849 6000 -Fax: +41 22 849 6001 -Web: http://www.ecma-international.org - -This document and possible 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 Ecma International, except as -needed for the purpose of developing any document or deliverable produced by -Ecma International (in which case the rules applied to copyrights must be -followed) or as required to translate it into languages other than English. The -limited permissions granted above are perpetual and will not be revoked by Ecma -International or its successors or assigns. This document and the information -contained herein is provided on an "AS IS" basis and ECMA INTERNATIONAL -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." Software License - -All Software contained in this document ("Software)" is protected by copyright -and is being made available under the "BSD License", included below. This -Software may be subject to third party rights (rights from parties other than -Ecma International), including patent rights, and no licenses under such third -party rights are granted under this license even if the third party concerned is -a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS -AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR -INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO -IMPLEMENT ECMA INTERNATIONAL STANDARDS*. 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. Neither the name of the authors nor Ecma International may be used to endorse -or promote products derived from this software without specific prior written -permission. - -THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "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 ECMA INTERNATIONAL 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 library which is included -with the Nashorn technology. - ---- begin of 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 Joni library which is included -with the Nashorn technology. - ---- begin of LICENSE --- -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 --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to FontConfig 2.5, which may be -included with JRE 8, JDK 8, and OpenJDK 8 source distributions on -Linux and Solaris. - ---- begin of LICENSE --- - -Copyright © 2001,2003 Keith Packard - -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, and that -the name of Keith Packard not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior permission. -Keith Packard makes no representations about the suitability of this software -for any purpose. It is provided "as is" without express or implied warranty. - -KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KEITH -PACKARD 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. - - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to IAIK PKCS#11 Wrapper, -which may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -IAIK PKCS#11 Wrapper 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 ICU4C 4.0.1 and ICU4J 4.4, which -may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Copyright (c) 1995-2010 International Business Machines Corporation and others - -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, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -provided that the above copyright notice(s) and this permission notice appear -in all copies of the Software and that both the above copyright notice(s) and -this permission notice appear in supporting documentation. - -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 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 THIS 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 this Software without prior written authorization of the copyright holder. -All trademarks and registered trademarks mentioned herein are the property of -their respective owners. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to IJG JPEG 6b, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -This software is copyright (C) 1991-1998, Thomas G. Lane. -All Rights Reserved except as specified below. - -Permission is hereby granted to use, copy, modify, and distribute this -software (or portions thereof) for any purpose, without fee, subject to these -conditions: -(1) If any part of the source code for this software is distributed, then this -README file must be included, with this copyright and no-warranty notice -unaltered; and any additions, deletions, or changes to the original files -must be clearly indicated in accompanying documentation. -(2) If only executable code is distributed, then the accompanying -documentation must state that "this software is based in part on the work of -the Independent JPEG Group". -(3) Permission for use of this software is granted only if the user accepts -full responsibility for any undesirable consequences; the authors accept -NO LIABILITY for damages of any kind. - -These conditions apply to any software derived from or based on the IJG code, -not just to the unmodified library. If you use our work, you ought to -acknowledge us. - -Permission is NOT granted for the use of any IJG author's name or company name -in advertising or publicity relating to this software or products derived from -it. This software may be referred to only as "the Independent JPEG Group's -software". - -We specifically permit and encourage the use of this software as the basis of -commercial products, provided that all warranty or liability claims are -assumed by the product vendor. - ---- end of LICENSE --- - --------------------------------------------------------------------------------- - -%% This notice is provided with respect to Joni v1.1.9, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -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 --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to JOpt-Simple v3.0, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - - Copyright (c) 2004-2009 Paul R. Holser, Jr. - - 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 --- - --------------------------------------------------------------------------------- - -%% This notice is provided with respect to Kerberos functionality, which -which may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - - (C) Copyright IBM Corp. 1999 All Rights Reserved. - Copyright 1997 The Open Group Research Institute. All rights reserved. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Kerberos functionality from -FundsXpress, INC., which may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - - Copyright (C) 1998 by the FundsXpress, INC. - - All rights reserved. - - Export of this software from the United States of America may require - a specific license from the United States Government. It is the - responsibility of any person or organization contemplating export to - obtain such a license before exporting. - - WITHIN THAT CONSTRAINT, 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 that copyright notice and - this permission notice appear in supporting documentation, and that - the name of FundsXpress. not be used in advertising or publicity pertaining - to distribution of the software without specific, written prior - permission. FundsXpress makes no representations about the suitability of - this software for any purpose. It is provided "as is" without express - or implied warranty. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Kronos OpenGL headers, which may be -included with JDK 8 and OpenJDK 8 source distributions. - ---- begin of LICENSE --- - - Copyright (c) 2007 The Khronos Group Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and/or associated documentation files (the "Materials"), to - deal in the Materials without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Materials, and to permit persons to whom the Materials are - 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 Materials. - - THE MATERIALS 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. 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 MATERIALS OR THE USE OR OTHER DEALINGS IN THE - MATERIALS. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% Lucida is a registered trademark or trademark of Bigelow & Holmes in the -U.S. and other countries. - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Mesa 3D Graphics Library v4.1, -which may be included with JRE 8, JDK 8, and OpenJDK 8 source distributions. - ---- begin of LICENSE --- - - Mesa 3-D graphics library - Version: 4.1 - - Copyright (C) 1999-2002 Brian Paul 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 - BRIAN PAUL 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 Mozilla Network Security -Services (NSS), which is supplied with the JDK test suite in the OpenJDK -source code repository. It is licensed under Mozilla Public License (MPL), -version 2.0. - -The NSS libraries are supplied in executable form, built from unmodified -NSS source code labeled with the "NSS_3.13.1_RTM" release tag. - -The NSS source code is available in the OpenJDK source code repository at: - jdk/test/sun/security/pkcs11/nss/src - -The NSS libraries are available in the OpenJDK source code repository at: - jdk/test/sun/security/pkcs11/nss/lib - ---- begin of LICENSE --- - -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 http://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 PC/SC Lite for Suse Linux v.1.1.1, -which may be included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. - ---- begin of LICENSE --- - -Copyright (c) 1999-2004 David Corcoran -Copyright (c) 1999-2004 Ludovic Rousseau -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. All advertising materials mentioning features or use of this software - must display the following acknowledgement: - This product includes software developed by: - David Corcoran - http://www.linuxnet.com (MUSCLE) -4. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -Changes to this license can be made only by the copyright author with -explicit written consent. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to PorterStemmer v4, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -See: http://tartarus.org/~martin/PorterStemmer - -The software is completely free for any purpose, unless notes at the head of -the program text indicates otherwise (which is rare). In any case, the notes -about licensing are never more restrictive than the BSD License. - -In every case where the software is not written by me (Martin Porter), this -licensing arrangement has been endorsed by the contributor, and it is -therefore unnecessary to ask the contributor again to confirm it. - -I have not asked any contributors (or their employers, if they have them) for -proofs that they have the right to distribute their software in this way. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Relax NG Object/Parser v.20050510, -which may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Copyright (c) Kohsuke Kawaguchi - -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 --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to RelaxNGCC v1.12, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Copyright (c) 2000-2003 Daisuke Okajima and Kohsuke Kawaguchi. -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 Daisuke Okajima - and Kohsuke Kawaguchi (http://relaxngcc.sf.net/)." - -Alternately, this acknowledgment may appear in the software itself, if and -wherever such third-party acknowledgments normally appear. - -4. The names of the copyright holders must not be used to endorse or promote - products derived from this software without prior written permission. For - written permission, please contact the copyright holders. - -5. Products derived from this software may not be called "RELAXNGCC", nor may - "RELAXNGCC" appear in their name, without prior written permission of the - copyright holders. - -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 APACHE -SOFTWARE FOUNDATION OR ITS 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 SAX 2.0.1, which may be included -with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - - SAX is free! - - In fact, it's not possible to own a license to SAX, since it's been placed in - the public domain. - - No Warranty - - Because SAX is released to the public domain, there is no warranty for the - design or for the software implementation, to the extent permitted by - applicable law. Except when otherwise stated in writing the copyright holders - and/or other parties provide SAX "as is" without warranty of any kind, either - expressed or implied, including, but not limited to, the implied warranties - of merchantability and fitness for a particular purpose. The entire risk as - to the quality and performance of SAX is with you. Should SAX prove - defective, you assume the cost of all necessary servicing, repair or - correction. - - In no event unless required by applicable law or agreed to in writing will - any copyright holder, or any other party who may modify and/or redistribute - SAX, be liable to you for damages, including any general, special, incidental - or consequential damages arising out of the use or inability to use SAX - (including but not limited to loss of data or data being rendered inaccurate - or losses sustained by you or third parties or a failure of the SAX to - operate with any other programs), even if such holder or other party has been - advised of the possibility of such damages. - - Copyright Disclaimers - - This page includes statements to that effect by David Megginson, who would - have been able to claim copyright for the original work. SAX 1.0 - - Version 1.0 of the Simple API for XML (SAX), created collectively by the - membership of the XML-DEV mailing list, is hereby released into the public - domain. - - No one owns SAX: you may use it freely in both commercial and non-commercial - applications, bundle it with your software distribution, include it on a - CD-ROM, list the source code in a book, mirror the documentation at your own - web site, or use it in any other way you see fit. - - David Megginson, sax@megginson.com - 1998-05-11 - - SAX 2.0 - - I hereby abandon any property rights to SAX 2.0 (the Simple API for XML), and - release all of the SAX 2.0 source code, compiled code, and documentation - contained in this distribution into the Public Domain. SAX comes with NO - WARRANTY or guarantee of fitness for any purpose. - - David Megginson, david@megginson.com - 2000-05-05 - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to SoftFloat version 2b, which may be -included with JRE 8, JDK 8, and OpenJDK 8 on Linux/ARM. - ---- begin of LICENSE --- - -Use of any of this software is governed by the terms of the license below: - -SoftFloat was written by me, John R. Hauser. This work was made possible in -part by the International Computer Science Institute, located at Suite 600, -1947 Center Street, Berkeley, California 94704. Funding was partially -provided by the National Science Foundation under grant MIP-9311980. The -original version of this code was written as part of a project to build -a fixed-point vector processor in collaboration with the University of -California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort -has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT -TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO -PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL -LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO -FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER -SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, -COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE -SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, provided -that the minimal documentation requirements stated in the source code are -satisfied. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Sparkle 1.5, -which may be included with JRE 8 on Mac OS X. - ---- begin of LICENSE --- - -Copyright (c) 2012 Sparkle.org and Andy Matuschak - -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 --- - -------------------------------------------------------------------------------- - -%% Portions licensed from Taligent, Inc. - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Thai Dictionary, which may be -included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of 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 --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Unicode 6.2.0 & CLDR 21.0.1 -which may be included with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - -Unicode Terms of Use - -For the general privacy policy governing access to this site, see the Unicode -Privacy Policy. For trademark usage, see the Unicode® Consortium Name and -Trademark Usage Policy. - -A. Unicode Copyright. - 1. Copyright © 1991-2013 Unicode, Inc. All rights reserved. - - 2. 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. - - 3. Any person is hereby authorized, without fee, to view, use, reproduce, - and distribute all documents and files solely for informational - purposes in the creation of products supporting the Unicode Standard, - subject to the Terms and Conditions herein. - - 4. Further specifications of rights and restrictions pertaining to the use - of the particular set of data files known as the "Unicode Character - Database" can be found in Exhibit 1. - - 5. 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 online - code charts carry specific restrictions. All other files, including - online documentation of the core specification for Unicode 6.0 and - later, are covered under these general Terms of Use. - - 6. No license is granted to "mirror" the Unicode website where a fee is - charged for access to the "mirror" site. - - 7. Modification is not permitted with respect to this document. All copies - of this document must be verbatim. - -B. 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. - -C. Warranties and Disclaimers. - 1. 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 may make improvements and/or - changes in the product(s) and/or program(s) described in this - publication and/or website at any time. - - 2. 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. - - 3. EXCEPT AS PROVIDED IN SECTION C.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 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. - -D. Waiver of Damages. In no event shall Unicode or its licensors be liable for - any special, incidental, indirect or consequential damages of any kind, or - any damages whatsoever, whether or not Unicode 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. - -E.Trademarks & Logos. - 1. 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. - - 2. 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. - - 3. All third party trademarks referenced herein are the property of their - respective owners. - -Miscellaneous. - 1. Jurisdiction and Venue. This server is operated from a location in the - State of California, United States of America. Unicode makes no - representation that the materials are appropriate for use in other - locations. If you access this server from other locations, you are - responsible for compliance with local laws. This Agreement, all use of - this site and any claims and damages resulting from use of this site 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 site 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. - - 2. Modification by Unicode. Unicode shall have the right to modify this - Agreement at any time by posting it to this site. The user may not - assign any part of this Agreement without Unicode’s prior written - consent. - - 3. 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. - - 4. Severability. If any provision of this Agreement is declared invalid or - unenforceable, the remaining provisions of this Agreement shall remain - in effect. - - 5. Entire Agreement. This Agreement constitutes the entire agreement - between the parties. - -EXHIBIT 1 -UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - -Unicode Data Files include all data files under the directories -http://www.unicode.org/Public/, http://www.unicode.org/reports/, and -http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF -online code charts under the directory http://www.unicode.org/Public/. -Software includes any source code published in the Unicode Standard or under -the directories http://www.unicode.org/Public/, -http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/. - -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-2012 Unicode, Inc. All rights reserved. Distributed under the -Terms of Use in http://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 (a) the above -copyright notice(s) and this permission notice appear with all copies of the -Data Files or Software, (b) both the above copyright notice(s) and this -permission notice appear in associated documentation, and (c) there is clear -notice in each modified Data File or in the Software as well as in the -documentation associated with the Data File(s) or Software that the data or -software has been modified. - -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. - -Unicode and the Unicode logo are trademarks of Unicode, Inc. in the United -States and other countries. All third party trademarks referenced herein are -the property of their respective owners. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to UPX v3.01, which may be included -with JRE 8 on Windows. - ---- begin of LICENSE --- - -Use of any of this software is governed by the terms of the license below: - - - ooooo ooo ooooooooo. ooooooo ooooo - `888' `8' `888 `Y88. `8888 d8' - 888 8 888 .d88' Y888..8P - 888 8 888ooo88P' `8888' - 888 8 888 .8PY888. - `88. .8' 888 d8' `888b - `YbodP' o888o o888o o88888o - - - The Ultimate Packer for eXecutables - Copyright (c) 1996-2000 Markus Oberhumer & Laszlo Molnar - http://wildsau.idv.uni-linz.ac.at/mfx/upx.html - http://www.nexus.hu/upx - http://upx.tsx.org - - -PLEASE CAREFULLY READ THIS LICENSE AGREEMENT, ESPECIALLY IF YOU PLAN -TO MODIFY THE UPX SOURCE CODE OR USE A MODIFIED UPX VERSION. - - -ABSTRACT -======== - - UPX and UCL are copyrighted software distributed under the terms - of the GNU General Public License (hereinafter the "GPL"). - - The stub which is imbedded in each UPX compressed program is part - of UPX and UCL, and contains code that is under our copyright. The - terms of the GNU General Public License still apply as compressing - a program is a special form of linking with our stub. - - As a special exception we grant the free usage of UPX for all - executables, including commercial programs. - See below for details and restrictions. - - -COPYRIGHT -========= - - UPX and UCL are copyrighted software. All rights remain with the authors. - - UPX is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer - UPX is Copyright (C) 1996-2000 Laszlo Molnar - - UCL is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer - - -GNU GENERAL PUBLIC LICENSE -========================== - - UPX and the UCL library are free software; you can redistribute them - and/or modify them under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - UPX and UCL are distributed in the hope that they will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. - - -SPECIAL EXCEPTION FOR COMPRESSED EXECUTABLES -============================================ - - The stub which is imbedded in each UPX compressed program is part - of UPX and UCL, and contains code that is under our copyright. The - terms of the GNU General Public License still apply as compressing - a program is a special form of linking with our stub. - - Hereby Markus F.X.J. Oberhumer and Laszlo Molnar grant you special - permission to freely use and distribute all UPX compressed programs - (including commercial ones), subject to the following restrictions: - - 1. You must compress your program with a completely unmodified UPX - version; either with our precompiled version, or (at your option) - with a self compiled version of the unmodified UPX sources as - distributed by us. - 2. This also implies that the UPX stub must be completely unmodfied, i.e. - the stub imbedded in your compressed program must be byte-identical - to the stub that is produced by the official unmodified UPX version. - 3. The decompressor and any other code from the stub must exclusively get - used by the unmodified UPX stub for decompressing your program at - program startup. No portion of the stub may get read, copied, - called or otherwise get used or accessed by your program. - - -ANNOTATIONS -=========== - - - You can use a modified UPX version or modified UPX stub only for - programs that are compatible with the GNU General Public License. - - - We grant you special permission to freely use and distribute all UPX - compressed programs. But any modification of the UPX stub (such as, - but not limited to, removing our copyright string or making your - program non-decompressible) will immediately revoke your right to - use and distribute a UPX compressed program. - - - UPX is not a software protection tool; by requiring that you use - the unmodified UPX version for your proprietary programs we - make sure that any user can decompress your program. This protects - both you and your users as nobody can hide malicious code - - any program that cannot be decompressed is highly suspicious - by definition. - - - You can integrate all or part of UPX and UCL into projects that - are compatible with the GNU GPL, but obviously you cannot grant - any special exceptions beyond the GPL for our code in your project. - - - We want to actively support manufacturers of virus scanners and - similar security software. Please contact us if you would like to - incorporate parts of UPX or UCL into such a product. - - - -Markus F.X.J. Oberhumer Laszlo Molnar -markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu - -Linz, Austria, 25 Feb 2000 - -Additional License(s) - -The UPX license file is at http://upx.sourceforge.net/upx-license.html. - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to Xfree86-VidMode Extension 1.0, -which may be included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. - ---- begin of LICENSE --- - -Version 1.1 of XFree86 ProjectLicence. - -Copyright (C) 1994-2004 The XFree86 Project, Inc. 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, sublicence, 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. 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, and in the same place - and form as other copyright, license and disclaimer information. - - 3. The end-user documentation included with the redistribution, if any,must - include the following acknowledgment: "This product includes - software developed by The XFree86 Project, Inc (http://www.xfree86.org/) and - its contributors", in the same place and form as other third-party - acknowledgments. Alternately, this acknowledgment may appear in the software - itself, in the same form and location as other such third-party - acknowledgments. - + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + . + . + SPECIAL EXCEPTION FOR COMPRESSED EXECUTABLES + ============================================ + . + The stub which is imbedded in each UPX compressed program is part + of UPX and UCL, and contains code that is under our copyright. The + terms of the GNU General Public License still apply as compressing + a program is a special form of linking with our stub. + . + Hereby Markus F.X.J. Oberhumer and Laszlo Molnar grant you special + permission to freely use and distribute all UPX compressed programs + (including commercial ones), subject to the following restrictions: + . + 1. You must compress your program with a completely unmodified UPX + version; either with our precompiled version, or (at your option) + with a self compiled version of the unmodified UPX sources as + distributed by us. + 2. This also implies that the UPX stub must be completely unmodfied, i.e. + the stub imbedded in your compressed program must be byte-identical + to the stub that is produced by the official unmodified UPX version. + 3. The decompressor and any other code from the stub must exclusively get + used by the unmodified UPX stub for decompressing your program at + program startup. No portion of the stub may get read, copied, + called or otherwise get used or accessed by your program. + . + . + ANNOTATIONS + =========== + . + - You can use a modified UPX version or modified UPX stub only for + programs that are compatible with the GNU General Public License. + . + - We grant you special permission to freely use and distribute all UPX + compressed programs. But any modification of the UPX stub (such as, + but not limited to, removing our copyright string or making your + program non-decompressible) will immediately revoke your right to + use and distribute a UPX compressed program. + . + - UPX is not a software protection tool; by requiring that you use + the unmodified UPX version for your proprietary programs we + make sure that any user can decompress your program. This protects + both you and your users as nobody can hide malicious code - + any program that cannot be decompressed is highly suspicious + by definition. + . + - You can integrate all or part of UPX and UCL into projects that + are compatible with the GNU GPL, but obviously you cannot grant + any special exceptions beyond the GPL for our code in your project. + . + - We want to actively support manufacturers of virus scanners and + similar security software. Please contact us if you would like to + incorporate parts of UPX or UCL into such a product. + . + . + . + Markus F.X.J. Oberhumer Laszlo Molnar + markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu + . + Linz, Austria, 25 Feb 2000 + . + Additional License(s) + . + The UPX license file is at http://upx.sourceforge.net/upx-license.html. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to Xfree86-VidMode Extension 1.0, + which may be included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. + . + --- begin of LICENSE --- + . + Version 1.1 of XFree86 ProjectLicence. + . + Copyright (C) 1994-2004 The XFree86 Project, Inc. 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, sublicence, 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. 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, and in the same place + and form as other copyright, license and disclaimer information. + . + 3. The end-user documentation included with the redistribution, if any,must + include the following acknowledgment: "This product includes + software developed by The XFree86 Project, Inc (http://www.xfree86.org/) and + its contributors", in the same place and form as other third-party + acknowledgments. Alternately, this acknowledgment may appear in the software + itself, in the same form and location as other such third-party + acknowledgments. + . 4. Except as contained in this notice, the name of The XFree86 Project,Inc 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 XFree86 Project, Inc. - + . 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 @@ -2555,883 +2525,907 @@ 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 X Window System 6.8.2, which may be -included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. - ---- begin of LICENSE --- - - Licenses -The X.Org Foundation March 2004 - -1. Introduction - -The X.org Foundation X Window System distribution is a compilation of code and -documentation from many sources. This document is intended primarily as a -guide to the licenses used in the distribution: you must check each file -and/or package for precise redistribution terms. None-the-less, this summary -may be useful to many users. No software incorporating the XFree86 1.1 license -has been incorporated. - -This document is based on the compilation from XFree86. - -2. XFree86 License - -XFree86 code without an explicit copyright is covered by the following -copyright/license: - -Copyright (C) 1994-2003 The XFree86 Project, Inc. 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 -XFREE86 PROJECT 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. - -Except as contained in this notice, the name of the XFree86 Project 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 XFree86 Project. - -3. Other Licenses - -Portions of code are covered by the following licenses/copyrights. See -individual files for the copyright dates. - -3.1. X/MIT Copyrights - -3.1.1. X Consortium - -Copyright (C) X Consortium - -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 X -CONSORTIUM 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. - -Except as contained in this notice, the name of the X Consortium 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 X Consortium. - -X Window System is a trademark of X Consortium, Inc. - -3.1.2. The Open Group - -Copyright The Open Group - -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. - -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. - -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. 3.2. -Berkeley-based copyrights: - -o -3.2.1. General - -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 name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. 3.2.2. UCB/LBL - -Copyright (c) 1993 The Regents of the University of California. All rights -reserved. - -This software was developed by the Computer Systems Engineering group at -Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and contributed to -Berkeley. - -All advertising materials mentioning features or use of this software must -display the following acknowledgement: This product includes software -developed by the University of California, Lawrence Berkeley Laboratory. - -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. All advertising materials mentioning features or use of this software - must display the following acknowledgement: This product includes software - developed by the University of California, Berkeley and its contributors. - - 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. 3.2.3. The -NetBSD Foundation, Inc. - -Copyright (c) 2003 The NetBSD Foundation, Inc. All rights reserved. - -This code is derived from software contributed to The NetBSD Foundation by Ben -Collver - -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. All advertising materials mentioning features or use of this software - must display the following acknowledgement: This product includes software - developed by the NetBSD Foundation, Inc. and its contributors. - - 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. 3.2.4. Theodore -Ts'o. - -Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. 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, - and the entire permission notice in its entirety, including the disclaimer - of warranties. - - 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. he name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE, ALL OF WHICH ARE HEREBY DISCLAIMED. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. 3.2.5. Theo de Raadt and Damien Miller - -Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. Copyright (c) -2001-2002 Damien Miller. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. 3.2.6. Todd C. Miller - -Copyright (c) 1998 Todd C. Miller - -Permission to use, copy, modify, and distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright -notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 3.2.7. Thomas -Winischhofer - -Copyright (C) 2001-2004 Thomas Winischhofer - -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 name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. 3.3. NVIDIA Corp - -Copyright (c) 1996 NVIDIA, Corp. All rights reserved. - -NOTICE TO USER: The source code is copyrighted under U.S. and international -laws. NVIDIA, Corp. of Sunnyvale, California owns the copyright and as design -patents pending on the design and interface of the NV chips. Users and -possessors of this source code are hereby granted a nonexclusive, royalty-free -copyright and design patent license to use this code in individual and -commercial software. - -Any use of this source code must include, in the user documentation and -internal comments to the code, notices to the end user as follows: - -Copyright (c) 1996 NVIDIA, Corp. NVIDIA design patents pending in the U.S. and -foreign countries. - -NVIDIA, CORP. MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE -CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED -WARRANTY OF ANY KIND. NVIDIA, CORP. DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORP. BE LIABLE -FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 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 SOURCE CODE. 3.4. GLX Public -License - -GLX PUBLIC LICENSE (Version 1.0 (2/11/99)) ("License") - -Subject to any third party claims, Silicon Graphics, Inc. ("SGI") hereby -grants permission to Recipient (defined below), under Recipient's copyrights -in the Original Software (defined below), to use, copy, modify, merge, -publish, distribute, sublicense and/or sell copies of Subject Software -(defined below), and to permit persons to whom the Subject Software is -furnished in accordance with this License to do the same, subject to all of -the following terms and conditions, which Recipient accepts by engaging in any -such use, copying, modifying, merging, publishing, distributing, sublicensing -or selling: - -1. Definitions. - - (a) "Original Software" means source code of computer software code which - is described in Exhibit A as Original Software. - - (b) "Modifications" means any addition to or deletion from the substance - or structure of either the Original Software or any previous - Modifications. When Subject Software is released as a series of files, a - Modification means (i) any addition to or deletion from the contents of a - file containing Original Software or previous Modifications and (ii) any - new file that contains any part of the Original Code or previous - Modifications. - - (c) "Subject Software" means the Original Software or Modifications or the - combination of the Original Software and Modifications, or portions of any - of the foregoing. - - (d) "Recipient" means an individual or a legal entity exercising rights - under, and complying with all of the terms of, this License. For legal - entities, "Recipient" includes any entity which controls, is controlled - by, or is under common control with Recipient. For purposes of this - definition, "control" of an entity means (a) the power, direct or - indirect, to direct or manage such entity, or (b) ownership of fifty - percent (50%) or more of the outstanding shares or beneficial ownership of - such entity. - -2. Redistribution of Source Code Subject to These Terms. Redistributions of -Subject Software in source code form must retain the notice set forth in -Exhibit A, below, in every file. A copy of this License must be included in -any documentation for such Subject Software where the recipients' rights -relating to Subject Software are described. Recipient may distribute the -source code version of Subject Software under a license of Recipient's choice, -which may contain terms different from this License, provided that (i) -Recipient is in compliance with the terms of this License, and (ii) the -license terms include this Section 2 and Sections 3, 4, 7, 8, 10, 12 and 13 of -this License, which terms may not be modified or superseded by any other terms -of such license. If Recipient distributes the source code version under a -different license Recipient must make it absolutely clear that any terms which -differ from this License are offered by Recipient alone, not by SGI. Recipient -hereby agrees to indemnify SGI for any liability incurred by SGI as a result -of any such terms Recipient offers. - -3. Redistribution in Executable Form. The notice set forth in Exhibit A must -be conspicuously included in any notice in an executable version of Subject -Software, related documentation or collateral in which Recipient describes the -user's rights relating to the Subject Software. Recipient may distribute the -executable version of Subject Software under a license of Recipient's choice, -which may contain terms different from this License, provided that (i) -Recipient is in compliance with the terms of this License, and (ii) the -license terms include this Section 3 and Sections 4, 7, 8, 10, 12 and 13 of -this License, which terms may not be modified or superseded by any other terms -of such license. If Recipient distributes the executable version under a -different license Recipient must make it absolutely clear that any terms which -differ from this License are offered by Recipient alone, not by SGI. Recipient -hereby agrees to indemnify SGI for any liability incurred by SGI as a result -of any such terms Recipient offers. - -4. Termination. This License and the rights granted hereunder will terminate -automatically if Recipient fails to comply with terms herein and fails to cure -such breach within 30 days of the breach. Any sublicense to the Subject -Software which is properly granted shall survive any termination of this -License absent termination by the terms of such sublicense. Provisions which, -by their nature, must remain in effect beyond the termination of this License -shall survive. - -5. No Trademark Rights. This License does not grant any rights to use any -trade name, trademark or service mark whatsoever. No trade name, trademark or -service mark of SGI may be used to endorse or promote products derived from -the Subject Software without prior written permission of SGI. - -6. No Other Rights. This License does not grant any rights with respect to the -OpenGL API or to any software or hardware implementation thereof or to any -other software whatsoever, nor shall any other rights or licenses not -expressly granted hereunder arise by implication, estoppel or otherwise with -respect to the Subject Software. Title to and ownership of the Original -Software at all times remains with SGI. All rights in the Original Software -not expressly granted under this License are reserved. - -7. Compliance with Laws; Non-Infringement. Recipient shall comply with all -applicable laws and regulations in connection with use and distribution of the -Subject Software, including but not limited to, all export and import control -laws and regulations of the U.S. government and other countries. Recipient may -not distribute Subject Software that (i) in any way infringes (directly or -contributorily) the rights (including patent, copyright, trade secret, -trademark or other intellectual property rights of any kind) of any other -person or entity or (ii) breaches any representation or warranty, express, -implied or statutory, which under any applicable law it might be deemed to -have been distributed. - -8. Claims of Infringement. If Recipient at any time has knowledge of any one -or more third party claims that reproduction, modification, use, distribution, -import or sale of Subject Software (including particular functionality or code -incorporated in Subject Software) infringes the third party's intellectual -property rights, Recipient must place in a well-identified web page bearing -the title "LEGAL" a description of each such claim and a description of the -party making each such claim in sufficient detail that a user of the Subject -Software will know whom to contact regarding the claim. Also, upon gaining -such knowledge of any such claim, Recipient must conspicuously include the URL -for such web page in the Exhibit A notice required under Sections 2 and 3, -above, and in the text of any related documentation, license agreement or -collateral in which Recipient describes end user's rights relating to the -Subject Software. If Recipient obtains such knowledge after it makes Subject -Software available to any other person or entity, Recipient shall take other -steps (such as notifying appropriate mailing lists or newsgroups) reasonably -calculated to inform those who received the Subject Software that new -knowledge has been obtained. - -9. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, -WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT -LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, -MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON- INFRINGING. SGI ASSUMES NO -RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE -PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY -SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN -ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED -HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, -WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY), -CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR ANY -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY -CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK -STOPPAGE, LOSS OF DATA, 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 SGI'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 -THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO RECIPIENT. - -11. Indemnity. Recipient shall be solely responsible for damages arising, -directly or indirectly, out of its utilization of rights under this License. -Recipient will defend, indemnify and hold harmless Silicon Graphics, Inc. from -and against any loss, liability, damages, costs or expenses (including the -payment of reasonable attorneys fees) arising out of Recipient's use, -modification, reproduction and distribution of the Subject Software or out of -any representation or warranty made by Recipient. - -12. U.S. Government End Users. The Subject Software is a "commercial item" -consisting of "commercial computer software" as such terms are defined in -title 48 of the Code of Federal Regulations and all U.S. Government End Users -acquire only the rights set forth in this License and are subject to the terms -of this License. - -13. Miscellaneous. This License represents the complete agreement concerning -subject matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed so as to achieve as nearly as -possible the same economic effect as the original provision and the remainder -of this License will remain in effect. This License shall be governed by and -construed in accordance with the laws of the United States and the State of -California as applied to agreements entered into and to be performed entirely -within California between California residents. Any litigation relating to -this License shall be subject to the exclusive jurisdiction of the Federal -Courts of the Northern District of California (or, absent subject matter -jurisdiction in such courts, the courts of the State of California), with -venue lying exclusively in Santa Clara County, California, with the losing -party responsible for costs, including without limitation, court costs and -reasonable attorneys fees and expenses. The application of the United Nations -Convention on Contracts for the International Sale of Goods is expressly -excluded. Any law or regulation which provides that the language of a contract -shall be construed against the drafter shall not apply to this License. - -Exhibit A - -The contents of this file are subject to Sections 2, 3, 4, 7, 8, 10, 12 and 13 -of the GLX Public License Version 1.0 (the "License"). You may not use this -file except in compliance with those sections of the License. You may obtain a -copy of the License at Silicon Graphics, Inc., attn: Legal Services, 2011 N. -Shoreline Blvd., Mountain View, CA 94043 or at -http://www.sgi.com/software/opensource/glx/license.html. - -Software distributed under the License is distributed on an "AS IS" basis. ALL -WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED -WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF NON- -INFRINGEMENT. See the License for the specific language governing rights and -limitations under the License. - -The Original Software is GLX version 1.2 source code, released February, 1999. -The developer of the Original Software is Silicon Graphics, Inc. Those -portions of the Subject Software created by Silicon Graphics, Inc. are -Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved. 3.5. CID -Font Code Public License - -CID FONT CODE PUBLIC LICENSE (Version 1.0 (3/31/99))("License") - -Subject to any applicable third party claims, Silicon Graphics, Inc. ("SGI") -hereby grants permission to Recipient (defined below), under SGI's copyrights -in the Original Software (defined below), to use, copy, modify, merge, -publish, distribute, sublicense and/or sell copies of Subject Software -(defined below) in both source code and executable form, and to permit persons -to whom the Subject Software is furnished in accordance with this License to -do the same, subject to all of the following terms and conditions, which -Recipient accepts by engaging in any such use, copying, modifying, merging, -publication, distributing, sublicensing or selling: - -1. Definitions. - - a. "Original Software" means source code of computer software code that is - described in Exhibit A as Original Software. - - b. "Modifications" means any addition to or deletion from the substance or - structure of either the Original Software or any previous Modifications. - When Subject Software is released as a series of files, a Modification - means (i) any addition to or deletion from the contents of a file - containing Original Software or previous Modifications and (ii) any new - file that contains any part of the Original Code or previous - Modifications. - - c. "Subject Software" means the Original Software or Modifications or the - combination of the Original Software and Modifications, or portions of any - of the foregoing. - - d. "Recipient" means an individual or a legal entity exercising rights - under the terms of this License. For legal entities, "Recipient" includes - any entity that controls, is controlled by, or is under common control - with Recipient. For purposes of this definition, "control" of an entity - means (i) the power, direct or indirect, to direct or manage such entity, - or (ii) ownership of fifty percent (50%) or more of the outstanding shares - or beneficial ownership of such entity. - - e. "Required Notice" means the notice set forth in Exhibit A to this - License. - - f. "Accompanying Technology" means any software or other technology that - is not a Modification and that is distributed or made publicly available - by Recipient with the Subject Software. Separate software files that do - not contain any Original Software or any previous Modification shall not - be deemed a Modification, even if such software files are aggregated as - part of a product, or in any medium of storage, with any file that does - contain Original Software or any previous Modification. - -2. License Terms. All distribution of the Subject Software must be made -subject to the terms of this License. A copy of this License and the Required -Notice must be included in any documentation for Subject Software where -Recipient's rights relating to Subject Software and/or any Accompanying -Technology are described. Distributions of Subject Software in source code -form must also include the Required Notice in every file distributed. In -addition, a ReadMe file entitled "Important Legal Notice" must be distributed -with each distribution of one or more files that incorporate Subject Software. -That file must be included with distributions made in both source code and -executable form. A copy of the License and the Required Notice must be -included in that file. Recipient may distribute Accompanying Technology under -a license of Recipient's choice, which may contain terms different from this -License, provided that (i) Recipient is in compliance with the terms of this -License, (ii) such other license terms do not modify or supersede the terms of -this License as applicable to the Subject Software, (iii) Recipient hereby -indemnifies SGI for any liability incurred by SGI as a result of the -distribution of Accompanying Technology or the use of other license terms. - -3. Termination. This License and the rights granted hereunder will terminate -automatically if Recipient fails to comply with terms herein and fails to cure -such breach within 30 days of the breach. Any sublicense to the Subject -Software that is properly granted shall survive any termination of this -License absent termination by the terms of such sublicense. Provisions which, -by their nature, must remain in effect beyond the termination of this License -shall survive. - -4. Trademark Rights. This License does not grant any rights to use any trade -name, trademark or service mark whatsoever. No trade name, trademark or -service mark of SGI may be used to endorse or promote products derived from or -incorporating any Subject Software without prior written permission of SGI. - -5. No Other Rights. No rights or licenses not expressly granted hereunder -shall arise by implication, estoppel or otherwise. Title to and ownership of -the Original Software at all times remains with SGI. All rights in the -Original Software not expressly granted under this License are reserved. - -6. Compliance with Laws; Non-Infringement. Recipient shall comply with all -applicable laws and regulations in connection with use and distribution of the -Subject Software, including but not limited to, all export and import control -laws and regulations of the U.S. government and other countries. Recipient may -not distribute Subject Software that (i) in any way infringes (directly or -contributorily) the rights (including patent, copyright, trade secret, -trademark or other intellectual property rights of any kind) of any other -person or entity, or (ii) breaches any representation or warranty, express, -implied or statutory, which under any applicable law it might be deemed to -have been distributed. - -7. Claims of Infringement. If Recipient at any time has knowledge of any one -or more third party claims that reproduction, modification, use, distribution, -import or sale of Subject Software (including particular functionality or code -incorporated in Subject Software) infringes the third party's intellectual -property rights, Recipient must place in a well-identified web page bearing -the title "LEGAL" a description of each such claim and a description of the -party making each such claim in sufficient detail that a user of the Subject -Software will know whom to contact regarding the claim. Also, upon gaining -such knowledge of any such claim, Recipient must conspicuously include the URL -for such web page in the Required Notice, and in the text of any related -documentation, license agreement or collateral in which Recipient describes -end user's rights relating to the Subject Software. If Recipient obtains such -knowledge after it makes Subject Software available to any other person or -entity, Recipient shall take other steps (such as notifying appropriate -mailing lists or newsgroups) reasonably calculated to provide such knowledge -to those who received the Subject Software. - -8. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, -WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT -LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, -MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. SGI ASSUMES NO -RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE -PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY -SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN -ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED -HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, -WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY), -CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR 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 SUBJECT SOFTWARE OR -THE USE OR OTHER DEALINGS IN THE SUBJECT SOFTWARE. SOME JURISDICTIONS DO NOT -ALLOW THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES, SO THIS EXCLUSION AND -LIMITATION MAY NOT APPLY TO RECIPIENT TO THE EXTENT SO DISALLOWED. - -10. Indemnity. Recipient shall be solely responsible for damages arising, -directly or indirectly, out of its utilization of rights under this License. -Recipient will defend, indemnify and hold SGI and its successors and assigns -harmless from and against any loss, liability, damages, costs or expenses -(including the payment of reasonable attorneys fees) arising out of -(Recipient's use, modification, reproduction and distribution of the Subject -Software or out of any representation or warranty made by Recipient. - -11. U.S. Government End Users. The Subject Software is a "commercial item" -consisting of "commercial computer software" as such terms are defined in -title 48 of the Code of Federal Regulations and all U.S. Government End Users -acquire only the rights set forth in this License and are subject to the terms -of this License. - -12. Miscellaneous. This License represents the complete agreement concerning -subject matter hereof. If any provision of this License is held to be -unenforceable by any judicial or administrative authority having proper -jurisdiction with respect thereto, such provision shall be reformed so as to -achieve as nearly as possible the same economic effect as the original -provision and the remainder of this License will remain in effect. This -License shall be governed by and construed in accordance with the laws of the -United States and the State of California as applied to agreements entered -into and to be performed entirely within California between California -residents. Any litigation relating to this License shall be subject to the -exclusive jurisdiction of the Federal Courts of the Northern District of -California (or, absent subject matter jurisdiction in such courts, the courts -of the State of California), with venue lying exclusively in Santa Clara -County, California, with the losing party responsible for costs, including -without limitation, court costs and reasonable attorneys fees and expenses. -The application of the United Nations Convention on Contracts for the -International Sale of Goods is expressly excluded. Any law or regulation that -provides that the language of a contract shall be construed against the -drafter shall not apply to this License. - -Exhibit A - -Copyright (c) 1994-1999 Silicon Graphics, Inc. - -The contents of this file are subject to the CID Font Code Public License -Version 1.0 (the "License"). You may not use this file except in compliance -with the License. You may obtain a copy of the License at Silicon Graphics, -Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043 -or at http://www.sgi.com/software/opensource/cid/license.html - -Software distributed under the License is distributed on an "AS IS" basis. ALL -WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED -WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF -NON-INFRINGEMENT. See the License for the specific language governing rights -and limitations under the License. - -The Original Software (as defined in the License) is CID font code that was -developed by Silicon Graphics, Inc. Those portions of the Subject Software (as -defined in the License) that were created by Silicon Graphics, Inc. are -Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. - -[NOTE: When using this text in connection with Subject Software delivered -solely in object code form, Recipient may replace the words "this file" with -"this software" in both the first and second sentences.] 3.6. Bitstream Vera -Fonts Copyright - -The fonts have a generous copyright, allowing derivative works (as long as -"Bitstream" or "Vera" are not in the names), and full redistribution (so long -as they are not *sold* by themselves). They can be be bundled, redistributed -and sold with any software. - -The fonts are distributed under the following copyright: - -Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a -trademark of Bitstream, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of the fonts accompanying this license ("Fonts") and associated documentation -files (the "Font Software"), to reproduce and distribute the Font Software, -including without limitation the rights to use, copy, merge, publish, -distribute, and/or sell copies of the Font Software, and to permit persons to -whom the Font Software is furnished to do so, subject to the following -conditions: - -The above copyright and trademark notices and this permission notice shall be -included in all copies of one or more of the Font Software typefaces. - -The Font Software may be modified, altered, or added to, and in particular the -designs of glyphs or characters in the Fonts may be modified and additional -glyphs or characters may be added to the Fonts, only if the fonts are renamed -to names not containing either the words "Bitstream" or the word "Vera". - -This License becomes null and void to the extent applicable to Fonts or Font -Software that has been modified and is distributed under the "Bitstream Vera" -names. - -The Font Software may be sold as part of a larger software package but no copy -of one or more of the Font Software typefaces may be sold by itself. - -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, -TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, -SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO -USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. - -Except as contained in this notice, the names of Gnome, the Gnome Foundation, -and Bitstream Inc., shall not be used in advertising or otherwise to promote -the sale, use or other dealings in this Font Software without prior written -authorization from the Gnome Foundation or Bitstream Inc., respectively. For -further information, contact: fonts at gnome dot org. 3.7. Bigelow & Holmes -Inc and URW++ GmbH Luxi font license - -Luxi fonts copyright (c) 2001 by Bigelow & Holmes Inc. Luxi font instruction -code copyright (c) 2001 by URW++ GmbH. All Rights Reserved. Luxi is a -registered trademark of Bigelow & Holmes Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of these Fonts and associated documentation files (the "Font Software"), to -deal in the Font Software, including without limitation the rights to use, -copy, merge, publish, distribute, sublicense, and/or sell copies of the Font -Software, and to permit persons to whom the Font Software is furnished to do -so, subject to the following conditions: - -The above copyright and trademark notices and this permission notice shall be -included in all copies of one or more of the Font Software. - -The Font Software may not be modified, altered, or added to, and in particular -the designs of glyphs or characters in the Fonts may not be modified nor may -additional glyphs or characters be added to the Fonts. This License becomes -null and void when the Fonts or Font Software have been modified. - -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, -TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BIGELOW & HOLMES INC. OR URW++ -GMBH. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY -GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR -INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT -SOFTWARE. - -Except as contained in this notice, the names of Bigelow & Holmes Inc. and -URW++ GmbH. shall not be used in advertising or otherwise to promote the sale, -use or other dealings in this Font Software without prior written -authorization from Bigelow & Holmes Inc. and URW++ GmbH. - -For further information, contact: - -info@urwpp.de or design@bigelowandholmes.com - - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to zlib v1.2.5, which may be included -with JRE 8, JDK 8, and OpenJDK 8. - ---- begin of LICENSE --- - - version 1.2.5, July 18th, 2005 - - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - ---- end of LICENSE --- - -------------------------------------------------------------------------------- - -%% This notice is provided with respect to the following which may be -included with JRE 8, JDK 8, and OpenJDK 8, except where noted: - - Apache Commons Math 2.2 - Apache Derby 10.10.1.2 [included with JDK 8] - Apache Jakarta BCEL 5.2 - Apache Jakarta Regexp 1.4 - Apache Santuario XML Security for Java 1.5.4 - Apache Xalan-Java 2.7.1 - Apache Xerces Java 2.10.0 - Apache XML Resolver 1.1 - Dynalink 0.5 - -These components are licensed under the Apache License, Version 2.0. -See /usr/share/common-licenses/Apache-2.0 - -------------------------------------------------------------------------------- - - -=============================================================================== - -debian/dbg8.py: -# Copyright 2016, Red Hat and individual contributors -# by the @authors tag. -# -# This is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. + DAMAGE. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to X Window System 6.8.2, which may be + included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. + . + --- begin of LICENSE --- + . + Licenses + The X.Org Foundation March 2004 + . + 1. Introduction + . + The X.org Foundation X Window System distribution is a compilation of code and + documentation from many sources. This document is intended primarily as a + guide to the licenses used in the distribution: you must check each file + and/or package for precise redistribution terms. None-the-less, this summary + may be useful to many users. No software incorporating the XFree86 1.1 license + has been incorporated. + . + This document is based on the compilation from XFree86. + . + 2. XFree86 License + . + XFree86 code without an explicit copyright is covered by the following + copyright/license: + . + Copyright (C) 1994-2003 The XFree86 Project, Inc. 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 + XFREE86 PROJECT 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. + . + Except as contained in this notice, the name of the XFree86 Project 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 XFree86 Project. + . + 3. Other Licenses + . + Portions of code are covered by the following licenses/copyrights. See + individual files for the copyright dates. + . + 3.1. X/MIT Copyrights + . + 3.1.1. X Consortium + . + Copyright (C) X Consortium + . + 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 X + CONSORTIUM 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. + . + Except as contained in this notice, the name of the X Consortium 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 X Consortium. + . + X Window System is a trademark of X Consortium, Inc. + . + 3.1.2. The Open Group + . + Copyright The Open Group + . + 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. + . + 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. + . + 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. 3.2. + Berkeley-based copyrights: + . + o + 3.2.1. General + . + 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 name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. 3.2.2. UCB/LBL + . + Copyright (c) 1993 The Regents of the University of California. All rights + reserved. + . + This software was developed by the Computer Systems Engineering group at + Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and contributed to + Berkeley. + . + All advertising materials mentioning features or use of this software must + display the following acknowledgement: This product includes software + developed by the University of California, Lawrence Berkeley Laboratory. + . + 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. All advertising materials mentioning features or use of this software + must display the following acknowledgement: This product includes software + developed by the University of California, Berkeley and its contributors. + . + 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. 3.2.3. The + NetBSD Foundation, Inc. + . + Copyright (c) 2003 The NetBSD Foundation, Inc. All rights reserved. + . + This code is derived from software contributed to The NetBSD Foundation by Ben + Collver + . + 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. All advertising materials mentioning features or use of this software + must display the following acknowledgement: This product includes software + developed by the NetBSD Foundation, Inc. and its contributors. + . + 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. 3.2.4. Theodore + Ts'o. + . + Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. 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, + and the entire permission notice in its entirety, including the disclaimer + of warranties. + . + 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. he name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE, ALL OF WHICH ARE HEREBY DISCLAIMED. IN NO + EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. 3.2.5. Theo de Raadt and Damien Miller + . + Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. Copyright (c) + 2001-2002 Damien Miller. All rights reserved. + . + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. 3.2.6. Todd C. Miller + . + Copyright (c) 1998 Todd C. Miller + . + Permission to use, copy, modify, and distribute this software for any purpose + with or without fee is hereby granted, provided that the above copyright + notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 3.2.7. Thomas + Winischhofer + . + Copyright (C) 2001-2004 Thomas Winischhofer + . + 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 name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. 3.3. NVIDIA Corp + . + Copyright (c) 1996 NVIDIA, Corp. All rights reserved. + . + NOTICE TO USER: The source code is copyrighted under U.S. and international + laws. NVIDIA, Corp. of Sunnyvale, California owns the copyright and as design + patents pending on the design and interface of the NV chips. Users and + possessors of this source code are hereby granted a nonexclusive, royalty-free + copyright and design patent license to use this code in individual and + commercial software. + . + Any use of this source code must include, in the user documentation and + internal comments to the code, notices to the end user as follows: + . + Copyright (c) 1996 NVIDIA, Corp. NVIDIA design patents pending in the U.S. and + foreign countries. + . + NVIDIA, CORP. MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED + WARRANTY OF ANY KIND. NVIDIA, CORP. DISCLAIMS ALL WARRANTIES WITH REGARD TO + THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORP. BE LIABLE + FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 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 SOURCE CODE. 3.4. GLX Public + License + . + GLX PUBLIC LICENSE (Version 1.0 (2/11/99)) ("License") + . + Subject to any third party claims, Silicon Graphics, Inc. ("SGI") hereby + grants permission to Recipient (defined below), under Recipient's copyrights + in the Original Software (defined below), to use, copy, modify, merge, + publish, distribute, sublicense and/or sell copies of Subject Software + (defined below), and to permit persons to whom the Subject Software is + furnished in accordance with this License to do the same, subject to all of + the following terms and conditions, which Recipient accepts by engaging in any + such use, copying, modifying, merging, publishing, distributing, sublicensing + or selling: + . + 1. Definitions. + . + (a) "Original Software" means source code of computer software code which + is described in Exhibit A as Original Software. + . + (b) "Modifications" means any addition to or deletion from the substance + or structure of either the Original Software or any previous + Modifications. When Subject Software is released as a series of files, a + Modification means (i) any addition to or deletion from the contents of a + file containing Original Software or previous Modifications and (ii) any + new file that contains any part of the Original Code or previous + Modifications. + . + (c) "Subject Software" means the Original Software or Modifications or the + combination of the Original Software and Modifications, or portions of any + of the foregoing. + . + (d) "Recipient" means an individual or a legal entity exercising rights + under, and complying with all of the terms of, this License. For legal + entities, "Recipient" includes any entity which controls, is controlled + by, or is under common control with Recipient. For purposes of this + definition, "control" of an entity means (a) the power, direct or + indirect, to direct or manage such entity, or (b) ownership of fifty + percent (50%) or more of the outstanding shares or beneficial ownership of + such entity. + . + 2. Redistribution of Source Code Subject to These Terms. Redistributions of + Subject Software in source code form must retain the notice set forth in + Exhibit A, below, in every file. A copy of this License must be included in + any documentation for such Subject Software where the recipients' rights + relating to Subject Software are described. Recipient may distribute the + source code version of Subject Software under a license of Recipient's choice, + which may contain terms different from this License, provided that (i) + Recipient is in compliance with the terms of this License, and (ii) the + license terms include this Section 2 and Sections 3, 4, 7, 8, 10, 12 and 13 of + this License, which terms may not be modified or superseded by any other terms + of such license. If Recipient distributes the source code version under a + different license Recipient must make it absolutely clear that any terms which + differ from this License are offered by Recipient alone, not by SGI. Recipient + hereby agrees to indemnify SGI for any liability incurred by SGI as a result + of any such terms Recipient offers. + . + 3. Redistribution in Executable Form. The notice set forth in Exhibit A must + be conspicuously included in any notice in an executable version of Subject + Software, related documentation or collateral in which Recipient describes the + user's rights relating to the Subject Software. Recipient may distribute the + executable version of Subject Software under a license of Recipient's choice, + which may contain terms different from this License, provided that (i) + Recipient is in compliance with the terms of this License, and (ii) the + license terms include this Section 3 and Sections 4, 7, 8, 10, 12 and 13 of + this License, which terms may not be modified or superseded by any other terms + of such license. If Recipient distributes the executable version under a + different license Recipient must make it absolutely clear that any terms which + differ from this License are offered by Recipient alone, not by SGI. Recipient + hereby agrees to indemnify SGI for any liability incurred by SGI as a result + of any such terms Recipient offers. + . + 4. Termination. This License and the rights granted hereunder will terminate + automatically if Recipient fails to comply with terms herein and fails to cure + such breach within 30 days of the breach. Any sublicense to the Subject + Software which is properly granted shall survive any termination of this + License absent termination by the terms of such sublicense. Provisions which, + by their nature, must remain in effect beyond the termination of this License + shall survive. + . + 5. No Trademark Rights. This License does not grant any rights to use any + trade name, trademark or service mark whatsoever. No trade name, trademark or + service mark of SGI may be used to endorse or promote products derived from + the Subject Software without prior written permission of SGI. + . + 6. No Other Rights. This License does not grant any rights with respect to the + OpenGL API or to any software or hardware implementation thereof or to any + other software whatsoever, nor shall any other rights or licenses not + expressly granted hereunder arise by implication, estoppel or otherwise with + respect to the Subject Software. Title to and ownership of the Original + Software at all times remains with SGI. All rights in the Original Software + not expressly granted under this License are reserved. + . + 7. Compliance with Laws; Non-Infringement. Recipient shall comply with all + applicable laws and regulations in connection with use and distribution of the + Subject Software, including but not limited to, all export and import control + laws and regulations of the U.S. government and other countries. Recipient may + not distribute Subject Software that (i) in any way infringes (directly or + contributorily) the rights (including patent, copyright, trade secret, + trademark or other intellectual property rights of any kind) of any other + person or entity or (ii) breaches any representation or warranty, express, + implied or statutory, which under any applicable law it might be deemed to + have been distributed. + . + 8. Claims of Infringement. If Recipient at any time has knowledge of any one + or more third party claims that reproduction, modification, use, distribution, + import or sale of Subject Software (including particular functionality or code + incorporated in Subject Software) infringes the third party's intellectual + property rights, Recipient must place in a well-identified web page bearing + the title "LEGAL" a description of each such claim and a description of the + party making each such claim in sufficient detail that a user of the Subject + Software will know whom to contact regarding the claim. Also, upon gaining + such knowledge of any such claim, Recipient must conspicuously include the URL + for such web page in the Exhibit A notice required under Sections 2 and 3, + above, and in the text of any related documentation, license agreement or + collateral in which Recipient describes end user's rights relating to the + Subject Software. If Recipient obtains such knowledge after it makes Subject + Software available to any other person or entity, Recipient shall take other + steps (such as notifying appropriate mailing lists or newsgroups) reasonably + calculated to inform those who received the Subject Software that new + knowledge has been obtained. + . + 9. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT + LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, + MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON- INFRINGING. SGI ASSUMES NO + RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE + PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY + SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED + HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + . + 10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, + WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY), + CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR ANY + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK + STOPPAGE, LOSS OF DATA, 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 SGI'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 + THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO RECIPIENT. + . + 11. Indemnity. Recipient shall be solely responsible for damages arising, + directly or indirectly, out of its utilization of rights under this License. + Recipient will defend, indemnify and hold harmless Silicon Graphics, Inc. from + and against any loss, liability, damages, costs or expenses (including the + payment of reasonable attorneys fees) arising out of Recipient's use, + modification, reproduction and distribution of the Subject Software or out of + any representation or warranty made by Recipient. + . + 12. U.S. Government End Users. The Subject Software is a "commercial item" + consisting of "commercial computer software" as such terms are defined in + title 48 of the Code of Federal Regulations and all U.S. Government End Users + acquire only the rights set forth in this License and are subject to the terms + of this License. + . + 13. Miscellaneous. This License represents the complete agreement concerning + subject matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed so as to achieve as nearly as + possible the same economic effect as the original provision and the remainder + of this License will remain in effect. This License shall be governed by and + construed in accordance with the laws of the United States and the State of + California as applied to agreements entered into and to be performed entirely + within California between California residents. Any litigation relating to + this License shall be subject to the exclusive jurisdiction of the Federal + Courts of the Northern District of California (or, absent subject matter + jurisdiction in such courts, the courts of the State of California), with + venue lying exclusively in Santa Clara County, California, with the losing + party responsible for costs, including without limitation, court costs and + reasonable attorneys fees and expenses. The application of the United Nations + Convention on Contracts for the International Sale of Goods is expressly + excluded. Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this License. + . + Exhibit A + . + The contents of this file are subject to Sections 2, 3, 4, 7, 8, 10, 12 and 13 + of the GLX Public License Version 1.0 (the "License"). You may not use this + file except in compliance with those sections of the License. You may obtain a + copy of the License at Silicon Graphics, Inc., attn: Legal Services, 2011 N. + Shoreline Blvd., Mountain View, CA 94043 or at + http://www.sgi.com/software/opensource/glx/license.html. + . + Software distributed under the License is distributed on an "AS IS" basis. ALL + WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF NON- + INFRINGEMENT. See the License for the specific language governing rights and + limitations under the License. + . + The Original Software is GLX version 1.2 source code, released February, 1999. + The developer of the Original Software is Silicon Graphics, Inc. Those + portions of the Subject Software created by Silicon Graphics, Inc. are + Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved. 3.5. CID + Font Code Public License + . + CID FONT CODE PUBLIC LICENSE (Version 1.0 (3/31/99))("License") + . + Subject to any applicable third party claims, Silicon Graphics, Inc. ("SGI") + hereby grants permission to Recipient (defined below), under SGI's copyrights + in the Original Software (defined below), to use, copy, modify, merge, + publish, distribute, sublicense and/or sell copies of Subject Software + (defined below) in both source code and executable form, and to permit persons + to whom the Subject Software is furnished in accordance with this License to + do the same, subject to all of the following terms and conditions, which + Recipient accepts by engaging in any such use, copying, modifying, merging, + publication, distributing, sublicensing or selling: + . + 1. Definitions. + . + a. "Original Software" means source code of computer software code that is + described in Exhibit A as Original Software. + . + b. "Modifications" means any addition to or deletion from the substance or + structure of either the Original Software or any previous Modifications. + When Subject Software is released as a series of files, a Modification + means (i) any addition to or deletion from the contents of a file + containing Original Software or previous Modifications and (ii) any new + file that contains any part of the Original Code or previous + Modifications. + . + c. "Subject Software" means the Original Software or Modifications or the + combination of the Original Software and Modifications, or portions of any + of the foregoing. + . + d. "Recipient" means an individual or a legal entity exercising rights + under the terms of this License. For legal entities, "Recipient" includes + any entity that controls, is controlled by, or is under common control + with Recipient. For purposes of this definition, "control" of an entity + means (i) the power, direct or indirect, to direct or manage such entity, + or (ii) ownership of fifty percent (50%) or more of the outstanding shares + or beneficial ownership of such entity. + . + e. "Required Notice" means the notice set forth in Exhibit A to this + License. + . + f. "Accompanying Technology" means any software or other technology that + is not a Modification and that is distributed or made publicly available + by Recipient with the Subject Software. Separate software files that do + not contain any Original Software or any previous Modification shall not + be deemed a Modification, even if such software files are aggregated as + part of a product, or in any medium of storage, with any file that does + contain Original Software or any previous Modification. + . + 2. License Terms. All distribution of the Subject Software must be made + subject to the terms of this License. A copy of this License and the Required + Notice must be included in any documentation for Subject Software where + Recipient's rights relating to Subject Software and/or any Accompanying + Technology are described. Distributions of Subject Software in source code + form must also include the Required Notice in every file distributed. In + addition, a ReadMe file entitled "Important Legal Notice" must be distributed + with each distribution of one or more files that incorporate Subject Software. + That file must be included with distributions made in both source code and + executable form. A copy of the License and the Required Notice must be + included in that file. Recipient may distribute Accompanying Technology under + a license of Recipient's choice, which may contain terms different from this + License, provided that (i) Recipient is in compliance with the terms of this + License, (ii) such other license terms do not modify or supersede the terms of + this License as applicable to the Subject Software, (iii) Recipient hereby + indemnifies SGI for any liability incurred by SGI as a result of the + distribution of Accompanying Technology or the use of other license terms. + . + 3. Termination. This License and the rights granted hereunder will terminate + automatically if Recipient fails to comply with terms herein and fails to cure + such breach within 30 days of the breach. Any sublicense to the Subject + Software that is properly granted shall survive any termination of this + License absent termination by the terms of such sublicense. Provisions which, + by their nature, must remain in effect beyond the termination of this License + shall survive. + . + 4. Trademark Rights. This License does not grant any rights to use any trade + name, trademark or service mark whatsoever. No trade name, trademark or + service mark of SGI may be used to endorse or promote products derived from or + incorporating any Subject Software without prior written permission of SGI. + . + 5. No Other Rights. No rights or licenses not expressly granted hereunder + shall arise by implication, estoppel or otherwise. Title to and ownership of + the Original Software at all times remains with SGI. All rights in the + Original Software not expressly granted under this License are reserved. + . + 6. Compliance with Laws; Non-Infringement. Recipient shall comply with all + applicable laws and regulations in connection with use and distribution of the + Subject Software, including but not limited to, all export and import control + laws and regulations of the U.S. government and other countries. Recipient may + not distribute Subject Software that (i) in any way infringes (directly or + contributorily) the rights (including patent, copyright, trade secret, + trademark or other intellectual property rights of any kind) of any other + person or entity, or (ii) breaches any representation or warranty, express, + implied or statutory, which under any applicable law it might be deemed to + have been distributed. + . + 7. Claims of Infringement. If Recipient at any time has knowledge of any one + or more third party claims that reproduction, modification, use, distribution, + import or sale of Subject Software (including particular functionality or code + incorporated in Subject Software) infringes the third party's intellectual + property rights, Recipient must place in a well-identified web page bearing + the title "LEGAL" a description of each such claim and a description of the + party making each such claim in sufficient detail that a user of the Subject + Software will know whom to contact regarding the claim. Also, upon gaining + such knowledge of any such claim, Recipient must conspicuously include the URL + for such web page in the Required Notice, and in the text of any related + documentation, license agreement or collateral in which Recipient describes + end user's rights relating to the Subject Software. If Recipient obtains such + knowledge after it makes Subject Software available to any other person or + entity, Recipient shall take other steps (such as notifying appropriate + mailing lists or newsgroups) reasonably calculated to provide such knowledge + to those who received the Subject Software. + . + 8. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT + LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, + MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. SGI ASSUMES NO + RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE + PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY + SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED + HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + . + 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, + WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY), + CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR 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 SUBJECT SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SUBJECT SOFTWARE. SOME JURISDICTIONS DO NOT + ALLOW THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES, SO THIS EXCLUSION AND + LIMITATION MAY NOT APPLY TO RECIPIENT TO THE EXTENT SO DISALLOWED. + . + 10. Indemnity. Recipient shall be solely responsible for damages arising, + directly or indirectly, out of its utilization of rights under this License. + Recipient will defend, indemnify and hold SGI and its successors and assigns + harmless from and against any loss, liability, damages, costs or expenses + (including the payment of reasonable attorneys fees) arising out of + (Recipient's use, modification, reproduction and distribution of the Subject + Software or out of any representation or warranty made by Recipient. + . + 11. U.S. Government End Users. The Subject Software is a "commercial item" + consisting of "commercial computer software" as such terms are defined in + title 48 of the Code of Federal Regulations and all U.S. Government End Users + acquire only the rights set forth in this License and are subject to the terms + of this License. + . + 12. Miscellaneous. This License represents the complete agreement concerning + subject matter hereof. If any provision of this License is held to be + unenforceable by any judicial or administrative authority having proper + jurisdiction with respect thereto, such provision shall be reformed so as to + achieve as nearly as possible the same economic effect as the original + provision and the remainder of this License will remain in effect. This + License shall be governed by and construed in accordance with the laws of the + United States and the State of California as applied to agreements entered + into and to be performed entirely within California between California + residents. Any litigation relating to this License shall be subject to the + exclusive jurisdiction of the Federal Courts of the Northern District of + California (or, absent subject matter jurisdiction in such courts, the courts + of the State of California), with venue lying exclusively in Santa Clara + County, California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys fees and expenses. + The application of the United Nations Convention on Contracts for the + International Sale of Goods is expressly excluded. Any law or regulation that + provides that the language of a contract shall be construed against the + drafter shall not apply to this License. + . + Exhibit A + . + Copyright (c) 1994-1999 Silicon Graphics, Inc. + . + The contents of this file are subject to the CID Font Code Public License + Version 1.0 (the "License"). You may not use this file except in compliance + with the License. You may obtain a copy of the License at Silicon Graphics, + Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043 + or at http://www.sgi.com/software/opensource/cid/license.html + . + Software distributed under the License is distributed on an "AS IS" basis. ALL + WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + NON-INFRINGEMENT. See the License for the specific language governing rights + and limitations under the License. + . + The Original Software (as defined in the License) is CID font code that was + developed by Silicon Graphics, Inc. Those portions of the Subject Software (as + defined in the License) that were created by Silicon Graphics, Inc. are + Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + . + [NOTE: When using this text in connection with Subject Software delivered + solely in object code form, Recipient may replace the words "this file" with + "this software" in both the first and second sentences.] 3.6. Bitstream Vera + Fonts Copyright + . + The fonts have a generous copyright, allowing derivative works (as long as + "Bitstream" or "Vera" are not in the names), and full redistribution (so long + as they are not *sold* by themselves). They can be be bundled, redistributed + and sold with any software. + . + The fonts are distributed under the following copyright: + . + Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a + trademark of Bitstream, Inc. + . + Permission is hereby granted, free of charge, to any person obtaining a copy + of the fonts accompanying this license ("Fonts") and associated documentation + files (the "Font Software"), to reproduce and distribute the Font Software, + including without limitation the rights to use, copy, merge, publish, + distribute, and/or sell copies of the Font Software, and to permit persons to + whom the Font Software is furnished to do so, subject to the following + conditions: + . + The above copyright and trademark notices and this permission notice shall be + included in all copies of one or more of the Font Software typefaces. + . + The Font Software may be modified, altered, or added to, and in particular the + designs of glyphs or characters in the Fonts may be modified and additional + glyphs or characters may be added to the Fonts, only if the fonts are renamed + to names not containing either the words "Bitstream" or the word "Vera". + . + This License becomes null and void to the extent applicable to Fonts or Font + Software that has been modified and is distributed under the "Bitstream Vera" + names. + . + The Font Software may be sold as part of a larger software package but no copy + of one or more of the Font Software typefaces may be sold by itself. + . + THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, + TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, + SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO + USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. + . + Except as contained in this notice, the names of Gnome, the Gnome Foundation, + and Bitstream Inc., shall not be used in advertising or otherwise to promote + the sale, use or other dealings in this Font Software without prior written + authorization from the Gnome Foundation or Bitstream Inc., respectively. For + further information, contact: fonts at gnome dot org. 3.7. Bigelow & Holmes + Inc and URW++ GmbH Luxi font license + . + Luxi fonts copyright (c) 2001 by Bigelow & Holmes Inc. Luxi font instruction + code copyright (c) 2001 by URW++ GmbH. All Rights Reserved. Luxi is a + registered trademark of Bigelow & Holmes Inc. + . + Permission is hereby granted, free of charge, to any person obtaining a copy + of these Fonts and associated documentation files (the "Font Software"), to + deal in the Font Software, including without limitation the rights to use, + copy, merge, publish, distribute, sublicense, and/or sell copies of the Font + Software, and to permit persons to whom the Font Software is furnished to do + so, subject to the following conditions: + . + The above copyright and trademark notices and this permission notice shall be + included in all copies of one or more of the Font Software. + . + The Font Software may not be modified, altered, or added to, and in particular + the designs of glyphs or characters in the Fonts may not be modified nor may + additional glyphs or characters be added to the Fonts. This License becomes + null and void when the Fonts or Font Software have been modified. + . + THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, + TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BIGELOW & HOLMES INC. OR URW++ + GMBH. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY + GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR + INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT + SOFTWARE. + . + Except as contained in this notice, the names of Bigelow & Holmes Inc. and + URW++ GmbH. shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Font Software without prior written + authorization from Bigelow & Holmes Inc. and URW++ GmbH. + . + For further information, contact: + . + info@urwpp.de or design@bigelowandholmes.com + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to zlib v1.2.5, which may be included + with JRE 8, JDK 8, and OpenJDK 8. + . + --- begin of LICENSE --- + . + version 1.2.5, July 18th, 2005 + . + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + . + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + . + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + . + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + . + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + . + %% This notice is provided with respect to the following which may be + included with JRE 8, JDK 8, and OpenJDK 8, except where noted: + . + Apache Commons Math 2.2 + Apache Derby 10.10.1.2 [included with JDK 8] + Apache Jakarta BCEL 5.2 + Apache Jakarta Regexp 1.4 + Apache Santuario XML Security for Java 1.5.4 + Apache Xalan-Java 2.7.1 + Apache Xerces Java 2.10.0 + Apache XML Resolver 1.1 + Dynalink 0.5 + . + These components are licensed under the Apache License, Version 2.0. + See /usr/share/common-licenses/Apache-2.0 + . + ------------------------------------------------------------------------------ + . + . + ============================================================================== + +Files: debian/* +Copyright: Copyright © 2007-2023 Canonical Ltd. +License: MIT + 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. -On Debian systems a full copy of the GNU General Public License, GPL, can be -found in the file /usr/share/common-licenses/GPL-2. +Files: debian/dbg.py +Copyright: Copyright 2016, Red Hat and individual contributors +License: LGPL + # Copyright 2016, Red Hat and individual contributors + # by the @authors tag. + # + # This is free software; you can redistribute it and/or modify it + # under the terms of the GNU Lesser General Public License as + # published by the Free Software Foundation; either version 2.1 of + # the License, or (at your option) any later version. + # + # This software is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + # Lesser General Public License for more details. + . + On Debian systems a full copy of the GNU General Public License, GPL, can be + found in the file /usr/share/common-licenses/GPL-2. diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/8276799.diff openjdk-17-17.0.8+7/debian/patches/8276799.diff --- openjdk-17-17.0.7+7~us1/debian/patches/8276799.diff 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/8276799.diff 2023-07-12 12:32:17.000000000 +0000 @@ -0,0 +1,61916 @@ +--- a/make/autoconf/build-aux/config.sub ++++ b/make/autoconf/build-aux/config.sub +@@ -1,6 +1,6 @@ + #!/bin/sh + # +-# Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. ++# Copyright (c) 2014, 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 +@@ -46,6 +46,13 @@ if echo $* | grep pc-msys >/dev/null ; t + exit + fi + ++# Canonicalize for riscv which autoconf-config.sub doesn't handle ++if echo $* | grep '^riscv\(32\|64\)-linux' >/dev/null ; then ++ result=`echo $@ | sed 's/linux/unknown-linux/'` ++ echo $result ++ exit ++fi ++ + # Filter out everything that doesn't begin with "aarch64-" + if ! echo $* | grep '^aarch64-' >/dev/null ; then + . $DIR/autoconf-config.sub "$@" +@@ -78,4 +85,3 @@ result=`echo $result | sed "s/^arm-/aarc + + echo $result + exit $exitcode +- +--- a/make/autoconf/jvm-features.m4 ++++ b/make/autoconf/jvm-features.m4 +@@ -311,7 +311,8 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_SHENAN + AC_MSG_CHECKING([if platform is supported by Shenandoah]) + if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86" || \ + test "x$OPENJDK_TARGET_CPU" = "xaarch64" || \ +- test "x$OPENJDK_TARGET_CPU" = "xppc64le"; then ++ test "x$OPENJDK_TARGET_CPU" = "xppc64le" || \ ++ test "x$OPENJDK_TARGET_CPU" = "xriscv64"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU]) +@@ -361,7 +362,8 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_ZGC], + AC_MSG_RESULT([no, $OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU]) + AVAILABLE=false + fi +- elif test "x$OPENJDK_TARGET_CPU" = "xppc64le"; then ++ elif test "x$OPENJDK_TARGET_CPU" = "xppc64le" || \ ++ test "x$OPENJDK_TARGET_CPU" = "xriscv64"; then + if test "x$OPENJDK_TARGET_OS" = "xlinux"; then + AC_MSG_RESULT([yes]) + else +--- a/make/autoconf/libraries.m4 ++++ b/make/autoconf/libraries.m4 +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. ++# Copyright (c) 2011, 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 +@@ -146,6 +146,12 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES], + fi + fi + ++ # Because RISC-V only has word-sized atomics, it requries libatomic where ++ # other common architectures do not. So link libatomic by default. ++ if test "x$OPENJDK_TARGET_OS" = xlinux && test "x$OPENJDK_TARGET_CPU" = xriscv64; then ++ BASIC_JVM_LIBS="$BASIC_JVM_LIBS -latomic" ++ fi ++ + # perfstat lib + if test "x$OPENJDK_TARGET_OS" = xaix; then + BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lperfstat" +--- a/make/autoconf/platform.m4 ++++ b/make/autoconf/platform.m4 +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. ++# Copyright (c) 2011, 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 +@@ -565,6 +565,8 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HEL + HOTSPOT_$1_CPU_DEFINE=PPC64 + elif test "x$OPENJDK_$1_CPU" = xppc64le; then + HOTSPOT_$1_CPU_DEFINE=PPC64 ++ elif test "x$OPENJDK_$1_CPU" = xriscv64; then ++ HOTSPOT_$1_CPU_DEFINE=RISCV64 + + # The cpu defines below are for zero, we don't support them directly. + elif test "x$OPENJDK_$1_CPU" = xsparc; then +@@ -575,8 +577,6 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HEL + HOTSPOT_$1_CPU_DEFINE=S390 + elif test "x$OPENJDK_$1_CPU" = xs390x; then + HOTSPOT_$1_CPU_DEFINE=S390 +- elif test "x$OPENJDK_$1_CPU" = xriscv64; then +- HOTSPOT_$1_CPU_DEFINE=RISCV + elif test "x$OPENJDK_$1_CPU" != x; then + HOTSPOT_$1_CPU_DEFINE=$(echo $OPENJDK_$1_CPU | tr a-z A-Z) + fi +--- a/make/hotspot/gensrc/GensrcAdlc.gmk ++++ b/make/hotspot/gensrc/GensrcAdlc.gmk +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. ++# Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + # + # This code is free software; you can redistribute it and/or modify it +@@ -149,6 +149,13 @@ ifeq ($(call check-jvm-feature, compiler + ))) + endif + ++ ifeq ($(HOTSPOT_TARGET_CPU_ARCH), riscv) ++ AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \ ++ $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_CPU_ARCH)_v.ad \ ++ $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_CPU_ARCH)_b.ad \ ++ ))) ++ endif ++ + ifeq ($(call check-jvm-feature, shenandoahgc), true) + AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \ + $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/gc/shenandoah/shenandoah_$(HOTSPOT_TARGET_CPU).ad \ +--- /dev/null ++++ b/src/hotspot/cpu/riscv/abstractInterpreter_riscv.cpp +@@ -0,0 +1,177 @@ ++/* ++ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "interpreter/interpreter.hpp" ++#include "oops/constMethod.hpp" ++#include "oops/klass.inline.hpp" ++#include "oops/method.hpp" ++#include "runtime/frame.inline.hpp" ++#include "utilities/align.hpp" ++#include "utilities/debug.hpp" ++#include "utilities/macros.hpp" ++ ++int AbstractInterpreter::BasicType_as_index(BasicType type) { ++ int i = 0; ++ switch (type) { ++ case T_BOOLEAN: i = 0; break; ++ case T_CHAR : i = 1; break; ++ case T_BYTE : i = 2; break; ++ case T_SHORT : i = 3; break; ++ case T_INT : i = 4; break; ++ case T_LONG : i = 5; break; ++ case T_VOID : i = 6; break; ++ case T_FLOAT : i = 7; break; ++ case T_DOUBLE : i = 8; break; ++ case T_OBJECT : i = 9; break; ++ case T_ARRAY : i = 9; break; ++ default : ShouldNotReachHere(); ++ } ++ assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, ++ "index out of bounds"); ++ return i; ++} ++ ++// How much stack a method activation needs in words. ++int AbstractInterpreter::size_top_interpreter_activation(Method* method) { ++ const int entry_size = frame::interpreter_frame_monitor_size(); ++ ++ // total overhead size: entry_size + (saved fp thru expr stack ++ // bottom). be sure to change this if you add/subtract anything ++ // to/from the overhead area ++ const int overhead_size = ++ -(frame::interpreter_frame_initial_sp_offset) + entry_size; ++ ++ const int stub_code = frame::entry_frame_after_call_words; ++ assert_cond(method != NULL); ++ const int method_stack = (method->max_locals() + method->max_stack()) * ++ Interpreter::stackElementWords; ++ return (overhead_size + method_stack + stub_code); ++} ++ ++// asm based interpreter deoptimization helpers ++int AbstractInterpreter::size_activation(int max_stack, ++ int temps, ++ int extra_args, ++ int monitors, ++ int callee_params, ++ int callee_locals, ++ bool is_top_frame) { ++ // Note: This calculation must exactly parallel the frame setup ++ // in TemplateInterpreterGenerator::generate_method_entry. ++ ++ // fixed size of an interpreter frame: ++ int overhead = frame::sender_sp_offset - ++ frame::interpreter_frame_initial_sp_offset; ++ // Our locals were accounted for by the caller (or last_frame_adjust ++ // on the transistion) Since the callee parameters already account ++ // for the callee's params we only need to account for the extra ++ // locals. ++ int size = overhead + ++ (callee_locals - callee_params) + ++ monitors * frame::interpreter_frame_monitor_size() + ++ // On the top frame, at all times SP <= ESP, and SP is ++ // 16-aligned. We ensure this by adjusting SP on method ++ // entry and re-entry to allow room for the maximum size of ++ // the expression stack. When we call another method we bump ++ // SP so that no stack space is wasted. So, only on the top ++ // frame do we need to allow max_stack words. ++ (is_top_frame ? max_stack : temps + extra_args); ++ ++ // On riscv we always keep the stack pointer 16-aligned, so we ++ // must round up here. ++ size = align_up(size, 2); ++ ++ return size; ++} ++ ++void AbstractInterpreter::layout_activation(Method* method, ++ int tempcount, ++ int popframe_extra_args, ++ int moncount, ++ int caller_actual_parameters, ++ int callee_param_count, ++ int callee_locals, ++ frame* caller, ++ frame* interpreter_frame, ++ bool is_top_frame, ++ bool is_bottom_frame) { ++ // The frame interpreter_frame is guaranteed to be the right size, ++ // as determined by a previous call to the size_activation() method. ++ // It is also guaranteed to be walkable even though it is in a ++ // skeletal state ++ assert_cond(method != NULL && caller != NULL && interpreter_frame != NULL); ++ int max_locals = method->max_locals() * Interpreter::stackElementWords; ++ int extra_locals = (method->max_locals() - method->size_of_parameters()) * ++ Interpreter::stackElementWords; ++ ++#ifdef ASSERT ++ assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable"); ++#endif ++ ++ interpreter_frame->interpreter_frame_set_method(method); ++ // NOTE the difference in using sender_sp and interpreter_frame_sender_sp ++ // interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp) ++ // and sender_sp is fp ++ intptr_t* locals = NULL; ++ if (caller->is_interpreted_frame()) { ++ locals = caller->interpreter_frame_last_sp() + caller_actual_parameters - 1; ++ } else { ++ locals = interpreter_frame->sender_sp() + max_locals - 1; ++ } ++ ++#ifdef ASSERT ++ if (caller->is_interpreted_frame()) { ++ assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); ++ } ++#endif ++ ++ interpreter_frame->interpreter_frame_set_locals(locals); ++ BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); ++ BasicObjectLock* monbot = montop - moncount; ++ interpreter_frame->interpreter_frame_set_monitor_end(monbot); ++ ++ // Set last_sp ++ intptr_t* last_sp = (intptr_t*) monbot - ++ tempcount*Interpreter::stackElementWords - ++ popframe_extra_args; ++ interpreter_frame->interpreter_frame_set_last_sp(last_sp); ++ ++ // All frames but the initial (oldest) interpreter frame we fill in have ++ // a value for sender_sp that allows walking the stack but isn't ++ // truly correct. Correct the value here. ++ if (extra_locals != 0 && ++ interpreter_frame->sender_sp() == ++ interpreter_frame->interpreter_frame_sender_sp()) { ++ interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + ++ extra_locals); ++ } ++ ++ *interpreter_frame->interpreter_frame_cache_addr() = ++ method->constants()->cache(); ++ *interpreter_frame->interpreter_frame_mirror_addr() = ++ method->method_holder()->java_mirror(); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/assembler_riscv.cpp +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include ++#include ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "asm/assembler.inline.hpp" ++#include "compiler/disassembler.hpp" ++#include "interpreter/interpreter.hpp" ++#include "memory/resourceArea.hpp" ++#include "runtime/interfaceSupport.inline.hpp" ++#include "runtime/sharedRuntime.hpp" ++ ++int AbstractAssembler::code_fill_byte() { ++ return 0; ++} ++ ++Address::Address(address target, relocInfo::relocType rtype) : _base(noreg), _offset(0), _mode(literal) { ++ _target = target; ++ switch (rtype) { ++ case relocInfo::oop_type: ++ case relocInfo::metadata_type: ++ // Oops are a special case. Normally they would be their own section ++ // but in cases like icBuffer they are literals in the code stream that ++ // we don't have a section for. We use none so that we get a literal address ++ // which is always patchable. ++ break; ++ case relocInfo::external_word_type: ++ _rspec = external_word_Relocation::spec(target); ++ break; ++ case relocInfo::internal_word_type: ++ _rspec = internal_word_Relocation::spec(target); ++ break; ++ case relocInfo::opt_virtual_call_type: ++ _rspec = opt_virtual_call_Relocation::spec(); ++ break; ++ case relocInfo::static_call_type: ++ _rspec = static_call_Relocation::spec(); ++ break; ++ case relocInfo::runtime_call_type: ++ _rspec = runtime_call_Relocation::spec(); ++ break; ++ case relocInfo::poll_type: ++ case relocInfo::poll_return_type: ++ _rspec = Relocation::spec_simple(rtype); ++ break; ++ case relocInfo::none: ++ _rspec = RelocationHolder::none; ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp +@@ -0,0 +1,2764 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_ASSEMBLER_RISCV_HPP ++#define CPU_RISCV_ASSEMBLER_RISCV_HPP ++ ++#include "asm/register.hpp" ++#include "code/codeCache.hpp" ++#include "metaprogramming/enableIf.hpp" ++ ++#define XLEN 64 ++ ++// definitions of various symbolic names for machine registers ++ ++// First intercalls between C and Java which use 8 general registers ++// and 8 floating registers ++ ++class Argument { ++ public: ++ enum { ++ n_int_register_parameters_c = 8, // x10, x11, ... x17 (c_rarg0, c_rarg1, ...) ++ n_float_register_parameters_c = 8, // f10, f11, ... f17 (c_farg0, c_farg1, ... ) ++ ++ n_int_register_parameters_j = 8, // x11, ... x17, x10 (j_rarg0, j_rarg1, ...) ++ n_float_register_parameters_j = 8 // f10, f11, ... f17 (j_farg0, j_farg1, ...) ++ }; ++}; ++ ++// function argument(caller-save registers) ++REGISTER_DECLARATION(Register, c_rarg0, x10); ++REGISTER_DECLARATION(Register, c_rarg1, x11); ++REGISTER_DECLARATION(Register, c_rarg2, x12); ++REGISTER_DECLARATION(Register, c_rarg3, x13); ++REGISTER_DECLARATION(Register, c_rarg4, x14); ++REGISTER_DECLARATION(Register, c_rarg5, x15); ++REGISTER_DECLARATION(Register, c_rarg6, x16); ++REGISTER_DECLARATION(Register, c_rarg7, x17); ++ ++REGISTER_DECLARATION(FloatRegister, c_farg0, f10); ++REGISTER_DECLARATION(FloatRegister, c_farg1, f11); ++REGISTER_DECLARATION(FloatRegister, c_farg2, f12); ++REGISTER_DECLARATION(FloatRegister, c_farg3, f13); ++REGISTER_DECLARATION(FloatRegister, c_farg4, f14); ++REGISTER_DECLARATION(FloatRegister, c_farg5, f15); ++REGISTER_DECLARATION(FloatRegister, c_farg6, f16); ++REGISTER_DECLARATION(FloatRegister, c_farg7, f17); ++ ++// Symbolically name the register arguments used by the Java calling convention. ++// We have control over the convention for java so we can do what we please. ++// What pleases us is to offset the java calling convention so that when ++// we call a suitable jni method the arguments are lined up and we don't ++// have to do much shuffling. A suitable jni method is non-static and a ++// small number of arguments. ++// ++// |------------------------------------------------------------------------| ++// | c_rarg0 c_rarg1 c_rarg2 c_rarg3 c_rarg4 c_rarg5 c_rarg6 c_rarg7 | ++// |------------------------------------------------------------------------| ++// | x10 x11 x12 x13 x14 x15 x16 x17 | ++// |------------------------------------------------------------------------| ++// | j_rarg7 j_rarg0 j_rarg1 j_rarg2 j_rarg3 j_rarg4 j_rarg5 j_rarg6 | ++// |------------------------------------------------------------------------| ++ ++REGISTER_DECLARATION(Register, j_rarg0, c_rarg1); ++REGISTER_DECLARATION(Register, j_rarg1, c_rarg2); ++REGISTER_DECLARATION(Register, j_rarg2, c_rarg3); ++REGISTER_DECLARATION(Register, j_rarg3, c_rarg4); ++REGISTER_DECLARATION(Register, j_rarg4, c_rarg5); ++REGISTER_DECLARATION(Register, j_rarg5, c_rarg6); ++REGISTER_DECLARATION(Register, j_rarg6, c_rarg7); ++REGISTER_DECLARATION(Register, j_rarg7, c_rarg0); ++ ++// Java floating args are passed as per C ++ ++REGISTER_DECLARATION(FloatRegister, j_farg0, f10); ++REGISTER_DECLARATION(FloatRegister, j_farg1, f11); ++REGISTER_DECLARATION(FloatRegister, j_farg2, f12); ++REGISTER_DECLARATION(FloatRegister, j_farg3, f13); ++REGISTER_DECLARATION(FloatRegister, j_farg4, f14); ++REGISTER_DECLARATION(FloatRegister, j_farg5, f15); ++REGISTER_DECLARATION(FloatRegister, j_farg6, f16); ++REGISTER_DECLARATION(FloatRegister, j_farg7, f17); ++ ++// zero rigster ++REGISTER_DECLARATION(Register, zr, x0); ++// global pointer ++REGISTER_DECLARATION(Register, gp, x3); ++// thread pointer ++REGISTER_DECLARATION(Register, tp, x4); ++ ++// registers used to hold VM data either temporarily within a method ++// or across method calls ++ ++// volatile (caller-save) registers ++ ++// current method -- must be in a call-clobbered register ++REGISTER_DECLARATION(Register, xmethod, x31); ++// return address ++REGISTER_DECLARATION(Register, ra, x1); ++ ++// non-volatile (callee-save) registers ++ ++// stack pointer ++REGISTER_DECLARATION(Register, sp, x2); ++// frame pointer ++REGISTER_DECLARATION(Register, fp, x8); ++// base of heap ++REGISTER_DECLARATION(Register, xheapbase, x27); ++// constant pool cache ++REGISTER_DECLARATION(Register, xcpool, x26); ++// monitors allocated on stack ++REGISTER_DECLARATION(Register, xmonitors, x25); ++// locals on stack ++REGISTER_DECLARATION(Register, xlocals, x24); ++ ++// java thread pointer ++REGISTER_DECLARATION(Register, xthread, x23); ++// bytecode pointer ++REGISTER_DECLARATION(Register, xbcp, x22); ++// Dispatch table base ++REGISTER_DECLARATION(Register, xdispatch, x21); ++// Java stack pointer ++REGISTER_DECLARATION(Register, esp, x20); ++ ++// temporary register(caller-save registers) ++REGISTER_DECLARATION(Register, t0, x5); ++REGISTER_DECLARATION(Register, t1, x6); ++REGISTER_DECLARATION(Register, t2, x7); ++ ++const Register g_INTArgReg[Argument::n_int_register_parameters_c] = { ++ c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, c_rarg5, c_rarg6, c_rarg7 ++}; ++ ++const FloatRegister g_FPArgReg[Argument::n_float_register_parameters_c] = { ++ c_farg0, c_farg1, c_farg2, c_farg3, c_farg4, c_farg5, c_farg6, c_farg7 ++}; ++ ++#define assert_cond(ARG1) assert(ARG1, #ARG1) ++ ++// Addressing modes ++class Address { ++ public: ++ ++ enum mode { no_mode, base_plus_offset, pcrel, literal }; ++ ++ private: ++ Register _base; ++ Register _index; ++ int64_t _offset; ++ enum mode _mode; ++ ++ RelocationHolder _rspec; ++ ++ // If the target is far we'll need to load the ea of this to a ++ // register to reach it. Otherwise if near we can do PC-relative ++ // addressing. ++ address _target; ++ ++ public: ++ Address() ++ : _base(noreg), _index(noreg), _offset(0), _mode(no_mode), _target(NULL) { } ++ ++ Address(Register r) ++ : _base(r), _index(noreg), _offset(0), _mode(base_plus_offset), _target(NULL) { } ++ ++ template::value)> ++ Address(Register r, T o) ++ : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(NULL) {} ++ ++ Address(Register r, ByteSize disp) ++ : Address(r, in_bytes(disp)) {} ++ ++ Address(address target, RelocationHolder const& rspec) ++ : _base(noreg), ++ _index(noreg), ++ _offset(0), ++ _mode(literal), ++ _rspec(rspec), ++ _target(target) { } ++ ++ Address(address target, relocInfo::relocType rtype = relocInfo::external_word_type); ++ ++ const Register base() const { ++ guarantee((_mode == base_plus_offset | _mode == pcrel | _mode == literal), "wrong mode"); ++ return _base; ++ } ++ long offset() const { ++ return _offset; ++ } ++ Register index() const { ++ return _index; ++ } ++ mode getMode() const { ++ return _mode; ++ } ++ ++ bool uses(Register reg) const { return _base == reg; } ++ const address target() const { return _target; } ++ const RelocationHolder& rspec() const { return _rspec; } ++ ~Address() { ++ _target = NULL; ++ _base = NULL; ++ } ++}; ++ ++// Convience classes ++class RuntimeAddress: public Address { ++ ++ public: ++ ++ RuntimeAddress(address target) : Address(target, relocInfo::runtime_call_type) {} ++ ~RuntimeAddress() {} ++}; ++ ++class OopAddress: public Address { ++ ++ public: ++ ++ OopAddress(address target) : Address(target, relocInfo::oop_type) {} ++ ~OopAddress() {} ++}; ++ ++class ExternalAddress: public Address { ++ private: ++ static relocInfo::relocType reloc_for_target(address target) { ++ // Sometimes ExternalAddress is used for values which aren't ++ // exactly addresses, like the card table base. ++ // external_word_type can't be used for values in the first page ++ // so just skip the reloc in that case. ++ return external_word_Relocation::can_be_relocated(target) ? relocInfo::external_word_type : relocInfo::none; ++ } ++ ++ public: ++ ++ ExternalAddress(address target) : Address(target, reloc_for_target(target)) {} ++ ~ExternalAddress() {} ++}; ++ ++class InternalAddress: public Address { ++ ++ public: ++ ++ InternalAddress(address target) : Address(target, relocInfo::internal_word_type) {} ++ ~InternalAddress() {} ++}; ++ ++class Assembler : public AbstractAssembler { ++public: ++ ++ enum { ++ instruction_size = 4, ++ compressed_instruction_size = 2, ++ }; ++ ++ // instruction must start at passed address ++ static bool is_compressed_instr(address instr) { ++ // The RISC-V ISA Manual, Section 'Base Instruction-Length Encoding': ++ // Instructions are stored in memory as a sequence of 16-bit little-endian parcels, regardless of ++ // memory system endianness. Parcels forming one instruction are stored at increasing halfword ++ // addresses, with the lowest-addressed parcel holding the lowest-numbered bits in the instruction ++ // specification. ++ if (UseRVC && (((uint16_t *)instr)[0] & 0b11) != 0b11) { ++ // 16-bit instructions have their lowest two bits equal to 0b00, 0b01, or 0b10 ++ return true; ++ } ++ // 32-bit instructions have their lowest two bits set to 0b11 ++ return false; ++ } ++ ++ //---< calculate length of instruction >--- ++ // We just use the values set above. ++ // instruction must start at passed address ++ static unsigned int instr_len(address instr) { ++ return is_compressed_instr(instr) ? compressed_instruction_size : instruction_size; ++ } ++ ++ //---< longest instructions >--- ++ static unsigned int instr_maxlen() { return instruction_size; } ++ ++ enum RoundingMode { ++ rne = 0b000, // round to Nearest, ties to Even ++ rtz = 0b001, // round towards Zero ++ rdn = 0b010, // round Down (towards eegative infinity) ++ rup = 0b011, // round Up (towards infinity) ++ rmm = 0b100, // round to Nearest, ties to Max Magnitude ++ rdy = 0b111, // in instruction's rm field, selects dynamic rounding mode.In Rounding Mode register, Invalid. ++ }; ++ ++ static inline uint32_t extract(uint32_t val, unsigned msb, unsigned lsb) { ++ assert_cond(msb >= lsb && msb <= 31); ++ unsigned nbits = msb - lsb + 1; ++ uint32_t mask = (1U << nbits) - 1; ++ uint32_t result = val >> lsb; ++ result &= mask; ++ return result; ++ } ++ ++ static inline int32_t sextract(uint32_t val, unsigned msb, unsigned lsb) { ++ assert_cond(msb >= lsb && msb <= 31); ++ int32_t result = val << (31 - msb); ++ result >>= (31 - msb + lsb); ++ return result; ++ } ++ ++ static void patch(address a, unsigned msb, unsigned lsb, unsigned val) { ++ assert_cond(a != NULL); ++ assert_cond(msb >= lsb && msb <= 31); ++ unsigned nbits = msb - lsb + 1; ++ guarantee(val < (1U << nbits), "Field too big for insn"); ++ unsigned mask = (1U << nbits) - 1; ++ val <<= lsb; ++ mask <<= lsb; ++ unsigned target = *(unsigned *)a; ++ target &= ~mask; ++ target |= val; ++ *(unsigned *)a = target; ++ } ++ ++ static void patch(address a, unsigned bit, unsigned val) { ++ patch(a, bit, bit, val); ++ } ++ ++ static void patch_reg(address a, unsigned lsb, Register reg) { ++ patch(a, lsb + 4, lsb, reg->encoding_nocheck()); ++ } ++ ++ static void patch_reg(address a, unsigned lsb, FloatRegister reg) { ++ patch(a, lsb + 4, lsb, reg->encoding_nocheck()); ++ } ++ ++ static void patch_reg(address a, unsigned lsb, VectorRegister reg) { ++ patch(a, lsb + 4, lsb, reg->encoding_nocheck()); ++ } ++ ++ void emit(unsigned insn) { ++ emit_int32((jint)insn); ++ } ++ ++ enum csr { ++ cycle = 0xc00, ++ time, ++ instret, ++ hpmcounter3, ++ hpmcounter4, ++ hpmcounter5, ++ hpmcounter6, ++ hpmcounter7, ++ hpmcounter8, ++ hpmcounter9, ++ hpmcounter10, ++ hpmcounter11, ++ hpmcounter12, ++ hpmcounter13, ++ hpmcounter14, ++ hpmcounter15, ++ hpmcounter16, ++ hpmcounter17, ++ hpmcounter18, ++ hpmcounter19, ++ hpmcounter20, ++ hpmcounter21, ++ hpmcounter22, ++ hpmcounter23, ++ hpmcounter24, ++ hpmcounter25, ++ hpmcounter26, ++ hpmcounter27, ++ hpmcounter28, ++ hpmcounter29, ++ hpmcounter30, ++ hpmcounter31 = 0xc1f ++ }; ++ ++ // Emit an illegal instruction that's known to trap, with 32 read-only CSR ++ // to choose as the input operand. ++ // According to the RISC-V Assembly Programmer's Manual, a de facto implementation ++ // of this instruction is the UNIMP pseduo-instruction, 'CSRRW x0, cycle, x0', ++ // attempting to write zero to a read-only CSR 'cycle' (0xC00). ++ // RISC-V ISAs provide a set of up to 32 read-only CSR registers 0xC00-0xC1F, ++ // and an attempt to write into any read-only CSR (whether it exists or not) ++ // will generate an illegal instruction exception. ++ void illegal_instruction(csr csr_reg) { ++ csrrw(x0, (unsigned)csr_reg, x0); ++ } ++ ++// Register Instruction ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ emit(insn); \ ++ } ++ ++ INSN(_add, 0b0110011, 0b000, 0b0000000); ++ INSN(_sub, 0b0110011, 0b000, 0b0100000); ++ INSN(_andr, 0b0110011, 0b111, 0b0000000); ++ INSN(_orr, 0b0110011, 0b110, 0b0000000); ++ INSN(_xorr, 0b0110011, 0b100, 0b0000000); ++ INSN(sll, 0b0110011, 0b001, 0b0000000); ++ INSN(sra, 0b0110011, 0b101, 0b0100000); ++ INSN(srl, 0b0110011, 0b101, 0b0000000); ++ INSN(slt, 0b0110011, 0b010, 0b0000000); ++ INSN(sltu, 0b0110011, 0b011, 0b0000000); ++ INSN(_addw, 0b0111011, 0b000, 0b0000000); ++ INSN(_subw, 0b0111011, 0b000, 0b0100000); ++ INSN(sllw, 0b0111011, 0b001, 0b0000000); ++ INSN(sraw, 0b0111011, 0b101, 0b0100000); ++ INSN(srlw, 0b0111011, 0b101, 0b0000000); ++ INSN(mul, 0b0110011, 0b000, 0b0000001); ++ INSN(mulh, 0b0110011, 0b001, 0b0000001); ++ INSN(mulhsu,0b0110011, 0b010, 0b0000001); ++ INSN(mulhu, 0b0110011, 0b011, 0b0000001); ++ INSN(mulw, 0b0111011, 0b000, 0b0000001); ++ INSN(div, 0b0110011, 0b100, 0b0000001); ++ INSN(divu, 0b0110011, 0b101, 0b0000001); ++ INSN(divw, 0b0111011, 0b100, 0b0000001); ++ INSN(divuw, 0b0111011, 0b101, 0b0000001); ++ INSN(rem, 0b0110011, 0b110, 0b0000001); ++ INSN(remu, 0b0110011, 0b111, 0b0000001); ++ INSN(remw, 0b0111011, 0b110, 0b0000001); ++ INSN(remuw, 0b0111011, 0b111, 0b0000001); ++ ++#undef INSN ++ ++// Load/store register (all modes) ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rd, Register Rs, const int32_t offset) { \ ++ guarantee(is_simm12(offset), "offset is invalid."); \ ++ unsigned insn = 0; \ ++ int32_t val = offset & 0xfff; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 15, Rs); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch((address)&insn, 31, 20, val); \ ++ emit(insn); \ ++ } ++ ++ INSN(lb, 0b0000011, 0b000); ++ INSN(lbu, 0b0000011, 0b100); ++ INSN(lh, 0b0000011, 0b001); ++ INSN(lhu, 0b0000011, 0b101); ++ INSN(_lw, 0b0000011, 0b010); ++ INSN(lwu, 0b0000011, 0b110); ++ INSN(_ld, 0b0000011, 0b011); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3) \ ++ void NAME(FloatRegister Rd, Register Rs, const int32_t offset) { \ ++ guarantee(is_simm12(offset), "offset is invalid."); \ ++ unsigned insn = 0; \ ++ uint32_t val = offset & 0xfff; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 15, Rs); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch((address)&insn, 31, 20, val); \ ++ emit(insn); \ ++ } ++ ++ INSN(flw, 0b0000111, 0b010); ++ INSN(_fld, 0b0000111, 0b011); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rs1, Register Rs2, const int64_t offset) { \ ++ guarantee(is_simm13(offset) && ((offset % 2) == 0), "offset is invalid."); \ ++ unsigned insn = 0; \ ++ uint32_t val = offset & 0x1fff; \ ++ uint32_t val11 = (val >> 11) & 0x1; \ ++ uint32_t val12 = (val >> 12) & 0x1; \ ++ uint32_t low = (val >> 1) & 0xf; \ ++ uint32_t high = (val >> 5) & 0x3f; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ patch((address)&insn, 7, val11); \ ++ patch((address)&insn, 11, 8, low); \ ++ patch((address)&insn, 30, 25, high); \ ++ patch((address)&insn, 31, val12); \ ++ emit(insn); \ ++ } ++ ++ INSN(beq, 0b1100011, 0b000); ++ INSN(bne, 0b1100011, 0b001); ++ INSN(bge, 0b1100011, 0b101); ++ INSN(bgeu, 0b1100011, 0b111); ++ INSN(blt, 0b1100011, 0b100); ++ INSN(bltu, 0b1100011, 0b110); ++ ++#undef INSN ++ ++#define INSN(NAME, REGISTER, op, funct3) \ ++ void NAME(REGISTER Rs1, Register Rs2, const int32_t offset) { \ ++ guarantee(is_simm12(offset), "offset is invalid."); \ ++ unsigned insn = 0; \ ++ uint32_t val = offset & 0xfff; \ ++ uint32_t low = val & 0x1f; \ ++ uint32_t high = (val >> 5) & 0x7f; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 15, Rs2); \ ++ patch_reg((address)&insn, 20, Rs1); \ ++ patch((address)&insn, 11, 7, low); \ ++ patch((address)&insn, 31, 25, high); \ ++ emit(insn); \ ++ } \ ++ ++ INSN(sb, Register, 0b0100011, 0b000); ++ INSN(sh, Register, 0b0100011, 0b001); ++ INSN(_sw, Register, 0b0100011, 0b010); ++ INSN(_sd, Register, 0b0100011, 0b011); ++ INSN(fsw, FloatRegister, 0b0100111, 0b010); ++ INSN(_fsd, FloatRegister, 0b0100111, 0b011); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rd, const uint32_t csr, Register Rs1) { \ ++ guarantee(is_uimm12(csr), "csr is invalid"); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch((address)&insn, 31, 20, csr); \ ++ emit(insn); \ ++ } ++ ++ INSN(csrrw, 0b1110011, 0b001); ++ INSN(csrrs, 0b1110011, 0b010); ++ INSN(csrrc, 0b1110011, 0b011); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rd, const uint32_t csr, const uint32_t uimm) { \ ++ guarantee(is_uimm12(csr), "csr is invalid"); \ ++ guarantee(is_uimm5(uimm), "uimm is invalid"); \ ++ unsigned insn = 0; \ ++ uint32_t val = uimm & 0x1f; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch((address)&insn, 19, 15, val); \ ++ patch((address)&insn, 31, 20, csr); \ ++ emit(insn); \ ++ } ++ ++ INSN(csrrwi, 0b1110011, 0b101); ++ INSN(csrrsi, 0b1110011, 0b110); ++ INSN(csrrci, 0b1110011, 0b111); ++ ++#undef INSN ++ ++#define INSN(NAME, op) \ ++ void NAME(Register Rd, const int32_t offset) { \ ++ guarantee(is_simm21(offset) && ((offset % 2) == 0), "offset is invalid."); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch((address)&insn, 19, 12, (uint32_t)((offset >> 12) & 0xff)); \ ++ patch((address)&insn, 20, (uint32_t)((offset >> 11) & 0x1)); \ ++ patch((address)&insn, 30, 21, (uint32_t)((offset >> 1) & 0x3ff)); \ ++ patch((address)&insn, 31, (uint32_t)((offset >> 20) & 0x1)); \ ++ emit(insn); \ ++ } ++ ++ INSN(jal, 0b1101111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct) \ ++ void NAME(Register Rd, Register Rs, const int32_t offset) { \ ++ guarantee(is_simm12(offset), "offset is invalid."); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch((address)&insn, 14, 12, funct); \ ++ patch_reg((address)&insn, 15, Rs); \ ++ int32_t val = offset & 0xfff; \ ++ patch((address)&insn, 31, 20, val); \ ++ emit(insn); \ ++ } ++ ++ INSN(_jalr, 0b1100111, 0b000); ++ ++#undef INSN ++ ++ enum barrier { ++ i = 0b1000, o = 0b0100, r = 0b0010, w = 0b0001, ++ ir = i | r, ow = o | w, iorw = i | o | r | w ++ }; ++ ++ void fence(const uint32_t predecessor, const uint32_t successor) { ++ unsigned insn = 0; ++ guarantee(predecessor < 16, "predecessor is invalid"); ++ guarantee(successor < 16, "successor is invalid"); ++ patch((address)&insn, 6, 0, 0b001111); ++ patch((address)&insn, 11, 7, 0b00000); ++ patch((address)&insn, 14, 12, 0b000); ++ patch((address)&insn, 19, 15, 0b00000); ++ patch((address)&insn, 23, 20, successor); ++ patch((address)&insn, 27, 24, predecessor); ++ patch((address)&insn, 31, 28, 0b0000); ++ emit(insn); ++ } ++ ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME() { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 11, 7, 0b00000); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 19, 15, 0b00000); \ ++ patch((address)&insn, 31, 20, funct7); \ ++ emit(insn); \ ++ } ++ ++ INSN(ecall, 0b1110011, 0b000, 0b000000000000); ++ INSN(_ebreak, 0b1110011, 0b000, 0b000000000001); ++ ++#undef INSN ++ ++enum Aqrl {relaxed = 0b00, rl = 0b01, aq = 0b10, aqrl = 0b11}; ++ ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ patch((address)&insn, 31, 27, funct7); \ ++ patch((address)&insn, 26, 25, memory_order); \ ++ emit(insn); \ ++ } ++ ++ INSN(amoswap_w, 0b0101111, 0b010, 0b00001); ++ INSN(amoadd_w, 0b0101111, 0b010, 0b00000); ++ INSN(amoxor_w, 0b0101111, 0b010, 0b00100); ++ INSN(amoand_w, 0b0101111, 0b010, 0b01100); ++ INSN(amoor_w, 0b0101111, 0b010, 0b01000); ++ INSN(amomin_w, 0b0101111, 0b010, 0b10000); ++ INSN(amomax_w, 0b0101111, 0b010, 0b10100); ++ INSN(amominu_w, 0b0101111, 0b010, 0b11000); ++ INSN(amomaxu_w, 0b0101111, 0b010, 0b11100); ++ INSN(amoswap_d, 0b0101111, 0b011, 0b00001); ++ INSN(amoadd_d, 0b0101111, 0b011, 0b00000); ++ INSN(amoxor_d, 0b0101111, 0b011, 0b00100); ++ INSN(amoand_d, 0b0101111, 0b011, 0b01100); ++ INSN(amoor_d, 0b0101111, 0b011, 0b01000); ++ INSN(amomin_d, 0b0101111, 0b011, 0b10000); ++ INSN(amomax_d , 0b0101111, 0b011, 0b10100); ++ INSN(amominu_d, 0b0101111, 0b011, 0b11000); ++ INSN(amomaxu_d, 0b0101111, 0b011, 0b11100); ++#undef INSN ++ ++enum operand_size { int8, int16, int32, uint32, int64 }; ++ ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, Aqrl memory_order = relaxed) { \ ++ unsigned insn = 0; \ ++ uint32_t val = memory_order & 0x3; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch((address)&insn, 25, 20, 0b00000); \ ++ patch((address)&insn, 31, 27, funct7); \ ++ patch((address)&insn, 26, 25, val); \ ++ emit(insn); \ ++ } ++ ++ INSN(lr_w, 0b0101111, 0b010, 0b00010); ++ INSN(lr_d, 0b0101111, 0b011, 0b00010); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = relaxed) { \ ++ unsigned insn = 0; \ ++ uint32_t val = memory_order & 0x3; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs2); \ ++ patch_reg((address)&insn, 20, Rs1); \ ++ patch((address)&insn, 31, 27, funct7); \ ++ patch((address)&insn, 26, 25, val); \ ++ emit(insn); \ ++ } ++ ++ INSN(sc_w, 0b0101111, 0b010, 0b00011); ++ INSN(sc_d, 0b0101111, 0b011, 0b00011); ++#undef INSN ++ ++#define INSN(NAME, op, funct5, funct7) \ ++ void NAME(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, rm); \ ++ patch((address)&insn, 24, 20, funct5); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(fsqrt_s, 0b1010011, 0b00000, 0b0101100); ++ INSN(fsqrt_d, 0b1010011, 0b00000, 0b0101101); ++ INSN(fcvt_s_d, 0b1010011, 0b00001, 0b0100000); ++ INSN(fcvt_d_s, 0b1010011, 0b00000, 0b0100001); ++#undef INSN ++ ++// Immediate Instruction ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rd, Register Rs1, int32_t imm) { \ ++ guarantee(is_simm12(imm), "Immediate is out of validity"); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 20, imm & 0x00000fff); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(_addi, 0b0010011, 0b000); ++ INSN(slti, 0b0010011, 0b010); ++ INSN(_addiw, 0b0011011, 0b000); ++ INSN(_and_imm12, 0b0010011, 0b111); ++ INSN(ori, 0b0010011, 0b110); ++ INSN(xori, 0b0010011, 0b100); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rd, Register Rs1, uint32_t imm) { \ ++ guarantee(is_uimm12(imm), "Immediate is out of validity"); \ ++ unsigned insn = 0; \ ++ patch((address)&insn,6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 20, imm & 0x00000fff); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(sltiu, 0b0010011, 0b011); ++ ++#undef INSN ++ ++// Shift Immediate Instruction ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(Register Rd, Register Rs1, unsigned shamt) { \ ++ guarantee(shamt <= 0x3f, "Shamt is invalid"); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 25, 20, shamt); \ ++ patch((address)&insn, 31, 26, funct6); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(_slli, 0b0010011, 0b001, 0b000000); ++ INSN(_srai, 0b0010011, 0b101, 0b010000); ++ INSN(_srli, 0b0010011, 0b101, 0b000000); ++ ++#undef INSN ++ ++// Shift Word Immediate Instruction ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, unsigned shamt) { \ ++ guarantee(shamt <= 0x1f, "Shamt is invalid"); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 24, 20, shamt); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(slliw, 0b0011011, 0b001, 0b0000000); ++ INSN(sraiw, 0b0011011, 0b101, 0b0100000); ++ INSN(srliw, 0b0011011, 0b101, 0b0000000); ++ ++#undef INSN ++ ++// Upper Immediate Instruction ++#define INSN(NAME, op) \ ++ void NAME(Register Rd, int32_t imm) { \ ++ int32_t upperImm = imm >> 12; \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ upperImm &= 0x000fffff; \ ++ patch((address)&insn, 31, 12, upperImm); \ ++ emit(insn); \ ++ } ++ ++ INSN(_lui, 0b0110111); ++ INSN(auipc, 0b0010111); ++ ++#undef INSN ++ ++// Float and Double Rigster Instruction ++#define INSN(NAME, op, funct2) \ ++ void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, rm); \ ++ patch((address)&insn, 26, 25, funct2); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ patch_reg((address)&insn, 27, Rs3); \ ++ emit(insn); \ ++ } ++ ++ INSN(fmadd_s, 0b1000011, 0b00); ++ INSN(fmsub_s, 0b1000111, 0b00); ++ INSN(fnmsub_s, 0b1001011, 0b00); ++ INSN(fnmadd_s, 0b1001111, 0b00); ++ INSN(fmadd_d, 0b1000011, 0b01); ++ INSN(fmsub_d, 0b1000111, 0b01); ++ INSN(fnmsub_d, 0b1001011, 0b01); ++ INSN(fnmadd_d, 0b1001111, 0b01); ++ ++#undef INSN ++ ++// Float and Double Rigster Instruction ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ emit(insn); \ ++ } ++ ++ INSN(fsgnj_s, 0b1010011, 0b000, 0b0010000); ++ INSN(fsgnjn_s, 0b1010011, 0b001, 0b0010000); ++ INSN(fsgnjx_s, 0b1010011, 0b010, 0b0010000); ++ INSN(fmin_s, 0b1010011, 0b000, 0b0010100); ++ INSN(fmax_s, 0b1010011, 0b001, 0b0010100); ++ INSN(fsgnj_d, 0b1010011, 0b000, 0b0010001); ++ INSN(fsgnjn_d, 0b1010011, 0b001, 0b0010001); ++ INSN(fsgnjx_d, 0b1010011, 0b010, 0b0010001); ++ INSN(fmin_d, 0b1010011, 0b000, 0b0010101); ++ INSN(fmax_d, 0b1010011, 0b001, 0b0010101); ++ ++#undef INSN ++ ++// Float and Double Rigster Arith Instruction ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ emit(insn); \ ++ } ++ ++ INSN(feq_s, 0b1010011, 0b010, 0b1010000); ++ INSN(flt_s, 0b1010011, 0b001, 0b1010000); ++ INSN(fle_s, 0b1010011, 0b000, 0b1010000); ++ INSN(feq_d, 0b1010011, 0b010, 0b1010001); ++ INSN(fle_d, 0b1010011, 0b000, 0b1010001); ++ INSN(flt_d, 0b1010011, 0b001, 0b1010001); ++#undef INSN ++ ++// Float and Double Arith Instruction ++#define INSN(NAME, op, funct7) \ ++ void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, rm); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ emit(insn); \ ++ } ++ ++ INSN(fadd_s, 0b1010011, 0b0000000); ++ INSN(fsub_s, 0b1010011, 0b0000100); ++ INSN(fmul_s, 0b1010011, 0b0001000); ++ INSN(fdiv_s, 0b1010011, 0b0001100); ++ INSN(fadd_d, 0b1010011, 0b0000001); ++ INSN(fsub_d, 0b1010011, 0b0000101); ++ INSN(fmul_d, 0b1010011, 0b0001001); ++ INSN(fdiv_d, 0b1010011, 0b0001101); ++ ++#undef INSN ++ ++// Whole Float and Double Conversion Instruction ++#define INSN(NAME, op, funct5, funct7) \ ++ void NAME(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, rm); \ ++ patch((address)&insn, 24, 20, funct5); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(fcvt_s_w, 0b1010011, 0b00000, 0b1101000); ++ INSN(fcvt_s_wu, 0b1010011, 0b00001, 0b1101000); ++ INSN(fcvt_s_l, 0b1010011, 0b00010, 0b1101000); ++ INSN(fcvt_s_lu, 0b1010011, 0b00011, 0b1101000); ++ INSN(fcvt_d_w, 0b1010011, 0b00000, 0b1101001); ++ INSN(fcvt_d_wu, 0b1010011, 0b00001, 0b1101001); ++ INSN(fcvt_d_l, 0b1010011, 0b00010, 0b1101001); ++ INSN(fcvt_d_lu, 0b1010011, 0b00011, 0b1101001); ++ ++#undef INSN ++ ++// Float and Double Conversion Instruction ++#define INSN(NAME, op, funct5, funct7) \ ++ void NAME(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, rm); \ ++ patch((address)&insn, 24, 20, funct5); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(fcvt_w_s, 0b1010011, 0b00000, 0b1100000); ++ INSN(fcvt_l_s, 0b1010011, 0b00010, 0b1100000); ++ INSN(fcvt_wu_s, 0b1010011, 0b00001, 0b1100000); ++ INSN(fcvt_lu_s, 0b1010011, 0b00011, 0b1100000); ++ INSN(fcvt_w_d, 0b1010011, 0b00000, 0b1100001); ++ INSN(fcvt_wu_d, 0b1010011, 0b00001, 0b1100001); ++ INSN(fcvt_l_d, 0b1010011, 0b00010, 0b1100001); ++ INSN(fcvt_lu_d, 0b1010011, 0b00011, 0b1100001); ++ ++#undef INSN ++ ++// Float and Double Move Instruction ++#define INSN(NAME, op, funct3, funct5, funct7) \ ++ void NAME(FloatRegister Rd, Register Rs1) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 20, funct5); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(fmv_w_x, 0b1010011, 0b000, 0b00000, 0b1111000); ++ INSN(fmv_d_x, 0b1010011, 0b000, 0b00000, 0b1111001); ++ ++#undef INSN ++ ++// Float and Double Conversion Instruction ++#define INSN(NAME, op, funct3, funct5, funct7) \ ++ void NAME(Register Rd, FloatRegister Rs1) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 20, funct5); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(fclass_s, 0b1010011, 0b001, 0b00000, 0b1110000); ++ INSN(fclass_d, 0b1010011, 0b001, 0b00000, 0b1110001); ++ INSN(fmv_x_w, 0b1010011, 0b000, 0b00000, 0b1110000); ++ INSN(fmv_x_d, 0b1010011, 0b000, 0b00000, 0b1110001); ++ ++#undef INSN ++ ++// ========================== ++// RISC-V Vector Extension ++// ========================== ++enum SEW { ++ e8, ++ e16, ++ e32, ++ e64, ++ RESERVED, ++}; ++ ++enum LMUL { ++ mf8 = 0b101, ++ mf4 = 0b110, ++ mf2 = 0b111, ++ m1 = 0b000, ++ m2 = 0b001, ++ m4 = 0b010, ++ m8 = 0b011, ++}; ++ ++enum VMA { ++ mu, // undisturbed ++ ma, // agnostic ++}; ++ ++enum VTA { ++ tu, // undisturbed ++ ta, // agnostic ++}; ++ ++static Assembler::SEW elembytes_to_sew(int ebytes) { ++ assert(ebytes > 0 && ebytes <= 8, "unsupported element size"); ++ return (Assembler::SEW) exact_log2(ebytes); ++} ++ ++static Assembler::SEW elemtype_to_sew(BasicType etype) { ++ return Assembler::elembytes_to_sew(type2aelembytes(etype)); ++} ++ ++#define patch_vtype(hsb, lsb, vlmul, vsew, vta, vma, vill) \ ++ if (vill == 1) { \ ++ guarantee((vlmul | vsew | vta | vma == 0), \ ++ "the other bits in vtype shall be zero"); \ ++ } \ ++ patch((address)&insn, lsb + 2, lsb, vlmul); \ ++ patch((address)&insn, lsb + 5, lsb + 3, vsew); \ ++ patch((address)&insn, lsb + 6, vta); \ ++ patch((address)&insn, lsb + 7, vma); \ ++ patch((address)&insn, hsb - 1, lsb + 8, 0); \ ++ patch((address)&insn, hsb, vill) ++ ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rd, Register Rs1, SEW sew, LMUL lmul = m1, \ ++ VMA vma = mu, VTA vta = tu, bool vill = false) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch_vtype(30, 20, lmul, sew, vta, vma, vill); \ ++ patch((address)&insn, 31, 0); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(vsetvli, 0b1010111, 0b111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3) \ ++ void NAME(Register Rd, uint32_t imm, SEW sew, LMUL lmul = m1, \ ++ VMA vma = mu, VTA vta = tu, bool vill = false) { \ ++ unsigned insn = 0; \ ++ guarantee(is_uimm5(imm), "imm is invalid"); \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 19, 15, imm); \ ++ patch_vtype(29, 20, lmul, sew, vta, vma, vill); \ ++ patch((address)&insn, 31, 30, 0b11); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ emit(insn); \ ++ } ++ ++ INSN(vsetivli, 0b1010111, 0b111); ++ ++#undef INSN ++ ++#undef patch_vtype ++ ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ emit(insn); \ ++ } ++ ++ // Vector Configuration Instruction ++ INSN(vsetvl, 0b1010111, 0b111, 0b1000000); ++ ++#undef INSN ++ ++enum VectorMask { ++ v0_t = 0b0, ++ unmasked = 0b1 ++}; ++ ++#define patch_VArith(op, Reg, funct3, Reg_or_Imm5, Vs2, vm, funct6) \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 19, 15, Reg_or_Imm5); \ ++ patch((address)&insn, 25, vm); \ ++ patch((address)&insn, 31, 26, funct6); \ ++ patch_reg((address)&insn, 7, Reg); \ ++ patch_reg((address)&insn, 20, Vs2); \ ++ emit(insn) ++ ++// r2_vm ++#define INSN(NAME, op, funct3, Vs1, funct6) \ ++ void NAME(Register Rd, VectorRegister Vs2, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Rd, funct3, Vs1, Vs2, vm, funct6); \ ++ } ++ ++ // Vector Mask ++ INSN(vcpop_m, 0b1010111, 0b010, 0b10000, 0b010000); ++ INSN(vfirst_m, 0b1010111, 0b010, 0b10001, 0b010000); ++#undef INSN ++ ++#define INSN(NAME, op, funct3, Vs1, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Vd, funct3, Vs1, Vs2, vm, funct6); \ ++ } ++ ++ // Vector Integer Extension ++ INSN(vzext_vf2, 0b1010111, 0b010, 0b00110, 0b010010); ++ INSN(vzext_vf4, 0b1010111, 0b010, 0b00100, 0b010010); ++ INSN(vzext_vf8, 0b1010111, 0b010, 0b00010, 0b010010); ++ INSN(vsext_vf2, 0b1010111, 0b010, 0b00111, 0b010010); ++ INSN(vsext_vf4, 0b1010111, 0b010, 0b00101, 0b010010); ++ INSN(vsext_vf8, 0b1010111, 0b010, 0b00011, 0b010010); ++ ++ // Vector Mask ++ INSN(vmsbf_m, 0b1010111, 0b010, 0b00001, 0b010100); ++ INSN(vmsif_m, 0b1010111, 0b010, 0b00011, 0b010100); ++ INSN(vmsof_m, 0b1010111, 0b010, 0b00010, 0b010100); ++ INSN(viota_m, 0b1010111, 0b010, 0b10000, 0b010100); ++ ++ // Vector Single-Width Floating-Point/Integer Type-Convert Instructions ++ INSN(vfcvt_xu_f_v, 0b1010111, 0b001, 0b00000, 0b010010); ++ INSN(vfcvt_x_f_v, 0b1010111, 0b001, 0b00001, 0b010010); ++ INSN(vfcvt_f_xu_v, 0b1010111, 0b001, 0b00010, 0b010010); ++ INSN(vfcvt_f_x_v, 0b1010111, 0b001, 0b00011, 0b010010); ++ INSN(vfcvt_rtz_xu_f_v, 0b1010111, 0b001, 0b00110, 0b010010); ++ INSN(vfcvt_rtz_x_f_v, 0b1010111, 0b001, 0b00111, 0b010010); ++ ++ // Vector Floating-Point Instruction ++ INSN(vfsqrt_v, 0b1010111, 0b001, 0b00000, 0b010011); ++ INSN(vfclass_v, 0b1010111, 0b001, 0b10000, 0b010011); ++ ++#undef INSN ++ ++// r2rd ++#define INSN(NAME, op, funct3, simm5, vm, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2) { \ ++ patch_VArith(op, Vd, funct3, simm5, Vs2, vm, funct6); \ ++ } ++ ++ // Vector Whole Vector Register Move ++ INSN(vmv1r_v, 0b1010111, 0b011, 0b00000, 0b1, 0b100111); ++ INSN(vmv2r_v, 0b1010111, 0b011, 0b00001, 0b1, 0b100111); ++ INSN(vmv4r_v, 0b1010111, 0b011, 0b00011, 0b1, 0b100111); ++ INSN(vmv8r_v, 0b1010111, 0b011, 0b00111, 0b1, 0b100111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, Vs1, vm, funct6) \ ++ void NAME(FloatRegister Rd, VectorRegister Vs2) { \ ++ patch_VArith(op, Rd, funct3, Vs1, Vs2, vm, funct6); \ ++ } ++ ++ // Vector Floating-Point Move Instruction ++ INSN(vfmv_f_s, 0b1010111, 0b001, 0b00000, 0b1, 0b010000); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, Vs1, vm, funct6) \ ++ void NAME(Register Rd, VectorRegister Vs2) { \ ++ patch_VArith(op, Rd, funct3, Vs1, Vs2, vm, funct6); \ ++ } ++ ++ // Vector Integer Scalar Move Instructions ++ INSN(vmv_x_s, 0b1010111, 0b010, 0b00000, 0b1, 0b010000); ++ ++#undef INSN ++ ++// r_vm ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2, uint32_t imm, VectorMask vm = unmasked) { \ ++ guarantee(is_uimm5(imm), "imm is invalid"); \ ++ patch_VArith(op, Vd, funct3, (uint32_t)(imm & 0x1f), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Single-Width Bit Shift Instructions ++ INSN(vsra_vi, 0b1010111, 0b011, 0b101001); ++ INSN(vsrl_vi, 0b1010111, 0b011, 0b101000); ++ INSN(vsll_vi, 0b1010111, 0b011, 0b100101); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs1, VectorRegister Vs2, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Vd, funct3, Vs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Single-Width Floating-Point Fused Multiply-Add Instructions ++ INSN(vfnmsub_vv, 0b1010111, 0b001, 0b101011); ++ INSN(vfmsub_vv, 0b1010111, 0b001, 0b101010); ++ INSN(vfnmadd_vv, 0b1010111, 0b001, 0b101001); ++ INSN(vfmadd_vv, 0b1010111, 0b001, 0b101000); ++ INSN(vfnmsac_vv, 0b1010111, 0b001, 0b101111); ++ INSN(vfmsac_vv, 0b1010111, 0b001, 0b101110); ++ INSN(vfmacc_vv, 0b1010111, 0b001, 0b101100); ++ INSN(vfnmacc_vv, 0b1010111, 0b001, 0b101101); ++ ++ // Vector Single-Width Integer Multiply-Add Instructions ++ INSN(vnmsub_vv, 0b1010111, 0b010, 0b101011); ++ INSN(vmadd_vv, 0b1010111, 0b010, 0b101001); ++ INSN(vnmsac_vv, 0b1010111, 0b010, 0b101111); ++ INSN(vmacc_vv, 0b1010111, 0b010, 0b101101); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, Register Rs1, VectorRegister Vs2, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Vd, funct3, Rs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Single-Width Integer Multiply-Add Instructions ++ INSN(vnmsub_vx, 0b1010111, 0b110, 0b101011); ++ INSN(vmadd_vx, 0b1010111, 0b110, 0b101001); ++ INSN(vnmsac_vx, 0b1010111, 0b110, 0b101111); ++ INSN(vmacc_vx, 0b1010111, 0b110, 0b101101); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, FloatRegister Rs1, VectorRegister Vs2, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Vd, funct3, Rs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Single-Width Floating-Point Fused Multiply-Add Instructions ++ INSN(vfnmsub_vf, 0b1010111, 0b101, 0b101011); ++ INSN(vfmsub_vf, 0b1010111, 0b101, 0b101010); ++ INSN(vfnmadd_vf, 0b1010111, 0b101, 0b101001); ++ INSN(vfmadd_vf, 0b1010111, 0b101, 0b101000); ++ INSN(vfnmsac_vf, 0b1010111, 0b101, 0b101111); ++ INSN(vfmsac_vf, 0b1010111, 0b101, 0b101110); ++ INSN(vfmacc_vf, 0b1010111, 0b101, 0b101100); ++ INSN(vfnmacc_vf, 0b1010111, 0b101, 0b101101); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Vd, funct3, Vs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Single-Width Floating-Point Reduction Instructions ++ INSN(vfredusum_vs, 0b1010111, 0b001, 0b000001); ++ INSN(vfredosum_vs, 0b1010111, 0b001, 0b000011); ++ INSN(vfredmin_vs, 0b1010111, 0b001, 0b000101); ++ INSN(vfredmax_vs, 0b1010111, 0b001, 0b000111); ++ ++ // Vector Single-Width Integer Reduction Instructions ++ INSN(vredsum_vs, 0b1010111, 0b010, 0b000000); ++ INSN(vredand_vs, 0b1010111, 0b010, 0b000001); ++ INSN(vredor_vs, 0b1010111, 0b010, 0b000010); ++ INSN(vredxor_vs, 0b1010111, 0b010, 0b000011); ++ INSN(vredminu_vs, 0b1010111, 0b010, 0b000100); ++ INSN(vredmin_vs, 0b1010111, 0b010, 0b000101); ++ INSN(vredmaxu_vs, 0b1010111, 0b010, 0b000110); ++ INSN(vredmax_vs, 0b1010111, 0b010, 0b000111); ++ ++ // Vector Floating-Point Compare Instructions ++ INSN(vmfle_vv, 0b1010111, 0b001, 0b011001); ++ INSN(vmflt_vv, 0b1010111, 0b001, 0b011011); ++ INSN(vmfne_vv, 0b1010111, 0b001, 0b011100); ++ INSN(vmfeq_vv, 0b1010111, 0b001, 0b011000); ++ ++ // Vector Floating-Point Sign-Injection Instructions ++ INSN(vfsgnjx_vv, 0b1010111, 0b001, 0b001010); ++ INSN(vfsgnjn_vv, 0b1010111, 0b001, 0b001001); ++ INSN(vfsgnj_vv, 0b1010111, 0b001, 0b001000); ++ ++ // Vector Floating-Point MIN/MAX Instructions ++ INSN(vfmax_vv, 0b1010111, 0b001, 0b000110); ++ INSN(vfmin_vv, 0b1010111, 0b001, 0b000100); ++ ++ // Vector Single-Width Floating-Point Multiply/Divide Instructions ++ INSN(vfdiv_vv, 0b1010111, 0b001, 0b100000); ++ INSN(vfmul_vv, 0b1010111, 0b001, 0b100100); ++ ++ // Vector Single-Width Floating-Point Add/Subtract Instructions ++ INSN(vfsub_vv, 0b1010111, 0b001, 0b000010); ++ INSN(vfadd_vv, 0b1010111, 0b001, 0b000000); ++ ++ // Vector Single-Width Fractional Multiply with Rounding and Saturation ++ INSN(vsmul_vv, 0b1010111, 0b000, 0b100111); ++ ++ // Vector Integer Divide Instructions ++ INSN(vrem_vv, 0b1010111, 0b010, 0b100011); ++ INSN(vremu_vv, 0b1010111, 0b010, 0b100010); ++ INSN(vdiv_vv, 0b1010111, 0b010, 0b100001); ++ INSN(vdivu_vv, 0b1010111, 0b010, 0b100000); ++ ++ // Vector Single-Width Integer Multiply Instructions ++ INSN(vmulhsu_vv, 0b1010111, 0b010, 0b100110); ++ INSN(vmulhu_vv, 0b1010111, 0b010, 0b100100); ++ INSN(vmulh_vv, 0b1010111, 0b010, 0b100111); ++ INSN(vmul_vv, 0b1010111, 0b010, 0b100101); ++ ++ // Vector Integer Min/Max Instructions ++ INSN(vmax_vv, 0b1010111, 0b000, 0b000111); ++ INSN(vmaxu_vv, 0b1010111, 0b000, 0b000110); ++ INSN(vmin_vv, 0b1010111, 0b000, 0b000101); ++ INSN(vminu_vv, 0b1010111, 0b000, 0b000100); ++ ++ // Vector Integer Comparison Instructions ++ INSN(vmsle_vv, 0b1010111, 0b000, 0b011101); ++ INSN(vmsleu_vv, 0b1010111, 0b000, 0b011100); ++ INSN(vmslt_vv, 0b1010111, 0b000, 0b011011); ++ INSN(vmsltu_vv, 0b1010111, 0b000, 0b011010); ++ INSN(vmsne_vv, 0b1010111, 0b000, 0b011001); ++ INSN(vmseq_vv, 0b1010111, 0b000, 0b011000); ++ ++ // Vector Single-Width Bit Shift Instructions ++ INSN(vsra_vv, 0b1010111, 0b000, 0b101001); ++ INSN(vsrl_vv, 0b1010111, 0b000, 0b101000); ++ INSN(vsll_vv, 0b1010111, 0b000, 0b100101); ++ ++ // Vector Bitwise Logical Instructions ++ INSN(vxor_vv, 0b1010111, 0b000, 0b001011); ++ INSN(vor_vv, 0b1010111, 0b000, 0b001010); ++ INSN(vand_vv, 0b1010111, 0b000, 0b001001); ++ ++ // Vector Single-Width Integer Add and Subtract ++ INSN(vsub_vv, 0b1010111, 0b000, 0b000010); ++ INSN(vadd_vv, 0b1010111, 0b000, 0b000000); ++ ++#undef INSN ++ ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2, Register Rs1, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Vd, funct3, Rs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Integer Divide Instructions ++ INSN(vrem_vx, 0b1010111, 0b110, 0b100011); ++ INSN(vremu_vx, 0b1010111, 0b110, 0b100010); ++ INSN(vdiv_vx, 0b1010111, 0b110, 0b100001); ++ INSN(vdivu_vx, 0b1010111, 0b110, 0b100000); ++ ++ // Vector Single-Width Integer Multiply Instructions ++ INSN(vmulhsu_vx, 0b1010111, 0b110, 0b100110); ++ INSN(vmulhu_vx, 0b1010111, 0b110, 0b100100); ++ INSN(vmulh_vx, 0b1010111, 0b110, 0b100111); ++ INSN(vmul_vx, 0b1010111, 0b110, 0b100101); ++ ++ // Vector Integer Min/Max Instructions ++ INSN(vmax_vx, 0b1010111, 0b100, 0b000111); ++ INSN(vmaxu_vx, 0b1010111, 0b100, 0b000110); ++ INSN(vmin_vx, 0b1010111, 0b100, 0b000101); ++ INSN(vminu_vx, 0b1010111, 0b100, 0b000100); ++ ++ // Vector Integer Comparison Instructions ++ INSN(vmsgt_vx, 0b1010111, 0b100, 0b011111); ++ INSN(vmsgtu_vx, 0b1010111, 0b100, 0b011110); ++ INSN(vmsle_vx, 0b1010111, 0b100, 0b011101); ++ INSN(vmsleu_vx, 0b1010111, 0b100, 0b011100); ++ INSN(vmslt_vx, 0b1010111, 0b100, 0b011011); ++ INSN(vmsltu_vx, 0b1010111, 0b100, 0b011010); ++ INSN(vmsne_vx, 0b1010111, 0b100, 0b011001); ++ INSN(vmseq_vx, 0b1010111, 0b100, 0b011000); ++ ++ // Vector Narrowing Integer Right Shift Instructions ++ INSN(vnsra_wx, 0b1010111, 0b100, 0b101101); ++ INSN(vnsrl_wx, 0b1010111, 0b100, 0b101100); ++ ++ // Vector Single-Width Bit Shift Instructions ++ INSN(vsra_vx, 0b1010111, 0b100, 0b101001); ++ INSN(vsrl_vx, 0b1010111, 0b100, 0b101000); ++ INSN(vsll_vx, 0b1010111, 0b100, 0b100101); ++ ++ // Vector Bitwise Logical Instructions ++ INSN(vxor_vx, 0b1010111, 0b100, 0b001011); ++ INSN(vor_vx, 0b1010111, 0b100, 0b001010); ++ INSN(vand_vx, 0b1010111, 0b100, 0b001001); ++ ++ // Vector Single-Width Integer Add and Subtract ++ INSN(vsub_vx, 0b1010111, 0b100, 0b000010); ++ INSN(vadd_vx, 0b1010111, 0b100, 0b000000); ++ INSN(vrsub_vx, 0b1010111, 0b100, 0b000011); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2, FloatRegister Rs1, VectorMask vm = unmasked) { \ ++ patch_VArith(op, Vd, funct3, Rs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Floating-Point Compare Instructions ++ INSN(vmfge_vf, 0b1010111, 0b101, 0b011111); ++ INSN(vmfgt_vf, 0b1010111, 0b101, 0b011101); ++ INSN(vmfle_vf, 0b1010111, 0b101, 0b011001); ++ INSN(vmflt_vf, 0b1010111, 0b101, 0b011011); ++ INSN(vmfne_vf, 0b1010111, 0b101, 0b011100); ++ INSN(vmfeq_vf, 0b1010111, 0b101, 0b011000); ++ ++ // Vector Floating-Point Sign-Injection Instructions ++ INSN(vfsgnjx_vf, 0b1010111, 0b101, 0b001010); ++ INSN(vfsgnjn_vf, 0b1010111, 0b101, 0b001001); ++ INSN(vfsgnj_vf, 0b1010111, 0b101, 0b001000); ++ ++ // Vector Floating-Point MIN/MAX Instructions ++ INSN(vfmax_vf, 0b1010111, 0b101, 0b000110); ++ INSN(vfmin_vf, 0b1010111, 0b101, 0b000100); ++ ++ // Vector Single-Width Floating-Point Multiply/Divide Instructions ++ INSN(vfdiv_vf, 0b1010111, 0b101, 0b100000); ++ INSN(vfmul_vf, 0b1010111, 0b101, 0b100100); ++ INSN(vfrdiv_vf, 0b1010111, 0b101, 0b100001); ++ ++ // Vector Single-Width Floating-Point Add/Subtract Instructions ++ INSN(vfsub_vf, 0b1010111, 0b101, 0b000010); ++ INSN(vfadd_vf, 0b1010111, 0b101, 0b000000); ++ INSN(vfrsub_vf, 0b1010111, 0b101, 0b100111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2, int32_t imm, VectorMask vm = unmasked) { \ ++ guarantee(is_simm5(imm), "imm is invalid"); \ ++ patch_VArith(op, Vd, funct3, (uint32_t)(imm & 0x1f), Vs2, vm, funct6); \ ++ } ++ ++ INSN(vmsgt_vi, 0b1010111, 0b011, 0b011111); ++ INSN(vmsgtu_vi, 0b1010111, 0b011, 0b011110); ++ INSN(vmsle_vi, 0b1010111, 0b011, 0b011101); ++ INSN(vmsleu_vi, 0b1010111, 0b011, 0b011100); ++ INSN(vmsne_vi, 0b1010111, 0b011, 0b011001); ++ INSN(vmseq_vi, 0b1010111, 0b011, 0b011000); ++ INSN(vxor_vi, 0b1010111, 0b011, 0b001011); ++ INSN(vor_vi, 0b1010111, 0b011, 0b001010); ++ INSN(vand_vi, 0b1010111, 0b011, 0b001001); ++ INSN(vadd_vi, 0b1010111, 0b011, 0b000000); ++ INSN(vrsub_vi, 0b1010111, 0b011, 0b000011); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, vm, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1) { \ ++ patch_VArith(op, Vd, funct3, Vs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Compress Instruction ++ INSN(vcompress_vm, 0b1010111, 0b010, 0b1, 0b010111); ++ ++ // Vector Mask-Register Logical Instructions ++ INSN(vmxnor_mm, 0b1010111, 0b010, 0b1, 0b011111); ++ INSN(vmorn_mm, 0b1010111, 0b010, 0b1, 0b011100); ++ INSN(vmnor_mm, 0b1010111, 0b010, 0b1, 0b011110); ++ INSN(vmor_mm, 0b1010111, 0b010, 0b1, 0b011010); ++ INSN(vmxor_mm, 0b1010111, 0b010, 0b1, 0b011011); ++ INSN(vmandn_mm, 0b1010111, 0b010, 0b1, 0b011000); ++ INSN(vmnand_mm, 0b1010111, 0b010, 0b1, 0b011101); ++ INSN(vmand_mm, 0b1010111, 0b010, 0b1, 0b011001); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, Vs2, vm, funct6) \ ++ void NAME(VectorRegister Vd, int32_t imm) { \ ++ guarantee(is_simm5(imm), "imm is invalid"); \ ++ patch_VArith(op, Vd, funct3, (uint32_t)(imm & 0x1f), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Integer Move Instructions ++ INSN(vmv_v_i, 0b1010111, 0b011, v0, 0b1, 0b010111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, Vs2, vm, funct6) \ ++ void NAME(VectorRegister Vd, FloatRegister Rs1) { \ ++ patch_VArith(op, Vd, funct3, Rs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Floating-Point Scalar Move Instructions ++ INSN(vfmv_s_f, 0b1010111, 0b101, v0, 0b1, 0b010000); ++ // Vector Floating-Point Move Instruction ++ INSN(vfmv_v_f, 0b1010111, 0b101, v0, 0b1, 0b010111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, Vs2, vm, funct6) \ ++ void NAME(VectorRegister Vd, VectorRegister Vs1) { \ ++ patch_VArith(op, Vd, funct3, Vs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Vector Integer Move Instructions ++ INSN(vmv_v_v, 0b1010111, 0b000, v0, 0b1, 0b010111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, Vs2, vm, funct6) \ ++ void NAME(VectorRegister Vd, Register Rs1) { \ ++ patch_VArith(op, Vd, funct3, Rs1->encoding_nocheck(), Vs2, vm, funct6); \ ++ } ++ ++ // Integer Scalar Move Instructions ++ INSN(vmv_s_x, 0b1010111, 0b110, v0, 0b1, 0b010000); ++ ++ // Vector Integer Move Instructions ++ INSN(vmv_v_x, 0b1010111, 0b100, v0, 0b1, 0b010111); ++ ++#undef INSN ++#undef patch_VArith ++ ++#define INSN(NAME, op, funct13, funct6) \ ++ void NAME(VectorRegister Vd, VectorMask vm = unmasked) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 24, 12, funct13); \ ++ patch((address)&insn, 25, vm); \ ++ patch((address)&insn, 31, 26, funct6); \ ++ patch_reg((address)&insn, 7, Vd); \ ++ emit(insn); \ ++ } ++ ++ // Vector Element Index Instruction ++ INSN(vid_v, 0b1010111, 0b0000010001010, 0b010100); ++ ++#undef INSN ++ ++enum Nf { ++ g1 = 0b000, ++ g2 = 0b001, ++ g3 = 0b010, ++ g4 = 0b011, ++ g5 = 0b100, ++ g6 = 0b101, ++ g7 = 0b110, ++ g8 = 0b111 ++}; ++ ++#define patch_VLdSt(op, VReg, width, Rs1, Reg_or_umop, vm, mop, mew, nf) \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, width); \ ++ patch((address)&insn, 24, 20, Reg_or_umop); \ ++ patch((address)&insn, 25, vm); \ ++ patch((address)&insn, 27, 26, mop); \ ++ patch((address)&insn, 28, mew); \ ++ patch((address)&insn, 31, 29, nf); \ ++ patch_reg((address)&insn, 7, VReg); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn) ++ ++#define INSN(NAME, op, lumop, vm, mop, nf) \ ++ void NAME(VectorRegister Vd, Register Rs1, uint32_t width = 0, bool mew = false) { \ ++ guarantee(is_uimm3(width), "width is invalid"); \ ++ patch_VLdSt(op, Vd, width, Rs1, lumop, vm, mop, mew, nf); \ ++ } ++ ++ // Vector Load/Store Instructions ++ INSN(vl1re8_v, 0b0000111, 0b01000, 0b1, 0b00, g1); ++ ++#undef INSN ++ ++#define INSN(NAME, op, width, sumop, vm, mop, mew, nf) \ ++ void NAME(VectorRegister Vs3, Register Rs1) { \ ++ patch_VLdSt(op, Vs3, width, Rs1, sumop, vm, mop, mew, nf); \ ++ } ++ ++ // Vector Load/Store Instructions ++ INSN(vs1r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g1); ++ ++#undef INSN ++ ++// r2_nfvm ++#define INSN(NAME, op, width, umop, mop, mew) \ ++ void NAME(VectorRegister Vd_or_Vs3, Register Rs1, Nf nf = g1) { \ ++ patch_VLdSt(op, Vd_or_Vs3, width, Rs1, umop, 1, mop, mew, nf); \ ++ } ++ ++ // Vector Unit-Stride Instructions ++ INSN(vlm_v, 0b0000111, 0b000, 0b01011, 0b00, 0b0); ++ INSN(vsm_v, 0b0100111, 0b000, 0b01011, 0b00, 0b0); ++ ++#undef INSN ++ ++#define INSN(NAME, op, width, umop, mop, mew) \ ++ void NAME(VectorRegister Vd_or_Vs3, Register Rs1, VectorMask vm = unmasked, Nf nf = g1) { \ ++ patch_VLdSt(op, Vd_or_Vs3, width, Rs1, umop, vm, mop, mew, nf); \ ++ } ++ ++ // Vector Unit-Stride Instructions ++ INSN(vle8_v, 0b0000111, 0b000, 0b00000, 0b00, 0b0); ++ INSN(vle16_v, 0b0000111, 0b101, 0b00000, 0b00, 0b0); ++ INSN(vle32_v, 0b0000111, 0b110, 0b00000, 0b00, 0b0); ++ INSN(vle64_v, 0b0000111, 0b111, 0b00000, 0b00, 0b0); ++ ++ // Vector unit-stride fault-only-first Instructions ++ INSN(vle8ff_v, 0b0000111, 0b000, 0b10000, 0b00, 0b0); ++ INSN(vle16ff_v, 0b0000111, 0b101, 0b10000, 0b00, 0b0); ++ INSN(vle32ff_v, 0b0000111, 0b110, 0b10000, 0b00, 0b0); ++ INSN(vle64ff_v, 0b0000111, 0b111, 0b10000, 0b00, 0b0); ++ ++ INSN(vse8_v, 0b0100111, 0b000, 0b00000, 0b00, 0b0); ++ INSN(vse16_v, 0b0100111, 0b101, 0b00000, 0b00, 0b0); ++ INSN(vse32_v, 0b0100111, 0b110, 0b00000, 0b00, 0b0); ++ INSN(vse64_v, 0b0100111, 0b111, 0b00000, 0b00, 0b0); ++ ++#undef INSN ++ ++#define INSN(NAME, op, width, mop, mew) \ ++ void NAME(VectorRegister Vd, Register Rs1, VectorRegister Vs2, VectorMask vm = unmasked, Nf nf = g1) { \ ++ patch_VLdSt(op, Vd, width, Rs1, Vs2->encoding_nocheck(), vm, mop, mew, nf); \ ++ } ++ ++ // Vector unordered indexed load instructions ++ INSN(vluxei8_v, 0b0000111, 0b000, 0b01, 0b0); ++ INSN(vluxei16_v, 0b0000111, 0b101, 0b01, 0b0); ++ INSN(vluxei32_v, 0b0000111, 0b110, 0b01, 0b0); ++ INSN(vluxei64_v, 0b0000111, 0b111, 0b01, 0b0); ++ ++ // Vector ordered indexed load instructions ++ INSN(vloxei8_v, 0b0000111, 0b000, 0b11, 0b0); ++ INSN(vloxei16_v, 0b0000111, 0b101, 0b11, 0b0); ++ INSN(vloxei32_v, 0b0000111, 0b110, 0b11, 0b0); ++ INSN(vloxei64_v, 0b0000111, 0b111, 0b11, 0b0); ++#undef INSN ++ ++#define INSN(NAME, op, width, mop, mew) \ ++ void NAME(VectorRegister Vd, Register Rs1, Register Rs2, VectorMask vm = unmasked, Nf nf = g1) { \ ++ patch_VLdSt(op, Vd, width, Rs1, Rs2->encoding_nocheck(), vm, mop, mew, nf); \ ++ } ++ ++ // Vector Strided Instructions ++ INSN(vlse8_v, 0b0000111, 0b000, 0b10, 0b0); ++ INSN(vlse16_v, 0b0000111, 0b101, 0b10, 0b0); ++ INSN(vlse32_v, 0b0000111, 0b110, 0b10, 0b0); ++ INSN(vlse64_v, 0b0000111, 0b111, 0b10, 0b0); ++ ++#undef INSN ++#undef patch_VLdSt ++ ++// ==================================== ++// RISC-V Bit-Manipulation Extension ++// Currently only support Zba, Zbb and Zbs bitmanip extensions. ++// ==================================== ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ patch_reg((address)&insn, 20, Rs2); \ ++ emit(insn); \ ++ } ++ ++ INSN(add_uw, 0b0111011, 0b000, 0b0000100); ++ INSN(rol, 0b0110011, 0b001, 0b0110000); ++ INSN(rolw, 0b0111011, 0b001, 0b0110000); ++ INSN(ror, 0b0110011, 0b101, 0b0110000); ++ INSN(rorw, 0b0111011, 0b101, 0b0110000); ++ INSN(sh1add, 0b0110011, 0b010, 0b0010000); ++ INSN(sh2add, 0b0110011, 0b100, 0b0010000); ++ INSN(sh3add, 0b0110011, 0b110, 0b0010000); ++ INSN(sh1add_uw, 0b0111011, 0b010, 0b0010000); ++ INSN(sh2add_uw, 0b0111011, 0b100, 0b0010000); ++ INSN(sh3add_uw, 0b0111011, 0b110, 0b0010000); ++ INSN(andn, 0b0110011, 0b111, 0b0100000); ++ INSN(orn, 0b0110011, 0b110, 0b0100000); ++ INSN(xnor, 0b0110011, 0b100, 0b0100000); ++ INSN(max, 0b0110011, 0b110, 0b0000101); ++ INSN(maxu, 0b0110011, 0b111, 0b0000101); ++ INSN(min, 0b0110011, 0b100, 0b0000101); ++ INSN(minu, 0b0110011, 0b101, 0b0000101); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct12) \ ++ void NAME(Register Rd, Register Rs1) { \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 31, 20, funct12); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(rev8, 0b0010011, 0b101, 0b011010111000); ++ INSN(sext_b, 0b0010011, 0b001, 0b011000000100); ++ INSN(sext_h, 0b0010011, 0b001, 0b011000000101); ++ INSN(zext_h, 0b0111011, 0b100, 0b000010000000); ++ INSN(clz, 0b0010011, 0b001, 0b011000000000); ++ INSN(clzw, 0b0011011, 0b001, 0b011000000000); ++ INSN(ctz, 0b0010011, 0b001, 0b011000000001); ++ INSN(ctzw, 0b0011011, 0b001, 0b011000000001); ++ INSN(cpop, 0b0010011, 0b001, 0b011000000010); ++ INSN(cpopw, 0b0011011, 0b001, 0b011000000010); ++ INSN(orc_b, 0b0010011, 0b101, 0b001010000111); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct6) \ ++ void NAME(Register Rd, Register Rs1, unsigned shamt) {\ ++ guarantee(shamt <= 0x3f, "Shamt is invalid"); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 25, 20, shamt); \ ++ patch((address)&insn, 31, 26, funct6); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(rori, 0b0010011, 0b101, 0b011000); ++ INSN(slli_uw, 0b0011011, 0b001, 0b000010); ++ INSN(bexti, 0b0010011, 0b101, 0b010010); ++ ++#undef INSN ++ ++#define INSN(NAME, op, funct3, funct7) \ ++ void NAME(Register Rd, Register Rs1, unsigned shamt) {\ ++ guarantee(shamt <= 0x1f, "Shamt is invalid"); \ ++ unsigned insn = 0; \ ++ patch((address)&insn, 6, 0, op); \ ++ patch((address)&insn, 14, 12, funct3); \ ++ patch((address)&insn, 24, 20, shamt); \ ++ patch((address)&insn, 31, 25, funct7); \ ++ patch_reg((address)&insn, 7, Rd); \ ++ patch_reg((address)&insn, 15, Rs1); \ ++ emit(insn); \ ++ } ++ ++ INSN(roriw, 0b0011011, 0b101, 0b0110000); ++ ++#undef INSN ++ ++// ======================================== ++// RISC-V Compressed Instructions Extension ++// ======================================== ++// Note: ++// 1. Assembler functions encoding 16-bit compressed instructions always begin with a 'c_' ++// prefix, such as 'c_add'. Correspondingly, assembler functions encoding normal 32-bit ++// instructions with begin with a '_' prefix, such as "_add". Most of time users have no ++// need to explicitly emit these compressed instructions. Instead, they still use unified ++// wrappers such as 'add' which do the compressing work through 'c_add' depending on the ++// the operands of the instruction and availability of the RVC hardware extension. ++// ++// 2. 'CompressibleRegion' and 'IncompressibleRegion' are introduced to mark assembler scopes ++// within which instructions are qualified or unqualified to be compressed into their 16-bit ++// versions. An example: ++// ++// CompressibleRegion cr(_masm); ++// __ add(...); // this instruction will be compressed into 'c.add' when possible ++// { ++// IncompressibleRegion ir(_masm); ++// __ add(...); // this instruction will not be compressed ++// { ++// CompressibleRegion cr(_masm); ++// __ add(...); // this instruction will be compressed into 'c.add' when possible ++// } ++// } ++// ++// 3. When printing JIT assembly code, using -XX:PrintAssemblyOptions=no-aliases could help ++// distinguish compressed 16-bit instructions from normal 32-bit ones. ++ ++private: ++ bool _in_compressible_region; ++public: ++ bool in_compressible_region() const { return _in_compressible_region; } ++ void set_in_compressible_region(bool b) { _in_compressible_region = b; } ++public: ++ ++ // an abstract compressible region ++ class AbstractCompressibleRegion : public StackObj { ++ protected: ++ Assembler *_masm; ++ bool _saved_in_compressible_region; ++ protected: ++ AbstractCompressibleRegion(Assembler *_masm) ++ : _masm(_masm) ++ , _saved_in_compressible_region(_masm->in_compressible_region()) {} ++ }; ++ // a compressible region ++ class CompressibleRegion : public AbstractCompressibleRegion { ++ public: ++ CompressibleRegion(Assembler *_masm) : AbstractCompressibleRegion(_masm) { ++ _masm->set_in_compressible_region(true); ++ } ++ ~CompressibleRegion() { ++ _masm->set_in_compressible_region(_saved_in_compressible_region); ++ } ++ }; ++ // an incompressible region ++ class IncompressibleRegion : public AbstractCompressibleRegion { ++ public: ++ IncompressibleRegion(Assembler *_masm) : AbstractCompressibleRegion(_masm) { ++ _masm->set_in_compressible_region(false); ++ } ++ ~IncompressibleRegion() { ++ _masm->set_in_compressible_region(_saved_in_compressible_region); ++ } ++ }; ++ ++public: ++ // Emit a relocation. ++ void relocate(RelocationHolder const& rspec, int format = 0) { ++ AbstractAssembler::relocate(rspec, format); ++ } ++ void relocate(relocInfo::relocType rtype, int format = 0) { ++ AbstractAssembler::relocate(rtype, format); ++ } ++ template ++ void relocate(RelocationHolder const& rspec, Callback emit_insts, int format = 0) { ++ AbstractAssembler::relocate(rspec, format); ++ IncompressibleRegion ir(this); // relocations ++ emit_insts(); ++ } ++ template ++ void relocate(relocInfo::relocType rtype, Callback emit_insts, int format = 0) { ++ AbstractAssembler::relocate(rtype, format); ++ IncompressibleRegion ir(this); // relocations ++ emit_insts(); ++ } ++ ++ // patch a 16-bit instruction. ++ static void c_patch(address a, unsigned msb, unsigned lsb, uint16_t val) { ++ assert_cond(a != NULL); ++ assert_cond(msb >= lsb && msb <= 15); ++ unsigned nbits = msb - lsb + 1; ++ guarantee(val < (1U << nbits), "Field too big for insn"); ++ uint16_t mask = (1U << nbits) - 1; ++ val <<= lsb; ++ mask <<= lsb; ++ uint16_t target = *(uint16_t *)a; ++ target &= ~mask; ++ target |= val; ++ *(uint16_t *)a = target; ++ } ++ ++ static void c_patch(address a, unsigned bit, uint16_t val) { ++ c_patch(a, bit, bit, val); ++ } ++ ++ // patch a 16-bit instruction with a general purpose register ranging [0, 31] (5 bits) ++ static void c_patch_reg(address a, unsigned lsb, Register reg) { ++ c_patch(a, lsb + 4, lsb, reg->encoding_nocheck()); ++ } ++ ++ // patch a 16-bit instruction with a general purpose register ranging [8, 15] (3 bits) ++ static void c_patch_compressed_reg(address a, unsigned lsb, Register reg) { ++ c_patch(a, lsb + 2, lsb, reg->compressed_encoding_nocheck()); ++ } ++ ++ // patch a 16-bit instruction with a float register ranging [0, 31] (5 bits) ++ static void c_patch_reg(address a, unsigned lsb, FloatRegister reg) { ++ c_patch(a, lsb + 4, lsb, reg->encoding_nocheck()); ++ } ++ ++ // patch a 16-bit instruction with a float register ranging [8, 15] (3 bits) ++ static void c_patch_compressed_reg(address a, unsigned lsb, FloatRegister reg) { ++ c_patch(a, lsb + 2, lsb, reg->compressed_encoding_nocheck()); ++ } ++ ++// -------------- RVC Instruction Definitions -------------- ++ ++ void c_nop() { ++ c_addi(x0, 0); ++ } ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd_Rs1, int32_t imm) { \ ++ assert_cond(is_simm6(imm)); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 6, 2, (imm & right_n_bits(5))); \ ++ c_patch_reg((address)&insn, 7, Rd_Rs1); \ ++ c_patch((address)&insn, 12, 12, (imm & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_addi, 0b000, 0b01); ++ INSN(c_addiw, 0b001, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(int32_t imm) { \ ++ assert_cond(is_simm10(imm)); \ ++ assert_cond((imm & 0b1111) == 0); \ ++ assert_cond(imm != 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 2, 2, (imm & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 4, 3, (imm & right_n_bits(9)) >> 7); \ ++ c_patch((address)&insn, 5, 5, (imm & nth_bit(6)) >> 6); \ ++ c_patch((address)&insn, 6, 6, (imm & nth_bit(4)) >> 4); \ ++ c_patch_reg((address)&insn, 7, sp); \ ++ c_patch((address)&insn, 12, 12, (imm & nth_bit(9)) >> 9); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_addi16sp, 0b011, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd, uint32_t uimm) { \ ++ assert_cond(is_uimm10(uimm)); \ ++ assert_cond((uimm & 0b11) == 0); \ ++ assert_cond(uimm != 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_compressed_reg((address)&insn, 2, Rd); \ ++ c_patch((address)&insn, 5, 5, (uimm & nth_bit(3)) >> 3); \ ++ c_patch((address)&insn, 6, 6, (uimm & nth_bit(2)) >> 2); \ ++ c_patch((address)&insn, 10, 7, (uimm & right_n_bits(10)) >> 6); \ ++ c_patch((address)&insn, 12, 11, (uimm & right_n_bits(6)) >> 4); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_addi4spn, 0b000, 0b00); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd_Rs1, uint32_t shamt) { \ ++ assert_cond(is_uimm6(shamt)); \ ++ assert_cond(shamt != 0); \ ++ assert_cond(Rd_Rs1 != x0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 6, 2, (shamt & right_n_bits(5))); \ ++ c_patch_reg((address)&insn, 7, Rd_Rs1); \ ++ c_patch((address)&insn, 12, 12, (shamt & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_slli, 0b000, 0b10); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, funct2, op) \ ++ void NAME(Register Rd_Rs1, uint32_t shamt) { \ ++ assert_cond(is_uimm6(shamt)); \ ++ assert_cond(shamt != 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 6, 2, (shamt & right_n_bits(5))); \ ++ c_patch_compressed_reg((address)&insn, 7, Rd_Rs1); \ ++ c_patch((address)&insn, 11, 10, funct2); \ ++ c_patch((address)&insn, 12, 12, (shamt & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_srli, 0b100, 0b00, 0b01); ++ INSN(c_srai, 0b100, 0b01, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, funct2, op) \ ++ void NAME(Register Rd_Rs1, int32_t imm) { \ ++ assert_cond(is_simm6(imm)); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 6, 2, (imm & right_n_bits(5))); \ ++ c_patch_compressed_reg((address)&insn, 7, Rd_Rs1); \ ++ c_patch((address)&insn, 11, 10, funct2); \ ++ c_patch((address)&insn, 12, 12, (imm & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_andi, 0b100, 0b10, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct6, funct2, op) \ ++ void NAME(Register Rd_Rs1, Register Rs2) { \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_compressed_reg((address)&insn, 2, Rs2); \ ++ c_patch((address)&insn, 6, 5, funct2); \ ++ c_patch_compressed_reg((address)&insn, 7, Rd_Rs1); \ ++ c_patch((address)&insn, 15, 10, funct6); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_sub, 0b100011, 0b00, 0b01); ++ INSN(c_xor, 0b100011, 0b01, 0b01); ++ INSN(c_or, 0b100011, 0b10, 0b01); ++ INSN(c_and, 0b100011, 0b11, 0b01); ++ INSN(c_subw, 0b100111, 0b00, 0b01); ++ INSN(c_addw, 0b100111, 0b01, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct4, op) \ ++ void NAME(Register Rd_Rs1, Register Rs2) { \ ++ assert_cond(Rd_Rs1 != x0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_reg((address)&insn, 2, Rs2); \ ++ c_patch_reg((address)&insn, 7, Rd_Rs1); \ ++ c_patch((address)&insn, 15, 12, funct4); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_mv, 0b1000, 0b10); ++ INSN(c_add, 0b1001, 0b10); ++ ++#undef INSN ++ ++#define INSN(NAME, funct4, op) \ ++ void NAME(Register Rs1) { \ ++ assert_cond(Rs1 != x0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_reg((address)&insn, 2, x0); \ ++ c_patch_reg((address)&insn, 7, Rs1); \ ++ c_patch((address)&insn, 15, 12, funct4); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_jr, 0b1000, 0b10); ++ INSN(c_jalr, 0b1001, 0b10); ++ ++#undef INSN ++ ++ typedef void (Assembler::* j_c_insn)(address dest); ++ typedef void (Assembler::* compare_and_branch_c_insn)(Register Rs1, address dest); ++ ++ void wrap_label(Label &L, j_c_insn insn) { ++ if (L.is_bound()) { ++ (this->*insn)(target(L)); ++ } else { ++ L.add_patch_at(code(), locator()); ++ (this->*insn)(pc()); ++ } ++ } ++ ++ void wrap_label(Label &L, Register r, compare_and_branch_c_insn insn) { ++ if (L.is_bound()) { ++ (this->*insn)(r, target(L)); ++ } else { ++ L.add_patch_at(code(), locator()); ++ (this->*insn)(r, pc()); ++ } ++ } ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(int32_t offset) { \ ++ assert(is_simm12(offset) && ((offset % 2) == 0), "invalid encoding"); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 2, 2, (offset & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 5, 3, (offset & right_n_bits(4)) >> 1); \ ++ c_patch((address)&insn, 6, 6, (offset & nth_bit(7)) >> 7); \ ++ c_patch((address)&insn, 7, 7, (offset & nth_bit(6)) >> 6); \ ++ c_patch((address)&insn, 8, 8, (offset & nth_bit(10)) >> 10); \ ++ c_patch((address)&insn, 10, 9, (offset & right_n_bits(10)) >> 8); \ ++ c_patch((address)&insn, 11, 11, (offset & nth_bit(4)) >> 4); \ ++ c_patch((address)&insn, 12, 12, (offset & nth_bit(11)) >> 11); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } \ ++ void NAME(address dest) { \ ++ assert_cond(dest != NULL); \ ++ int64_t distance = dest - pc(); \ ++ assert(is_simm12(distance) && ((distance % 2) == 0), "invalid encoding"); \ ++ c_j(distance); \ ++ } \ ++ void NAME(Label &L) { \ ++ wrap_label(L, &Assembler::NAME); \ ++ } ++ ++ INSN(c_j, 0b101, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rs1, int32_t imm) { \ ++ assert(is_simm9(imm) && ((imm % 2) == 0), "invalid encoding"); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 2, 2, (imm & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 4, 3, (imm & right_n_bits(3)) >> 1); \ ++ c_patch((address)&insn, 6, 5, (imm & right_n_bits(8)) >> 6); \ ++ c_patch_compressed_reg((address)&insn, 7, Rs1); \ ++ c_patch((address)&insn, 11, 10, (imm & right_n_bits(5)) >> 3); \ ++ c_patch((address)&insn, 12, 12, (imm & nth_bit(8)) >> 8); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } \ ++ void NAME(Register Rs1, address dest) { \ ++ assert_cond(dest != NULL); \ ++ int64_t distance = dest - pc(); \ ++ assert(is_simm9(distance) && ((distance % 2) == 0), "invalid encoding"); \ ++ NAME(Rs1, distance); \ ++ } \ ++ void NAME(Register Rs1, Label &L) { \ ++ wrap_label(L, Rs1, &Assembler::NAME); \ ++ } ++ ++ INSN(c_beqz, 0b110, 0b01); ++ INSN(c_bnez, 0b111, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd, int32_t imm) { \ ++ assert_cond(is_simm18(imm)); \ ++ assert_cond((imm & 0xfff) == 0); \ ++ assert_cond(imm != 0); \ ++ assert_cond(Rd != x0 && Rd != x2); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 6, 2, (imm & right_n_bits(17)) >> 12); \ ++ c_patch_reg((address)&insn, 7, Rd); \ ++ c_patch((address)&insn, 12, 12, (imm & nth_bit(17)) >> 17); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_lui, 0b011, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd, int32_t imm) { \ ++ assert_cond(is_simm6(imm)); \ ++ assert_cond(Rd != x0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 6, 2, (imm & right_n_bits(5))); \ ++ c_patch_reg((address)&insn, 7, Rd); \ ++ c_patch((address)&insn, 12, 12, (imm & right_n_bits(6)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_li, 0b010, 0b01); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd, uint32_t uimm) { \ ++ assert_cond(is_uimm9(uimm)); \ ++ assert_cond((uimm & 0b111) == 0); \ ++ assert_cond(Rd != x0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 4, 2, (uimm & right_n_bits(9)) >> 6); \ ++ c_patch((address)&insn, 6, 5, (uimm & right_n_bits(5)) >> 3); \ ++ c_patch_reg((address)&insn, 7, Rd); \ ++ c_patch((address)&insn, 12, 12, (uimm & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_ldsp, 0b011, 0b10); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(FloatRegister Rd, uint32_t uimm) { \ ++ assert_cond(is_uimm9(uimm)); \ ++ assert_cond((uimm & 0b111) == 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 4, 2, (uimm & right_n_bits(9)) >> 6); \ ++ c_patch((address)&insn, 6, 5, (uimm & right_n_bits(5)) >> 3); \ ++ c_patch_reg((address)&insn, 7, Rd); \ ++ c_patch((address)&insn, 12, 12, (uimm & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_fldsp, 0b001, 0b10); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op, REGISTER_TYPE) \ ++ void NAME(REGISTER_TYPE Rd_Rs2, Register Rs1, uint32_t uimm) { \ ++ assert_cond(is_uimm8(uimm)); \ ++ assert_cond((uimm & 0b111) == 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_compressed_reg((address)&insn, 2, Rd_Rs2); \ ++ c_patch((address)&insn, 6, 5, (uimm & right_n_bits(8)) >> 6); \ ++ c_patch_compressed_reg((address)&insn, 7, Rs1); \ ++ c_patch((address)&insn, 12, 10, (uimm & right_n_bits(6)) >> 3); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_ld, 0b011, 0b00, Register); ++ INSN(c_sd, 0b111, 0b00, Register); ++ INSN(c_fld, 0b001, 0b00, FloatRegister); ++ INSN(c_fsd, 0b101, 0b00, FloatRegister); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op, REGISTER_TYPE) \ ++ void NAME(REGISTER_TYPE Rs2, uint32_t uimm) { \ ++ assert_cond(is_uimm9(uimm)); \ ++ assert_cond((uimm & 0b111) == 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_reg((address)&insn, 2, Rs2); \ ++ c_patch((address)&insn, 9, 7, (uimm & right_n_bits(9)) >> 6); \ ++ c_patch((address)&insn, 12, 10, (uimm & right_n_bits(6)) >> 3); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_sdsp, 0b111, 0b10, Register); ++ INSN(c_fsdsp, 0b101, 0b10, FloatRegister); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rs2, uint32_t uimm) { \ ++ assert_cond(is_uimm8(uimm)); \ ++ assert_cond((uimm & 0b11) == 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_reg((address)&insn, 2, Rs2); \ ++ c_patch((address)&insn, 8, 7, (uimm & right_n_bits(8)) >> 6); \ ++ c_patch((address)&insn, 12, 9, (uimm & right_n_bits(6)) >> 2); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_swsp, 0b110, 0b10); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd, uint32_t uimm) { \ ++ assert_cond(is_uimm8(uimm)); \ ++ assert_cond((uimm & 0b11) == 0); \ ++ assert_cond(Rd != x0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 3, 2, (uimm & right_n_bits(8)) >> 6); \ ++ c_patch((address)&insn, 6, 4, (uimm & right_n_bits(5)) >> 2); \ ++ c_patch_reg((address)&insn, 7, Rd); \ ++ c_patch((address)&insn, 12, 12, (uimm & nth_bit(5)) >> 5); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_lwsp, 0b010, 0b10); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME(Register Rd_Rs2, Register Rs1, uint32_t uimm) { \ ++ assert_cond(is_uimm7(uimm)); \ ++ assert_cond((uimm & 0b11) == 0); \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch_compressed_reg((address)&insn, 2, Rd_Rs2); \ ++ c_patch((address)&insn, 5, 5, (uimm & nth_bit(6)) >> 6); \ ++ c_patch((address)&insn, 6, 6, (uimm & nth_bit(2)) >> 2); \ ++ c_patch_compressed_reg((address)&insn, 7, Rs1); \ ++ c_patch((address)&insn, 12, 10, (uimm & right_n_bits(6)) >> 3); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_lw, 0b010, 0b00); ++ INSN(c_sw, 0b110, 0b00); ++ ++#undef INSN ++ ++#define INSN(NAME, funct3, op) \ ++ void NAME() { \ ++ uint16_t insn = 0; \ ++ c_patch((address)&insn, 1, 0, op); \ ++ c_patch((address)&insn, 11, 2, 0x0); \ ++ c_patch((address)&insn, 12, 12, 0b1); \ ++ c_patch((address)&insn, 15, 13, funct3); \ ++ emit_int16(insn); \ ++ } ++ ++ INSN(c_ebreak, 0b100, 0b10); ++ ++#undef INSN ++ ++// -------------- RVC Transformation Functions -------------- ++ ++// -------------------------- ++// Register instructions ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2) { \ ++ /* add -> c.add */ \ ++ if (do_compress()) { \ ++ Register src = noreg; \ ++ if (Rs1 != x0 && Rs2 != x0 && ((src = Rs1, Rs2 == Rd) || (src = Rs2, Rs1 == Rd))) { \ ++ c_add(Rd, src); \ ++ return; \ ++ } \ ++ } \ ++ _add(Rd, Rs1, Rs2); \ ++ } ++ ++ INSN(add); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME, C_NAME, NORMAL_NAME) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2) { \ ++ /* sub/subw -> c.sub/c.subw */ \ ++ if (do_compress() && \ ++ (Rd == Rs1 && Rd->is_compressed_valid() && Rs2->is_compressed_valid())) { \ ++ C_NAME(Rd, Rs2); \ ++ return; \ ++ } \ ++ NORMAL_NAME(Rd, Rs1, Rs2); \ ++ } ++ ++ INSN(sub, c_sub, _sub); ++ INSN(subw, c_subw, _subw); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME, C_NAME, NORMAL_NAME) \ ++ void NAME(Register Rd, Register Rs1, Register Rs2) { \ ++ /* and/or/xor/addw -> c.and/c.or/c.xor/c.addw */ \ ++ if (do_compress()) { \ ++ Register src = noreg; \ ++ if (Rs1->is_compressed_valid() && Rs2->is_compressed_valid() && \ ++ ((src = Rs1, Rs2 == Rd) || (src = Rs2, Rs1 == Rd))) { \ ++ C_NAME(Rd, src); \ ++ return; \ ++ } \ ++ } \ ++ NORMAL_NAME(Rd, Rs1, Rs2); \ ++ } ++ ++ INSN(andr, c_and, _andr); ++ INSN(orr, c_or, _orr); ++ INSN(xorr, c_xor, _xorr); ++ INSN(addw, c_addw, _addw); ++ ++#undef INSN ++ ++private: ++// some helper functions ++#define FUNC(NAME, funct3, bits) \ ++ bool NAME(Register rs1, Register rd_rs2, int32_t imm12, bool ld) { \ ++ return rs1 == sp && \ ++ is_uimm(imm12, bits) && \ ++ (intx(imm12) & funct3) == 0x0 && \ ++ (!ld || rd_rs2 != x0); \ ++ } \ ++ ++ FUNC(is_c_ldsdsp, 0b111, 9); ++ FUNC(is_c_lwswsp, 0b011, 8); ++ ++#undef FUNC ++ ++#define FUNC(NAME, funct3, bits) \ ++ bool NAME(Register rs1, int32_t imm12) { \ ++ return rs1 == sp && \ ++ is_uimm(imm12, bits) && \ ++ (intx(imm12) & funct3) == 0x0; \ ++ } \ ++ ++ FUNC(is_c_fldsdsp, 0b111, 9); ++ ++#undef FUNC ++ ++#define FUNC(NAME, REG_TYPE, funct3, bits) \ ++ bool NAME(Register rs1, REG_TYPE rd_rs2, int32_t imm12) { \ ++ return rs1->is_compressed_valid() && \ ++ rd_rs2->is_compressed_valid() && \ ++ is_uimm(imm12, bits) && \ ++ (intx(imm12) & funct3) == 0x0; \ ++ } \ ++ ++ FUNC(is_c_ldsd, Register, 0b111, 8); ++ FUNC(is_c_lwsw, Register, 0b011, 7); ++ FUNC(is_c_fldsd, FloatRegister, 0b111, 8); ++ ++#undef FUNC ++ ++public: ++ bool do_compress() const { ++ return UseRVC && in_compressible_region(); ++ } ++ ++// -------------------------- ++// Load/store register ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs, const int32_t offset) { \ ++ /* lw -> c.lwsp/c.lw */ \ ++ if (do_compress()) { \ ++ if (is_c_lwswsp(Rs, Rd, offset, true)) { \ ++ c_lwsp(Rd, offset); \ ++ return; \ ++ } else if (is_c_lwsw(Rs, Rd, offset)) { \ ++ c_lw(Rd, Rs, offset); \ ++ return; \ ++ } \ ++ } \ ++ _lw(Rd, Rs, offset); \ ++ } ++ ++ INSN(lw); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs, const int32_t offset) { \ ++ /* ld -> c.ldsp/c.ld */ \ ++ if (do_compress()) { \ ++ if (is_c_ldsdsp(Rs, Rd, offset, true)) { \ ++ c_ldsp(Rd, offset); \ ++ return; \ ++ } else if (is_c_ldsd(Rs, Rd, offset)) { \ ++ c_ld(Rd, Rs, offset); \ ++ return; \ ++ } \ ++ } \ ++ _ld(Rd, Rs, offset); \ ++ } ++ ++ INSN(ld); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(FloatRegister Rd, Register Rs, const int32_t offset) { \ ++ /* fld -> c.fldsp/c.fld */ \ ++ if (do_compress()) { \ ++ if (is_c_fldsdsp(Rs, offset)) { \ ++ c_fldsp(Rd, offset); \ ++ return; \ ++ } else if (is_c_fldsd(Rs, Rd, offset)) { \ ++ c_fld(Rd, Rs, offset); \ ++ return; \ ++ } \ ++ } \ ++ _fld(Rd, Rs, offset); \ ++ } ++ ++ INSN(fld); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs, const int32_t offset) { \ ++ /* sd -> c.sdsp/c.sd */ \ ++ if (do_compress()) { \ ++ if (is_c_ldsdsp(Rs, Rd, offset, false)) { \ ++ c_sdsp(Rd, offset); \ ++ return; \ ++ } else if (is_c_ldsd(Rs, Rd, offset)) { \ ++ c_sd(Rd, Rs, offset); \ ++ return; \ ++ } \ ++ } \ ++ _sd(Rd, Rs, offset); \ ++ } ++ ++ INSN(sd); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs, const int32_t offset) { \ ++ /* sw -> c.swsp/c.sw */ \ ++ if (do_compress()) { \ ++ if (is_c_lwswsp(Rs, Rd, offset, false)) { \ ++ c_swsp(Rd, offset); \ ++ return; \ ++ } else if (is_c_lwsw(Rs, Rd, offset)) { \ ++ c_sw(Rd, Rs, offset); \ ++ return; \ ++ } \ ++ } \ ++ _sw(Rd, Rs, offset); \ ++ } ++ ++ INSN(sw); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(FloatRegister Rd, Register Rs, const int32_t offset) { \ ++ /* fsd -> c.fsdsp/c.fsd */ \ ++ if (do_compress()) { \ ++ if (is_c_fldsdsp(Rs, offset)) { \ ++ c_fsdsp(Rd, offset); \ ++ return; \ ++ } else if (is_c_fldsd(Rs, Rd, offset)) { \ ++ c_fsd(Rd, Rs, offset); \ ++ return; \ ++ } \ ++ } \ ++ _fsd(Rd, Rs, offset); \ ++ } ++ ++ INSN(fsd); ++ ++#undef INSN ++ ++// -------------------------- ++// Unconditional branch instructions ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs, const int32_t offset) { \ ++ /* jalr -> c.jr/c.jalr */ \ ++ if (do_compress() && (offset == 0 && Rs != x0)) { \ ++ if (Rd == x1) { \ ++ c_jalr(Rs); \ ++ return; \ ++ } else if (Rd == x0) { \ ++ c_jr(Rs); \ ++ return; \ ++ } \ ++ } \ ++ _jalr(Rd, Rs, offset); \ ++ } ++ ++ INSN(jalr); ++ ++#undef INSN ++ ++// -------------------------- ++// Miscellaneous Instructions ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME() { \ ++ /* ebreak -> c.ebreak */ \ ++ if (do_compress()) { \ ++ c_ebreak(); \ ++ return; \ ++ } \ ++ _ebreak(); \ ++ } ++ ++ INSN(ebreak); ++ ++#undef INSN ++ ++// -------------------------- ++// Immediate Instructions ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs1, int32_t imm) { \ ++ /* addi -> c.addi/c.nop/c.mv/c.addi16sp/c.addi4spn */ \ ++ if (do_compress()) { \ ++ if (Rd == Rs1 && is_simm6(imm)) { \ ++ c_addi(Rd, imm); \ ++ return; \ ++ } else if (imm == 0 && Rd != x0 && Rs1 != x0) { \ ++ c_mv(Rd, Rs1); \ ++ return; \ ++ } else if (Rs1 == sp && imm != 0) { \ ++ if (Rd == Rs1 && (imm & 0b1111) == 0x0 && is_simm10(imm)) { \ ++ c_addi16sp(imm); \ ++ return; \ ++ } else if (Rd->is_compressed_valid() && (imm & 0b11) == 0x0 && is_uimm10(imm)) { \ ++ c_addi4spn(Rd, imm); \ ++ return; \ ++ } \ ++ } \ ++ } \ ++ _addi(Rd, Rs1, imm); \ ++ } ++ ++ INSN(addi); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs1, int32_t imm) { \ ++ /* addiw -> c.addiw */ \ ++ if (do_compress() && (Rd == Rs1 && Rd != x0 && is_simm6(imm))) { \ ++ c_addiw(Rd, imm); \ ++ return; \ ++ } \ ++ _addiw(Rd, Rs1, imm); \ ++ } ++ ++ INSN(addiw); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs1, int32_t imm) { \ ++ /* and_imm12 -> c.andi */ \ ++ if (do_compress() && \ ++ (Rd == Rs1 && Rd->is_compressed_valid() && is_simm6(imm))) { \ ++ c_andi(Rd, imm); \ ++ return; \ ++ } \ ++ _and_imm12(Rd, Rs1, imm); \ ++ } ++ ++ INSN(and_imm12); ++ ++#undef INSN ++ ++// -------------------------- ++// Shift Immediate Instructions ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, Register Rs1, unsigned shamt) { \ ++ /* slli -> c.slli */ \ ++ if (do_compress() && (Rd == Rs1 && Rd != x0 && shamt != 0)) { \ ++ c_slli(Rd, shamt); \ ++ return; \ ++ } \ ++ _slli(Rd, Rs1, shamt); \ ++ } ++ ++ INSN(slli); ++ ++#undef INSN ++ ++// -------------------------- ++#define INSN(NAME, C_NAME, NORMAL_NAME) \ ++ void NAME(Register Rd, Register Rs1, unsigned shamt) { \ ++ /* srai/srli -> c.srai/c.srli */ \ ++ if (do_compress() && (Rd == Rs1 && Rd->is_compressed_valid() && shamt != 0)) { \ ++ C_NAME(Rd, shamt); \ ++ return; \ ++ } \ ++ NORMAL_NAME(Rd, Rs1, shamt); \ ++ } ++ ++ INSN(srai, c_srai, _srai); ++ INSN(srli, c_srli, _srli); ++ ++#undef INSN ++ ++// -------------------------- ++// Upper Immediate Instruction ++// -------------------------- ++#define INSN(NAME) \ ++ void NAME(Register Rd, int32_t imm) { \ ++ /* lui -> c.lui */ \ ++ if (do_compress() && (Rd != x0 && Rd != x2 && imm != 0 && is_simm18(imm))) { \ ++ c_lui(Rd, imm); \ ++ return; \ ++ } \ ++ _lui(Rd, imm); \ ++ } ++ ++ INSN(lui); ++ ++#undef INSN ++ ++// --------------------------------------------------------------------------------------- ++ ++#define INSN(NAME, REGISTER) \ ++ void NAME(Register Rs) { \ ++ jalr(REGISTER, Rs, 0); \ ++ } ++ ++ INSN(jr, x0); ++ INSN(jalr, x1); ++ ++#undef INSN ++ ++ // Stack overflow checking ++ virtual void bang_stack_with_offset(int offset) { Unimplemented(); } ++ ++ static bool is_simm5(int64_t x); ++ static bool is_simm6(int64_t x); ++ static bool is_simm12(int64_t x); ++ static bool is_simm13(int64_t x); ++ static bool is_simm18(int64_t x); ++ static bool is_simm21(int64_t x); ++ ++ static bool is_uimm3(uint64_t x); ++ static bool is_uimm5(uint64_t x); ++ static bool is_uimm6(uint64_t x); ++ static bool is_uimm7(uint64_t x); ++ static bool is_uimm8(uint64_t x); ++ static bool is_uimm9(uint64_t x); ++ static bool is_uimm10(uint64_t x); ++ ++ // The maximum range of a branch is fixed for the RISCV architecture. ++ static const unsigned long branch_range = 1 * M; ++ ++ static bool reachable_from_branch_at(address branch, address target) { ++ return uabs(target - branch) < branch_range; ++ } ++ ++ Assembler(CodeBuffer* code) : AbstractAssembler(code), _in_compressible_region(false) {} ++ ++ virtual ~Assembler() {} ++}; ++ ++class BiasedLockingCounters; ++ ++#endif // CPU_RISCV_ASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/assembler_riscv.inline.hpp +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_ASSEMBLER_RISCV_INLINE_HPP ++#define CPU_RISCV_ASSEMBLER_RISCV_INLINE_HPP ++ ++#include "asm/assembler.inline.hpp" ++#include "asm/codeBuffer.hpp" ++#include "code/codeCache.hpp" ++ ++inline bool Assembler::is_simm5(int64_t x) { return is_simm(x, 5); } ++inline bool Assembler::is_simm6(int64_t x) { return is_simm(x, 6); } ++inline bool Assembler::is_simm12(int64_t x) { return is_simm(x, 12); } ++inline bool Assembler::is_simm13(int64_t x) { return is_simm(x, 13); } ++inline bool Assembler::is_simm18(int64_t x) { return is_simm(x, 18); } ++inline bool Assembler::is_simm21(int64_t x) { return is_simm(x, 21); } ++ ++inline bool Assembler::is_uimm3(uint64_t x) { return is_uimm(x, 3); } ++inline bool Assembler::is_uimm5(uint64_t x) { return is_uimm(x, 5); } ++inline bool Assembler::is_uimm6(uint64_t x) { return is_uimm(x, 6); } ++inline bool Assembler::is_uimm7(uint64_t x) { return is_uimm(x, 7); } ++inline bool Assembler::is_uimm8(uint64_t x) { return is_uimm(x, 8); } ++inline bool Assembler::is_uimm9(uint64_t x) { return is_uimm(x, 9); } ++inline bool Assembler::is_uimm10(uint64_t x) { return is_uimm(x, 10); } ++ ++#endif // CPU_RISCV_ASSEMBLER_RISCV_INLINE_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/bytes_riscv.hpp +@@ -0,0 +1,169 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2012, 2016 SAP SE. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_BYTES_RISCV_HPP ++#define CPU_RISCV_BYTES_RISCV_HPP ++ ++#include "memory/allStatic.hpp" ++ ++class Bytes: AllStatic { ++ public: ++ // Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering ++ // RISCV needs to check for alignment. ++ ++ // Forward declarations of the compiler-dependent implementation ++ static inline u2 swap_u2(u2 x); ++ static inline u4 swap_u4(u4 x); ++ static inline u8 swap_u8(u8 x); ++ ++ static inline u2 get_native_u2(address p) { ++ if ((intptr_t(p) & 1) == 0) { ++ return *(u2*)p; ++ } else { ++ return ((u2)(p[1]) << 8) | ++ ((u2)(p[0])); ++ } ++ } ++ ++ static inline u4 get_native_u4(address p) { ++ switch (intptr_t(p) & 3) { ++ case 0: ++ return *(u4*)p; ++ ++ case 2: ++ return ((u4)(((u2*)p)[1]) << 16) | ++ ((u4)(((u2*)p)[0])); ++ ++ default: ++ return ((u4)(p[3]) << 24) | ++ ((u4)(p[2]) << 16) | ++ ((u4)(p[1]) << 8) | ++ ((u4)(p[0])); ++ } ++ } ++ ++ static inline u8 get_native_u8(address p) { ++ switch (intptr_t(p) & 7) { ++ case 0: ++ return *(u8*)p; ++ ++ case 4: ++ return ((u8)(((u4*)p)[1]) << 32) | ++ ((u8)(((u4*)p)[0])); ++ ++ case 2: ++ case 6: ++ return ((u8)(((u2*)p)[3]) << 48) | ++ ((u8)(((u2*)p)[2]) << 32) | ++ ((u8)(((u2*)p)[1]) << 16) | ++ ((u8)(((u2*)p)[0])); ++ ++ default: ++ return ((u8)(p[7]) << 56) | ++ ((u8)(p[6]) << 48) | ++ ((u8)(p[5]) << 40) | ++ ((u8)(p[4]) << 32) | ++ ((u8)(p[3]) << 24) | ++ ((u8)(p[2]) << 16) | ++ ((u8)(p[1]) << 8) | ++ ((u8)(p[0])); ++ } ++ } ++ ++ static inline void put_native_u2(address p, u2 x) { ++ if ((intptr_t(p) & 1) == 0) { ++ *(u2*)p = x; ++ } else { ++ p[1] = x >> 8; ++ p[0] = x; ++ } ++ } ++ ++ static inline void put_native_u4(address p, u4 x) { ++ switch (intptr_t(p) & 3) { ++ case 0: ++ *(u4*)p = x; ++ break; ++ ++ case 2: ++ ((u2*)p)[1] = x >> 16; ++ ((u2*)p)[0] = x; ++ break; ++ ++ default: ++ ((u1*)p)[3] = x >> 24; ++ ((u1*)p)[2] = x >> 16; ++ ((u1*)p)[1] = x >> 8; ++ ((u1*)p)[0] = x; ++ break; ++ } ++ } ++ ++ static inline void put_native_u8(address p, u8 x) { ++ switch (intptr_t(p) & 7) { ++ case 0: ++ *(u8*)p = x; ++ break; ++ ++ case 4: ++ ((u4*)p)[1] = x >> 32; ++ ((u4*)p)[0] = x; ++ break; ++ ++ case 2: ++ case 6: ++ ((u2*)p)[3] = x >> 48; ++ ((u2*)p)[2] = x >> 32; ++ ((u2*)p)[1] = x >> 16; ++ ((u2*)p)[0] = x; ++ break; ++ ++ default: ++ ((u1*)p)[7] = x >> 56; ++ ((u1*)p)[6] = x >> 48; ++ ((u1*)p)[5] = x >> 40; ++ ((u1*)p)[4] = x >> 32; ++ ((u1*)p)[3] = x >> 24; ++ ((u1*)p)[2] = x >> 16; ++ ((u1*)p)[1] = x >> 8; ++ ((u1*)p)[0] = x; ++ break; ++ } ++ } ++ ++ // Efficient reading and writing of unaligned unsigned data in Java byte ordering (i.e. big-endian ordering) ++ static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); } ++ static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); } ++ static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); } ++ ++ static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); } ++ static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); } ++ static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); } ++}; ++ ++#include OS_CPU_HEADER(bytes) ++ ++#endif // CPU_RISCV_BYTES_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp +@@ -0,0 +1,357 @@ ++/* ++ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "c1/c1_CodeStubs.hpp" ++#include "c1/c1_FrameMap.hpp" ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "c1/c1_Runtime1.hpp" ++#include "classfile/javaClasses.hpp" ++#include "nativeInst_riscv.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "vmreg_riscv.inline.hpp" ++ ++ ++#define __ ce->masm()-> ++ ++void C1SafepointPollStub::emit_code(LIR_Assembler* ce) { ++ __ bind(_entry); ++ InternalAddress safepoint_pc(__ pc() - __ offset() + safepoint_offset()); ++ __ relocate(safepoint_pc.rspec(), [&] { ++ __ la(t0, safepoint_pc.target()); ++ }); ++ __ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset())); ++ ++ assert(SharedRuntime::polling_page_return_handler_blob() != NULL, ++ "polling page return stub not created yet"); ++ address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point(); ++ ++ __ far_jump(RuntimeAddress(stub)); ++} ++ ++void CounterOverflowStub::emit_code(LIR_Assembler* ce) { ++ __ bind(_entry); ++ Metadata *m = _method->as_constant_ptr()->as_metadata(); ++ __ mov_metadata(t0, m); ++ ce->store_parameter(t0, 1); ++ ce->store_parameter(_bci, 0); ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::counter_overflow_id))); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ __ j(_continuation); ++} ++ ++RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array) ++ : _index(index), _array(array), _throw_index_out_of_bounds_exception(false) { ++ assert(info != NULL, "must have info"); ++ _info = new CodeEmitInfo(info); ++} ++ ++RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index) ++ : _index(index), _array(NULL), _throw_index_out_of_bounds_exception(true) { ++ assert(info != NULL, "must have info"); ++ _info = new CodeEmitInfo(info); ++} ++ ++void RangeCheckStub::emit_code(LIR_Assembler* ce) { ++ __ bind(_entry); ++ if (_info->deoptimize_on_exception()) { ++ address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); ++ __ far_call(RuntimeAddress(a)); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ debug_only(__ should_not_reach_here()); ++ return; ++ } ++ ++ if (_index->is_cpu_register()) { ++ __ mv(t0, _index->as_register()); ++ } else { ++ __ mv(t0, _index->as_jint()); ++ } ++ Runtime1::StubID stub_id; ++ if (_throw_index_out_of_bounds_exception) { ++ stub_id = Runtime1::throw_index_exception_id; ++ } else { ++ assert(_array != NULL, "sanity"); ++ __ mv(t1, _array->as_pointer_register()); ++ stub_id = Runtime1::throw_range_check_failed_id; ++ } ++ RuntimeAddress target(Runtime1::entry_for(stub_id)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(ra, target, offset); ++ __ jalr(ra, ra, offset); ++ }); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ debug_only(__ should_not_reach_here()); ++} ++ ++PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) { ++ _info = new CodeEmitInfo(info); ++} ++ ++void PredicateFailedStub::emit_code(LIR_Assembler* ce) { ++ __ bind(_entry); ++ address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); ++ __ far_call(RuntimeAddress(a)); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ debug_only(__ should_not_reach_here()); ++} ++ ++void DivByZeroStub::emit_code(LIR_Assembler* ce) { ++ if (_offset != -1) { ++ ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); ++ } ++ __ bind(_entry); ++ __ far_call(Address(Runtime1::entry_for(Runtime1::throw_div0_exception_id), relocInfo::runtime_call_type)); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++#ifdef ASSERT ++ __ should_not_reach_here(); ++#endif ++} ++ ++// Implementation of NewInstanceStub ++NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) { ++ _result = result; ++ _klass = klass; ++ _klass_reg = klass_reg; ++ _info = new CodeEmitInfo(info); ++ assert(stub_id == Runtime1::new_instance_id || ++ stub_id == Runtime1::fast_new_instance_id || ++ stub_id == Runtime1::fast_new_instance_init_check_id, ++ "need new_instance id"); ++ _stub_id = stub_id; ++} ++ ++void NewInstanceStub::emit_code(LIR_Assembler* ce) { ++ assert(__ rsp_offset() == 0, "frame size should be fixed"); ++ __ bind(_entry); ++ __ mv(x13, _klass_reg->as_register()); ++ __ far_call(RuntimeAddress(Runtime1::entry_for(_stub_id))); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ assert(_result->as_register() == x10, "result must in x10"); ++ __ j(_continuation); ++} ++ ++// Implementation of NewTypeArrayStub ++NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) { ++ _klass_reg = klass_reg; ++ _length = length; ++ _result = result; ++ _info = new CodeEmitInfo(info); ++} ++ ++void NewTypeArrayStub::emit_code(LIR_Assembler* ce) { ++ assert(__ rsp_offset() == 0, "frame size should be fixed"); ++ __ bind(_entry); ++ assert(_length->as_register() == x9, "length must in x9"); ++ assert(_klass_reg->as_register() == x13, "klass_reg must in x13"); ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_type_array_id))); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ assert(_result->as_register() == x10, "result must in x10"); ++ __ j(_continuation); ++} ++ ++// Implementation of NewObjectArrayStub ++NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) { ++ _klass_reg = klass_reg; ++ _result = result; ++ _length = length; ++ _info = new CodeEmitInfo(info); ++} ++ ++void NewObjectArrayStub::emit_code(LIR_Assembler* ce) { ++ assert(__ rsp_offset() == 0, "frame size should be fixed"); ++ __ bind(_entry); ++ assert(_length->as_register() == x9, "length must in x9"); ++ assert(_klass_reg->as_register() == x13, "klass_reg must in x13"); ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_object_array_id))); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ assert(_result->as_register() == x10, "result must in x10"); ++ __ j(_continuation); ++} ++ ++// Implementation of MonitorAccessStubs ++MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info) ++: MonitorAccessStub(obj_reg, lock_reg) { ++ _info = new CodeEmitInfo(info); ++} ++ ++void MonitorEnterStub::emit_code(LIR_Assembler* ce) { ++ assert(__ rsp_offset() == 0, "frame size should be fixed"); ++ __ bind(_entry); ++ ce->store_parameter(_obj_reg->as_register(), 1); ++ ce->store_parameter(_lock_reg->as_register(), 0); ++ Runtime1::StubID enter_id; ++ if (ce->compilation()->has_fpu_code()) { ++ enter_id = Runtime1::monitorenter_id; ++ } else { ++ enter_id = Runtime1::monitorenter_nofpu_id; ++ } ++ __ far_call(RuntimeAddress(Runtime1::entry_for(enter_id))); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ __ j(_continuation); ++} ++ ++void MonitorExitStub::emit_code(LIR_Assembler* ce) { ++ __ bind(_entry); ++ if (_compute_lock) { ++ // lock_reg was destroyed by fast unlocking attempt => recompute it ++ ce->monitor_address(_monitor_ix, _lock_reg); ++ } ++ ce->store_parameter(_lock_reg->as_register(), 0); ++ // note: non-blocking leaf routine => no call info needed ++ Runtime1::StubID exit_id; ++ if (ce->compilation()->has_fpu_code()) { ++ exit_id = Runtime1::monitorexit_id; ++ } else { ++ exit_id = Runtime1::monitorexit_nofpu_id; ++ } ++ __ la(ra, _continuation); ++ __ far_jump(RuntimeAddress(Runtime1::entry_for(exit_id))); ++} ++ ++// Implementation of patching: ++// - Copy the code at given offset to an inlined buffer (first the bytes, then the number of bytes) ++// - Replace original code with a call to the stub ++// At Runtime: ++// - call to stub, jump to runtime ++// - in runtime: preserve all registers (rspecially objects, i.e., source and destination object) ++// - in runtime: after initializing class, restore original code, reexecute instruction ++ ++int PatchingStub::_patch_info_offset = -NativeGeneralJump::instruction_size; ++ ++void PatchingStub::align_patch_site(MacroAssembler* masm) {} ++ ++void PatchingStub::emit_code(LIR_Assembler* ce) { ++ assert(false, "RISCV should not use C1 runtime patching"); ++} ++ ++void DeoptimizeStub::emit_code(LIR_Assembler* ce) { ++ __ bind(_entry); ++ ce->store_parameter(_trap_request, 0); ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id))); ++ ce->add_call_info_here(_info); ++ DEBUG_ONLY(__ should_not_reach_here()); ++} ++ ++void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { ++ address a = NULL; ++ if (_info->deoptimize_on_exception()) { ++ // Deoptimize, do not throw the exception, because it is probably wrong to do it here. ++ a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); ++ } else { ++ a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id); ++ } ++ ++ ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); ++ __ bind(_entry); ++ __ far_call(RuntimeAddress(a)); ++ ce->add_call_info_here(_info); ++ ce->verify_oop_map(_info); ++ debug_only(__ should_not_reach_here()); ++} ++ ++void SimpleExceptionStub::emit_code(LIR_Assembler* ce) { ++ assert(__ rsp_offset() == 0, "frame size should be fixed"); ++ ++ __ bind(_entry); ++ // pass the object in a tmp register because all other registers ++ // must be preserved ++ if (_obj->is_cpu_register()) { ++ __ mv(t0, _obj->as_register()); ++ } ++ __ far_call(RuntimeAddress(Runtime1::entry_for(_stub)), NULL, t1); ++ ce->add_call_info_here(_info); ++ debug_only(__ should_not_reach_here()); ++} ++ ++void ArrayCopyStub::emit_code(LIR_Assembler* ce) { ++ // ---------------slow case: call to native----------------- ++ __ bind(_entry); ++ // Figure out where the args should go ++ // This should really convert the IntrinsicID to the Method* and signature ++ // but I don't know how to do that. ++ const int args_num = 5; ++ VMRegPair args[args_num]; ++ BasicType signature[args_num] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT }; ++ SharedRuntime::java_calling_convention(signature, args, args_num); ++ ++ // push parameters ++ Register r[args_num]; ++ r[0] = src()->as_register(); ++ r[1] = src_pos()->as_register(); ++ r[2] = dst()->as_register(); ++ r[3] = dst_pos()->as_register(); ++ r[4] = length()->as_register(); ++ ++ // next registers will get stored on the stack ++ for (int j = 0; j < args_num; j++) { ++ VMReg r_1 = args[j].first(); ++ if (r_1->is_stack()) { ++ int st_off = r_1->reg2stack() * wordSize; ++ __ sd(r[j], Address(sp, st_off)); ++ } else { ++ assert(r[j] == args[j].first()->as_Register(), "Wrong register for arg"); ++ } ++ } ++ ++ ce->align_call(lir_static_call); ++ ++ ce->emit_static_call_stub(); ++ if (ce->compilation()->bailed_out()) { ++ return; // CodeCache is full ++ } ++ Address resolve(SharedRuntime::get_resolve_static_call_stub(), ++ relocInfo::static_call_type); ++ address call = __ trampoline_call(resolve); ++ if (call == NULL) { ++ ce->bailout("trampoline stub overflow"); ++ return; ++ } ++ ce->add_call_info_here(info()); ++ ++#ifndef PRODUCT ++ if (PrintC1Statistics) { ++ __ la(t1, ExternalAddress((address)&Runtime1::_arraycopy_slowcase_cnt)); ++ __ incrementw(Address(t1)); ++ } ++#endif ++ ++ __ j(_continuation); ++} ++ ++#undef __ +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_Defs_riscv.hpp +@@ -0,0 +1,84 @@ ++/* ++ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_DEFS_RISCV_HPP ++#define CPU_RISCV_C1_DEFS_RISCV_HPP ++ ++// native word offsets from memory address (little endian) ++enum { ++ pd_lo_word_offset_in_bytes = 0, ++ pd_hi_word_offset_in_bytes = BytesPerWord ++}; ++ ++// explicit rounding operations are required to implement the strictFP mode ++enum { ++ pd_strict_fp_requires_explicit_rounding = false ++}; ++ ++// registers ++enum { ++ pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission ++ pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of float registers used during code emission ++ ++ // caller saved ++ pd_nof_caller_save_cpu_regs_frame_map = 13, // number of registers killed by calls ++ pd_nof_caller_save_fpu_regs_frame_map = 32, // number of float registers killed by calls ++ ++ pd_first_callee_saved_reg = pd_nof_caller_save_cpu_regs_frame_map, ++ pd_last_callee_saved_reg = 21, ++ ++ pd_last_allocatable_cpu_reg = pd_nof_caller_save_cpu_regs_frame_map - 1, ++ ++ pd_nof_cpu_regs_reg_alloc ++ = pd_nof_caller_save_cpu_regs_frame_map, // number of registers that are visible to register allocator ++ pd_nof_fpu_regs_reg_alloc = 32, // number of float registers that are visible to register allocator ++ ++ pd_nof_cpu_regs_linearscan = 32, // number of registers visible to linear scan ++ pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of float registers visible to linear scan ++ pd_nof_xmm_regs_linearscan = 0, // don't have vector registers ++ ++ pd_first_cpu_reg = 0, ++ pd_last_cpu_reg = pd_nof_cpu_regs_reg_alloc - 1, ++ pd_first_byte_reg = 0, ++ pd_last_byte_reg = pd_nof_cpu_regs_reg_alloc - 1, ++ ++ pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, ++ pd_last_fpu_reg = pd_first_fpu_reg + 31, ++ ++ pd_first_callee_saved_fpu_reg_1 = 8 + pd_first_fpu_reg, ++ pd_last_callee_saved_fpu_reg_1 = 9 + pd_first_fpu_reg, ++ pd_first_callee_saved_fpu_reg_2 = 18 + pd_first_fpu_reg, ++ pd_last_callee_saved_fpu_reg_2 = 27 + pd_first_fpu_reg ++}; ++ ++ ++// Encoding of float value in debug info. This is true on x86 where ++// floats are extended to doubles when stored in the stack, false for ++// RISCV where floats and doubles are stored in their native form. ++enum { ++ pd_float_saved_as_double = false ++}; ++ ++#endif // CPU_RISCV_C1_DEFS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_FpuStackSim_riscv.cpp +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++//-------------------------------------------------------- ++// FpuStackSim ++//-------------------------------------------------------- ++ ++// No FPU stack on RISCV +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_FpuStackSim_riscv.hpp +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_FPUSTACKSIM_RISCV_HPP ++#define CPU_RISCV_C1_FPUSTACKSIM_RISCV_HPP ++ ++// No FPU stack on RISCV ++class FpuStackSim; ++ ++#endif // CPU_RISCV_C1_FPUSTACKSIM_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_FrameMap_riscv.cpp +@@ -0,0 +1,388 @@ ++/* ++ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "c1/c1_FrameMap.hpp" ++#include "c1/c1_LIR.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "vmreg_riscv.inline.hpp" ++ ++LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { ++ LIR_Opr opr = LIR_OprFact::illegalOpr; ++ VMReg r_1 = reg->first(); ++ VMReg r_2 = reg->second(); ++ if (r_1->is_stack()) { ++ // Convert stack slot to an SP offset ++ // The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value ++ // so we must add it in here. ++ int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; ++ opr = LIR_OprFact::address(new LIR_Address(sp_opr, st_off, type)); ++ } else if (r_1->is_Register()) { ++ Register reg1 = r_1->as_Register(); ++ if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { ++ Register reg2 = r_2->as_Register(); ++ assert(reg2 == reg1, "must be same register"); ++ opr = as_long_opr(reg1); ++ } else if (is_reference_type(type)) { ++ opr = as_oop_opr(reg1); ++ } else if (type == T_METADATA) { ++ opr = as_metadata_opr(reg1); ++ } else if (type == T_ADDRESS) { ++ opr = as_address_opr(reg1); ++ } else { ++ opr = as_opr(reg1); ++ } ++ } else if (r_1->is_FloatRegister()) { ++ assert(type == T_DOUBLE || type == T_FLOAT, "wrong type"); ++ int num = r_1->as_FloatRegister()->encoding(); ++ if (type == T_FLOAT) { ++ opr = LIR_OprFact::single_fpu(num); ++ } else { ++ opr = LIR_OprFact::double_fpu(num); ++ } ++ } else { ++ ShouldNotReachHere(); ++ } ++ return opr; ++} ++ ++LIR_Opr FrameMap::zr_opr; ++LIR_Opr FrameMap::r1_opr; ++LIR_Opr FrameMap::r2_opr; ++LIR_Opr FrameMap::r3_opr; ++LIR_Opr FrameMap::r4_opr; ++LIR_Opr FrameMap::r5_opr; ++LIR_Opr FrameMap::r6_opr; ++LIR_Opr FrameMap::r7_opr; ++LIR_Opr FrameMap::r8_opr; ++LIR_Opr FrameMap::r9_opr; ++LIR_Opr FrameMap::r10_opr; ++LIR_Opr FrameMap::r11_opr; ++LIR_Opr FrameMap::r12_opr; ++LIR_Opr FrameMap::r13_opr; ++LIR_Opr FrameMap::r14_opr; ++LIR_Opr FrameMap::r15_opr; ++LIR_Opr FrameMap::r16_opr; ++LIR_Opr FrameMap::r17_opr; ++LIR_Opr FrameMap::r18_opr; ++LIR_Opr FrameMap::r19_opr; ++LIR_Opr FrameMap::r20_opr; ++LIR_Opr FrameMap::r21_opr; ++LIR_Opr FrameMap::r22_opr; ++LIR_Opr FrameMap::r23_opr; ++LIR_Opr FrameMap::r24_opr; ++LIR_Opr FrameMap::r25_opr; ++LIR_Opr FrameMap::r26_opr; ++LIR_Opr FrameMap::r27_opr; ++LIR_Opr FrameMap::r28_opr; ++LIR_Opr FrameMap::r29_opr; ++LIR_Opr FrameMap::r30_opr; ++LIR_Opr FrameMap::r31_opr; ++ ++LIR_Opr FrameMap::fp_opr; ++LIR_Opr FrameMap::sp_opr; ++ ++LIR_Opr FrameMap::receiver_opr; ++ ++LIR_Opr FrameMap::zr_oop_opr; ++LIR_Opr FrameMap::r1_oop_opr; ++LIR_Opr FrameMap::r2_oop_opr; ++LIR_Opr FrameMap::r3_oop_opr; ++LIR_Opr FrameMap::r4_oop_opr; ++LIR_Opr FrameMap::r5_oop_opr; ++LIR_Opr FrameMap::r6_oop_opr; ++LIR_Opr FrameMap::r7_oop_opr; ++LIR_Opr FrameMap::r8_oop_opr; ++LIR_Opr FrameMap::r9_oop_opr; ++LIR_Opr FrameMap::r10_oop_opr; ++LIR_Opr FrameMap::r11_oop_opr; ++LIR_Opr FrameMap::r12_oop_opr; ++LIR_Opr FrameMap::r13_oop_opr; ++LIR_Opr FrameMap::r14_oop_opr; ++LIR_Opr FrameMap::r15_oop_opr; ++LIR_Opr FrameMap::r16_oop_opr; ++LIR_Opr FrameMap::r17_oop_opr; ++LIR_Opr FrameMap::r18_oop_opr; ++LIR_Opr FrameMap::r19_oop_opr; ++LIR_Opr FrameMap::r20_oop_opr; ++LIR_Opr FrameMap::r21_oop_opr; ++LIR_Opr FrameMap::r22_oop_opr; ++LIR_Opr FrameMap::r23_oop_opr; ++LIR_Opr FrameMap::r24_oop_opr; ++LIR_Opr FrameMap::r25_oop_opr; ++LIR_Opr FrameMap::r26_oop_opr; ++LIR_Opr FrameMap::r27_oop_opr; ++LIR_Opr FrameMap::r28_oop_opr; ++LIR_Opr FrameMap::r29_oop_opr; ++LIR_Opr FrameMap::r30_oop_opr; ++LIR_Opr FrameMap::r31_oop_opr; ++ ++LIR_Opr FrameMap::t0_opr; ++LIR_Opr FrameMap::t1_opr; ++LIR_Opr FrameMap::t0_long_opr; ++LIR_Opr FrameMap::t1_long_opr; ++ ++LIR_Opr FrameMap::r10_metadata_opr; ++LIR_Opr FrameMap::r11_metadata_opr; ++LIR_Opr FrameMap::r12_metadata_opr; ++LIR_Opr FrameMap::r13_metadata_opr; ++LIR_Opr FrameMap::r14_metadata_opr; ++LIR_Opr FrameMap::r15_metadata_opr; ++ ++LIR_Opr FrameMap::long10_opr; ++LIR_Opr FrameMap::long11_opr; ++LIR_Opr FrameMap::fpu10_float_opr; ++LIR_Opr FrameMap::fpu10_double_opr; ++ ++LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, }; ++LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, }; ++ ++//-------------------------------------------------------- ++// FrameMap ++//-------------------------------------------------------- ++// |---f31--| ++// |---..---| ++// |---f28--| ++// |---f27--|<---pd_last_callee_saved_fpu_reg_2 ++// |---..---| ++// |---f18--|<---pd_first_callee_saved_fpu_reg_2 ++// |---f17--| ++// |---..---| ++// |---f10--| ++// |---f9---|<---pd_last_callee_saved_fpu_reg_1 ++// |---f8---|<---pd_first_callee_saved_fpu_reg_1 ++// |---f7---| ++// |---..---| ++// |---f0---| ++// |---x27--| ++// |---x23--| ++// |---x8---| ++// |---x4---| ++// |---x3---| ++// |---x2---| ++// |---x1---| ++// |---x0---| ++// |---x26--|<---pd_last_callee_saved_reg ++// |---..---| ++// |---x18--| ++// |---x9---|<---pd_first_callee_saved_reg ++// |---x31--| ++// |---..---| ++// |---x28--| ++// |---x17--| ++// |---..---| ++// |---x10--| ++// |---x7---| ++ ++void FrameMap::initialize() { ++ assert(!_init_done, "once"); ++ ++ int i = 0; ++ ++ // caller save register ++ map_register(i, x7); r7_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x10); r10_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x11); r11_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x12); r12_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x13); r13_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x14); r14_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x15); r15_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x16); r16_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x17); r17_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x28); r28_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x29); r29_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x30); r30_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x31); r31_opr = LIR_OprFact::single_cpu(i); i++; ++ ++ // callee save register ++ map_register(i, x9); r9_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x18); r18_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x19); r19_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x20); r20_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x21); r21_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x22); r22_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x24); r24_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x25); r25_opr = LIR_OprFact::single_cpu(i); i++; ++ map_register(i, x26); r26_opr = LIR_OprFact::single_cpu(i); i++; ++ ++ // special register ++ map_register(i, x0); zr_opr = LIR_OprFact::single_cpu(i); i++; // zr ++ map_register(i, x1); r1_opr = LIR_OprFact::single_cpu(i); i++; // ra ++ map_register(i, x2); r2_opr = LIR_OprFact::single_cpu(i); i++; // sp ++ map_register(i, x3); r3_opr = LIR_OprFact::single_cpu(i); i++; // gp ++ map_register(i, x4); r4_opr = LIR_OprFact::single_cpu(i); i++; // thread ++ map_register(i, x8); r8_opr = LIR_OprFact::single_cpu(i); i++; // fp ++ map_register(i, x23); r23_opr = LIR_OprFact::single_cpu(i); i++; // java thread ++ map_register(i, x27); r27_opr = LIR_OprFact::single_cpu(i); i++; // heapbase ++ ++ // tmp register ++ map_register(i, x5); r5_opr = LIR_OprFact::single_cpu(i); i++; // t0 ++ map_register(i, x6); r6_opr = LIR_OprFact::single_cpu(i); i++; // t1 ++ ++ t0_opr = r5_opr; ++ t1_opr = r6_opr; ++ t0_long_opr = LIR_OprFact::double_cpu(r5_opr->cpu_regnr(), r5_opr->cpu_regnr()); ++ t1_long_opr = LIR_OprFact::double_cpu(r6_opr->cpu_regnr(), r6_opr->cpu_regnr()); ++ ++ long10_opr = LIR_OprFact::double_cpu(r10_opr->cpu_regnr(), r10_opr->cpu_regnr()); ++ long11_opr = LIR_OprFact::double_cpu(r11_opr->cpu_regnr(), r11_opr->cpu_regnr()); ++ ++ fpu10_float_opr = LIR_OprFact::single_fpu(10); ++ fpu10_double_opr = LIR_OprFact::double_fpu(10); ++ ++ i = 0; ++ _caller_save_cpu_regs[i++] = r7_opr; ++ _caller_save_cpu_regs[i++] = r10_opr; ++ _caller_save_cpu_regs[i++] = r11_opr; ++ _caller_save_cpu_regs[i++] = r12_opr; ++ _caller_save_cpu_regs[i++] = r13_opr; ++ _caller_save_cpu_regs[i++] = r14_opr; ++ _caller_save_cpu_regs[i++] = r15_opr; ++ _caller_save_cpu_regs[i++] = r16_opr; ++ _caller_save_cpu_regs[i++] = r17_opr; ++ _caller_save_cpu_regs[i++] = r28_opr; ++ _caller_save_cpu_regs[i++] = r29_opr; ++ _caller_save_cpu_regs[i++] = r30_opr; ++ _caller_save_cpu_regs[i++] = r31_opr; ++ ++ _init_done = true; ++ ++ zr_oop_opr = as_oop_opr(x0); ++ r1_oop_opr = as_oop_opr(x1); ++ r2_oop_opr = as_oop_opr(x2); ++ r3_oop_opr = as_oop_opr(x3); ++ r4_oop_opr = as_oop_opr(x4); ++ r5_oop_opr = as_oop_opr(x5); ++ r6_oop_opr = as_oop_opr(x6); ++ r7_oop_opr = as_oop_opr(x7); ++ r8_oop_opr = as_oop_opr(x8); ++ r9_oop_opr = as_oop_opr(x9); ++ r10_oop_opr = as_oop_opr(x10); ++ r11_oop_opr = as_oop_opr(x11); ++ r12_oop_opr = as_oop_opr(x12); ++ r13_oop_opr = as_oop_opr(x13); ++ r14_oop_opr = as_oop_opr(x14); ++ r15_oop_opr = as_oop_opr(x15); ++ r16_oop_opr = as_oop_opr(x16); ++ r17_oop_opr = as_oop_opr(x17); ++ r18_oop_opr = as_oop_opr(x18); ++ r19_oop_opr = as_oop_opr(x19); ++ r20_oop_opr = as_oop_opr(x20); ++ r21_oop_opr = as_oop_opr(x21); ++ r22_oop_opr = as_oop_opr(x22); ++ r23_oop_opr = as_oop_opr(x23); ++ r24_oop_opr = as_oop_opr(x24); ++ r25_oop_opr = as_oop_opr(x25); ++ r26_oop_opr = as_oop_opr(x26); ++ r27_oop_opr = as_oop_opr(x27); ++ r28_oop_opr = as_oop_opr(x28); ++ r29_oop_opr = as_oop_opr(x29); ++ r30_oop_opr = as_oop_opr(x30); ++ r31_oop_opr = as_oop_opr(x31); ++ ++ r10_metadata_opr = as_metadata_opr(x10); ++ r11_metadata_opr = as_metadata_opr(x11); ++ r12_metadata_opr = as_metadata_opr(x12); ++ r13_metadata_opr = as_metadata_opr(x13); ++ r14_metadata_opr = as_metadata_opr(x14); ++ r15_metadata_opr = as_metadata_opr(x15); ++ ++ sp_opr = as_pointer_opr(sp); ++ fp_opr = as_pointer_opr(fp); ++ ++ VMRegPair regs; ++ BasicType sig_bt = T_OBJECT; ++ SharedRuntime::java_calling_convention(&sig_bt, ®s, 1); ++ receiver_opr = as_oop_opr(regs.first()->as_Register()); ++ ++ for (i = 0; i < nof_caller_save_fpu_regs; i++) { ++ _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); ++ } ++} ++ ++ ++Address FrameMap::make_new_address(ByteSize sp_offset) const { ++ return Address(sp, in_bytes(sp_offset)); ++} ++ ++ ++// ----------------mapping----------------------- ++// all mapping is based on fp addressing, except for simple leaf methods where we access ++// the locals sp based (and no frame is built) ++ ++ ++// Frame for simple leaf methods (quick entries) ++// ++// +----------+ ++// | ret addr | <- TOS ++// +----------+ ++// | args | ++// | ...... | ++ ++// Frame for standard methods ++// ++// | .........| <- TOS ++// | locals | ++// +----------+ ++// | old fp, | ++// +----------+ ++// | ret addr | ++// +----------+ ++// | args | <- FP ++// | .........| ++ ++ ++// For OopMaps, map a local variable or spill index to an VMRegImpl name. ++// This is the offset from sp() in the frame of the slot for the index, ++// skewed by VMRegImpl::stack0 to indicate a stack location (vs.a register.) ++// ++// framesize + ++// stack0 stack0 0 <- VMReg ++// | | | ++// ...........|..............|.............| ++// 0 1 2 3 x x 4 5 6 ... | <- local indices ++// ^ ^ sp() ( x x indicate link ++// | | and return addr) ++// arguments non-argument locals ++ ++ ++VMReg FrameMap::fpu_regname (int n) { ++ // Return the OptoReg name for the fpu stack slot "n" ++ // A spilled fpu stack slot comprises to two single-word OptoReg's. ++ return as_FloatRegister(n)->as_VMReg(); ++} ++ ++LIR_Opr FrameMap::stack_pointer() { ++ return FrameMap::sp_opr; ++} ++ ++// JSR 292 ++LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() { ++ return LIR_OprFact::illegalOpr; // Not needed on riscv ++} ++ ++bool FrameMap::validate_frame() { ++ return true; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_FrameMap_riscv.hpp +@@ -0,0 +1,148 @@ ++/* ++ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_FRAMEMAP_RISCV_HPP ++#define CPU_RISCV_C1_FRAMEMAP_RISCV_HPP ++ ++// On RISCV the frame looks as follows: ++// ++// +-----------------------------+---------+----------------------------------------+----------------+----------- ++// | size_arguments-nof_reg_args | 2 words | size_locals-size_arguments+numreg_args | _size_monitors | spilling . ++// +-----------------------------+---------+----------------------------------------+----------------+----------- ++ ++ public: ++ static const int pd_c_runtime_reserved_arg_size; ++ ++ enum { ++ first_available_sp_in_frame = 0, ++ frame_pad_in_bytes = 16, ++ nof_reg_args = 8 ++ }; ++ ++ public: ++ static LIR_Opr receiver_opr; ++ ++ static LIR_Opr zr_opr; ++ static LIR_Opr r1_opr; ++ static LIR_Opr r2_opr; ++ static LIR_Opr r3_opr; ++ static LIR_Opr r4_opr; ++ static LIR_Opr r5_opr; ++ static LIR_Opr r6_opr; ++ static LIR_Opr r7_opr; ++ static LIR_Opr r8_opr; ++ static LIR_Opr r9_opr; ++ static LIR_Opr r10_opr; ++ static LIR_Opr r11_opr; ++ static LIR_Opr r12_opr; ++ static LIR_Opr r13_opr; ++ static LIR_Opr r14_opr; ++ static LIR_Opr r15_opr; ++ static LIR_Opr r16_opr; ++ static LIR_Opr r17_opr; ++ static LIR_Opr r18_opr; ++ static LIR_Opr r19_opr; ++ static LIR_Opr r20_opr; ++ static LIR_Opr r21_opr; ++ static LIR_Opr r22_opr; ++ static LIR_Opr r23_opr; ++ static LIR_Opr r24_opr; ++ static LIR_Opr r25_opr; ++ static LIR_Opr r26_opr; ++ static LIR_Opr r27_opr; ++ static LIR_Opr r28_opr; ++ static LIR_Opr r29_opr; ++ static LIR_Opr r30_opr; ++ static LIR_Opr r31_opr; ++ static LIR_Opr fp_opr; ++ static LIR_Opr sp_opr; ++ ++ static LIR_Opr zr_oop_opr; ++ static LIR_Opr r1_oop_opr; ++ static LIR_Opr r2_oop_opr; ++ static LIR_Opr r3_oop_opr; ++ static LIR_Opr r4_oop_opr; ++ static LIR_Opr r5_oop_opr; ++ static LIR_Opr r6_oop_opr; ++ static LIR_Opr r7_oop_opr; ++ static LIR_Opr r8_oop_opr; ++ static LIR_Opr r9_oop_opr; ++ static LIR_Opr r10_oop_opr; ++ static LIR_Opr r11_oop_opr; ++ static LIR_Opr r12_oop_opr; ++ static LIR_Opr r13_oop_opr; ++ static LIR_Opr r14_oop_opr; ++ static LIR_Opr r15_oop_opr; ++ static LIR_Opr r16_oop_opr; ++ static LIR_Opr r17_oop_opr; ++ static LIR_Opr r18_oop_opr; ++ static LIR_Opr r19_oop_opr; ++ static LIR_Opr r20_oop_opr; ++ static LIR_Opr r21_oop_opr; ++ static LIR_Opr r22_oop_opr; ++ static LIR_Opr r23_oop_opr; ++ static LIR_Opr r24_oop_opr; ++ static LIR_Opr r25_oop_opr; ++ static LIR_Opr r26_oop_opr; ++ static LIR_Opr r27_oop_opr; ++ static LIR_Opr r28_oop_opr; ++ static LIR_Opr r29_oop_opr; ++ static LIR_Opr r30_oop_opr; ++ static LIR_Opr r31_oop_opr; ++ ++ static LIR_Opr t0_opr; ++ static LIR_Opr t1_opr; ++ static LIR_Opr t0_long_opr; ++ static LIR_Opr t1_long_opr; ++ ++ static LIR_Opr r10_metadata_opr; ++ static LIR_Opr r11_metadata_opr; ++ static LIR_Opr r12_metadata_opr; ++ static LIR_Opr r13_metadata_opr; ++ static LIR_Opr r14_metadata_opr; ++ static LIR_Opr r15_metadata_opr; ++ ++ static LIR_Opr long10_opr; ++ static LIR_Opr long11_opr; ++ static LIR_Opr fpu10_float_opr; ++ static LIR_Opr fpu10_double_opr; ++ ++ static LIR_Opr as_long_opr(Register r) { ++ return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r)); ++ } ++ static LIR_Opr as_pointer_opr(Register r) { ++ return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r)); ++ } ++ ++ // VMReg name for spilled physical FPU stack slot n ++ static VMReg fpu_regname(int n); ++ ++ static bool is_caller_save_register(LIR_Opr opr) { return true; } ++ static bool is_caller_save_register(Register r) { return true; } ++ ++ static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; } ++ static int last_cpu_reg() { return pd_last_cpu_reg; } ++ ++#endif // CPU_RISCV_C1_FRAMEMAP_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp +@@ -0,0 +1,281 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++ ++#ifndef PRODUCT ++#define COMMENT(x) do { __ block_comment(x); } while (0) ++#else ++#define COMMENT(x) ++#endif ++ ++#define __ _masm-> ++ ++void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr illegal, ++ LIR_Opr result, CodeEmitInfo* info) { ++ // opcode check ++ assert((code == lir_idiv) || (code == lir_irem), "opcode must be idiv or irem"); ++ bool is_irem = (code == lir_irem); ++ // opreand check ++ assert(left->is_single_cpu(), "left must be a register"); ++ assert(right->is_single_cpu() || right->is_constant(), "right must be a register or constant"); ++ assert(result->is_single_cpu(), "result must be a register"); ++ Register lreg = left->as_register(); ++ Register dreg = result->as_register(); ++ ++ // power-of-2 constant check and codegen ++ if (right->is_constant()) { ++ int c = right->as_constant_ptr()->as_jint(); ++ assert(c > 0 && is_power_of_2(c), "divisor must be power-of-2 constant"); ++ if (is_irem) { ++ if (c == 1) { ++ // move 0 to dreg if divisor is 1 ++ __ mv(dreg, zr); ++ } else { ++ unsigned int shift = exact_log2(c); ++ __ sraiw(t0, lreg, 0x1f); ++ __ srliw(t0, t0, BitsPerInt - shift); ++ __ addw(t1, lreg, t0); ++ if (Assembler::is_simm12(c - 1)) { ++ __ andi(t1, t1, c - 1); ++ } else { ++ __ zero_extend(t1, t1, shift); ++ } ++ __ subw(dreg, t1, t0); ++ } ++ } else { ++ if (c == 1) { ++ // move lreg to dreg if divisor is 1 ++ __ mv(dreg, lreg); ++ } else { ++ unsigned int shift = exact_log2(c); ++ __ sraiw(t0, lreg, 0x1f); ++ if (Assembler::is_simm12(c - 1)) { ++ __ andi(t0, t0, c - 1); ++ } else { ++ __ zero_extend(t0, t0, shift); ++ } ++ __ addw(dreg, t0, lreg); ++ __ sraiw(dreg, dreg, shift); ++ } ++ } ++ } else { ++ Register rreg = right->as_register(); ++ __ corrected_idivl(dreg, lreg, rreg, is_irem); ++ } ++} ++ ++void LIR_Assembler::arith_op_single_cpu_right_constant(LIR_Code code, LIR_Opr left, LIR_Opr right, ++ Register lreg, Register dreg) { ++ // cpu register - constant ++ jlong c; ++ ++ switch (right->type()) { ++ case T_LONG: ++ c = right->as_constant_ptr()->as_jlong(); break; ++ case T_INT: // fall through ++ case T_ADDRESS: ++ c = right->as_constant_ptr()->as_jint(); break; ++ default: ++ ShouldNotReachHere(); ++ c = 0; // unreachable ++ } ++ ++ assert(code == lir_add || code == lir_sub, "mismatched arithmetic op"); ++ if (c == 0 && dreg == lreg) { ++ COMMENT("effective nop elided"); ++ return; ++ } ++ switch (left->type()) { ++ case T_INT: ++ switch (code) { ++ case lir_add: __ addw(dreg, lreg, c); break; ++ case lir_sub: __ subw(dreg, lreg, c); break; ++ default: ShouldNotReachHere(); ++ } ++ break; ++ case T_OBJECT: // fall through ++ case T_ADDRESS: ++ switch (code) { ++ case lir_add: __ add(dreg, lreg, c); break; ++ case lir_sub: __ sub(dreg, lreg, c); break; ++ default: ShouldNotReachHere(); ++ } ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::arith_op_single_cpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest) { ++ Register lreg = left->as_register(); ++ Register dreg = as_reg(dest); ++ ++ if (right->is_single_cpu()) { ++ // cpu register - cpu register ++ assert(left->type() == T_INT && right->type() == T_INT && dest->type() == T_INT, "should be"); ++ Register rreg = right->as_register(); ++ switch (code) { ++ case lir_add: __ addw(dest->as_register(), lreg, rreg); break; ++ case lir_sub: __ subw(dest->as_register(), lreg, rreg); break; ++ case lir_mul: __ mulw(dest->as_register(), lreg, rreg); break; ++ default: ShouldNotReachHere(); ++ } ++ } else if (right->is_double_cpu()) { ++ Register rreg = right->as_register_lo(); ++ // sigle_cpu + double_cpu; can happen with obj_long ++ assert(code == lir_add || code == lir_sub, "mismatched arithmetic op"); ++ switch (code) { ++ case lir_add: __ add(dreg, lreg, rreg); break; ++ case lir_sub: __ sub(dreg, lreg, rreg); break; ++ default: ShouldNotReachHere(); ++ } ++ } else if (right->is_constant()) { ++ arith_op_single_cpu_right_constant(code, left, right, lreg, dreg); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::arith_op_double_cpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest) { ++ Register lreg_lo = left->as_register_lo(); ++ ++ if (right->is_double_cpu()) { ++ // cpu register - cpu register ++ Register rreg_lo = right->as_register_lo(); ++ switch (code) { ++ case lir_add: __ add(dest->as_register_lo(), lreg_lo, rreg_lo); break; ++ case lir_sub: __ sub(dest->as_register_lo(), lreg_lo, rreg_lo); break; ++ case lir_mul: __ mul(dest->as_register_lo(), lreg_lo, rreg_lo); break; ++ case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, false); break; ++ case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, true); break; ++ default: ++ ShouldNotReachHere(); ++ } ++ } else if (right->is_constant()) { ++ jlong c = right->as_constant_ptr()->as_jlong(); ++ Register dreg = as_reg(dest); ++ switch (code) { ++ case lir_add: // fall through ++ case lir_sub: ++ if (c == 0 && dreg == lreg_lo) { ++ COMMENT("effective nop elided"); ++ return; ++ } ++ code == lir_add ? __ add(dreg, lreg_lo, c) : __ sub(dreg, lreg_lo, c); ++ break; ++ case lir_div: ++ assert(c > 0 && is_power_of_2(c), "divisor must be power-of-2 constant"); ++ if (c == 1) { ++ // move lreg_lo to dreg if divisor is 1 ++ __ mv(dreg, lreg_lo); ++ } else { ++ unsigned int shift = exact_log2_long(c); ++ // use t0 as intermediate result register ++ __ srai(t0, lreg_lo, 0x3f); ++ if (Assembler::is_simm12(c - 1)) { ++ __ andi(t0, t0, c - 1); ++ } else { ++ __ zero_extend(t0, t0, shift); ++ } ++ __ add(dreg, t0, lreg_lo); ++ __ srai(dreg, dreg, shift); ++ } ++ break; ++ case lir_rem: ++ assert(c > 0 && is_power_of_2(c), "divisor must be power-of-2 constant"); ++ if (c == 1) { ++ // move 0 to dreg if divisor is 1 ++ __ mv(dreg, zr); ++ } else { ++ unsigned int shift = exact_log2_long(c); ++ __ srai(t0, lreg_lo, 0x3f); ++ __ srli(t0, t0, BitsPerLong - shift); ++ __ add(t1, lreg_lo, t0); ++ if (Assembler::is_simm12(c - 1)) { ++ __ andi(t1, t1, c - 1); ++ } else { ++ __ zero_extend(t1, t1, shift); ++ } ++ __ sub(dreg, t1, t0); ++ } ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::arith_op_single_fpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest) { ++ assert(right->is_single_fpu(), "right hand side of float arithmetics needs to be float register"); ++ switch (code) { ++ case lir_add: __ fadd_s(dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; ++ case lir_sub: __ fsub_s(dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; ++ case lir_mul: __ fmul_s(dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; ++ case lir_div: __ fdiv_s(dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::arith_op_double_fpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest) { ++ if (right->is_double_fpu()) { ++ // fpu register - fpu register ++ switch (code) { ++ case lir_add: __ fadd_d(dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; ++ case lir_sub: __ fsub_d(dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; ++ case lir_mul: __ fmul_d(dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; ++ case lir_div: __ fdiv_d(dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; ++ default: ++ ShouldNotReachHere(); ++ } ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, ++ CodeEmitInfo* info, bool pop_fpu_stack) { ++ assert(info == NULL, "should never be used, idiv/irem and ldiv/lrem not handled by this method"); ++ ++ if (left->is_single_cpu()) { ++ arith_op_single_cpu(code, left, right, dest); ++ } else if (left->is_double_cpu()) { ++ arith_op_double_cpu(code, left, right, dest); ++ } else if (left->is_single_fpu()) { ++ arith_op_single_fpu(code, left, right, dest); ++ } else if (left->is_double_fpu()) { ++ arith_op_double_fpu(code, left, right, dest); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++#undef __ +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.hpp +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2000, 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_LIRASSEMBLER_ARITH_RISCV_HPP ++#define CPU_RISCV_C1_LIRASSEMBLER_ARITH_RISCV_HPP ++ ++ // arith_op sub functions ++ void arith_op_single_cpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest); ++ void arith_op_double_cpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest); ++ void arith_op_single_fpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest); ++ void arith_op_double_fpu(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest); ++ void arith_op_single_cpu_right_constant(LIR_Code code, LIR_Opr left, LIR_Opr right, Register lreg, Register dreg); ++ void arithmetic_idiv(LIR_Op3* op, bool is_irem); ++ ++#endif // CPU_RISCV_C1_LIRASSEMBLER_ARITH_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp +@@ -0,0 +1,387 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "ci/ciArrayKlass.hpp" ++#include "oops/objArrayKlass.hpp" ++#include "runtime/stubRoutines.hpp" ++ ++#define __ _masm-> ++ ++ ++void LIR_Assembler::generic_arraycopy(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, CodeStub *stub) { ++ assert(src == x11 && src_pos == x12, "mismatch in calling convention"); ++ // Save the arguments in case the generic arraycopy fails and we ++ // have to fall back to the JNI stub ++ arraycopy_store_args(src, src_pos, length, dst, dst_pos); ++ ++ address copyfunc_addr = StubRoutines::generic_arraycopy(); ++ assert(copyfunc_addr != NULL, "generic arraycopy stub required"); ++ ++ // The arguments are in java calling convention so we shift them ++ // to C convention ++ assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4); ++ __ mv(c_rarg0, j_rarg0); ++ assert_different_registers(c_rarg1, j_rarg2, j_rarg3, j_rarg4); ++ __ mv(c_rarg1, j_rarg1); ++ assert_different_registers(c_rarg2, j_rarg3, j_rarg4); ++ __ mv(c_rarg2, j_rarg2); ++ assert_different_registers(c_rarg3, j_rarg4); ++ __ mv(c_rarg3, j_rarg3); ++ __ mv(c_rarg4, j_rarg4); ++#ifndef PRODUCT ++ if (PrintC1Statistics) { ++ __ incrementw(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); ++ } ++#endif ++ __ far_call(RuntimeAddress(copyfunc_addr)); ++ __ beqz(x10, *stub->continuation()); ++ // Reload values from the stack so they are where the stub ++ // expects them. ++ arraycopy_load_args(src, src_pos, length, dst, dst_pos); ++ ++ // x10 is -1^K where K == partial copied count ++ __ xori(t0, x10, -1); ++ // adjust length down and src/end pos up by partial copied count ++ __ subw(length, length, t0); ++ __ addw(src_pos, src_pos, t0); ++ __ addw(dst_pos, dst_pos, t0); ++ __ j(*stub->entry()); ++ ++ __ bind(*stub->continuation()); ++} ++ ++void LIR_Assembler::arraycopy_simple_check(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, Register tmp, ++ CodeStub *stub, int flags) { ++ // test for NULL ++ if (flags & LIR_OpArrayCopy::src_null_check) { ++ __ beqz(src, *stub->entry(), /* is_far */ true); ++ } ++ if (flags & LIR_OpArrayCopy::dst_null_check) { ++ __ beqz(dst, *stub->entry(), /* is_far */ true); ++ } ++ ++ // If the compiler was not able to prove that exact type of the source or the destination ++ // of the arraycopy is an array type, check at runtime if the source or the destination is ++ // an instance type. ++ if (flags & LIR_OpArrayCopy::type_check) { ++ assert(Klass::_lh_neutral_value == 0, "or replace bgez instructions"); ++ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) { ++ __ load_klass(tmp, dst); ++ __ lw(t0, Address(tmp, in_bytes(Klass::layout_helper_offset()))); ++ __ bgez(t0, *stub->entry(), /* is_far */ true); ++ } ++ ++ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) { ++ __ load_klass(tmp, src); ++ __ lw(t0, Address(tmp, in_bytes(Klass::layout_helper_offset()))); ++ __ bgez(t0, *stub->entry(), /* is_far */ true); ++ } ++ } ++ ++ // check if negative ++ if (flags & LIR_OpArrayCopy::src_pos_positive_check) { ++ __ bltz(src_pos, *stub->entry(), /* is_far */ true); ++ } ++ if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { ++ __ bltz(dst_pos, *stub->entry(), /* is_far */ true); ++ } ++ if (flags & LIR_OpArrayCopy::length_positive_check) { ++ __ bltz(length, *stub->entry(), /* is_far */ true); ++ } ++ ++ if (flags & LIR_OpArrayCopy::src_range_check) { ++ __ addw(tmp, src_pos, length); ++ __ lwu(t0, Address(src, arrayOopDesc::length_offset_in_bytes())); ++ __ bgtu(tmp, t0, *stub->entry(), /* is_far */ true); ++ } ++ if (flags & LIR_OpArrayCopy::dst_range_check) { ++ __ addw(tmp, dst_pos, length); ++ __ lwu(t0, Address(dst, arrayOopDesc::length_offset_in_bytes())); ++ __ bgtu(tmp, t0, *stub->entry(), /* is_far */ true); ++ } ++} ++ ++void LIR_Assembler::arraycopy_checkcast(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, Register tmp, ++ CodeStub *stub, BasicType basic_type, ++ address copyfunc_addr, int flags) { ++ // src is not a sub class of dst so we have to do a ++ // per-element check. ++ int mask = LIR_OpArrayCopy::src_objarray | LIR_OpArrayCopy::dst_objarray; ++ if ((flags & mask) != mask) { ++ // Check that at least both of them object arrays. ++ assert(flags & mask, "one of the two should be known to be an object array"); ++ ++ if (!(flags & LIR_OpArrayCopy::src_objarray)) { ++ __ load_klass(tmp, src); ++ } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) { ++ __ load_klass(tmp, dst); ++ } ++ int lh_offset = in_bytes(Klass::layout_helper_offset()); ++ Address klass_lh_addr(tmp, lh_offset); ++ jint objArray_lh = Klass::array_layout_helper(T_OBJECT); ++ __ lw(t0, klass_lh_addr); ++ __ mv(t1, objArray_lh); ++ __ bne(t0, t1, *stub->entry(), /* is_far */ true); ++ } ++ ++ // Spill because stubs can use any register they like and it's ++ // easier to restore just those that we care about. ++ arraycopy_store_args(src, src_pos, length, dst, dst_pos); ++ arraycopy_checkcast_prepare_params(src, src_pos, length, dst, dst_pos, basic_type); ++ __ far_call(RuntimeAddress(copyfunc_addr)); ++ ++#ifndef PRODUCT ++ if (PrintC1Statistics) { ++ Label failed; ++ __ bnez(x10, failed); ++ __ incrementw(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_cnt)); ++ __ bind(failed); ++ } ++#endif ++ ++ __ beqz(x10, *stub->continuation()); ++ ++#ifndef PRODUCT ++ if (PrintC1Statistics) { ++ __ incrementw(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_attempt_cnt)); ++ } ++#endif ++ assert_different_registers(dst, dst_pos, length, src_pos, src, x10, t0); ++ ++ // Restore previously spilled arguments ++ arraycopy_load_args(src, src_pos, length, dst, dst_pos); ++ ++ // return value is -1^K where K is partial copied count ++ __ xori(t0, x10, -1); ++ // adjust length down and src/end pos up by partial copied count ++ __ subw(length, length, t0); ++ __ addw(src_pos, src_pos, t0); ++ __ addw(dst_pos, dst_pos, t0); ++} ++ ++void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, Register tmp, ++ CodeStub *stub, BasicType basic_type, int flags) { ++ // We don't know the array types are compatible ++ if (basic_type != T_OBJECT) { ++ // Simple test for basic type arrays ++ if (UseCompressedClassPointers) { ++ __ lwu(tmp, Address(src, oopDesc::klass_offset_in_bytes())); ++ __ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } else { ++ __ ld(tmp, Address(src, oopDesc::klass_offset_in_bytes())); ++ __ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } ++ __ bne(tmp, t0, *stub->entry(), /* is_far */ true); ++ } else { ++ // For object arrays, if src is a sub class of dst then we can ++ // safely do the copy. ++ Label cont, slow; ++ ++#define PUSH(r1, r2) \ ++ __ addi(sp, sp, -2 * wordSize); \ ++ __ sd(r1, Address(sp, 1 * wordSize)); \ ++ __ sd(r2, Address(sp, 0)); ++ ++#define POP(r1, r2) \ ++ __ ld(r1, Address(sp, 1 * wordSize)); \ ++ __ ld(r2, Address(sp, 0)); \ ++ __ addi(sp, sp, 2 * wordSize); ++ ++ PUSH(src, dst); ++ __ load_klass(src, src); ++ __ load_klass(dst, dst); ++ __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL); ++ ++ PUSH(src, dst); ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); ++ POP(src, dst); ++ __ bnez(dst, cont); ++ ++ __ bind(slow); ++ POP(src, dst); ++ ++ address copyfunc_addr = StubRoutines::checkcast_arraycopy(); ++ if (copyfunc_addr != NULL) { // use stub if available ++ arraycopy_checkcast(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, copyfunc_addr, flags); ++ } ++ ++ __ j(*stub->entry()); ++ __ bind(cont); ++ POP(src, dst); ++ } ++} ++ ++void LIR_Assembler::arraycopy_assert(Register src, Register dst, Register tmp, ciArrayKlass *default_type, int flags) { ++ assert(default_type != NULL, "NULL default_type!"); ++ BasicType basic_type = default_type->element_type()->basic_type(); ++ ++ if (basic_type == T_ARRAY) { basic_type = T_OBJECT; } ++ if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { ++ // Sanity check the known type with the incoming class. For the ++ // primitive case the types must match exactly with src.klass and ++ // dst.klass each exactly matching the default type. For the ++ // object array case, if no type check is needed then either the ++ // dst type is exactly the expected type and the src type is a ++ // subtype which we can't check or src is the same array as dst ++ // but not necessarily exactly of type default_type. ++ Label known_ok, halt; ++ __ mov_metadata(tmp, default_type->constant_encoding()); ++ if (UseCompressedClassPointers) { ++ __ encode_klass_not_null(tmp); ++ } ++ ++ if (basic_type != T_OBJECT) { ++ if (UseCompressedClassPointers) { ++ __ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } else { ++ __ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } ++ __ bne(tmp, t0, halt); ++ if (UseCompressedClassPointers) { ++ __ lwu(t0, Address(src, oopDesc::klass_offset_in_bytes())); ++ } else { ++ __ ld(t0, Address(src, oopDesc::klass_offset_in_bytes())); ++ } ++ __ beq(tmp, t0, known_ok); ++ } else { ++ if (UseCompressedClassPointers) { ++ __ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } else { ++ __ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } ++ __ beq(tmp, t0, known_ok); ++ __ beq(src, dst, known_ok); ++ } ++ __ bind(halt); ++ __ stop("incorrect type information in arraycopy"); ++ __ bind(known_ok); ++ } ++} ++ ++void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { ++ ciArrayKlass *default_type = op->expected_type(); ++ Register src = op->src()->as_register(); ++ Register dst = op->dst()->as_register(); ++ Register src_pos = op->src_pos()->as_register(); ++ Register dst_pos = op->dst_pos()->as_register(); ++ Register length = op->length()->as_register(); ++ Register tmp = op->tmp()->as_register(); ++ ++ CodeStub* stub = op->stub(); ++ int flags = op->flags(); ++ BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL; ++ if (is_reference_type(basic_type)) { basic_type = T_OBJECT; } ++ ++ // if we don't know anything, just go through the generic arraycopy ++ if (default_type == NULL) { ++ generic_arraycopy(src, src_pos, length, dst, dst_pos, stub); ++ return; ++ } ++ ++ assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), ++ "must be true at this point"); ++ ++ arraycopy_simple_check(src, src_pos, length, dst, dst_pos, tmp, stub, flags); ++ ++ if (flags & LIR_OpArrayCopy::type_check) { ++ arraycopy_type_check(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, flags); ++ } ++ ++#ifdef ASSERT ++ arraycopy_assert(src, dst, tmp, default_type, flags); ++#endif ++ ++#ifndef PRODUCT ++ if (PrintC1Statistics) { ++ __ incrementw(ExternalAddress(Runtime1::arraycopy_count_address(basic_type))); ++ } ++#endif ++ arraycopy_prepare_params(src, src_pos, length, dst, dst_pos, basic_type); ++ ++ bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0; ++ bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0; ++ const char *name = NULL; ++ address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false); ++ ++ CodeBlob *cb = CodeCache::find_blob(entry); ++ if (cb != NULL) { ++ __ far_call(RuntimeAddress(entry)); ++ } else { ++ const int args_num = 3; ++ __ call_VM_leaf(entry, args_num); ++ } ++ ++ __ bind(*stub->continuation()); ++} ++ ++ ++void LIR_Assembler::arraycopy_prepare_params(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, BasicType basic_type) { ++ int scale = array_element_size(basic_type); ++ __ shadd(c_rarg0, src_pos, src, t0, scale); ++ __ add(c_rarg0, c_rarg0, arrayOopDesc::base_offset_in_bytes(basic_type)); ++ assert_different_registers(c_rarg0, dst, dst_pos, length); ++ __ shadd(c_rarg1, dst_pos, dst, t0, scale); ++ __ add(c_rarg1, c_rarg1, arrayOopDesc::base_offset_in_bytes(basic_type)); ++ assert_different_registers(c_rarg1, dst, length); ++ __ mv(c_rarg2, length); ++ assert_different_registers(c_rarg2, dst); ++} ++ ++void LIR_Assembler::arraycopy_checkcast_prepare_params(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, BasicType basic_type) { ++ arraycopy_prepare_params(src, src_pos, length, dst, dst_pos, basic_type); ++ __ load_klass(c_rarg4, dst); ++ __ ld(c_rarg4, Address(c_rarg4, ObjArrayKlass::element_klass_offset())); ++ __ lwu(c_rarg3, Address(c_rarg4, Klass::super_check_offset_offset())); ++} ++ ++void LIR_Assembler::arraycopy_store_args(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos) { ++ __ sd(dst_pos, Address(sp, 0)); // 0: dst_pos sp offset ++ __ sd(dst, Address(sp, 1 * BytesPerWord)); // 1: dst sp offset ++ __ sd(length, Address(sp, 2 * BytesPerWord)); // 2: length sp offset ++ __ sd(src_pos, Address(sp, 3 * BytesPerWord)); // 3: src_pos sp offset ++ __ sd(src, Address(sp, 4 * BytesPerWord)); // 4: src sp offset ++} ++ ++void LIR_Assembler::arraycopy_load_args(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos) { ++ __ ld(dst_pos, Address(sp, 0)); // 0: dst_pos sp offset ++ __ ld(dst, Address(sp, 1 * BytesPerWord)); // 1: dst sp offset ++ __ ld(length, Address(sp, 2 * BytesPerWord)); // 2: length sp offset ++ __ ld(src_pos, Address(sp, 3 * BytesPerWord)); // 3: src_pos sp offset ++ __ ld(src, Address(sp, 4 * BytesPerWord)); // 4: src sp offset ++} ++ ++#undef __ +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.hpp +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) 2000, 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_LIRASSEMBLER_ARRAYCOPY_RISCV_HPP ++#define CPU_RISCV_C1_LIRASSEMBLER_ARRAYCOPY_RISCV_HPP ++ ++ // arraycopy sub functions ++ void generic_arraycopy(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, CodeStub *stub); ++ void arraycopy_simple_check(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, Register tmp, ++ CodeStub *stub, int flags); ++ void arraycopy_checkcast(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, Register tmp, ++ CodeStub *stub, BasicType basic_type, ++ address copyfunc_addr, int flags); ++ void arraycopy_type_check(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, Register tmp, ++ CodeStub *stub, BasicType basic_type, int flags); ++ void arraycopy_assert(Register src, Register dst, Register tmp, ciArrayKlass *default_type, int flags); ++ void arraycopy_prepare_params(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, BasicType basic_type); ++ void arraycopy_checkcast_prepare_params(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos, BasicType basic_type); ++ void arraycopy_store_args(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos); ++ void arraycopy_load_args(Register src, Register src_pos, Register length, ++ Register dst, Register dst_pos); ++ ++#endif // CPU_RISCV_C1_LIRASSEMBLER_ARRAYCOPY_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +@@ -0,0 +1,2254 @@ ++/* ++ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "c1/c1_CodeStubs.hpp" ++#include "c1/c1_Compilation.hpp" ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "c1/c1_Runtime1.hpp" ++#include "c1/c1_ValueStack.hpp" ++#include "ci/ciArrayKlass.hpp" ++#include "ci/ciInstance.hpp" ++#include "code/compiledIC.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/objArrayKlass.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "utilities/powerOfTwo.hpp" ++#include "vmreg_riscv.inline.hpp" ++ ++#ifndef PRODUCT ++#define COMMENT(x) do { __ block_comment(x); } while (0) ++#else ++#define COMMENT(x) ++#endif ++ ++NEEDS_CLEANUP // remove this definitions ? ++const Register IC_Klass = t1; // where the IC klass is cached ++const Register SYNC_header = x10; // synchronization header ++const Register SHIFT_count = x10; // where count for shift operations must be ++ ++#define __ _masm-> ++ ++static void select_different_registers(Register preserve, ++ Register extra, ++ Register &tmp1, ++ Register &tmp2) { ++ if (tmp1 == preserve) { ++ assert_different_registers(tmp1, tmp2, extra); ++ tmp1 = extra; ++ } else if (tmp2 == preserve) { ++ assert_different_registers(tmp1, tmp2, extra); ++ tmp2 = extra; ++ } ++ assert_different_registers(preserve, tmp1, tmp2); ++} ++ ++static void select_different_registers(Register preserve, ++ Register extra, ++ Register &tmp1, ++ Register &tmp2, ++ Register &tmp3) { ++ if (tmp1 == preserve) { ++ assert_different_registers(tmp1, tmp2, tmp3, extra); ++ tmp1 = extra; ++ } else if (tmp2 == preserve) { ++ assert_different_registers(tmp1, tmp2, tmp3, extra); ++ tmp2 = extra; ++ } else if (tmp3 == preserve) { ++ assert_different_registers(tmp1, tmp2, tmp3, extra); ++ tmp3 = extra; ++ } ++ assert_different_registers(preserve, tmp1, tmp2, tmp3); ++} ++ ++bool LIR_Assembler::is_small_constant(LIR_Opr opr) { Unimplemented(); return false; } ++ ++void LIR_Assembler::clinit_barrier(ciMethod* method) { ++ assert(VM_Version::supports_fast_class_init_checks(), "sanity"); ++ assert(!method->holder()->is_not_initialized(), "initialization should have been started"); ++ ++ Label L_skip_barrier; ++ ++ __ mov_metadata(t1, method->holder()->constant_encoding()); ++ __ clinit_barrier(t1, t0, &L_skip_barrier /* L_fast_path */); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); ++ __ bind(L_skip_barrier); ++} ++ ++LIR_Opr LIR_Assembler::receiverOpr() { ++ return FrameMap::receiver_opr; ++} ++ ++LIR_Opr LIR_Assembler::osrBufferPointer() { ++ return FrameMap::as_pointer_opr(receiverOpr()->as_register()); ++} ++ ++void LIR_Assembler::breakpoint() { Unimplemented(); } ++ ++void LIR_Assembler::push(LIR_Opr opr) { Unimplemented(); } ++ ++void LIR_Assembler::pop(LIR_Opr opr) { Unimplemented(); } ++ ++static jlong as_long(LIR_Opr data) { ++ jlong result; ++ switch (data->type()) { ++ case T_INT: ++ result = (data->as_jint()); ++ break; ++ case T_LONG: ++ result = (data->as_jlong()); ++ break; ++ default: ++ ShouldNotReachHere(); ++ result = 0; // unreachable ++ } ++ return result; ++} ++ ++Address LIR_Assembler::as_Address(LIR_Address* addr, Register tmp) { ++ if (addr->base()->is_illegal()) { ++ assert(addr->index()->is_illegal(), "must be illegal too"); ++ __ movptr(tmp, addr->disp()); ++ return Address(tmp, 0); ++ } ++ ++ Register base = addr->base()->as_pointer_register(); ++ LIR_Opr index_opr = addr->index(); ++ ++ if (index_opr->is_illegal()) { ++ return Address(base, addr->disp()); ++ } ++ ++ int scale = addr->scale(); ++ if (index_opr->is_cpu_register()) { ++ Register index; ++ if (index_opr->is_single_cpu()) { ++ index = index_opr->as_register(); ++ } else { ++ index = index_opr->as_register_lo(); ++ } ++ if (scale != 0) { ++ __ shadd(tmp, index, base, tmp, scale); ++ } else { ++ __ add(tmp, base, index); ++ } ++ return Address(tmp, addr->disp()); ++ } else if (index_opr->is_constant()) { ++ intptr_t addr_offset = (((intptr_t)index_opr->as_constant_ptr()->as_jint()) << scale) + addr->disp(); ++ return Address(base, addr_offset); ++ } ++ ++ Unimplemented(); ++ return Address(); ++} ++ ++Address LIR_Assembler::as_Address_hi(LIR_Address* addr) { ++ ShouldNotReachHere(); ++ return Address(); ++} ++ ++Address LIR_Assembler::as_Address(LIR_Address* addr) { ++ return as_Address(addr, t0); ++} ++ ++Address LIR_Assembler::as_Address_lo(LIR_Address* addr) { ++ return as_Address(addr); ++} ++ ++// Ensure a valid Address (base + offset) to a stack-slot. If stack access is ++// not encodable as a base + (immediate) offset, generate an explicit address ++// calculation to hold the address in t0. ++Address LIR_Assembler::stack_slot_address(int index, uint size, int adjust) { ++ precond(size == 4 || size == 8); ++ Address addr = frame_map()->address_for_slot(index, adjust); ++ precond(addr.getMode() == Address::base_plus_offset); ++ precond(addr.base() == sp); ++ precond(addr.offset() > 0); ++ uint mask = size - 1; ++ assert((addr.offset() & mask) == 0, "scaled offsets only"); ++ ++ return addr; ++} ++ ++void LIR_Assembler::osr_entry() { ++ offsets()->set_value(CodeOffsets::OSR_Entry, code_offset()); ++ BlockBegin* osr_entry = compilation()->hir()->osr_entry(); ++ guarantee(osr_entry != NULL, "NULL osr_entry!"); ++ ValueStack* entry_state = osr_entry->state(); ++ int number_of_locks = entry_state->locks_size(); ++ ++ // we jump here if osr happens with the interpreter ++ // state set up to continue at the beginning of the ++ // loop that triggered osr - in particular, we have ++ // the following registers setup: ++ // ++ // x12: osr buffer ++ // ++ ++ //build frame ++ ciMethod* m = compilation()->method(); ++ __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); ++ ++ // OSR buffer is ++ // ++ // locals[nlocals-1..0] ++ // monitors[0..number_of_locks] ++ // ++ // locals is a direct copy of the interpreter frame so in the osr buffer ++ // so first slot in the local array is the last local from the interpreter ++ // and last slot is local[0] (receiver) from the interpreter ++ // ++ // Similarly with locks. The first lock slot in the osr buffer is the nth lock ++ // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock ++ // in the interpreter frame (the method lock if a sync method) ++ ++ // Initialize monitors in the compiled activation. ++ // x12: pointer to osr buffer ++ // All other registers are dead at this point and the locals will be ++ // copied into place by code emitted in the IR. ++ ++ Register OSR_buf = osrBufferPointer()->as_pointer_register(); ++ { ++ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); ++ int monitor_offset = BytesPerWord * method()->max_locals() + ++ (2 * BytesPerWord) * (number_of_locks - 1); ++ // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in ++ // the OSR buffer using 2 word entries: first the lock and then ++ // the oop. ++ for (int i = 0; i < number_of_locks; i++) { ++ int slot_offset = monitor_offset - ((i * 2) * BytesPerWord); ++#ifdef ASSERT ++ // verify the interpreter's monitor has a non-null object ++ { ++ Label L; ++ __ ld(t0, Address(OSR_buf, slot_offset + 1 * BytesPerWord)); ++ __ bnez(t0, L); ++ __ stop("locked object is NULL"); ++ __ bind(L); ++ } ++#endif // ASSERT ++ __ ld(x9, Address(OSR_buf, slot_offset + 0)); ++ __ sd(x9, frame_map()->address_for_monitor_lock(i)); ++ __ ld(x9, Address(OSR_buf, slot_offset + 1 * BytesPerWord)); ++ __ sd(x9, frame_map()->address_for_monitor_object(i)); ++ } ++ } ++} ++ ++// inline cache check; done before the frame is built. ++int LIR_Assembler::check_icache() { ++ Register receiver = FrameMap::receiver_opr->as_register(); ++ Register ic_klass = IC_Klass; ++ int start_offset = __ offset(); ++ Label dont; ++ __ inline_cache_check(receiver, ic_klass, dont); ++ ++ // if icache check fails, then jump to runtime routine ++ // Note: RECEIVER must still contain the receiver! ++ __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); ++ ++ // We align the verified entry point unless the method body ++ // (including its inline cache check) will fit in a single 64-byte ++ // icache line. ++ if (!method()->is_accessor() || __ offset() - start_offset > 4 * 4) { ++ // force alignment after the cache check. ++ __ align(CodeEntryAlignment); ++ } ++ ++ __ bind(dont); ++ return start_offset; ++} ++ ++void LIR_Assembler::jobject2reg(jobject o, Register reg) { ++ if (o == NULL) { ++ __ mv(reg, zr); ++ } else { ++ __ movoop(reg, o, /* immediate */ true); ++ } ++} ++ ++void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) { ++ deoptimize_trap(info); ++} ++ ++// This specifies the rsp decrement needed to build the frame ++int LIR_Assembler::initial_frame_size_in_bytes() const { ++ // if rounding, must let FrameMap know! ++ ++ return in_bytes(frame_map()->framesize_in_bytes()); ++} ++ ++int LIR_Assembler::emit_exception_handler() { ++ // if the last instruction is a call (typically to do a throw which ++ // is coming at the end after block reordering) the return address ++ // must still point into the code area in order to avoid assertion ++ // failures when searching for the corresponding bci ==> add a nop ++ // (was bug 5/14/1999 -gri) ++ __ nop(); ++ ++ // generate code for exception handler ++ address handler_base = __ start_a_stub(exception_handler_size()); ++ if (handler_base == NULL) { ++ // not enough space left for the handler ++ bailout("exception handler overflow"); ++ return -1; ++ } ++ ++ int offset = code_offset(); ++ ++ // the exception oop and pc are in x10, and x13 ++ // no other registers need to be preserved, so invalidate them ++ __ invalidate_registers(false, true, true, false, true, true); ++ ++ // check that there is really an exception ++ __ verify_not_null_oop(x10); ++ ++ // search an exception handler (x10: exception oop, x13: throwing pc) ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id))); ++ __ should_not_reach_here(); ++ guarantee(code_offset() - offset <= exception_handler_size(), "overflow"); ++ __ end_a_stub(); ++ ++ return offset; ++} ++ ++// Emit the code to remove the frame from the stack in the exception ++// unwind path. ++int LIR_Assembler::emit_unwind_handler() { ++#ifndef PRODUCT ++ if (CommentedAssembly) { ++ _masm->block_comment("Unwind handler"); ++ } ++#endif // PRODUCT ++ ++ int offset = code_offset(); ++ ++ // Fetch the exception from TLS and clear out exception related thread state ++ __ ld(x10, Address(xthread, JavaThread::exception_oop_offset())); ++ __ sd(zr, Address(xthread, JavaThread::exception_oop_offset())); ++ __ sd(zr, Address(xthread, JavaThread::exception_pc_offset())); ++ ++ __ bind(_unwind_handler_entry); ++ __ verify_not_null_oop(x10); ++ if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { ++ __ mv(x9, x10); // Perserve the exception ++ } ++ ++ // Preform needed unlocking ++ MonitorExitStub* stub = NULL; ++ if (method()->is_synchronized()) { ++ monitor_address(0, FrameMap::r10_opr); ++ stub = new MonitorExitStub(FrameMap::r10_opr, true, 0); ++ __ unlock_object(x15, x14, x10, *stub->entry()); ++ __ bind(*stub->continuation()); ++ } ++ ++ if (compilation()->env()->dtrace_method_probes()) { ++ __ mv(c_rarg0, xthread); ++ __ mov_metadata(c_rarg1, method()->constant_encoding()); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), c_rarg0, c_rarg1); ++ } ++ ++ if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { ++ __ mv(x10, x9); // Restore the exception ++ } ++ ++ // remove the activation and dispatch to the unwind handler ++ __ block_comment("remove_frame and dispatch to the unwind handler"); ++ __ remove_frame(initial_frame_size_in_bytes()); ++ __ far_jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); ++ ++ // Emit the slow path assembly ++ if (stub != NULL) { ++ stub->emit_code(this); ++ } ++ ++ return offset; ++} ++ ++int LIR_Assembler::emit_deopt_handler() { ++ // if the last instruciton is a call (typically to do a throw which ++ // is coming at the end after block reordering) the return address ++ // must still point into the code area in order to avoid assertion ++ // failures when searching for the corresponding bck => add a nop ++ // (was bug 5/14/1999 - gri) ++ __ nop(); ++ ++ // generate code for exception handler ++ address handler_base = __ start_a_stub(deopt_handler_size()); ++ if (handler_base == NULL) { ++ // not enough space left for the handler ++ bailout("deopt handler overflow"); ++ return -1; ++ } ++ ++ int offset = code_offset(); ++ ++ __ auipc(ra, 0); ++ __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); ++ guarantee(code_offset() - offset <= deopt_handler_size(), "overflow"); ++ __ end_a_stub(); ++ ++ return offset; ++} ++ ++void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) { ++ assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == x10, "word returns are in x10"); ++ ++ // Pop the stack before the safepoint code ++ __ remove_frame(initial_frame_size_in_bytes()); ++ ++ if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) { ++ __ reserved_stack_check(); ++ } ++ ++ code_stub->set_safepoint_offset(__ offset()); ++ __ relocate(relocInfo::poll_return_type); ++ __ safepoint_poll(*code_stub->entry(), true /* at_return */, false /* acquire */, true /* in_nmethod */); ++ __ ret(); ++} ++ ++int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { ++ guarantee(info != NULL, "Shouldn't be NULL"); ++ __ get_polling_page(t0, relocInfo::poll_type); ++ add_debug_info_for_branch(info); // This isn't just debug info: ++ // it's the oop map ++ __ read_polling_page(t0, 0, relocInfo::poll_type); ++ return __ offset(); ++} ++ ++void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { ++ __ mv(to_reg, from_reg); ++} ++ ++void LIR_Assembler::swap_reg(Register a, Register b) { Unimplemented(); } ++ ++void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { ++ assert(src->is_constant(), "should not call otherwise"); ++ assert(dest->is_register(), "should not call otherwise"); ++ LIR_Const* c = src->as_constant_ptr(); ++ address const_addr = NULL; ++ ++ switch (c->type()) { ++ case T_INT: ++ assert(patch_code == lir_patch_none, "no patching handled here"); ++ __ mv(dest->as_register(), c->as_jint()); ++ break; ++ ++ case T_ADDRESS: ++ assert(patch_code == lir_patch_none, "no patching handled here"); ++ __ mv(dest->as_register(), c->as_jint()); ++ break; ++ ++ case T_LONG: ++ assert(patch_code == lir_patch_none, "no patching handled here"); ++ __ mv(dest->as_register_lo(), (intptr_t)c->as_jlong()); ++ break; ++ ++ case T_OBJECT: ++ case T_ARRAY: ++ if (patch_code == lir_patch_none) { ++ jobject2reg(c->as_jobject(), dest->as_register()); ++ } else { ++ jobject2reg_with_patching(dest->as_register(), info); ++ } ++ break; ++ ++ case T_METADATA: ++ if (patch_code != lir_patch_none) { ++ klass2reg_with_patching(dest->as_register(), info); ++ } else { ++ __ mov_metadata(dest->as_register(), c->as_metadata()); ++ } ++ break; ++ ++ case T_FLOAT: ++ const_addr = float_constant(c->as_jfloat()); ++ assert(const_addr != NULL, "must create float constant in the constant table"); ++ __ flw(dest->as_float_reg(), InternalAddress(const_addr)); ++ break; ++ ++ case T_DOUBLE: ++ const_addr = double_constant(c->as_jdouble()); ++ assert(const_addr != NULL, "must create double constant in the constant table"); ++ __ fld(dest->as_double_reg(), InternalAddress(const_addr)); ++ break; ++ ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { ++ assert(src->is_constant(), "should not call otherwise"); ++ assert(dest->is_stack(), "should not call otherwise"); ++ LIR_Const* c = src->as_constant_ptr(); ++ switch (c->type()) { ++ case T_OBJECT: ++ if (c->as_jobject() == NULL) { ++ __ sd(zr, frame_map()->address_for_slot(dest->single_stack_ix())); ++ } else { ++ const2reg(src, FrameMap::t1_opr, lir_patch_none, NULL); ++ reg2stack(FrameMap::t1_opr, dest, c->type(), false); ++ } ++ break; ++ case T_ADDRESS: // fall through ++ const2reg(src, FrameMap::t1_opr, lir_patch_none, NULL); ++ reg2stack(FrameMap::t1_opr, dest, c->type(), false); ++ case T_INT: // fall through ++ case T_FLOAT: ++ if (c->as_jint_bits() == 0) { ++ __ sw(zr, frame_map()->address_for_slot(dest->single_stack_ix())); ++ } else { ++ __ mv(t1, c->as_jint_bits()); ++ __ sw(t1, frame_map()->address_for_slot(dest->single_stack_ix())); ++ } ++ break; ++ case T_LONG: // fall through ++ case T_DOUBLE: ++ if (c->as_jlong_bits() == 0) { ++ __ sd(zr, frame_map()->address_for_slot(dest->double_stack_ix(), ++ lo_word_offset_in_bytes)); ++ } else { ++ __ mv(t1, (intptr_t)c->as_jlong_bits()); ++ __ sd(t1, frame_map()->address_for_slot(dest->double_stack_ix(), ++ lo_word_offset_in_bytes)); ++ } ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { ++ assert(src->is_constant(), "should not call otherwise"); ++ assert(dest->is_address(), "should not call otherwise"); ++ LIR_Const* c = src->as_constant_ptr(); ++ LIR_Address* to_addr = dest->as_address_ptr(); ++ void (MacroAssembler::* insn)(Register Rt, const Address &adr, Register temp); ++ switch (type) { ++ case T_ADDRESS: ++ assert(c->as_jint() == 0, "should be"); ++ insn = &MacroAssembler::sd; break; ++ case T_LONG: ++ assert(c->as_jlong() == 0, "should be"); ++ insn = &MacroAssembler::sd; break; ++ case T_DOUBLE: ++ assert(c->as_jdouble() == 0.0, "should be"); ++ insn = &MacroAssembler::sd; break; ++ case T_INT: ++ assert(c->as_jint() == 0, "should be"); ++ insn = &MacroAssembler::sw; break; ++ case T_FLOAT: ++ assert(c->as_jfloat() == 0.0f, "should be"); ++ insn = &MacroAssembler::sw; break; ++ case T_OBJECT: // fall through ++ case T_ARRAY: ++ assert(c->as_jobject() == 0, "should be"); ++ if (UseCompressedOops && !wide) { ++ insn = &MacroAssembler::sw; ++ } else { ++ insn = &MacroAssembler::sd; ++ } ++ break; ++ case T_CHAR: // fall through ++ case T_SHORT: ++ assert(c->as_jint() == 0, "should be"); ++ insn = &MacroAssembler::sh; ++ break; ++ case T_BOOLEAN: // fall through ++ case T_BYTE: ++ assert(c->as_jint() == 0, "should be"); ++ insn = &MacroAssembler::sb; break; ++ default: ++ ShouldNotReachHere(); ++ insn = &MacroAssembler::sd; // unreachable ++ } ++ if (info != NULL) { ++ add_debug_info_for_null_check_here(info); ++ } ++ (_masm->*insn)(zr, as_Address(to_addr), t0); ++} ++ ++void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { ++ assert(src->is_register(), "should not call otherwise"); ++ assert(dest->is_register(), "should not call otherwise"); ++ ++ // move between cpu-registers ++ if (dest->is_single_cpu()) { ++ if (src->type() == T_LONG) { ++ // Can do LONG -> OBJECT ++ move_regs(src->as_register_lo(), dest->as_register()); ++ return; ++ } ++ assert(src->is_single_cpu(), "must match"); ++ if (src->type() == T_OBJECT) { ++ __ verify_oop(src->as_register()); ++ } ++ move_regs(src->as_register(), dest->as_register()); ++ } else if (dest->is_double_cpu()) { ++ if (is_reference_type(src->type())) { ++ __ verify_oop(src->as_register()); ++ move_regs(src->as_register(), dest->as_register_lo()); ++ return; ++ } ++ assert(src->is_double_cpu(), "must match"); ++ Register f_lo = src->as_register_lo(); ++ Register f_hi = src->as_register_hi(); ++ Register t_lo = dest->as_register_lo(); ++ Register t_hi = dest->as_register_hi(); ++ assert(f_hi == f_lo, "must be same"); ++ assert(t_hi == t_lo, "must be same"); ++ move_regs(f_lo, t_lo); ++ } else if (dest->is_single_fpu()) { ++ assert(src->is_single_fpu(), "expect single fpu"); ++ __ fmv_s(dest->as_float_reg(), src->as_float_reg()); ++ } else if (dest->is_double_fpu()) { ++ assert(src->is_double_fpu(), "expect double fpu"); ++ __ fmv_d(dest->as_double_reg(), src->as_double_reg()); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) { ++ precond(src->is_register() && dest->is_stack()); ++ ++ uint const c_sz32 = sizeof(uint32_t); ++ uint const c_sz64 = sizeof(uint64_t); ++ ++ assert(src->is_register(), "should not call otherwise"); ++ assert(dest->is_stack(), "should not call otherwise"); ++ if (src->is_single_cpu()) { ++ int index = dest->single_stack_ix(); ++ if (is_reference_type(type)) { ++ __ sd(src->as_register(), stack_slot_address(index, c_sz64)); ++ __ verify_oop(src->as_register()); ++ } else if (type == T_METADATA || type == T_DOUBLE || type == T_ADDRESS) { ++ __ sd(src->as_register(), stack_slot_address(index, c_sz64)); ++ } else { ++ __ sw(src->as_register(), stack_slot_address(index, c_sz32)); ++ } ++ } else if (src->is_double_cpu()) { ++ int index = dest->double_stack_ix(); ++ Address dest_addr_LO = stack_slot_address(index, c_sz64, lo_word_offset_in_bytes); ++ __ sd(src->as_register_lo(), dest_addr_LO); ++ } else if (src->is_single_fpu()) { ++ int index = dest->single_stack_ix(); ++ __ fsw(src->as_float_reg(), stack_slot_address(index, c_sz32)); ++ } else if (src->is_double_fpu()) { ++ int index = dest->double_stack_ix(); ++ __ fsd(src->as_double_reg(), stack_slot_address(index, c_sz64)); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) { ++ LIR_Address* to_addr = dest->as_address_ptr(); ++ // t0 was used as tmp reg in as_Address, so we use t1 as compressed_src ++ Register compressed_src = t1; ++ ++ if (patch_code != lir_patch_none) { ++ deoptimize_trap(info); ++ return; ++ } ++ ++ if (is_reference_type(type)) { ++ __ verify_oop(src->as_register()); ++ ++ if (UseCompressedOops && !wide) { ++ __ encode_heap_oop(compressed_src, src->as_register()); ++ } else { ++ compressed_src = src->as_register(); ++ } ++ } ++ ++ int null_check_here = code_offset(); ++ ++ switch (type) { ++ case T_FLOAT: ++ __ fsw(src->as_float_reg(), as_Address(to_addr)); ++ break; ++ ++ case T_DOUBLE: ++ __ fsd(src->as_double_reg(), as_Address(to_addr)); ++ break; ++ ++ case T_ARRAY: // fall through ++ case T_OBJECT: ++ if (UseCompressedOops && !wide) { ++ __ sw(compressed_src, as_Address(to_addr)); ++ } else { ++ __ sd(compressed_src, as_Address(to_addr)); ++ } ++ break; ++ case T_METADATA: ++ // We get here to store a method pointer to the stack to pass to ++ // a dtrace runtime call. This can't work on 64 bit with ++ // compressed klass ptrs: T_METADATA can be compressed klass ++ // ptr or a 64 bit method pointer. ++ ShouldNotReachHere(); ++ __ sd(src->as_register(), as_Address(to_addr)); ++ break; ++ case T_ADDRESS: ++ __ sd(src->as_register(), as_Address(to_addr)); ++ break; ++ case T_INT: ++ __ sw(src->as_register(), as_Address(to_addr)); ++ break; ++ case T_LONG: ++ __ sd(src->as_register_lo(), as_Address(to_addr)); ++ break; ++ case T_BYTE: // fall through ++ case T_BOOLEAN: ++ __ sb(src->as_register(), as_Address(to_addr)); ++ break; ++ case T_CHAR: // fall through ++ case T_SHORT: ++ __ sh(src->as_register(), as_Address(to_addr)); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ ++ if (info != NULL) { ++ add_debug_info_for_null_check(null_check_here, info); ++ } ++} ++ ++void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { ++ precond(src->is_stack() && dest->is_register()); ++ ++ uint const c_sz32 = sizeof(uint32_t); ++ uint const c_sz64 = sizeof(uint64_t); ++ ++ if (dest->is_single_cpu()) { ++ int index = src->single_stack_ix(); ++ if (type == T_INT) { ++ __ lw(dest->as_register(), stack_slot_address(index, c_sz32)); ++ } else if (is_reference_type(type)) { ++ __ ld(dest->as_register(), stack_slot_address(index, c_sz64)); ++ __ verify_oop(dest->as_register()); ++ } else if (type == T_METADATA || type == T_ADDRESS) { ++ __ ld(dest->as_register(), stack_slot_address(index, c_sz64)); ++ } else { ++ __ lwu(dest->as_register(), stack_slot_address(index, c_sz32)); ++ } ++ } else if (dest->is_double_cpu()) { ++ int index = src->double_stack_ix(); ++ Address src_addr_LO = stack_slot_address(index, c_sz64, lo_word_offset_in_bytes); ++ __ ld(dest->as_register_lo(), src_addr_LO); ++ } else if (dest->is_single_fpu()) { ++ int index = src->single_stack_ix(); ++ __ flw(dest->as_float_reg(), stack_slot_address(index, c_sz32)); ++ } else if (dest->is_double_fpu()) { ++ int index = src->double_stack_ix(); ++ __ fld(dest->as_double_reg(), stack_slot_address(index, c_sz64)); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo* info) { ++ deoptimize_trap(info); ++} ++ ++void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { ++ LIR_Opr temp; ++ if (type == T_LONG || type == T_DOUBLE) { ++ temp = FrameMap::t1_long_opr; ++ } else { ++ temp = FrameMap::t1_opr; ++ } ++ ++ stack2reg(src, temp, src->type()); ++ reg2stack(temp, dest, dest->type(), false); ++} ++ ++void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) { ++ assert(src->is_address(), "should not call otherwise"); ++ assert(dest->is_register(), "should not call otherwise"); ++ ++ LIR_Address* addr = src->as_address_ptr(); ++ LIR_Address* from_addr = src->as_address_ptr(); ++ ++ if (addr->base()->type() == T_OBJECT) { ++ __ verify_oop(addr->base()->as_pointer_register()); ++ } ++ ++ if (patch_code != lir_patch_none) { ++ deoptimize_trap(info); ++ return; ++ } ++ ++ if (info != NULL) { ++ add_debug_info_for_null_check_here(info); ++ } ++ ++ int null_check_here = code_offset(); ++ switch (type) { ++ case T_FLOAT: ++ __ flw(dest->as_float_reg(), as_Address(from_addr)); ++ break; ++ case T_DOUBLE: ++ __ fld(dest->as_double_reg(), as_Address(from_addr)); ++ break; ++ case T_ARRAY: // fall through ++ case T_OBJECT: ++ if (UseCompressedOops && !wide) { ++ __ lwu(dest->as_register(), as_Address(from_addr)); ++ } else { ++ __ ld(dest->as_register(), as_Address(from_addr)); ++ } ++ break; ++ case T_METADATA: ++ // We get here to store a method pointer to the stack to pass to ++ // a dtrace runtime call. This can't work on 64 bit with ++ // compressed klass ptrs: T_METADATA can be a compressed klass ++ // ptr or a 64 bit method pointer. ++ ShouldNotReachHere(); ++ __ ld(dest->as_register(), as_Address(from_addr)); ++ break; ++ case T_ADDRESS: ++ if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) { ++ __ lwu(dest->as_register(), as_Address(from_addr)); ++ } else { ++ __ ld(dest->as_register(), as_Address(from_addr)); ++ } ++ break; ++ case T_INT: ++ __ lw(dest->as_register(), as_Address(from_addr)); ++ break; ++ case T_LONG: ++ __ ld(dest->as_register_lo(), as_Address_lo(from_addr)); ++ break; ++ case T_BYTE: ++ __ lb(dest->as_register(), as_Address(from_addr)); ++ break; ++ case T_BOOLEAN: ++ __ lbu(dest->as_register(), as_Address(from_addr)); ++ break; ++ case T_CHAR: ++ __ lhu(dest->as_register(), as_Address(from_addr)); ++ break; ++ case T_SHORT: ++ __ lh(dest->as_register(), as_Address(from_addr)); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ ++ if (is_reference_type(type)) { ++ if (UseCompressedOops && !wide) { ++ __ decode_heap_oop(dest->as_register()); ++ } ++ ++ if (!UseZGC) { ++ // Load barrier has not yet been applied, so ZGC can't verify the oop here ++ __ verify_oop(dest->as_register()); ++ } ++ } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) { ++ if (UseCompressedClassPointers) { ++ __ decode_klass_not_null(dest->as_register()); ++ } ++ } ++} ++ ++void LIR_Assembler::emit_op3(LIR_Op3* op) { ++ switch (op->code()) { ++ case lir_idiv: // fall through ++ case lir_irem: ++ arithmetic_idiv(op->code(), ++ op->in_opr1(), ++ op->in_opr2(), ++ op->in_opr3(), ++ op->result_opr(), ++ op->info()); ++ break; ++ case lir_fmad: ++ __ fmadd_d(op->result_opr()->as_double_reg(), ++ op->in_opr1()->as_double_reg(), ++ op->in_opr2()->as_double_reg(), ++ op->in_opr3()->as_double_reg()); ++ break; ++ case lir_fmaf: ++ __ fmadd_s(op->result_opr()->as_float_reg(), ++ op->in_opr1()->as_float_reg(), ++ op->in_opr2()->as_float_reg(), ++ op->in_opr3()->as_float_reg()); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type, ++ LIR_Opr cmp_opr1, LIR_Opr cmp_opr2) { ++ Label label; ++ ++ emit_branch(condition, cmp_opr1, cmp_opr2, label, /* is_far */ false, ++ /* is_unordered */ (condition == lir_cond_greaterEqual || condition == lir_cond_greater) ? false : true); ++ ++ Label done; ++ move_op(opr2, result, type, lir_patch_none, NULL, ++ false, // pop_fpu_stack ++ false, // wide ++ false); // unaligned ++ __ j(done); ++ __ bind(label); ++ move_op(opr1, result, type, lir_patch_none, NULL, ++ false, // pop_fpu_stack ++ false, // wide ++ false); // unaligned ++ __ bind(done); ++} ++ ++void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) { ++ LIR_Condition condition = op->cond(); ++ if (condition == lir_cond_always) { ++ if (op->info() != NULL) { ++ add_debug_info_for_branch(op->info()); ++ } ++ } else { ++ assert(op->in_opr1() != LIR_OprFact::illegalOpr && op->in_opr2() != LIR_OprFact::illegalOpr, "conditional branches must have legal operands"); ++ } ++ bool is_unordered = (op->ublock() == op->block()); ++ emit_branch(condition, op->in_opr1(), op->in_opr2(), *op->label(), /* is_far */ true, is_unordered); ++} ++ ++void LIR_Assembler::emit_branch(LIR_Condition cmp_flag, LIR_Opr cmp1, LIR_Opr cmp2, Label& label, ++ bool is_far, bool is_unordered) { ++ ++ if (cmp_flag == lir_cond_always) { ++ __ j(label); ++ return; ++ } ++ ++ if (cmp1->is_cpu_register()) { ++ Register reg1 = as_reg(cmp1); ++ if (cmp2->is_cpu_register()) { ++ Register reg2 = as_reg(cmp2); ++ __ c1_cmp_branch(cmp_flag, reg1, reg2, label, cmp1->type(), is_far); ++ } else if (cmp2->is_constant()) { ++ const2reg_helper(cmp2); ++ __ c1_cmp_branch(cmp_flag, reg1, t0, label, cmp2->type(), is_far); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } else if (cmp1->is_single_fpu()) { ++ assert(cmp2->is_single_fpu(), "expect single float register"); ++ __ c1_float_cmp_branch(cmp_flag, cmp1->as_float_reg(), cmp2->as_float_reg(), label, is_far, is_unordered); ++ } else if (cmp1->is_double_fpu()) { ++ assert(cmp2->is_double_fpu(), "expect double float register"); ++ __ c1_float_cmp_branch(cmp_flag | C1_MacroAssembler::c1_double_branch_mask, ++ cmp1->as_double_reg(), cmp2->as_double_reg(), label, is_far, is_unordered); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { ++ LIR_Opr src = op->in_opr(); ++ LIR_Opr dest = op->result_opr(); ++ ++ switch (op->bytecode()) { ++ case Bytecodes::_i2f: ++ __ fcvt_s_w(dest->as_float_reg(), src->as_register()); break; ++ case Bytecodes::_i2d: ++ __ fcvt_d_w(dest->as_double_reg(), src->as_register()); break; ++ case Bytecodes::_l2d: ++ __ fcvt_d_l(dest->as_double_reg(), src->as_register_lo()); break; ++ case Bytecodes::_l2f: ++ __ fcvt_s_l(dest->as_float_reg(), src->as_register_lo()); break; ++ case Bytecodes::_f2d: ++ __ fcvt_d_s(dest->as_double_reg(), src->as_float_reg()); break; ++ case Bytecodes::_d2f: ++ __ fcvt_s_d(dest->as_float_reg(), src->as_double_reg()); break; ++ case Bytecodes::_i2c: ++ __ zero_extend(dest->as_register(), src->as_register(), 16); break; ++ case Bytecodes::_i2l: ++ __ sign_extend(dest->as_register_lo(), src->as_register(), 32); break; ++ case Bytecodes::_i2s: ++ __ sign_extend(dest->as_register(), src->as_register(), 16); break; ++ case Bytecodes::_i2b: ++ __ sign_extend(dest->as_register(), src->as_register(), 8); break; ++ case Bytecodes::_l2i: ++ __ sign_extend(dest->as_register(), src->as_register_lo(), 32); break; ++ case Bytecodes::_d2l: ++ __ fcvt_l_d_safe(dest->as_register_lo(), src->as_double_reg()); break; ++ case Bytecodes::_f2i: ++ __ fcvt_w_s_safe(dest->as_register(), src->as_float_reg()); break; ++ case Bytecodes::_f2l: ++ __ fcvt_l_s_safe(dest->as_register_lo(), src->as_float_reg()); break; ++ case Bytecodes::_d2i: ++ __ fcvt_w_d_safe(dest->as_register(), src->as_double_reg()); break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { ++ if (op->init_check()) { ++ __ lbu(t0, Address(op->klass()->as_register(), ++ InstanceKlass::init_state_offset())); ++ __ mv(t1, (u1)InstanceKlass::fully_initialized); ++ add_debug_info_for_null_check_here(op->stub()->info()); ++ __ bne(t0, t1, *op->stub()->entry(), /* is_far */ true); ++ } ++ ++ __ allocate_object(op->obj()->as_register(), ++ op->tmp1()->as_register(), ++ op->tmp2()->as_register(), ++ op->header_size(), ++ op->object_size(), ++ op->klass()->as_register(), ++ *op->stub()->entry()); ++ ++ __ bind(*op->stub()->continuation()); ++} ++ ++void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { ++ Register len = op->len()->as_register(); ++ ++ if (UseSlowPath || ++ (!UseFastNewObjectArray && is_reference_type(op->type())) || ++ (!UseFastNewTypeArray && !is_reference_type(op->type()))) { ++ __ j(*op->stub()->entry()); ++ } else { ++ Register tmp1 = op->tmp1()->as_register(); ++ Register tmp2 = op->tmp2()->as_register(); ++ Register tmp3 = op->tmp3()->as_register(); ++ if (len == tmp1) { ++ tmp1 = tmp3; ++ } else if (len == tmp2) { ++ tmp2 = tmp3; ++ } else if (len == tmp3) { ++ // everything is ok ++ } else { ++ __ mv(tmp3, len); ++ } ++ __ allocate_array(op->obj()->as_register(), ++ len, ++ tmp1, ++ tmp2, ++ arrayOopDesc::header_size(op->type()), ++ array_element_size(op->type()), ++ op->klass()->as_register(), ++ *op->stub()->entry()); ++ } ++ __ bind(*op->stub()->continuation()); ++} ++ ++void LIR_Assembler::type_profile_helper(Register mdo, ciMethodData *md, ciProfileData *data, ++ Register recv, Label* update_done) { ++ for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { ++ Label next_test; ++ // See if the receiver is receiver[n]. ++ __ ld(t1, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); ++ __ bne(recv, t1, next_test); ++ Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); ++ __ increment(data_addr, DataLayout::counter_increment); ++ __ j(*update_done); ++ __ bind(next_test); ++ } ++ ++ // Didn't find receiver; find next empty slot and fill it in ++ for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { ++ Label next_test; ++ Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))); ++ __ ld(t1, recv_addr); ++ __ bnez(t1, next_test); ++ __ sd(recv, recv_addr); ++ __ mv(t1, DataLayout::counter_increment); ++ __ sd(t1, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)))); ++ __ j(*update_done); ++ __ bind(next_test); ++ } ++} ++ ++void LIR_Assembler::data_check(LIR_OpTypeCheck *op, ciMethodData **md, ciProfileData **data) { ++ ciMethod* method = op->profiled_method(); ++ assert(method != NULL, "Should have method"); ++ int bci = op->profiled_bci(); ++ *md = method->method_data_or_null(); ++ guarantee(*md != NULL, "Sanity"); ++ *data = ((*md)->bci_to_data(bci)); ++ assert(*data != NULL, "need data for type check"); ++ assert((*data)->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); ++} ++ ++void LIR_Assembler::typecheck_helper_slowcheck(ciKlass *k, Register obj, Register Rtmp1, ++ Register k_RInfo, Register klass_RInfo, ++ Label *failure_target, Label *success_target) { ++ // get object class ++ // not a safepoint as obj null check happens earlier ++ __ load_klass(klass_RInfo, obj); ++ if (k->is_loaded()) { ++ // See if we get an immediate positive hit ++ __ ld(t0, Address(klass_RInfo, int64_t(k->super_check_offset()))); ++ if ((juint)in_bytes(Klass::secondary_super_cache_offset()) != k->super_check_offset()) { ++ __ bne(k_RInfo, t0, *failure_target, /* is_far */ true); ++ // successful cast, fall through to profile or jump ++ } else { ++ // See if we get an immediate positive hit ++ __ beq(k_RInfo, t0, *success_target); ++ // check for self ++ __ beq(klass_RInfo, k_RInfo, *success_target); ++ ++ __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo ++ __ sd(k_RInfo, Address(sp, 0)); // sub klass ++ __ sd(klass_RInfo, Address(sp, wordSize)); // super klass ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); ++ // load result to k_RInfo ++ __ ld(k_RInfo, Address(sp, 0)); ++ __ addi(sp, sp, 2 * wordSize); // 2: pop out k_RInfo and klass_RInfo ++ // result is a boolean ++ __ beqz(k_RInfo, *failure_target, /* is_far */ true); ++ // successful cast, fall through to profile or jump ++ } ++ } else { ++ // perform the fast part of the checking logic ++ __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); ++ // call out-of-line instance of __ check_klass_subtytpe_slow_path(...) ++ __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo ++ __ sd(klass_RInfo, Address(sp, wordSize)); // sub klass ++ __ sd(k_RInfo, Address(sp, 0)); // super klass ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); ++ // load result to k_RInfo ++ __ ld(k_RInfo, Address(sp, 0)); ++ __ addi(sp, sp, 2 * wordSize); // 2: pop out k_RInfo and klass_RInfo ++ // result is a boolean ++ __ beqz(k_RInfo, *failure_target, /* is_far */ true); ++ // successful cast, fall thriugh to profile or jump ++ } ++} ++ ++void LIR_Assembler::profile_object(ciMethodData* md, ciProfileData* data, Register obj, ++ Register klass_RInfo, Label* obj_is_null) { ++ Label not_null; ++ __ bnez(obj, not_null); ++ // Object is null, update MDO and exit ++ Register mdo = klass_RInfo; ++ __ mov_metadata(mdo, md->constant_encoding()); ++ Address data_addr = __ form_address(t1, mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset())); ++ __ lbu(t0, data_addr); ++ __ ori(t0, t0, BitData::null_seen_byte_constant()); ++ __ sb(t0, data_addr); ++ __ j(*obj_is_null); ++ __ bind(not_null); ++} ++ ++void LIR_Assembler::typecheck_loaded(LIR_OpTypeCheck *op, ciKlass* k, Register k_RInfo) { ++ if (!k->is_loaded()) { ++ klass2reg_with_patching(k_RInfo, op->info_for_patch()); ++ } else { ++ __ mov_metadata(k_RInfo, k->constant_encoding()); ++ } ++} ++ ++void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) { ++ Register obj = op->object()->as_register(); ++ Register k_RInfo = op->tmp1()->as_register(); ++ Register klass_RInfo = op->tmp2()->as_register(); ++ Register dst = op->result_opr()->as_register(); ++ ciKlass* k = op->klass(); ++ Register Rtmp1 = noreg; ++ ++ // check if it needs to be profiled ++ ciMethodData* md = NULL; ++ ciProfileData* data = NULL; ++ ++ const bool should_profile = op->should_profile(); ++ if (should_profile) { ++ data_check(op, &md, &data); ++ } ++ Label profile_cast_success, profile_cast_failure; ++ Label *success_target = should_profile ? &profile_cast_success : success; ++ Label *failure_target = should_profile ? &profile_cast_failure : failure; ++ ++ if (obj == k_RInfo) { ++ k_RInfo = dst; ++ } else if (obj == klass_RInfo) { ++ klass_RInfo = dst; ++ } ++ if (k->is_loaded() && !UseCompressedClassPointers) { ++ select_different_registers(obj, dst, k_RInfo, klass_RInfo); ++ } else { ++ Rtmp1 = op->tmp3()->as_register(); ++ select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); ++ } ++ ++ assert_different_registers(obj, k_RInfo, klass_RInfo); ++ ++ if (should_profile) { ++ profile_object(md, data, obj, klass_RInfo, obj_is_null); ++ } else { ++ __ beqz(obj, *obj_is_null); ++ } ++ ++ typecheck_loaded(op, k, k_RInfo); ++ __ verify_oop(obj); ++ ++ if (op->fast_check()) { ++ // get object class ++ // not a safepoint as obj null check happens earlier ++ __ load_klass(t0, obj, t1); ++ __ bne(t0, k_RInfo, *failure_target, /* is_far */ true); ++ // successful cast, fall through to profile or jump ++ } else { ++ typecheck_helper_slowcheck(k, obj, Rtmp1, k_RInfo, klass_RInfo, failure_target, success_target); ++ } ++ if (should_profile) { ++ type_profile(obj, md, klass_RInfo, k_RInfo, data, success, failure, profile_cast_success, profile_cast_failure); ++ } ++ __ j(*success); ++} ++ ++void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { ++ const bool should_profile = op->should_profile(); ++ ++ LIR_Code code = op->code(); ++ if (code == lir_store_check) { ++ typecheck_lir_store(op, should_profile); ++ } else if (code == lir_checkcast) { ++ Register obj = op->object()->as_register(); ++ Register dst = op->result_opr()->as_register(); ++ Label success; ++ emit_typecheck_helper(op, &success, op->stub()->entry(), &success); ++ __ bind(success); ++ if (dst != obj) { ++ __ mv(dst, obj); ++ } ++ } else if (code == lir_instanceof) { ++ Register obj = op->object()->as_register(); ++ Register dst = op->result_opr()->as_register(); ++ Label success, failure, done; ++ emit_typecheck_helper(op, &success, &failure, &failure); ++ __ bind(failure); ++ __ mv(dst, zr); ++ __ j(done); ++ __ bind(success); ++ __ mv(dst, 1); ++ __ bind(done); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { ++ assert(VM_Version::supports_cx8(), "wrong machine"); ++ Register addr; ++ if (op->addr()->is_register()) { ++ addr = as_reg(op->addr()); ++ } else { ++ assert(op->addr()->is_address(), "what else?"); ++ LIR_Address* addr_ptr = op->addr()->as_address_ptr(); ++ assert(addr_ptr->disp() == 0, "need 0 disp"); ++ assert(addr_ptr->index() == LIR_OprDesc::illegalOpr(), "need 0 index"); ++ addr = as_reg(addr_ptr->base()); ++ } ++ Register newval = as_reg(op->new_value()); ++ Register cmpval = as_reg(op->cmp_value()); ++ ++ if (op->code() == lir_cas_obj) { ++ if (UseCompressedOops) { ++ Register tmp1 = op->tmp1()->as_register(); ++ assert(op->tmp1()->is_valid(), "must be"); ++ __ encode_heap_oop(tmp1, cmpval); ++ cmpval = tmp1; ++ __ encode_heap_oop(t1, newval); ++ newval = t1; ++ caswu(addr, newval, cmpval); ++ } else { ++ casl(addr, newval, cmpval); ++ } ++ } else if (op->code() == lir_cas_int) { ++ casw(addr, newval, cmpval); ++ } else { ++ casl(addr, newval, cmpval); ++ } ++} ++ ++void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op) { ++ switch (code) { ++ case lir_abs: __ fabs_d(dest->as_double_reg(), value->as_double_reg()); break; ++ case lir_sqrt: __ fsqrt_d(dest->as_double_reg(), value->as_double_reg()); break; ++ default: ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) { ++ assert(left->is_single_cpu() || left->is_double_cpu(), "expect single or double register"); ++ Register Rleft = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); ++ if (dst->is_single_cpu()) { ++ Register Rdst = dst->as_register(); ++ if (right->is_constant()) { ++ int right_const = right->as_jint(); ++ if (Assembler::is_simm12(right_const)) { ++ logic_op_imm(Rdst, Rleft, right_const, code); ++ __ sign_extend(Rdst, Rdst, 32); ++ } else { ++ __ mv(t0, right_const); ++ logic_op_reg32(Rdst, Rleft, t0, code); ++ } ++ } else { ++ Register Rright = right->is_single_cpu() ? right->as_register() : right->as_register_lo(); ++ logic_op_reg32(Rdst, Rleft, Rright, code); ++ } ++ } else { ++ Register Rdst = dst->as_register_lo(); ++ if (right->is_constant()) { ++ long right_const = right->as_jlong(); ++ if (Assembler::is_simm12(right_const)) { ++ logic_op_imm(Rdst, Rleft, right_const, code); ++ } else { ++ __ mv(t0, right_const); ++ logic_op_reg(Rdst, Rleft, t0, code); ++ } ++ } else { ++ Register Rright = right->is_single_cpu() ? right->as_register() : right->as_register_lo(); ++ logic_op_reg(Rdst, Rleft, Rright, code); ++ } ++ } ++} ++ ++void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr src, LIR_Opr result, LIR_Op2* op) { ++ ShouldNotCallThis(); ++} ++ ++void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op) { ++ if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) { ++ bool is_unordered_less = (code == lir_ucmp_fd2i); ++ if (left->is_single_fpu()) { ++ __ float_cmp(true, is_unordered_less ? -1 : 1, ++ left->as_float_reg(), right->as_float_reg(), dst->as_register()); ++ } else if (left->is_double_fpu()) { ++ __ float_cmp(false, is_unordered_less ? -1 : 1, ++ left->as_double_reg(), right->as_double_reg(), dst->as_register()); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } else if (code == lir_cmp_l2i) { ++ __ cmp_l2i(dst->as_register(), left->as_register_lo(), right->as_register_lo()); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::align_call(LIR_Code code) { ++ // With RVC a call instruction may get 2-byte aligned. ++ // The address of the call instruction needs to be 4-byte aligned to ++ // ensure that it does not span a cache line so that it can be patched. ++ __ align(NativeInstruction::instruction_size); ++} ++ ++void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { ++ address call = __ trampoline_call(Address(op->addr(), rtype)); ++ if (call == NULL) { ++ bailout("trampoline stub overflow"); ++ return; ++ } ++ add_call_info(code_offset(), op->info()); ++} ++ ++void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { ++ address call = __ ic_call(op->addr()); ++ if (call == NULL) { ++ bailout("trampoline stub overflow"); ++ return; ++ } ++ add_call_info(code_offset(), op->info()); ++} ++ ++void LIR_Assembler::emit_static_call_stub() { ++ address call_pc = __ pc(); ++ MacroAssembler::assert_alignment(call_pc); ++ address stub = __ start_a_stub(call_stub_size()); ++ if (stub == NULL) { ++ bailout("static call stub overflow"); ++ return; ++ } ++ ++ int start = __ offset(); ++ ++ __ relocate(static_stub_Relocation::spec(call_pc)); ++ __ emit_static_call_stub(); ++ ++ assert(__ offset() - start + CompiledStaticCall::to_trampoline_stub_size() ++ <= call_stub_size(), "stub too big"); ++ __ end_a_stub(); ++} ++ ++void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { ++ assert(exceptionOop->as_register() == x10, "must match"); ++ assert(exceptionPC->as_register() == x13, "must match"); ++ ++ // exception object is not added to oop map by LinearScan ++ // (LinearScan assumes that no oops are in fixed registers) ++ info->add_register_oop(exceptionOop); ++ Runtime1::StubID unwind_id; ++ ++ // get current pc information ++ // pc is only needed if the method has an exception handler, the unwind code does not need it. ++ if (compilation()->debug_info_recorder()->last_pc_offset() == __ offset()) { ++ // As no instructions have been generated yet for this LIR node it's ++ // possible that an oop map already exists for the current offset. ++ // In that case insert an dummy NOP here to ensure all oop map PCs ++ // are unique. See JDK-8237483. ++ __ nop(); ++ } ++ int pc_for_athrow_offset = __ offset(); ++ InternalAddress pc_for_athrow(__ pc()); ++ __ relocate(pc_for_athrow.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(exceptionPC->as_register(), pc_for_athrow, offset); ++ __ addi(exceptionPC->as_register(), exceptionPC->as_register(), offset); ++ }); ++ add_call_info(pc_for_athrow_offset, info); // for exception handler ++ ++ __ verify_not_null_oop(x10); ++ // search an exception handler (x10: exception oop, x13: throwing pc) ++ if (compilation()->has_fpu_code()) { ++ unwind_id = Runtime1::handle_exception_id; ++ } else { ++ unwind_id = Runtime1::handle_exception_nofpu_id; ++ } ++ __ far_call(RuntimeAddress(Runtime1::entry_for(unwind_id))); ++ __ nop(); ++} ++ ++void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) { ++ assert(exceptionOop->as_register() == x10, "must match"); ++ __ j(_unwind_handler_entry); ++} ++ ++void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { ++ Register left_reg = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); ++ Register dest_reg = dest->is_single_cpu() ? dest->as_register() : dest->as_register_lo(); ++ Register count_reg = count->as_register(); ++ if (dest->is_single_cpu()) { ++ assert (dest->type() == T_INT, "unexpected result type"); ++ assert (left->type() == T_INT, "unexpected left type"); ++ __ andi(t0, count_reg, 31); // should not shift more than 31 bits ++ switch (code) { ++ case lir_shl: __ sllw(dest_reg, left_reg, t0); break; ++ case lir_shr: __ sraw(dest_reg, left_reg, t0); break; ++ case lir_ushr: __ srlw(dest_reg, left_reg, t0); break; ++ default: ShouldNotReachHere(); ++ } ++ } else if (dest->is_double_cpu()) { ++ __ andi(t0, count_reg, 63); // should not shift more than 63 bits ++ switch (code) { ++ case lir_shl: __ sll(dest_reg, left_reg, t0); break; ++ case lir_shr: __ sra(dest_reg, left_reg, t0); break; ++ case lir_ushr: __ srl(dest_reg, left_reg, t0); break; ++ default: ShouldNotReachHere(); ++ } ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) { ++ Register left_reg = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); ++ Register dest_reg = dest->is_single_cpu() ? dest->as_register() : dest->as_register_lo(); ++ if (dest->is_single_cpu()) { ++ assert (dest->type() == T_INT, "unexpected result type"); ++ assert (left->type() == T_INT, "unexpected left type"); ++ count &= 0x1f; ++ if (count != 0) { ++ switch (code) { ++ case lir_shl: __ slliw(dest_reg, left_reg, count); break; ++ case lir_shr: __ sraiw(dest_reg, left_reg, count); break; ++ case lir_ushr: __ srliw(dest_reg, left_reg, count); break; ++ default: ShouldNotReachHere(); ++ } ++ } else { ++ move_regs(left_reg, dest_reg); ++ } ++ } else if (dest->is_double_cpu()) { ++ count &= 0x3f; ++ if (count != 0) { ++ switch (code) { ++ case lir_shl: __ slli(dest_reg, left_reg, count); break; ++ case lir_shr: __ srai(dest_reg, left_reg, count); break; ++ case lir_ushr: __ srli(dest_reg, left_reg, count); break; ++ default: ShouldNotReachHere(); ++ } ++ } else { ++ move_regs(left->as_register_lo(), dest->as_register_lo()); ++ } ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::emit_lock(LIR_OpLock* op) { ++ 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(); ++ if (!UseFastLocking) { ++ __ j(*op->stub()->entry()); ++ } else if (op->code() == lir_lock) { ++ Register tmp = noreg; ++ if (UseBiasedLocking) { ++ tmp = op->scratch_opr()->as_register(); ++ } ++ 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, tmp, *op->stub()->entry()); ++ if (op->info() != NULL) { ++ 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()); ++ } else { ++ Unimplemented(); ++ } ++ __ bind(*op->stub()->continuation()); ++} ++ ++void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { ++ ciMethod* method = op->profiled_method(); ++ int bci = op->profiled_bci(); ++ ++ // Update counter for all call types ++ ciMethodData* md = method->method_data_or_null(); ++ guarantee(md != NULL, "Sanity"); ++ ciProfileData* data = md->bci_to_data(bci); ++ assert(data != NULL && data->is_CounterData(), "need CounterData for calls"); ++ assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); ++ Register mdo = op->mdo()->as_register(); ++ __ mov_metadata(mdo, md->constant_encoding()); ++ Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); ++ // Perform additional virtual call profiling for invokevirtual and ++ // invokeinterface bytecodes ++ if (op->should_profile_receiver_type()) { ++ assert(op->recv()->is_single_cpu(), "recv must be allocated"); ++ Register recv = op->recv()->as_register(); ++ assert_different_registers(mdo, recv); ++ assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); ++ ciKlass* known_klass = op->known_holder(); ++ if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { ++ // We know the type that will be seen at this call site; we can ++ // statically update the MethodData* rather than needing to do ++ // dynamic tests on the receiver type ++ // NOTE: we should probably put a lock around this search to ++ // avoid collisions by concurrent compilations ++ ciVirtualCallData* vc_data = (ciVirtualCallData*) data; ++ uint i; ++ for (i = 0; i < VirtualCallData::row_limit(); i++) { ++ ciKlass* receiver = vc_data->receiver(i); ++ if (known_klass->equals(receiver)) { ++ Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); ++ __ increment(data_addr, DataLayout::counter_increment); ++ return; ++ } ++ } ++ ++ // Receiver type not found in profile data; select an empty slot ++ // Note that this is less efficient than it should be because it ++ // always does a write to the receiver part of the ++ // VirtualCallData rather than just the first time ++ for (i = 0; i < VirtualCallData::row_limit(); i++) { ++ ciKlass* receiver = vc_data->receiver(i); ++ if (receiver == NULL) { ++ Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); ++ __ mov_metadata(t1, known_klass->constant_encoding()); ++ __ sd(t1, recv_addr); ++ Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); ++ __ increment(data_addr, DataLayout::counter_increment); ++ return; ++ } ++ } ++ } else { ++ __ load_klass(recv, recv); ++ Label update_done; ++ type_profile_helper(mdo, md, data, recv, &update_done); ++ // Receiver did not match any saved receiver and there is no empty row for it. ++ // Increment total counter to indicate polymorphic case. ++ __ increment(counter_addr, DataLayout::counter_increment); ++ ++ __ bind(update_done); ++ } ++ } else { ++ // Static call ++ __ increment(counter_addr, DataLayout::counter_increment); ++ } ++} ++ ++void LIR_Assembler::emit_delay(LIR_OpDelay*) { Unimplemented(); } ++ ++void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { ++ __ la(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); ++} ++ ++void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) { Unimplemented(); } ++ ++void LIR_Assembler::check_conflict(ciKlass* exact_klass, intptr_t current_klass, ++ Register tmp, Label &next, Label &none, ++ Address mdo_addr) { ++ if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { ++ if (exact_klass != NULL) { ++ __ mov_metadata(tmp, exact_klass->constant_encoding()); ++ } else { ++ __ load_klass(tmp, tmp); ++ } ++ ++ __ ld(t1, mdo_addr); ++ __ xorr(tmp, tmp, t1); ++ __ andi(t0, tmp, TypeEntries::type_klass_mask); ++ // klass seen before, nothing to do. The unknown bit may have been ++ // set already but no need to check. ++ __ beqz(t0, next); ++ ++ // already unknown. Nothing to do anymore. ++ __ test_bit(t0, tmp, exact_log2(TypeEntries::type_unknown)); ++ __ bnez(t0, next); ++ ++ if (TypeEntries::is_type_none(current_klass)) { ++ __ beqz(t1, none); ++ __ mv(t0, (u1)TypeEntries::null_seen); ++ __ beq(t0, t1, none); ++ // There is a chance that the checks above (re-reading profiling ++ // data from memory) fail if another thread has just set the ++ // profiling to this obj's klass ++ __ membar(MacroAssembler::LoadLoad); ++ __ ld(t1, mdo_addr); ++ __ xorr(tmp, tmp, t1); ++ __ andi(t0, tmp, TypeEntries::type_klass_mask); ++ __ beqz(t0, next); ++ } ++ } else { ++ assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && ++ ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); ++ ++ __ ld(tmp, mdo_addr); ++ // already unknown. Nothing to do anymore. ++ __ test_bit(t0, tmp, exact_log2(TypeEntries::type_unknown)); ++ __ bnez(t0, next); ++ } ++ ++ // different than before. Cannot keep accurate profile. ++ __ ld(t1, mdo_addr); ++ __ ori(t1, t1, TypeEntries::type_unknown); ++ __ sd(t1, mdo_addr); ++ ++ if (TypeEntries::is_type_none(current_klass)) { ++ __ j(next); ++ ++ __ bind(none); ++ // first time here. Set profile type. ++ __ sd(tmp, mdo_addr); ++ } ++} ++ ++void LIR_Assembler::check_no_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp, ++ Address mdo_addr, Label &next) { ++ // There's a single possible klass at this profile point ++ assert(exact_klass != NULL, "should be"); ++ if (TypeEntries::is_type_none(current_klass)) { ++ __ mov_metadata(tmp, exact_klass->constant_encoding()); ++ __ ld(t1, mdo_addr); ++ __ xorr(tmp, tmp, t1); ++ __ andi(t0, tmp, TypeEntries::type_klass_mask); ++ __ beqz(t0, next); ++#ifdef ASSERT ++ { ++ Label ok; ++ __ ld(t0, mdo_addr); ++ __ beqz(t0, ok); ++ __ mv(t1, (u1)TypeEntries::null_seen); ++ __ beq(t0, t1, ok); ++ // may have been set by another thread ++ __ membar(MacroAssembler::LoadLoad); ++ __ mov_metadata(t0, exact_klass->constant_encoding()); ++ __ ld(t1, mdo_addr); ++ __ xorr(t1, t0, t1); ++ __ andi(t1, t1, TypeEntries::type_mask); ++ __ beqz(t1, ok); ++ ++ __ stop("unexpected profiling mismatch"); ++ __ bind(ok); ++ } ++#endif ++ // first time here. Set profile type. ++ __ sd(tmp, mdo_addr); ++ } else { ++ assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && ++ ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); ++ ++ __ ld(tmp, mdo_addr); ++ // already unknown. Nothing to do anymore. ++ __ test_bit(t0, tmp, exact_log2(TypeEntries::type_unknown)); ++ __ bnez(t0, next); ++ ++ __ ori(tmp, tmp, TypeEntries::type_unknown); ++ __ sd(tmp, mdo_addr); ++ } ++} ++ ++void LIR_Assembler::check_null(Register tmp, Label &update, intptr_t current_klass, ++ Address mdo_addr, bool do_update, Label &next) { ++ __ bnez(tmp, update); ++ if (!TypeEntries::was_null_seen(current_klass)) { ++ __ ld(t1, mdo_addr); ++ __ ori(t1, t1, TypeEntries::null_seen); ++ __ sd(t1, mdo_addr); ++ } ++ if (do_update) { ++ __ j(next); ++ } ++} ++ ++void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { ++ COMMENT("emit_profile_type {"); ++ Register obj = op->obj()->as_register(); ++ Register tmp = op->tmp()->as_pointer_register(); ++ Address mdo_addr = as_Address(op->mdp()->as_address_ptr()); ++ ciKlass* exact_klass = op->exact_klass(); ++ intptr_t current_klass = op->current_klass(); ++ bool not_null = op->not_null(); ++ bool no_conflict = op->no_conflict(); ++ ++ Label update, next, none; ++ ++ bool do_null = !not_null; ++ bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; ++ bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; ++ ++ assert(do_null || do_update, "why are we here?"); ++ assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); ++ assert_different_registers(tmp, t0, t1, mdo_addr.base()); ++ ++ __ verify_oop(obj); ++ ++ if (tmp != obj) { ++ __ mv(tmp, obj); ++ } ++ if (do_null) { ++ check_null(tmp, update, current_klass, mdo_addr, do_update, next); ++#ifdef ASSERT ++ } else { ++ __ bnez(tmp, update); ++ __ stop("unexpected null obj"); ++#endif ++ } ++ ++ __ bind(update); ++ ++ if (do_update) { ++#ifdef ASSERT ++ if (exact_klass != NULL) { ++ check_exact_klass(tmp, exact_klass); ++ } ++#endif ++ if (!no_conflict) { ++ check_conflict(exact_klass, current_klass, tmp, next, none, mdo_addr); ++ } else { ++ check_no_conflict(exact_klass, current_klass, tmp, mdo_addr, next); ++ } ++ ++ __ bind(next); ++ } ++ COMMENT("} emit_profile_type"); ++} ++ ++void LIR_Assembler::align_backward_branch_target() { } ++ ++void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) { ++ // tmp must be unused ++ assert(tmp->is_illegal(), "wasting a register if tmp is allocated"); ++ ++ if (left->is_single_cpu()) { ++ assert(dest->is_single_cpu(), "expect single result reg"); ++ __ negw(dest->as_register(), left->as_register()); ++ } else if (left->is_double_cpu()) { ++ assert(dest->is_double_cpu(), "expect double result reg"); ++ __ neg(dest->as_register_lo(), left->as_register_lo()); ++ } else if (left->is_single_fpu()) { ++ assert(dest->is_single_fpu(), "expect single float result reg"); ++ __ fneg_s(dest->as_float_reg(), left->as_float_reg()); ++ } else { ++ assert(left->is_double_fpu(), "expect double float operand reg"); ++ assert(dest->is_double_fpu(), "expect double float result reg"); ++ __ fneg_d(dest->as_double_reg(), left->as_double_reg()); ++ } ++} ++ ++ ++void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { ++ if (patch_code != lir_patch_none) { ++ deoptimize_trap(info); ++ return; ++ } ++ ++ LIR_Address* adr = addr->as_address_ptr(); ++ Register dst = dest->as_register_lo(); ++ ++ assert_different_registers(dst, t0); ++ if (adr->base()->is_valid() && dst == adr->base()->as_pointer_register() && (!adr->index()->is_cpu_register())) { ++ int scale = adr->scale(); ++ intptr_t offset = adr->disp(); ++ LIR_Opr index_op = adr->index(); ++ if (index_op->is_constant()) { ++ offset += ((intptr_t)index_op->as_constant_ptr()->as_jint()) << scale; ++ } ++ ++ if (!Assembler::is_simm12(offset)) { ++ __ la(t0, as_Address(adr)); ++ __ mv(dst, t0); ++ return; ++ } ++ } ++ ++ __ la(dst, as_Address(adr)); ++} ++ ++ ++void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) { ++ assert(!tmp->is_valid(), "don't need temporary"); ++ ++ CodeBlob *cb = CodeCache::find_blob(dest); ++ if (cb != NULL) { ++ __ far_call(RuntimeAddress(dest)); ++ } else { ++ RuntimeAddress target(dest); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ } ++ ++ if (info != NULL) { ++ add_call_info_here(info); ++ } ++} ++ ++void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) { ++ if (dest->is_address() || src->is_address()) { ++ move_op(src, dest, type, lir_patch_none, info, /* pop_fpu_stack */ false, /* wide */ false, /* unaligned */ false); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++#ifdef ASSERT ++// emit run-time assertion ++void LIR_Assembler::emit_assert(LIR_OpAssert* op) { ++ assert(op->code() == lir_assert, "must be"); ++ ++ Label ok; ++ if (op->in_opr1()->is_valid()) { ++ assert(op->in_opr2()->is_valid(), "both operands must be valid"); ++ bool is_unordered = false; ++ LIR_Condition cond = op->condition(); ++ emit_branch(cond, op->in_opr1(), op->in_opr2(), ok, /* is_far */ false, ++ /* is_unordered */(cond == lir_cond_greaterEqual || cond == lir_cond_greater) ? false : true); ++ } else { ++ assert(op->in_opr2()->is_illegal(), "both operands must be illegal"); ++ assert(op->condition() == lir_cond_always, "no other conditions allowed"); ++ } ++ ++ if (op->halt()) { ++ const char* str = __ code_string(op->msg()); ++ __ stop(str); ++ } else { ++ breakpoint(); ++ } ++ __ bind(ok); ++} ++#endif ++ ++#ifndef PRODUCT ++#define COMMENT(x) do { __ block_comment(x); } while (0) ++#else ++#define COMMENT(x) ++#endif ++ ++void LIR_Assembler::membar() { ++ COMMENT("membar"); ++ __ membar(MacroAssembler::AnyAny); ++} ++ ++void LIR_Assembler::membar_acquire() { ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++} ++ ++void LIR_Assembler::membar_release() { ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++} ++ ++void LIR_Assembler::membar_loadload() { ++ __ membar(MacroAssembler::LoadLoad); ++} ++ ++void LIR_Assembler::membar_storestore() { ++ __ membar(MacroAssembler::StoreStore); ++} ++ ++void LIR_Assembler::membar_loadstore() { __ membar(MacroAssembler::LoadStore); } ++ ++void LIR_Assembler::membar_storeload() { __ membar(MacroAssembler::StoreLoad); } ++ ++void LIR_Assembler::on_spin_wait() { ++ Unimplemented(); ++} ++ ++void LIR_Assembler::get_thread(LIR_Opr result_reg) { ++ __ mv(result_reg->as_register(), xthread); ++} ++ ++void LIR_Assembler::peephole(LIR_List *lir) {} ++ ++void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp_op) { ++ Address addr = as_Address(src->as_address_ptr()); ++ BasicType type = src->type(); ++ bool is_oop = is_reference_type(type); ++ ++ get_op(type); ++ ++ switch (code) { ++ case lir_xadd: ++ { ++ RegisterOrConstant inc; ++ Register tmp = as_reg(tmp_op); ++ Register dst = as_reg(dest); ++ if (data->is_constant()) { ++ inc = RegisterOrConstant(as_long(data)); ++ assert_different_registers(dst, addr.base(), tmp); ++ assert_different_registers(tmp, t0); ++ } else { ++ inc = RegisterOrConstant(as_reg(data)); ++ assert_different_registers(inc.as_register(), dst, addr.base(), tmp); ++ } ++ __ la(tmp, addr); ++ (_masm->*add)(dst, inc, tmp); ++ break; ++ } ++ case lir_xchg: ++ { ++ Register tmp = tmp_op->as_register(); ++ Register obj = as_reg(data); ++ Register dst = as_reg(dest); ++ if (is_oop && UseCompressedOops) { ++ __ encode_heap_oop(t0, obj); ++ obj = t0; ++ } ++ assert_different_registers(obj, addr.base(), tmp, dst); ++ __ la(tmp, addr); ++ (_masm->*xchg)(dst, obj, tmp); ++ if (is_oop && UseCompressedOops) { ++ __ decode_heap_oop(dst); ++ } ++ } ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ __ membar(MacroAssembler::AnyAny); ++} ++ ++int LIR_Assembler::array_element_size(BasicType type) const { ++ int elem_size = type2aelembytes(type); ++ return exact_log2(elem_size); ++} ++ ++// helper functions which checks for overflow and sets bailout if it ++// occurs. Always returns a valid embeddable pointer but in the ++// bailout case the pointer won't be to unique storage. ++address LIR_Assembler::float_constant(float f) { ++ address const_addr = __ float_constant(f); ++ if (const_addr == NULL) { ++ bailout("const section overflow"); ++ return __ code()->consts()->start(); ++ } else { ++ return const_addr; ++ } ++} ++ ++address LIR_Assembler::double_constant(double d) { ++ address const_addr = __ double_constant(d); ++ if (const_addr == NULL) { ++ bailout("const section overflow"); ++ return __ code()->consts()->start(); ++ } else { ++ return const_addr; ++ } ++} ++ ++address LIR_Assembler::int_constant(jlong n) { ++ address const_addr = __ long_constant(n); ++ if (const_addr == NULL) { ++ bailout("const section overflow"); ++ return __ code()->consts()->start(); ++ } else { ++ return const_addr; ++ } ++} ++ ++void LIR_Assembler::casw(Register addr, Register newval, Register cmpval) { ++ __ cmpxchg(addr, cmpval, newval, Assembler::int32, Assembler::aq /* acquire */, ++ Assembler::rl /* release */, t0, true /* result as bool */); ++ __ seqz(t0, t0); // cmpxchg not equal, set t0 to 1 ++ __ membar(MacroAssembler::AnyAny); ++} ++ ++void LIR_Assembler::caswu(Register addr, Register newval, Register cmpval) { ++ __ cmpxchg(addr, cmpval, newval, Assembler::uint32, Assembler::aq /* acquire */, ++ Assembler::rl /* release */, t0, true /* result as bool */); ++ __ seqz(t0, t0); // cmpxchg not equal, set t0 to 1 ++ __ membar(MacroAssembler::AnyAny); ++} ++ ++void LIR_Assembler::casl(Register addr, Register newval, Register cmpval) { ++ __ cmpxchg(addr, cmpval, newval, Assembler::int64, Assembler::aq /* acquire */, ++ Assembler::rl /* release */, t0, true /* result as bool */); ++ __ seqz(t0, t0); // cmpxchg not equal, set t0 to 1 ++ __ membar(MacroAssembler::AnyAny); ++} ++ ++void LIR_Assembler::deoptimize_trap(CodeEmitInfo *info) { ++ address target = NULL; ++ ++ switch (patching_id(info)) { ++ case PatchingStub::access_field_id: ++ target = Runtime1::entry_for(Runtime1::access_field_patching_id); ++ break; ++ case PatchingStub::load_klass_id: ++ target = Runtime1::entry_for(Runtime1::load_klass_patching_id); ++ break; ++ case PatchingStub::load_mirror_id: ++ target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); ++ break; ++ case PatchingStub::load_appendix_id: ++ target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); ++ break; ++ default: ShouldNotReachHere(); ++ } ++ ++ __ far_call(RuntimeAddress(target)); ++ add_call_info_here(info); ++} ++ ++void LIR_Assembler::check_exact_klass(Register tmp, ciKlass* exact_klass) { ++ Label ok; ++ __ load_klass(tmp, tmp); ++ __ mov_metadata(t0, exact_klass->constant_encoding()); ++ __ beq(tmp, t0, ok); ++ __ stop("exact klass and actual klass differ"); ++ __ bind(ok); ++} ++ ++void LIR_Assembler::get_op(BasicType type) { ++ switch (type) { ++ case T_INT: ++ xchg = &MacroAssembler::atomic_xchgalw; ++ add = &MacroAssembler::atomic_addalw; ++ break; ++ case T_LONG: ++ xchg = &MacroAssembler::atomic_xchgal; ++ add = &MacroAssembler::atomic_addal; ++ break; ++ case T_OBJECT: ++ case T_ARRAY: ++ if (UseCompressedOops) { ++ xchg = &MacroAssembler::atomic_xchgalwu; ++ add = &MacroAssembler::atomic_addalw; ++ } else { ++ xchg = &MacroAssembler::atomic_xchgal; ++ add = &MacroAssembler::atomic_addal; ++ } ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++// emit_opTypeCheck sub functions ++void LIR_Assembler::typecheck_lir_store(LIR_OpTypeCheck* op, bool should_profile) { ++ Register value = op->object()->as_register(); ++ Register array = op->array()->as_register(); ++ Register k_RInfo = op->tmp1()->as_register(); ++ Register klass_RInfo = op->tmp2()->as_register(); ++ Register Rtmp1 = op->tmp3()->as_register(); ++ ++ CodeStub* stub = op->stub(); ++ ++ // check if it needs to be profiled ++ ciMethodData* md = NULL; ++ ciProfileData* data = NULL; ++ ++ if (should_profile) { ++ data_check(op, &md, &data); ++ } ++ Label profile_cast_success, profile_cast_failure, done; ++ Label *success_target = should_profile ? &profile_cast_success : &done; ++ Label *failure_target = should_profile ? &profile_cast_failure : stub->entry(); ++ ++ if (should_profile) { ++ profile_object(md, data, value, klass_RInfo, &done); ++ } else { ++ __ beqz(value, done); ++ } ++ ++ add_debug_info_for_null_check_here(op->info_for_exception()); ++ __ load_klass(k_RInfo, array); ++ __ load_klass(klass_RInfo, value); ++ ++ lir_store_slowcheck(k_RInfo, klass_RInfo, Rtmp1, success_target, failure_target); ++ ++ // fall through to the success case ++ if (should_profile) { ++ Register mdo = klass_RInfo; ++ Register recv = k_RInfo; ++ __ bind(profile_cast_success); ++ __ mov_metadata(mdo, md->constant_encoding()); ++ __ load_klass(recv, value); ++ type_profile_helper(mdo, md, data, recv, &done); ++ __ j(done); ++ ++ __ bind(profile_cast_failure); ++ __ mov_metadata(mdo, md->constant_encoding()); ++ Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); ++ __ ld(t1, counter_addr); ++ __ addi(t1, t1, -DataLayout::counter_increment); ++ __ sd(t1, counter_addr); ++ __ j(*stub->entry()); ++ } ++ ++ __ bind(done); ++} ++ ++void LIR_Assembler::type_profile(Register obj, ciMethodData* md, Register klass_RInfo, Register k_RInfo, ++ ciProfileData* data, Label* success, Label* failure, ++ Label& profile_cast_success, Label& profile_cast_failure) { ++ Register mdo = klass_RInfo; ++ Register recv = k_RInfo; ++ __ bind(profile_cast_success); ++ __ mov_metadata(mdo, md->constant_encoding()); ++ __ load_klass(recv, obj); ++ Label update_done; ++ type_profile_helper(mdo, md, data, recv, success); ++ __ j(*success); ++ ++ __ bind(profile_cast_failure); ++ __ mov_metadata(mdo, md->constant_encoding()); ++ Address counter_addr = __ form_address(t1, mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); ++ __ ld(t0, counter_addr); ++ __ addi(t0, t0, -DataLayout::counter_increment); ++ __ sd(t0, counter_addr); ++ __ j(*failure); ++} ++ ++void LIR_Assembler::lir_store_slowcheck(Register k_RInfo, Register klass_RInfo, Register Rtmp1, ++ Label* success_target, Label* failure_target) { ++ // get instance klass (it's already uncompressed) ++ __ ld(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset())); ++ // perform the fast part of the checking logic ++ __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); ++ // call out-of-line instance of __ check_klass_subtype_slow_path(...) ++ __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo ++ __ sd(klass_RInfo, Address(sp, wordSize)); // sub klass ++ __ sd(k_RInfo, Address(sp, 0)); // super klass ++ __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); ++ // load result to k_RInfo ++ __ ld(k_RInfo, Address(sp, 0)); ++ __ addi(sp, sp, 2 * wordSize); // 2: pop out k_RInfo and klass_RInfo ++ // result is a boolean ++ __ beqz(k_RInfo, *failure_target, /* is_far */ true); ++} ++ ++void LIR_Assembler::const2reg_helper(LIR_Opr src) { ++ switch (src->as_constant_ptr()->type()) { ++ case T_INT: ++ case T_ADDRESS: ++ case T_OBJECT: ++ case T_ARRAY: ++ case T_METADATA: ++ const2reg(src, FrameMap::t0_opr, lir_patch_none, NULL); ++ break; ++ case T_LONG: ++ const2reg(src, FrameMap::t0_long_opr, lir_patch_none, NULL); ++ break; ++ case T_FLOAT: ++ case T_DOUBLE: ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::logic_op_reg32(Register dst, Register left, Register right, LIR_Code code) { ++ switch (code) { ++ case lir_logic_and: __ andrw(dst, left, right); break; ++ case lir_logic_or: __ orrw (dst, left, right); break; ++ case lir_logic_xor: __ xorrw(dst, left, right); break; ++ default: ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::logic_op_reg(Register dst, Register left, Register right, LIR_Code code) { ++ switch (code) { ++ case lir_logic_and: __ andr(dst, left, right); break; ++ case lir_logic_or: __ orr (dst, left, right); break; ++ case lir_logic_xor: __ xorr(dst, left, right); break; ++ default: ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::logic_op_imm(Register dst, Register left, int right, LIR_Code code) { ++ switch (code) { ++ case lir_logic_and: __ andi(dst, left, right); break; ++ case lir_logic_or: __ ori (dst, left, right); break; ++ case lir_logic_xor: __ xori(dst, left, right); break; ++ default: ShouldNotReachHere(); ++ } ++} ++ ++void LIR_Assembler::store_parameter(Register r, int offset_from_rsp_in_words) { ++ assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); ++ int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; ++ assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); ++ __ sd(r, Address(sp, offset_from_rsp_in_bytes)); ++} ++ ++void LIR_Assembler::store_parameter(jint c, int offset_from_rsp_in_words) { ++ assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); ++ int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; ++ assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); ++ __ mv(t0, c); ++ __ sd(t0, Address(sp, offset_from_rsp_in_bytes)); ++} ++ ++#undef __ +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.hpp +@@ -0,0 +1,130 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP ++#define CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP ++ ++// ArrayCopyStub needs access to bailout ++friend class ArrayCopyStub; ++ ++private: ++ ++#include "c1_LIRAssembler_arith_riscv.hpp" ++#include "c1_LIRAssembler_arraycopy_riscv.hpp" ++ ++ int array_element_size(BasicType type) const; ++ ++ static Register as_reg(LIR_Opr op) { ++ return op->is_double_cpu() ? op->as_register_lo() : op->as_register(); ++ } ++ ++ Address as_Address(LIR_Address* addr, Register tmp); ++ ++ // helper functions which checks for overflow and sets bailout if it ++ // occurs. Always returns a valid embeddable pointer but in the ++ // bailout case the pointer won't be to unique storage. ++ address float_constant(float f); ++ address double_constant(double d); ++ address int_constant(jlong n); ++ ++ // Ensure we have a valid Address (base + offset) to a stack-slot. ++ Address stack_slot_address(int index, uint shift, int adjust = 0); ++ ++ // Record the type of the receiver in ReceiverTypeData ++ void type_profile_helper(Register mdo, ++ ciMethodData *md, ciProfileData *data, ++ Register recv, Label* update_done); ++ ++ void casw(Register addr, Register newval, Register cmpval); ++ void caswu(Register addr, Register newval, Register cmpval); ++ void casl(Register addr, Register newval, Register cmpval); ++ ++ void poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info = NULL); ++ ++ void deoptimize_trap(CodeEmitInfo *info); ++ ++ enum { ++ // See emit_static_call_stub for detail ++ // CompiledStaticCall::to_interp_stub_size() (14) + CompiledStaticCall::to_trampoline_stub_size() (1 + 3 + address) ++ _call_stub_size = 14 * NativeInstruction::instruction_size + ++ (NativeInstruction::instruction_size + NativeCallTrampolineStub::instruction_size), ++ // See emit_exception_handler for detail ++ // verify_not_null_oop + far_call + should_not_reach_here + invalidate_registers(DEBUG_ONLY) ++ _exception_handler_size = DEBUG_ONLY(584) NOT_DEBUG(548), // or smaller ++ // See emit_deopt_handler for detail ++ // auipc (1) + far_jump (6 or 2) ++ _deopt_handler_size = 1 * NativeInstruction::instruction_size + ++ 6 * NativeInstruction::instruction_size // or smaller ++ }; ++ ++ void check_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp, ++ Label &next, Label &none, Address mdo_addr); ++ void check_no_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp, Address mdo_addr, Label &next); ++ ++ void check_exact_klass(Register tmp, ciKlass* exact_klass); ++ ++ void check_null(Register tmp, Label &update, intptr_t current_klass, Address mdo_addr, bool do_update, Label &next); ++ ++ void (MacroAssembler::*add)(Register prev, RegisterOrConstant incr, Register addr); ++ void (MacroAssembler::*xchg)(Register prev, Register newv, Register addr); ++ ++ void get_op(BasicType type); ++ ++ // emit_typecheck_helper sub functions ++ void data_check(LIR_OpTypeCheck *op, ciMethodData **md, ciProfileData **data); ++ void typecheck_helper_slowcheck(ciKlass* k, Register obj, Register Rtmp1, ++ Register k_RInfo, Register klass_RInfo, ++ Label* failure_target, Label* success_target); ++ void profile_object(ciMethodData* md, ciProfileData* data, Register obj, ++ Register klass_RInfo, Label* obj_is_null); ++ void typecheck_loaded(LIR_OpTypeCheck* op, ciKlass* k, Register k_RInfo); ++ ++ // emit_opTypeCheck sub functions ++ void typecheck_lir_store(LIR_OpTypeCheck* op, bool should_profile); ++ ++ void type_profile(Register obj, ciMethodData* md, Register klass_RInfo, Register k_RInfo, ++ ciProfileData* data, Label* success, Label* failure, ++ Label& profile_cast_success, Label& profile_cast_failure); ++ ++ void lir_store_slowcheck(Register k_RInfo, Register klass_RInfo, Register Rtmp1, ++ Label* success_target, Label* failure_target); ++ ++ void const2reg_helper(LIR_Opr src); ++ ++ void emit_branch(LIR_Condition cmp_flag, LIR_Opr cmp1, LIR_Opr cmp2, Label& label, bool is_far, bool is_unordered); ++ ++ void logic_op_reg32(Register dst, Register left, Register right, LIR_Code code); ++ void logic_op_reg(Register dst, Register left, Register right, LIR_Code code); ++ void logic_op_imm(Register dst, Register left, int right, LIR_Code code); ++ ++public: ++ ++ void emit_cmove(LIR_Op4* op); ++ ++ void store_parameter(Register r, int offset_from_rsp_in_words); ++ void store_parameter(jint c, int offset_from_rsp_in_words); ++ ++#endif // CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp +@@ -0,0 +1,1086 @@ ++/* ++ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "c1/c1_Compilation.hpp" ++#include "c1/c1_FrameMap.hpp" ++#include "c1/c1_Instruction.hpp" ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_LIRGenerator.hpp" ++#include "c1/c1_Runtime1.hpp" ++#include "c1/c1_ValueStack.hpp" ++#include "ci/ciArray.hpp" ++#include "ci/ciObjArrayKlass.hpp" ++#include "ci/ciTypeArrayKlass.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "utilities/powerOfTwo.hpp" ++#include "vmreg_riscv.inline.hpp" ++ ++#ifdef ASSERT ++#define __ gen()->lir(__FILE__, __LINE__)-> ++#else ++#define __ gen()->lir()-> ++#endif ++ ++// Item will be loaded into a byte register; Intel only ++void LIRItem::load_byte_item() { ++ load_item(); ++} ++ ++ ++void LIRItem::load_nonconstant() { ++ LIR_Opr r = value()->operand(); ++ if (r->is_constant()) { ++ _result = r; ++ } else { ++ load_item(); ++ } ++} ++ ++//-------------------------------------------------------------- ++// LIRGenerator ++//-------------------------------------------------------------- ++ ++ ++LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::r10_oop_opr; } ++LIR_Opr LIRGenerator::exceptionPcOpr() { return FrameMap::r13_opr; } ++LIR_Opr LIRGenerator::divInOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } ++LIR_Opr LIRGenerator::divOutOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } ++LIR_Opr LIRGenerator::remOutOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } ++LIR_Opr LIRGenerator::shiftCountOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } ++LIR_Opr LIRGenerator::syncLockOpr() { return new_register(T_INT); } ++LIR_Opr LIRGenerator::syncTempOpr() { return FrameMap::r10_opr; } ++LIR_Opr LIRGenerator::getThreadTemp() { return LIR_OprFact::illegalOpr; } ++ ++ ++LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { ++ LIR_Opr opr; ++ switch (type->tag()) { ++ case intTag: opr = FrameMap::r10_opr; break; ++ case objectTag: opr = FrameMap::r10_oop_opr; break; ++ case longTag: opr = FrameMap::long10_opr; break; ++ case floatTag: opr = FrameMap::fpu10_float_opr; break; ++ case doubleTag: opr = FrameMap::fpu10_double_opr; break; ++ ++ case addressTag: // fall through ++ default: ++ ShouldNotReachHere(); ++ return LIR_OprFact::illegalOpr; ++ } ++ ++ assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch"); ++ return opr; ++} ++ ++ ++LIR_Opr LIRGenerator::rlock_byte(BasicType type) { ++ LIR_Opr reg = new_register(T_INT); ++ set_vreg_flag(reg, LIRGenerator::byte_reg); ++ return reg; ++} ++ ++//--------- loading items into registers -------------------------------- ++ ++ ++bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { ++ if (v->type()->as_IntConstant() != NULL) { ++ return v->type()->as_IntConstant()->value() == 0; ++ } else if (v->type()->as_LongConstant() != NULL) { ++ return v->type()->as_LongConstant()->value() == 0; ++ } else if (v->type()->as_ObjectConstant() != NULL) { ++ return v->type()->as_ObjectConstant()->value()->is_null_object(); ++ } else if (v->type()->as_FloatConstant() != NULL) { ++ return jint_cast(v->type()->as_FloatConstant()->value()) == 0.0f; ++ } else if (v->type()->as_DoubleConstant() != NULL) { ++ return jlong_cast(v->type()->as_DoubleConstant()->value()) == 0.0; ++ } ++ return false; ++} ++ ++bool LIRGenerator::can_inline_as_constant(Value v) const { ++ if (v->type()->as_IntConstant() != NULL) { ++ int value = v->type()->as_IntConstant()->value(); ++ // "-value" must be defined for value may be used for sub ++ return Assembler::is_simm12(value) && Assembler::is_simm12(- value); ++ } else if (v->type()->as_ObjectConstant() != NULL) { ++ return v->type()->as_ObjectConstant()->value()->is_null_object(); ++ } else if (v->type()->as_LongConstant() != NULL) { ++ long value = v->type()->as_LongConstant()->value(); ++ // "-value" must be defined for value may be used for sub ++ return Assembler::is_simm12(value) && Assembler::is_simm12(- value); ++ } else if (v->type()->as_FloatConstant() != NULL) { ++ return v->type()->as_FloatConstant()->value() == 0.0f; ++ } else if (v->type()->as_DoubleConstant() != NULL) { ++ return v->type()->as_DoubleConstant()->value() == 0.0; ++ } ++ return false; ++} ++ ++bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { ++ if (c->as_constant() != NULL) { ++ long constant = 0; ++ switch (c->type()) { ++ case T_INT: constant = c->as_jint(); break; ++ case T_LONG: constant = c->as_jlong(); break; ++ default: return false; ++ } ++ // "-constant" must be defined for c may be used for sub ++ return Assembler::is_simm12(constant) && Assembler::is_simm12(- constant); ++ } ++ return false; ++} ++ ++LIR_Opr LIRGenerator::safepoint_poll_register() { ++ return LIR_OprFact::illegalOpr; ++} ++ ++LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, ++ int shift, int disp, BasicType type) { ++ assert(base->is_register(), "must be"); ++ ++ if (index->is_constant()) { ++ LIR_Const *constant = index->as_constant_ptr(); ++ jlong c; ++ if (constant->type() == T_INT) { ++ c = (jlong(index->as_jint()) << shift) + disp; ++ } else { ++ assert(constant->type() == T_LONG, "should be"); ++ c = (index->as_jlong() << shift) + disp; ++ } ++ if ((jlong)((jint)c) == c) { ++ return new LIR_Address(base, (jint)c, type); ++ } else { ++ LIR_Opr tmp = new_register(T_LONG); ++ __ move(index, tmp); ++ return new LIR_Address(base, tmp, type); ++ } ++ } ++ ++ return new LIR_Address(base, index, (LIR_Address::Scale)shift, disp, type); ++} ++ ++LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, ++ BasicType type) { ++ int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type); ++ int elem_size = type2aelembytes(type); ++ int shift = exact_log2(elem_size); ++ return generate_address(array_opr, index_opr, shift, offset_in_bytes, type); ++} ++ ++LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { ++ LIR_Opr r; ++ switch (type) { ++ case T_LONG: ++ r = LIR_OprFact::longConst(x); ++ break; ++ case T_INT: ++ r = LIR_OprFact::intConst(x); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ return r; ++} ++ ++void LIRGenerator::increment_counter(address counter, BasicType type, int step) { ++ LIR_Opr pointer = new_pointer_register(); ++ __ move(LIR_OprFact::intptrConst(counter), pointer); ++ LIR_Address* addr = new LIR_Address(pointer, type); ++ increment_counter(addr, step); ++} ++ ++void LIRGenerator::increment_counter(LIR_Address* addr, int step) { ++ LIR_Opr reg = new_register(addr->type()); ++ __ load(addr, reg); ++ __ add(reg, load_immediate(step, addr->type()), reg); ++ __ store(reg, addr); ++} ++ ++void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) { ++ LIR_Opr reg = new_register(T_INT); ++ __ load(generate_address(base, disp, T_INT), reg, info); ++ __ cmp(condition, reg, LIR_OprFact::intConst(c)); ++} ++ ++void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) { ++ LIR_Opr reg1 = new_register(T_INT); ++ __ load(generate_address(base, disp, type), reg1, info); ++ __ cmp(condition, reg, reg1); ++} ++ ++bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, jint c, LIR_Opr result, LIR_Opr tmp) { ++ if (tmp->is_valid() && c > 0 && c < max_jint) { ++ if (is_power_of_2(c - 1)) { ++ __ shift_left(left, exact_log2(c - 1), tmp); ++ __ add(tmp, left, result); ++ return true; ++ } else if (is_power_of_2(c + 1)) { ++ __ shift_left(left, exact_log2(c + 1), tmp); ++ __ sub(tmp, left, result); ++ return true; ++ } ++ } ++ return false; ++} ++ ++void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) { ++ BasicType type = item->type(); ++ __ store(item, new LIR_Address(FrameMap::sp_opr, in_bytes(offset_from_sp), type)); ++} ++ ++void LIRGenerator::array_store_check(LIR_Opr value, LIR_Opr array, CodeEmitInfo* store_check_info, ++ ciMethod* profiled_method, int profiled_bci) { ++ LIR_Opr tmp1 = new_register(objectType); ++ LIR_Opr tmp2 = new_register(objectType); ++ LIR_Opr tmp3 = new_register(objectType); ++ __ store_check(value, array, tmp1, tmp2, tmp3, store_check_info, profiled_method, profiled_bci); ++} ++ ++//---------------------------------------------------------------------- ++// visitor functions ++//---------------------------------------------------------------------- ++ ++void LIRGenerator::do_MonitorEnter(MonitorEnter* x) { ++ assert(x->is_pinned(), ""); ++ LIRItem obj(x->obj(), this); ++ obj.load_item(); ++ ++ set_no_result(x); ++ ++ // "lock" stores the address of the monitor stack slot, so this is not an oop ++ LIR_Opr lock = new_register(T_INT); ++ // Need a tmp register for biased locking ++ LIR_Opr tmp = LIR_OprFact::illegalOpr; ++ if (UseBiasedLocking) { ++ tmp = new_register(T_INT); ++ } ++ ++ CodeEmitInfo* info_for_exception = NULL; ++ if (x->needs_null_check()) { ++ info_for_exception = state_for(x); ++ } ++ // 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(), tmp, ++ x->monitor_no(), info_for_exception, info); ++} ++ ++void LIRGenerator::do_MonitorExit(MonitorExit* x) { ++ assert(x->is_pinned(), ""); ++ ++ LIRItem obj(x->obj(), this); ++ obj.dont_load_item(); ++ ++ LIR_Opr lock = new_register(T_INT); ++ LIR_Opr obj_temp = new_register(T_INT); ++ set_no_result(x); ++ monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no()); ++} ++ ++// neg ++void LIRGenerator::do_NegateOp(NegateOp* x) { ++ LIRItem from(x->x(), this); ++ from.load_item(); ++ LIR_Opr result = rlock_result(x); ++ __ negate(from.result(), result); ++} ++ ++// for _fadd, _fmul, _fsub, _fdiv, _frem ++// _dadd, _dmul, _dsub, _ddiv, _drem ++void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { ++ LIRItem left(x->x(), this); ++ LIRItem right(x->y(), this); ++ ++ if (x->op() == Bytecodes::_frem || x->op() == Bytecodes::_drem) { ++ ++ // float remainder is implemented as a direct call into the runtime ++ BasicTypeList signature(2); ++ if (x->op() == Bytecodes::_frem) { ++ signature.append(T_FLOAT); ++ signature.append(T_FLOAT); ++ } else { ++ signature.append(T_DOUBLE); ++ signature.append(T_DOUBLE); ++ } ++ CallingConvention* cc = frame_map()->c_calling_convention(&signature); ++ ++ const LIR_Opr result_reg = result_register_for(x->type()); ++ ++ left.load_item(); ++ __ move(left.result(), cc->at(0)); ++ right.load_item_force(cc->at(1)); ++ ++ address entry; ++ if (x->op() == Bytecodes::_frem) { ++ entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem); ++ } else { ++ entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem); ++ } ++ ++ LIR_Opr result = rlock_result(x); ++ __ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args()); ++ __ move(result_reg, result); ++ ++ return; ++ } ++ ++ if (!left.is_register()) { ++ left.load_item(); ++ } ++ // Always load right hand side. ++ right.load_item(); ++ ++ LIR_Opr reg = rlock(x); ++ arithmetic_op_fpu(x->op(), reg, left.result(), right.result()); ++ ++ set_result(x, round_item(reg)); ++} ++ ++// for _ladd, _lmul, _lsub, _ldiv, _lrem ++void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { ++ ++ // missing test if instr is commutative and if we should swap ++ LIRItem left(x->x(), this); ++ LIRItem right(x->y(), this); ++ ++ if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) { ++ ++ left.load_item(); ++ ++ bool need_zero_check = true; ++ if (right.is_constant()) { ++ jlong c = right.get_jlong_constant(); ++ // no need to do div-by-zero check if the divisor is a non-zero constant ++ if (c != 0) { need_zero_check = false; } ++ // do not load right if the divisor is a power-of-2 constant ++ if (c > 0 && is_power_of_2(c)) { ++ right.dont_load_item(); ++ } else { ++ right.load_item(); ++ } ++ } else { ++ right.load_item(); ++ } ++ if (need_zero_check) { ++ CodeEmitInfo* info = state_for(x); ++ __ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0)); ++ __ branch(lir_cond_equal, new DivByZeroStub(info)); ++ } ++ ++ rlock_result(x); ++ switch (x->op()) { ++ case Bytecodes::_lrem: ++ __ rem(left.result(), right.result(), x->operand()); ++ break; ++ case Bytecodes::_ldiv: ++ __ div(left.result(), right.result(), x->operand()); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ } else { ++ assert(x->op() == Bytecodes::_lmul || x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub, ++ "expect lmul, ladd or lsub"); ++ // add, sub, mul ++ left.load_item(); ++ if (!right.is_register()) { ++ if (x->op() == Bytecodes::_lmul || ++ !right.is_constant() || ++ (x->op() == Bytecodes::_ladd && ++ !Assembler::is_simm12(right.get_jlong_constant())) || ++ (x->op() == Bytecodes::_lsub && ++ !Assembler::is_simm12(-right.get_jlong_constant()))) { ++ right.load_item(); ++ } else { // add, sub ++ assert(x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub, "expected ladd or lsub"); ++ // don't load constants to save register ++ right.load_nonconstant(); ++ } ++ } ++ rlock_result(x); ++ arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL); ++ } ++} ++ ++// for: _iadd, _imul, _isub, _idiv, _irem ++void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { ++ ++ // Test if instr is commutative and if we should swap ++ LIRItem left(x->x(), this); ++ LIRItem right(x->y(), this); ++ LIRItem* left_arg = &left; ++ LIRItem* right_arg = &right; ++ if (x->is_commutative() && left.is_stack() && right.is_register()) { ++ // swap them if left is real stack (or cached) and right is real register(not cached) ++ left_arg = &right; ++ right_arg = &left; ++ } ++ left_arg->load_item(); ++ // do not need to load right, as we can handle stack and constants ++ if (x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem) { ++ ++ rlock_result(x); ++ ++ bool need_zero_check = true; ++ if (right.is_constant()) { ++ jint c = right.get_jint_constant(); ++ // no need to do div-by-zero check if the divisor is a non-zero constant ++ if (c != 0) { need_zero_check = false; } ++ // do not load right if the divisor is a power-of-2 constant ++ if (c > 0 && is_power_of_2(c)) { ++ right_arg->dont_load_item(); ++ } else { ++ right_arg->load_item(); ++ } ++ } else { ++ right_arg->load_item(); ++ } ++ if (need_zero_check) { ++ CodeEmitInfo* info = state_for(x); ++ __ cmp(lir_cond_equal, right_arg->result(), LIR_OprFact::longConst(0)); ++ __ branch(lir_cond_equal, new DivByZeroStub(info)); ++ } ++ ++ LIR_Opr ill = LIR_OprFact::illegalOpr; ++ if (x->op() == Bytecodes::_irem) { ++ __ irem(left_arg->result(), right_arg->result(), x->operand(), ill, NULL); ++ } else if (x->op() == Bytecodes::_idiv) { ++ __ idiv(left_arg->result(), right_arg->result(), x->operand(), ill, NULL); ++ } ++ ++ } else if (x->op() == Bytecodes::_iadd || x->op() == Bytecodes::_isub) { ++ if (right.is_constant() && ++ ((x->op() == Bytecodes::_iadd && !Assembler::is_simm12(right.get_jint_constant())) || ++ (x->op() == Bytecodes::_isub && !Assembler::is_simm12(-right.get_jint_constant())))) { ++ right.load_nonconstant(); ++ } else { ++ right.load_item(); ++ } ++ rlock_result(x); ++ arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), LIR_OprFact::illegalOpr); ++ } else { ++ assert (x->op() == Bytecodes::_imul, "expect imul"); ++ if (right.is_constant()) { ++ jint c = right.get_jint_constant(); ++ if (c > 0 && c < max_jint && (is_power_of_2(c) || is_power_of_2(c - 1) || is_power_of_2(c + 1))) { ++ right_arg->dont_load_item(); ++ } else { ++ // Cannot use constant op. ++ right_arg->load_item(); ++ } ++ } else { ++ right.load_item(); ++ } ++ rlock_result(x); ++ arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), new_register(T_INT)); ++ } ++} ++ ++void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) { ++ // when an operand with use count 1 is the left operand, then it is ++ // likely that no move for 2-operand-LIR-form is necessary ++ if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) { ++ x->swap_operands(); ++ } ++ ++ ValueTag tag = x->type()->tag(); ++ assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters"); ++ switch (tag) { ++ case floatTag: ++ case doubleTag: do_ArithmeticOp_FPU(x); return; ++ case longTag: do_ArithmeticOp_Long(x); return; ++ case intTag: do_ArithmeticOp_Int(x); return; ++ default: ShouldNotReachHere(); return; ++ } ++} ++ ++// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr ++void LIRGenerator::do_ShiftOp(ShiftOp* x) { ++ LIRItem value(x->x(), this); ++ LIRItem count(x->y(), this); ++ ++ value.load_item(); ++ if (count.is_constant()) { ++ assert(count.type()->as_IntConstant() != NULL || count.type()->as_LongConstant() != NULL , "should be"); ++ count.dont_load_item(); ++ } else { ++ count.load_item(); ++ } ++ ++ LIR_Opr res = rlock_result(x); ++ shift_op(x->op(), res, value.result(), count.result(), LIR_OprFact::illegalOpr); ++} ++ ++ ++// _iand, _land, _ior, _lor, _ixor, _lxor ++void LIRGenerator::do_LogicOp(LogicOp* x) { ++ ++ LIRItem left(x->x(), this); ++ LIRItem right(x->y(), this); ++ ++ left.load_item(); ++ rlock_result(x); ++ ValueTag tag = right.type()->tag(); ++ if (right.is_constant() && ++ ((tag == longTag && Assembler::is_simm12(right.get_jlong_constant())) || ++ (tag == intTag && Assembler::is_simm12(right.get_jint_constant())))) { ++ right.dont_load_item(); ++ } else { ++ right.load_item(); ++ } ++ ++ switch (x->op()) { ++ case Bytecodes::_iand: // fall through ++ case Bytecodes::_land: ++ __ logical_and(left.result(), right.result(), x->operand()); break; ++ case Bytecodes::_ior: // fall through ++ case Bytecodes::_lor: ++ __ logical_or(left.result(), right.result(), x->operand()); break; ++ case Bytecodes::_ixor: // fall through ++ case Bytecodes::_lxor: ++ __ logical_xor(left.result(), right.result(), x->operand()); break; ++ default: Unimplemented(); ++ } ++} ++ ++// _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg ++void LIRGenerator::do_CompareOp(CompareOp* x) { ++ LIRItem left(x->x(), this); ++ LIRItem right(x->y(), this); ++ ValueTag tag = x->x()->type()->tag(); ++ if (tag == longTag) { ++ left.set_destroys_register(); ++ } ++ left.load_item(); ++ right.load_item(); ++ LIR_Opr reg = rlock_result(x); ++ ++ if (x->x()->type()->is_float_kind()) { ++ Bytecodes::Code code = x->op(); ++ __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl)); ++ } else if (x->x()->type()->tag() == longTag) { ++ __ lcmp2int(left.result(), right.result(), reg); ++ } else { ++ Unimplemented(); ++ } ++} ++ ++LIR_Opr LIRGenerator::atomic_cmpxchg(BasicType type, LIR_Opr addr, LIRItem& cmp_value, LIRItem& new_value) { ++ LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience ++ new_value.load_item(); ++ cmp_value.load_item(); ++ LIR_Opr result = new_register(T_INT); ++ if (is_reference_type(type)) { ++ __ cas_obj(addr, cmp_value.result(), new_value.result(), new_register(T_INT), new_register(T_INT), result); ++ } else if (type == T_INT) { ++ __ cas_int(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), ill, ill); ++ } else if (type == T_LONG) { ++ __ cas_long(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), ill, ill); ++ } else { ++ ShouldNotReachHere(); ++ } ++ __ logical_xor(FrameMap::r5_opr, LIR_OprFact::intConst(1), result); ++ return result; ++} ++ ++LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) { ++ bool is_oop = is_reference_type(type); ++ LIR_Opr result = new_register(type); ++ value.load_item(); ++ assert(type == T_INT || is_oop LP64_ONLY( || type == T_LONG ), "unexpected type"); ++ LIR_Opr tmp = new_register(T_INT); ++ __ xchg(addr, value.result(), result, tmp); ++ return result; ++} ++ ++LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) { ++ LIR_Opr result = new_register(type); ++ value.load_item(); ++ assert(type == T_INT LP64_ONLY( || type == T_LONG ), "unexpected type"); ++ LIR_Opr tmp = new_register(T_INT); ++ __ xadd(addr, value.result(), result, tmp); ++ return result; ++} ++ ++void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { ++ assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), ++ "wrong type"); ++ ++ switch (x->id()) { ++ case vmIntrinsics::_dexp: // fall through ++ case vmIntrinsics::_dlog: // fall through ++ case vmIntrinsics::_dpow: // fall through ++ case vmIntrinsics::_dcos: // fall through ++ case vmIntrinsics::_dsin: // fall through ++ case vmIntrinsics::_dtan: // fall through ++ case vmIntrinsics::_dlog10: ++ do_LibmIntrinsic(x); ++ break; ++ case vmIntrinsics::_dabs: // fall through ++ case vmIntrinsics::_dsqrt: { ++ assert(x->number_of_arguments() == 1, "wrong type"); ++ LIRItem value(x->argument_at(0), this); ++ value.load_item(); ++ LIR_Opr dst = rlock_result(x); ++ ++ switch (x->id()) { ++ case vmIntrinsics::_dsqrt: { ++ __ sqrt(value.result(), dst, LIR_OprFact::illegalOpr); ++ break; ++ } ++ case vmIntrinsics::_dabs: { ++ __ abs(value.result(), dst, LIR_OprFact::illegalOpr); ++ break; ++ } ++ default: ++ ShouldNotReachHere(); ++ } ++ break; ++ } ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { ++ LIRItem value(x->argument_at(0), this); ++ value.set_destroys_register(); ++ ++ LIR_Opr calc_result = rlock_result(x); ++ LIR_Opr result_reg = result_register_for(x->type()); ++ ++ CallingConvention* cc = NULL; ++ ++ if (x->id() == vmIntrinsics::_dpow) { ++ LIRItem value1(x->argument_at(1), this); ++ ++ value1.set_destroys_register(); ++ ++ BasicTypeList signature(2); ++ signature.append(T_DOUBLE); ++ signature.append(T_DOUBLE); ++ cc = frame_map()->c_calling_convention(&signature); ++ value.load_item_force(cc->at(0)); ++ value1.load_item_force(cc->at(1)); ++ } else { ++ BasicTypeList signature(1); ++ signature.append(T_DOUBLE); ++ cc = frame_map()->c_calling_convention(&signature); ++ value.load_item_force(cc->at(0)); ++ } ++ ++ switch (x->id()) { ++ case vmIntrinsics::_dexp: ++ if (StubRoutines::dexp() != NULL) { __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); } ++ else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); } ++ break; ++ case vmIntrinsics::_dlog: ++ if (StubRoutines::dlog() != NULL) { __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); } ++ else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); } ++ break; ++ case vmIntrinsics::_dlog10: ++ if (StubRoutines::dlog10() != NULL) { __ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args()); } ++ else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args()); } ++ break; ++ case vmIntrinsics::_dsin: ++ if (StubRoutines::dsin() != NULL) { __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); } ++ else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args()); } ++ break; ++ case vmIntrinsics::_dcos: ++ if (StubRoutines::dcos() != NULL) { __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); } ++ else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); } ++ break; ++ case vmIntrinsics::_dtan: ++ if (StubRoutines::dtan() != NULL) { __ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args()); } ++ else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args()); } ++ break; ++ case vmIntrinsics::_dpow: ++ if (StubRoutines::dpow() != NULL) { __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); } ++ else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args()); } ++ break; ++ default: ShouldNotReachHere(); ++ } ++ __ move(result_reg, calc_result); ++} ++ ++ ++void LIRGenerator::do_ArrayCopy(Intrinsic* x) { ++ assert(x->number_of_arguments() == 5, "wrong type"); ++ ++ // Make all state_for calls early since they can emit code ++ CodeEmitInfo* info = state_for(x, x->state()); ++ ++ LIRItem src(x->argument_at(0), this); ++ LIRItem src_pos(x->argument_at(1), this); ++ LIRItem dst(x->argument_at(2), this); ++ LIRItem dst_pos(x->argument_at(3), this); ++ LIRItem length(x->argument_at(4), this); ++ ++ // operands for arraycopy must use fixed registers, otherwise ++ // LinearScan will fail allocation (because arraycopy always needs a ++ // call) ++ ++ // The java calling convention will give us enough registers ++ // so that on the stub side the args will be perfect already. ++ // On the other slow/special case side we call C and the arg ++ // positions are not similar enough to pick one as the best. ++ // Also because the java calling convention is a "shifted" version ++ // of the C convention we can process the java args trivially into C ++ // args without worry of overwriting during the xfer ++ ++ src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); ++ src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); ++ dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); ++ dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); ++ length.load_item_force (FrameMap::as_opr(j_rarg4)); ++ ++ LIR_Opr tmp = FrameMap::as_opr(j_rarg5); ++ ++ set_no_result(x); ++ ++ int flags; ++ ciArrayKlass* expected_type = NULL; ++ arraycopy_helper(x, &flags, &expected_type); ++ ++ __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, ++ expected_type, flags, info); // does add_safepoint ++} ++ ++void LIRGenerator::do_update_CRC32(Intrinsic* x) { ++ ShouldNotReachHere(); ++} ++ ++void LIRGenerator::do_update_CRC32C(Intrinsic* x) { ++ ShouldNotReachHere(); ++} ++ ++void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) { ++ assert(x->number_of_arguments() == 3, "wrong type"); ++ assert(UseFMA, "Needs FMA instructions support."); ++ LIRItem value(x->argument_at(0), this); ++ LIRItem value1(x->argument_at(1), this); ++ LIRItem value2(x->argument_at(2), this); ++ ++ value.load_item(); ++ value1.load_item(); ++ value2.load_item(); ++ ++ LIR_Opr calc_input = value.result(); ++ LIR_Opr calc_input1 = value1.result(); ++ LIR_Opr calc_input2 = value2.result(); ++ LIR_Opr calc_result = rlock_result(x); ++ ++ switch (x->id()) { ++ case vmIntrinsics::_fmaD: __ fmad(calc_input, calc_input1, calc_input2, calc_result); break; ++ case vmIntrinsics::_fmaF: __ fmaf(calc_input, calc_input1, calc_input2, calc_result); break; ++ default: ShouldNotReachHere(); ++ } ++} ++ ++void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) { ++ fatal("vectorizedMismatch intrinsic is not implemented on this platform"); ++} ++ ++// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f ++// _i2b, _i2c, _i2s ++void LIRGenerator::do_Convert(Convert* x) { ++ LIRItem value(x->value(), this); ++ value.load_item(); ++ LIR_Opr input = value.result(); ++ LIR_Opr result = rlock(x); ++ ++ // arguments of lir_convert ++ LIR_Opr conv_input = input; ++ LIR_Opr conv_result = result; ++ ++ __ convert(x->op(), conv_input, conv_result); ++ ++ assert(result->is_virtual(), "result must be virtual register"); ++ set_result(x, result); ++} ++ ++void LIRGenerator::do_NewInstance(NewInstance* x) { ++#ifndef PRODUCT ++ if (PrintNotLoaded && !x->klass()->is_loaded()) { ++ tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci()); ++ } ++#endif ++ CodeEmitInfo* info = state_for(x, x->state()); ++ LIR_Opr reg = result_register_for(x->type()); ++ new_instance(reg, x->klass(), x->is_unresolved(), ++ FrameMap::r12_oop_opr, ++ FrameMap::r15_oop_opr, ++ FrameMap::r14_oop_opr, ++ LIR_OprFact::illegalOpr, ++ FrameMap::r13_metadata_opr, ++ info); ++ LIR_Opr result = rlock_result(x); ++ __ move(reg, result); ++} ++ ++void LIRGenerator::do_NewTypeArray(NewTypeArray* x) { ++ CodeEmitInfo* info = state_for(x, x->state()); ++ ++ LIRItem length(x->length(), this); ++ length.load_item_force(FrameMap::r9_opr); ++ ++ LIR_Opr reg = result_register_for(x->type()); ++ LIR_Opr tmp1 = FrameMap::r12_oop_opr; ++ LIR_Opr tmp2 = FrameMap::r14_oop_opr; ++ LIR_Opr tmp3 = FrameMap::r15_oop_opr; ++ LIR_Opr tmp4 = reg; ++ LIR_Opr klass_reg = FrameMap::r13_metadata_opr; ++ LIR_Opr len = length.result(); ++ BasicType elem_type = x->elt_type(); ++ ++ __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg); ++ ++ CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info); ++ __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path); ++ ++ LIR_Opr result = rlock_result(x); ++ __ move(reg, result); ++} ++ ++void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { ++ LIRItem length(x->length(), this); ++ // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction ++ // and therefore provide the state before the parameters have been consumed ++ CodeEmitInfo* patching_info = NULL; ++ if (!x->klass()->is_loaded() || PatchALot) { ++ patching_info = state_for(x, x->state_before()); ++ } ++ ++ CodeEmitInfo* info = state_for(x, x->state()); ++ ++ LIR_Opr reg = result_register_for(x->type()); ++ LIR_Opr tmp1 = FrameMap::r12_oop_opr; ++ LIR_Opr tmp2 = FrameMap::r14_oop_opr; ++ LIR_Opr tmp3 = FrameMap::r15_oop_opr; ++ LIR_Opr tmp4 = reg; ++ LIR_Opr klass_reg = FrameMap::r13_metadata_opr; ++ ++ length.load_item_force(FrameMap::r9_opr); ++ LIR_Opr len = length.result(); ++ ++ CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info); ++ ciKlass* obj = (ciKlass*) ciObjArrayKlass::make(x->klass()); ++ if (obj == ciEnv::unloaded_ciobjarrayklass()) { ++ BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error"); ++ } ++ klass2reg_with_patching(klass_reg, obj, patching_info); ++ __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path); ++ ++ LIR_Opr result = rlock_result(x); ++ __ move(reg, result); ++} ++ ++ ++void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { ++ Values* dims = x->dims(); ++ int i = dims->length(); ++ LIRItemList* items = new LIRItemList(i, i, NULL); ++ while (i-- > 0) { ++ LIRItem* size = new LIRItem(dims->at(i), this); ++ items->at_put(i, size); ++ } ++ ++ // Evaluate state_for early since it may emit code. ++ CodeEmitInfo* patching_info = NULL; ++ if (!x->klass()->is_loaded() || PatchALot) { ++ patching_info = state_for(x, x->state_before()); ++ ++ // Cannot re-use same xhandlers for multiple CodeEmitInfos, so ++ // clone all handlers (NOTE: Usually this is handled transparently ++ // by the CodeEmitInfo cloning logic in CodeStub constructors but ++ // is done explicitly here because a stub isn't being used). ++ x->set_exception_handlers(new XHandlers(x->exception_handlers())); ++ } ++ CodeEmitInfo* info = state_for(x, x->state()); ++ ++ i = dims->length(); ++ while (i-- > 0) { ++ LIRItem* size = items->at(i); ++ size->load_item(); ++ ++ store_stack_parameter(size->result(), in_ByteSize(i * BytesPerInt)); ++ } ++ ++ LIR_Opr klass_reg = FrameMap::r10_metadata_opr; ++ klass2reg_with_patching(klass_reg, x->klass(), patching_info); ++ ++ LIR_Opr rank = FrameMap::r9_opr; ++ __ move(LIR_OprFact::intConst(x->rank()), rank); ++ LIR_Opr varargs = FrameMap::r12_opr; ++ __ move(FrameMap::sp_opr, varargs); ++ LIR_OprList* args = new LIR_OprList(3); ++ args->append(klass_reg); ++ args->append(rank); ++ args->append(varargs); ++ LIR_Opr reg = result_register_for(x->type()); ++ __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id), ++ LIR_OprFact::illegalOpr, ++ reg, args, info); ++ ++ LIR_Opr result = rlock_result(x); ++ __ move(reg, result); ++} ++ ++void LIRGenerator::do_BlockBegin(BlockBegin* x) { ++ // nothing to do for now ++} ++ ++void LIRGenerator::do_CheckCast(CheckCast* x) { ++ LIRItem obj(x->obj(), this); ++ ++ CodeEmitInfo* patching_info = NULL; ++ if (!x->klass()->is_loaded() || ++ (PatchALot && !x->is_incompatible_class_change_check() && !x->is_invokespecial_receiver_check())) { ++ // must do this before locking the destination register as an oop register, ++ // and before the obj is loaded (the latter is for deoptimization) ++ patching_info = state_for(x, x->state_before()); ++ } ++ obj.load_item(); ++ ++ // info for exceptions ++ CodeEmitInfo* info_for_exception = ++ (x->needs_exception_state() ? state_for(x) : ++ state_for(x, x->state_before(), true /*ignore_xhandler*/ )); ++ ++ CodeStub* stub = NULL; ++ if (x->is_incompatible_class_change_check()) { ++ assert(patching_info == NULL, "can't patch this"); ++ stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, ++ info_for_exception); ++ } else if (x->is_invokespecial_receiver_check()) { ++ assert(patching_info == NULL, "can't patch this"); ++ stub = new DeoptimizeStub(info_for_exception, ++ Deoptimization::Reason_class_check, ++ Deoptimization::Action_none); ++ } else { ++ stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); ++ } ++ LIR_Opr reg = rlock_result(x); ++ LIR_Opr tmp3 = LIR_OprFact::illegalOpr; ++ if (!x->klass()->is_loaded() || UseCompressedClassPointers) { ++ tmp3 = new_register(objectType); ++ } ++ __ checkcast(reg, obj.result(), x->klass(), ++ new_register(objectType), new_register(objectType), tmp3, ++ x->direct_compare(), info_for_exception, patching_info, stub, ++ x->profiled_method(), x->profiled_bci()); ++} ++ ++void LIRGenerator::do_InstanceOf(InstanceOf* x) { ++ LIRItem obj(x->obj(), this); ++ ++ // result and test object may not be in same register ++ LIR_Opr reg = rlock_result(x); ++ CodeEmitInfo* patching_info = NULL; ++ if ((!x->klass()->is_loaded() || PatchALot)) { ++ // must do this before locking the destination register as an oop register ++ patching_info = state_for(x, x->state_before()); ++ } ++ obj.load_item(); ++ LIR_Opr tmp3 = LIR_OprFact::illegalOpr; ++ if (!x->klass()->is_loaded() || UseCompressedClassPointers) { ++ tmp3 = new_register(objectType); ++ } ++ __ instanceof(reg, obj.result(), x->klass(), ++ new_register(objectType), new_register(objectType), tmp3, ++ x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); ++} ++ ++void LIRGenerator::do_If(If* x) { ++ // If should have two successors ++ assert(x->number_of_sux() == 2, "inconsistency"); ++ ValueTag tag = x->x()->type()->tag(); ++ bool is_safepoint = x->is_safepoint(); ++ ++ If::Condition cond = x->cond(); ++ ++ LIRItem xitem(x->x(), this); ++ LIRItem yitem(x->y(), this); ++ LIRItem* xin = &xitem; ++ LIRItem* yin = &yitem; ++ ++ if (tag == longTag) { ++ // for longs, only conditions "eql", "neq", "lss", "geq" are valid; ++ // mirror for other conditions ++ if (cond == If::gtr || cond == If::leq) { ++ cond = Instruction::mirror(cond); ++ xin = &yitem; ++ yin = &xitem; ++ } ++ xin->set_destroys_register(); ++ } ++ xin->load_item(); ++ yin->load_item(); ++ ++ set_no_result(x); ++ ++ LIR_Opr left = xin->result(); ++ LIR_Opr right = yin->result(); ++ ++ // add safepoint before generating condition code so it can be recomputed ++ if (x->is_safepoint()) { ++ // increment backedge counter if needed ++ increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()), ++ x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci()); ++ __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before())); ++ } ++ ++ // Generate branch profiling. Profiling code doesn't kill flags. ++ __ cmp(lir_cond(cond), left, right); ++ profile_branch(x, cond); ++ move_to_phi(x->state()); ++ if (x->x()->type()->is_float_kind()) { ++ __ branch(lir_cond(cond), x->tsux(), x->usux()); ++ } else { ++ __ branch(lir_cond(cond), x->tsux()); ++ } ++ assert(x->default_sux() == x->fsux(), "wrong destination above"); ++ __ jump(x->default_sux()); ++} ++ ++LIR_Opr LIRGenerator::getThreadPointer() { ++ return FrameMap::as_pointer_opr(xthread); ++} ++ ++void LIRGenerator::trace_block_entry(BlockBegin* block) { Unimplemented(); } ++ ++void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address, ++ CodeEmitInfo* info) { ++ __ volatile_store_mem_reg(value, address, info); ++} ++ ++void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, ++ CodeEmitInfo* info) { ++ __ volatile_load_mem_reg(address, result, info); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LIR_riscv.cpp +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (c) 2016, 2020, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/register.hpp" ++#include "c1/c1_LIR.hpp" ++ ++FloatRegister LIR_OprDesc::as_float_reg() const { ++ return as_FloatRegister(fpu_regnr()); ++} ++ ++FloatRegister LIR_OprDesc::as_double_reg() const { ++ return as_FloatRegister(fpu_regnrLo()); ++} ++ ++// Reg2 unused. ++LIR_Opr LIR_OprFact::double_fpu(int reg1, int reg2) { ++ assert(as_FloatRegister(reg2) == fnoreg, "Not used on this platform"); ++ return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) | ++ (reg1 << LIR_OprDesc::reg2_shift) | ++ LIR_OprDesc::double_type | ++ LIR_OprDesc::fpu_register | ++ LIR_OprDesc::double_size); ++} ++ ++#ifndef PRODUCT ++void LIR_Address::verify() const { ++ assert(base()->is_cpu_register(), "wrong base operand"); ++ assert(index()->is_illegal() || index()->is_double_cpu() || index()->is_single_cpu(), "wrong index operand"); ++ assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_LONG || ++ base()->type() == T_METADATA, "wrong type for addresses"); ++} ++#endif // PRODUCT +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LinearScan_riscv.cpp +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "c1/c1_Instruction.hpp" ++#include "c1/c1_LinearScan.hpp" ++#include "utilities/bitMap.inline.hpp" ++ ++void LinearScan::allocate_fpu_stack() { ++ // No FPU stack on RISCV ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_LinearScan_riscv.hpp +@@ -0,0 +1,83 @@ ++/* ++ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_LINEARSCAN_RISCV_HPP ++#define CPU_RISCV_C1_LINEARSCAN_RISCV_HPP ++ ++inline bool LinearScan::is_processed_reg_num(int reg_num) ++{ ++ return reg_num <= FrameMap::last_cpu_reg() || reg_num >= pd_nof_cpu_regs_frame_map; ++} ++ ++inline int LinearScan::num_physical_regs(BasicType type) { ++ return 1; ++} ++ ++inline bool LinearScan::requires_adjacent_regs(BasicType type) { ++ return false; ++} ++ ++inline bool LinearScan::is_caller_save(int assigned_reg) { ++ assert(assigned_reg >= 0 && assigned_reg < nof_regs, "should call this only for registers"); ++ if (assigned_reg < pd_first_callee_saved_reg) { ++ return true; ++ } ++ if (assigned_reg > pd_last_callee_saved_reg && assigned_reg < pd_first_callee_saved_fpu_reg_1) { ++ return true; ++ } ++ if (assigned_reg > pd_last_callee_saved_fpu_reg_1 && assigned_reg < pd_first_callee_saved_fpu_reg_2) { ++ return true; ++ } ++ if (assigned_reg > pd_last_callee_saved_fpu_reg_2 && assigned_reg < pd_last_fpu_reg) { ++ return true; ++ } ++ return false; ++} ++ ++inline void LinearScan::pd_add_temps(LIR_Op* op) { ++ // No special case behaviours yet ++} ++ ++ ++// Implementation of LinearScanWalker ++ ++inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) ++{ ++ if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::callee_saved)) { ++ assert(cur->type() != T_FLOAT && cur->type() != T_DOUBLE, "cpu regs only"); ++ _first_reg = pd_first_callee_saved_reg; ++ _last_reg = pd_last_callee_saved_reg; ++ return true; ++ } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || ++ cur->type() == T_ADDRESS || cur->type() == T_METADATA) { ++ _first_reg = pd_first_cpu_reg; ++ _last_reg = pd_last_allocatable_cpu_reg; ++ return true; ++ } ++ return false; ++} ++ ++#endif // CPU_RISCV_C1_LINEARSCAN_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp +@@ -0,0 +1,451 @@ ++/* ++ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "c1/c1_LIR.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "c1/c1_Runtime1.hpp" ++#include "classfile/systemDictionary.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "interpreter/interpreter.hpp" ++#include "oops/arrayOop.hpp" ++#include "oops/markWord.hpp" ++#include "runtime/basicLock.hpp" ++#include "runtime/os.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++ ++void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result, ++ FloatRegister freg0, FloatRegister freg1, ++ Register result) { ++ if (is_float) { ++ float_compare(result, freg0, freg1, unordered_result); ++ } else { ++ double_compare(result, freg0, freg1, unordered_result); ++ } ++} ++ ++int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register tmp, 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"); ++ Label done; ++ int null_check_offset = -1; ++ ++ verify_oop(obj); ++ ++ // save object being locked into the BasicObjectLock ++ sd(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); ++ ++ null_check_offset = offset(); ++ ++ 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 */); ++ } ++ ++ if (UseBiasedLocking) { ++ assert(tmp != noreg, "should have tmp register at this point"); ++ biased_locking_enter(disp_hdr, obj, hdr, tmp, false, done, &slow_case); ++ } ++ ++ // Load object header ++ ld(hdr, Address(obj, hdr_offset)); ++ // and mark it as unlocked ++ ori(hdr, hdr, markWord::unlocked_value); ++ // save unlocked object header into the displaced header location on the stack ++ sd(hdr, Address(disp_hdr, 0)); ++ // 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*/NULL); ++ // 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.: ++ // ++ // 1) (hdr & aligned_mask) == 0 ++ // 2) sp <= hdr ++ // 3) hdr <= sp + page_size ++ // ++ // these 3 tests can be done by evaluating the following expression: ++ // ++ // (hdr -sp) & (aligned_mask - page_size) ++ // ++ // 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 - os::vm_page_size()); ++ andr(hdr, hdr, t0); ++ // 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)); ++ // otherwise we don't care about the result and handle locking via runtime call ++ bnez(hdr, slow_case, /* is_far */ true); ++ bind(done); ++ return null_check_offset; ++} ++ ++void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, 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"); ++ Label done; ++ ++ if (UseBiasedLocking) { ++ // load object ++ ld(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); ++ biased_locking_exit(obj, hdr, done); ++ } ++ ++ // load displaced header ++ ld(hdr, Address(disp_hdr, 0)); ++ // if the loaded hdr is NULL we had recursive locking ++ // if we had recursive locking, we are done ++ beqz(hdr, done); ++ if (!UseBiasedLocking) { ++ // load object ++ ld(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); ++ } ++ verify_oop(obj); ++ // 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 ++ // 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); ++ } else { ++ cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case); ++ } ++ bind(done); ++} ++ ++// Defines obj, preserves var_size_in_bytes ++void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, Label& slow_case) { ++ if (UseTLAB) { ++ tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, tmp1, tmp2, slow_case, /* is_far */ true); ++ } else { ++ eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, tmp1, slow_case, /* is_far */ true); ++ } ++} ++ ++void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) { ++ assert_different_registers(obj, klass, len); ++ if (UseBiasedLocking & !len->is_valid()) { ++ assert_different_registers(obj, klass, len, tmp1, tmp2); ++ ld(tmp1, Address(klass, Klass::prototype_header_offset())); ++ } else { ++ // This assumes that all prototype bits fitr in an int32_t ++ mv(tmp1, (int32_t)(intptr_t)markWord::prototype().value()); ++ } ++ sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes())); ++ ++ if (UseCompressedClassPointers) { // Take care not to kill klass ++ encode_klass_not_null(tmp1, klass, tmp2); ++ sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes())); ++ } else { ++ sd(klass, Address(obj, oopDesc::klass_offset_in_bytes())); ++ } ++ ++ if (len->is_valid()) { ++ sw(len, Address(obj, arrayOopDesc::length_offset_in_bytes())); ++ } else if (UseCompressedClassPointers) { ++ store_klass_gap(obj, zr); ++ } ++} ++ ++// preserves obj, destroys len_in_bytes ++void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register tmp) { ++ assert(hdr_size_in_bytes >= 0, "header size must be positive or 0"); ++ Label done; ++ ++ // len_in_bytes is positive and ptr sized ++ sub(len_in_bytes, len_in_bytes, hdr_size_in_bytes); ++ beqz(len_in_bytes, done); ++ ++ // Preserve obj ++ if (hdr_size_in_bytes) { ++ add(obj, obj, hdr_size_in_bytes); ++ } ++ zero_memory(obj, len_in_bytes, tmp); ++ if (hdr_size_in_bytes) { ++ sub(obj, obj, hdr_size_in_bytes); ++ } ++ ++ bind(done); ++} ++ ++void C1_MacroAssembler::allocate_object(Register obj, Register tmp1, Register tmp2, int header_size, int object_size, Register klass, Label& slow_case) { ++ assert_different_registers(obj, tmp1, tmp2); ++ assert(header_size >= 0 && object_size >= header_size, "illegal sizes"); ++ ++ try_allocate(obj, noreg, object_size * BytesPerWord, tmp1, tmp2, slow_case); ++ ++ initialize_object(obj, klass, noreg, object_size * HeapWordSize, tmp1, tmp2, UseTLAB); ++} ++ ++void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, bool is_tlab_allocated) { ++ assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, ++ "con_size_in_bytes is not multiple of alignment"); ++ const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; ++ ++ initialize_header(obj, klass, noreg, tmp1, tmp2); ++ ++ if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) { ++ // clear rest of allocated space ++ const Register index = tmp2; ++ // 16: multipler for threshold ++ const int threshold = 16 * BytesPerWord; // approximate break even point for code size (see comments below) ++ if (var_size_in_bytes != noreg) { ++ mv(index, var_size_in_bytes); ++ initialize_body(obj, index, hdr_size_in_bytes, tmp1); ++ } else if (con_size_in_bytes <= threshold) { ++ // use explicit null stores ++ int i = hdr_size_in_bytes; ++ if (i < con_size_in_bytes && (con_size_in_bytes % (2 * BytesPerWord))) { // 2: multipler for BytesPerWord ++ sd(zr, Address(obj, i)); ++ i += BytesPerWord; ++ } ++ for (; i < con_size_in_bytes; i += BytesPerWord) { ++ sd(zr, Address(obj, i)); ++ } ++ } else if (con_size_in_bytes > hdr_size_in_bytes) { ++ block_comment("zero memory"); ++ // use loop to null out the fields ++ int words = (con_size_in_bytes - hdr_size_in_bytes) / BytesPerWord; ++ mv(index, words / 8); // 8: byte size ++ ++ const int unroll = 8; // Number of sd(zr) instructions we'll unroll ++ int remainder = words % unroll; ++ la(t0, Address(obj, hdr_size_in_bytes + remainder * BytesPerWord)); ++ ++ Label entry_point, loop; ++ j(entry_point); ++ ++ bind(loop); ++ sub(index, index, 1); ++ for (int i = -unroll; i < 0; i++) { ++ if (-i == remainder) { ++ bind(entry_point); ++ } ++ sd(zr, Address(t0, i * wordSize)); ++ } ++ if (remainder == 0) { ++ bind(entry_point); ++ } ++ add(t0, t0, unroll * wordSize); ++ bnez(index, loop); ++ } ++ } ++ ++ membar(MacroAssembler::StoreStore); ++ ++ if (CURRENT_ENV->dtrace_alloc_probes()) { ++ assert(obj == x10, "must be"); ++ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id))); ++ } ++ ++ verify_oop(obj); ++} ++ ++void C1_MacroAssembler::allocate_array(Register obj, Register len, Register tmp1, Register tmp2, int header_size, int f, Register klass, Label& slow_case) { ++ assert_different_registers(obj, len, tmp1, tmp2, klass); ++ ++ // determine alignment mask ++ assert(!(BytesPerWord & 1), "must be multiple of 2 for masking code to work"); ++ ++ // check for negative or excessive length ++ mv(t0, (int32_t)max_array_allocation_length); ++ bgeu(len, t0, slow_case, /* is_far */ true); ++ ++ const Register arr_size = tmp2; // okay to be the same ++ // align object end ++ mv(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask); ++ shadd(arr_size, len, arr_size, t0, f); ++ andi(arr_size, arr_size, ~(uint)MinObjAlignmentInBytesMask); ++ ++ try_allocate(obj, arr_size, 0, tmp1, tmp2, slow_case); ++ ++ initialize_header(obj, klass, len, tmp1, tmp2); ++ ++ // clear rest of allocated space ++ const Register len_zero = len; ++ initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero); ++ ++ membar(MacroAssembler::StoreStore); ++ ++ if (CURRENT_ENV->dtrace_alloc_probes()) { ++ assert(obj == x10, "must be"); ++ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id))); ++ } ++ ++ verify_oop(obj); ++} ++ ++void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache, Label &L) { ++ verify_oop(receiver); ++ // explicit NULL check not needed since load from [klass_offset] causes a trap ++ // check against inline cache ++ assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); ++ assert_different_registers(receiver, iCache, t0, t2); ++ cmp_klass(receiver, iCache, t0, t2 /* call-clobbered t2 as a tmp */, L); ++} ++ ++void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) { ++ assert(bang_size_in_bytes >= framesize, "stack bang size incorrect"); ++ // Make sure there is enough stack space for this method's activation. ++ // Note that we do this before creating a frame. ++ generate_stack_overflow_check(bang_size_in_bytes); ++ MacroAssembler::build_frame(framesize); ++ ++ // Insert nmethod entry barrier into frame. ++ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->nmethod_entry_barrier(this); ++} ++ ++void C1_MacroAssembler::remove_frame(int framesize) { ++ MacroAssembler::remove_frame(framesize); ++} ++ ++ ++void C1_MacroAssembler::verified_entry(bool breakAtEntry) { ++ // If we have to make this method not-entrant we'll overwrite its ++ // first instruction with a jump. For this action to be legal we ++ // must ensure that this first instruction is a J, JAL or NOP. ++ // Make it a NOP. ++ IncompressibleRegion ir(this); // keep the nop as 4 bytes for patching. ++ assert_alignment(pc()); ++ nop(); // 4 bytes ++} ++ ++void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) { ++ // fp + -2: link ++ // + -1: return address ++ // + 0: argument with offset 0 ++ // + 1: argument with offset 1 ++ // + 2: ... ++ ld(reg, Address(fp, offset_in_words * BytesPerWord)); ++} ++ ++#ifndef PRODUCT ++ ++void C1_MacroAssembler::verify_stack_oop(int stack_offset) { ++ if (!VerifyOops) { ++ return; ++ } ++ verify_oop_addr(Address(sp, stack_offset), "oop"); ++} ++ ++void C1_MacroAssembler::verify_not_null_oop(Register r) { ++ if (!VerifyOops) return; ++ Label not_null; ++ bnez(r, not_null); ++ stop("non-null oop required"); ++ bind(not_null); ++ verify_oop(r); ++} ++ ++void C1_MacroAssembler::invalidate_registers(bool inv_x10, bool inv_x9, bool inv_x12, bool inv_x13, bool inv_x14, bool inv_x15) { ++#ifdef ASSERT ++ static int nn; ++ if (inv_x10) { mv(x10, 0xDEAD); } ++ if (inv_x9) { mv(x9, 0xDEAD); } ++ if (inv_x12) { mv(x12, nn++); } ++ if (inv_x13) { mv(x13, 0xDEAD); } ++ if (inv_x14) { mv(x14, 0xDEAD); } ++ if (inv_x15) { mv(x15, 0xDEAD); } ++#endif // ASSERT ++} ++#endif // ifndef PRODUCT ++ ++typedef void (C1_MacroAssembler::*c1_cond_branch_insn)(Register op1, Register op2, Label& label, bool is_far); ++typedef void (C1_MacroAssembler::*c1_float_cond_branch_insn)(FloatRegister op1, FloatRegister op2, ++ Label& label, bool is_far, bool is_unordered); ++ ++static c1_cond_branch_insn c1_cond_branch[] = ++{ ++ /* SHORT branches */ ++ (c1_cond_branch_insn)&MacroAssembler::beq, ++ (c1_cond_branch_insn)&MacroAssembler::bne, ++ (c1_cond_branch_insn)&MacroAssembler::blt, ++ (c1_cond_branch_insn)&MacroAssembler::ble, ++ (c1_cond_branch_insn)&MacroAssembler::bge, ++ (c1_cond_branch_insn)&MacroAssembler::bgt, ++ (c1_cond_branch_insn)&MacroAssembler::bleu, // lir_cond_belowEqual ++ (c1_cond_branch_insn)&MacroAssembler::bgeu // lir_cond_aboveEqual ++}; ++ ++static c1_float_cond_branch_insn c1_float_cond_branch[] = ++{ ++ /* FLOAT branches */ ++ (c1_float_cond_branch_insn)&MacroAssembler::float_beq, ++ (c1_float_cond_branch_insn)&MacroAssembler::float_bne, ++ (c1_float_cond_branch_insn)&MacroAssembler::float_blt, ++ (c1_float_cond_branch_insn)&MacroAssembler::float_ble, ++ (c1_float_cond_branch_insn)&MacroAssembler::float_bge, ++ (c1_float_cond_branch_insn)&MacroAssembler::float_bgt, ++ NULL, // lir_cond_belowEqual ++ NULL, // lir_cond_aboveEqual ++ ++ /* DOUBLE branches */ ++ (c1_float_cond_branch_insn)&MacroAssembler::double_beq, ++ (c1_float_cond_branch_insn)&MacroAssembler::double_bne, ++ (c1_float_cond_branch_insn)&MacroAssembler::double_blt, ++ (c1_float_cond_branch_insn)&MacroAssembler::double_ble, ++ (c1_float_cond_branch_insn)&MacroAssembler::double_bge, ++ (c1_float_cond_branch_insn)&MacroAssembler::double_bgt, ++ NULL, // lir_cond_belowEqual ++ NULL // lir_cond_aboveEqual ++}; ++ ++void C1_MacroAssembler::c1_cmp_branch(int cmpFlag, Register op1, Register op2, Label& label, ++ BasicType type, bool is_far) { ++ if (type == T_OBJECT || type == T_ARRAY) { ++ assert(cmpFlag == lir_cond_equal || cmpFlag == lir_cond_notEqual, "Should be equal or notEqual"); ++ if (cmpFlag == lir_cond_equal) { ++ beq(op1, op2, label, is_far); ++ } else { ++ bne(op1, op2, label, is_far); ++ } ++ } else { ++ assert(cmpFlag >= 0 && cmpFlag < (int)(sizeof(c1_cond_branch) / sizeof(c1_cond_branch[0])), ++ "invalid c1 conditional branch index"); ++ (this->*c1_cond_branch[cmpFlag])(op1, op2, label, is_far); ++ } ++} ++ ++void C1_MacroAssembler::c1_float_cmp_branch(int cmpFlag, FloatRegister op1, FloatRegister op2, Label& label, ++ bool is_far, bool is_unordered) { ++ assert(cmpFlag >= 0 && ++ cmpFlag < (int)(sizeof(c1_float_cond_branch) / sizeof(c1_float_cond_branch[0])), ++ "invalid c1 float conditional branch index"); ++ (this->*c1_float_cond_branch[cmpFlag])(op1, op2, label, is_far, is_unordered); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.hpp +@@ -0,0 +1,121 @@ ++/* ++ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_MACROASSEMBLER_RISCV_HPP ++#define CPU_RISCV_C1_MACROASSEMBLER_RISCV_HPP ++ ++using MacroAssembler::build_frame; ++using MacroAssembler::null_check; ++ ++// C1_MacroAssembler contains high-level macros for C1 ++ ++ private: ++ int _rsp_offset; // track rsp changes ++ // initialization ++ void pd_init() { _rsp_offset = 0; } ++ ++ ++ public: ++ void try_allocate( ++ Register obj, // result: pointer to object after successful allocation ++ Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise ++ int con_size_in_bytes, // object size in bytes if known at compile time ++ Register tmp1, // temp register ++ Register tmp2, // temp register ++ Label& slow_case // continuation point if fast allocation fails ++ ); ++ ++ void initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2); ++ void initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register tmp); ++ ++ void float_cmp(bool is_float, int unordered_result, ++ FloatRegister f0, FloatRegister f1, ++ Register result); ++ ++ // locking ++ // 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 ++ // tmp : temporary register, contents destroyed ++ // returns code offset at which to add null check debug information ++ int lock_object (Register swap, Register obj, Register disp_hdr, Register tmp, 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); ++ ++ void initialize_object( ++ Register obj, // result: pointer to object after successful allocation ++ Register klass, // object klass ++ Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise ++ int con_size_in_bytes, // object size in bytes if known at compile time ++ Register tmp1, // temp register ++ Register tmp2, // temp register ++ bool is_tlab_allocated // the object was allocated in a TLAB; relevant for the implementation of ZeroTLAB ++ ); ++ ++ // allocation of fixed-size objects ++ // (can also be used to allocate fixed-size arrays, by setting ++ // hdr_size correctly and storing the array length afterwards) ++ // obj : will contain pointer to allocated object ++ // t1, t2 : temp registers - contents destroyed ++ // header_size: size of object header in words ++ // object_size: total size of object in words ++ // slow_case : exit to slow case implementation if fast allocation fails ++ void allocate_object(Register obj, Register tmp1, Register tmp2, int header_size, int object_size, Register klass, Label& slow_case); ++ ++ enum { ++ max_array_allocation_length = 0x00FFFFFF ++ }; ++ ++ // allocation of arrays ++ // obj : will contain pointer to allocated object ++ // len : array length in number of elements ++ // t : temp register - contents destroyed ++ // header_size: size of object header in words ++ // f : element scale factor ++ // slow_case : exit to slow case implementation if fast allocation fails ++ void allocate_array(Register obj, Register len, Register tmp1, Register tmp2, int header_size, int f, Register klass, Label& slow_case); ++ ++ int rsp_offset() const { return _rsp_offset; } ++ ++ void invalidate_registers(bool inv_r0, bool inv_r19, bool inv_r2, bool inv_r3, bool inv_r4, bool inv_r5) PRODUCT_RETURN; ++ ++ // This platform only uses signal-based null checks. The Label is not needed. ++ void null_check(Register r, Label *Lnull = NULL) { MacroAssembler::null_check(r); } ++ ++ void load_parameter(int offset_in_words, Register reg); ++ ++ void inline_cache_check(Register receiver, Register iCache, Label &L); ++ ++ static const int c1_double_branch_mask = 1 << 3; // depend on c1_float_cond_branch ++ void c1_cmp_branch(int cmpFlag, Register op1, Register op2, Label& label, BasicType type, bool is_far); ++ void c1_float_cmp_branch(int cmpFlag, FloatRegister op1, FloatRegister op2, Label& label, ++ bool is_far, bool is_unordered = false); ++ ++#endif // CPU_RISCV_C1_MACROASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp +@@ -0,0 +1,1179 @@ ++/* ++ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "c1/c1_CodeStubs.hpp" ++#include "c1/c1_Defs.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "c1/c1_Runtime1.hpp" ++#include "compiler/disassembler.hpp" ++#include "compiler/oopMap.hpp" ++#include "gc/shared/cardTable.hpp" ++#include "gc/shared/cardTableBarrierSet.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "interpreter/interpreter.hpp" ++#include "memory/universe.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/compiledICHolder.hpp" ++#include "oops/oop.inline.hpp" ++#include "prims/jvmtiExport.hpp" ++#include "register_riscv.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/signature.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/vframe.hpp" ++#include "runtime/vframeArray.hpp" ++#include "utilities/powerOfTwo.hpp" ++#include "vmreg_riscv.inline.hpp" ++ ++ ++// Implementation of StubAssembler ++ ++int StubAssembler::call_RT(Register oop_result, Register metadata_result, address entry, int args_size) { ++ // setup registers ++ assert(!(oop_result->is_valid() || metadata_result->is_valid()) || oop_result != metadata_result, ++ "registers must be different"); ++ assert(oop_result != xthread && metadata_result != xthread, "registers must be different"); ++ assert(args_size >= 0, "illegal args_size"); ++ bool align_stack = false; ++ ++ mv(c_rarg0, xthread); ++ set_num_rt_args(0); // Nothing on stack ++ ++ Label retaddr; ++ set_last_Java_frame(sp, fp, retaddr, t0); ++ ++ // do the call ++ RuntimeAddress target(entry); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(t0, target, offset); ++ jalr(x1, t0, offset); ++ }); ++ bind(retaddr); ++ int call_offset = offset(); ++ // verify callee-saved register ++#ifdef ASSERT ++ push_reg(x10, sp); ++ { Label L; ++ get_thread(x10); ++ beq(xthread, x10, L); ++ stop("StubAssembler::call_RT: xthread not callee saved?"); ++ bind(L); ++ } ++ pop_reg(x10, sp); ++#endif ++ reset_last_Java_frame(true); ++ ++ // check for pending exceptions ++ { Label L; ++ // check for pending exceptions (java_thread is set upon return) ++ ld(t0, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ beqz(t0, L); ++ // exception pending => remove activation and forward to exception handler ++ // make sure that the vm_results are cleared ++ if (oop_result->is_valid()) { ++ sd(zr, Address(xthread, JavaThread::vm_result_offset())); ++ } ++ if (metadata_result->is_valid()) { ++ sd(zr, Address(xthread, JavaThread::vm_result_2_offset())); ++ } ++ if (frame_size() == no_frame_size) { ++ leave(); ++ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); ++ } else if (_stub_id == Runtime1::forward_exception_id) { ++ should_not_reach_here(); ++ } else { ++ far_jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id))); ++ } ++ bind(L); ++ } ++ // get oop results if there are any and reset the values in the thread ++ if (oop_result->is_valid()) { ++ get_vm_result(oop_result, xthread); ++ } ++ if (metadata_result->is_valid()) { ++ get_vm_result_2(metadata_result, xthread); ++ } ++ return call_offset; ++} ++ ++int StubAssembler::call_RT(Register oop_result, Register metadata_result, address entry, Register arg1) { ++ mv(c_rarg1, arg1); ++ return call_RT(oop_result, metadata_result, entry, 1); ++} ++ ++int StubAssembler::call_RT(Register oop_result, Register metadata_result, address entry, Register arg1, Register arg2) { ++ const int arg_num = 2; ++ if (c_rarg1 == arg2) { ++ if (c_rarg2 == arg1) { ++ xorr(arg1, arg1, arg2); ++ xorr(arg2, arg1, arg2); ++ xorr(arg1, arg1, arg2); ++ } else { ++ mv(c_rarg2, arg2); ++ mv(c_rarg1, arg1); ++ } ++ } else { ++ mv(c_rarg1, arg1); ++ mv(c_rarg2, arg2); ++ } ++ return call_RT(oop_result, metadata_result, entry, arg_num); ++} ++ ++int StubAssembler::call_RT(Register oop_result, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3) { ++ const int arg_num = 3; ++ // if there is any conflict use the stack ++ if (arg1 == c_rarg2 || arg1 == c_rarg3 || ++ arg2 == c_rarg1 || arg2 == c_rarg3 || ++ arg3 == c_rarg1 || arg3 == c_rarg2) { ++ const int arg1_sp_offset = 0; ++ const int arg2_sp_offset = 1; ++ const int arg3_sp_offset = 2; ++ addi(sp, sp, -(arg_num + 1) * wordSize); ++ sd(arg1, Address(sp, arg1_sp_offset * wordSize)); ++ sd(arg2, Address(sp, arg2_sp_offset * wordSize)); ++ sd(arg3, Address(sp, arg3_sp_offset * wordSize)); ++ ++ ld(c_rarg1, Address(sp, arg1_sp_offset * wordSize)); ++ ld(c_rarg2, Address(sp, arg2_sp_offset * wordSize)); ++ ld(c_rarg3, Address(sp, arg3_sp_offset * wordSize)); ++ addi(sp, sp, (arg_num + 1) * wordSize); ++ } else { ++ mv(c_rarg1, arg1); ++ mv(c_rarg2, arg2); ++ mv(c_rarg3, arg3); ++ } ++ return call_RT(oop_result, metadata_result, entry, arg_num); ++} ++ ++enum return_state_t { ++ does_not_return, requires_return ++}; ++ ++// Implementation of StubFrame ++ ++class StubFrame: public StackObj { ++ private: ++ StubAssembler* _sasm; ++ bool _return_state; ++ ++ public: ++ StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, return_state_t return_state=requires_return); ++ void load_argument(int offset_in_words, Register reg); ++ ++ ~StubFrame(); ++};; ++ ++void StubAssembler::prologue(const char* name, bool must_gc_arguments) { ++ set_info(name, must_gc_arguments); ++ enter(); ++} ++ ++void StubAssembler::epilogue() { ++ leave(); ++ ret(); ++} ++ ++#define __ _sasm-> ++ ++StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, return_state_t return_state) { ++ _sasm = sasm; ++ _return_state = return_state; ++ __ prologue(name, must_gc_arguments); ++} ++ ++// load parameters that were stored with LIR_Assembler::store_parameter ++// Note: offsets for store_parameter and load_argument must match ++void StubFrame::load_argument(int offset_in_words, Register reg) { ++ __ load_parameter(offset_in_words, reg); ++} ++ ++ ++StubFrame::~StubFrame() { ++ if (_return_state == requires_return) { ++ __ epilogue(); ++ } else { ++ __ should_not_reach_here(); ++ } ++ _sasm = NULL; ++} ++ ++#undef __ ++ ++ ++// Implementation of Runtime1 ++ ++#define __ sasm-> ++ ++const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2; ++ ++// Stack layout for saving/restoring all the registers needed during a runtime ++// call (this includes deoptimization) ++// Note: note that users of this frame may well have arguments to some runtime ++// while these values are on the stack. These positions neglect those arguments ++// but the code in save_live_registers will take the argument count into ++// account. ++// ++ ++enum reg_save_layout { ++ reg_save_frame_size = 32 /* float */ + 30 /* integer excluding x3, x4 */ ++}; ++ ++// Save off registers which might be killed by calls into the runtime. ++// Tries to smart of about FPU registers. In particular we separate ++// saving and describing the FPU registers for deoptimization since we ++// have to save the FPU registers twice if we describe them. The ++// deopt blob is the only thing which needs to describe FPU registers. ++// In all other cases it should be sufficient to simply save their ++// current value. ++ ++static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs]; ++static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs]; ++ ++static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) { ++ int frame_size_in_bytes = reg_save_frame_size * BytesPerWord; ++ sasm->set_frame_size(frame_size_in_bytes / BytesPerWord); ++ int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); ++ OopMap* oop_map = new OopMap(frame_size_in_slots, 0); ++ assert_cond(oop_map != NULL); ++ ++ // caller save registers only, see FrameMap::initialize ++ // in c1_FrameMap_riscv.cpp for detail. ++ const static Register caller_save_cpu_regs[FrameMap::max_nof_caller_save_cpu_regs] = { ++ x7, x10, x11, x12, x13, x14, x15, x16, x17, x28, x29, x30, x31 ++ }; ++ ++ for (int i = 0; i < FrameMap::max_nof_caller_save_cpu_regs; i++) { ++ Register r = caller_save_cpu_regs[i]; ++ int sp_offset = cpu_reg_save_offsets[r->encoding()]; ++ oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), ++ r->as_VMReg()); ++ } ++ ++ // fpu_regs ++ if (save_fpu_registers) { ++ for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { ++ FloatRegister r = as_FloatRegister(i); ++ int sp_offset = fpu_reg_save_offsets[i]; ++ oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), ++ r->as_VMReg()); ++ } ++ } ++ return oop_map; ++} ++ ++static OopMap* save_live_registers(StubAssembler* sasm, ++ bool save_fpu_registers = true) { ++ __ block_comment("save_live_registers"); ++ ++ // if the number of pushed regs is odd, one slot will be reserved for alignment ++ __ push_reg(RegSet::range(x5, x31), sp); // integer registers except ra(x1) & sp(x2) & gp(x3) & tp(x4) ++ ++ if (save_fpu_registers) { ++ // float registers ++ __ addi(sp, sp, -(FrameMap::nof_fpu_regs * wordSize)); ++ for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { ++ __ fsd(as_FloatRegister(i), Address(sp, i * wordSize)); ++ } ++ } else { ++ // we define reg_save_layout = 62 as the fixed frame size, ++ // we should also sub 32 * wordSize to sp when save_fpu_registers == false ++ __ addi(sp, sp, -32 * wordSize); ++ } ++ ++ return generate_oop_map(sasm, save_fpu_registers); ++} ++ ++static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) { ++ if (restore_fpu_registers) { ++ for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { ++ __ fld(as_FloatRegister(i), Address(sp, i * wordSize)); ++ } ++ __ addi(sp, sp, FrameMap::nof_fpu_regs * wordSize); ++ } else { ++ // we define reg_save_layout = 64 as the fixed frame size, ++ // we should also add 32 * wordSize to sp when save_fpu_registers == false ++ __ addi(sp, sp, 32 * wordSize); ++ } ++ ++ // if the number of popped regs is odd, the reserved slot for alignment will be removed ++ __ pop_reg(RegSet::range(x5, x31), sp); // integer registers except ra(x1) & sp(x2) & gp(x3) & tp(x4) ++} ++ ++static void restore_live_registers_except_r10(StubAssembler* sasm, bool restore_fpu_registers = true) { ++ if (restore_fpu_registers) { ++ for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { ++ __ fld(as_FloatRegister(i), Address(sp, i * wordSize)); ++ } ++ __ addi(sp, sp, FrameMap::nof_fpu_regs * wordSize); ++ } else { ++ // we define reg_save_layout = 64 as the fixed frame size, ++ // we should also add 32 * wordSize to sp when save_fpu_registers == false ++ __ addi(sp, sp, 32 * wordSize); ++ } ++ ++ // pop integer registers except ra(x1) & sp(x2) & gp(x3) & tp(x4) & x10 ++ // there is one reserved slot for alignment on the stack in save_live_registers(). ++ __ pop_reg(RegSet::range(x5, x9), sp); // pop x5 ~ x9 with the reserved slot for alignment ++ __ pop_reg(RegSet::range(x11, x31), sp); // pop x11 ~ x31; x10 will be automatically skipped here ++} ++ ++void Runtime1::initialize_pd() { ++ int i = 0; ++ int sp_offset = 0; ++ const int step = 2; // SP offsets are in halfwords ++ ++ // all float registers are saved explicitly ++ for (i = 0; i < FrameMap::nof_fpu_regs; i++) { ++ fpu_reg_save_offsets[i] = sp_offset; ++ sp_offset += step; ++ } ++ ++ // a slot reserved for stack 16-byte alignment, see MacroAssembler::push_reg ++ sp_offset += step; ++ // we save x5 ~ x31, except x0 ~ x4: loop starts from x5 ++ for (i = 5; i < FrameMap::nof_cpu_regs; i++) { ++ cpu_reg_save_offsets[i] = sp_offset; ++ sp_offset += step; ++ } ++} ++ ++// target: the entry point of the method that creates and posts the exception oop ++// has_argument: true if the exception needs arguments (passed in t0 and t1) ++ ++OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) { ++ // make a frame and preserve the caller's caller-save registers ++ OopMap* oop_map = save_live_registers(sasm); ++ assert_cond(oop_map != NULL); ++ int call_offset = 0; ++ if (!has_argument) { ++ call_offset = __ call_RT(noreg, noreg, target); ++ } else { ++ __ mv(c_rarg1, t0); ++ __ mv(c_rarg2, t1); ++ call_offset = __ call_RT(noreg, noreg, target); ++ } ++ OopMapSet* oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, oop_map); ++ ++ return oop_maps; ++} ++ ++OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) { ++ __ block_comment("generate_handle_exception"); ++ ++ // incoming parameters ++ const Register exception_oop = x10; ++ const Register exception_pc = x13; ++ ++ OopMapSet* oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ OopMap* oop_map = NULL; ++ ++ switch (id) { ++ case forward_exception_id: ++ // We're handling an exception in the context of a compiled frame. ++ // The registers have been saved in the standard places. Perform ++ // an exception lookup in the caller and dispatch to the handler ++ // if found. Otherwise unwind and dispatch to the callers ++ // exception handler. ++ oop_map = generate_oop_map(sasm, 1 /* thread */); ++ ++ // load and clear pending exception oop into x10 ++ __ ld(exception_oop, Address(xthread, Thread::pending_exception_offset())); ++ __ sd(zr, Address(xthread, Thread::pending_exception_offset())); ++ ++ // load issuing PC (the return address for this stub) into x13 ++ __ ld(exception_pc, Address(fp, frame::return_addr_offset * BytesPerWord)); ++ ++ // make sure that the vm_results are cleared (may be unnecessary) ++ __ sd(zr, Address(xthread, JavaThread::vm_result_offset())); ++ __ sd(zr, Address(xthread, JavaThread::vm_result_2_offset())); ++ break; ++ case handle_exception_nofpu_id: ++ case handle_exception_id: ++ // At this point all registers MAY be live. ++ oop_map = save_live_registers(sasm, id != handle_exception_nofpu_id); ++ break; ++ case handle_exception_from_callee_id: { ++ // At this point all registers except exception oop (x10) and ++ // exception pc (ra) are dead. ++ const int frame_size = 2 /* fp, return address */; ++ oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0); ++ sasm->set_frame_size(frame_size); ++ break; ++ } ++ default: ShouldNotReachHere(); ++ } ++ ++ // verify that only x10 and x13 are valid at this time ++ __ invalidate_registers(false, true, true, false, true, true); ++ // verify that x10 contains a valid exception ++ __ verify_not_null_oop(exception_oop); ++ ++#ifdef ASSERT ++ // check that fields in JavaThread for exception oop and issuing pc are ++ // empty before writing to them ++ Label oop_empty; ++ __ ld(t0, Address(xthread, JavaThread::exception_oop_offset())); ++ __ beqz(t0, oop_empty); ++ __ stop("exception oop already set"); ++ __ bind(oop_empty); ++ ++ Label pc_empty; ++ __ ld(t0, Address(xthread, JavaThread::exception_pc_offset())); ++ __ beqz(t0, pc_empty); ++ __ stop("exception pc already set"); ++ __ bind(pc_empty); ++#endif ++ ++ // save exception oop and issuing pc into JavaThread ++ // (exception handler will load it from here) ++ __ sd(exception_oop, Address(xthread, JavaThread::exception_oop_offset())); ++ __ sd(exception_pc, Address(xthread, JavaThread::exception_pc_offset())); ++ ++ // patch throwing pc into return address (has bci & oop map) ++ __ sd(exception_pc, Address(fp, frame::return_addr_offset * BytesPerWord)); ++ ++ // compute the exception handler. ++ // the exception oop and the throwing pc are read from the fields in JavaThread ++ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); ++ guarantee(oop_map != NULL, "NULL oop_map!"); ++ oop_maps->add_gc_map(call_offset, oop_map); ++ ++ // x10: handler address ++ // will be the deopt blob if nmethod was deoptimized while we looked up ++ // handler regardless of whether handler existed in the nmethod. ++ ++ // only x10 is valid at this time, all other registers have been destroyed by the runtime call ++ __ invalidate_registers(false, true, true, true, true, true); ++ ++ // patch the return address, this stub will directly return to the exception handler ++ __ sd(x10, Address(fp, frame::return_addr_offset * BytesPerWord)); ++ ++ switch (id) { ++ case forward_exception_id: ++ case handle_exception_nofpu_id: ++ case handle_exception_id: ++ // Restore the registers that were saved at the beginning. ++ restore_live_registers(sasm, id != handle_exception_nofpu_id); ++ break; ++ case handle_exception_from_callee_id: ++ break; ++ default: ShouldNotReachHere(); ++ } ++ ++ return oop_maps; ++} ++ ++ ++void Runtime1::generate_unwind_exception(StubAssembler *sasm) { ++ // incoming parameters ++ const Register exception_oop = x10; ++ // other registers used in this stub ++ const Register handler_addr = x11; ++ ++ // verify that only x10, is valid at this time ++ __ invalidate_registers(false, true, true, true, true, true); ++ ++#ifdef ASSERT ++ // check that fields in JavaThread for exception oop and issuing pc are empty ++ Label oop_empty; ++ __ ld(t0, Address(xthread, JavaThread::exception_oop_offset())); ++ __ beqz(t0, oop_empty); ++ __ stop("exception oop must be empty"); ++ __ bind(oop_empty); ++ ++ Label pc_empty; ++ __ ld(t0, Address(xthread, JavaThread::exception_pc_offset())); ++ __ beqz(t0, pc_empty); ++ __ stop("exception pc must be empty"); ++ __ bind(pc_empty); ++#endif ++ ++ // Save our return address because ++ // exception_handler_for_return_address will destroy it. We also ++ // save exception_oop ++ __ addi(sp, sp, -2 * wordSize); ++ __ sd(exception_oop, Address(sp, wordSize)); ++ __ sd(ra, Address(sp)); ++ ++ // search the exception handler address of the caller (using the return address) ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), xthread, ra); ++ // x10: exception handler address of the caller ++ ++ // Only x10 is valid at this time; all other registers have been ++ // destroyed by the call. ++ __ invalidate_registers(false, true, true, true, false, true); ++ ++ // move result of call into correct register ++ __ mv(handler_addr, x10); ++ ++ // get throwing pc (= return address). ++ // ra has been destroyed by the call ++ __ ld(ra, Address(sp)); ++ __ ld(exception_oop, Address(sp, wordSize)); ++ __ addi(sp, sp, 2 * wordSize); ++ __ mv(x13, ra); ++ ++ __ verify_not_null_oop(exception_oop); ++ ++ // continue at exception handler (return address removed) ++ // note: do *not* remove arguments when unwinding the ++ // activation since the caller assumes having ++ // all arguments on the stack when entering the ++ // runtime to determine the exception handler ++ // (GC happens at call site with arguments!) ++ // x10: exception oop ++ // x13: throwing pc ++ // x11: exception handler ++ __ jr(handler_addr); ++} ++ ++OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { ++ // use the maximum number of runtime-arguments here because it is difficult to ++ // distinguish each RT-Call. ++ // Note: This number affects also the RT-Call in generate_handle_exception because ++ // the oop-map is shared for all calls. ++ DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); ++ assert(deopt_blob != NULL, "deoptimization blob must have been created"); ++ ++ OopMap* oop_map = save_live_registers(sasm); ++ assert_cond(oop_map != NULL); ++ ++ __ mv(c_rarg0, xthread); ++ Label retaddr; ++ __ set_last_Java_frame(sp, fp, retaddr, t0); ++ // do the call ++ RuntimeAddress addr(target); ++ __ relocate(addr.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, addr, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ __ bind(retaddr); ++ OopMapSet* oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(__ offset(), oop_map); ++ // verify callee-saved register ++#ifdef ASSERT ++ { Label L; ++ __ get_thread(t0); ++ __ beq(xthread, t0, L); ++ __ stop("StubAssembler::call_RT: xthread not callee saved?"); ++ __ bind(L); ++ } ++#endif ++ __ reset_last_Java_frame(true); ++ ++#ifdef ASSERT ++ // Check that fields in JavaThread for exception oop and issuing pc are empty ++ Label oop_empty; ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ beqz(t0, oop_empty); ++ __ stop("exception oop must be empty"); ++ __ bind(oop_empty); ++ ++ Label pc_empty; ++ __ ld(t0, Address(xthread, JavaThread::exception_pc_offset())); ++ __ beqz(t0, pc_empty); ++ __ stop("exception pc must be empty"); ++ __ bind(pc_empty); ++#endif ++ ++ // Runtime will return true if the nmethod has been deoptimized, this is the ++ // expected scenario and anything else is an error. Note that we maintain a ++ // check on the result purely as a defensive measure. ++ Label no_deopt; ++ __ beqz(x10, no_deopt); // Have we deoptimized? ++ ++ // Perform a re-execute. The proper return address is already on the stack, ++ // we just need to restore registers, pop all of our frames but the return ++ // address and jump to the deopt blob. ++ ++ restore_live_registers(sasm); ++ __ leave(); ++ __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution())); ++ ++ __ bind(no_deopt); ++ __ stop("deopt not performed"); ++ ++ return oop_maps; ++} ++ ++OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { ++ // for better readability ++ const bool dont_gc_arguments = false; ++ ++ // default value; overwritten for some optimized stubs that are called from methods that do not use the fpu ++ bool save_fpu_registers = true; ++ ++ // stub code & info for the different stubs ++ OopMapSet* oop_maps = NULL; ++ switch (id) { ++ { ++ case forward_exception_id: ++ { ++ oop_maps = generate_handle_exception(id, sasm); ++ __ leave(); ++ __ ret(); ++ } ++ break; ++ ++ case throw_div0_exception_id: ++ { ++ StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments, does_not_return); ++ oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false); ++ } ++ break; ++ ++ case throw_null_pointer_exception_id: ++ { StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments, does_not_return); ++ oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); ++ } ++ break; ++ ++ case new_instance_id: ++ case fast_new_instance_id: ++ case fast_new_instance_init_check_id: ++ { ++ Register klass = x13; // Incoming ++ Register obj = x10; // Result ++ ++ if (id == new_instance_id) { ++ __ set_info("new_instance", dont_gc_arguments); ++ } else if (id == fast_new_instance_id) { ++ __ set_info("fast new_instance", dont_gc_arguments); ++ } else { ++ assert(id == fast_new_instance_init_check_id, "bad StubID"); ++ __ set_info("fast new_instance init check", dont_gc_arguments); ++ } ++ ++ // If TLAB is disabled, see if there is support for inlining contiguous ++ // allocations. ++ // Otherwise, just go to the slow path. ++ if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && ++ !UseTLAB && Universe::heap()->supports_inline_contig_alloc()) { ++ Label slow_path; ++ Register obj_size = x12; ++ Register tmp1 = x9; ++ Register tmp2 = x14; ++ assert_different_registers(klass, obj, obj_size, tmp1, tmp2); ++ ++ const int sp_offset = 2; ++ const int x9_offset = 1; ++ const int zr_offset = 0; ++ __ addi(sp, sp, -(sp_offset * wordSize)); ++ __ sd(x9, Address(sp, x9_offset * wordSize)); ++ __ sd(zr, Address(sp, zr_offset * wordSize)); ++ ++ if (id == fast_new_instance_init_check_id) { ++ // make sure the klass is initialized ++ __ lbu(t0, Address(klass, InstanceKlass::init_state_offset())); ++ __ mv(t1, InstanceKlass::fully_initialized); ++ __ bne(t0, t1, slow_path); ++ } ++ ++#ifdef ASSERT ++ // assert object can be fast path allocated ++ { ++ Label ok, not_ok; ++ __ lw(obj_size, Address(klass, Klass::layout_helper_offset())); ++ // make sure it's an instance. For instances, layout helper is a positive number. ++ // For arrays, layout helper is a negative number ++ __ blez(obj_size, not_ok); ++ __ andi(t0, obj_size, Klass::_lh_instance_slow_path_bit); ++ __ beqz(t0, ok); ++ __ bind(not_ok); ++ __ stop("assert(can be fast path allocated)"); ++ __ should_not_reach_here(); ++ __ bind(ok); ++ } ++#endif // ASSERT ++ ++ // get the instance size ++ __ lwu(obj_size, Address(klass, Klass::layout_helper_offset())); ++ ++ __ eden_allocate(obj, obj_size, 0, tmp1, slow_path); ++ ++ __ initialize_object(obj, klass, obj_size, 0, tmp1, tmp2, /* is_tlab_allocated */ false); ++ __ verify_oop(obj); ++ __ ld(x9, Address(sp, x9_offset * wordSize)); ++ __ ld(zr, Address(sp, zr_offset * wordSize)); ++ __ addi(sp, sp, sp_offset * wordSize); ++ __ ret(); ++ ++ __ bind(slow_path); ++ __ ld(x9, Address(sp, x9_offset * wordSize)); ++ __ ld(zr, Address(sp, zr_offset * wordSize)); ++ __ addi(sp, sp, sp_offset * wordSize); ++ } ++ ++ __ enter(); ++ OopMap* map = save_live_registers(sasm); ++ assert_cond(map != NULL); ++ int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass); ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, map); ++ restore_live_registers_except_r10(sasm); ++ __ verify_oop(obj); ++ __ leave(); ++ __ ret(); ++ ++ // x10: new instance ++ } ++ ++ break; ++ ++ case counter_overflow_id: ++ { ++ Register bci = x10; ++ Register method = x11; ++ __ enter(); ++ OopMap* map = save_live_registers(sasm); ++ assert_cond(map != NULL); ++ ++ const int bci_off = 0; ++ const int method_off = 1; ++ // Retrieve bci ++ __ lw(bci, Address(fp, bci_off * BytesPerWord)); ++ // And a pointer to the Method* ++ __ ld(method, Address(fp, method_off * BytesPerWord)); ++ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, map); ++ restore_live_registers(sasm); ++ __ leave(); ++ __ ret(); ++ } ++ break; ++ ++ case new_type_array_id: ++ case new_object_array_id: ++ { ++ Register length = x9; // Incoming ++ Register klass = x13; // Incoming ++ Register obj = x10; // Result ++ ++ if (id == new_type_array_id) { ++ __ set_info("new_type_array", dont_gc_arguments); ++ } else { ++ __ set_info("new_object_array", dont_gc_arguments); ++ } ++ ++#ifdef ASSERT ++ // assert object type is really an array of the proper kind ++ { ++ Label ok; ++ Register tmp = obj; ++ __ lwu(tmp, Address(klass, Klass::layout_helper_offset())); ++ __ sraiw(tmp, tmp, Klass::_lh_array_tag_shift); ++ int tag = ((id == new_type_array_id) ? Klass::_lh_array_tag_type_value : Klass::_lh_array_tag_obj_value); ++ __ mv(t0, tag); ++ __ beq(t0, tmp, ok); ++ __ stop("assert(is an array klass)"); ++ __ should_not_reach_here(); ++ __ bind(ok); ++ } ++#endif // ASSERT ++ ++ // If TLAB is disabled, see if there is support for inlining contiguous ++ // allocations. ++ // Otherwise, just go to the slow path. ++ if (!UseTLAB && Universe::heap()->supports_inline_contig_alloc()) { ++ Register arr_size = x14; ++ Register tmp1 = x12; ++ Register tmp2 = x15; ++ Label slow_path; ++ assert_different_registers(length, klass, obj, arr_size, tmp1, tmp2); ++ ++ // check that array length is small enough for fast path. ++ __ mv(t0, C1_MacroAssembler::max_array_allocation_length); ++ __ bgtu(length, t0, slow_path); ++ ++ // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) ++ __ lwu(tmp1, Address(klass, Klass::layout_helper_offset())); ++ __ andi(t0, tmp1, 0x1f); ++ __ sll(arr_size, length, t0); ++ int lh_header_size_width = exact_log2(Klass::_lh_header_size_mask + 1); ++ int lh_header_size_msb = Klass::_lh_header_size_shift + lh_header_size_width; ++ __ slli(tmp1, tmp1, XLEN - lh_header_size_msb); ++ __ srli(tmp1, tmp1, XLEN - lh_header_size_width); ++ __ add(arr_size, arr_size, tmp1); ++ __ addi(arr_size, arr_size, MinObjAlignmentInBytesMask); // align up ++ __ andi(arr_size, arr_size, ~(uint)MinObjAlignmentInBytesMask); ++ ++ __ eden_allocate(obj, arr_size, 0, tmp1, slow_path); // preserves arr_size ++ ++ __ initialize_header(obj, klass, length, tmp1, tmp2); ++ __ lbu(tmp1, Address(klass, ++ in_bytes(Klass::layout_helper_offset()) + ++ (Klass::_lh_header_size_shift / BitsPerByte))); ++ assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); ++ assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); ++ __ andi(tmp1, tmp1, Klass::_lh_header_size_mask); ++ __ sub(arr_size, arr_size, tmp1); // body length ++ __ add(tmp1, tmp1, obj); // body start ++ __ initialize_body(tmp1, arr_size, 0, tmp2); ++ __ membar(MacroAssembler::StoreStore); ++ __ verify_oop(obj); ++ ++ __ ret(); ++ ++ __ bind(slow_path); ++ } ++ ++ __ enter(); ++ OopMap* map = save_live_registers(sasm); ++ assert_cond(map != NULL); ++ int call_offset = 0; ++ if (id == new_type_array_id) { ++ call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length); ++ } else { ++ call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length); ++ } ++ ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, map); ++ restore_live_registers_except_r10(sasm); ++ ++ __ verify_oop(obj); ++ __ leave(); ++ __ ret(); ++ ++ // x10: new array ++ } ++ break; ++ ++ case new_multi_array_id: ++ { ++ StubFrame f(sasm, "new_multi_array", dont_gc_arguments); ++ // x10: klass ++ // x9: rank ++ // x12: address of 1st dimension ++ OopMap* map = save_live_registers(sasm); ++ assert_cond(map != NULL); ++ __ mv(c_rarg1, x10); ++ __ mv(c_rarg3, x12); ++ __ mv(c_rarg2, x9); ++ int call_offset = __ call_RT(x10, noreg, CAST_FROM_FN_PTR(address, new_multi_array), x11, x12, x13); ++ ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, map); ++ restore_live_registers_except_r10(sasm); ++ ++ // x10: new multi array ++ __ verify_oop(x10); ++ } ++ break; ++ ++ case register_finalizer_id: ++ { ++ __ set_info("register_finalizer", dont_gc_arguments); ++ ++ // This is called via call_runtime so the arguments ++ // will be place in C abi locations ++ __ verify_oop(c_rarg0); ++ ++ // load the klass and check the has finalizer flag ++ Label register_finalizer; ++ Register t = x15; ++ __ load_klass(t, x10); ++ __ lwu(t, Address(t, Klass::access_flags_offset())); ++ __ test_bit(t0, t, exact_log2(JVM_ACC_HAS_FINALIZER)); ++ __ bnez(t0, register_finalizer); ++ __ ret(); ++ ++ __ bind(register_finalizer); ++ __ enter(); ++ OopMap* oop_map = save_live_registers(sasm); ++ assert_cond(oop_map != NULL); ++ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), x10); ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, oop_map); ++ ++ // Now restore all the live registers ++ restore_live_registers(sasm); ++ ++ __ leave(); ++ __ ret(); ++ } ++ break; ++ ++ case throw_class_cast_exception_id: ++ { ++ StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments, does_not_return); ++ oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true); ++ } ++ break; ++ ++ case throw_incompatible_class_change_error_id: ++ { ++ StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments, does_not_return); ++ oop_maps = generate_exception_throw(sasm, ++ CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false); ++ } ++ break; ++ ++ case slow_subtype_check_id: ++ { ++ // Typical calling sequence: ++ // push klass_RInfo (object klass or other subclass) ++ // push sup_k_RInfo (array element klass or other superclass) ++ // jump to slow_subtype_check ++ // Note that the subclass is pushed first, and is therefore deepest. ++ enum layout { ++ x10_off, x10_off_hi, ++ x12_off, x12_off_hi, ++ x14_off, x14_off_hi, ++ x15_off, x15_off_hi, ++ sup_k_off, sup_k_off_hi, ++ klass_off, klass_off_hi, ++ framesize, ++ result_off = sup_k_off ++ }; ++ ++ __ set_info("slow_subtype_check", dont_gc_arguments); ++ __ push_reg(RegSet::of(x10, x12, x14, x15), sp); ++ ++ __ ld(x14, Address(sp, (klass_off) * VMRegImpl::stack_slot_size)); // sub klass ++ __ ld(x10, Address(sp, (sup_k_off) * VMRegImpl::stack_slot_size)); // super klass ++ ++ Label miss; ++ __ check_klass_subtype_slow_path(x14, x10, x12, x15, NULL, &miss); ++ ++ // fallthrough on success: ++ __ mv(t0, 1); ++ __ sd(t0, Address(sp, (result_off) * VMRegImpl::stack_slot_size)); // result ++ __ pop_reg(RegSet::of(x10, x12, x14, x15), sp); ++ __ ret(); ++ ++ __ bind(miss); ++ __ sd(zr, Address(sp, (result_off) * VMRegImpl::stack_slot_size)); // result ++ __ pop_reg(RegSet::of(x10, x12, x14, x15), sp); ++ __ ret(); ++ } ++ break; ++ ++ case monitorenter_nofpu_id: ++ save_fpu_registers = false; ++ // fall through ++ case monitorenter_id: ++ { ++ StubFrame f(sasm, "monitorenter", dont_gc_arguments); ++ OopMap* map = save_live_registers(sasm, save_fpu_registers); ++ assert_cond(map != NULL); ++ ++ // Called with store_parameter and not C abi ++ f.load_argument(1, x10); // x10: object ++ f.load_argument(0, x11); // x11: lock address ++ ++ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), x10, x11); ++ ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, map); ++ restore_live_registers(sasm, save_fpu_registers); ++ } ++ break; ++ ++ case monitorexit_nofpu_id: ++ save_fpu_registers = false; ++ // fall through ++ case monitorexit_id: ++ { ++ StubFrame f(sasm, "monitorexit", dont_gc_arguments); ++ OopMap* map = save_live_registers(sasm, save_fpu_registers); ++ assert_cond(map != NULL); ++ ++ // Called with store_parameter and not C abi ++ f.load_argument(0, x10); // x10: lock address ++ ++ // note: really a leaf routine but must setup last java sp ++ // => use call_RT for now (speed can be improved by ++ // doing last java sp setup manually) ++ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), x10); ++ ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, map); ++ restore_live_registers(sasm, save_fpu_registers); ++ } ++ break; ++ ++ case deoptimize_id: ++ { ++ StubFrame f(sasm, "deoptimize", dont_gc_arguments, does_not_return); ++ OopMap* oop_map = save_live_registers(sasm); ++ assert_cond(oop_map != NULL); ++ f.load_argument(0, c_rarg1); ++ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize), c_rarg1); ++ ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, oop_map); ++ restore_live_registers(sasm); ++ DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); ++ assert(deopt_blob != NULL, "deoptimization blob must have been created"); ++ __ leave(); ++ __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution())); ++ } ++ break; ++ ++ case throw_range_check_failed_id: ++ { ++ StubFrame f(sasm, "range_check_failed", dont_gc_arguments, does_not_return); ++ oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true); ++ } ++ break; ++ ++ case unwind_exception_id: ++ { ++ __ set_info("unwind_exception", dont_gc_arguments); ++ // note: no stubframe since we are about to leave the current ++ // activation and we are calling a leaf VM function only. ++ generate_unwind_exception(sasm); ++ } ++ break; ++ ++ case access_field_patching_id: ++ { ++ StubFrame f(sasm, "access_field_patching", dont_gc_arguments, does_not_return); ++ // we should set up register map ++ oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, access_field_patching)); ++ } ++ break; ++ ++ case load_klass_patching_id: ++ { ++ StubFrame f(sasm, "load_klass_patching", dont_gc_arguments, does_not_return); ++ // we should set up register map ++ oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching)); ++ } ++ break; ++ ++ case load_mirror_patching_id: ++ { ++ StubFrame f(sasm, "load_mirror_patching", dont_gc_arguments, does_not_return); ++ // we should set up register map ++ oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); ++ } ++ break; ++ ++ case load_appendix_patching_id: ++ { ++ StubFrame f(sasm, "load_appendix_patching", dont_gc_arguments, does_not_return); ++ // we should set up register map ++ oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching)); ++ } ++ break; ++ ++ case handle_exception_nofpu_id: ++ case handle_exception_id: ++ { ++ StubFrame f(sasm, "handle_exception", dont_gc_arguments); ++ oop_maps = generate_handle_exception(id, sasm); ++ } ++ break; ++ ++ case handle_exception_from_callee_id: ++ { ++ StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments); ++ oop_maps = generate_handle_exception(id, sasm); ++ } ++ break; ++ ++ case throw_index_exception_id: ++ { ++ StubFrame f(sasm, "index_range_check_failed", dont_gc_arguments, does_not_return); ++ oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true); ++ } ++ break; ++ ++ case throw_array_store_exception_id: ++ { ++ StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments, does_not_return); ++ // tos + 0: link ++ // + 1: return address ++ oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true); ++ } ++ break; ++ ++ case predicate_failed_trap_id: ++ { ++ StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments, does_not_return); ++ ++ OopMap* map = save_live_registers(sasm); ++ assert_cond(map != NULL); ++ ++ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap)); ++ oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ oop_maps->add_gc_map(call_offset, map); ++ restore_live_registers(sasm); ++ __ leave(); ++ DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); ++ assert(deopt_blob != NULL, "deoptimization blob must have been created"); ++ ++ __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution())); ++ } ++ break; ++ ++ case dtrace_object_alloc_id: ++ { // c_rarg0: object ++ StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments); ++ save_live_registers(sasm); ++ ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), c_rarg0); ++ ++ restore_live_registers(sasm); ++ } ++ break; ++ ++ default: ++ { ++ StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return); ++ __ mv(x10, (int)id); ++ __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), x10); ++ __ should_not_reach_here(); ++ } ++ break; ++ } ++ } ++ return oop_maps; ++} ++ ++#undef __ ++ ++const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); return 0; } +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c1_globals_riscv.hpp +@@ -0,0 +1,65 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C1_GLOBALS_RISCV_HPP ++#define CPU_RISCV_C1_GLOBALS_RISCV_HPP ++ ++#include "utilities/globalDefinitions.hpp" ++#include "utilities/macros.hpp" ++ ++// Sets the default values for platform dependent flags used by the client compiler. ++// (see c1_globals.hpp) ++ ++#ifndef COMPILER2 ++define_pd_global(bool, BackgroundCompilation, true ); ++define_pd_global(bool, InlineIntrinsics, true ); ++define_pd_global(bool, PreferInterpreterNativeStubs, false); ++define_pd_global(bool, ProfileTraps, false); ++define_pd_global(bool, UseOnStackReplacement, true ); ++define_pd_global(bool, TieredCompilation, false); ++define_pd_global(intx, CompileThreshold, 1500 ); ++ ++define_pd_global(intx, OnStackReplacePercentage, 933 ); ++define_pd_global(intx, NewSizeThreadIncrease, 4*K ); ++define_pd_global(intx, InitialCodeCacheSize, 160*K); ++define_pd_global(intx, ReservedCodeCacheSize, 32*M ); ++define_pd_global(intx, NonProfiledCodeHeapSize, 13*M ); ++define_pd_global(intx, ProfiledCodeHeapSize, 14*M ); ++define_pd_global(intx, NonNMethodCodeHeapSize, 5*M ); ++define_pd_global(bool, ProfileInterpreter, false); ++define_pd_global(intx, CodeCacheExpansionSize, 32*K ); ++define_pd_global(uintx, CodeCacheMinBlockLength, 1); ++define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K); ++define_pd_global(bool, NeverActAsServerClassMachine, true ); ++define_pd_global(uint64_t, MaxRAM, 1ULL*G); ++define_pd_global(bool, CICompileOSR, true ); ++#endif // !COMPILER2 ++define_pd_global(bool, UseTypeProfile, false); ++ ++define_pd_global(bool, OptimizeSinglePrecision, true ); ++define_pd_global(bool, CSEArrayLength, false); ++define_pd_global(bool, TwoOperandLIRForm, false); ++ ++#endif // CPU_RISCV_C1_GLOBALS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +@@ -0,0 +1,1644 @@ ++/* ++ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "asm/assembler.inline.hpp" ++#include "opto/c2_MacroAssembler.hpp" ++#include "opto/intrinsicnode.hpp" ++#include "opto/subnode.hpp" ++#include "runtime/stubRoutines.hpp" ++ ++#ifdef PRODUCT ++#define BLOCK_COMMENT(str) /* nothing */ ++#define STOP(error) stop(error) ++#else ++#define BLOCK_COMMENT(str) block_comment(str) ++#define STOP(error) block_comment(error); stop(error) ++#endif ++ ++#define BIND(label) bind(label); BLOCK_COMMENT(#label ":") ++ ++// short string ++// StringUTF16.indexOfChar ++// StringLatin1.indexOfChar ++void C2_MacroAssembler::string_indexof_char_short(Register str1, Register cnt1, ++ Register ch, Register result, ++ bool isL) ++{ ++ Register ch1 = t0; ++ Register index = t1; ++ ++ BLOCK_COMMENT("string_indexof_char_short {"); ++ ++ Label LOOP, LOOP1, LOOP4, LOOP8; ++ Label MATCH, MATCH1, MATCH2, MATCH3, ++ MATCH4, MATCH5, MATCH6, MATCH7, NOMATCH; ++ ++ mv(result, -1); ++ mv(index, zr); ++ ++ bind(LOOP); ++ addi(t0, index, 8); ++ ble(t0, cnt1, LOOP8); ++ addi(t0, index, 4); ++ ble(t0, cnt1, LOOP4); ++ j(LOOP1); ++ ++ bind(LOOP8); ++ isL ? lbu(ch1, Address(str1, 0)) : lhu(ch1, Address(str1, 0)); ++ beq(ch, ch1, MATCH); ++ isL ? lbu(ch1, Address(str1, 1)) : lhu(ch1, Address(str1, 2)); ++ beq(ch, ch1, MATCH1); ++ isL ? lbu(ch1, Address(str1, 2)) : lhu(ch1, Address(str1, 4)); ++ beq(ch, ch1, MATCH2); ++ isL ? lbu(ch1, Address(str1, 3)) : lhu(ch1, Address(str1, 6)); ++ beq(ch, ch1, MATCH3); ++ isL ? lbu(ch1, Address(str1, 4)) : lhu(ch1, Address(str1, 8)); ++ beq(ch, ch1, MATCH4); ++ isL ? lbu(ch1, Address(str1, 5)) : lhu(ch1, Address(str1, 10)); ++ beq(ch, ch1, MATCH5); ++ isL ? lbu(ch1, Address(str1, 6)) : lhu(ch1, Address(str1, 12)); ++ beq(ch, ch1, MATCH6); ++ isL ? lbu(ch1, Address(str1, 7)) : lhu(ch1, Address(str1, 14)); ++ beq(ch, ch1, MATCH7); ++ addi(index, index, 8); ++ addi(str1, str1, isL ? 8 : 16); ++ blt(index, cnt1, LOOP); ++ j(NOMATCH); ++ ++ bind(LOOP4); ++ isL ? lbu(ch1, Address(str1, 0)) : lhu(ch1, Address(str1, 0)); ++ beq(ch, ch1, MATCH); ++ isL ? lbu(ch1, Address(str1, 1)) : lhu(ch1, Address(str1, 2)); ++ beq(ch, ch1, MATCH1); ++ isL ? lbu(ch1, Address(str1, 2)) : lhu(ch1, Address(str1, 4)); ++ beq(ch, ch1, MATCH2); ++ isL ? lbu(ch1, Address(str1, 3)) : lhu(ch1, Address(str1, 6)); ++ beq(ch, ch1, MATCH3); ++ addi(index, index, 4); ++ addi(str1, str1, isL ? 4 : 8); ++ bge(index, cnt1, NOMATCH); ++ ++ bind(LOOP1); ++ isL ? lbu(ch1, Address(str1)) : lhu(ch1, Address(str1)); ++ beq(ch, ch1, MATCH); ++ addi(index, index, 1); ++ addi(str1, str1, isL ? 1 : 2); ++ blt(index, cnt1, LOOP1); ++ j(NOMATCH); ++ ++ bind(MATCH1); ++ addi(index, index, 1); ++ j(MATCH); ++ ++ bind(MATCH2); ++ addi(index, index, 2); ++ j(MATCH); ++ ++ bind(MATCH3); ++ addi(index, index, 3); ++ j(MATCH); ++ ++ bind(MATCH4); ++ addi(index, index, 4); ++ j(MATCH); ++ ++ bind(MATCH5); ++ addi(index, index, 5); ++ j(MATCH); ++ ++ bind(MATCH6); ++ addi(index, index, 6); ++ j(MATCH); ++ ++ bind(MATCH7); ++ addi(index, index, 7); ++ ++ bind(MATCH); ++ mv(result, index); ++ bind(NOMATCH); ++ BLOCK_COMMENT("} string_indexof_char_short"); ++} ++ ++// StringUTF16.indexOfChar ++// StringLatin1.indexOfChar ++void C2_MacroAssembler::string_indexof_char(Register str1, Register cnt1, ++ Register ch, Register result, ++ Register tmp1, Register tmp2, ++ Register tmp3, Register tmp4, ++ bool isL) ++{ ++ Label CH1_LOOP, HIT, NOMATCH, DONE, DO_LONG; ++ Register ch1 = t0; ++ Register orig_cnt = t1; ++ Register mask1 = tmp3; ++ Register mask2 = tmp2; ++ Register match_mask = tmp1; ++ Register trailing_char = tmp4; ++ Register unaligned_elems = tmp4; ++ ++ BLOCK_COMMENT("string_indexof_char {"); ++ beqz(cnt1, NOMATCH); ++ ++ addi(t0, cnt1, isL ? -32 : -16); ++ bgtz(t0, DO_LONG); ++ string_indexof_char_short(str1, cnt1, ch, result, isL); ++ j(DONE); ++ ++ bind(DO_LONG); ++ mv(orig_cnt, cnt1); ++ if (AvoidUnalignedAccesses) { ++ Label ALIGNED; ++ andi(unaligned_elems, str1, 0x7); ++ beqz(unaligned_elems, ALIGNED); ++ sub(unaligned_elems, unaligned_elems, 8); ++ neg(unaligned_elems, unaligned_elems); ++ if (!isL) { ++ srli(unaligned_elems, unaligned_elems, 1); ++ } ++ // do unaligned part per element ++ string_indexof_char_short(str1, unaligned_elems, ch, result, isL); ++ bgez(result, DONE); ++ mv(orig_cnt, cnt1); ++ sub(cnt1, cnt1, unaligned_elems); ++ bind(ALIGNED); ++ } ++ ++ // duplicate ch ++ if (isL) { ++ slli(ch1, ch, 8); ++ orr(ch, ch1, ch); ++ } ++ slli(ch1, ch, 16); ++ orr(ch, ch1, ch); ++ slli(ch1, ch, 32); ++ orr(ch, ch1, ch); ++ ++ if (!isL) { ++ slli(cnt1, cnt1, 1); ++ } ++ ++ uint64_t mask0101 = UCONST64(0x0101010101010101); ++ uint64_t mask0001 = UCONST64(0x0001000100010001); ++ mv(mask1, isL ? mask0101 : mask0001); ++ uint64_t mask7f7f = UCONST64(0x7f7f7f7f7f7f7f7f); ++ uint64_t mask7fff = UCONST64(0x7fff7fff7fff7fff); ++ mv(mask2, isL ? mask7f7f : mask7fff); ++ ++ bind(CH1_LOOP); ++ ld(ch1, Address(str1)); ++ addi(str1, str1, 8); ++ addi(cnt1, cnt1, -8); ++ compute_match_mask(ch1, ch, match_mask, mask1, mask2); ++ bnez(match_mask, HIT); ++ bgtz(cnt1, CH1_LOOP); ++ j(NOMATCH); ++ ++ bind(HIT); ++ ctzc_bit(trailing_char, match_mask, isL, ch1, result); ++ srli(trailing_char, trailing_char, 3); ++ addi(cnt1, cnt1, 8); ++ ble(cnt1, trailing_char, NOMATCH); ++ // match case ++ if (!isL) { ++ srli(cnt1, cnt1, 1); ++ srli(trailing_char, trailing_char, 1); ++ } ++ ++ sub(result, orig_cnt, cnt1); ++ add(result, result, trailing_char); ++ j(DONE); ++ ++ bind(NOMATCH); ++ mv(result, -1); ++ ++ bind(DONE); ++ BLOCK_COMMENT("} string_indexof_char"); ++} ++ ++typedef void (MacroAssembler::* load_chr_insn)(Register rd, const Address &adr, Register temp); ++ ++// Search for needle in haystack and return index or -1 ++// x10: result ++// x11: haystack ++// x12: haystack_len ++// x13: needle ++// x14: needle_len ++void C2_MacroAssembler::string_indexof(Register haystack, Register needle, ++ Register haystack_len, Register needle_len, ++ Register tmp1, Register tmp2, ++ Register tmp3, Register tmp4, ++ Register tmp5, Register tmp6, ++ Register result, int ae) ++{ ++ assert(ae != StrIntrinsicNode::LU, "Invalid encoding"); ++ ++ Label LINEARSEARCH, LINEARSTUB, DONE, NOMATCH; ++ ++ Register ch1 = t0; ++ Register ch2 = t1; ++ Register nlen_tmp = tmp1; // needle len tmp ++ Register hlen_tmp = tmp2; // haystack len tmp ++ Register result_tmp = tmp4; ++ ++ bool isLL = ae == StrIntrinsicNode::LL; ++ ++ bool needle_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UL; ++ bool haystack_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::LU; ++ int needle_chr_shift = needle_isL ? 0 : 1; ++ int haystack_chr_shift = haystack_isL ? 0 : 1; ++ int needle_chr_size = needle_isL ? 1 : 2; ++ int haystack_chr_size = haystack_isL ? 1 : 2; ++ load_chr_insn needle_load_1chr = needle_isL ? (load_chr_insn)&MacroAssembler::lbu : ++ (load_chr_insn)&MacroAssembler::lhu; ++ load_chr_insn haystack_load_1chr = haystack_isL ? (load_chr_insn)&MacroAssembler::lbu : ++ (load_chr_insn)&MacroAssembler::lhu; ++ ++ BLOCK_COMMENT("string_indexof {"); ++ ++ // Note, inline_string_indexOf() generates checks: ++ // if (pattern.count > src.count) return -1; ++ // if (pattern.count == 0) return 0; ++ ++ // We have two strings, a source string in haystack, haystack_len and a pattern string ++ // in needle, needle_len. Find the first occurence of pattern in source or return -1. ++ ++ // For larger pattern and source we use a simplified Boyer Moore algorithm. ++ // With a small pattern and source we use linear scan. ++ ++ // needle_len >=8 && needle_len < 256 && needle_len < haystack_len/4, use bmh algorithm. ++ sub(result_tmp, haystack_len, needle_len); ++ // needle_len < 8, use linear scan ++ sub(t0, needle_len, 8); ++ bltz(t0, LINEARSEARCH); ++ // needle_len >= 256, use linear scan ++ sub(t0, needle_len, 256); ++ bgez(t0, LINEARSTUB); ++ // needle_len >= haystack_len/4, use linear scan ++ srli(t0, haystack_len, 2); ++ bge(needle_len, t0, LINEARSTUB); ++ ++ // Boyer-Moore-Horspool introduction: ++ // The Boyer Moore alogorithm is based on the description here:- ++ // ++ // http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm ++ // ++ // This describes and algorithm with 2 shift rules. The 'Bad Character' rule ++ // and the 'Good Suffix' rule. ++ // ++ // These rules are essentially heuristics for how far we can shift the ++ // pattern along the search string. ++ // ++ // The implementation here uses the 'Bad Character' rule only because of the ++ // complexity of initialisation for the 'Good Suffix' rule. ++ // ++ // This is also known as the Boyer-Moore-Horspool algorithm: ++ // ++ // http://en.wikipedia.org/wiki/Boyer-Moore-Horspool_algorithm ++ // ++ // #define ASIZE 256 ++ // ++ // int bm(unsigned char *pattern, int m, unsigned char *src, int n) { ++ // int i, j; ++ // unsigned c; ++ // unsigned char bc[ASIZE]; ++ // ++ // /* Preprocessing */ ++ // for (i = 0; i < ASIZE; ++i) ++ // bc[i] = m; ++ // for (i = 0; i < m - 1; ) { ++ // c = pattern[i]; ++ // ++i; ++ // // c < 256 for Latin1 string, so, no need for branch ++ // #ifdef PATTERN_STRING_IS_LATIN1 ++ // bc[c] = m - i; ++ // #else ++ // if (c < ASIZE) bc[c] = m - i; ++ // #endif ++ // } ++ // ++ // /* Searching */ ++ // j = 0; ++ // while (j <= n - m) { ++ // c = src[i+j]; ++ // if (pattern[m-1] == c) ++ // int k; ++ // for (k = m - 2; k >= 0 && pattern[k] == src[k + j]; --k); ++ // if (k < 0) return j; ++ // // c < 256 for Latin1 string, so, no need for branch ++ // #ifdef SOURCE_STRING_IS_LATIN1_AND_PATTERN_STRING_IS_LATIN1 ++ // // LL case: (c< 256) always true. Remove branch ++ // j += bc[pattern[j+m-1]]; ++ // #endif ++ // #ifdef SOURCE_STRING_IS_UTF_AND_PATTERN_STRING_IS_UTF ++ // // UU case: need if (c if not. ++ // if (c < ASIZE) ++ // j += bc[pattern[j+m-1]]; ++ // else ++ // j += m ++ // #endif ++ // } ++ // return -1; ++ // } ++ ++ // temp register:t0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, result ++ Label BCLOOP, BCSKIP, BMLOOPSTR2, BMLOOPSTR1, BMSKIP, BMADV, BMMATCH, ++ BMLOOPSTR1_LASTCMP, BMLOOPSTR1_CMP, BMLOOPSTR1_AFTER_LOAD, BM_INIT_LOOP; ++ ++ Register haystack_end = haystack_len; ++ Register skipch = tmp2; ++ ++ // pattern length is >=8, so, we can read at least 1 register for cases when ++ // UTF->Latin1 conversion is not needed(8 LL or 4UU) and half register for ++ // UL case. We'll re-read last character in inner pre-loop code to have ++ // single outer pre-loop load ++ const int firstStep = isLL ? 7 : 3; ++ ++ const int ASIZE = 256; ++ const int STORE_BYTES = 8; // 8 bytes stored per instruction(sd) ++ ++ sub(sp, sp, ASIZE); ++ ++ // init BC offset table with default value: needle_len ++ slli(t0, needle_len, 8); ++ orr(t0, t0, needle_len); // [63...16][needle_len][needle_len] ++ slli(tmp1, t0, 16); ++ orr(t0, tmp1, t0); // [63...32][needle_len][needle_len][needle_len][needle_len] ++ slli(tmp1, t0, 32); ++ orr(tmp5, tmp1, t0); // tmp5: 8 elements [needle_len] ++ ++ mv(ch1, sp); // ch1 is t0 ++ mv(tmp6, ASIZE / STORE_BYTES); // loop iterations ++ ++ bind(BM_INIT_LOOP); ++ // for (i = 0; i < ASIZE; ++i) ++ // bc[i] = m; ++ for (int i = 0; i < 4; i++) { ++ sd(tmp5, Address(ch1, i * wordSize)); ++ } ++ add(ch1, ch1, 32); ++ sub(tmp6, tmp6, 4); ++ bgtz(tmp6, BM_INIT_LOOP); ++ ++ sub(nlen_tmp, needle_len, 1); // m - 1, index of the last element in pattern ++ Register orig_haystack = tmp5; ++ mv(orig_haystack, haystack); ++ // result_tmp = tmp4 ++ shadd(haystack_end, result_tmp, haystack, haystack_end, haystack_chr_shift); ++ sub(ch2, needle_len, 1); // bc offset init value, ch2 is t1 ++ mv(tmp3, needle); ++ ++ // for (i = 0; i < m - 1; ) { ++ // c = pattern[i]; ++ // ++i; ++ // // c < 256 for Latin1 string, so, no need for branch ++ // #ifdef PATTERN_STRING_IS_LATIN1 ++ // bc[c] = m - i; ++ // #else ++ // if (c < ASIZE) bc[c] = m - i; ++ // #endif ++ // } ++ bind(BCLOOP); ++ (this->*needle_load_1chr)(ch1, Address(tmp3), noreg); ++ add(tmp3, tmp3, needle_chr_size); ++ if (!needle_isL) { ++ // ae == StrIntrinsicNode::UU ++ mv(tmp6, ASIZE); ++ bgeu(ch1, tmp6, BCSKIP); ++ } ++ add(tmp4, sp, ch1); ++ sb(ch2, Address(tmp4)); // store skip offset to BC offset table ++ ++ bind(BCSKIP); ++ sub(ch2, ch2, 1); // for next pattern element, skip distance -1 ++ bgtz(ch2, BCLOOP); ++ ++ // tmp6: pattern end, address after needle ++ shadd(tmp6, needle_len, needle, tmp6, needle_chr_shift); ++ if (needle_isL == haystack_isL) { ++ // load last 8 bytes (8LL/4UU symbols) ++ ld(tmp6, Address(tmp6, -wordSize)); ++ } else { ++ // UL: from UTF-16(source) search Latin1(pattern) ++ lwu(tmp6, Address(tmp6, -wordSize / 2)); // load last 4 bytes(4 symbols) ++ // convert Latin1 to UTF. eg: 0x0000abcd -> 0x0a0b0c0d ++ // We'll have to wait until load completed, but it's still faster than per-character loads+checks ++ srli(tmp3, tmp6, BitsPerByte * (wordSize / 2 - needle_chr_size)); // pattern[m-1], eg:0x0000000a ++ slli(ch2, tmp6, XLEN - 24); ++ srli(ch2, ch2, XLEN - 8); // pattern[m-2], 0x0000000b ++ slli(ch1, tmp6, XLEN - 16); ++ srli(ch1, ch1, XLEN - 8); // pattern[m-3], 0x0000000c ++ andi(tmp6, tmp6, 0xff); // pattern[m-4], 0x0000000d ++ slli(ch2, ch2, 16); ++ orr(ch2, ch2, ch1); // 0x00000b0c ++ slli(result, tmp3, 48); // use result as temp register ++ orr(tmp6, tmp6, result); // 0x0a00000d ++ slli(result, ch2, 16); ++ orr(tmp6, tmp6, result); // UTF-16:0x0a0b0c0d ++ } ++ ++ // i = m - 1; ++ // skipch = j + i; ++ // if (skipch == pattern[m - 1] ++ // for (k = m - 2; k >= 0 && pattern[k] == src[k + j]; --k); ++ // else ++ // move j with bad char offset table ++ bind(BMLOOPSTR2); ++ // compare pattern to source string backward ++ shadd(result, nlen_tmp, haystack, result, haystack_chr_shift); ++ (this->*haystack_load_1chr)(skipch, Address(result), noreg); ++ sub(nlen_tmp, nlen_tmp, firstStep); // nlen_tmp is positive here, because needle_len >= 8 ++ if (needle_isL == haystack_isL) { ++ // re-init tmp3. It's for free because it's executed in parallel with ++ // load above. Alternative is to initialize it before loop, but it'll ++ // affect performance on in-order systems with 2 or more ld/st pipelines ++ srli(tmp3, tmp6, BitsPerByte * (wordSize - needle_chr_size)); // UU/LL: pattern[m-1] ++ } ++ if (!isLL) { // UU/UL case ++ slli(ch2, nlen_tmp, 1); // offsets in bytes ++ } ++ bne(tmp3, skipch, BMSKIP); // if not equal, skipch is bad char ++ add(result, haystack, isLL ? nlen_tmp : ch2); ++ ld(ch2, Address(result)); // load 8 bytes from source string ++ mv(ch1, tmp6); ++ if (isLL) { ++ j(BMLOOPSTR1_AFTER_LOAD); ++ } else { ++ sub(nlen_tmp, nlen_tmp, 1); // no need to branch for UU/UL case. cnt1 >= 8 ++ j(BMLOOPSTR1_CMP); ++ } ++ ++ bind(BMLOOPSTR1); ++ shadd(ch1, nlen_tmp, needle, ch1, needle_chr_shift); ++ (this->*needle_load_1chr)(ch1, Address(ch1), noreg); ++ shadd(ch2, nlen_tmp, haystack, ch2, haystack_chr_shift); ++ (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); ++ ++ bind(BMLOOPSTR1_AFTER_LOAD); ++ sub(nlen_tmp, nlen_tmp, 1); ++ bltz(nlen_tmp, BMLOOPSTR1_LASTCMP); ++ ++ bind(BMLOOPSTR1_CMP); ++ beq(ch1, ch2, BMLOOPSTR1); ++ ++ bind(BMSKIP); ++ if (!isLL) { ++ // if we've met UTF symbol while searching Latin1 pattern, then we can ++ // skip needle_len symbols ++ if (needle_isL != haystack_isL) { ++ mv(result_tmp, needle_len); ++ } else { ++ mv(result_tmp, 1); ++ } ++ mv(t0, ASIZE); ++ bgeu(skipch, t0, BMADV); ++ } ++ add(result_tmp, sp, skipch); ++ lbu(result_tmp, Address(result_tmp)); // load skip offset ++ ++ bind(BMADV); ++ sub(nlen_tmp, needle_len, 1); ++ // move haystack after bad char skip offset ++ shadd(haystack, result_tmp, haystack, result, haystack_chr_shift); ++ ble(haystack, haystack_end, BMLOOPSTR2); ++ add(sp, sp, ASIZE); ++ j(NOMATCH); ++ ++ bind(BMLOOPSTR1_LASTCMP); ++ bne(ch1, ch2, BMSKIP); ++ ++ bind(BMMATCH); ++ sub(result, haystack, orig_haystack); ++ if (!haystack_isL) { ++ srli(result, result, 1); ++ } ++ add(sp, sp, ASIZE); ++ j(DONE); ++ ++ bind(LINEARSTUB); ++ sub(t0, needle_len, 16); // small patterns still should be handled by simple algorithm ++ bltz(t0, LINEARSEARCH); ++ mv(result, zr); ++ RuntimeAddress stub = NULL; ++ if (isLL) { ++ stub = RuntimeAddress(StubRoutines::riscv::string_indexof_linear_ll()); ++ assert(stub.target() != NULL, "string_indexof_linear_ll stub has not been generated"); ++ } else if (needle_isL) { ++ stub = RuntimeAddress(StubRoutines::riscv::string_indexof_linear_ul()); ++ assert(stub.target() != NULL, "string_indexof_linear_ul stub has not been generated"); ++ } else { ++ stub = RuntimeAddress(StubRoutines::riscv::string_indexof_linear_uu()); ++ assert(stub.target() != NULL, "string_indexof_linear_uu stub has not been generated"); ++ } ++ trampoline_call(stub); ++ j(DONE); ++ ++ bind(NOMATCH); ++ mv(result, -1); ++ j(DONE); ++ ++ bind(LINEARSEARCH); ++ string_indexof_linearscan(haystack, needle, haystack_len, needle_len, tmp1, tmp2, tmp3, tmp4, -1, result, ae); ++ ++ bind(DONE); ++ BLOCK_COMMENT("} string_indexof"); ++} ++ ++// string_indexof ++// result: x10 ++// src: x11 ++// src_count: x12 ++// pattern: x13 ++// pattern_count: x14 or 1/2/3/4 ++void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register needle, ++ Register haystack_len, Register needle_len, ++ Register tmp1, Register tmp2, ++ Register tmp3, Register tmp4, ++ int needle_con_cnt, Register result, int ae) ++{ ++ // Note: ++ // needle_con_cnt > 0 means needle_len register is invalid, needle length is constant ++ // for UU/LL: needle_con_cnt[1, 4], UL: needle_con_cnt = 1 ++ assert(needle_con_cnt <= 4, "Invalid needle constant count"); ++ assert(ae != StrIntrinsicNode::LU, "Invalid encoding"); ++ ++ Register ch1 = t0; ++ Register ch2 = t1; ++ Register hlen_neg = haystack_len, nlen_neg = needle_len; ++ Register nlen_tmp = tmp1, hlen_tmp = tmp2, result_tmp = tmp4; ++ ++ bool isLL = ae == StrIntrinsicNode::LL; ++ ++ bool needle_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UL; ++ bool haystack_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::LU; ++ int needle_chr_shift = needle_isL ? 0 : 1; ++ int haystack_chr_shift = haystack_isL ? 0 : 1; ++ int needle_chr_size = needle_isL ? 1 : 2; ++ int haystack_chr_size = haystack_isL ? 1 : 2; ++ ++ load_chr_insn needle_load_1chr = needle_isL ? (load_chr_insn)&MacroAssembler::lbu : ++ (load_chr_insn)&MacroAssembler::lhu; ++ load_chr_insn haystack_load_1chr = haystack_isL ? (load_chr_insn)&MacroAssembler::lbu : ++ (load_chr_insn)&MacroAssembler::lhu; ++ load_chr_insn load_2chr = isLL ? (load_chr_insn)&MacroAssembler::lhu : (load_chr_insn)&MacroAssembler::lwu; ++ load_chr_insn load_4chr = isLL ? (load_chr_insn)&MacroAssembler::lwu : (load_chr_insn)&MacroAssembler::ld; ++ ++ Label DO1, DO2, DO3, MATCH, NOMATCH, DONE; ++ ++ Register first = tmp3; ++ ++ if (needle_con_cnt == -1) { ++ Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT; ++ ++ sub(t0, needle_len, needle_isL == haystack_isL ? 4 : 2); ++ bltz(t0, DOSHORT); ++ ++ (this->*needle_load_1chr)(first, Address(needle), noreg); ++ slli(t0, needle_len, needle_chr_shift); ++ add(needle, needle, t0); ++ neg(nlen_neg, t0); ++ slli(t0, result_tmp, haystack_chr_shift); ++ add(haystack, haystack, t0); ++ neg(hlen_neg, t0); ++ ++ bind(FIRST_LOOP); ++ add(t0, haystack, hlen_neg); ++ (this->*haystack_load_1chr)(ch2, Address(t0), noreg); ++ beq(first, ch2, STR1_LOOP); ++ ++ bind(STR2_NEXT); ++ add(hlen_neg, hlen_neg, haystack_chr_size); ++ blez(hlen_neg, FIRST_LOOP); ++ j(NOMATCH); ++ ++ bind(STR1_LOOP); ++ add(nlen_tmp, nlen_neg, needle_chr_size); ++ add(hlen_tmp, hlen_neg, haystack_chr_size); ++ bgez(nlen_tmp, MATCH); ++ ++ bind(STR1_NEXT); ++ add(ch1, needle, nlen_tmp); ++ (this->*needle_load_1chr)(ch1, Address(ch1), noreg); ++ add(ch2, haystack, hlen_tmp); ++ (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); ++ bne(ch1, ch2, STR2_NEXT); ++ add(nlen_tmp, nlen_tmp, needle_chr_size); ++ add(hlen_tmp, hlen_tmp, haystack_chr_size); ++ bltz(nlen_tmp, STR1_NEXT); ++ j(MATCH); ++ ++ bind(DOSHORT); ++ if (needle_isL == haystack_isL) { ++ sub(t0, needle_len, 2); ++ bltz(t0, DO1); ++ bgtz(t0, DO3); ++ } ++ } ++ ++ if (needle_con_cnt == 4) { ++ Label CH1_LOOP; ++ (this->*load_4chr)(ch1, Address(needle), noreg); ++ sub(result_tmp, haystack_len, 4); ++ slli(tmp3, result_tmp, haystack_chr_shift); // result as tmp ++ add(haystack, haystack, tmp3); ++ neg(hlen_neg, tmp3); ++ ++ bind(CH1_LOOP); ++ add(ch2, haystack, hlen_neg); ++ (this->*load_4chr)(ch2, Address(ch2), noreg); ++ beq(ch1, ch2, MATCH); ++ add(hlen_neg, hlen_neg, haystack_chr_size); ++ blez(hlen_neg, CH1_LOOP); ++ j(NOMATCH); ++ } ++ ++ if ((needle_con_cnt == -1 && needle_isL == haystack_isL) || needle_con_cnt == 2) { ++ Label CH1_LOOP; ++ BLOCK_COMMENT("string_indexof DO2 {"); ++ bind(DO2); ++ (this->*load_2chr)(ch1, Address(needle), noreg); ++ if (needle_con_cnt == 2) { ++ sub(result_tmp, haystack_len, 2); ++ } ++ slli(tmp3, result_tmp, haystack_chr_shift); ++ add(haystack, haystack, tmp3); ++ neg(hlen_neg, tmp3); ++ ++ bind(CH1_LOOP); ++ add(tmp3, haystack, hlen_neg); ++ (this->*load_2chr)(ch2, Address(tmp3), noreg); ++ beq(ch1, ch2, MATCH); ++ add(hlen_neg, hlen_neg, haystack_chr_size); ++ blez(hlen_neg, CH1_LOOP); ++ j(NOMATCH); ++ BLOCK_COMMENT("} string_indexof DO2"); ++ } ++ ++ if ((needle_con_cnt == -1 && needle_isL == haystack_isL) || needle_con_cnt == 3) { ++ Label FIRST_LOOP, STR2_NEXT, STR1_LOOP; ++ BLOCK_COMMENT("string_indexof DO3 {"); ++ ++ bind(DO3); ++ (this->*load_2chr)(first, Address(needle), noreg); ++ (this->*needle_load_1chr)(ch1, Address(needle, 2 * needle_chr_size), noreg); ++ if (needle_con_cnt == 3) { ++ sub(result_tmp, haystack_len, 3); ++ } ++ slli(hlen_tmp, result_tmp, haystack_chr_shift); ++ add(haystack, haystack, hlen_tmp); ++ neg(hlen_neg, hlen_tmp); ++ ++ bind(FIRST_LOOP); ++ add(ch2, haystack, hlen_neg); ++ (this->*load_2chr)(ch2, Address(ch2), noreg); ++ beq(first, ch2, STR1_LOOP); ++ ++ bind(STR2_NEXT); ++ add(hlen_neg, hlen_neg, haystack_chr_size); ++ blez(hlen_neg, FIRST_LOOP); ++ j(NOMATCH); ++ ++ bind(STR1_LOOP); ++ add(hlen_tmp, hlen_neg, 2 * haystack_chr_size); ++ add(ch2, haystack, hlen_tmp); ++ (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); ++ bne(ch1, ch2, STR2_NEXT); ++ j(MATCH); ++ BLOCK_COMMENT("} string_indexof DO3"); ++ } ++ ++ if (needle_con_cnt == -1 || needle_con_cnt == 1) { ++ Label DO1_LOOP; ++ ++ BLOCK_COMMENT("string_indexof DO1 {"); ++ bind(DO1); ++ (this->*needle_load_1chr)(ch1, Address(needle), noreg); ++ sub(result_tmp, haystack_len, 1); ++ mv(tmp3, result_tmp); ++ if (haystack_chr_shift) { ++ slli(tmp3, result_tmp, haystack_chr_shift); ++ } ++ add(haystack, haystack, tmp3); ++ neg(hlen_neg, tmp3); ++ ++ bind(DO1_LOOP); ++ add(tmp3, haystack, hlen_neg); ++ (this->*haystack_load_1chr)(ch2, Address(tmp3), noreg); ++ beq(ch1, ch2, MATCH); ++ add(hlen_neg, hlen_neg, haystack_chr_size); ++ blez(hlen_neg, DO1_LOOP); ++ BLOCK_COMMENT("} string_indexof DO1"); ++ } ++ ++ bind(NOMATCH); ++ mv(result, -1); ++ j(DONE); ++ ++ bind(MATCH); ++ srai(t0, hlen_neg, haystack_chr_shift); ++ add(result, result_tmp, t0); ++ ++ bind(DONE); ++} ++ ++// Compare strings. ++void C2_MacroAssembler::string_compare(Register str1, Register str2, ++ Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2, ++ Register tmp3, int ae) ++{ ++ Label DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, TAIL, STUB, ++ DIFFERENCE, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT, ++ SHORT_LOOP_START, TAIL_CHECK, L; ++ ++ const int STUB_THRESHOLD = 64 + 8; ++ bool isLL = ae == StrIntrinsicNode::LL; ++ bool isLU = ae == StrIntrinsicNode::LU; ++ bool isUL = ae == StrIntrinsicNode::UL; ++ ++ bool str1_isL = isLL || isLU; ++ bool str2_isL = isLL || isUL; ++ ++ // for L strings, 1 byte for 1 character ++ // for U strings, 2 bytes for 1 character ++ int str1_chr_size = str1_isL ? 1 : 2; ++ int str2_chr_size = str2_isL ? 1 : 2; ++ int minCharsInWord = isLL ? wordSize : wordSize / 2; ++ ++ load_chr_insn str1_load_chr = str1_isL ? (load_chr_insn)&MacroAssembler::lbu : (load_chr_insn)&MacroAssembler::lhu; ++ load_chr_insn str2_load_chr = str2_isL ? (load_chr_insn)&MacroAssembler::lbu : (load_chr_insn)&MacroAssembler::lhu; ++ ++ BLOCK_COMMENT("string_compare {"); ++ ++ // Bizzarely, the counts are passed in bytes, regardless of whether they ++ // are L or U strings, however the result is always in characters. ++ if (!str1_isL) { ++ sraiw(cnt1, cnt1, 1); ++ } ++ if (!str2_isL) { ++ sraiw(cnt2, cnt2, 1); ++ } ++ ++ // Compute the minimum of the string lengths and save the difference in result. ++ sub(result, cnt1, cnt2); ++ bgt(cnt1, cnt2, L); ++ mv(cnt2, cnt1); ++ bind(L); ++ ++ // A very short string ++ mv(t0, minCharsInWord); ++ ble(cnt2, t0, SHORT_STRING); ++ ++ // Compare longwords ++ // load first parts of strings and finish initialization while loading ++ { ++ if (str1_isL == str2_isL) { // LL or UU ++ // load 8 bytes once to compare ++ ld(tmp1, Address(str1)); ++ beq(str1, str2, DONE); ++ ld(tmp2, Address(str2)); ++ mv(t0, STUB_THRESHOLD); ++ bge(cnt2, t0, STUB); ++ sub(cnt2, cnt2, minCharsInWord); ++ beqz(cnt2, TAIL_CHECK); ++ // convert cnt2 from characters to bytes ++ if (!str1_isL) { ++ slli(cnt2, cnt2, 1); ++ } ++ add(str2, str2, cnt2); ++ add(str1, str1, cnt2); ++ sub(cnt2, zr, cnt2); ++ } else if (isLU) { // LU case ++ lwu(tmp1, Address(str1)); ++ ld(tmp2, Address(str2)); ++ mv(t0, STUB_THRESHOLD); ++ bge(cnt2, t0, STUB); ++ addi(cnt2, cnt2, -4); ++ add(str1, str1, cnt2); ++ sub(cnt1, zr, cnt2); ++ slli(cnt2, cnt2, 1); ++ add(str2, str2, cnt2); ++ inflate_lo32(tmp3, tmp1); ++ mv(tmp1, tmp3); ++ sub(cnt2, zr, cnt2); ++ addi(cnt1, cnt1, 4); ++ } else { // UL case ++ ld(tmp1, Address(str1)); ++ lwu(tmp2, Address(str2)); ++ mv(t0, STUB_THRESHOLD); ++ bge(cnt2, t0, STUB); ++ addi(cnt2, cnt2, -4); ++ slli(t0, cnt2, 1); ++ sub(cnt1, zr, t0); ++ add(str1, str1, t0); ++ add(str2, str2, cnt2); ++ inflate_lo32(tmp3, tmp2); ++ mv(tmp2, tmp3); ++ sub(cnt2, zr, cnt2); ++ addi(cnt1, cnt1, 8); ++ } ++ addi(cnt2, cnt2, isUL ? 4 : 8); ++ bgez(cnt2, TAIL); ++ xorr(tmp3, tmp1, tmp2); ++ bnez(tmp3, DIFFERENCE); ++ ++ // main loop ++ bind(NEXT_WORD); ++ if (str1_isL == str2_isL) { // LL or UU ++ add(t0, str1, cnt2); ++ ld(tmp1, Address(t0)); ++ add(t0, str2, cnt2); ++ ld(tmp2, Address(t0)); ++ addi(cnt2, cnt2, 8); ++ } else if (isLU) { // LU case ++ add(t0, str1, cnt1); ++ lwu(tmp1, Address(t0)); ++ add(t0, str2, cnt2); ++ ld(tmp2, Address(t0)); ++ addi(cnt1, cnt1, 4); ++ inflate_lo32(tmp3, tmp1); ++ mv(tmp1, tmp3); ++ addi(cnt2, cnt2, 8); ++ } else { // UL case ++ add(t0, str2, cnt2); ++ lwu(tmp2, Address(t0)); ++ add(t0, str1, cnt1); ++ ld(tmp1, Address(t0)); ++ inflate_lo32(tmp3, tmp2); ++ mv(tmp2, tmp3); ++ addi(cnt1, cnt1, 8); ++ addi(cnt2, cnt2, 4); ++ } ++ bgez(cnt2, TAIL); ++ ++ xorr(tmp3, tmp1, tmp2); ++ beqz(tmp3, NEXT_WORD); ++ j(DIFFERENCE); ++ bind(TAIL); ++ xorr(tmp3, tmp1, tmp2); ++ bnez(tmp3, DIFFERENCE); ++ // Last longword. In the case where length == 4 we compare the ++ // same longword twice, but that's still faster than another ++ // conditional branch. ++ if (str1_isL == str2_isL) { // LL or UU ++ ld(tmp1, Address(str1)); ++ ld(tmp2, Address(str2)); ++ } else if (isLU) { // LU case ++ lwu(tmp1, Address(str1)); ++ ld(tmp2, Address(str2)); ++ inflate_lo32(tmp3, tmp1); ++ mv(tmp1, tmp3); ++ } else { // UL case ++ lwu(tmp2, Address(str2)); ++ ld(tmp1, Address(str1)); ++ inflate_lo32(tmp3, tmp2); ++ mv(tmp2, tmp3); ++ } ++ bind(TAIL_CHECK); ++ xorr(tmp3, tmp1, tmp2); ++ beqz(tmp3, DONE); ++ ++ // Find the first different characters in the longwords and ++ // compute their difference. ++ bind(DIFFERENCE); ++ ctzc_bit(result, tmp3, isLL); // count zero from lsb to msb ++ srl(tmp1, tmp1, result); ++ srl(tmp2, tmp2, result); ++ if (isLL) { ++ andi(tmp1, tmp1, 0xFF); ++ andi(tmp2, tmp2, 0xFF); ++ } else { ++ andi(tmp1, tmp1, 0xFFFF); ++ andi(tmp2, tmp2, 0xFFFF); ++ } ++ sub(result, tmp1, tmp2); ++ j(DONE); ++ } ++ ++ bind(STUB); ++ RuntimeAddress stub = NULL; ++ switch (ae) { ++ case StrIntrinsicNode::LL: ++ stub = RuntimeAddress(StubRoutines::riscv::compare_long_string_LL()); ++ break; ++ case StrIntrinsicNode::UU: ++ stub = RuntimeAddress(StubRoutines::riscv::compare_long_string_UU()); ++ break; ++ case StrIntrinsicNode::LU: ++ stub = RuntimeAddress(StubRoutines::riscv::compare_long_string_LU()); ++ break; ++ case StrIntrinsicNode::UL: ++ stub = RuntimeAddress(StubRoutines::riscv::compare_long_string_UL()); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ assert(stub.target() != NULL, "compare_long_string stub has not been generated"); ++ trampoline_call(stub); ++ j(DONE); ++ ++ bind(SHORT_STRING); ++ // Is the minimum length zero? ++ beqz(cnt2, DONE); ++ // arrange code to do most branches while loading and loading next characters ++ // while comparing previous ++ (this->*str1_load_chr)(tmp1, Address(str1), t0); ++ addi(str1, str1, str1_chr_size); ++ addi(cnt2, cnt2, -1); ++ beqz(cnt2, SHORT_LAST_INIT); ++ (this->*str2_load_chr)(cnt1, Address(str2), t0); ++ addi(str2, str2, str2_chr_size); ++ j(SHORT_LOOP_START); ++ bind(SHORT_LOOP); ++ addi(cnt2, cnt2, -1); ++ beqz(cnt2, SHORT_LAST); ++ bind(SHORT_LOOP_START); ++ (this->*str1_load_chr)(tmp2, Address(str1), t0); ++ addi(str1, str1, str1_chr_size); ++ (this->*str2_load_chr)(t0, Address(str2), t0); ++ addi(str2, str2, str2_chr_size); ++ bne(tmp1, cnt1, SHORT_LOOP_TAIL); ++ addi(cnt2, cnt2, -1); ++ beqz(cnt2, SHORT_LAST2); ++ (this->*str1_load_chr)(tmp1, Address(str1), t0); ++ addi(str1, str1, str1_chr_size); ++ (this->*str2_load_chr)(cnt1, Address(str2), t0); ++ addi(str2, str2, str2_chr_size); ++ beq(tmp2, t0, SHORT_LOOP); ++ sub(result, tmp2, t0); ++ j(DONE); ++ bind(SHORT_LOOP_TAIL); ++ sub(result, tmp1, cnt1); ++ j(DONE); ++ bind(SHORT_LAST2); ++ beq(tmp2, t0, DONE); ++ sub(result, tmp2, t0); ++ ++ j(DONE); ++ bind(SHORT_LAST_INIT); ++ (this->*str2_load_chr)(cnt1, Address(str2), t0); ++ addi(str2, str2, str2_chr_size); ++ bind(SHORT_LAST); ++ beq(tmp1, cnt1, DONE); ++ sub(result, tmp1, cnt1); ++ ++ bind(DONE); ++ ++ BLOCK_COMMENT("} string_compare"); ++} ++ ++void C2_MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3, ++ Register tmp4, Register tmp5, Register tmp6, Register result, ++ Register cnt1, int elem_size) { ++ Label DONE, SAME, NEXT_DWORD, SHORT, TAIL, TAIL2, IS_TMP5_ZR; ++ Register tmp1 = t0; ++ Register tmp2 = t1; ++ Register cnt2 = tmp2; // cnt2 only used in array length compare ++ Register elem_per_word = tmp6; ++ int log_elem_size = exact_log2(elem_size); ++ int length_offset = arrayOopDesc::length_offset_in_bytes(); ++ int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE); ++ ++ assert(elem_size == 1 || elem_size == 2, "must be char or byte"); ++ assert_different_registers(a1, a2, result, cnt1, t0, t1, tmp3, tmp4, tmp5, tmp6); ++ mv(elem_per_word, wordSize / elem_size); ++ ++ BLOCK_COMMENT("arrays_equals {"); ++ ++ // if (a1 == a2), return true ++ beq(a1, a2, SAME); ++ ++ mv(result, false); ++ beqz(a1, DONE); ++ beqz(a2, DONE); ++ lwu(cnt1, Address(a1, length_offset)); ++ lwu(cnt2, Address(a2, length_offset)); ++ bne(cnt2, cnt1, DONE); ++ beqz(cnt1, SAME); ++ ++ slli(tmp5, cnt1, 3 + log_elem_size); ++ sub(tmp5, zr, tmp5); ++ add(a1, a1, base_offset); ++ add(a2, a2, base_offset); ++ ld(tmp3, Address(a1, 0)); ++ ld(tmp4, Address(a2, 0)); ++ ble(cnt1, elem_per_word, SHORT); // short or same ++ ++ // Main 16 byte comparison loop with 2 exits ++ bind(NEXT_DWORD); { ++ ld(tmp1, Address(a1, wordSize)); ++ ld(tmp2, Address(a2, wordSize)); ++ sub(cnt1, cnt1, 2 * wordSize / elem_size); ++ blez(cnt1, TAIL); ++ bne(tmp3, tmp4, DONE); ++ ld(tmp3, Address(a1, 2 * wordSize)); ++ ld(tmp4, Address(a2, 2 * wordSize)); ++ add(a1, a1, 2 * wordSize); ++ add(a2, a2, 2 * wordSize); ++ ble(cnt1, elem_per_word, TAIL2); ++ } beq(tmp1, tmp2, NEXT_DWORD); ++ j(DONE); ++ ++ bind(TAIL); ++ xorr(tmp4, tmp3, tmp4); ++ xorr(tmp2, tmp1, tmp2); ++ sll(tmp2, tmp2, tmp5); ++ orr(tmp5, tmp4, tmp2); ++ j(IS_TMP5_ZR); ++ ++ bind(TAIL2); ++ bne(tmp1, tmp2, DONE); ++ ++ bind(SHORT); ++ xorr(tmp4, tmp3, tmp4); ++ sll(tmp5, tmp4, tmp5); ++ ++ bind(IS_TMP5_ZR); ++ bnez(tmp5, DONE); ++ ++ bind(SAME); ++ mv(result, true); ++ // That's it. ++ bind(DONE); ++ ++ BLOCK_COMMENT("} array_equals"); ++} ++ ++// Compare Strings ++ ++// For Strings we're passed the address of the first characters in a1 ++// and a2 and the length in cnt1. ++// elem_size is the element size in bytes: either 1 or 2. ++// There are two implementations. For arrays >= 8 bytes, all ++// comparisons (including the final one, which may overlap) are ++// performed 8 bytes at a time. For strings < 8 bytes, we compare a ++// halfword, then a short, and then a byte. ++ ++void C2_MacroAssembler::string_equals(Register a1, Register a2, ++ Register result, Register cnt1, int elem_size) ++{ ++ Label SAME, DONE, SHORT, NEXT_WORD; ++ Register tmp1 = t0; ++ Register tmp2 = t1; ++ ++ assert(elem_size == 1 || elem_size == 2, "must be 2 or 1 byte"); ++ assert_different_registers(a1, a2, result, cnt1, t0, t1); ++ ++ BLOCK_COMMENT("string_equals {"); ++ ++ mv(result, false); ++ ++ // Check for short strings, i.e. smaller than wordSize. ++ sub(cnt1, cnt1, wordSize); ++ bltz(cnt1, SHORT); ++ ++ // Main 8 byte comparison loop. ++ bind(NEXT_WORD); { ++ ld(tmp1, Address(a1, 0)); ++ add(a1, a1, wordSize); ++ ld(tmp2, Address(a2, 0)); ++ add(a2, a2, wordSize); ++ sub(cnt1, cnt1, wordSize); ++ bne(tmp1, tmp2, DONE); ++ } bgtz(cnt1, NEXT_WORD); ++ ++ // Last longword. In the case where length == 4 we compare the ++ // same longword twice, but that's still faster than another ++ // conditional branch. ++ // cnt1 could be 0, -1, -2, -3, -4 for chars; -4 only happens when ++ // length == 4. ++ add(tmp1, a1, cnt1); ++ ld(tmp1, Address(tmp1, 0)); ++ add(tmp2, a2, cnt1); ++ ld(tmp2, Address(tmp2, 0)); ++ bne(tmp1, tmp2, DONE); ++ j(SAME); ++ ++ bind(SHORT); ++ Label TAIL03, TAIL01; ++ ++ // 0-7 bytes left. ++ test_bit(t0, cnt1, 2); ++ beqz(t0, TAIL03); ++ { ++ lwu(tmp1, Address(a1, 0)); ++ add(a1, a1, 4); ++ lwu(tmp2, Address(a2, 0)); ++ add(a2, a2, 4); ++ bne(tmp1, tmp2, DONE); ++ } ++ ++ bind(TAIL03); ++ // 0-3 bytes left. ++ test_bit(t0, cnt1, 1); ++ beqz(t0, TAIL01); ++ { ++ lhu(tmp1, Address(a1, 0)); ++ add(a1, a1, 2); ++ lhu(tmp2, Address(a2, 0)); ++ add(a2, a2, 2); ++ bne(tmp1, tmp2, DONE); ++ } ++ ++ bind(TAIL01); ++ if (elem_size == 1) { // Only needed when comparing 1-byte elements ++ // 0-1 bytes left. ++ test_bit(t0, cnt1, 0); ++ beqz(t0, SAME); ++ { ++ lbu(tmp1, Address(a1, 0)); ++ lbu(tmp2, Address(a2, 0)); ++ bne(tmp1, tmp2, DONE); ++ } ++ } ++ ++ // Arrays are equal. ++ bind(SAME); ++ mv(result, true); ++ ++ // That's it. ++ bind(DONE); ++ BLOCK_COMMENT("} string_equals"); ++} ++ ++typedef void (Assembler::*conditional_branch_insn)(Register op1, Register op2, Label& label, bool is_far); ++typedef void (MacroAssembler::*float_conditional_branch_insn)(FloatRegister op1, FloatRegister op2, Label& label, ++ bool is_far, bool is_unordered); ++ ++static conditional_branch_insn conditional_branches[] = ++{ ++ /* SHORT branches */ ++ (conditional_branch_insn)&MacroAssembler::beq, ++ (conditional_branch_insn)&MacroAssembler::bgt, ++ NULL, // BoolTest::overflow ++ (conditional_branch_insn)&MacroAssembler::blt, ++ (conditional_branch_insn)&MacroAssembler::bne, ++ (conditional_branch_insn)&MacroAssembler::ble, ++ NULL, // BoolTest::no_overflow ++ (conditional_branch_insn)&MacroAssembler::bge, ++ ++ /* UNSIGNED branches */ ++ (conditional_branch_insn)&MacroAssembler::beq, ++ (conditional_branch_insn)&MacroAssembler::bgtu, ++ NULL, ++ (conditional_branch_insn)&MacroAssembler::bltu, ++ (conditional_branch_insn)&MacroAssembler::bne, ++ (conditional_branch_insn)&MacroAssembler::bleu, ++ NULL, ++ (conditional_branch_insn)&MacroAssembler::bgeu ++}; ++ ++static float_conditional_branch_insn float_conditional_branches[] = ++{ ++ /* FLOAT SHORT branches */ ++ (float_conditional_branch_insn)&MacroAssembler::float_beq, ++ (float_conditional_branch_insn)&MacroAssembler::float_bgt, ++ NULL, // BoolTest::overflow ++ (float_conditional_branch_insn)&MacroAssembler::float_blt, ++ (float_conditional_branch_insn)&MacroAssembler::float_bne, ++ (float_conditional_branch_insn)&MacroAssembler::float_ble, ++ NULL, // BoolTest::no_overflow ++ (float_conditional_branch_insn)&MacroAssembler::float_bge, ++ ++ /* DOUBLE SHORT branches */ ++ (float_conditional_branch_insn)&MacroAssembler::double_beq, ++ (float_conditional_branch_insn)&MacroAssembler::double_bgt, ++ NULL, ++ (float_conditional_branch_insn)&MacroAssembler::double_blt, ++ (float_conditional_branch_insn)&MacroAssembler::double_bne, ++ (float_conditional_branch_insn)&MacroAssembler::double_ble, ++ NULL, ++ (float_conditional_branch_insn)&MacroAssembler::double_bge ++}; ++ ++void C2_MacroAssembler::cmp_branch(int cmpFlag, Register op1, Register op2, Label& label, bool is_far) { ++ assert(cmpFlag >= 0 && cmpFlag < (int)(sizeof(conditional_branches) / sizeof(conditional_branches[0])), ++ "invalid conditional branch index"); ++ (this->*conditional_branches[cmpFlag])(op1, op2, label, is_far); ++} ++ ++// This is a function should only be used by C2. Flip the unordered when unordered-greater, C2 would use ++// unordered-lesser instead of unordered-greater. Finally, commute the result bits at function do_one_bytecode(). ++void C2_MacroAssembler::float_cmp_branch(int cmpFlag, FloatRegister op1, FloatRegister op2, Label& label, bool is_far) { ++ assert(cmpFlag >= 0 && cmpFlag < (int)(sizeof(float_conditional_branches) / sizeof(float_conditional_branches[0])), ++ "invalid float conditional branch index"); ++ int booltest_flag = cmpFlag & ~(C2_MacroAssembler::double_branch_mask); ++ (this->*float_conditional_branches[cmpFlag])(op1, op2, label, is_far, ++ (booltest_flag == (BoolTest::ge) || booltest_flag == (BoolTest::gt)) ? false : true); ++} ++ ++void C2_MacroAssembler::enc_cmpUEqNeLeGt_imm0_branch(int cmpFlag, Register op1, Label& L, bool is_far) { ++ switch (cmpFlag) { ++ case BoolTest::eq: ++ case BoolTest::le: ++ beqz(op1, L, is_far); ++ break; ++ case BoolTest::ne: ++ case BoolTest::gt: ++ bnez(op1, L, is_far); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void C2_MacroAssembler::enc_cmpEqNe_imm0_branch(int cmpFlag, Register op1, Label& L, bool is_far) { ++ switch (cmpFlag) { ++ case BoolTest::eq: ++ beqz(op1, L, is_far); ++ break; ++ case BoolTest::ne: ++ bnez(op1, L, is_far); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void C2_MacroAssembler::enc_cmove(int cmpFlag, Register op1, Register op2, Register dst, Register src) { ++ Label L; ++ cmp_branch(cmpFlag ^ (1 << neg_cond_bits), op1, op2, L); ++ mv(dst, src); ++ bind(L); ++} ++ ++// Set dst to NaN if any NaN input. ++void C2_MacroAssembler::minmax_FD(FloatRegister dst, FloatRegister src1, FloatRegister src2, ++ bool is_double, bool is_min) { ++ assert_different_registers(dst, src1, src2); ++ ++ Label Done, Compare; ++ ++ is_double ? fclass_d(t0, src1) ++ : fclass_s(t0, src1); ++ is_double ? fclass_d(t1, src2) ++ : fclass_s(t1, src2); ++ orr(t0, t0, t1); ++ andi(t0, t0, 0b1100000000); //if src1 or src2 is quiet or signaling NaN then return NaN ++ beqz(t0, Compare); ++ is_double ? fadd_d(dst, src1, src2) ++ : fadd_s(dst, src1, src2); ++ j(Done); ++ ++ bind(Compare); ++ if (is_double) { ++ is_min ? fmin_d(dst, src1, src2) ++ : fmax_d(dst, src1, src2); ++ } else { ++ is_min ? fmin_s(dst, src1, src2) ++ : fmax_s(dst, src1, src2); ++ } ++ ++ bind(Done); ++} ++ ++void C2_MacroAssembler::element_compare(Register a1, Register a2, Register result, Register cnt, Register tmp1, Register tmp2, ++ VectorRegister vr1, VectorRegister vr2, VectorRegister vrs, bool islatin, Label &DONE) { ++ Label loop; ++ Assembler::SEW sew = islatin ? Assembler::e8 : Assembler::e16; ++ ++ bind(loop); ++ vsetvli(tmp1, cnt, sew, Assembler::m2); ++ vlex_v(vr1, a1, sew); ++ vlex_v(vr2, a2, sew); ++ vmsne_vv(vrs, vr1, vr2); ++ vfirst_m(tmp2, vrs); ++ bgez(tmp2, DONE); ++ sub(cnt, cnt, tmp1); ++ if (!islatin) { ++ slli(tmp1, tmp1, 1); // get byte counts ++ } ++ add(a1, a1, tmp1); ++ add(a2, a2, tmp1); ++ bnez(cnt, loop); ++ ++ mv(result, true); ++} ++ ++void C2_MacroAssembler::string_equals_v(Register a1, Register a2, Register result, Register cnt, int elem_size) { ++ Label DONE; ++ Register tmp1 = t0; ++ Register tmp2 = t1; ++ ++ BLOCK_COMMENT("string_equals_v {"); ++ ++ mv(result, false); ++ ++ if (elem_size == 2) { ++ srli(cnt, cnt, 1); ++ } ++ ++ element_compare(a1, a2, result, cnt, tmp1, tmp2, v0, v2, v0, elem_size == 1, DONE); ++ ++ bind(DONE); ++ BLOCK_COMMENT("} string_equals_v"); ++} ++ ++// used by C2 ClearArray patterns. ++// base: Address of a buffer to be zeroed ++// cnt: Count in HeapWords ++// ++// base, cnt, v0, v1 and t0 are clobbered. ++void C2_MacroAssembler::clear_array_v(Register base, Register cnt) { ++ Label loop; ++ ++ // making zero words ++ vsetvli(t0, cnt, Assembler::e64, Assembler::m4); ++ vxor_vv(v0, v0, v0); ++ ++ bind(loop); ++ vsetvli(t0, cnt, Assembler::e64, Assembler::m4); ++ vse64_v(v0, base); ++ sub(cnt, cnt, t0); ++ shadd(base, t0, base, t0, 3); ++ bnez(cnt, loop); ++} ++ ++void C2_MacroAssembler::arrays_equals_v(Register a1, Register a2, Register result, ++ Register cnt1, int elem_size) { ++ Label DONE; ++ Register tmp1 = t0; ++ Register tmp2 = t1; ++ Register cnt2 = tmp2; ++ int length_offset = arrayOopDesc::length_offset_in_bytes(); ++ int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE); ++ ++ BLOCK_COMMENT("arrays_equals_v {"); ++ ++ // if (a1 == a2), return true ++ mv(result, true); ++ beq(a1, a2, DONE); ++ ++ mv(result, false); ++ // if a1 == null or a2 == null, return false ++ beqz(a1, DONE); ++ beqz(a2, DONE); ++ // if (a1.length != a2.length), return false ++ lwu(cnt1, Address(a1, length_offset)); ++ lwu(cnt2, Address(a2, length_offset)); ++ bne(cnt1, cnt2, DONE); ++ ++ la(a1, Address(a1, base_offset)); ++ la(a2, Address(a2, base_offset)); ++ ++ element_compare(a1, a2, result, cnt1, tmp1, tmp2, v0, v2, v0, elem_size == 1, DONE); ++ ++ bind(DONE); ++ ++ BLOCK_COMMENT("} arrays_equals_v"); ++} ++ ++void C2_MacroAssembler::string_compare_v(Register str1, Register str2, Register cnt1, Register cnt2, ++ Register result, Register tmp1, Register tmp2, int encForm) { ++ Label DIFFERENCE, DONE, L, loop; ++ bool encLL = encForm == StrIntrinsicNode::LL; ++ bool encLU = encForm == StrIntrinsicNode::LU; ++ bool encUL = encForm == StrIntrinsicNode::UL; ++ ++ bool str1_isL = encLL || encLU; ++ bool str2_isL = encLL || encUL; ++ ++ int minCharsInWord = encLL ? wordSize : wordSize / 2; ++ ++ BLOCK_COMMENT("string_compare {"); ++ ++ // for Lating strings, 1 byte for 1 character ++ // for UTF16 strings, 2 bytes for 1 character ++ if (!str1_isL) ++ sraiw(cnt1, cnt1, 1); ++ if (!str2_isL) ++ sraiw(cnt2, cnt2, 1); ++ ++ // if str1 == str2, return the difference ++ // save the minimum of the string lengths in cnt2. ++ sub(result, cnt1, cnt2); ++ bgt(cnt1, cnt2, L); ++ mv(cnt2, cnt1); ++ bind(L); ++ ++ if (str1_isL == str2_isL) { // LL or UU ++ element_compare(str1, str2, zr, cnt2, tmp1, tmp2, v2, v4, v1, encLL, DIFFERENCE); ++ j(DONE); ++ } else { // LU or UL ++ Register strL = encLU ? str1 : str2; ++ Register strU = encLU ? str2 : str1; ++ VectorRegister vstr1 = encLU ? v4 : v0; ++ VectorRegister vstr2 = encLU ? v0 : v4; ++ ++ bind(loop); ++ vsetvli(tmp1, cnt2, Assembler::e8, Assembler::m2); ++ vle8_v(vstr1, strL); ++ vsetvli(tmp1, cnt2, Assembler::e16, Assembler::m4); ++ vzext_vf2(vstr2, vstr1); ++ vle16_v(vstr1, strU); ++ vmsne_vv(v0, vstr2, vstr1); ++ vfirst_m(tmp2, v0); ++ bgez(tmp2, DIFFERENCE); ++ sub(cnt2, cnt2, tmp1); ++ add(strL, strL, tmp1); ++ shadd(strU, tmp1, strU, tmp1, 1); ++ bnez(cnt2, loop); ++ j(DONE); ++ } ++ bind(DIFFERENCE); ++ slli(tmp1, tmp2, 1); ++ add(str1, str1, str1_isL ? tmp2 : tmp1); ++ add(str2, str2, str2_isL ? tmp2 : tmp1); ++ str1_isL ? lbu(tmp1, Address(str1, 0)) : lhu(tmp1, Address(str1, 0)); ++ str2_isL ? lbu(tmp2, Address(str2, 0)) : lhu(tmp2, Address(str2, 0)); ++ sub(result, tmp1, tmp2); ++ ++ bind(DONE); ++} ++ ++void C2_MacroAssembler::byte_array_inflate_v(Register src, Register dst, Register len, Register tmp) { ++ Label loop; ++ assert_different_registers(src, dst, len, tmp, t0); ++ ++ BLOCK_COMMENT("byte_array_inflate_v {"); ++ bind(loop); ++ vsetvli(tmp, len, Assembler::e8, Assembler::m2); ++ vle8_v(v2, src); ++ vsetvli(t0, len, Assembler::e16, Assembler::m4); ++ vzext_vf2(v0, v2); ++ vse16_v(v0, dst); ++ sub(len, len, tmp); ++ add(src, src, tmp); ++ shadd(dst, tmp, dst, tmp, 1); ++ bnez(len, loop); ++ BLOCK_COMMENT("} byte_array_inflate_v"); ++} ++ ++// Compress char[] array to byte[]. ++// result: the array length if every element in array can be encoded; 0, otherwise. ++void C2_MacroAssembler::char_array_compress_v(Register src, Register dst, Register len, Register result, Register tmp) { ++ Label done; ++ encode_iso_array_v(src, dst, len, result, tmp); ++ beqz(len, done); ++ mv(result, zr); ++ bind(done); ++} ++ ++// result: the number of elements had been encoded. ++void C2_MacroAssembler::encode_iso_array_v(Register src, Register dst, Register len, Register result, Register tmp) { ++ Label loop, DIFFERENCE, DONE; ++ ++ BLOCK_COMMENT("encode_iso_array_v {"); ++ mv(result, 0); ++ ++ bind(loop); ++ mv(tmp, 0xff); ++ vsetvli(t0, len, Assembler::e16, Assembler::m2); ++ vle16_v(v2, src); ++ // if element > 0xff, stop ++ vmsgtu_vx(v1, v2, tmp); ++ vfirst_m(tmp, v1); ++ vmsbf_m(v0, v1); ++ // compress char to byte ++ vsetvli(t0, len, Assembler::e8); ++ vncvt_x_x_w(v1, v2, Assembler::v0_t); ++ vse8_v(v1, dst, Assembler::v0_t); ++ ++ bgez(tmp, DIFFERENCE); ++ add(result, result, t0); ++ add(dst, dst, t0); ++ sub(len, len, t0); ++ shadd(src, t0, src, t0, 1); ++ bnez(len, loop); ++ j(DONE); ++ ++ bind(DIFFERENCE); ++ add(result, result, tmp); ++ ++ bind(DONE); ++ BLOCK_COMMENT("} encode_iso_array_v"); ++} ++ ++void C2_MacroAssembler::has_negatives_v(Register ary, Register len, ++ Register result, Register tmp) { ++ Label LOOP, DONE; ++ ++ BLOCK_COMMENT("has_negatives_v {"); ++ assert_different_registers(ary, len, result, tmp); ++ ++ mv(result, true); ++ ++ bind(LOOP); ++ vsetvli(t0, len, Assembler::e8, Assembler::m4); ++ vle8_v(v0, ary); ++ vmslt_vx(v0, v0, zr); ++ vfirst_m(tmp, v0); ++ bgez(tmp, DONE); ++ ++ sub(len, len, t0); ++ add(ary, ary, t0); ++ bnez(len, LOOP); ++ mv(result, false); ++ ++ bind(DONE); ++ BLOCK_COMMENT("} has_negatives_v"); ++} ++ ++void C2_MacroAssembler::string_indexof_char_v(Register str1, Register cnt1, ++ Register ch, Register result, ++ Register tmp1, Register tmp2, ++ bool isL) { ++ mv(result, zr); ++ ++ Label loop, MATCH, DONE; ++ Assembler::SEW sew = isL ? Assembler::e8 : Assembler::e16; ++ bind(loop); ++ vsetvli(tmp1, cnt1, sew, Assembler::m4); ++ vlex_v(v0, str1, sew); ++ vmseq_vx(v0, v0, ch); ++ vfirst_m(tmp2, v0); ++ bgez(tmp2, MATCH); // if equal, return index ++ ++ add(result, result, tmp1); ++ sub(cnt1, cnt1, tmp1); ++ if (!isL) slli(tmp1, tmp1, 1); ++ add(str1, str1, tmp1); ++ bnez(cnt1, loop); ++ ++ mv(result, -1); ++ j(DONE); ++ ++ bind(MATCH); ++ add(result, result, tmp2); ++ ++ bind(DONE); ++} ++ ++// Set dst to NaN if any NaN input. ++void C2_MacroAssembler::minmax_FD_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, ++ bool is_double, bool is_min) { ++ assert_different_registers(dst, src1, src2); ++ ++ vsetvli(t0, x0, is_double ? Assembler::e64 : Assembler::e32); ++ ++ is_min ? vfmin_vv(dst, src1, src2) ++ : vfmax_vv(dst, src1, src2); ++ ++ vmfne_vv(v0, src1, src1); ++ vfadd_vv(dst, src1, src1, Assembler::v0_t); ++ vmfne_vv(v0, src2, src2); ++ vfadd_vv(dst, src2, src2, Assembler::v0_t); ++} ++ ++// Set dst to NaN if any NaN input. ++void C2_MacroAssembler::reduce_minmax_FD_v(FloatRegister dst, ++ FloatRegister src1, VectorRegister src2, ++ VectorRegister tmp1, VectorRegister tmp2, ++ bool is_double, bool is_min) { ++ assert_different_registers(src2, tmp1, tmp2); ++ ++ Label L_done, L_NaN; ++ vsetvli(t0, x0, is_double ? Assembler::e64 : Assembler::e32); ++ vfmv_s_f(tmp2, src1); ++ ++ is_min ? vfredmin_vs(tmp1, src2, tmp2) ++ : vfredmax_vs(tmp1, src2, tmp2); ++ ++ fsflags(zr); ++ // Checking NaNs ++ vmflt_vf(tmp2, src2, src1); ++ frflags(t0); ++ bnez(t0, L_NaN); ++ j(L_done); ++ ++ bind(L_NaN); ++ vfmv_s_f(tmp2, src1); ++ vfredusum_vs(tmp1, src2, tmp2); ++ ++ bind(L_done); ++ vfmv_f_s(dst, tmp1); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +@@ -0,0 +1,193 @@ ++/* ++ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP ++#define CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP ++ ++// C2_MacroAssembler contains high-level macros for C2 ++ ++ private: ++ void element_compare(Register r1, Register r2, ++ Register result, Register cnt, ++ Register tmp1, Register tmp2, ++ VectorRegister vr1, VectorRegister vr2, ++ VectorRegister vrs, ++ bool is_latin, Label& DONE); ++ public: ++ ++ void string_compare(Register str1, Register str2, ++ Register cnt1, Register cnt2, Register result, ++ Register tmp1, Register tmp2, Register tmp3, ++ int ae); ++ ++ void string_indexof_char_short(Register str1, Register cnt1, ++ Register ch, Register result, ++ bool isL); ++ ++ void string_indexof_char(Register str1, Register cnt1, ++ Register ch, Register result, ++ Register tmp1, Register tmp2, ++ Register tmp3, Register tmp4, ++ bool isL); ++ ++ void string_indexof(Register str1, Register str2, ++ Register cnt1, Register cnt2, ++ Register tmp1, Register tmp2, ++ Register tmp3, Register tmp4, ++ Register tmp5, Register tmp6, ++ Register result, int ae); ++ ++ void string_indexof_linearscan(Register haystack, Register needle, ++ Register haystack_len, Register needle_len, ++ Register tmp1, Register tmp2, ++ Register tmp3, Register tmp4, ++ int needle_con_cnt, Register result, int ae); ++ ++ void arrays_equals(Register r1, Register r2, ++ Register tmp3, Register tmp4, ++ Register tmp5, Register tmp6, ++ Register result, Register cnt1, ++ int elem_size); ++ ++ void string_equals(Register r1, Register r2, ++ Register result, Register cnt1, ++ int elem_size); ++ ++ // refer to conditional_branches and float_conditional_branches ++ static const int bool_test_bits = 3; ++ static const int neg_cond_bits = 2; ++ static const int unsigned_branch_mask = 1 << bool_test_bits; ++ static const int double_branch_mask = 1 << bool_test_bits; ++ ++ // cmp ++ void cmp_branch(int cmpFlag, ++ Register op1, Register op2, ++ Label& label, bool is_far = false); ++ ++ void float_cmp_branch(int cmpFlag, ++ FloatRegister op1, FloatRegister op2, ++ Label& label, bool is_far = false); ++ ++ void enc_cmpUEqNeLeGt_imm0_branch(int cmpFlag, Register op, ++ Label& L, bool is_far = false); ++ ++ void enc_cmpEqNe_imm0_branch(int cmpFlag, Register op, ++ Label& L, bool is_far = false); ++ ++ void enc_cmove(int cmpFlag, ++ Register op1, Register op2, ++ Register dst, Register src); ++ ++ void spill(Register r, bool is64, int offset) { ++ is64 ? sd(r, Address(sp, offset)) ++ : sw(r, Address(sp, offset)); ++ } ++ ++ void spill(FloatRegister f, bool is64, int offset) { ++ is64 ? fsd(f, Address(sp, offset)) ++ : fsw(f, Address(sp, offset)); ++ } ++ ++ void spill(VectorRegister v, int offset) { ++ add(t0, sp, offset); ++ vs1r_v(v, t0); ++ } ++ ++ void unspill(Register r, bool is64, int offset) { ++ is64 ? ld(r, Address(sp, offset)) ++ : lw(r, Address(sp, offset)); ++ } ++ ++ void unspillu(Register r, bool is64, int offset) { ++ is64 ? ld(r, Address(sp, offset)) ++ : lwu(r, Address(sp, offset)); ++ } ++ ++ void unspill(FloatRegister f, bool is64, int offset) { ++ is64 ? fld(f, Address(sp, offset)) ++ : flw(f, Address(sp, offset)); ++ } ++ ++ void unspill(VectorRegister v, int offset) { ++ add(t0, sp, offset); ++ vl1re8_v(v, t0); ++ } ++ ++ void spill_copy_vector_stack_to_stack(int src_offset, int dst_offset, int vec_reg_size_in_bytes) { ++ assert(vec_reg_size_in_bytes % 16 == 0, "unexpected vector reg size"); ++ unspill(v0, src_offset); ++ spill(v0, dst_offset); ++ } ++ ++ void minmax_FD(FloatRegister dst, ++ FloatRegister src1, FloatRegister src2, ++ bool is_double, bool is_min); ++ ++ // intrinsic methods implemented by rvv instructions ++ void string_equals_v(Register r1, Register r2, ++ Register result, Register cnt1, ++ int elem_size); ++ ++ void arrays_equals_v(Register r1, Register r2, ++ Register result, Register cnt1, ++ int elem_size); ++ ++ void string_compare_v(Register str1, Register str2, ++ Register cnt1, Register cnt2, ++ Register result, ++ Register tmp1, Register tmp2, ++ int encForm); ++ ++ void clear_array_v(Register base, Register cnt); ++ ++ void byte_array_inflate_v(Register src, Register dst, ++ Register len, Register tmp); ++ ++ void char_array_compress_v(Register src, Register dst, ++ Register len, Register result, ++ Register tmp); ++ ++ void encode_iso_array_v(Register src, Register dst, ++ Register len, Register result, ++ Register tmp); ++ ++ void has_negatives_v(Register ary, Register len, ++ Register result, Register tmp); ++ ++ void string_indexof_char_v(Register str1, Register cnt1, ++ Register ch, Register result, ++ Register tmp1, Register tmp2, ++ bool isL); ++ ++ void minmax_FD_v(VectorRegister dst, ++ VectorRegister src1, VectorRegister src2, ++ bool is_double, bool is_min); ++ ++ void reduce_minmax_FD_v(FloatRegister dst, ++ FloatRegister src1, VectorRegister src2, ++ VectorRegister tmp1, VectorRegister tmp2, ++ bool is_double, bool is_min); ++ ++#endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c2_globals_riscv.hpp +@@ -0,0 +1,85 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_C2_GLOBALS_RISCV_HPP ++#define CPU_RISCV_C2_GLOBALS_RISCV_HPP ++ ++#include "utilities/globalDefinitions.hpp" ++#include "utilities/macros.hpp" ++ ++// Sets the default values for platform dependent flags used by the server compiler. ++// (see c2_globals.hpp). Alpha-sorted. ++ ++define_pd_global(bool, BackgroundCompilation, true); ++define_pd_global(bool, CICompileOSR, true); ++define_pd_global(bool, InlineIntrinsics, true); ++define_pd_global(bool, PreferInterpreterNativeStubs, false); ++define_pd_global(bool, ProfileTraps, true); ++define_pd_global(bool, UseOnStackReplacement, true); ++define_pd_global(bool, ProfileInterpreter, true); ++define_pd_global(bool, TieredCompilation, COMPILER1_PRESENT(true) NOT_COMPILER1(false)); ++define_pd_global(intx, CompileThreshold, 10000); ++ ++define_pd_global(intx, OnStackReplacePercentage, 140); ++define_pd_global(intx, ConditionalMoveLimit, 0); ++define_pd_global(intx, FLOATPRESSURE, 32); ++define_pd_global(intx, FreqInlineSize, 325); ++define_pd_global(intx, MinJumpTableSize, 10); ++define_pd_global(intx, INTPRESSURE, 24); ++define_pd_global(intx, InteriorEntryAlignment, 16); ++define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K)); ++define_pd_global(intx, LoopUnrollLimit, 60); ++define_pd_global(intx, LoopPercentProfileLimit, 10); ++// InitialCodeCacheSize derived from specjbb2000 run. ++define_pd_global(intx, InitialCodeCacheSize, 2496*K); // Integral multiple of CodeCacheExpansionSize ++define_pd_global(intx, CodeCacheExpansionSize, 64*K); ++ ++// Ergonomics related flags ++define_pd_global(uint64_t,MaxRAM, 128ULL*G); ++define_pd_global(intx, RegisterCostAreaRatio, 16000); ++ ++// Peephole and CISC spilling both break the graph, and so makes the ++// scheduler sick. ++define_pd_global(bool, OptoPeephole, false); ++define_pd_global(bool, UseCISCSpill, false); ++define_pd_global(bool, OptoScheduling, true); ++define_pd_global(bool, OptoBundling, false); ++define_pd_global(bool, OptoRegScheduling, false); ++define_pd_global(bool, SuperWordLoopUnrollAnalysis, true); ++define_pd_global(bool, IdealizeClearArrayNode, true); ++ ++define_pd_global(intx, ReservedCodeCacheSize, 48*M); ++define_pd_global(intx, NonProfiledCodeHeapSize, 21*M); ++define_pd_global(intx, ProfiledCodeHeapSize, 22*M); ++define_pd_global(intx, NonNMethodCodeHeapSize, 5*M ); ++define_pd_global(uintx, CodeCacheMinBlockLength, 6); ++define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K); ++ ++// Ergonomics related flags ++define_pd_global(bool, NeverActAsServerClassMachine, false); ++ ++define_pd_global(bool, TrapBasedRangeChecks, false); // Not needed. ++ ++#endif // CPU_RISCV_C2_GLOBALS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c2_init_riscv.cpp +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "opto/compile.hpp" ++#include "opto/node.hpp" ++ ++// processor dependent initialization for riscv ++ ++extern void reg_mask_init(); ++ ++void Compile::pd_compiler2_init() { ++ guarantee(CodeEntryAlignment >= InteriorEntryAlignment, "" ); ++ reg_mask_init(); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/c2_safepointPollStubTable_riscv.cpp +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "opto/compile.hpp" ++#include "opto/node.hpp" ++#include "opto/output.hpp" ++#include "runtime/sharedRuntime.hpp" ++ ++#define __ masm. ++void C2SafepointPollStubTable::emit_stub_impl(MacroAssembler& masm, C2SafepointPollStub* entry) const { ++ assert(SharedRuntime::polling_page_return_handler_blob() != NULL, ++ "polling page return stub not created yet"); ++ address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point(); ++ RuntimeAddress callback_addr(stub); ++ ++ __ bind(entry->_stub_label); ++ InternalAddress safepoint_pc(__ pc() - __ offset() + entry->_safepoint_offset); ++ __ relocate(safepoint_pc.rspec(), [&] { ++ __ la(t0, safepoint_pc.target()); ++ }); ++ __ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset())); ++ __ far_jump(callback_addr); ++} ++#undef __ +--- /dev/null ++++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_CODEBUFFER_RISCV_HPP ++#define CPU_RISCV_CODEBUFFER_RISCV_HPP ++ ++private: ++ void pd_initialize() {} ++ ++public: ++ void flush_bundle(bool start_new_bundle) {} ++ ++#endif // CPU_RISCV_CODEBUFFER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/compiledIC_riscv.cpp +@@ -0,0 +1,149 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "code/compiledIC.hpp" ++#include "code/icBuffer.hpp" ++#include "code/nmethod.hpp" ++#include "memory/resourceArea.hpp" ++#include "runtime/mutexLocker.hpp" ++#include "runtime/safepoint.hpp" ++ ++// ---------------------------------------------------------------------------- ++ ++#define __ _masm. ++address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) { ++ precond(cbuf.stubs()->start() != badAddress); ++ precond(cbuf.stubs()->end() != badAddress); ++ // Stub is fixed up when the corresponding call is converted from ++ // calling compiled code to calling interpreted code. ++ // mv xmethod, 0 ++ // jalr -4 # to self ++ ++ if (mark == NULL) { ++ mark = cbuf.insts_mark(); // Get mark within main instrs section. ++ } ++ ++ // Note that the code buffer's insts_mark is always relative to insts. ++ // That's why we must use the macroassembler to generate a stub. ++ MacroAssembler _masm(&cbuf); ++ ++ address base = __ start_a_stub(to_interp_stub_size()); ++ int offset = __ offset(); ++ if (base == NULL) { ++ return NULL; // CodeBuffer::expand failed ++ } ++ // static stub relocation stores the instruction address of the call ++ __ relocate(static_stub_Relocation::spec(mark)); ++ ++ __ emit_static_call_stub(); ++ ++ assert((__ offset() - offset) <= (int)to_interp_stub_size(), "stub too big"); ++ __ end_a_stub(); ++ return base; ++} ++#undef __ ++ ++int CompiledStaticCall::to_interp_stub_size() { ++ // (lui, addi, slli, addi, slli, addi) + (lui, addi, slli, addi, slli) + jalr ++ return 12 * NativeInstruction::instruction_size; ++} ++ ++int CompiledStaticCall::to_trampoline_stub_size() { ++ // Somewhat pessimistically, we count 4 instructions here (although ++ // there are only 3) because we sometimes emit an alignment nop. ++ // Trampoline stubs are always word aligned. ++ return NativeInstruction::instruction_size + NativeCallTrampolineStub::instruction_size; ++} ++ ++// Relocation entries for call stub, compiled java to interpreter. ++int CompiledStaticCall::reloc_to_interp_stub() { ++ return 4; // 3 in emit_to_interp_stub + 1 in emit_call ++} ++ ++void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, address entry) { ++ address stub = find_stub(); ++ guarantee(stub != NULL, "stub not found"); ++ ++ if (TraceICs) { ++ ResourceMark rm; ++ tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s", ++ p2i(instruction_address()), ++ callee->name_and_sig_as_C_string()); ++ } ++ ++ // Creation also verifies the object. ++ NativeMovConstReg* method_holder ++ = nativeMovConstReg_at(stub); ++#ifdef ASSERT ++ NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address()); ++ ++ verify_mt_safe(callee, entry, method_holder, jump); ++#endif ++ // Update stub. ++ method_holder->set_data((intptr_t)callee()); ++ NativeGeneralJump::insert_unconditional(method_holder->next_instruction_address(), entry); ++ ICache::invalidate_range(stub, to_interp_stub_size()); ++ // Update jump to call. ++ set_destination_mt_safe(stub); ++} ++ ++void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) { ++ // Reset stub. ++ address stub = static_stub->addr(); ++ assert(stub != NULL, "stub not found"); ++ assert(CompiledICLocker::is_safe(stub), "mt unsafe call"); ++ // Creation also verifies the object. ++ NativeMovConstReg* method_holder ++ = nativeMovConstReg_at(stub); ++ method_holder->set_data(0); ++ NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); ++ jump->set_jump_destination((address)-1); ++} ++ ++//----------------------------------------------------------------------------- ++// Non-product mode code ++#ifndef PRODUCT ++ ++void CompiledDirectStaticCall::verify() { ++ // Verify call. ++ _call->verify(); ++ _call->verify_alignment(); ++ ++ // Verify stub. ++ address stub = find_stub(); ++ assert(stub != NULL, "no stub found for static call"); ++ // Creation also verifies the object. ++ NativeMovConstReg* method_holder ++ = nativeMovConstReg_at(stub); ++ NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); ++ ++ // Verify state. ++ assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check"); ++} ++ ++#endif // !PRODUCT +--- /dev/null ++++ b/src/hotspot/cpu/riscv/copy_riscv.hpp +@@ -0,0 +1,143 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_COPY_RISCV_HPP ++#define CPU_RISCV_COPY_RISCV_HPP ++ ++#include OS_CPU_HEADER(copy) ++ ++static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) { ++ julong* to = (julong*) tohw; ++ julong v = ((julong) value << 32) | value; ++ while (count-- > 0) { ++ *to++ = v; ++ } ++} ++ ++static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) { ++ pd_fill_to_words(tohw, count, value); ++} ++ ++static void pd_fill_to_bytes(void* to, size_t count, jubyte value) { ++ (void)memset(to, value, count); ++} ++ ++static void pd_zero_to_words(HeapWord* tohw, size_t count) { ++ pd_fill_to_words(tohw, count, 0); ++} ++ ++static void pd_zero_to_bytes(void* to, size_t count) { ++ (void)memset(to, 0, count); ++} ++ ++static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { ++ (void)memmove(to, from, count * HeapWordSize); ++} ++ ++static inline void pd_disjoint_words_helper(const HeapWord* from, HeapWord* to, size_t count, bool is_atomic) { ++ switch (count) { ++ case 8: to[7] = from[7]; // fall through ++ case 7: to[6] = from[6]; // fall through ++ case 6: to[5] = from[5]; // fall through ++ case 5: to[4] = from[4]; // fall through ++ case 4: to[3] = from[3]; // fall through ++ case 3: to[2] = from[2]; // fall through ++ case 2: to[1] = from[1]; // fall through ++ case 1: to[0] = from[0]; // fall through ++ case 0: break; ++ default: ++ if (is_atomic) { ++ while (count-- > 0) { *to++ = *from++; } ++ } else { ++ memcpy(to, from, count * HeapWordSize); ++ } ++ } ++} ++ ++static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { ++ pd_disjoint_words_helper(from, to, count, false); ++} ++ ++static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { ++ pd_disjoint_words_helper(from, to, count, true); ++} ++ ++static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { ++ pd_conjoint_words(from, to, count); ++} ++ ++static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { ++ pd_disjoint_words(from, to, count); ++} ++ ++static void pd_conjoint_bytes(const void* from, void* to, size_t count) { ++ (void)memmove(to, from, count); ++} ++ ++static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { ++ pd_conjoint_bytes(from, to, count); ++} ++ ++static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { ++ _Copy_conjoint_jshorts_atomic(from, to, count); ++} ++ ++static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { ++ _Copy_conjoint_jints_atomic(from, to, count); ++} ++ ++static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { ++ _Copy_conjoint_jlongs_atomic(from, to, count); ++} ++ ++static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { ++ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size."); ++ _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); ++} ++ ++static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { ++ _Copy_arrayof_conjoint_bytes(from, to, count); ++} ++ ++static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { ++ _Copy_arrayof_conjoint_jshorts(from, to, count); ++} ++ ++static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { ++ _Copy_arrayof_conjoint_jints(from, to, count); ++} ++ ++static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { ++ _Copy_arrayof_conjoint_jlongs(from, to, count); ++} ++ ++static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { ++ assert(!UseCompressedOops, "foo!"); ++ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); ++ _Copy_arrayof_conjoint_jlongs(from, to, count); ++} ++ ++#endif // CPU_RISCV_COPY_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/disassembler_riscv.hpp +@@ -0,0 +1,50 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_DISASSEMBLER_RISCV_HPP ++#define CPU_RISCV_DISASSEMBLER_RISCV_HPP ++ ++static int pd_instruction_alignment() { ++ return 1; ++} ++ ++static const char* pd_cpu_opts() { ++ return ""; ++} ++ ++// special-case instruction decoding. ++// There may be cases where the binutils disassembler doesn't do ++// the perfect job. In those cases, decode_instruction0 may kick in ++// and do it right. ++// If nothing had to be done, just return "here", otherwise return "here + instr_len(here)" ++static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL) { ++ return here; ++} ++ ++// platform-specific instruction annotations (like value of loaded constants) ++static void annotate(address pc, outputStream* st) {} ++ ++#endif // CPU_RISCV_DISASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/foreign_globals_riscv.cpp +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2020, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "prims/foreign_globals.hpp" ++#include "utilities/debug.hpp" ++ ++// Stubbed out, implement later ++const ABIDescriptor ForeignGlobals::parse_abi_descriptor_impl(jobject jabi) const { ++ Unimplemented(); ++ return {}; ++} ++ ++const BufferLayout ForeignGlobals::parse_buffer_layout_impl(jobject jlayout) const { ++ Unimplemented(); ++ return {}; ++} ++ ++const CallRegs ForeignGlobals::parse_call_regs_impl(jobject jconv) const { ++ ShouldNotCallThis(); ++ return {}; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/foreign_globals_riscv.hpp +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2020, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_FOREIGN_GLOBALS_RISCV_HPP ++#define CPU_RISCV_FOREIGN_GLOBALS_RISCV_HPP ++ ++class ABIDescriptor {}; ++class BufferLayout {}; ++ ++#endif // CPU_RISCV_FOREIGN_GLOBALS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/frame_riscv.cpp +@@ -0,0 +1,688 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "compiler/oopMap.hpp" ++#include "interpreter/interpreter.hpp" ++#include "memory/resourceArea.hpp" ++#include "memory/universe.hpp" ++#include "oops/markWord.hpp" ++#include "oops/method.hpp" ++#include "oops/oop.inline.hpp" ++#include "prims/methodHandles.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/handles.inline.hpp" ++#include "runtime/javaCalls.hpp" ++#include "runtime/monitorChunk.hpp" ++#include "runtime/os.inline.hpp" ++#include "runtime/signature.hpp" ++#include "runtime/stackWatermarkSet.hpp" ++#include "runtime/stubCodeGenerator.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "vmreg_riscv.inline.hpp" ++#ifdef COMPILER1 ++#include "c1/c1_Runtime1.hpp" ++#include "runtime/vframeArray.hpp" ++#endif ++ ++#ifdef ASSERT ++void RegisterMap::check_location_valid() { ++} ++#endif ++ ++ ++// Profiling/safepoint support ++ ++bool frame::safe_for_sender(JavaThread *thread) { ++ address addr_sp = (address)_sp; ++ address addr_fp = (address)_fp; ++ address unextended_sp = (address)_unextended_sp; ++ ++ // consider stack guards when trying to determine "safe" stack pointers ++ // sp must be within the usable part of the stack (not in guards) ++ if (!thread->is_in_usable_stack(addr_sp)) { ++ return false; ++ } ++ ++ // When we are running interpreted code the machine stack pointer, SP, is ++ // set low enough so that the Java expression stack can grow and shrink ++ // without ever exceeding the machine stack bounds. So, ESP >= SP. ++ ++ // When we call out of an interpreted method, SP is incremented so that ++ // the space between SP and ESP is removed. The SP saved in the callee's ++ // frame is the SP *before* this increment. So, when we walk a stack of ++ // interpreter frames the sender's SP saved in a frame might be less than ++ // the SP at the point of call. ++ ++ // So unextended sp must be within the stack but we need not to check ++ // that unextended sp >= sp ++ ++ if (!thread->is_in_full_stack_checked(unextended_sp)) { ++ return false; ++ } ++ ++ // an fp must be within the stack and above (but not equal) sp ++ // second evaluation on fp+ is added to handle situation where fp is -1 ++ bool fp_safe = thread->is_in_stack_range_excl(addr_fp, addr_sp) && ++ thread->is_in_full_stack_checked(addr_fp + (return_addr_offset * sizeof(void*))); ++ ++ // We know sp/unextended_sp are safe only fp is questionable here ++ ++ // If the current frame is known to the code cache then we can attempt to ++ // to construct the sender and do some validation of it. This goes a long way ++ // toward eliminating issues when we get in frame construction code ++ ++ if (_cb != NULL) { ++ ++ // First check if frame is complete and tester is reliable ++ // Unfortunately we can only check frame complete for runtime stubs and nmethod ++ // other generic buffer blobs are more problematic so we just assume they are ++ // ok. adapter blobs never have a frame complete and are never ok. ++ ++ if (!_cb->is_frame_complete_at(_pc)) { ++ if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { ++ return false; ++ } ++ } ++ ++ // Could just be some random pointer within the codeBlob ++ if (!_cb->code_contains(_pc)) { ++ return false; ++ } ++ ++ // Entry frame checks ++ if (is_entry_frame()) { ++ // an entry frame must have a valid fp. ++ return fp_safe && is_entry_frame_valid(thread); ++ } ++ ++ intptr_t* sender_sp = NULL; ++ intptr_t* sender_unextended_sp = NULL; ++ address sender_pc = NULL; ++ intptr_t* saved_fp = NULL; ++ ++ if (is_interpreted_frame()) { ++ // fp must be safe ++ if (!fp_safe) { ++ return false; ++ } ++ ++ sender_pc = (address)this->fp()[return_addr_offset]; ++ // for interpreted frames, the value below is the sender "raw" sp, ++ // which can be different from the sender unextended sp (the sp seen ++ // by the sender) because of current frame local variables ++ sender_sp = (intptr_t*) addr_at(sender_sp_offset); ++ sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset]; ++ saved_fp = (intptr_t*) this->fp()[link_offset]; ++ } else { ++ // must be some sort of compiled/runtime frame ++ // fp does not have to be safe (although it could be check for c1?) ++ ++ // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc ++ if (_cb->frame_size() <= 0) { ++ return false; ++ } ++ ++ sender_sp = _unextended_sp + _cb->frame_size(); ++ // Is sender_sp safe? ++ if (!thread->is_in_full_stack_checked((address)sender_sp)) { ++ return false; ++ } ++ ++ sender_unextended_sp = sender_sp; ++ sender_pc = (address) *(sender_sp - 1); ++ saved_fp = (intptr_t*) *(sender_sp - 2); ++ } ++ ++ ++ // If the potential sender is the interpreter then we can do some more checking ++ if (Interpreter::contains(sender_pc)) { ++ ++ // fp is always saved in a recognizable place in any code we generate. However ++ // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved fp ++ // is really a frame pointer. ++ if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) { ++ return false; ++ } ++ ++ // construct the potential sender ++ frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); ++ ++ return sender.is_interpreted_frame_valid(thread); ++ } ++ ++ // We must always be able to find a recognizable pc ++ CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc); ++ if (sender_pc == NULL || sender_blob == NULL) { ++ return false; ++ } ++ ++ // Could be a zombie method ++ if (sender_blob->is_zombie() || sender_blob->is_unloaded()) { ++ return false; ++ } ++ ++ // Could just be some random pointer within the codeBlob ++ if (!sender_blob->code_contains(sender_pc)) { ++ return false; ++ } ++ ++ // We should never be able to see an adapter if the current frame is something from code cache ++ if (sender_blob->is_adapter_blob()) { ++ return false; ++ } ++ ++ // Could be the call_stub ++ if (StubRoutines::returns_to_call_stub(sender_pc)) { ++ if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) { ++ return false; ++ } ++ ++ // construct the potential sender ++ frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); ++ ++ // Validate the JavaCallWrapper an entry frame must have ++ address jcw = (address)sender.entry_frame_call_wrapper(); ++ ++ bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp()); ++ ++ return jcw_safe; ++ } ++ ++ CompiledMethod* nm = sender_blob->as_compiled_method_or_null(); ++ if (nm != NULL) { ++ if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) || ++ nm->method()->is_method_handle_intrinsic()) { ++ return false; ++ } ++ } ++ ++ // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size ++ // because the return address counts against the callee's frame. ++ if (sender_blob->frame_size() <= 0) { ++ assert(!sender_blob->is_compiled(), "should count return address at least"); ++ return false; ++ } ++ ++ // We should never be able to see anything here except an nmethod. If something in the ++ // code cache (current frame) is called by an entity within the code cache that entity ++ // should not be anything but the call stub (already covered), the interpreter (already covered) ++ // or an nmethod. ++ if (!sender_blob->is_compiled()) { ++ return false; ++ } ++ ++ // Could put some more validation for the potential non-interpreted sender ++ // frame we'd create by calling sender if I could think of any. Wait for next crash in forte... ++ ++ // One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb ++ ++ // We've validated the potential sender that would be created ++ return true; ++ } ++ ++ // Must be native-compiled frame. Since sender will try and use fp to find ++ // linkages it must be safe ++ if (!fp_safe) { ++ return false; ++ } ++ ++ // Will the pc we fetch be non-zero (which we'll find at the oldest frame) ++ if ((address)this->fp()[return_addr_offset] == NULL) { return false; } ++ ++ return true; ++} ++ ++void frame::patch_pc(Thread* thread, address pc) { ++ assert(_cb == CodeCache::find_blob(pc), "unexpected pc"); ++ address* pc_addr = &(((address*) sp())[-1]); ++ if (TracePcPatching) { ++ tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]", ++ p2i(pc_addr), p2i(*pc_addr), p2i(pc)); ++ } ++ // Either the return address is the original one or we are going to ++ // patch in the same address that's already there. ++ assert(_pc == *pc_addr || pc == *pc_addr, "must be"); ++ *pc_addr = pc; ++ address original_pc = CompiledMethod::get_deopt_original_pc(this); ++ if (original_pc != NULL) { ++ assert(original_pc == _pc, "expected original PC to be stored before patching"); ++ _deopt_state = is_deoptimized; ++ // leave _pc as is ++ } else { ++ _deopt_state = not_deoptimized; ++ _pc = pc; ++ } ++} ++ ++bool frame::is_interpreted_frame() const { ++ return Interpreter::contains(pc()); ++} ++ ++int frame::frame_size(RegisterMap* map) const { ++ frame sender = this->sender(map); ++ return sender.sp() - sp(); ++} ++ ++intptr_t* frame::entry_frame_argument_at(int offset) const { ++ // convert offset to index to deal with tsi ++ int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize); ++ // Entry frame's arguments are always in relation to unextended_sp() ++ return &unextended_sp()[index]; ++} ++ ++// sender_sp ++intptr_t* frame::interpreter_frame_sender_sp() const { ++ assert(is_interpreted_frame(), "interpreted frame expected"); ++ return (intptr_t*) at(interpreter_frame_sender_sp_offset); ++} ++ ++void frame::set_interpreter_frame_sender_sp(intptr_t* sender_sp) { ++ assert(is_interpreted_frame(), "interpreted frame expected"); ++ ptr_at_put(interpreter_frame_sender_sp_offset, (intptr_t) sender_sp); ++} ++ ++ ++// monitor elements ++ ++BasicObjectLock* frame::interpreter_frame_monitor_begin() const { ++ return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset); ++} ++ ++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 ++ assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer"); ++ assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer"); ++ return result; ++} ++ ++void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) { ++ *((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value; ++} ++ ++// Used by template based interpreter deoptimization ++void frame::interpreter_frame_set_last_sp(intptr_t* last_sp) { ++ *((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = last_sp; ++} ++ ++frame frame::sender_for_entry_frame(RegisterMap* map) const { ++ assert(map != NULL, "map must be set"); ++ // Java frame called from C; skip all C frames and return top C ++ // frame of that chunk as the sender ++ JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); ++ assert(!entry_frame_is_first(), "next Java fp must be non zero"); ++ assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); ++ // Since we are walking the stack now this nested anchor is obviously walkable ++ // even if it wasn't when it was stacked. ++ jfa->make_walkable(); ++ map->clear(); ++ assert(map->include_argument_oops(), "should be set by clear"); ++ vmassert(jfa->last_Java_pc() != NULL, "not walkable"); ++ frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc()); ++ return fr; ++} ++ ++OptimizedEntryBlob::FrameData* OptimizedEntryBlob::frame_data_for_frame(const frame& frame) const { ++ ShouldNotCallThis(); ++ return nullptr; ++} ++ ++bool frame::optimized_entry_frame_is_first() const { ++ ShouldNotCallThis(); ++ return false; ++} ++ ++frame frame::sender_for_optimized_entry_frame(RegisterMap* map) const { ++ ShouldNotCallThis(); ++ return {}; ++} ++ ++//------------------------------------------------------------------------------ ++// frame::verify_deopt_original_pc ++// ++// Verifies the calculated original PC of a deoptimization PC for the ++// given unextended SP. ++#ifdef ASSERT ++void frame::verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp) { ++ frame fr; ++ ++ // This is ugly but it's better than to change {get,set}_original_pc ++ // to take an SP value as argument. And it's only a debugging ++ // method anyway. ++ fr._unextended_sp = unextended_sp; ++ ++ assert_cond(nm != NULL); ++ address original_pc = nm->get_original_pc(&fr); ++ assert(nm->insts_contains_inclusive(original_pc), ++ "original PC must be in the main code section of the the compiled method (or must be immediately following it)"); ++} ++#endif ++ ++//------------------------------------------------------------------------------ ++// frame::adjust_unextended_sp ++void frame::adjust_unextended_sp() { ++ // On riscv, sites calling method handle intrinsics and lambda forms are treated ++ // as any other call site. Therefore, no special action is needed when we are ++ // returning to any of these call sites. ++ ++ if (_cb != NULL) { ++ CompiledMethod* sender_cm = _cb->as_compiled_method_or_null(); ++ if (sender_cm != NULL) { ++ // If the sender PC is a deoptimization point, get the original PC. ++ if (sender_cm->is_deopt_entry(_pc) || ++ sender_cm->is_deopt_mh_entry(_pc)) { ++ DEBUG_ONLY(verify_deopt_original_pc(sender_cm, _unextended_sp)); ++ } ++ } ++ } ++} ++ ++//------------------------------------------------------------------------------ ++// frame::update_map_with_saved_link ++void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) { ++ // The interpreter and compiler(s) always save fp in a known ++ // location on entry. We must record where that location is ++ // so that if fp was live on callout from c2 we can find ++ // the saved copy no matter what it called. ++ ++ // Since the interpreter always saves fp if we record where it is then ++ // we don't have to always save fp on entry and exit to c2 compiled ++ // code, on entry will be enough. ++ assert(map != NULL, "map must be set"); ++ map->set_location(::fp->as_VMReg(), (address) link_addr); ++ // this is weird "H" ought to be at a higher address however the ++ // oopMaps seems to have the "H" regs at the same address and the ++ // vanilla register. ++ map->set_location(::fp->as_VMReg()->next(), (address) link_addr); ++} ++ ++ ++//------------------------------------------------------------------------------ ++// frame::sender_for_interpreter_frame ++frame frame::sender_for_interpreter_frame(RegisterMap* map) const { ++ // SP is the raw SP from the sender after adapter or interpreter ++ // extension. ++ intptr_t* sender_sp = this->sender_sp(); ++ ++ // This is the sp before any possible extension (adapter/locals). ++ intptr_t* unextended_sp = interpreter_frame_sender_sp(); ++ ++#ifdef COMPILER2 ++ assert(map != NULL, "map must be set"); ++ if (map->update_map()) { ++ update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); ++ } ++#endif // COMPILER2 ++ ++ return frame(sender_sp, unextended_sp, link(), sender_pc()); ++} ++ ++ ++//------------------------------------------------------------------------------ ++// frame::sender_for_compiled_frame ++frame frame::sender_for_compiled_frame(RegisterMap* map) const { ++ // we cannot rely upon the last fp having been saved to the thread ++ // in C2 code but it will have been pushed onto the stack. so we ++ // have to find it relative to the unextended sp ++ ++ assert(_cb->frame_size() >= 0, "must have non-zero frame size"); ++ intptr_t* l_sender_sp = unextended_sp() + _cb->frame_size(); ++ intptr_t* unextended_sp = l_sender_sp; ++ ++ // the return_address is always the word on the stack ++ address sender_pc = (address) *(l_sender_sp + frame::return_addr_offset); ++ ++ intptr_t** saved_fp_addr = (intptr_t**) (l_sender_sp + frame::link_offset); ++ ++ assert(map != NULL, "map must be set"); ++ if (map->update_map()) { ++ // Tell GC to use argument oopmaps for some runtime stubs that need it. ++ // For C1, the runtime stub might not have oop maps, so set this flag ++ // outside of update_register_map. ++ map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread())); ++ if (_cb->oop_maps() != NULL) { ++ OopMapSet::update_register_map(this, map); ++ } ++ ++ // Since the prolog does the save and restore of FP there is no ++ // oopmap for it so we must fill in its location as if there was ++ // an oopmap entry since if our caller was compiled code there ++ // could be live jvm state in it. ++ update_map_with_saved_link(map, saved_fp_addr); ++ } ++ ++ return frame(l_sender_sp, unextended_sp, *saved_fp_addr, sender_pc); ++} ++ ++//------------------------------------------------------------------------------ ++// frame::sender_raw ++frame frame::sender_raw(RegisterMap* map) const { ++ // Default is we done have to follow them. The sender_for_xxx will ++ // update it accordingly ++ assert(map != NULL, "map must be set"); ++ 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); ++ } ++ assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); ++ ++ // This test looks odd: why is it not is_compiled_frame() ? That's ++ // because stubs also have OOP maps. ++ if (_cb != NULL) { ++ return sender_for_compiled_frame(map); ++ } ++ ++ // Must be native-compiled frame, i.e. the marshaling code for native ++ // methods that exists in the core system. ++ return frame(sender_sp(), link(), sender_pc()); ++} ++ ++frame frame::sender(RegisterMap* map) const { ++ frame result = sender_raw(map); ++ ++ if (map->process_frames()) { ++ StackWatermarkSet::on_iteration(map->thread(), result); ++ } ++ ++ return result; ++} ++ ++bool frame::is_interpreted_frame_valid(JavaThread* thread) const { ++ assert(is_interpreted_frame(), "Not an interpreted frame"); ++ // These are reasonable sanity checks ++ if (fp() == NULL || (intptr_t(fp()) & (wordSize-1)) != 0) { ++ return false; ++ } ++ if (sp() == NULL || (intptr_t(sp()) & (wordSize-1)) != 0) { ++ return false; ++ } ++ if (fp() + interpreter_frame_initial_sp_offset < sp()) { ++ return false; ++ } ++ // These are hacks to keep us out of trouble. ++ // The problem with these is that they mask other problems ++ if (fp() <= sp()) { // this attempts to deal with unsigned comparison above ++ return false; ++ } ++ ++ // do some validation of frame elements ++ ++ // first the method ++ Method* m = *interpreter_frame_method_addr(); ++ // validate the method we'd find in this potential sender ++ if (!Method::is_valid_method(m)) { ++ return false; ++ } ++ ++ // stack frames shouldn't be much larger than max_stack elements ++ // this test requires the use of unextended_sp which is the sp as seen by ++ // the current frame, and not sp which is the "raw" pc which could point ++ // further because of local variables of the callee method inserted after ++ // method arguments ++ if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { ++ return false; ++ } ++ ++ // validate bci/bcx ++ address bcp = interpreter_frame_bcp(); ++ if (m->validate_bci_from_bcp(bcp) < 0) { ++ return false; ++ } ++ ++ // validate constantPoolCache* ++ ConstantPoolCache* cp = *interpreter_frame_cache_addr(); ++ if (MetaspaceObj::is_valid(cp) == false) { ++ return false; ++ } ++ ++ // validate locals ++ address locals = (address) *interpreter_frame_locals_addr(); ++ if (locals > thread->stack_base() || locals < (address) fp()) { ++ return false; ++ } ++ ++ // We'd have to be pretty unlucky to be mislead at this point ++ return true; ++} ++ ++BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { ++ assert(is_interpreted_frame(), "interpreted frame expected"); ++ Method* method = interpreter_frame_method(); ++ BasicType type = method->result_type(); ++ ++ intptr_t* tos_addr = NULL; ++ if (method->is_native()) { ++ tos_addr = (intptr_t*)sp(); ++ if (type == T_FLOAT || type == T_DOUBLE) { ++ // This is because we do a push(ltos) after push(dtos) in generate_native_entry. ++ tos_addr += 2 * Interpreter::stackElementWords; ++ } ++ } else { ++ tos_addr = (intptr_t*)interpreter_frame_tos_address(); ++ } ++ ++ switch (type) { ++ case T_OBJECT : ++ case T_ARRAY : { ++ oop obj; ++ if (method->is_native()) { ++ obj = cast_to_oop(at(interpreter_frame_oop_temp_offset)); ++ } else { ++ oop* obj_p = (oop*)tos_addr; ++ obj = (obj_p == NULL) ? (oop)NULL : *obj_p; ++ } ++ assert(Universe::is_in_heap_or_null(obj), "sanity check"); ++ *oop_result = obj; ++ break; ++ } ++ case T_BOOLEAN : value_result->z = *(jboolean*)tos_addr; break; ++ case T_BYTE : value_result->b = *(jbyte*)tos_addr; break; ++ case T_CHAR : value_result->c = *(jchar*)tos_addr; break; ++ case T_SHORT : value_result->s = *(jshort*)tos_addr; break; ++ case T_INT : value_result->i = *(jint*)tos_addr; break; ++ case T_LONG : value_result->j = *(jlong*)tos_addr; break; ++ case T_FLOAT : { ++ value_result->f = *(jfloat*)tos_addr; ++ break; ++ } ++ case T_DOUBLE : value_result->d = *(jdouble*)tos_addr; break; ++ case T_VOID : /* Nothing to do */ break; ++ default : ShouldNotReachHere(); ++ } ++ ++ return type; ++} ++ ++ ++intptr_t* frame::interpreter_frame_tos_at(jint offset) const { ++ int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize); ++ return &interpreter_frame_tos_address()[index]; ++} ++ ++#ifndef PRODUCT ++ ++#define DESCRIBE_FP_OFFSET(name) \ ++ values.describe(frame_no, fp() + frame::name##_offset, #name) ++ ++void frame::describe_pd(FrameValues& values, int frame_no) { ++ if (is_interpreted_frame()) { ++ DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp); ++ DESCRIBE_FP_OFFSET(interpreter_frame_last_sp); ++ DESCRIBE_FP_OFFSET(interpreter_frame_method); ++ DESCRIBE_FP_OFFSET(interpreter_frame_mdp); ++ DESCRIBE_FP_OFFSET(interpreter_frame_mirror); ++ DESCRIBE_FP_OFFSET(interpreter_frame_cache); ++ DESCRIBE_FP_OFFSET(interpreter_frame_locals); ++ DESCRIBE_FP_OFFSET(interpreter_frame_bcp); ++ DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp); ++ } ++} ++#endif ++ ++intptr_t *frame::initial_deoptimization_info() { ++ // Not used on riscv, but we must return something. ++ return NULL; ++} ++ ++intptr_t* frame::real_fp() const { ++ if (_cb != NULL) { ++ // use the frame size if valid ++ int size = _cb->frame_size(); ++ if (size > 0) { ++ return unextended_sp() + size; ++ } ++ } ++ // else rely on fp() ++ assert(!is_compiled_frame(), "unknown compiled frame size"); ++ return fp(); ++} ++ ++#undef DESCRIBE_FP_OFFSET ++ ++#ifndef PRODUCT ++// This is a generic constructor which is only used by pns() in debug.cpp. ++frame::frame(void* ptr_sp, void* ptr_fp, void* pc) { ++ init((intptr_t*)ptr_sp, (intptr_t*)ptr_fp, (address)pc); ++} ++ ++void frame::pd_ps() {} ++#endif ++ ++void JavaFrameAnchor::make_walkable() { ++ // last frame set? ++ if (last_Java_sp() == NULL) { return; } ++ // already walkable? ++ if (walkable()) { return; } ++ vmassert(last_Java_sp() != NULL, "not called from Java code?"); ++ vmassert(last_Java_pc() == NULL, "already walkable"); ++ _last_Java_pc = (address)_last_Java_sp[-1]; ++ vmassert(walkable(), "something went wrong"); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/frame_riscv.hpp +@@ -0,0 +1,204 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_FRAME_RISCV_HPP ++#define CPU_RISCV_FRAME_RISCV_HPP ++ ++#include "runtime/synchronizer.hpp" ++ ++// A frame represents a physical stack frame (an activation). Frames can be ++// C or Java frames, and the Java frames can be interpreted or compiled. ++// In contrast, vframes represent source-level activations, so that one physical frame ++// can correspond to multiple source level frames because of inlining. ++// A frame is comprised of {pc, fp, sp} ++// ------------------------------ Asm interpreter ---------------------------------------- ++// Layout of asm interpreter frame: ++// [expression stack ] * <- sp ++ ++// [monitors[0] ] \ ++// ... | monitor block size = k ++// [monitors[k-1] ] / ++// [frame initial esp ] ( == &monitors[0], initially here) initial_sp_offset ++// [byte code index/pointr] = bcx() bcx_offset ++ ++// [pointer to locals ] = locals() locals_offset ++// [constant pool cache ] = cache() cache_offset ++ ++// [klass of method ] = mirror() mirror_offset ++// [padding ] ++ ++// [methodData ] = mdp() mdx_offset ++// [Method ] = method() method_offset ++ ++// [last esp ] = last_sp() last_sp_offset ++// [old stack pointer ] (sender_sp) sender_sp_offset ++ ++// [old frame pointer ] ++// [return pc ] ++ ++// [last sp ] <- fp = link() ++// [oop temp ] (only for native calls) ++ ++// [padding ] (to preserve machine SP alignment) ++// [locals and parameters ] ++// <- sender sp ++// ------------------------------ Asm interpreter ---------------------------------------- ++ ++// ------------------------------ C Frame ------------------------------------------------ ++// Stack: gcc with -fno-omit-frame-pointer ++// . ++// . ++// +-> . ++// | +-----------------+ | ++// | | return address | | ++// | | previous fp ------+ ++// | | saved registers | ++// | | local variables | ++// | | ... | <-+ ++// | +-----------------+ | ++// | | return address | | ++// +------ previous fp | | ++// | saved registers | | ++// | local variables | | ++// +-> | ... | | ++// | +-----------------+ | ++// | | return address | | ++// | | previous fp ------+ ++// | | saved registers | ++// | | local variables | ++// | | ... | <-+ ++// | +-----------------+ | ++// | | return address | | ++// +------ previous fp | | ++// | saved registers | | ++// | local variables | | ++// $fp --> | ... | | ++// +-----------------+ | ++// | return address | | ++// | previous fp ------+ ++// | saved registers | ++// $sp --> | local variables | ++// +-----------------+ ++// ------------------------------ C Frame ------------------------------------------------ ++ ++ public: ++ enum { ++ pc_return_offset = 0, ++ ++ // All frames ++ link_offset = -2, ++ return_addr_offset = -1, ++ sender_sp_offset = 0, ++ ++ // Interpreter frames ++ interpreter_frame_oop_temp_offset = 1, // for native calls only ++ ++ interpreter_frame_sender_sp_offset = -3, ++ // outgoing sp before a call to an invoked method ++ interpreter_frame_last_sp_offset = interpreter_frame_sender_sp_offset - 1, ++ interpreter_frame_method_offset = interpreter_frame_last_sp_offset - 1, ++ interpreter_frame_mdp_offset = interpreter_frame_method_offset - 1, ++ interpreter_frame_padding_offset = interpreter_frame_mdp_offset - 1, ++ interpreter_frame_mirror_offset = interpreter_frame_padding_offset - 1, ++ interpreter_frame_cache_offset = interpreter_frame_mirror_offset - 1, ++ interpreter_frame_locals_offset = interpreter_frame_cache_offset - 1, ++ interpreter_frame_bcp_offset = interpreter_frame_locals_offset - 1, ++ interpreter_frame_initial_sp_offset = interpreter_frame_bcp_offset - 1, ++ ++ interpreter_frame_monitor_block_top_offset = interpreter_frame_initial_sp_offset, ++ interpreter_frame_monitor_block_bottom_offset = interpreter_frame_initial_sp_offset, ++ ++ // Entry frames ++ // n.b. these values are determined by the layout defined in ++ // stubGenerator for the Java call stub ++ entry_frame_after_call_words = 34, ++ entry_frame_call_wrapper_offset = -10, ++ ++ // we don't need a save area ++ arg_reg_save_area_bytes = 0 ++ }; ++ ++ intptr_t ptr_at(int offset) const { ++ return *ptr_at_addr(offset); ++ } ++ ++ void ptr_at_put(int offset, intptr_t value) { ++ *ptr_at_addr(offset) = value; ++ } ++ ++ private: ++ // an additional field beyond _sp and _pc: ++ intptr_t* _fp; // frame pointer ++ // The interpreter and adapters will extend the frame of the caller. ++ // Since oopMaps are based on the sp of the caller before extension ++ // we need to know that value. However in order to compute the address ++ // of the return address we need the real "raw" sp. Since sparc already ++ // uses sp() to mean "raw" sp and unextended_sp() to mean the caller's ++ // original sp we use that convention. ++ ++ intptr_t* _unextended_sp; ++ void adjust_unextended_sp(); ++ ++ intptr_t* ptr_at_addr(int offset) const { ++ return (intptr_t*) addr_at(offset); ++ } ++ ++#ifdef ASSERT ++ // Used in frame::sender_for_{interpreter,compiled}_frame ++ static void verify_deopt_original_pc( CompiledMethod* nm, intptr_t* unextended_sp); ++#endif ++ ++ public: ++ // Constructors ++ ++ frame(intptr_t* ptr_sp, intptr_t* ptr_fp, address pc); ++ ++ frame(intptr_t* ptr_sp, intptr_t* unextended_sp, intptr_t* ptr_fp, address pc); ++ ++ frame(intptr_t* ptr_sp, intptr_t* ptr_fp); ++ ++ void init(intptr_t* ptr_sp, intptr_t* ptr_fp, address pc); ++ ++ // accessors for the instance variables ++ // Note: not necessarily the real 'frame pointer' (see real_fp) ++ intptr_t* fp() const { return _fp; } ++ ++ inline address* sender_pc_addr() const; ++ ++ // expression stack tos if we are nested in a java call ++ intptr_t* interpreter_frame_last_sp() const; ++ ++ // helper to update a map with callee-saved RBP ++ static void update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr); ++ ++ // deoptimization support ++ void interpreter_frame_set_last_sp(intptr_t* last_sp); ++ ++ static jint interpreter_frame_expression_stack_direction() { return -1; } ++ ++ // returns the sending frame, without applying any barriers ++ frame sender_raw(RegisterMap* map) const; ++ ++#endif // CPU_RISCV_FRAME_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/frame_riscv.inline.hpp +@@ -0,0 +1,246 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_FRAME_RISCV_INLINE_HPP ++#define CPU_RISCV_FRAME_RISCV_INLINE_HPP ++ ++#include "code/codeCache.hpp" ++#include "code/vmreg.inline.hpp" ++ ++// Inline functions for RISCV frames: ++ ++// Constructors: ++ ++inline frame::frame() { ++ _pc = NULL; ++ _sp = NULL; ++ _unextended_sp = NULL; ++ _fp = NULL; ++ _cb = NULL; ++ _deopt_state = unknown; ++} ++ ++static int spin; ++ ++inline void frame::init(intptr_t* ptr_sp, intptr_t* ptr_fp, address pc) { ++ intptr_t a = intptr_t(ptr_sp); ++ intptr_t b = intptr_t(ptr_fp); ++ _sp = ptr_sp; ++ _unextended_sp = ptr_sp; ++ _fp = ptr_fp; ++ _pc = pc; ++ assert(pc != NULL, "no pc?"); ++ _cb = CodeCache::find_blob(pc); ++ adjust_unextended_sp(); ++ ++ address original_pc = CompiledMethod::get_deopt_original_pc(this); ++ if (original_pc != NULL) { ++ _pc = original_pc; ++ _deopt_state = is_deoptimized; ++ } else { ++ _deopt_state = not_deoptimized; ++ } ++} ++ ++inline frame::frame(intptr_t* ptr_sp, intptr_t* ptr_fp, address pc) { ++ init(ptr_sp, ptr_fp, pc); ++} ++ ++inline frame::frame(intptr_t* ptr_sp, intptr_t* unextended_sp, intptr_t* ptr_fp, address pc) { ++ intptr_t a = intptr_t(ptr_sp); ++ intptr_t b = intptr_t(ptr_fp); ++ _sp = ptr_sp; ++ _unextended_sp = unextended_sp; ++ _fp = ptr_fp; ++ _pc = pc; ++ assert(pc != NULL, "no pc?"); ++ _cb = CodeCache::find_blob(pc); ++ adjust_unextended_sp(); ++ ++ address original_pc = CompiledMethod::get_deopt_original_pc(this); ++ if (original_pc != NULL) { ++ _pc = original_pc; ++ assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc), ++ "original PC must be in the main code section of the the compiled method (or must be immediately following it)"); ++ _deopt_state = is_deoptimized; ++ } else { ++ _deopt_state = not_deoptimized; ++ } ++} ++ ++inline frame::frame(intptr_t* ptr_sp, intptr_t* ptr_fp) { ++ intptr_t a = intptr_t(ptr_sp); ++ intptr_t b = intptr_t(ptr_fp); ++ _sp = ptr_sp; ++ _unextended_sp = ptr_sp; ++ _fp = ptr_fp; ++ _pc = (address)(ptr_sp[-1]); ++ ++ // Here's a sticky one. This constructor can be called via AsyncGetCallTrace ++ // when last_Java_sp is non-null but the pc fetched is junk. If we are truly ++ // unlucky the junk value could be to a zombied method and we'll die on the ++ // find_blob call. This is also why we can have no asserts on the validity ++ // of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler ++ // -> pd_last_frame should use a specialized version of pd_last_frame which could ++ // call a specilaized frame constructor instead of this one. ++ // Then we could use the assert below. However this assert is of somewhat dubious ++ // value. ++ ++ _cb = CodeCache::find_blob(_pc); ++ adjust_unextended_sp(); ++ ++ address original_pc = CompiledMethod::get_deopt_original_pc(this); ++ if (original_pc != NULL) { ++ _pc = original_pc; ++ _deopt_state = is_deoptimized; ++ } else { ++ _deopt_state = not_deoptimized; ++ } ++} ++ ++// Accessors ++ ++inline bool frame::equal(frame other) const { ++ bool ret = sp() == other.sp() && ++ unextended_sp() == other.unextended_sp() && ++ fp() == other.fp() && ++ pc() == other.pc(); ++ assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction"); ++ return ret; ++} ++ ++// Return unique id for this frame. The id must have a value where we can distinguish ++// identity and younger/older relationship. NULL represents an invalid (incomparable) ++// frame. ++inline intptr_t* frame::id(void) const { return unextended_sp(); } ++ ++// Return true if the frame is older (less recent activation) than the frame represented by id ++inline bool frame::is_older(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id"); ++ return this->id() > id ; } ++ ++inline intptr_t* frame::link() const { return (intptr_t*) *(intptr_t **)addr_at(link_offset); } ++ ++inline intptr_t* frame::link_or_null() const { ++ intptr_t** ptr = (intptr_t **)addr_at(link_offset); ++ return os::is_readable_pointer(ptr) ? *ptr : NULL; ++} ++ ++inline intptr_t* frame::unextended_sp() const { return _unextended_sp; } ++ ++// Return address ++inline address* frame::sender_pc_addr() const { return (address*) addr_at(return_addr_offset); } ++inline address frame::sender_pc() const { return *sender_pc_addr(); } ++inline intptr_t* frame::sender_sp() const { return addr_at(sender_sp_offset); } ++ ++inline intptr_t** frame::interpreter_frame_locals_addr() const { ++ return (intptr_t**)addr_at(interpreter_frame_locals_offset); ++} ++ ++inline intptr_t* frame::interpreter_frame_last_sp() const { ++ return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset); ++} ++ ++inline intptr_t* frame::interpreter_frame_bcp_addr() const { ++ return (intptr_t*)addr_at(interpreter_frame_bcp_offset); ++} ++ ++inline intptr_t* frame::interpreter_frame_mdp_addr() const { ++ return (intptr_t*)addr_at(interpreter_frame_mdp_offset); ++} ++ ++ ++// Constant pool cache ++ ++inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const { ++ return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset); ++} ++ ++// Method ++ ++inline Method** frame::interpreter_frame_method_addr() const { ++ return (Method**)addr_at(interpreter_frame_method_offset); ++} ++ ++// Mirror ++ ++inline oop* frame::interpreter_frame_mirror_addr() const { ++ return (oop*)addr_at(interpreter_frame_mirror_offset); ++} ++ ++// top of expression stack ++inline intptr_t* frame::interpreter_frame_tos_address() const { ++ intptr_t* last_sp = interpreter_frame_last_sp(); ++ if (last_sp == NULL) { ++ return sp(); ++ } else { ++ // sp() may have been extended or shrunk by an adapter. At least ++ // check that we don't fall behind the legal region. ++ // For top deoptimized frame last_sp == interpreter_frame_monitor_end. ++ assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos"); ++ return last_sp; ++ } ++} ++ ++inline oop* frame::interpreter_frame_temp_oop_addr() const { ++ return (oop *)(fp() + interpreter_frame_oop_temp_offset); ++} ++ ++inline int frame::interpreter_frame_monitor_size() { ++ return BasicObjectLock::size(); ++} ++ ++ ++// expression stack ++// (the max_stack arguments are used by the GC; see class FrameClosure) ++ ++inline intptr_t* frame::interpreter_frame_expression_stack() const { ++ intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end(); ++ return monitor_end-1; ++} ++ ++ ++// Entry frames ++ ++inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { ++ return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset); ++} ++ ++ ++// Compiled frames ++ ++inline oop frame::saved_oop_result(RegisterMap* map) const { ++ oop* result_adr = (oop *)map->location(x10->as_VMReg()); ++ guarantee(result_adr != NULL, "bad register save location"); ++ return (*result_adr); ++} ++ ++inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { ++ oop* result_adr = (oop *)map->location(x10->as_VMReg()); ++ guarantee(result_adr != NULL, "bad register save location"); ++ *result_adr = obj; ++} ++ ++#endif // CPU_RISCV_FRAME_RISCV_INLINE_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +@@ -0,0 +1,478 @@ ++/* ++ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "gc/g1/g1BarrierSet.hpp" ++#include "gc/g1/g1BarrierSetAssembler.hpp" ++#include "gc/g1/g1BarrierSetRuntime.hpp" ++#include "gc/g1/g1CardTable.hpp" ++#include "gc/g1/g1ThreadLocalData.hpp" ++#include "gc/g1/heapRegion.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "interpreter/interp_masm.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/thread.hpp" ++#ifdef COMPILER1 ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "gc/g1/c1/g1BarrierSetC1.hpp" ++#endif ++ ++#define __ masm-> ++ ++void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register addr, Register count, RegSet saved_regs) { ++ bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0; ++ if (!dest_uninitialized) { ++ Label done; ++ Address in_progress(xthread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset())); ++ ++ // Is marking active? ++ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { ++ __ lwu(t0, in_progress); ++ } else { ++ assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); ++ __ lbu(t0, in_progress); ++ } ++ __ beqz(t0, done); ++ ++ __ push_reg(saved_regs, sp); ++ if (count == c_rarg0) { ++ if (addr == c_rarg1) { ++ // exactly backwards!! ++ __ mv(t0, c_rarg0); ++ __ mv(c_rarg0, c_rarg1); ++ __ mv(c_rarg1, t0); ++ } else { ++ __ mv(c_rarg1, count); ++ __ mv(c_rarg0, addr); ++ } ++ } else { ++ __ mv(c_rarg0, addr); ++ __ mv(c_rarg1, count); ++ } ++ if (UseCompressedOops) { ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_pre_narrow_oop_entry), 2); ++ } else { ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_pre_oop_entry), 2); ++ } ++ __ pop_reg(saved_regs, sp); ++ ++ __ bind(done); ++ } ++} ++ ++void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register start, Register count, Register tmp, RegSet saved_regs) { ++ __ push_reg(saved_regs, sp); ++ assert_different_registers(start, count, tmp); ++ assert_different_registers(c_rarg0, count); ++ __ mv(c_rarg0, start); ++ __ mv(c_rarg1, count); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_post_entry), 2); ++ __ pop_reg(saved_regs, sp); ++} ++ ++void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, ++ Register obj, ++ Register pre_val, ++ Register thread, ++ Register tmp, ++ bool tosca_live, ++ bool expand_call) { ++ // If expand_call is true then we expand the call_VM_leaf macro ++ // directly to skip generating the check by ++ // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp. ++ ++ assert(thread == xthread, "must be"); ++ ++ Label done; ++ Label runtime; ++ ++ assert_different_registers(obj, pre_val, tmp, t0); ++ assert(pre_val != noreg && tmp != noreg, "expecting a register"); ++ ++ Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset())); ++ Address index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset())); ++ Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset())); ++ ++ // Is marking active? ++ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { // 4-byte width ++ __ lwu(tmp, in_progress); ++ } else { ++ assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); ++ __ lbu(tmp, in_progress); ++ } ++ __ beqz(tmp, done); ++ ++ // Do we need to load the previous value? ++ if (obj != noreg) { ++ __ load_heap_oop(pre_val, Address(obj, 0), noreg, noreg, AS_RAW); ++ } ++ ++ // Is the previous value null? ++ __ beqz(pre_val, done); ++ ++ // Can we store original value in the thread's buffer? ++ // Is index == 0? ++ // (The index field is typed as size_t.) ++ ++ __ ld(tmp, index); // tmp := *index_adr ++ __ beqz(tmp, runtime); // tmp == 0? ++ // If yes, goto runtime ++ ++ __ sub(tmp, tmp, wordSize); // tmp := tmp - wordSize ++ __ sd(tmp, index); // *index_adr := tmp ++ __ ld(t0, buffer); ++ __ add(tmp, tmp, t0); // tmp := tmp + *buffer_adr ++ ++ // Record the previous value ++ __ sd(pre_val, Address(tmp, 0)); ++ __ j(done); ++ ++ __ bind(runtime); ++ // save the live input values ++ RegSet saved = RegSet::of(pre_val); ++ if (tosca_live) { saved += RegSet::of(x10); } ++ if (obj != noreg) { saved += RegSet::of(obj); } ++ ++ __ push_reg(saved, sp); ++ ++ if (expand_call) { ++ assert(pre_val != c_rarg1, "smashed arg"); ++ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread); ++ } else { ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread); ++ } ++ ++ __ pop_reg(saved, sp); ++ ++ __ bind(done); ++ ++} ++ ++void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, ++ Register store_addr, ++ Register new_val, ++ Register thread, ++ Register tmp, ++ Register tmp2) { ++ assert(thread == xthread, "must be"); ++ assert_different_registers(store_addr, new_val, thread, tmp, tmp2, ++ t0); ++ assert(store_addr != noreg && new_val != noreg && tmp != noreg && ++ tmp2 != noreg, "expecting a register"); ++ ++ Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset())); ++ Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset())); ++ ++ BarrierSet* bs = BarrierSet::barrier_set(); ++ CardTableBarrierSet* ctbs = barrier_set_cast(bs); ++ CardTable* ct = ctbs->card_table(); ++ ++ Label done; ++ Label runtime; ++ ++ // Does store cross heap regions? ++ ++ __ xorr(tmp, store_addr, new_val); ++ __ srli(tmp, tmp, HeapRegion::LogOfHRGrainBytes); ++ __ beqz(tmp, done); ++ ++ // crosses regions, storing NULL? ++ ++ __ beqz(new_val, done); ++ ++ // storing region crossing non-NULL, is card already dirty? ++ ++ ExternalAddress cardtable((address) ct->byte_map_base()); ++ const Register card_addr = tmp; ++ ++ __ srli(card_addr, store_addr, CardTable::card_shift); ++ ++ // get the address of the card ++ __ load_byte_map_base(tmp2); ++ __ add(card_addr, card_addr, tmp2); ++ __ lbu(tmp2, Address(card_addr)); ++ __ mv(t0, (int)G1CardTable::g1_young_card_val()); ++ __ beq(tmp2, t0, done); ++ ++ assert((int)CardTable::dirty_card_val() == 0, "must be 0"); ++ ++ __ membar(MacroAssembler::StoreLoad); ++ ++ __ lbu(tmp2, Address(card_addr)); ++ __ beqz(tmp2, done); ++ ++ // storing a region crossing, non-NULL oop, card is clean. ++ // dirty card and log. ++ ++ __ sb(zr, Address(card_addr)); ++ ++ __ ld(t0, queue_index); ++ __ beqz(t0, runtime); ++ __ sub(t0, t0, wordSize); ++ __ sd(t0, queue_index); ++ ++ __ ld(tmp2, buffer); ++ __ add(t0, tmp2, t0); ++ __ sd(card_addr, Address(t0, 0)); ++ __ j(done); ++ ++ __ bind(runtime); ++ // save the live input values ++ RegSet saved = RegSet::of(store_addr); ++ __ push_reg(saved, sp); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread); ++ __ pop_reg(saved, sp); ++ ++ __ bind(done); ++} ++ ++void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Register dst, Address src, Register tmp1, Register tmp_thread) { ++ bool on_oop = is_reference_type(type); ++ bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; ++ bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; ++ bool on_reference = on_weak || on_phantom; ++ ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); ++ if (on_oop && on_reference) { ++ // RA is live. It must be saved around calls. ++ __ enter(); // barrier may call runtime ++ // Generate the G1 pre-barrier code to log the value of ++ // the referent field in an SATB buffer. ++ g1_write_barrier_pre(masm /* masm */, ++ noreg /* obj */, ++ dst /* pre_val */, ++ xthread /* thread */, ++ tmp1 /* tmp */, ++ true /* tosca_live */, ++ true /* expand_call */); ++ __ leave(); ++ } ++} ++ ++void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2) { ++ // flatten object address if needed ++ if (dst.offset() == 0) { ++ if (dst.base() != x13) { ++ __ mv(x13, dst.base()); ++ } ++ } else { ++ __ la(x13, dst); ++ } ++ ++ g1_write_barrier_pre(masm, ++ x13 /* obj */, ++ tmp2 /* pre_val */, ++ xthread /* thread */, ++ tmp1 /* tmp */, ++ val != noreg /* tosca_live */, ++ false /* expand_call */); ++ ++ if (val == noreg) { ++ BarrierSetAssembler::store_at(masm, decorators, type, Address(x13, 0), noreg, noreg, noreg); ++ } else { ++ // G1 barrier needs uncompressed oop for region cross check. ++ Register new_val = val; ++ if (UseCompressedOops) { ++ new_val = t1; ++ __ mv(new_val, val); ++ } ++ BarrierSetAssembler::store_at(masm, decorators, type, Address(x13, 0), val, noreg, noreg); ++ g1_write_barrier_post(masm, ++ x13 /* store_adr */, ++ new_val /* new_val */, ++ xthread /* thread */, ++ tmp1 /* tmp */, ++ tmp2 /* tmp2 */); ++ } ++} ++ ++#ifdef COMPILER1 ++ ++#undef __ ++#define __ ce->masm()-> ++ ++void G1BarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrierStub* stub) { ++ G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1(); ++ ++ // At this point we know that marking is in progress. ++ // If do_load() is true then we have to emit the ++ // load of the previous value; otherwise it has already ++ // been loaded into _pre_val. ++ __ bind(*stub->entry()); ++ ++ assert(stub->pre_val()->is_register(), "Precondition."); ++ ++ Register pre_val_reg = stub->pre_val()->as_register(); ++ ++ if (stub->do_load()) { ++ ce->mem2reg(stub->addr(), stub->pre_val(), T_OBJECT, stub->patch_code(), stub->info(), false /* wide */, false /* unaligned */); ++ } ++ __ beqz(pre_val_reg, *stub->continuation(), /* is_far */ true); ++ ce->store_parameter(stub->pre_val()->as_register(), 0); ++ __ far_call(RuntimeAddress(bs->pre_barrier_c1_runtime_code_blob()->code_begin())); ++ __ j(*stub->continuation()); ++} ++ ++void G1BarrierSetAssembler::gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub) { ++ G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1(); ++ __ bind(*stub->entry()); ++ assert(stub->addr()->is_register(), "Precondition"); ++ assert(stub->new_val()->is_register(), "Precondition"); ++ Register new_val_reg = stub->new_val()->as_register(); ++ __ beqz(new_val_reg, *stub->continuation(), /* is_far */ true); ++ ce->store_parameter(stub->addr()->as_pointer_register(), 0); ++ __ far_call(RuntimeAddress(bs->post_barrier_c1_runtime_code_blob()->code_begin())); ++ __ j(*stub->continuation()); ++} ++ ++#undef __ ++ ++#define __ sasm-> ++ ++void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) { ++ __ prologue("g1_pre_barrier", false); ++ ++ BarrierSet* bs = BarrierSet::barrier_set(); ++ ++ // arg0 : previous value of memory ++ const Register pre_val = x10; ++ const Register thread = xthread; ++ const Register tmp = t0; ++ ++ Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset())); ++ Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset())); ++ Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset())); ++ ++ Label done; ++ Label runtime; ++ ++ // Is marking still active? ++ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { // 4-byte width ++ __ lwu(tmp, in_progress); ++ } else { ++ assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); ++ __ lbu(tmp, in_progress); ++ } ++ __ beqz(tmp, done); ++ ++ // Can we store original value in the thread's buffer? ++ __ ld(tmp, queue_index); ++ __ beqz(tmp, runtime); ++ ++ __ sub(tmp, tmp, wordSize); ++ __ sd(tmp, queue_index); ++ __ ld(t1, buffer); ++ __ add(tmp, tmp, t1); ++ __ load_parameter(0, t1); ++ __ sd(t1, Address(tmp, 0)); ++ __ j(done); ++ ++ __ bind(runtime); ++ __ push_call_clobbered_registers(); ++ __ load_parameter(0, pre_val); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread); ++ __ pop_call_clobbered_registers(); ++ __ bind(done); ++ ++ __ epilogue(); ++} ++ ++void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* sasm) { ++ __ prologue("g1_post_barrier", false); ++ ++ // arg0 : store_address ++ Address store_addr(fp, 2 * BytesPerWord); // 2 BytesPerWord from fp ++ ++ BarrierSet* bs = BarrierSet::barrier_set(); ++ CardTableBarrierSet* ctbs = barrier_set_cast(bs); ++ CardTable* ct = ctbs->card_table(); ++ ++ Label done; ++ Label runtime; ++ ++ // At this point we know new_value is non-NULL and the new_value crosses regions. ++ // Must check to see if card is already dirty ++ const Register thread = xthread; ++ ++ Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset())); ++ Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset())); ++ ++ const Register card_offset = t1; ++ // RA is free here, so we can use it to hold the byte_map_base. ++ const Register byte_map_base = ra; ++ ++ assert_different_registers(card_offset, byte_map_base, t0); ++ ++ __ load_parameter(0, card_offset); ++ __ srli(card_offset, card_offset, CardTable::card_shift); ++ __ load_byte_map_base(byte_map_base); ++ ++ // Convert card offset into an address in card_addr ++ Register card_addr = card_offset; ++ __ add(card_addr, byte_map_base, card_addr); ++ ++ __ lbu(t0, Address(card_addr, 0)); ++ __ sub(t0, t0, (int)G1CardTable::g1_young_card_val()); ++ __ beqz(t0, done); ++ ++ assert((int)CardTable::dirty_card_val() == 0, "must be 0"); ++ ++ __ membar(MacroAssembler::StoreLoad); ++ __ lbu(t0, Address(card_addr, 0)); ++ __ beqz(t0, done); ++ ++ // storing region crossing non-NULL, card is clean. ++ // dirty card and log. ++ __ sb(zr, Address(card_addr, 0)); ++ ++ __ ld(t0, queue_index); ++ __ beqz(t0, runtime); ++ __ sub(t0, t0, wordSize); ++ __ sd(t0, queue_index); ++ ++ // Reuse RA to hold buffer_addr ++ const Register buffer_addr = ra; ++ ++ __ ld(buffer_addr, buffer); ++ __ add(t0, buffer_addr, t0); ++ __ sd(card_addr, Address(t0, 0)); ++ __ j(done); ++ ++ __ bind(runtime); ++ __ push_call_clobbered_registers(); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread); ++ __ pop_call_clobbered_registers(); ++ __ bind(done); ++ __ epilogue(); ++} ++ ++#undef __ ++ ++#endif // COMPILER1 +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.hpp +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (c) 2018, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_G1_G1BARRIERSETASSEMBLER_RISCV_HPP ++#define CPU_RISCV_GC_G1_G1BARRIERSETASSEMBLER_RISCV_HPP ++ ++#include "asm/macroAssembler.hpp" ++#include "gc/shared/modRefBarrierSetAssembler.hpp" ++#include "utilities/macros.hpp" ++ ++#ifdef COMPILER1 ++class LIR_Assembler; ++#endif ++class StubAssembler; ++class G1PreBarrierStub; ++class G1PostBarrierStub; ++ ++class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { ++protected: ++ void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register addr, Register count, RegSet saved_regs); ++ void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register start, Register count, Register tmp, RegSet saved_regs); ++ ++ void g1_write_barrier_pre(MacroAssembler* masm, ++ Register obj, ++ Register pre_val, ++ Register thread, ++ Register tmp, ++ bool tosca_live, ++ bool expand_call); ++ ++ void g1_write_barrier_post(MacroAssembler* masm, ++ Register store_addr, ++ Register new_val, ++ Register thread, ++ Register tmp, ++ Register tmp2); ++ ++ virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2); ++ ++public: ++#ifdef COMPILER1 ++ void gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrierStub* stub); ++ void gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub); ++ ++ void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm); ++ void generate_c1_post_barrier_runtime_stub(StubAssembler* sasm); ++#endif ++ ++ void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Register dst, Address src, Register tmp1, Register tmp_thread); ++}; ++ ++#endif // CPU_RISCV_GC_G1_G1BARRIERSETASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/g1/g1Globals_riscv.hpp +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_G1_G1GLOBALS_RISCV_HPP ++#define CPU_RISCV_GC_G1_G1GLOBALS_RISCV_HPP ++ ++const size_t G1MergeHeapRootsPrefetchCacheSize = 16; ++ ++#endif // CPU_RISCV_GC_G1_G1GLOBALS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp +@@ -0,0 +1,298 @@ ++/* ++ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "classfile/classLoaderData.hpp" ++#include "gc/shared/barrierSet.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "gc/shared/barrierSetNMethod.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "interpreter/interp_masm.hpp" ++#include "memory/universe.hpp" ++#include "runtime/jniHandles.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/thread.hpp" ++ ++#define __ masm-> ++ ++void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Register dst, Address src, Register tmp1, Register tmp_thread) { ++ // RA is live. It must be saved around calls. ++ ++ bool in_heap = (decorators & IN_HEAP) != 0; ++ bool in_native = (decorators & IN_NATIVE) != 0; ++ bool is_not_null = (decorators & IS_NOT_NULL) != 0; ++ switch (type) { ++ case T_OBJECT: // fall through ++ case T_ARRAY: { ++ if (in_heap) { ++ if (UseCompressedOops) { ++ __ lwu(dst, src); ++ if (is_not_null) { ++ __ decode_heap_oop_not_null(dst); ++ } else { ++ __ decode_heap_oop(dst); ++ } ++ } else { ++ __ ld(dst, src); ++ } ++ } else { ++ assert(in_native, "why else?"); ++ __ ld(dst, src); ++ } ++ break; ++ } ++ case T_BOOLEAN: __ load_unsigned_byte (dst, src); break; ++ case T_BYTE: __ load_signed_byte (dst, src); break; ++ case T_CHAR: __ load_unsigned_short(dst, src); break; ++ case T_SHORT: __ load_signed_short (dst, src); break; ++ case T_INT: __ lw (dst, src); break; ++ case T_LONG: __ ld (dst, src); break; ++ case T_ADDRESS: __ ld (dst, src); break; ++ case T_FLOAT: __ flw (f10, src); break; ++ case T_DOUBLE: __ fld (f10, src); break; ++ default: Unimplemented(); ++ } ++} ++ ++void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2) { ++ bool in_heap = (decorators & IN_HEAP) != 0; ++ bool in_native = (decorators & IN_NATIVE) != 0; ++ switch (type) { ++ case T_OBJECT: // fall through ++ case T_ARRAY: { ++ val = val == noreg ? zr : val; ++ if (in_heap) { ++ if (UseCompressedOops) { ++ assert(!dst.uses(val), "not enough registers"); ++ if (val != zr) { ++ __ encode_heap_oop(val); ++ } ++ __ sw(val, dst); ++ } else { ++ __ sd(val, dst); ++ } ++ } else { ++ assert(in_native, "why else?"); ++ __ sd(val, dst); ++ } ++ break; ++ } ++ case T_BOOLEAN: ++ __ andi(val, val, 0x1); // boolean is true if LSB is 1 ++ __ sb(val, dst); ++ break; ++ case T_BYTE: __ sb(val, dst); break; ++ case T_CHAR: __ sh(val, dst); break; ++ case T_SHORT: __ sh(val, dst); break; ++ case T_INT: __ sw(val, dst); break; ++ case T_LONG: __ sd(val, dst); break; ++ case T_ADDRESS: __ sd(val, dst); break; ++ case T_FLOAT: __ fsw(f10, dst); break; ++ case T_DOUBLE: __ fsd(f10, dst); break; ++ default: Unimplemented(); ++ } ++ ++} ++ ++void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env, ++ Register obj, Register tmp, Label& slowpath) { ++ // If mask changes we need to ensure that the inverse is still encodable as an immediate ++ STATIC_ASSERT(JNIHandles::weak_tag_mask == 1); ++ __ andi(obj, obj, ~JNIHandles::weak_tag_mask); ++ __ ld(obj, Address(obj, 0)); // *obj ++} ++ ++// Defines obj, preserves var_size_in_bytes, okay for tmp2 == var_size_in_bytes. ++void BarrierSetAssembler::tlab_allocate(MacroAssembler* masm, Register obj, ++ Register var_size_in_bytes, ++ int con_size_in_bytes, ++ Register tmp1, ++ Register tmp2, ++ Label& slow_case, ++ bool is_far) { ++ assert_different_registers(obj, tmp2); ++ assert_different_registers(obj, var_size_in_bytes); ++ Register end = tmp2; ++ ++ __ ld(obj, Address(xthread, JavaThread::tlab_top_offset())); ++ if (var_size_in_bytes == noreg) { ++ __ la(end, Address(obj, con_size_in_bytes)); ++ } else { ++ __ add(end, obj, var_size_in_bytes); ++ } ++ __ ld(t0, Address(xthread, JavaThread::tlab_end_offset())); ++ __ bgtu(end, t0, slow_case, is_far); ++ ++ // update the tlab top pointer ++ __ sd(end, Address(xthread, JavaThread::tlab_top_offset())); ++ ++ // recover var_size_in_bytes if necessary ++ if (var_size_in_bytes == end) { ++ __ sub(var_size_in_bytes, var_size_in_bytes, obj); ++ } ++} ++ ++// Defines obj, preserves var_size_in_bytes ++void BarrierSetAssembler::eden_allocate(MacroAssembler* masm, Register obj, ++ Register var_size_in_bytes, ++ int con_size_in_bytes, ++ Register tmp1, ++ Label& slow_case, ++ bool is_far) { ++ assert_cond(masm != NULL); ++ assert_different_registers(obj, var_size_in_bytes, tmp1); ++ if (!Universe::heap()->supports_inline_contig_alloc()) { ++ __ j(slow_case); ++ } else { ++ Register end = tmp1; ++ Label retry; ++ __ bind(retry); ++ ++ // Get the current end of the heap ++ ExternalAddress address_end((address) Universe::heap()->end_addr()); ++ { ++ int32_t offset; ++ __ la_patchable(t1, address_end, offset); ++ __ ld(t1, Address(t1, offset)); ++ } ++ ++ // Get the current top of the heap ++ ExternalAddress address_top((address) Universe::heap()->top_addr()); ++ { ++ int32_t offset; ++ __ la_patchable(t0, address_top, offset); ++ __ addi(t0, t0, offset); ++ __ lr_d(obj, t0, Assembler::aqrl); ++ } ++ ++ // Adjust it my the size of our new object ++ if (var_size_in_bytes == noreg) { ++ __ la(end, Address(obj, con_size_in_bytes)); ++ } else { ++ __ add(end, obj, var_size_in_bytes); ++ } ++ ++ // if end < obj then we wrapped around high memory ++ __ bltu(end, obj, slow_case, is_far); ++ ++ __ bgtu(end, t1, slow_case, is_far); ++ ++ // If heap_top hasn't been changed by some other thread, update it. ++ __ sc_d(t1, end, t0, Assembler::rl); ++ __ bnez(t1, retry); ++ ++ incr_allocated_bytes(masm, var_size_in_bytes, con_size_in_bytes, tmp1); ++ } ++} ++ ++void BarrierSetAssembler::incr_allocated_bytes(MacroAssembler* masm, ++ Register var_size_in_bytes, ++ int con_size_in_bytes, ++ Register tmp1) { ++ assert(tmp1->is_valid(), "need temp reg"); ++ ++ __ ld(tmp1, Address(xthread, in_bytes(JavaThread::allocated_bytes_offset()))); ++ if (var_size_in_bytes->is_valid()) { ++ __ add(tmp1, tmp1, var_size_in_bytes); ++ } else { ++ __ add(tmp1, tmp1, con_size_in_bytes); ++ } ++ __ sd(tmp1, Address(xthread, in_bytes(JavaThread::allocated_bytes_offset()))); ++} ++ ++void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) { ++ BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); ++ ++ if (bs_nm == NULL) { ++ return; ++ } ++ ++ Assembler::IncompressibleRegion ir(masm); // Fixed length: see entry_barrier_offset() ++ ++ // RISCV atomic operations require that the memory address be naturally aligned. ++ __ align(4); ++ ++ Label skip, guard; ++ Address thread_disarmed_addr(xthread, in_bytes(bs_nm->thread_disarmed_offset())); ++ ++ __ lwu(t0, guard); ++ ++ // Subsequent loads of oops must occur after load of guard value. ++ // BarrierSetNMethod::disarm sets guard with release semantics. ++ __ membar(MacroAssembler::LoadLoad); ++ __ lwu(t1, thread_disarmed_addr); ++ __ beq(t0, t1, skip); ++ ++ int32_t offset = 0; ++ __ movptr(t0, StubRoutines::riscv::method_entry_barrier(), offset); ++ __ jalr(ra, t0, offset); ++ __ j(skip); ++ ++ __ bind(guard); ++ ++ MacroAssembler::assert_alignment(__ pc()); ++ __ emit_int32(0); // nmethod guard value. Skipped over in common case. ++ ++ __ bind(skip); ++} ++ ++void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) { ++ BarrierSetNMethod* bs = BarrierSet::barrier_set()->barrier_set_nmethod(); ++ if (bs == NULL) { ++ return; ++ } ++ ++ Label bad_call; ++ __ beqz(xmethod, bad_call); ++ ++ // Pointer chase to the method holder to find out if the method is concurrently unloading. ++ Label method_live; ++ __ load_method_holder_cld(t0, xmethod); ++ ++ // Is it a strong CLD? ++ __ lwu(t1, Address(t0, ClassLoaderData::keep_alive_offset())); ++ __ bnez(t1, method_live); ++ ++ // Is it a weak but alive CLD? ++ __ push_reg(RegSet::of(x28, x29), sp); ++ ++ __ ld(x28, Address(t0, ClassLoaderData::holder_offset())); ++ ++ // Uses x28 & x29, so we must pass new temporaries. ++ __ resolve_weak_handle(x28, x29); ++ __ mv(t0, x28); ++ ++ __ pop_reg(RegSet::of(x28, x29), sp); ++ ++ __ bnez(t0, method_live); ++ ++ __ bind(bad_call); ++ ++ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); ++ __ bind(method_live); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.hpp +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (c) 2018, 2020, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_SHARED_BARRIERSETASSEMBLER_RISCV_HPP ++#define CPU_RISCV_GC_SHARED_BARRIERSETASSEMBLER_RISCV_HPP ++ ++#include "asm/macroAssembler.hpp" ++#include "gc/shared/barrierSet.hpp" ++#include "gc/shared/barrierSetNMethod.hpp" ++#include "memory/allocation.hpp" ++#include "oops/access.hpp" ++ ++class BarrierSetAssembler: public CHeapObj { ++private: ++ void incr_allocated_bytes(MacroAssembler* masm, ++ Register var_size_in_bytes, int con_size_in_bytes, ++ Register t1 = noreg); ++ ++public: ++ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register src, Register dst, Register count, RegSet saved_regs) {} ++ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register start, Register end, Register tmp, RegSet saved_regs) {} ++ virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Register dst, Address src, Register tmp1, Register tmp_thread); ++ virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2); ++ ++ virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env, ++ Register obj, Register tmp, Label& slowpath); ++ ++ virtual void tlab_allocate(MacroAssembler* masm, ++ Register obj, // result: pointer to object after successful allocation ++ Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise ++ int con_size_in_bytes, // object size in bytes if known at compile time ++ Register tmp1, // temp register ++ Register tmp2, // temp register ++ Label& slow_case, // continuation point if fast allocation fails ++ bool is_far = false ++ ); ++ ++ void eden_allocate(MacroAssembler* masm, ++ Register obj, // result: pointer to object after successful allocation ++ Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise ++ int con_size_in_bytes, // object size in bytes if known at compile time ++ Register tmp1, // temp register ++ Label& slow_case, // continuation point if fast allocation fails ++ bool is_far = false ++ ); ++ virtual void barrier_stubs_init() {} ++ ++ virtual void nmethod_entry_barrier(MacroAssembler* masm); ++ virtual void c2i_entry_barrier(MacroAssembler* masm); ++ virtual ~BarrierSetAssembler() {} ++}; ++ ++#endif // CPU_RISCV_GC_SHARED_BARRIERSETASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp +@@ -0,0 +1,171 @@ ++/* ++ * Copyright (c) 2018, 2020, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "code/codeCache.hpp" ++#include "code/nativeInst.hpp" ++#include "gc/shared/barrierSetNMethod.hpp" ++#include "logging/log.hpp" ++#include "memory/resourceArea.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/registerMap.hpp" ++#include "runtime/thread.hpp" ++#include "utilities/align.hpp" ++#include "utilities/debug.hpp" ++ ++class NativeNMethodBarrier: public NativeInstruction { ++ address instruction_address() const { return addr_at(0); } ++ ++ int *guard_addr() { ++ /* auipc + lwu + fence + lwu + beq + lui + addi + slli + addi + slli + jalr + j */ ++ return reinterpret_cast(instruction_address() + 12 * 4); ++ } ++ ++public: ++ int get_value() { ++ return Atomic::load_acquire(guard_addr()); ++ } ++ ++ void set_value(int value) { ++ Atomic::release_store(guard_addr(), value); ++ } ++ ++ void verify() const; ++}; ++ ++// Store the instruction bitmask, bits and name for checking the barrier. ++struct CheckInsn { ++ uint32_t mask; ++ uint32_t bits; ++ const char *name; ++}; ++ ++static const struct CheckInsn barrierInsn[] = { ++ { 0x00000fff, 0x00000297, "auipc t0, 0 "}, ++ { 0x000fffff, 0x0002e283, "lwu t0, 48(t0) "}, ++ { 0xffffffff, 0x0aa0000f, "fence ir, ir "}, ++ { 0x000fffff, 0x000be303, "lwu t1, 112(xthread)"}, ++ { 0x01fff07f, 0x00628063, "beq t0, t1, skip "}, ++ { 0x00000fff, 0x000002b7, "lui t0, imm0 "}, ++ { 0x000fffff, 0x00028293, "addi t0, t0, imm1 "}, ++ { 0xffffffff, 0x00b29293, "slli t0, t0, 11 "}, ++ { 0x000fffff, 0x00028293, "addi t0, t0, imm2 "}, ++ { 0xffffffff, 0x00629293, "slli t0, t0, 6 "}, ++ { 0x000fffff, 0x000280e7, "jalr ra, imm3(t0) "}, ++ { 0x00000fff, 0x0000006f, "j skip "} ++ /* guard: */ ++ /* 32bit nmethod guard value */ ++ /* skip: */ ++}; ++ ++// The encodings must match the instructions emitted by ++// BarrierSetAssembler::nmethod_entry_barrier. The matching ignores the specific ++// register numbers and immediate values in the encoding. ++void NativeNMethodBarrier::verify() const { ++ intptr_t addr = (intptr_t) instruction_address(); ++ for(unsigned int i = 0; i < sizeof(barrierInsn)/sizeof(struct CheckInsn); i++ ) { ++ uint32_t inst = *((uint32_t*) addr); ++ if ((inst & barrierInsn[i].mask) != barrierInsn[i].bits) { ++ tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", addr, inst); ++ fatal("not an %s instruction.", barrierInsn[i].name); ++ } ++ addr += 4; ++ } ++} ++ ++ ++/* We're called from an nmethod when we need to deoptimize it. We do ++ this by throwing away the nmethod's frame and jumping to the ++ ic_miss stub. This looks like there has been an IC miss at the ++ entry of the nmethod, so we resolve the call, which will fall back ++ to the interpreter if the nmethod has been unloaded. */ ++void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) { ++ ++ typedef struct { ++ intptr_t *sp; intptr_t *fp; address ra; address pc; ++ } frame_pointers_t; ++ ++ frame_pointers_t *new_frame = (frame_pointers_t *)(return_address_ptr - 5); ++ ++ JavaThread *thread = JavaThread::current(); ++ RegisterMap reg_map(thread, false); ++ frame frame = thread->last_frame(); ++ ++ assert(frame.is_compiled_frame() || frame.is_native_frame(), "must be"); ++ assert(frame.cb() == nm, "must be"); ++ frame = frame.sender(®_map); ++ ++ LogTarget(Trace, nmethod, barrier) out; ++ if (out.is_enabled()) { ++ ResourceMark mark; ++ log_trace(nmethod, barrier)("deoptimize(nmethod: %s(%p), return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p", ++ nm->method()->name_and_sig_as_C_string(), ++ nm, *(address *) return_address_ptr, nm->is_osr_method(), thread, ++ thread->name(), frame.sp(), nm->verified_entry_point()); ++ } ++ ++ new_frame->sp = frame.sp(); ++ new_frame->fp = frame.fp(); ++ new_frame->ra = frame.pc(); ++ new_frame->pc = SharedRuntime::get_handle_wrong_method_stub(); ++} ++ ++// This is the offset of the entry barrier from where the frame is completed. ++// If any code changes between the end of the verified entry where the entry ++// barrier resides, and the completion of the frame, then ++// NativeNMethodCmpBarrier::verify() will immediately complain when it does ++// not find the expected native instruction at this offset, which needs updating. ++// Note that this offset is invariant of PreserveFramePointer. ++ ++// see BarrierSetAssembler::nmethod_entry_barrier ++// auipc + lwu + fence + lwu + beq + movptr(5 instructions) + jalr + j + int32 ++static const int entry_barrier_offset = -4 * 13; ++ ++static NativeNMethodBarrier* native_nmethod_barrier(nmethod* nm) { ++ address barrier_address = nm->code_begin() + nm->frame_complete_offset() + entry_barrier_offset; ++ NativeNMethodBarrier* barrier = reinterpret_cast(barrier_address); ++ debug_only(barrier->verify()); ++ return barrier; ++} ++ ++void BarrierSetNMethod::disarm(nmethod* nm) { ++ if (!supports_entry_barrier(nm)) { ++ return; ++ } ++ ++ // Disarms the nmethod guard emitted by BarrierSetAssembler::nmethod_entry_barrier. ++ NativeNMethodBarrier* barrier = native_nmethod_barrier(nm); ++ ++ barrier->set_value(disarmed_value()); ++} ++ ++bool BarrierSetNMethod::is_armed(nmethod* nm) { ++ if (!supports_entry_barrier(nm)) { ++ return false; ++ } ++ ++ NativeNMethodBarrier* barrier = native_nmethod_barrier(nm); ++ return barrier->get_value() != disarmed_value(); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp +@@ -0,0 +1,107 @@ ++/* ++ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "gc/shared/barrierSet.hpp" ++#include "gc/shared/cardTable.hpp" ++#include "gc/shared/cardTableBarrierSet.hpp" ++#include "gc/shared/cardTableBarrierSetAssembler.hpp" ++#include "gc/shared/gc_globals.hpp" ++#include "interpreter/interp_masm.hpp" ++ ++#define __ masm-> ++ ++ ++void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Register tmp) { ++ assert_different_registers(obj, tmp); ++ BarrierSet* bs = BarrierSet::barrier_set(); ++ assert(bs->kind() == BarrierSet::CardTableBarrierSet, "Wrong barrier set kind"); ++ ++ __ srli(obj, obj, CardTable::card_shift); ++ ++ assert(CardTable::dirty_card_val() == 0, "must be"); ++ ++ __ load_byte_map_base(tmp); ++ __ add(tmp, obj, tmp); ++ ++ if (UseCondCardMark) { ++ Label L_already_dirty; ++ __ lbu(t1, Address(tmp)); ++ __ beqz(t1, L_already_dirty); ++ __ sb(zr, Address(tmp)); ++ __ bind(L_already_dirty); ++ } else { ++ __ sb(zr, Address(tmp)); ++ } ++} ++ ++void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register start, Register count, Register tmp, RegSet saved_regs) { ++ assert_different_registers(start, tmp); ++ assert_different_registers(count, tmp); ++ ++ Label L_loop, L_done; ++ const Register end = count; ++ ++ __ beqz(count, L_done); // zero count - nothing to do ++ // end = start + count << LogBytesPerHeapOop ++ __ shadd(end, count, start, count, LogBytesPerHeapOop); ++ __ sub(end, end, BytesPerHeapOop); // last element address to make inclusive ++ ++ __ srli(start, start, CardTable::card_shift); ++ __ srli(end, end, CardTable::card_shift); ++ __ sub(count, end, start); // number of bytes to copy ++ ++ __ load_byte_map_base(tmp); ++ __ add(start, start, tmp); ++ ++ __ bind(L_loop); ++ __ add(tmp, start, count); ++ __ sb(zr, Address(tmp)); ++ __ sub(count, count, 1); ++ __ bgez(count, L_loop); ++ __ bind(L_done); ++} ++ ++void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2) { ++ bool in_heap = (decorators & IN_HEAP) != 0; ++ bool is_array = (decorators & IS_ARRAY) != 0; ++ bool on_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; ++ bool precise = is_array || on_anonymous; ++ ++ bool needs_post_barrier = val != noreg && in_heap; ++ BarrierSetAssembler::store_at(masm, decorators, type, dst, val, noreg, noreg); ++ if (needs_post_barrier) { ++ // flatten object address if needed ++ if (!precise || dst.offset() == 0) { ++ store_check(masm, dst.base(), x13); ++ } else { ++ __ la(x13, dst); ++ store_check(masm, x13, t0); ++ } ++ } ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2018, 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_RISCV_HPP ++#define CPU_RISCV_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_RISCV_HPP ++ ++#include "asm/macroAssembler.hpp" ++#include "gc/shared/modRefBarrierSetAssembler.hpp" ++ ++class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { ++protected: ++ void store_check(MacroAssembler* masm, Register obj, Register tmp); ++ ++ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register start, Register count, Register tmp, RegSet saved_regs); ++ virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2); ++}; ++ ++#endif // #ifndef CPU_RISCV_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "gc/shared/modRefBarrierSetAssembler.hpp" ++ ++#define __ masm-> ++ ++void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register src, Register dst, Register count, RegSet saved_regs) { ++ if (is_oop) { ++ gen_write_ref_array_pre_barrier(masm, decorators, dst, count, saved_regs); ++ } ++} ++ ++void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register start, Register count, Register tmp, ++ RegSet saved_regs) { ++ if (is_oop) { ++ gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs); ++ } ++} ++ ++void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2) { ++ if (is_reference_type(type)) { ++ oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2); ++ } else { ++ BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2); ++ } ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.hpp +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (c) 2018, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_SHARED_MODREFBARRIERSETASSEMBLER_RISCV_HPP ++#define CPU_RISCV_GC_SHARED_MODREFBARRIERSETASSEMBLER_RISCV_HPP ++ ++#include "asm/macroAssembler.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++ ++// The ModRefBarrierSetAssembler filters away accesses on BasicTypes other ++// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected ++// accesses, which are overridden in the concrete BarrierSetAssembler. ++ ++class ModRefBarrierSetAssembler: public BarrierSetAssembler { ++protected: ++ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register addr, Register count, RegSet saved_regs) {} ++ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, ++ Register start, Register count, Register tmp, RegSet saved_regs) {} ++ ++ virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2) = 0; ++ ++public: ++ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register src, Register dst, Register count, RegSet saved_regs); ++ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register start, Register count, Register tmp, RegSet saved_regs); ++ virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2); ++}; ++ ++#endif // CPU_RISCV_GC_SHARED_MODREFBARRIERSETASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shenandoah/c1/shenandoahBarrierSetC1_riscv.cpp +@@ -0,0 +1,117 @@ ++/* ++ * Copyright (c) 2018, 2019, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "gc/shared/gc_globals.hpp" ++#include "gc/shenandoah/shenandoahBarrierSet.hpp" ++#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" ++#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp" ++ ++#define __ masm->masm()-> ++ ++void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) { ++ Register addr = _addr->as_register_lo(); ++ Register newval = _new_value->as_register(); ++ Register cmpval = _cmp_value->as_register(); ++ Register tmp1 = _tmp1->as_register(); ++ Register tmp2 = _tmp2->as_register(); ++ Register result = result_opr()->as_register(); ++ ++ ShenandoahBarrierSet::assembler()->iu_barrier(masm->masm(), newval, t1); ++ ++ if (UseCompressedOops) { ++ __ encode_heap_oop(tmp1, cmpval); ++ cmpval = tmp1; ++ __ encode_heap_oop(tmp2, newval); ++ newval = tmp2; ++ } ++ ++ ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), addr, cmpval, newval, /* acquire */ Assembler::aq, ++ /* release */ Assembler::rl, /* is_cae */ false, result); ++} ++ ++#undef __ ++ ++#ifdef ASSERT ++#define __ gen->lir(__FILE__, __LINE__)-> ++#else ++#define __ gen->lir()-> ++#endif ++ ++LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) { ++ BasicType bt = access.type(); ++ if (access.is_oop()) { ++ LIRGenerator *gen = access.gen(); ++ if (ShenandoahSATBBarrier) { ++ pre_barrier(gen, access.access_emit_info(), access.decorators(), access.resolved_addr(), ++ LIR_OprFact::illegalOpr /* pre_val */); ++ } ++ if (ShenandoahCASBarrier) { ++ cmp_value.load_item(); ++ new_value.load_item(); ++ ++ LIR_Opr tmp1 = gen->new_register(T_OBJECT); ++ LIR_Opr tmp2 = gen->new_register(T_OBJECT); ++ LIR_Opr addr = access.resolved_addr()->as_address_ptr()->base(); ++ LIR_Opr result = gen->new_register(T_INT); ++ ++ __ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), tmp1, tmp2, result)); ++ return result; ++ } ++ } ++ return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value); ++} ++ ++LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) { ++ LIRGenerator* gen = access.gen(); ++ BasicType type = access.type(); ++ ++ LIR_Opr result = gen->new_register(type); ++ value.load_item(); ++ LIR_Opr value_opr = value.result(); ++ ++ if (access.is_oop()) { ++ value_opr = iu_barrier(access.gen(), value_opr, access.access_emit_info(), access.decorators()); ++ } ++ ++ assert(type == T_INT || is_reference_type(type) LP64_ONLY( || type == T_LONG ), "unexpected type"); ++ LIR_Opr tmp = gen->new_register(T_INT); ++ __ xchg(access.resolved_addr(), value_opr, result, tmp); ++ ++ if (access.is_oop()) { ++ result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), access.decorators()); ++ LIR_Opr tmp_opr = gen->new_register(type); ++ __ move(result, tmp_opr); ++ result = tmp_opr; ++ if (ShenandoahSATBBarrier) { ++ pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr, ++ result /* pre_val */); ++ } ++ } ++ ++ return result; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp +@@ -0,0 +1,714 @@ ++/* ++ * Copyright (c) 2018, 2020, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "gc/shenandoah/shenandoahBarrierSet.hpp" ++#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" ++#include "gc/shenandoah/shenandoahForwarding.hpp" ++#include "gc/shenandoah/shenandoahHeap.inline.hpp" ++#include "gc/shenandoah/shenandoahHeapRegion.hpp" ++#include "gc/shenandoah/shenandoahRuntime.hpp" ++#include "gc/shenandoah/shenandoahThreadLocalData.hpp" ++#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" ++#include "interpreter/interpreter.hpp" ++#include "interpreter/interp_masm.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/thread.hpp" ++#ifdef COMPILER1 ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp" ++#endif ++ ++#define __ masm-> ++ ++void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register src, Register dst, Register count, RegSet saved_regs) { ++ if (is_oop) { ++ bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0; ++ if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahIUBarrier || ShenandoahLoadRefBarrier) { ++ ++ Label done; ++ ++ // Avoid calling runtime if count == 0 ++ __ beqz(count, done); ++ ++ // Is GC active? ++ Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); ++ assert_different_registers(src, dst, count, t0); ++ ++ __ lbu(t0, gc_state); ++ if (ShenandoahSATBBarrier && dest_uninitialized) { ++ __ test_bit(t0, t0, ShenandoahHeap::HAS_FORWARDED_BITPOS); ++ __ beqz(t0, done); ++ } else { ++ __ andi(t0, t0, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING); ++ __ beqz(t0, done); ++ } ++ ++ __ push_reg(saved_regs, sp); ++ if (UseCompressedOops) { ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry), ++ src, dst, count); ++ } else { ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), src, dst, count); ++ } ++ __ pop_reg(saved_regs, sp); ++ __ bind(done); ++ } ++ } ++} ++ ++void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm, ++ Register obj, ++ Register pre_val, ++ Register thread, ++ Register tmp, ++ bool tosca_live, ++ bool expand_call) { ++ if (ShenandoahSATBBarrier) { ++ satb_write_barrier_pre(masm, obj, pre_val, thread, tmp, tosca_live, expand_call); ++ } ++} ++ ++void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm, ++ Register obj, ++ Register pre_val, ++ Register thread, ++ Register tmp, ++ bool tosca_live, ++ bool expand_call) { ++ // If expand_call is true then we expand the call_VM_leaf macro ++ // directly to skip generating the check by ++ // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp. ++ assert(thread == xthread, "must be"); ++ ++ Label done; ++ Label runtime; ++ ++ assert_different_registers(obj, pre_val, tmp, t0); ++ assert(pre_val != noreg && tmp != noreg, "expecting a register"); ++ ++ Address in_progress(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset())); ++ Address index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset())); ++ Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset())); ++ ++ // Is marking active? ++ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { ++ __ lwu(tmp, in_progress); ++ } else { ++ assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); ++ __ lbu(tmp, in_progress); ++ } ++ __ beqz(tmp, done); ++ ++ // Do we need to load the previous value? ++ if (obj != noreg) { ++ __ load_heap_oop(pre_val, Address(obj, 0), noreg, noreg, AS_RAW); ++ } ++ ++ // Is the previous value null? ++ __ beqz(pre_val, done); ++ ++ // Can we store original value in the thread's buffer? ++ // Is index == 0? ++ // (The index field is typed as size_t.) ++ __ ld(tmp, index); // tmp := *index_adr ++ __ beqz(tmp, runtime); // tmp == 0? If yes, goto runtime ++ ++ __ sub(tmp, tmp, wordSize); // tmp := tmp - wordSize ++ __ sd(tmp, index); // *index_adr := tmp ++ __ ld(t0, buffer); ++ __ add(tmp, tmp, t0); // tmp := tmp + *buffer_adr ++ ++ // Record the previous value ++ __ sd(pre_val, Address(tmp, 0)); ++ __ j(done); ++ ++ __ bind(runtime); ++ // save the live input values ++ RegSet saved = RegSet::of(pre_val); ++ if (tosca_live) saved += RegSet::of(x10); ++ if (obj != noreg) saved += RegSet::of(obj); ++ ++ __ push_reg(saved, sp); ++ ++ // Calling the runtime using the regular call_VM_leaf mechanism generates ++ // code (generated by InterpreterMacroAssember::call_VM_leaf_base) ++ // that checks that the *(rfp+frame::interpreter_frame_last_sp) == NULL. ++ // ++ // If we care generating the pre-barrier without a frame (e.g. in the ++ // intrinsified Reference.get() routine) then ebp might be pointing to ++ // the caller frame and so this check will most likely fail at runtime. ++ // ++ // Expanding the call directly bypasses the generation of the check. ++ // So when we do not have have a full interpreter frame on the stack ++ // expand_call should be passed true. ++ if (expand_call) { ++ assert(pre_val != c_rarg1, "smashed arg"); ++ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread); ++ } else { ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread); ++ } ++ ++ __ pop_reg(saved, sp); ++ ++ __ bind(done); ++} ++ ++void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp) { ++ assert(ShenandoahLoadRefBarrier || ShenandoahCASBarrier, "Should be enabled"); ++ ++ Label is_null; ++ __ beqz(dst, is_null); ++ resolve_forward_pointer_not_null(masm, dst, tmp); ++ __ bind(is_null); ++} ++ ++// IMPORTANT: This must preserve all registers, even t0 and t1, except those explicitely ++// passed in. ++void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) { ++ assert(ShenandoahLoadRefBarrier || ShenandoahCASBarrier, "Should be enabled"); ++ // The below loads the mark word, checks if the lowest two bits are ++ // set, and if so, clear the lowest two bits and copy the result ++ // to dst. Otherwise it leaves dst alone. ++ // Implementing this is surprisingly awkward. I do it here by: ++ // - Inverting the mark word ++ // - Test lowest two bits == 0 ++ // - If so, set the lowest two bits ++ // - Invert the result back, and copy to dst ++ RegSet saved_regs = RegSet::of(t2); ++ bool borrow_reg = (tmp == noreg); ++ if (borrow_reg) { ++ // No free registers available. Make one useful. ++ tmp = t0; ++ if (tmp == dst) { ++ tmp = t1; ++ } ++ saved_regs += RegSet::of(tmp); ++ } ++ ++ assert_different_registers(tmp, dst, t2); ++ __ push_reg(saved_regs, sp); ++ ++ Label done; ++ __ ld(tmp, Address(dst, oopDesc::mark_offset_in_bytes())); ++ __ xori(tmp, tmp, -1); // eon with 0 is equivalent to XOR with -1 ++ __ andi(t2, tmp, markWord::lock_mask_in_place); ++ __ bnez(t2, done); ++ __ ori(tmp, tmp, markWord::marked_value); ++ __ xori(dst, tmp, -1); // eon with 0 is equivalent to XOR with -1 ++ __ bind(done); ++ ++ __ pop_reg(saved_regs, sp); ++} ++ ++void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, ++ Register dst, ++ Address load_addr, ++ DecoratorSet decorators) { ++ assert(ShenandoahLoadRefBarrier, "Should be enabled"); ++ assert(dst != t1 && load_addr.base() != t1, "need t1"); ++ assert_different_registers(load_addr.base(), t0, t1); ++ ++ bool is_strong = ShenandoahBarrierSet::is_strong_access(decorators); ++ bool is_weak = ShenandoahBarrierSet::is_weak_access(decorators); ++ bool is_phantom = ShenandoahBarrierSet::is_phantom_access(decorators); ++ bool is_native = ShenandoahBarrierSet::is_native_access(decorators); ++ bool is_narrow = UseCompressedOops && !is_native; ++ ++ Label heap_stable, not_cset; ++ __ enter(); ++ Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); ++ __ lbu(t1, gc_state); ++ ++ // Check for heap stability ++ if (is_strong) { ++ __ test_bit(t1, t1, ShenandoahHeap::HAS_FORWARDED_BITPOS); ++ __ beqz(t1, heap_stable); ++ } else { ++ Label lrb; ++ __ test_bit(t0, t1, ShenandoahHeap::WEAK_ROOTS_BITPOS); ++ __ bnez(t0, lrb); ++ __ test_bit(t0, t1, ShenandoahHeap::HAS_FORWARDED_BITPOS); ++ __ beqz(t0, heap_stable); ++ __ bind(lrb); ++ } ++ ++ // use x11 for load address ++ Register result_dst = dst; ++ if (dst == x11) { ++ __ mv(t1, dst); ++ dst = t1; ++ } ++ ++ // Save x10 and x11, unless it is an output register ++ RegSet saved_regs = RegSet::of(x10, x11) - result_dst; ++ __ push_reg(saved_regs, sp); ++ __ la(x11, load_addr); ++ __ mv(x10, dst); ++ ++ // Test for in-cset ++ if (is_strong) { ++ __ mv(t1, ShenandoahHeap::in_cset_fast_test_addr()); ++ __ srli(t0, x10, ShenandoahHeapRegion::region_size_bytes_shift_jint()); ++ __ add(t1, t1, t0); ++ __ lbu(t1, Address(t1)); ++ __ test_bit(t0, t1, 0); ++ __ beqz(t0, not_cset); ++ } ++ ++ __ push_call_clobbered_registers(); ++ address target = NULL; ++ if (is_strong) { ++ if (is_narrow) { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong_narrow); ++ } else { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong); ++ } ++ } else if (is_weak) { ++ if (is_narrow) { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow); ++ } else { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak); ++ } ++ } else { ++ assert(is_phantom, "only remaining strength"); ++ assert(!is_narrow, "phantom access cannot be narrow"); ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak); ++ } ++ __ call(target); ++ __ mv(t0, x10); ++ __ pop_call_clobbered_registers(); ++ __ mv(x10, t0); ++ __ bind(not_cset); ++ __ mv(result_dst, x10); ++ __ pop_reg(saved_regs, sp); ++ ++ __ bind(heap_stable); ++ __ leave(); ++} ++ ++void ShenandoahBarrierSetAssembler::iu_barrier(MacroAssembler* masm, Register dst, Register tmp) { ++ if (ShenandoahIUBarrier) { ++ __ push_call_clobbered_registers(); ++ ++ satb_write_barrier_pre(masm, noreg, dst, xthread, tmp, true, false); ++ ++ __ pop_call_clobbered_registers(); ++ } ++} ++ ++// ++// Arguments: ++// ++// Inputs: ++// src: oop location to load from, might be clobbered ++// ++// Output: ++// dst: oop loaded from src location ++// ++// Kill: ++// x30 (tmp reg) ++// ++// Alias: ++// dst: x30 (might use x30 as temporary output register to avoid clobbering src) ++// ++void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, ++ DecoratorSet decorators, ++ BasicType type, ++ Register dst, ++ Address src, ++ Register tmp1, ++ Register tmp_thread) { ++ // 1: non-reference load, no additional barrier is needed ++ if (!is_reference_type(type)) { ++ BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); ++ return; ++ } ++ ++ // 2: load a reference from src location and apply LRB if needed ++ if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) { ++ Register result_dst = dst; ++ ++ // Preserve src location for LRB ++ RegSet saved_regs; ++ if (dst == src.base()) { ++ dst = (src.base() == x28) ? x29 : x28; ++ saved_regs = RegSet::of(dst); ++ __ push_reg(saved_regs, sp); ++ } ++ assert_different_registers(dst, src.base()); ++ ++ BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); ++ ++ load_reference_barrier(masm, dst, src, decorators); ++ ++ if (dst != result_dst) { ++ __ mv(result_dst, dst); ++ dst = result_dst; ++ } ++ ++ if (saved_regs.bits() != 0) { ++ __ pop_reg(saved_regs, sp); ++ } ++ } else { ++ BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); ++ } ++ ++ // 3: apply keep-alive barrier if needed ++ if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) { ++ __ enter(); ++ __ push_call_clobbered_registers(); ++ satb_write_barrier_pre(masm /* masm */, ++ noreg /* obj */, ++ dst /* pre_val */, ++ xthread /* thread */, ++ tmp1 /* tmp */, ++ true /* tosca_live */, ++ true /* expand_call */); ++ __ pop_call_clobbered_registers(); ++ __ leave(); ++ } ++} ++ ++void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2) { ++ bool on_oop = is_reference_type(type); ++ if (!on_oop) { ++ BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2); ++ return; ++ } ++ ++ // flatten object address if needed ++ if (dst.offset() == 0) { ++ if (dst.base() != x13) { ++ __ mv(x13, dst.base()); ++ } ++ } else { ++ __ la(x13, dst); ++ } ++ ++ shenandoah_write_barrier_pre(masm, ++ x13 /* obj */, ++ tmp2 /* pre_val */, ++ xthread /* thread */, ++ tmp1 /* tmp */, ++ val != noreg /* tosca_live */, ++ false /* expand_call */); ++ ++ if (val == noreg) { ++ BarrierSetAssembler::store_at(masm, decorators, type, Address(x13, 0), noreg, noreg, noreg); ++ } else { ++ iu_barrier(masm, val, tmp1); ++ // G1 barrier needs uncompressed oop for region cross check. ++ Register new_val = val; ++ if (UseCompressedOops) { ++ new_val = t1; ++ __ mv(new_val, val); ++ } ++ BarrierSetAssembler::store_at(masm, decorators, type, Address(x13, 0), val, noreg, noreg); ++ } ++} ++ ++void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env, ++ Register obj, Register tmp, Label& slowpath) { ++ Label done; ++ // Resolve jobject ++ BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, obj, tmp, slowpath); ++ ++ // Check for null. ++ __ beqz(obj, done); ++ ++ assert(obj != t1, "need t1"); ++ Address gc_state(jni_env, ShenandoahThreadLocalData::gc_state_offset() - JavaThread::jni_environment_offset()); ++ __ lbu(t1, gc_state); ++ ++ // Check for heap in evacuation phase ++ __ test_bit(t0, t1, ShenandoahHeap::EVACUATION_BITPOS); ++ __ bnez(t0, slowpath); ++ ++ __ bind(done); ++} ++ ++// Special Shenandoah CAS implementation that handles false negatives due ++// to concurrent evacuation. The service is more complex than a ++// traditional CAS operation because the CAS operation is intended to ++// succeed if the reference at addr exactly matches expected or if the ++// reference at addr holds a pointer to a from-space object that has ++// been relocated to the location named by expected. There are two ++// races that must be addressed: ++// a) A parallel thread may mutate the contents of addr so that it points ++// to a different object. In this case, the CAS operation should fail. ++// b) A parallel thread may heal the contents of addr, replacing a ++// from-space pointer held in addr with the to-space pointer ++// representing the new location of the object. ++// Upon entry to cmpxchg_oop, it is assured that new_val equals NULL ++// or it refers to an object that is not being evacuated out of ++// from-space, or it refers to the to-space version of an object that ++// is being evacuated out of from-space. ++// ++// By default the value held in the result register following execution ++// of the generated code sequence is 0 to indicate failure of CAS, ++// non-zero to indicate success. If is_cae, the result is the value most ++// recently fetched from addr rather than a boolean success indicator. ++// ++// Clobbers t0, t1 ++void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, ++ Register addr, ++ Register expected, ++ Register new_val, ++ Assembler::Aqrl acquire, ++ Assembler::Aqrl release, ++ bool is_cae, ++ Register result) { ++ bool is_narrow = UseCompressedOops; ++ Assembler::operand_size size = is_narrow ? Assembler::uint32 : Assembler::int64; ++ ++ assert_different_registers(addr, expected, t0, t1); ++ assert_different_registers(addr, new_val, t0, t1); ++ ++ Label retry, success, fail, done; ++ ++ __ bind(retry); ++ ++ // Step1: Try to CAS. ++ __ cmpxchg(addr, expected, new_val, size, acquire, release, /* result */ t1); ++ ++ // If success, then we are done. ++ __ beq(expected, t1, success); ++ ++ // Step2: CAS failed, check the forwared pointer. ++ __ mv(t0, t1); ++ ++ if (is_narrow) { ++ __ decode_heap_oop(t0, t0); ++ } ++ resolve_forward_pointer(masm, t0); ++ ++ __ encode_heap_oop(t0, t0); ++ ++ // Report failure when the forwarded oop was not expected. ++ __ bne(t0, expected, fail); ++ ++ // Step 3: CAS again using the forwarded oop. ++ __ cmpxchg(addr, t1, new_val, size, acquire, release, /* result */ t0); ++ ++ // Retry when failed. ++ __ bne(t0, t1, retry); ++ ++ __ bind(success); ++ if (is_cae) { ++ __ mv(result, expected); ++ } else { ++ __ mv(result, 1); ++ } ++ __ j(done); ++ ++ __ bind(fail); ++ if (is_cae) { ++ __ mv(result, t0); ++ } else { ++ __ mv(result, zr); ++ } ++ ++ __ bind(done); ++} ++ ++#undef __ ++ ++#ifdef COMPILER1 ++ ++#define __ ce->masm()-> ++ ++void ShenandoahBarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub) { ++ ShenandoahBarrierSetC1* bs = (ShenandoahBarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1(); ++ // At this point we know that marking is in progress. ++ // If do_load() is true then we have to emit the ++ // load of the previous value; otherwise it has already ++ // been loaded into _pre_val. ++ __ bind(*stub->entry()); ++ ++ assert(stub->pre_val()->is_register(), "Precondition."); ++ ++ Register pre_val_reg = stub->pre_val()->as_register(); ++ ++ if (stub->do_load()) { ++ ce->mem2reg(stub->addr(), stub->pre_val(), T_OBJECT, stub->patch_code(), stub->info(), false /* wide */, false /* unaligned */); ++ } ++ __ beqz(pre_val_reg, *stub->continuation(), /* is_far */ true); ++ ce->store_parameter(stub->pre_val()->as_register(), 0); ++ __ far_call(RuntimeAddress(bs->pre_barrier_c1_runtime_code_blob()->code_begin())); ++ __ j(*stub->continuation()); ++} ++ ++void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assembler* ce, ++ ShenandoahLoadReferenceBarrierStub* stub) { ++ ShenandoahBarrierSetC1* bs = (ShenandoahBarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1(); ++ __ bind(*stub->entry()); ++ ++ DecoratorSet decorators = stub->decorators(); ++ bool is_strong = ShenandoahBarrierSet::is_strong_access(decorators); ++ bool is_weak = ShenandoahBarrierSet::is_weak_access(decorators); ++ bool is_phantom = ShenandoahBarrierSet::is_phantom_access(decorators); ++ bool is_native = ShenandoahBarrierSet::is_native_access(decorators); ++ ++ Register obj = stub->obj()->as_register(); ++ Register res = stub->result()->as_register(); ++ Register addr = stub->addr()->as_pointer_register(); ++ Register tmp1 = stub->tmp1()->as_register(); ++ Register tmp2 = stub->tmp2()->as_register(); ++ ++ assert(res == x10, "result must arrive in x10"); ++ assert_different_registers(tmp1, tmp2, t0); ++ ++ if (res != obj) { ++ __ mv(res, obj); ++ } ++ ++ if (is_strong) { ++ // Check for object in cset. ++ __ mv(tmp2, ShenandoahHeap::in_cset_fast_test_addr()); ++ __ srli(tmp1, res, ShenandoahHeapRegion::region_size_bytes_shift_jint()); ++ __ add(tmp2, tmp2, tmp1); ++ __ lbu(tmp2, Address(tmp2)); ++ __ beqz(tmp2, *stub->continuation(), true /* is_far */); ++ } ++ ++ ce->store_parameter(res, 0); ++ ce->store_parameter(addr, 1); ++ ++ if (is_strong) { ++ if (is_native) { ++ __ far_call(RuntimeAddress(bs->load_reference_barrier_strong_native_rt_code_blob()->code_begin())); ++ } else { ++ __ far_call(RuntimeAddress(bs->load_reference_barrier_strong_rt_code_blob()->code_begin())); ++ } ++ } else if (is_weak) { ++ __ far_call(RuntimeAddress(bs->load_reference_barrier_weak_rt_code_blob()->code_begin())); ++ } else { ++ assert(is_phantom, "only remaining strength"); ++ __ far_call(RuntimeAddress(bs->load_reference_barrier_phantom_rt_code_blob()->code_begin())); ++ } ++ ++ __ j(*stub->continuation()); ++} ++ ++#undef __ ++ ++#define __ sasm-> ++ ++void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) { ++ __ prologue("shenandoah_pre_barrier", false); ++ ++ // arg0 : previous value of memory ++ ++ BarrierSet* bs = BarrierSet::barrier_set(); ++ ++ const Register pre_val = x10; ++ const Register thread = xthread; ++ const Register tmp = t0; ++ ++ Address queue_index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset())); ++ Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset())); ++ ++ Label done; ++ Label runtime; ++ ++ // Is marking still active? ++ Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); ++ __ lb(tmp, gc_state); ++ __ test_bit(tmp, tmp, ShenandoahHeap::MARKING_BITPOS); ++ __ beqz(tmp, done); ++ ++ // Can we store original value in the thread's buffer? ++ __ ld(tmp, queue_index); ++ __ beqz(tmp, runtime); ++ ++ __ sub(tmp, tmp, wordSize); ++ __ sd(tmp, queue_index); ++ __ ld(t1, buffer); ++ __ add(tmp, tmp, t1); ++ __ load_parameter(0, t1); ++ __ sd(t1, Address(tmp, 0)); ++ __ j(done); ++ ++ __ bind(runtime); ++ __ push_call_clobbered_registers(); ++ __ load_parameter(0, pre_val); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread); ++ __ pop_call_clobbered_registers(); ++ __ bind(done); ++ ++ __ epilogue(); ++} ++ ++void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, ++ DecoratorSet decorators) { ++ __ prologue("shenandoah_load_reference_barrier", false); ++ // arg0 : object to be resolved ++ ++ __ push_call_clobbered_registers(); ++ __ load_parameter(0, x10); ++ __ load_parameter(1, x11); ++ ++ bool is_strong = ShenandoahBarrierSet::is_strong_access(decorators); ++ bool is_weak = ShenandoahBarrierSet::is_weak_access(decorators); ++ bool is_phantom = ShenandoahBarrierSet::is_phantom_access(decorators); ++ bool is_native = ShenandoahBarrierSet::is_native_access(decorators); ++ address target = NULL; ++ if (is_strong) { ++ if (is_native) { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong); ++ } else { ++ if (UseCompressedOops) { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong_narrow); ++ } else { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong); ++ } ++ } ++ } else if (is_weak) { ++ assert(!is_native, "weak must not be called off-heap"); ++ if (UseCompressedOops) { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow); ++ } else { ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak); ++ } ++ } else { ++ assert(is_phantom, "only remaining strength"); ++ assert(is_native, "phantom must only be called off-heap"); ++ target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom); ++ } ++ __ call(target); ++ __ mv(t0, x10); ++ __ pop_call_clobbered_registers(); ++ __ mv(x10, t0); ++ ++ __ epilogue(); ++} ++ ++#undef __ ++ ++#endif // COMPILER1 +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.hpp +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (c) 2018, 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_RISCV_HPP ++#define CPU_RISCV_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_RISCV_HPP ++ ++#include "asm/macroAssembler.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "gc/shenandoah/shenandoahBarrierSet.hpp" ++#ifdef COMPILER1 ++class LIR_Assembler; ++class ShenandoahPreBarrierStub; ++class ShenandoahLoadReferenceBarrierStub; ++class StubAssembler; ++#endif ++class StubCodeGenerator; ++ ++class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { ++private: ++ ++ void satb_write_barrier_pre(MacroAssembler* masm, ++ Register obj, ++ Register pre_val, ++ Register thread, ++ Register tmp, ++ bool tosca_live, ++ bool expand_call); ++ void shenandoah_write_barrier_pre(MacroAssembler* masm, ++ Register obj, ++ Register pre_val, ++ Register thread, ++ Register tmp, ++ bool tosca_live, ++ bool expand_call); ++ ++ void resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp = noreg); ++ void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg); ++ void load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr, DecoratorSet decorators); ++ ++public: ++ ++ void iu_barrier(MacroAssembler* masm, Register dst, Register tmp); ++ ++#ifdef COMPILER1 ++ void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub); ++ void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub); ++ void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm); ++ void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, DecoratorSet decorators); ++#endif ++ ++ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, ++ Register src, Register dst, Register count, RegSet saved_regs); ++ ++ virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Register dst, Address src, Register tmp1, Register tmp_thread); ++ virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, ++ Address dst, Register val, Register tmp1, Register tmp2); ++ ++ virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env, ++ Register obj, Register tmp, Label& slowpath); ++ ++ void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, bool is_cae, Register result); ++}; ++ ++#endif // CPU_RISCV_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv64.ad +@@ -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); ++%} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp +@@ -0,0 +1,445 @@ ++/* ++ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "code/codeBlob.hpp" ++#include "code/vmreg.inline.hpp" ++#include "gc/z/zBarrier.inline.hpp" ++#include "gc/z/zBarrierSet.hpp" ++#include "gc/z/zBarrierSetAssembler.hpp" ++#include "gc/z/zBarrierSetRuntime.hpp" ++#include "gc/z/zThreadLocalData.hpp" ++#include "memory/resourceArea.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "utilities/macros.hpp" ++#ifdef COMPILER1 ++#include "c1/c1_LIRAssembler.hpp" ++#include "c1/c1_MacroAssembler.hpp" ++#include "gc/z/c1/zBarrierSetC1.hpp" ++#endif // COMPILER1 ++#ifdef COMPILER2 ++#include "gc/z/c2/zBarrierSetC2.hpp" ++#endif // COMPILER2 ++ ++#ifdef PRODUCT ++#define BLOCK_COMMENT(str) /* nothing */ ++#else ++#define BLOCK_COMMENT(str) __ block_comment(str) ++#endif ++ ++#undef __ ++#define __ masm-> ++ ++void ZBarrierSetAssembler::load_at(MacroAssembler* masm, ++ DecoratorSet decorators, ++ BasicType type, ++ Register dst, ++ Address src, ++ Register tmp1, ++ Register tmp_thread) { ++ if (!ZBarrierSet::barrier_needed(decorators, type)) { ++ // Barrier not needed ++ BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); ++ return; ++ } ++ ++ assert_different_registers(t1, src.base()); ++ assert_different_registers(t0, t1, dst); ++ ++ Label done; ++ ++ // Load bad mask into temp register. ++ __ la(t0, src); ++ __ ld(t1, address_bad_mask_from_thread(xthread)); ++ __ ld(dst, Address(t0)); ++ ++ // Test reference against bad mask. If mask bad, then we need to fix it up. ++ __ andr(t1, dst, t1); ++ __ beqz(t1, done); ++ ++ __ enter(); ++ ++ __ push_call_clobbered_registers_except(RegSet::of(dst)); ++ ++ if (c_rarg0 != dst) { ++ __ mv(c_rarg0, dst); ++ } ++ ++ __ mv(c_rarg1, t0); ++ ++ __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2); ++ ++ // Make sure dst has the return value. ++ if (dst != x10) { ++ __ mv(dst, x10); ++ } ++ ++ __ pop_call_clobbered_registers_except(RegSet::of(dst)); ++ __ leave(); ++ ++ __ bind(done); ++} ++ ++#ifdef ASSERT ++ ++void ZBarrierSetAssembler::store_at(MacroAssembler* masm, ++ DecoratorSet decorators, ++ BasicType type, ++ Address dst, ++ Register val, ++ Register tmp1, ++ Register tmp2) { ++ // Verify value ++ if (is_reference_type(type)) { ++ // Note that src could be noreg, which means we ++ // are storing null and can skip verification. ++ if (val != noreg) { ++ Label done; ++ ++ // tmp1 and tmp2 are often set to noreg. ++ RegSet savedRegs = RegSet::of(t0); ++ __ push_reg(savedRegs, sp); ++ ++ __ ld(t0, address_bad_mask_from_thread(xthread)); ++ __ andr(t0, val, t0); ++ __ beqz(t0, done); ++ __ stop("Verify oop store failed"); ++ __ should_not_reach_here(); ++ __ bind(done); ++ __ pop_reg(savedRegs, sp); ++ } ++ } ++ ++ // Store value ++ BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2); ++} ++ ++#endif // ASSERT ++ ++void ZBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, ++ DecoratorSet decorators, ++ bool is_oop, ++ Register src, ++ Register dst, ++ Register count, ++ RegSet saved_regs) { ++ if (!is_oop) { ++ // Barrier not needed ++ return; ++ } ++ ++ BLOCK_COMMENT("ZBarrierSetAssembler::arraycopy_prologue {"); ++ ++ assert_different_registers(src, count, t0); ++ ++ __ push_reg(saved_regs, sp); ++ ++ if (count == c_rarg0 && src == c_rarg1) { ++ // exactly backwards!! ++ __ xorr(c_rarg0, c_rarg0, c_rarg1); ++ __ xorr(c_rarg1, c_rarg0, c_rarg1); ++ __ xorr(c_rarg0, c_rarg0, c_rarg1); ++ } else { ++ __ mv(c_rarg0, src); ++ __ mv(c_rarg1, count); ++ } ++ ++ __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_array_addr(), 2); ++ ++ __ pop_reg(saved_regs, sp); ++ ++ BLOCK_COMMENT("} ZBarrierSetAssembler::arraycopy_prologue"); ++} ++ ++void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, ++ Register jni_env, ++ Register robj, ++ Register tmp, ++ Label& slowpath) { ++ BLOCK_COMMENT("ZBarrierSetAssembler::try_resolve_jobject_in_native {"); ++ ++ assert_different_registers(jni_env, robj, tmp); ++ ++ // Resolve jobject ++ BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, robj, tmp, slowpath); ++ ++ // Compute the offset of address bad mask from the field of jni_environment ++ long int bad_mask_relative_offset = (long int) (in_bytes(ZThreadLocalData::address_bad_mask_offset()) - ++ in_bytes(JavaThread::jni_environment_offset())); ++ ++ // Load the address bad mask ++ __ ld(tmp, Address(jni_env, bad_mask_relative_offset)); ++ ++ // Check address bad mask ++ __ andr(tmp, robj, tmp); ++ __ bnez(tmp, slowpath); ++ ++ BLOCK_COMMENT("} ZBarrierSetAssembler::try_resolve_jobject_in_native"); ++} ++ ++#ifdef COMPILER2 ++ ++OptoReg::Name ZBarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) { ++ if (!OptoReg::is_reg(opto_reg)) { ++ return OptoReg::Bad; ++ } ++ ++ const VMReg vm_reg = OptoReg::as_VMReg(opto_reg); ++ if (vm_reg->is_FloatRegister()) { ++ return opto_reg & ~1; ++ } ++ ++ return opto_reg; ++} ++ ++#undef __ ++#define __ _masm-> ++ ++class ZSaveLiveRegisters { ++private: ++ MacroAssembler* const _masm; ++ RegSet _gp_regs; ++ FloatRegSet _fp_regs; ++ VectorRegSet _vp_regs; ++ ++public: ++ void initialize(ZLoadBarrierStubC2* stub) { ++ // Record registers that needs to be saved/restored ++ RegMaskIterator rmi(stub->live()); ++ while (rmi.has_next()) { ++ const OptoReg::Name opto_reg = rmi.next(); ++ if (OptoReg::is_reg(opto_reg)) { ++ const VMReg vm_reg = OptoReg::as_VMReg(opto_reg); ++ if (vm_reg->is_Register()) { ++ _gp_regs += RegSet::of(vm_reg->as_Register()); ++ } else if (vm_reg->is_FloatRegister()) { ++ _fp_regs += FloatRegSet::of(vm_reg->as_FloatRegister()); ++ } else if (vm_reg->is_VectorRegister()) { ++ const VMReg vm_reg_base = OptoReg::as_VMReg(opto_reg & ~(VectorRegisterImpl::max_slots_per_register - 1)); ++ _vp_regs += VectorRegSet::of(vm_reg_base->as_VectorRegister()); ++ } else { ++ fatal("Unknown register type"); ++ } ++ } ++ } ++ ++ // Remove C-ABI SOE registers, tmp regs and _ref register that will be updated ++ _gp_regs -= RegSet::range(x18, x27) + RegSet::of(x2) + RegSet::of(x8, x9) + RegSet::of(x5, stub->ref()); ++ } ++ ++ ZSaveLiveRegisters(MacroAssembler* masm, ZLoadBarrierStubC2* stub) : ++ _masm(masm), ++ _gp_regs(), ++ _fp_regs(), ++ _vp_regs() { ++ // Figure out what registers to save/restore ++ initialize(stub); ++ ++ // Save registers ++ __ push_reg(_gp_regs, sp); ++ __ push_fp(_fp_regs, sp); ++ __ push_v(_vp_regs, sp); ++ } ++ ++ ~ZSaveLiveRegisters() { ++ // Restore registers ++ __ pop_v(_vp_regs, sp); ++ __ pop_fp(_fp_regs, sp); ++ __ pop_reg(_gp_regs, sp); ++ } ++}; ++ ++class ZSetupArguments { ++private: ++ MacroAssembler* const _masm; ++ const Register _ref; ++ const Address _ref_addr; ++ ++public: ++ ZSetupArguments(MacroAssembler* masm, ZLoadBarrierStubC2* stub) : ++ _masm(masm), ++ _ref(stub->ref()), ++ _ref_addr(stub->ref_addr()) { ++ ++ // Setup arguments ++ if (_ref_addr.base() == noreg) { ++ // No self healing ++ if (_ref != c_rarg0) { ++ __ mv(c_rarg0, _ref); ++ } ++ __ mv(c_rarg1, zr); ++ } else { ++ // Self healing ++ if (_ref == c_rarg0) { ++ // _ref is already at correct place ++ __ la(c_rarg1, _ref_addr); ++ } else if (_ref != c_rarg1) { ++ // _ref is in wrong place, but not in c_rarg1, so fix it first ++ __ la(c_rarg1, _ref_addr); ++ __ mv(c_rarg0, _ref); ++ } else if (_ref_addr.base() != c_rarg0) { ++ assert(_ref == c_rarg1, "Mov ref first, vacating c_rarg0"); ++ __ mv(c_rarg0, _ref); ++ __ la(c_rarg1, _ref_addr); ++ } else { ++ assert(_ref == c_rarg1, "Need to vacate c_rarg1 and _ref_addr is using c_rarg0"); ++ if (_ref_addr.base() == c_rarg0) { ++ __ mv(t1, c_rarg1); ++ __ la(c_rarg1, _ref_addr); ++ __ mv(c_rarg0, t1); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } ++ } ++ } ++ ++ ~ZSetupArguments() { ++ // Transfer result ++ if (_ref != x10) { ++ __ mv(_ref, x10); ++ } ++ } ++}; ++ ++#undef __ ++#define __ masm-> ++ ++void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, ZLoadBarrierStubC2* stub) const { ++ BLOCK_COMMENT("ZLoadBarrierStubC2"); ++ ++ // Stub entry ++ __ bind(*stub->entry()); ++ ++ { ++ ZSaveLiveRegisters save_live_registers(masm, stub); ++ ZSetupArguments setup_arguments(masm, stub); ++ ++ Address target(stub->slow_path()); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ } ++ ++ // Stub exit ++ __ j(*stub->continuation()); ++} ++ ++#undef __ ++ ++#endif // COMPILER2 ++ ++#ifdef COMPILER1 ++#undef __ ++#define __ ce->masm()-> ++ ++void ZBarrierSetAssembler::generate_c1_load_barrier_test(LIR_Assembler* ce, ++ LIR_Opr ref) const { ++ assert_different_registers(xthread, ref->as_register(), t1); ++ __ ld(t1, address_bad_mask_from_thread(xthread)); ++ __ andr(t1, t1, ref->as_register()); ++} ++ ++void ZBarrierSetAssembler::generate_c1_load_barrier_stub(LIR_Assembler* ce, ++ ZLoadBarrierStubC1* stub) const { ++ // Stub entry ++ __ bind(*stub->entry()); ++ ++ Register ref = stub->ref()->as_register(); ++ Register ref_addr = noreg; ++ Register tmp = noreg; ++ ++ if (stub->tmp()->is_valid()) { ++ // Load address into tmp register ++ ce->leal(stub->ref_addr(), stub->tmp()); ++ ref_addr = tmp = stub->tmp()->as_pointer_register(); ++ } else { ++ // Address already in register ++ ref_addr = stub->ref_addr()->as_address_ptr()->base()->as_pointer_register(); ++ } ++ ++ assert_different_registers(ref, ref_addr, noreg); ++ ++ // Save x10 unless it is the result or tmp register ++ // Set up SP to accomodate parameters and maybe x10. ++ if (ref != x10 && tmp != x10) { ++ __ sub(sp, sp, 32); ++ __ sd(x10, Address(sp, 16)); ++ } else { ++ __ sub(sp, sp, 16); ++ } ++ ++ // Setup arguments and call runtime stub ++ ce->store_parameter(ref_addr, 1); ++ ce->store_parameter(ref, 0); ++ ++ __ far_call(stub->runtime_stub()); ++ ++ // Verify result ++ __ verify_oop(x10, "Bad oop"); ++ ++ ++ // Move result into place ++ if (ref != x10) { ++ __ mv(ref, x10); ++ } ++ ++ // Restore x10 unless it is the result or tmp register ++ if (ref != x10 && tmp != x10) { ++ __ ld(x10, Address(sp, 16)); ++ __ add(sp, sp, 32); ++ } else { ++ __ add(sp, sp, 16); ++ } ++ ++ // Stub exit ++ __ j(*stub->continuation()); ++} ++ ++#undef __ ++#define __ sasm-> ++ ++void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler* sasm, ++ DecoratorSet decorators) const { ++ __ prologue("zgc_load_barrier stub", false); ++ ++ __ push_call_clobbered_registers_except(RegSet::of(x10)); ++ ++ // Setup arguments ++ __ load_parameter(0, c_rarg0); ++ __ load_parameter(1, c_rarg1); ++ ++ __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2); ++ ++ __ pop_call_clobbered_registers_except(RegSet::of(x10)); ++ ++ __ epilogue(); ++} ++ ++#undef __ ++#endif // COMPILER1 +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.hpp +@@ -0,0 +1,102 @@ ++/* ++ * Copyright (c) 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_Z_ZBARRIERSETASSEMBLER_RISCV_HPP ++#define CPU_RISCV_GC_Z_ZBARRIERSETASSEMBLER_RISCV_HPP ++ ++#include "code/vmreg.hpp" ++#include "oops/accessDecorators.hpp" ++#ifdef COMPILER2 ++#include "opto/optoreg.hpp" ++#endif // COMPILER2 ++ ++#ifdef COMPILER1 ++class LIR_Assembler; ++class LIR_OprDesc; ++typedef LIR_OprDesc* LIR_Opr; ++class StubAssembler; ++class ZLoadBarrierStubC1; ++#endif // COMPILER1 ++ ++#ifdef COMPILER2 ++class Node; ++class ZLoadBarrierStubC2; ++#endif // COMPILER2 ++ ++class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase { ++public: ++ virtual void load_at(MacroAssembler* masm, ++ DecoratorSet decorators, ++ BasicType type, ++ Register dst, ++ Address src, ++ Register tmp1, ++ Register tmp_thread); ++ ++#ifdef ASSERT ++ virtual void store_at(MacroAssembler* masm, ++ DecoratorSet decorators, ++ BasicType type, ++ Address dst, ++ Register val, ++ Register tmp1, ++ Register tmp2); ++#endif // ASSERT ++ ++ virtual void arraycopy_prologue(MacroAssembler* masm, ++ DecoratorSet decorators, ++ bool is_oop, ++ Register src, ++ Register dst, ++ Register count, ++ RegSet saved_regs); ++ ++ virtual void try_resolve_jobject_in_native(MacroAssembler* masm, ++ Register jni_env, ++ Register robj, ++ Register tmp, ++ Label& slowpath); ++ ++#ifdef COMPILER1 ++ void generate_c1_load_barrier_test(LIR_Assembler* ce, ++ LIR_Opr ref) const; ++ ++ void generate_c1_load_barrier_stub(LIR_Assembler* ce, ++ ZLoadBarrierStubC1* stub) const; ++ ++ void generate_c1_load_barrier_runtime_stub(StubAssembler* sasm, ++ DecoratorSet decorators) const; ++#endif // COMPILER1 ++ ++#ifdef COMPILER2 ++ OptoReg::Name refine_register(const Node* node, ++ OptoReg::Name opto_reg); ++ ++ void generate_c2_load_barrier_stub(MacroAssembler* masm, ++ ZLoadBarrierStubC2* stub) const; ++#endif // COMPILER2 ++}; ++ ++#endif // CPU_RISCV_GC_Z_ZBARRIERSETASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/z/zGlobals_riscv.cpp +@@ -0,0 +1,212 @@ ++/* ++ * Copyright (c) 2017, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "gc/shared/gcLogPrecious.hpp" ++#include "gc/shared/gc_globals.hpp" ++#include "gc/z/zGlobals.hpp" ++#include "runtime/globals.hpp" ++#include "runtime/os.hpp" ++#include "utilities/globalDefinitions.hpp" ++#include "utilities/powerOfTwo.hpp" ++ ++#ifdef LINUX ++#include ++#endif // LINUX ++ ++// ++// The heap can have three different layouts, depending on the max heap size. ++// ++// Address Space & Pointer Layout 1 ++// -------------------------------- ++// ++// +--------------------------------+ 0x00007FFFFFFFFFFF (127TB) ++// . . ++// . . ++// . . ++// +--------------------------------+ 0x0000014000000000 (20TB) ++// | Remapped View | ++// +--------------------------------+ 0x0000010000000000 (16TB) ++// . . ++// +--------------------------------+ 0x00000c0000000000 (12TB) ++// | Marked1 View | ++// +--------------------------------+ 0x0000080000000000 (8TB) ++// | Marked0 View | ++// +--------------------------------+ 0x0000040000000000 (4TB) ++// . . ++// +--------------------------------+ 0x0000000000000000 ++// ++// 6 4 4 4 4 ++// 3 6 5 2 1 0 ++// +--------------------+----+-----------------------------------------------+ ++// |00000000 00000000 00|1111|11 11111111 11111111 11111111 11111111 11111111| ++// +--------------------+----+-----------------------------------------------+ ++// | | | ++// | | * 41-0 Object Offset (42-bits, 4TB address space) ++// | | ++// | * 45-42 Metadata Bits (4-bits) 0001 = Marked0 (Address view 4-8TB) ++// | 0010 = Marked1 (Address view 8-12TB) ++// | 0100 = Remapped (Address view 16-20TB) ++// | 1000 = Finalizable (Address view N/A) ++// | ++// * 63-46 Fixed (18-bits, always zero) ++// ++// ++// Address Space & Pointer Layout 2 ++// -------------------------------- ++// ++// +--------------------------------+ 0x00007FFFFFFFFFFF (127TB) ++// . . ++// . . ++// . . ++// +--------------------------------+ 0x0000280000000000 (40TB) ++// | Remapped View | ++// +--------------------------------+ 0x0000200000000000 (32TB) ++// . . ++// +--------------------------------+ 0x0000180000000000 (24TB) ++// | Marked1 View | ++// +--------------------------------+ 0x0000100000000000 (16TB) ++// | Marked0 View | ++// +--------------------------------+ 0x0000080000000000 (8TB) ++// . . ++// +--------------------------------+ 0x0000000000000000 ++// ++// 6 4 4 4 4 ++// 3 7 6 3 2 0 ++// +------------------+-----+------------------------------------------------+ ++// |00000000 00000000 0|1111|111 11111111 11111111 11111111 11111111 11111111| ++// +-------------------+----+------------------------------------------------+ ++// | | | ++// | | * 42-0 Object Offset (43-bits, 8TB address space) ++// | | ++// | * 46-43 Metadata Bits (4-bits) 0001 = Marked0 (Address view 8-16TB) ++// | 0010 = Marked1 (Address view 16-24TB) ++// | 0100 = Remapped (Address view 32-40TB) ++// | 1000 = Finalizable (Address view N/A) ++// | ++// * 63-47 Fixed (17-bits, always zero) ++// ++// ++// Address Space & Pointer Layout 3 ++// -------------------------------- ++// ++// +--------------------------------+ 0x00007FFFFFFFFFFF (127TB) ++// . . ++// . . ++// . . ++// +--------------------------------+ 0x0000500000000000 (80TB) ++// | Remapped View | ++// +--------------------------------+ 0x0000400000000000 (64TB) ++// . . ++// +--------------------------------+ 0x0000300000000000 (48TB) ++// | Marked1 View | ++// +--------------------------------+ 0x0000200000000000 (32TB) ++// | Marked0 View | ++// +--------------------------------+ 0x0000100000000000 (16TB) ++// . . ++// +--------------------------------+ 0x0000000000000000 ++// ++// 6 4 4 4 4 ++// 3 8 7 4 3 0 ++// +------------------+----+-------------------------------------------------+ ++// |00000000 00000000 |1111|1111 11111111 11111111 11111111 11111111 11111111| ++// +------------------+----+-------------------------------------------------+ ++// | | | ++// | | * 43-0 Object Offset (44-bits, 16TB address space) ++// | | ++// | * 47-44 Metadata Bits (4-bits) 0001 = Marked0 (Address view 16-32TB) ++// | 0010 = Marked1 (Address view 32-48TB) ++// | 0100 = Remapped (Address view 64-80TB) ++// | 1000 = Finalizable (Address view N/A) ++// | ++// * 63-48 Fixed (16-bits, always zero) ++// ++ ++// Default value if probing is not implemented for a certain platform: 128TB ++static const size_t DEFAULT_MAX_ADDRESS_BIT = 47; ++// Minimum value returned, if probing fails: 64GB ++static const size_t MINIMUM_MAX_ADDRESS_BIT = 36; ++ ++static size_t probe_valid_max_address_bit() { ++#ifdef LINUX ++ size_t max_address_bit = 0; ++ const size_t page_size = os::vm_page_size(); ++ for (size_t i = DEFAULT_MAX_ADDRESS_BIT; i > MINIMUM_MAX_ADDRESS_BIT; --i) { ++ const uintptr_t base_addr = ((uintptr_t) 1U) << i; ++ if (msync((void*)base_addr, page_size, MS_ASYNC) == 0) { ++ // msync suceeded, the address is valid, and maybe even already mapped. ++ max_address_bit = i; ++ break; ++ } ++ if (errno != ENOMEM) { ++ // Some error occured. This should never happen, but msync ++ // has some undefined behavior, hence ignore this bit. ++#ifdef ASSERT ++ fatal("Received '%s' while probing the address space for the highest valid bit", os::errno_name(errno)); ++#else // ASSERT ++ log_warning_p(gc)("Received '%s' while probing the address space for the highest valid bit", os::errno_name(errno)); ++#endif // ASSERT ++ continue; ++ } ++ // Since msync failed with ENOMEM, the page might not be mapped. ++ // Try to map it, to see if the address is valid. ++ void* const result_addr = mmap((void*) base_addr, page_size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0); ++ if (result_addr != MAP_FAILED) { ++ munmap(result_addr, page_size); ++ } ++ if ((uintptr_t) result_addr == base_addr) { ++ // address is valid ++ max_address_bit = i; ++ break; ++ } ++ } ++ if (max_address_bit == 0) { ++ // probing failed, allocate a very high page and take that bit as the maximum ++ const uintptr_t high_addr = ((uintptr_t) 1U) << DEFAULT_MAX_ADDRESS_BIT; ++ void* const result_addr = mmap((void*) high_addr, page_size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0); ++ if (result_addr != MAP_FAILED) { ++ max_address_bit = BitsPerSize_t - count_leading_zeros((size_t) result_addr) - 1; ++ munmap(result_addr, page_size); ++ } ++ } ++ log_info_p(gc, init)("Probing address space for the highest valid bit: " SIZE_FORMAT, max_address_bit); ++ return MAX2(max_address_bit, MINIMUM_MAX_ADDRESS_BIT); ++#else // LINUX ++ return DEFAULT_MAX_ADDRESS_BIT; ++#endif // LINUX ++} ++ ++size_t ZPlatformAddressOffsetBits() { ++ const static size_t valid_max_address_offset_bits = probe_valid_max_address_bit() + 1; ++ const size_t max_address_offset_bits = valid_max_address_offset_bits - 3; ++ const size_t min_address_offset_bits = max_address_offset_bits - 2; ++ const size_t address_offset = round_up_power_of_2(MaxHeapSize * ZVirtualToPhysicalRatio); ++ const size_t address_offset_bits = log2i_exact(address_offset); ++ return clamp(address_offset_bits, min_address_offset_bits, max_address_offset_bits); ++} ++ ++size_t ZPlatformAddressMetadataShift() { ++ return ZPlatformAddressOffsetBits(); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/z/zGlobals_riscv.hpp +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2015, 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GC_Z_ZGLOBALS_RISCV_HPP ++#define CPU_RISCV_GC_Z_ZGLOBALS_RISCV_HPP ++ ++const size_t ZPlatformGranuleSizeShift = 21; // 2MB ++const size_t ZPlatformHeapViews = 3; ++const size_t ZPlatformCacheLineSize = 64; ++ ++size_t ZPlatformAddressOffsetBits(); ++size_t ZPlatformAddressMetadataShift(); ++ ++#endif // CPU_RISCV_GC_Z_ZGLOBALS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/gc/z/z_riscv64.ad +@@ -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/z/c2/zBarrierSetC2.hpp" ++#include "gc/z/zThreadLocalData.hpp" ++ ++%} ++ ++source %{ ++ ++static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, int barrier_data) { ++ if (barrier_data == ZLoadBarrierElided) { ++ return; ++ } ++ ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, barrier_data); ++ __ ld(tmp, Address(xthread, ZThreadLocalData::address_bad_mask_offset())); ++ __ andr(tmp, tmp, ref); ++ __ bnez(tmp, *stub->entry(), true /* far */); ++ __ bind(*stub->continuation()); ++} ++ ++static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) { ++ ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, ZLoadBarrierStrong); ++ __ j(*stub->entry()); ++ __ bind(*stub->continuation()); ++} ++ ++%} ++ ++// Load Pointer ++instruct zLoadP(iRegPNoSp dst, memory mem) ++%{ ++ match(Set dst (LoadP mem)); ++ predicate(UseZGC && (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 /* tmp */, barrier_data()); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++instruct zCompareAndSwapP(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 && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong); ++ 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() != ZLoadBarrierElided) { ++ Label good; ++ __ ld(t1, Address(xthread, ZThreadLocalData::address_bad_mask_offset()), t1 /* tmp */); ++ __ andr(t1, t1, t0); ++ __ beqz(t1, good); ++ z_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 zCompareAndSwapPAcq(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 && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong)); ++ 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() != ZLoadBarrierElided) { ++ Label good; ++ __ ld(t1, Address(xthread, ZThreadLocalData::address_bad_mask_offset()), t1 /* tmp */); ++ __ andr(t1, t1, t0); ++ __ beqz(t1, good); ++ z_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 zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{ ++ match(Set res (CompareAndExchangeP mem (Binary oldval newval))); ++ predicate(UseZGC && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong); ++ 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() != ZLoadBarrierElided) { ++ Label good; ++ __ ld(t0, Address(xthread, ZThreadLocalData::address_bad_mask_offset())); ++ __ andr(t0, t0, $res$$Register); ++ __ beqz(t0, good); ++ z_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 zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{ ++ match(Set res (CompareAndExchangeP mem (Binary oldval newval))); ++ predicate(UseZGC && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong); ++ 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() != ZLoadBarrierElided) { ++ Label good; ++ __ ld(t0, Address(xthread, ZThreadLocalData::address_bad_mask_offset())); ++ __ andr(t0, t0, $res$$Register); ++ __ beqz(t0, good); ++ z_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 zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ ++ match(Set prev (GetAndSetP mem newv)); ++ predicate(UseZGC && !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)); ++ z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data()); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ ++ match(Set prev (GetAndSetP mem newv)); ++ predicate(UseZGC && 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)); ++ z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data()); ++ %} ++ ins_pipe(pipe_serial); ++%} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP ++#define CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP ++ ++const int StackAlignmentInBytes = 16; ++ ++// Indicates whether the C calling conventions require that ++// 32-bit integer argument values are extended to 64 bits. ++const bool CCallingConventionRequiresIntsAsLongs = false; ++ ++// RISCV has adopted a multicopy atomic model closely following ++// that of ARMv8. ++#define CPU_MULTI_COPY_ATOMIC ++ ++// To be safe, we deoptimize when we come across an access that needs ++// patching. This is similar to what is done on aarch64. ++#define DEOPTIMIZE_WHEN_PATCHING ++ ++#define SUPPORTS_NATIVE_CX8 ++ ++#define SUPPORT_RESERVED_STACK_AREA ++ ++#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS false ++ ++#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY ++ ++#endif // CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/globals_riscv.hpp +@@ -0,0 +1,101 @@ ++/* ++ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_GLOBALS_RISCV_HPP ++#define CPU_RISCV_GLOBALS_RISCV_HPP ++ ++#include "utilities/globalDefinitions.hpp" ++#include "utilities/macros.hpp" ++ ++// Sets the default values for platform dependent flags used by the runtime system. ++// (see globals.hpp) ++ ++define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks ++define_pd_global(bool, TrapBasedNullChecks, false); ++define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast ++ ++define_pd_global(uintx, CodeCacheSegmentSize, 64 COMPILER1_AND_COMPILER2_PRESENT(+64)); // Tiered compilation has large code-entry alignment. ++define_pd_global(intx, CodeEntryAlignment, 64); ++define_pd_global(intx, OptoLoopAlignment, 16); ++define_pd_global(intx, InlineFrequencyCount, 100); ++ ++#define DEFAULT_STACK_YELLOW_PAGES (2) ++#define DEFAULT_STACK_RED_PAGES (1) ++// Java_java_net_SocketOutputStream_socketWrite0() uses a 64k buffer on the ++// stack if compiled for unix and LP64. To pass stack overflow tests we need ++// 20 shadow pages. ++#define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+5)) ++#define DEFAULT_STACK_RESERVED_PAGES (1) ++ ++#define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES ++#define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES ++#define MIN_STACK_SHADOW_PAGES DEFAULT_STACK_SHADOW_PAGES ++#define MIN_STACK_RESERVED_PAGES (0) ++ ++define_pd_global(intx, StackYellowPages, DEFAULT_STACK_YELLOW_PAGES); ++define_pd_global(intx, StackRedPages, DEFAULT_STACK_RED_PAGES); ++define_pd_global(intx, StackShadowPages, DEFAULT_STACK_SHADOW_PAGES); ++define_pd_global(intx, StackReservedPages, DEFAULT_STACK_RESERVED_PAGES); ++ ++define_pd_global(bool, RewriteBytecodes, true); ++define_pd_global(bool, RewriteFrequentPairs, true); ++ ++define_pd_global(bool, PreserveFramePointer, false); ++ ++define_pd_global(uintx, TypeProfileLevel, 111); ++ ++define_pd_global(bool, CompactStrings, true); ++ ++// Clear short arrays bigger than one word in an arch-specific way ++define_pd_global(intx, InitArrayShortSize, BytesPerLong); ++ ++define_pd_global(intx, InlineSmallCode, 1000); ++ ++#define ARCH_FLAGS(develop, \ ++ product, \ ++ notproduct, \ ++ range, \ ++ constraint) \ ++ \ ++ product(bool, NearCpool, true, \ ++ "constant pool is close to instructions") \ ++ product(intx, BlockZeroingLowLimit, 256, \ ++ "Minimum size in bytes when block zeroing will be used") \ ++ range(1, max_jint) \ ++ product(bool, TraceTraps, false, "Trace all traps the signal handler") \ ++ /* For now we're going to be safe and add the I/O bits to userspace fences. */ \ ++ product(bool, UseConservativeFence, true, \ ++ "Extend i for r and o for w in the pred/succ flags of fence") \ ++ product(bool, AvoidUnalignedAccesses, true, \ ++ "Avoid generating unaligned memory accesses") \ ++ product(bool, UseRVC, true, "Use RVC instructions") \ ++ product(bool, UseRVV, false, EXPERIMENTAL, "Use RVV instructions") \ ++ product(bool, UseZba, false, EXPERIMENTAL, "Use Zba instructions") \ ++ product(bool, UseZbb, false, EXPERIMENTAL, "Use Zbb instructions") \ ++ product(bool, UseZbs, false, EXPERIMENTAL, "Use Zbs instructions") \ ++ product(bool, UseRVVForBigIntegerShiftIntrinsics, true, \ ++ "Use RVV instructions for left/right shift of BigInteger") ++ ++#endif // CPU_RISCV_GLOBALS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/icBuffer_riscv.cpp +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "code/icBuffer.hpp" ++#include "gc/shared/collectedHeap.inline.hpp" ++#include "interpreter/bytecodes.hpp" ++#include "memory/resourceArea.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/oop.inline.hpp" ++ ++int InlineCacheBuffer::ic_stub_code_size() { ++ // 6: auipc + ld + auipc + jalr + address(2 * instruction_size) ++ // 5: auipc + ld + j + address(2 * instruction_size) ++ return (MacroAssembler::far_branches() ? 6 : 5) * NativeInstruction::instruction_size; ++} ++ ++#define __ masm-> ++ ++void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, void* cached_value, address entry_point) { ++ assert_cond(code_begin != NULL && entry_point != NULL); ++ ResourceMark rm; ++ CodeBuffer code(code_begin, ic_stub_code_size()); ++ MacroAssembler* masm = new MacroAssembler(&code); ++ // Note: even though the code contains an embedded value, we do not need reloc info ++ // because ++ // (1) the value is old (i.e., doesn't matter for scavenges) ++ // (2) these ICStubs are removed *before* a GC happens, so the roots disappear ++ ++ address start = __ pc(); ++ Label l; ++ __ ld(t1, l); ++ __ far_jump(ExternalAddress(entry_point)); ++ __ align(wordSize); ++ __ bind(l); ++ __ emit_int64((intptr_t)cached_value); ++ // Only need to invalidate the 1st two instructions - not the whole ic stub ++ ICache::invalidate_range(code_begin, InlineCacheBuffer::ic_stub_code_size()); ++ assert(__ pc() - start == ic_stub_code_size(), "must be"); ++} ++ ++address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) { ++ NativeMovConstReg* move = nativeMovConstReg_at(code_begin); // creation also verifies the object ++ NativeJump* jump = nativeJump_at(move->next_instruction_address()); ++ return jump->jump_destination(); ++} ++ ++ ++void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) { ++ // The word containing the cached value is at the end of this IC buffer ++ uintptr_t *p = (uintptr_t *)(code_begin + ic_stub_code_size() - wordSize); ++ void* o = (void*)*p; ++ return o; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/icache_riscv.cpp +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "runtime/icache.hpp" ++ ++#define __ _masm-> ++ ++static int icache_flush(address addr, int lines, int magic) { ++ // To make a store to instruction memory visible to all RISC-V harts, ++ // the writing hart has to execute a data FENCE before requesting that ++ // all remote RISC-V harts execute a FENCE.I. ++ // ++ // No sush assurance is defined at the interface level of the builtin ++ // method, and so we should make sure it works. ++ __asm__ volatile("fence rw, rw" : : : "memory"); ++ ++ __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size)); ++ return magic; ++} ++ ++void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) { ++ address start = (address)icache_flush; ++ *flush_icache_stub = (ICache::flush_icache_stub_t)start; ++ ++ // ICache::invalidate_range() contains explicit condition that the first ++ // call is invoked on the generated icache flush stub code range. ++ ICache::invalidate_range(start, 0); ++ ++ { ++ StubCodeMark mark(this, "ICache", "fake_stub_for_inlined_icache_flush"); ++ __ ret(); ++ } ++} ++ ++#undef __ +--- /dev/null ++++ b/src/hotspot/cpu/riscv/icache_riscv.hpp +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 1997, 2020, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_ICACHE_RISCV_HPP ++#define CPU_RISCV_ICACHE_RISCV_HPP ++ ++// Interface for updating the instruction cache. Whenever the VM ++// modifies code, part of the processor instruction cache potentially ++// has to be flushed. ++ ++class ICache : public AbstractICache { ++public: ++ enum { ++ stub_size = 16, // Size of the icache flush stub in bytes ++ line_size = BytesPerWord, // conservative ++ log2_line_size = LogBytesPerWord // log2(line_size) ++ }; ++}; ++ ++#endif // CPU_RISCV_ICACHE_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +@@ -0,0 +1,1950 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "gc/shared/barrierSet.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "interp_masm_riscv.hpp" ++#include "interpreter/interpreter.hpp" ++#include "interpreter/interpreterRuntime.hpp" ++#include "logging/log.hpp" ++#include "oops/arrayOop.hpp" ++#include "oops/markWord.hpp" ++#include "oops/method.hpp" ++#include "oops/methodData.hpp" ++#include "prims/jvmtiExport.hpp" ++#include "prims/jvmtiThreadState.hpp" ++#include "runtime/basicLock.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/safepointMechanism.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/thread.inline.hpp" ++#include "utilities/powerOfTwo.hpp" ++ ++void InterpreterMacroAssembler::narrow(Register result) { ++ // Get method->_constMethod->_result_type ++ ld(t0, Address(fp, frame::interpreter_frame_method_offset * wordSize)); ++ ld(t0, Address(t0, Method::const_offset())); ++ lbu(t0, Address(t0, ConstMethod::result_type_offset())); ++ ++ Label done, notBool, notByte, notChar; ++ ++ // common case first ++ mv(t1, T_INT); ++ beq(t0, t1, done); ++ ++ // mask integer result to narrower return type. ++ mv(t1, T_BOOLEAN); ++ bne(t0, t1, notBool); ++ ++ andi(result, result, 0x1); ++ j(done); ++ ++ bind(notBool); ++ mv(t1, T_BYTE); ++ bne(t0, t1, notByte); ++ sign_extend(result, result, 8); ++ j(done); ++ ++ bind(notByte); ++ mv(t1, T_CHAR); ++ bne(t0, t1, notChar); ++ zero_extend(result, result, 16); ++ j(done); ++ ++ bind(notChar); ++ sign_extend(result, result, 16); ++ ++ bind(done); ++ sign_extend(result, result, 32); ++} ++ ++void InterpreterMacroAssembler::jump_to_entry(address entry) { ++ assert(entry != NULL, "Entry must have been generated by now"); ++ j(entry); ++} ++ ++void InterpreterMacroAssembler::check_and_handle_popframe(Register java_thread) { ++ if (JvmtiExport::can_pop_frame()) { ++ Label L; ++ // Initiate popframe handling only if it is not already being ++ // processed. If the flag has the popframe_processing bit set, ++ // it means that this code is called *during* popframe handling - we ++ // don't want to reenter. ++ // This method is only called just after the call into the vm in ++ // call_VM_base, so the arg registers are available. ++ lwu(t1, Address(xthread, JavaThread::popframe_condition_offset())); ++ test_bit(t0, t1, exact_log2(JavaThread::popframe_pending_bit)); ++ beqz(t0, L); ++ test_bit(t0, t1, exact_log2(JavaThread::popframe_processing_bit)); ++ bnez(t0, L); ++ // Call Interpreter::remove_activation_preserving_args_entry() to get the ++ // address of the same-named entrypoint in the generated interpreter code. ++ call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry)); ++ jr(x10); ++ bind(L); ++ } ++} ++ ++ ++void InterpreterMacroAssembler::load_earlyret_value(TosState state) { ++ ld(x12, Address(xthread, JavaThread::jvmti_thread_state_offset())); ++ const Address tos_addr(x12, JvmtiThreadState::earlyret_tos_offset()); ++ const Address oop_addr(x12, JvmtiThreadState::earlyret_oop_offset()); ++ const Address val_addr(x12, JvmtiThreadState::earlyret_value_offset()); ++ switch (state) { ++ case atos: ++ ld(x10, oop_addr); ++ sd(zr, oop_addr); ++ verify_oop(x10); ++ break; ++ case ltos: ++ ld(x10, val_addr); ++ break; ++ case btos: // fall through ++ case ztos: // fall through ++ case ctos: // fall through ++ case stos: // fall through ++ case itos: ++ lwu(x10, val_addr); ++ break; ++ case ftos: ++ flw(f10, val_addr); ++ break; ++ case dtos: ++ fld(f10, val_addr); ++ break; ++ case vtos: ++ /* nothing to do */ ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ // Clean up tos value in the thread object ++ mv(t0, (int)ilgl); ++ sw(t0, tos_addr); ++ sw(zr, val_addr); ++} ++ ++ ++void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) { ++ if (JvmtiExport::can_force_early_return()) { ++ Label L; ++ ld(t0, Address(xthread, JavaThread::jvmti_thread_state_offset())); ++ beqz(t0, L); // if [thread->jvmti_thread_state() == NULL] then exit ++ ++ // Initiate earlyret handling only if it is not already being processed. ++ // If the flag has the earlyret_processing bit set, it means that this code ++ // is called *during* earlyret handling - we don't want to reenter. ++ lwu(t0, Address(t0, JvmtiThreadState::earlyret_state_offset())); ++ mv(t1, JvmtiThreadState::earlyret_pending); ++ bne(t0, t1, L); ++ ++ // Call Interpreter::remove_activation_early_entry() to get the address of the ++ // same-named entrypoint in the generated interpreter code. ++ ld(t0, Address(xthread, JavaThread::jvmti_thread_state_offset())); ++ lwu(t0, Address(t0, JvmtiThreadState::earlyret_tos_offset())); ++ call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), t0); ++ jr(x10); ++ bind(L); ++ } ++} ++ ++void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) { ++ assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode"); ++ lhu(reg, Address(xbcp, bcp_offset)); ++ revb_h(reg, reg); ++} ++ ++void InterpreterMacroAssembler::get_dispatch() { ++ ExternalAddress target((address)Interpreter::dispatch_table()); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(xdispatch, target, offset); ++ addi(xdispatch, xdispatch, offset); ++ }); ++} ++ ++void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index, ++ int bcp_offset, ++ size_t index_size) { ++ assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); ++ if (index_size == sizeof(u2)) { ++ load_unsigned_short(index, Address(xbcp, bcp_offset)); ++ } else if (index_size == sizeof(u4)) { ++ lwu(index, Address(xbcp, bcp_offset)); ++ // Check if the secondary index definition is still ~x, otherwise ++ // we have to change the following assembler code to calculate the ++ // plain index. ++ assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line"); ++ xori(index, index, -1); ++ sign_extend(index, index, 32); ++ } else if (index_size == sizeof(u1)) { ++ load_unsigned_byte(index, Address(xbcp, bcp_offset)); ++ } else { ++ ShouldNotReachHere(); ++ } ++} ++ ++// Return ++// Rindex: index into constant pool ++// Rcache: address of cache entry - ConstantPoolCache::base_offset() ++// ++// A caller must add ConstantPoolCache::base_offset() to Rcache to get ++// the true address of the cache entry. ++// ++void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, ++ Register index, ++ int bcp_offset, ++ size_t index_size) { ++ assert_different_registers(cache, index); ++ assert_different_registers(cache, xcpool); ++ get_cache_index_at_bcp(index, bcp_offset, index_size); ++ assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); ++ // Convert from field index to ConstantPoolCacheEntry ++ // riscv already has the cache in xcpool so there is no need to ++ // install it in cache. Instead we pre-add the indexed offset to ++ // xcpool and return it in cache. All clients of this method need to ++ // be modified accordingly. ++ shadd(cache, index, xcpool, cache, 5); ++} ++ ++ ++void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache, ++ Register index, ++ Register bytecode, ++ int byte_no, ++ int bcp_offset, ++ size_t index_size) { ++ get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size); ++ // We use a 32-bit load here since the layout of 64-bit words on ++ // little-endian machines allow us that. ++ // n.b. unlike x86 cache already includes the index offset ++ la(bytecode, Address(cache, ++ ConstantPoolCache::base_offset() + ++ ConstantPoolCacheEntry::indices_offset())); ++ membar(MacroAssembler::AnyAny); ++ lwu(bytecode, bytecode); ++ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ const int shift_count = (1 + byte_no) * BitsPerByte; ++ slli(bytecode, bytecode, XLEN - (shift_count + BitsPerByte)); ++ srli(bytecode, bytecode, XLEN - BitsPerByte); ++} ++ ++void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, ++ Register tmp, ++ int bcp_offset, ++ size_t index_size) { ++ assert_different_registers(cache, tmp); ++ get_cache_index_at_bcp(tmp, bcp_offset, index_size); ++ assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); ++ // Convert from field index to ConstantPoolCacheEntry index ++ // and from word offset to byte offset ++ assert(exact_log2(in_bytes(ConstantPoolCacheEntry::size_in_bytes())) == 2 + LogBytesPerWord, ++ "else change next line"); ++ ld(cache, Address(fp, frame::interpreter_frame_cache_offset * wordSize)); ++ // skip past the header ++ add(cache, cache, in_bytes(ConstantPoolCache::base_offset())); ++ // construct pointer to cache entry ++ shadd(cache, tmp, cache, tmp, 2 + LogBytesPerWord); ++} ++ ++// Load object from cpool->resolved_references(index) ++void InterpreterMacroAssembler::load_resolved_reference_at_index( ++ Register result, Register index, Register tmp) { ++ assert_different_registers(result, index); ++ ++ get_constant_pool(result); ++ // Load pointer for resolved_references[] objArray ++ ld(result, Address(result, ConstantPool::cache_offset_in_bytes())); ++ ld(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes())); ++ resolve_oop_handle(result, tmp); ++ // Add in the index ++ addi(index, index, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); ++ shadd(result, index, result, index, LogBytesPerHeapOop); ++ load_heap_oop(result, Address(result, 0)); ++} ++ ++void InterpreterMacroAssembler::load_resolved_klass_at_offset( ++ Register cpool, Register index, Register klass, Register temp) { ++ shadd(temp, index, cpool, temp, LogBytesPerWord); ++ lhu(temp, Address(temp, sizeof(ConstantPool))); // temp = resolved_klass_index ++ ld(klass, Address(cpool, ConstantPool::resolved_klasses_offset_in_bytes())); // klass = cpool->_resolved_klasses ++ shadd(klass, temp, klass, temp, LogBytesPerWord); ++ ld(klass, Address(klass, Array::base_offset_in_bytes())); ++} ++ ++void InterpreterMacroAssembler::load_resolved_method_at_index(int byte_no, ++ Register method, ++ Register cache) { ++ const int method_offset = in_bytes( ++ ConstantPoolCache::base_offset() + ++ ((byte_no == TemplateTable::f2_byte) ++ ? ConstantPoolCacheEntry::f2_offset() ++ : ConstantPoolCacheEntry::f1_offset())); ++ ++ ld(method, Address(cache, method_offset)); // get f1 Method* ++} ++ ++// Generate a subtype check: branch to ok_is_subtype if sub_klass is a ++// subtype of super_klass. ++// ++// Args: ++// x10: superklass ++// Rsub_klass: subklass ++// ++// Kills: ++// x12, x15 ++void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, ++ Label& ok_is_subtype) { ++ assert(Rsub_klass != x10, "x10 holds superklass"); ++ assert(Rsub_klass != x12, "x12 holds 2ndary super array length"); ++ assert(Rsub_klass != x15, "x15 holds 2ndary super array scan ptr"); ++ ++ // Profile the not-null value's klass. ++ profile_typecheck(x12, Rsub_klass, x15); // blows x12, reloads x15 ++ ++ // Do the check. ++ check_klass_subtype(Rsub_klass, x10, x12, ok_is_subtype); // blows x12 ++ ++ // Profile the failure of the check. ++ profile_typecheck_failed(x12); // blows x12 ++} ++ ++// Java Expression Stack ++ ++void InterpreterMacroAssembler::pop_ptr(Register r) { ++ ld(r, Address(esp, 0)); ++ addi(esp, esp, wordSize); ++} ++ ++void InterpreterMacroAssembler::pop_i(Register r) { ++ lw(r, Address(esp, 0)); // lw do signed extended ++ addi(esp, esp, wordSize); ++} ++ ++void InterpreterMacroAssembler::pop_l(Register r) { ++ ld(r, Address(esp, 0)); ++ addi(esp, esp, 2 * Interpreter::stackElementSize); ++} ++ ++void InterpreterMacroAssembler::push_ptr(Register r) { ++ addi(esp, esp, -wordSize); ++ sd(r, Address(esp, 0)); ++} ++ ++void InterpreterMacroAssembler::push_i(Register r) { ++ addi(esp, esp, -wordSize); ++ sign_extend(r, r, 32); ++ sd(r, Address(esp, 0)); ++} ++ ++void InterpreterMacroAssembler::push_l(Register r) { ++ addi(esp, esp, -2 * wordSize); ++ sd(zr, Address(esp, wordSize)); ++ sd(r, Address(esp)); ++} ++ ++void InterpreterMacroAssembler::pop_f(FloatRegister r) { ++ flw(r, Address(esp, 0)); ++ addi(esp, esp, wordSize); ++} ++ ++void InterpreterMacroAssembler::pop_d(FloatRegister r) { ++ fld(r, Address(esp, 0)); ++ addi(esp, esp, 2 * Interpreter::stackElementSize); ++} ++ ++void InterpreterMacroAssembler::push_f(FloatRegister r) { ++ addi(esp, esp, -wordSize); ++ fsw(r, Address(esp, 0)); ++} ++ ++void InterpreterMacroAssembler::push_d(FloatRegister r) { ++ addi(esp, esp, -2 * wordSize); ++ fsd(r, Address(esp, 0)); ++} ++ ++void InterpreterMacroAssembler::pop(TosState state) { ++ switch (state) { ++ case atos: ++ pop_ptr(); ++ verify_oop(x10); ++ break; ++ case btos: // fall through ++ case ztos: // fall through ++ case ctos: // fall through ++ case stos: // fall through ++ case itos: ++ pop_i(); ++ break; ++ case ltos: ++ pop_l(); ++ break; ++ case ftos: ++ pop_f(); ++ break; ++ case dtos: ++ pop_d(); ++ break; ++ case vtos: ++ /* nothing to do */ ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void InterpreterMacroAssembler::push(TosState state) { ++ switch (state) { ++ case atos: ++ verify_oop(x10); ++ push_ptr(); ++ break; ++ case btos: // fall through ++ case ztos: // fall through ++ case ctos: // fall through ++ case stos: // fall through ++ case itos: ++ push_i(); ++ break; ++ case ltos: ++ push_l(); ++ break; ++ case ftos: ++ push_f(); ++ break; ++ case dtos: ++ push_d(); ++ break; ++ case vtos: ++ /* nothing to do */ ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++// Helpers for swap and dup ++void InterpreterMacroAssembler::load_ptr(int n, Register val) { ++ ld(val, Address(esp, Interpreter::expr_offset_in_bytes(n))); ++} ++ ++void InterpreterMacroAssembler::store_ptr(int n, Register val) { ++ sd(val, Address(esp, Interpreter::expr_offset_in_bytes(n))); ++} ++ ++void InterpreterMacroAssembler::load_float(Address src) { ++ flw(f10, src); ++} ++ ++void InterpreterMacroAssembler::load_double(Address src) { ++ fld(f10, src); ++} ++ ++void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() { ++ // set sender sp ++ mv(x30, sp); ++ // record last_sp ++ sd(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++} ++ ++// Jump to from_interpreted entry of a call unless single stepping is possible ++// in this thread in which case we must call the i2i entry ++void InterpreterMacroAssembler::jump_from_interpreted(Register method) { ++ prepare_to_jump_from_interpreted(); ++ if (JvmtiExport::can_post_interpreter_events()) { ++ Label run_compiled_code; ++ // JVMTI events, such as single-stepping, are implemented partly by avoiding running ++ // compiled code in threads for which the event is enabled. Check here for ++ // interp_only_mode if these events CAN be enabled. ++ lwu(t0, Address(xthread, JavaThread::interp_only_mode_offset())); ++ beqz(t0, run_compiled_code); ++ ld(t0, Address(method, Method::interpreter_entry_offset())); ++ jr(t0); ++ bind(run_compiled_code); ++ } ++ ++ ld(t0, Address(method, Method::from_interpreted_offset())); ++ jr(t0); ++} ++ ++// The following two routines provide a hook so that an implementation ++// can schedule the dispatch in two parts. amd64 does not do this. ++void InterpreterMacroAssembler::dispatch_prolog(TosState state, int step) { ++} ++ ++void InterpreterMacroAssembler::dispatch_epilog(TosState state, int step) { ++ dispatch_next(state, step); ++} ++ ++void InterpreterMacroAssembler::dispatch_base(TosState state, ++ address* table, ++ bool verifyoop, ++ bool generate_poll, ++ Register Rs) { ++ // Pay attention to the argument Rs, which is acquiesce in t0. ++ if (VerifyActivationFrameSize) { ++ Unimplemented(); ++ } ++ if (verifyoop && state == atos) { ++ verify_oop(x10); ++ } ++ ++ Label safepoint; ++ address* const safepoint_table = Interpreter::safept_table(state); ++ bool needs_thread_local_poll = generate_poll && table != safepoint_table; ++ ++ if (needs_thread_local_poll) { ++ NOT_PRODUCT(block_comment("Thread-local Safepoint poll")); ++ ld(t1, Address(xthread, JavaThread::polling_word_offset())); ++ test_bit(t1, t1, exact_log2(SafepointMechanism::poll_bit())); ++ bnez(t1, safepoint); ++ } ++ if (table == Interpreter::dispatch_table(state)) { ++ mv(t1, Interpreter::distance_from_dispatch_table(state)); ++ add(t1, Rs, t1); ++ shadd(t1, t1, xdispatch, t1, 3); ++ } else { ++ mv(t1, (address)table); ++ shadd(t1, Rs, t1, Rs, 3); ++ } ++ ld(t1, Address(t1)); ++ jr(t1); ++ ++ if (needs_thread_local_poll) { ++ bind(safepoint); ++ la(t1, ExternalAddress((address)safepoint_table)); ++ shadd(t1, Rs, t1, Rs, 3); ++ ld(t1, Address(t1)); ++ jr(t1); ++ } ++} ++ ++void InterpreterMacroAssembler::dispatch_only(TosState state, bool generate_poll, Register Rs) { ++ dispatch_base(state, Interpreter::dispatch_table(state), true, generate_poll, Rs); ++} ++ ++void InterpreterMacroAssembler::dispatch_only_normal(TosState state, Register Rs) { ++ dispatch_base(state, Interpreter::normal_table(state), Rs); ++} ++ ++void InterpreterMacroAssembler::dispatch_only_noverify(TosState state, Register Rs) { ++ dispatch_base(state, Interpreter::normal_table(state), false, Rs); ++} ++ ++void InterpreterMacroAssembler::dispatch_next(TosState state, int step, bool generate_poll) { ++ // load next bytecode ++ load_unsigned_byte(t0, Address(xbcp, step)); ++ add(xbcp, xbcp, step); ++ dispatch_base(state, Interpreter::dispatch_table(state), true, generate_poll); ++} ++ ++void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) { ++ // load current bytecode ++ lbu(t0, Address(xbcp, 0)); ++ dispatch_base(state, table); ++} ++ ++// remove activation ++// ++// Apply stack watermark barrier. ++// Unlock the receiver if this is a synchronized method. ++// Unlock any Java monitors from syncronized blocks. ++// Remove the activation from the stack. ++// ++// If there are locked Java monitors ++// If throw_monitor_exception ++// throws IllegalMonitorStateException ++// Else if install_monitor_exception ++// installs IllegalMonitorStateException ++// Else ++// no error processing ++void InterpreterMacroAssembler::remove_activation( ++ TosState state, ++ bool throw_monitor_exception, ++ bool install_monitor_exception, ++ bool notify_jvmdi) { ++ // Note: Registers x13 may be in use for the ++ // result check if synchronized method ++ Label unlocked, unlock, no_unlock; ++ ++ // The below poll is for the stack watermark barrier. It allows fixing up frames lazily, ++ // that would normally not be safe to use. Such bad returns into unsafe territory of ++ // the stack, will call InterpreterRuntime::at_unwind. ++ Label slow_path; ++ Label fast_path; ++ safepoint_poll(slow_path, true /* at_return */, false /* acquire */, false /* in_nmethod */); ++ j(fast_path); ++ ++ bind(slow_path); ++ push(state); ++ set_last_Java_frame(esp, fp, (address)pc(), t0); ++ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::at_unwind), xthread); ++ reset_last_Java_frame(true); ++ pop(state); ++ ++ bind(fast_path); ++ ++ // get the value of _do_not_unlock_if_synchronized into x13 ++ const Address do_not_unlock_if_synchronized(xthread, ++ in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); ++ lbu(x13, do_not_unlock_if_synchronized); ++ sb(zr, do_not_unlock_if_synchronized); // reset the flag ++ ++ // get method access flags ++ ld(x11, Address(fp, frame::interpreter_frame_method_offset * wordSize)); ++ ld(x12, Address(x11, Method::access_flags_offset())); ++ test_bit(t0, x12, exact_log2(JVM_ACC_SYNCHRONIZED)); ++ beqz(t0, unlocked); ++ ++ // Don't unlock anything if the _do_not_unlock_if_synchronized flag ++ // is set. ++ bnez(x13, no_unlock); ++ ++ // unlock monitor ++ push(state); // save result ++ ++ // BasicObjectLock will be first in list, since this is a ++ // synchronized method. However, need to check that the object has ++ // not been unlocked by an explicit monitorexit bytecode. ++ const Address monitor(fp, frame::interpreter_frame_initial_sp_offset * ++ wordSize - (int) sizeof(BasicObjectLock)); ++ // We use c_rarg1 so that if we go slow path it will be the correct ++ // register for unlock_object to pass to VM directly ++ la(c_rarg1, monitor); // address of first monitor ++ ++ ld(x10, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); ++ bnez(x10, unlock); ++ ++ pop(state); ++ if (throw_monitor_exception) { ++ // Entry already unlocked, need to throw exception ++ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_illegal_monitor_state_exception)); ++ should_not_reach_here(); ++ } else { ++ // Monitor already unlocked during a stack unroll. If requested, ++ // install an illegal_monitor_state_exception. Continue with ++ // stack unrolling. ++ if (install_monitor_exception) { ++ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::new_illegal_monitor_state_exception)); ++ } ++ j(unlocked); ++ } ++ ++ bind(unlock); ++ unlock_object(c_rarg1); ++ pop(state); ++ ++ // Check that for block-structured locking (i.e., that all locked ++ // objects has been unlocked) ++ bind(unlocked); ++ ++ // x10: Might contain return value ++ ++ // Check that all monitors are unlocked ++ { ++ Label loop, exception, entry, restart; ++ const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; ++ const Address monitor_block_top( ++ fp, frame::interpreter_frame_monitor_block_top_offset * wordSize); ++ const Address monitor_block_bot( ++ fp, frame::interpreter_frame_initial_sp_offset * wordSize); ++ ++ bind(restart); ++ // We use c_rarg1 so that if we go slow path it will be the correct ++ // register for unlock_object to pass to VM directly ++ ld(c_rarg1, monitor_block_top); // points to current entry, starting ++ // with top-most entry ++ la(x9, monitor_block_bot); // points to word before bottom of ++ // monitor block ++ ++ j(entry); ++ ++ // Entry already locked, need to throw exception ++ bind(exception); ++ ++ if (throw_monitor_exception) { ++ // Throw exception ++ MacroAssembler::call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime:: ++ throw_illegal_monitor_state_exception)); ++ ++ should_not_reach_here(); ++ } else { ++ // Stack unrolling. Unlock object and install illegal_monitor_exception. ++ // Unlock does not block, so don't have to worry about the frame. ++ // We don't have to preserve c_rarg1 since we are going to throw an exception. ++ ++ push(state); ++ unlock_object(c_rarg1); ++ pop(state); ++ ++ if (install_monitor_exception) { ++ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime:: ++ new_illegal_monitor_state_exception)); ++ } ++ ++ j(restart); ++ } ++ ++ bind(loop); ++ // check if current entry is used ++ add(t0, c_rarg1, BasicObjectLock::obj_offset_in_bytes()); ++ ld(t0, Address(t0, 0)); ++ bnez(t0, exception); ++ ++ add(c_rarg1, c_rarg1, entry_size); // otherwise advance to next entry ++ bind(entry); ++ bne(c_rarg1, x9, loop); // check if bottom reached if not at bottom then check this entry ++ } ++ ++ bind(no_unlock); ++ ++ // jvmti support ++ if (notify_jvmdi) { ++ notify_method_exit(state, NotifyJVMTI); // preserve TOSCA ++ ++ } else { ++ notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA ++ } ++ ++ // remove activation ++ // get sender esp ++ ld(t1, ++ Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize)); ++ if (StackReservedPages > 0) { ++ // testing if reserved zone needs to be re-enabled ++ Label no_reserved_zone_enabling; ++ ++ ld(t0, Address(xthread, JavaThread::reserved_stack_activation_offset())); ++ ble(t1, t0, no_reserved_zone_enabling); ++ ++ call_VM_leaf( ++ CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), xthread); ++ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_delayed_StackOverflowError)); ++ should_not_reach_here(); ++ ++ bind(no_reserved_zone_enabling); ++ } ++ ++ // restore sender esp ++ mv(esp, t1); ++ ++ // remove frame anchor ++ leave(); ++ // If we're returning to interpreted code we will shortly be ++ // adjusting SP to allow some space for ESP. If we're returning to ++ // compiled code the saved sender SP was saved in sender_sp, so this ++ // restores it. ++ andi(sp, esp, -16); ++} ++ ++// Lock object ++// ++// Args: ++// c_rarg1: BasicObjectLock to be used for locking ++// ++// Kills: ++// x10 ++// c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs) ++// t0, t1 (temp regs) ++void InterpreterMacroAssembler::lock_object(Register lock_reg) ++{ ++ assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1"); ++ if (UseHeavyMonitors) { ++ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), ++ lock_reg); ++ } else { ++ Label done; ++ ++ const Register swap_reg = x10; ++ const Register tmp = c_rarg2; ++ const Register obj_reg = c_rarg3; // Will contain the oop ++ ++ const int obj_offset = BasicObjectLock::obj_offset_in_bytes(); ++ const int lock_offset = BasicObjectLock::lock_offset_in_bytes (); ++ const int mark_offset = lock_offset + ++ BasicLock::displaced_header_offset_in_bytes(); ++ ++ Label slow_case; ++ ++ // Load object pointer into obj_reg c_rarg3 ++ ld(obj_reg, Address(lock_reg, obj_offset)); ++ ++ if (DiagnoseSyncOnValueBasedClasses != 0) { ++ load_klass(tmp, obj_reg); ++ lwu(tmp, Address(tmp, Klass::access_flags_offset())); ++ test_bit(tmp, tmp, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); ++ bnez(tmp, slow_case); ++ } ++ ++ if (UseBiasedLocking) { ++ biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp, false, done, &slow_case); ++ } ++ ++ // Load (object->mark() | 1) into swap_reg ++ ld(t0, Address(obj_reg, oopDesc::mark_offset_in_bytes())); ++ ori(swap_reg, t0, 1); ++ ++ // Save (object->mark() | 1) into BasicLock's displaced header ++ sd(swap_reg, Address(lock_reg, mark_offset)); ++ ++ assert(lock_offset == 0, ++ "displached header must be first word in BasicObjectLock"); ++ ++ cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, t0, done, /*fallthrough*/NULL); ++ ++ // Test if the oopMark is an obvious stack pointer, i.e., ++ // 1) (mark & 7) == 0, and ++ // 2) sp <= mark < mark + os::pagesize() ++ // ++ // These 3 tests can be done by evaluating the following ++ // expression: ((mark - sp) & (7 - os::vm_page_size())), ++ // assuming both stack pointer and pagesize have their ++ // least significant 3 bits clear. ++ // NOTE: the oopMark is in swap_reg x10 as the result of cmpxchg ++ sub(swap_reg, swap_reg, sp); ++ mv(t0, (int64_t)(7 - os::vm_page_size())); ++ andr(swap_reg, swap_reg, t0); ++ ++ // Save the test result, for recursive case, the result is zero ++ sd(swap_reg, Address(lock_reg, mark_offset)); ++ beqz(swap_reg, done); ++ ++ bind(slow_case); ++ ++ // Call the runtime routine for slow case ++ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), ++ lock_reg); ++ ++ bind(done); ++ } ++} ++ ++ ++// Unlocks an object. Used in monitorexit bytecode and ++// remove_activation. Throws an IllegalMonitorException if object is ++// not locked by current thread. ++// ++// Args: ++// c_rarg1: BasicObjectLock for lock ++// ++// Kills: ++// x10 ++// c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs) ++// t0, t1 (temp regs) ++void InterpreterMacroAssembler::unlock_object(Register lock_reg) ++{ ++ assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1"); ++ ++ if (UseHeavyMonitors) { ++ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); ++ } else { ++ Label done; ++ ++ 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 ++ ++ save_bcp(); // Save in case of exception ++ ++ // Convert from BasicObjectLock structure to object and BasicLock ++ // structure Store the BasicLock address into x10 ++ la(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); ++ ++ // Load oop into obj_reg(c_rarg3) ++ ld(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); ++ ++ // Free entry ++ sd(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); ++ ++ if (UseBiasedLocking) { ++ biased_locking_exit(obj_reg, header_reg, done); ++ } ++ ++ // Load the old header from BasicLock structure ++ ld(header_reg, Address(swap_reg, ++ BasicLock::displaced_header_offset_in_bytes())); ++ ++ // Test for recursion ++ beqz(header_reg, done); ++ ++ // Atomic swap back the old header ++ cmpxchg_obj_header(swap_reg, header_reg, obj_reg, t0, done, /*fallthrough*/NULL); ++ ++ // Call the runtime routine for slow case. ++ sd(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj ++ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); ++ ++ bind(done); ++ ++ restore_bcp(); ++ } ++} ++ ++ ++void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, ++ Label& zero_continue) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ ld(mdp, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); ++ beqz(mdp, zero_continue); ++} ++ ++// Set the method data pointer for the current bcp. ++void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ Label set_mdp; ++ push_reg(RegSet::of(x10, x11), sp); // save x10, x11 ++ ++ // Test MDO to avoid the call if it is NULL. ++ ld(x10, Address(xmethod, in_bytes(Method::method_data_offset()))); ++ beqz(x10, set_mdp); ++ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), xmethod, xbcp); ++ // x10: mdi ++ // mdo is guaranteed to be non-zero here, we checked for it before the call. ++ ld(x11, Address(xmethod, in_bytes(Method::method_data_offset()))); ++ la(x11, Address(x11, in_bytes(MethodData::data_offset()))); ++ add(x10, x11, x10); ++ sd(x10, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); ++ bind(set_mdp); ++ pop_reg(RegSet::of(x10, x11), sp); ++} ++ ++void InterpreterMacroAssembler::verify_method_data_pointer() { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++#ifdef ASSERT ++ Label verify_continue; ++ add(sp, sp, -4 * wordSize); ++ sd(x10, Address(sp, 0)); ++ sd(x11, Address(sp, wordSize)); ++ sd(x12, Address(sp, 2 * wordSize)); ++ sd(x13, Address(sp, 3 * wordSize)); ++ test_method_data_pointer(x13, verify_continue); // If mdp is zero, continue ++ get_method(x11); ++ ++ // If the mdp is valid, it will point to a DataLayout header which is ++ // consistent with the bcp. The converse is highly probable also. ++ lh(x12, Address(x13, in_bytes(DataLayout::bci_offset()))); ++ ld(t0, Address(x11, Method::const_offset())); ++ add(x12, x12, t0); ++ la(x12, Address(x12, ConstMethod::codes_offset())); ++ beq(x12, xbcp, verify_continue); ++ // x10: method ++ // xbcp: bcp // xbcp == 22 ++ // x13: mdp ++ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), ++ x11, xbcp, x13); ++ bind(verify_continue); ++ ld(x10, Address(sp, 0)); ++ ld(x11, Address(sp, wordSize)); ++ ld(x12, Address(sp, 2 * wordSize)); ++ ld(x13, Address(sp, 3 * wordSize)); ++ add(sp, sp, 4 * wordSize); ++#endif // ASSERT ++} ++ ++ ++void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, ++ int constant, ++ Register value) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ Address data(mdp_in, constant); ++ sd(value, data); ++} ++ ++ ++void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, ++ int constant, ++ bool decrement) { ++ increment_mdp_data_at(mdp_in, noreg, constant, decrement); ++} ++ ++void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, ++ Register reg, ++ int constant, ++ bool decrement) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ // %%% this does 64bit counters at best it is wasting space ++ // at worst it is a rare bug when counters overflow ++ ++ assert_different_registers(t1, t0, mdp_in, reg); ++ ++ Address addr1(mdp_in, constant); ++ Address addr2(t1, 0); ++ Address &addr = addr1; ++ if (reg != noreg) { ++ la(t1, addr1); ++ add(t1, t1, reg); ++ addr = addr2; ++ } ++ ++ if (decrement) { ++ ld(t0, addr); ++ addi(t0, t0, -DataLayout::counter_increment); ++ Label L; ++ bltz(t0, L); // skip store if counter underflow ++ sd(t0, addr); ++ bind(L); ++ } else { ++ assert(DataLayout::counter_increment == 1, ++ "flow-free idiom only works with 1"); ++ ld(t0, addr); ++ addi(t0, t0, DataLayout::counter_increment); ++ Label L; ++ blez(t0, L); // skip store if counter overflow ++ sd(t0, addr); ++ bind(L); ++ } ++} ++ ++void InterpreterMacroAssembler::set_mdp_flag_at(Register mdp_in, ++ int flag_byte_constant) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ int flags_offset = in_bytes(DataLayout::flags_offset()); ++ // Set the flag ++ lbu(t1, Address(mdp_in, flags_offset)); ++ ori(t1, t1, flag_byte_constant); ++ sb(t1, Address(mdp_in, flags_offset)); ++} ++ ++ ++void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in, ++ int offset, ++ Register value, ++ Register test_value_out, ++ Label& not_equal_continue) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ if (test_value_out == noreg) { ++ ld(t1, Address(mdp_in, offset)); ++ bne(value, t1, not_equal_continue); ++ } else { ++ // Put the test value into a register, so caller can use it: ++ ld(test_value_out, Address(mdp_in, offset)); ++ bne(value, test_value_out, not_equal_continue); ++ } ++} ++ ++ ++void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, ++ int offset_of_disp) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ ld(t1, Address(mdp_in, offset_of_disp)); ++ add(mdp_in, mdp_in, t1); ++ sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); ++} ++ ++void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, ++ Register reg, ++ int offset_of_disp) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ add(t1, mdp_in, reg); ++ ld(t1, Address(t1, offset_of_disp)); ++ add(mdp_in, mdp_in, t1); ++ sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); ++} ++ ++ ++void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, ++ int constant) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ addi(mdp_in, mdp_in, (unsigned)constant); ++ sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); ++} ++ ++ ++void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { ++ assert(ProfileInterpreter, "must be profiling interpreter"); ++ ++ // save/restore across call_VM ++ addi(sp, sp, -2 * wordSize); ++ sd(zr, Address(sp, 0)); ++ sd(return_bci, Address(sp, wordSize)); ++ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), ++ return_bci); ++ ld(zr, Address(sp, 0)); ++ ld(return_bci, Address(sp, wordSize)); ++ addi(sp, sp, 2 * wordSize); ++} ++ ++void InterpreterMacroAssembler::profile_taken_branch(Register mdp, ++ Register bumped_count) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ // Otherwise, assign to mdp ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // We are taking a branch. Increment the taken count. ++ Address data(mdp, in_bytes(JumpData::taken_offset())); ++ ld(bumped_count, data); ++ assert(DataLayout::counter_increment == 1, ++ "flow-free idiom only works with 1"); ++ addi(bumped_count, bumped_count, DataLayout::counter_increment); ++ Label L; ++ // eg: bumped_count=0x7fff ffff ffff ffff + 1 < 0. so we use <= 0; ++ blez(bumped_count, L); // skip store if counter overflow, ++ sd(bumped_count, data); ++ bind(L); ++ // The method data pointer needs to be updated to reflect the new target. ++ update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset())); ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // We are taking a branch. Increment the not taken count. ++ increment_mdp_data_at(mdp, in_bytes(BranchData::not_taken_offset())); ++ ++ // The method data pointer needs to be updated to correspond to ++ // the next bytecode ++ update_mdp_by_constant(mdp, in_bytes(BranchData::branch_data_size())); ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_call(Register mdp) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // We are making a call. Increment the count. ++ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); ++ ++ // The method data pointer needs to be updated to reflect the new target. ++ update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size())); ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_final_call(Register mdp) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // We are making a call. Increment the count. ++ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); ++ ++ // The method data pointer needs to be updated to reflect the new target. ++ update_mdp_by_constant(mdp, ++ in_bytes(VirtualCallData:: ++ virtual_call_data_size())); ++ bind(profile_continue); ++ } ++} ++ ++ ++void InterpreterMacroAssembler::profile_virtual_call(Register receiver, ++ Register mdp, ++ Register reg2, ++ bool receiver_can_be_null) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ Label skip_receiver_profile; ++ if (receiver_can_be_null) { ++ Label not_null; ++ // We are making a call. Increment the count for null receiver. ++ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); ++ j(skip_receiver_profile); ++ bind(not_null); ++ } ++ ++ // Record the receiver type. ++ record_klass_in_profile(receiver, mdp, reg2, true); ++ bind(skip_receiver_profile); ++ ++ // The method data pointer needs to be updated to reflect the new target. ++ ++ update_mdp_by_constant(mdp, ++ in_bytes(VirtualCallData:: ++ virtual_call_data_size())); ++ bind(profile_continue); ++ } ++} ++ ++// This routine creates a state machine for updating the multi-row ++// type profile at a virtual call site (or other type-sensitive bytecode). ++// The machine visits each row (of receiver/count) until the receiver type ++// is found, or until it runs out of rows. At the same time, it remembers ++// the location of the first empty row. (An empty row records null for its ++// receiver, and can be allocated for a newly-observed receiver type.) ++// Because there are two degrees of freedom in the state, a simple linear ++// search will not work; it must be a decision tree. Hence this helper ++// function is recursive, to generate the required tree structured code. ++// It's the interpreter, so we are trading off code space for speed. ++// See below for example code. ++void InterpreterMacroAssembler::record_klass_in_profile_helper( ++ Register receiver, Register mdp, ++ Register reg2, ++ Label& done, bool is_virtual_call) { ++ if (TypeProfileWidth == 0) { ++ if (is_virtual_call) { ++ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); ++ } ++ ++ } else { ++ int non_profiled_offset = -1; ++ if (is_virtual_call) { ++ non_profiled_offset = in_bytes(CounterData::count_offset()); ++ } ++ ++ record_item_in_profile_helper(receiver, mdp, reg2, 0, done, TypeProfileWidth, ++ &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset); ++ } ++} ++ ++void InterpreterMacroAssembler::record_item_in_profile_helper( ++ Register item, Register mdp, Register reg2, int start_row, Label& done, int total_rows, ++ OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn, int non_profiled_offset) { ++ int last_row = total_rows - 1; ++ assert(start_row <= last_row, "must be work left to do"); ++ // Test this row for both the item and for null. ++ // Take any of three different outcomes: ++ // 1. found item => increment count and goto done ++ // 2. found null => keep looking for case 1, maybe allocate this cell ++ // 3. found something else => keep looking for cases 1 and 2 ++ // Case 3 is handled by a recursive call. ++ for (int row = start_row; row <= last_row; row++) { ++ Label next_test; ++ bool test_for_null_also = (row == start_row); ++ ++ // See if the item is item[n]. ++ int item_offset = in_bytes(item_offset_fn(row)); ++ test_mdp_data_at(mdp, item_offset, item, ++ (test_for_null_also ? reg2 : noreg), ++ next_test); ++ // (Reg2 now contains the item from the CallData.) ++ ++ // The item is item[n]. Increment count[n]. ++ int count_offset = in_bytes(item_count_offset_fn(row)); ++ increment_mdp_data_at(mdp, count_offset); ++ j(done); ++ bind(next_test); ++ ++ if (test_for_null_also) { ++ Label found_null; ++ // Failed the equality check on item[n]... Test for null. ++ if (start_row == last_row) { ++ // The only thing left to do is handle the null case. ++ if (non_profiled_offset >= 0) { ++ beqz(reg2, found_null); ++ // Item did not match any saved item and there is no empty row for it. ++ // Increment total counter to indicate polymorphic case. ++ increment_mdp_data_at(mdp, non_profiled_offset); ++ j(done); ++ bind(found_null); ++ } else { ++ bnez(reg2, done); ++ } ++ break; ++ } ++ // Since null is rare, make it be the branch-taken case. ++ beqz(reg2, found_null); ++ ++ // Put all the "Case 3" tests here. ++ record_item_in_profile_helper(item, mdp, reg2, start_row + 1, done, total_rows, ++ item_offset_fn, item_count_offset_fn, non_profiled_offset); ++ ++ // Found a null. Keep searching for a matching item, ++ // but remember that this is an empty (unused) slot. ++ bind(found_null); ++ } ++ } ++ ++ // In the fall-through case, we found no matching item, but we ++ // observed the item[start_row] is NULL. ++ // Fill in the item field and increment the count. ++ int item_offset = in_bytes(item_offset_fn(start_row)); ++ set_mdp_data_at(mdp, item_offset, item); ++ int count_offset = in_bytes(item_count_offset_fn(start_row)); ++ mv(reg2, DataLayout::counter_increment); ++ set_mdp_data_at(mdp, count_offset, reg2); ++ if (start_row > 0) { ++ j(done); ++ } ++} ++ ++// Example state machine code for three profile rows: ++// # main copy of decision tree, rooted at row[1] ++// if (row[0].rec == rec) then [ ++// row[0].incr() ++// goto done ++// ] ++// if (row[0].rec != NULL) then [ ++// # inner copy of decision tree, rooted at row[1] ++// if (row[1].rec == rec) then [ ++// row[1].incr() ++// goto done ++// ] ++// if (row[1].rec != NULL) then [ ++// # degenerate decision tree, rooted at row[2] ++// if (row[2].rec == rec) then [ ++// row[2].incr() ++// goto done ++// ] ++// if (row[2].rec != NULL) then [ ++// count.incr() ++// goto done ++// ] # overflow ++// row[2].init(rec) ++// goto done ++// ] else [ ++// # remember row[1] is empty ++// if (row[2].rec == rec) then [ ++// row[2].incr() ++// goto done ++// ] ++// row[1].init(rec) ++// goto done ++// ] ++// else [ ++// # remember row[0] is empty ++// if (row[1].rec == rec) then [ ++// row[1].incr() ++// goto done ++// ] ++// if (row[2].rec == rec) then [ ++// row[2].incr() ++// goto done ++// ] ++// row[0].init(rec) ++// goto done ++// ] ++// done: ++ ++void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, ++ Register mdp, Register reg2, ++ bool is_virtual_call) { ++ assert(ProfileInterpreter, "must be profiling"); ++ Label done; ++ ++ record_klass_in_profile_helper(receiver, mdp, reg2, done, is_virtual_call); ++ ++ bind(done); ++} ++ ++void InterpreterMacroAssembler::profile_ret(Register return_bci, Register mdp) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // Update the total ret count. ++ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); ++ ++ for (uint row = 0; row < RetData::row_limit(); row++) { ++ Label next_test; ++ ++ // See if return_bci is equal to bci[n]: ++ test_mdp_data_at(mdp, ++ in_bytes(RetData::bci_offset(row)), ++ return_bci, noreg, ++ next_test); ++ ++ // return_bci is equal to bci[n]. Increment the count. ++ increment_mdp_data_at(mdp, in_bytes(RetData::bci_count_offset(row))); ++ ++ // The method data pointer needs to be updated to reflect the new target. ++ update_mdp_by_offset(mdp, ++ in_bytes(RetData::bci_displacement_offset(row))); ++ j(profile_continue); ++ bind(next_test); ++ } ++ ++ update_mdp_for_ret(return_bci); ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_null_seen(Register mdp) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ set_mdp_flag_at(mdp, BitData::null_seen_byte_constant()); ++ ++ // The method data pointer needs to be updated. ++ int mdp_delta = in_bytes(BitData::bit_data_size()); ++ if (TypeProfileCasts) { ++ mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); ++ } ++ update_mdp_by_constant(mdp, mdp_delta); ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_typecheck_failed(Register mdp) { ++ if (ProfileInterpreter && TypeProfileCasts) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ int count_offset = in_bytes(CounterData::count_offset()); ++ // Back up the address, since we have already bumped the mdp. ++ count_offset -= in_bytes(VirtualCallData::virtual_call_data_size()); ++ ++ // *Decrement* the counter. We expect to see zero or small negatives. ++ increment_mdp_data_at(mdp, count_offset, true); ++ ++ bind (profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass, Register reg2) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // The method data pointer needs to be updated. ++ int mdp_delta = in_bytes(BitData::bit_data_size()); ++ if (TypeProfileCasts) { ++ mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); ++ ++ // Record the object type. ++ record_klass_in_profile(klass, mdp, reg2, false); ++ } ++ update_mdp_by_constant(mdp, mdp_delta); ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_switch_default(Register mdp) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // Update the default case count ++ increment_mdp_data_at(mdp, ++ in_bytes(MultiBranchData::default_count_offset())); ++ ++ // The method data pointer needs to be updated. ++ update_mdp_by_offset(mdp, ++ in_bytes(MultiBranchData:: ++ default_displacement_offset())); ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_switch_case(Register index, ++ Register mdp, ++ Register reg2) { ++ if (ProfileInterpreter) { ++ Label profile_continue; ++ ++ // If no method data exists, go to profile_continue. ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // Build the base (index * per_case_size_in_bytes()) + ++ // case_array_offset_in_bytes() ++ mv(reg2, in_bytes(MultiBranchData::per_case_size())); ++ mv(t0, in_bytes(MultiBranchData::case_array_offset())); ++ Assembler::mul(index, index, reg2); ++ Assembler::add(index, index, t0); ++ ++ // Update the case count ++ increment_mdp_data_at(mdp, ++ index, ++ in_bytes(MultiBranchData::relative_count_offset())); ++ ++ // The method data pointer need to be updated. ++ update_mdp_by_offset(mdp, ++ index, ++ in_bytes(MultiBranchData:: ++ relative_displacement_offset())); ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { ; } ++ ++void InterpreterMacroAssembler::notify_method_entry() { ++ // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to ++ // track stack depth. If it is possible to enter interp_only_mode we add ++ // the code to check if the event should be sent. ++ if (JvmtiExport::can_post_interpreter_events()) { ++ Label L; ++ lwu(x13, Address(xthread, JavaThread::interp_only_mode_offset())); ++ beqz(x13, L); ++ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::post_method_entry)); ++ bind(L); ++ } ++ ++ { ++ SkipIfEqual skip(this, &DTraceMethodProbes, false); ++ get_method(c_rarg1); ++ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), ++ xthread, c_rarg1); ++ } ++ ++ // RedefineClasses() tracing support for obsolete method entry ++ if (log_is_enabled(Trace, redefine, class, obsolete)) { ++ get_method(c_rarg1); ++ call_VM_leaf( ++ CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry), ++ xthread, c_rarg1); ++ } ++} ++ ++ ++void InterpreterMacroAssembler::notify_method_exit( ++ TosState state, NotifyMethodExitMode mode) { ++ // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to ++ // track stack depth. If it is possible to enter interp_only_mode we add ++ // the code to check if the event should be sent. ++ if (mode == NotifyJVMTI && JvmtiExport::can_post_interpreter_events()) { ++ Label L; ++ // Note: frame::interpreter_frame_result has a dependency on how the ++ // method result is saved across the call to post_method_exit. If this ++ // is changed then the interpreter_frame_result implementation will ++ // need to be updated too. ++ ++ // template interpreter will leave the result on the top of the stack. ++ push(state); ++ lwu(x13, Address(xthread, JavaThread::interp_only_mode_offset())); ++ beqz(x13, L); ++ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit)); ++ bind(L); ++ pop(state); ++ } ++ ++ { ++ SkipIfEqual skip(this, &DTraceMethodProbes, false); ++ push(state); ++ get_method(c_rarg1); ++ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), ++ xthread, c_rarg1); ++ pop(state); ++ } ++} ++ ++ ++// Jump if ((*counter_addr += increment) & mask) satisfies the condition. ++void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr, ++ int increment, Address mask, ++ Register tmp1, Register tmp2, ++ bool preloaded, Label* where) { ++ Label done; ++ if (!preloaded) { ++ lwu(tmp1, counter_addr); ++ } ++ add(tmp1, tmp1, increment); ++ sw(tmp1, counter_addr); ++ lwu(tmp2, mask); ++ andr(tmp1, tmp1, tmp2); ++ bnez(tmp1, done); ++ j(*where); // offset is too large so we have to use j instead of beqz here ++ bind(done); ++} ++ ++void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, ++ int number_of_arguments) { ++ // interpreter specific ++ // ++ // Note: No need to save/restore rbcp & rlocals pointer since these ++ // are callee saved registers and no blocking/ GC can happen ++ // in leaf calls. ++#ifdef ASSERT ++ { ++ Label L; ++ ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ beqz(t0, L); ++ stop("InterpreterMacroAssembler::call_VM_leaf_base:" ++ " last_sp != NULL"); ++ bind(L); ++ } ++#endif /* ASSERT */ ++ // super call ++ MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments); ++} ++ ++void InterpreterMacroAssembler::call_VM_base(Register oop_result, ++ Register java_thread, ++ Register last_java_sp, ++ address entry_point, ++ int number_of_arguments, ++ bool check_exceptions) { ++ // interpreter specific ++ // ++ // Note: Could avoid restoring locals ptr (callee saved) - however doesn't ++ // really make a difference for these runtime calls, since they are ++ // slow anyway. Btw., bcp must be saved/restored since it may change ++ // due to GC. ++ save_bcp(); ++#ifdef ASSERT ++ { ++ Label L; ++ ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ beqz(t0, L); ++ stop("InterpreterMacroAssembler::call_VM_base:" ++ " last_sp != NULL"); ++ bind(L); ++ } ++#endif /* ASSERT */ ++ // super call ++ MacroAssembler::call_VM_base(oop_result, noreg, last_java_sp, ++ entry_point, number_of_arguments, ++ check_exceptions); ++// interpreter specific ++ restore_bcp(); ++ restore_locals(); ++} ++ ++void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr, Register tmp) { ++ assert_different_registers(obj, tmp, t0, mdo_addr.base()); ++ Label update, next, none; ++ ++ verify_oop(obj); ++ ++ bnez(obj, update); ++ orptr(mdo_addr, TypeEntries::null_seen, t0, tmp); ++ j(next); ++ ++ bind(update); ++ load_klass(obj, obj); ++ ++ ld(t0, mdo_addr); ++ xorr(obj, obj, t0); ++ andi(t0, obj, TypeEntries::type_klass_mask); ++ beqz(t0, next); // klass seen before, nothing to ++ // do. The unknown bit may have been ++ // set already but no need to check. ++ ++ test_bit(t0, obj, exact_log2(TypeEntries::type_unknown)); ++ bnez(t0, next); ++ // already unknown. Nothing to do anymore. ++ ++ ld(t0, mdo_addr); ++ beqz(t0, none); ++ mv(tmp, (u1)TypeEntries::null_seen); ++ beq(t0, tmp, none); ++ // There is a chance that the checks above (re-reading profiling ++ // data from memory) fail if another thread has just set the ++ // profiling to this obj's klass ++ ld(t0, mdo_addr); ++ xorr(obj, obj, t0); ++ andi(t0, obj, TypeEntries::type_klass_mask); ++ beqz(t0, next); ++ ++ // different than before. Cannot keep accurate profile. ++ orptr(mdo_addr, TypeEntries::type_unknown, t0, tmp); ++ j(next); ++ ++ bind(none); ++ // first time here. Set profile type. ++ sd(obj, mdo_addr); ++ ++ bind(next); ++} ++ ++void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) { ++ if (!ProfileInterpreter) { ++ return; ++ } ++ ++ if (MethodData::profile_arguments() || MethodData::profile_return()) { ++ Label profile_continue; ++ ++ test_method_data_pointer(mdp, profile_continue); ++ ++ int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); ++ ++ lbu(t0, Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start)); ++ if (is_virtual) { ++ mv(tmp, (u1)DataLayout::virtual_call_type_data_tag); ++ bne(t0, tmp, profile_continue); ++ } else { ++ mv(tmp, (u1)DataLayout::call_type_data_tag); ++ bne(t0, tmp, profile_continue); ++ } ++ ++ // calculate slot step ++ static int stack_slot_offset0 = in_bytes(TypeEntriesAtCall::stack_slot_offset(0)); ++ static int slot_step = in_bytes(TypeEntriesAtCall::stack_slot_offset(1)) - stack_slot_offset0; ++ ++ // calculate type step ++ static int argument_type_offset0 = in_bytes(TypeEntriesAtCall::argument_type_offset(0)); ++ static int type_step = in_bytes(TypeEntriesAtCall::argument_type_offset(1)) - argument_type_offset0; ++ ++ if (MethodData::profile_arguments()) { ++ Label done, loop, loopEnd, profileArgument, profileReturnType; ++ RegSet pushed_registers; ++ pushed_registers += x15; ++ pushed_registers += x16; ++ pushed_registers += x17; ++ Register mdo_addr = x15; ++ Register index = x16; ++ Register off_to_args = x17; ++ push_reg(pushed_registers, sp); ++ ++ mv(off_to_args, in_bytes(TypeEntriesAtCall::args_data_offset())); ++ mv(t0, TypeProfileArgsLimit); ++ beqz(t0, loopEnd); ++ ++ mv(index, zr); // index < TypeProfileArgsLimit ++ bind(loop); ++ bgtz(index, profileReturnType); ++ mv(t0, (int)MethodData::profile_return()); ++ beqz(t0, profileArgument); // (index > 0 || MethodData::profile_return()) == false ++ bind(profileReturnType); ++ // If return value type is profiled we may have no argument to profile ++ ld(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset()))); ++ mv(t1, - TypeStackSlotEntries::per_arg_count()); ++ mul(t1, index, t1); ++ add(tmp, tmp, t1); ++ mv(t1, TypeStackSlotEntries::per_arg_count()); ++ add(t0, mdp, off_to_args); ++ blt(tmp, t1, done); ++ ++ bind(profileArgument); ++ ++ ld(tmp, Address(callee, Method::const_offset())); ++ load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); ++ // stack offset o (zero based) from the start of the argument ++ // list, for n arguments translates into offset n - o - 1 from ++ // the end of the argument list ++ mv(t0, stack_slot_offset0); ++ mv(t1, slot_step); ++ mul(t1, index, t1); ++ add(t0, t0, t1); ++ add(t0, mdp, t0); ++ ld(t0, Address(t0)); ++ sub(tmp, tmp, t0); ++ addi(tmp, tmp, -1); ++ Address arg_addr = argument_address(tmp); ++ ld(tmp, arg_addr); ++ ++ mv(t0, argument_type_offset0); ++ mv(t1, type_step); ++ mul(t1, index, t1); ++ add(t0, t0, t1); ++ add(mdo_addr, mdp, t0); ++ Address mdo_arg_addr(mdo_addr, 0); ++ profile_obj_type(tmp, mdo_arg_addr, t1); ++ ++ int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); ++ addi(off_to_args, off_to_args, to_add); ++ ++ // increment index by 1 ++ addi(index, index, 1); ++ mv(t1, TypeProfileArgsLimit); ++ blt(index, t1, loop); ++ bind(loopEnd); ++ ++ if (MethodData::profile_return()) { ++ ld(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset()))); ++ addi(tmp, tmp, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); ++ } ++ ++ add(t0, mdp, off_to_args); ++ bind(done); ++ mv(mdp, t0); ++ ++ // unspill the clobbered registers ++ pop_reg(pushed_registers, sp); ++ ++ if (MethodData::profile_return()) { ++ // We're right after the type profile for the last ++ // argument. tmp is the number of cells left in the ++ // CallTypeData/VirtualCallTypeData to reach its end. Non null ++ // if there's a return to profile. ++ assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); ++ shadd(mdp, tmp, mdp, tmp, exact_log2(DataLayout::cell_size)); ++ } ++ sd(mdp, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); ++ } else { ++ assert(MethodData::profile_return(), "either profile call args or call ret"); ++ update_mdp_by_constant(mdp, in_bytes(TypeEntriesAtCall::return_only_size())); ++ } ++ ++ // mdp points right after the end of the ++ // CallTypeData/VirtualCallTypeData, right after the cells for the ++ // return value type if there's one ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) { ++ assert_different_registers(mdp, ret, tmp, xbcp, t0, t1); ++ if (ProfileInterpreter && MethodData::profile_return()) { ++ Label profile_continue, done; ++ ++ test_method_data_pointer(mdp, profile_continue); ++ ++ if (MethodData::profile_return_jsr292_only()) { ++ assert(Method::intrinsic_id_size_in_bytes() == 2, "assuming Method::_intrinsic_id is u2"); ++ ++ // If we don't profile all invoke bytecodes we must make sure ++ // it's a bytecode we indeed profile. We can't go back to the ++ // begining of the ProfileData we intend to update to check its ++ // type because we're right after it and we don't known its ++ // length ++ Label do_profile; ++ lbu(t0, Address(xbcp, 0)); ++ mv(tmp, (u1)Bytecodes::_invokedynamic); ++ beq(t0, tmp, do_profile); ++ mv(tmp, (u1)Bytecodes::_invokehandle); ++ beq(t0, tmp, do_profile); ++ get_method(tmp); ++ lhu(t0, Address(tmp, Method::intrinsic_id_offset_in_bytes())); ++ mv(t1, static_cast(vmIntrinsics::_compiledLambdaForm)); ++ bne(t0, t1, profile_continue); ++ bind(do_profile); ++ } ++ ++ Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size())); ++ mv(tmp, ret); ++ profile_obj_type(tmp, mdo_ret_addr, t1); ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2, Register tmp3) { ++ assert_different_registers(t0, t1, mdp, tmp1, tmp2, tmp3); ++ if (ProfileInterpreter && MethodData::profile_parameters()) { ++ Label profile_continue, done; ++ ++ test_method_data_pointer(mdp, profile_continue); ++ ++ // Load the offset of the area within the MDO used for ++ // parameters. If it's negative we're not profiling any parameters ++ lwu(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset()))); ++ srli(tmp2, tmp1, 31); ++ bnez(tmp2, profile_continue); // i.e. sign bit set ++ ++ // Compute a pointer to the area for parameters from the offset ++ // and move the pointer to the slot for the last ++ // parameters. Collect profiling from last parameter down. ++ // mdo start + parameters offset + array length - 1 ++ add(mdp, mdp, tmp1); ++ ld(tmp1, Address(mdp, ArrayData::array_len_offset())); ++ add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count()); ++ ++ Label loop; ++ bind(loop); ++ ++ int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0)); ++ int type_base = in_bytes(ParametersTypeData::type_offset(0)); ++ int per_arg_scale = exact_log2(DataLayout::cell_size); ++ add(t0, mdp, off_base); ++ add(t1, mdp, type_base); ++ ++ shadd(tmp2, tmp1, t0, tmp2, per_arg_scale); ++ // load offset on the stack from the slot for this parameter ++ ld(tmp2, Address(tmp2, 0)); ++ neg(tmp2, tmp2); ++ ++ // read the parameter from the local area ++ shadd(tmp2, tmp2, xlocals, tmp2, Interpreter::logStackElementSize); ++ ld(tmp2, Address(tmp2, 0)); ++ ++ // profile the parameter ++ shadd(t1, tmp1, t1, t0, per_arg_scale); ++ Address arg_type(t1, 0); ++ profile_obj_type(tmp2, arg_type, tmp3); ++ ++ // go to next parameter ++ add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count()); ++ bgez(tmp1, loop); ++ ++ bind(profile_continue); ++ } ++} ++ ++void InterpreterMacroAssembler::get_method_counters(Register method, ++ Register mcs, Label& skip) { ++ Label has_counters; ++ ld(mcs, Address(method, Method::method_counters_offset())); ++ bnez(mcs, has_counters); ++ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::build_method_counters), method); ++ ld(mcs, Address(method, Method::method_counters_offset())); ++ beqz(mcs, skip); // No MethodCounters allocated, OutOfMemory ++ bind(has_counters); ++} ++ ++#ifdef ASSERT ++void InterpreterMacroAssembler::verify_access_flags(Register access_flags, uint32_t flag, ++ const char* msg, bool stop_by_hit) { ++ Label L; ++ test_bit(t0, access_flags, exact_log2(flag)); ++ if (stop_by_hit) { ++ beqz(t0, L); ++ } else { ++ bnez(t0, L); ++ } ++ stop(msg); ++ bind(L); ++} ++ ++void InterpreterMacroAssembler::verify_frame_setup() { ++ Label L; ++ const Address monitor_block_top(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize); ++ ld(t0, monitor_block_top); ++ beq(esp, t0, L); ++ stop("broken stack frame setup in interpreter"); ++ bind(L); ++} ++#endif +--- /dev/null ++++ b/src/hotspot/cpu/riscv/interp_masm_riscv.hpp +@@ -0,0 +1,285 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2015, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_INTERP_MASM_RISCV_HPP ++#define CPU_RISCV_INTERP_MASM_RISCV_HPP ++ ++#include "asm/macroAssembler.hpp" ++#include "interpreter/invocationCounter.hpp" ++#include "runtime/frame.hpp" ++ ++// This file specializes the assember with interpreter-specific macros ++ ++typedef ByteSize (*OffsetFunction)(uint); ++ ++class InterpreterMacroAssembler: public MacroAssembler { ++ protected: ++ // Interpreter specific version of call_VM_base ++ using MacroAssembler::call_VM_leaf_base; ++ ++ virtual void call_VM_leaf_base(address entry_point, ++ int number_of_arguments); ++ ++ virtual void call_VM_base(Register oop_result, ++ Register java_thread, ++ Register last_java_sp, ++ address entry_point, ++ int number_of_arguments, ++ bool check_exceptions); ++ ++ // base routine for all dispatches ++ void dispatch_base(TosState state, address* table, bool verifyoop = true, ++ bool generate_poll = false, Register Rs = t0); ++ ++ public: ++ InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} ++ virtual ~InterpreterMacroAssembler() {} ++ ++ void load_earlyret_value(TosState state); ++ ++ void jump_to_entry(address entry); ++ ++ virtual void check_and_handle_popframe(Register java_thread); ++ virtual void check_and_handle_earlyret(Register java_thread); ++ ++ // Interpreter-specific registers ++ void save_bcp() { ++ sd(xbcp, Address(fp, frame::interpreter_frame_bcp_offset * wordSize)); ++ } ++ ++ void restore_bcp() { ++ ld(xbcp, Address(fp, frame::interpreter_frame_bcp_offset * wordSize)); ++ } ++ ++ void restore_locals() { ++ ld(xlocals, Address(fp, frame::interpreter_frame_locals_offset * wordSize)); ++ } ++ ++ void restore_constant_pool_cache() { ++ ld(xcpool, Address(fp, frame::interpreter_frame_cache_offset * wordSize)); ++ } ++ ++ void get_dispatch(); ++ ++ // Helpers for runtime call arguments/results ++ void get_method(Register reg) { ++ ld(reg, Address(fp, frame::interpreter_frame_method_offset * wordSize)); ++ } ++ ++ void get_const(Register reg) { ++ get_method(reg); ++ ld(reg, Address(reg, in_bytes(Method::const_offset()))); ++ } ++ ++ void get_constant_pool(Register reg) { ++ get_const(reg); ++ ld(reg, Address(reg, in_bytes(ConstMethod::constants_offset()))); ++ } ++ ++ void get_constant_pool_cache(Register reg) { ++ get_constant_pool(reg); ++ ld(reg, Address(reg, ConstantPool::cache_offset_in_bytes())); ++ } ++ ++ void get_cpool_and_tags(Register cpool, Register tags) { ++ get_constant_pool(cpool); ++ ld(tags, Address(cpool, ConstantPool::tags_offset_in_bytes())); ++ } ++ ++ void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); ++ void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2)); ++ void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2)); ++ void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); ++ void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); ++ void get_method_counters(Register method, Register mcs, Label& skip); ++ ++ // Load cpool->resolved_references(index). ++ void load_resolved_reference_at_index(Register result, Register index, Register tmp = x15); ++ ++ // Load cpool->resolved_klass_at(index). ++ void load_resolved_klass_at_offset(Register cpool, Register index, Register klass, Register temp); ++ ++ void load_resolved_method_at_index(int byte_no, Register method, Register cache); ++ ++ void pop_ptr(Register r = x10); ++ void pop_i(Register r = x10); ++ void pop_l(Register r = x10); ++ void pop_f(FloatRegister r = f10); ++ void pop_d(FloatRegister r = f10); ++ void push_ptr(Register r = x10); ++ void push_i(Register r = x10); ++ void push_l(Register r = x10); ++ void push_f(FloatRegister r = f10); ++ void push_d(FloatRegister r = f10); ++ ++ void pop(TosState state); // transition vtos -> state ++ void push(TosState state); // transition state -> vtos ++ ++ void empty_expression_stack() { ++ ld(esp, Address(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); ++ // NULL last_sp until next java call ++ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ } ++ ++ // Helpers for swap and dup ++ void load_ptr(int n, Register val); ++ void store_ptr(int n, Register val); ++ ++ // Load float value from 'address'. The value is loaded onto the fp register f10. ++ void load_float(Address src); ++ void load_double(Address src); ++ ++ // Generate a subtype check: branch to ok_is_subtype if sub_klass is ++ // a subtype of super_klass. ++ void gen_subtype_check( Register sub_klass, Label &ok_is_subtype ); ++ ++ // Dispatching ++ void dispatch_prolog(TosState state, int step = 0); ++ void dispatch_epilog(TosState state, int step = 0); ++ // dispatch via t0 ++ void dispatch_only(TosState state, bool generate_poll = false, Register Rs = t0); ++ // dispatch normal table via t0 (assume t0 is loaded already) ++ void dispatch_only_normal(TosState state, Register Rs = t0); ++ void dispatch_only_noverify(TosState state, Register Rs = t0); ++ // load t0 from [xbcp + step] and dispatch via t0 ++ void dispatch_next(TosState state, int step = 0, bool generate_poll = false); ++ // load t0 from [xbcp] and dispatch via t0 and table ++ void dispatch_via (TosState state, address* table); ++ ++ // jump to an invoked target ++ void prepare_to_jump_from_interpreted(); ++ void jump_from_interpreted(Register method); ++ ++ ++ // Returning from interpreted functions ++ // ++ // Removes the current activation (incl. unlocking of monitors) ++ // and sets up the return address. This code is also used for ++ // exception unwindwing. In that case, we do not want to throw ++ // IllegalMonitorStateExceptions, since that might get us into an ++ // infinite rethrow exception loop. ++ // Additionally this code is used for popFrame and earlyReturn. ++ // In popFrame case we want to skip throwing an exception, ++ // installing an exception, and notifying jvmdi. ++ // In earlyReturn case we only want to skip throwing an exception ++ // and installing an exception. ++ void remove_activation(TosState state, ++ bool throw_monitor_exception = true, ++ bool install_monitor_exception = true, ++ bool notify_jvmdi = true); ++ ++ // FIXME: Give us a valid frame at a null check. ++ virtual void null_check(Register reg, int offset = -1) { ++ MacroAssembler::null_check(reg, offset); ++ } ++ ++ // Object locking ++ void lock_object (Register lock_reg); ++ void unlock_object(Register lock_reg); ++ ++ // Interpreter profiling operations ++ void set_method_data_pointer_for_bcp(); ++ void test_method_data_pointer(Register mdp, Label& zero_continue); ++ void verify_method_data_pointer(); ++ ++ void set_mdp_data_at(Register mdp_in, int constant, Register value); ++ void increment_mdp_data_at(Address data, bool decrement = false); ++ void increment_mdp_data_at(Register mdp_in, int constant, ++ bool decrement = false); ++ void increment_mdp_data_at(Register mdp_in, Register reg, int constant, ++ bool decrement = false); ++ void increment_mask_and_jump(Address counter_addr, ++ int increment, Address mask, ++ Register tmp1, Register tmp2, ++ bool preloaded, Label* where); ++ ++ void set_mdp_flag_at(Register mdp_in, int flag_constant); ++ void test_mdp_data_at(Register mdp_in, int offset, Register value, ++ Register test_value_out, ++ Label& not_equal_continue); ++ ++ void record_klass_in_profile(Register receiver, Register mdp, ++ Register reg2, bool is_virtual_call); ++ void record_klass_in_profile_helper(Register receiver, Register mdp, ++ Register reg2, ++ Label& done, bool is_virtual_call); ++ void record_item_in_profile_helper(Register item, Register mdp, ++ Register reg2, int start_row, Label& done, int total_rows, ++ OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn, ++ int non_profiled_offset); ++ ++ void update_mdp_by_offset(Register mdp_in, int offset_of_offset); ++ void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp); ++ void update_mdp_by_constant(Register mdp_in, int constant); ++ void update_mdp_for_ret(Register return_bci); ++ ++ // narrow int return value ++ void narrow(Register result); ++ ++ void profile_taken_branch(Register mdp, Register bumped_count); ++ void profile_not_taken_branch(Register mdp); ++ void profile_call(Register mdp); ++ void profile_final_call(Register mdp); ++ void profile_virtual_call(Register receiver, Register mdp, ++ Register t1, ++ bool receiver_can_be_null = false); ++ void profile_ret(Register return_bci, Register mdp); ++ void profile_null_seen(Register mdp); ++ void profile_typecheck(Register mdp, Register klass, Register temp); ++ void profile_typecheck_failed(Register mdp); ++ void profile_switch_default(Register mdp); ++ void profile_switch_case(Register index_in_scratch, Register mdp, ++ Register temp); ++ ++ void profile_obj_type(Register obj, const Address& mdo_addr, Register tmp); ++ void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual); ++ void profile_return_type(Register mdp, Register ret, Register tmp); ++ void profile_parameters_type(Register mdp, Register tmp1, Register tmp2, Register tmp3); ++ ++ // Debugging ++ // only if +VerifyFPU && (state == ftos || state == dtos) ++ void verify_FPU(int stack_depth, TosState state = ftos); ++ ++ typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode; ++ ++ // support for jvmti/dtrace ++ void notify_method_entry(); ++ void notify_method_exit(TosState state, NotifyMethodExitMode mode); ++ ++ virtual void _call_Unimplemented(address call_site) { ++ save_bcp(); ++ set_last_Java_frame(esp, fp, (address) pc(), t0); ++ MacroAssembler::_call_Unimplemented(call_site); ++ } ++ ++#ifdef ASSERT ++ void verify_access_flags(Register access_flags, uint32_t flag, ++ const char* msg, bool stop_by_hit = true); ++ void verify_frame_setup(); ++#endif ++}; ++ ++#endif // CPU_RISCV_INTERP_MASM_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp +@@ -0,0 +1,295 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "interpreter/interp_masm.hpp" ++#include "interpreter/interpreter.hpp" ++#include "interpreter/interpreterRuntime.hpp" ++#include "memory/allocation.inline.hpp" ++#include "memory/universe.hpp" ++#include "oops/method.hpp" ++#include "oops/oop.inline.hpp" ++#include "runtime/handles.inline.hpp" ++#include "runtime/icache.hpp" ++#include "runtime/interfaceSupport.inline.hpp" ++#include "runtime/signature.hpp" ++ ++#define __ _masm-> ++ ++// Implementation of SignatureHandlerGenerator ++Register InterpreterRuntime::SignatureHandlerGenerator::from() { return xlocals; } ++Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; } ++Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return t0; } ++ ++Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() { ++ if (_num_reg_int_args < Argument::n_int_register_parameters_c - 1) { ++ return g_INTArgReg[++_num_reg_int_args]; ++ } ++ return noreg; ++} ++ ++FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() { ++ if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { ++ return g_FPArgReg[_num_reg_fp_args++]; ++ } else { ++ return fnoreg; ++ } ++} ++ ++int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset() { ++ int ret = _stack_offset; ++ _stack_offset += wordSize; ++ return ret; ++} ++ ++InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator( ++ const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) { ++ _masm = new MacroAssembler(buffer); // allocate on resourse area by default ++ _num_reg_int_args = (method->is_static() ? 1 : 0); ++ _num_reg_fp_args = 0; ++ _stack_offset = 0; ++} ++ ++void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { ++ const Address src(from(), Interpreter::local_offset_in_bytes(offset())); ++ ++ Register reg = next_gpr(); ++ if (reg != noreg) { ++ __ lw(reg, src); ++ } else { ++ __ lw(x10, src); ++ __ sw(x10, Address(to(), next_stack_offset())); ++ } ++} ++ ++void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { ++ const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); ++ ++ Register reg = next_gpr(); ++ if (reg != noreg) { ++ __ ld(reg, src); ++ } else { ++ __ ld(x10, src); ++ __ sd(x10, Address(to(), next_stack_offset())); ++ } ++} ++ ++void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { ++ const Address src(from(), Interpreter::local_offset_in_bytes(offset())); ++ ++ FloatRegister reg = next_fpr(); ++ if (reg != fnoreg) { ++ __ flw(reg, src); ++ } else { ++ // a floating-point argument is passed according to the integer calling ++ // convention if no floating-point argument register available ++ pass_int(); ++ } ++} ++ ++void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { ++ const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); ++ ++ FloatRegister reg = next_fpr(); ++ if (reg != fnoreg) { ++ __ fld(reg, src); ++ } else { ++ // a floating-point argument is passed according to the integer calling ++ // convention if no floating-point argument register available ++ pass_long(); ++ } ++} ++ ++void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { ++ Register reg = next_gpr(); ++ if (reg == c_rarg1) { ++ assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); ++ __ addi(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); ++ } else if (reg != noreg) { ++ // c_rarg2-c_rarg7 ++ __ addi(x10, from(), Interpreter::local_offset_in_bytes(offset())); ++ __ mv(reg, zr); //_num_reg_int_args:c_rarg -> 1:c_rarg2, 2:c_rarg3... ++ __ ld(temp(), x10); ++ Label L; ++ __ beqz(temp(), L); ++ __ mv(reg, x10); ++ __ bind(L); ++ } else { ++ //to stack ++ __ addi(x10, from(), Interpreter::local_offset_in_bytes(offset())); ++ __ ld(temp(), x10); ++ Label L; ++ __ bnez(temp(), L); ++ __ mv(x10, zr); ++ __ bind(L); ++ assert(sizeof(jobject) == wordSize, ""); ++ __ sd(x10, Address(to(), next_stack_offset())); ++ } ++} ++ ++void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { ++ // generate code to handle arguments ++ iterate(fingerprint); ++ ++ // return result handler ++ __ la(x10, ExternalAddress(Interpreter::result_handler(method()->result_type()))); ++ __ ret(); ++ ++ __ flush(); ++} ++ ++ ++// Implementation of SignatureHandlerLibrary ++ ++void SignatureHandlerLibrary::pd_set_handler(address handler) {} ++ ++ ++class SlowSignatureHandler ++ : public NativeSignatureIterator { ++ private: ++ address _from; ++ intptr_t* _to; ++ intptr_t* _int_args; ++ intptr_t* _fp_args; ++ intptr_t* _fp_identifiers; ++ unsigned int _num_reg_int_args; ++ unsigned int _num_reg_fp_args; ++ ++ intptr_t* single_slot_addr() { ++ intptr_t* from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); ++ _from -= Interpreter::stackElementSize; ++ return from_addr; ++ } ++ ++ intptr_t* double_slot_addr() { ++ intptr_t* from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(1)); ++ _from -= 2 * Interpreter::stackElementSize; ++ return from_addr; ++ } ++ ++ int pass_gpr(intptr_t value) { ++ if (_num_reg_int_args < Argument::n_int_register_parameters_c - 1) { ++ *_int_args++ = value; ++ return _num_reg_int_args++; ++ } ++ return -1; ++ } ++ ++ int pass_fpr(intptr_t value) { ++ if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { ++ *_fp_args++ = value; ++ return _num_reg_fp_args++; ++ } ++ return -1; ++ } ++ ++ void pass_stack(intptr_t value) { ++ *_to++ = value; ++ } ++ ++ virtual void pass_int() { ++ jint value = *(jint*)single_slot_addr(); ++ if (pass_gpr(value) < 0) { ++ pass_stack(value); ++ } ++ } ++ ++ virtual void pass_long() { ++ intptr_t value = *double_slot_addr(); ++ if (pass_gpr(value) < 0) { ++ pass_stack(value); ++ } ++ } ++ ++ virtual void pass_object() { ++ intptr_t* addr = single_slot_addr(); ++ intptr_t value = *addr == 0 ? NULL : (intptr_t)addr; ++ if (pass_gpr(value) < 0) { ++ pass_stack(value); ++ } ++ } ++ ++ virtual void pass_float() { ++ jint value = *(jint*) single_slot_addr(); ++ // a floating-point argument is passed according to the integer calling ++ // convention if no floating-point argument register available ++ if (pass_fpr(value) < 0 && pass_gpr(value) < 0) { ++ pass_stack(value); ++ } ++ } ++ ++ virtual void pass_double() { ++ intptr_t value = *double_slot_addr(); ++ int arg = pass_fpr(value); ++ if (0 <= arg) { ++ *_fp_identifiers |= (1ull << arg); // mark as double ++ } else if (pass_gpr(value) < 0) { // no need to mark if passing by integer registers or stack ++ pass_stack(value); ++ } ++ } ++ ++ public: ++ SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) ++ : NativeSignatureIterator(method) ++ { ++ _from = from; ++ _to = to; ++ ++ _int_args = to - (method->is_static() ? 16 : 17); ++ _fp_args = to - 8; ++ _fp_identifiers = to - 9; ++ *(int*) _fp_identifiers = 0; ++ _num_reg_int_args = (method->is_static() ? 1 : 0); ++ _num_reg_fp_args = 0; ++ } ++ ++ ~SlowSignatureHandler() ++ { ++ _from = NULL; ++ _to = NULL; ++ _int_args = NULL; ++ _fp_args = NULL; ++ _fp_identifiers = NULL; ++ } ++}; ++ ++ ++JRT_ENTRY(address, ++ InterpreterRuntime::slow_signature_handler(JavaThread* current, ++ Method* method, ++ intptr_t* from, ++ intptr_t* to)) ++ methodHandle m(current, (Method*)method); ++ assert(m->is_native(), "sanity check"); ++ ++ // handle arguments ++ SlowSignatureHandler ssh(m, (address)from, to); ++ ssh.iterate(UCONST64(-1)); ++ ++ // return result handler ++ return Interpreter::result_handler(m->result_type()); ++JRT_END +--- /dev/null ++++ b/src/hotspot/cpu/riscv/interpreterRT_riscv.hpp +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_INTERPRETERRT_RISCV_HPP ++#define CPU_RISCV_INTERPRETERRT_RISCV_HPP ++ ++// This is included in the middle of class Interpreter. ++// Do not include files here. ++ ++// native method calls ++ ++class SignatureHandlerGenerator: public NativeSignatureIterator { ++ private: ++ MacroAssembler* _masm; ++ unsigned int _num_reg_fp_args; ++ unsigned int _num_reg_int_args; ++ int _stack_offset; ++ ++ void pass_int(); ++ void pass_long(); ++ void pass_float(); ++ void pass_double(); ++ void pass_object(); ++ ++ Register next_gpr(); ++ FloatRegister next_fpr(); ++ int next_stack_offset(); ++ ++ public: ++ // Creation ++ SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer); ++ virtual ~SignatureHandlerGenerator() { ++ _masm = NULL; ++ } ++ ++ // Code generation ++ void generate(uint64_t fingerprint); ++ ++ // Code generation support ++ static Register from(); ++ static Register to(); ++ static Register temp(); ++}; ++ ++#endif // CPU_RISCV_INTERPRETERRT_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/javaFrameAnchor_riscv.hpp +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_JAVAFRAMEANCHOR_RISCV_HPP ++#define CPU_RISCV_JAVAFRAMEANCHOR_RISCV_HPP ++ ++private: ++ ++ // FP value associated with _last_Java_sp: ++ intptr_t* volatile _last_Java_fp; // pointer is volatile not what it points to ++ ++public: ++ // Each arch must define reset, save, restore ++ // These are used by objects that only care about: ++ // 1 - initializing a new state (thread creation, javaCalls) ++ // 2 - saving a current state (javaCalls) ++ // 3 - restoring an old state (javaCalls) ++ ++ void clear(void) { ++ // clearing _last_Java_sp must be first ++ _last_Java_sp = NULL; ++ OrderAccess::release(); ++ _last_Java_fp = NULL; ++ _last_Java_pc = NULL; ++ } ++ ++ void copy(JavaFrameAnchor* src) { ++ // In order to make sure the transition state is valid for "this" ++ // We must clear _last_Java_sp before copying the rest of the new data ++ // ++ // Hack Alert: Temporary bugfix for 4717480/4721647 ++ // To act like previous version (pd_cache_state) don't NULL _last_Java_sp ++ // unless the value is changing ++ // ++ assert(src != NULL, "Src should not be NULL."); ++ if (_last_Java_sp != src->_last_Java_sp) { ++ _last_Java_sp = NULL; ++ OrderAccess::release(); ++ } ++ _last_Java_fp = src->_last_Java_fp; ++ _last_Java_pc = src->_last_Java_pc; ++ // Must be last so profiler will always see valid frame if has_last_frame() is true ++ _last_Java_sp = src->_last_Java_sp; ++ } ++ ++ bool walkable(void) { return _last_Java_sp != NULL && _last_Java_pc != NULL; } ++ ++ void make_walkable(); ++ ++ intptr_t* last_Java_sp(void) const { return _last_Java_sp; } ++ ++ const address last_Java_pc(void) { return _last_Java_pc; } ++ ++private: ++ ++ static ByteSize last_Java_fp_offset() { return byte_offset_of(JavaFrameAnchor, _last_Java_fp); } ++ ++public: ++ ++ void set_last_Java_sp(intptr_t* java_sp) { _last_Java_sp = java_sp; OrderAccess::release(); } ++ ++ intptr_t* last_Java_fp(void) { return _last_Java_fp; } ++ ++#endif // CPU_RISCV_JAVAFRAMEANCHOR_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp +@@ -0,0 +1,221 @@ ++/* ++ * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "gc/shared/barrierSet.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "memory/resourceArea.hpp" ++#include "prims/jniFastGetField.hpp" ++#include "prims/jvm_misc.hpp" ++#include "prims/jvmtiExport.hpp" ++#include "runtime/safepoint.hpp" ++ ++#define __ masm-> ++ ++#define BUFFER_SIZE 30*wordSize ++ ++// Instead of issuing a LoadLoad barrier we create an address ++// dependency between loads; this might be more efficient. ++ ++// Common register usage: ++// x10/f10: result ++// c_rarg0: jni env ++// c_rarg1: obj ++// c_rarg2: jfield id ++ ++static const Register robj = x13; ++static const Register rcounter = x14; ++static const Register roffset = x15; ++static const Register rcounter_addr = x16; ++static const Register result = x17; ++ ++address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { ++ const char *name; ++ switch (type) { ++ case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break; ++ case T_BYTE: name = "jni_fast_GetByteField"; break; ++ case T_CHAR: name = "jni_fast_GetCharField"; break; ++ case T_SHORT: name = "jni_fast_GetShortField"; break; ++ case T_INT: name = "jni_fast_GetIntField"; break; ++ case T_LONG: name = "jni_fast_GetLongField"; break; ++ case T_FLOAT: name = "jni_fast_GetFloatField"; break; ++ case T_DOUBLE: name = "jni_fast_GetDoubleField"; break; ++ default: ShouldNotReachHere(); ++ name = NULL; // unreachable ++ } ++ ResourceMark rm; ++ BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE); ++ CodeBuffer cbuf(blob); ++ MacroAssembler* masm = new MacroAssembler(&cbuf); ++ address fast_entry = __ pc(); ++ ++ Address target(SafepointSynchronize::safepoint_counter_addr()); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(rcounter_addr, target, offset); ++ __ addi(rcounter_addr, rcounter_addr, offset); ++ }); ++ ++ Label slow; ++ Address safepoint_counter_addr(rcounter_addr, 0); ++ __ lwu(rcounter, safepoint_counter_addr); ++ // An even value means there are no ongoing safepoint operations ++ __ test_bit(t0, rcounter, 0); ++ __ bnez(t0, slow); ++ ++ if (JvmtiExport::can_post_field_access()) { ++ // Using barrier to order wrt. JVMTI check and load of result. ++ __ membar(MacroAssembler::LoadLoad); ++ ++ // Check to see if a field access watch has been set before we ++ // take the fast path. ++ ExternalAddress target((address) JvmtiExport::get_field_access_count_addr()); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(result, target, offset); ++ __ lwu(result, Address(result, offset)); ++ }); ++ __ bnez(result, slow); ++ ++ __ mv(robj, c_rarg1); ++ } else { ++ // Using address dependency to order wrt. load of result. ++ __ xorr(robj, c_rarg1, rcounter); ++ __ xorr(robj, robj, rcounter); // obj, since ++ // robj ^ rcounter ^ rcounter == robj ++ // robj is address dependent on rcounter. ++ } ++ ++ // Both robj and t0 are clobbered by try_resolve_jobject_in_native. ++ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ assert_cond(bs != NULL); ++ bs->try_resolve_jobject_in_native(masm, c_rarg0, robj, t0, slow); ++ ++ __ srli(roffset, c_rarg2, 2); // offset ++ ++ assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); ++ speculative_load_pclist[count] = __ pc(); // Used by the segfault handler ++ __ add(roffset, robj, roffset); ++ ++ switch (type) { ++ case T_BOOLEAN: __ lbu(result, Address(roffset, 0)); break; ++ case T_BYTE: __ lb(result, Address(roffset, 0)); break; ++ case T_CHAR: __ lhu(result, Address(roffset, 0)); break; ++ case T_SHORT: __ lh(result, Address(roffset, 0)); break; ++ case T_INT: __ lw(result, Address(roffset, 0)); break; ++ case T_LONG: __ ld(result, Address(roffset, 0)); break; ++ case T_FLOAT: { ++ __ flw(f28, Address(roffset, 0)); // f28 as temporaries ++ __ fmv_x_w(result, f28); // f{31--0}-->x ++ break; ++ } ++ case T_DOUBLE: { ++ __ fld(f28, Address(roffset, 0)); // f28 as temporaries ++ __ fmv_x_d(result, f28); // d{63--0}-->x ++ break; ++ } ++ default: ShouldNotReachHere(); ++ } ++ ++ // Using acquire: Order JVMTI check and load of result wrt. succeeding check ++ // (LoadStore for volatile field). ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ ++ __ lw(t0, safepoint_counter_addr); ++ __ bne(rcounter, t0, slow); ++ ++ switch (type) { ++ case T_FLOAT: __ fmv_w_x(f10, result); break; ++ case T_DOUBLE: __ fmv_d_x(f10, result); break; ++ default: __ mv(x10, result); break; ++ } ++ __ ret(); ++ ++ slowcase_entry_pclist[count++] = __ pc(); ++ __ bind(slow); ++ address slow_case_addr; ++ switch (type) { ++ case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break; ++ case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break; ++ case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break; ++ case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break; ++ case T_INT: slow_case_addr = jni_GetIntField_addr(); break; ++ case T_LONG: slow_case_addr = jni_GetLongField_addr(); break; ++ case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; ++ case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break; ++ default: ShouldNotReachHere(); ++ slow_case_addr = NULL; // unreachable ++ } ++ ++ { ++ __ enter(); ++ ExternalAddress target(slow_case_addr); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ __ leave(); ++ __ ret(); ++ } ++ __ flush(); ++ ++ return fast_entry; ++} ++ ++ ++address JNI_FastGetField::generate_fast_get_boolean_field() { ++ return generate_fast_get_int_field0(T_BOOLEAN); ++} ++ ++address JNI_FastGetField::generate_fast_get_byte_field() { ++ return generate_fast_get_int_field0(T_BYTE); ++} ++ ++address JNI_FastGetField::generate_fast_get_char_field() { ++ return generate_fast_get_int_field0(T_CHAR); ++} ++ ++address JNI_FastGetField::generate_fast_get_short_field() { ++ return generate_fast_get_int_field0(T_SHORT); ++} ++ ++address JNI_FastGetField::generate_fast_get_int_field() { ++ return generate_fast_get_int_field0(T_INT); ++} ++ ++address JNI_FastGetField::generate_fast_get_long_field() { ++ return generate_fast_get_int_field0(T_LONG); ++} ++ ++address JNI_FastGetField::generate_fast_get_float_field() { ++ return generate_fast_get_int_field0(T_FLOAT); ++} ++ ++address JNI_FastGetField::generate_fast_get_double_field() { ++ return generate_fast_get_int_field0(T_DOUBLE); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/jniTypes_riscv.hpp +@@ -0,0 +1,106 @@ ++/* ++ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_JNITYPES_RISCV_HPP ++#define CPU_RISCV_JNITYPES_RISCV_HPP ++ ++#include "jni.h" ++#include "memory/allStatic.hpp" ++#include "oops/oop.hpp" ++ ++// This file holds platform-dependent routines used to write primitive jni ++// types to the array of arguments passed into JavaCalls::call ++ ++class JNITypes : private AllStatic { ++ // These functions write a java primitive type (in native format) ++ // to a java stack slot array to be passed as an argument to JavaCalls:calls. ++ // I.e., they are functionally 'push' operations if they have a 'pos' ++ // formal parameter. Note that jlong's and jdouble's are written ++ // _in reverse_ of the order in which they appear in the interpreter ++ // stack. This is because call stubs (see stubGenerator_sparc.cpp) ++ // reverse the argument list constructed by JavaCallArguments (see ++ // javaCalls.hpp). ++ ++public: ++ // Ints are stored in native format in one JavaCallArgument slot at *to. ++ static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; } ++ static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; } ++ static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; } ++ ++ // Longs are stored in native format in one JavaCallArgument slot at ++ // *(to+1). ++ static inline void put_long(jlong from, intptr_t *to) { ++ *(jlong*) (to + 1) = from; ++ } ++ ++ static inline void put_long(jlong from, intptr_t *to, int& pos) { ++ *(jlong*) (to + 1 + pos) = from; ++ pos += 2; ++ } ++ ++ static inline void put_long(jlong *from, intptr_t *to, int& pos) { ++ *(jlong*) (to + 1 + pos) = *from; ++ pos += 2; ++ } ++ ++ // Oops are stored in native format in one JavaCallArgument slot at *to. ++ static inline void put_obj(const Handle& from_handle, intptr_t *to, int& pos) { *(to + pos++) = (intptr_t)from_handle.raw_value(); } ++ static inline void put_obj(jobject from_handle, intptr_t *to, int& pos) { *(to + pos++) = (intptr_t)from_handle; } ++ ++ // Floats are stored in native format in one JavaCallArgument slot at *to. ++ static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; } ++ static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; } ++ static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; } ++ ++#undef _JNI_SLOT_OFFSET ++#define _JNI_SLOT_OFFSET 1 ++ // Doubles are stored in native word format in one JavaCallArgument ++ // slot at *(to+1). ++ static inline void put_double(jdouble from, intptr_t *to) { ++ *(jdouble*) (to + 1) = from; ++ } ++ ++ static inline void put_double(jdouble from, intptr_t *to, int& pos) { ++ *(jdouble*) (to + 1 + pos) = from; ++ pos += 2; ++ } ++ ++ static inline void put_double(jdouble *from, intptr_t *to, int& pos) { ++ *(jdouble*) (to + 1 + pos) = *from; ++ pos += 2; ++ } ++ ++ // The get_xxx routines, on the other hand, actually _do_ fetch ++ // java primitive types from the interpreter stack. ++ // No need to worry about alignment on Intel. ++ static inline jint get_int (intptr_t *from) { return *(jint *) from; } ++ static inline jlong get_long (intptr_t *from) { return *(jlong *) (from + _JNI_SLOT_OFFSET); } ++ static inline oop get_obj (intptr_t *from) { return *(oop *) from; } ++ static inline jfloat get_float (intptr_t *from) { return *(jfloat *) from; } ++ static inline jdouble get_double(intptr_t *from) { return *(jdouble *)(from + _JNI_SLOT_OFFSET); } ++#undef _JNI_SLOT_OFFSET ++}; ++ ++#endif // CPU_RISCV_JNITYPES_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +@@ -0,0 +1,4392 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "asm/assembler.inline.hpp" ++#include "compiler/disassembler.hpp" ++#include "gc/shared/barrierSet.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "gc/shared/cardTable.hpp" ++#include "gc/shared/cardTableBarrierSet.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "interpreter/bytecodeHistogram.hpp" ++#include "interpreter/interpreter.hpp" ++#include "memory/resourceArea.hpp" ++#include "memory/universe.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/accessDecorators.hpp" ++#include "oops/compressedOops.inline.hpp" ++#include "oops/klass.inline.hpp" ++#include "oops/oop.hpp" ++#include "runtime/biasedLocking.hpp" ++#include "runtime/interfaceSupport.inline.hpp" ++#include "runtime/jniHandles.inline.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/thread.hpp" ++#include "utilities/powerOfTwo.hpp" ++#ifdef COMPILER2 ++#include "opto/compile.hpp" ++#include "opto/node.hpp" ++#include "opto/output.hpp" ++#endif ++ ++#ifdef PRODUCT ++#define BLOCK_COMMENT(str) /* nothing */ ++#else ++#define BLOCK_COMMENT(str) block_comment(str) ++#endif ++#define BIND(label) bind(label); __ BLOCK_COMMENT(#label ":") ++ ++static void pass_arg0(MacroAssembler* masm, Register arg) { ++ if (c_rarg0 != arg) { ++ masm->mv(c_rarg0, arg); ++ } ++} ++ ++static void pass_arg1(MacroAssembler* masm, Register arg) { ++ if (c_rarg1 != arg) { ++ masm->mv(c_rarg1, arg); ++ } ++} ++ ++static void pass_arg2(MacroAssembler* masm, Register arg) { ++ if (c_rarg2 != arg) { ++ masm->mv(c_rarg2, arg); ++ } ++} ++ ++static void pass_arg3(MacroAssembler* masm, Register arg) { ++ if (c_rarg3 != arg) { ++ masm->mv(c_rarg3, arg); ++ } ++} ++ ++void MacroAssembler::align(int modulus, int extra_offset) { ++ CompressibleRegion cr(this); ++ while ((offset() + extra_offset) % modulus != 0) { nop(); } ++} ++ ++void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) { ++ call_VM_base(oop_result, noreg, noreg, entry_point, number_of_arguments, check_exceptions); ++} ++ ++// Implementation of call_VM versions ++ ++void MacroAssembler::call_VM(Register oop_result, ++ address entry_point, ++ bool check_exceptions) { ++ call_VM_helper(oop_result, entry_point, 0, check_exceptions); ++} ++ ++void MacroAssembler::call_VM(Register oop_result, ++ address entry_point, ++ Register arg_1, ++ bool check_exceptions) { ++ pass_arg1(this, arg_1); ++ call_VM_helper(oop_result, entry_point, 1, check_exceptions); ++} ++ ++void MacroAssembler::call_VM(Register oop_result, ++ address entry_point, ++ Register arg_1, ++ Register arg_2, ++ bool check_exceptions) { ++ assert(arg_1 != c_rarg2, "smashed arg"); ++ pass_arg2(this, arg_2); ++ pass_arg1(this, arg_1); ++ call_VM_helper(oop_result, entry_point, 2, check_exceptions); ++} ++ ++void MacroAssembler::call_VM(Register oop_result, ++ address entry_point, ++ Register arg_1, ++ Register arg_2, ++ Register arg_3, ++ bool check_exceptions) { ++ assert(arg_1 != c_rarg3, "smashed arg"); ++ assert(arg_2 != c_rarg3, "smashed arg"); ++ pass_arg3(this, arg_3); ++ ++ assert(arg_1 != c_rarg2, "smashed arg"); ++ pass_arg2(this, arg_2); ++ ++ pass_arg1(this, arg_1); ++ call_VM_helper(oop_result, entry_point, 3, check_exceptions); ++} ++ ++void MacroAssembler::call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ int number_of_arguments, ++ bool check_exceptions) { ++ call_VM_base(oop_result, xthread, last_java_sp, entry_point, number_of_arguments, check_exceptions); ++} ++ ++void MacroAssembler::call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ Register arg_1, ++ bool check_exceptions) { ++ pass_arg1(this, arg_1); ++ call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); ++} ++ ++void MacroAssembler::call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ Register arg_1, ++ Register arg_2, ++ bool check_exceptions) { ++ ++ assert(arg_1 != c_rarg2, "smashed arg"); ++ pass_arg2(this, arg_2); ++ pass_arg1(this, arg_1); ++ call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); ++} ++ ++void MacroAssembler::call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ Register arg_1, ++ Register arg_2, ++ Register arg_3, ++ bool check_exceptions) { ++ assert(arg_1 != c_rarg3, "smashed arg"); ++ assert(arg_2 != c_rarg3, "smashed arg"); ++ pass_arg3(this, arg_3); ++ assert(arg_1 != c_rarg2, "smashed arg"); ++ pass_arg2(this, arg_2); ++ pass_arg1(this, arg_1); ++ call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); ++} ++ ++// these are no-ops overridden by InterpreterMacroAssembler ++void MacroAssembler::check_and_handle_earlyret(Register java_thread) {} ++void MacroAssembler::check_and_handle_popframe(Register java_thread) {} ++ ++// Calls to C land ++// ++// When entering C land, the fp, & esp of the last Java frame have to be recorded ++// in the (thread-local) JavaThread object. When leaving C land, the last Java fp ++// has to be reset to 0. This is required to allow proper stack traversal. ++void MacroAssembler::set_last_Java_frame(Register last_java_sp, ++ Register last_java_fp, ++ Register last_java_pc, ++ Register tmp) { ++ ++ if (last_java_pc->is_valid()) { ++ sd(last_java_pc, Address(xthread, ++ JavaThread::frame_anchor_offset() + ++ JavaFrameAnchor::last_Java_pc_offset())); ++ } ++ ++ // determine last_java_sp register ++ if (last_java_sp == sp) { ++ mv(tmp, sp); ++ last_java_sp = tmp; ++ } else if (!last_java_sp->is_valid()) { ++ last_java_sp = esp; ++ } ++ ++ sd(last_java_sp, Address(xthread, JavaThread::last_Java_sp_offset())); ++ ++ // last_java_fp is optional ++ if (last_java_fp->is_valid()) { ++ sd(last_java_fp, Address(xthread, JavaThread::last_Java_fp_offset())); ++ } ++} ++ ++void MacroAssembler::set_last_Java_frame(Register last_java_sp, ++ Register last_java_fp, ++ address last_java_pc, ++ Register tmp) { ++ assert(last_java_pc != NULL, "must provide a valid PC"); ++ ++ la(tmp, last_java_pc); ++ sd(tmp, Address(xthread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset())); ++ ++ set_last_Java_frame(last_java_sp, last_java_fp, noreg, tmp); ++} ++ ++void MacroAssembler::set_last_Java_frame(Register last_java_sp, ++ Register last_java_fp, ++ Label &L, ++ Register tmp) { ++ if (L.is_bound()) { ++ set_last_Java_frame(last_java_sp, last_java_fp, target(L), tmp); ++ } else { ++ L.add_patch_at(code(), locator()); ++ IncompressibleRegion ir(this); // the label address will be patched back. ++ set_last_Java_frame(last_java_sp, last_java_fp, pc() /* Patched later */, tmp); ++ } ++} ++ ++void MacroAssembler::reset_last_Java_frame(bool clear_fp) { ++ // we must set sp to zero to clear frame ++ sd(zr, Address(xthread, JavaThread::last_Java_sp_offset())); ++ ++ // must clear fp, so that compiled frames are not confused; it is ++ // possible that we need it only for debugging ++ if (clear_fp) { ++ sd(zr, Address(xthread, JavaThread::last_Java_fp_offset())); ++ } ++ ++ // Always clear the pc because it could have been set by make_walkable() ++ sd(zr, Address(xthread, JavaThread::last_Java_pc_offset())); ++} ++ ++void MacroAssembler::call_VM_base(Register oop_result, ++ Register java_thread, ++ Register last_java_sp, ++ address entry_point, ++ int number_of_arguments, ++ bool check_exceptions) { ++ // determine java_thread register ++ if (!java_thread->is_valid()) { ++ java_thread = xthread; ++ } ++ // determine last_java_sp register ++ if (!last_java_sp->is_valid()) { ++ last_java_sp = esp; ++ } ++ ++ // debugging support ++ assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); ++ assert(java_thread == xthread, "unexpected register"); ++ ++ assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); ++ assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); ++ ++ // push java thread (becomes first argument of C function) ++ mv(c_rarg0, java_thread); ++ ++ // set last Java frame before call ++ assert(last_java_sp != fp, "can't use fp"); ++ ++ Label l; ++ set_last_Java_frame(last_java_sp, fp, l, t0); ++ ++ // do the call, remove parameters ++ MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments, &l); ++ ++ // reset last Java frame ++ // Only interpreter should have to clear fp ++ reset_last_Java_frame(true); ++ ++ // C++ interp handles this in the interpreter ++ check_and_handle_popframe(java_thread); ++ check_and_handle_earlyret(java_thread); ++ ++ if (check_exceptions) { ++ // check for pending exceptions (java_thread is set upon return) ++ ld(t0, Address(java_thread, in_bytes(Thread::pending_exception_offset()))); ++ Label ok; ++ beqz(t0, ok); ++ RuntimeAddress target(StubRoutines::forward_exception_entry()); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(t0, target, offset); ++ jalr(x0, t0, offset); ++ }); ++ bind(ok); ++ } ++ ++ // get oop result if there is one and reset the value in the thread ++ if (oop_result->is_valid()) { ++ get_vm_result(oop_result, java_thread); ++ } ++} ++ ++void MacroAssembler::get_vm_result(Register oop_result, Register java_thread) { ++ ld(oop_result, Address(java_thread, JavaThread::vm_result_offset())); ++ sd(zr, Address(java_thread, JavaThread::vm_result_offset())); ++ verify_oop(oop_result, "broken oop in call_VM_base"); ++} ++ ++void MacroAssembler::get_vm_result_2(Register metadata_result, Register java_thread) { ++ ld(metadata_result, Address(java_thread, JavaThread::vm_result_2_offset())); ++ sd(zr, Address(java_thread, JavaThread::vm_result_2_offset())); ++} ++ ++void MacroAssembler::clinit_barrier(Register klass, Register tmp, Label* L_fast_path, Label* L_slow_path) { ++ assert(L_fast_path != NULL || L_slow_path != NULL, "at least one is required"); ++ assert_different_registers(klass, xthread, tmp); ++ ++ Label L_fallthrough, L_tmp; ++ if (L_fast_path == NULL) { ++ L_fast_path = &L_fallthrough; ++ } else if (L_slow_path == NULL) { ++ L_slow_path = &L_fallthrough; ++ } ++ ++ // Fast path check: class is fully initialized ++ lbu(tmp, Address(klass, InstanceKlass::init_state_offset())); ++ sub(tmp, tmp, InstanceKlass::fully_initialized); ++ beqz(tmp, *L_fast_path); ++ ++ // Fast path check: current thread is initializer thread ++ ld(tmp, Address(klass, InstanceKlass::init_thread_offset())); ++ ++ if (L_slow_path == &L_fallthrough) { ++ beq(xthread, tmp, *L_fast_path); ++ bind(*L_slow_path); ++ } else if (L_fast_path == &L_fallthrough) { ++ bne(xthread, tmp, *L_slow_path); ++ bind(*L_fast_path); ++ } else { ++ Unimplemented(); ++ } ++} ++ ++void MacroAssembler::verify_oop(Register reg, const char* s) { ++ if (!VerifyOops) { return; } ++ ++ // Pass register number to verify_oop_subroutine ++ const char* b = NULL; ++ { ++ ResourceMark rm; ++ stringStream ss; ++ ss.print("verify_oop: %s: %s", reg->name(), s); ++ b = code_string(ss.as_string()); ++ } ++ BLOCK_COMMENT("verify_oop {"); ++ ++ push_reg(RegSet::of(ra, t0, t1, c_rarg0), sp); ++ ++ mv(c_rarg0, reg); // c_rarg0 : x10 ++ { ++ // The length of the instruction sequence emitted should not depend ++ // on the address of the char buffer so that the size of mach nodes for ++ // scratch emit and normal emit matches. ++ IncompressibleRegion ir(this); // Fixed length ++ movptr(t0, (address) b); ++ } ++ ++ // call indirectly to solve generation ordering problem ++ ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address()); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(t1, target, offset); ++ ld(t1, Address(t1, offset)); ++ }); ++ jalr(t1); ++ ++ pop_reg(RegSet::of(ra, t0, t1, c_rarg0), sp); ++ ++ BLOCK_COMMENT("} verify_oop"); ++} ++ ++void MacroAssembler::verify_oop_addr(Address addr, const char* s) { ++ if (!VerifyOops) { ++ return; ++ } ++ ++ const char* b = NULL; ++ { ++ ResourceMark rm; ++ stringStream ss; ++ ss.print("verify_oop_addr: %s", s); ++ b = code_string(ss.as_string()); ++ } ++ BLOCK_COMMENT("verify_oop_addr {"); ++ ++ push_reg(RegSet::of(ra, t0, t1, c_rarg0), sp); ++ ++ if (addr.uses(sp)) { ++ la(x10, addr); ++ ld(x10, Address(x10, 4 * wordSize)); ++ } else { ++ ld(x10, addr); ++ } ++ ++ { ++ // The length of the instruction sequence emitted should not depend ++ // on the address of the char buffer so that the size of mach nodes for ++ // scratch emit and normal emit matches. ++ IncompressibleRegion ir(this); // Fixed length ++ movptr(t0, (address) b); ++ } ++ ++ // call indirectly to solve generation ordering problem ++ ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address()); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(t1, target, offset); ++ ld(t1, Address(t1, offset)); ++ }); ++ jalr(t1); ++ ++ pop_reg(RegSet::of(ra, t0, t1, c_rarg0), sp); ++ ++ BLOCK_COMMENT("} verify_oop_addr"); ++} ++ ++Address MacroAssembler::argument_address(RegisterOrConstant arg_slot, ++ int extra_slot_offset) { ++ // cf. TemplateTable::prepare_invoke(), if (load_receiver). ++ int stackElementSize = Interpreter::stackElementSize; ++ int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0); ++#ifdef ASSERT ++ int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1); ++ assert(offset1 - offset == stackElementSize, "correct arithmetic"); ++#endif ++ if (arg_slot.is_constant()) { ++ return Address(esp, arg_slot.as_constant() * stackElementSize + offset); ++ } else { ++ assert_different_registers(t0, arg_slot.as_register()); ++ shadd(t0, arg_slot.as_register(), esp, t0, exact_log2(stackElementSize)); ++ return Address(t0, offset); ++ } ++} ++ ++#ifndef PRODUCT ++extern "C" void findpc(intptr_t x); ++#endif ++ ++void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[]) ++{ ++ // In order to get locks to work, we need to fake a in_VM state ++ if (ShowMessageBoxOnError) { ++ JavaThread* thread = JavaThread::current(); ++ JavaThreadState saved_state = thread->thread_state(); ++ thread->set_thread_state(_thread_in_vm); ++#ifndef PRODUCT ++ if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { ++ ttyLocker ttyl; ++ BytecodeCounter::print(); ++ } ++#endif ++ if (os::message_box(msg, "Execution stopped, print registers?")) { ++ ttyLocker ttyl; ++ tty->print_cr(" pc = 0x%016lx", pc); ++#ifndef PRODUCT ++ tty->cr(); ++ findpc(pc); ++ tty->cr(); ++#endif ++ tty->print_cr(" x0 = 0x%016lx", regs[0]); ++ tty->print_cr(" x1 = 0x%016lx", regs[1]); ++ tty->print_cr(" x2 = 0x%016lx", regs[2]); ++ tty->print_cr(" x3 = 0x%016lx", regs[3]); ++ tty->print_cr(" x4 = 0x%016lx", regs[4]); ++ tty->print_cr(" x5 = 0x%016lx", regs[5]); ++ tty->print_cr(" x6 = 0x%016lx", regs[6]); ++ tty->print_cr(" x7 = 0x%016lx", regs[7]); ++ tty->print_cr(" x8 = 0x%016lx", regs[8]); ++ tty->print_cr(" x9 = 0x%016lx", regs[9]); ++ tty->print_cr("x10 = 0x%016lx", regs[10]); ++ tty->print_cr("x11 = 0x%016lx", regs[11]); ++ tty->print_cr("x12 = 0x%016lx", regs[12]); ++ tty->print_cr("x13 = 0x%016lx", regs[13]); ++ tty->print_cr("x14 = 0x%016lx", regs[14]); ++ tty->print_cr("x15 = 0x%016lx", regs[15]); ++ tty->print_cr("x16 = 0x%016lx", regs[16]); ++ tty->print_cr("x17 = 0x%016lx", regs[17]); ++ tty->print_cr("x18 = 0x%016lx", regs[18]); ++ tty->print_cr("x19 = 0x%016lx", regs[19]); ++ tty->print_cr("x20 = 0x%016lx", regs[20]); ++ tty->print_cr("x21 = 0x%016lx", regs[21]); ++ tty->print_cr("x22 = 0x%016lx", regs[22]); ++ tty->print_cr("x23 = 0x%016lx", regs[23]); ++ tty->print_cr("x24 = 0x%016lx", regs[24]); ++ tty->print_cr("x25 = 0x%016lx", regs[25]); ++ tty->print_cr("x26 = 0x%016lx", regs[26]); ++ tty->print_cr("x27 = 0x%016lx", regs[27]); ++ tty->print_cr("x28 = 0x%016lx", regs[28]); ++ tty->print_cr("x30 = 0x%016lx", regs[30]); ++ tty->print_cr("x31 = 0x%016lx", regs[31]); ++ BREAKPOINT; ++ } ++ } ++ fatal("DEBUG MESSAGE: %s", msg); ++} ++ ++void MacroAssembler::resolve_jobject(Register value, Register thread, Register tmp) { ++ Label done, not_weak; ++ beqz(value, done); // Use NULL as-is. ++ ++ // Test for jweak tag. ++ test_bit(t0, value, exact_log2(JNIHandles::weak_tag_mask)); ++ beqz(t0, not_weak); ++ ++ // Resolve jweak. ++ access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, value, ++ Address(value, -JNIHandles::weak_tag_value), tmp, thread); ++ verify_oop(value); ++ j(done); ++ ++ bind(not_weak); ++ // Resolve (untagged) jobject. ++ access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, 0), tmp, thread); ++ verify_oop(value); ++ bind(done); ++} ++ ++void MacroAssembler::stop(const char* msg) { ++ BLOCK_COMMENT(msg); ++ illegal_instruction(Assembler::csr::time); ++ emit_int64((uintptr_t)msg); ++} ++ ++void MacroAssembler::unimplemented(const char* what) { ++ const char* buf = NULL; ++ { ++ ResourceMark rm; ++ stringStream ss; ++ ss.print("unimplemented: %s", what); ++ buf = code_string(ss.as_string()); ++ } ++ stop(buf); ++} ++ ++void MacroAssembler::emit_static_call_stub() { ++ IncompressibleRegion ir(this); // Fixed length: see CompiledStaticCall::to_interp_stub_size(). ++ // CompiledDirectStaticCall::set_to_interpreted knows the ++ // exact layout of this stub. ++ ++ mov_metadata(xmethod, (Metadata*)NULL); ++ ++ // Jump to the entry point of the i2c stub. ++ int32_t offset = 0; ++ movptr(t0, 0, offset); ++ jalr(x0, t0, offset); ++} ++ ++void MacroAssembler::call_VM_leaf_base(address entry_point, ++ int number_of_arguments, ++ Label *retaddr) { ++ push_reg(RegSet::of(t0, xmethod), sp); // push << t0 & xmethod >> to sp ++ call(entry_point); ++ if (retaddr != NULL) { ++ bind(*retaddr); ++ } ++ pop_reg(RegSet::of(t0, xmethod), sp); // pop << t0 & xmethod >> from sp ++} ++ ++void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) { ++ call_VM_leaf_base(entry_point, number_of_arguments); ++} ++ ++void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0) { ++ pass_arg0(this, arg_0); ++ call_VM_leaf_base(entry_point, 1); ++} ++ ++void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, Register arg_1) { ++ pass_arg0(this, arg_0); ++ pass_arg1(this, arg_1); ++ call_VM_leaf_base(entry_point, 2); ++} ++ ++void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, ++ Register arg_1, Register arg_2) { ++ pass_arg0(this, arg_0); ++ pass_arg1(this, arg_1); ++ pass_arg2(this, arg_2); ++ call_VM_leaf_base(entry_point, 3); ++} ++ ++void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0) { ++ pass_arg0(this, arg_0); ++ MacroAssembler::call_VM_leaf_base(entry_point, 1); ++} ++ ++void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1) { ++ ++ assert(arg_0 != c_rarg1, "smashed arg"); ++ pass_arg1(this, arg_1); ++ pass_arg0(this, arg_0); ++ MacroAssembler::call_VM_leaf_base(entry_point, 2); ++} ++ ++void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2) { ++ assert(arg_0 != c_rarg2, "smashed arg"); ++ assert(arg_1 != c_rarg2, "smashed arg"); ++ pass_arg2(this, arg_2); ++ assert(arg_0 != c_rarg1, "smashed arg"); ++ pass_arg1(this, arg_1); ++ pass_arg0(this, arg_0); ++ MacroAssembler::call_VM_leaf_base(entry_point, 3); ++} ++ ++void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2, Register arg_3) { ++ assert(arg_0 != c_rarg3, "smashed arg"); ++ assert(arg_1 != c_rarg3, "smashed arg"); ++ assert(arg_2 != c_rarg3, "smashed arg"); ++ pass_arg3(this, arg_3); ++ assert(arg_0 != c_rarg2, "smashed arg"); ++ assert(arg_1 != c_rarg2, "smashed arg"); ++ pass_arg2(this, arg_2); ++ assert(arg_0 != c_rarg1, "smashed arg"); ++ pass_arg1(this, arg_1); ++ pass_arg0(this, arg_0); ++ MacroAssembler::call_VM_leaf_base(entry_point, 4); ++} ++ ++void MacroAssembler::la(Register Rd, const address dest) { ++ int64_t offset = dest - pc(); ++ if (is_simm32(offset)) { ++ auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit ++ addi(Rd, Rd, ((int64_t)offset << 52) >> 52); ++ } else { ++ movptr(Rd, dest); ++ } ++} ++ ++void MacroAssembler::la(Register Rd, const Address &adr) { ++ switch (adr.getMode()) { ++ case Address::literal: { ++ relocInfo::relocType rtype = adr.rspec().reloc()->type(); ++ if (rtype == relocInfo::none) { ++ mv(Rd, (intptr_t)(adr.target())); ++ } else { ++ relocate(adr.rspec(), [&] { ++ movptr(Rd, adr.target()); ++ }); ++ } ++ break; ++ } ++ case Address::base_plus_offset: { ++ Address new_adr = legitimize_address(Rd, adr); ++ if (!(new_adr.base() == Rd && new_adr.offset() == 0)) { ++ addi(Rd, new_adr.base(), new_adr.offset()); ++ } ++ break; ++ } ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void MacroAssembler::la(Register Rd, Label &label) { ++ IncompressibleRegion ir(this); // the label address may be patched back. ++ la(Rd, target(label)); ++} ++ ++void MacroAssembler::li32(Register Rd, int32_t imm) { ++ // int32_t is in range 0x8000 0000 ~ 0x7fff ffff, and imm[31] is the sign bit ++ int64_t upper = imm, lower = imm; ++ lower = (imm << 20) >> 20; ++ upper -= lower; ++ upper = (int32_t)upper; ++ // lui Rd, imm[31:12] + imm[11] ++ lui(Rd, upper); ++ // use addiw to distinguish li32 to li64 ++ addiw(Rd, Rd, lower); ++} ++ ++void MacroAssembler::li64(Register Rd, int64_t imm) { ++ // Load upper 32 bits. upper = imm[63:32], but if imm[31] == 1 or ++ // (imm[31:20] == 0x7ff && imm[19] == 1), upper = imm[63:32] + 1. ++ int64_t lower = imm & 0xffffffff; ++ lower -= ((lower << 44) >> 44); ++ int64_t tmp_imm = ((uint64_t)(imm & 0xffffffff00000000)) + (uint64_t)lower; ++ int32_t upper = (tmp_imm - (int32_t)lower) >> 32; ++ ++ // Load upper 32 bits ++ int64_t up = upper, lo = upper; ++ lo = (lo << 52) >> 52; ++ up -= lo; ++ up = (int32_t)up; ++ lui(Rd, up); ++ addi(Rd, Rd, lo); ++ ++ // Load the rest 32 bits. ++ slli(Rd, Rd, 12); ++ addi(Rd, Rd, (int32_t)lower >> 20); ++ slli(Rd, Rd, 12); ++ lower = ((int32_t)imm << 12) >> 20; ++ addi(Rd, Rd, lower); ++ slli(Rd, Rd, 8); ++ lower = imm & 0xff; ++ addi(Rd, Rd, lower); ++} ++ ++void MacroAssembler::li(Register Rd, int64_t imm) { ++ // int64_t is in range 0x8000 0000 0000 0000 ~ 0x7fff ffff ffff ffff ++ // li -> c.li ++ if (do_compress() && (is_simm6(imm) && Rd != x0)) { ++ c_li(Rd, imm); ++ return; ++ } ++ ++ int shift = 12; ++ int64_t upper = imm, lower = imm; ++ // Split imm to a lower 12-bit sign-extended part and the remainder, ++ // because addi will sign-extend the lower imm. ++ lower = ((int32_t)imm << 20) >> 20; ++ upper -= lower; ++ ++ // Test whether imm is a 32-bit integer. ++ if (!(((imm) & ~(int64_t)0x7fffffff) == 0 || ++ (((imm) & ~(int64_t)0x7fffffff) == ~(int64_t)0x7fffffff))) { ++ while (((upper >> shift) & 1) == 0) { shift++; } ++ upper >>= shift; ++ li(Rd, upper); ++ slli(Rd, Rd, shift); ++ if (lower != 0) { ++ addi(Rd, Rd, lower); ++ } ++ } else { ++ // 32-bit integer ++ Register hi_Rd = zr; ++ if (upper != 0) { ++ lui(Rd, (int32_t)upper); ++ hi_Rd = Rd; ++ } ++ if (lower != 0 || hi_Rd == zr) { ++ addiw(Rd, hi_Rd, lower); ++ } ++ } ++} ++ ++#define INSN(NAME, REGISTER) \ ++ void MacroAssembler::NAME(const address dest, Register temp) { \ ++ assert_cond(dest != NULL); \ ++ int64_t distance = dest - pc(); \ ++ if (is_simm21(distance) && ((distance % 2) == 0)) { \ ++ Assembler::jal(REGISTER, distance); \ ++ } else { \ ++ assert(temp != noreg, "expecting a register"); \ ++ int32_t offset = 0; \ ++ movptr(temp, dest, offset); \ ++ Assembler::jalr(REGISTER, temp, offset); \ ++ } \ ++ } \ ++ ++ INSN(j, x0); ++ INSN(jal, x1); ++ ++#undef INSN ++ ++#define INSN(NAME, REGISTER) \ ++ void MacroAssembler::NAME(const Address &adr, Register temp) { \ ++ switch (adr.getMode()) { \ ++ case Address::literal: { \ ++ relocate(adr.rspec()); \ ++ NAME(adr.target(), temp); \ ++ break; \ ++ } \ ++ case Address::base_plus_offset: { \ ++ int32_t offset = ((int32_t)adr.offset() << 20) >> 20; \ ++ la(temp, Address(adr.base(), adr.offset() - offset)); \ ++ Assembler::jalr(REGISTER, temp, offset); \ ++ break; \ ++ } \ ++ default: \ ++ ShouldNotReachHere(); \ ++ } \ ++ } ++ ++ INSN(j, x0); ++ INSN(jal, x1); ++ ++#undef INSN ++ ++#define INSN(NAME) \ ++ void MacroAssembler::NAME(Register Rd, const address dest, Register temp) { \ ++ assert_cond(dest != NULL); \ ++ int64_t distance = dest - pc(); \ ++ if (is_simm21(distance) && ((distance % 2) == 0)) { \ ++ Assembler::NAME(Rd, distance); \ ++ } else { \ ++ assert_different_registers(Rd, temp); \ ++ int32_t offset = 0; \ ++ movptr(temp, dest, offset); \ ++ jalr(Rd, temp, offset); \ ++ } \ ++ } \ ++ void MacroAssembler::NAME(Register Rd, Label &L, Register temp) { \ ++ assert_different_registers(Rd, temp); \ ++ wrap_label(Rd, L, temp, &MacroAssembler::NAME); \ ++ } ++ ++ INSN(jal); ++ ++#undef INSN ++ ++#define INSN(NAME, REGISTER) \ ++ void MacroAssembler::NAME(Label &l, Register temp) { \ ++ jal(REGISTER, l, temp); \ ++ } \ ++ ++ INSN(j, x0); ++ INSN(jal, x1); ++ ++#undef INSN ++ ++void MacroAssembler::wrap_label(Register Rt, Label &L, Register tmp, load_insn_by_temp insn) { ++ if (L.is_bound()) { ++ (this->*insn)(Rt, target(L), tmp); ++ } else { ++ L.add_patch_at(code(), locator()); ++ (this->*insn)(Rt, pc(), tmp); ++ } ++} ++ ++void MacroAssembler::wrap_label(Register Rt, Label &L, jal_jalr_insn insn) { ++ if (L.is_bound()) { ++ (this->*insn)(Rt, target(L)); ++ } else { ++ L.add_patch_at(code(), locator()); ++ (this->*insn)(Rt, pc()); ++ } ++} ++ ++void MacroAssembler::wrap_label(Register r1, Register r2, Label &L, ++ compare_and_branch_insn insn, ++ compare_and_branch_label_insn neg_insn, bool is_far) { ++ if (is_far) { ++ Label done; ++ (this->*neg_insn)(r1, r2, done, /* is_far */ false); ++ j(L); ++ bind(done); ++ } else { ++ if (L.is_bound()) { ++ (this->*insn)(r1, r2, target(L)); ++ } else { ++ L.add_patch_at(code(), locator()); ++ (this->*insn)(r1, r2, pc()); ++ } ++ } ++} ++ ++#define INSN(NAME, NEG_INSN) \ ++ void MacroAssembler::NAME(Register Rs1, Register Rs2, Label &L, bool is_far) { \ ++ wrap_label(Rs1, Rs2, L, &MacroAssembler::NAME, &MacroAssembler::NEG_INSN, is_far); \ ++ } ++ ++ INSN(beq, bne); ++ INSN(bne, beq); ++ INSN(blt, bge); ++ INSN(bge, blt); ++ INSN(bltu, bgeu); ++ INSN(bgeu, bltu); ++ ++#undef INSN ++ ++#define INSN(NAME) \ ++ void MacroAssembler::NAME##z(Register Rs, const address dest) { \ ++ NAME(Rs, zr, dest); \ ++ } \ ++ void MacroAssembler::NAME##z(Register Rs, Label &l, bool is_far) { \ ++ NAME(Rs, zr, l, is_far); \ ++ } \ ++ ++ INSN(beq); ++ INSN(bne); ++ INSN(blt); ++ INSN(ble); ++ INSN(bge); ++ INSN(bgt); ++ ++#undef INSN ++ ++#define INSN(NAME, NEG_INSN) \ ++ void MacroAssembler::NAME(Register Rs, Register Rt, const address dest) { \ ++ NEG_INSN(Rt, Rs, dest); \ ++ } \ ++ void MacroAssembler::NAME(Register Rs, Register Rt, Label &l, bool is_far) { \ ++ NEG_INSN(Rt, Rs, l, is_far); \ ++ } ++ ++ INSN(bgt, blt); ++ INSN(ble, bge); ++ INSN(bgtu, bltu); ++ INSN(bleu, bgeu); ++ ++#undef INSN ++ ++// Float compare branch instructions ++ ++#define INSN(NAME, FLOATCMP, BRANCH) \ ++ void MacroAssembler::float_##NAME(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far, bool is_unordered) { \ ++ FLOATCMP##_s(t0, Rs1, Rs2); \ ++ BRANCH(t0, l, is_far); \ ++ } \ ++ void MacroAssembler::double_##NAME(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far, bool is_unordered) { \ ++ FLOATCMP##_d(t0, Rs1, Rs2); \ ++ BRANCH(t0, l, is_far); \ ++ } ++ ++ INSN(beq, feq, bnez); ++ INSN(bne, feq, beqz); ++ ++#undef INSN ++ ++ ++#define INSN(NAME, FLOATCMP1, FLOATCMP2) \ ++ void MacroAssembler::float_##NAME(FloatRegister Rs1, FloatRegister Rs2, Label &l, \ ++ bool is_far, bool is_unordered) { \ ++ if (is_unordered) { \ ++ /* jump if either source is NaN or condition is expected */ \ ++ FLOATCMP2##_s(t0, Rs2, Rs1); \ ++ beqz(t0, l, is_far); \ ++ } else { \ ++ /* jump if no NaN in source and condition is expected */ \ ++ FLOATCMP1##_s(t0, Rs1, Rs2); \ ++ bnez(t0, l, is_far); \ ++ } \ ++ } \ ++ void MacroAssembler::double_##NAME(FloatRegister Rs1, FloatRegister Rs2, Label &l, \ ++ bool is_far, bool is_unordered) { \ ++ if (is_unordered) { \ ++ /* jump if either source is NaN or condition is expected */ \ ++ FLOATCMP2##_d(t0, Rs2, Rs1); \ ++ beqz(t0, l, is_far); \ ++ } else { \ ++ /* jump if no NaN in source and condition is expected */ \ ++ FLOATCMP1##_d(t0, Rs1, Rs2); \ ++ bnez(t0, l, is_far); \ ++ } \ ++ } ++ ++ INSN(ble, fle, flt); ++ INSN(blt, flt, fle); ++ ++#undef INSN ++ ++#define INSN(NAME, CMP) \ ++ void MacroAssembler::float_##NAME(FloatRegister Rs1, FloatRegister Rs2, Label &l, \ ++ bool is_far, bool is_unordered) { \ ++ float_##CMP(Rs2, Rs1, l, is_far, is_unordered); \ ++ } \ ++ void MacroAssembler::double_##NAME(FloatRegister Rs1, FloatRegister Rs2, Label &l, \ ++ bool is_far, bool is_unordered) { \ ++ double_##CMP(Rs2, Rs1, l, is_far, is_unordered); \ ++ } ++ ++ INSN(bgt, blt); ++ INSN(bge, ble); ++ ++#undef INSN ++ ++ ++#define INSN(NAME, CSR) \ ++ void MacroAssembler::NAME(Register Rd) { \ ++ csrr(Rd, CSR); \ ++ } ++ ++ INSN(rdinstret, CSR_INSTRET); ++ INSN(rdcycle, CSR_CYCLE); ++ INSN(rdtime, CSR_TIME); ++ INSN(frcsr, CSR_FCSR); ++ INSN(frrm, CSR_FRM); ++ INSN(frflags, CSR_FFLAGS); ++ ++#undef INSN ++ ++void MacroAssembler::csrr(Register Rd, unsigned csr) { ++ csrrs(Rd, csr, x0); ++} ++ ++#define INSN(NAME, OPFUN) \ ++ void MacroAssembler::NAME(unsigned csr, Register Rs) { \ ++ OPFUN(x0, csr, Rs); \ ++ } ++ ++ INSN(csrw, csrrw); ++ INSN(csrs, csrrs); ++ INSN(csrc, csrrc); ++ ++#undef INSN ++ ++#define INSN(NAME, OPFUN) \ ++ void MacroAssembler::NAME(unsigned csr, unsigned imm) { \ ++ OPFUN(x0, csr, imm); \ ++ } ++ ++ INSN(csrwi, csrrwi); ++ INSN(csrsi, csrrsi); ++ INSN(csrci, csrrci); ++ ++#undef INSN ++ ++#define INSN(NAME, CSR) \ ++ void MacroAssembler::NAME(Register Rd, Register Rs) { \ ++ csrrw(Rd, CSR, Rs); \ ++ } ++ ++ INSN(fscsr, CSR_FCSR); ++ INSN(fsrm, CSR_FRM); ++ INSN(fsflags, CSR_FFLAGS); ++ ++#undef INSN ++ ++#define INSN(NAME) \ ++ void MacroAssembler::NAME(Register Rs) { \ ++ NAME(x0, Rs); \ ++ } ++ ++ INSN(fscsr); ++ INSN(fsrm); ++ INSN(fsflags); ++ ++#undef INSN ++ ++void MacroAssembler::fsrmi(Register Rd, unsigned imm) { ++ guarantee(imm < 5, "Rounding Mode is invalid in Rounding Mode register"); ++ csrrwi(Rd, CSR_FRM, imm); ++} ++ ++void MacroAssembler::fsflagsi(Register Rd, unsigned imm) { ++ csrrwi(Rd, CSR_FFLAGS, imm); ++} ++ ++#define INSN(NAME) \ ++ void MacroAssembler::NAME(unsigned imm) { \ ++ NAME(x0, imm); \ ++ } ++ ++ INSN(fsrmi); ++ INSN(fsflagsi); ++ ++#undef INSN ++ ++void MacroAssembler::push_reg(Register Rs) ++{ ++ addi(esp, esp, 0 - wordSize); ++ sd(Rs, Address(esp, 0)); ++} ++ ++void MacroAssembler::pop_reg(Register Rd) ++{ ++ ld(Rd, Address(esp, 0)); ++ addi(esp, esp, wordSize); ++} ++ ++int MacroAssembler::bitset_to_regs(unsigned int bitset, unsigned char* regs) { ++ int count = 0; ++ // Scan bitset to accumulate register pairs ++ for (int reg = 31; reg >= 0; reg--) { ++ if ((1U << 31) & bitset) { ++ regs[count++] = reg; ++ } ++ bitset <<= 1; ++ } ++ return count; ++} ++ ++// Push integer registers in the bitset supplied. Don't push sp. ++// Return the number of words pushed ++int MacroAssembler::push_reg(unsigned int bitset, Register stack) { ++ DEBUG_ONLY(int words_pushed = 0;) ++ unsigned char regs[32]; ++ int count = bitset_to_regs(bitset, regs); ++ // reserve one slot to align for odd count ++ int offset = is_even(count) ? 0 : wordSize; ++ ++ if (count) { ++ addi(stack, stack, -count * wordSize - offset); ++ } ++ for (int i = count - 1; i >= 0; i--) { ++ sd(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset)); ++ DEBUG_ONLY(words_pushed++;) ++ } ++ ++ assert(words_pushed == count, "oops, pushed != count"); ++ ++ return count; ++} ++ ++int MacroAssembler::pop_reg(unsigned int bitset, Register stack) { ++ DEBUG_ONLY(int words_popped = 0;) ++ unsigned char regs[32]; ++ int count = bitset_to_regs(bitset, regs); ++ // reserve one slot to align for odd count ++ int offset = is_even(count) ? 0 : wordSize; ++ ++ for (int i = count - 1; i >= 0; i--) { ++ ld(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset)); ++ DEBUG_ONLY(words_popped++;) ++ } ++ ++ if (count) { ++ addi(stack, stack, count * wordSize + offset); ++ } ++ assert(words_popped == count, "oops, popped != count"); ++ ++ return count; ++} ++ ++// Push floating-point registers in the bitset supplied. ++// Return the number of words pushed ++int MacroAssembler::push_fp(unsigned int bitset, Register stack) { ++ DEBUG_ONLY(int words_pushed = 0;) ++ unsigned char regs[32]; ++ int count = bitset_to_regs(bitset, regs); ++ int push_slots = count + (count & 1); ++ ++ if (count) { ++ addi(stack, stack, -push_slots * wordSize); ++ } ++ ++ for (int i = count - 1; i >= 0; i--) { ++ fsd(as_FloatRegister(regs[i]), Address(stack, (push_slots - 1 - i) * wordSize)); ++ DEBUG_ONLY(words_pushed++;) ++ } ++ ++ assert(words_pushed == count, "oops, pushed(%d) != count(%d)", words_pushed, count); ++ ++ return count; ++} ++ ++int MacroAssembler::pop_fp(unsigned int bitset, Register stack) { ++ DEBUG_ONLY(int words_popped = 0;) ++ unsigned char regs[32]; ++ int count = bitset_to_regs(bitset, regs); ++ int pop_slots = count + (count & 1); ++ ++ for (int i = count - 1; i >= 0; i--) { ++ fld(as_FloatRegister(regs[i]), Address(stack, (pop_slots - 1 - i) * wordSize)); ++ DEBUG_ONLY(words_popped++;) ++ } ++ ++ if (count) { ++ addi(stack, stack, pop_slots * wordSize); ++ } ++ ++ assert(words_popped == count, "oops, popped(%d) != count(%d)", words_popped, count); ++ ++ return count; ++} ++ ++#ifdef COMPILER2 ++// Push vector registers in the bitset supplied. ++// Return the number of words pushed ++int MacroAssembler::push_v(unsigned int bitset, Register stack) { ++ int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); ++ ++ // Scan bitset to accumulate register pairs ++ unsigned char regs[32]; ++ int count = bitset_to_regs(bitset, regs); ++ ++ for (int i = 0; i < count; i++) { ++ sub(stack, stack, vector_size_in_bytes); ++ vs1r_v(as_VectorRegister(regs[i]), stack); ++ } ++ ++ return count * vector_size_in_bytes / wordSize; ++} ++ ++int MacroAssembler::pop_v(unsigned int bitset, Register stack) { ++ int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); ++ ++ // Scan bitset to accumulate register pairs ++ unsigned char regs[32]; ++ int count = bitset_to_regs(bitset, regs); ++ ++ for (int i = count - 1; i >= 0; i--) { ++ vl1re8_v(as_VectorRegister(regs[i]), stack); ++ add(stack, stack, vector_size_in_bytes); ++ } ++ ++ return count * vector_size_in_bytes / wordSize; ++} ++#endif // COMPILER2 ++ ++void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) { ++ // Push integer registers x7, x10-x17, x28-x31. ++ push_reg(RegSet::of(x7) + RegSet::range(x10, x17) + RegSet::range(x28, x31) - exclude, sp); ++ ++ // Push float registers f0-f7, f10-f17, f28-f31. ++ addi(sp, sp, - wordSize * 20); ++ int offset = 0; ++ for (int i = 0; i < 32; i++) { ++ if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) { ++ fsd(as_FloatRegister(i), Address(sp, wordSize * (offset++))); ++ } ++ } ++} ++ ++void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) { ++ int offset = 0; ++ for (int i = 0; i < 32; i++) { ++ if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) { ++ fld(as_FloatRegister(i), Address(sp, wordSize * (offset++))); ++ } ++ } ++ addi(sp, sp, wordSize * 20); ++ ++ pop_reg(RegSet::of(x7) + RegSet::range(x10, x17) + RegSet::range(x28, x31) - exclude, sp); ++} ++ ++void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes) { ++ // integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4) ++ push_reg(RegSet::range(x5, x31), sp); ++ ++ // float registers ++ addi(sp, sp, - 32 * wordSize); ++ for (int i = 0; i < 32; i++) { ++ fsd(as_FloatRegister(i), Address(sp, i * wordSize)); ++ } ++ ++ // vector registers ++ if (save_vectors) { ++ sub(sp, sp, vector_size_in_bytes * VectorRegisterImpl::number_of_registers); ++ vsetvli(t0, x0, Assembler::e64, Assembler::m8); ++ for (int i = 0; i < VectorRegisterImpl::number_of_registers; i += 8) { ++ add(t0, sp, vector_size_in_bytes * i); ++ vse64_v(as_VectorRegister(i), t0); ++ } ++ } ++} ++ ++void MacroAssembler::pop_CPU_state(bool restore_vectors, int vector_size_in_bytes) { ++ // vector registers ++ if (restore_vectors) { ++ vsetvli(t0, x0, Assembler::e64, Assembler::m8); ++ for (int i = 0; i < VectorRegisterImpl::number_of_registers; i += 8) { ++ vle64_v(as_VectorRegister(i), sp); ++ add(sp, sp, vector_size_in_bytes * 8); ++ } ++ } ++ ++ // float registers ++ for (int i = 0; i < 32; i++) { ++ fld(as_FloatRegister(i), Address(sp, i * wordSize)); ++ } ++ addi(sp, sp, 32 * wordSize); ++ ++ // integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4) ++ pop_reg(RegSet::range(x5, x31), sp); ++} ++ ++static int patch_offset_in_jal(address branch, int64_t offset) { ++ assert(Assembler::is_simm21(offset) && ((offset % 2) == 0), ++ "offset is too large to be patched in one jal instruction!\n"); ++ Assembler::patch(branch, 31, 31, (offset >> 20) & 0x1); // offset[20] ==> branch[31] ++ Assembler::patch(branch, 30, 21, (offset >> 1) & 0x3ff); // offset[10:1] ==> branch[30:21] ++ Assembler::patch(branch, 20, 20, (offset >> 11) & 0x1); // offset[11] ==> branch[20] ++ Assembler::patch(branch, 19, 12, (offset >> 12) & 0xff); // offset[19:12] ==> branch[19:12] ++ return NativeInstruction::instruction_size; // only one instruction ++} ++ ++static int patch_offset_in_conditional_branch(address branch, int64_t offset) { ++ assert(Assembler::is_simm13(offset) && ((offset % 2) == 0), ++ "offset is too large to be patched in one beq/bge/bgeu/blt/bltu/bne instruction!\n"); ++ Assembler::patch(branch, 31, 31, (offset >> 12) & 0x1); // offset[12] ==> branch[31] ++ Assembler::patch(branch, 30, 25, (offset >> 5) & 0x3f); // offset[10:5] ==> branch[30:25] ++ Assembler::patch(branch, 7, 7, (offset >> 11) & 0x1); // offset[11] ==> branch[7] ++ Assembler::patch(branch, 11, 8, (offset >> 1) & 0xf); // offset[4:1] ==> branch[11:8] ++ return NativeInstruction::instruction_size; // only one instruction ++} ++ ++static int patch_offset_in_pc_relative(address branch, int64_t offset) { ++ const int PC_RELATIVE_INSTRUCTION_NUM = 2; // auipc, addi/jalr/load ++ Assembler::patch(branch, 31, 12, ((offset + 0x800) >> 12) & 0xfffff); // Auipc. offset[31:12] ==> branch[31:12] ++ Assembler::patch(branch + 4, 31, 20, offset & 0xfff); // Addi/Jalr/Load. offset[11:0] ==> branch[31:20] ++ return PC_RELATIVE_INSTRUCTION_NUM * NativeInstruction::instruction_size; ++} ++ ++static int patch_addr_in_movptr(address branch, address target) { ++ const int MOVPTR_INSTRUCTIONS_NUM = 6; // lui + addi + slli + addi + slli + addi/jalr/load ++ int32_t lower = ((intptr_t)target << 35) >> 35; ++ int64_t upper = ((intptr_t)target - lower) >> 29; ++ Assembler::patch(branch + 0, 31, 12, upper & 0xfffff); // Lui. target[48:29] + target[28] ==> branch[31:12] ++ Assembler::patch(branch + 4, 31, 20, (lower >> 17) & 0xfff); // Addi. target[28:17] ==> branch[31:20] ++ Assembler::patch(branch + 12, 31, 20, (lower >> 6) & 0x7ff); // Addi. target[16: 6] ==> branch[31:20] ++ Assembler::patch(branch + 20, 31, 20, lower & 0x3f); // Addi/Jalr/Load. target[ 5: 0] ==> branch[31:20] ++ return MOVPTR_INSTRUCTIONS_NUM * NativeInstruction::instruction_size; ++} ++ ++static int patch_imm_in_li64(address branch, address target) { ++ const int LI64_INSTRUCTIONS_NUM = 8; // lui + addi + slli + addi + slli + addi + slli + addi ++ int64_t lower = (intptr_t)target & 0xffffffff; ++ lower = lower - ((lower << 44) >> 44); ++ int64_t tmp_imm = ((uint64_t)((intptr_t)target & 0xffffffff00000000)) + (uint64_t)lower; ++ int32_t upper = (tmp_imm - (int32_t)lower) >> 32; ++ int64_t tmp_upper = upper, tmp_lower = upper; ++ tmp_lower = (tmp_lower << 52) >> 52; ++ tmp_upper -= tmp_lower; ++ tmp_upper >>= 12; ++ // Load upper 32 bits. Upper = target[63:32], but if target[31] = 1 or (target[31:20] == 0x7ff && target[19] == 1), ++ // upper = target[63:32] + 1. ++ Assembler::patch(branch + 0, 31, 12, tmp_upper & 0xfffff); // Lui. ++ Assembler::patch(branch + 4, 31, 20, tmp_lower & 0xfff); // Addi. ++ // Load the rest 32 bits. ++ Assembler::patch(branch + 12, 31, 20, ((int32_t)lower >> 20) & 0xfff); // Addi. ++ Assembler::patch(branch + 20, 31, 20, (((intptr_t)target << 44) >> 52) & 0xfff); // Addi. ++ Assembler::patch(branch + 28, 31, 20, (intptr_t)target & 0xff); // Addi. ++ return LI64_INSTRUCTIONS_NUM * NativeInstruction::instruction_size; ++} ++ ++static int patch_imm_in_li32(address branch, int32_t target) { ++ const int LI32_INSTRUCTIONS_NUM = 2; // lui + addiw ++ int64_t upper = (intptr_t)target; ++ int32_t lower = (((int32_t)target) << 20) >> 20; ++ upper -= lower; ++ upper = (int32_t)upper; ++ Assembler::patch(branch + 0, 31, 12, (upper >> 12) & 0xfffff); // Lui. ++ Assembler::patch(branch + 4, 31, 20, lower & 0xfff); // Addiw. ++ return LI32_INSTRUCTIONS_NUM * NativeInstruction::instruction_size; ++} ++ ++static long get_offset_of_jal(address insn_addr) { ++ assert_cond(insn_addr != NULL); ++ long offset = 0; ++ unsigned insn = *(unsigned*)insn_addr; ++ long val = (long)Assembler::sextract(insn, 31, 12); ++ offset |= ((val >> 19) & 0x1) << 20; ++ offset |= (val & 0xff) << 12; ++ offset |= ((val >> 8) & 0x1) << 11; ++ offset |= ((val >> 9) & 0x3ff) << 1; ++ offset = (offset << 43) >> 43; ++ return offset; ++} ++ ++static long get_offset_of_conditional_branch(address insn_addr) { ++ long offset = 0; ++ assert_cond(insn_addr != NULL); ++ unsigned insn = *(unsigned*)insn_addr; ++ offset = (long)Assembler::sextract(insn, 31, 31); ++ offset = (offset << 12) | (((long)(Assembler::sextract(insn, 7, 7) & 0x1)) << 11); ++ offset = offset | (((long)(Assembler::sextract(insn, 30, 25) & 0x3f)) << 5); ++ offset = offset | (((long)(Assembler::sextract(insn, 11, 8) & 0xf)) << 1); ++ offset = (offset << 41) >> 41; ++ return offset; ++} ++ ++static long get_offset_of_pc_relative(address insn_addr) { ++ long offset = 0; ++ assert_cond(insn_addr != NULL); ++ offset = ((long)(Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12))) << 12; // Auipc. ++ offset += ((long)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)); // Addi/Jalr/Load. ++ offset = (offset << 32) >> 32; ++ return offset; ++} ++ ++static address get_target_of_movptr(address insn_addr) { ++ assert_cond(insn_addr != NULL); ++ intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 29; // Lui. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)) << 17; // Addi. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[3], 31, 20)) << 6; // Addi. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[5], 31, 20)); // Addi/Jalr/Load. ++ return (address) target_address; ++} ++ ++static address get_target_of_li64(address insn_addr) { ++ assert_cond(insn_addr != NULL); ++ intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 44; // Lui. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)) << 32; // Addi. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[3], 31, 20)) << 20; // Addi. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[5], 31, 20)) << 8; // Addi. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[7], 31, 20)); // Addi. ++ return (address)target_address; ++} ++ ++static address get_target_of_li32(address insn_addr) { ++ assert_cond(insn_addr != NULL); ++ intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 12; // Lui. ++ target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)); // Addiw. ++ return (address)target_address; ++} ++ ++// Patch any kind of instruction; there may be several instructions. ++// Return the total length (in bytes) of the instructions. ++int MacroAssembler::pd_patch_instruction_size(address branch, address target) { ++ assert_cond(branch != NULL); ++ int64_t offset = target - branch; ++ if (NativeInstruction::is_jal_at(branch)) { // jal ++ return patch_offset_in_jal(branch, offset); ++ } else if (NativeInstruction::is_branch_at(branch)) { // beq/bge/bgeu/blt/bltu/bne ++ return patch_offset_in_conditional_branch(branch, offset); ++ } else if (NativeInstruction::is_pc_relative_at(branch)) { // auipc, addi/jalr/load ++ return patch_offset_in_pc_relative(branch, offset); ++ } else if (NativeInstruction::is_movptr_at(branch)) { // movptr ++ return patch_addr_in_movptr(branch, target); ++ } else if (NativeInstruction::is_li64_at(branch)) { // li64 ++ return patch_imm_in_li64(branch, target); ++ } else if (NativeInstruction::is_li32_at(branch)) { // li32 ++ int64_t imm = (intptr_t)target; ++ return patch_imm_in_li32(branch, (int32_t)imm); ++ } else { ++#ifdef ASSERT ++ tty->print_cr("pd_patch_instruction_size: instruction 0x%x at " INTPTR_FORMAT " could not be patched!\n", ++ *(unsigned*)branch, p2i(branch)); ++ Disassembler::decode(branch - 16, branch + 16); ++#endif ++ ShouldNotReachHere(); ++ return -1; ++ } ++} ++ ++address MacroAssembler::target_addr_for_insn(address insn_addr) { ++ long offset = 0; ++ assert_cond(insn_addr != NULL); ++ if (NativeInstruction::is_jal_at(insn_addr)) { // jal ++ offset = get_offset_of_jal(insn_addr); ++ } else if (NativeInstruction::is_branch_at(insn_addr)) { // beq/bge/bgeu/blt/bltu/bne ++ offset = get_offset_of_conditional_branch(insn_addr); ++ } else if (NativeInstruction::is_pc_relative_at(insn_addr)) { // auipc, addi/jalr/load ++ offset = get_offset_of_pc_relative(insn_addr); ++ } else if (NativeInstruction::is_movptr_at(insn_addr)) { // movptr ++ return get_target_of_movptr(insn_addr); ++ } else if (NativeInstruction::is_li64_at(insn_addr)) { // li64 ++ return get_target_of_li64(insn_addr); ++ } else if (NativeInstruction::is_li32_at(insn_addr)) { // li32 ++ return get_target_of_li32(insn_addr); ++ } else { ++ ShouldNotReachHere(); ++ } ++ return address(((uintptr_t)insn_addr + offset)); ++} ++ ++int MacroAssembler::patch_oop(address insn_addr, address o) { ++ // OOPs are either narrow (32 bits) or wide (48 bits). We encode ++ // narrow OOPs by setting the upper 16 bits in the first ++ // instruction. ++ if (NativeInstruction::is_li32_at(insn_addr)) { ++ // Move narrow OOP ++ uint32_t n = CompressedOops::narrow_oop_value(cast_to_oop(o)); ++ return patch_imm_in_li32(insn_addr, (int32_t)n); ++ } else if (NativeInstruction::is_movptr_at(insn_addr)) { ++ // Move wide OOP ++ return patch_addr_in_movptr(insn_addr, o); ++ } ++ ShouldNotReachHere(); ++ return -1; ++} ++ ++void MacroAssembler::reinit_heapbase() { ++ if (UseCompressedOops) { ++ if (Universe::is_fully_initialized()) { ++ mv(xheapbase, CompressedOops::ptrs_base()); ++ } else { ++ ExternalAddress target((address)CompressedOops::ptrs_base_addr()); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(xheapbase, target, offset); ++ ld(xheapbase, Address(xheapbase, offset)); ++ }); ++ } ++ } ++} ++ ++void MacroAssembler::movptr(Register Rd, address addr, int32_t &offset) { ++ int64_t imm64 = (int64_t)addr; ++#ifndef PRODUCT ++ { ++ char buffer[64]; ++ snprintf(buffer, sizeof(buffer), "0x%" PRIx64, imm64); ++ block_comment(buffer); ++ } ++#endif ++ assert((uintptr_t)imm64 < (1ull << 48), "48-bit overflow in address constant"); ++ // Load upper 31 bits ++ int64_t imm = imm64 >> 17; ++ int64_t upper = imm, lower = imm; ++ lower = (lower << 52) >> 52; ++ upper -= lower; ++ upper = (int32_t)upper; ++ lui(Rd, upper); ++ addi(Rd, Rd, lower); ++ ++ // Load the rest 17 bits. ++ slli(Rd, Rd, 11); ++ addi(Rd, Rd, (imm64 >> 6) & 0x7ff); ++ slli(Rd, Rd, 6); ++ ++ // This offset will be used by following jalr/ld. ++ offset = imm64 & 0x3f; ++} ++ ++void MacroAssembler::add(Register Rd, Register Rn, int64_t increment, Register temp) { ++ if (is_simm12(increment)) { ++ addi(Rd, Rn, increment); ++ } else { ++ assert_different_registers(Rn, temp); ++ li(temp, increment); ++ add(Rd, Rn, temp); ++ } ++} ++ ++void MacroAssembler::addw(Register Rd, Register Rn, int32_t increment, Register temp) { ++ if (is_simm12(increment)) { ++ addiw(Rd, Rn, increment); ++ } else { ++ assert_different_registers(Rn, temp); ++ li(temp, increment); ++ addw(Rd, Rn, temp); ++ } ++} ++ ++void MacroAssembler::sub(Register Rd, Register Rn, int64_t decrement, Register temp) { ++ if (is_simm12(-decrement)) { ++ addi(Rd, Rn, -decrement); ++ } else { ++ assert_different_registers(Rn, temp); ++ li(temp, decrement); ++ sub(Rd, Rn, temp); ++ } ++} ++ ++void MacroAssembler::subw(Register Rd, Register Rn, int32_t decrement, Register temp) { ++ if (is_simm12(-decrement)) { ++ addiw(Rd, Rn, -decrement); ++ } else { ++ assert_different_registers(Rn, temp); ++ li(temp, decrement); ++ subw(Rd, Rn, temp); ++ } ++} ++ ++void MacroAssembler::andrw(Register Rd, Register Rs1, Register Rs2) { ++ andr(Rd, Rs1, Rs2); ++ sign_extend(Rd, Rd, 32); ++} ++ ++void MacroAssembler::orrw(Register Rd, Register Rs1, Register Rs2) { ++ orr(Rd, Rs1, Rs2); ++ sign_extend(Rd, Rd, 32); ++} ++ ++void MacroAssembler::xorrw(Register Rd, Register Rs1, Register Rs2) { ++ xorr(Rd, Rs1, Rs2); ++ sign_extend(Rd, Rd, 32); ++} ++ ++// Note: load_unsigned_short used to be called load_unsigned_word. ++int MacroAssembler::load_unsigned_short(Register dst, Address src) { ++ int off = offset(); ++ lhu(dst, src); ++ return off; ++} ++ ++int MacroAssembler::load_unsigned_byte(Register dst, Address src) { ++ int off = offset(); ++ lbu(dst, src); ++ return off; ++} ++ ++int MacroAssembler::load_signed_short(Register dst, Address src) { ++ int off = offset(); ++ lh(dst, src); ++ return off; ++} ++ ++int MacroAssembler::load_signed_byte(Register dst, Address src) { ++ int off = offset(); ++ lb(dst, src); ++ return off; ++} ++ ++void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2) { ++ switch (size_in_bytes) { ++ case 8: ld(dst, src); break; ++ case 4: is_signed ? lw(dst, src) : lwu(dst, src); break; ++ case 2: is_signed ? load_signed_short(dst, src) : load_unsigned_short(dst, src); break; ++ case 1: is_signed ? load_signed_byte( dst, src) : load_unsigned_byte( dst, src); break; ++ default: ShouldNotReachHere(); ++ } ++} ++ ++void MacroAssembler::store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2) { ++ switch (size_in_bytes) { ++ case 8: sd(src, dst); break; ++ case 4: sw(src, dst); break; ++ case 2: sh(src, dst); break; ++ case 1: sb(src, dst); break; ++ default: ShouldNotReachHere(); ++ } ++} ++ ++// reverse bytes in halfword in lower 16 bits and sign-extend ++// Rd[15:0] = Rs[7:0] Rs[15:8] (sign-extend to 64 bits) ++void MacroAssembler::revb_h_h(Register Rd, Register Rs, Register tmp) { ++ if (UseZbb) { ++ rev8(Rd, Rs); ++ srai(Rd, Rd, 48); ++ return; ++ } ++ assert_different_registers(Rs, tmp); ++ assert_different_registers(Rd, tmp); ++ srli(tmp, Rs, 8); ++ andi(tmp, tmp, 0xFF); ++ slli(Rd, Rs, 56); ++ srai(Rd, Rd, 48); // sign-extend ++ orr(Rd, Rd, tmp); ++} ++ ++// reverse bytes in lower word and sign-extend ++// Rd[31:0] = Rs[7:0] Rs[15:8] Rs[23:16] Rs[31:24] (sign-extend to 64 bits) ++void MacroAssembler::revb_w_w(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ if (UseZbb) { ++ rev8(Rd, Rs); ++ srai(Rd, Rd, 32); ++ return; ++ } ++ assert_different_registers(Rs, tmp1, tmp2); ++ assert_different_registers(Rd, tmp1, tmp2); ++ revb_h_w_u(Rd, Rs, tmp1, tmp2); ++ slli(tmp2, Rd, 48); ++ srai(tmp2, tmp2, 32); // sign-extend ++ srli(Rd, Rd, 16); ++ orr(Rd, Rd, tmp2); ++} ++ ++// reverse bytes in halfword in lower 16 bits and zero-extend ++// Rd[15:0] = Rs[7:0] Rs[15:8] (zero-extend to 64 bits) ++void MacroAssembler::revb_h_h_u(Register Rd, Register Rs, Register tmp) { ++ if (UseZbb) { ++ rev8(Rd, Rs); ++ srli(Rd, Rd, 48); ++ return; ++ } ++ assert_different_registers(Rs, tmp); ++ assert_different_registers(Rd, tmp); ++ srli(tmp, Rs, 8); ++ andi(tmp, tmp, 0xFF); ++ andi(Rd, Rs, 0xFF); ++ slli(Rd, Rd, 8); ++ orr(Rd, Rd, tmp); ++} ++ ++// reverse bytes in halfwords in lower 32 bits and zero-extend ++// Rd[31:0] = Rs[23:16] Rs[31:24] Rs[7:0] Rs[15:8] (zero-extend to 64 bits) ++void MacroAssembler::revb_h_w_u(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ if (UseZbb) { ++ rev8(Rd, Rs); ++ rori(Rd, Rd, 32); ++ roriw(Rd, Rd, 16); ++ zero_extend(Rd, Rd, 32); ++ return; ++ } ++ assert_different_registers(Rs, tmp1, tmp2); ++ assert_different_registers(Rd, tmp1, tmp2); ++ srli(tmp2, Rs, 16); ++ revb_h_h_u(tmp2, tmp2, tmp1); ++ revb_h_h_u(Rd, Rs, tmp1); ++ slli(tmp2, tmp2, 16); ++ orr(Rd, Rd, tmp2); ++} ++ ++// This method is only used for revb_h ++// Rd = Rs[47:0] Rs[55:48] Rs[63:56] ++void MacroAssembler::revb_h_helper(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ assert_different_registers(Rs, tmp1, tmp2); ++ assert_different_registers(Rd, tmp1); ++ srli(tmp1, Rs, 48); ++ andi(tmp2, tmp1, 0xFF); ++ slli(tmp2, tmp2, 8); ++ srli(tmp1, tmp1, 8); ++ orr(tmp1, tmp1, tmp2); ++ slli(Rd, Rs, 16); ++ orr(Rd, Rd, tmp1); ++} ++ ++// reverse bytes in each halfword ++// Rd[63:0] = Rs[55:48] Rs[63:56] Rs[39:32] Rs[47:40] Rs[23:16] Rs[31:24] Rs[7:0] Rs[15:8] ++void MacroAssembler::revb_h(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ if (UseZbb) { ++ assert_different_registers(Rs, tmp1); ++ assert_different_registers(Rd, tmp1); ++ rev8(Rd, Rs); ++ zero_extend(tmp1, Rd, 32); ++ roriw(tmp1, tmp1, 16); ++ slli(tmp1, tmp1, 32); ++ srli(Rd, Rd, 32); ++ roriw(Rd, Rd, 16); ++ zero_extend(Rd, Rd, 32); ++ orr(Rd, Rd, tmp1); ++ return; ++ } ++ assert_different_registers(Rs, tmp1, tmp2); ++ assert_different_registers(Rd, tmp1, tmp2); ++ revb_h_helper(Rd, Rs, tmp1, tmp2); ++ for (int i = 0; i < 3; ++i) { ++ revb_h_helper(Rd, Rd, tmp1, tmp2); ++ } ++} ++ ++// reverse bytes in each word ++// Rd[63:0] = Rs[39:32] Rs[47:40] Rs[55:48] Rs[63:56] Rs[7:0] Rs[15:8] Rs[23:16] Rs[31:24] ++void MacroAssembler::revb_w(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ if (UseZbb) { ++ rev8(Rd, Rs); ++ rori(Rd, Rd, 32); ++ return; ++ } ++ assert_different_registers(Rs, tmp1, tmp2); ++ assert_different_registers(Rd, tmp1, tmp2); ++ revb(Rd, Rs, tmp1, tmp2); ++ ror_imm(Rd, Rd, 32); ++} ++ ++// reverse bytes in doubleword ++// Rd[63:0] = Rs[7:0] Rs[15:8] Rs[23:16] Rs[31:24] Rs[39:32] Rs[47,40] Rs[55,48] Rs[63:56] ++void MacroAssembler::revb(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ if (UseZbb) { ++ rev8(Rd, Rs); ++ return; ++ } ++ assert_different_registers(Rs, tmp1, tmp2); ++ assert_different_registers(Rd, tmp1, tmp2); ++ andi(tmp1, Rs, 0xFF); ++ slli(tmp1, tmp1, 8); ++ for (int step = 8; step < 56; step += 8) { ++ srli(tmp2, Rs, step); ++ andi(tmp2, tmp2, 0xFF); ++ orr(tmp1, tmp1, tmp2); ++ slli(tmp1, tmp1, 8); ++ } ++ srli(Rd, Rs, 56); ++ andi(Rd, Rd, 0xFF); ++ orr(Rd, tmp1, Rd); ++} ++ ++// rotate right with shift bits ++void MacroAssembler::ror_imm(Register dst, Register src, uint32_t shift, Register tmp) ++{ ++ if (UseZbb) { ++ rori(dst, src, shift); ++ return; ++ } ++ ++ assert_different_registers(dst, tmp); ++ assert_different_registers(src, tmp); ++ assert(shift < 64, "shift amount must be < 64"); ++ slli(tmp, src, 64 - shift); ++ srli(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); ++ } else { ++ assert_different_registers(Rn, tmp); ++ mv(tmp, imm); ++ andr(Rd, Rn, tmp); ++ } ++} ++ ++void MacroAssembler::orptr(Address adr, RegisterOrConstant src, Register tmp1, Register tmp2) { ++ ld(tmp1, adr); ++ if (src.is_register()) { ++ orr(tmp1, tmp1, src.as_register()); ++ } else { ++ if (is_simm12(src.as_constant())) { ++ ori(tmp1, tmp1, src.as_constant()); ++ } else { ++ assert_different_registers(tmp1, tmp2); ++ mv(tmp2, src.as_constant()); ++ orr(tmp1, tmp1, tmp2); ++ } ++ } ++ sd(tmp1, adr); ++} ++ ++void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp1, Register tmp2, Label &L) { ++ assert_different_registers(oop, trial_klass, tmp1, tmp2); ++ if (UseCompressedClassPointers) { ++ lwu(tmp1, Address(oop, oopDesc::klass_offset_in_bytes())); ++ if (CompressedKlassPointers::base() == NULL) { ++ slli(tmp1, tmp1, CompressedKlassPointers::shift()); ++ beq(trial_klass, tmp1, L); ++ return; ++ } ++ decode_klass_not_null(tmp1, tmp2); ++ } else { ++ ld(tmp1, Address(oop, oopDesc::klass_offset_in_bytes())); ++ } ++ beq(trial_klass, tmp1, L); ++} ++ ++// Move an oop into a register. immediate is true if we want ++// immediate instructions and nmethod entry barriers are not enabled. ++// i.e. we are not going to patch this instruction while the code is being ++// executed by another thread. ++void MacroAssembler::movoop(Register dst, jobject obj, bool immediate) { ++ int oop_index; ++ if (obj == NULL) { ++ oop_index = oop_recorder()->allocate_oop_index(obj); ++ } else { ++#ifdef ASSERT ++ { ++ ThreadInVMfromUnknown tiv; ++ assert(Universe::heap()->is_in(JNIHandles::resolve(obj)), "should be real oop"); ++ } ++#endif ++ oop_index = oop_recorder()->find_index(obj); ++ } ++ RelocationHolder rspec = oop_Relocation::spec(oop_index); ++ ++ // nmethod entry barrier necessitate using the constant pool. They have to be ++ // ordered with respected to oop access. ++ if (BarrierSet::barrier_set()->barrier_set_nmethod() != NULL || !immediate) { ++ address dummy = address(uintptr_t(pc()) & -wordSize); // A nearby aligned address ++ ld_constant(dst, Address(dummy, rspec)); ++ } else ++ mv(dst, Address((address)obj, rspec)); ++} ++ ++// Move a metadata address into a register. ++void MacroAssembler::mov_metadata(Register dst, Metadata* obj) { ++ int oop_index; ++ if (obj == NULL) { ++ oop_index = oop_recorder()->allocate_metadata_index(obj); ++ } else { ++ oop_index = oop_recorder()->find_index(obj); ++ } ++ RelocationHolder rspec = metadata_Relocation::spec(oop_index); ++ mv(dst, Address((address)obj, rspec)); ++} ++ ++// Writes to stack successive pages until offset reached to check for ++// stack overflow + shadow pages. This clobbers tmp. ++void MacroAssembler::bang_stack_size(Register size, Register tmp) { ++ assert_different_registers(tmp, size, t0); ++ // Bang stack for total size given plus shadow page size. ++ // Bang one page at a time because large size can bang beyond yellow and ++ // red zones. ++ mv(t0, os::vm_page_size()); ++ Label loop; ++ bind(loop); ++ sub(tmp, sp, t0); ++ subw(size, size, t0); ++ sd(size, Address(tmp)); ++ bgtz(size, loop); ++ ++ // Bang down shadow pages too. ++ // At this point, (tmp-0) is the last address touched, so don't ++ // touch it again. (It was touched as (tmp-pagesize) but then tmp ++ // was post-decremented.) Skip this address by starting at i=1, and ++ // touch a few more pages below. N.B. It is important to touch all ++ // the way down to and including i=StackShadowPages. ++ for (int i = 0; i < (int)(StackOverflow::stack_shadow_zone_size() / os::vm_page_size()) - 1; i++) { ++ // this could be any sized move but this is can be a debugging crumb ++ // so the bigger the better. ++ sub(tmp, tmp, os::vm_page_size()); ++ sd(size, Address(tmp, 0)); ++ } ++} ++ ++SkipIfEqual::SkipIfEqual(MacroAssembler* masm, const bool* flag_addr, bool value) { ++ int32_t offset = 0; ++ _masm = masm; ++ ExternalAddress target((address)flag_addr); ++ _masm->relocate(target.rspec(), [&] { ++ int32_t offset; ++ _masm->la_patchable(t0, target, offset); ++ _masm->lbu(t0, Address(t0, offset)); ++ }); ++ _masm->beqz(t0, _label); ++} ++ ++SkipIfEqual::~SkipIfEqual() { ++ _masm->bind(_label); ++ _masm = NULL; ++} ++ ++void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) { ++ const int mirror_offset = in_bytes(Klass::java_mirror_offset()); ++ ld(dst, Address(xmethod, Method::const_offset())); ++ ld(dst, Address(dst, ConstMethod::constants_offset())); ++ ld(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes())); ++ ld(dst, Address(dst, mirror_offset)); ++ resolve_oop_handle(dst, tmp); ++} ++ ++void MacroAssembler::resolve_oop_handle(Register result, Register tmp) { ++ // OopHandle::resolve is an indirection. ++ assert_different_registers(result, tmp); ++ access_load_at(T_OBJECT, IN_NATIVE, result, Address(result, 0), tmp, noreg); ++} ++ ++// ((WeakHandle)result).resolve() ++void MacroAssembler::resolve_weak_handle(Register result, Register tmp) { ++ assert_different_registers(result, tmp); ++ Label resolved; ++ ++ // A null weak handle resolves to null. ++ beqz(result, resolved); ++ ++ // Only 64 bit platforms support GCs that require a tmp register ++ // Only IN_HEAP loads require a thread_tmp register ++ // WeakHandle::resolve is an indirection like jweak. ++ access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, ++ result, Address(result), tmp, noreg /* tmp_thread */); ++ bind(resolved); ++} ++ ++void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators, ++ Register dst, Address src, ++ Register tmp1, Register thread_tmp) { ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ decorators = AccessInternal::decorator_fixup(decorators); ++ bool as_raw = (decorators & AS_RAW) != 0; ++ if (as_raw) { ++ bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, thread_tmp); ++ } else { ++ bs->load_at(this, decorators, type, dst, src, tmp1, thread_tmp); ++ } ++} ++ ++void MacroAssembler::null_check(Register reg, int offset) { ++ if (needs_explicit_null_check(offset)) { ++ // provoke OS NULL exception if reg = NULL by ++ // accessing M[reg] w/o changing any registers ++ // NOTE: this is plenty to provoke a segv ++ ld(zr, Address(reg, 0)); ++ } else { ++ // nothing to do, (later) access of M[reg + offset] ++ // will provoke OS NULL exception if reg = NULL ++ } ++} ++ ++void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators, ++ Address dst, Register src, ++ Register tmp1, Register thread_tmp) { ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ decorators = AccessInternal::decorator_fixup(decorators); ++ bool as_raw = (decorators & AS_RAW) != 0; ++ if (as_raw) { ++ bs->BarrierSetAssembler::store_at(this, decorators, type, dst, src, tmp1, thread_tmp); ++ } else { ++ bs->store_at(this, decorators, type, dst, src, tmp1, thread_tmp); ++ } ++} ++ ++// Algorithm must match CompressedOops::encode. ++void MacroAssembler::encode_heap_oop(Register d, Register s) { ++ verify_oop(s, "broken oop in encode_heap_oop"); ++ if (CompressedOops::base() == NULL) { ++ if (CompressedOops::shift() != 0) { ++ assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong"); ++ srli(d, s, LogMinObjAlignmentInBytes); ++ } else { ++ mv(d, s); ++ } ++ } else { ++ Label notNull; ++ sub(d, s, xheapbase); ++ bgez(d, notNull); ++ mv(d, zr); ++ bind(notNull); ++ if (CompressedOops::shift() != 0) { ++ assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong"); ++ srli(d, d, CompressedOops::shift()); ++ } ++ } ++} ++ ++void MacroAssembler::load_klass(Register dst, Register src, Register tmp) { ++ assert_different_registers(dst, tmp); ++ assert_different_registers(src, tmp); ++ if (UseCompressedClassPointers) { ++ lwu(dst, Address(src, oopDesc::klass_offset_in_bytes())); ++ decode_klass_not_null(dst, tmp); ++ } else { ++ ld(dst, Address(src, oopDesc::klass_offset_in_bytes())); ++ } ++} ++ ++void MacroAssembler::store_klass(Register dst, Register src, Register tmp) { ++ // FIXME: Should this be a store release? concurrent gcs assumes ++ // klass length is valid if klass field is not null. ++ if (UseCompressedClassPointers) { ++ encode_klass_not_null(src, tmp); ++ sw(src, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } else { ++ sd(src, Address(dst, oopDesc::klass_offset_in_bytes())); ++ } ++} ++ ++void MacroAssembler::store_klass_gap(Register dst, Register src) { ++ if (UseCompressedClassPointers) { ++ // Store to klass gap in destination ++ sw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes())); ++ } ++} ++ ++void MacroAssembler::decode_klass_not_null(Register r, Register tmp) { ++ assert_different_registers(r, tmp); ++ decode_klass_not_null(r, r, tmp); ++} ++ ++void MacroAssembler::decode_klass_not_null(Register dst, Register src, Register tmp) { ++ assert(UseCompressedClassPointers, "should only be used for compressed headers"); ++ ++ if (CompressedKlassPointers::base() == NULL) { ++ if (CompressedKlassPointers::shift() != 0) { ++ assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong"); ++ slli(dst, src, LogKlassAlignmentInBytes); ++ } else { ++ mv(dst, src); ++ } ++ return; ++ } ++ ++ Register xbase = dst; ++ if (dst == src) { ++ xbase = tmp; ++ } ++ ++ assert_different_registers(src, xbase); ++ mv(xbase, (uintptr_t)CompressedKlassPointers::base()); ++ ++ if (CompressedKlassPointers::shift() != 0) { ++ assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong"); ++ assert_different_registers(t0, xbase); ++ shadd(dst, src, xbase, t0, LogKlassAlignmentInBytes); ++ } else { ++ add(dst, xbase, src); ++ } ++} ++ ++void MacroAssembler::encode_klass_not_null(Register r, Register tmp) { ++ assert_different_registers(r, tmp); ++ encode_klass_not_null(r, r, tmp); ++} ++ ++void MacroAssembler::encode_klass_not_null(Register dst, Register src, Register tmp) { ++ assert(UseCompressedClassPointers, "should only be used for compressed headers"); ++ ++ if (CompressedKlassPointers::base() == NULL) { ++ if (CompressedKlassPointers::shift() != 0) { ++ assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong"); ++ srli(dst, src, LogKlassAlignmentInBytes); ++ } else { ++ mv(dst, src); ++ } ++ return; ++ } ++ ++ if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0 && ++ CompressedKlassPointers::shift() == 0) { ++ zero_extend(dst, src, 32); ++ return; ++ } ++ ++ Register xbase = dst; ++ if (dst == src) { ++ xbase = tmp; ++ } ++ ++ assert_different_registers(src, xbase); ++ mv(xbase, (uintptr_t)CompressedKlassPointers::base()); ++ sub(dst, src, xbase); ++ if (CompressedKlassPointers::shift() != 0) { ++ assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong"); ++ srli(dst, dst, LogKlassAlignmentInBytes); ++ } ++} ++ ++void MacroAssembler::decode_heap_oop_not_null(Register r) { ++ decode_heap_oop_not_null(r, r); ++} ++ ++void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { ++ assert(UseCompressedOops, "should only be used for compressed headers"); ++ assert(Universe::heap() != NULL, "java heap should be initialized"); ++ // Cannot assert, unverified entry point counts instructions (see .ad file) ++ // vtableStubs also counts instructions in pd_code_size_limit. ++ // Also do not verify_oop as this is called by verify_oop. ++ if (CompressedOops::shift() != 0) { ++ assert(LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong"); ++ slli(dst, src, LogMinObjAlignmentInBytes); ++ if (CompressedOops::base() != NULL) { ++ add(dst, xheapbase, dst); ++ } ++ } else { ++ assert(CompressedOops::base() == NULL, "sanity"); ++ mv(dst, src); ++ } ++} ++ ++void MacroAssembler::decode_heap_oop(Register d, Register s) { ++ if (CompressedOops::base() == NULL) { ++ if (CompressedOops::shift() != 0 || d != s) { ++ slli(d, s, CompressedOops::shift()); ++ } ++ } else { ++ Label done; ++ mv(d, s); ++ beqz(s, done); ++ shadd(d, s, xheapbase, d, LogMinObjAlignmentInBytes); ++ bind(done); ++ } ++ verify_oop(d, "broken oop in decode_heap_oop"); ++} ++ ++void MacroAssembler::store_heap_oop(Address dst, Register src, Register tmp1, ++ Register thread_tmp, DecoratorSet decorators) { ++ access_store_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp); ++} ++ ++void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1, ++ Register thread_tmp, DecoratorSet decorators) { ++ access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp); ++} ++ ++void MacroAssembler::load_heap_oop_not_null(Register dst, Address src, Register tmp1, ++ Register thread_tmp, DecoratorSet decorators) { ++ access_load_at(T_OBJECT, IN_HEAP | IS_NOT_NULL, dst, src, tmp1, thread_tmp); ++} ++ ++// Used for storing NULLs. ++void MacroAssembler::store_heap_oop_null(Address dst) { ++ access_store_at(T_OBJECT, IN_HEAP, dst, noreg, noreg, noreg); ++} ++ ++int MacroAssembler::corrected_idivl(Register result, Register rs1, Register rs2, ++ bool want_remainder) ++{ ++ // Full implementation of Java idiv and irem. The function ++ // returns the (pc) offset of the div instruction - may be needed ++ // for implicit exceptions. ++ // ++ // input : rs1: dividend ++ // rs2: divisor ++ // ++ // result: either ++ // quotient (= rs1 idiv rs2) ++ // remainder (= rs1 irem rs2) ++ ++ ++ int idivl_offset = offset(); ++ if (!want_remainder) { ++ divw(result, rs1, rs2); ++ } else { ++ remw(result, rs1, rs2); // result = rs1 % rs2; ++ } ++ return idivl_offset; ++} ++ ++int MacroAssembler::corrected_idivq(Register result, Register rs1, Register rs2, ++ bool want_remainder) ++{ ++ // Full implementation of Java ldiv and lrem. The function ++ // returns the (pc) offset of the div instruction - may be needed ++ // for implicit exceptions. ++ // ++ // input : rs1: dividend ++ // rs2: divisor ++ // ++ // result: either ++ // quotient (= rs1 idiv rs2) ++ // remainder (= rs1 irem rs2) ++ ++ int idivq_offset = offset(); ++ if (!want_remainder) { ++ div(result, rs1, rs2); ++ } else { ++ rem(result, rs1, rs2); // result = rs1 % rs2; ++ } ++ return idivq_offset; ++} ++ ++// Look up the method for a megamorpic invkkeinterface call. ++// The target method is determined by . ++// The receiver klass is in recv_klass. ++// On success, the result will be in method_result, and execution falls through. ++// On failure, execution transfers to the given label. ++void MacroAssembler::lookup_interface_method(Register recv_klass, ++ Register intf_klass, ++ RegisterOrConstant itable_index, ++ Register method_result, ++ Register scan_tmp, ++ Label& L_no_such_interface, ++ bool return_method) { ++ assert_different_registers(recv_klass, intf_klass, scan_tmp); ++ assert_different_registers(method_result, intf_klass, scan_tmp); ++ assert(recv_klass != method_result || !return_method, ++ "recv_klass can be destroyed when mehtid isn't needed"); ++ assert(itable_index.is_constant() || itable_index.as_register() == method_result, ++ "caller must be same register for non-constant itable index as for method"); ++ ++ // Compute start of first itableOffsetEntry (which is at the end of the vtable). ++ int vtable_base = in_bytes(Klass::vtable_start_offset()); ++ int itentry_off = itableMethodEntry::method_offset_in_bytes(); ++ int scan_step = itableOffsetEntry::size() * wordSize; ++ int vte_size = vtableEntry::size_in_bytes(); ++ assert(vte_size == wordSize, "else adjust times_vte_scale"); ++ ++ lwu(scan_tmp, Address(recv_klass, Klass::vtable_length_offset())); ++ ++ // %%% Could store the aligned, prescaled offset in the klassoop. ++ shadd(scan_tmp, scan_tmp, recv_klass, scan_tmp, 3); ++ add(scan_tmp, scan_tmp, vtable_base); ++ ++ if (return_method) { ++ // Adjust recv_klass by scaled itable_index, so we can free itable_index. ++ assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below"); ++ if (itable_index.is_register()) { ++ slli(t0, itable_index.as_register(), 3); ++ } else { ++ mv(t0, itable_index.as_constant() << 3); ++ } ++ add(recv_klass, recv_klass, t0); ++ if (itentry_off) { ++ add(recv_klass, recv_klass, itentry_off); ++ } ++ } ++ ++ Label search, found_method; ++ ++ ld(method_result, Address(scan_tmp, itableOffsetEntry::interface_offset_in_bytes())); ++ beq(intf_klass, method_result, found_method); ++ bind(search); ++ // Check that the previous entry is non-null. A null entry means that ++ // the receiver class doens't implement the interface, and wasn't the ++ // same as when the caller was compiled. ++ beqz(method_result, L_no_such_interface, /* is_far */ true); ++ addi(scan_tmp, scan_tmp, scan_step); ++ ld(method_result, Address(scan_tmp, itableOffsetEntry::interface_offset_in_bytes())); ++ bne(intf_klass, method_result, search); ++ ++ bind(found_method); ++ ++ // Got a hit. ++ if (return_method) { ++ lwu(scan_tmp, Address(scan_tmp, itableOffsetEntry::offset_offset_in_bytes())); ++ add(method_result, recv_klass, scan_tmp); ++ ld(method_result, Address(method_result)); ++ } ++} ++ ++// virtual method calling ++void MacroAssembler::lookup_virtual_method(Register recv_klass, ++ RegisterOrConstant vtable_index, ++ Register method_result) { ++ const int base = in_bytes(Klass::vtable_start_offset()); ++ assert(vtableEntry::size() * wordSize == 8, ++ "adjust the scaling in the code below"); ++ int vtable_offset_in_bytes = base + vtableEntry::method_offset_in_bytes(); ++ ++ if (vtable_index.is_register()) { ++ shadd(method_result, vtable_index.as_register(), recv_klass, method_result, LogBytesPerWord); ++ ld(method_result, Address(method_result, vtable_offset_in_bytes)); ++ } else { ++ vtable_offset_in_bytes += vtable_index.as_constant() * wordSize; ++ ld(method_result, form_address(method_result, recv_klass, vtable_offset_in_bytes)); ++ } ++} ++ ++void MacroAssembler::membar(uint32_t order_constraint) { ++ address prev = pc() - NativeMembar::instruction_size; ++ address last = code()->last_insn(); ++ ++ if (last != NULL && nativeInstruction_at(last)->is_membar() && prev == last) { ++ NativeMembar *bar = NativeMembar_at(prev); ++ // We are merging two memory barrier instructions. On RISCV we ++ // can do this simply by ORing them together. ++ bar->set_kind(bar->get_kind() | order_constraint); ++ BLOCK_COMMENT("merged membar"); ++ } else { ++ code()->set_last_insn(pc()); ++ ++ uint32_t predecessor = 0; ++ uint32_t successor = 0; ++ ++ membar_mask_to_pred_succ(order_constraint, predecessor, successor); ++ fence(predecessor, successor); ++ } ++} ++ ++// Form an addres from base + offset in Rd. Rd my or may not ++// actually be used: you must use the Address that is returned. It ++// is up to you to ensure that the shift provided mathces the size ++// of your data. ++Address MacroAssembler::form_address(Register Rd, Register base, int64_t byte_offset) { ++ if (is_simm12(byte_offset)) { // 12: imm in range 2^12 ++ return Address(base, byte_offset); ++ } ++ ++ assert_different_registers(Rd, base, noreg); ++ ++ // Do it the hard way ++ mv(Rd, byte_offset); ++ add(Rd, base, Rd); ++ return Address(Rd); ++} ++ ++void MacroAssembler::check_klass_subtype(Register sub_klass, ++ Register super_klass, ++ Register tmp_reg, ++ Label& L_success) { ++ Label L_failure; ++ check_klass_subtype_fast_path(sub_klass, super_klass, tmp_reg, &L_success, &L_failure, NULL); ++ check_klass_subtype_slow_path(sub_klass, super_klass, tmp_reg, noreg, &L_success, NULL); ++ bind(L_failure); ++} ++ ++void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod) { ++ ld(t0, Address(xthread, JavaThread::polling_word_offset())); ++ if (acquire) { ++ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ } ++ if (at_return) { ++ bgtu(in_nmethod ? sp : fp, t0, slow_path, true /* is_far */); ++ } else { ++ test_bit(t0, t0, exact_log2(SafepointMechanism::poll_bit())); ++ bnez(t0, slow_path, true /* is_far */); ++ } ++} ++ ++void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp, ++ Label &succeed, Label *fail) { ++ // oldv holds comparison value ++ // newv holds value to write in exchange ++ // addr identifies memory word to compare against/update ++ Label retry_load, nope; ++ bind(retry_load); ++ // Load reserved from the memory location ++ lr_d(tmp, addr, Assembler::aqrl); ++ // Fail and exit if it is not what we expect ++ bne(tmp, oldv, nope); ++ // If the store conditional succeeds, tmp will be zero ++ sc_d(tmp, newv, addr, Assembler::rl); ++ beqz(tmp, succeed); ++ // Retry only when the store conditional failed ++ j(retry_load); ++ ++ bind(nope); ++ membar(AnyAny); ++ mv(oldv, tmp); ++ if (fail != NULL) { ++ j(*fail); ++ } ++} ++ ++void MacroAssembler::cmpxchg_obj_header(Register oldv, Register newv, Register obj, Register tmp, ++ Label &succeed, Label *fail) { ++ assert(oopDesc::mark_offset_in_bytes() == 0, "assumption"); ++ cmpxchgptr(oldv, newv, obj, tmp, succeed, fail); ++} ++ ++void MacroAssembler::load_reserved(Register addr, ++ enum operand_size size, ++ Assembler::Aqrl acquire) { ++ switch (size) { ++ case int64: ++ lr_d(t0, addr, acquire); ++ break; ++ case int32: ++ lr_w(t0, addr, acquire); ++ break; ++ case uint32: ++ lr_w(t0, addr, acquire); ++ zero_extend(t0, t0, 32); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void MacroAssembler::store_conditional(Register addr, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl release) { ++ switch (size) { ++ case int64: ++ sc_d(t0, new_val, addr, release); ++ break; ++ case int32: ++ case uint32: ++ sc_w(t0, new_val, addr, release); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++ ++void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Register tmp1, Register tmp2, Register tmp3) { ++ assert(size == int8 || size == int16, "unsupported operand size"); ++ ++ Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3; ++ ++ andi(shift, addr, 3); ++ slli(shift, shift, 3); ++ ++ andi(aligned_addr, addr, ~3); ++ ++ if (size == int8) { ++ mv(mask, 0xff); ++ } else { ++ // size == int16 case ++ mv(mask, -1); ++ zero_extend(mask, mask, 16); ++ } ++ sll(mask, mask, shift); ++ ++ xori(not_mask, mask, -1); ++ ++ sll(expected, expected, shift); ++ andr(expected, expected, mask); ++ ++ sll(new_val, new_val, shift); ++ andr(new_val, new_val, mask); ++} ++ ++// cmpxchg_narrow_value will kill t0, t1, expected, new_val and tmps. ++// It's designed to implement compare and swap byte/boolean/char/short by lr.w/sc.w, ++// which are forced to work with 4-byte aligned address. ++void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result, bool result_as_bool, ++ Register tmp1, Register tmp2, Register tmp3) { ++ Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3, old = result, tmp = t0; ++ assert_different_registers(addr, old, mask, not_mask, new_val, expected, shift, tmp); ++ cmpxchg_narrow_value_helper(addr, expected, new_val, size, tmp1, tmp2, tmp3); ++ ++ Label retry, fail, done; ++ ++ bind(retry); ++ lr_w(old, aligned_addr, acquire); ++ andr(tmp, old, mask); ++ bne(tmp, expected, fail); ++ ++ andr(tmp, old, not_mask); ++ orr(tmp, tmp, new_val); ++ sc_w(tmp, tmp, aligned_addr, release); ++ bnez(tmp, retry); ++ ++ if (result_as_bool) { ++ mv(result, 1); ++ j(done); ++ ++ bind(fail); ++ mv(result, zr); ++ ++ bind(done); ++ } else { ++ andr(tmp, old, mask); ++ ++ bind(fail); ++ srl(result, tmp, shift); ++ ++ if (size == int8) { ++ sign_extend(result, result, 8); ++ } else { ++ // size == int16 case ++ sign_extend(result, result, 16); ++ } ++ } ++} ++ ++// weak_cmpxchg_narrow_value is a weak version of cmpxchg_narrow_value, to implement ++// the weak CAS stuff. The major difference is that it just failed when store conditional ++// failed. ++void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result, ++ Register tmp1, Register tmp2, Register tmp3) { ++ Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3, old = result, tmp = t0; ++ assert_different_registers(addr, old, mask, not_mask, new_val, expected, shift, tmp); ++ cmpxchg_narrow_value_helper(addr, expected, new_val, size, tmp1, tmp2, tmp3); ++ ++ Label fail, done; ++ ++ lr_w(old, aligned_addr, acquire); ++ andr(tmp, old, mask); ++ bne(tmp, expected, fail); ++ ++ andr(tmp, old, not_mask); ++ orr(tmp, tmp, new_val); ++ sc_w(tmp, tmp, aligned_addr, release); ++ bnez(tmp, fail); ++ ++ // Success ++ mv(result, 1); ++ j(done); ++ ++ // Fail ++ bind(fail); ++ mv(result, zr); ++ ++ bind(done); ++} ++ ++void MacroAssembler::cmpxchg(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result, bool result_as_bool) { ++ assert(size != int8 && size != int16, "unsupported operand size"); ++ ++ Label retry_load, done, ne_done; ++ bind(retry_load); ++ load_reserved(addr, size, acquire); ++ bne(t0, expected, ne_done); ++ store_conditional(addr, new_val, size, release); ++ bnez(t0, retry_load); ++ ++ // equal, succeed ++ if (result_as_bool) { ++ mv(result, 1); ++ } else { ++ mv(result, expected); ++ } ++ j(done); ++ ++ // not equal, failed ++ bind(ne_done); ++ if (result_as_bool) { ++ mv(result, zr); ++ } else { ++ mv(result, t0); ++ } ++ ++ bind(done); ++} ++ ++void MacroAssembler::cmpxchg_weak(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result) { ++ Label fail, done; ++ load_reserved(addr, size, acquire); ++ bne(t0, expected, fail); ++ store_conditional(addr, new_val, size, release); ++ bnez(t0, fail); ++ ++ // Success ++ mv(result, 1); ++ j(done); ++ ++ // Fail ++ bind(fail); ++ mv(result, zr); ++ ++ bind(done); ++} ++ ++#define ATOMIC_OP(NAME, AOP, ACQUIRE, RELEASE) \ ++void MacroAssembler::atomic_##NAME(Register prev, RegisterOrConstant incr, Register addr) { \ ++ prev = prev->is_valid() ? prev : zr; \ ++ if (incr.is_register()) { \ ++ AOP(prev, addr, incr.as_register(), (Assembler::Aqrl)(ACQUIRE | RELEASE)); \ ++ } else { \ ++ mv(t0, incr.as_constant()); \ ++ AOP(prev, addr, t0, (Assembler::Aqrl)(ACQUIRE | RELEASE)); \ ++ } \ ++ return; \ ++} ++ ++ATOMIC_OP(add, amoadd_d, Assembler::relaxed, Assembler::relaxed) ++ATOMIC_OP(addw, amoadd_w, Assembler::relaxed, Assembler::relaxed) ++ATOMIC_OP(addal, amoadd_d, Assembler::aq, Assembler::rl) ++ATOMIC_OP(addalw, amoadd_w, Assembler::aq, Assembler::rl) ++ ++#undef ATOMIC_OP ++ ++#define ATOMIC_XCHG(OP, AOP, ACQUIRE, RELEASE) \ ++void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) { \ ++ prev = prev->is_valid() ? prev : zr; \ ++ AOP(prev, addr, newv, (Assembler::Aqrl)(ACQUIRE | RELEASE)); \ ++ return; \ ++} ++ ++ATOMIC_XCHG(xchg, amoswap_d, Assembler::relaxed, Assembler::relaxed) ++ATOMIC_XCHG(xchgw, amoswap_w, Assembler::relaxed, Assembler::relaxed) ++ATOMIC_XCHG(xchgal, amoswap_d, Assembler::aq, Assembler::rl) ++ATOMIC_XCHG(xchgalw, amoswap_w, Assembler::aq, Assembler::rl) ++ ++#undef ATOMIC_XCHG ++ ++#define ATOMIC_XCHGU(OP1, OP2) \ ++void MacroAssembler::atomic_##OP1(Register prev, Register newv, Register addr) { \ ++ atomic_##OP2(prev, newv, addr); \ ++ zero_extend(prev, prev, 32); \ ++ return; \ ++} ++ ++ATOMIC_XCHGU(xchgwu, xchgw) ++ATOMIC_XCHGU(xchgalwu, xchgalw) ++ ++#undef ATOMIC_XCHGU ++ ++void MacroAssembler::far_jump(Address entry, CodeBuffer *cbuf, Register tmp) { ++ assert(ReservedCodeCacheSize < 4*G, "branch out of range"); ++ assert(CodeCache::find_blob(entry.target()) != NULL, ++ "destination of far call not found in code cache"); ++ IncompressibleRegion ir(this); // Fixed length: see MacroAssembler::far_branch_size() ++ if (far_branches()) { ++ // We can use auipc + jalr here because we know that the total size of ++ // the code cache cannot exceed 2Gb. ++ relocate(entry.rspec(), [&] { ++ int32_t offset; ++ la_patchable(tmp, entry, offset); ++ if (cbuf != NULL) { cbuf->set_insts_mark(); } ++ jalr(x0, tmp, offset); ++ }); ++ } else { ++ if (cbuf != NULL) { cbuf->set_insts_mark(); } ++ j(entry); ++ } ++} ++ ++void MacroAssembler::far_call(Address entry, CodeBuffer *cbuf, Register tmp) { ++ assert(ReservedCodeCacheSize < 4*G, "branch out of range"); ++ assert(CodeCache::find_blob(entry.target()) != NULL, ++ "destination of far call not found in code cache"); ++ IncompressibleRegion ir(this); // Fixed length: see MacroAssembler::far_branch_size() ++ if (far_branches()) { ++ // We can use auipc + jalr here because we know that the total size of ++ // the code cache cannot exceed 2Gb. ++ relocate(entry.rspec(), [&] { ++ int32_t offset; ++ la_patchable(tmp, entry, offset); ++ if (cbuf != NULL) { cbuf->set_insts_mark(); } ++ jalr(x1, tmp, offset); // link ++ }); ++ } else { ++ if (cbuf != NULL) { cbuf->set_insts_mark(); } ++ jal(entry); // link ++ } ++} ++ ++void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, ++ Register super_klass, ++ Register tmp_reg, ++ Label* L_success, ++ Label* L_failure, ++ Label* L_slow_path, ++ Register super_check_offset) { ++ assert_different_registers(sub_klass, super_klass, tmp_reg); ++ bool must_load_sco = (super_check_offset == noreg); ++ if (must_load_sco) { ++ assert(tmp_reg != noreg, "supply either a temp or a register offset"); ++ } else { ++ assert_different_registers(sub_klass, super_klass, super_check_offset); ++ } ++ ++ Label L_fallthrough; ++ int label_nulls = 0; ++ if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; } ++ if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; } ++ if (L_slow_path == NULL) { L_slow_path = &L_fallthrough; label_nulls++; } ++ assert(label_nulls <= 1, "at most one NULL in batch"); ++ ++ int sc_offset = in_bytes(Klass::secondary_super_cache_offset()); ++ int sco_offset = in_bytes(Klass::super_check_offset_offset()); ++ Address super_check_offset_addr(super_klass, sco_offset); ++ ++ // Hacked jmp, which may only be used just before L_fallthrough. ++#define final_jmp(label) \ ++ if (&(label) == &L_fallthrough) { /*do nothing*/ } \ ++ else j(label) /*omit semi*/ ++ ++ // If the pointers are equal, we are done (e.g., String[] elements). ++ // This self-check enables sharing of secondary supertype arrays among ++ // non-primary types such as array-of-interface. Otherwise, each such ++ // type would need its own customized SSA. ++ // We move this check to the front fo the fast path because many ++ // type checks are in fact trivially successful in this manner, ++ // so we get a nicely predicted branch right at the start of the check. ++ beq(sub_klass, super_klass, *L_success); ++ ++ // Check the supertype display: ++ if (must_load_sco) { ++ lwu(tmp_reg, super_check_offset_addr); ++ super_check_offset = tmp_reg; ++ } ++ add(t0, sub_klass, super_check_offset); ++ Address super_check_addr(t0); ++ ld(t0, super_check_addr); // load displayed supertype ++ ++ // Ths check has worked decisively for primary supers. ++ // Secondary supers are sought in the super_cache ('super_cache_addr'). ++ // (Secondary supers are interfaces and very deeply nested subtypes.) ++ // This works in the same check above because of a tricky aliasing ++ // between the super_Cache and the primary super dispaly elements. ++ // (The 'super_check_addr' can address either, as the case requires.) ++ // Note that the cache is updated below if it does not help us find ++ // what we need immediately. ++ // So if it was a primary super, we can just fail immediately. ++ // Otherwise, it's the slow path for us (no success at this point). ++ ++ beq(super_klass, t0, *L_success); ++ mv(t1, sc_offset); ++ if (L_failure == &L_fallthrough) { ++ beq(super_check_offset, t1, *L_slow_path); ++ } else { ++ bne(super_check_offset, t1, *L_failure, /* is_far */ true); ++ final_jmp(*L_slow_path); ++ } ++ ++ bind(L_fallthrough); ++ ++#undef final_jmp ++} ++ ++// Scans count pointer sized words at [addr] for occurence of value, ++// generic ++void MacroAssembler::repne_scan(Register addr, Register value, Register count, ++ Register tmp) { ++ Label Lloop, Lexit; ++ beqz(count, Lexit); ++ bind(Lloop); ++ ld(tmp, addr); ++ beq(value, tmp, Lexit); ++ add(addr, addr, wordSize); ++ sub(count, count, 1); ++ bnez(count, Lloop); ++ bind(Lexit); ++} ++ ++void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, ++ Register super_klass, ++ Register tmp1_reg, ++ Register tmp2_reg, ++ Label* L_success, ++ Label* L_failure) { ++ assert_different_registers(sub_klass, super_klass, tmp1_reg); ++ if (tmp2_reg != noreg) { ++ assert_different_registers(sub_klass, super_klass, tmp1_reg, tmp2_reg, t0); ++ } ++#define IS_A_TEMP(reg) ((reg) == tmp1_reg || (reg) == tmp2_reg) ++ ++ Label L_fallthrough; ++ int label_nulls = 0; ++ if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; } ++ if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; } ++ ++ assert(label_nulls <= 1, "at most one NULL in the batch"); ++ ++ // A couple of usefule fields in sub_klass: ++ int ss_offset = in_bytes(Klass::secondary_supers_offset()); ++ int sc_offset = in_bytes(Klass::secondary_super_cache_offset()); ++ Address secondary_supers_addr(sub_klass, ss_offset); ++ Address super_cache_addr( sub_klass, sc_offset); ++ ++ BLOCK_COMMENT("check_klass_subtype_slow_path"); ++ ++ // Do a linear scan of the secondary super-klass chain. ++ // This code is rarely used, so simplicity is a virtue here. ++ // The repne_scan instruction uses fixed registers, which we must spill. ++ // Don't worry too much about pre-existing connecitons with the input regs. ++ ++ assert(sub_klass != x10, "killed reg"); // killed by mv(x10, super) ++ assert(sub_klass != x12, "killed reg"); // killed by la(x12, &pst_counter) ++ ++ RegSet pushed_registers; ++ if (!IS_A_TEMP(x12)) { ++ pushed_registers += x12; ++ } ++ if (!IS_A_TEMP(x15)) { ++ pushed_registers += x15; ++ } ++ ++ if (super_klass != x10) { ++ if (!IS_A_TEMP(x10)) { ++ pushed_registers += x10; ++ } ++ } ++ ++ push_reg(pushed_registers, sp); ++ ++ // Get super_klass value into x10 (even if it was in x15 or x12) ++ mv(x10, super_klass); ++ ++#ifndef PRODUCT ++ mv(t1, (address)&SharedRuntime::_partial_subtype_ctr); ++ Address pst_counter_addr(t1); ++ ld(t0, pst_counter_addr); ++ add(t0, t0, 1); ++ sd(t0, pst_counter_addr); ++#endif // PRODUCT ++ ++ // We will consult the secondary-super array. ++ ld(x15, secondary_supers_addr); ++ // Load the array length. ++ lwu(x12, Address(x15, Array::length_offset_in_bytes())); ++ // Skip to start of data. ++ add(x15, x15, Array::base_offset_in_bytes()); ++ ++ // Set t0 to an obvious invalid value, falling through by default ++ mv(t0, -1); ++ // Scan X12 words at [X15] for an occurrence of X10. ++ repne_scan(x15, x10, x12, t0); ++ ++ // pop will restore x10, so we should use a temp register to keep its value ++ mv(t1, x10); ++ ++ // Unspill the temp registers: ++ pop_reg(pushed_registers, sp); ++ ++ bne(t1, t0, *L_failure); ++ ++ // Success. Cache the super we found an proceed in triumph. ++ sd(super_klass, super_cache_addr); ++ ++ if (L_success != &L_fallthrough) { ++ j(*L_success); ++ } ++ ++#undef IS_A_TEMP ++ ++ bind(L_fallthrough); ++} ++ ++// Defines obj, preserves var_size_in_bytes, okay for tmp2 == var_size_in_bytes. ++void MacroAssembler::tlab_allocate(Register obj, ++ Register var_size_in_bytes, ++ int con_size_in_bytes, ++ Register tmp1, ++ Register tmp2, ++ Label& slow_case, ++ bool is_far) { ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->tlab_allocate(this, obj, var_size_in_bytes, con_size_in_bytes, tmp1, tmp2, slow_case, is_far); ++} ++ ++// Defines obj, preserves var_size_in_bytes ++void MacroAssembler::eden_allocate(Register obj, ++ Register var_size_in_bytes, ++ int con_size_in_bytes, ++ Register tmp, ++ Label& slow_case, ++ bool is_far) { ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->eden_allocate(this, obj, var_size_in_bytes, con_size_in_bytes, tmp, slow_case, is_far); ++} ++ ++ ++// get_thread() can be called anywhere inside generated code so we ++// need to save whatever non-callee save context might get clobbered ++// by the call to Thread::current() or, indeed, the call setup code. ++void MacroAssembler::get_thread(Register thread) { ++ // save all call-clobbered regs except thread ++ RegSet saved_regs = RegSet::range(x5, x7) + RegSet::range(x10, x17) + ++ RegSet::range(x28, x31) + ra - thread; ++ push_reg(saved_regs, sp); ++ ++ mv(ra, CAST_FROM_FN_PTR(address, Thread::current)); ++ jalr(ra); ++ if (thread != c_rarg0) { ++ mv(thread, c_rarg0); ++ } ++ ++ // restore pushed registers ++ pop_reg(saved_regs, sp); ++} ++ ++void MacroAssembler::load_byte_map_base(Register reg) { ++ CardTable::CardValue* byte_map_base = ++ ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base(); ++ mv(reg, (uint64_t)byte_map_base); ++} ++ ++void MacroAssembler::la_patchable(Register reg1, const Address &dest, int32_t &offset) { ++ unsigned long low_address = (uintptr_t)CodeCache::low_bound(); ++ unsigned long high_address = (uintptr_t)CodeCache::high_bound(); ++ unsigned long dest_address = (uintptr_t)dest.target(); ++ long offset_low = dest_address - low_address; ++ long offset_high = dest_address - high_address; ++ ++ assert(dest.getMode() == Address::literal, "la_patchable must be applied to a literal address"); ++ assert((uintptr_t)dest.target() < (1ull << 48), "bad address"); ++ ++ // RISC-V doesn't compute a page-aligned address, in order to partially ++ // compensate for the use of *signed* offsets in its base+disp12 ++ // addressing mode (RISC-V's PC-relative reach remains asymmetric ++ // [-(2G + 2K), 2G - 2k). ++ if (offset_high >= -((1L << 31) + (1L << 11)) && offset_low < (1L << 31) - (1L << 11)) { ++ int64_t distance = dest.target() - pc(); ++ auipc(reg1, (int32_t)distance + 0x800); ++ offset = ((int32_t)distance << 20) >> 20; ++ } else { ++ movptr(reg1, dest.target(), offset); ++ } ++} ++ ++void MacroAssembler::build_frame(int framesize) { ++ assert(framesize >= 2, "framesize must include space for FP/RA"); ++ assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment"); ++ sub(sp, sp, framesize); ++ sd(fp, Address(sp, framesize - 2 * wordSize)); ++ sd(ra, Address(sp, framesize - wordSize)); ++ if (PreserveFramePointer) { add(fp, sp, framesize); } ++} ++ ++void MacroAssembler::remove_frame(int framesize) { ++ assert(framesize >= 2, "framesize must include space for FP/RA"); ++ assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment"); ++ ld(fp, Address(sp, framesize - 2 * wordSize)); ++ ld(ra, Address(sp, framesize - wordSize)); ++ add(sp, sp, framesize); ++} ++ ++void MacroAssembler::reserved_stack_check() { ++ // testing if reserved zone needs to be enabled ++ Label no_reserved_zone_enabling; ++ ++ ld(t0, Address(xthread, JavaThread::reserved_stack_activation_offset())); ++ bltu(sp, t0, no_reserved_zone_enabling); ++ ++ enter(); // RA and FP are live. ++ mv(c_rarg0, xthread); ++ RuntimeAddress target(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone)); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(t0, target, offset); ++ jalr(x1, t0, offset); ++ }); ++ leave(); ++ ++ // We have already removed our own frame. ++ // throw_delayed_StackOverflowError will think that it's been ++ // called by our caller. ++ target = RuntimeAddress(StubRoutines::throw_delayed_StackOverflowError_entry()); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(t0, target, offset); ++ jalr(x0, t0, offset); ++ }); ++ should_not_reach_here(); ++ ++ bind(no_reserved_zone_enabling); ++} ++ ++void MacroAssembler::biased_locking_enter(Register lock_reg, ++ Register obj_reg, ++ Register swap_reg, ++ Register tmp_reg, ++ bool swap_reg_contains_mark, ++ Label& done, ++ Label* slow_case, ++ BiasedLockingCounters* counters, ++ Register flag) { ++ assert(UseBiasedLocking, "why call this otherwise?"); ++ assert_different_registers(lock_reg, obj_reg, swap_reg); ++ ++ if (PrintBiasedLockingStatistics && counters == NULL) { ++ counters = BiasedLocking::counters(); ++ } ++ ++ assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg, t0, flag); ++ assert(markWord::age_shift == markWord::lock_bits + markWord::biased_lock_bits, "biased locking makes assumptions about bit layout"); ++ Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); ++ ++ // Biased locking ++ // See whether the lock is currently biased toward our thread and ++ // whether the epoch is still valid ++ // Note that the runtime guarantees sufficient alignment of JavaThread ++ // pointers to allow age to be placed into low bits ++ // First check to see whether biasing is even enabled for this object ++ Label cas_label; ++ if (!swap_reg_contains_mark) { ++ ld(swap_reg, mark_addr); ++ } ++ andi(tmp_reg, swap_reg, markWord::biased_lock_mask_in_place); ++ xori(t0, tmp_reg, (u1)markWord::biased_lock_pattern); ++ bnez(t0, cas_label); // don't care flag unless jumping to done ++ // The bias pattern is present in the object's header. Need to check ++ // whether the bias owner and the epoch are both still current. ++ load_prototype_header(tmp_reg, obj_reg); ++ orr(tmp_reg, tmp_reg, xthread); ++ xorr(tmp_reg, tmp_reg, swap_reg); ++ andi(tmp_reg, tmp_reg, ~((int) markWord::age_mask_in_place)); ++ if (flag->is_valid()) { ++ mv(flag, tmp_reg); ++ } ++ ++ if (counters != NULL) { ++ Label around; ++ bnez(tmp_reg, around); ++ atomic_incw(Address((address)counters->biased_lock_entry_count_addr()), tmp_reg, t0); ++ j(done); ++ bind(around); ++ } else { ++ beqz(tmp_reg, done); ++ } ++ ++ Label try_revoke_bias; ++ Label try_rebias; ++ ++ // At this point we know the header has the bias pattern and ++ // that we are not the bias owner in the current epoch. We need to ++ // figure out more details about the state of the header in order to ++ // know what operations can be legally performed on the object's ++ // header. ++ ++ // If the low three bits in the xor result aren't clear, that means ++ // the prototype header is no longer biased and we have to revoke ++ // the bias on this object. ++ andi(t0, tmp_reg, markWord::biased_lock_mask_in_place); ++ bnez(t0, try_revoke_bias); ++ ++ // Biasing is still enabled for this data type. See whether the ++ // epoch of the current bias is still valid, meaning that the epoch ++ // bits of the mark word are equal to the epoch bits of the ++ // prototype header. (Note that the prototype header's epoch bits ++ // only change at a safepoint.) If not, attempt to rebias the object ++ // toward the current thread. Note that we must be absolutely sure ++ // that the current epoch is invalid in order to do this because ++ // otherwise the manipulations it performs on the mark word are ++ // illegal. ++ andi(t0, tmp_reg, markWord::epoch_mask_in_place); ++ bnez(t0, try_rebias); ++ ++ // The epoch of the current bias is still valid but we know nothing ++ // about the owner; it might be set or it might be clear. Try to ++ // acquire the bias of the object using an atomic operation. If this ++ // fails we will go in to the runtime to revoke the object's bias. ++ // Note that we first construct the presumed unbiased header so we ++ // don't accidentally blow away another thread's valid bias. ++ { ++ Label cas_success; ++ Label counter; ++ li(t0, (int64_t)(markWord::biased_lock_mask_in_place | markWord::age_mask_in_place | markWord::epoch_mask_in_place)); ++ andr(swap_reg, swap_reg, t0); ++ orr(tmp_reg, swap_reg, xthread); ++ cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, t0, cas_success, slow_case); ++ // cas failed here if slow_cas == NULL ++ if (flag->is_valid()) { ++ li(flag, 1); ++ j(counter); ++ } ++ ++ // If the biasing toward our thread failed, this means that ++ // another thread succeeded in biasing it toward itself and we ++ // need to revoke that bias. The revocation will occur in the ++ // interpreter runtime in the slow case. ++ bind(cas_success); ++ if (flag->is_valid()) { ++ li(flag, 0); ++ bind(counter); ++ } ++ ++ if (counters != NULL) { ++ atomic_incw(Address((address)counters->anonymously_biased_lock_entry_count_addr()), ++ tmp_reg, t0); ++ } ++ } ++ j(done); ++ ++ bind(try_rebias); ++ // At this point we know the epoch has expired, meaning that the ++ // current "bias owner", if any, is actually invalid. Under these ++ // circumstantces _only_, we are allowed to use the current header's ++ // value as the comparison value when doing the cas to acquire the ++ // bias in the current epoch. In other words, we allow transfer of ++ // the bias from one thread to another directly in this situation. ++ // ++ // FIXME: due to a lack of registers we currently blow away the age ++ // bias in this situation. Should attempt to preserve them. ++ { ++ Label cas_success; ++ Label counter; ++ load_prototype_header(tmp_reg, obj_reg); ++ orr(tmp_reg, tmp_reg, xthread); ++ cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, t0, cas_success, slow_case); ++ // cas failed here if slow_case == NULL ++ if (flag->is_valid()) { ++ li(flag, 1); ++ j(counter); ++ } ++ ++ // If the biasing toward our thread failed, then another thread ++ // succeeded in biasing it toward itself and we need to revoke that ++ // bias. The revocation will occur in the runtime in the slow case. ++ bind(cas_success); ++ if (flag->is_valid()) { ++ li(flag, 0); ++ bind(counter); ++ } ++ ++ if (counters != NULL) { ++ atomic_incw(Address((address)counters->rebiased_lock_entry_count_addr()), ++ tmp_reg, t0); ++ } ++ } ++ j(done); ++ ++ // don't care flag unless jumping to done ++ bind(try_revoke_bias); ++ // The prototype mark in the klass doesn't have the bias bit set any ++ // more, indicating that objects of this data type are not supposed ++ // to be biased any more. We are going to try to reset the mark of ++ // this object to the prototype value and fail through to the ++ // CAS-based locking scheme. Note that if our CAS fails, it means ++ // that another thread raced us for the privilege of revoking the ++ // bias of this particular object, so it's okay to continue in the ++ // normal locking code. ++ // ++ // FIXME: due to a lack of registers we currently blow away the age ++ // bits in this situation. Should attempt to preserve them. ++ { ++ Label cas_success, nope; ++ load_prototype_header(tmp_reg, obj_reg); ++ cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, t0, cas_success, &nope); ++ bind(cas_success); ++ ++ // Fall through to the normal CAS-based lock, because no matter what ++ // the result of the above CAS, some thread must have succeeded in ++ // removing the bias bit from the object's header. ++ if (counters != NULL) { ++ atomic_incw(Address((address)counters->revoked_lock_entry_count_addr()), ++ tmp_reg, t0); ++ } ++ bind(nope); ++ } ++ ++ bind(cas_label); ++} ++ ++void MacroAssembler::biased_locking_exit(Register obj_reg, Register tmp_reg, Label& done, Register flag) { ++ assert(UseBiasedLocking, "why call this otherwise"); ++ ++ // Check for biased locking unlock case, which is a no-op ++ // Note: we do not have to check the thread ID for two reasons. ++ // First, the interpreter checks for IllegalMonitorStateException at ++ // a higher level. Second, if the bias was revoke while we held the ++ // lock, the object could not be rebiased toward another, so ++ // the bias bit would be clear. ++ ld(tmp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); ++ andi(tmp_reg, tmp_reg, markWord::biased_lock_mask_in_place); ++ sub(tmp_reg, tmp_reg, markWord::biased_lock_pattern); ++ if (flag->is_valid()) { ++ mv(flag, tmp_reg); ++ } ++ beqz(tmp_reg, done); ++} ++ ++void MacroAssembler::load_prototype_header(Register dst, Register src) { ++ load_klass(dst, src); ++ ld(dst, Address(dst, Klass::prototype_header_offset())); ++} ++ ++void MacroAssembler::atomic_incw(Register counter_addr, Register tmp) { ++ Label retry_load; ++ bind(retry_load); ++ lr_w(tmp, counter_addr); ++ addw(tmp, tmp, 1); ++ sc_w(tmp, tmp, counter_addr); ++ bnez(tmp, retry_load); ++} ++ ++// Move the address of the polling page into dest. ++void MacroAssembler::get_polling_page(Register dest, relocInfo::relocType rtype) { ++ ld(dest, Address(xthread, JavaThread::polling_page_offset())); ++} ++ ++// Read the polling page. The address of the polling page must ++// already be in r. ++void MacroAssembler::read_polling_page(Register r, int32_t offset, relocInfo::relocType rtype) { ++ relocate(rtype, [&] { ++ lwu(zr, Address(r, offset)); ++ }); ++} ++ ++void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { ++#ifdef ASSERT ++ { ++ ThreadInVMfromUnknown tiv; ++ assert (UseCompressedOops, "should only be used for compressed oops"); ++ assert (Universe::heap() != NULL, "java heap should be initialized"); ++ assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); ++ assert(Universe::heap()->is_in(JNIHandles::resolve(obj)), "should be real oop"); ++ } ++#endif ++ int oop_index = oop_recorder()->find_index(obj); ++ relocate(oop_Relocation::spec(oop_index), [&] { ++ li32(dst, 0xDEADBEEF); ++ }); ++ zero_extend(dst, dst, 32); ++} ++ ++void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { ++ assert (UseCompressedClassPointers, "should only be used for compressed headers"); ++ assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); ++ int index = oop_recorder()->find_index(k); ++ assert(!Universe::heap()->is_in(k), "should not be an oop"); ++ ++ narrowKlass nk = CompressedKlassPointers::encode(k); ++ relocate(metadata_Relocation::spec(index), [&] { ++ li32(dst, nk); ++ }); ++ zero_extend(dst, dst, 32); ++} ++ ++// Maybe emit a call via a trampoline. If the code cache is small ++// trampolines won't be emitted. ++address MacroAssembler::trampoline_call(Address entry, CodeBuffer* cbuf) { ++ assert(JavaThread::current()->is_Compiler_thread(), "just checking"); ++ assert(entry.rspec().type() == relocInfo::runtime_call_type || ++ entry.rspec().type() == relocInfo::opt_virtual_call_type || ++ entry.rspec().type() == relocInfo::static_call_type || ++ entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type"); ++ ++ // We need a trampoline if branches are far. ++ if (far_branches()) { ++ bool in_scratch_emit_size = false; ++#ifdef COMPILER2 ++ // We don't want to emit a trampoline if C2 is generating dummy ++ // code during its branch shortening phase. ++ CompileTask* task = ciEnv::current()->task(); ++ in_scratch_emit_size = ++ (task != NULL && is_c2_compile(task->comp_level()) && ++ Compile::current()->output()->in_scratch_emit_size()); ++#endif ++ if (!in_scratch_emit_size) { ++ address stub = emit_trampoline_stub(offset(), entry.target()); ++ if (stub == NULL) { ++ postcond(pc() == badAddress); ++ return NULL; // CodeCache is full ++ } ++ } ++ } ++ ++ if (cbuf != NULL) { cbuf->set_insts_mark(); } ++#ifdef ASSERT ++ if (entry.rspec().type() != relocInfo::runtime_call_type) { ++ assert_alignment(pc()); ++ } ++#endif ++ relocate(entry.rspec(), [&] { ++ if (!far_branches()) { ++ jal(entry.target()); ++ } else { ++ jal(pc()); ++ } ++ }); ++ // just need to return a non-null address ++ postcond(pc() != badAddress); ++ return pc(); ++} ++ ++address MacroAssembler::ic_call(address entry, jint method_index) { ++ RelocationHolder rh = virtual_call_Relocation::spec(pc(), method_index); ++ IncompressibleRegion ir(this); // relocations ++ movptr(t1, (address)Universe::non_oop_word()); ++ assert_cond(entry != NULL); ++ return trampoline_call(Address(entry, rh)); ++} ++ ++// Emit a trampoline stub for a call to a target which is too far away. ++// ++// code sequences: ++// ++// call-site: ++// branch-and-link to or ++// ++// Related trampoline stub for this call site in the stub section: ++// load the call target from the constant pool ++// branch (RA still points to the call site above) ++ ++address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset, ++ address dest) { ++ address stub = start_a_stub(NativeInstruction::instruction_size ++ + NativeCallTrampolineStub::instruction_size); ++ if (stub == NULL) { ++ return NULL; // CodeBuffer::expand failed ++ } ++ ++ // Create a trampoline stub relocation which relates this trampoline stub ++ // with the call instruction at insts_call_instruction_offset in the ++ // instructions code-section. ++ ++ // Make sure the address of destination 8-byte aligned after 3 instructions. ++ align(wordSize, NativeCallTrampolineStub::data_offset); ++ ++ RelocationHolder rh = trampoline_stub_Relocation::spec(code()->insts()->start() + ++ insts_call_instruction_offset); ++ const int stub_start_offset = offset(); ++ relocate(rh, [&] { ++ // Now, create the trampoline stub's code: ++ // - load the call ++ // - call ++ Label target; ++ ld(t0, target); // auipc + ld ++ jr(t0); // jalr ++ bind(target); ++ assert(offset() - stub_start_offset == NativeCallTrampolineStub::data_offset, ++ "should be"); ++ assert(offset() % wordSize == 0, "bad alignment"); ++ emit_int64((int64_t)dest); ++ }); ++ ++ const address stub_start_addr = addr_at(stub_start_offset); ++ ++ assert(is_NativeCallTrampolineStub_at(stub_start_addr), "doesn't look like a trampoline"); ++ ++ end_a_stub(); ++ return stub_start_addr; ++} ++ ++Address MacroAssembler::add_memory_helper(const Address dst, Register tmp) { ++ switch (dst.getMode()) { ++ case Address::base_plus_offset: ++ // This is the expected mode, although we allow all the other ++ // forms below. ++ return form_address(tmp, dst.base(), dst.offset()); ++ default: ++ la(tmp, dst); ++ return Address(tmp); ++ } ++} ++ ++void MacroAssembler::increment(const Address dst, int64_t value, Register tmp1, Register tmp2) { ++ assert(((dst.getMode() == Address::base_plus_offset && ++ is_simm12(dst.offset())) || is_simm12(value)), ++ "invalid value and address mode combination"); ++ Address adr = add_memory_helper(dst, tmp2); ++ assert(!adr.uses(tmp1), "invalid dst for address increment"); ++ ld(tmp1, adr); ++ add(tmp1, tmp1, value, tmp2); ++ sd(tmp1, adr); ++} ++ ++void MacroAssembler::incrementw(const Address dst, int32_t value, Register tmp1, Register tmp2) { ++ assert(((dst.getMode() == Address::base_plus_offset && ++ is_simm12(dst.offset())) || is_simm12(value)), ++ "invalid value and address mode combination"); ++ Address adr = add_memory_helper(dst, tmp2); ++ assert(!adr.uses(tmp1), "invalid dst for address increment"); ++ lwu(tmp1, adr); ++ addw(tmp1, tmp1, value, tmp2); ++ sw(tmp1, adr); ++} ++ ++void MacroAssembler::decrement(const Address dst, int64_t value, Register tmp1, Register tmp2) { ++ assert(((dst.getMode() == Address::base_plus_offset && ++ is_simm12(dst.offset())) || is_simm12(value)), ++ "invalid value and address mode combination"); ++ Address adr = add_memory_helper(dst, tmp2); ++ assert(!adr.uses(tmp1), "invalid dst for address decrement"); ++ ld(tmp1, adr); ++ sub(tmp1, tmp1, value, tmp2); ++ sd(tmp1, adr); ++} ++ ++void MacroAssembler::decrementw(const Address dst, int32_t value, Register tmp1, Register tmp2) { ++ assert(((dst.getMode() == Address::base_plus_offset && ++ is_simm12(dst.offset())) || is_simm12(value)), ++ "invalid value and address mode combination"); ++ Address adr = add_memory_helper(dst, tmp2); ++ assert(!adr.uses(tmp1), "invalid dst for address decrement"); ++ lwu(tmp1, adr); ++ subw(tmp1, tmp1, value, tmp2); ++ sw(tmp1, adr); ++} ++ ++void MacroAssembler::cmpptr(Register src1, Address src2, Label& equal) { ++ assert_different_registers(src1, t0); ++ relocate(src2.rspec(), [&] { ++ int32_t offset; ++ la_patchable(t0, src2, offset); ++ ld(t0, Address(t0, offset)); ++ }); ++ beq(src1, t0, equal); ++} ++ ++void MacroAssembler::load_method_holder_cld(Register result, Register method) { ++ load_method_holder(result, method); ++ ld(result, Address(result, InstanceKlass::class_loader_data_offset())); ++} ++ ++void MacroAssembler::load_method_holder(Register holder, Register method) { ++ ld(holder, Address(method, Method::const_offset())); // ConstMethod* ++ ld(holder, Address(holder, ConstMethod::constants_offset())); // ConstantPool* ++ ld(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass* ++} ++ ++// string indexof ++// compute index by trailing zeros ++void MacroAssembler::compute_index(Register haystack, Register trailing_zeros, ++ Register match_mask, Register result, ++ Register ch2, Register tmp, ++ bool haystack_isL) { ++ int haystack_chr_shift = haystack_isL ? 0 : 1; ++ srl(match_mask, match_mask, trailing_zeros); ++ srli(match_mask, match_mask, 1); ++ srli(tmp, trailing_zeros, LogBitsPerByte); ++ if (!haystack_isL) andi(tmp, tmp, 0xE); ++ add(haystack, haystack, tmp); ++ ld(ch2, Address(haystack)); ++ if (!haystack_isL) srli(tmp, tmp, haystack_chr_shift); ++ add(result, result, tmp); ++} ++ ++// string indexof ++// Find pattern element in src, compute match mask, ++// only the first occurrence of 0x80/0x8000 at low bits is the valid match index ++// match mask patterns and corresponding indices would be like: ++// - 0x8080808080808080 (Latin1) ++// - 7 6 5 4 3 2 1 0 (match index) ++// - 0x8000800080008000 (UTF16) ++// - 3 2 1 0 (match index) ++void MacroAssembler::compute_match_mask(Register src, Register pattern, Register match_mask, ++ Register mask1, Register mask2) { ++ xorr(src, pattern, src); ++ sub(match_mask, src, mask1); ++ orr(src, src, mask2); ++ notr(src, src); ++ andr(match_mask, match_mask, src); ++} ++ ++#ifdef COMPILER2 ++// Code for BigInteger::mulAdd instrinsic ++// out = x10 ++// in = x11 ++// offset = x12 (already out.length-offset) ++// len = x13 ++// k = x14 ++// tmp = x28 ++// ++// pseudo code from java implementation: ++// long kLong = k & LONG_MASK; ++// carry = 0; ++// offset = out.length-offset - 1; ++// for (int j = len - 1; j >= 0; j--) { ++// product = (in[j] & LONG_MASK) * kLong + (out[offset] & LONG_MASK) + carry; ++// out[offset--] = (int)product; ++// carry = product >>> 32; ++// } ++// return (int)carry; ++void MacroAssembler::mul_add(Register out, Register in, Register offset, ++ Register len, Register k, Register tmp) { ++ Label L_tail_loop, L_unroll, L_end; ++ mv(tmp, out); ++ mv(out, zr); ++ blez(len, L_end); ++ zero_extend(k, k, 32); ++ slliw(t0, offset, LogBytesPerInt); ++ add(offset, tmp, t0); ++ slliw(t0, len, LogBytesPerInt); ++ add(in, in, t0); ++ ++ const int unroll = 8; ++ mv(tmp, unroll); ++ blt(len, tmp, L_tail_loop); ++ bind(L_unroll); ++ for (int i = 0; i < unroll; i++) { ++ sub(in, in, BytesPerInt); ++ lwu(t0, Address(in, 0)); ++ mul(t1, t0, k); ++ add(t0, t1, out); ++ sub(offset, offset, BytesPerInt); ++ lwu(t1, Address(offset, 0)); ++ add(t0, t0, t1); ++ sw(t0, Address(offset, 0)); ++ srli(out, t0, 32); ++ } ++ subw(len, len, tmp); ++ bge(len, tmp, L_unroll); ++ ++ bind(L_tail_loop); ++ blez(len, L_end); ++ sub(in, in, BytesPerInt); ++ lwu(t0, Address(in, 0)); ++ mul(t1, t0, k); ++ add(t0, t1, out); ++ sub(offset, offset, BytesPerInt); ++ lwu(t1, Address(offset, 0)); ++ add(t0, t0, t1); ++ sw(t0, Address(offset, 0)); ++ srli(out, t0, 32); ++ subw(len, len, 1); ++ j(L_tail_loop); ++ ++ bind(L_end); ++} ++ ++// add two unsigned input and output carry ++void MacroAssembler::cad(Register dst, Register src1, Register src2, Register carry) ++{ ++ assert_different_registers(dst, carry); ++ assert_different_registers(dst, src2); ++ add(dst, src1, src2); ++ sltu(carry, dst, src2); ++} ++ ++// add two input with carry ++void MacroAssembler::adc(Register dst, Register src1, Register src2, Register carry) { ++ assert_different_registers(dst, carry); ++ add(dst, src1, src2); ++ add(dst, dst, carry); ++} ++ ++// add two unsigned input with carry and output carry ++void MacroAssembler::cadc(Register dst, Register src1, Register src2, Register carry) { ++ assert_different_registers(dst, src2); ++ adc(dst, src1, src2, carry); ++ sltu(carry, dst, src2); ++} ++ ++void MacroAssembler::add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo, ++ Register src1, Register src2, Register carry) { ++ cad(dest_lo, dest_lo, src1, carry); ++ add(dest_hi, dest_hi, carry); ++ cad(dest_lo, dest_lo, src2, carry); ++ add(final_dest_hi, dest_hi, carry); ++} ++ ++/** ++ * Multiply 32 bit by 32 bit first loop. ++ */ ++void MacroAssembler::multiply_32_x_32_loop(Register x, Register xstart, Register x_xstart, ++ Register y, Register y_idx, Register z, ++ Register carry, Register product, ++ Register idx, Register kdx) { ++ // jlong carry, x[], y[], z[]; ++ // for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx--, kdx--) { ++ // long product = y[idx] * x[xstart] + carry; ++ // z[kdx] = (int)product; ++ // carry = product >>> 32; ++ // } ++ // z[xstart] = (int)carry; ++ ++ Label L_first_loop, L_first_loop_exit; ++ blez(idx, L_first_loop_exit); ++ ++ shadd(t0, xstart, x, t0, LogBytesPerInt); ++ lwu(x_xstart, Address(t0, 0)); ++ ++ bind(L_first_loop); ++ subw(idx, idx, 1); ++ shadd(t0, idx, y, t0, LogBytesPerInt); ++ lwu(y_idx, Address(t0, 0)); ++ mul(product, x_xstart, y_idx); ++ add(product, product, carry); ++ srli(carry, product, 32); ++ subw(kdx, kdx, 1); ++ shadd(t0, kdx, z, t0, LogBytesPerInt); ++ sw(product, Address(t0, 0)); ++ bgtz(idx, L_first_loop); ++ ++ bind(L_first_loop_exit); ++} ++ ++/** ++ * Multiply 64 bit by 64 bit first loop. ++ */ ++void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Register x_xstart, ++ Register y, Register y_idx, Register z, ++ Register carry, Register product, ++ Register idx, Register kdx) { ++ // ++ // jlong carry, x[], y[], z[]; ++ // for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx--, kdx--) { ++ // huge_128 product = y[idx] * x[xstart] + carry; ++ // z[kdx] = (jlong)product; ++ // carry = (jlong)(product >>> 64); ++ // } ++ // z[xstart] = carry; ++ // ++ ++ Label L_first_loop, L_first_loop_exit; ++ Label L_one_x, L_one_y, L_multiply; ++ ++ subw(xstart, xstart, 1); ++ bltz(xstart, L_one_x); ++ ++ shadd(t0, xstart, x, t0, LogBytesPerInt); ++ ld(x_xstart, Address(t0, 0)); ++ ror_imm(x_xstart, x_xstart, 32); // convert big-endian to little-endian ++ ++ bind(L_first_loop); ++ subw(idx, idx, 1); ++ bltz(idx, L_first_loop_exit); ++ subw(idx, idx, 1); ++ bltz(idx, L_one_y); ++ ++ shadd(t0, idx, y, t0, LogBytesPerInt); ++ ld(y_idx, Address(t0, 0)); ++ ror_imm(y_idx, y_idx, 32); // convert big-endian to little-endian ++ bind(L_multiply); ++ ++ mulhu(t0, x_xstart, y_idx); ++ mul(product, x_xstart, y_idx); ++ cad(product, product, carry, t1); ++ adc(carry, t0, zr, t1); ++ ++ subw(kdx, kdx, 2); ++ ror_imm(product, product, 32); // back to big-endian ++ shadd(t0, kdx, z, t0, LogBytesPerInt); ++ sd(product, Address(t0, 0)); ++ ++ j(L_first_loop); ++ ++ bind(L_one_y); ++ lwu(y_idx, Address(y, 0)); ++ j(L_multiply); ++ ++ bind(L_one_x); ++ lwu(x_xstart, Address(x, 0)); ++ j(L_first_loop); ++ ++ bind(L_first_loop_exit); ++} ++ ++/** ++ * Multiply 128 bit by 128 bit. Unrolled inner loop. ++ * ++ */ ++void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, ++ Register carry, Register carry2, ++ Register idx, Register jdx, ++ Register yz_idx1, Register yz_idx2, ++ Register tmp, Register tmp3, Register tmp4, ++ Register tmp6, Register product_hi) { ++ // jlong carry, x[], y[], z[]; ++ // int kdx = xstart+1; ++ // for (int idx=ystart-2; idx >= 0; idx -= 2) { // Third loop ++ // huge_128 tmp3 = (y[idx+1] * product_hi) + z[kdx+idx+1] + carry; ++ // jlong carry2 = (jlong)(tmp3 >>> 64); ++ // huge_128 tmp4 = (y[idx] * product_hi) + z[kdx+idx] + carry2; ++ // carry = (jlong)(tmp4 >>> 64); ++ // z[kdx+idx+1] = (jlong)tmp3; ++ // z[kdx+idx] = (jlong)tmp4; ++ // } ++ // idx += 2; ++ // if (idx > 0) { ++ // yz_idx1 = (y[idx] * product_hi) + z[kdx+idx] + carry; ++ // z[kdx+idx] = (jlong)yz_idx1; ++ // carry = (jlong)(yz_idx1 >>> 64); ++ // } ++ // ++ ++ Label L_third_loop, L_third_loop_exit, L_post_third_loop_done; ++ ++ srliw(jdx, idx, 2); ++ ++ bind(L_third_loop); ++ ++ subw(jdx, jdx, 1); ++ bltz(jdx, L_third_loop_exit); ++ subw(idx, idx, 4); ++ ++ shadd(t0, idx, y, t0, LogBytesPerInt); ++ ld(yz_idx2, Address(t0, 0)); ++ ld(yz_idx1, Address(t0, wordSize)); ++ ++ shadd(tmp6, idx, z, t0, LogBytesPerInt); ++ ++ ror_imm(yz_idx1, yz_idx1, 32); // convert big-endian to little-endian ++ ror_imm(yz_idx2, yz_idx2, 32); ++ ++ ld(t1, Address(tmp6, 0)); ++ ld(t0, Address(tmp6, wordSize)); ++ ++ mul(tmp3, product_hi, yz_idx1); // yz_idx1 * product_hi -> tmp4:tmp3 ++ mulhu(tmp4, product_hi, yz_idx1); ++ ++ ror_imm(t0, t0, 32, tmp); // convert big-endian to little-endian ++ ror_imm(t1, t1, 32, tmp); ++ ++ mul(tmp, product_hi, yz_idx2); // yz_idx2 * product_hi -> carry2:tmp ++ mulhu(carry2, product_hi, yz_idx2); ++ ++ cad(tmp3, tmp3, carry, carry); ++ adc(tmp4, tmp4, zr, carry); ++ cad(tmp3, tmp3, t0, t0); ++ cadc(tmp4, tmp4, tmp, t0); ++ adc(carry, carry2, zr, t0); ++ cad(tmp4, tmp4, t1, carry2); ++ adc(carry, carry, zr, carry2); ++ ++ ror_imm(tmp3, tmp3, 32); // convert little-endian to big-endian ++ ror_imm(tmp4, tmp4, 32); ++ sd(tmp4, Address(tmp6, 0)); ++ sd(tmp3, Address(tmp6, wordSize)); ++ ++ j(L_third_loop); ++ ++ bind(L_third_loop_exit); ++ ++ andi(idx, idx, 0x3); ++ beqz(idx, L_post_third_loop_done); ++ ++ Label L_check_1; ++ subw(idx, idx, 2); ++ bltz(idx, L_check_1); ++ ++ shadd(t0, idx, y, t0, LogBytesPerInt); ++ ld(yz_idx1, Address(t0, 0)); ++ ror_imm(yz_idx1, yz_idx1, 32); ++ ++ mul(tmp3, product_hi, yz_idx1); // yz_idx1 * product_hi -> tmp4:tmp3 ++ mulhu(tmp4, product_hi, yz_idx1); ++ ++ shadd(t0, idx, z, t0, LogBytesPerInt); ++ ld(yz_idx2, Address(t0, 0)); ++ ror_imm(yz_idx2, yz_idx2, 32, tmp); ++ ++ add2_with_carry(carry, tmp4, tmp3, carry, yz_idx2, tmp); ++ ++ ror_imm(tmp3, tmp3, 32, tmp); ++ sd(tmp3, Address(t0, 0)); ++ ++ bind(L_check_1); ++ ++ andi(idx, idx, 0x1); ++ subw(idx, idx, 1); ++ bltz(idx, L_post_third_loop_done); ++ shadd(t0, idx, y, t0, LogBytesPerInt); ++ lwu(tmp4, Address(t0, 0)); ++ mul(tmp3, tmp4, product_hi); // tmp4 * product_hi -> carry2:tmp3 ++ mulhu(carry2, tmp4, product_hi); ++ ++ shadd(t0, idx, z, t0, LogBytesPerInt); ++ lwu(tmp4, Address(t0, 0)); ++ ++ add2_with_carry(carry2, carry2, tmp3, tmp4, carry, t0); ++ ++ shadd(t0, idx, z, t0, LogBytesPerInt); ++ sw(tmp3, Address(t0, 0)); ++ ++ slli(t0, carry2, 32); ++ srli(carry, tmp3, 32); ++ orr(carry, carry, t0); ++ ++ bind(L_post_third_loop_done); ++} ++ ++/** ++ * Code for BigInteger::multiplyToLen() intrinsic. ++ * ++ * x10: x ++ * x11: xlen ++ * x12: y ++ * x13: ylen ++ * x14: z ++ * x15: zlen ++ * x16: tmp1 ++ * x17: tmp2 ++ * x7: tmp3 ++ * x28: tmp4 ++ * x29: tmp5 ++ * x30: tmp6 ++ * x31: tmp7 ++ */ ++void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Register ylen, ++ Register z, Register zlen, ++ Register tmp1, Register tmp2, Register tmp3, Register tmp4, ++ Register tmp5, Register tmp6, Register product_hi) { ++ assert_different_registers(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6); ++ ++ const Register idx = tmp1; ++ const Register kdx = tmp2; ++ const Register xstart = tmp3; ++ ++ const Register y_idx = tmp4; ++ const Register carry = tmp5; ++ const Register product = xlen; ++ const Register x_xstart = zlen; // reuse register ++ ++ mv(idx, ylen); // idx = ylen; ++ mv(kdx, zlen); // kdx = xlen+ylen; ++ mv(carry, zr); // carry = 0; ++ ++ Label L_multiply_64_x_64_loop, L_done; ++ ++ subw(xstart, xlen, 1); ++ bltz(xstart, L_done); ++ ++ const Register jdx = tmp1; ++ ++ if (AvoidUnalignedAccesses) { ++ // Check if x and y are both 8-byte aligned. ++ orr(t0, xlen, ylen); ++ test_bit(t0, t0, 0); ++ beqz(t0, L_multiply_64_x_64_loop); ++ ++ multiply_32_x_32_loop(x, xstart, x_xstart, y, y_idx, z, carry, product, idx, kdx); ++ shadd(t0, xstart, z, t0, LogBytesPerInt); ++ sw(carry, Address(t0, 0)); ++ ++ Label L_second_loop_unaligned; ++ bind(L_second_loop_unaligned); ++ mv(carry, zr); ++ mv(jdx, ylen); ++ subw(xstart, xstart, 1); ++ bltz(xstart, L_done); ++ sub(sp, sp, 2 * wordSize); ++ sd(z, Address(sp, 0)); ++ sd(zr, Address(sp, wordSize)); ++ shadd(t0, xstart, z, t0, LogBytesPerInt); ++ addi(z, t0, 4); ++ shadd(t0, xstart, x, t0, LogBytesPerInt); ++ lwu(product, Address(t0, 0)); ++ Label L_third_loop, L_third_loop_exit; ++ ++ blez(jdx, L_third_loop_exit); ++ ++ bind(L_third_loop); ++ subw(jdx, jdx, 1); ++ shadd(t0, jdx, y, t0, LogBytesPerInt); ++ lwu(t0, Address(t0, 0)); ++ mul(t1, t0, product); ++ add(t0, t1, carry); ++ shadd(tmp6, jdx, z, t1, LogBytesPerInt); ++ lwu(t1, Address(tmp6, 0)); ++ add(t0, t0, t1); ++ sw(t0, Address(tmp6, 0)); ++ srli(carry, t0, 32); ++ bgtz(jdx, L_third_loop); ++ ++ bind(L_third_loop_exit); ++ ld(z, Address(sp, 0)); ++ addi(sp, sp, 2 * wordSize); ++ shadd(t0, xstart, z, t0, LogBytesPerInt); ++ sw(carry, Address(t0, 0)); ++ ++ j(L_second_loop_unaligned); ++ } ++ ++ bind(L_multiply_64_x_64_loop); ++ multiply_64_x_64_loop(x, xstart, x_xstart, y, y_idx, z, carry, product, idx, kdx); ++ ++ Label L_second_loop_aligned; ++ beqz(kdx, L_second_loop_aligned); ++ ++ Label L_carry; ++ subw(kdx, kdx, 1); ++ beqz(kdx, L_carry); ++ ++ shadd(t0, kdx, z, t0, LogBytesPerInt); ++ sw(carry, Address(t0, 0)); ++ srli(carry, carry, 32); ++ subw(kdx, kdx, 1); ++ ++ bind(L_carry); ++ shadd(t0, kdx, z, t0, LogBytesPerInt); ++ sw(carry, Address(t0, 0)); ++ ++ // Second and third (nested) loops. ++ // ++ // for (int i = xstart-1; i >= 0; i--) { // Second loop ++ // carry = 0; ++ // for (int jdx=ystart, k=ystart+1+i; jdx >= 0; jdx--, k--) { // Third loop ++ // long product = (y[jdx] & LONG_MASK) * (x[i] & LONG_MASK) + ++ // (z[k] & LONG_MASK) + carry; ++ // z[k] = (int)product; ++ // carry = product >>> 32; ++ // } ++ // z[i] = (int)carry; ++ // } ++ // ++ // i = xlen, j = tmp1, k = tmp2, carry = tmp5, x[i] = product_hi ++ ++ bind(L_second_loop_aligned); ++ mv(carry, zr); // carry = 0; ++ mv(jdx, ylen); // j = ystart+1 ++ ++ subw(xstart, xstart, 1); // i = xstart-1; ++ bltz(xstart, L_done); ++ ++ sub(sp, sp, 4 * wordSize); ++ sd(z, Address(sp, 0)); ++ ++ Label L_last_x; ++ shadd(t0, xstart, z, t0, LogBytesPerInt); ++ addi(z, t0, 4); ++ subw(xstart, xstart, 1); // i = xstart-1; ++ bltz(xstart, L_last_x); ++ ++ shadd(t0, xstart, x, t0, LogBytesPerInt); ++ ld(product_hi, Address(t0, 0)); ++ ror_imm(product_hi, product_hi, 32); // convert big-endian to little-endian ++ ++ Label L_third_loop_prologue; ++ bind(L_third_loop_prologue); ++ ++ sd(ylen, Address(sp, wordSize)); ++ sd(x, Address(sp, 2 * wordSize)); ++ sd(xstart, Address(sp, 3 * wordSize)); ++ multiply_128_x_128_loop(y, z, carry, x, jdx, ylen, product, ++ tmp2, x_xstart, tmp3, tmp4, tmp6, product_hi); ++ ld(z, Address(sp, 0)); ++ ld(ylen, Address(sp, wordSize)); ++ ld(x, Address(sp, 2 * wordSize)); ++ ld(xlen, Address(sp, 3 * wordSize)); // copy old xstart -> xlen ++ addi(sp, sp, 4 * wordSize); ++ ++ addiw(tmp3, xlen, 1); ++ shadd(t0, tmp3, z, t0, LogBytesPerInt); ++ sw(carry, Address(t0, 0)); ++ ++ subw(tmp3, tmp3, 1); ++ bltz(tmp3, L_done); ++ ++ srli(carry, carry, 32); ++ shadd(t0, tmp3, z, t0, LogBytesPerInt); ++ sw(carry, Address(t0, 0)); ++ j(L_second_loop_aligned); ++ ++ // Next infrequent code is moved outside loops. ++ bind(L_last_x); ++ lwu(product_hi, Address(x, 0)); ++ j(L_third_loop_prologue); ++ ++ bind(L_done); ++} ++#endif ++ ++// Count bits of trailing zero chars from lsb to msb until first non-zero element. ++// For LL case, one byte for one element, so shift 8 bits once, and for other case, ++// shift 16 bits once. ++void MacroAssembler::ctzc_bit(Register Rd, Register Rs, bool isLL, Register tmp1, Register tmp2) { ++ if (UseZbb) { ++ assert_different_registers(Rd, Rs, tmp1); ++ int step = isLL ? 8 : 16; ++ ctz(Rd, Rs); ++ andi(tmp1, Rd, step - 1); ++ sub(Rd, Rd, tmp1); ++ return; ++ } ++ ++ assert_different_registers(Rd, Rs, tmp1, tmp2); ++ Label Loop; ++ int step = isLL ? 8 : 16; ++ mv(Rd, -step); ++ mv(tmp2, Rs); ++ ++ bind(Loop); ++ addi(Rd, Rd, step); ++ andi(tmp1, tmp2, ((1 << step) - 1)); ++ srli(tmp2, tmp2, step); ++ beqz(tmp1, Loop); ++} ++ ++// This instruction reads adjacent 4 bytes from the lower half of source register, ++// inflate into a register, for example: ++// Rs: A7A6A5A4A3A2A1A0 ++// Rd: 00A300A200A100A0 ++void MacroAssembler::inflate_lo32(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ assert_different_registers(Rd, Rs, tmp1, tmp2); ++ ++ mv(tmp1, 0xFF); ++ mv(Rd, zr); ++ for (int i = 0; i <= 3; i++) { ++ andr(tmp2, Rs, tmp1); ++ if (i) { ++ slli(tmp2, tmp2, i * 8); ++ } ++ orr(Rd, Rd, tmp2); ++ if (i != 3) { ++ slli(tmp1, tmp1, 8); ++ } ++ } ++} ++ ++// This instruction reads adjacent 4 bytes from the upper half of source register, ++// inflate into a register, for example: ++// Rs: A7A6A5A4A3A2A1A0 ++// Rd: 00A700A600A500A4 ++void MacroAssembler::inflate_hi32(Register Rd, Register Rs, Register tmp1, Register tmp2) { ++ assert_different_registers(Rd, Rs, tmp1, tmp2); ++ ++ mv(tmp1, 0xFF00000000); ++ mv(Rd, zr); ++ for (int i = 0; i <= 3; i++) { ++ andr(tmp2, Rs, tmp1); ++ orr(Rd, Rd, tmp2); ++ srli(Rd, Rd, 8); ++ if (i != 3) { ++ slli(tmp1, tmp1, 8); ++ } ++ } ++} ++ ++// The size of the blocks erased by the zero_blocks stub. We must ++// handle anything smaller than this ourselves in zero_words(). ++const int MacroAssembler::zero_words_block_size = 8; ++ ++// zero_words() is used by C2 ClearArray patterns. It is as small as ++// possible, handling small word counts locally and delegating ++// anything larger to the zero_blocks stub. It is expanded many times ++// in compiled code, so it is important to keep it short. ++ ++// ptr: Address of a buffer to be zeroed. ++// cnt: Count in HeapWords. ++// ++// ptr, cnt, and t0 are clobbered. ++address MacroAssembler::zero_words(Register ptr, Register cnt) { ++ assert(is_power_of_2(zero_words_block_size), "adjust this"); ++ assert(ptr == x28 && cnt == x29, "mismatch in register usage"); ++ assert_different_registers(cnt, t0); ++ ++ BLOCK_COMMENT("zero_words {"); ++ ++ mv(t0, zero_words_block_size); ++ Label around, done, done16; ++ bltu(cnt, t0, around); ++ { ++ RuntimeAddress zero_blocks = RuntimeAddress(StubRoutines::riscv::zero_blocks()); ++ assert(zero_blocks.target() != NULL, "zero_blocks stub has not been generated"); ++ if (StubRoutines::riscv::complete()) { ++ address tpc = trampoline_call(zero_blocks); ++ if (tpc == NULL) { ++ DEBUG_ONLY(reset_labels(around)); ++ postcond(pc() == badAddress); ++ return NULL; ++ } ++ } else { ++ jal(zero_blocks); ++ } ++ } ++ bind(around); ++ for (int i = zero_words_block_size >> 1; i > 1; i >>= 1) { ++ Label l; ++ test_bit(t0, cnt, exact_log2(i)); ++ beqz(t0, l); ++ for (int j = 0; j < i; j++) { ++ sd(zr, Address(ptr, 0)); ++ addi(ptr, ptr, 8); ++ } ++ bind(l); ++ } ++ { ++ Label l; ++ test_bit(t0, cnt, 0); ++ beqz(t0, l); ++ sd(zr, Address(ptr, 0)); ++ bind(l); ++ } ++ ++ BLOCK_COMMENT("} zero_words"); ++ postcond(pc() != badAddress); ++ return pc(); ++} ++ ++#define SmallArraySize (18 * BytesPerLong) ++ ++// base: Address of a buffer to be zeroed, 8 bytes aligned. ++// cnt: Immediate count in HeapWords. ++void MacroAssembler::zero_words(Register base, u_int64_t cnt) { ++ assert_different_registers(base, t0, t1); ++ ++ BLOCK_COMMENT("zero_words {"); ++ ++ if (cnt <= SmallArraySize / BytesPerLong) { ++ for (int i = 0; i < (int)cnt; i++) { ++ sd(zr, Address(base, i * wordSize)); ++ } ++ } else { ++ const int unroll = 8; // Number of sd(zr, adr), instructions we'll unroll ++ int remainder = cnt % unroll; ++ for (int i = 0; i < remainder; i++) { ++ sd(zr, Address(base, i * wordSize)); ++ } ++ ++ Label loop; ++ Register cnt_reg = t0; ++ Register loop_base = t1; ++ cnt = cnt - remainder; ++ mv(cnt_reg, cnt); ++ add(loop_base, base, remainder * wordSize); ++ bind(loop); ++ sub(cnt_reg, cnt_reg, unroll); ++ for (int i = 0; i < unroll; i++) { ++ sd(zr, Address(loop_base, i * wordSize)); ++ } ++ add(loop_base, loop_base, unroll * wordSize); ++ bnez(cnt_reg, loop); ++ } ++ ++ BLOCK_COMMENT("} zero_words"); ++} ++ ++// base: Address of a buffer to be filled, 8 bytes aligned. ++// cnt: Count in 8-byte unit. ++// value: Value to be filled with. ++// base will point to the end of the buffer after filling. ++void MacroAssembler::fill_words(Register base, Register cnt, Register value) { ++// Algorithm: ++// ++// t0 = cnt & 7 ++// cnt -= t0 ++// p += t0 ++// switch (t0): ++// switch start: ++// do while cnt ++// cnt -= 8 ++// p[-8] = value ++// case 7: ++// p[-7] = value ++// case 6: ++// p[-6] = value ++// // ... ++// case 1: ++// p[-1] = value ++// case 0: ++// p += 8 ++// do-while end ++// switch end ++ ++ assert_different_registers(base, cnt, value, t0, t1); ++ ++ Label fini, skip, entry, loop; ++ const int unroll = 8; // Number of sd instructions we'll unroll ++ ++ beqz(cnt, fini); ++ ++ andi(t0, cnt, unroll - 1); ++ sub(cnt, cnt, t0); ++ // align 8, so first sd n % 8 = mod, next loop sd 8 * n. ++ shadd(base, t0, base, t1, 3); ++ la(t1, entry); ++ slli(t0, t0, 2); // sd_inst_nums * 4; t0 is cnt % 8, so t1 = t1 - sd_inst_nums * 4, 4 is sizeof(inst) ++ sub(t1, t1, t0); ++ jr(t1); ++ ++ bind(loop); ++ add(base, base, unroll * 8); ++ for (int i = -unroll; i < 0; i++) { ++ sd(value, Address(base, i * 8)); ++ } ++ bind(entry); ++ sub(cnt, cnt, unroll); ++ bgez(cnt, loop); ++ ++ bind(fini); ++} ++ ++#define FCVT_SAFE(FLOATCVT, FLOATSIG) \ ++void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register tmp) { \ ++ Label done; \ ++ assert_different_registers(dst, tmp); \ ++ fclass_##FLOATSIG(tmp, src); \ ++ mv(dst, zr); \ ++ /* check if src is NaN */ \ ++ andi(tmp, tmp, 0b1100000000); \ ++ bnez(tmp, done); \ ++ FLOATCVT(dst, src); \ ++ bind(done); \ ++} ++ ++FCVT_SAFE(fcvt_w_s, s); ++FCVT_SAFE(fcvt_l_s, s); ++FCVT_SAFE(fcvt_w_d, d); ++FCVT_SAFE(fcvt_l_d, d); ++ ++#undef FCVT_SAFE ++ ++#define FCMP(FLOATTYPE, FLOATSIG) \ ++void MacroAssembler::FLOATTYPE##_compare(Register result, FloatRegister Rs1, \ ++ FloatRegister Rs2, int unordered_result) { \ ++ Label Ldone; \ ++ if (unordered_result < 0) { \ ++ /* we want -1 for unordered or less than, 0 for equal and 1 for greater than. */ \ ++ /* installs 1 if gt else 0 */ \ ++ flt_##FLOATSIG(result, Rs2, Rs1); \ ++ /* Rs1 > Rs2, install 1 */ \ ++ bgtz(result, Ldone); \ ++ feq_##FLOATSIG(result, Rs1, Rs2); \ ++ addi(result, result, -1); \ ++ /* Rs1 = Rs2, install 0 */ \ ++ /* NaN or Rs1 < Rs2, install -1 */ \ ++ bind(Ldone); \ ++ } else { \ ++ /* we want -1 for less than, 0 for equal and 1 for unordered or greater than. */ \ ++ /* installs 1 if gt or unordered else 0 */ \ ++ flt_##FLOATSIG(result, Rs1, Rs2); \ ++ /* Rs1 < Rs2, install -1 */ \ ++ bgtz(result, Ldone); \ ++ feq_##FLOATSIG(result, Rs1, Rs2); \ ++ addi(result, result, -1); \ ++ /* Rs1 = Rs2, install 0 */ \ ++ /* NaN or Rs1 > Rs2, install 1 */ \ ++ bind(Ldone); \ ++ neg(result, result); \ ++ } \ ++} ++ ++FCMP(float, s); ++FCMP(double, d); ++ ++#undef FCMP ++ ++// Zero words; len is in bytes ++// Destroys all registers except addr ++// len must be a nonzero multiple of wordSize ++void MacroAssembler::zero_memory(Register addr, Register len, Register tmp) { ++ assert_different_registers(addr, len, tmp, t0, t1); ++ ++#ifdef ASSERT ++ { ++ Label L; ++ andi(t0, len, BytesPerWord - 1); ++ beqz(t0, L); ++ stop("len is not a multiple of BytesPerWord"); ++ bind(L); ++ } ++#endif // ASSERT ++ ++#ifndef PRODUCT ++ block_comment("zero memory"); ++#endif // PRODUCT ++ ++ Label loop; ++ Label entry; ++ ++ // Algorithm: ++ // ++ // t0 = cnt & 7 ++ // cnt -= t0 ++ // p += t0 ++ // switch (t0) { ++ // do { ++ // cnt -= 8 ++ // p[-8] = 0 ++ // case 7: ++ // p[-7] = 0 ++ // case 6: ++ // p[-6] = 0 ++ // ... ++ // case 1: ++ // p[-1] = 0 ++ // case 0: ++ // p += 8 ++ // } while (cnt) ++ // } ++ ++ const int unroll = 8; // Number of sd(zr) instructions we'll unroll ++ ++ srli(len, len, LogBytesPerWord); ++ andi(t0, len, unroll - 1); // t0 = cnt % unroll ++ sub(len, len, t0); // cnt -= unroll ++ // tmp always points to the end of the region we're about to zero ++ shadd(tmp, t0, addr, t1, LogBytesPerWord); ++ la(t1, entry); ++ slli(t0, t0, 2); ++ sub(t1, t1, t0); ++ jr(t1); ++ bind(loop); ++ sub(len, len, unroll); ++ for (int i = -unroll; i < 0; i++) { ++ sd(zr, Address(tmp, i * wordSize)); ++ } ++ bind(entry); ++ add(tmp, tmp, unroll * wordSize); ++ bnez(len, loop); ++} ++ ++// shift left by shamt and add ++// Rd = (Rs1 << shamt) + Rs2 ++void MacroAssembler::shadd(Register Rd, Register Rs1, Register Rs2, Register tmp, int shamt) { ++ if (UseZba) { ++ if (shamt == 1) { ++ sh1add(Rd, Rs1, Rs2); ++ return; ++ } else if (shamt == 2) { ++ sh2add(Rd, Rs1, Rs2); ++ return; ++ } else if (shamt == 3) { ++ sh3add(Rd, Rs1, Rs2); ++ return; ++ } ++ } ++ ++ if (shamt != 0) { ++ slli(tmp, Rs1, shamt); ++ add(Rd, Rs2, tmp); ++ } else { ++ add(Rd, Rs1, Rs2); ++ } ++} ++ ++void MacroAssembler::zero_extend(Register dst, Register src, int bits) { ++ if (UseZba && bits == 32) { ++ zext_w(dst, src); ++ return; ++ } ++ ++ if (UseZbb && bits == 16) { ++ zext_h(dst, src); ++ return; ++ } ++ ++ if (bits == 8) { ++ zext_b(dst, src); ++ } else { ++ slli(dst, src, XLEN - bits); ++ srli(dst, dst, XLEN - bits); ++ } ++} ++ ++void MacroAssembler::sign_extend(Register dst, Register src, int bits) { ++ if (UseZbb) { ++ if (bits == 8) { ++ sext_b(dst, src); ++ return; ++ } else if (bits == 16) { ++ sext_h(dst, src); ++ return; ++ } ++ } ++ ++ if (bits == 32) { ++ sext_w(dst, src); ++ } else { ++ slli(dst, src, XLEN - bits); ++ srai(dst, dst, XLEN - bits); ++ } ++} ++ ++void MacroAssembler::cmp_l2i(Register dst, Register src1, Register src2, Register tmp) ++{ ++ if (src1 == src2) { ++ mv(dst, zr); ++ return; ++ } ++ Label done; ++ Register left = src1; ++ Register right = src2; ++ if (dst == src1) { ++ assert_different_registers(dst, src2, tmp); ++ mv(tmp, src1); ++ left = tmp; ++ } else if (dst == src2) { ++ assert_different_registers(dst, src1, tmp); ++ mv(tmp, src2); ++ right = tmp; ++ } ++ ++ // installs 1 if gt else 0 ++ slt(dst, right, left); ++ bnez(dst, done); ++ slt(dst, left, right); ++ // dst = -1 if lt; else if eq , dst = 0 ++ neg(dst, dst); ++ bind(done); ++} ++ ++void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos, Register tmp) { ++ assert(bit_pos < 64, "invalid bit range"); ++ if (UseZbs) { ++ bexti(Rd, Rs, bit_pos); ++ return; ++ } ++ andi(Rd, Rs, 1UL << bit_pos, tmp); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +@@ -0,0 +1,1310 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_MACROASSEMBLER_RISCV_HPP ++#define CPU_RISCV_MACROASSEMBLER_RISCV_HPP ++ ++#include "asm/assembler.inline.hpp" ++#include "metaprogramming/enableIf.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/compressedOops.hpp" ++#include "utilities/powerOfTwo.hpp" ++ ++// MacroAssembler extends Assembler by frequently used macros. ++// ++// Instructions for which a 'better' code sequence exists depending ++// on arguments should also go in here. ++ ++class MacroAssembler: public Assembler { ++ ++ public: ++ MacroAssembler(CodeBuffer* code) : Assembler(code) {} ++ ++ virtual ~MacroAssembler() {} ++ ++ void safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod); ++ ++ // Alignment ++ void align(int modulus, int extra_offset = 0); ++ ++ static inline void assert_alignment(address pc, int alignment = NativeInstruction::instruction_size) { ++ assert(is_aligned(pc, alignment), "bad alignment"); ++ } ++ ++ // Stack frame creation/removal ++ // Note that SP must be updated to the right place before saving/restoring RA and FP ++ // because signal based thread suspend/resume could happen asynchronously. ++ void enter() { ++ addi(sp, sp, - 2 * wordSize); ++ sd(ra, Address(sp, wordSize)); ++ sd(fp, Address(sp)); ++ addi(fp, sp, 2 * wordSize); ++ } ++ ++ void leave() { ++ addi(sp, fp, - 2 * wordSize); ++ ld(fp, Address(sp)); ++ ld(ra, Address(sp, wordSize)); ++ addi(sp, sp, 2 * wordSize); ++ } ++ ++ ++ // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information) ++ // The pointer will be loaded into the thread register. ++ void get_thread(Register thread); ++ ++ // Support for VM calls ++ // ++ // It is imperative that all calls into the VM are handled via the call_VM macros. ++ // They make sure that the stack linkage is setup correctly. call_VM's correspond ++ // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points. ++ ++ void call_VM(Register oop_result, ++ address entry_point, ++ bool check_exceptions = true); ++ void call_VM(Register oop_result, ++ address entry_point, ++ Register arg_1, ++ bool check_exceptions = true); ++ void call_VM(Register oop_result, ++ address entry_point, ++ Register arg_1, Register arg_2, ++ bool check_exceptions = true); ++ void call_VM(Register oop_result, ++ address entry_point, ++ Register arg_1, Register arg_2, Register arg_3, ++ bool check_exceptions = true); ++ ++ // Overloadings with last_Java_sp ++ void call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ int number_of_arguments = 0, ++ bool check_exceptions = true); ++ void call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ Register arg_1, ++ bool check_exceptions = true); ++ void call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ Register arg_1, Register arg_2, ++ bool check_exceptions = true); ++ void call_VM(Register oop_result, ++ Register last_java_sp, ++ address entry_point, ++ Register arg_1, Register arg_2, Register arg_3, ++ bool check_exceptions = true); ++ ++ void get_vm_result(Register oop_result, Register java_thread); ++ void get_vm_result_2(Register metadata_result, Register java_thread); ++ ++ // These always tightly bind to MacroAssembler::call_VM_leaf_base ++ // bypassing the virtual implementation ++ void call_VM_leaf(address entry_point, ++ int number_of_arguments = 0); ++ void call_VM_leaf(address entry_point, ++ Register arg_0); ++ void call_VM_leaf(address entry_point, ++ Register arg_0, Register arg_1); ++ void call_VM_leaf(address entry_point, ++ Register arg_0, Register arg_1, Register arg_2); ++ ++ // These always tightly bind to MacroAssembler::call_VM_base ++ // bypassing the virtual implementation ++ void super_call_VM_leaf(address entry_point, Register arg_0); ++ void super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1); ++ void super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2); ++ void super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2, Register arg_3); ++ ++ // last Java Frame (fills frame anchor) ++ void set_last_Java_frame(Register last_java_sp, Register last_java_fp, address last_java_pc, Register tmp); ++ void set_last_Java_frame(Register last_java_sp, Register last_java_fp, Label &last_java_pc, Register tmp); ++ void set_last_Java_frame(Register last_java_sp, Register last_java_fp, Register last_java_pc, Register tmp); ++ ++ // thread in the default location (xthread) ++ void reset_last_Java_frame(bool clear_fp); ++ ++ virtual void call_VM_leaf_base( ++ address entry_point, // the entry point ++ int number_of_arguments, // the number of arguments to pop after the call ++ Label* retaddr = NULL ++ ); ++ ++ virtual void call_VM_leaf_base( ++ address entry_point, // the entry point ++ int number_of_arguments, // the number of arguments to pop after the call ++ Label& retaddr) { ++ call_VM_leaf_base(entry_point, number_of_arguments, &retaddr); ++ } ++ ++ virtual void call_VM_base( // returns the register containing the thread upon return ++ Register oop_result, // where an oop-result ends up if any; use noreg otherwise ++ Register java_thread, // the thread if computed before ; use noreg otherwise ++ Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise ++ address entry_point, // the entry point ++ int number_of_arguments, // the number of arguments (w/o thread) to pop after the call ++ bool check_exceptions // whether to check for pending exceptions after return ++ ); ++ ++ void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions); ++ ++ virtual void check_and_handle_earlyret(Register java_thread); ++ virtual void check_and_handle_popframe(Register java_thread); ++ ++ void resolve_weak_handle(Register result, Register tmp); ++ void resolve_oop_handle(Register result, Register tmp = x15); ++ void resolve_jobject(Register value, Register thread, Register tmp); ++ ++ void movoop(Register dst, jobject obj, bool immediate = false); ++ void mov_metadata(Register dst, Metadata* obj); ++ void bang_stack_size(Register size, Register tmp); ++ void set_narrow_oop(Register dst, jobject obj); ++ void set_narrow_klass(Register dst, Klass* k); ++ ++ void load_mirror(Register dst, Register method, Register tmp = x15); ++ void access_load_at(BasicType type, DecoratorSet decorators, Register dst, ++ Address src, Register tmp1, Register thread_tmp); ++ void access_store_at(BasicType type, DecoratorSet decorators, Address dst, ++ Register src, Register tmp1, Register thread_tmp); ++ void load_klass(Register dst, Register src, Register tmp = t0); ++ void store_klass(Register dst, Register src, Register tmp = t0); ++ void cmp_klass(Register oop, Register trial_klass, Register tmp1, Register tmp2, Label &L); ++ ++ void encode_klass_not_null(Register r, Register tmp = t0); ++ void decode_klass_not_null(Register r, Register tmp = t0); ++ void encode_klass_not_null(Register dst, Register src, Register tmp); ++ void decode_klass_not_null(Register dst, Register src, Register tmp); ++ void decode_heap_oop_not_null(Register r); ++ void decode_heap_oop_not_null(Register dst, Register src); ++ void decode_heap_oop(Register d, Register s); ++ void decode_heap_oop(Register r) { decode_heap_oop(r, r); } ++ void encode_heap_oop(Register d, Register s); ++ void encode_heap_oop(Register r) { encode_heap_oop(r, r); }; ++ void load_heap_oop(Register dst, Address src, Register tmp1 = noreg, ++ Register thread_tmp = noreg, DecoratorSet decorators = 0); ++ void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg, ++ Register thread_tmp = noreg, DecoratorSet decorators = 0); ++ void store_heap_oop(Address dst, Register src, Register tmp1 = noreg, ++ Register thread_tmp = noreg, DecoratorSet decorators = 0); ++ ++ void store_klass_gap(Register dst, Register src); ++ ++ // currently unimplemented ++ // Used for storing NULL. All other oop constants should be ++ // stored using routines that take a jobject. ++ void store_heap_oop_null(Address dst); ++ ++ // This dummy is to prevent a call to store_heap_oop from ++ // converting a zero (linke NULL) into a Register by giving ++ // the compiler two choices it can't resolve ++ ++ void store_heap_oop(Address dst, void* dummy); ++ ++ // Support for NULL-checks ++ // ++ // Generates code that causes a NULL OS exception if the content of reg is NULL. ++ // If the accessed location is M[reg + offset] and the offset is known, provide the ++ // offset. No explicit code generateion is needed if the offset is within a certain ++ // range (0 <= offset <= page_size). ++ ++ virtual void null_check(Register reg, int offset = -1); ++ static bool needs_explicit_null_check(intptr_t offset); ++ static bool uses_implicit_null_check(void* address); ++ ++ // idiv variant which deals with MINLONG as dividend and -1 as divisor ++ int corrected_idivl(Register result, Register rs1, Register rs2, ++ bool want_remainder); ++ int corrected_idivq(Register result, Register rs1, Register rs2, ++ bool want_remainder); ++ ++ // interface method calling ++ void lookup_interface_method(Register recv_klass, ++ Register intf_klass, ++ RegisterOrConstant itable_index, ++ Register method_result, ++ Register scan_tmp, ++ Label& no_such_interface, ++ bool return_method = true); ++ ++ // virtual method calling ++ // n.n. x86 allows RegisterOrConstant for vtable_index ++ void lookup_virtual_method(Register recv_klass, ++ RegisterOrConstant vtable_index, ++ Register method_result); ++ ++ // Form an addres from base + offset in Rd. Rd my or may not ++ // actually be used: you must use the Address that is returned. It ++ // is up to you to ensure that the shift provided mathces the size ++ // of your data. ++ Address form_address(Register Rd, Register base, int64_t byte_offset); ++ ++ // Sometimes we get misaligned loads and stores, usually from Unsafe ++ // accesses, and these can exceed the offset range. ++ Address legitimize_address(Register Rd, const Address &adr) { ++ if (adr.getMode() == Address::base_plus_offset) { ++ if (!is_simm12(adr.offset())) { ++ return form_address(Rd, adr.base(), adr.offset()); ++ } ++ } ++ return adr; ++ } ++ ++ // allocation ++ void tlab_allocate( ++ Register obj, // result: pointer to object after successful allocation ++ Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise ++ int con_size_in_bytes, // object size in bytes if known at compile time ++ Register tmp1, // temp register ++ Register tmp2, // temp register ++ Label& slow_case, // continuation point of fast allocation fails ++ bool is_far = false ++ ); ++ ++ void eden_allocate( ++ Register obj, // result: pointer to object after successful allocation ++ Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise ++ int con_size_in_bytes, // object size in bytes if known at compile time ++ Register tmp, // temp register ++ Label& slow_case, // continuation point if fast allocation fails ++ bool is_far = false ++ ); ++ ++ // Test sub_klass against super_klass, with fast and slow paths. ++ ++ // The fast path produces a tri-state answer: yes / no / maybe-slow. ++ // One of the three labels can be NULL, meaning take the fall-through. ++ // If super_check_offset is -1, the value is loaded up from super_klass. ++ // No registers are killed, except tmp_reg ++ void check_klass_subtype_fast_path(Register sub_klass, ++ Register super_klass, ++ Register tmp_reg, ++ Label* L_success, ++ Label* L_failure, ++ Label* L_slow_path, ++ Register super_check_offset = noreg); ++ ++ // The reset of the type cehck; must be wired to a corresponding fast path. ++ // It does not repeat the fast path logic, so don't use it standalone. ++ // The tmp1_reg and tmp2_reg can be noreg, if no temps are avaliable. ++ // Updates the sub's secondary super cache as necessary. ++ void check_klass_subtype_slow_path(Register sub_klass, ++ Register super_klass, ++ Register tmp1_reg, ++ Register tmp2_reg, ++ Label* L_success, ++ Label* L_failure); ++ ++ void check_klass_subtype(Register sub_klass, ++ Register super_klass, ++ Register tmp_reg, ++ Label& L_success); ++ ++ Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0); ++ ++ // only if +VerifyOops ++ void verify_oop(Register reg, const char* s = "broken oop"); ++ void verify_oop_addr(Address addr, const char* s = "broken oop addr"); ++ ++ void _verify_method_ptr(Register reg, const char* msg, const char* file, int line) {} ++ void _verify_klass_ptr(Register reg, const char* msg, const char* file, int line) {} ++ ++#define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__) ++#define verify_klass_ptr(reg) _verify_method_ptr(reg, "broken klass " #reg, __FILE__, __LINE__) ++ ++ // A more convenient access to fence for our purposes ++ // We used four bit to indicate the read and write bits in the predecessors and successors, ++ // and extended i for r, o for w if UseConservativeFence enabled. ++ enum Membar_mask_bits { ++ StoreStore = 0b0101, // (pred = ow + succ = ow) ++ LoadStore = 0b1001, // (pred = ir + succ = ow) ++ StoreLoad = 0b0110, // (pred = ow + succ = ir) ++ LoadLoad = 0b1010, // (pred = ir + succ = ir) ++ AnyAny = LoadStore | StoreLoad // (pred = iorw + succ = iorw) ++ }; ++ ++ void membar(uint32_t order_constraint); ++ ++ static void membar_mask_to_pred_succ(uint32_t order_constraint, ++ uint32_t& predecessor, uint32_t& successor) { ++ predecessor = (order_constraint >> 2) & 0x3; ++ successor = order_constraint & 0x3; ++ ++ // extend rw -> iorw: ++ // 01(w) -> 0101(ow) ++ // 10(r) -> 1010(ir) ++ // 11(rw)-> 1111(iorw) ++ if (UseConservativeFence) { ++ predecessor |= predecessor << 2; ++ successor |= successor << 2; ++ } ++ } ++ ++ static int pred_succ_to_membar_mask(uint32_t predecessor, uint32_t successor) { ++ return ((predecessor & 0x3) << 2) | (successor & 0x3); ++ } ++ ++ // prints msg, dumps registers and stops execution ++ void stop(const char* msg); ++ ++ static void debug64(char* msg, int64_t pc, int64_t regs[]); ++ ++ void unimplemented(const char* what = ""); ++ ++ void should_not_reach_here() { stop("should not reach here"); } ++ ++ static address target_addr_for_insn(address insn_addr); ++ ++ // Required platform-specific helpers for Label::patch_instructions. ++ // They _shadow_ the declarations in AbstractAssembler, which are undefined. ++ static int pd_patch_instruction_size(address branch, address target); ++ static void pd_patch_instruction(address branch, address target, const char* file = NULL, int line = 0) { ++ pd_patch_instruction_size(branch, target); ++ } ++ static address pd_call_destination(address branch) { ++ return target_addr_for_insn(branch); ++ } ++ ++ static int patch_oop(address insn_addr, address o); ++ address emit_trampoline_stub(int insts_call_instruction_offset, address target); ++ void emit_static_call_stub(); ++ ++ // The following 4 methods return the offset of the appropriate move instruction ++ ++ // Support for fast byte/short loading with zero extension (depending on particular CPU) ++ int load_unsigned_byte(Register dst, Address src); ++ int load_unsigned_short(Register dst, Address src); ++ ++ // Support for fast byte/short loading with sign extension (depending on particular CPU) ++ int load_signed_byte(Register dst, Address src); ++ int load_signed_short(Register dst, Address src); ++ ++ // Load and store values by size and signed-ness ++ void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg); ++ void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg); ++ ++ public: ++ // Standard pseudo instructions ++ inline void nop() { ++ addi(x0, x0, 0); ++ } ++ ++ inline void mv(Register Rd, Register Rs) { ++ if (Rd != Rs) { ++ addi(Rd, Rs, 0); ++ } ++ } ++ ++ inline void notr(Register Rd, Register Rs) { ++ xori(Rd, Rs, -1); ++ } ++ ++ inline void neg(Register Rd, Register Rs) { ++ sub(Rd, x0, Rs); ++ } ++ ++ inline void negw(Register Rd, Register Rs) { ++ subw(Rd, x0, Rs); ++ } ++ ++ inline void sext_w(Register Rd, Register Rs) { ++ addiw(Rd, Rs, 0); ++ } ++ ++ inline void zext_b(Register Rd, Register Rs) { ++ andi(Rd, Rs, 0xFF); ++ } ++ ++ inline void seqz(Register Rd, Register Rs) { ++ sltiu(Rd, Rs, 1); ++ } ++ ++ inline void snez(Register Rd, Register Rs) { ++ sltu(Rd, x0, Rs); ++ } ++ ++ inline void sltz(Register Rd, Register Rs) { ++ slt(Rd, Rs, x0); ++ } ++ ++ inline void sgtz(Register Rd, Register Rs) { ++ slt(Rd, x0, Rs); ++ } ++ ++ // Bit-manipulation extension pseudo instructions ++ // zero extend word ++ inline void zext_w(Register Rd, Register Rs) { ++ add_uw(Rd, Rs, zr); ++ } ++ ++ // Floating-point data-processing pseudo instructions ++ inline void fmv_s(FloatRegister Rd, FloatRegister Rs) { ++ if (Rd != Rs) { ++ fsgnj_s(Rd, Rs, Rs); ++ } ++ } ++ ++ inline void fabs_s(FloatRegister Rd, FloatRegister Rs) { ++ fsgnjx_s(Rd, Rs, Rs); ++ } ++ ++ inline void fneg_s(FloatRegister Rd, FloatRegister Rs) { ++ fsgnjn_s(Rd, Rs, Rs); ++ } ++ ++ inline void fmv_d(FloatRegister Rd, FloatRegister Rs) { ++ if (Rd != Rs) { ++ fsgnj_d(Rd, Rs, Rs); ++ } ++ } ++ ++ inline void fabs_d(FloatRegister Rd, FloatRegister Rs) { ++ fsgnjx_d(Rd, Rs, Rs); ++ } ++ ++ inline void fneg_d(FloatRegister Rd, FloatRegister Rs) { ++ fsgnjn_d(Rd, Rs, Rs); ++ } ++ ++ // Control and status pseudo instructions ++ void rdinstret(Register Rd); // read instruction-retired counter ++ void rdcycle(Register Rd); // read cycle counter ++ void rdtime(Register Rd); // read time ++ void csrr(Register Rd, unsigned csr); // read csr ++ void csrw(unsigned csr, Register Rs); // write csr ++ void csrs(unsigned csr, Register Rs); // set bits in csr ++ void csrc(unsigned csr, Register Rs); // clear bits in csr ++ void csrwi(unsigned csr, unsigned imm); ++ void csrsi(unsigned csr, unsigned imm); ++ void csrci(unsigned csr, unsigned imm); ++ void frcsr(Register Rd); // read float-point csr ++ void fscsr(Register Rd, Register Rs); // swap float-point csr ++ void fscsr(Register Rs); // write float-point csr ++ void frrm(Register Rd); // read float-point rounding mode ++ void fsrm(Register Rd, Register Rs); // swap float-point rounding mode ++ void fsrm(Register Rs); // write float-point rounding mode ++ void fsrmi(Register Rd, unsigned imm); ++ void fsrmi(unsigned imm); ++ void frflags(Register Rd); // read float-point exception flags ++ void fsflags(Register Rd, Register Rs); // swap float-point exception flags ++ void fsflags(Register Rs); // write float-point exception flags ++ void fsflagsi(Register Rd, unsigned imm); ++ void fsflagsi(unsigned imm); ++ ++ // Control transfer pseudo instructions ++ void beqz(Register Rs, const address dest); ++ void bnez(Register Rs, const address dest); ++ void blez(Register Rs, const address dest); ++ void bgez(Register Rs, const address dest); ++ void bltz(Register Rs, const address dest); ++ void bgtz(Register Rs, const address dest); ++ ++ void j(Label &l, Register temp = t0); ++ void j(const address dest, Register temp = t0); ++ void j(const Address &adr, Register temp = t0); ++ void jal(Label &l, Register temp = t0); ++ void jal(const address dest, Register temp = t0); ++ void jal(const Address &adr, Register temp = t0); ++ void jal(Register Rd, Label &L, Register temp = t0); ++ void jal(Register Rd, const address dest, Register temp = t0); ++ ++ //label ++ void beqz(Register Rs, Label &l, bool is_far = false); ++ void bnez(Register Rs, Label &l, bool is_far = false); ++ void blez(Register Rs, Label &l, bool is_far = false); ++ void bgez(Register Rs, Label &l, bool is_far = false); ++ void bltz(Register Rs, Label &l, bool is_far = false); ++ void bgtz(Register Rs, Label &l, bool is_far = false); ++ ++ void beq (Register Rs1, Register Rs2, Label &L, bool is_far = false); ++ void bne (Register Rs1, Register Rs2, Label &L, bool is_far = false); ++ void blt (Register Rs1, Register Rs2, Label &L, bool is_far = false); ++ void bge (Register Rs1, Register Rs2, Label &L, bool is_far = false); ++ void bltu(Register Rs1, Register Rs2, Label &L, bool is_far = false); ++ void bgeu(Register Rs1, Register Rs2, Label &L, bool is_far = false); ++ ++ void bgt (Register Rs, Register Rt, const address dest); ++ void ble (Register Rs, Register Rt, const address dest); ++ void bgtu(Register Rs, Register Rt, const address dest); ++ void bleu(Register Rs, Register Rt, const address dest); ++ ++ void bgt (Register Rs, Register Rt, Label &l, bool is_far = false); ++ void ble (Register Rs, Register Rt, Label &l, bool is_far = false); ++ void bgtu(Register Rs, Register Rt, Label &l, bool is_far = false); ++ void bleu(Register Rs, Register Rt, Label &l, bool is_far = false); ++ ++#define INSN_ENTRY_RELOC(result_type, header) \ ++ result_type header { \ ++ guarantee(rtype == relocInfo::internal_word_type, \ ++ "only internal_word_type relocs make sense here"); \ ++ relocate(InternalAddress(dest).rspec()); \ ++ IncompressibleRegion ir(this); /* relocations */ ++ ++#define INSN(NAME) \ ++ void NAME(Register Rs1, Register Rs2, const address dest) { \ ++ assert_cond(dest != NULL); \ ++ int64_t offset = dest - pc(); \ ++ guarantee(is_simm13(offset) && ((offset % 2) == 0), "offset is invalid."); \ ++ Assembler::NAME(Rs1, Rs2, offset); \ ++ } \ ++ INSN_ENTRY_RELOC(void, NAME(Register Rs1, Register Rs2, address dest, relocInfo::relocType rtype)) \ ++ NAME(Rs1, Rs2, dest); \ ++ } ++ ++ INSN(beq); ++ INSN(bne); ++ INSN(bge); ++ INSN(bgeu); ++ INSN(blt); ++ INSN(bltu); ++ ++#undef INSN ++ ++#undef INSN_ENTRY_RELOC ++ ++ void float_beq(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void float_bne(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void float_ble(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void float_bge(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void float_blt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void float_bgt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ ++ void double_beq(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void double_bne(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void double_ble(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void double_bge(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void double_blt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ void double_bgt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); ++ ++private: ++ int push_reg(unsigned int bitset, Register stack); ++ int pop_reg(unsigned int bitset, Register stack); ++ int push_fp(unsigned int bitset, Register stack); ++ int pop_fp(unsigned int bitset, Register stack); ++#ifdef COMPILER2 ++ int push_v(unsigned int bitset, Register stack); ++ int pop_v(unsigned int bitset, Register stack); ++#endif // COMPILER2 ++ ++public: ++ void push_reg(Register Rs); ++ void pop_reg(Register Rd); ++ void push_reg(RegSet regs, Register stack) { if (regs.bits()) push_reg(regs.bits(), stack); } ++ void pop_reg(RegSet regs, Register stack) { if (regs.bits()) pop_reg(regs.bits(), stack); } ++ void push_fp(FloatRegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); } ++ void pop_fp(FloatRegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); } ++#ifdef COMPILER2 ++ void push_v(VectorRegSet regs, Register stack) { if (regs.bits()) push_v(regs.bits(), stack); } ++ void pop_v(VectorRegSet regs, Register stack) { if (regs.bits()) pop_v(regs.bits(), stack); } ++#endif // COMPILER2 ++ ++ // Push and pop everything that might be clobbered by a native ++ // runtime call except t0 and t1. (They are always ++ // temporary registers, so we don't have to protect them.) ++ // Additional registers can be excluded in a passed RegSet. ++ void push_call_clobbered_registers_except(RegSet exclude); ++ void pop_call_clobbered_registers_except(RegSet exclude); ++ ++ void push_call_clobbered_registers() { ++ push_call_clobbered_registers_except(RegSet()); ++ } ++ void pop_call_clobbered_registers() { ++ pop_call_clobbered_registers_except(RegSet()); ++ } ++ ++ void push_CPU_state(bool save_vectors = false, int vector_size_in_bytes = 0); ++ void pop_CPU_state(bool restore_vectors = false, int vector_size_in_bytes = 0); ++ ++ // if heap base register is used - reinit it with the correct value ++ void reinit_heapbase(); ++ ++ void bind(Label& L) { ++ Assembler::bind(L); ++ // fences across basic blocks should not be merged ++ code()->clear_last_insn(); ++ } ++ ++ typedef void (MacroAssembler::* compare_and_branch_insn)(Register Rs1, Register Rs2, const address dest); ++ typedef void (MacroAssembler::* compare_and_branch_label_insn)(Register Rs1, Register Rs2, Label &L, bool is_far); ++ typedef void (MacroAssembler::* jal_jalr_insn)(Register Rt, address dest); ++ typedef void (MacroAssembler::* load_insn_by_temp)(Register Rt, address dest, Register temp); ++ ++ void wrap_label(Register r, Label &L, Register t, load_insn_by_temp insn); ++ void wrap_label(Register r, Label &L, jal_jalr_insn insn); ++ void wrap_label(Register r1, Register r2, Label &L, ++ compare_and_branch_insn insn, ++ compare_and_branch_label_insn neg_insn, bool is_far = false); ++ ++ void la(Register Rd, Label &label); ++ void la(Register Rd, const address dest); ++ void la(Register Rd, const Address &adr); ++ ++ void li32(Register Rd, int32_t imm); ++ void li64(Register Rd, int64_t imm); ++ void li (Register Rd, int64_t imm); // optimized load immediate ++ ++ // mv ++ void mv(Register Rd, address addr) { li(Rd, (int64_t)addr); } ++ void mv(Register Rd, address addr, int32_t &offset) { ++ // Split address into a lower 12-bit sign-extended offset and the remainder, ++ // so that the offset could be encoded in jalr or load/store instruction. ++ offset = ((int32_t)(int64_t)addr << 20) >> 20; ++ li(Rd, (int64_t)addr - offset); ++ } ++ ++ template::value)> ++ inline void mv(Register Rd, T o) { li(Rd, (int64_t)o); } ++ ++ void mv(Register Rd, Address dest) { ++ assert(dest.getMode() == Address::literal, "Address mode should be Address::literal"); ++ relocate(dest.rspec(), [&] { ++ movptr(Rd, dest.target()); ++ }); ++ } ++ ++ void mv(Register Rd, RegisterOrConstant src) { ++ if (src.is_register()) { ++ mv(Rd, src.as_register()); ++ } else { ++ mv(Rd, src.as_constant()); ++ } ++ } ++ ++ void movptr(Register Rd, address addr, int32_t &offset); ++ ++ void movptr(Register Rd, address addr) { ++ int offset = 0; ++ movptr(Rd, addr, offset); ++ addi(Rd, Rd, offset); ++ } ++ ++ inline void movptr(Register Rd, uintptr_t imm64) { ++ movptr(Rd, (address)imm64); ++ } ++ ++ // arith ++ void add (Register Rd, Register Rn, int64_t increment, Register temp = t0); ++ void addw(Register Rd, Register Rn, int32_t increment, Register temp = t0); ++ void sub (Register Rd, Register Rn, int64_t decrement, Register temp = t0); ++ void subw(Register Rd, Register Rn, int32_t decrement, Register temp = t0); ++ ++#define INSN(NAME) \ ++ inline void NAME(Register Rd, Register Rs1, Register Rs2) { \ ++ Assembler::NAME(Rd, Rs1, Rs2); \ ++ } ++ ++ INSN(add); ++ INSN(addw); ++ INSN(sub); ++ INSN(subw); ++ ++#undef INSN ++ ++ // logic ++ void andrw(Register Rd, Register Rs1, Register Rs2); ++ void orrw(Register Rd, Register Rs1, Register Rs2); ++ void xorrw(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 ++ void revb_h_h_u(Register Rd, Register Rs, Register tmp = t0); // reverse bytes in halfword in lower 16 bits, zero-extend ++ void revb_h_w_u(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); // reverse bytes in halfwords in lower 32 bits, zero-extend ++ void revb_h_helper(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2= t1); // reverse bytes in upper 16 bits (48:63) and move to lower ++ void revb_h(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2= t1); // reverse bytes in each halfword ++ void revb_w(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2= t1); // reverse bytes in each word ++ 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 andi(Register Rd, Register Rn, int64_t imm, Register tmp = t0); ++ void orptr(Address adr, RegisterOrConstant src, Register tmp1 = t0, Register tmp2 = t1); ++ ++// Load and Store Instructions ++#define INSN_ENTRY_RELOC(result_type, header) \ ++ result_type header { \ ++ guarantee(rtype == relocInfo::internal_word_type, \ ++ "only internal_word_type relocs make sense here"); \ ++ relocate(InternalAddress(dest).rspec()); \ ++ IncompressibleRegion ir(this); /* relocations */ ++ ++#define INSN(NAME) \ ++ void NAME(Register Rd, address dest) { \ ++ assert_cond(dest != NULL); \ ++ int64_t distance = dest - pc(); \ ++ if (is_simm32(distance)) { \ ++ auipc(Rd, (int32_t)distance + 0x800); \ ++ Assembler::NAME(Rd, Rd, ((int32_t)distance << 20) >> 20); \ ++ } else { \ ++ int32_t offset = 0; \ ++ movptr(Rd, dest, offset); \ ++ Assembler::NAME(Rd, Rd, offset); \ ++ } \ ++ } \ ++ INSN_ENTRY_RELOC(void, NAME(Register Rd, address dest, relocInfo::relocType rtype)) \ ++ NAME(Rd, dest); \ ++ } \ ++ void NAME(Register Rd, const Address &adr, Register temp = t0) { \ ++ switch (adr.getMode()) { \ ++ case Address::literal: { \ ++ relocate(adr.rspec()); \ ++ NAME(Rd, adr.target()); \ ++ break; \ ++ } \ ++ case Address::base_plus_offset: { \ ++ if (is_simm12(adr.offset())) { \ ++ Assembler::NAME(Rd, adr.base(), adr.offset()); \ ++ } else { \ ++ int32_t offset = ((int32_t)adr.offset() << 20) >> 20; \ ++ if (Rd == adr.base()) { \ ++ la(temp, Address(adr.base(), adr.offset() - offset)); \ ++ Assembler::NAME(Rd, temp, offset); \ ++ } else { \ ++ la(Rd, Address(adr.base(), adr.offset() - offset)); \ ++ Assembler::NAME(Rd, Rd, offset); \ ++ } \ ++ } \ ++ break; \ ++ } \ ++ default: \ ++ ShouldNotReachHere(); \ ++ } \ ++ } \ ++ void NAME(Register Rd, Label &L) { \ ++ wrap_label(Rd, L, &MacroAssembler::NAME); \ ++ } ++ ++ INSN(lb); ++ INSN(lbu); ++ INSN(lh); ++ INSN(lhu); ++ INSN(lw); ++ INSN(lwu); ++ INSN(ld); ++ ++#undef INSN ++ ++#define INSN(NAME) \ ++ void NAME(FloatRegister Rd, address dest, Register temp = t0) { \ ++ assert_cond(dest != NULL); \ ++ int64_t distance = dest - pc(); \ ++ if (is_simm32(distance)) { \ ++ auipc(temp, (int32_t)distance + 0x800); \ ++ Assembler::NAME(Rd, temp, ((int32_t)distance << 20) >> 20); \ ++ } else { \ ++ int32_t offset = 0; \ ++ movptr(temp, dest, offset); \ ++ Assembler::NAME(Rd, temp, offset); \ ++ } \ ++ } \ ++ INSN_ENTRY_RELOC(void, NAME(FloatRegister Rd, address dest, \ ++ relocInfo::relocType rtype, Register temp = t0)) \ ++ NAME(Rd, dest, temp); \ ++ } \ ++ void NAME(FloatRegister Rd, const Address &adr, Register temp = t0) { \ ++ switch (adr.getMode()) { \ ++ case Address::literal: { \ ++ relocate(adr.rspec()); \ ++ NAME(Rd, adr.target(), temp); \ ++ break; \ ++ } \ ++ case Address::base_plus_offset: { \ ++ if (is_simm12(adr.offset())) { \ ++ Assembler::NAME(Rd, adr.base(), adr.offset()); \ ++ } else { \ ++ int32_t offset = ((int32_t)adr.offset() << 20) >> 20; \ ++ la(temp, Address(adr.base(), adr.offset() - offset)); \ ++ Assembler::NAME(Rd, temp, offset); \ ++ } \ ++ break; \ ++ } \ ++ default: \ ++ ShouldNotReachHere(); \ ++ } \ ++ } ++ ++ INSN(flw); ++ INSN(fld); ++ ++#undef INSN ++ ++#define INSN(NAME, REGISTER) \ ++ INSN_ENTRY_RELOC(void, NAME(REGISTER Rs, address dest, \ ++ relocInfo::relocType rtype, Register temp = t0)) \ ++ NAME(Rs, dest, temp); \ ++ } ++ ++ INSN(sb, Register); ++ INSN(sh, Register); ++ INSN(sw, Register); ++ INSN(sd, Register); ++ INSN(fsw, FloatRegister); ++ INSN(fsd, FloatRegister); ++ ++#undef INSN ++ ++#define INSN(NAME) \ ++ void NAME(Register Rs, address dest, Register temp = t0) { \ ++ assert_cond(dest != NULL); \ ++ assert_different_registers(Rs, temp); \ ++ int64_t distance = dest - pc(); \ ++ if (is_simm32(distance)) { \ ++ auipc(temp, (int32_t)distance + 0x800); \ ++ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ ++ } else { \ ++ int32_t offset = 0; \ ++ movptr(temp, dest, offset); \ ++ Assembler::NAME(Rs, temp, offset); \ ++ } \ ++ } \ ++ void NAME(Register Rs, const Address &adr, Register temp = t0) { \ ++ switch (adr.getMode()) { \ ++ case Address::literal: { \ ++ assert_different_registers(Rs, temp); \ ++ relocate(adr.rspec()); \ ++ NAME(Rs, adr.target(), temp); \ ++ break; \ ++ } \ ++ case Address::base_plus_offset: { \ ++ if (is_simm12(adr.offset())) { \ ++ Assembler::NAME(Rs, adr.base(), adr.offset()); \ ++ } else { \ ++ assert_different_registers(Rs, temp); \ ++ int32_t offset = ((int32_t)adr.offset() << 20) >> 20; \ ++ la(temp, Address(adr.base(), adr.offset() - offset)); \ ++ Assembler::NAME(Rs, temp, offset); \ ++ } \ ++ break; \ ++ } \ ++ default: \ ++ ShouldNotReachHere(); \ ++ } \ ++ } ++ ++ INSN(sb); ++ INSN(sh); ++ INSN(sw); ++ INSN(sd); ++ ++#undef INSN ++ ++#define INSN(NAME) \ ++ void NAME(FloatRegister Rs, address dest, Register temp = t0) { \ ++ assert_cond(dest != NULL); \ ++ int64_t distance = dest - pc(); \ ++ if (is_simm32(distance)) { \ ++ auipc(temp, (int32_t)distance + 0x800); \ ++ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ ++ } else { \ ++ int32_t offset = 0; \ ++ movptr(temp, dest, offset); \ ++ Assembler::NAME(Rs, temp, offset); \ ++ } \ ++ } \ ++ void NAME(FloatRegister Rs, const Address &adr, Register temp = t0) { \ ++ switch (adr.getMode()) { \ ++ case Address::literal: { \ ++ relocate(adr.rspec()); \ ++ NAME(Rs, adr.target(), temp); \ ++ break; \ ++ } \ ++ case Address::base_plus_offset: { \ ++ if (is_simm12(adr.offset())) { \ ++ Assembler::NAME(Rs, adr.base(), adr.offset()); \ ++ } else { \ ++ int32_t offset = ((int32_t)adr.offset() << 20) >> 20; \ ++ la(temp, Address(adr.base(), adr.offset() - offset)); \ ++ Assembler::NAME(Rs, temp, offset); \ ++ } \ ++ break; \ ++ } \ ++ default: \ ++ ShouldNotReachHere(); \ ++ } \ ++ } ++ ++ INSN(fsw); ++ INSN(fsd); ++ ++#undef INSN ++ ++#undef INSN_ENTRY_RELOC ++ ++ void cmpxchg_obj_header(Register oldv, Register newv, Register obj, Register tmp, Label &succeed, Label *fail); ++ void cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp, Label &succeed, Label *fail); ++ void cmpxchg(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result, bool result_as_bool = false); ++ void cmpxchg_weak(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result); ++ void cmpxchg_narrow_value_helper(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Register tmp1, Register tmp2, Register tmp3); ++ void cmpxchg_narrow_value(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result, bool result_as_bool, ++ Register tmp1, Register tmp2, Register tmp3); ++ void weak_cmpxchg_narrow_value(Register addr, Register expected, ++ Register new_val, ++ enum operand_size size, ++ Assembler::Aqrl acquire, Assembler::Aqrl release, ++ Register result, ++ Register tmp1, Register tmp2, Register tmp3); ++ ++ void atomic_add(Register prev, RegisterOrConstant incr, Register addr); ++ void atomic_addw(Register prev, RegisterOrConstant incr, Register addr); ++ void atomic_addal(Register prev, RegisterOrConstant incr, Register addr); ++ void atomic_addalw(Register prev, RegisterOrConstant incr, Register addr); ++ ++ void atomic_xchg(Register prev, Register newv, Register addr); ++ void atomic_xchgw(Register prev, Register newv, Register addr); ++ void atomic_xchgal(Register prev, Register newv, Register addr); ++ void atomic_xchgalw(Register prev, Register newv, Register addr); ++ void atomic_xchgwu(Register prev, Register newv, Register addr); ++ void atomic_xchgalwu(Register prev, Register newv, Register addr); ++ ++ void atomic_incw(Register counter_addr, Register tmp); ++ void atomic_incw(Address counter_addr, Register tmp1, Register tmp2) { ++ la(tmp1, counter_addr); ++ atomic_incw(tmp1, tmp2); ++ } ++ ++ // Biased locking support ++ // lock_reg and obj_reg must be loaded up with the appropriate values. ++ // swap_reg is killed. ++ // tmp_reg must be supplied and must not be t0 or t1 ++ // Optional slow case is for implementations (interpreter and C1) which branch to ++ // slow case directly. Leaves condition codes set for C2's Fast_Lock done. ++ // Returns offset of first potentially-faulting instruction for null ++ // check info (currently consumed only by C1). If ++ // swap_reg_contains_mark is true then returns -1 as it as assumed ++ // the calling code has already passed any potential faults. ++ void biased_locking_enter(Register lock_reg, Register obj_reg, ++ Register swap_reg, Register tmp_Reg, ++ bool swap_reg_contains_mark, ++ Label& done, Label* slow_case = NULL, ++ BiasedLockingCounters* counters = NULL, ++ Register flag = noreg); ++ void biased_locking_exit(Register obj_reg, Register tmp_reg, Label& done, Register flag = noreg); ++ ++ static bool far_branches() { ++ return ReservedCodeCacheSize > branch_range; ++ } ++ ++ // Jumps that can reach anywhere in the code cache. ++ // Trashes tmp. ++ void far_call(Address entry, CodeBuffer *cbuf = NULL, Register tmp = t0); ++ void far_jump(Address entry, CodeBuffer *cbuf = NULL, Register tmp = t0); ++ ++ static int far_branch_size() { ++ if (far_branches()) { ++ return 2 * 4; // auipc + jalr, see far_call() & far_jump() ++ } else { ++ return 4; ++ } ++ } ++ ++ void load_byte_map_base(Register reg); ++ ++ void bang_stack_with_offset(int offset) { ++ // stack grows down, caller passes positive offset ++ assert(offset > 0, "must bang with negative offset"); ++ sub(t0, sp, offset); ++ sd(zr, Address(t0)); ++ } ++ ++ void la_patchable(Register reg1, const Address &dest, int32_t &offset); ++ ++ virtual void _call_Unimplemented(address call_site) { ++ mv(t1, call_site); ++ } ++ ++ #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__) ++ ++ // Frame creation and destruction shared between JITs. ++ void build_frame(int framesize); ++ void remove_frame(int framesize); ++ ++ void reserved_stack_check(); ++ ++ void get_polling_page(Register dest, relocInfo::relocType rtype); ++ void read_polling_page(Register r, int32_t offset, relocInfo::relocType rtype); ++ ++ address trampoline_call(Address entry, CodeBuffer* cbuf = NULL); ++ address ic_call(address entry, jint method_index = 0); ++ ++ // Support for memory inc/dec ++ // n.b. increment/decrement calls with an Address destination will ++ // need to use a scratch register to load the value to be ++ // incremented. increment/decrement calls which add or subtract a ++ // constant value other than sign-extended 12-bit immediate will need ++ // to use a 2nd scratch register to hold the constant. so, an address ++ // increment/decrement may trash both t0 and t1. ++ ++ void increment(const Address dst, int64_t value = 1, Register tmp1 = t0, Register tmp2 = t1); ++ void incrementw(const Address dst, int32_t value = 1, Register tmp1 = t0, Register tmp2 = t1); ++ ++ void decrement(const Address dst, int64_t value = 1, Register tmp1 = t0, Register tmp2 = t1); ++ void decrementw(const Address dst, int32_t value = 1, Register tmp1 = t0, Register tmp2 = t1); ++ ++ void cmpptr(Register src1, Address src2, Label& equal); ++ ++ void clinit_barrier(Register klass, Register tmp, Label* L_fast_path = NULL, Label* L_slow_path = NULL); ++ void load_method_holder_cld(Register result, Register method); ++ void load_method_holder(Register holder, Register method); ++ ++ void compute_index(Register str1, Register trailing_zeros, Register match_mask, ++ Register result, Register char_tmp, Register tmp, ++ bool haystack_isL); ++ void compute_match_mask(Register src, Register pattern, Register match_mask, ++ Register mask1, Register mask2); ++ ++#ifdef COMPILER2 ++ void mul_add(Register out, Register in, Register offset, ++ Register len, Register k, Register tmp); ++ void cad(Register dst, Register src1, Register src2, Register carry); ++ void cadc(Register dst, Register src1, Register src2, Register carry); ++ void adc(Register dst, Register src1, Register src2, Register carry); ++ void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo, ++ Register src1, Register src2, Register carry); ++ void multiply_32_x_32_loop(Register x, Register xstart, Register x_xstart, ++ Register y, Register y_idx, Register z, ++ Register carry, Register product, ++ Register idx, Register kdx); ++ void multiply_64_x_64_loop(Register x, Register xstart, Register x_xstart, ++ Register y, Register y_idx, Register z, ++ Register carry, Register product, ++ Register idx, Register kdx); ++ void multiply_128_x_128_loop(Register y, Register z, ++ Register carry, Register carry2, ++ Register idx, Register jdx, ++ Register yz_idx1, Register yz_idx2, ++ Register tmp, Register tmp3, Register tmp4, ++ Register tmp6, Register product_hi); ++ void multiply_to_len(Register x, Register xlen, Register y, Register ylen, ++ Register z, Register zlen, ++ Register tmp1, Register tmp2, Register tmp3, Register tmp4, ++ Register tmp5, Register tmp6, Register product_hi); ++#endif ++ ++ void inflate_lo32(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); ++ void inflate_hi32(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); ++ ++ void ctzc_bit(Register Rd, Register Rs, bool isLL = false, Register tmp1 = t0, Register tmp2 = t1); ++ ++ void zero_words(Register base, u_int64_t cnt); ++ address zero_words(Register ptr, Register cnt); ++ void fill_words(Register base, Register cnt, Register value); ++ void zero_memory(Register addr, Register len, Register tmp); ++ ++ // shift left by shamt and add ++ 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); ++ ++ // Here the float instructions with safe deal with some exceptions. ++ // e.g. convert from NaN, +Inf, -Inf to int, float, double ++ // will trigger exception, we need to deal with these situations ++ // to get correct results. ++ void fcvt_w_s_safe(Register dst, FloatRegister src, Register tmp = t0); ++ void fcvt_l_s_safe(Register dst, FloatRegister src, Register tmp = t0); ++ void fcvt_w_d_safe(Register dst, FloatRegister src, Register tmp = t0); ++ void fcvt_l_d_safe(Register dst, FloatRegister src, Register tmp = t0); ++ ++ // vector load/store unit-stride instructions ++ void vlex_v(VectorRegister vd, Register base, Assembler::SEW sew, VectorMask vm = unmasked) { ++ switch (sew) { ++ case Assembler::e64: ++ vle64_v(vd, base, vm); ++ break; ++ case Assembler::e32: ++ vle32_v(vd, base, vm); ++ break; ++ case Assembler::e16: ++ vle16_v(vd, base, vm); ++ break; ++ case Assembler::e8: // fall through ++ default: ++ vle8_v(vd, base, vm); ++ break; ++ } ++ } ++ ++ void vsex_v(VectorRegister store_data, Register base, Assembler::SEW sew, VectorMask vm = unmasked) { ++ switch (sew) { ++ case Assembler::e64: ++ vse64_v(store_data, base, vm); ++ break; ++ case Assembler::e32: ++ vse32_v(store_data, base, vm); ++ break; ++ case Assembler::e16: ++ vse16_v(store_data, base, vm); ++ break; ++ case Assembler::e8: // fall through ++ default: ++ vse8_v(store_data, base, vm); ++ break; ++ } ++ } ++ ++ // vector pseudo instructions ++ inline void vmnot_m(VectorRegister vd, VectorRegister vs) { ++ vmnand_mm(vd, vs, vs); ++ } ++ ++ inline void vncvt_x_x_w(VectorRegister vd, VectorRegister vs, VectorMask vm) { ++ vnsrl_wx(vd, vs, x0, vm); ++ } ++ ++ inline void vfneg_v(VectorRegister vd, VectorRegister vs) { ++ vfsgnjn_vv(vd, vs, vs); ++ } ++ ++ static const int zero_words_block_size; ++ ++ void cast_primitive_type(BasicType type, Register Rt) { ++ switch (type) { ++ case T_BOOLEAN: ++ sltu(Rt, zr, Rt); ++ break; ++ case T_CHAR : ++ zero_extend(Rt, Rt, 16); ++ break; ++ case T_BYTE : ++ sign_extend(Rt, Rt, 8); ++ break; ++ case T_SHORT : ++ sign_extend(Rt, Rt, 16); ++ break; ++ case T_INT : ++ sign_extend(Rt, Rt, 32); ++ break; ++ case T_LONG : /* nothing to do */ break; ++ case T_VOID : /* nothing to do */ break; ++ case T_FLOAT : /* nothing to do */ break; ++ case T_DOUBLE : /* nothing to do */ break; ++ default: ShouldNotReachHere(); ++ } ++ } ++ ++ // float cmp with unordered_result ++ void float_compare(Register result, FloatRegister Rs1, FloatRegister Rs2, int unordered_result); ++ void double_compare(Register result, FloatRegister Rs1, FloatRegister Rs2, int unordered_result); ++ ++ // Zero/Sign-extend ++ void zero_extend(Register dst, Register src, int bits); ++ void sign_extend(Register dst, Register src, int bits); ++ ++ // compare src1 and src2 and get -1/0/1 in dst. ++ // if [src1 > src2], dst = 1; ++ // if [src1 == src2], dst = 0; ++ // if [src1 < src2], dst = -1; ++ void cmp_l2i(Register dst, Register src1, Register src2, Register tmp = t0); ++ ++ void call(const address dest, Register temp = t0) { ++ assert_cond(dest != NULL); ++ assert(temp != noreg, "expecting a register"); ++ int32_t offset = 0; ++ mv(temp, dest, offset); ++ jalr(x1, temp, offset); ++ } ++ ++ inline void ret() { ++ jalr(x0, x1, 0); ++ } ++ ++private: ++ ++#ifdef ASSERT ++ // Template short-hand support to clean-up after a failed call to trampoline ++ // call generation (see trampoline_call() below), when a set of Labels must ++ // be reset (before returning). ++ template ++ void reset_labels(Label& lbl, More&... more) { ++ lbl.reset(); reset_labels(more...); ++ } ++ template ++ void reset_labels(Label& lbl) { ++ lbl.reset(); ++ } ++#endif ++ void repne_scan(Register addr, Register value, Register count, Register tmp); ++ ++ void ld_constant(Register dest, const Address &const_addr) { ++ if (NearCpool) { ++ ld(dest, const_addr); ++ } else { ++ InternalAddress target(const_addr.target()); ++ relocate(target.rspec(), [&] { ++ int32_t offset; ++ la_patchable(dest, target, offset); ++ ld(dest, Address(dest, offset)); ++ }); ++ } ++ } ++ ++ int bitset_to_regs(unsigned int bitset, unsigned char* regs); ++ Address add_memory_helper(const Address dst, Register tmp); ++ ++ void load_reserved(Register addr, enum operand_size size, Assembler::Aqrl acquire); ++ void store_conditional(Register addr, Register new_val, enum operand_size size, Assembler::Aqrl release); ++ ++ void load_prototype_header(Register dst, Register src); ++}; ++ ++#ifdef ASSERT ++inline bool AbstractAssembler::pd_check_instruction_mark() { return false; } ++#endif ++ ++/** ++ * class SkipIfEqual: ++ * ++ * Instantiating this class will result in assembly code being output that will ++ * jump around any code emitted between the creation of the instance and it's ++ * automatic destruction at the end of a scope block, depending on the value of ++ * the flag passed to the constructor, which will be checked at run-time. ++ */ ++class SkipIfEqual { ++ private: ++ MacroAssembler* _masm; ++ Label _label; ++ ++ public: ++ SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value); ++ ~SkipIfEqual(); ++}; ++ ++#endif // CPU_RISCV_MACROASSEMBLER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.inline.hpp +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_MACROASSEMBLER_RISCV_INLINE_HPP ++#define CPU_RISCV_MACROASSEMBLER_RISCV_INLINE_HPP ++ ++// Still empty. ++ ++#endif // CPU_RISCV_MACROASSEMBLER_RISCV_INLINE_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/matcher_riscv.hpp +@@ -0,0 +1,169 @@ ++/* ++ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2021, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_MATCHER_RISCV_HPP ++#define CPU_RISCV_MATCHER_RISCV_HPP ++ ++ // Defined within class Matcher ++ ++ // false => size gets scaled to BytesPerLong, ok. ++ static const bool init_array_count_is_in_bytes = false; ++ ++ // Whether this platform implements the scalable vector feature ++ static const bool implements_scalable_vector = true; ++ ++ static const bool supports_scalable_vector() { ++ return UseRVV; ++ } ++ ++ // riscv supports misaligned vectors store/load. ++ static constexpr bool misaligned_vectors_ok() { ++ return true; ++ } ++ ++ // Whether code generation need accurate ConvI2L types. ++ static const bool convi2l_type_required = false; ++ ++ // Does the CPU require late expand (see block.cpp for description of late expand)? ++ static const bool require_postalloc_expand = false; ++ ++ // Do we need to mask the count passed to shift instructions or does ++ // the cpu only look at the lower 5/6 bits anyway? ++ static const bool need_masked_shift_count = false; ++ ++ // No support for generic vector operands. ++ static const bool supports_generic_vector_operands = false; ++ ++ static constexpr bool isSimpleConstant64(jlong value) { ++ // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. ++ // Probably always true, even if a temp register is required. ++ return true; ++ } ++ ++ // Use conditional move (CMOVL) ++ static constexpr int long_cmove_cost() { ++ // long cmoves are no more expensive than int cmoves ++ return 0; ++ } ++ ++ static constexpr int float_cmove_cost() { ++ // float cmoves are no more expensive than int cmoves ++ return 0; ++ } ++ ++ // This affects two different things: ++ // - how Decode nodes are matched ++ // - how ImplicitNullCheck opportunities are recognized ++ // If true, the matcher will try to remove all Decodes and match them ++ // (as operands) into nodes. NullChecks are not prepared to deal with ++ // Decodes by final_graph_reshaping(). ++ // If false, final_graph_reshaping() forces the decode behind the Cmp ++ // for a NullCheck. The matcher matches the Decode node into a register. ++ // Implicit_null_check optimization moves the Decode along with the ++ // memory operation back up before the NullCheck. ++ static bool narrow_oop_use_complex_address() { ++ return CompressedOops::shift() == 0; ++ } ++ ++ static bool narrow_klass_use_complex_address() { ++ return false; ++ } ++ ++ static bool const_oop_prefer_decode() { ++ // Prefer ConN+DecodeN over ConP in simple compressed oops mode. ++ return CompressedOops::base() == NULL; ++ } ++ ++ static bool const_klass_prefer_decode() { ++ // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. ++ return CompressedKlassPointers::base() == NULL; ++ } ++ ++ // Is it better to copy float constants, or load them directly from ++ // memory? Intel can load a float constant from a direct address, ++ // requiring no extra registers. Most RISCs will have to materialize ++ // an address into a register first, so they would do better to copy ++ // the constant from stack. ++ static const bool rematerialize_float_constants = false; ++ ++ // If CPU can load and store mis-aligned doubles directly then no ++ // fixup is needed. Else we split the double into 2 integer pieces ++ // and move it piece-by-piece. Only happens when passing doubles into ++ // C code as the Java calling convention forces doubles to be aligned. ++ static const bool misaligned_doubles_ok = true; ++ ++ // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. ++ static const bool strict_fp_requires_explicit_rounding = false; ++ ++ // Are floats converted to double when stored to stack during ++ // deoptimization? ++ static constexpr bool float_in_double() { return false; } ++ ++ // Do ints take an entire long register or just half? ++ // The relevant question is how the int is callee-saved: ++ // the whole long is written but de-opt'ing will have to extract ++ // the relevant 32 bits. ++ static const bool int_in_long = true; ++ ++ // Does the CPU supports vector variable shift instructions? ++ static constexpr bool supports_vector_variable_shifts(void) { ++ return false; ++ } ++ ++ // Does the CPU supports vector variable rotate instructions? ++ static constexpr bool supports_vector_variable_rotates(void) { ++ return false; ++ } ++ ++ // Does the CPU supports vector constant rotate instructions? ++ static constexpr bool supports_vector_constant_rotates(int shift) { ++ return false; ++ } ++ ++ // Does the CPU supports vector unsigned comparison instructions? ++ static const bool supports_vector_comparison_unsigned(int vlen, BasicType bt) { ++ return false; ++ } ++ ++ // Some microarchitectures have mask registers used on vectors ++ static const bool has_predicated_vectors(void) { ++ return false; ++ } ++ ++ // true means we have fast l2f convers ++ // false means that conversion is done by runtime call ++ static constexpr bool convL2FSupported(void) { ++ return true; ++ } ++ ++ // Implements a variant of EncodeISOArrayNode that encode ASCII only ++ static const bool supports_encode_ascii_array = false; ++ ++ // Returns pre-selection estimated size of a vector operation. ++ static int vector_op_pre_select_sz_estimate(int vopc, BasicType ety, int vlen) { ++ return 0; ++ } ++ ++#endif // CPU_RISCV_MATCHER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/methodHandles_riscv.cpp +@@ -0,0 +1,455 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "classfile/javaClasses.inline.hpp" ++#include "classfile/vmClasses.hpp" ++#include "interpreter/interpreter.hpp" ++#include "interpreter/interpreterRuntime.hpp" ++#include "memory/allocation.inline.hpp" ++#include "prims/jvmtiExport.hpp" ++#include "prims/methodHandles.hpp" ++#include "runtime/flags/flagSetting.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/stubRoutines.hpp" ++ ++#define __ _masm-> ++ ++#ifdef PRODUCT ++#define BLOCK_COMMENT(str) /* nothing */ ++#else ++#define BLOCK_COMMENT(str) __ block_comment(str) ++#endif ++ ++#define BIND(label) bind(label); BLOCK_COMMENT(#label ":") ++ ++void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg) { ++ if (VerifyMethodHandles) { ++ verify_klass(_masm, klass_reg, VM_CLASS_ID(java_lang_Class), ++ "MH argument is a Class"); ++ } ++ __ ld(klass_reg, Address(klass_reg, java_lang_Class::klass_offset())); ++} ++ ++#ifdef ASSERT ++static int check_nonzero(const char* xname, int x) { ++ assert(x != 0, "%s should be nonzero", xname); ++ return x; ++} ++#define NONZERO(x) check_nonzero(#x, x) ++#else //ASSERT ++#define NONZERO(x) (x) ++#endif //PRODUCT ++ ++#ifdef ASSERT ++void MethodHandles::verify_klass(MacroAssembler* _masm, ++ Register obj, vmClassID klass_id, ++ const char* error_message) { ++ InstanceKlass** klass_addr = vmClasses::klass_addr_at(klass_id); ++ Klass* klass = vmClasses::klass_at(klass_id); ++ Register temp1 = t1; ++ Register temp2 = t0; // used by MacroAssembler::cmpptr ++ Label L_ok, L_bad; ++ BLOCK_COMMENT("verify_klass {"); ++ __ verify_oop(obj); ++ __ beqz(obj, L_bad); ++ __ push_reg(RegSet::of(temp1, temp2), sp); ++ __ load_klass(temp1, obj, temp2); ++ __ cmpptr(temp1, ExternalAddress((address) klass_addr), L_ok); ++ intptr_t super_check_offset = klass->super_check_offset(); ++ __ ld(temp1, Address(temp1, super_check_offset)); ++ __ cmpptr(temp1, ExternalAddress((address) klass_addr), L_ok); ++ __ pop_reg(RegSet::of(temp1, temp2), sp); ++ __ bind(L_bad); ++ __ stop(error_message); ++ __ BIND(L_ok); ++ __ pop_reg(RegSet::of(temp1, temp2), sp); ++ BLOCK_COMMENT("} verify_klass"); ++} ++ ++void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {} ++ ++#endif //ASSERT ++ ++void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp, ++ bool for_compiler_entry) { ++ assert(method == xmethod, "interpreter calling convention"); ++ Label L_no_such_method; ++ __ beqz(xmethod, L_no_such_method); ++ __ verify_method_ptr(method); ++ ++ if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { ++ Label run_compiled_code; ++ // JVMTI events, such as single-stepping, are implemented partly by avoiding running ++ // compiled code in threads for which the event is enabled. Check here for ++ // interp_only_mode if these events CAN be enabled. ++ ++ __ lwu(t0, Address(xthread, JavaThread::interp_only_mode_offset())); ++ __ beqz(t0, run_compiled_code); ++ __ ld(t0, Address(method, Method::interpreter_entry_offset())); ++ __ jr(t0); ++ __ BIND(run_compiled_code); ++ } ++ ++ const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : ++ Method::from_interpreted_offset(); ++ __ ld(t0,Address(method, entry_offset)); ++ __ jr(t0); ++ __ bind(L_no_such_method); ++ __ far_jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry())); ++} ++ ++void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, ++ Register recv, Register method_temp, ++ Register temp2, ++ bool for_compiler_entry) { ++ BLOCK_COMMENT("jump_to_lambda_form {"); ++ // This is the initial entry point of a lazy method handle. ++ // After type checking, it picks up the invoker from the LambdaForm. ++ assert_different_registers(recv, method_temp, temp2); ++ assert(recv != noreg, "required register"); ++ assert(method_temp == xmethod, "required register for loading method"); ++ ++ // Load the invoker, as MH -> MH.form -> LF.vmentry ++ __ verify_oop(recv); ++ __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())), temp2); ++ __ verify_oop(method_temp); ++ __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset())), temp2); ++ __ verify_oop(method_temp); ++ __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset())), temp2); ++ __ verify_oop(method_temp); ++ __ access_load_at(T_ADDRESS, IN_HEAP, method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())), noreg, noreg); ++ ++ if (VerifyMethodHandles && !for_compiler_entry) { ++ // make sure recv is already on stack ++ __ ld(temp2, Address(method_temp, Method::const_offset())); ++ __ load_sized_value(temp2, ++ Address(temp2, ConstMethod::size_of_parameters_offset()), ++ sizeof(u2), /*is_signed*/ false); ++ Label L; ++ __ ld(t0, __ argument_address(temp2, -1)); ++ __ beq(recv, t0, L); ++ __ ld(x10, __ argument_address(temp2, -1)); ++ __ ebreak(); ++ __ BIND(L); ++ } ++ ++ jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry); ++ BLOCK_COMMENT("} jump_to_lambda_form"); ++} ++ ++// Code generation ++address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm, ++ vmIntrinsics::ID iid) { ++ const bool not_for_compiler_entry = false; // this is the interpreter entry ++ assert(is_signature_polymorphic(iid), "expected invoke iid"); ++ if (iid == vmIntrinsics::_invokeGeneric || ++ iid == vmIntrinsics::_compiledLambdaForm) { ++ // Perhaps surprisingly, the symbolic references visible to Java are not directly used. ++ // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod. ++ // They all allow an appendix argument. ++ __ ebreak(); // empty stubs make SG sick ++ return NULL; ++ } ++ ++ // No need in interpreter entry for linkToNative for now. ++ // Interpreter calls compiled entry through i2c. ++ if (iid == vmIntrinsics::_linkToNative) { ++ __ ebreak(); ++ return NULL; ++ } ++ ++ // x30: sender SP (must preserve; see prepare_to_jump_from_interpreted) ++ // xmethod: Method* ++ // x13: argument locator (parameter slot count, added to sp) ++ // x11: used as temp to hold mh or receiver ++ // x10, x29: garbage temps, blown away ++ Register argp = x13; // argument list ptr, live on error paths ++ Register mh = x11; // MH receiver; dies quickly and is recycled ++ ++ // here's where control starts out: ++ __ align(CodeEntryAlignment); ++ address entry_point = __ pc(); ++ ++ if (VerifyMethodHandles) { ++ assert(Method::intrinsic_id_size_in_bytes() == 2, "assuming Method::_intrinsic_id is u2"); ++ ++ Label L; ++ BLOCK_COMMENT("verify_intrinsic_id {"); ++ __ lhu(t0, Address(xmethod, Method::intrinsic_id_offset_in_bytes())); ++ __ mv(t1, (int) iid); ++ __ beq(t0, t1, L); ++ if (iid == vmIntrinsics::_linkToVirtual || ++ iid == vmIntrinsics::_linkToSpecial) { ++ // could do this for all kinds, but would explode assembly code size ++ trace_method_handle(_masm, "bad Method*::intrinsic_id"); ++ } ++ __ ebreak(); ++ __ bind(L); ++ BLOCK_COMMENT("} verify_intrinsic_id"); ++ } ++ ++ // First task: Find out how big the argument list is. ++ Address x13_first_arg_addr; ++ int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid); ++ assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic"); ++ if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) { ++ __ ld(argp, Address(xmethod, Method::const_offset())); ++ __ load_sized_value(argp, ++ Address(argp, ConstMethod::size_of_parameters_offset()), ++ sizeof(u2), /*is_signed*/ false); ++ x13_first_arg_addr = __ argument_address(argp, -1); ++ } else { ++ DEBUG_ONLY(argp = noreg); ++ } ++ ++ if (!is_signature_polymorphic_static(iid)) { ++ __ ld(mh, x13_first_arg_addr); ++ DEBUG_ONLY(argp = noreg); ++ } ++ ++ // x13_first_arg_addr is live! ++ ++ trace_method_handle_interpreter_entry(_masm, iid); ++ if (iid == vmIntrinsics::_invokeBasic) { ++ generate_method_handle_dispatch(_masm, iid, mh, noreg, not_for_compiler_entry); ++ } else { ++ // Adjust argument list by popping the trailing MemberName argument. ++ Register recv = noreg; ++ if (MethodHandles::ref_kind_has_receiver(ref_kind)) { ++ // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack. ++ __ ld(recv = x12, x13_first_arg_addr); ++ } ++ DEBUG_ONLY(argp = noreg); ++ Register xmember = xmethod; // MemberName ptr; incoming method ptr is dead now ++ __ pop_reg(xmember); // extract last argument ++ generate_method_handle_dispatch(_masm, iid, recv, xmember, not_for_compiler_entry); ++ } ++ ++ return entry_point; ++} ++ ++ ++void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, ++ vmIntrinsics::ID iid, ++ Register receiver_reg, ++ Register member_reg, ++ bool for_compiler_entry) { ++ assert(is_signature_polymorphic(iid), "expected invoke iid"); ++ // temps used in this code are not used in *either* compiled or interpreted calling sequences ++ Register temp1 = x7; ++ Register temp2 = x28; ++ Register temp3 = x29; // x30 is live by this point: it contains the sender SP ++ if (for_compiler_entry) { ++ assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : j_rarg0), "only valid assignment"); ++ assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7); ++ assert_different_registers(temp2, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7); ++ assert_different_registers(temp3, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7); ++ } ++ ++ assert_different_registers(temp1, temp2, temp3, receiver_reg); ++ assert_different_registers(temp1, temp2, temp3, member_reg); ++ ++ if (iid == vmIntrinsics::_invokeBasic || iid == vmIntrinsics::_linkToNative) { ++ if (iid == vmIntrinsics::_linkToNative) { ++ assert(for_compiler_entry, "only compiler entry is supported"); ++ } ++ // indirect through MH.form.vmentry.vmtarget ++ jump_to_lambda_form(_masm, receiver_reg, xmethod, temp1, for_compiler_entry); ++ } else { ++ // The method is a member invoker used by direct method handles. ++ if (VerifyMethodHandles) { ++ // make sure the trailing argument really is a MemberName (caller responsibility) ++ verify_klass(_masm, member_reg, VM_CLASS_ID(java_lang_invoke_MemberName), ++ "MemberName required for invokeVirtual etc."); ++ } ++ ++ Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset())); ++ Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset())); ++ Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset())); ++ Address vmtarget_method( xmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())); ++ ++ Register temp1_recv_klass = temp1; ++ if (iid != vmIntrinsics::_linkToStatic) { ++ __ verify_oop(receiver_reg); ++ if (iid == vmIntrinsics::_linkToSpecial) { ++ // Don't actually load the klass; just null-check the receiver. ++ __ null_check(receiver_reg); ++ } else { ++ // load receiver klass itself ++ __ null_check(receiver_reg, oopDesc::klass_offset_in_bytes()); ++ __ load_klass(temp1_recv_klass, receiver_reg); ++ __ verify_klass_ptr(temp1_recv_klass); ++ } ++ BLOCK_COMMENT("check_receiver {"); ++ // The receiver for the MemberName must be in receiver_reg. ++ // Check the receiver against the MemberName.clazz ++ if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) { ++ // Did not load it above... ++ __ load_klass(temp1_recv_klass, receiver_reg); ++ __ verify_klass_ptr(temp1_recv_klass); ++ } ++ if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) { ++ Label L_ok; ++ Register temp2_defc = temp2; ++ __ load_heap_oop(temp2_defc, member_clazz, temp3); ++ load_klass_from_Class(_masm, temp2_defc); ++ __ verify_klass_ptr(temp2_defc); ++ __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok); ++ // If we get here, the type check failed! ++ __ ebreak(); ++ __ bind(L_ok); ++ } ++ BLOCK_COMMENT("} check_receiver"); ++ } ++ if (iid == vmIntrinsics::_linkToSpecial || ++ iid == vmIntrinsics::_linkToStatic) { ++ DEBUG_ONLY(temp1_recv_klass = noreg); // these guys didn't load the recv_klass ++ } ++ ++ // Live registers at this point: ++ // member_reg - MemberName that was the trailing argument ++ // temp1_recv_klass - klass of stacked receiver, if needed ++ // x30 - interpreter linkage (if interpreted) ++ // x11 ... x10 - compiler arguments (if compiled) ++ ++ Label L_incompatible_class_change_error; ++ switch (iid) { ++ case vmIntrinsics::_linkToSpecial: ++ if (VerifyMethodHandles) { ++ verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); ++ } ++ __ load_heap_oop(xmethod, member_vmtarget); ++ __ access_load_at(T_ADDRESS, IN_HEAP, xmethod, vmtarget_method, noreg, noreg); ++ break; ++ ++ case vmIntrinsics::_linkToStatic: ++ if (VerifyMethodHandles) { ++ verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); ++ } ++ __ load_heap_oop(xmethod, member_vmtarget); ++ __ access_load_at(T_ADDRESS, IN_HEAP, xmethod, vmtarget_method, noreg, noreg); ++ break; ++ ++ case vmIntrinsics::_linkToVirtual: ++ { ++ // same as TemplateTable::invokevirtual, ++ // minus the CP setup and profiling: ++ ++ if (VerifyMethodHandles) { ++ verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3); ++ } ++ ++ // pick out the vtable index from the MemberName, and then we can discard it: ++ Register temp2_index = temp2; ++ __ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg); ++ ++ if (VerifyMethodHandles) { ++ Label L_index_ok; ++ __ bgez(temp2_index, L_index_ok); ++ __ ebreak(); ++ __ BIND(L_index_ok); ++ } ++ ++ // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget ++ // at this point. And VerifyMethodHandles has already checked clazz, if needed. ++ ++ // get target Method* & entry point ++ __ lookup_virtual_method(temp1_recv_klass, temp2_index, xmethod); ++ break; ++ } ++ ++ case vmIntrinsics::_linkToInterface: ++ { ++ // same as TemplateTable::invokeinterface ++ // (minus the CP setup and profiling, with different argument motion) ++ if (VerifyMethodHandles) { ++ verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3); ++ } ++ ++ Register temp3_intf = temp3; ++ __ load_heap_oop(temp3_intf, member_clazz); ++ load_klass_from_Class(_masm, temp3_intf); ++ __ verify_klass_ptr(temp3_intf); ++ ++ Register rindex = xmethod; ++ __ access_load_at(T_ADDRESS, IN_HEAP, rindex, member_vmindex, noreg, noreg); ++ if (VerifyMethodHandles) { ++ Label L; ++ __ bgez(rindex, L); ++ __ ebreak(); ++ __ bind(L); ++ } ++ ++ // given intf, index, and recv klass, dispatch to the implementation method ++ __ lookup_interface_method(temp1_recv_klass, temp3_intf, ++ // note: next two args must be the same: ++ rindex, xmethod, ++ temp2, ++ L_incompatible_class_change_error); ++ break; ++ } ++ ++ default: ++ fatal("unexpected intrinsic %d: %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid)); ++ break; ++ } ++ ++ // live at this point: xmethod, x30 (if interpreted) ++ ++ // After figuring out which concrete method to call, jump into it. ++ // Note that this works in the interpreter with no data motion. ++ // But the compiled version will require that r2_recv be shifted out. ++ __ verify_method_ptr(xmethod); ++ jump_from_method_handle(_masm, xmethod, temp1, for_compiler_entry); ++ if (iid == vmIntrinsics::_linkToInterface) { ++ __ bind(L_incompatible_class_change_error); ++ __ far_jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); ++ } ++ } ++ ++} ++ ++#ifndef PRODUCT ++void trace_method_handle_stub(const char* adaptername, ++ oopDesc* mh, ++ intptr_t* saved_regs, ++ intptr_t* entry_sp) { } ++ ++// The stub wraps the arguments in a struct on the stack to avoid ++// dealing with the different calling conventions for passing 6 ++// arguments. ++struct MethodHandleStubArguments { ++ const char* adaptername; ++ oopDesc* mh; ++ intptr_t* saved_regs; ++ intptr_t* entry_sp; ++}; ++void trace_method_handle_stub_wrapper(MethodHandleStubArguments* args) { } ++ ++void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { } ++#endif //PRODUCT +--- /dev/null ++++ b/src/hotspot/cpu/riscv/methodHandles_riscv.hpp +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (c) 2010, 2012, 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. ++ * ++ */ ++ ++// Platform-specific definitions for method handles. ++// These definitions are inlined into class MethodHandles. ++ ++// Adapters ++enum /* platform_dependent_constants */ { ++ adapter_code_size = 32000 DEBUG_ONLY(+ 120000) ++}; ++ ++public: ++ ++ static void load_klass_from_Class(MacroAssembler* _masm, Register klass_reg); ++ ++ static void verify_klass(MacroAssembler* _masm, ++ Register obj, vmClassID klass_id, ++ const char* error_message = "wrong klass") NOT_DEBUG_RETURN; ++ ++ static void verify_method_handle(MacroAssembler* _masm, Register mh_reg) { ++ verify_klass(_masm, mh_reg, VM_CLASS_ID(java_lang_invoke_MethodHandle), ++ "reference is a MH"); ++ } ++ ++ static void verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) NOT_DEBUG_RETURN; ++ ++ // Similar to InterpreterMacroAssembler::jump_from_interpreted. ++ // Takes care of special dispatch from single stepping too. ++ static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp, ++ bool for_compiler_entry); ++ ++ static void jump_to_lambda_form(MacroAssembler* _masm, ++ Register recv, Register method_temp, ++ Register temp2, ++ bool for_compiler_entry); +--- /dev/null ++++ b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp +@@ -0,0 +1,441 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "code/compiledIC.hpp" ++#include "memory/resourceArea.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/oop.inline.hpp" ++#include "runtime/handles.hpp" ++#include "runtime/orderAccess.hpp" ++#include "runtime/safepoint.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "utilities/ostream.hpp" ++#ifdef COMPILER1 ++#include "c1/c1_Runtime1.hpp" ++#endif ++ ++Register NativeInstruction::extract_rs1(address instr) { ++ assert_cond(instr != NULL); ++ return as_Register(Assembler::extract(((unsigned*)instr)[0], 19, 15)); ++} ++ ++Register NativeInstruction::extract_rs2(address instr) { ++ assert_cond(instr != NULL); ++ return as_Register(Assembler::extract(((unsigned*)instr)[0], 24, 20)); ++} ++ ++Register NativeInstruction::extract_rd(address instr) { ++ assert_cond(instr != NULL); ++ return as_Register(Assembler::extract(((unsigned*)instr)[0], 11, 7)); ++} ++ ++uint32_t NativeInstruction::extract_opcode(address instr) { ++ assert_cond(instr != NULL); ++ return Assembler::extract(((unsigned*)instr)[0], 6, 0); ++} ++ ++uint32_t NativeInstruction::extract_funct3(address instr) { ++ assert_cond(instr != NULL); ++ return Assembler::extract(((unsigned*)instr)[0], 14, 12); ++} ++ ++bool NativeInstruction::is_pc_relative_at(address instr) { ++ // auipc + jalr ++ // auipc + addi ++ // auipc + load ++ // auipc + fload_load ++ return (is_auipc_at(instr)) && ++ (is_addi_at(instr + instruction_size) || ++ is_jalr_at(instr + instruction_size) || ++ is_load_at(instr + instruction_size) || ++ is_float_load_at(instr + instruction_size)) && ++ check_pc_relative_data_dependency(instr); ++} ++ ++// ie:ld(Rd, Label) ++bool NativeInstruction::is_load_pc_relative_at(address instr) { ++ return is_auipc_at(instr) && // auipc ++ is_ld_at(instr + instruction_size) && // ld ++ check_load_pc_relative_data_dependency(instr); ++} ++ ++bool NativeInstruction::is_movptr_at(address instr) { ++ return is_lui_at(instr) && // Lui ++ is_addi_at(instr + instruction_size) && // Addi ++ is_slli_shift_at(instr + instruction_size * 2, 11) && // Slli Rd, Rs, 11 ++ is_addi_at(instr + instruction_size * 3) && // Addi ++ is_slli_shift_at(instr + instruction_size * 4, 6) && // Slli Rd, Rs, 6 ++ (is_addi_at(instr + instruction_size * 5) || ++ is_jalr_at(instr + instruction_size * 5) || ++ is_load_at(instr + instruction_size * 5)) && // Addi/Jalr/Load ++ check_movptr_data_dependency(instr); ++} ++ ++bool NativeInstruction::is_li32_at(address instr) { ++ return is_lui_at(instr) && // lui ++ is_addiw_at(instr + instruction_size) && // addiw ++ check_li32_data_dependency(instr); ++} ++ ++bool NativeInstruction::is_li64_at(address instr) { ++ return is_lui_at(instr) && // lui ++ is_addi_at(instr + instruction_size) && // addi ++ is_slli_shift_at(instr + instruction_size * 2, 12) && // Slli Rd, Rs, 12 ++ is_addi_at(instr + instruction_size * 3) && // addi ++ is_slli_shift_at(instr + instruction_size * 4, 12) && // Slli Rd, Rs, 12 ++ is_addi_at(instr + instruction_size * 5) && // addi ++ is_slli_shift_at(instr + instruction_size * 6, 8) && // Slli Rd, Rs, 8 ++ is_addi_at(instr + instruction_size * 7) && // addi ++ check_li64_data_dependency(instr); ++} ++ ++void NativeCall::verify() { ++ assert(NativeCall::is_call_at((address)this), "unexpected code at call site"); ++} ++ ++address NativeCall::destination() const { ++ address addr = (address)this; ++ assert(NativeInstruction::is_jal_at(instruction_address()), "inst must be jal."); ++ address destination = MacroAssembler::target_addr_for_insn(instruction_address()); ++ ++ // Do we use a trampoline stub for this call? ++ CodeBlob* cb = CodeCache::find_blob_unsafe(addr); // Else we get assertion if nmethod is zombie. ++ assert(cb && cb->is_nmethod(), "sanity"); ++ nmethod *nm = (nmethod *)cb; ++ if (nm != NULL && nm->stub_contains(destination) && is_NativeCallTrampolineStub_at(destination)) { ++ // Yes we do, so get the destination from the trampoline stub. ++ const address trampoline_stub_addr = destination; ++ destination = nativeCallTrampolineStub_at(trampoline_stub_addr)->destination(); ++ } ++ ++ return destination; ++} ++ ++// Similar to replace_mt_safe, but just changes the destination. The ++// important thing is that free-running threads are able to execute this ++// call instruction at all times. ++// ++// Used in the runtime linkage of calls; see class CompiledIC. ++// ++// Add parameter assert_lock to switch off assertion ++// during code generation, where no patching lock is needed. ++void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) { ++ assert(!assert_lock || ++ (Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) || ++ CompiledICLocker::is_safe(addr_at(0)), ++ "concurrent code patching"); ++ ++ ResourceMark rm; ++ address addr_call = addr_at(0); ++ assert(NativeCall::is_call_at(addr_call), "unexpected code at call site"); ++ ++ // Patch the constant in the call's trampoline stub. ++ address trampoline_stub_addr = get_trampoline(); ++ if (trampoline_stub_addr != NULL) { ++ assert (!is_NativeCallTrampolineStub_at(dest), "chained trampolines"); ++ nativeCallTrampolineStub_at(trampoline_stub_addr)->set_destination(dest); ++ } ++ ++ // Patch the call. ++ if (Assembler::reachable_from_branch_at(addr_call, dest)) { ++ set_destination(dest); ++ } else { ++ assert (trampoline_stub_addr != NULL, "we need a trampoline"); ++ set_destination(trampoline_stub_addr); ++ } ++ ++ ICache::invalidate_range(addr_call, instruction_size); ++} ++ ++address NativeCall::get_trampoline() { ++ address call_addr = addr_at(0); ++ ++ CodeBlob *code = CodeCache::find_blob(call_addr); ++ assert(code != NULL, "Could not find the containing code blob"); ++ ++ address jal_destination = MacroAssembler::pd_call_destination(call_addr); ++ if (code != NULL && code->contains(jal_destination) && is_NativeCallTrampolineStub_at(jal_destination)) { ++ return jal_destination; ++ } ++ ++ if (code != NULL && code->is_nmethod()) { ++ return trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code); ++ } ++ ++ return NULL; ++} ++ ++// Inserts a native call instruction at a given pc ++void NativeCall::insert(address code_pos, address entry) { Unimplemented(); } ++ ++//------------------------------------------------------------------- ++ ++void NativeMovConstReg::verify() { ++ if (!(nativeInstruction_at(instruction_address())->is_movptr() || ++ is_auipc_at(instruction_address()))) { ++ fatal("should be MOVPTR or AUIPC"); ++ } ++} ++ ++intptr_t NativeMovConstReg::data() const { ++ address addr = MacroAssembler::target_addr_for_insn(instruction_address()); ++ if (maybe_cpool_ref(instruction_address())) { ++ return *(intptr_t*)addr; ++ } else { ++ return (intptr_t)addr; ++ } ++} ++ ++void NativeMovConstReg::set_data(intptr_t x) { ++ if (maybe_cpool_ref(instruction_address())) { ++ address addr = MacroAssembler::target_addr_for_insn(instruction_address()); ++ *(intptr_t*)addr = x; ++ } else { ++ // Store x into the instruction stream. ++ MacroAssembler::pd_patch_instruction_size(instruction_address(), (address)x); ++ ICache::invalidate_range(instruction_address(), movptr_instruction_size); ++ } ++ ++ // Find and replace the oop/metadata corresponding to this ++ // instruction in oops section. ++ CodeBlob* cb = CodeCache::find_blob(instruction_address()); ++ nmethod* nm = cb->as_nmethod_or_null(); ++ if (nm != NULL) { ++ RelocIterator iter(nm, instruction_address(), next_instruction_address()); ++ while (iter.next()) { ++ if (iter.type() == relocInfo::oop_type) { ++ oop* oop_addr = iter.oop_reloc()->oop_addr(); ++ *oop_addr = cast_to_oop(x); ++ break; ++ } else if (iter.type() == relocInfo::metadata_type) { ++ Metadata** metadata_addr = iter.metadata_reloc()->metadata_addr(); ++ *metadata_addr = (Metadata*)x; ++ break; ++ } ++ } ++ } ++} ++ ++void NativeMovConstReg::print() { ++ tty->print_cr(PTR_FORMAT ": mov reg, " INTPTR_FORMAT, ++ p2i(instruction_address()), data()); ++} ++ ++//------------------------------------------------------------------- ++ ++int NativeMovRegMem::offset() const { ++ Unimplemented(); ++ return 0; ++} ++ ++void NativeMovRegMem::set_offset(int x) { Unimplemented(); } ++ ++void NativeMovRegMem::verify() { ++ Unimplemented(); ++} ++ ++//-------------------------------------------------------------------------------- ++ ++void NativeJump::verify() { } ++ ++ ++void NativeJump::check_verified_entry_alignment(address entry, address verified_entry) { ++ // Patching to not_entrant can happen while activations of the method are ++ // in use. The patching in that instance must happen only when certain ++ // alignment restrictions are true. These guarantees check those ++ // conditions. ++ ++ // Must be 4 bytes aligned ++ MacroAssembler::assert_alignment(verified_entry); ++} ++ ++ ++address NativeJump::jump_destination() const { ++ address dest = MacroAssembler::target_addr_for_insn(instruction_address()); ++ ++ // We use jump to self as the unresolved address which the inline ++ // cache code (and relocs) know about ++ // As a special case we also use sequence movptr(r,0), jalr(r,0) ++ // i.e. jump to 0 when we need leave space for a wide immediate ++ // load ++ ++ // return -1 if jump to self or to 0 ++ if ((dest == (address) this) || dest == 0) { ++ dest = (address) -1; ++ } ++ ++ return dest; ++}; ++ ++void NativeJump::set_jump_destination(address dest) { ++ // We use jump to self as the unresolved address which the inline ++ // cache code (and relocs) know about ++ if (dest == (address) -1) ++ dest = instruction_address(); ++ ++ MacroAssembler::pd_patch_instruction(instruction_address(), dest); ++ ICache::invalidate_range(instruction_address(), instruction_size); ++} ++ ++//------------------------------------------------------------------- ++ ++address NativeGeneralJump::jump_destination() const { ++ NativeMovConstReg* move = nativeMovConstReg_at(instruction_address()); ++ address dest = (address) move->data(); ++ ++ // We use jump to self as the unresolved address which the inline ++ // cache code (and relocs) know about ++ // As a special case we also use jump to 0 when first generating ++ // a general jump ++ ++ // return -1 if jump to self or to 0 ++ if ((dest == (address) this) || dest == 0) { ++ dest = (address) -1; ++ } ++ ++ return dest; ++} ++ ++//------------------------------------------------------------------- ++ ++bool NativeInstruction::is_safepoint_poll() { ++ return is_lwu_to_zr(address(this)); ++} ++ ++bool NativeInstruction::is_lwu_to_zr(address instr) { ++ assert_cond(instr != NULL); ++ return (extract_opcode(instr) == 0b0000011 && ++ extract_funct3(instr) == 0b110 && ++ extract_rd(instr) == zr); // zr ++} ++ ++// A 16-bit instruction with all bits ones is permanently reserved as an illegal instruction. ++bool NativeInstruction::is_sigill_zombie_not_entrant() { ++ // jvmci ++ return uint_at(0) == 0xffffffff; ++} ++ ++void NativeIllegalInstruction::insert(address code_pos) { ++ assert_cond(code_pos != NULL); ++ *(juint*)code_pos = 0xffffffff; // all bits ones is permanently reserved as an illegal instruction ++} ++ ++bool NativeInstruction::is_stop() { ++ return uint_at(0) == 0xc0101073; // an illegal instruction, 'csrrw x0, time, x0' ++} ++ ++//------------------------------------------------------------------- ++ ++// MT-safe inserting of a jump over a jump or a nop (used by ++// nmethod::make_not_entrant_or_zombie) ++ ++void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) { ++ ++ assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch"); ++ ++ assert(nativeInstruction_at(verified_entry)->is_jump_or_nop() || ++ nativeInstruction_at(verified_entry)->is_sigill_zombie_not_entrant(), ++ "riscv cannot replace non-jump with jump"); ++ ++ check_verified_entry_alignment(entry, verified_entry); ++ ++ // Patch this nmethod atomically. ++ if (Assembler::reachable_from_branch_at(verified_entry, dest)) { ++ ptrdiff_t offset = dest - verified_entry; ++ guarantee(Assembler::is_simm21(offset) && ((offset % 2) == 0), ++ "offset is too large to be patched in one jal instruction."); // 1M ++ ++ uint32_t insn = 0; ++ address pInsn = (address)&insn; ++ Assembler::patch(pInsn, 31, 31, (offset >> 20) & 0x1); ++ Assembler::patch(pInsn, 30, 21, (offset >> 1) & 0x3ff); ++ Assembler::patch(pInsn, 20, 20, (offset >> 11) & 0x1); ++ Assembler::patch(pInsn, 19, 12, (offset >> 12) & 0xff); ++ Assembler::patch(pInsn, 11, 7, 0); // zero, no link jump ++ Assembler::patch(pInsn, 6, 0, 0b1101111); // j, (jal x0 offset) ++ *(unsigned int*)verified_entry = insn; ++ } else { ++ // We use an illegal instruction for marking a method as ++ // not_entrant or zombie. ++ NativeIllegalInstruction::insert(verified_entry); ++ } ++ ++ ICache::invalidate_range(verified_entry, instruction_size); ++} ++ ++void NativeGeneralJump::insert_unconditional(address code_pos, address entry) { ++ CodeBuffer cb(code_pos, instruction_size); ++ MacroAssembler a(&cb); ++ Assembler::IncompressibleRegion ir(&a); // Fixed length: see NativeGeneralJump::get_instruction_size() ++ ++ int32_t offset = 0; ++ a.movptr(t0, entry, offset); // lui, addi, slli, addi, slli ++ a.jalr(x0, t0, offset); // jalr ++ ++ ICache::invalidate_range(code_pos, instruction_size); ++} ++ ++// MT-safe patching of a long jump instruction. ++void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) { ++ ShouldNotCallThis(); ++} ++ ++ ++address NativeCallTrampolineStub::destination(nmethod *nm) const { ++ return ptr_at(data_offset); ++} ++ ++void NativeCallTrampolineStub::set_destination(address new_destination) { ++ set_ptr_at(data_offset, new_destination); ++ OrderAccess::release(); ++} ++ ++uint32_t NativeMembar::get_kind() { ++ uint32_t insn = uint_at(0); ++ ++ uint32_t predecessor = Assembler::extract(insn, 27, 24); ++ uint32_t successor = Assembler::extract(insn, 23, 20); ++ ++ return MacroAssembler::pred_succ_to_membar_mask(predecessor, successor); ++} ++ ++void NativeMembar::set_kind(uint32_t order_kind) { ++ uint32_t predecessor = 0; ++ uint32_t successor = 0; ++ ++ MacroAssembler::membar_mask_to_pred_succ(order_kind, predecessor, successor); ++ ++ uint32_t insn = uint_at(0); ++ address pInsn = (address) &insn; ++ Assembler::patch(pInsn, 27, 24, predecessor); ++ Assembler::patch(pInsn, 23, 20, successor); ++ ++ address membar = addr_at(0); ++ *(unsigned int*) membar = insn; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/nativeInst_riscv.hpp +@@ -0,0 +1,554 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_NATIVEINST_RISCV_HPP ++#define CPU_RISCV_NATIVEINST_RISCV_HPP ++ ++#include "asm/assembler.hpp" ++#include "runtime/icache.hpp" ++#include "runtime/os.hpp" ++ ++// We have interfaces for the following instructions: ++// - NativeInstruction ++// - - NativeCall ++// - - NativeMovConstReg ++// - - NativeMovRegMem ++// - - NativeJump ++// - - NativeGeneralJump ++// - - NativeIllegalInstruction ++// - - NativeCallTrampolineStub ++// - - NativeMembar ++ ++// The base class for different kinds of native instruction abstractions. ++// Provides the primitive operations to manipulate code relative to this. ++ ++class NativeCall; ++ ++class NativeInstruction { ++ friend class Relocation; ++ friend bool is_NativeCallTrampolineStub_at(address); ++ public: ++ enum { ++ instruction_size = 4, ++ compressed_instruction_size = 2, ++ }; ++ ++ juint encoding() const { ++ return uint_at(0); ++ } ++ ++ bool is_jal() const { return is_jal_at(addr_at(0)); } ++ bool is_movptr() const { return is_movptr_at(addr_at(0)); } ++ bool is_call() const { return is_call_at(addr_at(0)); } ++ bool is_jump() const { return is_jump_at(addr_at(0)); } ++ ++ static bool is_jal_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b1101111; } ++ static bool is_jalr_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b1100111 && extract_funct3(instr) == 0b000; } ++ static bool is_branch_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b1100011; } ++ static bool is_ld_at(address instr) { assert_cond(instr != NULL); return is_load_at(instr) && extract_funct3(instr) == 0b011; } ++ static bool is_load_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0000011; } ++ static bool is_float_load_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0000111; } ++ static bool is_auipc_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0010111; } ++ static bool is_jump_at(address instr) { assert_cond(instr != NULL); return is_branch_at(instr) || is_jal_at(instr) || is_jalr_at(instr); } ++ static bool is_addi_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0010011 && extract_funct3(instr) == 0b000; } ++ static bool is_addiw_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0011011 && extract_funct3(instr) == 0b000; } ++ static bool is_lui_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0110111; } ++ static bool is_slli_shift_at(address instr, uint32_t shift) { ++ assert_cond(instr != NULL); ++ return (extract_opcode(instr) == 0b0010011 && // opcode field ++ extract_funct3(instr) == 0b001 && // funct3 field, select the type of operation ++ Assembler::extract(((unsigned*)instr)[0], 25, 20) == shift); // shamt field ++ } ++ ++ static Register extract_rs1(address instr); ++ static Register extract_rs2(address instr); ++ static Register extract_rd(address instr); ++ static uint32_t extract_opcode(address instr); ++ static uint32_t extract_funct3(address instr); ++ ++ // the instruction sequence of movptr is as below: ++ // lui ++ // addi ++ // slli ++ // addi ++ // slli ++ // addi/jalr/load ++ static bool check_movptr_data_dependency(address instr) { ++ address lui = instr; ++ address addi1 = lui + instruction_size; ++ address slli1 = addi1 + instruction_size; ++ address addi2 = slli1 + instruction_size; ++ address slli2 = addi2 + instruction_size; ++ address last_instr = slli2 + instruction_size; ++ return extract_rs1(addi1) == extract_rd(lui) && ++ extract_rs1(addi1) == extract_rd(addi1) && ++ extract_rs1(slli1) == extract_rd(addi1) && ++ extract_rs1(slli1) == extract_rd(slli1) && ++ extract_rs1(addi2) == extract_rd(slli1) && ++ extract_rs1(addi2) == extract_rd(addi2) && ++ extract_rs1(slli2) == extract_rd(addi2) && ++ extract_rs1(slli2) == extract_rd(slli2) && ++ extract_rs1(last_instr) == extract_rd(slli2); ++ } ++ ++ // the instruction sequence of li64 is as below: ++ // lui ++ // addi ++ // slli ++ // addi ++ // slli ++ // addi ++ // slli ++ // addi ++ static bool check_li64_data_dependency(address instr) { ++ address lui = instr; ++ address addi1 = lui + instruction_size; ++ address slli1 = addi1 + instruction_size; ++ address addi2 = slli1 + instruction_size; ++ address slli2 = addi2 + instruction_size; ++ address addi3 = slli2 + instruction_size; ++ address slli3 = addi3 + instruction_size; ++ address addi4 = slli3 + instruction_size; ++ return extract_rs1(addi1) == extract_rd(lui) && ++ extract_rs1(addi1) == extract_rd(addi1) && ++ extract_rs1(slli1) == extract_rd(addi1) && ++ extract_rs1(slli1) == extract_rd(slli1) && ++ extract_rs1(addi2) == extract_rd(slli1) && ++ extract_rs1(addi2) == extract_rd(addi2) && ++ extract_rs1(slli2) == extract_rd(addi2) && ++ extract_rs1(slli2) == extract_rd(slli2) && ++ extract_rs1(addi3) == extract_rd(slli2) && ++ extract_rs1(addi3) == extract_rd(addi3) && ++ extract_rs1(slli3) == extract_rd(addi3) && ++ extract_rs1(slli3) == extract_rd(slli3) && ++ extract_rs1(addi4) == extract_rd(slli3) && ++ extract_rs1(addi4) == extract_rd(addi4); ++ } ++ ++ // the instruction sequence of li32 is as below: ++ // lui ++ // addiw ++ static bool check_li32_data_dependency(address instr) { ++ address lui = instr; ++ address addiw = lui + instruction_size; ++ ++ return extract_rs1(addiw) == extract_rd(lui) && ++ extract_rs1(addiw) == extract_rd(addiw); ++ } ++ ++ // the instruction sequence of pc-relative is as below: ++ // auipc ++ // jalr/addi/load/float_load ++ static bool check_pc_relative_data_dependency(address instr) { ++ address auipc = instr; ++ address last_instr = auipc + instruction_size; ++ ++ return extract_rs1(last_instr) == extract_rd(auipc); ++ } ++ ++ // the instruction sequence of load_label is as below: ++ // auipc ++ // load ++ static bool check_load_pc_relative_data_dependency(address instr) { ++ address auipc = instr; ++ address load = auipc + instruction_size; ++ ++ return extract_rd(load) == extract_rd(auipc) && ++ extract_rs1(load) == extract_rd(load); ++ } ++ ++ static bool is_movptr_at(address instr); ++ static bool is_li32_at(address instr); ++ static bool is_li64_at(address instr); ++ static bool is_pc_relative_at(address branch); ++ static bool is_load_pc_relative_at(address branch); ++ ++ static bool is_call_at(address instr) { ++ if (is_jal_at(instr) || is_jalr_at(instr)) { ++ return true; ++ } ++ return false; ++ } ++ static bool is_lwu_to_zr(address instr); ++ ++ inline bool is_nop(); ++ inline bool is_jump_or_nop(); ++ bool is_safepoint_poll(); ++ bool is_sigill_zombie_not_entrant(); ++ bool is_stop(); ++ ++ protected: ++ address addr_at(int offset) const { return address(this) + offset; } ++ ++ jint int_at(int offset) const { return *(jint*) addr_at(offset); } ++ juint uint_at(int offset) const { return *(juint*) addr_at(offset); } ++ ++ address ptr_at(int offset) const { return *(address*) addr_at(offset); } ++ ++ oop oop_at (int offset) const { return *(oop*) addr_at(offset); } ++ ++ ++ void set_int_at(int offset, jint i) { *(jint*)addr_at(offset) = i; } ++ void set_uint_at(int offset, jint i) { *(juint*)addr_at(offset) = i; } ++ void set_ptr_at (int offset, address ptr) { *(address*) addr_at(offset) = ptr; } ++ void set_oop_at (int offset, oop o) { *(oop*) addr_at(offset) = o; } ++ ++ public: ++ ++ inline friend NativeInstruction* nativeInstruction_at(address addr); ++ ++ static bool maybe_cpool_ref(address instr) { ++ return is_auipc_at(instr); ++ } ++ ++ bool is_membar() { ++ return (uint_at(0) & 0x7f) == 0b1111 && extract_funct3(addr_at(0)) == 0; ++ } ++}; ++ ++inline NativeInstruction* nativeInstruction_at(address addr) { ++ return (NativeInstruction*)addr; ++} ++ ++// The natural type of an RISCV instruction is uint32_t ++inline NativeInstruction* nativeInstruction_at(uint32_t *addr) { ++ return (NativeInstruction*)addr; ++} ++ ++inline NativeCall* nativeCall_at(address addr); ++// The NativeCall is an abstraction for accessing/manipulating native ++// call instructions (used to manipulate inline caches, primitive & ++// DSO calls, etc.). ++ ++class NativeCall: public NativeInstruction { ++ public: ++ enum RISCV_specific_constants { ++ instruction_size = 4, ++ instruction_offset = 0, ++ displacement_offset = 0, ++ return_address_offset = 4 ++ }; ++ ++ address instruction_address() const { return addr_at(instruction_offset); } ++ address next_instruction_address() const { return addr_at(return_address_offset); } ++ address return_address() const { return addr_at(return_address_offset); } ++ address destination() const; ++ ++ void set_destination(address dest) { ++ assert(is_jal(), "Should be jal instruction!"); ++ intptr_t offset = (intptr_t)(dest - instruction_address()); ++ assert((offset & 0x1) == 0, "bad alignment"); ++ assert(Assembler::is_simm21(offset), "encoding constraint"); ++ unsigned int insn = 0b1101111; // jal ++ address pInsn = (address)(&insn); ++ Assembler::patch(pInsn, 31, 31, (offset >> 20) & 0x1); ++ Assembler::patch(pInsn, 30, 21, (offset >> 1) & 0x3ff); ++ Assembler::patch(pInsn, 20, 20, (offset >> 11) & 0x1); ++ Assembler::patch(pInsn, 19, 12, (offset >> 12) & 0xff); ++ Assembler::patch(pInsn, 11, 7, ra->encoding()); // Rd must be x1, need ra ++ set_int_at(displacement_offset, insn); ++ } ++ ++ void verify_alignment() {} // do nothing on riscv ++ void verify(); ++ void print(); ++ ++ // Creation ++ inline friend NativeCall* nativeCall_at(address addr); ++ inline friend NativeCall* nativeCall_before(address return_address); ++ ++ static bool is_call_before(address return_address) { ++ return is_call_at(return_address - NativeCall::return_address_offset); ++ } ++ ++ // MT-safe patching of a call instruction. ++ static void insert(address code_pos, address entry); ++ ++ static void replace_mt_safe(address instr_addr, address code_buffer); ++ ++ // Similar to replace_mt_safe, but just changes the destination. The ++ // important thing is that free-running threads are able to execute ++ // this call instruction at all times. If the call is an immediate BL ++ // instruction we can simply rely on atomicity of 32-bit writes to ++ // make sure other threads will see no intermediate states. ++ ++ // We cannot rely on locks here, since the free-running threads must run at ++ // full speed. ++ // ++ // Used in the runtime linkage of calls; see class CompiledIC. ++ // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.) ++ ++ // The parameter assert_lock disables the assertion during code generation. ++ void set_destination_mt_safe(address dest, bool assert_lock = true); ++ ++ address get_trampoline(); ++}; ++ ++inline NativeCall* nativeCall_at(address addr) { ++ assert_cond(addr != NULL); ++ NativeCall* call = (NativeCall*)(addr - NativeCall::instruction_offset); ++ DEBUG_ONLY(call->verify()); ++ return call; ++} ++ ++inline NativeCall* nativeCall_before(address return_address) { ++ assert_cond(return_address != NULL); ++ NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset); ++ DEBUG_ONLY(call->verify()); ++ return call; ++} ++ ++// An interface for accessing/manipulating native mov reg, imm instructions. ++// (used to manipulate inlined 64-bit data calls, etc.) ++class NativeMovConstReg: public NativeInstruction { ++ public: ++ enum RISCV_specific_constants { ++ movptr_instruction_size = 6 * NativeInstruction::instruction_size, // lui, addi, slli, addi, slli, addi. See movptr(). ++ load_pc_relative_instruction_size = 2 * NativeInstruction::instruction_size, // auipc, ld ++ instruction_offset = 0, ++ displacement_offset = 0 ++ }; ++ ++ address instruction_address() const { return addr_at(instruction_offset); } ++ address next_instruction_address() const { ++ // if the instruction at 5 * instruction_size is addi, ++ // it means a lui + addi + slli + addi + slli + addi instruction sequence, ++ // and the next instruction address should be addr_at(6 * instruction_size). ++ // However, when the instruction at 5 * instruction_size isn't addi, ++ // the next instruction address should be addr_at(5 * instruction_size) ++ if (nativeInstruction_at(instruction_address())->is_movptr()) { ++ if (is_addi_at(addr_at(movptr_instruction_size - NativeInstruction::instruction_size))) { ++ // Assume: lui, addi, slli, addi, slli, addi ++ return addr_at(movptr_instruction_size); ++ } else { ++ // Assume: lui, addi, slli, addi, slli ++ return addr_at(movptr_instruction_size - NativeInstruction::instruction_size); ++ } ++ } else if (is_load_pc_relative_at(instruction_address())) { ++ // Assume: auipc, ld ++ return addr_at(load_pc_relative_instruction_size); ++ } ++ guarantee(false, "Unknown instruction in NativeMovConstReg"); ++ return NULL; ++ } ++ ++ intptr_t data() const; ++ void set_data(intptr_t x); ++ ++ void flush() { ++ if (!maybe_cpool_ref(instruction_address())) { ++ ICache::invalidate_range(instruction_address(), movptr_instruction_size); ++ } ++ } ++ ++ void verify(); ++ void print(); ++ ++ // Creation ++ inline friend NativeMovConstReg* nativeMovConstReg_at(address addr); ++ inline friend NativeMovConstReg* nativeMovConstReg_before(address addr); ++}; ++ ++inline NativeMovConstReg* nativeMovConstReg_at(address addr) { ++ assert_cond(addr != NULL); ++ NativeMovConstReg* test = (NativeMovConstReg*)(addr - NativeMovConstReg::instruction_offset); ++ DEBUG_ONLY(test->verify()); ++ return test; ++} ++ ++inline NativeMovConstReg* nativeMovConstReg_before(address addr) { ++ assert_cond(addr != NULL); ++ NativeMovConstReg* test = (NativeMovConstReg*)(addr - NativeMovConstReg::instruction_size - NativeMovConstReg::instruction_offset); ++ DEBUG_ONLY(test->verify()); ++ return test; ++} ++ ++// RISCV should not use C1 runtime patching, but still implement ++// NativeMovRegMem to keep some compilers happy. ++class NativeMovRegMem: public NativeInstruction { ++ public: ++ enum RISCV_specific_constants { ++ instruction_size = NativeInstruction::instruction_size, ++ instruction_offset = 0, ++ data_offset = 0, ++ next_instruction_offset = NativeInstruction::instruction_size ++ }; ++ ++ int instruction_start() const { return instruction_offset; } ++ ++ address instruction_address() const { return addr_at(instruction_offset); } ++ ++ int num_bytes_to_end_of_patch() const { return instruction_offset + instruction_size; } ++ ++ int offset() const; ++ ++ void set_offset(int x); ++ ++ void add_offset_in_bytes(int add_offset) { ++ set_offset(offset() + add_offset); ++ } ++ ++ void verify(); ++ void print(); ++ ++ private: ++ inline friend NativeMovRegMem* nativeMovRegMem_at(address addr); ++}; ++ ++inline NativeMovRegMem* nativeMovRegMem_at(address addr) { ++ NativeMovRegMem* test = (NativeMovRegMem*)(addr - NativeMovRegMem::instruction_offset); ++ DEBUG_ONLY(test->verify()); ++ return test; ++} ++ ++class NativeJump: public NativeInstruction { ++ public: ++ enum RISCV_specific_constants { ++ instruction_size = NativeInstruction::instruction_size, ++ instruction_offset = 0, ++ data_offset = 0, ++ next_instruction_offset = NativeInstruction::instruction_size ++ }; ++ ++ address instruction_address() const { return addr_at(instruction_offset); } ++ address next_instruction_address() const { return addr_at(instruction_size); } ++ address jump_destination() const; ++ void set_jump_destination(address dest); ++ ++ // Creation ++ inline friend NativeJump* nativeJump_at(address address); ++ ++ void verify(); ++ ++ // Insertion of native jump instruction ++ static void insert(address code_pos, address entry); ++ // MT-safe insertion of native jump at verified method entry ++ static void check_verified_entry_alignment(address entry, address verified_entry); ++ static void patch_verified_entry(address entry, address verified_entry, address dest); ++}; ++ ++inline NativeJump* nativeJump_at(address addr) { ++ NativeJump* jump = (NativeJump*)(addr - NativeJump::instruction_offset); ++ DEBUG_ONLY(jump->verify()); ++ return jump; ++} ++ ++class NativeGeneralJump: public NativeJump { ++public: ++ enum RISCV_specific_constants { ++ instruction_size = 6 * NativeInstruction::instruction_size, // lui, addi, slli, addi, slli, jalr ++ instruction_offset = 0, ++ data_offset = 0, ++ next_instruction_offset = 6 * NativeInstruction::instruction_size // lui, addi, slli, addi, slli, jalr ++ }; ++ ++ address jump_destination() const; ++ ++ static void insert_unconditional(address code_pos, address entry); ++ static void replace_mt_safe(address instr_addr, address code_buffer); ++}; ++ ++inline NativeGeneralJump* nativeGeneralJump_at(address addr) { ++ assert_cond(addr != NULL); ++ NativeGeneralJump* jump = (NativeGeneralJump*)(addr); ++ debug_only(jump->verify();) ++ return jump; ++} ++ ++class NativeIllegalInstruction: public NativeInstruction { ++ public: ++ // Insert illegal opcode as specific address ++ static void insert(address code_pos); ++}; ++ ++inline bool NativeInstruction::is_nop() { ++ uint32_t insn = *(uint32_t*)addr_at(0); ++ return insn == 0x13; ++} ++ ++inline bool NativeInstruction::is_jump_or_nop() { ++ return is_nop() || is_jump(); ++} ++ ++// Call trampoline stubs. ++class NativeCallTrampolineStub : public NativeInstruction { ++ public: ++ ++ enum RISCV_specific_constants { ++ // Refer to function emit_trampoline_stub. ++ instruction_size = 3 * NativeInstruction::instruction_size + wordSize, // auipc + ld + jr + target address ++ data_offset = 3 * NativeInstruction::instruction_size, // auipc + ld + jr ++ }; ++ ++ address destination(nmethod *nm = NULL) const; ++ void set_destination(address new_destination); ++ ptrdiff_t destination_offset() const; ++}; ++ ++inline bool is_NativeCallTrampolineStub_at(address addr) { ++ // Ensure that the stub is exactly ++ // ld t0, L--->auipc + ld ++ // jr t0 ++ // L: ++ ++ // judge inst + register + imm ++ // 1). check the instructions: auipc + ld + jalr ++ // 2). check if auipc[11:7] == t0 and ld[11:7] == t0 and ld[19:15] == t0 && jr[19:15] == t0 ++ // 3). check if the offset in ld[31:20] equals the data_offset ++ assert_cond(addr != NULL); ++ const int instr_size = NativeInstruction::instruction_size; ++ if (NativeInstruction::is_auipc_at(addr) && ++ NativeInstruction::is_ld_at(addr + instr_size) && ++ NativeInstruction::is_jalr_at(addr + 2 * instr_size) && ++ (NativeInstruction::extract_rd(addr) == x5) && ++ (NativeInstruction::extract_rd(addr + instr_size) == x5) && ++ (NativeInstruction::extract_rs1(addr + instr_size) == x5) && ++ (NativeInstruction::extract_rs1(addr + 2 * instr_size) == x5) && ++ (Assembler::extract(((unsigned*)addr)[1], 31, 20) == NativeCallTrampolineStub::data_offset)) { ++ return true; ++ } ++ return false; ++} ++ ++inline NativeCallTrampolineStub* nativeCallTrampolineStub_at(address addr) { ++ assert_cond(addr != NULL); ++ assert(is_NativeCallTrampolineStub_at(addr), "no call trampoline found"); ++ return (NativeCallTrampolineStub*)addr; ++} ++ ++class NativeMembar : public NativeInstruction { ++public: ++ uint32_t get_kind(); ++ void set_kind(uint32_t order_kind); ++}; ++ ++inline NativeMembar *NativeMembar_at(address addr) { ++ assert_cond(addr != NULL); ++ assert(nativeInstruction_at(addr)->is_membar(), "no membar found"); ++ return (NativeMembar*)addr; ++} ++ ++#endif // CPU_RISCV_NATIVEINST_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/registerMap_riscv.cpp +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "runtime/registerMap.hpp" ++#include "vmreg_riscv.inline.hpp" ++ ++address RegisterMap::pd_location(VMReg base_reg, int slot_idx) const { ++ if (base_reg->is_VectorRegister()) { ++ assert(base_reg->is_concrete(), "must pass base reg"); ++ int base_reg_enc = (base_reg->value() - ConcreteRegisterImpl::max_fpr) / ++ VectorRegisterImpl::max_slots_per_register; ++ intptr_t offset_in_bytes = slot_idx * VMRegImpl::stack_slot_size; ++ address base_location = location(base_reg); ++ if (base_location != NULL) { ++ return base_location + offset_in_bytes; ++ } else { ++ return NULL; ++ } ++ } else { ++ return location(base_reg->next(slot_idx)); ++ } ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/registerMap_riscv.hpp +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 1998, 2020, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_REGISTERMAP_RISCV_HPP ++#define CPU_RISCV_REGISTERMAP_RISCV_HPP ++ ++// machine-dependent implemention for register maps ++ friend class frame; ++ ++ private: ++ // This is the hook for finding a register in an "well-known" location, ++ // such as a register block of a predetermined format. ++ address pd_location(VMReg reg) const { return NULL; } ++ address pd_location(VMReg base_reg, int slot_idx) const; ++ ++ // no PD state to clear or copy: ++ void pd_clear() {} ++ void pd_initialize() {} ++ void pd_initialize_from(const RegisterMap* map) {} ++ ++#endif // CPU_RISCV_REGISTERMAP_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/register_definitions_riscv.cpp +@@ -0,0 +1,193 @@ ++/* ++ * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "asm/register.hpp" ++#include "interp_masm_riscv.hpp" ++#include "register_riscv.hpp" ++ ++REGISTER_DEFINITION(Register, noreg); ++ ++REGISTER_DEFINITION(Register, x0); ++REGISTER_DEFINITION(Register, x1); ++REGISTER_DEFINITION(Register, x2); ++REGISTER_DEFINITION(Register, x3); ++REGISTER_DEFINITION(Register, x4); ++REGISTER_DEFINITION(Register, x5); ++REGISTER_DEFINITION(Register, x6); ++REGISTER_DEFINITION(Register, x7); ++REGISTER_DEFINITION(Register, x8); ++REGISTER_DEFINITION(Register, x9); ++REGISTER_DEFINITION(Register, x10); ++REGISTER_DEFINITION(Register, x11); ++REGISTER_DEFINITION(Register, x12); ++REGISTER_DEFINITION(Register, x13); ++REGISTER_DEFINITION(Register, x14); ++REGISTER_DEFINITION(Register, x15); ++REGISTER_DEFINITION(Register, x16); ++REGISTER_DEFINITION(Register, x17); ++REGISTER_DEFINITION(Register, x18); ++REGISTER_DEFINITION(Register, x19); ++REGISTER_DEFINITION(Register, x20); ++REGISTER_DEFINITION(Register, x21); ++REGISTER_DEFINITION(Register, x22); ++REGISTER_DEFINITION(Register, x23); ++REGISTER_DEFINITION(Register, x24); ++REGISTER_DEFINITION(Register, x25); ++REGISTER_DEFINITION(Register, x26); ++REGISTER_DEFINITION(Register, x27); ++REGISTER_DEFINITION(Register, x28); ++REGISTER_DEFINITION(Register, x29); ++REGISTER_DEFINITION(Register, x30); ++REGISTER_DEFINITION(Register, x31); ++ ++REGISTER_DEFINITION(FloatRegister, fnoreg); ++ ++REGISTER_DEFINITION(FloatRegister, f0); ++REGISTER_DEFINITION(FloatRegister, f1); ++REGISTER_DEFINITION(FloatRegister, f2); ++REGISTER_DEFINITION(FloatRegister, f3); ++REGISTER_DEFINITION(FloatRegister, f4); ++REGISTER_DEFINITION(FloatRegister, f5); ++REGISTER_DEFINITION(FloatRegister, f6); ++REGISTER_DEFINITION(FloatRegister, f7); ++REGISTER_DEFINITION(FloatRegister, f8); ++REGISTER_DEFINITION(FloatRegister, f9); ++REGISTER_DEFINITION(FloatRegister, f10); ++REGISTER_DEFINITION(FloatRegister, f11); ++REGISTER_DEFINITION(FloatRegister, f12); ++REGISTER_DEFINITION(FloatRegister, f13); ++REGISTER_DEFINITION(FloatRegister, f14); ++REGISTER_DEFINITION(FloatRegister, f15); ++REGISTER_DEFINITION(FloatRegister, f16); ++REGISTER_DEFINITION(FloatRegister, f17); ++REGISTER_DEFINITION(FloatRegister, f18); ++REGISTER_DEFINITION(FloatRegister, f19); ++REGISTER_DEFINITION(FloatRegister, f20); ++REGISTER_DEFINITION(FloatRegister, f21); ++REGISTER_DEFINITION(FloatRegister, f22); ++REGISTER_DEFINITION(FloatRegister, f23); ++REGISTER_DEFINITION(FloatRegister, f24); ++REGISTER_DEFINITION(FloatRegister, f25); ++REGISTER_DEFINITION(FloatRegister, f26); ++REGISTER_DEFINITION(FloatRegister, f27); ++REGISTER_DEFINITION(FloatRegister, f28); ++REGISTER_DEFINITION(FloatRegister, f29); ++REGISTER_DEFINITION(FloatRegister, f30); ++REGISTER_DEFINITION(FloatRegister, f31); ++ ++REGISTER_DEFINITION(VectorRegister, vnoreg); ++ ++REGISTER_DEFINITION(VectorRegister, v0); ++REGISTER_DEFINITION(VectorRegister, v1); ++REGISTER_DEFINITION(VectorRegister, v2); ++REGISTER_DEFINITION(VectorRegister, v3); ++REGISTER_DEFINITION(VectorRegister, v4); ++REGISTER_DEFINITION(VectorRegister, v5); ++REGISTER_DEFINITION(VectorRegister, v6); ++REGISTER_DEFINITION(VectorRegister, v7); ++REGISTER_DEFINITION(VectorRegister, v8); ++REGISTER_DEFINITION(VectorRegister, v9); ++REGISTER_DEFINITION(VectorRegister, v10); ++REGISTER_DEFINITION(VectorRegister, v11); ++REGISTER_DEFINITION(VectorRegister, v12); ++REGISTER_DEFINITION(VectorRegister, v13); ++REGISTER_DEFINITION(VectorRegister, v14); ++REGISTER_DEFINITION(VectorRegister, v15); ++REGISTER_DEFINITION(VectorRegister, v16); ++REGISTER_DEFINITION(VectorRegister, v17); ++REGISTER_DEFINITION(VectorRegister, v18); ++REGISTER_DEFINITION(VectorRegister, v19); ++REGISTER_DEFINITION(VectorRegister, v20); ++REGISTER_DEFINITION(VectorRegister, v21); ++REGISTER_DEFINITION(VectorRegister, v22); ++REGISTER_DEFINITION(VectorRegister, v23); ++REGISTER_DEFINITION(VectorRegister, v24); ++REGISTER_DEFINITION(VectorRegister, v25); ++REGISTER_DEFINITION(VectorRegister, v26); ++REGISTER_DEFINITION(VectorRegister, v27); ++REGISTER_DEFINITION(VectorRegister, v28); ++REGISTER_DEFINITION(VectorRegister, v29); ++REGISTER_DEFINITION(VectorRegister, v30); ++REGISTER_DEFINITION(VectorRegister, v31); ++ ++REGISTER_DEFINITION(Register, c_rarg0); ++REGISTER_DEFINITION(Register, c_rarg1); ++REGISTER_DEFINITION(Register, c_rarg2); ++REGISTER_DEFINITION(Register, c_rarg3); ++REGISTER_DEFINITION(Register, c_rarg4); ++REGISTER_DEFINITION(Register, c_rarg5); ++REGISTER_DEFINITION(Register, c_rarg6); ++REGISTER_DEFINITION(Register, c_rarg7); ++ ++REGISTER_DEFINITION(FloatRegister, c_farg0); ++REGISTER_DEFINITION(FloatRegister, c_farg1); ++REGISTER_DEFINITION(FloatRegister, c_farg2); ++REGISTER_DEFINITION(FloatRegister, c_farg3); ++REGISTER_DEFINITION(FloatRegister, c_farg4); ++REGISTER_DEFINITION(FloatRegister, c_farg5); ++REGISTER_DEFINITION(FloatRegister, c_farg6); ++REGISTER_DEFINITION(FloatRegister, c_farg7); ++ ++REGISTER_DEFINITION(Register, j_rarg0); ++REGISTER_DEFINITION(Register, j_rarg1); ++REGISTER_DEFINITION(Register, j_rarg2); ++REGISTER_DEFINITION(Register, j_rarg3); ++REGISTER_DEFINITION(Register, j_rarg4); ++REGISTER_DEFINITION(Register, j_rarg5); ++REGISTER_DEFINITION(Register, j_rarg6); ++REGISTER_DEFINITION(Register, j_rarg7); ++ ++REGISTER_DEFINITION(FloatRegister, j_farg0); ++REGISTER_DEFINITION(FloatRegister, j_farg1); ++REGISTER_DEFINITION(FloatRegister, j_farg2); ++REGISTER_DEFINITION(FloatRegister, j_farg3); ++REGISTER_DEFINITION(FloatRegister, j_farg4); ++REGISTER_DEFINITION(FloatRegister, j_farg5); ++REGISTER_DEFINITION(FloatRegister, j_farg6); ++REGISTER_DEFINITION(FloatRegister, j_farg7); ++ ++REGISTER_DEFINITION(Register, zr); ++REGISTER_DEFINITION(Register, gp); ++REGISTER_DEFINITION(Register, tp); ++REGISTER_DEFINITION(Register, xmethod); ++REGISTER_DEFINITION(Register, ra); ++REGISTER_DEFINITION(Register, sp); ++REGISTER_DEFINITION(Register, fp); ++REGISTER_DEFINITION(Register, xheapbase); ++REGISTER_DEFINITION(Register, xcpool); ++REGISTER_DEFINITION(Register, xmonitors); ++REGISTER_DEFINITION(Register, xlocals); ++REGISTER_DEFINITION(Register, xthread); ++REGISTER_DEFINITION(Register, xbcp); ++REGISTER_DEFINITION(Register, xdispatch); ++REGISTER_DEFINITION(Register, esp); ++ ++REGISTER_DEFINITION(Register, t0); ++REGISTER_DEFINITION(Register, t1); ++REGISTER_DEFINITION(Register, t2); +--- /dev/null ++++ b/src/hotspot/cpu/riscv/register_riscv.cpp +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "register_riscv.hpp" ++ ++const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers * ++ RegisterImpl::max_slots_per_register; ++ ++const int ConcreteRegisterImpl::max_fpr = ++ ConcreteRegisterImpl::max_gpr + ++ FloatRegisterImpl::number_of_registers * FloatRegisterImpl::max_slots_per_register; ++ ++const int ConcreteRegisterImpl::max_vpr = ++ ConcreteRegisterImpl::max_fpr + ++ VectorRegisterImpl::number_of_registers * VectorRegisterImpl::max_slots_per_register; ++ ++ ++const char* RegisterImpl::name() const { ++ static const char *const names[number_of_registers] = { ++ "zr", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "x9", ++ "c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7", ++ "x18", "x19", "esp", "xdispatch", "xbcp", "xthread", "xlocals", ++ "xmonitors", "xcpool", "xheapbase", "x28", "x29", "x30", "xmethod" ++ }; ++ return is_valid() ? names[encoding()] : "noreg"; ++} ++ ++const char* FloatRegisterImpl::name() const { ++ static const char *const names[number_of_registers] = { ++ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", ++ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", ++ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", ++ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" ++ }; ++ return is_valid() ? names[encoding()] : "noreg"; ++} ++ ++const char* VectorRegisterImpl::name() const { ++ static const char *const names[number_of_registers] = { ++ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", ++ "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", ++ "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", ++ "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" ++ }; ++ return is_valid() ? names[encoding()] : "noreg"; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/register_riscv.hpp +@@ -0,0 +1,385 @@ ++/* ++ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_REGISTER_RISCV_HPP ++#define CPU_RISCV_REGISTER_RISCV_HPP ++ ++#include "asm/register.hpp" ++ ++#define CSR_FFLAGS 0x001 // Floating-Point Accrued Exceptions. ++#define CSR_FRM 0x002 // Floating-Point Dynamic Rounding Mode. ++#define CSR_FCSR 0x003 // Floating-Point Control and Status Register (frm + fflags). ++#define CSR_VSTART 0x008 // Vector start position ++#define CSR_VXSAT 0x009 // Fixed-Point Saturate Flag ++#define CSR_VXRM 0x00A // Fixed-Point Rounding Mode ++#define CSR_VCSR 0x00F // Vector control and status register ++#define CSR_VL 0xC20 // Vector length ++#define CSR_VTYPE 0xC21 // Vector data type register ++#define CSR_VLENB 0xC22 // VLEN/8 (vector register length in bytes) ++#define CSR_CYCLE 0xc00 // Cycle counter for RDCYCLE instruction. ++#define CSR_TIME 0xc01 // Timer for RDTIME instruction. ++#define CSR_INSTRET 0xc02 // Instructions-retired counter for RDINSTRET instruction. ++ ++class VMRegImpl; ++typedef VMRegImpl* VMReg; ++ ++// Use Register as shortcut ++class RegisterImpl; ++typedef RegisterImpl* Register; ++ ++inline Register as_Register(int encoding) { ++ return (Register)(intptr_t) encoding; ++} ++ ++class RegisterImpl: public AbstractRegisterImpl { ++ ++ public: ++ enum { ++ number_of_registers = 32, ++ max_slots_per_register = 2, ++ ++ // integer registers x8 - x15 and floating-point registers f8 - f15 are allocatable ++ // for compressed instructions. See Table 17.2 in spec. ++ compressed_register_base = 8, ++ compressed_register_top = 15, ++ }; ++ ++ // derived registers, offsets, and addresses ++ Register successor() const { return as_Register(encoding() + 1); } ++ ++ // construction ++ inline friend Register as_Register(int encoding); ++ ++ VMReg as_VMReg(); ++ ++ // accessors ++ int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); } ++ bool is_valid() const { return 0 <= encoding_nocheck() && encoding_nocheck() < number_of_registers; } ++ const char* name() const; ++ int encoding_nocheck() const { return (intptr_t)this; } ++ ++ // Return the bit which represents this register. This is intended ++ // to be ORed into a bitmask: for usage see class AbstractRegSet below. ++ unsigned long bit(bool should_set = true) const { return should_set ? 1 << encoding() : 0; } ++ ++ // for rvc ++ int compressed_encoding() const { ++ assert(is_compressed_valid(), "invalid compressed register"); ++ return encoding() - compressed_register_base; ++ } ++ ++ int compressed_encoding_nocheck() const { ++ return encoding_nocheck() - compressed_register_base; ++ } ++ ++ bool is_compressed_valid() const { ++ return encoding_nocheck() >= compressed_register_base && ++ encoding_nocheck() <= compressed_register_top; ++ } ++}; ++ ++// The integer registers of the RISCV architecture ++ ++CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); ++ ++CONSTANT_REGISTER_DECLARATION(Register, x0, (0)); ++CONSTANT_REGISTER_DECLARATION(Register, x1, (1)); ++CONSTANT_REGISTER_DECLARATION(Register, x2, (2)); ++CONSTANT_REGISTER_DECLARATION(Register, x3, (3)); ++CONSTANT_REGISTER_DECLARATION(Register, x4, (4)); ++CONSTANT_REGISTER_DECLARATION(Register, x5, (5)); ++CONSTANT_REGISTER_DECLARATION(Register, x6, (6)); ++CONSTANT_REGISTER_DECLARATION(Register, x7, (7)); ++CONSTANT_REGISTER_DECLARATION(Register, x8, (8)); ++CONSTANT_REGISTER_DECLARATION(Register, x9, (9)); ++CONSTANT_REGISTER_DECLARATION(Register, x10, (10)); ++CONSTANT_REGISTER_DECLARATION(Register, x11, (11)); ++CONSTANT_REGISTER_DECLARATION(Register, x12, (12)); ++CONSTANT_REGISTER_DECLARATION(Register, x13, (13)); ++CONSTANT_REGISTER_DECLARATION(Register, x14, (14)); ++CONSTANT_REGISTER_DECLARATION(Register, x15, (15)); ++CONSTANT_REGISTER_DECLARATION(Register, x16, (16)); ++CONSTANT_REGISTER_DECLARATION(Register, x17, (17)); ++CONSTANT_REGISTER_DECLARATION(Register, x18, (18)); ++CONSTANT_REGISTER_DECLARATION(Register, x19, (19)); ++CONSTANT_REGISTER_DECLARATION(Register, x20, (20)); ++CONSTANT_REGISTER_DECLARATION(Register, x21, (21)); ++CONSTANT_REGISTER_DECLARATION(Register, x22, (22)); ++CONSTANT_REGISTER_DECLARATION(Register, x23, (23)); ++CONSTANT_REGISTER_DECLARATION(Register, x24, (24)); ++CONSTANT_REGISTER_DECLARATION(Register, x25, (25)); ++CONSTANT_REGISTER_DECLARATION(Register, x26, (26)); ++CONSTANT_REGISTER_DECLARATION(Register, x27, (27)); ++CONSTANT_REGISTER_DECLARATION(Register, x28, (28)); ++CONSTANT_REGISTER_DECLARATION(Register, x29, (29)); ++CONSTANT_REGISTER_DECLARATION(Register, x30, (30)); ++CONSTANT_REGISTER_DECLARATION(Register, x31, (31)); ++ ++// Use FloatRegister as shortcut ++class FloatRegisterImpl; ++typedef FloatRegisterImpl* FloatRegister; ++ ++inline FloatRegister as_FloatRegister(int encoding) { ++ return (FloatRegister)(intptr_t) encoding; ++} ++ ++// The implementation of floating point registers for the architecture ++class FloatRegisterImpl: public AbstractRegisterImpl { ++ ++ public: ++ enum { ++ number_of_registers = 32, ++ max_slots_per_register = 2, ++ ++ // float registers in the range of [f8~f15] correspond to RVC. Please see Table 16.2 in spec. ++ compressed_register_base = 8, ++ compressed_register_top = 15, ++ }; ++ ++ // construction ++ inline friend FloatRegister as_FloatRegister(int encoding); ++ ++ VMReg as_VMReg(); ++ ++ // derived registers, offsets, and addresses ++ FloatRegister successor() const { ++ return as_FloatRegister((encoding() + 1)); ++ } ++ ++ // accessors ++ int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); } ++ int encoding_nocheck() const { return (intptr_t)this; } ++ int is_valid() const { return 0 <= encoding_nocheck() && encoding_nocheck() < number_of_registers; } ++ const char* name() const; ++ ++ // for rvc ++ int compressed_encoding() const { ++ assert(is_compressed_valid(), "invalid compressed register"); ++ return encoding() - compressed_register_base; ++ } ++ ++ int compressed_encoding_nocheck() const { ++ return encoding_nocheck() - compressed_register_base; ++ } ++ ++ bool is_compressed_valid() const { ++ return encoding_nocheck() >= compressed_register_base && ++ encoding_nocheck() <= compressed_register_top; ++ } ++}; ++ ++// The float registers of the RISCV architecture ++ ++CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1)); ++ ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f0 , ( 0)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f1 , ( 1)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f2 , ( 2)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f3 , ( 3)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f4 , ( 4)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f5 , ( 5)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f6 , ( 6)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f7 , ( 7)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f8 , ( 8)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f9 , ( 9)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f10 , (10)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f11 , (11)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f12 , (12)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f13 , (13)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f14 , (14)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f15 , (15)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f16 , (16)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f17 , (17)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f18 , (18)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f19 , (19)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f20 , (20)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f21 , (21)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f22 , (22)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f23 , (23)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f24 , (24)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f25 , (25)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f26 , (26)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f27 , (27)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f28 , (28)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f29 , (29)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f30 , (30)); ++CONSTANT_REGISTER_DECLARATION(FloatRegister, f31 , (31)); ++ ++// Use VectorRegister as shortcut ++class VectorRegisterImpl; ++typedef VectorRegisterImpl* VectorRegister; ++ ++inline VectorRegister as_VectorRegister(int encoding) { ++ return (VectorRegister)(intptr_t) encoding; ++} ++ ++// The implementation of vector registers for RVV ++class VectorRegisterImpl: public AbstractRegisterImpl { ++ ++ public: ++ enum { ++ number_of_registers = 32, ++ max_slots_per_register = 4 ++ }; ++ ++ // construction ++ inline friend VectorRegister as_VectorRegister(int encoding); ++ ++ VMReg as_VMReg(); ++ ++ // derived registers, offsets, and addresses ++ VectorRegister successor() const { return as_VectorRegister(encoding() + 1); } ++ ++ // accessors ++ int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); } ++ int encoding_nocheck() const { return (intptr_t)this; } ++ bool is_valid() const { return 0 <= encoding_nocheck() && encoding_nocheck() < number_of_registers; } ++ const char* name() const; ++ ++}; ++ ++// The vector registers of RVV ++CONSTANT_REGISTER_DECLARATION(VectorRegister, vnoreg , (-1)); ++ ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v0 , ( 0)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v1 , ( 1)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v2 , ( 2)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v3 , ( 3)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v4 , ( 4)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v5 , ( 5)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v6 , ( 6)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v7 , ( 7)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v8 , ( 8)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v9 , ( 9)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v10 , (10)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v11 , (11)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v12 , (12)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v13 , (13)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v14 , (14)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v15 , (15)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v16 , (16)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v17 , (17)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v18 , (18)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v19 , (19)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v20 , (20)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v21 , (21)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v22 , (22)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v23 , (23)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v24 , (24)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v25 , (25)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v26 , (26)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v27 , (27)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v28 , (28)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v29 , (29)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v30 , (30)); ++CONSTANT_REGISTER_DECLARATION(VectorRegister, v31 , (31)); ++ ++ ++// Need to know the total number of registers of all sorts for SharedInfo. ++// Define a class that exports it. ++class ConcreteRegisterImpl : public AbstractRegisterImpl { ++ public: ++ enum { ++ // A big enough number for C2: all the registers plus flags ++ // This number must be large enough to cover REG_COUNT (defined by c2) registers. ++ // There is no requirement that any ordering here matches any ordering c2 gives ++ // it's optoregs. ++ ++ number_of_registers = (RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers + ++ FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers + ++ VectorRegisterImpl::max_slots_per_register * VectorRegisterImpl::number_of_registers) ++ }; ++ ++ // added to make it compile ++ static const int max_gpr; ++ static const int max_fpr; ++ static const int max_vpr; ++}; ++ ++// A set of registers ++template ++class AbstractRegSet { ++ uint32_t _bitset; ++ ++ AbstractRegSet(uint32_t bitset) : _bitset(bitset) { } ++ ++ public: ++ AbstractRegSet() : _bitset(0) { } ++ ++ AbstractRegSet(RegImpl r1) : _bitset(1 << r1->encoding()) { } ++ ++ AbstractRegSet operator+(const AbstractRegSet aSet) const { ++ AbstractRegSet result(_bitset | aSet._bitset); ++ return result; ++ } ++ ++ AbstractRegSet operator-(const AbstractRegSet aSet) const { ++ AbstractRegSet result(_bitset & ~aSet._bitset); ++ return result; ++ } ++ ++ AbstractRegSet &operator+=(const AbstractRegSet aSet) { ++ *this = *this + aSet; ++ return *this; ++ } ++ ++ AbstractRegSet &operator-=(const AbstractRegSet aSet) { ++ *this = *this - aSet; ++ return *this; ++ } ++ ++ static AbstractRegSet of(RegImpl r1) { ++ return AbstractRegSet(r1); ++ } ++ ++ static AbstractRegSet of(RegImpl r1, RegImpl r2) { ++ return of(r1) + r2; ++ } ++ ++ static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3) { ++ return of(r1, r2) + r3; ++ } ++ ++ static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3, RegImpl r4) { ++ return of(r1, r2, r3) + r4; ++ } ++ ++ static AbstractRegSet range(RegImpl start, RegImpl end) { ++ uint32_t bits = ~0; ++ bits <<= start->encoding(); ++ bits <<= (31 - end->encoding()); ++ bits >>= (31 - end->encoding()); ++ ++ return AbstractRegSet(bits); ++ } ++ ++ uint32_t bits() const { return _bitset; } ++}; ++ ++typedef AbstractRegSet RegSet; ++typedef AbstractRegSet FloatRegSet; ++typedef AbstractRegSet VectorRegSet; ++ ++#endif // CPU_RISCV_REGISTER_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/relocInfo_riscv.cpp +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "code/relocInfo.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/oop.inline.hpp" ++#include "runtime/safepoint.hpp" ++ ++void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) { ++ if (verify_only) { ++ return; ++ } ++ ++ int bytes; ++ ++ switch (type()) { ++ case relocInfo::oop_type: { ++ oop_Relocation *reloc = (oop_Relocation *)this; ++ // in movoop when BarrierSet::barrier_set()->barrier_set_nmethod() != NULL || !immediate ++ if (NativeInstruction::is_load_pc_relative_at(addr())) { ++ address constptr = (address)code()->oop_addr_at(reloc->oop_index()); ++ bytes = MacroAssembler::pd_patch_instruction_size(addr(), constptr); ++ assert(*(address*)constptr == x, "error in oop relocation"); ++ } else { ++ bytes = MacroAssembler::patch_oop(addr(), x); ++ } ++ break; ++ } ++ default: ++ bytes = MacroAssembler::pd_patch_instruction_size(addr(), x); ++ break; ++ } ++ ICache::invalidate_range(addr(), bytes); ++} ++ ++address Relocation::pd_call_destination(address orig_addr) { ++ assert(is_call(), "should be an address instruction here"); ++ if (NativeCall::is_call_at(addr())) { ++ address trampoline = nativeCall_at(addr())->get_trampoline(); ++ if (trampoline != NULL) { ++ return nativeCallTrampolineStub_at(trampoline)->destination(); ++ } ++ } ++ if (orig_addr != NULL) { ++ // the extracted address from the instructions in address orig_addr ++ address new_addr = MacroAssembler::pd_call_destination(orig_addr); ++ // If call is branch to self, don't try to relocate it, just leave it ++ // as branch to self. This happens during code generation if the code ++ // buffer expands. It will be relocated to the trampoline above once ++ // code generation is complete. ++ new_addr = (new_addr == orig_addr) ? addr() : new_addr; ++ return new_addr; ++ } ++ return MacroAssembler::pd_call_destination(addr()); ++} ++ ++void Relocation::pd_set_call_destination(address x) { ++ assert(is_call(), "should be an address instruction here"); ++ if (NativeCall::is_call_at(addr())) { ++ address trampoline = nativeCall_at(addr())->get_trampoline(); ++ if (trampoline != NULL) { ++ nativeCall_at(addr())->set_destination_mt_safe(x, /* assert_lock */false); ++ return; ++ } ++ } ++ MacroAssembler::pd_patch_instruction_size(addr(), x); ++ address pd_call = pd_call_destination(addr()); ++ assert(pd_call == x, "fail in reloc"); ++} ++ ++address* Relocation::pd_address_in_code() { ++ assert(NativeCall::is_load_pc_relative_at(addr()), "Not the expected instruction sequence!"); ++ return (address*)(MacroAssembler::target_addr_for_insn(addr())); ++} ++ ++address Relocation::pd_get_address_from_code() { ++ return MacroAssembler::pd_call_destination(addr()); ++} ++ ++void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { ++ if (NativeInstruction::maybe_cpool_ref(addr())) { ++ address old_addr = old_addr_for(addr(), src, dest); ++ MacroAssembler::pd_patch_instruction_size(addr(), MacroAssembler::target_addr_for_insn(old_addr)); ++ } ++} ++ ++void metadata_Relocation::pd_fix_value(address x) { ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/relocInfo_riscv.hpp +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 1997, 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_RELOCINFO_RISCV_HPP ++#define CPU_RISCV_RELOCINFO_RISCV_HPP ++ ++ // machine-dependent parts of class relocInfo ++ private: ++ enum { ++ // Relocations are byte-aligned. ++ offset_unit = 1, ++ // Must be at least 1 for RelocInfo::narrow_oop_in_const. ++ format_width = 1 ++ }; ++ ++ public: ++ ++ // This platform has no oops in the code that are not also ++ // listed in the oop section. ++ static bool mustIterateImmediateOopsInCode() { return false; } ++ ++#endif // CPU_RISCV_RELOCINFO_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/riscv.ad +@@ -0,0 +1,10645 @@ ++// ++// Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++// Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++// Copyright (c) 2020, 2022, 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. ++// ++// ++ ++// RISCV Architecture Description File ++ ++//----------REGISTER DEFINITION BLOCK------------------------------------------ ++// This information is used by the matcher and the register allocator to ++// describe individual registers and classes of registers within the target ++// archtecture. ++ ++register %{ ++//----------Architecture Description Register Definitions---------------------- ++// General Registers ++// "reg_def" name ( register save type, C convention save type, ++// ideal register type, encoding ); ++// Register Save Types: ++// ++// NS = No-Save: The register allocator assumes that these registers ++// can be used without saving upon entry to the method, & ++// that they do not need to be saved at call sites. ++// ++// SOC = Save-On-Call: The register allocator assumes that these registers ++// can be used without saving upon entry to the method, ++// but that they must be saved at call sites. ++// ++// SOE = Save-On-Entry: The register allocator assumes that these registers ++// must be saved before using them upon entry to the ++// method, but they do not need to be saved at call ++// sites. ++// ++// AS = Always-Save: The register allocator assumes that these registers ++// must be saved before using them upon entry to the ++// method, & that they must be saved at call sites. ++// ++// Ideal Register Type is used to determine how to save & restore a ++// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get ++// spilled with LoadP/StoreP. If the register supports both, use Op_RegI. ++// ++// The encoding number is the actual bit-pattern placed into the opcodes. ++ ++// We must define the 64 bit int registers in two 32 bit halves, the ++// real lower register and a virtual upper half register. upper halves ++// are used by the register allocator but are not actually supplied as ++// operands to memory ops. ++// ++// follow the C1 compiler in making registers ++// ++// x7, x9-x17, x27-x31 volatile (caller save) ++// x0-x4, x8, x23 system (no save, no allocate) ++// x5-x6 non-allocatable (so we can use them as temporary regs) ++ ++// ++// as regards Java usage. we don't use any callee save registers ++// because this makes it difficult to de-optimise a frame (see comment ++// in x86 implementation of Deoptimization::unwind_callee_save_values) ++// ++ ++// General Registers ++ ++reg_def R0 ( NS, NS, Op_RegI, 0, x0->as_VMReg() ); // zr ++reg_def R0_H ( NS, NS, Op_RegI, 0, x0->as_VMReg()->next() ); ++reg_def R1 ( NS, SOC, Op_RegI, 1, x1->as_VMReg() ); // ra ++reg_def R1_H ( NS, SOC, Op_RegI, 1, x1->as_VMReg()->next() ); ++reg_def R2 ( NS, SOE, Op_RegI, 2, x2->as_VMReg() ); // sp ++reg_def R2_H ( NS, SOE, Op_RegI, 2, x2->as_VMReg()->next() ); ++reg_def R3 ( NS, NS, Op_RegI, 3, x3->as_VMReg() ); // gp ++reg_def R3_H ( NS, NS, Op_RegI, 3, x3->as_VMReg()->next() ); ++reg_def R4 ( NS, NS, Op_RegI, 4, x4->as_VMReg() ); // tp ++reg_def R4_H ( NS, NS, Op_RegI, 4, x4->as_VMReg()->next() ); ++reg_def R7 ( SOC, SOC, Op_RegI, 7, x7->as_VMReg() ); ++reg_def R7_H ( SOC, SOC, Op_RegI, 7, x7->as_VMReg()->next() ); ++reg_def R8 ( NS, SOE, Op_RegI, 8, x8->as_VMReg() ); // fp ++reg_def R8_H ( NS, SOE, Op_RegI, 8, x8->as_VMReg()->next() ); ++reg_def R9 ( SOC, SOE, Op_RegI, 9, x9->as_VMReg() ); ++reg_def R9_H ( SOC, SOE, Op_RegI, 9, x9->as_VMReg()->next() ); ++reg_def R10 ( SOC, SOC, Op_RegI, 10, x10->as_VMReg() ); ++reg_def R10_H ( SOC, SOC, Op_RegI, 10, x10->as_VMReg()->next()); ++reg_def R11 ( SOC, SOC, Op_RegI, 11, x11->as_VMReg() ); ++reg_def R11_H ( SOC, SOC, Op_RegI, 11, x11->as_VMReg()->next()); ++reg_def R12 ( SOC, SOC, Op_RegI, 12, x12->as_VMReg() ); ++reg_def R12_H ( SOC, SOC, Op_RegI, 12, x12->as_VMReg()->next()); ++reg_def R13 ( SOC, SOC, Op_RegI, 13, x13->as_VMReg() ); ++reg_def R13_H ( SOC, SOC, Op_RegI, 13, x13->as_VMReg()->next()); ++reg_def R14 ( SOC, SOC, Op_RegI, 14, x14->as_VMReg() ); ++reg_def R14_H ( SOC, SOC, Op_RegI, 14, x14->as_VMReg()->next()); ++reg_def R15 ( SOC, SOC, Op_RegI, 15, x15->as_VMReg() ); ++reg_def R15_H ( SOC, SOC, Op_RegI, 15, x15->as_VMReg()->next()); ++reg_def R16 ( SOC, SOC, Op_RegI, 16, x16->as_VMReg() ); ++reg_def R16_H ( SOC, SOC, Op_RegI, 16, x16->as_VMReg()->next()); ++reg_def R17 ( SOC, SOC, Op_RegI, 17, x17->as_VMReg() ); ++reg_def R17_H ( SOC, SOC, Op_RegI, 17, x17->as_VMReg()->next()); ++reg_def R18 ( SOC, SOE, Op_RegI, 18, x18->as_VMReg() ); ++reg_def R18_H ( SOC, SOE, Op_RegI, 18, x18->as_VMReg()->next()); ++reg_def R19 ( SOC, SOE, Op_RegI, 19, x19->as_VMReg() ); ++reg_def R19_H ( SOC, SOE, Op_RegI, 19, x19->as_VMReg()->next()); ++reg_def R20 ( SOC, SOE, Op_RegI, 20, x20->as_VMReg() ); // caller esp ++reg_def R20_H ( SOC, SOE, Op_RegI, 20, x20->as_VMReg()->next()); ++reg_def R21 ( SOC, SOE, Op_RegI, 21, x21->as_VMReg() ); ++reg_def R21_H ( SOC, SOE, Op_RegI, 21, x21->as_VMReg()->next()); ++reg_def R22 ( SOC, SOE, Op_RegI, 22, x22->as_VMReg() ); ++reg_def R22_H ( SOC, SOE, Op_RegI, 22, x22->as_VMReg()->next()); ++reg_def R23 ( NS, SOE, Op_RegI, 23, x23->as_VMReg() ); // java thread ++reg_def R23_H ( NS, SOE, Op_RegI, 23, x23->as_VMReg()->next()); ++reg_def R24 ( SOC, SOE, Op_RegI, 24, x24->as_VMReg() ); ++reg_def R24_H ( SOC, SOE, Op_RegI, 24, x24->as_VMReg()->next()); ++reg_def R25 ( SOC, SOE, Op_RegI, 25, x25->as_VMReg() ); ++reg_def R25_H ( SOC, SOE, Op_RegI, 25, x25->as_VMReg()->next()); ++reg_def R26 ( SOC, SOE, Op_RegI, 26, x26->as_VMReg() ); ++reg_def R26_H ( SOC, SOE, Op_RegI, 26, x26->as_VMReg()->next()); ++reg_def R27 ( SOC, SOE, Op_RegI, 27, x27->as_VMReg() ); // heapbase ++reg_def R27_H ( SOC, SOE, Op_RegI, 27, x27->as_VMReg()->next()); ++reg_def R28 ( SOC, SOC, Op_RegI, 28, x28->as_VMReg() ); ++reg_def R28_H ( SOC, SOC, Op_RegI, 28, x28->as_VMReg()->next()); ++reg_def R29 ( SOC, SOC, Op_RegI, 29, x29->as_VMReg() ); ++reg_def R29_H ( SOC, SOC, Op_RegI, 29, x29->as_VMReg()->next()); ++reg_def R30 ( SOC, SOC, Op_RegI, 30, x30->as_VMReg() ); ++reg_def R30_H ( SOC, SOC, Op_RegI, 30, x30->as_VMReg()->next()); ++reg_def R31 ( SOC, SOC, Op_RegI, 31, x31->as_VMReg() ); ++reg_def R31_H ( SOC, SOC, Op_RegI, 31, x31->as_VMReg()->next()); ++ ++// ---------------------------- ++// Float/Double Registers ++// ---------------------------- ++ ++// Double Registers ++ ++// The rules of ADL require that double registers be defined in pairs. ++// Each pair must be two 32-bit values, but not necessarily a pair of ++// single float registers. In each pair, ADLC-assigned register numbers ++// must be adjacent, with the lower number even. Finally, when the ++// CPU stores such a register pair to memory, the word associated with ++// the lower ADLC-assigned number must be stored to the lower address. ++ ++// RISCV has 32 floating-point registers. Each can store a single ++// or double precision floating-point value. ++ ++// for Java use float registers f0-f31 are always save on call whereas ++// the platform ABI treats f8-f9 and f18-f27 as callee save). Other ++// float registers are SOC as per the platform spec ++ ++reg_def F0 ( SOC, SOC, Op_RegF, 0, f0->as_VMReg() ); ++reg_def F0_H ( SOC, SOC, Op_RegF, 0, f0->as_VMReg()->next() ); ++reg_def F1 ( SOC, SOC, Op_RegF, 1, f1->as_VMReg() ); ++reg_def F1_H ( SOC, SOC, Op_RegF, 1, f1->as_VMReg()->next() ); ++reg_def F2 ( SOC, SOC, Op_RegF, 2, f2->as_VMReg() ); ++reg_def F2_H ( SOC, SOC, Op_RegF, 2, f2->as_VMReg()->next() ); ++reg_def F3 ( SOC, SOC, Op_RegF, 3, f3->as_VMReg() ); ++reg_def F3_H ( SOC, SOC, Op_RegF, 3, f3->as_VMReg()->next() ); ++reg_def F4 ( SOC, SOC, Op_RegF, 4, f4->as_VMReg() ); ++reg_def F4_H ( SOC, SOC, Op_RegF, 4, f4->as_VMReg()->next() ); ++reg_def F5 ( SOC, SOC, Op_RegF, 5, f5->as_VMReg() ); ++reg_def F5_H ( SOC, SOC, Op_RegF, 5, f5->as_VMReg()->next() ); ++reg_def F6 ( SOC, SOC, Op_RegF, 6, f6->as_VMReg() ); ++reg_def F6_H ( SOC, SOC, Op_RegF, 6, f6->as_VMReg()->next() ); ++reg_def F7 ( SOC, SOC, Op_RegF, 7, f7->as_VMReg() ); ++reg_def F7_H ( SOC, SOC, Op_RegF, 7, f7->as_VMReg()->next() ); ++reg_def F8 ( SOC, SOE, Op_RegF, 8, f8->as_VMReg() ); ++reg_def F8_H ( SOC, SOE, Op_RegF, 8, f8->as_VMReg()->next() ); ++reg_def F9 ( SOC, SOE, Op_RegF, 9, f9->as_VMReg() ); ++reg_def F9_H ( SOC, SOE, Op_RegF, 9, f9->as_VMReg()->next() ); ++reg_def F10 ( SOC, SOC, Op_RegF, 10, f10->as_VMReg() ); ++reg_def F10_H ( SOC, SOC, Op_RegF, 10, f10->as_VMReg()->next() ); ++reg_def F11 ( SOC, SOC, Op_RegF, 11, f11->as_VMReg() ); ++reg_def F11_H ( SOC, SOC, Op_RegF, 11, f11->as_VMReg()->next() ); ++reg_def F12 ( SOC, SOC, Op_RegF, 12, f12->as_VMReg() ); ++reg_def F12_H ( SOC, SOC, Op_RegF, 12, f12->as_VMReg()->next() ); ++reg_def F13 ( SOC, SOC, Op_RegF, 13, f13->as_VMReg() ); ++reg_def F13_H ( SOC, SOC, Op_RegF, 13, f13->as_VMReg()->next() ); ++reg_def F14 ( SOC, SOC, Op_RegF, 14, f14->as_VMReg() ); ++reg_def F14_H ( SOC, SOC, Op_RegF, 14, f14->as_VMReg()->next() ); ++reg_def F15 ( SOC, SOC, Op_RegF, 15, f15->as_VMReg() ); ++reg_def F15_H ( SOC, SOC, Op_RegF, 15, f15->as_VMReg()->next() ); ++reg_def F16 ( SOC, SOC, Op_RegF, 16, f16->as_VMReg() ); ++reg_def F16_H ( SOC, SOC, Op_RegF, 16, f16->as_VMReg()->next() ); ++reg_def F17 ( SOC, SOC, Op_RegF, 17, f17->as_VMReg() ); ++reg_def F17_H ( SOC, SOC, Op_RegF, 17, f17->as_VMReg()->next() ); ++reg_def F18 ( SOC, SOE, Op_RegF, 18, f18->as_VMReg() ); ++reg_def F18_H ( SOC, SOE, Op_RegF, 18, f18->as_VMReg()->next() ); ++reg_def F19 ( SOC, SOE, Op_RegF, 19, f19->as_VMReg() ); ++reg_def F19_H ( SOC, SOE, Op_RegF, 19, f19->as_VMReg()->next() ); ++reg_def F20 ( SOC, SOE, Op_RegF, 20, f20->as_VMReg() ); ++reg_def F20_H ( SOC, SOE, Op_RegF, 20, f20->as_VMReg()->next() ); ++reg_def F21 ( SOC, SOE, Op_RegF, 21, f21->as_VMReg() ); ++reg_def F21_H ( SOC, SOE, Op_RegF, 21, f21->as_VMReg()->next() ); ++reg_def F22 ( SOC, SOE, Op_RegF, 22, f22->as_VMReg() ); ++reg_def F22_H ( SOC, SOE, Op_RegF, 22, f22->as_VMReg()->next() ); ++reg_def F23 ( SOC, SOE, Op_RegF, 23, f23->as_VMReg() ); ++reg_def F23_H ( SOC, SOE, Op_RegF, 23, f23->as_VMReg()->next() ); ++reg_def F24 ( SOC, SOE, Op_RegF, 24, f24->as_VMReg() ); ++reg_def F24_H ( SOC, SOE, Op_RegF, 24, f24->as_VMReg()->next() ); ++reg_def F25 ( SOC, SOE, Op_RegF, 25, f25->as_VMReg() ); ++reg_def F25_H ( SOC, SOE, Op_RegF, 25, f25->as_VMReg()->next() ); ++reg_def F26 ( SOC, SOE, Op_RegF, 26, f26->as_VMReg() ); ++reg_def F26_H ( SOC, SOE, Op_RegF, 26, f26->as_VMReg()->next() ); ++reg_def F27 ( SOC, SOE, Op_RegF, 27, f27->as_VMReg() ); ++reg_def F27_H ( SOC, SOE, Op_RegF, 27, f27->as_VMReg()->next() ); ++reg_def F28 ( SOC, SOC, Op_RegF, 28, f28->as_VMReg() ); ++reg_def F28_H ( SOC, SOC, Op_RegF, 28, f28->as_VMReg()->next() ); ++reg_def F29 ( SOC, SOC, Op_RegF, 29, f29->as_VMReg() ); ++reg_def F29_H ( SOC, SOC, Op_RegF, 29, f29->as_VMReg()->next() ); ++reg_def F30 ( SOC, SOC, Op_RegF, 30, f30->as_VMReg() ); ++reg_def F30_H ( SOC, SOC, Op_RegF, 30, f30->as_VMReg()->next() ); ++reg_def F31 ( SOC, SOC, Op_RegF, 31, f31->as_VMReg() ); ++reg_def F31_H ( SOC, SOC, Op_RegF, 31, f31->as_VMReg()->next() ); ++ ++// ---------------------------- ++// Vector Registers ++// ---------------------------- ++ ++// For RVV vector registers, we simply extend vector register size to 4 ++// 'logical' slots. This is nominally 128 bits but it actually covers ++// all possible 'physical' RVV vector register lengths from 128 ~ 1024 ++// bits. The 'physical' RVV vector register length is detected during ++// startup, so the register allocator is able to identify the correct ++// number of bytes needed for an RVV spill/unspill. ++ ++reg_def V0 ( SOC, SOC, Op_VecA, 0, v0->as_VMReg() ); ++reg_def V0_H ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next() ); ++reg_def V0_J ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next(2) ); ++reg_def V0_K ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next(3) ); ++ ++reg_def V1 ( SOC, SOC, Op_VecA, 1, v1->as_VMReg() ); ++reg_def V1_H ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next() ); ++reg_def V1_J ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next(2) ); ++reg_def V1_K ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next(3) ); ++ ++reg_def V2 ( SOC, SOC, Op_VecA, 2, v2->as_VMReg() ); ++reg_def V2_H ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next() ); ++reg_def V2_J ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next(2) ); ++reg_def V2_K ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next(3) ); ++ ++reg_def V3 ( SOC, SOC, Op_VecA, 3, v3->as_VMReg() ); ++reg_def V3_H ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next() ); ++reg_def V3_J ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next(2) ); ++reg_def V3_K ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next(3) ); ++ ++reg_def V4 ( SOC, SOC, Op_VecA, 4, v4->as_VMReg() ); ++reg_def V4_H ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next() ); ++reg_def V4_J ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next(2) ); ++reg_def V4_K ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next(3) ); ++ ++reg_def V5 ( SOC, SOC, Op_VecA, 5, v5->as_VMReg() ); ++reg_def V5_H ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next() ); ++reg_def V5_J ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next(2) ); ++reg_def V5_K ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next(3) ); ++ ++reg_def V6 ( SOC, SOC, Op_VecA, 6, v6->as_VMReg() ); ++reg_def V6_H ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next() ); ++reg_def V6_J ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next(2) ); ++reg_def V6_K ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next(3) ); ++ ++reg_def V7 ( SOC, SOC, Op_VecA, 7, v7->as_VMReg() ); ++reg_def V7_H ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next() ); ++reg_def V7_J ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next(2) ); ++reg_def V7_K ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next(3) ); ++ ++reg_def V8 ( SOC, SOC, Op_VecA, 8, v8->as_VMReg() ); ++reg_def V8_H ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next() ); ++reg_def V8_J ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next(2) ); ++reg_def V8_K ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next(3) ); ++ ++reg_def V9 ( SOC, SOC, Op_VecA, 9, v9->as_VMReg() ); ++reg_def V9_H ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next() ); ++reg_def V9_J ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next(2) ); ++reg_def V9_K ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next(3) ); ++ ++reg_def V10 ( SOC, SOC, Op_VecA, 10, v10->as_VMReg() ); ++reg_def V10_H ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next() ); ++reg_def V10_J ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(2) ); ++reg_def V10_K ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(3) ); ++ ++reg_def V11 ( SOC, SOC, Op_VecA, 11, v11->as_VMReg() ); ++reg_def V11_H ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next() ); ++reg_def V11_J ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(2) ); ++reg_def V11_K ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(3) ); ++ ++reg_def V12 ( SOC, SOC, Op_VecA, 12, v12->as_VMReg() ); ++reg_def V12_H ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next() ); ++reg_def V12_J ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(2) ); ++reg_def V12_K ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(3) ); ++ ++reg_def V13 ( SOC, SOC, Op_VecA, 13, v13->as_VMReg() ); ++reg_def V13_H ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next() ); ++reg_def V13_J ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(2) ); ++reg_def V13_K ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(3) ); ++ ++reg_def V14 ( SOC, SOC, Op_VecA, 14, v14->as_VMReg() ); ++reg_def V14_H ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next() ); ++reg_def V14_J ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(2) ); ++reg_def V14_K ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(3) ); ++ ++reg_def V15 ( SOC, SOC, Op_VecA, 15, v15->as_VMReg() ); ++reg_def V15_H ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next() ); ++reg_def V15_J ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(2) ); ++reg_def V15_K ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(3) ); ++ ++reg_def V16 ( SOC, SOC, Op_VecA, 16, v16->as_VMReg() ); ++reg_def V16_H ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next() ); ++reg_def V16_J ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(2) ); ++reg_def V16_K ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(3) ); ++ ++reg_def V17 ( SOC, SOC, Op_VecA, 17, v17->as_VMReg() ); ++reg_def V17_H ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next() ); ++reg_def V17_J ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(2) ); ++reg_def V17_K ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(3) ); ++ ++reg_def V18 ( SOC, SOC, Op_VecA, 18, v18->as_VMReg() ); ++reg_def V18_H ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next() ); ++reg_def V18_J ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(2) ); ++reg_def V18_K ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(3) ); ++ ++reg_def V19 ( SOC, SOC, Op_VecA, 19, v19->as_VMReg() ); ++reg_def V19_H ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next() ); ++reg_def V19_J ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(2) ); ++reg_def V19_K ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(3) ); ++ ++reg_def V20 ( SOC, SOC, Op_VecA, 20, v20->as_VMReg() ); ++reg_def V20_H ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next() ); ++reg_def V20_J ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(2) ); ++reg_def V20_K ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(3) ); ++ ++reg_def V21 ( SOC, SOC, Op_VecA, 21, v21->as_VMReg() ); ++reg_def V21_H ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next() ); ++reg_def V21_J ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(2) ); ++reg_def V21_K ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(3) ); ++ ++reg_def V22 ( SOC, SOC, Op_VecA, 22, v22->as_VMReg() ); ++reg_def V22_H ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next() ); ++reg_def V22_J ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(2) ); ++reg_def V22_K ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(3) ); ++ ++reg_def V23 ( SOC, SOC, Op_VecA, 23, v23->as_VMReg() ); ++reg_def V23_H ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next() ); ++reg_def V23_J ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(2) ); ++reg_def V23_K ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(3) ); ++ ++reg_def V24 ( SOC, SOC, Op_VecA, 24, v24->as_VMReg() ); ++reg_def V24_H ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next() ); ++reg_def V24_J ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(2) ); ++reg_def V24_K ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(3) ); ++ ++reg_def V25 ( SOC, SOC, Op_VecA, 25, v25->as_VMReg() ); ++reg_def V25_H ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next() ); ++reg_def V25_J ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(2) ); ++reg_def V25_K ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(3) ); ++ ++reg_def V26 ( SOC, SOC, Op_VecA, 26, v26->as_VMReg() ); ++reg_def V26_H ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next() ); ++reg_def V26_J ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(2) ); ++reg_def V26_K ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(3) ); ++ ++reg_def V27 ( SOC, SOC, Op_VecA, 27, v27->as_VMReg() ); ++reg_def V27_H ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next() ); ++reg_def V27_J ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(2) ); ++reg_def V27_K ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(3) ); ++ ++reg_def V28 ( SOC, SOC, Op_VecA, 28, v28->as_VMReg() ); ++reg_def V28_H ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next() ); ++reg_def V28_J ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(2) ); ++reg_def V28_K ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(3) ); ++ ++reg_def V29 ( SOC, SOC, Op_VecA, 29, v29->as_VMReg() ); ++reg_def V29_H ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next() ); ++reg_def V29_J ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(2) ); ++reg_def V29_K ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(3) ); ++ ++reg_def V30 ( SOC, SOC, Op_VecA, 30, v30->as_VMReg() ); ++reg_def V30_H ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next() ); ++reg_def V30_J ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(2) ); ++reg_def V30_K ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(3) ); ++ ++reg_def V31 ( SOC, SOC, Op_VecA, 31, v31->as_VMReg() ); ++reg_def V31_H ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next() ); ++reg_def V31_J ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(2) ); ++reg_def V31_K ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(3) ); ++ ++// ---------------------------- ++// Special Registers ++// ---------------------------- ++ ++// On riscv, the physical flag register is missing, so we use t1 instead, ++// to bridge the RegFlag semantics in share/opto ++ ++reg_def RFLAGS (SOC, SOC, Op_RegFlags, 6, x6->as_VMReg() ); ++ ++// Specify priority of register selection within phases of register ++// allocation. Highest priority is first. A useful heuristic is to ++// give registers a low priority when they are required by machine ++// instructions, like EAX and EDX on I486, and choose no-save registers ++// before save-on-call, & save-on-call before save-on-entry. Registers ++// which participate in fixed calling sequences should come last. ++// Registers which are used as pairs must fall on an even boundary. ++ ++alloc_class chunk0( ++ // volatiles ++ R7, R7_H, ++ R28, R28_H, ++ R29, R29_H, ++ R30, R30_H, ++ R31, R31_H, ++ ++ // arg registers ++ R10, R10_H, ++ R11, R11_H, ++ R12, R12_H, ++ R13, R13_H, ++ R14, R14_H, ++ R15, R15_H, ++ R16, R16_H, ++ R17, R17_H, ++ ++ // non-volatiles ++ R9, R9_H, ++ R18, R18_H, ++ R19, R19_H, ++ R20, R20_H, ++ R21, R21_H, ++ R22, R22_H, ++ R24, R24_H, ++ R25, R25_H, ++ R26, R26_H, ++ ++ // non-allocatable registers ++ R23, R23_H, // java thread ++ R27, R27_H, // heapbase ++ R4, R4_H, // thread ++ R8, R8_H, // fp ++ R0, R0_H, // zero ++ R1, R1_H, // ra ++ R2, R2_H, // sp ++ R3, R3_H, // gp ++); ++ ++alloc_class chunk1( ++ ++ // no save ++ F0, F0_H, ++ F1, F1_H, ++ F2, F2_H, ++ F3, F3_H, ++ F4, F4_H, ++ F5, F5_H, ++ F6, F6_H, ++ F7, F7_H, ++ F28, F28_H, ++ F29, F29_H, ++ F30, F30_H, ++ F31, F31_H, ++ ++ // arg registers ++ F10, F10_H, ++ F11, F11_H, ++ F12, F12_H, ++ F13, F13_H, ++ F14, F14_H, ++ F15, F15_H, ++ F16, F16_H, ++ F17, F17_H, ++ ++ // non-volatiles ++ F8, F8_H, ++ F9, F9_H, ++ F18, F18_H, ++ F19, F19_H, ++ F20, F20_H, ++ F21, F21_H, ++ F22, F22_H, ++ F23, F23_H, ++ F24, F24_H, ++ F25, F25_H, ++ F26, F26_H, ++ F27, F27_H, ++); ++ ++alloc_class chunk2( ++ V0, V0_H, V0_J, V0_K, ++ V1, V1_H, V1_J, V1_K, ++ V2, V2_H, V2_J, V2_K, ++ V3, V3_H, V3_J, V3_K, ++ V4, V4_H, V4_J, V4_K, ++ V5, V5_H, V5_J, V5_K, ++ V6, V6_H, V6_J, V6_K, ++ V7, V7_H, V7_J, V7_K, ++ V8, V8_H, V8_J, V8_K, ++ V9, V9_H, V9_J, V9_K, ++ V10, V10_H, V10_J, V10_K, ++ V11, V11_H, V11_J, V11_K, ++ V12, V12_H, V12_J, V12_K, ++ V13, V13_H, V13_J, V13_K, ++ V14, V14_H, V14_J, V14_K, ++ V15, V15_H, V15_J, V15_K, ++ V16, V16_H, V16_J, V16_K, ++ V17, V17_H, V17_J, V17_K, ++ V18, V18_H, V18_J, V18_K, ++ V19, V19_H, V19_J, V19_K, ++ V20, V20_H, V20_J, V20_K, ++ V21, V21_H, V21_J, V21_K, ++ V22, V22_H, V22_J, V22_K, ++ V23, V23_H, V23_J, V23_K, ++ V24, V24_H, V24_J, V24_K, ++ V25, V25_H, V25_J, V25_K, ++ V26, V26_H, V26_J, V26_K, ++ V27, V27_H, V27_J, V27_K, ++ V28, V28_H, V28_J, V28_K, ++ V29, V29_H, V29_J, V29_K, ++ V30, V30_H, V30_J, V30_K, ++ V31, V31_H, V31_J, V31_K, ++); ++ ++alloc_class chunk3(RFLAGS); ++ ++//----------Architecture Description Register Classes-------------------------- ++// Several register classes are automatically defined based upon information in ++// this architecture description. ++// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) ++// 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) ++// ++ ++// Class for all 32 bit general purpose registers ++reg_class all_reg32( ++ R0, ++ R1, ++ R2, ++ R3, ++ R4, ++ R7, ++ R8, ++ R9, ++ R10, ++ R11, ++ R12, ++ R13, ++ R14, ++ R15, ++ R16, ++ R17, ++ R18, ++ R19, ++ R20, ++ R21, ++ R22, ++ R23, ++ R24, ++ R25, ++ R26, ++ R27, ++ R28, ++ R29, ++ R30, ++ R31 ++); ++ ++// Class for any 32 bit integer registers (excluding zr) ++reg_class any_reg32 %{ ++ return _ANY_REG32_mask; ++%} ++ ++// Singleton class for R10 int register ++reg_class int_r10_reg(R10); ++ ++// Singleton class for R12 int register ++reg_class int_r12_reg(R12); ++ ++// Singleton class for R13 int register ++reg_class int_r13_reg(R13); ++ ++// Singleton class for R14 int register ++reg_class int_r14_reg(R14); ++ ++// Class for all long integer registers ++reg_class all_reg( ++ R0, R0_H, ++ R1, R1_H, ++ R2, R2_H, ++ R3, R3_H, ++ R4, R4_H, ++ R7, R7_H, ++ R8, R8_H, ++ R9, R9_H, ++ R10, R10_H, ++ R11, R11_H, ++ R12, R12_H, ++ R13, R13_H, ++ R14, R14_H, ++ R15, R15_H, ++ R16, R16_H, ++ R17, R17_H, ++ R18, R18_H, ++ R19, R19_H, ++ R20, R20_H, ++ R21, R21_H, ++ R22, R22_H, ++ R23, R23_H, ++ R24, R24_H, ++ R25, R25_H, ++ R26, R26_H, ++ R27, R27_H, ++ R28, R28_H, ++ R29, R29_H, ++ R30, R30_H, ++ R31, R31_H ++); ++ ++// Class for all long integer registers (excluding zr) ++reg_class any_reg %{ ++ return _ANY_REG_mask; ++%} ++ ++// Class for non-allocatable 32 bit registers ++reg_class non_allocatable_reg32( ++ R0, // zr ++ R1, // ra ++ R2, // sp ++ R3, // gp ++ R4, // tp ++ R23 // java thread ++); ++ ++// Class for non-allocatable 64 bit registers ++reg_class non_allocatable_reg( ++ R0, R0_H, // zr ++ R1, R1_H, // ra ++ R2, R2_H, // sp ++ R3, R3_H, // gp ++ R4, R4_H, // tp ++ R23, R23_H // java thread ++); ++ ++reg_class no_special_reg32 %{ ++ return _NO_SPECIAL_REG32_mask; ++%} ++ ++reg_class no_special_reg %{ ++ return _NO_SPECIAL_REG_mask; ++%} ++ ++reg_class ptr_reg %{ ++ return _PTR_REG_mask; ++%} ++ ++reg_class no_special_ptr_reg %{ ++ return _NO_SPECIAL_PTR_REG_mask; ++%} ++ ++// Class for 64 bit register r10 ++reg_class r10_reg( ++ R10, R10_H ++); ++ ++// Class for 64 bit register r11 ++reg_class r11_reg( ++ R11, R11_H ++); ++ ++// Class for 64 bit register r12 ++reg_class r12_reg( ++ R12, R12_H ++); ++ ++// Class for 64 bit register r13 ++reg_class r13_reg( ++ R13, R13_H ++); ++ ++// Class for 64 bit register r14 ++reg_class r14_reg( ++ R14, R14_H ++); ++ ++// Class for 64 bit register r15 ++reg_class r15_reg( ++ R15, R15_H ++); ++ ++// Class for 64 bit register r16 ++reg_class r16_reg( ++ R16, R16_H ++); ++ ++// Class for method register ++reg_class method_reg( ++ R31, R31_H ++); ++ ++// Class for heapbase register ++reg_class heapbase_reg( ++ R27, R27_H ++); ++ ++// Class for java thread register ++reg_class java_thread_reg( ++ R23, R23_H ++); ++ ++reg_class r28_reg( ++ R28, R28_H ++); ++ ++reg_class r29_reg( ++ R29, R29_H ++); ++ ++reg_class r30_reg( ++ R30, R30_H ++); ++ ++// Class for zero registesr ++reg_class zr_reg( ++ R0, R0_H ++); ++ ++// Class for thread register ++reg_class thread_reg( ++ R4, R4_H ++); ++ ++// Class for frame pointer register ++reg_class fp_reg( ++ R8, R8_H ++); ++ ++// Class for link register ++reg_class ra_reg( ++ R1, R1_H ++); ++ ++// Class for long sp register ++reg_class sp_reg( ++ R2, R2_H ++); ++ ++// Class for all float registers ++reg_class float_reg( ++ F0, ++ F1, ++ F2, ++ F3, ++ F4, ++ F5, ++ F6, ++ F7, ++ F8, ++ F9, ++ F10, ++ F11, ++ F12, ++ F13, ++ F14, ++ F15, ++ F16, ++ F17, ++ F18, ++ F19, ++ F20, ++ F21, ++ F22, ++ F23, ++ F24, ++ F25, ++ F26, ++ F27, ++ F28, ++ F29, ++ F30, ++ F31 ++); ++ ++// Double precision float registers have virtual `high halves' that ++// are needed by the allocator. ++// Class for all double registers ++reg_class double_reg( ++ F0, F0_H, ++ F1, F1_H, ++ F2, F2_H, ++ F3, F3_H, ++ F4, F4_H, ++ F5, F5_H, ++ F6, F6_H, ++ F7, F7_H, ++ F8, F8_H, ++ F9, F9_H, ++ F10, F10_H, ++ F11, F11_H, ++ F12, F12_H, ++ F13, F13_H, ++ F14, F14_H, ++ F15, F15_H, ++ F16, F16_H, ++ F17, F17_H, ++ F18, F18_H, ++ F19, F19_H, ++ F20, F20_H, ++ F21, F21_H, ++ F22, F22_H, ++ F23, F23_H, ++ F24, F24_H, ++ F25, F25_H, ++ F26, F26_H, ++ F27, F27_H, ++ F28, F28_H, ++ F29, F29_H, ++ F30, F30_H, ++ F31, F31_H ++); ++ ++// Class for all RVV vector registers ++reg_class vectora_reg( ++ V1, V1_H, V1_J, V1_K, ++ V2, V2_H, V2_J, V2_K, ++ V3, V3_H, V3_J, V3_K, ++ V4, V4_H, V4_J, V4_K, ++ V5, V5_H, V5_J, V5_K, ++ V6, V6_H, V6_J, V6_K, ++ V7, V7_H, V7_J, V7_K, ++ V8, V8_H, V8_J, V8_K, ++ V9, V9_H, V9_J, V9_K, ++ V10, V10_H, V10_J, V10_K, ++ V11, V11_H, V11_J, V11_K, ++ V12, V12_H, V12_J, V12_K, ++ V13, V13_H, V13_J, V13_K, ++ V14, V14_H, V14_J, V14_K, ++ V15, V15_H, V15_J, V15_K, ++ V16, V16_H, V16_J, V16_K, ++ V17, V17_H, V17_J, V17_K, ++ V18, V18_H, V18_J, V18_K, ++ V19, V19_H, V19_J, V19_K, ++ V20, V20_H, V20_J, V20_K, ++ V21, V21_H, V21_J, V21_K, ++ V22, V22_H, V22_J, V22_K, ++ V23, V23_H, V23_J, V23_K, ++ V24, V24_H, V24_J, V24_K, ++ V25, V25_H, V25_J, V25_K, ++ V26, V26_H, V26_J, V26_K, ++ V27, V27_H, V27_J, V27_K, ++ V28, V28_H, V28_J, V28_K, ++ V29, V29_H, V29_J, V29_K, ++ V30, V30_H, V30_J, V30_K, ++ V31, V31_H, V31_J, V31_K ++); ++ ++// Class for 64 bit register f0 ++reg_class f0_reg( ++ F0, F0_H ++); ++ ++// Class for 64 bit register f1 ++reg_class f1_reg( ++ F1, F1_H ++); ++ ++// Class for 64 bit register f2 ++reg_class f2_reg( ++ F2, F2_H ++); ++ ++// Class for 64 bit register f3 ++reg_class f3_reg( ++ F3, F3_H ++); ++ ++// class for vector register v1 ++reg_class v1_reg( ++ V1, V1_H, V1_J, V1_K ++); ++ ++// class for vector register v2 ++reg_class v2_reg( ++ V2, V2_H, V2_J, V2_K ++); ++ ++// class for vector register v3 ++reg_class v3_reg( ++ V3, V3_H, V3_J, V3_K ++); ++ ++// class for vector register v4 ++reg_class v4_reg( ++ V4, V4_H, V4_J, V4_K ++); ++ ++// class for vector register v5 ++reg_class v5_reg( ++ V5, V5_H, V5_J, V5_K ++); ++ ++// class for condition codes ++reg_class reg_flags(RFLAGS); ++%} ++ ++//----------DEFINITION BLOCK--------------------------------------------------- ++// Define name --> value mappings to inform the ADLC of an integer valued name ++// Current support includes integer values in the range [0, 0x7FFFFFFF] ++// Format: ++// int_def ( , ); ++// Generated Code in ad_.hpp ++// #define () ++// // value == ++// Generated code in ad_.cpp adlc_verification() ++// assert( == , "Expect () to equal "); ++// ++ ++// we follow the ppc-aix port in using a simple cost model which ranks ++// register operations as cheap, memory ops as more expensive and ++// branches as most expensive. the first two have a low as well as a ++// normal cost. huge cost appears to be a way of saying don't do ++// something ++ ++definitions %{ ++ // The default cost (of a register move instruction). ++ int_def DEFAULT_COST ( 100, 100); ++ int_def ALU_COST ( 100, 1 * DEFAULT_COST); // unknown, const, arith, shift, slt, ++ // multi, auipc, nop, logical, move ++ int_def LOAD_COST ( 300, 3 * DEFAULT_COST); // load, fpload ++ int_def STORE_COST ( 100, 1 * DEFAULT_COST); // store, fpstore ++ int_def XFER_COST ( 300, 3 * DEFAULT_COST); // mfc, mtc, fcvt, fmove, fcmp ++ int_def BRANCH_COST ( 200, 2 * DEFAULT_COST); // branch, jmp, call ++ int_def IMUL_COST ( 1000, 10 * DEFAULT_COST); // imul ++ int_def IDIVSI_COST ( 3400, 34 * DEFAULT_COST); // idivdi ++ int_def IDIVDI_COST ( 6600, 66 * DEFAULT_COST); // idivsi ++ int_def FMUL_SINGLE_COST ( 500, 5 * DEFAULT_COST); // fmul, fmadd ++ int_def FMUL_DOUBLE_COST ( 700, 7 * DEFAULT_COST); // fmul, fmadd ++ int_def FDIV_COST ( 2000, 20 * DEFAULT_COST); // fdiv ++ int_def FSQRT_COST ( 2500, 25 * DEFAULT_COST); // fsqrt ++ int_def VOLATILE_REF_COST ( 1000, 10 * DEFAULT_COST); ++%} ++ ++ ++ ++//----------SOURCE BLOCK------------------------------------------------------- ++// This is a block of C++ code which provides values, functions, and ++// definitions necessary in the rest of the architecture description ++ ++source_hpp %{ ++ ++#include "asm/macroAssembler.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "gc/shared/cardTable.hpp" ++#include "gc/shared/cardTableBarrierSet.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "opto/addnode.hpp" ++#include "opto/convertnode.hpp" ++#include "runtime/objectMonitor.hpp" ++ ++extern RegMask _ANY_REG32_mask; ++extern RegMask _ANY_REG_mask; ++extern RegMask _PTR_REG_mask; ++extern RegMask _NO_SPECIAL_REG32_mask; ++extern RegMask _NO_SPECIAL_REG_mask; ++extern RegMask _NO_SPECIAL_PTR_REG_mask; ++ ++class CallStubImpl { ++ ++ //-------------------------------------------------------------- ++ //---< Used for optimization in Compile::shorten_branches >--- ++ //-------------------------------------------------------------- ++ ++ public: ++ // Size of call trampoline stub. ++ static uint size_call_trampoline() { ++ return 0; // no call trampolines on this platform ++ } ++ ++ // number of relocations needed by a call trampoline stub ++ static uint reloc_call_trampoline() { ++ return 0; // no call trampolines on this platform ++ } ++}; ++ ++class HandlerImpl { ++ ++ public: ++ ++ static int emit_exception_handler(CodeBuffer &cbuf); ++ static int emit_deopt_handler(CodeBuffer& cbuf); ++ ++ static uint size_exception_handler() { ++ return MacroAssembler::far_branch_size(); ++ } ++ ++ static uint size_deopt_handler() { ++ // count auipc + far branch ++ return NativeInstruction::instruction_size + MacroAssembler::far_branch_size(); ++ } ++}; ++ ++class Node::PD { ++public: ++ enum NodeFlags { ++ _last_flag = Node::_last_flag ++ }; ++}; ++ ++bool is_CAS(int opcode, bool maybe_volatile); ++ ++// predicate controlling translation of CompareAndSwapX ++bool needs_acquiring_load_reserved(const Node *load); ++ ++// predicate controlling addressing modes ++bool size_fits_all_mem_uses(AddPNode* addp, int shift); ++%} ++ ++source %{ ++ ++// Derived RegMask with conditionally allocatable registers ++ ++RegMask _ANY_REG32_mask; ++RegMask _ANY_REG_mask; ++RegMask _PTR_REG_mask; ++RegMask _NO_SPECIAL_REG32_mask; ++RegMask _NO_SPECIAL_REG_mask; ++RegMask _NO_SPECIAL_PTR_REG_mask; ++ ++void reg_mask_init() { ++ ++ _ANY_REG32_mask = _ALL_REG32_mask; ++ _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(x0->as_VMReg())); ++ ++ _ANY_REG_mask = _ALL_REG_mask; ++ _ANY_REG_mask.SUBTRACT(_ZR_REG_mask); ++ ++ _PTR_REG_mask = _ALL_REG_mask; ++ _PTR_REG_mask.SUBTRACT(_ZR_REG_mask); ++ ++ _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; ++ _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); ++ ++ _NO_SPECIAL_REG_mask = _ALL_REG_mask; ++ _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); ++ ++ _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; ++ _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); ++ ++ // x27 is not allocatable when compressed oops is on ++ if (UseCompressedOops) { ++ _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(x27->as_VMReg())); ++ _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); ++ _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); ++ } ++ ++ // x8 is not allocatable when PreserveFramePointer is on ++ if (PreserveFramePointer) { ++ _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(x8->as_VMReg())); ++ _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask); ++ _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask); ++ } ++} ++ ++void PhaseOutput::pd_perform_mach_node_analysis() { ++} ++ ++int MachNode::pd_alignment_required() const { ++ return 1; ++} ++ ++int MachNode::compute_padding(int current_offset) const { ++ return 0; ++} ++ ++// is_CAS(int opcode, bool maybe_volatile) ++// ++// return true if opcode is one of the possible CompareAndSwapX ++// values otherwise false. ++bool is_CAS(int opcode, bool maybe_volatile) ++{ ++ switch (opcode) { ++ // We handle these ++ case Op_CompareAndSwapI: ++ case Op_CompareAndSwapL: ++ case Op_CompareAndSwapP: ++ case Op_CompareAndSwapN: ++ case Op_ShenandoahCompareAndSwapP: ++ case Op_ShenandoahCompareAndSwapN: ++ case Op_CompareAndSwapB: ++ case Op_CompareAndSwapS: ++ case Op_GetAndSetI: ++ case Op_GetAndSetL: ++ case Op_GetAndSetP: ++ case Op_GetAndSetN: ++ case Op_GetAndAddI: ++ case Op_GetAndAddL: ++ return true; ++ case Op_CompareAndExchangeI: ++ case Op_CompareAndExchangeN: ++ case Op_CompareAndExchangeB: ++ case Op_CompareAndExchangeS: ++ case Op_CompareAndExchangeL: ++ case Op_CompareAndExchangeP: ++ case Op_WeakCompareAndSwapB: ++ case Op_WeakCompareAndSwapS: ++ case Op_WeakCompareAndSwapI: ++ case Op_WeakCompareAndSwapL: ++ case Op_WeakCompareAndSwapP: ++ case Op_WeakCompareAndSwapN: ++ case Op_ShenandoahWeakCompareAndSwapP: ++ case Op_ShenandoahWeakCompareAndSwapN: ++ case Op_ShenandoahCompareAndExchangeP: ++ case Op_ShenandoahCompareAndExchangeN: ++ return maybe_volatile; ++ default: ++ return false; ++ } ++} ++ ++// predicate controlling translation of CAS ++// ++// returns true if CAS needs to use an acquiring load otherwise false ++bool needs_acquiring_load_reserved(const Node *n) ++{ ++ assert(n != NULL && is_CAS(n->Opcode(), true), "expecting a compare and swap"); ++ ++ LoadStoreNode* ldst = n->as_LoadStore(); ++ if (n != NULL && is_CAS(n->Opcode(), false)) { ++ assert(ldst != NULL && ldst->trailing_membar() != NULL, "expected trailing membar"); ++ } else { ++ return ldst != NULL && ldst->trailing_membar() != NULL; ++ } ++ // so we can just return true here ++ return true; ++} ++#define __ _masm. ++ ++// advance declarations for helper functions to convert register ++// indices to register objects ++ ++// the ad file has to provide implementations of certain methods ++// expected by the generic code ++// ++// REQUIRED FUNCTIONALITY ++ ++//============================================================================= ++ ++// !!!!! Special hack to get all types of calls to specify the byte offset ++// from the start of the call to the point where the return address ++// will point. ++ ++int MachCallStaticJavaNode::ret_addr_offset() ++{ ++ // jal ++ return 1 * NativeInstruction::instruction_size; ++} ++ ++int MachCallDynamicJavaNode::ret_addr_offset() ++{ ++ return 7 * NativeInstruction::instruction_size; // movptr, jal ++} ++ ++int MachCallRuntimeNode::ret_addr_offset() { ++ // for generated stubs the call will be ++ // jal(addr) ++ // or with far branches ++ // jal(trampoline_stub) ++ // for real runtime callouts it will be 11 instructions ++ // see riscv_enc_java_to_runtime ++ // la(t1, retaddr) -> auipc + addi ++ // la(t0, RuntimeAddress(addr)) -> lui + addi + slli + addi + slli + addi ++ // addi(sp, sp, -2 * wordSize) -> addi ++ // sd(t1, Address(sp, wordSize)) -> sd ++ // jalr(t0) -> jalr ++ CodeBlob *cb = CodeCache::find_blob(_entry_point); ++ if (cb != NULL) { ++ return 1 * NativeInstruction::instruction_size; ++ } else { ++ return 11 * NativeInstruction::instruction_size; ++ } ++} ++ ++int MachCallNativeNode::ret_addr_offset() { ++ Unimplemented(); ++ return -1; ++} ++ ++// ++// Compute padding required for nodes which need alignment ++// ++ ++// With RVC a call instruction may get 2-byte aligned. ++// The address of the call instruction needs to be 4-byte aligned to ++// ensure that it does not span a cache line so that it can be patched. ++int CallStaticJavaDirectNode::compute_padding(int current_offset) const ++{ ++ // to make sure the address of jal 4-byte aligned. ++ return align_up(current_offset, alignment_required()) - current_offset; ++} ++ ++// With RVC a call instruction may get 2-byte aligned. ++// The address of the call instruction needs to be 4-byte aligned to ++// ensure that it does not span a cache line so that it can be patched. ++int CallDynamicJavaDirectNode::compute_padding(int current_offset) const ++{ ++ // skip the movptr in MacroAssembler::ic_call(): ++ // lui + addi + slli + addi + slli + addi ++ // Though movptr() has already 4-byte aligned with or without RVC, ++ // We need to prevent from further changes by explicitly calculating the size. ++ const int movptr_size = 6 * NativeInstruction::instruction_size; ++ current_offset += movptr_size; ++ // to make sure the address of jal 4-byte aligned. ++ return align_up(current_offset, alignment_required()) - current_offset; ++} ++ ++//============================================================================= ++ ++#ifndef PRODUCT ++void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { ++ assert_cond(st != NULL); ++ st->print("BREAKPOINT"); ++} ++#endif ++ ++void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { ++ C2_MacroAssembler _masm(&cbuf); ++ __ ebreak(); ++} ++ ++uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { ++ return MachNode::size(ra_); ++} ++ ++//============================================================================= ++ ++#ifndef PRODUCT ++ void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { ++ st->print("nop \t# %d bytes pad for loops and calls", _count); ++ } ++#endif ++ ++ void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { ++ C2_MacroAssembler _masm(&cbuf); ++ Assembler::CompressibleRegion cr(&_masm); // nops shall be 2-byte under RVC for alignment purposes. ++ for (int i = 0; i < _count; i++) { ++ __ nop(); ++ } ++ } ++ ++ uint MachNopNode::size(PhaseRegAlloc*) const { ++ return _count * (UseRVC ? NativeInstruction::compressed_instruction_size : NativeInstruction::instruction_size); ++ } ++ ++//============================================================================= ++const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; ++ ++int ConstantTable::calculate_table_base_offset() const { ++ return 0; // absolute addressing, no offset ++} ++ ++bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } ++void MachConstantBaseNode::postalloc_expand(GrowableArray *nodes, PhaseRegAlloc *ra_) { ++ ShouldNotReachHere(); ++} ++ ++void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { ++ // Empty encoding ++} ++ ++uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { ++ return 0; ++} ++ ++#ifndef PRODUCT ++void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { ++ assert_cond(st != NULL); ++ st->print("-- \t// MachConstantBaseNode (empty encoding)"); ++} ++#endif ++ ++#ifndef PRODUCT ++void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { ++ assert_cond(st != NULL && ra_ != NULL); ++ Compile* C = ra_->C; ++ ++ int framesize = C->output()->frame_slots() << LogBytesPerInt; ++ ++ if (C->output()->need_stack_bang(framesize)) { ++ st->print("# stack bang size=%d\n\t", framesize); ++ } ++ ++ st->print("sd fp, [sp, #%d]\n\t", - 2 * wordSize); ++ st->print("sd ra, [sp, #%d]\n\t", - wordSize); ++ if (PreserveFramePointer) { st->print("sub fp, sp, #%d\n\t", 2 * wordSize); } ++ st->print("sub sp, sp, #%d\n\t", framesize); ++ ++ if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { ++ st->print("ld t0, [guard]\n\t"); ++ st->print("membar LoadLoad\n\t"); ++ st->print("ld t1, [xthread, #thread_disarmed_offset]\n\t"); ++ st->print("beq t0, t1, skip\n\t"); ++ st->print("jalr #nmethod_entry_barrier_stub\n\t"); ++ st->print("j skip\n\t"); ++ st->print("guard: int\n\t"); ++ st->print("skip:\n\t"); ++ } ++} ++#endif ++ ++void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { ++ assert_cond(ra_ != NULL); ++ Compile* C = ra_->C; ++ C2_MacroAssembler _masm(&cbuf); ++ ++ // n.b. frame size includes space for return pc and fp ++ const int framesize = C->output()->frame_size_in_bytes(); ++ ++ // insert a nop at the start of the prolog so we can patch in a ++ // branch if we need to invalidate the method later ++ { ++ Assembler::IncompressibleRegion ir(&_masm); // keep the nop as 4 bytes for patching. ++ MacroAssembler::assert_alignment(__ pc()); ++ __ nop(); // 4 bytes ++ } ++ ++ assert_cond(C != NULL); ++ ++ if (C->clinit_barrier_on_entry()) { ++ assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); ++ ++ Label L_skip_barrier; ++ ++ __ mov_metadata(t1, C->method()->holder()->constant_encoding()); ++ __ clinit_barrier(t1, t0, &L_skip_barrier); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); ++ __ bind(L_skip_barrier); ++ } ++ ++ int bangsize = C->output()->bang_size_in_bytes(); ++ if (C->output()->need_stack_bang(bangsize)) { ++ __ generate_stack_overflow_check(bangsize); ++ } ++ ++ __ build_frame(framesize); ++ ++ if (C->stub_function() == NULL) { ++ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->nmethod_entry_barrier(&_masm); ++ } ++ ++ if (VerifyStackAtCalls) { ++ Unimplemented(); ++ } ++ ++ C->output()->set_frame_complete(cbuf.insts_size()); ++ ++ if (C->has_mach_constant_base_node()) { ++ // NOTE: We set the table base offset here because users might be ++ // emitted before MachConstantBaseNode. ++ ConstantTable& constant_table = C->output()->constant_table(); ++ constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); ++ } ++} ++ ++uint MachPrologNode::size(PhaseRegAlloc* ra_) const ++{ ++ assert_cond(ra_ != NULL); ++ return MachNode::size(ra_); // too many variables; just compute it ++ // the hard way ++} ++ ++int MachPrologNode::reloc() const ++{ ++ return 0; ++} ++ ++//============================================================================= ++ ++#ifndef PRODUCT ++void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { ++ assert_cond(st != NULL && ra_ != NULL); ++ Compile* C = ra_->C; ++ assert_cond(C != NULL); ++ int framesize = C->output()->frame_size_in_bytes(); ++ ++ st->print("# pop frame %d\n\t", framesize); ++ ++ if (framesize == 0) { ++ st->print("ld ra, [sp,#%d]\n\t", (2 * wordSize)); ++ st->print("ld fp, [sp,#%d]\n\t", (3 * wordSize)); ++ st->print("add sp, sp, #%d\n\t", (2 * wordSize)); ++ } else { ++ st->print("add sp, sp, #%d\n\t", framesize); ++ st->print("ld ra, [sp,#%d]\n\t", - 2 * wordSize); ++ st->print("ld fp, [sp,#%d]\n\t", - wordSize); ++ } ++ ++ if (do_polling() && C->is_method_compilation()) { ++ st->print("# test polling word\n\t"); ++ st->print("ld t0, [xthread,#%d]\n\t", in_bytes(JavaThread::polling_word_offset())); ++ st->print("bgtu sp, t0, #slow_path"); ++ } ++} ++#endif ++ ++void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { ++ assert_cond(ra_ != NULL); ++ Compile* C = ra_->C; ++ C2_MacroAssembler _masm(&cbuf); ++ assert_cond(C != NULL); ++ int framesize = C->output()->frame_size_in_bytes(); ++ ++ __ remove_frame(framesize); ++ ++ if (StackReservedPages > 0 && C->has_reserved_stack_access()) { ++ __ reserved_stack_check(); ++ } ++ ++ if (do_polling() && C->is_method_compilation()) { ++ Label dummy_label; ++ Label* code_stub = &dummy_label; ++ if (!C->output()->in_scratch_emit_size()) { ++ code_stub = &C->output()->safepoint_poll_table()->add_safepoint(__ offset()); ++ } ++ __ relocate(relocInfo::poll_return_type); ++ __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */); ++ } ++} ++ ++uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { ++ assert_cond(ra_ != NULL); ++ // Variable size. Determine dynamically. ++ return MachNode::size(ra_); ++} ++ ++int MachEpilogNode::reloc() const { ++ // Return number of relocatable values contained in this instruction. ++ return 1; // 1 for polling page. ++} ++const Pipeline * MachEpilogNode::pipeline() const { ++ return MachNode::pipeline_class(); ++} ++ ++//============================================================================= ++ ++// Figure out which register class each belongs in: rc_int, rc_float or ++// rc_stack. ++enum RC { rc_bad, rc_int, rc_float, rc_vector, rc_stack }; ++ ++static enum RC rc_class(OptoReg::Name reg) { ++ ++ if (reg == OptoReg::Bad) { ++ return rc_bad; ++ } ++ ++ // we have 30 int registers * 2 halves ++ // (t0 and t1 are omitted) ++ int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); ++ if (reg < slots_of_int_registers) { ++ return rc_int; ++ } ++ ++ // we have 32 float register * 2 halves ++ int slots_of_float_registers = FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers; ++ if (reg < slots_of_int_registers + slots_of_float_registers) { ++ return rc_float; ++ } ++ ++ // we have 32 vector register * 4 halves ++ int slots_of_vector_registers = VectorRegisterImpl::max_slots_per_register * VectorRegisterImpl::number_of_registers; ++ if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_vector_registers) { ++ return rc_vector; ++ } ++ ++ // Between vector regs & stack is the flags regs. ++ assert(OptoReg::is_stack(reg), "blow up if spilling flags"); ++ ++ return rc_stack; ++} ++ ++uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { ++ assert_cond(ra_ != NULL); ++ Compile* C = ra_->C; ++ ++ // Get registers to move. ++ OptoReg::Name src_hi = ra_->get_reg_second(in(1)); ++ OptoReg::Name src_lo = ra_->get_reg_first(in(1)); ++ OptoReg::Name dst_hi = ra_->get_reg_second(this); ++ OptoReg::Name dst_lo = ra_->get_reg_first(this); ++ ++ enum RC src_hi_rc = rc_class(src_hi); ++ enum RC src_lo_rc = rc_class(src_lo); ++ enum RC dst_hi_rc = rc_class(dst_hi); ++ enum RC dst_lo_rc = rc_class(dst_lo); ++ ++ assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); ++ ++ if (src_hi != OptoReg::Bad) { ++ assert((src_lo & 1) == 0 && src_lo + 1 == src_hi && ++ (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi, ++ "expected aligned-adjacent pairs"); ++ } ++ ++ if (src_lo == dst_lo && src_hi == dst_hi) { ++ return 0; // Self copy, no move. ++ } ++ ++ bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && ++ (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; ++ int src_offset = ra_->reg2offset(src_lo); ++ int dst_offset = ra_->reg2offset(dst_lo); ++ ++ if (bottom_type()->isa_vect() != NULL) { ++ uint ireg = ideal_reg(); ++ if (ireg == Op_VecA && cbuf) { ++ C2_MacroAssembler _masm(cbuf); ++ int vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); ++ if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { ++ // stack to stack ++ __ spill_copy_vector_stack_to_stack(src_offset, dst_offset, ++ vector_reg_size_in_bytes); ++ } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_stack) { ++ // vpr to stack ++ __ spill(as_VectorRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo)); ++ } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vector) { ++ // stack to vpr ++ __ unspill(as_VectorRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo)); ++ } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_vector) { ++ // vpr to vpr ++ __ vmv1r_v(as_VectorRegister(Matcher::_regEncode[dst_lo]), as_VectorRegister(Matcher::_regEncode[src_lo])); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } ++ } else if (cbuf != NULL) { ++ C2_MacroAssembler _masm(cbuf); ++ switch (src_lo_rc) { ++ case rc_int: ++ if (dst_lo_rc == rc_int) { // gpr --> gpr copy ++ if (!is64 && this->ideal_reg() != Op_RegI) { // zero extended for narrow oop or klass ++ __ zero_extend(as_Register(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo]), 32); ++ } else { ++ __ mv(as_Register(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo])); ++ } ++ } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy ++ if (is64) { ++ __ fmv_d_x(as_FloatRegister(Matcher::_regEncode[dst_lo]), ++ as_Register(Matcher::_regEncode[src_lo])); ++ } else { ++ __ fmv_w_x(as_FloatRegister(Matcher::_regEncode[dst_lo]), ++ as_Register(Matcher::_regEncode[src_lo])); ++ } ++ } else { // gpr --> stack spill ++ assert(dst_lo_rc == rc_stack, "spill to bad register class"); ++ __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); ++ } ++ break; ++ case rc_float: ++ if (dst_lo_rc == rc_int) { // fpr --> gpr copy ++ if (is64) { ++ __ fmv_x_d(as_Register(Matcher::_regEncode[dst_lo]), ++ as_FloatRegister(Matcher::_regEncode[src_lo])); ++ } else { ++ __ fmv_x_w(as_Register(Matcher::_regEncode[dst_lo]), ++ as_FloatRegister(Matcher::_regEncode[src_lo])); ++ } ++ } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy ++ if (is64) { ++ __ fmv_d(as_FloatRegister(Matcher::_regEncode[dst_lo]), ++ as_FloatRegister(Matcher::_regEncode[src_lo])); ++ } else { ++ __ fmv_s(as_FloatRegister(Matcher::_regEncode[dst_lo]), ++ as_FloatRegister(Matcher::_regEncode[src_lo])); ++ } ++ } else { // fpr --> stack spill ++ assert(dst_lo_rc == rc_stack, "spill to bad register class"); ++ __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), ++ is64, dst_offset); ++ } ++ break; ++ case rc_stack: ++ if (dst_lo_rc == rc_int) { // stack --> gpr load ++ if (this->ideal_reg() == Op_RegI) { ++ __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); ++ } else { // // zero extended for narrow oop or klass ++ __ unspillu(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); ++ } ++ } else if (dst_lo_rc == rc_float) { // stack --> fpr load ++ __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), ++ is64, src_offset); ++ } else { // stack --> stack copy ++ assert(dst_lo_rc == rc_stack, "spill to bad register class"); ++ if (this->ideal_reg() == Op_RegI) { ++ __ unspill(t0, is64, src_offset); ++ } else { // zero extended for narrow oop or klass ++ __ unspillu(t0, is64, src_offset); ++ } ++ __ spill(t0, is64, dst_offset); ++ } ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ } ++ ++ if (st != NULL) { ++ st->print("spill "); ++ if (src_lo_rc == rc_stack) { ++ st->print("[sp, #%d] -> ", src_offset); ++ } else { ++ st->print("%s -> ", Matcher::regName[src_lo]); ++ } ++ if (dst_lo_rc == rc_stack) { ++ st->print("[sp, #%d]", dst_offset); ++ } else { ++ st->print("%s", Matcher::regName[dst_lo]); ++ } ++ if (bottom_type()->isa_vect() != NULL) { ++ int vsize = 0; ++ if (ideal_reg() == Op_VecA) { ++ vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8; ++ } else { ++ ShouldNotReachHere(); ++ } ++ st->print("\t# vector spill size = %d", vsize); ++ } else { ++ st->print("\t# spill size = %d", is64 ? 64 : 32); ++ } ++ } ++ ++ return 0; ++} ++ ++#ifndef PRODUCT ++void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { ++ if (ra_ == NULL) { ++ st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); ++ } else { ++ implementation(NULL, ra_, false, st); ++ } ++} ++#endif ++ ++void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { ++ implementation(&cbuf, ra_, false, NULL); ++} ++ ++uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { ++ return MachNode::size(ra_); ++} ++ ++//============================================================================= ++ ++#ifndef PRODUCT ++void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { ++ assert_cond(ra_ != NULL && st != NULL); ++ int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); ++ int reg = ra_->get_reg_first(this); ++ st->print("add %s, sp, #%d\t# box lock", ++ Matcher::regName[reg], offset); ++} ++#endif ++ ++void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { ++ C2_MacroAssembler _masm(&cbuf); ++ Assembler::IncompressibleRegion ir(&_masm); // Fixed length: see BoxLockNode::size() ++ ++ assert_cond(ra_ != NULL); ++ int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); ++ int reg = ra_->get_encode(this); ++ ++ if (Assembler::is_simm12(offset)) { ++ __ addi(as_Register(reg), sp, offset); ++ } else { ++ __ li32(t0, offset); ++ __ add(as_Register(reg), sp, t0); ++ } ++} ++ ++uint BoxLockNode::size(PhaseRegAlloc *ra_) const { ++ // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). ++ int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); ++ ++ if (Assembler::is_simm12(offset)) { ++ return NativeInstruction::instruction_size; ++ } else { ++ return 3 * NativeInstruction::instruction_size; // lui + addiw + add; ++ } ++} ++ ++//============================================================================= ++ ++#ifndef PRODUCT ++void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const ++{ ++ assert_cond(st != NULL); ++ st->print_cr("# MachUEPNode"); ++ if (UseCompressedClassPointers) { ++ st->print_cr("\tlwu t0, [j_rarg0, oopDesc::klass_offset_in_bytes()]\t# compressed klass"); ++ if (CompressedKlassPointers::shift() != 0) { ++ st->print_cr("\tdecode_klass_not_null t0, t0"); ++ } ++ } else { ++ st->print_cr("\tld t0, [j_rarg0, oopDesc::klass_offset_in_bytes()]\t# compressed klass"); ++ } ++ st->print_cr("\tbeq t0, t1, ic_hit"); ++ st->print_cr("\tj, SharedRuntime::_ic_miss_stub\t # Inline cache check"); ++ st->print_cr("\tic_hit:"); ++} ++#endif ++ ++void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const ++{ ++ // This is the unverified entry point. ++ C2_MacroAssembler _masm(&cbuf); ++ ++ Label skip; ++ __ cmp_klass(j_rarg0, t1, t0, t2 /* call-clobbered t2 as a tmp */, skip); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); ++ __ bind(skip); ++ ++ // These NOPs are critical so that verified entry point is properly ++ // 4 bytes aligned for patching by NativeJump::patch_verified_entry() ++ __ align(NativeInstruction::instruction_size); ++} ++ ++uint MachUEPNode::size(PhaseRegAlloc* ra_) const ++{ ++ assert_cond(ra_ != NULL); ++ return MachNode::size(ra_); ++} ++ ++// REQUIRED EMIT CODE ++ ++//============================================================================= ++ ++// Emit exception handler code. ++int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) ++{ ++ // la_patchable t0, #exception_blob_entry_point ++ // jr (offset)t0 ++ // or ++ // j #exception_blob_entry_point ++ // Note that the code buffer's insts_mark is always relative to insts. ++ // That's why we must use the macroassembler to generate a handler. ++ C2_MacroAssembler _masm(&cbuf); ++ address base = __ start_a_stub(size_exception_handler()); ++ if (base == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return 0; // CodeBuffer::expand failed ++ } ++ int offset = __ offset(); ++ __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); ++ assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); ++ __ end_a_stub(); ++ return offset; ++} ++ ++// Emit deopt handler code. ++int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) ++{ ++ // Note that the code buffer's insts_mark is always relative to insts. ++ // That's why we must use the macroassembler to generate a handler. ++ C2_MacroAssembler _masm(&cbuf); ++ address base = __ start_a_stub(size_deopt_handler()); ++ if (base == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return 0; // CodeBuffer::expand failed ++ } ++ int offset = __ offset(); ++ ++ __ auipc(ra, 0); ++ __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); ++ ++ assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); ++ __ end_a_stub(); ++ return offset; ++ ++} ++// REQUIRED MATCHER CODE ++ ++//============================================================================= ++ ++const bool Matcher::match_rule_supported(int opcode) { ++ if (!has_match_rule(opcode)) { ++ return false; ++ } ++ ++ switch (opcode) { ++ case Op_CacheWB: // fall through ++ case Op_CacheWBPreSync: // fall through ++ case Op_CacheWBPostSync: ++ if (!VM_Version::supports_data_cache_line_flush()) { ++ return false; ++ } ++ break; ++ ++ case Op_StrCompressedCopy: // fall through ++ case Op_StrInflatedCopy: // fall through ++ case Op_HasNegatives: ++ return UseRVV; ++ ++ case Op_EncodeISOArray: ++ return UseRVV && SpecialEncodeISOArray; ++ ++ case Op_PopCountI: ++ case Op_PopCountL: ++ return UsePopCountInstruction; ++ ++ case Op_RotateRight: ++ case Op_RotateLeft: ++ case Op_CountLeadingZerosI: ++ case Op_CountLeadingZerosL: ++ case Op_CountTrailingZerosI: ++ case Op_CountTrailingZerosL: ++ return UseZbb; ++ } ++ ++ return true; // Per default match rules are supported. ++} ++ ++// Identify extra cases that we might want to provide match rules for vector nodes and ++// other intrinsics guarded with vector length (vlen) and element type (bt). ++const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { ++ if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) { ++ return false; ++ } ++ ++ return op_vec_supported(opcode); ++} ++ ++const RegMask* Matcher::predicate_reg_mask(void) { ++ return NULL; ++} ++ ++const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { ++ return NULL; ++} ++ ++// Vector calling convention not yet implemented. ++const bool Matcher::supports_vector_calling_convention(void) { ++ return false; ++} ++ ++OptoRegPair Matcher::vector_return_value(uint ideal_reg) { ++ Unimplemented(); ++ return OptoRegPair(0, 0); ++} ++ ++// Is this branch offset short enough that a short branch can be used? ++// ++// NOTE: If the platform does not provide any short branch variants, then ++// this method should return false for offset 0. ++// |---label(L1)-----| ++// |-----------------| ++// |-----------------|----------eq: float------------------- ++// |-----------------| // far_cmpD_branch | cmpD_branch ++// |------- ---------| feq; | feq; ++// |-far_cmpD_branch-| beqz done; | bnez L; ++// |-----------------| j L; | ++// |-----------------| bind(done); | ++// |-----------------|-------------------------------------- ++// |-----------------| // so shortBrSize = br_size - 4; ++// |-----------------| // so offs = offset - shortBrSize + 4; ++// |---label(L2)-----| ++bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { ++ // The passed offset is relative to address of the branch. ++ int shortBrSize = br_size - 4; ++ int offs = offset - shortBrSize + 4; ++ return (-4096 <= offs && offs < 4096); ++} ++ ++// Vector width in bytes. ++const int Matcher::vector_width_in_bytes(BasicType bt) { ++ if (UseRVV) { ++ // The MaxVectorSize should have been set by detecting RVV max vector register size when check UseRVV. ++ // MaxVectorSize == VM_Version::_initial_vector_length ++ return MaxVectorSize; ++ } ++ return 0; ++} ++ ++// Limits on vector size (number of elements) loaded into vector. ++const int Matcher::max_vector_size(const BasicType bt) { ++ return vector_width_in_bytes(bt) / type2aelembytes(bt); ++} ++const int Matcher::min_vector_size(const BasicType bt) { ++ return max_vector_size(bt); ++} ++ ++// Vector ideal reg. ++const uint Matcher::vector_ideal_reg(int len) { ++ assert(MaxVectorSize >= len, ""); ++ if (UseRVV) { ++ return Op_VecA; ++ } ++ ++ ShouldNotReachHere(); ++ return 0; ++} ++ ++const int Matcher::scalable_vector_reg_size(const BasicType bt) { ++ return Matcher::max_vector_size(bt); ++} ++ ++MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { ++ ShouldNotReachHere(); // generic vector operands not supported ++ return NULL; ++} ++ ++bool Matcher::is_generic_reg2reg_move(MachNode* m) { ++ ShouldNotReachHere(); // generic vector operands not supported ++ return false; ++} ++ ++bool Matcher::is_generic_vector(MachOper* opnd) { ++ ShouldNotReachHere(); // generic vector operands not supported ++ return false; ++} ++ ++// Return whether or not this register is ever used as an argument. ++// This function is used on startup to build the trampoline stubs in ++// generateOptoStub. Registers not mentioned will be killed by the VM ++// call in the trampoline, and arguments in those registers not be ++// available to the callee. ++bool Matcher::can_be_java_arg(int reg) ++{ ++ return ++ reg == R10_num || reg == R10_H_num || ++ reg == R11_num || reg == R11_H_num || ++ reg == R12_num || reg == R12_H_num || ++ reg == R13_num || reg == R13_H_num || ++ reg == R14_num || reg == R14_H_num || ++ reg == R15_num || reg == R15_H_num || ++ reg == R16_num || reg == R16_H_num || ++ reg == R17_num || reg == R17_H_num || ++ reg == F10_num || reg == F10_H_num || ++ reg == F11_num || reg == F11_H_num || ++ reg == F12_num || reg == F12_H_num || ++ reg == F13_num || reg == F13_H_num || ++ reg == F14_num || reg == F14_H_num || ++ reg == F15_num || reg == F15_H_num || ++ reg == F16_num || reg == F16_H_num || ++ reg == F17_num || reg == F17_H_num; ++} ++ ++bool Matcher::is_spillable_arg(int reg) ++{ ++ return can_be_java_arg(reg); ++} ++ ++const int Matcher::float_pressure(int default_pressure_threshold) { ++ return default_pressure_threshold; ++} ++ ++bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { ++ return false; ++} ++ ++RegMask Matcher::divI_proj_mask() { ++ ShouldNotReachHere(); ++ return RegMask(); ++} ++ ++// Register for MODI projection of divmodI. ++RegMask Matcher::modI_proj_mask() { ++ ShouldNotReachHere(); ++ return RegMask(); ++} ++ ++// Register for DIVL projection of divmodL. ++RegMask Matcher::divL_proj_mask() { ++ ShouldNotReachHere(); ++ return RegMask(); ++} ++ ++// Register for MODL projection of divmodL. ++RegMask Matcher::modL_proj_mask() { ++ ShouldNotReachHere(); ++ return RegMask(); ++} ++ ++const RegMask Matcher::method_handle_invoke_SP_save_mask() { ++ return FP_REG_mask(); ++} ++ ++bool size_fits_all_mem_uses(AddPNode* addp, int shift) { ++ assert_cond(addp != NULL); ++ for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { ++ Node* u = addp->fast_out(i); ++ if (u != NULL && u->is_Mem()) { ++ int opsize = u->as_Mem()->memory_size(); ++ assert(opsize > 0, "unexpected memory operand size"); ++ if (u->as_Mem()->memory_size() != (1 << shift)) { ++ return false; ++ } ++ } ++ } ++ return true; ++} ++ ++// Should the Matcher clone input 'm' of node 'n'? ++bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { ++ assert_cond(m != NULL); ++ if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con) ++ mstack.push(m, Visit); // m = ShiftCntV ++ return true; ++ } ++ return false; ++} ++ ++// Should the Matcher clone shifts on addressing modes, expecting them ++// to be subsumed into complex addressing expressions or compute them ++// into registers? ++bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { ++ return clone_base_plus_offset_address(m, mstack, address_visited); ++} ++ ++%} ++ ++ ++ ++//----------ENCODING BLOCK----------------------------------------------------- ++// This block specifies the encoding classes used by the compiler to ++// output byte streams. Encoding classes are parameterized macros ++// used by Machine Instruction Nodes in order to generate the bit ++// encoding of the instruction. Operands specify their base encoding ++// interface with the interface keyword. There are currently ++// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & ++// COND_INTER. REG_INTER causes an operand to generate a function ++// which returns its register number when queried. CONST_INTER causes ++// an operand to generate a function which returns the value of the ++// constant when queried. MEMORY_INTER causes an operand to generate ++// four functions which return the Base Register, the Index Register, ++// the Scale Value, and the Offset Value of the operand when queried. ++// COND_INTER causes an operand to generate six functions which return ++// the encoding code (ie - encoding bits for the instruction) ++// associated with each basic boolean condition for a conditional ++// instruction. ++// ++// Instructions specify two basic values for encoding. Again, a ++// function is available to check if the constant displacement is an ++// oop. They use the ins_encode keyword to specify their encoding ++// classes (which must be a sequence of enc_class names, and their ++// parameters, specified in the encoding block), and they use the ++// opcode keyword to specify, in order, their primary, secondary, and ++// tertiary opcode. Only the opcode sections which a particular ++// instruction needs for encoding need to be specified. ++encode %{ ++ // BEGIN Non-volatile memory access ++ ++ enc_class riscv_enc_li_imm(iRegIorL dst, immIorL src) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ int64_t con = (int64_t)$src$$constant; ++ Register dst_reg = as_Register($dst$$reg); ++ __ mv(dst_reg, con); ++ %} ++ ++ enc_class riscv_enc_mov_p(iRegP dst, immP src) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ address con = (address)$src$$constant; ++ if (con == NULL || con == (address)1) { ++ ShouldNotReachHere(); ++ } else { ++ relocInfo::relocType rtype = $src->constant_reloc(); ++ if (rtype == relocInfo::oop_type) { ++ __ movoop(dst_reg, (jobject)con, /*immediate*/true); ++ } else if (rtype == relocInfo::metadata_type) { ++ __ mov_metadata(dst_reg, (Metadata*)con); ++ } else { ++ assert(rtype == relocInfo::none, "unexpected reloc type"); ++ __ mv(dst_reg, $src$$constant); ++ } ++ } ++ %} ++ ++ enc_class riscv_enc_mov_p1(iRegP dst) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ __ mv(dst_reg, 1); ++ %} ++ ++ enc_class riscv_enc_mov_byte_map_base(iRegP dst) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ load_byte_map_base($dst$$Register); ++ %} ++ ++ enc_class riscv_enc_mov_n(iRegN dst, immN src) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ address con = (address)$src$$constant; ++ if (con == NULL) { ++ ShouldNotReachHere(); ++ } else { ++ relocInfo::relocType rtype = $src->constant_reloc(); ++ assert(rtype == relocInfo::oop_type, "unexpected reloc type"); ++ __ set_narrow_oop(dst_reg, (jobject)con); ++ } ++ %} ++ ++ enc_class riscv_enc_mov_zero(iRegNorP dst) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ __ mv(dst_reg, zr); ++ %} ++ ++ enc_class riscv_enc_mov_nk(iRegN dst, immNKlass src) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ address con = (address)$src$$constant; ++ if (con == NULL) { ++ ShouldNotReachHere(); ++ } else { ++ relocInfo::relocType rtype = $src->constant_reloc(); ++ assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); ++ __ set_narrow_klass(dst_reg, (Klass *)con); ++ } ++ %} ++ ++ enc_class riscv_enc_cmpxchgw(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, ++ /*result as bool*/ true); ++ %} ++ ++ enc_class riscv_enc_cmpxchgn(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, ++ /*result as bool*/ true); ++ %} ++ ++ enc_class riscv_enc_cmpxchg(iRegINoSp res, memory mem, iRegL oldval, iRegL newval) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, ++ /*result as bool*/ true); ++ %} ++ ++ enc_class riscv_enc_cmpxchgw_acq(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, ++ /*result as bool*/ true); ++ %} ++ ++ enc_class riscv_enc_cmpxchgn_acq(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, ++ /*result as bool*/ true); ++ %} ++ ++ enc_class riscv_enc_cmpxchg_acq(iRegINoSp res, memory mem, iRegL oldval, iRegL newval) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, ++ /*result as bool*/ true); ++ %} ++ ++ // compare and branch instruction encodings ++ ++ enc_class riscv_enc_j(label lbl) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Label* L = $lbl$$label; ++ __ j(*L); ++ %} ++ ++ enc_class riscv_enc_far_cmpULtGe_imm0_branch(cmpOpULtGe cmp, iRegIorL op1, label lbl) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Label* L = $lbl$$label; ++ switch ($cmp$$cmpcode) { ++ case(BoolTest::ge): ++ __ j(*L); ++ break; ++ case(BoolTest::lt): ++ break; ++ default: ++ Unimplemented(); ++ } ++ %} ++ ++ // call instruction encodings ++ ++ enc_class riscv_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) %{ ++ Register sub_reg = as_Register($sub$$reg); ++ Register super_reg = as_Register($super$$reg); ++ Register temp_reg = as_Register($temp$$reg); ++ Register result_reg = as_Register($result$$reg); ++ Register cr_reg = t1; ++ ++ Label miss; ++ Label done; ++ C2_MacroAssembler _masm(&cbuf); ++ __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, ++ NULL, &miss); ++ if ($primary) { ++ __ mv(result_reg, zr); ++ } else { ++ __ mv(cr_reg, zr); ++ __ j(done); ++ } ++ ++ __ bind(miss); ++ if (!$primary) { ++ __ mv(cr_reg, 1); ++ } ++ ++ __ bind(done); ++ %} ++ ++ enc_class riscv_enc_java_static_call(method meth) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Assembler::IncompressibleRegion ir(&_masm); // Fixed length: see ret_addr_offset ++ ++ address addr = (address)$meth$$method; ++ address call = NULL; ++ assert_cond(addr != NULL); ++ if (!_method) { ++ // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. ++ call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); ++ if (call == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return; ++ } ++ } else { ++ int method_index = resolved_method_index(cbuf); ++ RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) ++ : static_call_Relocation::spec(method_index); ++ call = __ trampoline_call(Address(addr, rspec), &cbuf); ++ if (call == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return; ++ } ++ ++ // Emit stub for static call ++ address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); ++ if (stub == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return; ++ } ++ } ++ %} ++ ++ enc_class riscv_enc_java_dynamic_call(method meth) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Assembler::IncompressibleRegion ir(&_masm); // Fixed length: see ret_addr_offset ++ int method_index = resolved_method_index(cbuf); ++ address call = __ ic_call((address)$meth$$method, method_index); ++ if (call == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return; ++ } ++ %} ++ ++ enc_class riscv_enc_call_epilog() %{ ++ C2_MacroAssembler _masm(&cbuf); ++ if (VerifyStackAtCalls) { ++ // Check that stack depth is unchanged: find majik cookie on stack ++ __ call_Unimplemented(); ++ } ++ %} ++ ++ enc_class riscv_enc_java_to_runtime(method meth) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Assembler::IncompressibleRegion ir(&_masm); // Fixed length: see ret_addr_offset ++ ++ // some calls to generated routines (arraycopy code) are scheduled ++ // by C2 as runtime calls. if so we can call them using a jr (they ++ // will be in a reachable segment) otherwise we have to use a jalr ++ // which loads the absolute address into a register. ++ address entry = (address)$meth$$method; ++ CodeBlob *cb = CodeCache::find_blob(entry); ++ if (cb != NULL) { ++ address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); ++ if (call == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return; ++ } ++ } else { ++ Label retaddr; ++ __ la(t1, retaddr); ++ __ la(t0, RuntimeAddress(entry)); ++ // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() ++ __ addi(sp, sp, -2 * wordSize); ++ __ sd(t1, Address(sp, wordSize)); ++ __ jalr(t0); ++ __ bind(retaddr); ++ __ addi(sp, sp, 2 * wordSize); ++ } ++ %} ++ ++ // using the cr register as the bool result: 0 for success; others failed. ++ 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; ++ ++ 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 */); ++ } ++ ++ if (UseBiasedLocking && !UseOptoBiasInlining) { ++ __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont, NULL /* slow_case */, NULL, flag); ++ } ++ ++ // Check for existing monitor ++ __ test_bit(t0, disp_hdr, exact_log2(markWord::monitor_value)); ++ __ bnez(t0, object_has_monitor); ++ ++ // 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); ++ ++ // 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, (ObjectMonitor::owner_offset_in_bytes() - 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) ++ ++ // 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, ObjectMonitor::recursions_offset_in_bytes() - markWord::monitor_value), 1, t0, tmp); ++ ++ __ bind(cont); ++ %} ++ ++ // using cr flag to indicate the fast_unlock result: 0 for success; others failed. ++ 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; ++ ++ assert_different_registers(oop, box, tmp, disp_hdr, flag); ++ ++ if (UseBiasedLocking && !UseOptoBiasInlining) { ++ __ biased_locking_exit(oop, tmp, cont, flag); ++ } ++ ++ // 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); ++ ++ // 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); ++ ++ 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 ++ __ ld(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); ++ ++ 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_in_bytes())); ++ __ mv(flag, zr); ++ __ j(cont); ++ ++ __ bind(notRecursive); ++ __ ld(flag, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); ++ __ ld(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); ++ __ 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_in_bytes())); ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ __ sd(zr, Address(tmp)); // set unowned ++ ++ __ bind(cont); ++ %} ++ ++ // arithmetic encodings ++ ++ enc_class riscv_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ Register src1_reg = as_Register($src1$$reg); ++ Register src2_reg = as_Register($src2$$reg); ++ __ corrected_idivl(dst_reg, src1_reg, src2_reg, false); ++ %} ++ ++ enc_class riscv_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ Register src1_reg = as_Register($src1$$reg); ++ Register src2_reg = as_Register($src2$$reg); ++ __ corrected_idivq(dst_reg, src1_reg, src2_reg, false); ++ %} ++ ++ enc_class riscv_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ Register src1_reg = as_Register($src1$$reg); ++ Register src2_reg = as_Register($src2$$reg); ++ __ corrected_idivl(dst_reg, src1_reg, src2_reg, true); ++ %} ++ ++ enc_class riscv_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register dst_reg = as_Register($dst$$reg); ++ Register src1_reg = as_Register($src1$$reg); ++ Register src2_reg = as_Register($src2$$reg); ++ __ corrected_idivq(dst_reg, src1_reg, src2_reg, true); ++ %} ++ ++ enc_class riscv_enc_tail_call(iRegP jump_target) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register target_reg = as_Register($jump_target$$reg); ++ __ jr(target_reg); ++ %} ++ ++ enc_class riscv_enc_tail_jmp(iRegP jump_target) %{ ++ C2_MacroAssembler _masm(&cbuf); ++ Register target_reg = as_Register($jump_target$$reg); ++ // exception oop should be in x10 ++ // ret addr has been popped into ra ++ // callee expects it in x13 ++ __ mv(x13, ra); ++ __ jr(target_reg); ++ %} ++ ++ enc_class riscv_enc_rethrow() %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); ++ %} ++ ++ enc_class riscv_enc_ret() %{ ++ C2_MacroAssembler _masm(&cbuf); ++ __ ret(); ++ %} ++ ++%} ++ ++//----------FRAME-------------------------------------------------------------- ++// Definition of frame structure and management information. ++// ++// S T A C K L A Y O U T Allocators stack-slot number ++// | (to get allocators register number ++// G Owned by | | v add OptoReg::stack0()) ++// r CALLER | | ++// o | +--------+ pad to even-align allocators stack-slot ++// w V | pad0 | numbers; owned by CALLER ++// t -----------+--------+----> Matcher::_in_arg_limit, unaligned ++// h ^ | in | 5 ++// | | args | 4 Holes in incoming args owned by SELF ++// | | | | 3 ++// | | +--------+ ++// V | | old out| Empty on Intel, window on Sparc ++// | old |preserve| Must be even aligned. ++// | SP-+--------+----> Matcher::_old_SP, even aligned ++// | | in | 3 area for Intel ret address ++// Owned by |preserve| Empty on Sparc. ++// SELF +--------+ ++// | | pad2 | 2 pad to align old SP ++// | +--------+ 1 ++// | | locks | 0 ++// | +--------+----> OptoReg::stack0(), even aligned ++// | | pad1 | 11 pad to align new SP ++// | +--------+ ++// | | | 10 ++// | | spills | 9 spills ++// V | | 8 (pad0 slot for callee) ++// -----------+--------+----> Matcher::_out_arg_limit, unaligned ++// ^ | out | 7 ++// | | args | 6 Holes in outgoing args owned by CALLEE ++// Owned by +--------+ ++// CALLEE | new out| 6 Empty on Intel, window on Sparc ++// | new |preserve| Must be even-aligned. ++// | SP-+--------+----> Matcher::_new_SP, even aligned ++// | | | ++// ++// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is ++// known from SELF's arguments and the Java calling convention. ++// Region 6-7 is determined per call site. ++// Note 2: If the calling convention leaves holes in the incoming argument ++// area, those holes are owned by SELF. Holes in the outgoing area ++// are owned by the CALLEE. Holes should not be nessecary in the ++// incoming area, as the Java calling convention is completely under ++// the control of the AD file. Doubles can be sorted and packed to ++// avoid holes. Holes in the outgoing arguments may be nessecary for ++// varargs C calling conventions. ++// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is ++// even aligned with pad0 as needed. ++// Region 6 is even aligned. Region 6-7 is NOT even aligned; ++// (the latter is true on Intel but is it false on RISCV?) ++// region 6-11 is even aligned; it may be padded out more so that ++// the region from SP to FP meets the minimum stack alignment. ++// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack ++// alignment. Region 11, pad1, may be dynamically extended so that ++// SP meets the minimum alignment. ++ ++frame %{ ++ // These three registers define part of the calling convention ++ // between compiled code and the interpreter. ++ ++ // Inline Cache Register or methodOop for I2C. ++ inline_cache_reg(R31); ++ ++ // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] ++ cisc_spilling_operand_name(indOffset); ++ ++ // Number of stack slots consumed by locking an object ++ // generate Compile::sync_stack_slots ++ // VMRegImpl::slots_per_word = wordSize / stack_slot_size = 8 / 4 = 2 ++ sync_stack_slots(1 * VMRegImpl::slots_per_word); ++ ++ // Compiled code's Frame Pointer ++ frame_pointer(R2); ++ ++ // Interpreter stores its frame pointer in a register which is ++ // stored to the stack by I2CAdaptors. ++ // I2CAdaptors convert from interpreted java to compiled java. ++ interpreter_frame_pointer(R8); ++ ++ // Stack alignment requirement ++ stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) ++ ++ // Number of outgoing stack slots killed above the out_preserve_stack_slots ++ // for calls to C. Supports the var-args backing area for register parms. ++ varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes / BytesPerInt); ++ ++ // The after-PROLOG location of the return address. Location of ++ // return address specifies a type (REG or STACK) and a number ++ // representing the register number (i.e. - use a register name) or ++ // stack slot. ++ // Ret Addr is on stack in slot 0 if no locks or verification or alignment. ++ // Otherwise, it is above the locks and verification slot and alignment word ++ // TODO this may well be correct but need to check why that - 2 is there ++ // ppc port uses 0 but we definitely need to allow for fixed_slots ++ // which folds in the space used for monitors ++ return_addr(STACK - 2 + ++ align_up((Compile::current()->in_preserve_stack_slots() + ++ Compile::current()->fixed_slots()), ++ stack_alignment_in_slots())); ++ ++ // Location of compiled Java return values. Same as C for now. ++ return_value ++ %{ ++ assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, ++ "only return normal values"); ++ ++ static const int lo[Op_RegL + 1] = { // enum name ++ 0, // Op_Node ++ 0, // Op_Set ++ R10_num, // Op_RegN ++ R10_num, // Op_RegI ++ R10_num, // Op_RegP ++ F10_num, // Op_RegF ++ F10_num, // Op_RegD ++ R10_num // Op_RegL ++ }; ++ ++ static const int hi[Op_RegL + 1] = { // enum name ++ 0, // Op_Node ++ 0, // Op_Set ++ OptoReg::Bad, // Op_RegN ++ OptoReg::Bad, // Op_RegI ++ R10_H_num, // Op_RegP ++ OptoReg::Bad, // Op_RegF ++ F10_H_num, // Op_RegD ++ R10_H_num // Op_RegL ++ }; ++ ++ return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); ++ %} ++%} ++ ++//----------ATTRIBUTES--------------------------------------------------------- ++//----------Operand Attributes------------------------------------------------- ++op_attrib op_cost(1); // Required cost attribute ++ ++//----------Instruction Attributes--------------------------------------------- ++ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute ++ins_attrib ins_size(32); // Required size attribute (in bits) ++ins_attrib ins_short_branch(0); // Required flag: is this instruction ++ // a non-matching short branch variant ++ // of some long branch? ++ins_attrib ins_alignment(4); // Required alignment attribute (must ++ // be a power of 2) specifies the ++ // alignment that some part of the ++ // instruction (not necessarily the ++ // start) requires. If > 1, a ++ // compute_padding() function must be ++ // provided for the instruction ++ ++//----------OPERANDS----------------------------------------------------------- ++// Operand definitions must precede instruction definitions for correct parsing ++// in the ADLC because operands constitute user defined types which are used in ++// instruction definitions. ++ ++//----------Simple Operands---------------------------------------------------- ++ ++// Integer operands 32 bit ++// 32 bit immediate ++operand immI() ++%{ ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 32 bit zero ++operand immI0() ++%{ ++ predicate(n->get_int() == 0); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 32 bit unit increment ++operand immI_1() ++%{ ++ predicate(n->get_int() == 1); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 32 bit unit decrement ++operand immI_M1() ++%{ ++ predicate(n->get_int() == -1); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Unsigned Integer Immediate: 6-bit int, greater than 32 ++operand uimmI6_ge32() %{ ++ predicate(((unsigned int)(n->get_int()) < 64) && (n->get_int() >= 32)); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immI_le_4() ++%{ ++ predicate(n->get_int() <= 4); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immI_16() ++%{ ++ predicate(n->get_int() == 16); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immI_24() ++%{ ++ predicate(n->get_int() == 24); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immI_31() ++%{ ++ predicate(n->get_int() == 31); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immI_63() ++%{ ++ predicate(n->get_int() == 63); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 32 bit integer valid for add immediate ++operand immIAdd() ++%{ ++ predicate(Assembler::is_simm12((int64_t)n->get_int())); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 32 bit integer valid for sub immediate ++operand immISub() ++%{ ++ predicate(Assembler::is_simm12(-(int64_t)n->get_int())); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 5 bit signed value. ++operand immI5() ++%{ ++ predicate(n->get_int() <= 15 && n->get_int() >= -16); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 5 bit signed value (simm5) ++operand immL5() ++%{ ++ predicate(n->get_long() <= 15 && n->get_long() >= -16); ++ match(ConL); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Integer operands 64 bit ++// 64 bit immediate ++operand immL() ++%{ ++ match(ConL); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 64 bit zero ++operand immL0() ++%{ ++ predicate(n->get_long() == 0); ++ match(ConL); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Pointer operands ++// Pointer Immediate ++operand immP() ++%{ ++ match(ConP); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// NULL Pointer Immediate ++operand immP0() ++%{ ++ predicate(n->get_ptr() == 0); ++ match(ConP); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Pointer Immediate One ++// this is used in object initialization (initial object header) ++operand immP_1() ++%{ ++ predicate(n->get_ptr() == 1); ++ match(ConP); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Card Table Byte Map Base ++operand immByteMapBase() ++%{ ++ // Get base of card map ++ predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && ++ (CardTable::CardValue*)n->get_ptr() == ++ ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); ++ match(ConP); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Int Immediate: low 16-bit mask ++operand immI_16bits() ++%{ ++ predicate(n->get_int() == 0xFFFF); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immIpowerOf2() %{ ++ predicate(is_power_of_2((juint)(n->get_int()))); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Long Immediate: low 32-bit mask ++operand immL_32bits() ++%{ ++ predicate(n->get_long() == 0xFFFFFFFFL); ++ match(ConL); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 64 bit unit decrement ++operand immL_M1() ++%{ ++ predicate(n->get_long() == -1); ++ match(ConL); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++ ++// 32 bit offset of pc in thread anchor ++ ++operand immL_pc_off() ++%{ ++ predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + ++ in_bytes(JavaFrameAnchor::last_Java_pc_offset())); ++ match(ConL); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 64 bit integer valid for add immediate ++operand immLAdd() ++%{ ++ predicate(Assembler::is_simm12(n->get_long())); ++ match(ConL); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// 64 bit integer valid for sub immediate ++operand immLSub() ++%{ ++ predicate(Assembler::is_simm12(-(n->get_long()))); ++ match(ConL); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Narrow pointer operands ++// Narrow Pointer Immediate ++operand immN() ++%{ ++ match(ConN); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Narrow NULL Pointer Immediate ++operand immN0() ++%{ ++ predicate(n->get_narrowcon() == 0); ++ match(ConN); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immNKlass() ++%{ ++ match(ConNKlass); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Float and Double operands ++// Double Immediate ++operand immD() ++%{ ++ match(ConD); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Double Immediate: +0.0d ++operand immD0() ++%{ ++ predicate(jlong_cast(n->getd()) == 0); ++ match(ConD); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Float Immediate ++operand immF() ++%{ ++ match(ConF); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Float Immediate: +0.0f. ++operand immF0() ++%{ ++ predicate(jint_cast(n->getf()) == 0); ++ match(ConF); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immIOffset() ++%{ ++ predicate(Assembler::is_simm12(n->get_int())); ++ match(ConI); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++operand immLOffset() ++%{ ++ predicate(Assembler::is_simm12(n->get_long())); ++ match(ConL); ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Scale values ++operand immIScale() ++%{ ++ predicate(1 <= n->get_int() && (n->get_int() <= 3)); ++ match(ConI); ++ ++ op_cost(0); ++ format %{ %} ++ interface(CONST_INTER); ++%} ++ ++// Integer 32 bit Register Operands ++operand iRegI() ++%{ ++ constraint(ALLOC_IN_RC(any_reg32)); ++ match(RegI); ++ match(iRegINoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Integer 32 bit Register not Special ++operand iRegINoSp() ++%{ ++ constraint(ALLOC_IN_RC(no_special_reg32)); ++ match(RegI); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Register R10 only ++operand iRegI_R10() ++%{ ++ constraint(ALLOC_IN_RC(int_r10_reg)); ++ match(RegI); ++ match(iRegINoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Register R12 only ++operand iRegI_R12() ++%{ ++ constraint(ALLOC_IN_RC(int_r12_reg)); ++ match(RegI); ++ match(iRegINoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Register R13 only ++operand iRegI_R13() ++%{ ++ constraint(ALLOC_IN_RC(int_r13_reg)); ++ match(RegI); ++ match(iRegINoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Register R14 only ++operand iRegI_R14() ++%{ ++ constraint(ALLOC_IN_RC(int_r14_reg)); ++ match(RegI); ++ match(iRegINoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Integer 64 bit Register Operands ++operand iRegL() ++%{ ++ constraint(ALLOC_IN_RC(any_reg)); ++ match(RegL); ++ match(iRegLNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Integer 64 bit Register not Special ++operand iRegLNoSp() ++%{ ++ constraint(ALLOC_IN_RC(no_special_reg)); ++ match(RegL); ++ match(iRegL_R10); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Long 64 bit Register R28 only ++operand iRegL_R28() ++%{ ++ constraint(ALLOC_IN_RC(r28_reg)); ++ match(RegL); ++ match(iRegLNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Long 64 bit Register R29 only ++operand iRegL_R29() ++%{ ++ constraint(ALLOC_IN_RC(r29_reg)); ++ match(RegL); ++ match(iRegLNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Long 64 bit Register R30 only ++operand iRegL_R30() ++%{ ++ constraint(ALLOC_IN_RC(r30_reg)); ++ match(RegL); ++ match(iRegLNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Pointer Register Operands ++// Pointer Register ++operand iRegP() ++%{ ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(RegP); ++ match(iRegPNoSp); ++ match(iRegP_R10); ++ match(iRegP_R15); ++ match(javaThread_RegP); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Pointer 64 bit Register not Special ++operand iRegPNoSp() ++%{ ++ constraint(ALLOC_IN_RC(no_special_ptr_reg)); ++ match(RegP); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand iRegP_R10() ++%{ ++ constraint(ALLOC_IN_RC(r10_reg)); ++ match(RegP); ++ // match(iRegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Pointer 64 bit Register R11 only ++operand iRegP_R11() ++%{ ++ constraint(ALLOC_IN_RC(r11_reg)); ++ match(RegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand iRegP_R12() ++%{ ++ constraint(ALLOC_IN_RC(r12_reg)); ++ match(RegP); ++ // match(iRegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Pointer 64 bit Register R13 only ++operand iRegP_R13() ++%{ ++ constraint(ALLOC_IN_RC(r13_reg)); ++ match(RegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand iRegP_R14() ++%{ ++ constraint(ALLOC_IN_RC(r14_reg)); ++ match(RegP); ++ // match(iRegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand iRegP_R15() ++%{ ++ constraint(ALLOC_IN_RC(r15_reg)); ++ match(RegP); ++ // match(iRegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand iRegP_R16() ++%{ ++ constraint(ALLOC_IN_RC(r16_reg)); ++ match(RegP); ++ // match(iRegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Pointer 64 bit Register R28 only ++operand iRegP_R28() ++%{ ++ constraint(ALLOC_IN_RC(r28_reg)); ++ match(RegP); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Pointer Register Operands ++// Narrow Pointer Register ++operand iRegN() ++%{ ++ constraint(ALLOC_IN_RC(any_reg32)); ++ match(RegN); ++ match(iRegNNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Integer 64 bit Register not Special ++operand iRegNNoSp() ++%{ ++ constraint(ALLOC_IN_RC(no_special_reg32)); ++ match(RegN); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// heap base register -- used for encoding immN0 ++operand iRegIHeapbase() ++%{ ++ constraint(ALLOC_IN_RC(heapbase_reg)); ++ match(RegI); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Long 64 bit Register R10 only ++operand iRegL_R10() ++%{ ++ constraint(ALLOC_IN_RC(r10_reg)); ++ match(RegL); ++ match(iRegLNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Float Register ++// Float register operands ++operand fRegF() ++%{ ++ constraint(ALLOC_IN_RC(float_reg)); ++ match(RegF); ++ ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Double Register ++// Double register operands ++operand fRegD() ++%{ ++ constraint(ALLOC_IN_RC(double_reg)); ++ match(RegD); ++ ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Generic vector class. This will be used for ++// all vector operands. ++operand vReg() ++%{ ++ constraint(ALLOC_IN_RC(vectora_reg)); ++ match(VecA); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand vReg_V1() ++%{ ++ constraint(ALLOC_IN_RC(v1_reg)); ++ match(VecA); ++ match(vReg); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand vReg_V2() ++%{ ++ constraint(ALLOC_IN_RC(v2_reg)); ++ match(VecA); ++ match(vReg); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand vReg_V3() ++%{ ++ constraint(ALLOC_IN_RC(v3_reg)); ++ match(VecA); ++ match(vReg); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand vReg_V4() ++%{ ++ constraint(ALLOC_IN_RC(v4_reg)); ++ match(VecA); ++ match(vReg); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++operand vReg_V5() ++%{ ++ constraint(ALLOC_IN_RC(v5_reg)); ++ match(VecA); ++ match(vReg); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++// Java Thread Register ++operand javaThread_RegP(iRegP reg) ++%{ ++ constraint(ALLOC_IN_RC(java_thread_reg)); // java_thread_reg ++ match(reg); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++//----------Memory Operands---------------------------------------------------- ++// RISCV has only base_plus_offset and literal address mode, so no need to use ++// index and scale. Here set index as 0xffffffff and scale as 0x0. ++operand indirect(iRegP reg) ++%{ ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(reg); ++ op_cost(0); ++ format %{ "[$reg]" %} ++ interface(MEMORY_INTER) %{ ++ base($reg); ++ index(0xffffffff); ++ scale(0x0); ++ disp(0x0); ++ %} ++%} ++ ++operand indOffI(iRegP reg, immIOffset off) ++%{ ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(AddP reg off); ++ op_cost(0); ++ format %{ "[$reg, $off]" %} ++ interface(MEMORY_INTER) %{ ++ base($reg); ++ index(0xffffffff); ++ scale(0x0); ++ disp($off); ++ %} ++%} ++ ++operand indOffL(iRegP reg, immLOffset off) ++%{ ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(AddP reg off); ++ op_cost(0); ++ format %{ "[$reg, $off]" %} ++ interface(MEMORY_INTER) %{ ++ base($reg); ++ index(0xffffffff); ++ scale(0x0); ++ disp($off); ++ %} ++%} ++ ++operand indirectN(iRegN reg) ++%{ ++ predicate(CompressedOops::shift() == 0); ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(DecodeN reg); ++ op_cost(0); ++ format %{ "[$reg]\t# narrow" %} ++ interface(MEMORY_INTER) %{ ++ base($reg); ++ index(0xffffffff); ++ scale(0x0); ++ disp(0x0); ++ %} ++%} ++ ++operand indOffIN(iRegN reg, immIOffset off) ++%{ ++ predicate(CompressedOops::shift() == 0); ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(AddP (DecodeN reg) off); ++ op_cost(0); ++ format %{ "[$reg, $off]\t# narrow" %} ++ interface(MEMORY_INTER) %{ ++ base($reg); ++ index(0xffffffff); ++ scale(0x0); ++ disp($off); ++ %} ++%} ++ ++operand indOffLN(iRegN reg, immLOffset off) ++%{ ++ predicate(CompressedOops::shift() == 0); ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(AddP (DecodeN reg) off); ++ op_cost(0); ++ format %{ "[$reg, $off]\t# narrow" %} ++ interface(MEMORY_INTER) %{ ++ base($reg); ++ index(0xffffffff); ++ scale(0x0); ++ disp($off); ++ %} ++%} ++ ++// RISCV opto stubs need to write to the pc slot in the thread anchor ++operand thread_anchor_pc(javaThread_RegP reg, immL_pc_off off) ++%{ ++ constraint(ALLOC_IN_RC(ptr_reg)); ++ match(AddP reg off); ++ op_cost(0); ++ format %{ "[$reg, $off]" %} ++ interface(MEMORY_INTER) %{ ++ base($reg); ++ index(0xffffffff); ++ scale(0x0); ++ disp($off); ++ %} ++%} ++ ++ ++//----------Special Memory Operands-------------------------------------------- ++// Stack Slot Operand - This operand is used for loading and storing temporary ++// values on the stack where a match requires a value to ++// flow through memory. ++operand stackSlotI(sRegI reg) ++%{ ++ constraint(ALLOC_IN_RC(stack_slots)); ++ // No match rule because this operand is only generated in matching ++ // match(RegI); ++ format %{ "[$reg]" %} ++ interface(MEMORY_INTER) %{ ++ base(0x02); // RSP ++ index(0xffffffff); // No Index ++ scale(0x0); // No Scale ++ disp($reg); // Stack Offset ++ %} ++%} ++ ++operand stackSlotF(sRegF reg) ++%{ ++ constraint(ALLOC_IN_RC(stack_slots)); ++ // No match rule because this operand is only generated in matching ++ // match(RegF); ++ format %{ "[$reg]" %} ++ interface(MEMORY_INTER) %{ ++ base(0x02); // RSP ++ index(0xffffffff); // No Index ++ scale(0x0); // No Scale ++ disp($reg); // Stack Offset ++ %} ++%} ++ ++operand stackSlotD(sRegD reg) ++%{ ++ constraint(ALLOC_IN_RC(stack_slots)); ++ // No match rule because this operand is only generated in matching ++ // match(RegD); ++ format %{ "[$reg]" %} ++ interface(MEMORY_INTER) %{ ++ base(0x02); // RSP ++ index(0xffffffff); // No Index ++ scale(0x0); // No Scale ++ disp($reg); // Stack Offset ++ %} ++%} ++ ++operand stackSlotL(sRegL reg) ++%{ ++ constraint(ALLOC_IN_RC(stack_slots)); ++ // No match rule because this operand is only generated in matching ++ // match(RegL); ++ format %{ "[$reg]" %} ++ interface(MEMORY_INTER) %{ ++ base(0x02); // RSP ++ index(0xffffffff); // No Index ++ scale(0x0); // No Scale ++ disp($reg); // Stack Offset ++ %} ++%} ++ ++// Special operand allowing long args to int ops to be truncated for free ++ ++operand iRegL2I(iRegL reg) %{ ++ ++ op_cost(0); ++ ++ match(ConvL2I reg); ++ ++ format %{ "l2i($reg)" %} ++ ++ interface(REG_INTER) ++%} ++ ++ ++// Comparison Operands ++// NOTE: Label is a predefined operand which should not be redefined in ++// the AD file. It is generically handled within the ADLC. ++ ++//----------Conditional Branch Operands---------------------------------------- ++// Comparison Op - This is the operation of the comparison, and is limited to ++// the following set of codes: ++// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) ++// ++// Other attributes of the comparison, such as unsignedness, are specified ++// by the comparison instruction that sets a condition code flags register. ++// That result is represented by a flags operand whose subtype is appropriate ++// to the unsignedness (etc.) of the comparison. ++// ++// Later, the instruction which matches both the Comparison Op (a Bool) and ++// the flags (produced by the Cmp) specifies the coding of the comparison op ++// by matching a specific subtype of Bool operand below, such as cmpOpU. ++ ++ ++// used for signed integral comparisons and fp comparisons ++operand cmpOp() ++%{ ++ match(Bool); ++ ++ format %{ "" %} ++ ++ // the values in interface derives from struct BoolTest::mask ++ interface(COND_INTER) %{ ++ equal(0x0, "eq"); ++ greater(0x1, "gt"); ++ overflow(0x2, "overflow"); ++ less(0x3, "lt"); ++ not_equal(0x4, "ne"); ++ less_equal(0x5, "le"); ++ no_overflow(0x6, "no_overflow"); ++ greater_equal(0x7, "ge"); ++ %} ++%} ++ ++// used for unsigned integral comparisons ++operand cmpOpU() ++%{ ++ match(Bool); ++ ++ format %{ "" %} ++ // the values in interface derives from struct BoolTest::mask ++ interface(COND_INTER) %{ ++ equal(0x0, "eq"); ++ greater(0x1, "gtu"); ++ overflow(0x2, "overflow"); ++ less(0x3, "ltu"); ++ not_equal(0x4, "ne"); ++ less_equal(0x5, "leu"); ++ no_overflow(0x6, "no_overflow"); ++ greater_equal(0x7, "geu"); ++ %} ++%} ++ ++// used for certain integral comparisons which can be ++// converted to bxx instructions ++operand cmpOpEqNe() ++%{ ++ match(Bool); ++ op_cost(0); ++ predicate(n->as_Bool()->_test._test == BoolTest::ne || ++ n->as_Bool()->_test._test == BoolTest::eq); ++ ++ format %{ "" %} ++ interface(COND_INTER) %{ ++ equal(0x0, "eq"); ++ greater(0x1, "gt"); ++ overflow(0x2, "overflow"); ++ less(0x3, "lt"); ++ not_equal(0x4, "ne"); ++ less_equal(0x5, "le"); ++ no_overflow(0x6, "no_overflow"); ++ greater_equal(0x7, "ge"); ++ %} ++%} ++ ++operand cmpOpULtGe() ++%{ ++ match(Bool); ++ op_cost(0); ++ predicate(n->as_Bool()->_test._test == BoolTest::lt || ++ n->as_Bool()->_test._test == BoolTest::ge); ++ ++ format %{ "" %} ++ interface(COND_INTER) %{ ++ equal(0x0, "eq"); ++ greater(0x1, "gtu"); ++ overflow(0x2, "overflow"); ++ less(0x3, "ltu"); ++ not_equal(0x4, "ne"); ++ less_equal(0x5, "leu"); ++ no_overflow(0x6, "no_overflow"); ++ greater_equal(0x7, "geu"); ++ %} ++%} ++ ++operand cmpOpUEqNeLeGt() ++%{ ++ match(Bool); ++ op_cost(0); ++ predicate(n->as_Bool()->_test._test == BoolTest::ne || ++ n->as_Bool()->_test._test == BoolTest::eq || ++ n->as_Bool()->_test._test == BoolTest::le || ++ n->as_Bool()->_test._test == BoolTest::gt); ++ ++ format %{ "" %} ++ interface(COND_INTER) %{ ++ equal(0x0, "eq"); ++ greater(0x1, "gtu"); ++ overflow(0x2, "overflow"); ++ less(0x3, "ltu"); ++ not_equal(0x4, "ne"); ++ less_equal(0x5, "leu"); ++ no_overflow(0x6, "no_overflow"); ++ greater_equal(0x7, "geu"); ++ %} ++%} ++ ++ ++// Flags register, used as output of compare logic ++operand rFlagsReg() ++%{ ++ constraint(ALLOC_IN_RC(reg_flags)); ++ match(RegFlags); ++ ++ op_cost(0); ++ format %{ "RFLAGS" %} ++ interface(REG_INTER); ++%} ++ ++// Special Registers ++ ++// Method Register ++operand inline_cache_RegP(iRegP reg) ++%{ ++ constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg ++ match(reg); ++ match(iRegPNoSp); ++ op_cost(0); ++ format %{ %} ++ interface(REG_INTER); ++%} ++ ++//----------OPERAND CLASSES---------------------------------------------------- ++// Operand Classes are groups of operands that are used as to simplify ++// instruction definitions by not requiring the AD writer to specify ++// separate instructions for every form of operand when the ++// instruction accepts multiple operand types with the same basic ++// encoding and format. The classic case of this is memory operands. ++ ++// memory is used to define read/write location for load/store ++// instruction defs. we can turn a memory op into an Address ++ ++opclass memory(indirect, indOffI, indOffL, indirectN, indOffIN, indOffLN); ++ ++// iRegIorL2I is used for src inputs in rules for 32 bit int (I) ++// operations. it allows the src to be either an iRegI or a (ConvL2I ++// iRegL). in the latter case the l2i normally planted for a ConvL2I ++// can be elided because the 32-bit instruction will just employ the ++// lower 32 bits anyway. ++// ++// n.b. this does not elide all L2I conversions. if the truncated ++// value is consumed by more than one operation then the ConvL2I ++// cannot be bundled into the consuming nodes so an l2i gets planted ++// (actually an addiw $dst, $src, 0) and the downstream instructions ++// consume the result of the L2I as an iRegI input. That's a shame since ++// the addiw is actually redundant but its not too costly. ++ ++opclass iRegIorL2I(iRegI, iRegL2I); ++opclass iRegIorL(iRegI, iRegL); ++opclass iRegNorP(iRegN, iRegP); ++opclass iRegILNP(iRegI, iRegL, iRegN, iRegP); ++opclass iRegILNPNoSp(iRegINoSp, iRegLNoSp, iRegNNoSp, iRegPNoSp); ++opclass immIorL(immI, immL); ++ ++//----------PIPELINE----------------------------------------------------------- ++// Rules which define the behavior of the target architectures pipeline. ++ ++// For specific pipelines, e.g. generic RISC-V, define the stages of that pipeline ++//pipe_desc(ID, EX, MEM, WR); ++#define ID S0 ++#define EX S1 ++#define MEM S2 ++#define WR S3 ++ ++// Integer ALU reg operation ++pipeline %{ ++ ++attributes %{ ++ // RISC-V instructions are of fixed length ++ fixed_size_instructions; // Fixed size instructions TODO does ++ max_instructions_per_bundle = 2; // Generic RISC-V 1, Sifive Series 7 2 ++ // RISC-V instructions come in 32-bit word units ++ instruction_unit_size = 4; // An instruction is 4 bytes long ++ instruction_fetch_unit_size = 64; // The processor fetches one line ++ instruction_fetch_units = 1; // of 64 bytes ++ ++ // List of nop instructions ++ nops( MachNop ); ++%} ++ ++// We don't use an actual pipeline model so don't care about resources ++// or description. we do use pipeline classes to introduce fixed ++// latencies ++ ++//----------RESOURCES---------------------------------------------------------- ++// Resources are the functional units available to the machine ++ ++// Generic RISC-V pipeline ++// 1 decoder ++// 1 instruction decoded per cycle ++// 1 load/store ops per cycle, 1 branch, 1 FPU ++// 1 mul, 1 div ++ ++resources ( DECODE, ++ ALU, ++ MUL, ++ DIV, ++ BRANCH, ++ LDST, ++ FPU); ++ ++//----------PIPELINE DESCRIPTION----------------------------------------------- ++// Pipeline Description specifies the stages in the machine's pipeline ++ ++// Define the pipeline as a generic 6 stage pipeline ++pipe_desc(S0, S1, S2, S3, S4, S5); ++ ++//----------PIPELINE CLASSES--------------------------------------------------- ++// Pipeline Classes describe the stages in which input and output are ++// referenced by the hardware pipeline. ++ ++pipe_class fp_dop_reg_reg_s(fRegF dst, fRegF src1, fRegF src2) ++%{ ++ single_instruction; ++ src1 : S1(read); ++ src2 : S2(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_dop_reg_reg_d(fRegD dst, fRegD src1, fRegD src2) ++%{ ++ src1 : S1(read); ++ src2 : S2(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_uop_s(fRegF dst, fRegF src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_uop_d(fRegD dst, fRegD src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_d2f(fRegF dst, fRegD src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_f2d(fRegD dst, fRegF src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_f2i(iRegINoSp dst, fRegF src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_f2l(iRegLNoSp dst, fRegF src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_i2f(fRegF dst, iRegIorL2I src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_l2f(fRegF dst, iRegL src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_d2i(iRegINoSp dst, fRegD src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_d2l(iRegLNoSp dst, fRegD src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_i2d(fRegD dst, iRegIorL2I src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_l2d(fRegD dst, iRegIorL2I src) ++%{ ++ single_instruction; ++ src : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_div_s(fRegF dst, fRegF src1, fRegF src2) ++%{ ++ single_instruction; ++ src1 : S1(read); ++ src2 : S2(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_div_d(fRegD dst, fRegD src1, fRegD src2) ++%{ ++ single_instruction; ++ src1 : S1(read); ++ src2 : S2(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_sqrt_s(fRegF dst, fRegF src1, fRegF src2) ++%{ ++ single_instruction; ++ src1 : S1(read); ++ src2 : S2(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_sqrt_d(fRegD dst, fRegD src1, fRegD src2) ++%{ ++ single_instruction; ++ src1 : S1(read); ++ src2 : S2(read); ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_load_constant_s(fRegF dst) ++%{ ++ single_instruction; ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_load_constant_d(fRegD dst) ++%{ ++ single_instruction; ++ dst : S5(write); ++ DECODE : ID; ++ FPU : S5; ++%} ++ ++pipe_class fp_load_mem_s(fRegF dst, memory mem) ++%{ ++ single_instruction; ++ mem : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++pipe_class fp_load_mem_d(fRegD dst, memory mem) ++%{ ++ single_instruction; ++ mem : S1(read); ++ dst : S5(write); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++pipe_class fp_store_reg_s(fRegF src, memory mem) ++%{ ++ single_instruction; ++ src : S1(read); ++ mem : S5(write); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++pipe_class fp_store_reg_d(fRegD src, memory mem) ++%{ ++ single_instruction; ++ src : S1(read); ++ mem : S5(write); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++//------- Integer ALU operations -------------------------- ++ ++// Integer ALU reg-reg operation ++// Operands needs in ID, result generated in EX ++// E.g. ADD Rd, Rs1, Rs2 ++pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) ++%{ ++ single_instruction; ++ dst : EX(write); ++ src1 : ID(read); ++ src2 : ID(read); ++ DECODE : ID; ++ ALU : EX; ++%} ++ ++// Integer ALU reg operation with constant shift ++// E.g. SLLI Rd, Rs1, #shift ++pipe_class ialu_reg_shift(iRegI dst, iRegI src1) ++%{ ++ single_instruction; ++ dst : EX(write); ++ src1 : ID(read); ++ DECODE : ID; ++ ALU : EX; ++%} ++ ++// Integer ALU reg-reg operation with variable shift ++// both operands must be available in ID ++// E.g. SLL Rd, Rs1, Rs2 ++pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) ++%{ ++ single_instruction; ++ dst : EX(write); ++ src1 : ID(read); ++ src2 : ID(read); ++ DECODE : ID; ++ ALU : EX; ++%} ++ ++// Integer ALU reg operation ++// E.g. NEG Rd, Rs2 ++pipe_class ialu_reg(iRegI dst, iRegI src) ++%{ ++ single_instruction; ++ dst : EX(write); ++ src : ID(read); ++ DECODE : ID; ++ ALU : EX; ++%} ++ ++// Integer ALU reg immediate operation ++// E.g. ADDI Rd, Rs1, #imm ++pipe_class ialu_reg_imm(iRegI dst, iRegI src1) ++%{ ++ single_instruction; ++ dst : EX(write); ++ src1 : ID(read); ++ DECODE : ID; ++ ALU : EX; ++%} ++ ++// Integer ALU immediate operation (no source operands) ++// E.g. LI Rd, #imm ++pipe_class ialu_imm(iRegI dst) ++%{ ++ single_instruction; ++ dst : EX(write); ++ DECODE : ID; ++ ALU : EX; ++%} ++ ++//------- Multiply pipeline operations -------------------- ++ ++// Multiply reg-reg ++// E.g. MULW Rd, Rs1, Rs2 ++pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) ++%{ ++ single_instruction; ++ dst : WR(write); ++ src1 : ID(read); ++ src2 : ID(read); ++ DECODE : ID; ++ MUL : WR; ++%} ++ ++// E.g. MUL RD, Rs1, Rs2 ++pipe_class lmul_reg_reg(iRegL dst, iRegL src1, iRegL src2) ++%{ ++ single_instruction; ++ fixed_latency(3); // Maximum latency for 64 bit mul ++ dst : WR(write); ++ src1 : ID(read); ++ src2 : ID(read); ++ DECODE : ID; ++ MUL : WR; ++%} ++ ++//------- Divide pipeline operations -------------------- ++ ++// E.g. DIVW Rd, Rs1, Rs2 ++pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) ++%{ ++ single_instruction; ++ fixed_latency(8); // Maximum latency for 32 bit divide ++ dst : WR(write); ++ src1 : ID(read); ++ src2 : ID(read); ++ DECODE : ID; ++ DIV : WR; ++%} ++ ++// E.g. DIV RD, Rs1, Rs2 ++pipe_class ldiv_reg_reg(iRegL dst, iRegL src1, iRegL src2) ++%{ ++ single_instruction; ++ fixed_latency(16); // Maximum latency for 64 bit divide ++ dst : WR(write); ++ src1 : ID(read); ++ src2 : ID(read); ++ DECODE : ID; ++ DIV : WR; ++%} ++ ++//------- Load pipeline operations ------------------------ ++ ++// Load - reg, mem ++// E.g. LA Rd, mem ++pipe_class iload_reg_mem(iRegI dst, memory mem) ++%{ ++ single_instruction; ++ dst : WR(write); ++ mem : ID(read); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++// Load - reg, reg ++// E.g. LD Rd, Rs ++pipe_class iload_reg_reg(iRegI dst, iRegI src) ++%{ ++ single_instruction; ++ dst : WR(write); ++ src : ID(read); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++//------- Store pipeline operations ----------------------- ++ ++// Store - zr, mem ++// E.g. SD zr, mem ++pipe_class istore_mem(memory mem) ++%{ ++ single_instruction; ++ mem : ID(read); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++// Store - reg, mem ++// E.g. SD Rs, mem ++pipe_class istore_reg_mem(iRegI src, memory mem) ++%{ ++ single_instruction; ++ mem : ID(read); ++ src : EX(read); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++// Store - reg, reg ++// E.g. SD Rs2, Rs1 ++pipe_class istore_reg_reg(iRegI dst, iRegI src) ++%{ ++ single_instruction; ++ dst : ID(read); ++ src : EX(read); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++//------- Control transfer pipeline operations ------------ ++ ++// Branch ++pipe_class pipe_branch() ++%{ ++ single_instruction; ++ DECODE : ID; ++ BRANCH : EX; ++%} ++ ++// Branch ++pipe_class pipe_branch_reg(iRegI src) ++%{ ++ single_instruction; ++ src : ID(read); ++ DECODE : ID; ++ BRANCH : EX; ++%} ++ ++// Compare & Branch ++// E.g. BEQ Rs1, Rs2, L ++pipe_class pipe_cmp_branch(iRegI src1, iRegI src2) ++%{ ++ single_instruction; ++ src1 : ID(read); ++ src2 : ID(read); ++ DECODE : ID; ++ BRANCH : EX; ++%} ++ ++// E.g. BEQZ Rs, L ++pipe_class pipe_cmpz_branch(iRegI src) ++%{ ++ single_instruction; ++ src : ID(read); ++ DECODE : ID; ++ BRANCH : EX; ++%} ++ ++//------- Synchronisation operations ---------------------- ++// Any operation requiring serialization ++// E.g. FENCE/Atomic Ops/Load Acquire/Store Release ++pipe_class pipe_serial() ++%{ ++ single_instruction; ++ force_serialization; ++ fixed_latency(16); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++pipe_class pipe_slow() ++%{ ++ instruction_count(10); ++ multiple_bundles; ++ force_serialization; ++ fixed_latency(16); ++ DECODE : ID; ++ LDST : MEM; ++%} ++ ++// Empty pipeline class ++pipe_class pipe_class_empty() ++%{ ++ single_instruction; ++ fixed_latency(0); ++%} ++ ++// Default pipeline class. ++pipe_class pipe_class_default() ++%{ ++ single_instruction; ++ fixed_latency(2); ++%} ++ ++// Pipeline class for compares. ++pipe_class pipe_class_compare() ++%{ ++ single_instruction; ++ fixed_latency(16); ++%} ++ ++// Pipeline class for memory operations. ++pipe_class pipe_class_memory() ++%{ ++ single_instruction; ++ fixed_latency(16); ++%} ++ ++// Pipeline class for call. ++pipe_class pipe_class_call() ++%{ ++ single_instruction; ++ fixed_latency(100); ++%} ++ ++// Define the class for the Nop node. ++define %{ ++ MachNop = pipe_class_empty; ++%} ++%} ++//----------INSTRUCTIONS------------------------------------------------------- ++// ++// match -- States which machine-independent subtree may be replaced ++// by this instruction. ++// ins_cost -- The estimated cost of this instruction is used by instruction ++// selection to identify a minimum cost tree of machine ++// instructions that matches a tree of machine-independent ++// instructions. ++// format -- A string providing the disassembly for this instruction. ++// The value of an instruction's operand may be inserted ++// by referring to it with a '$' prefix. ++// opcode -- Three instruction opcodes may be provided. These are referred ++// to within an encode class as $primary, $secondary, and $tertiary ++// rrspectively. The primary opcode is commonly used to ++// indicate the type of machine instruction, while secondary ++// and tertiary are often used for prefix options or addressing ++// modes. ++// ins_encode -- A list of encode classes with parameters. The encode class ++// name must have been defined in an 'enc_class' specification ++// in the encode section of the architecture description. ++ ++// ============================================================================ ++// Memory (Load/Store) Instructions ++ ++// Load Instructions ++ ++// Load Byte (8 bit signed) ++instruct loadB(iRegINoSp dst, memory mem) ++%{ ++ match(Set dst (LoadB mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lb $dst, $mem\t# byte, #@loadB" %} ++ ++ ins_encode %{ ++ __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Byte (8 bit signed) into long ++instruct loadB2L(iRegLNoSp dst, memory mem) ++%{ ++ match(Set dst (ConvI2L (LoadB mem))); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lb $dst, $mem\t# byte, #@loadB2L" %} ++ ++ ins_encode %{ ++ __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Byte (8 bit unsigned) ++instruct loadUB(iRegINoSp dst, memory mem) ++%{ ++ match(Set dst (LoadUB mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lbu $dst, $mem\t# byte, #@loadUB" %} ++ ++ ins_encode %{ ++ __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Byte (8 bit unsigned) into long ++instruct loadUB2L(iRegLNoSp dst, memory mem) ++%{ ++ match(Set dst (ConvI2L (LoadUB mem))); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lbu $dst, $mem\t# byte, #@loadUB2L" %} ++ ++ ins_encode %{ ++ __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Short (16 bit signed) ++instruct loadS(iRegINoSp dst, memory mem) ++%{ ++ match(Set dst (LoadS mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lh $dst, $mem\t# short, #@loadS" %} ++ ++ ins_encode %{ ++ __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Short (16 bit signed) into long ++instruct loadS2L(iRegLNoSp dst, memory mem) ++%{ ++ match(Set dst (ConvI2L (LoadS mem))); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lh $dst, $mem\t# short, #@loadS2L" %} ++ ++ ins_encode %{ ++ __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Char (16 bit unsigned) ++instruct loadUS(iRegINoSp dst, memory mem) ++%{ ++ match(Set dst (LoadUS mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lhu $dst, $mem\t# short, #@loadUS" %} ++ ++ ins_encode %{ ++ __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Short/Char (16 bit unsigned) into long ++instruct loadUS2L(iRegLNoSp dst, memory mem) ++%{ ++ match(Set dst (ConvI2L (LoadUS mem))); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lhu $dst, $mem\t# short, #@loadUS2L" %} ++ ++ ins_encode %{ ++ __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Integer (32 bit signed) ++instruct loadI(iRegINoSp dst, memory mem) ++%{ ++ match(Set dst (LoadI mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lw $dst, $mem\t# int, #@loadI" %} ++ ++ ins_encode %{ ++ __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Integer (32 bit signed) into long ++instruct loadI2L(iRegLNoSp dst, memory mem) ++%{ ++ match(Set dst (ConvI2L (LoadI mem))); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lw $dst, $mem\t# int, #@loadI2L" %} ++ ++ ins_encode %{ ++ __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Integer (32 bit unsigned) into long ++instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) ++%{ ++ match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lwu $dst, $mem\t# int, #@loadUI2L" %} ++ ++ ins_encode %{ ++ __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Long (64 bit signed) ++instruct loadL(iRegLNoSp dst, memory mem) ++%{ ++ match(Set dst (LoadL mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "ld $dst, $mem\t# int, #@loadL" %} ++ ++ ins_encode %{ ++ __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Range ++instruct loadRange(iRegINoSp dst, memory mem) ++%{ ++ match(Set dst (LoadRange mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lwu $dst, $mem\t# range, #@loadRange" %} ++ ++ ins_encode %{ ++ __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Pointer ++instruct loadP(iRegPNoSp dst, memory mem) ++%{ ++ match(Set dst (LoadP mem)); ++ predicate(n->as_Load()->barrier_data() == 0); ++ ++ ins_cost(LOAD_COST); ++ format %{ "ld $dst, $mem\t# ptr, #@loadP" %} ++ ++ ins_encode %{ ++ __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Compressed Pointer ++instruct loadN(iRegNNoSp dst, memory mem) ++%{ ++ match(Set dst (LoadN mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lwu $dst, $mem\t# loadN, compressed ptr, #@loadN" %} ++ ++ ins_encode %{ ++ __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Klass Pointer ++instruct loadKlass(iRegPNoSp dst, memory mem) ++%{ ++ match(Set dst (LoadKlass mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "ld $dst, $mem\t# class, #@loadKlass" %} ++ ++ ins_encode %{ ++ __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Narrow Klass Pointer ++instruct loadNKlass(iRegNNoSp dst, memory mem) ++%{ ++ match(Set dst (LoadNKlass mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "lwu $dst, $mem\t# loadNKlass, compressed class ptr, #@loadNKlass" %} ++ ++ ins_encode %{ ++ __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_mem); ++%} ++ ++// Load Float ++instruct loadF(fRegF dst, memory mem) ++%{ ++ match(Set dst (LoadF mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "flw $dst, $mem\t# float, #@loadF" %} ++ ++ ins_encode %{ ++ __ flw(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(fp_load_mem_s); ++%} ++ ++// Load Double ++instruct loadD(fRegD dst, memory mem) ++%{ ++ match(Set dst (LoadD mem)); ++ ++ ins_cost(LOAD_COST); ++ format %{ "fld $dst, $mem\t# double, #@loadD" %} ++ ++ ins_encode %{ ++ __ fld(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(fp_load_mem_d); ++%} ++ ++// Load Int Constant ++instruct loadConI(iRegINoSp dst, immI src) ++%{ ++ match(Set dst src); ++ ++ ins_cost(ALU_COST); ++ format %{ "li $dst, $src\t# int, #@loadConI" %} ++ ++ ins_encode(riscv_enc_li_imm(dst, src)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Long Constant ++instruct loadConL(iRegLNoSp dst, immL src) ++%{ ++ match(Set dst src); ++ ++ ins_cost(ALU_COST); ++ format %{ "li $dst, $src\t# long, #@loadConL" %} ++ ++ ins_encode(riscv_enc_li_imm(dst, src)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Pointer Constant ++instruct loadConP(iRegPNoSp dst, immP con) ++%{ ++ match(Set dst con); ++ ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $con\t# ptr, #@loadConP" %} ++ ++ ins_encode(riscv_enc_mov_p(dst, con)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Null Pointer Constant ++instruct loadConP0(iRegPNoSp dst, immP0 con) ++%{ ++ match(Set dst con); ++ ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $con\t# NULL ptr, #@loadConP0" %} ++ ++ ins_encode(riscv_enc_mov_zero(dst)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Pointer Constant One ++instruct loadConP1(iRegPNoSp dst, immP_1 con) ++%{ ++ match(Set dst con); ++ ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $con\t# load ptr constant one, #@loadConP1" %} ++ ++ ins_encode(riscv_enc_mov_p1(dst)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Byte Map Base Constant ++instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) ++%{ ++ match(Set dst con); ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $con\t# Byte Map Base, #@loadByteMapBase" %} ++ ++ ins_encode(riscv_enc_mov_byte_map_base(dst)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Narrow Pointer Constant ++instruct loadConN(iRegNNoSp dst, immN con) ++%{ ++ match(Set dst con); ++ ++ ins_cost(ALU_COST * 4); ++ format %{ "mv $dst, $con\t# compressed ptr, #@loadConN" %} ++ ++ ins_encode(riscv_enc_mov_n(dst, con)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Narrow Null Pointer Constant ++instruct loadConN0(iRegNNoSp dst, immN0 con) ++%{ ++ match(Set dst con); ++ ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $con\t# compressed NULL ptr, #@loadConN0" %} ++ ++ ins_encode(riscv_enc_mov_zero(dst)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Narrow Klass Constant ++instruct loadConNKlass(iRegNNoSp dst, immNKlass con) ++%{ ++ match(Set dst con); ++ ++ ins_cost(ALU_COST * 6); ++ format %{ "mv $dst, $con\t# compressed klass ptr, #@loadConNKlass" %} ++ ++ ins_encode(riscv_enc_mov_nk(dst, con)); ++ ++ ins_pipe(ialu_imm); ++%} ++ ++// Load Float Constant ++instruct loadConF(fRegF dst, immF con) %{ ++ match(Set dst con); ++ ++ ins_cost(LOAD_COST); ++ format %{ ++ "flw $dst, [$constantaddress]\t# load from constant table: float=$con, #@loadConF" ++ %} ++ ++ ins_encode %{ ++ __ flw(as_FloatRegister($dst$$reg), $constantaddress($con)); ++ %} ++ ++ ins_pipe(fp_load_constant_s); ++%} ++ ++instruct loadConF0(fRegF dst, immF0 con) %{ ++ match(Set dst con); ++ ++ ins_cost(XFER_COST); ++ ++ format %{ "fmv.w.x $dst, zr\t# float, #@loadConF0" %} ++ ++ ins_encode %{ ++ __ fmv_w_x(as_FloatRegister($dst$$reg), zr); ++ %} ++ ++ ins_pipe(fp_load_constant_s); ++%} ++ ++// Load Double Constant ++instruct loadConD(fRegD dst, immD con) %{ ++ match(Set dst con); ++ ++ ins_cost(LOAD_COST); ++ format %{ ++ "fld $dst, [$constantaddress]\t# load from constant table: double=$con, #@loadConD" ++ %} ++ ++ ins_encode %{ ++ __ fld(as_FloatRegister($dst$$reg), $constantaddress($con)); ++ %} ++ ++ ins_pipe(fp_load_constant_d); ++%} ++ ++instruct loadConD0(fRegD dst, immD0 con) %{ ++ match(Set dst con); ++ ++ ins_cost(XFER_COST); ++ ++ format %{ "fmv.d.x $dst, zr\t# double, #@loadConD0" %} ++ ++ ins_encode %{ ++ __ fmv_d_x(as_FloatRegister($dst$$reg), zr); ++ %} ++ ++ ins_pipe(fp_load_constant_d); ++%} ++ ++// Store Instructions ++// Store CMS card-mark Immediate ++instruct storeimmCM0(immI0 zero, memory mem) ++%{ ++ match(Set mem (StoreCM mem zero)); ++ ++ ins_cost(STORE_COST); ++ format %{ "storestore (elided)\n\t" ++ "sb zr, $mem\t# byte, #@storeimmCM0" %} ++ ++ ins_encode %{ ++ __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_mem); ++%} ++ ++// Store CMS card-mark Immediate with intervening StoreStore ++// needed when using CMS with no conditional card marking ++instruct storeimmCM0_ordered(immI0 zero, memory mem) ++%{ ++ match(Set mem (StoreCM mem zero)); ++ ++ ins_cost(ALU_COST + STORE_COST); ++ format %{ "membar(StoreStore)\n\t" ++ "sb zr, $mem\t# byte, #@storeimmCM0_ordered" %} ++ ++ ins_encode %{ ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_mem); ++%} ++ ++// Store Byte ++instruct storeB(iRegIorL2I src, memory mem) ++%{ ++ match(Set mem (StoreB mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sb $src, $mem\t# byte, #@storeB" %} ++ ++ ins_encode %{ ++ __ sb(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++instruct storeimmB0(immI0 zero, memory mem) ++%{ ++ match(Set mem (StoreB mem zero)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sb zr, $mem\t# byte, #@storeimmB0" %} ++ ++ ins_encode %{ ++ __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_mem); ++%} ++ ++// Store Char/Short ++instruct storeC(iRegIorL2I src, memory mem) ++%{ ++ match(Set mem (StoreC mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sh $src, $mem\t# short, #@storeC" %} ++ ++ ins_encode %{ ++ __ sh(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++instruct storeimmC0(immI0 zero, memory mem) ++%{ ++ match(Set mem (StoreC mem zero)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sh zr, $mem\t# short, #@storeimmC0" %} ++ ++ ins_encode %{ ++ __ sh(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_mem); ++%} ++ ++// Store Integer ++instruct storeI(iRegIorL2I src, memory mem) ++%{ ++ match(Set mem(StoreI mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sw $src, $mem\t# int, #@storeI" %} ++ ++ ins_encode %{ ++ __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++instruct storeimmI0(immI0 zero, memory mem) ++%{ ++ match(Set mem(StoreI mem zero)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sw zr, $mem\t# int, #@storeimmI0" %} ++ ++ ins_encode %{ ++ __ sw(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_mem); ++%} ++ ++// Store Long (64 bit signed) ++instruct storeL(iRegL src, memory mem) ++%{ ++ match(Set mem (StoreL mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sd $src, $mem\t# long, #@storeL" %} ++ ++ ins_encode %{ ++ __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++// Store Long (64 bit signed) ++instruct storeimmL0(immL0 zero, memory mem) ++%{ ++ match(Set mem (StoreL mem zero)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sd zr, $mem\t# long, #@storeimmL0" %} ++ ++ ins_encode %{ ++ __ sd(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_mem); ++%} ++ ++// Store Pointer ++instruct storeP(iRegP src, memory mem) ++%{ ++ match(Set mem (StoreP mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sd $src, $mem\t# ptr, #@storeP" %} ++ ++ ins_encode %{ ++ __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++// Store Pointer ++instruct storeimmP0(immP0 zero, memory mem) ++%{ ++ match(Set mem (StoreP mem zero)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sd zr, $mem\t# ptr, #@storeimmP0" %} ++ ++ ins_encode %{ ++ __ sd(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_mem); ++%} ++ ++// Store Compressed Pointer ++instruct storeN(iRegN src, memory mem) ++%{ ++ match(Set mem (StoreN mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sw $src, $mem\t# compressed ptr, #@storeN" %} ++ ++ ins_encode %{ ++ __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++instruct storeImmN0(immN0 zero, memory mem) ++%{ ++ match(Set mem (StoreN mem zero)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sw zr, $mem\t# compressed ptr, #@storeImmN0" %} ++ ++ ins_encode %{ ++ __ sw(zr, Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++// Store Float ++instruct storeF(fRegF src, memory mem) ++%{ ++ match(Set mem (StoreF mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "fsw $src, $mem\t# float, #@storeF" %} ++ ++ ins_encode %{ ++ __ fsw(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(fp_store_reg_s); ++%} ++ ++// Store Double ++instruct storeD(fRegD src, memory mem) ++%{ ++ match(Set mem (StoreD mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "fsd $src, $mem\t# double, #@storeD" %} ++ ++ ins_encode %{ ++ __ fsd(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(fp_store_reg_d); ++%} ++ ++// Store Compressed Klass Pointer ++instruct storeNKlass(iRegN src, memory mem) ++%{ ++ match(Set mem (StoreNKlass mem src)); ++ ++ ins_cost(STORE_COST); ++ format %{ "sw $src, $mem\t# compressed klass ptr, #@storeNKlass" %} ++ ++ ins_encode %{ ++ __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_mem); ++%} ++ ++// ============================================================================ ++// Atomic operation instructions ++// ++// Intel and SPARC both implement Ideal Node LoadPLocked and ++// Store{PIL}Conditional instructions using a normal load for the ++// LoadPLocked and a CAS for the Store{PIL}Conditional. ++// ++// The ideal code appears only to use LoadPLocked/storePConditional as a ++// pair to lock object allocations from Eden space when not using ++// TLABs. ++// ++// There does not appear to be a Load{IL}Locked Ideal Node and the ++// Ideal code appears to use Store{IL}Conditional as an alias for CAS ++// and to use StoreIConditional only for 32-bit and StoreLConditional ++// only for 64-bit. ++// ++// We implement LoadPLocked and storePConditional instructions using, ++// respectively the RISCV hw load-reserve and store-conditional ++// instructions. Whereas we must implement each of ++// Store{IL}Conditional using a CAS which employs a pair of ++// instructions comprising a load-reserve followed by a ++// store-conditional. ++ ++ ++// Locked-load (load reserved) of the current heap-top ++// used when updating the eden heap top ++// implemented using lr_d on RISCV64 ++instruct loadPLocked(iRegPNoSp dst, indirect mem) ++%{ ++ match(Set dst (LoadPLocked mem)); ++ ++ ins_cost(ALU_COST * 2 + LOAD_COST); ++ ++ format %{ "lr.d $dst, $mem\t# ptr load reserved, #@loadPLocked" %} ++ ++ ins_encode %{ ++ __ la(t0, Address(as_Register($mem$$base), $mem$$disp)); ++ __ lr_d($dst$$Register, t0, Assembler::aq); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++// Conditional-store of the updated heap-top. ++// Used during allocation of the shared heap. ++// implemented using sc_d on RISCV64. ++instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) ++%{ ++ match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); ++ ++ ins_cost(ALU_COST * 2 + STORE_COST); ++ ++ format %{ ++ "sc_d t1, $newval $heap_top_ptr,\t# ptr store conditional, #@storePConditional" ++ %} ++ ++ ins_encode %{ ++ __ la(t0, Address(as_Register($heap_top_ptr$$base), $heap_top_ptr$$disp)); ++ __ sc_d($cr$$Register, $newval$$Register, t0, Assembler::rl); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct storeLConditional(indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) ++%{ ++ match(Set cr (StoreLConditional mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + 2 * BRANCH_COST); ++ ++ format %{ ++ "cmpxchg t1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" ++ "xorr $cr, $cr, $oldval\t# $cr == 0 on successful write, #@storeLConditional" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $cr$$Register); ++ __ xorr($cr$$Register,$cr$$Register, $oldval$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++// storeIConditional also has acquire semantics, for no better reason ++// than matching storeLConditional. ++instruct storeIConditional(indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) ++%{ ++ match(Set cr (StoreIConditional mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2); ++ ++ format %{ ++ "cmpxchgw t1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" ++ "xorr $cr, $cr, $oldval\t# $cr == 0 on successful write, #@storeIConditional" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $cr$$Register); ++ __ xorr($cr$$Register,$cr$$Register, $oldval$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++// standard CompareAndSwapX when we are using barriers ++// these have higher priority than the rules selected by a predicate ++instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ match(Set res (CompareAndSwapB mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); ++ ++ effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); ++ ++ format %{ ++ "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, ++ Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, ++ true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ match(Set res (CompareAndSwapS mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); ++ ++ effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); ++ ++ format %{ ++ "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, ++ Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, ++ true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) ++%{ ++ match(Set res (CompareAndSwapI mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapI" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchgw(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) ++%{ ++ match(Set res (CompareAndSwapL mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapL" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) ++%{ ++ predicate(n->as_LoadStore()->barrier_data() == 0); ++ ++ match(Set res (CompareAndSwapP mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapP" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) ++%{ ++ match(Set res (CompareAndSwapN mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapN" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchgn(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++// alternative CompareAndSwapX when we are eliding barriers ++instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndSwapB mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_acq $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, ++ Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, ++ true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndSwapS mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_acq $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, ++ Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, ++ true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndSwapI mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapIAcq" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchgw_acq(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndSwapL mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapLAcq" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); ++ ++ match(Set res (CompareAndSwapP mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapPAcq" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndSwapN mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); ++ ++ format %{ ++ "cmpxchg_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" ++ "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapNAcq" ++ %} ++ ++ ins_encode(riscv_enc_cmpxchgn_acq(res, mem, oldval, newval)); ++ ++ ins_pipe(pipe_slow); ++%} ++ ++// Sundry CAS operations. Note that release is always true, ++// regardless of the memory ordering of the CAS. This is because we ++// need the volatile case to be sequentially consistent but there is ++// no trailing StoreLoad barrier emitted by C2. Unfortunately we ++// can't check the type of memory ordering here, so we always emit a ++// sc_d(w) with rl bit set. ++instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ match(Set res (CompareAndExchangeB mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, ++ /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ match(Set res (CompareAndExchangeS mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, ++ /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) ++%{ ++ match(Set res (CompareAndExchangeI mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeI" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval) ++%{ ++ match(Set res (CompareAndExchangeL mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeL" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval) ++%{ ++ match(Set res (CompareAndExchangeN mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 3); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) ++%{ ++ predicate(n->as_LoadStore()->barrier_data() == 0); ++ match(Set res (CompareAndExchangeP mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeP" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndExchangeB mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, ++ /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndExchangeS mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, ++ /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndExchangeI mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeIAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndExchangeL mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeLAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (CompareAndExchangeN mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); ++ ++ match(Set res (CompareAndExchangeP mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); ++ ++ effect(TEMP_DEF res); ++ ++ format %{ ++ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_weak $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapB" ++ %} ++ ++ ins_encode %{ ++ __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_weak $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapS" ++ %} ++ ++ ins_encode %{ ++ __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) ++%{ ++ match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); ++ ++ format %{ ++ "cmpxchg_weak $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapI" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) ++%{ ++ match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); ++ ++ format %{ ++ "cmpxchg_weak $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapL" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) ++%{ ++ match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); ++ ++ format %{ ++ "cmpxchg_weak $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapN" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) ++%{ ++ predicate(n->as_LoadStore()->barrier_data() == 0); ++ match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); ++ ++ format %{ ++ "cmpxchg_weak $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapP" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_weak_acq $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapBAcq" ++ %} ++ ++ ins_encode %{ ++ __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, ++ iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); ++ ++ effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); ++ ++ format %{ ++ "cmpxchg_weak_acq $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapSAcq" ++ %} ++ ++ ins_encode %{ ++ __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); ++ ++ format %{ ++ "cmpxchg_weak_acq $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapIAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); ++ ++ format %{ ++ "cmpxchg_weak_acq $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapLAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); ++ ++ format %{ ++ "cmpxchg_weak_acq $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "# $res == 1 when success, #@weakCompareAndSwapNAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) ++%{ ++ predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); ++ ++ match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); ++ ++ ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); ++ ++ format %{ ++ "cmpxchg_weak_acq $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" ++ "\t# $res == 1 when success, #@weakCompareAndSwapPAcq" ++ %} ++ ++ ins_encode %{ ++ __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, ++ /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) ++%{ ++ match(Set prev (GetAndSetI mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchgw $prev, $newv, [$mem]\t#@get_and_setI" %} ++ ++ ins_encode %{ ++ __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) ++%{ ++ match(Set prev (GetAndSetL mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchg $prev, $newv, [$mem]\t#@get_and_setL" %} ++ ++ ins_encode %{ ++ __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) ++%{ ++ match(Set prev (GetAndSetN mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchgwu $prev, $newv, [$mem]\t#@get_and_setN" %} ++ ++ ins_encode %{ ++ __ atomic_xchgwu($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) ++%{ ++ predicate(n->as_LoadStore()->barrier_data() == 0); ++ match(Set prev (GetAndSetP mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchg $prev, $newv, [$mem]\t#@get_and_setP" %} ++ ++ ins_encode %{ ++ __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set prev (GetAndSetI mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchgw_acq $prev, $newv, [$mem]\t#@get_and_setIAcq" %} ++ ++ ins_encode %{ ++ __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set prev (GetAndSetL mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchg_acq $prev, $newv, [$mem]\t#@get_and_setLAcq" %} ++ ++ ins_encode %{ ++ __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set prev (GetAndSetN mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchgwu_acq $prev, $newv, [$mem]\t#@get_and_setNAcq" %} ++ ++ ins_encode %{ ++ __ atomic_xchgalwu($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) ++%{ ++ predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); ++ ++ match(Set prev (GetAndSetP mem newv)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "atomic_xchg_acq $prev, $newv, [$mem]\t#@get_and_setPAcq" %} ++ ++ ins_encode %{ ++ __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) ++%{ ++ match(Set newval (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addL" %} ++ ++ ins_encode %{ ++ __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) ++%{ ++ predicate(n->as_LoadStore()->result_not_used()); ++ ++ match(Set dummy (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL [$mem], $incr\t#@get_and_addL_no_res" %} ++ ++ ins_encode %{ ++ __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAdd incr) ++%{ ++ match(Set newval (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addLi" %} ++ ++ ins_encode %{ ++ __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAdd incr) ++%{ ++ predicate(n->as_LoadStore()->result_not_used()); ++ ++ match(Set dummy (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL [$mem], $incr\t#@get_and_addLi_no_res" %} ++ ++ ins_encode %{ ++ __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) ++%{ ++ match(Set newval (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addI" %} ++ ++ ins_encode %{ ++ __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) ++%{ ++ predicate(n->as_LoadStore()->result_not_used()); ++ ++ match(Set dummy (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI [$mem], $incr\t#@get_and_addI_no_res" %} ++ ++ ins_encode %{ ++ __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAdd incr) ++%{ ++ match(Set newval (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addIi" %} ++ ++ ins_encode %{ ++ __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAdd incr) ++%{ ++ predicate(n->as_LoadStore()->result_not_used()); ++ ++ match(Set dummy (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI [$mem], $incr\t#@get_and_addIi_no_res" %} ++ ++ ins_encode %{ ++ __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set newval (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ ++ predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); ++ ++ match(Set dummy (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addL_no_resAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAdd incr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set newval (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLiAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAdd incr) ++%{ ++ predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); ++ ++ match(Set dummy (GetAndAddL mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addLi_no_resAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set newval (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) ++%{ ++ predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); ++ ++ match(Set dummy (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addI_no_resAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAdd incr) ++%{ ++ predicate(needs_acquiring_load_reserved(n)); ++ ++ match(Set newval (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIiAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAdd incr) ++%{ ++ predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); ++ ++ match(Set dummy (GetAndAddI mem incr)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addIi_no_resAcq" %} ++ ++ ins_encode %{ ++ __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++// ============================================================================ ++// Arithmetic Instructions ++// ++ ++// Integer Addition ++ ++// TODO ++// these currently employ operations which do not set CR and hence are ++// not flagged as killing CR but we would like to isolate the cases ++// where we want to set flags from those where we don't. need to work ++// out how to do that. ++instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ++ match(Set dst (AddI src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "addw $dst, $src1, $src2\t#@addI_reg_reg" %} ++ ++ ins_encode %{ ++ __ addw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAdd src2) %{ ++ match(Set dst (AddI src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "addiw $dst, $src1, $src2\t#@addI_reg_imm" %} ++ ++ ins_encode %{ ++ int32_t con = (int32_t)$src2$$constant; ++ __ addiw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ $src2$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++instruct addI_reg_imm_l2i(iRegINoSp dst, iRegL src1, immIAdd src2) %{ ++ match(Set dst (AddI (ConvL2I src1) src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "addiw $dst, $src1, $src2\t#@addI_reg_imm_l2i" %} ++ ++ ins_encode %{ ++ __ addiw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ $src2$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Pointer Addition ++instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ ++ match(Set dst (AddP src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "add $dst, $src1, $src2\t# ptr, #@addP_reg_reg" %} ++ ++ ins_encode %{ ++ __ add(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// If we shift more than 32 bits, we need not convert I2L. ++instruct lShiftL_regI_immGE32(iRegLNoSp dst, iRegI src, uimmI6_ge32 scale) %{ ++ match(Set dst (LShiftL (ConvI2L src) scale)); ++ ins_cost(ALU_COST); ++ format %{ "slli $dst, $src, $scale & 63\t#@lShiftL_regI_immGE32" %} ++ ++ ins_encode %{ ++ __ slli(as_Register($dst$$reg), as_Register($src$$reg), $scale$$constant & 63); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Pointer Immediate Addition ++// n.b. this needs to be more expensive than using an indirect memory ++// operand ++instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAdd src2) %{ ++ match(Set dst (AddP src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "addi $dst, $src1, $src2\t# ptr, #@addP_reg_imm" %} ++ ++ ins_encode %{ ++ // src2 is imm, so actually call the addi ++ __ add(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ $src2$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Long Addition ++instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (AddL src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "add $dst, $src1, $src2\t#@addL_reg_reg" %} ++ ++ ins_encode %{ ++ __ add(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// No constant pool entries requiredLong Immediate Addition. ++instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ ++ match(Set dst (AddL src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "addi $dst, $src1, $src2\t#@addL_reg_imm" %} ++ ++ ins_encode %{ ++ // src2 is imm, so actually call the addi ++ __ add(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ $src2$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Integer Subtraction ++instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ++ match(Set dst (SubI src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "subw $dst, $src1, $src2\t#@subI_reg_reg" %} ++ ++ ins_encode %{ ++ __ subw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Immediate Subtraction ++instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immISub src2) %{ ++ match(Set dst (SubI src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "addiw $dst, $src1, -$src2\t#@subI_reg_imm" %} ++ ++ ins_encode %{ ++ // src2 is imm, so actually call the addiw ++ __ subw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ $src2$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Long Subtraction ++instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (SubL src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "sub $dst, $src1, $src2\t#@subL_reg_reg" %} ++ ++ ins_encode %{ ++ __ sub(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// No constant pool entries requiredLong Immediate Subtraction. ++instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLSub src2) %{ ++ match(Set dst (SubL src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "addi $dst, $src1, -$src2\t#@subL_reg_imm" %} ++ ++ ins_encode %{ ++ // src2 is imm, so actually call the addi ++ __ sub(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ $src2$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Integer Negation (special case for sub) ++ ++instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ ++ match(Set dst (SubI zero src)); ++ ins_cost(ALU_COST); ++ format %{ "subw $dst, x0, $src\t# int, #@negI_reg" %} ++ ++ ins_encode %{ ++ // actually call the subw ++ __ negw(as_Register($dst$$reg), ++ as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Long Negation ++ ++instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero) %{ ++ match(Set dst (SubL zero src)); ++ ins_cost(ALU_COST); ++ format %{ "sub $dst, x0, $src\t# long, #@negL_reg" %} ++ ++ ins_encode %{ ++ // actually call the sub ++ __ neg(as_Register($dst$$reg), ++ as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Integer Multiply ++ ++instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ++ match(Set dst (MulI src1 src2)); ++ ins_cost(IMUL_COST); ++ format %{ "mulw $dst, $src1, $src2\t#@mulI" %} ++ ++ //this means 2 word multi, and no sign extend to 64 bits ++ ins_encode %{ ++ // riscv64 mulw will sign-extension to high 32 bits in dst reg ++ __ mulw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(imul_reg_reg); ++%} ++ ++// Long Multiply ++ ++instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (MulL src1 src2)); ++ ins_cost(IMUL_COST); ++ format %{ "mul $dst, $src1, $src2\t#@mulL" %} ++ ++ ins_encode %{ ++ __ mul(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(lmul_reg_reg); ++%} ++ ++instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2) ++%{ ++ match(Set dst (MulHiL src1 src2)); ++ ins_cost(IMUL_COST); ++ format %{ "mulh $dst, $src1, $src2\t# mulhi, #@mulHiL_rReg" %} ++ ++ ins_encode %{ ++ __ mulh(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) %{ ++ match(Set dst (DivI src1 src2)); ++ ins_cost(IDIVSI_COST); ++ format %{ "divw $dst, $src1, $src2\t#@divI"%} ++ ++ ins_encode(riscv_enc_divw(dst, src1, src2)); ++ ins_pipe(idiv_reg_reg); ++%} ++ ++instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ ++ match(Set dst (URShiftI (RShiftI src1 div1) div2)); ++ ins_cost(ALU_COST); ++ format %{ "srliw $dst, $src1, $div1\t# int signExtract, #@signExtract" %} ++ ++ ins_encode %{ ++ __ srliw(as_Register($dst$$reg), as_Register($src1$$reg), 31); ++ %} ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Long Divide ++ ++instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (DivL src1 src2)); ++ ins_cost(IDIVDI_COST); ++ format %{ "div $dst, $src1, $src2\t#@divL" %} ++ ++ ins_encode(riscv_enc_div(dst, src1, src2)); ++ ins_pipe(ldiv_reg_reg); ++%} ++ ++instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ ++ match(Set dst (URShiftL (RShiftL src1 div1) div2)); ++ ins_cost(ALU_COST); ++ format %{ "srli $dst, $src1, $div1\t# long signExtract, #@signExtractL" %} ++ ++ ins_encode %{ ++ __ srli(as_Register($dst$$reg), as_Register($src1$$reg), 63); ++ %} ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Integer Remainder ++ ++instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ++ match(Set dst (ModI src1 src2)); ++ ins_cost(IDIVSI_COST); ++ format %{ "remw $dst, $src1, $src2\t#@modI" %} ++ ++ ins_encode(riscv_enc_modw(dst, src1, src2)); ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Long Remainder ++ ++instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (ModL src1 src2)); ++ ins_cost(IDIVDI_COST); ++ format %{ "rem $dst, $src1, $src2\t#@modL" %} ++ ++ ins_encode(riscv_enc_mod(dst, src1, src2)); ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Integer Shifts ++ ++// Shift Left Register ++// In RV64I, only the low 5 bits of src2 are considered for the shift amount ++instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ++ match(Set dst (LShiftI src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "sllw $dst, $src1, $src2\t#@lShiftI_reg_reg" %} ++ ++ ins_encode %{ ++ __ sllw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg_vshift); ++%} ++ ++// Shift Left Immediate ++instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ ++ match(Set dst (LShiftI src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "slliw $dst, $src1, ($src2 & 0x1f)\t#@lShiftI_reg_imm" %} ++ ++ ins_encode %{ ++ // the shift amount is encoded in the lower ++ // 5 bits of the I-immediate field for RV32I ++ __ slliw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (unsigned) $src2$$constant & 0x1f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Shift Right Logical Register ++// In RV64I, only the low 5 bits of src2 are considered for the shift amount ++instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ++ match(Set dst (URShiftI src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "srlw $dst, $src1, $src2\t#@urShiftI_reg_reg" %} ++ ++ ins_encode %{ ++ __ srlw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg_vshift); ++%} ++ ++// Shift Right Logical Immediate ++instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ ++ match(Set dst (URShiftI src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "srliw $dst, $src1, ($src2 & 0x1f)\t#@urShiftI_reg_imm" %} ++ ++ ins_encode %{ ++ // the shift amount is encoded in the lower ++ // 6 bits of the I-immediate field for RV64I ++ __ srliw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (unsigned) $src2$$constant & 0x1f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Shift Right Arithmetic Register ++// In RV64I, only the low 5 bits of src2 are considered for the shift amount ++instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ++ match(Set dst (RShiftI src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "sraw $dst, $src1, $src2\t#@rShiftI_reg_reg" %} ++ ++ ins_encode %{ ++ // riscv will sign-ext dst high 32 bits ++ __ sraw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg_vshift); ++%} ++ ++// Shift Right Arithmetic Immediate ++instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ ++ match(Set dst (RShiftI src1 src2)); ++ ins_cost(ALU_COST); ++ format %{ "sraiw $dst, $src1, ($src2 & 0x1f)\t#@rShiftI_reg_imm" %} ++ ++ ins_encode %{ ++ // riscv will sign-ext dst high 32 bits ++ __ sraiw(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (unsigned) $src2$$constant & 0x1f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Long Shifts ++ ++// Shift Left Register ++// In RV64I, only the low 6 bits of src2 are considered for the shift amount ++instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ ++ match(Set dst (LShiftL src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "sll $dst, $src1, $src2\t#@lShiftL_reg_reg" %} ++ ++ ins_encode %{ ++ __ sll(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg_vshift); ++%} ++ ++// Shift Left Immediate ++instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ ++ match(Set dst (LShiftL src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "slli $dst, $src1, ($src2 & 0x3f)\t#@lShiftL_reg_imm" %} ++ ++ ins_encode %{ ++ // the shift amount is encoded in the lower ++ // 6 bits of the I-immediate field for RV64I ++ __ slli(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (unsigned) $src2$$constant & 0x3f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Shift Right Logical Register ++// In RV64I, only the low 6 bits of src2 are considered for the shift amount ++instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ ++ match(Set dst (URShiftL src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "srl $dst, $src1, $src2\t#@urShiftL_reg_reg" %} ++ ++ ins_encode %{ ++ __ srl(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg_vshift); ++%} ++ ++// Shift Right Logical Immediate ++instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ ++ match(Set dst (URShiftL src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "srli $dst, $src1, ($src2 & 0x3f)\t#@urShiftL_reg_imm" %} ++ ++ ins_encode %{ ++ // the shift amount is encoded in the lower ++ // 6 bits of the I-immediate field for RV64I ++ __ srli(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (unsigned) $src2$$constant & 0x3f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// A special-case pattern for card table stores. ++instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ ++ match(Set dst (URShiftL (CastP2X src1) src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "srli $dst, p2x($src1), ($src2 & 0x3f)\t#@urShiftP_reg_imm" %} ++ ++ ins_encode %{ ++ // the shift amount is encoded in the lower ++ // 6 bits of the I-immediate field for RV64I ++ __ srli(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (unsigned) $src2$$constant & 0x3f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// Shift Right Arithmetic Register ++// In RV64I, only the low 6 bits of src2 are considered for the shift amount ++instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ ++ match(Set dst (RShiftL src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "sra $dst, $src1, $src2\t#@rShiftL_reg_reg" %} ++ ++ ins_encode %{ ++ __ sra(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg_vshift); ++%} ++ ++// Shift Right Arithmetic Immediate ++instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ ++ match(Set dst (RShiftL src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "srai $dst, $src1, ($src2 & 0x3f)\t#@rShiftL_reg_imm" %} ++ ++ ins_encode %{ ++ // the shift amount is encoded in the lower ++ // 6 bits of the I-immediate field for RV64I ++ __ srai(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (unsigned) $src2$$constant & 0x3f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++instruct regI_not_reg(iRegINoSp dst, iRegI src1, immI_M1 m1) %{ ++ match(Set dst (XorI src1 m1)); ++ ins_cost(ALU_COST); ++ format %{ "xori $dst, $src1, -1\t#@regI_not_reg" %} ++ ++ ins_encode %{ ++ __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++instruct regL_not_reg(iRegLNoSp dst, iRegL src1, immL_M1 m1) %{ ++ match(Set dst (XorL src1 m1)); ++ ins_cost(ALU_COST); ++ format %{ "xori $dst, $src1, -1\t#@regL_not_reg" %} ++ ++ ins_encode %{ ++ __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++ ++// ============================================================================ ++// Floating Point Arithmetic Instructions ++ ++instruct addF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ ++ match(Set dst (AddF src1 src2)); ++ ++ ins_cost(DEFAULT_COST * 5); ++ format %{ "fadd.s $dst, $src1, $src2\t#@addF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fadd_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_dop_reg_reg_s); ++%} ++ ++instruct addD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ ++ match(Set dst (AddD src1 src2)); ++ ++ ins_cost(DEFAULT_COST * 5); ++ format %{ "fadd.d $dst, $src1, $src2\t#@addD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fadd_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_dop_reg_reg_d); ++%} ++ ++instruct subF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ ++ match(Set dst (SubF src1 src2)); ++ ++ ins_cost(DEFAULT_COST * 5); ++ format %{ "fsub.s $dst, $src1, $src2\t#@subF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fsub_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_dop_reg_reg_s); ++%} ++ ++instruct subD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ ++ match(Set dst (SubD src1 src2)); ++ ++ ins_cost(DEFAULT_COST * 5); ++ format %{ "fsub.d $dst, $src1, $src2\t#@subD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fsub_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_dop_reg_reg_d); ++%} ++ ++instruct mulF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ ++ match(Set dst (MulF src1 src2)); ++ ++ ins_cost(FMUL_SINGLE_COST); ++ format %{ "fmul.s $dst, $src1, $src2\t#@mulF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmul_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_dop_reg_reg_s); ++%} ++ ++instruct mulD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ ++ match(Set dst (MulD src1 src2)); ++ ++ ins_cost(FMUL_DOUBLE_COST); ++ format %{ "fmul.d $dst, $src1, $src2\t#@mulD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmul_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_dop_reg_reg_d); ++%} ++ ++// src1 * src2 + src3 ++instruct maddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaF src3 (Binary src1 src2))); ++ ++ ins_cost(FMUL_SINGLE_COST); ++ format %{ "fmadd.s $dst, $src1, $src2, $src3\t#@maddF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmadd_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// src1 * src2 + src3 ++instruct maddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaD src3 (Binary src1 src2))); ++ ++ ins_cost(FMUL_DOUBLE_COST); ++ format %{ "fmadd.d $dst, $src1, $src2, $src3\t#@maddD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmadd_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// src1 * src2 - src3 ++instruct msubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaF (NegF src3) (Binary src1 src2))); ++ ++ ins_cost(FMUL_SINGLE_COST); ++ format %{ "fmsub.s $dst, $src1, $src2, $src3\t#@msubF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmsub_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// src1 * src2 - src3 ++instruct msubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaD (NegD src3) (Binary src1 src2))); ++ ++ ins_cost(FMUL_DOUBLE_COST); ++ format %{ "fmsub.d $dst, $src1, $src2, $src3\t#@msubD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmsub_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// -src1 * src2 + src3 ++instruct nmsubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaF src3 (Binary (NegF src1) src2))); ++ match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); ++ ++ ins_cost(FMUL_SINGLE_COST); ++ format %{ "fnmsub.s $dst, $src1, $src2, $src3\t#@nmsubF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fnmsub_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// -src1 * src2 + src3 ++instruct nmsubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaD src3 (Binary (NegD src1) src2))); ++ match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); ++ ++ ins_cost(FMUL_DOUBLE_COST); ++ format %{ "fnmsub.d $dst, $src1, $src2, $src3\t#@nmsubD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fnmsub_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// -src1 * src2 - src3 ++instruct nmaddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); ++ match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); ++ ++ ins_cost(FMUL_SINGLE_COST); ++ format %{ "fnmadd.s $dst, $src1, $src2, $src3\t#@nmaddF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fnmadd_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// -src1 * src2 - src3 ++instruct nmaddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ ++ predicate(UseFMA); ++ match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); ++ match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); ++ ++ ins_cost(FMUL_DOUBLE_COST); ++ format %{ "fnmadd.d $dst, $src1, $src2, $src3\t#@nmaddD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fnmadd_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg), ++ as_FloatRegister($src3$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// Math.max(FF)F ++instruct maxF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ ++ match(Set dst (MaxF src1 src2)); ++ effect(TEMP_DEF dst, KILL cr); ++ ++ format %{ "maxF $dst, $src1, $src2" %} ++ ++ ins_encode %{ ++ __ minmax_FD(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), ++ false /* is_double */, false /* is_min */); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// Math.min(FF)F ++instruct minF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ ++ match(Set dst (MinF src1 src2)); ++ effect(TEMP_DEF dst, KILL cr); ++ ++ format %{ "minF $dst, $src1, $src2" %} ++ ++ ins_encode %{ ++ __ minmax_FD(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), ++ false /* is_double */, true /* is_min */); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// Math.max(DD)D ++instruct maxD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ ++ match(Set dst (MaxD src1 src2)); ++ effect(TEMP_DEF dst, KILL cr); ++ ++ format %{ "maxD $dst, $src1, $src2" %} ++ ++ ins_encode %{ ++ __ minmax_FD(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), ++ true /* is_double */, false /* is_min */); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// Math.min(DD)D ++instruct minD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ ++ match(Set dst (MinD src1 src2)); ++ effect(TEMP_DEF dst, KILL cr); ++ ++ format %{ "minD $dst, $src1, $src2" %} ++ ++ ins_encode %{ ++ __ minmax_FD(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), ++ true /* is_double */, true /* is_min */); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct divF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ ++ match(Set dst (DivF src1 src2)); ++ ++ ins_cost(FDIV_COST); ++ format %{ "fdiv.s $dst, $src1, $src2\t#@divF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fdiv_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_div_s); ++%} ++ ++instruct divD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ ++ match(Set dst (DivD src1 src2)); ++ ++ ins_cost(FDIV_COST); ++ format %{ "fdiv.d $dst, $src1, $src2\t#@divD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fdiv_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src1$$reg), ++ as_FloatRegister($src2$$reg)); ++ %} ++ ++ ins_pipe(fp_div_d); ++%} ++ ++instruct negF_reg_reg(fRegF dst, fRegF src) %{ ++ match(Set dst (NegF src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fsgnjn.s $dst, $src, $src\t#@negF_reg_reg" %} ++ ++ ins_encode %{ ++ __ fneg_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_uop_s); ++%} ++ ++instruct negD_reg_reg(fRegD dst, fRegD src) %{ ++ match(Set dst (NegD src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fsgnjn.d $dst, $src, $src\t#@negD_reg_reg" %} ++ ++ ins_encode %{ ++ __ fneg_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_uop_d); ++%} ++ ++instruct absI_reg(iRegINoSp dst, iRegIorL2I src) %{ ++ match(Set dst (AbsI src)); ++ ++ ins_cost(ALU_COST * 3); ++ format %{ ++ "sraiw t0, $src, 0x1f\n\t" ++ "addw $dst, $src, t0\n\t" ++ "xorr $dst, $dst, t0\t#@absI_reg" ++ %} ++ ++ ins_encode %{ ++ __ sraiw(t0, as_Register($src$$reg), 0x1f); ++ __ addw(as_Register($dst$$reg), as_Register($src$$reg), t0); ++ __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct absL_reg(iRegLNoSp dst, iRegL src) %{ ++ match(Set dst (AbsL src)); ++ ++ ins_cost(ALU_COST * 3); ++ format %{ ++ "srai t0, $src, 0x3f\n\t" ++ "add $dst, $src, t0\n\t" ++ "xorr $dst, $dst, t0\t#@absL_reg" ++ %} ++ ++ ins_encode %{ ++ __ srai(t0, as_Register($src$$reg), 0x3f); ++ __ add(as_Register($dst$$reg), as_Register($src$$reg), t0); ++ __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct absF_reg(fRegF dst, fRegF src) %{ ++ match(Set dst (AbsF src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fsgnjx.s $dst, $src, $src\t#@absF_reg" %} ++ ins_encode %{ ++ __ fabs_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_uop_s); ++%} ++ ++instruct absD_reg(fRegD dst, fRegD src) %{ ++ match(Set dst (AbsD src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fsgnjx.d $dst, $src, $src\t#@absD_reg" %} ++ ins_encode %{ ++ __ fabs_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_uop_d); ++%} ++ ++instruct sqrtF_reg(fRegF dst, fRegF src) %{ ++ match(Set dst (SqrtF src)); ++ ++ ins_cost(FSQRT_COST); ++ format %{ "fsqrt.s $dst, $src\t#@sqrtF_reg" %} ++ ins_encode %{ ++ __ fsqrt_s(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_sqrt_s); ++%} ++ ++instruct sqrtD_reg(fRegD dst, fRegD src) %{ ++ match(Set dst (SqrtD src)); ++ ++ ins_cost(FSQRT_COST); ++ format %{ "fsqrt.d $dst, $src\t#@sqrtD_reg" %} ++ ins_encode %{ ++ __ fsqrt_d(as_FloatRegister($dst$$reg), ++ as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_sqrt_d); ++%} ++ ++// Arithmetic Instructions End ++ ++// ============================================================================ ++// Logical Instructions ++ ++// Register And ++instruct andI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ ++ match(Set dst (AndI src1 src2)); ++ ++ format %{ "andr $dst, $src1, $src2\t#@andI_reg_reg" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ andr(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Immediate And ++instruct andI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ ++ match(Set dst (AndI src1 src2)); ++ ++ format %{ "andi $dst, $src1, $src2\t#@andI_reg_imm" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ andi(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (int32_t)($src2$$constant)); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Register Or ++instruct orI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ ++ match(Set dst (OrI src1 src2)); ++ ++ format %{ "orr $dst, $src1, $src2\t#@orI_reg_reg" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ orr(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Immediate Or ++instruct orI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ ++ match(Set dst (OrI src1 src2)); ++ ++ format %{ "ori $dst, $src1, $src2\t#@orI_reg_imm" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ ori(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (int32_t)($src2$$constant)); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Register Xor ++instruct xorI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ ++ match(Set dst (XorI src1 src2)); ++ ++ format %{ "xorr $dst, $src1, $src2\t#@xorI_reg_reg" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ xorr(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Immediate Xor ++instruct xorI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ ++ match(Set dst (XorI src1 src2)); ++ ++ format %{ "xori $dst, $src1, $src2\t#@xorI_reg_imm" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ xori(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (int32_t)($src2$$constant)); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Register And Long ++instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (AndL src1 src2)); ++ ++ format %{ "andr $dst, $src1, $src2\t#@andL_reg_reg" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ andr(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Immediate And Long ++instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ ++ match(Set dst (AndL src1 src2)); ++ ++ format %{ "andi $dst, $src1, $src2\t#@andL_reg_imm" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ andi(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (int32_t)($src2$$constant)); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Register Or Long ++instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (OrL src1 src2)); ++ ++ format %{ "orr $dst, $src1, $src2\t#@orL_reg_reg" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ orr(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Immediate Or Long ++instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ ++ match(Set dst (OrL src1 src2)); ++ ++ format %{ "ori $dst, $src1, $src2\t#@orL_reg_imm" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ ori(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (int32_t)($src2$$constant)); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// Register Xor Long ++instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ++ match(Set dst (XorL src1 src2)); ++ ++ format %{ "xorr $dst, $src1, $src2\t#@xorL_reg_reg" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ xorr(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Immediate Xor Long ++instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ ++ match(Set dst (XorL src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "xori $dst, $src1, $src2\t#@xorL_reg_imm" %} ++ ++ ins_encode %{ ++ __ xori(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ (int32_t)($src2$$constant)); ++ %} ++ ++ ins_pipe(ialu_reg_imm); ++%} ++ ++// ============================================================================ ++// BSWAP Instructions ++ ++instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) %{ ++ match(Set dst (ReverseBytesI src)); ++ effect(KILL cr); ++ ++ ins_cost(ALU_COST * 13); ++ format %{ "revb_w_w $dst, $src\t#@bytes_reverse_int" %} ++ ++ ins_encode %{ ++ __ revb_w_w(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct bytes_reverse_long(iRegLNoSp dst, iRegL src, rFlagsReg cr) %{ ++ match(Set dst (ReverseBytesL src)); ++ effect(KILL cr); ++ ++ ins_cost(ALU_COST * 29); ++ format %{ "revb $dst, $src\t#@bytes_reverse_long" %} ++ ++ ins_encode %{ ++ __ revb(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ ++ match(Set dst (ReverseBytesUS src)); ++ ++ ins_cost(ALU_COST * 5); ++ format %{ "revb_h_h_u $dst, $src\t#@bytes_reverse_unsigned_short" %} ++ ++ ins_encode %{ ++ __ revb_h_h_u(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ ++ match(Set dst (ReverseBytesS src)); ++ ++ ins_cost(ALU_COST * 5); ++ format %{ "revb_h_h $dst, $src\t#@bytes_reverse_short" %} ++ ++ ins_encode %{ ++ __ revb_h_h(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// ============================================================================ ++// MemBar Instruction ++ ++instruct load_fence() %{ ++ match(LoadFence); ++ ins_cost(ALU_COST); ++ ++ format %{ "#@load_fence" %} ++ ++ ins_encode %{ ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ %} ++ ins_pipe(pipe_serial); ++%} ++ ++instruct membar_acquire() %{ ++ match(MemBarAcquire); ++ ins_cost(ALU_COST); ++ ++ format %{ "#@membar_acquire\n\t" ++ "fence ir iorw" %} ++ ++ ins_encode %{ ++ __ block_comment("membar_acquire"); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct membar_acquire_lock() %{ ++ match(MemBarAcquireLock); ++ ins_cost(0); ++ ++ format %{ "#@membar_acquire_lock (elided)" %} ++ ++ ins_encode %{ ++ __ block_comment("membar_acquire_lock (elided)"); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct store_fence() %{ ++ match(StoreFence); ++ ins_cost(ALU_COST); ++ ++ format %{ "#@store_fence" %} ++ ++ ins_encode %{ ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ %} ++ ins_pipe(pipe_serial); ++%} ++ ++instruct membar_release() %{ ++ match(MemBarRelease); ++ ins_cost(ALU_COST); ++ ++ format %{ "#@membar_release\n\t" ++ "fence iorw ow" %} ++ ++ ins_encode %{ ++ __ block_comment("membar_release"); ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ %} ++ ins_pipe(pipe_serial); ++%} ++ ++instruct membar_storestore() %{ ++ match(MemBarStoreStore); ++ match(StoreStoreFence); ++ ins_cost(ALU_COST); ++ ++ format %{ "MEMBAR-store-store\t#@membar_storestore" %} ++ ++ ins_encode %{ ++ __ membar(MacroAssembler::StoreStore); ++ %} ++ ins_pipe(pipe_serial); ++%} ++ ++instruct membar_release_lock() %{ ++ match(MemBarReleaseLock); ++ ins_cost(0); ++ ++ format %{ "#@membar_release_lock (elided)" %} ++ ++ ins_encode %{ ++ __ block_comment("membar_release_lock (elided)"); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++instruct membar_volatile() %{ ++ match(MemBarVolatile); ++ ins_cost(ALU_COST); ++ ++ format %{ "#@membar_volatile\n\t" ++ "fence iorw iorw"%} ++ ++ ins_encode %{ ++ __ block_comment("membar_volatile"); ++ __ membar(MacroAssembler::StoreLoad); ++ %} ++ ++ ins_pipe(pipe_serial); ++%} ++ ++// ============================================================================ ++// Cast Instructions (Java-level type cast) ++ ++instruct castX2P(iRegPNoSp dst, iRegL src) %{ ++ match(Set dst (CastX2P src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $src\t# long -> ptr, #@castX2P" %} ++ ++ ins_encode %{ ++ if ($dst$$reg != $src$$reg) { ++ __ mv(as_Register($dst$$reg), as_Register($src$$reg)); ++ } ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct castP2X(iRegLNoSp dst, iRegP src) %{ ++ match(Set dst (CastP2X src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $src\t# ptr -> long, #@castP2X" %} ++ ++ ins_encode %{ ++ if ($dst$$reg != $src$$reg) { ++ __ mv(as_Register($dst$$reg), as_Register($src$$reg)); ++ } ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct castPP(iRegPNoSp dst) ++%{ ++ match(Set dst (CastPP dst)); ++ ins_cost(0); ++ ++ size(0); ++ format %{ "# castPP of $dst, #@castPP" %} ++ ins_encode(/* empty encoding */); ++ ins_pipe(pipe_class_empty); ++%} ++ ++instruct castLL(iRegL dst) ++%{ ++ match(Set dst (CastLL dst)); ++ ++ size(0); ++ format %{ "# castLL of $dst, #@castLL" %} ++ ins_encode(/* empty encoding */); ++ ins_cost(0); ++ ins_pipe(pipe_class_empty); ++%} ++ ++instruct castII(iRegI dst) ++%{ ++ match(Set dst (CastII dst)); ++ ++ size(0); ++ format %{ "# castII of $dst, #@castII" %} ++ ins_encode(/* empty encoding */); ++ ins_cost(0); ++ ins_pipe(pipe_class_empty); ++%} ++ ++instruct checkCastPP(iRegPNoSp dst) ++%{ ++ match(Set dst (CheckCastPP dst)); ++ ++ size(0); ++ ins_cost(0); ++ format %{ "# checkcastPP of $dst, #@checkCastPP" %} ++ ins_encode(/* empty encoding */); ++ ins_pipe(pipe_class_empty); ++%} ++ ++instruct castFF(fRegF dst) ++%{ ++ match(Set dst (CastFF dst)); ++ ++ size(0); ++ format %{ "# castFF of $dst" %} ++ ins_encode(/* empty encoding */); ++ ins_cost(0); ++ ins_pipe(pipe_class_empty); ++%} ++ ++instruct castDD(fRegD dst) ++%{ ++ match(Set dst (CastDD dst)); ++ ++ size(0); ++ format %{ "# castDD of $dst" %} ++ ins_encode(/* empty encoding */); ++ ins_cost(0); ++ ins_pipe(pipe_class_empty); ++%} ++ ++instruct castVV(vReg dst) ++%{ ++ match(Set dst (CastVV dst)); ++ ++ size(0); ++ format %{ "# castVV of $dst" %} ++ ins_encode(/* empty encoding */); ++ ins_cost(0); ++ ins_pipe(pipe_class_empty); ++%} ++ ++// ============================================================================ ++// Convert Instructions ++ ++// int to bool ++instruct convI2Bool(iRegINoSp dst, iRegI src) ++%{ ++ match(Set dst (Conv2B src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "snez $dst, $src\t#@convI2Bool" %} ++ ++ ins_encode %{ ++ __ snez(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// pointer to bool ++instruct convP2Bool(iRegINoSp dst, iRegP src) ++%{ ++ match(Set dst (Conv2B src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "snez $dst, $src\t#@convP2Bool" %} ++ ++ ins_encode %{ ++ __ snez(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// int <-> long ++ ++instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) ++%{ ++ match(Set dst (ConvI2L src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "addw $dst, $src, zr\t#@convI2L_reg_reg" %} ++ ins_encode %{ ++ __ sign_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); ++ %} ++ ins_pipe(ialu_reg); ++%} ++ ++instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ ++ match(Set dst (ConvL2I src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "addw $dst, $src, zr\t#@convL2I_reg" %} ++ ++ ins_encode %{ ++ __ sign_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// int to unsigned long (Zero-extend) ++instruct convI2UL_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) ++%{ ++ match(Set dst (AndL (ConvI2L src) mask)); ++ ++ ins_cost(ALU_COST * 2); ++ format %{ "zero_extend $dst, $src, 32\t# i2ul, #@convI2UL_reg_reg" %} ++ ++ ins_encode %{ ++ __ zero_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// float <-> double ++ ++instruct convF2D_reg(fRegD dst, fRegF src) %{ ++ match(Set dst (ConvF2D src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.d.s $dst, $src\t#@convF2D_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_d_s(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_f2d); ++%} ++ ++instruct convD2F_reg(fRegF dst, fRegD src) %{ ++ match(Set dst (ConvD2F src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.s.d $dst, $src\t#@convD2F_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_s_d(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_d2f); ++%} ++ ++// float <-> int ++ ++instruct convF2I_reg_reg(iRegINoSp dst, fRegF src) %{ ++ match(Set dst (ConvF2I src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.w.s $dst, $src\t#@convF2I_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_w_s_safe($dst$$Register, $src$$FloatRegister); ++ %} ++ ++ ins_pipe(fp_f2i); ++%} ++ ++instruct convI2F_reg_reg(fRegF dst, iRegIorL2I src) %{ ++ match(Set dst (ConvI2F src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.s.w $dst, $src\t#@convI2F_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_s_w(as_FloatRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(fp_i2f); ++%} ++ ++// float <-> long ++ ++instruct convF2L_reg_reg(iRegLNoSp dst, fRegF src) %{ ++ match(Set dst (ConvF2L src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.l.s $dst, $src\t#@convF2L_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_l_s_safe($dst$$Register, $src$$FloatRegister); ++ %} ++ ++ ins_pipe(fp_f2l); ++%} ++ ++instruct convL2F_reg_reg(fRegF dst, iRegL src) %{ ++ match(Set dst (ConvL2F src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.s.l $dst, $src\t#@convL2F_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_s_l(as_FloatRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(fp_l2f); ++%} ++ ++// double <-> int ++ ++instruct convD2I_reg_reg(iRegINoSp dst, fRegD src) %{ ++ match(Set dst (ConvD2I src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.w.d $dst, $src\t#@convD2I_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_w_d_safe($dst$$Register, $src$$FloatRegister); ++ %} ++ ++ ins_pipe(fp_d2i); ++%} ++ ++instruct convI2D_reg_reg(fRegD dst, iRegIorL2I src) %{ ++ match(Set dst (ConvI2D src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.d.w $dst, $src\t#@convI2D_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_d_w(as_FloatRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(fp_i2d); ++%} ++ ++// double <-> long ++ ++instruct convD2L_reg_reg(iRegLNoSp dst, fRegD src) %{ ++ match(Set dst (ConvD2L src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.l.d $dst, $src\t#@convD2L_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_l_d_safe($dst$$Register, $src$$FloatRegister); ++ %} ++ ++ ins_pipe(fp_d2l); ++%} ++ ++instruct convL2D_reg_reg(fRegD dst, iRegL src) %{ ++ match(Set dst (ConvL2D src)); ++ ++ ins_cost(XFER_COST); ++ format %{ "fcvt.d.l $dst, $src\t#@convL2D_reg_reg" %} ++ ++ ins_encode %{ ++ __ fcvt_d_l(as_FloatRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(fp_l2d); ++%} ++ ++// Convert oop into int for vectors alignment masking ++instruct convP2I(iRegINoSp dst, iRegP src) %{ ++ match(Set dst (ConvL2I (CastP2X src))); ++ ++ ins_cost(ALU_COST * 2); ++ format %{ "zero_extend $dst, $src, 32\t# ptr -> int, #@convP2I" %} ++ ++ ins_encode %{ ++ __ zero_extend($dst$$Register, $src$$Register, 32); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Convert compressed oop into int for vectors alignment masking ++// in case of 32bit oops (heap < 4Gb). ++instruct convN2I(iRegINoSp dst, iRegN src) ++%{ ++ predicate(CompressedOops::shift() == 0); ++ match(Set dst (ConvL2I (CastP2X (DecodeN src)))); ++ ++ ins_cost(ALU_COST); ++ format %{ "mv $dst, $src\t# compressed ptr -> int, #@convN2I" %} ++ ++ ins_encode %{ ++ __ mv($dst$$Register, $src$$Register); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Convert oop pointer into compressed form ++instruct encodeHeapOop(iRegNNoSp dst, iRegP src) %{ ++ match(Set dst (EncodeP src)); ++ ins_cost(ALU_COST); ++ format %{ "encode_heap_oop $dst, $src\t#@encodeHeapOop" %} ++ ins_encode %{ ++ Register s = $src$$Register; ++ Register d = $dst$$Register; ++ __ encode_heap_oop(d, s); ++ %} ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct decodeHeapOop(iRegPNoSp dst, iRegN src) %{ ++ predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && ++ n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); ++ match(Set dst (DecodeN src)); ++ ++ ins_cost(0); ++ format %{ "decode_heap_oop $dst, $src\t#@decodeHeapOop" %} ++ ins_encode %{ ++ Register s = $src$$Register; ++ Register d = $dst$$Register; ++ __ decode_heap_oop(d, s); ++ %} ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src) %{ ++ predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || ++ n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); ++ match(Set dst (DecodeN src)); ++ ++ ins_cost(0); ++ format %{ "decode_heap_oop_not_null $dst, $src\t#@decodeHeapOop_not_null" %} ++ ins_encode %{ ++ Register s = $src$$Register; ++ Register d = $dst$$Register; ++ __ decode_heap_oop_not_null(d, s); ++ %} ++ ins_pipe(pipe_class_default); ++%} ++ ++// Convert klass pointer into compressed form. ++instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ ++ match(Set dst (EncodePKlass src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "encode_klass_not_null $dst, $src\t#@encodeKlass_not_null" %} ++ ++ ins_encode %{ ++ Register src_reg = as_Register($src$$reg); ++ Register dst_reg = as_Register($dst$$reg); ++ __ encode_klass_not_null(dst_reg, src_reg, t0); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src, iRegPNoSp tmp) %{ ++ match(Set dst (DecodeNKlass src)); ++ ++ effect(TEMP tmp); ++ ++ ins_cost(ALU_COST); ++ format %{ "decode_klass_not_null $dst, $src\t#@decodeKlass_not_null" %} ++ ++ ins_encode %{ ++ Register src_reg = as_Register($src$$reg); ++ Register dst_reg = as_Register($dst$$reg); ++ Register tmp_reg = as_Register($tmp$$reg); ++ __ decode_klass_not_null(dst_reg, src_reg, tmp_reg); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++// stack <-> reg and reg <-> reg shuffles with no conversion ++ ++instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ ++ ++ match(Set dst (MoveF2I src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(LOAD_COST); ++ ++ format %{ "lw $dst, $src\t#@MoveF2I_stack_reg" %} ++ ++ ins_encode %{ ++ __ lw(as_Register($dst$$reg), Address(sp, $src$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_reg); ++ ++%} ++ ++instruct MoveI2F_stack_reg(fRegF dst, stackSlotI src) %{ ++ ++ match(Set dst (MoveI2F src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(LOAD_COST); ++ ++ format %{ "flw $dst, $src\t#@MoveI2F_stack_reg" %} ++ ++ ins_encode %{ ++ __ flw(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); ++ %} ++ ++ ins_pipe(fp_load_mem_s); ++ ++%} ++ ++instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ ++ ++ match(Set dst (MoveD2L src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(LOAD_COST); ++ ++ format %{ "ld $dst, $src\t#@MoveD2L_stack_reg" %} ++ ++ ins_encode %{ ++ __ ld(as_Register($dst$$reg), Address(sp, $src$$disp)); ++ %} ++ ++ ins_pipe(iload_reg_reg); ++ ++%} ++ ++instruct MoveL2D_stack_reg(fRegD dst, stackSlotL src) %{ ++ ++ match(Set dst (MoveL2D src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(LOAD_COST); ++ ++ format %{ "fld $dst, $src\t#@MoveL2D_stack_reg" %} ++ ++ ins_encode %{ ++ __ fld(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); ++ %} ++ ++ ins_pipe(fp_load_mem_d); ++ ++%} ++ ++instruct MoveF2I_reg_stack(stackSlotI dst, fRegF src) %{ ++ ++ match(Set dst (MoveF2I src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(STORE_COST); ++ ++ format %{ "fsw $src, $dst\t#@MoveF2I_reg_stack" %} ++ ++ ins_encode %{ ++ __ fsw(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); ++ %} ++ ++ ins_pipe(fp_store_reg_s); ++ ++%} ++ ++instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ ++ ++ match(Set dst (MoveI2F src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(STORE_COST); ++ ++ format %{ "sw $src, $dst\t#@MoveI2F_reg_stack" %} ++ ++ ins_encode %{ ++ __ sw(as_Register($src$$reg), Address(sp, $dst$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_reg); ++ ++%} ++ ++instruct MoveD2L_reg_stack(stackSlotL dst, fRegD src) %{ ++ ++ match(Set dst (MoveD2L src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(STORE_COST); ++ ++ format %{ "fsd $dst, $src\t#@MoveD2L_reg_stack" %} ++ ++ ins_encode %{ ++ __ fsd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); ++ %} ++ ++ ins_pipe(fp_store_reg_d); ++ ++%} ++ ++instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ ++ ++ match(Set dst (MoveL2D src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(STORE_COST); ++ ++ format %{ "sd $src, $dst\t#@MoveL2D_reg_stack" %} ++ ++ ins_encode %{ ++ __ sd(as_Register($src$$reg), Address(sp, $dst$$disp)); ++ %} ++ ++ ins_pipe(istore_reg_reg); ++ ++%} ++ ++instruct MoveF2I_reg_reg(iRegINoSp dst, fRegF src) %{ ++ ++ match(Set dst (MoveF2I src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(XFER_COST); ++ ++ format %{ "fmv.x.w $dst, $src\t#@MoveL2D_reg_stack" %} ++ ++ ins_encode %{ ++ __ fmv_x_w(as_Register($dst$$reg), as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_f2i); ++ ++%} ++ ++instruct MoveI2F_reg_reg(fRegF dst, iRegI src) %{ ++ ++ match(Set dst (MoveI2F src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(XFER_COST); ++ ++ format %{ "fmv.w.x $dst, $src\t#@MoveI2F_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmv_w_x(as_FloatRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(fp_i2f); ++ ++%} ++ ++instruct MoveD2L_reg_reg(iRegLNoSp dst, fRegD src) %{ ++ ++ match(Set dst (MoveD2L src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(XFER_COST); ++ ++ format %{ "fmv.x.d $dst, $src\t#@MoveD2L_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmv_x_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); ++ %} ++ ++ ins_pipe(fp_d2l); ++ ++%} ++ ++instruct MoveL2D_reg_reg(fRegD dst, iRegL src) %{ ++ ++ match(Set dst (MoveL2D src)); ++ ++ effect(DEF dst, USE src); ++ ++ ins_cost(XFER_COST); ++ ++ format %{ "fmv.d.x $dst, $src\t#@MoveD2L_reg_reg" %} ++ ++ ins_encode %{ ++ __ fmv_d_x(as_FloatRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(fp_l2d); ++ ++%} ++ ++// ============================================================================ ++// Compare Instructions which set the result float comparisons in dest register. ++ ++instruct cmpF3_reg_reg(iRegINoSp dst, fRegF op1, fRegF op2) ++%{ ++ match(Set dst (CmpF3 op1 op2)); ++ ++ ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST); ++ format %{ "flt.s $dst, $op2, $op1\t#@cmpF3_reg_reg\n\t" ++ "bgtz $dst, done\n\t" ++ "feq.s $dst, $op1, $op2\n\t" ++ "addi $dst, $dst, -1\t#@cmpF3_reg_reg" ++ %} ++ ++ ins_encode %{ ++ // we want -1 for unordered or less than, 0 for equal and 1 for greater than. ++ __ float_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg), ++ as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct cmpD3_reg_reg(iRegINoSp dst, fRegD op1, fRegD op2) ++%{ ++ match(Set dst (CmpD3 op1 op2)); ++ ++ ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST); ++ format %{ "flt.d $dst, $op2, $op1\t#@cmpD3_reg_reg\n\t" ++ "bgtz $dst, done\n\t" ++ "feq.d $dst, $op1, $op2\n\t" ++ "addi $dst, $dst, -1\t#@cmpD3_reg_reg" ++ %} ++ ++ ins_encode %{ ++ // we want -1 for unordered or less than, 0 for equal and 1 for greater than. ++ __ double_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct cmpL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2) ++%{ ++ match(Set dst (CmpL3 op1 op2)); ++ ++ ins_cost(ALU_COST * 3 + BRANCH_COST); ++ format %{ "slt $dst, $op2, $op1\t#@cmpL3_reg_reg\n\t" ++ "bnez $dst, done\n\t" ++ "slt $dst, $op1, $op2\n\t" ++ "neg $dst, $dst\t#@cmpL3_reg_reg" ++ %} ++ ins_encode %{ ++ __ cmp_l2i(t0, as_Register($op1$$reg), as_Register($op2$$reg)); ++ __ mv(as_Register($dst$$reg), t0); ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q) ++%{ ++ match(Set dst (CmpLTMask p q)); ++ ++ ins_cost(2 * ALU_COST); ++ ++ format %{ "slt $dst, $p, $q\t#@cmpLTMask_reg_reg\n\t" ++ "subw $dst, zr, $dst\t#@cmpLTMask_reg_reg" ++ %} ++ ++ ins_encode %{ ++ __ slt(as_Register($dst$$reg), as_Register($p$$reg), as_Register($q$$reg)); ++ __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I op, immI0 zero) ++%{ ++ match(Set dst (CmpLTMask op zero)); ++ ++ ins_cost(ALU_COST); ++ ++ format %{ "sraiw $dst, $dst, 31\t#@cmpLTMask_reg_reg" %} ++ ++ ins_encode %{ ++ __ sraiw(as_Register($dst$$reg), as_Register($op$$reg), 31); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++ ++// ============================================================================ ++// Max and Min ++ ++instruct minI_reg_reg(iRegINoSp dst, iRegI src) ++%{ ++ match(Set dst (MinI dst src)); ++ ++ ins_cost(BRANCH_COST + ALU_COST); ++ format %{ ++ "ble $dst, $src, skip\t#@minI_reg_reg\n\t" ++ "mv $dst, $src\n\t" ++ "skip:" ++ %} ++ ++ ins_encode %{ ++ Label Lskip; ++ __ ble(as_Register($dst$$reg), as_Register($src$$reg), Lskip); ++ __ mv(as_Register($dst$$reg), as_Register($src$$reg)); ++ __ bind(Lskip); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct maxI_reg_reg(iRegINoSp dst, iRegI src) ++%{ ++ match(Set dst (MaxI dst src)); ++ ++ ins_cost(BRANCH_COST + ALU_COST); ++ format %{ ++ "bge $dst, $src, skip\t#@maxI_reg_reg\n\t" ++ "mv $dst, $src\n\t" ++ "skip:" ++ %} ++ ++ ins_encode %{ ++ Label Lskip; ++ __ bge(as_Register($dst$$reg), as_Register($src$$reg), Lskip); ++ __ mv(as_Register($dst$$reg), as_Register($src$$reg)); ++ __ bind(Lskip); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++// special case for comparing with zero ++// n.b. this is selected in preference to the rule above because it ++// avoids loading constant 0 into a source register ++ ++instruct minI_reg_zero(iRegINoSp dst, immI0 zero) ++%{ ++ match(Set dst (MinI dst zero)); ++ match(Set dst (MinI zero dst)); ++ ++ ins_cost(BRANCH_COST + ALU_COST); ++ format %{ ++ "blez $dst, skip\t#@minI_reg_zero\n\t" ++ "mv $dst, zr\n\t" ++ "skip:" ++ %} ++ ++ ins_encode %{ ++ Label Lskip; ++ __ blez(as_Register($dst$$reg), Lskip); ++ __ mv(as_Register($dst$$reg), zr); ++ __ bind(Lskip); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct maxI_reg_zero(iRegINoSp dst, immI0 zero) ++%{ ++ match(Set dst (MaxI dst zero)); ++ match(Set dst (MaxI zero dst)); ++ ++ ins_cost(BRANCH_COST + ALU_COST); ++ format %{ ++ "bgez $dst, skip\t#@maxI_reg_zero\n\t" ++ "mv $dst, zr\n\t" ++ "skip:" ++ %} ++ ++ ins_encode %{ ++ Label Lskip; ++ __ bgez(as_Register($dst$$reg), Lskip); ++ __ mv(as_Register($dst$$reg), zr); ++ __ bind(Lskip); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) ++%{ ++ match(Set dst (MinI src1 src2)); ++ ++ effect(DEF dst, USE src1, USE src2); ++ ++ ins_cost(BRANCH_COST + ALU_COST * 2); ++ format %{ ++ "ble $src1, $src2, Lsrc1.\t#@minI_rReg\n\t" ++ "mv $dst, $src2\n\t" ++ "j Ldone\n\t" ++ "bind Lsrc1\n\t" ++ "mv $dst, $src1\n\t" ++ "bind\t#@minI_rReg" ++ %} ++ ++ ins_encode %{ ++ Label Lsrc1, Ldone; ++ __ ble(as_Register($src1$$reg), as_Register($src2$$reg), Lsrc1); ++ __ mv(as_Register($dst$$reg), as_Register($src2$$reg)); ++ __ j(Ldone); ++ __ bind(Lsrc1); ++ __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); ++ __ bind(Ldone); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) ++%{ ++ match(Set dst (MaxI src1 src2)); ++ ++ effect(DEF dst, USE src1, USE src2); ++ ++ ins_cost(BRANCH_COST + ALU_COST * 2); ++ format %{ ++ "bge $src1, $src2, Lsrc1\t#@maxI_rReg\n\t" ++ "mv $dst, $src2\n\t" ++ "j Ldone\n\t" ++ "bind Lsrc1\n\t" ++ "mv $dst, $src1\n\t" ++ "bind\t#@maxI_rReg" ++ %} ++ ++ ins_encode %{ ++ Label Lsrc1, Ldone; ++ __ bge(as_Register($src1$$reg), as_Register($src2$$reg), Lsrc1); ++ __ mv(as_Register($dst$$reg), as_Register($src2$$reg)); ++ __ j(Ldone); ++ __ bind(Lsrc1); ++ __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); ++ __ bind(Ldone); ++ ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++// ============================================================================ ++// Branch Instructions ++// Direct Branch. ++instruct branch(label lbl) ++%{ ++ match(Goto); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "j $lbl\t#@branch" %} ++ ++ ins_encode(riscv_enc_j(lbl)); ++ ++ ins_pipe(pipe_branch); ++%} ++ ++// ============================================================================ ++// Compare and Branch Instructions ++ ++// Patterns for short (< 12KiB) variants ++ ++// Compare flags and branch near instructions. ++instruct cmpFlag_branch(cmpOpEqNe cmp, rFlagsReg cr, label lbl) %{ ++ match(If cmp cr); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $cr, zr, $lbl\t#@cmpFlag_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label)); ++ %} ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare signed int and branch near instructions ++instruct cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl) ++%{ ++ // Same match rule as `far_cmpI_branch'. ++ match(If cmp (CmpI op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpI_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl) ++%{ ++ // Same match rule as `far_cmpI_loop'. ++ match(CountedLoopEnd cmp (CmpI op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpI_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare unsigned int and branch near instructions ++instruct cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) ++%{ ++ // Same match rule as `far_cmpU_branch'. ++ match(If cmp (CmpU op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpU_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpU_loop(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) ++%{ ++ // Same match rule as `far_cmpU_loop'. ++ match(CountedLoopEnd cmp (CmpU op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpU_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare signed long and branch near instructions ++instruct cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl) ++%{ ++ // Same match rule as `far_cmpL_branch'. ++ match(If cmp (CmpL op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpL_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpL_loop(cmpOp cmp, iRegL op1, iRegL op2, label lbl) ++%{ ++ // Same match rule as `far_cmpL_loop'. ++ match(CountedLoopEnd cmp (CmpL op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpL_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare unsigned long and branch near instructions ++instruct cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) ++%{ ++ // Same match rule as `far_cmpUL_branch'. ++ match(If cmp (CmpUL op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpUL_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpUL_loop(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) ++%{ ++ // Same match rule as `far_cmpUL_loop'. ++ match(CountedLoopEnd cmp (CmpUL op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpUL_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare pointer and branch near instructions ++instruct cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) ++%{ ++ // Same match rule as `far_cmpP_branch'. ++ match(If cmp (CmpP op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpP_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpP_loop(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) ++%{ ++ // Same match rule as `far_cmpP_loop'. ++ match(CountedLoopEnd cmp (CmpP op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpP_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare narrow pointer and branch near instructions ++instruct cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) ++%{ ++ // Same match rule as `far_cmpN_branch'. ++ match(If cmp (CmpN op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpN_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpN_loop(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) ++%{ ++ // Same match rule as `far_cmpN_loop'. ++ match(CountedLoopEnd cmp (CmpN op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, $op2, $lbl\t#@cmpN_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare float and branch near instructions ++instruct cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl) ++%{ ++ // Same match rule as `far_cmpF_branch'. ++ match(If cmp (CmpF op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST); ++ format %{ "float_b$cmp $op1, $op2, $lbl \t#@cmpF_branch"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++ ins_short_branch(1); ++%} ++ ++instruct cmpF_loop(cmpOp cmp, fRegF op1, fRegF op2, label lbl) ++%{ ++ // Same match rule as `far_cmpF_loop'. ++ match(CountedLoopEnd cmp (CmpF op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST); ++ format %{ "float_b$cmp $op1, $op2, $lbl\t#@cmpF_loop"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++ ins_short_branch(1); ++%} ++ ++// Compare double and branch near instructions ++instruct cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl) ++%{ ++ // Same match rule as `far_cmpD_branch'. ++ match(If cmp (CmpD op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST); ++ format %{ "double_b$cmp $op1, $op2, $lbl\t#@cmpD_branch"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), ++ as_FloatRegister($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++ ins_short_branch(1); ++%} ++ ++instruct cmpD_loop(cmpOp cmp, fRegD op1, fRegD op2, label lbl) ++%{ ++ // Same match rule as `far_cmpD_loop'. ++ match(CountedLoopEnd cmp (CmpD op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST); ++ format %{ "double_b$cmp $op1, $op2, $lbl\t#@cmpD_loop"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), ++ as_FloatRegister($op2$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++ ins_short_branch(1); ++%} ++ ++// Compare signed int with zero and branch near instructions ++instruct cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpI_reg_imm0_branch'. ++ match(If cmp (CmpI op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpI_reg_imm0_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpI_reg_imm0_loop'. ++ match(CountedLoopEnd cmp (CmpI op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpI_reg_imm0_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare unsigned int with zero and branch near instructions ++instruct cmpUEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpUEqNeLeGt_reg_imm0_branch'. ++ match(If cmp (CmpU op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpUEqNeLeGt_reg_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpUEqNeLeGt_reg_imm0_loop(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpUEqNeLeGt_reg_imm0_loop'. ++ match(CountedLoopEnd cmp (CmpU op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpUEqNeLeGt_reg_imm0_loop" %} ++ ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare signed long with zero and branch near instructions ++instruct cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpL_reg_imm0_branch'. ++ match(If cmp (CmpL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpL_reg_imm0_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpL_reg_imm0_loop'. ++ match(CountedLoopEnd cmp (CmpL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpL_reg_imm0_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare unsigned long with zero and branch near instructions ++instruct cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpULEqNeLeGt_reg_imm0_branch'. ++ match(If cmp (CmpUL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpULEqNeLeGt_reg_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpULEqNeLeGt_reg_imm0_loop(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ // Same match rule as `far_cmpULEqNeLeGt_reg_imm0_loop'. ++ match(CountedLoopEnd cmp (CmpUL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpULEqNeLeGt_reg_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare pointer with zero and branch near instructions ++instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ ++ // Same match rule as `far_cmpP_reg_imm0_branch'. ++ match(If cmp (CmpP op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpP_imm0_loop(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ ++ // Same match rule as `far_cmpP_reg_imm0_loop'. ++ match(CountedLoopEnd cmp (CmpP op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare narrow pointer with zero and branch near instructions ++instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ ++ // Same match rule as `far_cmpN_reg_imm0_branch'. ++ match(If cmp (CmpN op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpN_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpN_imm0_loop(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ ++ // Same match rule as `far_cmpN_reg_imm0_loop'. ++ match(CountedLoopEnd cmp (CmpN op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpN_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Compare narrow pointer with pointer zero and branch near instructions ++instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ ++ // Same match rule as `far_cmpP_narrowOop_imm0_branch'. ++ match(If cmp (CmpP (DecodeN op1) zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_narrowOop_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++instruct cmpP_narrowOop_imm0_loop(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ ++ // Same match rule as `far_cmpP_narrowOop_imm0_loop'. ++ match(CountedLoopEnd cmp (CmpP (DecodeN op1) zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_narrowOop_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++ ins_short_branch(1); ++%} ++ ++// Patterns for far (20KiB) variants ++ ++instruct far_cmpFlag_branch(cmpOp cmp, rFlagsReg cr, label lbl) %{ ++ match(If cmp cr); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "far_b$cmp $cr, zr, $lbl\t#@far_cmpFlag_branch"%} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++// Compare signed int and branch far instructions ++instruct far_cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{ ++ match(If cmp (CmpI op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ // the format instruction [far_b$cmp] here is be used as two insructions ++ // in macroassembler: b$not_cmp(op1, op2, done), j($lbl), bind(done) ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpI_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{ ++ match(CountedLoopEnd cmp (CmpI op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpI_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) %{ ++ match(If cmp (CmpU op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpU_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpU_loop(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) %{ ++ match(CountedLoopEnd cmp (CmpU op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpU_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{ ++ match(If cmp (CmpL op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpL_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpLloop(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{ ++ match(CountedLoopEnd cmp (CmpL op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpL_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) %{ ++ match(If cmp (CmpUL op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpUL_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpUL_loop(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) %{ ++ match(CountedLoopEnd cmp (CmpUL op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpUL_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) ++%{ ++ match(If cmp (CmpP op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpP_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpP_loop(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpP op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpP_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) ++%{ ++ match(If cmp (CmpN op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpN_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++instruct far_cmpN_loop(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpN op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpN_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), ++ as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmp_branch); ++%} ++ ++// Float compare and branch instructions ++instruct far_cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl) ++%{ ++ match(If cmp (CmpF op1 op2)); ++ ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST * 2); ++ format %{ "far_float_b$cmp $op1, $op2, $lbl\t#@far_cmpF_branch"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), ++ *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct far_cmpF_loop(cmpOp cmp, fRegF op1, fRegF op2, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpF op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST * 2); ++ format %{ "far_float_b$cmp $op1, $op2, $lbl\t#@far_cmpF_loop"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), ++ *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++// Double compare and branch instructions ++instruct far_cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl) ++%{ ++ match(If cmp (CmpD op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST * 2); ++ format %{ "far_double_b$cmp $op1, $op2, $lbl\t#@far_cmpD_branch"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), ++ as_FloatRegister($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct far_cmpD_loop(cmpOp cmp, fRegD op1, fRegD op2, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpD op1 op2)); ++ effect(USE lbl); ++ ++ ins_cost(XFER_COST + BRANCH_COST * 2); ++ format %{ "far_double_b$cmp $op1, $op2, $lbl\t#@far_cmpD_loop"%} ++ ++ ins_encode %{ ++ __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), ++ as_FloatRegister($op2$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct far_cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ match(If cmp (CmpI op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpI_reg_imm0_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpI op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpI_reg_imm0_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpUEqNeLeGt_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ match(If cmp (CmpU op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpUEqNeLeGt_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpUEqNeLeGt_reg_imm0_loop(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpU op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpUEqNeLeGt_reg_imm0_loop" %} ++ ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++// compare lt/ge unsigned instructs has no short instruct with same match ++instruct far_cmpULtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ match(If cmp (CmpU op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "j $lbl if $cmp == ge\t#@far_cmpULtGe_reg_imm0_branch" %} ++ ++ ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpULtGe_reg_imm0_loop(cmpOpULtGe cmp, iRegI op1, immI0 zero, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpU op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "j $lbl if $cmp == ge\t#@far_cmpULtGe_reg_imm0_loop" %} ++ ++ ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ match(If cmp (CmpL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpL_reg_imm0_branch" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpL_reg_imm0_loop" %} ++ ++ ins_encode %{ ++ __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ match(If cmp (CmpUL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpULEqNeLeGt_reg_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpULEqNeLeGt_reg_imm0_loop(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpUL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpULEqNeLeGt_reg_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++// compare lt/ge unsigned instructs has no short instruct with same match ++instruct far_cmpULLtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ match(If cmp (CmpUL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "j $lbl if $cmp == ge\t#@far_cmpULLtGe_reg_imm0_branch" %} ++ ++ ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpULLtGe_reg_imm0_loop(cmpOpULtGe cmp, iRegL op1, immL0 zero, label lbl) ++%{ ++ match(CountedLoopEnd cmp (CmpUL op1 zero)); ++ ++ effect(USE op1, USE lbl); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "j $lbl if $cmp == ge\t#@far_cmpULLtGe_reg_imm0_loop" %} ++ ++ ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ ++ match(If cmp (CmpP op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpP_imm0_loop(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ ++ match(CountedLoopEnd cmp (CmpP op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ ++ match(If cmp (CmpN op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpN_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpN_imm0_loop(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ ++ match(CountedLoopEnd cmp (CmpN op1 zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpN_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ ++ match(If cmp (CmpP (DecodeN op1) zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_narrowOop_imm0_branch" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++instruct far_cmpP_narrowOop_imm0_loop(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ ++ match(CountedLoopEnd cmp (CmpP (DecodeN op1) zero)); ++ effect(USE lbl); ++ ++ ins_cost(BRANCH_COST * 2); ++ format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_narrowOop_imm0_loop" %} ++ ++ ins_encode %{ ++ __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); ++ %} ++ ++ ins_pipe(pipe_cmpz_branch); ++%} ++ ++// ============================================================================ ++// Conditional Move Instructions ++instruct cmovI_cmpI(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOp cop) %{ ++ match(Set dst (CMoveI (Binary cop (CmpI op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpI\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct cmovI_cmpU(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOpU cop) %{ ++ match(Set dst (CMoveI (Binary cop (CmpU op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpU\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct cmovI_cmpL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOp cop) %{ ++ match(Set dst (CMoveI (Binary cop (CmpL op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpL\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct cmovI_cmpUL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOpU cop) %{ ++ match(Set dst (CMoveI (Binary cop (CmpUL op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpUL\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct cmovL_cmpL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOp cop) %{ ++ match(Set dst (CMoveL (Binary cop (CmpL op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpL\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct cmovL_cmpUL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOpU cop) %{ ++ match(Set dst (CMoveL (Binary cop (CmpUL op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpUL\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct cmovL_cmpI(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOp cop) %{ ++ match(Set dst (CMoveL (Binary cop (CmpI op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpI\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++instruct cmovL_cmpU(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOpU cop) %{ ++ match(Set dst (CMoveL (Binary cop (CmpU op1 op2)) (Binary dst src))); ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ ++ "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpU\n\t" ++ %} ++ ++ ins_encode %{ ++ __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, ++ as_Register($op1$$reg), as_Register($op2$$reg), ++ as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(pipe_class_compare); ++%} ++ ++// ============================================================================ ++// Procedure Call/Return Instructions ++ ++// Call Java Static Instruction ++// Note: If this code changes, the corresponding ret_addr_offset() and ++// compute_padding() functions will have to be adjusted. ++instruct CallStaticJavaDirect(method meth) ++%{ ++ match(CallStaticJava); ++ ++ effect(USE meth); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "CALL,static $meth\t#@CallStaticJavaDirect" %} ++ ++ ins_encode(riscv_enc_java_static_call(meth), ++ riscv_enc_call_epilog); ++ ++ ins_pipe(pipe_class_call); ++ ins_alignment(4); ++%} ++ ++// TO HERE ++ ++// Call Java Dynamic Instruction ++// Note: If this code changes, the corresponding ret_addr_offset() and ++// compute_padding() functions will have to be adjusted. ++instruct CallDynamicJavaDirect(method meth, rFlagsReg cr) ++%{ ++ match(CallDynamicJava); ++ ++ effect(USE meth, KILL cr); ++ ++ ins_cost(BRANCH_COST + ALU_COST * 6); ++ ++ format %{ "CALL,dynamic $meth\t#@CallDynamicJavaDirect" %} ++ ++ ins_encode(riscv_enc_java_dynamic_call(meth), ++ riscv_enc_call_epilog); ++ ++ ins_pipe(pipe_class_call); ++ ins_alignment(4); ++%} ++ ++// Call Runtime Instruction ++ ++instruct CallRuntimeDirect(method meth, rFlagsReg cr) ++%{ ++ match(CallRuntime); ++ ++ effect(USE meth, KILL cr); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "CALL, runtime $meth\t#@CallRuntimeDirect" %} ++ ++ ins_encode(riscv_enc_java_to_runtime(meth)); ++ ++ ins_pipe(pipe_class_call); ++%} ++ ++// Call Runtime Instruction ++ ++instruct CallLeafDirect(method meth, rFlagsReg cr) ++%{ ++ match(CallLeaf); ++ ++ effect(USE meth, KILL cr); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "CALL, runtime leaf $meth\t#@CallLeafDirect" %} ++ ++ ins_encode(riscv_enc_java_to_runtime(meth)); ++ ++ ins_pipe(pipe_class_call); ++%} ++ ++// Call Runtime Instruction ++ ++instruct CallLeafNoFPDirect(method meth, rFlagsReg cr) ++%{ ++ match(CallLeafNoFP); ++ ++ effect(USE meth, KILL cr); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %} ++ ++ ins_encode(riscv_enc_java_to_runtime(meth)); ++ ++ ins_pipe(pipe_class_call); ++%} ++ ++// ============================================================================ ++// Partial Subtype Check ++// ++// superklass array for an instance of the superklass. Set a hidden ++// internal cache on a hit (cache is checked with exposed code in ++// gen_subtype_check()). Return zero for a hit. The encoding ++// ALSO sets flags. ++ ++instruct partialSubtypeCheck(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, rFlagsReg cr) ++%{ ++ match(Set result (PartialSubtypeCheck sub super)); ++ effect(KILL tmp, KILL cr); ++ ++ ins_cost(2 * STORE_COST + 3 * LOAD_COST + 4 * ALU_COST + BRANCH_COST * 4); ++ format %{ "partialSubtypeCheck $result, $sub, $super\t#@partialSubtypeCheck" %} ++ ++ ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); ++ ++ opcode(0x1); // Force zero of result reg on hit ++ ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct partialSubtypeCheckVsZero(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, ++ immP0 zero, rFlagsReg cr) ++%{ ++ match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); ++ effect(KILL tmp, KILL result); ++ ++ ins_cost(2 * STORE_COST + 3 * LOAD_COST + 4 * ALU_COST + BRANCH_COST * 4); ++ format %{ "partialSubtypeCheck $result, $sub, $super == 0\t#@partialSubtypeCheckVsZero" %} ++ ++ ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); ++ ++ opcode(0x0); // Don't zero result reg on hit ++ ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result (StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); ++ ++ format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %} ++ ins_encode %{ ++ // Count is in 8-bit bytes; non-Compact chars are 16 bits. ++ __ string_compare($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, ++ StrIntrinsicNode::UU); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result (StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); ++ ++ format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %} ++ ins_encode %{ ++ __ string_compare($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, ++ StrIntrinsicNode::LL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL); ++ match(Set result (StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); ++ ++ format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %} ++ ins_encode %{ ++ __ string_compare($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, ++ StrIntrinsicNode::UL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, ++ rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU); ++ match(Set result (StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); ++ ++ format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %} ++ ins_encode %{ ++ __ string_compare($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, ++ StrIntrinsicNode::LU); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_indexofUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, ++ iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) ++%{ ++ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); ++ ++ format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} ++ ins_encode %{ ++ __ string_indexof($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, ++ $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, ++ $tmp5$$Register, $tmp6$$Register, ++ $result$$Register, StrIntrinsicNode::UU); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_indexofLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, ++ iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) ++%{ ++ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); ++ ++ format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} ++ ins_encode %{ ++ __ string_indexof($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, ++ $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, ++ $tmp5$$Register, $tmp6$$Register, ++ $result$$Register, StrIntrinsicNode::LL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_indexofUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, ++ iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) ++%{ ++ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); ++ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); ++ format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} ++ ++ ins_encode %{ ++ __ string_indexof($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, ++ $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, ++ $tmp5$$Register, $tmp6$$Register, ++ $result$$Register, StrIntrinsicNode::UL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_indexof_conUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, ++ immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, ++ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) ++%{ ++ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); ++ ++ format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} ++ ++ ins_encode %{ ++ int icnt2 = (int)$int_cnt2$$constant; ++ __ string_indexof_linearscan($str1$$Register, $str2$$Register, ++ $cnt1$$Register, zr, ++ $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, ++ icnt2, $result$$Register, StrIntrinsicNode::UU); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_indexof_conLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, ++ immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, ++ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) ++%{ ++ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); ++ ++ format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} ++ ins_encode %{ ++ int icnt2 = (int)$int_cnt2$$constant; ++ __ string_indexof_linearscan($str1$$Register, $str2$$Register, ++ $cnt1$$Register, zr, ++ $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, ++ icnt2, $result$$Register, StrIntrinsicNode::LL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_indexof_conUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, ++ immI_1 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, ++ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) ++%{ ++ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); ++ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); ++ ++ format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} ++ ins_encode %{ ++ int icnt2 = (int)$int_cnt2$$constant; ++ __ string_indexof_linearscan($str1$$Register, $str2$$Register, ++ $cnt1$$Register, zr, ++ $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, ++ icnt2, $result$$Register, StrIntrinsicNode::UL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct stringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, ++ iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, ++ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) ++%{ ++ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); ++ predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); ++ effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); ++ ++ format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %} ++ ins_encode %{ ++ __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, ++ $result$$Register, $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, false /* isU */); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++ ++instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, ++ iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, ++ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) ++%{ ++ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); ++ predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); ++ effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result, ++ TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); ++ ++ format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %} ++ ins_encode %{ ++ __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, ++ $result$$Register, $tmp1$$Register, $tmp2$$Register, ++ $tmp3$$Register, $tmp4$$Register, true /* isL */); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++// clearing of an array ++instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, Universe dummy) ++%{ ++ predicate(!UseRVV); ++ match(Set dummy (ClearArray cnt base)); ++ effect(USE_KILL cnt, USE_KILL base); ++ ++ ins_cost(4 * DEFAULT_COST); ++ format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %} ++ ++ ins_encode %{ ++ address tpc = __ zero_words($base$$Register, $cnt$$Register); ++ if (tpc == NULL) { ++ ciEnv::current()->record_failure("CodeCache is full"); ++ return; ++ } ++ %} ++ ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && (uint64_t)n->in(2)->get_long() ++ < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); ++ match(Set dummy (ClearArray cnt base)); ++ effect(USE_KILL base, KILL cr); ++ ++ ins_cost(4 * DEFAULT_COST); ++ format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %} ++ ++ ins_encode %{ ++ __ zero_words($base$$Register, (uint64_t)$cnt$$constant); ++ %} ++ ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, ++ iRegI_R10 result, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result (StrEquals (Binary str1 str2) cnt)); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); ++ ++ format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %} ++ ins_encode %{ ++ // Count is in 8-bit bytes; non-Compact chars are 16 bits. ++ __ string_equals($str1$$Register, $str2$$Register, ++ $result$$Register, $cnt$$Register, 1); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct string_equalsU(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, ++ iRegI_R10 result, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result (StrEquals (Binary str1 str2) cnt)); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); ++ ++ format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsU" %} ++ ins_encode %{ ++ // Count is in 8-bit bytes; non-Compact chars are 16 bits. ++ __ string_equals($str1$$Register, $str2$$Register, ++ $result$$Register, $cnt$$Register, 2); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct array_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, ++ iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3, ++ iRegP_R16 tmp4, iRegP_R28 tmp5, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result (AryEq ary1 ary2)); ++ effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL tmp5, KILL cr); ++ ++ format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsB // KILL $tmp5" %} ++ ins_encode %{ ++ __ arrays_equals($ary1$$Register, $ary2$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, ++ $result$$Register, $tmp5$$Register, 1); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct array_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, ++ iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3, ++ iRegP_R16 tmp4, iRegP_R28 tmp5, rFlagsReg cr) ++%{ ++ predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result (AryEq ary1 ary2)); ++ effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL tmp5, KILL cr); ++ ++ format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsC // KILL $tmp5" %} ++ ins_encode %{ ++ __ arrays_equals($ary1$$Register, $ary2$$Register, ++ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, ++ $result$$Register, $tmp5$$Register, 2); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++// ============================================================================ ++// Safepoint Instructions ++ ++instruct safePoint(iRegP poll) ++%{ ++ match(SafePoint poll); ++ ++ ins_cost(2 * LOAD_COST); ++ format %{ ++ "lwu zr, [$poll]\t# Safepoint: poll for GC, #@safePoint" ++ %} ++ ins_encode %{ ++ __ read_polling_page(as_Register($poll$$reg), 0, relocInfo::poll_type); ++ %} ++ ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); ++%} ++ ++// ============================================================================ ++// This name is KNOWN by the ADLC and cannot be changed. ++// The ADLC forces a 'TypeRawPtr::BOTTOM' output type ++// for this guy. ++instruct tlsLoadP(javaThread_RegP dst) ++%{ ++ match(Set dst (ThreadLocal)); ++ ++ ins_cost(0); ++ ++ format %{ " -- \t// $dst=Thread::current(), empty, #@tlsLoadP" %} ++ ++ size(0); ++ ++ ins_encode( /*empty*/ ); ++ ++ ins_pipe(pipe_class_empty); ++%} ++ ++// 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) ++%{ ++ match(Set cr (FastLock object box)); ++ effect(TEMP tmp1, TEMP tmp2); ++ ++ ins_cost(LOAD_COST * 2 + STORE_COST * 3 + ALU_COST * 6 + BRANCH_COST * 3); ++ format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2, #@cmpFastLock" %} ++ ++ ins_encode(riscv_enc_fast_lock(object, box, tmp1, tmp2)); ++ ++ ins_pipe(pipe_serial); ++%} ++ ++// using t1 as the 'flag' register to bridge the BoolNode producers and consumers ++instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2) ++%{ ++ match(Set cr (FastUnlock object box)); ++ effect(TEMP tmp1, TEMP tmp2); ++ ++ 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_pipe(pipe_serial); ++%} ++ ++// Tail Call; Jump from runtime stub to Java code. ++// Also known as an 'interprocedural jump'. ++// Target of jump will eventually return to caller. ++// TailJump below removes the return address. ++instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) ++%{ ++ match(TailCall jump_target method_oop); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "jalr $jump_target\t# $method_oop holds method oop, #@TailCalljmpInd." %} ++ ++ ins_encode(riscv_enc_tail_call(jump_target)); ++ ++ ins_pipe(pipe_class_call); ++%} ++ ++instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R10 ex_oop) ++%{ ++ match(TailJump jump_target ex_oop); ++ ++ ins_cost(ALU_COST + BRANCH_COST); ++ ++ format %{ "jalr $jump_target\t# $ex_oop holds exception oop, #@TailjmpInd." %} ++ ++ ins_encode(riscv_enc_tail_jmp(jump_target)); ++ ++ ins_pipe(pipe_class_call); ++%} ++ ++// Create exception oop: created by stack-crawling runtime code. ++// Created exception is now available to this handler, and is setup ++// just prior to jumping to this handler. No code emitted. ++instruct CreateException(iRegP_R10 ex_oop) ++%{ ++ match(Set ex_oop (CreateEx)); ++ ++ ins_cost(0); ++ format %{ " -- \t// exception oop; no code emitted, #@CreateException" %} ++ ++ size(0); ++ ++ ins_encode( /*empty*/ ); ++ ++ ins_pipe(pipe_class_empty); ++%} ++ ++// Rethrow exception: The exception oop will come in the first ++// argument position. Then JUMP (not call) to the rethrow stub code. ++instruct RethrowException() ++%{ ++ match(Rethrow); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "j rethrow_stub\t#@RethrowException" %} ++ ++ ins_encode(riscv_enc_rethrow()); ++ ++ ins_pipe(pipe_class_call); ++%} ++ ++// Return Instruction ++// epilog node loads ret address into ra as part of frame pop ++instruct Ret() ++%{ ++ match(Return); ++ ++ ins_cost(BRANCH_COST); ++ format %{ "ret\t// return register, #@Ret" %} ++ ++ ins_encode(riscv_enc_ret()); ++ ++ ins_pipe(pipe_branch); ++%} ++ ++// Die now. ++instruct ShouldNotReachHere() %{ ++ match(Halt); ++ ++ ins_cost(BRANCH_COST); ++ ++ format %{ "#@ShouldNotReachHere" %} ++ ++ ins_encode %{ ++ if (is_reachable()) { ++ __ stop(_halt_reason); ++ } ++ %} ++ ++ ins_pipe(pipe_class_default); ++%} ++ ++ ++//----------PEEPHOLE RULES----------------------------------------------------- ++// These must follow all instruction definitions as they use the names ++// defined in the instructions definitions. ++// ++// peepmatch ( root_instr_name [preceding_instruction]* ); ++// ++// peepconstraint %{ ++// (instruction_number.operand_name relational_op instruction_number.operand_name ++// [, ...] ); ++// // instruction numbers are zero-based using left to right order in peepmatch ++// ++// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); ++// // provide an instruction_number.operand_name for each operand that appears ++// // in the replacement instruction's match rule ++// ++// ---------VM FLAGS--------------------------------------------------------- ++// ++// All peephole optimizations can be turned off using -XX:-OptoPeephole ++// ++// Each peephole rule is given an identifying number starting with zero and ++// increasing by one in the order seen by the parser. An individual peephole ++// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# ++// on the command-line. ++// ++// ---------CURRENT LIMITATIONS---------------------------------------------- ++// ++// Only match adjacent instructions in same basic block ++// Only equality constraints ++// Only constraints between operands, not (0.dest_reg == RAX_enc) ++// Only one replacement instruction ++// ++//----------SMARTSPILL RULES--------------------------------------------------- ++// These must follow all instruction definitions as they use the names ++// defined in the instructions definitions. ++ ++// Local Variables: ++// mode: c++ ++// End: +--- /dev/null ++++ b/src/hotspot/cpu/riscv/riscv_b.ad +@@ -0,0 +1,575 @@ ++// ++// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. ++// Copyright (c) 2022, 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. ++// ++// ++ ++// RISCV Bit-Manipulation Extension Architecture Description File ++ ++instruct rorI_imm_b(iRegINoSp dst, iRegI src, immI shift) %{ ++ predicate(UseZbb); ++ match(Set dst (RotateRight src shift)); ++ ++ format %{ "roriw $dst, $src, ($shift & 0x1f)\t#@rorI_imm_b" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ roriw(as_Register($dst$$reg), as_Register($src$$reg), $shift$$constant & 0x1f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++instruct rorL_imm_b(iRegLNoSp dst, iRegL src, immI shift) %{ ++ predicate(UseZbb); ++ match(Set dst (RotateRight src shift)); ++ ++ format %{ "rori $dst, $src, ($shift & 0x3f)\t#@rorL_imm_b" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ rori(as_Register($dst$$reg), as_Register($src$$reg), $shift$$constant & 0x3f); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++instruct rorI_reg_b(iRegINoSp dst, iRegI src, iRegI shift) %{ ++ predicate(UseZbb); ++ match(Set dst (RotateRight src shift)); ++ ++ format %{ "rorw $dst, $src, $shift\t#@rorI_reg_b" %} ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ rorw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); ++ %} ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct rorL_reg_b(iRegLNoSp dst, iRegL src, iRegI shift) %{ ++ predicate(UseZbb); ++ match(Set dst (RotateRight src shift)); ++ ++ format %{ "ror $dst, $src, $shift\t#@rorL_reg_b" %} ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ ror(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); ++ %} ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct rolI_reg_b(iRegINoSp dst, iRegI src, iRegI shift) %{ ++ predicate(UseZbb); ++ match(Set dst (RotateLeft src shift)); ++ ++ format %{ "rolw $dst, $src, $shift\t#@rolI_reg_b" %} ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ rolw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); ++ %} ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct rolL_reg_b(iRegLNoSp dst, iRegL src, iRegI shift) %{ ++ predicate(UseZbb); ++ match(Set dst (RotateLeft src shift)); ++ ++ format %{ "rol $dst, $src, $shift\t#@rolL_reg_b" %} ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ rol(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); ++ %} ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Convert oop into int for vectors alignment masking ++instruct convP2I_b(iRegINoSp dst, iRegP src) %{ ++ predicate(UseZba); ++ match(Set dst (ConvL2I (CastP2X src))); ++ ++ format %{ "zext.w $dst, $src\t# ptr -> int @convP2I_b" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ zext_w(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// byte to int ++instruct convB2I_reg_reg_b(iRegINoSp dst, iRegIorL2I src, immI_24 lshift, immI_24 rshift) %{ ++ predicate(UseZbb); ++ match(Set dst (RShiftI (LShiftI src lshift) rshift)); ++ ++ format %{ "sext.b $dst, $src\t# b2i, #@convB2I_reg_reg_b" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ sext_b(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// int to short ++instruct convI2S_reg_reg_b(iRegINoSp dst, iRegIorL2I src, immI_16 lshift, immI_16 rshift) %{ ++ predicate(UseZbb); ++ match(Set dst (RShiftI (LShiftI src lshift) rshift)); ++ ++ format %{ "sext.h $dst, $src\t# i2s, #@convI2S_reg_reg_b" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ sext_h(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// short to unsigned int ++instruct convS2UI_reg_reg_b(iRegINoSp dst, iRegIorL2I src, immI_16bits mask) %{ ++ predicate(UseZbb); ++ match(Set dst (AndI src mask)); ++ ++ format %{ "zext.h $dst, $src\t# s2ui, #@convS2UI_reg_reg_b" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ zext_h(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// int to unsigned long (zero extend) ++instruct convI2UL_reg_reg_b(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) %{ ++ predicate(UseZba); ++ match(Set dst (AndL (ConvI2L src) mask)); ++ ++ format %{ "zext.w $dst, $src\t# i2ul, #@convI2UL_reg_reg_b" %} ++ ++ ins_cost(ALU_COST); ++ ins_encode %{ ++ __ zext_w(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_shift); ++%} ++ ++// BSWAP instructions ++instruct bytes_reverse_int_b(iRegINoSp dst, iRegIorL2I src) %{ ++ predicate(UseZbb); ++ match(Set dst (ReverseBytesI src)); ++ ++ ins_cost(ALU_COST * 2); ++ format %{ "revb_w_w $dst, $src\t#@bytes_reverse_int_b" %} ++ ++ ins_encode %{ ++ __ revb_w_w(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct bytes_reverse_long_b(iRegLNoSp dst, iRegL src) %{ ++ predicate(UseZbb); ++ match(Set dst (ReverseBytesL src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "rev8 $dst, $src\t#@bytes_reverse_long_b" %} ++ ++ ins_encode %{ ++ __ rev8(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct bytes_reverse_unsigned_short_b(iRegINoSp dst, iRegIorL2I src) %{ ++ predicate(UseZbb); ++ match(Set dst (ReverseBytesUS src)); ++ ++ ins_cost(ALU_COST * 2); ++ format %{ "revb_h_h_u $dst, $src\t#@bytes_reverse_unsigned_short_b" %} ++ ++ ins_encode %{ ++ __ revb_h_h_u(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct bytes_reverse_short_b(iRegINoSp dst, iRegIorL2I src) %{ ++ predicate(UseZbb); ++ match(Set dst (ReverseBytesS src)); ++ ++ ins_cost(ALU_COST * 2); ++ format %{ "revb_h_h $dst, $src\t#@bytes_reverse_short_b" %} ++ ++ ins_encode %{ ++ __ revb_h_h(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Shift Add Pointer ++instruct shaddP_reg_reg_b(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale imm) %{ ++ predicate(UseZba); ++ match(Set dst (AddP src1 (LShiftL src2 imm))); ++ ++ ins_cost(ALU_COST); ++ format %{ "shadd $dst, $src2, $src1, $imm\t# ptr, #@shaddP_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ shadd(as_Register($dst$$reg), ++ as_Register($src2$$reg), ++ as_Register($src1$$reg), ++ t0, ++ $imm$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct shaddP_reg_reg_ext_b(iRegPNoSp dst, iRegP src1, iRegI src2, immIScale imm) %{ ++ predicate(UseZba); ++ match(Set dst (AddP src1 (LShiftL (ConvI2L src2) imm))); ++ ++ ins_cost(ALU_COST); ++ format %{ "shadd $dst, $src2, $src1, $imm\t# ptr, #@shaddP_reg_reg_ext_b" %} ++ ++ ins_encode %{ ++ __ shadd(as_Register($dst$$reg), ++ as_Register($src2$$reg), ++ as_Register($src1$$reg), ++ t0, ++ $imm$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Shift Add Long ++instruct shaddL_reg_reg_b(iRegLNoSp dst, iRegL src1, iRegL src2, immIScale imm) %{ ++ predicate(UseZba); ++ match(Set dst (AddL src1 (LShiftL src2 imm))); ++ ++ ins_cost(ALU_COST); ++ format %{ "shadd $dst, $src2, $src1, $imm\t#@shaddL_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ shadd(as_Register($dst$$reg), ++ as_Register($src2$$reg), ++ as_Register($src1$$reg), ++ t0, ++ $imm$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct shaddL_reg_reg_ext_b(iRegLNoSp dst, iRegL src1, iRegI src2, immIScale imm) %{ ++ predicate(UseZba); ++ match(Set dst (AddL src1 (LShiftL (ConvI2L src2) imm))); ++ ++ ins_cost(ALU_COST); ++ format %{ "shadd $dst, $src2, $src1, $imm\t#@shaddL_reg_reg_ext_b" %} ++ ++ ins_encode %{ ++ __ shadd(as_Register($dst$$reg), ++ as_Register($src2$$reg), ++ as_Register($src1$$reg), ++ t0, ++ $imm$$constant); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Zeros Count instructions ++instruct countLeadingZerosI_b(iRegINoSp dst, iRegIorL2I src) %{ ++ predicate(UseZbb); ++ match(Set dst (CountLeadingZerosI src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "clzw $dst, $src\t#@countLeadingZerosI_b" %} ++ ++ ins_encode %{ ++ __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct countLeadingZerosL_b(iRegINoSp dst, iRegL src) %{ ++ predicate(UseZbb); ++ match(Set dst (CountLeadingZerosL src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "clz $dst, $src\t#@countLeadingZerosL_b" %} ++ ++ ins_encode %{ ++ __ clz(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct countTrailingZerosI_b(iRegINoSp dst, iRegIorL2I src) %{ ++ predicate(UseZbb); ++ match(Set dst (CountTrailingZerosI src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "ctzw $dst, $src\t#@countTrailingZerosI_b" %} ++ ++ ins_encode %{ ++ __ ctzw(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++instruct countTrailingZerosL_b(iRegINoSp dst, iRegL src) %{ ++ predicate(UseZbb); ++ match(Set dst (CountTrailingZerosL src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "ctz $dst, $src\t#@countTrailingZerosL_b" %} ++ ++ ins_encode %{ ++ __ ctz(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Population Count instructions ++instruct popCountI_b(iRegINoSp dst, iRegIorL2I src) %{ ++ predicate(UsePopCountInstruction); ++ match(Set dst (PopCountI src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "cpopw $dst, $src\t#@popCountI_b" %} ++ ++ ins_encode %{ ++ __ cpopw(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Note: Long/bitCount(long) returns an int. ++instruct popCountL_b(iRegINoSp dst, iRegL src) %{ ++ predicate(UsePopCountInstruction); ++ match(Set dst (PopCountL src)); ++ ++ ins_cost(ALU_COST); ++ format %{ "cpop $dst, $src\t#@popCountL_b" %} ++ ++ ins_encode %{ ++ __ cpop(as_Register($dst$$reg), as_Register($src$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// Max and Min ++instruct minI_reg_reg_b(iRegINoSp dst, iRegI src1, iRegI src2) %{ ++ predicate(UseZbb); ++ match(Set dst (MinI src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "min $dst, $src1, $src2\t#@minI_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ min(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct maxI_reg_reg_b(iRegINoSp dst, iRegI src1, iRegI src2) %{ ++ predicate(UseZbb); ++ match(Set dst (MaxI src1 src2)); ++ ++ ins_cost(ALU_COST); ++ format %{ "max $dst, $src1, $src2\t#@maxI_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ max(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// special case for comparing with zero ++// n.b. this is selected in preference to the rule above because it ++// avoids loading constant 0 into a source register ++ ++instruct minI_reg_zero_b(iRegINoSp dst, iRegI src1, immI0 zero) %{ ++ predicate(UseZbb); ++ match(Set dst (MinI src1 zero)); ++ match(Set dst (MinI zero src1)); ++ ++ ins_cost(ALU_COST); ++ format %{ "min $dst, $src1, zr\t#@minI_reg_zero_b" %} ++ ++ ins_encode %{ ++ __ min(as_Register($dst$$reg), as_Register($src1$$reg), zr); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct maxI_reg_zero_b(iRegINoSp dst, iRegI src1, immI0 zero) %{ ++ predicate(UseZbb); ++ match(Set dst (MaxI src1 zero)); ++ match(Set dst (MaxI zero src1)); ++ ++ ins_cost(ALU_COST); ++ format %{ "max $dst, $src1, zr\t#@maxI_reg_zero_b" %} ++ ++ ins_encode %{ ++ __ max(as_Register($dst$$reg), as_Register($src1$$reg), zr); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Abs ++instruct absI_reg_b(iRegINoSp dst, iRegI src) %{ ++ predicate(UseZbb); ++ match(Set dst (AbsI src)); ++ ++ ins_cost(ALU_COST * 2); ++ format %{ ++ "negw t0, $src\n\t" ++ "max $dst, $src, t0\t#@absI_reg_b" ++ %} ++ ++ ins_encode %{ ++ __ negw(t0, as_Register($src$$reg)); ++ __ max(as_Register($dst$$reg), as_Register($src$$reg), t0); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct absL_reg_b(iRegLNoSp dst, iRegL src) %{ ++ predicate(UseZbb); ++ match(Set dst (AbsL src)); ++ ++ ins_cost(ALU_COST * 2); ++ format %{ ++ "neg t0, $src\n\t" ++ "max $dst, $src, t0\t#@absL_reg_b" ++ %} ++ ++ ins_encode %{ ++ __ neg(t0, as_Register($src$$reg)); ++ __ max(as_Register($dst$$reg), as_Register($src$$reg), t0); ++ %} ++ ++ ins_pipe(ialu_reg); ++%} ++ ++// And Not ++instruct andnI_reg_reg_b(iRegINoSp dst, iRegI src1, iRegI src2, immI_M1 m1) %{ ++ predicate(UseZbb); ++ match(Set dst (AndI src1 (XorI src2 m1))); ++ ++ ins_cost(ALU_COST); ++ format %{ "andn $dst, $src1, $src2\t#@andnI_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ andn(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct andnL_reg_reg_b(iRegLNoSp dst, iRegL src1, iRegL src2, immL_M1 m1) %{ ++ predicate(UseZbb); ++ match(Set dst (AndL src1 (XorL src2 m1))); ++ ++ ins_cost(ALU_COST); ++ format %{ "andn $dst, $src1, $src2\t#@andnL_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ andn(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// Or Not ++instruct ornI_reg_reg_b(iRegINoSp dst, iRegI src1, iRegI src2, immI_M1 m1) %{ ++ predicate(UseZbb); ++ match(Set dst (OrI src1 (XorI src2 m1))); ++ ++ ins_cost(ALU_COST); ++ format %{ "orn $dst, $src1, $src2\t#@ornI_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ orn(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++instruct ornL_reg_reg_b(iRegLNoSp dst, iRegL src1, iRegL src2, immL_M1 m1) %{ ++ predicate(UseZbb); ++ match(Set dst (OrL src1 (XorL src2 m1))); ++ ++ ins_cost(ALU_COST); ++ format %{ "orn $dst, $src1, $src2\t#@ornL_reg_reg_b" %} ++ ++ ins_encode %{ ++ __ orn(as_Register($dst$$reg), ++ as_Register($src1$$reg), ++ as_Register($src2$$reg)); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} ++ ++// AndI 0b0..010..0 + ConvI2B ++instruct convI2Bool_andI_reg_immIpowerOf2(iRegINoSp dst, iRegIorL2I src, immIpowerOf2 mask) %{ ++ predicate(UseZbs); ++ match(Set dst (Conv2B (AndI src mask))); ++ ins_cost(ALU_COST); ++ ++ format %{ "bexti $dst, $src, $mask\t#@convI2Bool_andI_reg_immIpowerOf2" %} ++ ins_encode %{ ++ __ bexti($dst$$Register, $src$$Register, exact_log2((juint)($mask$$constant))); ++ %} ++ ++ ins_pipe(ialu_reg_reg); ++%} +\ No newline at end of file +--- /dev/null ++++ b/src/hotspot/cpu/riscv/riscv_v.ad +@@ -0,0 +1,2038 @@ ++// ++// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. ++// Copyright (c) 2020, Arm Limited. All rights reserved. ++// Copyright (c) 2020, 2022, 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. ++// ++// ++ ++// RISCV Vector Extension Architecture Description File ++ ++opclass vmemA(indirect); ++ ++source_hpp %{ ++ bool op_vec_supported(int opcode); ++%} ++ ++source %{ ++ static inline BasicType vector_element_basic_type(const MachNode* n) { ++ const TypeVect* vt = n->bottom_type()->is_vect(); ++ return vt->element_basic_type(); ++ } ++ ++ static inline BasicType vector_element_basic_type(const MachNode* use, const MachOper* opnd) { ++ int def_idx = use->operand_index(opnd); ++ Node* def = use->in(def_idx); ++ const TypeVect* vt = def->bottom_type()->is_vect(); ++ return vt->element_basic_type(); ++ } ++ ++ static void loadStore(C2_MacroAssembler masm, bool is_store, ++ VectorRegister reg, BasicType bt, Register base) { ++ Assembler::SEW sew = Assembler::elemtype_to_sew(bt); ++ masm.vsetvli(t0, x0, sew); ++ if (is_store) { ++ masm.vsex_v(reg, base, sew); ++ } else { ++ masm.vlex_v(reg, base, sew); ++ } ++ } ++ ++ bool op_vec_supported(int opcode) { ++ switch (opcode) { ++ // No multiply reduction instructions ++ case Op_MulReductionVD: ++ case Op_MulReductionVF: ++ case Op_MulReductionVI: ++ case Op_MulReductionVL: ++ // Others ++ case Op_Extract: ++ case Op_ExtractB: ++ case Op_ExtractC: ++ case Op_ExtractD: ++ case Op_ExtractF: ++ case Op_ExtractI: ++ case Op_ExtractL: ++ case Op_ExtractS: ++ case Op_ExtractUB: ++ // Vector API specific ++ case Op_AndReductionV: ++ case Op_OrReductionV: ++ case Op_XorReductionV: ++ case Op_LoadVectorGather: ++ case Op_StoreVectorScatter: ++ case Op_VectorBlend: ++ case Op_VectorCast: ++ case Op_VectorCastB2X: ++ case Op_VectorCastD2X: ++ case Op_VectorCastF2X: ++ case Op_VectorCastI2X: ++ case Op_VectorCastL2X: ++ case Op_VectorCastS2X: ++ case Op_VectorInsert: ++ case Op_VectorLoadConst: ++ case Op_VectorLoadMask: ++ case Op_VectorLoadShuffle: ++ case Op_VectorMaskCmp: ++ case Op_VectorRearrange: ++ case Op_VectorReinterpret: ++ case Op_VectorStoreMask: ++ case Op_VectorTest: ++ case Op_PopCountVI: ++ return false; ++ default: ++ return UseRVV; ++ } ++ } ++ ++%} ++ ++definitions %{ ++ int_def VEC_COST (200, 200); ++%} ++ ++// All VEC instructions ++ ++// vector load/store ++instruct loadV(vReg dst, vmemA mem) %{ ++ match(Set dst (LoadVector mem)); ++ ins_cost(VEC_COST); ++ format %{ "vle $dst, $mem\t#@loadV" %} ++ ins_encode %{ ++ VectorRegister dst_reg = as_VectorRegister($dst$$reg); ++ loadStore(C2_MacroAssembler(&cbuf), false, dst_reg, ++ vector_element_basic_type(this), as_Register($mem$$base)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct storeV(vReg src, vmemA mem) %{ ++ match(Set mem (StoreVector mem src)); ++ ins_cost(VEC_COST); ++ format %{ "vse $src, $mem\t#@storeV" %} ++ ins_encode %{ ++ VectorRegister src_reg = as_VectorRegister($src$$reg); ++ loadStore(C2_MacroAssembler(&cbuf), true, src_reg, ++ vector_element_basic_type(this, $src), as_Register($mem$$base)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector abs ++ ++instruct vabsB(vReg dst, vReg src, vReg tmp) %{ ++ match(Set dst (AbsVB src)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vrsub.vi $tmp, 0, $src\t#@vabsB\n\t" ++ "vmax.vv $dst, $tmp, $src" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0); ++ __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vabsS(vReg dst, vReg src, vReg tmp) %{ ++ match(Set dst (AbsVS src)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vrsub.vi $tmp, 0, $src\t#@vabsS\n\t" ++ "vmax.vv $dst, $tmp, $src" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0); ++ __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vabsI(vReg dst, vReg src, vReg tmp) %{ ++ match(Set dst (AbsVI src)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vrsub.vi $tmp, 0, $src\t#@vabsI\n\t" ++ "vmax.vv $dst, $tmp, $src" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0); ++ __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vabsL(vReg dst, vReg src, vReg tmp) %{ ++ match(Set dst (AbsVL src)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vrsub.vi $tmp, 0, $src\t#@vabsL\n\t" ++ "vmax.vv $dst, $tmp, $src" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0); ++ __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vabsF(vReg dst, vReg src) %{ ++ match(Set dst (AbsVF src)); ++ ins_cost(VEC_COST); ++ format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vabsD(vReg dst, vReg src) %{ ++ match(Set dst (AbsVD src)); ++ ins_cost(VEC_COST); ++ format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector add ++ ++instruct vaddB(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (AddVB src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vadd.vv $dst, $src1, $src2\t#@vaddB" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vadd_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vaddS(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (AddVS src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vadd.vv $dst, $src1, $src2\t#@vaddS" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vadd_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vaddI(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (AddVI src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vadd.vv $dst, $src1, $src2\t#@vaddI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vadd_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vaddL(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (AddVL src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vadd.vv $dst, $src1, $src2\t#@vaddL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vadd_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vaddF(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (AddVF src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfadd_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vaddD(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (AddVD src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfadd_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector and ++ ++instruct vand(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (AndV src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vand.vv $dst, $src1, $src2\t#@vand" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vand_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector or ++ ++instruct vor(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (OrV src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vor.vv $dst, $src1, $src2\t#@vor" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vor_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector xor ++ ++instruct vxor(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (XorV src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vxor.vv $dst, $src1, $src2\t#@vxor" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vxor_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector float div ++ ++instruct vdivF(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (DivVF src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfdiv.vv $dst, $src1, $src2\t#@vdivF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfdiv_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vdivD(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (DivVD src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfdiv.vv $dst, $src1, $src2\t#@vdivD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfdiv_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector integer max/min ++ ++instruct vmax(vReg dst, vReg src1, vReg src2) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() != T_FLOAT && ++ n->bottom_type()->is_vect()->element_basic_type() != T_DOUBLE); ++ match(Set dst (MaxV src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vmax.vv $dst, $src1, $src2\t#@vmax" %} ++ ins_encode %{ ++ BasicType bt = vector_element_basic_type(this); ++ Assembler::SEW sew = Assembler::elemtype_to_sew(bt); ++ __ vsetvli(t0, x0, sew); ++ __ vmax_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vmin(vReg dst, vReg src1, vReg src2) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() != T_FLOAT && ++ n->bottom_type()->is_vect()->element_basic_type() != T_DOUBLE); ++ match(Set dst (MinV src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vmin.vv $dst, $src1, $src2\t#@vmin" %} ++ ins_encode %{ ++ BasicType bt = vector_element_basic_type(this); ++ Assembler::SEW sew = Assembler::elemtype_to_sew(bt); ++ __ vsetvli(t0, x0, sew); ++ __ vmin_vv(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector float-point max/min ++ ++instruct vmaxF(vReg dst, vReg src1, vReg src2) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); ++ match(Set dst (MaxV src1 src2)); ++ effect(TEMP_DEF dst); ++ ins_cost(VEC_COST); ++ format %{ "vmaxF $dst, $src1, $src2\t#@vmaxF" %} ++ ins_encode %{ ++ __ minmax_FD_v(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), ++ false /* is_double */, false /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vmaxD(vReg dst, vReg src1, vReg src2) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); ++ match(Set dst (MaxV src1 src2)); ++ effect(TEMP_DEF dst); ++ ins_cost(VEC_COST); ++ format %{ "vmaxD $dst, $src1, $src2\t#@vmaxD" %} ++ ins_encode %{ ++ __ minmax_FD_v(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), ++ true /* is_double */, false /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vminF(vReg dst, vReg src1, vReg src2) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); ++ match(Set dst (MinV src1 src2)); ++ effect(TEMP_DEF dst); ++ ins_cost(VEC_COST); ++ format %{ "vminF $dst, $src1, $src2\t#@vminF" %} ++ ins_encode %{ ++ __ minmax_FD_v(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), ++ false /* is_double */, true /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vminD(vReg dst, vReg src1, vReg src2) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); ++ match(Set dst (MinV src1 src2)); ++ effect(TEMP_DEF dst); ++ ins_cost(VEC_COST); ++ format %{ "vminD $dst, $src1, $src2\t#@vminD" %} ++ ins_encode %{ ++ __ minmax_FD_v(as_VectorRegister($dst$$reg), ++ as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), ++ true /* is_double */, true /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector fmla ++ ++// dst_src1 = dst_src1 + src2 * src3 ++instruct vfmlaF(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVF dst_src1 (Binary src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 + src2 * src3 ++instruct vfmlaD(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVD dst_src1 (Binary src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector fmls ++ ++// dst_src1 = dst_src1 + -src2 * src3 ++// dst_src1 = dst_src1 + src2 * -src3 ++instruct vfmlsF(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVF dst_src1 (Binary (NegVF src2) src3))); ++ match(Set dst_src1 (FmaVF dst_src1 (Binary src2 (NegVF src3)))); ++ ins_cost(VEC_COST); ++ format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 + -src2 * src3 ++// dst_src1 = dst_src1 + src2 * -src3 ++instruct vfmlsD(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVD dst_src1 (Binary (NegVD src2) src3))); ++ match(Set dst_src1 (FmaVD dst_src1 (Binary src2 (NegVD src3)))); ++ ins_cost(VEC_COST); ++ format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector fnmla ++ ++// dst_src1 = -dst_src1 + -src2 * src3 ++// dst_src1 = -dst_src1 + src2 * -src3 ++instruct vfnmlaF(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary (NegVF src2) src3))); ++ match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 (NegVF src3)))); ++ ins_cost(VEC_COST); ++ format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = -dst_src1 + -src2 * src3 ++// dst_src1 = -dst_src1 + src2 * -src3 ++instruct vfnmlaD(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary (NegVD src2) src3))); ++ match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 (NegVD src3)))); ++ ins_cost(VEC_COST); ++ format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector fnmls ++ ++// dst_src1 = -dst_src1 + src2 * src3 ++instruct vfnmlsF(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = -dst_src1 + src2 * src3 ++instruct vfnmlsD(vReg dst_src1, vReg src2, vReg src3) %{ ++ predicate(UseFMA); ++ match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector mla ++ ++// dst_src1 = dst_src1 + src2 * src3 ++instruct vmlaB(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (AddVB dst_src1 (MulVB src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaB" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 + src2 * src3 ++instruct vmlaS(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (AddVS dst_src1 (MulVS src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaS" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 + src2 * src3 ++instruct vmlaI(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (AddVI dst_src1 (MulVI src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 + src2 * src3 ++instruct vmlaL(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (AddVL dst_src1 (MulVL src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmacc_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector mls ++ ++// dst_src1 = dst_src1 - src2 * src3 ++instruct vmlsB(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (SubVB dst_src1 (MulVB src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsB" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vnmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 - src2 * src3 ++instruct vmlsS(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (SubVS dst_src1 (MulVS src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsS" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vnmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 - src2 * src3 ++instruct vmlsI(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (SubVI dst_src1 (MulVI src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vnmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// dst_src1 = dst_src1 - src2 * src3 ++instruct vmlsL(vReg dst_src1, vReg src2, vReg src3) %{ ++ match(Set dst_src1 (SubVL dst_src1 (MulVL src2 src3))); ++ ins_cost(VEC_COST); ++ format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vnmsac_vv(as_VectorRegister($dst_src1$$reg), ++ as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector mul ++ ++instruct vmulB(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (MulVB src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vmul.vv $dst, $src1, $src2\t#@vmulB" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vmulS(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (MulVS src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vmul.vv $dst, $src1, $src2\t#@vmulS" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vmulI(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (MulVI src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vmul.vv $dst, $src1, $src2\t#@vmulI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vmulL(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (MulVL src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vmul.vv $dst, $src1, $src2\t#@vmulL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vmulF(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (MulVF src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vmulD(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (MulVD src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector fneg ++ ++instruct vnegF(vReg dst, vReg src) %{ ++ match(Set dst (NegVF src)); ++ ins_cost(VEC_COST); ++ format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vnegD(vReg dst, vReg src) %{ ++ match(Set dst (NegVD src)); ++ ins_cost(VEC_COST); ++ format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector add reduction ++ ++instruct reduce_addB(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); ++ match(Set dst (AddReductionVI src1 src2)); ++ effect(TEMP tmp); ++ ins_cost(VEC_COST); ++ format %{ "vmv.s.x $tmp, $src1\t#@reduce_addB\n\t" ++ "vredsum.vs $tmp, $src2, $tmp\n\t" ++ "vmv.x.s $dst, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct reduce_addS(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); ++ match(Set dst (AddReductionVI src1 src2)); ++ effect(TEMP tmp); ++ ins_cost(VEC_COST); ++ format %{ "vmv.s.x $tmp, $src1\t#@reduce_addS\n\t" ++ "vredsum.vs $tmp, $src2, $tmp\n\t" ++ "vmv.x.s $dst, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); ++ match(Set dst (AddReductionVI src1 src2)); ++ effect(TEMP tmp); ++ ins_cost(VEC_COST); ++ format %{ "vmv.s.x $tmp, $src1\t#@reduce_addI\n\t" ++ "vredsum.vs $tmp, $src2, $tmp\n\t" ++ "vmv.x.s $dst, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct reduce_addL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); ++ match(Set dst (AddReductionVL src1 src2)); ++ effect(TEMP tmp); ++ ins_cost(VEC_COST); ++ format %{ "vmv.s.x $tmp, $src1\t#@reduce_addL\n\t" ++ "vredsum.vs $tmp, $src2, $tmp\n\t" ++ "vmv.x.s $dst, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct reduce_addF(fRegF src1_dst, vReg src2, vReg tmp) %{ ++ match(Set src1_dst (AddReductionVF src1_dst src2)); ++ effect(TEMP tmp); ++ ins_cost(VEC_COST); ++ format %{ "vfmv.s.f $tmp, $src1_dst\t#@reduce_addF\n\t" ++ "vfredosum.vs $tmp, $src2, $tmp\n\t" ++ "vfmv.f.s $src1_dst, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1_dst$$FloatRegister); ++ __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp$$reg)); ++ __ vfmv_f_s($src1_dst$$FloatRegister, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct reduce_addD(fRegD src1_dst, vReg src2, vReg tmp) %{ ++ match(Set src1_dst (AddReductionVD src1_dst src2)); ++ effect(TEMP tmp); ++ ins_cost(VEC_COST); ++ format %{ "vfmv.s.f $tmp, $src1_dst\t#@reduce_addD\n\t" ++ "vfredosum.vs $tmp, $src2, $tmp\n\t" ++ "vfmv.f.s $src1_dst, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1_dst$$FloatRegister); ++ __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp$$reg)); ++ __ vfmv_f_s($src1_dst$$FloatRegister, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector integer max reduction ++instruct vreduce_maxB(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); ++ match(Set dst (MaxReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_maxB $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ Label Ldone; ++ __ ble(as_Register($src1$$reg), as_Register($dst$$reg), Ldone); ++ __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); ++ __ bind(Ldone); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_maxS(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); ++ match(Set dst (MaxReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_maxS $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ Label Ldone; ++ __ ble(as_Register($src1$$reg), as_Register($dst$$reg), Ldone); ++ __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); ++ __ bind(Ldone); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_maxI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); ++ match(Set dst (MaxReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_maxI $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_maxL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); ++ match(Set dst (MaxReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_maxL $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector integer min reduction ++instruct vreduce_minB(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); ++ match(Set dst (MinReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_minB $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ Label Ldone; ++ __ bge(as_Register($src1$$reg), as_Register($dst$$reg), Ldone); ++ __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); ++ __ bind(Ldone); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_minS(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); ++ match(Set dst (MinReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_minS $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ Label Ldone; ++ __ bge(as_Register($src1$$reg), as_Register($dst$$reg), Ldone); ++ __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); ++ __ bind(Ldone); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_minI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); ++ match(Set dst (MinReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_minI $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_minL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); ++ match(Set dst (MinReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP tmp); ++ format %{ "vreduce_minL $dst, $src1, $src2, $tmp" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register); ++ __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg)); ++ __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector float max reduction ++ ++instruct vreduce_maxF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); ++ match(Set dst (MaxReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); ++ format %{ "reduce_maxF $dst, $src1, $src2, $tmp1, $tmp2" %} ++ ins_encode %{ ++ __ reduce_minmax_FD_v($dst$$FloatRegister, ++ $src1$$FloatRegister, as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), ++ false /* is_double */, false /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_maxD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); ++ match(Set dst (MaxReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); ++ format %{ "reduce_maxD $dst, $src1, $src2, $tmp1, $tmp2" %} ++ ins_encode %{ ++ __ reduce_minmax_FD_v($dst$$FloatRegister, ++ $src1$$FloatRegister, as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), ++ true /* is_double */, false /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector float min reduction ++ ++instruct vreduce_minF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); ++ match(Set dst (MinReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); ++ format %{ "reduce_minF $dst, $src1, $src2, $tmp1, $tmp2" %} ++ ins_encode %{ ++ __ reduce_minmax_FD_v($dst$$FloatRegister, ++ $src1$$FloatRegister, as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), ++ false /* is_double */, true /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vreduce_minD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{ ++ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); ++ match(Set dst (MinReductionV src1 src2)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); ++ format %{ "reduce_minD $dst, $src1, $src2, $tmp1, $tmp2" %} ++ ins_encode %{ ++ __ reduce_minmax_FD_v($dst$$FloatRegister, ++ $src1$$FloatRegister, as_VectorRegister($src2$$reg), ++ as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), ++ true /* is_double */, true /* is_min */); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector replicate ++ ++instruct replicateB(vReg dst, iRegIorL2I src) %{ ++ match(Set dst (ReplicateB src)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.x $dst, $src\t#@replicateB" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateS(vReg dst, iRegIorL2I src) %{ ++ match(Set dst (ReplicateS src)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.x $dst, $src\t#@replicateS" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateI(vReg dst, iRegIorL2I src) %{ ++ match(Set dst (ReplicateI src)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.x $dst, $src\t#@replicateI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateL(vReg dst, iRegL src) %{ ++ match(Set dst (ReplicateL src)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.x $dst, $src\t#@replicateL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateB_imm5(vReg dst, immI5 con) %{ ++ match(Set dst (ReplicateB con)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.i $dst, $con\t#@replicateB_imm5" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateS_imm5(vReg dst, immI5 con) %{ ++ match(Set dst (ReplicateS con)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.i $dst, $con\t#@replicateS_imm5" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateI_imm5(vReg dst, immI5 con) %{ ++ match(Set dst (ReplicateI con)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.i $dst, $con\t#@replicateI_imm5" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateL_imm5(vReg dst, immL5 con) %{ ++ match(Set dst (ReplicateL con)); ++ ins_cost(VEC_COST); ++ format %{ "vmv.v.i $dst, $con\t#@replicateL_imm5" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateF(vReg dst, fRegF src) %{ ++ match(Set dst (ReplicateF src)); ++ ins_cost(VEC_COST); ++ format %{ "vfmv.v.f $dst, $src\t#@replicateF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct replicateD(vReg dst, fRegD src) %{ ++ match(Set dst (ReplicateD src)); ++ ins_cost(VEC_COST); ++ format %{ "vfmv.v.f $dst, $src\t#@replicateD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector shift ++ ++instruct vasrB(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (RShiftVB src shift)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst); ++ format %{ "vmsgtu.vi v0, $shift 7\t#@vasrB\n\t" ++ "vsra.vi $dst, $src, 7, Assembler::v0_t\n\t" ++ "vmnot.m v0, v0\n\t" ++ "vsra.vv $dst, $src, $shift, Assembler::v0_t" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ // if shift > BitsPerByte - 1, clear the low BitsPerByte - 1 bits ++ __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1); ++ __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ BitsPerByte - 1, Assembler::v0_t); ++ // otherwise, shift ++ __ vmnot_m(v0, v0); ++ __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg), Assembler::v0_t); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vasrS(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (RShiftVS src shift)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst); ++ format %{ "vmsgtu.vi v0, $shift, 15\t#@vasrS\n\t" ++ "vsra.vi $dst, $src, 15, Assembler::v0_t\n\t" ++ "vmnot.m v0, v0\n\t" ++ "vsra.vv $dst, $src, $shift, Assembler::v0_t" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ // if shift > BitsPerShort - 1, clear the low BitsPerShort - 1 bits ++ __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1); ++ __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ BitsPerShort - 1, Assembler::v0_t); ++ // otherwise, shift ++ __ vmnot_m(v0, v0); ++ __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg), Assembler::v0_t); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vasrI(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (RShiftVI src shift)); ++ ins_cost(VEC_COST); ++ format %{ "vsra.vv $dst, $src, $shift\t#@vasrI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vasrL(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (RShiftVL src shift)); ++ ins_cost(VEC_COST); ++ format %{ "vsra.vv $dst, $src, $shift\t#@vasrL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslB(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (LShiftVB src shift)); ++ ins_cost(VEC_COST); ++ effect( TEMP_DEF dst); ++ format %{ "vmsgtu.vi v0, $shift, 7\t#@vlslB\n\t" ++ "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" ++ "vmnot.m v0, v0\n\t" ++ "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ // if shift > BitsPerByte - 1, clear the element ++ __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1); ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg), Assembler::v0_t); ++ // otherwise, shift ++ __ vmnot_m(v0, v0); ++ __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg), Assembler::v0_t); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslS(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (LShiftVS src shift)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst); ++ format %{ "vmsgtu.vi v0, $shift, 15\t#@vlslS\n\t" ++ "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" ++ "vmnot.m v0, v0\n\t" ++ "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ // if shift > BitsPerShort - 1, clear the element ++ __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1); ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg), Assembler::v0_t); ++ // otherwise, shift ++ __ vmnot_m(v0, v0); ++ __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg), Assembler::v0_t); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslI(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (LShiftVI src shift)); ++ ins_cost(VEC_COST); ++ format %{ "vsll.vv $dst, $src, $shift\t#@vlslI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslL(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (LShiftVL src shift)); ++ ins_cost(VEC_COST); ++ format %{ "vsll.vv $dst, $src, $shift\t# vector (D)" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlsrB(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (URShiftVB src shift)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst); ++ format %{ "vmsgtu.vi v0, $shift, 7\t#@vlsrB\n\t" ++ "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" ++ "vmnot.m v0, v0, v0\n\t" ++ "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ // if shift > BitsPerByte - 1, clear the element ++ __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1); ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg), Assembler::v0_t); ++ // otherwise, shift ++ __ vmnot_m(v0, v0); ++ __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg), Assembler::v0_t); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlsrS(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (URShiftVS src shift)); ++ ins_cost(VEC_COST); ++ effect(TEMP_DEF dst); ++ format %{ "vmsgtu.vi v0, $shift, 15\t#@vlsrS\n\t" ++ "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" ++ "vmnot.m v0, v0\n\t" ++ "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ // if shift > BitsPerShort - 1, clear the element ++ __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1); ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg), Assembler::v0_t); ++ // otherwise, shift ++ __ vmnot_m(v0, v0); ++ __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg), Assembler::v0_t); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++ ++instruct vlsrI(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (URShiftVI src shift)); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++ ++instruct vlsrL(vReg dst, vReg src, vReg shift) %{ ++ match(Set dst (URShiftVL src shift)); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($shift$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vasrB_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (RShiftVB src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsra.vi $dst, $src, $shift\t#@vasrB_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e8); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ if (con >= BitsPerByte) con = BitsPerByte - 1; ++ __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vasrS_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (RShiftVS src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsra.vi $dst, $src, $shift\t#@vasrS_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e16); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ if (con >= BitsPerShort) con = BitsPerShort - 1; ++ __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vasrI_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (RShiftVI src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vi $dst, $src, $shift\t#@vasrI_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e32); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vasrL_imm(vReg dst, vReg src, immI shift) %{ ++ predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32); ++ match(Set dst (RShiftVL src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vi $dst, $src, $shift\t#@vasrL_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e64); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlsrB_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (URShiftVB src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrB_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e8); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ if (con >= BitsPerByte) { ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlsrS_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (URShiftVS src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrS_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e16); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ if (con >= BitsPerShort) { ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlsrI_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (URShiftVI src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrI_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e32); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlsrL_imm(vReg dst, vReg src, immI shift) %{ ++ predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32); ++ match(Set dst (URShiftVL src (RShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrL_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e64); ++ if (con == 0) { ++ __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslB_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (LShiftVB src (LShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsll.vi $dst, $src, $shift\t#@vlslB_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e8); ++ if (con >= BitsPerByte) { ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslS_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (LShiftVS src (LShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsll.vi $dst, $src, $shift\t#@vlslS_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e16); ++ if (con >= BitsPerShort) { ++ __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), ++ as_VectorRegister($src$$reg)); ++ return; ++ } ++ __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslI_imm(vReg dst, vReg src, immI shift) %{ ++ match(Set dst (LShiftVI src (LShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsll.vi $dst, $src, $shift\t#@vlslI_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vlslL_imm(vReg dst, vReg src, immI shift) %{ ++ predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32); ++ match(Set dst (LShiftVL src (LShiftCntV shift))); ++ ins_cost(VEC_COST); ++ format %{ "vsll.vi $dst, $src, $shift\t#@vlslL_imm" %} ++ ins_encode %{ ++ uint32_t con = (unsigned)$shift$$constant & 0x1f; ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vshiftcntB(vReg dst, iRegIorL2I cnt) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); ++ match(Set dst (LShiftCntV cnt)); ++ match(Set dst (RShiftCntV cnt)); ++ format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntB" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vshiftcntS(vReg dst, iRegIorL2I cnt) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_SHORT || ++ n->bottom_type()->is_vect()->element_basic_type() == T_CHAR); ++ match(Set dst (LShiftCntV cnt)); ++ match(Set dst (RShiftCntV cnt)); ++ format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntS" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vshiftcntI(vReg dst, iRegIorL2I cnt) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_INT); ++ match(Set dst (LShiftCntV cnt)); ++ match(Set dst (RShiftCntV cnt)); ++ format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vshiftcntL(vReg dst, iRegIorL2I cnt) %{ ++ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_LONG); ++ match(Set dst (LShiftCntV cnt)); ++ match(Set dst (RShiftCntV cnt)); ++ format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector sqrt ++ ++instruct vsqrtF(vReg dst, vReg src) %{ ++ match(Set dst (SqrtVF src)); ++ ins_cost(VEC_COST); ++ format %{ "vfsqrt.v $dst, $src\t#@vsqrtF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vsqrtD(vReg dst, vReg src) %{ ++ match(Set dst (SqrtVD src)); ++ ins_cost(VEC_COST); ++ format %{ "vfsqrt.v $dst, $src\t#@vsqrtD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++// vector sub ++ ++instruct vsubB(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (SubVB src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vsub.vv $dst, $src1, $src2\t#@vsubB" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e8); ++ __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vsubS(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (SubVS src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vsub.vv $dst, $src1, $src2\t#@vsubS" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e16); ++ __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vsubI(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (SubVI src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vsub.vv $dst, $src1, $src2\t#@vsubI" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vsubL(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (SubVL src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vsub.vv $dst, $src1, $src2\t#@vsubL" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vsubF(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (SubVF src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfsub.vv $dst, $src1, $src2\t@vsubF" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e32); ++ __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vsubD(vReg dst, vReg src1, vReg src2) %{ ++ match(Set dst (SubVD src1 src2)); ++ ins_cost(VEC_COST); ++ format %{ "vfsub.vv $dst, $src1, $src2\t#@vsubD" %} ++ ins_encode %{ ++ __ vsetvli(t0, x0, Assembler::e64); ++ __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), ++ as_VectorRegister($src2$$reg)); ++ %} ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vstring_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, ++ iRegI_R10 result, vReg_V1 v1, ++ vReg_V2 v2, vReg_V3 v3, rFlagsReg cr) ++%{ ++ predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result (StrEquals (Binary str1 str2) cnt)); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr); ++ ++ format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %} ++ ins_encode %{ ++ // Count is in 8-bit bytes; non-Compact chars are 16 bits. ++ __ string_equals_v($str1$$Register, $str2$$Register, ++ $result$$Register, $cnt$$Register, 1); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct vstring_equalsU(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, ++ iRegI_R10 result, vReg_V1 v1, ++ vReg_V2 v2, vReg_V3 v3, rFlagsReg cr) ++%{ ++ predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result (StrEquals (Binary str1 str2) cnt)); ++ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr); ++ ++ format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsU" %} ++ ins_encode %{ ++ // Count is in 8-bit bytes; non-Compact chars are 16 bits. ++ __ string_equals_v($str1$$Register, $str2$$Register, ++ $result$$Register, $cnt$$Register, 2); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct varray_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr) ++%{ ++ predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result (AryEq ary1 ary2)); ++ effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr); ++ ++ format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsB // KILL $tmp" %} ++ ins_encode %{ ++ __ arrays_equals_v($ary1$$Register, $ary2$$Register, ++ $result$$Register, $tmp$$Register, 1); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct varray_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr) ++%{ ++ predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result (AryEq ary1 ary2)); ++ effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr); ++ ++ format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsC // KILL $tmp" %} ++ ins_encode %{ ++ __ arrays_equals_v($ary1$$Register, $ary2$$Register, ++ $result$$Register, $tmp$$Register, 2); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct vstring_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, ++ iRegP_R28 tmp1, iRegL_R29 tmp2) ++%{ ++ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU); ++ match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, ++ TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); ++ ++ format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %} ++ ins_encode %{ ++ // Count is in 8-bit bytes; non-Compact chars are 16 bits. ++ __ string_compare_v($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, ++ StrIntrinsicNode::UU); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++instruct vstring_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, ++ iRegP_R28 tmp1, iRegL_R29 tmp2) ++%{ ++ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL); ++ match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, ++ TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); ++ ++ format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %} ++ ins_encode %{ ++ __ string_compare_v($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, ++ StrIntrinsicNode::LL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct vstring_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, ++ iRegP_R28 tmp1, iRegL_R29 tmp2) ++%{ ++ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL); ++ match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, ++ TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); ++ ++ format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %} ++ ins_encode %{ ++ __ string_compare_v($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, ++ StrIntrinsicNode::UL); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++instruct vstring_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, ++ iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, ++ iRegP_R28 tmp1, iRegL_R29 tmp2) ++%{ ++ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU); ++ match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); ++ effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, ++ TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); ++ ++ format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %} ++ ins_encode %{ ++ __ string_compare_v($str1$$Register, $str2$$Register, ++ $cnt1$$Register, $cnt2$$Register, $result$$Register, ++ $tmp1$$Register, $tmp2$$Register, ++ StrIntrinsicNode::LU); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++// fast byte[] to char[] inflation ++instruct vstring_inflate(Universe dummy, iRegP_R10 src, iRegP_R11 dst, iRegI_R12 len, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) ++%{ ++ predicate(UseRVV); ++ match(Set dummy (StrInflatedCopy src (Binary dst len))); ++ effect(TEMP v1, TEMP v2, TEMP v3, TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len); ++ ++ format %{ "String Inflate $src,$dst" %} ++ ins_encode %{ ++ __ byte_array_inflate_v($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register); ++ %} ++ ins_pipe(pipe_class_memory); ++%} ++ ++// encode char[] to byte[] in ISO_8859_1 ++instruct vencode_iso_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) ++%{ ++ predicate(UseRVV); ++ match(Set result (EncodeISOArray src (Binary dst len))); ++ effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len, ++ TEMP v1, TEMP v2, TEMP v3, TEMP tmp); ++ ++ format %{ "Encode array $src,$dst,$len -> $result" %} ++ ins_encode %{ ++ __ encode_iso_array_v($src$$Register, $dst$$Register, $len$$Register, ++ $result$$Register, $tmp$$Register); ++ %} ++ ins_pipe( pipe_class_memory ); ++%} ++ ++// fast char[] to byte[] compression ++instruct vstring_compress(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) ++%{ ++ predicate(UseRVV); ++ match(Set result (StrCompressedCopy src (Binary dst len))); ++ effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len, ++ TEMP v1, TEMP v2, TEMP v3, TEMP tmp); ++ ++ format %{ "String Compress $src,$dst -> $result // KILL R11, R12, R13" %} ++ ins_encode %{ ++ __ char_array_compress_v($src$$Register, $dst$$Register, $len$$Register, ++ $result$$Register, $tmp$$Register); ++ %} ++ ins_pipe( pipe_slow ); ++%} ++ ++instruct vhas_negatives(iRegP_R11 ary, iRegI_R12 len, iRegI_R10 result, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) ++%{ ++ predicate(UseRVV); ++ match(Set result (HasNegatives ary len)); ++ effect(TEMP_DEF result, USE_KILL ary, USE_KILL len, TEMP v1, TEMP v2, TEMP v3, TEMP tmp); ++ ++ format %{ "has negatives byte[] $ary, $len -> $result" %} ++ ins_encode %{ ++ __ has_negatives_v($ary$$Register, $len$$Register, $result$$Register, $tmp$$Register); ++ %} ++ ++ ins_pipe(pipe_slow); ++%} ++ ++instruct vstringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, ++ iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3) ++%{ ++ predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); ++ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); ++ effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, ++ TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3); ++ ++ format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %} ++ ++ ins_encode %{ ++ __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register, ++ $result$$Register, $tmp1$$Register, $tmp2$$Register, ++ false /* isL */); ++ %} ++ ++ ins_pipe(pipe_class_memory); ++%} ++ ++instruct vstringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, ++ iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, ++ vReg_V1 v1, vReg_V2 v2, vReg_V3 v3) ++%{ ++ predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); ++ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); ++ effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, ++ TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3); ++ ++ format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %} ++ ++ ins_encode %{ ++ __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register, ++ $result$$Register, $tmp1$$Register, $tmp2$$Register, ++ true /* isL */); ++ %} ++ ++ ins_pipe(pipe_class_memory); ++%} ++ ++// clearing of an array ++instruct vclearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, Universe dummy, ++ vReg_V1 vReg1, vReg_V2 vReg2, vReg_V3 vReg3) ++%{ ++ predicate(UseRVV); ++ match(Set dummy (ClearArray cnt base)); ++ effect(USE_KILL cnt, USE_KILL base, TEMP vReg1, TEMP vReg2, TEMP vReg3); ++ ++ format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %} ++ ++ ins_encode %{ ++ __ clear_array_v($base$$Register, $cnt$$Register); ++ %} ++ ++ ins_pipe(pipe_class_memory); ++%} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +@@ -0,0 +1,2966 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "code/debugInfoRec.hpp" ++#include "code/icBuffer.hpp" ++#include "code/vtableStubs.hpp" ++#include "compiler/oopMap.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "interpreter/interp_masm.hpp" ++#include "interpreter/interpreter.hpp" ++#include "logging/log.hpp" ++#include "memory/resourceArea.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/compiledICHolder.hpp" ++#include "oops/klass.inline.hpp" ++#include "prims/methodHandles.hpp" ++#include "runtime/jniHandles.hpp" ++#include "runtime/safepointMechanism.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/signature.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/vframeArray.hpp" ++#include "utilities/align.hpp" ++#include "utilities/formatBuffer.hpp" ++#include "vmreg_riscv.inline.hpp" ++#ifdef COMPILER1 ++#include "c1/c1_Runtime1.hpp" ++#endif ++#ifdef COMPILER2 ++#include "adfiles/ad_riscv.hpp" ++#include "opto/runtime.hpp" ++#endif ++ ++#define __ masm-> ++ ++const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size; ++ ++class SimpleRuntimeFrame { ++public: ++ ++ // Most of the runtime stubs have this simple frame layout. ++ // This class exists to make the layout shared in one place. ++ // Offsets are for compiler stack slots, which are jints. ++ enum layout { ++ // The frame sender code expects that fp will be in the "natural" place and ++ // will override any oopMap setting for it. We must therefore force the layout ++ // so that it agrees with the frame sender code. ++ // we don't expect any arg reg save area so riscv asserts that ++ // frame::arg_reg_save_area_bytes == 0 ++ fp_off = 0, fp_off2, ++ return_off, return_off2, ++ framesize ++ }; ++}; ++ ++class RegisterSaver { ++ const bool _save_vectors; ++ public: ++ RegisterSaver(bool save_vectors) : _save_vectors(UseRVV && save_vectors) {} ++ ~RegisterSaver() {} ++ OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words); ++ void restore_live_registers(MacroAssembler* masm); ++ ++ // Offsets into the register save area ++ // Used by deoptimization when it is managing result register ++ // values on its own ++ // gregs:28, float_register:32; except: x1(ra) & x2(sp) & gp(x3) & tp(x4) ++ // |---v0---|<---SP ++ // |---v1---|save vectors only in generate_handler_blob ++ // |-- .. --| ++ // |---v31--|----- ++ // |---f0---| ++ // |---f1---| ++ // | .. | ++ // |---f31--| ++ // |---reserved slot for stack alignment---| ++ // |---x5---| ++ // | x6 | ++ // |---.. --| ++ // |---x31--| ++ // |---fp---| ++ // |---ra---| ++ int v0_offset_in_bytes(void) { return 0; } ++ int f0_offset_in_bytes(void) { ++ int f0_offset = 0; ++#ifdef COMPILER2 ++ if (_save_vectors) { ++ f0_offset += Matcher::scalable_vector_reg_size(T_INT) * VectorRegisterImpl::number_of_registers * ++ BytesPerInt; ++ } ++#endif ++ return f0_offset; ++ } ++ int reserved_slot_offset_in_bytes(void) { ++ return f0_offset_in_bytes() + ++ FloatRegisterImpl::max_slots_per_register * ++ FloatRegisterImpl::number_of_registers * ++ BytesPerInt; ++ } ++ ++ int reg_offset_in_bytes(Register r) { ++ assert (r->encoding() > 4, "ra, sp, gp and tp not saved"); ++ return reserved_slot_offset_in_bytes() + (r->encoding() - 4 /* x1, x2, x3, x4 */) * wordSize; ++ } ++ ++ int freg_offset_in_bytes(FloatRegister f) { ++ return f0_offset_in_bytes() + f->encoding() * wordSize; ++ } ++ ++ int ra_offset_in_bytes(void) { ++ return reserved_slot_offset_in_bytes() + ++ (RegisterImpl::number_of_registers - 3) * ++ RegisterImpl::max_slots_per_register * ++ BytesPerInt; ++ } ++}; ++ ++OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words) { ++ int vector_size_in_bytes = 0; ++ int vector_size_in_slots = 0; ++#ifdef COMPILER2 ++ if (_save_vectors) { ++ vector_size_in_bytes += Matcher::scalable_vector_reg_size(T_BYTE); ++ vector_size_in_slots += Matcher::scalable_vector_reg_size(T_INT); ++ } ++#endif ++ ++ int frame_size_in_bytes = align_up(additional_frame_words * wordSize + ra_offset_in_bytes() + wordSize, 16); ++ // OopMap frame size is in compiler stack slots (jint's) not bytes or words ++ int frame_size_in_slots = frame_size_in_bytes / BytesPerInt; ++ // The caller will allocate additional_frame_words ++ int additional_frame_slots = additional_frame_words * wordSize / BytesPerInt; ++ // CodeBlob frame size is in words. ++ int frame_size_in_words = frame_size_in_bytes / wordSize; ++ *total_frame_words = frame_size_in_words; ++ ++ // Save Integer, Float and Vector registers. ++ __ enter(); ++ __ push_CPU_state(_save_vectors, vector_size_in_bytes); ++ ++ // Set an oopmap for the call site. This oopmap will map all ++ // oop-registers and debug-info registers as callee-saved. This ++ // will allow deoptimization at this safepoint to find all possible ++ // debug-info recordings, as well as let GC find all oops. ++ ++ OopMapSet *oop_maps = new OopMapSet(); ++ OopMap* oop_map = new OopMap(frame_size_in_slots, 0); ++ assert_cond(oop_maps != NULL && oop_map != NULL); ++ ++ int sp_offset_in_slots = 0; ++ int step_in_slots = 0; ++ if (_save_vectors) { ++ step_in_slots = vector_size_in_slots; ++ for (int i = 0; i < VectorRegisterImpl::number_of_registers; i++, sp_offset_in_slots += step_in_slots) { ++ VectorRegister r = as_VectorRegister(i); ++ oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset_in_slots), r->as_VMReg()); ++ } ++ } ++ ++ step_in_slots = FloatRegisterImpl::max_slots_per_register; ++ for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++, sp_offset_in_slots += step_in_slots) { ++ FloatRegister r = as_FloatRegister(i); ++ oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset_in_slots), r->as_VMReg()); ++ } ++ ++ step_in_slots = RegisterImpl::max_slots_per_register; ++ // skip the slot reserved for alignment, see MacroAssembler::push_reg; ++ // also skip x5 ~ x6 on the stack because they are caller-saved registers. ++ sp_offset_in_slots += RegisterImpl::max_slots_per_register * 3; ++ // besides, we ignore x0 ~ x4 because push_CPU_state won't push them on the stack. ++ for (int i = 7; i < RegisterImpl::number_of_registers; i++, sp_offset_in_slots += step_in_slots) { ++ Register r = as_Register(i); ++ if (r != xthread) { ++ oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset_in_slots + additional_frame_slots), r->as_VMReg()); ++ } ++ } ++ ++ return oop_map; ++} ++ ++void RegisterSaver::restore_live_registers(MacroAssembler* masm) { ++#ifdef COMPILER2 ++ __ pop_CPU_state(_save_vectors, Matcher::scalable_vector_reg_size(T_BYTE)); ++#else ++ __ pop_CPU_state(_save_vectors); ++#endif ++ __ leave(); ++} ++ ++// Is vector's size (in bytes) bigger than a size saved by default? ++// riscv does not ovlerlay the floating-point registers on vector registers like aarch64. ++bool SharedRuntime::is_wide_vector(int size) { ++ return UseRVV; ++} ++ ++// The java_calling_convention describes stack locations as ideal slots on ++// a frame with no abi restrictions. Since we must observe abi restrictions ++// (like the placement of the register window) the slots must be biased by ++// the following value. ++static int reg2offset_in(VMReg r) { ++ // Account for saved fp and ra ++ // This should really be in_preserve_stack_slots ++ return r->reg2stack() * VMRegImpl::stack_slot_size; ++} ++ ++static int reg2offset_out(VMReg r) { ++ return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; ++} ++ ++// --------------------------------------------------------------------------- ++// Read the array of BasicTypes from a signature, and compute where the ++// arguments should go. Values in the VMRegPair regs array refer to 4-byte ++// quantities. Values less than VMRegImpl::stack0 are registers, those above ++// refer to 4-byte stack slots. All stack slots are based off of the stack pointer ++// as framesizes are fixed. ++// VMRegImpl::stack0 refers to the first slot 0(sp). ++// and VMRegImpl::stack0+1 refers to the memory word 4-byes higher. Register ++// up to RegisterImpl::number_of_registers) are the 64-bit ++// integer registers. ++ ++// Note: the INPUTS in sig_bt are in units of Java argument words, ++// which are 64-bit. The OUTPUTS are in 32-bit units. ++ ++// The Java calling convention is a "shifted" version of the C ABI. ++// By skipping the first C ABI register we can call non-static jni ++// methods with small numbers of arguments without having to shuffle ++// the arguments at all. Since we control the java ABI we ought to at ++// least get some advantage out of it. ++ ++int SharedRuntime::java_calling_convention(const BasicType *sig_bt, ++ VMRegPair *regs, ++ int total_args_passed) { ++ // Create the mapping between argument positions and ++ // registers. ++ static const Register INT_ArgReg[Argument::n_int_register_parameters_j] = { ++ j_rarg0, j_rarg1, j_rarg2, j_rarg3, ++ j_rarg4, j_rarg5, j_rarg6, j_rarg7 ++ }; ++ static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters_j] = { ++ j_farg0, j_farg1, j_farg2, j_farg3, ++ j_farg4, j_farg5, j_farg6, j_farg7 ++ }; ++ ++ uint int_args = 0; ++ uint fp_args = 0; ++ uint stk_args = 0; // inc by 2 each time ++ ++ for (int i = 0; i < total_args_passed; i++) { ++ switch (sig_bt[i]) { ++ case T_BOOLEAN: // fall through ++ case T_CHAR: // fall through ++ case T_BYTE: // fall through ++ case T_SHORT: // fall through ++ case T_INT: ++ if (int_args < Argument::n_int_register_parameters_j) { ++ regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); ++ } else { ++ regs[i].set1(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ case T_VOID: ++ // halves of T_LONG or T_DOUBLE ++ assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half"); ++ regs[i].set_bad(); ++ break; ++ case T_LONG: // fall through ++ assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half"); ++ case T_OBJECT: // fall through ++ case T_ARRAY: // fall through ++ case T_ADDRESS: ++ if (int_args < Argument::n_int_register_parameters_j) { ++ regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); ++ } else { ++ regs[i].set2(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ case T_FLOAT: ++ if (fp_args < Argument::n_float_register_parameters_j) { ++ regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); ++ } else { ++ regs[i].set1(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ case T_DOUBLE: ++ assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half"); ++ if (fp_args < Argument::n_float_register_parameters_j) { ++ regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg()); ++ } else { ++ regs[i].set2(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ } ++ ++ return align_up(stk_args, 2); ++} ++ ++// Patch the callers callsite with entry to compiled code if it exists. ++static void patch_callers_callsite(MacroAssembler *masm) { ++ Label L; ++ __ ld(t0, Address(xmethod, in_bytes(Method::code_offset()))); ++ __ beqz(t0, L); ++ ++ __ enter(); ++ __ push_CPU_state(); ++ ++ // VM needs caller's callsite ++ // VM needs target method ++ // This needs to be a long call since we will relocate this adapter to ++ // the codeBuffer and it may not reach ++ ++#ifndef PRODUCT ++ assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); ++#endif ++ ++ __ mv(c_rarg0, xmethod); ++ __ mv(c_rarg1, ra); ++ RuntimeAddress target(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ ++ __ pop_CPU_state(); ++ // restore sp ++ __ leave(); ++ __ bind(L); ++} ++ ++static void gen_c2i_adapter(MacroAssembler *masm, ++ int total_args_passed, ++ int comp_args_on_stack, ++ const BasicType *sig_bt, ++ const VMRegPair *regs, ++ Label& skip_fixup) { ++ // Before we get into the guts of the C2I adapter, see if we should be here ++ // at all. We've come from compiled code and are attempting to jump to the ++ // interpreter, which means the caller made a static call to get here ++ // (vcalls always get a compiled target if there is one). Check for a ++ // compiled target. If there is one, we need to patch the caller's call. ++ patch_callers_callsite(masm); ++ ++ __ bind(skip_fixup); ++ ++ int words_pushed = 0; ++ ++ // Since all args are passed on the stack, total_args_passed * ++ // Interpreter::stackElementSize is the space we need. ++ ++ int extraspace = total_args_passed * Interpreter::stackElementSize; ++ ++ __ mv(x30, sp); ++ ++ // stack is aligned, keep it that way ++ extraspace = align_up(extraspace, 2 * wordSize); ++ ++ if (extraspace) { ++ __ sub(sp, sp, extraspace); ++ } ++ ++ // Now write the args into the outgoing interpreter space ++ for (int i = 0; i < total_args_passed; i++) { ++ if (sig_bt[i] == T_VOID) { ++ assert(i > 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "missing half"); ++ continue; ++ } ++ ++ // offset to start parameters ++ int st_off = (total_args_passed - i - 1) * Interpreter::stackElementSize; ++ int next_off = st_off - Interpreter::stackElementSize; ++ ++ // Say 4 args: ++ // i st_off ++ // 0 32 T_LONG ++ // 1 24 T_VOID ++ // 2 16 T_OBJECT ++ // 3 8 T_BOOL ++ // - 0 return address ++ // ++ // However to make thing extra confusing. Because we can fit a Java long/double in ++ // a single slot on a 64 bt vm and it would be silly to break them up, the interpreter ++ // leaves one slot empty and only stores to a single slot. In this case the ++ // slot that is occupied is the T_VOID slot. See I said it was confusing. ++ ++ VMReg r_1 = regs[i].first(); ++ VMReg r_2 = regs[i].second(); ++ if (!r_1->is_valid()) { ++ assert(!r_2->is_valid(), ""); ++ continue; ++ } ++ if (r_1->is_stack()) { ++ // memory to memory use t0 ++ int ld_off = (r_1->reg2stack() * VMRegImpl::stack_slot_size ++ + extraspace ++ + words_pushed * wordSize); ++ if (!r_2->is_valid()) { ++ __ lwu(t0, Address(sp, ld_off)); ++ __ sd(t0, Address(sp, st_off), /*temp register*/esp); ++ } else { ++ __ ld(t0, Address(sp, ld_off), /*temp register*/esp); ++ ++ // Two VMREgs|OptoRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG ++ // T_DOUBLE and T_LONG use two slots in the interpreter ++ if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { ++ // ld_off == LSW, ld_off+wordSize == MSW ++ // st_off == MSW, next_off == LSW ++ __ sd(t0, Address(sp, next_off), /*temp register*/esp); ++#ifdef ASSERT ++ // Overwrite the unused slot with known junk ++ __ mv(t0, 0xdeadffffdeadaaaaul); ++ __ sd(t0, Address(sp, st_off), /*temp register*/esp); ++#endif /* ASSERT */ ++ } else { ++ __ sd(t0, Address(sp, st_off), /*temp register*/esp); ++ } ++ } ++ } else if (r_1->is_Register()) { ++ Register r = r_1->as_Register(); ++ if (!r_2->is_valid()) { ++ // must be only an int (or less ) so move only 32bits to slot ++ __ sd(r, Address(sp, st_off)); ++ } else { ++ // Two VMREgs|OptoRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG ++ // T_DOUBLE and T_LONG use two slots in the interpreter ++ if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { ++ // long/double in gpr ++#ifdef ASSERT ++ // Overwrite the unused slot with known junk ++ __ mv(t0, 0xdeadffffdeadaaabul); ++ __ sd(t0, Address(sp, st_off), /*temp register*/esp); ++#endif /* ASSERT */ ++ __ sd(r, Address(sp, next_off)); ++ } else { ++ __ sd(r, Address(sp, st_off)); ++ } ++ } ++ } else { ++ assert(r_1->is_FloatRegister(), ""); ++ if (!r_2->is_valid()) { ++ // only a float use just part of the slot ++ __ fsw(r_1->as_FloatRegister(), Address(sp, st_off)); ++ } else { ++#ifdef ASSERT ++ // Overwrite the unused slot with known junk ++ __ mv(t0, 0xdeadffffdeadaaacul); ++ __ sd(t0, Address(sp, st_off), /*temp register*/esp); ++#endif /* ASSERT */ ++ __ fsd(r_1->as_FloatRegister(), Address(sp, next_off)); ++ } ++ } ++ } ++ ++ __ mv(esp, sp); // Interp expects args on caller's expression stack ++ ++ __ ld(t0, Address(xmethod, in_bytes(Method::interpreter_entry_offset()))); ++ __ jr(t0); ++} ++ ++void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm, ++ int total_args_passed, ++ int comp_args_on_stack, ++ const BasicType *sig_bt, ++ const VMRegPair *regs) { ++ // Cut-out for having no stack args. ++ int comp_words_on_stack = align_up(comp_args_on_stack * VMRegImpl::stack_slot_size, wordSize) >> LogBytesPerWord; ++ if (comp_args_on_stack != 0) { ++ __ sub(t0, sp, comp_words_on_stack * wordSize); ++ __ andi(sp, t0, -16); ++ } ++ ++ // Will jump to the compiled code just as if compiled code was doing it. ++ // Pre-load the register-jump target early, to schedule it better. ++ __ ld(t1, Address(xmethod, in_bytes(Method::from_compiled_offset()))); ++ ++ // Now generate the shuffle code. ++ for (int i = 0; i < total_args_passed; i++) { ++ if (sig_bt[i] == T_VOID) { ++ assert(i > 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "missing half"); ++ continue; ++ } ++ ++ // Pick up 0, 1 or 2 words from SP+offset. ++ ++ assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), ++ "scrambled load targets?"); ++ // Load in argument order going down. ++ int ld_off = (total_args_passed - i - 1) * Interpreter::stackElementSize; ++ // Point to interpreter value (vs. tag) ++ int next_off = ld_off - Interpreter::stackElementSize; ++ ++ VMReg r_1 = regs[i].first(); ++ VMReg r_2 = regs[i].second(); ++ if (!r_1->is_valid()) { ++ assert(!r_2->is_valid(), ""); ++ continue; ++ } ++ if (r_1->is_stack()) { ++ // Convert stack slot to an SP offset (+ wordSize to account for return address ) ++ int st_off = regs[i].first()->reg2stack() * VMRegImpl::stack_slot_size; ++ if (!r_2->is_valid()) { ++ __ lw(t0, Address(esp, ld_off)); ++ __ sd(t0, Address(sp, st_off), /*temp register*/t2); ++ } else { ++ // ++ // We are using two optoregs. This can be either T_OBJECT, ++ // T_ADDRESS, T_LONG, or T_DOUBLE the interpreter allocates ++ // two slots but only uses one for thr T_LONG or T_DOUBLE case ++ // So we must adjust where to pick up the data to match the ++ // interpreter. ++ // ++ // Interpreter local[n] == MSW, local[n+1] == LSW however locals ++ // are accessed as negative so LSW is at LOW address ++ ++ // ld_off is MSW so get LSW ++ const int offset = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ? ++ next_off : ld_off; ++ __ ld(t0, Address(esp, offset)); ++ // st_off is LSW (i.e. reg.first()) ++ __ sd(t0, Address(sp, st_off), /*temp register*/t2); ++ } ++ } else if (r_1->is_Register()) { // Register argument ++ Register r = r_1->as_Register(); ++ if (r_2->is_valid()) { ++ // ++ // We are using two VMRegs. This can be either T_OBJECT, ++ // T_ADDRESS, T_LONG, or T_DOUBLE the interpreter allocates ++ // two slots but only uses one for thr T_LONG or T_DOUBLE case ++ // So we must adjust where to pick up the data to match the ++ // interpreter. ++ ++ const int offset = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ? ++ next_off : ld_off; ++ ++ // this can be a misaligned move ++ __ ld(r, Address(esp, offset)); ++ } else { ++ // sign extend and use a full word? ++ __ lw(r, Address(esp, ld_off)); ++ } ++ } else { ++ if (!r_2->is_valid()) { ++ __ flw(r_1->as_FloatRegister(), Address(esp, ld_off)); ++ } else { ++ __ fld(r_1->as_FloatRegister(), Address(esp, next_off)); ++ } ++ } ++ } ++ ++ // 6243940 We might end up in handle_wrong_method if ++ // the callee is deoptimized as we race thru here. If that ++ // happens we don't want to take a safepoint because the ++ // caller frame will look interpreted and arguments are now ++ // "compiled" so it is much better to make this transition ++ // invisible to the stack walking code. Unfortunately if ++ // we try and find the callee by normal means a safepoint ++ // is possible. So we stash the desired callee in the thread ++ // and the vm will find there should this case occur. ++ ++ __ sd(xmethod, Address(xthread, JavaThread::callee_target_offset())); ++ ++ __ jr(t1); ++} ++ ++// --------------------------------------------------------------- ++AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, ++ int total_args_passed, ++ int comp_args_on_stack, ++ const BasicType *sig_bt, ++ const VMRegPair *regs, ++ AdapterFingerPrint* fingerprint) { ++ address i2c_entry = __ pc(); ++ gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); ++ ++ address c2i_unverified_entry = __ pc(); ++ Label skip_fixup; ++ ++ Label ok; ++ ++ const Register holder = t1; ++ const Register receiver = j_rarg0; ++ const Register tmp = t2; // A call-clobbered register not used for arg passing ++ ++ // ------------------------------------------------------------------------- ++ // Generate a C2I adapter. On entry we know xmethod holds the Method* during calls ++ // to the interpreter. The args start out packed in the compiled layout. They ++ // need to be unpacked into the interpreter layout. This will almost always ++ // require some stack space. We grow the current (compiled) stack, then repack ++ // the args. We finally end in a jump to the generic interpreter entry point. ++ // On exit from the interpreter, the interpreter will restore our SP (lest the ++ // compiled code, which relys solely on SP and not FP, get sick). ++ ++ { ++ __ block_comment("c2i_unverified_entry {"); ++ __ load_klass(t0, receiver, tmp); ++ __ ld(tmp, Address(holder, CompiledICHolder::holder_klass_offset())); ++ __ ld(xmethod, Address(holder, CompiledICHolder::holder_metadata_offset())); ++ __ beq(t0, tmp, ok); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); ++ ++ __ bind(ok); ++ // Method might have been compiled since the call site was patched to ++ // interpreted; if that is the case treat it as a miss so we can get ++ // the call site corrected. ++ __ ld(t0, Address(xmethod, in_bytes(Method::code_offset()))); ++ __ beqz(t0, skip_fixup); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); ++ __ block_comment("} c2i_unverified_entry"); ++ } ++ ++ address c2i_entry = __ pc(); ++ ++ // Class initialization barrier for static methods ++ address c2i_no_clinit_check_entry = NULL; ++ if (VM_Version::supports_fast_class_init_checks()) { ++ Label L_skip_barrier; ++ ++ { // Bypass the barrier for non-static methods ++ __ lwu(t0, Address(xmethod, Method::access_flags_offset())); ++ __ test_bit(t1, t0, exact_log2(JVM_ACC_STATIC)); ++ __ beqz(t1, L_skip_barrier); // non-static ++ } ++ ++ __ load_method_holder(t1, xmethod); ++ __ clinit_barrier(t1, t0, &L_skip_barrier); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); ++ ++ __ bind(L_skip_barrier); ++ c2i_no_clinit_check_entry = __ pc(); ++ } ++ ++ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->c2i_entry_barrier(masm); ++ ++ gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); ++ ++ __ flush(); ++ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry); ++} ++ ++int SharedRuntime::vector_calling_convention(VMRegPair *regs, ++ uint num_bits, ++ uint total_args_passed) { ++ Unimplemented(); ++ return 0; ++} ++ ++int SharedRuntime::c_calling_convention(const BasicType *sig_bt, ++ VMRegPair *regs, ++ VMRegPair *regs2, ++ int total_args_passed) { ++ assert(regs2 == NULL, "not needed on riscv"); ++ ++ // We return the amount of VMRegImpl stack slots we need to reserve for all ++ // the arguments NOT counting out_preserve_stack_slots. ++ ++ static const Register INT_ArgReg[Argument::n_int_register_parameters_c] = { ++ c_rarg0, c_rarg1, c_rarg2, c_rarg3, ++ c_rarg4, c_rarg5, c_rarg6, c_rarg7 ++ }; ++ static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters_c] = { ++ c_farg0, c_farg1, c_farg2, c_farg3, ++ c_farg4, c_farg5, c_farg6, c_farg7 ++ }; ++ ++ uint int_args = 0; ++ uint fp_args = 0; ++ uint stk_args = 0; // inc by 2 each time ++ ++ for (int i = 0; i < total_args_passed; i++) { ++ switch (sig_bt[i]) { ++ case T_BOOLEAN: // fall through ++ case T_CHAR: // fall through ++ case T_BYTE: // fall through ++ case T_SHORT: // fall through ++ case T_INT: ++ if (int_args < Argument::n_int_register_parameters_c) { ++ regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); ++ } else { ++ regs[i].set1(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ case T_LONG: // fall through ++ assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half"); ++ case T_OBJECT: // fall through ++ case T_ARRAY: // fall through ++ case T_ADDRESS: // fall through ++ case T_METADATA: ++ if (int_args < Argument::n_int_register_parameters_c) { ++ regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); ++ } else { ++ regs[i].set2(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ case T_FLOAT: ++ if (fp_args < Argument::n_float_register_parameters_c) { ++ regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); ++ } else if (int_args < Argument::n_int_register_parameters_c) { ++ regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); ++ } else { ++ regs[i].set1(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ case T_DOUBLE: ++ assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half"); ++ if (fp_args < Argument::n_float_register_parameters_c) { ++ regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg()); ++ } else if (int_args < Argument::n_int_register_parameters_c) { ++ regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); ++ } else { ++ regs[i].set2(VMRegImpl::stack2reg(stk_args)); ++ stk_args += 2; ++ } ++ break; ++ case T_VOID: // Halves of longs and doubles ++ assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half"); ++ regs[i].set_bad(); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ } ++ ++ return stk_args; ++} ++ ++// On 64 bit we will store integer like items to the stack as ++// 64 bits items (riscv64 abi) even though java would only store ++// 32bits for a parameter. On 32bit it will simply be 32 bits ++// So this routine will do 32->32 on 32bit and 32->64 on 64bit ++static void move32_64(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { ++ if (src.first()->is_stack()) { ++ if (dst.first()->is_stack()) { ++ // stack to stack ++ __ ld(t0, Address(fp, reg2offset_in(src.first()))); ++ __ sd(t0, Address(sp, reg2offset_out(dst.first()))); ++ } else { ++ // stack to reg ++ __ lw(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first()))); ++ } ++ } else if (dst.first()->is_stack()) { ++ // reg to stack ++ __ sd(src.first()->as_Register(), Address(sp, reg2offset_out(dst.first()))); ++ } else { ++ if (dst.first() != src.first()) { ++ // 32bits extend sign ++ __ sign_extend(dst.first()->as_Register(), src.first()->as_Register(), 32); ++ } ++ } ++} ++ ++// An oop arg. Must pass a handle not the oop itself ++static void object_move(MacroAssembler* masm, ++ OopMap* map, ++ int oop_handle_offset, ++ int framesize_in_slots, ++ VMRegPair src, ++ VMRegPair dst, ++ bool is_receiver, ++ int* receiver_offset) { ++ // must pass a handle. First figure out the location we use as a handle ++ Register rHandle = dst.first()->is_stack() ? t1 : dst.first()->as_Register(); ++ ++ // See if oop is NULL if it is we need no handle ++ ++ if (src.first()->is_stack()) { ++ ++ // Oop is already on the stack as an argument ++ int offset_in_older_frame = src.first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); ++ map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots)); ++ if (is_receiver) { ++ *receiver_offset = (offset_in_older_frame + framesize_in_slots) * VMRegImpl::stack_slot_size; ++ } ++ ++ __ ld(t0, Address(fp, reg2offset_in(src.first()))); ++ __ la(rHandle, Address(fp, reg2offset_in(src.first()))); ++ // conditionally move a NULL ++ Label notZero1; ++ __ bnez(t0, notZero1); ++ __ mv(rHandle, zr); ++ __ bind(notZero1); ++ } else { ++ ++ // Oop is in an a register we must store it to the space we reserve ++ // on the stack for oop_handles and pass a handle if oop is non-NULL ++ ++ const Register rOop = src.first()->as_Register(); ++ int oop_slot = -1; ++ if (rOop == j_rarg0) { ++ oop_slot = 0; ++ } else if (rOop == j_rarg1) { ++ oop_slot = 1; ++ } else if (rOop == j_rarg2) { ++ oop_slot = 2; ++ } else if (rOop == j_rarg3) { ++ oop_slot = 3; ++ } else if (rOop == j_rarg4) { ++ oop_slot = 4; ++ } else if (rOop == j_rarg5) { ++ oop_slot = 5; ++ } else if (rOop == j_rarg6) { ++ oop_slot = 6; ++ } else { ++ assert(rOop == j_rarg7, "wrong register"); ++ oop_slot = 7; ++ } ++ ++ oop_slot = oop_slot * VMRegImpl::slots_per_word + oop_handle_offset; ++ int offset = oop_slot * VMRegImpl::stack_slot_size; ++ ++ map->set_oop(VMRegImpl::stack2reg(oop_slot)); ++ // Store oop in handle area, may be NULL ++ __ sd(rOop, Address(sp, offset)); ++ if (is_receiver) { ++ *receiver_offset = offset; ++ } ++ ++ //rOop maybe the same as rHandle ++ if (rOop == rHandle) { ++ Label isZero; ++ __ beqz(rOop, isZero); ++ __ la(rHandle, Address(sp, offset)); ++ __ bind(isZero); ++ } else { ++ Label notZero2; ++ __ la(rHandle, Address(sp, offset)); ++ __ bnez(rOop, notZero2); ++ __ mv(rHandle, zr); ++ __ bind(notZero2); ++ } ++ } ++ ++ // If arg is on the stack then place it otherwise it is already in correct reg. ++ if (dst.first()->is_stack()) { ++ __ sd(rHandle, Address(sp, reg2offset_out(dst.first()))); ++ } ++} ++ ++// A float arg may have to do float reg int reg conversion ++static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { ++ assert(src.first()->is_stack() && dst.first()->is_stack() || ++ src.first()->is_reg() && dst.first()->is_reg() || src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error"); ++ if (src.first()->is_stack()) { ++ if (dst.first()->is_stack()) { ++ __ lwu(t0, Address(fp, reg2offset_in(src.first()))); ++ __ sw(t0, Address(sp, reg2offset_out(dst.first()))); ++ } else if (dst.first()->is_Register()) { ++ __ lwu(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first()))); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } else if (src.first() != dst.first()) { ++ if (src.is_single_phys_reg() && dst.is_single_phys_reg()) { ++ __ fmv_s(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } ++} ++ ++// A long move ++static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { ++ if (src.first()->is_stack()) { ++ if (dst.first()->is_stack()) { ++ // stack to stack ++ __ ld(t0, Address(fp, reg2offset_in(src.first()))); ++ __ sd(t0, Address(sp, reg2offset_out(dst.first()))); ++ } else { ++ // stack to reg ++ __ ld(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first()))); ++ } ++ } else if (dst.first()->is_stack()) { ++ // reg to stack ++ __ sd(src.first()->as_Register(), Address(sp, reg2offset_out(dst.first()))); ++ } else { ++ if (dst.first() != src.first()) { ++ __ mv(dst.first()->as_Register(), src.first()->as_Register()); ++ } ++ } ++} ++ ++// A double move ++static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { ++ assert(src.first()->is_stack() && dst.first()->is_stack() || ++ src.first()->is_reg() && dst.first()->is_reg() || src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error"); ++ if (src.first()->is_stack()) { ++ if (dst.first()->is_stack()) { ++ __ ld(t0, Address(fp, reg2offset_in(src.first()))); ++ __ sd(t0, Address(sp, reg2offset_out(dst.first()))); ++ } else if (dst.first()-> is_Register()) { ++ __ ld(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first()))); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } else if (src.first() != dst.first()) { ++ if (src.is_single_phys_reg() && dst.is_single_phys_reg()) { ++ __ fmv_d(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); ++ } else { ++ ShouldNotReachHere(); ++ } ++ } ++} ++ ++void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) { ++ // We always ignore the frame_slots arg and just use the space just below frame pointer ++ // which by this time is free to use ++ switch (ret_type) { ++ case T_FLOAT: ++ __ fsw(f10, Address(fp, -3 * wordSize)); ++ break; ++ case T_DOUBLE: ++ __ fsd(f10, Address(fp, -3 * wordSize)); ++ break; ++ case T_VOID: break; ++ default: { ++ __ sd(x10, Address(fp, -3 * wordSize)); ++ } ++ } ++} ++ ++void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) { ++ // We always ignore the frame_slots arg and just use the space just below frame pointer ++ // which by this time is free to use ++ switch (ret_type) { ++ case T_FLOAT: ++ __ flw(f10, Address(fp, -3 * wordSize)); ++ break; ++ case T_DOUBLE: ++ __ fld(f10, Address(fp, -3 * wordSize)); ++ break; ++ case T_VOID: break; ++ default: { ++ __ ld(x10, Address(fp, -3 * wordSize)); ++ } ++ } ++} ++ ++static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { ++ RegSet x; ++ for ( int i = first_arg ; i < arg_count ; i++ ) { ++ if (args[i].first()->is_Register()) { ++ x = x + args[i].first()->as_Register(); ++ } else if (args[i].first()->is_FloatRegister()) { ++ __ addi(sp, sp, -2 * wordSize); ++ __ fsd(args[i].first()->as_FloatRegister(), Address(sp, 0)); ++ } ++ } ++ __ push_reg(x, sp); ++} ++ ++static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { ++ RegSet x; ++ for ( int i = first_arg ; i < arg_count ; i++ ) { ++ if (args[i].first()->is_Register()) { ++ x = x + args[i].first()->as_Register(); ++ } else { ++ ; ++ } ++ } ++ __ pop_reg(x, sp); ++ for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) { ++ if (args[i].first()->is_Register()) { ++ ; ++ } else if (args[i].first()->is_FloatRegister()) { ++ __ fld(args[i].first()->as_FloatRegister(), Address(sp, 0)); ++ __ add(sp, sp, 2 * wordSize); ++ } ++ } ++} ++ ++// Unpack an array argument into a pointer to the body and the length ++// if the array is non-null, otherwise pass 0 for both. ++static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType in_elem_type, VMRegPair body_arg, VMRegPair length_arg) { Unimplemented(); } ++ ++class ComputeMoveOrder: public StackObj { ++ class MoveOperation: public ResourceObj { ++ friend class ComputeMoveOrder; ++ private: ++ VMRegPair _src; ++ VMRegPair _dst; ++ int _src_index; ++ int _dst_index; ++ bool _processed; ++ MoveOperation* _next; ++ MoveOperation* _prev; ++ ++ static int get_id(VMRegPair r) { Unimplemented(); return 0; } ++ ++ public: ++ MoveOperation(int src_index, VMRegPair src, int dst_index, VMRegPair dst): ++ _src(src) ++ , _dst(dst) ++ , _src_index(src_index) ++ , _dst_index(dst_index) ++ , _processed(false) ++ , _next(NULL) ++ , _prev(NULL) { Unimplemented(); } ++ ++ VMRegPair src() const { Unimplemented(); return _src; } ++ int src_id() const { Unimplemented(); return 0; } ++ int src_index() const { Unimplemented(); return 0; } ++ VMRegPair dst() const { Unimplemented(); return _src; } ++ void set_dst(int i, VMRegPair dst) { Unimplemented(); } ++ int dst_index() const { Unimplemented(); return 0; } ++ int dst_id() const { Unimplemented(); return 0; } ++ MoveOperation* next() const { Unimplemented(); return 0; } ++ MoveOperation* prev() const { Unimplemented(); return 0; } ++ void set_processed() { Unimplemented(); } ++ bool is_processed() const { Unimplemented(); return 0; } ++ ++ // insert ++ void break_cycle(VMRegPair temp_register) { Unimplemented(); } ++ ++ void link(GrowableArray& killer) { Unimplemented(); } ++ }; ++ ++ private: ++ GrowableArray edges; ++ ++ public: ++ ComputeMoveOrder(int total_in_args, VMRegPair* in_regs, int total_c_args, VMRegPair* out_regs, ++ BasicType* in_sig_bt, GrowableArray& arg_order, VMRegPair tmp_vmreg) { Unimplemented(); } ++ ++ // Collected all the move operations ++ void add_edge(int src_index, VMRegPair src, int dst_index, VMRegPair dst) { Unimplemented(); } ++ ++ // Walk the edges breaking cycles between moves. The result list ++ // can be walked in order to produce the proper set of loads ++ GrowableArray* get_store_order(VMRegPair temp_register) { Unimplemented(); return 0; } ++}; ++ ++static void rt_call(MacroAssembler* masm, address dest) { ++ CodeBlob *cb = CodeCache::find_blob(dest); ++ RuntimeAddress target(dest); ++ if (cb) { ++ __ far_call(target); ++ } else { ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ } ++} ++ ++static void verify_oop_args(MacroAssembler* masm, ++ const methodHandle& method, ++ const BasicType* sig_bt, ++ const VMRegPair* regs) { ++ const Register temp_reg = x9; // not part of any compiled calling seq ++ if (VerifyOops) { ++ for (int i = 0; i < method->size_of_parameters(); i++) { ++ if (sig_bt[i] == T_OBJECT || ++ sig_bt[i] == T_ARRAY) { ++ VMReg r = regs[i].first(); ++ assert(r->is_valid(), "bad oop arg"); ++ if (r->is_stack()) { ++ __ ld(temp_reg, Address(sp, r->reg2stack() * VMRegImpl::stack_slot_size)); ++ __ verify_oop(temp_reg); ++ } else { ++ __ verify_oop(r->as_Register()); ++ } ++ } ++ } ++ } ++} ++ ++static void gen_special_dispatch(MacroAssembler* masm, ++ const methodHandle& method, ++ const BasicType* sig_bt, ++ const VMRegPair* regs) { ++ verify_oop_args(masm, method, sig_bt, regs); ++ vmIntrinsics::ID iid = method->intrinsic_id(); ++ ++ // Now write the args into the outgoing interpreter space ++ bool has_receiver = false; ++ Register receiver_reg = noreg; ++ int member_arg_pos = -1; ++ Register member_reg = noreg; ++ int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid); ++ if (ref_kind != 0) { ++ member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument ++ member_reg = x9; // known to be free at this point ++ has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); ++ } else if (iid == vmIntrinsics::_invokeBasic || iid == vmIntrinsics::_linkToNative) { ++ has_receiver = true; ++ } else { ++ fatal("unexpected intrinsic id %d", vmIntrinsics::as_int(iid)); ++ } ++ ++ if (member_reg != noreg) { ++ // Load the member_arg into register, if necessary. ++ SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs); ++ VMReg r = regs[member_arg_pos].first(); ++ if (r->is_stack()) { ++ __ ld(member_reg, Address(sp, r->reg2stack() * VMRegImpl::stack_slot_size)); ++ } else { ++ // no data motion is needed ++ member_reg = r->as_Register(); ++ } ++ } ++ ++ if (has_receiver) { ++ // Make sure the receiver is loaded into a register. ++ assert(method->size_of_parameters() > 0, "oob"); ++ assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); ++ VMReg r = regs[0].first(); ++ assert(r->is_valid(), "bad receiver arg"); ++ if (r->is_stack()) { ++ // Porting note: This assumes that compiled calling conventions always ++ // pass the receiver oop in a register. If this is not true on some ++ // platform, pick a temp and load the receiver from stack. ++ fatal("receiver always in a register"); ++ receiver_reg = x12; // known to be free at this point ++ __ ld(receiver_reg, Address(sp, r->reg2stack() * VMRegImpl::stack_slot_size)); ++ } else { ++ // no data motion is needed ++ receiver_reg = r->as_Register(); ++ } ++ } ++ ++ // Figure out which address we are really jumping to: ++ MethodHandles::generate_method_handle_dispatch(masm, iid, ++ receiver_reg, member_reg, /*for_compiler_entry:*/ true); ++} ++ ++// --------------------------------------------------------------------------- ++// Generate a native wrapper for a given method. The method takes arguments ++// in the Java compiled code convention, marshals them to the native ++// convention (handlizes oops, etc), transitions to native, makes the call, ++// returns to java state (possibly blocking), unhandlizes any result and ++// returns. ++// ++// Critical native functions are a shorthand for the use of ++// GetPrimtiveArrayCritical and disallow the use of any other JNI ++// functions. The wrapper is expected to unpack the arguments before ++// passing them to the callee and perform checks before and after the ++// native call to ensure that they GCLocker ++// lock_critical/unlock_critical semantics are followed. Some other ++// parts of JNI setup are skipped like the tear down of the JNI handle ++// block and the check for pending exceptions it's impossible for them ++// to be thrown. ++// ++// They are roughly structured like this: ++// if (GCLocker::needs_gc()) SharedRuntime::block_for_jni_critical() ++// tranistion to thread_in_native ++// unpack arrray arguments and call native entry point ++// check for safepoint in progress ++// check if any thread suspend flags are set ++// call into JVM and possible unlock the JNI critical ++// if a GC was suppressed while in the critical native. ++// transition back to thread_in_Java ++// return to caller ++// ++nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, ++ const methodHandle& method, ++ int compile_id, ++ BasicType* in_sig_bt, ++ VMRegPair* in_regs, ++ BasicType ret_type, ++ address critical_entry) { ++ if (method->is_method_handle_intrinsic()) { ++ vmIntrinsics::ID iid = method->intrinsic_id(); ++ intptr_t start = (intptr_t)__ pc(); ++ int vep_offset = ((intptr_t)__ pc()) - start; ++ ++ // First instruction must be a nop as it may need to be patched on deoptimisation ++ { ++ Assembler::IncompressibleRegion ir(masm); // keep the nop as 4 bytes for patching. ++ MacroAssembler::assert_alignment(__ pc()); ++ __ nop(); // 4 bytes ++ } ++ gen_special_dispatch(masm, ++ method, ++ in_sig_bt, ++ in_regs); ++ int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period ++ __ flush(); ++ int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually ++ return nmethod::new_native_nmethod(method, ++ compile_id, ++ masm->code(), ++ vep_offset, ++ frame_complete, ++ stack_slots / VMRegImpl::slots_per_word, ++ in_ByteSize(-1), ++ in_ByteSize(-1), ++ (OopMapSet*)NULL); ++ } ++ bool is_critical_native = true; ++ address native_func = critical_entry; ++ if (native_func == NULL) { ++ native_func = method->native_function(); ++ is_critical_native = false; ++ } ++ assert(native_func != NULL, "must have function"); ++ ++ // An OopMap for lock (and class if static) ++ OopMapSet *oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ intptr_t start = (intptr_t)__ pc(); ++ ++ // We have received a description of where all the java arg are located ++ // on entry to the wrapper. We need to convert these args to where ++ // the jni function will expect them. To figure out where they go ++ // we convert the java signature to a C signature by inserting ++ // the hidden arguments as arg[0] and possibly arg[1] (static method) ++ ++ const int total_in_args = method->size_of_parameters(); ++ int total_c_args = total_in_args; ++ if (!is_critical_native) { ++ total_c_args += 1; ++ if (method->is_static()) { ++ total_c_args++; ++ } ++ } else { ++ for (int i = 0; i < total_in_args; i++) { ++ if (in_sig_bt[i] == T_ARRAY) { ++ total_c_args++; ++ } ++ } ++ } ++ ++ BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); ++ VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); ++ BasicType* in_elem_bt = NULL; ++ ++ int argc = 0; ++ if (!is_critical_native) { ++ out_sig_bt[argc++] = T_ADDRESS; ++ if (method->is_static()) { ++ out_sig_bt[argc++] = T_OBJECT; ++ } ++ ++ for (int i = 0; i < total_in_args ; i++ ) { ++ out_sig_bt[argc++] = in_sig_bt[i]; ++ } ++ } else { ++ in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args); ++ SignatureStream ss(method->signature()); ++ for (int i = 0; i < total_in_args ; i++ ) { ++ if (in_sig_bt[i] == T_ARRAY) { ++ // Arrays are passed as int, elem* pair ++ out_sig_bt[argc++] = T_INT; ++ out_sig_bt[argc++] = T_ADDRESS; ++ ss.skip_array_prefix(1); // skip one '[' ++ assert(ss.is_primitive(), "primitive type expected"); ++ in_elem_bt[i] = ss.type(); ++ } else { ++ out_sig_bt[argc++] = in_sig_bt[i]; ++ in_elem_bt[i] = T_VOID; ++ } ++ if (in_sig_bt[i] != T_VOID) { ++ assert(in_sig_bt[i] == ss.type() || ++ in_sig_bt[i] == T_ARRAY, "must match"); ++ ss.next(); ++ } ++ } ++ } ++ ++ // Now figure out where the args must be stored and how much stack space ++ // they require. ++ int out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); ++ ++ // Compute framesize for the wrapper. We need to handlize all oops in ++ // incoming registers ++ ++ // Calculate the total number of stack slots we will need. ++ ++ // First count the abi requirement plus all of the outgoing args ++ int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; ++ ++ // Now the space for the inbound oop handle area ++ int total_save_slots = 8 * VMRegImpl::slots_per_word; // 8 arguments passed in registers ++ if (is_critical_native) { ++ // Critical natives may have to call out so they need a save area ++ // for register arguments. ++ int double_slots = 0; ++ int single_slots = 0; ++ for ( int i = 0; i < total_in_args; i++) { ++ if (in_regs[i].first()->is_Register()) { ++ const Register reg = in_regs[i].first()->as_Register(); ++ switch (in_sig_bt[i]) { ++ case T_BOOLEAN: ++ case T_BYTE: ++ case T_SHORT: ++ case T_CHAR: ++ case T_INT: single_slots++; break; ++ case T_ARRAY: // specific to LP64 (7145024) ++ case T_LONG: double_slots++; break; ++ default: ShouldNotReachHere(); ++ } ++ } else if (in_regs[i].first()->is_FloatRegister()) { ++ ShouldNotReachHere(); ++ } ++ } ++ total_save_slots = double_slots * 2 + single_slots; ++ // align the save area ++ if (double_slots != 0) { ++ stack_slots = align_up(stack_slots, 2); ++ } ++ } ++ ++ int oop_handle_offset = stack_slots; ++ stack_slots += total_save_slots; ++ ++ // Now any space we need for handlizing a klass if static method ++ ++ int klass_slot_offset = 0; ++ int klass_offset = -1; ++ int lock_slot_offset = 0; ++ bool is_static = false; ++ ++ if (method->is_static()) { ++ klass_slot_offset = stack_slots; ++ stack_slots += VMRegImpl::slots_per_word; ++ klass_offset = klass_slot_offset * VMRegImpl::stack_slot_size; ++ is_static = true; ++ } ++ ++ // Plus a lock if needed ++ ++ if (method->is_synchronized()) { ++ lock_slot_offset = stack_slots; ++ stack_slots += VMRegImpl::slots_per_word; ++ } ++ ++ // Now a place (+2) to save return values or temp during shuffling ++ // + 4 for return address (which we own) and saved fp ++ stack_slots += 6; ++ ++ // Ok The space we have allocated will look like: ++ // ++ // ++ // FP-> | | ++ // | 2 slots (ra) | ++ // | 2 slots (fp) | ++ // |---------------------| ++ // | 2 slots for moves | ++ // |---------------------| ++ // | lock box (if sync) | ++ // |---------------------| <- lock_slot_offset ++ // | klass (if static) | ++ // |---------------------| <- klass_slot_offset ++ // | oopHandle area | ++ // |---------------------| <- oop_handle_offset (8 java arg registers) ++ // | outbound memory | ++ // | based arguments | ++ // | | ++ // |---------------------| ++ // | | ++ // SP-> | out_preserved_slots | ++ // ++ // ++ ++ ++ // Now compute actual number of stack words we need rounding to make ++ // stack properly aligned. ++ stack_slots = align_up(stack_slots, StackAlignmentInSlots); ++ ++ int stack_size = stack_slots * VMRegImpl::stack_slot_size; ++ ++ // First thing make an ic check to see if we should even be here ++ ++ // We are free to use all registers as temps without saving them and ++ // restoring them except fp. fp is the only callee save register ++ // as far as the interpreter and the compiler(s) are concerned. ++ ++ ++ const Register ic_reg = t1; ++ const Register receiver = j_rarg0; ++ ++ Label hit; ++ Label exception_pending; ++ ++ __ verify_oop(receiver); ++ assert_different_registers(ic_reg, receiver, t0, t2); ++ __ cmp_klass(receiver, ic_reg, t0, t2 /* call-clobbered t2 as a tmp */, hit); ++ ++ __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); ++ ++ // Verified entry point must be aligned ++ __ align(8); ++ ++ __ bind(hit); ++ ++ int vep_offset = ((intptr_t)__ pc()) - start; ++ ++ // If we have to make this method not-entrant we'll overwrite its ++ // first instruction with a jump. ++ { ++ Assembler::IncompressibleRegion ir(masm); // keep the nop as 4 bytes for patching. ++ MacroAssembler::assert_alignment(__ pc()); ++ __ nop(); // 4 bytes ++ } ++ ++ if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) { ++ Label L_skip_barrier; ++ __ mov_metadata(t1, method->method_holder()); // InstanceKlass* ++ __ clinit_barrier(t1, t0, &L_skip_barrier); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); ++ ++ __ bind(L_skip_barrier); ++ } ++ ++ // Generate stack overflow check ++ __ bang_stack_with_offset(checked_cast(StackOverflow::stack_shadow_zone_size())); ++ ++ // Generate a new frame for the wrapper. ++ __ enter(); ++ // -2 because return address is already present and so is saved fp ++ __ sub(sp, sp, stack_size - 2 * wordSize); ++ ++ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ assert_cond(bs != NULL); ++ bs->nmethod_entry_barrier(masm); ++ ++ // Frame is now completed as far as size and linkage. ++ int frame_complete = ((intptr_t)__ pc()) - start; ++ ++ // We use x18 as the oop handle for the receiver/klass ++ // It is callee save so it survives the call to native ++ ++ const Register oop_handle_reg = x18; ++ ++ // ++ // We immediately shuffle the arguments so that any vm call we have to ++ // make from here on out (sync slow path, jvmti, etc.) we will have ++ // captured the oops from our caller and have a valid oopMap for ++ // them. ++ ++ // ----------------- ++ // The Grand Shuffle ++ ++ // The Java calling convention is either equal (linux) or denser (win64) than the ++ // c calling convention. However the because of the jni_env argument the c calling ++ // convention always has at least one more (and two for static) arguments than Java. ++ // Therefore if we move the args from java -> c backwards then we will never have ++ // a register->register conflict and we don't have to build a dependency graph ++ // and figure out how to break any cycles. ++ // ++ ++ // Record esp-based slot for receiver on stack for non-static methods ++ int receiver_offset = -1; ++ ++ // This is a trick. We double the stack slots so we can claim ++ // the oops in the caller's frame. Since we are sure to have ++ // more args than the caller doubling is enough to make ++ // sure we can capture all the incoming oop args from the ++ // caller. ++ // ++ OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); ++ assert_cond(map != NULL); ++ ++ int float_args = 0; ++ int int_args = 0; ++ ++#ifdef ASSERT ++ bool reg_destroyed[RegisterImpl::number_of_registers]; ++ bool freg_destroyed[FloatRegisterImpl::number_of_registers]; ++ for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) { ++ reg_destroyed[r] = false; ++ } ++ for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) { ++ freg_destroyed[f] = false; ++ } ++ ++#endif /* ASSERT */ ++ ++ // This may iterate in two different directions depending on the ++ // kind of native it is. The reason is that for regular JNI natives ++ // the incoming and outgoing registers are offset upwards and for ++ // critical natives they are offset down. ++ GrowableArray arg_order(2 * total_in_args); ++ VMRegPair tmp_vmreg; ++ tmp_vmreg.set2(x9->as_VMReg()); ++ ++ if (!is_critical_native) { ++ for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { ++ arg_order.push(i); ++ arg_order.push(c_arg); ++ } ++ } else { ++ // Compute a valid move order, using tmp_vmreg to break any cycles ++ ComputeMoveOrder cmo(total_in_args, in_regs, total_c_args, out_regs, in_sig_bt, arg_order, tmp_vmreg); ++ } ++ ++ int temploc = -1; ++ for (int ai = 0; ai < arg_order.length(); ai += 2) { ++ int i = arg_order.at(ai); ++ int c_arg = arg_order.at(ai + 1); ++ __ block_comment(err_msg("mv %d -> %d", i, c_arg)); ++ if (c_arg == -1) { ++ assert(is_critical_native, "should only be required for critical natives"); ++ // This arg needs to be moved to a temporary ++ __ mv(tmp_vmreg.first()->as_Register(), in_regs[i].first()->as_Register()); ++ in_regs[i] = tmp_vmreg; ++ temploc = i; ++ continue; ++ } else if (i == -1) { ++ assert(is_critical_native, "should only be required for critical natives"); ++ // Read from the temporary location ++ assert(temploc != -1, "must be valid"); ++ i = temploc; ++ temploc = -1; ++ } ++#ifdef ASSERT ++ if (in_regs[i].first()->is_Register()) { ++ assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!"); ++ } else if (in_regs[i].first()->is_FloatRegister()) { ++ assert(!freg_destroyed[in_regs[i].first()->as_FloatRegister()->encoding()], "destroyed reg!"); ++ } ++ if (out_regs[c_arg].first()->is_Register()) { ++ reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true; ++ } else if (out_regs[c_arg].first()->is_FloatRegister()) { ++ freg_destroyed[out_regs[c_arg].first()->as_FloatRegister()->encoding()] = true; ++ } ++#endif /* ASSERT */ ++ switch (in_sig_bt[i]) { ++ case T_ARRAY: ++ if (is_critical_native) { ++ unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]); ++ c_arg++; ++#ifdef ASSERT ++ if (out_regs[c_arg].first()->is_Register()) { ++ reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true; ++ } else if (out_regs[c_arg].first()->is_FloatRegister()) { ++ freg_destroyed[out_regs[c_arg].first()->as_FloatRegister()->encoding()] = true; ++ } ++#endif ++ int_args++; ++ break; ++ } ++ case T_OBJECT: ++ assert(!is_critical_native, "no oop arguments"); ++ object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg], ++ ((i == 0) && (!is_static)), ++ &receiver_offset); ++ int_args++; ++ break; ++ case T_VOID: ++ break; ++ ++ case T_FLOAT: ++ float_move(masm, in_regs[i], out_regs[c_arg]); ++ float_args++; ++ break; ++ ++ case T_DOUBLE: ++ assert( i + 1 < total_in_args && ++ in_sig_bt[i + 1] == T_VOID && ++ out_sig_bt[c_arg + 1] == T_VOID, "bad arg list"); ++ double_move(masm, in_regs[i], out_regs[c_arg]); ++ float_args++; ++ break; ++ ++ case T_LONG : ++ long_move(masm, in_regs[i], out_regs[c_arg]); ++ int_args++; ++ break; ++ ++ case T_ADDRESS: ++ assert(false, "found T_ADDRESS in java args"); ++ break; ++ ++ default: ++ move32_64(masm, in_regs[i], out_regs[c_arg]); ++ int_args++; ++ } ++ } ++ ++ // point c_arg at the first arg that is already loaded in case we ++ // need to spill before we call out ++ int c_arg = total_c_args - total_in_args; ++ ++ // Pre-load a static method's oop into c_rarg1. ++ if (method->is_static() && !is_critical_native) { ++ ++ // load oop into a register ++ __ movoop(c_rarg1, ++ JNIHandles::make_local(method->method_holder()->java_mirror()), ++ /*immediate*/true); ++ ++ // Now handlize the static class mirror it's known not-null. ++ __ sd(c_rarg1, Address(sp, klass_offset)); ++ map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); ++ ++ // Now get the handle ++ __ la(c_rarg1, Address(sp, klass_offset)); ++ // and protect the arg if we must spill ++ c_arg--; ++ } ++ ++ // Change state to native (we save the return address in the thread, since it might not ++ // be pushed on the stack when we do a stack traversal). ++ // We use the same pc/oopMap repeatedly when we call out ++ ++ Label native_return; ++ __ set_last_Java_frame(sp, noreg, native_return, t0); ++ ++ Label dtrace_method_entry, dtrace_method_entry_done; ++ { ++ ExternalAddress target((address)&DTraceMethodProbes); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ lbu(t0, Address(t0, offset)); ++ }); ++ __ bnez(t0, dtrace_method_entry); ++ __ bind(dtrace_method_entry_done); ++ } ++ ++ // RedefineClasses() tracing support for obsolete method entry ++ if (log_is_enabled(Trace, redefine, class, obsolete)) { ++ // protect the args we've loaded ++ save_args(masm, total_c_args, c_arg, out_regs); ++ __ mov_metadata(c_rarg1, method()); ++ __ call_VM_leaf( ++ CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry), ++ xthread, c_rarg1); ++ restore_args(masm, total_c_args, c_arg, out_regs); ++ } ++ ++ // Lock a synchronized method ++ ++ // Register definitions used by locking and unlocking ++ ++ const Register swap_reg = x10; ++ 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 tmp = ra; ++ ++ Label slow_path_lock; ++ Label lock_done; ++ ++ if (method->is_synchronized()) { ++ ++ const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); ++ ++ // Get the handle (the 2nd argument) ++ __ mv(oop_handle_reg, c_rarg1); ++ ++ // Get address of the box ++ __ la(lock_reg, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); ++ ++ // Load the oop from the handle ++ __ ld(obj_reg, Address(oop_handle_reg, 0)); ++ ++ if (UseBiasedLocking) { ++ __ biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp, false, lock_done, &slow_path_lock); ++ } ++ ++ // Load (object->mark() | 1) into swap_reg % x10 ++ __ ld(t0, Address(obj_reg, oopDesc::mark_offset_in_bytes())); ++ __ ori(swap_reg, t0, 1); ++ ++ // Save (object->mark() | 1) into BasicLock's displaced header ++ __ sd(swap_reg, Address(lock_reg, mark_word_offset)); ++ ++ // src -> dest if dest == x10 else x10 <- dest ++ { ++ Label here; ++ __ cmpxchg_obj_header(x10, lock_reg, obj_reg, t0, lock_done, /*fallthrough*/NULL); ++ } ++ ++ // Test if the oopMark is an obvious stack pointer, i.e., ++ // 1) (mark & 3) == 0, and ++ // 2) sp <= mark < mark + os::pagesize() ++ // These 3 tests can be done by evaluating the following ++ // expression: ((mark - sp) & (3 - os::vm_page_size())), ++ // assuming both stack pointer and pagesize have their ++ // least significant 2 bits clear. ++ // NOTE: the oopMark is in swap_reg % 10 as the result of cmpxchg ++ ++ __ sub(swap_reg, swap_reg, sp); ++ __ andi(swap_reg, swap_reg, 3 - os::vm_page_size()); ++ ++ // Save the test result, for recursive case, the result is zero ++ __ sd(swap_reg, Address(lock_reg, mark_word_offset)); ++ __ bnez(swap_reg, slow_path_lock); ++ ++ // Slow path will re-enter here ++ __ bind(lock_done); ++ } ++ ++ ++ // Finally just about ready to make the JNI call ++ ++ // get JNIEnv* which is first argument to native ++ if (!is_critical_native) { ++ __ la(c_rarg0, Address(xthread, in_bytes(JavaThread::jni_environment_offset()))); ++ ++ // Now set thread in native ++ __ la(t1, Address(xthread, JavaThread::thread_state_offset())); ++ __ mv(t0, _thread_in_native); ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ __ sw(t0, Address(t1)); ++ } ++ ++ rt_call(masm, native_func); ++ ++ __ bind(native_return); ++ ++ intptr_t return_pc = (intptr_t) __ pc(); ++ oop_maps->add_gc_map(return_pc - start, map); ++ ++ // Unpack native results. ++ if (ret_type != T_OBJECT && ret_type != T_ARRAY) { ++ __ cast_primitive_type(ret_type, x10); ++ } ++ ++ Label safepoint_in_progress, safepoint_in_progress_done; ++ Label after_transition; ++ ++ // If this is a critical native, check for a safepoint or suspend request after the call. ++ // If a safepoint is needed, transition to native, then to native_trans to handle ++ // safepoint like the native methods that are not critical natives. ++ if (is_critical_native) { ++ Label needs_safepoint; ++ __ safepoint_poll(needs_safepoint, false /* as_return */, true /* acquire */, false /* in_nmethod */); ++ __ lwu(t0, Address(xthread, JavaThread::suspend_flags_offset())); ++ __ bnez(t0, needs_safepoint); ++ __ j(after_transition); ++ __ bind(needs_safepoint); ++ } ++ ++ // Switch thread to "native transition" state before reading the synchronization state. ++ // This additional state is necessary because reading and testing the synchronization ++ // state is not atomic w.r.t. GC, as this scenario demonstrates: ++ // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted. ++ // VM thread changes sync state to synchronizing and suspends threads for GC. ++ // Thread A is resumed to finish this native method, but doesn't block here since it ++ // didn't see any synchronization is progress, and escapes. ++ __ mv(t0, _thread_in_native_trans); ++ ++ __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); ++ ++ // Force this write out before the read below ++ __ membar(MacroAssembler::AnyAny); ++ ++ // check for safepoint operation in progress and/or pending suspend requests ++ { ++ // We need an acquire here to ensure that any subsequent load of the ++ // global SafepointSynchronize::_state flag is ordered after this load ++ // of the thread-local polling word. We don't want this poll to ++ // return false (i.e. not safepointing) and a later poll of the global ++ // SafepointSynchronize::_state spuriously to return true. ++ // This is to avoid a race when we're in a native->Java transition ++ // racing the code which wakes up from a safepoint. ++ ++ __ safepoint_poll(safepoint_in_progress, true /* at_return */, true /* acquire */, false /* in_nmethod */); ++ __ lwu(t0, Address(xthread, JavaThread::suspend_flags_offset())); ++ __ bnez(t0, safepoint_in_progress); ++ __ bind(safepoint_in_progress_done); ++ } ++ ++ // change thread state ++ __ la(t1, Address(xthread, JavaThread::thread_state_offset())); ++ __ mv(t0, _thread_in_Java); ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ __ sw(t0, Address(t1)); ++ __ bind(after_transition); ++ ++ Label reguard; ++ Label reguard_done; ++ __ lbu(t0, Address(xthread, JavaThread::stack_guard_state_offset())); ++ __ mv(t1, StackOverflow::stack_guard_yellow_reserved_disabled); ++ __ beq(t0, t1, reguard); ++ __ bind(reguard_done); ++ ++ // native result if any is live ++ ++ // Unlock ++ Label unlock_done; ++ Label slow_path_unlock; ++ if (method->is_synchronized()) { ++ ++ // Get locked oop from the handle we passed to jni ++ __ ld(obj_reg, Address(oop_handle_reg, 0)); ++ ++ Label done; ++ ++ if (UseBiasedLocking) { ++ __ biased_locking_exit(obj_reg, old_hdr, done); ++ } ++ ++ // Simple recursive lock? ++ __ ld(t0, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); ++ __ beqz(t0, done); ++ ++ // Must save x10 if it is live now because cmpxchg must use it ++ if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { ++ save_native_result(masm, ret_type, stack_slots); ++ } ++ ++ // get address of the stack lock ++ __ la(x10, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); ++ // get old displaced header ++ __ ld(old_hdr, Address(x10, 0)); ++ ++ // Atomic swap old header if oop still contains the stack lock ++ Label succeed; ++ __ cmpxchg_obj_header(x10, old_hdr, obj_reg, t0, succeed, &slow_path_unlock); ++ __ bind(succeed); ++ ++ // slow path re-enters here ++ __ bind(unlock_done); ++ if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { ++ restore_native_result(masm, ret_type, stack_slots); ++ } ++ ++ __ bind(done); ++ } ++ ++ Label dtrace_method_exit, dtrace_method_exit_done; ++ { ++ ExternalAddress target((address)&DTraceMethodProbes); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ lbu(t0, Address(t0, offset)); ++ }); ++ __ bnez(t0, dtrace_method_exit); ++ __ bind(dtrace_method_exit_done); ++ } ++ ++ __ reset_last_Java_frame(false); ++ ++ // Unbox oop result, e.g. JNIHandles::resolve result. ++ if (is_reference_type(ret_type)) { ++ __ resolve_jobject(x10, xthread, t1); ++ } ++ ++ if (CheckJNICalls) { ++ // clear_pending_jni_exception_check ++ __ sd(zr, Address(xthread, JavaThread::pending_jni_exception_check_fn_offset())); ++ } ++ ++ if (!is_critical_native) { ++ // reset handle block ++ __ ld(x12, Address(xthread, JavaThread::active_handles_offset())); ++ __ sd(zr, Address(x12, JNIHandleBlock::top_offset_in_bytes())); ++ } ++ ++ __ leave(); ++ ++ if (!is_critical_native) { ++ // Any exception pending? ++ __ ld(t0, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ __ bnez(t0, exception_pending); ++ } ++ ++ // We're done ++ __ ret(); ++ ++ // Unexpected paths are out of line and go here ++ ++ if (!is_critical_native) { ++ // forward the exception ++ __ bind(exception_pending); ++ ++ // and forward the exception ++ __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); ++ } ++ ++ // Slow path locking & unlocking ++ if (method->is_synchronized()) { ++ ++ __ block_comment("Slow path lock {"); ++ __ bind(slow_path_lock); ++ ++ // has last_Java_frame setup. No exceptions so do vanilla call not call_VM ++ // args are (oop obj, BasicLock* lock, JavaThread* thread) ++ ++ // protect the args we've loaded ++ save_args(masm, total_c_args, c_arg, out_regs); ++ ++ __ mv(c_rarg0, obj_reg); ++ __ mv(c_rarg1, lock_reg); ++ __ mv(c_rarg2, xthread); ++ ++ // Not a leaf but we have last_Java_frame setup as we want ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), 3); ++ restore_args(masm, total_c_args, c_arg, out_regs); ++ ++#ifdef ASSERT ++ { Label L; ++ __ ld(t0, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ __ beqz(t0, L); ++ __ stop("no pending exception allowed on exit from monitorenter"); ++ __ bind(L); ++ } ++#endif ++ __ j(lock_done); ++ ++ __ block_comment("} Slow path lock"); ++ ++ __ block_comment("Slow path unlock {"); ++ __ bind(slow_path_unlock); ++ ++ if (ret_type == T_FLOAT || ret_type == T_DOUBLE) { ++ save_native_result(masm, ret_type, stack_slots); ++ } ++ ++ __ mv(c_rarg2, xthread); ++ __ la(c_rarg1, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); ++ __ mv(c_rarg0, obj_reg); ++ ++ // Save pending exception around call to VM (which contains an EXCEPTION_MARK) ++ // NOTE that obj_reg == x9 currently ++ __ ld(x9, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ __ sd(zr, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ ++ rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C)); ++ ++#ifdef ASSERT ++ { ++ Label L; ++ __ ld(t0, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ __ beqz(t0, L); ++ __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); ++ __ bind(L); ++ } ++#endif /* ASSERT */ ++ ++ __ sd(x9, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ ++ if (ret_type == T_FLOAT || ret_type == T_DOUBLE) { ++ restore_native_result(masm, ret_type, stack_slots); ++ } ++ __ j(unlock_done); ++ ++ __ block_comment("} Slow path unlock"); ++ ++ } // synchronized ++ ++ // SLOW PATH Reguard the stack if needed ++ ++ __ bind(reguard); ++ save_native_result(masm, ret_type, stack_slots); ++ rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); ++ restore_native_result(masm, ret_type, stack_slots); ++ // and continue ++ __ j(reguard_done); ++ ++ // SLOW PATH safepoint ++ { ++ __ block_comment("safepoint {"); ++ __ bind(safepoint_in_progress); ++ ++ // Don't use call_VM as it will see a possible pending exception and forward it ++ // and never return here preventing us from clearing _last_native_pc down below. ++ // ++ save_native_result(masm, ret_type, stack_slots); ++ __ mv(c_rarg0, xthread); ++#ifndef PRODUCT ++ assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); ++#endif ++ RuntimeAddress target(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ ++ // Restore any method result value ++ restore_native_result(masm, ret_type, stack_slots); ++ ++ __ j(safepoint_in_progress_done); ++ __ block_comment("} safepoint"); ++ } ++ ++ // SLOW PATH dtrace support ++ { ++ __ block_comment("dtrace entry {"); ++ __ bind(dtrace_method_entry); ++ ++ // We have all of the arguments setup at this point. We must not touch any register ++ // argument registers at this point (what if we save/restore them there are no oop? ++ ++ save_args(masm, total_c_args, c_arg, out_regs); ++ __ mov_metadata(c_rarg1, method()); ++ __ call_VM_leaf( ++ CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), ++ xthread, c_rarg1); ++ restore_args(masm, total_c_args, c_arg, out_regs); ++ __ j(dtrace_method_entry_done); ++ __ block_comment("} dtrace entry"); ++ } ++ ++ { ++ __ block_comment("dtrace exit {"); ++ __ bind(dtrace_method_exit); ++ save_native_result(masm, ret_type, stack_slots); ++ __ mov_metadata(c_rarg1, method()); ++ __ call_VM_leaf( ++ CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), ++ xthread, c_rarg1); ++ restore_native_result(masm, ret_type, stack_slots); ++ __ j(dtrace_method_exit_done); ++ __ block_comment("} dtrace exit"); ++ } ++ ++ __ flush(); ++ ++ nmethod *nm = nmethod::new_native_nmethod(method, ++ compile_id, ++ masm->code(), ++ vep_offset, ++ frame_complete, ++ stack_slots / VMRegImpl::slots_per_word, ++ (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), ++ in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), ++ oop_maps); ++ assert(nm != NULL, "create native nmethod fail!"); ++ return nm; ++} ++ ++// this function returns the adjust size (in number of words) to a c2i adapter ++// activation for use during deoptimization ++int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) { ++ assert(callee_locals >= callee_parameters, ++ "test and remove; got more parms than locals"); ++ if (callee_locals < callee_parameters) { ++ return 0; // No adjustment for negative locals ++ } ++ int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords; ++ // diff is counted in stack words ++ return align_up(diff, 2); ++} ++ ++//------------------------------generate_deopt_blob---------------------------- ++void SharedRuntime::generate_deopt_blob() { ++ // Allocate space for the code ++ ResourceMark rm; ++ // Setup code generation tools ++ int pad = 0; ++ CodeBuffer buffer("deopt_blob", 2048 + pad, 1024); ++ MacroAssembler* masm = new MacroAssembler(&buffer); ++ int frame_size_in_words = -1; ++ OopMap* map = NULL; ++ OopMapSet *oop_maps = new OopMapSet(); ++ assert_cond(masm != NULL && oop_maps != NULL); ++ RegisterSaver reg_saver(COMPILER2_OR_JVMCI != 0); ++ ++ // ------------- ++ // This code enters when returning to a de-optimized nmethod. A return ++ // address has been pushed on the the stack, and return values are in ++ // registers. ++ // If we are doing a normal deopt then we were called from the patched ++ // nmethod from the point we returned to the nmethod. So the return ++ // address on the stack is wrong by NativeCall::instruction_size ++ // We will adjust the value so it looks like we have the original return ++ // address on the stack (like when we eagerly deoptimized). ++ // In the case of an exception pending when deoptimizing, we enter ++ // with a return address on the stack that points after the call we patched ++ // into the exception handler. We have the following register state from, ++ // e.g., the forward exception stub (see stubGenerator_riscv.cpp). ++ // x10: exception oop ++ // x9: exception handler ++ // x13: throwing pc ++ // So in this case we simply jam x13 into the useless return address and ++ // the stack looks just like we want. ++ // ++ // At this point we need to de-opt. We save the argument return ++ // registers. We call the first C routine, fetch_unroll_info(). This ++ // routine captures the return values and returns a structure which ++ // describes the current frame size and the sizes of all replacement frames. ++ // The current frame is compiled code and may contain many inlined ++ // functions, each with their own JVM state. We pop the current frame, then ++ // push all the new frames. Then we call the C routine unpack_frames() to ++ // populate these frames. Finally unpack_frames() returns us the new target ++ // address. Notice that callee-save registers are BLOWN here; they have ++ // already been captured in the vframeArray at the time the return PC was ++ // patched. ++ address start = __ pc(); ++ Label cont; ++ ++ // Prolog for non exception case! ++ ++ // Save everything in sight. ++ map = reg_saver.save_live_registers(masm, 0, &frame_size_in_words); ++ ++ // Normal deoptimization. Save exec mode for unpack_frames. ++ __ mv(xcpool, Deoptimization::Unpack_deopt); // callee-saved ++ __ j(cont); ++ ++ int reexecute_offset = __ pc() - start; ++ ++ // Reexecute case ++ // return address is the pc describes what bci to do re-execute at ++ ++ // No need to update map as each call to save_live_registers will produce identical oopmap ++ (void) reg_saver.save_live_registers(masm, 0, &frame_size_in_words); ++ ++ __ mv(xcpool, Deoptimization::Unpack_reexecute); // callee-saved ++ __ j(cont); ++ ++ int exception_offset = __ pc() - start; ++ ++ // Prolog for exception case ++ ++ // all registers are dead at this entry point, except for x10, and ++ // x13 which contain the exception oop and exception pc ++ // respectively. Set them in TLS and fall thru to the ++ // unpack_with_exception_in_tls entry point. ++ ++ __ sd(x13, Address(xthread, JavaThread::exception_pc_offset())); ++ __ sd(x10, Address(xthread, JavaThread::exception_oop_offset())); ++ ++ int exception_in_tls_offset = __ pc() - start; ++ ++ // new implementation because exception oop is now passed in JavaThread ++ ++ // Prolog for exception case ++ // All registers must be preserved because they might be used by LinearScan ++ // Exceptiop oop and throwing PC are passed in JavaThread ++ // tos: stack at point of call to method that threw the exception (i.e. only ++ // args are on the stack, no return address) ++ ++ // The return address pushed by save_live_registers will be patched ++ // later with the throwing pc. The correct value is not available ++ // now because loading it from memory would destroy registers. ++ ++ // NB: The SP at this point must be the SP of the method that is ++ // being deoptimized. Deoptimization assumes that the frame created ++ // here by save_live_registers is immediately below the method's SP. ++ // This is a somewhat fragile mechanism. ++ ++ // Save everything in sight. ++ map = reg_saver.save_live_registers(masm, 0, &frame_size_in_words); ++ ++ // Now it is safe to overwrite any register ++ ++ // Deopt during an exception. Save exec mode for unpack_frames. ++ __ mv(xcpool, Deoptimization::Unpack_exception); // callee-saved ++ ++ // load throwing pc from JavaThread and patch it as the return address ++ // of the current frame. Then clear the field in JavaThread ++ ++ __ ld(x13, Address(xthread, JavaThread::exception_pc_offset())); ++ __ sd(x13, Address(fp, frame::return_addr_offset * wordSize)); ++ __ sd(zr, Address(xthread, JavaThread::exception_pc_offset())); ++ ++#ifdef ASSERT ++ // verify that there is really an exception oop in JavaThread ++ __ ld(x10, Address(xthread, JavaThread::exception_oop_offset())); ++ __ verify_oop(x10); ++ ++ // verify that there is no pending exception ++ Label no_pending_exception; ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ beqz(t0, no_pending_exception); ++ __ stop("must not have pending exception here"); ++ __ bind(no_pending_exception); ++#endif ++ ++ __ bind(cont); ++ ++ // Call C code. Need thread and this frame, but NOT official VM entry ++ // crud. We cannot block on this call, no GC can happen. ++ // ++ // UnrollBlock* fetch_unroll_info(JavaThread* thread) ++ ++ // fetch_unroll_info needs to call last_java_frame(). ++ ++ Label retaddr; ++ __ set_last_Java_frame(sp, noreg, retaddr, t0); ++#ifdef ASSERT ++ { ++ Label L; ++ __ ld(t0, Address(xthread, ++ JavaThread::last_Java_fp_offset())); ++ __ beqz(t0, L); ++ __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared"); ++ __ bind(L); ++ } ++#endif // ASSERT ++ __ mv(c_rarg0, xthread); ++ __ mv(c_rarg1, xcpool); ++ RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ __ bind(retaddr); ++ ++ // Need to have an oopmap that tells fetch_unroll_info where to ++ // find any register it might need. ++ oop_maps->add_gc_map(__ pc() - start, map); ++ ++ __ reset_last_Java_frame(false); ++ ++ // Load UnrollBlock* into x15 ++ __ mv(x15, x10); ++ ++ __ lwu(xcpool, Address(x15, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes())); ++ Label noException; ++ __ mv(t0, Deoptimization::Unpack_exception); ++ __ bne(xcpool, t0, noException); // Was exception pending? ++ __ ld(x10, Address(xthread, JavaThread::exception_oop_offset())); ++ __ ld(x13, Address(xthread, JavaThread::exception_pc_offset())); ++ __ sd(zr, Address(xthread, JavaThread::exception_oop_offset())); ++ __ sd(zr, Address(xthread, JavaThread::exception_pc_offset())); ++ ++ __ verify_oop(x10); ++ ++ // Overwrite the result registers with the exception results. ++ __ sd(x10, Address(sp, reg_saver.reg_offset_in_bytes(x10))); ++ ++ __ bind(noException); ++ ++ // Only register save data is on the stack. ++ // Now restore the result registers. Everything else is either dead ++ // or captured in the vframeArray. ++ ++ // Restore fp result register ++ __ fld(f10, Address(sp, reg_saver.freg_offset_in_bytes(f10))); ++ // Restore integer result register ++ __ ld(x10, Address(sp, reg_saver.reg_offset_in_bytes(x10))); ++ ++ // Pop all of the register save area off the stack ++ __ add(sp, sp, frame_size_in_words * wordSize); ++ ++ // All of the register save area has been popped of the stack. Only the ++ // return address remains. ++ ++ // Pop all the frames we must move/replace. ++ // ++ // Frame picture (youngest to oldest) ++ // 1: self-frame (no frame link) ++ // 2: deopting frame (no frame link) ++ // 3: caller of deopting frame (could be compiled/interpreted). ++ // ++ // Note: by leaving the return address of self-frame on the stack ++ // and using the size of frame 2 to adjust the stack ++ // when we are done the return to frame 3 will still be on the stack. ++ ++ // Pop deoptimized frame ++ __ lwu(x12, Address(x15, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); ++ __ sub(x12, x12, 2 * wordSize); ++ __ add(sp, sp, x12); ++ __ ld(fp, Address(sp, 0)); ++ __ ld(ra, Address(sp, wordSize)); ++ __ addi(sp, sp, 2 * wordSize); ++ // RA should now be the return address to the caller (3) ++ ++#ifdef ASSERT ++ // Compilers generate code that bang the stack by as much as the ++ // interpreter would need. So this stack banging should never ++ // trigger a fault. Verify that it does not on non product builds. ++ __ lwu(x9, Address(x15, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); ++ __ bang_stack_size(x9, x12); ++#endif ++ // Load address of array of frame pcs into x12 ++ __ ld(x12, Address(x15, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); ++ ++ // Load address of array of frame sizes into x14 ++ __ ld(x14, Address(x15, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); ++ ++ // Load counter into x13 ++ __ lwu(x13, Address(x15, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes())); ++ ++ // Now adjust the caller's stack to make up for the extra locals ++ // but record the original sp so that we can save it in the skeletal interpreter ++ // frame and the stack walking of interpreter_sender will get the unextended sp ++ // value and not the "real" sp value. ++ ++ const Register sender_sp = x16; ++ ++ __ mv(sender_sp, sp); ++ __ lwu(x9, Address(x15, ++ Deoptimization::UnrollBlock:: ++ caller_adjustment_offset_in_bytes())); ++ __ sub(sp, sp, x9); ++ ++ // Push interpreter frames in a loop ++ __ mv(t0, 0xDEADDEAD); // Make a recognizable pattern ++ __ mv(t1, t0); ++ Label loop; ++ __ bind(loop); ++ __ ld(x9, Address(x14, 0)); // Load frame size ++ __ addi(x14, x14, wordSize); ++ __ sub(x9, x9, 2 * wordSize); // We'll push pc and fp by hand ++ __ ld(ra, Address(x12, 0)); // Load pc ++ __ addi(x12, x12, wordSize); ++ __ enter(); // Save old & set new fp ++ __ sub(sp, sp, x9); // Prolog ++ // This value is corrected by layout_activation_impl ++ __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ __ sd(sender_sp, Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize)); // Make it walkable ++ __ mv(sender_sp, sp); // Pass sender_sp to next frame ++ __ addi(x13, x13, -1); // Decrement counter ++ __ bnez(x13, loop); ++ ++ // Re-push self-frame ++ __ ld(ra, Address(x12)); ++ __ enter(); ++ ++ // Allocate a full sized register save area. We subtract 2 because ++ // enter() just pushed 2 words ++ __ sub(sp, sp, (frame_size_in_words - 2) * wordSize); ++ ++ // Restore frame locals after moving the frame ++ __ fsd(f10, Address(sp, reg_saver.freg_offset_in_bytes(f10))); ++ __ sd(x10, Address(sp, reg_saver.reg_offset_in_bytes(x10))); ++ ++ // Call C code. Need thread but NOT official VM entry ++ // crud. We cannot block on this call, no GC can happen. Call should ++ // restore return values to their stack-slots with the new SP. ++ // ++ // void Deoptimization::unpack_frames(JavaThread* thread, int exec_mode) ++ ++ // Use fp because the frames look interpreted now ++ // Don't need the precise return PC here, just precise enough to point into this code blob. ++ address the_pc = __ pc(); ++ __ set_last_Java_frame(sp, fp, the_pc, t0); ++ ++ __ mv(c_rarg0, xthread); ++ __ mv(c_rarg1, xcpool); // second arg: exec_mode ++ target = RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ ++ // Set an oopmap for the call site ++ // Use the same PC we used for the last java frame ++ oop_maps->add_gc_map(the_pc - start, ++ new OopMap(frame_size_in_words, 0)); ++ ++ // Clear fp AND pc ++ __ reset_last_Java_frame(true); ++ ++ // Collect return values ++ __ fld(f10, Address(sp, reg_saver.freg_offset_in_bytes(f10))); ++ __ ld(x10, Address(sp, reg_saver.reg_offset_in_bytes(x10))); ++ ++ // Pop self-frame. ++ __ leave(); // Epilog ++ ++ // Jump to interpreter ++ __ ret(); ++ ++ // Make sure all code is generated ++ masm->flush(); ++ ++ _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); ++ assert(_deopt_blob != NULL, "create deoptimization blob fail!"); ++ _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); ++} ++ ++// Number of stack slots between incoming argument block and the start of ++// a new frame. The PROLOG must add this many slots to the stack. The ++// EPILOG must remove this many slots. ++// RISCV needs two words for RA (return address) and FP (frame pointer). ++uint SharedRuntime::in_preserve_stack_slots() { ++ return 2 * VMRegImpl::slots_per_word; ++} ++ ++uint SharedRuntime::out_preserve_stack_slots() { ++ return 0; ++} ++ ++#ifdef COMPILER2 ++//------------------------------generate_uncommon_trap_blob-------------------- ++void SharedRuntime::generate_uncommon_trap_blob() { ++ // Allocate space for the code ++ ResourceMark rm; ++ // Setup code generation tools ++ CodeBuffer buffer("uncommon_trap_blob", 2048, 1024); ++ MacroAssembler* masm = new MacroAssembler(&buffer); ++ assert_cond(masm != NULL); ++ ++ assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned"); ++ ++ address start = __ pc(); ++ ++ // Push self-frame. We get here with a return address in RA ++ // and sp should be 16 byte aligned ++ // push fp and retaddr by hand ++ __ addi(sp, sp, -2 * wordSize); ++ __ sd(ra, Address(sp, wordSize)); ++ __ sd(fp, Address(sp, 0)); ++ // we don't expect an arg reg save area ++#ifndef PRODUCT ++ assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); ++#endif ++ // compiler left unloaded_class_index in j_rarg0 move to where the ++ // runtime expects it. ++ __ sign_extend(c_rarg1, j_rarg0, 32); ++ ++ // we need to set the past SP to the stack pointer of the stub frame ++ // and the pc to the address where this runtime call will return ++ // although actually any pc in this code blob will do). ++ Label retaddr; ++ __ set_last_Java_frame(sp, noreg, retaddr, t0); ++ ++ // Call C code. Need thread but NOT official VM entry ++ // crud. We cannot block on this call, no GC can happen. Call should ++ // capture callee-saved registers as well as return values. ++ // ++ // UnrollBlock* uncommon_trap(JavaThread* thread, jint unloaded_class_index, jint exec_mode) ++ // ++ // n.b. 3 gp args, 0 fp args, integral return type ++ ++ __ mv(c_rarg0, xthread); ++ __ mv(c_rarg2, Deoptimization::Unpack_uncommon_trap); ++ RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ __ bind(retaddr); ++ ++ // Set an oopmap for the call site ++ OopMapSet* oop_maps = new OopMapSet(); ++ OopMap* map = new OopMap(SimpleRuntimeFrame::framesize, 0); ++ assert_cond(oop_maps != NULL && map != NULL); ++ ++ // location of fp is known implicitly by the frame sender code ++ ++ oop_maps->add_gc_map(__ pc() - start, map); ++ ++ __ reset_last_Java_frame(false); ++ ++ // move UnrollBlock* into x14 ++ __ mv(x14, x10); ++ ++#ifdef ASSERT ++ { Label L; ++ __ lwu(t0, Address(x14, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes())); ++ __ mv(t1, Deoptimization::Unpack_uncommon_trap); ++ __ beq(t0, t1, L); ++ __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared"); ++ __ bind(L); ++ } ++#endif ++ ++ // Pop all the frames we must move/replace. ++ // ++ // Frame picture (youngest to oldest) ++ // 1: self-frame (no frame link) ++ // 2: deopting frame (no frame link) ++ // 3: caller of deopting frame (could be compiled/interpreted). ++ ++ __ add(sp, sp, (SimpleRuntimeFrame::framesize) << LogBytesPerInt); // Epilog! ++ ++ // Pop deoptimized frame (int) ++ __ lwu(x12, Address(x14, ++ Deoptimization::UnrollBlock:: ++ size_of_deoptimized_frame_offset_in_bytes())); ++ __ sub(x12, x12, 2 * wordSize); ++ __ add(sp, sp, x12); ++ __ ld(fp, Address(sp, 0)); ++ __ ld(ra, Address(sp, wordSize)); ++ __ addi(sp, sp, 2 * wordSize); ++ // RA should now be the return address to the caller (3) frame ++ ++#ifdef ASSERT ++ // Compilers generate code that bang the stack by as much as the ++ // interpreter would need. So this stack banging should never ++ // trigger a fault. Verify that it does not on non product builds. ++ __ lwu(x11, Address(x14, ++ Deoptimization::UnrollBlock:: ++ total_frame_sizes_offset_in_bytes())); ++ __ bang_stack_size(x11, x12); ++#endif ++ ++ // Load address of array of frame pcs into x12 (address*) ++ __ ld(x12, Address(x14, ++ Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); ++ ++ // Load address of array of frame sizes into x15 (intptr_t*) ++ __ ld(x15, Address(x14, ++ Deoptimization::UnrollBlock:: ++ frame_sizes_offset_in_bytes())); ++ ++ // Counter ++ __ lwu(x13, Address(x14, ++ Deoptimization::UnrollBlock:: ++ number_of_frames_offset_in_bytes())); // (int) ++ ++ // Now adjust the caller's stack to make up for the extra locals but ++ // record the original sp so that we can save it in the skeletal ++ // interpreter frame and the stack walking of interpreter_sender ++ // will get the unextended sp value and not the "real" sp value. ++ ++ const Register sender_sp = t1; // temporary register ++ ++ __ lwu(x11, Address(x14, ++ Deoptimization::UnrollBlock:: ++ caller_adjustment_offset_in_bytes())); // (int) ++ __ mv(sender_sp, sp); ++ __ sub(sp, sp, x11); ++ ++ // Push interpreter frames in a loop ++ Label loop; ++ __ bind(loop); ++ __ ld(x11, Address(x15, 0)); // Load frame size ++ __ sub(x11, x11, 2 * wordSize); // We'll push pc and fp by hand ++ __ ld(ra, Address(x12, 0)); // Save return address ++ __ enter(); // and old fp & set new fp ++ __ sub(sp, sp, x11); // Prolog ++ __ sd(sender_sp, Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize)); // Make it walkable ++ // This value is corrected by layout_activation_impl ++ __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ __ mv(sender_sp, sp); // Pass sender_sp to next frame ++ __ add(x15, x15, wordSize); // Bump array pointer (sizes) ++ __ add(x12, x12, wordSize); // Bump array pointer (pcs) ++ __ subw(x13, x13, 1); // Decrement counter ++ __ bgtz(x13, loop); ++ __ ld(ra, Address(x12, 0)); // save final return address ++ // Re-push self-frame ++ __ enter(); // & old fp & set new fp ++ ++ // Use fp because the frames look interpreted now ++ // Save "the_pc" since it cannot easily be retrieved using the last_java_SP after we aligned SP. ++ // Don't need the precise return PC here, just precise enough to point into this code blob. ++ address the_pc = __ pc(); ++ __ set_last_Java_frame(sp, fp, the_pc, t0); ++ ++ // Call C code. Need thread but NOT official VM entry ++ // crud. We cannot block on this call, no GC can happen. Call should ++ // restore return values to their stack-slots with the new SP. ++ // ++ // BasicType unpack_frames(JavaThread* thread, int exec_mode) ++ // ++ ++ // n.b. 2 gp args, 0 fp args, integral return type ++ ++ // sp should already be aligned ++ __ mv(c_rarg0, xthread); ++ __ mv(c_rarg1, Deoptimization::Unpack_uncommon_trap); ++ target = RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ ++ // Set an oopmap for the call site ++ // Use the same PC we used for the last java frame ++ oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0)); ++ ++ // Clear fp AND pc ++ __ reset_last_Java_frame(true); ++ ++ // Pop self-frame. ++ __ leave(); // Epilog ++ ++ // Jump to interpreter ++ __ ret(); ++ ++ // Make sure all code is generated ++ masm->flush(); ++ ++ _uncommon_trap_blob = UncommonTrapBlob::create(&buffer, oop_maps, ++ SimpleRuntimeFrame::framesize >> 1); ++} ++#endif // COMPILER2 ++ ++//------------------------------generate_handler_blob------ ++// ++// Generate a special Compile2Runtime blob that saves all registers, ++// and setup oopmap. ++// ++SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { ++ ResourceMark rm; ++ OopMapSet *oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ OopMap* map = NULL; ++ ++ // Allocate space for the code. Setup code generation tools. ++ CodeBuffer buffer("handler_blob", 2048, 1024); ++ MacroAssembler* masm = new MacroAssembler(&buffer); ++ assert_cond(masm != NULL); ++ ++ address start = __ pc(); ++ address call_pc = NULL; ++ int frame_size_in_words = -1; ++ bool cause_return = (poll_type == POLL_AT_RETURN); ++ RegisterSaver reg_saver(poll_type == POLL_AT_VECTOR_LOOP /* save_vectors */); ++ ++ // Save Integer and Float registers. ++ map = reg_saver.save_live_registers(masm, 0, &frame_size_in_words); ++ ++ // The following is basically a call_VM. However, we need the precise ++ // address of the call in order to generate an oopmap. Hence, we do all the ++ // work outselves. ++ ++ Label retaddr; ++ __ set_last_Java_frame(sp, noreg, retaddr, t0); ++ ++ // The return address must always be correct so that frame constructor never ++ // sees an invalid pc. ++ ++ if (!cause_return) { ++ // overwrite the return address pushed by save_live_registers ++ // Additionally, x18 is a callee-saved register so we can look at ++ // it later to determine if someone changed the return address for ++ // us! ++ __ ld(x18, Address(xthread, JavaThread::saved_exception_pc_offset())); ++ __ sd(x18, Address(fp, frame::return_addr_offset * wordSize)); ++ } ++ ++ // Do the call ++ __ mv(c_rarg0, xthread); ++ RuntimeAddress target(call_ptr); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ __ bind(retaddr); ++ ++ // Set an oopmap for the call site. This oopmap will map all ++ // oop-registers and debug-info registers as callee-saved. This ++ // will allow deoptimization at this safepoint to find all possible ++ // debug-info recordings, as well as let GC find all oops. ++ ++ oop_maps->add_gc_map( __ pc() - start, map); ++ ++ Label noException; ++ ++ __ reset_last_Java_frame(false); ++ ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ beqz(t0, noException); ++ ++ // Exception pending ++ ++ reg_saver.restore_live_registers(masm); ++ ++ __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); ++ ++ // No exception case ++ __ bind(noException); ++ ++ Label no_adjust, bail; ++ if (!cause_return) { ++ // If our stashed return pc was modified by the runtime we avoid touching it ++ __ ld(t0, Address(fp, frame::return_addr_offset * wordSize)); ++ __ bne(x18, t0, no_adjust); ++ ++#ifdef ASSERT ++ // Verify the correct encoding of the poll we're about to skip. ++ // See NativeInstruction::is_lwu_to_zr() ++ __ lwu(t0, Address(x18)); ++ __ andi(t1, t0, 0b0000011); ++ __ mv(t2, 0b0000011); ++ __ bne(t1, t2, bail); // 0-6:0b0000011 ++ __ srli(t1, t0, 7); ++ __ andi(t1, t1, 0b00000); ++ __ bnez(t1, bail); // 7-11:0b00000 ++ __ srli(t1, t0, 12); ++ __ andi(t1, t1, 0b110); ++ __ mv(t2, 0b110); ++ __ bne(t1, t2, bail); // 12-14:0b110 ++#endif ++ // Adjust return pc forward to step over the safepoint poll instruction ++ __ add(x18, x18, NativeInstruction::instruction_size); ++ __ sd(x18, Address(fp, frame::return_addr_offset * wordSize)); ++ } ++ ++ __ bind(no_adjust); ++ // Normal exit, restore registers and exit. ++ ++ reg_saver.restore_live_registers(masm); ++ __ ret(); ++ ++#ifdef ASSERT ++ __ bind(bail); ++ __ stop("Attempting to adjust pc to skip safepoint poll but the return point is not what we expected"); ++#endif ++ ++ // Make sure all code is generated ++ masm->flush(); ++ ++ // Fill-out other meta info ++ return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words); ++} ++ ++// ++// generate_resolve_blob - call resolution (static/virtual/opt-virtual/ic-miss ++// ++// Generate a stub that calls into vm to find out the proper destination ++// of a java call. All the argument registers are live at this point ++// but since this is generic code we don't know what they are and the caller ++// must do any gc of the args. ++// ++RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const char* name) { ++ assert(StubRoutines::forward_exception_entry() != NULL, "must be generated before"); ++ ++ // allocate space for the code ++ ResourceMark rm; ++ ++ CodeBuffer buffer(name, 1000, 512); ++ MacroAssembler* masm = new MacroAssembler(&buffer); ++ assert_cond(masm != NULL); ++ ++ int frame_size_in_words = -1; ++ RegisterSaver reg_saver(false /* save_vectors */); ++ ++ OopMapSet *oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ OopMap* map = NULL; ++ ++ int start = __ offset(); ++ ++ map = reg_saver.save_live_registers(masm, 0, &frame_size_in_words); ++ ++ int frame_complete = __ offset(); ++ ++ { ++ Label retaddr; ++ __ set_last_Java_frame(sp, noreg, retaddr, t0); ++ ++ __ mv(c_rarg0, xthread); ++ RuntimeAddress target(destination); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ __ bind(retaddr); ++ } ++ ++ // Set an oopmap for the call site. ++ // We need this not only for callee-saved registers, but also for volatile ++ // registers that the compiler might be keeping live across a safepoint. ++ ++ oop_maps->add_gc_map( __ offset() - start, map); ++ ++ // x10 contains the address we are going to jump to assuming no exception got installed ++ ++ // clear last_Java_sp ++ __ reset_last_Java_frame(false); ++ // check for pending exceptions ++ Label pending; ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ bnez(t0, pending); ++ ++ // get the returned Method* ++ __ get_vm_result_2(xmethod, xthread); ++ __ sd(xmethod, Address(sp, reg_saver.reg_offset_in_bytes(xmethod))); ++ ++ // x10 is where we want to jump, overwrite t0 which is saved and temporary ++ __ sd(x10, Address(sp, reg_saver.reg_offset_in_bytes(t0))); ++ reg_saver.restore_live_registers(masm); ++ ++ // We are back the the original state on entry and ready to go. ++ ++ __ jr(t0); ++ ++ // Pending exception after the safepoint ++ ++ __ bind(pending); ++ ++ reg_saver.restore_live_registers(masm); ++ ++ // exception pending => remove activation and forward to exception handler ++ ++ __ sd(zr, Address(xthread, JavaThread::vm_result_offset())); ++ ++ __ ld(x10, Address(xthread, Thread::pending_exception_offset())); ++ __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); ++ ++ // ------------- ++ // make sure all code is generated ++ masm->flush(); ++ ++ // return the blob ++ return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true); ++} ++ ++#ifdef COMPILER2 ++RuntimeStub* SharedRuntime::make_native_invoker(address call_target, ++ int shadow_space_bytes, ++ const GrowableArray& input_registers, ++ const GrowableArray& output_registers) { ++ Unimplemented(); ++ return nullptr; ++} ++ ++//------------------------------generate_exception_blob--------------------------- ++// creates exception blob at the end ++// Using exception blob, this code is jumped from a compiled method. ++// (see emit_exception_handler in riscv.ad file) ++// ++// Given an exception pc at a call we call into the runtime for the ++// handler in this method. This handler might merely restore state ++// (i.e. callee save registers) unwind the frame and jump to the ++// exception handler for the nmethod if there is no Java level handler ++// for the nmethod. ++// ++// This code is entered with a jmp. ++// ++// Arguments: ++// x10: exception oop ++// x13: exception pc ++// ++// Results: ++// x10: exception oop ++// x13: exception pc in caller ++// destination: exception handler of caller ++// ++// Note: the exception pc MUST be at a call (precise debug information) ++// Registers x10, x13, x12, x14, x15, t0 are not callee saved. ++// ++ ++void OptoRuntime::generate_exception_blob() { ++ assert(!OptoRuntime::is_callee_saved_register(R13_num), ""); ++ assert(!OptoRuntime::is_callee_saved_register(R10_num), ""); ++ assert(!OptoRuntime::is_callee_saved_register(R12_num), ""); ++ ++ assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned"); ++ ++ // Allocate space for the code ++ ResourceMark rm; ++ // Setup code generation tools ++ CodeBuffer buffer("exception_blob", 2048, 1024); ++ MacroAssembler* masm = new MacroAssembler(&buffer); ++ assert_cond(masm != NULL); ++ ++ // TODO check various assumptions made here ++ // ++ // make sure we do so before running this ++ ++ address start = __ pc(); ++ ++ // push fp and retaddr by hand ++ // Exception pc is 'return address' for stack walker ++ __ addi(sp, sp, -2 * wordSize); ++ __ sd(ra, Address(sp, wordSize)); ++ __ sd(fp, Address(sp)); ++ // there are no callee save registers and we don't expect an ++ // arg reg save area ++#ifndef PRODUCT ++ assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); ++#endif ++ // Store exception in Thread object. We cannot pass any arguments to the ++ // handle_exception call, since we do not want to make any assumption ++ // about the size of the frame where the exception happened in. ++ __ sd(x10, Address(xthread, JavaThread::exception_oop_offset())); ++ __ sd(x13, Address(xthread, JavaThread::exception_pc_offset())); ++ ++ // This call does all the hard work. It checks if an exception handler ++ // exists in the method. ++ // If so, it returns the handler address. ++ // If not, it prepares for stack-unwinding, restoring the callee-save ++ // registers of the frame being removed. ++ // ++ // address OptoRuntime::handle_exception_C(JavaThread* thread) ++ // ++ // n.b. 1 gp arg, 0 fp args, integral return type ++ ++ // the stack should always be aligned ++ address the_pc = __ pc(); ++ __ set_last_Java_frame(sp, noreg, the_pc, t0); ++ __ mv(c_rarg0, xthread); ++ RuntimeAddress target(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ jalr(x1, t0, offset); ++ }); ++ ++ ++ // handle_exception_C is a special VM call which does not require an explicit ++ // instruction sync afterwards. ++ ++ // Set an oopmap for the call site. This oopmap will only be used if we ++ // are unwinding the stack. Hence, all locations will be dead. ++ // Callee-saved registers will be the same as the frame above (i.e., ++ // handle_exception_stub), since they were restored when we got the ++ // exception. ++ ++ OopMapSet* oop_maps = new OopMapSet(); ++ assert_cond(oop_maps != NULL); ++ ++ oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0)); ++ ++ __ reset_last_Java_frame(false); ++ ++ // Restore callee-saved registers ++ ++ // fp is an implicitly saved callee saved register (i.e. the calling ++ // convention will save restore it in prolog/epilog) Other than that ++ // there are no callee save registers now that adapter frames are gone. ++ // and we dont' expect an arg reg save area ++ __ ld(fp, Address(sp)); ++ __ ld(x13, Address(sp, wordSize)); ++ __ addi(sp, sp , 2 * wordSize); ++ ++ // x10: exception handler ++ ++ // We have a handler in x10 (could be deopt blob). ++ __ mv(t0, x10); ++ ++ // Get the exception oop ++ __ ld(x10, Address(xthread, JavaThread::exception_oop_offset())); ++ // Get the exception pc in case we are deoptimized ++ __ ld(x14, Address(xthread, JavaThread::exception_pc_offset())); ++#ifdef ASSERT ++ __ sd(zr, Address(xthread, JavaThread::exception_handler_pc_offset())); ++ __ sd(zr, Address(xthread, JavaThread::exception_pc_offset())); ++#endif ++ // Clear the exception oop so GC no longer processes it as a root. ++ __ sd(zr, Address(xthread, JavaThread::exception_oop_offset())); ++ ++ // x10: exception oop ++ // t0: exception handler ++ // x14: exception pc ++ // Jump to handler ++ ++ __ jr(t0); ++ ++ // Make sure all code is generated ++ masm->flush(); ++ ++ // Set exception blob ++ _exception_blob = ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1); ++} ++#endif // COMPILER2 +--- /dev/null ++++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +@@ -0,0 +1,3959 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "compiler/oopMap.hpp" ++#include "gc/shared/barrierSet.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "interpreter/interpreter.hpp" ++#include "memory/universe.hpp" ++#include "nativeInst_riscv.hpp" ++#include "oops/instanceOop.hpp" ++#include "oops/method.hpp" ++#include "oops/objArrayKlass.hpp" ++#include "oops/oop.inline.hpp" ++#include "prims/methodHandles.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/handles.inline.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubCodeGenerator.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/thread.inline.hpp" ++#include "utilities/align.hpp" ++#include "utilities/powerOfTwo.hpp" ++#ifdef COMPILER2 ++#include "opto/runtime.hpp" ++#endif ++#if INCLUDE_ZGC ++#include "gc/z/zThreadLocalData.hpp" ++#endif ++ ++// Declaration and definition of StubGenerator (no .hpp file). ++// For a more detailed description of the stub routine structure ++// see the comment in stubRoutines.hpp ++ ++#undef __ ++#define __ _masm-> ++ ++#ifdef PRODUCT ++#define BLOCK_COMMENT(str) /* nothing */ ++#else ++#define BLOCK_COMMENT(str) __ block_comment(str) ++#endif ++ ++#define BIND(label) bind(label); BLOCK_COMMENT(#label ":") ++ ++// Stub Code definitions ++ ++class StubGenerator: public StubCodeGenerator { ++ private: ++ ++#ifdef PRODUCT ++#define inc_counter_np(counter) ((void)0) ++#else ++ void inc_counter_np_(int& counter) { ++ __ la(t1, ExternalAddress((address)&counter)); ++ __ lwu(t0, Address(t1, 0)); ++ __ addiw(t0, t0, 1); ++ __ sw(t0, Address(t1, 0)); ++ } ++#define inc_counter_np(counter) \ ++ BLOCK_COMMENT("inc_counter " #counter); \ ++ inc_counter_np_(counter); ++#endif ++ ++ // Call stubs are used to call Java from C ++ // ++ // Arguments: ++ // c_rarg0: call wrapper address address ++ // c_rarg1: result address ++ // c_rarg2: result type BasicType ++ // c_rarg3: method Method* ++ // c_rarg4: (interpreter) entry point address ++ // c_rarg5: parameters intptr_t* ++ // c_rarg6: parameter size (in words) int ++ // c_rarg7: thread Thread* ++ // ++ // There is no return from the stub itself as any Java result ++ // is written to result ++ // ++ // we save x1 (ra) as the return PC at the base of the frame and ++ // link x8 (fp) below it as the frame pointer installing sp (x2) ++ // into fp. ++ // ++ // we save x10-x17, which accounts for all the c arguments. ++ // ++ // TODO: strictly do we need to save them all? they are treated as ++ // volatile by C so could we omit saving the ones we are going to ++ // place in global registers (thread? method?) or those we only use ++ // during setup of the Java call? ++ // ++ // we don't need to save x5 which C uses as an indirect result location ++ // return register. ++ // ++ // we don't need to save x6-x7 and x28-x31 which both C and Java treat as ++ // volatile ++ // ++ // we save x9, x18-x27, f8-f9, and f18-f27 which Java uses as temporary ++ // registers and C expects to be callee-save ++ // ++ // so the stub frame looks like this when we enter Java code ++ // ++ // [ return_from_Java ] <--- sp ++ // [ argument word n ] ++ // ... ++ // -34 [ argument word 1 ] ++ // -33 [ saved f27 ] <--- sp_after_call ++ // -32 [ saved f26 ] ++ // -31 [ saved f25 ] ++ // -30 [ saved f24 ] ++ // -29 [ saved f23 ] ++ // -28 [ saved f22 ] ++ // -27 [ saved f21 ] ++ // -26 [ saved f20 ] ++ // -25 [ saved f19 ] ++ // -24 [ saved f18 ] ++ // -23 [ saved f9 ] ++ // -22 [ saved f8 ] ++ // -21 [ saved x27 ] ++ // -20 [ saved x26 ] ++ // -19 [ saved x25 ] ++ // -18 [ saved x24 ] ++ // -17 [ saved x23 ] ++ // -16 [ saved x22 ] ++ // -15 [ saved x21 ] ++ // -14 [ saved x20 ] ++ // -13 [ saved x19 ] ++ // -12 [ saved x18 ] ++ // -11 [ saved x9 ] ++ // -10 [ call wrapper (x10) ] ++ // -9 [ result (x11) ] ++ // -8 [ result type (x12) ] ++ // -7 [ method (x13) ] ++ // -6 [ entry point (x14) ] ++ // -5 [ parameters (x15) ] ++ // -4 [ parameter size (x16) ] ++ // -3 [ thread (x17) ] ++ // -2 [ saved fp (x8) ] ++ // -1 [ saved ra (x1) ] ++ // 0 [ ] <--- fp == saved sp (x2) ++ ++ // Call stub stack layout word offsets from fp ++ enum call_stub_layout { ++ sp_after_call_off = -33, ++ ++ f27_off = -33, ++ f26_off = -32, ++ f25_off = -31, ++ f24_off = -30, ++ f23_off = -29, ++ f22_off = -28, ++ f21_off = -27, ++ f20_off = -26, ++ f19_off = -25, ++ f18_off = -24, ++ f9_off = -23, ++ f8_off = -22, ++ ++ x27_off = -21, ++ x26_off = -20, ++ x25_off = -19, ++ x24_off = -18, ++ x23_off = -17, ++ x22_off = -16, ++ x21_off = -15, ++ x20_off = -14, ++ x19_off = -13, ++ x18_off = -12, ++ x9_off = -11, ++ ++ call_wrapper_off = -10, ++ result_off = -9, ++ result_type_off = -8, ++ method_off = -7, ++ entry_point_off = -6, ++ parameters_off = -5, ++ parameter_size_off = -4, ++ thread_off = -3, ++ fp_f = -2, ++ retaddr_off = -1, ++ }; ++ ++ address generate_call_stub(address& return_address) { ++ assert((int)frame::entry_frame_after_call_words == -(int)sp_after_call_off + 1 && ++ (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off, ++ "adjust this code"); ++ ++ StubCodeMark mark(this, "StubRoutines", "call_stub"); ++ address start = __ pc(); ++ ++ const Address sp_after_call (fp, sp_after_call_off * wordSize); ++ ++ const Address call_wrapper (fp, call_wrapper_off * wordSize); ++ const Address result (fp, result_off * wordSize); ++ const Address result_type (fp, result_type_off * wordSize); ++ const Address method (fp, method_off * wordSize); ++ const Address entry_point (fp, entry_point_off * wordSize); ++ const Address parameters (fp, parameters_off * wordSize); ++ const Address parameter_size(fp, parameter_size_off * wordSize); ++ ++ const Address thread (fp, thread_off * wordSize); ++ ++ const Address f27_save (fp, f27_off * wordSize); ++ const Address f26_save (fp, f26_off * wordSize); ++ const Address f25_save (fp, f25_off * wordSize); ++ const Address f24_save (fp, f24_off * wordSize); ++ const Address f23_save (fp, f23_off * wordSize); ++ const Address f22_save (fp, f22_off * wordSize); ++ const Address f21_save (fp, f21_off * wordSize); ++ const Address f20_save (fp, f20_off * wordSize); ++ const Address f19_save (fp, f19_off * wordSize); ++ const Address f18_save (fp, f18_off * wordSize); ++ const Address f9_save (fp, f9_off * wordSize); ++ const Address f8_save (fp, f8_off * wordSize); ++ ++ const Address x27_save (fp, x27_off * wordSize); ++ const Address x26_save (fp, x26_off * wordSize); ++ const Address x25_save (fp, x25_off * wordSize); ++ const Address x24_save (fp, x24_off * wordSize); ++ const Address x23_save (fp, x23_off * wordSize); ++ const Address x22_save (fp, x22_off * wordSize); ++ const Address x21_save (fp, x21_off * wordSize); ++ const Address x20_save (fp, x20_off * wordSize); ++ const Address x19_save (fp, x19_off * wordSize); ++ const Address x18_save (fp, x18_off * wordSize); ++ ++ const Address x9_save (fp, x9_off * wordSize); ++ ++ // stub code ++ ++ address riscv_entry = __ pc(); ++ ++ // set up frame and move sp to end of save area ++ __ enter(); ++ __ addi(sp, fp, sp_after_call_off * wordSize); ++ ++ // save register parameters and Java temporary/global registers ++ // n.b. we save thread even though it gets installed in ++ // xthread because we want to sanity check tp later ++ __ sd(c_rarg7, thread); ++ __ sw(c_rarg6, parameter_size); ++ __ sd(c_rarg5, parameters); ++ __ sd(c_rarg4, entry_point); ++ __ sd(c_rarg3, method); ++ __ sd(c_rarg2, result_type); ++ __ sd(c_rarg1, result); ++ __ sd(c_rarg0, call_wrapper); ++ ++ __ sd(x9, x9_save); ++ ++ __ sd(x18, x18_save); ++ __ sd(x19, x19_save); ++ __ sd(x20, x20_save); ++ __ sd(x21, x21_save); ++ __ sd(x22, x22_save); ++ __ sd(x23, x23_save); ++ __ sd(x24, x24_save); ++ __ sd(x25, x25_save); ++ __ sd(x26, x26_save); ++ __ sd(x27, x27_save); ++ ++ __ fsd(f8, f8_save); ++ __ fsd(f9, f9_save); ++ __ fsd(f18, f18_save); ++ __ fsd(f19, f19_save); ++ __ fsd(f20, f20_save); ++ __ fsd(f21, f21_save); ++ __ fsd(f22, f22_save); ++ __ fsd(f23, f23_save); ++ __ fsd(f24, f24_save); ++ __ fsd(f25, f25_save); ++ __ fsd(f26, f26_save); ++ __ fsd(f27, f27_save); ++ ++ // install Java thread in global register now we have saved ++ // whatever value it held ++ __ mv(xthread, c_rarg7); ++ ++ // And method ++ __ mv(xmethod, c_rarg3); ++ ++ // set up the heapbase register ++ __ reinit_heapbase(); ++ ++#ifdef ASSERT ++ // make sure we have no pending exceptions ++ { ++ Label L; ++ __ ld(t0, Address(xthread, in_bytes(Thread::pending_exception_offset()))); ++ __ beqz(t0, L); ++ __ stop("StubRoutines::call_stub: entered with pending exception"); ++ __ BIND(L); ++ } ++#endif ++ // pass parameters if any ++ __ mv(esp, sp); ++ __ slli(t0, c_rarg6, LogBytesPerWord); ++ __ sub(t0, sp, t0); // Move SP out of the way ++ __ andi(sp, t0, -2 * wordSize); ++ ++ BLOCK_COMMENT("pass parameters if any"); ++ Label parameters_done; ++ // parameter count is still in c_rarg6 ++ // and parameter pointer identifying param 1 is in c_rarg5 ++ __ beqz(c_rarg6, parameters_done); ++ ++ address loop = __ pc(); ++ __ ld(t0, Address(c_rarg5, 0)); ++ __ addi(c_rarg5, c_rarg5, wordSize); ++ __ addi(c_rarg6, c_rarg6, -1); ++ __ push_reg(t0); ++ __ bgtz(c_rarg6, loop); ++ ++ __ BIND(parameters_done); ++ ++ // call Java entry -- passing methdoOop, and current sp ++ // xmethod: Method* ++ // x30: sender sp ++ BLOCK_COMMENT("call Java function"); ++ __ mv(x30, sp); ++ __ jalr(c_rarg4); ++ ++ // save current address for use by exception handling code ++ ++ return_address = __ pc(); ++ ++ // store result depending on type (everything that is not ++ // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) ++ // n.b. this assumes Java returns an integral result in x10 ++ // and a floating result in j_farg0 ++ __ ld(j_rarg2, result); ++ Label is_long, is_float, is_double, exit; ++ __ ld(j_rarg1, result_type); ++ __ mv(t0, (u1)T_OBJECT); ++ __ beq(j_rarg1, t0, is_long); ++ __ mv(t0, (u1)T_LONG); ++ __ beq(j_rarg1, t0, is_long); ++ __ mv(t0, (u1)T_FLOAT); ++ __ beq(j_rarg1, t0, is_float); ++ __ mv(t0, (u1)T_DOUBLE); ++ __ beq(j_rarg1, t0, is_double); ++ ++ // handle T_INT case ++ __ sw(x10, Address(j_rarg2)); ++ ++ __ BIND(exit); ++ ++ // pop parameters ++ __ addi(esp, fp, sp_after_call_off * wordSize); ++ ++#ifdef ASSERT ++ // verify that threads correspond ++ { ++ Label L, S; ++ __ ld(t0, thread); ++ __ bne(xthread, t0, S); ++ __ get_thread(t0); ++ __ beq(xthread, t0, L); ++ __ BIND(S); ++ __ stop("StubRoutines::call_stub: threads must correspond"); ++ __ BIND(L); ++ } ++#endif ++ ++ // restore callee-save registers ++ __ fld(f27, f27_save); ++ __ fld(f26, f26_save); ++ __ fld(f25, f25_save); ++ __ fld(f24, f24_save); ++ __ fld(f23, f23_save); ++ __ fld(f22, f22_save); ++ __ fld(f21, f21_save); ++ __ fld(f20, f20_save); ++ __ fld(f19, f19_save); ++ __ fld(f18, f18_save); ++ __ fld(f9, f9_save); ++ __ fld(f8, f8_save); ++ ++ __ ld(x27, x27_save); ++ __ ld(x26, x26_save); ++ __ ld(x25, x25_save); ++ __ ld(x24, x24_save); ++ __ ld(x23, x23_save); ++ __ ld(x22, x22_save); ++ __ ld(x21, x21_save); ++ __ ld(x20, x20_save); ++ __ ld(x19, x19_save); ++ __ ld(x18, x18_save); ++ ++ __ ld(x9, x9_save); ++ ++ __ ld(c_rarg0, call_wrapper); ++ __ ld(c_rarg1, result); ++ __ ld(c_rarg2, result_type); ++ __ ld(c_rarg3, method); ++ __ ld(c_rarg4, entry_point); ++ __ ld(c_rarg5, parameters); ++ __ ld(c_rarg6, parameter_size); ++ __ ld(c_rarg7, thread); ++ ++ // leave frame and return to caller ++ __ leave(); ++ __ ret(); ++ ++ // handle return types different from T_INT ++ ++ __ BIND(is_long); ++ __ sd(x10, Address(j_rarg2, 0)); ++ __ j(exit); ++ ++ __ BIND(is_float); ++ __ fsw(j_farg0, Address(j_rarg2, 0), t0); ++ __ j(exit); ++ ++ __ BIND(is_double); ++ __ fsd(j_farg0, Address(j_rarg2, 0), t0); ++ __ j(exit); ++ ++ return start; ++ } ++ ++ // Return point for a Java call if there's an exception thrown in ++ // Java code. The exception is caught and transformed into a ++ // pending exception stored in JavaThread that can be tested from ++ // within the VM. ++ // ++ // Note: Usually the parameters are removed by the callee. In case ++ // of an exception crossing an activation frame boundary, that is ++ // not the case if the callee is compiled code => need to setup the ++ // sp. ++ // ++ // x10: exception oop ++ ++ address generate_catch_exception() { ++ StubCodeMark mark(this, "StubRoutines", "catch_exception"); ++ address start = __ pc(); ++ ++ // same as in generate_call_stub(): ++ const Address thread(fp, thread_off * wordSize); ++ ++#ifdef ASSERT ++ // verify that threads correspond ++ { ++ Label L, S; ++ __ ld(t0, thread); ++ __ bne(xthread, t0, S); ++ __ get_thread(t0); ++ __ beq(xthread, t0, L); ++ __ bind(S); ++ __ stop("StubRoutines::catch_exception: threads must correspond"); ++ __ bind(L); ++ } ++#endif ++ ++ // set pending exception ++ __ verify_oop(x10); ++ ++ __ sd(x10, Address(xthread, Thread::pending_exception_offset())); ++ __ mv(t0, (address)__FILE__); ++ __ sd(t0, Address(xthread, Thread::exception_file_offset())); ++ __ mv(t0, (int)__LINE__); ++ __ sw(t0, Address(xthread, Thread::exception_line_offset())); ++ ++ // complete return to VM ++ assert(StubRoutines::_call_stub_return_address != NULL, ++ "_call_stub_return_address must have been generated before"); ++ __ j(StubRoutines::_call_stub_return_address); ++ ++ return start; ++ } ++ ++ // Continuation point for runtime calls returning with a pending ++ // exception. The pending exception check happened in the runtime ++ // or native call stub. The pending exception in Thread is ++ // converted into a Java-level exception. ++ // ++ // Contract with Java-level exception handlers: ++ // x10: exception ++ // x13: throwing pc ++ // ++ // NOTE: At entry of this stub, exception-pc must be in RA !! ++ ++ // NOTE: this is always used as a jump target within generated code ++ // so it just needs to be generated code with no x86 prolog ++ ++ address generate_forward_exception() { ++ StubCodeMark mark(this, "StubRoutines", "forward exception"); ++ address start = __ pc(); ++ ++ // Upon entry, RA points to the return address returning into ++ // Java (interpreted or compiled) code; i.e., the return address ++ // becomes the throwing pc. ++ // ++ // Arguments pushed before the runtime call are still on the stack ++ // but the exception handler will reset the stack pointer -> ++ // ignore them. A potential result in registers can be ignored as ++ // well. ++ ++#ifdef ASSERT ++ // make sure this code is only executed if there is a pending exception ++ { ++ Label L; ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ bnez(t0, L); ++ __ stop("StubRoutines::forward exception: no pending exception (1)"); ++ __ bind(L); ++ } ++#endif ++ ++ // compute exception handler into x9 ++ ++ // call the VM to find the handler address associated with the ++ // caller address. pass thread in x10 and caller pc (ret address) ++ // in x11. n.b. the caller pc is in ra, unlike x86 where it is on ++ // the stack. ++ __ mv(c_rarg1, ra); ++ // ra will be trashed by the VM call so we move it to x9 ++ // (callee-saved) because we also need to pass it to the handler ++ // returned by this call. ++ __ mv(x9, ra); ++ BLOCK_COMMENT("call exception_handler_for_return_address"); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, ++ SharedRuntime::exception_handler_for_return_address), ++ xthread, c_rarg1); ++ // we should not really care that ra is no longer the callee ++ // address. we saved the value the handler needs in x9 so we can ++ // just copy it to x13. however, the C2 handler will push its own ++ // frame and then calls into the VM and the VM code asserts that ++ // the PC for the frame above the handler belongs to a compiled ++ // Java method. So, we restore ra here to satisfy that assert. ++ __ mv(ra, x9); ++ // setup x10 & x13 & clear pending exception ++ __ mv(x13, x9); ++ __ mv(x9, x10); ++ __ ld(x10, Address(xthread, Thread::pending_exception_offset())); ++ __ sd(zr, Address(xthread, Thread::pending_exception_offset())); ++ ++#ifdef ASSERT ++ // make sure exception is set ++ { ++ Label L; ++ __ bnez(x10, L); ++ __ stop("StubRoutines::forward exception: no pending exception (2)"); ++ __ bind(L); ++ } ++#endif ++ ++ // continue at exception handler ++ // x10: exception ++ // x13: throwing pc ++ // x9: exception handler ++ __ verify_oop(x10); ++ __ jr(x9); ++ ++ return start; ++ } ++ ++ // Non-destructive plausibility checks for oops ++ // ++ // Arguments: ++ // x10: oop to verify ++ // t0: error message ++ // ++ // Stack after saving c_rarg3: ++ // [tos + 0]: saved c_rarg3 ++ // [tos + 1]: saved c_rarg2 ++ // [tos + 2]: saved ra ++ // [tos + 3]: saved t1 ++ // [tos + 4]: saved x10 ++ // [tos + 5]: saved t0 ++ address generate_verify_oop() { ++ ++ StubCodeMark mark(this, "StubRoutines", "verify_oop"); ++ address start = __ pc(); ++ ++ Label exit, error; ++ ++ __ push_reg(RegSet::of(c_rarg2, c_rarg3), sp); // save c_rarg2 and c_rarg3 ++ ++ __ la(c_rarg2, ExternalAddress((address) StubRoutines::verify_oop_count_addr())); ++ __ ld(c_rarg3, Address(c_rarg2)); ++ __ add(c_rarg3, c_rarg3, 1); ++ __ sd(c_rarg3, Address(c_rarg2)); ++ ++ // object is in x10 ++ // make sure object is 'reasonable' ++ __ beqz(x10, exit); // if obj is NULL it is OK ++ ++#if INCLUDE_ZGC ++ if (UseZGC) { ++ // Check if mask is good. ++ // verifies that ZAddressBadMask & x10 == 0 ++ __ ld(c_rarg3, Address(xthread, ZThreadLocalData::address_bad_mask_offset())); ++ __ andr(c_rarg2, x10, c_rarg3); ++ __ bnez(c_rarg2, error); ++ } ++#endif ++ ++ // Check if the oop is in the right area of memory ++ __ mv(c_rarg3, (intptr_t) Universe::verify_oop_mask()); ++ __ andr(c_rarg2, x10, c_rarg3); ++ __ mv(c_rarg3, (intptr_t) Universe::verify_oop_bits()); ++ ++ // Compare c_rarg2 and c_rarg3. ++ __ bne(c_rarg2, c_rarg3, error); ++ ++ // make sure klass is 'reasonable', which is not zero. ++ __ load_klass(x10, x10); // get klass ++ __ beqz(x10, error); // if klass is NULL it is broken ++ ++ // return if everything seems ok ++ __ bind(exit); ++ ++ __ pop_reg(RegSet::of(c_rarg2, c_rarg3), sp); // pop c_rarg2 and c_rarg3 ++ __ ret(); ++ ++ // handle errors ++ __ bind(error); ++ __ pop_reg(RegSet::of(c_rarg2, c_rarg3), sp); // pop c_rarg2 and c_rarg3 ++ ++ __ push_reg(RegSet::range(x0, x31), sp); ++ // debug(char* msg, int64_t pc, int64_t regs[]) ++ __ mv(c_rarg0, t0); // pass address of error message ++ __ mv(c_rarg1, ra); // pass return address ++ __ mv(c_rarg2, sp); // pass address of regs on stack ++#ifndef PRODUCT ++ assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); ++#endif ++ BLOCK_COMMENT("call MacroAssembler::debug"); ++ __ call(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)); ++ __ ebreak(); ++ ++ return start; ++ } ++ ++ // The inner part of zero_words(). ++ // ++ // Inputs: ++ // x28: the HeapWord-aligned base address of an array to zero. ++ // x29: the count in HeapWords, x29 > 0. ++ // ++ // Returns x28 and x29, adjusted for the caller to clear. ++ // x28: the base address of the tail of words left to clear. ++ // x29: the number of words in the tail. ++ // x29 < MacroAssembler::zero_words_block_size. ++ ++ address generate_zero_blocks() { ++ Label done; ++ ++ const Register base = x28, cnt = x29; ++ ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", "zero_blocks"); ++ address start = __ pc(); ++ ++ { ++ // Clear the remaining blocks. ++ Label loop; ++ __ sub(cnt, cnt, MacroAssembler::zero_words_block_size); ++ __ bltz(cnt, done); ++ __ bind(loop); ++ for (int i = 0; i < MacroAssembler::zero_words_block_size; i++) { ++ __ sd(zr, Address(base, 0)); ++ __ add(base, base, 8); ++ } ++ __ sub(cnt, cnt, MacroAssembler::zero_words_block_size); ++ __ bgez(cnt, loop); ++ __ bind(done); ++ __ add(cnt, cnt, MacroAssembler::zero_words_block_size); ++ } ++ ++ __ ret(); ++ ++ return start; ++ } ++ ++ typedef enum { ++ copy_forwards = 1, ++ copy_backwards = -1 ++ } copy_direction; ++ ++ // Bulk copy of blocks of 8 words. ++ // ++ // count is a count of words. ++ // ++ // Precondition: count >= 8 ++ // ++ // Postconditions: ++ // ++ // The least significant bit of count contains the remaining count ++ // of words to copy. The rest of count is trash. ++ // ++ // s and d are adjusted to point to the remaining words to copy ++ // ++ void generate_copy_longs(Label &start, Register s, Register d, Register count, ++ copy_direction direction) { ++ int unit = wordSize * direction; ++ int bias = wordSize; ++ ++ const Register tmp_reg0 = x13, tmp_reg1 = x14, tmp_reg2 = x15, tmp_reg3 = x16, ++ tmp_reg4 = x17, tmp_reg5 = x7, tmp_reg6 = x28, tmp_reg7 = x29; ++ ++ const Register stride = x30; ++ ++ assert_different_registers(t0, tmp_reg0, tmp_reg1, tmp_reg2, tmp_reg3, ++ tmp_reg4, tmp_reg5, tmp_reg6, tmp_reg7); ++ assert_different_registers(s, d, count, t0); ++ ++ Label again, drain; ++ const char* stub_name = NULL; ++ if (direction == copy_forwards) { ++ stub_name = "forward_copy_longs"; ++ } else { ++ stub_name = "backward_copy_longs"; ++ } ++ StubCodeMark mark(this, "StubRoutines", stub_name); ++ __ align(CodeEntryAlignment); ++ __ bind(start); ++ ++ if (direction == copy_forwards) { ++ __ sub(s, s, bias); ++ __ sub(d, d, bias); ++ } ++ ++#ifdef ASSERT ++ // Make sure we are never given < 8 words ++ { ++ Label L; ++ ++ __ mv(t0, 8); ++ __ bge(count, t0, L); ++ __ stop("genrate_copy_longs called with < 8 words"); ++ __ bind(L); ++ } ++#endif ++ ++ __ ld(tmp_reg0, Address(s, 1 * unit)); ++ __ ld(tmp_reg1, Address(s, 2 * unit)); ++ __ ld(tmp_reg2, Address(s, 3 * unit)); ++ __ ld(tmp_reg3, Address(s, 4 * unit)); ++ __ ld(tmp_reg4, Address(s, 5 * unit)); ++ __ ld(tmp_reg5, Address(s, 6 * unit)); ++ __ ld(tmp_reg6, Address(s, 7 * unit)); ++ __ ld(tmp_reg7, Address(s, 8 * unit)); ++ __ addi(s, s, 8 * unit); ++ ++ __ sub(count, count, 16); ++ __ bltz(count, drain); ++ ++ __ bind(again); ++ ++ __ sd(tmp_reg0, Address(d, 1 * unit)); ++ __ sd(tmp_reg1, Address(d, 2 * unit)); ++ __ sd(tmp_reg2, Address(d, 3 * unit)); ++ __ sd(tmp_reg3, Address(d, 4 * unit)); ++ __ sd(tmp_reg4, Address(d, 5 * unit)); ++ __ sd(tmp_reg5, Address(d, 6 * unit)); ++ __ sd(tmp_reg6, Address(d, 7 * unit)); ++ __ sd(tmp_reg7, Address(d, 8 * unit)); ++ ++ __ ld(tmp_reg0, Address(s, 1 * unit)); ++ __ ld(tmp_reg1, Address(s, 2 * unit)); ++ __ ld(tmp_reg2, Address(s, 3 * unit)); ++ __ ld(tmp_reg3, Address(s, 4 * unit)); ++ __ ld(tmp_reg4, Address(s, 5 * unit)); ++ __ ld(tmp_reg5, Address(s, 6 * unit)); ++ __ ld(tmp_reg6, Address(s, 7 * unit)); ++ __ ld(tmp_reg7, Address(s, 8 * unit)); ++ ++ __ addi(s, s, 8 * unit); ++ __ addi(d, d, 8 * unit); ++ ++ __ sub(count, count, 8); ++ __ bgez(count, again); ++ ++ // Drain ++ __ bind(drain); ++ ++ __ sd(tmp_reg0, Address(d, 1 * unit)); ++ __ sd(tmp_reg1, Address(d, 2 * unit)); ++ __ sd(tmp_reg2, Address(d, 3 * unit)); ++ __ sd(tmp_reg3, Address(d, 4 * unit)); ++ __ sd(tmp_reg4, Address(d, 5 * unit)); ++ __ sd(tmp_reg5, Address(d, 6 * unit)); ++ __ sd(tmp_reg6, Address(d, 7 * unit)); ++ __ sd(tmp_reg7, Address(d, 8 * unit)); ++ __ addi(d, d, 8 * unit); ++ ++ { ++ Label L1, L2; ++ __ test_bit(t0, count, 2); ++ __ beqz(t0, L1); ++ ++ __ ld(tmp_reg0, Address(s, 1 * unit)); ++ __ ld(tmp_reg1, Address(s, 2 * unit)); ++ __ ld(tmp_reg2, Address(s, 3 * unit)); ++ __ ld(tmp_reg3, Address(s, 4 * unit)); ++ __ addi(s, s, 4 * unit); ++ ++ __ sd(tmp_reg0, Address(d, 1 * unit)); ++ __ sd(tmp_reg1, Address(d, 2 * unit)); ++ __ sd(tmp_reg2, Address(d, 3 * unit)); ++ __ sd(tmp_reg3, Address(d, 4 * unit)); ++ __ addi(d, d, 4 * unit); ++ ++ __ bind(L1); ++ ++ if (direction == copy_forwards) { ++ __ addi(s, s, bias); ++ __ addi(d, d, bias); ++ } ++ ++ __ test_bit(t0, count, 1); ++ __ beqz(t0, L2); ++ if (direction == copy_backwards) { ++ __ addi(s, s, 2 * unit); ++ __ ld(tmp_reg0, Address(s)); ++ __ ld(tmp_reg1, Address(s, wordSize)); ++ __ addi(d, d, 2 * unit); ++ __ sd(tmp_reg0, Address(d)); ++ __ sd(tmp_reg1, Address(d, wordSize)); ++ } else { ++ __ ld(tmp_reg0, Address(s)); ++ __ ld(tmp_reg1, Address(s, wordSize)); ++ __ addi(s, s, 2 * unit); ++ __ sd(tmp_reg0, Address(d)); ++ __ sd(tmp_reg1, Address(d, wordSize)); ++ __ addi(d, d, 2 * unit); ++ } ++ __ bind(L2); ++ } ++ ++ __ ret(); ++ } ++ ++ Label copy_f, copy_b; ++ ++ // All-singing all-dancing memory copy. ++ // ++ // Copy count units of memory from s to d. The size of a unit is ++ // step, which can be positive or negative depending on the direction ++ // of copy. If is_aligned is false, we align the source address. ++ // ++ /* ++ * if (is_aligned) { ++ * if (count >= 32) ++ * goto copy32_loop; ++ * if (count >= 8) ++ * goto copy8_loop; ++ * goto copy_small; ++ * } ++ * bool is_backwards = step < 0; ++ * int granularity = uabs(step); ++ * count = count * granularity; * count bytes ++ * ++ * if (is_backwards) { ++ * s += count; ++ * d += count; ++ * } ++ * ++ * count limit maybe greater than 16, for better performance ++ * if (count < 16) { ++ * goto copy_small; ++ * } ++ * ++ * if ((dst % 8) == (src % 8)) { ++ * aligned; ++ * goto copy_big; ++ * } ++ * ++ * copy_big: ++ * if the amount to copy is more than (or equal to) 32 bytes goto copy32_loop ++ * else goto copy8_loop ++ * copy_small: ++ * load element one by one; ++ * done; ++ */ ++ ++ typedef void (MacroAssembler::*copy_insn)(Register Rd, const Address &adr, Register temp); ++ ++ void copy_memory_v(Register s, Register d, Register count, Register tmp, int step) { ++ bool is_backward = step < 0; ++ int granularity = uabs(step); ++ ++ const Register src = x30, dst = x31, vl = x14, cnt = x15, tmp1 = x16, tmp2 = x17; ++ assert_different_registers(s, d, cnt, vl, tmp, tmp1, tmp2); ++ Assembler::SEW sew = Assembler::elembytes_to_sew(granularity); ++ Label loop_forward, loop_backward, done; ++ ++ __ mv(dst, d); ++ __ mv(src, s); ++ __ mv(cnt, count); ++ ++ __ bind(loop_forward); ++ __ vsetvli(vl, cnt, sew, Assembler::m8); ++ if (is_backward) { ++ __ bne(vl, cnt, loop_backward); ++ } ++ ++ __ vlex_v(v0, src, sew); ++ __ sub(cnt, cnt, vl); ++ __ slli(vl, vl, (int)sew); ++ __ add(src, src, vl); ++ ++ __ vsex_v(v0, dst, sew); ++ __ add(dst, dst, vl); ++ __ bnez(cnt, loop_forward); ++ ++ if (is_backward) { ++ __ j(done); ++ ++ __ bind(loop_backward); ++ __ sub(tmp, cnt, vl); ++ __ slli(tmp, tmp, sew); ++ __ add(tmp1, s, tmp); ++ __ vlex_v(v0, tmp1, sew); ++ __ add(tmp2, d, tmp); ++ __ vsex_v(v0, tmp2, sew); ++ __ sub(cnt, cnt, vl); ++ __ bnez(cnt, loop_forward); ++ __ bind(done); ++ } ++ } ++ ++ void copy_memory(bool is_aligned, Register s, Register d, ++ Register count, Register tmp, int step) { ++ if (UseRVV) { ++ return copy_memory_v(s, d, count, tmp, step); ++ } ++ ++ bool is_backwards = step < 0; ++ int granularity = uabs(step); ++ ++ const Register src = x30, dst = x31, cnt = x15, tmp3 = x16, tmp4 = x17, tmp5 = x14, tmp6 = x13; ++ ++ Label same_aligned; ++ Label copy_big, copy32_loop, copy8_loop, copy_small, done; ++ ++ copy_insn ld_arr = NULL, st_arr = NULL; ++ switch (granularity) { ++ case 1 : ++ ld_arr = (copy_insn)&MacroAssembler::lbu; ++ st_arr = (copy_insn)&MacroAssembler::sb; ++ break; ++ case 2 : ++ ld_arr = (copy_insn)&MacroAssembler::lhu; ++ st_arr = (copy_insn)&MacroAssembler::sh; ++ break; ++ case 4 : ++ ld_arr = (copy_insn)&MacroAssembler::lwu; ++ st_arr = (copy_insn)&MacroAssembler::sw; ++ break; ++ case 8 : ++ ld_arr = (copy_insn)&MacroAssembler::ld; ++ st_arr = (copy_insn)&MacroAssembler::sd; ++ break; ++ default : ++ ShouldNotReachHere(); ++ } ++ ++ __ beqz(count, done); ++ __ slli(cnt, count, exact_log2(granularity)); ++ if (is_backwards) { ++ __ add(src, s, cnt); ++ __ add(dst, d, cnt); ++ } else { ++ __ mv(src, s); ++ __ mv(dst, d); ++ } ++ ++ if (is_aligned) { ++ __ addi(tmp, cnt, -32); ++ __ bgez(tmp, copy32_loop); ++ __ addi(tmp, cnt, -8); ++ __ bgez(tmp, copy8_loop); ++ __ j(copy_small); ++ } else { ++ __ mv(tmp, 16); ++ __ blt(cnt, tmp, copy_small); ++ ++ __ xorr(tmp, src, dst); ++ __ andi(tmp, tmp, 0b111); ++ __ bnez(tmp, copy_small); ++ ++ __ bind(same_aligned); ++ __ andi(tmp, src, 0b111); ++ __ beqz(tmp, copy_big); ++ if (is_backwards) { ++ __ addi(src, src, step); ++ __ addi(dst, dst, step); ++ } ++ (_masm->*ld_arr)(tmp3, Address(src), t0); ++ (_masm->*st_arr)(tmp3, Address(dst), t0); ++ if (!is_backwards) { ++ __ addi(src, src, step); ++ __ addi(dst, dst, step); ++ } ++ __ addi(cnt, cnt, -granularity); ++ __ beqz(cnt, done); ++ __ j(same_aligned); ++ ++ __ bind(copy_big); ++ __ mv(tmp, 32); ++ __ blt(cnt, tmp, copy8_loop); ++ } ++ __ bind(copy32_loop); ++ if (is_backwards) { ++ __ addi(src, src, -wordSize * 4); ++ __ addi(dst, dst, -wordSize * 4); ++ } ++ // we first load 32 bytes, then write it, so the direction here doesn't matter ++ __ ld(tmp3, Address(src)); ++ __ ld(tmp4, Address(src, 8)); ++ __ ld(tmp5, Address(src, 16)); ++ __ ld(tmp6, Address(src, 24)); ++ __ sd(tmp3, Address(dst)); ++ __ sd(tmp4, Address(dst, 8)); ++ __ sd(tmp5, Address(dst, 16)); ++ __ sd(tmp6, Address(dst, 24)); ++ ++ if (!is_backwards) { ++ __ addi(src, src, wordSize * 4); ++ __ addi(dst, dst, wordSize * 4); ++ } ++ __ addi(tmp, cnt, -(32 + wordSize * 4)); ++ __ addi(cnt, cnt, -wordSize * 4); ++ __ bgez(tmp, copy32_loop); // cnt >= 32, do next loop ++ ++ __ beqz(cnt, done); // if that's all - done ++ ++ __ addi(tmp, cnt, -8); // if not - copy the reminder ++ __ bltz(tmp, copy_small); // cnt < 8, go to copy_small, else fall throught to copy8_loop ++ ++ __ bind(copy8_loop); ++ if (is_backwards) { ++ __ addi(src, src, -wordSize); ++ __ addi(dst, dst, -wordSize); ++ } ++ __ ld(tmp3, Address(src)); ++ __ sd(tmp3, Address(dst)); ++ if (!is_backwards) { ++ __ addi(src, src, wordSize); ++ __ addi(dst, dst, wordSize); ++ } ++ __ addi(tmp, cnt, -(8 + wordSize)); ++ __ addi(cnt, cnt, -wordSize); ++ __ bgez(tmp, copy8_loop); // cnt >= 8, do next loop ++ ++ __ beqz(cnt, done); // if that's all - done ++ ++ __ bind(copy_small); ++ if (is_backwards) { ++ __ addi(src, src, step); ++ __ addi(dst, dst, step); ++ } ++ (_masm->*ld_arr)(tmp3, Address(src), t0); ++ (_masm->*st_arr)(tmp3, Address(dst), t0); ++ if (!is_backwards) { ++ __ addi(src, src, step); ++ __ addi(dst, dst, step); ++ } ++ __ addi(cnt, cnt, -granularity); ++ __ bgtz(cnt, copy_small); ++ ++ __ bind(done); ++ } ++ ++ // Scan over array at a for count oops, verifying each one. ++ // Preserves a and count, clobbers t0 and t1. ++ void verify_oop_array(size_t size, Register a, Register count, Register temp) { ++ Label loop, end; ++ __ mv(t1, zr); ++ __ slli(t0, count, exact_log2(size)); ++ __ bind(loop); ++ __ bgeu(t1, t0, end); ++ ++ __ add(temp, a, t1); ++ if (size == (size_t)wordSize) { ++ __ ld(temp, Address(temp, 0)); ++ __ verify_oop(temp); ++ } else { ++ __ lwu(temp, Address(temp, 0)); ++ __ decode_heap_oop(temp); // calls verify_oop ++ } ++ __ add(t1, t1, size); ++ __ j(loop); ++ __ bind(end); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // is_oop - true => oop array, so generate store check code ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let ++ // the hardware handle it. The two dwords within qwords that span ++ // cache line boundaries will still be loaded and stored atomicly. ++ // ++ // Side Effects: ++ // disjoint_int_copy_entry is set to the no-overlap entry point ++ // used by generate_conjoint_int_oop_copy(). ++ // ++ address generate_disjoint_copy(size_t size, bool aligned, bool is_oop, address* entry, ++ const char* name, bool dest_uninitialized = false) { ++ const Register s = c_rarg0, d = c_rarg1, count = c_rarg2; ++ RegSet saved_reg = RegSet::of(s, d, count); ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", name); ++ address start = __ pc(); ++ __ enter(); ++ ++ if (entry != NULL) { ++ *entry = __ pc(); ++ // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) ++ BLOCK_COMMENT("Entry:"); ++ } ++ ++ DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT; ++ if (dest_uninitialized) { ++ decorators |= IS_DEST_UNINITIALIZED; ++ } ++ if (aligned) { ++ decorators |= ARRAYCOPY_ALIGNED; ++ } ++ ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->arraycopy_prologue(_masm, decorators, is_oop, s, d, count, saved_reg); ++ ++ if (is_oop) { ++ // save regs before copy_memory ++ __ push_reg(RegSet::of(d, count), sp); ++ } ++ ++ { ++ // UnsafeCopyMemory page error: continue after ucm ++ bool add_entry = !is_oop && (!aligned || sizeof(jlong) == size); ++ UnsafeCopyMemoryMark ucmm(this, add_entry, true); ++ copy_memory(aligned, s, d, count, t0, size); ++ } ++ ++ if (is_oop) { ++ __ pop_reg(RegSet::of(d, count), sp); ++ if (VerifyOops) { ++ verify_oop_array(size, d, count, t2); ++ } ++ } ++ ++ bs->arraycopy_epilogue(_masm, decorators, is_oop, d, count, t0, RegSet()); ++ ++ __ leave(); ++ __ mv(x10, zr); // return 0 ++ __ ret(); ++ return start; ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // is_oop - true => oop array, so generate store check code ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let ++ // the hardware handle it. The two dwords within qwords that span ++ // cache line boundaries will still be loaded and stored atomicly. ++ // ++ address generate_conjoint_copy(size_t size, bool aligned, bool is_oop, address nooverlap_target, ++ address* entry, const char* name, ++ bool dest_uninitialized = false) { ++ const Register s = c_rarg0, d = c_rarg1, count = c_rarg2; ++ RegSet saved_regs = RegSet::of(s, d, count); ++ StubCodeMark mark(this, "StubRoutines", name); ++ address start = __ pc(); ++ __ enter(); ++ ++ if (entry != NULL) { ++ *entry = __ pc(); ++ // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) ++ BLOCK_COMMENT("Entry:"); ++ } ++ ++ // use fwd copy when (d-s) above_equal (count*size) ++ __ sub(t0, d, s); ++ __ slli(t1, count, exact_log2(size)); ++ __ bgeu(t0, t1, nooverlap_target); ++ ++ DecoratorSet decorators = IN_HEAP | IS_ARRAY; ++ if (dest_uninitialized) { ++ decorators |= IS_DEST_UNINITIALIZED; ++ } ++ if (aligned) { ++ decorators |= ARRAYCOPY_ALIGNED; ++ } ++ ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->arraycopy_prologue(_masm, decorators, is_oop, s, d, count, saved_regs); ++ ++ if (is_oop) { ++ // save regs before copy_memory ++ __ push_reg(RegSet::of(d, count), sp); ++ } ++ ++ { ++ // UnsafeCopyMemory page error: continue after ucm ++ bool add_entry = !is_oop && (!aligned || sizeof(jlong) == size); ++ UnsafeCopyMemoryMark ucmm(this, add_entry, true); ++ copy_memory(aligned, s, d, count, t0, -size); ++ } ++ ++ if (is_oop) { ++ __ pop_reg(RegSet::of(d, count), sp); ++ if (VerifyOops) { ++ verify_oop_array(size, d, count, t2); ++ } ++ } ++ bs->arraycopy_epilogue(_masm, decorators, is_oop, d, count, t0, RegSet()); ++ __ leave(); ++ __ mv(x10, zr); // return 0 ++ __ ret(); ++ return start; ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, ++ // we let the hardware handle it. The one to eight bytes within words, ++ // dwords or qwords that span cache line boundaries will still be loaded ++ // and stored atomically. ++ // ++ // Side Effects: ++ // disjoint_byte_copy_entry is set to the no-overlap entry point // ++ // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, ++ // we let the hardware handle it. The one to eight bytes within words, ++ // dwords or qwords that span cache line boundaries will still be loaded ++ // and stored atomically. ++ // ++ // Side Effects: ++ // disjoint_byte_copy_entry is set to the no-overlap entry point ++ // used by generate_conjoint_byte_copy(). ++ // ++ address generate_disjoint_byte_copy(bool aligned, address* entry, const char* name) { ++ const bool not_oop = false; ++ return generate_disjoint_copy(sizeof (jbyte), aligned, not_oop, entry, name); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, ++ // we let the hardware handle it. The one to eight bytes within words, ++ // dwords or qwords that span cache line boundaries will still be loaded ++ // and stored atomically. ++ // ++ address generate_conjoint_byte_copy(bool aligned, address nooverlap_target, ++ address* entry, const char* name) { ++ const bool not_oop = false; ++ return generate_conjoint_copy(sizeof (jbyte), aligned, not_oop, nooverlap_target, entry, name); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we ++ // let the hardware handle it. The two or four words within dwords ++ // or qwords that span cache line boundaries will still be loaded ++ // and stored atomically. ++ // ++ // Side Effects: ++ // disjoint_short_copy_entry is set to the no-overlap entry point ++ // used by generate_conjoint_short_copy(). ++ // ++ address generate_disjoint_short_copy(bool aligned, ++ address* entry, const char* name) { ++ const bool not_oop = false; ++ return generate_disjoint_copy(sizeof (jshort), aligned, not_oop, entry, name); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we ++ // let the hardware handle it. The two or four words within dwords ++ // or qwords that span cache line boundaries will still be loaded ++ // and stored atomically. ++ // ++ address generate_conjoint_short_copy(bool aligned, address nooverlap_target, ++ address* entry, const char* name) { ++ const bool not_oop = false; ++ return generate_conjoint_copy(sizeof (jshort), aligned, not_oop, nooverlap_target, entry, name); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let ++ // the hardware handle it. The two dwords within qwords that span ++ // cache line boundaries will still be loaded and stored atomicly. ++ // ++ // Side Effects: ++ // disjoint_int_copy_entry is set to the no-overlap entry point ++ // used by generate_conjoint_int_oop_copy(). ++ // ++ address generate_disjoint_int_copy(bool aligned, address* entry, ++ const char* name, bool dest_uninitialized = false) { ++ const bool not_oop = false; ++ return generate_disjoint_copy(sizeof (jint), aligned, not_oop, entry, name); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // ++ // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let ++ // the hardware handle it. The two dwords within qwords that span ++ // cache line boundaries will still be loaded and stored atomicly. ++ // ++ address generate_conjoint_int_copy(bool aligned, address nooverlap_target, ++ address* entry, const char* name, ++ bool dest_uninitialized = false) { ++ const bool not_oop = false; ++ return generate_conjoint_copy(sizeof (jint), aligned, not_oop, nooverlap_target, entry, name); ++ } ++ ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as size_t, can be zero ++ // ++ // Side Effects: ++ // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the ++ // no-overlap entry point used by generate_conjoint_long_oop_copy(). ++ // ++ address generate_disjoint_long_copy(bool aligned, address* entry, ++ const char* name, bool dest_uninitialized = false) { ++ const bool not_oop = false; ++ return generate_disjoint_copy(sizeof (jlong), aligned, not_oop, entry, name); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as size_t, can be zero ++ // ++ address generate_conjoint_long_copy(bool aligned, ++ address nooverlap_target, address* entry, ++ const char* name, bool dest_uninitialized = false) { ++ const bool not_oop = false; ++ return generate_conjoint_copy(sizeof (jlong), aligned, not_oop, nooverlap_target, entry, name); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as size_t, can be zero ++ // ++ // Side Effects: ++ // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the ++ // no-overlap entry point used by generate_conjoint_long_oop_copy(). ++ // ++ address generate_disjoint_oop_copy(bool aligned, address* entry, ++ const char* name, bool dest_uninitialized) { ++ const bool is_oop = true; ++ const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); ++ return generate_disjoint_copy(size, aligned, is_oop, entry, name, dest_uninitialized); ++ } ++ ++ // Arguments: ++ // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes ++ // ignored ++ // name - stub name string ++ // ++ // Inputs: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as size_t, can be zero ++ // ++ address generate_conjoint_oop_copy(bool aligned, ++ address nooverlap_target, address* entry, ++ const char* name, bool dest_uninitialized) { ++ const bool is_oop = true; ++ const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); ++ return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry, ++ name, dest_uninitialized); ++ } ++ ++ // Helper for generating a dynamic type check. ++ // Smashes t0, t1. ++ void generate_type_check(Register sub_klass, ++ Register super_check_offset, ++ Register super_klass, ++ Label& L_success) { ++ assert_different_registers(sub_klass, super_check_offset, super_klass); ++ ++ BLOCK_COMMENT("type_check:"); ++ ++ Label L_miss; ++ ++ __ check_klass_subtype_fast_path(sub_klass, super_klass, noreg, &L_success, &L_miss, NULL, super_check_offset); ++ __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg, &L_success, NULL); ++ ++ // Fall through on failure! ++ __ BIND(L_miss); ++ } ++ ++ // ++ // Generate checkcasting array copy stub ++ // ++ // Input: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - element count, treated as ssize_t, can be zero ++ // c_rarg3 - size_t ckoff (super_check_offset) ++ // c_rarg4 - oop ckval (super_klass) ++ // ++ // Output: ++ // x10 == 0 - success ++ // x10 == -1^K - failure, where K is partial transfer count ++ // ++ address generate_checkcast_copy(const char* name, address* entry, ++ bool dest_uninitialized = false) { ++ Label L_load_element, L_store_element, L_do_card_marks, L_done, L_done_pop; ++ ++ // Input registers (after setup_arg_regs) ++ const Register from = c_rarg0; // source array address ++ const Register to = c_rarg1; // destination array address ++ const Register count = c_rarg2; // elementscount ++ const Register ckoff = c_rarg3; // super_check_offset ++ const Register ckval = c_rarg4; // super_klass ++ ++ RegSet wb_pre_saved_regs = RegSet::range(c_rarg0, c_rarg4); ++ RegSet wb_post_saved_regs = RegSet::of(count); ++ ++ // Registers used as temps (x7, x9, x18 are save-on-entry) ++ const Register count_save = x19; // orig elementscount ++ const Register start_to = x18; // destination array start address ++ const Register copied_oop = x7; // actual oop copied ++ const Register r9_klass = x9; // oop._klass ++ ++ //--------------------------------------------------------------- ++ // Assembler stub will be used for this call to arraycopy ++ // if the two arrays are subtypes of Object[] but the ++ // destination array type is not equal to or a supertype ++ // of the source type. Each element must be separately ++ // checked. ++ ++ assert_different_registers(from, to, count, ckoff, ckval, start_to, ++ copied_oop, r9_klass, count_save); ++ ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", name); ++ address start = __ pc(); ++ ++ __ enter(); // required for proper stackwalking of RuntimeStub frame ++ ++ // Caller of this entry point must set up the argument registers. ++ if (entry != NULL) { ++ *entry = __ pc(); ++ BLOCK_COMMENT("Entry:"); ++ } ++ ++ // Empty array: Nothing to do ++ __ beqz(count, L_done); ++ ++ __ push_reg(RegSet::of(x7, x9, x18, x19), sp); ++ ++#ifdef ASSERT ++ BLOCK_COMMENT("assert consistent ckoff/ckval"); ++ // The ckoff and ckval must be mutually consistent, ++ // even though caller generates both. ++ { Label L; ++ int sco_offset = in_bytes(Klass::super_check_offset_offset()); ++ __ lwu(start_to, Address(ckval, sco_offset)); ++ __ beq(ckoff, start_to, L); ++ __ stop("super_check_offset inconsistent"); ++ __ bind(L); ++ } ++#endif //ASSERT ++ ++ DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT; ++ bool is_oop = true; ++ if (dest_uninitialized) { ++ decorators |= IS_DEST_UNINITIALIZED; ++ } ++ ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->arraycopy_prologue(_masm, decorators, is_oop, from, to, count, wb_pre_saved_regs); ++ ++ // save the original count ++ __ mv(count_save, count); ++ ++ // Copy from low to high addresses ++ __ mv(start_to, to); // Save destination array start address ++ __ j(L_load_element); ++ ++ // ======== begin loop ======== ++ // (Loop is rotated; its entry is L_load_element.) ++ // Loop control: ++ // for count to 0 do ++ // copied_oop = load_heap_oop(from++) ++ // ... generate_type_check ... ++ // store_heap_oop(to++, copied_oop) ++ // end ++ ++ __ align(OptoLoopAlignment); ++ ++ __ BIND(L_store_element); ++ __ store_heap_oop(Address(to, 0), copied_oop, noreg, noreg, AS_RAW); // store the oop ++ __ add(to, to, UseCompressedOops ? 4 : 8); ++ __ sub(count, count, 1); ++ __ beqz(count, L_do_card_marks); ++ ++ // ======== loop entry is here ======== ++ __ BIND(L_load_element); ++ __ load_heap_oop(copied_oop, Address(from, 0), noreg, noreg, AS_RAW); // load the oop ++ __ add(from, from, UseCompressedOops ? 4 : 8); ++ __ beqz(copied_oop, L_store_element); ++ ++ __ load_klass(r9_klass, copied_oop);// query the object klass ++ generate_type_check(r9_klass, ckoff, ckval, L_store_element); ++ // ======== end loop ======== ++ ++ // It was a real error; we must depend on the caller to finish the job. ++ // Register count = remaining oops, count_orig = total oops. ++ // Emit GC store barriers for the oops we have copied and report ++ // their number to the caller. ++ ++ __ sub(count, count_save, count); // K = partially copied oop count ++ __ xori(count, count, -1); // report (-1^K) to caller ++ __ beqz(count, L_done_pop); ++ ++ __ BIND(L_do_card_marks); ++ bs->arraycopy_epilogue(_masm, decorators, is_oop, start_to, count_save, t0, wb_post_saved_regs); ++ ++ __ bind(L_done_pop); ++ __ pop_reg(RegSet::of(x7, x9, x18, x19), sp); ++ inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); ++ ++ __ bind(L_done); ++ __ mv(x10, count); ++ __ leave(); ++ __ ret(); ++ ++ return start; ++ } ++ ++ // Perform range checks on the proposed arraycopy. ++ // Kills temp, but nothing else. ++ // Also, clean the sign bits of src_pos and dst_pos. ++ void arraycopy_range_checks(Register src, // source array oop (c_rarg0) ++ Register src_pos, // source position (c_rarg1) ++ Register dst, // destination array oo (c_rarg2) ++ Register dst_pos, // destination position (c_rarg3) ++ Register length, ++ Register temp, ++ Label& L_failed) { ++ BLOCK_COMMENT("arraycopy_range_checks:"); ++ ++ assert_different_registers(t0, temp); ++ ++ // if [src_pos + length > arrayOop(src)->length()] then FAIL ++ __ lwu(t0, Address(src, arrayOopDesc::length_offset_in_bytes())); ++ __ addw(temp, length, src_pos); ++ __ bgtu(temp, t0, L_failed); ++ ++ // if [dst_pos + length > arrayOop(dst)->length()] then FAIL ++ __ lwu(t0, Address(dst, arrayOopDesc::length_offset_in_bytes())); ++ __ addw(temp, length, dst_pos); ++ __ bgtu(temp, t0, L_failed); ++ ++ // Have to clean up high 32 bits of 'src_pos' and 'dst_pos'. ++ __ zero_extend(src_pos, src_pos, 32); ++ __ zero_extend(dst_pos, dst_pos, 32); ++ ++ BLOCK_COMMENT("arraycopy_range_checks done"); ++ } ++ ++ // ++ // Generate 'unsafe' array copy stub ++ // Though just as safe as the other stubs, it takes an unscaled ++ // size_t argument instead of an element count. ++ // ++ // Input: ++ // c_rarg0 - source array address ++ // c_rarg1 - destination array address ++ // c_rarg2 - byte count, treated as ssize_t, can be zero ++ // ++ // Examines the alignment of the operands and dispatches ++ // to a long, int, short, or byte copy loop. ++ // ++ address generate_unsafe_copy(const char* name, ++ address byte_copy_entry, ++ address short_copy_entry, ++ address int_copy_entry, ++ address long_copy_entry) { ++ assert_cond(byte_copy_entry != NULL && short_copy_entry != NULL && ++ int_copy_entry != NULL && long_copy_entry != NULL); ++ Label L_long_aligned, L_int_aligned, L_short_aligned; ++ const Register s = c_rarg0, d = c_rarg1, count = c_rarg2; ++ ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", name); ++ address start = __ pc(); ++ __ enter(); // required for proper stackwalking of RuntimeStub frame ++ ++ // bump this on entry, not on exit: ++ inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr); ++ ++ __ orr(t0, s, d); ++ __ orr(t0, t0, count); ++ ++ __ andi(t0, t0, BytesPerLong - 1); ++ __ beqz(t0, L_long_aligned); ++ __ andi(t0, t0, BytesPerInt - 1); ++ __ beqz(t0, L_int_aligned); ++ __ test_bit(t0, t0, 0); ++ __ beqz(t0, L_short_aligned); ++ __ j(RuntimeAddress(byte_copy_entry)); ++ ++ __ BIND(L_short_aligned); ++ __ srli(count, count, LogBytesPerShort); // size => short_count ++ __ j(RuntimeAddress(short_copy_entry)); ++ __ BIND(L_int_aligned); ++ __ srli(count, count, LogBytesPerInt); // size => int_count ++ __ j(RuntimeAddress(int_copy_entry)); ++ __ BIND(L_long_aligned); ++ __ srli(count, count, LogBytesPerLong); // size => long_count ++ __ j(RuntimeAddress(long_copy_entry)); ++ ++ return start; ++ } ++ ++ // ++ // Generate generic array copy stubs ++ // ++ // Input: ++ // c_rarg0 - src oop ++ // c_rarg1 - src_pos (32-bits) ++ // c_rarg2 - dst oop ++ // c_rarg3 - dst_pos (32-bits) ++ // c_rarg4 - element count (32-bits) ++ // ++ // Output: ++ // x10 == 0 - success ++ // x10 == -1^K - failure, where K is partial transfer count ++ // ++ address generate_generic_copy(const char* name, ++ address byte_copy_entry, address short_copy_entry, ++ address int_copy_entry, address oop_copy_entry, ++ address long_copy_entry, address checkcast_copy_entry) { ++ assert_cond(byte_copy_entry != NULL && short_copy_entry != NULL && ++ int_copy_entry != NULL && oop_copy_entry != NULL && ++ long_copy_entry != NULL && checkcast_copy_entry != NULL); ++ Label L_failed, L_failed_0, L_objArray; ++ Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs; ++ ++ // Input registers ++ const Register src = c_rarg0; // source array oop ++ const Register src_pos = c_rarg1; // source position ++ const Register dst = c_rarg2; // destination array oop ++ const Register dst_pos = c_rarg3; // destination position ++ const Register length = c_rarg4; ++ ++ // Registers used as temps ++ const Register dst_klass = c_rarg5; ++ ++ __ align(CodeEntryAlignment); ++ ++ StubCodeMark mark(this, "StubRoutines", name); ++ ++ address start = __ pc(); ++ ++ __ enter(); // required for proper stackwalking of RuntimeStub frame ++ ++ // bump this on entry, not on exit: ++ inc_counter_np(SharedRuntime::_generic_array_copy_ctr); ++ ++ //----------------------------------------------------------------------- ++ // Assembler stub will be used for this call to arraycopy ++ // if the following conditions are met: ++ // ++ // (1) src and dst must not be null. ++ // (2) src_pos must not be negative. ++ // (3) dst_pos must not be negative. ++ // (4) length must not be negative. ++ // (5) src klass and dst klass should be the same and not NULL. ++ // (6) src and dst should be arrays. ++ // (7) src_pos + length must not exceed length of src. ++ // (8) dst_pos + length must not exceed length of dst. ++ // ++ ++ // if [src == NULL] then return -1 ++ __ beqz(src, L_failed); ++ ++ // if [src_pos < 0] then return -1 ++ __ sign_extend(t0, src_pos, 32); ++ __ bltz(t0, L_failed); ++ ++ // if [dst == NULL] then return -1 ++ __ beqz(dst, L_failed); ++ ++ // if [dst_pos < 0] then return -1 ++ __ sign_extend(t0, dst_pos, 32); ++ __ bltz(t0, L_failed); ++ ++ // registers used as temp ++ const Register scratch_length = x28; // elements count to copy ++ const Register scratch_src_klass = x29; // array klass ++ const Register lh = x30; // layout helper ++ ++ // if [length < 0] then return -1 ++ __ sign_extend(scratch_length, length, 32); // length (elements count, 32-bits value) ++ __ bltz(scratch_length, L_failed); ++ ++ __ load_klass(scratch_src_klass, src); ++#ifdef ASSERT ++ { ++ BLOCK_COMMENT("assert klasses not null {"); ++ Label L1, L2; ++ __ bnez(scratch_src_klass, L2); // it is broken if klass is NULL ++ __ bind(L1); ++ __ stop("broken null klass"); ++ __ bind(L2); ++ __ load_klass(t0, dst, t1); ++ __ beqz(t0, L1); // this would be broken also ++ BLOCK_COMMENT("} assert klasses not null done"); ++ } ++#endif ++ ++ // Load layout helper (32-bits) ++ // ++ // |array_tag| | header_size | element_type | |log2_element_size| ++ // 32 30 24 16 8 2 0 ++ // ++ // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0 ++ // ++ ++ const int lh_offset = in_bytes(Klass::layout_helper_offset()); ++ ++ // Handle objArrays completely differently... ++ const jint objArray_lh = Klass::array_layout_helper(T_OBJECT); ++ __ lw(lh, Address(scratch_src_klass, lh_offset)); ++ __ mv(t0, objArray_lh); ++ __ beq(lh, t0, L_objArray); ++ ++ // if [src->klass() != dst->klass()] then return -1 ++ __ load_klass(t1, dst); ++ __ bne(t1, scratch_src_klass, L_failed); ++ ++ // if [src->is_Array() != NULL] then return -1 ++ // i.e. (lh >= 0) ++ __ bgez(lh, L_failed); ++ ++ // At this point, it is known to be a typeArray (array_tag 0x3). ++#ifdef ASSERT ++ { ++ BLOCK_COMMENT("assert primitive array {"); ++ Label L; ++ __ mv(t1, (int32_t)(Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift)); ++ __ bge(lh, t1, L); ++ __ stop("must be a primitive array"); ++ __ bind(L); ++ BLOCK_COMMENT("} assert primitive array done"); ++ } ++#endif ++ ++ arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, ++ t1, L_failed); ++ ++ // TypeArrayKlass ++ // ++ // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize) ++ // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize) ++ // ++ ++ const Register t0_offset = t0; // array offset ++ const Register x30_elsize = lh; // element size ++ ++ // Get array_header_in_bytes() ++ int lh_header_size_width = exact_log2(Klass::_lh_header_size_mask + 1); ++ int lh_header_size_msb = Klass::_lh_header_size_shift + lh_header_size_width; ++ __ slli(t0_offset, lh, XLEN - lh_header_size_msb); // left shift to remove 24 ~ 32; ++ __ srli(t0_offset, t0_offset, XLEN - lh_header_size_width); // array_offset ++ ++ __ add(src, src, t0_offset); // src array offset ++ __ add(dst, dst, t0_offset); // dst array offset ++ BLOCK_COMMENT("choose copy loop based on element size"); ++ ++ // next registers should be set before the jump to corresponding stub ++ const Register from = c_rarg0; // source array address ++ const Register to = c_rarg1; // destination array address ++ const Register count = c_rarg2; // elements count ++ ++ // 'from', 'to', 'count' registers should be set in such order ++ // since they are the same as 'src', 'src_pos', 'dst'. ++ ++ assert(Klass::_lh_log2_element_size_shift == 0, "fix this code"); ++ ++ // The possible values of elsize are 0-3, i.e. exact_log2(element ++ // size in bytes). We do a simple bitwise binary search. ++ __ BIND(L_copy_bytes); ++ __ test_bit(t0, x30_elsize, 1); ++ __ bnez(t0, L_copy_ints); ++ __ test_bit(t0, x30_elsize, 0); ++ __ bnez(t0, L_copy_shorts); ++ __ add(from, src, src_pos); // src_addr ++ __ add(to, dst, dst_pos); // dst_addr ++ __ sign_extend(count, scratch_length, 32); // length ++ __ j(RuntimeAddress(byte_copy_entry)); ++ ++ __ BIND(L_copy_shorts); ++ __ shadd(from, src_pos, src, t0, 1); // src_addr ++ __ shadd(to, dst_pos, dst, t0, 1); // dst_addr ++ __ sign_extend(count, scratch_length, 32); // length ++ __ j(RuntimeAddress(short_copy_entry)); ++ ++ __ BIND(L_copy_ints); ++ __ test_bit(t0, x30_elsize, 0); ++ __ bnez(t0, L_copy_longs); ++ __ shadd(from, src_pos, src, t0, 2); // src_addr ++ __ shadd(to, dst_pos, dst, t0, 2); // dst_addr ++ __ sign_extend(count, scratch_length, 32); // length ++ __ j(RuntimeAddress(int_copy_entry)); ++ ++ __ BIND(L_copy_longs); ++#ifdef ASSERT ++ { ++ BLOCK_COMMENT("assert long copy {"); ++ Label L; ++ __ andi(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> x30_elsize ++ __ sign_extend(lh, lh, 32); ++ __ mv(t0, LogBytesPerLong); ++ __ beq(x30_elsize, t0, L); ++ __ stop("must be long copy, but elsize is wrong"); ++ __ bind(L); ++ BLOCK_COMMENT("} assert long copy done"); ++ } ++#endif ++ __ shadd(from, src_pos, src, t0, 3); // src_addr ++ __ shadd(to, dst_pos, dst, t0, 3); // dst_addr ++ __ sign_extend(count, scratch_length, 32); // length ++ __ j(RuntimeAddress(long_copy_entry)); ++ ++ // ObjArrayKlass ++ __ BIND(L_objArray); ++ // live at this point: scratch_src_klass, scratch_length, src[_pos], dst[_pos] ++ ++ Label L_plain_copy, L_checkcast_copy; ++ // test array classes for subtyping ++ __ load_klass(t2, dst); ++ __ bne(scratch_src_klass, t2, L_checkcast_copy); // usual case is exact equality ++ ++ // Identically typed arrays can be copied without element-wise checks. ++ arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, ++ t1, L_failed); ++ ++ __ shadd(from, src_pos, src, t0, LogBytesPerHeapOop); ++ __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); ++ __ shadd(to, dst_pos, dst, t0, LogBytesPerHeapOop); ++ __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); ++ __ sign_extend(count, scratch_length, 32); // length ++ __ BIND(L_plain_copy); ++ __ j(RuntimeAddress(oop_copy_entry)); ++ ++ __ BIND(L_checkcast_copy); ++ // live at this point: scratch_src_klass, scratch_length, t2 (dst_klass) ++ { ++ // Before looking at dst.length, make sure dst is also an objArray. ++ __ lwu(t0, Address(t2, lh_offset)); ++ __ mv(t1, objArray_lh); ++ __ bne(t0, t1, L_failed); ++ ++ // It is safe to examine both src.length and dst.length. ++ arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, ++ t2, L_failed); ++ ++ __ load_klass(dst_klass, dst); // reload ++ ++ // Marshal the base address arguments now, freeing registers. ++ __ shadd(from, src_pos, src, t0, LogBytesPerHeapOop); ++ __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); ++ __ shadd(to, dst_pos, dst, t0, LogBytesPerHeapOop); ++ __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); ++ __ sign_extend(count, length, 32); // length (reloaded) ++ const Register sco_temp = c_rarg3; // this register is free now ++ assert_different_registers(from, to, count, sco_temp, ++ dst_klass, scratch_src_klass); ++ ++ // Generate the type check. ++ const int sco_offset = in_bytes(Klass::super_check_offset_offset()); ++ __ lwu(sco_temp, Address(dst_klass, sco_offset)); ++ ++ // Smashes t0, t1 ++ generate_type_check(scratch_src_klass, sco_temp, dst_klass, L_plain_copy); ++ ++ // Fetch destination element klass from the ObjArrayKlass header. ++ int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset()); ++ __ ld(dst_klass, Address(dst_klass, ek_offset)); ++ __ lwu(sco_temp, Address(dst_klass, sco_offset)); ++ ++ // the checkcast_copy loop needs two extra arguments: ++ assert(c_rarg3 == sco_temp, "#3 already in place"); ++ // Set up arguments for checkcast_copy_entry. ++ __ mv(c_rarg4, dst_klass); // dst.klass.element_klass ++ __ j(RuntimeAddress(checkcast_copy_entry)); ++ } ++ ++ __ BIND(L_failed); ++ __ mv(x10, -1); ++ __ leave(); // required for proper stackwalking of RuntimeStub frame ++ __ ret(); ++ ++ return start; ++ } ++ ++ // ++ // Generate stub for array fill. If "aligned" is true, the ++ // "to" address is assumed to be heapword aligned. ++ // ++ // Arguments for generated stub: ++ // to: c_rarg0 ++ // value: c_rarg1 ++ // count: c_rarg2 treated as signed ++ // ++ address generate_fill(BasicType t, bool aligned, const char* name) { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", name); ++ address start = __ pc(); ++ ++ BLOCK_COMMENT("Entry:"); ++ ++ const Register to = c_rarg0; // source array address ++ const Register value = c_rarg1; // value ++ const Register count = c_rarg2; // elements count ++ ++ const Register bz_base = x28; // base for block_zero routine ++ const Register cnt_words = x29; // temp register ++ const Register tmp_reg = t1; ++ ++ __ enter(); ++ ++ Label L_fill_elements, L_exit1; ++ ++ int shift = -1; ++ switch (t) { ++ case T_BYTE: ++ shift = 0; ++ ++ // Zero extend value ++ // 8 bit -> 16 bit ++ __ andi(value, value, 0xff); ++ __ mv(tmp_reg, value); ++ __ slli(tmp_reg, tmp_reg, 8); ++ __ orr(value, value, tmp_reg); ++ ++ // 16 bit -> 32 bit ++ __ mv(tmp_reg, value); ++ __ slli(tmp_reg, tmp_reg, 16); ++ __ orr(value, value, tmp_reg); ++ ++ __ mv(tmp_reg, 8 >> shift); // Short arrays (< 8 bytes) fill by element ++ __ bltu(count, tmp_reg, L_fill_elements); ++ break; ++ case T_SHORT: ++ shift = 1; ++ // Zero extend value ++ // 16 bit -> 32 bit ++ __ andi(value, value, 0xffff); ++ __ mv(tmp_reg, value); ++ __ slli(tmp_reg, tmp_reg, 16); ++ __ orr(value, value, tmp_reg); ++ ++ // Short arrays (< 8 bytes) fill by element ++ __ mv(tmp_reg, 8 >> shift); ++ __ bltu(count, tmp_reg, L_fill_elements); ++ break; ++ case T_INT: ++ shift = 2; ++ ++ // Short arrays (< 8 bytes) fill by element ++ __ mv(tmp_reg, 8 >> shift); ++ __ bltu(count, tmp_reg, L_fill_elements); ++ break; ++ default: ShouldNotReachHere(); ++ } ++ ++ // Align source address at 8 bytes address boundary. ++ Label L_skip_align1, L_skip_align2, L_skip_align4; ++ if (!aligned) { ++ switch (t) { ++ case T_BYTE: ++ // One byte misalignment happens only for byte arrays. ++ __ test_bit(t0, to, 0); ++ __ beqz(t0, L_skip_align1); ++ __ sb(value, Address(to, 0)); ++ __ addi(to, to, 1); ++ __ addiw(count, count, -1); ++ __ bind(L_skip_align1); ++ // Fallthrough ++ case T_SHORT: ++ // Two bytes misalignment happens only for byte and short (char) arrays. ++ __ test_bit(t0, to, 1); ++ __ beqz(t0, L_skip_align2); ++ __ sh(value, Address(to, 0)); ++ __ addi(to, to, 2); ++ __ addiw(count, count, -(2 >> shift)); ++ __ bind(L_skip_align2); ++ // Fallthrough ++ case T_INT: ++ // Align to 8 bytes, we know we are 4 byte aligned to start. ++ __ test_bit(t0, to, 2); ++ __ beqz(t0, L_skip_align4); ++ __ sw(value, Address(to, 0)); ++ __ addi(to, to, 4); ++ __ addiw(count, count, -(4 >> shift)); ++ __ bind(L_skip_align4); ++ break; ++ default: ShouldNotReachHere(); ++ } ++ } ++ ++ // ++ // Fill large chunks ++ // ++ __ srliw(cnt_words, count, 3 - shift); // number of words ++ ++ // 32 bit -> 64 bit ++ __ andi(value, value, 0xffffffff); ++ __ mv(tmp_reg, value); ++ __ slli(tmp_reg, tmp_reg, 32); ++ __ orr(value, value, tmp_reg); ++ ++ __ slli(tmp_reg, cnt_words, 3 - shift); ++ __ subw(count, count, tmp_reg); ++ { ++ __ fill_words(to, cnt_words, value); ++ } ++ ++ // Remaining count is less than 8 bytes. Fill it by a single store. ++ // Note that the total length is no less than 8 bytes. ++ if (t == T_BYTE || t == T_SHORT) { ++ __ beqz(count, L_exit1); ++ __ shadd(to, count, to, tmp_reg, shift); // points to the end ++ __ sd(value, Address(to, -8)); // overwrite some elements ++ __ bind(L_exit1); ++ __ leave(); ++ __ ret(); ++ } ++ ++ // Handle copies less than 8 bytes. ++ Label L_fill_2, L_fill_4, L_exit2; ++ __ bind(L_fill_elements); ++ switch (t) { ++ case T_BYTE: ++ __ test_bit(t0, count, 0); ++ __ beqz(t0, L_fill_2); ++ __ sb(value, Address(to, 0)); ++ __ addi(to, to, 1); ++ __ bind(L_fill_2); ++ __ test_bit(t0, count, 1); ++ __ beqz(t0, L_fill_4); ++ __ sh(value, Address(to, 0)); ++ __ addi(to, to, 2); ++ __ bind(L_fill_4); ++ __ test_bit(t0, count, 2); ++ __ beqz(t0, L_exit2); ++ __ sw(value, Address(to, 0)); ++ break; ++ case T_SHORT: ++ __ test_bit(t0, count, 0); ++ __ beqz(t0, L_fill_4); ++ __ sh(value, Address(to, 0)); ++ __ addi(to, to, 2); ++ __ bind(L_fill_4); ++ __ test_bit(t0, count, 1); ++ __ beqz(t0, L_exit2); ++ __ sw(value, Address(to, 0)); ++ break; ++ case T_INT: ++ __ beqz(count, L_exit2); ++ __ sw(value, Address(to, 0)); ++ break; ++ default: ShouldNotReachHere(); ++ } ++ __ bind(L_exit2); ++ __ leave(); ++ __ ret(); ++ return start; ++ } ++ ++ void generate_arraycopy_stubs() { ++ address entry = NULL; ++ address entry_jbyte_arraycopy = NULL; ++ address entry_jshort_arraycopy = NULL; ++ address entry_jint_arraycopy = NULL; ++ address entry_oop_arraycopy = NULL; ++ address entry_jlong_arraycopy = NULL; ++ address entry_checkcast_arraycopy = NULL; ++ ++ generate_copy_longs(copy_f, c_rarg0, c_rarg1, t1, copy_forwards); ++ generate_copy_longs(copy_b, c_rarg0, c_rarg1, t1, copy_backwards); ++ ++ StubRoutines::riscv::_zero_blocks = generate_zero_blocks(); ++ ++ //*** jbyte ++ // Always need aligned and unaligned versions ++ StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, ++ "jbyte_disjoint_arraycopy"); ++ StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, ++ &entry_jbyte_arraycopy, ++ "jbyte_arraycopy"); ++ StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry, ++ "arrayof_jbyte_disjoint_arraycopy"); ++ StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, entry, NULL, ++ "arrayof_jbyte_arraycopy"); ++ ++ //*** jshort ++ // Always need aligned and unaligned versions ++ StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, ++ "jshort_disjoint_arraycopy"); ++ StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, ++ &entry_jshort_arraycopy, ++ "jshort_arraycopy"); ++ StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry, ++ "arrayof_jshort_disjoint_arraycopy"); ++ StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, entry, NULL, ++ "arrayof_jshort_arraycopy"); ++ ++ //*** jint ++ // Aligned versions ++ StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry, ++ "arrayof_jint_disjoint_arraycopy"); ++ StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, entry, &entry_jint_arraycopy, ++ "arrayof_jint_arraycopy"); ++ // In 64 bit we need both aligned and unaligned versions of jint arraycopy. ++ // entry_jint_arraycopy always points to the unaligned version ++ StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, &entry, ++ "jint_disjoint_arraycopy"); ++ StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, entry, ++ &entry_jint_arraycopy, ++ "jint_arraycopy"); ++ ++ //*** jlong ++ // It is always aligned ++ StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, &entry, ++ "arrayof_jlong_disjoint_arraycopy"); ++ StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_long_copy(true, entry, &entry_jlong_arraycopy, ++ "arrayof_jlong_arraycopy"); ++ StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy; ++ StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy; ++ ++ //*** oops ++ { ++ // With compressed oops we need unaligned versions; notice that ++ // we overwrite entry_oop_arraycopy. ++ bool aligned = !UseCompressedOops; ++ ++ StubRoutines::_arrayof_oop_disjoint_arraycopy ++ = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy", ++ /*dest_uninitialized*/false); ++ StubRoutines::_arrayof_oop_arraycopy ++ = generate_conjoint_oop_copy(aligned, entry, &entry_oop_arraycopy, "arrayof_oop_arraycopy", ++ /*dest_uninitialized*/false); ++ // Aligned versions without pre-barriers ++ StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit ++ = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit", ++ /*dest_uninitialized*/true); ++ StubRoutines::_arrayof_oop_arraycopy_uninit ++ = generate_conjoint_oop_copy(aligned, entry, NULL, "arrayof_oop_arraycopy_uninit", ++ /*dest_uninitialized*/true); ++ } ++ ++ StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy; ++ StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy; ++ StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit; ++ StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit; ++ ++ StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); ++ StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL, ++ /*dest_uninitialized*/true); ++ ++ ++ StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", ++ entry_jbyte_arraycopy, ++ entry_jshort_arraycopy, ++ entry_jint_arraycopy, ++ entry_jlong_arraycopy); ++ ++ StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", ++ entry_jbyte_arraycopy, ++ entry_jshort_arraycopy, ++ entry_jint_arraycopy, ++ entry_oop_arraycopy, ++ entry_jlong_arraycopy, ++ entry_checkcast_arraycopy); ++ ++ StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); ++ StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); ++ StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); ++ StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); ++ StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); ++ StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); ++ } ++ ++ // Safefetch stubs. ++ void generate_safefetch(const char* name, int size, address* entry, ++ address* fault_pc, address* continuation_pc) { ++ // safefetch signatures: ++ // int SafeFetch32(int* adr, int errValue) ++ // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue) ++ // ++ // arguments: ++ // c_rarg0 = adr ++ // c_rarg1 = errValue ++ // ++ // result: ++ // PPC_RET = *adr or errValue ++ assert_cond(entry != NULL && fault_pc != NULL && continuation_pc != NULL); ++ StubCodeMark mark(this, "StubRoutines", name); ++ ++ // Entry point, pc or function descriptor. ++ *entry = __ pc(); ++ ++ // Load *adr into c_rarg1, may fault. ++ *fault_pc = __ pc(); ++ switch (size) { ++ case 4: ++ // int32_t ++ __ lw(c_rarg1, Address(c_rarg0, 0)); ++ break; ++ case 8: ++ // int64_t ++ __ ld(c_rarg1, Address(c_rarg0, 0)); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ ++ // return errValue or *adr ++ *continuation_pc = __ pc(); ++ __ mv(x10, c_rarg1); ++ __ ret(); ++ } ++ ++ // code for comparing 16 bytes of strings with same encoding ++ void compare_string_16_bytes_same(Label &DIFF1, Label &DIFF2) { ++ const Register result = x10, str1 = x11, cnt1 = x12, str2 = x13, tmp1 = x28, tmp2 = x29, tmp4 = x7, tmp5 = x31; ++ __ ld(tmp5, Address(str1)); ++ __ addi(str1, str1, 8); ++ __ xorr(tmp4, tmp1, tmp2); ++ __ ld(cnt1, Address(str2)); ++ __ addi(str2, str2, 8); ++ __ bnez(tmp4, DIFF1); ++ __ ld(tmp1, Address(str1)); ++ __ addi(str1, str1, 8); ++ __ xorr(tmp4, tmp5, cnt1); ++ __ ld(tmp2, Address(str2)); ++ __ addi(str2, str2, 8); ++ __ bnez(tmp4, DIFF2); ++ } ++ ++ // code for comparing 8 characters of strings with Latin1 and Utf16 encoding ++ void compare_string_8_x_LU(Register tmpL, Register tmpU, Label &DIFF1, ++ Label &DIFF2) { ++ const Register strU = x12, curU = x7, strL = x29, tmp = x30; ++ __ ld(tmpL, Address(strL)); ++ __ addi(strL, strL, 8); ++ __ ld(tmpU, Address(strU)); ++ __ addi(strU, strU, 8); ++ __ inflate_lo32(tmp, tmpL); ++ __ mv(t0, tmp); ++ __ xorr(tmp, curU, t0); ++ __ bnez(tmp, DIFF2); ++ ++ __ ld(curU, Address(strU)); ++ __ addi(strU, strU, 8); ++ __ inflate_hi32(tmp, tmpL); ++ __ mv(t0, tmp); ++ __ xorr(tmp, tmpU, t0); ++ __ bnez(tmp, DIFF1); ++ } ++ ++ // x10 = result ++ // x11 = str1 ++ // x12 = cnt1 ++ // x13 = str2 ++ // x14 = cnt2 ++ // x28 = tmp1 ++ // x29 = tmp2 ++ // x30 = tmp3 ++ address generate_compare_long_string_different_encoding(bool isLU) { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", isLU ? "compare_long_string_different_encoding LU" : "compare_long_string_different_encoding UL"); ++ address entry = __ pc(); ++ Label SMALL_LOOP, TAIL, TAIL_LOAD_16, LOAD_LAST, DIFF1, DIFF2, ++ DONE, CALCULATE_DIFFERENCE; ++ const Register result = x10, str1 = x11, cnt1 = x12, str2 = x13, cnt2 = x14, ++ tmp1 = x28, tmp2 = x29, tmp3 = x30, tmp4 = x7, tmp5 = x31; ++ RegSet spilled_regs = RegSet::of(tmp4, tmp5); ++ ++ // cnt2 == amount of characters left to compare ++ // Check already loaded first 4 symbols ++ __ inflate_lo32(tmp3, isLU ? tmp1 : tmp2); ++ __ mv(isLU ? tmp1 : tmp2, tmp3); ++ __ addi(str1, str1, isLU ? wordSize / 2 : wordSize); ++ __ addi(str2, str2, isLU ? wordSize : wordSize / 2); ++ __ sub(cnt2, cnt2, 8); // Already loaded 4 symbols. Last 4 is special case. ++ __ push_reg(spilled_regs, sp); ++ ++ if (isLU) { ++ __ add(str1, str1, cnt2); ++ __ shadd(str2, cnt2, str2, t0, 1); ++ } else { ++ __ shadd(str1, cnt2, str1, t0, 1); ++ __ add(str2, str2, cnt2); ++ } ++ __ xorr(tmp3, tmp1, tmp2); ++ __ mv(tmp5, tmp2); ++ __ bnez(tmp3, CALCULATE_DIFFERENCE); ++ ++ Register strU = isLU ? str2 : str1, ++ strL = isLU ? str1 : str2, ++ tmpU = isLU ? tmp5 : tmp1, // where to keep U for comparison ++ tmpL = isLU ? tmp1 : tmp5; // where to keep L for comparison ++ ++ __ sub(tmp2, strL, cnt2); // strL pointer to load from ++ __ slli(t0, cnt2, 1); ++ __ sub(cnt1, strU, t0); // strU pointer to load from ++ ++ __ ld(tmp4, Address(cnt1)); ++ __ addi(cnt1, cnt1, 8); ++ __ beqz(cnt2, LOAD_LAST); // no characters left except last load ++ __ sub(cnt2, cnt2, 16); ++ __ bltz(cnt2, TAIL); ++ __ bind(SMALL_LOOP); // smaller loop ++ __ sub(cnt2, cnt2, 16); ++ compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2); ++ compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2); ++ __ bgez(cnt2, SMALL_LOOP); ++ __ addi(t0, cnt2, 16); ++ __ beqz(t0, LOAD_LAST); ++ __ bind(TAIL); // 1..15 characters left until last load (last 4 characters) ++ // Address of 8 bytes before last 4 characters in UTF-16 string ++ __ shadd(cnt1, cnt2, cnt1, t0, 1); ++ // Address of 16 bytes before last 4 characters in Latin1 string ++ __ add(tmp2, tmp2, cnt2); ++ __ ld(tmp4, Address(cnt1, -8)); ++ // last 16 characters before last load ++ compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2); ++ compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2); ++ __ j(LOAD_LAST); ++ __ bind(DIFF2); ++ __ mv(tmpU, tmp4); ++ __ bind(DIFF1); ++ __ mv(tmpL, t0); ++ __ j(CALCULATE_DIFFERENCE); ++ __ bind(LOAD_LAST); ++ // Last 4 UTF-16 characters are already pre-loaded into tmp4 by compare_string_8_x_LU. ++ // No need to load it again ++ __ mv(tmpU, tmp4); ++ __ ld(tmpL, Address(strL)); ++ __ inflate_lo32(tmp3, tmpL); ++ __ mv(tmpL, tmp3); ++ __ xorr(tmp3, tmpU, tmpL); ++ __ beqz(tmp3, DONE); ++ ++ // Find the first different characters in the longwords and ++ // compute their difference. ++ __ bind(CALCULATE_DIFFERENCE); ++ __ ctzc_bit(tmp4, tmp3); ++ __ srl(tmp1, tmp1, tmp4); ++ __ srl(tmp5, tmp5, tmp4); ++ __ andi(tmp1, tmp1, 0xFFFF); ++ __ andi(tmp5, tmp5, 0xFFFF); ++ __ sub(result, tmp1, tmp5); ++ __ bind(DONE); ++ __ pop_reg(spilled_regs, sp); ++ __ ret(); ++ return entry; ++ } ++ ++ address generate_method_entry_barrier() { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); ++ ++ Label deoptimize_label; ++ ++ address start = __ pc(); ++ ++ __ set_last_Java_frame(sp, fp, ra, t0); ++ ++ __ enter(); ++ __ add(t1, sp, wordSize); ++ ++ __ sub(sp, sp, 4 * wordSize); ++ ++ __ push_call_clobbered_registers(); ++ ++ __ mv(c_rarg0, t1); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetNMethod::nmethod_stub_entry_barrier), 1); ++ ++ __ reset_last_Java_frame(true); ++ ++ __ mv(t0, x10); ++ ++ __ pop_call_clobbered_registers(); ++ ++ __ bnez(t0, deoptimize_label); ++ ++ __ leave(); ++ __ ret(); ++ ++ __ BIND(deoptimize_label); ++ ++ __ ld(t0, Address(sp, 0)); ++ __ ld(fp, Address(sp, wordSize)); ++ __ ld(ra, Address(sp, wordSize * 2)); ++ __ ld(t1, Address(sp, wordSize * 3)); ++ ++ __ mv(sp, t0); ++ __ jr(t1); ++ ++ return start; ++ } ++ ++ // x10 = result ++ // x11 = str1 ++ // x12 = cnt1 ++ // x13 = str2 ++ // x14 = cnt2 ++ // x28 = tmp1 ++ // x29 = tmp2 ++ // x30 = tmp3 ++ // x31 = tmp4 ++ address generate_compare_long_string_same_encoding(bool isLL) { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", isLL ? ++ "compare_long_string_same_encoding LL" : "compare_long_string_same_encoding UU"); ++ address entry = __ pc(); ++ Label SMALL_LOOP, CHECK_LAST, DIFF2, TAIL, ++ LENGTH_DIFF, DIFF, LAST_CHECK_AND_LENGTH_DIFF; ++ const Register result = x10, str1 = x11, cnt1 = x12, str2 = x13, cnt2 = x14, ++ tmp1 = x28, tmp2 = x29, tmp3 = x30, tmp4 = x7, tmp5 = x31; ++ RegSet spilled_regs = RegSet::of(tmp4, tmp5); ++ ++ // cnt1/cnt2 contains amount of characters to compare. cnt1 can be re-used ++ // update cnt2 counter with already loaded 8 bytes ++ __ sub(cnt2, cnt2, wordSize / (isLL ? 1 : 2)); ++ // update pointers, because of previous read ++ __ add(str1, str1, wordSize); ++ __ add(str2, str2, wordSize); ++ // less than 16 bytes left? ++ __ sub(cnt2, cnt2, isLL ? 16 : 8); ++ __ push_reg(spilled_regs, sp); ++ __ bltz(cnt2, TAIL); ++ __ bind(SMALL_LOOP); ++ compare_string_16_bytes_same(DIFF, DIFF2); ++ __ sub(cnt2, cnt2, isLL ? 16 : 8); ++ __ bgez(cnt2, SMALL_LOOP); ++ __ bind(TAIL); ++ __ addi(cnt2, cnt2, isLL ? 16 : 8); ++ __ beqz(cnt2, LAST_CHECK_AND_LENGTH_DIFF); ++ __ sub(cnt2, cnt2, isLL ? 8 : 4); ++ __ blez(cnt2, CHECK_LAST); ++ __ xorr(tmp4, tmp1, tmp2); ++ __ bnez(tmp4, DIFF); ++ __ ld(tmp1, Address(str1)); ++ __ addi(str1, str1, 8); ++ __ ld(tmp2, Address(str2)); ++ __ addi(str2, str2, 8); ++ __ sub(cnt2, cnt2, isLL ? 8 : 4); ++ __ bind(CHECK_LAST); ++ if (!isLL) { ++ __ add(cnt2, cnt2, cnt2); // now in bytes ++ } ++ __ xorr(tmp4, tmp1, tmp2); ++ __ bnez(tmp4, DIFF); ++ __ add(str1, str1, cnt2); ++ __ ld(tmp5, Address(str1)); ++ __ add(str2, str2, cnt2); ++ __ ld(cnt1, Address(str2)); ++ __ xorr(tmp4, tmp5, cnt1); ++ __ beqz(tmp4, LENGTH_DIFF); ++ // Find the first different characters in the longwords and ++ // compute their difference. ++ __ bind(DIFF2); ++ __ ctzc_bit(tmp3, tmp4, isLL); // count zero from lsb to msb ++ __ srl(tmp5, tmp5, tmp3); ++ __ srl(cnt1, cnt1, tmp3); ++ if (isLL) { ++ __ andi(tmp5, tmp5, 0xFF); ++ __ andi(cnt1, cnt1, 0xFF); ++ } else { ++ __ andi(tmp5, tmp5, 0xFFFF); ++ __ andi(cnt1, cnt1, 0xFFFF); ++ } ++ __ sub(result, tmp5, cnt1); ++ __ j(LENGTH_DIFF); ++ __ bind(DIFF); ++ __ ctzc_bit(tmp3, tmp4, isLL); // count zero from lsb to msb ++ __ srl(tmp1, tmp1, tmp3); ++ __ srl(tmp2, tmp2, tmp3); ++ if (isLL) { ++ __ andi(tmp1, tmp1, 0xFF); ++ __ andi(tmp2, tmp2, 0xFF); ++ } else { ++ __ andi(tmp1, tmp1, 0xFFFF); ++ __ andi(tmp2, tmp2, 0xFFFF); ++ } ++ __ sub(result, tmp1, tmp2); ++ __ j(LENGTH_DIFF); ++ __ bind(LAST_CHECK_AND_LENGTH_DIFF); ++ __ xorr(tmp4, tmp1, tmp2); ++ __ bnez(tmp4, DIFF); ++ __ bind(LENGTH_DIFF); ++ __ pop_reg(spilled_regs, sp); ++ __ ret(); ++ return entry; ++ } ++ ++ void generate_compare_long_strings() { ++ StubRoutines::riscv::_compare_long_string_LL = generate_compare_long_string_same_encoding(true); ++ StubRoutines::riscv::_compare_long_string_UU = generate_compare_long_string_same_encoding(false); ++ StubRoutines::riscv::_compare_long_string_LU = generate_compare_long_string_different_encoding(true); ++ StubRoutines::riscv::_compare_long_string_UL = generate_compare_long_string_different_encoding(false); ++ } ++ ++ // x10 result ++ // x11 src ++ // x12 src count ++ // x13 pattern ++ // x14 pattern count ++ address generate_string_indexof_linear(bool needle_isL, bool haystack_isL) ++ { ++ const char* stubName = needle_isL ++ ? (haystack_isL ? "indexof_linear_ll" : "indexof_linear_ul") ++ : "indexof_linear_uu"; ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", stubName); ++ address entry = __ pc(); ++ ++ int needle_chr_size = needle_isL ? 1 : 2; ++ int haystack_chr_size = haystack_isL ? 1 : 2; ++ int needle_chr_shift = needle_isL ? 0 : 1; ++ int haystack_chr_shift = haystack_isL ? 0 : 1; ++ bool isL = needle_isL && haystack_isL; ++ // parameters ++ Register result = x10, haystack = x11, haystack_len = x12, needle = x13, needle_len = x14; ++ // temporary registers ++ Register mask1 = x20, match_mask = x21, first = x22, trailing_zeros = x23, mask2 = x24, tmp = x25; ++ // redefinitions ++ Register ch1 = x28, ch2 = x29; ++ RegSet spilled_regs = RegSet::range(x20, x25) + RegSet::range(x28, x29); ++ ++ __ push_reg(spilled_regs, sp); ++ ++ Label L_LOOP, L_LOOP_PROCEED, L_SMALL, L_HAS_ZERO, ++ L_HAS_ZERO_LOOP, L_CMP_LOOP, L_CMP_LOOP_NOMATCH, L_SMALL_PROCEED, ++ L_SMALL_HAS_ZERO_LOOP, L_SMALL_CMP_LOOP_NOMATCH, L_SMALL_CMP_LOOP, ++ L_POST_LOOP, L_CMP_LOOP_LAST_CMP, L_HAS_ZERO_LOOP_NOMATCH, ++ L_SMALL_CMP_LOOP_LAST_CMP, L_SMALL_CMP_LOOP_LAST_CMP2, ++ L_CMP_LOOP_LAST_CMP2, DONE, NOMATCH; ++ ++ __ ld(ch1, Address(needle)); ++ __ ld(ch2, Address(haystack)); ++ // src.length - pattern.length ++ __ sub(haystack_len, haystack_len, needle_len); ++ ++ // first is needle[0] ++ __ andi(first, ch1, needle_isL ? 0xFF : 0xFFFF, first); ++ uint64_t mask0101 = UCONST64(0x0101010101010101); ++ uint64_t mask0001 = UCONST64(0x0001000100010001); ++ __ mv(mask1, haystack_isL ? mask0101 : mask0001); ++ __ mul(first, first, mask1); ++ uint64_t mask7f7f = UCONST64(0x7f7f7f7f7f7f7f7f); ++ uint64_t mask7fff = UCONST64(0x7fff7fff7fff7fff); ++ __ mv(mask2, haystack_isL ? mask7f7f : mask7fff); ++ if (needle_isL != haystack_isL) { ++ __ mv(tmp, ch1); ++ } ++ __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size - 1); ++ __ blez(haystack_len, L_SMALL); ++ ++ if (needle_isL != haystack_isL) { ++ __ inflate_lo32(ch1, tmp, match_mask, trailing_zeros); ++ } ++ // xorr, sub, orr, notr, andr ++ // compare and set match_mask[i] with 0x80/0x8000 (Latin1/UTF16) if ch2[i] == first[i] ++ // eg: ++ // first: aa aa aa aa aa aa aa aa ++ // ch2: aa aa li nx jd ka aa aa ++ // match_mask: 80 80 00 00 00 00 80 80 ++ __ compute_match_mask(ch2, first, match_mask, mask1, mask2); ++ ++ // search first char of needle, if success, goto L_HAS_ZERO; ++ __ bnez(match_mask, L_HAS_ZERO); ++ __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size); ++ __ add(result, result, wordSize / haystack_chr_size); ++ __ add(haystack, haystack, wordSize); ++ __ bltz(haystack_len, L_POST_LOOP); ++ ++ __ bind(L_LOOP); ++ __ ld(ch2, Address(haystack)); ++ __ compute_match_mask(ch2, first, match_mask, mask1, mask2); ++ __ bnez(match_mask, L_HAS_ZERO); ++ ++ __ bind(L_LOOP_PROCEED); ++ __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size); ++ __ add(haystack, haystack, wordSize); ++ __ add(result, result, wordSize / haystack_chr_size); ++ __ bgez(haystack_len, L_LOOP); ++ ++ __ bind(L_POST_LOOP); ++ __ mv(ch2, -wordSize / haystack_chr_size); ++ __ ble(haystack_len, ch2, NOMATCH); // no extra characters to check ++ __ ld(ch2, Address(haystack)); ++ __ slli(haystack_len, haystack_len, LogBitsPerByte + haystack_chr_shift); ++ __ neg(haystack_len, haystack_len); ++ __ xorr(ch2, first, ch2); ++ __ sub(match_mask, ch2, mask1); ++ __ orr(ch2, ch2, mask2); ++ __ mv(trailing_zeros, -1); // all bits set ++ __ j(L_SMALL_PROCEED); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(L_SMALL); ++ __ slli(haystack_len, haystack_len, LogBitsPerByte + haystack_chr_shift); ++ __ neg(haystack_len, haystack_len); ++ if (needle_isL != haystack_isL) { ++ __ inflate_lo32(ch1, tmp, match_mask, trailing_zeros); ++ } ++ __ xorr(ch2, first, ch2); ++ __ sub(match_mask, ch2, mask1); ++ __ orr(ch2, ch2, mask2); ++ __ mv(trailing_zeros, -1); // all bits set ++ ++ __ bind(L_SMALL_PROCEED); ++ __ srl(trailing_zeros, trailing_zeros, haystack_len); // mask. zeroes on useless bits. ++ __ notr(ch2, ch2); ++ __ andr(match_mask, match_mask, ch2); ++ __ andr(match_mask, match_mask, trailing_zeros); // clear useless bits and check ++ __ beqz(match_mask, NOMATCH); ++ ++ __ bind(L_SMALL_HAS_ZERO_LOOP); ++ __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, ch2, tmp); // count trailing zeros ++ __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); ++ __ mv(ch2, wordSize / haystack_chr_size); ++ __ ble(needle_len, ch2, L_SMALL_CMP_LOOP_LAST_CMP2); ++ __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); ++ __ mv(trailing_zeros, wordSize / haystack_chr_size); ++ __ bne(ch1, ch2, L_SMALL_CMP_LOOP_NOMATCH); ++ ++ __ bind(L_SMALL_CMP_LOOP); ++ __ shadd(first, trailing_zeros, needle, first, needle_chr_shift); ++ __ shadd(ch2, trailing_zeros, haystack, ch2, haystack_chr_shift); ++ needle_isL ? __ lbu(first, Address(first)) : __ lhu(first, Address(first)); ++ haystack_isL ? __ lbu(ch2, Address(ch2)) : __ lhu(ch2, Address(ch2)); ++ __ add(trailing_zeros, trailing_zeros, 1); ++ __ bge(trailing_zeros, needle_len, L_SMALL_CMP_LOOP_LAST_CMP); ++ __ beq(first, ch2, L_SMALL_CMP_LOOP); ++ ++ __ bind(L_SMALL_CMP_LOOP_NOMATCH); ++ __ beqz(match_mask, NOMATCH); ++ __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, tmp, ch2); ++ __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); ++ __ add(result, result, 1); ++ __ add(haystack, haystack, haystack_chr_size); ++ __ j(L_SMALL_HAS_ZERO_LOOP); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(L_SMALL_CMP_LOOP_LAST_CMP); ++ __ bne(first, ch2, L_SMALL_CMP_LOOP_NOMATCH); ++ __ j(DONE); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(L_SMALL_CMP_LOOP_LAST_CMP2); ++ __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); ++ __ bne(ch1, ch2, L_SMALL_CMP_LOOP_NOMATCH); ++ __ j(DONE); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(L_HAS_ZERO); ++ __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, tmp, ch2); ++ __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); ++ __ slli(needle_len, needle_len, BitsPerByte * wordSize / 2); ++ __ orr(haystack_len, haystack_len, needle_len); // restore needle_len(32bits) ++ __ sub(result, result, 1); // array index from 0, so result -= 1 ++ ++ __ bind(L_HAS_ZERO_LOOP); ++ __ mv(needle_len, wordSize / haystack_chr_size); ++ __ srli(ch2, haystack_len, BitsPerByte * wordSize / 2); ++ __ bge(needle_len, ch2, L_CMP_LOOP_LAST_CMP2); ++ // load next 8 bytes from haystack, and increase result index ++ __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); ++ __ add(result, result, 1); ++ __ mv(trailing_zeros, wordSize / haystack_chr_size); ++ __ bne(ch1, ch2, L_CMP_LOOP_NOMATCH); ++ ++ // compare one char ++ __ bind(L_CMP_LOOP); ++ __ shadd(needle_len, trailing_zeros, needle, needle_len, needle_chr_shift); ++ needle_isL ? __ lbu(needle_len, Address(needle_len)) : __ lhu(needle_len, Address(needle_len)); ++ __ shadd(ch2, trailing_zeros, haystack, ch2, haystack_chr_shift); ++ haystack_isL ? __ lbu(ch2, Address(ch2)) : __ lhu(ch2, Address(ch2)); ++ __ add(trailing_zeros, trailing_zeros, 1); // next char index ++ __ srli(tmp, haystack_len, BitsPerByte * wordSize / 2); ++ __ bge(trailing_zeros, tmp, L_CMP_LOOP_LAST_CMP); ++ __ beq(needle_len, ch2, L_CMP_LOOP); ++ ++ __ bind(L_CMP_LOOP_NOMATCH); ++ __ beqz(match_mask, L_HAS_ZERO_LOOP_NOMATCH); ++ __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, needle_len, ch2); // find next "first" char index ++ __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); ++ __ add(haystack, haystack, haystack_chr_size); ++ __ j(L_HAS_ZERO_LOOP); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(L_CMP_LOOP_LAST_CMP); ++ __ bne(needle_len, ch2, L_CMP_LOOP_NOMATCH); ++ __ j(DONE); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(L_CMP_LOOP_LAST_CMP2); ++ __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); ++ __ add(result, result, 1); ++ __ bne(ch1, ch2, L_CMP_LOOP_NOMATCH); ++ __ j(DONE); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(L_HAS_ZERO_LOOP_NOMATCH); ++ // 1) Restore "result" index. Index was wordSize/str2_chr_size * N until ++ // L_HAS_ZERO block. Byte octet was analyzed in L_HAS_ZERO_LOOP, ++ // so, result was increased at max by wordSize/str2_chr_size - 1, so, ++ // respective high bit wasn't changed. L_LOOP_PROCEED will increase ++ // result by analyzed characters value, so, we can just reset lower bits ++ // in result here. Clear 2 lower bits for UU/UL and 3 bits for LL ++ // 2) restore needle_len and haystack_len values from "compressed" haystack_len ++ // 3) advance haystack value to represent next haystack octet. result & 7/3 is ++ // index of last analyzed substring inside current octet. So, haystack in at ++ // respective start address. We need to advance it to next octet ++ __ andi(match_mask, result, wordSize / haystack_chr_size - 1); ++ __ srli(needle_len, haystack_len, BitsPerByte * wordSize / 2); ++ __ andi(result, result, haystack_isL ? -8 : -4); ++ __ slli(tmp, match_mask, haystack_chr_shift); ++ __ sub(haystack, haystack, tmp); ++ __ sign_extend(haystack_len, haystack_len, 32); ++ __ j(L_LOOP_PROCEED); ++ ++ __ align(OptoLoopAlignment); ++ __ bind(NOMATCH); ++ __ mv(result, -1); ++ ++ __ bind(DONE); ++ __ pop_reg(spilled_regs, sp); ++ __ ret(); ++ return entry; ++ } ++ ++ void generate_string_indexof_stubs() ++ { ++ StubRoutines::riscv::_string_indexof_linear_ll = generate_string_indexof_linear(true, true); ++ StubRoutines::riscv::_string_indexof_linear_uu = generate_string_indexof_linear(false, false); ++ StubRoutines::riscv::_string_indexof_linear_ul = generate_string_indexof_linear(true, false); ++ } ++ ++#ifdef COMPILER2 ++ address generate_mulAdd() ++ { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", "mulAdd"); ++ ++ address entry = __ pc(); ++ ++ const Register out = x10; ++ const Register in = x11; ++ const Register offset = x12; ++ const Register len = x13; ++ const Register k = x14; ++ const Register tmp = x28; ++ ++ BLOCK_COMMENT("Entry:"); ++ __ enter(); ++ __ mul_add(out, in, offset, len, k, tmp); ++ __ leave(); ++ __ ret(); ++ ++ return entry; ++ } ++ ++ /** ++ * Arguments: ++ * ++ * Input: ++ * c_rarg0 - x address ++ * c_rarg1 - x length ++ * c_rarg2 - y address ++ * c_rarg3 - y length ++ * c_rarg4 - z address ++ * c_rarg5 - z length ++ */ ++ address generate_multiplyToLen() ++ { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", "multiplyToLen"); ++ address entry = __ pc(); ++ ++ const Register x = x10; ++ const Register xlen = x11; ++ const Register y = x12; ++ const Register ylen = x13; ++ const Register z = x14; ++ const Register zlen = x15; ++ ++ const Register tmp1 = x16; ++ const Register tmp2 = x17; ++ const Register tmp3 = x7; ++ const Register tmp4 = x28; ++ const Register tmp5 = x29; ++ const Register tmp6 = x30; ++ const Register tmp7 = x31; ++ ++ BLOCK_COMMENT("Entry:"); ++ __ enter(); // required for proper stackwalking of RuntimeStub frame ++ __ multiply_to_len(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7); ++ __ leave(); // required for proper stackwalking of RuntimeStub frame ++ __ ret(); ++ ++ return entry; ++ } ++ ++ address generate_squareToLen() ++ { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", "squareToLen"); ++ address entry = __ pc(); ++ ++ const Register x = x10; ++ const Register xlen = x11; ++ const Register z = x12; ++ const Register zlen = x13; ++ const Register y = x14; // == x ++ const Register ylen = x15; // == xlen ++ ++ const Register tmp1 = x16; ++ const Register tmp2 = x17; ++ const Register tmp3 = x7; ++ const Register tmp4 = x28; ++ const Register tmp5 = x29; ++ const Register tmp6 = x30; ++ const Register tmp7 = x31; ++ ++ BLOCK_COMMENT("Entry:"); ++ __ enter(); ++ __ mv(y, x); ++ __ mv(ylen, xlen); ++ __ multiply_to_len(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7); ++ __ leave(); ++ __ ret(); ++ ++ return entry; ++ } ++ ++ // Arguments: ++ // ++ // Input: ++ // c_rarg0 - newArr address ++ // c_rarg1 - oldArr address ++ // c_rarg2 - newIdx ++ // c_rarg3 - shiftCount ++ // c_rarg4 - numIter ++ // ++ address generate_bigIntegerLeftShift() { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", "bigIntegerLeftShiftWorker"); ++ address entry = __ pc(); ++ ++ Label loop, exit; ++ ++ Register newArr = c_rarg0; ++ Register oldArr = c_rarg1; ++ Register newIdx = c_rarg2; ++ Register shiftCount = c_rarg3; ++ Register numIter = c_rarg4; ++ ++ Register shiftRevCount = c_rarg5; ++ Register oldArrNext = t1; ++ ++ __ beqz(numIter, exit); ++ __ shadd(newArr, newIdx, newArr, t0, 2); ++ ++ __ mv(shiftRevCount, 32); ++ __ sub(shiftRevCount, shiftRevCount, shiftCount); ++ ++ __ bind(loop); ++ __ addi(oldArrNext, oldArr, 4); ++ __ vsetvli(t0, numIter, Assembler::e32, Assembler::m4); ++ __ vle32_v(v0, oldArr); ++ __ vle32_v(v4, oldArrNext); ++ __ vsll_vx(v0, v0, shiftCount); ++ __ vsrl_vx(v4, v4, shiftRevCount); ++ __ vor_vv(v0, v0, v4); ++ __ vse32_v(v0, newArr); ++ __ sub(numIter, numIter, t0); ++ __ shadd(oldArr, t0, oldArr, t1, 2); ++ __ shadd(newArr, t0, newArr, t1, 2); ++ __ bnez(numIter, loop); ++ ++ __ bind(exit); ++ __ ret(); ++ ++ return entry; ++ } ++ ++ // Arguments: ++ // ++ // Input: ++ // c_rarg0 - newArr address ++ // c_rarg1 - oldArr address ++ // c_rarg2 - newIdx ++ // c_rarg3 - shiftCount ++ // c_rarg4 - numIter ++ // ++ address generate_bigIntegerRightShift() { ++ __ align(CodeEntryAlignment); ++ StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker"); ++ address entry = __ pc(); ++ ++ Label loop, exit; ++ ++ Register newArr = c_rarg0; ++ Register oldArr = c_rarg1; ++ Register newIdx = c_rarg2; ++ Register shiftCount = c_rarg3; ++ Register numIter = c_rarg4; ++ Register idx = numIter; ++ ++ Register shiftRevCount = c_rarg5; ++ Register oldArrNext = c_rarg6; ++ Register newArrCur = t0; ++ Register oldArrCur = t1; ++ ++ __ beqz(idx, exit); ++ __ shadd(newArr, newIdx, newArr, t0, 2); ++ ++ __ mv(shiftRevCount, 32); ++ __ sub(shiftRevCount, shiftRevCount, shiftCount); ++ ++ __ bind(loop); ++ __ vsetvli(t0, idx, Assembler::e32, Assembler::m4); ++ __ sub(idx, idx, t0); ++ __ shadd(oldArrNext, idx, oldArr, t1, 2); ++ __ shadd(newArrCur, idx, newArr, t1, 2); ++ __ addi(oldArrCur, oldArrNext, 4); ++ __ vle32_v(v0, oldArrCur); ++ __ vle32_v(v4, oldArrNext); ++ __ vsrl_vx(v0, v0, shiftCount); ++ __ vsll_vx(v4, v4, shiftRevCount); ++ __ vor_vv(v0, v0, v4); ++ __ vse32_v(v0, newArrCur); ++ __ bnez(idx, loop); ++ ++ __ bind(exit); ++ __ ret(); ++ ++ return entry; ++ } ++#endif ++ ++#ifdef COMPILER2 ++ class MontgomeryMultiplyGenerator : public MacroAssembler { ++ ++ Register Pa_base, Pb_base, Pn_base, Pm_base, inv, Rlen, Ra, Rb, Rm, Rn, ++ Pa, Pb, Pn, Pm, Rhi_ab, Rlo_ab, Rhi_mn, Rlo_mn, tmp0, tmp1, tmp2, Ri, Rj; ++ ++ RegSet _toSave; ++ bool _squaring; ++ ++ public: ++ MontgomeryMultiplyGenerator (Assembler *as, bool squaring) ++ : MacroAssembler(as->code()), _squaring(squaring) { ++ ++ // Register allocation ++ ++ Register reg = c_rarg0; ++ Pa_base = reg; // Argument registers ++ if (squaring) { ++ Pb_base = Pa_base; ++ } else { ++ Pb_base = ++reg; ++ } ++ Pn_base = ++reg; ++ Rlen= ++reg; ++ inv = ++reg; ++ Pm_base = ++reg; ++ ++ // Working registers: ++ Ra = ++reg; // The current digit of a, b, n, and m. ++ Rb = ++reg; ++ Rm = ++reg; ++ Rn = ++reg; ++ ++ Pa = ++reg; // Pointers to the current/next digit of a, b, n, and m. ++ Pb = ++reg; ++ Pm = ++reg; ++ Pn = ++reg; ++ ++ tmp0 = ++reg; // Three registers which form a ++ tmp1 = ++reg; // triple-precision accumuator. ++ tmp2 = ++reg; ++ ++ Ri = x6; // Inner and outer loop indexes. ++ Rj = x7; ++ ++ Rhi_ab = x28; // Product registers: low and high parts ++ Rlo_ab = x29; // of a*b and m*n. ++ Rhi_mn = x30; ++ Rlo_mn = x31; ++ ++ // x18 and up are callee-saved. ++ _toSave = RegSet::range(x18, reg) + Pm_base; ++ } ++ ++ private: ++ void save_regs() { ++ push_reg(_toSave, sp); ++ } ++ ++ void restore_regs() { ++ pop_reg(_toSave, sp); ++ } ++ ++ template ++ void unroll_2(Register count, T block) { ++ Label loop, end, odd; ++ beqz(count, end); ++ test_bit(t0, count, 0); ++ bnez(t0, odd); ++ align(16); ++ bind(loop); ++ (this->*block)(); ++ bind(odd); ++ (this->*block)(); ++ addi(count, count, -2); ++ bgtz(count, loop); ++ bind(end); ++ } ++ ++ template ++ void unroll_2(Register count, T block, Register d, Register s, Register tmp) { ++ Label loop, end, odd; ++ beqz(count, end); ++ test_bit(tmp, count, 0); ++ bnez(tmp, odd); ++ align(16); ++ bind(loop); ++ (this->*block)(d, s, tmp); ++ bind(odd); ++ (this->*block)(d, s, tmp); ++ addi(count, count, -2); ++ bgtz(count, loop); ++ bind(end); ++ } ++ ++ void pre1(RegisterOrConstant i) { ++ block_comment("pre1"); ++ // Pa = Pa_base; ++ // Pb = Pb_base + i; ++ // Pm = Pm_base; ++ // Pn = Pn_base + i; ++ // Ra = *Pa; ++ // Rb = *Pb; ++ // Rm = *Pm; ++ // Rn = *Pn; ++ if (i.is_register()) { ++ slli(t0, i.as_register(), LogBytesPerWord); ++ } else { ++ mv(t0, i.as_constant()); ++ slli(t0, t0, LogBytesPerWord); ++ } ++ ++ mv(Pa, Pa_base); ++ add(Pb, Pb_base, t0); ++ mv(Pm, Pm_base); ++ add(Pn, Pn_base, t0); ++ ++ ld(Ra, Address(Pa)); ++ ld(Rb, Address(Pb)); ++ ld(Rm, Address(Pm)); ++ ld(Rn, Address(Pn)); ++ ++ // Zero the m*n result. ++ mv(Rhi_mn, zr); ++ mv(Rlo_mn, zr); ++ } ++ ++ // The core multiply-accumulate step of a Montgomery ++ // multiplication. The idea is to schedule operations as a ++ // pipeline so that instructions with long latencies (loads and ++ // multiplies) have time to complete before their results are ++ // used. This most benefits in-order implementations of the ++ // architecture but out-of-order ones also benefit. ++ void step() { ++ block_comment("step"); ++ // MACC(Ra, Rb, tmp0, tmp1, tmp2); ++ // Ra = *++Pa; ++ // Rb = *--Pb; ++ mulhu(Rhi_ab, Ra, Rb); ++ mul(Rlo_ab, Ra, Rb); ++ addi(Pa, Pa, wordSize); ++ ld(Ra, Address(Pa)); ++ addi(Pb, Pb, -wordSize); ++ ld(Rb, Address(Pb)); ++ acc(Rhi_mn, Rlo_mn, tmp0, tmp1, tmp2); // The pending m*n from the ++ // previous iteration. ++ // MACC(Rm, Rn, tmp0, tmp1, tmp2); ++ // Rm = *++Pm; ++ // Rn = *--Pn; ++ mulhu(Rhi_mn, Rm, Rn); ++ mul(Rlo_mn, Rm, Rn); ++ addi(Pm, Pm, wordSize); ++ ld(Rm, Address(Pm)); ++ addi(Pn, Pn, -wordSize); ++ ld(Rn, Address(Pn)); ++ acc(Rhi_ab, Rlo_ab, tmp0, tmp1, tmp2); ++ } ++ ++ void post1() { ++ block_comment("post1"); ++ ++ // MACC(Ra, Rb, tmp0, tmp1, tmp2); ++ // Ra = *++Pa; ++ // Rb = *--Pb; ++ mulhu(Rhi_ab, Ra, Rb); ++ mul(Rlo_ab, Ra, Rb); ++ acc(Rhi_mn, Rlo_mn, tmp0, tmp1, tmp2); // The pending m*n ++ acc(Rhi_ab, Rlo_ab, tmp0, tmp1, tmp2); ++ ++ // *Pm = Rm = tmp0 * inv; ++ mul(Rm, tmp0, inv); ++ sd(Rm, Address(Pm)); ++ ++ // MACC(Rm, Rn, tmp0, tmp1, tmp2); ++ // tmp0 = tmp1; tmp1 = tmp2; tmp2 = 0; ++ mulhu(Rhi_mn, Rm, Rn); ++ ++#ifndef PRODUCT ++ // assert(m[i] * n[0] + tmp0 == 0, "broken Montgomery multiply"); ++ { ++ mul(Rlo_mn, Rm, Rn); ++ add(Rlo_mn, tmp0, Rlo_mn); ++ Label ok; ++ beqz(Rlo_mn, ok); ++ stop("broken Montgomery multiply"); ++ bind(ok); ++ } ++#endif ++ // We have very carefully set things up so that ++ // m[i]*n[0] + tmp0 == 0 (mod b), so we don't have to calculate ++ // the lower half of Rm * Rn because we know the result already: ++ // it must be -tmp0. tmp0 + (-tmp0) must generate a carry iff ++ // tmp0 != 0. So, rather than do a mul and an cad we just set ++ // the carry flag iff tmp0 is nonzero. ++ // ++ // mul(Rlo_mn, Rm, Rn); ++ // cad(zr, tmp0, Rlo_mn); ++ addi(t0, tmp0, -1); ++ sltu(t0, t0, tmp0); // Set carry iff tmp0 is nonzero ++ cadc(tmp0, tmp1, Rhi_mn, t0); ++ adc(tmp1, tmp2, zr, t0); ++ mv(tmp2, zr); ++ } ++ ++ void pre2(Register i, Register len) { ++ block_comment("pre2"); ++ // Pa = Pa_base + i-len; ++ // Pb = Pb_base + len; ++ // Pm = Pm_base + i-len; ++ // Pn = Pn_base + len; ++ ++ sub(Rj, i, len); ++ // Rj == i-len ++ ++ // Ra as temp register ++ slli(Ra, Rj, LogBytesPerWord); ++ add(Pa, Pa_base, Ra); ++ add(Pm, Pm_base, Ra); ++ slli(Ra, len, LogBytesPerWord); ++ add(Pb, Pb_base, Ra); ++ add(Pn, Pn_base, Ra); ++ ++ // Ra = *++Pa; ++ // Rb = *--Pb; ++ // Rm = *++Pm; ++ // Rn = *--Pn; ++ add(Pa, Pa, wordSize); ++ ld(Ra, Address(Pa)); ++ add(Pb, Pb, -wordSize); ++ ld(Rb, Address(Pb)); ++ add(Pm, Pm, wordSize); ++ ld(Rm, Address(Pm)); ++ add(Pn, Pn, -wordSize); ++ ld(Rn, Address(Pn)); ++ ++ mv(Rhi_mn, zr); ++ mv(Rlo_mn, zr); ++ } ++ ++ void post2(Register i, Register len) { ++ block_comment("post2"); ++ sub(Rj, i, len); ++ ++ cad(tmp0, tmp0, Rlo_mn, t0); // The pending m*n, low part ++ ++ // As soon as we know the least significant digit of our result, ++ // store it. ++ // Pm_base[i-len] = tmp0; ++ // Rj as temp register ++ slli(Rj, Rj, LogBytesPerWord); ++ add(Rj, Pm_base, Rj); ++ sd(tmp0, Address(Rj)); ++ ++ // tmp0 = tmp1; tmp1 = tmp2; tmp2 = 0; ++ cadc(tmp0, tmp1, Rhi_mn, t0); // The pending m*n, high part ++ adc(tmp1, tmp2, zr, t0); ++ mv(tmp2, zr); ++ } ++ ++ // A carry in tmp0 after Montgomery multiplication means that we ++ // should subtract multiples of n from our result in m. We'll ++ // keep doing that until there is no carry. ++ void normalize(Register len) { ++ block_comment("normalize"); ++ // while (tmp0) ++ // tmp0 = sub(Pm_base, Pn_base, tmp0, len); ++ Label loop, post, again; ++ Register cnt = tmp1, i = tmp2; // Re-use registers; we're done with them now ++ beqz(tmp0, post); { ++ bind(again); { ++ mv(i, zr); ++ mv(cnt, len); ++ slli(Rn, i, LogBytesPerWord); ++ add(Rm, Pm_base, Rn); ++ ld(Rm, Address(Rm)); ++ add(Rn, Pn_base, Rn); ++ ld(Rn, Address(Rn)); ++ mv(t0, 1); // set carry flag, i.e. no borrow ++ align(16); ++ bind(loop); { ++ notr(Rn, Rn); ++ add(Rm, Rm, t0); ++ add(Rm, Rm, Rn); ++ sltu(t0, Rm, Rn); ++ slli(Rn, i, LogBytesPerWord); // Rn as temp register ++ add(Rn, Pm_base, Rn); ++ sd(Rm, Address(Rn)); ++ add(i, i, 1); ++ slli(Rn, i, LogBytesPerWord); ++ add(Rm, Pm_base, Rn); ++ ld(Rm, Address(Rm)); ++ add(Rn, Pn_base, Rn); ++ ld(Rn, Address(Rn)); ++ sub(cnt, cnt, 1); ++ } bnez(cnt, loop); ++ addi(tmp0, tmp0, -1); ++ add(tmp0, tmp0, t0); ++ } bnez(tmp0, again); ++ } bind(post); ++ } ++ ++ // Move memory at s to d, reversing words. ++ // Increments d to end of copied memory ++ // Destroys tmp1, tmp2 ++ // Preserves len ++ // Leaves s pointing to the address which was in d at start ++ void reverse(Register d, Register s, Register len, Register tmp1, Register tmp2) { ++ assert(tmp1 < x28 && tmp2 < x28, "register corruption"); ++ ++ slli(tmp1, len, LogBytesPerWord); ++ add(s, s, tmp1); ++ mv(tmp1, len); ++ unroll_2(tmp1, &MontgomeryMultiplyGenerator::reverse1, d, s, tmp2); ++ slli(tmp1, len, LogBytesPerWord); ++ sub(s, d, tmp1); ++ } ++ // [63...0] -> [31...0][63...32] ++ void reverse1(Register d, Register s, Register tmp) { ++ addi(s, s, -wordSize); ++ ld(tmp, Address(s)); ++ ror_imm(tmp, tmp, 32, t0); ++ sd(tmp, Address(d)); ++ addi(d, d, wordSize); ++ } ++ ++ void step_squaring() { ++ // An extra ACC ++ step(); ++ acc(Rhi_ab, Rlo_ab, tmp0, tmp1, tmp2); ++ } ++ ++ void last_squaring(Register i) { ++ Label dont; ++ // if ((i & 1) == 0) { ++ test_bit(t0, i, 0); ++ bnez(t0, dont); { ++ // MACC(Ra, Rb, tmp0, tmp1, tmp2); ++ // Ra = *++Pa; ++ // Rb = *--Pb; ++ mulhu(Rhi_ab, Ra, Rb); ++ mul(Rlo_ab, Ra, Rb); ++ acc(Rhi_ab, Rlo_ab, tmp0, tmp1, tmp2); ++ } bind(dont); ++ } ++ ++ void extra_step_squaring() { ++ acc(Rhi_mn, Rlo_mn, tmp0, tmp1, tmp2); // The pending m*n ++ ++ // MACC(Rm, Rn, tmp0, tmp1, tmp2); ++ // Rm = *++Pm; ++ // Rn = *--Pn; ++ mulhu(Rhi_mn, Rm, Rn); ++ mul(Rlo_mn, Rm, Rn); ++ addi(Pm, Pm, wordSize); ++ ld(Rm, Address(Pm)); ++ addi(Pn, Pn, -wordSize); ++ ld(Rn, Address(Pn)); ++ } ++ ++ void post1_squaring() { ++ acc(Rhi_mn, Rlo_mn, tmp0, tmp1, tmp2); // The pending m*n ++ ++ // *Pm = Rm = tmp0 * inv; ++ mul(Rm, tmp0, inv); ++ sd(Rm, Address(Pm)); ++ ++ // MACC(Rm, Rn, tmp0, tmp1, tmp2); ++ // tmp0 = tmp1; tmp1 = tmp2; tmp2 = 0; ++ mulhu(Rhi_mn, Rm, Rn); ++ ++#ifndef PRODUCT ++ // assert(m[i] * n[0] + tmp0 == 0, "broken Montgomery multiply"); ++ { ++ mul(Rlo_mn, Rm, Rn); ++ add(Rlo_mn, tmp0, Rlo_mn); ++ Label ok; ++ beqz(Rlo_mn, ok); { ++ stop("broken Montgomery multiply"); ++ } bind(ok); ++ } ++#endif ++ // We have very carefully set things up so that ++ // m[i]*n[0] + tmp0 == 0 (mod b), so we don't have to calculate ++ // the lower half of Rm * Rn because we know the result already: ++ // it must be -tmp0. tmp0 + (-tmp0) must generate a carry iff ++ // tmp0 != 0. So, rather than do a mul and a cad we just set ++ // the carry flag iff tmp0 is nonzero. ++ // ++ // mul(Rlo_mn, Rm, Rn); ++ // cad(zr, tmp, Rlo_mn); ++ addi(t0, tmp0, -1); ++ sltu(t0, t0, tmp0); // Set carry iff tmp0 is nonzero ++ cadc(tmp0, tmp1, Rhi_mn, t0); ++ adc(tmp1, tmp2, zr, t0); ++ mv(tmp2, zr); ++ } ++ ++ // use t0 as carry ++ void acc(Register Rhi, Register Rlo, ++ Register tmp0, Register tmp1, Register tmp2) { ++ cad(tmp0, tmp0, Rlo, t0); ++ cadc(tmp1, tmp1, Rhi, t0); ++ adc(tmp2, tmp2, zr, t0); ++ } ++ ++ public: ++ /** ++ * Fast Montgomery multiplication. The derivation of the ++ * algorithm is in A Cryptographic Library for the Motorola ++ * DSP56000, Dusse and Kaliski, Proc. EUROCRYPT 90, pp. 230-237. ++ * ++ * Arguments: ++ * ++ * Inputs for multiplication: ++ * c_rarg0 - int array elements a ++ * c_rarg1 - int array elements b ++ * c_rarg2 - int array elements n (the modulus) ++ * c_rarg3 - int length ++ * c_rarg4 - int inv ++ * c_rarg5 - int array elements m (the result) ++ * ++ * Inputs for squaring: ++ * c_rarg0 - int array elements a ++ * c_rarg1 - int array elements n (the modulus) ++ * c_rarg2 - int length ++ * c_rarg3 - int inv ++ * c_rarg4 - int array elements m (the result) ++ * ++ */ ++ address generate_multiply() { ++ Label argh, nothing; ++ bind(argh); ++ stop("MontgomeryMultiply total_allocation must be <= 8192"); ++ ++ align(CodeEntryAlignment); ++ address entry = pc(); ++ ++ beqz(Rlen, nothing); ++ ++ enter(); ++ ++ // Make room. ++ mv(Ra, 512); ++ bgt(Rlen, Ra, argh); ++ slli(Ra, Rlen, exact_log2(4 * sizeof(jint))); ++ sub(Ra, sp, Ra); ++ andi(sp, Ra, -2 * wordSize); ++ ++ srliw(Rlen, Rlen, 1); // length in longwords = len/2 ++ ++ { ++ // Copy input args, reversing as we go. We use Ra as a ++ // temporary variable. ++ reverse(Ra, Pa_base, Rlen, Ri, Rj); ++ if (!_squaring) ++ reverse(Ra, Pb_base, Rlen, Ri, Rj); ++ reverse(Ra, Pn_base, Rlen, Ri, Rj); ++ } ++ ++ // Push all call-saved registers and also Pm_base which we'll need ++ // at the end. ++ save_regs(); ++ ++#ifndef PRODUCT ++ // assert(inv * n[0] == -1UL, "broken inverse in Montgomery multiply"); ++ { ++ ld(Rn, Address(Pn_base)); ++ mul(Rlo_mn, Rn, inv); ++ mv(t0, -1); ++ Label ok; ++ beq(Rlo_mn, t0, ok); ++ stop("broken inverse in Montgomery multiply"); ++ bind(ok); ++ } ++#endif ++ ++ mv(Pm_base, Ra); ++ ++ mv(tmp0, zr); ++ mv(tmp1, zr); ++ mv(tmp2, zr); ++ ++ block_comment("for (int i = 0; i < len; i++) {"); ++ mv(Ri, zr); { ++ Label loop, end; ++ bge(Ri, Rlen, end); ++ ++ bind(loop); ++ pre1(Ri); ++ ++ block_comment(" for (j = i; j; j--) {"); { ++ mv(Rj, Ri); ++ unroll_2(Rj, &MontgomeryMultiplyGenerator::step); ++ } block_comment(" } // j"); ++ ++ post1(); ++ addw(Ri, Ri, 1); ++ blt(Ri, Rlen, loop); ++ bind(end); ++ block_comment("} // i"); ++ } ++ ++ block_comment("for (int i = len; i < 2*len; i++) {"); ++ mv(Ri, Rlen); { ++ Label loop, end; ++ slli(t0, Rlen, 1); ++ bge(Ri, t0, end); ++ ++ bind(loop); ++ pre2(Ri, Rlen); ++ ++ block_comment(" for (j = len*2-i-1; j; j--) {"); { ++ slliw(Rj, Rlen, 1); ++ subw(Rj, Rj, Ri); ++ subw(Rj, Rj, 1); ++ unroll_2(Rj, &MontgomeryMultiplyGenerator::step); ++ } block_comment(" } // j"); ++ ++ post2(Ri, Rlen); ++ addw(Ri, Ri, 1); ++ slli(t0, Rlen, 1); ++ blt(Ri, t0, loop); ++ bind(end); ++ } ++ block_comment("} // i"); ++ ++ normalize(Rlen); ++ ++ mv(Ra, Pm_base); // Save Pm_base in Ra ++ restore_regs(); // Restore caller's Pm_base ++ ++ // Copy our result into caller's Pm_base ++ reverse(Pm_base, Ra, Rlen, Ri, Rj); ++ ++ leave(); ++ bind(nothing); ++ ret(); ++ ++ return entry; ++ } ++ ++ /** ++ * ++ * Arguments: ++ * ++ * Inputs: ++ * c_rarg0 - int array elements a ++ * c_rarg1 - int array elements n (the modulus) ++ * c_rarg2 - int length ++ * c_rarg3 - int inv ++ * c_rarg4 - int array elements m (the result) ++ * ++ */ ++ address generate_square() { ++ Label argh; ++ bind(argh); ++ stop("MontgomeryMultiply total_allocation must be <= 8192"); ++ ++ align(CodeEntryAlignment); ++ address entry = pc(); ++ ++ enter(); ++ ++ // Make room. ++ mv(Ra, 512); ++ bgt(Rlen, Ra, argh); ++ slli(Ra, Rlen, exact_log2(4 * sizeof(jint))); ++ sub(Ra, sp, Ra); ++ andi(sp, Ra, -2 * wordSize); ++ ++ srliw(Rlen, Rlen, 1); // length in longwords = len/2 ++ ++ { ++ // Copy input args, reversing as we go. We use Ra as a ++ // temporary variable. ++ reverse(Ra, Pa_base, Rlen, Ri, Rj); ++ reverse(Ra, Pn_base, Rlen, Ri, Rj); ++ } ++ ++ // Push all call-saved registers and also Pm_base which we'll need ++ // at the end. ++ save_regs(); ++ ++ mv(Pm_base, Ra); ++ ++ mv(tmp0, zr); ++ mv(tmp1, zr); ++ mv(tmp2, zr); ++ ++ block_comment("for (int i = 0; i < len; i++) {"); ++ mv(Ri, zr); { ++ Label loop, end; ++ bind(loop); ++ bge(Ri, Rlen, end); ++ ++ pre1(Ri); ++ ++ block_comment("for (j = (i+1)/2; j; j--) {"); { ++ addi(Rj, Ri, 1); ++ srliw(Rj, Rj, 1); ++ unroll_2(Rj, &MontgomeryMultiplyGenerator::step_squaring); ++ } block_comment(" } // j"); ++ ++ last_squaring(Ri); ++ ++ block_comment(" for (j = i/2; j; j--) {"); { ++ srliw(Rj, Ri, 1); ++ unroll_2(Rj, &MontgomeryMultiplyGenerator::extra_step_squaring); ++ } block_comment(" } // j"); ++ ++ post1_squaring(); ++ addi(Ri, Ri, 1); ++ blt(Ri, Rlen, loop); ++ ++ bind(end); ++ block_comment("} // i"); ++ } ++ ++ block_comment("for (int i = len; i < 2*len; i++) {"); ++ mv(Ri, Rlen); { ++ Label loop, end; ++ bind(loop); ++ slli(t0, Rlen, 1); ++ bge(Ri, t0, end); ++ ++ pre2(Ri, Rlen); ++ ++ block_comment(" for (j = (2*len-i-1)/2; j; j--) {"); { ++ slli(Rj, Rlen, 1); ++ sub(Rj, Rj, Ri); ++ sub(Rj, Rj, 1); ++ srliw(Rj, Rj, 1); ++ unroll_2(Rj, &MontgomeryMultiplyGenerator::step_squaring); ++ } block_comment(" } // j"); ++ ++ last_squaring(Ri); ++ ++ block_comment(" for (j = (2*len-i)/2; j; j--) {"); { ++ slli(Rj, Rlen, 1); ++ sub(Rj, Rj, Ri); ++ srliw(Rj, Rj, 1); ++ unroll_2(Rj, &MontgomeryMultiplyGenerator::extra_step_squaring); ++ } block_comment(" } // j"); ++ ++ post2(Ri, Rlen); ++ addi(Ri, Ri, 1); ++ slli(t0, Rlen, 1); ++ blt(Ri, t0, loop); ++ ++ bind(end); ++ block_comment("} // i"); ++ } ++ ++ normalize(Rlen); ++ ++ mv(Ra, Pm_base); // Save Pm_base in Ra ++ restore_regs(); // Restore caller's Pm_base ++ ++ // Copy our result into caller's Pm_base ++ reverse(Pm_base, Ra, Rlen, Ri, Rj); ++ ++ leave(); ++ ret(); ++ ++ return entry; ++ } ++ }; ++#endif // COMPILER2 ++ ++ // Continuation point for throwing of implicit exceptions that are ++ // not handled in the current activation. Fabricates an exception ++ // oop and initiates normal exception dispatching in this ++ // frame. Since we need to preserve callee-saved values (currently ++ // only for C2, but done for C1 as well) we need a callee-saved oop ++ // map and therefore have to make these stubs into RuntimeStubs ++ // rather than BufferBlobs. If the compiler needs all registers to ++ // be preserved between the fault point and the exception handler ++ // then it must assume responsibility for that in ++ // AbstractCompiler::continuation_for_implicit_null_exception or ++ // continuation_for_implicit_division_by_zero_exception. All other ++ // implicit exceptions (e.g., NullPointerException or ++ // AbstractMethodError on entry) are either at call sites or ++ // otherwise assume that stack unwinding will be initiated, so ++ // caller saved registers were assumed volatile in the compiler. ++ ++#undef __ ++#define __ masm-> ++ ++ address generate_throw_exception(const char* name, ++ address runtime_entry, ++ Register arg1 = noreg, ++ Register arg2 = noreg) { ++ // Information about frame layout at time of blocking runtime call. ++ // Note that we only have to preserve callee-saved registers since ++ // the compilers are responsible for supplying a continuation point ++ // if they expect all registers to be preserved. ++ // n.b. riscv asserts that frame::arg_reg_save_area_bytes == 0 ++ assert_cond(runtime_entry != NULL); ++ enum layout { ++ fp_off = 0, ++ fp_off2, ++ return_off, ++ return_off2, ++ framesize // inclusive of return address ++ }; ++ ++ const int insts_size = 512; ++ const int locs_size = 64; ++ ++ CodeBuffer code(name, insts_size, locs_size); ++ OopMapSet* oop_maps = new OopMapSet(); ++ MacroAssembler* masm = new MacroAssembler(&code); ++ assert_cond(oop_maps != NULL && masm != NULL); ++ ++ address start = __ pc(); ++ ++ // This is an inlined and slightly modified version of call_VM ++ // which has the ability to fetch the return PC out of ++ // thread-local storage and also sets up last_Java_sp slightly ++ // differently than the real call_VM ++ ++ __ enter(); // Save FP and RA before call ++ ++ assert(is_even(framesize / 2), "sp not 16-byte aligned"); ++ ++ // ra and fp are already in place ++ __ addi(sp, fp, 0 - ((unsigned)framesize << LogBytesPerInt)); // prolog ++ ++ int frame_complete = __ pc() - start; ++ ++ // Set up last_Java_sp and last_Java_fp ++ address the_pc = __ pc(); ++ __ set_last_Java_frame(sp, fp, the_pc, t0); ++ ++ // Call runtime ++ if (arg1 != noreg) { ++ assert(arg2 != c_rarg1, "clobbered"); ++ __ mv(c_rarg1, arg1); ++ } ++ if (arg2 != noreg) { ++ __ mv(c_rarg2, arg2); ++ } ++ __ mv(c_rarg0, xthread); ++ BLOCK_COMMENT("call runtime_entry"); ++ __ call(runtime_entry); ++ ++ // Generate oop map ++ OopMap* map = new OopMap(framesize, 0); ++ assert_cond(map != NULL); ++ ++ oop_maps->add_gc_map(the_pc - start, map); ++ ++ __ reset_last_Java_frame(true); ++ ++ __ leave(); ++ ++ // check for pending exceptions ++#ifdef ASSERT ++ Label L; ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ bnez(t0, L); ++ __ should_not_reach_here(); ++ __ bind(L); ++#endif // ASSERT ++ __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); ++ ++ ++ // codeBlob framesize is in words (not VMRegImpl::slot_size) ++ RuntimeStub* stub = ++ RuntimeStub::new_runtime_stub(name, ++ &code, ++ frame_complete, ++ (framesize >> (LogBytesPerWord - LogBytesPerInt)), ++ oop_maps, false); ++ assert(stub != NULL, "create runtime stub fail!"); ++ return stub->entry_point(); ++ } ++ ++ // Initialization ++ void generate_initial() { ++ // Generate initial stubs and initializes the entry points ++ ++ // entry points that exist in all platforms Note: This is code ++ // that could be shared among different platforms - however the ++ // benefit seems to be smaller than the disadvantage of having a ++ // much more complicated generator structure. See also comment in ++ // stubRoutines.hpp. ++ ++ StubRoutines::_forward_exception_entry = generate_forward_exception(); ++ ++ StubRoutines::_call_stub_entry = ++ generate_call_stub(StubRoutines::_call_stub_return_address); ++ ++ // is referenced by megamorphic call ++ StubRoutines::_catch_exception_entry = generate_catch_exception(); ++ ++ // Build this early so it's available for the interpreter. ++ StubRoutines::_throw_StackOverflowError_entry = ++ generate_throw_exception("StackOverflowError throw_exception", ++ CAST_FROM_FN_PTR(address, ++ SharedRuntime::throw_StackOverflowError)); ++ StubRoutines::_throw_delayed_StackOverflowError_entry = ++ generate_throw_exception("delayed StackOverflowError throw_exception", ++ CAST_FROM_FN_PTR(address, ++ SharedRuntime::throw_delayed_StackOverflowError)); ++ // Safefetch stubs. ++ generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, ++ &StubRoutines::_safefetch32_fault_pc, ++ &StubRoutines::_safefetch32_continuation_pc); ++ generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, ++ &StubRoutines::_safefetchN_fault_pc, ++ &StubRoutines::_safefetchN_continuation_pc); ++ } ++ ++ void generate_all() { ++ // support for verify_oop (must happen after universe_init) ++ StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); ++ StubRoutines::_throw_AbstractMethodError_entry = ++ generate_throw_exception("AbstractMethodError throw_exception", ++ CAST_FROM_FN_PTR(address, ++ SharedRuntime:: ++ throw_AbstractMethodError)); ++ ++ StubRoutines::_throw_IncompatibleClassChangeError_entry = ++ generate_throw_exception("IncompatibleClassChangeError throw_exception", ++ CAST_FROM_FN_PTR(address, ++ SharedRuntime:: ++ throw_IncompatibleClassChangeError)); ++ ++ StubRoutines::_throw_NullPointerException_at_call_entry = ++ generate_throw_exception("NullPointerException at call throw_exception", ++ CAST_FROM_FN_PTR(address, ++ SharedRuntime:: ++ throw_NullPointerException_at_call)); ++ // arraycopy stubs used by compilers ++ generate_arraycopy_stubs(); ++ ++#ifdef COMPILER2 ++ if (UseMulAddIntrinsic) { ++ StubRoutines::_mulAdd = generate_mulAdd(); ++ } ++ ++ if (UseMultiplyToLenIntrinsic) { ++ StubRoutines::_multiplyToLen = generate_multiplyToLen(); ++ } ++ ++ if (UseSquareToLenIntrinsic) { ++ StubRoutines::_squareToLen = generate_squareToLen(); ++ } ++ ++ if (UseMontgomeryMultiplyIntrinsic) { ++ StubCodeMark mark(this, "StubRoutines", "montgomeryMultiply"); ++ MontgomeryMultiplyGenerator g(_masm, /*squaring*/false); ++ StubRoutines::_montgomeryMultiply = g.generate_multiply(); ++ } ++ ++ if (UseMontgomerySquareIntrinsic) { ++ StubCodeMark mark(this, "StubRoutines", "montgomerySquare"); ++ MontgomeryMultiplyGenerator g(_masm, /*squaring*/true); ++ StubRoutines::_montgomerySquare = g.generate_square(); ++ } ++ ++ if (UseRVVForBigIntegerShiftIntrinsics) { ++ StubRoutines::_bigIntegerLeftShiftWorker = generate_bigIntegerLeftShift(); ++ StubRoutines::_bigIntegerRightShiftWorker = generate_bigIntegerRightShift(); ++ } ++#endif ++ ++ generate_compare_long_strings(); ++ ++ generate_string_indexof_stubs(); ++ ++ BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); ++ if (bs_nm != NULL) { ++ StubRoutines::riscv::_method_entry_barrier = generate_method_entry_barrier(); ++ } ++ ++ StubRoutines::riscv::set_completed(); ++ } ++ ++ public: ++ StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { ++ if (all) { ++ generate_all(); ++ } else { ++ generate_initial(); ++ } ++ } ++ ++ ~StubGenerator() {} ++}; // end class declaration ++ ++#define UCM_TABLE_MAX_ENTRIES 8 ++void StubGenerator_generate(CodeBuffer* code, bool all) { ++ if (UnsafeCopyMemory::_table == NULL) { ++ UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES); ++ } ++ ++ StubGenerator g(code, all); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "runtime/deoptimization.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/thread.inline.hpp" ++#include "utilities/globalDefinitions.hpp" ++ ++// Implementation of the platform-specific part of StubRoutines - for ++// a description of how to extend it, see the stubRoutines.hpp file. ++ ++address StubRoutines::riscv::_get_previous_sp_entry = NULL; ++ ++address StubRoutines::riscv::_f2i_fixup = NULL; ++address StubRoutines::riscv::_f2l_fixup = NULL; ++address StubRoutines::riscv::_d2i_fixup = NULL; ++address StubRoutines::riscv::_d2l_fixup = NULL; ++address StubRoutines::riscv::_float_sign_mask = NULL; ++address StubRoutines::riscv::_float_sign_flip = NULL; ++address StubRoutines::riscv::_double_sign_mask = NULL; ++address StubRoutines::riscv::_double_sign_flip = NULL; ++address StubRoutines::riscv::_zero_blocks = NULL; ++address StubRoutines::riscv::_compare_long_string_LL = NULL; ++address StubRoutines::riscv::_compare_long_string_UU = NULL; ++address StubRoutines::riscv::_compare_long_string_LU = NULL; ++address StubRoutines::riscv::_compare_long_string_UL = NULL; ++address StubRoutines::riscv::_string_indexof_linear_ll = NULL; ++address StubRoutines::riscv::_string_indexof_linear_uu = NULL; ++address StubRoutines::riscv::_string_indexof_linear_ul = NULL; ++address StubRoutines::riscv::_large_byte_array_inflate = NULL; ++address StubRoutines::riscv::_method_entry_barrier = NULL; ++ ++bool StubRoutines::riscv::_completed = false; +--- /dev/null ++++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp +@@ -0,0 +1,161 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_STUBROUTINES_RISCV_HPP ++#define CPU_RISCV_STUBROUTINES_RISCV_HPP ++ ++// This file holds the platform specific parts of the StubRoutines ++// definition. See stubRoutines.hpp for a description on how to ++// extend it. ++ ++static bool returns_to_call_stub(address return_pc) { ++ return return_pc == _call_stub_return_address; ++} ++ ++enum platform_dependent_constants { ++ code_size1 = 19000, // simply increase if too small (assembler will crash if too small) ++ code_size2 = 28000 // simply increase if too small (assembler will crash if too small) ++}; ++ ++class riscv { ++ friend class StubGenerator; ++ ++ private: ++ static address _get_previous_sp_entry; ++ ++ static address _f2i_fixup; ++ static address _f2l_fixup; ++ static address _d2i_fixup; ++ static address _d2l_fixup; ++ ++ static address _float_sign_mask; ++ static address _float_sign_flip; ++ static address _double_sign_mask; ++ static address _double_sign_flip; ++ ++ static address _zero_blocks; ++ ++ static address _compare_long_string_LL; ++ static address _compare_long_string_LU; ++ static address _compare_long_string_UL; ++ static address _compare_long_string_UU; ++ static address _string_indexof_linear_ll; ++ static address _string_indexof_linear_uu; ++ static address _string_indexof_linear_ul; ++ static address _large_byte_array_inflate; ++ ++ static address _method_entry_barrier; ++ ++ static bool _completed; ++ ++ public: ++ ++ static address get_previous_sp_entry() { ++ return _get_previous_sp_entry; ++ } ++ ++ static address f2i_fixup() { ++ return _f2i_fixup; ++ } ++ ++ static address f2l_fixup() { ++ return _f2l_fixup; ++ } ++ ++ static address d2i_fixup() { ++ return _d2i_fixup; ++ } ++ ++ static address d2l_fixup() { ++ return _d2l_fixup; ++ } ++ ++ static address float_sign_mask() { ++ return _float_sign_mask; ++ } ++ ++ static address float_sign_flip() { ++ return _float_sign_flip; ++ } ++ ++ static address double_sign_mask() { ++ return _double_sign_mask; ++ } ++ ++ static address double_sign_flip() { ++ return _double_sign_flip; ++ } ++ ++ static address zero_blocks() { ++ return _zero_blocks; ++ } ++ ++ static address compare_long_string_LL() { ++ return _compare_long_string_LL; ++ } ++ ++ static address compare_long_string_LU() { ++ return _compare_long_string_LU; ++ } ++ ++ static address compare_long_string_UL() { ++ return _compare_long_string_UL; ++ } ++ ++ static address compare_long_string_UU() { ++ return _compare_long_string_UU; ++ } ++ ++ static address string_indexof_linear_ul() { ++ return _string_indexof_linear_ul; ++ } ++ ++ static address string_indexof_linear_ll() { ++ return _string_indexof_linear_ll; ++ } ++ ++ static address string_indexof_linear_uu() { ++ return _string_indexof_linear_uu; ++ } ++ ++ static address large_byte_array_inflate() { ++ return _large_byte_array_inflate; ++ } ++ ++ static address method_entry_barrier() { ++ return _method_entry_barrier; ++ } ++ ++ static bool complete() { ++ return _completed; ++ } ++ ++ static void set_completed() { ++ _completed = true; ++ } ++}; ++ ++#endif // CPU_RISCV_STUBROUTINES_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +@@ -0,0 +1,1760 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "classfile/javaClasses.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "interpreter/bytecodeHistogram.hpp" ++#include "interpreter/bytecodeTracer.hpp" ++#include "interpreter/interp_masm.hpp" ++#include "interpreter/interpreter.hpp" ++#include "interpreter/interpreterRuntime.hpp" ++#include "interpreter/templateInterpreterGenerator.hpp" ++#include "interpreter/templateTable.hpp" ++#include "memory/resourceArea.hpp" ++#include "oops/arrayOop.hpp" ++#include "oops/method.hpp" ++#include "oops/methodData.hpp" ++#include "oops/oop.inline.hpp" ++#include "prims/jvmtiExport.hpp" ++#include "prims/jvmtiThreadState.hpp" ++#include "runtime/arguments.hpp" ++#include "runtime/deoptimization.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/jniHandles.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/synchronizer.hpp" ++#include "runtime/timer.hpp" ++#include "runtime/vframeArray.hpp" ++#include "utilities/debug.hpp" ++#include "utilities/powerOfTwo.hpp" ++#include ++ ++#ifndef PRODUCT ++#include "oops/method.hpp" ++#endif // !PRODUCT ++ ++// Size of interpreter code. Increase if too small. Interpreter will ++// fail with a guarantee ("not enough space for interpreter generation"); ++// if too small. ++// Run with +PrintInterpreter to get the VM to print out the size. ++// Max size with JVMTI ++int TemplateInterpreter::InterpreterCodeSize = 256 * 1024; ++ ++#define __ _masm-> ++ ++//----------------------------------------------------------------------------- ++ ++address TemplateInterpreterGenerator::generate_slow_signature_handler() { ++ address entry = __ pc(); ++ ++ __ andi(esp, esp, -16); ++ __ mv(c_rarg3, esp); ++ // xmethod ++ // xlocals ++ // c_rarg3: first stack arg - wordSize ++ // adjust sp ++ ++ __ addi(sp, c_rarg3, -18 * wordSize); ++ __ addi(sp, sp, -2 * wordSize); ++ __ sd(ra, Address(sp, 0)); ++ ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::slow_signature_handler), ++ xmethod, xlocals, c_rarg3); ++ ++ // x10: result handler ++ ++ // Stack layout: ++ // sp: return address <- sp ++ // 1 garbage ++ // 8 integer args (if static first is unused) ++ // 1 float/double identifiers ++ // 8 double args ++ // stack args <- esp ++ // garbage ++ // expression stack bottom ++ // bcp (NULL) ++ // ... ++ ++ // Restore ra ++ __ ld(ra, Address(sp, 0)); ++ __ addi(sp, sp , 2 * wordSize); ++ ++ // Do FP first so we can use c_rarg3 as temp ++ __ lwu(c_rarg3, Address(sp, 9 * wordSize)); // float/double identifiers ++ ++ for (int i = 0; i < Argument::n_float_register_parameters_c; i++) { ++ const FloatRegister r = g_FPArgReg[i]; ++ Label d, done; ++ ++ __ test_bit(t0, c_rarg3, i); ++ __ bnez(t0, d); ++ __ flw(r, Address(sp, (10 + i) * wordSize)); ++ __ j(done); ++ __ bind(d); ++ __ fld(r, Address(sp, (10 + i) * wordSize)); ++ __ bind(done); ++ } ++ ++ // c_rarg0 contains the result from the call of ++ // InterpreterRuntime::slow_signature_handler so we don't touch it ++ // here. It will be loaded with the JNIEnv* later. ++ for (int i = 1; i < Argument::n_int_register_parameters_c; i++) { ++ const Register rm = g_INTArgReg[i]; ++ __ ld(rm, Address(sp, i * wordSize)); ++ } ++ ++ __ addi(sp, sp, 18 * wordSize); ++ __ ret(); ++ ++ return entry; ++} ++ ++// Various method entries ++address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { ++ // xmethod: Method* ++ // x30: sender sp ++ // esp: args ++ ++ if (!InlineIntrinsics) { ++ return NULL; // Generate a vanilla entry ++ } ++ ++ // These don't need a safepoint check because they aren't virtually ++ // callable. We won't enter these intrinsics from compiled code. ++ // If in the future we added an intrinsic which was virtually callable ++ // we'd have to worry about how to safepoint so that this code is used. ++ ++ // mathematical functions inlined by compiler ++ // (interpreter must provide identical implementation ++ // in order to avoid monotonicity bugs when switching ++ // from interpreter to compiler in the middle of some ++ // computation) ++ // ++ // stack: ++ // [ arg ] <-- esp ++ // [ arg ] ++ // retaddr in ra ++ ++ address fn = NULL; ++ address entry_point = NULL; ++ Register continuation = ra; ++ switch (kind) { ++ case Interpreter::java_lang_math_abs: ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ fabs_d(f10, f10); ++ __ mv(sp, x30); // Restore caller's SP ++ break; ++ case Interpreter::java_lang_math_sqrt: ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ fsqrt_d(f10, f10); ++ __ mv(sp, x30); ++ break; ++ case Interpreter::java_lang_math_sin : ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ mv(sp, x30); ++ __ mv(x9, ra); ++ continuation = x9; // The first callee-saved register ++ if (StubRoutines::dsin() == NULL) { ++ fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); ++ } else { ++ fn = CAST_FROM_FN_PTR(address, StubRoutines::dsin()); ++ } ++ __ call(fn); ++ break; ++ case Interpreter::java_lang_math_cos : ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ mv(sp, x30); ++ __ mv(x9, ra); ++ continuation = x9; // The first callee-saved register ++ if (StubRoutines::dcos() == NULL) { ++ fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); ++ } else { ++ fn = CAST_FROM_FN_PTR(address, StubRoutines::dcos()); ++ } ++ __ call(fn); ++ break; ++ case Interpreter::java_lang_math_tan : ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ mv(sp, x30); ++ __ mv(x9, ra); ++ continuation = x9; // The first callee-saved register ++ if (StubRoutines::dtan() == NULL) { ++ fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); ++ } else { ++ fn = CAST_FROM_FN_PTR(address, StubRoutines::dtan()); ++ } ++ __ call(fn); ++ break; ++ case Interpreter::java_lang_math_log : ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ mv(sp, x30); ++ __ mv(x9, ra); ++ continuation = x9; // The first callee-saved register ++ if (StubRoutines::dlog() == NULL) { ++ fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); ++ } else { ++ fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog()); ++ } ++ __ call(fn); ++ break; ++ case Interpreter::java_lang_math_log10 : ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ mv(sp, x30); ++ __ mv(x9, ra); ++ continuation = x9; // The first callee-saved register ++ if (StubRoutines::dlog10() == NULL) { ++ fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); ++ } else { ++ fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog10()); ++ } ++ __ call(fn); ++ break; ++ case Interpreter::java_lang_math_exp : ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp)); ++ __ mv(sp, x30); ++ __ mv(x9, ra); ++ continuation = x9; // The first callee-saved register ++ if (StubRoutines::dexp() == NULL) { ++ fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); ++ } else { ++ fn = CAST_FROM_FN_PTR(address, StubRoutines::dexp()); ++ } ++ __ call(fn); ++ break; ++ case Interpreter::java_lang_math_pow : ++ entry_point = __ pc(); ++ __ mv(x9, ra); ++ continuation = x9; ++ __ fld(f10, Address(esp, 2 * Interpreter::stackElementSize)); ++ __ fld(f11, Address(esp)); ++ __ mv(sp, x30); ++ if (StubRoutines::dpow() == NULL) { ++ fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); ++ } else { ++ fn = CAST_FROM_FN_PTR(address, StubRoutines::dpow()); ++ } ++ __ call(fn); ++ break; ++ case Interpreter::java_lang_math_fmaD : ++ if (UseFMA) { ++ entry_point = __ pc(); ++ __ fld(f10, Address(esp, 4 * Interpreter::stackElementSize)); ++ __ fld(f11, Address(esp, 2 * Interpreter::stackElementSize)); ++ __ fld(f12, Address(esp)); ++ __ fmadd_d(f10, f10, f11, f12); ++ __ mv(sp, x30); // Restore caller's SP ++ } ++ break; ++ case Interpreter::java_lang_math_fmaF : ++ if (UseFMA) { ++ entry_point = __ pc(); ++ __ flw(f10, Address(esp, 2 * Interpreter::stackElementSize)); ++ __ flw(f11, Address(esp, Interpreter::stackElementSize)); ++ __ flw(f12, Address(esp)); ++ __ fmadd_s(f10, f10, f11, f12); ++ __ mv(sp, x30); // Restore caller's SP ++ } ++ break; ++ default: ++ ; ++ } ++ if (entry_point != NULL) { ++ __ jr(continuation); ++ } ++ ++ return entry_point; ++} ++ ++// Abstract method entry ++// Attempt to execute abstract method. Throw exception ++address TemplateInterpreterGenerator::generate_abstract_entry(void) { ++ // xmethod: Method* ++ // x30: sender SP ++ ++ address entry_point = __ pc(); ++ ++ // abstract method entry ++ ++ // pop return address, reset last_sp to NULL ++ __ empty_expression_stack(); ++ __ restore_bcp(); // bcp must be correct for exception handler (was destroyed) ++ __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) ++ ++ // throw exception ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_AbstractMethodErrorWithMethod), ++ xmethod); ++ // the call_VM checks for exception, so we should never return here. ++ __ should_not_reach_here(); ++ ++ return entry_point; ++} ++ ++address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { ++ address entry = __ pc(); ++ ++#ifdef ASSERT ++ { ++ Label L; ++ __ ld(t0, Address(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); ++ __ mv(t1, sp); ++ // maximal sp for current fp (stack grows negative) ++ // check if frame is complete ++ __ bge(t0, t1, L); ++ __ stop ("interpreter frame not set up"); ++ __ bind(L); ++ } ++#endif // ASSERT ++ // Restore bcp under the assumption that the current frame is still ++ // interpreted ++ __ restore_bcp(); ++ ++ // expression stack must be empty before entering the VM if an ++ // exception happened ++ __ empty_expression_stack(); ++ // throw exception ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); ++ return entry; ++} ++ ++address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler() { ++ address entry = __ pc(); ++ // expression stack must be empty before entering the VM if an ++ // exception happened ++ __ empty_expression_stack(); ++ // setup parameters ++ ++ // convention: expect aberrant index in register x11 ++ __ zero_extend(c_rarg2, x11, 32); ++ // convention: expect array in register x13 ++ __ mv(c_rarg1, x13); ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime:: ++ throw_ArrayIndexOutOfBoundsException), ++ c_rarg1, c_rarg2); ++ return entry; ++} ++ ++address TemplateInterpreterGenerator::generate_ClassCastException_handler() { ++ address entry = __ pc(); ++ ++ // object is at TOS ++ __ pop_reg(c_rarg1); ++ ++ // expression stack must be empty before entering the VM if an ++ // exception happened ++ __ empty_expression_stack(); ++ ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime:: ++ throw_ClassCastException), ++ c_rarg1); ++ return entry; ++} ++ ++address TemplateInterpreterGenerator::generate_exception_handler_common( ++ const char* name, const char* message, bool pass_oop) { ++ assert(!pass_oop || message == NULL, "either oop or message but not both"); ++ address entry = __ pc(); ++ if (pass_oop) { ++ // object is at TOS ++ __ pop_reg(c_rarg2); ++ } ++ // expression stack must be empty before entering the VM if an ++ // exception happened ++ __ empty_expression_stack(); ++ // setup parameters ++ __ la(c_rarg1, Address((address)name)); ++ if (pass_oop) { ++ __ call_VM(x10, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime:: ++ create_klass_exception), ++ c_rarg1, c_rarg2); ++ } else { ++ // kind of lame ExternalAddress can't take NULL because ++ // external_word_Relocation will assert. ++ if (message != NULL) { ++ __ la(c_rarg2, Address((address)message)); ++ } else { ++ __ mv(c_rarg2, NULL_WORD); ++ } ++ __ call_VM(x10, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), ++ c_rarg1, c_rarg2); ++ } ++ // throw exception ++ __ j(address(Interpreter::throw_exception_entry())); ++ return entry; ++} ++ ++address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) { ++ address entry = __ pc(); ++ ++ // Restore stack bottom in case i2c adjusted stack ++ __ ld(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ // and NULL it as marker that esp is now tos until next java call ++ __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ __ restore_bcp(); ++ __ restore_locals(); ++ __ restore_constant_pool_cache(); ++ __ get_method(xmethod); ++ ++ if (state == atos) { ++ Register obj = x10; ++ Register mdp = x11; ++ Register tmp = x12; ++ __ ld(mdp, Address(xmethod, Method::method_data_offset())); ++ __ profile_return_type(mdp, obj, tmp); ++ } ++ ++ // Pop N words from the stack ++ __ get_cache_and_index_at_bcp(x11, x12, 1, index_size); ++ __ ld(x11, Address(x11, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); ++ __ andi(x11, x11, ConstantPoolCacheEntry::parameter_size_mask); ++ ++ __ shadd(esp, x11, esp, t0, 3); ++ ++ // Restore machine SP ++ __ ld(t0, Address(xmethod, Method::const_offset())); ++ __ lhu(t0, Address(t0, ConstMethod::max_stack_offset())); ++ __ addi(t0, t0, frame::interpreter_frame_monitor_size() + 2); ++ __ ld(t1, ++ Address(fp, frame::interpreter_frame_initial_sp_offset * wordSize)); ++ __ slli(t0, t0, 3); ++ __ sub(t0, t1, t0); ++ __ andi(sp, t0, -16); ++ ++ __ check_and_handle_popframe(xthread); ++ __ check_and_handle_earlyret(xthread); ++ ++ __ get_dispatch(); ++ __ dispatch_next(state, step); ++ ++ return entry; ++} ++ ++address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, ++ int step, ++ address continuation) { ++ address entry = __ pc(); ++ __ restore_bcp(); ++ __ restore_locals(); ++ __ restore_constant_pool_cache(); ++ __ get_method(xmethod); ++ __ get_dispatch(); ++ ++ // Calculate stack limit ++ __ ld(t0, Address(xmethod, Method::const_offset())); ++ __ lhu(t0, Address(t0, ConstMethod::max_stack_offset())); ++ __ addi(t0, t0, frame::interpreter_frame_monitor_size() + 2); ++ __ ld(t1, Address(fp, frame::interpreter_frame_initial_sp_offset * wordSize)); ++ __ slli(t0, t0, 3); ++ __ sub(t0, t1, t0); ++ __ andi(sp, t0, -16); ++ ++ // Restore expression stack pointer ++ __ ld(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ // NULL last_sp until next java call ++ __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ ++ // handle exceptions ++ { ++ Label L; ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ beqz(t0, L); ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); ++ __ should_not_reach_here(); ++ __ bind(L); ++ } ++ ++ if (continuation == NULL) { ++ __ dispatch_next(state, step); ++ } else { ++ __ jump_to_entry(continuation); ++ } ++ return entry; ++} ++ ++address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) { ++ address entry = __ pc(); ++ if (type == T_OBJECT) { ++ // retrieve result from frame ++ __ ld(x10, Address(fp, frame::interpreter_frame_oop_temp_offset * wordSize)); ++ // and verify it ++ __ verify_oop(x10); ++ } else { ++ __ cast_primitive_type(type, x10); ++ } ++ ++ __ ret(); // return from result handler ++ return entry; ++} ++ ++address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, ++ address runtime_entry) { ++ assert_cond(runtime_entry != NULL); ++ address entry = __ pc(); ++ __ push(state); ++ __ call_VM(noreg, runtime_entry); ++ __ membar(MacroAssembler::AnyAny); ++ __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos)); ++ return entry; ++} ++ ++// Helpers for commoning out cases in the various type of method entries. ++// ++ ++ ++// increment invocation count & check for overflow ++// ++// Note: checking for negative value instead of overflow ++// so we have a 'sticky' overflow test ++// ++// xmethod: method ++// ++void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow) { ++ Label done; ++ // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. ++ int increment = InvocationCounter::count_increment; ++ Label no_mdo; ++ if (ProfileInterpreter) { ++ // Are we profiling? ++ __ ld(x10, Address(xmethod, Method::method_data_offset())); ++ __ beqz(x10, no_mdo); ++ // Increment counter in the MDO ++ const Address mdo_invocation_counter(x10, in_bytes(MethodData::invocation_counter_offset()) + ++ in_bytes(InvocationCounter::counter_offset())); ++ const Address mask(x10, in_bytes(MethodData::invoke_mask_offset())); ++ __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, t0, t1, false, overflow); ++ __ j(done); ++ } ++ __ bind(no_mdo); ++ // Increment counter in MethodCounters ++ const Address invocation_counter(t1, ++ MethodCounters::invocation_counter_offset() + ++ InvocationCounter::counter_offset()); ++ __ get_method_counters(xmethod, t1, done); ++ const Address mask(t1, in_bytes(MethodCounters::invoke_mask_offset())); ++ __ increment_mask_and_jump(invocation_counter, increment, mask, t0, x11, false, overflow); ++ __ bind(done); ++} ++ ++void TemplateInterpreterGenerator::generate_counter_overflow(Label& do_continue) { ++ __ mv(c_rarg1, zr); ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), c_rarg1); ++ __ j(do_continue); ++} ++ ++// See if we've got enough room on the stack for locals plus overhead ++// below JavaThread::stack_overflow_limit(). If not, throw a StackOverflowError ++// without going through the signal handler, i.e., reserved and yellow zones ++// will not be made usable. The shadow zone must suffice to handle the ++// overflow. ++// The expression stack grows down incrementally, so the normal guard ++// page mechanism will work for that. ++// ++// NOTE: Since the additional locals are also always pushed (wasn't ++// obvious in generate_method_entry) so the guard should work for them ++// too. ++// ++// Args: ++// x13: number of additional locals this frame needs (what we must check) ++// xmethod: Method* ++// ++// Kills: ++// x10 ++void TemplateInterpreterGenerator::generate_stack_overflow_check(void) { ++ ++ // 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; ++ ++ // total overhead size: entry_size + (saved fp through expr stack ++ // bottom). be sure to change this if you add/subtract anything ++ // to/from the overhead area ++ const int overhead_size = ++ -(frame::interpreter_frame_initial_sp_offset * wordSize) + entry_size; ++ ++ const int page_size = os::vm_page_size(); ++ ++ Label after_frame_check; ++ ++ // see if the frame is greater than one page in size. If so, ++ // then we need to verify there is enough stack space remaining ++ // for the additional locals. ++ __ mv(t0, (page_size - overhead_size) / Interpreter::stackElementSize); ++ __ bleu(x13, t0, after_frame_check); ++ ++ // compute sp as if this were going to be the last frame on ++ // the stack before the red zone ++ ++ // locals + overhead, in bytes ++ __ mv(x10, overhead_size); ++ __ shadd(x10, x13, x10, t0, Interpreter::logStackElementSize); // 2 slots per parameter. ++ ++ const Address stack_limit(xthread, JavaThread::stack_overflow_limit_offset()); ++ __ ld(t0, stack_limit); ++ ++#ifdef ASSERT ++ Label limit_okay; ++ // Verify that thread stack limit is non-zero. ++ __ bnez(t0, limit_okay); ++ __ stop("stack overflow limit is zero"); ++ __ bind(limit_okay); ++#endif ++ ++ // Add stack limit to locals. ++ __ add(x10, x10, t0); ++ ++ // Check against the current stack bottom. ++ __ bgtu(sp, x10, after_frame_check); ++ ++ // Remove the incoming args, peeling the machine SP back to where it ++ // was in the caller. This is not strictly necessary, but unless we ++ // do so the stack frame may have a garbage FP; this ensures a ++ // correct call stack that we can always unwind. The ANDI should be ++ // unnecessary because the sender SP in x30 is always aligned, but ++ // it doesn't hurt. ++ __ andi(sp, x30, -16); ++ ++ // Note: the restored frame is not necessarily interpreted. ++ // Use the shared runtime version of the StackOverflowError. ++ assert(StubRoutines::throw_StackOverflowError_entry() != NULL, "stub not yet generated"); ++ __ far_jump(RuntimeAddress(StubRoutines::throw_StackOverflowError_entry())); ++ ++ // all done with frame size check ++ __ bind(after_frame_check); ++} ++ ++// Allocate monitor and lock method (asm interpreter) ++// ++// Args: ++// xmethod: Method* ++// xlocals: locals ++// ++// Kills: ++// x10 ++// c_rarg0, c_rarg1, c_rarg2, c_rarg3, ...(param regs) ++// t0, t1 (temporary regs) ++void TemplateInterpreterGenerator::lock_method() { ++ // 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; ++ ++#ifdef ASSERT ++ __ lwu(x10, access_flags); ++ __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method doesn't need synchronization", false); ++#endif // ASSERT ++ ++ // get synchronization object ++ { ++ Label done; ++ __ lwu(x10, access_flags); ++ __ andi(t0, x10, JVM_ACC_STATIC); ++ // get receiver (assume this is frequent case) ++ __ ld(x10, Address(xlocals, Interpreter::local_offset_in_bytes(0))); ++ __ beqz(t0, done); ++ __ load_mirror(x10, xmethod); ++ ++#ifdef ASSERT ++ { ++ Label L; ++ __ bnez(x10, L); ++ __ stop("synchronization object is NULL"); ++ __ bind(L); ++ } ++#endif // ASSERT ++ ++ __ bind(done); ++ } ++ ++ // add space for monitor & lock ++ __ add(sp, sp, - entry_size); // add space for a monitor entry ++ __ add(esp, esp, - entry_size); ++ __ mv(t0, esp); ++ __ sd(t0, monitor_block_top); // set new monitor block top ++ // store object ++ __ sd(x10, Address(esp, BasicObjectLock::obj_offset_in_bytes())); ++ __ mv(c_rarg1, esp); // object address ++ __ lock_object(c_rarg1); ++} ++ ++// Generate a fixed interpreter frame. This is identical setup for ++// interpreted methods and for native methods hence the shared code. ++// ++// Args: ++// ra: return address ++// xmethod: Method* ++// xlocals: pointer to locals ++// xcpool: cp cache ++// stack_pointer: previous sp ++void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { ++ // initialize fixed part of activation frame ++ if (native_call) { ++ __ add(esp, sp, - 14 * wordSize); ++ __ mv(xbcp, zr); ++ __ add(sp, sp, - 14 * wordSize); ++ // add 2 zero-initialized slots for native calls ++ __ sd(zr, Address(sp, 13 * wordSize)); ++ __ sd(zr, Address(sp, 12 * wordSize)); ++ } else { ++ __ add(esp, sp, - 12 * wordSize); ++ __ ld(t0, Address(xmethod, Method::const_offset())); // get ConstMethod ++ __ add(xbcp, t0, in_bytes(ConstMethod::codes_offset())); // get codebase ++ __ add(sp, sp, - 12 * wordSize); ++ } ++ __ sd(xbcp, Address(sp, wordSize)); ++ __ sd(esp, Address(sp, 0)); ++ ++ if (ProfileInterpreter) { ++ Label method_data_continue; ++ __ ld(t0, Address(xmethod, Method::method_data_offset())); ++ __ beqz(t0, method_data_continue); ++ __ la(t0, Address(t0, in_bytes(MethodData::data_offset()))); ++ __ bind(method_data_continue); ++ } ++ ++ __ sd(xmethod, Address(sp, 7 * wordSize)); ++ __ sd(ProfileInterpreter ? t0 : zr, Address(sp, 6 * wordSize)); ++ ++ // Get mirror and store it in the frame as GC root for this Method* ++ __ load_mirror(t2, xmethod); ++ __ sd(zr, Address(sp, 5 * wordSize)); ++ __ sd(t2, Address(sp, 4 * wordSize)); ++ ++ __ ld(xcpool, Address(xmethod, Method::const_offset())); ++ __ ld(xcpool, Address(xcpool, ConstMethod::constants_offset())); ++ __ ld(xcpool, Address(xcpool, ConstantPool::cache_offset_in_bytes())); ++ __ sd(xcpool, Address(sp, 3 * wordSize)); ++ __ sd(xlocals, Address(sp, 2 * wordSize)); ++ ++ __ sd(ra, Address(sp, 11 * wordSize)); ++ __ sd(fp, Address(sp, 10 * wordSize)); ++ __ la(fp, Address(sp, 12 * wordSize)); // include ra & fp ++ ++ // set sender sp ++ // leave last_sp as null ++ __ sd(x30, Address(sp, 9 * wordSize)); ++ __ sd(zr, Address(sp, 8 * wordSize)); ++ ++ // Move SP out of the way ++ if (!native_call) { ++ __ ld(t0, Address(xmethod, Method::const_offset())); ++ __ lhu(t0, Address(t0, ConstMethod::max_stack_offset())); ++ __ add(t0, t0, frame::interpreter_frame_monitor_size() + 2); ++ __ slli(t0, t0, 3); ++ __ sub(t0, sp, t0); ++ __ andi(sp, t0, -16); ++ } ++} ++ ++// End of helpers ++ ++// Various method entries ++//------------------------------------------------------------------------------------------------------------------------ ++// ++// ++ ++// Method entry for java.lang.ref.Reference.get. ++address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { ++ // Code: _aload_0, _getfield, _areturn ++ // parameter size = 1 ++ // ++ // The code that gets generated by this routine is split into 2 parts: ++ // 1. The "intrinsified" code for G1 (or any SATB based GC), ++ // 2. The slow path - which is an expansion of the regular method entry. ++ // ++ // Notes:- ++ // * In the G1 code we do not check whether we need to block for ++ // a safepoint. If G1 is enabled then we must execute the specialized ++ // code for Reference.get (except when the Reference object is null) ++ // so that we can log the value in the referent field with an SATB ++ // update buffer. ++ // If the code for the getfield template is modified so that the ++ // G1 pre-barrier code is executed when the current method is ++ // Reference.get() then going through the normal method entry ++ // will be fine. ++ // * The G1 code can, however, check the receiver object (the instance ++ // of java.lang.Reference) and jump to the slow path if null. If the ++ // Reference object is null then we obviously cannot fetch the referent ++ // and so we don't need to call the G1 pre-barrier. Thus we can use the ++ // regular method entry code to generate the NPE. ++ // ++ // This code is based on generate_accessor_entry. ++ // ++ // xmethod: Method* ++ // x30: senderSP must preserve for slow path, set SP to it on fast path ++ ++ // ra is live. It must be saved around calls. ++ ++ address entry = __ pc(); ++ ++ const int referent_offset = java_lang_ref_Reference::referent_offset(); ++ guarantee(referent_offset > 0, "referent offset not initialized"); ++ ++ Label slow_path; ++ const Register local_0 = c_rarg0; ++ // Check if local 0 != NULL ++ // If the receiver is null then it is OK to jump to the slow path. ++ __ ld(local_0, Address(esp, 0)); ++ __ beqz(local_0, slow_path); ++ ++ __ mv(x9, x30); // Move senderSP to a callee-saved register ++ ++ // Load the value of the referent field. ++ const Address field_address(local_0, referent_offset); ++ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); ++ bs->load_at(_masm, IN_HEAP | ON_WEAK_OOP_REF, T_OBJECT, local_0, field_address, /*tmp1*/ t1, /*tmp2*/ t0); ++ ++ // areturn ++ __ andi(sp, x9, -16); // done with stack ++ __ ret(); ++ ++ // generate a vanilla interpreter entry as the slow path ++ __ bind(slow_path); ++ __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals)); ++ return entry; ++} ++ ++/** ++ * Method entry for static native methods: ++ * int java.util.zip.CRC32.update(int crc, int b) ++ */ ++address TemplateInterpreterGenerator::generate_CRC32_update_entry() { ++ // TODO: Unimplemented generate_CRC32_update_entry ++ return 0; ++} ++ ++/** ++ * Method entry for static native methods: ++ * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) ++ * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) ++ */ ++address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { ++ // TODO: Unimplemented generate_CRC32_updateBytes_entry ++ return 0; ++} ++ ++/** ++ * Method entry for intrinsic-candidate (non-native) methods: ++ * int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end) ++ * int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long buf, int off, int end) ++ * Unlike CRC32, CRC32C does not have any methods marked as native ++ * CRC32C also uses an "end" variable instead of the length variable CRC32 uses ++ */ ++address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { ++ // TODO: Unimplemented generate_CRC32C_updateBytes_entry ++ return 0; ++} ++ ++void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) { ++ // Bang each page in the shadow zone. We can't assume it's been done for ++ // an interpreter frame with greater than a page of locals, so each page ++ // needs to be checked. Only true for non-native. ++ const int n_shadow_pages = (int)(StackOverflow::stack_shadow_zone_size() / os::vm_page_size()); ++ const int start_page = native_call ? n_shadow_pages : 1; ++ const int page_size = os::vm_page_size(); ++ for (int pages = start_page; pages <= n_shadow_pages ; pages++) { ++ __ sub(t1, sp, pages * page_size); ++ __ sd(zr, Address(t1)); ++ } ++} ++ ++// Interpreter stub for calling a native method. (asm interpreter) ++// This sets up a somewhat different looking stack for calling the ++// native method than the typical interpreter frame setup. ++address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { ++ // determine code generation flags ++ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; ++ ++ // x11: Method* ++ // x30: sender sp ++ ++ address entry_point = __ pc(); ++ ++ const Address constMethod (xmethod, Method::const_offset()); ++ const Address access_flags (xmethod, Method::access_flags_offset()); ++ const Address size_of_parameters(x12, ConstMethod:: ++ size_of_parameters_offset()); ++ ++ // get parameter size (always needed) ++ __ ld(x12, constMethod); ++ __ load_unsigned_short(x12, size_of_parameters); ++ ++ // Native calls don't need the stack size check since they have no ++ // expression stack and the arguments are already on the stack and ++ // we only add a handful of words to the stack. ++ ++ // xmethod: Method* ++ // x12: size of parameters ++ // x30: sender sp ++ ++ // for natives the size of locals is zero ++ ++ // compute beginning of parameters (xlocals) ++ __ shadd(xlocals, x12, esp, xlocals, 3); ++ __ addi(xlocals, xlocals, -wordSize); ++ ++ // Pull SP back to minimum size: this avoids holes in the stack ++ __ andi(sp, esp, -16); ++ ++ // initialize fixed part of activation frame ++ generate_fixed_frame(true); ++ ++ // make sure method is native & not abstract ++#ifdef ASSERT ++ __ lwu(x10, access_flags); ++ __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute non-native method as native", false); ++ __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); ++#endif ++ ++ // Since at this point in the method invocation the exception ++ // handler would try to exit the monitor of synchronized methods ++ // which hasn't been entered yet, we set the thread local variable ++ // _do_not_unlock_if_synchronized to true. The remove_activation ++ // will check this flag. ++ ++ const Address do_not_unlock_if_synchronized(xthread, ++ in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); ++ __ mv(t1, true); ++ __ sb(t1, do_not_unlock_if_synchronized); ++ ++ // increment invocation count & check for overflow ++ Label invocation_counter_overflow; ++ if (inc_counter) { ++ generate_counter_incr(&invocation_counter_overflow); ++ } ++ ++ Label continue_after_compile; ++ __ bind(continue_after_compile); ++ ++ bang_stack_shadow_pages(true); ++ ++ // reset the _do_not_unlock_if_synchronized flag ++ __ sb(zr, do_not_unlock_if_synchronized); ++ ++ // check for synchronized methods ++ // Must happen AFTER invocation_counter check and stack overflow check, ++ // so method is not locked if overflows. ++ if (synchronized) { ++ lock_method(); ++ } else { ++ // no synchronization necessary ++#ifdef ASSERT ++ __ lwu(x10, access_flags); ++ __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); ++#endif ++ } ++ ++ // start execution ++#ifdef ASSERT ++ __ verify_frame_setup(); ++#endif ++ ++ // jvmti support ++ __ notify_method_entry(); ++ ++ // work registers ++ const Register t = x18; ++ const Register result_handler = x19; ++ ++ // allocate space for parameters ++ __ ld(t, Address(xmethod, Method::const_offset())); ++ __ load_unsigned_short(t, Address(t, ConstMethod::size_of_parameters_offset())); ++ ++ __ slli(t, t, Interpreter::logStackElementSize); ++ __ sub(x30, esp, t); ++ __ andi(sp, x30, -16); ++ __ mv(esp, x30); ++ ++ // get signature handler ++ { ++ Label L; ++ __ ld(t, Address(xmethod, Method::signature_handler_offset())); ++ __ bnez(t, L); ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::prepare_native_call), ++ xmethod); ++ __ ld(t, Address(xmethod, Method::signature_handler_offset())); ++ __ bind(L); ++ } ++ ++ // call signature handler ++ assert(InterpreterRuntime::SignatureHandlerGenerator::from() == xlocals, ++ "adjust this code"); ++ assert(InterpreterRuntime::SignatureHandlerGenerator::to() == sp, ++ "adjust this code"); ++ assert(InterpreterRuntime::SignatureHandlerGenerator::temp() == t0, ++ "adjust this code"); ++ ++ // The generated handlers do not touch xmethod (the method). ++ // However, large signatures cannot be cached and are generated ++ // each time here. The slow-path generator can do a GC on return, ++ // so we must reload it after the call. ++ __ jalr(t); ++ __ get_method(xmethod); // slow path can do a GC, reload xmethod ++ ++ ++ // result handler is in x10 ++ // set result handler ++ __ mv(result_handler, x10); ++ // pass mirror handle if static call ++ { ++ Label L; ++ __ lwu(t, Address(xmethod, Method::access_flags_offset())); ++ __ test_bit(t0, t, exact_log2(JVM_ACC_STATIC)); ++ __ beqz(t0, L); ++ // get mirror ++ __ load_mirror(t, xmethod); ++ // copy mirror into activation frame ++ __ sd(t, Address(fp, frame::interpreter_frame_oop_temp_offset * wordSize)); ++ // pass handle to mirror ++ __ addi(c_rarg1, fp, frame::interpreter_frame_oop_temp_offset * wordSize); ++ __ bind(L); ++ } ++ ++ // get native function entry point in x28 ++ { ++ Label L; ++ __ ld(x28, Address(xmethod, Method::native_function_offset())); ++ address unsatisfied = (SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); ++ __ mv(t1, unsatisfied); ++ __ ld(t1, Address(t1, 0)); ++ __ bne(x28, t1, L); ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::prepare_native_call), ++ xmethod); ++ __ get_method(xmethod); ++ __ ld(x28, Address(xmethod, Method::native_function_offset())); ++ __ bind(L); ++ } ++ ++ // pass JNIEnv ++ __ add(c_rarg0, xthread, in_bytes(JavaThread::jni_environment_offset())); ++ ++ // It is enough that the pc() points into the right code ++ // segment. It does not have to be the correct return pc. ++ Label native_return; ++ __ set_last_Java_frame(esp, fp, native_return, x30); ++ ++ // change thread state ++#ifdef ASSERT ++ { ++ Label L; ++ __ lwu(t, Address(xthread, JavaThread::thread_state_offset())); ++ __ addi(t0, zr, (u1)_thread_in_Java); ++ __ beq(t, t0, L); ++ __ stop("Wrong thread state in native stub"); ++ __ bind(L); ++ } ++#endif ++ ++ // Change state to native ++ __ la(t1, Address(xthread, JavaThread::thread_state_offset())); ++ __ mv(t0, _thread_in_native); ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ __ sw(t0, Address(t1)); ++ ++ // Call the native method. ++ __ jalr(x28); ++ __ bind(native_return); ++ __ get_method(xmethod); ++ // result potentially in x10 or f10 ++ ++ // make room for the pushes we're about to do ++ __ sub(t0, esp, 4 * wordSize); ++ __ andi(sp, t0, -16); ++ ++ // NOTE: The order of these pushes is known to frame::interpreter_frame_result ++ // in order to extract the result of a method call. If the order of these ++ // pushes change or anything else is added to the stack then the code in ++ // interpreter_frame_result must also change. ++ __ push(dtos); ++ __ push(ltos); ++ ++ // change thread state ++ // Force all preceding writes to be observed prior to thread state change ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ ++ __ mv(t0, _thread_in_native_trans); ++ __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); ++ ++ // Force this write out before the read below ++ __ membar(MacroAssembler::AnyAny); ++ ++ // check for safepoint operation in progress and/or pending suspend requests ++ { ++ Label L, Continue; ++ ++ // We need an acquire here to ensure that any subsequent load of the ++ // global SafepointSynchronize::_state flag is ordered after this load ++ // of the thread-local polling word. We don't want this poll to ++ // return false (i.e. not safepointing) and a later poll of the global ++ // SafepointSynchronize::_state spuriously to return true. ++ // ++ // This is to avoid a race when we're in a native->Java transition ++ // racing the code which wakes up from a safepoint. ++ __ safepoint_poll(L, true /* at_return */, true /* acquire */, false /* in_nmethod */); ++ __ lwu(t1, Address(xthread, JavaThread::suspend_flags_offset())); ++ __ beqz(t1, Continue); ++ __ bind(L); ++ ++ // Don't use call_VM as it will see a possible pending exception ++ // and forward it and never return here preventing us from ++ // clearing _last_native_pc down below. So we do a runtime call by ++ // hand. ++ // ++ __ mv(c_rarg0, xthread); ++ __ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); ++ __ get_method(xmethod); ++ __ reinit_heapbase(); ++ __ bind(Continue); ++ } ++ ++ // change thread state ++ // Force all preceding writes to be observed prior to thread state change ++ __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); ++ ++ __ mv(t0, _thread_in_Java); ++ __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); ++ ++ // reset_last_Java_frame ++ __ reset_last_Java_frame(true); ++ ++ if (CheckJNICalls) { ++ // clear_pending_jni_exception_check ++ __ sd(zr, Address(xthread, JavaThread::pending_jni_exception_check_fn_offset())); ++ } ++ ++ // reset handle block ++ __ ld(t, Address(xthread, JavaThread::active_handles_offset())); ++ __ sd(zr, Address(t, JNIHandleBlock::top_offset_in_bytes())); ++ ++ // If result is an oop unbox and store it in frame where gc will see it ++ // and result handler will pick it up ++ ++ { ++ Label no_oop; ++ __ la(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); ++ __ bne(t, result_handler, no_oop); ++ // Unbox oop result, e.g. JNIHandles::resolve result. ++ __ pop(ltos); ++ __ resolve_jobject(x10, xthread, t); ++ __ sd(x10, Address(fp, frame::interpreter_frame_oop_temp_offset * wordSize)); ++ // keep stack depth as expected by pushing oop which will eventually be discarded ++ __ push(ltos); ++ __ bind(no_oop); ++ } ++ ++ { ++ Label no_reguard; ++ __ lwu(t0, Address(xthread, in_bytes(JavaThread::stack_guard_state_offset()))); ++ __ addi(t1, zr, (u1)StackOverflow::stack_guard_yellow_reserved_disabled); ++ __ bne(t0, t1, no_reguard); ++ ++ __ push_call_clobbered_registers(); ++ __ mv(c_rarg0, xthread); ++ __ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); ++ __ pop_call_clobbered_registers(); ++ __ bind(no_reguard); ++ } ++ ++ // The method register is junk from after the thread_in_native transition ++ // until here. Also can't call_VM until the bcp has been ++ // restored. Need bcp for throwing exception below so get it now. ++ __ get_method(xmethod); ++ ++ // restore bcp to have legal interpreter frame, i.e., bci == 0 <=> ++ // xbcp == code_base() ++ __ ld(xbcp, Address(xmethod, Method::const_offset())); // get ConstMethod* ++ __ add(xbcp, xbcp, in_bytes(ConstMethod::codes_offset())); // get codebase ++ // handle exceptions (exception handling will handle unlocking!) ++ { ++ Label L; ++ __ ld(t0, Address(xthread, Thread::pending_exception_offset())); ++ __ beqz(t0, L); ++ // Note: At some point we may want to unify this with the code ++ // used in call_VM_base(); i.e., we should use the ++ // StubRoutines::forward_exception code. For now this doesn't work ++ // here because the sp is not correctly set at this point. ++ __ MacroAssembler::call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_pending_exception)); ++ __ should_not_reach_here(); ++ __ bind(L); ++ } ++ ++ // do unlocking if necessary ++ { ++ Label L; ++ __ lwu(t, Address(xmethod, Method::access_flags_offset())); ++ __ test_bit(t0, t, exact_log2(JVM_ACC_SYNCHRONIZED)); ++ __ beqz(t0, L); ++ // the code below should be shared with interpreter macro ++ // assembler implementation ++ { ++ Label unlock; ++ // BasicObjectLock will be first in list, since this is a ++ // synchronized method. However, need to check that the object ++ // has not been unlocked by an explicit monitorexit bytecode. ++ ++ // monitor expect in c_rarg1 for slow unlock path ++ __ la(c_rarg1, Address(fp, // address of first monitor ++ (intptr_t)(frame::interpreter_frame_initial_sp_offset * ++ wordSize - sizeof(BasicObjectLock)))); ++ ++ __ ld(t, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); ++ __ bnez(t, unlock); ++ ++ // Entry already unlocked, need to throw exception ++ __ MacroAssembler::call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_illegal_monitor_state_exception)); ++ __ should_not_reach_here(); ++ ++ __ bind(unlock); ++ __ unlock_object(c_rarg1); ++ } ++ __ bind(L); ++ } ++ ++ // jvmti support ++ // Note: This must happen _after_ handling/throwing any exceptions since ++ // the exception handler code notifies the runtime of method exits ++ // too. If this happens before, method entry/exit notifications are ++ // not properly paired (was bug - gri 11/22/99). ++ __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI); ++ ++ __ pop(ltos); ++ __ pop(dtos); ++ ++ __ jalr(result_handler); ++ ++ // remove activation ++ __ ld(esp, Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp ++ // remove frame anchor ++ __ leave(); ++ ++ // restore sender sp ++ __ mv(sp, esp); ++ ++ __ ret(); ++ ++ if (inc_counter) { ++ // Handle overflow of counter and compile method ++ __ bind(invocation_counter_overflow); ++ generate_counter_overflow(continue_after_compile); ++ } ++ ++ return entry_point; ++} ++ ++// ++// Generic interpreted method entry to (asm) interpreter ++// ++address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { ++ ++ // determine code generation flags ++ const bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; ++ ++ // t0: sender sp ++ address entry_point = __ pc(); ++ ++ const Address constMethod(xmethod, Method::const_offset()); ++ const Address access_flags(xmethod, Method::access_flags_offset()); ++ const Address size_of_parameters(x13, ++ ConstMethod::size_of_parameters_offset()); ++ const Address size_of_locals(x13, ConstMethod::size_of_locals_offset()); ++ ++ // get parameter size (always needed) ++ // need to load the const method first ++ __ ld(x13, constMethod); ++ __ load_unsigned_short(x12, size_of_parameters); ++ ++ // x12: size of parameters ++ ++ __ load_unsigned_short(x13, size_of_locals); // get size of locals in words ++ __ sub(x13, x13, x12); // x13 = no. of additional locals ++ ++ // see if we've got enough room on the stack for locals plus overhead. ++ generate_stack_overflow_check(); ++ ++ // compute beginning of parameters (xlocals) ++ __ shadd(xlocals, x12, esp, t1, 3); ++ __ add(xlocals, xlocals, -wordSize); ++ ++ // Make room for additional locals ++ __ slli(t1, x13, 3); ++ __ sub(t0, esp, t1); ++ ++ // Padding between locals and fixed part of activation frame to ensure ++ // SP is always 16-byte aligned. ++ __ andi(sp, t0, -16); ++ ++ // x13 - # of additional locals ++ // allocate space for locals ++ // explicitly initialize locals ++ { ++ Label exit, loop; ++ __ blez(x13, exit); // do nothing if x13 <= 0 ++ __ bind(loop); ++ __ sd(zr, Address(t0)); ++ __ add(t0, t0, wordSize); ++ __ add(x13, x13, -1); // until everything initialized ++ __ bnez(x13, loop); ++ __ bind(exit); ++ } ++ ++ // And the base dispatch table ++ __ get_dispatch(); ++ ++ // initialize fixed part of activation frame ++ generate_fixed_frame(false); ++ ++ // make sure method is not native & not abstract ++#ifdef ASSERT ++ __ lwu(x10, access_flags); ++ __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute native method as non-native"); ++ __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); ++#endif ++ ++ // Since at this point in the method invocation the exception ++ // handler would try to exit the monitor of synchronized methods ++ // which hasn't been entered yet, we set the thread local variable ++ // _do_not_unlock_if_synchronized to true. The remove_activation ++ // will check this flag. ++ ++ const Address do_not_unlock_if_synchronized(xthread, ++ in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); ++ __ mv(t1, true); ++ __ sb(t1, do_not_unlock_if_synchronized); ++ ++ Label no_mdp; ++ const Register mdp = x13; ++ __ ld(mdp, Address(xmethod, Method::method_data_offset())); ++ __ beqz(mdp, no_mdp); ++ __ add(mdp, mdp, in_bytes(MethodData::data_offset())); ++ __ profile_parameters_type(mdp, x11, x12, x14); // use x11, x12, x14 as tmp registers ++ __ bind(no_mdp); ++ ++ // increment invocation count & check for overflow ++ Label invocation_counter_overflow; ++ if (inc_counter) { ++ generate_counter_incr(&invocation_counter_overflow); ++ } ++ ++ Label continue_after_compile; ++ __ bind(continue_after_compile); ++ ++ bang_stack_shadow_pages(false); ++ ++ // reset the _do_not_unlock_if_synchronized flag ++ __ sb(zr, do_not_unlock_if_synchronized); ++ ++ // check for synchronized methods ++ // Must happen AFTER invocation_counter check and stack overflow check, ++ // so method is not locked if overflows. ++ if (synchronized) { ++ // Allocate monitor and lock method ++ lock_method(); ++ } else { ++ // no synchronization necessary ++#ifdef ASSERT ++ __ lwu(x10, access_flags); ++ __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); ++#endif ++ } ++ ++ // start execution ++#ifdef ASSERT ++ __ verify_frame_setup(); ++#endif ++ ++ // jvmti support ++ __ notify_method_entry(); ++ ++ __ dispatch_next(vtos); ++ ++ // invocation counter overflow ++ if (inc_counter) { ++ // Handle overflow of counter and compile method ++ __ bind(invocation_counter_overflow); ++ generate_counter_overflow(continue_after_compile); ++ } ++ ++ return entry_point; ++} ++ ++//----------------------------------------------------------------------------- ++// Exceptions ++ ++void TemplateInterpreterGenerator::generate_throw_exception() { ++ // Entry point in previous activation (i.e., if the caller was ++ // interpreted) ++ Interpreter::_rethrow_exception_entry = __ pc(); ++ // Restore sp to interpreter_frame_last_sp even though we are going ++ // to empty the expression stack for the exception processing. ++ __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ // x10: exception ++ // x13: return address/pc that threw exception ++ __ restore_bcp(); // xbcp points to call/send ++ __ restore_locals(); ++ __ restore_constant_pool_cache(); ++ __ reinit_heapbase(); // restore xheapbase as heapbase. ++ __ get_dispatch(); ++ ++ // Entry point for exceptions thrown within interpreter code ++ Interpreter::_throw_exception_entry = __ pc(); ++ // If we came here via a NullPointerException on the receiver of a ++ // method, xthread may be corrupt. ++ __ get_method(xmethod); ++ // expression stack is undefined here ++ // x10: exception ++ // xbcp: exception bcp ++ __ verify_oop(x10); ++ __ mv(c_rarg1, x10); ++ ++ // expression stack must be empty before entering the VM in case of ++ // an exception ++ __ empty_expression_stack(); ++ // find exception handler address and preserve exception oop ++ __ call_VM(x13, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::exception_handler_for_exception), ++ c_rarg1); ++ ++ // Calculate stack limit ++ __ ld(t0, Address(xmethod, Method::const_offset())); ++ __ lhu(t0, Address(t0, ConstMethod::max_stack_offset())); ++ __ add(t0, t0, frame::interpreter_frame_monitor_size() + 4); ++ __ ld(t1, Address(fp, frame::interpreter_frame_initial_sp_offset * wordSize)); ++ __ slli(t0, t0, 3); ++ __ sub(t0, t1, t0); ++ __ andi(sp, t0, -16); ++ ++ // x10: exception handler entry point ++ // x13: preserved exception oop ++ // xbcp: bcp for exception handler ++ __ push_ptr(x13); // push exception which is now the only value on the stack ++ __ jr(x10); // jump to exception handler (may be _remove_activation_entry!) ++ ++ // If the exception is not handled in the current frame the frame is ++ // removed and the exception is rethrown (i.e. exception ++ // continuation is _rethrow_exception). ++ // ++ // Note: At this point the bci is still the bxi for the instruction ++ // which caused the exception and the expression stack is ++ // empty. Thus, for any VM calls at this point, GC will find a legal ++ // oop map (with empty expression stack). ++ ++ // ++ // JVMTI PopFrame support ++ // ++ ++ Interpreter::_remove_activation_preserving_args_entry = __ pc(); ++ __ empty_expression_stack(); ++ // Set the popframe_processing bit in pending_popframe_condition ++ // indicating that we are currently handling popframe, so that ++ // call_VMs that may happen later do not trigger new popframe ++ // handling cycles. ++ __ lwu(x13, Address(xthread, JavaThread::popframe_condition_offset())); ++ __ ori(x13, x13, JavaThread::popframe_processing_bit); ++ __ sw(x13, Address(xthread, JavaThread::popframe_condition_offset())); ++ ++ { ++ // Check to see whether we are returning to a deoptimized frame. ++ // (The PopFrame call ensures that the caller of the popped frame is ++ // either interpreted or compiled and deoptimizes it if compiled.) ++ // In this case, we can't call dispatch_next() after the frame is ++ // popped, but instead must save the incoming arguments and restore ++ // them after deoptimization has occurred. ++ // ++ // Note that we don't compare the return PC against the ++ // deoptimization blob's unpack entry because of the presence of ++ // adapter frames in C2. ++ Label caller_not_deoptimized; ++ __ ld(c_rarg1, Address(fp, frame::return_addr_offset * wordSize)); ++ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), c_rarg1); ++ __ bnez(x10, caller_not_deoptimized); ++ ++ // Compute size of arguments for saving when returning to ++ // deoptimized caller ++ __ get_method(x10); ++ __ ld(x10, Address(x10, Method::const_offset())); ++ __ load_unsigned_short(x10, Address(x10, in_bytes(ConstMethod:: ++ size_of_parameters_offset()))); ++ __ slli(x10, x10, Interpreter::logStackElementSize); ++ __ restore_locals(); ++ __ sub(xlocals, xlocals, x10); ++ __ add(xlocals, xlocals, wordSize); ++ // Save these arguments ++ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ++ Deoptimization:: ++ popframe_preserve_args), ++ xthread, x10, xlocals); ++ ++ __ remove_activation(vtos, ++ /* throw_monitor_exception */ false, ++ /* install_monitor_exception */ false, ++ /* notify_jvmdi */ false); ++ ++ // Inform deoptimization that it is responsible for restoring ++ // these arguments ++ __ mv(t0, JavaThread::popframe_force_deopt_reexecution_bit); ++ __ sw(t0, Address(xthread, JavaThread::popframe_condition_offset())); ++ ++ // Continue in deoptimization handler ++ __ ret(); ++ ++ __ bind(caller_not_deoptimized); ++ } ++ ++ __ remove_activation(vtos, ++ /* throw_monitor_exception */ false, ++ /* install_monitor_exception */ false, ++ /* notify_jvmdi */ false); ++ ++ // Restore the last_sp and null it out ++ __ ld(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); ++ ++ __ restore_bcp(); ++ __ restore_locals(); ++ __ restore_constant_pool_cache(); ++ __ get_method(xmethod); ++ __ get_dispatch(); ++ ++ // The method data pointer was incremented already during ++ // call profiling. We have to restore the mdp for the current bcp. ++ if (ProfileInterpreter) { ++ __ set_method_data_pointer_for_bcp(); ++ } ++ ++ // Clear the popframe condition flag ++ __ sw(zr, Address(xthread, JavaThread::popframe_condition_offset())); ++ assert(JavaThread::popframe_inactive == 0, "fix popframe_inactive"); ++ ++#if INCLUDE_JVMTI ++ { ++ Label L_done; ++ ++ __ lbu(t0, Address(xbcp, 0)); ++ __ mv(t1, Bytecodes::_invokestatic); ++ __ bne(t1, t0, L_done); ++ ++ // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. ++ // Detect such a case in the InterpreterRuntime function and return the member name argument,or NULL. ++ ++ __ ld(c_rarg0, Address(xlocals, 0)); ++ __ call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null),c_rarg0, xmethod, xbcp); ++ ++ __ beqz(x10, L_done); ++ ++ __ sd(x10, Address(esp, 0)); ++ __ bind(L_done); ++ } ++#endif // INCLUDE_JVMTI ++ ++ // Restore machine SP ++ __ ld(t0, Address(xmethod, Method::const_offset())); ++ __ lhu(t0, Address(t0, ConstMethod::max_stack_offset())); ++ __ add(t0, t0, frame::interpreter_frame_monitor_size() + 4); ++ __ ld(t1, Address(fp, frame::interpreter_frame_initial_sp_offset * wordSize)); ++ __ slliw(t0, t0, 3); ++ __ sub(t0, t1, t0); ++ __ andi(sp, t0, -16); ++ ++ __ dispatch_next(vtos); ++ // end of PopFrame support ++ ++ Interpreter::_remove_activation_entry = __ pc(); ++ ++ // preserve exception over this code sequence ++ __ pop_ptr(x10); ++ __ sd(x10, Address(xthread, JavaThread::vm_result_offset())); ++ // remove the activation (without doing throws on illegalMonitorExceptions) ++ __ remove_activation(vtos, false, true, false); ++ // restore exception ++ __ get_vm_result(x10, xthread); ++ ++ // In between activations - previous activation type unknown yet ++ // compute continuation point - the continuation point expects the ++ // following registers set up: ++ // ++ // x10: exception ++ // ra: return address/pc that threw exception ++ // sp: expression stack of caller ++ // fp: fp of caller ++ // FIXME: There's no point saving ra here because VM calls don't trash it ++ __ sub(sp, sp, 2 * wordSize); ++ __ sd(x10, Address(sp, 0)); // save exception ++ __ sd(ra, Address(sp, wordSize)); // save return address ++ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ++ SharedRuntime::exception_handler_for_return_address), ++ xthread, ra); ++ __ mv(x11, x10); // save exception handler ++ __ ld(x10, Address(sp, 0)); // restore exception ++ __ ld(ra, Address(sp, wordSize)); // restore return address ++ __ add(sp, sp, 2 * wordSize); ++ // We might be returning to a deopt handler that expects x13 to ++ // contain the exception pc ++ __ mv(x13, ra); ++ // Note that an "issuing PC" is actually the next PC after the call ++ __ jr(x11); // jump to exception ++ // handler of caller ++} ++ ++// ++// JVMTI ForceEarlyReturn support ++// ++address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) { ++ address entry = __ pc(); ++ ++ __ restore_bcp(); ++ __ restore_locals(); ++ __ empty_expression_stack(); ++ __ load_earlyret_value(state); ++ ++ __ ld(t0, Address(xthread, JavaThread::jvmti_thread_state_offset())); ++ Address cond_addr(t0, JvmtiThreadState::earlyret_state_offset()); ++ ++ // Clear the earlyret state ++ assert(JvmtiThreadState::earlyret_inactive == 0, "should be"); ++ __ sd(zr, cond_addr); ++ ++ __ remove_activation(state, ++ false, /* throw_monitor_exception */ ++ false, /* install_monitor_exception */ ++ true); /* notify_jvmdi */ ++ __ ret(); ++ ++ return entry; ++} ++// end of ForceEarlyReturn support ++ ++//----------------------------------------------------------------------------- ++// Helper for vtos entry point generation ++ ++void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, ++ address& bep, ++ address& cep, ++ address& sep, ++ address& aep, ++ address& iep, ++ address& lep, ++ address& fep, ++ address& dep, ++ address& vep) { ++ assert(t != NULL && t->is_valid() && t->tos_in() == vtos, "illegal template"); ++ Label L; ++ aep = __ pc(); __ push_ptr(); __ j(L); ++ fep = __ pc(); __ push_f(); __ j(L); ++ dep = __ pc(); __ push_d(); __ j(L); ++ lep = __ pc(); __ push_l(); __ j(L); ++ bep = cep = sep = ++ iep = __ pc(); __ push_i(); ++ vep = __ pc(); ++ __ bind(L); ++ generate_and_dispatch(t); ++} ++ ++//----------------------------------------------------------------------------- ++ ++// Non-product code ++#ifndef PRODUCT ++address TemplateInterpreterGenerator::generate_trace_code(TosState state) { ++ address entry = __ pc(); ++ ++ __ push_reg(ra); ++ __ push(state); ++ __ push_reg(RegSet::range(x10, x17) + RegSet::range(x5, x7) + RegSet::range(x28, x31), sp); ++ __ mv(c_rarg2, x10); // Pass itos ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), c_rarg1, c_rarg2, c_rarg3); ++ __ pop_reg(RegSet::range(x10, x17) + RegSet::range(x5, x7) + RegSet::range(x28, x31), sp); ++ __ pop(state); ++ __ pop_reg(ra); ++ __ ret(); // return from result handler ++ ++ return entry; ++} ++ ++void TemplateInterpreterGenerator::count_bytecode() { ++ __ push_reg(t0); ++ __ push_reg(x10); ++ __ mv(x10, (address) &BytecodeCounter::_counter_value); ++ __ mv(t0, 1); ++ __ amoadd_d(zr, x10, t0, Assembler::aqrl); ++ __ pop_reg(x10); ++ __ pop_reg(t0); ++} ++ ++void TemplateInterpreterGenerator::histogram_bytecode(Template* t) { ; } ++ ++void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) { ; } ++ ++void TemplateInterpreterGenerator::trace_bytecode(Template* t) { ++ // Call a little run-time stub to avoid blow-up for each bytecode. ++ // The run-time runtime saves the right registers, depending on ++ // the tosca in-state for the given template. ++ ++ assert(Interpreter::trace_code(t->tos_in()) != NULL, "entry must have been generated"); ++ __ jal(Interpreter::trace_code(t->tos_in())); ++ __ reinit_heapbase(); ++} ++ ++void TemplateInterpreterGenerator::stop_interpreter_at() { ++ Label L; ++ __ push_reg(t0); ++ __ mv(t0, (address) &BytecodeCounter::_counter_value); ++ __ ld(t0, Address(t0)); ++ __ mv(t1, StopInterpreterAt); ++ __ bne(t0, t1, L); ++ __ ebreak(); ++ __ bind(L); ++ __ pop_reg(t0); ++} ++ ++#endif // !PRODUCT +--- /dev/null ++++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp +@@ -0,0 +1,3949 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "gc/shared/barrierSetAssembler.hpp" ++#include "gc/shared/collectedHeap.hpp" ++#include "gc/shared/tlab_globals.hpp" ++#include "interpreter/interp_masm.hpp" ++#include "interpreter/interpreter.hpp" ++#include "interpreter/interpreterRuntime.hpp" ++#include "interpreter/templateTable.hpp" ++#include "memory/universe.hpp" ++#include "oops/method.hpp" ++#include "oops/methodData.hpp" ++#include "oops/objArrayKlass.hpp" ++#include "oops/oop.inline.hpp" ++#include "prims/jvmtiExport.hpp" ++#include "prims/methodHandles.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/synchronizer.hpp" ++#include "utilities/powerOfTwo.hpp" ++ ++#define __ _masm-> ++ ++// Address computation: local variables ++ ++static inline Address iaddress(int n) { ++ return Address(xlocals, Interpreter::local_offset_in_bytes(n)); ++} ++ ++static inline Address laddress(int n) { ++ return iaddress(n + 1); ++} ++ ++static inline Address faddress(int n) { ++ return iaddress(n); ++} ++ ++static inline Address daddress(int n) { ++ return laddress(n); ++} ++ ++static inline Address aaddress(int n) { ++ return iaddress(n); ++} ++ ++static inline Address iaddress(Register r, Register temp, InterpreterMacroAssembler* _masm) { ++ _masm->shadd(temp, r, xlocals, temp, 3); ++ return Address(temp, 0); ++} ++ ++static inline Address laddress(Register r, Register temp, InterpreterMacroAssembler* _masm) { ++ _masm->shadd(temp, r, xlocals, temp, 3); ++ return Address(temp, Interpreter::local_offset_in_bytes(1));; ++} ++ ++static inline Address faddress(Register r, Register temp, InterpreterMacroAssembler* _masm) { ++ return iaddress(r, temp, _masm); ++} ++ ++static inline Address daddress(Register r, Register temp, InterpreterMacroAssembler* _masm) { ++ return laddress(r, temp, _masm); ++} ++ ++static inline Address aaddress(Register r, Register temp, InterpreterMacroAssembler* _masm) { ++ return iaddress(r, temp, _masm); ++} ++ ++static inline Address at_rsp() { ++ return Address(esp, 0); ++} ++ ++// At top of Java expression stack which may be different than esp(). It ++// isn't for category 1 objects. ++static inline Address at_tos () { ++ return Address(esp, Interpreter::expr_offset_in_bytes(0)); ++} ++ ++static inline Address at_tos_p1() { ++ return Address(esp, Interpreter::expr_offset_in_bytes(1)); ++} ++ ++static inline Address at_tos_p2() { ++ return Address(esp, Interpreter::expr_offset_in_bytes(2)); ++} ++ ++static inline Address at_tos_p3() { ++ return Address(esp, Interpreter::expr_offset_in_bytes(3)); ++} ++ ++static inline Address at_tos_p4() { ++ return Address(esp, Interpreter::expr_offset_in_bytes(4)); ++} ++ ++static inline Address at_tos_p5() { ++ return Address(esp, Interpreter::expr_offset_in_bytes(5)); ++} ++ ++// Miscelaneous helper routines ++// Store an oop (or NULL) at the Address described by obj. ++// If val == noreg this means store a NULL ++static void do_oop_store(InterpreterMacroAssembler* _masm, ++ Address dst, ++ Register val, ++ DecoratorSet decorators) { ++ assert(val == noreg || val == x10, "parameter is just for looks"); ++ __ store_heap_oop(dst, val, x29, x11, decorators); ++} ++ ++static void do_oop_load(InterpreterMacroAssembler* _masm, ++ Address src, ++ Register dst, ++ DecoratorSet decorators) { ++ __ load_heap_oop(dst, src, x7, x11, decorators); ++} ++ ++Address TemplateTable::at_bcp(int offset) { ++ assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); ++ return Address(xbcp, offset); ++} ++ ++void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, ++ Register temp_reg, bool load_bc_into_bc_reg/*=true*/, ++ int byte_no) ++{ ++ if (!RewriteBytecodes) { return; } ++ Label L_patch_done; ++ ++ switch (bc) { ++ case Bytecodes::_fast_aputfield: // fall through ++ case Bytecodes::_fast_bputfield: // fall through ++ case Bytecodes::_fast_zputfield: // fall through ++ case Bytecodes::_fast_cputfield: // fall through ++ case Bytecodes::_fast_dputfield: // fall through ++ case Bytecodes::_fast_fputfield: // fall through ++ case Bytecodes::_fast_iputfield: // fall through ++ case Bytecodes::_fast_lputfield: // fall through ++ case Bytecodes::_fast_sputfield: { ++ // We skip bytecode quickening for putfield instructions when ++ // the put_code written to the constant pool cache is zero. ++ // This is required so that every execution of this instruction ++ // calls out to InterpreterRuntime::resolve_get_put to do ++ // additional, required work. ++ assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); ++ assert(load_bc_into_bc_reg, "we use bc_reg as temp"); ++ __ get_cache_and_index_and_bytecode_at_bcp(temp_reg, bc_reg, temp_reg, byte_no, 1); ++ __ mv(bc_reg, bc); ++ __ beqz(temp_reg, L_patch_done); ++ break; ++ } ++ default: ++ assert(byte_no == -1, "sanity"); ++ // the pair bytecodes have already done the load. ++ if (load_bc_into_bc_reg) { ++ __ mv(bc_reg, bc); ++ } ++ } ++ ++ if (JvmtiExport::can_post_breakpoint()) { ++ Label L_fast_patch; ++ // if a breakpoint is present we can't rewrite the stream directly ++ __ load_unsigned_byte(temp_reg, at_bcp(0)); ++ __ addi(temp_reg, temp_reg, -Bytecodes::_breakpoint); // temp_reg is temporary register. ++ __ bnez(temp_reg, L_fast_patch); ++ // Let breakpoint table handling rewrite to quicker bytecode ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), xmethod, xbcp, bc_reg); ++ __ j(L_patch_done); ++ __ bind(L_fast_patch); ++ } ++ ++#ifdef ASSERT ++ Label L_okay; ++ __ load_unsigned_byte(temp_reg, at_bcp(0)); ++ __ beq(temp_reg, bc_reg, L_okay); ++ __ addi(temp_reg, temp_reg, -(int) Bytecodes::java_code(bc)); ++ __ beqz(temp_reg, L_okay); ++ __ stop("patching the wrong bytecode"); ++ __ bind(L_okay); ++#endif ++ ++ // patch bytecode ++ __ sb(bc_reg, at_bcp(0)); ++ __ bind(L_patch_done); ++} ++ ++// Individual instructions ++ ++void TemplateTable::nop() { ++ transition(vtos, vtos); ++ // nothing to do ++} ++ ++void TemplateTable::shouldnotreachhere() { ++ transition(vtos, vtos); ++ __ stop("should not reach here bytecode"); ++} ++ ++void TemplateTable::aconst_null() ++{ ++ transition(vtos, atos); ++ __ mv(x10, zr); ++} ++ ++void TemplateTable::iconst(int value) ++{ ++ transition(vtos, itos); ++ __ mv(x10, value); ++} ++ ++void TemplateTable::lconst(int value) ++{ ++ transition(vtos, ltos); ++ __ mv(x10, value); ++} ++ ++void TemplateTable::fconst(int value) ++{ ++ transition(vtos, ftos); ++ static float fBuf[2] = {1.0, 2.0}; ++ __ mv(t0, (intptr_t)fBuf); ++ switch (value) { ++ case 0: ++ __ fmv_w_x(f10, zr); ++ break; ++ case 1: ++ __ flw(f10, Address(t0, 0)); ++ break; ++ case 2: ++ __ flw(f10, Address(t0, sizeof(float))); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void TemplateTable::dconst(int value) ++{ ++ transition(vtos, dtos); ++ static double dBuf[2] = {1.0, 2.0}; ++ __ mv(t0, (intptr_t)dBuf); ++ switch (value) { ++ case 0: ++ __ fmv_d_x(f10, zr); ++ break; ++ case 1: ++ __ fld(f10, Address(t0, 0)); ++ break; ++ case 2: ++ __ fld(f10, Address(t0, sizeof(double))); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void TemplateTable::bipush() ++{ ++ transition(vtos, itos); ++ __ load_signed_byte(x10, at_bcp(1)); ++} ++ ++void TemplateTable::sipush() ++{ ++ transition(vtos, itos); ++ __ load_unsigned_short(x10, at_bcp(1)); ++ __ revb_w_w(x10, x10); ++ __ sraiw(x10, x10, 16); ++} ++ ++void TemplateTable::ldc(bool wide) ++{ ++ transition(vtos, vtos); ++ Label call_ldc, notFloat, notClass, notInt, Done; ++ ++ if (wide) { ++ __ get_unsigned_2_byte_index_at_bcp(x11, 1); ++ } else { ++ __ load_unsigned_byte(x11, at_bcp(1)); ++ } ++ __ get_cpool_and_tags(x12, x10); ++ ++ const int base_offset = ConstantPool::header_size() * wordSize; ++ const int tags_offset = Array::base_offset_in_bytes(); ++ ++ // get type ++ __ addi(x13, x11, tags_offset); ++ __ add(x13, x10, x13); ++ __ membar(MacroAssembler::AnyAny); ++ __ lbu(x13, Address(x13, 0)); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ ++ // unresolved class - get the resolved class ++ __ mv(t1, (u1)JVM_CONSTANT_UnresolvedClass); ++ __ beq(x13, t1, call_ldc); ++ ++ // unresolved class in error state - call into runtime to throw the error ++ // from the first resolution attempt ++ __ mv(t1, (u1)JVM_CONSTANT_UnresolvedClassInError); ++ __ beq(x13, t1, call_ldc); ++ ++ // resolved class - need to call vm to get java mirror of the class ++ __ mv(t1, (u1)JVM_CONSTANT_Class); ++ __ bne(x13, t1, notClass); ++ ++ __ bind(call_ldc); ++ __ mv(c_rarg1, wide); ++ call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), c_rarg1); ++ __ push_ptr(x10); ++ __ verify_oop(x10); ++ __ j(Done); ++ ++ __ bind(notClass); ++ __ mv(t1, (u1)JVM_CONSTANT_Float); ++ __ bne(x13, t1, notFloat); ++ ++ // ftos ++ __ shadd(x11, x11, x12, x11, 3); ++ __ flw(f10, Address(x11, base_offset)); ++ __ push_f(f10); ++ __ j(Done); ++ ++ __ bind(notFloat); ++ ++ __ mv(t1, (u1)JVM_CONSTANT_Integer); ++ __ bne(x13, t1, notInt); ++ ++ // itos ++ __ shadd(x11, x11, x12, x11, 3); ++ __ lw(x10, Address(x11, base_offset)); ++ __ push_i(x10); ++ __ j(Done); ++ ++ __ bind(notInt); ++ condy_helper(Done); ++ ++ __ bind(Done); ++} ++ ++// Fast path for caching oop constants. ++void TemplateTable::fast_aldc(bool wide) ++{ ++ transition(vtos, atos); ++ ++ const Register result = x10; ++ const Register tmp = x11; ++ const Register rarg = x12; ++ ++ const int index_size = wide ? sizeof(u2) : sizeof(u1); ++ ++ Label resolved; ++ ++ // We are resolved if the resolved reference cache entry contains a ++ // non-null object (String, MethodType, etc.) ++ assert_different_registers(result, tmp); ++ __ get_cache_index_at_bcp(tmp, 1, index_size); ++ __ load_resolved_reference_at_index(result, tmp); ++ __ bnez(result, resolved); ++ ++ const address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); ++ ++ // first time invocation - must resolve first ++ __ mv(rarg, (int)bytecode()); ++ __ call_VM(result, entry, rarg); ++ ++ __ bind(resolved); ++ ++ { // Check for the null sentinel. ++ // If we just called the VM, it already did the mapping for us, ++ // but it's harmless to retry. ++ Label notNull; ++ ++ // Stash null_sentinel address to get its value later ++ int32_t offset = 0; ++ __ mv(rarg, Universe::the_null_sentinel_addr(), offset); ++ __ ld(tmp, Address(rarg, offset)); ++ __ resolve_oop_handle(tmp); ++ __ bne(result, tmp, notNull); ++ __ mv(result, zr); // NULL object reference ++ __ bind(notNull); ++ } ++ ++ if (VerifyOops) { ++ // Safe to call with 0 result ++ __ verify_oop(result); ++ } ++} ++ ++void TemplateTable::ldc2_w() ++{ ++ transition(vtos, vtos); ++ Label notDouble, notLong, Done; ++ __ get_unsigned_2_byte_index_at_bcp(x10, 1); ++ ++ __ get_cpool_and_tags(x11, x12); ++ const int base_offset = ConstantPool::header_size() * wordSize; ++ const int tags_offset = Array::base_offset_in_bytes(); ++ ++ // get type ++ __ add(x12, x12, x10); ++ __ load_unsigned_byte(x12, Address(x12, tags_offset)); ++ __ mv(t1, JVM_CONSTANT_Double); ++ __ bne(x12, t1, notDouble); ++ ++ // dtos ++ __ shadd(x12, x10, x11, x12, 3); ++ __ fld(f10, Address(x12, base_offset)); ++ __ push_d(f10); ++ __ j(Done); ++ ++ __ bind(notDouble); ++ __ mv(t1, (int)JVM_CONSTANT_Long); ++ __ bne(x12, t1, notLong); ++ ++ // ltos ++ __ shadd(x10, x10, x11, x10, 3); ++ __ ld(x10, Address(x10, base_offset)); ++ __ push_l(x10); ++ __ j(Done); ++ ++ __ bind(notLong); ++ condy_helper(Done); ++ __ bind(Done); ++} ++ ++void TemplateTable::condy_helper(Label& Done) ++{ ++ const Register obj = x10; ++ const Register rarg = x11; ++ const Register flags = x12; ++ const Register off = x13; ++ ++ const address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); ++ ++ __ mv(rarg, (int) bytecode()); ++ __ call_VM(obj, entry, rarg); ++ ++ __ get_vm_result_2(flags, xthread); ++ ++ // VMr = obj = base address to find primitive value to push ++ // VMr2 = flags = (tos, off) using format of CPCE::_flags ++ __ mv(off, flags); ++ __ mv(t0, ConstantPoolCacheEntry::field_index_mask); ++ __ andrw(off, off, t0); ++ ++ __ add(off, obj, off); ++ const Address field(off, 0); // base + R---->base + offset ++ ++ __ slli(flags, flags, XLEN - (ConstantPoolCacheEntry::tos_state_shift + ConstantPoolCacheEntry::tos_state_bits)); ++ __ srli(flags, flags, XLEN - ConstantPoolCacheEntry::tos_state_bits); // (1 << 5) - 4 --> 28~31==> flags:0~3 ++ ++ switch (bytecode()) { ++ case Bytecodes::_ldc: // fall through ++ case Bytecodes::_ldc_w: { ++ // tos in (itos, ftos, stos, btos, ctos, ztos) ++ Label notInt, notFloat, notShort, notByte, notChar, notBool; ++ __ mv(t1, itos); ++ __ bne(flags, t1, notInt); ++ // itos ++ __ lw(x10, field); ++ __ push(itos); ++ __ j(Done); ++ ++ __ bind(notInt); ++ __ mv(t1, ftos); ++ __ bne(flags, t1, notFloat); ++ // ftos ++ __ load_float(field); ++ __ push(ftos); ++ __ j(Done); ++ ++ __ bind(notFloat); ++ __ mv(t1, stos); ++ __ bne(flags, t1, notShort); ++ // stos ++ __ load_signed_short(x10, field); ++ __ push(stos); ++ __ j(Done); ++ ++ __ bind(notShort); ++ __ mv(t1, btos); ++ __ bne(flags, t1, notByte); ++ // btos ++ __ load_signed_byte(x10, field); ++ __ push(btos); ++ __ j(Done); ++ ++ __ bind(notByte); ++ __ mv(t1, ctos); ++ __ bne(flags, t1, notChar); ++ // ctos ++ __ load_unsigned_short(x10, field); ++ __ push(ctos); ++ __ j(Done); ++ ++ __ bind(notChar); ++ __ mv(t1, ztos); ++ __ bne(flags, t1, notBool); ++ // ztos ++ __ load_signed_byte(x10, field); ++ __ push(ztos); ++ __ j(Done); ++ ++ __ bind(notBool); ++ break; ++ } ++ ++ case Bytecodes::_ldc2_w: { ++ Label notLong, notDouble; ++ __ mv(t1, ltos); ++ __ bne(flags, t1, notLong); ++ // ltos ++ __ ld(x10, field); ++ __ push(ltos); ++ __ j(Done); ++ ++ __ bind(notLong); ++ __ mv(t1, dtos); ++ __ bne(flags, t1, notDouble); ++ // dtos ++ __ load_double(field); ++ __ push(dtos); ++ __ j(Done); ++ ++ __ bind(notDouble); ++ break; ++ } ++ ++ default: ++ ShouldNotReachHere(); ++ } ++ ++ __ stop("bad ldc/condy"); ++} ++ ++void TemplateTable::locals_index(Register reg, int offset) ++{ ++ __ lbu(reg, at_bcp(offset)); ++ __ neg(reg, reg); ++} ++ ++void TemplateTable::iload() { ++ iload_internal(); ++} ++ ++void TemplateTable::nofast_iload() { ++ iload_internal(may_not_rewrite); ++} ++ ++void TemplateTable::iload_internal(RewriteControl rc) { ++ transition(vtos, itos); ++ if (RewriteFrequentPairs && rc == may_rewrite) { ++ Label rewrite, done; ++ const Register bc = x14; ++ ++ // get next bytecode ++ __ load_unsigned_byte(x11, at_bcp(Bytecodes::length_for(Bytecodes::_iload))); ++ ++ // if _iload, wait to rewrite to iload2. We only want to rewrite the ++ // last two iloads in a pair. Comparing against fast_iload means that ++ // the next bytecode is neither an iload or a caload, and therefore ++ // an iload pair. ++ __ mv(t1, Bytecodes::_iload); ++ __ beq(x11, t1, done); ++ ++ // if _fast_iload rewrite to _fast_iload2 ++ __ mv(t1, Bytecodes::_fast_iload); ++ __ mv(bc, Bytecodes::_fast_iload2); ++ __ beq(x11, t1, rewrite); ++ ++ // if _caload rewrite to _fast_icaload ++ __ mv(t1, Bytecodes::_caload); ++ __ mv(bc, Bytecodes::_fast_icaload); ++ __ beq(x11, t1, rewrite); ++ ++ // else rewrite to _fast_iload ++ __ mv(bc, Bytecodes::_fast_iload); ++ ++ // rewrite ++ // bc: new bytecode ++ __ bind(rewrite); ++ patch_bytecode(Bytecodes::_iload, bc, x11, false); ++ __ bind(done); ++ ++ } ++ ++ // do iload, get the local value into tos ++ locals_index(x11); ++ __ lw(x10, iaddress(x11, x10, _masm)); ++} ++ ++void TemplateTable::fast_iload2() ++{ ++ transition(vtos, itos); ++ locals_index(x11); ++ __ lw(x10, iaddress(x11, x10, _masm)); ++ __ push(itos); ++ locals_index(x11, 3); ++ __ lw(x10, iaddress(x11, x10, _masm)); ++} ++ ++void TemplateTable::fast_iload() ++{ ++ transition(vtos, itos); ++ locals_index(x11); ++ __ lw(x10, iaddress(x11, x10, _masm)); ++} ++ ++void TemplateTable::lload() ++{ ++ transition(vtos, ltos); ++ __ lbu(x11, at_bcp(1)); ++ __ slli(x11, x11, LogBytesPerWord); ++ __ sub(x11, xlocals, x11); ++ __ ld(x10, Address(x11, Interpreter::local_offset_in_bytes(1))); ++} ++ ++void TemplateTable::fload() ++{ ++ transition(vtos, ftos); ++ locals_index(x11); ++ __ flw(f10, faddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::dload() ++{ ++ transition(vtos, dtos); ++ __ lbu(x11, at_bcp(1)); ++ __ slli(x11, x11, LogBytesPerWord); ++ __ sub(x11, xlocals, x11); ++ __ fld(f10, Address(x11, Interpreter::local_offset_in_bytes(1))); ++} ++ ++void TemplateTable::aload() ++{ ++ transition(vtos, atos); ++ locals_index(x11); ++ __ ld(x10, iaddress(x11, x10, _masm)); ++ ++} ++ ++void TemplateTable::locals_index_wide(Register reg) { ++ __ lhu(reg, at_bcp(2)); ++ __ revb_h_h_u(reg, reg); // reverse bytes in half-word and zero-extend ++ __ neg(reg, reg); ++} ++ ++void TemplateTable::wide_iload() { ++ transition(vtos, itos); ++ locals_index_wide(x11); ++ __ lw(x10, iaddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::wide_lload() ++{ ++ transition(vtos, ltos); ++ __ lhu(x11, at_bcp(2)); ++ __ revb_h_h_u(x11, x11); // reverse bytes in half-word and zero-extend ++ __ slli(x11, x11, LogBytesPerWord); ++ __ sub(x11, xlocals, x11); ++ __ ld(x10, Address(x11, Interpreter::local_offset_in_bytes(1))); ++} ++ ++void TemplateTable::wide_fload() ++{ ++ transition(vtos, ftos); ++ locals_index_wide(x11); ++ __ flw(f10, faddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::wide_dload() ++{ ++ transition(vtos, dtos); ++ __ lhu(x11, at_bcp(2)); ++ __ revb_h_h_u(x11, x11); // reverse bytes in half-word and zero-extend ++ __ slli(x11, x11, LogBytesPerWord); ++ __ sub(x11, xlocals, x11); ++ __ fld(f10, Address(x11, Interpreter::local_offset_in_bytes(1))); ++} ++ ++void TemplateTable::wide_aload() ++{ ++ transition(vtos, atos); ++ locals_index_wide(x11); ++ __ ld(x10, aaddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::index_check(Register array, Register index) ++{ ++ // destroys x11, t0 ++ // check array ++ __ null_check(array, arrayOopDesc::length_offset_in_bytes()); ++ // sign extend index for use by indexed load ++ // check index ++ const Register length = t0; ++ __ lwu(length, Address(array, arrayOopDesc::length_offset_in_bytes())); ++ if (index != x11) { ++ assert(x11 != array, "different registers"); ++ __ mv(x11, index); ++ } ++ Label ok; ++ __ sign_extend(index, index, 32); ++ __ bltu(index, length, ok); ++ __ mv(x13, array); ++ __ mv(t0, Interpreter::_throw_ArrayIndexOutOfBoundsException_entry); ++ __ jr(t0); ++ __ bind(ok); ++} ++ ++void TemplateTable::iaload() ++{ ++ transition(itos, itos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); ++ __ shadd(x10, x11, x10, t0, 2); ++ __ access_load_at(T_INT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++ __ sign_extend(x10, x10, 32); ++} ++ ++void TemplateTable::laload() ++{ ++ transition(itos, ltos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); ++ __ shadd(x10, x11, x10, t0, 3); ++ __ access_load_at(T_LONG, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++} ++ ++void TemplateTable::faload() ++{ ++ transition(itos, ftos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); ++ __ shadd(x10, x11, x10, t0, 2); ++ __ access_load_at(T_FLOAT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++} ++ ++void TemplateTable::daload() ++{ ++ transition(itos, dtos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); ++ __ shadd(x10, x11, x10, t0, 3); ++ __ access_load_at(T_DOUBLE, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++} ++ ++void TemplateTable::aaload() ++{ ++ transition(itos, atos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); ++ __ shadd(x10, x11, x10, t0, LogBytesPerHeapOop); ++ do_oop_load(_masm, ++ Address(x10), ++ x10, ++ IS_ARRAY); ++} ++ ++void TemplateTable::baload() ++{ ++ transition(itos, itos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); ++ __ shadd(x10, x11, x10, t0, 0); ++ __ access_load_at(T_BYTE, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++} ++ ++void TemplateTable::caload() ++{ ++ transition(itos, itos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); ++ __ shadd(x10, x11, x10, t0, 1); ++ __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++} ++ ++// iload followed by caload frequent pair ++void TemplateTable::fast_icaload() ++{ ++ transition(vtos, itos); ++ // load index out of locals ++ locals_index(x12); ++ __ lw(x11, iaddress(x12, x11, _masm)); ++ __ pop_ptr(x10); ++ ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11, kills t0 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); // addi, max imm is 2^11 ++ __ shadd(x10, x11, x10, t0, 1); ++ __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++} ++ ++void TemplateTable::saload() ++{ ++ transition(itos, itos); ++ __ mv(x11, x10); ++ __ pop_ptr(x10); ++ // x10: array ++ // x11: index ++ index_check(x10, x11); // leaves index in x11, kills t0 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_SHORT) >> 1); ++ __ shadd(x10, x11, x10, t0, 1); ++ __ access_load_at(T_SHORT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); ++} ++ ++void TemplateTable::iload(int n) ++{ ++ transition(vtos, itos); ++ __ lw(x10, iaddress(n)); ++} ++ ++void TemplateTable::lload(int n) ++{ ++ transition(vtos, ltos); ++ __ ld(x10, laddress(n)); ++} ++ ++void TemplateTable::fload(int n) ++{ ++ transition(vtos, ftos); ++ __ flw(f10, faddress(n)); ++} ++ ++void TemplateTable::dload(int n) ++{ ++ transition(vtos, dtos); ++ __ fld(f10, daddress(n)); ++} ++ ++void TemplateTable::aload(int n) ++{ ++ transition(vtos, atos); ++ __ ld(x10, iaddress(n)); ++} ++ ++void TemplateTable::aload_0() { ++ aload_0_internal(); ++} ++ ++void TemplateTable::nofast_aload_0() { ++ aload_0_internal(may_not_rewrite); ++} ++ ++void TemplateTable::aload_0_internal(RewriteControl rc) { ++ // According to bytecode histograms, the pairs: ++ // ++ // _aload_0, _fast_igetfield ++ // _aload_0, _fast_agetfield ++ // _aload_0, _fast_fgetfield ++ // ++ // occur frequently. If RewriteFrequentPairs is set, the (slow) ++ // _aload_0 bytecode checks if the next bytecode is either ++ // _fast_igetfield, _fast_agetfield or _fast_fgetfield and then ++ // rewrites the current bytecode into a pair bytecode; otherwise it ++ // rewrites the current bytecode into _fast_aload_0 that doesn't do ++ // the pair check anymore. ++ // ++ // Note: If the next bytecode is _getfield, the rewrite must be ++ // delayed, otherwise we may miss an opportunity for a pair. ++ // ++ // Also rewrite frequent pairs ++ // aload_0, aload_1 ++ // aload_0, iload_1 ++ // These bytecodes with a small amount of code are most profitable ++ // to rewrite ++ if (RewriteFrequentPairs && rc == may_rewrite) { ++ Label rewrite, done; ++ const Register bc = x14; ++ ++ // get next bytecode ++ __ load_unsigned_byte(x11, at_bcp(Bytecodes::length_for(Bytecodes::_aload_0))); ++ ++ // if _getfield then wait with rewrite ++ __ mv(t1, Bytecodes::Bytecodes::_getfield); ++ __ beq(x11, t1, done); ++ ++ // if _igetfield then rewrite to _fast_iaccess_0 ++ assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) == Bytecodes::_aload_0, "fix bytecode definition"); ++ __ mv(t1, Bytecodes::_fast_igetfield); ++ __ mv(bc, Bytecodes::_fast_iaccess_0); ++ __ beq(x11, t1, rewrite); ++ ++ // if _agetfield then rewrite to _fast_aaccess_0 ++ assert(Bytecodes::java_code(Bytecodes::_fast_aaccess_0) == Bytecodes::_aload_0, "fix bytecode definition"); ++ __ mv(t1, Bytecodes::_fast_agetfield); ++ __ mv(bc, Bytecodes::_fast_aaccess_0); ++ __ beq(x11, t1, rewrite); ++ ++ // if _fgetfield then rewrite to _fast_faccess_0 ++ assert(Bytecodes::java_code(Bytecodes::_fast_faccess_0) == Bytecodes::_aload_0, "fix bytecode definition"); ++ __ mv(t1, Bytecodes::_fast_fgetfield); ++ __ mv(bc, Bytecodes::_fast_faccess_0); ++ __ beq(x11, t1, rewrite); ++ ++ // else rewrite to _fast_aload0 ++ assert(Bytecodes::java_code(Bytecodes::_fast_aload_0) == Bytecodes::_aload_0, "fix bytecode definition"); ++ __ mv(bc, Bytecodes::Bytecodes::_fast_aload_0); ++ ++ // rewrite ++ // bc: new bytecode ++ __ bind(rewrite); ++ patch_bytecode(Bytecodes::_aload_0, bc, x11, false); ++ ++ __ bind(done); ++ } ++ ++ // Do actual aload_0 (must do this after patch_bytecode which might call VM and GC might change oop). ++ aload(0); ++} ++ ++void TemplateTable::istore() ++{ ++ transition(itos, vtos); ++ locals_index(x11); ++ __ sw(x10, iaddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::lstore() ++{ ++ transition(ltos, vtos); ++ locals_index(x11); ++ __ sd(x10, laddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::fstore() { ++ transition(ftos, vtos); ++ locals_index(x11); ++ __ fsw(f10, iaddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::dstore() { ++ transition(dtos, vtos); ++ locals_index(x11); ++ __ fsd(f10, daddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::astore() ++{ ++ transition(vtos, vtos); ++ __ pop_ptr(x10); ++ locals_index(x11); ++ __ sd(x10, aaddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::wide_istore() { ++ transition(vtos, vtos); ++ __ pop_i(); ++ locals_index_wide(x11); ++ __ sw(x10, iaddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::wide_lstore() { ++ transition(vtos, vtos); ++ __ pop_l(); ++ locals_index_wide(x11); ++ __ sd(x10, laddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::wide_fstore() { ++ transition(vtos, vtos); ++ __ pop_f(); ++ locals_index_wide(x11); ++ __ fsw(f10, faddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::wide_dstore() { ++ transition(vtos, vtos); ++ __ pop_d(); ++ locals_index_wide(x11); ++ __ fsd(f10, daddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::wide_astore() { ++ transition(vtos, vtos); ++ __ pop_ptr(x10); ++ locals_index_wide(x11); ++ __ sd(x10, aaddress(x11, t0, _masm)); ++} ++ ++void TemplateTable::iastore() { ++ transition(itos, vtos); ++ __ pop_i(x11); ++ __ pop_ptr(x13); ++ // x10: value ++ // x11: index ++ // x13: array ++ index_check(x13, x11); // prefer index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); ++ __ shadd(t0, x11, x13, t0, 2); ++ __ access_store_at(T_INT, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg); ++} ++ ++void TemplateTable::lastore() { ++ transition(ltos, vtos); ++ __ pop_i(x11); ++ __ pop_ptr(x13); ++ // x10: value ++ // x11: index ++ // x13: array ++ index_check(x13, x11); // prefer index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); ++ __ shadd(t0, x11, x13, t0, 3); ++ __ access_store_at(T_LONG, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg); ++} ++ ++void TemplateTable::fastore() { ++ transition(ftos, vtos); ++ __ pop_i(x11); ++ __ pop_ptr(x13); ++ // f10: value ++ // x11: index ++ // x13: array ++ index_check(x13, x11); // prefer index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); ++ __ shadd(t0, x11, x13, t0, 2); ++ __ access_store_at(T_FLOAT, IN_HEAP | IS_ARRAY, Address(t0, 0), noreg /* ftos */, noreg, noreg); ++} ++ ++void TemplateTable::dastore() { ++ transition(dtos, vtos); ++ __ pop_i(x11); ++ __ pop_ptr(x13); ++ // f10: value ++ // x11: index ++ // x13: array ++ index_check(x13, x11); // prefer index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); ++ __ shadd(t0, x11, x13, t0, 3); ++ __ access_store_at(T_DOUBLE, IN_HEAP | IS_ARRAY, Address(t0, 0), noreg /* dtos */, noreg, noreg); ++} ++ ++void TemplateTable::aastore() { ++ Label is_null, ok_is_subtype, done; ++ transition(vtos, vtos); ++ // stack: ..., array, index, value ++ __ ld(x10, at_tos()); // value ++ __ ld(x12, at_tos_p1()); // index ++ __ ld(x13, at_tos_p2()); // array ++ ++ index_check(x13, x12); // kills x11 ++ __ add(x14, x12, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); ++ __ shadd(x14, x14, x13, x14, LogBytesPerHeapOop); ++ ++ Address element_address(x14, 0); ++ ++ // do array store check - check for NULL value first ++ __ beqz(x10, is_null); ++ ++ // Move subklass into x11 ++ __ load_klass(x11, x10); ++ // Move superklass into x10 ++ __ load_klass(x10, x13); ++ __ ld(x10, Address(x10, ++ ObjArrayKlass::element_klass_offset())); ++ // Compress array + index * oopSize + 12 into a single register. Frees x12. ++ ++ // Generate subtype check. Blows x12, x15 ++ // Superklass in x10. Subklass in x11. ++ __ gen_subtype_check(x11, ok_is_subtype); //todo ++ ++ // Come here on failure ++ // object is at TOS ++ __ j(Interpreter::_throw_ArrayStoreException_entry); ++ ++ // Come here on success ++ __ bind(ok_is_subtype); ++ ++ // Get the value we will store ++ __ ld(x10, at_tos()); ++ // Now store using the appropriate barrier ++ do_oop_store(_masm, element_address, x10, IS_ARRAY); ++ __ j(done); ++ ++ // Have a NULL in x10, x13=array, x12=index. Store NULL at ary[idx] ++ __ bind(is_null); ++ __ profile_null_seen(x12); ++ ++ // Store a NULL ++ do_oop_store(_masm, element_address, noreg, IS_ARRAY); ++ ++ // Pop stack arguments ++ __ bind(done); ++ __ add(esp, esp, 3 * Interpreter::stackElementSize); ++ ++} ++ ++void TemplateTable::bastore() ++{ ++ transition(itos, vtos); ++ __ pop_i(x11); ++ __ pop_ptr(x13); ++ // x10: value ++ // x11: index ++ // x13: array ++ index_check(x13, x11); // prefer index in x11 ++ ++ // Need to check whether array is boolean or byte ++ // since both types share the bastore bytecode. ++ __ load_klass(x12, x13); ++ __ lwu(x12, Address(x12, Klass::layout_helper_offset())); ++ Label L_skip; ++ __ test_bit(t0, x12, exact_log2(Klass::layout_helper_boolean_diffbit())); ++ __ beqz(t0, L_skip); ++ __ andi(x10, x10, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 ++ __ bind(L_skip); ++ ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); ++ ++ __ add(x11, x13, x11); ++ __ access_store_at(T_BYTE, IN_HEAP | IS_ARRAY, Address(x11, 0), x10, noreg, noreg); ++} ++ ++void TemplateTable::castore() ++{ ++ transition(itos, vtos); ++ __ pop_i(x11); ++ __ pop_ptr(x13); ++ // x10: value ++ // x11: index ++ // x13: array ++ index_check(x13, x11); // prefer index in x11 ++ __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); ++ __ shadd(t0, x11, x13, t0, 1); ++ __ access_store_at(T_CHAR, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg); ++} ++ ++void TemplateTable::sastore() ++{ ++ castore(); ++} ++ ++void TemplateTable::istore(int n) ++{ ++ transition(itos, vtos); ++ __ sd(x10, iaddress(n)); ++} ++ ++void TemplateTable::lstore(int n) ++{ ++ transition(ltos, vtos); ++ __ sd(x10, laddress(n)); ++} ++ ++void TemplateTable::fstore(int n) ++{ ++ transition(ftos, vtos); ++ __ fsw(f10, faddress(n)); ++} ++ ++void TemplateTable::dstore(int n) ++{ ++ transition(dtos, vtos); ++ __ fsd(f10, daddress(n)); ++} ++ ++void TemplateTable::astore(int n) ++{ ++ transition(vtos, vtos); ++ __ pop_ptr(x10); ++ __ sd(x10, iaddress(n)); ++} ++ ++void TemplateTable::pop() ++{ ++ transition(vtos, vtos); ++ __ addi(esp, esp, Interpreter::stackElementSize); ++} ++ ++void TemplateTable::pop2() ++{ ++ transition(vtos, vtos); ++ __ addi(esp, esp, 2 * Interpreter::stackElementSize); ++} ++ ++void TemplateTable::dup() ++{ ++ transition(vtos, vtos); ++ __ ld(x10, Address(esp, 0)); ++ __ push_reg(x10); ++ // stack: ..., a, a ++} ++ ++void TemplateTable::dup_x1() ++{ ++ transition(vtos, vtos); ++ // stack: ..., a, b ++ __ ld(x10, at_tos()); // load b ++ __ ld(x12, at_tos_p1()); // load a ++ __ sd(x10, at_tos_p1()); // store b ++ __ sd(x12, at_tos()); // store a ++ __ push_reg(x10); // push b ++ // stack: ..., b, a, b ++} ++ ++void TemplateTable::dup_x2() ++{ ++ transition(vtos, vtos); ++ // stack: ..., a, b, c ++ __ ld(x10, at_tos()); // load c ++ __ ld(x12, at_tos_p2()); // load a ++ __ sd(x10, at_tos_p2()); // store c in a ++ __ push_reg(x10); // push c ++ // stack: ..., c, b, c, c ++ __ ld(x10, at_tos_p2()); // load b ++ __ sd(x12, at_tos_p2()); // store a in b ++ // stack: ..., c, a, c, c ++ __ sd(x10, at_tos_p1()); // store b in c ++ // stack: ..., c, a, b, c ++} ++ ++void TemplateTable::dup2() ++{ ++ transition(vtos, vtos); ++ // stack: ..., a, b ++ __ ld(x10, at_tos_p1()); // load a ++ __ push_reg(x10); // push a ++ __ ld(x10, at_tos_p1()); // load b ++ __ push_reg(x10); // push b ++ // stack: ..., a, b, a, b ++} ++ ++void TemplateTable::dup2_x1() ++{ ++ transition(vtos, vtos); ++ // stack: ..., a, b, c ++ __ ld(x12, at_tos()); // load c ++ __ ld(x10, at_tos_p1()); // load b ++ __ push_reg(x10); // push b ++ __ push_reg(x12); // push c ++ // stack: ..., a, b, c, b, c ++ __ sd(x12, at_tos_p3()); // store c in b ++ // stack: ..., a, c, c, b, c ++ __ ld(x12, at_tos_p4()); // load a ++ __ sd(x12, at_tos_p2()); // store a in 2nd c ++ // stack: ..., a, c, a, b, c ++ __ sd(x10, at_tos_p4()); // store b in a ++ // stack: ..., b, c, a, b, c ++} ++ ++void TemplateTable::dup2_x2() ++{ ++ transition(vtos, vtos); ++ // stack: ..., a, b, c, d ++ __ ld(x12, at_tos()); // load d ++ __ ld(x10, at_tos_p1()); // load c ++ __ push_reg(x10); // push c ++ __ push_reg(x12); // push d ++ // stack: ..., a, b, c, d, c, d ++ __ ld(x10, at_tos_p4()); // load b ++ __ sd(x10, at_tos_p2()); // store b in d ++ __ sd(x12, at_tos_p4()); // store d in b ++ // stack: ..., a, d, c, b, c, d ++ __ ld(x12, at_tos_p5()); // load a ++ __ ld(x10, at_tos_p3()); // load c ++ __ sd(x12, at_tos_p3()); // store a in c ++ __ sd(x10, at_tos_p5()); // store c in a ++ // stack: ..., c, d, a, b, c, d ++} ++ ++void TemplateTable::swap() ++{ ++ transition(vtos, vtos); ++ // stack: ..., a, b ++ __ ld(x12, at_tos_p1()); // load a ++ __ ld(x10, at_tos()); // load b ++ __ sd(x12, at_tos()); // store a in b ++ __ sd(x10, at_tos_p1()); // store b in a ++ // stack: ..., b, a ++} ++ ++void TemplateTable::iop2(Operation op) ++{ ++ transition(itos, itos); ++ // x10 <== x11 op x10 ++ __ pop_i(x11); ++ switch (op) { ++ case add : __ addw(x10, x11, x10); break; ++ case sub : __ subw(x10, x11, x10); break; ++ case mul : __ mulw(x10, x11, x10); break; ++ case _and : __ andrw(x10, x11, x10); break; ++ case _or : __ orrw(x10, x11, x10); break; ++ case _xor : __ xorrw(x10, x11, x10); break; ++ case shl : __ sllw(x10, x11, x10); break; ++ case shr : __ sraw(x10, x11, x10); break; ++ case ushr : __ srlw(x10, x11, x10); break; ++ default : ShouldNotReachHere(); ++ } ++} ++ ++void TemplateTable::lop2(Operation op) ++{ ++ transition(ltos, ltos); ++ // x10 <== x11 op x10 ++ __ pop_l(x11); ++ switch (op) { ++ case add : __ add(x10, x11, x10); break; ++ case sub : __ sub(x10, x11, x10); break; ++ case mul : __ mul(x10, x11, x10); break; ++ case _and : __ andr(x10, x11, x10); break; ++ case _or : __ orr(x10, x11, x10); break; ++ case _xor : __ xorr(x10, x11, x10); break; ++ default : ShouldNotReachHere(); ++ } ++} ++ ++void TemplateTable::idiv() ++{ ++ transition(itos, itos); ++ // explicitly check for div0 ++ Label no_div0; ++ __ bnez(x10, no_div0); ++ __ mv(t0, Interpreter::_throw_ArithmeticException_entry); ++ __ jr(t0); ++ __ bind(no_div0); ++ __ pop_i(x11); ++ // x10 <== x11 idiv x10 ++ __ corrected_idivl(x10, x11, x10, /* want_remainder */ false); ++} ++ ++void TemplateTable::irem() ++{ ++ transition(itos, itos); ++ // explicitly check for div0 ++ Label no_div0; ++ __ bnez(x10, no_div0); ++ __ mv(t0, Interpreter::_throw_ArithmeticException_entry); ++ __ jr(t0); ++ __ bind(no_div0); ++ __ pop_i(x11); ++ // x10 <== x11 irem x10 ++ __ corrected_idivl(x10, x11, x10, /* want_remainder */ true); ++} ++ ++void TemplateTable::lmul() ++{ ++ transition(ltos, ltos); ++ __ pop_l(x11); ++ __ mul(x10, x10, x11); ++} ++ ++void TemplateTable::ldiv() ++{ ++ transition(ltos, ltos); ++ // explicitly check for div0 ++ Label no_div0; ++ __ bnez(x10, no_div0); ++ __ mv(t0, Interpreter::_throw_ArithmeticException_entry); ++ __ jr(t0); ++ __ bind(no_div0); ++ __ pop_l(x11); ++ // x10 <== x11 ldiv x10 ++ __ corrected_idivq(x10, x11, x10, /* want_remainder */ false); ++} ++ ++void TemplateTable::lrem() ++{ ++ transition(ltos, ltos); ++ // explicitly check for div0 ++ Label no_div0; ++ __ bnez(x10, no_div0); ++ __ mv(t0, Interpreter::_throw_ArithmeticException_entry); ++ __ jr(t0); ++ __ bind(no_div0); ++ __ pop_l(x11); ++ // x10 <== x11 lrem x10 ++ __ corrected_idivq(x10, x11, x10, /* want_remainder */ true); ++} ++ ++void TemplateTable::lshl() ++{ ++ transition(itos, ltos); ++ // shift count is in x10 ++ __ pop_l(x11); ++ __ sll(x10, x11, x10); ++} ++ ++void TemplateTable::lshr() ++{ ++ transition(itos, ltos); ++ // shift count is in x10 ++ __ pop_l(x11); ++ __ sra(x10, x11, x10); ++} ++ ++void TemplateTable::lushr() ++{ ++ transition(itos, ltos); ++ // shift count is in x10 ++ __ pop_l(x11); ++ __ srl(x10, x11, x10); ++} ++ ++void TemplateTable::fop2(Operation op) ++{ ++ transition(ftos, ftos); ++ switch (op) { ++ case add: ++ __ pop_f(f11); ++ __ fadd_s(f10, f11, f10); ++ break; ++ case sub: ++ __ pop_f(f11); ++ __ fsub_s(f10, f11, f10); ++ break; ++ case mul: ++ __ pop_f(f11); ++ __ fmul_s(f10, f11, f10); ++ break; ++ case div: ++ __ pop_f(f11); ++ __ fdiv_s(f10, f11, f10); ++ break; ++ case rem: ++ __ fmv_s(f11, f10); ++ __ pop_f(f10); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::frem)); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void TemplateTable::dop2(Operation op) ++{ ++ transition(dtos, dtos); ++ switch (op) { ++ case add: ++ __ pop_d(f11); ++ __ fadd_d(f10, f11, f10); ++ break; ++ case sub: ++ __ pop_d(f11); ++ __ fsub_d(f10, f11, f10); ++ break; ++ case mul: ++ __ pop_d(f11); ++ __ fmul_d(f10, f11, f10); ++ break; ++ case div: ++ __ pop_d(f11); ++ __ fdiv_d(f10, f11, f10); ++ break; ++ case rem: ++ __ fmv_d(f11, f10); ++ __ pop_d(f10); ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::drem)); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void TemplateTable::ineg() ++{ ++ transition(itos, itos); ++ __ negw(x10, x10); ++} ++ ++void TemplateTable::lneg() ++{ ++ transition(ltos, ltos); ++ __ neg(x10, x10); ++} ++ ++void TemplateTable::fneg() ++{ ++ transition(ftos, ftos); ++ __ fneg_s(f10, f10); ++} ++ ++void TemplateTable::dneg() ++{ ++ transition(dtos, dtos); ++ __ fneg_d(f10, f10); ++} ++ ++void TemplateTable::iinc() ++{ ++ transition(vtos, vtos); ++ __ load_signed_byte(x11, at_bcp(2)); // get constant ++ locals_index(x12); ++ __ ld(x10, iaddress(x12, x10, _masm)); ++ __ addw(x10, x10, x11); ++ __ sd(x10, iaddress(x12, t0, _masm)); ++} ++ ++void TemplateTable::wide_iinc() ++{ ++ transition(vtos, vtos); ++ __ lwu(x11, at_bcp(2)); // get constant and index ++ __ revb_h_w_u(x11, x11); // reverse bytes in half-word (32bit) and zero-extend ++ __ zero_extend(x12, x11, 16); ++ __ neg(x12, x12); ++ __ slli(x11, x11, 32); ++ __ srai(x11, x11, 48); ++ __ ld(x10, iaddress(x12, t0, _masm)); ++ __ addw(x10, x10, x11); ++ __ sd(x10, iaddress(x12, t0, _masm)); ++} ++ ++void TemplateTable::convert() ++{ ++ // Checking ++#ifdef ASSERT ++ { ++ TosState tos_in = ilgl; ++ TosState tos_out = ilgl; ++ switch (bytecode()) { ++ case Bytecodes::_i2l: // fall through ++ case Bytecodes::_i2f: // fall through ++ case Bytecodes::_i2d: // fall through ++ case Bytecodes::_i2b: // fall through ++ case Bytecodes::_i2c: // fall through ++ case Bytecodes::_i2s: tos_in = itos; break; ++ case Bytecodes::_l2i: // fall through ++ case Bytecodes::_l2f: // fall through ++ case Bytecodes::_l2d: tos_in = ltos; break; ++ case Bytecodes::_f2i: // fall through ++ case Bytecodes::_f2l: // fall through ++ case Bytecodes::_f2d: tos_in = ftos; break; ++ case Bytecodes::_d2i: // fall through ++ case Bytecodes::_d2l: // fall through ++ case Bytecodes::_d2f: tos_in = dtos; break; ++ default : ShouldNotReachHere(); ++ } ++ switch (bytecode()) { ++ case Bytecodes::_l2i: // fall through ++ case Bytecodes::_f2i: // fall through ++ case Bytecodes::_d2i: // fall through ++ case Bytecodes::_i2b: // fall through ++ case Bytecodes::_i2c: // fall through ++ case Bytecodes::_i2s: tos_out = itos; break; ++ case Bytecodes::_i2l: // fall through ++ case Bytecodes::_f2l: // fall through ++ case Bytecodes::_d2l: tos_out = ltos; break; ++ case Bytecodes::_i2f: // fall through ++ case Bytecodes::_l2f: // fall through ++ case Bytecodes::_d2f: tos_out = ftos; break; ++ case Bytecodes::_i2d: // fall through ++ case Bytecodes::_l2d: // fall through ++ case Bytecodes::_f2d: tos_out = dtos; break; ++ default : ShouldNotReachHere(); ++ } ++ transition(tos_in, tos_out); ++ } ++#endif // ASSERT ++ ++ // Conversion ++ switch (bytecode()) { ++ case Bytecodes::_i2l: ++ __ sign_extend(x10, x10, 32); ++ break; ++ case Bytecodes::_i2f: ++ __ fcvt_s_w(f10, x10); ++ break; ++ case Bytecodes::_i2d: ++ __ fcvt_d_w(f10, x10); ++ break; ++ case Bytecodes::_i2b: ++ __ sign_extend(x10, x10, 8); ++ break; ++ case Bytecodes::_i2c: ++ __ zero_extend(x10, x10, 16); ++ break; ++ case Bytecodes::_i2s: ++ __ sign_extend(x10, x10, 16); ++ break; ++ case Bytecodes::_l2i: ++ __ sign_extend(x10, x10, 32); ++ break; ++ case Bytecodes::_l2f: ++ __ fcvt_s_l(f10, x10); ++ break; ++ case Bytecodes::_l2d: ++ __ fcvt_d_l(f10, x10); ++ break; ++ case Bytecodes::_f2i: ++ __ fcvt_w_s_safe(x10, f10); ++ break; ++ case Bytecodes::_f2l: ++ __ fcvt_l_s_safe(x10, f10); ++ break; ++ case Bytecodes::_f2d: ++ __ fcvt_d_s(f10, f10); ++ break; ++ case Bytecodes::_d2i: ++ __ fcvt_w_d_safe(x10, f10); ++ break; ++ case Bytecodes::_d2l: ++ __ fcvt_l_d_safe(x10, f10); ++ break; ++ case Bytecodes::_d2f: ++ __ fcvt_s_d(f10, f10); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++} ++ ++void TemplateTable::lcmp() ++{ ++ transition(ltos, itos); ++ __ pop_l(x11); ++ __ cmp_l2i(t0, x11, x10); ++ __ mv(x10, t0); ++} ++ ++void TemplateTable::float_cmp(bool is_float, int unordered_result) ++{ ++ // For instruction feq, flt and fle, the result is 0 if either operand is NaN ++ if (is_float) { ++ __ pop_f(f11); ++ // if unordered_result < 0: ++ // we want -1 for unordered or less than, 0 for equal and 1 for ++ // greater than. ++ // else: ++ // we want -1 for less than, 0 for equal and 1 for unordered or ++ // greater than. ++ // f11 primary, f10 secondary ++ __ float_compare(x10, f11, f10, unordered_result); ++ } else { ++ __ pop_d(f11); ++ // if unordered_result < 0: ++ // we want -1 for unordered or less than, 0 for equal and 1 for ++ // greater than. ++ // else: ++ // we want -1 for less than, 0 for equal and 1 for unordered or ++ // greater than. ++ // f11 primary, f10 secondary ++ __ double_compare(x10, f11, f10, unordered_result); ++ } ++} ++ ++void TemplateTable::branch(bool is_jsr, bool is_wide) ++{ ++ __ profile_taken_branch(x10, x11); ++ const ByteSize be_offset = MethodCounters::backedge_counter_offset() + ++ InvocationCounter::counter_offset(); ++ const ByteSize inv_offset = MethodCounters::invocation_counter_offset() + ++ InvocationCounter::counter_offset(); ++ ++ // load branch displacement ++ if (!is_wide) { ++ __ lhu(x12, at_bcp(1)); ++ __ revb_h_h(x12, x12); // reverse bytes in half-word and sign-extend ++ } else { ++ __ lwu(x12, at_bcp(1)); ++ __ revb_w_w(x12, x12); // reverse bytes in word and sign-extend ++ } ++ ++ // Handle all the JSR stuff here, then exit. ++ // It's much shorter and cleaner than intermingling with the non-JSR ++ // normal-branch stuff occurring below. ++ ++ if (is_jsr) { ++ // compute return address as bci ++ __ ld(t1, Address(xmethod, Method::const_offset())); ++ __ add(t1, t1, ++ in_bytes(ConstMethod::codes_offset()) - (is_wide ? 5 : 3)); ++ __ sub(x11, xbcp, t1); ++ __ push_i(x11); ++ // Adjust the bcp by the 16-bit displacement in x12 ++ __ add(xbcp, xbcp, x12); ++ __ load_unsigned_byte(t0, Address(xbcp, 0)); ++ // load the next target bytecode into t0, it is the argument of dispatch_only ++ __ dispatch_only(vtos, /*generate_poll*/true); ++ return; ++ } ++ ++ // Normal (non-jsr) branch handling ++ ++ // Adjust the bcp by the displacement in x12 ++ __ add(xbcp, xbcp, x12); ++ ++ assert(UseLoopCounter || !UseOnStackReplacement, ++ "on-stack-replacement requires loop counters"); ++ Label backedge_counter_overflow; ++ Label dispatch; ++ if (UseLoopCounter) { ++ // increment backedge counter for backward branches ++ // x10: MDO ++ // x11: MDO bumped taken-count ++ // x12: target offset ++ __ bgtz(x12, dispatch); // count only if backward branch ++ ++ // check if MethodCounters exists ++ Label has_counters; ++ __ ld(t0, Address(xmethod, Method::method_counters_offset())); ++ __ bnez(t0, has_counters); ++ __ push_reg(x10); ++ __ push_reg(x11); ++ __ push_reg(x12); ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::build_method_counters), xmethod); ++ __ pop_reg(x12); ++ __ pop_reg(x11); ++ __ pop_reg(x10); ++ __ ld(t0, Address(xmethod, Method::method_counters_offset())); ++ __ beqz(t0, dispatch); // No MethodCounters allocated, OutOfMemory ++ __ bind(has_counters); ++ ++ Label no_mdo; ++ int increment = InvocationCounter::count_increment; ++ if (ProfileInterpreter) { ++ // Are we profiling? ++ __ ld(x11, Address(xmethod, in_bytes(Method::method_data_offset()))); ++ __ beqz(x11, no_mdo); ++ // Increment the MDO backedge counter ++ const Address mdo_backedge_counter(x11, in_bytes(MethodData::backedge_counter_offset()) + ++ in_bytes(InvocationCounter::counter_offset())); ++ const Address mask(x11, in_bytes(MethodData::backedge_mask_offset())); ++ __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, ++ x10, t0, false, ++ UseOnStackReplacement ? &backedge_counter_overflow : &dispatch); ++ __ j(dispatch); ++ } ++ __ bind(no_mdo); ++ // Increment backedge counter in MethodCounters* ++ __ ld(t0, Address(xmethod, Method::method_counters_offset())); ++ const Address mask(t0, in_bytes(MethodCounters::backedge_mask_offset())); ++ __ increment_mask_and_jump(Address(t0, be_offset), increment, mask, ++ x10, t1, false, ++ UseOnStackReplacement ? &backedge_counter_overflow : &dispatch); ++ __ bind(dispatch); ++ } ++ ++ // Pre-load the next target bytecode into t0 ++ __ load_unsigned_byte(t0, Address(xbcp, 0)); ++ ++ // continue with the bytecode @ target ++ // t0: target bytecode ++ // xbcp: target bcp ++ __ dispatch_only(vtos, /*generate_poll*/true); ++ ++ if (UseLoopCounter && UseOnStackReplacement) { ++ // invocation counter overflow ++ __ bind(backedge_counter_overflow); ++ __ neg(x12, x12); ++ __ add(x12, x12, xbcp); // branch xbcp ++ // IcoResult frequency_counter_overflow([JavaThread*], address branch_bcp) ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::frequency_counter_overflow), ++ x12); ++ __ load_unsigned_byte(x11, Address(xbcp, 0)); // restore target bytecode ++ ++ // x10: osr nmethod (osr ok) or NULL (osr not possible) ++ // w11: target bytecode ++ // x12: temporary ++ __ beqz(x10, dispatch); // test result -- no osr if null ++ // nmethod may have been invalidated (VM may block upon call_VM return) ++ __ lbu(x12, Address(x10, nmethod::state_offset())); ++ if (nmethod::in_use != 0) { ++ __ sub(x12, x12, nmethod::in_use); ++ } ++ __ bnez(x12, dispatch); ++ ++ // We have the address of an on stack replacement routine in x10 ++ // We need to prepare to execute the OSR method. First we must ++ // migrate the locals and monitors off of the stack. ++ ++ __ mv(x9, x10); // save the nmethod ++ ++ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin)); ++ ++ // x10 is OSR buffer, move it to expected parameter location ++ __ mv(j_rarg0, x10); ++ ++ // remove activation ++ // get sender esp ++ __ ld(esp, ++ Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize)); ++ // remove frame anchor ++ __ leave(); ++ // Ensure compiled code always sees stack at proper alignment ++ __ andi(sp, esp, -16); ++ ++ // and begin the OSR nmethod ++ __ ld(t0, Address(x9, nmethod::osr_entry_point_offset())); ++ __ jr(t0); ++ } ++} ++ ++void TemplateTable::if_0cmp(Condition cc) ++{ ++ transition(itos, vtos); ++ // assume branch is more often taken than not (loops use backward branches) ++ Label not_taken; ++ ++ __ sign_extend(x10, x10, 32); ++ switch (cc) { ++ case equal: ++ __ bnez(x10, not_taken); ++ break; ++ case not_equal: ++ __ beqz(x10, not_taken); ++ break; ++ case less: ++ __ bgez(x10, not_taken); ++ break; ++ case less_equal: ++ __ bgtz(x10, not_taken); ++ break; ++ case greater: ++ __ blez(x10, not_taken); ++ break; ++ case greater_equal: ++ __ bltz(x10, not_taken); ++ break; ++ default: ++ break; ++ } ++ ++ branch(false, false); ++ __ bind(not_taken); ++ __ profile_not_taken_branch(x10); ++} ++ ++void TemplateTable::if_icmp(Condition cc) ++{ ++ transition(itos, vtos); ++ // assume branch is more often taken than not (loops use backward branches) ++ Label not_taken; ++ __ pop_i(x11); ++ __ sign_extend(x10, x10, 32); ++ switch (cc) { ++ case equal: ++ __ bne(x11, x10, not_taken); ++ break; ++ case not_equal: ++ __ beq(x11, x10, not_taken); ++ break; ++ case less: ++ __ bge(x11, x10, not_taken); ++ break; ++ case less_equal: ++ __ bgt(x11, x10, not_taken); ++ break; ++ case greater: ++ __ ble(x11, x10, not_taken); ++ break; ++ case greater_equal: ++ __ blt(x11, x10, not_taken); ++ break; ++ default: ++ break; ++ } ++ ++ branch(false, false); ++ __ bind(not_taken); ++ __ profile_not_taken_branch(x10); ++} ++ ++void TemplateTable::if_nullcmp(Condition cc) ++{ ++ transition(atos, vtos); ++ // assume branch is more often taken than not (loops use backward branches) ++ Label not_taken; ++ if (cc == equal) { ++ __ bnez(x10, not_taken); ++ } else { ++ __ beqz(x10, not_taken); ++ } ++ branch(false, false); ++ __ bind(not_taken); ++ __ profile_not_taken_branch(x10); ++} ++ ++void TemplateTable::if_acmp(Condition cc) ++{ ++ transition(atos, vtos); ++ // assume branch is more often taken than not (loops use backward branches) ++ Label not_taken; ++ __ pop_ptr(x11); ++ ++ if (cc == equal) { ++ __ bne(x11, x10, not_taken); ++ } else if (cc == not_equal) { ++ __ beq(x11, x10, not_taken); ++ } ++ branch(false, false); ++ __ bind(not_taken); ++ __ profile_not_taken_branch(x10); ++} ++ ++void TemplateTable::ret() { ++ transition(vtos, vtos); ++ locals_index(x11); ++ __ ld(x11, aaddress(x11, t1, _masm)); // get return bci, compute return bcp ++ __ profile_ret(x11, x12); ++ __ ld(xbcp, Address(xmethod, Method::const_offset())); ++ __ add(xbcp, xbcp, x11); ++ __ addi(xbcp, xbcp, in_bytes(ConstMethod::codes_offset())); ++ __ dispatch_next(vtos, 0, /*generate_poll*/true); ++} ++ ++void TemplateTable::wide_ret() { ++ transition(vtos, vtos); ++ locals_index_wide(x11); ++ __ ld(x11, aaddress(x11, t0, _masm)); // get return bci, compute return bcp ++ __ profile_ret(x11, x12); ++ __ ld(xbcp, Address(xmethod, Method::const_offset())); ++ __ add(xbcp, xbcp, x11); ++ __ add(xbcp, xbcp, in_bytes(ConstMethod::codes_offset())); ++ __ dispatch_next(vtos, 0, /*generate_poll*/true); ++} ++ ++void TemplateTable::tableswitch() { ++ Label default_case, continue_execution; ++ transition(itos, vtos); ++ // align xbcp ++ __ la(x11, at_bcp(BytesPerInt)); ++ __ andi(x11, x11, -BytesPerInt); ++ // load lo & hi ++ __ lwu(x12, Address(x11, BytesPerInt)); ++ __ lwu(x13, Address(x11, 2 * BytesPerInt)); ++ __ revb_w_w(x12, x12); // reverse bytes in word (32bit) and sign-extend ++ __ revb_w_w(x13, x13); // reverse bytes in word (32bit) and sign-extend ++ // check against lo & hi ++ __ blt(x10, x12, default_case); ++ __ bgt(x10, x13, default_case); ++ // lookup dispatch offset ++ __ subw(x10, x10, x12); ++ __ shadd(x13, x10, x11, t0, 2); ++ __ lwu(x13, Address(x13, 3 * BytesPerInt)); ++ __ profile_switch_case(x10, x11, x12); ++ // continue execution ++ __ bind(continue_execution); ++ __ revb_w_w(x13, x13); // reverse bytes in word (32bit) and sign-extend ++ __ add(xbcp, xbcp, x13); ++ __ load_unsigned_byte(t0, Address(xbcp)); ++ __ dispatch_only(vtos, /*generate_poll*/true); ++ // handle default ++ __ bind(default_case); ++ __ profile_switch_default(x10); ++ __ lwu(x13, Address(x11, 0)); ++ __ j(continue_execution); ++} ++ ++void TemplateTable::lookupswitch() { ++ transition(itos, itos); ++ __ stop("lookupswitch bytecode should have been rewritten"); ++} ++ ++void TemplateTable::fast_linearswitch() { ++ transition(itos, vtos); ++ Label loop_entry, loop, found, continue_execution; ++ // bswap x10 so we can avoid bswapping the table entries ++ __ revb_w_w(x10, x10); // reverse bytes in word (32bit) and sign-extend ++ // align xbcp ++ __ la(x9, at_bcp(BytesPerInt)); // btw: should be able to get rid of ++ // this instruction (change offsets ++ // below) ++ __ andi(x9, x9, -BytesPerInt); ++ // set counter ++ __ lwu(x11, Address(x9, BytesPerInt)); ++ __ revb_w(x11, x11); ++ __ j(loop_entry); ++ // table search ++ __ bind(loop); ++ __ shadd(t0, x11, x9, t0, 3); ++ __ lw(t0, Address(t0, 2 * BytesPerInt)); ++ __ beq(x10, t0, found); ++ __ bind(loop_entry); ++ __ addi(x11, x11, -1); ++ __ bgez(x11, loop); ++ // default case ++ __ profile_switch_default(x10); ++ __ lwu(x13, Address(x9, 0)); ++ __ j(continue_execution); ++ // entry found -> get offset ++ __ bind(found); ++ __ shadd(t0, x11, x9, t0, 3); ++ __ lwu(x13, Address(t0, 3 * BytesPerInt)); ++ __ profile_switch_case(x11, x10, x9); ++ // continue execution ++ __ bind(continue_execution); ++ __ revb_w_w(x13, x13); // reverse bytes in word (32bit) and sign-extend ++ __ add(xbcp, xbcp, x13); ++ __ lbu(t0, Address(xbcp, 0)); ++ __ dispatch_only(vtos, /*generate_poll*/true); ++} ++ ++void TemplateTable::fast_binaryswitch() { ++ transition(itos, vtos); ++ // Implementation using the following core algorithm: ++ // ++ // int binary_search(int key, LookupswitchPair* array, int n) ++ // binary_search start: ++ // #Binary search according to "Methodik des Programmierens" by ++ // # Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985. ++ // int i = 0; ++ // int j = n; ++ // while (i + 1 < j) do ++ // # invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q) ++ // # with Q: for all i: 0 <= i < n: key < a[i] ++ // # where a stands for the array and assuming that the (inexisting) ++ // # element a[n] is infinitely big. ++ // int h = (i + j) >> 1 ++ // # i < h < j ++ // if (key < array[h].fast_match()) ++ // then [j = h] ++ // else [i = h] ++ // end ++ // # R: a[i] <= key < a[i+1] or Q ++ // # (i.e., if key is within array, i is the correct index) ++ // return i ++ // binary_search end ++ ++ ++ // Register allocation ++ const Register key = x10; // already set (tosca) ++ const Register array = x11; ++ const Register i = x12; ++ const Register j = x13; ++ const Register h = x14; ++ const Register temp = x15; ++ ++ // Find array start ++ __ la(array, at_bcp(3 * BytesPerInt)); // btw: should be able to ++ // get rid of this ++ // instruction (change ++ // offsets below) ++ __ andi(array, array, -BytesPerInt); ++ ++ // Initialize i & j ++ __ mv(i, zr); // i = 0 ++ __ lwu(j, Address(array, -BytesPerInt)); // j = length(array) ++ ++ // Convert j into native byteordering ++ __ revb_w(j, j); ++ ++ // And start ++ Label entry; ++ __ j(entry); ++ ++ // binary search loop ++ { ++ Label loop; ++ __ bind(loop); ++ __ addw(h, i, j); // h = i + j ++ __ srliw(h, h, 1); // h = (i + j) >> 1 ++ // if [key < array[h].fast_match()] ++ // then [j = h] ++ // else [i = h] ++ // Convert array[h].match to native byte-ordering before compare ++ __ shadd(temp, h, array, temp, 3); ++ __ ld(temp, Address(temp, 0)); ++ __ revb_w_w(temp, temp); // reverse bytes in word (32bit) and sign-extend ++ ++ Label L_done, L_greater; ++ __ bge(key, temp, L_greater); ++ // if [key < array[h].fast_match()] then j = h ++ __ mv(j, h); ++ __ j(L_done); ++ __ bind(L_greater); ++ // if [key >= array[h].fast_match()] then i = h ++ __ mv(i, h); ++ __ bind(L_done); ++ ++ // while [i + 1 < j] ++ __ bind(entry); ++ __ addiw(h, i, 1); // i + 1 ++ __ blt(h, j, loop); // i + 1 < j ++ } ++ ++ // end of binary search, result index is i (must check again!) ++ Label default_case; ++ // Convert array[i].match to native byte-ordering before compare ++ __ shadd(temp, i, array, temp, 3); ++ __ ld(temp, Address(temp, 0)); ++ __ revb_w_w(temp, temp); // reverse bytes in word (32bit) and sign-extend ++ __ bne(key, temp, default_case); ++ ++ // entry found -> j = offset ++ __ shadd(temp, i, array, temp, 3); ++ __ lwu(j, Address(temp, BytesPerInt)); ++ __ profile_switch_case(i, key, array); ++ __ revb_w_w(j, j); // reverse bytes in word (32bit) and sign-extend ++ ++ __ add(temp, xbcp, j); ++ __ load_unsigned_byte(t0, Address(temp, 0)); ++ ++ __ add(xbcp, xbcp, j); ++ __ la(xbcp, Address(xbcp, 0)); ++ __ dispatch_only(vtos, /*generate_poll*/true); ++ ++ // default case -> j = default offset ++ __ bind(default_case); ++ __ profile_switch_default(i); ++ __ lwu(j, Address(array, -2 * BytesPerInt)); ++ __ revb_w_w(j, j); // reverse bytes in word (32bit) and sign-extend ++ ++ __ add(temp, xbcp, j); ++ __ load_unsigned_byte(t0, Address(temp, 0)); ++ ++ __ add(xbcp, xbcp, j); ++ __ la(xbcp, Address(xbcp, 0)); ++ __ dispatch_only(vtos, /*generate_poll*/true); ++} ++ ++void TemplateTable::_return(TosState state) ++{ ++ transition(state, state); ++ assert(_desc->calls_vm(), ++ "inconsistent calls_vm information"); // call in remove_activation ++ ++ if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { ++ assert(state == vtos, "only valid state"); ++ ++ __ ld(c_rarg1, aaddress(0)); ++ __ load_klass(x13, c_rarg1); ++ __ lwu(x13, Address(x13, Klass::access_flags_offset())); ++ Label skip_register_finalizer; ++ __ test_bit(t0, x13, exact_log2(JVM_ACC_HAS_FINALIZER)); ++ __ beqz(t0, skip_register_finalizer); ++ ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), c_rarg1); ++ ++ __ bind(skip_register_finalizer); ++ } ++ ++ // Issue a StoreStore barrier after all stores but before return ++ // from any constructor for any class with a final field. We don't ++ // know if this is a finalizer, so we always do so. ++ if (_desc->bytecode() == Bytecodes::_return) { ++ __ membar(MacroAssembler::StoreStore); ++ } ++ ++ // Narrow result if state is itos but result type is smaller. ++ // Need to narrow in the return bytecode rather than in generate_return_entry ++ // since compiled code callers expect the result to already be narrowed. ++ if (state == itos) { ++ __ narrow(x10); ++ } ++ ++ __ remove_activation(state); ++ __ ret(); ++} ++ ++ ++// ---------------------------------------------------------------------------- ++// Volatile variables demand their effects be made known to all CPU's ++// in order. Store buffers on most chips allow reads & writes to ++// reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode ++// without some kind of memory barrier (i.e., it's not sufficient that ++// the interpreter does not reorder volatile references, the hardware ++// also must not reorder them). ++// ++// According to the new Java Memory Model (JMM): ++// (1) All volatiles are serialized wrt to each other. ALSO reads & ++// writes act as aquire & release, so: ++// (2) A read cannot let unrelated NON-volatile memory refs that ++// happen after the read float up to before the read. It's OK for ++// non-volatile memory refs that happen before the volatile read to ++// float down below it. ++// (3) Similar a volatile write cannot let unrelated NON-volatile ++// memory refs that happen BEFORE the write float down to after the ++// write. It's OK for non-volatile memory refs that happen after the ++// volatile write to float up before it. ++// ++// We only put in barriers around volatile refs (they are expensive), ++// not _between_ memory refs (that would require us to track the ++// flavor of the previous memory refs). Requirements (2) and (3) ++// require some barriers before volatile stores and after volatile ++// loads. These nearly cover requirement (1) but miss the ++// volatile-store-volatile-load case. This final case is placed after ++// volatile-stores although it could just as well go before ++// volatile-loads. ++ ++void TemplateTable::resolve_cache_and_index(int byte_no, ++ Register Rcache, ++ Register index, ++ size_t index_size) { ++ const Register temp = x9; ++ assert_different_registers(Rcache, index, temp); ++ ++ Label resolved, clinit_barrier_slow; ++ ++ Bytecodes::Code code = bytecode(); ++ switch (code) { ++ case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break; ++ case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break; ++ default: break; ++ } ++ ++ assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); ++ __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size); ++ __ mv(t0, (int) code); ++ __ beq(temp, t0, resolved); ++ ++ // resolve first time through ++ // Class initialization barrier slow path lands here as well. ++ __ bind(clinit_barrier_slow); ++ ++ address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache); ++ __ mv(temp, (int) code); ++ __ call_VM(noreg, entry, temp); ++ ++ // Update registers with resolved info ++ __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); ++ // n.b. unlike x86 Rcache is now rcpool plus the indexed offset ++ // so all clients ofthis method must be modified accordingly ++ __ bind(resolved); ++ ++ // Class initialization barrier for static methods ++ if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) { ++ __ load_resolved_method_at_index(byte_no, temp, Rcache); ++ __ load_method_holder(temp, temp); ++ __ clinit_barrier(temp, t0, NULL, &clinit_barrier_slow); ++ } ++} ++ ++// The Rcache and index registers must be set before call ++// n.b unlike x86 cache already includes the index offset ++void TemplateTable::load_field_cp_cache_entry(Register obj, ++ Register cache, ++ Register index, ++ Register off, ++ Register flags, ++ bool is_static = false) { ++ assert_different_registers(cache, index, flags, off); ++ ++ ByteSize cp_base_offset = ConstantPoolCache::base_offset(); ++ // Field offset ++ __ ld(off, Address(cache, in_bytes(cp_base_offset + ++ ConstantPoolCacheEntry::f2_offset()))); ++ // Flags ++ __ lwu(flags, Address(cache, in_bytes(cp_base_offset + ++ ConstantPoolCacheEntry::flags_offset()))); ++ ++ // klass overwrite register ++ if (is_static) { ++ __ ld(obj, Address(cache, in_bytes(cp_base_offset + ++ ConstantPoolCacheEntry::f1_offset()))); ++ const int mirror_offset = in_bytes(Klass::java_mirror_offset()); ++ __ ld(obj, Address(obj, mirror_offset)); ++ __ resolve_oop_handle(obj); ++ } ++} ++ ++void TemplateTable::load_invoke_cp_cache_entry(int byte_no, ++ Register method, ++ Register itable_index, ++ Register flags, ++ bool is_invokevirtual, ++ bool is_invokevfinal, /*unused*/ ++ bool is_invokedynamic) { ++ // setup registers ++ const Register cache = t1; ++ const Register index = x14; ++ assert_different_registers(method, flags); ++ assert_different_registers(method, cache, index); ++ assert_different_registers(itable_index, flags); ++ assert_different_registers(itable_index, cache, index); ++ // determine constant pool cache field offsets ++ assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant"); ++ const int method_offset = in_bytes(ConstantPoolCache::base_offset() + ++ (is_invokevirtual ? ++ ConstantPoolCacheEntry::f2_offset() : ++ ConstantPoolCacheEntry::f1_offset())); ++ const int flags_offset = in_bytes(ConstantPoolCache::base_offset() + ++ ConstantPoolCacheEntry::flags_offset()); ++ // access constant pool cache fields ++ const int index_offset = in_bytes(ConstantPoolCache::base_offset() + ++ ConstantPoolCacheEntry::f2_offset()); ++ ++ const size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2)); ++ resolve_cache_and_index(byte_no, cache, index, index_size); ++ __ ld(method, Address(cache, method_offset)); ++ ++ if (itable_index != noreg) { ++ __ ld(itable_index, Address(cache, index_offset)); ++ } ++ __ lwu(flags, Address(cache, flags_offset)); ++} ++ ++// The registers cache and index expected to be set before call. ++// Correct values of the cache and index registers are preserved. ++void TemplateTable::jvmti_post_field_access(Register cache, Register index, ++ bool is_static, bool has_tos) { ++ // do the JVMTI work here to avoid disturbing the register state below ++ // We use c_rarg registers here beacause we want to use the register used in ++ // the call to the VM ++ if (JvmtiExport::can_post_field_access()) { ++ // Check to see if a field access watch has been set before we ++ // take the time to call into the VM. ++ Label L1; ++ assert_different_registers(cache, index, x10); ++ ExternalAddress target((address) JvmtiExport::get_field_access_count_addr()); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ lwu(x10, Address(t0, offset)); ++ }); ++ ++ __ beqz(x10, L1); ++ ++ __ get_cache_and_index_at_bcp(c_rarg2, c_rarg3, 1); ++ __ la(c_rarg2, Address(c_rarg2, in_bytes(ConstantPoolCache::base_offset()))); ++ ++ if (is_static) { ++ __ mv(c_rarg1, zr); // NULL object reference ++ } else { ++ __ ld(c_rarg1, at_tos()); // get object pointer without popping it ++ __ verify_oop(c_rarg1); ++ } ++ // c_rarg1: object pointer or NULL ++ // c_rarg2: cache entry pointer ++ // c_rarg3: jvalue object on the stack ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::post_field_access), ++ c_rarg1, c_rarg2, c_rarg3); ++ __ get_cache_and_index_at_bcp(cache, index, 1); ++ __ bind(L1); ++ } ++} ++ ++void TemplateTable::pop_and_check_object(Register r) ++{ ++ __ pop_ptr(r); ++ __ null_check(r); // for field access must check obj. ++ __ verify_oop(r); ++} ++ ++void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) ++{ ++ const Register cache = x12; ++ const Register index = x13; ++ const Register obj = x14; ++ const Register off = x9; ++ const Register flags = x10; ++ const Register raw_flags = x16; ++ const Register bc = x14; // uses same reg as obj, so don't mix them ++ ++ resolve_cache_and_index(byte_no, cache, index, sizeof(u2)); ++ jvmti_post_field_access(cache, index, is_static, false); ++ load_field_cp_cache_entry(obj, cache, index, off, raw_flags, is_static); ++ ++ if (!is_static) { ++ // obj is on the stack ++ pop_and_check_object(obj); ++ } ++ ++ __ add(off, obj, off); ++ const Address field(off); ++ ++ Label Done, notByte, notBool, notInt, notShort, notChar, ++ notLong, notFloat, notObj, notDouble; ++ ++ __ slli(flags, raw_flags, XLEN - (ConstantPoolCacheEntry::tos_state_shift + ++ ConstantPoolCacheEntry::tos_state_bits)); ++ __ srli(flags, flags, XLEN - ConstantPoolCacheEntry::tos_state_bits); ++ ++ assert(btos == 0, "change code, btos != 0"); ++ __ bnez(flags, notByte); ++ ++ // Dont't rewrite getstatic, only getfield ++ if (is_static) { ++ rc = may_not_rewrite; ++ } ++ ++ // btos ++ __ access_load_at(T_BYTE, IN_HEAP, x10, field, noreg, noreg); ++ __ push(btos); ++ // Rewrite bytecode to be faster ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_bgetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notByte); ++ __ sub(t0, flags, (u1)ztos); ++ __ bnez(t0, notBool); ++ ++ // ztos (same code as btos) ++ __ access_load_at(T_BOOLEAN, IN_HEAP, x10, field, noreg, noreg); ++ __ push(ztos); ++ // Rewirte bytecode to be faster ++ if (rc == may_rewrite) { ++ // uses btos rewriting, no truncating to t/f bit is needed for getfield ++ patch_bytecode(Bytecodes::_fast_bgetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notBool); ++ __ sub(t0, flags, (u1)atos); ++ __ bnez(t0, notObj); ++ // atos ++ do_oop_load(_masm, field, x10, IN_HEAP); ++ __ push(atos); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_agetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notObj); ++ __ sub(t0, flags, (u1)itos); ++ __ bnez(t0, notInt); ++ // itos ++ __ access_load_at(T_INT, IN_HEAP, x10, field, noreg, noreg); ++ __ sign_extend(x10, x10, 32); ++ __ push(itos); ++ // Rewrite bytecode to be faster ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_igetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notInt); ++ __ sub(t0, flags, (u1)ctos); ++ __ bnez(t0, notChar); ++ // ctos ++ __ access_load_at(T_CHAR, IN_HEAP, x10, field, noreg, noreg); ++ __ push(ctos); ++ // Rewrite bytecode to be faster ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_cgetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notChar); ++ __ sub(t0, flags, (u1)stos); ++ __ bnez(t0, notShort); ++ // stos ++ __ access_load_at(T_SHORT, IN_HEAP, x10, field, noreg, noreg); ++ __ push(stos); ++ // Rewrite bytecode to be faster ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_sgetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notShort); ++ __ sub(t0, flags, (u1)ltos); ++ __ bnez(t0, notLong); ++ // ltos ++ __ access_load_at(T_LONG, IN_HEAP, x10, field, noreg, noreg); ++ __ push(ltos); ++ // Rewrite bytecode to be faster ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_lgetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notLong); ++ __ sub(t0, flags, (u1)ftos); ++ __ bnez(t0, notFloat); ++ // ftos ++ __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg); ++ __ push(ftos); ++ // Rewrite bytecode to be faster ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_fgetfield, bc, x11); ++ } ++ __ j(Done); ++ ++ __ bind(notFloat); ++#ifdef ASSERT ++ __ sub(t0, flags, (u1)dtos); ++ __ bnez(t0, notDouble); ++#endif ++ // dtos ++ __ access_load_at(T_DOUBLE, IN_HEAP, noreg /* ftos */, field, noreg, noreg); ++ __ push(dtos); ++ // Rewrite bytecode to be faster ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_dgetfield, bc, x11); ++ } ++#ifdef ASSERT ++ __ j(Done); ++ ++ __ bind(notDouble); ++ __ stop("Bad state"); ++#endif ++ ++ __ bind(Done); ++ ++ Label notVolatile; ++ __ test_bit(t0, raw_flags, ConstantPoolCacheEntry::is_volatile_shift); ++ __ beqz(t0, notVolatile); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ __ bind(notVolatile); ++} ++ ++void TemplateTable::getfield(int byte_no) ++{ ++ getfield_or_static(byte_no, false); ++} ++ ++void TemplateTable::nofast_getfield(int byte_no) { ++ getfield_or_static(byte_no, false, may_not_rewrite); ++} ++ ++void TemplateTable::getstatic(int byte_no) ++{ ++ getfield_or_static(byte_no, true); ++} ++ ++// The registers cache and index expected to be set before call. ++// The function may destroy various registers, just not the cache and index registers. ++void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) { ++ transition(vtos, vtos); ++ ++ ByteSize cp_base_offset = ConstantPoolCache::base_offset(); ++ ++ if (JvmtiExport::can_post_field_modification()) { ++ // Check to see if a field modification watch has been set before ++ // we take the time to call into the VM. ++ Label L1; ++ assert_different_registers(cache, index, x10); ++ ExternalAddress target((address)JvmtiExport::get_field_modification_count_addr()); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ lwu(x10, Address(t0, offset)); ++ }); ++ __ beqz(x10, L1); ++ ++ __ get_cache_and_index_at_bcp(c_rarg2, t0, 1); ++ ++ if (is_static) { ++ // Life is simple. Null out the object pointer. ++ __ mv(c_rarg1, zr); ++ } else { ++ // Life is harder. The stack holds the value on top, followed by ++ // the object. We don't know the size of the value, though; it ++ // could be one or two words depending on its type. As a result, ++ // we must find the type to determine where the object is. ++ __ lwu(c_rarg3, Address(c_rarg2, ++ in_bytes(cp_base_offset + ++ ConstantPoolCacheEntry::flags_offset()))); ++ __ srli(c_rarg3, c_rarg3, ConstantPoolCacheEntry::tos_state_shift); ++ ConstantPoolCacheEntry::verify_tos_state_shift(); ++ Label nope2, done, ok; ++ __ ld(c_rarg1, at_tos_p1()); // initially assume a one word jvalue ++ __ sub(t0, c_rarg3, ltos); ++ __ beqz(t0, ok); ++ __ sub(t0, c_rarg3, dtos); ++ __ bnez(t0, nope2); ++ __ bind(ok); ++ __ ld(c_rarg1, at_tos_p2()); // ltos (two word jvalue); ++ __ bind(nope2); ++ } ++ // cache entry pointer ++ __ add(c_rarg2, c_rarg2, in_bytes(cp_base_offset)); ++ // object (tos) ++ __ mv(c_rarg3, esp); ++ // c_rarg1: object pointer set up above (NULL if static) ++ // c_rarg2: cache entry pointer ++ // c_rarg3: jvalue object on the stack ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::post_field_modification), ++ c_rarg1, c_rarg2, c_rarg3); ++ __ get_cache_and_index_at_bcp(cache, index, 1); ++ __ bind(L1); ++ } ++} ++ ++void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) { ++ transition(vtos, vtos); ++ ++ const Register cache = x12; ++ const Register index = x13; ++ const Register obj = x12; ++ const Register off = x9; ++ const Register flags = x10; ++ const Register bc = x14; ++ ++ resolve_cache_and_index(byte_no, cache, index, sizeof(u2)); ++ jvmti_post_field_mod(cache, index, is_static); ++ load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); ++ ++ Label Done; ++ __ mv(x15, flags); ++ ++ { ++ Label notVolatile; ++ __ test_bit(t0, x15, ConstantPoolCacheEntry::is_volatile_shift); ++ __ beqz(t0, notVolatile); ++ __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore); ++ __ bind(notVolatile); ++ } ++ ++ Label notByte, notBool, notInt, notShort, notChar, ++ notLong, notFloat, notObj, notDouble; ++ ++ __ slli(flags, flags, XLEN - (ConstantPoolCacheEntry::tos_state_shift + ++ ConstantPoolCacheEntry::tos_state_bits)); ++ __ srli(flags, flags, XLEN - ConstantPoolCacheEntry::tos_state_bits); ++ ++ assert(btos == 0, "change code, btos != 0"); ++ __ bnez(flags, notByte); ++ ++ // Don't rewrite putstatic, only putfield ++ if (is_static) { ++ rc = may_not_rewrite; ++ } ++ ++ // btos ++ { ++ __ pop(btos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); // off register as temparator register. ++ __ access_store_at(T_BYTE, IN_HEAP, field, x10, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_bputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notByte); ++ __ sub(t0, flags, (u1)ztos); ++ __ bnez(t0, notBool); ++ ++ // ztos ++ { ++ __ pop(ztos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ __ access_store_at(T_BOOLEAN, IN_HEAP, field, x10, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_zputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notBool); ++ __ sub(t0, flags, (u1)atos); ++ __ bnez(t0, notObj); ++ ++ // atos ++ { ++ __ pop(atos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ // Store into the field ++ do_oop_store(_masm, field, x10, IN_HEAP); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_aputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notObj); ++ __ sub(t0, flags, (u1)itos); ++ __ bnez(t0, notInt); ++ ++ // itos ++ { ++ __ pop(itos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ __ access_store_at(T_INT, IN_HEAP, field, x10, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_iputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notInt); ++ __ sub(t0, flags, (u1)ctos); ++ __ bnez(t0, notChar); ++ ++ // ctos ++ { ++ __ pop(ctos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ __ access_store_at(T_CHAR, IN_HEAP, field, x10, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_cputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notChar); ++ __ sub(t0, flags, (u1)stos); ++ __ bnez(t0, notShort); ++ ++ // stos ++ { ++ __ pop(stos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ __ access_store_at(T_SHORT, IN_HEAP, field, x10, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_sputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notShort); ++ __ sub(t0, flags, (u1)ltos); ++ __ bnez(t0, notLong); ++ ++ // ltos ++ { ++ __ pop(ltos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ __ access_store_at(T_LONG, IN_HEAP, field, x10, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_lputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notLong); ++ __ sub(t0, flags, (u1)ftos); ++ __ bnez(t0, notFloat); ++ ++ // ftos ++ { ++ __ pop(ftos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ __ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos */, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_fputfield, bc, x11, true, byte_no); ++ } ++ __ j(Done); ++ } ++ ++ __ bind(notFloat); ++#ifdef ASSERT ++ __ sub(t0, flags, (u1)dtos); ++ __ bnez(t0, notDouble); ++#endif ++ ++ // dtos ++ { ++ __ pop(dtos); ++ // field address ++ if (!is_static) { ++ pop_and_check_object(obj); ++ } ++ __ add(off, obj, off); // if static, obj from cache, else obj from stack. ++ const Address field(off, 0); ++ __ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* dtos */, noreg, noreg); ++ if (rc == may_rewrite) { ++ patch_bytecode(Bytecodes::_fast_dputfield, bc, x11, true, byte_no); ++ } ++ } ++ ++#ifdef ASSERT ++ __ j(Done); ++ ++ __ bind(notDouble); ++ __ stop("Bad state"); ++#endif ++ ++ __ bind(Done); ++ ++ { ++ Label notVolatile; ++ __ test_bit(t0, x15, ConstantPoolCacheEntry::is_volatile_shift); ++ __ beqz(t0, notVolatile); ++ __ membar(MacroAssembler::StoreLoad | MacroAssembler::StoreStore); ++ __ bind(notVolatile); ++ } ++} ++ ++void TemplateTable::putfield(int byte_no) ++{ ++ putfield_or_static(byte_no, false); ++} ++ ++void TemplateTable::nofast_putfield(int byte_no) { ++ putfield_or_static(byte_no, false, may_not_rewrite); ++} ++ ++void TemplateTable::putstatic(int byte_no) { ++ putfield_or_static(byte_no, true); ++} ++ ++void TemplateTable::jvmti_post_fast_field_mod() ++{ ++ if (JvmtiExport::can_post_field_modification()) { ++ // Check to see if a field modification watch has been set before ++ // we take the time to call into the VM. ++ Label L2; ++ ExternalAddress target((address)JvmtiExport::get_field_modification_count_addr()); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ lwu(c_rarg3, Address(t0, offset)); ++ }); ++ __ beqz(c_rarg3, L2); ++ __ pop_ptr(x9); // copy the object pointer from tos ++ __ verify_oop(x9); ++ __ push_ptr(x9); // put the object pointer back on tos ++ // Save tos values before call_VM() clobbers them. Since we have ++ // to do it for every data type, we use the saved values as the ++ // jvalue object. ++ switch (bytecode()) { // load values into the jvalue object ++ case Bytecodes::_fast_aputfield: __ push_ptr(x10); break; ++ case Bytecodes::_fast_bputfield: // fall through ++ case Bytecodes::_fast_zputfield: // fall through ++ case Bytecodes::_fast_sputfield: // fall through ++ case Bytecodes::_fast_cputfield: // fall through ++ case Bytecodes::_fast_iputfield: __ push_i(x10); break; ++ case Bytecodes::_fast_dputfield: __ push_d(); break; ++ case Bytecodes::_fast_fputfield: __ push_f(); break; ++ case Bytecodes::_fast_lputfield: __ push_l(x10); break; ++ ++ default: ++ ShouldNotReachHere(); ++ } ++ __ mv(c_rarg3, esp); // points to jvalue on the stack ++ // access constant pool cache entry ++ __ get_cache_entry_pointer_at_bcp(c_rarg2, x10, 1); ++ __ verify_oop(x9); ++ // x9: object pointer copied above ++ // c_rarg2: cache entry pointer ++ // c_rarg3: jvalue object on the stack ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::post_field_modification), ++ x9, c_rarg2, c_rarg3); ++ ++ switch (bytecode()) { // restore tos values ++ case Bytecodes::_fast_aputfield: __ pop_ptr(x10); break; ++ case Bytecodes::_fast_bputfield: // fall through ++ case Bytecodes::_fast_zputfield: // fall through ++ case Bytecodes::_fast_sputfield: // fall through ++ case Bytecodes::_fast_cputfield: // fall through ++ case Bytecodes::_fast_iputfield: __ pop_i(x10); break; ++ case Bytecodes::_fast_dputfield: __ pop_d(); break; ++ case Bytecodes::_fast_fputfield: __ pop_f(); break; ++ case Bytecodes::_fast_lputfield: __ pop_l(x10); break; ++ default: break; ++ } ++ __ bind(L2); ++ } ++} ++ ++void TemplateTable::fast_storefield(TosState state) ++{ ++ transition(state, vtos); ++ ++ ByteSize base = ConstantPoolCache::base_offset(); ++ ++ jvmti_post_fast_field_mod(); ++ ++ // access constant pool cache ++ __ get_cache_and_index_at_bcp(x12, x11, 1); ++ ++ // Must prevent reordering of the following cp cache loads with bytecode load ++ __ membar(MacroAssembler::LoadLoad); ++ ++ // test for volatile with x13 ++ __ lwu(x13, Address(x12, in_bytes(base + ++ ConstantPoolCacheEntry::flags_offset()))); ++ ++ // replace index with field offset from cache entry ++ __ ld(x11, Address(x12, in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); ++ ++ { ++ Label notVolatile; ++ __ test_bit(t0, x13, ConstantPoolCacheEntry::is_volatile_shift); ++ __ beqz(t0, notVolatile); ++ __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore); ++ __ bind(notVolatile); ++ } ++ ++ // Get object from stack ++ pop_and_check_object(x12); ++ ++ // field address ++ __ add(x11, x12, x11); ++ const Address field(x11, 0); ++ ++ // access field ++ switch (bytecode()) { ++ case Bytecodes::_fast_aputfield: ++ do_oop_store(_masm, field, x10, IN_HEAP); ++ break; ++ case Bytecodes::_fast_lputfield: ++ __ access_store_at(T_LONG, IN_HEAP, field, x10, noreg, noreg); ++ break; ++ case Bytecodes::_fast_iputfield: ++ __ access_store_at(T_INT, IN_HEAP, field, x10, noreg, noreg); ++ break; ++ case Bytecodes::_fast_zputfield: ++ __ access_store_at(T_BOOLEAN, IN_HEAP, field, x10, noreg, noreg); ++ break; ++ case Bytecodes::_fast_bputfield: ++ __ access_store_at(T_BYTE, IN_HEAP, field, x10, noreg, noreg); ++ break; ++ case Bytecodes::_fast_sputfield: ++ __ access_store_at(T_SHORT, IN_HEAP, field, x10, noreg, noreg); ++ break; ++ case Bytecodes::_fast_cputfield: ++ __ access_store_at(T_CHAR, IN_HEAP, field, x10, noreg, noreg); ++ break; ++ case Bytecodes::_fast_fputfield: ++ __ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos */, noreg, noreg); ++ break; ++ case Bytecodes::_fast_dputfield: ++ __ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* dtos */, noreg, noreg); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ ++ { ++ Label notVolatile; ++ __ test_bit(t0, x13, ConstantPoolCacheEntry::is_volatile_shift); ++ __ beqz(t0, notVolatile); ++ __ membar(MacroAssembler::StoreLoad | MacroAssembler::StoreStore); ++ __ bind(notVolatile); ++ } ++} ++ ++void TemplateTable::fast_accessfield(TosState state) ++{ ++ transition(atos, state); ++ // Do the JVMTI work here to avoid disturbing the register state below ++ if (JvmtiExport::can_post_field_access()) { ++ // Check to see if a field access watch has been set before we ++ // take the time to call into the VM. ++ Label L1; ++ ExternalAddress target((address)JvmtiExport::get_field_access_count_addr()); ++ __ relocate(target.rspec(), [&] { ++ int32_t offset; ++ __ la_patchable(t0, target, offset); ++ __ lwu(x12, Address(t0, offset)); ++ }); ++ __ beqz(x12, L1); ++ // access constant pool cache entry ++ __ get_cache_entry_pointer_at_bcp(c_rarg2, t1, 1); ++ __ verify_oop(x10); ++ __ push_ptr(x10); // save object pointer before call_VM() clobbers it ++ __ mv(c_rarg1, x10); ++ // c_rarg1: object pointer copied above ++ // c_rarg2: cache entry pointer ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::post_field_access), ++ c_rarg1, c_rarg2); ++ __ pop_ptr(x10); // restore object pointer ++ __ bind(L1); ++ } ++ ++ // access constant pool cache ++ __ get_cache_and_index_at_bcp(x12, x11, 1); ++ ++ // Must prevent reordering of the following cp cache loads with bytecode load ++ __ membar(MacroAssembler::LoadLoad); ++ ++ __ ld(x11, Address(x12, in_bytes(ConstantPoolCache::base_offset() + ++ ConstantPoolCacheEntry::f2_offset()))); ++ __ lwu(x13, Address(x12, in_bytes(ConstantPoolCache::base_offset() + ++ ConstantPoolCacheEntry::flags_offset()))); ++ ++ // x10: object ++ __ verify_oop(x10); ++ __ null_check(x10); ++ __ add(x11, x10, x11); ++ const Address field(x11, 0); ++ ++ // access field ++ switch (bytecode()) { ++ case Bytecodes::_fast_agetfield: ++ do_oop_load(_masm, field, x10, IN_HEAP); ++ __ verify_oop(x10); ++ break; ++ case Bytecodes::_fast_lgetfield: ++ __ access_load_at(T_LONG, IN_HEAP, x10, field, noreg, noreg); ++ break; ++ case Bytecodes::_fast_igetfield: ++ __ access_load_at(T_INT, IN_HEAP, x10, field, noreg, noreg); ++ __ sign_extend(x10, x10, 32); ++ break; ++ case Bytecodes::_fast_bgetfield: ++ __ access_load_at(T_BYTE, IN_HEAP, x10, field, noreg, noreg); ++ break; ++ case Bytecodes::_fast_sgetfield: ++ __ access_load_at(T_SHORT, IN_HEAP, x10, field, noreg, noreg); ++ break; ++ case Bytecodes::_fast_cgetfield: ++ __ access_load_at(T_CHAR, IN_HEAP, x10, field, noreg, noreg); ++ break; ++ case Bytecodes::_fast_fgetfield: ++ __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg); ++ break; ++ case Bytecodes::_fast_dgetfield: ++ __ access_load_at(T_DOUBLE, IN_HEAP, noreg /* dtos */, field, noreg, noreg); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ { ++ Label notVolatile; ++ __ test_bit(t0, x13, ConstantPoolCacheEntry::is_volatile_shift); ++ __ beqz(t0, notVolatile); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ __ bind(notVolatile); ++ } ++} ++ ++void TemplateTable::fast_xaccess(TosState state) ++{ ++ transition(vtos, state); ++ ++ // get receiver ++ __ ld(x10, aaddress(0)); ++ // access constant pool cache ++ __ get_cache_and_index_at_bcp(x12, x13, 2); ++ __ ld(x11, Address(x12, in_bytes(ConstantPoolCache::base_offset() + ++ ConstantPoolCacheEntry::f2_offset()))); ++ ++ // make sure exception is reported in correct bcp range (getfield is ++ // next instruction) ++ __ addi(xbcp, xbcp, 1); ++ __ null_check(x10); ++ switch (state) { ++ case itos: ++ __ add(x10, x10, x11); ++ __ access_load_at(T_INT, IN_HEAP, x10, Address(x10, 0), noreg, noreg); ++ __ sign_extend(x10, x10, 32); ++ break; ++ case atos: ++ __ add(x10, x10, x11); ++ do_oop_load(_masm, Address(x10, 0), x10, IN_HEAP); ++ __ verify_oop(x10); ++ break; ++ case ftos: ++ __ add(x10, x10, x11); ++ __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, Address(x10), noreg, noreg); ++ break; ++ default: ++ ShouldNotReachHere(); ++ } ++ ++ { ++ Label notVolatile; ++ __ lwu(x13, Address(x12, in_bytes(ConstantPoolCache::base_offset() + ++ ConstantPoolCacheEntry::flags_offset()))); ++ __ test_bit(t0, x13, ConstantPoolCacheEntry::is_volatile_shift); ++ __ beqz(t0, notVolatile); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ __ bind(notVolatile); ++ } ++ ++ __ sub(xbcp, xbcp, 1); ++} ++ ++//----------------------------------------------------------------------------- ++// Calls ++ ++void TemplateTable::prepare_invoke(int byte_no, ++ Register method, // linked method (or i-klass) ++ Register index, // itable index, MethodType, etc. ++ Register recv, // if caller wants to see it ++ Register flags // if caller wants to test it ++ ) { ++ // determine flags ++ const Bytecodes::Code code = bytecode(); ++ const bool is_invokeinterface = code == Bytecodes::_invokeinterface; ++ const bool is_invokedynamic = code == Bytecodes::_invokedynamic; ++ const bool is_invokehandle = code == Bytecodes::_invokehandle; ++ const bool is_invokevirtual = code == Bytecodes::_invokevirtual; ++ const bool is_invokespecial = code == Bytecodes::_invokespecial; ++ const bool load_receiver = (recv != noreg); ++ const bool save_flags = (flags != noreg); ++ assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), ""); ++ assert(save_flags == (is_invokeinterface || is_invokevirtual), "need flags for vfinal"); ++ assert(flags == noreg || flags == x13, ""); ++ assert(recv == noreg || recv == x12, ""); ++ ++ // setup registers & access constant pool cache ++ if (recv == noreg) { ++ recv = x12; ++ } ++ if (flags == noreg) { ++ flags = x13; ++ } ++ assert_different_registers(method, index, recv, flags); ++ ++ // save 'interpreter return address' ++ __ save_bcp(); ++ ++ load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic); ++ ++ // maybe push appendix to arguments (just before return address) ++ if (is_invokedynamic || is_invokehandle) { ++ Label L_no_push; ++ __ test_bit(t0, flags, ConstantPoolCacheEntry::has_appendix_shift); ++ __ beqz(t0, L_no_push); ++ // Push the appendix as a trailing parameter. ++ // This must be done before we get the receiver, ++ // since the parameter_size includes it. ++ __ push_reg(x9); ++ __ mv(x9, index); ++ __ load_resolved_reference_at_index(index, x9); ++ __ pop_reg(x9); ++ __ push_reg(index); // push appendix (MethodType, CallSite, etc.) ++ __ bind(L_no_push); ++ } ++ ++ // load receiver if needed (note: no return address pushed yet) ++ if (load_receiver) { ++ __ andi(recv, flags, ConstantPoolCacheEntry::parameter_size_mask); // parameter_size_mask = 1 << 8 ++ __ shadd(t0, recv, esp, t0, 3); ++ __ ld(recv, Address(t0, -Interpreter::expr_offset_in_bytes(1))); ++ __ verify_oop(recv); ++ } ++ ++ // compute return type ++ __ slli(t1, flags, XLEN - (ConstantPoolCacheEntry::tos_state_shift + ConstantPoolCacheEntry::tos_state_bits)); ++ __ srli(t1, t1, XLEN - ConstantPoolCacheEntry::tos_state_bits); // (1 << 5) - 4 --> 28~31==> t1:0~3 ++ ++ // load return address ++ { ++ const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code); ++ __ mv(t0, table_addr); ++ __ shadd(t0, t1, t0, t1, 3); ++ __ ld(ra, Address(t0, 0)); ++ } ++} ++ ++void TemplateTable::invokevirtual_helper(Register index, ++ Register recv, ++ Register flags) ++{ ++ // Uses temporary registers x10, x13 ++ assert_different_registers(index, recv, x10, x13); ++ // Test for an invoke of a final method ++ Label notFinal; ++ __ test_bit(t0, flags, ConstantPoolCacheEntry::is_vfinal_shift); ++ __ beqz(t0, notFinal); ++ ++ const Register method = index; // method must be xmethod ++ assert(method == xmethod, "Method must be xmethod for interpreter calling convention"); ++ ++ // do the call - the index is actually the method to call ++ // that is, f2 is a vtable index if !is_vfinal, else f2 is a Method* ++ ++ // It's final, need a null check here! ++ __ null_check(recv); ++ ++ // profile this call ++ __ profile_final_call(x10); ++ __ profile_arguments_type(x10, method, x14, true); ++ ++ __ jump_from_interpreted(method); ++ ++ __ bind(notFinal); ++ ++ // get receiver klass ++ __ null_check(recv, oopDesc::klass_offset_in_bytes()); ++ __ load_klass(x10, recv); ++ ++ // profile this call ++ __ profile_virtual_call(x10, xlocals, x13); ++ ++ // get target Method & entry point ++ __ lookup_virtual_method(x10, index, method); ++ __ profile_arguments_type(x13, method, x14, true); ++ __ jump_from_interpreted(method); ++} ++ ++void TemplateTable::invokevirtual(int byte_no) ++{ ++ transition(vtos, vtos); ++ assert(byte_no == f2_byte, "use this argument"); ++ ++ prepare_invoke(byte_no, xmethod, noreg, x12, x13); ++ ++ // xmethod: index (actually a Method*) ++ // x12: receiver ++ // x13: flags ++ ++ invokevirtual_helper(xmethod, x12, x13); ++} ++ ++void TemplateTable::invokespecial(int byte_no) ++{ ++ transition(vtos, vtos); ++ assert(byte_no == f1_byte, "use this argument"); ++ ++ prepare_invoke(byte_no, xmethod, noreg, // get f1 Method* ++ x12); // get receiver also for null check ++ __ verify_oop(x12); ++ __ null_check(x12); ++ // do the call ++ __ profile_call(x10); ++ __ profile_arguments_type(x10, xmethod, xbcp, false); ++ __ jump_from_interpreted(xmethod); ++} ++ ++void TemplateTable::invokestatic(int byte_no) ++{ ++ transition(vtos, vtos); ++ assert(byte_no == f1_byte, "use this arugment"); ++ ++ prepare_invoke(byte_no, xmethod); // get f1 Method* ++ // do the call ++ __ profile_call(x10); ++ __ profile_arguments_type(x10, xmethod, x14, false); ++ __ jump_from_interpreted(xmethod); ++} ++ ++void TemplateTable::fast_invokevfinal(int byte_no) ++{ ++ __ call_Unimplemented(); ++} ++ ++void TemplateTable::invokeinterface(int byte_no) { ++ transition(vtos, vtos); ++ assert(byte_no == f1_byte, "use this argument"); ++ ++ prepare_invoke(byte_no, x10, xmethod, // get f1 Klass*, f2 Method* ++ x12, x13); // recv, flags ++ ++ // x10: interface klass (from f1) ++ // xmethod: method (from f2) ++ // x12: receiver ++ // x13: flags ++ ++ // First check for Object case, then private interface method, ++ // then regular interface method. ++ ++ // Special case of invokeinterface called for virtual method of ++ // java.lang.Object. See cpCache.cpp for details ++ Label notObjectMethod; ++ __ test_bit(t0, x13, ConstantPoolCacheEntry::is_forced_virtual_shift); ++ __ beqz(t0, notObjectMethod); ++ ++ invokevirtual_helper(xmethod, x12, x13); ++ __ bind(notObjectMethod); ++ ++ Label no_such_interface; ++ ++ // Check for private method invocation - indicated by vfinal ++ Label notVFinal; ++ __ test_bit(t0, x13, ConstantPoolCacheEntry::is_vfinal_shift); ++ __ beqz(t0, notVFinal); ++ ++ // Check receiver klass into x13 - also a null check ++ __ null_check(x12, oopDesc::klass_offset_in_bytes()); ++ __ load_klass(x13, x12); ++ ++ Label subtype; ++ __ check_klass_subtype(x13, x10, x14, subtype); ++ // If we get here the typecheck failed ++ __ j(no_such_interface); ++ __ bind(subtype); ++ ++ __ profile_final_call(x10); ++ __ profile_arguments_type(x10, xmethod, x14, true); ++ __ jump_from_interpreted(xmethod); ++ ++ __ bind(notVFinal); ++ ++ // Get receiver klass into x13 - also a null check ++ __ restore_locals(); ++ __ null_check(x12, oopDesc::klass_offset_in_bytes()); ++ __ load_klass(x13, x12); ++ ++ Label no_such_method; ++ ++ // Preserve method for the throw_AbstractMethodErrorVerbose. ++ __ mv(x28, xmethod); ++ // Receiver subtype check against REFC. ++ // Superklass in x10. Subklass in x13. Blows t1, x30 ++ __ lookup_interface_method(// inputs: rec. class, interface, itable index ++ x13, x10, noreg, ++ // outputs: scan temp. reg, scan temp. reg ++ t1, x30, ++ no_such_interface, ++ /*return_method=*/false); ++ ++ // profile this call ++ __ profile_virtual_call(x13, x30, x9); ++ ++ // Get declaring interface class from method, and itable index ++ __ load_method_holder(x10, xmethod); ++ __ lwu(xmethod, Address(xmethod, Method::itable_index_offset())); ++ __ subw(xmethod, xmethod, Method::itable_index_max); ++ __ negw(xmethod, xmethod); ++ ++ // Preserve recvKlass for throw_AbstractMethodErrorVerbose ++ __ mv(xlocals, x13); ++ __ lookup_interface_method(// inputs: rec. class, interface, itable index ++ xlocals, x10, xmethod, ++ // outputs: method, scan temp. reg ++ xmethod, x30, ++ no_such_interface); ++ ++ // xmethod: Method to call ++ // x12: receiver ++ // Check for abstract method error ++ // Note: This should be done more efficiently via a throw_abstract_method_error ++ // interpreter entry point and a conditional jump to it in case of a null ++ // method. ++ __ beqz(xmethod, no_such_method); ++ ++ __ profile_arguments_type(x13, xmethod, x30, true); ++ ++ // do the call ++ // x12: receiver ++ // xmethod: Method ++ __ jump_from_interpreted(xmethod); ++ __ should_not_reach_here(); ++ ++ // exception handling code follows ... ++ // note: must restore interpreter registers to canonical ++ // state for exception handling to work correctly! ++ ++ __ bind(no_such_method); ++ // throw exception ++ __ restore_bcp(); // bcp must be correct for exception handler (was destroyed) ++ __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) ++ // Pass arguments for generating a verbose error message. ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose), x13, x28); ++ // the call_VM checks for exception, so we should never return here. ++ __ should_not_reach_here(); ++ ++ __ bind(no_such_interface); ++ // throw exceptiong ++ __ restore_bcp(); // bcp must be correct for exception handler (was destroyed) ++ __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) ++ // Pass arguments for generating a verbose error message. ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose), x13, x10); ++ // the call_VM checks for exception, so we should never return here. ++ __ should_not_reach_here(); ++ return; ++} ++ ++void TemplateTable::invokehandle(int byte_no) { ++ transition(vtos, vtos); ++ assert(byte_no == f1_byte, "use this argument"); ++ ++ prepare_invoke(byte_no, xmethod, x10, x12); ++ __ verify_method_ptr(x12); ++ __ verify_oop(x12); ++ __ null_check(x12); ++ ++ // FIXME: profile the LambdaForm also ++ ++ // x30 is safe to use here as a temp reg because it is about to ++ // be clobbered by jump_from_interpreted(). ++ __ profile_final_call(x30); ++ __ profile_arguments_type(x30, xmethod, x14, true); ++ ++ __ jump_from_interpreted(xmethod); ++} ++ ++void TemplateTable::invokedynamic(int byte_no) { ++ transition(vtos, vtos); ++ assert(byte_no == f1_byte, "use this argument"); ++ ++ prepare_invoke(byte_no, xmethod, x10); ++ ++ // x10: CallSite object (from cpool->resolved_references[]) ++ // xmethod: MH.linkToCallSite method (from f2) ++ ++ // Note: x10_callsite is already pushed by prepare_invoke ++ ++ // %%% should make a type profile for any invokedynamic that takes a ref argument ++ // profile this call ++ __ profile_call(xbcp); ++ __ profile_arguments_type(x13, xmethod, x30, false); ++ ++ __ verify_oop(x10); ++ ++ __ jump_from_interpreted(xmethod); ++} ++ ++//----------------------------------------------------------------------------- ++// Allocation ++ ++void TemplateTable::_new() { ++ transition(vtos, atos); ++ ++ __ get_unsigned_2_byte_index_at_bcp(x13, 1); ++ Label slow_case; ++ Label done; ++ Label initialize_header; ++ Label initialize_object; // including clearing the fields ++ ++ __ get_cpool_and_tags(x14, x10); ++ // Make sure the class we're about to instantiate has been resolved. ++ // This is done before loading InstanceKlass to be consistent with the order ++ // how Constant Pool is update (see ConstantPool::klass_at_put) ++ const int tags_offset = Array::base_offset_in_bytes(); ++ __ add(t0, x10, x13); ++ __ la(t0, Address(t0, tags_offset)); ++ __ membar(MacroAssembler::AnyAny); ++ __ lbu(t0, t0); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ __ sub(t1, t0, (u1)JVM_CONSTANT_Class); ++ __ bnez(t1, slow_case); ++ ++ // get InstanceKlass ++ __ load_resolved_klass_at_offset(x14, x13, x14, t0); ++ ++ // make sure klass is initialized & doesn't have finalizer ++ // make sure klass is fully initialized ++ __ lbu(t0, Address(x14, InstanceKlass::init_state_offset())); ++ __ sub(t1, t0, (u1)InstanceKlass::fully_initialized); ++ __ bnez(t1, slow_case); ++ ++ // get instance_size in InstanceKlass (scaled to a count of bytes) ++ __ lwu(x13, Address(x14, Klass::layout_helper_offset())); ++ // test to see if it has a finalizer or is malformed in some way ++ __ test_bit(t0, x13, exact_log2(Klass::_lh_instance_slow_path_bit)); ++ __ bnez(t0, slow_case); ++ ++ // Allocate the instance: ++ // If TLAB is enabled: ++ // Try to allocate in the TLAB. ++ // If fails, go to the slow path. ++ // Else If inline contiguous allocations are enabled: ++ // Try to allocate in eden. ++ // If fails due to heap end, go to slow path ++ // ++ // If TLAB is enabled OR inline contiguous is enabled: ++ // Initialize the allocation. ++ // Exit. ++ // Go to slow path. ++ const bool allow_shared_alloc = Universe::heap()->supports_inline_contig_alloc(); ++ ++ if (UseTLAB) { ++ __ tlab_allocate(x10, x13, 0, noreg, x11, slow_case); ++ ++ if (ZeroTLAB) { ++ // the fields have been already cleared ++ __ j(initialize_header); ++ } else { ++ // initialize both the header and fields ++ __ j(initialize_object); ++ } ++ } else { ++ // Allocation in the shared Eden, if allowed. ++ // ++ // x13: instance size in bytes ++ if (allow_shared_alloc) { ++ __ eden_allocate(x10, x13, 0, x28, slow_case); ++ } ++ } ++ ++ // If USETLAB or allow_shared_alloc are true, the object is created above and ++ // there is an initialized need. Otherwise, skip and go to the slow path. ++ if (UseTLAB || allow_shared_alloc) { ++ // The object is initialized before the header. If the object size is ++ // zero, go directly to the header initialization. ++ __ bind(initialize_object); ++ __ sub(x13, x13, sizeof(oopDesc)); ++ __ beqz(x13, initialize_header); ++ ++ // Initialize obejct fields ++ { ++ __ add(x12, x10, sizeof(oopDesc)); ++ Label loop; ++ __ bind(loop); ++ __ sd(zr, Address(x12)); ++ __ add(x12, x12, BytesPerLong); ++ __ sub(x13, x13, BytesPerLong); ++ __ bnez(x13, loop); ++ } ++ ++ // initialize object hader only. ++ __ bind(initialize_header); ++ if (UseBiasedLocking) { ++ __ ld(t0, Address(x14, Klass::prototype_header_offset())); ++ } else { ++ __ mv(t0, (intptr_t)markWord::prototype().value()); ++ } ++ __ sd(t0, Address(x10, oopDesc::mark_offset_in_bytes())); ++ __ store_klass_gap(x10, zr); // zero klass gap for compressed oops ++ __ store_klass(x10, x14); // store klass last ++ ++ { ++ SkipIfEqual skip(_masm, &DTraceAllocProbes, false); ++ // Trigger dtrace event for fastpath ++ __ push(atos); // save the return value ++ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), x10); ++ __ pop(atos); // restore the return value ++ } ++ __ j(done); ++ } ++ ++ // slow case ++ __ bind(slow_case); ++ __ get_constant_pool(c_rarg1); ++ __ get_unsigned_2_byte_index_at_bcp(c_rarg2, 1); ++ call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), c_rarg1, c_rarg2); ++ __ verify_oop(x10); ++ ++ // continue ++ __ bind(done); ++ // Must prevent reordering of stores for object initialization with stores that publish the new object. ++ __ membar(MacroAssembler::StoreStore); ++} ++ ++void TemplateTable::newarray() { ++ transition(itos, atos); ++ __ load_unsigned_byte(c_rarg1, at_bcp(1)); ++ __ mv(c_rarg2, x10); ++ call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::newarray), ++ c_rarg1, c_rarg2); ++ // Must prevent reordering of stores for object initialization with stores that publish the new object. ++ __ membar(MacroAssembler::StoreStore); ++} ++ ++void TemplateTable::anewarray() { ++ transition(itos, atos); ++ __ get_unsigned_2_byte_index_at_bcp(c_rarg2, 1); ++ __ get_constant_pool(c_rarg1); ++ __ mv(c_rarg3, x10); ++ call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::anewarray), ++ c_rarg1, c_rarg2, c_rarg3); ++ // Must prevent reordering of stores for object initialization with stores that publish the new object. ++ __ membar(MacroAssembler::StoreStore); ++} ++ ++void TemplateTable::arraylength() { ++ transition(atos, itos); ++ __ null_check(x10, arrayOopDesc::length_offset_in_bytes()); ++ __ lwu(x10, Address(x10, arrayOopDesc::length_offset_in_bytes())); ++} ++ ++void TemplateTable::checkcast() ++{ ++ transition(atos, atos); ++ Label done, is_null, ok_is_subtype, quicked, resolved; ++ __ beqz(x10, is_null); ++ ++ // Get cpool & tags index ++ __ get_cpool_and_tags(x12, x13); // x12=cpool, x13=tags array ++ __ get_unsigned_2_byte_index_at_bcp(x9, 1); // x9=index ++ // See if bytecode has already been quicked ++ __ add(t0, x13, Array::base_offset_in_bytes()); ++ __ add(x11, t0, x9); ++ __ membar(MacroAssembler::AnyAny); ++ __ lbu(x11, x11); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ __ sub(t0, x11, (u1)JVM_CONSTANT_Class); ++ __ beqz(t0, quicked); ++ ++ __ push(atos); // save receiver for result, and for GC ++ call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); ++ // vm_result_2 has metadata result ++ __ get_vm_result_2(x10, xthread); ++ __ pop_reg(x13); // restore receiver ++ __ j(resolved); ++ ++ // Get superklass in x10 and subklass in x13 ++ __ bind(quicked); ++ __ mv(x13, x10); // Save object in x13; x10 needed for subtype check ++ __ load_resolved_klass_at_offset(x12, x9, x10, t0); // x10 = klass ++ ++ __ bind(resolved); ++ __ load_klass(x9, x13); ++ ++ // Generate subtype check. Blows x12, x15. Object in x13. ++ // Superklass in x10. Subklass in x9. ++ __ gen_subtype_check(x9, ok_is_subtype); ++ ++ // Come here on failure ++ __ push_reg(x13); ++ // object is at TOS ++ __ j(Interpreter::_throw_ClassCastException_entry); ++ ++ // Come here on success ++ __ bind(ok_is_subtype); ++ __ mv(x10, x13); // Restore object in x13 ++ ++ // Collect counts on whether this test sees NULLs a lot or not. ++ if (ProfileInterpreter) { ++ __ j(done); ++ __ bind(is_null); ++ __ profile_null_seen(x12); ++ } else { ++ __ bind(is_null); // same as 'done' ++ } ++ __ bind(done); ++} ++ ++void TemplateTable::instanceof() { ++ transition(atos, itos); ++ Label done, is_null, ok_is_subtype, quicked, resolved; ++ __ beqz(x10, is_null); ++ ++ // Get cpool & tags index ++ __ get_cpool_and_tags(x12, x13); // x12=cpool, x13=tags array ++ __ get_unsigned_2_byte_index_at_bcp(x9, 1); // x9=index ++ // See if bytecode has already been quicked ++ __ add(t0, x13, Array::base_offset_in_bytes()); ++ __ add(x11, t0, x9); ++ __ membar(MacroAssembler::AnyAny); ++ __ lbu(x11, x11); ++ __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); ++ __ sub(t0, x11, (u1)JVM_CONSTANT_Class); ++ __ beqz(t0, quicked); ++ ++ __ push(atos); // save receiver for result, and for GC ++ call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); ++ // vm_result_2 has metadata result ++ __ get_vm_result_2(x10, xthread); ++ __ pop_reg(x13); // restore receiver ++ __ verify_oop(x13); ++ __ load_klass(x13, x13); ++ __ j(resolved); ++ ++ // Get superklass in x10 and subklass in x13 ++ __ bind(quicked); ++ __ load_klass(x13, x10); ++ __ load_resolved_klass_at_offset(x12, x9, x10, t0); ++ ++ __ bind(resolved); ++ ++ // Generate subtype check. Blows x12, x15 ++ // Superklass in x10. Subklass in x13. ++ __ gen_subtype_check(x13, ok_is_subtype); ++ ++ // Come here on failure ++ __ mv(x10, zr); ++ __ j(done); ++ // Come here on success ++ __ bind(ok_is_subtype); ++ __ mv(x10, 1); ++ ++ // Collect counts on whether this test sees NULLs a lot or not. ++ if (ProfileInterpreter) { ++ __ j(done); ++ __ bind(is_null); ++ __ profile_null_seen(x12); ++ } else { ++ __ bind(is_null); // same as 'done' ++ } ++ __ bind(done); ++ // x10 = 0: obj == NULL or obj is not an instanceof the specified klass ++ // x10 = 1: obj != NULL and obj is an instanceof the specified klass ++} ++ ++//----------------------------------------------------------------------------- ++// Breakpoints ++void TemplateTable::_breakpoint() { ++ // Note: We get here even if we are single stepping.. ++ // jbug inists on setting breakpoints at every bytecode ++ // even if we are in single step mode. ++ ++ transition(vtos, vtos); ++ ++ // get the unpatched byte code ++ __ get_method(c_rarg1); ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::get_original_bytecode_at), ++ c_rarg1, xbcp); ++ __ mv(x9, x10); ++ ++ // post the breakpoint event ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::_breakpoint), ++ xmethod, xbcp); ++ ++ // complete the execution of original bytecode ++ __ mv(t0, x9); ++ __ dispatch_only_normal(vtos); ++} ++ ++//----------------------------------------------------------------------------- ++// Exceptions ++ ++void TemplateTable::athrow() { ++ transition(atos, vtos); ++ __ null_check(x10); ++ __ j(Interpreter::throw_exception_entry()); ++} ++ ++//----------------------------------------------------------------------------- ++// Synchronization ++// ++// Note: monitorenter & exit are symmetric routines; which is reflected ++// in the assembly code structure as well ++// ++// Stack layout: ++// ++// [expressions ] <--- esp = expression stack top ++// .. ++// [expressions ] ++// [monitor entry] <--- monitor block top = expression stack bot ++// .. ++// [monitor entry] ++// [frame data ] <--- monitor block bot ++// ... ++// [saved fp ] <--- fp ++void TemplateTable::monitorenter() ++{ ++ transition(atos, vtos); ++ ++ // check for NULL object ++ __ null_check(x10); ++ ++ const Address monitor_block_top( ++ 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; ++ ++ Label allocated; ++ ++ // initialize entry pointer ++ __ mv(c_rarg1, zr); // points to free slot or NULL ++ ++ // find a free slot in the monitor block (result in c_rarg1) ++ { ++ Label entry, loop, exit, notUsed; ++ __ ld(c_rarg3, monitor_block_top); // points to current entry, ++ // starting with top-most entry ++ __ la(c_rarg2, monitor_block_bot); // points to word before bottom ++ ++ __ j(entry); ++ ++ __ bind(loop); ++ // check if current entry is used ++ // if not used then remember entry in c_rarg1 ++ __ ld(t0, Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes())); ++ __ bnez(t0, notUsed); ++ __ mv(c_rarg1, c_rarg3); ++ __ bind(notUsed); ++ // check if current entry is for same object ++ // if same object then stop searching ++ __ beq(x10, t0, exit); ++ // otherwise advance to next entry ++ __ add(c_rarg3, c_rarg3, entry_size); ++ __ bind(entry); ++ // check if bottom reached ++ // if not at bottom then check this entry ++ __ bne(c_rarg3, c_rarg2, loop); ++ __ bind(exit); ++ } ++ ++ __ bnez(c_rarg1, allocated); // check if a slot has been found and ++ // if found, continue with that on ++ ++ // allocate one if there's no free slot ++ { ++ Label entry, loop; ++ // 1. compute new pointers // esp: old expression stack top ++ __ ld(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom ++ __ sub(esp, esp, entry_size); // move expression stack top ++ __ sub(c_rarg1, c_rarg1, entry_size); // move expression stack bottom ++ __ mv(c_rarg3, esp); // set start value for copy loop ++ __ sd(c_rarg1, monitor_block_bot); // set new monitor block bottom ++ __ sub(sp, sp, entry_size); // make room for the monitor ++ ++ __ j(entry); ++ // 2. move expression stack contents ++ __ bind(loop); ++ __ ld(c_rarg2, Address(c_rarg3, entry_size)); // load expression stack ++ // word from old location ++ __ sd(c_rarg2, Address(c_rarg3, 0)); // and store it at new location ++ __ add(c_rarg3, c_rarg3, wordSize); // advance to next word ++ __ bind(entry); ++ __ bne(c_rarg3, c_rarg1, loop); // check if bottom reached.if not at bottom ++ // then copy next word ++ } ++ ++ // call run-time routine ++ // c_rarg1: points to monitor entry ++ __ bind(allocated); ++ ++ // Increment bcp to point to the next bytecode, so exception ++ // handling for async. exceptions work correctly. ++ // The object has already been poped from the stack, so the ++ // expression stack looks correct. ++ __ addi(xbcp, xbcp, 1); ++ ++ // store object ++ __ sd(x10, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); ++ __ lock_object(c_rarg1); ++ ++ // check to make sure this monitor doesn't cause stack overflow after locking ++ __ save_bcp(); // in case of exception ++ __ generate_stack_overflow_check(0); ++ ++ // The bcp has already been incremented. Just need to dispatch to ++ // next instruction. ++ __ dispatch_next(vtos); ++} ++ ++void TemplateTable::monitorexit() ++{ ++ transition(atos, vtos); ++ ++ // check for NULL object ++ __ null_check(x10); ++ ++ const Address monitor_block_top( ++ 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; ++ ++ Label found; ++ ++ // find matching slot ++ { ++ Label entry, loop; ++ __ ld(c_rarg1, monitor_block_top); // points to current entry, ++ // starting with top-most entry ++ __ la(c_rarg2, monitor_block_bot); // points to word before bottom ++ // of monitor block ++ __ j(entry); ++ ++ __ bind(loop); ++ // check if current entry is for same object ++ __ ld(t0, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); ++ // if same object then stop searching ++ __ beq(x10, t0, found); ++ // otherwise advance to next entry ++ __ add(c_rarg1, c_rarg1, entry_size); ++ __ bind(entry); ++ // check if bottom reached ++ // if not at bottom then check this entry ++ __ bne(c_rarg1, c_rarg2, loop); ++ } ++ ++ // error handling. Unlocking was not block-structured ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_illegal_monitor_state_exception)); ++ __ should_not_reach_here(); ++ ++ // call run-time routine ++ __ bind(found); ++ __ push_ptr(x10); // make sure object is on stack (contract with oopMaps) ++ __ unlock_object(c_rarg1); ++ __ pop_ptr(x10); // discard object ++} ++ ++// Wide instructions ++void TemplateTable::wide() ++{ ++ __ load_unsigned_byte(x9, at_bcp(1)); ++ __ mv(t0, (address)Interpreter::_wentry_point); ++ __ shadd(t0, x9, t0, t1, 3); ++ __ ld(t0, Address(t0)); ++ __ jr(t0); ++} ++ ++// Multi arrays ++void TemplateTable::multianewarray() { ++ transition(vtos, atos); ++ __ load_unsigned_byte(x10, at_bcp(3)); // get number of dimensions ++ // last dim is on top of stack; we want address of first one: ++ // first_addr = last_addr + (ndims - 1) * wordSize ++ __ shadd(c_rarg1, x10, esp, c_rarg1, 3); ++ __ sub(c_rarg1, c_rarg1, wordSize); ++ call_VM(x10, ++ CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), ++ c_rarg1); ++ __ load_unsigned_byte(x11, at_bcp(3)); ++ __ shadd(esp, x11, esp, t0, 3); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/templateTable_riscv.hpp +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_TEMPLATETABLE_RISCV_HPP ++#define CPU_RISCV_TEMPLATETABLE_RISCV_HPP ++ ++static void prepare_invoke(int byte_no, ++ Register method, // linked method (or i-klass) ++ Register index = noreg, // itable index, MethodType, etc. ++ Register recv = noreg, // if caller wants to see it ++ Register flags = noreg // if caller wants to test it ++ ); ++static void invokevirtual_helper(Register index, Register recv, ++ Register flags); ++ ++// Helpers ++static void index_check(Register array, Register index); ++ ++#endif // CPU_RISCV_TEMPLATETABLE_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/universalNativeInvoker_riscv.cpp +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (c) 2020, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "prims/universalNativeInvoker.hpp" ++#include "utilities/debug.hpp" ++ ++address ProgrammableInvoker::generate_adapter(jobject jabi, jobject jlayout) { ++ Unimplemented(); ++ return nullptr; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/universalUpcallHandle_riscv.cpp +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "prims/universalUpcallHandler.hpp" ++#include "utilities/debug.hpp" ++ ++address ProgrammableUpcallHandler::generate_upcall_stub(jobject jrec, jobject jabi, jobject jlayout) { ++ Unimplemented(); ++ return nullptr; ++} ++ ++address ProgrammableUpcallHandler::generate_optimized_upcall_stub(jobject mh, Method* entry, jobject jabi, jobject jconv) { ++ ShouldNotCallThis(); ++ return nullptr; ++} ++ ++bool ProgrammableUpcallHandler::supports_optimized_upcalls() { ++ return false; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vmStructs_riscv.hpp +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2015, 2019, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_VMSTRUCTS_RISCV_HPP ++#define CPU_RISCV_VMSTRUCTS_RISCV_HPP ++ ++// These are the CPU-specific fields, types and integer ++// constants required by the Serviceability Agent. This file is ++// referenced by vmStructs.cpp. ++ ++#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ ++ volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) ++ ++#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) ++ ++#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#endif // CPU_RISCV_VMSTRUCTS_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vm_version_ext_riscv.cpp +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "memory/allocation.hpp" ++#include "memory/allocation.inline.hpp" ++#include "runtime/os.inline.hpp" ++#include "vm_version_ext_riscv.hpp" ++ ++// VM_Version_Ext statics ++int VM_Version_Ext::_no_of_threads = 0; ++int VM_Version_Ext::_no_of_cores = 0; ++int VM_Version_Ext::_no_of_sockets = 0; ++bool VM_Version_Ext::_initialized = false; ++char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0}; ++char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0}; ++ ++void VM_Version_Ext::initialize_cpu_information(void) { ++ // do nothing if cpu info has been initialized ++ if (_initialized) { ++ return; ++ } ++ ++ _no_of_cores = os::processor_count(); ++ _no_of_threads = _no_of_cores; ++ _no_of_sockets = _no_of_cores; ++ snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "RISCV64"); ++ snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "RISCV64 %s", _features_string); ++ _initialized = true; ++} ++ ++int VM_Version_Ext::number_of_threads(void) { ++ initialize_cpu_information(); ++ return _no_of_threads; ++} ++ ++int VM_Version_Ext::number_of_cores(void) { ++ initialize_cpu_information(); ++ return _no_of_cores; ++} ++ ++int VM_Version_Ext::number_of_sockets(void) { ++ initialize_cpu_information(); ++ return _no_of_sockets; ++} ++ ++const char* VM_Version_Ext::cpu_name(void) { ++ initialize_cpu_information(); ++ char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing); ++ if (NULL == tmp) { ++ return NULL; ++ } ++ strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE); ++ return tmp; ++} ++ ++const char* VM_Version_Ext::cpu_description(void) { ++ initialize_cpu_information(); ++ char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing); ++ if (NULL == tmp) { ++ return NULL; ++ } ++ strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE); ++ return tmp; ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vm_version_ext_riscv.hpp +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_VM_VERSION_EXT_RISCV_HPP ++#define CPU_RISCV_VM_VERSION_EXT_RISCV_HPP ++ ++#include "runtime/vm_version.hpp" ++#include "utilities/macros.hpp" ++ ++class VM_Version_Ext : public VM_Version { ++ private: ++ static const size_t CPU_TYPE_DESC_BUF_SIZE = 256; ++ static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096; ++ ++ static int _no_of_threads; ++ static int _no_of_cores; ++ static int _no_of_sockets; ++ static bool _initialized; ++ static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE]; ++ static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE]; ++ ++ public: ++ static int number_of_threads(void); ++ static int number_of_cores(void); ++ static int number_of_sockets(void); ++ ++ static const char* cpu_name(void); ++ static const char* cpu_description(void); ++ static void initialize_cpu_information(void); ++ ++}; ++ ++#endif // CPU_RISCV_VM_VERSION_EXT_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp +@@ -0,0 +1,225 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "runtime/java.hpp" ++#include "runtime/os.hpp" ++#include "runtime/vm_version.hpp" ++#include "utilities/formatBuffer.hpp" ++#include "utilities/macros.hpp" ++ ++#include OS_HEADER_INLINE(os) ++ ++const char* VM_Version::_uarch = ""; ++const char* VM_Version::_vm_mode = ""; ++uint32_t VM_Version::_initial_vector_length = 0; ++ ++void VM_Version::initialize() { ++ _supports_cx8 = true; ++ _supports_atomic_getset4 = true; ++ _supports_atomic_getadd4 = true; ++ _supports_atomic_getset8 = true; ++ _supports_atomic_getadd8 = true; ++ ++ get_os_cpu_info(); ++ ++ // check if satp.mode is supported, currently supports up to SV48(RV64) ++ if (get_satp_mode() > VM_SV48) { ++ vm_exit_during_initialization( ++ err_msg("Unsupported satp mode: %s. Only satp modes up to sv48 are supported for now.", ++ _vm_mode)); ++ } ++ ++ if (FLAG_IS_DEFAULT(UseFMA)) { ++ FLAG_SET_DEFAULT(UseFMA, true); ++ } ++ ++ if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) { ++ FLAG_SET_DEFAULT(AllocatePrefetchDistance, 0); ++ } ++ ++ if (UseAES || UseAESIntrinsics) { ++ if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { ++ warning("AES instructions are not available on this CPU"); ++ FLAG_SET_DEFAULT(UseAES, false); ++ } ++ if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { ++ warning("AES intrinsics are not available on this CPU"); ++ FLAG_SET_DEFAULT(UseAESIntrinsics, false); ++ } ++ } ++ ++ if (UseAESCTRIntrinsics) { ++ warning("AES/CTR intrinsics are not available on this CPU"); ++ FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); ++ } ++ ++ if (UseSHA) { ++ warning("SHA instructions are not available on this CPU"); ++ FLAG_SET_DEFAULT(UseSHA, false); ++ } ++ ++ if (UseSHA1Intrinsics) { ++ warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU."); ++ FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); ++ } ++ ++ if (UseSHA256Intrinsics) { ++ warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU."); ++ FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); ++ } ++ ++ if (UseSHA512Intrinsics) { ++ warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU."); ++ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); ++ } ++ ++ if (UseSHA3Intrinsics) { ++ warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); ++ FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); ++ } ++ ++ if (UseCRC32Intrinsics) { ++ warning("CRC32 intrinsics are not available on this CPU."); ++ FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); ++ } ++ ++ if (UseCRC32CIntrinsics) { ++ warning("CRC32C intrinsics are not available on this CPU."); ++ FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); ++ } ++ ++ if (UseMD5Intrinsics) { ++ warning("MD5 intrinsics are not available on this CPU."); ++ FLAG_SET_DEFAULT(UseMD5Intrinsics, false); ++ } ++ ++ if (UseRVV) { ++ if (!(_features & CPU_V)) { ++ warning("RVV is not supported on this CPU"); ++ FLAG_SET_DEFAULT(UseRVV, false); ++ } else { ++ // read vector length from vector CSR vlenb ++ _initial_vector_length = get_current_vector_length(); ++ } ++ } ++ ++ if (UseRVC && !(_features & CPU_C)) { ++ warning("RVC is not supported on this CPU"); ++ FLAG_SET_DEFAULT(UseRVC, false); ++ } ++ ++ if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) { ++ FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true); ++ } ++ ++ if (UseZbb) { ++ if (FLAG_IS_DEFAULT(UsePopCountInstruction)) { ++ FLAG_SET_DEFAULT(UsePopCountInstruction, true); ++ } ++ } else { ++ FLAG_SET_DEFAULT(UsePopCountInstruction, false); ++ } ++ ++ char buf[512]; ++ buf[0] = '\0'; ++ if (_uarch != NULL && strcmp(_uarch, "") != 0) snprintf(buf, sizeof(buf), "%s,", _uarch); ++ strcat(buf, "rv64"); ++#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (_features & CPU_##id) strcat(buf, name); ++ CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED) ++#undef ADD_FEATURE_IF_SUPPORTED ++ ++ _features_string = os::strdup(buf); ++ ++#ifdef COMPILER2 ++ c2_initialize(); ++#endif // COMPILER2 ++} ++ ++#ifdef COMPILER2 ++void VM_Version::c2_initialize() { ++ if (UseCMoveUnconditionally) { ++ FLAG_SET_DEFAULT(UseCMoveUnconditionally, false); ++ } ++ ++ if (ConditionalMoveLimit > 0) { ++ FLAG_SET_DEFAULT(ConditionalMoveLimit, 0); ++ } ++ ++ if (!UseRVV) { ++ FLAG_SET_DEFAULT(SpecialEncodeISOArray, false); ++ } ++ ++ if (!UseRVV && MaxVectorSize) { ++ FLAG_SET_DEFAULT(MaxVectorSize, 0); ++ } ++ ++ if (!UseRVV) { ++ FLAG_SET_DEFAULT(UseRVVForBigIntegerShiftIntrinsics, false); ++ } ++ ++ if (UseRVV) { ++ if (FLAG_IS_DEFAULT(MaxVectorSize)) { ++ MaxVectorSize = _initial_vector_length; ++ } else if (MaxVectorSize < 16) { ++ warning("RVV does not support vector length less than 16 bytes. Disabling RVV."); ++ UseRVV = false; ++ } else if (is_power_of_2(MaxVectorSize)) { ++ if (MaxVectorSize > _initial_vector_length) { ++ warning("Current system only supports max RVV vector length %d. Set MaxVectorSize to %d", ++ _initial_vector_length, _initial_vector_length); ++ } ++ MaxVectorSize = _initial_vector_length; ++ } else { ++ vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize)); ++ } ++ } ++ ++ // disable prefetch ++ if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { ++ FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0); ++ } ++ ++ if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) { ++ FLAG_SET_DEFAULT(UseMulAddIntrinsic, true); ++ } ++ ++ if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) { ++ FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, true); ++ } ++ ++ if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) { ++ FLAG_SET_DEFAULT(UseSquareToLenIntrinsic, true); ++ } ++ ++ if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) { ++ FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, true); ++ } ++ ++ if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) { ++ FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, true); ++ } ++} ++#endif // COMPILER2 +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_VM_VERSION_RISCV_HPP ++#define CPU_RISCV_VM_VERSION_RISCV_HPP ++ ++#include "runtime/abstract_vm_version.hpp" ++#include "runtime/arguments.hpp" ++#include "runtime/globals_extension.hpp" ++#include "utilities/sizes.hpp" ++ ++class VM_Version : public Abstract_VM_Version { ++#ifdef COMPILER2 ++private: ++ static void c2_initialize(); ++#endif // COMPILER2 ++ ++// VM modes (satp.mode) privileged ISA 1.10 ++enum VM_MODE { ++ VM_MBARE = 0, ++ VM_SV39 = 8, ++ VM_SV48 = 9, ++ VM_SV57 = 10, ++ VM_SV64 = 11 ++}; ++ ++protected: ++ static const char* _uarch; ++ static const char* _vm_mode; ++ static uint32_t _initial_vector_length; ++ static void get_os_cpu_info(); ++ static uint32_t get_current_vector_length(); ++ static VM_MODE get_satp_mode(); ++ ++public: ++ // Initialization ++ static void initialize(); ++ ++ constexpr static bool supports_stack_watermark_barrier() { return true; } ++ ++ enum Feature_Flag { ++#define CPU_FEATURE_FLAGS(decl) \ ++ decl(I, "i", 8) \ ++ decl(M, "m", 12) \ ++ decl(A, "a", 0) \ ++ decl(F, "f", 5) \ ++ decl(D, "d", 3) \ ++ decl(C, "c", 2) \ ++ decl(V, "v", 21) ++ ++#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit), ++ CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG) ++#undef DECLARE_CPU_FEATURE_FLAG ++ }; ++ ++ static void initialize_cpu_information(void); ++}; ++ ++#endif // CPU_RISCV_VM_VERSION_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vmreg_riscv.cpp +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/assembler.hpp" ++#include "code/vmreg.hpp" ++ ++void VMRegImpl::set_regName() { ++ int i = 0; ++ Register reg = ::as_Register(0); ++ for ( ; i < ConcreteRegisterImpl::max_gpr ; ) { ++ for (int j = 0 ; j < RegisterImpl::max_slots_per_register ; j++) { ++ regName[i++] = reg->name(); ++ } ++ reg = reg->successor(); ++ } ++ ++ FloatRegister freg = ::as_FloatRegister(0); ++ for ( ; i < ConcreteRegisterImpl::max_fpr ; ) { ++ for (int j = 0 ; j < FloatRegisterImpl::max_slots_per_register ; j++) { ++ regName[i++] = freg->name(); ++ } ++ freg = freg->successor(); ++ } ++ ++ VectorRegister vreg = ::as_VectorRegister(0); ++ for ( ; i < ConcreteRegisterImpl::max_vpr ; ) { ++ for (int j = 0 ; j < VectorRegisterImpl::max_slots_per_register ; j++) { ++ regName[i++] = vreg->name(); ++ } ++ vreg = vreg->successor(); ++ } ++ ++ for ( ; i < ConcreteRegisterImpl::number_of_registers ; i++) { ++ regName[i] = "NON-GPR-FPR-VPR"; ++ } ++} ++ ++VMReg VMRegImpl::vmStorageToVMReg(int type, int index) { ++ Unimplemented(); ++ return VMRegImpl::Bad(); ++} +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vmreg_riscv.hpp +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_VMREG_RISCV_HPP ++#define CPU_RISCV_VMREG_RISCV_HPP ++ ++inline bool is_Register() { ++ return (unsigned int) value() < (unsigned int) ConcreteRegisterImpl::max_gpr; ++} ++ ++inline bool is_FloatRegister() { ++ return value() >= ConcreteRegisterImpl::max_gpr && value() < ConcreteRegisterImpl::max_fpr; ++} ++ ++inline bool is_VectorRegister() { ++ return value() >= ConcreteRegisterImpl::max_fpr && value() < ConcreteRegisterImpl::max_vpr; ++} ++ ++inline Register as_Register() { ++ assert(is_Register(), "must be"); ++ return ::as_Register(value() / RegisterImpl::max_slots_per_register); ++} ++ ++inline FloatRegister as_FloatRegister() { ++ assert(is_FloatRegister() && is_even(value()), "must be"); ++ return ::as_FloatRegister((value() - ConcreteRegisterImpl::max_gpr) / ++ FloatRegisterImpl::max_slots_per_register); ++} ++ ++inline VectorRegister as_VectorRegister() { ++ assert(is_VectorRegister() && ((value() & (VectorRegisterImpl::max_slots_per_register - 1)) == 0), "must be"); ++ return ::as_VectorRegister((value() - ConcreteRegisterImpl::max_fpr) / ++ VectorRegisterImpl::max_slots_per_register); ++} ++ ++inline bool is_concrete() { ++ assert(is_reg(), "must be"); ++ if (is_VectorRegister()) { ++ int base = value() - ConcreteRegisterImpl::max_fpr; ++ return (base % VectorRegisterImpl::max_slots_per_register) == 0; ++ } else { ++ return is_even(value()); ++ } ++} ++ ++#endif // CPU_RISCV_VMREG_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vmreg_riscv.inline.hpp +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef CPU_RISCV_VM_VMREG_RISCV_INLINE_HPP ++#define CPU_RISCV_VM_VMREG_RISCV_INLINE_HPP ++ ++inline VMReg RegisterImpl::as_VMReg() { ++ if (this == noreg) { ++ return VMRegImpl::Bad(); ++ } ++ return VMRegImpl::as_VMReg(encoding() * RegisterImpl::max_slots_per_register); ++} ++ ++inline VMReg FloatRegisterImpl::as_VMReg() { ++ return VMRegImpl::as_VMReg((encoding() * FloatRegisterImpl::max_slots_per_register) + ++ ConcreteRegisterImpl::max_gpr); ++} ++ ++inline VMReg VectorRegisterImpl::as_VMReg() { ++ return VMRegImpl::as_VMReg((encoding() * VectorRegisterImpl::max_slots_per_register) + ++ ConcreteRegisterImpl::max_fpr); ++} ++ ++#endif // CPU_RISCV_VM_VMREG_RISCV_INLINE_HPP +--- /dev/null ++++ b/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp +@@ -0,0 +1,260 @@ ++/* ++ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, Red Hat Inc. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "assembler_riscv.inline.hpp" ++#include "code/vtableStubs.hpp" ++#include "interp_masm_riscv.hpp" ++#include "memory/resourceArea.hpp" ++#include "oops/compiledICHolder.hpp" ++#include "oops/instanceKlass.hpp" ++#include "oops/klassVtable.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "vmreg_riscv.inline.hpp" ++#ifdef COMPILER2 ++#include "opto/runtime.hpp" ++#endif ++ ++// machine-dependent part of VtableStubs: create VtableStub of correct size and ++// initialize its code ++ ++#define __ masm-> ++ ++#ifndef PRODUCT ++extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int index); ++#endif ++ ++VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { ++ // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing. ++ const int stub_code_length = code_size_limit(true); ++ VtableStub* s = new(stub_code_length) VtableStub(true, vtable_index); ++ // Can be NULL if there is no free space in the code cache. ++ if (s == NULL) { ++ return NULL; ++ } ++ ++ // Count unused bytes in instruction sequences of variable size. ++ // We add them to the computed buffer size in order to avoid ++ // overflow in subsequently generated stubs. ++ address start_pc = NULL; ++ int slop_bytes = 0; ++ int slop_delta = 0; ++ ++ ResourceMark rm; ++ CodeBuffer cb(s->entry_point(), stub_code_length); ++ MacroAssembler* masm = new MacroAssembler(&cb); ++ assert_cond(masm != NULL); ++ ++#if (!defined(PRODUCT) && defined(COMPILER2)) ++ if (CountCompiledCalls) { ++ __ la(t2, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); ++ __ increment(Address(t2)); ++ } ++#endif ++ ++ // get receiver (need to skip return address on top of stack) ++ assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0"); ++ ++ // get receiver klass ++ address npe_addr = __ pc(); ++ __ load_klass(t2, j_rarg0); ++ ++#ifndef PRODUCT ++ if (DebugVtables) { ++ Label L; ++ start_pc = __ pc(); ++ ++ // check offset vs vtable length ++ __ lwu(t0, Address(t2, Klass::vtable_length_offset())); ++ __ mv(t1, vtable_index * vtableEntry::size()); ++ __ bgt(t0, t1, L); ++ __ enter(); ++ __ mv(x12, vtable_index); ++ ++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), j_rarg0, x12); ++ const ptrdiff_t estimate = 256; ++ const ptrdiff_t codesize = __ pc() - start_pc; ++ slop_delta = estimate - codesize; // call_VM varies in length, depending on data ++ slop_bytes += slop_delta; ++ assert(slop_delta >= 0, "vtable #%d: Code size estimate (%d) for DebugVtables too small, required: %d", vtable_index, (int)estimate, (int)codesize); ++ ++ __ leave(); ++ __ bind(L); ++ } ++#endif // PRODUCT ++ ++ start_pc = __ pc(); ++ __ lookup_virtual_method(t2, vtable_index, xmethod); ++ // lookup_virtual_method generates ++ // 4 instructions (maximum value encountered in normal case):li(lui + addiw) + add + ld ++ // 1 instruction (best case):ld * 1 ++ slop_delta = 16 - (int)(__ pc() - start_pc); ++ slop_bytes += slop_delta; ++ assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta); ++ ++#ifndef PRODUCT ++ if (DebugVtables) { ++ Label L; ++ __ beqz(xmethod, L); ++ __ ld(t0, Address(xmethod, Method::from_compiled_offset())); ++ __ bnez(t0, L); ++ __ stop("Vtable entry is NULL"); ++ __ bind(L); ++ } ++#endif // PRODUCT ++ ++ // x10: receiver klass ++ // xmethod: Method* ++ // x12: receiver ++ address ame_addr = __ pc(); ++ __ ld(t0, Address(xmethod, Method::from_compiled_offset())); ++ __ jr(t0); ++ ++ masm->flush(); ++ bookkeeping(masm, tty, s, npe_addr, ame_addr, true, vtable_index, slop_bytes, 0); ++ ++ return s; ++} ++ ++VtableStub* VtableStubs::create_itable_stub(int itable_index) { ++ // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing. ++ const int stub_code_length = code_size_limit(false); ++ VtableStub* s = new(stub_code_length) VtableStub(false, itable_index); ++ // Can be NULL if there is no free space in the code cache. ++ if (s == NULL) { ++ return NULL; ++ } ++ // Count unused bytes in instruction sequences of variable size. ++ // We add them to the computed buffer size in order to avoid ++ // overflow in subsequently generated stubs. ++ address start_pc = NULL; ++ int slop_bytes = 0; ++ int slop_delta = 0; ++ ++ ResourceMark rm; ++ CodeBuffer cb(s->entry_point(), stub_code_length); ++ MacroAssembler* masm = new MacroAssembler(&cb); ++ assert_cond(masm != NULL); ++ ++#if (!defined(PRODUCT) && defined(COMPILER2)) ++ if (CountCompiledCalls) { ++ __ la(x18, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); ++ __ increment(Address(x18)); ++ } ++#endif ++ ++ // get receiver (need to skip return address on top of stack) ++ assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0"); ++ ++ // Entry arguments: ++ // t1: CompiledICHolder ++ // j_rarg0: Receiver ++ ++ // This stub is called from compiled code which has no callee-saved registers, ++ // so all registers except arguments are free at this point. ++ const Register recv_klass_reg = x18; ++ const Register holder_klass_reg = x19; // declaring interface klass (DECC) ++ const Register resolved_klass_reg = xmethod; // resolved interface klass (REFC) ++ const Register temp_reg = x28; ++ const Register temp_reg2 = x29; ++ const Register icholder_reg = t1; ++ ++ Label L_no_such_interface; ++ ++ __ ld(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset())); ++ __ ld(holder_klass_reg, Address(icholder_reg, CompiledICHolder::holder_metadata_offset())); ++ ++ start_pc = __ pc(); ++ ++ // get receiver klass (also an implicit null-check) ++ address npe_addr = __ pc(); ++ __ load_klass(recv_klass_reg, j_rarg0); ++ ++ // Receiver subtype check against REFC. ++ __ lookup_interface_method(// inputs: rec. class, interface ++ recv_klass_reg, resolved_klass_reg, noreg, ++ // outputs: scan temp. reg1, scan temp. reg2 ++ temp_reg2, temp_reg, ++ L_no_such_interface, ++ /*return_method=*/false); ++ ++ const ptrdiff_t typecheckSize = __ pc() - start_pc; ++ start_pc = __ pc(); ++ ++ // Get selected method from declaring class and itable index ++ __ lookup_interface_method(// inputs: rec. class, interface, itable index ++ recv_klass_reg, holder_klass_reg, itable_index, ++ // outputs: method, scan temp. reg ++ xmethod, temp_reg, ++ L_no_such_interface); ++ ++ const ptrdiff_t lookupSize = __ pc() - start_pc; ++ ++ // Reduce "estimate" such that "padding" does not drop below 8. ++ const ptrdiff_t estimate = 256; ++ const ptrdiff_t codesize = typecheckSize + lookupSize; ++ slop_delta = (int)(estimate - codesize); ++ slop_bytes += slop_delta; ++ assert(slop_delta >= 0, "itable #%d: Code size estimate (%d) for lookup_interface_method too small, required: %d", itable_index, (int)estimate, (int)codesize); ++ ++#ifdef ASSERT ++ if (DebugVtables) { ++ Label L2; ++ __ beqz(xmethod, L2); ++ __ ld(t0, Address(xmethod, Method::from_compiled_offset())); ++ __ bnez(t0, L2); ++ __ stop("compiler entrypoint is null"); ++ __ bind(L2); ++ } ++#endif // ASSERT ++ ++ // xmethod: Method* ++ // j_rarg0: receiver ++ address ame_addr = __ pc(); ++ __ ld(t0, Address(xmethod, Method::from_compiled_offset())); ++ __ jr(t0); ++ ++ __ bind(L_no_such_interface); ++ // Handle IncompatibleClassChangeError in itable stubs. ++ // More detailed error message. ++ // We force resolving of the call site by jumping to the "handle ++ // wrong method" stub, and so let the interpreter runtime do all the ++ // dirty work. ++ assert(SharedRuntime::get_handle_wrong_method_stub() != NULL, "check initialization order"); ++ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); ++ ++ masm->flush(); ++ bookkeeping(masm, tty, s, npe_addr, ame_addr, false, itable_index, slop_bytes, 0); ++ ++ return s; ++} ++ ++int VtableStub::pd_code_alignment() { ++ // RISCV cache line size is not an architected constant. We just align on word size. ++ const unsigned int icache_line_size = wordSize; ++ return icache_line_size; ++} +--- a/src/hotspot/os/linux/os_linux.cpp ++++ b/src/hotspot/os/linux/os_linux.cpp +@@ -2559,6 +2559,8 @@ void os::get_summary_cpu_info(char* cpui + strncpy(cpuinfo, "IA64", length); + #elif defined(PPC) + strncpy(cpuinfo, "PPC64", length); ++#elif defined(RISCV) ++ strncpy(cpuinfo, "RISCV64", length); + #elif defined(S390) + strncpy(cpuinfo, "S390", length); + #elif defined(SPARC) +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/assembler_linux_riscv.cpp +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (c) 1999, 2015, 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. ++ * ++ */ ++ ++// nothing required here +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp +@@ -0,0 +1,151 @@ ++/* ++ * Copyright (c) 1999, 2019, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_ATOMIC_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_ATOMIC_LINUX_RISCV_HPP ++ ++#include "runtime/vm_version.hpp" ++ ++// Implementation of class atomic ++ ++// Note that memory_order_conservative requires a full barrier after atomic stores. ++// See https://patchwork.kernel.org/patch/3575821/ ++ ++template ++struct Atomic::PlatformAdd { ++ template ++ D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const { ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ ++ D res = __atomic_add_fetch(dest, add_value, __ATOMIC_RELAXED); ++ ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ return res; ++ } ++ ++ template ++ D fetch_and_add(D volatile* dest, I add_value, atomic_memory_order order) const { ++ return add_and_fetch(dest, add_value, order) - add_value; ++ } ++}; ++ ++template ++template ++inline T Atomic::PlatformXchg::operator()(T volatile* dest, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(byte_size == sizeof(T)); ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ ++ T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELAXED); ++ ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ return res; ++} ++ ++// __attribute__((unused)) on dest is to get rid of spurious GCC warnings. ++template ++template ++inline T Atomic::PlatformCmpxchg::operator()(T volatile* dest __attribute__((unused)), ++ T compare_value, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(byte_size == sizeof(T)); ++ T value = compare_value; ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ ++ __atomic_compare_exchange(dest, &value, &exchange_value, /* weak */ false, ++ __ATOMIC_RELAXED, __ATOMIC_RELAXED); ++ ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ return value; ++} ++ ++template<> ++template ++inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest __attribute__((unused)), ++ T compare_value, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(4 == sizeof(T)); ++ ++ T old_value; ++ long rc; ++ ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ ++ __asm__ __volatile__ ( ++ "1: sext.w %1, %3 \n\t" // sign-extend compare_value ++ " lr.w %0, %2 \n\t" ++ " bne %0, %1, 2f \n\t" ++ " sc.w %1, %4, %2 \n\t" ++ " bnez %1, 1b \n\t" ++ "2: \n\t" ++ : /*%0*/"=&r" (old_value), /*%1*/"=&r" (rc), /*%2*/"+A" (*dest) ++ : /*%3*/"r" (compare_value), /*%4*/"r" (exchange_value) ++ : "memory" ); ++ ++ if (order != memory_order_relaxed) { ++ FULL_MEM_BARRIER; ++ } ++ return old_value; ++} ++ ++template ++struct Atomic::PlatformOrderedLoad ++{ ++ template ++ T operator()(const volatile T* p) const { T data; __atomic_load(const_cast(p), &data, __ATOMIC_ACQUIRE); return data; } ++}; ++ ++template ++struct Atomic::PlatformOrderedStore ++{ ++ template ++ void operator()(volatile T* p, T v) const { __atomic_store(const_cast(p), &v, __ATOMIC_RELEASE); } ++}; ++ ++template ++struct Atomic::PlatformOrderedStore ++{ ++ template ++ void operator()(volatile T* p, T v) const { release_store(p, v); OrderAccess::fence(); } ++}; ++ ++#endif // OS_CPU_LINUX_RISCV_ATOMIC_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/bytes_linux_riscv.hpp +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 1999, 2019, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_BYTES_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_BYTES_LINUX_RISCV_HPP ++ ++#include ++ ++// Efficient swapping of data bytes from Java byte ++// ordering to native byte ordering and vice versa. ++inline u2 Bytes::swap_u2(u2 x) { ++ return bswap_16(x); ++} ++ ++inline u4 Bytes::swap_u4(u4 x) { ++ return bswap_32(x); ++} ++ ++inline u8 Bytes::swap_u8(u8 x) { ++ return bswap_64(x); ++} ++ ++#endif // OS_CPU_LINUX_RISCV_BYTES_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/copy_linux_riscv.hpp +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_VM_COPY_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_VM_COPY_LINUX_RISCV_HPP ++ ++// Empty for build system ++ ++#endif // OS_CPU_LINUX_RISCV_VM_COPY_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/gc/z/zSyscall_linux_riscv.hpp +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2019, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_GC_Z_ZSYSCALL_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_GC_Z_ZSYSCALL_LINUX_RISCV_HPP ++ ++#include ++ ++// ++// Support for building on older Linux systems ++// ++ ++#ifndef SYS_memfd_create ++#define SYS_memfd_create 279 ++#endif ++#ifndef SYS_fallocate ++#define SYS_fallocate 47 ++#endif ++ ++#endif // OS_CPU_LINUX_RISCV_GC_Z_ZSYSCALL_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/globals_linux_riscv.hpp +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_VM_GLOBALS_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_VM_GLOBALS_LINUX_RISCV_HPP ++ ++// Sets the default values for platform dependent flags used by the runtime system. ++// (see globals.hpp) ++ ++define_pd_global(bool, DontYieldALot, false); ++define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default ++define_pd_global(intx, VMThreadStackSize, 2048); ++ ++define_pd_global(intx, CompilerThreadStackSize, 2048); ++ ++define_pd_global(uintx, JVMInvokeMethodSlack, 8192); ++ ++// Used on 64 bit platforms for UseCompressedOops base address ++define_pd_global(uintx, HeapBaseMinAddress, 2 * G); ++ ++#endif // OS_CPU_LINUX_RISCV_VM_GLOBALS_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (c) 2003, 2019, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_ORDERACCESS_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_ORDERACCESS_LINUX_RISCV_HPP ++ ++// Included in orderAccess.hpp header file. ++ ++#include "runtime/vm_version.hpp" ++ ++// Implementation of class OrderAccess. ++ ++inline void OrderAccess::loadload() { acquire(); } ++inline void OrderAccess::storestore() { release(); } ++inline void OrderAccess::loadstore() { acquire(); } ++inline void OrderAccess::storeload() { fence(); } ++ ++#define FULL_MEM_BARRIER __sync_synchronize() ++#define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); ++#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); ++ ++inline void OrderAccess::acquire() { ++ READ_MEM_BARRIER; ++} ++ ++inline void OrderAccess::release() { ++ WRITE_MEM_BARRIER; ++} ++ ++inline void OrderAccess::fence() { ++ FULL_MEM_BARRIER; ++} ++ ++inline void OrderAccess::cross_modify_fence_impl() { ++} ++ ++#endif // OS_CPU_LINUX_RISCV_ORDERACCESS_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp +@@ -0,0 +1,475 @@ ++/* ++ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++// no precompiled headers ++#include "asm/macroAssembler.hpp" ++#include "classfile/vmSymbols.hpp" ++#include "code/codeCache.hpp" ++#include "code/icBuffer.hpp" ++#include "code/nativeInst.hpp" ++#include "code/vtableStubs.hpp" ++#include "interpreter/interpreter.hpp" ++#include "jvm.h" ++#include "memory/allocation.inline.hpp" ++#include "os_share_linux.hpp" ++#include "prims/jniFastGetField.hpp" ++#include "prims/jvm_misc.hpp" ++#include "runtime/arguments.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/interfaceSupport.inline.hpp" ++#include "runtime/java.hpp" ++#include "runtime/javaCalls.hpp" ++#include "runtime/mutexLocker.hpp" ++#include "runtime/osThread.hpp" ++#include "runtime/safepointMechanism.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/thread.inline.hpp" ++#include "runtime/timer.hpp" ++#include "signals_posix.hpp" ++#include "utilities/debug.hpp" ++#include "utilities/events.hpp" ++#include "utilities/vmError.hpp" ++ ++// put OS-includes here ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++ ++#define REG_LR 1 ++#define REG_FP 8 ++ ++NOINLINE address os::current_stack_pointer() { ++ return (address)__builtin_frame_address(0); ++} ++ ++char* os::non_memory_address_word() { ++ // Must never look like an address returned by reserve_memory, ++ // even in its subfields (as defined by the CPU immediate fields, ++ // if the CPU splits constants across multiple instructions). ++ ++ return (char*) 0xffffffffffff; ++} ++ ++address os::Posix::ucontext_get_pc(const ucontext_t * uc) { ++ return (address)uc->uc_mcontext.__gregs[REG_PC]; ++} ++ ++void os::Posix::ucontext_set_pc(ucontext_t * uc, address pc) { ++ uc->uc_mcontext.__gregs[REG_PC] = (intptr_t)pc; ++} ++ ++intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) { ++ return (intptr_t*)uc->uc_mcontext.__gregs[REG_SP]; ++} ++ ++intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) { ++ return (intptr_t*)uc->uc_mcontext.__gregs[REG_FP]; ++} ++ ++address os::fetch_frame_from_context(const void* ucVoid, ++ intptr_t** ret_sp, intptr_t** ret_fp) { ++ address epc; ++ const ucontext_t* uc = (const ucontext_t*)ucVoid; ++ ++ if (uc != NULL) { ++ epc = os::Posix::ucontext_get_pc(uc); ++ if (ret_sp != NULL) { ++ *ret_sp = os::Linux::ucontext_get_sp(uc); ++ } ++ if (ret_fp != NULL) { ++ *ret_fp = os::Linux::ucontext_get_fp(uc); ++ } ++ } else { ++ epc = NULL; ++ if (ret_sp != NULL) { ++ *ret_sp = (intptr_t *)NULL; ++ } ++ if (ret_fp != NULL) { ++ *ret_fp = (intptr_t *)NULL; ++ } ++ } ++ ++ return epc; ++} ++ ++frame os::fetch_compiled_frame_from_context(const void* ucVoid) { ++ const ucontext_t* uc = (const ucontext_t*)ucVoid; ++ // In compiled code, the stack banging is performed before RA ++ // has been saved in the frame. RA is live, and SP and FP ++ // belong to the caller. ++ intptr_t* frame_fp = os::Linux::ucontext_get_fp(uc); ++ intptr_t* frame_sp = os::Linux::ucontext_get_sp(uc); ++ address frame_pc = (address)(uc->uc_mcontext.__gregs[REG_LR] ++ - NativeInstruction::instruction_size); ++ return frame(frame_sp, frame_fp, frame_pc); ++} ++ ++frame os::fetch_frame_from_context(const void* ucVoid) { ++ intptr_t* frame_sp = NULL; ++ intptr_t* frame_fp = NULL; ++ address epc = fetch_frame_from_context(ucVoid, &frame_sp, &frame_fp); ++ if (!is_readable_pointer(epc)) { ++ // Try to recover from calling into bad memory ++ // Assume new frame has not been set up, the same as ++ // compiled frame stack bang ++ return fetch_compiled_frame_from_context(ucVoid); ++ } ++ return frame(frame_sp, frame_fp, epc); ++} ++ ++// By default, gcc always saves frame pointer rfp on this stack. This ++// may get turned off by -fomit-frame-pointer. ++frame os::get_sender_for_C_frame(frame* fr) { ++ return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); ++} ++ ++NOINLINE frame os::current_frame() { ++ intptr_t **sender_sp = (intptr_t **)__builtin_frame_address(0); ++ if (sender_sp != NULL) { ++ frame myframe((intptr_t*)os::current_stack_pointer(), ++ sender_sp[frame::link_offset], ++ CAST_FROM_FN_PTR(address, os::current_frame)); ++ if (os::is_first_C_frame(&myframe)) { ++ // stack is not walkable ++ return frame(); ++ } else { ++ return os::get_sender_for_C_frame(&myframe); ++ } ++ } else { ++ ShouldNotReachHere(); ++ return frame(); ++ } ++} ++ ++// Utility functions ++bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info, ++ ucontext_t* uc, JavaThread* thread) { ++ ++ // decide if this trap can be handled by a stub ++ address stub = NULL; ++ ++ address pc = NULL; ++ ++ //%note os_trap_1 ++ if (info != NULL && uc != NULL && thread != NULL) { ++ pc = (address) os::Posix::ucontext_get_pc(uc); ++ ++ address addr = (address) info->si_addr; ++ ++ // Make sure the high order byte is sign extended, as it may be masked away by the hardware. ++ if ((uintptr_t(addr) & (uintptr_t(1) << 55)) != 0) { ++ addr = address(uintptr_t(addr) | (uintptr_t(0xFF) << 56)); ++ } ++ ++ // Handle ALL stack overflow variations here ++ if (sig == SIGSEGV) { ++ // check if fault address is within thread stack ++ if (thread->is_in_full_stack(addr)) { ++ if (os::Posix::handle_stack_overflow(thread, addr, pc, uc, &stub)) { ++ return true; // continue ++ } ++ } ++ } ++ ++ if (thread->thread_state() == _thread_in_Java) { ++ // Java thread running in Java code => find exception handler if any ++ // a fault inside compiled code, the interpreter, or a stub ++ ++ // Handle signal from NativeJump::patch_verified_entry(). ++ if ((sig == SIGILL || sig == SIGTRAP) ++ && nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) { ++ if (TraceTraps) { ++ tty->print_cr("trap: zombie_not_entrant (%s)", (sig == SIGTRAP) ? "SIGTRAP" : "SIGILL"); ++ } ++ stub = SharedRuntime::get_handle_wrong_method_stub(); ++ } else if (sig == SIGSEGV && SafepointMechanism::is_poll_address((address)info->si_addr)) { ++ stub = SharedRuntime::get_poll_stub(pc); ++ } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) { ++ // BugId 4454115: A read from a MappedByteBuffer can fault ++ // here if the underlying file has been truncated. ++ // Do not crash the VM in such a case. ++ CodeBlob* cb = CodeCache::find_blob_unsafe(pc); ++ CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; ++ bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc)); ++ if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) { ++ address next_pc = pc + NativeCall::instruction_size; ++ if (is_unsafe_arraycopy) { ++ next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); ++ } ++ stub = SharedRuntime::handle_unsafe_access(thread, next_pc); ++ } ++ } else if (sig == SIGILL && nativeInstruction_at(pc)->is_stop()) { ++ // Pull a pointer to the error message out of the instruction ++ // stream. ++ const uint64_t *detail_msg_ptr ++ = (uint64_t*)(pc + NativeInstruction::instruction_size); ++ const char *detail_msg = (const char *)*detail_msg_ptr; ++ const char *msg = "stop"; ++ if (TraceTraps) { ++ tty->print_cr("trap: %s: (SIGILL)", msg); ++ } ++ ++ // End life with a fatal error, message and detail message and the context. ++ // Note: no need to do any post-processing here (e.g. signal chaining) ++ va_list va_dummy; ++ VMError::report_and_die(thread, uc, NULL, 0, msg, detail_msg, va_dummy); ++ va_end(va_dummy); ++ ++ ShouldNotReachHere(); ++ } else if (sig == SIGFPE && ++ (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) { ++ stub = ++ SharedRuntime:: ++ continuation_for_implicit_exception(thread, ++ pc, ++ SharedRuntime:: ++ IMPLICIT_DIVIDE_BY_ZERO); ++ } else if (sig == SIGSEGV && ++ MacroAssembler::uses_implicit_null_check((void*)addr)) { ++ // Determination of interpreter/vtable stub/compiled code null exception ++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); ++ } ++ } else if ((thread->thread_state() == _thread_in_vm || ++ thread->thread_state() == _thread_in_native) && ++ sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ ++ thread->doing_unsafe_access()) { ++ address next_pc = pc + NativeCall::instruction_size; ++ if (UnsafeCopyMemory::contains_pc(pc)) { ++ next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); ++ } ++ stub = SharedRuntime::handle_unsafe_access(thread, next_pc); ++ } ++ ++ // jni_fast_GetField can trap at certain pc's if a GC kicks in ++ // and the heap gets shrunk before the field access. ++ if ((sig == SIGSEGV) || (sig == SIGBUS)) { ++ address addr_slow = JNI_FastGetField::find_slowcase_pc(pc); ++ if (addr_slow != (address)-1) { ++ stub = addr_slow; ++ } ++ } ++ } ++ ++ if (stub != NULL) { ++ // save all thread context in case we need to restore it ++ if (thread != NULL) { ++ thread->set_saved_exception_pc(pc); ++ } ++ ++ os::Posix::ucontext_set_pc(uc, stub); ++ return true; ++ } ++ ++ return false; // Mute compiler ++} ++ ++void os::Linux::init_thread_fpu_state(void) { ++} ++ ++int os::Linux::get_fpu_control_word(void) { ++ return 0; ++} ++ ++void os::Linux::set_fpu_control_word(int fpu_control) { ++} ++ ++//////////////////////////////////////////////////////////////////////////////// ++// thread stack ++ ++// Minimum usable stack sizes required to get to user code. Space for ++// HotSpot guard pages is added later. ++size_t os::Posix::_compiler_thread_min_stack_allowed = 72 * K; ++size_t os::Posix::_java_thread_min_stack_allowed = 72 * K; ++size_t os::Posix::_vm_internal_thread_min_stack_allowed = 72 * K; ++ ++// return default stack size for thr_type ++size_t os::Posix::default_stack_size(os::ThreadType thr_type) { ++ // default stack size (compiler thread needs larger stack) ++ size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); ++ return s; ++} ++ ++///////////////////////////////////////////////////////////////////////////// ++// helper functions for fatal error handler ++ ++static const char* reg_abi_names[] = { ++ "pc", ++ "x1(ra)", "x2(sp)", "x3(gp)", "x4(tp)", ++ "x5(t0)", "x6(t1)", "x7(t2)", ++ "x8(s0)", "x9(s1)", ++ "x10(a0)", "x11(a1)", "x12(a2)", "x13(a3)", "x14(a4)", "x15(a5)", "x16(a6)", "x17(a7)", ++ "x18(s2)", "x19(s3)", "x20(s4)", "x21(s5)", "x22(s6)", "x23(s7)", "x24(s8)", "x25(s9)", "x26(s10)", "x27(s11)", ++ "x28(t3)", "x29(t4)","x30(t5)", "x31(t6)" ++}; ++ ++void os::print_context(outputStream *st, const void *context) { ++ if (context == NULL) { ++ return; ++ } ++ ++ const ucontext_t *uc = (const ucontext_t*)context; ++ st->print_cr("Registers:"); ++ for (int r = 0; r < 32; r++) { ++ st->print("%-*.*s=", 8, 8, reg_abi_names[r]); ++ print_location(st, uc->uc_mcontext.__gregs[r]); ++ } ++ st->cr(); ++ ++ intptr_t *frame_sp = (intptr_t *)os::Linux::ucontext_get_sp(uc); ++ st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(frame_sp)); ++ print_hex_dump(st, (address)frame_sp, (address)(frame_sp + 64), sizeof(intptr_t)); ++ st->cr(); ++ ++ // Note: it may be unsafe to inspect memory near pc. For example, pc may ++ // point to garbage if entry point in an nmethod is corrupted. Leave ++ // this at the end, and hope for the best. ++ address pc = os::fetch_frame_from_context(uc).pc(); ++ print_instructions(st, pc, UseRVC ? sizeof(char) : (int)NativeInstruction::instruction_size); ++ st->cr(); ++} ++ ++void os::print_register_info(outputStream *st, const void *context) { ++ if (context == NULL) { ++ return; ++ } ++ ++ const ucontext_t *uc = (const ucontext_t*)context; ++ ++ st->print_cr("Register to memory mapping:"); ++ st->cr(); ++ ++ // this is horrendously verbose but the layout of the registers in the ++ // context does not match how we defined our abstract Register set, so ++ // we can't just iterate through the gregs area ++ ++ // this is only for the "general purpose" registers ++ ++ for (int r = 0; r < 32; r++) ++ st->print_cr("%-*.*s=" INTPTR_FORMAT, 8, 8, reg_abi_names[r], (uintptr_t)uc->uc_mcontext.__gregs[r]); ++ st->cr(); ++} ++ ++void os::setup_fpu() { ++} ++ ++#ifndef PRODUCT ++void os::verify_stack_alignment() { ++ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); ++} ++#endif ++ ++int os::extra_bang_size_in_bytes() { ++ return 0; ++} ++ ++extern "C" { ++ int SpinPause() { ++ return 0; ++ } ++ ++ void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { ++ if (from > to) { ++ const jshort *end = from + count; ++ while (from < end) { ++ *(to++) = *(from++); ++ } ++ } else if (from < to) { ++ const jshort *end = from; ++ from += count - 1; ++ to += count - 1; ++ while (from >= end) { ++ *(to--) = *(from--); ++ } ++ } ++ } ++ void _Copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { ++ if (from > to) { ++ const jint *end = from + count; ++ while (from < end) { ++ *(to++) = *(from++); ++ } ++ } else if (from < to) { ++ const jint *end = from; ++ from += count - 1; ++ to += count - 1; ++ while (from >= end) { ++ *(to--) = *(from--); ++ } ++ } ++ } ++ void _Copy_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { ++ if (from > to) { ++ const jlong *end = from + count; ++ while (from < end) { ++ os::atomic_copy64(from++, to++); ++ } ++ } else if (from < to) { ++ const jlong *end = from; ++ from += count - 1; ++ to += count - 1; ++ while (from >= end) { ++ os::atomic_copy64(from--, to--); ++ } ++ } ++ } ++ ++ void _Copy_arrayof_conjoint_bytes(const HeapWord* from, ++ HeapWord* to, ++ size_t count) { ++ memmove(to, from, count); ++ } ++ void _Copy_arrayof_conjoint_jshorts(const HeapWord* from, ++ HeapWord* to, ++ size_t count) { ++ memmove(to, from, count * 2); ++ } ++ void _Copy_arrayof_conjoint_jints(const HeapWord* from, ++ HeapWord* to, ++ size_t count) { ++ memmove(to, from, count * 4); ++ } ++ void _Copy_arrayof_conjoint_jlongs(const HeapWord* from, ++ HeapWord* to, ++ size_t count) { ++ memmove(to, from, count * 8); ++ } ++}; +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.hpp +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 1999, 2020, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_VM_OS_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_VM_OS_LINUX_RISCV_HPP ++ ++ static void setup_fpu(); ++ ++ // Used to register dynamic code cache area with the OS ++ // Note: Currently only used in 64 bit Windows implementations ++ static bool register_code_area(char *low, char *high) { return true; } ++ ++ // Atomically copy 64 bits of data ++ static void atomic_copy64(const volatile void *src, volatile void *dst) { ++ *(jlong *) dst = *(const jlong *) src; ++ } ++ ++#endif // OS_CPU_LINUX_RISCV_VM_OS_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/prefetch_linux_riscv.inline.hpp +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (c) 2003, 2019, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_VM_PREFETCH_LINUX_RISCV_INLINE_HPP ++#define OS_CPU_LINUX_RISCV_VM_PREFETCH_LINUX_RISCV_INLINE_HPP ++ ++#include "runtime/prefetch.hpp" ++ ++ ++inline void Prefetch::read (void *loc, intx interval) { ++} ++ ++inline void Prefetch::write(void *loc, intx interval) { ++} ++ ++#endif // OS_CPU_LINUX_RISCV_VM_PREFETCH_LINUX_RISCV_INLINE_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/thread_linux_riscv.cpp +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (c) 2003, 2019, 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/thread.inline.hpp" ++ ++frame JavaThread::pd_last_frame() { ++ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); ++ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); ++} ++ ++// For Forte Analyzer AsyncGetCallTrace profiling support - thread is ++// currently interrupted by SIGPROF ++bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, ++ void* ucontext, bool isInJava) { ++ ++ assert(Thread::current() == this, "caller must be current thread"); ++ return pd_get_top_frame(fr_addr, ucontext, isInJava); ++} ++ ++bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { ++ return pd_get_top_frame(fr_addr, ucontext, isInJava); ++} ++ ++bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) { ++ // If we have a last_Java_frame, then we should use it even if ++ // isInJava == true. It should be more reliable than ucontext info. ++ if (has_last_Java_frame() && frame_anchor()->walkable()) { ++ *fr_addr = pd_last_frame(); ++ return true; ++ } ++ ++ // At this point, we don't have a last_Java_frame, so ++ // we try to glean some information out of the ucontext ++ // if we were running Java code when SIGPROF came in. ++ if (isInJava) { ++ ucontext_t* uc = (ucontext_t*) ucontext; ++ ++ intptr_t* ret_fp = NULL; ++ intptr_t* ret_sp = NULL; ++ address addr = os::fetch_frame_from_context(uc, &ret_sp, &ret_fp); ++ if (addr == NULL || ret_sp == NULL ) { ++ // ucontext wasn't useful ++ return false; ++ } ++ ++ frame ret_frame(ret_sp, ret_fp, addr); ++ if (!ret_frame.safe_for_sender(this)) { ++#ifdef COMPILER2 ++ frame ret_frame2(ret_sp, NULL, addr); ++ if (!ret_frame2.safe_for_sender(this)) { ++ // nothing else to try if the frame isn't good ++ return false; ++ } ++ ret_frame = ret_frame2; ++#else ++ // nothing else to try if the frame isn't good ++ return false; ++#endif /* COMPILER2 */ ++ } ++ *fr_addr = ret_frame; ++ return true; ++ } ++ ++ // nothing else to try ++ return false; ++} ++ ++void JavaThread::cache_global_variables() { } +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/thread_linux_riscv.hpp +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_THREAD_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_THREAD_LINUX_RISCV_HPP ++ ++ private: ++ void pd_initialize() { ++ _anchor.clear(); ++ } ++ ++ frame pd_last_frame(); ++ ++ public: ++ static ByteSize last_Java_fp_offset() { ++ return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset(); ++ } ++ ++ bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, ++ bool isInJava); ++ ++ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava); ++private: ++ bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava); ++ ++#endif // OS_CPU_LINUX_RISCV_THREAD_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/vmStructs_linux_riscv.hpp +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (c) 2000, 2019, 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. ++ * ++ */ ++ ++#ifndef OS_CPU_LINUX_RISCV_VM_VMSTRUCTS_LINUX_RISCV_HPP ++#define OS_CPU_LINUX_RISCV_VM_VMSTRUCTS_LINUX_RISCV_HPP ++ ++// These are the OS and CPU-specific fields, types and integer ++// constants required by the Serviceability Agent. This file is ++// referenced by vmStructs.cpp. ++ ++#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ ++ \ ++ /******************************/ \ ++ /* Threads (NOTE: incomplete) */ \ ++ /******************************/ \ ++ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ ++ nonstatic_field(OSThread, _pthread_id, pthread_t) ++ ++ ++#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ ++ \ ++ /**********************/ \ ++ /* Posix Thread IDs */ \ ++ /**********************/ \ ++ \ ++ declare_integer_type(OSThread::thread_id_t) \ ++ declare_unsigned_integer_type(pthread_t) ++ ++#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#endif // OS_CPU_LINUX_RISCV_VM_VMSTRUCTS_LINUX_RISCV_HPP +--- /dev/null ++++ b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 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. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/register.hpp" ++#include "runtime/os.hpp" ++#include "runtime/os.inline.hpp" ++#include "runtime/vm_version.hpp" ++ ++#include ++#include ++ ++#ifndef HWCAP_ISA_I ++#define HWCAP_ISA_I (1 << ('I' - 'A')) ++#endif ++ ++#ifndef HWCAP_ISA_M ++#define HWCAP_ISA_M (1 << ('M' - 'A')) ++#endif ++ ++#ifndef HWCAP_ISA_A ++#define HWCAP_ISA_A (1 << ('A' - 'A')) ++#endif ++ ++#ifndef HWCAP_ISA_F ++#define HWCAP_ISA_F (1 << ('F' - 'A')) ++#endif ++ ++#ifndef HWCAP_ISA_D ++#define HWCAP_ISA_D (1 << ('D' - 'A')) ++#endif ++ ++#ifndef HWCAP_ISA_C ++#define HWCAP_ISA_C (1 << ('C' - 'A')) ++#endif ++ ++#ifndef HWCAP_ISA_V ++#define HWCAP_ISA_V (1 << ('V' - 'A')) ++#endif ++ ++#define read_csr(csr) \ ++({ \ ++ register unsigned long __v; \ ++ __asm__ __volatile__ ("csrr %0, %1" \ ++ : "=r" (__v) \ ++ : "i" (csr) \ ++ : "memory"); \ ++ __v; \ ++}) ++ ++uint32_t VM_Version::get_current_vector_length() { ++ assert(_features & CPU_V, "should not call this"); ++ return (uint32_t)read_csr(CSR_VLENB); ++} ++ ++VM_Version::VM_MODE VM_Version::get_satp_mode() { ++ if (!strcmp(_vm_mode, "sv39")) { ++ return VM_SV39; ++ } else if (!strcmp(_vm_mode, "sv48")) { ++ return VM_SV48; ++ } else if (!strcmp(_vm_mode, "sv57")) { ++ return VM_SV57; ++ } else if (!strcmp(_vm_mode, "sv64")) { ++ return VM_SV64; ++ } else { ++ return VM_MBARE; ++ } ++} ++ ++void VM_Version::get_os_cpu_info() { ++ ++ uint64_t auxv = getauxval(AT_HWCAP); ++ ++ static_assert(CPU_I == HWCAP_ISA_I, "Flag CPU_I must follow Linux HWCAP"); ++ static_assert(CPU_M == HWCAP_ISA_M, "Flag CPU_M must follow Linux HWCAP"); ++ static_assert(CPU_A == HWCAP_ISA_A, "Flag CPU_A must follow Linux HWCAP"); ++ static_assert(CPU_F == HWCAP_ISA_F, "Flag CPU_F must follow Linux HWCAP"); ++ static_assert(CPU_D == HWCAP_ISA_D, "Flag CPU_D must follow Linux HWCAP"); ++ static_assert(CPU_C == HWCAP_ISA_C, "Flag CPU_C must follow Linux HWCAP"); ++ static_assert(CPU_V == HWCAP_ISA_V, "Flag CPU_V must follow Linux HWCAP"); ++ ++ // RISC-V has four bit-manipulation ISA-extensions: Zba/Zbb/Zbc/Zbs. ++ // Availability for those extensions could not be queried from HWCAP. ++ // TODO: Add proper detection for those extensions. ++ _features = auxv & ( ++ HWCAP_ISA_I | ++ HWCAP_ISA_M | ++ HWCAP_ISA_A | ++ HWCAP_ISA_F | ++ HWCAP_ISA_D | ++ HWCAP_ISA_C | ++ HWCAP_ISA_V); ++ ++ if (FILE *f = fopen("/proc/cpuinfo", "r")) { ++ char buf[512], *p; ++ while (fgets(buf, sizeof (buf), f) != NULL) { ++ if ((p = strchr(buf, ':')) != NULL) { ++ if (strncmp(buf, "mmu", sizeof "mmu" - 1) == 0) { ++ if (_vm_mode[0] != '\0') { ++ continue; ++ } ++ char* vm_mode = os::strdup(p + 2); ++ vm_mode[strcspn(vm_mode, "\n")] = '\0'; ++ _vm_mode = vm_mode; ++ } else if (strncmp(buf, "uarch", sizeof "uarch" - 1) == 0) { ++ char* uarch = os::strdup(p + 2); ++ uarch[strcspn(uarch, "\n")] = '\0'; ++ _uarch = uarch; ++ break; ++ } ++ } ++ } ++ fclose(f); ++ } ++} +--- a/src/hotspot/share/c1/c1_LIR.cpp ++++ b/src/hotspot/share/c1/c1_LIR.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -188,6 +188,9 @@ void LIR_Op2::verify() const { + #ifdef ASSERT + switch (code()) { + case lir_cmove: ++#ifdef RISCV ++ assert(false, "lir_cmove is LIR_Op4 on RISCV"); ++#endif + case lir_xchg: + break; + +@@ -238,8 +241,12 @@ void LIR_Op2::verify() const { + + + LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, BlockBegin* block) ++#ifdef RISCV ++ : LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) ++#else + : LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) + , _cond(cond) ++#endif + , _label(block->label()) + , _block(block) + , _ublock(NULL) +@@ -247,8 +254,12 @@ LIR_OpBranch::LIR_OpBranch(LIR_Condition + } + + LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, CodeStub* stub) : ++#ifdef RISCV ++ LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) ++#else + LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) + , _cond(cond) ++#endif + , _label(stub->entry()) + , _block(NULL) + , _ublock(NULL) +@@ -256,8 +267,12 @@ LIR_OpBranch::LIR_OpBranch(LIR_Condition + } + + LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock) ++#ifdef RISCV ++ : LIR_Op2(lir_cond_float_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) ++#else + : LIR_Op(lir_cond_float_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) + , _cond(cond) ++#endif + , _label(block->label()) + , _block(block) + , _ublock(ublock) +@@ -279,13 +294,13 @@ void LIR_OpBranch::change_ublock(BlockBe + } + + void LIR_OpBranch::negate_cond() { +- switch (_cond) { +- case lir_cond_equal: _cond = lir_cond_notEqual; break; +- case lir_cond_notEqual: _cond = lir_cond_equal; break; +- case lir_cond_less: _cond = lir_cond_greaterEqual; break; +- case lir_cond_lessEqual: _cond = lir_cond_greater; break; +- case lir_cond_greaterEqual: _cond = lir_cond_less; break; +- case lir_cond_greater: _cond = lir_cond_lessEqual; break; ++ switch (cond()) { ++ case lir_cond_equal: set_cond(lir_cond_notEqual); break; ++ case lir_cond_notEqual: set_cond(lir_cond_equal); break; ++ case lir_cond_less: set_cond(lir_cond_greaterEqual); break; ++ case lir_cond_lessEqual: set_cond(lir_cond_greater); break; ++ case lir_cond_greaterEqual: set_cond(lir_cond_less); break; ++ case lir_cond_greater: set_cond(lir_cond_lessEqual); break; + default: ShouldNotReachHere(); + } + } +@@ -513,6 +528,15 @@ void LIR_OpVisitState::visit(LIR_Op* op) + assert(op->as_OpBranch() != NULL, "must be"); + LIR_OpBranch* opBranch = (LIR_OpBranch*)op; + ++#ifdef RISCV ++ assert(opBranch->_tmp1->is_illegal() && opBranch->_tmp2->is_illegal() && ++ opBranch->_tmp3->is_illegal() && opBranch->_tmp4->is_illegal() && ++ opBranch->_tmp5->is_illegal(), "not used"); ++ ++ if (opBranch->_opr1->is_valid()) do_input(opBranch->_opr1); ++ if (opBranch->_opr2->is_valid()) do_input(opBranch->_opr2); ++#endif ++ + if (opBranch->_info != NULL) do_info(opBranch->_info); + assert(opBranch->_result->is_illegal(), "not used"); + if (opBranch->_stub != NULL) opBranch->stub()->visit(this); +@@ -601,6 +625,21 @@ void LIR_OpVisitState::visit(LIR_Op* op) + // to the result operand, otherwise the backend fails + case lir_cmove: + { ++#ifdef RISCV ++ assert(op->as_Op4() != NULL, "must be"); ++ LIR_Op4* op4 = (LIR_Op4*)op; ++ ++ assert(op4->_info == NULL && op4->_tmp1->is_illegal() && op4->_tmp2->is_illegal() && ++ op4->_tmp3->is_illegal() && op4->_tmp4->is_illegal() && op4->_tmp5->is_illegal(), "not used"); ++ assert(op4->_opr1->is_valid() && op4->_opr2->is_valid() && op4->_result->is_valid(), "used"); ++ ++ do_input(op4->_opr1); ++ do_input(op4->_opr2); ++ if (op4->_opr3->is_valid()) do_input(op4->_opr3); ++ if (op4->_opr4->is_valid()) do_input(op4->_opr4); ++ do_temp(op4->_opr2); ++ do_output(op4->_result); ++#else + assert(op->as_Op2() != NULL, "must be"); + LIR_Op2* op2 = (LIR_Op2*)op; + +@@ -612,6 +651,7 @@ void LIR_OpVisitState::visit(LIR_Op* op) + do_input(op2->_opr2); + do_temp(op2->_opr2); + do_output(op2->_result); ++#endif + + break; + } +@@ -1042,6 +1082,12 @@ void LIR_Op3::emit_code(LIR_Assembler* m + masm->emit_op3(this); + } + ++#ifdef RISCV ++void LIR_Op4::emit_code(LIR_Assembler* masm) { ++ masm->emit_op4(this); ++} ++#endif ++ + void LIR_OpLock::emit_code(LIR_Assembler* masm) { + masm->emit_lock(this); + if (stub()) { +@@ -1078,6 +1124,10 @@ LIR_List::LIR_List(Compilation* compilat + , _file(NULL) + , _line(0) + #endif ++#ifdef RISCV ++ , _cmp_opr1(LIR_OprFact::illegalOpr) ++ , _cmp_opr2(LIR_OprFact::illegalOpr) ++#endif + { } + + +@@ -1095,6 +1145,38 @@ void LIR_List::set_file_and_line(const c + } + #endif + ++#ifdef RISCV ++void LIR_List::set_cmp_oprs(LIR_Op* op) { ++ switch (op->code()) { ++ case lir_cmp: ++ _cmp_opr1 = op->as_Op2()->in_opr1(); ++ _cmp_opr2 = op->as_Op2()->in_opr2(); ++ break; ++ case lir_branch: // fall through ++ case lir_cond_float_branch: ++ assert(op->as_OpBranch()->cond() == lir_cond_always || ++ (_cmp_opr1 != LIR_OprFact::illegalOpr && _cmp_opr2 != LIR_OprFact::illegalOpr), ++ "conditional branches must have legal operands"); ++ if (op->as_OpBranch()->cond() != lir_cond_always) { ++ op->as_Op2()->set_in_opr1(_cmp_opr1); ++ op->as_Op2()->set_in_opr2(_cmp_opr2); ++ } ++ break; ++ case lir_cmove: ++ op->as_Op4()->set_in_opr3(_cmp_opr1); ++ op->as_Op4()->set_in_opr4(_cmp_opr2); ++ break; ++#if INCLUDE_ZGC ++ case lir_zloadbarrier_test: ++ _cmp_opr1 = FrameMap::as_opr(t1); ++ _cmp_opr2 = LIR_OprFact::intConst(0); ++ break; ++#endif ++ default: ++ break; ++ } ++} ++#endif + + void LIR_List::append(LIR_InsertionBuffer* buffer) { + assert(this == buffer->lir_list(), "wrong lir list"); +@@ -1825,6 +1907,10 @@ void LIR_Op1::print_patch_code(outputStr + // LIR_OpBranch + void LIR_OpBranch::print_instr(outputStream* out) const { + print_condition(out, cond()); out->print(" "); ++#ifdef RISCV ++ in_opr1()->print(out); out->print(" "); ++ in_opr2()->print(out); out->print(" "); ++#endif + if (block() != NULL) { + out->print("[B%d] ", block()->block_id()); + } else if (stub() != NULL) { +@@ -1911,7 +1997,11 @@ void LIR_OpRoundFP::print_instr(outputSt + + // LIR_Op2 + void LIR_Op2::print_instr(outputStream* out) const { ++#ifdef RISCV ++ if (code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch) { ++#else + if (code() == lir_cmove || code() == lir_cmp) { ++#endif + print_condition(out, condition()); out->print(" "); + } + in_opr1()->print(out); out->print(" "); +@@ -1962,6 +2052,17 @@ void LIR_Op3::print_instr(outputStream* + result_opr()->print(out); + } + ++#ifdef RISCV ++// LIR_Op4 ++void LIR_Op4::print_instr(outputStream* out) const { ++ print_condition(out, condition()); out->print(" "); ++ in_opr1()->print(out); out->print(" "); ++ in_opr2()->print(out); out->print(" "); ++ in_opr3()->print(out); out->print(" "); ++ in_opr4()->print(out); out->print(" "); ++ result_opr()->print(out); ++} ++#endif + + void LIR_OpLock::print_instr(outputStream* out) const { + hdr_opr()->print(out); out->print(" "); +--- a/src/hotspot/share/c1/c1_LIR.hpp ++++ b/src/hotspot/share/c1/c1_LIR.hpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -869,6 +869,9 @@ class LIR_Op2; + class LIR_OpDelay; + class LIR_Op3; + class LIR_OpAllocArray; ++#ifdef RISCV ++class LIR_Op4; ++#endif + class LIR_OpCall; + class LIR_OpJavaCall; + class LIR_OpRTCall; +@@ -913,8 +916,10 @@ enum LIR_Code { + , lir_null_check + , lir_return + , lir_leal ++#ifndef RISCV + , lir_branch + , lir_cond_float_branch ++#endif + , lir_move + , lir_convert + , lir_alloc_object +@@ -924,11 +929,17 @@ enum LIR_Code { + , lir_unwind + , end_op1 + , begin_op2 ++#ifdef RISCV ++ , lir_branch ++ , lir_cond_float_branch ++#endif + , lir_cmp + , lir_cmp_l2i + , lir_ucmp_fd2i + , lir_cmp_fd2i ++#ifndef RISCV + , lir_cmove ++#endif + , lir_add + , lir_sub + , lir_mul +@@ -956,6 +967,11 @@ enum LIR_Code { + , lir_fmad + , lir_fmaf + , end_op3 ++#ifdef RISCV ++ , begin_op4 ++ , lir_cmove ++ , end_op4 ++#endif + , begin_opJavaCall + , lir_static_call + , lir_optvirtual_call +@@ -992,6 +1008,11 @@ enum LIR_Code { + , begin_opAssert + , lir_assert + , end_opAssert ++#if defined(RISCV) && defined(INCLUDE_ZGC) ++ , begin_opZLoadBarrierTest ++ , lir_zloadbarrier_test ++ , end_opZLoadBarrierTest ++#endif + }; + + +@@ -1128,6 +1149,9 @@ class LIR_Op: public CompilationResource + virtual LIR_Op1* as_Op1() { return NULL; } + virtual LIR_Op2* as_Op2() { return NULL; } + virtual LIR_Op3* as_Op3() { return NULL; } ++#ifdef RISCV ++ virtual LIR_Op4* as_Op4() { return NULL; } ++#endif + virtual LIR_OpArrayCopy* as_OpArrayCopy() { return NULL; } + virtual LIR_OpUpdateCRC32* as_OpUpdateCRC32() { return NULL; } + virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; } +@@ -1399,47 +1423,6 @@ class LIR_OpRTCall: public LIR_OpCall { + virtual void verify() const; + }; + +- +-class LIR_OpBranch: public LIR_Op { +- friend class LIR_OpVisitState; +- +- private: +- LIR_Condition _cond; +- Label* _label; +- BlockBegin* _block; // if this is a branch to a block, this is the block +- BlockBegin* _ublock; // if this is a float-branch, this is the unorderd block +- CodeStub* _stub; // if this is a branch to a stub, this is the stub +- +- public: +- LIR_OpBranch(LIR_Condition cond, Label* lbl) +- : LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL) +- , _cond(cond) +- , _label(lbl) +- , _block(NULL) +- , _ublock(NULL) +- , _stub(NULL) { } +- +- LIR_OpBranch(LIR_Condition cond, BlockBegin* block); +- LIR_OpBranch(LIR_Condition cond, CodeStub* stub); +- +- // for unordered comparisons +- LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock); +- +- LIR_Condition cond() const { return _cond; } +- Label* label() const { return _label; } +- BlockBegin* block() const { return _block; } +- BlockBegin* ublock() const { return _ublock; } +- CodeStub* stub() const { return _stub; } +- +- void change_block(BlockBegin* b); +- void change_ublock(BlockBegin* b); +- void negate_cond(); +- +- virtual void emit_code(LIR_Assembler* masm); +- virtual LIR_OpBranch* as_OpBranch() { return this; } +- virtual void print_instr(outputStream* out) const PRODUCT_RETURN; +-}; +- + class LIR_OpReturn: public LIR_Op1 { + friend class LIR_OpVisitState; + +@@ -1612,19 +1595,19 @@ class LIR_Op2: public LIR_Op { + void verify() const; + + public: +- LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, CodeEmitInfo* info = NULL) ++ LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, CodeEmitInfo* info = NULL, BasicType type = T_ILLEGAL) + : LIR_Op(code, LIR_OprFact::illegalOpr, info) + , _fpu_stack_size(0) + , _opr1(opr1) + , _opr2(opr2) +- , _type(T_ILLEGAL) ++ , _type(type) + , _tmp1(LIR_OprFact::illegalOpr) + , _tmp2(LIR_OprFact::illegalOpr) + , _tmp3(LIR_OprFact::illegalOpr) + , _tmp4(LIR_OprFact::illegalOpr) + , _tmp5(LIR_OprFact::illegalOpr) + , _condition(condition) { +- assert(code == lir_cmp || code == lir_assert, "code check"); ++ assert(code == lir_cmp || code == lir_assert RISCV_ONLY(|| code == lir_branch || code == lir_cond_float_branch), "code check"); + } + + LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) +@@ -1656,7 +1639,7 @@ class LIR_Op2: public LIR_Op { + , _tmp4(LIR_OprFact::illegalOpr) + , _tmp5(LIR_OprFact::illegalOpr) + , _condition(lir_cond_unknown) { +- assert(code != lir_cmp && is_in_range(code, begin_op2, end_op2), "code check"); ++ assert(code != lir_cmp && RISCV_ONLY(code != lir_branch && code != lir_cond_float_branch &&) is_in_range(code, begin_op2, end_op2), "code check"); + } + + LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2 = LIR_OprFact::illegalOpr, +@@ -1672,7 +1655,7 @@ class LIR_Op2: public LIR_Op { + , _tmp4(tmp4) + , _tmp5(tmp5) + , _condition(lir_cond_unknown) { +- assert(code != lir_cmp && is_in_range(code, begin_op2, end_op2), "code check"); ++ assert(code != lir_cmp && RISCV_ONLY(code != lir_branch && code != lir_cond_float_branch &&) is_in_range(code, begin_op2, end_op2), "code check"); + } + + LIR_Opr in_opr1() const { return _opr1; } +@@ -1684,10 +1667,18 @@ class LIR_Op2: public LIR_Op { + LIR_Opr tmp4_opr() const { return _tmp4; } + LIR_Opr tmp5_opr() const { return _tmp5; } + LIR_Condition condition() const { ++#ifdef RISCV ++ assert(code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch || code() == lir_assert, "only valid for branch and assert"); return _condition; ++#else + assert(code() == lir_cmp || code() == lir_cmove || code() == lir_assert, "only valid for cmp and cmove and assert"); return _condition; ++#endif + } + void set_condition(LIR_Condition condition) { ++#ifdef RISCV ++ assert(code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch, "only valid for branch"); _condition = condition; ++#else + assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); _condition = condition; ++#endif + } + + void set_fpu_stack_size(int size) { _fpu_stack_size = size; } +@@ -1701,6 +1692,62 @@ class LIR_Op2: public LIR_Op { + virtual void print_instr(outputStream* out) const PRODUCT_RETURN; + }; + ++#ifdef RISCV ++class LIR_OpBranch: public LIR_Op2 { ++#else ++class LIR_OpBranch: public LIR_Op { ++#endif ++ friend class LIR_OpVisitState; ++ ++ private: ++#ifndef RISCV ++ LIR_Condition _cond; ++#endif ++ Label* _label; ++ BlockBegin* _block; // if this is a branch to a block, this is the block ++ BlockBegin* _ublock; // if this is a float-branch, this is the unordered block ++ CodeStub* _stub; // if this is a branch to a stub, this is the stub ++ ++ public: ++ LIR_OpBranch(LIR_Condition cond, Label* lbl) ++#ifdef RISCV ++ : LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL) ++#else ++ : LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL) ++ , _cond(cond) ++#endif ++ , _label(lbl) ++ , _block(NULL) ++ , _ublock(NULL) ++ , _stub(NULL) { } ++ ++ LIR_OpBranch(LIR_Condition cond, BlockBegin* block); ++ LIR_OpBranch(LIR_Condition cond, CodeStub* stub); ++ ++ // for unordered comparisons ++ LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock); ++ ++#ifdef RISCV ++ LIR_Condition cond() const { return condition(); } ++ void set_cond(LIR_Condition cond) { set_condition(cond); } ++#else ++ LIR_Condition cond() const { return _cond; } ++ void set_cond(LIR_Condition cond) { _cond = cond; } ++#endif ++ Label* label() const { return _label; } ++ BlockBegin* block() const { return _block; } ++ BlockBegin* ublock() const { return _ublock; } ++ CodeStub* stub() const { return _stub; } ++ ++ void change_block(BlockBegin* b); ++ void change_ublock(BlockBegin* b); ++ void negate_cond(); ++ ++ virtual void emit_code(LIR_Assembler* masm); ++ virtual LIR_OpBranch* as_OpBranch() { return this; } ++ virtual void print_instr(outputStream* out) const PRODUCT_RETURN; ++}; ++ + class LIR_OpAllocArray : public LIR_Op { + friend class LIR_OpVisitState; + +@@ -1764,6 +1811,65 @@ class LIR_Op3: public LIR_Op { + virtual void print_instr(outputStream* out) const PRODUCT_RETURN; + }; + ++#ifdef RISCV ++class LIR_Op4: public LIR_Op { ++ friend class LIR_OpVisitState; ++ protected: ++ LIR_Opr _opr1; ++ LIR_Opr _opr2; ++ LIR_Opr _opr3; ++ LIR_Opr _opr4; ++ BasicType _type; ++ LIR_Opr _tmp1; ++ LIR_Opr _tmp2; ++ LIR_Opr _tmp3; ++ LIR_Opr _tmp4; ++ LIR_Opr _tmp5; ++ LIR_Condition _condition; ++ ++ public: ++ LIR_Op4(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr opr3, LIR_Opr opr4, ++ LIR_Opr result, BasicType type) ++ : LIR_Op(code, result, NULL) ++ , _opr1(opr1) ++ , _opr2(opr2) ++ , _opr3(opr3) ++ , _opr4(opr4) ++ , _type(type) ++ , _tmp1(LIR_OprFact::illegalOpr) ++ , _tmp2(LIR_OprFact::illegalOpr) ++ , _tmp3(LIR_OprFact::illegalOpr) ++ , _tmp4(LIR_OprFact::illegalOpr) ++ , _tmp5(LIR_OprFact::illegalOpr) ++ , _condition(condition) { ++ assert(code == lir_cmove, "code check"); ++ assert(type != T_ILLEGAL, "cmove should have type"); ++ } ++ ++ LIR_Opr in_opr1() const { return _opr1; } ++ LIR_Opr in_opr2() const { return _opr2; } ++ LIR_Opr in_opr3() const { return _opr3; } ++ LIR_Opr in_opr4() const { return _opr4; } ++ BasicType type() const { return _type; } ++ LIR_Opr tmp1_opr() const { return _tmp1; } ++ LIR_Opr tmp2_opr() const { return _tmp2; } ++ LIR_Opr tmp3_opr() const { return _tmp3; } ++ LIR_Opr tmp4_opr() const { return _tmp4; } ++ LIR_Opr tmp5_opr() const { return _tmp5; } ++ ++ LIR_Condition condition() const { return _condition; } ++ void set_condition(LIR_Condition condition) { _condition = condition; } ++ ++ void set_in_opr1(LIR_Opr opr) { _opr1 = opr; } ++ void set_in_opr2(LIR_Opr opr) { _opr2 = opr; } ++ void set_in_opr3(LIR_Opr opr) { _opr3 = opr; } ++ void set_in_opr4(LIR_Opr opr) { _opr4 = opr; } ++ virtual void emit_code(LIR_Assembler* masm); ++ virtual LIR_Op4* as_Op4() { return this; } ++ ++ virtual void print_instr(outputStream* out) const PRODUCT_RETURN; ++}; ++#endif + + //-------------------------------- + class LabelObj: public CompilationResourceObj { +@@ -1986,6 +2092,10 @@ class LIR_List: public CompilationResour + const char * _file; + int _line; + #endif ++#ifdef RISCV ++ LIR_Opr _cmp_opr1; ++ LIR_Opr _cmp_opr2; ++#endif + + public: + void append(LIR_Op* op) { +@@ -1998,6 +2108,12 @@ class LIR_List: public CompilationResour + } + #endif // PRODUCT + ++#ifdef RISCV ++ set_cmp_oprs(op); ++ // lir_cmp set cmp oprs only on riscv ++ if (op->code() == lir_cmp) return; ++#endif ++ + _operations.append(op); + + #ifdef ASSERT +@@ -2014,6 +2130,10 @@ class LIR_List: public CompilationResour + void set_file_and_line(const char * file, int line); + #endif + ++#ifdef RISCV ++ void set_cmp_oprs(LIR_Op* op); ++#endif ++ + //---------- accessors --------------- + LIR_OpList* instructions_list() { return &_operations; } + int length() const { return _operations.length(); } +@@ -2133,9 +2253,16 @@ class LIR_List: public CompilationResour + void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info); + void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Address* addr, CodeEmitInfo* info); + ++#ifdef RISCV ++ void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type, ++ LIR_Opr cmp_opr1 = LIR_OprFact::illegalOpr, LIR_Opr cmp_opr2 = LIR_OprFact::illegalOpr) { ++ append(new LIR_Op4(lir_cmove, condition, src1, src2, cmp_opr1, cmp_opr2, dst, type)); ++ } ++#else + void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type) { + append(new LIR_Op2(lir_cmove, condition, src1, src2, dst, type)); + } ++#endif + + void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr); +--- a/src/hotspot/share/c1/c1_LIRAssembler.cpp ++++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp +@@ -691,9 +691,11 @@ void LIR_Assembler::emit_op2(LIR_Op2* op + comp_fl2i(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op); + break; + ++#ifndef RISCV + case lir_cmove: + cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type()); + break; ++#endif + + case lir_shl: + case lir_shr: +@@ -756,6 +758,19 @@ void LIR_Assembler::emit_op2(LIR_Op2* op + } + } + ++#ifdef RISCV ++void LIR_Assembler::emit_op4(LIR_Op4* op) { ++ switch(op->code()) { ++ case lir_cmove: ++ cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type(), op->in_opr3(), op->in_opr4()); ++ break; ++ ++ default: ++ Unimplemented(); ++ break; ++ } ++} ++#endif + + void LIR_Assembler::build_frame() { + _masm->build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); +--- a/src/hotspot/share/c1/c1_LIRAssembler.hpp ++++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp +@@ -186,6 +186,9 @@ class LIR_Assembler: public CompilationR + void emit_op1(LIR_Op1* op); + void emit_op2(LIR_Op2* op); + void emit_op3(LIR_Op3* op); ++#ifdef RISCV ++ void emit_op4(LIR_Op4* op); ++#endif + void emit_opBranch(LIR_OpBranch* op); + void emit_opLabel(LIR_OpLabel* op); + void emit_arraycopy(LIR_OpArrayCopy* op); +@@ -218,8 +221,12 @@ class LIR_Assembler: public CompilationR + void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); + void comp_mem_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); // info set for null exceptions + void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op); ++#ifdef RISCV ++ void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result, BasicType type, ++ LIR_Opr cmp_opr1 = LIR_OprFact::illegalOpr, LIR_Opr cmp_opr2 = LIR_OprFact::illegalOpr); ++#else + void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result, BasicType type); +- ++#endif + void call( LIR_OpJavaCall* op, relocInfo::relocType rtype); + void ic_call( LIR_OpJavaCall* op); + void vtable_call( LIR_OpJavaCall* op); +--- a/src/hotspot/share/c1/c1_LinearScan.cpp ++++ b/src/hotspot/share/c1/c1_LinearScan.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2005, 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 +@@ -1240,8 +1240,13 @@ void LinearScan::add_register_hints(LIR_ + break; + } + case lir_cmove: { ++#ifdef RISCV ++ assert(op->as_Op4() != NULL, "lir_cmove must be LIR_Op4"); ++ LIR_Op4* cmove = (LIR_Op4*)op; ++#else + assert(op->as_Op2() != NULL, "lir_cmove must be LIR_Op2"); + LIR_Op2* cmove = (LIR_Op2*)op; ++#endif + + LIR_Opr move_from = cmove->in_opr1(); + LIR_Opr move_to = cmove->result_opr(); +@@ -3138,6 +3143,9 @@ void LinearScan::do_linear_scan() { + } + } + ++#ifndef RISCV ++ // Disable these optimizations on riscv temporarily, because it does not ++ // work when the comparison operands are bound to branches or cmoves. + { TIME_LINEAR_SCAN(timer_optimize_lir); + + EdgeMoveOptimizer::optimize(ir()->code()); +@@ -3145,6 +3153,7 @@ void LinearScan::do_linear_scan() { + // check that cfg is still correct after optimizations + ir()->verify(); + } ++#endif + + NOT_PRODUCT(print_lir(1, "Before Code Generation", false)); + NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_final)); +@@ -6368,14 +6377,23 @@ void ControlFlowOptimizer::delete_unnece + // There might be a cmove inserted for profiling which depends on the same + // compare. If we change the condition of the respective compare, we have + // to take care of this cmove as well. ++#ifdef RISCV ++ LIR_Op4* prev_cmove = NULL; ++#else + LIR_Op2* prev_cmove = NULL; ++#endif + + for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) { + prev_op = instructions->at(j); + // check for the cmove + if (prev_op->code() == lir_cmove) { ++#ifdef RISCV ++ assert(prev_op->as_Op4() != NULL, "cmove must be of type LIR_Op4"); ++ prev_cmove = (LIR_Op4*)prev_op; ++#else + assert(prev_op->as_Op2() != NULL, "cmove must be of type LIR_Op2"); + prev_cmove = (LIR_Op2*)prev_op; ++#endif + assert(prev_branch->cond() == prev_cmove->condition(), "should be the same"); + } + if (prev_op->code() == lir_cmp) { +--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp ++++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved. ++ * Copyright (c) 2018, 2022, 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 +@@ -35,7 +35,7 @@ + #include "utilities/defaultStream.hpp" + + void ShenandoahArguments::initialize() { +-#if !(defined AARCH64 || defined AMD64 || defined IA32 || defined PPC64) ++#if !(defined AARCH64 || defined AMD64 || defined IA32 || defined PPC64 || defined RISCV64) + vm_exit_during_initialization("Shenandoah GC is not supported on this platform."); + #endif + +--- a/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp ++++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -94,7 +94,11 @@ private: + + public: + LIR_OpZLoadBarrierTest(LIR_Opr opr) : ++#ifdef RISCV ++ LIR_Op(lir_zloadbarrier_test, LIR_OprFact::illegalOpr, NULL), ++#else + LIR_Op(), ++#endif + _opr(opr) {} + + virtual void visit(LIR_OpVisitState* state) { +--- a/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp ++++ b/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp +@@ -102,7 +102,7 @@ inline T JfrBigEndian::read_unaligned(co + inline bool JfrBigEndian::platform_supports_unaligned_reads(void) { + #if defined(IA32) || defined(AMD64) || defined(PPC) || defined(S390) + return true; +-#elif defined(ARM) || defined(AARCH64) ++#elif defined(ARM) || defined(AARCH64) || defined(RISCV) + return false; + #else + #warning "Unconfigured platform" +--- a/src/hotspot/share/opto/regmask.hpp ++++ b/src/hotspot/share/opto/regmask.hpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1997, 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 +@@ -99,7 +99,7 @@ class RegMask { + // requirement is internal to the allocator, and independent of any + // particular platform. + enum { SlotsPerLong = 2, +- SlotsPerVecA = 8, ++ SlotsPerVecA = RISCV_ONLY(4) NOT_RISCV(8), + SlotsPerVecS = 1, + SlotsPerVecD = 2, + SlotsPerVecX = 4, +--- a/src/hotspot/share/runtime/abstract_vm_version.cpp ++++ b/src/hotspot/share/runtime/abstract_vm_version.cpp +@@ -183,7 +183,8 @@ const char* Abstract_VM_Version::jre_rel + AMD64_ONLY("amd64") \ + IA32_ONLY("x86") \ + IA64_ONLY("ia64") \ +- S390_ONLY("s390") ++ S390_ONLY("s390") \ ++ RISCV64_ONLY("riscv64") + #endif // !ZERO + #endif // !CPU + +--- a/src/hotspot/share/runtime/thread.inline.hpp ++++ b/src/hotspot/share/runtime/thread.inline.hpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * +@@ -132,7 +132,7 @@ inline void JavaThread::set_pending_asyn + } + + inline JavaThreadState JavaThread::thread_state() const { +-#if defined(PPC64) || defined (AARCH64) ++#if defined(PPC64) || defined (AARCH64) || defined(RISCV64) + // Use membars when accessing volatile _thread_state. See + // Threads::create_vm() for size checks. + return (JavaThreadState) Atomic::load_acquire((volatile jint*)&_thread_state); +@@ -144,7 +144,7 @@ inline JavaThreadState JavaThread::threa + inline void JavaThread::set_thread_state(JavaThreadState s) { + assert(current_or_null() == NULL || current_or_null() == this, + "state change should only be called by the current thread"); +-#if defined(PPC64) || defined (AARCH64) ++#if defined(PPC64) || defined (AARCH64) || defined(RISCV64) + // Use membars when accessing volatile _thread_state. See + // Threads::create_vm() for size checks. + Atomic::release_store((volatile jint*)&_thread_state, (jint)s); +--- a/src/hotspot/share/utilities/macros.hpp ++++ b/src/hotspot/share/utilities/macros.hpp +@@ -553,6 +553,32 @@ + + #define MACOS_AARCH64_ONLY(x) MACOS_ONLY(AARCH64_ONLY(x)) + ++#if defined(RISCV32) || defined(RISCV64) ++#define RISCV ++#define RISCV_ONLY(code) code ++#define NOT_RISCV(code) ++#else ++#undef RISCV ++#define RISCV_ONLY(code) ++#define NOT_RISCV(code) code ++#endif ++ ++#ifdef RISCV32 ++#define RISCV32_ONLY(code) code ++#define NOT_RISCV32(code) ++#else ++#define RISCV32_ONLY(code) ++#define NOT_RISCV32(code) code ++#endif ++ ++#ifdef RISCV64 ++#define RISCV64_ONLY(code) code ++#define NOT_RISCV64(code) ++#else ++#define RISCV64_ONLY(code) ++#define NOT_RISCV64(code) code ++#endif ++ + #ifdef VM_LITTLE_ENDIAN + #define LITTLE_ENDIAN_ONLY(code) code + #define BIG_ENDIAN_ONLY(code) +--- a/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp ++++ b/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, NTT DATA. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * +@@ -60,6 +60,10 @@ + #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h" + #endif + ++#ifdef riscv64 ++#include "sun_jvm_hotspot_debugger_riscv64_RISCV64ThreadContext.h" ++#endif ++ + class AutoJavaString { + JNIEnv* m_env; + jstring m_str; +@@ -408,7 +412,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_jv + return (err == PS_OK)? array : 0; + } + +-#if defined(i586) || defined(amd64) || defined(ppc64) || defined(ppc64le) || defined(aarch64) ++#if defined(i586) || defined(amd64) || defined(ppc64) || defined(ppc64le) || defined(aarch64) || defined(riscv64) + extern "C" + JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 + (JNIEnv *env, jobject this_obj, jint lwp_id) { +@@ -440,6 +444,9 @@ JNIEXPORT jlongArray JNICALL Java_sun_jv + #ifdef aarch64 + #define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG + #endif ++#ifdef riscv64 ++#define NPRGREG sun_jvm_hotspot_debugger_riscv64_RISCV64ThreadContext_NPRGREG ++#endif + #if defined(ppc64) || defined(ppc64le) + #define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG + #endif +@@ -516,6 +523,44 @@ JNIEXPORT jlongArray JNICALL Java_sun_jv + } + #endif /* aarch64 */ + ++#if defined(riscv64) ++#define REG_INDEX(reg) sun_jvm_hotspot_debugger_riscv64_RISCV64ThreadContext_##reg ++ ++ regs[REG_INDEX(PC)] = gregs.pc; ++ regs[REG_INDEX(LR)] = gregs.ra; ++ regs[REG_INDEX(SP)] = gregs.sp; ++ regs[REG_INDEX(R3)] = gregs.gp; ++ regs[REG_INDEX(R4)] = gregs.tp; ++ regs[REG_INDEX(R5)] = gregs.t0; ++ regs[REG_INDEX(R6)] = gregs.t1; ++ regs[REG_INDEX(R7)] = gregs.t2; ++ regs[REG_INDEX(R8)] = gregs.s0; ++ regs[REG_INDEX(R9)] = gregs.s1; ++ regs[REG_INDEX(R10)] = gregs.a0; ++ regs[REG_INDEX(R11)] = gregs.a1; ++ regs[REG_INDEX(R12)] = gregs.a2; ++ regs[REG_INDEX(R13)] = gregs.a3; ++ regs[REG_INDEX(R14)] = gregs.a4; ++ regs[REG_INDEX(R15)] = gregs.a5; ++ regs[REG_INDEX(R16)] = gregs.a6; ++ regs[REG_INDEX(R17)] = gregs.a7; ++ regs[REG_INDEX(R18)] = gregs.s2; ++ regs[REG_INDEX(R19)] = gregs.s3; ++ regs[REG_INDEX(R20)] = gregs.s4; ++ regs[REG_INDEX(R21)] = gregs.s5; ++ regs[REG_INDEX(R22)] = gregs.s6; ++ regs[REG_INDEX(R23)] = gregs.s7; ++ regs[REG_INDEX(R24)] = gregs.s8; ++ regs[REG_INDEX(R25)] = gregs.s9; ++ regs[REG_INDEX(R26)] = gregs.s10; ++ regs[REG_INDEX(R27)] = gregs.s11; ++ regs[REG_INDEX(R28)] = gregs.t3; ++ regs[REG_INDEX(R29)] = gregs.t4; ++ regs[REG_INDEX(R30)] = gregs.t5; ++ regs[REG_INDEX(R31)] = gregs.t6; ++ ++#endif /* riscv64 */ ++ + #if defined(ppc64) || defined(ppc64le) + #define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg + +--- a/src/jdk.hotspot.agent/linux/native/libsaproc/libproc.h ++++ b/src/jdk.hotspot.agent/linux/native/libsaproc/libproc.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 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 +@@ -43,6 +43,8 @@ + #elif defined(arm) + #include + #define user_regs_struct pt_regs ++#elif defined(riscv64) ++#include + #endif + + // This C bool type must be int for compatibility with Linux calls and +--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java +@@ -36,6 +36,7 @@ import sun.jvm.hotspot.debugger.MachineD + import sun.jvm.hotspot.debugger.MachineDescriptionAMD64; + import sun.jvm.hotspot.debugger.MachineDescriptionPPC64; + import sun.jvm.hotspot.debugger.MachineDescriptionAArch64; ++import sun.jvm.hotspot.debugger.MachineDescriptionRISCV64; + import sun.jvm.hotspot.debugger.MachineDescriptionIntelX86; + import sun.jvm.hotspot.debugger.NoSuchSymbolException; + import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal; +@@ -569,6 +570,8 @@ public class HotSpotAgent { + machDesc = new MachineDescriptionPPC64(); + } else if (cpu.equals("aarch64")) { + machDesc = new MachineDescriptionAArch64(); ++ } else if (cpu.equals("riscv64")) { ++ machDesc = new MachineDescriptionRISCV64(); + } else { + try { + machDesc = (MachineDescription) +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionRISCV64.java +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2003, 2014, 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger; ++ ++public class MachineDescriptionRISCV64 extends MachineDescriptionTwosComplement implements MachineDescription { ++ public long getAddressSize() { ++ return 8; ++ } ++ ++ public boolean isLP64() { ++ return true; ++ } ++ ++ public boolean isBigEndian() { ++ return false; ++ } ++} +--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Red Hat Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * +@@ -33,11 +33,13 @@ import sun.jvm.hotspot.debugger.cdbg.*; + import sun.jvm.hotspot.debugger.x86.*; + import sun.jvm.hotspot.debugger.amd64.*; + import sun.jvm.hotspot.debugger.aarch64.*; ++import sun.jvm.hotspot.debugger.riscv64.*; + import sun.jvm.hotspot.debugger.ppc64.*; + import sun.jvm.hotspot.debugger.linux.x86.*; + import sun.jvm.hotspot.debugger.linux.amd64.*; + import sun.jvm.hotspot.debugger.linux.ppc64.*; + import sun.jvm.hotspot.debugger.linux.aarch64.*; ++import sun.jvm.hotspot.debugger.linux.riscv64.*; + import sun.jvm.hotspot.utilities.*; + + class LinuxCDebugger implements CDebugger { +@@ -105,7 +107,14 @@ class LinuxCDebugger implements CDebugge + Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC); + if (pc == null) return null; + return new LinuxAARCH64CFrame(dbg, fp, pc); +- } else { ++ } else if (cpu.equals("riscv64")) { ++ RISCV64ThreadContext context = (RISCV64ThreadContext) thread.getContext(); ++ Address fp = context.getRegisterAsAddress(RISCV64ThreadContext.FP); ++ if (fp == null) return null; ++ Address pc = context.getRegisterAsAddress(RISCV64ThreadContext.PC); ++ if (pc == null) return null; ++ return new LinuxRISCV64CFrame(dbg, fp, pc); ++ } else { + // Runtime exception thrown by LinuxThreadContextFactory if unknown cpu + ThreadContext context = (ThreadContext) thread.getContext(); + return context.getTopFrame(dbg); +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/riscv64/LinuxRISCV64CFrame.java +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.linux.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.debugger.linux.*; ++import sun.jvm.hotspot.debugger.cdbg.*; ++import sun.jvm.hotspot.debugger.cdbg.basic.*; ++ ++public final class LinuxRISCV64CFrame extends BasicCFrame { ++ private static final int C_FRAME_LINK_OFFSET = -2; ++ private static final int C_FRAME_RETURN_ADDR_OFFSET = -1; ++ ++ public LinuxRISCV64CFrame(LinuxDebugger dbg, Address fp, Address pc) { ++ super(dbg.getCDebugger()); ++ this.fp = fp; ++ this.pc = pc; ++ this.dbg = dbg; ++ } ++ ++ // override base class impl to avoid ELF parsing ++ public ClosestSymbol closestSymbolToPC() { ++ // try native lookup in debugger. ++ return dbg.lookup(dbg.getAddressValue(pc())); ++ } ++ ++ public Address pc() { ++ return pc; ++ } ++ ++ public Address localVariableBase() { ++ return fp; ++ } ++ ++ public CFrame sender(ThreadProxy thread) { ++ RISCV64ThreadContext context = (RISCV64ThreadContext) thread.getContext(); ++ Address rsp = context.getRegisterAsAddress(RISCV64ThreadContext.SP); ++ ++ if ((fp == null) || fp.lessThan(rsp)) { ++ return null; ++ } ++ ++ // Check alignment of fp ++ if (dbg.getAddressValue(fp) % (2 * ADDRESS_SIZE) != 0) { ++ return null; ++ } ++ ++ Address nextFP = fp.getAddressAt(C_FRAME_LINK_OFFSET * ADDRESS_SIZE); ++ if (nextFP == null || nextFP.lessThanOrEqual(fp)) { ++ return null; ++ } ++ Address nextPC = fp.getAddressAt(C_FRAME_RETURN_ADDR_OFFSET * ADDRESS_SIZE); ++ if (nextPC == null) { ++ return null; ++ } ++ return new LinuxRISCV64CFrame(dbg, nextFP, nextPC); ++ } ++ ++ // package/class internals only ++ private static final int ADDRESS_SIZE = 8; ++ private Address pc; ++ private Address sp; ++ private Address fp; ++ private LinuxDebugger dbg; ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/riscv64/LinuxRISCV64ThreadContext.java +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.linux.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.debugger.linux.*; ++ ++public class LinuxRISCV64ThreadContext extends RISCV64ThreadContext { ++ private LinuxDebugger debugger; ++ ++ public LinuxRISCV64ThreadContext(LinuxDebugger debugger) { ++ super(); ++ this.debugger = debugger; ++ } ++ ++ public void setRegisterAsAddress(int index, Address value) { ++ setRegister(index, debugger.getAddressValue(value)); ++ } ++ ++ public Address getRegisterAsAddress(int index) { ++ return debugger.newAddress(getRegister(index)); ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/riscv64/ProcRISCV64Thread.java +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.proc.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.debugger.proc.*; ++import sun.jvm.hotspot.utilities.*; ++ ++public class ProcRISCV64Thread implements ThreadProxy { ++ private ProcDebugger debugger; ++ private int id; ++ ++ public ProcRISCV64Thread(ProcDebugger debugger, Address addr) { ++ this.debugger = debugger; ++ ++ // FIXME: the size here should be configurable. However, making it ++ // so would produce a dependency on the "types" package from the ++ // debugger package, which is not desired. ++ this.id = (int) addr.getCIntegerAt(0, 4, true); ++ } ++ ++ public ProcRISCV64Thread(ProcDebugger debugger, long id) { ++ this.debugger = debugger; ++ this.id = (int) id; ++ } ++ ++ public ThreadContext getContext() throws IllegalThreadStateException { ++ ProcRISCV64ThreadContext context = new ProcRISCV64ThreadContext(debugger); ++ long[] regs = debugger.getThreadIntegerRegisterSet(id); ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(regs.length == RISCV64ThreadContext.NPRGREG, "size mismatch"); ++ } ++ for (int i = 0; i < regs.length; i++) { ++ context.setRegister(i, regs[i]); ++ } ++ return context; ++ } ++ ++ public boolean canSetContext() throws DebuggerException { ++ return false; ++ } ++ ++ public void setContext(ThreadContext context) ++ throws IllegalThreadStateException, DebuggerException { ++ throw new DebuggerException("Unimplemented"); ++ } ++ ++ public String toString() { ++ return "t@" + id; ++ } ++ ++ public boolean equals(Object obj) { ++ if ((obj == null) || !(obj instanceof ProcRISCV64Thread)) { ++ return false; ++ } ++ ++ return (((ProcRISCV64Thread) obj).id == id); ++ } ++ ++ public int hashCode() { ++ return id; ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/riscv64/ProcRISCV64ThreadContext.java +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.proc.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.debugger.proc.*; ++ ++public class ProcRISCV64ThreadContext extends RISCV64ThreadContext { ++ private ProcDebugger debugger; ++ ++ public ProcRISCV64ThreadContext(ProcDebugger debugger) { ++ super(); ++ this.debugger = debugger; ++ } ++ ++ public void setRegisterAsAddress(int index, Address value) { ++ setRegister(index, debugger.getAddressValue(value)); ++ } ++ ++ public Address getRegisterAsAddress(int index) { ++ return debugger.newAddress(getRegister(index)); ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/riscv64/ProcRISCV64ThreadFactory.java +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.proc.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.proc.*; ++ ++public class ProcRISCV64ThreadFactory implements ProcThreadFactory { ++ private ProcDebugger debugger; ++ ++ public ProcRISCV64ThreadFactory(ProcDebugger debugger) { ++ this.debugger = debugger; ++ } ++ ++ public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { ++ return new ProcRISCV64Thread(debugger, threadIdentifierAddr); ++ } ++ ++ public ThreadProxy createThreadWrapper(long id) { ++ return new ProcRISCV64Thread(debugger, id); ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/riscv64/RemoteRISCV64Thread.java +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.remote.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.debugger.remote.*; ++import sun.jvm.hotspot.utilities.*; ++ ++public class RemoteRISCV64Thread extends RemoteThread { ++ public RemoteRISCV64Thread(RemoteDebuggerClient debugger, Address addr) { ++ super(debugger, addr); ++ } ++ ++ public RemoteRISCV64Thread(RemoteDebuggerClient debugger, long id) { ++ super(debugger, id); ++ } ++ ++ public ThreadContext getContext() throws IllegalThreadStateException { ++ RemoteRISCV64ThreadContext context = new RemoteRISCV64ThreadContext(debugger); ++ long[] regs = (addr != null)? debugger.getThreadIntegerRegisterSet(addr) : ++ debugger.getThreadIntegerRegisterSet(id); ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(regs.length == RISCV64ThreadContext.NPRGREG, "size of register set must match"); ++ } ++ for (int i = 0; i < regs.length; i++) { ++ context.setRegister(i, regs[i]); ++ } ++ return context; ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/riscv64/RemoteRISCV64ThreadContext.java +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.remote.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.debugger.remote.*; ++ ++public class RemoteRISCV64ThreadContext extends RISCV64ThreadContext { ++ private RemoteDebuggerClient debugger; ++ ++ public RemoteRISCV64ThreadContext(RemoteDebuggerClient debugger) { ++ super(); ++ this.debugger = debugger; ++ } ++ ++ public void setRegisterAsAddress(int index, Address value) { ++ setRegister(index, debugger.getAddressValue(value)); ++ } ++ ++ public Address getRegisterAsAddress(int index) { ++ return debugger.newAddress(getRegister(index)); ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/riscv64/RemoteRISCV64ThreadFactory.java +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.remote.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.remote.*; ++ ++public class RemoteRISCV64ThreadFactory implements RemoteThreadFactory { ++ private RemoteDebuggerClient debugger; ++ ++ public RemoteRISCV64ThreadFactory(RemoteDebuggerClient debugger) { ++ this.debugger = debugger; ++ } ++ ++ public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { ++ return new RemoteRISCV64Thread(debugger, threadIdentifierAddr); ++ } ++ ++ public ThreadProxy createThreadWrapper(long id) { ++ return new RemoteRISCV64Thread(debugger, id); ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/riscv/RISCV64ThreadContext.java +@@ -0,0 +1,172 @@ ++/* ++ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.debugger.riscv64; ++ ++import java.lang.annotation.Native; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.cdbg.*; ++ ++/** Specifies the thread context on riscv64 platforms; only a sub-portion ++ * of the context is guaranteed to be present on all operating ++ * systems. */ ++ ++public abstract class RISCV64ThreadContext implements ThreadContext { ++ // Taken from /usr/include/asm/sigcontext.h on Linux/RISCV64. ++ ++ // /* ++ // * Signal context structure - contains all info to do with the state ++ // * before the signal handler was invoked. ++ // */ ++ // struct sigcontext { ++ // struct user_regs_struct sc_regs; ++ // union __riscv_fp_state sc_fpregs; ++ // }; ++ // ++ // struct user_regs_struct { ++ // unsigned long pc; ++ // unsigned long ra; ++ // unsigned long sp; ++ // unsigned long gp; ++ // unsigned long tp; ++ // unsigned long t0; ++ // unsigned long t1; ++ // unsigned long t2; ++ // unsigned long s0; ++ // unsigned long s1; ++ // unsigned long a0; ++ // unsigned long a1; ++ // unsigned long a2; ++ // unsigned long a3; ++ // unsigned long a4; ++ // unsigned long a5; ++ // unsigned long a6; ++ // unsigned long a7; ++ // unsigned long s2; ++ // unsigned long s3; ++ // unsigned long s4; ++ // unsigned long s5; ++ // unsigned long s6; ++ // unsigned long s7; ++ // unsigned long s8; ++ // unsigned long s9; ++ // unsigned long s10; ++ // unsigned long s11; ++ // unsigned long t3; ++ // unsigned long t4; ++ // unsigned long t5; ++ // unsigned long t6; ++ // }; ++ ++ // NOTE: the indices for the various registers must be maintained as ++ // listed across various operating systems. However, only a small ++ // subset of the registers' values are guaranteed to be present (and ++ // must be present for the SA's stack walking to work) ++ ++ // One instance of the Native annotation is enough to trigger header generation ++ // for this file. ++ @Native ++ public static final int R0 = 0; ++ public static final int R1 = 1; ++ public static final int R2 = 2; ++ public static final int R3 = 3; ++ public static final int R4 = 4; ++ public static final int R5 = 5; ++ public static final int R6 = 6; ++ public static final int R7 = 7; ++ public static final int R8 = 8; ++ public static final int R9 = 9; ++ public static final int R10 = 10; ++ public static final int R11 = 11; ++ public static final int R12 = 12; ++ public static final int R13 = 13; ++ public static final int R14 = 14; ++ public static final int R15 = 15; ++ public static final int R16 = 16; ++ public static final int R17 = 17; ++ public static final int R18 = 18; ++ public static final int R19 = 19; ++ public static final int R20 = 20; ++ public static final int R21 = 21; ++ public static final int R22 = 22; ++ public static final int R23 = 23; ++ public static final int R24 = 24; ++ public static final int R25 = 25; ++ public static final int R26 = 26; ++ public static final int R27 = 27; ++ public static final int R28 = 28; ++ public static final int R29 = 29; ++ public static final int R30 = 30; ++ public static final int R31 = 31; ++ ++ public static final int NPRGREG = 32; ++ ++ public static final int PC = R0; ++ public static final int LR = R1; ++ public static final int SP = R2; ++ public static final int FP = R8; ++ ++ private long[] data; ++ ++ public RISCV64ThreadContext() { ++ data = new long[NPRGREG]; ++ } ++ ++ public int getNumRegisters() { ++ return NPRGREG; ++ } ++ ++ public String getRegisterName(int index) { ++ switch (index) { ++ case LR: return "lr"; ++ case SP: return "sp"; ++ case PC: return "pc"; ++ default: ++ return "r" + index; ++ } ++ } ++ ++ public void setRegister(int index, long value) { ++ data[index] = value; ++ } ++ ++ public long getRegister(int index) { ++ return data[index]; ++ } ++ ++ public CFrame getTopFrame(Debugger dbg) { ++ return null; ++ } ++ ++ /** This can't be implemented in this class since we would have to ++ * tie the implementation to, for example, the debugging system */ ++ public abstract void setRegisterAsAddress(int index, Address value); ++ ++ /** This can't be implemented in this class since we would have to ++ * tie the implementation to, for example, the debugging system */ ++ public abstract Address getRegisterAsAddress(int index); ++} +--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -34,6 +34,7 @@ import sun.jvm.hotspot.runtime.win32_aar + import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess; ++import sun.jvm.hotspot.runtime.linux_riscv64.LinuxRISCV64JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess; +@@ -113,6 +114,8 @@ public class Threads { + access = new LinuxPPC64JavaThreadPDAccess(); + } else if (cpu.equals("aarch64")) { + access = new LinuxAARCH64JavaThreadPDAccess(); ++ } else if (cpu.equals("riscv64")) { ++ access = new LinuxRISCV64JavaThreadPDAccess(); + } else { + try { + access = (JavaThreadPDAccess) +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/linux_riscv64/LinuxRISCV64JavaThreadPDAccess.java +@@ -0,0 +1,134 @@ ++/* ++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.runtime.linux_riscv64; ++ ++import java.io.*; ++import java.util.*; ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.runtime.*; ++import sun.jvm.hotspot.runtime.riscv64.*; ++import sun.jvm.hotspot.types.*; ++import sun.jvm.hotspot.utilities.*; ++import sun.jvm.hotspot.utilities.Observable; ++import sun.jvm.hotspot.utilities.Observer; ++ ++public class LinuxRISCV64JavaThreadPDAccess implements JavaThreadPDAccess { ++ private static AddressField lastJavaFPField; ++ private static AddressField osThreadField; ++ ++ // Field from OSThread ++ private static CIntegerField osThreadThreadIDField; ++ ++ // This is currently unneeded but is being kept in case we change ++ // the currentFrameGuess algorithm ++ private static final long GUESS_SCAN_RANGE = 128 * 1024; ++ ++ static { ++ VM.registerVMInitializedObserver(new Observer() { ++ public void update(Observable o, Object data) { ++ initialize(VM.getVM().getTypeDataBase()); ++ } ++ }); ++ } ++ ++ private static synchronized void initialize(TypeDataBase db) { ++ Type type = db.lookupType("JavaThread"); ++ osThreadField = type.getAddressField("_osthread"); ++ ++ Type anchorType = db.lookupType("JavaFrameAnchor"); ++ lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); ++ ++ Type osThreadType = db.lookupType("OSThread"); ++ osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); ++ } ++ ++ public Address getLastJavaFP(Address addr) { ++ return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset())); ++ } ++ ++ public Address getLastJavaPC(Address addr) { ++ return null; ++ } ++ ++ public Address getBaseOfStackPointer(Address addr) { ++ return null; ++ } ++ ++ public Frame getLastFramePD(JavaThread thread, Address addr) { ++ Address fp = thread.getLastJavaFP(); ++ if (fp == null) { ++ return null; // no information ++ } ++ return new RISCV64Frame(thread.getLastJavaSP(), fp); ++ } ++ ++ public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { ++ return new RISCV64RegisterMap(thread, updateMap); ++ } ++ ++ public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { ++ ThreadProxy t = getThreadProxy(addr); ++ RISCV64ThreadContext context = (RISCV64ThreadContext) t.getContext(); ++ RISCV64CurrentFrameGuess guesser = new RISCV64CurrentFrameGuess(context, thread); ++ if (!guesser.run(GUESS_SCAN_RANGE)) { ++ return null; ++ } ++ if (guesser.getPC() == null) { ++ return new RISCV64Frame(guesser.getSP(), guesser.getFP()); ++ } else { ++ return new RISCV64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); ++ } ++ } ++ ++ public void printThreadIDOn(Address addr, PrintStream tty) { ++ tty.print(getThreadProxy(addr)); ++ } ++ ++ public void printInfoOn(Address threadAddr, PrintStream tty) { ++ tty.print("Thread id: "); ++ printThreadIDOn(threadAddr, tty); ++ } ++ ++ public Address getLastSP(Address addr) { ++ ThreadProxy t = getThreadProxy(addr); ++ RISCV64ThreadContext context = (RISCV64ThreadContext) t.getContext(); ++ return context.getRegisterAsAddress(RISCV64ThreadContext.SP); ++ } ++ ++ public ThreadProxy getThreadProxy(Address addr) { ++ // Addr is the address of the JavaThread. ++ // Fetch the OSThread (for now and for simplicity, not making a ++ // separate "OSThread" class in this package) ++ Address osThreadAddr = osThreadField.getValue(addr); ++ // Get the address of the _thread_id from the OSThread ++ Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); ++ ++ JVMDebugger debugger = VM.getVM().getDebugger(); ++ return debugger.getThreadForIdentifierAddress(threadIdAddr); ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64CurrentFrameGuess.java +@@ -0,0 +1,223 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 2019, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.runtime.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.debugger.riscv64.*; ++import sun.jvm.hotspot.code.*; ++import sun.jvm.hotspot.interpreter.*; ++import sun.jvm.hotspot.runtime.*; ++import sun.jvm.hotspot.runtime.riscv64.*; ++ ++/**

Should be able to be used on all riscv64 platforms we support ++ (Linux/riscv64) to implement JavaThread's "currentFrameGuess()" ++ functionality. Input is an RISCV64ThreadContext; output is SP, FP, ++ and PC for an RISCV64Frame. Instantiation of the RISCV64Frame is ++ left to the caller, since we may need to subclass RISCV64Frame to ++ support signal handler frames on Unix platforms.

++ ++

Algorithm is to walk up the stack within a given range (say, ++ 512K at most) looking for a plausible PC and SP for a Java frame, ++ also considering those coming in from the context. If we find a PC ++ that belongs to the VM (i.e., in generated code like the ++ interpreter or CodeCache) then we try to find an associated FP. ++ We repeat this until we either find a complete frame or run out of ++ stack to look at.

*/ ++ ++public class RISCV64CurrentFrameGuess { ++ private RISCV64ThreadContext context; ++ private JavaThread thread; ++ private Address spFound; ++ private Address fpFound; ++ private Address pcFound; ++ ++ private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.riscv64.RISCV64Frame.DEBUG") ++ != null; ++ ++ public RISCV64CurrentFrameGuess(RISCV64ThreadContext context, ++ JavaThread thread) { ++ this.context = context; ++ this.thread = thread; ++ } ++ ++ /** Returns false if not able to find a frame within a reasonable range. */ ++ public boolean run(long regionInBytesToSearch) { ++ Address sp = context.getRegisterAsAddress(RISCV64ThreadContext.SP); ++ Address pc = context.getRegisterAsAddress(RISCV64ThreadContext.PC); ++ Address fp = context.getRegisterAsAddress(RISCV64ThreadContext.FP); ++ if (sp == null) { ++ // Bail out if no last java frame either ++ if (thread.getLastJavaSP() != null) { ++ setValues(thread.getLastJavaSP(), thread.getLastJavaFP(), null); ++ return true; ++ } ++ return false; ++ } ++ Address end = sp.addOffsetTo(regionInBytesToSearch); ++ VM vm = VM.getVM(); ++ ++ setValues(null, null, null); // Assume we're not going to find anything ++ ++ if (vm.isJavaPCDbg(pc)) { ++ if (vm.isClientCompiler()) { ++ // If the topmost frame is a Java frame, we are (pretty much) ++ // guaranteed to have a viable FP. We should be more robust ++ // than this (we have the potential for losing entire threads' ++ // stack traces) but need to see how much work we really have ++ // to do here. Searching the stack for an (SP, FP) pair is ++ // hard since it's easy to misinterpret inter-frame stack ++ // pointers as base-of-frame pointers; we also don't know the ++ // sizes of C1 frames (not registered in the nmethod) so can't ++ // derive them from SP. ++ ++ setValues(sp, fp, pc); ++ return true; ++ } else { ++ if (vm.getInterpreter().contains(pc)) { ++ if (DEBUG) { ++ System.out.println("CurrentFrameGuess: choosing interpreter frame: sp = " + ++ sp + ", fp = " + fp + ", pc = " + pc); ++ } ++ setValues(sp, fp, pc); ++ return true; ++ } ++ ++ // For the server compiler, FP is not guaranteed to be valid ++ // for compiled code. In addition, an earlier attempt at a ++ // non-searching algorithm (see below) failed because the ++ // stack pointer from the thread context was pointing ++ // (considerably) beyond the ostensible end of the stack, into ++ // garbage; walking from the topmost frame back caused a crash. ++ // ++ // This algorithm takes the current PC as a given and tries to ++ // find the correct corresponding SP by walking up the stack ++ // and repeatedly performing stackwalks (very inefficient). ++ // ++ // FIXME: there is something wrong with stackwalking across ++ // adapter frames...this is likely to be the root cause of the ++ // failure with the simpler algorithm below. ++ ++ for (long offset = 0; ++ offset < regionInBytesToSearch; ++ offset += vm.getAddressSize()) { ++ try { ++ Address curSP = sp.addOffsetTo(offset); ++ Frame frame = new RISCV64Frame(curSP, null, pc); ++ RegisterMap map = thread.newRegisterMap(false); ++ while (frame != null) { ++ if (frame.isEntryFrame() && frame.entryFrameIsFirst()) { ++ // We were able to traverse all the way to the ++ // bottommost Java frame. ++ // This sp looks good. Keep it. ++ if (DEBUG) { ++ System.out.println("CurrentFrameGuess: Choosing sp = " + curSP + ", pc = " + pc); ++ } ++ setValues(curSP, null, pc); ++ return true; ++ } ++ frame = frame.sender(map); ++ } ++ } catch (Exception e) { ++ if (DEBUG) { ++ System.out.println("CurrentFrameGuess: Exception " + e + " at offset " + offset); ++ } ++ // Bad SP. Try another. ++ } ++ } ++ ++ // Were not able to find a plausible SP to go with this PC. ++ // Bail out. ++ return false; ++ } ++ } else { ++ // If the current program counter was not known to us as a Java ++ // PC, we currently assume that we are in the run-time system ++ // and attempt to look to thread-local storage for saved SP and ++ // FP. Note that if these are null (because we were, in fact, ++ // in Java code, i.e., vtable stubs or similar, and the SA ++ // didn't have enough insight into the target VM to understand ++ // that) then we are going to lose the entire stack trace for ++ // the thread, which is sub-optimal. FIXME. ++ ++ if (DEBUG) { ++ System.out.println("CurrentFrameGuess: choosing last Java frame: sp = " + ++ thread.getLastJavaSP() + ", fp = " + thread.getLastJavaFP()); ++ } ++ if (thread.getLastJavaSP() == null) { ++ return false; // No known Java frames on stack ++ } ++ ++ // The runtime has a nasty habit of not saving fp in the frame ++ // anchor, leaving us to grovel about in the stack to find a ++ // plausible address. Fortunately, this only happens in ++ // compiled code; there we always have a valid PC, and we always ++ // push LR and FP onto the stack as a pair, with FP at the lower ++ // address. ++ pc = thread.getLastJavaPC(); ++ fp = thread.getLastJavaFP(); ++ sp = thread.getLastJavaSP(); ++ ++ if (fp == null) { ++ CodeCache cc = vm.getCodeCache(); ++ if (cc.contains(pc)) { ++ CodeBlob cb = cc.findBlob(pc); ++ if (DEBUG) { ++ System.out.println("FP is null. Found blob frame size " + cb.getFrameSize()); ++ } ++ // See if we can derive a frame pointer from SP and PC ++ long link_offset = cb.getFrameSize() - 2 * VM.getVM().getAddressSize(); ++ if (link_offset >= 0) { ++ fp = sp.addOffsetTo(link_offset); ++ } ++ } ++ } ++ ++ // We found a PC in the frame anchor. Check that it's plausible, and ++ // if it is, use it. ++ if (vm.isJavaPCDbg(pc)) { ++ setValues(sp, fp, pc); ++ } else { ++ setValues(sp, fp, null); ++ } ++ ++ return true; ++ } ++ } ++ ++ public Address getSP() { return spFound; } ++ public Address getFP() { return fpFound; } ++ /** May be null if getting values from thread-local storage; take ++ care to call the correct RISCV64Frame constructor to recover this if ++ necessary */ ++ public Address getPC() { return pcFound; } ++ ++ private void setValues(Address sp, Address fp, Address pc) { ++ spFound = sp; ++ fpFound = fp; ++ pcFound = pc; ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64Frame.java +@@ -0,0 +1,556 @@ ++/* ++ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 2019, Red Hat Inc. ++ * Copyright (c) 2021, 2022, 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.runtime.riscv64; ++ ++import java.util.*; ++import sun.jvm.hotspot.code.*; ++import sun.jvm.hotspot.compiler.*; ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.oops.*; ++import sun.jvm.hotspot.runtime.*; ++import sun.jvm.hotspot.types.*; ++import sun.jvm.hotspot.utilities.*; ++import sun.jvm.hotspot.utilities.Observable; ++import sun.jvm.hotspot.utilities.Observer; ++ ++/** Specialization of and implementation of abstract methods of the ++ Frame class for the riscv64 family of CPUs. */ ++ ++public class RISCV64Frame extends Frame { ++ private static final boolean DEBUG; ++ static { ++ DEBUG = System.getProperty("sun.jvm.hotspot.runtime.RISCV64.RISCV64Frame.DEBUG") != null; ++ } ++ ++ // Java frames ++ private static final int LINK_OFFSET = -2; ++ private static final int RETURN_ADDR_OFFSET = -1; ++ private static final int SENDER_SP_OFFSET = 0; ++ ++ // Interpreter frames ++ private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -3; ++ private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1; ++ private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET - 1; ++ private static int INTERPRETER_FRAME_MDX_OFFSET; // Non-core builds only ++ private static int INTERPRETER_FRAME_PADDING_OFFSET; ++ private static int INTERPRETER_FRAME_MIRROR_OFFSET; ++ private static int INTERPRETER_FRAME_CACHE_OFFSET; ++ private static int INTERPRETER_FRAME_LOCALS_OFFSET; ++ private static int INTERPRETER_FRAME_BCX_OFFSET; ++ private static int INTERPRETER_FRAME_INITIAL_SP_OFFSET; ++ private static int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET; ++ private static int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET; ++ ++ // Entry frames ++ private static int ENTRY_FRAME_CALL_WRAPPER_OFFSET = -10; ++ ++ // Native frames ++ private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET = 2; ++ ++ private static VMReg fp = new VMReg(8); ++ ++ static { ++ VM.registerVMInitializedObserver(new Observer() { ++ public void update(Observable o, Object data) { ++ initialize(VM.getVM().getTypeDataBase()); ++ } ++ }); ++ } ++ ++ private static synchronized void initialize(TypeDataBase db) { ++ INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1; ++ INTERPRETER_FRAME_PADDING_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1; ++ INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_PADDING_OFFSET - 1; ++ INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1; ++ INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1; ++ INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1; ++ INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; ++ INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; ++ INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; ++ } ++ ++ ++ // an additional field beyond sp and pc: ++ Address raw_fp; // frame pointer ++ private Address raw_unextendedSP; ++ ++ private RISCV64Frame() { ++ } ++ ++ private void adjustForDeopt() { ++ if ( pc != null) { ++ // Look for a deopt pc and if it is deopted convert to original pc ++ CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc); ++ if (cb != null && cb.isJavaMethod()) { ++ NMethod nm = (NMethod) cb; ++ if (pc.equals(nm.deoptHandlerBegin())) { ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(this.getUnextendedSP() != null, "null SP in Java frame"); ++ } ++ // adjust pc if frame is deoptimized. ++ pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset()); ++ deoptimized = true; ++ } ++ } ++ } ++ } ++ ++ public RISCV64Frame(Address raw_sp, Address raw_fp, Address pc) { ++ this.raw_sp = raw_sp; ++ this.raw_unextendedSP = raw_sp; ++ this.raw_fp = raw_fp; ++ this.pc = pc; ++ adjustUnextendedSP(); ++ ++ // Frame must be fully constructed before this call ++ adjustForDeopt(); ++ ++ if (DEBUG) { ++ System.out.println("RISCV64Frame(sp, fp, pc): " + this); ++ dumpStack(); ++ } ++ } ++ ++ public RISCV64Frame(Address raw_sp, Address raw_fp) { ++ this.raw_sp = raw_sp; ++ this.raw_unextendedSP = raw_sp; ++ this.raw_fp = raw_fp; ++ ++ // We cannot assume SP[-1] always contains a valid return PC (e.g. if ++ // the callee is a C/C++ compiled frame). If the PC is not known to ++ // Java then this.pc is null. ++ Address savedPC = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize()); ++ if (VM.getVM().isJavaPCDbg(savedPC)) { ++ this.pc = savedPC; ++ } ++ ++ adjustUnextendedSP(); ++ ++ // Frame must be fully constructed before this call ++ adjustForDeopt(); ++ ++ if (DEBUG) { ++ System.out.println("RISCV64Frame(sp, fp): " + this); ++ dumpStack(); ++ } ++ } ++ ++ public RISCV64Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) { ++ this.raw_sp = raw_sp; ++ this.raw_unextendedSP = raw_unextendedSp; ++ this.raw_fp = raw_fp; ++ this.pc = pc; ++ adjustUnextendedSP(); ++ ++ // Frame must be fully constructed before this call ++ adjustForDeopt(); ++ ++ if (DEBUG) { ++ System.out.println("RISCV64Frame(sp, unextendedSP, fp, pc): " + this); ++ dumpStack(); ++ } ++ ++ } ++ ++ public Object clone() { ++ RISCV64Frame frame = new RISCV64Frame(); ++ frame.raw_sp = raw_sp; ++ frame.raw_unextendedSP = raw_unextendedSP; ++ frame.raw_fp = raw_fp; ++ frame.pc = pc; ++ frame.deoptimized = deoptimized; ++ return frame; ++ } ++ ++ public boolean equals(Object arg) { ++ if (arg == null) { ++ return false; ++ } ++ ++ if (!(arg instanceof RISCV64Frame)) { ++ return false; ++ } ++ ++ RISCV64Frame other = (RISCV64Frame) arg; ++ ++ return (AddressOps.equal(getSP(), other.getSP()) && ++ AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) && ++ AddressOps.equal(getFP(), other.getFP()) && ++ AddressOps.equal(getPC(), other.getPC())); ++ } ++ ++ public int hashCode() { ++ if (raw_sp == null) { ++ return 0; ++ } ++ ++ return raw_sp.hashCode(); ++ } ++ ++ public String toString() { ++ return "sp: " + (getSP() == null? "null" : getSP().toString()) + ++ ", unextendedSP: " + (getUnextendedSP() == null? "null" : getUnextendedSP().toString()) + ++ ", fp: " + (getFP() == null? "null" : getFP().toString()) + ++ ", pc: " + (pc == null? "null" : pc.toString()); ++ } ++ ++ // accessors for the instance variables ++ public Address getFP() { return raw_fp; } ++ public Address getSP() { return raw_sp; } ++ public Address getID() { return raw_sp; } ++ ++ // FIXME: not implemented yet ++ public boolean isSignalHandlerFrameDbg() { return false; } ++ public int getSignalNumberDbg() { return 0; } ++ public String getSignalNameDbg() { return null; } ++ ++ public boolean isInterpretedFrameValid() { ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(isInterpretedFrame(), "Not an interpreted frame"); ++ } ++ ++ // These are reasonable sanity checks ++ if (getFP() == null || getFP().andWithMask(0x3) != null) { ++ return false; ++ } ++ ++ if (getSP() == null || getSP().andWithMask(0x3) != null) { ++ return false; ++ } ++ ++ if (getFP().addOffsetTo(INTERPRETER_FRAME_INITIAL_SP_OFFSET * VM.getVM().getAddressSize()).lessThan(getSP())) { ++ return false; ++ } ++ ++ // These are hacks to keep us out of trouble. ++ // The problem with these is that they mask other problems ++ if (getFP().lessThanOrEqual(getSP())) { ++ // this attempts to deal with unsigned comparison above ++ return false; ++ } ++ ++ if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) { ++ // stack frames shouldn't be large. ++ return false; ++ } ++ ++ return true; ++ } ++ ++ public Frame sender(RegisterMap regMap, CodeBlob cb) { ++ RISCV64RegisterMap map = (RISCV64RegisterMap) regMap; ++ ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(map != null, "map must be set"); ++ } ++ ++ // Default is we done have to follow them. The sender_for_xxx will ++ // update it accordingly ++ map.setIncludeArgumentOops(false); ++ ++ if (isEntryFrame()) return senderForEntryFrame(map); ++ if (isInterpretedFrame()) return senderForInterpreterFrame(map); ++ ++ if(cb == null) { ++ cb = VM.getVM().getCodeCache().findBlob(getPC()); ++ } else { ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same"); ++ } ++ } ++ ++ if (cb != null) { ++ return senderForCompiledFrame(map, cb); ++ } ++ ++ // Must be native-compiled frame, i.e. the marshaling code for native ++ // methods that exists in the core system. ++ return new RISCV64Frame(getSenderSP(), getLink(), getSenderPC()); ++ } ++ ++ private Frame senderForEntryFrame(RISCV64RegisterMap map) { ++ if (DEBUG) { ++ System.out.println("senderForEntryFrame"); ++ } ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(map != null, "map must be set"); ++ } ++ // Java frame called from C; skip all C frames and return top C ++ // frame of that chunk as the sender ++ RISCV64JavaCallWrapper jcw = (RISCV64JavaCallWrapper) getEntryFrameCallWrapper(); ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero"); ++ Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack"); ++ } ++ RISCV64Frame fr; ++ if (jcw.getLastJavaPC() != null) { ++ fr = new RISCV64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC()); ++ } else { ++ fr = new RISCV64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP()); ++ } ++ map.clear(); ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(map.getIncludeArgumentOops(), "should be set by clear"); ++ } ++ return fr; ++ } ++ ++ //------------------------------------------------------------------------------ ++ // frame::adjust_unextended_sp ++ private void adjustUnextendedSP() { ++ // If we are returning to a compiled MethodHandle call site, the ++ // saved_fp will in fact be a saved value of the unextended SP. The ++ // simplest way to tell whether we are returning to such a call site ++ // is as follows: ++ ++ CodeBlob cb = cb(); ++ NMethod senderNm = (cb == null) ? null : cb.asNMethodOrNull(); ++ if (senderNm != null) { ++ // If the sender PC is a deoptimization point, get the original ++ // PC. For MethodHandle call site the unextended_sp is stored in ++ // saved_fp. ++ if (senderNm.isDeoptMhEntry(getPC())) { ++ raw_unextendedSP = getFP(); ++ } ++ else if (senderNm.isDeoptEntry(getPC())) { ++ } ++ else if (senderNm.isMethodHandleReturn(getPC())) { ++ raw_unextendedSP = getFP(); ++ } ++ } ++ } ++ ++ private Frame senderForInterpreterFrame(RISCV64RegisterMap map) { ++ if (DEBUG) { ++ System.out.println("senderForInterpreterFrame"); ++ } ++ Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); ++ Address sp = addressOfStackSlot(SENDER_SP_OFFSET); ++ // We do not need to update the callee-save register mapping because above ++ // us is either another interpreter frame or a converter-frame, but never ++ // directly a compiled frame. ++ // 11/24/04 SFG. With the removal of adapter frames this is no longer true. ++ // However c2 no longer uses callee save register for java calls so there ++ // are no callee register to find. ++ ++ if (map.getUpdateMap()) ++ updateMapWithSavedLink(map, addressOfStackSlot(LINK_OFFSET)); ++ ++ return new RISCV64Frame(sp, unextendedSP, getLink(), getSenderPC()); ++ } ++ ++ private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) { ++ map.setLocation(fp, savedFPAddr); ++ } ++ ++ private Frame senderForCompiledFrame(RISCV64RegisterMap map, CodeBlob cb) { ++ if (DEBUG) { ++ System.out.println("senderForCompiledFrame"); ++ } ++ ++ // ++ // NOTE: some of this code is (unfortunately) duplicated RISCV64CurrentFrameGuess ++ // ++ ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(map != null, "map must be set"); ++ } ++ ++ // frame owned by optimizing compiler ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size"); ++ } ++ Address senderSP = getUnextendedSP().addOffsetTo(cb.getFrameSize()); ++ ++ // The return_address is always the word on the stack ++ Address senderPC = senderSP.getAddressAt(-1 * VM.getVM().getAddressSize()); ++ ++ // This is the saved value of FP which may or may not really be an FP. ++ // It is only an FP if the sender is an interpreter frame. ++ Address savedFPAddr = senderSP.addOffsetTo(-2 * VM.getVM().getAddressSize()); ++ ++ if (map.getUpdateMap()) { ++ // Tell GC to use argument oopmaps for some runtime stubs that need it. ++ // For C1, the runtime stub might not have oop maps, so set this flag ++ // outside of update_register_map. ++ map.setIncludeArgumentOops(cb.callerMustGCArguments()); ++ ++ if (cb.getOopMaps() != null) { ++ ImmutableOopMapSet.updateRegisterMap(this, cb, map, true); ++ } ++ ++ // Since the prolog does the save and restore of FP there is no oopmap ++ // for it so we must fill in its location as if there was an oopmap entry ++ // since if our caller was compiled code there could be live jvm state in it. ++ updateMapWithSavedLink(map, savedFPAddr); ++ } ++ ++ return new RISCV64Frame(senderSP, savedFPAddr.getAddressAt(0), senderPC); ++ } ++ ++ protected boolean hasSenderPD() { ++ return true; ++ } ++ ++ public long frameSize() { ++ return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize()); ++ } ++ ++ public Address getLink() { ++ try { ++ if (DEBUG) { ++ System.out.println("Reading link at " + addressOfStackSlot(LINK_OFFSET) ++ + " = " + addressOfStackSlot(LINK_OFFSET).getAddressAt(0)); ++ } ++ return addressOfStackSlot(LINK_OFFSET).getAddressAt(0); ++ } catch (Exception e) { ++ if (DEBUG) ++ System.out.println("Returning null"); ++ return null; ++ } ++ } ++ ++ public Address getUnextendedSP() { return raw_unextendedSP; } ++ ++ // Return address: ++ public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); } ++ public Address getSenderPC() { return getSenderPCAddr().getAddressAt(0); } ++ ++ // return address of param, zero origin index. ++ public Address getNativeParamAddr(int idx) { ++ return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx); ++ } ++ ++ public Address getSenderSP() { return addressOfStackSlot(SENDER_SP_OFFSET); } ++ ++ public Address addressOfInterpreterFrameLocals() { ++ return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET); ++ } ++ ++ private Address addressOfInterpreterFrameBCX() { ++ return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET); ++ } ++ ++ public int getInterpreterFrameBCI() { ++ // FIXME: this is not atomic with respect to GC and is unsuitable ++ // for use in a non-debugging, or reflective, system. Need to ++ // figure out how to express this. ++ Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0); ++ Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0); ++ Method method = (Method)Metadata.instantiateWrapperFor(methodHandle); ++ return bcpToBci(bcp, method); ++ } ++ ++ public Address addressOfInterpreterFrameMDX() { ++ return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET); ++ } ++ ++ // expression stack ++ // (the max_stack arguments are used by the GC; see class FrameClosure) ++ ++ public Address addressOfInterpreterFrameExpressionStack() { ++ Address monitorEnd = interpreterFrameMonitorEnd().address(); ++ return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize()); ++ } ++ ++ public int getInterpreterFrameExpressionStackDirection() { return -1; } ++ ++ // top of expression stack ++ public Address addressOfInterpreterFrameTOS() { ++ return getSP(); ++ } ++ ++ /** Expression stack from top down */ ++ public Address addressOfInterpreterFrameTOSAt(int slot) { ++ return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize()); ++ } ++ ++ public Address getInterpreterFrameSenderSP() { ++ if (Assert.ASSERTS_ENABLED) { ++ Assert.that(isInterpretedFrame(), "interpreted frame expected"); ++ } ++ return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); ++ } ++ ++ // Monitors ++ public BasicObjectLock interpreterFrameMonitorBegin() { ++ return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET)); ++ } ++ ++ public BasicObjectLock interpreterFrameMonitorEnd() { ++ Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0); ++ if (Assert.ASSERTS_ENABLED) { ++ // make sure the pointer points inside the frame ++ Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer"); ++ Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer"); ++ } ++ return new BasicObjectLock(result); ++ } ++ ++ public int interpreterFrameMonitorSize() { ++ return BasicObjectLock.size(); ++ } ++ ++ // Method ++ public Address addressOfInterpreterFrameMethod() { ++ return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET); ++ } ++ ++ // Constant pool cache ++ public Address addressOfInterpreterFrameCPCache() { ++ return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET); ++ } ++ ++ // Entry frames ++ public JavaCallWrapper getEntryFrameCallWrapper() { ++ return new RISCV64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0)); ++ } ++ ++ protected Address addressOfSavedOopResult() { ++ // offset is 2 for compiler2 and 3 for compiler1 ++ return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) * ++ VM.getVM().getAddressSize()); ++ } ++ ++ protected Address addressOfSavedReceiver() { ++ return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize()); ++ } ++ ++ private void dumpStack() { ++ for (Address addr = getSP().addOffsetTo(-4 * VM.getVM().getAddressSize()); ++ AddressOps.lt(addr, getSP()); ++ addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { ++ System.out.println(addr + ": " + addr.getAddressAt(0)); ++ } ++ System.out.println("-----------------------"); ++ for (Address addr = getSP(); ++ AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize())); ++ addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { ++ System.out.println(addr + ": " + addr.getAddressAt(0)); ++ } ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64JavaCallWrapper.java +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.runtime.riscv64; ++ ++import java.util.*; ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.types.*; ++import sun.jvm.hotspot.runtime.*; ++import sun.jvm.hotspot.utilities.*; ++import sun.jvm.hotspot.utilities.Observable; ++import sun.jvm.hotspot.utilities.Observer; ++ ++public class RISCV64JavaCallWrapper extends JavaCallWrapper { ++ private static AddressField lastJavaFPField; ++ ++ static { ++ VM.registerVMInitializedObserver(new Observer() { ++ public void update(Observable o, Object data) { ++ initialize(VM.getVM().getTypeDataBase()); ++ } ++ }); ++ } ++ ++ private static synchronized void initialize(TypeDataBase db) { ++ Type type = db.lookupType("JavaFrameAnchor"); ++ ++ lastJavaFPField = type.getAddressField("_last_Java_fp"); ++ } ++ ++ public RISCV64JavaCallWrapper(Address addr) { ++ super(addr); ++ } ++ ++ public Address getLastJavaFP() { ++ return lastJavaFPField.getValue(addr.addOffsetTo(anchorField.getOffset())); ++ } ++} +--- /dev/null ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64RegisterMap.java +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, Red Hat Inc. ++ * Copyright (c) 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. ++ * ++ */ ++ ++package sun.jvm.hotspot.runtime.riscv64; ++ ++import sun.jvm.hotspot.debugger.*; ++import sun.jvm.hotspot.runtime.*; ++ ++public class RISCV64RegisterMap extends RegisterMap { ++ ++ /** This is the only public constructor */ ++ public RISCV64RegisterMap(JavaThread thread, boolean updateMap) { ++ super(thread, updateMap); ++ } ++ ++ protected RISCV64RegisterMap(RegisterMap map) { ++ super(map); ++ } ++ ++ public Object clone() { ++ RISCV64RegisterMap retval = new RISCV64RegisterMap(this); ++ return retval; ++ } ++ ++ // no PD state to clear or copy: ++ protected void clearPD() {} ++ protected void initializePD() {} ++ protected void initializeFromPD(RegisterMap map) {} ++ protected Address getLocationPD(VMReg reg) { return null; } ++} +--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java ++++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -50,7 +50,7 @@ public class PlatformInfo { + + public static boolean knownCPU(String cpu) { + final String[] KNOWN = +- new String[] {"i386", "x86", "x86_64", "amd64", "ppc64", "ppc64le", "aarch64"}; ++ new String[] {"i386", "x86", "x86_64", "amd64", "ppc64", "ppc64le", "aarch64", "riscv64"}; + + for(String s : KNOWN) { + if(s.equals(cpu)) +--- a/test/hotspot/jtreg/compiler/c2/TestBit.java ++++ b/test/hotspot/jtreg/compiler/c2/TestBit.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it +@@ -33,7 +33,7 @@ import jdk.test.lib.process.ProcessTools + * @library /test/lib / + * + * @requires vm.flagless +- * @requires os.arch=="aarch64" | os.arch=="amd64" | os.arch == "ppc64le" ++ * @requires os.arch=="aarch64" | os.arch=="amd64" | os.arch == "ppc64le" | os.arch == "riscv64" + * @requires vm.debug == true & vm.compiler2.enabled + * + * @run driver compiler.c2.TestBit +@@ -55,7 +55,8 @@ public class TestBit { + String expectedTestBitInstruction = + "ppc64le".equals(System.getProperty("os.arch")) ? "ANDI" : + "aarch64".equals(System.getProperty("os.arch")) ? "tb" : +- "amd64".equals(System.getProperty("os.arch")) ? "test" : null; ++ "amd64".equals(System.getProperty("os.arch")) ? "test" : ++ "riscv64".equals(System.getProperty("os.arch")) ? "andi" : null; + + if (expectedTestBitInstruction != null) { + output.shouldContain(expectedTestBitInstruction); +--- /dev/null ++++ b/test/hotspot/jtreg/compiler/floatingpoint/TestLibmIntrinsics.java +@@ -0,0 +1,80 @@ ++/* ++ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2022, Alibaba Group Holding Limited. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please 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 libm intrinsics ++ * @library /test/lib / ++ * ++ * @build jdk.test.whitebox.WhiteBox ++ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox ++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ++ * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement ++ * compiler.floatingpoint.TestLibmIntrinsics ++ */ ++ ++package compiler.floatingpoint; ++ ++import compiler.whitebox.CompilerWhiteBoxTest; ++import jdk.test.whitebox.WhiteBox; ++ ++import java.lang.reflect.Method; ++ ++public class TestLibmIntrinsics { ++ ++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); ++ ++ private static final double pi = 3.1415926; ++ ++ private static final double expected = 2.5355263553695413; ++ ++ static double m() { ++ return Math.pow(pi, Math.sin(Math.cos(Math.tan(Math.log(Math.log10(Math.exp(pi))))))); ++ } ++ ++ static public void main(String[] args) throws NoSuchMethodException { ++ Method test_method = compiler.floatingpoint.TestLibmIntrinsics.class.getDeclaredMethod("m"); ++ ++ double interpreter_result = m(); ++ ++ // Compile with C1 if possible ++ WHITE_BOX.enqueueMethodForCompilation(test_method, CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE); ++ ++ double c1_result = m(); ++ ++ WHITE_BOX.deoptimizeMethod(test_method); ++ ++ // Compile it with C2 if possible ++ WHITE_BOX.enqueueMethodForCompilation(test_method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); ++ ++ double c2_result = m(); ++ ++ if (interpreter_result != c1_result || ++ interpreter_result != c2_result || ++ c1_result != c2_result) { ++ System.out.println("interpreter = " + interpreter_result + " c1 = " + c1_result + " c2 = " + c2_result); ++ throw new RuntimeException("Test Failed"); ++ } ++ } ++} +--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java ++++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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 +@@ -39,6 +39,7 @@ package compiler.intrinsics.sha.cli; + + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; ++import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; + import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; + +@@ -49,6 +50,8 @@ public class TestUseSHA1IntrinsicsOption + DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), + new GenericTestCaseForUnsupportedAArch64CPU( + DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), ++ new GenericTestCaseForUnsupportedRISCV64CPU( ++ DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), + new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( + DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), + new GenericTestCaseForOtherCPU( +--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java ++++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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 +@@ -39,6 +39,7 @@ package compiler.intrinsics.sha.cli; + + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; ++import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; + import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; + +@@ -49,6 +50,8 @@ public class TestUseSHA256IntrinsicsOpti + DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), + new GenericTestCaseForUnsupportedAArch64CPU( + DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), ++ new GenericTestCaseForUnsupportedRISCV64CPU( ++ DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), + new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( + DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), + new GenericTestCaseForOtherCPU( +--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java ++++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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 +@@ -39,6 +39,7 @@ package compiler.intrinsics.sha.cli; + + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; ++import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; + import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; + +@@ -49,6 +50,8 @@ public class TestUseSHA512IntrinsicsOpti + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), + new GenericTestCaseForUnsupportedAArch64CPU( + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), ++ new GenericTestCaseForUnsupportedRISCV64CPU( ++ DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), + new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), + new GenericTestCaseForOtherCPU( +--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java ++++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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 +@@ -39,6 +39,7 @@ package compiler.intrinsics.sha.cli; + + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; ++import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; + import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; + import compiler.intrinsics.sha.cli.testcases.UseSHASpecificTestCaseForUnsupportedCPU; + +@@ -49,6 +50,8 @@ public class TestUseSHAOptionOnUnsupport + DigestOptionsBase.USE_SHA_OPTION), + new GenericTestCaseForUnsupportedAArch64CPU( + DigestOptionsBase.USE_SHA_OPTION), ++ new GenericTestCaseForUnsupportedRISCV64CPU( ++ DigestOptionsBase.USE_SHA_OPTION), + new UseSHASpecificTestCaseForUnsupportedCPU( + DigestOptionsBase.USE_SHA_OPTION), + new GenericTestCaseForOtherCPU( +--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java ++++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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 +@@ -32,7 +32,7 @@ import jdk.test.lib.cli.predicate.OrPred + + /** + * Generic test case for SHA-related options targeted to any CPU except +- * AArch64, PPC, S390x, and X86. ++ * AArch64, RISCV64, PPC, S390x, and X86. + */ + public class GenericTestCaseForOtherCPU extends + DigestOptionsBase.TestCase { +@@ -44,13 +44,14 @@ public class GenericTestCaseForOtherCPU + } + + public GenericTestCaseForOtherCPU(String optionName, boolean checkUseSHA) { +- // Execute the test case on any CPU except AArch64, PPC, S390x, and X86. ++ // Execute the test case on any CPU except AArch64, RISCV64, PPC, S390x, and X86. + super(optionName, new NotPredicate( + new OrPredicate(Platform::isAArch64, ++ new OrPredicate(Platform::isRISCV64, + new OrPredicate(Platform::isS390x, + new OrPredicate(Platform::isPPC, + new OrPredicate(Platform::isX64, +- Platform::isX86)))))); ++ Platform::isX86))))))); + + this.checkUseSHA = checkUseSHA; + } +@@ -59,7 +60,7 @@ public class GenericTestCaseForOtherCPU + protected void verifyWarnings() throws Throwable { + String shouldPassMessage = String.format("JVM should start with " + + "option '%s' without any warnings", optionName); +- // Verify that on non-x86 and non-AArch64 CPU usage of SHA-related ++ // Verify that on non-x86, non-RISCV64 and non-AArch64 CPU usage of SHA-related + // options will not cause any warnings. + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { ".*" + optionName + ".*" }, shouldPassMessage, +--- /dev/null ++++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedRISCV64CPU.java +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (c) 2014, 2016, 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. ++ */ ++ ++package compiler.intrinsics.sha.cli.testcases; ++ ++import compiler.intrinsics.sha.cli.DigestOptionsBase; ++import jdk.test.lib.process.ExitCode; ++import jdk.test.lib.Platform; ++import jdk.test.lib.cli.CommandLineOptionTest; ++import jdk.test.lib.cli.predicate.AndPredicate; ++import jdk.test.lib.cli.predicate.NotPredicate; ++ ++/** ++ * Generic test case for SHA-related options targeted to RISCV64 CPUs ++ * which don't support instruction required by the tested option. ++ */ ++public class GenericTestCaseForUnsupportedRISCV64CPU extends ++ DigestOptionsBase.TestCase { ++ ++ final private boolean checkUseSHA; ++ ++ public GenericTestCaseForUnsupportedRISCV64CPU(String optionName) { ++ this(optionName, true); ++ } ++ ++ public GenericTestCaseForUnsupportedRISCV64CPU(String optionName, boolean checkUseSHA) { ++ super(optionName, new AndPredicate(Platform::isRISCV64, ++ new NotPredicate(DigestOptionsBase.getPredicateForOption( ++ optionName)))); ++ ++ this.checkUseSHA = checkUseSHA; ++ } ++ ++ @Override ++ protected void verifyWarnings() throws Throwable { ++ String shouldPassMessage = String.format("JVM startup should pass with" ++ + "option '-XX:-%s' without any warnings", optionName); ++ //Verify that option could be disabled without any warnings. ++ CommandLineOptionTest.verifySameJVMStartup(null, new String[] { ++ DigestOptionsBase.getWarningForUnsupportedCPU(optionName) ++ }, shouldPassMessage, shouldPassMessage, ExitCode.OK, ++ DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, ++ CommandLineOptionTest.prepareBooleanFlag(optionName, false)); ++ ++ if (checkUseSHA) { ++ shouldPassMessage = String.format("If JVM is started with '-XX:-" ++ + "%s' '-XX:+%s', output should contain warning.", ++ DigestOptionsBase.USE_SHA_OPTION, optionName); ++ ++ // Verify that when the tested option is enabled, then ++ // a warning will occur in VM output if UseSHA is disabled. ++ if (!optionName.equals(DigestOptionsBase.USE_SHA_OPTION)) { ++ CommandLineOptionTest.verifySameJVMStartup( ++ new String[] { DigestOptionsBase.getWarningForUnsupportedCPU(optionName) }, ++ null, ++ shouldPassMessage, ++ shouldPassMessage, ++ ExitCode.OK, ++ DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, ++ CommandLineOptionTest.prepareBooleanFlag(DigestOptionsBase.USE_SHA_OPTION, false), ++ CommandLineOptionTest.prepareBooleanFlag(optionName, true)); ++ } ++ } ++ } ++ ++ @Override ++ protected void verifyOptionValues() throws Throwable { ++ // Verify that option is disabled by default. ++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", ++ String.format("Option '%s' should be disabled by default", ++ optionName), ++ DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS); ++ ++ if (checkUseSHA) { ++ // Verify that option is disabled even if it was explicitly enabled ++ // using CLI options. ++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", ++ String.format("Option '%s' should be off on unsupported " ++ + "RISCV64CPU even if set to true directly", optionName), ++ DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, ++ CommandLineOptionTest.prepareBooleanFlag(optionName, true)); ++ ++ // Verify that option is disabled when +UseSHA was passed to JVM. ++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", ++ String.format("Option '%s' should be off on unsupported " ++ + "RISCV64CPU even if %s flag set to JVM", ++ optionName, CommandLineOptionTest.prepareBooleanFlag( ++ DigestOptionsBase.USE_SHA_OPTION, true)), ++ DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, ++ CommandLineOptionTest.prepareBooleanFlag( ++ DigestOptionsBase.USE_SHA_OPTION, true)); ++ } ++ } ++} +--- a/test/hotspot/jtreg/compiler/loopopts/superword/ProdRed_Double.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/ProdRed_Double.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8074981 + * @summary Add C2 x86 Superword support for scalar product reduction optimizations : float test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/ProdRed_Float.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/ProdRed_Float.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8074981 + * @summary Add C2 x86 Superword support for scalar product reduction optimizations : float test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/ProdRed_Int.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/ProdRed_Int.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8074981 + * @summary Add C2 x86 Superword support for scalar product reduction optimizations : int test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/ReductionPerf.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/ReductionPerf.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8074981 + * @summary Add C2 x86 Superword support for scalar product reduction optimizations : int test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions + * -XX:LoopUnrollLimit=250 -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/SumRedAbsNeg_Double.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/SumRedAbsNeg_Double.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8138583 + * @summary Add C2 AArch64 Superword support for scalar sum reduction optimizations : double abs & neg test +- * @requires os.arch=="aarch64" ++ * @requires os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/SumRedAbsNeg_Float.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/SumRedAbsNeg_Float.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8138583 + * @summary Add C2 AArch64 Superword support for scalar sum reduction optimizations : float abs & neg test +- * @requires os.arch=="aarch64" ++ * @requires os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/SumRedSqrt_Double.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/SumRedSqrt_Double.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8135028 + * @summary Add C2 x86 Superword support for scalar sum reduction optimizations : double sqrt test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/SumRed_Double.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/SumRed_Double.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8074981 + * @summary Add C2 x86 Superword support for scalar sum reduction optimizations : double test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/SumRed_Float.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/SumRed_Float.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8074981 + * @summary Add C2 x86 Superword support for scalar sum reduction optimizations : float test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/loopopts/superword/SumRed_Int.java ++++ b/test/hotspot/jtreg/compiler/loopopts/superword/SumRed_Int.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -25,7 +25,7 @@ + * @test + * @bug 8074981 + * @summary Add C2 x86 Superword support for scalar sum reduction optimizations : int test +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:LoopUnrollLimit=250 + * -XX:CompileThresholdScaling=0.1 +--- a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java ++++ b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java +@@ -130,7 +130,7 @@ public abstract class TestConstantsInErr + results.shouldMatch("Test_C1/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_C2/.*::test \\(3 bytes\\)$"); + +- if (isC1 && Platform.isAArch64()) { // no code patching ++ if (isC1 && (Platform.isAArch64() || Platform.isRISCV64())) { // no code patching + results.shouldMatch("Test_C1/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_C2/.*::test \\(3 bytes\\) made not entrant"); + } else { +@@ -168,7 +168,7 @@ public abstract class TestConstantsInErr + .shouldMatch("Test_MH3/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_MH4/.*::test \\(3 bytes\\)$"); + +- if (isC1 && Platform.isAArch64()) { // no code patching ++ if (isC1 && (Platform.isAArch64() || Platform.isRISCV64())) { // no code patching + results.shouldMatch("Test_MH1/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_MH2/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_MH3/.*::test \\(3 bytes\\) made not entrant") +@@ -191,7 +191,7 @@ public abstract class TestConstantsInErr + results.shouldMatch("Test_MT1/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_MT2/.*::test \\(3 bytes\\)$"); + +- if (isC1 && Platform.isAArch64()) { // no code patching ++ if (isC1 && (Platform.isAArch64() || Platform.isRISCV64())) { // no code patching + results.shouldMatch("Test_MT1/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_MT2/.*::test \\(3 bytes\\) made not entrant"); + } else { +--- a/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java ++++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java +@@ -24,7 +24,7 @@ + + /* @test + * @bug 8167409 +- * @requires (os.arch != "aarch64") & (os.arch != "arm") & (vm.flavor != "zero") ++ * @requires (os.arch != "aarch64") & (os.arch != "arm") & (os.arch != "riscv64") & (vm.flavor != "zero") + * @run main/othervm/native -Xcomp -XX:+CriticalJNINatives compiler.runtime.criticalnatives.argumentcorruption.CheckLongArgs + */ + package compiler.runtime.criticalnatives.argumentcorruption; +--- a/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java ++++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java +@@ -24,7 +24,7 @@ + + /* @test + * @bug 8167408 +- * @requires (os.arch != "aarch64") & (os.arch != "arm") & (vm.flavor != "zero") ++ * @requires (os.arch != "aarch64") & (os.arch != "arm") & (os.arch != "riscv64") & (vm.flavor != "zero") + * @run main/othervm/native -Xcomp -XX:+CriticalJNINatives compiler.runtime.criticalnatives.lookup.LookUp + */ + package compiler.runtime.criticalnatives.lookup; +--- a/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java ++++ b/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2014, 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 +@@ -68,14 +68,16 @@ public class IntrinsicPredicates { + + public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE + = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha1" }, null), ++ new OrPredicate(new CPUSpecificPredicate("riscv64.*", new String[] { "sha1" }, null), + new OrPredicate(new CPUSpecificPredicate("s390.*", new String[] { "sha1" }, null), + // x86 variants + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), +- new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null))))); ++ new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null)))))); + + public static final BooleanSupplier SHA256_INSTRUCTION_AVAILABLE + = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha256" }, null), ++ new OrPredicate(new CPUSpecificPredicate("riscv64.*", new String[] { "sha256" }, null), + new OrPredicate(new CPUSpecificPredicate("s390.*", new String[] { "sha256" }, null), + new OrPredicate(new CPUSpecificPredicate("ppc64.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("ppc64le.*", new String[] { "sha" }, null), +@@ -84,10 +86,11 @@ public class IntrinsicPredicates { + new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), +- new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null))))))))); ++ new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null)))))))))); + + public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE + = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha512" }, null), ++ new OrPredicate(new CPUSpecificPredicate("riscv64.*", new String[] { "sha512" }, null), + new OrPredicate(new CPUSpecificPredicate("s390.*", new String[] { "sha512" }, null), + new OrPredicate(new CPUSpecificPredicate("ppc64.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("ppc64le.*", new String[] { "sha" }, null), +@@ -96,7 +99,7 @@ public class IntrinsicPredicates { + new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), +- new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null))))))))); ++ new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null)))))))))); + + public static final BooleanSupplier SHA3_INSTRUCTION_AVAILABLE + // sha3 is only implemented on aarch64 for now +--- a/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java ++++ b/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2016, 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 +@@ -133,7 +133,7 @@ public class CheckForProperDetailStackTr + // It's ok for ARM not to have symbols, because it does not support NMT detail + // when targeting thumb2. It's also ok for Windows not to have symbols, because + // they are only available if the symbols file is included with the build. +- if (Platform.isWindows() || Platform.isARM()) { ++ if (Platform.isWindows() || Platform.isARM() || Platform.isRISCV64()) { + return; // we are done + } + output.reportDiagnosticSummary(); +--- a/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java ++++ b/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2015, 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 +@@ -240,7 +240,7 @@ public class ReservedStackTest { + return Platform.isAix() || + (Platform.isLinux() && + (Platform.isPPC() || Platform.isS390x() || Platform.isX64() || +- Platform.isX86() || Platform.isAArch64())) || ++ Platform.isX86() || Platform.isAArch64() || Platform.isRISCV64())) || + Platform.isOSX(); + } + +--- a/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java ++++ b/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Google and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * +@@ -29,7 +29,7 @@ package MyPackage; + * @summary Verifies that AsyncGetCallTrace is call-able and provides sane information. + * @compile ASGCTBaseTest.java + * @requires os.family == "linux" +- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="arm" | os.arch=="aarch64" | os.arch=="ppc64" | os.arch=="s390" ++ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="arm" | os.arch=="aarch64" | os.arch=="ppc64" | os.arch=="s390" | os.arch=="riscv64" + * @requires vm.jvmti + * @run main/othervm/native -agentlib:AsyncGetCallTraceTest MyPackage.ASGCTBaseTest + */ +--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java ++++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2001, 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 +@@ -529,6 +529,7 @@ class CheckedFeatures { + {"linux-ppc64", "com.sun.jdi.SharedMemoryAttach"}, + {"linux-ppc64le", "com.sun.jdi.SharedMemoryAttach"}, + {"linux-s390x", "com.sun.jdi.SharedMemoryAttach"}, ++ {"linux-riscv64", "com.sun.jdi.SharedMemoryAttach"}, + {"macosx-amd64", "com.sun.jdi.SharedMemoryAttach"}, + {"mac-x64", "com.sun.jdi.SharedMemoryAttach"}, + {"macosx-aarch64", "com.sun.jdi.SharedMemoryAttach"}, +@@ -554,6 +555,7 @@ class CheckedFeatures { + {"linux-ppc64", "com.sun.jdi.SharedMemoryListen"}, + {"linux-ppc64le", "com.sun.jdi.SharedMemoryListen"}, + {"linux-s390x", "com.sun.jdi.SharedMemoryListen"}, ++ {"linux-riscv64", "com.sun.jdi.SharedMemoryListen"}, + {"macosx-amd64", "com.sun.jdi.SharedMemoryListen"}, + {"mac-x64", "com.sun.jdi.SharedMemoryListen"}, + {"macosx-aarch64", "com.sun.jdi.SharedMemoryListen"}, +@@ -600,6 +602,9 @@ class CheckedFeatures { + {"linux-s390x", "com.sun.jdi.CommandLineLaunch", "dt_shmem"}, + {"linux-s390x", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"}, + ++ {"linux-riscv64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"}, ++ {"linux-riscv64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"}, ++ + {"windows-i586", "com.sun.jdi.CommandLineLaunch", "dt_socket"}, + {"windows-i586", "com.sun.jdi.RawCommandLineLaunch", "dt_socket"}, + +@@ -637,6 +642,7 @@ class CheckedFeatures { + {"linux-ppc64", "dt_shmem"}, + {"linux-ppc64le", "dt_shmem"}, + {"linux-s390x", "dt_shmem"}, ++ {"linux-riscv64", "dt_shmem"}, + {"macosx-amd64", "dt_shmem"}, + {"mac-x64", "dt_shmem"}, + {"macosx-aarch64", "dt_shmem"}, +--- a/test/jdk/jdk/jfr/event/os/TestCPUInformation.java ++++ b/test/jdk/jdk/jfr/event/os/TestCPUInformation.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it +@@ -52,8 +52,8 @@ public class TestCPUInformation { + Events.assertField(event, "hwThreads").atLeast(1); + Events.assertField(event, "cores").atLeast(1); + Events.assertField(event, "sockets").atLeast(1); +- Events.assertField(event, "cpu").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "s390"); +- Events.assertField(event, "description").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "s390"); ++ Events.assertField(event, "cpu").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "RISCV64", "s390"); ++ Events.assertField(event, "description").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "RISCV64", "s390"); + } + } + } +--- a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java ++++ b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java +@@ -45,7 +45,7 @@ import java.util.Set; + */ + public class TestMutuallyExclusivePlatformPredicates { + private static enum MethodGroup { +- ARCH("isAArch64", "isARM", "isPPC", "isS390x", "isX64", "isX86"), ++ ARCH("isAArch64", "isARM", "isRISCV64", "isPPC", "isS390x", "isX64", "isX86"), + BITNESS("is32bit", "is64bit"), + OS("isAix", "isLinux", "isOSX", "isWindows"), + VM_TYPE("isClient", "isServer", "isMinimal", "isZero", "isEmbedded"), +--- a/test/lib/jdk/test/lib/Platform.java ++++ b/test/lib/jdk/test/lib/Platform.java +@@ -210,6 +210,10 @@ public class Platform { + return isArch("arm.*"); + } + ++ public static boolean isRISCV64() { ++ return isArch("riscv64"); ++ } ++ + public static boolean isPPC() { + return isArch("ppc.*"); + } diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/build_gtest.patch openjdk-17-17.0.8+7/debian/patches/build_gtest.patch --- openjdk-17-17.0.7+7~us1/debian/patches/build_gtest.patch 2023-05-06 09:34:26.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/build_gtest.patch 2023-07-20 08:58:17.000000000 +0000 @@ -4,7 +4,7 @@ with the system google test. Author: Vladimir Petko Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/openjdk-20/+bug/2012316 -Last-Update: 2023-04-13 +Last-Update: 2023-07-20 --- a/make/autoconf/lib-tests.m4 +++ b/make/autoconf/lib-tests.m4 @@ -36,6 +36,8 @@ @@ -18,12 +18,14 @@ AC_MSG_ERROR([--with-gtest must have a value]) --- a/test/hotspot/gtest/gtestMain.cpp +++ b/test/hotspot/gtest/gtestMain.cpp -@@ -230,7 +230,7 @@ +@@ -230,7 +230,9 @@ bool is_vmassert_test = false; bool is_othervm_test = false; // death tests facility is used for both regular death tests, other vm and vmassert tests - if (::testing::internal::GTEST_FLAG(internal_run_death_test).length() > 0) { -+ if (::testing::GTEST_FLAG(internal_run_death_test).length() > 0) { ++using namespace ::testing; ++using namespace ::testing::internal; ++ if (GTEST_FLAG(internal_run_death_test).length() > 0) { // when we execute death test, filter value equals to test name const char* test_name = ::testing::GTEST_FLAG(filter).c_str(); const char* const othervm_suffix = "_other_vm"; // TEST_OTHER_VM diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/default-jvm-cfg.diff openjdk-17-17.0.8+7/debian/patches/default-jvm-cfg.diff --- openjdk-17-17.0.7+7~us1/debian/patches/default-jvm-cfg.diff 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/default-jvm-cfg.diff 2023-06-09 08:47:21.000000000 +0000 @@ -10,7 +10,7 @@ int lineno = 0; jlong start = 0, end = 0; @@ -2015,6 +2015,11 @@ - + jvmCfg = fopen(jvmCfgName, "r"); if (jvmCfg == NULL) { + char cfgName[strlen(jvmCfgName)+10]; diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/disable-thumb-assertion.patch openjdk-17-17.0.8+7/debian/patches/disable-thumb-assertion.patch --- openjdk-17-17.0.7+7~us1/debian/patches/disable-thumb-assertion.patch 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/disable-thumb-assertion.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -Description: Unable to obtain frame pointer on Thumb architecture - ARM Thumb has os::current_frame() disabled. Disable associated test. -Author: Vladimir Petko -Bug: https://bugs.openjdk.org/browse/JDK-8305481 -Last-Update: 2023-03-30 ---- a/test/hotspot/gtest/runtime/test_os.cpp -+++ b/test/hotspot/gtest/runtime/test_os.cpp -@@ -844,7 +844,7 @@ - } - - TEST_VM(os, is_first_C_frame) { --#if !defined(_WIN32) && !defined(ZERO) -+#if !defined(_WIN32) && !defined(ZERO) && !defined(__thumb__) - frame invalid_frame; - EXPECT_TRUE(os::is_first_C_frame(&invalid_frame)); // the frame has zeroes for all values - diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/exclude-broken-tests.patch openjdk-17-17.0.8+7/debian/patches/exclude-broken-tests.patch --- openjdk-17-17.0.7+7~us1/debian/patches/exclude-broken-tests.patch 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/exclude-broken-tests.patch 2023-07-20 09:02:18.000000000 +0000 @@ -44,11 +44,14 @@ # javadoc --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt -@@ -109,6 +109,49 @@ +@@ -109,6 +109,52 @@ # ############################################################################# -+ ++# NSS3 failure when processing SHA3 hashes (needs investigation) ++sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java 0000000 generic-all ++sun/security/pkcs11/MessageDigest/TestCloning.java 0000000 generic-all ++sun/security/pkcs11/Signature/SignatureTestPSS.java 0000000 generic-all + +# to investigate +# unable to read LD_LIBRARY_PATH env variable @@ -94,7 +97,7 @@ ############################################################################ # jdk_awt -@@ -537,7 +580,6 @@ +@@ -537,7 +583,6 @@ 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 diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/hotspot-disable-exec-shield-workaround.diff openjdk-17-17.0.8+7/debian/patches/hotspot-disable-exec-shield-workaround.diff --- openjdk-17-17.0.7+7~us1/debian/patches/hotspot-disable-exec-shield-workaround.diff 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/hotspot-disable-exec-shield-workaround.diff 2023-06-09 08:47:21.000000000 +0000 @@ -8,4 +8,4 @@ +#if 0 assert(Linux::initial_thread_stack_bottom() != NULL, "sanity"); size_t page_size = os::vm_page_size(); - + diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/riscv64.diff openjdk-17-17.0.8+7/debian/patches/riscv64.diff --- openjdk-17-17.0.7+7~us1/debian/patches/riscv64.diff 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/riscv64.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -# HG changeset patch -# User enevill -# Date 1521985117 -3600 -# Sun Mar 25 14:38:37 2018 +0100 -# Node ID 7d1ae835ef5194e7ae5b56b51f944029fe602d11 -# Parent 1b1de4b263c81853719f6bb0385fe23bc4e35f6c -8199138: Add RISC-V support to Zero -Reviewed-by: aph, erikj, ehelin, ihse - ---- a/make/autoconf/build-aux/config.guess -+++ b/make/autoconf/build-aux/config.guess -@@ -28,6 +28,13 @@ - # autoconf system (which might easily get lost in a future update), we wrap it - # and fix the broken property, if needed. - -+machine=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -+if test $machine = riscv64; then -+ # This is all we need to know for riscv64 -+ echo riscv64-unknown-linux-gnu -+ exit -+fi -+ - DIR=`dirname $0` - OUT=`. $DIR/autoconf-config.guess 2> /dev/null` - ---- a/make/autoconf/build-aux/config.sub -+++ b/make/autoconf/build-aux/config.sub -@@ -46,8 +46,8 @@ - exit - fi - --# Filter out everything that doesn't begin with "aarch64-" --if ! echo $* | grep '^aarch64-' >/dev/null ; then -+# First, filter out everything that doesn't begin with "aarch64-" or "riscv64-" -+if ! echo $* | grep '^aarch64-\|^riscv64-' >/dev/null ; then - . $DIR/autoconf-config.sub "$@" - # autoconf-config.sub exits, so we never reach here, but just in - # case we do: -@@ -62,6 +62,10 @@ - config=`echo $1 | sed 's/^aarch64-/arm-/'` - sub_args="$sub_args $config" - shift; ;; -+ riscv64-* ) -+ config=`echo $1 | sed 's/^riscv64-/x86-/'` -+ sub_args="$sub_args $config" -+ shift; ;; - - ) # Use stdin as input. - sub_args="$sub_args $1" - shift; break ;; -@@ -74,7 +78,7 @@ - result=`. $DIR/autoconf-config.sub $sub_args "$@"` - exitcode=$? - --result=`echo $result | sed "s/^arm-/aarch64-/"` -+result=`echo $result | sed "s/^arm-/aarch64-/" | sed "s/^x86-/riscv64-/"` - - echo $result - exit $exitcode ---- a/src/hotspot/os/linux/os_linux.cpp -+++ b/src/hotspot/os/linux/os_linux.cpp -@@ -2559,6 +2559,8 @@ - strncpy(cpuinfo, "IA64", length); - #elif defined(PPC) - strncpy(cpuinfo, "PPC64", length); -+#elif defined(RISCV) -+ strncpy(cpuinfo, "RISCV", length); - #elif defined(S390) - strncpy(cpuinfo, "S390", length); - #elif defined(SPARC) diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/s390x-opt.diff openjdk-17-17.0.8+7/debian/patches/s390x-opt.diff --- openjdk-17-17.0.7+7~us1/debian/patches/s390x-opt.diff 2023-03-16 22:04:55.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/s390x-opt.diff 2023-07-19 06:29:02.000000000 +0000 @@ -1,6 +1,6 @@ --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 -@@ -735,6 +735,9 @@ +@@ -739,6 +739,9 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], fi elif test "x$FLAGS_CPU" = xs390x; then $1_CFLAGS_CPU="-mbackchain -march=z10" diff -Nru openjdk-17-17.0.7+7~us1/debian/patches/series openjdk-17-17.0.8+7/debian/patches/series --- openjdk-17-17.0.7+7~us1/debian/patches/series 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/patches/series 2023-06-27 10:34:26.000000000 +0000 @@ -25,12 +25,10 @@ reproducible-character-data.diff reproducible-module-info.diff #reproducible-copyright-headers.diff -riscv64.diff reproducible-build-jmod.diff mips.diff #nspr+nss-headers.diff build_gtest.patch -disable-thumb-assertion.patch update-assertion-for-armhf.patch misalign-pointer-for-armhf.patch log-generated-classes-test.patch @@ -38,3 +36,4 @@ ldap-timeout-test-use-ip.patch test-use-ip-address.patch exclude-broken-tests.patch +8276799.diff diff -Nru openjdk-17-17.0.7+7~us1/debian/rules openjdk-17-17.0.8+7/debian/rules --- openjdk-17-17.0.7+7~us1/debian/rules 2023-05-06 09:36:49.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/rules 2023-07-20 09:09:30.000000000 +0000 @@ -55,7 +55,7 @@ multiarch_dir = /$(DEB_HOST_MULTIARCH) -hotspot_archs = amd64 i386 arm64 armhf ppc64 ppc64el s390x +hotspot_archs = amd64 i386 arm64 armhf ppc64 ppc64el riscv64 s390x jtreg_archs = $(hotspot_archs) alpha ia64 powerpc ppc64 sh4 x32 jtreg_archs += armel mipsel mips64el jtreg_archs += riscv64 @@ -105,27 +105,20 @@ v_upstream := $(shell echo $(v_debian) | sed 's/-[^-][^-]*$$//') v_pkgrel := $(shell echo $(v_debian) | sed 's/^.*-//') -# uncomment for final release -v_upbase := $(word 1, $(subst +, , $(v_upstream))) -v_upbuild := $(word 2, $(subst +, , $(v_upstream))) - -# uncomment for pre-release -#v_upbase := $(word 1, $(subst ~, , $(v_upstream))) -#v_upbuild := $(word 2, $(subst ~, , $(v_upstream))) -# that should be the package version ... - -#$(warning XXXXX $(v_upstream) / $(v_pkgrel) / $(v_upbase) / $(v_upbuild)) - -#uncomment for final release -ifneq ($(v_debian),$(v_upbase)+$(v_upbuild)-$(v_pkgrel)) - $(error wrong version: $(v_upbase)+$(v_upbuild)-$(v_pkgrel) should be: $(v_debian)) +ifeq (yes,$(is_upstream_release)) + v_upbase := $(word 1, $(subst +, , $(v_upstream))) + v_upbuild := $(word 2, $(subst +, , $(v_upstream))) + ifneq ($(v_debian),$(v_upbase)+$(v_upbuild)-$(v_pkgrel)) + $(error wrong version: $(v_upbase)+$(v_upbuild)-$(v_pkgrel) should be: $(v_debian)) + endif +else + v_upbase := $(word 1, $(subst ~, , $(v_upstream))) + v_upbuild := $(word 2, $(subst ~, , $(v_upstream))) + ifneq ($(v_debian),$(v_upbase)~$(v_upbuild)-$(v_pkgrel)) + $(error wrong version: $(v_upbase)~$(v_upbuild)-$(v_pkgrel) should be: $(v_debian)) + endif endif -# uncomment for pre-releases -#ifneq ($(v_debian),$(v_upbase)~$(v_upbuild)-$(v_pkgrel)) -# $(error wrong version: $(v_upbase)~$(v_upbuild)-$(v_pkgrel) should be: $(v_debian)) -#endif - ifneq (,$(DEB_HOST_MULTIARCH)) jdirname = java-$(shortver)-$(origin)-$(DEB_HOST_ARCH) jdiralias = java-$(jvmver)-$(origin)-$(DEB_HOST_ARCH) @@ -164,13 +157,18 @@ endif jtreg_pkg = jtreg6 +testng_pkg= libtestng7-java with_check = $(if $(findstring nocheck, $(DEB_BUILD_OPTIONS)),,yes) -ifneq (,$(filter $(DEB_HOST_ARCH), alpha armel mipsel mips64el riscv64)) +ifneq (,$(filter $(DEB_HOST_ARCH), alpha armel ia64 mipsel mips64el powerpc x32)) with_check = disabled running check on $(DEB_HOST_ARCH) endif +ifeq ($(distribution)-$(distrel),Ubuntu-riscv64) + with_check = yes +endif + # no jtreg backport yet -ifneq (,$(filter $(distrel), buster bullseye precise trusty xenial bionic focal groovy hirsute impish)) +ifneq (,$(filter $(distrel), buster bullseye precise trusty xenial groovy hirsute impish)) with_check = disabled for $(distrel), no $(jtreg_pkg) endif @@ -299,7 +297,7 @@ # jdk/make/CompileDemos.gmk (SetupJVMTIDemo) doesn't like commas in flags dpkg_buildflags_hs += \ DEB_LDFLAGS_MAINT_STRIP="-Wl,-z,relro -Wl,-Bsymbolic-functions" \ - DEB_LDFLAGS_MAINT_APPEND="-Xlinker -z -Xlinker relro -Xlinker -Bsymbolic-functions" + DEB_LDFLAGS_MAINT_APPEND="-Xlinker -z -Xlinker relro -Xlinker -Bsymbolic-functions -Xlinker --no-as-needed" dpkg_buildflags_hs += dpkg-buildflags export EXTRA_CPPFLAGS_HS := $(shell $(dpkg_buildflags_hs) --get CPPFLAGS) export EXTRA_CFLAGS_HS := $(shell $(dpkg_buildflags_hs) --get CFLAGS; $(dpkg_buildflags_hs) --get CPPFLAGS) @@ -315,7 +313,7 @@ # jdk/make/CompileDemos.gmk (SetupJVMTIDemo) doesn't like commas in flags dpkg_buildflags_zero += \ DEB_LDFLAGS_MAINT_STRIP="-Wl,-z,relro -Wl,-Bsymbolic-functions" \ - DEB_LDFLAGS_MAINT_APPEND="-Xlinker -z -Xlinker relro -Xlinker -Bsymbolic-functions" + DEB_LDFLAGS_MAINT_APPEND="-Xlinker -z -Xlinker relro -Xlinker -Bsymbolic-functions -Xlinker --no-as-needed" dpkg_buildflags_zero += dpkg-buildflags export EXTRA_CPPFLAGS_ZERO := $(shell $(dpkg_buildflags_zero) --get CPPFLAGS) export EXTRA_CFLAGS_ZERO := $(shell $(dpkg_buildflags_zero) --get CFLAGS; $(dpkg_buildflags_zero) --get CPPFLAGS) @@ -326,19 +324,6 @@ export EXTRA_LDFLAGS_ZERO += -Wl,--no-relax endif -# for JDK: jdk/make/common/Defs.gmk -# Don't overwrite JDK opt level : -# 1) with forced -03, it cause wrong Math.* computations, see #679292 and #678228 -# 2) JDK already use it's own OPTIMIZATION_LEVEL variable for each module -dpkg_buildflags_jdk = \ - DEB_BUILD_MAINT_OPTIONS="$(DEB_BUILD_MAINT_OPTIONS)" \ - DEB_CFLAGS_MAINT_STRIP="-O2" DEB_CXXFLAGS_MAINT_STRIP="-O2" -dpkg_buildflags_jdk += dpkg-buildflags -export EXTRA_CPPFLAGS_JDK := $(shell $(dpkg_buildflags_jdk) --get CPPFLAGS) -export EXTRA_CFLAGS_JDK := $(shell $(dpkg_buildflags_jdk) --get CFLAGS) $(shell $(dpkg_buildflags_jdk) --get CPPFLAGS) -export EXTRA_CXXFLAGS_JDK := $(shell $(dpkg_buildflags_jdk) --get CXXFLAGS) -export EXTRA_LDFLAGS_JDK := $(shell $(dpkg_buildflags_jdk) --get LDFLAGS) - ifneq (,$(filter $(distrel),squeeze lucid)) with_bridge = bridge with_jni_bridge = yes @@ -543,6 +528,12 @@ # building with a GCC from a PPA ... COMMON_CONFIGURE_ARGS += \ --with-stdc++lib=static +else ifneq (,$(filter $(DEB_HOST_ARCH), ia64)) + # seen in 2023 on ia64: + # /usr/bin/ld: jvm-test-launcher: no symbol version section for versioned symbol `__cxa_pure_virtual@CXXABI_1.3' + # works when linking statically + COMMON_CONFIGURE_ARGS += \ + --with-stdc++lib=static else COMMON_CONFIGURE_ARGS += \ --with-stdc++lib=dynamic @@ -606,7 +597,7 @@ jdk_hl_tools = jar jarsigner javac javadoc javap jcmd jdb \ jdeprscan jdeps jfr jimage jinfo jlink jmap jmod jps \ jrunscript jshell jstack jstat jstatd serialver -ifeq (,$(filter $(DEB_HOST_ARCH), alpha armel ia64 m68k mips mipsel mips64el powerpc riscv64 s390x sh4 sparc64 x32)) +ifeq (,$(filter $(DEB_HOST_ARCH), alpha armel ia64 m68k mips mipsel mips64el powerpc s390x sh4 sparc64 x32)) all_tools += jhsdb jdk_hl_tools += jhsdb endif @@ -674,12 +665,11 @@ bd_openjdk += libharfbuzz-dev, endif -pkg_ffidev = libffi-dev - -bd_zero = \ - $(pkg_ffidev) [$(foreach a,$(hotspot_archs),!$(a))], -bd_zero = \ - $(pkg_ffidev), +ifeq (,$(filter $(distrel),precise)) + bd_zero = libffi-dev, libffi-dev:native, +else + bd_zero = libffi-dev, +endif bd_ant = ant, ant-optional, @@ -716,13 +706,15 @@ ifeq ($(with_check),yes) bd_check = \ - $(jtreg_pkg) (>= $(min_jtreg_version))$(nocheck_profile), libtestng7-java$(nocheck_profile), \ + $(jtreg_pkg) (>= $(min_jtreg_version))$(nocheck_profile), $(testng_pkg)$(nocheck_profile), \ xvfb$(nocheck_profile), xauth$(nocheck_profile), \ xfonts-base$(nocheck_profile), libgl1-mesa-dri [!x32]$(nocheck_profile), \ xfwm4$(nocheck_profile), x11-xkb-utils$(nocheck_profile), \ - dbus-x11$(nocheck_profile), libasmtools-java$(nocheck_profile), \ - googletest$(nocheck_profile), google-mock$(nocheck_profile),\ - xvfb $(nocheck_profile), + dbus-x11$(nocheck_profile), googletest$(nocheck_profile), \ + google-mock$(nocheck_profile), xvfb $(nocheck_profile), +ifeq (,$(filter $(distrel),jessie stretch buster)) + bd_check += libasmtools-java$(nocheck_profile), +endif else bd_check = file, endif @@ -838,6 +830,7 @@ control_vars = \ '-Vvm:Name=$(vm_name)' \ + '-Vvm:Version=$(shortver)' \ '-Vdlopenhl:Depends=$(dlopen_hl_depends)' \ '-Vdlopenhl:Recommends=$(dlopen_hl_recommends)' \ '-Vdlopenjre:Depends=$(dlopen_jre_depends)' \ @@ -1270,7 +1263,7 @@ chmod -R u+w $(d) - : # use javaws from icedtea-netx + : # use javaws from icedtea-netx find $(d) -name 'javaws*' | xargs -r rm -f : # install default jvm config file @@ -1903,9 +1896,8 @@ dh_builddeb -a $(nodemo) $(nojrez) #$(bd_options) is_release = yes -#is_release = git_project = jdk17u -git_tag = jdk-17.0.6+10 +git_tag = jdk-17.0.8+7 package_version = $(subst jdk-,,$(git_tag)) package_version = $(shell echo $(PKGVERSION) | sed 's/-[^-][^-]*$$//') ifneq ($(is_release),yes) @@ -1940,8 +1932,8 @@ rm -rf $(topdir) # keep these in the tarball, older lcms are not supported - rm -v -f $$d/src/java.desktop/share/native/liblcms/cms*.c; \ - rm -v -f $$d/src/java.desktop/share/native/liblcms/lcms2*.h; \ +# rm -v -f $$d/src/java.desktop/share/native/liblcms/cms*.c; \ +# rm -v -f $$d/src/java.desktop/share/native/liblcms/lcms2*.h; \ rm -rf $(origdir) diff -Nru openjdk-17-17.0.7+7~us1/debian/tests/jtreg-autopkgtest.in openjdk-17-17.0.8+7/debian/tests/jtreg-autopkgtest.in --- openjdk-17-17.0.7+7~us1/debian/tests/jtreg-autopkgtest.in 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/tests/jtreg-autopkgtest.in 2023-07-20 05:37:00.000000000 +0000 @@ -104,6 +104,7 @@ -jdk:${JDK_TO_TEST} \ -vmoption:-Dtest.boot.jdk=${BOOTJDK_HOME} \ -vmoption:-XX:MaxRAMPercentage=25 \ + -e:NSS_DEFAULT_DB_TYPE=sql \ ${on_retry:-} $@ \ && exit_code=0 || exit_code=$? diff -Nru openjdk-17-17.0.7+7~us1/debian/tests/jtreg-autopkgtest.sh openjdk-17-17.0.8+7/debian/tests/jtreg-autopkgtest.sh --- openjdk-17-17.0.7+7~us1/debian/tests/jtreg-autopkgtest.sh 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/tests/jtreg-autopkgtest.sh 2023-07-20 05:37:00.000000000 +0000 @@ -110,6 +110,7 @@ -jdk:${JDK_TO_TEST} \ -vmoption:-Dtest.boot.jdk=${BOOTJDK_HOME} \ -vmoption:-XX:MaxRAMPercentage=25 \ + -e:NSS_DEFAULT_DB_TYPE=sql \ ${on_retry:-} $@ \ && exit_code=0 || exit_code=$? diff -Nru openjdk-17-17.0.7+7~us1/debian/tests/problems-armhf.txt openjdk-17-17.0.8+7/debian/tests/problems-armhf.txt --- openjdk-17-17.0.7+7~us1/debian/tests/problems-armhf.txt 2023-05-01 14:42:31.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/tests/problems-armhf.txt 2023-07-20 09:03:02.000000000 +0000 @@ -19,4 +19,12 @@ jdk/sun/security/rsa/SignedObjectChain.java 000000 generic-all sun/security/ec/ed/EdDSATest.java 000000 generic-all -java/security/SignedObject/Chain.java 000000 generic-all \ No newline at end of file +java/security/SignedObject/Chain.java 000000 generic-all + +# JDK-8311092 - native stack not implemented for armhf, disable test +runtime/jni/nativeStack/TestNativeStack.java 8311092 generic-all + +# timeout in SSL connection +java/net/httpclient/ManyRequestsLegacy.java 000000 generic-all +# deadlock +java/util/Random/RandomTestBsi1999.java 000000 generic-all diff -Nru openjdk-17-17.0.7+7~us1/debian/watch openjdk-17-17.0.8+7/debian/watch --- openjdk-17-17.0.7+7~us1/debian/watch 2023-03-26 22:36:50.000000000 +0000 +++ openjdk-17-17.0.8+7/debian/watch 2023-07-05 18:14:41.000000000 +0000 @@ -1,8 +1,6 @@ version=4 opts=\ repack,\ -compression=xz,\ -repacksuffix=~us1,\ -dversionmangle=s/~\d*\~us\d*$/\+\d*/, \ +compression=xz \ https://github.com/openjdk/jdk17u/tags \ (?:.*?/)?jdk-(\d[\d.]*\+\d[\d]*)\.tar\.gz diff -Nru openjdk-17-17.0.7+7~us1/doc/building.html openjdk-17-17.0.8+7/doc/building.html --- openjdk-17-17.0.7+7~us1/doc/building.html 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/doc/building.html 2023-07-05 07:11:54.000000000 +0000 @@ -273,7 +273,7 @@ Linux -gcc 10.2.0 +gcc 11.2.0 macOS @@ -288,7 +288,7 @@

All compilers are expected to be able to compile to the C99 language standard, as some C99 features are used in the source code. Microsoft Visual Studio doesn't fully support C99 so in practice shared code is limited to using C99 features that it does support.

gcc

The minimum accepted version of gcc is 5.0. Older versions will generate a warning by configure and are unlikely to work.

-

The JDK is currently known to be able to compile with at least version 10.2 of gcc.

+

The JDK is currently known to be able to compile with at least version 11.2 of gcc.

In general, any version between these two should be usable.

clang

The minimum accepted version of clang is 3.5. Older versions will not be accepted by configure.

diff -Nru openjdk-17-17.0.7+7~us1/doc/building.md openjdk-17-17.0.8+7/doc/building.md --- openjdk-17-17.0.7+7~us1/doc/building.md 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/doc/building.md 2023-07-05 07:11:54.000000000 +0000 @@ -321,7 +321,7 @@ | Operating system | Toolchain version | | ------------------ | ------------------------------------------ | -| Linux | gcc 10.2.0 | +| Linux | gcc 11.2.0 | | macOS | Apple Xcode 10.1 (using clang 10.0.0) | | Windows | Microsoft Visual Studio 2022 update 17.1.0 | @@ -335,7 +335,7 @@ The minimum accepted version of gcc is 5.0. Older versions will generate a warning by `configure` and are unlikely to work. -The JDK is currently known to be able to compile with at least version 10.2 of +The JDK is currently known to be able to compile with at least version 11.2 of gcc. In general, any version between these two should be usable. diff -Nru openjdk-17-17.0.7+7~us1/doc/testing.html openjdk-17-17.0.8+7/doc/testing.html --- openjdk-17-17.0.7+7~us1/doc/testing.html 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/doc/testing.html 2023-07-05 07:11:54.000000000 +0000 @@ -242,14 +242,39 @@ JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs"

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

Client UI Tests

+

System key shortcuts

Some Client UI tests use key sequences which may be reserved by the operating system. Usually that causes the test failure. So it is highly recommended to disable system key shortcuts prior testing. The steps to access and disable system key shortcuts for various platforms are provided below.

-

MacOS

+
MacOS

Choose Apple menu; System Preferences, click Keyboard, then click Shortcuts; select or deselect desired shortcut.

For example, test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java fails on MacOS because it uses CTRL + F1 key sequence to show or hide tooltip message but the key combination is reserved by the operating system. To run the test correctly the default global key shortcut should be disabled using the steps described above, and then deselect "Turn keyboard access on or off" option which is responsible for CTRL + F1 combination.

-

Linux

+
Linux

Open the Activities overview and start typing Settings; Choose Settings, click Devices, then click Keyboard; set or override desired shortcut.

-

Windows

+
Windows

Type gpedit in the Search and then click Edit group policy; navigate to User Configuration -> Administrative Templates -> Windows Components -> File Explorer; in the right-side pane look for "Turn off Windows key hotkeys" and double click on it; enable or disable hotkeys.

Note: restart is required to make the settings take effect.

+

Robot API

+

Most automated Client UI tests use Robot API to control +the UI. Usually, the default operating system settings need to be +adjusted for Robot to work correctly. The detailed steps how to access +and update these settings for different platforms are provided +below.

+
macOS
+

Robot is not permitted to control your Mac by default +since macOS 10.15. To allow it, choose Apple menu -> System Settings, +click Privacy & Security; then click Accessibility and ensure the +following apps are allowed to control your computer: Java and +Terminal. If the tests are run from an IDE, the IDE should be +granted this permission too.

+
Windows
+

On Windows if Cygwin terminal is used to run the tests, there is a +delay in focus transfer. Usually it causes automated UI test failure. To +disable the delay, type regedit in the Search and then +select Registry Editor; navigate to the following key: +HKEY_CURRENT_USER\Control Panel\Desktop; make sure the +ForegroundLockTimeout value is set to 0.

+

Additional information about Client UI tests configuration for +various operating systems can be obtained at Automated +client GUI testing system set up requirements

diff -Nru openjdk-17-17.0.7+7~us1/doc/testing.md openjdk-17-17.0.8+7/doc/testing.md --- openjdk-17-17.0.7+7~us1/doc/testing.md 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/doc/testing.md 2023-07-05 07:11:54.000000000 +0000 @@ -546,12 +546,14 @@ ### Client UI Tests +#### System key shortcuts + Some Client UI tests use key sequences which may be reserved by the operating system. Usually that causes the test failure. So it is highly recommended to disable system key shortcuts prior testing. The steps to access and disable system key shortcuts for various platforms are provided below. -#### MacOS +##### macOS Choose Apple menu; System Preferences, click Keyboard, then click Shortcuts; select or deselect desired shortcut. @@ -564,12 +566,12 @@ steps described above, and then deselect "Turn keyboard access on or off" option which is responsible for `CTRL + F1` combination. -#### Linux +##### Linux Open the Activities overview and start typing Settings; Choose Settings, click Devices, then click Keyboard; set or override desired shortcut. -#### Windows +##### Windows Type `gpedit` in the Search and then click Edit group policy; navigate to User Configuration -> Administrative Templates -> Windows Components -> File @@ -578,6 +580,33 @@ Note: restart is required to make the settings take effect. +#### Robot API + +Most automated Client UI tests use `Robot` API to control the UI. Usually, +the default operating system settings need to be adjusted for Robot +to work correctly. The detailed steps how to access and update these settings +for different platforms are provided below. + +##### macOS + +`Robot` is not permitted to control your Mac by default since +macOS 10.15. To allow it, choose Apple menu -> System Settings, click +Privacy & Security; then click Accessibility and ensure the following apps are +allowed to control your computer: *Java* and *Terminal*. If the tests are run +from an IDE, the IDE should be granted this permission too. + +##### Windows + +On Windows if Cygwin terminal is used to run the tests, there is a delay in +focus transfer. Usually it causes automated UI test failure. To disable the +delay, type `regedit` in the Search and then select Registry Editor; navigate +to the following key: `HKEY_CURRENT_USER\Control Panel\Desktop`; make sure +the `ForegroundLockTimeout` value is set to 0. + +Additional information about Client UI tests configuration for various operating +systems can be obtained at [Automated client GUI testing system set up +requirements](https://wiki.openjdk.org/display/ClientLibs/Automated+client+GUI+testing+system+set+up+requirements) + --- # Override some definitions in the global css file that are not optimal for # this document. diff -Nru openjdk-17-17.0.7+7~us1/.gitignore openjdk-17-17.0.8+7/.gitignore --- openjdk-17-17.0.7+7~us1/.gitignore 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/.gitignore 2023-07-05 07:11:54.000000000 +0000 @@ -18,3 +18,5 @@ /src/utils/LogCompilation/target/ /.project/ /.settings/ +/compile_commands.json +/.cache diff -Nru openjdk-17-17.0.7+7~us1/.jcheck/conf openjdk-17-17.0.8+7/.jcheck/conf --- openjdk-17-17.0.7+7~us1/.jcheck/conf 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/.jcheck/conf 2023-07-05 07:11:54.000000000 +0000 @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=17.0.7 +version=17.0.8 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff -Nru openjdk-17-17.0.7+7~us1/make/autoconf/basic.m4 openjdk-17-17.0.8+7/make/autoconf/basic.m4 --- openjdk-17-17.0.7+7~us1/make/autoconf/basic.m4 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/autoconf/basic.m4 2023-07-05 07:11:54.000000000 +0000 @@ -55,6 +55,7 @@ ############################################################################### # Setup basic configuration paths, and platform-specific stuff related to PATHs. +# Make sure to only use tools set up in BASIC_SETUP_FUNDAMENTAL_TOOLS. AC_DEFUN_ONCE([BASIC_SETUP_PATHS], [ # Save the current directory this script was started from diff -Nru openjdk-17-17.0.7+7~us1/make/autoconf/basic_tools.m4 openjdk-17-17.0.8+7/make/autoconf/basic_tools.m4 --- openjdk-17-17.0.7+7~us1/make/autoconf/basic_tools.m4 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/autoconf/basic_tools.m4 2023-07-05 07:11:54.000000000 +0000 @@ -24,8 +24,8 @@ # ############################################################################### -# Setup the most fundamental tools that relies on not much else to set up, -# but is used by much of the early bootstrap code. +# Setup the most fundamental tools, used for setting up build platform and +# path handling. AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], [ # Bootstrapping: These tools are needed by UTIL_LOOKUP_PROGS @@ -37,7 +37,28 @@ UTIL_CHECK_NONEMPTY(FILE) AC_PATH_PROGS(LDD, ldd) - # First are all the fundamental required tools. + # Required tools + UTIL_REQUIRE_PROGS(ECHO, echo) + UTIL_REQUIRE_PROGS(TR, tr) + UTIL_REQUIRE_PROGS(UNAME, uname) + UTIL_REQUIRE_PROGS(WC, wc) + + # Required tools with some special treatment + UTIL_REQUIRE_SPECIAL(GREP, [AC_PROG_GREP]) + UTIL_REQUIRE_SPECIAL(EGREP, [AC_PROG_EGREP]) + UTIL_REQUIRE_SPECIAL(SED, [AC_PROG_SED]) + + # Tools only needed on some platforms + UTIL_LOOKUP_PROGS(PATHTOOL, cygpath wslpath) + UTIL_LOOKUP_PROGS(CMD, cmd.exe, $PATH:/cygdrive/c/windows/system32:/mnt/c/windows/system32:/c/windows/system32) +]) + +############################################################################### +# Setup further tools that should be resolved early but after setting up +# build platform and path handling. +AC_DEFUN_ONCE([BASIC_SETUP_TOOLS], +[ + # Required tools UTIL_REQUIRE_PROGS(BASH, bash) UTIL_REQUIRE_PROGS(CAT, cat) UTIL_REQUIRE_PROGS(CHMOD, chmod) @@ -45,7 +66,6 @@ UTIL_REQUIRE_PROGS(CUT, cut) UTIL_REQUIRE_PROGS(DATE, date) UTIL_REQUIRE_PROGS(DIFF, gdiff diff) - UTIL_REQUIRE_PROGS(ECHO, echo) UTIL_REQUIRE_PROGS(EXPR, expr) UTIL_REQUIRE_PROGS(FIND, find) UTIL_REQUIRE_PROGS(GUNZIP, gunzip) @@ -67,26 +87,18 @@ UTIL_REQUIRE_PROGS(TAR, gtar tar) UTIL_REQUIRE_PROGS(TEE, tee) UTIL_REQUIRE_PROGS(TOUCH, touch) - UTIL_REQUIRE_PROGS(TR, tr) - UTIL_REQUIRE_PROGS(UNAME, uname) - UTIL_REQUIRE_PROGS(WC, wc) UTIL_REQUIRE_PROGS(XARGS, xargs) - # Then required tools that require some special treatment. - UTIL_REQUIRE_SPECIAL(GREP, [AC_PROG_GREP]) - UTIL_REQUIRE_SPECIAL(EGREP, [AC_PROG_EGREP]) + # Required tools with some special treatment UTIL_REQUIRE_SPECIAL(FGREP, [AC_PROG_FGREP]) - UTIL_REQUIRE_SPECIAL(SED, [AC_PROG_SED]) # Optional tools, we can do without them UTIL_LOOKUP_PROGS(DF, df) UTIL_LOOKUP_PROGS(NICE, nice) UTIL_LOOKUP_PROGS(READLINK, greadlink readlink) - # These are only needed on some platforms - UTIL_LOOKUP_PROGS(PATHTOOL, cygpath wslpath) + # Tools only needed on some platforms UTIL_LOOKUP_PROGS(LSB_RELEASE, lsb_release) - UTIL_LOOKUP_PROGS(CMD, cmd.exe, $PATH:/cygdrive/c/windows/system32:/mnt/c/windows/system32:/c/windows/system32) # For compare.sh only UTIL_LOOKUP_PROGS(CMP, cmp) diff -Nru openjdk-17-17.0.7+7~us1/make/autoconf/configure.ac openjdk-17-17.0.8+7/make/autoconf/configure.ac --- openjdk-17-17.0.7+7~us1/make/autoconf/configure.ac 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/autoconf/configure.ac 2023-07-05 07:11:54.000000000 +0000 @@ -86,6 +86,7 @@ # Continue setting up basic stuff. Most remaining code require fundamental tools. BASIC_SETUP_PATHS +BASIC_SETUP_TOOLS # Check if it's a pure open build or if custom sources are to be used. JDKOPT_SETUP_OPEN_OR_CUSTOM diff -Nru openjdk-17-17.0.7+7~us1/make/autoconf/flags-cflags.m4 openjdk-17-17.0.8+7/make/autoconf/flags-cflags.m4 --- openjdk-17-17.0.7+7~us1/make/autoconf/flags-cflags.m4 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/autoconf/flags-cflags.m4 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -188,6 +188,10 @@ WARNINGS_ENABLE_ALL_CXXFLAGS="$WARNINGS_ENABLE_ALL_CFLAGS $WARNINGS_ENABLE_ADDITIONAL_CXX" DISABLED_WARNINGS="unused-parameter unused" + # gcc10/11 on ppc generate lots of abi warnings about layout of aggregates containing vectors + if test "x$OPENJDK_TARGET_CPU_ARCH" = "xppc"; then + DISABLED_WARNINGS="$DISABLED_WARNINGS psabi" + fi ;; clang) diff -Nru openjdk-17-17.0.7+7~us1/make/autoconf/jvm-features.m4 openjdk-17-17.0.8+7/make/autoconf/jvm-features.m4 --- openjdk-17-17.0.7+7~us1/make/autoconf/jvm-features.m4 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/autoconf/jvm-features.m4 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -248,8 +248,11 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_DTRACE], [ JVM_FEATURES_CHECK_AVAILABILITY(dtrace, [ - AC_MSG_CHECKING([for dtrace tool]) - if test "x$DTRACE" != "x" && test -x "$DTRACE"; then + AC_MSG_CHECKING([for dtrace tool and platform support]) + if test "x$OPENJDK_TARGET_CPU_ARCH" = "xppc"; then + AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU_ARCH]) + AVAILABLE=false + elif test "x$DTRACE" != "x" && test -x "$DTRACE"; then AC_MSG_RESULT([$DTRACE]) else AC_MSG_RESULT([no]) diff -Nru openjdk-17-17.0.7+7~us1/make/autoconf/libraries.m4 openjdk-17-17.0.8+7/make/autoconf/libraries.m4 --- openjdk-17-17.0.7+7~us1/make/autoconf/libraries.m4 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/autoconf/libraries.m4 2023-07-05 07:11:54.000000000 +0000 @@ -153,7 +153,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then BASIC_JVM_LIBS="$BASIC_JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \ - comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib powrprof.lib uuid.lib \ wsock32.lib winmm.lib version.lib psapi.lib" fi diff -Nru openjdk-17-17.0.7+7~us1/make/autoconf/platform.m4 openjdk-17-17.0.8+7/make/autoconf/platform.m4 --- openjdk-17-17.0.7+7~us1/make/autoconf/platform.m4 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/autoconf/platform.m4 2023-07-05 07:11:54.000000000 +0000 @@ -632,6 +632,7 @@ ]) #%%% Build and target systems %%% +# Make sure to only use tools set up in BASIC_SETUP_FUNDAMENTAL_TOOLS. AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_BUILD_AND_TARGET], [ # Figure out the build and target systems. # Note that in autoconf terminology, "build" is obvious, but "target" @@ -718,7 +719,7 @@ [ ############################################################################### # - # Is the target little of big endian? + # Is the target little or big endian? # AC_C_BIGENDIAN([ENDIAN="big"],[ENDIAN="little"],[ENDIAN="unknown"],[ENDIAN="universal_endianness"]) diff -Nru openjdk-17-17.0.7+7~us1/make/common/NativeCompilation.gmk openjdk-17-17.0.8+7/make/common/NativeCompilation.gmk --- openjdk-17-17.0.7+7~us1/make/common/NativeCompilation.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/common/NativeCompilation.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -343,10 +343,15 @@ endif endif + ifneq ($(DISABLE_WARNING_PREFIX), ) + $1_WARNINGS_FLAGS := $$(addprefix $(DISABLE_WARNING_PREFIX), \ + $$($$($1_BASE)_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)_$$($1_FILENAME))) + endif + $1_BASE_CFLAGS := $$($$($1_BASE)_CFLAGS) $$($$($1_BASE)_EXTRA_CFLAGS) \ - $$($$($1_BASE)_SYSROOT_CFLAGS) + $$($$($1_BASE)_SYSROOT_CFLAGS) $$($1_WARNINGS_FLAGS) $1_BASE_CXXFLAGS := $$($$($1_BASE)_CXXFLAGS) $$($$($1_BASE)_EXTRA_CXXFLAGS) \ - $$($$($1_BASE)_SYSROOT_CFLAGS) $$($1_EXTRA_CXXFLAGS) + $$($$($1_BASE)_SYSROOT_CFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_WARNINGS_FLAGS) $1_BASE_ASFLAGS := $$($$($1_BASE)_ASFLAGS) $$($$($1_BASE)_EXTRA_ASFLAGS) ifneq ($$(filter %.c, $$($1_FILENAME)), ) diff -Nru openjdk-17-17.0.7+7~us1/make/conf/jib-profiles.js openjdk-17-17.0.8+7/make/conf/jib-profiles.js --- openjdk-17-17.0.7+7~us1/make/conf/jib-profiles.js 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/conf/jib-profiles.js 2023-07-05 07:11:54.000000000 +0000 @@ -1048,10 +1048,10 @@ var getJibProfilesDependencies = function (input, common) { var devkit_platform_revisions = { - linux_x64: "gcc10.3.0-OL6.4+1.0", + linux_x64: "gcc11.2.0-OL6.4+1.0", macosx: "Xcode12.4+1.0", windows_x64: "VS2022-17.1.0+1.0", - linux_aarch64: "gcc10.3.0-OL7.6+1.0", + linux_aarch64: "gcc11.2.0-OL7.6+1.0", linux_arm: "gcc8.2.0-Fedora27+1.0", linux_ppc64le: "gcc8.2.0-Fedora27+1.0", linux_s390x: "gcc8.2.0-Fedora27+1.0" diff -Nru openjdk-17-17.0.7+7~us1/make/conf/version-numbers.conf openjdk-17-17.0.8+7/make/conf/version-numbers.conf --- openjdk-17-17.0.7+7~us1/make/conf/version-numbers.conf 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/conf/version-numbers.conf 2023-07-05 07:11:54.000000000 +0000 @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=17 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=7 +DEFAULT_VERSION_UPDATE=8 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2023-04-18 +DEFAULT_VERSION_DATE=2023-07-18 DEFAULT_VERSION_CLASSFILE_MAJOR=61 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 diff -Nru openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootcar1 openjdk-17-17.0.8+7/make/data/cacerts/gtsrootcar1 --- openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootcar1 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/cacerts/gtsrootcar1 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,38 @@ +Owner: CN=GTS Root R1, O=Google Trust Services LLC, C=US +Issuer: CN=GTS Root R1, O=Google Trust Services LLC, C=US +Serial number: 203e5936f31b01349886ba217 +Valid from: Wed Jun 22 00:00:00 GMT 2016 until: Sun Jun 22 00:00:00 GMT 2036 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootcar2 openjdk-17-17.0.8+7/make/data/cacerts/gtsrootcar2 --- openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootcar2 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/cacerts/gtsrootcar2 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,38 @@ +Owner: CN=GTS Root R2, O=Google Trust Services LLC, C=US +Issuer: CN=GTS Root R2, O=Google Trust Services LLC, C=US +Serial number: 203e5aec58d04251aab1125aa +Valid from: Wed Jun 22 00:00:00 GMT 2016 until: Sun Jun 22 00:00:00 GMT 2036 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL +-----END CERTIFICATE----- \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootecccar3 openjdk-17-17.0.8+7/make/data/cacerts/gtsrootecccar3 --- openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootecccar3 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/cacerts/gtsrootecccar3 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,20 @@ +Owner: CN=GTS Root R3, O=Google Trust Services LLC, C=US +Issuer: CN=GTS Root R3, O=Google Trust Services LLC, C=US +Serial number: 203e5b882eb20f825276d3d66 +Valid from: Wed Jun 22 00:00:00 GMT 2016 until: Sun Jun 22 00:00:00 GMT 2036 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootecccar4 openjdk-17-17.0.8+7/make/data/cacerts/gtsrootecccar4 --- openjdk-17-17.0.7+7~us1/make/data/cacerts/gtsrootecccar4 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/cacerts/gtsrootecccar4 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,20 @@ +Owner: CN=GTS Root R4, O=Google Trust Services LLC, C=US +Issuer: CN=GTS Root R4, O=Google Trust Services LLC, C=US +Serial number: 203e5c068ef631a9c72905052 +Valid from: Wed Jun 22 00:00:00 GMT 2016 until: Sun Jun 22 00:00:00 GMT 2036 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/make/data/cacerts/microsoftecc2017 openjdk-17-17.0.8+7/make/data/cacerts/microsoftecc2017 --- openjdk-17-17.0.7+7~us1/make/data/cacerts/microsoftecc2017 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/cacerts/microsoftecc2017 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,22 @@ +Owner: CN=Microsoft ECC Root Certificate Authority 2017, O=Microsoft Corporation, C=US +Issuer: CN=Microsoft ECC Root Certificate Authority 2017, O=Microsoft Corporation, C=US +Serial number: 66f23daf87de8bb14aea0c573101c2ec +Valid from: Wed Dec 18 23:06:45 GMT 2019 until: Fri Jul 18 23:16:04 GMT 2042 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- diff -Nru openjdk-17-17.0.7+7~us1/make/data/cacerts/microsoftrsa2017 openjdk-17-17.0.8+7/make/data/cacerts/microsoftrsa2017 --- openjdk-17-17.0.7+7~us1/make/data/cacerts/microsoftrsa2017 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/cacerts/microsoftrsa2017 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +Owner: CN=Microsoft RSA Root Certificate Authority 2017, O=Microsoft Corporation, C=US +Issuer: CN=Microsoft RSA Root Certificate Authority 2017, O=Microsoft Corporation, C=US +Serial number: 1ed397095fd8b4b347701eaabe7f45b3 +Valid from: Wed Dec 18 22:51:22 GMT 2019 until: Fri Jul 18 23:00:23 GMT 2042 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- diff -Nru openjdk-17-17.0.7+7~us1/make/data/cacerts/twcaglobalrootca openjdk-17-17.0.8+7/make/data/cacerts/twcaglobalrootca --- openjdk-17-17.0.7+7~us1/make/data/cacerts/twcaglobalrootca 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/cacerts/twcaglobalrootca 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,38 @@ +Owner: CN=TWCA Global Root CA, OU=Root CA, O=TAIWAN-CA, C=TW +Issuer: CN=TWCA Global Root CA, OU=Root CA, O=TAIWAN-CA, C=TW +Serial number: cbe +Valid from: Wed Jun 27 06:28:33 GMT 2012 until: Tue Dec 31 15:59:59 GMT 2030 +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- diff -Nru openjdk-17-17.0.7+7~us1/make/data/charsetmapping/charsets openjdk-17-17.0.8+7/make/data/charsetmapping/charsets --- openjdk-17-17.0.7+7~us1/make/data/charsetmapping/charsets 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/charsetmapping/charsets 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -477,6 +477,11 @@ alias ibm-874 alias 874 +# alias for GB18030 is generated at runtime +charset GB18030 GB18030 + package sun.nio.cs + type source + ######################################################## # # charsets provided by ExtendedCharsets provider. @@ -564,11 +569,6 @@ alias windows-936 alias CP936 -charset GB18030 GB18030 - package sun.nio.cs.ext - type template - alias gb18030-2000 - charset GB2312 EUC_CN package sun.nio.cs.ext type dbcs diff -Nru openjdk-17-17.0.7+7~us1/make/data/charsetmapping/GB18030.map openjdk-17-17.0.8+7/make/data/charsetmapping/GB18030.map --- openjdk-17-17.0.7+7~us1/make/data/charsetmapping/GB18030.map 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/charsetmapping/GB18030.map 1970-01-01 00:00:00.000000000 +0000 @@ -1,63491 +0,0 @@ -# GB18030.java is NOT generated from this mapping right now. This -# map is here for testing only. -# -00 0000 -01 0001 -02 0002 -03 0003 -04 0004 -05 0005 -06 0006 -07 0007 -08 0008 -09 0009 -0A 000A -0B 000B -0C 000C -0D 000D -0E 000E -0F 000F -10 0010 -11 0011 -12 0012 -13 0013 -14 0014 -15 0015 -16 0016 -17 0017 -18 0018 -19 0019 -1A 001A -1B 001B -1C 001C -1D 001D -1E 001E -1F 001F -20 0020 -21 0021 -22 0022 -23 0023 -24 0024 -25 0025 -26 0026 -27 0027 -28 0028 -29 0029 -2A 002A -2B 002B -2C 002C -2D 002D -2E 002E -2F 002F -30 0030 -31 0031 -32 0032 -33 0033 -34 0034 -35 0035 -36 0036 -37 0037 -38 0038 -39 0039 -3A 003A -3B 003B -3C 003C -3D 003D -3E 003E -3F 003F -40 0040 -41 0041 -42 0042 -43 0043 -44 0044 -45 0045 -46 0046 -47 0047 -48 0048 -49 0049 -4A 004A -4B 004B -4C 004C -4D 004D -4E 004E -4F 004F -50 0050 -51 0051 -52 0052 -53 0053 -54 0054 -55 0055 -56 0056 -57 0057 -58 0058 -59 0059 -5A 005A -5B 005B -5C 005C -5D 005D -5E 005E -5F 005F -60 0060 -61 0061 -62 0062 -63 0063 -64 0064 -65 0065 -66 0066 -67 0067 -68 0068 -69 0069 -6A 006A -6B 006B -6C 006C -6D 006D -6E 006E -6F 006F -70 0070 -71 0071 -72 0072 -73 0073 -74 0074 -75 0075 -76 0076 -77 0077 -78 0078 -79 0079 -7A 007A -7B 007B -7C 007C -7D 007D -7E 007E -7F 007F -81308130 0080 -81308131 0081 -81308132 0082 -81308133 0083 -81308134 0084 -81308135 0085 -81308136 0086 -81308137 0087 -81308138 0088 -81308139 0089 -81308230 008A -81308231 008B -81308232 008C -81308233 008D -81308234 008E -81308235 008F -81308236 0090 -81308237 0091 -81308238 0092 -81308239 0093 -81308330 0094 -81308331 0095 -81308332 0096 -81308333 0097 -81308334 0098 -81308335 0099 -81308336 009A -81308337 009B -81308338 009C -81308339 009D -81308430 009E -81308431 009F -81308432 00A0 -81308433 00A1 -81308434 00A2 -81308435 00A3 -A1E8 00A4 -81308436 00A5 -81308437 00A6 -A1EC 00A7 -A1A7 00A8 -81308438 00A9 -81308439 00AA -81308530 00AB -81308531 00AC -81308532 00AD -81308533 00AE -81308534 00AF -A1E3 00B0 -A1C0 00B1 -81308535 00B2 -81308536 00B3 -81308537 00B4 -81308538 00B5 -81308539 00B6 -A1A4 00B7 -81308630 00B8 -81308631 00B9 -81308632 00BA -81308633 00BB -81308634 00BC -81308635 00BD -81308636 00BE -81308637 00BF -81308638 00C0 -81308639 00C1 -81308730 00C2 -81308731 00C3 -81308732 00C4 -81308733 00C5 -81308734 00C6 -81308735 00C7 -81308736 00C8 -81308737 00C9 -81308738 00CA -81308739 00CB -81308830 00CC -81308831 00CD -81308832 00CE -81308833 00CF -81308834 00D0 -81308835 00D1 -81308836 00D2 -81308837 00D3 -81308838 00D4 -81308839 00D5 -81308930 00D6 -A1C1 00D7 -81308931 00D8 -81308932 00D9 -81308933 00DA -81308934 00DB -81308935 00DC -81308936 00DD -81308937 00DE -81308938 00DF -A8A4 00E0 -A8A2 00E1 -81308939 00E2 -81308A30 00E3 -81308A31 00E4 -81308A32 00E5 -81308A33 00E6 -81308A34 00E7 -A8A8 00E8 -A8A6 00E9 -A8BA 00EA -81308A35 00EB -A8AC 00EC -A8AA 00ED -81308A36 00EE -81308A37 00EF -81308A38 00F0 -81308A39 00F1 -A8B0 00F2 -A8AE 00F3 -81308B30 00F4 -81308B31 00F5 -81308B32 00F6 -A1C2 00F7 -81308B33 00F8 -A8B4 00F9 -A8B2 00FA -81308B34 00FB -A8B9 00FC -81308B35 00FD -81308B36 00FE -81308B37 00FF -81308B38 0100 -A8A1 0101 -81308B39 0102 -81308C30 0103 -81308C31 0104 -81308C32 0105 -81308C33 0106 -81308C34 0107 -81308C35 0108 -81308C36 0109 -81308C37 010A -81308C38 010B -81308C39 010C -81308D30 010D -81308D31 010E -81308D32 010F -81308D33 0110 -81308D34 0111 -81308D35 0112 -A8A5 0113 -81308D36 0114 -81308D37 0115 -81308D38 0116 -81308D39 0117 -81308E30 0118 -81308E31 0119 -81308E32 011A -A8A7 011B -81308E33 011C -81308E34 011D -81308E35 011E -81308E36 011F -81308E37 0120 -81308E38 0121 -81308E39 0122 -81308F30 0123 -81308F31 0124 -81308F32 0125 -81308F33 0126 -81308F34 0127 -81308F35 0128 -81308F36 0129 -81308F37 012A -A8A9 012B -81308F38 012C -81308F39 012D -81309030 012E -81309031 012F -81309032 0130 -81309033 0131 -81309034 0132 -81309035 0133 -81309036 0134 -81309037 0135 -81309038 0136 -81309039 0137 -81309130 0138 -81309131 0139 -81309132 013A -81309133 013B -81309134 013C -81309135 013D -81309136 013E -81309137 013F -81309138 0140 -81309139 0141 -81309230 0142 -81309231 0143 -A8BD 0144 -81309232 0145 -81309233 0146 -81309234 0147 -A8BE 0148 -81309235 0149 -81309236 014A -81309237 014B -81309238 014C -A8AD 014D -81309239 014E -81309330 014F -81309331 0150 -81309332 0151 -81309333 0152 -81309334 0153 -81309335 0154 -81309336 0155 -81309337 0156 -81309338 0157 -81309339 0158 -81309430 0159 -81309431 015A -81309432 015B -81309433 015C -81309434 015D -81309435 015E -81309436 015F -81309437 0160 -81309438 0161 -81309439 0162 -81309530 0163 -81309531 0164 -81309532 0165 -81309533 0166 -81309534 0167 -81309535 0168 -81309536 0169 -81309537 016A -A8B1 016B -81309538 016C -81309539 016D -81309630 016E -81309631 016F -81309632 0170 -81309633 0171 -81309634 0172 -81309635 0173 -81309636 0174 -81309637 0175 -81309638 0176 -81309639 0177 -81309730 0178 -81309731 0179 -81309732 017A -81309733 017B -81309734 017C -81309735 017D -81309736 017E -81309737 017F -81309738 0180 -81309739 0181 -81309830 0182 -81309831 0183 -81309832 0184 -81309833 0185 -81309834 0186 -81309835 0187 -81309836 0188 -81309837 0189 -81309838 018A -81309839 018B -81309930 018C -81309931 018D -81309932 018E -81309933 018F -81309934 0190 -81309935 0191 -81309936 0192 -81309937 0193 -81309938 0194 -81309939 0195 -81309A30 0196 -81309A31 0197 -81309A32 0198 -81309A33 0199 -81309A34 019A -81309A35 019B -81309A36 019C -81309A37 019D -81309A38 019E -81309A39 019F -81309B30 01A0 -81309B31 01A1 -81309B32 01A2 -81309B33 01A3 -81309B34 01A4 -81309B35 01A5 -81309B36 01A6 -81309B37 01A7 -81309B38 01A8 -81309B39 01A9 -81309C30 01AA -81309C31 01AB -81309C32 01AC -81309C33 01AD -81309C34 01AE -81309C35 01AF -81309C36 01B0 -81309C37 01B1 -81309C38 01B2 -81309C39 01B3 -81309D30 01B4 -81309D31 01B5 -81309D32 01B6 -81309D33 01B7 -81309D34 01B8 -81309D35 01B9 -81309D36 01BA -81309D37 01BB -81309D38 01BC -81309D39 01BD -81309E30 01BE -81309E31 01BF -81309E32 01C0 -81309E33 01C1 -81309E34 01C2 -81309E35 01C3 -81309E36 01C4 -81309E37 01C5 -81309E38 01C6 -81309E39 01C7 -81309F30 01C8 -81309F31 01C9 -81309F32 01CA -81309F33 01CB -81309F34 01CC -81309F35 01CD -A8A3 01CE -81309F36 01CF -A8AB 01D0 -81309F37 01D1 -A8AF 01D2 -81309F38 01D3 -A8B3 01D4 -81309F39 01D5 -A8B5 01D6 -8130A030 01D7 -A8B6 01D8 -8130A031 01D9 -A8B7 01DA -8130A032 01DB -A8B8 01DC -8130A033 01DD -8130A034 01DE -8130A035 01DF -8130A036 01E0 -8130A037 01E1 -8130A038 01E2 -8130A039 01E3 -8130A130 01E4 -8130A131 01E5 -8130A132 01E6 -8130A133 01E7 -8130A134 01E8 -8130A135 01E9 -8130A136 01EA -8130A137 01EB -8130A138 01EC -8130A139 01ED -8130A230 01EE -8130A231 01EF -8130A232 01F0 -8130A233 01F1 -8130A234 01F2 -8130A235 01F3 -8130A236 01F4 -8130A237 01F5 -8130A238 01F6 -8130A239 01F7 -8130A330 01F8 -A8BF 01F9 -8130A331 01FA -8130A332 01FB -8130A333 01FC -8130A334 01FD -8130A335 01FE -8130A336 01FF -8130A337 0200 -8130A338 0201 -8130A339 0202 -8130A430 0203 -8130A431 0204 -8130A432 0205 -8130A433 0206 -8130A434 0207 -8130A435 0208 -8130A436 0209 -8130A437 020A -8130A438 020B -8130A439 020C -8130A530 020D -8130A531 020E -8130A532 020F -8130A533 0210 -8130A534 0211 -8130A535 0212 -8130A536 0213 -8130A537 0214 -8130A538 0215 -8130A539 0216 -8130A630 0217 -8130A631 0218 -8130A632 0219 -8130A633 021A -8130A634 021B -8130A635 021C -8130A636 021D -8130A637 021E -8130A638 021F -8130A639 0220 -8130A730 0221 -8130A731 0222 -8130A732 0223 -8130A733 0224 -8130A734 0225 -8130A735 0226 -8130A736 0227 -8130A737 0228 -8130A738 0229 -8130A739 022A -8130A830 022B -8130A831 022C -8130A832 022D -8130A833 022E -8130A834 022F -8130A835 0230 -8130A836 0231 -8130A837 0232 -8130A838 0233 -8130A839 0234 -8130A930 0235 -8130A931 0236 -8130A932 0237 -8130A933 0238 -8130A934 0239 -8130A935 023A -8130A936 023B -8130A937 023C -8130A938 023D -8130A939 023E -8130AA30 023F -8130AA31 0240 -8130AA32 0241 -8130AA33 0242 -8130AA34 0243 -8130AA35 0244 -8130AA36 0245 -8130AA37 0246 -8130AA38 0247 -8130AA39 0248 -8130AB30 0249 -8130AB31 024A -8130AB32 024B -8130AB33 024C -8130AB34 024D -8130AB35 024E -8130AB36 024F -8130AB37 0250 -A8BB 0251 -8130AB38 0252 -8130AB39 0253 -8130AC30 0254 -8130AC31 0255 -8130AC32 0256 -8130AC33 0257 -8130AC34 0258 -8130AC35 0259 -8130AC36 025A -8130AC37 025B -8130AC38 025C -8130AC39 025D -8130AD30 025E -8130AD31 025F -8130AD32 0260 -A8C0 0261 -8130AD33 0262 -8130AD34 0263 -8130AD35 0264 -8130AD36 0265 -8130AD37 0266 -8130AD38 0267 -8130AD39 0268 -8130AE30 0269 -8130AE31 026A -8130AE32 026B -8130AE33 026C -8130AE34 026D -8130AE35 026E -8130AE36 026F -8130AE37 0270 -8130AE38 0271 -8130AE39 0272 -8130AF30 0273 -8130AF31 0274 -8130AF32 0275 -8130AF33 0276 -8130AF34 0277 -8130AF35 0278 -8130AF36 0279 -8130AF37 027A -8130AF38 027B -8130AF39 027C -8130B030 027D -8130B031 027E -8130B032 027F -8130B033 0280 -8130B034 0281 -8130B035 0282 -8130B036 0283 -8130B037 0284 -8130B038 0285 -8130B039 0286 -8130B130 0287 -8130B131 0288 -8130B132 0289 -8130B133 028A -8130B134 028B -8130B135 028C -8130B136 028D -8130B137 028E -8130B138 028F -8130B139 0290 -8130B230 0291 -8130B231 0292 -8130B232 0293 -8130B233 0294 -8130B234 0295 -8130B235 0296 -8130B236 0297 -8130B237 0298 -8130B238 0299 -8130B239 029A -8130B330 029B -8130B331 029C -8130B332 029D -8130B333 029E -8130B334 029F -8130B335 02A0 -8130B336 02A1 -8130B337 02A2 -8130B338 02A3 -8130B339 02A4 -8130B430 02A5 -8130B431 02A6 -8130B432 02A7 -8130B433 02A8 -8130B434 02A9 -8130B435 02AA -8130B436 02AB -8130B437 02AC -8130B438 02AD -8130B439 02AE -8130B530 02AF -8130B531 02B0 -8130B532 02B1 -8130B533 02B2 -8130B534 02B3 -8130B535 02B4 -8130B536 02B5 -8130B537 02B6 -8130B538 02B7 -8130B539 02B8 -8130B630 02B9 -8130B631 02BA -8130B632 02BB -8130B633 02BC -8130B634 02BD -8130B635 02BE -8130B636 02BF -8130B637 02C0 -8130B638 02C1 -8130B639 02C2 -8130B730 02C3 -8130B731 02C4 -8130B732 02C5 -8130B733 02C6 -A1A6 02C7 -8130B734 02C8 -A1A5 02C9 -A840 02CA -A841 02CB -8130B735 02CC -8130B736 02CD -8130B737 02CE -8130B738 02CF -8130B739 02D0 -8130B830 02D1 -8130B831 02D2 -8130B832 02D3 -8130B833 02D4 -8130B834 02D5 -8130B835 02D6 -8130B836 02D7 -8130B837 02D8 -A842 02D9 -8130B838 02DA -8130B839 02DB -8130B930 02DC -8130B931 02DD -8130B932 02DE -8130B933 02DF -8130B934 02E0 -8130B935 02E1 -8130B936 02E2 -8130B937 02E3 -8130B938 02E4 -8130B939 02E5 -8130BA30 02E6 -8130BA31 02E7 -8130BA32 02E8 -8130BA33 02E9 -8130BA34 02EA -8130BA35 02EB -8130BA36 02EC -8130BA37 02ED -8130BA38 02EE -8130BA39 02EF -8130BB30 02F0 -8130BB31 02F1 -8130BB32 02F2 -8130BB33 02F3 -8130BB34 02F4 -8130BB35 02F5 -8130BB36 02F6 -8130BB37 02F7 -8130BB38 02F8 -8130BB39 02F9 -8130BC30 02FA -8130BC31 02FB -8130BC32 02FC -8130BC33 02FD -8130BC34 02FE -8130BC35 02FF -8130BC36 0300 -8130BC37 0301 -8130BC38 0302 -8130BC39 0303 -8130BD30 0304 -8130BD31 0305 -8130BD32 0306 -8130BD33 0307 -8130BD34 0308 -8130BD35 0309 -8130BD36 030A -8130BD37 030B -8130BD38 030C -8130BD39 030D -8130BE30 030E -8130BE31 030F -8130BE32 0310 -8130BE33 0311 -8130BE34 0312 -8130BE35 0313 -8130BE36 0314 -8130BE37 0315 -8130BE38 0316 -8130BE39 0317 -8130BF30 0318 -8130BF31 0319 -8130BF32 031A -8130BF33 031B -8130BF34 031C -8130BF35 031D -8130BF36 031E -8130BF37 031F -8130BF38 0320 -8130BF39 0321 -8130C030 0322 -8130C031 0323 -8130C032 0324 -8130C033 0325 -8130C034 0326 -8130C035 0327 -8130C036 0328 -8130C037 0329 -8130C038 032A -8130C039 032B -8130C130 032C -8130C131 032D -8130C132 032E -8130C133 032F -8130C134 0330 -8130C135 0331 -8130C136 0332 -8130C137 0333 -8130C138 0334 -8130C139 0335 -8130C230 0336 -8130C231 0337 -8130C232 0338 -8130C233 0339 -8130C234 033A -8130C235 033B -8130C236 033C -8130C237 033D -8130C238 033E -8130C239 033F -8130C330 0340 -8130C331 0341 -8130C332 0342 -8130C333 0343 -8130C334 0344 -8130C335 0345 -8130C336 0346 -8130C337 0347 -8130C338 0348 -8130C339 0349 -8130C430 034A -8130C431 034B -8130C432 034C -8130C433 034D -8130C434 034E -8130C435 034F -8130C436 0350 -8130C437 0351 -8130C438 0352 -8130C439 0353 -8130C530 0354 -8130C531 0355 -8130C532 0356 -8130C533 0357 -8130C534 0358 -8130C535 0359 -8130C536 035A -8130C537 035B -8130C538 035C -8130C539 035D -8130C630 035E -8130C631 035F -8130C632 0360 -8130C633 0361 -8130C634 0362 -8130C635 0363 -8130C636 0364 -8130C637 0365 -8130C638 0366 -8130C639 0367 -8130C730 0368 -8130C731 0369 -8130C732 036A -8130C733 036B -8130C734 036C -8130C735 036D -8130C736 036E -8130C737 036F -8130C738 0370 -8130C739 0371 -8130C830 0372 -8130C831 0373 -8130C832 0374 -8130C833 0375 -8130C834 0376 -8130C835 0377 -8130C836 0378 -8130C837 0379 -8130C838 037A -8130C839 037B -8130C930 037C -8130C931 037D -8130C932 037E -8130C933 037F -8130C934 0380 -8130C935 0381 -8130C936 0382 -8130C937 0383 -8130C938 0384 -8130C939 0385 -8130CA30 0386 -8130CA31 0387 -8130CA32 0388 -8130CA33 0389 -8130CA34 038A -8130CA35 038B -8130CA36 038C -8130CA37 038D -8130CA38 038E -8130CA39 038F -8130CB30 0390 -A6A1 0391 -A6A2 0392 -A6A3 0393 -A6A4 0394 -A6A5 0395 -A6A6 0396 -A6A7 0397 -A6A8 0398 -A6A9 0399 -A6AA 039A -A6AB 039B -A6AC 039C -A6AD 039D -A6AE 039E -A6AF 039F -A6B0 03A0 -A6B1 03A1 -8130CB31 03A2 -A6B2 03A3 -A6B3 03A4 -A6B4 03A5 -A6B5 03A6 -A6B6 03A7 -A6B7 03A8 -A6B8 03A9 -8130CB32 03AA -8130CB33 03AB -8130CB34 03AC -8130CB35 03AD -8130CB36 03AE -8130CB37 03AF -8130CB38 03B0 -A6C1 03B1 -A6C2 03B2 -A6C3 03B3 -A6C4 03B4 -A6C5 03B5 -A6C6 03B6 -A6C7 03B7 -A6C8 03B8 -A6C9 03B9 -A6CA 03BA -A6CB 03BB -A6CC 03BC -A6CD 03BD -A6CE 03BE -A6CF 03BF -A6D0 03C0 -A6D1 03C1 -8130CB39 03C2 -A6D2 03C3 -A6D3 03C4 -A6D4 03C5 -A6D5 03C6 -A6D6 03C7 -A6D7 03C8 -A6D8 03C9 -8130CC30 03CA -8130CC31 03CB -8130CC32 03CC -8130CC33 03CD -8130CC34 03CE -8130CC35 03CF -8130CC36 03D0 -8130CC37 03D1 -8130CC38 03D2 -8130CC39 03D3 -8130CD30 03D4 -8130CD31 03D5 -8130CD32 03D6 -8130CD33 03D7 -8130CD34 03D8 -8130CD35 03D9 -8130CD36 03DA -8130CD37 03DB -8130CD38 03DC -8130CD39 03DD -8130CE30 03DE -8130CE31 03DF -8130CE32 03E0 -8130CE33 03E1 -8130CE34 03E2 -8130CE35 03E3 -8130CE36 03E4 -8130CE37 03E5 -8130CE38 03E6 -8130CE39 03E7 -8130CF30 03E8 -8130CF31 03E9 -8130CF32 03EA -8130CF33 03EB -8130CF34 03EC -8130CF35 03ED -8130CF36 03EE -8130CF37 03EF -8130CF38 03F0 -8130CF39 03F1 -8130D030 03F2 -8130D031 03F3 -8130D032 03F4 -8130D033 03F5 -8130D034 03F6 -8130D035 03F7 -8130D036 03F8 -8130D037 03F9 -8130D038 03FA -8130D039 03FB -8130D130 03FC -8130D131 03FD -8130D132 03FE -8130D133 03FF -8130D134 0400 -A7A7 0401 -8130D135 0402 -8130D136 0403 -8130D137 0404 -8130D138 0405 -8130D139 0406 -8130D230 0407 -8130D231 0408 -8130D232 0409 -8130D233 040A -8130D234 040B -8130D235 040C -8130D236 040D -8130D237 040E -8130D238 040F -A7A1 0410 -A7A2 0411 -A7A3 0412 -A7A4 0413 -A7A5 0414 -A7A6 0415 -A7A8 0416 -A7A9 0417 -A7AA 0418 -A7AB 0419 -A7AC 041A -A7AD 041B -A7AE 041C -A7AF 041D -A7B0 041E -A7B1 041F -A7B2 0420 -A7B3 0421 -A7B4 0422 -A7B5 0423 -A7B6 0424 -A7B7 0425 -A7B8 0426 -A7B9 0427 -A7BA 0428 -A7BB 0429 -A7BC 042A -A7BD 042B -A7BE 042C -A7BF 042D -A7C0 042E -A7C1 042F -A7D1 0430 -A7D2 0431 -A7D3 0432 -A7D4 0433 -A7D5 0434 -A7D6 0435 -A7D8 0436 -A7D9 0437 -A7DA 0438 -A7DB 0439 -A7DC 043A -A7DD 043B -A7DE 043C -A7DF 043D -A7E0 043E -A7E1 043F -A7E2 0440 -A7E3 0441 -A7E4 0442 -A7E5 0443 -A7E6 0444 -A7E7 0445 -A7E8 0446 -A7E9 0447 -A7EA 0448 -A7EB 0449 -A7EC 044A -A7ED 044B -A7EE 044C -A7EF 044D -A7F0 044E -A7F1 044F -8130D239 0450 -A7D7 0451 -8130D330 0452 -8130D331 0453 -8130D332 0454 -8130D333 0455 -8130D334 0456 -8130D335 0457 -8130D336 0458 -8130D337 0459 -8130D338 045A -8130D339 045B -8130D430 045C -8130D431 045D -8130D432 045E -8130D433 045F -8130D434 0460 -8130D435 0461 -8130D436 0462 -8130D437 0463 -8130D438 0464 -8130D439 0465 -8130D530 0466 -8130D531 0467 -8130D532 0468 -8130D533 0469 -8130D534 046A -8130D535 046B -8130D536 046C -8130D537 046D -8130D538 046E -8130D539 046F -8130D630 0470 -8130D631 0471 -8130D632 0472 -8130D633 0473 -8130D634 0474 -8130D635 0475 -8130D636 0476 -8130D637 0477 -8130D638 0478 -8130D639 0479 -8130D730 047A -8130D731 047B -8130D732 047C -8130D733 047D -8130D734 047E -8130D735 047F -8130D736 0480 -8130D737 0481 -8130D738 0482 -8130D739 0483 -8130D830 0484 -8130D831 0485 -8130D832 0486 -8130D833 0487 -8130D834 0488 -8130D835 0489 -8130D836 048A -8130D837 048B -8130D838 048C -8130D839 048D -8130D930 048E -8130D931 048F -8130D932 0490 -8130D933 0491 -8130D934 0492 -8130D935 0493 -8130D936 0494 -8130D937 0495 -8130D938 0496 -8130D939 0497 -8130DA30 0498 -8130DA31 0499 -8130DA32 049A -8130DA33 049B -8130DA34 049C -8130DA35 049D -8130DA36 049E -8130DA37 049F -8130DA38 04A0 -8130DA39 04A1 -8130DB30 04A2 -8130DB31 04A3 -8130DB32 04A4 -8130DB33 04A5 -8130DB34 04A6 -8130DB35 04A7 -8130DB36 04A8 -8130DB37 04A9 -8130DB38 04AA -8130DB39 04AB -8130DC30 04AC -8130DC31 04AD -8130DC32 04AE -8130DC33 04AF -8130DC34 04B0 -8130DC35 04B1 -8130DC36 04B2 -8130DC37 04B3 -8130DC38 04B4 -8130DC39 04B5 -8130DD30 04B6 -8130DD31 04B7 -8130DD32 04B8 -8130DD33 04B9 -8130DD34 04BA -8130DD35 04BB -8130DD36 04BC -8130DD37 04BD -8130DD38 04BE -8130DD39 04BF -8130DE30 04C0 -8130DE31 04C1 -8130DE32 04C2 -8130DE33 04C3 -8130DE34 04C4 -8130DE35 04C5 -8130DE36 04C6 -8130DE37 04C7 -8130DE38 04C8 -8130DE39 04C9 -8130DF30 04CA -8130DF31 04CB -8130DF32 04CC -8130DF33 04CD -8130DF34 04CE -8130DF35 04CF -8130DF36 04D0 -8130DF37 04D1 -8130DF38 04D2 -8130DF39 04D3 -8130E030 04D4 -8130E031 04D5 -8130E032 04D6 -8130E033 04D7 -8130E034 04D8 -8130E035 04D9 -8130E036 04DA -8130E037 04DB -8130E038 04DC -8130E039 04DD -8130E130 04DE -8130E131 04DF -8130E132 04E0 -8130E133 04E1 -8130E134 04E2 -8130E135 04E3 -8130E136 04E4 -8130E137 04E5 -8130E138 04E6 -8130E139 04E7 -8130E230 04E8 -8130E231 04E9 -8130E232 04EA -8130E233 04EB -8130E234 04EC -8130E235 04ED -8130E236 04EE -8130E237 04EF -8130E238 04F0 -8130E239 04F1 -8130E330 04F2 -8130E331 04F3 -8130E332 04F4 -8130E333 04F5 -8130E334 04F6 -8130E335 04F7 -8130E336 04F8 -8130E337 04F9 -8130E338 04FA -8130E339 04FB -8130E430 04FC -8130E431 04FD -8130E432 04FE -8130E433 04FF -8130E434 0500 -8130E435 0501 -8130E436 0502 -8130E437 0503 -8130E438 0504 -8130E439 0505 -8130E530 0506 -8130E531 0507 -8130E532 0508 -8130E533 0509 -8130E534 050A -8130E535 050B -8130E536 050C -8130E537 050D -8130E538 050E -8130E539 050F -8130E630 0510 -8130E631 0511 -8130E632 0512 -8130E633 0513 -8130E634 0514 -8130E635 0515 -8130E636 0516 -8130E637 0517 -8130E638 0518 -8130E639 0519 -8130E730 051A -8130E731 051B -8130E732 051C -8130E733 051D -8130E734 051E -8130E735 051F -8130E736 0520 -8130E737 0521 -8130E738 0522 -8130E739 0523 -8130E830 0524 -8130E831 0525 -8130E832 0526 -8130E833 0527 -8130E834 0528 -8130E835 0529 -8130E836 052A -8130E837 052B -8130E838 052C -8130E839 052D -8130E930 052E -8130E931 052F -8130E932 0530 -8130E933 0531 -8130E934 0532 -8130E935 0533 -8130E936 0534 -8130E937 0535 -8130E938 0536 -8130E939 0537 -8130EA30 0538 -8130EA31 0539 -8130EA32 053A -8130EA33 053B -8130EA34 053C -8130EA35 053D -8130EA36 053E -8130EA37 053F -8130EA38 0540 -8130EA39 0541 -8130EB30 0542 -8130EB31 0543 -8130EB32 0544 -8130EB33 0545 -8130EB34 0546 -8130EB35 0547 -8130EB36 0548 -8130EB37 0549 -8130EB38 054A -8130EB39 054B -8130EC30 054C -8130EC31 054D -8130EC32 054E -8130EC33 054F -8130EC34 0550 -8130EC35 0551 -8130EC36 0552 -8130EC37 0553 -8130EC38 0554 -8130EC39 0555 -8130ED30 0556 -8130ED31 0557 -8130ED32 0558 -8130ED33 0559 -8130ED34 055A -8130ED35 055B -8130ED36 055C -8130ED37 055D -8130ED38 055E -8130ED39 055F -8130EE30 0560 -8130EE31 0561 -8130EE32 0562 -8130EE33 0563 -8130EE34 0564 -8130EE35 0565 -8130EE36 0566 -8130EE37 0567 -8130EE38 0568 -8130EE39 0569 -8130EF30 056A -8130EF31 056B -8130EF32 056C -8130EF33 056D -8130EF34 056E -8130EF35 056F -8130EF36 0570 -8130EF37 0571 -8130EF38 0572 -8130EF39 0573 -8130F030 0574 -8130F031 0575 -8130F032 0576 -8130F033 0577 -8130F034 0578 -8130F035 0579 -8130F036 057A -8130F037 057B -8130F038 057C -8130F039 057D -8130F130 057E -8130F131 057F -8130F132 0580 -8130F133 0581 -8130F134 0582 -8130F135 0583 -8130F136 0584 -8130F137 0585 -8130F138 0586 -8130F139 0587 -8130F230 0588 -8130F231 0589 -8130F232 058A -8130F233 058B -8130F234 058C -8130F235 058D -8130F236 058E -8130F237 058F -8130F238 0590 -8130F239 0591 -8130F330 0592 -8130F331 0593 -8130F332 0594 -8130F333 0595 -8130F334 0596 -8130F335 0597 -8130F336 0598 -8130F337 0599 -8130F338 059A -8130F339 059B -8130F430 059C -8130F431 059D -8130F432 059E -8130F433 059F -8130F434 05A0 -8130F435 05A1 -8130F436 05A2 -8130F437 05A3 -8130F438 05A4 -8130F439 05A5 -8130F530 05A6 -8130F531 05A7 -8130F532 05A8 -8130F533 05A9 -8130F534 05AA -8130F535 05AB -8130F536 05AC -8130F537 05AD -8130F538 05AE -8130F539 05AF -8130F630 05B0 -8130F631 05B1 -8130F632 05B2 -8130F633 05B3 -8130F634 05B4 -8130F635 05B5 -8130F636 05B6 -8130F637 05B7 -8130F638 05B8 -8130F639 05B9 -8130F730 05BA -8130F731 05BB -8130F732 05BC -8130F733 05BD -8130F734 05BE -8130F735 05BF -8130F736 05C0 -8130F737 05C1 -8130F738 05C2 -8130F739 05C3 -8130F830 05C4 -8130F831 05C5 -8130F832 05C6 -8130F833 05C7 -8130F834 05C8 -8130F835 05C9 -8130F836 05CA -8130F837 05CB -8130F838 05CC -8130F839 05CD -8130F930 05CE -8130F931 05CF -8130F932 05D0 -8130F933 05D1 -8130F934 05D2 -8130F935 05D3 -8130F936 05D4 -8130F937 05D5 -8130F938 05D6 -8130F939 05D7 -8130FA30 05D8 -8130FA31 05D9 -8130FA32 05DA -8130FA33 05DB -8130FA34 05DC -8130FA35 05DD -8130FA36 05DE -8130FA37 05DF -8130FA38 05E0 -8130FA39 05E1 -8130FB30 05E2 -8130FB31 05E3 -8130FB32 05E4 -8130FB33 05E5 -8130FB34 05E6 -8130FB35 05E7 -8130FB36 05E8 -8130FB37 05E9 -8130FB38 05EA -8130FB39 05EB -8130FC30 05EC -8130FC31 05ED -8130FC32 05EE -8130FC33 05EF -8130FC34 05F0 -8130FC35 05F1 -8130FC36 05F2 -8130FC37 05F3 -8130FC38 05F4 -8130FC39 05F5 -8130FD30 05F6 -8130FD31 05F7 -8130FD32 05F8 -8130FD33 05F9 -8130FD34 05FA -8130FD35 05FB -8130FD36 05FC -8130FD37 05FD -8130FD38 05FE -8130FD39 05FF -8130FE30 0600 -8130FE31 0601 -8130FE32 0602 -8130FE33 0603 -8130FE34 0604 -8130FE35 0605 -8130FE36 0606 -8130FE37 0607 -8130FE38 0608 -8130FE39 0609 -81318130 060A -81318131 060B -81318132 060C -81318133 060D -81318134 060E -81318135 060F -81318136 0610 -81318137 0611 -81318138 0612 -81318139 0613 -81318230 0614 -81318231 0615 -81318232 0616 -81318233 0617 -81318234 0618 -81318235 0619 -81318236 061A -81318237 061B -81318238 061C -81318239 061D -81318330 061E -81318331 061F -81318332 0620 -81318333 0621 -81318334 0622 -81318335 0623 -81318336 0624 -81318337 0625 -81318338 0626 -81318339 0627 -81318430 0628 -81318431 0629 -81318432 062A -81318433 062B -81318434 062C -81318435 062D -81318436 062E -81318437 062F -81318438 0630 -81318439 0631 -81318530 0632 -81318531 0633 -81318532 0634 -81318533 0635 -81318534 0636 -81318535 0637 -81318536 0638 -81318537 0639 -81318538 063A -81318539 063B -81318630 063C -81318631 063D -81318632 063E -81318633 063F -81318634 0640 -81318635 0641 -81318636 0642 -81318637 0643 -81318638 0644 -81318639 0645 -81318730 0646 -81318731 0647 -81318732 0648 -81318733 0649 -81318734 064A -81318735 064B -81318736 064C -81318737 064D -81318738 064E -81318739 064F -81318830 0650 -81318831 0651 -81318832 0652 -81318833 0653 -81318834 0654 -81318835 0655 -81318836 0656 -81318837 0657 -81318838 0658 -81318839 0659 -81318930 065A -81318931 065B -81318932 065C -81318933 065D -81318934 065E -81318935 065F -81318936 0660 -81318937 0661 -81318938 0662 -81318939 0663 -81318A30 0664 -81318A31 0665 -81318A32 0666 -81318A33 0667 -81318A34 0668 -81318A35 0669 -81318A36 066A -81318A37 066B -81318A38 066C -81318A39 066D -81318B30 066E -81318B31 066F -81318B32 0670 -81318B33 0671 -81318B34 0672 -81318B35 0673 -81318B36 0674 -81318B37 0675 -81318B38 0676 -81318B39 0677 -81318C30 0678 -81318C31 0679 -81318C32 067A -81318C33 067B -81318C34 067C -81318C35 067D -81318C36 067E -81318C37 067F -81318C38 0680 -81318C39 0681 -81318D30 0682 -81318D31 0683 -81318D32 0684 -81318D33 0685 -81318D34 0686 -81318D35 0687 -81318D36 0688 -81318D37 0689 -81318D38 068A -81318D39 068B -81318E30 068C -81318E31 068D -81318E32 068E -81318E33 068F -81318E34 0690 -81318E35 0691 -81318E36 0692 -81318E37 0693 -81318E38 0694 -81318E39 0695 -81318F30 0696 -81318F31 0697 -81318F32 0698 -81318F33 0699 -81318F34 069A -81318F35 069B -81318F36 069C -81318F37 069D -81318F38 069E -81318F39 069F -81319030 06A0 -81319031 06A1 -81319032 06A2 -81319033 06A3 -81319034 06A4 -81319035 06A5 -81319036 06A6 -81319037 06A7 -81319038 06A8 -81319039 06A9 -81319130 06AA -81319131 06AB -81319132 06AC -81319133 06AD -81319134 06AE -81319135 06AF -81319136 06B0 -81319137 06B1 -81319138 06B2 -81319139 06B3 -81319230 06B4 -81319231 06B5 -81319232 06B6 -81319233 06B7 -81319234 06B8 -81319235 06B9 -81319236 06BA -81319237 06BB -81319238 06BC -81319239 06BD -81319330 06BE -81319331 06BF -81319332 06C0 -81319333 06C1 -81319334 06C2 -81319335 06C3 -81319336 06C4 -81319337 06C5 -81319338 06C6 -81319339 06C7 -81319430 06C8 -81319431 06C9 -81319432 06CA -81319433 06CB -81319434 06CC -81319435 06CD -81319436 06CE -81319437 06CF -81319438 06D0 -81319439 06D1 -81319530 06D2 -81319531 06D3 -81319532 06D4 -81319533 06D5 -81319534 06D6 -81319535 06D7 -81319536 06D8 -81319537 06D9 -81319538 06DA -81319539 06DB -81319630 06DC -81319631 06DD -81319632 06DE -81319633 06DF -81319634 06E0 -81319635 06E1 -81319636 06E2 -81319637 06E3 -81319638 06E4 -81319639 06E5 -81319730 06E6 -81319731 06E7 -81319732 06E8 -81319733 06E9 -81319734 06EA -81319735 06EB -81319736 06EC -81319737 06ED -81319738 06EE -81319739 06EF -81319830 06F0 -81319831 06F1 -81319832 06F2 -81319833 06F3 -81319834 06F4 -81319835 06F5 -81319836 06F6 -81319837 06F7 -81319838 06F8 -81319839 06F9 -81319930 06FA -81319931 06FB -81319932 06FC -81319933 06FD -81319934 06FE -81319935 06FF -81319936 0700 -81319937 0701 -81319938 0702 -81319939 0703 -81319A30 0704 -81319A31 0705 -81319A32 0706 -81319A33 0707 -81319A34 0708 -81319A35 0709 -81319A36 070A -81319A37 070B -81319A38 070C -81319A39 070D -81319B30 070E -81319B31 070F -81319B32 0710 -81319B33 0711 -81319B34 0712 -81319B35 0713 -81319B36 0714 -81319B37 0715 -81319B38 0716 -81319B39 0717 -81319C30 0718 -81319C31 0719 -81319C32 071A -81319C33 071B -81319C34 071C -81319C35 071D -81319C36 071E -81319C37 071F -81319C38 0720 -81319C39 0721 -81319D30 0722 -81319D31 0723 -81319D32 0724 -81319D33 0725 -81319D34 0726 -81319D35 0727 -81319D36 0728 -81319D37 0729 -81319D38 072A -81319D39 072B -81319E30 072C -81319E31 072D -81319E32 072E -81319E33 072F -81319E34 0730 -81319E35 0731 -81319E36 0732 -81319E37 0733 -81319E38 0734 -81319E39 0735 -81319F30 0736 -81319F31 0737 -81319F32 0738 -81319F33 0739 -81319F34 073A -81319F35 073B -81319F36 073C -81319F37 073D -81319F38 073E -81319F39 073F -8131A030 0740 -8131A031 0741 -8131A032 0742 -8131A033 0743 -8131A034 0744 -8131A035 0745 -8131A036 0746 -8131A037 0747 -8131A038 0748 -8131A039 0749 -8131A130 074A -8131A131 074B -8131A132 074C -8131A133 074D -8131A134 074E -8131A135 074F -8131A136 0750 -8131A137 0751 -8131A138 0752 -8131A139 0753 -8131A230 0754 -8131A231 0755 -8131A232 0756 -8131A233 0757 -8131A234 0758 -8131A235 0759 -8131A236 075A -8131A237 075B -8131A238 075C -8131A239 075D -8131A330 075E -8131A331 075F -8131A332 0760 -8131A333 0761 -8131A334 0762 -8131A335 0763 -8131A336 0764 -8131A337 0765 -8131A338 0766 -8131A339 0767 -8131A430 0768 -8131A431 0769 -8131A432 076A -8131A433 076B -8131A434 076C -8131A435 076D -8131A436 076E -8131A437 076F -8131A438 0770 -8131A439 0771 -8131A530 0772 -8131A531 0773 -8131A532 0774 -8131A533 0775 -8131A534 0776 -8131A535 0777 -8131A536 0778 -8131A537 0779 -8131A538 077A -8131A539 077B -8131A630 077C -8131A631 077D -8131A632 077E -8131A633 077F -8131A634 0780 -8131A635 0781 -8131A636 0782 -8131A637 0783 -8131A638 0784 -8131A639 0785 -8131A730 0786 -8131A731 0787 -8131A732 0788 -8131A733 0789 -8131A734 078A -8131A735 078B -8131A736 078C -8131A737 078D -8131A738 078E -8131A739 078F -8131A830 0790 -8131A831 0791 -8131A832 0792 -8131A833 0793 -8131A834 0794 -8131A835 0795 -8131A836 0796 -8131A837 0797 -8131A838 0798 -8131A839 0799 -8131A930 079A -8131A931 079B -8131A932 079C -8131A933 079D -8131A934 079E -8131A935 079F -8131A936 07A0 -8131A937 07A1 -8131A938 07A2 -8131A939 07A3 -8131AA30 07A4 -8131AA31 07A5 -8131AA32 07A6 -8131AA33 07A7 -8131AA34 07A8 -8131AA35 07A9 -8131AA36 07AA -8131AA37 07AB -8131AA38 07AC -8131AA39 07AD -8131AB30 07AE -8131AB31 07AF -8131AB32 07B0 -8131AB33 07B1 -8131AB34 07B2 -8131AB35 07B3 -8131AB36 07B4 -8131AB37 07B5 -8131AB38 07B6 -8131AB39 07B7 -8131AC30 07B8 -8131AC31 07B9 -8131AC32 07BA -8131AC33 07BB -8131AC34 07BC -8131AC35 07BD -8131AC36 07BE -8131AC37 07BF -8131AC38 07C0 -8131AC39 07C1 -8131AD30 07C2 -8131AD31 07C3 -8131AD32 07C4 -8131AD33 07C5 -8131AD34 07C6 -8131AD35 07C7 -8131AD36 07C8 -8131AD37 07C9 -8131AD38 07CA -8131AD39 07CB -8131AE30 07CC -8131AE31 07CD -8131AE32 07CE -8131AE33 07CF -8131AE34 07D0 -8131AE35 07D1 -8131AE36 07D2 -8131AE37 07D3 -8131AE38 07D4 -8131AE39 07D5 -8131AF30 07D6 -8131AF31 07D7 -8131AF32 07D8 -8131AF33 07D9 -8131AF34 07DA -8131AF35 07DB -8131AF36 07DC -8131AF37 07DD -8131AF38 07DE -8131AF39 07DF -8131B030 07E0 -8131B031 07E1 -8131B032 07E2 -8131B033 07E3 -8131B034 07E4 -8131B035 07E5 -8131B036 07E6 -8131B037 07E7 -8131B038 07E8 -8131B039 07E9 -8131B130 07EA -8131B131 07EB -8131B132 07EC -8131B133 07ED -8131B134 07EE -8131B135 07EF -8131B136 07F0 -8131B137 07F1 -8131B138 07F2 -8131B139 07F3 -8131B230 07F4 -8131B231 07F5 -8131B232 07F6 -8131B233 07F7 -8131B234 07F8 -8131B235 07F9 -8131B236 07FA -8131B237 07FB -8131B238 07FC -8131B239 07FD -8131B330 07FE -8131B331 07FF -8131B332 0800 -8131B333 0801 -8131B334 0802 -8131B335 0803 -8131B336 0804 -8131B337 0805 -8131B338 0806 -8131B339 0807 -8131B430 0808 -8131B431 0809 -8131B432 080A -8131B433 080B -8131B434 080C -8131B435 080D -8131B436 080E -8131B437 080F -8131B438 0810 -8131B439 0811 -8131B530 0812 -8131B531 0813 -8131B532 0814 -8131B533 0815 -8131B534 0816 -8131B535 0817 -8131B536 0818 -8131B537 0819 -8131B538 081A -8131B539 081B -8131B630 081C -8131B631 081D -8131B632 081E -8131B633 081F -8131B634 0820 -8131B635 0821 -8131B636 0822 -8131B637 0823 -8131B638 0824 -8131B639 0825 -8131B730 0826 -8131B731 0827 -8131B732 0828 -8131B733 0829 -8131B734 082A -8131B735 082B -8131B736 082C -8131B737 082D -8131B738 082E -8131B739 082F -8131B830 0830 -8131B831 0831 -8131B832 0832 -8131B833 0833 -8131B834 0834 -8131B835 0835 -8131B836 0836 -8131B837 0837 -8131B838 0838 -8131B839 0839 -8131B930 083A -8131B931 083B -8131B932 083C -8131B933 083D -8131B934 083E -8131B935 083F -8131B936 0840 -8131B937 0841 -8131B938 0842 -8131B939 0843 -8131BA30 0844 -8131BA31 0845 -8131BA32 0846 -8131BA33 0847 -8131BA34 0848 -8131BA35 0849 -8131BA36 084A -8131BA37 084B -8131BA38 084C -8131BA39 084D -8131BB30 084E -8131BB31 084F -8131BB32 0850 -8131BB33 0851 -8131BB34 0852 -8131BB35 0853 -8131BB36 0854 -8131BB37 0855 -8131BB38 0856 -8131BB39 0857 -8131BC30 0858 -8131BC31 0859 -8131BC32 085A -8131BC33 085B -8131BC34 085C -8131BC35 085D -8131BC36 085E -8131BC37 085F -8131BC38 0860 -8131BC39 0861 -8131BD30 0862 -8131BD31 0863 -8131BD32 0864 -8131BD33 0865 -8131BD34 0866 -8131BD35 0867 -8131BD36 0868 -8131BD37 0869 -8131BD38 086A -8131BD39 086B -8131BE30 086C -8131BE31 086D -8131BE32 086E -8131BE33 086F -8131BE34 0870 -8131BE35 0871 -8131BE36 0872 -8131BE37 0873 -8131BE38 0874 -8131BE39 0875 -8131BF30 0876 -8131BF31 0877 -8131BF32 0878 -8131BF33 0879 -8131BF34 087A -8131BF35 087B -8131BF36 087C -8131BF37 087D -8131BF38 087E -8131BF39 087F -8131C030 0880 -8131C031 0881 -8131C032 0882 -8131C033 0883 -8131C034 0884 -8131C035 0885 -8131C036 0886 -8131C037 0887 -8131C038 0888 -8131C039 0889 -8131C130 088A -8131C131 088B -8131C132 088C -8131C133 088D -8131C134 088E -8131C135 088F -8131C136 0890 -8131C137 0891 -8131C138 0892 -8131C139 0893 -8131C230 0894 -8131C231 0895 -8131C232 0896 -8131C233 0897 -8131C234 0898 -8131C235 0899 -8131C236 089A -8131C237 089B -8131C238 089C -8131C239 089D -8131C330 089E -8131C331 089F -8131C332 08A0 -8131C333 08A1 -8131C334 08A2 -8131C335 08A3 -8131C336 08A4 -8131C337 08A5 -8131C338 08A6 -8131C339 08A7 -8131C430 08A8 -8131C431 08A9 -8131C432 08AA -8131C433 08AB -8131C434 08AC -8131C435 08AD -8131C436 08AE -8131C437 08AF -8131C438 08B0 -8131C439 08B1 -8131C530 08B2 -8131C531 08B3 -8131C532 08B4 -8131C533 08B5 -8131C534 08B6 -8131C535 08B7 -8131C536 08B8 -8131C537 08B9 -8131C538 08BA -8131C539 08BB -8131C630 08BC -8131C631 08BD -8131C632 08BE -8131C633 08BF -8131C634 08C0 -8131C635 08C1 -8131C636 08C2 -8131C637 08C3 -8131C638 08C4 -8131C639 08C5 -8131C730 08C6 -8131C731 08C7 -8131C732 08C8 -8131C733 08C9 -8131C734 08CA -8131C735 08CB -8131C736 08CC -8131C737 08CD -8131C738 08CE -8131C739 08CF -8131C830 08D0 -8131C831 08D1 -8131C832 08D2 -8131C833 08D3 -8131C834 08D4 -8131C835 08D5 -8131C836 08D6 -8131C837 08D7 -8131C838 08D8 -8131C839 08D9 -8131C930 08DA -8131C931 08DB -8131C932 08DC -8131C933 08DD -8131C934 08DE -8131C935 08DF -8131C936 08E0 -8131C937 08E1 -8131C938 08E2 -8131C939 08E3 -8131CA30 08E4 -8131CA31 08E5 -8131CA32 08E6 -8131CA33 08E7 -8131CA34 08E8 -8131CA35 08E9 -8131CA36 08EA -8131CA37 08EB -8131CA38 08EC -8131CA39 08ED -8131CB30 08EE -8131CB31 08EF -8131CB32 08F0 -8131CB33 08F1 -8131CB34 08F2 -8131CB35 08F3 -8131CB36 08F4 -8131CB37 08F5 -8131CB38 08F6 -8131CB39 08F7 -8131CC30 08F8 -8131CC31 08F9 -8131CC32 08FA -8131CC33 08FB -8131CC34 08FC -8131CC35 08FD -8131CC36 08FE -8131CC37 08FF -8131CC38 0900 -8131CC39 0901 -8131CD30 0902 -8131CD31 0903 -8131CD32 0904 -8131CD33 0905 -8131CD34 0906 -8131CD35 0907 -8131CD36 0908 -8131CD37 0909 -8131CD38 090A -8131CD39 090B -8131CE30 090C -8131CE31 090D -8131CE32 090E -8131CE33 090F -8131CE34 0910 -8131CE35 0911 -8131CE36 0912 -8131CE37 0913 -8131CE38 0914 -8131CE39 0915 -8131CF30 0916 -8131CF31 0917 -8131CF32 0918 -8131CF33 0919 -8131CF34 091A -8131CF35 091B -8131CF36 091C -8131CF37 091D -8131CF38 091E -8131CF39 091F -8131D030 0920 -8131D031 0921 -8131D032 0922 -8131D033 0923 -8131D034 0924 -8131D035 0925 -8131D036 0926 -8131D037 0927 -8131D038 0928 -8131D039 0929 -8131D130 092A -8131D131 092B -8131D132 092C -8131D133 092D -8131D134 092E -8131D135 092F -8131D136 0930 -8131D137 0931 -8131D138 0932 -8131D139 0933 -8131D230 0934 -8131D231 0935 -8131D232 0936 -8131D233 0937 -8131D234 0938 -8131D235 0939 -8131D236 093A -8131D237 093B -8131D238 093C -8131D239 093D -8131D330 093E -8131D331 093F -8131D332 0940 -8131D333 0941 -8131D334 0942 -8131D335 0943 -8131D336 0944 -8131D337 0945 -8131D338 0946 -8131D339 0947 -8131D430 0948 -8131D431 0949 -8131D432 094A -8131D433 094B -8131D434 094C -8131D435 094D -8131D436 094E -8131D437 094F -8131D438 0950 -8131D439 0951 -8131D530 0952 -8131D531 0953 -8131D532 0954 -8131D533 0955 -8131D534 0956 -8131D535 0957 -8131D536 0958 -8131D537 0959 -8131D538 095A -8131D539 095B -8131D630 095C -8131D631 095D -8131D632 095E -8131D633 095F -8131D634 0960 -8131D635 0961 -8131D636 0962 -8131D637 0963 -8131D638 0964 -8131D639 0965 -8131D730 0966 -8131D731 0967 -8131D732 0968 -8131D733 0969 -8131D734 096A -8131D735 096B -8131D736 096C -8131D737 096D -8131D738 096E -8131D739 096F -8131D830 0970 -8131D831 0971 -8131D832 0972 -8131D833 0973 -8131D834 0974 -8131D835 0975 -8131D836 0976 -8131D837 0977 -8131D838 0978 -8131D839 0979 -8131D930 097A -8131D931 097B -8131D932 097C -8131D933 097D -8131D934 097E -8131D935 097F -8131D936 0980 -8131D937 0981 -8131D938 0982 -8131D939 0983 -8131DA30 0984 -8131DA31 0985 -8131DA32 0986 -8131DA33 0987 -8131DA34 0988 -8131DA35 0989 -8131DA36 098A -8131DA37 098B -8131DA38 098C -8131DA39 098D -8131DB30 098E -8131DB31 098F -8131DB32 0990 -8131DB33 0991 -8131DB34 0992 -8131DB35 0993 -8131DB36 0994 -8131DB37 0995 -8131DB38 0996 -8131DB39 0997 -8131DC30 0998 -8131DC31 0999 -8131DC32 099A -8131DC33 099B -8131DC34 099C -8131DC35 099D -8131DC36 099E -8131DC37 099F -8131DC38 09A0 -8131DC39 09A1 -8131DD30 09A2 -8131DD31 09A3 -8131DD32 09A4 -8131DD33 09A5 -8131DD34 09A6 -8131DD35 09A7 -8131DD36 09A8 -8131DD37 09A9 -8131DD38 09AA -8131DD39 09AB -8131DE30 09AC -8131DE31 09AD -8131DE32 09AE -8131DE33 09AF -8131DE34 09B0 -8131DE35 09B1 -8131DE36 09B2 -8131DE37 09B3 -8131DE38 09B4 -8131DE39 09B5 -8131DF30 09B6 -8131DF31 09B7 -8131DF32 09B8 -8131DF33 09B9 -8131DF34 09BA -8131DF35 09BB -8131DF36 09BC -8131DF37 09BD -8131DF38 09BE -8131DF39 09BF -8131E030 09C0 -8131E031 09C1 -8131E032 09C2 -8131E033 09C3 -8131E034 09C4 -8131E035 09C5 -8131E036 09C6 -8131E037 09C7 -8131E038 09C8 -8131E039 09C9 -8131E130 09CA -8131E131 09CB -8131E132 09CC -8131E133 09CD -8131E134 09CE -8131E135 09CF -8131E136 09D0 -8131E137 09D1 -8131E138 09D2 -8131E139 09D3 -8131E230 09D4 -8131E231 09D5 -8131E232 09D6 -8131E233 09D7 -8131E234 09D8 -8131E235 09D9 -8131E236 09DA -8131E237 09DB -8131E238 09DC -8131E239 09DD -8131E330 09DE -8131E331 09DF -8131E332 09E0 -8131E333 09E1 -8131E334 09E2 -8131E335 09E3 -8131E336 09E4 -8131E337 09E5 -8131E338 09E6 -8131E339 09E7 -8131E430 09E8 -8131E431 09E9 -8131E432 09EA -8131E433 09EB -8131E434 09EC -8131E435 09ED -8131E436 09EE -8131E437 09EF -8131E438 09F0 -8131E439 09F1 -8131E530 09F2 -8131E531 09F3 -8131E532 09F4 -8131E533 09F5 -8131E534 09F6 -8131E535 09F7 -8131E536 09F8 -8131E537 09F9 -8131E538 09FA -8131E539 09FB -8131E630 09FC -8131E631 09FD -8131E632 09FE -8131E633 09FF -8131E634 0A00 -8131E635 0A01 -8131E636 0A02 -8131E637 0A03 -8131E638 0A04 -8131E639 0A05 -8131E730 0A06 -8131E731 0A07 -8131E732 0A08 -8131E733 0A09 -8131E734 0A0A -8131E735 0A0B -8131E736 0A0C -8131E737 0A0D -8131E738 0A0E -8131E739 0A0F -8131E830 0A10 -8131E831 0A11 -8131E832 0A12 -8131E833 0A13 -8131E834 0A14 -8131E835 0A15 -8131E836 0A16 -8131E837 0A17 -8131E838 0A18 -8131E839 0A19 -8131E930 0A1A -8131E931 0A1B -8131E932 0A1C -8131E933 0A1D -8131E934 0A1E -8131E935 0A1F -8131E936 0A20 -8131E937 0A21 -8131E938 0A22 -8131E939 0A23 -8131EA30 0A24 -8131EA31 0A25 -8131EA32 0A26 -8131EA33 0A27 -8131EA34 0A28 -8131EA35 0A29 -8131EA36 0A2A -8131EA37 0A2B -8131EA38 0A2C -8131EA39 0A2D -8131EB30 0A2E -8131EB31 0A2F -8131EB32 0A30 -8131EB33 0A31 -8131EB34 0A32 -8131EB35 0A33 -8131EB36 0A34 -8131EB37 0A35 -8131EB38 0A36 -8131EB39 0A37 -8131EC30 0A38 -8131EC31 0A39 -8131EC32 0A3A -8131EC33 0A3B -8131EC34 0A3C -8131EC35 0A3D -8131EC36 0A3E -8131EC37 0A3F -8131EC38 0A40 -8131EC39 0A41 -8131ED30 0A42 -8131ED31 0A43 -8131ED32 0A44 -8131ED33 0A45 -8131ED34 0A46 -8131ED35 0A47 -8131ED36 0A48 -8131ED37 0A49 -8131ED38 0A4A -8131ED39 0A4B -8131EE30 0A4C -8131EE31 0A4D -8131EE32 0A4E -8131EE33 0A4F -8131EE34 0A50 -8131EE35 0A51 -8131EE36 0A52 -8131EE37 0A53 -8131EE38 0A54 -8131EE39 0A55 -8131EF30 0A56 -8131EF31 0A57 -8131EF32 0A58 -8131EF33 0A59 -8131EF34 0A5A -8131EF35 0A5B -8131EF36 0A5C -8131EF37 0A5D -8131EF38 0A5E -8131EF39 0A5F -8131F030 0A60 -8131F031 0A61 -8131F032 0A62 -8131F033 0A63 -8131F034 0A64 -8131F035 0A65 -8131F036 0A66 -8131F037 0A67 -8131F038 0A68 -8131F039 0A69 -8131F130 0A6A -8131F131 0A6B -8131F132 0A6C -8131F133 0A6D -8131F134 0A6E -8131F135 0A6F -8131F136 0A70 -8131F137 0A71 -8131F138 0A72 -8131F139 0A73 -8131F230 0A74 -8131F231 0A75 -8131F232 0A76 -8131F233 0A77 -8131F234 0A78 -8131F235 0A79 -8131F236 0A7A -8131F237 0A7B -8131F238 0A7C -8131F239 0A7D -8131F330 0A7E -8131F331 0A7F -8131F332 0A80 -8131F333 0A81 -8131F334 0A82 -8131F335 0A83 -8131F336 0A84 -8131F337 0A85 -8131F338 0A86 -8131F339 0A87 -8131F430 0A88 -8131F431 0A89 -8131F432 0A8A -8131F433 0A8B -8131F434 0A8C -8131F435 0A8D -8131F436 0A8E -8131F437 0A8F -8131F438 0A90 -8131F439 0A91 -8131F530 0A92 -8131F531 0A93 -8131F532 0A94 -8131F533 0A95 -8131F534 0A96 -8131F535 0A97 -8131F536 0A98 -8131F537 0A99 -8131F538 0A9A -8131F539 0A9B -8131F630 0A9C -8131F631 0A9D -8131F632 0A9E -8131F633 0A9F -8131F634 0AA0 -8131F635 0AA1 -8131F636 0AA2 -8131F637 0AA3 -8131F638 0AA4 -8131F639 0AA5 -8131F730 0AA6 -8131F731 0AA7 -8131F732 0AA8 -8131F733 0AA9 -8131F734 0AAA -8131F735 0AAB -8131F736 0AAC -8131F737 0AAD -8131F738 0AAE -8131F739 0AAF -8131F830 0AB0 -8131F831 0AB1 -8131F832 0AB2 -8131F833 0AB3 -8131F834 0AB4 -8131F835 0AB5 -8131F836 0AB6 -8131F837 0AB7 -8131F838 0AB8 -8131F839 0AB9 -8131F930 0ABA -8131F931 0ABB -8131F932 0ABC -8131F933 0ABD -8131F934 0ABE -8131F935 0ABF -8131F936 0AC0 -8131F937 0AC1 -8131F938 0AC2 -8131F939 0AC3 -8131FA30 0AC4 -8131FA31 0AC5 -8131FA32 0AC6 -8131FA33 0AC7 -8131FA34 0AC8 -8131FA35 0AC9 -8131FA36 0ACA -8131FA37 0ACB -8131FA38 0ACC -8131FA39 0ACD -8131FB30 0ACE -8131FB31 0ACF -8131FB32 0AD0 -8131FB33 0AD1 -8131FB34 0AD2 -8131FB35 0AD3 -8131FB36 0AD4 -8131FB37 0AD5 -8131FB38 0AD6 -8131FB39 0AD7 -8131FC30 0AD8 -8131FC31 0AD9 -8131FC32 0ADA -8131FC33 0ADB -8131FC34 0ADC -8131FC35 0ADD -8131FC36 0ADE -8131FC37 0ADF -8131FC38 0AE0 -8131FC39 0AE1 -8131FD30 0AE2 -8131FD31 0AE3 -8131FD32 0AE4 -8131FD33 0AE5 -8131FD34 0AE6 -8131FD35 0AE7 -8131FD36 0AE8 -8131FD37 0AE9 -8131FD38 0AEA -8131FD39 0AEB -8131FE30 0AEC -8131FE31 0AED -8131FE32 0AEE -8131FE33 0AEF -8131FE34 0AF0 -8131FE35 0AF1 -8131FE36 0AF2 -8131FE37 0AF3 -8131FE38 0AF4 -8131FE39 0AF5 -81328130 0AF6 -81328131 0AF7 -81328132 0AF8 -81328133 0AF9 -81328134 0AFA -81328135 0AFB -81328136 0AFC -81328137 0AFD -81328138 0AFE -81328139 0AFF -81328230 0B00 -81328231 0B01 -81328232 0B02 -81328233 0B03 -81328234 0B04 -81328235 0B05 -81328236 0B06 -81328237 0B07 -81328238 0B08 -81328239 0B09 -81328330 0B0A -81328331 0B0B -81328332 0B0C -81328333 0B0D -81328334 0B0E -81328335 0B0F -81328336 0B10 -81328337 0B11 -81328338 0B12 -81328339 0B13 -81328430 0B14 -81328431 0B15 -81328432 0B16 -81328433 0B17 -81328434 0B18 -81328435 0B19 -81328436 0B1A -81328437 0B1B -81328438 0B1C -81328439 0B1D -81328530 0B1E -81328531 0B1F -81328532 0B20 -81328533 0B21 -81328534 0B22 -81328535 0B23 -81328536 0B24 -81328537 0B25 -81328538 0B26 -81328539 0B27 -81328630 0B28 -81328631 0B29 -81328632 0B2A -81328633 0B2B -81328634 0B2C -81328635 0B2D -81328636 0B2E -81328637 0B2F -81328638 0B30 -81328639 0B31 -81328730 0B32 -81328731 0B33 -81328732 0B34 -81328733 0B35 -81328734 0B36 -81328735 0B37 -81328736 0B38 -81328737 0B39 -81328738 0B3A -81328739 0B3B -81328830 0B3C -81328831 0B3D -81328832 0B3E -81328833 0B3F -81328834 0B40 -81328835 0B41 -81328836 0B42 -81328837 0B43 -81328838 0B44 -81328839 0B45 -81328930 0B46 -81328931 0B47 -81328932 0B48 -81328933 0B49 -81328934 0B4A -81328935 0B4B -81328936 0B4C -81328937 0B4D -81328938 0B4E -81328939 0B4F -81328A30 0B50 -81328A31 0B51 -81328A32 0B52 -81328A33 0B53 -81328A34 0B54 -81328A35 0B55 -81328A36 0B56 -81328A37 0B57 -81328A38 0B58 -81328A39 0B59 -81328B30 0B5A -81328B31 0B5B -81328B32 0B5C -81328B33 0B5D -81328B34 0B5E -81328B35 0B5F -81328B36 0B60 -81328B37 0B61 -81328B38 0B62 -81328B39 0B63 -81328C30 0B64 -81328C31 0B65 -81328C32 0B66 -81328C33 0B67 -81328C34 0B68 -81328C35 0B69 -81328C36 0B6A -81328C37 0B6B -81328C38 0B6C -81328C39 0B6D -81328D30 0B6E -81328D31 0B6F -81328D32 0B70 -81328D33 0B71 -81328D34 0B72 -81328D35 0B73 -81328D36 0B74 -81328D37 0B75 -81328D38 0B76 -81328D39 0B77 -81328E30 0B78 -81328E31 0B79 -81328E32 0B7A -81328E33 0B7B -81328E34 0B7C -81328E35 0B7D -81328E36 0B7E -81328E37 0B7F -81328E38 0B80 -81328E39 0B81 -81328F30 0B82 -81328F31 0B83 -81328F32 0B84 -81328F33 0B85 -81328F34 0B86 -81328F35 0B87 -81328F36 0B88 -81328F37 0B89 -81328F38 0B8A -81328F39 0B8B -81329030 0B8C -81329031 0B8D -81329032 0B8E -81329033 0B8F -81329034 0B90 -81329035 0B91 -81329036 0B92 -81329037 0B93 -81329038 0B94 -81329039 0B95 -81329130 0B96 -81329131 0B97 -81329132 0B98 -81329133 0B99 -81329134 0B9A -81329135 0B9B -81329136 0B9C -81329137 0B9D -81329138 0B9E -81329139 0B9F -81329230 0BA0 -81329231 0BA1 -81329232 0BA2 -81329233 0BA3 -81329234 0BA4 -81329235 0BA5 -81329236 0BA6 -81329237 0BA7 -81329238 0BA8 -81329239 0BA9 -81329330 0BAA -81329331 0BAB -81329332 0BAC -81329333 0BAD -81329334 0BAE -81329335 0BAF -81329336 0BB0 -81329337 0BB1 -81329338 0BB2 -81329339 0BB3 -81329430 0BB4 -81329431 0BB5 -81329432 0BB6 -81329433 0BB7 -81329434 0BB8 -81329435 0BB9 -81329436 0BBA -81329437 0BBB -81329438 0BBC -81329439 0BBD -81329530 0BBE -81329531 0BBF -81329532 0BC0 -81329533 0BC1 -81329534 0BC2 -81329535 0BC3 -81329536 0BC4 -81329537 0BC5 -81329538 0BC6 -81329539 0BC7 -81329630 0BC8 -81329631 0BC9 -81329632 0BCA -81329633 0BCB -81329634 0BCC -81329635 0BCD -81329636 0BCE -81329637 0BCF -81329638 0BD0 -81329639 0BD1 -81329730 0BD2 -81329731 0BD3 -81329732 0BD4 -81329733 0BD5 -81329734 0BD6 -81329735 0BD7 -81329736 0BD8 -81329737 0BD9 -81329738 0BDA -81329739 0BDB -81329830 0BDC -81329831 0BDD -81329832 0BDE -81329833 0BDF -81329834 0BE0 -81329835 0BE1 -81329836 0BE2 -81329837 0BE3 -81329838 0BE4 -81329839 0BE5 -81329930 0BE6 -81329931 0BE7 -81329932 0BE8 -81329933 0BE9 -81329934 0BEA -81329935 0BEB -81329936 0BEC -81329937 0BED -81329938 0BEE -81329939 0BEF -81329A30 0BF0 -81329A31 0BF1 -81329A32 0BF2 -81329A33 0BF3 -81329A34 0BF4 -81329A35 0BF5 -81329A36 0BF6 -81329A37 0BF7 -81329A38 0BF8 -81329A39 0BF9 -81329B30 0BFA -81329B31 0BFB -81329B32 0BFC -81329B33 0BFD -81329B34 0BFE -81329B35 0BFF -81329B36 0C00 -81329B37 0C01 -81329B38 0C02 -81329B39 0C03 -81329C30 0C04 -81329C31 0C05 -81329C32 0C06 -81329C33 0C07 -81329C34 0C08 -81329C35 0C09 -81329C36 0C0A -81329C37 0C0B -81329C38 0C0C -81329C39 0C0D -81329D30 0C0E -81329D31 0C0F -81329D32 0C10 -81329D33 0C11 -81329D34 0C12 -81329D35 0C13 -81329D36 0C14 -81329D37 0C15 -81329D38 0C16 -81329D39 0C17 -81329E30 0C18 -81329E31 0C19 -81329E32 0C1A -81329E33 0C1B -81329E34 0C1C -81329E35 0C1D -81329E36 0C1E -81329E37 0C1F -81329E38 0C20 -81329E39 0C21 -81329F30 0C22 -81329F31 0C23 -81329F32 0C24 -81329F33 0C25 -81329F34 0C26 -81329F35 0C27 -81329F36 0C28 -81329F37 0C29 -81329F38 0C2A -81329F39 0C2B -8132A030 0C2C -8132A031 0C2D -8132A032 0C2E -8132A033 0C2F -8132A034 0C30 -8132A035 0C31 -8132A036 0C32 -8132A037 0C33 -8132A038 0C34 -8132A039 0C35 -8132A130 0C36 -8132A131 0C37 -8132A132 0C38 -8132A133 0C39 -8132A134 0C3A -8132A135 0C3B -8132A136 0C3C -8132A137 0C3D -8132A138 0C3E -8132A139 0C3F -8132A230 0C40 -8132A231 0C41 -8132A232 0C42 -8132A233 0C43 -8132A234 0C44 -8132A235 0C45 -8132A236 0C46 -8132A237 0C47 -8132A238 0C48 -8132A239 0C49 -8132A330 0C4A -8132A331 0C4B -8132A332 0C4C -8132A333 0C4D -8132A334 0C4E -8132A335 0C4F -8132A336 0C50 -8132A337 0C51 -8132A338 0C52 -8132A339 0C53 -8132A430 0C54 -8132A431 0C55 -8132A432 0C56 -8132A433 0C57 -8132A434 0C58 -8132A435 0C59 -8132A436 0C5A -8132A437 0C5B -8132A438 0C5C -8132A439 0C5D -8132A530 0C5E -8132A531 0C5F -8132A532 0C60 -8132A533 0C61 -8132A534 0C62 -8132A535 0C63 -8132A536 0C64 -8132A537 0C65 -8132A538 0C66 -8132A539 0C67 -8132A630 0C68 -8132A631 0C69 -8132A632 0C6A -8132A633 0C6B -8132A634 0C6C -8132A635 0C6D -8132A636 0C6E -8132A637 0C6F -8132A638 0C70 -8132A639 0C71 -8132A730 0C72 -8132A731 0C73 -8132A732 0C74 -8132A733 0C75 -8132A734 0C76 -8132A735 0C77 -8132A736 0C78 -8132A737 0C79 -8132A738 0C7A -8132A739 0C7B -8132A830 0C7C -8132A831 0C7D -8132A832 0C7E -8132A833 0C7F -8132A834 0C80 -8132A835 0C81 -8132A836 0C82 -8132A837 0C83 -8132A838 0C84 -8132A839 0C85 -8132A930 0C86 -8132A931 0C87 -8132A932 0C88 -8132A933 0C89 -8132A934 0C8A -8132A935 0C8B -8132A936 0C8C -8132A937 0C8D -8132A938 0C8E -8132A939 0C8F -8132AA30 0C90 -8132AA31 0C91 -8132AA32 0C92 -8132AA33 0C93 -8132AA34 0C94 -8132AA35 0C95 -8132AA36 0C96 -8132AA37 0C97 -8132AA38 0C98 -8132AA39 0C99 -8132AB30 0C9A -8132AB31 0C9B -8132AB32 0C9C -8132AB33 0C9D -8132AB34 0C9E -8132AB35 0C9F -8132AB36 0CA0 -8132AB37 0CA1 -8132AB38 0CA2 -8132AB39 0CA3 -8132AC30 0CA4 -8132AC31 0CA5 -8132AC32 0CA6 -8132AC33 0CA7 -8132AC34 0CA8 -8132AC35 0CA9 -8132AC36 0CAA -8132AC37 0CAB -8132AC38 0CAC -8132AC39 0CAD -8132AD30 0CAE -8132AD31 0CAF -8132AD32 0CB0 -8132AD33 0CB1 -8132AD34 0CB2 -8132AD35 0CB3 -8132AD36 0CB4 -8132AD37 0CB5 -8132AD38 0CB6 -8132AD39 0CB7 -8132AE30 0CB8 -8132AE31 0CB9 -8132AE32 0CBA -8132AE33 0CBB -8132AE34 0CBC -8132AE35 0CBD -8132AE36 0CBE -8132AE37 0CBF -8132AE38 0CC0 -8132AE39 0CC1 -8132AF30 0CC2 -8132AF31 0CC3 -8132AF32 0CC4 -8132AF33 0CC5 -8132AF34 0CC6 -8132AF35 0CC7 -8132AF36 0CC8 -8132AF37 0CC9 -8132AF38 0CCA -8132AF39 0CCB -8132B030 0CCC -8132B031 0CCD -8132B032 0CCE -8132B033 0CCF -8132B034 0CD0 -8132B035 0CD1 -8132B036 0CD2 -8132B037 0CD3 -8132B038 0CD4 -8132B039 0CD5 -8132B130 0CD6 -8132B131 0CD7 -8132B132 0CD8 -8132B133 0CD9 -8132B134 0CDA -8132B135 0CDB -8132B136 0CDC -8132B137 0CDD -8132B138 0CDE -8132B139 0CDF -8132B230 0CE0 -8132B231 0CE1 -8132B232 0CE2 -8132B233 0CE3 -8132B234 0CE4 -8132B235 0CE5 -8132B236 0CE6 -8132B237 0CE7 -8132B238 0CE8 -8132B239 0CE9 -8132B330 0CEA -8132B331 0CEB -8132B332 0CEC -8132B333 0CED -8132B334 0CEE -8132B335 0CEF -8132B336 0CF0 -8132B337 0CF1 -8132B338 0CF2 -8132B339 0CF3 -8132B430 0CF4 -8132B431 0CF5 -8132B432 0CF6 -8132B433 0CF7 -8132B434 0CF8 -8132B435 0CF9 -8132B436 0CFA -8132B437 0CFB -8132B438 0CFC -8132B439 0CFD -8132B530 0CFE -8132B531 0CFF -8132B532 0D00 -8132B533 0D01 -8132B534 0D02 -8132B535 0D03 -8132B536 0D04 -8132B537 0D05 -8132B538 0D06 -8132B539 0D07 -8132B630 0D08 -8132B631 0D09 -8132B632 0D0A -8132B633 0D0B -8132B634 0D0C -8132B635 0D0D -8132B636 0D0E -8132B637 0D0F -8132B638 0D10 -8132B639 0D11 -8132B730 0D12 -8132B731 0D13 -8132B732 0D14 -8132B733 0D15 -8132B734 0D16 -8132B735 0D17 -8132B736 0D18 -8132B737 0D19 -8132B738 0D1A -8132B739 0D1B -8132B830 0D1C -8132B831 0D1D -8132B832 0D1E -8132B833 0D1F -8132B834 0D20 -8132B835 0D21 -8132B836 0D22 -8132B837 0D23 -8132B838 0D24 -8132B839 0D25 -8132B930 0D26 -8132B931 0D27 -8132B932 0D28 -8132B933 0D29 -8132B934 0D2A -8132B935 0D2B -8132B936 0D2C -8132B937 0D2D -8132B938 0D2E -8132B939 0D2F -8132BA30 0D30 -8132BA31 0D31 -8132BA32 0D32 -8132BA33 0D33 -8132BA34 0D34 -8132BA35 0D35 -8132BA36 0D36 -8132BA37 0D37 -8132BA38 0D38 -8132BA39 0D39 -8132BB30 0D3A -8132BB31 0D3B -8132BB32 0D3C -8132BB33 0D3D -8132BB34 0D3E -8132BB35 0D3F -8132BB36 0D40 -8132BB37 0D41 -8132BB38 0D42 -8132BB39 0D43 -8132BC30 0D44 -8132BC31 0D45 -8132BC32 0D46 -8132BC33 0D47 -8132BC34 0D48 -8132BC35 0D49 -8132BC36 0D4A -8132BC37 0D4B -8132BC38 0D4C -8132BC39 0D4D -8132BD30 0D4E -8132BD31 0D4F -8132BD32 0D50 -8132BD33 0D51 -8132BD34 0D52 -8132BD35 0D53 -8132BD36 0D54 -8132BD37 0D55 -8132BD38 0D56 -8132BD39 0D57 -8132BE30 0D58 -8132BE31 0D59 -8132BE32 0D5A -8132BE33 0D5B -8132BE34 0D5C -8132BE35 0D5D -8132BE36 0D5E -8132BE37 0D5F -8132BE38 0D60 -8132BE39 0D61 -8132BF30 0D62 -8132BF31 0D63 -8132BF32 0D64 -8132BF33 0D65 -8132BF34 0D66 -8132BF35 0D67 -8132BF36 0D68 -8132BF37 0D69 -8132BF38 0D6A -8132BF39 0D6B -8132C030 0D6C -8132C031 0D6D -8132C032 0D6E -8132C033 0D6F -8132C034 0D70 -8132C035 0D71 -8132C036 0D72 -8132C037 0D73 -8132C038 0D74 -8132C039 0D75 -8132C130 0D76 -8132C131 0D77 -8132C132 0D78 -8132C133 0D79 -8132C134 0D7A -8132C135 0D7B -8132C136 0D7C -8132C137 0D7D -8132C138 0D7E -8132C139 0D7F -8132C230 0D80 -8132C231 0D81 -8132C232 0D82 -8132C233 0D83 -8132C234 0D84 -8132C235 0D85 -8132C236 0D86 -8132C237 0D87 -8132C238 0D88 -8132C239 0D89 -8132C330 0D8A -8132C331 0D8B -8132C332 0D8C -8132C333 0D8D -8132C334 0D8E -8132C335 0D8F -8132C336 0D90 -8132C337 0D91 -8132C338 0D92 -8132C339 0D93 -8132C430 0D94 -8132C431 0D95 -8132C432 0D96 -8132C433 0D97 -8132C434 0D98 -8132C435 0D99 -8132C436 0D9A -8132C437 0D9B -8132C438 0D9C -8132C439 0D9D -8132C530 0D9E -8132C531 0D9F -8132C532 0DA0 -8132C533 0DA1 -8132C534 0DA2 -8132C535 0DA3 -8132C536 0DA4 -8132C537 0DA5 -8132C538 0DA6 -8132C539 0DA7 -8132C630 0DA8 -8132C631 0DA9 -8132C632 0DAA -8132C633 0DAB -8132C634 0DAC -8132C635 0DAD -8132C636 0DAE -8132C637 0DAF -8132C638 0DB0 -8132C639 0DB1 -8132C730 0DB2 -8132C731 0DB3 -8132C732 0DB4 -8132C733 0DB5 -8132C734 0DB6 -8132C735 0DB7 -8132C736 0DB8 -8132C737 0DB9 -8132C738 0DBA -8132C739 0DBB -8132C830 0DBC -8132C831 0DBD -8132C832 0DBE -8132C833 0DBF -8132C834 0DC0 -8132C835 0DC1 -8132C836 0DC2 -8132C837 0DC3 -8132C838 0DC4 -8132C839 0DC5 -8132C930 0DC6 -8132C931 0DC7 -8132C932 0DC8 -8132C933 0DC9 -8132C934 0DCA -8132C935 0DCB -8132C936 0DCC -8132C937 0DCD -8132C938 0DCE -8132C939 0DCF -8132CA30 0DD0 -8132CA31 0DD1 -8132CA32 0DD2 -8132CA33 0DD3 -8132CA34 0DD4 -8132CA35 0DD5 -8132CA36 0DD6 -8132CA37 0DD7 -8132CA38 0DD8 -8132CA39 0DD9 -8132CB30 0DDA -8132CB31 0DDB -8132CB32 0DDC -8132CB33 0DDD -8132CB34 0DDE -8132CB35 0DDF -8132CB36 0DE0 -8132CB37 0DE1 -8132CB38 0DE2 -8132CB39 0DE3 -8132CC30 0DE4 -8132CC31 0DE5 -8132CC32 0DE6 -8132CC33 0DE7 -8132CC34 0DE8 -8132CC35 0DE9 -8132CC36 0DEA -8132CC37 0DEB -8132CC38 0DEC -8132CC39 0DED -8132CD30 0DEE -8132CD31 0DEF -8132CD32 0DF0 -8132CD33 0DF1 -8132CD34 0DF2 -8132CD35 0DF3 -8132CD36 0DF4 -8132CD37 0DF5 -8132CD38 0DF6 -8132CD39 0DF7 -8132CE30 0DF8 -8132CE31 0DF9 -8132CE32 0DFA -8132CE33 0DFB -8132CE34 0DFC -8132CE35 0DFD -8132CE36 0DFE -8132CE37 0DFF -8132CE38 0E00 -8132CE39 0E01 -8132CF30 0E02 -8132CF31 0E03 -8132CF32 0E04 -8132CF33 0E05 -8132CF34 0E06 -8132CF35 0E07 -8132CF36 0E08 -8132CF37 0E09 -8132CF38 0E0A -8132CF39 0E0B -8132D030 0E0C -8132D031 0E0D -8132D032 0E0E -8132D033 0E0F -8132D034 0E10 -8132D035 0E11 -8132D036 0E12 -8132D037 0E13 -8132D038 0E14 -8132D039 0E15 -8132D130 0E16 -8132D131 0E17 -8132D132 0E18 -8132D133 0E19 -8132D134 0E1A -8132D135 0E1B -8132D136 0E1C -8132D137 0E1D -8132D138 0E1E -8132D139 0E1F -8132D230 0E20 -8132D231 0E21 -8132D232 0E22 -8132D233 0E23 -8132D234 0E24 -8132D235 0E25 -8132D236 0E26 -8132D237 0E27 -8132D238 0E28 -8132D239 0E29 -8132D330 0E2A -8132D331 0E2B -8132D332 0E2C -8132D333 0E2D -8132D334 0E2E -8132D335 0E2F -8132D336 0E30 -8132D337 0E31 -8132D338 0E32 -8132D339 0E33 -8132D430 0E34 -8132D431 0E35 -8132D432 0E36 -8132D433 0E37 -8132D434 0E38 -8132D435 0E39 -8132D436 0E3A -8132D437 0E3B -8132D438 0E3C -8132D439 0E3D -8132D530 0E3E -8132D531 0E3F -8132D532 0E40 -8132D533 0E41 -8132D534 0E42 -8132D535 0E43 -8132D536 0E44 -8132D537 0E45 -8132D538 0E46 -8132D539 0E47 -8132D630 0E48 -8132D631 0E49 -8132D632 0E4A -8132D633 0E4B -8132D634 0E4C -8132D635 0E4D -8132D636 0E4E -8132D637 0E4F -8132D638 0E50 -8132D639 0E51 -8132D730 0E52 -8132D731 0E53 -8132D732 0E54 -8132D733 0E55 -8132D734 0E56 -8132D735 0E57 -8132D736 0E58 -8132D737 0E59 -8132D738 0E5A -8132D739 0E5B -8132D830 0E5C -8132D831 0E5D -8132D832 0E5E -8132D833 0E5F -8132D834 0E60 -8132D835 0E61 -8132D836 0E62 -8132D837 0E63 -8132D838 0E64 -8132D839 0E65 -8132D930 0E66 -8132D931 0E67 -8132D932 0E68 -8132D933 0E69 -8132D934 0E6A -8132D935 0E6B -8132D936 0E6C -8132D937 0E6D -8132D938 0E6E -8132D939 0E6F -8132DA30 0E70 -8132DA31 0E71 -8132DA32 0E72 -8132DA33 0E73 -8132DA34 0E74 -8132DA35 0E75 -8132DA36 0E76 -8132DA37 0E77 -8132DA38 0E78 -8132DA39 0E79 -8132DB30 0E7A -8132DB31 0E7B -8132DB32 0E7C -8132DB33 0E7D -8132DB34 0E7E -8132DB35 0E7F -8132DB36 0E80 -8132DB37 0E81 -8132DB38 0E82 -8132DB39 0E83 -8132DC30 0E84 -8132DC31 0E85 -8132DC32 0E86 -8132DC33 0E87 -8132DC34 0E88 -8132DC35 0E89 -8132DC36 0E8A -8132DC37 0E8B -8132DC38 0E8C -8132DC39 0E8D -8132DD30 0E8E -8132DD31 0E8F -8132DD32 0E90 -8132DD33 0E91 -8132DD34 0E92 -8132DD35 0E93 -8132DD36 0E94 -8132DD37 0E95 -8132DD38 0E96 -8132DD39 0E97 -8132DE30 0E98 -8132DE31 0E99 -8132DE32 0E9A -8132DE33 0E9B -8132DE34 0E9C -8132DE35 0E9D -8132DE36 0E9E -8132DE37 0E9F -8132DE38 0EA0 -8132DE39 0EA1 -8132DF30 0EA2 -8132DF31 0EA3 -8132DF32 0EA4 -8132DF33 0EA5 -8132DF34 0EA6 -8132DF35 0EA7 -8132DF36 0EA8 -8132DF37 0EA9 -8132DF38 0EAA -8132DF39 0EAB -8132E030 0EAC -8132E031 0EAD -8132E032 0EAE -8132E033 0EAF -8132E034 0EB0 -8132E035 0EB1 -8132E036 0EB2 -8132E037 0EB3 -8132E038 0EB4 -8132E039 0EB5 -8132E130 0EB6 -8132E131 0EB7 -8132E132 0EB8 -8132E133 0EB9 -8132E134 0EBA -8132E135 0EBB -8132E136 0EBC -8132E137 0EBD -8132E138 0EBE -8132E139 0EBF -8132E230 0EC0 -8132E231 0EC1 -8132E232 0EC2 -8132E233 0EC3 -8132E234 0EC4 -8132E235 0EC5 -8132E236 0EC6 -8132E237 0EC7 -8132E238 0EC8 -8132E239 0EC9 -8132E330 0ECA -8132E331 0ECB -8132E332 0ECC -8132E333 0ECD -8132E334 0ECE -8132E335 0ECF -8132E336 0ED0 -8132E337 0ED1 -8132E338 0ED2 -8132E339 0ED3 -8132E430 0ED4 -8132E431 0ED5 -8132E432 0ED6 -8132E433 0ED7 -8132E434 0ED8 -8132E435 0ED9 -8132E436 0EDA -8132E437 0EDB -8132E438 0EDC -8132E439 0EDD -8132E530 0EDE -8132E531 0EDF -8132E532 0EE0 -8132E533 0EE1 -8132E534 0EE2 -8132E535 0EE3 -8132E536 0EE4 -8132E537 0EE5 -8132E538 0EE6 -8132E539 0EE7 -8132E630 0EE8 -8132E631 0EE9 -8132E632 0EEA -8132E633 0EEB -8132E634 0EEC -8132E635 0EED -8132E636 0EEE -8132E637 0EEF -8132E638 0EF0 -8132E639 0EF1 -8132E730 0EF2 -8132E731 0EF3 -8132E732 0EF4 -8132E733 0EF5 -8132E734 0EF6 -8132E735 0EF7 -8132E736 0EF8 -8132E737 0EF9 -8132E738 0EFA -8132E739 0EFB -8132E830 0EFC -8132E831 0EFD -8132E832 0EFE -8132E833 0EFF -8132E834 0F00 -8132E835 0F01 -8132E836 0F02 -8132E837 0F03 -8132E838 0F04 -8132E839 0F05 -8132E930 0F06 -8132E931 0F07 -8132E932 0F08 -8132E933 0F09 -8132E934 0F0A -8132E935 0F0B -8132E936 0F0C -8132E937 0F0D -8132E938 0F0E -8132E939 0F0F -8132EA30 0F10 -8132EA31 0F11 -8132EA32 0F12 -8132EA33 0F13 -8132EA34 0F14 -8132EA35 0F15 -8132EA36 0F16 -8132EA37 0F17 -8132EA38 0F18 -8132EA39 0F19 -8132EB30 0F1A -8132EB31 0F1B -8132EB32 0F1C -8132EB33 0F1D -8132EB34 0F1E -8132EB35 0F1F -8132EB36 0F20 -8132EB37 0F21 -8132EB38 0F22 -8132EB39 0F23 -8132EC30 0F24 -8132EC31 0F25 -8132EC32 0F26 -8132EC33 0F27 -8132EC34 0F28 -8132EC35 0F29 -8132EC36 0F2A -8132EC37 0F2B -8132EC38 0F2C -8132EC39 0F2D -8132ED30 0F2E -8132ED31 0F2F -8132ED32 0F30 -8132ED33 0F31 -8132ED34 0F32 -8132ED35 0F33 -8132ED36 0F34 -8132ED37 0F35 -8132ED38 0F36 -8132ED39 0F37 -8132EE30 0F38 -8132EE31 0F39 -8132EE32 0F3A -8132EE33 0F3B -8132EE34 0F3C -8132EE35 0F3D -8132EE36 0F3E -8132EE37 0F3F -8132EE38 0F40 -8132EE39 0F41 -8132EF30 0F42 -8132EF31 0F43 -8132EF32 0F44 -8132EF33 0F45 -8132EF34 0F46 -8132EF35 0F47 -8132EF36 0F48 -8132EF37 0F49 -8132EF38 0F4A -8132EF39 0F4B -8132F030 0F4C -8132F031 0F4D -8132F032 0F4E -8132F033 0F4F -8132F034 0F50 -8132F035 0F51 -8132F036 0F52 -8132F037 0F53 -8132F038 0F54 -8132F039 0F55 -8132F130 0F56 -8132F131 0F57 -8132F132 0F58 -8132F133 0F59 -8132F134 0F5A -8132F135 0F5B -8132F136 0F5C -8132F137 0F5D -8132F138 0F5E -8132F139 0F5F -8132F230 0F60 -8132F231 0F61 -8132F232 0F62 -8132F233 0F63 -8132F234 0F64 -8132F235 0F65 -8132F236 0F66 -8132F237 0F67 -8132F238 0F68 -8132F239 0F69 -8132F330 0F6A -8132F331 0F6B -8132F332 0F6C -8132F333 0F6D -8132F334 0F6E -8132F335 0F6F -8132F336 0F70 -8132F337 0F71 -8132F338 0F72 -8132F339 0F73 -8132F430 0F74 -8132F431 0F75 -8132F432 0F76 -8132F433 0F77 -8132F434 0F78 -8132F435 0F79 -8132F436 0F7A -8132F437 0F7B -8132F438 0F7C -8132F439 0F7D -8132F530 0F7E -8132F531 0F7F -8132F532 0F80 -8132F533 0F81 -8132F534 0F82 -8132F535 0F83 -8132F536 0F84 -8132F537 0F85 -8132F538 0F86 -8132F539 0F87 -8132F630 0F88 -8132F631 0F89 -8132F632 0F8A -8132F633 0F8B -8132F634 0F8C -8132F635 0F8D -8132F636 0F8E -8132F637 0F8F -8132F638 0F90 -8132F639 0F91 -8132F730 0F92 -8132F731 0F93 -8132F732 0F94 -8132F733 0F95 -8132F734 0F96 -8132F735 0F97 -8132F736 0F98 -8132F737 0F99 -8132F738 0F9A -8132F739 0F9B -8132F830 0F9C -8132F831 0F9D -8132F832 0F9E -8132F833 0F9F -8132F834 0FA0 -8132F835 0FA1 -8132F836 0FA2 -8132F837 0FA3 -8132F838 0FA4 -8132F839 0FA5 -8132F930 0FA6 -8132F931 0FA7 -8132F932 0FA8 -8132F933 0FA9 -8132F934 0FAA -8132F935 0FAB -8132F936 0FAC -8132F937 0FAD -8132F938 0FAE -8132F939 0FAF -8132FA30 0FB0 -8132FA31 0FB1 -8132FA32 0FB2 -8132FA33 0FB3 -8132FA34 0FB4 -8132FA35 0FB5 -8132FA36 0FB6 -8132FA37 0FB7 -8132FA38 0FB8 -8132FA39 0FB9 -8132FB30 0FBA -8132FB31 0FBB -8132FB32 0FBC -8132FB33 0FBD -8132FB34 0FBE -8132FB35 0FBF -8132FB36 0FC0 -8132FB37 0FC1 -8132FB38 0FC2 -8132FB39 0FC3 -8132FC30 0FC4 -8132FC31 0FC5 -8132FC32 0FC6 -8132FC33 0FC7 -8132FC34 0FC8 -8132FC35 0FC9 -8132FC36 0FCA -8132FC37 0FCB -8132FC38 0FCC -8132FC39 0FCD -8132FD30 0FCE -8132FD31 0FCF -8132FD32 0FD0 -8132FD33 0FD1 -8132FD34 0FD2 -8132FD35 0FD3 -8132FD36 0FD4 -8132FD37 0FD5 -8132FD38 0FD6 -8132FD39 0FD7 -8132FE30 0FD8 -8132FE31 0FD9 -8132FE32 0FDA -8132FE33 0FDB -8132FE34 0FDC -8132FE35 0FDD -8132FE36 0FDE -8132FE37 0FDF -8132FE38 0FE0 -8132FE39 0FE1 -81338130 0FE2 -81338131 0FE3 -81338132 0FE4 -81338133 0FE5 -81338134 0FE6 -81338135 0FE7 -81338136 0FE8 -81338137 0FE9 -81338138 0FEA -81338139 0FEB -81338230 0FEC -81338231 0FED -81338232 0FEE -81338233 0FEF -81338234 0FF0 -81338235 0FF1 -81338236 0FF2 -81338237 0FF3 -81338238 0FF4 -81338239 0FF5 -81338330 0FF6 -81338331 0FF7 -81338332 0FF8 -81338333 0FF9 -81338334 0FFA -81338335 0FFB -81338336 0FFC -81338337 0FFD -81338338 0FFE -81338339 0FFF -81338430 1000 -81338431 1001 -81338432 1002 -81338433 1003 -81338434 1004 -81338435 1005 -81338436 1006 -81338437 1007 -81338438 1008 -81338439 1009 -81338530 100A -81338531 100B -81338532 100C -81338533 100D -81338534 100E -81338535 100F -81338536 1010 -81338537 1011 -81338538 1012 -81338539 1013 -81338630 1014 -81338631 1015 -81338632 1016 -81338633 1017 -81338634 1018 -81338635 1019 -81338636 101A -81338637 101B -81338638 101C -81338639 101D -81338730 101E -81338731 101F -81338732 1020 -81338733 1021 -81338734 1022 -81338735 1023 -81338736 1024 -81338737 1025 -81338738 1026 -81338739 1027 -81338830 1028 -81338831 1029 -81338832 102A -81338833 102B -81338834 102C -81338835 102D -81338836 102E -81338837 102F -81338838 1030 -81338839 1031 -81338930 1032 -81338931 1033 -81338932 1034 -81338933 1035 -81338934 1036 -81338935 1037 -81338936 1038 -81338937 1039 -81338938 103A -81338939 103B -81338A30 103C -81338A31 103D -81338A32 103E -81338A33 103F -81338A34 1040 -81338A35 1041 -81338A36 1042 -81338A37 1043 -81338A38 1044 -81338A39 1045 -81338B30 1046 -81338B31 1047 -81338B32 1048 -81338B33 1049 -81338B34 104A -81338B35 104B -81338B36 104C -81338B37 104D -81338B38 104E -81338B39 104F -81338C30 1050 -81338C31 1051 -81338C32 1052 -81338C33 1053 -81338C34 1054 -81338C35 1055 -81338C36 1056 -81338C37 1057 -81338C38 1058 -81338C39 1059 -81338D30 105A -81338D31 105B -81338D32 105C -81338D33 105D -81338D34 105E -81338D35 105F -81338D36 1060 -81338D37 1061 -81338D38 1062 -81338D39 1063 -81338E30 1064 -81338E31 1065 -81338E32 1066 -81338E33 1067 -81338E34 1068 -81338E35 1069 -81338E36 106A -81338E37 106B -81338E38 106C -81338E39 106D -81338F30 106E -81338F31 106F -81338F32 1070 -81338F33 1071 -81338F34 1072 -81338F35 1073 -81338F36 1074 -81338F37 1075 -81338F38 1076 -81338F39 1077 -81339030 1078 -81339031 1079 -81339032 107A -81339033 107B -81339034 107C -81339035 107D -81339036 107E -81339037 107F -81339038 1080 -81339039 1081 -81339130 1082 -81339131 1083 -81339132 1084 -81339133 1085 -81339134 1086 -81339135 1087 -81339136 1088 -81339137 1089 -81339138 108A -81339139 108B -81339230 108C -81339231 108D -81339232 108E -81339233 108F -81339234 1090 -81339235 1091 -81339236 1092 -81339237 1093 -81339238 1094 -81339239 1095 -81339330 1096 -81339331 1097 -81339332 1098 -81339333 1099 -81339334 109A -81339335 109B -81339336 109C -81339337 109D -81339338 109E -81339339 109F -81339430 10A0 -81339431 10A1 -81339432 10A2 -81339433 10A3 -81339434 10A4 -81339435 10A5 -81339436 10A6 -81339437 10A7 -81339438 10A8 -81339439 10A9 -81339530 10AA -81339531 10AB -81339532 10AC -81339533 10AD -81339534 10AE -81339535 10AF -81339536 10B0 -81339537 10B1 -81339538 10B2 -81339539 10B3 -81339630 10B4 -81339631 10B5 -81339632 10B6 -81339633 10B7 -81339634 10B8 -81339635 10B9 -81339636 10BA -81339637 10BB -81339638 10BC -81339639 10BD -81339730 10BE -81339731 10BF -81339732 10C0 -81339733 10C1 -81339734 10C2 -81339735 10C3 -81339736 10C4 -81339737 10C5 -81339738 10C6 -81339739 10C7 -81339830 10C8 -81339831 10C9 -81339832 10CA -81339833 10CB -81339834 10CC -81339835 10CD -81339836 10CE -81339837 10CF -81339838 10D0 -81339839 10D1 -81339930 10D2 -81339931 10D3 -81339932 10D4 -81339933 10D5 -81339934 10D6 -81339935 10D7 -81339936 10D8 -81339937 10D9 -81339938 10DA -81339939 10DB -81339A30 10DC -81339A31 10DD -81339A32 10DE -81339A33 10DF -81339A34 10E0 -81339A35 10E1 -81339A36 10E2 -81339A37 10E3 -81339A38 10E4 -81339A39 10E5 -81339B30 10E6 -81339B31 10E7 -81339B32 10E8 -81339B33 10E9 -81339B34 10EA -81339B35 10EB -81339B36 10EC -81339B37 10ED -81339B38 10EE -81339B39 10EF -81339C30 10F0 -81339C31 10F1 -81339C32 10F2 -81339C33 10F3 -81339C34 10F4 -81339C35 10F5 -81339C36 10F6 -81339C37 10F7 -81339C38 10F8 -81339C39 10F9 -81339D30 10FA -81339D31 10FB -81339D32 10FC -81339D33 10FD -81339D34 10FE -81339D35 10FF -81339D36 1100 -81339D37 1101 -81339D38 1102 -81339D39 1103 -81339E30 1104 -81339E31 1105 -81339E32 1106 -81339E33 1107 -81339E34 1108 -81339E35 1109 -81339E36 110A -81339E37 110B -81339E38 110C -81339E39 110D -81339F30 110E -81339F31 110F -81339F32 1110 -81339F33 1111 -81339F34 1112 -81339F35 1113 -81339F36 1114 -81339F37 1115 -81339F38 1116 -81339F39 1117 -8133A030 1118 -8133A031 1119 -8133A032 111A -8133A033 111B -8133A034 111C -8133A035 111D -8133A036 111E -8133A037 111F -8133A038 1120 -8133A039 1121 -8133A130 1122 -8133A131 1123 -8133A132 1124 -8133A133 1125 -8133A134 1126 -8133A135 1127 -8133A136 1128 -8133A137 1129 -8133A138 112A -8133A139 112B -8133A230 112C -8133A231 112D -8133A232 112E -8133A233 112F -8133A234 1130 -8133A235 1131 -8133A236 1132 -8133A237 1133 -8133A238 1134 -8133A239 1135 -8133A330 1136 -8133A331 1137 -8133A332 1138 -8133A333 1139 -8133A334 113A -8133A335 113B -8133A336 113C -8133A337 113D -8133A338 113E -8133A339 113F -8133A430 1140 -8133A431 1141 -8133A432 1142 -8133A433 1143 -8133A434 1144 -8133A435 1145 -8133A436 1146 -8133A437 1147 -8133A438 1148 -8133A439 1149 -8133A530 114A -8133A531 114B -8133A532 114C -8133A533 114D -8133A534 114E -8133A535 114F -8133A536 1150 -8133A537 1151 -8133A538 1152 -8133A539 1153 -8133A630 1154 -8133A631 1155 -8133A632 1156 -8133A633 1157 -8133A634 1158 -8133A635 1159 -8133A636 115A -8133A637 115B -8133A638 115C -8133A639 115D -8133A730 115E -8133A731 115F -8133A732 1160 -8133A733 1161 -8133A734 1162 -8133A735 1163 -8133A736 1164 -8133A737 1165 -8133A738 1166 -8133A739 1167 -8133A830 1168 -8133A831 1169 -8133A832 116A -8133A833 116B -8133A834 116C -8133A835 116D -8133A836 116E -8133A837 116F -8133A838 1170 -8133A839 1171 -8133A930 1172 -8133A931 1173 -8133A932 1174 -8133A933 1175 -8133A934 1176 -8133A935 1177 -8133A936 1178 -8133A937 1179 -8133A938 117A -8133A939 117B -8133AA30 117C -8133AA31 117D -8133AA32 117E -8133AA33 117F -8133AA34 1180 -8133AA35 1181 -8133AA36 1182 -8133AA37 1183 -8133AA38 1184 -8133AA39 1185 -8133AB30 1186 -8133AB31 1187 -8133AB32 1188 -8133AB33 1189 -8133AB34 118A -8133AB35 118B -8133AB36 118C -8133AB37 118D -8133AB38 118E -8133AB39 118F -8133AC30 1190 -8133AC31 1191 -8133AC32 1192 -8133AC33 1193 -8133AC34 1194 -8133AC35 1195 -8133AC36 1196 -8133AC37 1197 -8133AC38 1198 -8133AC39 1199 -8133AD30 119A -8133AD31 119B -8133AD32 119C -8133AD33 119D -8133AD34 119E -8133AD35 119F -8133AD36 11A0 -8133AD37 11A1 -8133AD38 11A2 -8133AD39 11A3 -8133AE30 11A4 -8133AE31 11A5 -8133AE32 11A6 -8133AE33 11A7 -8133AE34 11A8 -8133AE35 11A9 -8133AE36 11AA -8133AE37 11AB -8133AE38 11AC -8133AE39 11AD -8133AF30 11AE -8133AF31 11AF -8133AF32 11B0 -8133AF33 11B1 -8133AF34 11B2 -8133AF35 11B3 -8133AF36 11B4 -8133AF37 11B5 -8133AF38 11B6 -8133AF39 11B7 -8133B030 11B8 -8133B031 11B9 -8133B032 11BA -8133B033 11BB -8133B034 11BC -8133B035 11BD -8133B036 11BE -8133B037 11BF -8133B038 11C0 -8133B039 11C1 -8133B130 11C2 -8133B131 11C3 -8133B132 11C4 -8133B133 11C5 -8133B134 11C6 -8133B135 11C7 -8133B136 11C8 -8133B137 11C9 -8133B138 11CA -8133B139 11CB -8133B230 11CC -8133B231 11CD -8133B232 11CE -8133B233 11CF -8133B234 11D0 -8133B235 11D1 -8133B236 11D2 -8133B237 11D3 -8133B238 11D4 -8133B239 11D5 -8133B330 11D6 -8133B331 11D7 -8133B332 11D8 -8133B333 11D9 -8133B334 11DA -8133B335 11DB -8133B336 11DC -8133B337 11DD -8133B338 11DE -8133B339 11DF -8133B430 11E0 -8133B431 11E1 -8133B432 11E2 -8133B433 11E3 -8133B434 11E4 -8133B435 11E5 -8133B436 11E6 -8133B437 11E7 -8133B438 11E8 -8133B439 11E9 -8133B530 11EA -8133B531 11EB -8133B532 11EC -8133B533 11ED -8133B534 11EE -8133B535 11EF -8133B536 11F0 -8133B537 11F1 -8133B538 11F2 -8133B539 11F3 -8133B630 11F4 -8133B631 11F5 -8133B632 11F6 -8133B633 11F7 -8133B634 11F8 -8133B635 11F9 -8133B636 11FA -8133B637 11FB -8133B638 11FC -8133B639 11FD -8133B730 11FE -8133B731 11FF -8133B732 1200 -8133B733 1201 -8133B734 1202 -8133B735 1203 -8133B736 1204 -8133B737 1205 -8133B738 1206 -8133B739 1207 -8133B830 1208 -8133B831 1209 -8133B832 120A -8133B833 120B -8133B834 120C -8133B835 120D -8133B836 120E -8133B837 120F -8133B838 1210 -8133B839 1211 -8133B930 1212 -8133B931 1213 -8133B932 1214 -8133B933 1215 -8133B934 1216 -8133B935 1217 -8133B936 1218 -8133B937 1219 -8133B938 121A -8133B939 121B -8133BA30 121C -8133BA31 121D -8133BA32 121E -8133BA33 121F -8133BA34 1220 -8133BA35 1221 -8133BA36 1222 -8133BA37 1223 -8133BA38 1224 -8133BA39 1225 -8133BB30 1226 -8133BB31 1227 -8133BB32 1228 -8133BB33 1229 -8133BB34 122A -8133BB35 122B -8133BB36 122C -8133BB37 122D -8133BB38 122E -8133BB39 122F -8133BC30 1230 -8133BC31 1231 -8133BC32 1232 -8133BC33 1233 -8133BC34 1234 -8133BC35 1235 -8133BC36 1236 -8133BC37 1237 -8133BC38 1238 -8133BC39 1239 -8133BD30 123A -8133BD31 123B -8133BD32 123C -8133BD33 123D -8133BD34 123E -8133BD35 123F -8133BD36 1240 -8133BD37 1241 -8133BD38 1242 -8133BD39 1243 -8133BE30 1244 -8133BE31 1245 -8133BE32 1246 -8133BE33 1247 -8133BE34 1248 -8133BE35 1249 -8133BE36 124A -8133BE37 124B -8133BE38 124C -8133BE39 124D -8133BF30 124E -8133BF31 124F -8133BF32 1250 -8133BF33 1251 -8133BF34 1252 -8133BF35 1253 -8133BF36 1254 -8133BF37 1255 -8133BF38 1256 -8133BF39 1257 -8133C030 1258 -8133C031 1259 -8133C032 125A -8133C033 125B -8133C034 125C -8133C035 125D -8133C036 125E -8133C037 125F -8133C038 1260 -8133C039 1261 -8133C130 1262 -8133C131 1263 -8133C132 1264 -8133C133 1265 -8133C134 1266 -8133C135 1267 -8133C136 1268 -8133C137 1269 -8133C138 126A -8133C139 126B -8133C230 126C -8133C231 126D -8133C232 126E -8133C233 126F -8133C234 1270 -8133C235 1271 -8133C236 1272 -8133C237 1273 -8133C238 1274 -8133C239 1275 -8133C330 1276 -8133C331 1277 -8133C332 1278 -8133C333 1279 -8133C334 127A -8133C335 127B -8133C336 127C -8133C337 127D -8133C338 127E -8133C339 127F -8133C430 1280 -8133C431 1281 -8133C432 1282 -8133C433 1283 -8133C434 1284 -8133C435 1285 -8133C436 1286 -8133C437 1287 -8133C438 1288 -8133C439 1289 -8133C530 128A -8133C531 128B -8133C532 128C -8133C533 128D -8133C534 128E -8133C535 128F -8133C536 1290 -8133C537 1291 -8133C538 1292 -8133C539 1293 -8133C630 1294 -8133C631 1295 -8133C632 1296 -8133C633 1297 -8133C634 1298 -8133C635 1299 -8133C636 129A -8133C637 129B -8133C638 129C -8133C639 129D -8133C730 129E -8133C731 129F -8133C732 12A0 -8133C733 12A1 -8133C734 12A2 -8133C735 12A3 -8133C736 12A4 -8133C737 12A5 -8133C738 12A6 -8133C739 12A7 -8133C830 12A8 -8133C831 12A9 -8133C832 12AA -8133C833 12AB -8133C834 12AC -8133C835 12AD -8133C836 12AE -8133C837 12AF -8133C838 12B0 -8133C839 12B1 -8133C930 12B2 -8133C931 12B3 -8133C932 12B4 -8133C933 12B5 -8133C934 12B6 -8133C935 12B7 -8133C936 12B8 -8133C937 12B9 -8133C938 12BA -8133C939 12BB -8133CA30 12BC -8133CA31 12BD -8133CA32 12BE -8133CA33 12BF -8133CA34 12C0 -8133CA35 12C1 -8133CA36 12C2 -8133CA37 12C3 -8133CA38 12C4 -8133CA39 12C5 -8133CB30 12C6 -8133CB31 12C7 -8133CB32 12C8 -8133CB33 12C9 -8133CB34 12CA -8133CB35 12CB -8133CB36 12CC -8133CB37 12CD -8133CB38 12CE -8133CB39 12CF -8133CC30 12D0 -8133CC31 12D1 -8133CC32 12D2 -8133CC33 12D3 -8133CC34 12D4 -8133CC35 12D5 -8133CC36 12D6 -8133CC37 12D7 -8133CC38 12D8 -8133CC39 12D9 -8133CD30 12DA -8133CD31 12DB -8133CD32 12DC -8133CD33 12DD -8133CD34 12DE -8133CD35 12DF -8133CD36 12E0 -8133CD37 12E1 -8133CD38 12E2 -8133CD39 12E3 -8133CE30 12E4 -8133CE31 12E5 -8133CE32 12E6 -8133CE33 12E7 -8133CE34 12E8 -8133CE35 12E9 -8133CE36 12EA -8133CE37 12EB -8133CE38 12EC -8133CE39 12ED -8133CF30 12EE -8133CF31 12EF -8133CF32 12F0 -8133CF33 12F1 -8133CF34 12F2 -8133CF35 12F3 -8133CF36 12F4 -8133CF37 12F5 -8133CF38 12F6 -8133CF39 12F7 -8133D030 12F8 -8133D031 12F9 -8133D032 12FA -8133D033 12FB -8133D034 12FC -8133D035 12FD -8133D036 12FE -8133D037 12FF -8133D038 1300 -8133D039 1301 -8133D130 1302 -8133D131 1303 -8133D132 1304 -8133D133 1305 -8133D134 1306 -8133D135 1307 -8133D136 1308 -8133D137 1309 -8133D138 130A -8133D139 130B -8133D230 130C -8133D231 130D -8133D232 130E -8133D233 130F -8133D234 1310 -8133D235 1311 -8133D236 1312 -8133D237 1313 -8133D238 1314 -8133D239 1315 -8133D330 1316 -8133D331 1317 -8133D332 1318 -8133D333 1319 -8133D334 131A -8133D335 131B -8133D336 131C -8133D337 131D -8133D338 131E -8133D339 131F -8133D430 1320 -8133D431 1321 -8133D432 1322 -8133D433 1323 -8133D434 1324 -8133D435 1325 -8133D436 1326 -8133D437 1327 -8133D438 1328 -8133D439 1329 -8133D530 132A -8133D531 132B -8133D532 132C -8133D533 132D -8133D534 132E -8133D535 132F -8133D536 1330 -8133D537 1331 -8133D538 1332 -8133D539 1333 -8133D630 1334 -8133D631 1335 -8133D632 1336 -8133D633 1337 -8133D634 1338 -8133D635 1339 -8133D636 133A -8133D637 133B -8133D638 133C -8133D639 133D -8133D730 133E -8133D731 133F -8133D732 1340 -8133D733 1341 -8133D734 1342 -8133D735 1343 -8133D736 1344 -8133D737 1345 -8133D738 1346 -8133D739 1347 -8133D830 1348 -8133D831 1349 -8133D832 134A -8133D833 134B -8133D834 134C -8133D835 134D -8133D836 134E -8133D837 134F -8133D838 1350 -8133D839 1351 -8133D930 1352 -8133D931 1353 -8133D932 1354 -8133D933 1355 -8133D934 1356 -8133D935 1357 -8133D936 1358 -8133D937 1359 -8133D938 135A -8133D939 135B -8133DA30 135C -8133DA31 135D -8133DA32 135E -8133DA33 135F -8133DA34 1360 -8133DA35 1361 -8133DA36 1362 -8133DA37 1363 -8133DA38 1364 -8133DA39 1365 -8133DB30 1366 -8133DB31 1367 -8133DB32 1368 -8133DB33 1369 -8133DB34 136A -8133DB35 136B -8133DB36 136C -8133DB37 136D -8133DB38 136E -8133DB39 136F -8133DC30 1370 -8133DC31 1371 -8133DC32 1372 -8133DC33 1373 -8133DC34 1374 -8133DC35 1375 -8133DC36 1376 -8133DC37 1377 -8133DC38 1378 -8133DC39 1379 -8133DD30 137A -8133DD31 137B -8133DD32 137C -8133DD33 137D -8133DD34 137E -8133DD35 137F -8133DD36 1380 -8133DD37 1381 -8133DD38 1382 -8133DD39 1383 -8133DE30 1384 -8133DE31 1385 -8133DE32 1386 -8133DE33 1387 -8133DE34 1388 -8133DE35 1389 -8133DE36 138A -8133DE37 138B -8133DE38 138C -8133DE39 138D -8133DF30 138E -8133DF31 138F -8133DF32 1390 -8133DF33 1391 -8133DF34 1392 -8133DF35 1393 -8133DF36 1394 -8133DF37 1395 -8133DF38 1396 -8133DF39 1397 -8133E030 1398 -8133E031 1399 -8133E032 139A -8133E033 139B -8133E034 139C -8133E035 139D -8133E036 139E -8133E037 139F -8133E038 13A0 -8133E039 13A1 -8133E130 13A2 -8133E131 13A3 -8133E132 13A4 -8133E133 13A5 -8133E134 13A6 -8133E135 13A7 -8133E136 13A8 -8133E137 13A9 -8133E138 13AA -8133E139 13AB -8133E230 13AC -8133E231 13AD -8133E232 13AE -8133E233 13AF -8133E234 13B0 -8133E235 13B1 -8133E236 13B2 -8133E237 13B3 -8133E238 13B4 -8133E239 13B5 -8133E330 13B6 -8133E331 13B7 -8133E332 13B8 -8133E333 13B9 -8133E334 13BA -8133E335 13BB -8133E336 13BC -8133E337 13BD -8133E338 13BE -8133E339 13BF -8133E430 13C0 -8133E431 13C1 -8133E432 13C2 -8133E433 13C3 -8133E434 13C4 -8133E435 13C5 -8133E436 13C6 -8133E437 13C7 -8133E438 13C8 -8133E439 13C9 -8133E530 13CA -8133E531 13CB -8133E532 13CC -8133E533 13CD -8133E534 13CE -8133E535 13CF -8133E536 13D0 -8133E537 13D1 -8133E538 13D2 -8133E539 13D3 -8133E630 13D4 -8133E631 13D5 -8133E632 13D6 -8133E633 13D7 -8133E634 13D8 -8133E635 13D9 -8133E636 13DA -8133E637 13DB -8133E638 13DC -8133E639 13DD -8133E730 13DE -8133E731 13DF -8133E732 13E0 -8133E733 13E1 -8133E734 13E2 -8133E735 13E3 -8133E736 13E4 -8133E737 13E5 -8133E738 13E6 -8133E739 13E7 -8133E830 13E8 -8133E831 13E9 -8133E832 13EA -8133E833 13EB -8133E834 13EC -8133E835 13ED -8133E836 13EE -8133E837 13EF -8133E838 13F0 -8133E839 13F1 -8133E930 13F2 -8133E931 13F3 -8133E932 13F4 -8133E933 13F5 -8133E934 13F6 -8133E935 13F7 -8133E936 13F8 -8133E937 13F9 -8133E938 13FA -8133E939 13FB -8133EA30 13FC -8133EA31 13FD -8133EA32 13FE -8133EA33 13FF -8133EA34 1400 -8133EA35 1401 -8133EA36 1402 -8133EA37 1403 -8133EA38 1404 -8133EA39 1405 -8133EB30 1406 -8133EB31 1407 -8133EB32 1408 -8133EB33 1409 -8133EB34 140A -8133EB35 140B -8133EB36 140C -8133EB37 140D -8133EB38 140E -8133EB39 140F -8133EC30 1410 -8133EC31 1411 -8133EC32 1412 -8133EC33 1413 -8133EC34 1414 -8133EC35 1415 -8133EC36 1416 -8133EC37 1417 -8133EC38 1418 -8133EC39 1419 -8133ED30 141A -8133ED31 141B -8133ED32 141C -8133ED33 141D -8133ED34 141E -8133ED35 141F -8133ED36 1420 -8133ED37 1421 -8133ED38 1422 -8133ED39 1423 -8133EE30 1424 -8133EE31 1425 -8133EE32 1426 -8133EE33 1427 -8133EE34 1428 -8133EE35 1429 -8133EE36 142A -8133EE37 142B -8133EE38 142C -8133EE39 142D -8133EF30 142E -8133EF31 142F -8133EF32 1430 -8133EF33 1431 -8133EF34 1432 -8133EF35 1433 -8133EF36 1434 -8133EF37 1435 -8133EF38 1436 -8133EF39 1437 -8133F030 1438 -8133F031 1439 -8133F032 143A -8133F033 143B -8133F034 143C -8133F035 143D -8133F036 143E -8133F037 143F -8133F038 1440 -8133F039 1441 -8133F130 1442 -8133F131 1443 -8133F132 1444 -8133F133 1445 -8133F134 1446 -8133F135 1447 -8133F136 1448 -8133F137 1449 -8133F138 144A -8133F139 144B -8133F230 144C -8133F231 144D -8133F232 144E -8133F233 144F -8133F234 1450 -8133F235 1451 -8133F236 1452 -8133F237 1453 -8133F238 1454 -8133F239 1455 -8133F330 1456 -8133F331 1457 -8133F332 1458 -8133F333 1459 -8133F334 145A -8133F335 145B -8133F336 145C -8133F337 145D -8133F338 145E -8133F339 145F -8133F430 1460 -8133F431 1461 -8133F432 1462 -8133F433 1463 -8133F434 1464 -8133F435 1465 -8133F436 1466 -8133F437 1467 -8133F438 1468 -8133F439 1469 -8133F530 146A -8133F531 146B -8133F532 146C -8133F533 146D -8133F534 146E -8133F535 146F -8133F536 1470 -8133F537 1471 -8133F538 1472 -8133F539 1473 -8133F630 1474 -8133F631 1475 -8133F632 1476 -8133F633 1477 -8133F634 1478 -8133F635 1479 -8133F636 147A -8133F637 147B -8133F638 147C -8133F639 147D -8133F730 147E -8133F731 147F -8133F732 1480 -8133F733 1481 -8133F734 1482 -8133F735 1483 -8133F736 1484 -8133F737 1485 -8133F738 1486 -8133F739 1487 -8133F830 1488 -8133F831 1489 -8133F832 148A -8133F833 148B -8133F834 148C -8133F835 148D -8133F836 148E -8133F837 148F -8133F838 1490 -8133F839 1491 -8133F930 1492 -8133F931 1493 -8133F932 1494 -8133F933 1495 -8133F934 1496 -8133F935 1497 -8133F936 1498 -8133F937 1499 -8133F938 149A -8133F939 149B -8133FA30 149C -8133FA31 149D -8133FA32 149E -8133FA33 149F -8133FA34 14A0 -8133FA35 14A1 -8133FA36 14A2 -8133FA37 14A3 -8133FA38 14A4 -8133FA39 14A5 -8133FB30 14A6 -8133FB31 14A7 -8133FB32 14A8 -8133FB33 14A9 -8133FB34 14AA -8133FB35 14AB -8133FB36 14AC -8133FB37 14AD -8133FB38 14AE -8133FB39 14AF -8133FC30 14B0 -8133FC31 14B1 -8133FC32 14B2 -8133FC33 14B3 -8133FC34 14B4 -8133FC35 14B5 -8133FC36 14B6 -8133FC37 14B7 -8133FC38 14B8 -8133FC39 14B9 -8133FD30 14BA -8133FD31 14BB -8133FD32 14BC -8133FD33 14BD -8133FD34 14BE -8133FD35 14BF -8133FD36 14C0 -8133FD37 14C1 -8133FD38 14C2 -8133FD39 14C3 -8133FE30 14C4 -8133FE31 14C5 -8133FE32 14C6 -8133FE33 14C7 -8133FE34 14C8 -8133FE35 14C9 -8133FE36 14CA -8133FE37 14CB -8133FE38 14CC -8133FE39 14CD -81348130 14CE -81348131 14CF -81348132 14D0 -81348133 14D1 -81348134 14D2 -81348135 14D3 -81348136 14D4 -81348137 14D5 -81348138 14D6 -81348139 14D7 -81348230 14D8 -81348231 14D9 -81348232 14DA -81348233 14DB -81348234 14DC -81348235 14DD -81348236 14DE -81348237 14DF -81348238 14E0 -81348239 14E1 -81348330 14E2 -81348331 14E3 -81348332 14E4 -81348333 14E5 -81348334 14E6 -81348335 14E7 -81348336 14E8 -81348337 14E9 -81348338 14EA -81348339 14EB -81348430 14EC -81348431 14ED -81348432 14EE -81348433 14EF -81348434 14F0 -81348435 14F1 -81348436 14F2 -81348437 14F3 -81348438 14F4 -81348439 14F5 -81348530 14F6 -81348531 14F7 -81348532 14F8 -81348533 14F9 -81348534 14FA -81348535 14FB -81348536 14FC -81348537 14FD -81348538 14FE -81348539 14FF -81348630 1500 -81348631 1501 -81348632 1502 -81348633 1503 -81348634 1504 -81348635 1505 -81348636 1506 -81348637 1507 -81348638 1508 -81348639 1509 -81348730 150A -81348731 150B -81348732 150C -81348733 150D -81348734 150E -81348735 150F -81348736 1510 -81348737 1511 -81348738 1512 -81348739 1513 -81348830 1514 -81348831 1515 -81348832 1516 -81348833 1517 -81348834 1518 -81348835 1519 -81348836 151A -81348837 151B -81348838 151C -81348839 151D -81348930 151E -81348931 151F -81348932 1520 -81348933 1521 -81348934 1522 -81348935 1523 -81348936 1524 -81348937 1525 -81348938 1526 -81348939 1527 -81348A30 1528 -81348A31 1529 -81348A32 152A -81348A33 152B -81348A34 152C -81348A35 152D -81348A36 152E -81348A37 152F -81348A38 1530 -81348A39 1531 -81348B30 1532 -81348B31 1533 -81348B32 1534 -81348B33 1535 -81348B34 1536 -81348B35 1537 -81348B36 1538 -81348B37 1539 -81348B38 153A -81348B39 153B -81348C30 153C -81348C31 153D -81348C32 153E -81348C33 153F -81348C34 1540 -81348C35 1541 -81348C36 1542 -81348C37 1543 -81348C38 1544 -81348C39 1545 -81348D30 1546 -81348D31 1547 -81348D32 1548 -81348D33 1549 -81348D34 154A -81348D35 154B -81348D36 154C -81348D37 154D -81348D38 154E -81348D39 154F -81348E30 1550 -81348E31 1551 -81348E32 1552 -81348E33 1553 -81348E34 1554 -81348E35 1555 -81348E36 1556 -81348E37 1557 -81348E38 1558 -81348E39 1559 -81348F30 155A -81348F31 155B -81348F32 155C -81348F33 155D -81348F34 155E -81348F35 155F -81348F36 1560 -81348F37 1561 -81348F38 1562 -81348F39 1563 -81349030 1564 -81349031 1565 -81349032 1566 -81349033 1567 -81349034 1568 -81349035 1569 -81349036 156A -81349037 156B -81349038 156C -81349039 156D -81349130 156E -81349131 156F -81349132 1570 -81349133 1571 -81349134 1572 -81349135 1573 -81349136 1574 -81349137 1575 -81349138 1576 -81349139 1577 -81349230 1578 -81349231 1579 -81349232 157A -81349233 157B -81349234 157C -81349235 157D -81349236 157E -81349237 157F -81349238 1580 -81349239 1581 -81349330 1582 -81349331 1583 -81349332 1584 -81349333 1585 -81349334 1586 -81349335 1587 -81349336 1588 -81349337 1589 -81349338 158A -81349339 158B -81349430 158C -81349431 158D -81349432 158E -81349433 158F -81349434 1590 -81349435 1591 -81349436 1592 -81349437 1593 -81349438 1594 -81349439 1595 -81349530 1596 -81349531 1597 -81349532 1598 -81349533 1599 -81349534 159A -81349535 159B -81349536 159C -81349537 159D -81349538 159E -81349539 159F -81349630 15A0 -81349631 15A1 -81349632 15A2 -81349633 15A3 -81349634 15A4 -81349635 15A5 -81349636 15A6 -81349637 15A7 -81349638 15A8 -81349639 15A9 -81349730 15AA -81349731 15AB -81349732 15AC -81349733 15AD -81349734 15AE -81349735 15AF -81349736 15B0 -81349737 15B1 -81349738 15B2 -81349739 15B3 -81349830 15B4 -81349831 15B5 -81349832 15B6 -81349833 15B7 -81349834 15B8 -81349835 15B9 -81349836 15BA -81349837 15BB -81349838 15BC -81349839 15BD -81349930 15BE -81349931 15BF -81349932 15C0 -81349933 15C1 -81349934 15C2 -81349935 15C3 -81349936 15C4 -81349937 15C5 -81349938 15C6 -81349939 15C7 -81349A30 15C8 -81349A31 15C9 -81349A32 15CA -81349A33 15CB -81349A34 15CC -81349A35 15CD -81349A36 15CE -81349A37 15CF -81349A38 15D0 -81349A39 15D1 -81349B30 15D2 -81349B31 15D3 -81349B32 15D4 -81349B33 15D5 -81349B34 15D6 -81349B35 15D7 -81349B36 15D8 -81349B37 15D9 -81349B38 15DA -81349B39 15DB -81349C30 15DC -81349C31 15DD -81349C32 15DE -81349C33 15DF -81349C34 15E0 -81349C35 15E1 -81349C36 15E2 -81349C37 15E3 -81349C38 15E4 -81349C39 15E5 -81349D30 15E6 -81349D31 15E7 -81349D32 15E8 -81349D33 15E9 -81349D34 15EA -81349D35 15EB -81349D36 15EC -81349D37 15ED -81349D38 15EE -81349D39 15EF -81349E30 15F0 -81349E31 15F1 -81349E32 15F2 -81349E33 15F3 -81349E34 15F4 -81349E35 15F5 -81349E36 15F6 -81349E37 15F7 -81349E38 15F8 -81349E39 15F9 -81349F30 15FA -81349F31 15FB -81349F32 15FC -81349F33 15FD -81349F34 15FE -81349F35 15FF -81349F36 1600 -81349F37 1601 -81349F38 1602 -81349F39 1603 -8134A030 1604 -8134A031 1605 -8134A032 1606 -8134A033 1607 -8134A034 1608 -8134A035 1609 -8134A036 160A -8134A037 160B -8134A038 160C -8134A039 160D -8134A130 160E -8134A131 160F -8134A132 1610 -8134A133 1611 -8134A134 1612 -8134A135 1613 -8134A136 1614 -8134A137 1615 -8134A138 1616 -8134A139 1617 -8134A230 1618 -8134A231 1619 -8134A232 161A -8134A233 161B -8134A234 161C -8134A235 161D -8134A236 161E -8134A237 161F -8134A238 1620 -8134A239 1621 -8134A330 1622 -8134A331 1623 -8134A332 1624 -8134A333 1625 -8134A334 1626 -8134A335 1627 -8134A336 1628 -8134A337 1629 -8134A338 162A -8134A339 162B -8134A430 162C -8134A431 162D -8134A432 162E -8134A433 162F -8134A434 1630 -8134A435 1631 -8134A436 1632 -8134A437 1633 -8134A438 1634 -8134A439 1635 -8134A530 1636 -8134A531 1637 -8134A532 1638 -8134A533 1639 -8134A534 163A -8134A535 163B -8134A536 163C -8134A537 163D -8134A538 163E -8134A539 163F -8134A630 1640 -8134A631 1641 -8134A632 1642 -8134A633 1643 -8134A634 1644 -8134A635 1645 -8134A636 1646 -8134A637 1647 -8134A638 1648 -8134A639 1649 -8134A730 164A -8134A731 164B -8134A732 164C -8134A733 164D -8134A734 164E -8134A735 164F -8134A736 1650 -8134A737 1651 -8134A738 1652 -8134A739 1653 -8134A830 1654 -8134A831 1655 -8134A832 1656 -8134A833 1657 -8134A834 1658 -8134A835 1659 -8134A836 165A -8134A837 165B -8134A838 165C -8134A839 165D -8134A930 165E -8134A931 165F -8134A932 1660 -8134A933 1661 -8134A934 1662 -8134A935 1663 -8134A936 1664 -8134A937 1665 -8134A938 1666 -8134A939 1667 -8134AA30 1668 -8134AA31 1669 -8134AA32 166A -8134AA33 166B -8134AA34 166C -8134AA35 166D -8134AA36 166E -8134AA37 166F -8134AA38 1670 -8134AA39 1671 -8134AB30 1672 -8134AB31 1673 -8134AB32 1674 -8134AB33 1675 -8134AB34 1676 -8134AB35 1677 -8134AB36 1678 -8134AB37 1679 -8134AB38 167A -8134AB39 167B -8134AC30 167C -8134AC31 167D -8134AC32 167E -8134AC33 167F -8134AC34 1680 -8134AC35 1681 -8134AC36 1682 -8134AC37 1683 -8134AC38 1684 -8134AC39 1685 -8134AD30 1686 -8134AD31 1687 -8134AD32 1688 -8134AD33 1689 -8134AD34 168A -8134AD35 168B -8134AD36 168C -8134AD37 168D -8134AD38 168E -8134AD39 168F -8134AE30 1690 -8134AE31 1691 -8134AE32 1692 -8134AE33 1693 -8134AE34 1694 -8134AE35 1695 -8134AE36 1696 -8134AE37 1697 -8134AE38 1698 -8134AE39 1699 -8134AF30 169A -8134AF31 169B -8134AF32 169C -8134AF33 169D -8134AF34 169E -8134AF35 169F -8134AF36 16A0 -8134AF37 16A1 -8134AF38 16A2 -8134AF39 16A3 -8134B030 16A4 -8134B031 16A5 -8134B032 16A6 -8134B033 16A7 -8134B034 16A8 -8134B035 16A9 -8134B036 16AA -8134B037 16AB -8134B038 16AC -8134B039 16AD -8134B130 16AE -8134B131 16AF -8134B132 16B0 -8134B133 16B1 -8134B134 16B2 -8134B135 16B3 -8134B136 16B4 -8134B137 16B5 -8134B138 16B6 -8134B139 16B7 -8134B230 16B8 -8134B231 16B9 -8134B232 16BA -8134B233 16BB -8134B234 16BC -8134B235 16BD -8134B236 16BE -8134B237 16BF -8134B238 16C0 -8134B239 16C1 -8134B330 16C2 -8134B331 16C3 -8134B332 16C4 -8134B333 16C5 -8134B334 16C6 -8134B335 16C7 -8134B336 16C8 -8134B337 16C9 -8134B338 16CA -8134B339 16CB -8134B430 16CC -8134B431 16CD -8134B432 16CE -8134B433 16CF -8134B434 16D0 -8134B435 16D1 -8134B436 16D2 -8134B437 16D3 -8134B438 16D4 -8134B439 16D5 -8134B530 16D6 -8134B531 16D7 -8134B532 16D8 -8134B533 16D9 -8134B534 16DA -8134B535 16DB -8134B536 16DC -8134B537 16DD -8134B538 16DE -8134B539 16DF -8134B630 16E0 -8134B631 16E1 -8134B632 16E2 -8134B633 16E3 -8134B634 16E4 -8134B635 16E5 -8134B636 16E6 -8134B637 16E7 -8134B638 16E8 -8134B639 16E9 -8134B730 16EA -8134B731 16EB -8134B732 16EC -8134B733 16ED -8134B734 16EE -8134B735 16EF -8134B736 16F0 -8134B737 16F1 -8134B738 16F2 -8134B739 16F3 -8134B830 16F4 -8134B831 16F5 -8134B832 16F6 -8134B833 16F7 -8134B834 16F8 -8134B835 16F9 -8134B836 16FA -8134B837 16FB -8134B838 16FC -8134B839 16FD -8134B930 16FE -8134B931 16FF -8134B932 1700 -8134B933 1701 -8134B934 1702 -8134B935 1703 -8134B936 1704 -8134B937 1705 -8134B938 1706 -8134B939 1707 -8134BA30 1708 -8134BA31 1709 -8134BA32 170A -8134BA33 170B -8134BA34 170C -8134BA35 170D -8134BA36 170E -8134BA37 170F -8134BA38 1710 -8134BA39 1711 -8134BB30 1712 -8134BB31 1713 -8134BB32 1714 -8134BB33 1715 -8134BB34 1716 -8134BB35 1717 -8134BB36 1718 -8134BB37 1719 -8134BB38 171A -8134BB39 171B -8134BC30 171C -8134BC31 171D -8134BC32 171E -8134BC33 171F -8134BC34 1720 -8134BC35 1721 -8134BC36 1722 -8134BC37 1723 -8134BC38 1724 -8134BC39 1725 -8134BD30 1726 -8134BD31 1727 -8134BD32 1728 -8134BD33 1729 -8134BD34 172A -8134BD35 172B -8134BD36 172C -8134BD37 172D -8134BD38 172E -8134BD39 172F -8134BE30 1730 -8134BE31 1731 -8134BE32 1732 -8134BE33 1733 -8134BE34 1734 -8134BE35 1735 -8134BE36 1736 -8134BE37 1737 -8134BE38 1738 -8134BE39 1739 -8134BF30 173A -8134BF31 173B -8134BF32 173C -8134BF33 173D -8134BF34 173E -8134BF35 173F -8134BF36 1740 -8134BF37 1741 -8134BF38 1742 -8134BF39 1743 -8134C030 1744 -8134C031 1745 -8134C032 1746 -8134C033 1747 -8134C034 1748 -8134C035 1749 -8134C036 174A -8134C037 174B -8134C038 174C -8134C039 174D -8134C130 174E -8134C131 174F -8134C132 1750 -8134C133 1751 -8134C134 1752 -8134C135 1753 -8134C136 1754 -8134C137 1755 -8134C138 1756 -8134C139 1757 -8134C230 1758 -8134C231 1759 -8134C232 175A -8134C233 175B -8134C234 175C -8134C235 175D -8134C236 175E -8134C237 175F -8134C238 1760 -8134C239 1761 -8134C330 1762 -8134C331 1763 -8134C332 1764 -8134C333 1765 -8134C334 1766 -8134C335 1767 -8134C336 1768 -8134C337 1769 -8134C338 176A -8134C339 176B -8134C430 176C -8134C431 176D -8134C432 176E -8134C433 176F -8134C434 1770 -8134C435 1771 -8134C436 1772 -8134C437 1773 -8134C438 1774 -8134C439 1775 -8134C530 1776 -8134C531 1777 -8134C532 1778 -8134C533 1779 -8134C534 177A -8134C535 177B -8134C536 177C -8134C537 177D -8134C538 177E -8134C539 177F -8134C630 1780 -8134C631 1781 -8134C632 1782 -8134C633 1783 -8134C634 1784 -8134C635 1785 -8134C636 1786 -8134C637 1787 -8134C638 1788 -8134C639 1789 -8134C730 178A -8134C731 178B -8134C732 178C -8134C733 178D -8134C734 178E -8134C735 178F -8134C736 1790 -8134C737 1791 -8134C738 1792 -8134C739 1793 -8134C830 1794 -8134C831 1795 -8134C832 1796 -8134C833 1797 -8134C834 1798 -8134C835 1799 -8134C836 179A -8134C837 179B -8134C838 179C -8134C839 179D -8134C930 179E -8134C931 179F -8134C932 17A0 -8134C933 17A1 -8134C934 17A2 -8134C935 17A3 -8134C936 17A4 -8134C937 17A5 -8134C938 17A6 -8134C939 17A7 -8134CA30 17A8 -8134CA31 17A9 -8134CA32 17AA -8134CA33 17AB -8134CA34 17AC -8134CA35 17AD -8134CA36 17AE -8134CA37 17AF -8134CA38 17B0 -8134CA39 17B1 -8134CB30 17B2 -8134CB31 17B3 -8134CB32 17B4 -8134CB33 17B5 -8134CB34 17B6 -8134CB35 17B7 -8134CB36 17B8 -8134CB37 17B9 -8134CB38 17BA -8134CB39 17BB -8134CC30 17BC -8134CC31 17BD -8134CC32 17BE -8134CC33 17BF -8134CC34 17C0 -8134CC35 17C1 -8134CC36 17C2 -8134CC37 17C3 -8134CC38 17C4 -8134CC39 17C5 -8134CD30 17C6 -8134CD31 17C7 -8134CD32 17C8 -8134CD33 17C9 -8134CD34 17CA -8134CD35 17CB -8134CD36 17CC -8134CD37 17CD -8134CD38 17CE -8134CD39 17CF -8134CE30 17D0 -8134CE31 17D1 -8134CE32 17D2 -8134CE33 17D3 -8134CE34 17D4 -8134CE35 17D5 -8134CE36 17D6 -8134CE37 17D7 -8134CE38 17D8 -8134CE39 17D9 -8134CF30 17DA -8134CF31 17DB -8134CF32 17DC -8134CF33 17DD -8134CF34 17DE -8134CF35 17DF -8134CF36 17E0 -8134CF37 17E1 -8134CF38 17E2 -8134CF39 17E3 -8134D030 17E4 -8134D031 17E5 -8134D032 17E6 -8134D033 17E7 -8134D034 17E8 -8134D035 17E9 -8134D036 17EA -8134D037 17EB -8134D038 17EC -8134D039 17ED -8134D130 17EE -8134D131 17EF -8134D132 17F0 -8134D133 17F1 -8134D134 17F2 -8134D135 17F3 -8134D136 17F4 -8134D137 17F5 -8134D138 17F6 -8134D139 17F7 -8134D230 17F8 -8134D231 17F9 -8134D232 17FA -8134D233 17FB -8134D234 17FC -8134D235 17FD -8134D236 17FE -8134D237 17FF -8134D238 1800 -8134D239 1801 -8134D330 1802 -8134D331 1803 -8134D332 1804 -8134D333 1805 -8134D334 1806 -8134D335 1807 -8134D336 1808 -8134D337 1809 -8134D338 180A -8134D339 180B -8134D430 180C -8134D431 180D -8134D432 180E -8134D433 180F -8134D434 1810 -8134D435 1811 -8134D436 1812 -8134D437 1813 -8134D438 1814 -8134D439 1815 -8134D530 1816 -8134D531 1817 -8134D532 1818 -8134D533 1819 -8134D534 181A -8134D535 181B -8134D536 181C -8134D537 181D -8134D538 181E -8134D539 181F -8134D630 1820 -8134D631 1821 -8134D632 1822 -8134D633 1823 -8134D634 1824 -8134D635 1825 -8134D636 1826 -8134D637 1827 -8134D638 1828 -8134D639 1829 -8134D730 182A -8134D731 182B -8134D732 182C -8134D733 182D -8134D734 182E -8134D735 182F -8134D736 1830 -8134D737 1831 -8134D738 1832 -8134D739 1833 -8134D830 1834 -8134D831 1835 -8134D832 1836 -8134D833 1837 -8134D834 1838 -8134D835 1839 -8134D836 183A -8134D837 183B -8134D838 183C -8134D839 183D -8134D930 183E -8134D931 183F -8134D932 1840 -8134D933 1841 -8134D934 1842 -8134D935 1843 -8134D936 1844 -8134D937 1845 -8134D938 1846 -8134D939 1847 -8134DA30 1848 -8134DA31 1849 -8134DA32 184A -8134DA33 184B -8134DA34 184C -8134DA35 184D -8134DA36 184E -8134DA37 184F -8134DA38 1850 -8134DA39 1851 -8134DB30 1852 -8134DB31 1853 -8134DB32 1854 -8134DB33 1855 -8134DB34 1856 -8134DB35 1857 -8134DB36 1858 -8134DB37 1859 -8134DB38 185A -8134DB39 185B -8134DC30 185C -8134DC31 185D -8134DC32 185E -8134DC33 185F -8134DC34 1860 -8134DC35 1861 -8134DC36 1862 -8134DC37 1863 -8134DC38 1864 -8134DC39 1865 -8134DD30 1866 -8134DD31 1867 -8134DD32 1868 -8134DD33 1869 -8134DD34 186A -8134DD35 186B -8134DD36 186C -8134DD37 186D -8134DD38 186E -8134DD39 186F -8134DE30 1870 -8134DE31 1871 -8134DE32 1872 -8134DE33 1873 -8134DE34 1874 -8134DE35 1875 -8134DE36 1876 -8134DE37 1877 -8134DE38 1878 -8134DE39 1879 -8134DF30 187A -8134DF31 187B -8134DF32 187C -8134DF33 187D -8134DF34 187E -8134DF35 187F -8134DF36 1880 -8134DF37 1881 -8134DF38 1882 -8134DF39 1883 -8134E030 1884 -8134E031 1885 -8134E032 1886 -8134E033 1887 -8134E034 1888 -8134E035 1889 -8134E036 188A -8134E037 188B -8134E038 188C -8134E039 188D -8134E130 188E -8134E131 188F -8134E132 1890 -8134E133 1891 -8134E134 1892 -8134E135 1893 -8134E136 1894 -8134E137 1895 -8134E138 1896 -8134E139 1897 -8134E230 1898 -8134E231 1899 -8134E232 189A -8134E233 189B -8134E234 189C -8134E235 189D -8134E236 189E -8134E237 189F -8134E238 18A0 -8134E239 18A1 -8134E330 18A2 -8134E331 18A3 -8134E332 18A4 -8134E333 18A5 -8134E334 18A6 -8134E335 18A7 -8134E336 18A8 -8134E337 18A9 -8134E338 18AA -8134E339 18AB -8134E430 18AC -8134E431 18AD -8134E432 18AE -8134E433 18AF -8134E434 18B0 -8134E435 18B1 -8134E436 18B2 -8134E437 18B3 -8134E438 18B4 -8134E439 18B5 -8134E530 18B6 -8134E531 18B7 -8134E532 18B8 -8134E533 18B9 -8134E534 18BA -8134E535 18BB -8134E536 18BC -8134E537 18BD -8134E538 18BE -8134E539 18BF -8134E630 18C0 -8134E631 18C1 -8134E632 18C2 -8134E633 18C3 -8134E634 18C4 -8134E635 18C5 -8134E636 18C6 -8134E637 18C7 -8134E638 18C8 -8134E639 18C9 -8134E730 18CA -8134E731 18CB -8134E732 18CC -8134E733 18CD -8134E734 18CE -8134E735 18CF -8134E736 18D0 -8134E737 18D1 -8134E738 18D2 -8134E739 18D3 -8134E830 18D4 -8134E831 18D5 -8134E832 18D6 -8134E833 18D7 -8134E834 18D8 -8134E835 18D9 -8134E836 18DA -8134E837 18DB -8134E838 18DC -8134E839 18DD -8134E930 18DE -8134E931 18DF -8134E932 18E0 -8134E933 18E1 -8134E934 18E2 -8134E935 18E3 -8134E936 18E4 -8134E937 18E5 -8134E938 18E6 -8134E939 18E7 -8134EA30 18E8 -8134EA31 18E9 -8134EA32 18EA -8134EA33 18EB -8134EA34 18EC -8134EA35 18ED -8134EA36 18EE -8134EA37 18EF -8134EA38 18F0 -8134EA39 18F1 -8134EB30 18F2 -8134EB31 18F3 -8134EB32 18F4 -8134EB33 18F5 -8134EB34 18F6 -8134EB35 18F7 -8134EB36 18F8 -8134EB37 18F9 -8134EB38 18FA -8134EB39 18FB -8134EC30 18FC -8134EC31 18FD -8134EC32 18FE -8134EC33 18FF -8134EC34 1900 -8134EC35 1901 -8134EC36 1902 -8134EC37 1903 -8134EC38 1904 -8134EC39 1905 -8134ED30 1906 -8134ED31 1907 -8134ED32 1908 -8134ED33 1909 -8134ED34 190A -8134ED35 190B -8134ED36 190C -8134ED37 190D -8134ED38 190E -8134ED39 190F -8134EE30 1910 -8134EE31 1911 -8134EE32 1912 -8134EE33 1913 -8134EE34 1914 -8134EE35 1915 -8134EE36 1916 -8134EE37 1917 -8134EE38 1918 -8134EE39 1919 -8134EF30 191A -8134EF31 191B -8134EF32 191C -8134EF33 191D -8134EF34 191E -8134EF35 191F -8134EF36 1920 -8134EF37 1921 -8134EF38 1922 -8134EF39 1923 -8134F030 1924 -8134F031 1925 -8134F032 1926 -8134F033 1927 -8134F034 1928 -8134F035 1929 -8134F036 192A -8134F037 192B -8134F038 192C -8134F039 192D -8134F130 192E -8134F131 192F -8134F132 1930 -8134F133 1931 -8134F134 1932 -8134F135 1933 -8134F136 1934 -8134F137 1935 -8134F138 1936 -8134F139 1937 -8134F230 1938 -8134F231 1939 -8134F232 193A -8134F233 193B -8134F234 193C -8134F235 193D -8134F236 193E -8134F237 193F -8134F238 1940 -8134F239 1941 -8134F330 1942 -8134F331 1943 -8134F332 1944 -8134F333 1945 -8134F334 1946 -8134F335 1947 -8134F336 1948 -8134F337 1949 -8134F338 194A -8134F339 194B -8134F430 194C -8134F431 194D -8134F432 194E -8134F433 194F -8134F434 1950 -8134F435 1951 -8134F436 1952 -8134F437 1953 -8134F438 1954 -8134F439 1955 -8134F530 1956 -8134F531 1957 -8134F532 1958 -8134F533 1959 -8134F534 195A -8134F535 195B -8134F536 195C -8134F537 195D -8134F538 195E -8134F539 195F -8134F630 1960 -8134F631 1961 -8134F632 1962 -8134F633 1963 -8134F634 1964 -8134F635 1965 -8134F636 1966 -8134F637 1967 -8134F638 1968 -8134F639 1969 -8134F730 196A -8134F731 196B -8134F732 196C -8134F733 196D -8134F734 196E -8134F735 196F -8134F736 1970 -8134F737 1971 -8134F738 1972 -8134F739 1973 -8134F830 1974 -8134F831 1975 -8134F832 1976 -8134F833 1977 -8134F834 1978 -8134F835 1979 -8134F836 197A -8134F837 197B -8134F838 197C -8134F839 197D -8134F930 197E -8134F931 197F -8134F932 1980 -8134F933 1981 -8134F934 1982 -8134F935 1983 -8134F936 1984 -8134F937 1985 -8134F938 1986 -8134F939 1987 -8134FA30 1988 -8134FA31 1989 -8134FA32 198A -8134FA33 198B -8134FA34 198C -8134FA35 198D -8134FA36 198E -8134FA37 198F -8134FA38 1990 -8134FA39 1991 -8134FB30 1992 -8134FB31 1993 -8134FB32 1994 -8134FB33 1995 -8134FB34 1996 -8134FB35 1997 -8134FB36 1998 -8134FB37 1999 -8134FB38 199A -8134FB39 199B -8134FC30 199C -8134FC31 199D -8134FC32 199E -8134FC33 199F -8134FC34 19A0 -8134FC35 19A1 -8134FC36 19A2 -8134FC37 19A3 -8134FC38 19A4 -8134FC39 19A5 -8134FD30 19A6 -8134FD31 19A7 -8134FD32 19A8 -8134FD33 19A9 -8134FD34 19AA -8134FD35 19AB -8134FD36 19AC -8134FD37 19AD -8134FD38 19AE -8134FD39 19AF -8134FE30 19B0 -8134FE31 19B1 -8134FE32 19B2 -8134FE33 19B3 -8134FE34 19B4 -8134FE35 19B5 -8134FE36 19B6 -8134FE37 19B7 -8134FE38 19B8 -8134FE39 19B9 -81358130 19BA -81358131 19BB -81358132 19BC -81358133 19BD -81358134 19BE -81358135 19BF -81358136 19C0 -81358137 19C1 -81358138 19C2 -81358139 19C3 -81358230 19C4 -81358231 19C5 -81358232 19C6 -81358233 19C7 -81358234 19C8 -81358235 19C9 -81358236 19CA -81358237 19CB -81358238 19CC -81358239 19CD -81358330 19CE -81358331 19CF -81358332 19D0 -81358333 19D1 -81358334 19D2 -81358335 19D3 -81358336 19D4 -81358337 19D5 -81358338 19D6 -81358339 19D7 -81358430 19D8 -81358431 19D9 -81358432 19DA -81358433 19DB -81358434 19DC -81358435 19DD -81358436 19DE -81358437 19DF -81358438 19E0 -81358439 19E1 -81358530 19E2 -81358531 19E3 -81358532 19E4 -81358533 19E5 -81358534 19E6 -81358535 19E7 -81358536 19E8 -81358537 19E9 -81358538 19EA -81358539 19EB -81358630 19EC -81358631 19ED -81358632 19EE -81358633 19EF -81358634 19F0 -81358635 19F1 -81358636 19F2 -81358637 19F3 -81358638 19F4 -81358639 19F5 -81358730 19F6 -81358731 19F7 -81358732 19F8 -81358733 19F9 -81358734 19FA -81358735 19FB -81358736 19FC -81358737 19FD -81358738 19FE -81358739 19FF -81358830 1A00 -81358831 1A01 -81358832 1A02 -81358833 1A03 -81358834 1A04 -81358835 1A05 -81358836 1A06 -81358837 1A07 -81358838 1A08 -81358839 1A09 -81358930 1A0A -81358931 1A0B -81358932 1A0C -81358933 1A0D -81358934 1A0E -81358935 1A0F -81358936 1A10 -81358937 1A11 -81358938 1A12 -81358939 1A13 -81358A30 1A14 -81358A31 1A15 -81358A32 1A16 -81358A33 1A17 -81358A34 1A18 -81358A35 1A19 -81358A36 1A1A -81358A37 1A1B -81358A38 1A1C -81358A39 1A1D -81358B30 1A1E -81358B31 1A1F -81358B32 1A20 -81358B33 1A21 -81358B34 1A22 -81358B35 1A23 -81358B36 1A24 -81358B37 1A25 -81358B38 1A26 -81358B39 1A27 -81358C30 1A28 -81358C31 1A29 -81358C32 1A2A -81358C33 1A2B -81358C34 1A2C -81358C35 1A2D -81358C36 1A2E -81358C37 1A2F -81358C38 1A30 -81358C39 1A31 -81358D30 1A32 -81358D31 1A33 -81358D32 1A34 -81358D33 1A35 -81358D34 1A36 -81358D35 1A37 -81358D36 1A38 -81358D37 1A39 -81358D38 1A3A -81358D39 1A3B -81358E30 1A3C -81358E31 1A3D -81358E32 1A3E -81358E33 1A3F -81358E34 1A40 -81358E35 1A41 -81358E36 1A42 -81358E37 1A43 -81358E38 1A44 -81358E39 1A45 -81358F30 1A46 -81358F31 1A47 -81358F32 1A48 -81358F33 1A49 -81358F34 1A4A -81358F35 1A4B -81358F36 1A4C -81358F37 1A4D -81358F38 1A4E -81358F39 1A4F -81359030 1A50 -81359031 1A51 -81359032 1A52 -81359033 1A53 -81359034 1A54 -81359035 1A55 -81359036 1A56 -81359037 1A57 -81359038 1A58 -81359039 1A59 -81359130 1A5A -81359131 1A5B -81359132 1A5C -81359133 1A5D -81359134 1A5E -81359135 1A5F -81359136 1A60 -81359137 1A61 -81359138 1A62 -81359139 1A63 -81359230 1A64 -81359231 1A65 -81359232 1A66 -81359233 1A67 -81359234 1A68 -81359235 1A69 -81359236 1A6A -81359237 1A6B -81359238 1A6C -81359239 1A6D -81359330 1A6E -81359331 1A6F -81359332 1A70 -81359333 1A71 -81359334 1A72 -81359335 1A73 -81359336 1A74 -81359337 1A75 -81359338 1A76 -81359339 1A77 -81359430 1A78 -81359431 1A79 -81359432 1A7A -81359433 1A7B -81359434 1A7C -81359435 1A7D -81359436 1A7E -81359437 1A7F -81359438 1A80 -81359439 1A81 -81359530 1A82 -81359531 1A83 -81359532 1A84 -81359533 1A85 -81359534 1A86 -81359535 1A87 -81359536 1A88 -81359537 1A89 -81359538 1A8A -81359539 1A8B -81359630 1A8C -81359631 1A8D -81359632 1A8E -81359633 1A8F -81359634 1A90 -81359635 1A91 -81359636 1A92 -81359637 1A93 -81359638 1A94 -81359639 1A95 -81359730 1A96 -81359731 1A97 -81359732 1A98 -81359733 1A99 -81359734 1A9A -81359735 1A9B -81359736 1A9C -81359737 1A9D -81359738 1A9E -81359739 1A9F -81359830 1AA0 -81359831 1AA1 -81359832 1AA2 -81359833 1AA3 -81359834 1AA4 -81359835 1AA5 -81359836 1AA6 -81359837 1AA7 -81359838 1AA8 -81359839 1AA9 -81359930 1AAA -81359931 1AAB -81359932 1AAC -81359933 1AAD -81359934 1AAE -81359935 1AAF -81359936 1AB0 -81359937 1AB1 -81359938 1AB2 -81359939 1AB3 -81359A30 1AB4 -81359A31 1AB5 -81359A32 1AB6 -81359A33 1AB7 -81359A34 1AB8 -81359A35 1AB9 -81359A36 1ABA -81359A37 1ABB -81359A38 1ABC -81359A39 1ABD -81359B30 1ABE -81359B31 1ABF -81359B32 1AC0 -81359B33 1AC1 -81359B34 1AC2 -81359B35 1AC3 -81359B36 1AC4 -81359B37 1AC5 -81359B38 1AC6 -81359B39 1AC7 -81359C30 1AC8 -81359C31 1AC9 -81359C32 1ACA -81359C33 1ACB -81359C34 1ACC -81359C35 1ACD -81359C36 1ACE -81359C37 1ACF -81359C38 1AD0 -81359C39 1AD1 -81359D30 1AD2 -81359D31 1AD3 -81359D32 1AD4 -81359D33 1AD5 -81359D34 1AD6 -81359D35 1AD7 -81359D36 1AD8 -81359D37 1AD9 -81359D38 1ADA -81359D39 1ADB -81359E30 1ADC -81359E31 1ADD -81359E32 1ADE -81359E33 1ADF -81359E34 1AE0 -81359E35 1AE1 -81359E36 1AE2 -81359E37 1AE3 -81359E38 1AE4 -81359E39 1AE5 -81359F30 1AE6 -81359F31 1AE7 -81359F32 1AE8 -81359F33 1AE9 -81359F34 1AEA -81359F35 1AEB -81359F36 1AEC -81359F37 1AED -81359F38 1AEE -81359F39 1AEF -8135A030 1AF0 -8135A031 1AF1 -8135A032 1AF2 -8135A033 1AF3 -8135A034 1AF4 -8135A035 1AF5 -8135A036 1AF6 -8135A037 1AF7 -8135A038 1AF8 -8135A039 1AF9 -8135A130 1AFA -8135A131 1AFB -8135A132 1AFC -8135A133 1AFD -8135A134 1AFE -8135A135 1AFF -8135A136 1B00 -8135A137 1B01 -8135A138 1B02 -8135A139 1B03 -8135A230 1B04 -8135A231 1B05 -8135A232 1B06 -8135A233 1B07 -8135A234 1B08 -8135A235 1B09 -8135A236 1B0A -8135A237 1B0B -8135A238 1B0C -8135A239 1B0D -8135A330 1B0E -8135A331 1B0F -8135A332 1B10 -8135A333 1B11 -8135A334 1B12 -8135A335 1B13 -8135A336 1B14 -8135A337 1B15 -8135A338 1B16 -8135A339 1B17 -8135A430 1B18 -8135A431 1B19 -8135A432 1B1A -8135A433 1B1B -8135A434 1B1C -8135A435 1B1D -8135A436 1B1E -8135A437 1B1F -8135A438 1B20 -8135A439 1B21 -8135A530 1B22 -8135A531 1B23 -8135A532 1B24 -8135A533 1B25 -8135A534 1B26 -8135A535 1B27 -8135A536 1B28 -8135A537 1B29 -8135A538 1B2A -8135A539 1B2B -8135A630 1B2C -8135A631 1B2D -8135A632 1B2E -8135A633 1B2F -8135A634 1B30 -8135A635 1B31 -8135A636 1B32 -8135A637 1B33 -8135A638 1B34 -8135A639 1B35 -8135A730 1B36 -8135A731 1B37 -8135A732 1B38 -8135A733 1B39 -8135A734 1B3A -8135A735 1B3B -8135A736 1B3C -8135A737 1B3D -8135A738 1B3E -8135A739 1B3F -8135A830 1B40 -8135A831 1B41 -8135A832 1B42 -8135A833 1B43 -8135A834 1B44 -8135A835 1B45 -8135A836 1B46 -8135A837 1B47 -8135A838 1B48 -8135A839 1B49 -8135A930 1B4A -8135A931 1B4B -8135A932 1B4C -8135A933 1B4D -8135A934 1B4E -8135A935 1B4F -8135A936 1B50 -8135A937 1B51 -8135A938 1B52 -8135A939 1B53 -8135AA30 1B54 -8135AA31 1B55 -8135AA32 1B56 -8135AA33 1B57 -8135AA34 1B58 -8135AA35 1B59 -8135AA36 1B5A -8135AA37 1B5B -8135AA38 1B5C -8135AA39 1B5D -8135AB30 1B5E -8135AB31 1B5F -8135AB32 1B60 -8135AB33 1B61 -8135AB34 1B62 -8135AB35 1B63 -8135AB36 1B64 -8135AB37 1B65 -8135AB38 1B66 -8135AB39 1B67 -8135AC30 1B68 -8135AC31 1B69 -8135AC32 1B6A -8135AC33 1B6B -8135AC34 1B6C -8135AC35 1B6D -8135AC36 1B6E -8135AC37 1B6F -8135AC38 1B70 -8135AC39 1B71 -8135AD30 1B72 -8135AD31 1B73 -8135AD32 1B74 -8135AD33 1B75 -8135AD34 1B76 -8135AD35 1B77 -8135AD36 1B78 -8135AD37 1B79 -8135AD38 1B7A -8135AD39 1B7B -8135AE30 1B7C -8135AE31 1B7D -8135AE32 1B7E -8135AE33 1B7F -8135AE34 1B80 -8135AE35 1B81 -8135AE36 1B82 -8135AE37 1B83 -8135AE38 1B84 -8135AE39 1B85 -8135AF30 1B86 -8135AF31 1B87 -8135AF32 1B88 -8135AF33 1B89 -8135AF34 1B8A -8135AF35 1B8B -8135AF36 1B8C -8135AF37 1B8D -8135AF38 1B8E -8135AF39 1B8F -8135B030 1B90 -8135B031 1B91 -8135B032 1B92 -8135B033 1B93 -8135B034 1B94 -8135B035 1B95 -8135B036 1B96 -8135B037 1B97 -8135B038 1B98 -8135B039 1B99 -8135B130 1B9A -8135B131 1B9B -8135B132 1B9C -8135B133 1B9D -8135B134 1B9E -8135B135 1B9F -8135B136 1BA0 -8135B137 1BA1 -8135B138 1BA2 -8135B139 1BA3 -8135B230 1BA4 -8135B231 1BA5 -8135B232 1BA6 -8135B233 1BA7 -8135B234 1BA8 -8135B235 1BA9 -8135B236 1BAA -8135B237 1BAB -8135B238 1BAC -8135B239 1BAD -8135B330 1BAE -8135B331 1BAF -8135B332 1BB0 -8135B333 1BB1 -8135B334 1BB2 -8135B335 1BB3 -8135B336 1BB4 -8135B337 1BB5 -8135B338 1BB6 -8135B339 1BB7 -8135B430 1BB8 -8135B431 1BB9 -8135B432 1BBA -8135B433 1BBB -8135B434 1BBC -8135B435 1BBD -8135B436 1BBE -8135B437 1BBF -8135B438 1BC0 -8135B439 1BC1 -8135B530 1BC2 -8135B531 1BC3 -8135B532 1BC4 -8135B533 1BC5 -8135B534 1BC6 -8135B535 1BC7 -8135B536 1BC8 -8135B537 1BC9 -8135B538 1BCA -8135B539 1BCB -8135B630 1BCC -8135B631 1BCD -8135B632 1BCE -8135B633 1BCF -8135B634 1BD0 -8135B635 1BD1 -8135B636 1BD2 -8135B637 1BD3 -8135B638 1BD4 -8135B639 1BD5 -8135B730 1BD6 -8135B731 1BD7 -8135B732 1BD8 -8135B733 1BD9 -8135B734 1BDA -8135B735 1BDB -8135B736 1BDC -8135B737 1BDD -8135B738 1BDE -8135B739 1BDF -8135B830 1BE0 -8135B831 1BE1 -8135B832 1BE2 -8135B833 1BE3 -8135B834 1BE4 -8135B835 1BE5 -8135B836 1BE6 -8135B837 1BE7 -8135B838 1BE8 -8135B839 1BE9 -8135B930 1BEA -8135B931 1BEB -8135B932 1BEC -8135B933 1BED -8135B934 1BEE -8135B935 1BEF -8135B936 1BF0 -8135B937 1BF1 -8135B938 1BF2 -8135B939 1BF3 -8135BA30 1BF4 -8135BA31 1BF5 -8135BA32 1BF6 -8135BA33 1BF7 -8135BA34 1BF8 -8135BA35 1BF9 -8135BA36 1BFA -8135BA37 1BFB -8135BA38 1BFC -8135BA39 1BFD -8135BB30 1BFE -8135BB31 1BFF -8135BB32 1C00 -8135BB33 1C01 -8135BB34 1C02 -8135BB35 1C03 -8135BB36 1C04 -8135BB37 1C05 -8135BB38 1C06 -8135BB39 1C07 -8135BC30 1C08 -8135BC31 1C09 -8135BC32 1C0A -8135BC33 1C0B -8135BC34 1C0C -8135BC35 1C0D -8135BC36 1C0E -8135BC37 1C0F -8135BC38 1C10 -8135BC39 1C11 -8135BD30 1C12 -8135BD31 1C13 -8135BD32 1C14 -8135BD33 1C15 -8135BD34 1C16 -8135BD35 1C17 -8135BD36 1C18 -8135BD37 1C19 -8135BD38 1C1A -8135BD39 1C1B -8135BE30 1C1C -8135BE31 1C1D -8135BE32 1C1E -8135BE33 1C1F -8135BE34 1C20 -8135BE35 1C21 -8135BE36 1C22 -8135BE37 1C23 -8135BE38 1C24 -8135BE39 1C25 -8135BF30 1C26 -8135BF31 1C27 -8135BF32 1C28 -8135BF33 1C29 -8135BF34 1C2A -8135BF35 1C2B -8135BF36 1C2C -8135BF37 1C2D -8135BF38 1C2E -8135BF39 1C2F -8135C030 1C30 -8135C031 1C31 -8135C032 1C32 -8135C033 1C33 -8135C034 1C34 -8135C035 1C35 -8135C036 1C36 -8135C037 1C37 -8135C038 1C38 -8135C039 1C39 -8135C130 1C3A -8135C131 1C3B -8135C132 1C3C -8135C133 1C3D -8135C134 1C3E -8135C135 1C3F -8135C136 1C40 -8135C137 1C41 -8135C138 1C42 -8135C139 1C43 -8135C230 1C44 -8135C231 1C45 -8135C232 1C46 -8135C233 1C47 -8135C234 1C48 -8135C235 1C49 -8135C236 1C4A -8135C237 1C4B -8135C238 1C4C -8135C239 1C4D -8135C330 1C4E -8135C331 1C4F -8135C332 1C50 -8135C333 1C51 -8135C334 1C52 -8135C335 1C53 -8135C336 1C54 -8135C337 1C55 -8135C338 1C56 -8135C339 1C57 -8135C430 1C58 -8135C431 1C59 -8135C432 1C5A -8135C433 1C5B -8135C434 1C5C -8135C435 1C5D -8135C436 1C5E -8135C437 1C5F -8135C438 1C60 -8135C439 1C61 -8135C530 1C62 -8135C531 1C63 -8135C532 1C64 -8135C533 1C65 -8135C534 1C66 -8135C535 1C67 -8135C536 1C68 -8135C537 1C69 -8135C538 1C6A -8135C539 1C6B -8135C630 1C6C -8135C631 1C6D -8135C632 1C6E -8135C633 1C6F -8135C634 1C70 -8135C635 1C71 -8135C636 1C72 -8135C637 1C73 -8135C638 1C74 -8135C639 1C75 -8135C730 1C76 -8135C731 1C77 -8135C732 1C78 -8135C733 1C79 -8135C734 1C7A -8135C735 1C7B -8135C736 1C7C -8135C737 1C7D -8135C738 1C7E -8135C739 1C7F -8135C830 1C80 -8135C831 1C81 -8135C832 1C82 -8135C833 1C83 -8135C834 1C84 -8135C835 1C85 -8135C836 1C86 -8135C837 1C87 -8135C838 1C88 -8135C839 1C89 -8135C930 1C8A -8135C931 1C8B -8135C932 1C8C -8135C933 1C8D -8135C934 1C8E -8135C935 1C8F -8135C936 1C90 -8135C937 1C91 -8135C938 1C92 -8135C939 1C93 -8135CA30 1C94 -8135CA31 1C95 -8135CA32 1C96 -8135CA33 1C97 -8135CA34 1C98 -8135CA35 1C99 -8135CA36 1C9A -8135CA37 1C9B -8135CA38 1C9C -8135CA39 1C9D -8135CB30 1C9E -8135CB31 1C9F -8135CB32 1CA0 -8135CB33 1CA1 -8135CB34 1CA2 -8135CB35 1CA3 -8135CB36 1CA4 -8135CB37 1CA5 -8135CB38 1CA6 -8135CB39 1CA7 -8135CC30 1CA8 -8135CC31 1CA9 -8135CC32 1CAA -8135CC33 1CAB -8135CC34 1CAC -8135CC35 1CAD -8135CC36 1CAE -8135CC37 1CAF -8135CC38 1CB0 -8135CC39 1CB1 -8135CD30 1CB2 -8135CD31 1CB3 -8135CD32 1CB4 -8135CD33 1CB5 -8135CD34 1CB6 -8135CD35 1CB7 -8135CD36 1CB8 -8135CD37 1CB9 -8135CD38 1CBA -8135CD39 1CBB -8135CE30 1CBC -8135CE31 1CBD -8135CE32 1CBE -8135CE33 1CBF -8135CE34 1CC0 -8135CE35 1CC1 -8135CE36 1CC2 -8135CE37 1CC3 -8135CE38 1CC4 -8135CE39 1CC5 -8135CF30 1CC6 -8135CF31 1CC7 -8135CF32 1CC8 -8135CF33 1CC9 -8135CF34 1CCA -8135CF35 1CCB -8135CF36 1CCC -8135CF37 1CCD -8135CF38 1CCE -8135CF39 1CCF -8135D030 1CD0 -8135D031 1CD1 -8135D032 1CD2 -8135D033 1CD3 -8135D034 1CD4 -8135D035 1CD5 -8135D036 1CD6 -8135D037 1CD7 -8135D038 1CD8 -8135D039 1CD9 -8135D130 1CDA -8135D131 1CDB -8135D132 1CDC -8135D133 1CDD -8135D134 1CDE -8135D135 1CDF -8135D136 1CE0 -8135D137 1CE1 -8135D138 1CE2 -8135D139 1CE3 -8135D230 1CE4 -8135D231 1CE5 -8135D232 1CE6 -8135D233 1CE7 -8135D234 1CE8 -8135D235 1CE9 -8135D236 1CEA -8135D237 1CEB -8135D238 1CEC -8135D239 1CED -8135D330 1CEE -8135D331 1CEF -8135D332 1CF0 -8135D333 1CF1 -8135D334 1CF2 -8135D335 1CF3 -8135D336 1CF4 -8135D337 1CF5 -8135D338 1CF6 -8135D339 1CF7 -8135D430 1CF8 -8135D431 1CF9 -8135D432 1CFA -8135D433 1CFB -8135D434 1CFC -8135D435 1CFD -8135D436 1CFE -8135D437 1CFF -8135D438 1D00 -8135D439 1D01 -8135D530 1D02 -8135D531 1D03 -8135D532 1D04 -8135D533 1D05 -8135D534 1D06 -8135D535 1D07 -8135D536 1D08 -8135D537 1D09 -8135D538 1D0A -8135D539 1D0B -8135D630 1D0C -8135D631 1D0D -8135D632 1D0E -8135D633 1D0F -8135D634 1D10 -8135D635 1D11 -8135D636 1D12 -8135D637 1D13 -8135D638 1D14 -8135D639 1D15 -8135D730 1D16 -8135D731 1D17 -8135D732 1D18 -8135D733 1D19 -8135D734 1D1A -8135D735 1D1B -8135D736 1D1C -8135D737 1D1D -8135D738 1D1E -8135D739 1D1F -8135D830 1D20 -8135D831 1D21 -8135D832 1D22 -8135D833 1D23 -8135D834 1D24 -8135D835 1D25 -8135D836 1D26 -8135D837 1D27 -8135D838 1D28 -8135D839 1D29 -8135D930 1D2A -8135D931 1D2B -8135D932 1D2C -8135D933 1D2D -8135D934 1D2E -8135D935 1D2F -8135D936 1D30 -8135D937 1D31 -8135D938 1D32 -8135D939 1D33 -8135DA30 1D34 -8135DA31 1D35 -8135DA32 1D36 -8135DA33 1D37 -8135DA34 1D38 -8135DA35 1D39 -8135DA36 1D3A -8135DA37 1D3B -8135DA38 1D3C -8135DA39 1D3D -8135DB30 1D3E -8135DB31 1D3F -8135DB32 1D40 -8135DB33 1D41 -8135DB34 1D42 -8135DB35 1D43 -8135DB36 1D44 -8135DB37 1D45 -8135DB38 1D46 -8135DB39 1D47 -8135DC30 1D48 -8135DC31 1D49 -8135DC32 1D4A -8135DC33 1D4B -8135DC34 1D4C -8135DC35 1D4D -8135DC36 1D4E -8135DC37 1D4F -8135DC38 1D50 -8135DC39 1D51 -8135DD30 1D52 -8135DD31 1D53 -8135DD32 1D54 -8135DD33 1D55 -8135DD34 1D56 -8135DD35 1D57 -8135DD36 1D58 -8135DD37 1D59 -8135DD38 1D5A -8135DD39 1D5B -8135DE30 1D5C -8135DE31 1D5D -8135DE32 1D5E -8135DE33 1D5F -8135DE34 1D60 -8135DE35 1D61 -8135DE36 1D62 -8135DE37 1D63 -8135DE38 1D64 -8135DE39 1D65 -8135DF30 1D66 -8135DF31 1D67 -8135DF32 1D68 -8135DF33 1D69 -8135DF34 1D6A -8135DF35 1D6B -8135DF36 1D6C -8135DF37 1D6D -8135DF38 1D6E -8135DF39 1D6F -8135E030 1D70 -8135E031 1D71 -8135E032 1D72 -8135E033 1D73 -8135E034 1D74 -8135E035 1D75 -8135E036 1D76 -8135E037 1D77 -8135E038 1D78 -8135E039 1D79 -8135E130 1D7A -8135E131 1D7B -8135E132 1D7C -8135E133 1D7D -8135E134 1D7E -8135E135 1D7F -8135E136 1D80 -8135E137 1D81 -8135E138 1D82 -8135E139 1D83 -8135E230 1D84 -8135E231 1D85 -8135E232 1D86 -8135E233 1D87 -8135E234 1D88 -8135E235 1D89 -8135E236 1D8A -8135E237 1D8B -8135E238 1D8C -8135E239 1D8D -8135E330 1D8E -8135E331 1D8F -8135E332 1D90 -8135E333 1D91 -8135E334 1D92 -8135E335 1D93 -8135E336 1D94 -8135E337 1D95 -8135E338 1D96 -8135E339 1D97 -8135E430 1D98 -8135E431 1D99 -8135E432 1D9A -8135E433 1D9B -8135E434 1D9C -8135E435 1D9D -8135E436 1D9E -8135E437 1D9F -8135E438 1DA0 -8135E439 1DA1 -8135E530 1DA2 -8135E531 1DA3 -8135E532 1DA4 -8135E533 1DA5 -8135E534 1DA6 -8135E535 1DA7 -8135E536 1DA8 -8135E537 1DA9 -8135E538 1DAA -8135E539 1DAB -8135E630 1DAC -8135E631 1DAD -8135E632 1DAE -8135E633 1DAF -8135E634 1DB0 -8135E635 1DB1 -8135E636 1DB2 -8135E637 1DB3 -8135E638 1DB4 -8135E639 1DB5 -8135E730 1DB6 -8135E731 1DB7 -8135E732 1DB8 -8135E733 1DB9 -8135E734 1DBA -8135E735 1DBB -8135E736 1DBC -8135E737 1DBD -8135E738 1DBE -8135E739 1DBF -8135E830 1DC0 -8135E831 1DC1 -8135E832 1DC2 -8135E833 1DC3 -8135E834 1DC4 -8135E835 1DC5 -8135E836 1DC6 -8135E837 1DC7 -8135E838 1DC8 -8135E839 1DC9 -8135E930 1DCA -8135E931 1DCB -8135E932 1DCC -8135E933 1DCD -8135E934 1DCE -8135E935 1DCF -8135E936 1DD0 -8135E937 1DD1 -8135E938 1DD2 -8135E939 1DD3 -8135EA30 1DD4 -8135EA31 1DD5 -8135EA32 1DD6 -8135EA33 1DD7 -8135EA34 1DD8 -8135EA35 1DD9 -8135EA36 1DDA -8135EA37 1DDB -8135EA38 1DDC -8135EA39 1DDD -8135EB30 1DDE -8135EB31 1DDF -8135EB32 1DE0 -8135EB33 1DE1 -8135EB34 1DE2 -8135EB35 1DE3 -8135EB36 1DE4 -8135EB37 1DE5 -8135EB38 1DE6 -8135EB39 1DE7 -8135EC30 1DE8 -8135EC31 1DE9 -8135EC32 1DEA -8135EC33 1DEB -8135EC34 1DEC -8135EC35 1DED -8135EC36 1DEE -8135EC37 1DEF -8135EC38 1DF0 -8135EC39 1DF1 -8135ED30 1DF2 -8135ED31 1DF3 -8135ED32 1DF4 -8135ED33 1DF5 -8135ED34 1DF6 -8135ED35 1DF7 -8135ED36 1DF8 -8135ED37 1DF9 -8135ED38 1DFA -8135ED39 1DFB -8135EE30 1DFC -8135EE31 1DFD -8135EE32 1DFE -8135EE33 1DFF -8135EE34 1E00 -8135EE35 1E01 -8135EE36 1E02 -8135EE37 1E03 -8135EE38 1E04 -8135EE39 1E05 -8135EF30 1E06 -8135EF31 1E07 -8135EF32 1E08 -8135EF33 1E09 -8135EF34 1E0A -8135EF35 1E0B -8135EF36 1E0C -8135EF37 1E0D -8135EF38 1E0E -8135EF39 1E0F -8135F030 1E10 -8135F031 1E11 -8135F032 1E12 -8135F033 1E13 -8135F034 1E14 -8135F035 1E15 -8135F036 1E16 -8135F037 1E17 -8135F038 1E18 -8135F039 1E19 -8135F130 1E1A -8135F131 1E1B -8135F132 1E1C -8135F133 1E1D -8135F134 1E1E -8135F135 1E1F -8135F136 1E20 -8135F137 1E21 -8135F138 1E22 -8135F139 1E23 -8135F230 1E24 -8135F231 1E25 -8135F232 1E26 -8135F233 1E27 -8135F234 1E28 -8135F235 1E29 -8135F236 1E2A -8135F237 1E2B -8135F238 1E2C -8135F239 1E2D -8135F330 1E2E -8135F331 1E2F -8135F332 1E30 -8135F333 1E31 -8135F334 1E32 -8135F335 1E33 -8135F336 1E34 -8135F337 1E35 -8135F338 1E36 -8135F339 1E37 -8135F430 1E38 -8135F431 1E39 -8135F432 1E3A -8135F433 1E3B -8135F434 1E3C -8135F435 1E3D -8135F436 1E3E -8135F437 1E3F -8135F438 1E40 -8135F439 1E41 -8135F530 1E42 -8135F531 1E43 -8135F532 1E44 -8135F533 1E45 -8135F534 1E46 -8135F535 1E47 -8135F536 1E48 -8135F537 1E49 -8135F538 1E4A -8135F539 1E4B -8135F630 1E4C -8135F631 1E4D -8135F632 1E4E -8135F633 1E4F -8135F634 1E50 -8135F635 1E51 -8135F636 1E52 -8135F637 1E53 -8135F638 1E54 -8135F639 1E55 -8135F730 1E56 -8135F731 1E57 -8135F732 1E58 -8135F733 1E59 -8135F734 1E5A -8135F735 1E5B -8135F736 1E5C -8135F737 1E5D -8135F738 1E5E -8135F739 1E5F -8135F830 1E60 -8135F831 1E61 -8135F832 1E62 -8135F833 1E63 -8135F834 1E64 -8135F835 1E65 -8135F836 1E66 -8135F837 1E67 -8135F838 1E68 -8135F839 1E69 -8135F930 1E6A -8135F931 1E6B -8135F932 1E6C -8135F933 1E6D -8135F934 1E6E -8135F935 1E6F -8135F936 1E70 -8135F937 1E71 -8135F938 1E72 -8135F939 1E73 -8135FA30 1E74 -8135FA31 1E75 -8135FA32 1E76 -8135FA33 1E77 -8135FA34 1E78 -8135FA35 1E79 -8135FA36 1E7A -8135FA37 1E7B -8135FA38 1E7C -8135FA39 1E7D -8135FB30 1E7E -8135FB31 1E7F -8135FB32 1E80 -8135FB33 1E81 -8135FB34 1E82 -8135FB35 1E83 -8135FB36 1E84 -8135FB37 1E85 -8135FB38 1E86 -8135FB39 1E87 -8135FC30 1E88 -8135FC31 1E89 -8135FC32 1E8A -8135FC33 1E8B -8135FC34 1E8C -8135FC35 1E8D -8135FC36 1E8E -8135FC37 1E8F -8135FC38 1E90 -8135FC39 1E91 -8135FD30 1E92 -8135FD31 1E93 -8135FD32 1E94 -8135FD33 1E95 -8135FD34 1E96 -8135FD35 1E97 -8135FD36 1E98 -8135FD37 1E99 -8135FD38 1E9A -8135FD39 1E9B -8135FE30 1E9C -8135FE31 1E9D -8135FE32 1E9E -8135FE33 1E9F -8135FE34 1EA0 -8135FE35 1EA1 -8135FE36 1EA2 -8135FE37 1EA3 -8135FE38 1EA4 -8135FE39 1EA5 -81368130 1EA6 -81368131 1EA7 -81368132 1EA8 -81368133 1EA9 -81368134 1EAA -81368135 1EAB -81368136 1EAC -81368137 1EAD -81368138 1EAE -81368139 1EAF -81368230 1EB0 -81368231 1EB1 -81368232 1EB2 -81368233 1EB3 -81368234 1EB4 -81368235 1EB5 -81368236 1EB6 -81368237 1EB7 -81368238 1EB8 -81368239 1EB9 -81368330 1EBA -81368331 1EBB -81368332 1EBC -81368333 1EBD -81368334 1EBE -81368335 1EBF -81368336 1EC0 -81368337 1EC1 -81368338 1EC2 -81368339 1EC3 -81368430 1EC4 -81368431 1EC5 -81368432 1EC6 -81368433 1EC7 -81368434 1EC8 -81368435 1EC9 -81368436 1ECA -81368437 1ECB -81368438 1ECC -81368439 1ECD -81368530 1ECE -81368531 1ECF -81368532 1ED0 -81368533 1ED1 -81368534 1ED2 -81368535 1ED3 -81368536 1ED4 -81368537 1ED5 -81368538 1ED6 -81368539 1ED7 -81368630 1ED8 -81368631 1ED9 -81368632 1EDA -81368633 1EDB -81368634 1EDC -81368635 1EDD -81368636 1EDE -81368637 1EDF -81368638 1EE0 -81368639 1EE1 -81368730 1EE2 -81368731 1EE3 -81368732 1EE4 -81368733 1EE5 -81368734 1EE6 -81368735 1EE7 -81368736 1EE8 -81368737 1EE9 -81368738 1EEA -81368739 1EEB -81368830 1EEC -81368831 1EED -81368832 1EEE -81368833 1EEF -81368834 1EF0 -81368835 1EF1 -81368836 1EF2 -81368837 1EF3 -81368838 1EF4 -81368839 1EF5 -81368930 1EF6 -81368931 1EF7 -81368932 1EF8 -81368933 1EF9 -81368934 1EFA -81368935 1EFB -81368936 1EFC -81368937 1EFD -81368938 1EFE -81368939 1EFF -81368A30 1F00 -81368A31 1F01 -81368A32 1F02 -81368A33 1F03 -81368A34 1F04 -81368A35 1F05 -81368A36 1F06 -81368A37 1F07 -81368A38 1F08 -81368A39 1F09 -81368B30 1F0A -81368B31 1F0B -81368B32 1F0C -81368B33 1F0D -81368B34 1F0E -81368B35 1F0F -81368B36 1F10 -81368B37 1F11 -81368B38 1F12 -81368B39 1F13 -81368C30 1F14 -81368C31 1F15 -81368C32 1F16 -81368C33 1F17 -81368C34 1F18 -81368C35 1F19 -81368C36 1F1A -81368C37 1F1B -81368C38 1F1C -81368C39 1F1D -81368D30 1F1E -81368D31 1F1F -81368D32 1F20 -81368D33 1F21 -81368D34 1F22 -81368D35 1F23 -81368D36 1F24 -81368D37 1F25 -81368D38 1F26 -81368D39 1F27 -81368E30 1F28 -81368E31 1F29 -81368E32 1F2A -81368E33 1F2B -81368E34 1F2C -81368E35 1F2D -81368E36 1F2E -81368E37 1F2F -81368E38 1F30 -81368E39 1F31 -81368F30 1F32 -81368F31 1F33 -81368F32 1F34 -81368F33 1F35 -81368F34 1F36 -81368F35 1F37 -81368F36 1F38 -81368F37 1F39 -81368F38 1F3A -81368F39 1F3B -81369030 1F3C -81369031 1F3D -81369032 1F3E -81369033 1F3F -81369034 1F40 -81369035 1F41 -81369036 1F42 -81369037 1F43 -81369038 1F44 -81369039 1F45 -81369130 1F46 -81369131 1F47 -81369132 1F48 -81369133 1F49 -81369134 1F4A -81369135 1F4B -81369136 1F4C -81369137 1F4D -81369138 1F4E -81369139 1F4F -81369230 1F50 -81369231 1F51 -81369232 1F52 -81369233 1F53 -81369234 1F54 -81369235 1F55 -81369236 1F56 -81369237 1F57 -81369238 1F58 -81369239 1F59 -81369330 1F5A -81369331 1F5B -81369332 1F5C -81369333 1F5D -81369334 1F5E -81369335 1F5F -81369336 1F60 -81369337 1F61 -81369338 1F62 -81369339 1F63 -81369430 1F64 -81369431 1F65 -81369432 1F66 -81369433 1F67 -81369434 1F68 -81369435 1F69 -81369436 1F6A -81369437 1F6B -81369438 1F6C -81369439 1F6D -81369530 1F6E -81369531 1F6F -81369532 1F70 -81369533 1F71 -81369534 1F72 -81369535 1F73 -81369536 1F74 -81369537 1F75 -81369538 1F76 -81369539 1F77 -81369630 1F78 -81369631 1F79 -81369632 1F7A -81369633 1F7B -81369634 1F7C -81369635 1F7D -81369636 1F7E -81369637 1F7F -81369638 1F80 -81369639 1F81 -81369730 1F82 -81369731 1F83 -81369732 1F84 -81369733 1F85 -81369734 1F86 -81369735 1F87 -81369736 1F88 -81369737 1F89 -81369738 1F8A -81369739 1F8B -81369830 1F8C -81369831 1F8D -81369832 1F8E -81369833 1F8F -81369834 1F90 -81369835 1F91 -81369836 1F92 -81369837 1F93 -81369838 1F94 -81369839 1F95 -81369930 1F96 -81369931 1F97 -81369932 1F98 -81369933 1F99 -81369934 1F9A -81369935 1F9B -81369936 1F9C -81369937 1F9D -81369938 1F9E -81369939 1F9F -81369A30 1FA0 -81369A31 1FA1 -81369A32 1FA2 -81369A33 1FA3 -81369A34 1FA4 -81369A35 1FA5 -81369A36 1FA6 -81369A37 1FA7 -81369A38 1FA8 -81369A39 1FA9 -81369B30 1FAA -81369B31 1FAB -81369B32 1FAC -81369B33 1FAD -81369B34 1FAE -81369B35 1FAF -81369B36 1FB0 -81369B37 1FB1 -81369B38 1FB2 -81369B39 1FB3 -81369C30 1FB4 -81369C31 1FB5 -81369C32 1FB6 -81369C33 1FB7 -81369C34 1FB8 -81369C35 1FB9 -81369C36 1FBA -81369C37 1FBB -81369C38 1FBC -81369C39 1FBD -81369D30 1FBE -81369D31 1FBF -81369D32 1FC0 -81369D33 1FC1 -81369D34 1FC2 -81369D35 1FC3 -81369D36 1FC4 -81369D37 1FC5 -81369D38 1FC6 -81369D39 1FC7 -81369E30 1FC8 -81369E31 1FC9 -81369E32 1FCA -81369E33 1FCB -81369E34 1FCC -81369E35 1FCD -81369E36 1FCE -81369E37 1FCF -81369E38 1FD0 -81369E39 1FD1 -81369F30 1FD2 -81369F31 1FD3 -81369F32 1FD4 -81369F33 1FD5 -81369F34 1FD6 -81369F35 1FD7 -81369F36 1FD8 -81369F37 1FD9 -81369F38 1FDA -81369F39 1FDB -8136A030 1FDC -8136A031 1FDD -8136A032 1FDE -8136A033 1FDF -8136A034 1FE0 -8136A035 1FE1 -8136A036 1FE2 -8136A037 1FE3 -8136A038 1FE4 -8136A039 1FE5 -8136A130 1FE6 -8136A131 1FE7 -8136A132 1FE8 -8136A133 1FE9 -8136A134 1FEA -8136A135 1FEB -8136A136 1FEC -8136A137 1FED -8136A138 1FEE -8136A139 1FEF -8136A230 1FF0 -8136A231 1FF1 -8136A232 1FF2 -8136A233 1FF3 -8136A234 1FF4 -8136A235 1FF5 -8136A236 1FF6 -8136A237 1FF7 -8136A238 1FF8 -8136A239 1FF9 -8136A330 1FFA -8136A331 1FFB -8136A332 1FFC -8136A333 1FFD -8136A334 1FFE -8136A335 1FFF -8136A336 2000 -8136A337 2001 -8136A338 2002 -8136A339 2003 -8136A430 2004 -8136A431 2005 -8136A432 2006 -8136A433 2007 -8136A434 2008 -8136A435 2009 -8136A436 200A -8136A437 200B -8136A438 200C -8136A439 200D -8136A530 200E -8136A531 200F -A95C 2010 -8136A532 2011 -8136A533 2012 -A843 2013 -A1AA 2014 -A844 2015 -A1AC 2016 -8136A534 2017 -A1AE 2018 -A1AF 2019 -8136A535 201A -8136A536 201B -A1B0 201C -A1B1 201D -8136A537 201E -8136A538 201F -8136A539 2020 -8136A630 2021 -8136A631 2022 -8136A632 2023 -8136A633 2024 -A845 2025 -A1AD 2026 -8136A634 2027 -8136A635 2028 -8136A636 2029 -8136A637 202A -8136A638 202B -8136A639 202C -8136A730 202D -8136A731 202E -8136A732 202F -A1EB 2030 -8136A733 2031 -A1E4 2032 -A1E5 2033 -8136A734 2034 -A846 2035 -8136A735 2036 -8136A736 2037 -8136A737 2038 -8136A738 2039 -8136A739 203A -A1F9 203B -8136A830 203C -8136A831 203D -8136A832 203E -8136A833 203F -8136A834 2040 -8136A835 2041 -8136A836 2042 -8136A837 2043 -8136A838 2044 -8136A839 2045 -8136A930 2046 -8136A931 2047 -8136A932 2048 -8136A933 2049 -8136A934 204A -8136A935 204B -8136A936 204C -8136A937 204D -8136A938 204E -8136A939 204F -8136AA30 2050 -8136AA31 2051 -8136AA32 2052 -8136AA33 2053 -8136AA34 2054 -8136AA35 2055 -8136AA36 2056 -8136AA37 2057 -8136AA38 2058 -8136AA39 2059 -8136AB30 205A -8136AB31 205B -8136AB32 205C -8136AB33 205D -8136AB34 205E -8136AB35 205F -8136AB36 2060 -8136AB37 2061 -8136AB38 2062 -8136AB39 2063 -8136AC30 2064 -8136AC31 2065 -8136AC32 2066 -8136AC33 2067 -8136AC34 2068 -8136AC35 2069 -8136AC36 206A -8136AC37 206B -8136AC38 206C -8136AC39 206D -8136AD30 206E -8136AD31 206F -8136AD32 2070 -8136AD33 2071 -8136AD34 2072 -8136AD35 2073 -8136AD36 2074 -8136AD37 2075 -8136AD38 2076 -8136AD39 2077 -8136AE30 2078 -8136AE31 2079 -8136AE32 207A -8136AE33 207B -8136AE34 207C -8136AE35 207D -8136AE36 207E -8136AE37 207F -8136AE38 2080 -8136AE39 2081 -8136AF30 2082 -8136AF31 2083 -8136AF32 2084 -8136AF33 2085 -8136AF34 2086 -8136AF35 2087 -8136AF36 2088 -8136AF37 2089 -8136AF38 208A -8136AF39 208B -8136B030 208C -8136B031 208D -8136B032 208E -8136B033 208F -8136B034 2090 -8136B035 2091 -8136B036 2092 -8136B037 2093 -8136B038 2094 -8136B039 2095 -8136B130 2096 -8136B131 2097 -8136B132 2098 -8136B133 2099 -8136B134 209A -8136B135 209B -8136B136 209C -8136B137 209D -8136B138 209E -8136B139 209F -8136B230 20A0 -8136B231 20A1 -8136B232 20A2 -8136B233 20A3 -8136B234 20A4 -8136B235 20A5 -8136B236 20A6 -8136B237 20A7 -8136B238 20A8 -8136B239 20A9 -8136B330 20AA -8136B331 20AB -A2E3 20AC -8136B332 20AD -8136B333 20AE -8136B334 20AF -8136B335 20B0 -8136B336 20B1 -8136B337 20B2 -8136B338 20B3 -8136B339 20B4 -8136B430 20B5 -8136B431 20B6 -8136B432 20B7 -8136B433 20B8 -8136B434 20B9 -8136B435 20BA -8136B436 20BB -8136B437 20BC -8136B438 20BD -8136B439 20BE -8136B530 20BF -8136B531 20C0 -8136B532 20C1 -8136B533 20C2 -8136B534 20C3 -8136B535 20C4 -8136B536 20C5 -8136B537 20C6 -8136B538 20C7 -8136B539 20C8 -8136B630 20C9 -8136B631 20CA -8136B632 20CB -8136B633 20CC -8136B634 20CD -8136B635 20CE -8136B636 20CF -8136B637 20D0 -8136B638 20D1 -8136B639 20D2 -8136B730 20D3 -8136B731 20D4 -8136B732 20D5 -8136B733 20D6 -8136B734 20D7 -8136B735 20D8 -8136B736 20D9 -8136B737 20DA -8136B738 20DB -8136B739 20DC -8136B830 20DD -8136B831 20DE -8136B832 20DF -8136B833 20E0 -8136B834 20E1 -8136B835 20E2 -8136B836 20E3 -8136B837 20E4 -8136B838 20E5 -8136B839 20E6 -8136B930 20E7 -8136B931 20E8 -8136B932 20E9 -8136B933 20EA -8136B934 20EB -8136B935 20EC -8136B936 20ED -8136B937 20EE -8136B938 20EF -8136B939 20F0 -8136BA30 20F1 -8136BA31 20F2 -8136BA32 20F3 -8136BA33 20F4 -8136BA34 20F5 -8136BA35 20F6 -8136BA36 20F7 -8136BA37 20F8 -8136BA38 20F9 -8136BA39 20FA -8136BB30 20FB -8136BB31 20FC -8136BB32 20FD -8136BB33 20FE -8136BB34 20FF -8136BB35 2100 -8136BB36 2101 -8136BB37 2102 -A1E6 2103 -8136BB38 2104 -A847 2105 -8136BB39 2106 -8136BC30 2107 -8136BC31 2108 -A848 2109 -8136BC32 210A -8136BC33 210B -8136BC34 210C -8136BC35 210D -8136BC36 210E -8136BC37 210F -8136BC38 2110 -8136BC39 2111 -8136BD30 2112 -8136BD31 2113 -8136BD32 2114 -8136BD33 2115 -A1ED 2116 -8136BD34 2117 -8136BD35 2118 -8136BD36 2119 -8136BD37 211A -8136BD38 211B -8136BD39 211C -8136BE30 211D -8136BE31 211E -8136BE32 211F -8136BE33 2120 -A959 2121 -8136BE34 2122 -8136BE35 2123 -8136BE36 2124 -8136BE37 2125 -8136BE38 2126 -8136BE39 2127 -8136BF30 2128 -8136BF31 2129 -8136BF32 212A -8136BF33 212B -8136BF34 212C -8136BF35 212D -8136BF36 212E -8136BF37 212F -8136BF38 2130 -8136BF39 2131 -8136C030 2132 -8136C031 2133 -8136C032 2134 -8136C033 2135 -8136C034 2136 -8136C035 2137 -8136C036 2138 -8136C037 2139 -8136C038 213A -8136C039 213B -8136C130 213C -8136C131 213D -8136C132 213E -8136C133 213F -8136C134 2140 -8136C135 2141 -8136C136 2142 -8136C137 2143 -8136C138 2144 -8136C139 2145 -8136C230 2146 -8136C231 2147 -8136C232 2148 -8136C233 2149 -8136C234 214A -8136C235 214B -8136C236 214C -8136C237 214D -8136C238 214E -8136C239 214F -8136C330 2150 -8136C331 2151 -8136C332 2152 -8136C333 2153 -8136C334 2154 -8136C335 2155 -8136C336 2156 -8136C337 2157 -8136C338 2158 -8136C339 2159 -8136C430 215A -8136C431 215B -8136C432 215C -8136C433 215D -8136C434 215E -8136C435 215F -A2F1 2160 -A2F2 2161 -A2F3 2162 -A2F4 2163 -A2F5 2164 -A2F6 2165 -A2F7 2166 -A2F8 2167 -A2F9 2168 -A2FA 2169 -A2FB 216A -A2FC 216B -8136C436 216C -8136C437 216D -8136C438 216E -8136C439 216F -A2A1 2170 -A2A2 2171 -A2A3 2172 -A2A4 2173 -A2A5 2174 -A2A6 2175 -A2A7 2176 -A2A8 2177 -A2A9 2178 -A2AA 2179 -8136C530 217A -8136C531 217B -8136C532 217C -8136C533 217D -8136C534 217E -8136C535 217F -8136C536 2180 -8136C537 2181 -8136C538 2182 -8136C539 2183 -8136C630 2184 -8136C631 2185 -8136C632 2186 -8136C633 2187 -8136C634 2188 -8136C635 2189 -8136C636 218A -8136C637 218B -8136C638 218C -8136C639 218D -8136C730 218E -8136C731 218F -A1FB 2190 -A1FC 2191 -A1FA 2192 -A1FD 2193 -8136C732 2194 -8136C733 2195 -A849 2196 -A84A 2197 -A84B 2198 -A84C 2199 -8136C734 219A -8136C735 219B -8136C736 219C -8136C737 219D -8136C738 219E -8136C739 219F -8136C830 21A0 -8136C831 21A1 -8136C832 21A2 -8136C833 21A3 -8136C834 21A4 -8136C835 21A5 -8136C836 21A6 -8136C837 21A7 -8136C838 21A8 -8136C839 21A9 -8136C930 21AA -8136C931 21AB -8136C932 21AC -8136C933 21AD -8136C934 21AE -8136C935 21AF -8136C936 21B0 -8136C937 21B1 -8136C938 21B2 -8136C939 21B3 -8136CA30 21B4 -8136CA31 21B5 -8136CA32 21B6 -8136CA33 21B7 -8136CA34 21B8 -8136CA35 21B9 -8136CA36 21BA -8136CA37 21BB -8136CA38 21BC -8136CA39 21BD -8136CB30 21BE -8136CB31 21BF -8136CB32 21C0 -8136CB33 21C1 -8136CB34 21C2 -8136CB35 21C3 -8136CB36 21C4 -8136CB37 21C5 -8136CB38 21C6 -8136CB39 21C7 -8136CC30 21C8 -8136CC31 21C9 -8136CC32 21CA -8136CC33 21CB -8136CC34 21CC -8136CC35 21CD -8136CC36 21CE -8136CC37 21CF -8136CC38 21D0 -8136CC39 21D1 -8136CD30 21D2 -8136CD31 21D3 -8136CD32 21D4 -8136CD33 21D5 -8136CD34 21D6 -8136CD35 21D7 -8136CD36 21D8 -8136CD37 21D9 -8136CD38 21DA -8136CD39 21DB -8136CE30 21DC -8136CE31 21DD -8136CE32 21DE -8136CE33 21DF -8136CE34 21E0 -8136CE35 21E1 -8136CE36 21E2 -8136CE37 21E3 -8136CE38 21E4 -8136CE39 21E5 -8136CF30 21E6 -8136CF31 21E7 -8136CF32 21E8 -8136CF33 21E9 -8136CF34 21EA -8136CF35 21EB -8136CF36 21EC -8136CF37 21ED -8136CF38 21EE -8136CF39 21EF -8136D030 21F0 -8136D031 21F1 -8136D032 21F2 -8136D033 21F3 -8136D034 21F4 -8136D035 21F5 -8136D036 21F6 -8136D037 21F7 -8136D038 21F8 -8136D039 21F9 -8136D130 21FA -8136D131 21FB -8136D132 21FC -8136D133 21FD -8136D134 21FE -8136D135 21FF -8136D136 2200 -8136D137 2201 -8136D138 2202 -8136D139 2203 -8136D230 2204 -8136D231 2205 -8136D232 2206 -8136D233 2207 -A1CA 2208 -8136D234 2209 -8136D235 220A -8136D236 220B -8136D237 220C -8136D238 220D -8136D239 220E -A1C7 220F -8136D330 2210 -A1C6 2211 -8136D331 2212 -8136D332 2213 -8136D333 2214 -A84D 2215 -8136D334 2216 -8136D335 2217 -8136D336 2218 -8136D337 2219 -A1CC 221A -8136D338 221B -8136D339 221C -A1D8 221D -A1DE 221E -A84E 221F -A1CF 2220 -8136D430 2221 -8136D431 2222 -A84F 2223 -8136D432 2224 -A1CE 2225 -8136D433 2226 -A1C4 2227 -A1C5 2228 -A1C9 2229 -A1C8 222A -A1D2 222B -8136D434 222C -8136D435 222D -A1D3 222E -8136D436 222F -8136D437 2230 -8136D438 2231 -8136D439 2232 -8136D530 2233 -A1E0 2234 -A1DF 2235 -A1C3 2236 -A1CB 2237 -8136D531 2238 -8136D532 2239 -8136D533 223A -8136D534 223B -8136D535 223C -A1D7 223D -8136D536 223E -8136D537 223F -8136D538 2240 -8136D539 2241 -8136D630 2242 -8136D631 2243 -8136D632 2244 -8136D633 2245 -8136D634 2246 -8136D635 2247 -A1D6 2248 -8136D636 2249 -8136D637 224A -8136D638 224B -A1D5 224C -8136D639 224D -8136D730 224E -8136D731 224F -8136D732 2250 -8136D733 2251 -A850 2252 -8136D734 2253 -8136D735 2254 -8136D736 2255 -8136D737 2256 -8136D738 2257 -8136D739 2258 -8136D830 2259 -8136D831 225A -8136D832 225B -8136D833 225C -8136D834 225D -8136D835 225E -8136D836 225F -A1D9 2260 -A1D4 2261 -8136D837 2262 -8136D838 2263 -A1DC 2264 -A1DD 2265 -A851 2266 -A852 2267 -8136D839 2268 -8136D930 2269 -8136D931 226A -8136D932 226B -8136D933 226C -8136D934 226D -A1DA 226E -A1DB 226F -8136D935 2270 -8136D936 2271 -8136D937 2272 -8136D938 2273 -8136D939 2274 -8136DA30 2275 -8136DA31 2276 -8136DA32 2277 -8136DA33 2278 -8136DA34 2279 -8136DA35 227A -8136DA36 227B -8136DA37 227C -8136DA38 227D -8136DA39 227E -8136DB30 227F -8136DB31 2280 -8136DB32 2281 -8136DB33 2282 -8136DB34 2283 -8136DB35 2284 -8136DB36 2285 -8136DB37 2286 -8136DB38 2287 -8136DB39 2288 -8136DC30 2289 -8136DC31 228A -8136DC32 228B -8136DC33 228C -8136DC34 228D -8136DC35 228E -8136DC36 228F -8136DC37 2290 -8136DC38 2291 -8136DC39 2292 -8136DD30 2293 -8136DD31 2294 -A892 2295 -8136DD32 2296 -8136DD33 2297 -8136DD34 2298 -A1D1 2299 -8136DD35 229A -8136DD36 229B -8136DD37 229C -8136DD38 229D -8136DD39 229E -8136DE30 229F -8136DE31 22A0 -8136DE32 22A1 -8136DE33 22A2 -8136DE34 22A3 -8136DE35 22A4 -A1CD 22A5 -8136DE36 22A6 -8136DE37 22A7 -8136DE38 22A8 -8136DE39 22A9 -8136DF30 22AA -8136DF31 22AB -8136DF32 22AC -8136DF33 22AD -8136DF34 22AE -8136DF35 22AF -8136DF36 22B0 -8136DF37 22B1 -8136DF38 22B2 -8136DF39 22B3 -8136E030 22B4 -8136E031 22B5 -8136E032 22B6 -8136E033 22B7 -8136E034 22B8 -8136E035 22B9 -8136E036 22BA -8136E037 22BB -8136E038 22BC -8136E039 22BD -8136E130 22BE -A853 22BF -8136E131 22C0 -8136E132 22C1 -8136E133 22C2 -8136E134 22C3 -8136E135 22C4 -8136E136 22C5 -8136E137 22C6 -8136E138 22C7 -8136E139 22C8 -8136E230 22C9 -8136E231 22CA -8136E232 22CB -8136E233 22CC -8136E234 22CD -8136E235 22CE -8136E236 22CF -8136E237 22D0 -8136E238 22D1 -8136E239 22D2 -8136E330 22D3 -8136E331 22D4 -8136E332 22D5 -8136E333 22D6 -8136E334 22D7 -8136E335 22D8 -8136E336 22D9 -8136E337 22DA -8136E338 22DB -8136E339 22DC -8136E430 22DD -8136E431 22DE -8136E432 22DF -8136E433 22E0 -8136E434 22E1 -8136E435 22E2 -8136E436 22E3 -8136E437 22E4 -8136E438 22E5 -8136E439 22E6 -8136E530 22E7 -8136E531 22E8 -8136E532 22E9 -8136E533 22EA -8136E534 22EB -8136E535 22EC -8136E536 22ED -8136E537 22EE -8136E538 22EF -8136E539 22F0 -8136E630 22F1 -8136E631 22F2 -8136E632 22F3 -8136E633 22F4 -8136E634 22F5 -8136E635 22F6 -8136E636 22F7 -8136E637 22F8 -8136E638 22F9 -8136E639 22FA -8136E730 22FB -8136E731 22FC -8136E732 22FD -8136E733 22FE -8136E734 22FF -8136E735 2300 -8136E736 2301 -8136E737 2302 -8136E738 2303 -8136E739 2304 -8136E830 2305 -8136E831 2306 -8136E832 2307 -8136E833 2308 -8136E834 2309 -8136E835 230A -8136E836 230B -8136E837 230C -8136E838 230D -8136E839 230E -8136E930 230F -8136E931 2310 -8136E932 2311 -A1D0 2312 -8136E933 2313 -8136E934 2314 -8136E935 2315 -8136E936 2316 -8136E937 2317 -8136E938 2318 -8136E939 2319 -8136EA30 231A -8136EA31 231B -8136EA32 231C -8136EA33 231D -8136EA34 231E -8136EA35 231F -8136EA36 2320 -8136EA37 2321 -8136EA38 2322 -8136EA39 2323 -8136EB30 2324 -8136EB31 2325 -8136EB32 2326 -8136EB33 2327 -8136EB34 2328 -8136EB35 2329 -8136EB36 232A -8136EB37 232B -8136EB38 232C -8136EB39 232D -8136EC30 232E -8136EC31 232F -8136EC32 2330 -8136EC33 2331 -8136EC34 2332 -8136EC35 2333 -8136EC36 2334 -8136EC37 2335 -8136EC38 2336 -8136EC39 2337 -8136ED30 2338 -8136ED31 2339 -8136ED32 233A -8136ED33 233B -8136ED34 233C -8136ED35 233D -8136ED36 233E -8136ED37 233F -8136ED38 2340 -8136ED39 2341 -8136EE30 2342 -8136EE31 2343 -8136EE32 2344 -8136EE33 2345 -8136EE34 2346 -8136EE35 2347 -8136EE36 2348 -8136EE37 2349 -8136EE38 234A -8136EE39 234B -8136EF30 234C -8136EF31 234D -8136EF32 234E -8136EF33 234F -8136EF34 2350 -8136EF35 2351 -8136EF36 2352 -8136EF37 2353 -8136EF38 2354 -8136EF39 2355 -8136F030 2356 -8136F031 2357 -8136F032 2358 -8136F033 2359 -8136F034 235A -8136F035 235B -8136F036 235C -8136F037 235D -8136F038 235E -8136F039 235F -8136F130 2360 -8136F131 2361 -8136F132 2362 -8136F133 2363 -8136F134 2364 -8136F135 2365 -8136F136 2366 -8136F137 2367 -8136F138 2368 -8136F139 2369 -8136F230 236A -8136F231 236B -8136F232 236C -8136F233 236D -8136F234 236E -8136F235 236F -8136F236 2370 -8136F237 2371 -8136F238 2372 -8136F239 2373 -8136F330 2374 -8136F331 2375 -8136F332 2376 -8136F333 2377 -8136F334 2378 -8136F335 2379 -8136F336 237A -8136F337 237B -8136F338 237C -8136F339 237D -8136F430 237E -8136F431 237F -8136F432 2380 -8136F433 2381 -8136F434 2382 -8136F435 2383 -8136F436 2384 -8136F437 2385 -8136F438 2386 -8136F439 2387 -8136F530 2388 -8136F531 2389 -8136F532 238A -8136F533 238B -8136F534 238C -8136F535 238D -8136F536 238E -8136F537 238F -8136F538 2390 -8136F539 2391 -8136F630 2392 -8136F631 2393 -8136F632 2394 -8136F633 2395 -8136F634 2396 -8136F635 2397 -8136F636 2398 -8136F637 2399 -8136F638 239A -8136F639 239B -8136F730 239C -8136F731 239D -8136F732 239E -8136F733 239F -8136F734 23A0 -8136F735 23A1 -8136F736 23A2 -8136F737 23A3 -8136F738 23A4 -8136F739 23A5 -8136F830 23A6 -8136F831 23A7 -8136F832 23A8 -8136F833 23A9 -8136F834 23AA -8136F835 23AB -8136F836 23AC -8136F837 23AD -8136F838 23AE -8136F839 23AF -8136F930 23B0 -8136F931 23B1 -8136F932 23B2 -8136F933 23B3 -8136F934 23B4 -8136F935 23B5 -8136F936 23B6 -8136F937 23B7 -8136F938 23B8 -8136F939 23B9 -8136FA30 23BA -8136FA31 23BB -8136FA32 23BC -8136FA33 23BD -8136FA34 23BE -8136FA35 23BF -8136FA36 23C0 -8136FA37 23C1 -8136FA38 23C2 -8136FA39 23C3 -8136FB30 23C4 -8136FB31 23C5 -8136FB32 23C6 -8136FB33 23C7 -8136FB34 23C8 -8136FB35 23C9 -8136FB36 23CA -8136FB37 23CB -8136FB38 23CC -8136FB39 23CD -8136FC30 23CE -8136FC31 23CF -8136FC32 23D0 -8136FC33 23D1 -8136FC34 23D2 -8136FC35 23D3 -8136FC36 23D4 -8136FC37 23D5 -8136FC38 23D6 -8136FC39 23D7 -8136FD30 23D8 -8136FD31 23D9 -8136FD32 23DA -8136FD33 23DB -8136FD34 23DC -8136FD35 23DD -8136FD36 23DE -8136FD37 23DF -8136FD38 23E0 -8136FD39 23E1 -8136FE30 23E2 -8136FE31 23E3 -8136FE32 23E4 -8136FE33 23E5 -8136FE34 23E6 -8136FE35 23E7 -8136FE36 23E8 -8136FE37 23E9 -8136FE38 23EA -8136FE39 23EB -81378130 23EC -81378131 23ED -81378132 23EE -81378133 23EF -81378134 23F0 -81378135 23F1 -81378136 23F2 -81378137 23F3 -81378138 23F4 -81378139 23F5 -81378230 23F6 -81378231 23F7 -81378232 23F8 -81378233 23F9 -81378234 23FA -81378235 23FB -81378236 23FC -81378237 23FD -81378238 23FE -81378239 23FF -81378330 2400 -81378331 2401 -81378332 2402 -81378333 2403 -81378334 2404 -81378335 2405 -81378336 2406 -81378337 2407 -81378338 2408 -81378339 2409 -81378430 240A -81378431 240B -81378432 240C -81378433 240D -81378434 240E -81378435 240F -81378436 2410 -81378437 2411 -81378438 2412 -81378439 2413 -81378530 2414 -81378531 2415 -81378532 2416 -81378533 2417 -81378534 2418 -81378535 2419 -81378536 241A -81378537 241B -81378538 241C -81378539 241D -81378630 241E -81378631 241F -81378632 2420 -81378633 2421 -81378634 2422 -81378635 2423 -81378636 2424 -81378637 2425 -81378638 2426 -81378639 2427 -81378730 2428 -81378731 2429 -81378732 242A -81378733 242B -81378734 242C -81378735 242D -81378736 242E -81378737 242F -81378738 2430 -81378739 2431 -81378830 2432 -81378831 2433 -81378832 2434 -81378833 2435 -81378834 2436 -81378835 2437 -81378836 2438 -81378837 2439 -81378838 243A -81378839 243B -81378930 243C -81378931 243D -81378932 243E -81378933 243F -81378934 2440 -81378935 2441 -81378936 2442 -81378937 2443 -81378938 2444 -81378939 2445 -81378A30 2446 -81378A31 2447 -81378A32 2448 -81378A33 2449 -81378A34 244A -81378A35 244B -81378A36 244C -81378A37 244D -81378A38 244E -81378A39 244F -81378B30 2450 -81378B31 2451 -81378B32 2452 -81378B33 2453 -81378B34 2454 -81378B35 2455 -81378B36 2456 -81378B37 2457 -81378B38 2458 -81378B39 2459 -81378C30 245A -81378C31 245B -81378C32 245C -81378C33 245D -81378C34 245E -81378C35 245F -A2D9 2460 -A2DA 2461 -A2DB 2462 -A2DC 2463 -A2DD 2464 -A2DE 2465 -A2DF 2466 -A2E0 2467 -A2E1 2468 -A2E2 2469 -81378C36 246A -81378C37 246B -81378C38 246C -81378C39 246D -81378D30 246E -81378D31 246F -81378D32 2470 -81378D33 2471 -81378D34 2472 -81378D35 2473 -A2C5 2474 -A2C6 2475 -A2C7 2476 -A2C8 2477 -A2C9 2478 -A2CA 2479 -A2CB 247A -A2CC 247B -A2CD 247C -A2CE 247D -A2CF 247E -A2D0 247F -A2D1 2480 -A2D2 2481 -A2D3 2482 -A2D4 2483 -A2D5 2484 -A2D6 2485 -A2D7 2486 -A2D8 2487 -A2B1 2488 -A2B2 2489 -A2B3 248A -A2B4 248B -A2B5 248C -A2B6 248D -A2B7 248E -A2B8 248F -A2B9 2490 -A2BA 2491 -A2BB 2492 -A2BC 2493 -A2BD 2494 -A2BE 2495 -A2BF 2496 -A2C0 2497 -A2C1 2498 -A2C2 2499 -A2C3 249A -A2C4 249B -81378D36 249C -81378D37 249D -81378D38 249E -81378D39 249F -81378E30 24A0 -81378E31 24A1 -81378E32 24A2 -81378E33 24A3 -81378E34 24A4 -81378E35 24A5 -81378E36 24A6 -81378E37 24A7 -81378E38 24A8 -81378E39 24A9 -81378F30 24AA -81378F31 24AB -81378F32 24AC -81378F33 24AD -81378F34 24AE -81378F35 24AF -81378F36 24B0 -81378F37 24B1 -81378F38 24B2 -81378F39 24B3 -81379030 24B4 -81379031 24B5 -81379032 24B6 -81379033 24B7 -81379034 24B8 -81379035 24B9 -81379036 24BA -81379037 24BB -81379038 24BC -81379039 24BD -81379130 24BE -81379131 24BF -81379132 24C0 -81379133 24C1 -81379134 24C2 -81379135 24C3 -81379136 24C4 -81379137 24C5 -81379138 24C6 -81379139 24C7 -81379230 24C8 -81379231 24C9 -81379232 24CA -81379233 24CB -81379234 24CC -81379235 24CD -81379236 24CE -81379237 24CF -81379238 24D0 -81379239 24D1 -81379330 24D2 -81379331 24D3 -81379332 24D4 -81379333 24D5 -81379334 24D6 -81379335 24D7 -81379336 24D8 -81379337 24D9 -81379338 24DA -81379339 24DB -81379430 24DC -81379431 24DD -81379432 24DE -81379433 24DF -81379434 24E0 -81379435 24E1 -81379436 24E2 -81379437 24E3 -81379438 24E4 -81379439 24E5 -81379530 24E6 -81379531 24E7 -81379532 24E8 -81379533 24E9 -81379534 24EA -81379535 24EB -81379536 24EC -81379537 24ED -81379538 24EE -81379539 24EF -81379630 24F0 -81379631 24F1 -81379632 24F2 -81379633 24F3 -81379634 24F4 -81379635 24F5 -81379636 24F6 -81379637 24F7 -81379638 24F8 -81379639 24F9 -81379730 24FA -81379731 24FB -81379732 24FC -81379733 24FD -81379734 24FE -81379735 24FF -A9A4 2500 -A9A5 2501 -A9A6 2502 -A9A7 2503 -A9A8 2504 -A9A9 2505 -A9AA 2506 -A9AB 2507 -A9AC 2508 -A9AD 2509 -A9AE 250A -A9AF 250B -A9B0 250C -A9B1 250D -A9B2 250E -A9B3 250F -A9B4 2510 -A9B5 2511 -A9B6 2512 -A9B7 2513 -A9B8 2514 -A9B9 2515 -A9BA 2516 -A9BB 2517 -A9BC 2518 -A9BD 2519 -A9BE 251A -A9BF 251B -A9C0 251C -A9C1 251D -A9C2 251E -A9C3 251F -A9C4 2520 -A9C5 2521 -A9C6 2522 -A9C7 2523 -A9C8 2524 -A9C9 2525 -A9CA 2526 -A9CB 2527 -A9CC 2528 -A9CD 2529 -A9CE 252A -A9CF 252B -A9D0 252C -A9D1 252D -A9D2 252E -A9D3 252F -A9D4 2530 -A9D5 2531 -A9D6 2532 -A9D7 2533 -A9D8 2534 -A9D9 2535 -A9DA 2536 -A9DB 2537 -A9DC 2538 -A9DD 2539 -A9DE 253A -A9DF 253B -A9E0 253C -A9E1 253D -A9E2 253E -A9E3 253F -A9E4 2540 -A9E5 2541 -A9E6 2542 -A9E7 2543 -A9E8 2544 -A9E9 2545 -A9EA 2546 -A9EB 2547 -A9EC 2548 -A9ED 2549 -A9EE 254A -A9EF 254B -81379736 254C -81379737 254D -81379738 254E -81379739 254F -A854 2550 -A855 2551 -A856 2552 -A857 2553 -A858 2554 -A859 2555 -A85A 2556 -A85B 2557 -A85C 2558 -A85D 2559 -A85E 255A -A85F 255B -A860 255C -A861 255D -A862 255E -A863 255F -A864 2560 -A865 2561 -A866 2562 -A867 2563 -A868 2564 -A869 2565 -A86A 2566 -A86B 2567 -A86C 2568 -A86D 2569 -A86E 256A -A86F 256B -A870 256C -A871 256D -A872 256E -A873 256F -A874 2570 -A875 2571 -A876 2572 -A877 2573 -81379830 2574 -81379831 2575 -81379832 2576 -81379833 2577 -81379834 2578 -81379835 2579 -81379836 257A -81379837 257B -81379838 257C -81379839 257D -81379930 257E -81379931 257F -81379932 2580 -A878 2581 -A879 2582 -A87A 2583 -A87B 2584 -A87C 2585 -A87D 2586 -A87E 2587 -A880 2588 -A881 2589 -A882 258A -A883 258B -A884 258C -A885 258D -A886 258E -A887 258F -81379933 2590 -81379934 2591 -81379935 2592 -A888 2593 -A889 2594 -A88A 2595 -81379936 2596 -81379937 2597 -81379938 2598 -81379939 2599 -81379A30 259A -81379A31 259B -81379A32 259C -81379A33 259D -81379A34 259E -81379A35 259F -A1F6 25A0 -A1F5 25A1 -81379A36 25A2 -81379A37 25A3 -81379A38 25A4 -81379A39 25A5 -81379B30 25A6 -81379B31 25A7 -81379B32 25A8 -81379B33 25A9 -81379B34 25AA -81379B35 25AB -81379B36 25AC -81379B37 25AD -81379B38 25AE -81379B39 25AF -81379C30 25B0 -81379C31 25B1 -A1F8 25B2 -A1F7 25B3 -81379C32 25B4 -81379C33 25B5 -81379C34 25B6 -81379C35 25B7 -81379C36 25B8 -81379C37 25B9 -81379C38 25BA -81379C39 25BB -A88B 25BC -A88C 25BD -81379D30 25BE -81379D31 25BF -81379D32 25C0 -81379D33 25C1 -81379D34 25C2 -81379D35 25C3 -81379D36 25C4 -81379D37 25C5 -A1F4 25C6 -A1F3 25C7 -81379D38 25C8 -81379D39 25C9 -81379E30 25CA -A1F0 25CB -81379E31 25CC -81379E32 25CD -A1F2 25CE -A1F1 25CF -81379E33 25D0 -81379E34 25D1 -81379E35 25D2 -81379E36 25D3 -81379E37 25D4 -81379E38 25D5 -81379E39 25D6 -81379F30 25D7 -81379F31 25D8 -81379F32 25D9 -81379F33 25DA -81379F34 25DB -81379F35 25DC -81379F36 25DD -81379F37 25DE -81379F38 25DF -81379F39 25E0 -8137A030 25E1 -A88D 25E2 -A88E 25E3 -A88F 25E4 -A890 25E5 -8137A031 25E6 -8137A032 25E7 -8137A033 25E8 -8137A034 25E9 -8137A035 25EA -8137A036 25EB -8137A037 25EC -8137A038 25ED -8137A039 25EE -8137A130 25EF -8137A131 25F0 -8137A132 25F1 -8137A133 25F2 -8137A134 25F3 -8137A135 25F4 -8137A136 25F5 -8137A137 25F6 -8137A138 25F7 -8137A139 25F8 -8137A230 25F9 -8137A231 25FA -8137A232 25FB -8137A233 25FC -8137A234 25FD -8137A235 25FE -8137A236 25FF -8137A237 2600 -8137A238 2601 -8137A239 2602 -8137A330 2603 -8137A331 2604 -A1EF 2605 -A1EE 2606 -8137A332 2607 -8137A333 2608 -A891 2609 -8137A334 260A -8137A335 260B -8137A336 260C -8137A337 260D -8137A338 260E -8137A339 260F -8137A430 2610 -8137A431 2611 -8137A432 2612 -8137A433 2613 -8137A434 2614 -8137A435 2615 -8137A436 2616 -8137A437 2617 -8137A438 2618 -8137A439 2619 -8137A530 261A -8137A531 261B -8137A532 261C -8137A533 261D -8137A534 261E -8137A535 261F -8137A536 2620 -8137A537 2621 -8137A538 2622 -8137A539 2623 -8137A630 2624 -8137A631 2625 -8137A632 2626 -8137A633 2627 -8137A634 2628 -8137A635 2629 -8137A636 262A -8137A637 262B -8137A638 262C -8137A639 262D -8137A730 262E -8137A731 262F -8137A732 2630 -8137A733 2631 -8137A734 2632 -8137A735 2633 -8137A736 2634 -8137A737 2635 -8137A738 2636 -8137A739 2637 -8137A830 2638 -8137A831 2639 -8137A832 263A -8137A833 263B -8137A834 263C -8137A835 263D -8137A836 263E -8137A837 263F -A1E2 2640 -8137A838 2641 -A1E1 2642 -8137A839 2643 -8137A930 2644 -8137A931 2645 -8137A932 2646 -8137A933 2647 -8137A934 2648 -8137A935 2649 -8137A936 264A -8137A937 264B -8137A938 264C -8137A939 264D -8137AA30 264E -8137AA31 264F -8137AA32 2650 -8137AA33 2651 -8137AA34 2652 -8137AA35 2653 -8137AA36 2654 -8137AA37 2655 -8137AA38 2656 -8137AA39 2657 -8137AB30 2658 -8137AB31 2659 -8137AB32 265A -8137AB33 265B -8137AB34 265C -8137AB35 265D -8137AB36 265E -8137AB37 265F -8137AB38 2660 -8137AB39 2661 -8137AC30 2662 -8137AC31 2663 -8137AC32 2664 -8137AC33 2665 -8137AC34 2666 -8137AC35 2667 -8137AC36 2668 -8137AC37 2669 -8137AC38 266A -8137AC39 266B -8137AD30 266C -8137AD31 266D -8137AD32 266E -8137AD33 266F -8137AD34 2670 -8137AD35 2671 -8137AD36 2672 -8137AD37 2673 -8137AD38 2674 -8137AD39 2675 -8137AE30 2676 -8137AE31 2677 -8137AE32 2678 -8137AE33 2679 -8137AE34 267A -8137AE35 267B -8137AE36 267C -8137AE37 267D -8137AE38 267E -8137AE39 267F -8137AF30 2680 -8137AF31 2681 -8137AF32 2682 -8137AF33 2683 -8137AF34 2684 -8137AF35 2685 -8137AF36 2686 -8137AF37 2687 -8137AF38 2688 -8137AF39 2689 -8137B030 268A -8137B031 268B -8137B032 268C -8137B033 268D -8137B034 268E -8137B035 268F -8137B036 2690 -8137B037 2691 -8137B038 2692 -8137B039 2693 -8137B130 2694 -8137B131 2695 -8137B132 2696 -8137B133 2697 -8137B134 2698 -8137B135 2699 -8137B136 269A -8137B137 269B -8137B138 269C -8137B139 269D -8137B230 269E -8137B231 269F -8137B232 26A0 -8137B233 26A1 -8137B234 26A2 -8137B235 26A3 -8137B236 26A4 -8137B237 26A5 -8137B238 26A6 -8137B239 26A7 -8137B330 26A8 -8137B331 26A9 -8137B332 26AA -8137B333 26AB -8137B334 26AC -8137B335 26AD -8137B336 26AE -8137B337 26AF -8137B338 26B0 -8137B339 26B1 -8137B430 26B2 -8137B431 26B3 -8137B432 26B4 -8137B433 26B5 -8137B434 26B6 -8137B435 26B7 -8137B436 26B8 -8137B437 26B9 -8137B438 26BA -8137B439 26BB -8137B530 26BC -8137B531 26BD -8137B532 26BE -8137B533 26BF -8137B534 26C0 -8137B535 26C1 -8137B536 26C2 -8137B537 26C3 -8137B538 26C4 -8137B539 26C5 -8137B630 26C6 -8137B631 26C7 -8137B632 26C8 -8137B633 26C9 -8137B634 26CA -8137B635 26CB -8137B636 26CC -8137B637 26CD -8137B638 26CE -8137B639 26CF -8137B730 26D0 -8137B731 26D1 -8137B732 26D2 -8137B733 26D3 -8137B734 26D4 -8137B735 26D5 -8137B736 26D6 -8137B737 26D7 -8137B738 26D8 -8137B739 26D9 -8137B830 26DA -8137B831 26DB -8137B832 26DC -8137B833 26DD -8137B834 26DE -8137B835 26DF -8137B836 26E0 -8137B837 26E1 -8137B838 26E2 -8137B839 26E3 -8137B930 26E4 -8137B931 26E5 -8137B932 26E6 -8137B933 26E7 -8137B934 26E8 -8137B935 26E9 -8137B936 26EA -8137B937 26EB -8137B938 26EC -8137B939 26ED -8137BA30 26EE -8137BA31 26EF -8137BA32 26F0 -8137BA33 26F1 -8137BA34 26F2 -8137BA35 26F3 -8137BA36 26F4 -8137BA37 26F5 -8137BA38 26F6 -8137BA39 26F7 -8137BB30 26F8 -8137BB31 26F9 -8137BB32 26FA -8137BB33 26FB -8137BB34 26FC -8137BB35 26FD -8137BB36 26FE -8137BB37 26FF -8137BB38 2700 -8137BB39 2701 -8137BC30 2702 -8137BC31 2703 -8137BC32 2704 -8137BC33 2705 -8137BC34 2706 -8137BC35 2707 -8137BC36 2708 -8137BC37 2709 -8137BC38 270A -8137BC39 270B -8137BD30 270C -8137BD31 270D -8137BD32 270E -8137BD33 270F -8137BD34 2710 -8137BD35 2711 -8137BD36 2712 -8137BD37 2713 -8137BD38 2714 -8137BD39 2715 -8137BE30 2716 -8137BE31 2717 -8137BE32 2718 -8137BE33 2719 -8137BE34 271A -8137BE35 271B -8137BE36 271C -8137BE37 271D -8137BE38 271E -8137BE39 271F -8137BF30 2720 -8137BF31 2721 -8137BF32 2722 -8137BF33 2723 -8137BF34 2724 -8137BF35 2725 -8137BF36 2726 -8137BF37 2727 -8137BF38 2728 -8137BF39 2729 -8137C030 272A -8137C031 272B -8137C032 272C -8137C033 272D -8137C034 272E -8137C035 272F -8137C036 2730 -8137C037 2731 -8137C038 2732 -8137C039 2733 -8137C130 2734 -8137C131 2735 -8137C132 2736 -8137C133 2737 -8137C134 2738 -8137C135 2739 -8137C136 273A -8137C137 273B -8137C138 273C -8137C139 273D -8137C230 273E -8137C231 273F -8137C232 2740 -8137C233 2741 -8137C234 2742 -8137C235 2743 -8137C236 2744 -8137C237 2745 -8137C238 2746 -8137C239 2747 -8137C330 2748 -8137C331 2749 -8137C332 274A -8137C333 274B -8137C334 274C -8137C335 274D -8137C336 274E -8137C337 274F -8137C338 2750 -8137C339 2751 -8137C430 2752 -8137C431 2753 -8137C432 2754 -8137C433 2755 -8137C434 2756 -8137C435 2757 -8137C436 2758 -8137C437 2759 -8137C438 275A -8137C439 275B -8137C530 275C -8137C531 275D -8137C532 275E -8137C533 275F -8137C534 2760 -8137C535 2761 -8137C536 2762 -8137C537 2763 -8137C538 2764 -8137C539 2765 -8137C630 2766 -8137C631 2767 -8137C632 2768 -8137C633 2769 -8137C634 276A -8137C635 276B -8137C636 276C -8137C637 276D -8137C638 276E -8137C639 276F -8137C730 2770 -8137C731 2771 -8137C732 2772 -8137C733 2773 -8137C734 2774 -8137C735 2775 -8137C736 2776 -8137C737 2777 -8137C738 2778 -8137C739 2779 -8137C830 277A -8137C831 277B -8137C832 277C -8137C833 277D -8137C834 277E -8137C835 277F -8137C836 2780 -8137C837 2781 -8137C838 2782 -8137C839 2783 -8137C930 2784 -8137C931 2785 -8137C932 2786 -8137C933 2787 -8137C934 2788 -8137C935 2789 -8137C936 278A -8137C937 278B -8137C938 278C -8137C939 278D -8137CA30 278E -8137CA31 278F -8137CA32 2790 -8137CA33 2791 -8137CA34 2792 -8137CA35 2793 -8137CA36 2794 -8137CA37 2795 -8137CA38 2796 -8137CA39 2797 -8137CB30 2798 -8137CB31 2799 -8137CB32 279A -8137CB33 279B -8137CB34 279C -8137CB35 279D -8137CB36 279E -8137CB37 279F -8137CB38 27A0 -8137CB39 27A1 -8137CC30 27A2 -8137CC31 27A3 -8137CC32 27A4 -8137CC33 27A5 -8137CC34 27A6 -8137CC35 27A7 -8137CC36 27A8 -8137CC37 27A9 -8137CC38 27AA -8137CC39 27AB -8137CD30 27AC -8137CD31 27AD -8137CD32 27AE -8137CD33 27AF -8137CD34 27B0 -8137CD35 27B1 -8137CD36 27B2 -8137CD37 27B3 -8137CD38 27B4 -8137CD39 27B5 -8137CE30 27B6 -8137CE31 27B7 -8137CE32 27B8 -8137CE33 27B9 -8137CE34 27BA -8137CE35 27BB -8137CE36 27BC -8137CE37 27BD -8137CE38 27BE -8137CE39 27BF -8137CF30 27C0 -8137CF31 27C1 -8137CF32 27C2 -8137CF33 27C3 -8137CF34 27C4 -8137CF35 27C5 -8137CF36 27C6 -8137CF37 27C7 -8137CF38 27C8 -8137CF39 27C9 -8137D030 27CA -8137D031 27CB -8137D032 27CC -8137D033 27CD -8137D034 27CE -8137D035 27CF -8137D036 27D0 -8137D037 27D1 -8137D038 27D2 -8137D039 27D3 -8137D130 27D4 -8137D131 27D5 -8137D132 27D6 -8137D133 27D7 -8137D134 27D8 -8137D135 27D9 -8137D136 27DA -8137D137 27DB -8137D138 27DC -8137D139 27DD -8137D230 27DE -8137D231 27DF -8137D232 27E0 -8137D233 27E1 -8137D234 27E2 -8137D235 27E3 -8137D236 27E4 -8137D237 27E5 -8137D238 27E6 -8137D239 27E7 -8137D330 27E8 -8137D331 27E9 -8137D332 27EA -8137D333 27EB -8137D334 27EC -8137D335 27ED -8137D336 27EE -8137D337 27EF -8137D338 27F0 -8137D339 27F1 -8137D430 27F2 -8137D431 27F3 -8137D432 27F4 -8137D433 27F5 -8137D434 27F6 -8137D435 27F7 -8137D436 27F8 -8137D437 27F9 -8137D438 27FA -8137D439 27FB -8137D530 27FC -8137D531 27FD -8137D532 27FE -8137D533 27FF -8137D534 2800 -8137D535 2801 -8137D536 2802 -8137D537 2803 -8137D538 2804 -8137D539 2805 -8137D630 2806 -8137D631 2807 -8137D632 2808 -8137D633 2809 -8137D634 280A -8137D635 280B -8137D636 280C -8137D637 280D -8137D638 280E -8137D639 280F -8137D730 2810 -8137D731 2811 -8137D732 2812 -8137D733 2813 -8137D734 2814 -8137D735 2815 -8137D736 2816 -8137D737 2817 -8137D738 2818 -8137D739 2819 -8137D830 281A -8137D831 281B -8137D832 281C -8137D833 281D -8137D834 281E -8137D835 281F -8137D836 2820 -8137D837 2821 -8137D838 2822 -8137D839 2823 -8137D930 2824 -8137D931 2825 -8137D932 2826 -8137D933 2827 -8137D934 2828 -8137D935 2829 -8137D936 282A -8137D937 282B -8137D938 282C -8137D939 282D -8137DA30 282E -8137DA31 282F -8137DA32 2830 -8137DA33 2831 -8137DA34 2832 -8137DA35 2833 -8137DA36 2834 -8137DA37 2835 -8137DA38 2836 -8137DA39 2837 -8137DB30 2838 -8137DB31 2839 -8137DB32 283A -8137DB33 283B -8137DB34 283C -8137DB35 283D -8137DB36 283E -8137DB37 283F -8137DB38 2840 -8137DB39 2841 -8137DC30 2842 -8137DC31 2843 -8137DC32 2844 -8137DC33 2845 -8137DC34 2846 -8137DC35 2847 -8137DC36 2848 -8137DC37 2849 -8137DC38 284A -8137DC39 284B -8137DD30 284C -8137DD31 284D -8137DD32 284E -8137DD33 284F -8137DD34 2850 -8137DD35 2851 -8137DD36 2852 -8137DD37 2853 -8137DD38 2854 -8137DD39 2855 -8137DE30 2856 -8137DE31 2857 -8137DE32 2858 -8137DE33 2859 -8137DE34 285A -8137DE35 285B -8137DE36 285C -8137DE37 285D -8137DE38 285E -8137DE39 285F -8137DF30 2860 -8137DF31 2861 -8137DF32 2862 -8137DF33 2863 -8137DF34 2864 -8137DF35 2865 -8137DF36 2866 -8137DF37 2867 -8137DF38 2868 -8137DF39 2869 -8137E030 286A -8137E031 286B -8137E032 286C -8137E033 286D -8137E034 286E -8137E035 286F -8137E036 2870 -8137E037 2871 -8137E038 2872 -8137E039 2873 -8137E130 2874 -8137E131 2875 -8137E132 2876 -8137E133 2877 -8137E134 2878 -8137E135 2879 -8137E136 287A -8137E137 287B -8137E138 287C -8137E139 287D -8137E230 287E -8137E231 287F -8137E232 2880 -8137E233 2881 -8137E234 2882 -8137E235 2883 -8137E236 2884 -8137E237 2885 -8137E238 2886 -8137E239 2887 -8137E330 2888 -8137E331 2889 -8137E332 288A -8137E333 288B -8137E334 288C -8137E335 288D -8137E336 288E -8137E337 288F -8137E338 2890 -8137E339 2891 -8137E430 2892 -8137E431 2893 -8137E432 2894 -8137E433 2895 -8137E434 2896 -8137E435 2897 -8137E436 2898 -8137E437 2899 -8137E438 289A -8137E439 289B -8137E530 289C -8137E531 289D -8137E532 289E -8137E533 289F -8137E534 28A0 -8137E535 28A1 -8137E536 28A2 -8137E537 28A3 -8137E538 28A4 -8137E539 28A5 -8137E630 28A6 -8137E631 28A7 -8137E632 28A8 -8137E633 28A9 -8137E634 28AA -8137E635 28AB -8137E636 28AC -8137E637 28AD -8137E638 28AE -8137E639 28AF -8137E730 28B0 -8137E731 28B1 -8137E732 28B2 -8137E733 28B3 -8137E734 28B4 -8137E735 28B5 -8137E736 28B6 -8137E737 28B7 -8137E738 28B8 -8137E739 28B9 -8137E830 28BA -8137E831 28BB -8137E832 28BC -8137E833 28BD -8137E834 28BE -8137E835 28BF -8137E836 28C0 -8137E837 28C1 -8137E838 28C2 -8137E839 28C3 -8137E930 28C4 -8137E931 28C5 -8137E932 28C6 -8137E933 28C7 -8137E934 28C8 -8137E935 28C9 -8137E936 28CA -8137E937 28CB -8137E938 28CC -8137E939 28CD -8137EA30 28CE -8137EA31 28CF -8137EA32 28D0 -8137EA33 28D1 -8137EA34 28D2 -8137EA35 28D3 -8137EA36 28D4 -8137EA37 28D5 -8137EA38 28D6 -8137EA39 28D7 -8137EB30 28D8 -8137EB31 28D9 -8137EB32 28DA -8137EB33 28DB -8137EB34 28DC -8137EB35 28DD -8137EB36 28DE -8137EB37 28DF -8137EB38 28E0 -8137EB39 28E1 -8137EC30 28E2 -8137EC31 28E3 -8137EC32 28E4 -8137EC33 28E5 -8137EC34 28E6 -8137EC35 28E7 -8137EC36 28E8 -8137EC37 28E9 -8137EC38 28EA -8137EC39 28EB -8137ED30 28EC -8137ED31 28ED -8137ED32 28EE -8137ED33 28EF -8137ED34 28F0 -8137ED35 28F1 -8137ED36 28F2 -8137ED37 28F3 -8137ED38 28F4 -8137ED39 28F5 -8137EE30 28F6 -8137EE31 28F7 -8137EE32 28F8 -8137EE33 28F9 -8137EE34 28FA -8137EE35 28FB -8137EE36 28FC -8137EE37 28FD -8137EE38 28FE -8137EE39 28FF -8137EF30 2900 -8137EF31 2901 -8137EF32 2902 -8137EF33 2903 -8137EF34 2904 -8137EF35 2905 -8137EF36 2906 -8137EF37 2907 -8137EF38 2908 -8137EF39 2909 -8137F030 290A -8137F031 290B -8137F032 290C -8137F033 290D -8137F034 290E -8137F035 290F -8137F036 2910 -8137F037 2911 -8137F038 2912 -8137F039 2913 -8137F130 2914 -8137F131 2915 -8137F132 2916 -8137F133 2917 -8137F134 2918 -8137F135 2919 -8137F136 291A -8137F137 291B -8137F138 291C -8137F139 291D -8137F230 291E -8137F231 291F -8137F232 2920 -8137F233 2921 -8137F234 2922 -8137F235 2923 -8137F236 2924 -8137F237 2925 -8137F238 2926 -8137F239 2927 -8137F330 2928 -8137F331 2929 -8137F332 292A -8137F333 292B -8137F334 292C -8137F335 292D -8137F336 292E -8137F337 292F -8137F338 2930 -8137F339 2931 -8137F430 2932 -8137F431 2933 -8137F432 2934 -8137F433 2935 -8137F434 2936 -8137F435 2937 -8137F436 2938 -8137F437 2939 -8137F438 293A -8137F439 293B -8137F530 293C -8137F531 293D -8137F532 293E -8137F533 293F -8137F534 2940 -8137F535 2941 -8137F536 2942 -8137F537 2943 -8137F538 2944 -8137F539 2945 -8137F630 2946 -8137F631 2947 -8137F632 2948 -8137F633 2949 -8137F634 294A -8137F635 294B -8137F636 294C -8137F637 294D -8137F638 294E -8137F639 294F -8137F730 2950 -8137F731 2951 -8137F732 2952 -8137F733 2953 -8137F734 2954 -8137F735 2955 -8137F736 2956 -8137F737 2957 -8137F738 2958 -8137F739 2959 -8137F830 295A -8137F831 295B -8137F832 295C -8137F833 295D -8137F834 295E -8137F835 295F -8137F836 2960 -8137F837 2961 -8137F838 2962 -8137F839 2963 -8137F930 2964 -8137F931 2965 -8137F932 2966 -8137F933 2967 -8137F934 2968 -8137F935 2969 -8137F936 296A -8137F937 296B -8137F938 296C -8137F939 296D -8137FA30 296E -8137FA31 296F -8137FA32 2970 -8137FA33 2971 -8137FA34 2972 -8137FA35 2973 -8137FA36 2974 -8137FA37 2975 -8137FA38 2976 -8137FA39 2977 -8137FB30 2978 -8137FB31 2979 -8137FB32 297A -8137FB33 297B -8137FB34 297C -8137FB35 297D -8137FB36 297E -8137FB37 297F -8137FB38 2980 -8137FB39 2981 -8137FC30 2982 -8137FC31 2983 -8137FC32 2984 -8137FC33 2985 -8137FC34 2986 -8137FC35 2987 -8137FC36 2988 -8137FC37 2989 -8137FC38 298A -8137FC39 298B -8137FD30 298C -8137FD31 298D -8137FD32 298E -8137FD33 298F -8137FD34 2990 -8137FD35 2991 -8137FD36 2992 -8137FD37 2993 -8137FD38 2994 -8137FD39 2995 -8137FE30 2996 -8137FE31 2997 -8137FE32 2998 -8137FE33 2999 -8137FE34 299A -8137FE35 299B -8137FE36 299C -8137FE37 299D -8137FE38 299E -8137FE39 299F -81388130 29A0 -81388131 29A1 -81388132 29A2 -81388133 29A3 -81388134 29A4 -81388135 29A5 -81388136 29A6 -81388137 29A7 -81388138 29A8 -81388139 29A9 -81388230 29AA -81388231 29AB -81388232 29AC -81388233 29AD -81388234 29AE -81388235 29AF -81388236 29B0 -81388237 29B1 -81388238 29B2 -81388239 29B3 -81388330 29B4 -81388331 29B5 -81388332 29B6 -81388333 29B7 -81388334 29B8 -81388335 29B9 -81388336 29BA -81388337 29BB -81388338 29BC -81388339 29BD -81388430 29BE -81388431 29BF -81388432 29C0 -81388433 29C1 -81388434 29C2 -81388435 29C3 -81388436 29C4 -81388437 29C5 -81388438 29C6 -81388439 29C7 -81388530 29C8 -81388531 29C9 -81388532 29CA -81388533 29CB -81388534 29CC -81388535 29CD -81388536 29CE -81388537 29CF -81388538 29D0 -81388539 29D1 -81388630 29D2 -81388631 29D3 -81388632 29D4 -81388633 29D5 -81388634 29D6 -81388635 29D7 -81388636 29D8 -81388637 29D9 -81388638 29DA -81388639 29DB -81388730 29DC -81388731 29DD -81388732 29DE -81388733 29DF -81388734 29E0 -81388735 29E1 -81388736 29E2 -81388737 29E3 -81388738 29E4 -81388739 29E5 -81388830 29E6 -81388831 29E7 -81388832 29E8 -81388833 29E9 -81388834 29EA -81388835 29EB -81388836 29EC -81388837 29ED -81388838 29EE -81388839 29EF -81388930 29F0 -81388931 29F1 -81388932 29F2 -81388933 29F3 -81388934 29F4 -81388935 29F5 -81388936 29F6 -81388937 29F7 -81388938 29F8 -81388939 29F9 -81388A30 29FA -81388A31 29FB -81388A32 29FC -81388A33 29FD -81388A34 29FE -81388A35 29FF -81388A36 2A00 -81388A37 2A01 -81388A38 2A02 -81388A39 2A03 -81388B30 2A04 -81388B31 2A05 -81388B32 2A06 -81388B33 2A07 -81388B34 2A08 -81388B35 2A09 -81388B36 2A0A -81388B37 2A0B -81388B38 2A0C -81388B39 2A0D -81388C30 2A0E -81388C31 2A0F -81388C32 2A10 -81388C33 2A11 -81388C34 2A12 -81388C35 2A13 -81388C36 2A14 -81388C37 2A15 -81388C38 2A16 -81388C39 2A17 -81388D30 2A18 -81388D31 2A19 -81388D32 2A1A -81388D33 2A1B -81388D34 2A1C -81388D35 2A1D -81388D36 2A1E -81388D37 2A1F -81388D38 2A20 -81388D39 2A21 -81388E30 2A22 -81388E31 2A23 -81388E32 2A24 -81388E33 2A25 -81388E34 2A26 -81388E35 2A27 -81388E36 2A28 -81388E37 2A29 -81388E38 2A2A -81388E39 2A2B -81388F30 2A2C -81388F31 2A2D -81388F32 2A2E -81388F33 2A2F -81388F34 2A30 -81388F35 2A31 -81388F36 2A32 -81388F37 2A33 -81388F38 2A34 -81388F39 2A35 -81389030 2A36 -81389031 2A37 -81389032 2A38 -81389033 2A39 -81389034 2A3A -81389035 2A3B -81389036 2A3C -81389037 2A3D -81389038 2A3E -81389039 2A3F -81389130 2A40 -81389131 2A41 -81389132 2A42 -81389133 2A43 -81389134 2A44 -81389135 2A45 -81389136 2A46 -81389137 2A47 -81389138 2A48 -81389139 2A49 -81389230 2A4A -81389231 2A4B -81389232 2A4C -81389233 2A4D -81389234 2A4E -81389235 2A4F -81389236 2A50 -81389237 2A51 -81389238 2A52 -81389239 2A53 -81389330 2A54 -81389331 2A55 -81389332 2A56 -81389333 2A57 -81389334 2A58 -81389335 2A59 -81389336 2A5A -81389337 2A5B -81389338 2A5C -81389339 2A5D -81389430 2A5E -81389431 2A5F -81389432 2A60 -81389433 2A61 -81389434 2A62 -81389435 2A63 -81389436 2A64 -81389437 2A65 -81389438 2A66 -81389439 2A67 -81389530 2A68 -81389531 2A69 -81389532 2A6A -81389533 2A6B -81389534 2A6C -81389535 2A6D -81389536 2A6E -81389537 2A6F -81389538 2A70 -81389539 2A71 -81389630 2A72 -81389631 2A73 -81389632 2A74 -81389633 2A75 -81389634 2A76 -81389635 2A77 -81389636 2A78 -81389637 2A79 -81389638 2A7A -81389639 2A7B -81389730 2A7C -81389731 2A7D -81389732 2A7E -81389733 2A7F -81389734 2A80 -81389735 2A81 -81389736 2A82 -81389737 2A83 -81389738 2A84 -81389739 2A85 -81389830 2A86 -81389831 2A87 -81389832 2A88 -81389833 2A89 -81389834 2A8A -81389835 2A8B -81389836 2A8C -81389837 2A8D -81389838 2A8E -81389839 2A8F -81389930 2A90 -81389931 2A91 -81389932 2A92 -81389933 2A93 -81389934 2A94 -81389935 2A95 -81389936 2A96 -81389937 2A97 -81389938 2A98 -81389939 2A99 -81389A30 2A9A -81389A31 2A9B -81389A32 2A9C -81389A33 2A9D -81389A34 2A9E -81389A35 2A9F -81389A36 2AA0 -81389A37 2AA1 -81389A38 2AA2 -81389A39 2AA3 -81389B30 2AA4 -81389B31 2AA5 -81389B32 2AA6 -81389B33 2AA7 -81389B34 2AA8 -81389B35 2AA9 -81389B36 2AAA -81389B37 2AAB -81389B38 2AAC -81389B39 2AAD -81389C30 2AAE -81389C31 2AAF -81389C32 2AB0 -81389C33 2AB1 -81389C34 2AB2 -81389C35 2AB3 -81389C36 2AB4 -81389C37 2AB5 -81389C38 2AB6 -81389C39 2AB7 -81389D30 2AB8 -81389D31 2AB9 -81389D32 2ABA -81389D33 2ABB -81389D34 2ABC -81389D35 2ABD -81389D36 2ABE -81389D37 2ABF -81389D38 2AC0 -81389D39 2AC1 -81389E30 2AC2 -81389E31 2AC3 -81389E32 2AC4 -81389E33 2AC5 -81389E34 2AC6 -81389E35 2AC7 -81389E36 2AC8 -81389E37 2AC9 -81389E38 2ACA -81389E39 2ACB -81389F30 2ACC -81389F31 2ACD -81389F32 2ACE -81389F33 2ACF -81389F34 2AD0 -81389F35 2AD1 -81389F36 2AD2 -81389F37 2AD3 -81389F38 2AD4 -81389F39 2AD5 -8138A030 2AD6 -8138A031 2AD7 -8138A032 2AD8 -8138A033 2AD9 -8138A034 2ADA -8138A035 2ADB -8138A036 2ADC -8138A037 2ADD -8138A038 2ADE -8138A039 2ADF -8138A130 2AE0 -8138A131 2AE1 -8138A132 2AE2 -8138A133 2AE3 -8138A134 2AE4 -8138A135 2AE5 -8138A136 2AE6 -8138A137 2AE7 -8138A138 2AE8 -8138A139 2AE9 -8138A230 2AEA -8138A231 2AEB -8138A232 2AEC -8138A233 2AED -8138A234 2AEE -8138A235 2AEF -8138A236 2AF0 -8138A237 2AF1 -8138A238 2AF2 -8138A239 2AF3 -8138A330 2AF4 -8138A331 2AF5 -8138A332 2AF6 -8138A333 2AF7 -8138A334 2AF8 -8138A335 2AF9 -8138A336 2AFA -8138A337 2AFB -8138A338 2AFC -8138A339 2AFD -8138A430 2AFE -8138A431 2AFF -8138A432 2B00 -8138A433 2B01 -8138A434 2B02 -8138A435 2B03 -8138A436 2B04 -8138A437 2B05 -8138A438 2B06 -8138A439 2B07 -8138A530 2B08 -8138A531 2B09 -8138A532 2B0A -8138A533 2B0B -8138A534 2B0C -8138A535 2B0D -8138A536 2B0E -8138A537 2B0F -8138A538 2B10 -8138A539 2B11 -8138A630 2B12 -8138A631 2B13 -8138A632 2B14 -8138A633 2B15 -8138A634 2B16 -8138A635 2B17 -8138A636 2B18 -8138A637 2B19 -8138A638 2B1A -8138A639 2B1B -8138A730 2B1C -8138A731 2B1D -8138A732 2B1E -8138A733 2B1F -8138A734 2B20 -8138A735 2B21 -8138A736 2B22 -8138A737 2B23 -8138A738 2B24 -8138A739 2B25 -8138A830 2B26 -8138A831 2B27 -8138A832 2B28 -8138A833 2B29 -8138A834 2B2A -8138A835 2B2B -8138A836 2B2C -8138A837 2B2D -8138A838 2B2E -8138A839 2B2F -8138A930 2B30 -8138A931 2B31 -8138A932 2B32 -8138A933 2B33 -8138A934 2B34 -8138A935 2B35 -8138A936 2B36 -8138A937 2B37 -8138A938 2B38 -8138A939 2B39 -8138AA30 2B3A -8138AA31 2B3B -8138AA32 2B3C -8138AA33 2B3D -8138AA34 2B3E -8138AA35 2B3F -8138AA36 2B40 -8138AA37 2B41 -8138AA38 2B42 -8138AA39 2B43 -8138AB30 2B44 -8138AB31 2B45 -8138AB32 2B46 -8138AB33 2B47 -8138AB34 2B48 -8138AB35 2B49 -8138AB36 2B4A -8138AB37 2B4B -8138AB38 2B4C -8138AB39 2B4D -8138AC30 2B4E -8138AC31 2B4F -8138AC32 2B50 -8138AC33 2B51 -8138AC34 2B52 -8138AC35 2B53 -8138AC36 2B54 -8138AC37 2B55 -8138AC38 2B56 -8138AC39 2B57 -8138AD30 2B58 -8138AD31 2B59 -8138AD32 2B5A -8138AD33 2B5B -8138AD34 2B5C -8138AD35 2B5D -8138AD36 2B5E -8138AD37 2B5F -8138AD38 2B60 -8138AD39 2B61 -8138AE30 2B62 -8138AE31 2B63 -8138AE32 2B64 -8138AE33 2B65 -8138AE34 2B66 -8138AE35 2B67 -8138AE36 2B68 -8138AE37 2B69 -8138AE38 2B6A -8138AE39 2B6B -8138AF30 2B6C -8138AF31 2B6D -8138AF32 2B6E -8138AF33 2B6F -8138AF34 2B70 -8138AF35 2B71 -8138AF36 2B72 -8138AF37 2B73 -8138AF38 2B74 -8138AF39 2B75 -8138B030 2B76 -8138B031 2B77 -8138B032 2B78 -8138B033 2B79 -8138B034 2B7A -8138B035 2B7B -8138B036 2B7C -8138B037 2B7D -8138B038 2B7E -8138B039 2B7F -8138B130 2B80 -8138B131 2B81 -8138B132 2B82 -8138B133 2B83 -8138B134 2B84 -8138B135 2B85 -8138B136 2B86 -8138B137 2B87 -8138B138 2B88 -8138B139 2B89 -8138B230 2B8A -8138B231 2B8B -8138B232 2B8C -8138B233 2B8D -8138B234 2B8E -8138B235 2B8F -8138B236 2B90 -8138B237 2B91 -8138B238 2B92 -8138B239 2B93 -8138B330 2B94 -8138B331 2B95 -8138B332 2B96 -8138B333 2B97 -8138B334 2B98 -8138B335 2B99 -8138B336 2B9A -8138B337 2B9B -8138B338 2B9C -8138B339 2B9D -8138B430 2B9E -8138B431 2B9F -8138B432 2BA0 -8138B433 2BA1 -8138B434 2BA2 -8138B435 2BA3 -8138B436 2BA4 -8138B437 2BA5 -8138B438 2BA6 -8138B439 2BA7 -8138B530 2BA8 -8138B531 2BA9 -8138B532 2BAA -8138B533 2BAB -8138B534 2BAC -8138B535 2BAD -8138B536 2BAE -8138B537 2BAF -8138B538 2BB0 -8138B539 2BB1 -8138B630 2BB2 -8138B631 2BB3 -8138B632 2BB4 -8138B633 2BB5 -8138B634 2BB6 -8138B635 2BB7 -8138B636 2BB8 -8138B637 2BB9 -8138B638 2BBA -8138B639 2BBB -8138B730 2BBC -8138B731 2BBD -8138B732 2BBE -8138B733 2BBF -8138B734 2BC0 -8138B735 2BC1 -8138B736 2BC2 -8138B737 2BC3 -8138B738 2BC4 -8138B739 2BC5 -8138B830 2BC6 -8138B831 2BC7 -8138B832 2BC8 -8138B833 2BC9 -8138B834 2BCA -8138B835 2BCB -8138B836 2BCC -8138B837 2BCD -8138B838 2BCE -8138B839 2BCF -8138B930 2BD0 -8138B931 2BD1 -8138B932 2BD2 -8138B933 2BD3 -8138B934 2BD4 -8138B935 2BD5 -8138B936 2BD6 -8138B937 2BD7 -8138B938 2BD8 -8138B939 2BD9 -8138BA30 2BDA -8138BA31 2BDB -8138BA32 2BDC -8138BA33 2BDD -8138BA34 2BDE -8138BA35 2BDF -8138BA36 2BE0 -8138BA37 2BE1 -8138BA38 2BE2 -8138BA39 2BE3 -8138BB30 2BE4 -8138BB31 2BE5 -8138BB32 2BE6 -8138BB33 2BE7 -8138BB34 2BE8 -8138BB35 2BE9 -8138BB36 2BEA -8138BB37 2BEB -8138BB38 2BEC -8138BB39 2BED -8138BC30 2BEE -8138BC31 2BEF -8138BC32 2BF0 -8138BC33 2BF1 -8138BC34 2BF2 -8138BC35 2BF3 -8138BC36 2BF4 -8138BC37 2BF5 -8138BC38 2BF6 -8138BC39 2BF7 -8138BD30 2BF8 -8138BD31 2BF9 -8138BD32 2BFA -8138BD33 2BFB -8138BD34 2BFC -8138BD35 2BFD -8138BD36 2BFE -8138BD37 2BFF -8138BD38 2C00 -8138BD39 2C01 -8138BE30 2C02 -8138BE31 2C03 -8138BE32 2C04 -8138BE33 2C05 -8138BE34 2C06 -8138BE35 2C07 -8138BE36 2C08 -8138BE37 2C09 -8138BE38 2C0A -8138BE39 2C0B -8138BF30 2C0C -8138BF31 2C0D -8138BF32 2C0E -8138BF33 2C0F -8138BF34 2C10 -8138BF35 2C11 -8138BF36 2C12 -8138BF37 2C13 -8138BF38 2C14 -8138BF39 2C15 -8138C030 2C16 -8138C031 2C17 -8138C032 2C18 -8138C033 2C19 -8138C034 2C1A -8138C035 2C1B -8138C036 2C1C -8138C037 2C1D -8138C038 2C1E -8138C039 2C1F -8138C130 2C20 -8138C131 2C21 -8138C132 2C22 -8138C133 2C23 -8138C134 2C24 -8138C135 2C25 -8138C136 2C26 -8138C137 2C27 -8138C138 2C28 -8138C139 2C29 -8138C230 2C2A -8138C231 2C2B -8138C232 2C2C -8138C233 2C2D -8138C234 2C2E -8138C235 2C2F -8138C236 2C30 -8138C237 2C31 -8138C238 2C32 -8138C239 2C33 -8138C330 2C34 -8138C331 2C35 -8138C332 2C36 -8138C333 2C37 -8138C334 2C38 -8138C335 2C39 -8138C336 2C3A -8138C337 2C3B -8138C338 2C3C -8138C339 2C3D -8138C430 2C3E -8138C431 2C3F -8138C432 2C40 -8138C433 2C41 -8138C434 2C42 -8138C435 2C43 -8138C436 2C44 -8138C437 2C45 -8138C438 2C46 -8138C439 2C47 -8138C530 2C48 -8138C531 2C49 -8138C532 2C4A -8138C533 2C4B -8138C534 2C4C -8138C535 2C4D -8138C536 2C4E -8138C537 2C4F -8138C538 2C50 -8138C539 2C51 -8138C630 2C52 -8138C631 2C53 -8138C632 2C54 -8138C633 2C55 -8138C634 2C56 -8138C635 2C57 -8138C636 2C58 -8138C637 2C59 -8138C638 2C5A -8138C639 2C5B -8138C730 2C5C -8138C731 2C5D -8138C732 2C5E -8138C733 2C5F -8138C734 2C60 -8138C735 2C61 -8138C736 2C62 -8138C737 2C63 -8138C738 2C64 -8138C739 2C65 -8138C830 2C66 -8138C831 2C67 -8138C832 2C68 -8138C833 2C69 -8138C834 2C6A -8138C835 2C6B -8138C836 2C6C -8138C837 2C6D -8138C838 2C6E -8138C839 2C6F -8138C930 2C70 -8138C931 2C71 -8138C932 2C72 -8138C933 2C73 -8138C934 2C74 -8138C935 2C75 -8138C936 2C76 -8138C937 2C77 -8138C938 2C78 -8138C939 2C79 -8138CA30 2C7A -8138CA31 2C7B -8138CA32 2C7C -8138CA33 2C7D -8138CA34 2C7E -8138CA35 2C7F -8138CA36 2C80 -8138CA37 2C81 -8138CA38 2C82 -8138CA39 2C83 -8138CB30 2C84 -8138CB31 2C85 -8138CB32 2C86 -8138CB33 2C87 -8138CB34 2C88 -8138CB35 2C89 -8138CB36 2C8A -8138CB37 2C8B -8138CB38 2C8C -8138CB39 2C8D -8138CC30 2C8E -8138CC31 2C8F -8138CC32 2C90 -8138CC33 2C91 -8138CC34 2C92 -8138CC35 2C93 -8138CC36 2C94 -8138CC37 2C95 -8138CC38 2C96 -8138CC39 2C97 -8138CD30 2C98 -8138CD31 2C99 -8138CD32 2C9A -8138CD33 2C9B -8138CD34 2C9C -8138CD35 2C9D -8138CD36 2C9E -8138CD37 2C9F -8138CD38 2CA0 -8138CD39 2CA1 -8138CE30 2CA2 -8138CE31 2CA3 -8138CE32 2CA4 -8138CE33 2CA5 -8138CE34 2CA6 -8138CE35 2CA7 -8138CE36 2CA8 -8138CE37 2CA9 -8138CE38 2CAA -8138CE39 2CAB -8138CF30 2CAC -8138CF31 2CAD -8138CF32 2CAE -8138CF33 2CAF -8138CF34 2CB0 -8138CF35 2CB1 -8138CF36 2CB2 -8138CF37 2CB3 -8138CF38 2CB4 -8138CF39 2CB5 -8138D030 2CB6 -8138D031 2CB7 -8138D032 2CB8 -8138D033 2CB9 -8138D034 2CBA -8138D035 2CBB -8138D036 2CBC -8138D037 2CBD -8138D038 2CBE -8138D039 2CBF -8138D130 2CC0 -8138D131 2CC1 -8138D132 2CC2 -8138D133 2CC3 -8138D134 2CC4 -8138D135 2CC5 -8138D136 2CC6 -8138D137 2CC7 -8138D138 2CC8 -8138D139 2CC9 -8138D230 2CCA -8138D231 2CCB -8138D232 2CCC -8138D233 2CCD -8138D234 2CCE -8138D235 2CCF -8138D236 2CD0 -8138D237 2CD1 -8138D238 2CD2 -8138D239 2CD3 -8138D330 2CD4 -8138D331 2CD5 -8138D332 2CD6 -8138D333 2CD7 -8138D334 2CD8 -8138D335 2CD9 -8138D336 2CDA -8138D337 2CDB -8138D338 2CDC -8138D339 2CDD -8138D430 2CDE -8138D431 2CDF -8138D432 2CE0 -8138D433 2CE1 -8138D434 2CE2 -8138D435 2CE3 -8138D436 2CE4 -8138D437 2CE5 -8138D438 2CE6 -8138D439 2CE7 -8138D530 2CE8 -8138D531 2CE9 -8138D532 2CEA -8138D533 2CEB -8138D534 2CEC -8138D535 2CED -8138D536 2CEE -8138D537 2CEF -8138D538 2CF0 -8138D539 2CF1 -8138D630 2CF2 -8138D631 2CF3 -8138D632 2CF4 -8138D633 2CF5 -8138D634 2CF6 -8138D635 2CF7 -8138D636 2CF8 -8138D637 2CF9 -8138D638 2CFA -8138D639 2CFB -8138D730 2CFC -8138D731 2CFD -8138D732 2CFE -8138D733 2CFF -8138D734 2D00 -8138D735 2D01 -8138D736 2D02 -8138D737 2D03 -8138D738 2D04 -8138D739 2D05 -8138D830 2D06 -8138D831 2D07 -8138D832 2D08 -8138D833 2D09 -8138D834 2D0A -8138D835 2D0B -8138D836 2D0C -8138D837 2D0D -8138D838 2D0E -8138D839 2D0F -8138D930 2D10 -8138D931 2D11 -8138D932 2D12 -8138D933 2D13 -8138D934 2D14 -8138D935 2D15 -8138D936 2D16 -8138D937 2D17 -8138D938 2D18 -8138D939 2D19 -8138DA30 2D1A -8138DA31 2D1B -8138DA32 2D1C -8138DA33 2D1D -8138DA34 2D1E -8138DA35 2D1F -8138DA36 2D20 -8138DA37 2D21 -8138DA38 2D22 -8138DA39 2D23 -8138DB30 2D24 -8138DB31 2D25 -8138DB32 2D26 -8138DB33 2D27 -8138DB34 2D28 -8138DB35 2D29 -8138DB36 2D2A -8138DB37 2D2B -8138DB38 2D2C -8138DB39 2D2D -8138DC30 2D2E -8138DC31 2D2F -8138DC32 2D30 -8138DC33 2D31 -8138DC34 2D32 -8138DC35 2D33 -8138DC36 2D34 -8138DC37 2D35 -8138DC38 2D36 -8138DC39 2D37 -8138DD30 2D38 -8138DD31 2D39 -8138DD32 2D3A -8138DD33 2D3B -8138DD34 2D3C -8138DD35 2D3D -8138DD36 2D3E -8138DD37 2D3F -8138DD38 2D40 -8138DD39 2D41 -8138DE30 2D42 -8138DE31 2D43 -8138DE32 2D44 -8138DE33 2D45 -8138DE34 2D46 -8138DE35 2D47 -8138DE36 2D48 -8138DE37 2D49 -8138DE38 2D4A -8138DE39 2D4B -8138DF30 2D4C -8138DF31 2D4D -8138DF32 2D4E -8138DF33 2D4F -8138DF34 2D50 -8138DF35 2D51 -8138DF36 2D52 -8138DF37 2D53 -8138DF38 2D54 -8138DF39 2D55 -8138E030 2D56 -8138E031 2D57 -8138E032 2D58 -8138E033 2D59 -8138E034 2D5A -8138E035 2D5B -8138E036 2D5C -8138E037 2D5D -8138E038 2D5E -8138E039 2D5F -8138E130 2D60 -8138E131 2D61 -8138E132 2D62 -8138E133 2D63 -8138E134 2D64 -8138E135 2D65 -8138E136 2D66 -8138E137 2D67 -8138E138 2D68 -8138E139 2D69 -8138E230 2D6A -8138E231 2D6B -8138E232 2D6C -8138E233 2D6D -8138E234 2D6E -8138E235 2D6F -8138E236 2D70 -8138E237 2D71 -8138E238 2D72 -8138E239 2D73 -8138E330 2D74 -8138E331 2D75 -8138E332 2D76 -8138E333 2D77 -8138E334 2D78 -8138E335 2D79 -8138E336 2D7A -8138E337 2D7B -8138E338 2D7C -8138E339 2D7D -8138E430 2D7E -8138E431 2D7F -8138E432 2D80 -8138E433 2D81 -8138E434 2D82 -8138E435 2D83 -8138E436 2D84 -8138E437 2D85 -8138E438 2D86 -8138E439 2D87 -8138E530 2D88 -8138E531 2D89 -8138E532 2D8A -8138E533 2D8B -8138E534 2D8C -8138E535 2D8D -8138E536 2D8E -8138E537 2D8F -8138E538 2D90 -8138E539 2D91 -8138E630 2D92 -8138E631 2D93 -8138E632 2D94 -8138E633 2D95 -8138E634 2D96 -8138E635 2D97 -8138E636 2D98 -8138E637 2D99 -8138E638 2D9A -8138E639 2D9B -8138E730 2D9C -8138E731 2D9D -8138E732 2D9E -8138E733 2D9F -8138E734 2DA0 -8138E735 2DA1 -8138E736 2DA2 -8138E737 2DA3 -8138E738 2DA4 -8138E739 2DA5 -8138E830 2DA6 -8138E831 2DA7 -8138E832 2DA8 -8138E833 2DA9 -8138E834 2DAA -8138E835 2DAB -8138E836 2DAC -8138E837 2DAD -8138E838 2DAE -8138E839 2DAF -8138E930 2DB0 -8138E931 2DB1 -8138E932 2DB2 -8138E933 2DB3 -8138E934 2DB4 -8138E935 2DB5 -8138E936 2DB6 -8138E937 2DB7 -8138E938 2DB8 -8138E939 2DB9 -8138EA30 2DBA -8138EA31 2DBB -8138EA32 2DBC -8138EA33 2DBD -8138EA34 2DBE -8138EA35 2DBF -8138EA36 2DC0 -8138EA37 2DC1 -8138EA38 2DC2 -8138EA39 2DC3 -8138EB30 2DC4 -8138EB31 2DC5 -8138EB32 2DC6 -8138EB33 2DC7 -8138EB34 2DC8 -8138EB35 2DC9 -8138EB36 2DCA -8138EB37 2DCB -8138EB38 2DCC -8138EB39 2DCD -8138EC30 2DCE -8138EC31 2DCF -8138EC32 2DD0 -8138EC33 2DD1 -8138EC34 2DD2 -8138EC35 2DD3 -8138EC36 2DD4 -8138EC37 2DD5 -8138EC38 2DD6 -8138EC39 2DD7 -8138ED30 2DD8 -8138ED31 2DD9 -8138ED32 2DDA -8138ED33 2DDB -8138ED34 2DDC -8138ED35 2DDD -8138ED36 2DDE -8138ED37 2DDF -8138ED38 2DE0 -8138ED39 2DE1 -8138EE30 2DE2 -8138EE31 2DE3 -8138EE32 2DE4 -8138EE33 2DE5 -8138EE34 2DE6 -8138EE35 2DE7 -8138EE36 2DE8 -8138EE37 2DE9 -8138EE38 2DEA -8138EE39 2DEB -8138EF30 2DEC -8138EF31 2DED -8138EF32 2DEE -8138EF33 2DEF -8138EF34 2DF0 -8138EF35 2DF1 -8138EF36 2DF2 -8138EF37 2DF3 -8138EF38 2DF4 -8138EF39 2DF5 -8138F030 2DF6 -8138F031 2DF7 -8138F032 2DF8 -8138F033 2DF9 -8138F034 2DFA -8138F035 2DFB -8138F036 2DFC -8138F037 2DFD -8138F038 2DFE -8138F039 2DFF -8138F130 2E00 -8138F131 2E01 -8138F132 2E02 -8138F133 2E03 -8138F134 2E04 -8138F135 2E05 -8138F136 2E06 -8138F137 2E07 -8138F138 2E08 -8138F139 2E09 -8138F230 2E0A -8138F231 2E0B -8138F232 2E0C -8138F233 2E0D -8138F234 2E0E -8138F235 2E0F -8138F236 2E10 -8138F237 2E11 -8138F238 2E12 -8138F239 2E13 -8138F330 2E14 -8138F331 2E15 -8138F332 2E16 -8138F333 2E17 -8138F334 2E18 -8138F335 2E19 -8138F336 2E1A -8138F337 2E1B -8138F338 2E1C -8138F339 2E1D -8138F430 2E1E -8138F431 2E1F -8138F432 2E20 -8138F433 2E21 -8138F434 2E22 -8138F435 2E23 -8138F436 2E24 -8138F437 2E25 -8138F438 2E26 -8138F439 2E27 -8138F530 2E28 -8138F531 2E29 -8138F532 2E2A -8138F533 2E2B -8138F534 2E2C -8138F535 2E2D -8138F536 2E2E -8138F537 2E2F -8138F538 2E30 -8138F539 2E31 -8138F630 2E32 -8138F631 2E33 -8138F632 2E34 -8138F633 2E35 -8138F634 2E36 -8138F635 2E37 -8138F636 2E38 -8138F637 2E39 -8138F638 2E3A -8138F639 2E3B -8138F730 2E3C -8138F731 2E3D -8138F732 2E3E -8138F733 2E3F -8138F734 2E40 -8138F735 2E41 -8138F736 2E42 -8138F737 2E43 -8138F738 2E44 -8138F739 2E45 -8138F830 2E46 -8138F831 2E47 -8138F832 2E48 -8138F833 2E49 -8138F834 2E4A -8138F835 2E4B -8138F836 2E4C -8138F837 2E4D -8138F838 2E4E -8138F839 2E4F -8138F930 2E50 -8138F931 2E51 -8138F932 2E52 -8138F933 2E53 -8138F934 2E54 -8138F935 2E55 -8138F936 2E56 -8138F937 2E57 -8138F938 2E58 -8138F939 2E59 -8138FA30 2E5A -8138FA31 2E5B -8138FA32 2E5C -8138FA33 2E5D -8138FA34 2E5E -8138FA35 2E5F -8138FA36 2E60 -8138FA37 2E61 -8138FA38 2E62 -8138FA39 2E63 -8138FB30 2E64 -8138FB31 2E65 -8138FB32 2E66 -8138FB33 2E67 -8138FB34 2E68 -8138FB35 2E69 -8138FB36 2E6A -8138FB37 2E6B -8138FB38 2E6C -8138FB39 2E6D -8138FC30 2E6E -8138FC31 2E6F -8138FC32 2E70 -8138FC33 2E71 -8138FC34 2E72 -8138FC35 2E73 -8138FC36 2E74 -8138FC37 2E75 -8138FC38 2E76 -8138FC39 2E77 -8138FD30 2E78 -8138FD31 2E79 -8138FD32 2E7A -8138FD33 2E7B -8138FD34 2E7C -8138FD35 2E7D -8138FD36 2E7E -8138FD37 2E7F -8138FD38 2E80 -FE50 2E81 -8138FD39 2E82 -8138FE30 2E83 -FE54 2E84 -8138FE31 2E85 -8138FE32 2E86 -8138FE33 2E87 -FE57 2E88 -8138FE34 2E89 -8138FE35 2E8A -FE58 2E8B -FE5D 2E8C -8138FE36 2E8D -8138FE37 2E8E -8138FE38 2E8F -8138FE39 2E90 -81398130 2E91 -81398131 2E92 -81398132 2E93 -81398133 2E94 -81398134 2E95 -81398135 2E96 -FE5E 2E97 -81398136 2E98 -81398137 2E99 -81398138 2E9A -81398139 2E9B -81398230 2E9C -81398231 2E9D -81398232 2E9E -81398233 2E9F -81398234 2EA0 -81398235 2EA1 -81398236 2EA2 -81398237 2EA3 -81398238 2EA4 -81398239 2EA5 -81398330 2EA6 -FE6B 2EA7 -81398331 2EA8 -81398332 2EA9 -FE6E 2EAA -81398333 2EAB -81398334 2EAC -81398335 2EAD -FE71 2EAE -81398336 2EAF -81398337 2EB0 -81398338 2EB1 -81398339 2EB2 -FE73 2EB3 -81398430 2EB4 -81398431 2EB5 -FE74 2EB6 -FE75 2EB7 -81398432 2EB8 -81398433 2EB9 -81398434 2EBA -FE79 2EBB -81398435 2EBC -81398436 2EBD -81398437 2EBE -81398438 2EBF -81398439 2EC0 -81398530 2EC1 -81398531 2EC2 -81398532 2EC3 -81398533 2EC4 -81398534 2EC5 -81398535 2EC6 -81398536 2EC7 -81398537 2EC8 -81398538 2EC9 -FE84 2ECA -81398539 2ECB -81398630 2ECC -81398631 2ECD -81398632 2ECE -81398633 2ECF -81398634 2ED0 -81398635 2ED1 -81398636 2ED2 -81398637 2ED3 -81398638 2ED4 -81398639 2ED5 -81398730 2ED6 -81398731 2ED7 -81398732 2ED8 -81398733 2ED9 -81398734 2EDA -81398735 2EDB -81398736 2EDC -81398737 2EDD -81398738 2EDE -81398739 2EDF -81398830 2EE0 -81398831 2EE1 -81398832 2EE2 -81398833 2EE3 -81398834 2EE4 -81398835 2EE5 -81398836 2EE6 -81398837 2EE7 -81398838 2EE8 -81398839 2EE9 -81398930 2EEA -81398931 2EEB -81398932 2EEC -81398933 2EED -81398934 2EEE -81398935 2EEF -81398936 2EF0 -81398937 2EF1 -81398938 2EF2 -81398939 2EF3 -81398A30 2EF4 -81398A31 2EF5 -81398A32 2EF6 -81398A33 2EF7 -81398A34 2EF8 -81398A35 2EF9 -81398A36 2EFA -81398A37 2EFB -81398A38 2EFC -81398A39 2EFD -81398B30 2EFE -81398B31 2EFF -81398B32 2F00 -81398B33 2F01 -81398B34 2F02 -81398B35 2F03 -81398B36 2F04 -81398B37 2F05 -81398B38 2F06 -81398B39 2F07 -81398C30 2F08 -81398C31 2F09 -81398C32 2F0A -81398C33 2F0B -81398C34 2F0C -81398C35 2F0D -81398C36 2F0E -81398C37 2F0F -81398C38 2F10 -81398C39 2F11 -81398D30 2F12 -81398D31 2F13 -81398D32 2F14 -81398D33 2F15 -81398D34 2F16 -81398D35 2F17 -81398D36 2F18 -81398D37 2F19 -81398D38 2F1A -81398D39 2F1B -81398E30 2F1C -81398E31 2F1D -81398E32 2F1E -81398E33 2F1F -81398E34 2F20 -81398E35 2F21 -81398E36 2F22 -81398E37 2F23 -81398E38 2F24 -81398E39 2F25 -81398F30 2F26 -81398F31 2F27 -81398F32 2F28 -81398F33 2F29 -81398F34 2F2A -81398F35 2F2B -81398F36 2F2C -81398F37 2F2D -81398F38 2F2E -81398F39 2F2F -81399030 2F30 -81399031 2F31 -81399032 2F32 -81399033 2F33 -81399034 2F34 -81399035 2F35 -81399036 2F36 -81399037 2F37 -81399038 2F38 -81399039 2F39 -81399130 2F3A -81399131 2F3B -81399132 2F3C -81399133 2F3D -81399134 2F3E -81399135 2F3F -81399136 2F40 -81399137 2F41 -81399138 2F42 -81399139 2F43 -81399230 2F44 -81399231 2F45 -81399232 2F46 -81399233 2F47 -81399234 2F48 -81399235 2F49 -81399236 2F4A -81399237 2F4B -81399238 2F4C -81399239 2F4D -81399330 2F4E -81399331 2F4F -81399332 2F50 -81399333 2F51 -81399334 2F52 -81399335 2F53 -81399336 2F54 -81399337 2F55 -81399338 2F56 -81399339 2F57 -81399430 2F58 -81399431 2F59 -81399432 2F5A -81399433 2F5B -81399434 2F5C -81399435 2F5D -81399436 2F5E -81399437 2F5F -81399438 2F60 -81399439 2F61 -81399530 2F62 -81399531 2F63 -81399532 2F64 -81399533 2F65 -81399534 2F66 -81399535 2F67 -81399536 2F68 -81399537 2F69 -81399538 2F6A -81399539 2F6B -81399630 2F6C -81399631 2F6D -81399632 2F6E -81399633 2F6F -81399634 2F70 -81399635 2F71 -81399636 2F72 -81399637 2F73 -81399638 2F74 -81399639 2F75 -81399730 2F76 -81399731 2F77 -81399732 2F78 -81399733 2F79 -81399734 2F7A -81399735 2F7B -81399736 2F7C -81399737 2F7D -81399738 2F7E -81399739 2F7F -81399830 2F80 -81399831 2F81 -81399832 2F82 -81399833 2F83 -81399834 2F84 -81399835 2F85 -81399836 2F86 -81399837 2F87 -81399838 2F88 -81399839 2F89 -81399930 2F8A -81399931 2F8B -81399932 2F8C -81399933 2F8D -81399934 2F8E -81399935 2F8F -81399936 2F90 -81399937 2F91 -81399938 2F92 -81399939 2F93 -81399A30 2F94 -81399A31 2F95 -81399A32 2F96 -81399A33 2F97 -81399A34 2F98 -81399A35 2F99 -81399A36 2F9A -81399A37 2F9B -81399A38 2F9C -81399A39 2F9D -81399B30 2F9E -81399B31 2F9F -81399B32 2FA0 -81399B33 2FA1 -81399B34 2FA2 -81399B35 2FA3 -81399B36 2FA4 -81399B37 2FA5 -81399B38 2FA6 -81399B39 2FA7 -81399C30 2FA8 -81399C31 2FA9 -81399C32 2FAA -81399C33 2FAB -81399C34 2FAC -81399C35 2FAD -81399C36 2FAE -81399C37 2FAF -81399C38 2FB0 -81399C39 2FB1 -81399D30 2FB2 -81399D31 2FB3 -81399D32 2FB4 -81399D33 2FB5 -81399D34 2FB6 -81399D35 2FB7 -81399D36 2FB8 -81399D37 2FB9 -81399D38 2FBA -81399D39 2FBB -81399E30 2FBC -81399E31 2FBD -81399E32 2FBE -81399E33 2FBF -81399E34 2FC0 -81399E35 2FC1 -81399E36 2FC2 -81399E37 2FC3 -81399E38 2FC4 -81399E39 2FC5 -81399F30 2FC6 -81399F31 2FC7 -81399F32 2FC8 -81399F33 2FC9 -81399F34 2FCA -81399F35 2FCB -81399F36 2FCC -81399F37 2FCD -81399F38 2FCE -81399F39 2FCF -8139A030 2FD0 -8139A031 2FD1 -8139A032 2FD2 -8139A033 2FD3 -8139A034 2FD4 -8139A035 2FD5 -8139A036 2FD6 -8139A037 2FD7 -8139A038 2FD8 -8139A039 2FD9 -8139A130 2FDA -8139A131 2FDB -8139A132 2FDC -8139A133 2FDD -8139A134 2FDE -8139A135 2FDF -8139A136 2FE0 -8139A137 2FE1 -8139A138 2FE2 -8139A139 2FE3 -8139A230 2FE4 -8139A231 2FE5 -8139A232 2FE6 -8139A233 2FE7 -8139A234 2FE8 -8139A235 2FE9 -8139A236 2FEA -8139A237 2FEB -8139A238 2FEC -8139A239 2FED -8139A330 2FEE -8139A331 2FEF -A98A 2FF0 -A98B 2FF1 -A98C 2FF2 -A98D 2FF3 -A98E 2FF4 -A98F 2FF5 -A990 2FF6 -A991 2FF7 -A992 2FF8 -A993 2FF9 -A994 2FFA -A995 2FFB -8139A332 2FFC -8139A333 2FFD -8139A334 2FFE -8139A335 2FFF -A1A1 3000 -A1A2 3001 -A1A3 3002 -A1A8 3003 -8139A336 3004 -A1A9 3005 -A965 3006 -A996 3007 -A1B4 3008 -A1B5 3009 -A1B6 300A -A1B7 300B -A1B8 300C -A1B9 300D -A1BA 300E -A1BB 300F -A1BE 3010 -A1BF 3011 -A893 3012 -A1FE 3013 -A1B2 3014 -A1B3 3015 -A1BC 3016 -A1BD 3017 -8139A337 3018 -8139A338 3019 -8139A339 301A -8139A430 301B -8139A431 301C -A894 301D -A895 301E -8139A432 301F -8139A433 3020 -A940 3021 -A941 3022 -A942 3023 -A943 3024 -A944 3025 -A945 3026 -A946 3027 -A947 3028 -A948 3029 -8139A434 302A -8139A435 302B -8139A436 302C -8139A437 302D -8139A438 302E -8139A439 302F -8139A530 3030 -8139A531 3031 -8139A532 3032 -8139A533 3033 -8139A534 3034 -8139A535 3035 -8139A536 3036 -8139A537 3037 -8139A538 3038 -8139A539 3039 -8139A630 303A -8139A631 303B -8139A632 303C -8139A633 303D -A989 303E -8139A634 303F -8139A635 3040 -A4A1 3041 -A4A2 3042 -A4A3 3043 -A4A4 3044 -A4A5 3045 -A4A6 3046 -A4A7 3047 -A4A8 3048 -A4A9 3049 -A4AA 304A -A4AB 304B -A4AC 304C -A4AD 304D -A4AE 304E -A4AF 304F -A4B0 3050 -A4B1 3051 -A4B2 3052 -A4B3 3053 -A4B4 3054 -A4B5 3055 -A4B6 3056 -A4B7 3057 -A4B8 3058 -A4B9 3059 -A4BA 305A -A4BB 305B -A4BC 305C -A4BD 305D -A4BE 305E -A4BF 305F -A4C0 3060 -A4C1 3061 -A4C2 3062 -A4C3 3063 -A4C4 3064 -A4C5 3065 -A4C6 3066 -A4C7 3067 -A4C8 3068 -A4C9 3069 -A4CA 306A -A4CB 306B -A4CC 306C -A4CD 306D -A4CE 306E -A4CF 306F -A4D0 3070 -A4D1 3071 -A4D2 3072 -A4D3 3073 -A4D4 3074 -A4D5 3075 -A4D6 3076 -A4D7 3077 -A4D8 3078 -A4D9 3079 -A4DA 307A -A4DB 307B -A4DC 307C -A4DD 307D -A4DE 307E -A4DF 307F -A4E0 3080 -A4E1 3081 -A4E2 3082 -A4E3 3083 -A4E4 3084 -A4E5 3085 -A4E6 3086 -A4E7 3087 -A4E8 3088 -A4E9 3089 -A4EA 308A -A4EB 308B -A4EC 308C -A4ED 308D -A4EE 308E -A4EF 308F -A4F0 3090 -A4F1 3091 -A4F2 3092 -A4F3 3093 -8139A636 3094 -8139A637 3095 -8139A638 3096 -8139A639 3097 -8139A730 3098 -8139A731 3099 -8139A732 309A -A961 309B -A962 309C -A966 309D -A967 309E -8139A733 309F -8139A734 30A0 -A5A1 30A1 -A5A2 30A2 -A5A3 30A3 -A5A4 30A4 -A5A5 30A5 -A5A6 30A6 -A5A7 30A7 -A5A8 30A8 -A5A9 30A9 -A5AA 30AA -A5AB 30AB -A5AC 30AC -A5AD 30AD -A5AE 30AE -A5AF 30AF -A5B0 30B0 -A5B1 30B1 -A5B2 30B2 -A5B3 30B3 -A5B4 30B4 -A5B5 30B5 -A5B6 30B6 -A5B7 30B7 -A5B8 30B8 -A5B9 30B9 -A5BA 30BA -A5BB 30BB -A5BC 30BC -A5BD 30BD -A5BE 30BE -A5BF 30BF -A5C0 30C0 -A5C1 30C1 -A5C2 30C2 -A5C3 30C3 -A5C4 30C4 -A5C5 30C5 -A5C6 30C6 -A5C7 30C7 -A5C8 30C8 -A5C9 30C9 -A5CA 30CA -A5CB 30CB -A5CC 30CC -A5CD 30CD -A5CE 30CE -A5CF 30CF -A5D0 30D0 -A5D1 30D1 -A5D2 30D2 -A5D3 30D3 -A5D4 30D4 -A5D5 30D5 -A5D6 30D6 -A5D7 30D7 -A5D8 30D8 -A5D9 30D9 -A5DA 30DA -A5DB 30DB -A5DC 30DC -A5DD 30DD -A5DE 30DE -A5DF 30DF -A5E0 30E0 -A5E1 30E1 -A5E2 30E2 -A5E3 30E3 -A5E4 30E4 -A5E5 30E5 -A5E6 30E6 -A5E7 30E7 -A5E8 30E8 -A5E9 30E9 -A5EA 30EA -A5EB 30EB -A5EC 30EC -A5ED 30ED -A5EE 30EE -A5EF 30EF -A5F0 30F0 -A5F1 30F1 -A5F2 30F2 -A5F3 30F3 -A5F4 30F4 -A5F5 30F5 -A5F6 30F6 -8139A735 30F7 -8139A736 30F8 -8139A737 30F9 -8139A738 30FA -8139A739 30FB -A960 30FC -A963 30FD -A964 30FE -8139A830 30FF -8139A831 3100 -8139A832 3101 -8139A833 3102 -8139A834 3103 -8139A835 3104 -A8C5 3105 -A8C6 3106 -A8C7 3107 -A8C8 3108 -A8C9 3109 -A8CA 310A -A8CB 310B -A8CC 310C -A8CD 310D -A8CE 310E -A8CF 310F -A8D0 3110 -A8D1 3111 -A8D2 3112 -A8D3 3113 -A8D4 3114 -A8D5 3115 -A8D6 3116 -A8D7 3117 -A8D8 3118 -A8D9 3119 -A8DA 311A -A8DB 311B -A8DC 311C -A8DD 311D -A8DE 311E -A8DF 311F -A8E0 3120 -A8E1 3121 -A8E2 3122 -A8E3 3123 -A8E4 3124 -A8E5 3125 -A8E6 3126 -A8E7 3127 -A8E8 3128 -A8E9 3129 -8139A836 312A -8139A837 312B -8139A838 312C -8139A839 312D -8139A930 312E -8139A931 312F -8139A932 3130 -8139A933 3131 -8139A934 3132 -8139A935 3133 -8139A936 3134 -8139A937 3135 -8139A938 3136 -8139A939 3137 -8139AA30 3138 -8139AA31 3139 -8139AA32 313A -8139AA33 313B -8139AA34 313C -8139AA35 313D -8139AA36 313E -8139AA37 313F -8139AA38 3140 -8139AA39 3141 -8139AB30 3142 -8139AB31 3143 -8139AB32 3144 -8139AB33 3145 -8139AB34 3146 -8139AB35 3147 -8139AB36 3148 -8139AB37 3149 -8139AB38 314A -8139AB39 314B -8139AC30 314C -8139AC31 314D -8139AC32 314E -8139AC33 314F -8139AC34 3150 -8139AC35 3151 -8139AC36 3152 -8139AC37 3153 -8139AC38 3154 -8139AC39 3155 -8139AD30 3156 -8139AD31 3157 -8139AD32 3158 -8139AD33 3159 -8139AD34 315A -8139AD35 315B -8139AD36 315C -8139AD37 315D -8139AD38 315E -8139AD39 315F -8139AE30 3160 -8139AE31 3161 -8139AE32 3162 -8139AE33 3163 -8139AE34 3164 -8139AE35 3165 -8139AE36 3166 -8139AE37 3167 -8139AE38 3168 -8139AE39 3169 -8139AF30 316A -8139AF31 316B -8139AF32 316C -8139AF33 316D -8139AF34 316E -8139AF35 316F -8139AF36 3170 -8139AF37 3171 -8139AF38 3172 -8139AF39 3173 -8139B030 3174 -8139B031 3175 -8139B032 3176 -8139B033 3177 -8139B034 3178 -8139B035 3179 -8139B036 317A -8139B037 317B -8139B038 317C -8139B039 317D -8139B130 317E -8139B131 317F -8139B132 3180 -8139B133 3181 -8139B134 3182 -8139B135 3183 -8139B136 3184 -8139B137 3185 -8139B138 3186 -8139B139 3187 -8139B230 3188 -8139B231 3189 -8139B232 318A -8139B233 318B -8139B234 318C -8139B235 318D -8139B236 318E -8139B237 318F -8139B238 3190 -8139B239 3191 -8139B330 3192 -8139B331 3193 -8139B332 3194 -8139B333 3195 -8139B334 3196 -8139B335 3197 -8139B336 3198 -8139B337 3199 -8139B338 319A -8139B339 319B -8139B430 319C -8139B431 319D -8139B432 319E -8139B433 319F -8139B434 31A0 -8139B435 31A1 -8139B436 31A2 -8139B437 31A3 -8139B438 31A4 -8139B439 31A5 -8139B530 31A6 -8139B531 31A7 -8139B532 31A8 -8139B533 31A9 -8139B534 31AA -8139B535 31AB -8139B536 31AC -8139B537 31AD -8139B538 31AE -8139B539 31AF -8139B630 31B0 -8139B631 31B1 -8139B632 31B2 -8139B633 31B3 -8139B634 31B4 -8139B635 31B5 -8139B636 31B6 -8139B637 31B7 -8139B638 31B8 -8139B639 31B9 -8139B730 31BA -8139B731 31BB -8139B732 31BC -8139B733 31BD -8139B734 31BE -8139B735 31BF -8139B736 31C0 -8139B737 31C1 -8139B738 31C2 -8139B739 31C3 -8139B830 31C4 -8139B831 31C5 -8139B832 31C6 -8139B833 31C7 -8139B834 31C8 -8139B835 31C9 -8139B836 31CA -8139B837 31CB -8139B838 31CC -8139B839 31CD -8139B930 31CE -8139B931 31CF -8139B932 31D0 -8139B933 31D1 -8139B934 31D2 -8139B935 31D3 -8139B936 31D4 -8139B937 31D5 -8139B938 31D6 -8139B939 31D7 -8139BA30 31D8 -8139BA31 31D9 -8139BA32 31DA -8139BA33 31DB -8139BA34 31DC -8139BA35 31DD -8139BA36 31DE -8139BA37 31DF -8139BA38 31E0 -8139BA39 31E1 -8139BB30 31E2 -8139BB31 31E3 -8139BB32 31E4 -8139BB33 31E5 -8139BB34 31E6 -8139BB35 31E7 -8139BB36 31E8 -8139BB37 31E9 -8139BB38 31EA -8139BB39 31EB -8139BC30 31EC -8139BC31 31ED -8139BC32 31EE -8139BC33 31EF -8139BC34 31F0 -8139BC35 31F1 -8139BC36 31F2 -8139BC37 31F3 -8139BC38 31F4 -8139BC39 31F5 -8139BD30 31F6 -8139BD31 31F7 -8139BD32 31F8 -8139BD33 31F9 -8139BD34 31FA -8139BD35 31FB -8139BD36 31FC -8139BD37 31FD -8139BD38 31FE -8139BD39 31FF -8139BE30 3200 -8139BE31 3201 -8139BE32 3202 -8139BE33 3203 -8139BE34 3204 -8139BE35 3205 -8139BE36 3206 -8139BE37 3207 -8139BE38 3208 -8139BE39 3209 -8139BF30 320A -8139BF31 320B -8139BF32 320C -8139BF33 320D -8139BF34 320E -8139BF35 320F -8139BF36 3210 -8139BF37 3211 -8139BF38 3212 -8139BF39 3213 -8139C030 3214 -8139C031 3215 -8139C032 3216 -8139C033 3217 -8139C034 3218 -8139C035 3219 -8139C036 321A -8139C037 321B -8139C038 321C -8139C039 321D -8139C130 321E -8139C131 321F -A2E5 3220 -A2E6 3221 -A2E7 3222 -A2E8 3223 -A2E9 3224 -A2EA 3225 -A2EB 3226 -A2EC 3227 -A2ED 3228 -A2EE 3229 -8139C132 322A -8139C133 322B -8139C134 322C -8139C135 322D -8139C136 322E -8139C137 322F -8139C138 3230 -A95A 3231 -8139C139 3232 -8139C230 3233 -8139C231 3234 -8139C232 3235 -8139C233 3236 -8139C234 3237 -8139C235 3238 -8139C236 3239 -8139C237 323A -8139C238 323B -8139C239 323C -8139C330 323D -8139C331 323E -8139C332 323F -8139C333 3240 -8139C334 3241 -8139C335 3242 -8139C336 3243 -8139C337 3244 -8139C338 3245 -8139C339 3246 -8139C430 3247 -8139C431 3248 -8139C432 3249 -8139C433 324A -8139C434 324B -8139C435 324C -8139C436 324D -8139C437 324E -8139C438 324F -8139C439 3250 -8139C530 3251 -8139C531 3252 -8139C532 3253 -8139C533 3254 -8139C534 3255 -8139C535 3256 -8139C536 3257 -8139C537 3258 -8139C538 3259 -8139C539 325A -8139C630 325B -8139C631 325C -8139C632 325D -8139C633 325E -8139C634 325F -8139C635 3260 -8139C636 3261 -8139C637 3262 -8139C638 3263 -8139C639 3264 -8139C730 3265 -8139C731 3266 -8139C732 3267 -8139C733 3268 -8139C734 3269 -8139C735 326A -8139C736 326B -8139C737 326C -8139C738 326D -8139C739 326E -8139C830 326F -8139C831 3270 -8139C832 3271 -8139C833 3272 -8139C834 3273 -8139C835 3274 -8139C836 3275 -8139C837 3276 -8139C838 3277 -8139C839 3278 -8139C930 3279 -8139C931 327A -8139C932 327B -8139C933 327C -8139C934 327D -8139C935 327E -8139C936 327F -8139C937 3280 -8139C938 3281 -8139C939 3282 -8139CA30 3283 -8139CA31 3284 -8139CA32 3285 -8139CA33 3286 -8139CA34 3287 -8139CA35 3288 -8139CA36 3289 -8139CA37 328A -8139CA38 328B -8139CA39 328C -8139CB30 328D -8139CB31 328E -8139CB32 328F -8139CB33 3290 -8139CB34 3291 -8139CB35 3292 -8139CB36 3293 -8139CB37 3294 -8139CB38 3295 -8139CB39 3296 -8139CC30 3297 -8139CC31 3298 -8139CC32 3299 -8139CC33 329A -8139CC34 329B -8139CC35 329C -8139CC36 329D -8139CC37 329E -8139CC38 329F -8139CC39 32A0 -8139CD30 32A1 -8139CD31 32A2 -A949 32A3 -8139CD32 32A4 -8139CD33 32A5 -8139CD34 32A6 -8139CD35 32A7 -8139CD36 32A8 -8139CD37 32A9 -8139CD38 32AA -8139CD39 32AB -8139CE30 32AC -8139CE31 32AD -8139CE32 32AE -8139CE33 32AF -8139CE34 32B0 -8139CE35 32B1 -8139CE36 32B2 -8139CE37 32B3 -8139CE38 32B4 -8139CE39 32B5 -8139CF30 32B6 -8139CF31 32B7 -8139CF32 32B8 -8139CF33 32B9 -8139CF34 32BA -8139CF35 32BB -8139CF36 32BC -8139CF37 32BD -8139CF38 32BE -8139CF39 32BF -8139D030 32C0 -8139D031 32C1 -8139D032 32C2 -8139D033 32C3 -8139D034 32C4 -8139D035 32C5 -8139D036 32C6 -8139D037 32C7 -8139D038 32C8 -8139D039 32C9 -8139D130 32CA -8139D131 32CB -8139D132 32CC -8139D133 32CD -8139D134 32CE -8139D135 32CF -8139D136 32D0 -8139D137 32D1 -8139D138 32D2 -8139D139 32D3 -8139D230 32D4 -8139D231 32D5 -8139D232 32D6 -8139D233 32D7 -8139D234 32D8 -8139D235 32D9 -8139D236 32DA -8139D237 32DB -8139D238 32DC -8139D239 32DD -8139D330 32DE -8139D331 32DF -8139D332 32E0 -8139D333 32E1 -8139D334 32E2 -8139D335 32E3 -8139D336 32E4 -8139D337 32E5 -8139D338 32E6 -8139D339 32E7 -8139D430 32E8 -8139D431 32E9 -8139D432 32EA -8139D433 32EB -8139D434 32EC -8139D435 32ED -8139D436 32EE -8139D437 32EF -8139D438 32F0 -8139D439 32F1 -8139D530 32F2 -8139D531 32F3 -8139D532 32F4 -8139D533 32F5 -8139D534 32F6 -8139D535 32F7 -8139D536 32F8 -8139D537 32F9 -8139D538 32FA -8139D539 32FB -8139D630 32FC -8139D631 32FD -8139D632 32FE -8139D633 32FF -8139D634 3300 -8139D635 3301 -8139D636 3302 -8139D637 3303 -8139D638 3304 -8139D639 3305 -8139D730 3306 -8139D731 3307 -8139D732 3308 -8139D733 3309 -8139D734 330A -8139D735 330B -8139D736 330C -8139D737 330D -8139D738 330E -8139D739 330F -8139D830 3310 -8139D831 3311 -8139D832 3312 -8139D833 3313 -8139D834 3314 -8139D835 3315 -8139D836 3316 -8139D837 3317 -8139D838 3318 -8139D839 3319 -8139D930 331A -8139D931 331B -8139D932 331C -8139D933 331D -8139D934 331E -8139D935 331F -8139D936 3320 -8139D937 3321 -8139D938 3322 -8139D939 3323 -8139DA30 3324 -8139DA31 3325 -8139DA32 3326 -8139DA33 3327 -8139DA34 3328 -8139DA35 3329 -8139DA36 332A -8139DA37 332B -8139DA38 332C -8139DA39 332D -8139DB30 332E -8139DB31 332F -8139DB32 3330 -8139DB33 3331 -8139DB34 3332 -8139DB35 3333 -8139DB36 3334 -8139DB37 3335 -8139DB38 3336 -8139DB39 3337 -8139DC30 3338 -8139DC31 3339 -8139DC32 333A -8139DC33 333B -8139DC34 333C -8139DC35 333D -8139DC36 333E -8139DC37 333F -8139DC38 3340 -8139DC39 3341 -8139DD30 3342 -8139DD31 3343 -8139DD32 3344 -8139DD33 3345 -8139DD34 3346 -8139DD35 3347 -8139DD36 3348 -8139DD37 3349 -8139DD38 334A -8139DD39 334B -8139DE30 334C -8139DE31 334D -8139DE32 334E -8139DE33 334F -8139DE34 3350 -8139DE35 3351 -8139DE36 3352 -8139DE37 3353 -8139DE38 3354 -8139DE39 3355 -8139DF30 3356 -8139DF31 3357 -8139DF32 3358 -8139DF33 3359 -8139DF34 335A -8139DF35 335B -8139DF36 335C -8139DF37 335D -8139DF38 335E -8139DF39 335F -8139E030 3360 -8139E031 3361 -8139E032 3362 -8139E033 3363 -8139E034 3364 -8139E035 3365 -8139E036 3366 -8139E037 3367 -8139E038 3368 -8139E039 3369 -8139E130 336A -8139E131 336B -8139E132 336C -8139E133 336D -8139E134 336E -8139E135 336F -8139E136 3370 -8139E137 3371 -8139E138 3372 -8139E139 3373 -8139E230 3374 -8139E231 3375 -8139E232 3376 -8139E233 3377 -8139E234 3378 -8139E235 3379 -8139E236 337A -8139E237 337B -8139E238 337C -8139E239 337D -8139E330 337E -8139E331 337F -8139E332 3380 -8139E333 3381 -8139E334 3382 -8139E335 3383 -8139E336 3384 -8139E337 3385 -8139E338 3386 -8139E339 3387 -8139E430 3388 -8139E431 3389 -8139E432 338A -8139E433 338B -8139E434 338C -8139E435 338D -A94A 338E -A94B 338F -8139E436 3390 -8139E437 3391 -8139E438 3392 -8139E439 3393 -8139E530 3394 -8139E531 3395 -8139E532 3396 -8139E533 3397 -8139E534 3398 -8139E535 3399 -8139E536 339A -8139E537 339B -A94C 339C -A94D 339D -A94E 339E -8139E538 339F -8139E539 33A0 -A94F 33A1 -8139E630 33A2 -8139E631 33A3 -8139E632 33A4 -8139E633 33A5 -8139E634 33A6 -8139E635 33A7 -8139E636 33A8 -8139E637 33A9 -8139E638 33AA -8139E639 33AB -8139E730 33AC -8139E731 33AD -8139E732 33AE -8139E733 33AF -8139E734 33B0 -8139E735 33B1 -8139E736 33B2 -8139E737 33B3 -8139E738 33B4 -8139E739 33B5 -8139E830 33B6 -8139E831 33B7 -8139E832 33B8 -8139E833 33B9 -8139E834 33BA -8139E835 33BB -8139E836 33BC -8139E837 33BD -8139E838 33BE -8139E839 33BF -8139E930 33C0 -8139E931 33C1 -8139E932 33C2 -8139E933 33C3 -A950 33C4 -8139E934 33C5 -8139E935 33C6 -8139E936 33C7 -8139E937 33C8 -8139E938 33C9 -8139E939 33CA -8139EA30 33CB -8139EA31 33CC -8139EA32 33CD -A951 33CE -8139EA33 33CF -8139EA34 33D0 -A952 33D1 -A953 33D2 -8139EA35 33D3 -8139EA36 33D4 -A954 33D5 -8139EA37 33D6 -8139EA38 33D7 -8139EA39 33D8 -8139EB30 33D9 -8139EB31 33DA -8139EB32 33DB -8139EB33 33DC -8139EB34 33DD -8139EB35 33DE -8139EB36 33DF -8139EB37 33E0 -8139EB38 33E1 -8139EB39 33E2 -8139EC30 33E3 -8139EC31 33E4 -8139EC32 33E5 -8139EC33 33E6 -8139EC34 33E7 -8139EC35 33E8 -8139EC36 33E9 -8139EC37 33EA -8139EC38 33EB -8139EC39 33EC -8139ED30 33ED -8139ED31 33EE -8139ED32 33EF -8139ED33 33F0 -8139ED34 33F1 -8139ED35 33F2 -8139ED36 33F3 -8139ED37 33F4 -8139ED38 33F5 -8139ED39 33F6 -8139EE30 33F7 -8139EE31 33F8 -8139EE32 33F9 -8139EE33 33FA -8139EE34 33FB -8139EE35 33FC -8139EE36 33FD -8139EE37 33FE -8139EE38 33FF -8139EE39 3400 -8139EF30 3401 -8139EF31 3402 -8139EF32 3403 -8139EF33 3404 -8139EF34 3405 -8139EF35 3406 -8139EF36 3407 -8139EF37 3408 -8139EF38 3409 -8139EF39 340A -8139F030 340B -8139F031 340C -8139F032 340D -8139F033 340E -8139F034 340F -8139F035 3410 -8139F036 3411 -8139F037 3412 -8139F038 3413 -8139F039 3414 -8139F130 3415 -8139F131 3416 -8139F132 3417 -8139F133 3418 -8139F134 3419 -8139F135 341A -8139F136 341B -8139F137 341C -8139F138 341D -8139F139 341E -8139F230 341F -8139F231 3420 -8139F232 3421 -8139F233 3422 -8139F234 3423 -8139F235 3424 -8139F236 3425 -8139F237 3426 -8139F238 3427 -8139F239 3428 -8139F330 3429 -8139F331 342A -8139F332 342B -8139F333 342C -8139F334 342D -8139F335 342E -8139F336 342F -8139F337 3430 -8139F338 3431 -8139F339 3432 -8139F430 3433 -8139F431 3434 -8139F432 3435 -8139F433 3436 -8139F434 3437 -8139F435 3438 -8139F436 3439 -8139F437 343A -8139F438 343B -8139F439 343C -8139F530 343D -8139F531 343E -8139F532 343F -8139F533 3440 -8139F534 3441 -8139F535 3442 -8139F536 3443 -8139F537 3444 -8139F538 3445 -8139F539 3446 -FE56 3447 -8139F630 3448 -8139F631 3449 -8139F632 344A -8139F633 344B -8139F634 344C -8139F635 344D -8139F636 344E -8139F637 344F -8139F638 3450 -8139F639 3451 -8139F730 3452 -8139F731 3453 -8139F732 3454 -8139F733 3455 -8139F734 3456 -8139F735 3457 -8139F736 3458 -8139F737 3459 -8139F738 345A -8139F739 345B -8139F830 345C -8139F831 345D -8139F832 345E -8139F833 345F -8139F834 3460 -8139F835 3461 -8139F836 3462 -8139F837 3463 -8139F838 3464 -8139F839 3465 -8139F930 3466 -8139F931 3467 -8139F932 3468 -8139F933 3469 -8139F934 346A -8139F935 346B -8139F936 346C -8139F937 346D -8139F938 346E -8139F939 346F -8139FA30 3470 -8139FA31 3471 -8139FA32 3472 -FE55 3473 -8139FA33 3474 -8139FA34 3475 -8139FA35 3476 -8139FA36 3477 -8139FA37 3478 -8139FA38 3479 -8139FA39 347A -8139FB30 347B -8139FB31 347C -8139FB32 347D -8139FB33 347E -8139FB34 347F -8139FB35 3480 -8139FB36 3481 -8139FB37 3482 -8139FB38 3483 -8139FB39 3484 -8139FC30 3485 -8139FC31 3486 -8139FC32 3487 -8139FC33 3488 -8139FC34 3489 -8139FC35 348A -8139FC36 348B -8139FC37 348C -8139FC38 348D -8139FC39 348E -8139FD30 348F -8139FD31 3490 -8139FD32 3491 -8139FD33 3492 -8139FD34 3493 -8139FD35 3494 -8139FD36 3495 -8139FD37 3496 -8139FD38 3497 -8139FD39 3498 -8139FE30 3499 -8139FE31 349A -8139FE32 349B -8139FE33 349C -8139FE34 349D -8139FE35 349E -8139FE36 349F -8139FE37 34A0 -8139FE38 34A1 -8139FE39 34A2 -82308130 34A3 -82308131 34A4 -82308132 34A5 -82308133 34A6 -82308134 34A7 -82308135 34A8 -82308136 34A9 -82308137 34AA -82308138 34AB -82308139 34AC -82308230 34AD -82308231 34AE -82308232 34AF -82308233 34B0 -82308234 34B1 -82308235 34B2 -82308236 34B3 -82308237 34B4 -82308238 34B5 -82308239 34B6 -82308330 34B7 -82308331 34B8 -82308332 34B9 -82308333 34BA -82308334 34BB -82308335 34BC -82308336 34BD -82308337 34BE -82308338 34BF -82308339 34C0 -82308430 34C1 -82308431 34C2 -82308432 34C3 -82308433 34C4 -82308434 34C5 -82308435 34C6 -82308436 34C7 -82308437 34C8 -82308438 34C9 -82308439 34CA -82308530 34CB -82308531 34CC -82308532 34CD -82308533 34CE -82308534 34CF -82308535 34D0 -82308536 34D1 -82308537 34D2 -82308538 34D3 -82308539 34D4 -82308630 34D5 -82308631 34D6 -82308632 34D7 -82308633 34D8 -82308634 34D9 -82308635 34DA -82308636 34DB -82308637 34DC -82308638 34DD -82308639 34DE -82308730 34DF -82308731 34E0 -82308732 34E1 -82308733 34E2 -82308734 34E3 -82308735 34E4 -82308736 34E5 -82308737 34E6 -82308738 34E7 -82308739 34E8 -82308830 34E9 -82308831 34EA -82308832 34EB -82308833 34EC -82308834 34ED -82308835 34EE -82308836 34EF -82308837 34F0 -82308838 34F1 -82308839 34F2 -82308930 34F3 -82308931 34F4 -82308932 34F5 -82308933 34F6 -82308934 34F7 -82308935 34F8 -82308936 34F9 -82308937 34FA -82308938 34FB -82308939 34FC -82308A30 34FD -82308A31 34FE -82308A32 34FF -82308A33 3500 -82308A34 3501 -82308A35 3502 -82308A36 3503 -82308A37 3504 -82308A38 3505 -82308A39 3506 -82308B30 3507 -82308B31 3508 -82308B32 3509 -82308B33 350A -82308B34 350B -82308B35 350C -82308B36 350D -82308B37 350E -82308B38 350F -82308B39 3510 -82308C30 3511 -82308C31 3512 -82308C32 3513 -82308C33 3514 -82308C34 3515 -82308C35 3516 -82308C36 3517 -82308C37 3518 -82308C38 3519 -82308C39 351A -82308D30 351B -82308D31 351C -82308D32 351D -82308D33 351E -82308D34 351F -82308D35 3520 -82308D36 3521 -82308D37 3522 -82308D38 3523 -82308D39 3524 -82308E30 3525 -82308E31 3526 -82308E32 3527 -82308E33 3528 -82308E34 3529 -82308E35 352A -82308E36 352B -82308E37 352C -82308E38 352D -82308E39 352E -82308F30 352F -82308F31 3530 -82308F32 3531 -82308F33 3532 -82308F34 3533 -82308F35 3534 -82308F36 3535 -82308F37 3536 -82308F38 3537 -82308F39 3538 -82309030 3539 -82309031 353A -82309032 353B -82309033 353C -82309034 353D -82309035 353E -82309036 353F -82309037 3540 -82309038 3541 -82309039 3542 -82309130 3543 -82309131 3544 -82309132 3545 -82309133 3546 -82309134 3547 -82309135 3548 -82309136 3549 -82309137 354A -82309138 354B -82309139 354C -82309230 354D -82309231 354E -82309232 354F -82309233 3550 -82309234 3551 -82309235 3552 -82309236 3553 -82309237 3554 -82309238 3555 -82309239 3556 -82309330 3557 -82309331 3558 -82309332 3559 -82309333 355A -82309334 355B -82309335 355C -82309336 355D -82309337 355E -82309338 355F -82309339 3560 -82309430 3561 -82309431 3562 -82309432 3563 -82309433 3564 -82309434 3565 -82309435 3566 -82309436 3567 -82309437 3568 -82309438 3569 -82309439 356A -82309530 356B -82309531 356C -82309532 356D -82309533 356E -82309534 356F -82309535 3570 -82309536 3571 -82309537 3572 -82309538 3573 -82309539 3574 -82309630 3575 -82309631 3576 -82309632 3577 -82309633 3578 -82309634 3579 -82309635 357A -82309636 357B -82309637 357C -82309638 357D -82309639 357E -82309730 357F -82309731 3580 -82309732 3581 -82309733 3582 -82309734 3583 -82309735 3584 -82309736 3585 -82309737 3586 -82309738 3587 -82309739 3588 -82309830 3589 -82309831 358A -82309832 358B -82309833 358C -82309834 358D -82309835 358E -82309836 358F -82309837 3590 -82309838 3591 -82309839 3592 -82309930 3593 -82309931 3594 -82309932 3595 -82309933 3596 -82309934 3597 -82309935 3598 -82309936 3599 -82309937 359A -82309938 359B -82309939 359C -82309A30 359D -FE5A 359E -82309A31 359F -82309A32 35A0 -82309A33 35A1 -82309A34 35A2 -82309A35 35A3 -82309A36 35A4 -82309A37 35A5 -82309A38 35A6 -82309A39 35A7 -82309B30 35A8 -82309B31 35A9 -82309B32 35AA -82309B33 35AB -82309B34 35AC -82309B35 35AD -82309B36 35AE -82309B37 35AF -82309B38 35B0 -82309B39 35B1 -82309C30 35B2 -82309C31 35B3 -82309C32 35B4 -82309C33 35B5 -82309C34 35B6 -82309C35 35B7 -82309C36 35B8 -82309C37 35B9 -82309C38 35BA -82309C39 35BB -82309D30 35BC -82309D31 35BD -82309D32 35BE -82309D33 35BF -82309D34 35C0 -82309D35 35C1 -82309D36 35C2 -82309D37 35C3 -82309D38 35C4 -82309D39 35C5 -82309E30 35C6 -82309E31 35C7 -82309E32 35C8 -82309E33 35C9 -82309E34 35CA -82309E35 35CB -82309E36 35CC -82309E37 35CD -82309E38 35CE -82309E39 35CF -82309F30 35D0 -82309F31 35D1 -82309F32 35D2 -82309F33 35D3 -82309F34 35D4 -82309F35 35D5 -82309F36 35D6 -82309F37 35D7 -82309F38 35D8 -82309F39 35D9 -8230A030 35DA -8230A031 35DB -8230A032 35DC -8230A033 35DD -8230A034 35DE -8230A035 35DF -8230A036 35E0 -8230A037 35E1 -8230A038 35E2 -8230A039 35E3 -8230A130 35E4 -8230A131 35E5 -8230A132 35E6 -8230A133 35E7 -8230A134 35E8 -8230A135 35E9 -8230A136 35EA -8230A137 35EB -8230A138 35EC -8230A139 35ED -8230A230 35EE -8230A231 35EF -8230A232 35F0 -8230A233 35F1 -8230A234 35F2 -8230A235 35F3 -8230A236 35F4 -8230A237 35F5 -8230A238 35F6 -8230A239 35F7 -8230A330 35F8 -8230A331 35F9 -8230A332 35FA -8230A333 35FB -8230A334 35FC -8230A335 35FD -8230A336 35FE -8230A337 35FF -8230A338 3600 -8230A339 3601 -8230A430 3602 -8230A431 3603 -8230A432 3604 -8230A433 3605 -8230A434 3606 -8230A435 3607 -8230A436 3608 -8230A437 3609 -8230A438 360A -8230A439 360B -8230A530 360C -8230A531 360D -FE5C 360E -8230A532 360F -8230A533 3610 -8230A534 3611 -8230A535 3612 -8230A536 3613 -8230A537 3614 -8230A538 3615 -8230A539 3616 -8230A630 3617 -8230A631 3618 -8230A632 3619 -FE5B 361A -8230A633 361B -8230A634 361C -8230A635 361D -8230A636 361E -8230A637 361F -8230A638 3620 -8230A639 3621 -8230A730 3622 -8230A731 3623 -8230A732 3624 -8230A733 3625 -8230A734 3626 -8230A735 3627 -8230A736 3628 -8230A737 3629 -8230A738 362A -8230A739 362B -8230A830 362C -8230A831 362D -8230A832 362E -8230A833 362F -8230A834 3630 -8230A835 3631 -8230A836 3632 -8230A837 3633 -8230A838 3634 -8230A839 3635 -8230A930 3636 -8230A931 3637 -8230A932 3638 -8230A933 3639 -8230A934 363A -8230A935 363B -8230A936 363C -8230A937 363D -8230A938 363E -8230A939 363F -8230AA30 3640 -8230AA31 3641 -8230AA32 3642 -8230AA33 3643 -8230AA34 3644 -8230AA35 3645 -8230AA36 3646 -8230AA37 3647 -8230AA38 3648 -8230AA39 3649 -8230AB30 364A -8230AB31 364B -8230AB32 364C -8230AB33 364D -8230AB34 364E -8230AB35 364F -8230AB36 3650 -8230AB37 3651 -8230AB38 3652 -8230AB39 3653 -8230AC30 3654 -8230AC31 3655 -8230AC32 3656 -8230AC33 3657 -8230AC34 3658 -8230AC35 3659 -8230AC36 365A -8230AC37 365B -8230AC38 365C -8230AC39 365D -8230AD30 365E -8230AD31 365F -8230AD32 3660 -8230AD33 3661 -8230AD34 3662 -8230AD35 3663 -8230AD36 3664 -8230AD37 3665 -8230AD38 3666 -8230AD39 3667 -8230AE30 3668 -8230AE31 3669 -8230AE32 366A -8230AE33 366B -8230AE34 366C -8230AE35 366D -8230AE36 366E -8230AE37 366F -8230AE38 3670 -8230AE39 3671 -8230AF30 3672 -8230AF31 3673 -8230AF32 3674 -8230AF33 3675 -8230AF34 3676 -8230AF35 3677 -8230AF36 3678 -8230AF37 3679 -8230AF38 367A -8230AF39 367B -8230B030 367C -8230B031 367D -8230B032 367E -8230B033 367F -8230B034 3680 -8230B035 3681 -8230B036 3682 -8230B037 3683 -8230B038 3684 -8230B039 3685 -8230B130 3686 -8230B131 3687 -8230B132 3688 -8230B133 3689 -8230B134 368A -8230B135 368B -8230B136 368C -8230B137 368D -8230B138 368E -8230B139 368F -8230B230 3690 -8230B231 3691 -8230B232 3692 -8230B233 3693 -8230B234 3694 -8230B235 3695 -8230B236 3696 -8230B237 3697 -8230B238 3698 -8230B239 3699 -8230B330 369A -8230B331 369B -8230B332 369C -8230B333 369D -8230B334 369E -8230B335 369F -8230B336 36A0 -8230B337 36A1 -8230B338 36A2 -8230B339 36A3 -8230B430 36A4 -8230B431 36A5 -8230B432 36A6 -8230B433 36A7 -8230B434 36A8 -8230B435 36A9 -8230B436 36AA -8230B437 36AB -8230B438 36AC -8230B439 36AD -8230B530 36AE -8230B531 36AF -8230B532 36B0 -8230B533 36B1 -8230B534 36B2 -8230B535 36B3 -8230B536 36B4 -8230B537 36B5 -8230B538 36B6 -8230B539 36B7 -8230B630 36B8 -8230B631 36B9 -8230B632 36BA -8230B633 36BB -8230B634 36BC -8230B635 36BD -8230B636 36BE -8230B637 36BF -8230B638 36C0 -8230B639 36C1 -8230B730 36C2 -8230B731 36C3 -8230B732 36C4 -8230B733 36C5 -8230B734 36C6 -8230B735 36C7 -8230B736 36C8 -8230B737 36C9 -8230B738 36CA -8230B739 36CB -8230B830 36CC -8230B831 36CD -8230B832 36CE -8230B833 36CF -8230B834 36D0 -8230B835 36D1 -8230B836 36D2 -8230B837 36D3 -8230B838 36D4 -8230B839 36D5 -8230B930 36D6 -8230B931 36D7 -8230B932 36D8 -8230B933 36D9 -8230B934 36DA -8230B935 36DB -8230B936 36DC -8230B937 36DD -8230B938 36DE -8230B939 36DF -8230BA30 36E0 -8230BA31 36E1 -8230BA32 36E2 -8230BA33 36E3 -8230BA34 36E4 -8230BA35 36E5 -8230BA36 36E6 -8230BA37 36E7 -8230BA38 36E8 -8230BA39 36E9 -8230BB30 36EA -8230BB31 36EB -8230BB32 36EC -8230BB33 36ED -8230BB34 36EE -8230BB35 36EF -8230BB36 36F0 -8230BB37 36F1 -8230BB38 36F2 -8230BB39 36F3 -8230BC30 36F4 -8230BC31 36F5 -8230BC32 36F6 -8230BC33 36F7 -8230BC34 36F8 -8230BC35 36F9 -8230BC36 36FA -8230BC37 36FB -8230BC38 36FC -8230BC39 36FD -8230BD30 36FE -8230BD31 36FF -8230BD32 3700 -8230BD33 3701 -8230BD34 3702 -8230BD35 3703 -8230BD36 3704 -8230BD37 3705 -8230BD38 3706 -8230BD39 3707 -8230BE30 3708 -8230BE31 3709 -8230BE32 370A -8230BE33 370B -8230BE34 370C -8230BE35 370D -8230BE36 370E -8230BE37 370F -8230BE38 3710 -8230BE39 3711 -8230BF30 3712 -8230BF31 3713 -8230BF32 3714 -8230BF33 3715 -8230BF34 3716 -8230BF35 3717 -8230BF36 3718 -8230BF37 3719 -8230BF38 371A -8230BF39 371B -8230C030 371C -8230C031 371D -8230C032 371E -8230C033 371F -8230C034 3720 -8230C035 3721 -8230C036 3722 -8230C037 3723 -8230C038 3724 -8230C039 3725 -8230C130 3726 -8230C131 3727 -8230C132 3728 -8230C133 3729 -8230C134 372A -8230C135 372B -8230C136 372C -8230C137 372D -8230C138 372E -8230C139 372F -8230C230 3730 -8230C231 3731 -8230C232 3732 -8230C233 3733 -8230C234 3734 -8230C235 3735 -8230C236 3736 -8230C237 3737 -8230C238 3738 -8230C239 3739 -8230C330 373A -8230C331 373B -8230C332 373C -8230C333 373D -8230C334 373E -8230C335 373F -8230C336 3740 -8230C337 3741 -8230C338 3742 -8230C339 3743 -8230C430 3744 -8230C431 3745 -8230C432 3746 -8230C433 3747 -8230C434 3748 -8230C435 3749 -8230C436 374A -8230C437 374B -8230C438 374C -8230C439 374D -8230C530 374E -8230C531 374F -8230C532 3750 -8230C533 3751 -8230C534 3752 -8230C535 3753 -8230C536 3754 -8230C537 3755 -8230C538 3756 -8230C539 3757 -8230C630 3758 -8230C631 3759 -8230C632 375A -8230C633 375B -8230C634 375C -8230C635 375D -8230C636 375E -8230C637 375F -8230C638 3760 -8230C639 3761 -8230C730 3762 -8230C731 3763 -8230C732 3764 -8230C733 3765 -8230C734 3766 -8230C735 3767 -8230C736 3768 -8230C737 3769 -8230C738 376A -8230C739 376B -8230C830 376C -8230C831 376D -8230C832 376E -8230C833 376F -8230C834 3770 -8230C835 3771 -8230C836 3772 -8230C837 3773 -8230C838 3774 -8230C839 3775 -8230C930 3776 -8230C931 3777 -8230C932 3778 -8230C933 3779 -8230C934 377A -8230C935 377B -8230C936 377C -8230C937 377D -8230C938 377E -8230C939 377F -8230CA30 3780 -8230CA31 3781 -8230CA32 3782 -8230CA33 3783 -8230CA34 3784 -8230CA35 3785 -8230CA36 3786 -8230CA37 3787 -8230CA38 3788 -8230CA39 3789 -8230CB30 378A -8230CB31 378B -8230CB32 378C -8230CB33 378D -8230CB34 378E -8230CB35 378F -8230CB36 3790 -8230CB37 3791 -8230CB38 3792 -8230CB39 3793 -8230CC30 3794 -8230CC31 3795 -8230CC32 3796 -8230CC33 3797 -8230CC34 3798 -8230CC35 3799 -8230CC36 379A -8230CC37 379B -8230CC38 379C -8230CC39 379D -8230CD30 379E -8230CD31 379F -8230CD32 37A0 -8230CD33 37A1 -8230CD34 37A2 -8230CD35 37A3 -8230CD36 37A4 -8230CD37 37A5 -8230CD38 37A6 -8230CD39 37A7 -8230CE30 37A8 -8230CE31 37A9 -8230CE32 37AA -8230CE33 37AB -8230CE34 37AC -8230CE35 37AD -8230CE36 37AE -8230CE37 37AF -8230CE38 37B0 -8230CE39 37B1 -8230CF30 37B2 -8230CF31 37B3 -8230CF32 37B4 -8230CF33 37B5 -8230CF34 37B6 -8230CF35 37B7 -8230CF36 37B8 -8230CF37 37B9 -8230CF38 37BA -8230CF39 37BB -8230D030 37BC -8230D031 37BD -8230D032 37BE -8230D033 37BF -8230D034 37C0 -8230D035 37C1 -8230D036 37C2 -8230D037 37C3 -8230D038 37C4 -8230D039 37C5 -8230D130 37C6 -8230D131 37C7 -8230D132 37C8 -8230D133 37C9 -8230D134 37CA -8230D135 37CB -8230D136 37CC -8230D137 37CD -8230D138 37CE -8230D139 37CF -8230D230 37D0 -8230D231 37D1 -8230D232 37D2 -8230D233 37D3 -8230D234 37D4 -8230D235 37D5 -8230D236 37D6 -8230D237 37D7 -8230D238 37D8 -8230D239 37D9 -8230D330 37DA -8230D331 37DB -8230D332 37DC -8230D333 37DD -8230D334 37DE -8230D335 37DF -8230D336 37E0 -8230D337 37E1 -8230D338 37E2 -8230D339 37E3 -8230D430 37E4 -8230D431 37E5 -8230D432 37E6 -8230D433 37E7 -8230D434 37E8 -8230D435 37E9 -8230D436 37EA -8230D437 37EB -8230D438 37EC -8230D439 37ED -8230D530 37EE -8230D531 37EF -8230D532 37F0 -8230D533 37F1 -8230D534 37F2 -8230D535 37F3 -8230D536 37F4 -8230D537 37F5 -8230D538 37F6 -8230D539 37F7 -8230D630 37F8 -8230D631 37F9 -8230D632 37FA -8230D633 37FB -8230D634 37FC -8230D635 37FD -8230D636 37FE -8230D637 37FF -8230D638 3800 -8230D639 3801 -8230D730 3802 -8230D731 3803 -8230D732 3804 -8230D733 3805 -8230D734 3806 -8230D735 3807 -8230D736 3808 -8230D737 3809 -8230D738 380A -8230D739 380B -8230D830 380C -8230D831 380D -8230D832 380E -8230D833 380F -8230D834 3810 -8230D835 3811 -8230D836 3812 -8230D837 3813 -8230D838 3814 -8230D839 3815 -8230D930 3816 -8230D931 3817 -8230D932 3818 -8230D933 3819 -8230D934 381A -8230D935 381B -8230D936 381C -8230D937 381D -8230D938 381E -8230D939 381F -8230DA30 3820 -8230DA31 3821 -8230DA32 3822 -8230DA33 3823 -8230DA34 3824 -8230DA35 3825 -8230DA36 3826 -8230DA37 3827 -8230DA38 3828 -8230DA39 3829 -8230DB30 382A -8230DB31 382B -8230DB32 382C -8230DB33 382D -8230DB34 382E -8230DB35 382F -8230DB36 3830 -8230DB37 3831 -8230DB38 3832 -8230DB39 3833 -8230DC30 3834 -8230DC31 3835 -8230DC32 3836 -8230DC33 3837 -8230DC34 3838 -8230DC35 3839 -8230DC36 383A -8230DC37 383B -8230DC38 383C -8230DC39 383D -8230DD30 383E -8230DD31 383F -8230DD32 3840 -8230DD33 3841 -8230DD34 3842 -8230DD35 3843 -8230DD36 3844 -8230DD37 3845 -8230DD38 3846 -8230DD39 3847 -8230DE30 3848 -8230DE31 3849 -8230DE32 384A -8230DE33 384B -8230DE34 384C -8230DE35 384D -8230DE36 384E -8230DE37 384F -8230DE38 3850 -8230DE39 3851 -8230DF30 3852 -8230DF31 3853 -8230DF32 3854 -8230DF33 3855 -8230DF34 3856 -8230DF35 3857 -8230DF36 3858 -8230DF37 3859 -8230DF38 385A -8230DF39 385B -8230E030 385C -8230E031 385D -8230E032 385E -8230E033 385F -8230E034 3860 -8230E035 3861 -8230E036 3862 -8230E037 3863 -8230E038 3864 -8230E039 3865 -8230E130 3866 -8230E131 3867 -8230E132 3868 -8230E133 3869 -8230E134 386A -8230E135 386B -8230E136 386C -8230E137 386D -8230E138 386E -8230E139 386F -8230E230 3870 -8230E231 3871 -8230E232 3872 -8230E233 3873 -8230E234 3874 -8230E235 3875 -8230E236 3876 -8230E237 3877 -8230E238 3878 -8230E239 3879 -8230E330 387A -8230E331 387B -8230E332 387C -8230E333 387D -8230E334 387E -8230E335 387F -8230E336 3880 -8230E337 3881 -8230E338 3882 -8230E339 3883 -8230E430 3884 -8230E431 3885 -8230E432 3886 -8230E433 3887 -8230E434 3888 -8230E435 3889 -8230E436 388A -8230E437 388B -8230E438 388C -8230E439 388D -8230E530 388E -8230E531 388F -8230E532 3890 -8230E533 3891 -8230E534 3892 -8230E535 3893 -8230E536 3894 -8230E537 3895 -8230E538 3896 -8230E539 3897 -8230E630 3898 -8230E631 3899 -8230E632 389A -8230E633 389B -8230E634 389C -8230E635 389D -8230E636 389E -8230E637 389F -8230E638 38A0 -8230E639 38A1 -8230E730 38A2 -8230E731 38A3 -8230E732 38A4 -8230E733 38A5 -8230E734 38A6 -8230E735 38A7 -8230E736 38A8 -8230E737 38A9 -8230E738 38AA -8230E739 38AB -8230E830 38AC -8230E831 38AD -8230E832 38AE -8230E833 38AF -8230E834 38B0 -8230E835 38B1 -8230E836 38B2 -8230E837 38B3 -8230E838 38B4 -8230E839 38B5 -8230E930 38B6 -8230E931 38B7 -8230E932 38B8 -8230E933 38B9 -8230E934 38BA -8230E935 38BB -8230E936 38BC -8230E937 38BD -8230E938 38BE -8230E939 38BF -8230EA30 38C0 -8230EA31 38C1 -8230EA32 38C2 -8230EA33 38C3 -8230EA34 38C4 -8230EA35 38C5 -8230EA36 38C6 -8230EA37 38C7 -8230EA38 38C8 -8230EA39 38C9 -8230EB30 38CA -8230EB31 38CB -8230EB32 38CC -8230EB33 38CD -8230EB34 38CE -8230EB35 38CF -8230EB36 38D0 -8230EB37 38D1 -8230EB38 38D2 -8230EB39 38D3 -8230EC30 38D4 -8230EC31 38D5 -8230EC32 38D6 -8230EC33 38D7 -8230EC34 38D8 -8230EC35 38D9 -8230EC36 38DA -8230EC37 38DB -8230EC38 38DC -8230EC39 38DD -8230ED30 38DE -8230ED31 38DF -8230ED32 38E0 -8230ED33 38E1 -8230ED34 38E2 -8230ED35 38E3 -8230ED36 38E4 -8230ED37 38E5 -8230ED38 38E6 -8230ED39 38E7 -8230EE30 38E8 -8230EE31 38E9 -8230EE32 38EA -8230EE33 38EB -8230EE34 38EC -8230EE35 38ED -8230EE36 38EE -8230EE37 38EF -8230EE38 38F0 -8230EE39 38F1 -8230EF30 38F2 -8230EF31 38F3 -8230EF32 38F4 -8230EF33 38F5 -8230EF34 38F6 -8230EF35 38F7 -8230EF36 38F8 -8230EF37 38F9 -8230EF38 38FA -8230EF39 38FB -8230F030 38FC -8230F031 38FD -8230F032 38FE -8230F033 38FF -8230F034 3900 -8230F035 3901 -8230F036 3902 -8230F037 3903 -8230F038 3904 -8230F039 3905 -8230F130 3906 -8230F131 3907 -8230F132 3908 -8230F133 3909 -8230F134 390A -8230F135 390B -8230F136 390C -8230F137 390D -8230F138 390E -8230F139 390F -8230F230 3910 -8230F231 3911 -8230F232 3912 -8230F233 3913 -8230F234 3914 -8230F235 3915 -8230F236 3916 -8230F237 3917 -FE60 3918 -8230F238 3919 -8230F239 391A -8230F330 391B -8230F331 391C -8230F332 391D -8230F333 391E -8230F334 391F -8230F335 3920 -8230F336 3921 -8230F337 3922 -8230F338 3923 -8230F339 3924 -8230F430 3925 -8230F431 3926 -8230F432 3927 -8230F433 3928 -8230F434 3929 -8230F435 392A -8230F436 392B -8230F437 392C -8230F438 392D -8230F439 392E -8230F530 392F -8230F531 3930 -8230F532 3931 -8230F533 3932 -8230F534 3933 -8230F535 3934 -8230F536 3935 -8230F537 3936 -8230F538 3937 -8230F539 3938 -8230F630 3939 -8230F631 393A -8230F632 393B -8230F633 393C -8230F634 393D -8230F635 393E -8230F636 393F -8230F637 3940 -8230F638 3941 -8230F639 3942 -8230F730 3943 -8230F731 3944 -8230F732 3945 -8230F733 3946 -8230F734 3947 -8230F735 3948 -8230F736 3949 -8230F737 394A -8230F738 394B -8230F739 394C -8230F830 394D -8230F831 394E -8230F832 394F -8230F833 3950 -8230F834 3951 -8230F835 3952 -8230F836 3953 -8230F837 3954 -8230F838 3955 -8230F839 3956 -8230F930 3957 -8230F931 3958 -8230F932 3959 -8230F933 395A -8230F934 395B -8230F935 395C -8230F936 395D -8230F937 395E -8230F938 395F -8230F939 3960 -8230FA30 3961 -8230FA31 3962 -8230FA32 3963 -8230FA33 3964 -8230FA34 3965 -8230FA35 3966 -8230FA36 3967 -8230FA37 3968 -8230FA38 3969 -8230FA39 396A -8230FB30 396B -8230FB31 396C -8230FB32 396D -FE5F 396E -8230FB33 396F -8230FB34 3970 -8230FB35 3971 -8230FB36 3972 -8230FB37 3973 -8230FB38 3974 -8230FB39 3975 -8230FC30 3976 -8230FC31 3977 -8230FC32 3978 -8230FC33 3979 -8230FC34 397A -8230FC35 397B -8230FC36 397C -8230FC37 397D -8230FC38 397E -8230FC39 397F -8230FD30 3980 -8230FD31 3981 -8230FD32 3982 -8230FD33 3983 -8230FD34 3984 -8230FD35 3985 -8230FD36 3986 -8230FD37 3987 -8230FD38 3988 -8230FD39 3989 -8230FE30 398A -8230FE31 398B -8230FE32 398C -8230FE33 398D -8230FE34 398E -8230FE35 398F -8230FE36 3990 -8230FE37 3991 -8230FE38 3992 -8230FE39 3993 -82318130 3994 -82318131 3995 -82318132 3996 -82318133 3997 -82318134 3998 -82318135 3999 -82318136 399A -82318137 399B -82318138 399C -82318139 399D -82318230 399E -82318231 399F -82318232 39A0 -82318233 39A1 -82318234 39A2 -82318235 39A3 -82318236 39A4 -82318237 39A5 -82318238 39A6 -82318239 39A7 -82318330 39A8 -82318331 39A9 -82318332 39AA -82318333 39AB -82318334 39AC -82318335 39AD -82318336 39AE -82318337 39AF -82318338 39B0 -82318339 39B1 -82318430 39B2 -82318431 39B3 -82318432 39B4 -82318433 39B5 -82318434 39B6 -82318435 39B7 -82318436 39B8 -82318437 39B9 -82318438 39BA -82318439 39BB -82318530 39BC -82318531 39BD -82318532 39BE -82318533 39BF -82318534 39C0 -82318535 39C1 -82318536 39C2 -82318537 39C3 -82318538 39C4 -82318539 39C5 -82318630 39C6 -82318631 39C7 -82318632 39C8 -82318633 39C9 -82318634 39CA -82318635 39CB -82318636 39CC -82318637 39CD -82318638 39CE -FE62 39CF -FE65 39D0 -82318639 39D1 -82318730 39D2 -82318731 39D3 -82318732 39D4 -82318733 39D5 -82318734 39D6 -82318735 39D7 -82318736 39D8 -82318737 39D9 -82318738 39DA -82318739 39DB -82318830 39DC -82318831 39DD -82318832 39DE -FE63 39DF -82318833 39E0 -82318834 39E1 -82318835 39E2 -82318836 39E3 -82318837 39E4 -82318838 39E5 -82318839 39E6 -82318930 39E7 -82318931 39E8 -82318932 39E9 -82318933 39EA -82318934 39EB -82318935 39EC -82318936 39ED -82318937 39EE -82318938 39EF -82318939 39F0 -82318A30 39F1 -82318A31 39F2 -82318A32 39F3 -82318A33 39F4 -82318A34 39F5 -82318A35 39F6 -82318A36 39F7 -82318A37 39F8 -82318A38 39F9 -82318A39 39FA -82318B30 39FB -82318B31 39FC -82318B32 39FD -82318B33 39FE -82318B34 39FF -82318B35 3A00 -82318B36 3A01 -82318B37 3A02 -82318B38 3A03 -82318B39 3A04 -82318C30 3A05 -82318C31 3A06 -82318C32 3A07 -82318C33 3A08 -82318C34 3A09 -82318C35 3A0A -82318C36 3A0B -82318C37 3A0C -82318C38 3A0D -82318C39 3A0E -82318D30 3A0F -82318D31 3A10 -82318D32 3A11 -82318D33 3A12 -82318D34 3A13 -82318D35 3A14 -82318D36 3A15 -82318D37 3A16 -82318D38 3A17 -82318D39 3A18 -82318E30 3A19 -82318E31 3A1A -82318E32 3A1B -82318E33 3A1C -82318E34 3A1D -82318E35 3A1E -82318E36 3A1F -82318E37 3A20 -82318E38 3A21 -82318E39 3A22 -82318F30 3A23 -82318F31 3A24 -82318F32 3A25 -82318F33 3A26 -82318F34 3A27 -82318F35 3A28 -82318F36 3A29 -82318F37 3A2A -82318F38 3A2B -82318F39 3A2C -82319030 3A2D -82319031 3A2E -82319032 3A2F -82319033 3A30 -82319034 3A31 -82319035 3A32 -82319036 3A33 -82319037 3A34 -82319038 3A35 -82319039 3A36 -82319130 3A37 -82319131 3A38 -82319132 3A39 -82319133 3A3A -82319134 3A3B -82319135 3A3C -82319136 3A3D -82319137 3A3E -82319138 3A3F -82319139 3A40 -82319230 3A41 -82319231 3A42 -82319232 3A43 -82319233 3A44 -82319234 3A45 -82319235 3A46 -82319236 3A47 -82319237 3A48 -82319238 3A49 -82319239 3A4A -82319330 3A4B -82319331 3A4C -82319332 3A4D -82319333 3A4E -82319334 3A4F -82319335 3A50 -82319336 3A51 -82319337 3A52 -82319338 3A53 -82319339 3A54 -82319430 3A55 -82319431 3A56 -82319432 3A57 -82319433 3A58 -82319434 3A59 -82319435 3A5A -82319436 3A5B -82319437 3A5C -82319438 3A5D -82319439 3A5E -82319530 3A5F -82319531 3A60 -82319532 3A61 -82319533 3A62 -82319534 3A63 -82319535 3A64 -82319536 3A65 -82319537 3A66 -82319538 3A67 -82319539 3A68 -82319630 3A69 -82319631 3A6A -82319632 3A6B -82319633 3A6C -82319634 3A6D -82319635 3A6E -82319636 3A6F -82319637 3A70 -82319638 3A71 -82319639 3A72 -FE64 3A73 -82319730 3A74 -82319731 3A75 -82319732 3A76 -82319733 3A77 -82319734 3A78 -82319735 3A79 -82319736 3A7A -82319737 3A7B -82319738 3A7C -82319739 3A7D -82319830 3A7E -82319831 3A7F -82319832 3A80 -82319833 3A81 -82319834 3A82 -82319835 3A83 -82319836 3A84 -82319837 3A85 -82319838 3A86 -82319839 3A87 -82319930 3A88 -82319931 3A89 -82319932 3A8A -82319933 3A8B -82319934 3A8C -82319935 3A8D -82319936 3A8E -82319937 3A8F -82319938 3A90 -82319939 3A91 -82319A30 3A92 -82319A31 3A93 -82319A32 3A94 -82319A33 3A95 -82319A34 3A96 -82319A35 3A97 -82319A36 3A98 -82319A37 3A99 -82319A38 3A9A -82319A39 3A9B -82319B30 3A9C -82319B31 3A9D -82319B32 3A9E -82319B33 3A9F -82319B34 3AA0 -82319B35 3AA1 -82319B36 3AA2 -82319B37 3AA3 -82319B38 3AA4 -82319B39 3AA5 -82319C30 3AA6 -82319C31 3AA7 -82319C32 3AA8 -82319C33 3AA9 -82319C34 3AAA -82319C35 3AAB -82319C36 3AAC -82319C37 3AAD -82319C38 3AAE -82319C39 3AAF -82319D30 3AB0 -82319D31 3AB1 -82319D32 3AB2 -82319D33 3AB3 -82319D34 3AB4 -82319D35 3AB5 -82319D36 3AB6 -82319D37 3AB7 -82319D38 3AB8 -82319D39 3AB9 -82319E30 3ABA -82319E31 3ABB -82319E32 3ABC -82319E33 3ABD -82319E34 3ABE -82319E35 3ABF -82319E36 3AC0 -82319E37 3AC1 -82319E38 3AC2 -82319E39 3AC3 -82319F30 3AC4 -82319F31 3AC5 -82319F32 3AC6 -82319F33 3AC7 -82319F34 3AC8 -82319F35 3AC9 -82319F36 3ACA -82319F37 3ACB -82319F38 3ACC -82319F39 3ACD -8231A030 3ACE -8231A031 3ACF -8231A032 3AD0 -8231A033 3AD1 -8231A034 3AD2 -8231A035 3AD3 -8231A036 3AD4 -8231A037 3AD5 -8231A038 3AD6 -8231A039 3AD7 -8231A130 3AD8 -8231A131 3AD9 -8231A132 3ADA -8231A133 3ADB -8231A134 3ADC -8231A135 3ADD -8231A136 3ADE -8231A137 3ADF -8231A138 3AE0 -8231A139 3AE1 -8231A230 3AE2 -8231A231 3AE3 -8231A232 3AE4 -8231A233 3AE5 -8231A234 3AE6 -8231A235 3AE7 -8231A236 3AE8 -8231A237 3AE9 -8231A238 3AEA -8231A239 3AEB -8231A330 3AEC -8231A331 3AED -8231A332 3AEE -8231A333 3AEF -8231A334 3AF0 -8231A335 3AF1 -8231A336 3AF2 -8231A337 3AF3 -8231A338 3AF4 -8231A339 3AF5 -8231A430 3AF6 -8231A431 3AF7 -8231A432 3AF8 -8231A433 3AF9 -8231A434 3AFA -8231A435 3AFB -8231A436 3AFC -8231A437 3AFD -8231A438 3AFE -8231A439 3AFF -8231A530 3B00 -8231A531 3B01 -8231A532 3B02 -8231A533 3B03 -8231A534 3B04 -8231A535 3B05 -8231A536 3B06 -8231A537 3B07 -8231A538 3B08 -8231A539 3B09 -8231A630 3B0A -8231A631 3B0B -8231A632 3B0C -8231A633 3B0D -8231A634 3B0E -8231A635 3B0F -8231A636 3B10 -8231A637 3B11 -8231A638 3B12 -8231A639 3B13 -8231A730 3B14 -8231A731 3B15 -8231A732 3B16 -8231A733 3B17 -8231A734 3B18 -8231A735 3B19 -8231A736 3B1A -8231A737 3B1B -8231A738 3B1C -8231A739 3B1D -8231A830 3B1E -8231A831 3B1F -8231A832 3B20 -8231A833 3B21 -8231A834 3B22 -8231A835 3B23 -8231A836 3B24 -8231A837 3B25 -8231A838 3B26 -8231A839 3B27 -8231A930 3B28 -8231A931 3B29 -8231A932 3B2A -8231A933 3B2B -8231A934 3B2C -8231A935 3B2D -8231A936 3B2E -8231A937 3B2F -8231A938 3B30 -8231A939 3B31 -8231AA30 3B32 -8231AA31 3B33 -8231AA32 3B34 -8231AA33 3B35 -8231AA34 3B36 -8231AA35 3B37 -8231AA36 3B38 -8231AA37 3B39 -8231AA38 3B3A -8231AA39 3B3B -8231AB30 3B3C -8231AB31 3B3D -8231AB32 3B3E -8231AB33 3B3F -8231AB34 3B40 -8231AB35 3B41 -8231AB36 3B42 -8231AB37 3B43 -8231AB38 3B44 -8231AB39 3B45 -8231AC30 3B46 -8231AC31 3B47 -8231AC32 3B48 -8231AC33 3B49 -8231AC34 3B4A -8231AC35 3B4B -8231AC36 3B4C -8231AC37 3B4D -FE68 3B4E -8231AC38 3B4F -8231AC39 3B50 -8231AD30 3B51 -8231AD31 3B52 -8231AD32 3B53 -8231AD33 3B54 -8231AD34 3B55 -8231AD35 3B56 -8231AD36 3B57 -8231AD37 3B58 -8231AD38 3B59 -8231AD39 3B5A -8231AE30 3B5B -8231AE31 3B5C -8231AE32 3B5D -8231AE33 3B5E -8231AE34 3B5F -8231AE35 3B60 -8231AE36 3B61 -8231AE37 3B62 -8231AE38 3B63 -8231AE39 3B64 -8231AF30 3B65 -8231AF31 3B66 -8231AF32 3B67 -8231AF33 3B68 -8231AF34 3B69 -8231AF35 3B6A -8231AF36 3B6B -8231AF37 3B6C -8231AF38 3B6D -8231AF39 3B6E -8231B030 3B6F -8231B031 3B70 -8231B032 3B71 -8231B033 3B72 -8231B034 3B73 -8231B035 3B74 -8231B036 3B75 -8231B037 3B76 -8231B038 3B77 -8231B039 3B78 -8231B130 3B79 -8231B131 3B7A -8231B132 3B7B -8231B133 3B7C -8231B134 3B7D -8231B135 3B7E -8231B136 3B7F -8231B137 3B80 -8231B138 3B81 -8231B139 3B82 -8231B230 3B83 -8231B231 3B84 -8231B232 3B85 -8231B233 3B86 -8231B234 3B87 -8231B235 3B88 -8231B236 3B89 -8231B237 3B8A -8231B238 3B8B -8231B239 3B8C -8231B330 3B8D -8231B331 3B8E -8231B332 3B8F -8231B333 3B90 -8231B334 3B91 -8231B335 3B92 -8231B336 3B93 -8231B337 3B94 -8231B338 3B95 -8231B339 3B96 -8231B430 3B97 -8231B431 3B98 -8231B432 3B99 -8231B433 3B9A -8231B434 3B9B -8231B435 3B9C -8231B436 3B9D -8231B437 3B9E -8231B438 3B9F -8231B439 3BA0 -8231B530 3BA1 -8231B531 3BA2 -8231B532 3BA3 -8231B533 3BA4 -8231B534 3BA5 -8231B535 3BA6 -8231B536 3BA7 -8231B537 3BA8 -8231B538 3BA9 -8231B539 3BAA -8231B630 3BAB -8231B631 3BAC -8231B632 3BAD -8231B633 3BAE -8231B634 3BAF -8231B635 3BB0 -8231B636 3BB1 -8231B637 3BB2 -8231B638 3BB3 -8231B639 3BB4 -8231B730 3BB5 -8231B731 3BB6 -8231B732 3BB7 -8231B733 3BB8 -8231B734 3BB9 -8231B735 3BBA -8231B736 3BBB -8231B737 3BBC -8231B738 3BBD -8231B739 3BBE -8231B830 3BBF -8231B831 3BC0 -8231B832 3BC1 -8231B833 3BC2 -8231B834 3BC3 -8231B835 3BC4 -8231B836 3BC5 -8231B837 3BC6 -8231B838 3BC7 -8231B839 3BC8 -8231B930 3BC9 -8231B931 3BCA -8231B932 3BCB -8231B933 3BCC -8231B934 3BCD -8231B935 3BCE -8231B936 3BCF -8231B937 3BD0 -8231B938 3BD1 -8231B939 3BD2 -8231BA30 3BD3 -8231BA31 3BD4 -8231BA32 3BD5 -8231BA33 3BD6 -8231BA34 3BD7 -8231BA35 3BD8 -8231BA36 3BD9 -8231BA37 3BDA -8231BA38 3BDB -8231BA39 3BDC -8231BB30 3BDD -8231BB31 3BDE -8231BB32 3BDF -8231BB33 3BE0 -8231BB34 3BE1 -8231BB35 3BE2 -8231BB36 3BE3 -8231BB37 3BE4 -8231BB38 3BE5 -8231BB39 3BE6 -8231BC30 3BE7 -8231BC31 3BE8 -8231BC32 3BE9 -8231BC33 3BEA -8231BC34 3BEB -8231BC35 3BEC -8231BC36 3BED -8231BC37 3BEE -8231BC38 3BEF -8231BC39 3BF0 -8231BD30 3BF1 -8231BD31 3BF2 -8231BD32 3BF3 -8231BD33 3BF4 -8231BD34 3BF5 -8231BD35 3BF6 -8231BD36 3BF7 -8231BD37 3BF8 -8231BD38 3BF9 -8231BD39 3BFA -8231BE30 3BFB -8231BE31 3BFC -8231BE32 3BFD -8231BE33 3BFE -8231BE34 3BFF -8231BE35 3C00 -8231BE36 3C01 -8231BE37 3C02 -8231BE38 3C03 -8231BE39 3C04 -8231BF30 3C05 -8231BF31 3C06 -8231BF32 3C07 -8231BF33 3C08 -8231BF34 3C09 -8231BF35 3C0A -8231BF36 3C0B -8231BF37 3C0C -8231BF38 3C0D -8231BF39 3C0E -8231C030 3C0F -8231C031 3C10 -8231C032 3C11 -8231C033 3C12 -8231C034 3C13 -8231C035 3C14 -8231C036 3C15 -8231C037 3C16 -8231C038 3C17 -8231C039 3C18 -8231C130 3C19 -8231C131 3C1A -8231C132 3C1B -8231C133 3C1C -8231C134 3C1D -8231C135 3C1E -8231C136 3C1F -8231C137 3C20 -8231C138 3C21 -8231C139 3C22 -8231C230 3C23 -8231C231 3C24 -8231C232 3C25 -8231C233 3C26 -8231C234 3C27 -8231C235 3C28 -8231C236 3C29 -8231C237 3C2A -8231C238 3C2B -8231C239 3C2C -8231C330 3C2D -8231C331 3C2E -8231C332 3C2F -8231C333 3C30 -8231C334 3C31 -8231C335 3C32 -8231C336 3C33 -8231C337 3C34 -8231C338 3C35 -8231C339 3C36 -8231C430 3C37 -8231C431 3C38 -8231C432 3C39 -8231C433 3C3A -8231C434 3C3B -8231C435 3C3C -8231C436 3C3D -8231C437 3C3E -8231C438 3C3F -8231C439 3C40 -8231C530 3C41 -8231C531 3C42 -8231C532 3C43 -8231C533 3C44 -8231C534 3C45 -8231C535 3C46 -8231C536 3C47 -8231C537 3C48 -8231C538 3C49 -8231C539 3C4A -8231C630 3C4B -8231C631 3C4C -8231C632 3C4D -8231C633 3C4E -8231C634 3C4F -8231C635 3C50 -8231C636 3C51 -8231C637 3C52 -8231C638 3C53 -8231C639 3C54 -8231C730 3C55 -8231C731 3C56 -8231C732 3C57 -8231C733 3C58 -8231C734 3C59 -8231C735 3C5A -8231C736 3C5B -8231C737 3C5C -8231C738 3C5D -8231C739 3C5E -8231C830 3C5F -8231C831 3C60 -8231C832 3C61 -8231C833 3C62 -8231C834 3C63 -8231C835 3C64 -8231C836 3C65 -8231C837 3C66 -8231C838 3C67 -8231C839 3C68 -8231C930 3C69 -8231C931 3C6A -8231C932 3C6B -8231C933 3C6C -8231C934 3C6D -FE69 3C6E -8231C935 3C6F -8231C936 3C70 -8231C937 3C71 -8231C938 3C72 -8231C939 3C73 -8231CA30 3C74 -8231CA31 3C75 -8231CA32 3C76 -8231CA33 3C77 -8231CA34 3C78 -8231CA35 3C79 -8231CA36 3C7A -8231CA37 3C7B -8231CA38 3C7C -8231CA39 3C7D -8231CB30 3C7E -8231CB31 3C7F -8231CB32 3C80 -8231CB33 3C81 -8231CB34 3C82 -8231CB35 3C83 -8231CB36 3C84 -8231CB37 3C85 -8231CB38 3C86 -8231CB39 3C87 -8231CC30 3C88 -8231CC31 3C89 -8231CC32 3C8A -8231CC33 3C8B -8231CC34 3C8C -8231CC35 3C8D -8231CC36 3C8E -8231CC37 3C8F -8231CC38 3C90 -8231CC39 3C91 -8231CD30 3C92 -8231CD31 3C93 -8231CD32 3C94 -8231CD33 3C95 -8231CD34 3C96 -8231CD35 3C97 -8231CD36 3C98 -8231CD37 3C99 -8231CD38 3C9A -8231CD39 3C9B -8231CE30 3C9C -8231CE31 3C9D -8231CE32 3C9E -8231CE33 3C9F -8231CE34 3CA0 -8231CE35 3CA1 -8231CE36 3CA2 -8231CE37 3CA3 -8231CE38 3CA4 -8231CE39 3CA5 -8231CF30 3CA6 -8231CF31 3CA7 -8231CF32 3CA8 -8231CF33 3CA9 -8231CF34 3CAA -8231CF35 3CAB -8231CF36 3CAC -8231CF37 3CAD -8231CF38 3CAE -8231CF39 3CAF -8231D030 3CB0 -8231D031 3CB1 -8231D032 3CB2 -8231D033 3CB3 -8231D034 3CB4 -8231D035 3CB5 -8231D036 3CB6 -8231D037 3CB7 -8231D038 3CB8 -8231D039 3CB9 -8231D130 3CBA -8231D131 3CBB -8231D132 3CBC -8231D133 3CBD -8231D134 3CBE -8231D135 3CBF -8231D136 3CC0 -8231D137 3CC1 -8231D138 3CC2 -8231D139 3CC3 -8231D230 3CC4 -8231D231 3CC5 -8231D232 3CC6 -8231D233 3CC7 -8231D234 3CC8 -8231D235 3CC9 -8231D236 3CCA -8231D237 3CCB -8231D238 3CCC -8231D239 3CCD -8231D330 3CCE -8231D331 3CCF -8231D332 3CD0 -8231D333 3CD1 -8231D334 3CD2 -8231D335 3CD3 -8231D336 3CD4 -8231D337 3CD5 -8231D338 3CD6 -8231D339 3CD7 -8231D430 3CD8 -8231D431 3CD9 -8231D432 3CDA -8231D433 3CDB -8231D434 3CDC -8231D435 3CDD -8231D436 3CDE -8231D437 3CDF -FE6A 3CE0 -8231D438 3CE1 -8231D439 3CE2 -8231D530 3CE3 -8231D531 3CE4 -8231D532 3CE5 -8231D533 3CE6 -8231D534 3CE7 -8231D535 3CE8 -8231D536 3CE9 -8231D537 3CEA -8231D538 3CEB -8231D539 3CEC -8231D630 3CED -8231D631 3CEE -8231D632 3CEF -8231D633 3CF0 -8231D634 3CF1 -8231D635 3CF2 -8231D636 3CF3 -8231D637 3CF4 -8231D638 3CF5 -8231D639 3CF6 -8231D730 3CF7 -8231D731 3CF8 -8231D732 3CF9 -8231D733 3CFA -8231D734 3CFB -8231D735 3CFC -8231D736 3CFD -8231D737 3CFE -8231D738 3CFF -8231D739 3D00 -8231D830 3D01 -8231D831 3D02 -8231D832 3D03 -8231D833 3D04 -8231D834 3D05 -8231D835 3D06 -8231D836 3D07 -8231D837 3D08 -8231D838 3D09 -8231D839 3D0A -8231D930 3D0B -8231D931 3D0C -8231D932 3D0D -8231D933 3D0E -8231D934 3D0F -8231D935 3D10 -8231D936 3D11 -8231D937 3D12 -8231D938 3D13 -8231D939 3D14 -8231DA30 3D15 -8231DA31 3D16 -8231DA32 3D17 -8231DA33 3D18 -8231DA34 3D19 -8231DA35 3D1A -8231DA36 3D1B -8231DA37 3D1C -8231DA38 3D1D -8231DA39 3D1E -8231DB30 3D1F -8231DB31 3D20 -8231DB32 3D21 -8231DB33 3D22 -8231DB34 3D23 -8231DB35 3D24 -8231DB36 3D25 -8231DB37 3D26 -8231DB38 3D27 -8231DB39 3D28 -8231DC30 3D29 -8231DC31 3D2A -8231DC32 3D2B -8231DC33 3D2C -8231DC34 3D2D -8231DC35 3D2E -8231DC36 3D2F -8231DC37 3D30 -8231DC38 3D31 -8231DC39 3D32 -8231DD30 3D33 -8231DD31 3D34 -8231DD32 3D35 -8231DD33 3D36 -8231DD34 3D37 -8231DD35 3D38 -8231DD36 3D39 -8231DD37 3D3A -8231DD38 3D3B -8231DD39 3D3C -8231DE30 3D3D -8231DE31 3D3E -8231DE32 3D3F -8231DE33 3D40 -8231DE34 3D41 -8231DE35 3D42 -8231DE36 3D43 -8231DE37 3D44 -8231DE38 3D45 -8231DE39 3D46 -8231DF30 3D47 -8231DF31 3D48 -8231DF32 3D49 -8231DF33 3D4A -8231DF34 3D4B -8231DF35 3D4C -8231DF36 3D4D -8231DF37 3D4E -8231DF38 3D4F -8231DF39 3D50 -8231E030 3D51 -8231E031 3D52 -8231E032 3D53 -8231E033 3D54 -8231E034 3D55 -8231E035 3D56 -8231E036 3D57 -8231E037 3D58 -8231E038 3D59 -8231E039 3D5A -8231E130 3D5B -8231E131 3D5C -8231E132 3D5D -8231E133 3D5E -8231E134 3D5F -8231E135 3D60 -8231E136 3D61 -8231E137 3D62 -8231E138 3D63 -8231E139 3D64 -8231E230 3D65 -8231E231 3D66 -8231E232 3D67 -8231E233 3D68 -8231E234 3D69 -8231E235 3D6A -8231E236 3D6B -8231E237 3D6C -8231E238 3D6D -8231E239 3D6E -8231E330 3D6F -8231E331 3D70 -8231E332 3D71 -8231E333 3D72 -8231E334 3D73 -8231E335 3D74 -8231E336 3D75 -8231E337 3D76 -8231E338 3D77 -8231E339 3D78 -8231E430 3D79 -8231E431 3D7A -8231E432 3D7B -8231E433 3D7C -8231E434 3D7D -8231E435 3D7E -8231E436 3D7F -8231E437 3D80 -8231E438 3D81 -8231E439 3D82 -8231E530 3D83 -8231E531 3D84 -8231E532 3D85 -8231E533 3D86 -8231E534 3D87 -8231E535 3D88 -8231E536 3D89 -8231E537 3D8A -8231E538 3D8B -8231E539 3D8C -8231E630 3D8D -8231E631 3D8E -8231E632 3D8F -8231E633 3D90 -8231E634 3D91 -8231E635 3D92 -8231E636 3D93 -8231E637 3D94 -8231E638 3D95 -8231E639 3D96 -8231E730 3D97 -8231E731 3D98 -8231E732 3D99 -8231E733 3D9A -8231E734 3D9B -8231E735 3D9C -8231E736 3D9D -8231E737 3D9E -8231E738 3D9F -8231E739 3DA0 -8231E830 3DA1 -8231E831 3DA2 -8231E832 3DA3 -8231E833 3DA4 -8231E834 3DA5 -8231E835 3DA6 -8231E836 3DA7 -8231E837 3DA8 -8231E838 3DA9 -8231E839 3DAA -8231E930 3DAB -8231E931 3DAC -8231E932 3DAD -8231E933 3DAE -8231E934 3DAF -8231E935 3DB0 -8231E936 3DB1 -8231E937 3DB2 -8231E938 3DB3 -8231E939 3DB4 -8231EA30 3DB5 -8231EA31 3DB6 -8231EA32 3DB7 -8231EA33 3DB8 -8231EA34 3DB9 -8231EA35 3DBA -8231EA36 3DBB -8231EA37 3DBC -8231EA38 3DBD -8231EA39 3DBE -8231EB30 3DBF -8231EB31 3DC0 -8231EB32 3DC1 -8231EB33 3DC2 -8231EB34 3DC3 -8231EB35 3DC4 -8231EB36 3DC5 -8231EB37 3DC6 -8231EB38 3DC7 -8231EB39 3DC8 -8231EC30 3DC9 -8231EC31 3DCA -8231EC32 3DCB -8231EC33 3DCC -8231EC34 3DCD -8231EC35 3DCE -8231EC36 3DCF -8231EC37 3DD0 -8231EC38 3DD1 -8231EC39 3DD2 -8231ED30 3DD3 -8231ED31 3DD4 -8231ED32 3DD5 -8231ED33 3DD6 -8231ED34 3DD7 -8231ED35 3DD8 -8231ED36 3DD9 -8231ED37 3DDA -8231ED38 3DDB -8231ED39 3DDC -8231EE30 3DDD -8231EE31 3DDE -8231EE32 3DDF -8231EE33 3DE0 -8231EE34 3DE1 -8231EE35 3DE2 -8231EE36 3DE3 -8231EE37 3DE4 -8231EE38 3DE5 -8231EE39 3DE6 -8231EF30 3DE7 -8231EF31 3DE8 -8231EF32 3DE9 -8231EF33 3DEA -8231EF34 3DEB -8231EF35 3DEC -8231EF36 3DED -8231EF37 3DEE -8231EF38 3DEF -8231EF39 3DF0 -8231F030 3DF1 -8231F031 3DF2 -8231F032 3DF3 -8231F033 3DF4 -8231F034 3DF5 -8231F035 3DF6 -8231F036 3DF7 -8231F037 3DF8 -8231F038 3DF9 -8231F039 3DFA -8231F130 3DFB -8231F131 3DFC -8231F132 3DFD -8231F133 3DFE -8231F134 3DFF -8231F135 3E00 -8231F136 3E01 -8231F137 3E02 -8231F138 3E03 -8231F139 3E04 -8231F230 3E05 -8231F231 3E06 -8231F232 3E07 -8231F233 3E08 -8231F234 3E09 -8231F235 3E0A -8231F236 3E0B -8231F237 3E0C -8231F238 3E0D -8231F239 3E0E -8231F330 3E0F -8231F331 3E10 -8231F332 3E11 -8231F333 3E12 -8231F334 3E13 -8231F335 3E14 -8231F336 3E15 -8231F337 3E16 -8231F338 3E17 -8231F339 3E18 -8231F430 3E19 -8231F431 3E1A -8231F432 3E1B -8231F433 3E1C -8231F434 3E1D -8231F435 3E1E -8231F436 3E1F -8231F437 3E20 -8231F438 3E21 -8231F439 3E22 -8231F530 3E23 -8231F531 3E24 -8231F532 3E25 -8231F533 3E26 -8231F534 3E27 -8231F535 3E28 -8231F536 3E29 -8231F537 3E2A -8231F538 3E2B -8231F539 3E2C -8231F630 3E2D -8231F631 3E2E -8231F632 3E2F -8231F633 3E30 -8231F634 3E31 -8231F635 3E32 -8231F636 3E33 -8231F637 3E34 -8231F638 3E35 -8231F639 3E36 -8231F730 3E37 -8231F731 3E38 -8231F732 3E39 -8231F733 3E3A -8231F734 3E3B -8231F735 3E3C -8231F736 3E3D -8231F737 3E3E -8231F738 3E3F -8231F739 3E40 -8231F830 3E41 -8231F831 3E42 -8231F832 3E43 -8231F833 3E44 -8231F834 3E45 -8231F835 3E46 -8231F836 3E47 -8231F837 3E48 -8231F838 3E49 -8231F839 3E4A -8231F930 3E4B -8231F931 3E4C -8231F932 3E4D -8231F933 3E4E -8231F934 3E4F -8231F935 3E50 -8231F936 3E51 -8231F937 3E52 -8231F938 3E53 -8231F939 3E54 -8231FA30 3E55 -8231FA31 3E56 -8231FA32 3E57 -8231FA33 3E58 -8231FA34 3E59 -8231FA35 3E5A -8231FA36 3E5B -8231FA37 3E5C -8231FA38 3E5D -8231FA39 3E5E -8231FB30 3E5F -8231FB31 3E60 -8231FB32 3E61 -8231FB33 3E62 -8231FB34 3E63 -8231FB35 3E64 -8231FB36 3E65 -8231FB37 3E66 -8231FB38 3E67 -8231FB39 3E68 -8231FC30 3E69 -8231FC31 3E6A -8231FC32 3E6B -8231FC33 3E6C -8231FC34 3E6D -8231FC35 3E6E -8231FC36 3E6F -8231FC37 3E70 -8231FC38 3E71 -8231FC39 3E72 -8231FD30 3E73 -8231FD31 3E74 -8231FD32 3E75 -8231FD33 3E76 -8231FD34 3E77 -8231FD35 3E78 -8231FD36 3E79 -8231FD37 3E7A -8231FD38 3E7B -8231FD39 3E7C -8231FE30 3E7D -8231FE31 3E7E -8231FE32 3E7F -8231FE33 3E80 -8231FE34 3E81 -8231FE35 3E82 -8231FE36 3E83 -8231FE37 3E84 -8231FE38 3E85 -8231FE39 3E86 -82328130 3E87 -82328131 3E88 -82328132 3E89 -82328133 3E8A -82328134 3E8B -82328135 3E8C -82328136 3E8D -82328137 3E8E -82328138 3E8F -82328139 3E90 -82328230 3E91 -82328231 3E92 -82328232 3E93 -82328233 3E94 -82328234 3E95 -82328235 3E96 -82328236 3E97 -82328237 3E98 -82328238 3E99 -82328239 3E9A -82328330 3E9B -82328331 3E9C -82328332 3E9D -82328333 3E9E -82328334 3E9F -82328335 3EA0 -82328336 3EA1 -82328337 3EA2 -82328338 3EA3 -82328339 3EA4 -82328430 3EA5 -82328431 3EA6 -82328432 3EA7 -82328433 3EA8 -82328434 3EA9 -82328435 3EAA -82328436 3EAB -82328437 3EAC -82328438 3EAD -82328439 3EAE -82328530 3EAF -82328531 3EB0 -82328532 3EB1 -82328533 3EB2 -82328534 3EB3 -82328535 3EB4 -82328536 3EB5 -82328537 3EB6 -82328538 3EB7 -82328539 3EB8 -82328630 3EB9 -82328631 3EBA -82328632 3EBB -82328633 3EBC -82328634 3EBD -82328635 3EBE -82328636 3EBF -82328637 3EC0 -82328638 3EC1 -82328639 3EC2 -82328730 3EC3 -82328731 3EC4 -82328732 3EC5 -82328733 3EC6 -82328734 3EC7 -82328735 3EC8 -82328736 3EC9 -82328737 3ECA -82328738 3ECB -82328739 3ECC -82328830 3ECD -82328831 3ECE -82328832 3ECF -82328833 3ED0 -82328834 3ED1 -82328835 3ED2 -82328836 3ED3 -82328837 3ED4 -82328838 3ED5 -82328839 3ED6 -82328930 3ED7 -82328931 3ED8 -82328932 3ED9 -82328933 3EDA -82328934 3EDB -82328935 3EDC -82328936 3EDD -82328937 3EDE -82328938 3EDF -82328939 3EE0 -82328A30 3EE1 -82328A31 3EE2 -82328A32 3EE3 -82328A33 3EE4 -82328A34 3EE5 -82328A35 3EE6 -82328A36 3EE7 -82328A37 3EE8 -82328A38 3EE9 -82328A39 3EEA -82328B30 3EEB -82328B31 3EEC -82328B32 3EED -82328B33 3EEE -82328B34 3EEF -82328B35 3EF0 -82328B36 3EF1 -82328B37 3EF2 -82328B38 3EF3 -82328B39 3EF4 -82328C30 3EF5 -82328C31 3EF6 -82328C32 3EF7 -82328C33 3EF8 -82328C34 3EF9 -82328C35 3EFA -82328C36 3EFB -82328C37 3EFC -82328C38 3EFD -82328C39 3EFE -82328D30 3EFF -82328D31 3F00 -82328D32 3F01 -82328D33 3F02 -82328D34 3F03 -82328D35 3F04 -82328D36 3F05 -82328D37 3F06 -82328D38 3F07 -82328D39 3F08 -82328E30 3F09 -82328E31 3F0A -82328E32 3F0B -82328E33 3F0C -82328E34 3F0D -82328E35 3F0E -82328E36 3F0F -82328E37 3F10 -82328E38 3F11 -82328E39 3F12 -82328F30 3F13 -82328F31 3F14 -82328F32 3F15 -82328F33 3F16 -82328F34 3F17 -82328F35 3F18 -82328F36 3F19 -82328F37 3F1A -82328F38 3F1B -82328F39 3F1C -82329030 3F1D -82329031 3F1E -82329032 3F1F -82329033 3F20 -82329034 3F21 -82329035 3F22 -82329036 3F23 -82329037 3F24 -82329038 3F25 -82329039 3F26 -82329130 3F27 -82329131 3F28 -82329132 3F29 -82329133 3F2A -82329134 3F2B -82329135 3F2C -82329136 3F2D -82329137 3F2E -82329138 3F2F -82329139 3F30 -82329230 3F31 -82329231 3F32 -82329232 3F33 -82329233 3F34 -82329234 3F35 -82329235 3F36 -82329236 3F37 -82329237 3F38 -82329238 3F39 -82329239 3F3A -82329330 3F3B -82329331 3F3C -82329332 3F3D -82329333 3F3E -82329334 3F3F -82329335 3F40 -82329336 3F41 -82329337 3F42 -82329338 3F43 -82329339 3F44 -82329430 3F45 -82329431 3F46 -82329432 3F47 -82329433 3F48 -82329434 3F49 -82329435 3F4A -82329436 3F4B -82329437 3F4C -82329438 3F4D -82329439 3F4E -82329530 3F4F -82329531 3F50 -82329532 3F51 -82329533 3F52 -82329534 3F53 -82329535 3F54 -82329536 3F55 -82329537 3F56 -82329538 3F57 -82329539 3F58 -82329630 3F59 -82329631 3F5A -82329632 3F5B -82329633 3F5C -82329634 3F5D -82329635 3F5E -82329636 3F5F -82329637 3F60 -82329638 3F61 -82329639 3F62 -82329730 3F63 -82329731 3F64 -82329732 3F65 -82329733 3F66 -82329734 3F67 -82329735 3F68 -82329736 3F69 -82329737 3F6A -82329738 3F6B -82329739 3F6C -82329830 3F6D -82329831 3F6E -82329832 3F6F -82329833 3F70 -82329834 3F71 -82329835 3F72 -82329836 3F73 -82329837 3F74 -82329838 3F75 -82329839 3F76 -82329930 3F77 -82329931 3F78 -82329932 3F79 -82329933 3F7A -82329934 3F7B -82329935 3F7C -82329936 3F7D -82329937 3F7E -82329938 3F7F -82329939 3F80 -82329A30 3F81 -82329A31 3F82 -82329A32 3F83 -82329A33 3F84 -82329A34 3F85 -82329A35 3F86 -82329A36 3F87 -82329A37 3F88 -82329A38 3F89 -82329A39 3F8A -82329B30 3F8B -82329B31 3F8C -82329B32 3F8D -82329B33 3F8E -82329B34 3F8F -82329B35 3F90 -82329B36 3F91 -82329B37 3F92 -82329B38 3F93 -82329B39 3F94 -82329C30 3F95 -82329C31 3F96 -82329C32 3F97 -82329C33 3F98 -82329C34 3F99 -82329C35 3F9A -82329C36 3F9B -82329C37 3F9C -82329C38 3F9D -82329C39 3F9E -82329D30 3F9F -82329D31 3FA0 -82329D32 3FA1 -82329D33 3FA2 -82329D34 3FA3 -82329D35 3FA4 -82329D36 3FA5 -82329D37 3FA6 -82329D38 3FA7 -82329D39 3FA8 -82329E30 3FA9 -82329E31 3FAA -82329E32 3FAB -82329E33 3FAC -82329E34 3FAD -82329E35 3FAE -82329E36 3FAF -82329E37 3FB0 -82329E38 3FB1 -82329E39 3FB2 -82329F30 3FB3 -82329F31 3FB4 -82329F32 3FB5 -82329F33 3FB6 -82329F34 3FB7 -82329F35 3FB8 -82329F36 3FB9 -82329F37 3FBA -82329F38 3FBB -82329F39 3FBC -8232A030 3FBD -8232A031 3FBE -8232A032 3FBF -8232A033 3FC0 -8232A034 3FC1 -8232A035 3FC2 -8232A036 3FC3 -8232A037 3FC4 -8232A038 3FC5 -8232A039 3FC6 -8232A130 3FC7 -8232A131 3FC8 -8232A132 3FC9 -8232A133 3FCA -8232A134 3FCB -8232A135 3FCC -8232A136 3FCD -8232A137 3FCE -8232A138 3FCF -8232A139 3FD0 -8232A230 3FD1 -8232A231 3FD2 -8232A232 3FD3 -8232A233 3FD4 -8232A234 3FD5 -8232A235 3FD6 -8232A236 3FD7 -8232A237 3FD8 -8232A238 3FD9 -8232A239 3FDA -8232A330 3FDB -8232A331 3FDC -8232A332 3FDD -8232A333 3FDE -8232A334 3FDF -8232A335 3FE0 -8232A336 3FE1 -8232A337 3FE2 -8232A338 3FE3 -8232A339 3FE4 -8232A430 3FE5 -8232A431 3FE6 -8232A432 3FE7 -8232A433 3FE8 -8232A434 3FE9 -8232A435 3FEA -8232A436 3FEB -8232A437 3FEC -8232A438 3FED -8232A439 3FEE -8232A530 3FEF -8232A531 3FF0 -8232A532 3FF1 -8232A533 3FF2 -8232A534 3FF3 -8232A535 3FF4 -8232A536 3FF5 -8232A537 3FF6 -8232A538 3FF7 -8232A539 3FF8 -8232A630 3FF9 -8232A631 3FFA -8232A632 3FFB -8232A633 3FFC -8232A634 3FFD -8232A635 3FFE -8232A636 3FFF -8232A637 4000 -8232A638 4001 -8232A639 4002 -8232A730 4003 -8232A731 4004 -8232A732 4005 -8232A733 4006 -8232A734 4007 -8232A735 4008 -8232A736 4009 -8232A737 400A -8232A738 400B -8232A739 400C -8232A830 400D -8232A831 400E -8232A832 400F -8232A833 4010 -8232A834 4011 -8232A835 4012 -8232A836 4013 -8232A837 4014 -8232A838 4015 -8232A839 4016 -8232A930 4017 -8232A931 4018 -8232A932 4019 -8232A933 401A -8232A934 401B -8232A935 401C -8232A936 401D -8232A937 401E -8232A938 401F -8232A939 4020 -8232AA30 4021 -8232AA31 4022 -8232AA32 4023 -8232AA33 4024 -8232AA34 4025 -8232AA35 4026 -8232AA36 4027 -8232AA37 4028 -8232AA38 4029 -8232AA39 402A -8232AB30 402B -8232AB31 402C -8232AB32 402D -8232AB33 402E -8232AB34 402F -8232AB35 4030 -8232AB36 4031 -8232AB37 4032 -8232AB38 4033 -8232AB39 4034 -8232AC30 4035 -8232AC31 4036 -8232AC32 4037 -8232AC33 4038 -8232AC34 4039 -8232AC35 403A -8232AC36 403B -8232AC37 403C -8232AC38 403D -8232AC39 403E -8232AD30 403F -8232AD31 4040 -8232AD32 4041 -8232AD33 4042 -8232AD34 4043 -8232AD35 4044 -8232AD36 4045 -8232AD37 4046 -8232AD38 4047 -8232AD39 4048 -8232AE30 4049 -8232AE31 404A -8232AE32 404B -8232AE33 404C -8232AE34 404D -8232AE35 404E -8232AE36 404F -8232AE37 4050 -8232AE38 4051 -8232AE39 4052 -8232AF30 4053 -8232AF31 4054 -8232AF32 4055 -FE6F 4056 -8232AF33 4057 -8232AF34 4058 -8232AF35 4059 -8232AF36 405A -8232AF37 405B -8232AF38 405C -8232AF39 405D -8232B030 405E -8232B031 405F -8232B032 4060 -8232B033 4061 -8232B034 4062 -8232B035 4063 -8232B036 4064 -8232B037 4065 -8232B038 4066 -8232B039 4067 -8232B130 4068 -8232B131 4069 -8232B132 406A -8232B133 406B -8232B134 406C -8232B135 406D -8232B136 406E -8232B137 406F -8232B138 4070 -8232B139 4071 -8232B230 4072 -8232B231 4073 -8232B232 4074 -8232B233 4075 -8232B234 4076 -8232B235 4077 -8232B236 4078 -8232B237 4079 -8232B238 407A -8232B239 407B -8232B330 407C -8232B331 407D -8232B332 407E -8232B333 407F -8232B334 4080 -8232B335 4081 -8232B336 4082 -8232B337 4083 -8232B338 4084 -8232B339 4085 -8232B430 4086 -8232B431 4087 -8232B432 4088 -8232B433 4089 -8232B434 408A -8232B435 408B -8232B436 408C -8232B437 408D -8232B438 408E -8232B439 408F -8232B530 4090 -8232B531 4091 -8232B532 4092 -8232B533 4093 -8232B534 4094 -8232B535 4095 -8232B536 4096 -8232B537 4097 -8232B538 4098 -8232B539 4099 -8232B630 409A -8232B631 409B -8232B632 409C -8232B633 409D -8232B634 409E -8232B635 409F -8232B636 40A0 -8232B637 40A1 -8232B638 40A2 -8232B639 40A3 -8232B730 40A4 -8232B731 40A5 -8232B732 40A6 -8232B733 40A7 -8232B734 40A8 -8232B735 40A9 -8232B736 40AA -8232B737 40AB -8232B738 40AC -8232B739 40AD -8232B830 40AE -8232B831 40AF -8232B832 40B0 -8232B833 40B1 -8232B834 40B2 -8232B835 40B3 -8232B836 40B4 -8232B837 40B5 -8232B838 40B6 -8232B839 40B7 -8232B930 40B8 -8232B931 40B9 -8232B932 40BA -8232B933 40BB -8232B934 40BC -8232B935 40BD -8232B936 40BE -8232B937 40BF -8232B938 40C0 -8232B939 40C1 -8232BA30 40C2 -8232BA31 40C3 -8232BA32 40C4 -8232BA33 40C5 -8232BA34 40C6 -8232BA35 40C7 -8232BA36 40C8 -8232BA37 40C9 -8232BA38 40CA -8232BA39 40CB -8232BB30 40CC -8232BB31 40CD -8232BB32 40CE -8232BB33 40CF -8232BB34 40D0 -8232BB35 40D1 -8232BB36 40D2 -8232BB37 40D3 -8232BB38 40D4 -8232BB39 40D5 -8232BC30 40D6 -8232BC31 40D7 -8232BC32 40D8 -8232BC33 40D9 -8232BC34 40DA -8232BC35 40DB -8232BC36 40DC -8232BC37 40DD -8232BC38 40DE -8232BC39 40DF -8232BD30 40E0 -8232BD31 40E1 -8232BD32 40E2 -8232BD33 40E3 -8232BD34 40E4 -8232BD35 40E5 -8232BD36 40E6 -8232BD37 40E7 -8232BD38 40E8 -8232BD39 40E9 -8232BE30 40EA -8232BE31 40EB -8232BE32 40EC -8232BE33 40ED -8232BE34 40EE -8232BE35 40EF -8232BE36 40F0 -8232BE37 40F1 -8232BE38 40F2 -8232BE39 40F3 -8232BF30 40F4 -8232BF31 40F5 -8232BF32 40F6 -8232BF33 40F7 -8232BF34 40F8 -8232BF35 40F9 -8232BF36 40FA -8232BF37 40FB -8232BF38 40FC -8232BF39 40FD -8232C030 40FE -8232C031 40FF -8232C032 4100 -8232C033 4101 -8232C034 4102 -8232C035 4103 -8232C036 4104 -8232C037 4105 -8232C038 4106 -8232C039 4107 -8232C130 4108 -8232C131 4109 -8232C132 410A -8232C133 410B -8232C134 410C -8232C135 410D -8232C136 410E -8232C137 410F -8232C138 4110 -8232C139 4111 -8232C230 4112 -8232C231 4113 -8232C232 4114 -8232C233 4115 -8232C234 4116 -8232C235 4117 -8232C236 4118 -8232C237 4119 -8232C238 411A -8232C239 411B -8232C330 411C -8232C331 411D -8232C332 411E -8232C333 411F -8232C334 4120 -8232C335 4121 -8232C336 4122 -8232C337 4123 -8232C338 4124 -8232C339 4125 -8232C430 4126 -8232C431 4127 -8232C432 4128 -8232C433 4129 -8232C434 412A -8232C435 412B -8232C436 412C -8232C437 412D -8232C438 412E -8232C439 412F -8232C530 4130 -8232C531 4131 -8232C532 4132 -8232C533 4133 -8232C534 4134 -8232C535 4135 -8232C536 4136 -8232C537 4137 -8232C538 4138 -8232C539 4139 -8232C630 413A -8232C631 413B -8232C632 413C -8232C633 413D -8232C634 413E -8232C635 413F -8232C636 4140 -8232C637 4141 -8232C638 4142 -8232C639 4143 -8232C730 4144 -8232C731 4145 -8232C732 4146 -8232C733 4147 -8232C734 4148 -8232C735 4149 -8232C736 414A -8232C737 414B -8232C738 414C -8232C739 414D -8232C830 414E -8232C831 414F -8232C832 4150 -8232C833 4151 -8232C834 4152 -8232C835 4153 -8232C836 4154 -8232C837 4155 -8232C838 4156 -8232C839 4157 -8232C930 4158 -8232C931 4159 -8232C932 415A -8232C933 415B -8232C934 415C -8232C935 415D -8232C936 415E -FE70 415F -8232C937 4160 -8232C938 4161 -8232C939 4162 -8232CA30 4163 -8232CA31 4164 -8232CA32 4165 -8232CA33 4166 -8232CA34 4167 -8232CA35 4168 -8232CA36 4169 -8232CA37 416A -8232CA38 416B -8232CA39 416C -8232CB30 416D -8232CB31 416E -8232CB32 416F -8232CB33 4170 -8232CB34 4171 -8232CB35 4172 -8232CB36 4173 -8232CB37 4174 -8232CB38 4175 -8232CB39 4176 -8232CC30 4177 -8232CC31 4178 -8232CC32 4179 -8232CC33 417A -8232CC34 417B -8232CC35 417C -8232CC36 417D -8232CC37 417E -8232CC38 417F -8232CC39 4180 -8232CD30 4181 -8232CD31 4182 -8232CD32 4183 -8232CD33 4184 -8232CD34 4185 -8232CD35 4186 -8232CD36 4187 -8232CD37 4188 -8232CD38 4189 -8232CD39 418A -8232CE30 418B -8232CE31 418C -8232CE32 418D -8232CE33 418E -8232CE34 418F -8232CE35 4190 -8232CE36 4191 -8232CE37 4192 -8232CE38 4193 -8232CE39 4194 -8232CF30 4195 -8232CF31 4196 -8232CF32 4197 -8232CF33 4198 -8232CF34 4199 -8232CF35 419A -8232CF36 419B -8232CF37 419C -8232CF38 419D -8232CF39 419E -8232D030 419F -8232D031 41A0 -8232D032 41A1 -8232D033 41A2 -8232D034 41A3 -8232D035 41A4 -8232D036 41A5 -8232D037 41A6 -8232D038 41A7 -8232D039 41A8 -8232D130 41A9 -8232D131 41AA -8232D132 41AB -8232D133 41AC -8232D134 41AD -8232D135 41AE -8232D136 41AF -8232D137 41B0 -8232D138 41B1 -8232D139 41B2 -8232D230 41B3 -8232D231 41B4 -8232D232 41B5 -8232D233 41B6 -8232D234 41B7 -8232D235 41B8 -8232D236 41B9 -8232D237 41BA -8232D238 41BB -8232D239 41BC -8232D330 41BD -8232D331 41BE -8232D332 41BF -8232D333 41C0 -8232D334 41C1 -8232D335 41C2 -8232D336 41C3 -8232D337 41C4 -8232D338 41C5 -8232D339 41C6 -8232D430 41C7 -8232D431 41C8 -8232D432 41C9 -8232D433 41CA -8232D434 41CB -8232D435 41CC -8232D436 41CD -8232D437 41CE -8232D438 41CF -8232D439 41D0 -8232D530 41D1 -8232D531 41D2 -8232D532 41D3 -8232D533 41D4 -8232D534 41D5 -8232D535 41D6 -8232D536 41D7 -8232D537 41D8 -8232D538 41D9 -8232D539 41DA -8232D630 41DB -8232D631 41DC -8232D632 41DD -8232D633 41DE -8232D634 41DF -8232D635 41E0 -8232D636 41E1 -8232D637 41E2 -8232D638 41E3 -8232D639 41E4 -8232D730 41E5 -8232D731 41E6 -8232D732 41E7 -8232D733 41E8 -8232D734 41E9 -8232D735 41EA -8232D736 41EB -8232D737 41EC -8232D738 41ED -8232D739 41EE -8232D830 41EF -8232D831 41F0 -8232D832 41F1 -8232D833 41F2 -8232D834 41F3 -8232D835 41F4 -8232D836 41F5 -8232D837 41F6 -8232D838 41F7 -8232D839 41F8 -8232D930 41F9 -8232D931 41FA -8232D932 41FB -8232D933 41FC -8232D934 41FD -8232D935 41FE -8232D936 41FF -8232D937 4200 -8232D938 4201 -8232D939 4202 -8232DA30 4203 -8232DA31 4204 -8232DA32 4205 -8232DA33 4206 -8232DA34 4207 -8232DA35 4208 -8232DA36 4209 -8232DA37 420A -8232DA38 420B -8232DA39 420C -8232DB30 420D -8232DB31 420E -8232DB32 420F -8232DB33 4210 -8232DB34 4211 -8232DB35 4212 -8232DB36 4213 -8232DB37 4214 -8232DB38 4215 -8232DB39 4216 -8232DC30 4217 -8232DC31 4218 -8232DC32 4219 -8232DC33 421A -8232DC34 421B -8232DC35 421C -8232DC36 421D -8232DC37 421E -8232DC38 421F -8232DC39 4220 -8232DD30 4221 -8232DD31 4222 -8232DD32 4223 -8232DD33 4224 -8232DD34 4225 -8232DD35 4226 -8232DD36 4227 -8232DD37 4228 -8232DD38 4229 -8232DD39 422A -8232DE30 422B -8232DE31 422C -8232DE32 422D -8232DE33 422E -8232DE34 422F -8232DE35 4230 -8232DE36 4231 -8232DE37 4232 -8232DE38 4233 -8232DE39 4234 -8232DF30 4235 -8232DF31 4236 -8232DF32 4237 -8232DF33 4238 -8232DF34 4239 -8232DF35 423A -8232DF36 423B -8232DF37 423C -8232DF38 423D -8232DF39 423E -8232E030 423F -8232E031 4240 -8232E032 4241 -8232E033 4242 -8232E034 4243 -8232E035 4244 -8232E036 4245 -8232E037 4246 -8232E038 4247 -8232E039 4248 -8232E130 4249 -8232E131 424A -8232E132 424B -8232E133 424C -8232E134 424D -8232E135 424E -8232E136 424F -8232E137 4250 -8232E138 4251 -8232E139 4252 -8232E230 4253 -8232E231 4254 -8232E232 4255 -8232E233 4256 -8232E234 4257 -8232E235 4258 -8232E236 4259 -8232E237 425A -8232E238 425B -8232E239 425C -8232E330 425D -8232E331 425E -8232E332 425F -8232E333 4260 -8232E334 4261 -8232E335 4262 -8232E336 4263 -8232E337 4264 -8232E338 4265 -8232E339 4266 -8232E430 4267 -8232E431 4268 -8232E432 4269 -8232E433 426A -8232E434 426B -8232E435 426C -8232E436 426D -8232E437 426E -8232E438 426F -8232E439 4270 -8232E530 4271 -8232E531 4272 -8232E532 4273 -8232E533 4274 -8232E534 4275 -8232E535 4276 -8232E536 4277 -8232E537 4278 -8232E538 4279 -8232E539 427A -8232E630 427B -8232E631 427C -8232E632 427D -8232E633 427E -8232E634 427F -8232E635 4280 -8232E636 4281 -8232E637 4282 -8232E638 4283 -8232E639 4284 -8232E730 4285 -8232E731 4286 -8232E732 4287 -8232E733 4288 -8232E734 4289 -8232E735 428A -8232E736 428B -8232E737 428C -8232E738 428D -8232E739 428E -8232E830 428F -8232E831 4290 -8232E832 4291 -8232E833 4292 -8232E834 4293 -8232E835 4294 -8232E836 4295 -8232E837 4296 -8232E838 4297 -8232E839 4298 -8232E930 4299 -8232E931 429A -8232E932 429B -8232E933 429C -8232E934 429D -8232E935 429E -8232E936 429F -8232E937 42A0 -8232E938 42A1 -8232E939 42A2 -8232EA30 42A3 -8232EA31 42A4 -8232EA32 42A5 -8232EA33 42A6 -8232EA34 42A7 -8232EA35 42A8 -8232EA36 42A9 -8232EA37 42AA -8232EA38 42AB -8232EA39 42AC -8232EB30 42AD -8232EB31 42AE -8232EB32 42AF -8232EB33 42B0 -8232EB34 42B1 -8232EB35 42B2 -8232EB36 42B3 -8232EB37 42B4 -8232EB38 42B5 -8232EB39 42B6 -8232EC30 42B7 -8232EC31 42B8 -8232EC32 42B9 -8232EC33 42BA -8232EC34 42BB -8232EC35 42BC -8232EC36 42BD -8232EC37 42BE -8232EC38 42BF -8232EC39 42C0 -8232ED30 42C1 -8232ED31 42C2 -8232ED32 42C3 -8232ED33 42C4 -8232ED34 42C5 -8232ED35 42C6 -8232ED36 42C7 -8232ED37 42C8 -8232ED38 42C9 -8232ED39 42CA -8232EE30 42CB -8232EE31 42CC -8232EE32 42CD -8232EE33 42CE -8232EE34 42CF -8232EE35 42D0 -8232EE36 42D1 -8232EE37 42D2 -8232EE38 42D3 -8232EE39 42D4 -8232EF30 42D5 -8232EF31 42D6 -8232EF32 42D7 -8232EF33 42D8 -8232EF34 42D9 -8232EF35 42DA -8232EF36 42DB -8232EF37 42DC -8232EF38 42DD -8232EF39 42DE -8232F030 42DF -8232F031 42E0 -8232F032 42E1 -8232F033 42E2 -8232F034 42E3 -8232F035 42E4 -8232F036 42E5 -8232F037 42E6 -8232F038 42E7 -8232F039 42E8 -8232F130 42E9 -8232F131 42EA -8232F132 42EB -8232F133 42EC -8232F134 42ED -8232F135 42EE -8232F136 42EF -8232F137 42F0 -8232F138 42F1 -8232F139 42F2 -8232F230 42F3 -8232F231 42F4 -8232F232 42F5 -8232F233 42F6 -8232F234 42F7 -8232F235 42F8 -8232F236 42F9 -8232F237 42FA -8232F238 42FB -8232F239 42FC -8232F330 42FD -8232F331 42FE -8232F332 42FF -8232F333 4300 -8232F334 4301 -8232F335 4302 -8232F336 4303 -8232F337 4304 -8232F338 4305 -8232F339 4306 -8232F430 4307 -8232F431 4308 -8232F432 4309 -8232F433 430A -8232F434 430B -8232F435 430C -8232F436 430D -8232F437 430E -8232F438 430F -8232F439 4310 -8232F530 4311 -8232F531 4312 -8232F532 4313 -8232F533 4314 -8232F534 4315 -8232F535 4316 -8232F536 4317 -8232F537 4318 -8232F538 4319 -8232F539 431A -8232F630 431B -8232F631 431C -8232F632 431D -8232F633 431E -8232F634 431F -8232F635 4320 -8232F636 4321 -8232F637 4322 -8232F638 4323 -8232F639 4324 -8232F730 4325 -8232F731 4326 -8232F732 4327 -8232F733 4328 -8232F734 4329 -8232F735 432A -8232F736 432B -8232F737 432C -8232F738 432D -8232F739 432E -8232F830 432F -8232F831 4330 -8232F832 4331 -8232F833 4332 -8232F834 4333 -8232F835 4334 -8232F836 4335 -8232F837 4336 -FE72 4337 -8232F838 4338 -8232F839 4339 -8232F930 433A -8232F931 433B -8232F932 433C -8232F933 433D -8232F934 433E -8232F935 433F -8232F936 4340 -8232F937 4341 -8232F938 4342 -8232F939 4343 -8232FA30 4344 -8232FA31 4345 -8232FA32 4346 -8232FA33 4347 -8232FA34 4348 -8232FA35 4349 -8232FA36 434A -8232FA37 434B -8232FA38 434C -8232FA39 434D -8232FB30 434E -8232FB31 434F -8232FB32 4350 -8232FB33 4351 -8232FB34 4352 -8232FB35 4353 -8232FB36 4354 -8232FB37 4355 -8232FB38 4356 -8232FB39 4357 -8232FC30 4358 -8232FC31 4359 -8232FC32 435A -8232FC33 435B -8232FC34 435C -8232FC35 435D -8232FC36 435E -8232FC37 435F -8232FC38 4360 -8232FC39 4361 -8232FD30 4362 -8232FD31 4363 -8232FD32 4364 -8232FD33 4365 -8232FD34 4366 -8232FD35 4367 -8232FD36 4368 -8232FD37 4369 -8232FD38 436A -8232FD39 436B -8232FE30 436C -8232FE31 436D -8232FE32 436E -8232FE33 436F -8232FE34 4370 -8232FE35 4371 -8232FE36 4372 -8232FE37 4373 -8232FE38 4374 -8232FE39 4375 -82338130 4376 -82338131 4377 -82338132 4378 -82338133 4379 -82338134 437A -82338135 437B -82338136 437C -82338137 437D -82338138 437E -82338139 437F -82338230 4380 -82338231 4381 -82338232 4382 -82338233 4383 -82338234 4384 -82338235 4385 -82338236 4386 -82338237 4387 -82338238 4388 -82338239 4389 -82338330 438A -82338331 438B -82338332 438C -82338333 438D -82338334 438E -82338335 438F -82338336 4390 -82338337 4391 -82338338 4392 -82338339 4393 -82338430 4394 -82338431 4395 -82338432 4396 -82338433 4397 -82338434 4398 -82338435 4399 -82338436 439A -82338437 439B -82338438 439C -82338439 439D -82338530 439E -82338531 439F -82338532 43A0 -82338533 43A1 -82338534 43A2 -82338535 43A3 -82338536 43A4 -82338537 43A5 -82338538 43A6 -82338539 43A7 -82338630 43A8 -82338631 43A9 -82338632 43AA -82338633 43AB -FE78 43AC -82338634 43AD -82338635 43AE -82338636 43AF -82338637 43B0 -FE77 43B1 -82338638 43B2 -82338639 43B3 -82338730 43B4 -82338731 43B5 -82338732 43B6 -82338733 43B7 -82338734 43B8 -82338735 43B9 -82338736 43BA -82338737 43BB -82338738 43BC -82338739 43BD -82338830 43BE -82338831 43BF -82338832 43C0 -82338833 43C1 -82338834 43C2 -82338835 43C3 -82338836 43C4 -82338837 43C5 -82338838 43C6 -82338839 43C7 -82338930 43C8 -82338931 43C9 -82338932 43CA -82338933 43CB -82338934 43CC -82338935 43CD -82338936 43CE -82338937 43CF -82338938 43D0 -82338939 43D1 -82338A30 43D2 -82338A31 43D3 -82338A32 43D4 -82338A33 43D5 -82338A34 43D6 -82338A35 43D7 -82338A36 43D8 -82338A37 43D9 -82338A38 43DA -82338A39 43DB -82338B30 43DC -FE7A 43DD -82338B31 43DE -82338B32 43DF -82338B33 43E0 -82338B34 43E1 -82338B35 43E2 -82338B36 43E3 -82338B37 43E4 -82338B38 43E5 -82338B39 43E6 -82338C30 43E7 -82338C31 43E8 -82338C32 43E9 -82338C33 43EA -82338C34 43EB -82338C35 43EC -82338C36 43ED -82338C37 43EE -82338C38 43EF -82338C39 43F0 -82338D30 43F1 -82338D31 43F2 -82338D32 43F3 -82338D33 43F4 -82338D34 43F5 -82338D35 43F6 -82338D36 43F7 -82338D37 43F8 -82338D38 43F9 -82338D39 43FA -82338E30 43FB -82338E31 43FC -82338E32 43FD -82338E33 43FE -82338E34 43FF -82338E35 4400 -82338E36 4401 -82338E37 4402 -82338E38 4403 -82338E39 4404 -82338F30 4405 -82338F31 4406 -82338F32 4407 -82338F33 4408 -82338F34 4409 -82338F35 440A -82338F36 440B -82338F37 440C -82338F38 440D -82338F39 440E -82339030 440F -82339031 4410 -82339032 4411 -82339033 4412 -82339034 4413 -82339035 4414 -82339036 4415 -82339037 4416 -82339038 4417 -82339039 4418 -82339130 4419 -82339131 441A -82339132 441B -82339133 441C -82339134 441D -82339135 441E -82339136 441F -82339137 4420 -82339138 4421 -82339139 4422 -82339230 4423 -82339231 4424 -82339232 4425 -82339233 4426 -82339234 4427 -82339235 4428 -82339236 4429 -82339237 442A -82339238 442B -82339239 442C -82339330 442D -82339331 442E -82339332 442F -82339333 4430 -82339334 4431 -82339335 4432 -82339336 4433 -82339337 4434 -82339338 4435 -82339339 4436 -82339430 4437 -82339431 4438 -82339432 4439 -82339433 443A -82339434 443B -82339435 443C -82339436 443D -82339437 443E -82339438 443F -82339439 4440 -82339530 4441 -82339531 4442 -82339532 4443 -82339533 4444 -82339534 4445 -82339535 4446 -82339536 4447 -82339537 4448 -82339538 4449 -82339539 444A -82339630 444B -82339631 444C -82339632 444D -82339633 444E -82339634 444F -82339635 4450 -82339636 4451 -82339637 4452 -82339638 4453 -82339639 4454 -82339730 4455 -82339731 4456 -82339732 4457 -82339733 4458 -82339734 4459 -82339735 445A -82339736 445B -82339737 445C -82339738 445D -82339739 445E -82339830 445F -82339831 4460 -82339832 4461 -82339833 4462 -82339834 4463 -82339835 4464 -82339836 4465 -82339837 4466 -82339838 4467 -82339839 4468 -82339930 4469 -82339931 446A -82339932 446B -82339933 446C -82339934 446D -82339935 446E -82339936 446F -82339937 4470 -82339938 4471 -82339939 4472 -82339A30 4473 -82339A31 4474 -82339A32 4475 -82339A33 4476 -82339A34 4477 -82339A35 4478 -82339A36 4479 -82339A37 447A -82339A38 447B -82339A39 447C -82339B30 447D -82339B31 447E -82339B32 447F -82339B33 4480 -82339B34 4481 -82339B35 4482 -82339B36 4483 -82339B37 4484 -82339B38 4485 -82339B39 4486 -82339C30 4487 -82339C31 4488 -82339C32 4489 -82339C33 448A -82339C34 448B -82339C35 448C -82339C36 448D -82339C37 448E -82339C38 448F -82339C39 4490 -82339D30 4491 -82339D31 4492 -82339D32 4493 -82339D33 4494 -82339D34 4495 -82339D35 4496 -82339D36 4497 -82339D37 4498 -82339D38 4499 -82339D39 449A -82339E30 449B -82339E31 449C -82339E32 449D -82339E33 449E -82339E34 449F -82339E35 44A0 -82339E36 44A1 -82339E37 44A2 -82339E38 44A3 -82339E39 44A4 -82339F30 44A5 -82339F31 44A6 -82339F32 44A7 -82339F33 44A8 -82339F34 44A9 -82339F35 44AA -82339F36 44AB -82339F37 44AC -82339F38 44AD -82339F39 44AE -8233A030 44AF -8233A031 44B0 -8233A032 44B1 -8233A033 44B2 -8233A034 44B3 -8233A035 44B4 -8233A036 44B5 -8233A037 44B6 -8233A038 44B7 -8233A039 44B8 -8233A130 44B9 -8233A131 44BA -8233A132 44BB -8233A133 44BC -8233A134 44BD -8233A135 44BE -8233A136 44BF -8233A137 44C0 -8233A138 44C1 -8233A139 44C2 -8233A230 44C3 -8233A231 44C4 -8233A232 44C5 -8233A233 44C6 -8233A234 44C7 -8233A235 44C8 -8233A236 44C9 -8233A237 44CA -8233A238 44CB -8233A239 44CC -8233A330 44CD -8233A331 44CE -8233A332 44CF -8233A333 44D0 -8233A334 44D1 -8233A335 44D2 -8233A336 44D3 -8233A337 44D4 -8233A338 44D5 -FE7B 44D6 -8233A339 44D7 -8233A430 44D8 -8233A431 44D9 -8233A432 44DA -8233A433 44DB -8233A434 44DC -8233A435 44DD -8233A436 44DE -8233A437 44DF -8233A438 44E0 -8233A439 44E1 -8233A530 44E2 -8233A531 44E3 -8233A532 44E4 -8233A533 44E5 -8233A534 44E6 -8233A535 44E7 -8233A536 44E8 -8233A537 44E9 -8233A538 44EA -8233A539 44EB -8233A630 44EC -8233A631 44ED -8233A632 44EE -8233A633 44EF -8233A634 44F0 -8233A635 44F1 -8233A636 44F2 -8233A637 44F3 -8233A638 44F4 -8233A639 44F5 -8233A730 44F6 -8233A731 44F7 -8233A732 44F8 -8233A733 44F9 -8233A734 44FA -8233A735 44FB -8233A736 44FC -8233A737 44FD -8233A738 44FE -8233A739 44FF -8233A830 4500 -8233A831 4501 -8233A832 4502 -8233A833 4503 -8233A834 4504 -8233A835 4505 -8233A836 4506 -8233A837 4507 -8233A838 4508 -8233A839 4509 -8233A930 450A -8233A931 450B -8233A932 450C -8233A933 450D -8233A934 450E -8233A935 450F -8233A936 4510 -8233A937 4511 -8233A938 4512 -8233A939 4513 -8233AA30 4514 -8233AA31 4515 -8233AA32 4516 -8233AA33 4517 -8233AA34 4518 -8233AA35 4519 -8233AA36 451A -8233AA37 451B -8233AA38 451C -8233AA39 451D -8233AB30 451E -8233AB31 451F -8233AB32 4520 -8233AB33 4521 -8233AB34 4522 -8233AB35 4523 -8233AB36 4524 -8233AB37 4525 -8233AB38 4526 -8233AB39 4527 -8233AC30 4528 -8233AC31 4529 -8233AC32 452A -8233AC33 452B -8233AC34 452C -8233AC35 452D -8233AC36 452E -8233AC37 452F -8233AC38 4530 -8233AC39 4531 -8233AD30 4532 -8233AD31 4533 -8233AD32 4534 -8233AD33 4535 -8233AD34 4536 -8233AD35 4537 -8233AD36 4538 -8233AD37 4539 -8233AD38 453A -8233AD39 453B -8233AE30 453C -8233AE31 453D -8233AE32 453E -8233AE33 453F -8233AE34 4540 -8233AE35 4541 -8233AE36 4542 -8233AE37 4543 -8233AE38 4544 -8233AE39 4545 -8233AF30 4546 -8233AF31 4547 -8233AF32 4548 -8233AF33 4549 -8233AF34 454A -8233AF35 454B -8233AF36 454C -8233AF37 454D -8233AF38 454E -8233AF39 454F -8233B030 4550 -8233B031 4551 -8233B032 4552 -8233B033 4553 -8233B034 4554 -8233B035 4555 -8233B036 4556 -8233B037 4557 -8233B038 4558 -8233B039 4559 -8233B130 455A -8233B131 455B -8233B132 455C -8233B133 455D -8233B134 455E -8233B135 455F -8233B136 4560 -8233B137 4561 -8233B138 4562 -8233B139 4563 -8233B230 4564 -8233B231 4565 -8233B232 4566 -8233B233 4567 -8233B234 4568 -8233B235 4569 -8233B236 456A -8233B237 456B -8233B238 456C -8233B239 456D -8233B330 456E -8233B331 456F -8233B332 4570 -8233B333 4571 -8233B334 4572 -8233B335 4573 -8233B336 4574 -8233B337 4575 -8233B338 4576 -8233B339 4577 -8233B430 4578 -8233B431 4579 -8233B432 457A -8233B433 457B -8233B434 457C -8233B435 457D -8233B436 457E -8233B437 457F -8233B438 4580 -8233B439 4581 -8233B530 4582 -8233B531 4583 -8233B532 4584 -8233B533 4585 -8233B534 4586 -8233B535 4587 -8233B536 4588 -8233B537 4589 -8233B538 458A -8233B539 458B -8233B630 458C -8233B631 458D -8233B632 458E -8233B633 458F -8233B634 4590 -8233B635 4591 -8233B636 4592 -8233B637 4593 -8233B638 4594 -8233B639 4595 -8233B730 4596 -8233B731 4597 -8233B732 4598 -8233B733 4599 -8233B734 459A -8233B735 459B -8233B736 459C -8233B737 459D -8233B738 459E -8233B739 459F -8233B830 45A0 -8233B831 45A1 -8233B832 45A2 -8233B833 45A3 -8233B834 45A4 -8233B835 45A5 -8233B836 45A6 -8233B837 45A7 -8233B838 45A8 -8233B839 45A9 -8233B930 45AA -8233B931 45AB -8233B932 45AC -8233B933 45AD -8233B934 45AE -8233B935 45AF -8233B936 45B0 -8233B937 45B1 -8233B938 45B2 -8233B939 45B3 -8233BA30 45B4 -8233BA31 45B5 -8233BA32 45B6 -8233BA33 45B7 -8233BA34 45B8 -8233BA35 45B9 -8233BA36 45BA -8233BA37 45BB -8233BA38 45BC -8233BA39 45BD -8233BB30 45BE -8233BB31 45BF -8233BB32 45C0 -8233BB33 45C1 -8233BB34 45C2 -8233BB35 45C3 -8233BB36 45C4 -8233BB37 45C5 -8233BB38 45C6 -8233BB39 45C7 -8233BC30 45C8 -8233BC31 45C9 -8233BC32 45CA -8233BC33 45CB -8233BC34 45CC -8233BC35 45CD -8233BC36 45CE -8233BC37 45CF -8233BC38 45D0 -8233BC39 45D1 -8233BD30 45D2 -8233BD31 45D3 -8233BD32 45D4 -8233BD33 45D5 -8233BD34 45D6 -8233BD35 45D7 -8233BD36 45D8 -8233BD37 45D9 -8233BD38 45DA -8233BD39 45DB -8233BE30 45DC -8233BE31 45DD -8233BE32 45DE -8233BE33 45DF -8233BE34 45E0 -8233BE35 45E1 -8233BE36 45E2 -8233BE37 45E3 -8233BE38 45E4 -8233BE39 45E5 -8233BF30 45E6 -8233BF31 45E7 -8233BF32 45E8 -8233BF33 45E9 -8233BF34 45EA -8233BF35 45EB -8233BF36 45EC -8233BF37 45ED -8233BF38 45EE -8233BF39 45EF -8233C030 45F0 -8233C031 45F1 -8233C032 45F2 -8233C033 45F3 -8233C034 45F4 -8233C035 45F5 -8233C036 45F6 -8233C037 45F7 -8233C038 45F8 -8233C039 45F9 -8233C130 45FA -8233C131 45FB -8233C132 45FC -8233C133 45FD -8233C134 45FE -8233C135 45FF -8233C136 4600 -8233C137 4601 -8233C138 4602 -8233C139 4603 -8233C230 4604 -8233C231 4605 -8233C232 4606 -8233C233 4607 -8233C234 4608 -8233C235 4609 -8233C236 460A -8233C237 460B -8233C238 460C -8233C239 460D -8233C330 460E -8233C331 460F -8233C332 4610 -8233C333 4611 -8233C334 4612 -8233C335 4613 -8233C336 4614 -8233C337 4615 -8233C338 4616 -8233C339 4617 -8233C430 4618 -8233C431 4619 -8233C432 461A -8233C433 461B -8233C434 461C -8233C435 461D -8233C436 461E -8233C437 461F -8233C438 4620 -8233C439 4621 -8233C530 4622 -8233C531 4623 -8233C532 4624 -8233C533 4625 -8233C534 4626 -8233C535 4627 -8233C536 4628 -8233C537 4629 -8233C538 462A -8233C539 462B -8233C630 462C -8233C631 462D -8233C632 462E -8233C633 462F -8233C634 4630 -8233C635 4631 -8233C636 4632 -8233C637 4633 -8233C638 4634 -8233C639 4635 -8233C730 4636 -8233C731 4637 -8233C732 4638 -8233C733 4639 -8233C734 463A -8233C735 463B -8233C736 463C -8233C737 463D -8233C738 463E -8233C739 463F -8233C830 4640 -8233C831 4641 -8233C832 4642 -8233C833 4643 -8233C834 4644 -8233C835 4645 -8233C836 4646 -8233C837 4647 -8233C838 4648 -8233C839 4649 -8233C930 464A -8233C931 464B -FE7D 464C -8233C932 464D -8233C933 464E -8233C934 464F -8233C935 4650 -8233C936 4651 -8233C937 4652 -8233C938 4653 -8233C939 4654 -8233CA30 4655 -8233CA31 4656 -8233CA32 4657 -8233CA33 4658 -8233CA34 4659 -8233CA35 465A -8233CA36 465B -8233CA37 465C -8233CA38 465D -8233CA39 465E -8233CB30 465F -8233CB31 4660 -FE7C 4661 -8233CB32 4662 -8233CB33 4663 -8233CB34 4664 -8233CB35 4665 -8233CB36 4666 -8233CB37 4667 -8233CB38 4668 -8233CB39 4669 -8233CC30 466A -8233CC31 466B -8233CC32 466C -8233CC33 466D -8233CC34 466E -8233CC35 466F -8233CC36 4670 -8233CC37 4671 -8233CC38 4672 -8233CC39 4673 -8233CD30 4674 -8233CD31 4675 -8233CD32 4676 -8233CD33 4677 -8233CD34 4678 -8233CD35 4679 -8233CD36 467A -8233CD37 467B -8233CD38 467C -8233CD39 467D -8233CE30 467E -8233CE31 467F -8233CE32 4680 -8233CE33 4681 -8233CE34 4682 -8233CE35 4683 -8233CE36 4684 -8233CE37 4685 -8233CE38 4686 -8233CE39 4687 -8233CF30 4688 -8233CF31 4689 -8233CF32 468A -8233CF33 468B -8233CF34 468C -8233CF35 468D -8233CF36 468E -8233CF37 468F -8233CF38 4690 -8233CF39 4691 -8233D030 4692 -8233D031 4693 -8233D032 4694 -8233D033 4695 -8233D034 4696 -8233D035 4697 -8233D036 4698 -8233D037 4699 -8233D038 469A -8233D039 469B -8233D130 469C -8233D131 469D -8233D132 469E -8233D133 469F -8233D134 46A0 -8233D135 46A1 -8233D136 46A2 -8233D137 46A3 -8233D138 46A4 -8233D139 46A5 -8233D230 46A6 -8233D231 46A7 -8233D232 46A8 -8233D233 46A9 -8233D234 46AA -8233D235 46AB -8233D236 46AC -8233D237 46AD -8233D238 46AE -8233D239 46AF -8233D330 46B0 -8233D331 46B1 -8233D332 46B2 -8233D333 46B3 -8233D334 46B4 -8233D335 46B5 -8233D336 46B6 -8233D337 46B7 -8233D338 46B8 -8233D339 46B9 -8233D430 46BA -8233D431 46BB -8233D432 46BC -8233D433 46BD -8233D434 46BE -8233D435 46BF -8233D436 46C0 -8233D437 46C1 -8233D438 46C2 -8233D439 46C3 -8233D530 46C4 -8233D531 46C5 -8233D532 46C6 -8233D533 46C7 -8233D534 46C8 -8233D535 46C9 -8233D536 46CA -8233D537 46CB -8233D538 46CC -8233D539 46CD -8233D630 46CE -8233D631 46CF -8233D632 46D0 -8233D633 46D1 -8233D634 46D2 -8233D635 46D3 -8233D636 46D4 -8233D637 46D5 -8233D638 46D6 -8233D639 46D7 -8233D730 46D8 -8233D731 46D9 -8233D732 46DA -8233D733 46DB -8233D734 46DC -8233D735 46DD -8233D736 46DE -8233D737 46DF -8233D738 46E0 -8233D739 46E1 -8233D830 46E2 -8233D831 46E3 -8233D832 46E4 -8233D833 46E5 -8233D834 46E6 -8233D835 46E7 -8233D836 46E8 -8233D837 46E9 -8233D838 46EA -8233D839 46EB -8233D930 46EC -8233D931 46ED -8233D932 46EE -8233D933 46EF -8233D934 46F0 -8233D935 46F1 -8233D936 46F2 -8233D937 46F3 -8233D938 46F4 -8233D939 46F5 -8233DA30 46F6 -8233DA31 46F7 -8233DA32 46F8 -8233DA33 46F9 -8233DA34 46FA -8233DA35 46FB -8233DA36 46FC -8233DA37 46FD -8233DA38 46FE -8233DA39 46FF -8233DB30 4700 -8233DB31 4701 -8233DB32 4702 -8233DB33 4703 -8233DB34 4704 -8233DB35 4705 -8233DB36 4706 -8233DB37 4707 -8233DB38 4708 -8233DB39 4709 -8233DC30 470A -8233DC31 470B -8233DC32 470C -8233DC33 470D -8233DC34 470E -8233DC35 470F -8233DC36 4710 -8233DC37 4711 -8233DC38 4712 -8233DC39 4713 -8233DD30 4714 -8233DD31 4715 -8233DD32 4716 -8233DD33 4717 -8233DD34 4718 -8233DD35 4719 -8233DD36 471A -8233DD37 471B -8233DD38 471C -8233DD39 471D -8233DE30 471E -8233DE31 471F -8233DE32 4720 -8233DE33 4721 -8233DE34 4722 -FE80 4723 -8233DE35 4724 -8233DE36 4725 -8233DE37 4726 -8233DE38 4727 -8233DE39 4728 -FE81 4729 -8233DF30 472A -8233DF31 472B -8233DF32 472C -8233DF33 472D -8233DF34 472E -8233DF35 472F -8233DF36 4730 -8233DF37 4731 -8233DF38 4732 -8233DF39 4733 -8233E030 4734 -8233E031 4735 -8233E032 4736 -8233E033 4737 -8233E034 4738 -8233E035 4739 -8233E036 473A -8233E037 473B -8233E038 473C -8233E039 473D -8233E130 473E -8233E131 473F -8233E132 4740 -8233E133 4741 -8233E134 4742 -8233E135 4743 -8233E136 4744 -8233E137 4745 -8233E138 4746 -8233E139 4747 -8233E230 4748 -8233E231 4749 -8233E232 474A -8233E233 474B -8233E234 474C -8233E235 474D -8233E236 474E -8233E237 474F -8233E238 4750 -8233E239 4751 -8233E330 4752 -8233E331 4753 -8233E332 4754 -8233E333 4755 -8233E334 4756 -8233E335 4757 -8233E336 4758 -8233E337 4759 -8233E338 475A -8233E339 475B -8233E430 475C -8233E431 475D -8233E432 475E -8233E433 475F -8233E434 4760 -8233E435 4761 -8233E436 4762 -8233E437 4763 -8233E438 4764 -8233E439 4765 -8233E530 4766 -8233E531 4767 -8233E532 4768 -8233E533 4769 -8233E534 476A -8233E535 476B -8233E536 476C -8233E537 476D -8233E538 476E -8233E539 476F -8233E630 4770 -8233E631 4771 -8233E632 4772 -8233E633 4773 -8233E634 4774 -8233E635 4775 -8233E636 4776 -8233E637 4777 -8233E638 4778 -8233E639 4779 -8233E730 477A -8233E731 477B -FE82 477C -8233E732 477D -8233E733 477E -8233E734 477F -8233E735 4780 -8233E736 4781 -8233E737 4782 -8233E738 4783 -8233E739 4784 -8233E830 4785 -8233E831 4786 -8233E832 4787 -8233E833 4788 -8233E834 4789 -8233E835 478A -8233E836 478B -8233E837 478C -FE83 478D -8233E838 478E -8233E839 478F -8233E930 4790 -8233E931 4791 -8233E932 4792 -8233E933 4793 -8233E934 4794 -8233E935 4795 -8233E936 4796 -8233E937 4797 -8233E938 4798 -8233E939 4799 -8233EA30 479A -8233EA31 479B -8233EA32 479C -8233EA33 479D -8233EA34 479E -8233EA35 479F -8233EA36 47A0 -8233EA37 47A1 -8233EA38 47A2 -8233EA39 47A3 -8233EB30 47A4 -8233EB31 47A5 -8233EB32 47A6 -8233EB33 47A7 -8233EB34 47A8 -8233EB35 47A9 -8233EB36 47AA -8233EB37 47AB -8233EB38 47AC -8233EB39 47AD -8233EC30 47AE -8233EC31 47AF -8233EC32 47B0 -8233EC33 47B1 -8233EC34 47B2 -8233EC35 47B3 -8233EC36 47B4 -8233EC37 47B5 -8233EC38 47B6 -8233EC39 47B7 -8233ED30 47B8 -8233ED31 47B9 -8233ED32 47BA -8233ED33 47BB -8233ED34 47BC -8233ED35 47BD -8233ED36 47BE -8233ED37 47BF -8233ED38 47C0 -8233ED39 47C1 -8233EE30 47C2 -8233EE31 47C3 -8233EE32 47C4 -8233EE33 47C5 -8233EE34 47C6 -8233EE35 47C7 -8233EE36 47C8 -8233EE37 47C9 -8233EE38 47CA -8233EE39 47CB -8233EF30 47CC -8233EF31 47CD -8233EF32 47CE -8233EF33 47CF -8233EF34 47D0 -8233EF35 47D1 -8233EF36 47D2 -8233EF37 47D3 -8233EF38 47D4 -8233EF39 47D5 -8233F030 47D6 -8233F031 47D7 -8233F032 47D8 -8233F033 47D9 -8233F034 47DA -8233F035 47DB -8233F036 47DC -8233F037 47DD -8233F038 47DE -8233F039 47DF -8233F130 47E0 -8233F131 47E1 -8233F132 47E2 -8233F133 47E3 -8233F134 47E4 -8233F135 47E5 -8233F136 47E6 -8233F137 47E7 -8233F138 47E8 -8233F139 47E9 -8233F230 47EA -8233F231 47EB -8233F232 47EC -8233F233 47ED -8233F234 47EE -8233F235 47EF -8233F236 47F0 -8233F237 47F1 -8233F238 47F2 -8233F239 47F3 -8233F330 47F4 -8233F331 47F5 -8233F332 47F6 -8233F333 47F7 -8233F334 47F8 -8233F335 47F9 -8233F336 47FA -8233F337 47FB -8233F338 47FC -8233F339 47FD -8233F430 47FE -8233F431 47FF -8233F432 4800 -8233F433 4801 -8233F434 4802 -8233F435 4803 -8233F436 4804 -8233F437 4805 -8233F438 4806 -8233F439 4807 -8233F530 4808 -8233F531 4809 -8233F532 480A -8233F533 480B -8233F534 480C -8233F535 480D -8233F536 480E -8233F537 480F -8233F538 4810 -8233F539 4811 -8233F630 4812 -8233F631 4813 -8233F632 4814 -8233F633 4815 -8233F634 4816 -8233F635 4817 -8233F636 4818 -8233F637 4819 -8233F638 481A -8233F639 481B -8233F730 481C -8233F731 481D -8233F732 481E -8233F733 481F -8233F734 4820 -8233F735 4821 -8233F736 4822 -8233F737 4823 -8233F738 4824 -8233F739 4825 -8233F830 4826 -8233F831 4827 -8233F832 4828 -8233F833 4829 -8233F834 482A -8233F835 482B -8233F836 482C -8233F837 482D -8233F838 482E -8233F839 482F -8233F930 4830 -8233F931 4831 -8233F932 4832 -8233F933 4833 -8233F934 4834 -8233F935 4835 -8233F936 4836 -8233F937 4837 -8233F938 4838 -8233F939 4839 -8233FA30 483A -8233FA31 483B -8233FA32 483C -8233FA33 483D -8233FA34 483E -8233FA35 483F -8233FA36 4840 -8233FA37 4841 -8233FA38 4842 -8233FA39 4843 -8233FB30 4844 -8233FB31 4845 -8233FB32 4846 -8233FB33 4847 -8233FB34 4848 -8233FB35 4849 -8233FB36 484A -8233FB37 484B -8233FB38 484C -8233FB39 484D -8233FC30 484E -8233FC31 484F -8233FC32 4850 -8233FC33 4851 -8233FC34 4852 -8233FC35 4853 -8233FC36 4854 -8233FC37 4855 -8233FC38 4856 -8233FC39 4857 -8233FD30 4858 -8233FD31 4859 -8233FD32 485A -8233FD33 485B -8233FD34 485C -8233FD35 485D -8233FD36 485E -8233FD37 485F -8233FD38 4860 -8233FD39 4861 -8233FE30 4862 -8233FE31 4863 -8233FE32 4864 -8233FE33 4865 -8233FE34 4866 -8233FE35 4867 -8233FE36 4868 -8233FE37 4869 -8233FE38 486A -8233FE39 486B -82348130 486C -82348131 486D -82348132 486E -82348133 486F -82348134 4870 -82348135 4871 -82348136 4872 -82348137 4873 -82348138 4874 -82348139 4875 -82348230 4876 -82348231 4877 -82348232 4878 -82348233 4879 -82348234 487A -82348235 487B -82348236 487C -82348237 487D -82348238 487E -82348239 487F -82348330 4880 -82348331 4881 -82348332 4882 -82348333 4883 -82348334 4884 -82348335 4885 -82348336 4886 -82348337 4887 -82348338 4888 -82348339 4889 -82348430 488A -82348431 488B -82348432 488C -82348433 488D -82348434 488E -82348435 488F -82348436 4890 -82348437 4891 -82348438 4892 -82348439 4893 -82348530 4894 -82348531 4895 -82348532 4896 -82348533 4897 -82348534 4898 -82348535 4899 -82348536 489A -82348537 489B -82348538 489C -82348539 489D -82348630 489E -82348631 489F -82348632 48A0 -82348633 48A1 -82348634 48A2 -82348635 48A3 -82348636 48A4 -82348637 48A5 -82348638 48A6 -82348639 48A7 -82348730 48A8 -82348731 48A9 -82348732 48AA -82348733 48AB -82348734 48AC -82348735 48AD -82348736 48AE -82348737 48AF -82348738 48B0 -82348739 48B1 -82348830 48B2 -82348831 48B3 -82348832 48B4 -82348833 48B5 -82348834 48B6 -82348835 48B7 -82348836 48B8 -82348837 48B9 -82348838 48BA -82348839 48BB -82348930 48BC -82348931 48BD -82348932 48BE -82348933 48BF -82348934 48C0 -82348935 48C1 -82348936 48C2 -82348937 48C3 -82348938 48C4 -82348939 48C5 -82348A30 48C6 -82348A31 48C7 -82348A32 48C8 -82348A33 48C9 -82348A34 48CA -82348A35 48CB -82348A36 48CC -82348A37 48CD -82348A38 48CE -82348A39 48CF -82348B30 48D0 -82348B31 48D1 -82348B32 48D2 -82348B33 48D3 -82348B34 48D4 -82348B35 48D5 -82348B36 48D6 -82348B37 48D7 -82348B38 48D8 -82348B39 48D9 -82348C30 48DA -82348C31 48DB -82348C32 48DC -82348C33 48DD -82348C34 48DE -82348C35 48DF -82348C36 48E0 -82348C37 48E1 -82348C38 48E2 -82348C39 48E3 -82348D30 48E4 -82348D31 48E5 -82348D32 48E6 -82348D33 48E7 -82348D34 48E8 -82348D35 48E9 -82348D36 48EA -82348D37 48EB -82348D38 48EC -82348D39 48ED -82348E30 48EE -82348E31 48EF -82348E32 48F0 -82348E33 48F1 -82348E34 48F2 -82348E35 48F3 -82348E36 48F4 -82348E37 48F5 -82348E38 48F6 -82348E39 48F7 -82348F30 48F8 -82348F31 48F9 -82348F32 48FA -82348F33 48FB -82348F34 48FC -82348F35 48FD -82348F36 48FE -82348F37 48FF -82348F38 4900 -82348F39 4901 -82349030 4902 -82349031 4903 -82349032 4904 -82349033 4905 -82349034 4906 -82349035 4907 -82349036 4908 -82349037 4909 -82349038 490A -82349039 490B -82349130 490C -82349131 490D -82349132 490E -82349133 490F -82349134 4910 -82349135 4911 -82349136 4912 -82349137 4913 -82349138 4914 -82349139 4915 -82349230 4916 -82349231 4917 -82349232 4918 -82349233 4919 -82349234 491A -82349235 491B -82349236 491C -82349237 491D -82349238 491E -82349239 491F -82349330 4920 -82349331 4921 -82349332 4922 -82349333 4923 -82349334 4924 -82349335 4925 -82349336 4926 -82349337 4927 -82349338 4928 -82349339 4929 -82349430 492A -82349431 492B -82349432 492C -82349433 492D -82349434 492E -82349435 492F -82349436 4930 -82349437 4931 -82349438 4932 -82349439 4933 -82349530 4934 -82349531 4935 -82349532 4936 -82349533 4937 -82349534 4938 -82349535 4939 -82349536 493A -82349537 493B -82349538 493C -82349539 493D -82349630 493E -82349631 493F -82349632 4940 -82349633 4941 -82349634 4942 -82349635 4943 -82349636 4944 -82349637 4945 -82349638 4946 -FE85 4947 -82349639 4948 -82349730 4949 -82349731 494A -82349732 494B -82349733 494C -82349734 494D -82349735 494E -82349736 494F -82349737 4950 -82349738 4951 -82349739 4952 -82349830 4953 -82349831 4954 -82349832 4955 -82349833 4956 -82349834 4957 -82349835 4958 -82349836 4959 -82349837 495A -82349838 495B -82349839 495C -82349930 495D -82349931 495E -82349932 495F -82349933 4960 -82349934 4961 -82349935 4962 -82349936 4963 -82349937 4964 -82349938 4965 -82349939 4966 -82349A30 4967 -82349A31 4968 -82349A32 4969 -82349A33 496A -82349A34 496B -82349A35 496C -82349A36 496D -82349A37 496E -82349A38 496F -82349A39 4970 -82349B30 4971 -82349B31 4972 -82349B32 4973 -82349B33 4974 -82349B34 4975 -82349B35 4976 -82349B36 4977 -82349B37 4978 -82349B38 4979 -FE86 497A -82349B39 497B -82349C30 497C -FE87 497D -82349C31 497E -82349C32 497F -82349C33 4980 -82349C34 4981 -FE88 4982 -FE89 4983 -82349C35 4984 -FE8A 4985 -FE8B 4986 -82349C36 4987 -82349C37 4988 -82349C38 4989 -82349C39 498A -82349D30 498B -82349D31 498C -82349D32 498D -82349D33 498E -82349D34 498F -82349D35 4990 -82349D36 4991 -82349D37 4992 -82349D38 4993 -82349D39 4994 -82349E30 4995 -82349E31 4996 -82349E32 4997 -82349E33 4998 -82349E34 4999 -82349E35 499A -FE8D 499B -82349E36 499C -82349E37 499D -82349E38 499E -FE8C 499F -82349E39 49A0 -82349F30 49A1 -82349F31 49A2 -82349F32 49A3 -82349F33 49A4 -82349F34 49A5 -82349F35 49A6 -82349F36 49A7 -82349F37 49A8 -82349F38 49A9 -82349F39 49AA -8234A030 49AB -8234A031 49AC -8234A032 49AD -8234A033 49AE -8234A034 49AF -8234A035 49B0 -8234A036 49B1 -8234A037 49B2 -8234A038 49B3 -8234A039 49B4 -8234A130 49B5 -FE8F 49B6 -FE8E 49B7 -8234A131 49B8 -8234A132 49B9 -8234A133 49BA -8234A134 49BB -8234A135 49BC -8234A136 49BD -8234A137 49BE -8234A138 49BF -8234A139 49C0 -8234A230 49C1 -8234A231 49C2 -8234A232 49C3 -8234A233 49C4 -8234A234 49C5 -8234A235 49C6 -8234A236 49C7 -8234A237 49C8 -8234A238 49C9 -8234A239 49CA -8234A330 49CB -8234A331 49CC -8234A332 49CD -8234A333 49CE -8234A334 49CF -8234A335 49D0 -8234A336 49D1 -8234A337 49D2 -8234A338 49D3 -8234A339 49D4 -8234A430 49D5 -8234A431 49D6 -8234A432 49D7 -8234A433 49D8 -8234A434 49D9 -8234A435 49DA -8234A436 49DB -8234A437 49DC -8234A438 49DD -8234A439 49DE -8234A530 49DF -8234A531 49E0 -8234A532 49E1 -8234A533 49E2 -8234A534 49E3 -8234A535 49E4 -8234A536 49E5 -8234A537 49E6 -8234A538 49E7 -8234A539 49E8 -8234A630 49E9 -8234A631 49EA -8234A632 49EB -8234A633 49EC -8234A634 49ED -8234A635 49EE -8234A636 49EF -8234A637 49F0 -8234A638 49F1 -8234A639 49F2 -8234A730 49F3 -8234A731 49F4 -8234A732 49F5 -8234A733 49F6 -8234A734 49F7 -8234A735 49F8 -8234A736 49F9 -8234A737 49FA -8234A738 49FB -8234A739 49FC -8234A830 49FD -8234A831 49FE -8234A832 49FF -8234A833 4A00 -8234A834 4A01 -8234A835 4A02 -8234A836 4A03 -8234A837 4A04 -8234A838 4A05 -8234A839 4A06 -8234A930 4A07 -8234A931 4A08 -8234A932 4A09 -8234A933 4A0A -8234A934 4A0B -8234A935 4A0C -8234A936 4A0D -8234A937 4A0E -8234A938 4A0F -8234A939 4A10 -8234AA30 4A11 -8234AA31 4A12 -8234AA32 4A13 -8234AA33 4A14 -8234AA34 4A15 -8234AA35 4A16 -8234AA36 4A17 -8234AA37 4A18 -8234AA38 4A19 -8234AA39 4A1A -8234AB30 4A1B -8234AB31 4A1C -8234AB32 4A1D -8234AB33 4A1E -8234AB34 4A1F -8234AB35 4A20 -8234AB36 4A21 -8234AB37 4A22 -8234AB38 4A23 -8234AB39 4A24 -8234AC30 4A25 -8234AC31 4A26 -8234AC32 4A27 -8234AC33 4A28 -8234AC34 4A29 -8234AC35 4A2A -8234AC36 4A2B -8234AC37 4A2C -8234AC38 4A2D -8234AC39 4A2E -8234AD30 4A2F -8234AD31 4A30 -8234AD32 4A31 -8234AD33 4A32 -8234AD34 4A33 -8234AD35 4A34 -8234AD36 4A35 -8234AD37 4A36 -8234AD38 4A37 -8234AD39 4A38 -8234AE30 4A39 -8234AE31 4A3A -8234AE32 4A3B -8234AE33 4A3C -8234AE34 4A3D -8234AE35 4A3E -8234AE36 4A3F -8234AE37 4A40 -8234AE38 4A41 -8234AE39 4A42 -8234AF30 4A43 -8234AF31 4A44 -8234AF32 4A45 -8234AF33 4A46 -8234AF34 4A47 -8234AF35 4A48 -8234AF36 4A49 -8234AF37 4A4A -8234AF38 4A4B -8234AF39 4A4C -8234B030 4A4D -8234B031 4A4E -8234B032 4A4F -8234B033 4A50 -8234B034 4A51 -8234B035 4A52 -8234B036 4A53 -8234B037 4A54 -8234B038 4A55 -8234B039 4A56 -8234B130 4A57 -8234B131 4A58 -8234B132 4A59 -8234B133 4A5A -8234B134 4A5B -8234B135 4A5C -8234B136 4A5D -8234B137 4A5E -8234B138 4A5F -8234B139 4A60 -8234B230 4A61 -8234B231 4A62 -8234B232 4A63 -8234B233 4A64 -8234B234 4A65 -8234B235 4A66 -8234B236 4A67 -8234B237 4A68 -8234B238 4A69 -8234B239 4A6A -8234B330 4A6B -8234B331 4A6C -8234B332 4A6D -8234B333 4A6E -8234B334 4A6F -8234B335 4A70 -8234B336 4A71 -8234B337 4A72 -8234B338 4A73 -8234B339 4A74 -8234B430 4A75 -8234B431 4A76 -8234B432 4A77 -8234B433 4A78 -8234B434 4A79 -8234B435 4A7A -8234B436 4A7B -8234B437 4A7C -8234B438 4A7D -8234B439 4A7E -8234B530 4A7F -8234B531 4A80 -8234B532 4A81 -8234B533 4A82 -8234B534 4A83 -8234B535 4A84 -8234B536 4A85 -8234B537 4A86 -8234B538 4A87 -8234B539 4A88 -8234B630 4A89 -8234B631 4A8A -8234B632 4A8B -8234B633 4A8C -8234B634 4A8D -8234B635 4A8E -8234B636 4A8F -8234B637 4A90 -8234B638 4A91 -8234B639 4A92 -8234B730 4A93 -8234B731 4A94 -8234B732 4A95 -8234B733 4A96 -8234B734 4A97 -8234B735 4A98 -8234B736 4A99 -8234B737 4A9A -8234B738 4A9B -8234B739 4A9C -8234B830 4A9D -8234B831 4A9E -8234B832 4A9F -8234B833 4AA0 -8234B834 4AA1 -8234B835 4AA2 -8234B836 4AA3 -8234B837 4AA4 -8234B838 4AA5 -8234B839 4AA6 -8234B930 4AA7 -8234B931 4AA8 -8234B932 4AA9 -8234B933 4AAA -8234B934 4AAB -8234B935 4AAC -8234B936 4AAD -8234B937 4AAE -8234B938 4AAF -8234B939 4AB0 -8234BA30 4AB1 -8234BA31 4AB2 -8234BA32 4AB3 -8234BA33 4AB4 -8234BA34 4AB5 -8234BA35 4AB6 -8234BA36 4AB7 -8234BA37 4AB8 -8234BA38 4AB9 -8234BA39 4ABA -8234BB30 4ABB -8234BB31 4ABC -8234BB32 4ABD -8234BB33 4ABE -8234BB34 4ABF -8234BB35 4AC0 -8234BB36 4AC1 -8234BB37 4AC2 -8234BB38 4AC3 -8234BB39 4AC4 -8234BC30 4AC5 -8234BC31 4AC6 -8234BC32 4AC7 -8234BC33 4AC8 -8234BC34 4AC9 -8234BC35 4ACA -8234BC36 4ACB -8234BC37 4ACC -8234BC38 4ACD -8234BC39 4ACE -8234BD30 4ACF -8234BD31 4AD0 -8234BD32 4AD1 -8234BD33 4AD2 -8234BD34 4AD3 -8234BD35 4AD4 -8234BD36 4AD5 -8234BD37 4AD6 -8234BD38 4AD7 -8234BD39 4AD8 -8234BE30 4AD9 -8234BE31 4ADA -8234BE32 4ADB -8234BE33 4ADC -8234BE34 4ADD -8234BE35 4ADE -8234BE36 4ADF -8234BE37 4AE0 -8234BE38 4AE1 -8234BE39 4AE2 -8234BF30 4AE3 -8234BF31 4AE4 -8234BF32 4AE5 -8234BF33 4AE6 -8234BF34 4AE7 -8234BF35 4AE8 -8234BF36 4AE9 -8234BF37 4AEA -8234BF38 4AEB -8234BF39 4AEC -8234C030 4AED -8234C031 4AEE -8234C032 4AEF -8234C033 4AF0 -8234C034 4AF1 -8234C035 4AF2 -8234C036 4AF3 -8234C037 4AF4 -8234C038 4AF5 -8234C039 4AF6 -8234C130 4AF7 -8234C131 4AF8 -8234C132 4AF9 -8234C133 4AFA -8234C134 4AFB -8234C135 4AFC -8234C136 4AFD -8234C137 4AFE -8234C138 4AFF -8234C139 4B00 -8234C230 4B01 -8234C231 4B02 -8234C232 4B03 -8234C233 4B04 -8234C234 4B05 -8234C235 4B06 -8234C236 4B07 -8234C237 4B08 -8234C238 4B09 -8234C239 4B0A -8234C330 4B0B -8234C331 4B0C -8234C332 4B0D -8234C333 4B0E -8234C334 4B0F -8234C335 4B10 -8234C336 4B11 -8234C337 4B12 -8234C338 4B13 -8234C339 4B14 -8234C430 4B15 -8234C431 4B16 -8234C432 4B17 -8234C433 4B18 -8234C434 4B19 -8234C435 4B1A -8234C436 4B1B -8234C437 4B1C -8234C438 4B1D -8234C439 4B1E -8234C530 4B1F -8234C531 4B20 -8234C532 4B21 -8234C533 4B22 -8234C534 4B23 -8234C535 4B24 -8234C536 4B25 -8234C537 4B26 -8234C538 4B27 -8234C539 4B28 -8234C630 4B29 -8234C631 4B2A -8234C632 4B2B -8234C633 4B2C -8234C634 4B2D -8234C635 4B2E -8234C636 4B2F -8234C637 4B30 -8234C638 4B31 -8234C639 4B32 -8234C730 4B33 -8234C731 4B34 -8234C732 4B35 -8234C733 4B36 -8234C734 4B37 -8234C735 4B38 -8234C736 4B39 -8234C737 4B3A -8234C738 4B3B -8234C739 4B3C -8234C830 4B3D -8234C831 4B3E -8234C832 4B3F -8234C833 4B40 -8234C834 4B41 -8234C835 4B42 -8234C836 4B43 -8234C837 4B44 -8234C838 4B45 -8234C839 4B46 -8234C930 4B47 -8234C931 4B48 -8234C932 4B49 -8234C933 4B4A -8234C934 4B4B -8234C935 4B4C -8234C936 4B4D -8234C937 4B4E -8234C938 4B4F -8234C939 4B50 -8234CA30 4B51 -8234CA31 4B52 -8234CA32 4B53 -8234CA33 4B54 -8234CA34 4B55 -8234CA35 4B56 -8234CA36 4B57 -8234CA37 4B58 -8234CA38 4B59 -8234CA39 4B5A -8234CB30 4B5B -8234CB31 4B5C -8234CB32 4B5D -8234CB33 4B5E -8234CB34 4B5F -8234CB35 4B60 -8234CB36 4B61 -8234CB37 4B62 -8234CB38 4B63 -8234CB39 4B64 -8234CC30 4B65 -8234CC31 4B66 -8234CC32 4B67 -8234CC33 4B68 -8234CC34 4B69 -8234CC35 4B6A -8234CC36 4B6B -8234CC37 4B6C -8234CC38 4B6D -8234CC39 4B6E -8234CD30 4B6F -8234CD31 4B70 -8234CD32 4B71 -8234CD33 4B72 -8234CD34 4B73 -8234CD35 4B74 -8234CD36 4B75 -8234CD37 4B76 -8234CD38 4B77 -8234CD39 4B78 -8234CE30 4B79 -8234CE31 4B7A -8234CE32 4B7B -8234CE33 4B7C -8234CE34 4B7D -8234CE35 4B7E -8234CE36 4B7F -8234CE37 4B80 -8234CE38 4B81 -8234CE39 4B82 -8234CF30 4B83 -8234CF31 4B84 -8234CF32 4B85 -8234CF33 4B86 -8234CF34 4B87 -8234CF35 4B88 -8234CF36 4B89 -8234CF37 4B8A -8234CF38 4B8B -8234CF39 4B8C -8234D030 4B8D -8234D031 4B8E -8234D032 4B8F -8234D033 4B90 -8234D034 4B91 -8234D035 4B92 -8234D036 4B93 -8234D037 4B94 -8234D038 4B95 -8234D039 4B96 -8234D130 4B97 -8234D131 4B98 -8234D132 4B99 -8234D133 4B9A -8234D134 4B9B -8234D135 4B9C -8234D136 4B9D -8234D137 4B9E -8234D138 4B9F -8234D139 4BA0 -8234D230 4BA1 -8234D231 4BA2 -8234D232 4BA3 -8234D233 4BA4 -8234D234 4BA5 -8234D235 4BA6 -8234D236 4BA7 -8234D237 4BA8 -8234D238 4BA9 -8234D239 4BAA -8234D330 4BAB -8234D331 4BAC -8234D332 4BAD -8234D333 4BAE -8234D334 4BAF -8234D335 4BB0 -8234D336 4BB1 -8234D337 4BB2 -8234D338 4BB3 -8234D339 4BB4 -8234D430 4BB5 -8234D431 4BB6 -8234D432 4BB7 -8234D433 4BB8 -8234D434 4BB9 -8234D435 4BBA -8234D436 4BBB -8234D437 4BBC -8234D438 4BBD -8234D439 4BBE -8234D530 4BBF -8234D531 4BC0 -8234D532 4BC1 -8234D533 4BC2 -8234D534 4BC3 -8234D535 4BC4 -8234D536 4BC5 -8234D537 4BC6 -8234D538 4BC7 -8234D539 4BC8 -8234D630 4BC9 -8234D631 4BCA -8234D632 4BCB -8234D633 4BCC -8234D634 4BCD -8234D635 4BCE -8234D636 4BCF -8234D637 4BD0 -8234D638 4BD1 -8234D639 4BD2 -8234D730 4BD3 -8234D731 4BD4 -8234D732 4BD5 -8234D733 4BD6 -8234D734 4BD7 -8234D735 4BD8 -8234D736 4BD9 -8234D737 4BDA -8234D738 4BDB -8234D739 4BDC -8234D830 4BDD -8234D831 4BDE -8234D832 4BDF -8234D833 4BE0 -8234D834 4BE1 -8234D835 4BE2 -8234D836 4BE3 -8234D837 4BE4 -8234D838 4BE5 -8234D839 4BE6 -8234D930 4BE7 -8234D931 4BE8 -8234D932 4BE9 -8234D933 4BEA -8234D934 4BEB -8234D935 4BEC -8234D936 4BED -8234D937 4BEE -8234D938 4BEF -8234D939 4BF0 -8234DA30 4BF1 -8234DA31 4BF2 -8234DA32 4BF3 -8234DA33 4BF4 -8234DA34 4BF5 -8234DA35 4BF6 -8234DA36 4BF7 -8234DA37 4BF8 -8234DA38 4BF9 -8234DA39 4BFA -8234DB30 4BFB -8234DB31 4BFC -8234DB32 4BFD -8234DB33 4BFE -8234DB34 4BFF -8234DB35 4C00 -8234DB36 4C01 -8234DB37 4C02 -8234DB38 4C03 -8234DB39 4C04 -8234DC30 4C05 -8234DC31 4C06 -8234DC32 4C07 -8234DC33 4C08 -8234DC34 4C09 -8234DC35 4C0A -8234DC36 4C0B -8234DC37 4C0C -8234DC38 4C0D -8234DC39 4C0E -8234DD30 4C0F -8234DD31 4C10 -8234DD32 4C11 -8234DD33 4C12 -8234DD34 4C13 -8234DD35 4C14 -8234DD36 4C15 -8234DD37 4C16 -8234DD38 4C17 -8234DD39 4C18 -8234DE30 4C19 -8234DE31 4C1A -8234DE32 4C1B -8234DE33 4C1C -8234DE34 4C1D -8234DE35 4C1E -8234DE36 4C1F -8234DE37 4C20 -8234DE38 4C21 -8234DE39 4C22 -8234DF30 4C23 -8234DF31 4C24 -8234DF32 4C25 -8234DF33 4C26 -8234DF34 4C27 -8234DF35 4C28 -8234DF36 4C29 -8234DF37 4C2A -8234DF38 4C2B -8234DF39 4C2C -8234E030 4C2D -8234E031 4C2E -8234E032 4C2F -8234E033 4C30 -8234E034 4C31 -8234E035 4C32 -8234E036 4C33 -8234E037 4C34 -8234E038 4C35 -8234E039 4C36 -8234E130 4C37 -8234E131 4C38 -8234E132 4C39 -8234E133 4C3A -8234E134 4C3B -8234E135 4C3C -8234E136 4C3D -8234E137 4C3E -8234E138 4C3F -8234E139 4C40 -8234E230 4C41 -8234E231 4C42 -8234E232 4C43 -8234E233 4C44 -8234E234 4C45 -8234E235 4C46 -8234E236 4C47 -8234E237 4C48 -8234E238 4C49 -8234E239 4C4A -8234E330 4C4B -8234E331 4C4C -8234E332 4C4D -8234E333 4C4E -8234E334 4C4F -8234E335 4C50 -8234E336 4C51 -8234E337 4C52 -8234E338 4C53 -8234E339 4C54 -8234E430 4C55 -8234E431 4C56 -8234E432 4C57 -8234E433 4C58 -8234E434 4C59 -8234E435 4C5A -8234E436 4C5B -8234E437 4C5C -8234E438 4C5D -8234E439 4C5E -8234E530 4C5F -8234E531 4C60 -8234E532 4C61 -8234E533 4C62 -8234E534 4C63 -8234E535 4C64 -8234E536 4C65 -8234E537 4C66 -8234E538 4C67 -8234E539 4C68 -8234E630 4C69 -8234E631 4C6A -8234E632 4C6B -8234E633 4C6C -8234E634 4C6D -8234E635 4C6E -8234E636 4C6F -8234E637 4C70 -8234E638 4C71 -8234E639 4C72 -8234E730 4C73 -8234E731 4C74 -8234E732 4C75 -8234E733 4C76 -FE96 4C77 -8234E734 4C78 -8234E735 4C79 -8234E736 4C7A -8234E737 4C7B -8234E738 4C7C -8234E739 4C7D -8234E830 4C7E -8234E831 4C7F -8234E832 4C80 -8234E833 4C81 -8234E834 4C82 -8234E835 4C83 -8234E836 4C84 -8234E837 4C85 -8234E838 4C86 -8234E839 4C87 -8234E930 4C88 -8234E931 4C89 -8234E932 4C8A -8234E933 4C8B -8234E934 4C8C -8234E935 4C8D -8234E936 4C8E -8234E937 4C8F -8234E938 4C90 -8234E939 4C91 -8234EA30 4C92 -8234EA31 4C93 -8234EA32 4C94 -8234EA33 4C95 -8234EA34 4C96 -8234EA35 4C97 -8234EA36 4C98 -8234EA37 4C99 -8234EA38 4C9A -8234EA39 4C9B -8234EB30 4C9C -8234EB31 4C9D -8234EB32 4C9E -FE93 4C9F -FE94 4CA0 -FE95 4CA1 -FE97 4CA2 -FE92 4CA3 -8234EB33 4CA4 -8234EB34 4CA5 -8234EB35 4CA6 -8234EB36 4CA7 -8234EB37 4CA8 -8234EB38 4CA9 -8234EB39 4CAA -8234EC30 4CAB -8234EC31 4CAC -8234EC32 4CAD -8234EC33 4CAE -8234EC34 4CAF -8234EC35 4CB0 -8234EC36 4CB1 -8234EC37 4CB2 -8234EC38 4CB3 -8234EC39 4CB4 -8234ED30 4CB5 -8234ED31 4CB6 -8234ED32 4CB7 -8234ED33 4CB8 -8234ED34 4CB9 -8234ED35 4CBA -8234ED36 4CBB -8234ED37 4CBC -8234ED38 4CBD -8234ED39 4CBE -8234EE30 4CBF -8234EE31 4CC0 -8234EE32 4CC1 -8234EE33 4CC2 -8234EE34 4CC3 -8234EE35 4CC4 -8234EE36 4CC5 -8234EE37 4CC6 -8234EE38 4CC7 -8234EE39 4CC8 -8234EF30 4CC9 -8234EF31 4CCA -8234EF32 4CCB -8234EF33 4CCC -8234EF34 4CCD -8234EF35 4CCE -8234EF36 4CCF -8234EF37 4CD0 -8234EF38 4CD1 -8234EF39 4CD2 -8234F030 4CD3 -8234F031 4CD4 -8234F032 4CD5 -8234F033 4CD6 -8234F034 4CD7 -8234F035 4CD8 -8234F036 4CD9 -8234F037 4CDA -8234F038 4CDB -8234F039 4CDC -8234F130 4CDD -8234F131 4CDE -8234F132 4CDF -8234F133 4CE0 -8234F134 4CE1 -8234F135 4CE2 -8234F136 4CE3 -8234F137 4CE4 -8234F138 4CE5 -8234F139 4CE6 -8234F230 4CE7 -8234F231 4CE8 -8234F232 4CE9 -8234F233 4CEA -8234F234 4CEB -8234F235 4CEC -8234F236 4CED -8234F237 4CEE -8234F238 4CEF -8234F239 4CF0 -8234F330 4CF1 -8234F331 4CF2 -8234F332 4CF3 -8234F333 4CF4 -8234F334 4CF5 -8234F335 4CF6 -8234F336 4CF7 -8234F337 4CF8 -8234F338 4CF9 -8234F339 4CFA -8234F430 4CFB -8234F431 4CFC -8234F432 4CFD -8234F433 4CFE -8234F434 4CFF -8234F435 4D00 -8234F436 4D01 -8234F437 4D02 -8234F438 4D03 -8234F439 4D04 -8234F530 4D05 -8234F531 4D06 -8234F532 4D07 -8234F533 4D08 -8234F534 4D09 -8234F535 4D0A -8234F536 4D0B -8234F537 4D0C -8234F538 4D0D -8234F539 4D0E -8234F630 4D0F -8234F631 4D10 -8234F632 4D11 -8234F633 4D12 -FE98 4D13 -FE99 4D14 -FE9A 4D15 -FE9B 4D16 -FE9C 4D17 -FE9D 4D18 -FE9E 4D19 -8234F634 4D1A -8234F635 4D1B -8234F636 4D1C -8234F637 4D1D -8234F638 4D1E -8234F639 4D1F -8234F730 4D20 -8234F731 4D21 -8234F732 4D22 -8234F733 4D23 -8234F734 4D24 -8234F735 4D25 -8234F736 4D26 -8234F737 4D27 -8234F738 4D28 -8234F739 4D29 -8234F830 4D2A -8234F831 4D2B -8234F832 4D2C -8234F833 4D2D -8234F834 4D2E -8234F835 4D2F -8234F836 4D30 -8234F837 4D31 -8234F838 4D32 -8234F839 4D33 -8234F930 4D34 -8234F931 4D35 -8234F932 4D36 -8234F933 4D37 -8234F934 4D38 -8234F935 4D39 -8234F936 4D3A -8234F937 4D3B -8234F938 4D3C -8234F939 4D3D -8234FA30 4D3E -8234FA31 4D3F -8234FA32 4D40 -8234FA33 4D41 -8234FA34 4D42 -8234FA35 4D43 -8234FA36 4D44 -8234FA37 4D45 -8234FA38 4D46 -8234FA39 4D47 -8234FB30 4D48 -8234FB31 4D49 -8234FB32 4D4A -8234FB33 4D4B -8234FB34 4D4C -8234FB35 4D4D -8234FB36 4D4E -8234FB37 4D4F -8234FB38 4D50 -8234FB39 4D51 -8234FC30 4D52 -8234FC31 4D53 -8234FC32 4D54 -8234FC33 4D55 -8234FC34 4D56 -8234FC35 4D57 -8234FC36 4D58 -8234FC37 4D59 -8234FC38 4D5A -8234FC39 4D5B -8234FD30 4D5C -8234FD31 4D5D -8234FD32 4D5E -8234FD33 4D5F -8234FD34 4D60 -8234FD35 4D61 -8234FD36 4D62 -8234FD37 4D63 -8234FD38 4D64 -8234FD39 4D65 -8234FE30 4D66 -8234FE31 4D67 -8234FE32 4D68 -8234FE33 4D69 -8234FE34 4D6A -8234FE35 4D6B -8234FE36 4D6C -8234FE37 4D6D -8234FE38 4D6E -8234FE39 4D6F -82358130 4D70 -82358131 4D71 -82358132 4D72 -82358133 4D73 -82358134 4D74 -82358135 4D75 -82358136 4D76 -82358137 4D77 -82358138 4D78 -82358139 4D79 -82358230 4D7A -82358231 4D7B -82358232 4D7C -82358233 4D7D -82358234 4D7E -82358235 4D7F -82358236 4D80 -82358237 4D81 -82358238 4D82 -82358239 4D83 -82358330 4D84 -82358331 4D85 -82358332 4D86 -82358333 4D87 -82358334 4D88 -82358335 4D89 -82358336 4D8A -82358337 4D8B -82358338 4D8C -82358339 4D8D -82358430 4D8E -82358431 4D8F -82358432 4D90 -82358433 4D91 -82358434 4D92 -82358435 4D93 -82358436 4D94 -82358437 4D95 -82358438 4D96 -82358439 4D97 -82358530 4D98 -82358531 4D99 -82358532 4D9A -82358533 4D9B -82358534 4D9C -82358535 4D9D -82358536 4D9E -82358537 4D9F -82358538 4DA0 -82358539 4DA1 -82358630 4DA2 -82358631 4DA3 -82358632 4DA4 -82358633 4DA5 -82358634 4DA6 -82358635 4DA7 -82358636 4DA8 -82358637 4DA9 -82358638 4DAA -82358639 4DAB -82358730 4DAC -82358731 4DAD -FE9F 4DAE -82358732 4DAF -82358733 4DB0 -82358734 4DB1 -82358735 4DB2 -82358736 4DB3 -82358737 4DB4 -82358738 4DB5 -82358739 4DB6 -82358830 4DB7 -82358831 4DB8 -82358832 4DB9 -82358833 4DBA -82358834 4DBB -82358835 4DBC -82358836 4DBD -82358837 4DBE -82358838 4DBF -82358839 4DC0 -82358930 4DC1 -82358931 4DC2 -82358932 4DC3 -82358933 4DC4 -82358934 4DC5 -82358935 4DC6 -82358936 4DC7 -82358937 4DC8 -82358938 4DC9 -82358939 4DCA -82358A30 4DCB -82358A31 4DCC -82358A32 4DCD -82358A33 4DCE -82358A34 4DCF -82358A35 4DD0 -82358A36 4DD1 -82358A37 4DD2 -82358A38 4DD3 -82358A39 4DD4 -82358B30 4DD5 -82358B31 4DD6 -82358B32 4DD7 -82358B33 4DD8 -82358B34 4DD9 -82358B35 4DDA -82358B36 4DDB -82358B37 4DDC -82358B38 4DDD -82358B39 4DDE -82358C30 4DDF -82358C31 4DE0 -82358C32 4DE1 -82358C33 4DE2 -82358C34 4DE3 -82358C35 4DE4 -82358C36 4DE5 -82358C37 4DE6 -82358C38 4DE7 -82358C39 4DE8 -82358D30 4DE9 -82358D31 4DEA -82358D32 4DEB -82358D33 4DEC -82358D34 4DED -82358D35 4DEE -82358D36 4DEF -82358D37 4DF0 -82358D38 4DF1 -82358D39 4DF2 -82358E30 4DF3 -82358E31 4DF4 -82358E32 4DF5 -82358E33 4DF6 -82358E34 4DF7 -82358E35 4DF8 -82358E36 4DF9 -82358E37 4DFA -82358E38 4DFB -82358E39 4DFC -82358F30 4DFD -82358F31 4DFE -82358F32 4DFF -D2BB 4E00 -B6A1 4E01 -8140 4E02 -C6DF 4E03 -8141 4E04 -8142 4E05 -8143 4E06 -CDF2 4E07 -D5C9 4E08 -C8FD 4E09 -C9CF 4E0A -CFC2 4E0B -D8A2 4E0C -B2BB 4E0D -D3EB 4E0E -8144 4E0F -D8A4 4E10 -B3F3 4E11 -8145 4E12 -D7A8 4E13 -C7D2 4E14 -D8A7 4E15 -CAC0 4E16 -8146 4E17 -C7F0 4E18 -B1FB 4E19 -D2B5 4E1A -B4D4 4E1B -B6AB 4E1C -CBBF 4E1D -D8A9 4E1E -8147 4E1F -8148 4E20 -8149 4E21 -B6AA 4E22 -814A 4E23 -C1BD 4E24 -D1CF 4E25 -814B 4E26 -C9A5 4E27 -D8AD 4E28 -814C 4E29 -B8F6 4E2A -D1BE 4E2B -E3DC 4E2C -D6D0 4E2D -814D 4E2E -814E 4E2F -B7E1 4E30 -814F 4E31 -B4AE 4E32 -8150 4E33 -C1D9 4E34 -8151 4E35 -D8BC 4E36 -8152 4E37 -CDE8 4E38 -B5A4 4E39 -CEAA 4E3A -D6F7 4E3B -8153 4E3C -C0F6 4E3D -BED9 4E3E -D8AF 4E3F -8154 4E40 -8155 4E41 -8156 4E42 -C4CB 4E43 -8157 4E44 -BEC3 4E45 -8158 4E46 -D8B1 4E47 -C3B4 4E48 -D2E5 4E49 -8159 4E4A -D6AE 4E4B -CEDA 4E4C -D5A7 4E4D -BAF5 4E4E -B7A6 4E4F -C0D6 4E50 -815A 4E51 -C6B9 4E52 -C5D2 4E53 -C7C7 4E54 -815B 4E55 -B9D4 4E56 -815C 4E57 -B3CB 4E58 -D2D2 4E59 -815D 4E5A -815E 4E5B -D8BF 4E5C -BEC5 4E5D -C6F2 4E5E -D2B2 4E5F -CFB0 4E60 -CFE7 4E61 -815F 4E62 -8160 4E63 -8161 4E64 -8162 4E65 -CAE9 4E66 -8163 4E67 -8164 4E68 -D8C0 4E69 -8165 4E6A -8166 4E6B -8167 4E6C -8168 4E6D -8169 4E6E -816A 4E6F -C2F2 4E70 -C2D2 4E71 -816B 4E72 -C8E9 4E73 -816C 4E74 -816D 4E75 -816E 4E76 -816F 4E77 -8170 4E78 -8171 4E79 -8172 4E7A -8173 4E7B -8174 4E7C -8175 4E7D -C7AC 4E7E -8176 4E7F -8177 4E80 -8178 4E81 -8179 4E82 -817A 4E83 -817B 4E84 -817C 4E85 -C1CB 4E86 -817D 4E87 -D3E8 4E88 -D5F9 4E89 -817E 4E8A -CAC2 4E8B -B6FE 4E8C -D8A1 4E8D -D3DA 4E8E -BFF7 4E8F -8180 4E90 -D4C6 4E91 -BBA5 4E92 -D8C1 4E93 -CEE5 4E94 -BEAE 4E95 -8181 4E96 -8182 4E97 -D8A8 4E98 -8183 4E99 -D1C7 4E9A -D0A9 4E9B -8184 4E9C -8185 4E9D -8186 4E9E -D8BD 4E9F -D9EF 4EA0 -CDF6 4EA1 -BFBA 4EA2 -8187 4EA3 -BDBB 4EA4 -BAA5 4EA5 -D2E0 4EA6 -B2FA 4EA7 -BAE0 4EA8 -C4B6 4EA9 -8188 4EAA -CFED 4EAB -BEA9 4EAC -CDA4 4EAD -C1C1 4EAE -8189 4EAF -818A 4EB0 -818B 4EB1 -C7D7 4EB2 -D9F1 4EB3 -818C 4EB4 -D9F4 4EB5 -818D 4EB6 -818E 4EB7 -818F 4EB8 -8190 4EB9 -C8CB 4EBA -D8E9 4EBB -8191 4EBC -8192 4EBD -8193 4EBE -D2DA 4EBF -CAB2 4EC0 -C8CA 4EC1 -D8EC 4EC2 -D8EA 4EC3 -D8C6 4EC4 -BDF6 4EC5 -C6CD 4EC6 -B3F0 4EC7 -8194 4EC8 -D8EB 4EC9 -BDF1 4ECA -BDE9 4ECB -8195 4ECC -C8D4 4ECD -B4D3 4ECE -8196 4ECF -8197 4ED0 -C2D8 4ED1 -8198 4ED2 -B2D6 4ED3 -D7D0 4ED4 -CACB 4ED5 -CBFB 4ED6 -D5CC 4ED7 -B8B6 4ED8 -CFC9 4ED9 -8199 4EDA -819A 4EDB -819B 4EDC -D9DA 4EDD -D8F0 4EDE -C7AA 4EDF -819C 4EE0 -D8EE 4EE1 -819D 4EE2 -B4FA 4EE3 -C1EE 4EE4 -D2D4 4EE5 -819E 4EE6 -819F 4EE7 -D8ED 4EE8 -81A0 4EE9 -D2C7 4EEA -D8EF 4EEB -C3C7 4EEC -81A1 4EED -81A2 4EEE -81A3 4EEF -D1F6 4EF0 -81A4 4EF1 -D6D9 4EF2 -D8F2 4EF3 -81A5 4EF4 -D8F5 4EF5 -BCFE 4EF6 -BCDB 4EF7 -81A6 4EF8 -81A7 4EF9 -81A8 4EFA -C8CE 4EFB -81A9 4EFC -B7DD 4EFD -81AA 4EFE -B7C2 4EFF -81AB 4F00 -C6F3 4F01 -81AC 4F02 -81AD 4F03 -81AE 4F04 -81AF 4F05 -81B0 4F06 -81B1 4F07 -81B2 4F08 -D8F8 4F09 -D2C1 4F0A -81B3 4F0B -81B4 4F0C -CEE9 4F0D -BCBF 4F0E -B7FC 4F0F -B7A5 4F10 -D0DD 4F11 -81B5 4F12 -81B6 4F13 -81B7 4F14 -81B8 4F15 -81B9 4F16 -D6DA 4F17 -D3C5 4F18 -BBEF 4F19 -BBE1 4F1A -D8F1 4F1B -81BA 4F1C -81BB 4F1D -C9A1 4F1E -CEB0 4F1F -B4AB 4F20 -81BC 4F21 -D8F3 4F22 -81BD 4F23 -C9CB 4F24 -D8F6 4F25 -C2D7 4F26 -D8F7 4F27 -81BE 4F28 -81BF 4F29 -CEB1 4F2A -D8F9 4F2B -81C0 4F2C -81C1 4F2D -81C2 4F2E -B2AE 4F2F -B9C0 4F30 -81C3 4F31 -D9A3 4F32 -81C4 4F33 -B0E9 4F34 -81C5 4F35 -C1E6 4F36 -81C6 4F37 -C9EC 4F38 -81C7 4F39 -CBC5 4F3A -81C8 4F3B -CBC6 4F3C -D9A4 4F3D -81C9 4F3E -81CA 4F3F -81CB 4F40 -81CC 4F41 -81CD 4F42 -B5E8 4F43 -81CE 4F44 -81CF 4F45 -B5AB 4F46 -81D0 4F47 -81D1 4F48 -81D2 4F49 -81D3 4F4A -81D4 4F4B -81D5 4F4C -CEBB 4F4D -B5CD 4F4E -D7A1 4F4F -D7F4 4F50 -D3D3 4F51 -81D6 4F52 -CCE5 4F53 -81D7 4F54 -BACE 4F55 -81D8 4F56 -D9A2 4F57 -D9DC 4F58 -D3E0 4F59 -D8FD 4F5A -B7F0 4F5B -D7F7 4F5C -D8FE 4F5D -D8FA 4F5E -D9A1 4F5F -C4E3 4F60 -81D9 4F61 -81DA 4F62 -D3B6 4F63 -D8F4 4F64 -D9DD 4F65 -81DB 4F66 -D8FB 4F67 -81DC 4F68 -C5E5 4F69 -81DD 4F6A -81DE 4F6B -C0D0 4F6C -81DF 4F6D -81E0 4F6E -D1F0 4F6F -B0DB 4F70 -81E1 4F71 -81E2 4F72 -BCD1 4F73 -D9A6 4F74 -81E3 4F75 -D9A5 4F76 -81E4 4F77 -81E5 4F78 -81E6 4F79 -81E7 4F7A -D9AC 4F7B -D9AE 4F7C -81E8 4F7D -D9AB 4F7E -CAB9 4F7F -81E9 4F80 -81EA 4F81 -81EB 4F82 -D9A9 4F83 -D6B6 4F84 -81EC 4F85 -81ED 4F86 -81EE 4F87 -B3DE 4F88 -D9A8 4F89 -81EF 4F8A -C0FD 4F8B -81F0 4F8C -CACC 4F8D -81F1 4F8E -D9AA 4F8F -81F2 4F90 -D9A7 4F91 -81F3 4F92 -81F4 4F93 -D9B0 4F94 -81F5 4F95 -81F6 4F96 -B6B1 4F97 -81F7 4F98 -81F8 4F99 -81F9 4F9A -B9A9 4F9B -81FA 4F9C -D2C0 4F9D -81FB 4F9E -81FC 4F9F -CFC0 4FA0 -81FD 4FA1 -81FE 4FA2 -C2C2 4FA3 -8240 4FA4 -BDC4 4FA5 -D5EC 4FA6 -B2E0 4FA7 -C7C8 4FA8 -BFEB 4FA9 -D9AD 4FAA -8241 4FAB -D9AF 4FAC -8242 4FAD -CEEA 4FAE -BAEE 4FAF -8243 4FB0 -8244 4FB1 -8245 4FB2 -8246 4FB3 -8247 4FB4 -C7D6 4FB5 -8248 4FB6 -8249 4FB7 -824A 4FB8 -824B 4FB9 -824C 4FBA -824D 4FBB -824E 4FBC -824F 4FBD -8250 4FBE -B1E3 4FBF -8251 4FC0 -8252 4FC1 -8253 4FC2 -B4D9 4FC3 -B6ED 4FC4 -D9B4 4FC5 -8254 4FC6 -8255 4FC7 -8256 4FC8 -8257 4FC9 -BFA1 4FCA -8258 4FCB -8259 4FCC -825A 4FCD -D9DE 4FCE -C7CE 4FCF -C0FE 4FD0 -D9B8 4FD1 -825B 4FD2 -825C 4FD3 -825D 4FD4 -825E 4FD5 -825F 4FD6 -CBD7 4FD7 -B7FD 4FD8 -8260 4FD9 -D9B5 4FDA -8261 4FDB -D9B7 4FDC -B1A3 4FDD -D3E1 4FDE -D9B9 4FDF -8262 4FE0 -D0C5 4FE1 -8263 4FE2 -D9B6 4FE3 -8264 4FE4 -8265 4FE5 -D9B1 4FE6 -8266 4FE7 -D9B2 4FE8 -C1A9 4FE9 -D9B3 4FEA -8267 4FEB -8268 4FEC -BCF3 4FED -D0DE 4FEE -B8A9 4FEF -8269 4FF0 -BEE3 4FF1 -826A 4FF2 -D9BD 4FF3 -826B 4FF4 -826C 4FF5 -826D 4FF6 -826E 4FF7 -D9BA 4FF8 -826F 4FF9 -B0B3 4FFA -8270 4FFB -8271 4FFC -8272 4FFD -D9C2 4FFE -8273 4FFF -8274 5000 -8275 5001 -8276 5002 -8277 5003 -8278 5004 -8279 5005 -827A 5006 -827B 5007 -827C 5008 -827D 5009 -827E 500A -8280 500B -D9C4 500C -B1B6 500D -8281 500E -D9BF 500F -8282 5010 -8283 5011 -B5B9 5012 -8284 5013 -BEF3 5014 -8285 5015 -8286 5016 -8287 5017 -CCC8 5018 -BAF2 5019 -D2D0 501A -8288 501B -D9C3 501C -8289 501D -828A 501E -BDE8 501F -828B 5020 -B3AB 5021 -828C 5022 -828D 5023 -828E 5024 -D9C5 5025 -BEEB 5026 -828F 5027 -D9C6 5028 -D9BB 5029 -C4DF 502A -8290 502B -D9BE 502C -D9C1 502D -D9C0 502E -8291 502F -8292 5030 -8293 5031 -8294 5032 -8295 5033 -8296 5034 -8297 5035 -8298 5036 -8299 5037 -829A 5038 -829B 5039 -D5AE 503A -829C 503B -D6B5 503C -829D 503D -C7E3 503E -829E 503F -829F 5040 -82A0 5041 -82A1 5042 -D9C8 5043 -82A2 5044 -82A3 5045 -82A4 5046 -BCD9 5047 -D9CA 5048 -82A5 5049 -82A6 504A -82A7 504B -D9BC 504C -82A8 504D -D9CB 504E -C6AB 504F -82A9 5050 -82AA 5051 -82AB 5052 -82AC 5053 -82AD 5054 -D9C9 5055 -82AE 5056 -82AF 5057 -82B0 5058 -82B1 5059 -D7F6 505A -82B2 505B -CDA3 505C -82B3 505D -82B4 505E -82B5 505F -82B6 5060 -82B7 5061 -82B8 5062 -82B9 5063 -82BA 5064 -BDA1 5065 -82BB 5066 -82BC 5067 -82BD 5068 -82BE 5069 -82BF 506A -82C0 506B -D9CC 506C -82C1 506D -82C2 506E -82C3 506F -82C4 5070 -82C5 5071 -82C6 5072 -82C7 5073 -82C8 5074 -82C9 5075 -C5BC 5076 -CDB5 5077 -82CA 5078 -82CB 5079 -82CC 507A -D9CD 507B -82CD 507C -82CE 507D -D9C7 507E -B3A5 507F -BFFE 5080 -82CF 5081 -82D0 5082 -82D1 5083 -82D2 5084 -B8B5 5085 -82D3 5086 -82D4 5087 -C0FC 5088 -82D5 5089 -82D6 508A -82D7 508B -82D8 508C -B0F8 508D -82D9 508E -82DA 508F -82DB 5090 -82DC 5091 -82DD 5092 -82DE 5093 -82DF 5094 -82E0 5095 -82E1 5096 -82E2 5097 -82E3 5098 -82E4 5099 -82E5 509A -82E6 509B -82E7 509C -82E8 509D -82E9 509E -82EA 509F -82EB 50A0 -82EC 50A1 -82ED 50A2 -B4F6 50A3 -82EE 50A4 -D9CE 50A5 -82EF 50A6 -D9CF 50A7 -B4A2 50A8 -D9D0 50A9 -82F0 50AA -82F1 50AB -B4DF 50AC -82F2 50AD -82F3 50AE -82F4 50AF -82F5 50B0 -82F6 50B1 -B0C1 50B2 -82F7 50B3 -82F8 50B4 -82F9 50B5 -82FA 50B6 -82FB 50B7 -82FC 50B8 -82FD 50B9 -D9D1 50BA -C9B5 50BB -82FE 50BC -8340 50BD -8341 50BE -8342 50BF -8343 50C0 -8344 50C1 -8345 50C2 -8346 50C3 -8347 50C4 -8348 50C5 -8349 50C6 -834A 50C7 -834B 50C8 -834C 50C9 -834D 50CA -834E 50CB -834F 50CC -8350 50CD -8351 50CE -CFF1 50CF -8352 50D0 -8353 50D1 -8354 50D2 -8355 50D3 -8356 50D4 -8357 50D5 -D9D2 50D6 -8358 50D7 -8359 50D8 -835A 50D9 -C1C5 50DA -835B 50DB -835C 50DC -835D 50DD -835E 50DE -835F 50DF -8360 50E0 -8361 50E1 -8362 50E2 -8363 50E3 -8364 50E4 -8365 50E5 -D9D6 50E6 -C9AE 50E7 -8366 50E8 -8367 50E9 -8368 50EA -8369 50EB -D9D5 50EC -D9D4 50ED -D9D7 50EE -836A 50EF -836B 50F0 -836C 50F1 -836D 50F2 -CBDB 50F3 -836E 50F4 -BDA9 50F5 -836F 50F6 -8370 50F7 -8371 50F8 -8372 50F9 -8373 50FA -C6A7 50FB -8374 50FC -8375 50FD -8376 50FE -8377 50FF -8378 5100 -8379 5101 -837A 5102 -837B 5103 -837C 5104 -837D 5105 -D9D3 5106 -D9D8 5107 -837E 5108 -8380 5109 -8381 510A -D9D9 510B -8382 510C -8383 510D -8384 510E -8385 510F -8386 5110 -8387 5111 -C8E5 5112 -8388 5113 -8389 5114 -838A 5115 -838B 5116 -838C 5117 -838D 5118 -838E 5119 -838F 511A -8390 511B -8391 511C -8392 511D -8393 511E -8394 511F -8395 5120 -C0DC 5121 -8396 5122 -8397 5123 -8398 5124 -8399 5125 -839A 5126 -839B 5127 -839C 5128 -839D 5129 -839E 512A -839F 512B -83A0 512C -83A1 512D -83A2 512E -83A3 512F -83A4 5130 -83A5 5131 -83A6 5132 -83A7 5133 -83A8 5134 -83A9 5135 -83AA 5136 -83AB 5137 -83AC 5138 -83AD 5139 -83AE 513A -83AF 513B -83B0 513C -83B1 513D -83B2 513E -B6F9 513F -D8A3 5140 -D4CA 5141 -83B3 5142 -D4AA 5143 -D0D6 5144 -B3E4 5145 -D5D7 5146 -83B4 5147 -CFC8 5148 -B9E2 5149 -83B5 514A -BFCB 514B -83B6 514C -C3E2 514D -83B7 514E -83B8 514F -83B9 5150 -B6D2 5151 -83BA 5152 -83BB 5153 -CDC3 5154 -D9EE 5155 -D9F0 5156 -83BC 5157 -83BD 5158 -83BE 5159 -B5B3 515A -83BF 515B -B6B5 515C -83C0 515D -83C1 515E -83C2 515F -83C3 5160 -83C4 5161 -BEA4 5162 -83C5 5163 -83C6 5164 -C8EB 5165 -83C7 5166 -83C8 5167 -C8AB 5168 -83C9 5169 -83CA 516A -B0CB 516B -B9AB 516C -C1F9 516D -D9E2 516E -83CB 516F -C0BC 5170 -B9B2 5171 -83CC 5172 -B9D8 5173 -D0CB 5174 -B1F8 5175 -C6E4 5176 -BEDF 5177 -B5E4 5178 -D7C8 5179 -83CD 517A -D1F8 517B -BCE6 517C -CADE 517D -83CE 517E -83CF 517F -BCBD 5180 -D9E6 5181 -D8E7 5182 -83D0 5183 -83D1 5184 -C4DA 5185 -83D2 5186 -83D3 5187 -B8D4 5188 -C8BD 5189 -83D4 518A -83D5 518B -B2E1 518C -D4D9 518D -83D6 518E -83D7 518F -83D8 5190 -83D9 5191 -C3B0 5192 -83DA 5193 -83DB 5194 -C3E1 5195 -DAA2 5196 -C8DF 5197 -83DC 5198 -D0B4 5199 -83DD 519A -BEFC 519B -C5A9 519C -83DE 519D -83DF 519E -83E0 519F -B9DA 51A0 -83E1 51A1 -DAA3 51A2 -83E2 51A3 -D4A9 51A4 -DAA4 51A5 -83E3 51A6 -83E4 51A7 -83E5 51A8 -83E6 51A9 -83E7 51AA -D9FB 51AB -B6AC 51AC -83E8 51AD -83E9 51AE -B7EB 51AF -B1F9 51B0 -D9FC 51B1 -B3E5 51B2 -BEF6 51B3 -83EA 51B4 -BFF6 51B5 -D2B1 51B6 -C0E4 51B7 -83EB 51B8 -83EC 51B9 -83ED 51BA -B6B3 51BB -D9FE 51BC -D9FD 51BD -83EE 51BE -83EF 51BF -BEBB 51C0 -83F0 51C1 -83F1 51C2 -83F2 51C3 -C6E0 51C4 -83F3 51C5 -D7BC 51C6 -DAA1 51C7 -83F4 51C8 -C1B9 51C9 -83F5 51CA -B5F2 51CB -C1E8 51CC -83F6 51CD -83F7 51CE -BCF5 51CF -83F8 51D0 -B4D5 51D1 -83F9 51D2 -83FA 51D3 -83FB 51D4 -83FC 51D5 -83FD 51D6 -83FE 51D7 -8440 51D8 -8441 51D9 -8442 51DA -C1DD 51DB -8443 51DC -C4FD 51DD -8444 51DE -8445 51DF -BCB8 51E0 -B7B2 51E1 -8446 51E2 -8447 51E3 -B7EF 51E4 -8448 51E5 -8449 51E6 -844A 51E7 -844B 51E8 -844C 51E9 -844D 51EA -D9EC 51EB -844E 51EC -C6BE 51ED -844F 51EE -BFAD 51EF -BBCB 51F0 -8450 51F1 -8451 51F2 -B5CA 51F3 -8452 51F4 -DBC9 51F5 -D0D7 51F6 -8453 51F7 -CDB9 51F8 -B0BC 51F9 -B3F6 51FA -BBF7 51FB -DBCA 51FC -BAAF 51FD -8454 51FE -D4E4 51FF -B5B6 5200 -B5F3 5201 -D8D6 5202 -C8D0 5203 -8455 5204 -8456 5205 -B7D6 5206 -C7D0 5207 -D8D7 5208 -8457 5209 -BFAF 520A -8458 520B -8459 520C -DBBB 520D -D8D8 520E -845A 520F -845B 5210 -D0CC 5211 -BBAE 5212 -845C 5213 -845D 5214 -845E 5215 -EBBE 5216 -C1D0 5217 -C1F5 5218 -D4F2 5219 -B8D5 521A -B4B4 521B -845F 521C -B3F5 521D -8460 521E -8461 521F -C9BE 5220 -8462 5221 -8463 5222 -8464 5223 -C5D0 5224 -8465 5225 -8466 5226 -8467 5227 -C5D9 5228 -C0FB 5229 -8468 522A -B1F0 522B -8469 522C -D8D9 522D -B9CE 522E -846A 522F -B5BD 5230 -846B 5231 -846C 5232 -D8DA 5233 -846D 5234 -846E 5235 -D6C6 5236 -CBA2 5237 -C8AF 5238 -C9B2 5239 -B4CC 523A -BFCC 523B -846F 523C -B9F4 523D -8470 523E -D8DB 523F -D8DC 5240 -B6E7 5241 -BCC1 5242 -CCEA 5243 -8471 5244 -8472 5245 -8473 5246 -8474 5247 -8475 5248 -8476 5249 -CFF7 524A -8477 524B -D8DD 524C -C7B0 524D -8478 524E -8479 524F -B9D0 5250 -BDA3 5251 -847A 5252 -847B 5253 -CCDE 5254 -847C 5255 -C6CA 5256 -847D 5257 -847E 5258 -8480 5259 -8481 525A -8482 525B -D8E0 525C -8483 525D -D8DE 525E -8484 525F -8485 5260 -D8DF 5261 -8486 5262 -8487 5263 -8488 5264 -B0FE 5265 -8489 5266 -BEE7 5267 -848A 5268 -CAA3 5269 -BCF4 526A -848B 526B -848C 526C -848D 526D -848E 526E -B8B1 526F -848F 5270 -8490 5271 -B8EE 5272 -8491 5273 -8492 5274 -8493 5275 -8494 5276 -8495 5277 -8496 5278 -8497 5279 -8498 527A -8499 527B -849A 527C -D8E2 527D -849B 527E -BDCB 527F -849C 5280 -D8E4 5281 -D8E3 5282 -849D 5283 -849E 5284 -849F 5285 -84A0 5286 -84A1 5287 -C5FC 5288 -84A2 5289 -84A3 528A -84A4 528B -84A5 528C -84A6 528D -84A7 528E -84A8 528F -D8E5 5290 -84A9 5291 -84AA 5292 -D8E6 5293 -84AB 5294 -84AC 5295 -84AD 5296 -84AE 5297 -84AF 5298 -84B0 5299 -84B1 529A -C1A6 529B -84B2 529C -C8B0 529D -B0EC 529E -B9A6 529F -BCD3 52A0 -CEF1 52A1 -DBBD 52A2 -C1D3 52A3 -84B3 52A4 -84B4 52A5 -84B5 52A6 -84B6 52A7 -B6AF 52A8 -D6FA 52A9 -C5AC 52AA -BDD9 52AB -DBBE 52AC -DBBF 52AD -84B7 52AE -84B8 52AF -84B9 52B0 -C0F8 52B1 -BEA2 52B2 -C0CD 52B3 -84BA 52B4 -84BB 52B5 -84BC 52B6 -84BD 52B7 -84BE 52B8 -84BF 52B9 -84C0 52BA -84C1 52BB -84C2 52BC -84C3 52BD -DBC0 52BE -CAC6 52BF -84C4 52C0 -84C5 52C1 -84C6 52C2 -B2AA 52C3 -84C7 52C4 -84C8 52C5 -84C9 52C6 -D3C2 52C7 -84CA 52C8 -C3E3 52C9 -84CB 52CA -D1AB 52CB -84CC 52CC -84CD 52CD -84CE 52CE -84CF 52CF -DBC2 52D0 -84D0 52D1 -C0D5 52D2 -84D1 52D3 -84D2 52D4 -84D3 52D5 -DBC3 52D6 -84D4 52D7 -BFB1 52D8 -84D5 52D9 -84D6 52DA -84D7 52DB -84D8 52DC -84D9 52DD -84DA 52DE -C4BC 52DF -84DB 52E0 -84DC 52E1 -84DD 52E2 -84DE 52E3 -C7DA 52E4 -84DF 52E5 -84E0 52E6 -84E1 52E7 -84E2 52E8 -84E3 52E9 -84E4 52EA -84E5 52EB -84E6 52EC -84E7 52ED -84E8 52EE -84E9 52EF -DBC4 52F0 -84EA 52F1 -84EB 52F2 -84EC 52F3 -84ED 52F4 -84EE 52F5 -84EF 52F6 -84F0 52F7 -84F1 52F8 -D9E8 52F9 -C9D7 52FA -84F2 52FB -84F3 52FC -84F4 52FD -B9B4 52FE -CEF0 52FF -D4C8 5300 -84F5 5301 -84F6 5302 -84F7 5303 -84F8 5304 -B0FC 5305 -B4D2 5306 -84F9 5307 -D0D9 5308 -84FA 5309 -84FB 530A -84FC 530B -84FD 530C -D9E9 530D -84FE 530E -DECB 530F -D9EB 5310 -8540 5311 -8541 5312 -8542 5313 -8543 5314 -D8B0 5315 -BBAF 5316 -B1B1 5317 -8544 5318 -B3D7 5319 -D8CE 531A -8545 531B -8546 531C -D4D1 531D -8547 531E -8548 531F -BDB3 5320 -BFEF 5321 -8549 5322 -CFBB 5323 -854A 5324 -854B 5325 -D8D0 5326 -854C 5327 -854D 5328 -854E 5329 -B7CB 532A -854F 532B -8550 532C -8551 532D -D8D1 532E -8552 532F -8553 5330 -8554 5331 -8555 5332 -8556 5333 -8557 5334 -8558 5335 -8559 5336 -855A 5337 -855B 5338 -C6A5 5339 -C7F8 533A -D2BD 533B -855C 533C -855D 533D -D8D2 533E -C4E4 533F -855E 5340 -CAAE 5341 -855F 5342 -C7A7 5343 -8560 5344 -D8A6 5345 -8561 5346 -C9FD 5347 -CEE7 5348 -BBDC 5349 -B0EB 534A -8562 534B -8563 534C -8564 534D -BBAA 534E -D0AD 534F -8565 5350 -B1B0 5351 -D7E4 5352 -D7BF 5353 -8566 5354 -B5A5 5355 -C2F4 5356 -C4CF 5357 -8567 5358 -8568 5359 -B2A9 535A -8569 535B -B2B7 535C -856A 535D -B1E5 535E -DFB2 535F -D5BC 5360 -BFA8 5361 -C2AC 5362 -D8D5 5363 -C2B1 5364 -856B 5365 -D8D4 5366 -CED4 5367 -856C 5368 -DAE0 5369 -856D 536A -CEC0 536B -856E 536C -856F 536D -D8B4 536E -C3AE 536F -D3A1 5370 -CEA3 5371 -8570 5372 -BCB4 5373 -C8B4 5374 -C2D1 5375 -8571 5376 -BEED 5377 -D0B6 5378 -8572 5379 -DAE1 537A -8573 537B -8574 537C -8575 537D -8576 537E -C7E4 537F -8577 5380 -8578 5381 -B3A7 5382 -8579 5383 -B6F2 5384 -CCFC 5385 -C0FA 5386 -857A 5387 -857B 5388 -C0F7 5389 -857C 538A -D1B9 538B -D1E1 538C -D8C7 538D -857D 538E -857E 538F -8580 5390 -8581 5391 -8582 5392 -8583 5393 -8584 5394 -B2DE 5395 -8585 5396 -8586 5397 -C0E5 5398 -8587 5399 -BAF1 539A -8588 539B -8589 539C -D8C8 539D -858A 539E -D4AD 539F -858B 53A0 -858C 53A1 -CFE1 53A2 -D8C9 53A3 -858D 53A4 -D8CA 53A5 -CFC3 53A6 -858E 53A7 -B3F8 53A8 -BEC7 53A9 -858F 53AA -8590 53AB -8591 53AC -8592 53AD -D8CB 53AE -8593 53AF -8594 53B0 -8595 53B1 -8596 53B2 -8597 53B3 -8598 53B4 -8599 53B5 -DBCC 53B6 -859A 53B7 -859B 53B8 -859C 53B9 -859D 53BA -C8A5 53BB -859E 53BC -859F 53BD -85A0 53BE -CFD8 53BF -85A1 53C0 -C8FE 53C1 -B2CE 53C2 -85A2 53C3 -85A3 53C4 -85A4 53C5 -85A5 53C6 -85A6 53C7 -D3D6 53C8 -B2E6 53C9 -BCB0 53CA -D3D1 53CB -CBAB 53CC -B7B4 53CD -85A7 53CE -85A8 53CF -85A9 53D0 -B7A2 53D1 -85AA 53D2 -85AB 53D3 -CAE5 53D4 -85AC 53D5 -C8A1 53D6 -CADC 53D7 -B1E4 53D8 -D0F0 53D9 -85AD 53DA -C5D1 53DB -85AE 53DC -85AF 53DD -85B0 53DE -DBC5 53DF -B5FE 53E0 -85B1 53E1 -85B2 53E2 -BFDA 53E3 -B9C5 53E4 -BEE4 53E5 -C1ED 53E6 -85B3 53E7 -DFB6 53E8 -DFB5 53E9 -D6BB 53EA -BDD0 53EB -D5D9 53EC -B0C8 53ED -B6A3 53EE -BFC9 53EF -CCA8 53F0 -DFB3 53F1 -CAB7 53F2 -D3D2 53F3 -85B4 53F4 -D8CF 53F5 -D2B6 53F6 -BAC5 53F7 -CBBE 53F8 -CCBE 53F9 -85B5 53FA -DFB7 53FB -B5F0 53FC -DFB4 53FD -85B6 53FE -85B7 53FF -85B8 5400 -D3F5 5401 -85B9 5402 -B3D4 5403 -B8F7 5404 -85BA 5405 -DFBA 5406 -85BB 5407 -BACF 5408 -BCAA 5409 -B5F5 540A -85BC 540B -CDAC 540C -C3FB 540D -BAF3 540E -C0F4 540F -CDC2 5410 -CFF2 5411 -DFB8 5412 -CFC5 5413 -85BD 5414 -C2C0 5415 -DFB9 5416 -C2F0 5417 -85BE 5418 -85BF 5419 -85C0 541A -BEFD 541B -85C1 541C -C1DF 541D -CDCC 541E -D2F7 541F -B7CD 5420 -DFC1 5421 -85C2 5422 -DFC4 5423 -85C3 5424 -85C4 5425 -B7F1 5426 -B0C9 5427 -B6D6 5428 -B7D4 5429 -85C5 542A -BAAC 542B -CCFD 542C -BFD4 542D -CBB1 542E -C6F4 542F -85C6 5430 -D6A8 5431 -DFC5 5432 -85C7 5433 -CEE2 5434 -B3B3 5435 -85C8 5436 -85C9 5437 -CEFC 5438 -B4B5 5439 -85CA 543A -CEC7 543B -BAF0 543C -85CB 543D -CEE1 543E -85CC 543F -D1BD 5440 -85CD 5441 -85CE 5442 -DFC0 5443 -85CF 5444 -85D0 5445 -B4F4 5446 -85D1 5447 -B3CA 5448 -85D2 5449 -B8E6 544A -DFBB 544B -85D3 544C -85D4 544D -85D5 544E -85D6 544F -C4C5 5450 -85D7 5451 -DFBC 5452 -DFBD 5453 -DFBE 5454 -C5BB 5455 -DFBF 5456 -DFC2 5457 -D4B1 5458 -DFC3 5459 -85D8 545A -C7BA 545B -CED8 545C -85D9 545D -85DA 545E -85DB 545F -85DC 5460 -85DD 5461 -C4D8 5462 -85DE 5463 -DFCA 5464 -85DF 5465 -DFCF 5466 -85E0 5467 -D6DC 5468 -85E1 5469 -85E2 546A -85E3 546B -85E4 546C -85E5 546D -85E6 546E -85E7 546F -85E8 5470 -DFC9 5471 -DFDA 5472 -CEB6 5473 -85E9 5474 -BAC7 5475 -DFCE 5476 -DFC8 5477 -C5DE 5478 -85EA 5479 -85EB 547A -C9EB 547B -BAF4 547C -C3FC 547D -85EC 547E -85ED 547F -BED7 5480 -85EE 5481 -DFC6 5482 -85EF 5483 -DFCD 5484 -85F0 5485 -C5D8 5486 -85F1 5487 -85F2 5488 -85F3 5489 -85F4 548A -D5A6 548B -BACD 548C -85F5 548D -BECC 548E -D3BD 548F -B8C0 5490 -85F6 5491 -D6E4 5492 -85F7 5493 -DFC7 5494 -B9BE 5495 -BFA7 5496 -85F8 5497 -85F9 5498 -C1FC 5499 -DFCB 549A -DFCC 549B -85FA 549C -DFD0 549D -85FB 549E -85FC 549F -85FD 54A0 -85FE 54A1 -8640 54A2 -DFDB 54A3 -DFE5 54A4 -8641 54A5 -DFD7 54A6 -DFD6 54A7 -D7C9 54A8 -DFE3 54A9 -DFE4 54AA -E5EB 54AB -D2A7 54AC -DFD2 54AD -8642 54AE -BFA9 54AF -8643 54B0 -D4DB 54B1 -8644 54B2 -BFC8 54B3 -DFD4 54B4 -8645 54B5 -8646 54B6 -8647 54B7 -CFCC 54B8 -8648 54B9 -8649 54BA -DFDD 54BB -864A 54BC -D1CA 54BD -864B 54BE -DFDE 54BF -B0A7 54C0 -C6B7 54C1 -DFD3 54C2 -864C 54C3 -BAE5 54C4 -864D 54C5 -B6DF 54C6 -CDDB 54C7 -B9FE 54C8 -D4D5 54C9 -864E 54CA -864F 54CB -DFDF 54CC -CFEC 54CD -B0A5 54CE -DFE7 54CF -DFD1 54D0 -D1C6 54D1 -DFD5 54D2 -DFD8 54D3 -DFD9 54D4 -DFDC 54D5 -8650 54D6 -BBA9 54D7 -8651 54D8 -DFE0 54D9 -DFE1 54DA -8652 54DB -DFE2 54DC -DFE6 54DD -DFE8 54DE -D3B4 54DF -8653 54E0 -8654 54E1 -8655 54E2 -8656 54E3 -8657 54E4 -B8E7 54E5 -C5B6 54E6 -DFEA 54E7 -C9DA 54E8 -C1A8 54E9 -C4C4 54EA -8658 54EB -8659 54EC -BFDE 54ED -CFF8 54EE -865A 54EF -865B 54F0 -865C 54F1 -D5DC 54F2 -DFEE 54F3 -865D 54F4 -865E 54F5 -865F 54F6 -8660 54F7 -8661 54F8 -8662 54F9 -B2B8 54FA -8663 54FB -BADF 54FC -DFEC 54FD -8664 54FE -DBC1 54FF -8665 5500 -D1E4 5501 -8666 5502 -8667 5503 -8668 5504 -8669 5505 -CBF4 5506 -B4BD 5507 -866A 5508 -B0A6 5509 -866B 550A -866C 550B -866D 550C -866E 550D -866F 550E -DFF1 550F -CCC6 5510 -DFF2 5511 -8670 5512 -8671 5513 -DFED 5514 -8672 5515 -8673 5516 -8674 5517 -8675 5518 -8676 5519 -8677 551A -DFE9 551B -8678 551C -8679 551D -867A 551E -867B 551F -DFEB 5520 -867C 5521 -DFEF 5522 -DFF0 5523 -BBBD 5524 -867D 5525 -867E 5526 -DFF3 5527 -8680 5528 -8681 5529 -DFF4 552A -8682 552B -BBA3 552C -8683 552D -CADB 552E -CEA8 552F -E0A7 5530 -B3AA 5531 -8684 5532 -E0A6 5533 -8685 5534 -8686 5535 -8687 5536 -E0A1 5537 -8688 5538 -8689 5539 -868A 553A -868B 553B -DFFE 553C -868C 553D -CDD9 553E -DFFC 553F -868D 5540 -DFFA 5541 -868E 5542 -BFD0 5543 -D7C4 5544 -868F 5545 -C9CC 5546 -8690 5547 -8691 5548 -DFF8 5549 -B0A1 554A -8692 554B -8693 554C -8694 554D -8695 554E -8696 554F -DFFD 5550 -8697 5551 -8698 5552 -8699 5553 -869A 5554 -DFFB 5555 -E0A2 5556 -869B 5557 -869C 5558 -869D 5559 -869E 555A -869F 555B -E0A8 555C -86A0 555D -86A1 555E -86A2 555F -86A3 5560 -B7C8 5561 -86A4 5562 -86A5 5563 -C6A1 5564 -C9B6 5565 -C0B2 5566 -DFF5 5567 -86A6 5568 -86A7 5569 -C5BE 556A -86A8 556B -D8C4 556C -DFF9 556D -C4F6 556E -86A9 556F -86AA 5570 -86AB 5571 -86AC 5572 -86AD 5573 -86AE 5574 -E0A3 5575 -E0A4 5576 -E0A5 5577 -D0A5 5578 -86AF 5579 -86B0 557A -E0B4 557B -CCE4 557C -86B1 557D -E0B1 557E -86B2 557F -BFA6 5580 -E0AF 5581 -CEB9 5582 -E0AB 5583 -C9C6 5584 -86B3 5585 -86B4 5586 -C0AE 5587 -E0AE 5588 -BAED 5589 -BAB0 558A -E0A9 558B -86B5 558C -86B6 558D -86B7 558E -DFF6 558F -86B8 5590 -E0B3 5591 -86B9 5592 -86BA 5593 -E0B8 5594 -86BB 5595 -86BC 5596 -86BD 5597 -B4AD 5598 -E0B9 5599 -86BE 559A -86BF 559B -CFB2 559C -BAC8 559D -86C0 559E -E0B0 559F -86C1 55A0 -86C2 55A1 -86C3 55A2 -86C4 55A3 -86C5 55A4 -86C6 55A5 -86C7 55A6 -D0FA 55A7 -86C8 55A8 -86C9 55A9 -86CA 55AA -86CB 55AB -86CC 55AC -86CD 55AD -86CE 55AE -86CF 55AF -86D0 55B0 -E0AC 55B1 -86D1 55B2 -D4FB 55B3 -86D2 55B4 -DFF7 55B5 -86D3 55B6 -C5E7 55B7 -86D4 55B8 -E0AD 55B9 -86D5 55BA -D3F7 55BB -86D6 55BC -E0B6 55BD -E0B7 55BE -86D7 55BF -86D8 55C0 -86D9 55C1 -86DA 55C2 -86DB 55C3 -E0C4 55C4 -D0E1 55C5 -86DC 55C6 -86DD 55C7 -86DE 55C8 -E0BC 55C9 -86DF 55CA -86E0 55CB -E0C9 55CC -E0CA 55CD -86E1 55CE -86E2 55CF -86E3 55D0 -E0BE 55D1 -E0AA 55D2 -C9A4 55D3 -E0C1 55D4 -86E4 55D5 -E0B2 55D6 -86E5 55D7 -86E6 55D8 -86E7 55D9 -86E8 55DA -86E9 55DB -CAC8 55DC -E0C3 55DD -86EA 55DE -E0B5 55DF -86EB 55E0 -CECB 55E1 -86EC 55E2 -CBC3 55E3 -E0CD 55E4 -E0C6 55E5 -E0C2 55E6 -86ED 55E7 -E0CB 55E8 -86EE 55E9 -E0BA 55EA -E0BF 55EB -E0C0 55EC -86EF 55ED -86F0 55EE -E0C5 55EF -86F1 55F0 -86F2 55F1 -E0C7 55F2 -E0C8 55F3 -86F3 55F4 -E0CC 55F5 -86F4 55F6 -E0BB 55F7 -86F5 55F8 -86F6 55F9 -86F7 55FA -86F8 55FB -86F9 55FC -CBD4 55FD -E0D5 55FE -86FA 55FF -E0D6 5600 -E0D2 5601 -86FB 5602 -86FC 5603 -86FD 5604 -86FE 5605 -8740 5606 -8741 5607 -E0D0 5608 -BCCE 5609 -8742 560A -8743 560B -E0D1 560C -8744 560D -B8C2 560E -D8C5 560F -8745 5610 -8746 5611 -8747 5612 -8748 5613 -8749 5614 -874A 5615 -874B 5616 -874C 5617 -D0EA 5618 -874D 5619 -874E 561A -C2EF 561B -874F 561C -8750 561D -E0CF 561E -E0BD 561F -8751 5620 -8752 5621 -8753 5622 -E0D4 5623 -E0D3 5624 -8754 5625 -8755 5626 -E0D7 5627 -8756 5628 -8757 5629 -8758 562A -8759 562B -E0DC 562C -E0D8 562D -875A 562E -875B 562F -875C 5630 -D6F6 5631 -B3B0 5632 -875D 5633 -D7EC 5634 -875E 5635 -CBBB 5636 -875F 5637 -8760 5638 -E0DA 5639 -8761 563A -CEFB 563B -8762 563C -8763 563D -8764 563E -BAD9 563F -8765 5640 -8766 5641 -8767 5642 -8768 5643 -8769 5644 -876A 5645 -876B 5646 -876C 5647 -876D 5648 -876E 5649 -876F 564A -8770 564B -E0E1 564C -E0DD 564D -D2AD 564E -8771 564F -8772 5650 -8773 5651 -8774 5652 -8775 5653 -E0E2 5654 -8776 5655 -8777 5656 -E0DB 5657 -E0D9 5658 -E0DF 5659 -8778 565A -8779 565B -E0E0 565C -877A 565D -877B 565E -877C 565F -877D 5660 -877E 5661 -E0DE 5662 -8780 5663 -E0E4 5664 -8781 5665 -8782 5666 -8783 5667 -C6F7 5668 -D8AC 5669 -D4EB 566A -E0E6 566B -CAC9 566C -8784 566D -8785 566E -8786 566F -8787 5670 -E0E5 5671 -8788 5672 -8789 5673 -878A 5674 -878B 5675 -B8C1 5676 -878C 5677 -878D 5678 -878E 5679 -878F 567A -E0E7 567B -E0E8 567C -8790 567D -8791 567E -8792 567F -8793 5680 -8794 5681 -8795 5682 -8796 5683 -8797 5684 -E0E9 5685 -E0E3 5686 -8798 5687 -8799 5688 -879A 5689 -879B 568A -879C 568B -879D 568C -879E 568D -BABF 568E -CCE7 568F -879F 5690 -87A0 5691 -87A1 5692 -E0EA 5693 -87A2 5694 -87A3 5695 -87A4 5696 -87A5 5697 -87A6 5698 -87A7 5699 -87A8 569A -87A9 569B -87AA 569C -87AB 569D -87AC 569E -87AD 569F -87AE 56A0 -87AF 56A1 -87B0 56A2 -CFF9 56A3 -87B1 56A4 -87B2 56A5 -87B3 56A6 -87B4 56A7 -87B5 56A8 -87B6 56A9 -87B7 56AA -87B8 56AB -87B9 56AC -87BA 56AD -87BB 56AE -E0EB 56AF -87BC 56B0 -87BD 56B1 -87BE 56B2 -87BF 56B3 -87C0 56B4 -87C1 56B5 -87C2 56B6 -C8C2 56B7 -87C3 56B8 -87C4 56B9 -87C5 56BA -87C6 56BB -BDC0 56BC -87C7 56BD -87C8 56BE -87C9 56BF -87CA 56C0 -87CB 56C1 -87CC 56C2 -87CD 56C3 -87CE 56C4 -87CF 56C5 -87D0 56C6 -87D1 56C7 -87D2 56C8 -87D3 56C9 -C4D2 56CA -87D4 56CB -87D5 56CC -87D6 56CD -87D7 56CE -87D8 56CF -87D9 56D0 -87DA 56D1 -87DB 56D2 -87DC 56D3 -E0EC 56D4 -87DD 56D5 -87DE 56D6 -E0ED 56D7 -87DF 56D8 -87E0 56D9 -C7F4 56DA -CBC4 56DB -87E1 56DC -E0EE 56DD -BBD8 56DE -D8B6 56DF -D2F2 56E0 -E0EF 56E1 -CDC5 56E2 -87E2 56E3 -B6DA 56E4 -87E3 56E5 -87E4 56E6 -87E5 56E7 -87E6 56E8 -87E7 56E9 -87E8 56EA -E0F1 56EB -87E9 56EC -D4B0 56ED -87EA 56EE -87EB 56EF -C0A7 56F0 -B4D1 56F1 -87EC 56F2 -87ED 56F3 -CEA7 56F4 -E0F0 56F5 -87EE 56F6 -87EF 56F7 -87F0 56F8 -E0F2 56F9 -B9CC 56FA -87F1 56FB -87F2 56FC -B9FA 56FD -CDBC 56FE -E0F3 56FF -87F3 5700 -87F4 5701 -87F5 5702 -C6D4 5703 -E0F4 5704 -87F6 5705 -D4B2 5706 -87F7 5707 -C8A6 5708 -E0F6 5709 -E0F5 570A -87F8 570B -87F9 570C -87FA 570D -87FB 570E -87FC 570F -87FD 5710 -87FE 5711 -8840 5712 -8841 5713 -8842 5714 -8843 5715 -8844 5716 -8845 5717 -8846 5718 -8847 5719 -8848 571A -8849 571B -E0F7 571C -884A 571D -884B 571E -CDC1 571F -884C 5720 -884D 5721 -884E 5722 -CAA5 5723 -884F 5724 -8850 5725 -8851 5726 -8852 5727 -D4DA 5728 -DBD7 5729 -DBD9 572A -8853 572B -DBD8 572C -B9E7 572D -DBDC 572E -DBDD 572F -B5D8 5730 -8854 5731 -8855 5732 -DBDA 5733 -8856 5734 -8857 5735 -8858 5736 -8859 5737 -885A 5738 -DBDB 5739 -B3A1 573A -DBDF 573B -885B 573C -885C 573D -BBF8 573E -885D 573F -D6B7 5740 -885E 5741 -DBE0 5742 -885F 5743 -8860 5744 -8861 5745 -8862 5746 -BEF9 5747 -8863 5748 -8864 5749 -B7BB 574A -8865 574B -DBD0 574C -CCAE 574D -BFB2 574E -BBB5 574F -D7F8 5750 -BFD3 5751 -8866 5752 -8867 5753 -8868 5754 -8869 5755 -886A 5756 -BFE9 5757 -886B 5758 -886C 5759 -BCE1 575A -CCB3 575B -DBDE 575C -B0D3 575D -CEEB 575E -B7D8 575F -D7B9 5760 -C6C2 5761 -886D 5762 -886E 5763 -C0A4 5764 -886F 5765 -CCB9 5766 -8870 5767 -DBE7 5768 -DBE1 5769 -C6BA 576A -DBE3 576B -8871 576C -DBE8 576D -8872 576E -C5F7 576F -8873 5770 -8874 5771 -8875 5772 -DBEA 5773 -8876 5774 -8877 5775 -DBE9 5776 -BFC0 5777 -8878 5778 -8879 5779 -887A 577A -DBE6 577B -DBE5 577C -887B 577D -887C 577E -887D 577F -887E 5780 -8880 5781 -B4B9 5782 -C0AC 5783 -C2A2 5784 -DBE2 5785 -DBE4 5786 -8881 5787 -8882 5788 -8883 5789 -8884 578A -D0CD 578B -DBED 578C -8885 578D -8886 578E -8887 578F -8888 5790 -8889 5791 -C0DD 5792 -DBF2 5793 -888A 5794 -888B 5795 -888C 5796 -888D 5797 -888E 5798 -888F 5799 -8890 579A -B6E2 579B -8891 579C -8892 579D -8893 579E -8894 579F -DBF3 57A0 -DBD2 57A1 -B9B8 57A2 -D4AB 57A3 -DBEC 57A4 -8895 57A5 -BFD1 57A6 -DBF0 57A7 -8896 57A8 -DBD1 57A9 -8897 57AA -B5E6 57AB -8898 57AC -DBEB 57AD -BFE5 57AE -8899 57AF -889A 57B0 -889B 57B1 -DBEE 57B2 -889C 57B3 -DBF1 57B4 -889D 57B5 -889E 57B6 -889F 57B7 -DBF9 57B8 -88A0 57B9 -88A1 57BA -88A2 57BB -88A3 57BC -88A4 57BD -88A5 57BE -88A6 57BF -88A7 57C0 -88A8 57C1 -B9A1 57C2 -B0A3 57C3 -88A9 57C4 -88AA 57C5 -88AB 57C6 -88AC 57C7 -88AD 57C8 -88AE 57C9 -88AF 57CA -C2F1 57CB -88B0 57CC -88B1 57CD -B3C7 57CE -DBEF 57CF -88B2 57D0 -88B3 57D1 -DBF8 57D2 -88B4 57D3 -C6D2 57D4 -DBF4 57D5 -88B5 57D6 -88B6 57D7 -DBF5 57D8 -DBF7 57D9 -DBF6 57DA -88B7 57DB -88B8 57DC -DBFE 57DD -88B9 57DE -D3F2 57DF -B2BA 57E0 -88BA 57E1 -88BB 57E2 -88BC 57E3 -DBFD 57E4 -88BD 57E5 -88BE 57E6 -88BF 57E7 -88C0 57E8 -88C1 57E9 -88C2 57EA -88C3 57EB -88C4 57EC -DCA4 57ED -88C5 57EE -DBFB 57EF -88C6 57F0 -88C7 57F1 -88C8 57F2 -88C9 57F3 -DBFA 57F4 -88CA 57F5 -88CB 57F6 -88CC 57F7 -DBFC 57F8 -C5E0 57F9 -BBF9 57FA -88CD 57FB -88CE 57FC -DCA3 57FD -88CF 57FE -88D0 57FF -DCA5 5800 -88D1 5801 -CCC3 5802 -88D2 5803 -88D3 5804 -88D4 5805 -B6D1 5806 -DDC0 5807 -88D5 5808 -88D6 5809 -88D7 580A -DCA1 580B -88D8 580C -DCA2 580D -88D9 580E -88DA 580F -88DB 5810 -C7B5 5811 -88DC 5812 -88DD 5813 -88DE 5814 -B6E9 5815 -88DF 5816 -88E0 5817 -88E1 5818 -DCA7 5819 -88E2 581A -88E3 581B -88E4 581C -88E5 581D -DCA6 581E -88E6 581F -DCA9 5820 -B1A4 5821 -88E7 5822 -88E8 5823 -B5CC 5824 -88E9 5825 -88EA 5826 -88EB 5827 -88EC 5828 -88ED 5829 -BFB0 582A -88EE 582B -88EF 582C -88F0 582D -88F1 582E -88F2 582F -D1DF 5830 -88F3 5831 -88F4 5832 -88F5 5833 -88F6 5834 -B6C2 5835 -88F7 5836 -88F8 5837 -88F9 5838 -88FA 5839 -88FB 583A -88FC 583B -88FD 583C -88FE 583D -8940 583E -8941 583F -8942 5840 -8943 5841 -8944 5842 -8945 5843 -DCA8 5844 -8946 5845 -8947 5846 -8948 5847 -8949 5848 -894A 5849 -894B 584A -894C 584B -CBFA 584C -EBF3 584D -894D 584E -894E 584F -894F 5850 -CBDC 5851 -8950 5852 -8951 5853 -CBFE 5854 -8952 5855 -8953 5856 -8954 5857 -CCC1 5858 -8955 5859 -8956 585A -8957 585B -8958 585C -8959 585D -C8FB 585E -895A 585F -895B 5860 -895C 5861 -895D 5862 -895E 5863 -895F 5864 -DCAA 5865 -8960 5866 -8961 5867 -8962 5868 -8963 5869 -8964 586A -CCEE 586B -DCAB 586C -8965 586D -8966 586E -8967 586F -8968 5870 -8969 5871 -896A 5872 -896B 5873 -896C 5874 -896D 5875 -896E 5876 -896F 5877 -8970 5878 -8971 5879 -8972 587A -8973 587B -8974 587C -8975 587D -DBD3 587E -8976 587F -DCAF 5880 -DCAC 5881 -8977 5882 -BEB3 5883 -8978 5884 -CAFB 5885 -8979 5886 -897A 5887 -897B 5888 -DCAD 5889 -897C 588A -897D 588B -897E 588C -8980 588D -8981 588E -8982 588F -8983 5890 -8984 5891 -C9CA 5892 -C4B9 5893 -8985 5894 -8986 5895 -8987 5896 -8988 5897 -8989 5898 -C7BD 5899 -DCAE 589A -898A 589B -898B 589C -898C 589D -D4F6 589E -D0E6 589F -898D 58A0 -898E 58A1 -898F 58A2 -8990 58A3 -8991 58A4 -8992 58A5 -8993 58A6 -8994 58A7 -C4AB 58A8 -B6D5 58A9 -8995 58AA -8996 58AB -8997 58AC -8998 58AD -8999 58AE -899A 58AF -899B 58B0 -899C 58B1 -899D 58B2 -899E 58B3 -899F 58B4 -89A0 58B5 -89A1 58B6 -89A2 58B7 -89A3 58B8 -89A4 58B9 -89A5 58BA -89A6 58BB -DBD4 58BC -89A7 58BD -89A8 58BE -89A9 58BF -89AA 58C0 -B1DA 58C1 -89AB 58C2 -89AC 58C3 -89AD 58C4 -DBD5 58C5 -89AE 58C6 -89AF 58C7 -89B0 58C8 -89B1 58C9 -89B2 58CA -89B3 58CB -89B4 58CC -89B5 58CD -89B6 58CE -89B7 58CF -89B8 58D0 -DBD6 58D1 -89B9 58D2 -89BA 58D3 -89BB 58D4 -BABE 58D5 -89BC 58D6 -89BD 58D7 -89BE 58D8 -89BF 58D9 -89C0 58DA -89C1 58DB -89C2 58DC -89C3 58DD -89C4 58DE -89C5 58DF -89C6 58E0 -89C7 58E1 -89C8 58E2 -89C9 58E3 -C8C0 58E4 -89CA 58E5 -89CB 58E6 -89CC 58E7 -89CD 58E8 -89CE 58E9 -89CF 58EA -CABF 58EB -C8C9 58EC -89D0 58ED -D7B3 58EE -89D1 58EF -C9F9 58F0 -89D2 58F1 -89D3 58F2 -BFC7 58F3 -89D4 58F4 -89D5 58F5 -BAF8 58F6 -89D6 58F7 -89D7 58F8 -D2BC 58F9 -89D8 58FA -89D9 58FB -89DA 58FC -89DB 58FD -89DC 58FE -89DD 58FF -89DE 5900 -89DF 5901 -E2BA 5902 -89E0 5903 -B4A6 5904 -89E1 5905 -89E2 5906 -B1B8 5907 -89E3 5908 -89E4 5909 -89E5 590A -89E6 590B -89E7 590C -B8B4 590D -89E8 590E -CFC4 590F -89E9 5910 -89EA 5911 -89EB 5912 -89EC 5913 -D9E7 5914 -CFA6 5915 -CDE2 5916 -89ED 5917 -89EE 5918 -D9ED 5919 -B6E0 591A -89EF 591B -D2B9 591C -89F0 591D -89F1 591E -B9BB 591F -89F2 5920 -89F3 5921 -89F4 5922 -89F5 5923 -E2B9 5924 -E2B7 5925 -89F6 5926 -B4F3 5927 -89F7 5928 -CCEC 5929 -CCAB 592A -B7F2 592B -89F8 592C -D8B2 592D -D1EB 592E -BABB 592F -89F9 5930 -CAA7 5931 -89FA 5932 -89FB 5933 -CDB7 5934 -89FC 5935 -89FD 5936 -D2C4 5937 -BFE4 5938 -BCD0 5939 -B6E1 593A -89FE 593B -DEC5 593C -8A40 593D -8A41 593E -8A42 593F -8A43 5940 -DEC6 5941 -DBBC 5942 -8A44 5943 -D1D9 5944 -8A45 5945 -8A46 5946 -C6E6 5947 -C4CE 5948 -B7EE 5949 -8A47 594A -B7DC 594B -8A48 594C -8A49 594D -BFFC 594E -D7E0 594F -8A4A 5950 -C6F5 5951 -8A4B 5952 -8A4C 5953 -B1BC 5954 -DEC8 5955 -BDB1 5956 -CCD7 5957 -DECA 5958 -8A4D 5959 -DEC9 595A -8A4E 595B -8A4F 595C -8A50 595D -8A51 595E -8A52 595F -B5EC 5960 -8A53 5961 -C9DD 5962 -8A54 5963 -8A55 5964 -B0C2 5965 -8A56 5966 -8A57 5967 -8A58 5968 -8A59 5969 -8A5A 596A -8A5B 596B -8A5C 596C -8A5D 596D -8A5E 596E -8A5F 596F -8A60 5970 -8A61 5971 -8A62 5972 -C5AE 5973 -C5AB 5974 -8A63 5975 -C4CC 5976 -8A64 5977 -BCE9 5978 -CBFD 5979 -8A65 597A -8A66 597B -8A67 597C -BAC3 597D -8A68 597E -8A69 597F -8A6A 5980 -E5F9 5981 -C8E7 5982 -E5FA 5983 -CDFD 5984 -8A6B 5985 -D7B1 5986 -B8BE 5987 -C2E8 5988 -8A6C 5989 -C8D1 598A -8A6D 598B -8A6E 598C -E5FB 598D -8A6F 598E -8A70 598F -8A71 5990 -8A72 5991 -B6CA 5992 -BCCB 5993 -8A73 5994 -8A74 5995 -D1FD 5996 -E6A1 5997 -8A75 5998 -C3EE 5999 -8A76 599A -8A77 599B -8A78 599C -8A79 599D -E6A4 599E -8A7A 599F -8A7B 59A0 -8A7C 59A1 -8A7D 59A2 -E5FE 59A3 -E6A5 59A4 -CDD7 59A5 -8A7E 59A6 -8A80 59A7 -B7C1 59A8 -E5FC 59A9 -E5FD 59AA -E6A3 59AB -8A81 59AC -8A82 59AD -C4DD 59AE -E6A8 59AF -8A83 59B0 -8A84 59B1 -E6A7 59B2 -8A85 59B3 -8A86 59B4 -8A87 59B5 -8A88 59B6 -8A89 59B7 -8A8A 59B8 -C3C3 59B9 -8A8B 59BA -C6DE 59BB -8A8C 59BC -8A8D 59BD -E6AA 59BE -8A8E 59BF -8A8F 59C0 -8A90 59C1 -8A91 59C2 -8A92 59C3 -8A93 59C4 -8A94 59C5 -C4B7 59C6 -8A95 59C7 -8A96 59C8 -8A97 59C9 -E6A2 59CA -CABC 59CB -8A98 59CC -8A99 59CD -8A9A 59CE -8A9B 59CF -BDE3 59D0 -B9C3 59D1 -E6A6 59D2 -D0D5 59D3 -CEAF 59D4 -8A9C 59D5 -8A9D 59D6 -E6A9 59D7 -E6B0 59D8 -8A9E 59D9 -D2A6 59DA -8A9F 59DB -BDAA 59DC -E6AD 59DD -8AA0 59DE -8AA1 59DF -8AA2 59E0 -8AA3 59E1 -8AA4 59E2 -E6AF 59E3 -8AA5 59E4 -C0D1 59E5 -8AA6 59E6 -8AA7 59E7 -D2CC 59E8 -8AA8 59E9 -8AA9 59EA -8AAA 59EB -BCA7 59EC -8AAB 59ED -8AAC 59EE -8AAD 59EF -8AAE 59F0 -8AAF 59F1 -8AB0 59F2 -8AB1 59F3 -8AB2 59F4 -8AB3 59F5 -8AB4 59F6 -8AB5 59F7 -8AB6 59F8 -E6B1 59F9 -8AB7 59FA -D2F6 59FB -8AB8 59FC -8AB9 59FD -8ABA 59FE -D7CB 59FF -8ABB 5A00 -CDFE 5A01 -8ABC 5A02 -CDDE 5A03 -C2A6 5A04 -E6AB 5A05 -E6AC 5A06 -BDBF 5A07 -E6AE 5A08 -E6B3 5A09 -8ABD 5A0A -8ABE 5A0B -E6B2 5A0C -8ABF 5A0D -8AC0 5A0E -8AC1 5A0F -8AC2 5A10 -E6B6 5A11 -8AC3 5A12 -E6B8 5A13 -8AC4 5A14 -8AC5 5A15 -8AC6 5A16 -8AC7 5A17 -C4EF 5A18 -8AC8 5A19 -8AC9 5A1A -8ACA 5A1B -C4C8 5A1C -8ACB 5A1D -8ACC 5A1E -BEEA 5A1F -C9EF 5A20 -8ACD 5A21 -8ACE 5A22 -E6B7 5A23 -8ACF 5A24 -B6F0 5A25 -8AD0 5A26 -8AD1 5A27 -8AD2 5A28 -C3E4 5A29 -8AD3 5A2A -8AD4 5A2B -8AD5 5A2C -8AD6 5A2D -8AD7 5A2E -8AD8 5A2F -8AD9 5A30 -D3E9 5A31 -E6B4 5A32 -8ADA 5A33 -E6B5 5A34 -8ADB 5A35 -C8A2 5A36 -8ADC 5A37 -8ADD 5A38 -8ADE 5A39 -8ADF 5A3A -8AE0 5A3B -E6BD 5A3C -8AE1 5A3D -8AE2 5A3E -8AE3 5A3F -E6B9 5A40 -8AE4 5A41 -8AE5 5A42 -8AE6 5A43 -8AE7 5A44 -8AE8 5A45 -C6C5 5A46 -8AE9 5A47 -8AEA 5A48 -CDF1 5A49 -E6BB 5A4A -8AEB 5A4B -8AEC 5A4C -8AED 5A4D -8AEE 5A4E -8AEF 5A4F -8AF0 5A50 -8AF1 5A51 -8AF2 5A52 -8AF3 5A53 -8AF4 5A54 -E6BC 5A55 -8AF5 5A56 -8AF6 5A57 -8AF7 5A58 -8AF8 5A59 -BBE9 5A5A -8AF9 5A5B -8AFA 5A5C -8AFB 5A5D -8AFC 5A5E -8AFD 5A5F -8AFE 5A60 -8B40 5A61 -E6BE 5A62 -8B41 5A63 -8B42 5A64 -8B43 5A65 -8B44 5A66 -E6BA 5A67 -8B45 5A68 -8B46 5A69 -C0B7 5A6A -8B47 5A6B -8B48 5A6C -8B49 5A6D -8B4A 5A6E -8B4B 5A6F -8B4C 5A70 -8B4D 5A71 -8B4E 5A72 -8B4F 5A73 -D3A4 5A74 -E6BF 5A75 -C9F4 5A76 -E6C3 5A77 -8B50 5A78 -8B51 5A79 -E6C4 5A7A -8B52 5A7B -8B53 5A7C -8B54 5A7D -8B55 5A7E -D0F6 5A7F -8B56 5A80 -8B57 5A81 -8B58 5A82 -8B59 5A83 -8B5A 5A84 -8B5B 5A85 -8B5C 5A86 -8B5D 5A87 -8B5E 5A88 -8B5F 5A89 -8B60 5A8A -8B61 5A8B -8B62 5A8C -8B63 5A8D -8B64 5A8E -8B65 5A8F -8B66 5A90 -8B67 5A91 -C3BD 5A92 -8B68 5A93 -8B69 5A94 -8B6A 5A95 -8B6B 5A96 -8B6C 5A97 -8B6D 5A98 -8B6E 5A99 -C3C4 5A9A -E6C2 5A9B -8B6F 5A9C -8B70 5A9D -8B71 5A9E -8B72 5A9F -8B73 5AA0 -8B74 5AA1 -8B75 5AA2 -8B76 5AA3 -8B77 5AA4 -8B78 5AA5 -8B79 5AA6 -8B7A 5AA7 -8B7B 5AA8 -8B7C 5AA9 -E6C1 5AAA -8B7D 5AAB -8B7E 5AAC -8B80 5AAD -8B81 5AAE -8B82 5AAF -8B83 5AB0 -8B84 5AB1 -E6C7 5AB2 -CFB1 5AB3 -8B85 5AB4 -EBF4 5AB5 -8B86 5AB6 -8B87 5AB7 -E6CA 5AB8 -8B88 5AB9 -8B89 5ABA -8B8A 5ABB -8B8B 5ABC -8B8C 5ABD -E6C5 5ABE -8B8D 5ABF -8B8E 5AC0 -BCDE 5AC1 -C9A9 5AC2 -8B8F 5AC3 -8B90 5AC4 -8B91 5AC5 -8B92 5AC6 -8B93 5AC7 -8B94 5AC8 -BCB5 5AC9 -8B95 5ACA -8B96 5ACB -CFD3 5ACC -8B97 5ACD -8B98 5ACE -8B99 5ACF -8B9A 5AD0 -8B9B 5AD1 -E6C8 5AD2 -8B9C 5AD3 -E6C9 5AD4 -8B9D 5AD5 -E6CE 5AD6 -8B9E 5AD7 -E6D0 5AD8 -8B9F 5AD9 -8BA0 5ADA -8BA1 5ADB -E6D1 5ADC -8BA2 5ADD -8BA3 5ADE -8BA4 5ADF -E6CB 5AE0 -B5D5 5AE1 -8BA5 5AE2 -E6CC 5AE3 -8BA6 5AE4 -8BA7 5AE5 -E6CF 5AE6 -8BA8 5AE7 -8BA9 5AE8 -C4DB 5AE9 -8BAA 5AEA -E6C6 5AEB -8BAB 5AEC -8BAC 5AED -8BAD 5AEE -8BAE 5AEF -8BAF 5AF0 -E6CD 5AF1 -8BB0 5AF2 -8BB1 5AF3 -8BB2 5AF4 -8BB3 5AF5 -8BB4 5AF6 -8BB5 5AF7 -8BB6 5AF8 -8BB7 5AF9 -8BB8 5AFA -8BB9 5AFB -8BBA 5AFC -8BBB 5AFD -8BBC 5AFE -8BBD 5AFF -8BBE 5B00 -8BBF 5B01 -8BC0 5B02 -8BC1 5B03 -8BC2 5B04 -8BC3 5B05 -8BC4 5B06 -8BC5 5B07 -8BC6 5B08 -E6D2 5B09 -8BC7 5B0A -8BC8 5B0B -8BC9 5B0C -8BCA 5B0D -8BCB 5B0E -8BCC 5B0F -8BCD 5B10 -8BCE 5B11 -8BCF 5B12 -8BD0 5B13 -8BD1 5B14 -8BD2 5B15 -E6D4 5B16 -E6D3 5B17 -8BD3 5B18 -8BD4 5B19 -8BD5 5B1A -8BD6 5B1B -8BD7 5B1C -8BD8 5B1D -8BD9 5B1E -8BDA 5B1F -8BDB 5B20 -8BDC 5B21 -8BDD 5B22 -8BDE 5B23 -8BDF 5B24 -8BE0 5B25 -8BE1 5B26 -8BE2 5B27 -8BE3 5B28 -8BE4 5B29 -8BE5 5B2A -8BE6 5B2B -8BE7 5B2C -8BE8 5B2D -8BE9 5B2E -8BEA 5B2F -8BEB 5B30 -8BEC 5B31 -E6D5 5B32 -8BED 5B33 -D9F8 5B34 -8BEE 5B35 -8BEF 5B36 -E6D6 5B37 -8BF0 5B38 -8BF1 5B39 -8BF2 5B3A -8BF3 5B3B -8BF4 5B3C -8BF5 5B3D -8BF6 5B3E -8BF7 5B3F -E6D7 5B40 -8BF8 5B41 -8BF9 5B42 -8BFA 5B43 -8BFB 5B44 -8BFC 5B45 -8BFD 5B46 -8BFE 5B47 -8C40 5B48 -8C41 5B49 -8C42 5B4A -8C43 5B4B -8C44 5B4C -8C45 5B4D -8C46 5B4E -8C47 5B4F -D7D3 5B50 -E6DD 5B51 -8C48 5B52 -E6DE 5B53 -BFD7 5B54 -D4D0 5B55 -8C49 5B56 -D7D6 5B57 -B4E6 5B58 -CBEF 5B59 -E6DA 5B5A -D8C3 5B5B -D7CE 5B5C -D0A2 5B5D -8C4A 5B5E -C3CF 5B5F -8C4B 5B60 -8C4C 5B61 -E6DF 5B62 -BCBE 5B63 -B9C2 5B64 -E6DB 5B65 -D1A7 5B66 -8C4D 5B67 -8C4E 5B68 -BAA2 5B69 -C2CF 5B6A -8C4F 5B6B -D8AB 5B6C -8C50 5B6D -8C51 5B6E -8C52 5B6F -CAEB 5B70 -E5EE 5B71 -8C53 5B72 -E6DC 5B73 -8C54 5B74 -B7F5 5B75 -8C55 5B76 -8C56 5B77 -8C57 5B78 -8C58 5B79 -C8E6 5B7A -8C59 5B7B -8C5A 5B7C -C4F5 5B7D -8C5B 5B7E -8C5C 5B7F -E5B2 5B80 -C4FE 5B81 -8C5D 5B82 -CBFC 5B83 -E5B3 5B84 -D5AC 5B85 -8C5E 5B86 -D3EE 5B87 -CAD8 5B88 -B0B2 5B89 -8C5F 5B8A -CBCE 5B8B -CDEA 5B8C -8C60 5B8D -8C61 5B8E -BAEA 5B8F -8C62 5B90 -8C63 5B91 -8C64 5B92 -E5B5 5B93 -8C65 5B94 -E5B4 5B95 -8C66 5B96 -D7DA 5B97 -B9D9 5B98 -D6E6 5B99 -B6A8 5B9A -CDF0 5B9B -D2CB 5B9C -B1A6 5B9D -CAB5 5B9E -8C67 5B9F -B3E8 5BA0 -C9F3 5BA1 -BFCD 5BA2 -D0FB 5BA3 -CAD2 5BA4 -E5B6 5BA5 -BBC2 5BA6 -8C68 5BA7 -8C69 5BA8 -8C6A 5BA9 -CFDC 5BAA -B9AC 5BAB -8C6B 5BAC -8C6C 5BAD -8C6D 5BAE -8C6E 5BAF -D4D7 5BB0 -8C6F 5BB1 -8C70 5BB2 -BAA6 5BB3 -D1E7 5BB4 -CFFC 5BB5 -BCD2 5BB6 -8C71 5BB7 -E5B7 5BB8 -C8DD 5BB9 -8C72 5BBA -8C73 5BBB -8C74 5BBC -BFED 5BBD -B1F6 5BBE -CBDE 5BBF -8C75 5BC0 -8C76 5BC1 -BCC5 5BC2 -8C77 5BC3 -BCC4 5BC4 -D2FA 5BC5 -C3DC 5BC6 -BFDC 5BC7 -8C78 5BC8 -8C79 5BC9 -8C7A 5BCA -8C7B 5BCB -B8BB 5BCC -8C7C 5BCD -8C7D 5BCE -8C7E 5BCF -C3C2 5BD0 -8C80 5BD1 -BAAE 5BD2 -D4A2 5BD3 -8C81 5BD4 -8C82 5BD5 -8C83 5BD6 -8C84 5BD7 -8C85 5BD8 -8C86 5BD9 -8C87 5BDA -8C88 5BDB -8C89 5BDC -C7DE 5BDD -C4AF 5BDE -B2EC 5BDF -8C8A 5BE0 -B9D1 5BE1 -8C8B 5BE2 -8C8C 5BE3 -E5BB 5BE4 -C1C8 5BE5 -8C8D 5BE6 -8C8E 5BE7 -D5AF 5BE8 -8C8F 5BE9 -8C90 5BEA -8C91 5BEB -8C92 5BEC -8C93 5BED -E5BC 5BEE -8C94 5BEF -E5BE 5BF0 -8C95 5BF1 -8C96 5BF2 -8C97 5BF3 -8C98 5BF4 -8C99 5BF5 -8C9A 5BF6 -8C9B 5BF7 -B4E7 5BF8 -B6D4 5BF9 -CBC2 5BFA -D1B0 5BFB -B5BC 5BFC -8C9C 5BFD -8C9D 5BFE -CAD9 5BFF -8C9E 5C00 -B7E2 5C01 -8C9F 5C02 -8CA0 5C03 -C9E4 5C04 -8CA1 5C05 -BDAB 5C06 -8CA2 5C07 -8CA3 5C08 -CEBE 5C09 -D7F0 5C0A -8CA4 5C0B -8CA5 5C0C -8CA6 5C0D -8CA7 5C0E -D0A1 5C0F -8CA8 5C10 -C9D9 5C11 -8CA9 5C12 -8CAA 5C13 -B6FB 5C14 -E6D8 5C15 -BCE2 5C16 -8CAB 5C17 -B3BE 5C18 -8CAC 5C19 -C9D0 5C1A -8CAD 5C1B -E6D9 5C1C -B3A2 5C1D -8CAE 5C1E -8CAF 5C1F -8CB0 5C20 -8CB1 5C21 -DECC 5C22 -8CB2 5C23 -D3C8 5C24 -DECD 5C25 -8CB3 5C26 -D2A2 5C27 -8CB4 5C28 -8CB5 5C29 -8CB6 5C2A -8CB7 5C2B -DECE 5C2C -8CB8 5C2D -8CB9 5C2E -8CBA 5C2F -8CBB 5C30 -BECD 5C31 -8CBC 5C32 -8CBD 5C33 -DECF 5C34 -8CBE 5C35 -8CBF 5C36 -8CC0 5C37 -CAAC 5C38 -D2FC 5C39 -B3DF 5C3A -E5EA 5C3B -C4E1 5C3C -BEA1 5C3D -CEB2 5C3E -C4F2 5C3F -BED6 5C40 -C6A8 5C41 -B2E3 5C42 -8CC1 5C43 -8CC2 5C44 -BED3 5C45 -8CC3 5C46 -8CC4 5C47 -C7FC 5C48 -CCEB 5C49 -BDEC 5C4A -CEDD 5C4B -8CC5 5C4C -8CC6 5C4D -CABA 5C4E -C6C1 5C4F -E5EC 5C50 -D0BC 5C51 -8CC7 5C52 -8CC8 5C53 -8CC9 5C54 -D5B9 5C55 -8CCA 5C56 -8CCB 5C57 -8CCC 5C58 -E5ED 5C59 -8CCD 5C5A -8CCE 5C5B -8CCF 5C5C -8CD0 5C5D -CAF4 5C5E -8CD1 5C5F -CDC0 5C60 -C2C5 5C61 -8CD2 5C62 -E5EF 5C63 -8CD3 5C64 -C2C4 5C65 -E5F0 5C66 -8CD4 5C67 -8CD5 5C68 -8CD6 5C69 -8CD7 5C6A -8CD8 5C6B -8CD9 5C6C -8CDA 5C6D -E5F8 5C6E -CDCD 5C6F -8CDB 5C70 -C9BD 5C71 -8CDC 5C72 -8CDD 5C73 -8CDE 5C74 -8CDF 5C75 -8CE0 5C76 -8CE1 5C77 -8CE2 5C78 -D2D9 5C79 -E1A8 5C7A -8CE3 5C7B -8CE4 5C7C -8CE5 5C7D -8CE6 5C7E -D3EC 5C7F -8CE7 5C80 -CBEA 5C81 -C6F1 5C82 -8CE8 5C83 -8CE9 5C84 -8CEA 5C85 -8CEB 5C86 -8CEC 5C87 -E1AC 5C88 -8CED 5C89 -8CEE 5C8A -8CEF 5C8B -E1A7 5C8C -E1A9 5C8D -8CF0 5C8E -8CF1 5C8F -E1AA 5C90 -E1AF 5C91 -8CF2 5C92 -8CF3 5C93 -B2ED 5C94 -8CF4 5C95 -E1AB 5C96 -B8DA 5C97 -E1AD 5C98 -E1AE 5C99 -E1B0 5C9A -B5BA 5C9B -E1B1 5C9C -8CF5 5C9D -8CF6 5C9E -8CF7 5C9F -8CF8 5CA0 -8CF9 5CA1 -E1B3 5CA2 -E1B8 5CA3 -8CFA 5CA4 -8CFB 5CA5 -8CFC 5CA6 -8CFD 5CA7 -8CFE 5CA8 -D1D2 5CA9 -8D40 5CAA -E1B6 5CAB -E1B5 5CAC -C1EB 5CAD -8D41 5CAE -8D42 5CAF -8D43 5CB0 -E1B7 5CB1 -8D44 5CB2 -D4C0 5CB3 -8D45 5CB4 -E1B2 5CB5 -8D46 5CB6 -E1BA 5CB7 -B0B6 5CB8 -8D47 5CB9 -8D48 5CBA -8D49 5CBB -8D4A 5CBC -E1B4 5CBD -8D4B 5CBE -BFF9 5CBF -8D4C 5CC0 -E1B9 5CC1 -8D4D 5CC2 -8D4E 5CC3 -E1BB 5CC4 -8D4F 5CC5 -8D50 5CC6 -8D51 5CC7 -8D52 5CC8 -8D53 5CC9 -8D54 5CCA -E1BE 5CCB -8D55 5CCC -8D56 5CCD -8D57 5CCE -8D58 5CCF -8D59 5CD0 -8D5A 5CD1 -E1BC 5CD2 -8D5B 5CD3 -8D5C 5CD4 -8D5D 5CD5 -8D5E 5CD6 -8D5F 5CD7 -8D60 5CD8 -D6C5 5CD9 -8D61 5CDA -8D62 5CDB -8D63 5CDC -8D64 5CDD -8D65 5CDE -8D66 5CDF -8D67 5CE0 -CFBF 5CE1 -8D68 5CE2 -8D69 5CE3 -E1BD 5CE4 -E1BF 5CE5 -C2CD 5CE6 -8D6A 5CE7 -B6EB 5CE8 -8D6B 5CE9 -D3F8 5CEA -8D6C 5CEB -8D6D 5CEC -C7CD 5CED -8D6E 5CEE -8D6F 5CEF -B7E5 5CF0 -8D70 5CF1 -8D71 5CF2 -8D72 5CF3 -8D73 5CF4 -8D74 5CF5 -8D75 5CF6 -8D76 5CF7 -8D77 5CF8 -8D78 5CF9 -8D79 5CFA -BEFE 5CFB -8D7A 5CFC -8D7B 5CFD -8D7C 5CFE -8D7D 5CFF -8D7E 5D00 -8D80 5D01 -E1C0 5D02 -E1C1 5D03 -8D81 5D04 -8D82 5D05 -E1C7 5D06 -B3E7 5D07 -8D83 5D08 -8D84 5D09 -8D85 5D0A -8D86 5D0B -8D87 5D0C -8D88 5D0D -C6E9 5D0E -8D89 5D0F -8D8A 5D10 -8D8B 5D11 -8D8C 5D12 -8D8D 5D13 -B4DE 5D14 -8D8E 5D15 -D1C2 5D16 -8D8F 5D17 -8D90 5D18 -8D91 5D19 -8D92 5D1A -E1C8 5D1B -8D93 5D1C -8D94 5D1D -E1C6 5D1E -8D95 5D1F -8D96 5D20 -8D97 5D21 -8D98 5D22 -8D99 5D23 -E1C5 5D24 -8D9A 5D25 -E1C3 5D26 -E1C2 5D27 -8D9B 5D28 -B1C0 5D29 -8D9C 5D2A -8D9D 5D2B -8D9E 5D2C -D5B8 5D2D -E1C4 5D2E -8D9F 5D2F -8DA0 5D30 -8DA1 5D31 -8DA2 5D32 -8DA3 5D33 -E1CB 5D34 -8DA4 5D35 -8DA5 5D36 -8DA6 5D37 -8DA7 5D38 -8DA8 5D39 -8DA9 5D3A -8DAA 5D3B -8DAB 5D3C -E1CC 5D3D -E1CA 5D3E -8DAC 5D3F -8DAD 5D40 -8DAE 5D41 -8DAF 5D42 -8DB0 5D43 -8DB1 5D44 -8DB2 5D45 -8DB3 5D46 -EFFA 5D47 -8DB4 5D48 -8DB5 5D49 -E1D3 5D4A -E1D2 5D4B -C7B6 5D4C -8DB6 5D4D -8DB7 5D4E -8DB8 5D4F -8DB9 5D50 -8DBA 5D51 -8DBB 5D52 -8DBC 5D53 -8DBD 5D54 -8DBE 5D55 -8DBF 5D56 -8DC0 5D57 -E1C9 5D58 -8DC1 5D59 -8DC2 5D5A -E1CE 5D5B -8DC3 5D5C -E1D0 5D5D -8DC4 5D5E -8DC5 5D5F -8DC6 5D60 -8DC7 5D61 -8DC8 5D62 -8DC9 5D63 -8DCA 5D64 -8DCB 5D65 -8DCC 5D66 -8DCD 5D67 -8DCE 5D68 -E1D4 5D69 -8DCF 5D6A -E1D1 5D6B -E1CD 5D6C -8DD0 5D6D -8DD1 5D6E -E1CF 5D6F -8DD2 5D70 -8DD3 5D71 -8DD4 5D72 -8DD5 5D73 -E1D5 5D74 -8DD6 5D75 -8DD7 5D76 -8DD8 5D77 -8DD9 5D78 -8DDA 5D79 -8DDB 5D7A -8DDC 5D7B -8DDD 5D7C -8DDE 5D7D -8DDF 5D7E -8DE0 5D7F -8DE1 5D80 -8DE2 5D81 -E1D6 5D82 -8DE3 5D83 -8DE4 5D84 -8DE5 5D85 -8DE6 5D86 -8DE7 5D87 -8DE8 5D88 -8DE9 5D89 -8DEA 5D8A -8DEB 5D8B -8DEC 5D8C -8DED 5D8D -8DEE 5D8E -8DEF 5D8F -8DF0 5D90 -8DF1 5D91 -8DF2 5D92 -8DF3 5D93 -8DF4 5D94 -8DF5 5D95 -8DF6 5D96 -8DF7 5D97 -8DF8 5D98 -E1D7 5D99 -8DF9 5D9A -8DFA 5D9B -8DFB 5D9C -E1D8 5D9D -8DFC 5D9E -8DFD 5D9F -8DFE 5DA0 -8E40 5DA1 -8E41 5DA2 -8E42 5DA3 -8E43 5DA4 -8E44 5DA5 -8E45 5DA6 -8E46 5DA7 -8E47 5DA8 -8E48 5DA9 -8E49 5DAA -8E4A 5DAB -8E4B 5DAC -8E4C 5DAD -8E4D 5DAE -8E4E 5DAF -8E4F 5DB0 -8E50 5DB1 -8E51 5DB2 -8E52 5DB3 -8E53 5DB4 -8E54 5DB5 -8E55 5DB6 -E1DA 5DB7 -8E56 5DB8 -8E57 5DB9 -8E58 5DBA -8E59 5DBB -8E5A 5DBC -8E5B 5DBD -8E5C 5DBE -8E5D 5DBF -8E5E 5DC0 -8E5F 5DC1 -8E60 5DC2 -8E61 5DC3 -8E62 5DC4 -E1DB 5DC5 -8E63 5DC6 -8E64 5DC7 -8E65 5DC8 -8E66 5DC9 -8E67 5DCA -8E68 5DCB -8E69 5DCC -CEA1 5DCD -8E6A 5DCE -8E6B 5DCF -8E6C 5DD0 -8E6D 5DD1 -8E6E 5DD2 -8E6F 5DD3 -8E70 5DD4 -8E71 5DD5 -8E72 5DD6 -8E73 5DD7 -8E74 5DD8 -8E75 5DD9 -8E76 5DDA -E7DD 5DDB -8E77 5DDC -B4A8 5DDD -D6DD 5DDE -8E78 5DDF -8E79 5DE0 -D1B2 5DE1 -B3B2 5DE2 -8E7A 5DE3 -8E7B 5DE4 -B9A4 5DE5 -D7F3 5DE6 -C7C9 5DE7 -BEDE 5DE8 -B9AE 5DE9 -8E7C 5DEA -CED7 5DEB -8E7D 5DEC -8E7E 5DED -B2EE 5DEE -DBCF 5DEF -8E80 5DF0 -BCBA 5DF1 -D2D1 5DF2 -CBC8 5DF3 -B0CD 5DF4 -8E81 5DF5 -8E82 5DF6 -CFEF 5DF7 -8E83 5DF8 -8E84 5DF9 -8E85 5DFA -8E86 5DFB -8E87 5DFC -D9E3 5DFD -BDED 5DFE -8E88 5DFF -8E89 5E00 -B1D2 5E01 -CAD0 5E02 -B2BC 5E03 -8E8A 5E04 -CBA7 5E05 -B7AB 5E06 -8E8B 5E07 -CAA6 5E08 -8E8C 5E09 -8E8D 5E0A -8E8E 5E0B -CFA3 5E0C -8E8F 5E0D -8E90 5E0E -E0F8 5E0F -D5CA 5E10 -E0FB 5E11 -8E91 5E12 -8E92 5E13 -E0FA 5E14 -C5C1 5E15 -CCFB 5E16 -8E93 5E17 -C1B1 5E18 -E0F9 5E19 -D6E3 5E1A -B2AF 5E1B -D6C4 5E1C -B5DB 5E1D -8E94 5E1E -8E95 5E1F -8E96 5E20 -8E97 5E21 -8E98 5E22 -8E99 5E23 -8E9A 5E24 -8E9B 5E25 -B4F8 5E26 -D6A1 5E27 -8E9C 5E28 -8E9D 5E29 -8E9E 5E2A -8E9F 5E2B -8EA0 5E2C -CFAF 5E2D -B0EF 5E2E -8EA1 5E2F -8EA2 5E30 -E0FC 5E31 -8EA3 5E32 -8EA4 5E33 -8EA5 5E34 -8EA6 5E35 -8EA7 5E36 -E1A1 5E37 -B3A3 5E38 -8EA8 5E39 -8EA9 5E3A -E0FD 5E3B -E0FE 5E3C -C3B1 5E3D -8EAA 5E3E -8EAB 5E3F -8EAC 5E40 -8EAD 5E41 -C3DD 5E42 -8EAE 5E43 -E1A2 5E44 -B7F9 5E45 -8EAF 5E46 -8EB0 5E47 -8EB1 5E48 -8EB2 5E49 -8EB3 5E4A -8EB4 5E4B -BBCF 5E4C -8EB5 5E4D -8EB6 5E4E -8EB7 5E4F -8EB8 5E50 -8EB9 5E51 -8EBA 5E52 -8EBB 5E53 -E1A3 5E54 -C4BB 5E55 -8EBC 5E56 -8EBD 5E57 -8EBE 5E58 -8EBF 5E59 -8EC0 5E5A -E1A4 5E5B -8EC1 5E5C -8EC2 5E5D -E1A5 5E5E -8EC3 5E5F -8EC4 5E60 -E1A6 5E61 -B4B1 5E62 -8EC5 5E63 -8EC6 5E64 -8EC7 5E65 -8EC8 5E66 -8EC9 5E67 -8ECA 5E68 -8ECB 5E69 -8ECC 5E6A -8ECD 5E6B -8ECE 5E6C -8ECF 5E6D -8ED0 5E6E -8ED1 5E6F -8ED2 5E70 -8ED3 5E71 -B8C9 5E72 -C6BD 5E73 -C4EA 5E74 -8ED4 5E75 -B2A2 5E76 -8ED5 5E77 -D0D2 5E78 -8ED6 5E79 -E7DB 5E7A -BBC3 5E7B -D3D7 5E7C -D3C4 5E7D -8ED7 5E7E -B9E3 5E7F -E2CF 5E80 -8ED8 5E81 -8ED9 5E82 -8EDA 5E83 -D7AF 5E84 -8EDB 5E85 -C7EC 5E86 -B1D3 5E87 -8EDC 5E88 -8EDD 5E89 -B4B2 5E8A -E2D1 5E8B -8EDE 5E8C -8EDF 5E8D -8EE0 5E8E -D0F2 5E8F -C2AE 5E90 -E2D0 5E91 -8EE1 5E92 -BFE2 5E93 -D3A6 5E94 -B5D7 5E95 -E2D2 5E96 -B5EA 5E97 -8EE2 5E98 -C3ED 5E99 -B8FD 5E9A -8EE3 5E9B -B8AE 5E9C -8EE4 5E9D -C5D3 5E9E -B7CF 5E9F -E2D4 5EA0 -8EE5 5EA1 -8EE6 5EA2 -8EE7 5EA3 -8EE8 5EA4 -E2D3 5EA5 -B6C8 5EA6 -D7F9 5EA7 -8EE9 5EA8 -8EEA 5EA9 -8EEB 5EAA -8EEC 5EAB -8EED 5EAC -CDA5 5EAD -8EEE 5EAE -8EEF 5EAF -8EF0 5EB0 -8EF1 5EB1 -8EF2 5EB2 -E2D8 5EB3 -8EF3 5EB4 -E2D6 5EB5 -CAFC 5EB6 -BFB5 5EB7 -D3B9 5EB8 -E2D5 5EB9 -8EF4 5EBA -8EF5 5EBB -8EF6 5EBC -8EF7 5EBD -E2D7 5EBE -8EF8 5EBF -8EF9 5EC0 -8EFA 5EC1 -8EFB 5EC2 -8EFC 5EC3 -8EFD 5EC4 -8EFE 5EC5 -8F40 5EC6 -8F41 5EC7 -8F42 5EC8 -C1AE 5EC9 -C0C8 5ECA -8F43 5ECB -8F44 5ECC -8F45 5ECD -8F46 5ECE -8F47 5ECF -8F48 5ED0 -E2DB 5ED1 -E2DA 5ED2 -C0AA 5ED3 -8F49 5ED4 -8F4A 5ED5 -C1CE 5ED6 -8F4B 5ED7 -8F4C 5ED8 -8F4D 5ED9 -8F4E 5EDA -E2DC 5EDB -8F4F 5EDC -8F50 5EDD -8F51 5EDE -8F52 5EDF -8F53 5EE0 -8F54 5EE1 -8F55 5EE2 -8F56 5EE3 -8F57 5EE4 -8F58 5EE5 -8F59 5EE6 -8F5A 5EE7 -E2DD 5EE8 -8F5B 5EE9 -E2DE 5EEA -8F5C 5EEB -8F5D 5EEC -8F5E 5EED -8F5F 5EEE -8F60 5EEF -8F61 5EF0 -8F62 5EF1 -8F63 5EF2 -8F64 5EF3 -DBC8 5EF4 -8F65 5EF5 -D1D3 5EF6 -CDA2 5EF7 -8F66 5EF8 -8F67 5EF9 -BDA8 5EFA -8F68 5EFB -8F69 5EFC -8F6A 5EFD -DEC3 5EFE -D8A5 5EFF -BFAA 5F00 -DBCD 5F01 -D2EC 5F02 -C6FA 5F03 -C5AA 5F04 -8F6B 5F05 -8F6C 5F06 -8F6D 5F07 -DEC4 5F08 -8F6E 5F09 -B1D7 5F0A -DFAE 5F0B -8F6F 5F0C -8F70 5F0D -8F71 5F0E -CABD 5F0F -8F72 5F10 -DFB1 5F11 -8F73 5F12 -B9AD 5F13 -8F74 5F14 -D2FD 5F15 -8F75 5F16 -B8A5 5F17 -BAEB 5F18 -8F76 5F19 -8F77 5F1A -B3DA 5F1B -8F78 5F1C -8F79 5F1D -8F7A 5F1E -B5DC 5F1F -D5C5 5F20 -8F7B 5F21 -8F7C 5F22 -8F7D 5F23 -8F7E 5F24 -C3D6 5F25 -CFD2 5F26 -BBA1 5F27 -8F80 5F28 -E5F3 5F29 -E5F2 5F2A -8F81 5F2B -8F82 5F2C -E5F4 5F2D -8F83 5F2E -CDE4 5F2F -8F84 5F30 -C8F5 5F31 -8F85 5F32 -8F86 5F33 -8F87 5F34 -8F88 5F35 -8F89 5F36 -8F8A 5F37 -8F8B 5F38 -B5AF 5F39 -C7BF 5F3A -8F8C 5F3B -E5F6 5F3C -8F8D 5F3D -8F8E 5F3E -8F8F 5F3F -ECB0 5F40 -8F90 5F41 -8F91 5F42 -8F92 5F43 -8F93 5F44 -8F94 5F45 -8F95 5F46 -8F96 5F47 -8F97 5F48 -8F98 5F49 -8F99 5F4A -8F9A 5F4B -8F9B 5F4C -8F9C 5F4D -8F9D 5F4E -8F9E 5F4F -E5E6 5F50 -8F9F 5F51 -B9E9 5F52 -B5B1 5F53 -8FA0 5F54 -C2BC 5F55 -E5E8 5F56 -E5E7 5F57 -E5E9 5F58 -8FA1 5F59 -8FA2 5F5A -8FA3 5F5B -8FA4 5F5C -D2CD 5F5D -8FA5 5F5E -8FA6 5F5F -8FA7 5F60 -E1EA 5F61 -D0CE 5F62 -8FA8 5F63 -CDAE 5F64 -8FA9 5F65 -D1E5 5F66 -8FAA 5F67 -8FAB 5F68 -B2CA 5F69 -B1EB 5F6A -8FAC 5F6B -B1F2 5F6C -C5ED 5F6D -8FAD 5F6E -8FAE 5F6F -D5C3 5F70 -D3B0 5F71 -8FAF 5F72 -E1DC 5F73 -8FB0 5F74 -8FB1 5F75 -8FB2 5F76 -E1DD 5F77 -8FB3 5F78 -D2DB 5F79 -8FB4 5F7A -B3B9 5F7B -B1CB 5F7C -8FB5 5F7D -8FB6 5F7E -8FB7 5F7F -CDF9 5F80 -D5F7 5F81 -E1DE 5F82 -8FB8 5F83 -BEB6 5F84 -B4FD 5F85 -8FB9 5F86 -E1DF 5F87 -BADC 5F88 -E1E0 5F89 -BBB2 5F8A -C2C9 5F8B -E1E1 5F8C -8FBA 5F8D -8FBB 5F8E -8FBC 5F8F -D0EC 5F90 -8FBD 5F91 -CDBD 5F92 -8FBE 5F93 -8FBF 5F94 -E1E2 5F95 -8FC0 5F96 -B5C3 5F97 -C5C7 5F98 -E1E3 5F99 -8FC1 5F9A -8FC2 5F9B -E1E4 5F9C -8FC3 5F9D -8FC4 5F9E -8FC5 5F9F -8FC6 5FA0 -D3F9 5FA1 -8FC7 5FA2 -8FC8 5FA3 -8FC9 5FA4 -8FCA 5FA5 -8FCB 5FA6 -8FCC 5FA7 -E1E5 5FA8 -8FCD 5FA9 -D1AD 5FAA -8FCE 5FAB -8FCF 5FAC -E1E6 5FAD -CEA2 5FAE -8FD0 5FAF -8FD1 5FB0 -8FD2 5FB1 -8FD3 5FB2 -8FD4 5FB3 -8FD5 5FB4 -E1E7 5FB5 -8FD6 5FB6 -B5C2 5FB7 -8FD7 5FB8 -8FD8 5FB9 -8FD9 5FBA -8FDA 5FBB -E1E8 5FBC -BBD5 5FBD -8FDB 5FBE -8FDC 5FBF -8FDD 5FC0 -8FDE 5FC1 -8FDF 5FC2 -D0C4 5FC3 -E2E0 5FC4 -B1D8 5FC5 -D2E4 5FC6 -8FE0 5FC7 -8FE1 5FC8 -E2E1 5FC9 -8FE2 5FCA -8FE3 5FCB -BCC9 5FCC -C8CC 5FCD -8FE4 5FCE -E2E3 5FCF -ECFE 5FD0 -ECFD 5FD1 -DFAF 5FD2 -8FE5 5FD3 -8FE6 5FD4 -8FE7 5FD5 -E2E2 5FD6 -D6BE 5FD7 -CDFC 5FD8 -C3A6 5FD9 -8FE8 5FDA -8FE9 5FDB -8FEA 5FDC -E3C3 5FDD -8FEB 5FDE -8FEC 5FDF -D6D2 5FE0 -E2E7 5FE1 -8FED 5FE2 -8FEE 5FE3 -E2E8 5FE4 -8FEF 5FE5 -8FF0 5FE6 -D3C7 5FE7 -8FF1 5FE8 -8FF2 5FE9 -E2EC 5FEA -BFEC 5FEB -8FF3 5FEC -E2ED 5FED -E2E5 5FEE -8FF4 5FEF -8FF5 5FF0 -B3C0 5FF1 -8FF6 5FF2 -8FF7 5FF3 -8FF8 5FF4 -C4EE 5FF5 -8FF9 5FF6 -8FFA 5FF7 -E2EE 5FF8 -8FFB 5FF9 -8FFC 5FFA -D0C3 5FFB -8FFD 5FFC -BAF6 5FFD -E2E9 5FFE -B7DE 5FFF -BBB3 6000 -CCAC 6001 -CBCB 6002 -E2E4 6003 -E2E6 6004 -E2EA 6005 -E2EB 6006 -8FFE 6007 -9040 6008 -9041 6009 -E2F7 600A -9042 600B -9043 600C -E2F4 600D -D4F5 600E -E2F3 600F -9044 6010 -9045 6011 -C5AD 6012 -9046 6013 -D5FA 6014 -C5C2 6015 -B2C0 6016 -9047 6017 -9048 6018 -E2EF 6019 -9049 601A -E2F2 601B -C1AF 601C -CBBC 601D -904A 601E -904B 601F -B5A1 6020 -E2F9 6021 -904C 6022 -904D 6023 -904E 6024 -BCB1 6025 -E2F1 6026 -D0D4 6027 -D4B9 6028 -E2F5 6029 -B9D6 602A -E2F6 602B -904F 602C -9050 602D -9051 602E -C7D3 602F -9052 6030 -9053 6031 -9054 6032 -9055 6033 -9056 6034 -E2F0 6035 -9057 6036 -9058 6037 -9059 6038 -905A 6039 -905B 603A -D7DC 603B -EDA1 603C -905C 603D -905D 603E -E2F8 603F -905E 6040 -EDA5 6041 -E2FE 6042 -CAD1 6043 -905F 6044 -9060 6045 -9061 6046 -9062 6047 -9063 6048 -9064 6049 -9065 604A -C1B5 604B -9066 604C -BBD0 604D -9067 604E -9068 604F -BFD6 6050 -9069 6051 -BAE3 6052 -906A 6053 -906B 6054 -CBA1 6055 -906C 6056 -906D 6057 -906E 6058 -EDA6 6059 -EDA3 605A -906F 605B -9070 605C -EDA2 605D -9071 605E -9072 605F -9073 6060 -9074 6061 -BBD6 6062 -EDA7 6063 -D0F4 6064 -9075 6065 -9076 6066 -EDA4 6067 -BADE 6068 -B6F7 6069 -E3A1 606A -B6B2 606B -CCF1 606C -B9A7 606D -9077 606E -CFA2 606F -C7A1 6070 -9078 6071 -9079 6072 -BFD2 6073 -907A 6074 -907B 6075 -B6F1 6076 -907C 6077 -E2FA 6078 -E2FB 6079 -E2FD 607A -E2FC 607B -C4D5 607C -E3A2 607D -907D 607E -D3C1 607F -907E 6080 -9080 6081 -9081 6082 -E3A7 6083 -C7C4 6084 -9082 6085 -9083 6086 -9084 6087 -9085 6088 -CFA4 6089 -9086 608A -9087 608B -E3A9 608C -BAB7 608D -9088 608E -9089 608F -908A 6090 -908B 6091 -E3A8 6092 -908C 6093 -BBDA 6094 -908D 6095 -E3A3 6096 -908E 6097 -908F 6098 -9090 6099 -E3A4 609A -E3AA 609B -9091 609C -E3A6 609D -9092 609E -CEF2 609F -D3C6 60A0 -9093 60A1 -9094 60A2 -BBBC 60A3 -9095 60A4 -9096 60A5 -D4C3 60A6 -9097 60A7 -C4FA 60A8 -9098 60A9 -9099 60AA -EDA8 60AB -D0FC 60AC -E3A5 60AD -909A 60AE -C3F5 60AF -909B 60B0 -E3AD 60B1 -B1AF 60B2 -909C 60B3 -E3B2 60B4 -909D 60B5 -909E 60B6 -909F 60B7 -BCC2 60B8 -90A0 60B9 -90A1 60BA -E3AC 60BB -B5BF 60BC -90A2 60BD -90A3 60BE -90A4 60BF -90A5 60C0 -90A6 60C1 -90A7 60C2 -90A8 60C3 -90A9 60C4 -C7E9 60C5 -E3B0 60C6 -90AA 60C7 -90AB 60C8 -90AC 60C9 -BEAA 60CA -CDEF 60CB -90AD 60CC -90AE 60CD -90AF 60CE -90B0 60CF -90B1 60D0 -BBF3 60D1 -90B2 60D2 -90B3 60D3 -90B4 60D4 -CCE8 60D5 -90B5 60D6 -90B6 60D7 -E3AF 60D8 -90B7 60D9 -E3B1 60DA -90B8 60DB -CFA7 60DC -E3AE 60DD -90B9 60DE -CEA9 60DF -BBDD 60E0 -90BA 60E1 -90BB 60E2 -90BC 60E3 -90BD 60E4 -90BE 60E5 -B5EB 60E6 -BEE5 60E7 -B2D2 60E8 -B3CD 60E9 -90BF 60EA -B1B9 60EB -E3AB 60EC -B2D1 60ED -B5AC 60EE -B9DF 60EF -B6E8 60F0 -90C0 60F1 -90C1 60F2 -CFEB 60F3 -E3B7 60F4 -90C2 60F5 -BBCC 60F6 -90C3 60F7 -90C4 60F8 -C8C7 60F9 -D0CA 60FA -90C5 60FB -90C6 60FC -90C7 60FD -90C8 60FE -90C9 60FF -E3B8 6100 -B3EE 6101 -90CA 6102 -90CB 6103 -90CC 6104 -90CD 6105 -EDA9 6106 -90CE 6107 -D3FA 6108 -D3E4 6109 -90CF 610A -90D0 610B -90D1 610C -EDAA 610D -E3B9 610E -D2E2 610F -90D2 6110 -90D3 6111 -90D4 6112 -90D5 6113 -90D6 6114 -E3B5 6115 -90D7 6116 -90D8 6117 -90D9 6118 -90DA 6119 -D3DE 611A -90DB 611B -90DC 611C -90DD 611D -90DE 611E -B8D0 611F -E3B3 6120 -90DF 6121 -90E0 6122 -E3B6 6123 -B7DF 6124 -90E1 6125 -E3B4 6126 -C0A2 6127 -90E2 6128 -90E3 6129 -90E4 612A -E3BA 612B -90E5 612C -90E6 612D -90E7 612E -90E8 612F -90E9 6130 -90EA 6131 -90EB 6132 -90EC 6133 -90ED 6134 -90EE 6135 -90EF 6136 -90F0 6137 -90F1 6138 -90F2 6139 -90F3 613A -90F4 613B -90F5 613C -90F6 613D -90F7 613E -D4B8 613F -90F8 6140 -90F9 6141 -90FA 6142 -90FB 6143 -90FC 6144 -90FD 6145 -90FE 6146 -9140 6147 -B4C8 6148 -9141 6149 -E3BB 614A -9142 614B -BBC5 614C -9143 614D -C9F7 614E -9144 614F -9145 6150 -C9E5 6151 -9146 6152 -9147 6153 -9148 6154 -C4BD 6155 -9149 6156 -914A 6157 -914B 6158 -914C 6159 -914D 615A -914E 615B -914F 615C -EDAB 615D -9150 615E -9151 615F -9152 6160 -9153 6161 -C2FD 6162 -9154 6163 -9155 6164 -9156 6165 -9157 6166 -BBDB 6167 -BFAE 6168 -9158 6169 -9159 616A -915A 616B -915B 616C -915C 616D -915D 616E -915E 616F -CEBF 6170 -915F 6171 -9160 6172 -9161 6173 -9162 6174 -E3BC 6175 -9163 6176 -BFB6 6177 -9164 6178 -9165 6179 -9166 617A -9167 617B -9168 617C -9169 617D -916A 617E -916B 617F -916C 6180 -916D 6181 -916E 6182 -916F 6183 -9170 6184 -9171 6185 -9172 6186 -9173 6187 -9174 6188 -9175 6189 -9176 618A -B1EF 618B -9177 618C -9178 618D -D4F7 618E -9179 618F -917A 6190 -917B 6191 -917C 6192 -917D 6193 -E3BE 6194 -917E 6195 -9180 6196 -9181 6197 -9182 6198 -9183 6199 -9184 619A -9185 619B -9186 619C -EDAD 619D -9187 619E -9188 619F -9189 61A0 -918A 61A1 -918B 61A2 -918C 61A3 -918D 61A4 -918E 61A5 -918F 61A6 -E3BF 61A7 -BAA9 61A8 -EDAC 61A9 -9190 61AA -9191 61AB -E3BD 61AC -9192 61AD -9193 61AE -9194 61AF -9195 61B0 -9196 61B1 -9197 61B2 -9198 61B3 -9199 61B4 -919A 61B5 -919B 61B6 -E3C0 61B7 -919C 61B8 -919D 61B9 -919E 61BA -919F 61BB -91A0 61BC -91A1 61BD -BAB6 61BE -91A2 61BF -91A3 61C0 -91A4 61C1 -B6AE 61C2 -91A5 61C3 -91A6 61C4 -91A7 61C5 -91A8 61C6 -91A9 61C7 -D0B8 61C8 -91AA 61C9 -B0C3 61CA -EDAE 61CB -91AB 61CC -91AC 61CD -91AD 61CE -91AE 61CF -91AF 61D0 -EDAF 61D1 -C0C1 61D2 -91B0 61D3 -E3C1 61D4 -91B1 61D5 -91B2 61D6 -91B3 61D7 -91B4 61D8 -91B5 61D9 -91B6 61DA -91B7 61DB -91B8 61DC -91B9 61DD -91BA 61DE -91BB 61DF -91BC 61E0 -91BD 61E1 -91BE 61E2 -91BF 61E3 -91C0 61E4 -91C1 61E5 -C5B3 61E6 -91C2 61E7 -91C3 61E8 -91C4 61E9 -91C5 61EA -91C6 61EB -91C7 61EC -91C8 61ED -91C9 61EE -91CA 61EF -91CB 61F0 -91CC 61F1 -91CD 61F2 -91CE 61F3 -91CF 61F4 -E3C2 61F5 -91D0 61F6 -91D1 61F7 -91D2 61F8 -91D3 61F9 -91D4 61FA -91D5 61FB -91D6 61FC -91D7 61FD -91D8 61FE -DCB2 61FF -91D9 6200 -91DA 6201 -91DB 6202 -91DC 6203 -91DD 6204 -91DE 6205 -EDB0 6206 -91DF 6207 -B8EA 6208 -91E0 6209 -CEEC 620A -EAA7 620B -D0E7 620C -CAF9 620D -C8D6 620E -CFB7 620F -B3C9 6210 -CED2 6211 -BDE4 6212 -91E1 6213 -91E2 6214 -E3DE 6215 -BBF2 6216 -EAA8 6217 -D5BD 6218 -91E3 6219 -C6DD 621A -EAA9 621B -91E4 621C -91E5 621D -91E6 621E -EAAA 621F -91E7 6220 -EAAC 6221 -EAAB 6222 -91E8 6223 -EAAE 6224 -EAAD 6225 -91E9 6226 -91EA 6227 -91EB 6228 -91EC 6229 -BDD8 622A -91ED 622B -EAAF 622C -91EE 622D -C2BE 622E -91EF 622F -91F0 6230 -91F1 6231 -91F2 6232 -B4C1 6233 -B4F7 6234 -91F3 6235 -91F4 6236 -BBA7 6237 -91F5 6238 -91F6 6239 -91F7 623A -91F8 623B -91F9 623C -ECE6 623D -ECE5 623E -B7BF 623F -CBF9 6240 -B1E2 6241 -91FA 6242 -ECE7 6243 -91FB 6244 -91FC 6245 -91FD 6246 -C9C8 6247 -ECE8 6248 -ECE9 6249 -91FE 624A -CAD6 624B -DED0 624C -B2C5 624D -D4FA 624E -9240 624F -9241 6250 -C6CB 6251 -B0C7 6252 -B4F2 6253 -C8D3 6254 -9242 6255 -9243 6256 -9244 6257 -CDD0 6258 -9245 6259 -9246 625A -BFB8 625B -9247 625C -9248 625D -9249 625E -924A 625F -924B 6260 -924C 6261 -924D 6262 -BFDB 6263 -924E 6264 -924F 6265 -C7A4 6266 -D6B4 6267 -9250 6268 -C0A9 6269 -DED1 626A -C9A8 626B -D1EF 626C -C5A4 626D -B0E7 626E -B3B6 626F -C8C5 6270 -9251 6271 -9252 6272 -B0E2 6273 -9253 6274 -9254 6275 -B7F6 6276 -9255 6277 -9256 6278 -C5FA 6279 -9257 627A -9258 627B -B6F3 627C -9259 627D -D5D2 627E -B3D0 627F -BCBC 6280 -925A 6281 -925B 6282 -925C 6283 -B3AD 6284 -925D 6285 -925E 6286 -925F 6287 -9260 6288 -BEF1 6289 -B0D1 628A -9261 628B -9262 628C -9263 628D -9264 628E -9265 628F -9266 6290 -D2D6 6291 -CAE3 6292 -D7A5 6293 -9267 6294 -CDB6 6295 -B6B6 6296 -BFB9 6297 -D5DB 6298 -9268 6299 -B8A7 629A -C5D7 629B -9269 629C -926A 629D -926B 629E -DED2 629F -BFD9 62A0 -C2D5 62A1 -C7C0 62A2 -926C 62A3 -BBA4 62A4 -B1A8 62A5 -926D 62A6 -926E 62A7 -C5EA 62A8 -926F 62A9 -9270 62AA -C5FB 62AB -CCA7 62AC -9271 62AD -9272 62AE -9273 62AF -9274 62B0 -B1A7 62B1 -9275 62B2 -9276 62B3 -9277 62B4 -B5D6 62B5 -9278 62B6 -9279 62B7 -927A 62B8 -C4A8 62B9 -927B 62BA -DED3 62BB -D1BA 62BC -B3E9 62BD -927C 62BE -C3F2 62BF -927D 62C0 -927E 62C1 -B7F7 62C2 -9280 62C3 -D6F4 62C4 -B5A3 62C5 -B2F0 62C6 -C4B4 62C7 -C4E9 62C8 -C0AD 62C9 -DED4 62CA -9281 62CB -B0E8 62CC -C5C4 62CD -C1E0 62CE -9282 62CF -B9D5 62D0 -9283 62D1 -BEDC 62D2 -CDD8 62D3 -B0CE 62D4 -9284 62D5 -CDCF 62D6 -DED6 62D7 -BED0 62D8 -D7BE 62D9 -DED5 62DA -D5D0 62DB -B0DD 62DC -9285 62DD -9286 62DE -C4E2 62DF -9287 62E0 -9288 62E1 -C2A3 62E2 -BCF0 62E3 -9289 62E4 -D3B5 62E5 -C0B9 62E6 -C5A1 62E7 -B2A6 62E8 -D4F1 62E9 -928A 62EA -928B 62EB -C0A8 62EC -CAC3 62ED -DED7 62EE -D5FC 62EF -928C 62F0 -B9B0 62F1 -928D 62F2 -C8AD 62F3 -CBA9 62F4 -928E 62F5 -DED9 62F6 -BFBD 62F7 -928F 62F8 -9290 62F9 -9291 62FA -9292 62FB -C6B4 62FC -D7A7 62FD -CAB0 62FE -C4C3 62FF -9293 6300 -B3D6 6301 -B9D2 6302 -9294 6303 -9295 6304 -9296 6305 -9297 6306 -D6B8 6307 -EAFC 6308 -B0B4 6309 -9298 630A -9299 630B -929A 630C -929B 630D -BFE6 630E -929C 630F -929D 6310 -CCF4 6311 -929E 6312 -929F 6313 -92A0 6314 -92A1 6315 -CDDA 6316 -92A2 6317 -92A3 6318 -92A4 6319 -D6BF 631A -C2CE 631B -92A5 631C -CECE 631D -CCA2 631E -D0AE 631F -C4D3 6320 -B5B2 6321 -DED8 6322 -D5F5 6323 -BCB7 6324 -BBD3 6325 -92A6 6326 -92A7 6327 -B0A4 6328 -92A8 6329 -C5B2 632A -B4EC 632B -92A9 632C -92AA 632D -92AB 632E -D5F1 632F -92AC 6330 -92AD 6331 -EAFD 6332 -92AE 6333 -92AF 6334 -92B0 6335 -92B1 6336 -92B2 6337 -92B3 6338 -DEDA 6339 -CDA6 633A -92B4 633B -92B5 633C -CDEC 633D -92B6 633E -92B7 633F -92B8 6340 -92B9 6341 -CEE6 6342 -DEDC 6343 -92BA 6344 -CDB1 6345 -C0A6 6346 -92BB 6347 -92BC 6348 -D7BD 6349 -92BD 634A -DEDB 634B -B0C6 634C -BAB4 634D -C9D3 634E -C4F3 634F -BEE8 6350 -92BE 6351 -92BF 6352 -92C0 6353 -92C1 6354 -B2B6 6355 -92C2 6356 -92C3 6357 -92C4 6358 -92C5 6359 -92C6 635A -92C7 635B -92C8 635C -92C9 635D -C0CC 635E -CBF0 635F -92CA 6360 -BCF1 6361 -BBBB 6362 -B5B7 6363 -92CB 6364 -92CC 6365 -92CD 6366 -C5F5 6367 -92CE 6368 -DEE6 6369 -92CF 636A -92D0 636B -92D1 636C -DEE3 636D -BEDD 636E -92D2 636F -92D3 6370 -DEDF 6371 -92D4 6372 -92D5 6373 -92D6 6374 -92D7 6375 -B4B7 6376 -BDDD 6377 -92D8 6378 -92D9 6379 -DEE0 637A -C4ED 637B -92DA 637C -92DB 637D -92DC 637E -92DD 637F -CFC6 6380 -92DE 6381 -B5E0 6382 -92DF 6383 -92E0 6384 -92E1 6385 -92E2 6386 -B6DE 6387 -CADA 6388 -B5F4 6389 -DEE5 638A -92E3 638B -D5C6 638C -92E4 638D -DEE1 638E -CCCD 638F -C6FE 6390 -92E5 6391 -C5C5 6392 -92E6 6393 -92E7 6394 -92E8 6395 -D2B4 6396 -92E9 6397 -BEF2 6398 -92EA 6399 -92EB 639A -92EC 639B -92ED 639C -92EE 639D -92EF 639E -92F0 639F -C2D3 63A0 -92F1 63A1 -CCBD 63A2 -B3B8 63A3 -92F2 63A4 -BDD3 63A5 -92F3 63A6 -BFD8 63A7 -CDC6 63A8 -D1DA 63A9 -B4EB 63AA -92F4 63AB -DEE4 63AC -DEDD 63AD -DEE7 63AE -92F5 63AF -EAFE 63B0 -92F6 63B1 -92F7 63B2 -C2B0 63B3 -DEE2 63B4 -92F8 63B5 -92F9 63B6 -D6C0 63B7 -B5A7 63B8 -92FA 63B9 -B2F4 63BA -92FB 63BB -DEE8 63BC -92FC 63BD -DEF2 63BE -92FD 63BF -92FE 63C0 -9340 63C1 -9341 63C2 -9342 63C3 -DEED 63C4 -9343 63C5 -DEF1 63C6 -9344 63C7 -9345 63C8 -C8E0 63C9 -9346 63CA -9347 63CB -9348 63CC -D7E1 63CD -DEEF 63CE -C3E8 63CF -CCE1 63D0 -9349 63D1 -B2E5 63D2 -934A 63D3 -934B 63D4 -934C 63D5 -D2BE 63D6 -934D 63D7 -934E 63D8 -934F 63D9 -9350 63DA -9351 63DB -9352 63DC -9353 63DD -DEEE 63DE -9354 63DF -DEEB 63E0 -CED5 63E1 -9355 63E2 -B4A7 63E3 -9356 63E4 -9357 63E5 -9358 63E6 -9359 63E7 -935A 63E8 -BFAB 63E9 -BEBE 63EA -935B 63EB -935C 63EC -BDD2 63ED -935D 63EE -935E 63EF -935F 63F0 -9360 63F1 -DEE9 63F2 -9361 63F3 -D4AE 63F4 -9362 63F5 -DEDE 63F6 -9363 63F7 -DEEA 63F8 -9364 63F9 -9365 63FA -9366 63FB -9367 63FC -C0BF 63FD -9368 63FE -DEEC 63FF -B2F3 6400 -B8E9 6401 -C2A7 6402 -9369 6403 -936A 6404 -BDC1 6405 -936B 6406 -936C 6407 -936D 6408 -936E 6409 -936F 640A -DEF5 640B -DEF8 640C -9370 640D -9371 640E -B2AB 640F -B4A4 6410 -9372 6411 -9373 6412 -B4EA 6413 -C9A6 6414 -9374 6415 -9375 6416 -9376 6417 -9377 6418 -9378 6419 -9379 641A -DEF6 641B -CBD1 641C -937A 641D -B8E3 641E -937B 641F -DEF7 6420 -DEFA 6421 -937C 6422 -937D 6423 -937E 6424 -9380 6425 -DEF9 6426 -9381 6427 -9382 6428 -9383 6429 -CCC2 642A -9384 642B -B0E1 642C -B4EE 642D -9385 642E -9386 642F -9387 6430 -9388 6431 -9389 6432 -938A 6433 -E5BA 6434 -938B 6435 -938C 6436 -938D 6437 -938E 6438 -938F 6439 -D0AF 643A -9390 643B -9391 643C -B2EB 643D -9392 643E -EBA1 643F -9393 6440 -DEF4 6441 -9394 6442 -9395 6443 -C9E3 6444 -DEF3 6445 -B0DA 6446 -D2A1 6447 -B1F7 6448 -9396 6449 -CCAF 644A -9397 644B -9398 644C -9399 644D -939A 644E -939B 644F -939C 6450 -939D 6451 -DEF0 6452 -939E 6453 -CBA4 6454 -939F 6455 -93A0 6456 -93A1 6457 -D5AA 6458 -93A2 6459 -93A3 645A -93A4 645B -93A5 645C -93A6 645D -DEFB 645E -93A7 645F -93A8 6460 -93A9 6461 -93AA 6462 -93AB 6463 -93AC 6464 -93AD 6465 -93AE 6466 -B4DD 6467 -93AF 6468 -C4A6 6469 -93B0 646A -93B1 646B -93B2 646C -DEFD 646D -93B3 646E -93B4 646F -93B5 6470 -93B6 6471 -93B7 6472 -93B8 6473 -93B9 6474 -93BA 6475 -93BB 6476 -93BC 6477 -C3FE 6478 -C4A1 6479 -DFA1 647A -93BD 647B -93BE 647C -93BF 647D -93C0 647E -93C1 647F -93C2 6480 -93C3 6481 -C1CC 6482 -93C4 6483 -DEFC 6484 -BEEF 6485 -93C5 6486 -C6B2 6487 -93C6 6488 -93C7 6489 -93C8 648A -93C9 648B -93CA 648C -93CB 648D -93CC 648E -93CD 648F -93CE 6490 -B3C5 6491 -C8F6 6492 -93CF 6493 -93D0 6494 -CBBA 6495 -DEFE 6496 -93D1 6497 -93D2 6498 -DFA4 6499 -93D3 649A -93D4 649B -93D5 649C -93D6 649D -D7B2 649E -93D7 649F -93D8 64A0 -93D9 64A1 -93DA 64A2 -93DB 64A3 -B3B7 64A4 -93DC 64A5 -93DD 64A6 -93DE 64A7 -93DF 64A8 -C1C3 64A9 -93E0 64AA -93E1 64AB -C7CB 64AC -B2A5 64AD -B4E9 64AE -93E2 64AF -D7AB 64B0 -93E3 64B1 -93E4 64B2 -93E5 64B3 -93E6 64B4 -C4EC 64B5 -93E7 64B6 -DFA2 64B7 -DFA3 64B8 -93E8 64B9 -DFA5 64BA -93E9 64BB -BAB3 64BC -93EA 64BD -93EB 64BE -93EC 64BF -DFA6 64C0 -93ED 64C1 -C0DE 64C2 -93EE 64C3 -93EF 64C4 -C9C3 64C5 -93F0 64C6 -93F1 64C7 -93F2 64C8 -93F3 64C9 -93F4 64CA -93F5 64CB -93F6 64CC -B2D9 64CD -C7E6 64CE -93F7 64CF -DFA7 64D0 -93F8 64D1 -C7DC 64D2 -93F9 64D3 -93FA 64D4 -93FB 64D5 -93FC 64D6 -DFA8 64D7 -EBA2 64D8 -93FD 64D9 -93FE 64DA -9440 64DB -9441 64DC -9442 64DD -CBD3 64DE -9443 64DF -9444 64E0 -9445 64E1 -DFAA 64E2 -9446 64E3 -DFA9 64E4 -9447 64E5 -B2C1 64E6 -9448 64E7 -9449 64E8 -944A 64E9 -944B 64EA -944C 64EB -944D 64EC -944E 64ED -944F 64EE -9450 64EF -9451 64F0 -9452 64F1 -9453 64F2 -9454 64F3 -9455 64F4 -9456 64F5 -9457 64F6 -9458 64F7 -9459 64F8 -945A 64F9 -945B 64FA -945C 64FB -945D 64FC -945E 64FD -945F 64FE -9460 64FF -C5CA 6500 -9461 6501 -9462 6502 -9463 6503 -9464 6504 -9465 6505 -9466 6506 -9467 6507 -9468 6508 -DFAB 6509 -9469 650A -946A 650B -946B 650C -946C 650D -946D 650E -946E 650F -946F 6510 -9470 6511 -D4DC 6512 -9471 6513 -9472 6514 -9473 6515 -9474 6516 -9475 6517 -C8C1 6518 -9476 6519 -9477 651A -9478 651B -9479 651C -947A 651D -947B 651E -947C 651F -947D 6520 -947E 6521 -9480 6522 -9481 6523 -9482 6524 -DFAC 6525 -9483 6526 -9484 6527 -9485 6528 -9486 6529 -9487 652A -BEF0 652B -9488 652C -9489 652D -DFAD 652E -D6A7 652F -948A 6530 -948B 6531 -948C 6532 -948D 6533 -EAB7 6534 -EBB6 6535 -CAD5 6536 -948E 6537 -D8FC 6538 -B8C4 6539 -948F 653A -B9A5 653B -9490 653C -9491 653D -B7C5 653E -D5FE 653F -9492 6540 -9493 6541 -9494 6542 -9495 6543 -9496 6544 -B9CA 6545 -9497 6546 -9498 6547 -D0A7 6548 -F4CD 6549 -9499 654A -949A 654B -B5D0 654C -949B 654D -949C 654E -C3F4 654F -949D 6550 -BEC8 6551 -949E 6552 -949F 6553 -94A0 6554 -EBB7 6555 -B0BD 6556 -94A1 6557 -94A2 6558 -BDCC 6559 -94A3 655A -C1B2 655B -94A4 655C -B1D6 655D -B3A8 655E -94A5 655F -94A6 6560 -94A7 6561 -B8D2 6562 -C9A2 6563 -94A8 6564 -94A9 6565 -B6D8 6566 -94AA 6567 -94AB 6568 -94AC 6569 -94AD 656A -EBB8 656B -BEB4 656C -94AE 656D -94AF 656E -94B0 656F -CAFD 6570 -94B1 6571 -C7C3 6572 -94B2 6573 -D5FB 6574 -94B3 6575 -94B4 6576 -B7F3 6577 -94B5 6578 -94B6 6579 -94B7 657A -94B8 657B -94B9 657C -94BA 657D -94BB 657E -94BC 657F -94BD 6580 -94BE 6581 -94BF 6582 -94C0 6583 -94C1 6584 -94C2 6585 -94C3 6586 -CEC4 6587 -94C4 6588 -94C5 6589 -94C6 658A -D5AB 658B -B1F3 658C -94C7 658D -94C8 658E -94C9 658F -ECB3 6590 -B0DF 6591 -94CA 6592 -ECB5 6593 -94CB 6594 -94CC 6595 -94CD 6596 -B6B7 6597 -94CE 6598 -C1CF 6599 -94CF 659A -F5FA 659B -D0B1 659C -94D0 659D -94D1 659E -D5E5 659F -94D2 65A0 -CED3 65A1 -94D3 65A2 -94D4 65A3 -BDEF 65A4 -B3E2 65A5 -94D5 65A6 -B8AB 65A7 -94D6 65A8 -D5B6 65A9 -94D7 65AA -EDBD 65AB -94D8 65AC -B6CF 65AD -94D9 65AE -CBB9 65AF -D0C2 65B0 -94DA 65B1 -94DB 65B2 -94DC 65B3 -94DD 65B4 -94DE 65B5 -94DF 65B6 -94E0 65B7 -94E1 65B8 -B7BD 65B9 -94E2 65BA -94E3 65BB -ECB6 65BC -CAA9 65BD -94E4 65BE -94E5 65BF -94E6 65C0 -C5D4 65C1 -94E7 65C2 -ECB9 65C3 -ECB8 65C4 -C2C3 65C5 -ECB7 65C6 -94E8 65C7 -94E9 65C8 -94EA 65C9 -94EB 65CA -D0FD 65CB -ECBA 65CC -94EC 65CD -ECBB 65CE -D7E5 65CF -94ED 65D0 -94EE 65D1 -ECBC 65D2 -94EF 65D3 -94F0 65D4 -94F1 65D5 -ECBD 65D6 -C6EC 65D7 -94F2 65D8 -94F3 65D9 -94F4 65DA -94F5 65DB -94F6 65DC -94F7 65DD -94F8 65DE -94F9 65DF -CEDE 65E0 -94FA 65E1 -BCC8 65E2 -94FB 65E3 -94FC 65E4 -C8D5 65E5 -B5A9 65E6 -BEC9 65E7 -D6BC 65E8 -D4E7 65E9 -94FD 65EA -94FE 65EB -D1AE 65EC -D0F1 65ED -EAB8 65EE -EAB9 65EF -EABA 65F0 -BAB5 65F1 -9540 65F2 -9541 65F3 -9542 65F4 -9543 65F5 -CAB1 65F6 -BFF5 65F7 -9544 65F8 -9545 65F9 -CDFA 65FA -9546 65FB -9547 65FC -9548 65FD -9549 65FE -954A 65FF -EAC0 6600 -954B 6601 -B0BA 6602 -EABE 6603 -954C 6604 -954D 6605 -C0A5 6606 -954E 6607 -954F 6608 -9550 6609 -EABB 660A -9551 660B -B2FD 660C -9552 660D -C3F7 660E -BBE8 660F -9553 6610 -9554 6611 -9555 6612 -D2D7 6613 -CEF4 6614 -EABF 6615 -9556 6616 -9557 6617 -9558 6618 -EABC 6619 -9559 661A -955A 661B -955B 661C -EAC3 661D -955C 661E -D0C7 661F -D3B3 6620 -955D 6621 -955E 6622 -955F 6623 -9560 6624 -B4BA 6625 -9561 6626 -C3C1 6627 -D7F2 6628 -9562 6629 -9563 662A -9564 662B -9565 662C -D5D1 662D -9566 662E -CAC7 662F -9567 6630 -EAC5 6631 -9568 6632 -9569 6633 -EAC4 6634 -EAC7 6635 -EAC6 6636 -956A 6637 -956B 6638 -956C 6639 -956D 663A -956E 663B -D6E7 663C -956F 663D -CFD4 663E -9570 663F -9571 6640 -EACB 6641 -9572 6642 -BBCE 6643 -9573 6644 -9574 6645 -9575 6646 -9576 6647 -9577 6648 -9578 6649 -9579 664A -BDFA 664B -C9CE 664C -957A 664D -957B 664E -EACC 664F -957C 6650 -957D 6651 -C9B9 6652 -CFFE 6653 -EACA 6654 -D4CE 6655 -EACD 6656 -EACF 6657 -957E 6658 -9580 6659 -CDED 665A -9581 665B -9582 665C -9583 665D -9584 665E -EAC9 665F -9585 6660 -EACE 6661 -9586 6662 -9587 6663 -CEEE 6664 -9588 6665 -BBDE 6666 -9589 6667 -B3BF 6668 -958A 6669 -958B 666A -958C 666B -958D 666C -958E 666D -C6D5 666E -BEB0 666F -CEFA 6670 -958F 6671 -9590 6672 -9591 6673 -C7E7 6674 -9592 6675 -BEA7 6676 -EAD0 6677 -9593 6678 -9594 6679 -D6C7 667A -9595 667B -9596 667C -9597 667D -C1C0 667E -9598 667F -9599 6680 -959A 6681 -D4DD 6682 -959B 6683 -EAD1 6684 -959C 6685 -959D 6686 -CFBE 6687 -959E 6688 -959F 6689 -95A0 668A -95A1 668B -EAD2 668C -95A2 668D -95A3 668E -95A4 668F -95A5 6690 -CAEE 6691 -95A6 6692 -95A7 6693 -95A8 6694 -95A9 6695 -C5AF 6696 -B0B5 6697 -95AA 6698 -95AB 6699 -95AC 669A -95AD 669B -95AE 669C -EAD4 669D -95AF 669E -95B0 669F -95B1 66A0 -95B2 66A1 -95B3 66A2 -95B4 66A3 -95B5 66A4 -95B6 66A5 -95B7 66A6 -EAD3 66A7 -F4DF 66A8 -95B8 66A9 -95B9 66AA -95BA 66AB -95BB 66AC -95BC 66AD -C4BA 66AE -95BD 66AF -95BE 66B0 -95BF 66B1 -95C0 66B2 -95C1 66B3 -B1A9 66B4 -95C2 66B5 -95C3 66B6 -95C4 66B7 -95C5 66B8 -E5DF 66B9 -95C6 66BA -95C7 66BB -95C8 66BC -95C9 66BD -EAD5 66BE -95CA 66BF -95CB 66C0 -95CC 66C1 -95CD 66C2 -95CE 66C3 -95CF 66C4 -95D0 66C5 -95D1 66C6 -95D2 66C7 -95D3 66C8 -95D4 66C9 -95D5 66CA -95D6 66CB -95D7 66CC -95D8 66CD -95D9 66CE -95DA 66CF -95DB 66D0 -95DC 66D1 -95DD 66D2 -95DE 66D3 -95DF 66D4 -95E0 66D5 -95E1 66D6 -95E2 66D7 -95E3 66D8 -CAEF 66D9 -95E4 66DA -EAD6 66DB -EAD7 66DC -C6D8 66DD -95E5 66DE -95E6 66DF -95E7 66E0 -95E8 66E1 -95E9 66E2 -95EA 66E3 -95EB 66E4 -95EC 66E5 -EAD8 66E6 -95ED 66E7 -95EE 66E8 -EAD9 66E9 -95EF 66EA -95F0 66EB -95F1 66EC -95F2 66ED -95F3 66EE -95F4 66EF -D4BB 66F0 -95F5 66F1 -C7FA 66F2 -D2B7 66F3 -B8FC 66F4 -95F6 66F5 -95F7 66F6 -EAC2 66F7 -95F8 66F8 -B2DC 66F9 -95F9 66FA -95FA 66FB -C2FC 66FC -95FB 66FD -D4F8 66FE -CCE6 66FF -D7EE 6700 -95FC 6701 -95FD 6702 -95FE 6703 -9640 6704 -9641 6705 -9642 6706 -9643 6707 -D4C2 6708 -D3D0 6709 -EBC3 670A -C5F3 670B -9644 670C -B7FE 670D -9645 670E -9646 670F -EBD4 6710 -9647 6711 -9648 6712 -9649 6713 -CBB7 6714 -EBDE 6715 -964A 6716 -C0CA 6717 -964B 6718 -964C 6719 -964D 671A -CDFB 671B -964E 671C -B3AF 671D -964F 671E -C6DA 671F -9650 6720 -9651 6721 -9652 6722 -9653 6723 -9654 6724 -9655 6725 -EBFC 6726 -9656 6727 -C4BE 6728 -9657 6729 -CEB4 672A -C4A9 672B -B1BE 672C -D4FD 672D -9658 672E -CAF5 672F -9659 6730 -D6EC 6731 -965A 6732 -965B 6733 -C6D3 6734 -B6E4 6735 -965C 6736 -965D 6737 -965E 6738 -965F 6739 -BBFA 673A -9660 673B -9661 673C -D0E0 673D -9662 673E -9663 673F -C9B1 6740 -9664 6741 -D4D3 6742 -C8A8 6743 -9665 6744 -9666 6745 -B8CB 6746 -9667 6747 -E8BE 6748 -C9BC 6749 -9668 674A -9669 674B -E8BB 674C -966A 674D -C0EE 674E -D0D3 674F -B2C4 6750 -B4E5 6751 -966B 6752 -E8BC 6753 -966C 6754 -966D 6755 -D5C8 6756 -966E 6757 -966F 6758 -9670 6759 -9671 675A -9672 675B -B6C5 675C -9673 675D -E8BD 675E -CAF8 675F -B8DC 6760 -CCF5 6761 -9674 6762 -9675 6763 -9676 6764 -C0B4 6765 -9677 6766 -9678 6767 -D1EE 6768 -E8BF 6769 -E8C2 676A -9679 676B -967A 676C -BABC 676D -967B 676E -B1AD 676F -BDDC 6770 -967C 6771 -EABD 6772 -E8C3 6773 -967D 6774 -E8C6 6775 -967E 6776 -E8CB 6777 -9680 6778 -9681 6779 -9682 677A -9683 677B -E8CC 677C -9684 677D -CBC9 677E -B0E5 677F -9685 6780 -BCAB 6781 -9686 6782 -9687 6783 -B9B9 6784 -9688 6785 -9689 6786 -E8C1 6787 -968A 6788 -CDF7 6789 -968B 678A -E8CA 678B -968C 678C -968D 678D -968E 678E -968F 678F -CEF6 6790 -9690 6791 -9691 6792 -9692 6793 -9693 6794 -D5ED 6795 -9694 6796 -C1D6 6797 -E8C4 6798 -9695 6799 -C3B6 679A -9696 679B -B9FB 679C -D6A6 679D -E8C8 679E -9697 679F -9698 67A0 -9699 67A1 -CAE0 67A2 -D4E6 67A3 -969A 67A4 -E8C0 67A5 -969B 67A6 -E8C5 67A7 -E8C7 67A8 -969C 67A9 -C7B9 67AA -B7E3 67AB -969D 67AC -E8C9 67AD -969E 67AE -BFDD 67AF -E8D2 67B0 -969F 67B1 -96A0 67B2 -E8D7 67B3 -96A1 67B4 -E8D5 67B5 -BCDC 67B6 -BCCF 67B7 -E8DB 67B8 -96A2 67B9 -96A3 67BA -96A4 67BB -96A5 67BC -96A6 67BD -96A7 67BE -96A8 67BF -96A9 67C0 -E8DE 67C1 -96AA 67C2 -E8DA 67C3 -B1FA 67C4 -96AB 67C5 -96AC 67C6 -96AD 67C7 -96AE 67C8 -96AF 67C9 -96B0 67CA -96B1 67CB -96B2 67CC -96B3 67CD -96B4 67CE -B0D8 67CF -C4B3 67D0 -B8CC 67D1 -C6E2 67D2 -C8BE 67D3 -C8E1 67D4 -96B5 67D5 -96B6 67D6 -96B7 67D7 -E8CF 67D8 -E8D4 67D9 -E8D6 67DA -96B8 67DB -B9F1 67DC -E8D8 67DD -D7F5 67DE -96B9 67DF -C4FB 67E0 -96BA 67E1 -E8DC 67E2 -96BB 67E3 -96BC 67E4 -B2E9 67E5 -96BD 67E6 -96BE 67E7 -96BF 67E8 -E8D1 67E9 -96C0 67EA -96C1 67EB -BCED 67EC -96C2 67ED -96C3 67EE -BFC2 67EF -E8CD 67F0 -D6F9 67F1 -96C4 67F2 -C1F8 67F3 -B2F1 67F4 -96C5 67F5 -96C6 67F6 -96C7 67F7 -96C8 67F8 -96C9 67F9 -96CA 67FA -96CB 67FB -96CC 67FC -E8DF 67FD -96CD 67FE -CAC1 67FF -E8D9 6800 -96CE 6801 -96CF 6802 -96D0 6803 -96D1 6804 -D5A4 6805 -96D2 6806 -B1EA 6807 -D5BB 6808 -E8CE 6809 -E8D0 680A -B6B0 680B -E8D3 680C -96D3 680D -E8DD 680E -C0B8 680F -96D4 6810 -CAF7 6811 -96D5 6812 -CBA8 6813 -96D6 6814 -96D7 6815 -C6DC 6816 -C0F5 6817 -96D8 6818 -96D9 6819 -96DA 681A -96DB 681B -96DC 681C -E8E9 681D -96DD 681E -96DE 681F -96DF 6820 -D0A3 6821 -96E0 6822 -96E1 6823 -96E2 6824 -96E3 6825 -96E4 6826 -96E5 6827 -96E6 6828 -E8F2 6829 -D6EA 682A -96E7 682B -96E8 682C -96E9 682D -96EA 682E -96EB 682F -96EC 6830 -96ED 6831 -E8E0 6832 -E8E1 6833 -96EE 6834 -96EF 6835 -96F0 6836 -D1F9 6837 -BACB 6838 -B8F9 6839 -96F1 683A -96F2 683B -B8F1 683C -D4D4 683D -E8EF 683E -96F3 683F -E8EE 6840 -E8EC 6841 -B9F0 6842 -CCD2 6843 -E8E6 6844 -CEA6 6845 -BFF2 6846 -96F4 6847 -B0B8 6848 -E8F1 6849 -E8F0 684A -96F5 684B -D7C0 684C -96F6 684D -E8E4 684E -96F7 684F -CDA9 6850 -C9A3 6851 -96F8 6852 -BBB8 6853 -BDDB 6854 -E8EA 6855 -96F9 6856 -96FA 6857 -96FB 6858 -96FC 6859 -96FD 685A -96FE 685B -9740 685C -9741 685D -9742 685E -9743 685F -E8E2 6860 -E8E3 6861 -E8E5 6862 -B5B5 6863 -E8E7 6864 -C7C5 6865 -E8EB 6866 -E8ED 6867 -BDB0 6868 -D7AE 6869 -9744 686A -E8F8 686B -9745 686C -9746 686D -9747 686E -9748 686F -9749 6870 -974A 6871 -974B 6872 -974C 6873 -E8F5 6874 -974D 6875 -CDB0 6876 -E8F6 6877 -974E 6878 -974F 6879 -9750 687A -9751 687B -9752 687C -9753 687D -9754 687E -9755 687F -9756 6880 -C1BA 6881 -9757 6882 -E8E8 6883 -9758 6884 -C3B7 6885 -B0F0 6886 -9759 6887 -975A 6888 -975B 6889 -975C 688A -975D 688B -975E 688C -975F 688D -9760 688E -E8F4 688F -9761 6890 -9762 6891 -9763 6892 -E8F7 6893 -9764 6894 -9765 6895 -9766 6896 -B9A3 6897 -9767 6898 -9768 6899 -9769 689A -976A 689B -976B 689C -976C 689D -976D 689E -976E 689F -976F 68A0 -9770 68A1 -C9D2 68A2 -9771 68A3 -9772 68A4 -9773 68A5 -C3CE 68A6 -CEE0 68A7 -C0E6 68A8 -9774 68A9 -9775 68AA -9776 68AB -9777 68AC -CBF3 68AD -9778 68AE -CCDD 68AF -D0B5 68B0 -9779 68B1 -977A 68B2 -CAE1 68B3 -977B 68B4 -E8F3 68B5 -977C 68B6 -977D 68B7 -977E 68B8 -9780 68B9 -9781 68BA -9782 68BB -9783 68BC -9784 68BD -9785 68BE -9786 68BF -BCEC 68C0 -9787 68C1 -E8F9 68C2 -9788 68C3 -9789 68C4 -978A 68C5 -978B 68C6 -978C 68C7 -978D 68C8 -C3DE 68C9 -978E 68CA -C6E5 68CB -978F 68CC -B9F7 68CD -9790 68CE -9791 68CF -9792 68D0 -9793 68D1 -B0F4 68D2 -9794 68D3 -9795 68D4 -D7D8 68D5 -9796 68D6 -9797 68D7 -BCAC 68D8 -9798 68D9 -C5EF 68DA -9799 68DB -979A 68DC -979B 68DD -979C 68DE -979D 68DF -CCC4 68E0 -979E 68E1 -979F 68E2 -E9A6 68E3 -97A0 68E4 -97A1 68E5 -97A2 68E6 -97A3 68E7 -97A4 68E8 -97A5 68E9 -97A6 68EA -97A7 68EB -97A8 68EC -97A9 68ED -C9AD 68EE -97AA 68EF -E9A2 68F0 -C0E2 68F1 -97AB 68F2 -97AC 68F3 -97AD 68F4 -BFC3 68F5 -97AE 68F6 -97AF 68F7 -97B0 68F8 -E8FE 68F9 -B9D7 68FA -97B1 68FB -E8FB 68FC -97B2 68FD -97B3 68FE -97B4 68FF -97B5 6900 -E9A4 6901 -97B6 6902 -97B7 6903 -97B8 6904 -D2CE 6905 -97B9 6906 -97BA 6907 -97BB 6908 -97BC 6909 -97BD 690A -E9A3 690B -97BE 690C -D6B2 690D -D7B5 690E -97BF 690F -E9A7 6910 -97C0 6911 -BDB7 6912 -97C1 6913 -97C2 6914 -97C3 6915 -97C4 6916 -97C5 6917 -97C6 6918 -97C7 6919 -97C8 691A -97C9 691B -97CA 691C -97CB 691D -97CC 691E -E8FC 691F -E8FD 6920 -97CD 6921 -97CE 6922 -97CF 6923 -E9A1 6924 -97D0 6925 -97D1 6926 -97D2 6927 -97D3 6928 -97D4 6929 -97D5 692A -97D6 692B -97D7 692C -CDD6 692D -97D8 692E -97D9 692F -D2AC 6930 -97DA 6931 -97DB 6932 -97DC 6933 -E9B2 6934 -97DD 6935 -97DE 6936 -97DF 6937 -97E0 6938 -E9A9 6939 -97E1 693A -97E2 693B -97E3 693C -B4AA 693D -97E4 693E -B4BB 693F -97E5 6940 -97E6 6941 -E9AB 6942 -97E7 6943 -97E8 6944 -97E9 6945 -97EA 6946 -97EB 6947 -97EC 6948 -97ED 6949 -97EE 694A -97EF 694B -97F0 694C -97F1 694D -97F2 694E -97F3 694F -97F4 6950 -97F5 6951 -97F6 6952 -97F7 6953 -D0A8 6954 -97F8 6955 -97F9 6956 -E9A5 6957 -97FA 6958 -97FB 6959 -B3FE 695A -97FC 695B -97FD 695C -E9AC 695D -C0E3 695E -97FE 695F -E9AA 6960 -9840 6961 -9841 6962 -E9B9 6963 -9842 6964 -9843 6965 -E9B8 6966 -9844 6967 -9845 6968 -9846 6969 -9847 696A -E9AE 696B -9848 696C -9849 696D -E8FA 696E -984A 696F -984B 6970 -E9A8 6971 -984C 6972 -984D 6973 -984E 6974 -984F 6975 -9850 6976 -BFAC 6977 -E9B1 6978 -E9BA 6979 -9851 697A -9852 697B -C2A5 697C -9853 697D -9854 697E -9855 697F -E9AF 6980 -9856 6981 -B8C5 6982 -9857 6983 -E9AD 6984 -9858 6985 -D3DC 6986 -E9B4 6987 -E9B5 6988 -E9B7 6989 -9859 698A -985A 698B -985B 698C -E9C7 698D -985C 698E -985D 698F -985E 6990 -985F 6991 -9860 6992 -9861 6993 -C0C6 6994 -E9C5 6995 -9862 6996 -9863 6997 -E9B0 6998 -9864 6999 -9865 699A -E9BB 699B -B0F1 699C -9866 699D -9867 699E -9868 699F -9869 69A0 -986A 69A1 -986B 69A2 -986C 69A3 -986D 69A4 -986E 69A5 -986F 69A6 -E9BC 69A7 -D5A5 69A8 -9870 69A9 -9871 69AA -E9BE 69AB -9872 69AC -E9BF 69AD -9873 69AE -9874 69AF -9875 69B0 -E9C1 69B1 -9876 69B2 -9877 69B3 -C1F1 69B4 -9878 69B5 -9879 69B6 -C8B6 69B7 -987A 69B8 -987B 69B9 -987C 69BA -E9BD 69BB -987D 69BC -987E 69BD -9880 69BE -9881 69BF -9882 69C0 -E9C2 69C1 -9883 69C2 -9884 69C3 -9885 69C4 -9886 69C5 -9887 69C6 -9888 69C7 -9889 69C8 -988A 69C9 -E9C3 69CA -988B 69CB -E9B3 69CC -988C 69CD -E9B6 69CE -988D 69CF -BBB1 69D0 -988E 69D1 -988F 69D2 -9890 69D3 -E9C0 69D4 -9891 69D5 -9892 69D6 -9893 69D7 -9894 69D8 -9895 69D9 -9896 69DA -BCF7 69DB -9897 69DC -9898 69DD -9899 69DE -E9C4 69DF -E9C6 69E0 -989A 69E1 -989B 69E2 -989C 69E3 -989D 69E4 -989E 69E5 -989F 69E6 -98A0 69E7 -98A1 69E8 -98A2 69E9 -98A3 69EA -98A4 69EB -98A5 69EC -E9CA 69ED -98A6 69EE -98A7 69EF -98A8 69F0 -98A9 69F1 -E9CE 69F2 -98AA 69F3 -98AB 69F4 -98AC 69F5 -98AD 69F6 -98AE 69F7 -98AF 69F8 -98B0 69F9 -98B1 69FA -98B2 69FB -98B3 69FC -B2DB 69FD -98B4 69FE -E9C8 69FF -98B5 6A00 -98B6 6A01 -98B7 6A02 -98B8 6A03 -98B9 6A04 -98BA 6A05 -98BB 6A06 -98BC 6A07 -98BD 6A08 -98BE 6A09 -B7AE 6A0A -98BF 6A0B -98C0 6A0C -98C1 6A0D -98C2 6A0E -98C3 6A0F -98C4 6A10 -98C5 6A11 -98C6 6A12 -98C7 6A13 -98C8 6A14 -98C9 6A15 -98CA 6A16 -E9CB 6A17 -E9CC 6A18 -98CB 6A19 -98CC 6A1A -98CD 6A1B -98CE 6A1C -98CF 6A1D -98D0 6A1E -D5C1 6A1F -98D1 6A20 -C4A3 6A21 -98D2 6A22 -98D3 6A23 -98D4 6A24 -98D5 6A25 -98D6 6A26 -98D7 6A27 -E9D8 6A28 -98D8 6A29 -BAE1 6A2A -98D9 6A2B -98DA 6A2C -98DB 6A2D -98DC 6A2E -E9C9 6A2F -98DD 6A30 -D3A3 6A31 -98DE 6A32 -98DF 6A33 -98E0 6A34 -E9D4 6A35 -98E1 6A36 -98E2 6A37 -98E3 6A38 -98E4 6A39 -98E5 6A3A -98E6 6A3B -98E7 6A3C -E9D7 6A3D -E9D0 6A3E -98E8 6A3F -98E9 6A40 -98EA 6A41 -98EB 6A42 -98EC 6A43 -E9CF 6A44 -98ED 6A45 -98EE 6A46 -C7C1 6A47 -98EF 6A48 -98F0 6A49 -98F1 6A4A -98F2 6A4B -98F3 6A4C -98F4 6A4D -98F5 6A4E -98F6 6A4F -E9D2 6A50 -98F7 6A51 -98F8 6A52 -98F9 6A53 -98FA 6A54 -98FB 6A55 -98FC 6A56 -98FD 6A57 -E9D9 6A58 -B3C8 6A59 -98FE 6A5A -E9D3 6A5B -9940 6A5C -9941 6A5D -9942 6A5E -9943 6A5F -9944 6A60 -CFF0 6A61 -9945 6A62 -9946 6A63 -9947 6A64 -E9CD 6A65 -9948 6A66 -9949 6A67 -994A 6A68 -994B 6A69 -994C 6A6A -994D 6A6B -994E 6A6C -994F 6A6D -9950 6A6E -9951 6A6F -9952 6A70 -B3F7 6A71 -9953 6A72 -9954 6A73 -9955 6A74 -9956 6A75 -9957 6A76 -9958 6A77 -9959 6A78 -E9D6 6A79 -995A 6A7A -995B 6A7B -E9DA 6A7C -995C 6A7D -995D 6A7E -995E 6A7F -CCB4 6A80 -995F 6A81 -9960 6A82 -9961 6A83 -CFAD 6A84 -9962 6A85 -9963 6A86 -9964 6A87 -9965 6A88 -9966 6A89 -9967 6A8A -9968 6A8B -9969 6A8C -996A 6A8D -E9D5 6A8E -996B 6A8F -E9DC 6A90 -E9DB 6A91 -996C 6A92 -996D 6A93 -996E 6A94 -996F 6A95 -9970 6A96 -E9DE 6A97 -9971 6A98 -9972 6A99 -9973 6A9A -9974 6A9B -9975 6A9C -9976 6A9D -9977 6A9E -9978 6A9F -E9D1 6AA0 -9979 6AA1 -997A 6AA2 -997B 6AA3 -997C 6AA4 -997D 6AA5 -997E 6AA6 -9980 6AA7 -9981 6AA8 -E9DD 6AA9 -9982 6AAA -E9DF 6AAB -C3CA 6AAC -9983 6AAD -9984 6AAE -9985 6AAF -9986 6AB0 -9987 6AB1 -9988 6AB2 -9989 6AB3 -998A 6AB4 -998B 6AB5 -998C 6AB6 -998D 6AB7 -998E 6AB8 -998F 6AB9 -9990 6ABA -9991 6ABB -9992 6ABC -9993 6ABD -9994 6ABE -9995 6ABF -9996 6AC0 -9997 6AC1 -9998 6AC2 -9999 6AC3 -999A 6AC4 -999B 6AC5 -999C 6AC6 -999D 6AC7 -999E 6AC8 -999F 6AC9 -99A0 6ACA -99A1 6ACB -99A2 6ACC -99A3 6ACD -99A4 6ACE -99A5 6ACF -99A6 6AD0 -99A7 6AD1 -99A8 6AD2 -99A9 6AD3 -99AA 6AD4 -99AB 6AD5 -99AC 6AD6 -99AD 6AD7 -99AE 6AD8 -99AF 6AD9 -99B0 6ADA -99B1 6ADB -99B2 6ADC -99B3 6ADD -99B4 6ADE -99B5 6ADF -99B6 6AE0 -99B7 6AE1 -99B8 6AE2 -99B9 6AE3 -99BA 6AE4 -99BB 6AE5 -99BC 6AE6 -99BD 6AE7 -99BE 6AE8 -99BF 6AE9 -99C0 6AEA -99C1 6AEB -99C2 6AEC -99C3 6AED -99C4 6AEE -99C5 6AEF -99C6 6AF0 -99C7 6AF1 -99C8 6AF2 -99C9 6AF3 -99CA 6AF4 -99CB 6AF5 -99CC 6AF6 -99CD 6AF7 -99CE 6AF8 -99CF 6AF9 -99D0 6AFA -99D1 6AFB -99D2 6AFC -99D3 6AFD -99D4 6AFE -99D5 6AFF -99D6 6B00 -99D7 6B01 -99D8 6B02 -99D9 6B03 -99DA 6B04 -99DB 6B05 -99DC 6B06 -99DD 6B07 -99DE 6B08 -99DF 6B09 -99E0 6B0A -99E1 6B0B -99E2 6B0C -99E3 6B0D -99E4 6B0E -99E5 6B0F -99E6 6B10 -99E7 6B11 -99E8 6B12 -99E9 6B13 -99EA 6B14 -99EB 6B15 -99EC 6B16 -99ED 6B17 -99EE 6B18 -99EF 6B19 -99F0 6B1A -99F1 6B1B -99F2 6B1C -99F3 6B1D -99F4 6B1E -99F5 6B1F -C7B7 6B20 -B4CE 6B21 -BBB6 6B22 -D0C0 6B23 -ECA3 6B24 -99F6 6B25 -99F7 6B26 -C5B7 6B27 -99F8 6B28 -99F9 6B29 -99FA 6B2A -99FB 6B2B -99FC 6B2C -99FD 6B2D -99FE 6B2E -9A40 6B2F -9A41 6B30 -9A42 6B31 -D3FB 6B32 -9A43 6B33 -9A44 6B34 -9A45 6B35 -9A46 6B36 -ECA4 6B37 -9A47 6B38 -ECA5 6B39 -C6DB 6B3A -9A48 6B3B -9A49 6B3C -9A4A 6B3D -BFEE 6B3E -9A4B 6B3F -9A4C 6B40 -9A4D 6B41 -9A4E 6B42 -ECA6 6B43 -9A4F 6B44 -9A50 6B45 -ECA7 6B46 -D0AA 6B47 -9A51 6B48 -C7B8 6B49 -9A52 6B4A -9A53 6B4B -B8E8 6B4C -9A54 6B4D -9A55 6B4E -9A56 6B4F -9A57 6B50 -9A58 6B51 -9A59 6B52 -9A5A 6B53 -9A5B 6B54 -9A5C 6B55 -9A5D 6B56 -9A5E 6B57 -9A5F 6B58 -ECA8 6B59 -9A60 6B5A -9A61 6B5B -9A62 6B5C -9A63 6B5D -9A64 6B5E -9A65 6B5F -9A66 6B60 -9A67 6B61 -D6B9 6B62 -D5FD 6B63 -B4CB 6B64 -B2BD 6B65 -CEE4 6B66 -C6E7 6B67 -9A68 6B68 -9A69 6B69 -CDE1 6B6A -9A6A 6B6B -9A6B 6B6C -9A6C 6B6D -9A6D 6B6E -9A6E 6B6F -9A6F 6B70 -9A70 6B71 -9A71 6B72 -9A72 6B73 -9A73 6B74 -9A74 6B75 -9A75 6B76 -9A76 6B77 -9A77 6B78 -B4F5 6B79 -9A78 6B7A -CBC0 6B7B -BCDF 6B7C -9A79 6B7D -9A7A 6B7E -9A7B 6B7F -9A7C 6B80 -E9E2 6B81 -E9E3 6B82 -D1EA 6B83 -E9E5 6B84 -9A7D 6B85 -B4F9 6B86 -E9E4 6B87 -9A7E 6B88 -D1B3 6B89 -CAE2 6B8A -B2D0 6B8B -9A80 6B8C -E9E8 6B8D -9A81 6B8E -9A82 6B8F -9A83 6B90 -9A84 6B91 -E9E6 6B92 -E9E7 6B93 -9A85 6B94 -9A86 6B95 -D6B3 6B96 -9A87 6B97 -9A88 6B98 -9A89 6B99 -E9E9 6B9A -E9EA 6B9B -9A8A 6B9C -9A8B 6B9D -9A8C 6B9E -9A8D 6B9F -9A8E 6BA0 -E9EB 6BA1 -9A8F 6BA2 -9A90 6BA3 -9A91 6BA4 -9A92 6BA5 -9A93 6BA6 -9A94 6BA7 -9A95 6BA8 -9A96 6BA9 -E9EC 6BAA -9A97 6BAB -9A98 6BAC -9A99 6BAD -9A9A 6BAE -9A9B 6BAF -9A9C 6BB0 -9A9D 6BB1 -9A9E 6BB2 -ECAF 6BB3 -C5B9 6BB4 -B6CE 6BB5 -9A9F 6BB6 -D2F3 6BB7 -9AA0 6BB8 -9AA1 6BB9 -9AA2 6BBA -9AA3 6BBB -9AA4 6BBC -9AA5 6BBD -9AA6 6BBE -B5EE 6BBF -9AA7 6BC0 -BBD9 6BC1 -ECB1 6BC2 -9AA8 6BC3 -9AA9 6BC4 -D2E3 6BC5 -9AAA 6BC6 -9AAB 6BC7 -9AAC 6BC8 -9AAD 6BC9 -9AAE 6BCA -CEE3 6BCB -9AAF 6BCC -C4B8 6BCD -9AB0 6BCE -C3BF 6BCF -9AB1 6BD0 -9AB2 6BD1 -B6BE 6BD2 -D8B9 6BD3 -B1C8 6BD4 -B1CF 6BD5 -B1D1 6BD6 -C5FE 6BD7 -9AB3 6BD8 -B1D0 6BD9 -9AB4 6BDA -C3AB 6BDB -9AB5 6BDC -9AB6 6BDD -9AB7 6BDE -9AB8 6BDF -9AB9 6BE0 -D5B1 6BE1 -9ABA 6BE2 -9ABB 6BE3 -9ABC 6BE4 -9ABD 6BE5 -9ABE 6BE6 -9ABF 6BE7 -9AC0 6BE8 -9AC1 6BE9 -EBA4 6BEA -BAC1 6BEB -9AC2 6BEC -9AC3 6BED -9AC4 6BEE -CCBA 6BEF -9AC5 6BF0 -9AC6 6BF1 -9AC7 6BF2 -EBA5 6BF3 -9AC8 6BF4 -EBA7 6BF5 -9AC9 6BF6 -9ACA 6BF7 -9ACB 6BF8 -EBA8 6BF9 -9ACC 6BFA -9ACD 6BFB -9ACE 6BFC -EBA6 6BFD -9ACF 6BFE -9AD0 6BFF -9AD1 6C00 -9AD2 6C01 -9AD3 6C02 -9AD4 6C03 -9AD5 6C04 -EBA9 6C05 -EBAB 6C06 -EBAA 6C07 -9AD6 6C08 -9AD7 6C09 -9AD8 6C0A -9AD9 6C0B -9ADA 6C0C -EBAC 6C0D -9ADB 6C0E -CACF 6C0F -D8B5 6C10 -C3F1 6C11 -9ADC 6C12 -C3A5 6C13 -C6F8 6C14 -EBAD 6C15 -C4CA 6C16 -9ADD 6C17 -EBAE 6C18 -EBAF 6C19 -EBB0 6C1A -B7D5 6C1B -9ADE 6C1C -9ADF 6C1D -9AE0 6C1E -B7FA 6C1F -9AE1 6C20 -EBB1 6C21 -C7E2 6C22 -9AE2 6C23 -EBB3 6C24 -9AE3 6C25 -BAA4 6C26 -D1F5 6C27 -B0B1 6C28 -EBB2 6C29 -EBB4 6C2A -9AE4 6C2B -9AE5 6C2C -9AE6 6C2D -B5AA 6C2E -C2C8 6C2F -C7E8 6C30 -9AE7 6C31 -EBB5 6C32 -9AE8 6C33 -CBAE 6C34 -E3DF 6C35 -9AE9 6C36 -9AEA 6C37 -D3C0 6C38 -9AEB 6C39 -9AEC 6C3A -9AED 6C3B -9AEE 6C3C -D9DB 6C3D -9AEF 6C3E -9AF0 6C3F -CDA1 6C40 -D6AD 6C41 -C7F3 6C42 -9AF1 6C43 -9AF2 6C44 -9AF3 6C45 -D9E0 6C46 -BBE3 6C47 -9AF4 6C48 -BABA 6C49 -E3E2 6C4A -9AF5 6C4B -9AF6 6C4C -9AF7 6C4D -9AF8 6C4E -9AF9 6C4F -CFAB 6C50 -9AFA 6C51 -9AFB 6C52 -9AFC 6C53 -E3E0 6C54 -C9C7 6C55 -9AFD 6C56 -BAB9 6C57 -9AFE 6C58 -9B40 6C59 -9B41 6C5A -D1B4 6C5B -E3E1 6C5C -C8EA 6C5D -B9AF 6C5E -BDAD 6C5F -B3D8 6C60 -CEDB 6C61 -9B42 6C62 -9B43 6C63 -CCC0 6C64 -9B44 6C65 -9B45 6C66 -9B46 6C67 -E3E8 6C68 -E3E9 6C69 -CDF4 6C6A -9B47 6C6B -9B48 6C6C -9B49 6C6D -9B4A 6C6E -9B4B 6C6F -CCAD 6C70 -9B4C 6C71 -BCB3 6C72 -9B4D 6C73 -E3EA 6C74 -9B4E 6C75 -E3EB 6C76 -9B4F 6C77 -9B50 6C78 -D0DA 6C79 -9B51 6C7A -9B52 6C7B -9B53 6C7C -C6FB 6C7D -B7DA 6C7E -9B54 6C7F -9B55 6C80 -C7DF 6C81 -D2CA 6C82 -CED6 6C83 -9B56 6C84 -E3E4 6C85 -E3EC 6C86 -9B57 6C87 -C9F2 6C88 -B3C1 6C89 -9B58 6C8A -9B59 6C8B -E3E7 6C8C -9B5A 6C8D -9B5B 6C8E -C6E3 6C8F -E3E5 6C90 -9B5C 6C91 -9B5D 6C92 -EDB3 6C93 -E3E6 6C94 -9B5E 6C95 -9B5F 6C96 -9B60 6C97 -9B61 6C98 -C9B3 6C99 -9B62 6C9A -C5E6 6C9B -9B63 6C9C -9B64 6C9D -9B65 6C9E -B9B5 6C9F -9B66 6CA0 -C3BB 6CA1 -9B67 6CA2 -E3E3 6CA3 -C5BD 6CA4 -C1A4 6CA5 -C2D9 6CA6 -B2D7 6CA7 -9B68 6CA8 -E3ED 6CA9 -BBA6 6CAA -C4AD 6CAB -9B69 6CAC -E3F0 6CAD -BEDA 6CAE -9B6A 6CAF -9B6B 6CB0 -E3FB 6CB1 -E3F5 6CB2 -BAD3 6CB3 -9B6C 6CB4 -9B6D 6CB5 -9B6E 6CB6 -9B6F 6CB7 -B7D0 6CB8 -D3CD 6CB9 -9B70 6CBA -D6CE 6CBB -D5D3 6CBC -B9C1 6CBD -D5B4 6CBE -D1D8 6CBF -9B71 6CC0 -9B72 6CC1 -9B73 6CC2 -9B74 6CC3 -D0B9 6CC4 -C7F6 6CC5 -9B75 6CC6 -9B76 6CC7 -9B77 6CC8 -C8AA 6CC9 -B2B4 6CCA -9B78 6CCB -C3DA 6CCC -9B79 6CCD -9B7A 6CCE -9B7B 6CCF -E3EE 6CD0 -9B7C 6CD1 -9B7D 6CD2 -E3FC 6CD3 -E3EF 6CD4 -B7A8 6CD5 -E3F7 6CD6 -E3F4 6CD7 -9B7E 6CD8 -9B80 6CD9 -9B81 6CDA -B7BA 6CDB -9B82 6CDC -9B83 6CDD -C5A2 6CDE -9B84 6CDF -E3F6 6CE0 -C5DD 6CE1 -B2A8 6CE2 -C6FC 6CE3 -9B85 6CE4 -C4E0 6CE5 -9B86 6CE6 -9B87 6CE7 -D7A2 6CE8 -9B88 6CE9 -C0E1 6CEA -E3F9 6CEB -9B89 6CEC -9B8A 6CED -E3FA 6CEE -E3FD 6CEF -CCA9 6CF0 -E3F3 6CF1 -9B8B 6CF2 -D3BE 6CF3 -9B8C 6CF4 -B1C3 6CF5 -EDB4 6CF6 -E3F1 6CF7 -E3F2 6CF8 -9B8D 6CF9 -E3F8 6CFA -D0BA 6CFB -C6C3 6CFC -D4F3 6CFD -E3FE 6CFE -9B8E 6CFF -9B8F 6D00 -BDE0 6D01 -9B90 6D02 -9B91 6D03 -E4A7 6D04 -9B92 6D05 -9B93 6D06 -E4A6 6D07 -9B94 6D08 -9B95 6D09 -9B96 6D0A -D1F3 6D0B -E4A3 6D0C -9B97 6D0D -E4A9 6D0E -9B98 6D0F -9B99 6D10 -9B9A 6D11 -C8F7 6D12 -9B9B 6D13 -9B9C 6D14 -9B9D 6D15 -9B9E 6D16 -CFB4 6D17 -9B9F 6D18 -E4A8 6D19 -E4AE 6D1A -C2E5 6D1B -9BA0 6D1C -9BA1 6D1D -B6B4 6D1E -9BA2 6D1F -9BA3 6D20 -9BA4 6D21 -9BA5 6D22 -9BA6 6D23 -9BA7 6D24 -BDF2 6D25 -9BA8 6D26 -E4A2 6D27 -9BA9 6D28 -9BAA 6D29 -BAE9 6D2A -E4AA 6D2B -9BAB 6D2C -9BAC 6D2D -E4AC 6D2E -9BAD 6D2F -9BAE 6D30 -B6FD 6D31 -D6DE 6D32 -E4B2 6D33 -9BAF 6D34 -E4AD 6D35 -9BB0 6D36 -9BB1 6D37 -9BB2 6D38 -E4A1 6D39 -9BB3 6D3A -BBEE 6D3B -CDDD 6D3C -C7A2 6D3D -C5C9 6D3E -9BB4 6D3F -9BB5 6D40 -C1F7 6D41 -9BB6 6D42 -E4A4 6D43 -9BB7 6D44 -C7B3 6D45 -BDAC 6D46 -BDBD 6D47 -E4A5 6D48 -9BB8 6D49 -D7C7 6D4A -B2E2 6D4B -9BB9 6D4C -E4AB 6D4D -BCC3 6D4E -E4AF 6D4F -9BBA 6D50 -BBEB 6D51 -E4B0 6D52 -C5A8 6D53 -E4B1 6D54 -9BBB 6D55 -9BBC 6D56 -9BBD 6D57 -9BBE 6D58 -D5E3 6D59 -BFA3 6D5A -9BBF 6D5B -E4BA 6D5C -9BC0 6D5D -E4B7 6D5E -9BC1 6D5F -E4BB 6D60 -9BC2 6D61 -9BC3 6D62 -E4BD 6D63 -9BC4 6D64 -9BC5 6D65 -C6D6 6D66 -9BC6 6D67 -9BC7 6D68 -BAC6 6D69 -C0CB 6D6A -9BC8 6D6B -9BC9 6D6C -9BCA 6D6D -B8A1 6D6E -E4B4 6D6F -9BCB 6D70 -9BCC 6D71 -9BCD 6D72 -9BCE 6D73 -D4A1 6D74 -9BCF 6D75 -9BD0 6D76 -BAA3 6D77 -BDFE 6D78 -9BD1 6D79 -9BD2 6D7A -9BD3 6D7B -E4BC 6D7C -9BD4 6D7D -9BD5 6D7E -9BD6 6D7F -9BD7 6D80 -9BD8 6D81 -CDBF 6D82 -9BD9 6D83 -9BDA 6D84 -C4F9 6D85 -9BDB 6D86 -9BDC 6D87 -CFFB 6D88 -C9E6 6D89 -9BDD 6D8A -9BDE 6D8B -D3BF 6D8C -9BDF 6D8D -CFD1 6D8E -9BE0 6D8F -9BE1 6D90 -E4B3 6D91 -9BE2 6D92 -E4B8 6D93 -E4B9 6D94 -CCE9 6D95 -9BE3 6D96 -9BE4 6D97 -9BE5 6D98 -9BE6 6D99 -9BE7 6D9A -CCCE 6D9B -9BE8 6D9C -C0D4 6D9D -E4B5 6D9E -C1B0 6D9F -E4B6 6DA0 -CED0 6DA1 -9BE9 6DA2 -BBC1 6DA3 -B5D3 6DA4 -9BEA 6DA5 -C8F3 6DA6 -BDA7 6DA7 -D5C7 6DA8 -C9AC 6DA9 -B8A2 6DAA -E4CA 6DAB -9BEB 6DAC -9BEC 6DAD -E4CC 6DAE -D1C4 6DAF -9BED 6DB0 -9BEE 6DB1 -D2BA 6DB2 -9BEF 6DB3 -9BF0 6DB4 -BAAD 6DB5 -9BF1 6DB6 -9BF2 6DB7 -BAD4 6DB8 -9BF3 6DB9 -9BF4 6DBA -9BF5 6DBB -9BF6 6DBC -9BF7 6DBD -9BF8 6DBE -E4C3 6DBF -B5ED 6DC0 -9BF9 6DC1 -9BFA 6DC2 -9BFB 6DC3 -D7CD 6DC4 -E4C0 6DC5 -CFFD 6DC6 -E4BF 6DC7 -9BFC 6DC8 -9BFD 6DC9 -9BFE 6DCA -C1DC 6DCB -CCCA 6DCC -9C40 6DCD -9C41 6DCE -9C42 6DCF -9C43 6DD0 -CAE7 6DD1 -9C44 6DD2 -9C45 6DD3 -9C46 6DD4 -9C47 6DD5 -C4D7 6DD6 -9C48 6DD7 -CCD4 6DD8 -E4C8 6DD9 -9C49 6DDA -9C4A 6DDB -9C4B 6DDC -E4C7 6DDD -E4C1 6DDE -9C4C 6DDF -E4C4 6DE0 -B5AD 6DE1 -9C4D 6DE2 -9C4E 6DE3 -D3D9 6DE4 -9C4F 6DE5 -E4C6 6DE6 -9C50 6DE7 -9C51 6DE8 -9C52 6DE9 -9C53 6DEA -D2F9 6DEB -B4E3 6DEC -9C54 6DED -BBB4 6DEE -9C55 6DEF -9C56 6DF0 -C9EE 6DF1 -9C57 6DF2 -B4BE 6DF3 -9C58 6DF4 -9C59 6DF5 -9C5A 6DF6 -BBEC 6DF7 -9C5B 6DF8 -D1CD 6DF9 -9C5C 6DFA -CCED 6DFB -EDB5 6DFC -9C5D 6DFD -9C5E 6DFE -9C5F 6DFF -9C60 6E00 -9C61 6E01 -9C62 6E02 -9C63 6E03 -9C64 6E04 -C7E5 6E05 -9C65 6E06 -9C66 6E07 -9C67 6E08 -9C68 6E09 -D4A8 6E0A -9C69 6E0B -E4CB 6E0C -D7D5 6E0D -E4C2 6E0E -9C6A 6E0F -BDA5 6E10 -E4C5 6E11 -9C6B 6E12 -9C6C 6E13 -D3E6 6E14 -9C6D 6E15 -E4C9 6E16 -C9F8 6E17 -9C6E 6E18 -9C6F 6E19 -E4BE 6E1A -9C70 6E1B -9C71 6E1C -D3E5 6E1D -9C72 6E1E -9C73 6E1F -C7FE 6E20 -B6C9 6E21 -9C74 6E22 -D4FC 6E23 -B2B3 6E24 -E4D7 6E25 -9C75 6E26 -9C76 6E27 -9C77 6E28 -CEC2 6E29 -9C78 6E2A -E4CD 6E2B -9C79 6E2C -CEBC 6E2D -9C7A 6E2E -B8DB 6E2F -9C7B 6E30 -9C7C 6E31 -E4D6 6E32 -9C7D 6E33 -BFCA 6E34 -9C7E 6E35 -9C80 6E36 -9C81 6E37 -D3CE 6E38 -9C82 6E39 -C3EC 6E3A -9C83 6E3B -9C84 6E3C -9C85 6E3D -9C86 6E3E -9C87 6E3F -9C88 6E40 -9C89 6E41 -9C8A 6E42 -C5C8 6E43 -E4D8 6E44 -9C8B 6E45 -9C8C 6E46 -9C8D 6E47 -9C8E 6E48 -9C8F 6E49 -9C90 6E4A -9C91 6E4B -9C92 6E4C -CDC4 6E4D -E4CF 6E4E -9C93 6E4F -9C94 6E50 -9C95 6E51 -9C96 6E52 -E4D4 6E53 -E4D5 6E54 -9C97 6E55 -BAFE 6E56 -9C98 6E57 -CFE6 6E58 -9C99 6E59 -9C9A 6E5A -D5BF 6E5B -9C9B 6E5C -9C9C 6E5D -9C9D 6E5E -E4D2 6E5F -9C9E 6E60 -9C9F 6E61 -9CA0 6E62 -9CA1 6E63 -9CA2 6E64 -9CA3 6E65 -9CA4 6E66 -9CA5 6E67 -9CA6 6E68 -9CA7 6E69 -9CA8 6E6A -E4D0 6E6B -9CA9 6E6C -9CAA 6E6D -E4CE 6E6E -9CAB 6E6F -9CAC 6E70 -9CAD 6E71 -9CAE 6E72 -9CAF 6E73 -9CB0 6E74 -9CB1 6E75 -9CB2 6E76 -9CB3 6E77 -9CB4 6E78 -9CB5 6E79 -9CB6 6E7A -9CB7 6E7B -9CB8 6E7C -9CB9 6E7D -CDE5 6E7E -CAAA 6E7F -9CBA 6E80 -9CBB 6E81 -9CBC 6E82 -C0A3 6E83 -9CBD 6E84 -BDA6 6E85 -E4D3 6E86 -9CBE 6E87 -9CBF 6E88 -B8C8 6E89 -9CC0 6E8A -9CC1 6E8B -9CC2 6E8C -9CC3 6E8D -9CC4 6E8E -E4E7 6E8F -D4B4 6E90 -9CC5 6E91 -9CC6 6E92 -9CC7 6E93 -9CC8 6E94 -9CC9 6E95 -9CCA 6E96 -9CCB 6E97 -E4DB 6E98 -9CCC 6E99 -9CCD 6E9A -9CCE 6E9B -C1EF 6E9C -9CCF 6E9D -9CD0 6E9E -E4E9 6E9F -9CD1 6EA0 -9CD2 6EA1 -D2E7 6EA2 -9CD3 6EA3 -9CD4 6EA4 -E4DF 6EA5 -9CD5 6EA6 -E4E0 6EA7 -9CD6 6EA8 -9CD7 6EA9 -CFAA 6EAA -9CD8 6EAB -9CD9 6EAC -9CDA 6EAD -9CDB 6EAE -CBDD 6EAF -9CDC 6EB0 -E4DA 6EB1 -E4D1 6EB2 -9CDD 6EB3 -E4E5 6EB4 -9CDE 6EB5 -C8DC 6EB6 -E4E3 6EB7 -9CDF 6EB8 -9CE0 6EB9 -C4E7 6EBA -E4E2 6EBB -9CE1 6EBC -E4E1 6EBD -9CE2 6EBE -9CE3 6EBF -9CE4 6EC0 -B3FC 6EC1 -E4E8 6EC2 -9CE5 6EC3 -9CE6 6EC4 -9CE7 6EC5 -9CE8 6EC6 -B5E1 6EC7 -9CE9 6EC8 -9CEA 6EC9 -9CEB 6ECA -D7CC 6ECB -9CEC 6ECC -9CED 6ECD -9CEE 6ECE -E4E6 6ECF -9CEF 6ED0 -BBAC 6ED1 -9CF0 6ED2 -D7D2 6ED3 -CCCF 6ED4 -EBF8 6ED5 -9CF1 6ED6 -E4E4 6ED7 -9CF2 6ED8 -9CF3 6ED9 -B9F6 6EDA -9CF4 6EDB -9CF5 6EDC -9CF6 6EDD -D6CD 6EDE -E4D9 6EDF -E4DC 6EE0 -C2FA 6EE1 -E4DE 6EE2 -9CF7 6EE3 -C2CB 6EE4 -C0C4 6EE5 -C2D0 6EE6 -9CF8 6EE7 -B1F5 6EE8 -CCB2 6EE9 -9CF9 6EEA -9CFA 6EEB -9CFB 6EEC -9CFC 6EED -9CFD 6EEE -9CFE 6EEF -9D40 6EF0 -9D41 6EF1 -9D42 6EF2 -9D43 6EF3 -B5CE 6EF4 -9D44 6EF5 -9D45 6EF6 -9D46 6EF7 -9D47 6EF8 -E4EF 6EF9 -9D48 6EFA -9D49 6EFB -9D4A 6EFC -9D4B 6EFD -9D4C 6EFE -9D4D 6EFF -9D4E 6F00 -9D4F 6F01 -C6AF 6F02 -9D50 6F03 -9D51 6F04 -9D52 6F05 -C6E1 6F06 -9D53 6F07 -9D54 6F08 -E4F5 6F09 -9D55 6F0A -9D56 6F0B -9D57 6F0C -9D58 6F0D -9D59 6F0E -C2A9 6F0F -9D5A 6F10 -9D5B 6F11 -9D5C 6F12 -C0EC 6F13 -D1DD 6F14 -E4EE 6F15 -9D5D 6F16 -9D5E 6F17 -9D5F 6F18 -9D60 6F19 -9D61 6F1A -9D62 6F1B -9D63 6F1C -9D64 6F1D -9D65 6F1E -9D66 6F1F -C4AE 6F20 -9D67 6F21 -9D68 6F22 -9D69 6F23 -E4ED 6F24 -9D6A 6F25 -9D6B 6F26 -9D6C 6F27 -9D6D 6F28 -E4F6 6F29 -E4F4 6F2A -C2FE 6F2B -9D6E 6F2C -E4DD 6F2D -9D6F 6F2E -E4F0 6F2F -9D70 6F30 -CAFE 6F31 -9D71 6F32 -D5C4 6F33 -9D72 6F34 -9D73 6F35 -E4F1 6F36 -9D74 6F37 -9D75 6F38 -9D76 6F39 -9D77 6F3A -9D78 6F3B -9D79 6F3C -9D7A 6F3D -D1FA 6F3E -9D7B 6F3F -9D7C 6F40 -9D7D 6F41 -9D7E 6F42 -9D80 6F43 -9D81 6F44 -9D82 6F45 -E4EB 6F46 -E4EC 6F47 -9D83 6F48 -9D84 6F49 -9D85 6F4A -E4F2 6F4B -9D86 6F4C -CEAB 6F4D -9D87 6F4E -9D88 6F4F -9D89 6F50 -9D8A 6F51 -9D8B 6F52 -9D8C 6F53 -9D8D 6F54 -9D8E 6F55 -9D8F 6F56 -9D90 6F57 -C5CB 6F58 -9D91 6F59 -9D92 6F5A -9D93 6F5B -C7B1 6F5C -9D94 6F5D -C2BA 6F5E -9D95 6F5F -9D96 6F60 -9D97 6F61 -E4EA 6F62 -9D98 6F63 -9D99 6F64 -9D9A 6F65 -C1CA 6F66 -9D9B 6F67 -9D9C 6F68 -9D9D 6F69 -9D9E 6F6A -9D9F 6F6B -9DA0 6F6C -CCB6 6F6D -B3B1 6F6E -9DA1 6F6F -9DA2 6F70 -9DA3 6F71 -E4FB 6F72 -9DA4 6F73 -E4F3 6F74 -9DA5 6F75 -9DA6 6F76 -9DA7 6F77 -E4FA 6F78 -9DA8 6F79 -E4FD 6F7A -9DA9 6F7B -E4FC 6F7C -9DAA 6F7D -9DAB 6F7E -9DAC 6F7F -9DAD 6F80 -9DAE 6F81 -9DAF 6F82 -9DB0 6F83 -B3CE 6F84 -9DB1 6F85 -9DB2 6F86 -9DB3 6F87 -B3BA 6F88 -E4F7 6F89 -9DB4 6F8A -9DB5 6F8B -E4F9 6F8C -E4F8 6F8D -C5EC 6F8E -9DB6 6F8F -9DB7 6F90 -9DB8 6F91 -9DB9 6F92 -9DBA 6F93 -9DBB 6F94 -9DBC 6F95 -9DBD 6F96 -9DBE 6F97 -9DBF 6F98 -9DC0 6F99 -9DC1 6F9A -9DC2 6F9B -C0BD 6F9C -9DC3 6F9D -9DC4 6F9E -9DC5 6F9F -9DC6 6FA0 -D4E8 6FA1 -9DC7 6FA2 -9DC8 6FA3 -9DC9 6FA4 -9DCA 6FA5 -9DCB 6FA6 -E5A2 6FA7 -9DCC 6FA8 -9DCD 6FA9 -9DCE 6FAA -9DCF 6FAB -9DD0 6FAC -9DD1 6FAD -9DD2 6FAE -9DD3 6FAF -9DD4 6FB0 -9DD5 6FB1 -9DD6 6FB2 -B0C4 6FB3 -9DD7 6FB4 -9DD8 6FB5 -E5A4 6FB6 -9DD9 6FB7 -9DDA 6FB8 -E5A3 6FB9 -9DDB 6FBA -9DDC 6FBB -9DDD 6FBC -9DDE 6FBD -9DDF 6FBE -9DE0 6FBF -BCA4 6FC0 -9DE1 6FC1 -E5A5 6FC2 -9DE2 6FC3 -9DE3 6FC4 -9DE4 6FC5 -9DE5 6FC6 -9DE6 6FC7 -9DE7 6FC8 -E5A1 6FC9 -9DE8 6FCA -9DE9 6FCB -9DEA 6FCC -9DEB 6FCD -9DEC 6FCE -9DED 6FCF -9DEE 6FD0 -E4FE 6FD1 -B1F4 6FD2 -9DEF 6FD3 -9DF0 6FD4 -9DF1 6FD5 -9DF2 6FD6 -9DF3 6FD7 -9DF4 6FD8 -9DF5 6FD9 -9DF6 6FDA -9DF7 6FDB -9DF8 6FDC -9DF9 6FDD -E5A8 6FDE -9DFA 6FDF -E5A9 6FE0 -E5A6 6FE1 -9DFB 6FE2 -9DFC 6FE3 -9DFD 6FE4 -9DFE 6FE5 -9E40 6FE6 -9E41 6FE7 -9E42 6FE8 -9E43 6FE9 -9E44 6FEA -9E45 6FEB -9E46 6FEC -9E47 6FED -E5A7 6FEE -E5AA 6FEF -9E48 6FF0 -9E49 6FF1 -9E4A 6FF2 -9E4B 6FF3 -9E4C 6FF4 -9E4D 6FF5 -9E4E 6FF6 -9E4F 6FF7 -9E50 6FF8 -9E51 6FF9 -9E52 6FFA -9E53 6FFB -9E54 6FFC -9E55 6FFD -9E56 6FFE -9E57 6FFF -9E58 7000 -9E59 7001 -9E5A 7002 -9E5B 7003 -9E5C 7004 -9E5D 7005 -9E5E 7006 -9E5F 7007 -9E60 7008 -9E61 7009 -9E62 700A -9E63 700B -9E64 700C -9E65 700D -9E66 700E -9E67 700F -9E68 7010 -C6D9 7011 -9E69 7012 -9E6A 7013 -9E6B 7014 -9E6C 7015 -9E6D 7016 -9E6E 7017 -9E6F 7018 -9E70 7019 -E5AB 701A -E5AD 701B -9E71 701C -9E72 701D -9E73 701E -9E74 701F -9E75 7020 -9E76 7021 -9E77 7022 -E5AC 7023 -9E78 7024 -9E79 7025 -9E7A 7026 -9E7B 7027 -9E7C 7028 -9E7D 7029 -9E7E 702A -9E80 702B -9E81 702C -9E82 702D -9E83 702E -9E84 702F -9E85 7030 -9E86 7031 -9E87 7032 -9E88 7033 -9E89 7034 -E5AF 7035 -9E8A 7036 -9E8B 7037 -9E8C 7038 -E5AE 7039 -9E8D 703A -9E8E 703B -9E8F 703C -9E90 703D -9E91 703E -9E92 703F -9E93 7040 -9E94 7041 -9E95 7042 -9E96 7043 -9E97 7044 -9E98 7045 -9E99 7046 -9E9A 7047 -9E9B 7048 -9E9C 7049 -9E9D 704A -9E9E 704B -B9E0 704C -9E9F 704D -9EA0 704E -E5B0 704F -9EA1 7050 -9EA2 7051 -9EA3 7052 -9EA4 7053 -9EA5 7054 -9EA6 7055 -9EA7 7056 -9EA8 7057 -9EA9 7058 -9EAA 7059 -9EAB 705A -9EAC 705B -9EAD 705C -9EAE 705D -E5B1 705E -9EAF 705F -9EB0 7060 -9EB1 7061 -9EB2 7062 -9EB3 7063 -9EB4 7064 -9EB5 7065 -9EB6 7066 -9EB7 7067 -9EB8 7068 -9EB9 7069 -9EBA 706A -BBF0 706B -ECE1 706C -C3F0 706D -9EBB 706E -B5C6 706F -BBD2 7070 -9EBC 7071 -9EBD 7072 -9EBE 7073 -9EBF 7074 -C1E9 7075 -D4EE 7076 -9EC0 7077 -BEC4 7078 -9EC1 7079 -9EC2 707A -9EC3 707B -D7C6 707C -9EC4 707D -D4D6 707E -B2D3 707F -ECBE 7080 -9EC5 7081 -9EC6 7082 -9EC7 7083 -9EC8 7084 -EAC1 7085 -9EC9 7086 -9ECA 7087 -9ECB 7088 -C2AF 7089 -B4B6 708A -9ECC 708B -9ECD 708C -9ECE 708D -D1D7 708E -9ECF 708F -9ED0 7090 -9ED1 7091 -B3B4 7092 -9ED2 7093 -C8B2 7094 -BFBB 7095 -ECC0 7096 -9ED3 7097 -9ED4 7098 -D6CB 7099 -9ED5 709A -9ED6 709B -ECBF 709C -ECC1 709D -9ED7 709E -9ED8 709F -9ED9 70A0 -9EDA 70A1 -9EDB 70A2 -9EDC 70A3 -9EDD 70A4 -9EDE 70A5 -9EDF 70A6 -9EE0 70A7 -9EE1 70A8 -9EE2 70A9 -9EE3 70AA -ECC5 70AB -BEE6 70AC -CCBF 70AD -C5DA 70AE -BEBC 70AF -9EE4 70B0 -ECC6 70B1 -9EE5 70B2 -B1FE 70B3 -9EE6 70B4 -9EE7 70B5 -9EE8 70B6 -ECC4 70B7 -D5A8 70B8 -B5E3 70B9 -9EE9 70BA -ECC2 70BB -C1B6 70BC -B3E3 70BD -9EEA 70BE -9EEB 70BF -ECC3 70C0 -CBB8 70C1 -C0C3 70C2 -CCFE 70C3 -9EEC 70C4 -9EED 70C5 -9EEE 70C6 -9EEF 70C7 -C1D2 70C8 -9EF0 70C9 -ECC8 70CA -9EF1 70CB -9EF2 70CC -9EF3 70CD -9EF4 70CE -9EF5 70CF -9EF6 70D0 -9EF7 70D1 -9EF8 70D2 -9EF9 70D3 -9EFA 70D4 -9EFB 70D5 -9EFC 70D6 -9EFD 70D7 -BAE6 70D8 -C0D3 70D9 -9EFE 70DA -D6F2 70DB -9F40 70DC -9F41 70DD -9F42 70DE -D1CC 70DF -9F43 70E0 -9F44 70E1 -9F45 70E2 -9F46 70E3 -BFBE 70E4 -9F47 70E5 -B7B3 70E6 -C9D5 70E7 -ECC7 70E8 -BBE2 70E9 -9F48 70EA -CCCC 70EB -BDFD 70EC -C8C8 70ED -9F49 70EE -CFA9 70EF -9F4A 70F0 -9F4B 70F1 -9F4C 70F2 -9F4D 70F3 -9F4E 70F4 -9F4F 70F5 -9F50 70F6 -CDE9 70F7 -9F51 70F8 -C5EB 70F9 -9F52 70FA -9F53 70FB -9F54 70FC -B7E9 70FD -9F55 70FE -9F56 70FF -9F57 7100 -9F58 7101 -9F59 7102 -9F5A 7103 -9F5B 7104 -9F5C 7105 -9F5D 7106 -9F5E 7107 -9F5F 7108 -D1C9 7109 -BAB8 710A -9F60 710B -9F61 710C -9F62 710D -9F63 710E -9F64 710F -ECC9 7110 -9F65 7111 -9F66 7112 -ECCA 7113 -9F67 7114 -BBC0 7115 -ECCB 7116 -9F68 7117 -ECE2 7118 -B1BA 7119 -B7D9 711A -9F69 711B -9F6A 711C -9F6B 711D -9F6C 711E -9F6D 711F -9F6E 7120 -9F6F 7121 -9F70 7122 -9F71 7123 -9F72 7124 -9F73 7125 -BDB9 7126 -9F74 7127 -9F75 7128 -9F76 7129 -9F77 712A -9F78 712B -9F79 712C -9F7A 712D -9F7B 712E -ECCC 712F -D1E6 7130 -ECCD 7131 -9F7C 7132 -9F7D 7133 -9F7E 7134 -9F80 7135 -C8BB 7136 -9F81 7137 -9F82 7138 -9F83 7139 -9F84 713A -9F85 713B -9F86 713C -9F87 713D -9F88 713E -9F89 713F -9F8A 7140 -9F8B 7141 -9F8C 7142 -9F8D 7143 -9F8E 7144 -ECD1 7145 -9F8F 7146 -9F90 7147 -9F91 7148 -9F92 7149 -ECD3 714A -9F93 714B -BBCD 714C -9F94 714D -BCE5 714E -9F95 714F -9F96 7150 -9F97 7151 -9F98 7152 -9F99 7153 -9F9A 7154 -9F9B 7155 -9F9C 7156 -9F9D 7157 -9F9E 7158 -9F9F 7159 -9FA0 715A -9FA1 715B -ECCF 715C -9FA2 715D -C9B7 715E -9FA3 715F -9FA4 7160 -9FA5 7161 -9FA6 7162 -9FA7 7163 -C3BA 7164 -9FA8 7165 -ECE3 7166 -D5D5 7167 -ECD0 7168 -9FA9 7169 -9FAA 716A -9FAB 716B -9FAC 716C -9FAD 716D -D6F3 716E -9FAE 716F -9FAF 7170 -9FB0 7171 -ECD2 7172 -ECCE 7173 -9FB1 7174 -9FB2 7175 -9FB3 7176 -9FB4 7177 -ECD4 7178 -9FB5 7179 -ECD5 717A -9FB6 717B -9FB7 717C -C9BF 717D -9FB8 717E -9FB9 717F -9FBA 7180 -9FBB 7181 -9FBC 7182 -9FBD 7183 -CFA8 7184 -9FBE 7185 -9FBF 7186 -9FC0 7187 -9FC1 7188 -9FC2 7189 -D0DC 718A -9FC3 718B -9FC4 718C -9FC5 718D -9FC6 718E -D1AC 718F -9FC7 7190 -9FC8 7191 -9FC9 7192 -9FCA 7193 -C8DB 7194 -9FCB 7195 -9FCC 7196 -9FCD 7197 -ECD6 7198 -CEF5 7199 -9FCE 719A -9FCF 719B -9FD0 719C -9FD1 719D -9FD2 719E -CAEC 719F -ECDA 71A0 -9FD3 71A1 -9FD4 71A2 -9FD5 71A3 -9FD6 71A4 -9FD7 71A5 -9FD8 71A6 -9FD9 71A7 -ECD9 71A8 -9FDA 71A9 -9FDB 71AA -9FDC 71AB -B0BE 71AC -9FDD 71AD -9FDE 71AE -9FDF 71AF -9FE0 71B0 -9FE1 71B1 -9FE2 71B2 -ECD7 71B3 -9FE3 71B4 -ECD8 71B5 -9FE4 71B6 -9FE5 71B7 -9FE6 71B8 -ECE4 71B9 -9FE7 71BA -9FE8 71BB -9FE9 71BC -9FEA 71BD -9FEB 71BE -9FEC 71BF -9FED 71C0 -9FEE 71C1 -9FEF 71C2 -C8BC 71C3 -9FF0 71C4 -9FF1 71C5 -9FF2 71C6 -9FF3 71C7 -9FF4 71C8 -9FF5 71C9 -9FF6 71CA -9FF7 71CB -9FF8 71CC -9FF9 71CD -C1C7 71CE -9FFA 71CF -9FFB 71D0 -9FFC 71D1 -9FFD 71D2 -9FFE 71D3 -ECDC 71D4 -D1E0 71D5 -A040 71D6 -A041 71D7 -A042 71D8 -A043 71D9 -A044 71DA -A045 71DB -A046 71DC -A047 71DD -A048 71DE -A049 71DF -ECDB 71E0 -A04A 71E1 -A04B 71E2 -A04C 71E3 -A04D 71E4 -D4EF 71E5 -A04E 71E6 -ECDD 71E7 -A04F 71E8 -A050 71E9 -A051 71EA -A052 71EB -A053 71EC -A054 71ED -DBC6 71EE -A055 71EF -A056 71F0 -A057 71F1 -A058 71F2 -A059 71F3 -A05A 71F4 -A05B 71F5 -A05C 71F6 -A05D 71F7 -A05E 71F8 -ECDE 71F9 -A05F 71FA -A060 71FB -A061 71FC -A062 71FD -A063 71FE -A064 71FF -A065 7200 -A066 7201 -A067 7202 -A068 7203 -A069 7204 -A06A 7205 -B1AC 7206 -A06B 7207 -A06C 7208 -A06D 7209 -A06E 720A -A06F 720B -A070 720C -A071 720D -A072 720E -A073 720F -A074 7210 -A075 7211 -A076 7212 -A077 7213 -A078 7214 -A079 7215 -A07A 7216 -A07B 7217 -A07C 7218 -A07D 7219 -A07E 721A -A080 721B -A081 721C -ECDF 721D -A082 721E -A083 721F -A084 7220 -A085 7221 -A086 7222 -A087 7223 -A088 7224 -A089 7225 -A08A 7226 -A08B 7227 -ECE0 7228 -A08C 7229 -D7A6 722A -A08D 722B -C5C0 722C -A08E 722D -A08F 722E -A090 722F -EBBC 7230 -B0AE 7231 -A091 7232 -A092 7233 -A093 7234 -BEF4 7235 -B8B8 7236 -D2AF 7237 -B0D6 7238 -B5F9 7239 -A094 723A -D8B3 723B -A095 723C -CBAC 723D -A096 723E -E3DD 723F -A097 7240 -A098 7241 -A099 7242 -A09A 7243 -A09B 7244 -A09C 7245 -A09D 7246 -C6AC 7247 -B0E6 7248 -A09E 7249 -A09F 724A -A0A0 724B -C5C6 724C -EBB9 724D -A0A1 724E -A0A2 724F -A0A3 7250 -A0A4 7251 -EBBA 7252 -A0A5 7253 -A0A6 7254 -A0A7 7255 -EBBB 7256 -A0A8 7257 -A0A9 7258 -D1C0 7259 -A0AA 725A -C5A3 725B -A0AB 725C -EAF2 725D -A0AC 725E -C4B2 725F -A0AD 7260 -C4B5 7261 -C0CE 7262 -A0AE 7263 -A0AF 7264 -A0B0 7265 -EAF3 7266 -C4C1 7267 -A0B1 7268 -CEEF 7269 -A0B2 726A -A0B3 726B -A0B4 726C -A0B5 726D -EAF0 726E -EAF4 726F -A0B6 7270 -A0B7 7271 -C9FC 7272 -A0B8 7273 -A0B9 7274 -C7A3 7275 -A0BA 7276 -A0BB 7277 -A0BC 7278 -CCD8 7279 -CEFE 727A -A0BD 727B -A0BE 727C -A0BF 727D -EAF5 727E -EAF6 727F -CFAC 7280 -C0E7 7281 -A0C0 7282 -A0C1 7283 -EAF7 7284 -A0C2 7285 -A0C3 7286 -A0C4 7287 -A0C5 7288 -A0C6 7289 -B6BF 728A -EAF8 728B -A0C7 728C -EAF9 728D -A0C8 728E -EAFA 728F -A0C9 7290 -A0CA 7291 -EAFB 7292 -A0CB 7293 -A0CC 7294 -A0CD 7295 -A0CE 7296 -A0CF 7297 -A0D0 7298 -A0D1 7299 -A0D2 729A -A0D3 729B -A0D4 729C -A0D5 729D -A0D6 729E -EAF1 729F -A0D7 72A0 -A0D8 72A1 -A0D9 72A2 -A0DA 72A3 -A0DB 72A4 -A0DC 72A5 -A0DD 72A6 -A0DE 72A7 -A0DF 72A8 -A0E0 72A9 -A0E1 72AA -A0E2 72AB -C8AE 72AC -E1EB 72AD -A0E3 72AE -B7B8 72AF -E1EC 72B0 -A0E4 72B1 -A0E5 72B2 -A0E6 72B3 -E1ED 72B4 -A0E7 72B5 -D7B4 72B6 -E1EE 72B7 -E1EF 72B8 -D3CC 72B9 -A0E8 72BA -A0E9 72BB -A0EA 72BC -A0EB 72BD -A0EC 72BE -A0ED 72BF -A0EE 72C0 -E1F1 72C1 -BFF1 72C2 -E1F0 72C3 -B5D2 72C4 -A0EF 72C5 -A0F0 72C6 -A0F1 72C7 -B1B7 72C8 -A0F2 72C9 -A0F3 72CA -A0F4 72CB -A0F5 72CC -E1F3 72CD -E1F2 72CE -A0F6 72CF -BAFC 72D0 -A0F7 72D1 -E1F4 72D2 -A0F8 72D3 -A0F9 72D4 -A0FA 72D5 -A0FB 72D6 -B9B7 72D7 -A0FC 72D8 -BED1 72D9 -A0FD 72DA -A0FE 72DB -AA40 72DC -AA41 72DD -C4FC 72DE -AA42 72DF -BADD 72E0 -BDC6 72E1 -AA43 72E2 -AA44 72E3 -AA45 72E4 -AA46 72E5 -AA47 72E6 -AA48 72E7 -E1F5 72E8 -E1F7 72E9 -AA49 72EA -AA4A 72EB -B6C0 72EC -CFC1 72ED -CAA8 72EE -E1F6 72EF -D5F8 72F0 -D3FC 72F1 -E1F8 72F2 -E1FC 72F3 -E1F9 72F4 -AA4B 72F5 -AA4C 72F6 -E1FA 72F7 -C0EA 72F8 -AA4D 72F9 -E1FE 72FA -E2A1 72FB -C0C7 72FC -AA4E 72FD -AA4F 72FE -AA50 72FF -AA51 7300 -E1FB 7301 -AA52 7302 -E1FD 7303 -AA53 7304 -AA54 7305 -AA55 7306 -AA56 7307 -AA57 7308 -AA58 7309 -E2A5 730A -AA59 730B -AA5A 730C -AA5B 730D -C1D4 730E -AA5C 730F -AA5D 7310 -AA5E 7311 -AA5F 7312 -E2A3 7313 -AA60 7314 -E2A8 7315 -B2FE 7316 -E2A2 7317 -AA61 7318 -AA62 7319 -AA63 731A -C3CD 731B -B2C2 731C -E2A7 731D -E2A6 731E -AA64 731F -AA65 7320 -E2A4 7321 -E2A9 7322 -AA66 7323 -AA67 7324 -E2AB 7325 -AA68 7326 -AA69 7327 -AA6A 7328 -D0C9 7329 -D6ED 732A -C3A8 732B -E2AC 732C -AA6B 732D -CFD7 732E -AA6C 732F -AA6D 7330 -E2AE 7331 -AA6E 7332 -AA6F 7333 -BAEF 7334 -AA70 7335 -AA71 7336 -E9E0 7337 -E2AD 7338 -E2AA 7339 -AA72 733A -AA73 733B -AA74 733C -AA75 733D -BBAB 733E -D4B3 733F -AA76 7340 -AA77 7341 -AA78 7342 -AA79 7343 -AA7A 7344 -AA7B 7345 -AA7C 7346 -AA7D 7347 -AA7E 7348 -AA80 7349 -AA81 734A -AA82 734B -AA83 734C -E2B0 734D -AA84 734E -AA85 734F -E2AF 7350 -AA86 7351 -E9E1 7352 -AA87 7353 -AA88 7354 -AA89 7355 -AA8A 7356 -E2B1 7357 -AA8B 7358 -AA8C 7359 -AA8D 735A -AA8E 735B -AA8F 735C -AA90 735D -AA91 735E -AA92 735F -E2B2 7360 -AA93 7361 -AA94 7362 -AA95 7363 -AA96 7364 -AA97 7365 -AA98 7366 -AA99 7367 -AA9A 7368 -AA9B 7369 -AA9C 736A -AA9D 736B -E2B3 736C -CCA1 736D -AA9E 736E -E2B4 736F -AA9F 7370 -AAA0 7371 -AB40 7372 -AB41 7373 -AB42 7374 -AB43 7375 -AB44 7376 -AB45 7377 -AB46 7378 -AB47 7379 -AB48 737A -AB49 737B -AB4A 737C -AB4B 737D -E2B5 737E -AB4C 737F -AB4D 7380 -AB4E 7381 -AB4F 7382 -AB50 7383 -D0FE 7384 -AB51 7385 -AB52 7386 -C2CA 7387 -AB53 7388 -D3F1 7389 -AB54 738A -CDF5 738B -AB55 738C -AB56 738D -E7E0 738E -AB57 738F -AB58 7390 -E7E1 7391 -AB59 7392 -AB5A 7393 -AB5B 7394 -AB5C 7395 -BEC1 7396 -AB5D 7397 -AB5E 7398 -AB5F 7399 -AB60 739A -C2EA 739B -AB61 739C -AB62 739D -AB63 739E -E7E4 739F -AB64 73A0 -AB65 73A1 -E7E3 73A2 -AB66 73A3 -AB67 73A4 -AB68 73A5 -AB69 73A6 -AB6A 73A7 -AB6B 73A8 -CDE6 73A9 -AB6C 73AA -C3B5 73AB -AB6D 73AC -AB6E 73AD -E7E2 73AE -BBB7 73AF -CFD6 73B0 -AB6F 73B1 -C1E1 73B2 -E7E9 73B3 -AB70 73B4 -AB71 73B5 -AB72 73B6 -E7E8 73B7 -AB73 73B8 -AB74 73B9 -E7F4 73BA -B2A3 73BB -AB75 73BC -AB76 73BD -AB77 73BE -AB78 73BF -E7EA 73C0 -AB79 73C1 -E7E6 73C2 -AB7A 73C3 -AB7B 73C4 -AB7C 73C5 -AB7D 73C6 -AB7E 73C7 -E7EC 73C8 -E7EB 73C9 -C9BA 73CA -AB80 73CB -AB81 73CC -D5E4 73CD -AB82 73CE -E7E5 73CF -B7A9 73D0 -E7E7 73D1 -AB83 73D2 -AB84 73D3 -AB85 73D4 -AB86 73D5 -AB87 73D6 -AB88 73D7 -AB89 73D8 -E7EE 73D9 -AB8A 73DA -AB8B 73DB -AB8C 73DC -AB8D 73DD -E7F3 73DE -AB8E 73DF -D6E9 73E0 -AB8F 73E1 -AB90 73E2 -AB91 73E3 -AB92 73E4 -E7ED 73E5 -AB93 73E6 -E7F2 73E7 -AB94 73E8 -E7F1 73E9 -AB95 73EA -AB96 73EB -AB97 73EC -B0E0 73ED -AB98 73EE -AB99 73EF -AB9A 73F0 -AB9B 73F1 -E7F5 73F2 -AB9C 73F3 -AB9D 73F4 -AB9E 73F5 -AB9F 73F6 -ABA0 73F7 -AC40 73F8 -AC41 73F9 -AC42 73FA -AC43 73FB -AC44 73FC -AC45 73FD -AC46 73FE -AC47 73FF -AC48 7400 -AC49 7401 -AC4A 7402 -C7F2 7403 -AC4B 7404 -C0C5 7405 -C0ED 7406 -AC4C 7407 -AC4D 7408 -C1F0 7409 -E7F0 740A -AC4E 740B -AC4F 740C -AC50 740D -AC51 740E -E7F6 740F -CBF6 7410 -AC52 7411 -AC53 7412 -AC54 7413 -AC55 7414 -AC56 7415 -AC57 7416 -AC58 7417 -AC59 7418 -AC5A 7419 -E8A2 741A -E8A1 741B -AC5B 741C -AC5C 741D -AC5D 741E -AC5E 741F -AC5F 7420 -AC60 7421 -D7C1 7422 -AC61 7423 -AC62 7424 -E7FA 7425 -E7F9 7426 -AC63 7427 -E7FB 7428 -AC64 7429 -E7F7 742A -AC65 742B -E7FE 742C -AC66 742D -E7FD 742E -AC67 742F -E7FC 7430 -AC68 7431 -AC69 7432 -C1D5 7433 -C7D9 7434 -C5FD 7435 -C5C3 7436 -AC6A 7437 -AC6B 7438 -AC6C 7439 -AC6D 743A -AC6E 743B -C7ED 743C -AC6F 743D -AC70 743E -AC71 743F -AC72 7440 -E8A3 7441 -AC73 7442 -AC74 7443 -AC75 7444 -AC76 7445 -AC77 7446 -AC78 7447 -AC79 7448 -AC7A 7449 -AC7B 744A -AC7C 744B -AC7D 744C -AC7E 744D -AC80 744E -AC81 744F -AC82 7450 -AC83 7451 -AC84 7452 -AC85 7453 -AC86 7454 -E8A6 7455 -AC87 7456 -E8A5 7457 -AC88 7458 -E8A7 7459 -BAF7 745A -E7F8 745B -E8A4 745C -AC89 745D -C8F0 745E -C9AA 745F -AC8A 7460 -AC8B 7461 -AC8C 7462 -AC8D 7463 -AC8E 7464 -AC8F 7465 -AC90 7466 -AC91 7467 -AC92 7468 -AC93 7469 -AC94 746A -AC95 746B -AC96 746C -E8A9 746D -AC97 746E -AC98 746F -B9E5 7470 -AC99 7471 -AC9A 7472 -AC9B 7473 -AC9C 7474 -AC9D 7475 -D1FE 7476 -E8A8 7477 -AC9E 7478 -AC9F 7479 -ACA0 747A -AD40 747B -AD41 747C -AD42 747D -E8AA 747E -AD43 747F -E8AD 7480 -E8AE 7481 -AD44 7482 -C1A7 7483 -AD45 7484 -AD46 7485 -AD47 7486 -E8AF 7487 -AD48 7488 -AD49 7489 -AD4A 748A -E8B0 748B -AD4B 748C -AD4C 748D -E8AC 748E -AD4D 748F -E8B4 7490 -AD4E 7491 -AD4F 7492 -AD50 7493 -AD51 7494 -AD52 7495 -AD53 7496 -AD54 7497 -AD55 7498 -AD56 7499 -AD57 749A -AD58 749B -E8AB 749C -AD59 749D -E8B1 749E -AD5A 749F -AD5B 74A0 -AD5C 74A1 -AD5D 74A2 -AD5E 74A3 -AD5F 74A4 -AD60 74A5 -AD61 74A6 -E8B5 74A7 -E8B2 74A8 -E8B3 74A9 -AD62 74AA -AD63 74AB -AD64 74AC -AD65 74AD -AD66 74AE -AD67 74AF -AD68 74B0 -AD69 74B1 -AD6A 74B2 -AD6B 74B3 -AD6C 74B4 -AD6D 74B5 -AD6E 74B6 -AD6F 74B7 -AD70 74B8 -AD71 74B9 -E8B7 74BA -AD72 74BB -AD73 74BC -AD74 74BD -AD75 74BE -AD76 74BF -AD77 74C0 -AD78 74C1 -AD79 74C2 -AD7A 74C3 -AD7B 74C4 -AD7C 74C5 -AD7D 74C6 -AD7E 74C7 -AD80 74C8 -AD81 74C9 -AD82 74CA -AD83 74CB -AD84 74CC -AD85 74CD -AD86 74CE -AD87 74CF -AD88 74D0 -AD89 74D1 -E8B6 74D2 -AD8A 74D3 -AD8B 74D4 -AD8C 74D5 -AD8D 74D6 -AD8E 74D7 -AD8F 74D8 -AD90 74D9 -AD91 74DA -AD92 74DB -B9CF 74DC -AD93 74DD -F0AC 74DE -AD94 74DF -F0AD 74E0 -AD95 74E1 -C6B0 74E2 -B0EA 74E3 -C8BF 74E4 -AD96 74E5 -CDDF 74E6 -AD97 74E7 -AD98 74E8 -AD99 74E9 -AD9A 74EA -AD9B 74EB -AD9C 74EC -AD9D 74ED -CECD 74EE -EAB1 74EF -AD9E 74F0 -AD9F 74F1 -ADA0 74F2 -AE40 74F3 -EAB2 74F4 -AE41 74F5 -C6BF 74F6 -B4C9 74F7 -AE42 74F8 -AE43 74F9 -AE44 74FA -AE45 74FB -AE46 74FC -AE47 74FD -AE48 74FE -EAB3 74FF -AE49 7500 -AE4A 7501 -AE4B 7502 -AE4C 7503 -D5E7 7504 -AE4D 7505 -AE4E 7506 -AE4F 7507 -AE50 7508 -AE51 7509 -AE52 750A -AE53 750B -AE54 750C -DDF9 750D -AE55 750E -EAB4 750F -AE56 7510 -EAB5 7511 -AE57 7512 -EAB6 7513 -AE58 7514 -AE59 7515 -AE5A 7516 -AE5B 7517 -B8CA 7518 -DFB0 7519 -C9F5 751A -AE5C 751B -CCF0 751C -AE5D 751D -AE5E 751E -C9FA 751F -AE5F 7520 -AE60 7521 -AE61 7522 -AE62 7523 -AE63 7524 -C9FB 7525 -AE64 7526 -AE65 7527 -D3C3 7528 -CBA6 7529 -AE66 752A -B8A6 752B -F0AE 752C -B1C2 752D -AE67 752E -E5B8 752F -CCEF 7530 -D3C9 7531 -BCD7 7532 -C9EA 7533 -AE68 7534 -B5E7 7535 -AE69 7536 -C4D0 7537 -B5E9 7538 -AE6A 7539 -EEAE 753A -BBAD 753B -AE6B 753C -AE6C 753D -E7DE 753E -AE6D 753F -EEAF 7540 -AE6E 7541 -AE6F 7542 -AE70 7543 -AE71 7544 -B3A9 7545 -AE72 7546 -AE73 7547 -EEB2 7548 -AE74 7549 -AE75 754A -EEB1 754B -BDE7 754C -AE76 754D -EEB0 754E -CEB7 754F -AE77 7550 -AE78 7551 -AE79 7552 -AE7A 7553 -C5CF 7554 -AE7B 7555 -AE7C 7556 -AE7D 7557 -AE7E 7558 -C1F4 7559 -DBCE 755A -EEB3 755B -D0F3 755C -AE80 755D -AE81 755E -AE82 755F -AE83 7560 -AE84 7561 -AE85 7562 -AE86 7563 -AE87 7564 -C2D4 7565 -C6E8 7566 -AE88 7567 -AE89 7568 -AE8A 7569 -B7AC 756A -AE8B 756B -AE8C 756C -AE8D 756D -AE8E 756E -AE8F 756F -AE90 7570 -AE91 7571 -EEB4 7572 -AE92 7573 -B3EB 7574 -AE93 7575 -AE94 7576 -AE95 7577 -BBFB 7578 -EEB5 7579 -AE96 757A -AE97 757B -AE98 757C -AE99 757D -AE9A 757E -E7DC 757F -AE9B 7580 -AE9C 7581 -AE9D 7582 -EEB6 7583 -AE9E 7584 -AE9F 7585 -BDAE 7586 -AEA0 7587 -AF40 7588 -AF41 7589 -AF42 758A -F1E2 758B -AF43 758C -AF44 758D -AF45 758E -CAE8 758F -AF46 7590 -D2C9 7591 -F0DA 7592 -AF47 7593 -F0DB 7594 -AF48 7595 -F0DC 7596 -C1C6 7597 -AF49 7598 -B8ED 7599 -BECE 759A -AF4A 759B -AF4B 759C -F0DE 759D -AF4C 759E -C5B1 759F -F0DD 75A0 -D1F1 75A1 -AF4D 75A2 -F0E0 75A3 -B0CC 75A4 -BDEA 75A5 -AF4E 75A6 -AF4F 75A7 -AF50 75A8 -AF51 75A9 -AF52 75AA -D2DF 75AB -F0DF 75AC -AF53 75AD -B4AF 75AE -B7E8 75AF -F0E6 75B0 -F0E5 75B1 -C6A3 75B2 -F0E1 75B3 -F0E2 75B4 -B4C3 75B5 -AF54 75B6 -AF55 75B7 -F0E3 75B8 -D5EE 75B9 -AF56 75BA -AF57 75BB -CCDB 75BC -BED2 75BD -BCB2 75BE -AF58 75BF -AF59 75C0 -AF5A 75C1 -F0E8 75C2 -F0E7 75C3 -F0E4 75C4 -B2A1 75C5 -AF5B 75C6 -D6A2 75C7 -D3B8 75C8 -BEB7 75C9 -C8AC 75CA -AF5C 75CB -AF5D 75CC -F0EA 75CD -AF5E 75CE -AF5F 75CF -AF60 75D0 -AF61 75D1 -D1F7 75D2 -AF62 75D3 -D6CC 75D4 -BADB 75D5 -F0E9 75D6 -AF63 75D7 -B6BB 75D8 -AF64 75D9 -AF65 75DA -CDB4 75DB -AF66 75DC -AF67 75DD -C6A6 75DE -AF68 75DF -AF69 75E0 -AF6A 75E1 -C1A1 75E2 -F0EB 75E3 -F0EE 75E4 -AF6B 75E5 -F0ED 75E6 -F0F0 75E7 -F0EC 75E8 -AF6C 75E9 -BBBE 75EA -F0EF 75EB -AF6D 75EC -AF6E 75ED -AF6F 75EE -AF70 75EF -CCB5 75F0 -F0F2 75F1 -AF71 75F2 -AF72 75F3 -B3D5 75F4 -AF73 75F5 -AF74 75F6 -AF75 75F7 -AF76 75F8 -B1D4 75F9 -AF77 75FA -AF78 75FB -F0F3 75FC -AF79 75FD -AF7A 75FE -F0F4 75FF -F0F6 7600 -B4E1 7601 -AF7B 7602 -F0F1 7603 -AF7C 7604 -F0F7 7605 -AF7D 7606 -AF7E 7607 -AF80 7608 -AF81 7609 -F0FA 760A -AF82 760B -F0F8 760C -AF83 760D -AF84 760E -AF85 760F -F0F5 7610 -AF86 7611 -AF87 7612 -AF88 7613 -AF89 7614 -F0FD 7615 -AF8A 7616 -F0F9 7617 -F0FC 7618 -F0FE 7619 -AF8B 761A -F1A1 761B -AF8C 761C -AF8D 761D -AF8E 761E -CEC1 761F -F1A4 7620 -AF8F 7621 -F1A3 7622 -AF90 7623 -C1F6 7624 -F0FB 7625 -CADD 7626 -AF91 7627 -AF92 7628 -B4F1 7629 -B1F1 762A -CCB1 762B -AF93 762C -F1A6 762D -AF94 762E -AF95 762F -F1A7 7630 -AF96 7631 -AF97 7632 -F1AC 7633 -D5CE 7634 -F1A9 7635 -AF98 7636 -AF99 7637 -C8B3 7638 -AF9A 7639 -AF9B 763A -AF9C 763B -F1A2 763C -AF9D 763D -F1AB 763E -F1A8 763F -F1A5 7640 -AF9E 7641 -AF9F 7642 -F1AA 7643 -AFA0 7644 -B040 7645 -B041 7646 -B042 7647 -B043 7648 -B044 7649 -B045 764A -B046 764B -B0A9 764C -F1AD 764D -B047 764E -B048 764F -B049 7650 -B04A 7651 -B04B 7652 -B04C 7653 -F1AF 7654 -B04D 7655 -F1B1 7656 -B04E 7657 -B04F 7658 -B050 7659 -B051 765A -B052 765B -F1B0 765C -B053 765D -F1AE 765E -B054 765F -B055 7660 -B056 7661 -B057 7662 -D1A2 7663 -B058 7664 -B059 7665 -B05A 7666 -B05B 7667 -B05C 7668 -B05D 7669 -B05E 766A -F1B2 766B -B05F 766C -B060 766D -B061 766E -F1B3 766F -B062 7670 -B063 7671 -B064 7672 -B065 7673 -B066 7674 -B067 7675 -B068 7676 -B069 7677 -B9EF 7678 -B06A 7679 -B06B 767A -B5C7 767B -B06C 767C -B0D7 767D -B0D9 767E -B06D 767F -B06E 7680 -B06F 7681 -D4ED 7682 -B070 7683 -B5C4 7684 -B071 7685 -BDD4 7686 -BBCA 7687 -F0A7 7688 -B072 7689 -B073 768A -B8DE 768B -B074 768C -B075 768D -F0A8 768E -B076 768F -B077 7690 -B0A8 7691 -B078 7692 -F0A9 7693 -B079 7694 -B07A 7695 -CDEE 7696 -B07B 7697 -B07C 7698 -F0AA 7699 -B07D 769A -B07E 769B -B080 769C -B081 769D -B082 769E -B083 769F -B084 76A0 -B085 76A1 -B086 76A2 -B087 76A3 -F0AB 76A4 -B088 76A5 -B089 76A6 -B08A 76A7 -B08B 76A8 -B08C 76A9 -B08D 76AA -B08E 76AB -B08F 76AC -B090 76AD -C6A4 76AE -B091 76AF -B092 76B0 -D6E5 76B1 -F1E4 76B2 -B093 76B3 -F1E5 76B4 -B094 76B5 -B095 76B6 -B096 76B7 -B097 76B8 -B098 76B9 -B099 76BA -B09A 76BB -B09B 76BC -B09C 76BD -B09D 76BE -C3F3 76BF -B09E 76C0 -B09F 76C1 -D3DB 76C2 -B0A0 76C3 -B140 76C4 -D6D1 76C5 -C5E8 76C6 -B141 76C7 -D3AF 76C8 -B142 76C9 -D2E6 76CA -B143 76CB -B144 76CC -EEC1 76CD -B0BB 76CE -D5B5 76CF -D1CE 76D0 -BCE0 76D1 -BAD0 76D2 -B145 76D3 -BFF8 76D4 -B146 76D5 -B8C7 76D6 -B5C1 76D7 -C5CC 76D8 -B147 76D9 -B148 76DA -CAA2 76DB -B149 76DC -B14A 76DD -B14B 76DE -C3CB 76DF -B14C 76E0 -B14D 76E1 -B14E 76E2 -B14F 76E3 -B150 76E4 -EEC2 76E5 -B151 76E6 -B152 76E7 -B153 76E8 -B154 76E9 -B155 76EA -B156 76EB -B157 76EC -B158 76ED -C4BF 76EE -B6A2 76EF -B159 76F0 -EDEC 76F1 -C3A4 76F2 -B15A 76F3 -D6B1 76F4 -B15B 76F5 -B15C 76F6 -B15D 76F7 -CFE0 76F8 -EDEF 76F9 -B15E 76FA -B15F 76FB -C5CE 76FC -B160 76FD -B6DC 76FE -B161 76FF -B162 7700 -CAA1 7701 -B163 7702 -B164 7703 -EDED 7704 -B165 7705 -B166 7706 -EDF0 7707 -EDF1 7708 -C3BC 7709 -B167 770A -BFB4 770B -B168 770C -EDEE 770D -B169 770E -B16A 770F -B16B 7710 -B16C 7711 -B16D 7712 -B16E 7713 -B16F 7714 -B170 7715 -B171 7716 -B172 7717 -B173 7718 -EDF4 7719 -EDF2 771A -B174 771B -B175 771C -B176 771D -B177 771E -D5E6 771F -C3DF 7720 -B178 7721 -EDF3 7722 -B179 7723 -B17A 7724 -B17B 7725 -EDF6 7726 -B17C 7727 -D5A3 7728 -D1A3 7729 -B17D 772A -B17E 772B -B180 772C -EDF5 772D -B181 772E -C3D0 772F -B182 7730 -B183 7731 -B184 7732 -B185 7733 -B186 7734 -EDF7 7735 -BFF4 7736 -BEEC 7737 -EDF8 7738 -B187 7739 -CCF7 773A -B188 773B -D1DB 773C -B189 773D -B18A 773E -B18B 773F -D7C5 7740 -D5F6 7741 -B18C 7742 -EDFC 7743 -B18D 7744 -B18E 7745 -B18F 7746 -EDFB 7747 -B190 7748 -B191 7749 -B192 774A -B193 774B -B194 774C -B195 774D -B196 774E -B197 774F -EDF9 7750 -EDFA 7751 -B198 7752 -B199 7753 -B19A 7754 -B19B 7755 -B19C 7756 -B19D 7757 -B19E 7758 -B19F 7759 -EDFD 775A -BEA6 775B -B1A0 775C -B240 775D -B241 775E -B242 775F -B243 7760 -CBAF 7761 -EEA1 7762 -B6BD 7763 -B244 7764 -EEA2 7765 -C4C0 7766 -B245 7767 -EDFE 7768 -B246 7769 -B247 776A -BDDE 776B -B2C7 776C -B248 776D -B249 776E -B24A 776F -B24B 7770 -B24C 7771 -B24D 7772 -B24E 7773 -B24F 7774 -B250 7775 -B251 7776 -B252 7777 -B253 7778 -B6C3 7779 -B254 777A -B255 777B -B256 777C -EEA5 777D -D8BA 777E -EEA3 777F -EEA6 7780 -B257 7781 -B258 7782 -B259 7783 -C3E9 7784 -B3F2 7785 -B25A 7786 -B25B 7787 -B25C 7788 -B25D 7789 -B25E 778A -B25F 778B -EEA7 778C -EEA4 778D -CFB9 778E -B260 778F -B261 7790 -EEA8 7791 -C2F7 7792 -B262 7793 -B263 7794 -B264 7795 -B265 7796 -B266 7797 -B267 7798 -B268 7799 -B269 779A -B26A 779B -B26B 779C -B26C 779D -B26D 779E -EEA9 779F -EEAA 77A0 -B26E 77A1 -DEAB 77A2 -B26F 77A3 -B270 77A4 -C6B3 77A5 -B271 77A6 -C7C6 77A7 -B272 77A8 -D6F5 77A9 -B5C9 77AA -B273 77AB -CBB2 77AC -B274 77AD -B275 77AE -B276 77AF -EEAB 77B0 -B277 77B1 -B278 77B2 -CDAB 77B3 -B279 77B4 -EEAC 77B5 -B27A 77B6 -B27B 77B7 -B27C 77B8 -B27D 77B9 -B27E 77BA -D5B0 77BB -B280 77BC -EEAD 77BD -B281 77BE -F6C4 77BF -B282 77C0 -B283 77C1 -B284 77C2 -B285 77C3 -B286 77C4 -B287 77C5 -B288 77C6 -B289 77C7 -B28A 77C8 -B28B 77C9 -B28C 77CA -B28D 77CB -B28E 77CC -DBC7 77CD -B28F 77CE -B290 77CF -B291 77D0 -B292 77D1 -B293 77D2 -B294 77D3 -B295 77D4 -B296 77D5 -B297 77D6 -B4A3 77D7 -B298 77D8 -B299 77D9 -B29A 77DA -C3AC 77DB -F1E6 77DC -B29B 77DD -B29C 77DE -B29D 77DF -B29E 77E0 -B29F 77E1 -CAB8 77E2 -D2D3 77E3 -B2A0 77E4 -D6AA 77E5 -B340 77E6 -EFF2 77E7 -B341 77E8 -BED8 77E9 -B342 77EA -BDC3 77EB -EFF3 77EC -B6CC 77ED -B0AB 77EE -B343 77EF -B344 77F0 -B345 77F1 -B346 77F2 -CAAF 77F3 -B347 77F4 -B348 77F5 -EDB6 77F6 -B349 77F7 -EDB7 77F8 -B34A 77F9 -B34B 77FA -B34C 77FB -B34D 77FC -CEF9 77FD -B7AF 77FE -BFF3 77FF -EDB8 7800 -C2EB 7801 -C9B0 7802 -B34E 7803 -B34F 7804 -B350 7805 -B351 7806 -B352 7807 -B353 7808 -EDB9 7809 -B354 780A -B355 780B -C6F6 780C -BFB3 780D -B356 780E -B357 780F -B358 7810 -EDBC 7811 -C5F8 7812 -B359 7813 -D1D0 7814 -B35A 7815 -D7A9 7816 -EDBA 7817 -EDBB 7818 -B35B 7819 -D1E2 781A -B35C 781B -EDBF 781C -EDC0 781D -B35D 781E -EDC4 781F -B35E 7820 -B35F 7821 -B360 7822 -EDC8 7823 -B361 7824 -EDC6 7825 -EDCE 7826 -D5E8 7827 -B362 7828 -EDC9 7829 -B363 782A -B364 782B -EDC7 782C -EDBE 782D -B365 782E -B366 782F -C5E9 7830 -B367 7831 -B368 7832 -B369 7833 -C6C6 7834 -B36A 7835 -B36B 7836 -C9E9 7837 -D4D2 7838 -EDC1 7839 -EDC2 783A -EDC3 783B -EDC5 783C -B36C 783D -C0F9 783E -B36D 783F -B4A1 7840 -B36E 7841 -B36F 7842 -B370 7843 -B371 7844 -B9E8 7845 -B372 7846 -EDD0 7847 -B373 7848 -B374 7849 -B375 784A -B376 784B -EDD1 784C -B377 784D -EDCA 784E -B378 784F -EDCF 7850 -B379 7851 -CEF8 7852 -B37A 7853 -B37B 7854 -CBB6 7855 -EDCC 7856 -EDCD 7857 -B37C 7858 -B37D 7859 -B37E 785A -B380 785B -B381 785C -CFF5 785D -B382 785E -B383 785F -B384 7860 -B385 7861 -B386 7862 -B387 7863 -B388 7864 -B389 7865 -B38A 7866 -B38B 7867 -B38C 7868 -B38D 7869 -EDD2 786A -C1F2 786B -D3B2 786C -EDCB 786D -C8B7 786E -B38E 786F -B38F 7870 -B390 7871 -B391 7872 -B392 7873 -B393 7874 -B394 7875 -B395 7876 -BCEF 7877 -B396 7878 -B397 7879 -B398 787A -B399 787B -C5F0 787C -B39A 787D -B39B 787E -B39C 787F -B39D 7880 -B39E 7881 -B39F 7882 -B3A0 7883 -B440 7884 -B441 7885 -B442 7886 -EDD6 7887 -B443 7888 -B5EF 7889 -B444 788A -B445 788B -C2B5 788C -B0AD 788D -CBE9 788E -B446 788F -B447 7890 -B1AE 7891 -B448 7892 -EDD4 7893 -B449 7894 -B44A 7895 -B44B 7896 -CDEB 7897 -B5E2 7898 -B44C 7899 -EDD5 789A -EDD3 789B -EDD7 789C -B44D 789D -B44E 789E -B5FA 789F -B44F 78A0 -EDD8 78A1 -B450 78A2 -EDD9 78A3 -B451 78A4 -EDDC 78A5 -B452 78A6 -B1CC 78A7 -B453 78A8 -B454 78A9 -B455 78AA -B456 78AB -B457 78AC -B458 78AD -B459 78AE -B45A 78AF -C5F6 78B0 -BCEE 78B1 -EDDA 78B2 -CCBC 78B3 -B2EA 78B4 -B45B 78B5 -B45C 78B6 -B45D 78B7 -B45E 78B8 -EDDB 78B9 -B45F 78BA -B460 78BB -B461 78BC -B462 78BD -C4EB 78BE -B463 78BF -B464 78C0 -B4C5 78C1 -B465 78C2 -B466 78C3 -B467 78C4 -B0F5 78C5 -B468 78C6 -B469 78C7 -B46A 78C8 -EDDF 78C9 -C0DA 78CA -B4E8 78CB -B46B 78CC -B46C 78CD -B46D 78CE -B46E 78CF -C5CD 78D0 -B46F 78D1 -B470 78D2 -B471 78D3 -EDDD 78D4 -BFC4 78D5 -B472 78D6 -B473 78D7 -B474 78D8 -EDDE 78D9 -B475 78DA -B476 78DB -B477 78DC -B478 78DD -B479 78DE -B47A 78DF -B47B 78E0 -B47C 78E1 -B47D 78E2 -B47E 78E3 -B480 78E4 -B481 78E5 -B482 78E6 -B483 78E7 -C4A5 78E8 -B484 78E9 -B485 78EA -B486 78EB -EDE0 78EC -B487 78ED -B488 78EE -B489 78EF -B48A 78F0 -B48B 78F1 -EDE1 78F2 -B48C 78F3 -EDE3 78F4 -B48D 78F5 -B48E 78F6 -C1D7 78F7 -B48F 78F8 -B490 78F9 -BBC7 78FA -B491 78FB -B492 78FC -B493 78FD -B494 78FE -B495 78FF -B496 7900 -BDB8 7901 -B497 7902 -B498 7903 -B499 7904 -EDE2 7905 -B49A 7906 -B49B 7907 -B49C 7908 -B49D 7909 -B49E 790A -B49F 790B -B4A0 790C -B540 790D -B541 790E -B542 790F -B543 7910 -B544 7911 -B545 7912 -EDE4 7913 -B546 7914 -B547 7915 -B548 7916 -B549 7917 -B54A 7918 -B54B 7919 -B54C 791A -B54D 791B -B54E 791C -B54F 791D -EDE6 791E -B550 791F -B551 7920 -B552 7921 -B553 7922 -B554 7923 -EDE5 7924 -B555 7925 -B556 7926 -B557 7927 -B558 7928 -B559 7929 -B55A 792A -B55B 792B -B55C 792C -B55D 792D -B55E 792E -B55F 792F -B560 7930 -B561 7931 -B562 7932 -B563 7933 -EDE7 7934 -B564 7935 -B565 7936 -B566 7937 -B567 7938 -B568 7939 -CABE 793A -ECEA 793B -C0F1 793C -B569 793D -C9E7 793E -B56A 793F -ECEB 7940 -C6EE 7941 -B56B 7942 -B56C 7943 -B56D 7944 -B56E 7945 -ECEC 7946 -B56F 7947 -C6ED 7948 -ECED 7949 -B570 794A -B571 794B -B572 794C -B573 794D -B574 794E -B575 794F -B576 7950 -B577 7951 -B578 7952 -ECF0 7953 -B579 7954 -B57A 7955 -D7E6 7956 -ECF3 7957 -B57B 7958 -B57C 7959 -ECF1 795A -ECEE 795B -ECEF 795C -D7A3 795D -C9F1 795E -CBEE 795F -ECF4 7960 -B57D 7961 -ECF2 7962 -B57E 7963 -B580 7964 -CFE9 7965 -B581 7966 -ECF6 7967 -C6B1 7968 -B582 7969 -B583 796A -B584 796B -B585 796C -BCC0 796D -B586 796E -ECF5 796F -B587 7970 -B588 7971 -B589 7972 -B58A 7973 -B58B 7974 -B58C 7975 -B58D 7976 -B5BB 7977 -BBF6 7978 -B58E 7979 -ECF7 797A -B58F 797B -B590 797C -B591 797D -B592 797E -B593 797F -D9F7 7980 -BDFB 7981 -B594 7982 -B595 7983 -C2BB 7984 -ECF8 7985 -B596 7986 -B597 7987 -B598 7988 -B599 7989 -ECF9 798A -B59A 798B -B59B 798C -B59C 798D -B59D 798E -B8A3 798F -B59E 7990 -B59F 7991 -B5A0 7992 -B640 7993 -B641 7994 -B642 7995 -B643 7996 -B644 7997 -B645 7998 -B646 7999 -ECFA 799A -B647 799B -B648 799C -B649 799D -B64A 799E -B64B 799F -B64C 79A0 -B64D 79A1 -B64E 79A2 -B64F 79A3 -B650 79A4 -B651 79A5 -B652 79A6 -ECFB 79A7 -B653 79A8 -B654 79A9 -B655 79AA -B656 79AB -B657 79AC -B658 79AD -B659 79AE -B65A 79AF -B65B 79B0 -B65C 79B1 -B65D 79B2 -ECFC 79B3 -B65E 79B4 -B65F 79B5 -B660 79B6 -B661 79B7 -B662 79B8 -D3ED 79B9 -D8AE 79BA -C0EB 79BB -B663 79BC -C7DD 79BD -BACC 79BE -B664 79BF -D0E3 79C0 -CBBD 79C1 -B665 79C2 -CDBA 79C3 -B666 79C4 -B667 79C5 -B8D1 79C6 -B668 79C7 -B669 79C8 -B1FC 79C9 -B66A 79CA -C7EF 79CB -B66B 79CC -D6D6 79CD -B66C 79CE -B66D 79CF -B66E 79D0 -BFC6 79D1 -C3EB 79D2 -B66F 79D3 -B670 79D4 -EFF5 79D5 -B671 79D6 -B672 79D7 -C3D8 79D8 -B673 79D9 -B674 79DA -B675 79DB -B676 79DC -B677 79DD -B678 79DE -D7E2 79DF -B679 79E0 -B67A 79E1 -B67B 79E2 -EFF7 79E3 -B3D3 79E4 -B67C 79E5 -C7D8 79E6 -D1ED 79E7 -B67D 79E8 -D6C8 79E9 -B67E 79EA -EFF8 79EB -B680 79EC -EFF6 79ED -B681 79EE -BBFD 79EF -B3C6 79F0 -B682 79F1 -B683 79F2 -B684 79F3 -B685 79F4 -B686 79F5 -B687 79F6 -B688 79F7 -BDD5 79F8 -B689 79F9 -B68A 79FA -D2C6 79FB -B68B 79FC -BBE0 79FD -B68C 79FE -B68D 79FF -CFA1 7A00 -B68E 7A01 -EFFC 7A02 -EFFB 7A03 -B68F 7A04 -B690 7A05 -EFF9 7A06 -B691 7A07 -B692 7A08 -B693 7A09 -B694 7A0A -B3CC 7A0B -B695 7A0C -C9D4 7A0D -CBB0 7A0E -B696 7A0F -B697 7A10 -B698 7A11 -B699 7A12 -B69A 7A13 -EFFE 7A14 -B69B 7A15 -B69C 7A16 -B0DE 7A17 -B69D 7A18 -B69E 7A19 -D6C9 7A1A -B69F 7A1B -B6A0 7A1C -B740 7A1D -EFFD 7A1E -B741 7A1F -B3ED 7A20 -B742 7A21 -B743 7A22 -F6D5 7A23 -B744 7A24 -B745 7A25 -B746 7A26 -B747 7A27 -B748 7A28 -B749 7A29 -B74A 7A2A -B74B 7A2B -B74C 7A2C -B74D 7A2D -B74E 7A2E -B74F 7A2F -B750 7A30 -B751 7A31 -B752 7A32 -CEC8 7A33 -B753 7A34 -B754 7A35 -B755 7A36 -F0A2 7A37 -B756 7A38 -F0A1 7A39 -B757 7A3A -B5BE 7A3B -BCDA 7A3C -BBFC 7A3D -B758 7A3E -B8E5 7A3F -B759 7A40 -B75A 7A41 -B75B 7A42 -B75C 7A43 -B75D 7A44 -B75E 7A45 -C4C2 7A46 -B75F 7A47 -B760 7A48 -B761 7A49 -B762 7A4A -B763 7A4B -B764 7A4C -B765 7A4D -B766 7A4E -B767 7A4F -B768 7A50 -F0A3 7A51 -B769 7A52 -B76A 7A53 -B76B 7A54 -B76C 7A55 -B76D 7A56 -CBEB 7A57 -B76E 7A58 -B76F 7A59 -B770 7A5A -B771 7A5B -B772 7A5C -B773 7A5D -B774 7A5E -B775 7A5F -B776 7A60 -B777 7A61 -B778 7A62 -B779 7A63 -B77A 7A64 -B77B 7A65 -B77C 7A66 -B77D 7A67 -B77E 7A68 -B780 7A69 -B781 7A6A -B782 7A6B -B783 7A6C -B784 7A6D -B785 7A6E -B786 7A6F -F0A6 7A70 -B787 7A71 -B788 7A72 -B789 7A73 -D1A8 7A74 -B78A 7A75 -BEBF 7A76 -C7EE 7A77 -F1B6 7A78 -F1B7 7A79 -BFD5 7A7A -B78B 7A7B -B78C 7A7C -B78D 7A7D -B78E 7A7E -B4A9 7A7F -F1B8 7A80 -CDBB 7A81 -B78F 7A82 -C7D4 7A83 -D5AD 7A84 -B790 7A85 -F1B9 7A86 -B791 7A87 -F1BA 7A88 -B792 7A89 -B793 7A8A -B794 7A8B -B795 7A8C -C7CF 7A8D -B796 7A8E -B797 7A8F -B798 7A90 -D2A4 7A91 -D6CF 7A92 -B799 7A93 -B79A 7A94 -F1BB 7A95 -BDD1 7A96 -B4B0 7A97 -BEBD 7A98 -B79B 7A99 -B79C 7A9A -B79D 7A9B -B4DC 7A9C -CED1 7A9D -B79E 7A9E -BFDF 7A9F -F1BD 7AA0 -B79F 7AA1 -B7A0 7AA2 -B840 7AA3 -B841 7AA4 -BFFA 7AA5 -F1BC 7AA6 -B842 7AA7 -F1BF 7AA8 -B843 7AA9 -B844 7AAA -B845 7AAB -F1BE 7AAC -F1C0 7AAD -B846 7AAE -B847 7AAF -B848 7AB0 -B849 7AB1 -B84A 7AB2 -F1C1 7AB3 -B84B 7AB4 -B84C 7AB5 -B84D 7AB6 -B84E 7AB7 -B84F 7AB8 -B850 7AB9 -B851 7ABA -B852 7ABB -B853 7ABC -B854 7ABD -B855 7ABE -C1FE 7ABF -B856 7AC0 -B857 7AC1 -B858 7AC2 -B859 7AC3 -B85A 7AC4 -B85B 7AC5 -B85C 7AC6 -B85D 7AC7 -B85E 7AC8 -B85F 7AC9 -B860 7ACA -C1A2 7ACB -B861 7ACC -B862 7ACD -B863 7ACE -B864 7ACF -B865 7AD0 -B866 7AD1 -B867 7AD2 -B868 7AD3 -B869 7AD4 -B86A 7AD5 -CAFA 7AD6 -B86B 7AD7 -B86C 7AD8 -D5BE 7AD9 -B86D 7ADA -B86E 7ADB -B86F 7ADC -B870 7ADD -BEBA 7ADE -BEB9 7ADF -D5C2 7AE0 -B871 7AE1 -B872 7AE2 -BFA2 7AE3 -B873 7AE4 -CDAF 7AE5 -F1B5 7AE6 -B874 7AE7 -B875 7AE8 -B876 7AE9 -B877 7AEA -B878 7AEB -B879 7AEC -BDDF 7AED -B87A 7AEE -B6CB 7AEF -B87B 7AF0 -B87C 7AF1 -B87D 7AF2 -B87E 7AF3 -B880 7AF4 -B881 7AF5 -B882 7AF6 -B883 7AF7 -B884 7AF8 -D6F1 7AF9 -F3C3 7AFA -B885 7AFB -B886 7AFC -F3C4 7AFD -B887 7AFE -B8CD 7AFF -B888 7B00 -B889 7B01 -B88A 7B02 -F3C6 7B03 -F3C7 7B04 -B88B 7B05 -B0CA 7B06 -B88C 7B07 -F3C5 7B08 -B88D 7B09 -F3C9 7B0A -CBF1 7B0B -B88E 7B0C -B88F 7B0D -B890 7B0E -F3CB 7B0F -B891 7B10 -D0A6 7B11 -B892 7B12 -B893 7B13 -B1CA 7B14 -F3C8 7B15 -B894 7B16 -B895 7B17 -B896 7B18 -F3CF 7B19 -B897 7B1A -B5D1 7B1B -B898 7B1C -B899 7B1D -F3D7 7B1E -B89A 7B1F -F3D2 7B20 -B89B 7B21 -B89C 7B22 -B89D 7B23 -F3D4 7B24 -F3D3 7B25 -B7FB 7B26 -B89E 7B27 -B1BF 7B28 -B89F 7B29 -F3CE 7B2A -F3CA 7B2B -B5DA 7B2C -B8A0 7B2D -F3D0 7B2E -B940 7B2F -B941 7B30 -F3D1 7B31 -B942 7B32 -F3D5 7B33 -B943 7B34 -B944 7B35 -B945 7B36 -B946 7B37 -F3CD 7B38 -B947 7B39 -BCE3 7B3A -B948 7B3B -C1FD 7B3C -B949 7B3D -F3D6 7B3E -B94A 7B3F -B94B 7B40 -B94C 7B41 -B94D 7B42 -B94E 7B43 -B94F 7B44 -F3DA 7B45 -B950 7B46 -F3CC 7B47 -B951 7B48 -B5C8 7B49 -B952 7B4A -BDEE 7B4B -F3DC 7B4C -B953 7B4D -B954 7B4E -B7A4 7B4F -BFF0 7B50 -D6FE 7B51 -CDB2 7B52 -B955 7B53 -B4F0 7B54 -B956 7B55 -B2DF 7B56 -B957 7B57 -F3D8 7B58 -B958 7B59 -F3D9 7B5A -C9B8 7B5B -B959 7B5C -F3DD 7B5D -B95A 7B5E -B95B 7B5F -F3DE 7B60 -B95C 7B61 -F3E1 7B62 -B95D 7B63 -B95E 7B64 -B95F 7B65 -B960 7B66 -B961 7B67 -B962 7B68 -B963 7B69 -B964 7B6A -B965 7B6B -B966 7B6C -B967 7B6D -F3DF 7B6E -B968 7B6F -B969 7B70 -F3E3 7B71 -F3E2 7B72 -B96A 7B73 -B96B 7B74 -F3DB 7B75 -B96C 7B76 -BFEA 7B77 -B96D 7B78 -B3EF 7B79 -B96E 7B7A -F3E0 7B7B -B96F 7B7C -B970 7B7D -C7A9 7B7E -B971 7B7F -BCF2 7B80 -B972 7B81 -B973 7B82 -B974 7B83 -B975 7B84 -F3EB 7B85 -B976 7B86 -B977 7B87 -B978 7B88 -B979 7B89 -B97A 7B8A -B97B 7B8B -B97C 7B8C -B9BF 7B8D -B97D 7B8E -B97E 7B8F -F3E4 7B90 -B980 7B91 -B981 7B92 -B982 7B93 -B2AD 7B94 -BBFE 7B95 -B983 7B96 -CBE3 7B97 -B984 7B98 -B985 7B99 -B986 7B9A -B987 7B9B -F3ED 7B9C -F3E9 7B9D -B988 7B9E -B989 7B9F -B98A 7BA0 -B9DC 7BA1 -F3EE 7BA2 -B98B 7BA3 -B98C 7BA4 -B98D 7BA5 -F3E5 7BA6 -F3E6 7BA7 -F3EA 7BA8 -C2E1 7BA9 -F3EC 7BAA -F3EF 7BAB -F3E8 7BAC -BCFD 7BAD -B98E 7BAE -B98F 7BAF -B990 7BB0 -CFE4 7BB1 -B991 7BB2 -B992 7BB3 -F3F0 7BB4 -B993 7BB5 -B994 7BB6 -B995 7BB7 -F3E7 7BB8 -B996 7BB9 -B997 7BBA -B998 7BBB -B999 7BBC -B99A 7BBD -B99B 7BBE -B99C 7BBF -B99D 7BC0 -F3F2 7BC1 -B99E 7BC2 -B99F 7BC3 -B9A0 7BC4 -BA40 7BC5 -D7AD 7BC6 -C6AA 7BC7 -BA41 7BC8 -BA42 7BC9 -BA43 7BCA -BA44 7BCB -F3F3 7BCC -BA45 7BCD -BA46 7BCE -BA47 7BCF -BA48 7BD0 -F3F1 7BD1 -BA49 7BD2 -C2A8 7BD3 -BA4A 7BD4 -BA4B 7BD5 -BA4C 7BD6 -BA4D 7BD7 -BA4E 7BD8 -B8DD 7BD9 -F3F5 7BDA -BA4F 7BDB -BA50 7BDC -F3F4 7BDD -BA51 7BDE -BA52 7BDF -BA53 7BE0 -B4DB 7BE1 -BA54 7BE2 -BA55 7BE3 -BA56 7BE4 -F3F6 7BE5 -F3F7 7BE6 -BA57 7BE7 -BA58 7BE8 -BA59 7BE9 -F3F8 7BEA -BA5A 7BEB -BA5B 7BEC -BA5C 7BED -C0BA 7BEE -BA5D 7BEF -BA5E 7BF0 -C0E9 7BF1 -BA5F 7BF2 -BA60 7BF3 -BA61 7BF4 -BA62 7BF5 -BA63 7BF6 -C5F1 7BF7 -BA64 7BF8 -BA65 7BF9 -BA66 7BFA -BA67 7BFB -F3FB 7BFC -BA68 7BFD -F3FA 7BFE -BA69 7BFF -BA6A 7C00 -BA6B 7C01 -BA6C 7C02 -BA6D 7C03 -BA6E 7C04 -BA6F 7C05 -BA70 7C06 -B4D8 7C07 -BA71 7C08 -BA72 7C09 -BA73 7C0A -F3FE 7C0B -F3F9 7C0C -BA74 7C0D -BA75 7C0E -F3FC 7C0F -BA76 7C10 -BA77 7C11 -BA78 7C12 -BA79 7C13 -BA7A 7C14 -BA7B 7C15 -F3FD 7C16 -BA7C 7C17 -BA7D 7C18 -BA7E 7C19 -BA80 7C1A -BA81 7C1B -BA82 7C1C -BA83 7C1D -BA84 7C1E -F4A1 7C1F -BA85 7C20 -BA86 7C21 -BA87 7C22 -BA88 7C23 -BA89 7C24 -BA8A 7C25 -F4A3 7C26 -BBC9 7C27 -BA8B 7C28 -BA8C 7C29 -F4A2 7C2A -BA8D 7C2B -BA8E 7C2C -BA8F 7C2D -BA90 7C2E -BA91 7C2F -BA92 7C30 -BA93 7C31 -BA94 7C32 -BA95 7C33 -BA96 7C34 -BA97 7C35 -BA98 7C36 -BA99 7C37 -F4A4 7C38 -BA9A 7C39 -BA9B 7C3A -BA9C 7C3B -BA9D 7C3C -BA9E 7C3D -BA9F 7C3E -B2BE 7C3F -F4A6 7C40 -F4A5 7C41 -BAA0 7C42 -BB40 7C43 -BB41 7C44 -BB42 7C45 -BB43 7C46 -BB44 7C47 -BB45 7C48 -BB46 7C49 -BB47 7C4A -BB48 7C4B -BB49 7C4C -BCAE 7C4D -BB4A 7C4E -BB4B 7C4F -BB4C 7C50 -BB4D 7C51 -BB4E 7C52 -BB4F 7C53 -BB50 7C54 -BB51 7C55 -BB52 7C56 -BB53 7C57 -BB54 7C58 -BB55 7C59 -BB56 7C5A -BB57 7C5B -BB58 7C5C -BB59 7C5D -BB5A 7C5E -BB5B 7C5F -BB5C 7C60 -BB5D 7C61 -BB5E 7C62 -BB5F 7C63 -BB60 7C64 -BB61 7C65 -BB62 7C66 -BB63 7C67 -BB64 7C68 -BB65 7C69 -BB66 7C6A -BB67 7C6B -BB68 7C6C -BB69 7C6D -BB6A 7C6E -BB6B 7C6F -BB6C 7C70 -BB6D 7C71 -BB6E 7C72 -C3D7 7C73 -D9E1 7C74 -BB6F 7C75 -BB70 7C76 -BB71 7C77 -BB72 7C78 -BB73 7C79 -BB74 7C7A -C0E0 7C7B -F4CC 7C7C -D7D1 7C7D -BB75 7C7E -BB76 7C7F -BB77 7C80 -BB78 7C81 -BB79 7C82 -BB7A 7C83 -BB7B 7C84 -BB7C 7C85 -BB7D 7C86 -BB7E 7C87 -BB80 7C88 -B7DB 7C89 -BB81 7C8A -BB82 7C8B -BB83 7C8C -BB84 7C8D -BB85 7C8E -BB86 7C8F -BB87 7C90 -F4CE 7C91 -C1A3 7C92 -BB88 7C93 -BB89 7C94 -C6C9 7C95 -BB8A 7C96 -B4D6 7C97 -D5B3 7C98 -BB8B 7C99 -BB8C 7C9A -BB8D 7C9B -F4D0 7C9C -F4CF 7C9D -F4D1 7C9E -CBDA 7C9F -BB8E 7CA0 -BB8F 7CA1 -F4D2 7CA2 -BB90 7CA3 -D4C1 7CA4 -D6E0 7CA5 -BB91 7CA6 -BB92 7CA7 -BB93 7CA8 -BB94 7CA9 -B7E0 7CAA -BB95 7CAB -BB96 7CAC -BB97 7CAD -C1B8 7CAE -BB98 7CAF -BB99 7CB0 -C1BB 7CB1 -F4D3 7CB2 -BEAC 7CB3 -BB9A 7CB4 -BB9B 7CB5 -BB9C 7CB6 -BB9D 7CB7 -BB9E 7CB8 -B4E2 7CB9 -BB9F 7CBA -BBA0 7CBB -F4D4 7CBC -F4D5 7CBD -BEAB 7CBE -BC40 7CBF -BC41 7CC0 -F4D6 7CC1 -BC42 7CC2 -BC43 7CC3 -BC44 7CC4 -F4DB 7CC5 -BC45 7CC6 -F4D7 7CC7 -F4DA 7CC8 -BC46 7CC9 -BAFD 7CCA -BC47 7CCB -F4D8 7CCC -F4D9 7CCD -BC48 7CCE -BC49 7CCF -BC4A 7CD0 -BC4B 7CD1 -BC4C 7CD2 -BC4D 7CD3 -BC4E 7CD4 -B8E2 7CD5 -CCC7 7CD6 -F4DC 7CD7 -BC4F 7CD8 -B2DA 7CD9 -BC50 7CDA -BC51 7CDB -C3D3 7CDC -BC52 7CDD -BC53 7CDE -D4E3 7CDF -BFB7 7CE0 -BC54 7CE1 -BC55 7CE2 -BC56 7CE3 -BC57 7CE4 -BC58 7CE5 -BC59 7CE6 -BC5A 7CE7 -F4DD 7CE8 -BC5B 7CE9 -BC5C 7CEA -BC5D 7CEB -BC5E 7CEC -BC5F 7CED -BC60 7CEE -C5B4 7CEF -BC61 7CF0 -BC62 7CF1 -BC63 7CF2 -BC64 7CF3 -BC65 7CF4 -BC66 7CF5 -BC67 7CF6 -BC68 7CF7 -F4E9 7CF8 -BC69 7CF9 -BC6A 7CFA -CFB5 7CFB -BC6B 7CFC -BC6C 7CFD -BC6D 7CFE -BC6E 7CFF -BC6F 7D00 -BC70 7D01 -BC71 7D02 -BC72 7D03 -BC73 7D04 -BC74 7D05 -BC75 7D06 -BC76 7D07 -BC77 7D08 -BC78 7D09 -CEC9 7D0A -BC79 7D0B -BC7A 7D0C -BC7B 7D0D -BC7C 7D0E -BC7D 7D0F -BC7E 7D10 -BC80 7D11 -BC81 7D12 -BC82 7D13 -BC83 7D14 -BC84 7D15 -BC85 7D16 -BC86 7D17 -BC87 7D18 -BC88 7D19 -BC89 7D1A -BC8A 7D1B -BC8B 7D1C -BC8C 7D1D -BC8D 7D1E -BC8E 7D1F -CBD8 7D20 -BC8F 7D21 -CBF7 7D22 -BC90 7D23 -BC91 7D24 -BC92 7D25 -BC93 7D26 -BDF4 7D27 -BC94 7D28 -BC95 7D29 -BC96 7D2A -D7CF 7D2B -BC97 7D2C -BC98 7D2D -BC99 7D2E -C0DB 7D2F -BC9A 7D30 -BC9B 7D31 -BC9C 7D32 -BC9D 7D33 -BC9E 7D34 -BC9F 7D35 -BCA0 7D36 -BD40 7D37 -BD41 7D38 -BD42 7D39 -BD43 7D3A -BD44 7D3B -BD45 7D3C -BD46 7D3D -BD47 7D3E -BD48 7D3F -BD49 7D40 -BD4A 7D41 -BD4B 7D42 -BD4C 7D43 -BD4D 7D44 -BD4E 7D45 -BD4F 7D46 -BD50 7D47 -BD51 7D48 -BD52 7D49 -BD53 7D4A -BD54 7D4B -BD55 7D4C -BD56 7D4D -BD57 7D4E -BD58 7D4F -BD59 7D50 -BD5A 7D51 -BD5B 7D52 -BD5C 7D53 -BD5D 7D54 -BD5E 7D55 -BD5F 7D56 -BD60 7D57 -BD61 7D58 -BD62 7D59 -BD63 7D5A -BD64 7D5B -BD65 7D5C -BD66 7D5D -BD67 7D5E -BD68 7D5F -BD69 7D60 -BD6A 7D61 -BD6B 7D62 -BD6C 7D63 -BD6D 7D64 -BD6E 7D65 -BD6F 7D66 -BD70 7D67 -BD71 7D68 -BD72 7D69 -BD73 7D6A -BD74 7D6B -BD75 7D6C -BD76 7D6D -D0F5 7D6E -BD77 7D6F -BD78 7D70 -BD79 7D71 -BD7A 7D72 -BD7B 7D73 -BD7C 7D74 -BD7D 7D75 -BD7E 7D76 -F4EA 7D77 -BD80 7D78 -BD81 7D79 -BD82 7D7A -BD83 7D7B -BD84 7D7C -BD85 7D7D -BD86 7D7E -BD87 7D7F -BD88 7D80 -BD89 7D81 -BD8A 7D82 -BD8B 7D83 -BD8C 7D84 -BD8D 7D85 -BD8E 7D86 -BD8F 7D87 -BD90 7D88 -BD91 7D89 -BD92 7D8A -BD93 7D8B -BD94 7D8C -BD95 7D8D -BD96 7D8E -BD97 7D8F -BD98 7D90 -BD99 7D91 -BD9A 7D92 -BD9B 7D93 -BD9C 7D94 -BD9D 7D95 -BD9E 7D96 -BD9F 7D97 -BDA0 7D98 -BE40 7D99 -BE41 7D9A -BE42 7D9B -BE43 7D9C -BE44 7D9D -BE45 7D9E -BE46 7D9F -BE47 7DA0 -BE48 7DA1 -BE49 7DA2 -BE4A 7DA3 -BE4B 7DA4 -BE4C 7DA5 -F4EB 7DA6 -BE4D 7DA7 -BE4E 7DA8 -BE4F 7DA9 -BE50 7DAA -BE51 7DAB -BE52 7DAC -BE53 7DAD -F4EC 7DAE -BE54 7DAF -BE55 7DB0 -BE56 7DB1 -BE57 7DB2 -BE58 7DB3 -BE59 7DB4 -BE5A 7DB5 -BE5B 7DB6 -BE5C 7DB7 -BE5D 7DB8 -BE5E 7DB9 -BE5F 7DBA -BE60 7DBB -BE61 7DBC -BE62 7DBD -BE63 7DBE -BE64 7DBF -BE65 7DC0 -BE66 7DC1 -BE67 7DC2 -BE68 7DC3 -BE69 7DC4 -BE6A 7DC5 -BE6B 7DC6 -BE6C 7DC7 -BE6D 7DC8 -BE6E 7DC9 -BE6F 7DCA -BE70 7DCB -BE71 7DCC -BE72 7DCD -BE73 7DCE -BE74 7DCF -BE75 7DD0 -BE76 7DD1 -BE77 7DD2 -BE78 7DD3 -BE79 7DD4 -BE7A 7DD5 -BE7B 7DD6 -BE7C 7DD7 -BE7D 7DD8 -BE7E 7DD9 -BE80 7DDA -BE81 7DDB -BE82 7DDC -BE83 7DDD -BE84 7DDE -BE85 7DDF -BE86 7DE0 -BE87 7DE1 -BE88 7DE2 -BE89 7DE3 -BE8A 7DE4 -BE8B 7DE5 -BE8C 7DE6 -BE8D 7DE7 -BE8E 7DE8 -BE8F 7DE9 -BE90 7DEA -BE91 7DEB -BE92 7DEC -BE93 7DED -BE94 7DEE -BE95 7DEF -BE96 7DF0 -BE97 7DF1 -BE98 7DF2 -BE99 7DF3 -BE9A 7DF4 -BE9B 7DF5 -BE9C 7DF6 -BE9D 7DF7 -BE9E 7DF8 -BE9F 7DF9 -BEA0 7DFA -BF40 7DFB -BF41 7DFC -BF42 7DFD -BF43 7DFE -BF44 7DFF -BF45 7E00 -BF46 7E01 -BF47 7E02 -BF48 7E03 -BF49 7E04 -BF4A 7E05 -BF4B 7E06 -BF4C 7E07 -BF4D 7E08 -BF4E 7E09 -BF4F 7E0A -BF50 7E0B -BF51 7E0C -BF52 7E0D -BF53 7E0E -BF54 7E0F -BF55 7E10 -BF56 7E11 -BF57 7E12 -BF58 7E13 -BF59 7E14 -BF5A 7E15 -BF5B 7E16 -BF5C 7E17 -BF5D 7E18 -BF5E 7E19 -BF5F 7E1A -BF60 7E1B -BF61 7E1C -BF62 7E1D -BF63 7E1E -BF64 7E1F -BF65 7E20 -BF66 7E21 -BF67 7E22 -BF68 7E23 -BF69 7E24 -BF6A 7E25 -BF6B 7E26 -BF6C 7E27 -BF6D 7E28 -BF6E 7E29 -BF6F 7E2A -BF70 7E2B -BF71 7E2C -BF72 7E2D -BF73 7E2E -BF74 7E2F -BF75 7E30 -BF76 7E31 -BF77 7E32 -BF78 7E33 -BF79 7E34 -BF7A 7E35 -BF7B 7E36 -BF7C 7E37 -BF7D 7E38 -BF7E 7E39 -BF80 7E3A -F7E3 7E3B -BF81 7E3C -BF82 7E3D -BF83 7E3E -BF84 7E3F -BF85 7E40 -B7B1 7E41 -BF86 7E42 -BF87 7E43 -BF88 7E44 -BF89 7E45 -BF8A 7E46 -F4ED 7E47 -BF8B 7E48 -BF8C 7E49 -BF8D 7E4A -BF8E 7E4B -BF8F 7E4C -BF90 7E4D -BF91 7E4E -BF92 7E4F -BF93 7E50 -BF94 7E51 -BF95 7E52 -BF96 7E53 -BF97 7E54 -BF98 7E55 -BF99 7E56 -BF9A 7E57 -BF9B 7E58 -BF9C 7E59 -BF9D 7E5A -BF9E 7E5B -BF9F 7E5C -BFA0 7E5D -C040 7E5E -C041 7E5F -C042 7E60 -C043 7E61 -C044 7E62 -C045 7E63 -C046 7E64 -C047 7E65 -C048 7E66 -C049 7E67 -C04A 7E68 -C04B 7E69 -C04C 7E6A -C04D 7E6B -C04E 7E6C -C04F 7E6D -C050 7E6E -C051 7E6F -C052 7E70 -C053 7E71 -C054 7E72 -C055 7E73 -C056 7E74 -C057 7E75 -C058 7E76 -C059 7E77 -C05A 7E78 -C05B 7E79 -C05C 7E7A -C05D 7E7B -C05E 7E7C -C05F 7E7D -C060 7E7E -C061 7E7F -C062 7E80 -C063 7E81 -D7EB 7E82 -C064 7E83 -C065 7E84 -C066 7E85 -C067 7E86 -C068 7E87 -C069 7E88 -C06A 7E89 -C06B 7E8A -C06C 7E8B -C06D 7E8C -C06E 7E8D -C06F 7E8E -C070 7E8F -C071 7E90 -C072 7E91 -C073 7E92 -C074 7E93 -C075 7E94 -C076 7E95 -C077 7E96 -C078 7E97 -C079 7E98 -C07A 7E99 -C07B 7E9A -F4EE 7E9B -C07C 7E9C -C07D 7E9D -C07E 7E9E -E6F9 7E9F -BEC0 7EA0 -E6FA 7EA1 -BAEC 7EA2 -E6FB 7EA3 -CFCB 7EA4 -E6FC 7EA5 -D4BC 7EA6 -BCB6 7EA7 -E6FD 7EA8 -E6FE 7EA9 -BCCD 7EAA -C8D2 7EAB -CEB3 7EAC -E7A1 7EAD -C080 7EAE -B4BF 7EAF -E7A2 7EB0 -C9B4 7EB1 -B8D9 7EB2 -C4C9 7EB3 -C081 7EB4 -D7DD 7EB5 -C2DA 7EB6 -B7D7 7EB7 -D6BD 7EB8 -CEC6 7EB9 -B7C4 7EBA -C082 7EBB -C083 7EBC -C5A6 7EBD -E7A3 7EBE -CFDF 7EBF -E7A4 7EC0 -E7A5 7EC1 -E7A6 7EC2 -C1B7 7EC3 -D7E9 7EC4 -C9F0 7EC5 -CFB8 7EC6 -D6AF 7EC7 -D6D5 7EC8 -E7A7 7EC9 -B0ED 7ECA -E7A8 7ECB -E7A9 7ECC -C9DC 7ECD -D2EF 7ECE -BEAD 7ECF -E7AA 7ED0 -B0F3 7ED1 -C8DE 7ED2 -BDE1 7ED3 -E7AB 7ED4 -C8C6 7ED5 -C084 7ED6 -E7AC 7ED7 -BBE6 7ED8 -B8F8 7ED9 -D1A4 7EDA -E7AD 7EDB -C2E7 7EDC -BEF8 7EDD -BDCA 7EDE -CDB3 7EDF -E7AE 7EE0 -E7AF 7EE1 -BEEE 7EE2 -D0E5 7EE3 -C085 7EE4 -CBE7 7EE5 -CCD0 7EE6 -BCCC 7EE7 -E7B0 7EE8 -BCA8 7EE9 -D0F7 7EEA -E7B1 7EEB -C086 7EEC -D0F8 7EED -E7B2 7EEE -E7B3 7EEF -B4C2 7EF0 -E7B4 7EF1 -E7B5 7EF2 -C9FE 7EF3 -CEAC 7EF4 -C3E0 7EF5 -E7B7 7EF6 -B1C1 7EF7 -B3F1 7EF8 -C087 7EF9 -E7B8 7EFA -E7B9 7EFB -D7DB 7EFC -D5C0 7EFD -E7BA 7EFE -C2CC 7EFF -D7BA 7F00 -E7BB 7F01 -E7BC 7F02 -E7BD 7F03 -BCEA 7F04 -C3E5 7F05 -C0C2 7F06 -E7BE 7F07 -E7BF 7F08 -BCA9 7F09 -C088 7F0A -E7C0 7F0B -E7C1 7F0C -E7B6 7F0D -B6D0 7F0E -E7C2 7F0F -C089 7F10 -E7C3 7F11 -E7C4 7F12 -BBBA 7F13 -B5DE 7F14 -C2C6 7F15 -B1E0 7F16 -E7C5 7F17 -D4B5 7F18 -E7C6 7F19 -B8BF 7F1A -E7C8 7F1B -E7C7 7F1C -B7EC 7F1D -C08A 7F1E -E7C9 7F1F -B2F8 7F20 -E7CA 7F21 -E7CB 7F22 -E7CC 7F23 -E7CD 7F24 -E7CE 7F25 -E7CF 7F26 -E7D0 7F27 -D3A7 7F28 -CBF5 7F29 -E7D1 7F2A -E7D2 7F2B -E7D3 7F2C -E7D4 7F2D -C9C9 7F2E -E7D5 7F2F -E7D6 7F30 -E7D7 7F31 -E7D8 7F32 -E7D9 7F33 -BDC9 7F34 -E7DA 7F35 -F3BE 7F36 -C08B 7F37 -B8D7 7F38 -C08C 7F39 -C8B1 7F3A -C08D 7F3B -C08E 7F3C -C08F 7F3D -C090 7F3E -C091 7F3F -C092 7F40 -C093 7F41 -F3BF 7F42 -C094 7F43 -F3C0 7F44 -F3C1 7F45 -C095 7F46 -C096 7F47 -C097 7F48 -C098 7F49 -C099 7F4A -C09A 7F4B -C09B 7F4C -C09C 7F4D -C09D 7F4E -C09E 7F4F -B9DE 7F50 -CDF8 7F51 -C09F 7F52 -C0A0 7F53 -D8E8 7F54 -BAB1 7F55 -C140 7F56 -C2DE 7F57 -EEB7 7F58 -C141 7F59 -B7A3 7F5A -C142 7F5B -C143 7F5C -C144 7F5D -C145 7F5E -EEB9 7F5F -C146 7F60 -EEB8 7F61 -B0D5 7F62 -C147 7F63 -C148 7F64 -C149 7F65 -C14A 7F66 -C14B 7F67 -EEBB 7F68 -D5D6 7F69 -D7EF 7F6A -C14C 7F6B -C14D 7F6C -C14E 7F6D -D6C3 7F6E -C14F 7F6F -C150 7F70 -EEBD 7F71 -CAF0 7F72 -C151 7F73 -EEBC 7F74 -C152 7F75 -C153 7F76 -C154 7F77 -C155 7F78 -EEBE 7F79 -C156 7F7A -C157 7F7B -C158 7F7C -C159 7F7D -EEC0 7F7E -C15A 7F7F -C15B 7F80 -EEBF 7F81 -C15C 7F82 -C15D 7F83 -C15E 7F84 -C15F 7F85 -C160 7F86 -C161 7F87 -C162 7F88 -C163 7F89 -D1F2 7F8A -C164 7F8B -C7BC 7F8C -C165 7F8D -C3C0 7F8E -C166 7F8F -C167 7F90 -C168 7F91 -C169 7F92 -C16A 7F93 -B8E1 7F94 -C16B 7F95 -C16C 7F96 -C16D 7F97 -C16E 7F98 -C16F 7F99 -C1E7 7F9A -C170 7F9B -C171 7F9C -F4C6 7F9D -D0DF 7F9E -F4C7 7F9F -C172 7FA0 -CFDB 7FA1 -C173 7FA2 -C174 7FA3 -C8BA 7FA4 -C175 7FA5 -C176 7FA6 -F4C8 7FA7 -C177 7FA8 -C178 7FA9 -C179 7FAA -C17A 7FAB -C17B 7FAC -C17C 7FAD -C17D 7FAE -F4C9 7FAF -F4CA 7FB0 -C17E 7FB1 -F4CB 7FB2 -C180 7FB3 -C181 7FB4 -C182 7FB5 -C183 7FB6 -C184 7FB7 -D9FA 7FB8 -B8FE 7FB9 -C185 7FBA -C186 7FBB -E5F1 7FBC -D3F0 7FBD -C187 7FBE -F4E0 7FBF -C188 7FC0 -CECC 7FC1 -C189 7FC2 -C18A 7FC3 -C18B 7FC4 -B3E1 7FC5 -C18C 7FC6 -C18D 7FC7 -C18E 7FC8 -C18F 7FC9 -F1B4 7FCA -C190 7FCB -D2EE 7FCC -C191 7FCD -F4E1 7FCE -C192 7FCF -C193 7FD0 -C194 7FD1 -C195 7FD2 -C196 7FD3 -CFE8 7FD4 -F4E2 7FD5 -C197 7FD6 -C198 7FD7 -C7CC 7FD8 -C199 7FD9 -C19A 7FDA -C19B 7FDB -C19C 7FDC -C19D 7FDD -C19E 7FDE -B5D4 7FDF -B4E4 7FE0 -F4E4 7FE1 -C19F 7FE2 -C1A0 7FE3 -C240 7FE4 -F4E3 7FE5 -F4E5 7FE6 -C241 7FE7 -C242 7FE8 -F4E6 7FE9 -C243 7FEA -C244 7FEB -C245 7FEC -C246 7FED -F4E7 7FEE -C247 7FEF -BAB2 7FF0 -B0BF 7FF1 -C248 7FF2 -F4E8 7FF3 -C249 7FF4 -C24A 7FF5 -C24B 7FF6 -C24C 7FF7 -C24D 7FF8 -C24E 7FF9 -C24F 7FFA -B7AD 7FFB -D2ED 7FFC -C250 7FFD -C251 7FFE -C252 7FFF -D2AB 8000 -C0CF 8001 -C253 8002 -BFBC 8003 -EBA3 8004 -D5DF 8005 -EAC8 8006 -C254 8007 -C255 8008 -C256 8009 -C257 800A -F1F3 800B -B6F8 800C -CBA3 800D -C258 800E -C259 800F -C4CD 8010 -C25A 8011 -F1E7 8012 -C25B 8013 -F1E8 8014 -B8FB 8015 -F1E9 8016 -BAC4 8017 -D4C5 8018 -B0D2 8019 -C25C 801A -C25D 801B -F1EA 801C -C25E 801D -C25F 801E -C260 801F -F1EB 8020 -C261 8021 -F1EC 8022 -C262 8023 -C263 8024 -F1ED 8025 -F1EE 8026 -F1EF 8027 -F1F1 8028 -F1F0 8029 -C5D5 802A -C264 802B -C265 802C -C266 802D -C267 802E -C268 802F -C269 8030 -F1F2 8031 -C26A 8032 -B6FA 8033 -C26B 8034 -F1F4 8035 -D2AE 8036 -DEC7 8037 -CBCA 8038 -C26C 8039 -C26D 803A -B3DC 803B -C26E 803C -B5A2 803D -C26F 803E -B9A2 803F -C270 8040 -C271 8041 -C4F4 8042 -F1F5 8043 -C272 8044 -C273 8045 -F1F6 8046 -C274 8047 -C275 8048 -C276 8049 -C1C4 804A -C1FB 804B -D6B0 804C -F1F7 804D -C277 804E -C278 804F -C279 8050 -C27A 8051 -F1F8 8052 -C27B 8053 -C1AA 8054 -C27C 8055 -C27D 8056 -C27E 8057 -C6B8 8058 -C280 8059 -BEDB 805A -C281 805B -C282 805C -C283 805D -C284 805E -C285 805F -C286 8060 -C287 8061 -C288 8062 -C289 8063 -C28A 8064 -C28B 8065 -C28C 8066 -C28D 8067 -C28E 8068 -F1F9 8069 -B4CF 806A -C28F 806B -C290 806C -C291 806D -C292 806E -C293 806F -C294 8070 -F1FA 8071 -C295 8072 -C296 8073 -C297 8074 -C298 8075 -C299 8076 -C29A 8077 -C29B 8078 -C29C 8079 -C29D 807A -C29E 807B -C29F 807C -C2A0 807D -C340 807E -EDB2 807F -EDB1 8080 -C341 8081 -C342 8082 -CBE0 8083 -D2DE 8084 -C343 8085 -CBC1 8086 -D5D8 8087 -C344 8088 -C8E2 8089 -C345 808A -C0DF 808B -BCA1 808C -C346 808D -C347 808E -C348 808F -C349 8090 -C34A 8091 -C34B 8092 -EBC1 8093 -C34C 8094 -C34D 8095 -D0A4 8096 -C34E 8097 -D6E2 8098 -C34F 8099 -B6C7 809A -B8D8 809B -EBC0 809C -B8CE 809D -C350 809E -EBBF 809F -B3A6 80A0 -B9C9 80A1 -D6AB 80A2 -C351 80A3 -B7F4 80A4 -B7CA 80A5 -C352 80A6 -C353 80A7 -C354 80A8 -BCE7 80A9 -B7BE 80AA -EBC6 80AB -C355 80AC -EBC7 80AD -B0B9 80AE -BFCF 80AF -C356 80B0 -EBC5 80B1 -D3FD 80B2 -C357 80B3 -EBC8 80B4 -C358 80B5 -C359 80B6 -EBC9 80B7 -C35A 80B8 -C35B 80B9 -B7CE 80BA -C35C 80BB -EBC2 80BC -EBC4 80BD -C9F6 80BE -D6D7 80BF -D5CD 80C0 -D0B2 80C1 -EBCF 80C2 -CEB8 80C3 -EBD0 80C4 -C35D 80C5 -B5A8 80C6 -C35E 80C7 -C35F 80C8 -C360 80C9 -C361 80CA -C362 80CB -B1B3 80CC -EBD2 80CD -CCA5 80CE -C363 80CF -C364 80D0 -C365 80D1 -C366 80D2 -C367 80D3 -C368 80D4 -C369 80D5 -C5D6 80D6 -EBD3 80D7 -C36A 80D8 -EBD1 80D9 -C5DF 80DA -EBCE 80DB -CAA4 80DC -EBD5 80DD -B0FB 80DE -C36B 80DF -C36C 80E0 -BAFA 80E1 -C36D 80E2 -C36E 80E3 -D8B7 80E4 -F1E3 80E5 -C36F 80E6 -EBCA 80E7 -EBCB 80E8 -EBCC 80E9 -EBCD 80EA -EBD6 80EB -E6C0 80EC -EBD9 80ED -C370 80EE -BFE8 80EF -D2C8 80F0 -EBD7 80F1 -EBDC 80F2 -B8EC 80F3 -EBD8 80F4 -C371 80F5 -BDBA 80F6 -C372 80F7 -D0D8 80F8 -C373 80F9 -B0B7 80FA -C374 80FB -EBDD 80FC -C4DC 80FD -C375 80FE -C376 80FF -C377 8100 -C378 8101 -D6AC 8102 -C379 8103 -C37A 8104 -C37B 8105 -B4E0 8106 -C37C 8107 -C37D 8108 -C2F6 8109 -BCB9 810A -C37E 810B -C380 810C -EBDA 810D -EBDB 810E -D4E0 810F -C6EA 8110 -C4D4 8111 -EBDF 8112 -C5A7 8113 -D9F5 8114 -C381 8115 -B2B1 8116 -C382 8117 -EBE4 8118 -C383 8119 -BDC5 811A -C384 811B -C385 811C -C386 811D -EBE2 811E -C387 811F -C388 8120 -C389 8121 -C38A 8122 -C38B 8123 -C38C 8124 -C38D 8125 -C38E 8126 -C38F 8127 -C390 8128 -C391 8129 -C392 812A -C393 812B -EBE3 812C -C394 812D -C395 812E -B8AC 812F -C396 8130 -CDD1 8131 -EBE5 8132 -C397 8133 -C398 8134 -C399 8135 -EBE1 8136 -C39A 8137 -C1B3 8138 -C39B 8139 -C39C 813A -C39D 813B -C39E 813C -C39F 813D -C6A2 813E -C3A0 813F -C440 8140 -C441 8141 -C442 8142 -C443 8143 -C444 8144 -C445 8145 -CCF3 8146 -C446 8147 -EBE6 8148 -C447 8149 -C0B0 814A -D2B8 814B -EBE7 814C -C448 814D -C449 814E -C44A 814F -B8AF 8150 -B8AD 8151 -C44B 8152 -EBE8 8153 -C7BB 8154 -CDF3 8155 -C44C 8156 -C44D 8157 -C44E 8158 -EBEA 8159 -EBEB 815A -C44F 815B -C450 815C -C451 815D -C452 815E -C453 815F -EBED 8160 -C454 8161 -C455 8162 -C456 8163 -C457 8164 -D0C8 8165 -C458 8166 -EBF2 8167 -C459 8168 -EBEE 8169 -C45A 816A -C45B 816B -C45C 816C -EBF1 816D -C8F9 816E -C45D 816F -D1FC 8170 -EBEC 8171 -C45E 8172 -C45F 8173 -EBE9 8174 -C460 8175 -C461 8176 -C462 8177 -C463 8178 -B8B9 8179 -CFD9 817A -C4E5 817B -EBEF 817C -EBF0 817D -CCDA 817E -CDC8 817F -B0F2 8180 -C464 8181 -EBF6 8182 -C465 8183 -C466 8184 -C467 8185 -C468 8186 -C469 8187 -EBF5 8188 -C46A 8189 -B2B2 818A -C46B 818B -C46C 818C -C46D 818D -C46E 818E -B8E0 818F -C46F 8190 -EBF7 8191 -C470 8192 -C471 8193 -C472 8194 -C473 8195 -C474 8196 -C475 8197 -B1EC 8198 -C476 8199 -C477 819A -CCC5 819B -C4A4 819C -CFA5 819D -C478 819E -C479 819F -C47A 81A0 -C47B 81A1 -C47C 81A2 -EBF9 81A3 -C47D 81A4 -C47E 81A5 -ECA2 81A6 -C480 81A7 -C5F2 81A8 -C481 81A9 -EBFA 81AA -C482 81AB -C483 81AC -C484 81AD -C485 81AE -C486 81AF -C487 81B0 -C488 81B1 -C489 81B2 -C9C5 81B3 -C48A 81B4 -C48B 81B5 -C48C 81B6 -C48D 81B7 -C48E 81B8 -C48F 81B9 -E2DF 81BA -EBFE 81BB -C490 81BC -C491 81BD -C492 81BE -C493 81BF -CDCE 81C0 -ECA1 81C1 -B1DB 81C2 -D3B7 81C3 -C494 81C4 -C495 81C5 -D2DC 81C6 -C496 81C7 -C497 81C8 -C498 81C9 -EBFD 81CA -C499 81CB -EBFB 81CC -C49A 81CD -C49B 81CE -C49C 81CF -C49D 81D0 -C49E 81D1 -C49F 81D2 -C4A0 81D3 -C540 81D4 -C541 81D5 -C542 81D6 -C543 81D7 -C544 81D8 -C545 81D9 -C546 81DA -C547 81DB -C548 81DC -C549 81DD -C54A 81DE -C54B 81DF -C54C 81E0 -C54D 81E1 -C54E 81E2 -B3BC 81E3 -C54F 81E4 -C550 81E5 -C551 81E6 -EAB0 81E7 -C552 81E8 -C553 81E9 -D7D4 81EA -C554 81EB -F4AB 81EC -B3F4 81ED -C555 81EE -C556 81EF -C557 81F0 -C558 81F1 -C559 81F2 -D6C1 81F3 -D6C2 81F4 -C55A 81F5 -C55B 81F6 -C55C 81F7 -C55D 81F8 -C55E 81F9 -C55F 81FA -D5E9 81FB -BECA 81FC -C560 81FD -F4A7 81FE -C561 81FF -D2A8 8200 -F4A8 8201 -F4A9 8202 -C562 8203 -F4AA 8204 -BECB 8205 -D3DF 8206 -C563 8207 -C564 8208 -C565 8209 -C566 820A -C567 820B -C9E0 820C -C9E1 820D -C568 820E -C569 820F -F3C2 8210 -C56A 8211 -CAE6 8212 -C56B 8213 -CCF2 8214 -C56C 8215 -C56D 8216 -C56E 8217 -C56F 8218 -C570 8219 -C571 821A -E2B6 821B -CBB4 821C -C572 821D -CEE8 821E -D6DB 821F -C573 8220 -F4AD 8221 -F4AE 8222 -F4AF 8223 -C574 8224 -C575 8225 -C576 8226 -C577 8227 -F4B2 8228 -C578 8229 -BABD 822A -F4B3 822B -B0E3 822C -F4B0 822D -C579 822E -F4B1 822F -BDA2 8230 -B2D5 8231 -C57A 8232 -F4B6 8233 -F4B7 8234 -B6E6 8235 -B2B0 8236 -CFCF 8237 -F4B4 8238 -B4AC 8239 -C57B 823A -F4B5 823B -C57C 823C -C57D 823D -F4B8 823E -C57E 823F -C580 8240 -C581 8241 -C582 8242 -C583 8243 -F4B9 8244 -C584 8245 -C585 8246 -CDA7 8247 -C586 8248 -F4BA 8249 -C587 824A -F4BB 824B -C588 824C -C589 824D -C58A 824E -F4BC 824F -C58B 8250 -C58C 8251 -C58D 8252 -C58E 8253 -C58F 8254 -C590 8255 -C591 8256 -C592 8257 -CBD2 8258 -C593 8259 -F4BD 825A -C594 825B -C595 825C -C596 825D -C597 825E -F4BE 825F -C598 8260 -C599 8261 -C59A 8262 -C59B 8263 -C59C 8264 -C59D 8265 -C59E 8266 -C59F 8267 -F4BF 8268 -C5A0 8269 -C640 826A -C641 826B -C642 826C -C643 826D -F4DE 826E -C1BC 826F -BCE8 8270 -C644 8271 -C9AB 8272 -D1DE 8273 -E5F5 8274 -C645 8275 -C646 8276 -C647 8277 -C648 8278 -DCB3 8279 -D2D5 827A -C649 827B -C64A 827C -DCB4 827D -B0AC 827E -DCB5 827F -C64B 8280 -C64C 8281 -BDDA 8282 -C64D 8283 -DCB9 8284 -C64E 8285 -C64F 8286 -C650 8287 -D8C2 8288 -C651 8289 -DCB7 828A -D3F3 828B -C652 828C -C9D6 828D -DCBA 828E -DCB6 828F -C653 8290 -DCBB 8291 -C3A2 8292 -C654 8293 -C655 8294 -C656 8295 -C657 8296 -DCBC 8297 -DCC5 8298 -DCBD 8299 -C658 829A -C659 829B -CEDF 829C -D6A5 829D -C65A 829E -DCCF 829F -C65B 82A0 -DCCD 82A1 -C65C 82A2 -C65D 82A3 -DCD2 82A4 -BDE6 82A5 -C2AB 82A6 -C65E 82A7 -DCB8 82A8 -DCCB 82A9 -DCCE 82AA -DCBE 82AB -B7D2 82AC -B0C5 82AD -DCC7 82AE -D0BE 82AF -DCC1 82B0 -BBA8 82B1 -C65F 82B2 -B7BC 82B3 -DCCC 82B4 -C660 82B5 -C661 82B6 -DCC6 82B7 -DCBF 82B8 -C7DB 82B9 -C662 82BA -C663 82BB -C664 82BC -D1BF 82BD -DCC0 82BE -C665 82BF -C666 82C0 -DCCA 82C1 -C667 82C2 -C668 82C3 -DCD0 82C4 -C669 82C5 -C66A 82C6 -CEAD 82C7 -DCC2 82C8 -C66B 82C9 -DCC3 82CA -DCC8 82CB -DCC9 82CC -B2D4 82CD -DCD1 82CE -CBD5 82CF -C66C 82D0 -D4B7 82D1 -DCDB 82D2 -DCDF 82D3 -CCA6 82D4 -DCE6 82D5 -C66D 82D6 -C3E7 82D7 -DCDC 82D8 -C66E 82D9 -C66F 82DA -BFC1 82DB -DCD9 82DC -C670 82DD -B0FA 82DE -B9B6 82DF -DCE5 82E0 -DCD3 82E1 -C671 82E2 -DCC4 82E3 -DCD6 82E4 -C8F4 82E5 -BFE0 82E6 -C672 82E7 -C673 82E8 -C674 82E9 -C675 82EA -C9BB 82EB -C676 82EC -C677 82ED -C678 82EE -B1BD 82EF -C679 82F0 -D3A2 82F1 -C67A 82F2 -C67B 82F3 -DCDA 82F4 -C67C 82F5 -C67D 82F6 -DCD5 82F7 -C67E 82F8 -C6BB 82F9 -C680 82FA -DCDE 82FB -C681 82FC -C682 82FD -C683 82FE -C684 82FF -C685 8300 -D7C2 8301 -C3AF 8302 -B7B6 8303 -C7D1 8304 -C3A9 8305 -DCE2 8306 -DCD8 8307 -DCEB 8308 -DCD4 8309 -C686 830A -C687 830B -DCDD 830C -C688 830D -BEA5 830E -DCD7 830F -C689 8310 -DCE0 8311 -C68A 8312 -C68B 8313 -DCE3 8314 -DCE4 8315 -C68C 8316 -DCF8 8317 -C68D 8318 -C68E 8319 -DCE1 831A -DDA2 831B -DCE7 831C -C68F 831D -C690 831E -C691 831F -C692 8320 -C693 8321 -C694 8322 -C695 8323 -C696 8324 -C697 8325 -C698 8326 -BCEB 8327 -B4C4 8328 -C699 8329 -C69A 832A -C3A3 832B -B2E7 832C -DCFA 832D -C69B 832E -DCF2 832F -C69C 8330 -DCEF 8331 -C69D 8332 -DCFC 8333 -DCEE 8334 -D2F0 8335 -B2E8 8336 -C69E 8337 -C8D7 8338 -C8E3 8339 -DCFB 833A -C69F 833B -DCED 833C -C6A0 833D -C740 833E -C741 833F -DCF7 8340 -C742 8341 -C743 8342 -DCF5 8343 -C744 8344 -C745 8345 -BEA3 8346 -DCF4 8347 -C746 8348 -B2DD 8349 -C747 834A -C748 834B -C749 834C -C74A 834D -C74B 834E -DCF3 834F -BCF6 8350 -DCE8 8351 -BBC4 8352 -C74C 8353 -C0F3 8354 -C74D 8355 -C74E 8356 -C74F 8357 -C750 8358 -C751 8359 -BCD4 835A -DCE9 835B -DCEA 835C -C752 835D -DCF1 835E -DCF6 835F -DCF9 8360 -B5B4 8361 -C753 8362 -C8D9 8363 -BBE7 8364 -DCFE 8365 -DCFD 8366 -D3AB 8367 -DDA1 8368 -DDA3 8369 -DDA5 836A -D2F1 836B -DDA4 836C -DDA6 836D -DDA7 836E -D2A9 836F -C754 8370 -C755 8371 -C756 8372 -C757 8373 -C758 8374 -C759 8375 -C75A 8376 -BAC9 8377 -DDA9 8378 -C75B 8379 -C75C 837A -DDB6 837B -DDB1 837C -DDB4 837D -C75D 837E -C75E 837F -C75F 8380 -C760 8381 -C761 8382 -C762 8383 -C763 8384 -DDB0 8385 -C6CE 8386 -C764 8387 -C765 8388 -C0F2 8389 -C766 838A -C767 838B -C768 838C -C769 838D -C9AF 838E -C76A 838F -C76B 8390 -C76C 8391 -DCEC 8392 -DDAE 8393 -C76D 8394 -C76E 8395 -C76F 8396 -C770 8397 -DDB7 8398 -C771 8399 -C772 839A -DCF0 839B -DDAF 839C -C773 839D -DDB8 839E -C774 839F -DDAC 83A0 -C775 83A1 -C776 83A2 -C777 83A3 -C778 83A4 -C779 83A5 -C77A 83A6 -C77B 83A7 -DDB9 83A8 -DDB3 83A9 -DDAD 83AA -C4AA 83AB -C77C 83AC -C77D 83AD -C77E 83AE -C780 83AF -DDA8 83B0 -C0B3 83B1 -C1AB 83B2 -DDAA 83B3 -DDAB 83B4 -C781 83B5 -DDB2 83B6 -BBF1 83B7 -DDB5 83B8 -D3A8 83B9 -DDBA 83BA -C782 83BB -DDBB 83BC -C3A7 83BD -C783 83BE -C784 83BF -DDD2 83C0 -DDBC 83C1 -C785 83C2 -C786 83C3 -C787 83C4 -DDD1 83C5 -C788 83C6 -B9BD 83C7 -C789 83C8 -C78A 83C9 -BED5 83CA -C78B 83CB -BEFA 83CC -C78C 83CD -C78D 83CE -BACA 83CF -C78E 83D0 -C78F 83D1 -C790 83D2 -C791 83D3 -DDCA 83D4 -C792 83D5 -DDC5 83D6 -C793 83D7 -DDBF 83D8 -C794 83D9 -C795 83DA -C796 83DB -B2CB 83DC -DDC3 83DD -C797 83DE -DDCB 83DF -B2A4 83E0 -DDD5 83E1 -C798 83E2 -C799 83E3 -C79A 83E4 -DDBE 83E5 -C79B 83E6 -C79C 83E7 -C79D 83E8 -C6D0 83E9 -DDD0 83EA -C79E 83EB -C79F 83EC -C7A0 83ED -C840 83EE -C841 83EF -DDD4 83F0 -C1E2 83F1 -B7C6 83F2 -C842 83F3 -C843 83F4 -C844 83F5 -C845 83F6 -C846 83F7 -DDCE 83F8 -DDCF 83F9 -C847 83FA -C848 83FB -C849 83FC -DDC4 83FD -C84A 83FE -C84B 83FF -C84C 8400 -DDBD 8401 -C84D 8402 -DDCD 8403 -CCD1 8404 -C84E 8405 -DDC9 8406 -C84F 8407 -C850 8408 -C851 8409 -C852 840A -DDC2 840B -C3C8 840C -C6BC 840D -CEAE 840E -DDCC 840F -C853 8410 -DDC8 8411 -C854 8412 -C855 8413 -C856 8414 -C857 8415 -C858 8416 -C859 8417 -DDC1 8418 -C85A 8419 -C85B 841A -C85C 841B -DDC6 841C -C2DC 841D -C85D 841E -C85E 841F -C85F 8420 -C860 8421 -C861 8422 -C862 8423 -D3A9 8424 -D3AA 8425 -DDD3 8426 -CFF4 8427 -C8F8 8428 -C863 8429 -C864 842A -C865 842B -C866 842C -C867 842D -C868 842E -C869 842F -C86A 8430 -DDE6 8431 -C86B 8432 -C86C 8433 -C86D 8434 -C86E 8435 -C86F 8436 -C870 8437 -DDC7 8438 -C871 8439 -C872 843A -C873 843B -DDE0 843C -C2E4 843D -C874 843E -C875 843F -C876 8440 -C877 8441 -C878 8442 -C879 8443 -C87A 8444 -C87B 8445 -DDE1 8446 -C87C 8447 -C87D 8448 -C87E 8449 -C880 844A -C881 844B -C882 844C -C883 844D -C884 844E -C885 844F -C886 8450 -DDD7 8451 -C887 8452 -C888 8453 -C889 8454 -C88A 8455 -C88B 8456 -D6F8 8457 -C88C 8458 -DDD9 8459 -DDD8 845A -B8F0 845B -DDD6 845C -C88D 845D -C88E 845E -C88F 845F -C890 8460 -C6CF 8461 -C891 8462 -B6AD 8463 -C892 8464 -C893 8465 -C894 8466 -C895 8467 -C896 8468 -DDE2 8469 -C897 846A -BAF9 846B -D4E1 846C -DDE7 846D -C898 846E -C899 846F -C89A 8470 -B4D0 8471 -C89B 8472 -DDDA 8473 -C89C 8474 -BFFB 8475 -DDE3 8476 -C89D 8477 -DDDF 8478 -C89E 8479 -DDDD 847A -C89F 847B -C8A0 847C -C940 847D -C941 847E -C942 847F -C943 8480 -C944 8481 -B5D9 8482 -C945 8483 -C946 8484 -C947 8485 -C948 8486 -DDDB 8487 -DDDC 8488 -DDDE 8489 -C949 848A -BDAF 848B -DDE4 848C -C94A 848D -DDE5 848E -C94B 848F -C94C 8490 -C94D 8491 -C94E 8492 -C94F 8493 -C950 8494 -C951 8495 -C952 8496 -DDF5 8497 -C953 8498 -C3C9 8499 -C954 849A -C955 849B -CBE2 849C -C956 849D -C957 849E -C958 849F -C959 84A0 -DDF2 84A1 -C95A 84A2 -C95B 84A3 -C95C 84A4 -C95D 84A5 -C95E 84A6 -C95F 84A7 -C960 84A8 -C961 84A9 -C962 84AA -C963 84AB -C964 84AC -C965 84AD -C966 84AE -D8E1 84AF -C967 84B0 -C968 84B1 -C6D1 84B2 -C969 84B3 -DDF4 84B4 -C96A 84B5 -C96B 84B6 -C96C 84B7 -D5F4 84B8 -DDF3 84B9 -DDF0 84BA -C96D 84BB -C96E 84BC -DDEC 84BD -C96F 84BE -DDEF 84BF -C970 84C0 -DDE8 84C1 -C971 84C2 -C972 84C3 -D0EE 84C4 -C973 84C5 -C974 84C6 -C975 84C7 -C976 84C8 -C8D8 84C9 -DDEE 84CA -C977 84CB -C978 84CC -DDE9 84CD -C979 84CE -C97A 84CF -DDEA 84D0 -CBF2 84D1 -C97B 84D2 -DDED 84D3 -C97C 84D4 -C97D 84D5 -B1CD 84D6 -C97E 84D7 -C980 84D8 -C981 84D9 -C982 84DA -C983 84DB -C984 84DC -C0B6 84DD -C985 84DE -BCBB 84DF -DDF1 84E0 -C986 84E1 -C987 84E2 -DDF7 84E3 -C988 84E4 -DDF6 84E5 -DDEB 84E6 -C989 84E7 -C98A 84E8 -C98B 84E9 -C98C 84EA -C98D 84EB -C5EE 84EC -C98E 84ED -C98F 84EE -C990 84EF -DDFB 84F0 -C991 84F1 -C992 84F2 -C993 84F3 -C994 84F4 -C995 84F5 -C996 84F6 -C997 84F7 -C998 84F8 -C999 84F9 -C99A 84FA -C99B 84FB -DEA4 84FC -C99C 84FD -C99D 84FE -DEA3 84FF -C99E 8500 -C99F 8501 -C9A0 8502 -CA40 8503 -CA41 8504 -CA42 8505 -CA43 8506 -CA44 8507 -CA45 8508 -CA46 8509 -CA47 850A -CA48 850B -DDF8 850C -CA49 850D -CA4A 850E -CA4B 850F -CA4C 8510 -C3EF 8511 -CA4D 8512 -C2FB 8513 -CA4E 8514 -CA4F 8515 -CA50 8516 -D5E1 8517 -CA51 8518 -CA52 8519 -CEB5 851A -CA53 851B -CA54 851C -CA55 851D -CA56 851E -DDFD 851F -CA57 8520 -B2CC 8521 -CA58 8522 -CA59 8523 -CA5A 8524 -CA5B 8525 -CA5C 8526 -CA5D 8527 -CA5E 8528 -CA5F 8529 -CA60 852A -C4E8 852B -CADF 852C -CA61 852D -CA62 852E -CA63 852F -CA64 8530 -CA65 8531 -CA66 8532 -CA67 8533 -CA68 8534 -CA69 8535 -CA6A 8536 -C7BE 8537 -DDFA 8538 -DDFC 8539 -DDFE 853A -DEA2 853B -B0AA 853C -B1CE 853D -CA6B 853E -CA6C 853F -CA6D 8540 -CA6E 8541 -CA6F 8542 -DEAC 8543 -CA70 8544 -CA71 8545 -CA72 8546 -CA73 8547 -DEA6 8548 -BDB6 8549 -C8EF 854A -CA74 854B -CA75 854C -CA76 854D -CA77 854E -CA78 854F -CA79 8550 -CA7A 8551 -CA7B 8552 -CA7C 8553 -CA7D 8554 -CA7E 8555 -DEA1 8556 -CA80 8557 -CA81 8558 -DEA5 8559 -CA82 855A -CA83 855B -CA84 855C -CA85 855D -DEA9 855E -CA86 855F -CA87 8560 -CA88 8561 -CA89 8562 -CA8A 8563 -DEA8 8564 -CA8B 8565 -CA8C 8566 -CA8D 8567 -DEA7 8568 -CA8E 8569 -CA8F 856A -CA90 856B -CA91 856C -CA92 856D -CA93 856E -CA94 856F -CA95 8570 -CA96 8571 -DEAD 8572 -CA97 8573 -D4CC 8574 -CA98 8575 -CA99 8576 -CA9A 8577 -CA9B 8578 -DEB3 8579 -DEAA 857A -DEAE 857B -CA9C 857C -CA9D 857D -C0D9 857E -CA9E 857F -CA9F 8580 -CAA0 8581 -CB40 8582 -CB41 8583 -B1A1 8584 -DEB6 8585 -CB42 8586 -DEB1 8587 -CB43 8588 -CB44 8589 -CB45 858A -CB46 858B -CB47 858C -CB48 858D -CB49 858E -DEB2 858F -CB4A 8590 -CB4B 8591 -CB4C 8592 -CB4D 8593 -CB4E 8594 -CB4F 8595 -CB50 8596 -CB51 8597 -CB52 8598 -CB53 8599 -CB54 859A -D1A6 859B -DEB5 859C -CB55 859D -CB56 859E -CB57 859F -CB58 85A0 -CB59 85A1 -CB5A 85A2 -CB5B 85A3 -DEAF 85A4 -CB5C 85A5 -CB5D 85A6 -CB5E 85A7 -DEB0 85A8 -CB5F 85A9 -D0BD 85AA -CB60 85AB -CB61 85AC -CB62 85AD -DEB4 85AE -CAED 85AF -DEB9 85B0 -CB63 85B1 -CB64 85B2 -CB65 85B3 -CB66 85B4 -CB67 85B5 -CB68 85B6 -DEB8 85B7 -CB69 85B8 -DEB7 85B9 -CB6A 85BA -CB6B 85BB -CB6C 85BC -CB6D 85BD -CB6E 85BE -CB6F 85BF -CB70 85C0 -DEBB 85C1 -CB71 85C2 -CB72 85C3 -CB73 85C4 -CB74 85C5 -CB75 85C6 -CB76 85C7 -CB77 85C8 -BDE5 85C9 -CB78 85CA -CB79 85CB -CB7A 85CC -CB7B 85CD -CB7C 85CE -B2D8 85CF -C3EA 85D0 -CB7D 85D1 -CB7E 85D2 -DEBA 85D3 -CB80 85D4 -C5BA 85D5 -CB81 85D6 -CB82 85D7 -CB83 85D8 -CB84 85D9 -CB85 85DA -CB86 85DB -DEBC 85DC -CB87 85DD -CB88 85DE -CB89 85DF -CB8A 85E0 -CB8B 85E1 -CB8C 85E2 -CB8D 85E3 -CCD9 85E4 -CB8E 85E5 -CB8F 85E6 -CB90 85E7 -CB91 85E8 -B7AA 85E9 -CB92 85EA -CB93 85EB -CB94 85EC -CB95 85ED -CB96 85EE -CB97 85EF -CB98 85F0 -CB99 85F1 -CB9A 85F2 -CB9B 85F3 -CB9C 85F4 -CB9D 85F5 -CB9E 85F6 -CB9F 85F7 -CBA0 85F8 -CC40 85F9 -CC41 85FA -D4E5 85FB -CC42 85FC -CC43 85FD -CC44 85FE -DEBD 85FF -CC45 8600 -CC46 8601 -CC47 8602 -CC48 8603 -CC49 8604 -DEBF 8605 -CC4A 8606 -CC4B 8607 -CC4C 8608 -CC4D 8609 -CC4E 860A -CC4F 860B -CC50 860C -CC51 860D -CC52 860E -CC53 860F -CC54 8610 -C4A2 8611 -CC55 8612 -CC56 8613 -CC57 8614 -CC58 8615 -DEC1 8616 -CC59 8617 -CC5A 8618 -CC5B 8619 -CC5C 861A -CC5D 861B -CC5E 861C -CC5F 861D -CC60 861E -CC61 861F -CC62 8620 -CC63 8621 -CC64 8622 -CC65 8623 -CC66 8624 -CC67 8625 -CC68 8626 -DEBE 8627 -CC69 8628 -DEC0 8629 -CC6A 862A -CC6B 862B -CC6C 862C -CC6D 862D -CC6E 862E -CC6F 862F -CC70 8630 -CC71 8631 -CC72 8632 -CC73 8633 -CC74 8634 -CC75 8635 -CC76 8636 -CC77 8637 -D5BA 8638 -CC78 8639 -CC79 863A -CC7A 863B -DEC2 863C -CC7B 863D -CC7C 863E -CC7D 863F -CC7E 8640 -CC80 8641 -CC81 8642 -CC82 8643 -CC83 8644 -CC84 8645 -CC85 8646 -CC86 8647 -CC87 8648 -CC88 8649 -CC89 864A -CC8A 864B -CC8B 864C -F2AE 864D -BBA2 864E -C2B2 864F -C5B0 8650 -C2C7 8651 -CC8C 8652 -CC8D 8653 -F2AF 8654 -CC8E 8655 -CC8F 8656 -CC90 8657 -CC91 8658 -CC92 8659 -D0E9 865A -CC93 865B -CC94 865C -CC95 865D -D3DD 865E -CC96 865F -CC97 8660 -CC98 8661 -EBBD 8662 -CC99 8663 -CC9A 8664 -CC9B 8665 -CC9C 8666 -CC9D 8667 -CC9E 8668 -CC9F 8669 -CCA0 866A -B3E6 866B -F2B0 866C -CD40 866D -F2B1 866E -CD41 866F -CD42 8670 -CAAD 8671 -CD43 8672 -CD44 8673 -CD45 8674 -CD46 8675 -CD47 8676 -CD48 8677 -CD49 8678 -BAE7 8679 -F2B3 867A -F2B5 867B -F2B4 867C -CBE4 867D -CFBA 867E -F2B2 867F -CAB4 8680 -D2CF 8681 -C2EC 8682 -CD4A 8683 -CD4B 8684 -CD4C 8685 -CD4D 8686 -CD4E 8687 -CD4F 8688 -CD50 8689 -CEC3 868A -F2B8 868B -B0F6 868C -F2B7 868D -CD51 868E -CD52 868F -CD53 8690 -CD54 8691 -CD55 8692 -F2BE 8693 -CD56 8694 -B2CF 8695 -CD57 8696 -CD58 8697 -CD59 8698 -CD5A 8699 -CD5B 869A -CD5C 869B -D1C1 869C -F2BA 869D -CD5D 869E -CD5E 869F -CD5F 86A0 -CD60 86A1 -CD61 86A2 -F2BC 86A3 -D4E9 86A4 -CD62 86A5 -CD63 86A6 -F2BB 86A7 -F2B6 86A8 -F2BF 86A9 -F2BD 86AA -CD64 86AB -F2B9 86AC -CD65 86AD -CD66 86AE -F2C7 86AF -F2C4 86B0 -F2C6 86B1 -CD67 86B2 -CD68 86B3 -F2CA 86B4 -F2C2 86B5 -F2C0 86B6 -CD69 86B7 -CD6A 86B8 -CD6B 86B9 -F2C5 86BA -CD6C 86BB -CD6D 86BC -CD6E 86BD -CD6F 86BE -CD70 86BF -D6FB 86C0 -CD71 86C1 -CD72 86C2 -CD73 86C3 -F2C1 86C4 -CD74 86C5 -C7F9 86C6 -C9DF 86C7 -CD75 86C8 -F2C8 86C9 -B9C6 86CA -B5B0 86CB -CD76 86CC -CD77 86CD -F2C3 86CE -F2C9 86CF -F2D0 86D0 -F2D6 86D1 -CD78 86D2 -CD79 86D3 -BBD7 86D4 -CD7A 86D5 -CD7B 86D6 -CD7C 86D7 -F2D5 86D8 -CDDC 86D9 -CD7D 86DA -D6EB 86DB -CD7E 86DC -CD80 86DD -F2D2 86DE -F2D4 86DF -CD81 86E0 -CD82 86E1 -CD83 86E2 -CD84 86E3 -B8F2 86E4 -CD85 86E5 -CD86 86E6 -CD87 86E7 -CD88 86E8 -F2CB 86E9 -CD89 86EA -CD8A 86EB -CD8B 86EC -F2CE 86ED -C2F9 86EE -CD8C 86EF -D5DD 86F0 -F2CC 86F1 -F2CD 86F2 -F2CF 86F3 -F2D3 86F4 -CD8D 86F5 -CD8E 86F6 -CD8F 86F7 -F2D9 86F8 -D3BC 86F9 -CD90 86FA -CD91 86FB -CD92 86FC -CD93 86FD -B6EA 86FE -CD94 86FF -CAF1 8700 -CD95 8701 -B7E4 8702 -F2D7 8703 -CD96 8704 -CD97 8705 -CD98 8706 -F2D8 8707 -F2DA 8708 -F2DD 8709 -F2DB 870A -CD99 870B -CD9A 870C -F2DC 870D -CD9B 870E -CD9C 870F -CD9D 8710 -CD9E 8711 -D1D1 8712 -F2D1 8713 -CD9F 8714 -CDC9 8715 -CDA0 8716 -CECF 8717 -D6A9 8718 -CE40 8719 -F2E3 871A -CE41 871B -C3DB 871C -CE42 871D -F2E0 871E -CE43 871F -CE44 8720 -C0AF 8721 -F2EC 8722 -F2DE 8723 -CE45 8724 -F2E1 8725 -CE46 8726 -CE47 8727 -CE48 8728 -F2E8 8729 -CE49 872A -CE4A 872B -CE4B 872C -CE4C 872D -F2E2 872E -CE4D 872F -CE4E 8730 -F2E7 8731 -CE4F 8732 -CE50 8733 -F2E6 8734 -CE51 8735 -CE52 8736 -F2E9 8737 -CE53 8738 -CE54 8739 -CE55 873A -F2DF 873B -CE56 873C -CE57 873D -F2E4 873E -F2EA 873F -CE58 8740 -CE59 8741 -CE5A 8742 -CE5B 8743 -CE5C 8744 -CE5D 8745 -CE5E 8746 -D3AC 8747 -F2E5 8748 -B2F5 8749 -CE5F 874A -CE60 874B -F2F2 874C -CE61 874D -D0AB 874E -CE62 874F -CE63 8750 -CE64 8751 -CE65 8752 -F2F5 8753 -CE66 8754 -CE67 8755 -CE68 8756 -BBC8 8757 -CE69 8758 -F2F9 8759 -CE6A 875A -CE6B 875B -CE6C 875C -CE6D 875D -CE6E 875E -CE6F 875F -F2F0 8760 -CE70 8761 -CE71 8762 -F2F6 8763 -F2F8 8764 -F2FA 8765 -CE72 8766 -CE73 8767 -CE74 8768 -CE75 8769 -CE76 876A -CE77 876B -CE78 876C -CE79 876D -F2F3 876E -CE7A 876F -F2F1 8770 -CE7B 8771 -CE7C 8772 -CE7D 8773 -BAFB 8774 -CE7E 8775 -B5FB 8776 -CE80 8777 -CE81 8778 -CE82 8779 -CE83 877A -F2EF 877B -F2F7 877C -F2ED 877D -F2EE 877E -CE84 877F -CE85 8780 -CE86 8781 -F2EB 8782 -F3A6 8783 -CE87 8784 -F3A3 8785 -CE88 8786 -CE89 8787 -F3A2 8788 -CE8A 8789 -CE8B 878A -F2F4 878B -CE8C 878C -C8DA 878D -CE8D 878E -CE8E 878F -CE8F 8790 -CE90 8791 -CE91 8792 -F2FB 8793 -CE92 8794 -CE93 8795 -CE94 8796 -F3A5 8797 -CE95 8798 -CE96 8799 -CE97 879A -CE98 879B -CE99 879C -CE9A 879D -CE9B 879E -C3F8 879F -CE9C 87A0 -CE9D 87A1 -CE9E 87A2 -CE9F 87A3 -CEA0 87A4 -CF40 87A5 -CF41 87A6 -CF42 87A7 -F2FD 87A8 -CF43 87A9 -CF44 87AA -F3A7 87AB -F3A9 87AC -F3A4 87AD -CF45 87AE -F2FC 87AF -CF46 87B0 -CF47 87B1 -CF48 87B2 -F3AB 87B3 -CF49 87B4 -F3AA 87B5 -CF4A 87B6 -CF4B 87B7 -CF4C 87B8 -CF4D 87B9 -C2DD 87BA -CF4E 87BB -CF4F 87BC -F3AE 87BD -CF50 87BE -CF51 87BF -F3B0 87C0 -CF52 87C1 -CF53 87C2 -CF54 87C3 -CF55 87C4 -CF56 87C5 -F3A1 87C6 -CF57 87C7 -CF58 87C8 -CF59 87C9 -F3B1 87CA -F3AC 87CB -CF5A 87CC -CF5B 87CD -CF5C 87CE -CF5D 87CF -CF5E 87D0 -F3AF 87D1 -F2FE 87D2 -F3AD 87D3 -CF5F 87D4 -CF60 87D5 -CF61 87D6 -CF62 87D7 -CF63 87D8 -CF64 87D9 -CF65 87DA -F3B2 87DB -CF66 87DC -CF67 87DD -CF68 87DE -CF69 87DF -F3B4 87E0 -CF6A 87E1 -CF6B 87E2 -CF6C 87E3 -CF6D 87E4 -F3A8 87E5 -CF6E 87E6 -CF6F 87E7 -CF70 87E8 -CF71 87E9 -F3B3 87EA -CF72 87EB -CF73 87EC -CF74 87ED -F3B5 87EE -CF75 87EF -CF76 87F0 -CF77 87F1 -CF78 87F2 -CF79 87F3 -CF7A 87F4 -CF7B 87F5 -CF7C 87F6 -CF7D 87F7 -CF7E 87F8 -D0B7 87F9 -CF80 87FA -CF81 87FB -CF82 87FC -CF83 87FD -F3B8 87FE -CF84 87FF -CF85 8800 -CF86 8801 -CF87 8802 -D9F9 8803 -CF88 8804 -CF89 8805 -CF8A 8806 -CF8B 8807 -CF8C 8808 -CF8D 8809 -F3B9 880A -CF8E 880B -CF8F 880C -CF90 880D -CF91 880E -CF92 880F -CF93 8810 -CF94 8811 -CF95 8812 -F3B7 8813 -CF96 8814 -C8E4 8815 -F3B6 8816 -CF97 8817 -CF98 8818 -CF99 8819 -CF9A 881A -F3BA 881B -CF9B 881C -CF9C 881D -CF9D 881E -CF9E 881F -CF9F 8820 -F3BB 8821 -B4C0 8822 -CFA0 8823 -D040 8824 -D041 8825 -D042 8826 -D043 8827 -D044 8828 -D045 8829 -D046 882A -D047 882B -D048 882C -D049 882D -D04A 882E -D04B 882F -D04C 8830 -D04D 8831 -EEC3 8832 -D04E 8833 -D04F 8834 -D050 8835 -D051 8836 -D052 8837 -D053 8838 -F3BC 8839 -D054 883A -D055 883B -F3BD 883C -D056 883D -D057 883E -D058 883F -D1AA 8840 -D059 8841 -D05A 8842 -D05B 8843 -F4AC 8844 -D0C6 8845 -D05C 8846 -D05D 8847 -D05E 8848 -D05F 8849 -D060 884A -D061 884B -D0D0 884C -D1DC 884D -D062 884E -D063 884F -D064 8850 -D065 8851 -D066 8852 -D067 8853 -CFCE 8854 -D068 8855 -D069 8856 -BDD6 8857 -D06A 8858 -D1C3 8859 -D06B 885A -D06C 885B -D06D 885C -D06E 885D -D06F 885E -D070 885F -D071 8860 -BAE2 8861 -E1E9 8862 -D2C2 8863 -F1C2 8864 -B2B9 8865 -D072 8866 -D073 8867 -B1ED 8868 -F1C3 8869 -D074 886A -C9C0 886B -B3C4 886C -D075 886D -D9F2 886E -D076 886F -CBA5 8870 -D077 8871 -F1C4 8872 -D078 8873 -D079 8874 -D07A 8875 -D07B 8876 -D6D4 8877 -D07C 8878 -D07D 8879 -D07E 887A -D080 887B -D081 887C -F1C5 887D -F4C0 887E -F1C6 887F -D082 8880 -D4AC 8881 -F1C7 8882 -D083 8883 -B0C0 8884 -F4C1 8885 -D084 8886 -D085 8887 -F4C2 8888 -D086 8889 -D087 888A -B4FC 888B -D088 888C -C5DB 888D -D089 888E -D08A 888F -D08B 8890 -D08C 8891 -CCBB 8892 -D08D 8893 -D08E 8894 -D08F 8895 -D0E4 8896 -D090 8897 -D091 8898 -D092 8899 -D093 889A -D094 889B -CDE0 889C -D095 889D -D096 889E -D097 889F -D098 88A0 -D099 88A1 -F1C8 88A2 -D09A 88A3 -D9F3 88A4 -D09B 88A5 -D09C 88A6 -D09D 88A7 -D09E 88A8 -D09F 88A9 -D0A0 88AA -B1BB 88AB -D140 88AC -CFAE 88AD -D141 88AE -D142 88AF -D143 88B0 -B8A4 88B1 -D144 88B2 -D145 88B3 -D146 88B4 -D147 88B5 -D148 88B6 -F1CA 88B7 -D149 88B8 -D14A 88B9 -D14B 88BA -D14C 88BB -F1CB 88BC -D14D 88BD -D14E 88BE -D14F 88BF -D150 88C0 -B2C3 88C1 -C1D1 88C2 -D151 88C3 -D152 88C4 -D7B0 88C5 -F1C9 88C6 -D153 88C7 -D154 88C8 -F1CC 88C9 -D155 88CA -D156 88CB -D157 88CC -D158 88CD -F1CE 88CE -D159 88CF -D15A 88D0 -D15B 88D1 -D9F6 88D2 -D15C 88D3 -D2E1 88D4 -D4A3 88D5 -D15D 88D6 -D15E 88D7 -F4C3 88D8 -C8B9 88D9 -D15F 88DA -D160 88DB -D161 88DC -D162 88DD -D163 88DE -F4C4 88DF -D164 88E0 -D165 88E1 -F1CD 88E2 -F1CF 88E3 -BFE3 88E4 -F1D0 88E5 -D166 88E6 -D167 88E7 -F1D4 88E8 -D168 88E9 -D169 88EA -D16A 88EB -D16B 88EC -D16C 88ED -D16D 88EE -D16E 88EF -F1D6 88F0 -F1D1 88F1 -D16F 88F2 -C9D1 88F3 -C5E1 88F4 -D170 88F5 -D171 88F6 -D172 88F7 -C2E3 88F8 -B9FC 88F9 -D173 88FA -D174 88FB -F1D3 88FC -D175 88FD -F1D5 88FE -D176 88FF -D177 8900 -D178 8901 -B9D3 8902 -D179 8903 -D17A 8904 -D17B 8905 -D17C 8906 -D17D 8907 -D17E 8908 -D180 8909 -F1DB 890A -D181 890B -D182 890C -D183 890D -D184 890E -D185 890F -BAD6 8910 -D186 8911 -B0FD 8912 -F1D9 8913 -D187 8914 -D188 8915 -D189 8916 -D18A 8917 -D18B 8918 -F1D8 8919 -F1D2 891A -F1DA 891B -D18C 891C -D18D 891D -D18E 891E -D18F 891F -D190 8920 -F1D7 8921 -D191 8922 -D192 8923 -D193 8924 -C8EC 8925 -D194 8926 -D195 8927 -D196 8928 -D197 8929 -CDCA 892A -F1DD 892B -D198 892C -D199 892D -D19A 892E -D19B 892F -E5BD 8930 -D19C 8931 -D19D 8932 -D19E 8933 -F1DC 8934 -D19F 8935 -F1DE 8936 -D1A0 8937 -D240 8938 -D241 8939 -D242 893A -D243 893B -D244 893C -D245 893D -D246 893E -D247 893F -D248 8940 -F1DF 8941 -D249 8942 -D24A 8943 -CFE5 8944 -D24B 8945 -D24C 8946 -D24D 8947 -D24E 8948 -D24F 8949 -D250 894A -D251 894B -D252 894C -D253 894D -D254 894E -D255 894F -D256 8950 -D257 8951 -D258 8952 -D259 8953 -D25A 8954 -D25B 8955 -D25C 8956 -D25D 8957 -D25E 8958 -D25F 8959 -D260 895A -D261 895B -D262 895C -D263 895D -F4C5 895E -BDF3 895F -D264 8960 -D265 8961 -D266 8962 -D267 8963 -D268 8964 -D269 8965 -F1E0 8966 -D26A 8967 -D26B 8968 -D26C 8969 -D26D 896A -D26E 896B -D26F 896C -D270 896D -D271 896E -D272 896F -D273 8970 -D274 8971 -D275 8972 -D276 8973 -D277 8974 -D278 8975 -D279 8976 -D27A 8977 -D27B 8978 -D27C 8979 -D27D 897A -F1E1 897B -D27E 897C -D280 897D -D281 897E -CEF7 897F -D282 8980 -D2AA 8981 -D283 8982 -F1FB 8983 -D284 8984 -D285 8985 -B8B2 8986 -D286 8987 -D287 8988 -D288 8989 -D289 898A -D28A 898B -D28B 898C -D28C 898D -D28D 898E -D28E 898F -D28F 8990 -D290 8991 -D291 8992 -D292 8993 -D293 8994 -D294 8995 -D295 8996 -D296 8997 -D297 8998 -D298 8999 -D299 899A -D29A 899B -D29B 899C -D29C 899D -D29D 899E -D29E 899F -D29F 89A0 -D2A0 89A1 -D340 89A2 -D341 89A3 -D342 89A4 -D343 89A5 -D344 89A6 -D345 89A7 -D346 89A8 -D347 89A9 -D348 89AA -D349 89AB -D34A 89AC -D34B 89AD -D34C 89AE -D34D 89AF -D34E 89B0 -D34F 89B1 -D350 89B2 -D351 89B3 -D352 89B4 -D353 89B5 -D354 89B6 -D355 89B7 -D356 89B8 -D357 89B9 -D358 89BA -D359 89BB -D35A 89BC -D35B 89BD -D35C 89BE -D35D 89BF -D35E 89C0 -BCFB 89C1 -B9DB 89C2 -D35F 89C3 -B9E6 89C4 -C3D9 89C5 -CAD3 89C6 -EAE8 89C7 -C0C0 89C8 -BEF5 89C9 -EAE9 89CA -EAEA 89CB -EAEB 89CC -D360 89CD -EAEC 89CE -EAED 89CF -EAEE 89D0 -EAEF 89D1 -BDC7 89D2 -D361 89D3 -D362 89D4 -D363 89D5 -F5FB 89D6 -D364 89D7 -D365 89D8 -D366 89D9 -F5FD 89DA -D367 89DB -F5FE 89DC -D368 89DD -F5FC 89DE -D369 89DF -D36A 89E0 -D36B 89E1 -D36C 89E2 -BDE2 89E3 -D36D 89E4 -F6A1 89E5 -B4A5 89E6 -D36E 89E7 -D36F 89E8 -D370 89E9 -D371 89EA -F6A2 89EB -D372 89EC -D373 89ED -D374 89EE -F6A3 89EF -D375 89F0 -D376 89F1 -D377 89F2 -ECB2 89F3 -D378 89F4 -D379 89F5 -D37A 89F6 -D37B 89F7 -D37C 89F8 -D37D 89F9 -D37E 89FA -D380 89FB -D381 89FC -D382 89FD -D383 89FE -D384 89FF -D1D4 8A00 -D385 8A01 -D386 8A02 -D387 8A03 -D388 8A04 -D389 8A05 -D38A 8A06 -D9EA 8A07 -D38B 8A08 -D38C 8A09 -D38D 8A0A -D38E 8A0B -D38F 8A0C -D390 8A0D -D391 8A0E -D392 8A0F -D393 8A10 -D394 8A11 -D395 8A12 -D396 8A13 -D397 8A14 -D398 8A15 -D399 8A16 -D39A 8A17 -D39B 8A18 -D39C 8A19 -D39D 8A1A -D39E 8A1B -D39F 8A1C -D3A0 8A1D -D440 8A1E -D441 8A1F -D442 8A20 -D443 8A21 -D444 8A22 -D445 8A23 -D446 8A24 -D447 8A25 -D448 8A26 -D449 8A27 -D44A 8A28 -D44B 8A29 -D44C 8A2A -D44D 8A2B -D44E 8A2C -D44F 8A2D -D450 8A2E -D451 8A2F -D452 8A30 -D453 8A31 -D454 8A32 -D455 8A33 -D456 8A34 -D457 8A35 -D458 8A36 -D459 8A37 -D45A 8A38 -D45B 8A39 -D45C 8A3A -D45D 8A3B -D45E 8A3C -D45F 8A3D -F6A4 8A3E -D460 8A3F -D461 8A40 -D462 8A41 -D463 8A42 -D464 8A43 -D465 8A44 -D466 8A45 -D467 8A46 -D468 8A47 -EEBA 8A48 -D469 8A49 -D46A 8A4A -D46B 8A4B -D46C 8A4C -D46D 8A4D -D46E 8A4E -D46F 8A4F -D470 8A50 -D471 8A51 -D472 8A52 -D473 8A53 -D474 8A54 -D475 8A55 -D476 8A56 -D477 8A57 -D478 8A58 -D479 8A59 -D47A 8A5A -D47B 8A5B -D47C 8A5C -D47D 8A5D -D47E 8A5E -D480 8A5F -D481 8A60 -D482 8A61 -D483 8A62 -D484 8A63 -D485 8A64 -D486 8A65 -D487 8A66 -D488 8A67 -D489 8A68 -D48A 8A69 -D48B 8A6A -D48C 8A6B -D48D 8A6C -D48E 8A6D -D48F 8A6E -D490 8A6F -D491 8A70 -D492 8A71 -D493 8A72 -D494 8A73 -D495 8A74 -D496 8A75 -D497 8A76 -D498 8A77 -D499 8A78 -D5B2 8A79 -D49A 8A7A -D49B 8A7B -D49C 8A7C -D49D 8A7D -D49E 8A7E -D49F 8A7F -D4A0 8A80 -D540 8A81 -D541 8A82 -D542 8A83 -D543 8A84 -D544 8A85 -D545 8A86 -D546 8A87 -D547 8A88 -D3FE 8A89 -CCDC 8A8A -D548 8A8B -D549 8A8C -D54A 8A8D -D54B 8A8E -D54C 8A8F -D54D 8A90 -D54E 8A91 -D54F 8A92 -CAC4 8A93 -D550 8A94 -D551 8A95 -D552 8A96 -D553 8A97 -D554 8A98 -D555 8A99 -D556 8A9A -D557 8A9B -D558 8A9C -D559 8A9D -D55A 8A9E -D55B 8A9F -D55C 8AA0 -D55D 8AA1 -D55E 8AA2 -D55F 8AA3 -D560 8AA4 -D561 8AA5 -D562 8AA6 -D563 8AA7 -D564 8AA8 -D565 8AA9 -D566 8AAA -D567 8AAB -D568 8AAC -D569 8AAD -D56A 8AAE -D56B 8AAF -D56C 8AB0 -D56D 8AB1 -D56E 8AB2 -D56F 8AB3 -D570 8AB4 -D571 8AB5 -D572 8AB6 -D573 8AB7 -D574 8AB8 -D575 8AB9 -D576 8ABA -D577 8ABB -D578 8ABC -D579 8ABD -D57A 8ABE -D57B 8ABF -D57C 8AC0 -D57D 8AC1 -D57E 8AC2 -D580 8AC3 -D581 8AC4 -D582 8AC5 -D583 8AC6 -D584 8AC7 -D585 8AC8 -D586 8AC9 -D587 8ACA -D588 8ACB -D589 8ACC -D58A 8ACD -D58B 8ACE -D58C 8ACF -D58D 8AD0 -D58E 8AD1 -D58F 8AD2 -D590 8AD3 -D591 8AD4 -D592 8AD5 -D593 8AD6 -D594 8AD7 -D595 8AD8 -D596 8AD9 -D597 8ADA -D598 8ADB -D599 8ADC -D59A 8ADD -D59B 8ADE -D59C 8ADF -D59D 8AE0 -D59E 8AE1 -D59F 8AE2 -D5A0 8AE3 -D640 8AE4 -D641 8AE5 -D642 8AE6 -D643 8AE7 -D644 8AE8 -D645 8AE9 -D646 8AEA -D647 8AEB -D648 8AEC -D649 8AED -D64A 8AEE -D64B 8AEF -D64C 8AF0 -D64D 8AF1 -D64E 8AF2 -D64F 8AF3 -D650 8AF4 -D651 8AF5 -D652 8AF6 -D653 8AF7 -D654 8AF8 -D655 8AF9 -D656 8AFA -D657 8AFB -D658 8AFC -D659 8AFD -D65A 8AFE -D65B 8AFF -D65C 8B00 -D65D 8B01 -D65E 8B02 -D65F 8B03 -D660 8B04 -D661 8B05 -D662 8B06 -E5C0 8B07 -D663 8B08 -D664 8B09 -D665 8B0A -D666 8B0B -D667 8B0C -D668 8B0D -D669 8B0E -D66A 8B0F -D66B 8B10 -D66C 8B11 -D66D 8B12 -D66E 8B13 -D66F 8B14 -D670 8B15 -D671 8B16 -D672 8B17 -D673 8B18 -D674 8B19 -D675 8B1A -D676 8B1B -D677 8B1C -D678 8B1D -D679 8B1E -D67A 8B1F -D67B 8B20 -D67C 8B21 -D67D 8B22 -D67E 8B23 -D680 8B24 -D681 8B25 -F6A5 8B26 -D682 8B27 -D683 8B28 -D684 8B29 -D685 8B2A -D686 8B2B -D687 8B2C -D688 8B2D -D689 8B2E -D68A 8B2F -D68B 8B30 -D68C 8B31 -D68D 8B32 -D68E 8B33 -D68F 8B34 -D690 8B35 -D691 8B36 -D692 8B37 -D693 8B38 -D694 8B39 -D695 8B3A -D696 8B3B -D697 8B3C -D698 8B3D -D699 8B3E -D69A 8B3F -D69B 8B40 -D69C 8B41 -D69D 8B42 -D69E 8B43 -D69F 8B44 -D6A0 8B45 -D740 8B46 -D741 8B47 -D742 8B48 -D743 8B49 -D744 8B4A -D745 8B4B -D746 8B4C -D747 8B4D -D748 8B4E -D749 8B4F -D74A 8B50 -D74B 8B51 -D74C 8B52 -D74D 8B53 -D74E 8B54 -D74F 8B55 -D750 8B56 -D751 8B57 -D752 8B58 -D753 8B59 -D754 8B5A -D755 8B5B -D756 8B5C -D757 8B5D -D758 8B5E -D759 8B5F -D75A 8B60 -D75B 8B61 -D75C 8B62 -D75D 8B63 -D75E 8B64 -D75F 8B65 -BEAF 8B66 -D760 8B67 -D761 8B68 -D762 8B69 -D763 8B6A -D764 8B6B -C6A9 8B6C -D765 8B6D -D766 8B6E -D767 8B6F -D768 8B70 -D769 8B71 -D76A 8B72 -D76B 8B73 -D76C 8B74 -D76D 8B75 -D76E 8B76 -D76F 8B77 -D770 8B78 -D771 8B79 -D772 8B7A -D773 8B7B -D774 8B7C -D775 8B7D -D776 8B7E -D777 8B7F -D778 8B80 -D779 8B81 -D77A 8B82 -D77B 8B83 -D77C 8B84 -D77D 8B85 -D77E 8B86 -D780 8B87 -D781 8B88 -D782 8B89 -D783 8B8A -D784 8B8B -D785 8B8C -D786 8B8D -D787 8B8E -D788 8B8F -D789 8B90 -D78A 8B91 -D78B 8B92 -D78C 8B93 -D78D 8B94 -D78E 8B95 -D78F 8B96 -D790 8B97 -D791 8B98 -D792 8B99 -D793 8B9A -D794 8B9B -D795 8B9C -D796 8B9D -D797 8B9E -D798 8B9F -DAA5 8BA0 -BCC6 8BA1 -B6A9 8BA2 -B8BC 8BA3 -C8CF 8BA4 -BCA5 8BA5 -DAA6 8BA6 -DAA7 8BA7 -CCD6 8BA8 -C8C3 8BA9 -DAA8 8BAA -C6FD 8BAB -D799 8BAC -D1B5 8BAD -D2E9 8BAE -D1B6 8BAF -BCC7 8BB0 -D79A 8BB1 -BDB2 8BB2 -BBE4 8BB3 -DAA9 8BB4 -DAAA 8BB5 -D1C8 8BB6 -DAAB 8BB7 -D0ED 8BB8 -B6EF 8BB9 -C2DB 8BBA -D79B 8BBB -CBCF 8BBC -B7ED 8BBD -C9E8 8BBE -B7C3 8BBF -BEF7 8BC0 -D6A4 8BC1 -DAAC 8BC2 -DAAD 8BC3 -C6C0 8BC4 -D7E7 8BC5 -CAB6 8BC6 -D79C 8BC7 -D5A9 8BC8 -CBDF 8BC9 -D5EF 8BCA -DAAE 8BCB -D6DF 8BCC -B4CA 8BCD -DAB0 8BCE -DAAF 8BCF -D79D 8BD0 -D2EB 8BD1 -DAB1 8BD2 -DAB2 8BD3 -DAB3 8BD4 -CAD4 8BD5 -DAB4 8BD6 -CAAB 8BD7 -DAB5 8BD8 -DAB6 8BD9 -B3CF 8BDA -D6EF 8BDB -DAB7 8BDC -BBB0 8BDD -B5AE 8BDE -DAB8 8BDF -DAB9 8BE0 -B9EE 8BE1 -D1AF 8BE2 -D2E8 8BE3 -DABA 8BE4 -B8C3 8BE5 -CFEA 8BE6 -B2EF 8BE7 -DABB 8BE8 -DABC 8BE9 -D79E 8BEA -BDEB 8BEB -CEDC 8BEC -D3EF 8BED -DABD 8BEE -CEF3 8BEF -DABE 8BF0 -D3D5 8BF1 -BBE5 8BF2 -DABF 8BF3 -CBB5 8BF4 -CBD0 8BF5 -DAC0 8BF6 -C7EB 8BF7 -D6EE 8BF8 -DAC1 8BF9 -C5B5 8BFA -B6C1 8BFB -DAC2 8BFC -B7CC 8BFD -BFCE 8BFE -DAC3 8BFF -DAC4 8C00 -CBAD 8C01 -DAC5 8C02 -B5F7 8C03 -DAC6 8C04 -C1C2 8C05 -D7BB 8C06 -DAC7 8C07 -CCB8 8C08 -D79F 8C09 -D2EA 8C0A -C4B1 8C0B -DAC8 8C0C -B5FD 8C0D -BBD1 8C0E -DAC9 8C0F -D0B3 8C10 -DACA 8C11 -DACB 8C12 -CEBD 8C13 -DACC 8C14 -DACD 8C15 -DACE 8C16 -B2F7 8C17 -DAD1 8C18 -DACF 8C19 -D1E8 8C1A -DAD0 8C1B -C3D5 8C1C -DAD2 8C1D -D7A0 8C1E -DAD3 8C1F -DAD4 8C20 -DAD5 8C21 -D0BB 8C22 -D2A5 8C23 -B0F9 8C24 -DAD6 8C25 -C7AB 8C26 -DAD7 8C27 -BDF7 8C28 -C3A1 8C29 -DAD8 8C2A -DAD9 8C2B -C3FD 8C2C -CCB7 8C2D -DADA 8C2E -DADB 8C2F -C0BE 8C30 -C6D7 8C31 -DADC 8C32 -DADD 8C33 -C7B4 8C34 -DADE 8C35 -DADF 8C36 -B9C8 8C37 -D840 8C38 -D841 8C39 -D842 8C3A -D843 8C3B -D844 8C3C -D845 8C3D -D846 8C3E -D847 8C3F -D848 8C40 -BBED 8C41 -D849 8C42 -D84A 8C43 -D84B 8C44 -D84C 8C45 -B6B9 8C46 -F4F8 8C47 -D84D 8C48 -F4F9 8C49 -D84E 8C4A -D84F 8C4B -CDE3 8C4C -D850 8C4D -D851 8C4E -D852 8C4F -D853 8C50 -D854 8C51 -D855 8C52 -D856 8C53 -D857 8C54 -F5B9 8C55 -D858 8C56 -D859 8C57 -D85A 8C58 -D85B 8C59 -EBE0 8C5A -D85C 8C5B -D85D 8C5C -D85E 8C5D -D85F 8C5E -D860 8C5F -D861 8C60 -CFF3 8C61 -BBBF 8C62 -D862 8C63 -D863 8C64 -D864 8C65 -D865 8C66 -D866 8C67 -D867 8C68 -D868 8C69 -BAC0 8C6A -D4A5 8C6B -D869 8C6C -D86A 8C6D -D86B 8C6E -D86C 8C6F -D86D 8C70 -D86E 8C71 -D86F 8C72 -E1D9 8C73 -D870 8C74 -D871 8C75 -D872 8C76 -D873 8C77 -F5F4 8C78 -B1AA 8C79 -B2F2 8C7A -D874 8C7B -D875 8C7C -D876 8C7D -D877 8C7E -D878 8C7F -D879 8C80 -D87A 8C81 -F5F5 8C82 -D87B 8C83 -D87C 8C84 -F5F7 8C85 -D87D 8C86 -D87E 8C87 -D880 8C88 -BAD1 8C89 -F5F6 8C8A -D881 8C8B -C3B2 8C8C -D882 8C8D -D883 8C8E -D884 8C8F -D885 8C90 -D886 8C91 -D887 8C92 -D888 8C93 -F5F9 8C94 -D889 8C95 -D88A 8C96 -D88B 8C97 -F5F8 8C98 -D88C 8C99 -D88D 8C9A -D88E 8C9B -D88F 8C9C -D890 8C9D -D891 8C9E -D892 8C9F -D893 8CA0 -D894 8CA1 -D895 8CA2 -D896 8CA3 -D897 8CA4 -D898 8CA5 -D899 8CA6 -D89A 8CA7 -D89B 8CA8 -D89C 8CA9 -D89D 8CAA -D89E 8CAB -D89F 8CAC -D8A0 8CAD -D940 8CAE -D941 8CAF -D942 8CB0 -D943 8CB1 -D944 8CB2 -D945 8CB3 -D946 8CB4 -D947 8CB5 -D948 8CB6 -D949 8CB7 -D94A 8CB8 -D94B 8CB9 -D94C 8CBA -D94D 8CBB -D94E 8CBC -D94F 8CBD -D950 8CBE -D951 8CBF -D952 8CC0 -D953 8CC1 -D954 8CC2 -D955 8CC3 -D956 8CC4 -D957 8CC5 -D958 8CC6 -D959 8CC7 -D95A 8CC8 -D95B 8CC9 -D95C 8CCA -D95D 8CCB -D95E 8CCC -D95F 8CCD -D960 8CCE -D961 8CCF -D962 8CD0 -D963 8CD1 -D964 8CD2 -D965 8CD3 -D966 8CD4 -D967 8CD5 -D968 8CD6 -D969 8CD7 -D96A 8CD8 -D96B 8CD9 -D96C 8CDA -D96D 8CDB -D96E 8CDC -D96F 8CDD -D970 8CDE -D971 8CDF -D972 8CE0 -D973 8CE1 -D974 8CE2 -D975 8CE3 -D976 8CE4 -D977 8CE5 -D978 8CE6 -D979 8CE7 -D97A 8CE8 -D97B 8CE9 -D97C 8CEA -D97D 8CEB -D97E 8CEC -D980 8CED -D981 8CEE -D982 8CEF -D983 8CF0 -D984 8CF1 -D985 8CF2 -D986 8CF3 -D987 8CF4 -D988 8CF5 -D989 8CF6 -D98A 8CF7 -D98B 8CF8 -D98C 8CF9 -D98D 8CFA -D98E 8CFB -D98F 8CFC -D990 8CFD -D991 8CFE -D992 8CFF -D993 8D00 -D994 8D01 -D995 8D02 -D996 8D03 -D997 8D04 -D998 8D05 -D999 8D06 -D99A 8D07 -D99B 8D08 -D99C 8D09 -D99D 8D0A -D99E 8D0B -D99F 8D0C -D9A0 8D0D -DA40 8D0E -DA41 8D0F -DA42 8D10 -DA43 8D11 -DA44 8D12 -DA45 8D13 -DA46 8D14 -DA47 8D15 -DA48 8D16 -DA49 8D17 -DA4A 8D18 -DA4B 8D19 -DA4C 8D1A -DA4D 8D1B -DA4E 8D1C -B1B4 8D1D -D5EA 8D1E -B8BA 8D1F -DA4F 8D20 -B9B1 8D21 -B2C6 8D22 -D4F0 8D23 -CFCD 8D24 -B0DC 8D25 -D5CB 8D26 -BBF5 8D27 -D6CA 8D28 -B7B7 8D29 -CCB0 8D2A -C6B6 8D2B -B1E1 8D2C -B9BA 8D2D -D6FC 8D2E -B9E1 8D2F -B7A1 8D30 -BCFA 8D31 -EADA 8D32 -EADB 8D33 -CCF9 8D34 -B9F3 8D35 -EADC 8D36 -B4FB 8D37 -C3B3 8D38 -B7D1 8D39 -BAD8 8D3A -EADD 8D3B -D4F4 8D3C -EADE 8D3D -BCD6 8D3E -BBDF 8D3F -EADF 8D40 -C1DE 8D41 -C2B8 8D42 -D4DF 8D43 -D7CA 8D44 -EAE0 8D45 -EAE1 8D46 -EAE4 8D47 -EAE2 8D48 -EAE3 8D49 -C9DE 8D4A -B8B3 8D4B -B6C4 8D4C -EAE5 8D4D -CAEA 8D4E -C9CD 8D4F -B4CD 8D50 -DA50 8D51 -DA51 8D52 -E2D9 8D53 -C5E2 8D54 -EAE6 8D55 -C0B5 8D56 -DA52 8D57 -D7B8 8D58 -EAE7 8D59 -D7AC 8D5A -C8FC 8D5B -D8D3 8D5C -D8CD 8D5D -D4DE 8D5E -DA53 8D5F -D4F9 8D60 -C9C4 8D61 -D3AE 8D62 -B8D3 8D63 -B3E0 8D64 -DA54 8D65 -C9E2 8D66 -F4F6 8D67 -DA55 8D68 -DA56 8D69 -DA57 8D6A -BAD5 8D6B -DA58 8D6C -F4F7 8D6D -DA59 8D6E -DA5A 8D6F -D7DF 8D70 -DA5B 8D71 -DA5C 8D72 -F4F1 8D73 -B8B0 8D74 -D5D4 8D75 -B8CF 8D76 -C6F0 8D77 -DA5D 8D78 -DA5E 8D79 -DA5F 8D7A -DA60 8D7B -DA61 8D7C -DA62 8D7D -DA63 8D7E -DA64 8D7F -DA65 8D80 -B3C3 8D81 -DA66 8D82 -DA67 8D83 -F4F2 8D84 -B3AC 8D85 -DA68 8D86 -DA69 8D87 -DA6A 8D88 -DA6B 8D89 -D4BD 8D8A -C7F7 8D8B -DA6C 8D8C -DA6D 8D8D -DA6E 8D8E -DA6F 8D8F -DA70 8D90 -F4F4 8D91 -DA71 8D92 -DA72 8D93 -F4F3 8D94 -DA73 8D95 -DA74 8D96 -DA75 8D97 -DA76 8D98 -DA77 8D99 -DA78 8D9A -DA79 8D9B -DA7A 8D9C -DA7B 8D9D -DA7C 8D9E -CCCB 8D9F -DA7D 8DA0 -DA7E 8DA1 -DA80 8DA2 -C8A4 8DA3 -DA81 8DA4 -DA82 8DA5 -DA83 8DA6 -DA84 8DA7 -DA85 8DA8 -DA86 8DA9 -DA87 8DAA -DA88 8DAB -DA89 8DAC -DA8A 8DAD -DA8B 8DAE -DA8C 8DAF -DA8D 8DB0 -F4F5 8DB1 -DA8E 8DB2 -D7E3 8DB3 -C5BF 8DB4 -F5C0 8DB5 -DA8F 8DB6 -DA90 8DB7 -F5BB 8DB8 -DA91 8DB9 -F5C3 8DBA -DA92 8DBB -F5C2 8DBC -DA93 8DBD -D6BA 8DBE -F5C1 8DBF -DA94 8DC0 -DA95 8DC1 -DA96 8DC2 -D4BE 8DC3 -F5C4 8DC4 -DA97 8DC5 -F5CC 8DC6 -DA98 8DC7 -DA99 8DC8 -DA9A 8DC9 -DA9B 8DCA -B0CF 8DCB -B5F8 8DCC -DA9C 8DCD -F5C9 8DCE -F5CA 8DCF -DA9D 8DD0 -C5DC 8DD1 -DA9E 8DD2 -DA9F 8DD3 -DAA0 8DD4 -DB40 8DD5 -F5C5 8DD6 -F5C6 8DD7 -DB41 8DD8 -DB42 8DD9 -F5C7 8DDA -F5CB 8DDB -DB43 8DDC -BEE0 8DDD -F5C8 8DDE -B8FA 8DDF -DB44 8DE0 -DB45 8DE1 -DB46 8DE2 -F5D0 8DE3 -F5D3 8DE4 -DB47 8DE5 -DB48 8DE6 -DB49 8DE7 -BFE7 8DE8 -DB4A 8DE9 -B9F2 8DEA -F5BC 8DEB -F5CD 8DEC -DB4B 8DED -DB4C 8DEE -C2B7 8DEF -DB4D 8DF0 -DB4E 8DF1 -DB4F 8DF2 -CCF8 8DF3 -DB50 8DF4 -BCF9 8DF5 -DB51 8DF6 -F5CE 8DF7 -F5CF 8DF8 -F5D1 8DF9 -B6E5 8DFA -F5D2 8DFB -DB52 8DFC -F5D5 8DFD -DB53 8DFE -DB54 8DFF -DB55 8E00 -DB56 8E01 -DB57 8E02 -DB58 8E03 -DB59 8E04 -F5BD 8E05 -DB5A 8E06 -DB5B 8E07 -DB5C 8E08 -F5D4 8E09 -D3BB 8E0A -DB5D 8E0B -B3EC 8E0C -DB5E 8E0D -DB5F 8E0E -CCA4 8E0F -DB60 8E10 -DB61 8E11 -DB62 8E12 -DB63 8E13 -F5D6 8E14 -DB64 8E15 -DB65 8E16 -DB66 8E17 -DB67 8E18 -DB68 8E19 -DB69 8E1A -DB6A 8E1B -DB6B 8E1C -F5D7 8E1D -BEE1 8E1E -F5D8 8E1F -DB6C 8E20 -DB6D 8E21 -CCDF 8E22 -F5DB 8E23 -DB6E 8E24 -DB6F 8E25 -DB70 8E26 -DB71 8E27 -DB72 8E28 -B2C8 8E29 -D7D9 8E2A -DB73 8E2B -F5D9 8E2C -DB74 8E2D -F5DA 8E2E -F5DC 8E2F -DB75 8E30 -F5E2 8E31 -DB76 8E32 -DB77 8E33 -DB78 8E34 -F5E0 8E35 -DB79 8E36 -DB7A 8E37 -DB7B 8E38 -F5DF 8E39 -F5DD 8E3A -DB7C 8E3B -DB7D 8E3C -F5E1 8E3D -DB7E 8E3E -DB80 8E3F -F5DE 8E40 -F5E4 8E41 -F5E5 8E42 -DB81 8E43 -CCE3 8E44 -DB82 8E45 -DB83 8E46 -E5BF 8E47 -B5B8 8E48 -F5E3 8E49 -F5E8 8E4A -CCA3 8E4B -DB84 8E4C -DB85 8E4D -DB86 8E4E -DB87 8E4F -DB88 8E50 -F5E6 8E51 -F5E7 8E52 -DB89 8E53 -DB8A 8E54 -DB8B 8E55 -DB8C 8E56 -DB8D 8E57 -DB8E 8E58 -F5BE 8E59 -DB8F 8E5A -DB90 8E5B -DB91 8E5C -DB92 8E5D -DB93 8E5E -DB94 8E5F -DB95 8E60 -DB96 8E61 -DB97 8E62 -DB98 8E63 -DB99 8E64 -DB9A 8E65 -B1C4 8E66 -DB9B 8E67 -DB9C 8E68 -F5BF 8E69 -DB9D 8E6A -DB9E 8E6B -B5C5 8E6C -B2E4 8E6D -DB9F 8E6E -F5EC 8E6F -F5E9 8E70 -DBA0 8E71 -B6D7 8E72 -DC40 8E73 -F5ED 8E74 -DC41 8E75 -F5EA 8E76 -DC42 8E77 -DC43 8E78 -DC44 8E79 -DC45 8E7A -DC46 8E7B -F5EB 8E7C -DC47 8E7D -DC48 8E7E -B4DA 8E7F -DC49 8E80 -D4EA 8E81 -DC4A 8E82 -DC4B 8E83 -DC4C 8E84 -F5EE 8E85 -DC4D 8E86 -B3F9 8E87 -DC4E 8E88 -DC4F 8E89 -DC50 8E8A -DC51 8E8B -DC52 8E8C -DC53 8E8D -DC54 8E8E -F5EF 8E8F -F5F1 8E90 -DC55 8E91 -DC56 8E92 -DC57 8E93 -F5F0 8E94 -DC58 8E95 -DC59 8E96 -DC5A 8E97 -DC5B 8E98 -DC5C 8E99 -DC5D 8E9A -DC5E 8E9B -F5F2 8E9C -DC5F 8E9D -F5F3 8E9E -DC60 8E9F -DC61 8EA0 -DC62 8EA1 -DC63 8EA2 -DC64 8EA3 -DC65 8EA4 -DC66 8EA5 -DC67 8EA6 -DC68 8EA7 -DC69 8EA8 -DC6A 8EA9 -DC6B 8EAA -C9ED 8EAB -B9AA 8EAC -DC6C 8EAD -DC6D 8EAE -C7FB 8EAF -DC6E 8EB0 -DC6F 8EB1 -B6E3 8EB2 -DC70 8EB3 -DC71 8EB4 -DC72 8EB5 -DC73 8EB6 -DC74 8EB7 -DC75 8EB8 -DC76 8EB9 -CCC9 8EBA -DC77 8EBB -DC78 8EBC -DC79 8EBD -DC7A 8EBE -DC7B 8EBF -DC7C 8EC0 -DC7D 8EC1 -DC7E 8EC2 -DC80 8EC3 -DC81 8EC4 -DC82 8EC5 -DC83 8EC6 -DC84 8EC7 -DC85 8EC8 -DC86 8EC9 -DC87 8ECA -DC88 8ECB -DC89 8ECC -DC8A 8ECD -EAA6 8ECE -DC8B 8ECF -DC8C 8ED0 -DC8D 8ED1 -DC8E 8ED2 -DC8F 8ED3 -DC90 8ED4 -DC91 8ED5 -DC92 8ED6 -DC93 8ED7 -DC94 8ED8 -DC95 8ED9 -DC96 8EDA -DC97 8EDB -DC98 8EDC -DC99 8EDD -DC9A 8EDE -DC9B 8EDF -DC9C 8EE0 -DC9D 8EE1 -DC9E 8EE2 -DC9F 8EE3 -DCA0 8EE4 -DD40 8EE5 -DD41 8EE6 -DD42 8EE7 -DD43 8EE8 -DD44 8EE9 -DD45 8EEA -DD46 8EEB -DD47 8EEC -DD48 8EED -DD49 8EEE -DD4A 8EEF -DD4B 8EF0 -DD4C 8EF1 -DD4D 8EF2 -DD4E 8EF3 -DD4F 8EF4 -DD50 8EF5 -DD51 8EF6 -DD52 8EF7 -DD53 8EF8 -DD54 8EF9 -DD55 8EFA -DD56 8EFB -DD57 8EFC -DD58 8EFD -DD59 8EFE -DD5A 8EFF -DD5B 8F00 -DD5C 8F01 -DD5D 8F02 -DD5E 8F03 -DD5F 8F04 -DD60 8F05 -DD61 8F06 -DD62 8F07 -DD63 8F08 -DD64 8F09 -DD65 8F0A -DD66 8F0B -DD67 8F0C -DD68 8F0D -DD69 8F0E -DD6A 8F0F -DD6B 8F10 -DD6C 8F11 -DD6D 8F12 -DD6E 8F13 -DD6F 8F14 -DD70 8F15 -DD71 8F16 -DD72 8F17 -DD73 8F18 -DD74 8F19 -DD75 8F1A -DD76 8F1B -DD77 8F1C -DD78 8F1D -DD79 8F1E -DD7A 8F1F -DD7B 8F20 -DD7C 8F21 -DD7D 8F22 -DD7E 8F23 -DD80 8F24 -DD81 8F25 -DD82 8F26 -DD83 8F27 -DD84 8F28 -DD85 8F29 -DD86 8F2A -DD87 8F2B -DD88 8F2C -DD89 8F2D -DD8A 8F2E -DD8B 8F2F -DD8C 8F30 -DD8D 8F31 -DD8E 8F32 -DD8F 8F33 -DD90 8F34 -DD91 8F35 -DD92 8F36 -DD93 8F37 -DD94 8F38 -DD95 8F39 -DD96 8F3A -DD97 8F3B -DD98 8F3C -DD99 8F3D -DD9A 8F3E -DD9B 8F3F -DD9C 8F40 -DD9D 8F41 -DD9E 8F42 -DD9F 8F43 -DDA0 8F44 -DE40 8F45 -DE41 8F46 -DE42 8F47 -DE43 8F48 -DE44 8F49 -DE45 8F4A -DE46 8F4B -DE47 8F4C -DE48 8F4D -DE49 8F4E -DE4A 8F4F -DE4B 8F50 -DE4C 8F51 -DE4D 8F52 -DE4E 8F53 -DE4F 8F54 -DE50 8F55 -DE51 8F56 -DE52 8F57 -DE53 8F58 -DE54 8F59 -DE55 8F5A -DE56 8F5B -DE57 8F5C -DE58 8F5D -DE59 8F5E -DE5A 8F5F -DE5B 8F60 -DE5C 8F61 -DE5D 8F62 -DE5E 8F63 -DE5F 8F64 -DE60 8F65 -B3B5 8F66 -D4FE 8F67 -B9EC 8F68 -D0F9 8F69 -DE61 8F6A -E9ED 8F6B -D7AA 8F6C -E9EE 8F6D -C2D6 8F6E -C8ED 8F6F -BAE4 8F70 -E9EF 8F71 -E9F0 8F72 -E9F1 8F73 -D6E1 8F74 -E9F2 8F75 -E9F3 8F76 -E9F5 8F77 -E9F4 8F78 -E9F6 8F79 -E9F7 8F7A -C7E1 8F7B -E9F8 8F7C -D4D8 8F7D -E9F9 8F7E -BDCE 8F7F -DE62 8F80 -E9FA 8F81 -E9FB 8F82 -BDCF 8F83 -E9FC 8F84 -B8A8 8F85 -C1BE 8F86 -E9FD 8F87 -B1B2 8F88 -BBD4 8F89 -B9F5 8F8A -E9FE 8F8B -DE63 8F8C -EAA1 8F8D -EAA2 8F8E -EAA3 8F8F -B7F8 8F90 -BCAD 8F91 -DE64 8F92 -CAE4 8F93 -E0CE 8F94 -D4AF 8F95 -CFBD 8F96 -D5B7 8F97 -EAA4 8F98 -D5DE 8F99 -EAA5 8F9A -D0C1 8F9B -B9BC 8F9C -DE65 8F9D -B4C7 8F9E -B1D9 8F9F -DE66 8FA0 -DE67 8FA1 -DE68 8FA2 -C0B1 8FA3 -DE69 8FA4 -DE6A 8FA5 -DE6B 8FA6 -DE6C 8FA7 -B1E6 8FA8 -B1E7 8FA9 -DE6D 8FAA -B1E8 8FAB -DE6E 8FAC -DE6F 8FAD -DE70 8FAE -DE71 8FAF -B3BD 8FB0 -C8E8 8FB1 -DE72 8FB2 -DE73 8FB3 -DE74 8FB4 -DE75 8FB5 -E5C1 8FB6 -DE76 8FB7 -DE77 8FB8 -B1DF 8FB9 -DE78 8FBA -DE79 8FBB -DE7A 8FBC -C1C9 8FBD -B4EF 8FBE -DE7B 8FBF -DE7C 8FC0 -C7A8 8FC1 -D3D8 8FC2 -DE7D 8FC3 -C6F9 8FC4 -D1B8 8FC5 -DE7E 8FC6 -B9FD 8FC7 -C2F5 8FC8 -DE80 8FC9 -DE81 8FCA -DE82 8FCB -DE83 8FCC -DE84 8FCD -D3AD 8FCE -DE85 8FCF -D4CB 8FD0 -BDFC 8FD1 -DE86 8FD2 -E5C2 8FD3 -B7B5 8FD4 -E5C3 8FD5 -DE87 8FD6 -DE88 8FD7 -BBB9 8FD8 -D5E2 8FD9 -DE89 8FDA -BDF8 8FDB -D4B6 8FDC -CEA5 8FDD -C1AC 8FDE -B3D9 8FDF -DE8A 8FE0 -DE8B 8FE1 -CCF6 8FE2 -DE8C 8FE3 -E5C6 8FE4 -E5C4 8FE5 -E5C8 8FE6 -DE8D 8FE7 -E5CA 8FE8 -E5C7 8FE9 -B5CF 8FEA -C6C8 8FEB -DE8E 8FEC -B5FC 8FED -E5C5 8FEE -DE8F 8FEF -CAF6 8FF0 -DE90 8FF1 -DE91 8FF2 -E5C9 8FF3 -DE92 8FF4 -DE93 8FF5 -DE94 8FF6 -C3D4 8FF7 -B1C5 8FF8 -BCA3 8FF9 -DE95 8FFA -DE96 8FFB -DE97 8FFC -D7B7 8FFD -DE98 8FFE -DE99 8FFF -CDCB 9000 -CBCD 9001 -CACA 9002 -CCD3 9003 -E5CC 9004 -E5CB 9005 -C4E6 9006 -DE9A 9007 -DE9B 9008 -D1A1 9009 -D1B7 900A -E5CD 900B -DE9C 900C -E5D0 900D -DE9D 900E -CDB8 900F -D6F0 9010 -E5CF 9011 -B5DD 9012 -DE9E 9013 -CDBE 9014 -DE9F 9015 -E5D1 9016 -B6BA 9017 -DEA0 9018 -DF40 9019 -CDA8 901A -B9E4 901B -DF41 901C -CAC5 901D -B3D1 901E -CBD9 901F -D4EC 9020 -E5D2 9021 -B7EA 9022 -DF42 9023 -DF43 9024 -DF44 9025 -E5CE 9026 -DF45 9027 -DF46 9028 -DF47 9029 -DF48 902A -DF49 902B -DF4A 902C -E5D5 902D -B4FE 902E -E5D6 902F -DF4B 9030 -DF4C 9031 -DF4D 9032 -DF4E 9033 -DF4F 9034 -E5D3 9035 -E5D4 9036 -DF50 9037 -D2DD 9038 -DF51 9039 -DF52 903A -C2DF 903B -B1C6 903C -DF53 903D -D3E2 903E -DF54 903F -DF55 9040 -B6DD 9041 -CBEC 9042 -DF56 9043 -E5D7 9044 -DF57 9045 -DF58 9046 -D3F6 9047 -DF59 9048 -DF5A 9049 -DF5B 904A -DF5C 904B -DF5D 904C -B1E9 904D -DF5E 904E -B6F4 904F -E5DA 9050 -E5D8 9051 -E5D9 9052 -B5C0 9053 -DF5F 9054 -DF60 9055 -DF61 9056 -D2C5 9057 -E5DC 9058 -DF62 9059 -DF63 905A -E5DE 905B -DF64 905C -DF65 905D -DF66 905E -DF67 905F -DF68 9060 -DF69 9061 -E5DD 9062 -C7B2 9063 -DF6A 9064 -D2A3 9065 -DF6B 9066 -DF6C 9067 -E5DB 9068 -DF6D 9069 -DF6E 906A -DF6F 906B -DF70 906C -D4E2 906D -D5DA 906E -DF71 906F -DF72 9070 -DF73 9071 -DF74 9072 -DF75 9073 -E5E0 9074 -D7F1 9075 -DF76 9076 -DF77 9077 -DF78 9078 -DF79 9079 -DF7A 907A -DF7B 907B -DF7C 907C -E5E1 907D -DF7D 907E -B1DC 907F -D1FB 9080 -DF7E 9081 -E5E2 9082 -E5E4 9083 -DF80 9084 -DF81 9085 -DF82 9086 -DF83 9087 -E5E3 9088 -DF84 9089 -DF85 908A -E5E5 908B -DF86 908C -DF87 908D -DF88 908E -DF89 908F -DF8A 9090 -D2D8 9091 -DF8B 9092 -B5CB 9093 -DF8C 9094 -E7DF 9095 -DF8D 9096 -DAF5 9097 -DF8E 9098 -DAF8 9099 -DF8F 909A -DAF6 909B -DF90 909C -DAF7 909D -DF91 909E -DF92 909F -DF93 90A0 -DAFA 90A1 -D0CF 90A2 -C4C7 90A3 -DF94 90A4 -DF95 90A5 -B0EE 90A6 -DF96 90A7 -DF97 90A8 -DF98 90A9 -D0B0 90AA -DF99 90AB -DAF9 90AC -DF9A 90AD -D3CA 90AE -BAAA 90AF -DBA2 90B0 -C7F1 90B1 -DF9B 90B2 -DAFC 90B3 -DAFB 90B4 -C9DB 90B5 -DAFD 90B6 -DF9C 90B7 -DBA1 90B8 -D7DE 90B9 -DAFE 90BA -C1DA 90BB -DF9D 90BC -DF9E 90BD -DBA5 90BE -DF9F 90BF -DFA0 90C0 -D3F4 90C1 -E040 90C2 -E041 90C3 -DBA7 90C4 -DBA4 90C5 -E042 90C6 -DBA8 90C7 -E043 90C8 -E044 90C9 -BDBC 90CA -E045 90CB -E046 90CC -E047 90CD -C0C9 90CE -DBA3 90CF -DBA6 90D0 -D6A3 90D1 -E048 90D2 -DBA9 90D3 -E049 90D4 -E04A 90D5 -E04B 90D6 -DBAD 90D7 -E04C 90D8 -E04D 90D9 -E04E 90DA -DBAE 90DB -DBAC 90DC -BAC2 90DD -E04F 90DE -E050 90DF -E051 90E0 -BFA4 90E1 -DBAB 90E2 -E052 90E3 -E053 90E4 -E054 90E5 -DBAA 90E6 -D4C7 90E7 -B2BF 90E8 -E055 90E9 -E056 90EA -DBAF 90EB -E057 90EC -B9F9 90ED -E058 90EE -DBB0 90EF -E059 90F0 -E05A 90F1 -E05B 90F2 -E05C 90F3 -B3BB 90F4 -E05D 90F5 -E05E 90F6 -E05F 90F7 -B5A6 90F8 -E060 90F9 -E061 90FA -E062 90FB -E063 90FC -B6BC 90FD -DBB1 90FE -E064 90FF -E065 9100 -E066 9101 -B6F5 9102 -E067 9103 -DBB2 9104 -E068 9105 -E069 9106 -E06A 9107 -E06B 9108 -E06C 9109 -E06D 910A -E06E 910B -E06F 910C -E070 910D -E071 910E -E072 910F -E073 9110 -E074 9111 -E075 9112 -E076 9113 -E077 9114 -E078 9115 -E079 9116 -E07A 9117 -E07B 9118 -B1C9 9119 -E07C 911A -E07D 911B -E07E 911C -E080 911D -DBB4 911E -E081 911F -E082 9120 -E083 9121 -DBB3 9122 -DBB5 9123 -E084 9124 -E085 9125 -E086 9126 -E087 9127 -E088 9128 -E089 9129 -E08A 912A -E08B 912B -E08C 912C -E08D 912D -E08E 912E -DBB7 912F -E08F 9130 -DBB6 9131 -E090 9132 -E091 9133 -E092 9134 -E093 9135 -E094 9136 -E095 9137 -E096 9138 -DBB8 9139 -E097 913A -E098 913B -E099 913C -E09A 913D -E09B 913E -E09C 913F -E09D 9140 -E09E 9141 -E09F 9142 -DBB9 9143 -E0A0 9144 -E140 9145 -DBBA 9146 -E141 9147 -E142 9148 -D3CF 9149 -F4FA 914A -C7F5 914B -D7C3 914C -C5E4 914D -F4FC 914E -F4FD 914F -F4FB 9150 -E143 9151 -BEC6 9152 -E144 9153 -E145 9154 -E146 9155 -E147 9156 -D0EF 9157 -E148 9158 -E149 9159 -B7D3 915A -E14A 915B -E14B 915C -D4CD 915D -CCAA 915E -E14C 915F -E14D 9160 -F5A2 9161 -F5A1 9162 -BAA8 9163 -F4FE 9164 -CBD6 9165 -E14E 9166 -E14F 9167 -E150 9168 -F5A4 9169 -C0D2 916A -E151 916B -B3EA 916C -E152 916D -CDAA 916E -F5A5 916F -F5A3 9170 -BDB4 9171 -F5A8 9172 -E153 9173 -F5A9 9174 -BDCD 9175 -C3B8 9176 -BFE1 9177 -CBE1 9178 -F5AA 9179 -E154 917A -E155 917B -E156 917C -F5A6 917D -F5A7 917E -C4F0 917F -E157 9180 -E158 9181 -E159 9182 -E15A 9183 -E15B 9184 -F5AC 9185 -E15C 9186 -B4BC 9187 -E15D 9188 -D7ED 9189 -E15E 918A -B4D7 918B -F5AB 918C -F5AE 918D -E15F 918E -E160 918F -F5AD 9190 -F5AF 9191 -D0D1 9192 -E161 9193 -E162 9194 -E163 9195 -E164 9196 -E165 9197 -E166 9198 -E167 9199 -C3D1 919A -C8A9 919B -E168 919C -E169 919D -E16A 919E -E16B 919F -E16C 91A0 -E16D 91A1 -F5B0 91A2 -F5B1 91A3 -E16E 91A4 -E16F 91A5 -E170 91A6 -E171 91A7 -E172 91A8 -E173 91A9 -F5B2 91AA -E174 91AB -E175 91AC -F5B3 91AD -F5B4 91AE -F5B5 91AF -E176 91B0 -E177 91B1 -E178 91B2 -E179 91B3 -F5B7 91B4 -F5B6 91B5 -E17A 91B6 -E17B 91B7 -E17C 91B8 -E17D 91B9 -F5B8 91BA -E17E 91BB -E180 91BC -E181 91BD -E182 91BE -E183 91BF -E184 91C0 -E185 91C1 -E186 91C2 -E187 91C3 -E188 91C4 -E189 91C5 -E18A 91C6 -B2C9 91C7 -E18B 91C8 -D3D4 91C9 -CACD 91CA -E18C 91CB -C0EF 91CC -D6D8 91CD -D2B0 91CE -C1BF 91CF -E18D 91D0 -BDF0 91D1 -E18E 91D2 -E18F 91D3 -E190 91D4 -E191 91D5 -E192 91D6 -E193 91D7 -E194 91D8 -E195 91D9 -E196 91DA -E197 91DB -B8AA 91DC -E198 91DD -E199 91DE -E19A 91DF -E19B 91E0 -E19C 91E1 -E19D 91E2 -E19E 91E3 -E19F 91E4 -E1A0 91E5 -E240 91E6 -E241 91E7 -E242 91E8 -E243 91E9 -E244 91EA -E245 91EB -E246 91EC -E247 91ED -E248 91EE -E249 91EF -E24A 91F0 -E24B 91F1 -E24C 91F2 -E24D 91F3 -E24E 91F4 -E24F 91F5 -E250 91F6 -E251 91F7 -E252 91F8 -E253 91F9 -E254 91FA -E255 91FB -E256 91FC -E257 91FD -E258 91FE -E259 91FF -E25A 9200 -E25B 9201 -E25C 9202 -E25D 9203 -E25E 9204 -E25F 9205 -E260 9206 -E261 9207 -E262 9208 -E263 9209 -E264 920A -E265 920B -E266 920C -E267 920D -E268 920E -E269 920F -E26A 9210 -E26B 9211 -E26C 9212 -E26D 9213 -E26E 9214 -E26F 9215 -E270 9216 -E271 9217 -E272 9218 -E273 9219 -E274 921A -E275 921B -E276 921C -E277 921D -E278 921E -E279 921F -E27A 9220 -E27B 9221 -E27C 9222 -E27D 9223 -E27E 9224 -E280 9225 -E281 9226 -E282 9227 -E283 9228 -E284 9229 -E285 922A -E286 922B -E287 922C -E288 922D -E289 922E -E28A 922F -E28B 9230 -E28C 9231 -E28D 9232 -E28E 9233 -E28F 9234 -E290 9235 -E291 9236 -E292 9237 -E293 9238 -E294 9239 -E295 923A -E296 923B -E297 923C -E298 923D -E299 923E -E29A 923F -E29B 9240 -E29C 9241 -E29D 9242 -E29E 9243 -E29F 9244 -E2A0 9245 -E340 9246 -E341 9247 -E342 9248 -E343 9249 -E344 924A -E345 924B -E346 924C -E347 924D -E348 924E -E349 924F -E34A 9250 -E34B 9251 -E34C 9252 -E34D 9253 -E34E 9254 -E34F 9255 -E350 9256 -E351 9257 -E352 9258 -E353 9259 -E354 925A -E355 925B -E356 925C -E357 925D -E358 925E -E359 925F -E35A 9260 -E35B 9261 -E35C 9262 -E35D 9263 -E35E 9264 -E35F 9265 -E360 9266 -E361 9267 -E362 9268 -E363 9269 -E364 926A -E365 926B -E366 926C -E367 926D -E368 926E -E369 926F -E36A 9270 -E36B 9271 -E36C 9272 -E36D 9273 -BCF8 9274 -E36E 9275 -E36F 9276 -E370 9277 -E371 9278 -E372 9279 -E373 927A -E374 927B -E375 927C -E376 927D -E377 927E -E378 927F -E379 9280 -E37A 9281 -E37B 9282 -E37C 9283 -E37D 9284 -E37E 9285 -E380 9286 -E381 9287 -E382 9288 -E383 9289 -E384 928A -E385 928B -E386 928C -E387 928D -F6C6 928E -E388 928F -E389 9290 -E38A 9291 -E38B 9292 -E38C 9293 -E38D 9294 -E38E 9295 -E38F 9296 -E390 9297 -E391 9298 -E392 9299 -E393 929A -E394 929B -E395 929C -E396 929D -E397 929E -E398 929F -E399 92A0 -E39A 92A1 -E39B 92A2 -E39C 92A3 -E39D 92A4 -E39E 92A5 -E39F 92A6 -E3A0 92A7 -E440 92A8 -E441 92A9 -E442 92AA -E443 92AB -E444 92AC -E445 92AD -F6C7 92AE -E446 92AF -E447 92B0 -E448 92B1 -E449 92B2 -E44A 92B3 -E44B 92B4 -E44C 92B5 -E44D 92B6 -E44E 92B7 -E44F 92B8 -E450 92B9 -E451 92BA -E452 92BB -E453 92BC -E454 92BD -E455 92BE -E456 92BF -E457 92C0 -E458 92C1 -E459 92C2 -E45A 92C3 -E45B 92C4 -E45C 92C5 -E45D 92C6 -E45E 92C7 -F6C8 92C8 -E45F 92C9 -E460 92CA -E461 92CB -E462 92CC -E463 92CD -E464 92CE -E465 92CF -E466 92D0 -E467 92D1 -E468 92D2 -E469 92D3 -E46A 92D4 -E46B 92D5 -E46C 92D6 -E46D 92D7 -E46E 92D8 -E46F 92D9 -E470 92DA -E471 92DB -E472 92DC -E473 92DD -E474 92DE -E475 92DF -E476 92E0 -E477 92E1 -E478 92E2 -E479 92E3 -E47A 92E4 -E47B 92E5 -E47C 92E6 -E47D 92E7 -E47E 92E8 -E480 92E9 -E481 92EA -E482 92EB -E483 92EC -E484 92ED -E485 92EE -E486 92EF -E487 92F0 -E488 92F1 -E489 92F2 -E48A 92F3 -E48B 92F4 -E48C 92F5 -E48D 92F6 -E48E 92F7 -E48F 92F8 -E490 92F9 -E491 92FA -E492 92FB -E493 92FC -E494 92FD -E495 92FE -E496 92FF -E497 9300 -E498 9301 -E499 9302 -E49A 9303 -E49B 9304 -E49C 9305 -E49D 9306 -E49E 9307 -E49F 9308 -E4A0 9309 -E540 930A -E541 930B -E542 930C -E543 930D -E544 930E -E545 930F -E546 9310 -E547 9311 -E548 9312 -E549 9313 -E54A 9314 -E54B 9315 -E54C 9316 -E54D 9317 -E54E 9318 -E54F 9319 -E550 931A -E551 931B -E552 931C -E553 931D -E554 931E -E555 931F -E556 9320 -E557 9321 -E558 9322 -E559 9323 -E55A 9324 -E55B 9325 -E55C 9326 -E55D 9327 -E55E 9328 -E55F 9329 -E560 932A -E561 932B -E562 932C -E563 932D -E564 932E -E565 932F -E566 9330 -E567 9331 -E568 9332 -E569 9333 -E56A 9334 -E56B 9335 -E56C 9336 -E56D 9337 -E56E 9338 -E56F 9339 -E570 933A -E571 933B -E572 933C -E573 933D -F6C9 933E -E574 933F -E575 9340 -E576 9341 -E577 9342 -E578 9343 -E579 9344 -E57A 9345 -E57B 9346 -E57C 9347 -E57D 9348 -E57E 9349 -E580 934A -E581 934B -E582 934C -E583 934D -E584 934E -E585 934F -E586 9350 -E587 9351 -E588 9352 -E589 9353 -E58A 9354 -E58B 9355 -E58C 9356 -E58D 9357 -E58E 9358 -E58F 9359 -E590 935A -E591 935B -E592 935C -E593 935D -E594 935E -E595 935F -E596 9360 -E597 9361 -E598 9362 -E599 9363 -E59A 9364 -E59B 9365 -E59C 9366 -E59D 9367 -E59E 9368 -E59F 9369 -F6CA 936A -E5A0 936B -E640 936C -E641 936D -E642 936E -E643 936F -E644 9370 -E645 9371 -E646 9372 -E647 9373 -E648 9374 -E649 9375 -E64A 9376 -E64B 9377 -E64C 9378 -E64D 9379 -E64E 937A -E64F 937B -E650 937C -E651 937D -E652 937E -E653 937F -E654 9380 -E655 9381 -E656 9382 -E657 9383 -E658 9384 -E659 9385 -E65A 9386 -E65B 9387 -E65C 9388 -E65D 9389 -E65E 938A -E65F 938B -E660 938C -E661 938D -E662 938E -F6CC 938F -E663 9390 -E664 9391 -E665 9392 -E666 9393 -E667 9394 -E668 9395 -E669 9396 -E66A 9397 -E66B 9398 -E66C 9399 -E66D 939A -E66E 939B -E66F 939C -E670 939D -E671 939E -E672 939F -E673 93A0 -E674 93A1 -E675 93A2 -E676 93A3 -E677 93A4 -E678 93A5 -E679 93A6 -E67A 93A7 -E67B 93A8 -E67C 93A9 -E67D 93AA -E67E 93AB -E680 93AC -E681 93AD -E682 93AE -E683 93AF -E684 93B0 -E685 93B1 -E686 93B2 -E687 93B3 -E688 93B4 -E689 93B5 -E68A 93B6 -E68B 93B7 -E68C 93B8 -E68D 93B9 -E68E 93BA -E68F 93BB -E690 93BC -E691 93BD -E692 93BE -E693 93BF -E694 93C0 -E695 93C1 -E696 93C2 -E697 93C3 -E698 93C4 -E699 93C5 -E69A 93C6 -E69B 93C7 -E69C 93C8 -E69D 93C9 -F6CB 93CA -E69E 93CB -E69F 93CC -E6A0 93CD -E740 93CE -E741 93CF -E742 93D0 -E743 93D1 -E744 93D2 -E745 93D3 -E746 93D4 -E747 93D5 -F7E9 93D6 -E748 93D7 -E749 93D8 -E74A 93D9 -E74B 93DA -E74C 93DB -E74D 93DC -E74E 93DD -E74F 93DE -E750 93DF -E751 93E0 -E752 93E1 -E753 93E2 -E754 93E3 -E755 93E4 -E756 93E5 -E757 93E6 -E758 93E7 -E759 93E8 -E75A 93E9 -E75B 93EA -E75C 93EB -E75D 93EC -E75E 93ED -E75F 93EE -E760 93EF -E761 93F0 -E762 93F1 -E763 93F2 -E764 93F3 -E765 93F4 -E766 93F5 -E767 93F6 -E768 93F7 -E769 93F8 -E76A 93F9 -E76B 93FA -E76C 93FB -E76D 93FC -E76E 93FD -E76F 93FE -E770 93FF -E771 9400 -E772 9401 -E773 9402 -E774 9403 -E775 9404 -E776 9405 -E777 9406 -E778 9407 -E779 9408 -E77A 9409 -E77B 940A -E77C 940B -E77D 940C -E77E 940D -E780 940E -E781 940F -E782 9410 -E783 9411 -E784 9412 -E785 9413 -E786 9414 -E787 9415 -E788 9416 -E789 9417 -E78A 9418 -E78B 9419 -E78C 941A -E78D 941B -E78E 941C -E78F 941D -E790 941E -E791 941F -E792 9420 -E793 9421 -E794 9422 -E795 9423 -E796 9424 -E797 9425 -E798 9426 -E799 9427 -E79A 9428 -E79B 9429 -E79C 942A -E79D 942B -E79E 942C -E79F 942D -E7A0 942E -E840 942F -E841 9430 -E842 9431 -E843 9432 -E844 9433 -E845 9434 -E846 9435 -E847 9436 -E848 9437 -E849 9438 -E84A 9439 -E84B 943A -E84C 943B -E84D 943C -E84E 943D -F6CD 943E -E84F 943F -E850 9440 -E851 9441 -E852 9442 -E853 9443 -E854 9444 -E855 9445 -E856 9446 -E857 9447 -E858 9448 -E859 9449 -E85A 944A -E85B 944B -E85C 944C -E85D 944D -E85E 944E -E85F 944F -E860 9450 -E861 9451 -E862 9452 -E863 9453 -E864 9454 -E865 9455 -E866 9456 -E867 9457 -E868 9458 -E869 9459 -E86A 945A -E86B 945B -E86C 945C -E86D 945D -E86E 945E -E86F 945F -E870 9460 -E871 9461 -E872 9462 -E873 9463 -E874 9464 -E875 9465 -E876 9466 -E877 9467 -E878 9468 -E879 9469 -E87A 946A -F6CE 946B -E87B 946C -E87C 946D -E87D 946E -E87E 946F -E880 9470 -E881 9471 -E882 9472 -E883 9473 -E884 9474 -E885 9475 -E886 9476 -E887 9477 -E888 9478 -E889 9479 -E88A 947A -E88B 947B -E88C 947C -E88D 947D -E88E 947E -E88F 947F -E890 9480 -E891 9481 -E892 9482 -E893 9483 -E894 9484 -EEC4 9485 -EEC5 9486 -EEC6 9487 -D5EB 9488 -B6A4 9489 -EEC8 948A -EEC7 948B -EEC9 948C -EECA 948D -C7A5 948E -EECB 948F -EECC 9490 -E895 9491 -B7B0 9492 -B5F6 9493 -EECD 9494 -EECF 9495 -E896 9496 -EECE 9497 -E897 9498 -B8C6 9499 -EED0 949A -EED1 949B -EED2 949C -B6DB 949D -B3AE 949E -D6D3 949F -C4C6 94A0 -B1B5 94A1 -B8D6 94A2 -EED3 94A3 -EED4 94A4 -D4BF 94A5 -C7D5 94A6 -BEFB 94A7 -CED9 94A8 -B9B3 94A9 -EED6 94AA -EED5 94AB -EED8 94AC -EED7 94AD -C5A5 94AE -EED9 94AF -EEDA 94B0 -C7AE 94B1 -EEDB 94B2 -C7AF 94B3 -EEDC 94B4 -B2A7 94B5 -EEDD 94B6 -EEDE 94B7 -EEDF 94B8 -EEE0 94B9 -EEE1 94BA -D7EA 94BB -EEE2 94BC -EEE3 94BD -BCD8 94BE -EEE4 94BF -D3CB 94C0 -CCFA 94C1 -B2AC 94C2 -C1E5 94C3 -EEE5 94C4 -C7A6 94C5 -C3AD 94C6 -E898 94C7 -EEE6 94C8 -EEE7 94C9 -EEE8 94CA -EEE9 94CB -EEEA 94CC -EEEB 94CD -EEEC 94CE -E899 94CF -EEED 94D0 -EEEE 94D1 -EEEF 94D2 -E89A 94D3 -E89B 94D4 -EEF0 94D5 -EEF1 94D6 -EEF2 94D7 -EEF4 94D8 -EEF3 94D9 -E89C 94DA -EEF5 94DB -CDAD 94DC -C2C1 94DD -EEF6 94DE -EEF7 94DF -EEF8 94E0 -D5A1 94E1 -EEF9 94E2 -CFB3 94E3 -EEFA 94E4 -EEFB 94E5 -E89D 94E6 -EEFC 94E7 -EEFD 94E8 -EFA1 94E9 -EEFE 94EA -EFA2 94EB -B8F5 94EC -C3FA 94ED -EFA3 94EE -EFA4 94EF -BDC2 94F0 -D2BF 94F1 -B2F9 94F2 -EFA5 94F3 -EFA6 94F4 -EFA7 94F5 -D2F8 94F6 -EFA8 94F7 -D6FD 94F8 -EFA9 94F9 -C6CC 94FA -E89E 94FB -EFAA 94FC -EFAB 94FD -C1B4 94FE -EFAC 94FF -CFFA 9500 -CBF8 9501 -EFAE 9502 -EFAD 9503 -B3FA 9504 -B9F8 9505 -EFAF 9506 -EFB0 9507 -D0E2 9508 -EFB1 9509 -EFB2 950A -B7E6 950B -D0BF 950C -EFB3 950D -EFB4 950E -EFB5 950F -C8F1 9510 -CCE0 9511 -EFB6 9512 -EFB7 9513 -EFB8 9514 -EFB9 9515 -EFBA 9516 -D5E0 9517 -EFBB 9518 -B4ED 9519 -C3AA 951A -EFBC 951B -E89F 951C -EFBD 951D -EFBE 951E -EFBF 951F -E8A0 9520 -CEFD 9521 -EFC0 9522 -C2E0 9523 -B4B8 9524 -D7B6 9525 -BDF5 9526 -E940 9527 -CFC7 9528 -EFC3 9529 -EFC1 952A -EFC2 952B -EFC4 952C -B6A7 952D -BCFC 952E -BEE2 952F -C3CC 9530 -EFC5 9531 -EFC6 9532 -E941 9533 -EFC7 9534 -EFCF 9535 -EFC8 9536 -EFC9 9537 -EFCA 9538 -C7C2 9539 -EFF1 953A -B6CD 953B -EFCB 953C -E942 953D -EFCC 953E -EFCD 953F -B6C6 9540 -C3BE 9541 -EFCE 9542 -E943 9543 -EFD0 9544 -EFD1 9545 -EFD2 9546 -D5F2 9547 -E944 9548 -EFD3 9549 -C4F7 954A -E945 954B -EFD4 954C -C4F8 954D -EFD5 954E -EFD6 954F -B8E4 9550 -B0F7 9551 -EFD7 9552 -EFD8 9553 -EFD9 9554 -E946 9555 -EFDA 9556 -EFDB 9557 -EFDC 9558 -EFDD 9559 -E947 955A -EFDE 955B -BEB5 955C -EFE1 955D -EFDF 955E -EFE0 955F -E948 9560 -EFE2 9561 -EFE3 9562 -C1CD 9563 -EFE4 9564 -EFE5 9565 -EFE6 9566 -EFE7 9567 -EFE8 9568 -EFE9 9569 -EFEA 956A -EFEB 956B -EFEC 956C -C0D8 956D -E949 956E -EFED 956F -C1AD 9570 -EFEE 9571 -EFEF 9572 -EFF0 9573 -E94A 9574 -E94B 9575 -CFE2 9576 -E94C 9577 -E94D 9578 -E94E 9579 -E94F 957A -E950 957B -E951 957C -E952 957D -E953 957E -B3A4 957F -E954 9580 -E955 9581 -E956 9582 -E957 9583 -E958 9584 -E959 9585 -E95A 9586 -E95B 9587 -E95C 9588 -E95D 9589 -E95E 958A -E95F 958B -E960 958C -E961 958D -E962 958E -E963 958F -E964 9590 -E965 9591 -E966 9592 -E967 9593 -E968 9594 -E969 9595 -E96A 9596 -E96B 9597 -E96C 9598 -E96D 9599 -E96E 959A -E96F 959B -E970 959C -E971 959D -E972 959E -E973 959F -E974 95A0 -E975 95A1 -E976 95A2 -E977 95A3 -E978 95A4 -E979 95A5 -E97A 95A6 -E97B 95A7 -E97C 95A8 -E97D 95A9 -E97E 95AA -E980 95AB -E981 95AC -E982 95AD -E983 95AE -E984 95AF -E985 95B0 -E986 95B1 -E987 95B2 -E988 95B3 -E989 95B4 -E98A 95B5 -E98B 95B6 -E98C 95B7 -E98D 95B8 -E98E 95B9 -E98F 95BA -E990 95BB -E991 95BC -E992 95BD -E993 95BE -E994 95BF -E995 95C0 -E996 95C1 -E997 95C2 -E998 95C3 -E999 95C4 -E99A 95C5 -E99B 95C6 -E99C 95C7 -E99D 95C8 -E99E 95C9 -E99F 95CA -E9A0 95CB -EA40 95CC -EA41 95CD -EA42 95CE -EA43 95CF -EA44 95D0 -EA45 95D1 -EA46 95D2 -EA47 95D3 -EA48 95D4 -EA49 95D5 -EA4A 95D6 -EA4B 95D7 -EA4C 95D8 -EA4D 95D9 -EA4E 95DA -EA4F 95DB -EA50 95DC -EA51 95DD -EA52 95DE -EA53 95DF -EA54 95E0 -EA55 95E1 -EA56 95E2 -EA57 95E3 -EA58 95E4 -EA59 95E5 -EA5A 95E6 -EA5B 95E7 -C3C5 95E8 -E3C5 95E9 -C9C1 95EA -E3C6 95EB -EA5C 95EC -B1D5 95ED -CECA 95EE -B4B3 95EF -C8F2 95F0 -E3C7 95F1 -CFD0 95F2 -E3C8 95F3 -BCE4 95F4 -E3C9 95F5 -E3CA 95F6 -C3C6 95F7 -D5A2 95F8 -C4D6 95F9 -B9EB 95FA -CEC5 95FB -E3CB 95FC -C3F6 95FD -E3CC 95FE -EA5D 95FF -B7A7 9600 -B8F3 9601 -BAD2 9602 -E3CD 9603 -E3CE 9604 -D4C4 9605 -E3CF 9606 -EA5E 9607 -E3D0 9608 -D1CB 9609 -E3D1 960A -E3D2 960B -E3D3 960C -E3D4 960D -D1D6 960E -E3D5 960F -B2FB 9610 -C0BB 9611 -E3D6 9612 -EA5F 9613 -C0AB 9614 -E3D7 9615 -E3D8 9616 -E3D9 9617 -EA60 9618 -E3DA 9619 -E3DB 961A -EA61 961B -B8B7 961C -DAE2 961D -EA62 961E -B6D3 961F -EA63 9620 -DAE4 9621 -DAE3 9622 -EA64 9623 -EA65 9624 -EA66 9625 -EA67 9626 -EA68 9627 -EA69 9628 -EA6A 9629 -DAE6 962A -EA6B 962B -EA6C 962C -EA6D 962D -C8EE 962E -EA6E 962F -EA6F 9630 -DAE5 9631 -B7C0 9632 -D1F4 9633 -D2F5 9634 -D5F3 9635 -BDD7 9636 -EA70 9637 -EA71 9638 -EA72 9639 -EA73 963A -D7E8 963B -DAE8 963C -DAE7 963D -EA74 963E -B0A2 963F -CDD3 9640 -EA75 9641 -DAE9 9642 -EA76 9643 -B8BD 9644 -BCCA 9645 -C2BD 9646 -C2A4 9647 -B3C2 9648 -DAEA 9649 -EA77 964A -C2AA 964B -C4B0 964C -BDB5 964D -EA78 964E -EA79 964F -CFDE 9650 -EA7A 9651 -EA7B 9652 -EA7C 9653 -DAEB 9654 -C9C2 9655 -EA7D 9656 -EA7E 9657 -EA80 9658 -EA81 9659 -EA82 965A -B1DD 965B -EA83 965C -EA84 965D -EA85 965E -DAEC 965F -EA86 9660 -B6B8 9661 -D4BA 9662 -EA87 9663 -B3FD 9664 -EA88 9665 -EA89 9666 -DAED 9667 -D4C9 9668 -CFD5 9669 -C5E3 966A -EA8A 966B -DAEE 966C -EA8B 966D -EA8C 966E -EA8D 966F -EA8E 9670 -EA8F 9671 -DAEF 9672 -EA90 9673 -DAF0 9674 -C1EA 9675 -CCD5 9676 -CFDD 9677 -EA91 9678 -EA92 9679 -EA93 967A -EA94 967B -EA95 967C -EA96 967D -EA97 967E -EA98 967F -EA99 9680 -EA9A 9681 -EA9B 9682 -EA9C 9683 -EA9D 9684 -D3E7 9685 -C2A1 9686 -EA9E 9687 -DAF1 9688 -EA9F 9689 -EAA0 968A -CBE5 968B -EB40 968C -DAF2 968D -EB41 968E -CBE6 968F -D2FE 9690 -EB42 9691 -EB43 9692 -EB44 9693 -B8F4 9694 -EB45 9695 -EB46 9696 -DAF3 9697 -B0AF 9698 -CFB6 9699 -EB47 969A -EB48 969B -D5CF 969C -EB49 969D -EB4A 969E -EB4B 969F -EB4C 96A0 -EB4D 96A1 -EB4E 96A2 -EB4F 96A3 -EB50 96A4 -EB51 96A5 -EB52 96A6 -CBED 96A7 -EB53 96A8 -EB54 96A9 -EB55 96AA -EB56 96AB -EB57 96AC -EB58 96AD -EB59 96AE -EB5A 96AF -DAF4 96B0 -EB5B 96B1 -EB5C 96B2 -E3C4 96B3 -EB5D 96B4 -EB5E 96B5 -C1A5 96B6 -EB5F 96B7 -EB60 96B8 -F6BF 96B9 -EB61 96BA -EB62 96BB -F6C0 96BC -F6C1 96BD -C4D1 96BE -EB63 96BF -C8B8 96C0 -D1E3 96C1 -EB64 96C2 -EB65 96C3 -D0DB 96C4 -D1C5 96C5 -BCAF 96C6 -B9CD 96C7 -EB66 96C8 -EFF4 96C9 -EB67 96CA -EB68 96CB -B4C6 96CC -D3BA 96CD -F6C2 96CE -B3FB 96CF -EB69 96D0 -EB6A 96D1 -F6C3 96D2 -EB6B 96D3 -EB6C 96D4 -B5F1 96D5 -EB6D 96D6 -EB6E 96D7 -EB6F 96D8 -EB70 96D9 -EB71 96DA -EB72 96DB -EB73 96DC -EB74 96DD -EB75 96DE -EB76 96DF -F6C5 96E0 -EB77 96E1 -EB78 96E2 -EB79 96E3 -EB7A 96E4 -EB7B 96E5 -EB7C 96E6 -EB7D 96E7 -D3EA 96E8 -F6A7 96E9 -D1A9 96EA -EB7E 96EB -EB80 96EC -EB81 96ED -EB82 96EE -F6A9 96EF -EB83 96F0 -EB84 96F1 -EB85 96F2 -F6A8 96F3 -EB86 96F4 -EB87 96F5 -C1E3 96F6 -C0D7 96F7 -EB88 96F8 -B1A2 96F9 -EB89 96FA -EB8A 96FB -EB8B 96FC -EB8C 96FD -CEED 96FE -EB8D 96FF -D0E8 9700 -F6AB 9701 -EB8E 9702 -EB8F 9703 -CFF6 9704 -EB90 9705 -F6AA 9706 -D5F0 9707 -F6AC 9708 -C3B9 9709 -EB91 970A -EB92 970B -EB93 970C -BBF4 970D -F6AE 970E -F6AD 970F -EB94 9710 -EB95 9711 -EB96 9712 -C4DE 9713 -EB97 9714 -EB98 9715 -C1D8 9716 -EB99 9717 -EB9A 9718 -EB9B 9719 -EB9C 971A -EB9D 971B -CBAA 971C -EB9E 971D -CFBC 971E -EB9F 971F -EBA0 9720 -EC40 9721 -EC41 9722 -EC42 9723 -EC43 9724 -EC44 9725 -EC45 9726 -EC46 9727 -EC47 9728 -EC48 9729 -F6AF 972A -EC49 972B -EC4A 972C -F6B0 972D -EC4B 972E -EC4C 972F -F6B1 9730 -EC4D 9731 -C2B6 9732 -EC4E 9733 -EC4F 9734 -EC50 9735 -EC51 9736 -EC52 9737 -B0D4 9738 -C5F9 9739 -EC53 973A -EC54 973B -EC55 973C -EC56 973D -F6B2 973E -EC57 973F -EC58 9740 -EC59 9741 -EC5A 9742 -EC5B 9743 -EC5C 9744 -EC5D 9745 -EC5E 9746 -EC5F 9747 -EC60 9748 -EC61 9749 -EC62 974A -EC63 974B -EC64 974C -EC65 974D -EC66 974E -EC67 974F -EC68 9750 -EC69 9751 -C7E0 9752 -F6A6 9753 -EC6A 9754 -EC6B 9755 -BEB8 9756 -EC6C 9757 -EC6D 9758 -BEB2 9759 -EC6E 975A -B5E5 975B -EC6F 975C -EC70 975D -B7C7 975E -EC71 975F -BFBF 9760 -C3D2 9761 -C3E6 9762 -EC72 9763 -EC73 9764 -D8CC 9765 -EC74 9766 -EC75 9767 -EC76 9768 -B8EF 9769 -EC77 976A -EC78 976B -EC79 976C -EC7A 976D -EC7B 976E -EC7C 976F -EC7D 9770 -EC7E 9771 -EC80 9772 -BDF9 9773 -D1A5 9774 -EC81 9775 -B0D0 9776 -EC82 9777 -EC83 9778 -EC84 9779 -EC85 977A -EC86 977B -F7B0 977C -EC87 977D -EC88 977E -EC89 977F -EC8A 9780 -EC8B 9781 -EC8C 9782 -EC8D 9783 -EC8E 9784 -F7B1 9785 -EC8F 9786 -EC90 9787 -EC91 9788 -EC92 9789 -EC93 978A -D0AC 978B -EC94 978C -B0B0 978D -EC95 978E -EC96 978F -EC97 9790 -F7B2 9791 -F7B3 9792 -EC98 9793 -F7B4 9794 -EC99 9795 -EC9A 9796 -EC9B 9797 -C7CA 9798 -EC9C 9799 -EC9D 979A -EC9E 979B -EC9F 979C -ECA0 979D -ED40 979E -ED41 979F -BECF 97A0 -ED42 97A1 -ED43 97A2 -F7B7 97A3 -ED44 97A4 -ED45 97A5 -ED46 97A6 -ED47 97A7 -ED48 97A8 -ED49 97A9 -ED4A 97AA -F7B6 97AB -ED4B 97AC -B1DE 97AD -ED4C 97AE -F7B5 97AF -ED4D 97B0 -ED4E 97B1 -F7B8 97B2 -ED4F 97B3 -F7B9 97B4 -ED50 97B5 -ED51 97B6 -ED52 97B7 -ED53 97B8 -ED54 97B9 -ED55 97BA -ED56 97BB -ED57 97BC -ED58 97BD -ED59 97BE -ED5A 97BF -ED5B 97C0 -ED5C 97C1 -ED5D 97C2 -ED5E 97C3 -ED5F 97C4 -ED60 97C5 -ED61 97C6 -ED62 97C7 -ED63 97C8 -ED64 97C9 -ED65 97CA -ED66 97CB -ED67 97CC -ED68 97CD -ED69 97CE -ED6A 97CF -ED6B 97D0 -ED6C 97D1 -ED6D 97D2 -ED6E 97D3 -ED6F 97D4 -ED70 97D5 -ED71 97D6 -ED72 97D7 -ED73 97D8 -ED74 97D9 -ED75 97DA -ED76 97DB -ED77 97DC -ED78 97DD -ED79 97DE -ED7A 97DF -ED7B 97E0 -ED7C 97E1 -ED7D 97E2 -ED7E 97E3 -ED80 97E4 -ED81 97E5 -CEA4 97E6 -C8CD 97E7 -ED82 97E8 -BAAB 97E9 -E8B8 97EA -E8B9 97EB -E8BA 97EC -BEC2 97ED -ED83 97EE -ED84 97EF -ED85 97F0 -ED86 97F1 -ED87 97F2 -D2F4 97F3 -ED88 97F4 -D4CF 97F5 -C9D8 97F6 -ED89 97F7 -ED8A 97F8 -ED8B 97F9 -ED8C 97FA -ED8D 97FB -ED8E 97FC -ED8F 97FD -ED90 97FE -ED91 97FF -ED92 9800 -ED93 9801 -ED94 9802 -ED95 9803 -ED96 9804 -ED97 9805 -ED98 9806 -ED99 9807 -ED9A 9808 -ED9B 9809 -ED9C 980A -ED9D 980B -ED9E 980C -ED9F 980D -EDA0 980E -EE40 980F -EE41 9810 -EE42 9811 -EE43 9812 -EE44 9813 -EE45 9814 -EE46 9815 -EE47 9816 -EE48 9817 -EE49 9818 -EE4A 9819 -EE4B 981A -EE4C 981B -EE4D 981C -EE4E 981D -EE4F 981E -EE50 981F -EE51 9820 -EE52 9821 -EE53 9822 -EE54 9823 -EE55 9824 -EE56 9825 -EE57 9826 -EE58 9827 -EE59 9828 -EE5A 9829 -EE5B 982A -EE5C 982B -EE5D 982C -EE5E 982D -EE5F 982E -EE60 982F -EE61 9830 -EE62 9831 -EE63 9832 -EE64 9833 -EE65 9834 -EE66 9835 -EE67 9836 -EE68 9837 -EE69 9838 -EE6A 9839 -EE6B 983A -EE6C 983B -EE6D 983C -EE6E 983D -EE6F 983E -EE70 983F -EE71 9840 -EE72 9841 -EE73 9842 -EE74 9843 -EE75 9844 -EE76 9845 -EE77 9846 -EE78 9847 -EE79 9848 -EE7A 9849 -EE7B 984A -EE7C 984B -EE7D 984C -EE7E 984D -EE80 984E -EE81 984F -EE82 9850 -EE83 9851 -EE84 9852 -EE85 9853 -EE86 9854 -EE87 9855 -EE88 9856 -EE89 9857 -EE8A 9858 -EE8B 9859 -EE8C 985A -EE8D 985B -EE8E 985C -EE8F 985D -EE90 985E -EE91 985F -EE92 9860 -EE93 9861 -EE94 9862 -EE95 9863 -EE96 9864 -EE97 9865 -EE98 9866 -EE99 9867 -EE9A 9868 -EE9B 9869 -EE9C 986A -EE9D 986B -EE9E 986C -EE9F 986D -EEA0 986E -EF40 986F -EF41 9870 -EF42 9871 -EF43 9872 -EF44 9873 -EF45 9874 -D2B3 9875 -B6A5 9876 -C7EA 9877 -F1FC 9878 -CFEE 9879 -CBB3 987A -D0EB 987B -E7EF 987C -CDE7 987D -B9CB 987E -B6D9 987F -F1FD 9880 -B0E4 9881 -CBCC 9882 -F1FE 9883 -D4A4 9884 -C2AD 9885 -C1EC 9886 -C6C4 9887 -BEB1 9888 -F2A1 9889 -BCD5 988A -EF46 988B -F2A2 988C -F2A3 988D -EF47 988E -F2A4 988F -D2C3 9890 -C6B5 9891 -EF48 9892 -CDC7 9893 -F2A5 9894 -EF49 9895 -D3B1 9896 -BFC5 9897 -CCE2 9898 -EF4A 9899 -F2A6 989A -F2A7 989B -D1D5 989C -B6EE 989D -F2A8 989E -F2A9 989F -B5DF 98A0 -F2AA 98A1 -F2AB 98A2 -EF4B 98A3 -B2FC 98A4 -F2AC 98A5 -F2AD 98A6 -C8A7 98A7 -EF4C 98A8 -EF4D 98A9 -EF4E 98AA -EF4F 98AB -EF50 98AC -EF51 98AD -EF52 98AE -EF53 98AF -EF54 98B0 -EF55 98B1 -EF56 98B2 -EF57 98B3 -EF58 98B4 -EF59 98B5 -EF5A 98B6 -EF5B 98B7 -EF5C 98B8 -EF5D 98B9 -EF5E 98BA -EF5F 98BB -EF60 98BC -EF61 98BD -EF62 98BE -EF63 98BF -EF64 98C0 -EF65 98C1 -EF66 98C2 -EF67 98C3 -EF68 98C4 -EF69 98C5 -EF6A 98C6 -EF6B 98C7 -EF6C 98C8 -EF6D 98C9 -EF6E 98CA -EF6F 98CB -EF70 98CC -EF71 98CD -B7E7 98CE -EF72 98CF -EF73 98D0 -ECA9 98D1 -ECAA 98D2 -ECAB 98D3 -EF74 98D4 -ECAC 98D5 -EF75 98D6 -EF76 98D7 -C6AE 98D8 -ECAD 98D9 -ECAE 98DA -EF77 98DB -EF78 98DC -EF79 98DD -B7C9 98DE -CAB3 98DF -EF7A 98E0 -EF7B 98E1 -EF7C 98E2 -EF7D 98E3 -EF7E 98E4 -EF80 98E5 -EF81 98E6 -E2B8 98E7 -F7CF 98E8 -EF82 98E9 -EF83 98EA -EF84 98EB -EF85 98EC -EF86 98ED -EF87 98EE -EF88 98EF -EF89 98F0 -EF8A 98F1 -EF8B 98F2 -EF8C 98F3 -EF8D 98F4 -EF8E 98F5 -EF8F 98F6 -EF90 98F7 -EF91 98F8 -EF92 98F9 -EF93 98FA -EF94 98FB -EF95 98FC -EF96 98FD -EF97 98FE -EF98 98FF -EF99 9900 -EF9A 9901 -EF9B 9902 -EF9C 9903 -EF9D 9904 -EF9E 9905 -EF9F 9906 -EFA0 9907 -F040 9908 -F041 9909 -F042 990A -F043 990B -F044 990C -F7D0 990D -F045 990E -F046 990F -B2CD 9910 -F047 9911 -F048 9912 -F049 9913 -F04A 9914 -F04B 9915 -F04C 9916 -F04D 9917 -F04E 9918 -F04F 9919 -F050 991A -F051 991B -F052 991C -F053 991D -F054 991E -F055 991F -F056 9920 -F057 9921 -F058 9922 -F059 9923 -F05A 9924 -F05B 9925 -F05C 9926 -F05D 9927 -F05E 9928 -F05F 9929 -F060 992A -F061 992B -F062 992C -F063 992D -F7D1 992E -F064 992F -F065 9930 -F066 9931 -F067 9932 -F068 9933 -F069 9934 -F06A 9935 -F06B 9936 -F06C 9937 -F06D 9938 -F06E 9939 -F06F 993A -F070 993B -F071 993C -F072 993D -F073 993E -F074 993F -F075 9940 -F076 9941 -F077 9942 -F078 9943 -F079 9944 -F07A 9945 -F07B 9946 -F07C 9947 -F07D 9948 -F07E 9949 -F080 994A -F081 994B -F082 994C -F083 994D -F084 994E -F085 994F -F086 9950 -F087 9951 -F088 9952 -F089 9953 -F7D3 9954 -F7D2 9955 -F08A 9956 -F08B 9957 -F08C 9958 -F08D 9959 -F08E 995A -F08F 995B -F090 995C -F091 995D -F092 995E -F093 995F -F094 9960 -F095 9961 -F096 9962 -E2BB 9963 -F097 9964 -BCA2 9965 -F098 9966 -E2BC 9967 -E2BD 9968 -E2BE 9969 -E2BF 996A -E2C0 996B -E2C1 996C -B7B9 996D -D2FB 996E -BDA4 996F -CACE 9970 -B1A5 9971 -CBC7 9972 -F099 9973 -E2C2 9974 -B6FC 9975 -C8C4 9976 -E2C3 9977 -F09A 9978 -F09B 9979 -BDC8 997A -F09C 997B -B1FD 997C -E2C4 997D -F09D 997E -B6F6 997F -E2C5 9980 -C4D9 9981 -F09E 9982 -F09F 9983 -E2C6 9984 -CFDA 9985 -B9DD 9986 -E2C7 9987 -C0A1 9988 -F0A0 9989 -E2C8 998A -B2F6 998B -F140 998C -E2C9 998D -F141 998E -C1F3 998F -E2CA 9990 -E2CB 9991 -C2F8 9992 -E2CC 9993 -E2CD 9994 -E2CE 9995 -CAD7 9996 -D8B8 9997 -D9E5 9998 -CFE3 9999 -F142 999A -F143 999B -F144 999C -F145 999D -F146 999E -F147 999F -F148 99A0 -F149 99A1 -F14A 99A2 -F14B 99A3 -F14C 99A4 -F0A5 99A5 -F14D 99A6 -F14E 99A7 -DCB0 99A8 -F14F 99A9 -F150 99AA -F151 99AB -F152 99AC -F153 99AD -F154 99AE -F155 99AF -F156 99B0 -F157 99B1 -F158 99B2 -F159 99B3 -F15A 99B4 -F15B 99B5 -F15C 99B6 -F15D 99B7 -F15E 99B8 -F15F 99B9 -F160 99BA -F161 99BB -F162 99BC -F163 99BD -F164 99BE -F165 99BF -F166 99C0 -F167 99C1 -F168 99C2 -F169 99C3 -F16A 99C4 -F16B 99C5 -F16C 99C6 -F16D 99C7 -F16E 99C8 -F16F 99C9 -F170 99CA -F171 99CB -F172 99CC -F173 99CD -F174 99CE -F175 99CF -F176 99D0 -F177 99D1 -F178 99D2 -F179 99D3 -F17A 99D4 -F17B 99D5 -F17C 99D6 -F17D 99D7 -F17E 99D8 -F180 99D9 -F181 99DA -F182 99DB -F183 99DC -F184 99DD -F185 99DE -F186 99DF -F187 99E0 -F188 99E1 -F189 99E2 -F18A 99E3 -F18B 99E4 -F18C 99E5 -F18D 99E6 -F18E 99E7 -F18F 99E8 -F190 99E9 -F191 99EA -F192 99EB -F193 99EC -F194 99ED -F195 99EE -F196 99EF -F197 99F0 -F198 99F1 -F199 99F2 -F19A 99F3 -F19B 99F4 -F19C 99F5 -F19D 99F6 -F19E 99F7 -F19F 99F8 -F1A0 99F9 -F240 99FA -F241 99FB -F242 99FC -F243 99FD -F244 99FE -F245 99FF -F246 9A00 -F247 9A01 -F248 9A02 -F249 9A03 -F24A 9A04 -F24B 9A05 -F24C 9A06 -F24D 9A07 -F24E 9A08 -F24F 9A09 -F250 9A0A -F251 9A0B -F252 9A0C -F253 9A0D -F254 9A0E -F255 9A0F -F256 9A10 -F257 9A11 -F258 9A12 -F259 9A13 -F25A 9A14 -F25B 9A15 -F25C 9A16 -F25D 9A17 -F25E 9A18 -F25F 9A19 -F260 9A1A -F261 9A1B -F262 9A1C -F263 9A1D -F264 9A1E -F265 9A1F -F266 9A20 -F267 9A21 -F268 9A22 -F269 9A23 -F26A 9A24 -F26B 9A25 -F26C 9A26 -F26D 9A27 -F26E 9A28 -F26F 9A29 -F270 9A2A -F271 9A2B -F272 9A2C -F273 9A2D -F274 9A2E -F275 9A2F -F276 9A30 -F277 9A31 -F278 9A32 -F279 9A33 -F27A 9A34 -F27B 9A35 -F27C 9A36 -F27D 9A37 -F27E 9A38 -F280 9A39 -F281 9A3A -F282 9A3B -F283 9A3C -F284 9A3D -F285 9A3E -F286 9A3F -F287 9A40 -F288 9A41 -F289 9A42 -F28A 9A43 -F28B 9A44 -F28C 9A45 -F28D 9A46 -F28E 9A47 -F28F 9A48 -F290 9A49 -F291 9A4A -F292 9A4B -F293 9A4C -F294 9A4D -F295 9A4E -F296 9A4F -F297 9A50 -F298 9A51 -F299 9A52 -F29A 9A53 -F29B 9A54 -F29C 9A55 -F29D 9A56 -F29E 9A57 -F29F 9A58 -F2A0 9A59 -F340 9A5A -F341 9A5B -F342 9A5C -F343 9A5D -F344 9A5E -F345 9A5F -F346 9A60 -F347 9A61 -F348 9A62 -F349 9A63 -F34A 9A64 -F34B 9A65 -F34C 9A66 -F34D 9A67 -F34E 9A68 -F34F 9A69 -F350 9A6A -F351 9A6B -C2ED 9A6C -D4A6 9A6D -CDD4 9A6E -D1B1 9A6F -B3DB 9A70 -C7FD 9A71 -F352 9A72 -B2B5 9A73 -C2BF 9A74 -E6E0 9A75 -CABB 9A76 -E6E1 9A77 -E6E2 9A78 -BED4 9A79 -E6E3 9A7A -D7A4 9A7B -CDD5 9A7C -E6E5 9A7D -BCDD 9A7E -E6E4 9A7F -E6E6 9A80 -E6E7 9A81 -C2EE 9A82 -F353 9A83 -BDBE 9A84 -E6E8 9A85 -C2E6 9A86 -BAA7 9A87 -E6E9 9A88 -F354 9A89 -E6EA 9A8A -B3D2 9A8B -D1E9 9A8C -F355 9A8D -F356 9A8E -BFA5 9A8F -E6EB 9A90 -C6EF 9A91 -E6EC 9A92 -E6ED 9A93 -F357 9A94 -F358 9A95 -E6EE 9A96 -C6AD 9A97 -E6EF 9A98 -F359 9A99 -C9A7 9A9A -E6F0 9A9B -E6F1 9A9C -E6F2 9A9D -E5B9 9A9E -E6F3 9A9F -E6F4 9AA0 -C2E2 9AA1 -E6F5 9AA2 -E6F6 9AA3 -D6E8 9AA4 -E6F7 9AA5 -F35A 9AA6 -E6F8 9AA7 -B9C7 9AA8 -F35B 9AA9 -F35C 9AAA -F35D 9AAB -F35E 9AAC -F35F 9AAD -F360 9AAE -F361 9AAF -F7BB 9AB0 -F7BA 9AB1 -F362 9AB2 -F363 9AB3 -F364 9AB4 -F365 9AB5 -F7BE 9AB6 -F7BC 9AB7 -BAA1 9AB8 -F366 9AB9 -F7BF 9ABA -F367 9ABB -F7C0 9ABC -F368 9ABD -F369 9ABE -F36A 9ABF -F7C2 9AC0 -F7C1 9AC1 -F7C4 9AC2 -F36B 9AC3 -F36C 9AC4 -F7C3 9AC5 -F36D 9AC6 -F36E 9AC7 -F36F 9AC8 -F370 9AC9 -F371 9ACA -F7C5 9ACB -F7C6 9ACC -F372 9ACD -F373 9ACE -F374 9ACF -F375 9AD0 -F7C7 9AD1 -F376 9AD2 -CBE8 9AD3 -F377 9AD4 -F378 9AD5 -F379 9AD6 -F37A 9AD7 -B8DF 9AD8 -F37B 9AD9 -F37C 9ADA -F37D 9ADB -F37E 9ADC -F380 9ADD -F381 9ADE -F7D4 9ADF -F382 9AE0 -F7D5 9AE1 -F383 9AE2 -F384 9AE3 -F385 9AE4 -F386 9AE5 -F7D6 9AE6 -F387 9AE7 -F388 9AE8 -F389 9AE9 -F38A 9AEA -F7D8 9AEB -F38B 9AEC -F7DA 9AED -F38C 9AEE -F7D7 9AEF -F38D 9AF0 -F38E 9AF1 -F38F 9AF2 -F390 9AF3 -F391 9AF4 -F392 9AF5 -F393 9AF6 -F394 9AF7 -F395 9AF8 -F7DB 9AF9 -F396 9AFA -F7D9 9AFB -F397 9AFC -F398 9AFD -F399 9AFE -F39A 9AFF -F39B 9B00 -F39C 9B01 -F39D 9B02 -D7D7 9B03 -F39E 9B04 -F39F 9B05 -F3A0 9B06 -F440 9B07 -F7DC 9B08 -F441 9B09 -F442 9B0A -F443 9B0B -F444 9B0C -F445 9B0D -F446 9B0E -F7DD 9B0F -F447 9B10 -F448 9B11 -F449 9B12 -F7DE 9B13 -F44A 9B14 -F44B 9B15 -F44C 9B16 -F44D 9B17 -F44E 9B18 -F44F 9B19 -F450 9B1A -F451 9B1B -F452 9B1C -F453 9B1D -F454 9B1E -F7DF 9B1F -F455 9B20 -F456 9B21 -F457 9B22 -F7E0 9B23 -F458 9B24 -F459 9B25 -F45A 9B26 -F45B 9B27 -F45C 9B28 -F45D 9B29 -F45E 9B2A -F45F 9B2B -F460 9B2C -F461 9B2D -F462 9B2E -DBCB 9B2F -F463 9B30 -F464 9B31 -D8AA 9B32 -F465 9B33 -F466 9B34 -F467 9B35 -F468 9B36 -F469 9B37 -F46A 9B38 -F46B 9B39 -F46C 9B3A -E5F7 9B3B -B9ED 9B3C -F46D 9B3D -F46E 9B3E -F46F 9B3F -F470 9B40 -BFFD 9B41 -BBEA 9B42 -F7C9 9B43 -C6C7 9B44 -F7C8 9B45 -F471 9B46 -F7CA 9B47 -F7CC 9B48 -F7CB 9B49 -F472 9B4A -F473 9B4B -F474 9B4C -F7CD 9B4D -F475 9B4E -CEBA 9B4F -F476 9B50 -F7CE 9B51 -F477 9B52 -F478 9B53 -C4A7 9B54 -F479 9B55 -F47A 9B56 -F47B 9B57 -F47C 9B58 -F47D 9B59 -F47E 9B5A -F480 9B5B -F481 9B5C -F482 9B5D -F483 9B5E -F484 9B5F -F485 9B60 -F486 9B61 -F487 9B62 -F488 9B63 -F489 9B64 -F48A 9B65 -F48B 9B66 -F48C 9B67 -F48D 9B68 -F48E 9B69 -F48F 9B6A -F490 9B6B -F491 9B6C -F492 9B6D -F493 9B6E -F494 9B6F -F495 9B70 -F496 9B71 -F497 9B72 -F498 9B73 -F499 9B74 -F49A 9B75 -F49B 9B76 -F49C 9B77 -F49D 9B78 -F49E 9B79 -F49F 9B7A -F4A0 9B7B -F540 9B7C -F541 9B7D -F542 9B7E -F543 9B7F -F544 9B80 -F545 9B81 -F546 9B82 -F547 9B83 -F548 9B84 -F549 9B85 -F54A 9B86 -F54B 9B87 -F54C 9B88 -F54D 9B89 -F54E 9B8A -F54F 9B8B -F550 9B8C -F551 9B8D -F552 9B8E -F553 9B8F -F554 9B90 -F555 9B91 -F556 9B92 -F557 9B93 -F558 9B94 -F559 9B95 -F55A 9B96 -F55B 9B97 -F55C 9B98 -F55D 9B99 -F55E 9B9A -F55F 9B9B -F560 9B9C -F561 9B9D -F562 9B9E -F563 9B9F -F564 9BA0 -F565 9BA1 -F566 9BA2 -F567 9BA3 -F568 9BA4 -F569 9BA5 -F56A 9BA6 -F56B 9BA7 -F56C 9BA8 -F56D 9BA9 -F56E 9BAA -F56F 9BAB -F570 9BAC -F571 9BAD -F572 9BAE -F573 9BAF -F574 9BB0 -F575 9BB1 -F576 9BB2 -F577 9BB3 -F578 9BB4 -F579 9BB5 -F57A 9BB6 -F57B 9BB7 -F57C 9BB8 -F57D 9BB9 -F57E 9BBA -F580 9BBB -F581 9BBC -F582 9BBD -F583 9BBE -F584 9BBF -F585 9BC0 -F586 9BC1 -F587 9BC2 -F588 9BC3 -F589 9BC4 -F58A 9BC5 -F58B 9BC6 -F58C 9BC7 -F58D 9BC8 -F58E 9BC9 -F58F 9BCA -F590 9BCB -F591 9BCC -F592 9BCD -F593 9BCE -F594 9BCF -F595 9BD0 -F596 9BD1 -F597 9BD2 -F598 9BD3 -F599 9BD4 -F59A 9BD5 -F59B 9BD6 -F59C 9BD7 -F59D 9BD8 -F59E 9BD9 -F59F 9BDA -F5A0 9BDB -F640 9BDC -F641 9BDD -F642 9BDE -F643 9BDF -F644 9BE0 -F645 9BE1 -F646 9BE2 -F647 9BE3 -F648 9BE4 -F649 9BE5 -F64A 9BE6 -F64B 9BE7 -F64C 9BE8 -F64D 9BE9 -F64E 9BEA -F64F 9BEB -F650 9BEC -F651 9BED -F652 9BEE -F653 9BEF -F654 9BF0 -F655 9BF1 -F656 9BF2 -F657 9BF3 -F658 9BF4 -F659 9BF5 -F65A 9BF6 -F65B 9BF7 -F65C 9BF8 -F65D 9BF9 -F65E 9BFA -F65F 9BFB -F660 9BFC -F661 9BFD -F662 9BFE -F663 9BFF -F664 9C00 -F665 9C01 -F666 9C02 -F667 9C03 -F668 9C04 -F669 9C05 -F66A 9C06 -F66B 9C07 -F66C 9C08 -F66D 9C09 -F66E 9C0A -F66F 9C0B -F670 9C0C -F671 9C0D -F672 9C0E -F673 9C0F -F674 9C10 -F675 9C11 -F676 9C12 -F677 9C13 -F678 9C14 -F679 9C15 -F67A 9C16 -F67B 9C17 -F67C 9C18 -F67D 9C19 -F67E 9C1A -F680 9C1B -F681 9C1C -F682 9C1D -F683 9C1E -F684 9C1F -F685 9C20 -F686 9C21 -F687 9C22 -F688 9C23 -F689 9C24 -F68A 9C25 -F68B 9C26 -F68C 9C27 -F68D 9C28 -F68E 9C29 -F68F 9C2A -F690 9C2B -F691 9C2C -F692 9C2D -F693 9C2E -F694 9C2F -F695 9C30 -F696 9C31 -F697 9C32 -F698 9C33 -F699 9C34 -F69A 9C35 -F69B 9C36 -F69C 9C37 -F69D 9C38 -F69E 9C39 -F69F 9C3A -F6A0 9C3B -F740 9C3C -F741 9C3D -F742 9C3E -F743 9C3F -F744 9C40 -F745 9C41 -F746 9C42 -F747 9C43 -F748 9C44 -F749 9C45 -F74A 9C46 -F74B 9C47 -F74C 9C48 -F74D 9C49 -F74E 9C4A -F74F 9C4B -F750 9C4C -F751 9C4D -F752 9C4E -F753 9C4F -F754 9C50 -F755 9C51 -F756 9C52 -F757 9C53 -F758 9C54 -F759 9C55 -F75A 9C56 -F75B 9C57 -F75C 9C58 -F75D 9C59 -F75E 9C5A -F75F 9C5B -F760 9C5C -F761 9C5D -F762 9C5E -F763 9C5F -F764 9C60 -F765 9C61 -F766 9C62 -F767 9C63 -F768 9C64 -F769 9C65 -F76A 9C66 -F76B 9C67 -F76C 9C68 -F76D 9C69 -F76E 9C6A -F76F 9C6B -F770 9C6C -F771 9C6D -F772 9C6E -F773 9C6F -F774 9C70 -F775 9C71 -F776 9C72 -F777 9C73 -F778 9C74 -F779 9C75 -F77A 9C76 -F77B 9C77 -F77C 9C78 -F77D 9C79 -F77E 9C7A -F780 9C7B -D3E3 9C7C -F781 9C7D -F782 9C7E -F6CF 9C7F -F783 9C80 -C2B3 9C81 -F6D0 9C82 -F784 9C83 -F785 9C84 -F6D1 9C85 -F6D2 9C86 -F6D3 9C87 -F6D4 9C88 -F786 9C89 -F787 9C8A -F6D6 9C8B -F788 9C8C -B1AB 9C8D -F6D7 9C8E -F789 9C8F -F6D8 9C90 -F6D9 9C91 -F6DA 9C92 -F78A 9C93 -F6DB 9C94 -F6DC 9C95 -F78B 9C96 -F78C 9C97 -F78D 9C98 -F78E 9C99 -F6DD 9C9A -F6DE 9C9B -CFCA 9C9C -F78F 9C9D -F6DF 9C9E -F6E0 9C9F -F6E1 9CA0 -F6E2 9CA1 -F6E3 9CA2 -F6E4 9CA3 -C0F0 9CA4 -F6E5 9CA5 -F6E6 9CA6 -F6E7 9CA7 -F6E8 9CA8 -F6E9 9CA9 -F790 9CAA -F6EA 9CAB -F791 9CAC -F6EB 9CAD -F6EC 9CAE -F792 9CAF -F6ED 9CB0 -F6EE 9CB1 -F6EF 9CB2 -F6F0 9CB3 -F6F1 9CB4 -F6F2 9CB5 -F6F3 9CB6 -F6F4 9CB7 -BEA8 9CB8 -F793 9CB9 -F6F5 9CBA -F6F6 9CBB -F6F7 9CBC -F6F8 9CBD -F794 9CBE -F795 9CBF -F796 9CC0 -F797 9CC1 -F798 9CC2 -C8FA 9CC3 -F6F9 9CC4 -F6FA 9CC5 -F6FB 9CC6 -F6FC 9CC7 -F799 9CC8 -F79A 9CC9 -F6FD 9CCA -F6FE 9CCB -F7A1 9CCC -F7A2 9CCD -F7A3 9CCE -F7A4 9CCF -F7A5 9CD0 -F79B 9CD1 -F79C 9CD2 -F7A6 9CD3 -F7A7 9CD4 -F7A8 9CD5 -B1EE 9CD6 -F7A9 9CD7 -F7AA 9CD8 -F7AB 9CD9 -F79D 9CDA -F79E 9CDB -F7AC 9CDC -F7AD 9CDD -C1DB 9CDE -F7AE 9CDF -F79F 9CE0 -F7A0 9CE1 -F7AF 9CE2 -F840 9CE3 -F841 9CE4 -F842 9CE5 -F843 9CE6 -F844 9CE7 -F845 9CE8 -F846 9CE9 -F847 9CEA -F848 9CEB -F849 9CEC -F84A 9CED -F84B 9CEE -F84C 9CEF -F84D 9CF0 -F84E 9CF1 -F84F 9CF2 -F850 9CF3 -F851 9CF4 -F852 9CF5 -F853 9CF6 -F854 9CF7 -F855 9CF8 -F856 9CF9 -F857 9CFA -F858 9CFB -F859 9CFC -F85A 9CFD -F85B 9CFE -F85C 9CFF -F85D 9D00 -F85E 9D01 -F85F 9D02 -F860 9D03 -F861 9D04 -F862 9D05 -F863 9D06 -F864 9D07 -F865 9D08 -F866 9D09 -F867 9D0A -F868 9D0B -F869 9D0C -F86A 9D0D -F86B 9D0E -F86C 9D0F -F86D 9D10 -F86E 9D11 -F86F 9D12 -F870 9D13 -F871 9D14 -F872 9D15 -F873 9D16 -F874 9D17 -F875 9D18 -F876 9D19 -F877 9D1A -F878 9D1B -F879 9D1C -F87A 9D1D -F87B 9D1E -F87C 9D1F -F87D 9D20 -F87E 9D21 -F880 9D22 -F881 9D23 -F882 9D24 -F883 9D25 -F884 9D26 -F885 9D27 -F886 9D28 -F887 9D29 -F888 9D2A -F889 9D2B -F88A 9D2C -F88B 9D2D -F88C 9D2E -F88D 9D2F -F88E 9D30 -F88F 9D31 -F890 9D32 -F891 9D33 -F892 9D34 -F893 9D35 -F894 9D36 -F895 9D37 -F896 9D38 -F897 9D39 -F898 9D3A -F899 9D3B -F89A 9D3C -F89B 9D3D -F89C 9D3E -F89D 9D3F -F89E 9D40 -F89F 9D41 -F8A0 9D42 -F940 9D43 -F941 9D44 -F942 9D45 -F943 9D46 -F944 9D47 -F945 9D48 -F946 9D49 -F947 9D4A -F948 9D4B -F949 9D4C -F94A 9D4D -F94B 9D4E -F94C 9D4F -F94D 9D50 -F94E 9D51 -F94F 9D52 -F950 9D53 -F951 9D54 -F952 9D55 -F953 9D56 -F954 9D57 -F955 9D58 -F956 9D59 -F957 9D5A -F958 9D5B -F959 9D5C -F95A 9D5D -F95B 9D5E -F95C 9D5F -F95D 9D60 -F95E 9D61 -F95F 9D62 -F960 9D63 -F961 9D64 -F962 9D65 -F963 9D66 -F964 9D67 -F965 9D68 -F966 9D69 -F967 9D6A -F968 9D6B -F969 9D6C -F96A 9D6D -F96B 9D6E -F96C 9D6F -F96D 9D70 -F96E 9D71 -F96F 9D72 -F970 9D73 -F971 9D74 -F972 9D75 -F973 9D76 -F974 9D77 -F975 9D78 -F976 9D79 -F977 9D7A -F978 9D7B -F979 9D7C -F97A 9D7D -F97B 9D7E -F97C 9D7F -F97D 9D80 -F97E 9D81 -F980 9D82 -F981 9D83 -F982 9D84 -F983 9D85 -F984 9D86 -F985 9D87 -F986 9D88 -F987 9D89 -F988 9D8A -F989 9D8B -F98A 9D8C -F98B 9D8D -F98C 9D8E -F98D 9D8F -F98E 9D90 -F98F 9D91 -F990 9D92 -F991 9D93 -F992 9D94 -F993 9D95 -F994 9D96 -F995 9D97 -F996 9D98 -F997 9D99 -F998 9D9A -F999 9D9B -F99A 9D9C -F99B 9D9D -F99C 9D9E -F99D 9D9F -F99E 9DA0 -F99F 9DA1 -F9A0 9DA2 -FA40 9DA3 -FA41 9DA4 -FA42 9DA5 -FA43 9DA6 -FA44 9DA7 -FA45 9DA8 -FA46 9DA9 -FA47 9DAA -FA48 9DAB -FA49 9DAC -FA4A 9DAD -FA4B 9DAE -FA4C 9DAF -FA4D 9DB0 -FA4E 9DB1 -FA4F 9DB2 -FA50 9DB3 -FA51 9DB4 -FA52 9DB5 -FA53 9DB6 -FA54 9DB7 -FA55 9DB8 -FA56 9DB9 -FA57 9DBA -FA58 9DBB -FA59 9DBC -FA5A 9DBD -FA5B 9DBE -FA5C 9DBF -FA5D 9DC0 -FA5E 9DC1 -FA5F 9DC2 -FA60 9DC3 -FA61 9DC4 -FA62 9DC5 -FA63 9DC6 -FA64 9DC7 -FA65 9DC8 -FA66 9DC9 -FA67 9DCA -FA68 9DCB -FA69 9DCC -FA6A 9DCD -FA6B 9DCE -FA6C 9DCF -FA6D 9DD0 -FA6E 9DD1 -FA6F 9DD2 -FA70 9DD3 -FA71 9DD4 -FA72 9DD5 -FA73 9DD6 -FA74 9DD7 -FA75 9DD8 -FA76 9DD9 -FA77 9DDA -FA78 9DDB -FA79 9DDC -FA7A 9DDD -FA7B 9DDE -FA7C 9DDF -FA7D 9DE0 -FA7E 9DE1 -FA80 9DE2 -FA81 9DE3 -FA82 9DE4 -FA83 9DE5 -FA84 9DE6 -FA85 9DE7 -FA86 9DE8 -FA87 9DE9 -FA88 9DEA -FA89 9DEB -FA8A 9DEC -FA8B 9DED -FA8C 9DEE -FA8D 9DEF -FA8E 9DF0 -FA8F 9DF1 -FA90 9DF2 -FA91 9DF3 -FA92 9DF4 -FA93 9DF5 -FA94 9DF6 -FA95 9DF7 -FA96 9DF8 -FA97 9DF9 -FA98 9DFA -FA99 9DFB -FA9A 9DFC -FA9B 9DFD -FA9C 9DFE -FA9D 9DFF -FA9E 9E00 -FA9F 9E01 -FAA0 9E02 -FB40 9E03 -FB41 9E04 -FB42 9E05 -FB43 9E06 -FB44 9E07 -FB45 9E08 -FB46 9E09 -FB47 9E0A -FB48 9E0B -FB49 9E0C -FB4A 9E0D -FB4B 9E0E -FB4C 9E0F -FB4D 9E10 -FB4E 9E11 -FB4F 9E12 -FB50 9E13 -FB51 9E14 -FB52 9E15 -FB53 9E16 -FB54 9E17 -FB55 9E18 -FB56 9E19 -FB57 9E1A -FB58 9E1B -FB59 9E1C -FB5A 9E1D -FB5B 9E1E -C4F1 9E1F -F0AF 9E20 -BCA6 9E21 -F0B0 9E22 -C3F9 9E23 -FB5C 9E24 -C5B8 9E25 -D1BB 9E26 -FB5D 9E27 -F0B1 9E28 -F0B2 9E29 -F0B3 9E2A -F0B4 9E2B -F0B5 9E2C -D1BC 9E2D -FB5E 9E2E -D1EC 9E2F -FB5F 9E30 -F0B7 9E31 -F0B6 9E32 -D4A7 9E33 -FB60 9E34 -CDD2 9E35 -F0B8 9E36 -F0BA 9E37 -F0B9 9E38 -F0BB 9E39 -F0BC 9E3A -FB61 9E3B -FB62 9E3C -B8EB 9E3D -F0BD 9E3E -BAE8 9E3F -FB63 9E40 -F0BE 9E41 -F0BF 9E42 -BEE9 9E43 -F0C0 9E44 -B6EC 9E45 -F0C1 9E46 -F0C2 9E47 -F0C3 9E48 -F0C4 9E49 -C8B5 9E4A -F0C5 9E4B -F0C6 9E4C -FB64 9E4D -F0C7 9E4E -C5F4 9E4F -FB65 9E50 -F0C8 9E51 -FB66 9E52 -FB67 9E53 -FB68 9E54 -F0C9 9E55 -FB69 9E56 -F0CA 9E57 -F7BD 9E58 -FB6A 9E59 -F0CB 9E5A -F0CC 9E5B -F0CD 9E5C -FB6B 9E5D -F0CE 9E5E -FB6C 9E5F -FB6D 9E60 -FB6E 9E61 -FB6F 9E62 -F0CF 9E63 -BAD7 9E64 -FB70 9E65 -F0D0 9E66 -F0D1 9E67 -F0D2 9E68 -F0D3 9E69 -F0D4 9E6A -F0D5 9E6B -F0D6 9E6C -F0D8 9E6D -FB71 9E6E -FB72 9E6F -D3A5 9E70 -F0D7 9E71 -FB73 9E72 -F0D9 9E73 -FB74 9E74 -FB75 9E75 -FB76 9E76 -FB77 9E77 -FB78 9E78 -FB79 9E79 -FB7A 9E7A -FB7B 9E7B -FB7C 9E7C -FB7D 9E7D -F5BA 9E7E -C2B9 9E7F -FB7E 9E80 -FB80 9E81 -F7E4 9E82 -FB81 9E83 -FB82 9E84 -FB83 9E85 -FB84 9E86 -F7E5 9E87 -F7E6 9E88 -FB85 9E89 -FB86 9E8A -F7E7 9E8B -FB87 9E8C -FB88 9E8D -FB89 9E8E -FB8A 9E8F -FB8B 9E90 -FB8C 9E91 -F7E8 9E92 -C2B4 9E93 -FB8D 9E94 -FB8E 9E95 -FB8F 9E96 -FB90 9E97 -FB91 9E98 -FB92 9E99 -FB93 9E9A -FB94 9E9B -FB95 9E9C -F7EA 9E9D -FB96 9E9E -F7EB 9E9F -FB97 9EA0 -FB98 9EA1 -FB99 9EA2 -FB9A 9EA3 -FB9B 9EA4 -FB9C 9EA5 -C2F3 9EA6 -FB9D 9EA7 -FB9E 9EA8 -FB9F 9EA9 -FBA0 9EAA -FC40 9EAB -FC41 9EAC -FC42 9EAD -FC43 9EAE -FC44 9EAF -FC45 9EB0 -FC46 9EB1 -FC47 9EB2 -FC48 9EB3 -F4F0 9EB4 -FC49 9EB5 -FC4A 9EB6 -FC4B 9EB7 -F4EF 9EB8 -FC4C 9EB9 -FC4D 9EBA -C2E9 9EBB -FC4E 9EBC -F7E1 9EBD -F7E2 9EBE -FC4F 9EBF -FC50 9EC0 -FC51 9EC1 -FC52 9EC2 -FC53 9EC3 -BBC6 9EC4 -FC54 9EC5 -FC55 9EC6 -FC56 9EC7 -FC57 9EC8 -D9E4 9EC9 -FC58 9ECA -FC59 9ECB -FC5A 9ECC -CAF2 9ECD -C0E8 9ECE -F0A4 9ECF -FC5B 9ED0 -BADA 9ED1 -FC5C 9ED2 -FC5D 9ED3 -C7AD 9ED4 -FC5E 9ED5 -FC5F 9ED6 -FC60 9ED7 -C4AC 9ED8 -FC61 9ED9 -FC62 9EDA -F7EC 9EDB -F7ED 9EDC -F7EE 9EDD -FC63 9EDE -F7F0 9EDF -F7EF 9EE0 -FC64 9EE1 -F7F1 9EE2 -FC65 9EE3 -FC66 9EE4 -F7F4 9EE5 -FC67 9EE6 -F7F3 9EE7 -FC68 9EE8 -F7F2 9EE9 -F7F5 9EEA -FC69 9EEB -FC6A 9EEC -FC6B 9EED -FC6C 9EEE -F7F6 9EEF -FC6D 9EF0 -FC6E 9EF1 -FC6F 9EF2 -FC70 9EF3 -FC71 9EF4 -FC72 9EF5 -FC73 9EF6 -FC74 9EF7 -FC75 9EF8 -EDE9 9EF9 -FC76 9EFA -EDEA 9EFB -EDEB 9EFC -FC77 9EFD -F6BC 9EFE -FC78 9EFF -FC79 9F00 -FC7A 9F01 -FC7B 9F02 -FC7C 9F03 -FC7D 9F04 -FC7E 9F05 -FC80 9F06 -FC81 9F07 -FC82 9F08 -FC83 9F09 -FC84 9F0A -F6BD 9F0B -FC85 9F0C -F6BE 9F0D -B6A6 9F0E -FC86 9F0F -D8BE 9F10 -FC87 9F11 -FC88 9F12 -B9C4 9F13 -FC89 9F14 -FC8A 9F15 -FC8B 9F16 -D8BB 9F17 -FC8C 9F18 -DCB1 9F19 -FC8D 9F1A -FC8E 9F1B -FC8F 9F1C -FC90 9F1D -FC91 9F1E -FC92 9F1F -CAF3 9F20 -FC93 9F21 -F7F7 9F22 -FC94 9F23 -FC95 9F24 -FC96 9F25 -FC97 9F26 -FC98 9F27 -FC99 9F28 -FC9A 9F29 -FC9B 9F2A -FC9C 9F2B -F7F8 9F2C -FC9D 9F2D -FC9E 9F2E -F7F9 9F2F -FC9F 9F30 -FCA0 9F31 -FD40 9F32 -FD41 9F33 -FD42 9F34 -FD43 9F35 -FD44 9F36 -F7FB 9F37 -FD45 9F38 -F7FA 9F39 -FD46 9F3A -B1C7 9F3B -FD47 9F3C -F7FC 9F3D -F7FD 9F3E -FD48 9F3F -FD49 9F40 -FD4A 9F41 -FD4B 9F42 -FD4C 9F43 -F7FE 9F44 -FD4D 9F45 -FD4E 9F46 -FD4F 9F47 -FD50 9F48 -FD51 9F49 -FD52 9F4A -FD53 9F4B -FD54 9F4C -FD55 9F4D -FD56 9F4E -FD57 9F4F -C6EB 9F50 -ECB4 9F51 -FD58 9F52 -FD59 9F53 -FD5A 9F54 -FD5B 9F55 -FD5C 9F56 -FD5D 9F57 -FD5E 9F58 -FD5F 9F59 -FD60 9F5A -FD61 9F5B -FD62 9F5C -FD63 9F5D -FD64 9F5E -FD65 9F5F -FD66 9F60 -FD67 9F61 -FD68 9F62 -FD69 9F63 -FD6A 9F64 -FD6B 9F65 -FD6C 9F66 -FD6D 9F67 -FD6E 9F68 -FD6F 9F69 -FD70 9F6A -FD71 9F6B -FD72 9F6C -FD73 9F6D -FD74 9F6E -FD75 9F6F -FD76 9F70 -FD77 9F71 -FD78 9F72 -FD79 9F73 -FD7A 9F74 -FD7B 9F75 -FD7C 9F76 -FD7D 9F77 -FD7E 9F78 -FD80 9F79 -FD81 9F7A -FD82 9F7B -FD83 9F7C -FD84 9F7D -FD85 9F7E -B3DD 9F7F -F6B3 9F80 -FD86 9F81 -FD87 9F82 -F6B4 9F83 -C1E4 9F84 -F6B5 9F85 -F6B6 9F86 -F6B7 9F87 -F6B8 9F88 -F6B9 9F89 -F6BA 9F8A -C8A3 9F8B -F6BB 9F8C -FD88 9F8D -FD89 9F8E -FD8A 9F8F -FD8B 9F90 -FD8C 9F91 -FD8D 9F92 -FD8E 9F93 -FD8F 9F94 -FD90 9F95 -FD91 9F96 -FD92 9F97 -FD93 9F98 -C1FA 9F99 -B9A8 9F9A -EDE8 9F9B -FD94 9F9C -FD95 9F9D -FD96 9F9E -B9EA 9F9F -D9DF 9FA0 -FD97 9FA1 -FD98 9FA2 -FD99 9FA3 -FD9A 9FA4 -FD9B 9FA5 -82358F33 9FA6 -82358F34 9FA7 -82358F35 9FA8 -82358F36 9FA9 -82358F37 9FAA -82358F38 9FAB -82358F39 9FAC -82359030 9FAD -82359031 9FAE -82359032 9FAF -82359033 9FB0 -82359034 9FB1 -82359035 9FB2 -82359036 9FB3 -82359037 9FB4 -82359038 9FB5 -82359039 9FB6 -82359130 9FB7 -82359131 9FB8 -82359132 9FB9 -82359133 9FBA -82359134 9FBB -82359135 9FBC -82359136 9FBD -82359137 9FBE -82359138 9FBF -82359139 9FC0 -82359230 9FC1 -82359231 9FC2 -82359232 9FC3 -82359233 9FC4 -82359234 9FC5 -82359235 9FC6 -82359236 9FC7 -82359237 9FC8 -82359238 9FC9 -82359239 9FCA -82359330 9FCB -82359331 9FCC -82359332 9FCD -82359333 9FCE -82359334 9FCF -82359335 9FD0 -82359336 9FD1 -82359337 9FD2 -82359338 9FD3 -82359339 9FD4 -82359430 9FD5 -82359431 9FD6 -82359432 9FD7 -82359433 9FD8 -82359434 9FD9 -82359435 9FDA -82359436 9FDB -82359437 9FDC -82359438 9FDD -82359439 9FDE -82359530 9FDF -82359531 9FE0 -82359532 9FE1 -82359533 9FE2 -82359534 9FE3 -82359535 9FE4 -82359536 9FE5 -82359537 9FE6 -82359538 9FE7 -82359539 9FE8 -82359630 9FE9 -82359631 9FEA -82359632 9FEB -82359633 9FEC -82359634 9FED -82359635 9FEE -82359636 9FEF -82359637 9FF0 -82359638 9FF1 -82359639 9FF2 -82359730 9FF3 -82359731 9FF4 -82359732 9FF5 -82359733 9FF6 -82359734 9FF7 -82359735 9FF8 -82359736 9FF9 -82359737 9FFA -82359738 9FFB -82359739 9FFC -82359830 9FFD -82359831 9FFE -82359832 9FFF -82359833 A000 -82359834 A001 -82359835 A002 -82359836 A003 -82359837 A004 -82359838 A005 -82359839 A006 -82359930 A007 -82359931 A008 -82359932 A009 -82359933 A00A -82359934 A00B -82359935 A00C -82359936 A00D -82359937 A00E -82359938 A00F -82359939 A010 -82359A30 A011 -82359A31 A012 -82359A32 A013 -82359A33 A014 -82359A34 A015 -82359A35 A016 -82359A36 A017 -82359A37 A018 -82359A38 A019 -82359A39 A01A -82359B30 A01B -82359B31 A01C -82359B32 A01D -82359B33 A01E -82359B34 A01F -82359B35 A020 -82359B36 A021 -82359B37 A022 -82359B38 A023 -82359B39 A024 -82359C30 A025 -82359C31 A026 -82359C32 A027 -82359C33 A028 -82359C34 A029 -82359C35 A02A -82359C36 A02B -82359C37 A02C -82359C38 A02D -82359C39 A02E -82359D30 A02F -82359D31 A030 -82359D32 A031 -82359D33 A032 -82359D34 A033 -82359D35 A034 -82359D36 A035 -82359D37 A036 -82359D38 A037 -82359D39 A038 -82359E30 A039 -82359E31 A03A -82359E32 A03B -82359E33 A03C -82359E34 A03D -82359E35 A03E -82359E36 A03F -82359E37 A040 -82359E38 A041 -82359E39 A042 -82359F30 A043 -82359F31 A044 -82359F32 A045 -82359F33 A046 -82359F34 A047 -82359F35 A048 -82359F36 A049 -82359F37 A04A -82359F38 A04B -82359F39 A04C -8235A030 A04D -8235A031 A04E -8235A032 A04F -8235A033 A050 -8235A034 A051 -8235A035 A052 -8235A036 A053 -8235A037 A054 -8235A038 A055 -8235A039 A056 -8235A130 A057 -8235A131 A058 -8235A132 A059 -8235A133 A05A -8235A134 A05B -8235A135 A05C -8235A136 A05D -8235A137 A05E -8235A138 A05F -8235A139 A060 -8235A230 A061 -8235A231 A062 -8235A232 A063 -8235A233 A064 -8235A234 A065 -8235A235 A066 -8235A236 A067 -8235A237 A068 -8235A238 A069 -8235A239 A06A -8235A330 A06B -8235A331 A06C -8235A332 A06D -8235A333 A06E -8235A334 A06F -8235A335 A070 -8235A336 A071 -8235A337 A072 -8235A338 A073 -8235A339 A074 -8235A430 A075 -8235A431 A076 -8235A432 A077 -8235A433 A078 -8235A434 A079 -8235A435 A07A -8235A436 A07B -8235A437 A07C -8235A438 A07D -8235A439 A07E -8235A530 A07F -8235A531 A080 -8235A532 A081 -8235A533 A082 -8235A534 A083 -8235A535 A084 -8235A536 A085 -8235A537 A086 -8235A538 A087 -8235A539 A088 -8235A630 A089 -8235A631 A08A -8235A632 A08B -8235A633 A08C -8235A634 A08D -8235A635 A08E -8235A636 A08F -8235A637 A090 -8235A638 A091 -8235A639 A092 -8235A730 A093 -8235A731 A094 -8235A732 A095 -8235A733 A096 -8235A734 A097 -8235A735 A098 -8235A736 A099 -8235A737 A09A -8235A738 A09B -8235A739 A09C -8235A830 A09D -8235A831 A09E -8235A832 A09F -8235A833 A0A0 -8235A834 A0A1 -8235A835 A0A2 -8235A836 A0A3 -8235A837 A0A4 -8235A838 A0A5 -8235A839 A0A6 -8235A930 A0A7 -8235A931 A0A8 -8235A932 A0A9 -8235A933 A0AA -8235A934 A0AB -8235A935 A0AC -8235A936 A0AD -8235A937 A0AE -8235A938 A0AF -8235A939 A0B0 -8235AA30 A0B1 -8235AA31 A0B2 -8235AA32 A0B3 -8235AA33 A0B4 -8235AA34 A0B5 -8235AA35 A0B6 -8235AA36 A0B7 -8235AA37 A0B8 -8235AA38 A0B9 -8235AA39 A0BA -8235AB30 A0BB -8235AB31 A0BC -8235AB32 A0BD -8235AB33 A0BE -8235AB34 A0BF -8235AB35 A0C0 -8235AB36 A0C1 -8235AB37 A0C2 -8235AB38 A0C3 -8235AB39 A0C4 -8235AC30 A0C5 -8235AC31 A0C6 -8235AC32 A0C7 -8235AC33 A0C8 -8235AC34 A0C9 -8235AC35 A0CA -8235AC36 A0CB -8235AC37 A0CC -8235AC38 A0CD -8235AC39 A0CE -8235AD30 A0CF -8235AD31 A0D0 -8235AD32 A0D1 -8235AD33 A0D2 -8235AD34 A0D3 -8235AD35 A0D4 -8235AD36 A0D5 -8235AD37 A0D6 -8235AD38 A0D7 -8235AD39 A0D8 -8235AE30 A0D9 -8235AE31 A0DA -8235AE32 A0DB -8235AE33 A0DC -8235AE34 A0DD -8235AE35 A0DE -8235AE36 A0DF -8235AE37 A0E0 -8235AE38 A0E1 -8235AE39 A0E2 -8235AF30 A0E3 -8235AF31 A0E4 -8235AF32 A0E5 -8235AF33 A0E6 -8235AF34 A0E7 -8235AF35 A0E8 -8235AF36 A0E9 -8235AF37 A0EA -8235AF38 A0EB -8235AF39 A0EC -8235B030 A0ED -8235B031 A0EE -8235B032 A0EF -8235B033 A0F0 -8235B034 A0F1 -8235B035 A0F2 -8235B036 A0F3 -8235B037 A0F4 -8235B038 A0F5 -8235B039 A0F6 -8235B130 A0F7 -8235B131 A0F8 -8235B132 A0F9 -8235B133 A0FA -8235B134 A0FB -8235B135 A0FC -8235B136 A0FD -8235B137 A0FE -8235B138 A0FF -8235B139 A100 -8235B230 A101 -8235B231 A102 -8235B232 A103 -8235B233 A104 -8235B234 A105 -8235B235 A106 -8235B236 A107 -8235B237 A108 -8235B238 A109 -8235B239 A10A -8235B330 A10B -8235B331 A10C -8235B332 A10D -8235B333 A10E -8235B334 A10F -8235B335 A110 -8235B336 A111 -8235B337 A112 -8235B338 A113 -8235B339 A114 -8235B430 A115 -8235B431 A116 -8235B432 A117 -8235B433 A118 -8235B434 A119 -8235B435 A11A -8235B436 A11B -8235B437 A11C -8235B438 A11D -8235B439 A11E -8235B530 A11F -8235B531 A120 -8235B532 A121 -8235B533 A122 -8235B534 A123 -8235B535 A124 -8235B536 A125 -8235B537 A126 -8235B538 A127 -8235B539 A128 -8235B630 A129 -8235B631 A12A -8235B632 A12B -8235B633 A12C -8235B634 A12D -8235B635 A12E -8235B636 A12F -8235B637 A130 -8235B638 A131 -8235B639 A132 -8235B730 A133 -8235B731 A134 -8235B732 A135 -8235B733 A136 -8235B734 A137 -8235B735 A138 -8235B736 A139 -8235B737 A13A -8235B738 A13B -8235B739 A13C -8235B830 A13D -8235B831 A13E -8235B832 A13F -8235B833 A140 -8235B834 A141 -8235B835 A142 -8235B836 A143 -8235B837 A144 -8235B838 A145 -8235B839 A146 -8235B930 A147 -8235B931 A148 -8235B932 A149 -8235B933 A14A -8235B934 A14B -8235B935 A14C -8235B936 A14D -8235B937 A14E -8235B938 A14F -8235B939 A150 -8235BA30 A151 -8235BA31 A152 -8235BA32 A153 -8235BA33 A154 -8235BA34 A155 -8235BA35 A156 -8235BA36 A157 -8235BA37 A158 -8235BA38 A159 -8235BA39 A15A -8235BB30 A15B -8235BB31 A15C -8235BB32 A15D -8235BB33 A15E -8235BB34 A15F -8235BB35 A160 -8235BB36 A161 -8235BB37 A162 -8235BB38 A163 -8235BB39 A164 -8235BC30 A165 -8235BC31 A166 -8235BC32 A167 -8235BC33 A168 -8235BC34 A169 -8235BC35 A16A -8235BC36 A16B -8235BC37 A16C -8235BC38 A16D -8235BC39 A16E -8235BD30 A16F -8235BD31 A170 -8235BD32 A171 -8235BD33 A172 -8235BD34 A173 -8235BD35 A174 -8235BD36 A175 -8235BD37 A176 -8235BD38 A177 -8235BD39 A178 -8235BE30 A179 -8235BE31 A17A -8235BE32 A17B -8235BE33 A17C -8235BE34 A17D -8235BE35 A17E -8235BE36 A17F -8235BE37 A180 -8235BE38 A181 -8235BE39 A182 -8235BF30 A183 -8235BF31 A184 -8235BF32 A185 -8235BF33 A186 -8235BF34 A187 -8235BF35 A188 -8235BF36 A189 -8235BF37 A18A -8235BF38 A18B -8235BF39 A18C -8235C030 A18D -8235C031 A18E -8235C032 A18F -8235C033 A190 -8235C034 A191 -8235C035 A192 -8235C036 A193 -8235C037 A194 -8235C038 A195 -8235C039 A196 -8235C130 A197 -8235C131 A198 -8235C132 A199 -8235C133 A19A -8235C134 A19B -8235C135 A19C -8235C136 A19D -8235C137 A19E -8235C138 A19F -8235C139 A1A0 -8235C230 A1A1 -8235C231 A1A2 -8235C232 A1A3 -8235C233 A1A4 -8235C234 A1A5 -8235C235 A1A6 -8235C236 A1A7 -8235C237 A1A8 -8235C238 A1A9 -8235C239 A1AA -8235C330 A1AB -8235C331 A1AC -8235C332 A1AD -8235C333 A1AE -8235C334 A1AF -8235C335 A1B0 -8235C336 A1B1 -8235C337 A1B2 -8235C338 A1B3 -8235C339 A1B4 -8235C430 A1B5 -8235C431 A1B6 -8235C432 A1B7 -8235C433 A1B8 -8235C434 A1B9 -8235C435 A1BA -8235C436 A1BB -8235C437 A1BC -8235C438 A1BD -8235C439 A1BE -8235C530 A1BF -8235C531 A1C0 -8235C532 A1C1 -8235C533 A1C2 -8235C534 A1C3 -8235C535 A1C4 -8235C536 A1C5 -8235C537 A1C6 -8235C538 A1C7 -8235C539 A1C8 -8235C630 A1C9 -8235C631 A1CA -8235C632 A1CB -8235C633 A1CC -8235C634 A1CD -8235C635 A1CE -8235C636 A1CF -8235C637 A1D0 -8235C638 A1D1 -8235C639 A1D2 -8235C730 A1D3 -8235C731 A1D4 -8235C732 A1D5 -8235C733 A1D6 -8235C734 A1D7 -8235C735 A1D8 -8235C736 A1D9 -8235C737 A1DA -8235C738 A1DB -8235C739 A1DC -8235C830 A1DD -8235C831 A1DE -8235C832 A1DF -8235C833 A1E0 -8235C834 A1E1 -8235C835 A1E2 -8235C836 A1E3 -8235C837 A1E4 -8235C838 A1E5 -8235C839 A1E6 -8235C930 A1E7 -8235C931 A1E8 -8235C932 A1E9 -8235C933 A1EA -8235C934 A1EB -8235C935 A1EC -8235C936 A1ED -8235C937 A1EE -8235C938 A1EF -8235C939 A1F0 -8235CA30 A1F1 -8235CA31 A1F2 -8235CA32 A1F3 -8235CA33 A1F4 -8235CA34 A1F5 -8235CA35 A1F6 -8235CA36 A1F7 -8235CA37 A1F8 -8235CA38 A1F9 -8235CA39 A1FA -8235CB30 A1FB -8235CB31 A1FC -8235CB32 A1FD -8235CB33 A1FE -8235CB34 A1FF -8235CB35 A200 -8235CB36 A201 -8235CB37 A202 -8235CB38 A203 -8235CB39 A204 -8235CC30 A205 -8235CC31 A206 -8235CC32 A207 -8235CC33 A208 -8235CC34 A209 -8235CC35 A20A -8235CC36 A20B -8235CC37 A20C -8235CC38 A20D -8235CC39 A20E -8235CD30 A20F -8235CD31 A210 -8235CD32 A211 -8235CD33 A212 -8235CD34 A213 -8235CD35 A214 -8235CD36 A215 -8235CD37 A216 -8235CD38 A217 -8235CD39 A218 -8235CE30 A219 -8235CE31 A21A -8235CE32 A21B -8235CE33 A21C -8235CE34 A21D -8235CE35 A21E -8235CE36 A21F -8235CE37 A220 -8235CE38 A221 -8235CE39 A222 -8235CF30 A223 -8235CF31 A224 -8235CF32 A225 -8235CF33 A226 -8235CF34 A227 -8235CF35 A228 -8235CF36 A229 -8235CF37 A22A -8235CF38 A22B -8235CF39 A22C -8235D030 A22D -8235D031 A22E -8235D032 A22F -8235D033 A230 -8235D034 A231 -8235D035 A232 -8235D036 A233 -8235D037 A234 -8235D038 A235 -8235D039 A236 -8235D130 A237 -8235D131 A238 -8235D132 A239 -8235D133 A23A -8235D134 A23B -8235D135 A23C -8235D136 A23D -8235D137 A23E -8235D138 A23F -8235D139 A240 -8235D230 A241 -8235D231 A242 -8235D232 A243 -8235D233 A244 -8235D234 A245 -8235D235 A246 -8235D236 A247 -8235D237 A248 -8235D238 A249 -8235D239 A24A -8235D330 A24B -8235D331 A24C -8235D332 A24D -8235D333 A24E -8235D334 A24F -8235D335 A250 -8235D336 A251 -8235D337 A252 -8235D338 A253 -8235D339 A254 -8235D430 A255 -8235D431 A256 -8235D432 A257 -8235D433 A258 -8235D434 A259 -8235D435 A25A -8235D436 A25B -8235D437 A25C -8235D438 A25D -8235D439 A25E -8235D530 A25F -8235D531 A260 -8235D532 A261 -8235D533 A262 -8235D534 A263 -8235D535 A264 -8235D536 A265 -8235D537 A266 -8235D538 A267 -8235D539 A268 -8235D630 A269 -8235D631 A26A -8235D632 A26B -8235D633 A26C -8235D634 A26D -8235D635 A26E -8235D636 A26F -8235D637 A270 -8235D638 A271 -8235D639 A272 -8235D730 A273 -8235D731 A274 -8235D732 A275 -8235D733 A276 -8235D734 A277 -8235D735 A278 -8235D736 A279 -8235D737 A27A -8235D738 A27B -8235D739 A27C -8235D830 A27D -8235D831 A27E -8235D832 A27F -8235D833 A280 -8235D834 A281 -8235D835 A282 -8235D836 A283 -8235D837 A284 -8235D838 A285 -8235D839 A286 -8235D930 A287 -8235D931 A288 -8235D932 A289 -8235D933 A28A -8235D934 A28B -8235D935 A28C -8235D936 A28D -8235D937 A28E -8235D938 A28F -8235D939 A290 -8235DA30 A291 -8235DA31 A292 -8235DA32 A293 -8235DA33 A294 -8235DA34 A295 -8235DA35 A296 -8235DA36 A297 -8235DA37 A298 -8235DA38 A299 -8235DA39 A29A -8235DB30 A29B -8235DB31 A29C -8235DB32 A29D -8235DB33 A29E -8235DB34 A29F -8235DB35 A2A0 -8235DB36 A2A1 -8235DB37 A2A2 -8235DB38 A2A3 -8235DB39 A2A4 -8235DC30 A2A5 -8235DC31 A2A6 -8235DC32 A2A7 -8235DC33 A2A8 -8235DC34 A2A9 -8235DC35 A2AA -8235DC36 A2AB -8235DC37 A2AC -8235DC38 A2AD -8235DC39 A2AE -8235DD30 A2AF -8235DD31 A2B0 -8235DD32 A2B1 -8235DD33 A2B2 -8235DD34 A2B3 -8235DD35 A2B4 -8235DD36 A2B5 -8235DD37 A2B6 -8235DD38 A2B7 -8235DD39 A2B8 -8235DE30 A2B9 -8235DE31 A2BA -8235DE32 A2BB -8235DE33 A2BC -8235DE34 A2BD -8235DE35 A2BE -8235DE36 A2BF -8235DE37 A2C0 -8235DE38 A2C1 -8235DE39 A2C2 -8235DF30 A2C3 -8235DF31 A2C4 -8235DF32 A2C5 -8235DF33 A2C6 -8235DF34 A2C7 -8235DF35 A2C8 -8235DF36 A2C9 -8235DF37 A2CA -8235DF38 A2CB -8235DF39 A2CC -8235E030 A2CD -8235E031 A2CE -8235E032 A2CF -8235E033 A2D0 -8235E034 A2D1 -8235E035 A2D2 -8235E036 A2D3 -8235E037 A2D4 -8235E038 A2D5 -8235E039 A2D6 -8235E130 A2D7 -8235E131 A2D8 -8235E132 A2D9 -8235E133 A2DA -8235E134 A2DB -8235E135 A2DC -8235E136 A2DD -8235E137 A2DE -8235E138 A2DF -8235E139 A2E0 -8235E230 A2E1 -8235E231 A2E2 -8235E232 A2E3 -8235E233 A2E4 -8235E234 A2E5 -8235E235 A2E6 -8235E236 A2E7 -8235E237 A2E8 -8235E238 A2E9 -8235E239 A2EA -8235E330 A2EB -8235E331 A2EC -8235E332 A2ED -8235E333 A2EE -8235E334 A2EF -8235E335 A2F0 -8235E336 A2F1 -8235E337 A2F2 -8235E338 A2F3 -8235E339 A2F4 -8235E430 A2F5 -8235E431 A2F6 -8235E432 A2F7 -8235E433 A2F8 -8235E434 A2F9 -8235E435 A2FA -8235E436 A2FB -8235E437 A2FC -8235E438 A2FD -8235E439 A2FE -8235E530 A2FF -8235E531 A300 -8235E532 A301 -8235E533 A302 -8235E534 A303 -8235E535 A304 -8235E536 A305 -8235E537 A306 -8235E538 A307 -8235E539 A308 -8235E630 A309 -8235E631 A30A -8235E632 A30B -8235E633 A30C -8235E634 A30D -8235E635 A30E -8235E636 A30F -8235E637 A310 -8235E638 A311 -8235E639 A312 -8235E730 A313 -8235E731 A314 -8235E732 A315 -8235E733 A316 -8235E734 A317 -8235E735 A318 -8235E736 A319 -8235E737 A31A -8235E738 A31B -8235E739 A31C -8235E830 A31D -8235E831 A31E -8235E832 A31F -8235E833 A320 -8235E834 A321 -8235E835 A322 -8235E836 A323 -8235E837 A324 -8235E838 A325 -8235E839 A326 -8235E930 A327 -8235E931 A328 -8235E932 A329 -8235E933 A32A -8235E934 A32B -8235E935 A32C -8235E936 A32D -8235E937 A32E -8235E938 A32F -8235E939 A330 -8235EA30 A331 -8235EA31 A332 -8235EA32 A333 -8235EA33 A334 -8235EA34 A335 -8235EA35 A336 -8235EA36 A337 -8235EA37 A338 -8235EA38 A339 -8235EA39 A33A -8235EB30 A33B -8235EB31 A33C -8235EB32 A33D -8235EB33 A33E -8235EB34 A33F -8235EB35 A340 -8235EB36 A341 -8235EB37 A342 -8235EB38 A343 -8235EB39 A344 -8235EC30 A345 -8235EC31 A346 -8235EC32 A347 -8235EC33 A348 -8235EC34 A349 -8235EC35 A34A -8235EC36 A34B -8235EC37 A34C -8235EC38 A34D -8235EC39 A34E -8235ED30 A34F -8235ED31 A350 -8235ED32 A351 -8235ED33 A352 -8235ED34 A353 -8235ED35 A354 -8235ED36 A355 -8235ED37 A356 -8235ED38 A357 -8235ED39 A358 -8235EE30 A359 -8235EE31 A35A -8235EE32 A35B -8235EE33 A35C -8235EE34 A35D -8235EE35 A35E -8235EE36 A35F -8235EE37 A360 -8235EE38 A361 -8235EE39 A362 -8235EF30 A363 -8235EF31 A364 -8235EF32 A365 -8235EF33 A366 -8235EF34 A367 -8235EF35 A368 -8235EF36 A369 -8235EF37 A36A -8235EF38 A36B -8235EF39 A36C -8235F030 A36D -8235F031 A36E -8235F032 A36F -8235F033 A370 -8235F034 A371 -8235F035 A372 -8235F036 A373 -8235F037 A374 -8235F038 A375 -8235F039 A376 -8235F130 A377 -8235F131 A378 -8235F132 A379 -8235F133 A37A -8235F134 A37B -8235F135 A37C -8235F136 A37D -8235F137 A37E -8235F138 A37F -8235F139 A380 -8235F230 A381 -8235F231 A382 -8235F232 A383 -8235F233 A384 -8235F234 A385 -8235F235 A386 -8235F236 A387 -8235F237 A388 -8235F238 A389 -8235F239 A38A -8235F330 A38B -8235F331 A38C -8235F332 A38D -8235F333 A38E -8235F334 A38F -8235F335 A390 -8235F336 A391 -8235F337 A392 -8235F338 A393 -8235F339 A394 -8235F430 A395 -8235F431 A396 -8235F432 A397 -8235F433 A398 -8235F434 A399 -8235F435 A39A -8235F436 A39B -8235F437 A39C -8235F438 A39D -8235F439 A39E -8235F530 A39F -8235F531 A3A0 -8235F532 A3A1 -8235F533 A3A2 -8235F534 A3A3 -8235F535 A3A4 -8235F536 A3A5 -8235F537 A3A6 -8235F538 A3A7 -8235F539 A3A8 -8235F630 A3A9 -8235F631 A3AA -8235F632 A3AB -8235F633 A3AC -8235F634 A3AD -8235F635 A3AE -8235F636 A3AF -8235F637 A3B0 -8235F638 A3B1 -8235F639 A3B2 -8235F730 A3B3 -8235F731 A3B4 -8235F732 A3B5 -8235F733 A3B6 -8235F734 A3B7 -8235F735 A3B8 -8235F736 A3B9 -8235F737 A3BA -8235F738 A3BB -8235F739 A3BC -8235F830 A3BD -8235F831 A3BE -8235F832 A3BF -8235F833 A3C0 -8235F834 A3C1 -8235F835 A3C2 -8235F836 A3C3 -8235F837 A3C4 -8235F838 A3C5 -8235F839 A3C6 -8235F930 A3C7 -8235F931 A3C8 -8235F932 A3C9 -8235F933 A3CA -8235F934 A3CB -8235F935 A3CC -8235F936 A3CD -8235F937 A3CE -8235F938 A3CF -8235F939 A3D0 -8235FA30 A3D1 -8235FA31 A3D2 -8235FA32 A3D3 -8235FA33 A3D4 -8235FA34 A3D5 -8235FA35 A3D6 -8235FA36 A3D7 -8235FA37 A3D8 -8235FA38 A3D9 -8235FA39 A3DA -8235FB30 A3DB -8235FB31 A3DC -8235FB32 A3DD -8235FB33 A3DE -8235FB34 A3DF -8235FB35 A3E0 -8235FB36 A3E1 -8235FB37 A3E2 -8235FB38 A3E3 -8235FB39 A3E4 -8235FC30 A3E5 -8235FC31 A3E6 -8235FC32 A3E7 -8235FC33 A3E8 -8235FC34 A3E9 -8235FC35 A3EA -8235FC36 A3EB -8235FC37 A3EC -8235FC38 A3ED -8235FC39 A3EE -8235FD30 A3EF -8235FD31 A3F0 -8235FD32 A3F1 -8235FD33 A3F2 -8235FD34 A3F3 -8235FD35 A3F4 -8235FD36 A3F5 -8235FD37 A3F6 -8235FD38 A3F7 -8235FD39 A3F8 -8235FE30 A3F9 -8235FE31 A3FA -8235FE32 A3FB -8235FE33 A3FC -8235FE34 A3FD -8235FE35 A3FE -8235FE36 A3FF -8235FE37 A400 -8235FE38 A401 -8235FE39 A402 -82368130 A403 -82368131 A404 -82368132 A405 -82368133 A406 -82368134 A407 -82368135 A408 -82368136 A409 -82368137 A40A -82368138 A40B -82368139 A40C -82368230 A40D -82368231 A40E -82368232 A40F -82368233 A410 -82368234 A411 -82368235 A412 -82368236 A413 -82368237 A414 -82368238 A415 -82368239 A416 -82368330 A417 -82368331 A418 -82368332 A419 -82368333 A41A -82368334 A41B -82368335 A41C -82368336 A41D -82368337 A41E -82368338 A41F -82368339 A420 -82368430 A421 -82368431 A422 -82368432 A423 -82368433 A424 -82368434 A425 -82368435 A426 -82368436 A427 -82368437 A428 -82368438 A429 -82368439 A42A -82368530 A42B -82368531 A42C -82368532 A42D -82368533 A42E -82368534 A42F -82368535 A430 -82368536 A431 -82368537 A432 -82368538 A433 -82368539 A434 -82368630 A435 -82368631 A436 -82368632 A437 -82368633 A438 -82368634 A439 -82368635 A43A -82368636 A43B -82368637 A43C -82368638 A43D -82368639 A43E -82368730 A43F -82368731 A440 -82368732 A441 -82368733 A442 -82368734 A443 -82368735 A444 -82368736 A445 -82368737 A446 -82368738 A447 -82368739 A448 -82368830 A449 -82368831 A44A -82368832 A44B -82368833 A44C -82368834 A44D -82368835 A44E -82368836 A44F -82368837 A450 -82368838 A451 -82368839 A452 -82368930 A453 -82368931 A454 -82368932 A455 -82368933 A456 -82368934 A457 -82368935 A458 -82368936 A459 -82368937 A45A -82368938 A45B -82368939 A45C -82368A30 A45D -82368A31 A45E -82368A32 A45F -82368A33 A460 -82368A34 A461 -82368A35 A462 -82368A36 A463 -82368A37 A464 -82368A38 A465 -82368A39 A466 -82368B30 A467 -82368B31 A468 -82368B32 A469 -82368B33 A46A -82368B34 A46B -82368B35 A46C -82368B36 A46D -82368B37 A46E -82368B38 A46F -82368B39 A470 -82368C30 A471 -82368C31 A472 -82368C32 A473 -82368C33 A474 -82368C34 A475 -82368C35 A476 -82368C36 A477 -82368C37 A478 -82368C38 A479 -82368C39 A47A -82368D30 A47B -82368D31 A47C -82368D32 A47D -82368D33 A47E -82368D34 A47F -82368D35 A480 -82368D36 A481 -82368D37 A482 -82368D38 A483 -82368D39 A484 -82368E30 A485 -82368E31 A486 -82368E32 A487 -82368E33 A488 -82368E34 A489 -82368E35 A48A -82368E36 A48B -82368E37 A48C -82368E38 A48D -82368E39 A48E -82368F30 A48F -82368F31 A490 -82368F32 A491 -82368F33 A492 -82368F34 A493 -82368F35 A494 -82368F36 A495 -82368F37 A496 -82368F38 A497 -82368F39 A498 -82369030 A499 -82369031 A49A -82369032 A49B -82369033 A49C -82369034 A49D -82369035 A49E -82369036 A49F -82369037 A4A0 -82369038 A4A1 -82369039 A4A2 -82369130 A4A3 -82369131 A4A4 -82369132 A4A5 -82369133 A4A6 -82369134 A4A7 -82369135 A4A8 -82369136 A4A9 -82369137 A4AA -82369138 A4AB -82369139 A4AC -82369230 A4AD -82369231 A4AE -82369232 A4AF -82369233 A4B0 -82369234 A4B1 -82369235 A4B2 -82369236 A4B3 -82369237 A4B4 -82369238 A4B5 -82369239 A4B6 -82369330 A4B7 -82369331 A4B8 -82369332 A4B9 -82369333 A4BA -82369334 A4BB -82369335 A4BC -82369336 A4BD -82369337 A4BE -82369338 A4BF -82369339 A4C0 -82369430 A4C1 -82369431 A4C2 -82369432 A4C3 -82369433 A4C4 -82369434 A4C5 -82369435 A4C6 -82369436 A4C7 -82369437 A4C8 -82369438 A4C9 -82369439 A4CA -82369530 A4CB -82369531 A4CC -82369532 A4CD -82369533 A4CE -82369534 A4CF -82369535 A4D0 -82369536 A4D1 -82369537 A4D2 -82369538 A4D3 -82369539 A4D4 -82369630 A4D5 -82369631 A4D6 -82369632 A4D7 -82369633 A4D8 -82369634 A4D9 -82369635 A4DA -82369636 A4DB -82369637 A4DC -82369638 A4DD -82369639 A4DE -82369730 A4DF -82369731 A4E0 -82369732 A4E1 -82369733 A4E2 -82369734 A4E3 -82369735 A4E4 -82369736 A4E5 -82369737 A4E6 -82369738 A4E7 -82369739 A4E8 -82369830 A4E9 -82369831 A4EA -82369832 A4EB -82369833 A4EC -82369834 A4ED -82369835 A4EE -82369836 A4EF -82369837 A4F0 -82369838 A4F1 -82369839 A4F2 -82369930 A4F3 -82369931 A4F4 -82369932 A4F5 -82369933 A4F6 -82369934 A4F7 -82369935 A4F8 -82369936 A4F9 -82369937 A4FA -82369938 A4FB -82369939 A4FC -82369A30 A4FD -82369A31 A4FE -82369A32 A4FF -82369A33 A500 -82369A34 A501 -82369A35 A502 -82369A36 A503 -82369A37 A504 -82369A38 A505 -82369A39 A506 -82369B30 A507 -82369B31 A508 -82369B32 A509 -82369B33 A50A -82369B34 A50B -82369B35 A50C -82369B36 A50D -82369B37 A50E -82369B38 A50F -82369B39 A510 -82369C30 A511 -82369C31 A512 -82369C32 A513 -82369C33 A514 -82369C34 A515 -82369C35 A516 -82369C36 A517 -82369C37 A518 -82369C38 A519 -82369C39 A51A -82369D30 A51B -82369D31 A51C -82369D32 A51D -82369D33 A51E -82369D34 A51F -82369D35 A520 -82369D36 A521 -82369D37 A522 -82369D38 A523 -82369D39 A524 -82369E30 A525 -82369E31 A526 -82369E32 A527 -82369E33 A528 -82369E34 A529 -82369E35 A52A -82369E36 A52B -82369E37 A52C -82369E38 A52D -82369E39 A52E -82369F30 A52F -82369F31 A530 -82369F32 A531 -82369F33 A532 -82369F34 A533 -82369F35 A534 -82369F36 A535 -82369F37 A536 -82369F38 A537 -82369F39 A538 -8236A030 A539 -8236A031 A53A -8236A032 A53B -8236A033 A53C -8236A034 A53D -8236A035 A53E -8236A036 A53F -8236A037 A540 -8236A038 A541 -8236A039 A542 -8236A130 A543 -8236A131 A544 -8236A132 A545 -8236A133 A546 -8236A134 A547 -8236A135 A548 -8236A136 A549 -8236A137 A54A -8236A138 A54B -8236A139 A54C -8236A230 A54D -8236A231 A54E -8236A232 A54F -8236A233 A550 -8236A234 A551 -8236A235 A552 -8236A236 A553 -8236A237 A554 -8236A238 A555 -8236A239 A556 -8236A330 A557 -8236A331 A558 -8236A332 A559 -8236A333 A55A -8236A334 A55B -8236A335 A55C -8236A336 A55D -8236A337 A55E -8236A338 A55F -8236A339 A560 -8236A430 A561 -8236A431 A562 -8236A432 A563 -8236A433 A564 -8236A434 A565 -8236A435 A566 -8236A436 A567 -8236A437 A568 -8236A438 A569 -8236A439 A56A -8236A530 A56B -8236A531 A56C -8236A532 A56D -8236A533 A56E -8236A534 A56F -8236A535 A570 -8236A536 A571 -8236A537 A572 -8236A538 A573 -8236A539 A574 -8236A630 A575 -8236A631 A576 -8236A632 A577 -8236A633 A578 -8236A634 A579 -8236A635 A57A -8236A636 A57B -8236A637 A57C -8236A638 A57D -8236A639 A57E -8236A730 A57F -8236A731 A580 -8236A732 A581 -8236A733 A582 -8236A734 A583 -8236A735 A584 -8236A736 A585 -8236A737 A586 -8236A738 A587 -8236A739 A588 -8236A830 A589 -8236A831 A58A -8236A832 A58B -8236A833 A58C -8236A834 A58D -8236A835 A58E -8236A836 A58F -8236A837 A590 -8236A838 A591 -8236A839 A592 -8236A930 A593 -8236A931 A594 -8236A932 A595 -8236A933 A596 -8236A934 A597 -8236A935 A598 -8236A936 A599 -8236A937 A59A -8236A938 A59B -8236A939 A59C -8236AA30 A59D -8236AA31 A59E -8236AA32 A59F -8236AA33 A5A0 -8236AA34 A5A1 -8236AA35 A5A2 -8236AA36 A5A3 -8236AA37 A5A4 -8236AA38 A5A5 -8236AA39 A5A6 -8236AB30 A5A7 -8236AB31 A5A8 -8236AB32 A5A9 -8236AB33 A5AA -8236AB34 A5AB -8236AB35 A5AC -8236AB36 A5AD -8236AB37 A5AE -8236AB38 A5AF -8236AB39 A5B0 -8236AC30 A5B1 -8236AC31 A5B2 -8236AC32 A5B3 -8236AC33 A5B4 -8236AC34 A5B5 -8236AC35 A5B6 -8236AC36 A5B7 -8236AC37 A5B8 -8236AC38 A5B9 -8236AC39 A5BA -8236AD30 A5BB -8236AD31 A5BC -8236AD32 A5BD -8236AD33 A5BE -8236AD34 A5BF -8236AD35 A5C0 -8236AD36 A5C1 -8236AD37 A5C2 -8236AD38 A5C3 -8236AD39 A5C4 -8236AE30 A5C5 -8236AE31 A5C6 -8236AE32 A5C7 -8236AE33 A5C8 -8236AE34 A5C9 -8236AE35 A5CA -8236AE36 A5CB -8236AE37 A5CC -8236AE38 A5CD -8236AE39 A5CE -8236AF30 A5CF -8236AF31 A5D0 -8236AF32 A5D1 -8236AF33 A5D2 -8236AF34 A5D3 -8236AF35 A5D4 -8236AF36 A5D5 -8236AF37 A5D6 -8236AF38 A5D7 -8236AF39 A5D8 -8236B030 A5D9 -8236B031 A5DA -8236B032 A5DB -8236B033 A5DC -8236B034 A5DD -8236B035 A5DE -8236B036 A5DF -8236B037 A5E0 -8236B038 A5E1 -8236B039 A5E2 -8236B130 A5E3 -8236B131 A5E4 -8236B132 A5E5 -8236B133 A5E6 -8236B134 A5E7 -8236B135 A5E8 -8236B136 A5E9 -8236B137 A5EA -8236B138 A5EB -8236B139 A5EC -8236B230 A5ED -8236B231 A5EE -8236B232 A5EF -8236B233 A5F0 -8236B234 A5F1 -8236B235 A5F2 -8236B236 A5F3 -8236B237 A5F4 -8236B238 A5F5 -8236B239 A5F6 -8236B330 A5F7 -8236B331 A5F8 -8236B332 A5F9 -8236B333 A5FA -8236B334 A5FB -8236B335 A5FC -8236B336 A5FD -8236B337 A5FE -8236B338 A5FF -8236B339 A600 -8236B430 A601 -8236B431 A602 -8236B432 A603 -8236B433 A604 -8236B434 A605 -8236B435 A606 -8236B436 A607 -8236B437 A608 -8236B438 A609 -8236B439 A60A -8236B530 A60B -8236B531 A60C -8236B532 A60D -8236B533 A60E -8236B534 A60F -8236B535 A610 -8236B536 A611 -8236B537 A612 -8236B538 A613 -8236B539 A614 -8236B630 A615 -8236B631 A616 -8236B632 A617 -8236B633 A618 -8236B634 A619 -8236B635 A61A -8236B636 A61B -8236B637 A61C -8236B638 A61D -8236B639 A61E -8236B730 A61F -8236B731 A620 -8236B732 A621 -8236B733 A622 -8236B734 A623 -8236B735 A624 -8236B736 A625 -8236B737 A626 -8236B738 A627 -8236B739 A628 -8236B830 A629 -8236B831 A62A -8236B832 A62B -8236B833 A62C -8236B834 A62D -8236B835 A62E -8236B836 A62F -8236B837 A630 -8236B838 A631 -8236B839 A632 -8236B930 A633 -8236B931 A634 -8236B932 A635 -8236B933 A636 -8236B934 A637 -8236B935 A638 -8236B936 A639 -8236B937 A63A -8236B938 A63B -8236B939 A63C -8236BA30 A63D -8236BA31 A63E -8236BA32 A63F -8236BA33 A640 -8236BA34 A641 -8236BA35 A642 -8236BA36 A643 -8236BA37 A644 -8236BA38 A645 -8236BA39 A646 -8236BB30 A647 -8236BB31 A648 -8236BB32 A649 -8236BB33 A64A -8236BB34 A64B -8236BB35 A64C -8236BB36 A64D -8236BB37 A64E -8236BB38 A64F -8236BB39 A650 -8236BC30 A651 -8236BC31 A652 -8236BC32 A653 -8236BC33 A654 -8236BC34 A655 -8236BC35 A656 -8236BC36 A657 -8236BC37 A658 -8236BC38 A659 -8236BC39 A65A -8236BD30 A65B -8236BD31 A65C -8236BD32 A65D -8236BD33 A65E -8236BD34 A65F -8236BD35 A660 -8236BD36 A661 -8236BD37 A662 -8236BD38 A663 -8236BD39 A664 -8236BE30 A665 -8236BE31 A666 -8236BE32 A667 -8236BE33 A668 -8236BE34 A669 -8236BE35 A66A -8236BE36 A66B -8236BE37 A66C -8236BE38 A66D -8236BE39 A66E -8236BF30 A66F -8236BF31 A670 -8236BF32 A671 -8236BF33 A672 -8236BF34 A673 -8236BF35 A674 -8236BF36 A675 -8236BF37 A676 -8236BF38 A677 -8236BF39 A678 -8236C030 A679 -8236C031 A67A -8236C032 A67B -8236C033 A67C -8236C034 A67D -8236C035 A67E -8236C036 A67F -8236C037 A680 -8236C038 A681 -8236C039 A682 -8236C130 A683 -8236C131 A684 -8236C132 A685 -8236C133 A686 -8236C134 A687 -8236C135 A688 -8236C136 A689 -8236C137 A68A -8236C138 A68B -8236C139 A68C -8236C230 A68D -8236C231 A68E -8236C232 A68F -8236C233 A690 -8236C234 A691 -8236C235 A692 -8236C236 A693 -8236C237 A694 -8236C238 A695 -8236C239 A696 -8236C330 A697 -8236C331 A698 -8236C332 A699 -8236C333 A69A -8236C334 A69B -8236C335 A69C -8236C336 A69D -8236C337 A69E -8236C338 A69F -8236C339 A6A0 -8236C430 A6A1 -8236C431 A6A2 -8236C432 A6A3 -8236C433 A6A4 -8236C434 A6A5 -8236C435 A6A6 -8236C436 A6A7 -8236C437 A6A8 -8236C438 A6A9 -8236C439 A6AA -8236C530 A6AB -8236C531 A6AC -8236C532 A6AD -8236C533 A6AE -8236C534 A6AF -8236C535 A6B0 -8236C536 A6B1 -8236C537 A6B2 -8236C538 A6B3 -8236C539 A6B4 -8236C630 A6B5 -8236C631 A6B6 -8236C632 A6B7 -8236C633 A6B8 -8236C634 A6B9 -8236C635 A6BA -8236C636 A6BB -8236C637 A6BC -8236C638 A6BD -8236C639 A6BE -8236C730 A6BF -8236C731 A6C0 -8236C732 A6C1 -8236C733 A6C2 -8236C734 A6C3 -8236C735 A6C4 -8236C736 A6C5 -8236C737 A6C6 -8236C738 A6C7 -8236C739 A6C8 -8236C830 A6C9 -8236C831 A6CA -8236C832 A6CB -8236C833 A6CC -8236C834 A6CD -8236C835 A6CE -8236C836 A6CF -8236C837 A6D0 -8236C838 A6D1 -8236C839 A6D2 -8236C930 A6D3 -8236C931 A6D4 -8236C932 A6D5 -8236C933 A6D6 -8236C934 A6D7 -8236C935 A6D8 -8236C936 A6D9 -8236C937 A6DA -8236C938 A6DB -8236C939 A6DC -8236CA30 A6DD -8236CA31 A6DE -8236CA32 A6DF -8236CA33 A6E0 -8236CA34 A6E1 -8236CA35 A6E2 -8236CA36 A6E3 -8236CA37 A6E4 -8236CA38 A6E5 -8236CA39 A6E6 -8236CB30 A6E7 -8236CB31 A6E8 -8236CB32 A6E9 -8236CB33 A6EA -8236CB34 A6EB -8236CB35 A6EC -8236CB36 A6ED -8236CB37 A6EE -8236CB38 A6EF -8236CB39 A6F0 -8236CC30 A6F1 -8236CC31 A6F2 -8236CC32 A6F3 -8236CC33 A6F4 -8236CC34 A6F5 -8236CC35 A6F6 -8236CC36 A6F7 -8236CC37 A6F8 -8236CC38 A6F9 -8236CC39 A6FA -8236CD30 A6FB -8236CD31 A6FC -8236CD32 A6FD -8236CD33 A6FE -8236CD34 A6FF -8236CD35 A700 -8236CD36 A701 -8236CD37 A702 -8236CD38 A703 -8236CD39 A704 -8236CE30 A705 -8236CE31 A706 -8236CE32 A707 -8236CE33 A708 -8236CE34 A709 -8236CE35 A70A -8236CE36 A70B -8236CE37 A70C -8236CE38 A70D -8236CE39 A70E -8236CF30 A70F -8236CF31 A710 -8236CF32 A711 -8236CF33 A712 -8236CF34 A713 -8236CF35 A714 -8236CF36 A715 -8236CF37 A716 -8236CF38 A717 -8236CF39 A718 -8236D030 A719 -8236D031 A71A -8236D032 A71B -8236D033 A71C -8236D034 A71D -8236D035 A71E -8236D036 A71F -8236D037 A720 -8236D038 A721 -8236D039 A722 -8236D130 A723 -8236D131 A724 -8236D132 A725 -8236D133 A726 -8236D134 A727 -8236D135 A728 -8236D136 A729 -8236D137 A72A -8236D138 A72B -8236D139 A72C -8236D230 A72D -8236D231 A72E -8236D232 A72F -8236D233 A730 -8236D234 A731 -8236D235 A732 -8236D236 A733 -8236D237 A734 -8236D238 A735 -8236D239 A736 -8236D330 A737 -8236D331 A738 -8236D332 A739 -8236D333 A73A -8236D334 A73B -8236D335 A73C -8236D336 A73D -8236D337 A73E -8236D338 A73F -8236D339 A740 -8236D430 A741 -8236D431 A742 -8236D432 A743 -8236D433 A744 -8236D434 A745 -8236D435 A746 -8236D436 A747 -8236D437 A748 -8236D438 A749 -8236D439 A74A -8236D530 A74B -8236D531 A74C -8236D532 A74D -8236D533 A74E -8236D534 A74F -8236D535 A750 -8236D536 A751 -8236D537 A752 -8236D538 A753 -8236D539 A754 -8236D630 A755 -8236D631 A756 -8236D632 A757 -8236D633 A758 -8236D634 A759 -8236D635 A75A -8236D636 A75B -8236D637 A75C -8236D638 A75D -8236D639 A75E -8236D730 A75F -8236D731 A760 -8236D732 A761 -8236D733 A762 -8236D734 A763 -8236D735 A764 -8236D736 A765 -8236D737 A766 -8236D738 A767 -8236D739 A768 -8236D830 A769 -8236D831 A76A -8236D832 A76B -8236D833 A76C -8236D834 A76D -8236D835 A76E -8236D836 A76F -8236D837 A770 -8236D838 A771 -8236D839 A772 -8236D930 A773 -8236D931 A774 -8236D932 A775 -8236D933 A776 -8236D934 A777 -8236D935 A778 -8236D936 A779 -8236D937 A77A -8236D938 A77B -8236D939 A77C -8236DA30 A77D -8236DA31 A77E -8236DA32 A77F -8236DA33 A780 -8236DA34 A781 -8236DA35 A782 -8236DA36 A783 -8236DA37 A784 -8236DA38 A785 -8236DA39 A786 -8236DB30 A787 -8236DB31 A788 -8236DB32 A789 -8236DB33 A78A -8236DB34 A78B -8236DB35 A78C -8236DB36 A78D -8236DB37 A78E -8236DB38 A78F -8236DB39 A790 -8236DC30 A791 -8236DC31 A792 -8236DC32 A793 -8236DC33 A794 -8236DC34 A795 -8236DC35 A796 -8236DC36 A797 -8236DC37 A798 -8236DC38 A799 -8236DC39 A79A -8236DD30 A79B -8236DD31 A79C -8236DD32 A79D -8236DD33 A79E -8236DD34 A79F -8236DD35 A7A0 -8236DD36 A7A1 -8236DD37 A7A2 -8236DD38 A7A3 -8236DD39 A7A4 -8236DE30 A7A5 -8236DE31 A7A6 -8236DE32 A7A7 -8236DE33 A7A8 -8236DE34 A7A9 -8236DE35 A7AA -8236DE36 A7AB -8236DE37 A7AC -8236DE38 A7AD -8236DE39 A7AE -8236DF30 A7AF -8236DF31 A7B0 -8236DF32 A7B1 -8236DF33 A7B2 -8236DF34 A7B3 -8236DF35 A7B4 -8236DF36 A7B5 -8236DF37 A7B6 -8236DF38 A7B7 -8236DF39 A7B8 -8236E030 A7B9 -8236E031 A7BA -8236E032 A7BB -8236E033 A7BC -8236E034 A7BD -8236E035 A7BE -8236E036 A7BF -8236E037 A7C0 -8236E038 A7C1 -8236E039 A7C2 -8236E130 A7C3 -8236E131 A7C4 -8236E132 A7C5 -8236E133 A7C6 -8236E134 A7C7 -8236E135 A7C8 -8236E136 A7C9 -8236E137 A7CA -8236E138 A7CB -8236E139 A7CC -8236E230 A7CD -8236E231 A7CE -8236E232 A7CF -8236E233 A7D0 -8236E234 A7D1 -8236E235 A7D2 -8236E236 A7D3 -8236E237 A7D4 -8236E238 A7D5 -8236E239 A7D6 -8236E330 A7D7 -8236E331 A7D8 -8236E332 A7D9 -8236E333 A7DA -8236E334 A7DB -8236E335 A7DC -8236E336 A7DD -8236E337 A7DE -8236E338 A7DF -8236E339 A7E0 -8236E430 A7E1 -8236E431 A7E2 -8236E432 A7E3 -8236E433 A7E4 -8236E434 A7E5 -8236E435 A7E6 -8236E436 A7E7 -8236E437 A7E8 -8236E438 A7E9 -8236E439 A7EA -8236E530 A7EB -8236E531 A7EC -8236E532 A7ED -8236E533 A7EE -8236E534 A7EF -8236E535 A7F0 -8236E536 A7F1 -8236E537 A7F2 -8236E538 A7F3 -8236E539 A7F4 -8236E630 A7F5 -8236E631 A7F6 -8236E632 A7F7 -8236E633 A7F8 -8236E634 A7F9 -8236E635 A7FA -8236E636 A7FB -8236E637 A7FC -8236E638 A7FD -8236E639 A7FE -8236E730 A7FF -8236E731 A800 -8236E732 A801 -8236E733 A802 -8236E734 A803 -8236E735 A804 -8236E736 A805 -8236E737 A806 -8236E738 A807 -8236E739 A808 -8236E830 A809 -8236E831 A80A -8236E832 A80B -8236E833 A80C -8236E834 A80D -8236E835 A80E -8236E836 A80F -8236E837 A810 -8236E838 A811 -8236E839 A812 -8236E930 A813 -8236E931 A814 -8236E932 A815 -8236E933 A816 -8236E934 A817 -8236E935 A818 -8236E936 A819 -8236E937 A81A -8236E938 A81B -8236E939 A81C -8236EA30 A81D -8236EA31 A81E -8236EA32 A81F -8236EA33 A820 -8236EA34 A821 -8236EA35 A822 -8236EA36 A823 -8236EA37 A824 -8236EA38 A825 -8236EA39 A826 -8236EB30 A827 -8236EB31 A828 -8236EB32 A829 -8236EB33 A82A -8236EB34 A82B -8236EB35 A82C -8236EB36 A82D -8236EB37 A82E -8236EB38 A82F -8236EB39 A830 -8236EC30 A831 -8236EC31 A832 -8236EC32 A833 -8236EC33 A834 -8236EC34 A835 -8236EC35 A836 -8236EC36 A837 -8236EC37 A838 -8236EC38 A839 -8236EC39 A83A -8236ED30 A83B -8236ED31 A83C -8236ED32 A83D -8236ED33 A83E -8236ED34 A83F -8236ED35 A840 -8236ED36 A841 -8236ED37 A842 -8236ED38 A843 -8236ED39 A844 -8236EE30 A845 -8236EE31 A846 -8236EE32 A847 -8236EE33 A848 -8236EE34 A849 -8236EE35 A84A -8236EE36 A84B -8236EE37 A84C -8236EE38 A84D -8236EE39 A84E -8236EF30 A84F -8236EF31 A850 -8236EF32 A851 -8236EF33 A852 -8236EF34 A853 -8236EF35 A854 -8236EF36 A855 -8236EF37 A856 -8236EF38 A857 -8236EF39 A858 -8236F030 A859 -8236F031 A85A -8236F032 A85B -8236F033 A85C -8236F034 A85D -8236F035 A85E -8236F036 A85F -8236F037 A860 -8236F038 A861 -8236F039 A862 -8236F130 A863 -8236F131 A864 -8236F132 A865 -8236F133 A866 -8236F134 A867 -8236F135 A868 -8236F136 A869 -8236F137 A86A -8236F138 A86B -8236F139 A86C -8236F230 A86D -8236F231 A86E -8236F232 A86F -8236F233 A870 -8236F234 A871 -8236F235 A872 -8236F236 A873 -8236F237 A874 -8236F238 A875 -8236F239 A876 -8236F330 A877 -8236F331 A878 -8236F332 A879 -8236F333 A87A -8236F334 A87B -8236F335 A87C -8236F336 A87D -8236F337 A87E -8236F338 A87F -8236F339 A880 -8236F430 A881 -8236F431 A882 -8236F432 A883 -8236F433 A884 -8236F434 A885 -8236F435 A886 -8236F436 A887 -8236F437 A888 -8236F438 A889 -8236F439 A88A -8236F530 A88B -8236F531 A88C -8236F532 A88D -8236F533 A88E -8236F534 A88F -8236F535 A890 -8236F536 A891 -8236F537 A892 -8236F538 A893 -8236F539 A894 -8236F630 A895 -8236F631 A896 -8236F632 A897 -8236F633 A898 -8236F634 A899 -8236F635 A89A -8236F636 A89B -8236F637 A89C -8236F638 A89D -8236F639 A89E -8236F730 A89F -8236F731 A8A0 -8236F732 A8A1 -8236F733 A8A2 -8236F734 A8A3 -8236F735 A8A4 -8236F736 A8A5 -8236F737 A8A6 -8236F738 A8A7 -8236F739 A8A8 -8236F830 A8A9 -8236F831 A8AA -8236F832 A8AB -8236F833 A8AC -8236F834 A8AD -8236F835 A8AE -8236F836 A8AF -8236F837 A8B0 -8236F838 A8B1 -8236F839 A8B2 -8236F930 A8B3 -8236F931 A8B4 -8236F932 A8B5 -8236F933 A8B6 -8236F934 A8B7 -8236F935 A8B8 -8236F936 A8B9 -8236F937 A8BA -8236F938 A8BB -8236F939 A8BC -8236FA30 A8BD -8236FA31 A8BE -8236FA32 A8BF -8236FA33 A8C0 -8236FA34 A8C1 -8236FA35 A8C2 -8236FA36 A8C3 -8236FA37 A8C4 -8236FA38 A8C5 -8236FA39 A8C6 -8236FB30 A8C7 -8236FB31 A8C8 -8236FB32 A8C9 -8236FB33 A8CA -8236FB34 A8CB -8236FB35 A8CC -8236FB36 A8CD -8236FB37 A8CE -8236FB38 A8CF -8236FB39 A8D0 -8236FC30 A8D1 -8236FC31 A8D2 -8236FC32 A8D3 -8236FC33 A8D4 -8236FC34 A8D5 -8236FC35 A8D6 -8236FC36 A8D7 -8236FC37 A8D8 -8236FC38 A8D9 -8236FC39 A8DA -8236FD30 A8DB -8236FD31 A8DC -8236FD32 A8DD -8236FD33 A8DE -8236FD34 A8DF -8236FD35 A8E0 -8236FD36 A8E1 -8236FD37 A8E2 -8236FD38 A8E3 -8236FD39 A8E4 -8236FE30 A8E5 -8236FE31 A8E6 -8236FE32 A8E7 -8236FE33 A8E8 -8236FE34 A8E9 -8236FE35 A8EA -8236FE36 A8EB -8236FE37 A8EC -8236FE38 A8ED -8236FE39 A8EE -82378130 A8EF -82378131 A8F0 -82378132 A8F1 -82378133 A8F2 -82378134 A8F3 -82378135 A8F4 -82378136 A8F5 -82378137 A8F6 -82378138 A8F7 -82378139 A8F8 -82378230 A8F9 -82378231 A8FA -82378232 A8FB -82378233 A8FC -82378234 A8FD -82378235 A8FE -82378236 A8FF -82378237 A900 -82378238 A901 -82378239 A902 -82378330 A903 -82378331 A904 -82378332 A905 -82378333 A906 -82378334 A907 -82378335 A908 -82378336 A909 -82378337 A90A -82378338 A90B -82378339 A90C -82378430 A90D -82378431 A90E -82378432 A90F -82378433 A910 -82378434 A911 -82378435 A912 -82378436 A913 -82378437 A914 -82378438 A915 -82378439 A916 -82378530 A917 -82378531 A918 -82378532 A919 -82378533 A91A -82378534 A91B -82378535 A91C -82378536 A91D -82378537 A91E -82378538 A91F -82378539 A920 -82378630 A921 -82378631 A922 -82378632 A923 -82378633 A924 -82378634 A925 -82378635 A926 -82378636 A927 -82378637 A928 -82378638 A929 -82378639 A92A -82378730 A92B -82378731 A92C -82378732 A92D -82378733 A92E -82378734 A92F -82378735 A930 -82378736 A931 -82378737 A932 -82378738 A933 -82378739 A934 -82378830 A935 -82378831 A936 -82378832 A937 -82378833 A938 -82378834 A939 -82378835 A93A -82378836 A93B -82378837 A93C -82378838 A93D -82378839 A93E -82378930 A93F -82378931 A940 -82378932 A941 -82378933 A942 -82378934 A943 -82378935 A944 -82378936 A945 -82378937 A946 -82378938 A947 -82378939 A948 -82378A30 A949 -82378A31 A94A -82378A32 A94B -82378A33 A94C -82378A34 A94D -82378A35 A94E -82378A36 A94F -82378A37 A950 -82378A38 A951 -82378A39 A952 -82378B30 A953 -82378B31 A954 -82378B32 A955 -82378B33 A956 -82378B34 A957 -82378B35 A958 -82378B36 A959 -82378B37 A95A -82378B38 A95B -82378B39 A95C -82378C30 A95D -82378C31 A95E -82378C32 A95F -82378C33 A960 -82378C34 A961 -82378C35 A962 -82378C36 A963 -82378C37 A964 -82378C38 A965 -82378C39 A966 -82378D30 A967 -82378D31 A968 -82378D32 A969 -82378D33 A96A -82378D34 A96B -82378D35 A96C -82378D36 A96D -82378D37 A96E -82378D38 A96F -82378D39 A970 -82378E30 A971 -82378E31 A972 -82378E32 A973 -82378E33 A974 -82378E34 A975 -82378E35 A976 -82378E36 A977 -82378E37 A978 -82378E38 A979 -82378E39 A97A -82378F30 A97B -82378F31 A97C -82378F32 A97D -82378F33 A97E -82378F34 A97F -82378F35 A980 -82378F36 A981 -82378F37 A982 -82378F38 A983 -82378F39 A984 -82379030 A985 -82379031 A986 -82379032 A987 -82379033 A988 -82379034 A989 -82379035 A98A -82379036 A98B -82379037 A98C -82379038 A98D -82379039 A98E -82379130 A98F -82379131 A990 -82379132 A991 -82379133 A992 -82379134 A993 -82379135 A994 -82379136 A995 -82379137 A996 -82379138 A997 -82379139 A998 -82379230 A999 -82379231 A99A -82379232 A99B -82379233 A99C -82379234 A99D -82379235 A99E -82379236 A99F -82379237 A9A0 -82379238 A9A1 -82379239 A9A2 -82379330 A9A3 -82379331 A9A4 -82379332 A9A5 -82379333 A9A6 -82379334 A9A7 -82379335 A9A8 -82379336 A9A9 -82379337 A9AA -82379338 A9AB -82379339 A9AC -82379430 A9AD -82379431 A9AE -82379432 A9AF -82379433 A9B0 -82379434 A9B1 -82379435 A9B2 -82379436 A9B3 -82379437 A9B4 -82379438 A9B5 -82379439 A9B6 -82379530 A9B7 -82379531 A9B8 -82379532 A9B9 -82379533 A9BA -82379534 A9BB -82379535 A9BC -82379536 A9BD -82379537 A9BE -82379538 A9BF -82379539 A9C0 -82379630 A9C1 -82379631 A9C2 -82379632 A9C3 -82379633 A9C4 -82379634 A9C5 -82379635 A9C6 -82379636 A9C7 -82379637 A9C8 -82379638 A9C9 -82379639 A9CA -82379730 A9CB -82379731 A9CC -82379732 A9CD -82379733 A9CE -82379734 A9CF -82379735 A9D0 -82379736 A9D1 -82379737 A9D2 -82379738 A9D3 -82379739 A9D4 -82379830 A9D5 -82379831 A9D6 -82379832 A9D7 -82379833 A9D8 -82379834 A9D9 -82379835 A9DA -82379836 A9DB -82379837 A9DC -82379838 A9DD -82379839 A9DE -82379930 A9DF -82379931 A9E0 -82379932 A9E1 -82379933 A9E2 -82379934 A9E3 -82379935 A9E4 -82379936 A9E5 -82379937 A9E6 -82379938 A9E7 -82379939 A9E8 -82379A30 A9E9 -82379A31 A9EA -82379A32 A9EB -82379A33 A9EC -82379A34 A9ED -82379A35 A9EE -82379A36 A9EF -82379A37 A9F0 -82379A38 A9F1 -82379A39 A9F2 -82379B30 A9F3 -82379B31 A9F4 -82379B32 A9F5 -82379B33 A9F6 -82379B34 A9F7 -82379B35 A9F8 -82379B36 A9F9 -82379B37 A9FA -82379B38 A9FB -82379B39 A9FC -82379C30 A9FD -82379C31 A9FE -82379C32 A9FF -82379C33 AA00 -82379C34 AA01 -82379C35 AA02 -82379C36 AA03 -82379C37 AA04 -82379C38 AA05 -82379C39 AA06 -82379D30 AA07 -82379D31 AA08 -82379D32 AA09 -82379D33 AA0A -82379D34 AA0B -82379D35 AA0C -82379D36 AA0D -82379D37 AA0E -82379D38 AA0F -82379D39 AA10 -82379E30 AA11 -82379E31 AA12 -82379E32 AA13 -82379E33 AA14 -82379E34 AA15 -82379E35 AA16 -82379E36 AA17 -82379E37 AA18 -82379E38 AA19 -82379E39 AA1A -82379F30 AA1B -82379F31 AA1C -82379F32 AA1D -82379F33 AA1E -82379F34 AA1F -82379F35 AA20 -82379F36 AA21 -82379F37 AA22 -82379F38 AA23 -82379F39 AA24 -8237A030 AA25 -8237A031 AA26 -8237A032 AA27 -8237A033 AA28 -8237A034 AA29 -8237A035 AA2A -8237A036 AA2B -8237A037 AA2C -8237A038 AA2D -8237A039 AA2E -8237A130 AA2F -8237A131 AA30 -8237A132 AA31 -8237A133 AA32 -8237A134 AA33 -8237A135 AA34 -8237A136 AA35 -8237A137 AA36 -8237A138 AA37 -8237A139 AA38 -8237A230 AA39 -8237A231 AA3A -8237A232 AA3B -8237A233 AA3C -8237A234 AA3D -8237A235 AA3E -8237A236 AA3F -8237A237 AA40 -8237A238 AA41 -8237A239 AA42 -8237A330 AA43 -8237A331 AA44 -8237A332 AA45 -8237A333 AA46 -8237A334 AA47 -8237A335 AA48 -8237A336 AA49 -8237A337 AA4A -8237A338 AA4B -8237A339 AA4C -8237A430 AA4D -8237A431 AA4E -8237A432 AA4F -8237A433 AA50 -8237A434 AA51 -8237A435 AA52 -8237A436 AA53 -8237A437 AA54 -8237A438 AA55 -8237A439 AA56 -8237A530 AA57 -8237A531 AA58 -8237A532 AA59 -8237A533 AA5A -8237A534 AA5B -8237A535 AA5C -8237A536 AA5D -8237A537 AA5E -8237A538 AA5F -8237A539 AA60 -8237A630 AA61 -8237A631 AA62 -8237A632 AA63 -8237A633 AA64 -8237A634 AA65 -8237A635 AA66 -8237A636 AA67 -8237A637 AA68 -8237A638 AA69 -8237A639 AA6A -8237A730 AA6B -8237A731 AA6C -8237A732 AA6D -8237A733 AA6E -8237A734 AA6F -8237A735 AA70 -8237A736 AA71 -8237A737 AA72 -8237A738 AA73 -8237A739 AA74 -8237A830 AA75 -8237A831 AA76 -8237A832 AA77 -8237A833 AA78 -8237A834 AA79 -8237A835 AA7A -8237A836 AA7B -8237A837 AA7C -8237A838 AA7D -8237A839 AA7E -8237A930 AA7F -8237A931 AA80 -8237A932 AA81 -8237A933 AA82 -8237A934 AA83 -8237A935 AA84 -8237A936 AA85 -8237A937 AA86 -8237A938 AA87 -8237A939 AA88 -8237AA30 AA89 -8237AA31 AA8A -8237AA32 AA8B -8237AA33 AA8C -8237AA34 AA8D -8237AA35 AA8E -8237AA36 AA8F -8237AA37 AA90 -8237AA38 AA91 -8237AA39 AA92 -8237AB30 AA93 -8237AB31 AA94 -8237AB32 AA95 -8237AB33 AA96 -8237AB34 AA97 -8237AB35 AA98 -8237AB36 AA99 -8237AB37 AA9A -8237AB38 AA9B -8237AB39 AA9C -8237AC30 AA9D -8237AC31 AA9E -8237AC32 AA9F -8237AC33 AAA0 -8237AC34 AAA1 -8237AC35 AAA2 -8237AC36 AAA3 -8237AC37 AAA4 -8237AC38 AAA5 -8237AC39 AAA6 -8237AD30 AAA7 -8237AD31 AAA8 -8237AD32 AAA9 -8237AD33 AAAA -8237AD34 AAAB -8237AD35 AAAC -8237AD36 AAAD -8237AD37 AAAE -8237AD38 AAAF -8237AD39 AAB0 -8237AE30 AAB1 -8237AE31 AAB2 -8237AE32 AAB3 -8237AE33 AAB4 -8237AE34 AAB5 -8237AE35 AAB6 -8237AE36 AAB7 -8237AE37 AAB8 -8237AE38 AAB9 -8237AE39 AABA -8237AF30 AABB -8237AF31 AABC -8237AF32 AABD -8237AF33 AABE -8237AF34 AABF -8237AF35 AAC0 -8237AF36 AAC1 -8237AF37 AAC2 -8237AF38 AAC3 -8237AF39 AAC4 -8237B030 AAC5 -8237B031 AAC6 -8237B032 AAC7 -8237B033 AAC8 -8237B034 AAC9 -8237B035 AACA -8237B036 AACB -8237B037 AACC -8237B038 AACD -8237B039 AACE -8237B130 AACF -8237B131 AAD0 -8237B132 AAD1 -8237B133 AAD2 -8237B134 AAD3 -8237B135 AAD4 -8237B136 AAD5 -8237B137 AAD6 -8237B138 AAD7 -8237B139 AAD8 -8237B230 AAD9 -8237B231 AADA -8237B232 AADB -8237B233 AADC -8237B234 AADD -8237B235 AADE -8237B236 AADF -8237B237 AAE0 -8237B238 AAE1 -8237B239 AAE2 -8237B330 AAE3 -8237B331 AAE4 -8237B332 AAE5 -8237B333 AAE6 -8237B334 AAE7 -8237B335 AAE8 -8237B336 AAE9 -8237B337 AAEA -8237B338 AAEB -8237B339 AAEC -8237B430 AAED -8237B431 AAEE -8237B432 AAEF -8237B433 AAF0 -8237B434 AAF1 -8237B435 AAF2 -8237B436 AAF3 -8237B437 AAF4 -8237B438 AAF5 -8237B439 AAF6 -8237B530 AAF7 -8237B531 AAF8 -8237B532 AAF9 -8237B533 AAFA -8237B534 AAFB -8237B535 AAFC -8237B536 AAFD -8237B537 AAFE -8237B538 AAFF -8237B539 AB00 -8237B630 AB01 -8237B631 AB02 -8237B632 AB03 -8237B633 AB04 -8237B634 AB05 -8237B635 AB06 -8237B636 AB07 -8237B637 AB08 -8237B638 AB09 -8237B639 AB0A -8237B730 AB0B -8237B731 AB0C -8237B732 AB0D -8237B733 AB0E -8237B734 AB0F -8237B735 AB10 -8237B736 AB11 -8237B737 AB12 -8237B738 AB13 -8237B739 AB14 -8237B830 AB15 -8237B831 AB16 -8237B832 AB17 -8237B833 AB18 -8237B834 AB19 -8237B835 AB1A -8237B836 AB1B -8237B837 AB1C -8237B838 AB1D -8237B839 AB1E -8237B930 AB1F -8237B931 AB20 -8237B932 AB21 -8237B933 AB22 -8237B934 AB23 -8237B935 AB24 -8237B936 AB25 -8237B937 AB26 -8237B938 AB27 -8237B939 AB28 -8237BA30 AB29 -8237BA31 AB2A -8237BA32 AB2B -8237BA33 AB2C -8237BA34 AB2D -8237BA35 AB2E -8237BA36 AB2F -8237BA37 AB30 -8237BA38 AB31 -8237BA39 AB32 -8237BB30 AB33 -8237BB31 AB34 -8237BB32 AB35 -8237BB33 AB36 -8237BB34 AB37 -8237BB35 AB38 -8237BB36 AB39 -8237BB37 AB3A -8237BB38 AB3B -8237BB39 AB3C -8237BC30 AB3D -8237BC31 AB3E -8237BC32 AB3F -8237BC33 AB40 -8237BC34 AB41 -8237BC35 AB42 -8237BC36 AB43 -8237BC37 AB44 -8237BC38 AB45 -8237BC39 AB46 -8237BD30 AB47 -8237BD31 AB48 -8237BD32 AB49 -8237BD33 AB4A -8237BD34 AB4B -8237BD35 AB4C -8237BD36 AB4D -8237BD37 AB4E -8237BD38 AB4F -8237BD39 AB50 -8237BE30 AB51 -8237BE31 AB52 -8237BE32 AB53 -8237BE33 AB54 -8237BE34 AB55 -8237BE35 AB56 -8237BE36 AB57 -8237BE37 AB58 -8237BE38 AB59 -8237BE39 AB5A -8237BF30 AB5B -8237BF31 AB5C -8237BF32 AB5D -8237BF33 AB5E -8237BF34 AB5F -8237BF35 AB60 -8237BF36 AB61 -8237BF37 AB62 -8237BF38 AB63 -8237BF39 AB64 -8237C030 AB65 -8237C031 AB66 -8237C032 AB67 -8237C033 AB68 -8237C034 AB69 -8237C035 AB6A -8237C036 AB6B -8237C037 AB6C -8237C038 AB6D -8237C039 AB6E -8237C130 AB6F -8237C131 AB70 -8237C132 AB71 -8237C133 AB72 -8237C134 AB73 -8237C135 AB74 -8237C136 AB75 -8237C137 AB76 -8237C138 AB77 -8237C139 AB78 -8237C230 AB79 -8237C231 AB7A -8237C232 AB7B -8237C233 AB7C -8237C234 AB7D -8237C235 AB7E -8237C236 AB7F -8237C237 AB80 -8237C238 AB81 -8237C239 AB82 -8237C330 AB83 -8237C331 AB84 -8237C332 AB85 -8237C333 AB86 -8237C334 AB87 -8237C335 AB88 -8237C336 AB89 -8237C337 AB8A -8237C338 AB8B -8237C339 AB8C -8237C430 AB8D -8237C431 AB8E -8237C432 AB8F -8237C433 AB90 -8237C434 AB91 -8237C435 AB92 -8237C436 AB93 -8237C437 AB94 -8237C438 AB95 -8237C439 AB96 -8237C530 AB97 -8237C531 AB98 -8237C532 AB99 -8237C533 AB9A -8237C534 AB9B -8237C535 AB9C -8237C536 AB9D -8237C537 AB9E -8237C538 AB9F -8237C539 ABA0 -8237C630 ABA1 -8237C631 ABA2 -8237C632 ABA3 -8237C633 ABA4 -8237C634 ABA5 -8237C635 ABA6 -8237C636 ABA7 -8237C637 ABA8 -8237C638 ABA9 -8237C639 ABAA -8237C730 ABAB -8237C731 ABAC -8237C732 ABAD -8237C733 ABAE -8237C734 ABAF -8237C735 ABB0 -8237C736 ABB1 -8237C737 ABB2 -8237C738 ABB3 -8237C739 ABB4 -8237C830 ABB5 -8237C831 ABB6 -8237C832 ABB7 -8237C833 ABB8 -8237C834 ABB9 -8237C835 ABBA -8237C836 ABBB -8237C837 ABBC -8237C838 ABBD -8237C839 ABBE -8237C930 ABBF -8237C931 ABC0 -8237C932 ABC1 -8237C933 ABC2 -8237C934 ABC3 -8237C935 ABC4 -8237C936 ABC5 -8237C937 ABC6 -8237C938 ABC7 -8237C939 ABC8 -8237CA30 ABC9 -8237CA31 ABCA -8237CA32 ABCB -8237CA33 ABCC -8237CA34 ABCD -8237CA35 ABCE -8237CA36 ABCF -8237CA37 ABD0 -8237CA38 ABD1 -8237CA39 ABD2 -8237CB30 ABD3 -8237CB31 ABD4 -8237CB32 ABD5 -8237CB33 ABD6 -8237CB34 ABD7 -8237CB35 ABD8 -8237CB36 ABD9 -8237CB37 ABDA -8237CB38 ABDB -8237CB39 ABDC -8237CC30 ABDD -8237CC31 ABDE -8237CC32 ABDF -8237CC33 ABE0 -8237CC34 ABE1 -8237CC35 ABE2 -8237CC36 ABE3 -8237CC37 ABE4 -8237CC38 ABE5 -8237CC39 ABE6 -8237CD30 ABE7 -8237CD31 ABE8 -8237CD32 ABE9 -8237CD33 ABEA -8237CD34 ABEB -8237CD35 ABEC -8237CD36 ABED -8237CD37 ABEE -8237CD38 ABEF -8237CD39 ABF0 -8237CE30 ABF1 -8237CE31 ABF2 -8237CE32 ABF3 -8237CE33 ABF4 -8237CE34 ABF5 -8237CE35 ABF6 -8237CE36 ABF7 -8237CE37 ABF8 -8237CE38 ABF9 -8237CE39 ABFA -8237CF30 ABFB -8237CF31 ABFC -8237CF32 ABFD -8237CF33 ABFE -8237CF34 ABFF -8237CF35 AC00 -8237CF36 AC01 -8237CF37 AC02 -8237CF38 AC03 -8237CF39 AC04 -8237D030 AC05 -8237D031 AC06 -8237D032 AC07 -8237D033 AC08 -8237D034 AC09 -8237D035 AC0A -8237D036 AC0B -8237D037 AC0C -8237D038 AC0D -8237D039 AC0E -8237D130 AC0F -8237D131 AC10 -8237D132 AC11 -8237D133 AC12 -8237D134 AC13 -8237D135 AC14 -8237D136 AC15 -8237D137 AC16 -8237D138 AC17 -8237D139 AC18 -8237D230 AC19 -8237D231 AC1A -8237D232 AC1B -8237D233 AC1C -8237D234 AC1D -8237D235 AC1E -8237D236 AC1F -8237D237 AC20 -8237D238 AC21 -8237D239 AC22 -8237D330 AC23 -8237D331 AC24 -8237D332 AC25 -8237D333 AC26 -8237D334 AC27 -8237D335 AC28 -8237D336 AC29 -8237D337 AC2A -8237D338 AC2B -8237D339 AC2C -8237D430 AC2D -8237D431 AC2E -8237D432 AC2F -8237D433 AC30 -8237D434 AC31 -8237D435 AC32 -8237D436 AC33 -8237D437 AC34 -8237D438 AC35 -8237D439 AC36 -8237D530 AC37 -8237D531 AC38 -8237D532 AC39 -8237D533 AC3A -8237D534 AC3B -8237D535 AC3C -8237D536 AC3D -8237D537 AC3E -8237D538 AC3F -8237D539 AC40 -8237D630 AC41 -8237D631 AC42 -8237D632 AC43 -8237D633 AC44 -8237D634 AC45 -8237D635 AC46 -8237D636 AC47 -8237D637 AC48 -8237D638 AC49 -8237D639 AC4A -8237D730 AC4B -8237D731 AC4C -8237D732 AC4D -8237D733 AC4E -8237D734 AC4F -8237D735 AC50 -8237D736 AC51 -8237D737 AC52 -8237D738 AC53 -8237D739 AC54 -8237D830 AC55 -8237D831 AC56 -8237D832 AC57 -8237D833 AC58 -8237D834 AC59 -8237D835 AC5A -8237D836 AC5B -8237D837 AC5C -8237D838 AC5D -8237D839 AC5E -8237D930 AC5F -8237D931 AC60 -8237D932 AC61 -8237D933 AC62 -8237D934 AC63 -8237D935 AC64 -8237D936 AC65 -8237D937 AC66 -8237D938 AC67 -8237D939 AC68 -8237DA30 AC69 -8237DA31 AC6A -8237DA32 AC6B -8237DA33 AC6C -8237DA34 AC6D -8237DA35 AC6E -8237DA36 AC6F -8237DA37 AC70 -8237DA38 AC71 -8237DA39 AC72 -8237DB30 AC73 -8237DB31 AC74 -8237DB32 AC75 -8237DB33 AC76 -8237DB34 AC77 -8237DB35 AC78 -8237DB36 AC79 -8237DB37 AC7A -8237DB38 AC7B -8237DB39 AC7C -8237DC30 AC7D -8237DC31 AC7E -8237DC32 AC7F -8237DC33 AC80 -8237DC34 AC81 -8237DC35 AC82 -8237DC36 AC83 -8237DC37 AC84 -8237DC38 AC85 -8237DC39 AC86 -8237DD30 AC87 -8237DD31 AC88 -8237DD32 AC89 -8237DD33 AC8A -8237DD34 AC8B -8237DD35 AC8C -8237DD36 AC8D -8237DD37 AC8E -8237DD38 AC8F -8237DD39 AC90 -8237DE30 AC91 -8237DE31 AC92 -8237DE32 AC93 -8237DE33 AC94 -8237DE34 AC95 -8237DE35 AC96 -8237DE36 AC97 -8237DE37 AC98 -8237DE38 AC99 -8237DE39 AC9A -8237DF30 AC9B -8237DF31 AC9C -8237DF32 AC9D -8237DF33 AC9E -8237DF34 AC9F -8237DF35 ACA0 -8237DF36 ACA1 -8237DF37 ACA2 -8237DF38 ACA3 -8237DF39 ACA4 -8237E030 ACA5 -8237E031 ACA6 -8237E032 ACA7 -8237E033 ACA8 -8237E034 ACA9 -8237E035 ACAA -8237E036 ACAB -8237E037 ACAC -8237E038 ACAD -8237E039 ACAE -8237E130 ACAF -8237E131 ACB0 -8237E132 ACB1 -8237E133 ACB2 -8237E134 ACB3 -8237E135 ACB4 -8237E136 ACB5 -8237E137 ACB6 -8237E138 ACB7 -8237E139 ACB8 -8237E230 ACB9 -8237E231 ACBA -8237E232 ACBB -8237E233 ACBC -8237E234 ACBD -8237E235 ACBE -8237E236 ACBF -8237E237 ACC0 -8237E238 ACC1 -8237E239 ACC2 -8237E330 ACC3 -8237E331 ACC4 -8237E332 ACC5 -8237E333 ACC6 -8237E334 ACC7 -8237E335 ACC8 -8237E336 ACC9 -8237E337 ACCA -8237E338 ACCB -8237E339 ACCC -8237E430 ACCD -8237E431 ACCE -8237E432 ACCF -8237E433 ACD0 -8237E434 ACD1 -8237E435 ACD2 -8237E436 ACD3 -8237E437 ACD4 -8237E438 ACD5 -8237E439 ACD6 -8237E530 ACD7 -8237E531 ACD8 -8237E532 ACD9 -8237E533 ACDA -8237E534 ACDB -8237E535 ACDC -8237E536 ACDD -8237E537 ACDE -8237E538 ACDF -8237E539 ACE0 -8237E630 ACE1 -8237E631 ACE2 -8237E632 ACE3 -8237E633 ACE4 -8237E634 ACE5 -8237E635 ACE6 -8237E636 ACE7 -8237E637 ACE8 -8237E638 ACE9 -8237E639 ACEA -8237E730 ACEB -8237E731 ACEC -8237E732 ACED -8237E733 ACEE -8237E734 ACEF -8237E735 ACF0 -8237E736 ACF1 -8237E737 ACF2 -8237E738 ACF3 -8237E739 ACF4 -8237E830 ACF5 -8237E831 ACF6 -8237E832 ACF7 -8237E833 ACF8 -8237E834 ACF9 -8237E835 ACFA -8237E836 ACFB -8237E837 ACFC -8237E838 ACFD -8237E839 ACFE -8237E930 ACFF -8237E931 AD00 -8237E932 AD01 -8237E933 AD02 -8237E934 AD03 -8237E935 AD04 -8237E936 AD05 -8237E937 AD06 -8237E938 AD07 -8237E939 AD08 -8237EA30 AD09 -8237EA31 AD0A -8237EA32 AD0B -8237EA33 AD0C -8237EA34 AD0D -8237EA35 AD0E -8237EA36 AD0F -8237EA37 AD10 -8237EA38 AD11 -8237EA39 AD12 -8237EB30 AD13 -8237EB31 AD14 -8237EB32 AD15 -8237EB33 AD16 -8237EB34 AD17 -8237EB35 AD18 -8237EB36 AD19 -8237EB37 AD1A -8237EB38 AD1B -8237EB39 AD1C -8237EC30 AD1D -8237EC31 AD1E -8237EC32 AD1F -8237EC33 AD20 -8237EC34 AD21 -8237EC35 AD22 -8237EC36 AD23 -8237EC37 AD24 -8237EC38 AD25 -8237EC39 AD26 -8237ED30 AD27 -8237ED31 AD28 -8237ED32 AD29 -8237ED33 AD2A -8237ED34 AD2B -8237ED35 AD2C -8237ED36 AD2D -8237ED37 AD2E -8237ED38 AD2F -8237ED39 AD30 -8237EE30 AD31 -8237EE31 AD32 -8237EE32 AD33 -8237EE33 AD34 -8237EE34 AD35 -8237EE35 AD36 -8237EE36 AD37 -8237EE37 AD38 -8237EE38 AD39 -8237EE39 AD3A -8237EF30 AD3B -8237EF31 AD3C -8237EF32 AD3D -8237EF33 AD3E -8237EF34 AD3F -8237EF35 AD40 -8237EF36 AD41 -8237EF37 AD42 -8237EF38 AD43 -8237EF39 AD44 -8237F030 AD45 -8237F031 AD46 -8237F032 AD47 -8237F033 AD48 -8237F034 AD49 -8237F035 AD4A -8237F036 AD4B -8237F037 AD4C -8237F038 AD4D -8237F039 AD4E -8237F130 AD4F -8237F131 AD50 -8237F132 AD51 -8237F133 AD52 -8237F134 AD53 -8237F135 AD54 -8237F136 AD55 -8237F137 AD56 -8237F138 AD57 -8237F139 AD58 -8237F230 AD59 -8237F231 AD5A -8237F232 AD5B -8237F233 AD5C -8237F234 AD5D -8237F235 AD5E -8237F236 AD5F -8237F237 AD60 -8237F238 AD61 -8237F239 AD62 -8237F330 AD63 -8237F331 AD64 -8237F332 AD65 -8237F333 AD66 -8237F334 AD67 -8237F335 AD68 -8237F336 AD69 -8237F337 AD6A -8237F338 AD6B -8237F339 AD6C -8237F430 AD6D -8237F431 AD6E -8237F432 AD6F -8237F433 AD70 -8237F434 AD71 -8237F435 AD72 -8237F436 AD73 -8237F437 AD74 -8237F438 AD75 -8237F439 AD76 -8237F530 AD77 -8237F531 AD78 -8237F532 AD79 -8237F533 AD7A -8237F534 AD7B -8237F535 AD7C -8237F536 AD7D -8237F537 AD7E -8237F538 AD7F -8237F539 AD80 -8237F630 AD81 -8237F631 AD82 -8237F632 AD83 -8237F633 AD84 -8237F634 AD85 -8237F635 AD86 -8237F636 AD87 -8237F637 AD88 -8237F638 AD89 -8237F639 AD8A -8237F730 AD8B -8237F731 AD8C -8237F732 AD8D -8237F733 AD8E -8237F734 AD8F -8237F735 AD90 -8237F736 AD91 -8237F737 AD92 -8237F738 AD93 -8237F739 AD94 -8237F830 AD95 -8237F831 AD96 -8237F832 AD97 -8237F833 AD98 -8237F834 AD99 -8237F835 AD9A -8237F836 AD9B -8237F837 AD9C -8237F838 AD9D -8237F839 AD9E -8237F930 AD9F -8237F931 ADA0 -8237F932 ADA1 -8237F933 ADA2 -8237F934 ADA3 -8237F935 ADA4 -8237F936 ADA5 -8237F937 ADA6 -8237F938 ADA7 -8237F939 ADA8 -8237FA30 ADA9 -8237FA31 ADAA -8237FA32 ADAB -8237FA33 ADAC -8237FA34 ADAD -8237FA35 ADAE -8237FA36 ADAF -8237FA37 ADB0 -8237FA38 ADB1 -8237FA39 ADB2 -8237FB30 ADB3 -8237FB31 ADB4 -8237FB32 ADB5 -8237FB33 ADB6 -8237FB34 ADB7 -8237FB35 ADB8 -8237FB36 ADB9 -8237FB37 ADBA -8237FB38 ADBB -8237FB39 ADBC -8237FC30 ADBD -8237FC31 ADBE -8237FC32 ADBF -8237FC33 ADC0 -8237FC34 ADC1 -8237FC35 ADC2 -8237FC36 ADC3 -8237FC37 ADC4 -8237FC38 ADC5 -8237FC39 ADC6 -8237FD30 ADC7 -8237FD31 ADC8 -8237FD32 ADC9 -8237FD33 ADCA -8237FD34 ADCB -8237FD35 ADCC -8237FD36 ADCD -8237FD37 ADCE -8237FD38 ADCF -8237FD39 ADD0 -8237FE30 ADD1 -8237FE31 ADD2 -8237FE32 ADD3 -8237FE33 ADD4 -8237FE34 ADD5 -8237FE35 ADD6 -8237FE36 ADD7 -8237FE37 ADD8 -8237FE38 ADD9 -8237FE39 ADDA -82388130 ADDB -82388131 ADDC -82388132 ADDD -82388133 ADDE -82388134 ADDF -82388135 ADE0 -82388136 ADE1 -82388137 ADE2 -82388138 ADE3 -82388139 ADE4 -82388230 ADE5 -82388231 ADE6 -82388232 ADE7 -82388233 ADE8 -82388234 ADE9 -82388235 ADEA -82388236 ADEB -82388237 ADEC -82388238 ADED -82388239 ADEE -82388330 ADEF -82388331 ADF0 -82388332 ADF1 -82388333 ADF2 -82388334 ADF3 -82388335 ADF4 -82388336 ADF5 -82388337 ADF6 -82388338 ADF7 -82388339 ADF8 -82388430 ADF9 -82388431 ADFA -82388432 ADFB -82388433 ADFC -82388434 ADFD -82388435 ADFE -82388436 ADFF -82388437 AE00 -82388438 AE01 -82388439 AE02 -82388530 AE03 -82388531 AE04 -82388532 AE05 -82388533 AE06 -82388534 AE07 -82388535 AE08 -82388536 AE09 -82388537 AE0A -82388538 AE0B -82388539 AE0C -82388630 AE0D -82388631 AE0E -82388632 AE0F -82388633 AE10 -82388634 AE11 -82388635 AE12 -82388636 AE13 -82388637 AE14 -82388638 AE15 -82388639 AE16 -82388730 AE17 -82388731 AE18 -82388732 AE19 -82388733 AE1A -82388734 AE1B -82388735 AE1C -82388736 AE1D -82388737 AE1E -82388738 AE1F -82388739 AE20 -82388830 AE21 -82388831 AE22 -82388832 AE23 -82388833 AE24 -82388834 AE25 -82388835 AE26 -82388836 AE27 -82388837 AE28 -82388838 AE29 -82388839 AE2A -82388930 AE2B -82388931 AE2C -82388932 AE2D -82388933 AE2E -82388934 AE2F -82388935 AE30 -82388936 AE31 -82388937 AE32 -82388938 AE33 -82388939 AE34 -82388A30 AE35 -82388A31 AE36 -82388A32 AE37 -82388A33 AE38 -82388A34 AE39 -82388A35 AE3A -82388A36 AE3B -82388A37 AE3C -82388A38 AE3D -82388A39 AE3E -82388B30 AE3F -82388B31 AE40 -82388B32 AE41 -82388B33 AE42 -82388B34 AE43 -82388B35 AE44 -82388B36 AE45 -82388B37 AE46 -82388B38 AE47 -82388B39 AE48 -82388C30 AE49 -82388C31 AE4A -82388C32 AE4B -82388C33 AE4C -82388C34 AE4D -82388C35 AE4E -82388C36 AE4F -82388C37 AE50 -82388C38 AE51 -82388C39 AE52 -82388D30 AE53 -82388D31 AE54 -82388D32 AE55 -82388D33 AE56 -82388D34 AE57 -82388D35 AE58 -82388D36 AE59 -82388D37 AE5A -82388D38 AE5B -82388D39 AE5C -82388E30 AE5D -82388E31 AE5E -82388E32 AE5F -82388E33 AE60 -82388E34 AE61 -82388E35 AE62 -82388E36 AE63 -82388E37 AE64 -82388E38 AE65 -82388E39 AE66 -82388F30 AE67 -82388F31 AE68 -82388F32 AE69 -82388F33 AE6A -82388F34 AE6B -82388F35 AE6C -82388F36 AE6D -82388F37 AE6E -82388F38 AE6F -82388F39 AE70 -82389030 AE71 -82389031 AE72 -82389032 AE73 -82389033 AE74 -82389034 AE75 -82389035 AE76 -82389036 AE77 -82389037 AE78 -82389038 AE79 -82389039 AE7A -82389130 AE7B -82389131 AE7C -82389132 AE7D -82389133 AE7E -82389134 AE7F -82389135 AE80 -82389136 AE81 -82389137 AE82 -82389138 AE83 -82389139 AE84 -82389230 AE85 -82389231 AE86 -82389232 AE87 -82389233 AE88 -82389234 AE89 -82389235 AE8A -82389236 AE8B -82389237 AE8C -82389238 AE8D -82389239 AE8E -82389330 AE8F -82389331 AE90 -82389332 AE91 -82389333 AE92 -82389334 AE93 -82389335 AE94 -82389336 AE95 -82389337 AE96 -82389338 AE97 -82389339 AE98 -82389430 AE99 -82389431 AE9A -82389432 AE9B -82389433 AE9C -82389434 AE9D -82389435 AE9E -82389436 AE9F -82389437 AEA0 -82389438 AEA1 -82389439 AEA2 -82389530 AEA3 -82389531 AEA4 -82389532 AEA5 -82389533 AEA6 -82389534 AEA7 -82389535 AEA8 -82389536 AEA9 -82389537 AEAA -82389538 AEAB -82389539 AEAC -82389630 AEAD -82389631 AEAE -82389632 AEAF -82389633 AEB0 -82389634 AEB1 -82389635 AEB2 -82389636 AEB3 -82389637 AEB4 -82389638 AEB5 -82389639 AEB6 -82389730 AEB7 -82389731 AEB8 -82389732 AEB9 -82389733 AEBA -82389734 AEBB -82389735 AEBC -82389736 AEBD -82389737 AEBE -82389738 AEBF -82389739 AEC0 -82389830 AEC1 -82389831 AEC2 -82389832 AEC3 -82389833 AEC4 -82389834 AEC5 -82389835 AEC6 -82389836 AEC7 -82389837 AEC8 -82389838 AEC9 -82389839 AECA -82389930 AECB -82389931 AECC -82389932 AECD -82389933 AECE -82389934 AECF -82389935 AED0 -82389936 AED1 -82389937 AED2 -82389938 AED3 -82389939 AED4 -82389A30 AED5 -82389A31 AED6 -82389A32 AED7 -82389A33 AED8 -82389A34 AED9 -82389A35 AEDA -82389A36 AEDB -82389A37 AEDC -82389A38 AEDD -82389A39 AEDE -82389B30 AEDF -82389B31 AEE0 -82389B32 AEE1 -82389B33 AEE2 -82389B34 AEE3 -82389B35 AEE4 -82389B36 AEE5 -82389B37 AEE6 -82389B38 AEE7 -82389B39 AEE8 -82389C30 AEE9 -82389C31 AEEA -82389C32 AEEB -82389C33 AEEC -82389C34 AEED -82389C35 AEEE -82389C36 AEEF -82389C37 AEF0 -82389C38 AEF1 -82389C39 AEF2 -82389D30 AEF3 -82389D31 AEF4 -82389D32 AEF5 -82389D33 AEF6 -82389D34 AEF7 -82389D35 AEF8 -82389D36 AEF9 -82389D37 AEFA -82389D38 AEFB -82389D39 AEFC -82389E30 AEFD -82389E31 AEFE -82389E32 AEFF -82389E33 AF00 -82389E34 AF01 -82389E35 AF02 -82389E36 AF03 -82389E37 AF04 -82389E38 AF05 -82389E39 AF06 -82389F30 AF07 -82389F31 AF08 -82389F32 AF09 -82389F33 AF0A -82389F34 AF0B -82389F35 AF0C -82389F36 AF0D -82389F37 AF0E -82389F38 AF0F -82389F39 AF10 -8238A030 AF11 -8238A031 AF12 -8238A032 AF13 -8238A033 AF14 -8238A034 AF15 -8238A035 AF16 -8238A036 AF17 -8238A037 AF18 -8238A038 AF19 -8238A039 AF1A -8238A130 AF1B -8238A131 AF1C -8238A132 AF1D -8238A133 AF1E -8238A134 AF1F -8238A135 AF20 -8238A136 AF21 -8238A137 AF22 -8238A138 AF23 -8238A139 AF24 -8238A230 AF25 -8238A231 AF26 -8238A232 AF27 -8238A233 AF28 -8238A234 AF29 -8238A235 AF2A -8238A236 AF2B -8238A237 AF2C -8238A238 AF2D -8238A239 AF2E -8238A330 AF2F -8238A331 AF30 -8238A332 AF31 -8238A333 AF32 -8238A334 AF33 -8238A335 AF34 -8238A336 AF35 -8238A337 AF36 -8238A338 AF37 -8238A339 AF38 -8238A430 AF39 -8238A431 AF3A -8238A432 AF3B -8238A433 AF3C -8238A434 AF3D -8238A435 AF3E -8238A436 AF3F -8238A437 AF40 -8238A438 AF41 -8238A439 AF42 -8238A530 AF43 -8238A531 AF44 -8238A532 AF45 -8238A533 AF46 -8238A534 AF47 -8238A535 AF48 -8238A536 AF49 -8238A537 AF4A -8238A538 AF4B -8238A539 AF4C -8238A630 AF4D -8238A631 AF4E -8238A632 AF4F -8238A633 AF50 -8238A634 AF51 -8238A635 AF52 -8238A636 AF53 -8238A637 AF54 -8238A638 AF55 -8238A639 AF56 -8238A730 AF57 -8238A731 AF58 -8238A732 AF59 -8238A733 AF5A -8238A734 AF5B -8238A735 AF5C -8238A736 AF5D -8238A737 AF5E -8238A738 AF5F -8238A739 AF60 -8238A830 AF61 -8238A831 AF62 -8238A832 AF63 -8238A833 AF64 -8238A834 AF65 -8238A835 AF66 -8238A836 AF67 -8238A837 AF68 -8238A838 AF69 -8238A839 AF6A -8238A930 AF6B -8238A931 AF6C -8238A932 AF6D -8238A933 AF6E -8238A934 AF6F -8238A935 AF70 -8238A936 AF71 -8238A937 AF72 -8238A938 AF73 -8238A939 AF74 -8238AA30 AF75 -8238AA31 AF76 -8238AA32 AF77 -8238AA33 AF78 -8238AA34 AF79 -8238AA35 AF7A -8238AA36 AF7B -8238AA37 AF7C -8238AA38 AF7D -8238AA39 AF7E -8238AB30 AF7F -8238AB31 AF80 -8238AB32 AF81 -8238AB33 AF82 -8238AB34 AF83 -8238AB35 AF84 -8238AB36 AF85 -8238AB37 AF86 -8238AB38 AF87 -8238AB39 AF88 -8238AC30 AF89 -8238AC31 AF8A -8238AC32 AF8B -8238AC33 AF8C -8238AC34 AF8D -8238AC35 AF8E -8238AC36 AF8F -8238AC37 AF90 -8238AC38 AF91 -8238AC39 AF92 -8238AD30 AF93 -8238AD31 AF94 -8238AD32 AF95 -8238AD33 AF96 -8238AD34 AF97 -8238AD35 AF98 -8238AD36 AF99 -8238AD37 AF9A -8238AD38 AF9B -8238AD39 AF9C -8238AE30 AF9D -8238AE31 AF9E -8238AE32 AF9F -8238AE33 AFA0 -8238AE34 AFA1 -8238AE35 AFA2 -8238AE36 AFA3 -8238AE37 AFA4 -8238AE38 AFA5 -8238AE39 AFA6 -8238AF30 AFA7 -8238AF31 AFA8 -8238AF32 AFA9 -8238AF33 AFAA -8238AF34 AFAB -8238AF35 AFAC -8238AF36 AFAD -8238AF37 AFAE -8238AF38 AFAF -8238AF39 AFB0 -8238B030 AFB1 -8238B031 AFB2 -8238B032 AFB3 -8238B033 AFB4 -8238B034 AFB5 -8238B035 AFB6 -8238B036 AFB7 -8238B037 AFB8 -8238B038 AFB9 -8238B039 AFBA -8238B130 AFBB -8238B131 AFBC -8238B132 AFBD -8238B133 AFBE -8238B134 AFBF -8238B135 AFC0 -8238B136 AFC1 -8238B137 AFC2 -8238B138 AFC3 -8238B139 AFC4 -8238B230 AFC5 -8238B231 AFC6 -8238B232 AFC7 -8238B233 AFC8 -8238B234 AFC9 -8238B235 AFCA -8238B236 AFCB -8238B237 AFCC -8238B238 AFCD -8238B239 AFCE -8238B330 AFCF -8238B331 AFD0 -8238B332 AFD1 -8238B333 AFD2 -8238B334 AFD3 -8238B335 AFD4 -8238B336 AFD5 -8238B337 AFD6 -8238B338 AFD7 -8238B339 AFD8 -8238B430 AFD9 -8238B431 AFDA -8238B432 AFDB -8238B433 AFDC -8238B434 AFDD -8238B435 AFDE -8238B436 AFDF -8238B437 AFE0 -8238B438 AFE1 -8238B439 AFE2 -8238B530 AFE3 -8238B531 AFE4 -8238B532 AFE5 -8238B533 AFE6 -8238B534 AFE7 -8238B535 AFE8 -8238B536 AFE9 -8238B537 AFEA -8238B538 AFEB -8238B539 AFEC -8238B630 AFED -8238B631 AFEE -8238B632 AFEF -8238B633 AFF0 -8238B634 AFF1 -8238B635 AFF2 -8238B636 AFF3 -8238B637 AFF4 -8238B638 AFF5 -8238B639 AFF6 -8238B730 AFF7 -8238B731 AFF8 -8238B732 AFF9 -8238B733 AFFA -8238B734 AFFB -8238B735 AFFC -8238B736 AFFD -8238B737 AFFE -8238B738 AFFF -8238B739 B000 -8238B830 B001 -8238B831 B002 -8238B832 B003 -8238B833 B004 -8238B834 B005 -8238B835 B006 -8238B836 B007 -8238B837 B008 -8238B838 B009 -8238B839 B00A -8238B930 B00B -8238B931 B00C -8238B932 B00D -8238B933 B00E -8238B934 B00F -8238B935 B010 -8238B936 B011 -8238B937 B012 -8238B938 B013 -8238B939 B014 -8238BA30 B015 -8238BA31 B016 -8238BA32 B017 -8238BA33 B018 -8238BA34 B019 -8238BA35 B01A -8238BA36 B01B -8238BA37 B01C -8238BA38 B01D -8238BA39 B01E -8238BB30 B01F -8238BB31 B020 -8238BB32 B021 -8238BB33 B022 -8238BB34 B023 -8238BB35 B024 -8238BB36 B025 -8238BB37 B026 -8238BB38 B027 -8238BB39 B028 -8238BC30 B029 -8238BC31 B02A -8238BC32 B02B -8238BC33 B02C -8238BC34 B02D -8238BC35 B02E -8238BC36 B02F -8238BC37 B030 -8238BC38 B031 -8238BC39 B032 -8238BD30 B033 -8238BD31 B034 -8238BD32 B035 -8238BD33 B036 -8238BD34 B037 -8238BD35 B038 -8238BD36 B039 -8238BD37 B03A -8238BD38 B03B -8238BD39 B03C -8238BE30 B03D -8238BE31 B03E -8238BE32 B03F -8238BE33 B040 -8238BE34 B041 -8238BE35 B042 -8238BE36 B043 -8238BE37 B044 -8238BE38 B045 -8238BE39 B046 -8238BF30 B047 -8238BF31 B048 -8238BF32 B049 -8238BF33 B04A -8238BF34 B04B -8238BF35 B04C -8238BF36 B04D -8238BF37 B04E -8238BF38 B04F -8238BF39 B050 -8238C030 B051 -8238C031 B052 -8238C032 B053 -8238C033 B054 -8238C034 B055 -8238C035 B056 -8238C036 B057 -8238C037 B058 -8238C038 B059 -8238C039 B05A -8238C130 B05B -8238C131 B05C -8238C132 B05D -8238C133 B05E -8238C134 B05F -8238C135 B060 -8238C136 B061 -8238C137 B062 -8238C138 B063 -8238C139 B064 -8238C230 B065 -8238C231 B066 -8238C232 B067 -8238C233 B068 -8238C234 B069 -8238C235 B06A -8238C236 B06B -8238C237 B06C -8238C238 B06D -8238C239 B06E -8238C330 B06F -8238C331 B070 -8238C332 B071 -8238C333 B072 -8238C334 B073 -8238C335 B074 -8238C336 B075 -8238C337 B076 -8238C338 B077 -8238C339 B078 -8238C430 B079 -8238C431 B07A -8238C432 B07B -8238C433 B07C -8238C434 B07D -8238C435 B07E -8238C436 B07F -8238C437 B080 -8238C438 B081 -8238C439 B082 -8238C530 B083 -8238C531 B084 -8238C532 B085 -8238C533 B086 -8238C534 B087 -8238C535 B088 -8238C536 B089 -8238C537 B08A -8238C538 B08B -8238C539 B08C -8238C630 B08D -8238C631 B08E -8238C632 B08F -8238C633 B090 -8238C634 B091 -8238C635 B092 -8238C636 B093 -8238C637 B094 -8238C638 B095 -8238C639 B096 -8238C730 B097 -8238C731 B098 -8238C732 B099 -8238C733 B09A -8238C734 B09B -8238C735 B09C -8238C736 B09D -8238C737 B09E -8238C738 B09F -8238C739 B0A0 -8238C830 B0A1 -8238C831 B0A2 -8238C832 B0A3 -8238C833 B0A4 -8238C834 B0A5 -8238C835 B0A6 -8238C836 B0A7 -8238C837 B0A8 -8238C838 B0A9 -8238C839 B0AA -8238C930 B0AB -8238C931 B0AC -8238C932 B0AD -8238C933 B0AE -8238C934 B0AF -8238C935 B0B0 -8238C936 B0B1 -8238C937 B0B2 -8238C938 B0B3 -8238C939 B0B4 -8238CA30 B0B5 -8238CA31 B0B6 -8238CA32 B0B7 -8238CA33 B0B8 -8238CA34 B0B9 -8238CA35 B0BA -8238CA36 B0BB -8238CA37 B0BC -8238CA38 B0BD -8238CA39 B0BE -8238CB30 B0BF -8238CB31 B0C0 -8238CB32 B0C1 -8238CB33 B0C2 -8238CB34 B0C3 -8238CB35 B0C4 -8238CB36 B0C5 -8238CB37 B0C6 -8238CB38 B0C7 -8238CB39 B0C8 -8238CC30 B0C9 -8238CC31 B0CA -8238CC32 B0CB -8238CC33 B0CC -8238CC34 B0CD -8238CC35 B0CE -8238CC36 B0CF -8238CC37 B0D0 -8238CC38 B0D1 -8238CC39 B0D2 -8238CD30 B0D3 -8238CD31 B0D4 -8238CD32 B0D5 -8238CD33 B0D6 -8238CD34 B0D7 -8238CD35 B0D8 -8238CD36 B0D9 -8238CD37 B0DA -8238CD38 B0DB -8238CD39 B0DC -8238CE30 B0DD -8238CE31 B0DE -8238CE32 B0DF -8238CE33 B0E0 -8238CE34 B0E1 -8238CE35 B0E2 -8238CE36 B0E3 -8238CE37 B0E4 -8238CE38 B0E5 -8238CE39 B0E6 -8238CF30 B0E7 -8238CF31 B0E8 -8238CF32 B0E9 -8238CF33 B0EA -8238CF34 B0EB -8238CF35 B0EC -8238CF36 B0ED -8238CF37 B0EE -8238CF38 B0EF -8238CF39 B0F0 -8238D030 B0F1 -8238D031 B0F2 -8238D032 B0F3 -8238D033 B0F4 -8238D034 B0F5 -8238D035 B0F6 -8238D036 B0F7 -8238D037 B0F8 -8238D038 B0F9 -8238D039 B0FA -8238D130 B0FB -8238D131 B0FC -8238D132 B0FD -8238D133 B0FE -8238D134 B0FF -8238D135 B100 -8238D136 B101 -8238D137 B102 -8238D138 B103 -8238D139 B104 -8238D230 B105 -8238D231 B106 -8238D232 B107 -8238D233 B108 -8238D234 B109 -8238D235 B10A -8238D236 B10B -8238D237 B10C -8238D238 B10D -8238D239 B10E -8238D330 B10F -8238D331 B110 -8238D332 B111 -8238D333 B112 -8238D334 B113 -8238D335 B114 -8238D336 B115 -8238D337 B116 -8238D338 B117 -8238D339 B118 -8238D430 B119 -8238D431 B11A -8238D432 B11B -8238D433 B11C -8238D434 B11D -8238D435 B11E -8238D436 B11F -8238D437 B120 -8238D438 B121 -8238D439 B122 -8238D530 B123 -8238D531 B124 -8238D532 B125 -8238D533 B126 -8238D534 B127 -8238D535 B128 -8238D536 B129 -8238D537 B12A -8238D538 B12B -8238D539 B12C -8238D630 B12D -8238D631 B12E -8238D632 B12F -8238D633 B130 -8238D634 B131 -8238D635 B132 -8238D636 B133 -8238D637 B134 -8238D638 B135 -8238D639 B136 -8238D730 B137 -8238D731 B138 -8238D732 B139 -8238D733 B13A -8238D734 B13B -8238D735 B13C -8238D736 B13D -8238D737 B13E -8238D738 B13F -8238D739 B140 -8238D830 B141 -8238D831 B142 -8238D832 B143 -8238D833 B144 -8238D834 B145 -8238D835 B146 -8238D836 B147 -8238D837 B148 -8238D838 B149 -8238D839 B14A -8238D930 B14B -8238D931 B14C -8238D932 B14D -8238D933 B14E -8238D934 B14F -8238D935 B150 -8238D936 B151 -8238D937 B152 -8238D938 B153 -8238D939 B154 -8238DA30 B155 -8238DA31 B156 -8238DA32 B157 -8238DA33 B158 -8238DA34 B159 -8238DA35 B15A -8238DA36 B15B -8238DA37 B15C -8238DA38 B15D -8238DA39 B15E -8238DB30 B15F -8238DB31 B160 -8238DB32 B161 -8238DB33 B162 -8238DB34 B163 -8238DB35 B164 -8238DB36 B165 -8238DB37 B166 -8238DB38 B167 -8238DB39 B168 -8238DC30 B169 -8238DC31 B16A -8238DC32 B16B -8238DC33 B16C -8238DC34 B16D -8238DC35 B16E -8238DC36 B16F -8238DC37 B170 -8238DC38 B171 -8238DC39 B172 -8238DD30 B173 -8238DD31 B174 -8238DD32 B175 -8238DD33 B176 -8238DD34 B177 -8238DD35 B178 -8238DD36 B179 -8238DD37 B17A -8238DD38 B17B -8238DD39 B17C -8238DE30 B17D -8238DE31 B17E -8238DE32 B17F -8238DE33 B180 -8238DE34 B181 -8238DE35 B182 -8238DE36 B183 -8238DE37 B184 -8238DE38 B185 -8238DE39 B186 -8238DF30 B187 -8238DF31 B188 -8238DF32 B189 -8238DF33 B18A -8238DF34 B18B -8238DF35 B18C -8238DF36 B18D -8238DF37 B18E -8238DF38 B18F -8238DF39 B190 -8238E030 B191 -8238E031 B192 -8238E032 B193 -8238E033 B194 -8238E034 B195 -8238E035 B196 -8238E036 B197 -8238E037 B198 -8238E038 B199 -8238E039 B19A -8238E130 B19B -8238E131 B19C -8238E132 B19D -8238E133 B19E -8238E134 B19F -8238E135 B1A0 -8238E136 B1A1 -8238E137 B1A2 -8238E138 B1A3 -8238E139 B1A4 -8238E230 B1A5 -8238E231 B1A6 -8238E232 B1A7 -8238E233 B1A8 -8238E234 B1A9 -8238E235 B1AA -8238E236 B1AB -8238E237 B1AC -8238E238 B1AD -8238E239 B1AE -8238E330 B1AF -8238E331 B1B0 -8238E332 B1B1 -8238E333 B1B2 -8238E334 B1B3 -8238E335 B1B4 -8238E336 B1B5 -8238E337 B1B6 -8238E338 B1B7 -8238E339 B1B8 -8238E430 B1B9 -8238E431 B1BA -8238E432 B1BB -8238E433 B1BC -8238E434 B1BD -8238E435 B1BE -8238E436 B1BF -8238E437 B1C0 -8238E438 B1C1 -8238E439 B1C2 -8238E530 B1C3 -8238E531 B1C4 -8238E532 B1C5 -8238E533 B1C6 -8238E534 B1C7 -8238E535 B1C8 -8238E536 B1C9 -8238E537 B1CA -8238E538 B1CB -8238E539 B1CC -8238E630 B1CD -8238E631 B1CE -8238E632 B1CF -8238E633 B1D0 -8238E634 B1D1 -8238E635 B1D2 -8238E636 B1D3 -8238E637 B1D4 -8238E638 B1D5 -8238E639 B1D6 -8238E730 B1D7 -8238E731 B1D8 -8238E732 B1D9 -8238E733 B1DA -8238E734 B1DB -8238E735 B1DC -8238E736 B1DD -8238E737 B1DE -8238E738 B1DF -8238E739 B1E0 -8238E830 B1E1 -8238E831 B1E2 -8238E832 B1E3 -8238E833 B1E4 -8238E834 B1E5 -8238E835 B1E6 -8238E836 B1E7 -8238E837 B1E8 -8238E838 B1E9 -8238E839 B1EA -8238E930 B1EB -8238E931 B1EC -8238E932 B1ED -8238E933 B1EE -8238E934 B1EF -8238E935 B1F0 -8238E936 B1F1 -8238E937 B1F2 -8238E938 B1F3 -8238E939 B1F4 -8238EA30 B1F5 -8238EA31 B1F6 -8238EA32 B1F7 -8238EA33 B1F8 -8238EA34 B1F9 -8238EA35 B1FA -8238EA36 B1FB -8238EA37 B1FC -8238EA38 B1FD -8238EA39 B1FE -8238EB30 B1FF -8238EB31 B200 -8238EB32 B201 -8238EB33 B202 -8238EB34 B203 -8238EB35 B204 -8238EB36 B205 -8238EB37 B206 -8238EB38 B207 -8238EB39 B208 -8238EC30 B209 -8238EC31 B20A -8238EC32 B20B -8238EC33 B20C -8238EC34 B20D -8238EC35 B20E -8238EC36 B20F -8238EC37 B210 -8238EC38 B211 -8238EC39 B212 -8238ED30 B213 -8238ED31 B214 -8238ED32 B215 -8238ED33 B216 -8238ED34 B217 -8238ED35 B218 -8238ED36 B219 -8238ED37 B21A -8238ED38 B21B -8238ED39 B21C -8238EE30 B21D -8238EE31 B21E -8238EE32 B21F -8238EE33 B220 -8238EE34 B221 -8238EE35 B222 -8238EE36 B223 -8238EE37 B224 -8238EE38 B225 -8238EE39 B226 -8238EF30 B227 -8238EF31 B228 -8238EF32 B229 -8238EF33 B22A -8238EF34 B22B -8238EF35 B22C -8238EF36 B22D -8238EF37 B22E -8238EF38 B22F -8238EF39 B230 -8238F030 B231 -8238F031 B232 -8238F032 B233 -8238F033 B234 -8238F034 B235 -8238F035 B236 -8238F036 B237 -8238F037 B238 -8238F038 B239 -8238F039 B23A -8238F130 B23B -8238F131 B23C -8238F132 B23D -8238F133 B23E -8238F134 B23F -8238F135 B240 -8238F136 B241 -8238F137 B242 -8238F138 B243 -8238F139 B244 -8238F230 B245 -8238F231 B246 -8238F232 B247 -8238F233 B248 -8238F234 B249 -8238F235 B24A -8238F236 B24B -8238F237 B24C -8238F238 B24D -8238F239 B24E -8238F330 B24F -8238F331 B250 -8238F332 B251 -8238F333 B252 -8238F334 B253 -8238F335 B254 -8238F336 B255 -8238F337 B256 -8238F338 B257 -8238F339 B258 -8238F430 B259 -8238F431 B25A -8238F432 B25B -8238F433 B25C -8238F434 B25D -8238F435 B25E -8238F436 B25F -8238F437 B260 -8238F438 B261 -8238F439 B262 -8238F530 B263 -8238F531 B264 -8238F532 B265 -8238F533 B266 -8238F534 B267 -8238F535 B268 -8238F536 B269 -8238F537 B26A -8238F538 B26B -8238F539 B26C -8238F630 B26D -8238F631 B26E -8238F632 B26F -8238F633 B270 -8238F634 B271 -8238F635 B272 -8238F636 B273 -8238F637 B274 -8238F638 B275 -8238F639 B276 -8238F730 B277 -8238F731 B278 -8238F732 B279 -8238F733 B27A -8238F734 B27B -8238F735 B27C -8238F736 B27D -8238F737 B27E -8238F738 B27F -8238F739 B280 -8238F830 B281 -8238F831 B282 -8238F832 B283 -8238F833 B284 -8238F834 B285 -8238F835 B286 -8238F836 B287 -8238F837 B288 -8238F838 B289 -8238F839 B28A -8238F930 B28B -8238F931 B28C -8238F932 B28D -8238F933 B28E -8238F934 B28F -8238F935 B290 -8238F936 B291 -8238F937 B292 -8238F938 B293 -8238F939 B294 -8238FA30 B295 -8238FA31 B296 -8238FA32 B297 -8238FA33 B298 -8238FA34 B299 -8238FA35 B29A -8238FA36 B29B -8238FA37 B29C -8238FA38 B29D -8238FA39 B29E -8238FB30 B29F -8238FB31 B2A0 -8238FB32 B2A1 -8238FB33 B2A2 -8238FB34 B2A3 -8238FB35 B2A4 -8238FB36 B2A5 -8238FB37 B2A6 -8238FB38 B2A7 -8238FB39 B2A8 -8238FC30 B2A9 -8238FC31 B2AA -8238FC32 B2AB -8238FC33 B2AC -8238FC34 B2AD -8238FC35 B2AE -8238FC36 B2AF -8238FC37 B2B0 -8238FC38 B2B1 -8238FC39 B2B2 -8238FD30 B2B3 -8238FD31 B2B4 -8238FD32 B2B5 -8238FD33 B2B6 -8238FD34 B2B7 -8238FD35 B2B8 -8238FD36 B2B9 -8238FD37 B2BA -8238FD38 B2BB -8238FD39 B2BC -8238FE30 B2BD -8238FE31 B2BE -8238FE32 B2BF -8238FE33 B2C0 -8238FE34 B2C1 -8238FE35 B2C2 -8238FE36 B2C3 -8238FE37 B2C4 -8238FE38 B2C5 -8238FE39 B2C6 -82398130 B2C7 -82398131 B2C8 -82398132 B2C9 -82398133 B2CA -82398134 B2CB -82398135 B2CC -82398136 B2CD -82398137 B2CE -82398138 B2CF -82398139 B2D0 -82398230 B2D1 -82398231 B2D2 -82398232 B2D3 -82398233 B2D4 -82398234 B2D5 -82398235 B2D6 -82398236 B2D7 -82398237 B2D8 -82398238 B2D9 -82398239 B2DA -82398330 B2DB -82398331 B2DC -82398332 B2DD -82398333 B2DE -82398334 B2DF -82398335 B2E0 -82398336 B2E1 -82398337 B2E2 -82398338 B2E3 -82398339 B2E4 -82398430 B2E5 -82398431 B2E6 -82398432 B2E7 -82398433 B2E8 -82398434 B2E9 -82398435 B2EA -82398436 B2EB -82398437 B2EC -82398438 B2ED -82398439 B2EE -82398530 B2EF -82398531 B2F0 -82398532 B2F1 -82398533 B2F2 -82398534 B2F3 -82398535 B2F4 -82398536 B2F5 -82398537 B2F6 -82398538 B2F7 -82398539 B2F8 -82398630 B2F9 -82398631 B2FA -82398632 B2FB -82398633 B2FC -82398634 B2FD -82398635 B2FE -82398636 B2FF -82398637 B300 -82398638 B301 -82398639 B302 -82398730 B303 -82398731 B304 -82398732 B305 -82398733 B306 -82398734 B307 -82398735 B308 -82398736 B309 -82398737 B30A -82398738 B30B -82398739 B30C -82398830 B30D -82398831 B30E -82398832 B30F -82398833 B310 -82398834 B311 -82398835 B312 -82398836 B313 -82398837 B314 -82398838 B315 -82398839 B316 -82398930 B317 -82398931 B318 -82398932 B319 -82398933 B31A -82398934 B31B -82398935 B31C -82398936 B31D -82398937 B31E -82398938 B31F -82398939 B320 -82398A30 B321 -82398A31 B322 -82398A32 B323 -82398A33 B324 -82398A34 B325 -82398A35 B326 -82398A36 B327 -82398A37 B328 -82398A38 B329 -82398A39 B32A -82398B30 B32B -82398B31 B32C -82398B32 B32D -82398B33 B32E -82398B34 B32F -82398B35 B330 -82398B36 B331 -82398B37 B332 -82398B38 B333 -82398B39 B334 -82398C30 B335 -82398C31 B336 -82398C32 B337 -82398C33 B338 -82398C34 B339 -82398C35 B33A -82398C36 B33B -82398C37 B33C -82398C38 B33D -82398C39 B33E -82398D30 B33F -82398D31 B340 -82398D32 B341 -82398D33 B342 -82398D34 B343 -82398D35 B344 -82398D36 B345 -82398D37 B346 -82398D38 B347 -82398D39 B348 -82398E30 B349 -82398E31 B34A -82398E32 B34B -82398E33 B34C -82398E34 B34D -82398E35 B34E -82398E36 B34F -82398E37 B350 -82398E38 B351 -82398E39 B352 -82398F30 B353 -82398F31 B354 -82398F32 B355 -82398F33 B356 -82398F34 B357 -82398F35 B358 -82398F36 B359 -82398F37 B35A -82398F38 B35B -82398F39 B35C -82399030 B35D -82399031 B35E -82399032 B35F -82399033 B360 -82399034 B361 -82399035 B362 -82399036 B363 -82399037 B364 -82399038 B365 -82399039 B366 -82399130 B367 -82399131 B368 -82399132 B369 -82399133 B36A -82399134 B36B -82399135 B36C -82399136 B36D -82399137 B36E -82399138 B36F -82399139 B370 -82399230 B371 -82399231 B372 -82399232 B373 -82399233 B374 -82399234 B375 -82399235 B376 -82399236 B377 -82399237 B378 -82399238 B379 -82399239 B37A -82399330 B37B -82399331 B37C -82399332 B37D -82399333 B37E -82399334 B37F -82399335 B380 -82399336 B381 -82399337 B382 -82399338 B383 -82399339 B384 -82399430 B385 -82399431 B386 -82399432 B387 -82399433 B388 -82399434 B389 -82399435 B38A -82399436 B38B -82399437 B38C -82399438 B38D -82399439 B38E -82399530 B38F -82399531 B390 -82399532 B391 -82399533 B392 -82399534 B393 -82399535 B394 -82399536 B395 -82399537 B396 -82399538 B397 -82399539 B398 -82399630 B399 -82399631 B39A -82399632 B39B -82399633 B39C -82399634 B39D -82399635 B39E -82399636 B39F -82399637 B3A0 -82399638 B3A1 -82399639 B3A2 -82399730 B3A3 -82399731 B3A4 -82399732 B3A5 -82399733 B3A6 -82399734 B3A7 -82399735 B3A8 -82399736 B3A9 -82399737 B3AA -82399738 B3AB -82399739 B3AC -82399830 B3AD -82399831 B3AE -82399832 B3AF -82399833 B3B0 -82399834 B3B1 -82399835 B3B2 -82399836 B3B3 -82399837 B3B4 -82399838 B3B5 -82399839 B3B6 -82399930 B3B7 -82399931 B3B8 -82399932 B3B9 -82399933 B3BA -82399934 B3BB -82399935 B3BC -82399936 B3BD -82399937 B3BE -82399938 B3BF -82399939 B3C0 -82399A30 B3C1 -82399A31 B3C2 -82399A32 B3C3 -82399A33 B3C4 -82399A34 B3C5 -82399A35 B3C6 -82399A36 B3C7 -82399A37 B3C8 -82399A38 B3C9 -82399A39 B3CA -82399B30 B3CB -82399B31 B3CC -82399B32 B3CD -82399B33 B3CE -82399B34 B3CF -82399B35 B3D0 -82399B36 B3D1 -82399B37 B3D2 -82399B38 B3D3 -82399B39 B3D4 -82399C30 B3D5 -82399C31 B3D6 -82399C32 B3D7 -82399C33 B3D8 -82399C34 B3D9 -82399C35 B3DA -82399C36 B3DB -82399C37 B3DC -82399C38 B3DD -82399C39 B3DE -82399D30 B3DF -82399D31 B3E0 -82399D32 B3E1 -82399D33 B3E2 -82399D34 B3E3 -82399D35 B3E4 -82399D36 B3E5 -82399D37 B3E6 -82399D38 B3E7 -82399D39 B3E8 -82399E30 B3E9 -82399E31 B3EA -82399E32 B3EB -82399E33 B3EC -82399E34 B3ED -82399E35 B3EE -82399E36 B3EF -82399E37 B3F0 -82399E38 B3F1 -82399E39 B3F2 -82399F30 B3F3 -82399F31 B3F4 -82399F32 B3F5 -82399F33 B3F6 -82399F34 B3F7 -82399F35 B3F8 -82399F36 B3F9 -82399F37 B3FA -82399F38 B3FB -82399F39 B3FC -8239A030 B3FD -8239A031 B3FE -8239A032 B3FF -8239A033 B400 -8239A034 B401 -8239A035 B402 -8239A036 B403 -8239A037 B404 -8239A038 B405 -8239A039 B406 -8239A130 B407 -8239A131 B408 -8239A132 B409 -8239A133 B40A -8239A134 B40B -8239A135 B40C -8239A136 B40D -8239A137 B40E -8239A138 B40F -8239A139 B410 -8239A230 B411 -8239A231 B412 -8239A232 B413 -8239A233 B414 -8239A234 B415 -8239A235 B416 -8239A236 B417 -8239A237 B418 -8239A238 B419 -8239A239 B41A -8239A330 B41B -8239A331 B41C -8239A332 B41D -8239A333 B41E -8239A334 B41F -8239A335 B420 -8239A336 B421 -8239A337 B422 -8239A338 B423 -8239A339 B424 -8239A430 B425 -8239A431 B426 -8239A432 B427 -8239A433 B428 -8239A434 B429 -8239A435 B42A -8239A436 B42B -8239A437 B42C -8239A438 B42D -8239A439 B42E -8239A530 B42F -8239A531 B430 -8239A532 B431 -8239A533 B432 -8239A534 B433 -8239A535 B434 -8239A536 B435 -8239A537 B436 -8239A538 B437 -8239A539 B438 -8239A630 B439 -8239A631 B43A -8239A632 B43B -8239A633 B43C -8239A634 B43D -8239A635 B43E -8239A636 B43F -8239A637 B440 -8239A638 B441 -8239A639 B442 -8239A730 B443 -8239A731 B444 -8239A732 B445 -8239A733 B446 -8239A734 B447 -8239A735 B448 -8239A736 B449 -8239A737 B44A -8239A738 B44B -8239A739 B44C -8239A830 B44D -8239A831 B44E -8239A832 B44F -8239A833 B450 -8239A834 B451 -8239A835 B452 -8239A836 B453 -8239A837 B454 -8239A838 B455 -8239A839 B456 -8239A930 B457 -8239A931 B458 -8239A932 B459 -8239A933 B45A -8239A934 B45B -8239A935 B45C -8239A936 B45D -8239A937 B45E -8239A938 B45F -8239A939 B460 -8239AA30 B461 -8239AA31 B462 -8239AA32 B463 -8239AA33 B464 -8239AA34 B465 -8239AA35 B466 -8239AA36 B467 -8239AA37 B468 -8239AA38 B469 -8239AA39 B46A -8239AB30 B46B -8239AB31 B46C -8239AB32 B46D -8239AB33 B46E -8239AB34 B46F -8239AB35 B470 -8239AB36 B471 -8239AB37 B472 -8239AB38 B473 -8239AB39 B474 -8239AC30 B475 -8239AC31 B476 -8239AC32 B477 -8239AC33 B478 -8239AC34 B479 -8239AC35 B47A -8239AC36 B47B -8239AC37 B47C -8239AC38 B47D -8239AC39 B47E -8239AD30 B47F -8239AD31 B480 -8239AD32 B481 -8239AD33 B482 -8239AD34 B483 -8239AD35 B484 -8239AD36 B485 -8239AD37 B486 -8239AD38 B487 -8239AD39 B488 -8239AE30 B489 -8239AE31 B48A -8239AE32 B48B -8239AE33 B48C -8239AE34 B48D -8239AE35 B48E -8239AE36 B48F -8239AE37 B490 -8239AE38 B491 -8239AE39 B492 -8239AF30 B493 -8239AF31 B494 -8239AF32 B495 -8239AF33 B496 -8239AF34 B497 -8239AF35 B498 -8239AF36 B499 -8239AF37 B49A -8239AF38 B49B -8239AF39 B49C -8239B030 B49D -8239B031 B49E -8239B032 B49F -8239B033 B4A0 -8239B034 B4A1 -8239B035 B4A2 -8239B036 B4A3 -8239B037 B4A4 -8239B038 B4A5 -8239B039 B4A6 -8239B130 B4A7 -8239B131 B4A8 -8239B132 B4A9 -8239B133 B4AA -8239B134 B4AB -8239B135 B4AC -8239B136 B4AD -8239B137 B4AE -8239B138 B4AF -8239B139 B4B0 -8239B230 B4B1 -8239B231 B4B2 -8239B232 B4B3 -8239B233 B4B4 -8239B234 B4B5 -8239B235 B4B6 -8239B236 B4B7 -8239B237 B4B8 -8239B238 B4B9 -8239B239 B4BA -8239B330 B4BB -8239B331 B4BC -8239B332 B4BD -8239B333 B4BE -8239B334 B4BF -8239B335 B4C0 -8239B336 B4C1 -8239B337 B4C2 -8239B338 B4C3 -8239B339 B4C4 -8239B430 B4C5 -8239B431 B4C6 -8239B432 B4C7 -8239B433 B4C8 -8239B434 B4C9 -8239B435 B4CA -8239B436 B4CB -8239B437 B4CC -8239B438 B4CD -8239B439 B4CE -8239B530 B4CF -8239B531 B4D0 -8239B532 B4D1 -8239B533 B4D2 -8239B534 B4D3 -8239B535 B4D4 -8239B536 B4D5 -8239B537 B4D6 -8239B538 B4D7 -8239B539 B4D8 -8239B630 B4D9 -8239B631 B4DA -8239B632 B4DB -8239B633 B4DC -8239B634 B4DD -8239B635 B4DE -8239B636 B4DF -8239B637 B4E0 -8239B638 B4E1 -8239B639 B4E2 -8239B730 B4E3 -8239B731 B4E4 -8239B732 B4E5 -8239B733 B4E6 -8239B734 B4E7 -8239B735 B4E8 -8239B736 B4E9 -8239B737 B4EA -8239B738 B4EB -8239B739 B4EC -8239B830 B4ED -8239B831 B4EE -8239B832 B4EF -8239B833 B4F0 -8239B834 B4F1 -8239B835 B4F2 -8239B836 B4F3 -8239B837 B4F4 -8239B838 B4F5 -8239B839 B4F6 -8239B930 B4F7 -8239B931 B4F8 -8239B932 B4F9 -8239B933 B4FA -8239B934 B4FB -8239B935 B4FC -8239B936 B4FD -8239B937 B4FE -8239B938 B4FF -8239B939 B500 -8239BA30 B501 -8239BA31 B502 -8239BA32 B503 -8239BA33 B504 -8239BA34 B505 -8239BA35 B506 -8239BA36 B507 -8239BA37 B508 -8239BA38 B509 -8239BA39 B50A -8239BB30 B50B -8239BB31 B50C -8239BB32 B50D -8239BB33 B50E -8239BB34 B50F -8239BB35 B510 -8239BB36 B511 -8239BB37 B512 -8239BB38 B513 -8239BB39 B514 -8239BC30 B515 -8239BC31 B516 -8239BC32 B517 -8239BC33 B518 -8239BC34 B519 -8239BC35 B51A -8239BC36 B51B -8239BC37 B51C -8239BC38 B51D -8239BC39 B51E -8239BD30 B51F -8239BD31 B520 -8239BD32 B521 -8239BD33 B522 -8239BD34 B523 -8239BD35 B524 -8239BD36 B525 -8239BD37 B526 -8239BD38 B527 -8239BD39 B528 -8239BE30 B529 -8239BE31 B52A -8239BE32 B52B -8239BE33 B52C -8239BE34 B52D -8239BE35 B52E -8239BE36 B52F -8239BE37 B530 -8239BE38 B531 -8239BE39 B532 -8239BF30 B533 -8239BF31 B534 -8239BF32 B535 -8239BF33 B536 -8239BF34 B537 -8239BF35 B538 -8239BF36 B539 -8239BF37 B53A -8239BF38 B53B -8239BF39 B53C -8239C030 B53D -8239C031 B53E -8239C032 B53F -8239C033 B540 -8239C034 B541 -8239C035 B542 -8239C036 B543 -8239C037 B544 -8239C038 B545 -8239C039 B546 -8239C130 B547 -8239C131 B548 -8239C132 B549 -8239C133 B54A -8239C134 B54B -8239C135 B54C -8239C136 B54D -8239C137 B54E -8239C138 B54F -8239C139 B550 -8239C230 B551 -8239C231 B552 -8239C232 B553 -8239C233 B554 -8239C234 B555 -8239C235 B556 -8239C236 B557 -8239C237 B558 -8239C238 B559 -8239C239 B55A -8239C330 B55B -8239C331 B55C -8239C332 B55D -8239C333 B55E -8239C334 B55F -8239C335 B560 -8239C336 B561 -8239C337 B562 -8239C338 B563 -8239C339 B564 -8239C430 B565 -8239C431 B566 -8239C432 B567 -8239C433 B568 -8239C434 B569 -8239C435 B56A -8239C436 B56B -8239C437 B56C -8239C438 B56D -8239C439 B56E -8239C530 B56F -8239C531 B570 -8239C532 B571 -8239C533 B572 -8239C534 B573 -8239C535 B574 -8239C536 B575 -8239C537 B576 -8239C538 B577 -8239C539 B578 -8239C630 B579 -8239C631 B57A -8239C632 B57B -8239C633 B57C -8239C634 B57D -8239C635 B57E -8239C636 B57F -8239C637 B580 -8239C638 B581 -8239C639 B582 -8239C730 B583 -8239C731 B584 -8239C732 B585 -8239C733 B586 -8239C734 B587 -8239C735 B588 -8239C736 B589 -8239C737 B58A -8239C738 B58B -8239C739 B58C -8239C830 B58D -8239C831 B58E -8239C832 B58F -8239C833 B590 -8239C834 B591 -8239C835 B592 -8239C836 B593 -8239C837 B594 -8239C838 B595 -8239C839 B596 -8239C930 B597 -8239C931 B598 -8239C932 B599 -8239C933 B59A -8239C934 B59B -8239C935 B59C -8239C936 B59D -8239C937 B59E -8239C938 B59F -8239C939 B5A0 -8239CA30 B5A1 -8239CA31 B5A2 -8239CA32 B5A3 -8239CA33 B5A4 -8239CA34 B5A5 -8239CA35 B5A6 -8239CA36 B5A7 -8239CA37 B5A8 -8239CA38 B5A9 -8239CA39 B5AA -8239CB30 B5AB -8239CB31 B5AC -8239CB32 B5AD -8239CB33 B5AE -8239CB34 B5AF -8239CB35 B5B0 -8239CB36 B5B1 -8239CB37 B5B2 -8239CB38 B5B3 -8239CB39 B5B4 -8239CC30 B5B5 -8239CC31 B5B6 -8239CC32 B5B7 -8239CC33 B5B8 -8239CC34 B5B9 -8239CC35 B5BA -8239CC36 B5BB -8239CC37 B5BC -8239CC38 B5BD -8239CC39 B5BE -8239CD30 B5BF -8239CD31 B5C0 -8239CD32 B5C1 -8239CD33 B5C2 -8239CD34 B5C3 -8239CD35 B5C4 -8239CD36 B5C5 -8239CD37 B5C6 -8239CD38 B5C7 -8239CD39 B5C8 -8239CE30 B5C9 -8239CE31 B5CA -8239CE32 B5CB -8239CE33 B5CC -8239CE34 B5CD -8239CE35 B5CE -8239CE36 B5CF -8239CE37 B5D0 -8239CE38 B5D1 -8239CE39 B5D2 -8239CF30 B5D3 -8239CF31 B5D4 -8239CF32 B5D5 -8239CF33 B5D6 -8239CF34 B5D7 -8239CF35 B5D8 -8239CF36 B5D9 -8239CF37 B5DA -8239CF38 B5DB -8239CF39 B5DC -8239D030 B5DD -8239D031 B5DE -8239D032 B5DF -8239D033 B5E0 -8239D034 B5E1 -8239D035 B5E2 -8239D036 B5E3 -8239D037 B5E4 -8239D038 B5E5 -8239D039 B5E6 -8239D130 B5E7 -8239D131 B5E8 -8239D132 B5E9 -8239D133 B5EA -8239D134 B5EB -8239D135 B5EC -8239D136 B5ED -8239D137 B5EE -8239D138 B5EF -8239D139 B5F0 -8239D230 B5F1 -8239D231 B5F2 -8239D232 B5F3 -8239D233 B5F4 -8239D234 B5F5 -8239D235 B5F6 -8239D236 B5F7 -8239D237 B5F8 -8239D238 B5F9 -8239D239 B5FA -8239D330 B5FB -8239D331 B5FC -8239D332 B5FD -8239D333 B5FE -8239D334 B5FF -8239D335 B600 -8239D336 B601 -8239D337 B602 -8239D338 B603 -8239D339 B604 -8239D430 B605 -8239D431 B606 -8239D432 B607 -8239D433 B608 -8239D434 B609 -8239D435 B60A -8239D436 B60B -8239D437 B60C -8239D438 B60D -8239D439 B60E -8239D530 B60F -8239D531 B610 -8239D532 B611 -8239D533 B612 -8239D534 B613 -8239D535 B614 -8239D536 B615 -8239D537 B616 -8239D538 B617 -8239D539 B618 -8239D630 B619 -8239D631 B61A -8239D632 B61B -8239D633 B61C -8239D634 B61D -8239D635 B61E -8239D636 B61F -8239D637 B620 -8239D638 B621 -8239D639 B622 -8239D730 B623 -8239D731 B624 -8239D732 B625 -8239D733 B626 -8239D734 B627 -8239D735 B628 -8239D736 B629 -8239D737 B62A -8239D738 B62B -8239D739 B62C -8239D830 B62D -8239D831 B62E -8239D832 B62F -8239D833 B630 -8239D834 B631 -8239D835 B632 -8239D836 B633 -8239D837 B634 -8239D838 B635 -8239D839 B636 -8239D930 B637 -8239D931 B638 -8239D932 B639 -8239D933 B63A -8239D934 B63B -8239D935 B63C -8239D936 B63D -8239D937 B63E -8239D938 B63F -8239D939 B640 -8239DA30 B641 -8239DA31 B642 -8239DA32 B643 -8239DA33 B644 -8239DA34 B645 -8239DA35 B646 -8239DA36 B647 -8239DA37 B648 -8239DA38 B649 -8239DA39 B64A -8239DB30 B64B -8239DB31 B64C -8239DB32 B64D -8239DB33 B64E -8239DB34 B64F -8239DB35 B650 -8239DB36 B651 -8239DB37 B652 -8239DB38 B653 -8239DB39 B654 -8239DC30 B655 -8239DC31 B656 -8239DC32 B657 -8239DC33 B658 -8239DC34 B659 -8239DC35 B65A -8239DC36 B65B -8239DC37 B65C -8239DC38 B65D -8239DC39 B65E -8239DD30 B65F -8239DD31 B660 -8239DD32 B661 -8239DD33 B662 -8239DD34 B663 -8239DD35 B664 -8239DD36 B665 -8239DD37 B666 -8239DD38 B667 -8239DD39 B668 -8239DE30 B669 -8239DE31 B66A -8239DE32 B66B -8239DE33 B66C -8239DE34 B66D -8239DE35 B66E -8239DE36 B66F -8239DE37 B670 -8239DE38 B671 -8239DE39 B672 -8239DF30 B673 -8239DF31 B674 -8239DF32 B675 -8239DF33 B676 -8239DF34 B677 -8239DF35 B678 -8239DF36 B679 -8239DF37 B67A -8239DF38 B67B -8239DF39 B67C -8239E030 B67D -8239E031 B67E -8239E032 B67F -8239E033 B680 -8239E034 B681 -8239E035 B682 -8239E036 B683 -8239E037 B684 -8239E038 B685 -8239E039 B686 -8239E130 B687 -8239E131 B688 -8239E132 B689 -8239E133 B68A -8239E134 B68B -8239E135 B68C -8239E136 B68D -8239E137 B68E -8239E138 B68F -8239E139 B690 -8239E230 B691 -8239E231 B692 -8239E232 B693 -8239E233 B694 -8239E234 B695 -8239E235 B696 -8239E236 B697 -8239E237 B698 -8239E238 B699 -8239E239 B69A -8239E330 B69B -8239E331 B69C -8239E332 B69D -8239E333 B69E -8239E334 B69F -8239E335 B6A0 -8239E336 B6A1 -8239E337 B6A2 -8239E338 B6A3 -8239E339 B6A4 -8239E430 B6A5 -8239E431 B6A6 -8239E432 B6A7 -8239E433 B6A8 -8239E434 B6A9 -8239E435 B6AA -8239E436 B6AB -8239E437 B6AC -8239E438 B6AD -8239E439 B6AE -8239E530 B6AF -8239E531 B6B0 -8239E532 B6B1 -8239E533 B6B2 -8239E534 B6B3 -8239E535 B6B4 -8239E536 B6B5 -8239E537 B6B6 -8239E538 B6B7 -8239E539 B6B8 -8239E630 B6B9 -8239E631 B6BA -8239E632 B6BB -8239E633 B6BC -8239E634 B6BD -8239E635 B6BE -8239E636 B6BF -8239E637 B6C0 -8239E638 B6C1 -8239E639 B6C2 -8239E730 B6C3 -8239E731 B6C4 -8239E732 B6C5 -8239E733 B6C6 -8239E734 B6C7 -8239E735 B6C8 -8239E736 B6C9 -8239E737 B6CA -8239E738 B6CB -8239E739 B6CC -8239E830 B6CD -8239E831 B6CE -8239E832 B6CF -8239E833 B6D0 -8239E834 B6D1 -8239E835 B6D2 -8239E836 B6D3 -8239E837 B6D4 -8239E838 B6D5 -8239E839 B6D6 -8239E930 B6D7 -8239E931 B6D8 -8239E932 B6D9 -8239E933 B6DA -8239E934 B6DB -8239E935 B6DC -8239E936 B6DD -8239E937 B6DE -8239E938 B6DF -8239E939 B6E0 -8239EA30 B6E1 -8239EA31 B6E2 -8239EA32 B6E3 -8239EA33 B6E4 -8239EA34 B6E5 -8239EA35 B6E6 -8239EA36 B6E7 -8239EA37 B6E8 -8239EA38 B6E9 -8239EA39 B6EA -8239EB30 B6EB -8239EB31 B6EC -8239EB32 B6ED -8239EB33 B6EE -8239EB34 B6EF -8239EB35 B6F0 -8239EB36 B6F1 -8239EB37 B6F2 -8239EB38 B6F3 -8239EB39 B6F4 -8239EC30 B6F5 -8239EC31 B6F6 -8239EC32 B6F7 -8239EC33 B6F8 -8239EC34 B6F9 -8239EC35 B6FA -8239EC36 B6FB -8239EC37 B6FC -8239EC38 B6FD -8239EC39 B6FE -8239ED30 B6FF -8239ED31 B700 -8239ED32 B701 -8239ED33 B702 -8239ED34 B703 -8239ED35 B704 -8239ED36 B705 -8239ED37 B706 -8239ED38 B707 -8239ED39 B708 -8239EE30 B709 -8239EE31 B70A -8239EE32 B70B -8239EE33 B70C -8239EE34 B70D -8239EE35 B70E -8239EE36 B70F -8239EE37 B710 -8239EE38 B711 -8239EE39 B712 -8239EF30 B713 -8239EF31 B714 -8239EF32 B715 -8239EF33 B716 -8239EF34 B717 -8239EF35 B718 -8239EF36 B719 -8239EF37 B71A -8239EF38 B71B -8239EF39 B71C -8239F030 B71D -8239F031 B71E -8239F032 B71F -8239F033 B720 -8239F034 B721 -8239F035 B722 -8239F036 B723 -8239F037 B724 -8239F038 B725 -8239F039 B726 -8239F130 B727 -8239F131 B728 -8239F132 B729 -8239F133 B72A -8239F134 B72B -8239F135 B72C -8239F136 B72D -8239F137 B72E -8239F138 B72F -8239F139 B730 -8239F230 B731 -8239F231 B732 -8239F232 B733 -8239F233 B734 -8239F234 B735 -8239F235 B736 -8239F236 B737 -8239F237 B738 -8239F238 B739 -8239F239 B73A -8239F330 B73B -8239F331 B73C -8239F332 B73D -8239F333 B73E -8239F334 B73F -8239F335 B740 -8239F336 B741 -8239F337 B742 -8239F338 B743 -8239F339 B744 -8239F430 B745 -8239F431 B746 -8239F432 B747 -8239F433 B748 -8239F434 B749 -8239F435 B74A -8239F436 B74B -8239F437 B74C -8239F438 B74D -8239F439 B74E -8239F530 B74F -8239F531 B750 -8239F532 B751 -8239F533 B752 -8239F534 B753 -8239F535 B754 -8239F536 B755 -8239F537 B756 -8239F538 B757 -8239F539 B758 -8239F630 B759 -8239F631 B75A -8239F632 B75B -8239F633 B75C -8239F634 B75D -8239F635 B75E -8239F636 B75F -8239F637 B760 -8239F638 B761 -8239F639 B762 -8239F730 B763 -8239F731 B764 -8239F732 B765 -8239F733 B766 -8239F734 B767 -8239F735 B768 -8239F736 B769 -8239F737 B76A -8239F738 B76B -8239F739 B76C -8239F830 B76D -8239F831 B76E -8239F832 B76F -8239F833 B770 -8239F834 B771 -8239F835 B772 -8239F836 B773 -8239F837 B774 -8239F838 B775 -8239F839 B776 -8239F930 B777 -8239F931 B778 -8239F932 B779 -8239F933 B77A -8239F934 B77B -8239F935 B77C -8239F936 B77D -8239F937 B77E -8239F938 B77F -8239F939 B780 -8239FA30 B781 -8239FA31 B782 -8239FA32 B783 -8239FA33 B784 -8239FA34 B785 -8239FA35 B786 -8239FA36 B787 -8239FA37 B788 -8239FA38 B789 -8239FA39 B78A -8239FB30 B78B -8239FB31 B78C -8239FB32 B78D -8239FB33 B78E -8239FB34 B78F -8239FB35 B790 -8239FB36 B791 -8239FB37 B792 -8239FB38 B793 -8239FB39 B794 -8239FC30 B795 -8239FC31 B796 -8239FC32 B797 -8239FC33 B798 -8239FC34 B799 -8239FC35 B79A -8239FC36 B79B -8239FC37 B79C -8239FC38 B79D -8239FC39 B79E -8239FD30 B79F -8239FD31 B7A0 -8239FD32 B7A1 -8239FD33 B7A2 -8239FD34 B7A3 -8239FD35 B7A4 -8239FD36 B7A5 -8239FD37 B7A6 -8239FD38 B7A7 -8239FD39 B7A8 -8239FE30 B7A9 -8239FE31 B7AA -8239FE32 B7AB -8239FE33 B7AC -8239FE34 B7AD -8239FE35 B7AE -8239FE36 B7AF -8239FE37 B7B0 -8239FE38 B7B1 -8239FE39 B7B2 -83308130 B7B3 -83308131 B7B4 -83308132 B7B5 -83308133 B7B6 -83308134 B7B7 -83308135 B7B8 -83308136 B7B9 -83308137 B7BA -83308138 B7BB -83308139 B7BC -83308230 B7BD -83308231 B7BE -83308232 B7BF -83308233 B7C0 -83308234 B7C1 -83308235 B7C2 -83308236 B7C3 -83308237 B7C4 -83308238 B7C5 -83308239 B7C6 -83308330 B7C7 -83308331 B7C8 -83308332 B7C9 -83308333 B7CA -83308334 B7CB -83308335 B7CC -83308336 B7CD -83308337 B7CE -83308338 B7CF -83308339 B7D0 -83308430 B7D1 -83308431 B7D2 -83308432 B7D3 -83308433 B7D4 -83308434 B7D5 -83308435 B7D6 -83308436 B7D7 -83308437 B7D8 -83308438 B7D9 -83308439 B7DA -83308530 B7DB -83308531 B7DC -83308532 B7DD -83308533 B7DE -83308534 B7DF -83308535 B7E0 -83308536 B7E1 -83308537 B7E2 -83308538 B7E3 -83308539 B7E4 -83308630 B7E5 -83308631 B7E6 -83308632 B7E7 -83308633 B7E8 -83308634 B7E9 -83308635 B7EA -83308636 B7EB -83308637 B7EC -83308638 B7ED -83308639 B7EE -83308730 B7EF -83308731 B7F0 -83308732 B7F1 -83308733 B7F2 -83308734 B7F3 -83308735 B7F4 -83308736 B7F5 -83308737 B7F6 -83308738 B7F7 -83308739 B7F8 -83308830 B7F9 -83308831 B7FA -83308832 B7FB -83308833 B7FC -83308834 B7FD -83308835 B7FE -83308836 B7FF -83308837 B800 -83308838 B801 -83308839 B802 -83308930 B803 -83308931 B804 -83308932 B805 -83308933 B806 -83308934 B807 -83308935 B808 -83308936 B809 -83308937 B80A -83308938 B80B -83308939 B80C -83308A30 B80D -83308A31 B80E -83308A32 B80F -83308A33 B810 -83308A34 B811 -83308A35 B812 -83308A36 B813 -83308A37 B814 -83308A38 B815 -83308A39 B816 -83308B30 B817 -83308B31 B818 -83308B32 B819 -83308B33 B81A -83308B34 B81B -83308B35 B81C -83308B36 B81D -83308B37 B81E -83308B38 B81F -83308B39 B820 -83308C30 B821 -83308C31 B822 -83308C32 B823 -83308C33 B824 -83308C34 B825 -83308C35 B826 -83308C36 B827 -83308C37 B828 -83308C38 B829 -83308C39 B82A -83308D30 B82B -83308D31 B82C -83308D32 B82D -83308D33 B82E -83308D34 B82F -83308D35 B830 -83308D36 B831 -83308D37 B832 -83308D38 B833 -83308D39 B834 -83308E30 B835 -83308E31 B836 -83308E32 B837 -83308E33 B838 -83308E34 B839 -83308E35 B83A -83308E36 B83B -83308E37 B83C -83308E38 B83D -83308E39 B83E -83308F30 B83F -83308F31 B840 -83308F32 B841 -83308F33 B842 -83308F34 B843 -83308F35 B844 -83308F36 B845 -83308F37 B846 -83308F38 B847 -83308F39 B848 -83309030 B849 -83309031 B84A -83309032 B84B -83309033 B84C -83309034 B84D -83309035 B84E -83309036 B84F -83309037 B850 -83309038 B851 -83309039 B852 -83309130 B853 -83309131 B854 -83309132 B855 -83309133 B856 -83309134 B857 -83309135 B858 -83309136 B859 -83309137 B85A -83309138 B85B -83309139 B85C -83309230 B85D -83309231 B85E -83309232 B85F -83309233 B860 -83309234 B861 -83309235 B862 -83309236 B863 -83309237 B864 -83309238 B865 -83309239 B866 -83309330 B867 -83309331 B868 -83309332 B869 -83309333 B86A -83309334 B86B -83309335 B86C -83309336 B86D -83309337 B86E -83309338 B86F -83309339 B870 -83309430 B871 -83309431 B872 -83309432 B873 -83309433 B874 -83309434 B875 -83309435 B876 -83309436 B877 -83309437 B878 -83309438 B879 -83309439 B87A -83309530 B87B -83309531 B87C -83309532 B87D -83309533 B87E -83309534 B87F -83309535 B880 -83309536 B881 -83309537 B882 -83309538 B883 -83309539 B884 -83309630 B885 -83309631 B886 -83309632 B887 -83309633 B888 -83309634 B889 -83309635 B88A -83309636 B88B -83309637 B88C -83309638 B88D -83309639 B88E -83309730 B88F -83309731 B890 -83309732 B891 -83309733 B892 -83309734 B893 -83309735 B894 -83309736 B895 -83309737 B896 -83309738 B897 -83309739 B898 -83309830 B899 -83309831 B89A -83309832 B89B -83309833 B89C -83309834 B89D -83309835 B89E -83309836 B89F -83309837 B8A0 -83309838 B8A1 -83309839 B8A2 -83309930 B8A3 -83309931 B8A4 -83309932 B8A5 -83309933 B8A6 -83309934 B8A7 -83309935 B8A8 -83309936 B8A9 -83309937 B8AA -83309938 B8AB -83309939 B8AC -83309A30 B8AD -83309A31 B8AE -83309A32 B8AF -83309A33 B8B0 -83309A34 B8B1 -83309A35 B8B2 -83309A36 B8B3 -83309A37 B8B4 -83309A38 B8B5 -83309A39 B8B6 -83309B30 B8B7 -83309B31 B8B8 -83309B32 B8B9 -83309B33 B8BA -83309B34 B8BB -83309B35 B8BC -83309B36 B8BD -83309B37 B8BE -83309B38 B8BF -83309B39 B8C0 -83309C30 B8C1 -83309C31 B8C2 -83309C32 B8C3 -83309C33 B8C4 -83309C34 B8C5 -83309C35 B8C6 -83309C36 B8C7 -83309C37 B8C8 -83309C38 B8C9 -83309C39 B8CA -83309D30 B8CB -83309D31 B8CC -83309D32 B8CD -83309D33 B8CE -83309D34 B8CF -83309D35 B8D0 -83309D36 B8D1 -83309D37 B8D2 -83309D38 B8D3 -83309D39 B8D4 -83309E30 B8D5 -83309E31 B8D6 -83309E32 B8D7 -83309E33 B8D8 -83309E34 B8D9 -83309E35 B8DA -83309E36 B8DB -83309E37 B8DC -83309E38 B8DD -83309E39 B8DE -83309F30 B8DF -83309F31 B8E0 -83309F32 B8E1 -83309F33 B8E2 -83309F34 B8E3 -83309F35 B8E4 -83309F36 B8E5 -83309F37 B8E6 -83309F38 B8E7 -83309F39 B8E8 -8330A030 B8E9 -8330A031 B8EA -8330A032 B8EB -8330A033 B8EC -8330A034 B8ED -8330A035 B8EE -8330A036 B8EF -8330A037 B8F0 -8330A038 B8F1 -8330A039 B8F2 -8330A130 B8F3 -8330A131 B8F4 -8330A132 B8F5 -8330A133 B8F6 -8330A134 B8F7 -8330A135 B8F8 -8330A136 B8F9 -8330A137 B8FA -8330A138 B8FB -8330A139 B8FC -8330A230 B8FD -8330A231 B8FE -8330A232 B8FF -8330A233 B900 -8330A234 B901 -8330A235 B902 -8330A236 B903 -8330A237 B904 -8330A238 B905 -8330A239 B906 -8330A330 B907 -8330A331 B908 -8330A332 B909 -8330A333 B90A -8330A334 B90B -8330A335 B90C -8330A336 B90D -8330A337 B90E -8330A338 B90F -8330A339 B910 -8330A430 B911 -8330A431 B912 -8330A432 B913 -8330A433 B914 -8330A434 B915 -8330A435 B916 -8330A436 B917 -8330A437 B918 -8330A438 B919 -8330A439 B91A -8330A530 B91B -8330A531 B91C -8330A532 B91D -8330A533 B91E -8330A534 B91F -8330A535 B920 -8330A536 B921 -8330A537 B922 -8330A538 B923 -8330A539 B924 -8330A630 B925 -8330A631 B926 -8330A632 B927 -8330A633 B928 -8330A634 B929 -8330A635 B92A -8330A636 B92B -8330A637 B92C -8330A638 B92D -8330A639 B92E -8330A730 B92F -8330A731 B930 -8330A732 B931 -8330A733 B932 -8330A734 B933 -8330A735 B934 -8330A736 B935 -8330A737 B936 -8330A738 B937 -8330A739 B938 -8330A830 B939 -8330A831 B93A -8330A832 B93B -8330A833 B93C -8330A834 B93D -8330A835 B93E -8330A836 B93F -8330A837 B940 -8330A838 B941 -8330A839 B942 -8330A930 B943 -8330A931 B944 -8330A932 B945 -8330A933 B946 -8330A934 B947 -8330A935 B948 -8330A936 B949 -8330A937 B94A -8330A938 B94B -8330A939 B94C -8330AA30 B94D -8330AA31 B94E -8330AA32 B94F -8330AA33 B950 -8330AA34 B951 -8330AA35 B952 -8330AA36 B953 -8330AA37 B954 -8330AA38 B955 -8330AA39 B956 -8330AB30 B957 -8330AB31 B958 -8330AB32 B959 -8330AB33 B95A -8330AB34 B95B -8330AB35 B95C -8330AB36 B95D -8330AB37 B95E -8330AB38 B95F -8330AB39 B960 -8330AC30 B961 -8330AC31 B962 -8330AC32 B963 -8330AC33 B964 -8330AC34 B965 -8330AC35 B966 -8330AC36 B967 -8330AC37 B968 -8330AC38 B969 -8330AC39 B96A -8330AD30 B96B -8330AD31 B96C -8330AD32 B96D -8330AD33 B96E -8330AD34 B96F -8330AD35 B970 -8330AD36 B971 -8330AD37 B972 -8330AD38 B973 -8330AD39 B974 -8330AE30 B975 -8330AE31 B976 -8330AE32 B977 -8330AE33 B978 -8330AE34 B979 -8330AE35 B97A -8330AE36 B97B -8330AE37 B97C -8330AE38 B97D -8330AE39 B97E -8330AF30 B97F -8330AF31 B980 -8330AF32 B981 -8330AF33 B982 -8330AF34 B983 -8330AF35 B984 -8330AF36 B985 -8330AF37 B986 -8330AF38 B987 -8330AF39 B988 -8330B030 B989 -8330B031 B98A -8330B032 B98B -8330B033 B98C -8330B034 B98D -8330B035 B98E -8330B036 B98F -8330B037 B990 -8330B038 B991 -8330B039 B992 -8330B130 B993 -8330B131 B994 -8330B132 B995 -8330B133 B996 -8330B134 B997 -8330B135 B998 -8330B136 B999 -8330B137 B99A -8330B138 B99B -8330B139 B99C -8330B230 B99D -8330B231 B99E -8330B232 B99F -8330B233 B9A0 -8330B234 B9A1 -8330B235 B9A2 -8330B236 B9A3 -8330B237 B9A4 -8330B238 B9A5 -8330B239 B9A6 -8330B330 B9A7 -8330B331 B9A8 -8330B332 B9A9 -8330B333 B9AA -8330B334 B9AB -8330B335 B9AC -8330B336 B9AD -8330B337 B9AE -8330B338 B9AF -8330B339 B9B0 -8330B430 B9B1 -8330B431 B9B2 -8330B432 B9B3 -8330B433 B9B4 -8330B434 B9B5 -8330B435 B9B6 -8330B436 B9B7 -8330B437 B9B8 -8330B438 B9B9 -8330B439 B9BA -8330B530 B9BB -8330B531 B9BC -8330B532 B9BD -8330B533 B9BE -8330B534 B9BF -8330B535 B9C0 -8330B536 B9C1 -8330B537 B9C2 -8330B538 B9C3 -8330B539 B9C4 -8330B630 B9C5 -8330B631 B9C6 -8330B632 B9C7 -8330B633 B9C8 -8330B634 B9C9 -8330B635 B9CA -8330B636 B9CB -8330B637 B9CC -8330B638 B9CD -8330B639 B9CE -8330B730 B9CF -8330B731 B9D0 -8330B732 B9D1 -8330B733 B9D2 -8330B734 B9D3 -8330B735 B9D4 -8330B736 B9D5 -8330B737 B9D6 -8330B738 B9D7 -8330B739 B9D8 -8330B830 B9D9 -8330B831 B9DA -8330B832 B9DB -8330B833 B9DC -8330B834 B9DD -8330B835 B9DE -8330B836 B9DF -8330B837 B9E0 -8330B838 B9E1 -8330B839 B9E2 -8330B930 B9E3 -8330B931 B9E4 -8330B932 B9E5 -8330B933 B9E6 -8330B934 B9E7 -8330B935 B9E8 -8330B936 B9E9 -8330B937 B9EA -8330B938 B9EB -8330B939 B9EC -8330BA30 B9ED -8330BA31 B9EE -8330BA32 B9EF -8330BA33 B9F0 -8330BA34 B9F1 -8330BA35 B9F2 -8330BA36 B9F3 -8330BA37 B9F4 -8330BA38 B9F5 -8330BA39 B9F6 -8330BB30 B9F7 -8330BB31 B9F8 -8330BB32 B9F9 -8330BB33 B9FA -8330BB34 B9FB -8330BB35 B9FC -8330BB36 B9FD -8330BB37 B9FE -8330BB38 B9FF -8330BB39 BA00 -8330BC30 BA01 -8330BC31 BA02 -8330BC32 BA03 -8330BC33 BA04 -8330BC34 BA05 -8330BC35 BA06 -8330BC36 BA07 -8330BC37 BA08 -8330BC38 BA09 -8330BC39 BA0A -8330BD30 BA0B -8330BD31 BA0C -8330BD32 BA0D -8330BD33 BA0E -8330BD34 BA0F -8330BD35 BA10 -8330BD36 BA11 -8330BD37 BA12 -8330BD38 BA13 -8330BD39 BA14 -8330BE30 BA15 -8330BE31 BA16 -8330BE32 BA17 -8330BE33 BA18 -8330BE34 BA19 -8330BE35 BA1A -8330BE36 BA1B -8330BE37 BA1C -8330BE38 BA1D -8330BE39 BA1E -8330BF30 BA1F -8330BF31 BA20 -8330BF32 BA21 -8330BF33 BA22 -8330BF34 BA23 -8330BF35 BA24 -8330BF36 BA25 -8330BF37 BA26 -8330BF38 BA27 -8330BF39 BA28 -8330C030 BA29 -8330C031 BA2A -8330C032 BA2B -8330C033 BA2C -8330C034 BA2D -8330C035 BA2E -8330C036 BA2F -8330C037 BA30 -8330C038 BA31 -8330C039 BA32 -8330C130 BA33 -8330C131 BA34 -8330C132 BA35 -8330C133 BA36 -8330C134 BA37 -8330C135 BA38 -8330C136 BA39 -8330C137 BA3A -8330C138 BA3B -8330C139 BA3C -8330C230 BA3D -8330C231 BA3E -8330C232 BA3F -8330C233 BA40 -8330C234 BA41 -8330C235 BA42 -8330C236 BA43 -8330C237 BA44 -8330C238 BA45 -8330C239 BA46 -8330C330 BA47 -8330C331 BA48 -8330C332 BA49 -8330C333 BA4A -8330C334 BA4B -8330C335 BA4C -8330C336 BA4D -8330C337 BA4E -8330C338 BA4F -8330C339 BA50 -8330C430 BA51 -8330C431 BA52 -8330C432 BA53 -8330C433 BA54 -8330C434 BA55 -8330C435 BA56 -8330C436 BA57 -8330C437 BA58 -8330C438 BA59 -8330C439 BA5A -8330C530 BA5B -8330C531 BA5C -8330C532 BA5D -8330C533 BA5E -8330C534 BA5F -8330C535 BA60 -8330C536 BA61 -8330C537 BA62 -8330C538 BA63 -8330C539 BA64 -8330C630 BA65 -8330C631 BA66 -8330C632 BA67 -8330C633 BA68 -8330C634 BA69 -8330C635 BA6A -8330C636 BA6B -8330C637 BA6C -8330C638 BA6D -8330C639 BA6E -8330C730 BA6F -8330C731 BA70 -8330C732 BA71 -8330C733 BA72 -8330C734 BA73 -8330C735 BA74 -8330C736 BA75 -8330C737 BA76 -8330C738 BA77 -8330C739 BA78 -8330C830 BA79 -8330C831 BA7A -8330C832 BA7B -8330C833 BA7C -8330C834 BA7D -8330C835 BA7E -8330C836 BA7F -8330C837 BA80 -8330C838 BA81 -8330C839 BA82 -8330C930 BA83 -8330C931 BA84 -8330C932 BA85 -8330C933 BA86 -8330C934 BA87 -8330C935 BA88 -8330C936 BA89 -8330C937 BA8A -8330C938 BA8B -8330C939 BA8C -8330CA30 BA8D -8330CA31 BA8E -8330CA32 BA8F -8330CA33 BA90 -8330CA34 BA91 -8330CA35 BA92 -8330CA36 BA93 -8330CA37 BA94 -8330CA38 BA95 -8330CA39 BA96 -8330CB30 BA97 -8330CB31 BA98 -8330CB32 BA99 -8330CB33 BA9A -8330CB34 BA9B -8330CB35 BA9C -8330CB36 BA9D -8330CB37 BA9E -8330CB38 BA9F -8330CB39 BAA0 -8330CC30 BAA1 -8330CC31 BAA2 -8330CC32 BAA3 -8330CC33 BAA4 -8330CC34 BAA5 -8330CC35 BAA6 -8330CC36 BAA7 -8330CC37 BAA8 -8330CC38 BAA9 -8330CC39 BAAA -8330CD30 BAAB -8330CD31 BAAC -8330CD32 BAAD -8330CD33 BAAE -8330CD34 BAAF -8330CD35 BAB0 -8330CD36 BAB1 -8330CD37 BAB2 -8330CD38 BAB3 -8330CD39 BAB4 -8330CE30 BAB5 -8330CE31 BAB6 -8330CE32 BAB7 -8330CE33 BAB8 -8330CE34 BAB9 -8330CE35 BABA -8330CE36 BABB -8330CE37 BABC -8330CE38 BABD -8330CE39 BABE -8330CF30 BABF -8330CF31 BAC0 -8330CF32 BAC1 -8330CF33 BAC2 -8330CF34 BAC3 -8330CF35 BAC4 -8330CF36 BAC5 -8330CF37 BAC6 -8330CF38 BAC7 -8330CF39 BAC8 -8330D030 BAC9 -8330D031 BACA -8330D032 BACB -8330D033 BACC -8330D034 BACD -8330D035 BACE -8330D036 BACF -8330D037 BAD0 -8330D038 BAD1 -8330D039 BAD2 -8330D130 BAD3 -8330D131 BAD4 -8330D132 BAD5 -8330D133 BAD6 -8330D134 BAD7 -8330D135 BAD8 -8330D136 BAD9 -8330D137 BADA -8330D138 BADB -8330D139 BADC -8330D230 BADD -8330D231 BADE -8330D232 BADF -8330D233 BAE0 -8330D234 BAE1 -8330D235 BAE2 -8330D236 BAE3 -8330D237 BAE4 -8330D238 BAE5 -8330D239 BAE6 -8330D330 BAE7 -8330D331 BAE8 -8330D332 BAE9 -8330D333 BAEA -8330D334 BAEB -8330D335 BAEC -8330D336 BAED -8330D337 BAEE -8330D338 BAEF -8330D339 BAF0 -8330D430 BAF1 -8330D431 BAF2 -8330D432 BAF3 -8330D433 BAF4 -8330D434 BAF5 -8330D435 BAF6 -8330D436 BAF7 -8330D437 BAF8 -8330D438 BAF9 -8330D439 BAFA -8330D530 BAFB -8330D531 BAFC -8330D532 BAFD -8330D533 BAFE -8330D534 BAFF -8330D535 BB00 -8330D536 BB01 -8330D537 BB02 -8330D538 BB03 -8330D539 BB04 -8330D630 BB05 -8330D631 BB06 -8330D632 BB07 -8330D633 BB08 -8330D634 BB09 -8330D635 BB0A -8330D636 BB0B -8330D637 BB0C -8330D638 BB0D -8330D639 BB0E -8330D730 BB0F -8330D731 BB10 -8330D732 BB11 -8330D733 BB12 -8330D734 BB13 -8330D735 BB14 -8330D736 BB15 -8330D737 BB16 -8330D738 BB17 -8330D739 BB18 -8330D830 BB19 -8330D831 BB1A -8330D832 BB1B -8330D833 BB1C -8330D834 BB1D -8330D835 BB1E -8330D836 BB1F -8330D837 BB20 -8330D838 BB21 -8330D839 BB22 -8330D930 BB23 -8330D931 BB24 -8330D932 BB25 -8330D933 BB26 -8330D934 BB27 -8330D935 BB28 -8330D936 BB29 -8330D937 BB2A -8330D938 BB2B -8330D939 BB2C -8330DA30 BB2D -8330DA31 BB2E -8330DA32 BB2F -8330DA33 BB30 -8330DA34 BB31 -8330DA35 BB32 -8330DA36 BB33 -8330DA37 BB34 -8330DA38 BB35 -8330DA39 BB36 -8330DB30 BB37 -8330DB31 BB38 -8330DB32 BB39 -8330DB33 BB3A -8330DB34 BB3B -8330DB35 BB3C -8330DB36 BB3D -8330DB37 BB3E -8330DB38 BB3F -8330DB39 BB40 -8330DC30 BB41 -8330DC31 BB42 -8330DC32 BB43 -8330DC33 BB44 -8330DC34 BB45 -8330DC35 BB46 -8330DC36 BB47 -8330DC37 BB48 -8330DC38 BB49 -8330DC39 BB4A -8330DD30 BB4B -8330DD31 BB4C -8330DD32 BB4D -8330DD33 BB4E -8330DD34 BB4F -8330DD35 BB50 -8330DD36 BB51 -8330DD37 BB52 -8330DD38 BB53 -8330DD39 BB54 -8330DE30 BB55 -8330DE31 BB56 -8330DE32 BB57 -8330DE33 BB58 -8330DE34 BB59 -8330DE35 BB5A -8330DE36 BB5B -8330DE37 BB5C -8330DE38 BB5D -8330DE39 BB5E -8330DF30 BB5F -8330DF31 BB60 -8330DF32 BB61 -8330DF33 BB62 -8330DF34 BB63 -8330DF35 BB64 -8330DF36 BB65 -8330DF37 BB66 -8330DF38 BB67 -8330DF39 BB68 -8330E030 BB69 -8330E031 BB6A -8330E032 BB6B -8330E033 BB6C -8330E034 BB6D -8330E035 BB6E -8330E036 BB6F -8330E037 BB70 -8330E038 BB71 -8330E039 BB72 -8330E130 BB73 -8330E131 BB74 -8330E132 BB75 -8330E133 BB76 -8330E134 BB77 -8330E135 BB78 -8330E136 BB79 -8330E137 BB7A -8330E138 BB7B -8330E139 BB7C -8330E230 BB7D -8330E231 BB7E -8330E232 BB7F -8330E233 BB80 -8330E234 BB81 -8330E235 BB82 -8330E236 BB83 -8330E237 BB84 -8330E238 BB85 -8330E239 BB86 -8330E330 BB87 -8330E331 BB88 -8330E332 BB89 -8330E333 BB8A -8330E334 BB8B -8330E335 BB8C -8330E336 BB8D -8330E337 BB8E -8330E338 BB8F -8330E339 BB90 -8330E430 BB91 -8330E431 BB92 -8330E432 BB93 -8330E433 BB94 -8330E434 BB95 -8330E435 BB96 -8330E436 BB97 -8330E437 BB98 -8330E438 BB99 -8330E439 BB9A -8330E530 BB9B -8330E531 BB9C -8330E532 BB9D -8330E533 BB9E -8330E534 BB9F -8330E535 BBA0 -8330E536 BBA1 -8330E537 BBA2 -8330E538 BBA3 -8330E539 BBA4 -8330E630 BBA5 -8330E631 BBA6 -8330E632 BBA7 -8330E633 BBA8 -8330E634 BBA9 -8330E635 BBAA -8330E636 BBAB -8330E637 BBAC -8330E638 BBAD -8330E639 BBAE -8330E730 BBAF -8330E731 BBB0 -8330E732 BBB1 -8330E733 BBB2 -8330E734 BBB3 -8330E735 BBB4 -8330E736 BBB5 -8330E737 BBB6 -8330E738 BBB7 -8330E739 BBB8 -8330E830 BBB9 -8330E831 BBBA -8330E832 BBBB -8330E833 BBBC -8330E834 BBBD -8330E835 BBBE -8330E836 BBBF -8330E837 BBC0 -8330E838 BBC1 -8330E839 BBC2 -8330E930 BBC3 -8330E931 BBC4 -8330E932 BBC5 -8330E933 BBC6 -8330E934 BBC7 -8330E935 BBC8 -8330E936 BBC9 -8330E937 BBCA -8330E938 BBCB -8330E939 BBCC -8330EA30 BBCD -8330EA31 BBCE -8330EA32 BBCF -8330EA33 BBD0 -8330EA34 BBD1 -8330EA35 BBD2 -8330EA36 BBD3 -8330EA37 BBD4 -8330EA38 BBD5 -8330EA39 BBD6 -8330EB30 BBD7 -8330EB31 BBD8 -8330EB32 BBD9 -8330EB33 BBDA -8330EB34 BBDB -8330EB35 BBDC -8330EB36 BBDD -8330EB37 BBDE -8330EB38 BBDF -8330EB39 BBE0 -8330EC30 BBE1 -8330EC31 BBE2 -8330EC32 BBE3 -8330EC33 BBE4 -8330EC34 BBE5 -8330EC35 BBE6 -8330EC36 BBE7 -8330EC37 BBE8 -8330EC38 BBE9 -8330EC39 BBEA -8330ED30 BBEB -8330ED31 BBEC -8330ED32 BBED -8330ED33 BBEE -8330ED34 BBEF -8330ED35 BBF0 -8330ED36 BBF1 -8330ED37 BBF2 -8330ED38 BBF3 -8330ED39 BBF4 -8330EE30 BBF5 -8330EE31 BBF6 -8330EE32 BBF7 -8330EE33 BBF8 -8330EE34 BBF9 -8330EE35 BBFA -8330EE36 BBFB -8330EE37 BBFC -8330EE38 BBFD -8330EE39 BBFE -8330EF30 BBFF -8330EF31 BC00 -8330EF32 BC01 -8330EF33 BC02 -8330EF34 BC03 -8330EF35 BC04 -8330EF36 BC05 -8330EF37 BC06 -8330EF38 BC07 -8330EF39 BC08 -8330F030 BC09 -8330F031 BC0A -8330F032 BC0B -8330F033 BC0C -8330F034 BC0D -8330F035 BC0E -8330F036 BC0F -8330F037 BC10 -8330F038 BC11 -8330F039 BC12 -8330F130 BC13 -8330F131 BC14 -8330F132 BC15 -8330F133 BC16 -8330F134 BC17 -8330F135 BC18 -8330F136 BC19 -8330F137 BC1A -8330F138 BC1B -8330F139 BC1C -8330F230 BC1D -8330F231 BC1E -8330F232 BC1F -8330F233 BC20 -8330F234 BC21 -8330F235 BC22 -8330F236 BC23 -8330F237 BC24 -8330F238 BC25 -8330F239 BC26 -8330F330 BC27 -8330F331 BC28 -8330F332 BC29 -8330F333 BC2A -8330F334 BC2B -8330F335 BC2C -8330F336 BC2D -8330F337 BC2E -8330F338 BC2F -8330F339 BC30 -8330F430 BC31 -8330F431 BC32 -8330F432 BC33 -8330F433 BC34 -8330F434 BC35 -8330F435 BC36 -8330F436 BC37 -8330F437 BC38 -8330F438 BC39 -8330F439 BC3A -8330F530 BC3B -8330F531 BC3C -8330F532 BC3D -8330F533 BC3E -8330F534 BC3F -8330F535 BC40 -8330F536 BC41 -8330F537 BC42 -8330F538 BC43 -8330F539 BC44 -8330F630 BC45 -8330F631 BC46 -8330F632 BC47 -8330F633 BC48 -8330F634 BC49 -8330F635 BC4A -8330F636 BC4B -8330F637 BC4C -8330F638 BC4D -8330F639 BC4E -8330F730 BC4F -8330F731 BC50 -8330F732 BC51 -8330F733 BC52 -8330F734 BC53 -8330F735 BC54 -8330F736 BC55 -8330F737 BC56 -8330F738 BC57 -8330F739 BC58 -8330F830 BC59 -8330F831 BC5A -8330F832 BC5B -8330F833 BC5C -8330F834 BC5D -8330F835 BC5E -8330F836 BC5F -8330F837 BC60 -8330F838 BC61 -8330F839 BC62 -8330F930 BC63 -8330F931 BC64 -8330F932 BC65 -8330F933 BC66 -8330F934 BC67 -8330F935 BC68 -8330F936 BC69 -8330F937 BC6A -8330F938 BC6B -8330F939 BC6C -8330FA30 BC6D -8330FA31 BC6E -8330FA32 BC6F -8330FA33 BC70 -8330FA34 BC71 -8330FA35 BC72 -8330FA36 BC73 -8330FA37 BC74 -8330FA38 BC75 -8330FA39 BC76 -8330FB30 BC77 -8330FB31 BC78 -8330FB32 BC79 -8330FB33 BC7A -8330FB34 BC7B -8330FB35 BC7C -8330FB36 BC7D -8330FB37 BC7E -8330FB38 BC7F -8330FB39 BC80 -8330FC30 BC81 -8330FC31 BC82 -8330FC32 BC83 -8330FC33 BC84 -8330FC34 BC85 -8330FC35 BC86 -8330FC36 BC87 -8330FC37 BC88 -8330FC38 BC89 -8330FC39 BC8A -8330FD30 BC8B -8330FD31 BC8C -8330FD32 BC8D -8330FD33 BC8E -8330FD34 BC8F -8330FD35 BC90 -8330FD36 BC91 -8330FD37 BC92 -8330FD38 BC93 -8330FD39 BC94 -8330FE30 BC95 -8330FE31 BC96 -8330FE32 BC97 -8330FE33 BC98 -8330FE34 BC99 -8330FE35 BC9A -8330FE36 BC9B -8330FE37 BC9C -8330FE38 BC9D -8330FE39 BC9E -83318130 BC9F -83318131 BCA0 -83318132 BCA1 -83318133 BCA2 -83318134 BCA3 -83318135 BCA4 -83318136 BCA5 -83318137 BCA6 -83318138 BCA7 -83318139 BCA8 -83318230 BCA9 -83318231 BCAA -83318232 BCAB -83318233 BCAC -83318234 BCAD -83318235 BCAE -83318236 BCAF -83318237 BCB0 -83318238 BCB1 -83318239 BCB2 -83318330 BCB3 -83318331 BCB4 -83318332 BCB5 -83318333 BCB6 -83318334 BCB7 -83318335 BCB8 -83318336 BCB9 -83318337 BCBA -83318338 BCBB -83318339 BCBC -83318430 BCBD -83318431 BCBE -83318432 BCBF -83318433 BCC0 -83318434 BCC1 -83318435 BCC2 -83318436 BCC3 -83318437 BCC4 -83318438 BCC5 -83318439 BCC6 -83318530 BCC7 -83318531 BCC8 -83318532 BCC9 -83318533 BCCA -83318534 BCCB -83318535 BCCC -83318536 BCCD -83318537 BCCE -83318538 BCCF -83318539 BCD0 -83318630 BCD1 -83318631 BCD2 -83318632 BCD3 -83318633 BCD4 -83318634 BCD5 -83318635 BCD6 -83318636 BCD7 -83318637 BCD8 -83318638 BCD9 -83318639 BCDA -83318730 BCDB -83318731 BCDC -83318732 BCDD -83318733 BCDE -83318734 BCDF -83318735 BCE0 -83318736 BCE1 -83318737 BCE2 -83318738 BCE3 -83318739 BCE4 -83318830 BCE5 -83318831 BCE6 -83318832 BCE7 -83318833 BCE8 -83318834 BCE9 -83318835 BCEA -83318836 BCEB -83318837 BCEC -83318838 BCED -83318839 BCEE -83318930 BCEF -83318931 BCF0 -83318932 BCF1 -83318933 BCF2 -83318934 BCF3 -83318935 BCF4 -83318936 BCF5 -83318937 BCF6 -83318938 BCF7 -83318939 BCF8 -83318A30 BCF9 -83318A31 BCFA -83318A32 BCFB -83318A33 BCFC -83318A34 BCFD -83318A35 BCFE -83318A36 BCFF -83318A37 BD00 -83318A38 BD01 -83318A39 BD02 -83318B30 BD03 -83318B31 BD04 -83318B32 BD05 -83318B33 BD06 -83318B34 BD07 -83318B35 BD08 -83318B36 BD09 -83318B37 BD0A -83318B38 BD0B -83318B39 BD0C -83318C30 BD0D -83318C31 BD0E -83318C32 BD0F -83318C33 BD10 -83318C34 BD11 -83318C35 BD12 -83318C36 BD13 -83318C37 BD14 -83318C38 BD15 -83318C39 BD16 -83318D30 BD17 -83318D31 BD18 -83318D32 BD19 -83318D33 BD1A -83318D34 BD1B -83318D35 BD1C -83318D36 BD1D -83318D37 BD1E -83318D38 BD1F -83318D39 BD20 -83318E30 BD21 -83318E31 BD22 -83318E32 BD23 -83318E33 BD24 -83318E34 BD25 -83318E35 BD26 -83318E36 BD27 -83318E37 BD28 -83318E38 BD29 -83318E39 BD2A -83318F30 BD2B -83318F31 BD2C -83318F32 BD2D -83318F33 BD2E -83318F34 BD2F -83318F35 BD30 -83318F36 BD31 -83318F37 BD32 -83318F38 BD33 -83318F39 BD34 -83319030 BD35 -83319031 BD36 -83319032 BD37 -83319033 BD38 -83319034 BD39 -83319035 BD3A -83319036 BD3B -83319037 BD3C -83319038 BD3D -83319039 BD3E -83319130 BD3F -83319131 BD40 -83319132 BD41 -83319133 BD42 -83319134 BD43 -83319135 BD44 -83319136 BD45 -83319137 BD46 -83319138 BD47 -83319139 BD48 -83319230 BD49 -83319231 BD4A -83319232 BD4B -83319233 BD4C -83319234 BD4D -83319235 BD4E -83319236 BD4F -83319237 BD50 -83319238 BD51 -83319239 BD52 -83319330 BD53 -83319331 BD54 -83319332 BD55 -83319333 BD56 -83319334 BD57 -83319335 BD58 -83319336 BD59 -83319337 BD5A -83319338 BD5B -83319339 BD5C -83319430 BD5D -83319431 BD5E -83319432 BD5F -83319433 BD60 -83319434 BD61 -83319435 BD62 -83319436 BD63 -83319437 BD64 -83319438 BD65 -83319439 BD66 -83319530 BD67 -83319531 BD68 -83319532 BD69 -83319533 BD6A -83319534 BD6B -83319535 BD6C -83319536 BD6D -83319537 BD6E -83319538 BD6F -83319539 BD70 -83319630 BD71 -83319631 BD72 -83319632 BD73 -83319633 BD74 -83319634 BD75 -83319635 BD76 -83319636 BD77 -83319637 BD78 -83319638 BD79 -83319639 BD7A -83319730 BD7B -83319731 BD7C -83319732 BD7D -83319733 BD7E -83319734 BD7F -83319735 BD80 -83319736 BD81 -83319737 BD82 -83319738 BD83 -83319739 BD84 -83319830 BD85 -83319831 BD86 -83319832 BD87 -83319833 BD88 -83319834 BD89 -83319835 BD8A -83319836 BD8B -83319837 BD8C -83319838 BD8D -83319839 BD8E -83319930 BD8F -83319931 BD90 -83319932 BD91 -83319933 BD92 -83319934 BD93 -83319935 BD94 -83319936 BD95 -83319937 BD96 -83319938 BD97 -83319939 BD98 -83319A30 BD99 -83319A31 BD9A -83319A32 BD9B -83319A33 BD9C -83319A34 BD9D -83319A35 BD9E -83319A36 BD9F -83319A37 BDA0 -83319A38 BDA1 -83319A39 BDA2 -83319B30 BDA3 -83319B31 BDA4 -83319B32 BDA5 -83319B33 BDA6 -83319B34 BDA7 -83319B35 BDA8 -83319B36 BDA9 -83319B37 BDAA -83319B38 BDAB -83319B39 BDAC -83319C30 BDAD -83319C31 BDAE -83319C32 BDAF -83319C33 BDB0 -83319C34 BDB1 -83319C35 BDB2 -83319C36 BDB3 -83319C37 BDB4 -83319C38 BDB5 -83319C39 BDB6 -83319D30 BDB7 -83319D31 BDB8 -83319D32 BDB9 -83319D33 BDBA -83319D34 BDBB -83319D35 BDBC -83319D36 BDBD -83319D37 BDBE -83319D38 BDBF -83319D39 BDC0 -83319E30 BDC1 -83319E31 BDC2 -83319E32 BDC3 -83319E33 BDC4 -83319E34 BDC5 -83319E35 BDC6 -83319E36 BDC7 -83319E37 BDC8 -83319E38 BDC9 -83319E39 BDCA -83319F30 BDCB -83319F31 BDCC -83319F32 BDCD -83319F33 BDCE -83319F34 BDCF -83319F35 BDD0 -83319F36 BDD1 -83319F37 BDD2 -83319F38 BDD3 -83319F39 BDD4 -8331A030 BDD5 -8331A031 BDD6 -8331A032 BDD7 -8331A033 BDD8 -8331A034 BDD9 -8331A035 BDDA -8331A036 BDDB -8331A037 BDDC -8331A038 BDDD -8331A039 BDDE -8331A130 BDDF -8331A131 BDE0 -8331A132 BDE1 -8331A133 BDE2 -8331A134 BDE3 -8331A135 BDE4 -8331A136 BDE5 -8331A137 BDE6 -8331A138 BDE7 -8331A139 BDE8 -8331A230 BDE9 -8331A231 BDEA -8331A232 BDEB -8331A233 BDEC -8331A234 BDED -8331A235 BDEE -8331A236 BDEF -8331A237 BDF0 -8331A238 BDF1 -8331A239 BDF2 -8331A330 BDF3 -8331A331 BDF4 -8331A332 BDF5 -8331A333 BDF6 -8331A334 BDF7 -8331A335 BDF8 -8331A336 BDF9 -8331A337 BDFA -8331A338 BDFB -8331A339 BDFC -8331A430 BDFD -8331A431 BDFE -8331A432 BDFF -8331A433 BE00 -8331A434 BE01 -8331A435 BE02 -8331A436 BE03 -8331A437 BE04 -8331A438 BE05 -8331A439 BE06 -8331A530 BE07 -8331A531 BE08 -8331A532 BE09 -8331A533 BE0A -8331A534 BE0B -8331A535 BE0C -8331A536 BE0D -8331A537 BE0E -8331A538 BE0F -8331A539 BE10 -8331A630 BE11 -8331A631 BE12 -8331A632 BE13 -8331A633 BE14 -8331A634 BE15 -8331A635 BE16 -8331A636 BE17 -8331A637 BE18 -8331A638 BE19 -8331A639 BE1A -8331A730 BE1B -8331A731 BE1C -8331A732 BE1D -8331A733 BE1E -8331A734 BE1F -8331A735 BE20 -8331A736 BE21 -8331A737 BE22 -8331A738 BE23 -8331A739 BE24 -8331A830 BE25 -8331A831 BE26 -8331A832 BE27 -8331A833 BE28 -8331A834 BE29 -8331A835 BE2A -8331A836 BE2B -8331A837 BE2C -8331A838 BE2D -8331A839 BE2E -8331A930 BE2F -8331A931 BE30 -8331A932 BE31 -8331A933 BE32 -8331A934 BE33 -8331A935 BE34 -8331A936 BE35 -8331A937 BE36 -8331A938 BE37 -8331A939 BE38 -8331AA30 BE39 -8331AA31 BE3A -8331AA32 BE3B -8331AA33 BE3C -8331AA34 BE3D -8331AA35 BE3E -8331AA36 BE3F -8331AA37 BE40 -8331AA38 BE41 -8331AA39 BE42 -8331AB30 BE43 -8331AB31 BE44 -8331AB32 BE45 -8331AB33 BE46 -8331AB34 BE47 -8331AB35 BE48 -8331AB36 BE49 -8331AB37 BE4A -8331AB38 BE4B -8331AB39 BE4C -8331AC30 BE4D -8331AC31 BE4E -8331AC32 BE4F -8331AC33 BE50 -8331AC34 BE51 -8331AC35 BE52 -8331AC36 BE53 -8331AC37 BE54 -8331AC38 BE55 -8331AC39 BE56 -8331AD30 BE57 -8331AD31 BE58 -8331AD32 BE59 -8331AD33 BE5A -8331AD34 BE5B -8331AD35 BE5C -8331AD36 BE5D -8331AD37 BE5E -8331AD38 BE5F -8331AD39 BE60 -8331AE30 BE61 -8331AE31 BE62 -8331AE32 BE63 -8331AE33 BE64 -8331AE34 BE65 -8331AE35 BE66 -8331AE36 BE67 -8331AE37 BE68 -8331AE38 BE69 -8331AE39 BE6A -8331AF30 BE6B -8331AF31 BE6C -8331AF32 BE6D -8331AF33 BE6E -8331AF34 BE6F -8331AF35 BE70 -8331AF36 BE71 -8331AF37 BE72 -8331AF38 BE73 -8331AF39 BE74 -8331B030 BE75 -8331B031 BE76 -8331B032 BE77 -8331B033 BE78 -8331B034 BE79 -8331B035 BE7A -8331B036 BE7B -8331B037 BE7C -8331B038 BE7D -8331B039 BE7E -8331B130 BE7F -8331B131 BE80 -8331B132 BE81 -8331B133 BE82 -8331B134 BE83 -8331B135 BE84 -8331B136 BE85 -8331B137 BE86 -8331B138 BE87 -8331B139 BE88 -8331B230 BE89 -8331B231 BE8A -8331B232 BE8B -8331B233 BE8C -8331B234 BE8D -8331B235 BE8E -8331B236 BE8F -8331B237 BE90 -8331B238 BE91 -8331B239 BE92 -8331B330 BE93 -8331B331 BE94 -8331B332 BE95 -8331B333 BE96 -8331B334 BE97 -8331B335 BE98 -8331B336 BE99 -8331B337 BE9A -8331B338 BE9B -8331B339 BE9C -8331B430 BE9D -8331B431 BE9E -8331B432 BE9F -8331B433 BEA0 -8331B434 BEA1 -8331B435 BEA2 -8331B436 BEA3 -8331B437 BEA4 -8331B438 BEA5 -8331B439 BEA6 -8331B530 BEA7 -8331B531 BEA8 -8331B532 BEA9 -8331B533 BEAA -8331B534 BEAB -8331B535 BEAC -8331B536 BEAD -8331B537 BEAE -8331B538 BEAF -8331B539 BEB0 -8331B630 BEB1 -8331B631 BEB2 -8331B632 BEB3 -8331B633 BEB4 -8331B634 BEB5 -8331B635 BEB6 -8331B636 BEB7 -8331B637 BEB8 -8331B638 BEB9 -8331B639 BEBA -8331B730 BEBB -8331B731 BEBC -8331B732 BEBD -8331B733 BEBE -8331B734 BEBF -8331B735 BEC0 -8331B736 BEC1 -8331B737 BEC2 -8331B738 BEC3 -8331B739 BEC4 -8331B830 BEC5 -8331B831 BEC6 -8331B832 BEC7 -8331B833 BEC8 -8331B834 BEC9 -8331B835 BECA -8331B836 BECB -8331B837 BECC -8331B838 BECD -8331B839 BECE -8331B930 BECF -8331B931 BED0 -8331B932 BED1 -8331B933 BED2 -8331B934 BED3 -8331B935 BED4 -8331B936 BED5 -8331B937 BED6 -8331B938 BED7 -8331B939 BED8 -8331BA30 BED9 -8331BA31 BEDA -8331BA32 BEDB -8331BA33 BEDC -8331BA34 BEDD -8331BA35 BEDE -8331BA36 BEDF -8331BA37 BEE0 -8331BA38 BEE1 -8331BA39 BEE2 -8331BB30 BEE3 -8331BB31 BEE4 -8331BB32 BEE5 -8331BB33 BEE6 -8331BB34 BEE7 -8331BB35 BEE8 -8331BB36 BEE9 -8331BB37 BEEA -8331BB38 BEEB -8331BB39 BEEC -8331BC30 BEED -8331BC31 BEEE -8331BC32 BEEF -8331BC33 BEF0 -8331BC34 BEF1 -8331BC35 BEF2 -8331BC36 BEF3 -8331BC37 BEF4 -8331BC38 BEF5 -8331BC39 BEF6 -8331BD30 BEF7 -8331BD31 BEF8 -8331BD32 BEF9 -8331BD33 BEFA -8331BD34 BEFB -8331BD35 BEFC -8331BD36 BEFD -8331BD37 BEFE -8331BD38 BEFF -8331BD39 BF00 -8331BE30 BF01 -8331BE31 BF02 -8331BE32 BF03 -8331BE33 BF04 -8331BE34 BF05 -8331BE35 BF06 -8331BE36 BF07 -8331BE37 BF08 -8331BE38 BF09 -8331BE39 BF0A -8331BF30 BF0B -8331BF31 BF0C -8331BF32 BF0D -8331BF33 BF0E -8331BF34 BF0F -8331BF35 BF10 -8331BF36 BF11 -8331BF37 BF12 -8331BF38 BF13 -8331BF39 BF14 -8331C030 BF15 -8331C031 BF16 -8331C032 BF17 -8331C033 BF18 -8331C034 BF19 -8331C035 BF1A -8331C036 BF1B -8331C037 BF1C -8331C038 BF1D -8331C039 BF1E -8331C130 BF1F -8331C131 BF20 -8331C132 BF21 -8331C133 BF22 -8331C134 BF23 -8331C135 BF24 -8331C136 BF25 -8331C137 BF26 -8331C138 BF27 -8331C139 BF28 -8331C230 BF29 -8331C231 BF2A -8331C232 BF2B -8331C233 BF2C -8331C234 BF2D -8331C235 BF2E -8331C236 BF2F -8331C237 BF30 -8331C238 BF31 -8331C239 BF32 -8331C330 BF33 -8331C331 BF34 -8331C332 BF35 -8331C333 BF36 -8331C334 BF37 -8331C335 BF38 -8331C336 BF39 -8331C337 BF3A -8331C338 BF3B -8331C339 BF3C -8331C430 BF3D -8331C431 BF3E -8331C432 BF3F -8331C433 BF40 -8331C434 BF41 -8331C435 BF42 -8331C436 BF43 -8331C437 BF44 -8331C438 BF45 -8331C439 BF46 -8331C530 BF47 -8331C531 BF48 -8331C532 BF49 -8331C533 BF4A -8331C534 BF4B -8331C535 BF4C -8331C536 BF4D -8331C537 BF4E -8331C538 BF4F -8331C539 BF50 -8331C630 BF51 -8331C631 BF52 -8331C632 BF53 -8331C633 BF54 -8331C634 BF55 -8331C635 BF56 -8331C636 BF57 -8331C637 BF58 -8331C638 BF59 -8331C639 BF5A -8331C730 BF5B -8331C731 BF5C -8331C732 BF5D -8331C733 BF5E -8331C734 BF5F -8331C735 BF60 -8331C736 BF61 -8331C737 BF62 -8331C738 BF63 -8331C739 BF64 -8331C830 BF65 -8331C831 BF66 -8331C832 BF67 -8331C833 BF68 -8331C834 BF69 -8331C835 BF6A -8331C836 BF6B -8331C837 BF6C -8331C838 BF6D -8331C839 BF6E -8331C930 BF6F -8331C931 BF70 -8331C932 BF71 -8331C933 BF72 -8331C934 BF73 -8331C935 BF74 -8331C936 BF75 -8331C937 BF76 -8331C938 BF77 -8331C939 BF78 -8331CA30 BF79 -8331CA31 BF7A -8331CA32 BF7B -8331CA33 BF7C -8331CA34 BF7D -8331CA35 BF7E -8331CA36 BF7F -8331CA37 BF80 -8331CA38 BF81 -8331CA39 BF82 -8331CB30 BF83 -8331CB31 BF84 -8331CB32 BF85 -8331CB33 BF86 -8331CB34 BF87 -8331CB35 BF88 -8331CB36 BF89 -8331CB37 BF8A -8331CB38 BF8B -8331CB39 BF8C -8331CC30 BF8D -8331CC31 BF8E -8331CC32 BF8F -8331CC33 BF90 -8331CC34 BF91 -8331CC35 BF92 -8331CC36 BF93 -8331CC37 BF94 -8331CC38 BF95 -8331CC39 BF96 -8331CD30 BF97 -8331CD31 BF98 -8331CD32 BF99 -8331CD33 BF9A -8331CD34 BF9B -8331CD35 BF9C -8331CD36 BF9D -8331CD37 BF9E -8331CD38 BF9F -8331CD39 BFA0 -8331CE30 BFA1 -8331CE31 BFA2 -8331CE32 BFA3 -8331CE33 BFA4 -8331CE34 BFA5 -8331CE35 BFA6 -8331CE36 BFA7 -8331CE37 BFA8 -8331CE38 BFA9 -8331CE39 BFAA -8331CF30 BFAB -8331CF31 BFAC -8331CF32 BFAD -8331CF33 BFAE -8331CF34 BFAF -8331CF35 BFB0 -8331CF36 BFB1 -8331CF37 BFB2 -8331CF38 BFB3 -8331CF39 BFB4 -8331D030 BFB5 -8331D031 BFB6 -8331D032 BFB7 -8331D033 BFB8 -8331D034 BFB9 -8331D035 BFBA -8331D036 BFBB -8331D037 BFBC -8331D038 BFBD -8331D039 BFBE -8331D130 BFBF -8331D131 BFC0 -8331D132 BFC1 -8331D133 BFC2 -8331D134 BFC3 -8331D135 BFC4 -8331D136 BFC5 -8331D137 BFC6 -8331D138 BFC7 -8331D139 BFC8 -8331D230 BFC9 -8331D231 BFCA -8331D232 BFCB -8331D233 BFCC -8331D234 BFCD -8331D235 BFCE -8331D236 BFCF -8331D237 BFD0 -8331D238 BFD1 -8331D239 BFD2 -8331D330 BFD3 -8331D331 BFD4 -8331D332 BFD5 -8331D333 BFD6 -8331D334 BFD7 -8331D335 BFD8 -8331D336 BFD9 -8331D337 BFDA -8331D338 BFDB -8331D339 BFDC -8331D430 BFDD -8331D431 BFDE -8331D432 BFDF -8331D433 BFE0 -8331D434 BFE1 -8331D435 BFE2 -8331D436 BFE3 -8331D437 BFE4 -8331D438 BFE5 -8331D439 BFE6 -8331D530 BFE7 -8331D531 BFE8 -8331D532 BFE9 -8331D533 BFEA -8331D534 BFEB -8331D535 BFEC -8331D536 BFED -8331D537 BFEE -8331D538 BFEF -8331D539 BFF0 -8331D630 BFF1 -8331D631 BFF2 -8331D632 BFF3 -8331D633 BFF4 -8331D634 BFF5 -8331D635 BFF6 -8331D636 BFF7 -8331D637 BFF8 -8331D638 BFF9 -8331D639 BFFA -8331D730 BFFB -8331D731 BFFC -8331D732 BFFD -8331D733 BFFE -8331D734 BFFF -8331D735 C000 -8331D736 C001 -8331D737 C002 -8331D738 C003 -8331D739 C004 -8331D830 C005 -8331D831 C006 -8331D832 C007 -8331D833 C008 -8331D834 C009 -8331D835 C00A -8331D836 C00B -8331D837 C00C -8331D838 C00D -8331D839 C00E -8331D930 C00F -8331D931 C010 -8331D932 C011 -8331D933 C012 -8331D934 C013 -8331D935 C014 -8331D936 C015 -8331D937 C016 -8331D938 C017 -8331D939 C018 -8331DA30 C019 -8331DA31 C01A -8331DA32 C01B -8331DA33 C01C -8331DA34 C01D -8331DA35 C01E -8331DA36 C01F -8331DA37 C020 -8331DA38 C021 -8331DA39 C022 -8331DB30 C023 -8331DB31 C024 -8331DB32 C025 -8331DB33 C026 -8331DB34 C027 -8331DB35 C028 -8331DB36 C029 -8331DB37 C02A -8331DB38 C02B -8331DB39 C02C -8331DC30 C02D -8331DC31 C02E -8331DC32 C02F -8331DC33 C030 -8331DC34 C031 -8331DC35 C032 -8331DC36 C033 -8331DC37 C034 -8331DC38 C035 -8331DC39 C036 -8331DD30 C037 -8331DD31 C038 -8331DD32 C039 -8331DD33 C03A -8331DD34 C03B -8331DD35 C03C -8331DD36 C03D -8331DD37 C03E -8331DD38 C03F -8331DD39 C040 -8331DE30 C041 -8331DE31 C042 -8331DE32 C043 -8331DE33 C044 -8331DE34 C045 -8331DE35 C046 -8331DE36 C047 -8331DE37 C048 -8331DE38 C049 -8331DE39 C04A -8331DF30 C04B -8331DF31 C04C -8331DF32 C04D -8331DF33 C04E -8331DF34 C04F -8331DF35 C050 -8331DF36 C051 -8331DF37 C052 -8331DF38 C053 -8331DF39 C054 -8331E030 C055 -8331E031 C056 -8331E032 C057 -8331E033 C058 -8331E034 C059 -8331E035 C05A -8331E036 C05B -8331E037 C05C -8331E038 C05D -8331E039 C05E -8331E130 C05F -8331E131 C060 -8331E132 C061 -8331E133 C062 -8331E134 C063 -8331E135 C064 -8331E136 C065 -8331E137 C066 -8331E138 C067 -8331E139 C068 -8331E230 C069 -8331E231 C06A -8331E232 C06B -8331E233 C06C -8331E234 C06D -8331E235 C06E -8331E236 C06F -8331E237 C070 -8331E238 C071 -8331E239 C072 -8331E330 C073 -8331E331 C074 -8331E332 C075 -8331E333 C076 -8331E334 C077 -8331E335 C078 -8331E336 C079 -8331E337 C07A -8331E338 C07B -8331E339 C07C -8331E430 C07D -8331E431 C07E -8331E432 C07F -8331E433 C080 -8331E434 C081 -8331E435 C082 -8331E436 C083 -8331E437 C084 -8331E438 C085 -8331E439 C086 -8331E530 C087 -8331E531 C088 -8331E532 C089 -8331E533 C08A -8331E534 C08B -8331E535 C08C -8331E536 C08D -8331E537 C08E -8331E538 C08F -8331E539 C090 -8331E630 C091 -8331E631 C092 -8331E632 C093 -8331E633 C094 -8331E634 C095 -8331E635 C096 -8331E636 C097 -8331E637 C098 -8331E638 C099 -8331E639 C09A -8331E730 C09B -8331E731 C09C -8331E732 C09D -8331E733 C09E -8331E734 C09F -8331E735 C0A0 -8331E736 C0A1 -8331E737 C0A2 -8331E738 C0A3 -8331E739 C0A4 -8331E830 C0A5 -8331E831 C0A6 -8331E832 C0A7 -8331E833 C0A8 -8331E834 C0A9 -8331E835 C0AA -8331E836 C0AB -8331E837 C0AC -8331E838 C0AD -8331E839 C0AE -8331E930 C0AF -8331E931 C0B0 -8331E932 C0B1 -8331E933 C0B2 -8331E934 C0B3 -8331E935 C0B4 -8331E936 C0B5 -8331E937 C0B6 -8331E938 C0B7 -8331E939 C0B8 -8331EA30 C0B9 -8331EA31 C0BA -8331EA32 C0BB -8331EA33 C0BC -8331EA34 C0BD -8331EA35 C0BE -8331EA36 C0BF -8331EA37 C0C0 -8331EA38 C0C1 -8331EA39 C0C2 -8331EB30 C0C3 -8331EB31 C0C4 -8331EB32 C0C5 -8331EB33 C0C6 -8331EB34 C0C7 -8331EB35 C0C8 -8331EB36 C0C9 -8331EB37 C0CA -8331EB38 C0CB -8331EB39 C0CC -8331EC30 C0CD -8331EC31 C0CE -8331EC32 C0CF -8331EC33 C0D0 -8331EC34 C0D1 -8331EC35 C0D2 -8331EC36 C0D3 -8331EC37 C0D4 -8331EC38 C0D5 -8331EC39 C0D6 -8331ED30 C0D7 -8331ED31 C0D8 -8331ED32 C0D9 -8331ED33 C0DA -8331ED34 C0DB -8331ED35 C0DC -8331ED36 C0DD -8331ED37 C0DE -8331ED38 C0DF -8331ED39 C0E0 -8331EE30 C0E1 -8331EE31 C0E2 -8331EE32 C0E3 -8331EE33 C0E4 -8331EE34 C0E5 -8331EE35 C0E6 -8331EE36 C0E7 -8331EE37 C0E8 -8331EE38 C0E9 -8331EE39 C0EA -8331EF30 C0EB -8331EF31 C0EC -8331EF32 C0ED -8331EF33 C0EE -8331EF34 C0EF -8331EF35 C0F0 -8331EF36 C0F1 -8331EF37 C0F2 -8331EF38 C0F3 -8331EF39 C0F4 -8331F030 C0F5 -8331F031 C0F6 -8331F032 C0F7 -8331F033 C0F8 -8331F034 C0F9 -8331F035 C0FA -8331F036 C0FB -8331F037 C0FC -8331F038 C0FD -8331F039 C0FE -8331F130 C0FF -8331F131 C100 -8331F132 C101 -8331F133 C102 -8331F134 C103 -8331F135 C104 -8331F136 C105 -8331F137 C106 -8331F138 C107 -8331F139 C108 -8331F230 C109 -8331F231 C10A -8331F232 C10B -8331F233 C10C -8331F234 C10D -8331F235 C10E -8331F236 C10F -8331F237 C110 -8331F238 C111 -8331F239 C112 -8331F330 C113 -8331F331 C114 -8331F332 C115 -8331F333 C116 -8331F334 C117 -8331F335 C118 -8331F336 C119 -8331F337 C11A -8331F338 C11B -8331F339 C11C -8331F430 C11D -8331F431 C11E -8331F432 C11F -8331F433 C120 -8331F434 C121 -8331F435 C122 -8331F436 C123 -8331F437 C124 -8331F438 C125 -8331F439 C126 -8331F530 C127 -8331F531 C128 -8331F532 C129 -8331F533 C12A -8331F534 C12B -8331F535 C12C -8331F536 C12D -8331F537 C12E -8331F538 C12F -8331F539 C130 -8331F630 C131 -8331F631 C132 -8331F632 C133 -8331F633 C134 -8331F634 C135 -8331F635 C136 -8331F636 C137 -8331F637 C138 -8331F638 C139 -8331F639 C13A -8331F730 C13B -8331F731 C13C -8331F732 C13D -8331F733 C13E -8331F734 C13F -8331F735 C140 -8331F736 C141 -8331F737 C142 -8331F738 C143 -8331F739 C144 -8331F830 C145 -8331F831 C146 -8331F832 C147 -8331F833 C148 -8331F834 C149 -8331F835 C14A -8331F836 C14B -8331F837 C14C -8331F838 C14D -8331F839 C14E -8331F930 C14F -8331F931 C150 -8331F932 C151 -8331F933 C152 -8331F934 C153 -8331F935 C154 -8331F936 C155 -8331F937 C156 -8331F938 C157 -8331F939 C158 -8331FA30 C159 -8331FA31 C15A -8331FA32 C15B -8331FA33 C15C -8331FA34 C15D -8331FA35 C15E -8331FA36 C15F -8331FA37 C160 -8331FA38 C161 -8331FA39 C162 -8331FB30 C163 -8331FB31 C164 -8331FB32 C165 -8331FB33 C166 -8331FB34 C167 -8331FB35 C168 -8331FB36 C169 -8331FB37 C16A -8331FB38 C16B -8331FB39 C16C -8331FC30 C16D -8331FC31 C16E -8331FC32 C16F -8331FC33 C170 -8331FC34 C171 -8331FC35 C172 -8331FC36 C173 -8331FC37 C174 -8331FC38 C175 -8331FC39 C176 -8331FD30 C177 -8331FD31 C178 -8331FD32 C179 -8331FD33 C17A -8331FD34 C17B -8331FD35 C17C -8331FD36 C17D -8331FD37 C17E -8331FD38 C17F -8331FD39 C180 -8331FE30 C181 -8331FE31 C182 -8331FE32 C183 -8331FE33 C184 -8331FE34 C185 -8331FE35 C186 -8331FE36 C187 -8331FE37 C188 -8331FE38 C189 -8331FE39 C18A -83328130 C18B -83328131 C18C -83328132 C18D -83328133 C18E -83328134 C18F -83328135 C190 -83328136 C191 -83328137 C192 -83328138 C193 -83328139 C194 -83328230 C195 -83328231 C196 -83328232 C197 -83328233 C198 -83328234 C199 -83328235 C19A -83328236 C19B -83328237 C19C -83328238 C19D -83328239 C19E -83328330 C19F -83328331 C1A0 -83328332 C1A1 -83328333 C1A2 -83328334 C1A3 -83328335 C1A4 -83328336 C1A5 -83328337 C1A6 -83328338 C1A7 -83328339 C1A8 -83328430 C1A9 -83328431 C1AA -83328432 C1AB -83328433 C1AC -83328434 C1AD -83328435 C1AE -83328436 C1AF -83328437 C1B0 -83328438 C1B1 -83328439 C1B2 -83328530 C1B3 -83328531 C1B4 -83328532 C1B5 -83328533 C1B6 -83328534 C1B7 -83328535 C1B8 -83328536 C1B9 -83328537 C1BA -83328538 C1BB -83328539 C1BC -83328630 C1BD -83328631 C1BE -83328632 C1BF -83328633 C1C0 -83328634 C1C1 -83328635 C1C2 -83328636 C1C3 -83328637 C1C4 -83328638 C1C5 -83328639 C1C6 -83328730 C1C7 -83328731 C1C8 -83328732 C1C9 -83328733 C1CA -83328734 C1CB -83328735 C1CC -83328736 C1CD -83328737 C1CE -83328738 C1CF -83328739 C1D0 -83328830 C1D1 -83328831 C1D2 -83328832 C1D3 -83328833 C1D4 -83328834 C1D5 -83328835 C1D6 -83328836 C1D7 -83328837 C1D8 -83328838 C1D9 -83328839 C1DA -83328930 C1DB -83328931 C1DC -83328932 C1DD -83328933 C1DE -83328934 C1DF -83328935 C1E0 -83328936 C1E1 -83328937 C1E2 -83328938 C1E3 -83328939 C1E4 -83328A30 C1E5 -83328A31 C1E6 -83328A32 C1E7 -83328A33 C1E8 -83328A34 C1E9 -83328A35 C1EA -83328A36 C1EB -83328A37 C1EC -83328A38 C1ED -83328A39 C1EE -83328B30 C1EF -83328B31 C1F0 -83328B32 C1F1 -83328B33 C1F2 -83328B34 C1F3 -83328B35 C1F4 -83328B36 C1F5 -83328B37 C1F6 -83328B38 C1F7 -83328B39 C1F8 -83328C30 C1F9 -83328C31 C1FA -83328C32 C1FB -83328C33 C1FC -83328C34 C1FD -83328C35 C1FE -83328C36 C1FF -83328C37 C200 -83328C38 C201 -83328C39 C202 -83328D30 C203 -83328D31 C204 -83328D32 C205 -83328D33 C206 -83328D34 C207 -83328D35 C208 -83328D36 C209 -83328D37 C20A -83328D38 C20B -83328D39 C20C -83328E30 C20D -83328E31 C20E -83328E32 C20F -83328E33 C210 -83328E34 C211 -83328E35 C212 -83328E36 C213 -83328E37 C214 -83328E38 C215 -83328E39 C216 -83328F30 C217 -83328F31 C218 -83328F32 C219 -83328F33 C21A -83328F34 C21B -83328F35 C21C -83328F36 C21D -83328F37 C21E -83328F38 C21F -83328F39 C220 -83329030 C221 -83329031 C222 -83329032 C223 -83329033 C224 -83329034 C225 -83329035 C226 -83329036 C227 -83329037 C228 -83329038 C229 -83329039 C22A -83329130 C22B -83329131 C22C -83329132 C22D -83329133 C22E -83329134 C22F -83329135 C230 -83329136 C231 -83329137 C232 -83329138 C233 -83329139 C234 -83329230 C235 -83329231 C236 -83329232 C237 -83329233 C238 -83329234 C239 -83329235 C23A -83329236 C23B -83329237 C23C -83329238 C23D -83329239 C23E -83329330 C23F -83329331 C240 -83329332 C241 -83329333 C242 -83329334 C243 -83329335 C244 -83329336 C245 -83329337 C246 -83329338 C247 -83329339 C248 -83329430 C249 -83329431 C24A -83329432 C24B -83329433 C24C -83329434 C24D -83329435 C24E -83329436 C24F -83329437 C250 -83329438 C251 -83329439 C252 -83329530 C253 -83329531 C254 -83329532 C255 -83329533 C256 -83329534 C257 -83329535 C258 -83329536 C259 -83329537 C25A -83329538 C25B -83329539 C25C -83329630 C25D -83329631 C25E -83329632 C25F -83329633 C260 -83329634 C261 -83329635 C262 -83329636 C263 -83329637 C264 -83329638 C265 -83329639 C266 -83329730 C267 -83329731 C268 -83329732 C269 -83329733 C26A -83329734 C26B -83329735 C26C -83329736 C26D -83329737 C26E -83329738 C26F -83329739 C270 -83329830 C271 -83329831 C272 -83329832 C273 -83329833 C274 -83329834 C275 -83329835 C276 -83329836 C277 -83329837 C278 -83329838 C279 -83329839 C27A -83329930 C27B -83329931 C27C -83329932 C27D -83329933 C27E -83329934 C27F -83329935 C280 -83329936 C281 -83329937 C282 -83329938 C283 -83329939 C284 -83329A30 C285 -83329A31 C286 -83329A32 C287 -83329A33 C288 -83329A34 C289 -83329A35 C28A -83329A36 C28B -83329A37 C28C -83329A38 C28D -83329A39 C28E -83329B30 C28F -83329B31 C290 -83329B32 C291 -83329B33 C292 -83329B34 C293 -83329B35 C294 -83329B36 C295 -83329B37 C296 -83329B38 C297 -83329B39 C298 -83329C30 C299 -83329C31 C29A -83329C32 C29B -83329C33 C29C -83329C34 C29D -83329C35 C29E -83329C36 C29F -83329C37 C2A0 -83329C38 C2A1 -83329C39 C2A2 -83329D30 C2A3 -83329D31 C2A4 -83329D32 C2A5 -83329D33 C2A6 -83329D34 C2A7 -83329D35 C2A8 -83329D36 C2A9 -83329D37 C2AA -83329D38 C2AB -83329D39 C2AC -83329E30 C2AD -83329E31 C2AE -83329E32 C2AF -83329E33 C2B0 -83329E34 C2B1 -83329E35 C2B2 -83329E36 C2B3 -83329E37 C2B4 -83329E38 C2B5 -83329E39 C2B6 -83329F30 C2B7 -83329F31 C2B8 -83329F32 C2B9 -83329F33 C2BA -83329F34 C2BB -83329F35 C2BC -83329F36 C2BD -83329F37 C2BE -83329F38 C2BF -83329F39 C2C0 -8332A030 C2C1 -8332A031 C2C2 -8332A032 C2C3 -8332A033 C2C4 -8332A034 C2C5 -8332A035 C2C6 -8332A036 C2C7 -8332A037 C2C8 -8332A038 C2C9 -8332A039 C2CA -8332A130 C2CB -8332A131 C2CC -8332A132 C2CD -8332A133 C2CE -8332A134 C2CF -8332A135 C2D0 -8332A136 C2D1 -8332A137 C2D2 -8332A138 C2D3 -8332A139 C2D4 -8332A230 C2D5 -8332A231 C2D6 -8332A232 C2D7 -8332A233 C2D8 -8332A234 C2D9 -8332A235 C2DA -8332A236 C2DB -8332A237 C2DC -8332A238 C2DD -8332A239 C2DE -8332A330 C2DF -8332A331 C2E0 -8332A332 C2E1 -8332A333 C2E2 -8332A334 C2E3 -8332A335 C2E4 -8332A336 C2E5 -8332A337 C2E6 -8332A338 C2E7 -8332A339 C2E8 -8332A430 C2E9 -8332A431 C2EA -8332A432 C2EB -8332A433 C2EC -8332A434 C2ED -8332A435 C2EE -8332A436 C2EF -8332A437 C2F0 -8332A438 C2F1 -8332A439 C2F2 -8332A530 C2F3 -8332A531 C2F4 -8332A532 C2F5 -8332A533 C2F6 -8332A534 C2F7 -8332A535 C2F8 -8332A536 C2F9 -8332A537 C2FA -8332A538 C2FB -8332A539 C2FC -8332A630 C2FD -8332A631 C2FE -8332A632 C2FF -8332A633 C300 -8332A634 C301 -8332A635 C302 -8332A636 C303 -8332A637 C304 -8332A638 C305 -8332A639 C306 -8332A730 C307 -8332A731 C308 -8332A732 C309 -8332A733 C30A -8332A734 C30B -8332A735 C30C -8332A736 C30D -8332A737 C30E -8332A738 C30F -8332A739 C310 -8332A830 C311 -8332A831 C312 -8332A832 C313 -8332A833 C314 -8332A834 C315 -8332A835 C316 -8332A836 C317 -8332A837 C318 -8332A838 C319 -8332A839 C31A -8332A930 C31B -8332A931 C31C -8332A932 C31D -8332A933 C31E -8332A934 C31F -8332A935 C320 -8332A936 C321 -8332A937 C322 -8332A938 C323 -8332A939 C324 -8332AA30 C325 -8332AA31 C326 -8332AA32 C327 -8332AA33 C328 -8332AA34 C329 -8332AA35 C32A -8332AA36 C32B -8332AA37 C32C -8332AA38 C32D -8332AA39 C32E -8332AB30 C32F -8332AB31 C330 -8332AB32 C331 -8332AB33 C332 -8332AB34 C333 -8332AB35 C334 -8332AB36 C335 -8332AB37 C336 -8332AB38 C337 -8332AB39 C338 -8332AC30 C339 -8332AC31 C33A -8332AC32 C33B -8332AC33 C33C -8332AC34 C33D -8332AC35 C33E -8332AC36 C33F -8332AC37 C340 -8332AC38 C341 -8332AC39 C342 -8332AD30 C343 -8332AD31 C344 -8332AD32 C345 -8332AD33 C346 -8332AD34 C347 -8332AD35 C348 -8332AD36 C349 -8332AD37 C34A -8332AD38 C34B -8332AD39 C34C -8332AE30 C34D -8332AE31 C34E -8332AE32 C34F -8332AE33 C350 -8332AE34 C351 -8332AE35 C352 -8332AE36 C353 -8332AE37 C354 -8332AE38 C355 -8332AE39 C356 -8332AF30 C357 -8332AF31 C358 -8332AF32 C359 -8332AF33 C35A -8332AF34 C35B -8332AF35 C35C -8332AF36 C35D -8332AF37 C35E -8332AF38 C35F -8332AF39 C360 -8332B030 C361 -8332B031 C362 -8332B032 C363 -8332B033 C364 -8332B034 C365 -8332B035 C366 -8332B036 C367 -8332B037 C368 -8332B038 C369 -8332B039 C36A -8332B130 C36B -8332B131 C36C -8332B132 C36D -8332B133 C36E -8332B134 C36F -8332B135 C370 -8332B136 C371 -8332B137 C372 -8332B138 C373 -8332B139 C374 -8332B230 C375 -8332B231 C376 -8332B232 C377 -8332B233 C378 -8332B234 C379 -8332B235 C37A -8332B236 C37B -8332B237 C37C -8332B238 C37D -8332B239 C37E -8332B330 C37F -8332B331 C380 -8332B332 C381 -8332B333 C382 -8332B334 C383 -8332B335 C384 -8332B336 C385 -8332B337 C386 -8332B338 C387 -8332B339 C388 -8332B430 C389 -8332B431 C38A -8332B432 C38B -8332B433 C38C -8332B434 C38D -8332B435 C38E -8332B436 C38F -8332B437 C390 -8332B438 C391 -8332B439 C392 -8332B530 C393 -8332B531 C394 -8332B532 C395 -8332B533 C396 -8332B534 C397 -8332B535 C398 -8332B536 C399 -8332B537 C39A -8332B538 C39B -8332B539 C39C -8332B630 C39D -8332B631 C39E -8332B632 C39F -8332B633 C3A0 -8332B634 C3A1 -8332B635 C3A2 -8332B636 C3A3 -8332B637 C3A4 -8332B638 C3A5 -8332B639 C3A6 -8332B730 C3A7 -8332B731 C3A8 -8332B732 C3A9 -8332B733 C3AA -8332B734 C3AB -8332B735 C3AC -8332B736 C3AD -8332B737 C3AE -8332B738 C3AF -8332B739 C3B0 -8332B830 C3B1 -8332B831 C3B2 -8332B832 C3B3 -8332B833 C3B4 -8332B834 C3B5 -8332B835 C3B6 -8332B836 C3B7 -8332B837 C3B8 -8332B838 C3B9 -8332B839 C3BA -8332B930 C3BB -8332B931 C3BC -8332B932 C3BD -8332B933 C3BE -8332B934 C3BF -8332B935 C3C0 -8332B936 C3C1 -8332B937 C3C2 -8332B938 C3C3 -8332B939 C3C4 -8332BA30 C3C5 -8332BA31 C3C6 -8332BA32 C3C7 -8332BA33 C3C8 -8332BA34 C3C9 -8332BA35 C3CA -8332BA36 C3CB -8332BA37 C3CC -8332BA38 C3CD -8332BA39 C3CE -8332BB30 C3CF -8332BB31 C3D0 -8332BB32 C3D1 -8332BB33 C3D2 -8332BB34 C3D3 -8332BB35 C3D4 -8332BB36 C3D5 -8332BB37 C3D6 -8332BB38 C3D7 -8332BB39 C3D8 -8332BC30 C3D9 -8332BC31 C3DA -8332BC32 C3DB -8332BC33 C3DC -8332BC34 C3DD -8332BC35 C3DE -8332BC36 C3DF -8332BC37 C3E0 -8332BC38 C3E1 -8332BC39 C3E2 -8332BD30 C3E3 -8332BD31 C3E4 -8332BD32 C3E5 -8332BD33 C3E6 -8332BD34 C3E7 -8332BD35 C3E8 -8332BD36 C3E9 -8332BD37 C3EA -8332BD38 C3EB -8332BD39 C3EC -8332BE30 C3ED -8332BE31 C3EE -8332BE32 C3EF -8332BE33 C3F0 -8332BE34 C3F1 -8332BE35 C3F2 -8332BE36 C3F3 -8332BE37 C3F4 -8332BE38 C3F5 -8332BE39 C3F6 -8332BF30 C3F7 -8332BF31 C3F8 -8332BF32 C3F9 -8332BF33 C3FA -8332BF34 C3FB -8332BF35 C3FC -8332BF36 C3FD -8332BF37 C3FE -8332BF38 C3FF -8332BF39 C400 -8332C030 C401 -8332C031 C402 -8332C032 C403 -8332C033 C404 -8332C034 C405 -8332C035 C406 -8332C036 C407 -8332C037 C408 -8332C038 C409 -8332C039 C40A -8332C130 C40B -8332C131 C40C -8332C132 C40D -8332C133 C40E -8332C134 C40F -8332C135 C410 -8332C136 C411 -8332C137 C412 -8332C138 C413 -8332C139 C414 -8332C230 C415 -8332C231 C416 -8332C232 C417 -8332C233 C418 -8332C234 C419 -8332C235 C41A -8332C236 C41B -8332C237 C41C -8332C238 C41D -8332C239 C41E -8332C330 C41F -8332C331 C420 -8332C332 C421 -8332C333 C422 -8332C334 C423 -8332C335 C424 -8332C336 C425 -8332C337 C426 -8332C338 C427 -8332C339 C428 -8332C430 C429 -8332C431 C42A -8332C432 C42B -8332C433 C42C -8332C434 C42D -8332C435 C42E -8332C436 C42F -8332C437 C430 -8332C438 C431 -8332C439 C432 -8332C530 C433 -8332C531 C434 -8332C532 C435 -8332C533 C436 -8332C534 C437 -8332C535 C438 -8332C536 C439 -8332C537 C43A -8332C538 C43B -8332C539 C43C -8332C630 C43D -8332C631 C43E -8332C632 C43F -8332C633 C440 -8332C634 C441 -8332C635 C442 -8332C636 C443 -8332C637 C444 -8332C638 C445 -8332C639 C446 -8332C730 C447 -8332C731 C448 -8332C732 C449 -8332C733 C44A -8332C734 C44B -8332C735 C44C -8332C736 C44D -8332C737 C44E -8332C738 C44F -8332C739 C450 -8332C830 C451 -8332C831 C452 -8332C832 C453 -8332C833 C454 -8332C834 C455 -8332C835 C456 -8332C836 C457 -8332C837 C458 -8332C838 C459 -8332C839 C45A -8332C930 C45B -8332C931 C45C -8332C932 C45D -8332C933 C45E -8332C934 C45F -8332C935 C460 -8332C936 C461 -8332C937 C462 -8332C938 C463 -8332C939 C464 -8332CA30 C465 -8332CA31 C466 -8332CA32 C467 -8332CA33 C468 -8332CA34 C469 -8332CA35 C46A -8332CA36 C46B -8332CA37 C46C -8332CA38 C46D -8332CA39 C46E -8332CB30 C46F -8332CB31 C470 -8332CB32 C471 -8332CB33 C472 -8332CB34 C473 -8332CB35 C474 -8332CB36 C475 -8332CB37 C476 -8332CB38 C477 -8332CB39 C478 -8332CC30 C479 -8332CC31 C47A -8332CC32 C47B -8332CC33 C47C -8332CC34 C47D -8332CC35 C47E -8332CC36 C47F -8332CC37 C480 -8332CC38 C481 -8332CC39 C482 -8332CD30 C483 -8332CD31 C484 -8332CD32 C485 -8332CD33 C486 -8332CD34 C487 -8332CD35 C488 -8332CD36 C489 -8332CD37 C48A -8332CD38 C48B -8332CD39 C48C -8332CE30 C48D -8332CE31 C48E -8332CE32 C48F -8332CE33 C490 -8332CE34 C491 -8332CE35 C492 -8332CE36 C493 -8332CE37 C494 -8332CE38 C495 -8332CE39 C496 -8332CF30 C497 -8332CF31 C498 -8332CF32 C499 -8332CF33 C49A -8332CF34 C49B -8332CF35 C49C -8332CF36 C49D -8332CF37 C49E -8332CF38 C49F -8332CF39 C4A0 -8332D030 C4A1 -8332D031 C4A2 -8332D032 C4A3 -8332D033 C4A4 -8332D034 C4A5 -8332D035 C4A6 -8332D036 C4A7 -8332D037 C4A8 -8332D038 C4A9 -8332D039 C4AA -8332D130 C4AB -8332D131 C4AC -8332D132 C4AD -8332D133 C4AE -8332D134 C4AF -8332D135 C4B0 -8332D136 C4B1 -8332D137 C4B2 -8332D138 C4B3 -8332D139 C4B4 -8332D230 C4B5 -8332D231 C4B6 -8332D232 C4B7 -8332D233 C4B8 -8332D234 C4B9 -8332D235 C4BA -8332D236 C4BB -8332D237 C4BC -8332D238 C4BD -8332D239 C4BE -8332D330 C4BF -8332D331 C4C0 -8332D332 C4C1 -8332D333 C4C2 -8332D334 C4C3 -8332D335 C4C4 -8332D336 C4C5 -8332D337 C4C6 -8332D338 C4C7 -8332D339 C4C8 -8332D430 C4C9 -8332D431 C4CA -8332D432 C4CB -8332D433 C4CC -8332D434 C4CD -8332D435 C4CE -8332D436 C4CF -8332D437 C4D0 -8332D438 C4D1 -8332D439 C4D2 -8332D530 C4D3 -8332D531 C4D4 -8332D532 C4D5 -8332D533 C4D6 -8332D534 C4D7 -8332D535 C4D8 -8332D536 C4D9 -8332D537 C4DA -8332D538 C4DB -8332D539 C4DC -8332D630 C4DD -8332D631 C4DE -8332D632 C4DF -8332D633 C4E0 -8332D634 C4E1 -8332D635 C4E2 -8332D636 C4E3 -8332D637 C4E4 -8332D638 C4E5 -8332D639 C4E6 -8332D730 C4E7 -8332D731 C4E8 -8332D732 C4E9 -8332D733 C4EA -8332D734 C4EB -8332D735 C4EC -8332D736 C4ED -8332D737 C4EE -8332D738 C4EF -8332D739 C4F0 -8332D830 C4F1 -8332D831 C4F2 -8332D832 C4F3 -8332D833 C4F4 -8332D834 C4F5 -8332D835 C4F6 -8332D836 C4F7 -8332D837 C4F8 -8332D838 C4F9 -8332D839 C4FA -8332D930 C4FB -8332D931 C4FC -8332D932 C4FD -8332D933 C4FE -8332D934 C4FF -8332D935 C500 -8332D936 C501 -8332D937 C502 -8332D938 C503 -8332D939 C504 -8332DA30 C505 -8332DA31 C506 -8332DA32 C507 -8332DA33 C508 -8332DA34 C509 -8332DA35 C50A -8332DA36 C50B -8332DA37 C50C -8332DA38 C50D -8332DA39 C50E -8332DB30 C50F -8332DB31 C510 -8332DB32 C511 -8332DB33 C512 -8332DB34 C513 -8332DB35 C514 -8332DB36 C515 -8332DB37 C516 -8332DB38 C517 -8332DB39 C518 -8332DC30 C519 -8332DC31 C51A -8332DC32 C51B -8332DC33 C51C -8332DC34 C51D -8332DC35 C51E -8332DC36 C51F -8332DC37 C520 -8332DC38 C521 -8332DC39 C522 -8332DD30 C523 -8332DD31 C524 -8332DD32 C525 -8332DD33 C526 -8332DD34 C527 -8332DD35 C528 -8332DD36 C529 -8332DD37 C52A -8332DD38 C52B -8332DD39 C52C -8332DE30 C52D -8332DE31 C52E -8332DE32 C52F -8332DE33 C530 -8332DE34 C531 -8332DE35 C532 -8332DE36 C533 -8332DE37 C534 -8332DE38 C535 -8332DE39 C536 -8332DF30 C537 -8332DF31 C538 -8332DF32 C539 -8332DF33 C53A -8332DF34 C53B -8332DF35 C53C -8332DF36 C53D -8332DF37 C53E -8332DF38 C53F -8332DF39 C540 -8332E030 C541 -8332E031 C542 -8332E032 C543 -8332E033 C544 -8332E034 C545 -8332E035 C546 -8332E036 C547 -8332E037 C548 -8332E038 C549 -8332E039 C54A -8332E130 C54B -8332E131 C54C -8332E132 C54D -8332E133 C54E -8332E134 C54F -8332E135 C550 -8332E136 C551 -8332E137 C552 -8332E138 C553 -8332E139 C554 -8332E230 C555 -8332E231 C556 -8332E232 C557 -8332E233 C558 -8332E234 C559 -8332E235 C55A -8332E236 C55B -8332E237 C55C -8332E238 C55D -8332E239 C55E -8332E330 C55F -8332E331 C560 -8332E332 C561 -8332E333 C562 -8332E334 C563 -8332E335 C564 -8332E336 C565 -8332E337 C566 -8332E338 C567 -8332E339 C568 -8332E430 C569 -8332E431 C56A -8332E432 C56B -8332E433 C56C -8332E434 C56D -8332E435 C56E -8332E436 C56F -8332E437 C570 -8332E438 C571 -8332E439 C572 -8332E530 C573 -8332E531 C574 -8332E532 C575 -8332E533 C576 -8332E534 C577 -8332E535 C578 -8332E536 C579 -8332E537 C57A -8332E538 C57B -8332E539 C57C -8332E630 C57D -8332E631 C57E -8332E632 C57F -8332E633 C580 -8332E634 C581 -8332E635 C582 -8332E636 C583 -8332E637 C584 -8332E638 C585 -8332E639 C586 -8332E730 C587 -8332E731 C588 -8332E732 C589 -8332E733 C58A -8332E734 C58B -8332E735 C58C -8332E736 C58D -8332E737 C58E -8332E738 C58F -8332E739 C590 -8332E830 C591 -8332E831 C592 -8332E832 C593 -8332E833 C594 -8332E834 C595 -8332E835 C596 -8332E836 C597 -8332E837 C598 -8332E838 C599 -8332E839 C59A -8332E930 C59B -8332E931 C59C -8332E932 C59D -8332E933 C59E -8332E934 C59F -8332E935 C5A0 -8332E936 C5A1 -8332E937 C5A2 -8332E938 C5A3 -8332E939 C5A4 -8332EA30 C5A5 -8332EA31 C5A6 -8332EA32 C5A7 -8332EA33 C5A8 -8332EA34 C5A9 -8332EA35 C5AA -8332EA36 C5AB -8332EA37 C5AC -8332EA38 C5AD -8332EA39 C5AE -8332EB30 C5AF -8332EB31 C5B0 -8332EB32 C5B1 -8332EB33 C5B2 -8332EB34 C5B3 -8332EB35 C5B4 -8332EB36 C5B5 -8332EB37 C5B6 -8332EB38 C5B7 -8332EB39 C5B8 -8332EC30 C5B9 -8332EC31 C5BA -8332EC32 C5BB -8332EC33 C5BC -8332EC34 C5BD -8332EC35 C5BE -8332EC36 C5BF -8332EC37 C5C0 -8332EC38 C5C1 -8332EC39 C5C2 -8332ED30 C5C3 -8332ED31 C5C4 -8332ED32 C5C5 -8332ED33 C5C6 -8332ED34 C5C7 -8332ED35 C5C8 -8332ED36 C5C9 -8332ED37 C5CA -8332ED38 C5CB -8332ED39 C5CC -8332EE30 C5CD -8332EE31 C5CE -8332EE32 C5CF -8332EE33 C5D0 -8332EE34 C5D1 -8332EE35 C5D2 -8332EE36 C5D3 -8332EE37 C5D4 -8332EE38 C5D5 -8332EE39 C5D6 -8332EF30 C5D7 -8332EF31 C5D8 -8332EF32 C5D9 -8332EF33 C5DA -8332EF34 C5DB -8332EF35 C5DC -8332EF36 C5DD -8332EF37 C5DE -8332EF38 C5DF -8332EF39 C5E0 -8332F030 C5E1 -8332F031 C5E2 -8332F032 C5E3 -8332F033 C5E4 -8332F034 C5E5 -8332F035 C5E6 -8332F036 C5E7 -8332F037 C5E8 -8332F038 C5E9 -8332F039 C5EA -8332F130 C5EB -8332F131 C5EC -8332F132 C5ED -8332F133 C5EE -8332F134 C5EF -8332F135 C5F0 -8332F136 C5F1 -8332F137 C5F2 -8332F138 C5F3 -8332F139 C5F4 -8332F230 C5F5 -8332F231 C5F6 -8332F232 C5F7 -8332F233 C5F8 -8332F234 C5F9 -8332F235 C5FA -8332F236 C5FB -8332F237 C5FC -8332F238 C5FD -8332F239 C5FE -8332F330 C5FF -8332F331 C600 -8332F332 C601 -8332F333 C602 -8332F334 C603 -8332F335 C604 -8332F336 C605 -8332F337 C606 -8332F338 C607 -8332F339 C608 -8332F430 C609 -8332F431 C60A -8332F432 C60B -8332F433 C60C -8332F434 C60D -8332F435 C60E -8332F436 C60F -8332F437 C610 -8332F438 C611 -8332F439 C612 -8332F530 C613 -8332F531 C614 -8332F532 C615 -8332F533 C616 -8332F534 C617 -8332F535 C618 -8332F536 C619 -8332F537 C61A -8332F538 C61B -8332F539 C61C -8332F630 C61D -8332F631 C61E -8332F632 C61F -8332F633 C620 -8332F634 C621 -8332F635 C622 -8332F636 C623 -8332F637 C624 -8332F638 C625 -8332F639 C626 -8332F730 C627 -8332F731 C628 -8332F732 C629 -8332F733 C62A -8332F734 C62B -8332F735 C62C -8332F736 C62D -8332F737 C62E -8332F738 C62F -8332F739 C630 -8332F830 C631 -8332F831 C632 -8332F832 C633 -8332F833 C634 -8332F834 C635 -8332F835 C636 -8332F836 C637 -8332F837 C638 -8332F838 C639 -8332F839 C63A -8332F930 C63B -8332F931 C63C -8332F932 C63D -8332F933 C63E -8332F934 C63F -8332F935 C640 -8332F936 C641 -8332F937 C642 -8332F938 C643 -8332F939 C644 -8332FA30 C645 -8332FA31 C646 -8332FA32 C647 -8332FA33 C648 -8332FA34 C649 -8332FA35 C64A -8332FA36 C64B -8332FA37 C64C -8332FA38 C64D -8332FA39 C64E -8332FB30 C64F -8332FB31 C650 -8332FB32 C651 -8332FB33 C652 -8332FB34 C653 -8332FB35 C654 -8332FB36 C655 -8332FB37 C656 -8332FB38 C657 -8332FB39 C658 -8332FC30 C659 -8332FC31 C65A -8332FC32 C65B -8332FC33 C65C -8332FC34 C65D -8332FC35 C65E -8332FC36 C65F -8332FC37 C660 -8332FC38 C661 -8332FC39 C662 -8332FD30 C663 -8332FD31 C664 -8332FD32 C665 -8332FD33 C666 -8332FD34 C667 -8332FD35 C668 -8332FD36 C669 -8332FD37 C66A -8332FD38 C66B -8332FD39 C66C -8332FE30 C66D -8332FE31 C66E -8332FE32 C66F -8332FE33 C670 -8332FE34 C671 -8332FE35 C672 -8332FE36 C673 -8332FE37 C674 -8332FE38 C675 -8332FE39 C676 -83338130 C677 -83338131 C678 -83338132 C679 -83338133 C67A -83338134 C67B -83338135 C67C -83338136 C67D -83338137 C67E -83338138 C67F -83338139 C680 -83338230 C681 -83338231 C682 -83338232 C683 -83338233 C684 -83338234 C685 -83338235 C686 -83338236 C687 -83338237 C688 -83338238 C689 -83338239 C68A -83338330 C68B -83338331 C68C -83338332 C68D -83338333 C68E -83338334 C68F -83338335 C690 -83338336 C691 -83338337 C692 -83338338 C693 -83338339 C694 -83338430 C695 -83338431 C696 -83338432 C697 -83338433 C698 -83338434 C699 -83338435 C69A -83338436 C69B -83338437 C69C -83338438 C69D -83338439 C69E -83338530 C69F -83338531 C6A0 -83338532 C6A1 -83338533 C6A2 -83338534 C6A3 -83338535 C6A4 -83338536 C6A5 -83338537 C6A6 -83338538 C6A7 -83338539 C6A8 -83338630 C6A9 -83338631 C6AA -83338632 C6AB -83338633 C6AC -83338634 C6AD -83338635 C6AE -83338636 C6AF -83338637 C6B0 -83338638 C6B1 -83338639 C6B2 -83338730 C6B3 -83338731 C6B4 -83338732 C6B5 -83338733 C6B6 -83338734 C6B7 -83338735 C6B8 -83338736 C6B9 -83338737 C6BA -83338738 C6BB -83338739 C6BC -83338830 C6BD -83338831 C6BE -83338832 C6BF -83338833 C6C0 -83338834 C6C1 -83338835 C6C2 -83338836 C6C3 -83338837 C6C4 -83338838 C6C5 -83338839 C6C6 -83338930 C6C7 -83338931 C6C8 -83338932 C6C9 -83338933 C6CA -83338934 C6CB -83338935 C6CC -83338936 C6CD -83338937 C6CE -83338938 C6CF -83338939 C6D0 -83338A30 C6D1 -83338A31 C6D2 -83338A32 C6D3 -83338A33 C6D4 -83338A34 C6D5 -83338A35 C6D6 -83338A36 C6D7 -83338A37 C6D8 -83338A38 C6D9 -83338A39 C6DA -83338B30 C6DB -83338B31 C6DC -83338B32 C6DD -83338B33 C6DE -83338B34 C6DF -83338B35 C6E0 -83338B36 C6E1 -83338B37 C6E2 -83338B38 C6E3 -83338B39 C6E4 -83338C30 C6E5 -83338C31 C6E6 -83338C32 C6E7 -83338C33 C6E8 -83338C34 C6E9 -83338C35 C6EA -83338C36 C6EB -83338C37 C6EC -83338C38 C6ED -83338C39 C6EE -83338D30 C6EF -83338D31 C6F0 -83338D32 C6F1 -83338D33 C6F2 -83338D34 C6F3 -83338D35 C6F4 -83338D36 C6F5 -83338D37 C6F6 -83338D38 C6F7 -83338D39 C6F8 -83338E30 C6F9 -83338E31 C6FA -83338E32 C6FB -83338E33 C6FC -83338E34 C6FD -83338E35 C6FE -83338E36 C6FF -83338E37 C700 -83338E38 C701 -83338E39 C702 -83338F30 C703 -83338F31 C704 -83338F32 C705 -83338F33 C706 -83338F34 C707 -83338F35 C708 -83338F36 C709 -83338F37 C70A -83338F38 C70B -83338F39 C70C -83339030 C70D -83339031 C70E -83339032 C70F -83339033 C710 -83339034 C711 -83339035 C712 -83339036 C713 -83339037 C714 -83339038 C715 -83339039 C716 -83339130 C717 -83339131 C718 -83339132 C719 -83339133 C71A -83339134 C71B -83339135 C71C -83339136 C71D -83339137 C71E -83339138 C71F -83339139 C720 -83339230 C721 -83339231 C722 -83339232 C723 -83339233 C724 -83339234 C725 -83339235 C726 -83339236 C727 -83339237 C728 -83339238 C729 -83339239 C72A -83339330 C72B -83339331 C72C -83339332 C72D -83339333 C72E -83339334 C72F -83339335 C730 -83339336 C731 -83339337 C732 -83339338 C733 -83339339 C734 -83339430 C735 -83339431 C736 -83339432 C737 -83339433 C738 -83339434 C739 -83339435 C73A -83339436 C73B -83339437 C73C -83339438 C73D -83339439 C73E -83339530 C73F -83339531 C740 -83339532 C741 -83339533 C742 -83339534 C743 -83339535 C744 -83339536 C745 -83339537 C746 -83339538 C747 -83339539 C748 -83339630 C749 -83339631 C74A -83339632 C74B -83339633 C74C -83339634 C74D -83339635 C74E -83339636 C74F -83339637 C750 -83339638 C751 -83339639 C752 -83339730 C753 -83339731 C754 -83339732 C755 -83339733 C756 -83339734 C757 -83339735 C758 -83339736 C759 -83339737 C75A -83339738 C75B -83339739 C75C -83339830 C75D -83339831 C75E -83339832 C75F -83339833 C760 -83339834 C761 -83339835 C762 -83339836 C763 -83339837 C764 -83339838 C765 -83339839 C766 -83339930 C767 -83339931 C768 -83339932 C769 -83339933 C76A -83339934 C76B -83339935 C76C -83339936 C76D -83339937 C76E -83339938 C76F -83339939 C770 -83339A30 C771 -83339A31 C772 -83339A32 C773 -83339A33 C774 -83339A34 C775 -83339A35 C776 -83339A36 C777 -83339A37 C778 -83339A38 C779 -83339A39 C77A -83339B30 C77B -83339B31 C77C -83339B32 C77D -83339B33 C77E -83339B34 C77F -83339B35 C780 -83339B36 C781 -83339B37 C782 -83339B38 C783 -83339B39 C784 -83339C30 C785 -83339C31 C786 -83339C32 C787 -83339C33 C788 -83339C34 C789 -83339C35 C78A -83339C36 C78B -83339C37 C78C -83339C38 C78D -83339C39 C78E -83339D30 C78F -83339D31 C790 -83339D32 C791 -83339D33 C792 -83339D34 C793 -83339D35 C794 -83339D36 C795 -83339D37 C796 -83339D38 C797 -83339D39 C798 -83339E30 C799 -83339E31 C79A -83339E32 C79B -83339E33 C79C -83339E34 C79D -83339E35 C79E -83339E36 C79F -83339E37 C7A0 -83339E38 C7A1 -83339E39 C7A2 -83339F30 C7A3 -83339F31 C7A4 -83339F32 C7A5 -83339F33 C7A6 -83339F34 C7A7 -83339F35 C7A8 -83339F36 C7A9 -83339F37 C7AA -83339F38 C7AB -83339F39 C7AC -8333A030 C7AD -8333A031 C7AE -8333A032 C7AF -8333A033 C7B0 -8333A034 C7B1 -8333A035 C7B2 -8333A036 C7B3 -8333A037 C7B4 -8333A038 C7B5 -8333A039 C7B6 -8333A130 C7B7 -8333A131 C7B8 -8333A132 C7B9 -8333A133 C7BA -8333A134 C7BB -8333A135 C7BC -8333A136 C7BD -8333A137 C7BE -8333A138 C7BF -8333A139 C7C0 -8333A230 C7C1 -8333A231 C7C2 -8333A232 C7C3 -8333A233 C7C4 -8333A234 C7C5 -8333A235 C7C6 -8333A236 C7C7 -8333A237 C7C8 -8333A238 C7C9 -8333A239 C7CA -8333A330 C7CB -8333A331 C7CC -8333A332 C7CD -8333A333 C7CE -8333A334 C7CF -8333A335 C7D0 -8333A336 C7D1 -8333A337 C7D2 -8333A338 C7D3 -8333A339 C7D4 -8333A430 C7D5 -8333A431 C7D6 -8333A432 C7D7 -8333A433 C7D8 -8333A434 C7D9 -8333A435 C7DA -8333A436 C7DB -8333A437 C7DC -8333A438 C7DD -8333A439 C7DE -8333A530 C7DF -8333A531 C7E0 -8333A532 C7E1 -8333A533 C7E2 -8333A534 C7E3 -8333A535 C7E4 -8333A536 C7E5 -8333A537 C7E6 -8333A538 C7E7 -8333A539 C7E8 -8333A630 C7E9 -8333A631 C7EA -8333A632 C7EB -8333A633 C7EC -8333A634 C7ED -8333A635 C7EE -8333A636 C7EF -8333A637 C7F0 -8333A638 C7F1 -8333A639 C7F2 -8333A730 C7F3 -8333A731 C7F4 -8333A732 C7F5 -8333A733 C7F6 -8333A734 C7F7 -8333A735 C7F8 -8333A736 C7F9 -8333A737 C7FA -8333A738 C7FB -8333A739 C7FC -8333A830 C7FD -8333A831 C7FE -8333A832 C7FF -8333A833 C800 -8333A834 C801 -8333A835 C802 -8333A836 C803 -8333A837 C804 -8333A838 C805 -8333A839 C806 -8333A930 C807 -8333A931 C808 -8333A932 C809 -8333A933 C80A -8333A934 C80B -8333A935 C80C -8333A936 C80D -8333A937 C80E -8333A938 C80F -8333A939 C810 -8333AA30 C811 -8333AA31 C812 -8333AA32 C813 -8333AA33 C814 -8333AA34 C815 -8333AA35 C816 -8333AA36 C817 -8333AA37 C818 -8333AA38 C819 -8333AA39 C81A -8333AB30 C81B -8333AB31 C81C -8333AB32 C81D -8333AB33 C81E -8333AB34 C81F -8333AB35 C820 -8333AB36 C821 -8333AB37 C822 -8333AB38 C823 -8333AB39 C824 -8333AC30 C825 -8333AC31 C826 -8333AC32 C827 -8333AC33 C828 -8333AC34 C829 -8333AC35 C82A -8333AC36 C82B -8333AC37 C82C -8333AC38 C82D -8333AC39 C82E -8333AD30 C82F -8333AD31 C830 -8333AD32 C831 -8333AD33 C832 -8333AD34 C833 -8333AD35 C834 -8333AD36 C835 -8333AD37 C836 -8333AD38 C837 -8333AD39 C838 -8333AE30 C839 -8333AE31 C83A -8333AE32 C83B -8333AE33 C83C -8333AE34 C83D -8333AE35 C83E -8333AE36 C83F -8333AE37 C840 -8333AE38 C841 -8333AE39 C842 -8333AF30 C843 -8333AF31 C844 -8333AF32 C845 -8333AF33 C846 -8333AF34 C847 -8333AF35 C848 -8333AF36 C849 -8333AF37 C84A -8333AF38 C84B -8333AF39 C84C -8333B030 C84D -8333B031 C84E -8333B032 C84F -8333B033 C850 -8333B034 C851 -8333B035 C852 -8333B036 C853 -8333B037 C854 -8333B038 C855 -8333B039 C856 -8333B130 C857 -8333B131 C858 -8333B132 C859 -8333B133 C85A -8333B134 C85B -8333B135 C85C -8333B136 C85D -8333B137 C85E -8333B138 C85F -8333B139 C860 -8333B230 C861 -8333B231 C862 -8333B232 C863 -8333B233 C864 -8333B234 C865 -8333B235 C866 -8333B236 C867 -8333B237 C868 -8333B238 C869 -8333B239 C86A -8333B330 C86B -8333B331 C86C -8333B332 C86D -8333B333 C86E -8333B334 C86F -8333B335 C870 -8333B336 C871 -8333B337 C872 -8333B338 C873 -8333B339 C874 -8333B430 C875 -8333B431 C876 -8333B432 C877 -8333B433 C878 -8333B434 C879 -8333B435 C87A -8333B436 C87B -8333B437 C87C -8333B438 C87D -8333B439 C87E -8333B530 C87F -8333B531 C880 -8333B532 C881 -8333B533 C882 -8333B534 C883 -8333B535 C884 -8333B536 C885 -8333B537 C886 -8333B538 C887 -8333B539 C888 -8333B630 C889 -8333B631 C88A -8333B632 C88B -8333B633 C88C -8333B634 C88D -8333B635 C88E -8333B636 C88F -8333B637 C890 -8333B638 C891 -8333B639 C892 -8333B730 C893 -8333B731 C894 -8333B732 C895 -8333B733 C896 -8333B734 C897 -8333B735 C898 -8333B736 C899 -8333B737 C89A -8333B738 C89B -8333B739 C89C -8333B830 C89D -8333B831 C89E -8333B832 C89F -8333B833 C8A0 -8333B834 C8A1 -8333B835 C8A2 -8333B836 C8A3 -8333B837 C8A4 -8333B838 C8A5 -8333B839 C8A6 -8333B930 C8A7 -8333B931 C8A8 -8333B932 C8A9 -8333B933 C8AA -8333B934 C8AB -8333B935 C8AC -8333B936 C8AD -8333B937 C8AE -8333B938 C8AF -8333B939 C8B0 -8333BA30 C8B1 -8333BA31 C8B2 -8333BA32 C8B3 -8333BA33 C8B4 -8333BA34 C8B5 -8333BA35 C8B6 -8333BA36 C8B7 -8333BA37 C8B8 -8333BA38 C8B9 -8333BA39 C8BA -8333BB30 C8BB -8333BB31 C8BC -8333BB32 C8BD -8333BB33 C8BE -8333BB34 C8BF -8333BB35 C8C0 -8333BB36 C8C1 -8333BB37 C8C2 -8333BB38 C8C3 -8333BB39 C8C4 -8333BC30 C8C5 -8333BC31 C8C6 -8333BC32 C8C7 -8333BC33 C8C8 -8333BC34 C8C9 -8333BC35 C8CA -8333BC36 C8CB -8333BC37 C8CC -8333BC38 C8CD -8333BC39 C8CE -8333BD30 C8CF -8333BD31 C8D0 -8333BD32 C8D1 -8333BD33 C8D2 -8333BD34 C8D3 -8333BD35 C8D4 -8333BD36 C8D5 -8333BD37 C8D6 -8333BD38 C8D7 -8333BD39 C8D8 -8333BE30 C8D9 -8333BE31 C8DA -8333BE32 C8DB -8333BE33 C8DC -8333BE34 C8DD -8333BE35 C8DE -8333BE36 C8DF -8333BE37 C8E0 -8333BE38 C8E1 -8333BE39 C8E2 -8333BF30 C8E3 -8333BF31 C8E4 -8333BF32 C8E5 -8333BF33 C8E6 -8333BF34 C8E7 -8333BF35 C8E8 -8333BF36 C8E9 -8333BF37 C8EA -8333BF38 C8EB -8333BF39 C8EC -8333C030 C8ED -8333C031 C8EE -8333C032 C8EF -8333C033 C8F0 -8333C034 C8F1 -8333C035 C8F2 -8333C036 C8F3 -8333C037 C8F4 -8333C038 C8F5 -8333C039 C8F6 -8333C130 C8F7 -8333C131 C8F8 -8333C132 C8F9 -8333C133 C8FA -8333C134 C8FB -8333C135 C8FC -8333C136 C8FD -8333C137 C8FE -8333C138 C8FF -8333C139 C900 -8333C230 C901 -8333C231 C902 -8333C232 C903 -8333C233 C904 -8333C234 C905 -8333C235 C906 -8333C236 C907 -8333C237 C908 -8333C238 C909 -8333C239 C90A -8333C330 C90B -8333C331 C90C -8333C332 C90D -8333C333 C90E -8333C334 C90F -8333C335 C910 -8333C336 C911 -8333C337 C912 -8333C338 C913 -8333C339 C914 -8333C430 C915 -8333C431 C916 -8333C432 C917 -8333C433 C918 -8333C434 C919 -8333C435 C91A -8333C436 C91B -8333C437 C91C -8333C438 C91D -8333C439 C91E -8333C530 C91F -8333C531 C920 -8333C532 C921 -8333C533 C922 -8333C534 C923 -8333C535 C924 -8333C536 C925 -8333C537 C926 -8333C538 C927 -8333C539 C928 -8333C630 C929 -8333C631 C92A -8333C632 C92B -8333C633 C92C -8333C634 C92D -8333C635 C92E -8333C636 C92F -8333C637 C930 -8333C638 C931 -8333C639 C932 -8333C730 C933 -8333C731 C934 -8333C732 C935 -8333C733 C936 -8333C734 C937 -8333C735 C938 -8333C736 C939 -8333C737 C93A -8333C738 C93B -8333C739 C93C -8333C830 C93D -8333C831 C93E -8333C832 C93F -8333C833 C940 -8333C834 C941 -8333C835 C942 -8333C836 C943 -8333C837 C944 -8333C838 C945 -8333C839 C946 -8333C930 C947 -8333C931 C948 -8333C932 C949 -8333C933 C94A -8333C934 C94B -8333C935 C94C -8333C936 C94D -8333C937 C94E -8333C938 C94F -8333C939 C950 -8333CA30 C951 -8333CA31 C952 -8333CA32 C953 -8333CA33 C954 -8333CA34 C955 -8333CA35 C956 -8333CA36 C957 -8333CA37 C958 -8333CA38 C959 -8333CA39 C95A -8333CB30 C95B -8333CB31 C95C -8333CB32 C95D -8333CB33 C95E -8333CB34 C95F -8333CB35 C960 -8333CB36 C961 -8333CB37 C962 -8333CB38 C963 -8333CB39 C964 -8333CC30 C965 -8333CC31 C966 -8333CC32 C967 -8333CC33 C968 -8333CC34 C969 -8333CC35 C96A -8333CC36 C96B -8333CC37 C96C -8333CC38 C96D -8333CC39 C96E -8333CD30 C96F -8333CD31 C970 -8333CD32 C971 -8333CD33 C972 -8333CD34 C973 -8333CD35 C974 -8333CD36 C975 -8333CD37 C976 -8333CD38 C977 -8333CD39 C978 -8333CE30 C979 -8333CE31 C97A -8333CE32 C97B -8333CE33 C97C -8333CE34 C97D -8333CE35 C97E -8333CE36 C97F -8333CE37 C980 -8333CE38 C981 -8333CE39 C982 -8333CF30 C983 -8333CF31 C984 -8333CF32 C985 -8333CF33 C986 -8333CF34 C987 -8333CF35 C988 -8333CF36 C989 -8333CF37 C98A -8333CF38 C98B -8333CF39 C98C -8333D030 C98D -8333D031 C98E -8333D032 C98F -8333D033 C990 -8333D034 C991 -8333D035 C992 -8333D036 C993 -8333D037 C994 -8333D038 C995 -8333D039 C996 -8333D130 C997 -8333D131 C998 -8333D132 C999 -8333D133 C99A -8333D134 C99B -8333D135 C99C -8333D136 C99D -8333D137 C99E -8333D138 C99F -8333D139 C9A0 -8333D230 C9A1 -8333D231 C9A2 -8333D232 C9A3 -8333D233 C9A4 -8333D234 C9A5 -8333D235 C9A6 -8333D236 C9A7 -8333D237 C9A8 -8333D238 C9A9 -8333D239 C9AA -8333D330 C9AB -8333D331 C9AC -8333D332 C9AD -8333D333 C9AE -8333D334 C9AF -8333D335 C9B0 -8333D336 C9B1 -8333D337 C9B2 -8333D338 C9B3 -8333D339 C9B4 -8333D430 C9B5 -8333D431 C9B6 -8333D432 C9B7 -8333D433 C9B8 -8333D434 C9B9 -8333D435 C9BA -8333D436 C9BB -8333D437 C9BC -8333D438 C9BD -8333D439 C9BE -8333D530 C9BF -8333D531 C9C0 -8333D532 C9C1 -8333D533 C9C2 -8333D534 C9C3 -8333D535 C9C4 -8333D536 C9C5 -8333D537 C9C6 -8333D538 C9C7 -8333D539 C9C8 -8333D630 C9C9 -8333D631 C9CA -8333D632 C9CB -8333D633 C9CC -8333D634 C9CD -8333D635 C9CE -8333D636 C9CF -8333D637 C9D0 -8333D638 C9D1 -8333D639 C9D2 -8333D730 C9D3 -8333D731 C9D4 -8333D732 C9D5 -8333D733 C9D6 -8333D734 C9D7 -8333D735 C9D8 -8333D736 C9D9 -8333D737 C9DA -8333D738 C9DB -8333D739 C9DC -8333D830 C9DD -8333D831 C9DE -8333D832 C9DF -8333D833 C9E0 -8333D834 C9E1 -8333D835 C9E2 -8333D836 C9E3 -8333D837 C9E4 -8333D838 C9E5 -8333D839 C9E6 -8333D930 C9E7 -8333D931 C9E8 -8333D932 C9E9 -8333D933 C9EA -8333D934 C9EB -8333D935 C9EC -8333D936 C9ED -8333D937 C9EE -8333D938 C9EF -8333D939 C9F0 -8333DA30 C9F1 -8333DA31 C9F2 -8333DA32 C9F3 -8333DA33 C9F4 -8333DA34 C9F5 -8333DA35 C9F6 -8333DA36 C9F7 -8333DA37 C9F8 -8333DA38 C9F9 -8333DA39 C9FA -8333DB30 C9FB -8333DB31 C9FC -8333DB32 C9FD -8333DB33 C9FE -8333DB34 C9FF -8333DB35 CA00 -8333DB36 CA01 -8333DB37 CA02 -8333DB38 CA03 -8333DB39 CA04 -8333DC30 CA05 -8333DC31 CA06 -8333DC32 CA07 -8333DC33 CA08 -8333DC34 CA09 -8333DC35 CA0A -8333DC36 CA0B -8333DC37 CA0C -8333DC38 CA0D -8333DC39 CA0E -8333DD30 CA0F -8333DD31 CA10 -8333DD32 CA11 -8333DD33 CA12 -8333DD34 CA13 -8333DD35 CA14 -8333DD36 CA15 -8333DD37 CA16 -8333DD38 CA17 -8333DD39 CA18 -8333DE30 CA19 -8333DE31 CA1A -8333DE32 CA1B -8333DE33 CA1C -8333DE34 CA1D -8333DE35 CA1E -8333DE36 CA1F -8333DE37 CA20 -8333DE38 CA21 -8333DE39 CA22 -8333DF30 CA23 -8333DF31 CA24 -8333DF32 CA25 -8333DF33 CA26 -8333DF34 CA27 -8333DF35 CA28 -8333DF36 CA29 -8333DF37 CA2A -8333DF38 CA2B -8333DF39 CA2C -8333E030 CA2D -8333E031 CA2E -8333E032 CA2F -8333E033 CA30 -8333E034 CA31 -8333E035 CA32 -8333E036 CA33 -8333E037 CA34 -8333E038 CA35 -8333E039 CA36 -8333E130 CA37 -8333E131 CA38 -8333E132 CA39 -8333E133 CA3A -8333E134 CA3B -8333E135 CA3C -8333E136 CA3D -8333E137 CA3E -8333E138 CA3F -8333E139 CA40 -8333E230 CA41 -8333E231 CA42 -8333E232 CA43 -8333E233 CA44 -8333E234 CA45 -8333E235 CA46 -8333E236 CA47 -8333E237 CA48 -8333E238 CA49 -8333E239 CA4A -8333E330 CA4B -8333E331 CA4C -8333E332 CA4D -8333E333 CA4E -8333E334 CA4F -8333E335 CA50 -8333E336 CA51 -8333E337 CA52 -8333E338 CA53 -8333E339 CA54 -8333E430 CA55 -8333E431 CA56 -8333E432 CA57 -8333E433 CA58 -8333E434 CA59 -8333E435 CA5A -8333E436 CA5B -8333E437 CA5C -8333E438 CA5D -8333E439 CA5E -8333E530 CA5F -8333E531 CA60 -8333E532 CA61 -8333E533 CA62 -8333E534 CA63 -8333E535 CA64 -8333E536 CA65 -8333E537 CA66 -8333E538 CA67 -8333E539 CA68 -8333E630 CA69 -8333E631 CA6A -8333E632 CA6B -8333E633 CA6C -8333E634 CA6D -8333E635 CA6E -8333E636 CA6F -8333E637 CA70 -8333E638 CA71 -8333E639 CA72 -8333E730 CA73 -8333E731 CA74 -8333E732 CA75 -8333E733 CA76 -8333E734 CA77 -8333E735 CA78 -8333E736 CA79 -8333E737 CA7A -8333E738 CA7B -8333E739 CA7C -8333E830 CA7D -8333E831 CA7E -8333E832 CA7F -8333E833 CA80 -8333E834 CA81 -8333E835 CA82 -8333E836 CA83 -8333E837 CA84 -8333E838 CA85 -8333E839 CA86 -8333E930 CA87 -8333E931 CA88 -8333E932 CA89 -8333E933 CA8A -8333E934 CA8B -8333E935 CA8C -8333E936 CA8D -8333E937 CA8E -8333E938 CA8F -8333E939 CA90 -8333EA30 CA91 -8333EA31 CA92 -8333EA32 CA93 -8333EA33 CA94 -8333EA34 CA95 -8333EA35 CA96 -8333EA36 CA97 -8333EA37 CA98 -8333EA38 CA99 -8333EA39 CA9A -8333EB30 CA9B -8333EB31 CA9C -8333EB32 CA9D -8333EB33 CA9E -8333EB34 CA9F -8333EB35 CAA0 -8333EB36 CAA1 -8333EB37 CAA2 -8333EB38 CAA3 -8333EB39 CAA4 -8333EC30 CAA5 -8333EC31 CAA6 -8333EC32 CAA7 -8333EC33 CAA8 -8333EC34 CAA9 -8333EC35 CAAA -8333EC36 CAAB -8333EC37 CAAC -8333EC38 CAAD -8333EC39 CAAE -8333ED30 CAAF -8333ED31 CAB0 -8333ED32 CAB1 -8333ED33 CAB2 -8333ED34 CAB3 -8333ED35 CAB4 -8333ED36 CAB5 -8333ED37 CAB6 -8333ED38 CAB7 -8333ED39 CAB8 -8333EE30 CAB9 -8333EE31 CABA -8333EE32 CABB -8333EE33 CABC -8333EE34 CABD -8333EE35 CABE -8333EE36 CABF -8333EE37 CAC0 -8333EE38 CAC1 -8333EE39 CAC2 -8333EF30 CAC3 -8333EF31 CAC4 -8333EF32 CAC5 -8333EF33 CAC6 -8333EF34 CAC7 -8333EF35 CAC8 -8333EF36 CAC9 -8333EF37 CACA -8333EF38 CACB -8333EF39 CACC -8333F030 CACD -8333F031 CACE -8333F032 CACF -8333F033 CAD0 -8333F034 CAD1 -8333F035 CAD2 -8333F036 CAD3 -8333F037 CAD4 -8333F038 CAD5 -8333F039 CAD6 -8333F130 CAD7 -8333F131 CAD8 -8333F132 CAD9 -8333F133 CADA -8333F134 CADB -8333F135 CADC -8333F136 CADD -8333F137 CADE -8333F138 CADF -8333F139 CAE0 -8333F230 CAE1 -8333F231 CAE2 -8333F232 CAE3 -8333F233 CAE4 -8333F234 CAE5 -8333F235 CAE6 -8333F236 CAE7 -8333F237 CAE8 -8333F238 CAE9 -8333F239 CAEA -8333F330 CAEB -8333F331 CAEC -8333F332 CAED -8333F333 CAEE -8333F334 CAEF -8333F335 CAF0 -8333F336 CAF1 -8333F337 CAF2 -8333F338 CAF3 -8333F339 CAF4 -8333F430 CAF5 -8333F431 CAF6 -8333F432 CAF7 -8333F433 CAF8 -8333F434 CAF9 -8333F435 CAFA -8333F436 CAFB -8333F437 CAFC -8333F438 CAFD -8333F439 CAFE -8333F530 CAFF -8333F531 CB00 -8333F532 CB01 -8333F533 CB02 -8333F534 CB03 -8333F535 CB04 -8333F536 CB05 -8333F537 CB06 -8333F538 CB07 -8333F539 CB08 -8333F630 CB09 -8333F631 CB0A -8333F632 CB0B -8333F633 CB0C -8333F634 CB0D -8333F635 CB0E -8333F636 CB0F -8333F637 CB10 -8333F638 CB11 -8333F639 CB12 -8333F730 CB13 -8333F731 CB14 -8333F732 CB15 -8333F733 CB16 -8333F734 CB17 -8333F735 CB18 -8333F736 CB19 -8333F737 CB1A -8333F738 CB1B -8333F739 CB1C -8333F830 CB1D -8333F831 CB1E -8333F832 CB1F -8333F833 CB20 -8333F834 CB21 -8333F835 CB22 -8333F836 CB23 -8333F837 CB24 -8333F838 CB25 -8333F839 CB26 -8333F930 CB27 -8333F931 CB28 -8333F932 CB29 -8333F933 CB2A -8333F934 CB2B -8333F935 CB2C -8333F936 CB2D -8333F937 CB2E -8333F938 CB2F -8333F939 CB30 -8333FA30 CB31 -8333FA31 CB32 -8333FA32 CB33 -8333FA33 CB34 -8333FA34 CB35 -8333FA35 CB36 -8333FA36 CB37 -8333FA37 CB38 -8333FA38 CB39 -8333FA39 CB3A -8333FB30 CB3B -8333FB31 CB3C -8333FB32 CB3D -8333FB33 CB3E -8333FB34 CB3F -8333FB35 CB40 -8333FB36 CB41 -8333FB37 CB42 -8333FB38 CB43 -8333FB39 CB44 -8333FC30 CB45 -8333FC31 CB46 -8333FC32 CB47 -8333FC33 CB48 -8333FC34 CB49 -8333FC35 CB4A -8333FC36 CB4B -8333FC37 CB4C -8333FC38 CB4D -8333FC39 CB4E -8333FD30 CB4F -8333FD31 CB50 -8333FD32 CB51 -8333FD33 CB52 -8333FD34 CB53 -8333FD35 CB54 -8333FD36 CB55 -8333FD37 CB56 -8333FD38 CB57 -8333FD39 CB58 -8333FE30 CB59 -8333FE31 CB5A -8333FE32 CB5B -8333FE33 CB5C -8333FE34 CB5D -8333FE35 CB5E -8333FE36 CB5F -8333FE37 CB60 -8333FE38 CB61 -8333FE39 CB62 -83348130 CB63 -83348131 CB64 -83348132 CB65 -83348133 CB66 -83348134 CB67 -83348135 CB68 -83348136 CB69 -83348137 CB6A -83348138 CB6B -83348139 CB6C -83348230 CB6D -83348231 CB6E -83348232 CB6F -83348233 CB70 -83348234 CB71 -83348235 CB72 -83348236 CB73 -83348237 CB74 -83348238 CB75 -83348239 CB76 -83348330 CB77 -83348331 CB78 -83348332 CB79 -83348333 CB7A -83348334 CB7B -83348335 CB7C -83348336 CB7D -83348337 CB7E -83348338 CB7F -83348339 CB80 -83348430 CB81 -83348431 CB82 -83348432 CB83 -83348433 CB84 -83348434 CB85 -83348435 CB86 -83348436 CB87 -83348437 CB88 -83348438 CB89 -83348439 CB8A -83348530 CB8B -83348531 CB8C -83348532 CB8D -83348533 CB8E -83348534 CB8F -83348535 CB90 -83348536 CB91 -83348537 CB92 -83348538 CB93 -83348539 CB94 -83348630 CB95 -83348631 CB96 -83348632 CB97 -83348633 CB98 -83348634 CB99 -83348635 CB9A -83348636 CB9B -83348637 CB9C -83348638 CB9D -83348639 CB9E -83348730 CB9F -83348731 CBA0 -83348732 CBA1 -83348733 CBA2 -83348734 CBA3 -83348735 CBA4 -83348736 CBA5 -83348737 CBA6 -83348738 CBA7 -83348739 CBA8 -83348830 CBA9 -83348831 CBAA -83348832 CBAB -83348833 CBAC -83348834 CBAD -83348835 CBAE -83348836 CBAF -83348837 CBB0 -83348838 CBB1 -83348839 CBB2 -83348930 CBB3 -83348931 CBB4 -83348932 CBB5 -83348933 CBB6 -83348934 CBB7 -83348935 CBB8 -83348936 CBB9 -83348937 CBBA -83348938 CBBB -83348939 CBBC -83348A30 CBBD -83348A31 CBBE -83348A32 CBBF -83348A33 CBC0 -83348A34 CBC1 -83348A35 CBC2 -83348A36 CBC3 -83348A37 CBC4 -83348A38 CBC5 -83348A39 CBC6 -83348B30 CBC7 -83348B31 CBC8 -83348B32 CBC9 -83348B33 CBCA -83348B34 CBCB -83348B35 CBCC -83348B36 CBCD -83348B37 CBCE -83348B38 CBCF -83348B39 CBD0 -83348C30 CBD1 -83348C31 CBD2 -83348C32 CBD3 -83348C33 CBD4 -83348C34 CBD5 -83348C35 CBD6 -83348C36 CBD7 -83348C37 CBD8 -83348C38 CBD9 -83348C39 CBDA -83348D30 CBDB -83348D31 CBDC -83348D32 CBDD -83348D33 CBDE -83348D34 CBDF -83348D35 CBE0 -83348D36 CBE1 -83348D37 CBE2 -83348D38 CBE3 -83348D39 CBE4 -83348E30 CBE5 -83348E31 CBE6 -83348E32 CBE7 -83348E33 CBE8 -83348E34 CBE9 -83348E35 CBEA -83348E36 CBEB -83348E37 CBEC -83348E38 CBED -83348E39 CBEE -83348F30 CBEF -83348F31 CBF0 -83348F32 CBF1 -83348F33 CBF2 -83348F34 CBF3 -83348F35 CBF4 -83348F36 CBF5 -83348F37 CBF6 -83348F38 CBF7 -83348F39 CBF8 -83349030 CBF9 -83349031 CBFA -83349032 CBFB -83349033 CBFC -83349034 CBFD -83349035 CBFE -83349036 CBFF -83349037 CC00 -83349038 CC01 -83349039 CC02 -83349130 CC03 -83349131 CC04 -83349132 CC05 -83349133 CC06 -83349134 CC07 -83349135 CC08 -83349136 CC09 -83349137 CC0A -83349138 CC0B -83349139 CC0C -83349230 CC0D -83349231 CC0E -83349232 CC0F -83349233 CC10 -83349234 CC11 -83349235 CC12 -83349236 CC13 -83349237 CC14 -83349238 CC15 -83349239 CC16 -83349330 CC17 -83349331 CC18 -83349332 CC19 -83349333 CC1A -83349334 CC1B -83349335 CC1C -83349336 CC1D -83349337 CC1E -83349338 CC1F -83349339 CC20 -83349430 CC21 -83349431 CC22 -83349432 CC23 -83349433 CC24 -83349434 CC25 -83349435 CC26 -83349436 CC27 -83349437 CC28 -83349438 CC29 -83349439 CC2A -83349530 CC2B -83349531 CC2C -83349532 CC2D -83349533 CC2E -83349534 CC2F -83349535 CC30 -83349536 CC31 -83349537 CC32 -83349538 CC33 -83349539 CC34 -83349630 CC35 -83349631 CC36 -83349632 CC37 -83349633 CC38 -83349634 CC39 -83349635 CC3A -83349636 CC3B -83349637 CC3C -83349638 CC3D -83349639 CC3E -83349730 CC3F -83349731 CC40 -83349732 CC41 -83349733 CC42 -83349734 CC43 -83349735 CC44 -83349736 CC45 -83349737 CC46 -83349738 CC47 -83349739 CC48 -83349830 CC49 -83349831 CC4A -83349832 CC4B -83349833 CC4C -83349834 CC4D -83349835 CC4E -83349836 CC4F -83349837 CC50 -83349838 CC51 -83349839 CC52 -83349930 CC53 -83349931 CC54 -83349932 CC55 -83349933 CC56 -83349934 CC57 -83349935 CC58 -83349936 CC59 -83349937 CC5A -83349938 CC5B -83349939 CC5C -83349A30 CC5D -83349A31 CC5E -83349A32 CC5F -83349A33 CC60 -83349A34 CC61 -83349A35 CC62 -83349A36 CC63 -83349A37 CC64 -83349A38 CC65 -83349A39 CC66 -83349B30 CC67 -83349B31 CC68 -83349B32 CC69 -83349B33 CC6A -83349B34 CC6B -83349B35 CC6C -83349B36 CC6D -83349B37 CC6E -83349B38 CC6F -83349B39 CC70 -83349C30 CC71 -83349C31 CC72 -83349C32 CC73 -83349C33 CC74 -83349C34 CC75 -83349C35 CC76 -83349C36 CC77 -83349C37 CC78 -83349C38 CC79 -83349C39 CC7A -83349D30 CC7B -83349D31 CC7C -83349D32 CC7D -83349D33 CC7E -83349D34 CC7F -83349D35 CC80 -83349D36 CC81 -83349D37 CC82 -83349D38 CC83 -83349D39 CC84 -83349E30 CC85 -83349E31 CC86 -83349E32 CC87 -83349E33 CC88 -83349E34 CC89 -83349E35 CC8A -83349E36 CC8B -83349E37 CC8C -83349E38 CC8D -83349E39 CC8E -83349F30 CC8F -83349F31 CC90 -83349F32 CC91 -83349F33 CC92 -83349F34 CC93 -83349F35 CC94 -83349F36 CC95 -83349F37 CC96 -83349F38 CC97 -83349F39 CC98 -8334A030 CC99 -8334A031 CC9A -8334A032 CC9B -8334A033 CC9C -8334A034 CC9D -8334A035 CC9E -8334A036 CC9F -8334A037 CCA0 -8334A038 CCA1 -8334A039 CCA2 -8334A130 CCA3 -8334A131 CCA4 -8334A132 CCA5 -8334A133 CCA6 -8334A134 CCA7 -8334A135 CCA8 -8334A136 CCA9 -8334A137 CCAA -8334A138 CCAB -8334A139 CCAC -8334A230 CCAD -8334A231 CCAE -8334A232 CCAF -8334A233 CCB0 -8334A234 CCB1 -8334A235 CCB2 -8334A236 CCB3 -8334A237 CCB4 -8334A238 CCB5 -8334A239 CCB6 -8334A330 CCB7 -8334A331 CCB8 -8334A332 CCB9 -8334A333 CCBA -8334A334 CCBB -8334A335 CCBC -8334A336 CCBD -8334A337 CCBE -8334A338 CCBF -8334A339 CCC0 -8334A430 CCC1 -8334A431 CCC2 -8334A432 CCC3 -8334A433 CCC4 -8334A434 CCC5 -8334A435 CCC6 -8334A436 CCC7 -8334A437 CCC8 -8334A438 CCC9 -8334A439 CCCA -8334A530 CCCB -8334A531 CCCC -8334A532 CCCD -8334A533 CCCE -8334A534 CCCF -8334A535 CCD0 -8334A536 CCD1 -8334A537 CCD2 -8334A538 CCD3 -8334A539 CCD4 -8334A630 CCD5 -8334A631 CCD6 -8334A632 CCD7 -8334A633 CCD8 -8334A634 CCD9 -8334A635 CCDA -8334A636 CCDB -8334A637 CCDC -8334A638 CCDD -8334A639 CCDE -8334A730 CCDF -8334A731 CCE0 -8334A732 CCE1 -8334A733 CCE2 -8334A734 CCE3 -8334A735 CCE4 -8334A736 CCE5 -8334A737 CCE6 -8334A738 CCE7 -8334A739 CCE8 -8334A830 CCE9 -8334A831 CCEA -8334A832 CCEB -8334A833 CCEC -8334A834 CCED -8334A835 CCEE -8334A836 CCEF -8334A837 CCF0 -8334A838 CCF1 -8334A839 CCF2 -8334A930 CCF3 -8334A931 CCF4 -8334A932 CCF5 -8334A933 CCF6 -8334A934 CCF7 -8334A935 CCF8 -8334A936 CCF9 -8334A937 CCFA -8334A938 CCFB -8334A939 CCFC -8334AA30 CCFD -8334AA31 CCFE -8334AA32 CCFF -8334AA33 CD00 -8334AA34 CD01 -8334AA35 CD02 -8334AA36 CD03 -8334AA37 CD04 -8334AA38 CD05 -8334AA39 CD06 -8334AB30 CD07 -8334AB31 CD08 -8334AB32 CD09 -8334AB33 CD0A -8334AB34 CD0B -8334AB35 CD0C -8334AB36 CD0D -8334AB37 CD0E -8334AB38 CD0F -8334AB39 CD10 -8334AC30 CD11 -8334AC31 CD12 -8334AC32 CD13 -8334AC33 CD14 -8334AC34 CD15 -8334AC35 CD16 -8334AC36 CD17 -8334AC37 CD18 -8334AC38 CD19 -8334AC39 CD1A -8334AD30 CD1B -8334AD31 CD1C -8334AD32 CD1D -8334AD33 CD1E -8334AD34 CD1F -8334AD35 CD20 -8334AD36 CD21 -8334AD37 CD22 -8334AD38 CD23 -8334AD39 CD24 -8334AE30 CD25 -8334AE31 CD26 -8334AE32 CD27 -8334AE33 CD28 -8334AE34 CD29 -8334AE35 CD2A -8334AE36 CD2B -8334AE37 CD2C -8334AE38 CD2D -8334AE39 CD2E -8334AF30 CD2F -8334AF31 CD30 -8334AF32 CD31 -8334AF33 CD32 -8334AF34 CD33 -8334AF35 CD34 -8334AF36 CD35 -8334AF37 CD36 -8334AF38 CD37 -8334AF39 CD38 -8334B030 CD39 -8334B031 CD3A -8334B032 CD3B -8334B033 CD3C -8334B034 CD3D -8334B035 CD3E -8334B036 CD3F -8334B037 CD40 -8334B038 CD41 -8334B039 CD42 -8334B130 CD43 -8334B131 CD44 -8334B132 CD45 -8334B133 CD46 -8334B134 CD47 -8334B135 CD48 -8334B136 CD49 -8334B137 CD4A -8334B138 CD4B -8334B139 CD4C -8334B230 CD4D -8334B231 CD4E -8334B232 CD4F -8334B233 CD50 -8334B234 CD51 -8334B235 CD52 -8334B236 CD53 -8334B237 CD54 -8334B238 CD55 -8334B239 CD56 -8334B330 CD57 -8334B331 CD58 -8334B332 CD59 -8334B333 CD5A -8334B334 CD5B -8334B335 CD5C -8334B336 CD5D -8334B337 CD5E -8334B338 CD5F -8334B339 CD60 -8334B430 CD61 -8334B431 CD62 -8334B432 CD63 -8334B433 CD64 -8334B434 CD65 -8334B435 CD66 -8334B436 CD67 -8334B437 CD68 -8334B438 CD69 -8334B439 CD6A -8334B530 CD6B -8334B531 CD6C -8334B532 CD6D -8334B533 CD6E -8334B534 CD6F -8334B535 CD70 -8334B536 CD71 -8334B537 CD72 -8334B538 CD73 -8334B539 CD74 -8334B630 CD75 -8334B631 CD76 -8334B632 CD77 -8334B633 CD78 -8334B634 CD79 -8334B635 CD7A -8334B636 CD7B -8334B637 CD7C -8334B638 CD7D -8334B639 CD7E -8334B730 CD7F -8334B731 CD80 -8334B732 CD81 -8334B733 CD82 -8334B734 CD83 -8334B735 CD84 -8334B736 CD85 -8334B737 CD86 -8334B738 CD87 -8334B739 CD88 -8334B830 CD89 -8334B831 CD8A -8334B832 CD8B -8334B833 CD8C -8334B834 CD8D -8334B835 CD8E -8334B836 CD8F -8334B837 CD90 -8334B838 CD91 -8334B839 CD92 -8334B930 CD93 -8334B931 CD94 -8334B932 CD95 -8334B933 CD96 -8334B934 CD97 -8334B935 CD98 -8334B936 CD99 -8334B937 CD9A -8334B938 CD9B -8334B939 CD9C -8334BA30 CD9D -8334BA31 CD9E -8334BA32 CD9F -8334BA33 CDA0 -8334BA34 CDA1 -8334BA35 CDA2 -8334BA36 CDA3 -8334BA37 CDA4 -8334BA38 CDA5 -8334BA39 CDA6 -8334BB30 CDA7 -8334BB31 CDA8 -8334BB32 CDA9 -8334BB33 CDAA -8334BB34 CDAB -8334BB35 CDAC -8334BB36 CDAD -8334BB37 CDAE -8334BB38 CDAF -8334BB39 CDB0 -8334BC30 CDB1 -8334BC31 CDB2 -8334BC32 CDB3 -8334BC33 CDB4 -8334BC34 CDB5 -8334BC35 CDB6 -8334BC36 CDB7 -8334BC37 CDB8 -8334BC38 CDB9 -8334BC39 CDBA -8334BD30 CDBB -8334BD31 CDBC -8334BD32 CDBD -8334BD33 CDBE -8334BD34 CDBF -8334BD35 CDC0 -8334BD36 CDC1 -8334BD37 CDC2 -8334BD38 CDC3 -8334BD39 CDC4 -8334BE30 CDC5 -8334BE31 CDC6 -8334BE32 CDC7 -8334BE33 CDC8 -8334BE34 CDC9 -8334BE35 CDCA -8334BE36 CDCB -8334BE37 CDCC -8334BE38 CDCD -8334BE39 CDCE -8334BF30 CDCF -8334BF31 CDD0 -8334BF32 CDD1 -8334BF33 CDD2 -8334BF34 CDD3 -8334BF35 CDD4 -8334BF36 CDD5 -8334BF37 CDD6 -8334BF38 CDD7 -8334BF39 CDD8 -8334C030 CDD9 -8334C031 CDDA -8334C032 CDDB -8334C033 CDDC -8334C034 CDDD -8334C035 CDDE -8334C036 CDDF -8334C037 CDE0 -8334C038 CDE1 -8334C039 CDE2 -8334C130 CDE3 -8334C131 CDE4 -8334C132 CDE5 -8334C133 CDE6 -8334C134 CDE7 -8334C135 CDE8 -8334C136 CDE9 -8334C137 CDEA -8334C138 CDEB -8334C139 CDEC -8334C230 CDED -8334C231 CDEE -8334C232 CDEF -8334C233 CDF0 -8334C234 CDF1 -8334C235 CDF2 -8334C236 CDF3 -8334C237 CDF4 -8334C238 CDF5 -8334C239 CDF6 -8334C330 CDF7 -8334C331 CDF8 -8334C332 CDF9 -8334C333 CDFA -8334C334 CDFB -8334C335 CDFC -8334C336 CDFD -8334C337 CDFE -8334C338 CDFF -8334C339 CE00 -8334C430 CE01 -8334C431 CE02 -8334C432 CE03 -8334C433 CE04 -8334C434 CE05 -8334C435 CE06 -8334C436 CE07 -8334C437 CE08 -8334C438 CE09 -8334C439 CE0A -8334C530 CE0B -8334C531 CE0C -8334C532 CE0D -8334C533 CE0E -8334C534 CE0F -8334C535 CE10 -8334C536 CE11 -8334C537 CE12 -8334C538 CE13 -8334C539 CE14 -8334C630 CE15 -8334C631 CE16 -8334C632 CE17 -8334C633 CE18 -8334C634 CE19 -8334C635 CE1A -8334C636 CE1B -8334C637 CE1C -8334C638 CE1D -8334C639 CE1E -8334C730 CE1F -8334C731 CE20 -8334C732 CE21 -8334C733 CE22 -8334C734 CE23 -8334C735 CE24 -8334C736 CE25 -8334C737 CE26 -8334C738 CE27 -8334C739 CE28 -8334C830 CE29 -8334C831 CE2A -8334C832 CE2B -8334C833 CE2C -8334C834 CE2D -8334C835 CE2E -8334C836 CE2F -8334C837 CE30 -8334C838 CE31 -8334C839 CE32 -8334C930 CE33 -8334C931 CE34 -8334C932 CE35 -8334C933 CE36 -8334C934 CE37 -8334C935 CE38 -8334C936 CE39 -8334C937 CE3A -8334C938 CE3B -8334C939 CE3C -8334CA30 CE3D -8334CA31 CE3E -8334CA32 CE3F -8334CA33 CE40 -8334CA34 CE41 -8334CA35 CE42 -8334CA36 CE43 -8334CA37 CE44 -8334CA38 CE45 -8334CA39 CE46 -8334CB30 CE47 -8334CB31 CE48 -8334CB32 CE49 -8334CB33 CE4A -8334CB34 CE4B -8334CB35 CE4C -8334CB36 CE4D -8334CB37 CE4E -8334CB38 CE4F -8334CB39 CE50 -8334CC30 CE51 -8334CC31 CE52 -8334CC32 CE53 -8334CC33 CE54 -8334CC34 CE55 -8334CC35 CE56 -8334CC36 CE57 -8334CC37 CE58 -8334CC38 CE59 -8334CC39 CE5A -8334CD30 CE5B -8334CD31 CE5C -8334CD32 CE5D -8334CD33 CE5E -8334CD34 CE5F -8334CD35 CE60 -8334CD36 CE61 -8334CD37 CE62 -8334CD38 CE63 -8334CD39 CE64 -8334CE30 CE65 -8334CE31 CE66 -8334CE32 CE67 -8334CE33 CE68 -8334CE34 CE69 -8334CE35 CE6A -8334CE36 CE6B -8334CE37 CE6C -8334CE38 CE6D -8334CE39 CE6E -8334CF30 CE6F -8334CF31 CE70 -8334CF32 CE71 -8334CF33 CE72 -8334CF34 CE73 -8334CF35 CE74 -8334CF36 CE75 -8334CF37 CE76 -8334CF38 CE77 -8334CF39 CE78 -8334D030 CE79 -8334D031 CE7A -8334D032 CE7B -8334D033 CE7C -8334D034 CE7D -8334D035 CE7E -8334D036 CE7F -8334D037 CE80 -8334D038 CE81 -8334D039 CE82 -8334D130 CE83 -8334D131 CE84 -8334D132 CE85 -8334D133 CE86 -8334D134 CE87 -8334D135 CE88 -8334D136 CE89 -8334D137 CE8A -8334D138 CE8B -8334D139 CE8C -8334D230 CE8D -8334D231 CE8E -8334D232 CE8F -8334D233 CE90 -8334D234 CE91 -8334D235 CE92 -8334D236 CE93 -8334D237 CE94 -8334D238 CE95 -8334D239 CE96 -8334D330 CE97 -8334D331 CE98 -8334D332 CE99 -8334D333 CE9A -8334D334 CE9B -8334D335 CE9C -8334D336 CE9D -8334D337 CE9E -8334D338 CE9F -8334D339 CEA0 -8334D430 CEA1 -8334D431 CEA2 -8334D432 CEA3 -8334D433 CEA4 -8334D434 CEA5 -8334D435 CEA6 -8334D436 CEA7 -8334D437 CEA8 -8334D438 CEA9 -8334D439 CEAA -8334D530 CEAB -8334D531 CEAC -8334D532 CEAD -8334D533 CEAE -8334D534 CEAF -8334D535 CEB0 -8334D536 CEB1 -8334D537 CEB2 -8334D538 CEB3 -8334D539 CEB4 -8334D630 CEB5 -8334D631 CEB6 -8334D632 CEB7 -8334D633 CEB8 -8334D634 CEB9 -8334D635 CEBA -8334D636 CEBB -8334D637 CEBC -8334D638 CEBD -8334D639 CEBE -8334D730 CEBF -8334D731 CEC0 -8334D732 CEC1 -8334D733 CEC2 -8334D734 CEC3 -8334D735 CEC4 -8334D736 CEC5 -8334D737 CEC6 -8334D738 CEC7 -8334D739 CEC8 -8334D830 CEC9 -8334D831 CECA -8334D832 CECB -8334D833 CECC -8334D834 CECD -8334D835 CECE -8334D836 CECF -8334D837 CED0 -8334D838 CED1 -8334D839 CED2 -8334D930 CED3 -8334D931 CED4 -8334D932 CED5 -8334D933 CED6 -8334D934 CED7 -8334D935 CED8 -8334D936 CED9 -8334D937 CEDA -8334D938 CEDB -8334D939 CEDC -8334DA30 CEDD -8334DA31 CEDE -8334DA32 CEDF -8334DA33 CEE0 -8334DA34 CEE1 -8334DA35 CEE2 -8334DA36 CEE3 -8334DA37 CEE4 -8334DA38 CEE5 -8334DA39 CEE6 -8334DB30 CEE7 -8334DB31 CEE8 -8334DB32 CEE9 -8334DB33 CEEA -8334DB34 CEEB -8334DB35 CEEC -8334DB36 CEED -8334DB37 CEEE -8334DB38 CEEF -8334DB39 CEF0 -8334DC30 CEF1 -8334DC31 CEF2 -8334DC32 CEF3 -8334DC33 CEF4 -8334DC34 CEF5 -8334DC35 CEF6 -8334DC36 CEF7 -8334DC37 CEF8 -8334DC38 CEF9 -8334DC39 CEFA -8334DD30 CEFB -8334DD31 CEFC -8334DD32 CEFD -8334DD33 CEFE -8334DD34 CEFF -8334DD35 CF00 -8334DD36 CF01 -8334DD37 CF02 -8334DD38 CF03 -8334DD39 CF04 -8334DE30 CF05 -8334DE31 CF06 -8334DE32 CF07 -8334DE33 CF08 -8334DE34 CF09 -8334DE35 CF0A -8334DE36 CF0B -8334DE37 CF0C -8334DE38 CF0D -8334DE39 CF0E -8334DF30 CF0F -8334DF31 CF10 -8334DF32 CF11 -8334DF33 CF12 -8334DF34 CF13 -8334DF35 CF14 -8334DF36 CF15 -8334DF37 CF16 -8334DF38 CF17 -8334DF39 CF18 -8334E030 CF19 -8334E031 CF1A -8334E032 CF1B -8334E033 CF1C -8334E034 CF1D -8334E035 CF1E -8334E036 CF1F -8334E037 CF20 -8334E038 CF21 -8334E039 CF22 -8334E130 CF23 -8334E131 CF24 -8334E132 CF25 -8334E133 CF26 -8334E134 CF27 -8334E135 CF28 -8334E136 CF29 -8334E137 CF2A -8334E138 CF2B -8334E139 CF2C -8334E230 CF2D -8334E231 CF2E -8334E232 CF2F -8334E233 CF30 -8334E234 CF31 -8334E235 CF32 -8334E236 CF33 -8334E237 CF34 -8334E238 CF35 -8334E239 CF36 -8334E330 CF37 -8334E331 CF38 -8334E332 CF39 -8334E333 CF3A -8334E334 CF3B -8334E335 CF3C -8334E336 CF3D -8334E337 CF3E -8334E338 CF3F -8334E339 CF40 -8334E430 CF41 -8334E431 CF42 -8334E432 CF43 -8334E433 CF44 -8334E434 CF45 -8334E435 CF46 -8334E436 CF47 -8334E437 CF48 -8334E438 CF49 -8334E439 CF4A -8334E530 CF4B -8334E531 CF4C -8334E532 CF4D -8334E533 CF4E -8334E534 CF4F -8334E535 CF50 -8334E536 CF51 -8334E537 CF52 -8334E538 CF53 -8334E539 CF54 -8334E630 CF55 -8334E631 CF56 -8334E632 CF57 -8334E633 CF58 -8334E634 CF59 -8334E635 CF5A -8334E636 CF5B -8334E637 CF5C -8334E638 CF5D -8334E639 CF5E -8334E730 CF5F -8334E731 CF60 -8334E732 CF61 -8334E733 CF62 -8334E734 CF63 -8334E735 CF64 -8334E736 CF65 -8334E737 CF66 -8334E738 CF67 -8334E739 CF68 -8334E830 CF69 -8334E831 CF6A -8334E832 CF6B -8334E833 CF6C -8334E834 CF6D -8334E835 CF6E -8334E836 CF6F -8334E837 CF70 -8334E838 CF71 -8334E839 CF72 -8334E930 CF73 -8334E931 CF74 -8334E932 CF75 -8334E933 CF76 -8334E934 CF77 -8334E935 CF78 -8334E936 CF79 -8334E937 CF7A -8334E938 CF7B -8334E939 CF7C -8334EA30 CF7D -8334EA31 CF7E -8334EA32 CF7F -8334EA33 CF80 -8334EA34 CF81 -8334EA35 CF82 -8334EA36 CF83 -8334EA37 CF84 -8334EA38 CF85 -8334EA39 CF86 -8334EB30 CF87 -8334EB31 CF88 -8334EB32 CF89 -8334EB33 CF8A -8334EB34 CF8B -8334EB35 CF8C -8334EB36 CF8D -8334EB37 CF8E -8334EB38 CF8F -8334EB39 CF90 -8334EC30 CF91 -8334EC31 CF92 -8334EC32 CF93 -8334EC33 CF94 -8334EC34 CF95 -8334EC35 CF96 -8334EC36 CF97 -8334EC37 CF98 -8334EC38 CF99 -8334EC39 CF9A -8334ED30 CF9B -8334ED31 CF9C -8334ED32 CF9D -8334ED33 CF9E -8334ED34 CF9F -8334ED35 CFA0 -8334ED36 CFA1 -8334ED37 CFA2 -8334ED38 CFA3 -8334ED39 CFA4 -8334EE30 CFA5 -8334EE31 CFA6 -8334EE32 CFA7 -8334EE33 CFA8 -8334EE34 CFA9 -8334EE35 CFAA -8334EE36 CFAB -8334EE37 CFAC -8334EE38 CFAD -8334EE39 CFAE -8334EF30 CFAF -8334EF31 CFB0 -8334EF32 CFB1 -8334EF33 CFB2 -8334EF34 CFB3 -8334EF35 CFB4 -8334EF36 CFB5 -8334EF37 CFB6 -8334EF38 CFB7 -8334EF39 CFB8 -8334F030 CFB9 -8334F031 CFBA -8334F032 CFBB -8334F033 CFBC -8334F034 CFBD -8334F035 CFBE -8334F036 CFBF -8334F037 CFC0 -8334F038 CFC1 -8334F039 CFC2 -8334F130 CFC3 -8334F131 CFC4 -8334F132 CFC5 -8334F133 CFC6 -8334F134 CFC7 -8334F135 CFC8 -8334F136 CFC9 -8334F137 CFCA -8334F138 CFCB -8334F139 CFCC -8334F230 CFCD -8334F231 CFCE -8334F232 CFCF -8334F233 CFD0 -8334F234 CFD1 -8334F235 CFD2 -8334F236 CFD3 -8334F237 CFD4 -8334F238 CFD5 -8334F239 CFD6 -8334F330 CFD7 -8334F331 CFD8 -8334F332 CFD9 -8334F333 CFDA -8334F334 CFDB -8334F335 CFDC -8334F336 CFDD -8334F337 CFDE -8334F338 CFDF -8334F339 CFE0 -8334F430 CFE1 -8334F431 CFE2 -8334F432 CFE3 -8334F433 CFE4 -8334F434 CFE5 -8334F435 CFE6 -8334F436 CFE7 -8334F437 CFE8 -8334F438 CFE9 -8334F439 CFEA -8334F530 CFEB -8334F531 CFEC -8334F532 CFED -8334F533 CFEE -8334F534 CFEF -8334F535 CFF0 -8334F536 CFF1 -8334F537 CFF2 -8334F538 CFF3 -8334F539 CFF4 -8334F630 CFF5 -8334F631 CFF6 -8334F632 CFF7 -8334F633 CFF8 -8334F634 CFF9 -8334F635 CFFA -8334F636 CFFB -8334F637 CFFC -8334F638 CFFD -8334F639 CFFE -8334F730 CFFF -8334F731 D000 -8334F732 D001 -8334F733 D002 -8334F734 D003 -8334F735 D004 -8334F736 D005 -8334F737 D006 -8334F738 D007 -8334F739 D008 -8334F830 D009 -8334F831 D00A -8334F832 D00B -8334F833 D00C -8334F834 D00D -8334F835 D00E -8334F836 D00F -8334F837 D010 -8334F838 D011 -8334F839 D012 -8334F930 D013 -8334F931 D014 -8334F932 D015 -8334F933 D016 -8334F934 D017 -8334F935 D018 -8334F936 D019 -8334F937 D01A -8334F938 D01B -8334F939 D01C -8334FA30 D01D -8334FA31 D01E -8334FA32 D01F -8334FA33 D020 -8334FA34 D021 -8334FA35 D022 -8334FA36 D023 -8334FA37 D024 -8334FA38 D025 -8334FA39 D026 -8334FB30 D027 -8334FB31 D028 -8334FB32 D029 -8334FB33 D02A -8334FB34 D02B -8334FB35 D02C -8334FB36 D02D -8334FB37 D02E -8334FB38 D02F -8334FB39 D030 -8334FC30 D031 -8334FC31 D032 -8334FC32 D033 -8334FC33 D034 -8334FC34 D035 -8334FC35 D036 -8334FC36 D037 -8334FC37 D038 -8334FC38 D039 -8334FC39 D03A -8334FD30 D03B -8334FD31 D03C -8334FD32 D03D -8334FD33 D03E -8334FD34 D03F -8334FD35 D040 -8334FD36 D041 -8334FD37 D042 -8334FD38 D043 -8334FD39 D044 -8334FE30 D045 -8334FE31 D046 -8334FE32 D047 -8334FE33 D048 -8334FE34 D049 -8334FE35 D04A -8334FE36 D04B -8334FE37 D04C -8334FE38 D04D -8334FE39 D04E -83358130 D04F -83358131 D050 -83358132 D051 -83358133 D052 -83358134 D053 -83358135 D054 -83358136 D055 -83358137 D056 -83358138 D057 -83358139 D058 -83358230 D059 -83358231 D05A -83358232 D05B -83358233 D05C -83358234 D05D -83358235 D05E -83358236 D05F -83358237 D060 -83358238 D061 -83358239 D062 -83358330 D063 -83358331 D064 -83358332 D065 -83358333 D066 -83358334 D067 -83358335 D068 -83358336 D069 -83358337 D06A -83358338 D06B -83358339 D06C -83358430 D06D -83358431 D06E -83358432 D06F -83358433 D070 -83358434 D071 -83358435 D072 -83358436 D073 -83358437 D074 -83358438 D075 -83358439 D076 -83358530 D077 -83358531 D078 -83358532 D079 -83358533 D07A -83358534 D07B -83358535 D07C -83358536 D07D -83358537 D07E -83358538 D07F -83358539 D080 -83358630 D081 -83358631 D082 -83358632 D083 -83358633 D084 -83358634 D085 -83358635 D086 -83358636 D087 -83358637 D088 -83358638 D089 -83358639 D08A -83358730 D08B -83358731 D08C -83358732 D08D -83358733 D08E -83358734 D08F -83358735 D090 -83358736 D091 -83358737 D092 -83358738 D093 -83358739 D094 -83358830 D095 -83358831 D096 -83358832 D097 -83358833 D098 -83358834 D099 -83358835 D09A -83358836 D09B -83358837 D09C -83358838 D09D -83358839 D09E -83358930 D09F -83358931 D0A0 -83358932 D0A1 -83358933 D0A2 -83358934 D0A3 -83358935 D0A4 -83358936 D0A5 -83358937 D0A6 -83358938 D0A7 -83358939 D0A8 -83358A30 D0A9 -83358A31 D0AA -83358A32 D0AB -83358A33 D0AC -83358A34 D0AD -83358A35 D0AE -83358A36 D0AF -83358A37 D0B0 -83358A38 D0B1 -83358A39 D0B2 -83358B30 D0B3 -83358B31 D0B4 -83358B32 D0B5 -83358B33 D0B6 -83358B34 D0B7 -83358B35 D0B8 -83358B36 D0B9 -83358B37 D0BA -83358B38 D0BB -83358B39 D0BC -83358C30 D0BD -83358C31 D0BE -83358C32 D0BF -83358C33 D0C0 -83358C34 D0C1 -83358C35 D0C2 -83358C36 D0C3 -83358C37 D0C4 -83358C38 D0C5 -83358C39 D0C6 -83358D30 D0C7 -83358D31 D0C8 -83358D32 D0C9 -83358D33 D0CA -83358D34 D0CB -83358D35 D0CC -83358D36 D0CD -83358D37 D0CE -83358D38 D0CF -83358D39 D0D0 -83358E30 D0D1 -83358E31 D0D2 -83358E32 D0D3 -83358E33 D0D4 -83358E34 D0D5 -83358E35 D0D6 -83358E36 D0D7 -83358E37 D0D8 -83358E38 D0D9 -83358E39 D0DA -83358F30 D0DB -83358F31 D0DC -83358F32 D0DD -83358F33 D0DE -83358F34 D0DF -83358F35 D0E0 -83358F36 D0E1 -83358F37 D0E2 -83358F38 D0E3 -83358F39 D0E4 -83359030 D0E5 -83359031 D0E6 -83359032 D0E7 -83359033 D0E8 -83359034 D0E9 -83359035 D0EA -83359036 D0EB -83359037 D0EC -83359038 D0ED -83359039 D0EE -83359130 D0EF -83359131 D0F0 -83359132 D0F1 -83359133 D0F2 -83359134 D0F3 -83359135 D0F4 -83359136 D0F5 -83359137 D0F6 -83359138 D0F7 -83359139 D0F8 -83359230 D0F9 -83359231 D0FA -83359232 D0FB -83359233 D0FC -83359234 D0FD -83359235 D0FE -83359236 D0FF -83359237 D100 -83359238 D101 -83359239 D102 -83359330 D103 -83359331 D104 -83359332 D105 -83359333 D106 -83359334 D107 -83359335 D108 -83359336 D109 -83359337 D10A -83359338 D10B -83359339 D10C -83359430 D10D -83359431 D10E -83359432 D10F -83359433 D110 -83359434 D111 -83359435 D112 -83359436 D113 -83359437 D114 -83359438 D115 -83359439 D116 -83359530 D117 -83359531 D118 -83359532 D119 -83359533 D11A -83359534 D11B -83359535 D11C -83359536 D11D -83359537 D11E -83359538 D11F -83359539 D120 -83359630 D121 -83359631 D122 -83359632 D123 -83359633 D124 -83359634 D125 -83359635 D126 -83359636 D127 -83359637 D128 -83359638 D129 -83359639 D12A -83359730 D12B -83359731 D12C -83359732 D12D -83359733 D12E -83359734 D12F -83359735 D130 -83359736 D131 -83359737 D132 -83359738 D133 -83359739 D134 -83359830 D135 -83359831 D136 -83359832 D137 -83359833 D138 -83359834 D139 -83359835 D13A -83359836 D13B -83359837 D13C -83359838 D13D -83359839 D13E -83359930 D13F -83359931 D140 -83359932 D141 -83359933 D142 -83359934 D143 -83359935 D144 -83359936 D145 -83359937 D146 -83359938 D147 -83359939 D148 -83359A30 D149 -83359A31 D14A -83359A32 D14B -83359A33 D14C -83359A34 D14D -83359A35 D14E -83359A36 D14F -83359A37 D150 -83359A38 D151 -83359A39 D152 -83359B30 D153 -83359B31 D154 -83359B32 D155 -83359B33 D156 -83359B34 D157 -83359B35 D158 -83359B36 D159 -83359B37 D15A -83359B38 D15B -83359B39 D15C -83359C30 D15D -83359C31 D15E -83359C32 D15F -83359C33 D160 -83359C34 D161 -83359C35 D162 -83359C36 D163 -83359C37 D164 -83359C38 D165 -83359C39 D166 -83359D30 D167 -83359D31 D168 -83359D32 D169 -83359D33 D16A -83359D34 D16B -83359D35 D16C -83359D36 D16D -83359D37 D16E -83359D38 D16F -83359D39 D170 -83359E30 D171 -83359E31 D172 -83359E32 D173 -83359E33 D174 -83359E34 D175 -83359E35 D176 -83359E36 D177 -83359E37 D178 -83359E38 D179 -83359E39 D17A -83359F30 D17B -83359F31 D17C -83359F32 D17D -83359F33 D17E -83359F34 D17F -83359F35 D180 -83359F36 D181 -83359F37 D182 -83359F38 D183 -83359F39 D184 -8335A030 D185 -8335A031 D186 -8335A032 D187 -8335A033 D188 -8335A034 D189 -8335A035 D18A -8335A036 D18B -8335A037 D18C -8335A038 D18D -8335A039 D18E -8335A130 D18F -8335A131 D190 -8335A132 D191 -8335A133 D192 -8335A134 D193 -8335A135 D194 -8335A136 D195 -8335A137 D196 -8335A138 D197 -8335A139 D198 -8335A230 D199 -8335A231 D19A -8335A232 D19B -8335A233 D19C -8335A234 D19D -8335A235 D19E -8335A236 D19F -8335A237 D1A0 -8335A238 D1A1 -8335A239 D1A2 -8335A330 D1A3 -8335A331 D1A4 -8335A332 D1A5 -8335A333 D1A6 -8335A334 D1A7 -8335A335 D1A8 -8335A336 D1A9 -8335A337 D1AA -8335A338 D1AB -8335A339 D1AC -8335A430 D1AD -8335A431 D1AE -8335A432 D1AF -8335A433 D1B0 -8335A434 D1B1 -8335A435 D1B2 -8335A436 D1B3 -8335A437 D1B4 -8335A438 D1B5 -8335A439 D1B6 -8335A530 D1B7 -8335A531 D1B8 -8335A532 D1B9 -8335A533 D1BA -8335A534 D1BB -8335A535 D1BC -8335A536 D1BD -8335A537 D1BE -8335A538 D1BF -8335A539 D1C0 -8335A630 D1C1 -8335A631 D1C2 -8335A632 D1C3 -8335A633 D1C4 -8335A634 D1C5 -8335A635 D1C6 -8335A636 D1C7 -8335A637 D1C8 -8335A638 D1C9 -8335A639 D1CA -8335A730 D1CB -8335A731 D1CC -8335A732 D1CD -8335A733 D1CE -8335A734 D1CF -8335A735 D1D0 -8335A736 D1D1 -8335A737 D1D2 -8335A738 D1D3 -8335A739 D1D4 -8335A830 D1D5 -8335A831 D1D6 -8335A832 D1D7 -8335A833 D1D8 -8335A834 D1D9 -8335A835 D1DA -8335A836 D1DB -8335A837 D1DC -8335A838 D1DD -8335A839 D1DE -8335A930 D1DF -8335A931 D1E0 -8335A932 D1E1 -8335A933 D1E2 -8335A934 D1E3 -8335A935 D1E4 -8335A936 D1E5 -8335A937 D1E6 -8335A938 D1E7 -8335A939 D1E8 -8335AA30 D1E9 -8335AA31 D1EA -8335AA32 D1EB -8335AA33 D1EC -8335AA34 D1ED -8335AA35 D1EE -8335AA36 D1EF -8335AA37 D1F0 -8335AA38 D1F1 -8335AA39 D1F2 -8335AB30 D1F3 -8335AB31 D1F4 -8335AB32 D1F5 -8335AB33 D1F6 -8335AB34 D1F7 -8335AB35 D1F8 -8335AB36 D1F9 -8335AB37 D1FA -8335AB38 D1FB -8335AB39 D1FC -8335AC30 D1FD -8335AC31 D1FE -8335AC32 D1FF -8335AC33 D200 -8335AC34 D201 -8335AC35 D202 -8335AC36 D203 -8335AC37 D204 -8335AC38 D205 -8335AC39 D206 -8335AD30 D207 -8335AD31 D208 -8335AD32 D209 -8335AD33 D20A -8335AD34 D20B -8335AD35 D20C -8335AD36 D20D -8335AD37 D20E -8335AD38 D20F -8335AD39 D210 -8335AE30 D211 -8335AE31 D212 -8335AE32 D213 -8335AE33 D214 -8335AE34 D215 -8335AE35 D216 -8335AE36 D217 -8335AE37 D218 -8335AE38 D219 -8335AE39 D21A -8335AF30 D21B -8335AF31 D21C -8335AF32 D21D -8335AF33 D21E -8335AF34 D21F -8335AF35 D220 -8335AF36 D221 -8335AF37 D222 -8335AF38 D223 -8335AF39 D224 -8335B030 D225 -8335B031 D226 -8335B032 D227 -8335B033 D228 -8335B034 D229 -8335B035 D22A -8335B036 D22B -8335B037 D22C -8335B038 D22D -8335B039 D22E -8335B130 D22F -8335B131 D230 -8335B132 D231 -8335B133 D232 -8335B134 D233 -8335B135 D234 -8335B136 D235 -8335B137 D236 -8335B138 D237 -8335B139 D238 -8335B230 D239 -8335B231 D23A -8335B232 D23B -8335B233 D23C -8335B234 D23D -8335B235 D23E -8335B236 D23F -8335B237 D240 -8335B238 D241 -8335B239 D242 -8335B330 D243 -8335B331 D244 -8335B332 D245 -8335B333 D246 -8335B334 D247 -8335B335 D248 -8335B336 D249 -8335B337 D24A -8335B338 D24B -8335B339 D24C -8335B430 D24D -8335B431 D24E -8335B432 D24F -8335B433 D250 -8335B434 D251 -8335B435 D252 -8335B436 D253 -8335B437 D254 -8335B438 D255 -8335B439 D256 -8335B530 D257 -8335B531 D258 -8335B532 D259 -8335B533 D25A -8335B534 D25B -8335B535 D25C -8335B536 D25D -8335B537 D25E -8335B538 D25F -8335B539 D260 -8335B630 D261 -8335B631 D262 -8335B632 D263 -8335B633 D264 -8335B634 D265 -8335B635 D266 -8335B636 D267 -8335B637 D268 -8335B638 D269 -8335B639 D26A -8335B730 D26B -8335B731 D26C -8335B732 D26D -8335B733 D26E -8335B734 D26F -8335B735 D270 -8335B736 D271 -8335B737 D272 -8335B738 D273 -8335B739 D274 -8335B830 D275 -8335B831 D276 -8335B832 D277 -8335B833 D278 -8335B834 D279 -8335B835 D27A -8335B836 D27B -8335B837 D27C -8335B838 D27D -8335B839 D27E -8335B930 D27F -8335B931 D280 -8335B932 D281 -8335B933 D282 -8335B934 D283 -8335B935 D284 -8335B936 D285 -8335B937 D286 -8335B938 D287 -8335B939 D288 -8335BA30 D289 -8335BA31 D28A -8335BA32 D28B -8335BA33 D28C -8335BA34 D28D -8335BA35 D28E -8335BA36 D28F -8335BA37 D290 -8335BA38 D291 -8335BA39 D292 -8335BB30 D293 -8335BB31 D294 -8335BB32 D295 -8335BB33 D296 -8335BB34 D297 -8335BB35 D298 -8335BB36 D299 -8335BB37 D29A -8335BB38 D29B -8335BB39 D29C -8335BC30 D29D -8335BC31 D29E -8335BC32 D29F -8335BC33 D2A0 -8335BC34 D2A1 -8335BC35 D2A2 -8335BC36 D2A3 -8335BC37 D2A4 -8335BC38 D2A5 -8335BC39 D2A6 -8335BD30 D2A7 -8335BD31 D2A8 -8335BD32 D2A9 -8335BD33 D2AA -8335BD34 D2AB -8335BD35 D2AC -8335BD36 D2AD -8335BD37 D2AE -8335BD38 D2AF -8335BD39 D2B0 -8335BE30 D2B1 -8335BE31 D2B2 -8335BE32 D2B3 -8335BE33 D2B4 -8335BE34 D2B5 -8335BE35 D2B6 -8335BE36 D2B7 -8335BE37 D2B8 -8335BE38 D2B9 -8335BE39 D2BA -8335BF30 D2BB -8335BF31 D2BC -8335BF32 D2BD -8335BF33 D2BE -8335BF34 D2BF -8335BF35 D2C0 -8335BF36 D2C1 -8335BF37 D2C2 -8335BF38 D2C3 -8335BF39 D2C4 -8335C030 D2C5 -8335C031 D2C6 -8335C032 D2C7 -8335C033 D2C8 -8335C034 D2C9 -8335C035 D2CA -8335C036 D2CB -8335C037 D2CC -8335C038 D2CD -8335C039 D2CE -8335C130 D2CF -8335C131 D2D0 -8335C132 D2D1 -8335C133 D2D2 -8335C134 D2D3 -8335C135 D2D4 -8335C136 D2D5 -8335C137 D2D6 -8335C138 D2D7 -8335C139 D2D8 -8335C230 D2D9 -8335C231 D2DA -8335C232 D2DB -8335C233 D2DC -8335C234 D2DD -8335C235 D2DE -8335C236 D2DF -8335C237 D2E0 -8335C238 D2E1 -8335C239 D2E2 -8335C330 D2E3 -8335C331 D2E4 -8335C332 D2E5 -8335C333 D2E6 -8335C334 D2E7 -8335C335 D2E8 -8335C336 D2E9 -8335C337 D2EA -8335C338 D2EB -8335C339 D2EC -8335C430 D2ED -8335C431 D2EE -8335C432 D2EF -8335C433 D2F0 -8335C434 D2F1 -8335C435 D2F2 -8335C436 D2F3 -8335C437 D2F4 -8335C438 D2F5 -8335C439 D2F6 -8335C530 D2F7 -8335C531 D2F8 -8335C532 D2F9 -8335C533 D2FA -8335C534 D2FB -8335C535 D2FC -8335C536 D2FD -8335C537 D2FE -8335C538 D2FF -8335C539 D300 -8335C630 D301 -8335C631 D302 -8335C632 D303 -8335C633 D304 -8335C634 D305 -8335C635 D306 -8335C636 D307 -8335C637 D308 -8335C638 D309 -8335C639 D30A -8335C730 D30B -8335C731 D30C -8335C732 D30D -8335C733 D30E -8335C734 D30F -8335C735 D310 -8335C736 D311 -8335C737 D312 -8335C738 D313 -8335C739 D314 -8335C830 D315 -8335C831 D316 -8335C832 D317 -8335C833 D318 -8335C834 D319 -8335C835 D31A -8335C836 D31B -8335C837 D31C -8335C838 D31D -8335C839 D31E -8335C930 D31F -8335C931 D320 -8335C932 D321 -8335C933 D322 -8335C934 D323 -8335C935 D324 -8335C936 D325 -8335C937 D326 -8335C938 D327 -8335C939 D328 -8335CA30 D329 -8335CA31 D32A -8335CA32 D32B -8335CA33 D32C -8335CA34 D32D -8335CA35 D32E -8335CA36 D32F -8335CA37 D330 -8335CA38 D331 -8335CA39 D332 -8335CB30 D333 -8335CB31 D334 -8335CB32 D335 -8335CB33 D336 -8335CB34 D337 -8335CB35 D338 -8335CB36 D339 -8335CB37 D33A -8335CB38 D33B -8335CB39 D33C -8335CC30 D33D -8335CC31 D33E -8335CC32 D33F -8335CC33 D340 -8335CC34 D341 -8335CC35 D342 -8335CC36 D343 -8335CC37 D344 -8335CC38 D345 -8335CC39 D346 -8335CD30 D347 -8335CD31 D348 -8335CD32 D349 -8335CD33 D34A -8335CD34 D34B -8335CD35 D34C -8335CD36 D34D -8335CD37 D34E -8335CD38 D34F -8335CD39 D350 -8335CE30 D351 -8335CE31 D352 -8335CE32 D353 -8335CE33 D354 -8335CE34 D355 -8335CE35 D356 -8335CE36 D357 -8335CE37 D358 -8335CE38 D359 -8335CE39 D35A -8335CF30 D35B -8335CF31 D35C -8335CF32 D35D -8335CF33 D35E -8335CF34 D35F -8335CF35 D360 -8335CF36 D361 -8335CF37 D362 -8335CF38 D363 -8335CF39 D364 -8335D030 D365 -8335D031 D366 -8335D032 D367 -8335D033 D368 -8335D034 D369 -8335D035 D36A -8335D036 D36B -8335D037 D36C -8335D038 D36D -8335D039 D36E -8335D130 D36F -8335D131 D370 -8335D132 D371 -8335D133 D372 -8335D134 D373 -8335D135 D374 -8335D136 D375 -8335D137 D376 -8335D138 D377 -8335D139 D378 -8335D230 D379 -8335D231 D37A -8335D232 D37B -8335D233 D37C -8335D234 D37D -8335D235 D37E -8335D236 D37F -8335D237 D380 -8335D238 D381 -8335D239 D382 -8335D330 D383 -8335D331 D384 -8335D332 D385 -8335D333 D386 -8335D334 D387 -8335D335 D388 -8335D336 D389 -8335D337 D38A -8335D338 D38B -8335D339 D38C -8335D430 D38D -8335D431 D38E -8335D432 D38F -8335D433 D390 -8335D434 D391 -8335D435 D392 -8335D436 D393 -8335D437 D394 -8335D438 D395 -8335D439 D396 -8335D530 D397 -8335D531 D398 -8335D532 D399 -8335D533 D39A -8335D534 D39B -8335D535 D39C -8335D536 D39D -8335D537 D39E -8335D538 D39F -8335D539 D3A0 -8335D630 D3A1 -8335D631 D3A2 -8335D632 D3A3 -8335D633 D3A4 -8335D634 D3A5 -8335D635 D3A6 -8335D636 D3A7 -8335D637 D3A8 -8335D638 D3A9 -8335D639 D3AA -8335D730 D3AB -8335D731 D3AC -8335D732 D3AD -8335D733 D3AE -8335D734 D3AF -8335D735 D3B0 -8335D736 D3B1 -8335D737 D3B2 -8335D738 D3B3 -8335D739 D3B4 -8335D830 D3B5 -8335D831 D3B6 -8335D832 D3B7 -8335D833 D3B8 -8335D834 D3B9 -8335D835 D3BA -8335D836 D3BB -8335D837 D3BC -8335D838 D3BD -8335D839 D3BE -8335D930 D3BF -8335D931 D3C0 -8335D932 D3C1 -8335D933 D3C2 -8335D934 D3C3 -8335D935 D3C4 -8335D936 D3C5 -8335D937 D3C6 -8335D938 D3C7 -8335D939 D3C8 -8335DA30 D3C9 -8335DA31 D3CA -8335DA32 D3CB -8335DA33 D3CC -8335DA34 D3CD -8335DA35 D3CE -8335DA36 D3CF -8335DA37 D3D0 -8335DA38 D3D1 -8335DA39 D3D2 -8335DB30 D3D3 -8335DB31 D3D4 -8335DB32 D3D5 -8335DB33 D3D6 -8335DB34 D3D7 -8335DB35 D3D8 -8335DB36 D3D9 -8335DB37 D3DA -8335DB38 D3DB -8335DB39 D3DC -8335DC30 D3DD -8335DC31 D3DE -8335DC32 D3DF -8335DC33 D3E0 -8335DC34 D3E1 -8335DC35 D3E2 -8335DC36 D3E3 -8335DC37 D3E4 -8335DC38 D3E5 -8335DC39 D3E6 -8335DD30 D3E7 -8335DD31 D3E8 -8335DD32 D3E9 -8335DD33 D3EA -8335DD34 D3EB -8335DD35 D3EC -8335DD36 D3ED -8335DD37 D3EE -8335DD38 D3EF -8335DD39 D3F0 -8335DE30 D3F1 -8335DE31 D3F2 -8335DE32 D3F3 -8335DE33 D3F4 -8335DE34 D3F5 -8335DE35 D3F6 -8335DE36 D3F7 -8335DE37 D3F8 -8335DE38 D3F9 -8335DE39 D3FA -8335DF30 D3FB -8335DF31 D3FC -8335DF32 D3FD -8335DF33 D3FE -8335DF34 D3FF -8335DF35 D400 -8335DF36 D401 -8335DF37 D402 -8335DF38 D403 -8335DF39 D404 -8335E030 D405 -8335E031 D406 -8335E032 D407 -8335E033 D408 -8335E034 D409 -8335E035 D40A -8335E036 D40B -8335E037 D40C -8335E038 D40D -8335E039 D40E -8335E130 D40F -8335E131 D410 -8335E132 D411 -8335E133 D412 -8335E134 D413 -8335E135 D414 -8335E136 D415 -8335E137 D416 -8335E138 D417 -8335E139 D418 -8335E230 D419 -8335E231 D41A -8335E232 D41B -8335E233 D41C -8335E234 D41D -8335E235 D41E -8335E236 D41F -8335E237 D420 -8335E238 D421 -8335E239 D422 -8335E330 D423 -8335E331 D424 -8335E332 D425 -8335E333 D426 -8335E334 D427 -8335E335 D428 -8335E336 D429 -8335E337 D42A -8335E338 D42B -8335E339 D42C -8335E430 D42D -8335E431 D42E -8335E432 D42F -8335E433 D430 -8335E434 D431 -8335E435 D432 -8335E436 D433 -8335E437 D434 -8335E438 D435 -8335E439 D436 -8335E530 D437 -8335E531 D438 -8335E532 D439 -8335E533 D43A -8335E534 D43B -8335E535 D43C -8335E536 D43D -8335E537 D43E -8335E538 D43F -8335E539 D440 -8335E630 D441 -8335E631 D442 -8335E632 D443 -8335E633 D444 -8335E634 D445 -8335E635 D446 -8335E636 D447 -8335E637 D448 -8335E638 D449 -8335E639 D44A -8335E730 D44B -8335E731 D44C -8335E732 D44D -8335E733 D44E -8335E734 D44F -8335E735 D450 -8335E736 D451 -8335E737 D452 -8335E738 D453 -8335E739 D454 -8335E830 D455 -8335E831 D456 -8335E832 D457 -8335E833 D458 -8335E834 D459 -8335E835 D45A -8335E836 D45B -8335E837 D45C -8335E838 D45D -8335E839 D45E -8335E930 D45F -8335E931 D460 -8335E932 D461 -8335E933 D462 -8335E934 D463 -8335E935 D464 -8335E936 D465 -8335E937 D466 -8335E938 D467 -8335E939 D468 -8335EA30 D469 -8335EA31 D46A -8335EA32 D46B -8335EA33 D46C -8335EA34 D46D -8335EA35 D46E -8335EA36 D46F -8335EA37 D470 -8335EA38 D471 -8335EA39 D472 -8335EB30 D473 -8335EB31 D474 -8335EB32 D475 -8335EB33 D476 -8335EB34 D477 -8335EB35 D478 -8335EB36 D479 -8335EB37 D47A -8335EB38 D47B -8335EB39 D47C -8335EC30 D47D -8335EC31 D47E -8335EC32 D47F -8335EC33 D480 -8335EC34 D481 -8335EC35 D482 -8335EC36 D483 -8335EC37 D484 -8335EC38 D485 -8335EC39 D486 -8335ED30 D487 -8335ED31 D488 -8335ED32 D489 -8335ED33 D48A -8335ED34 D48B -8335ED35 D48C -8335ED36 D48D -8335ED37 D48E -8335ED38 D48F -8335ED39 D490 -8335EE30 D491 -8335EE31 D492 -8335EE32 D493 -8335EE33 D494 -8335EE34 D495 -8335EE35 D496 -8335EE36 D497 -8335EE37 D498 -8335EE38 D499 -8335EE39 D49A -8335EF30 D49B -8335EF31 D49C -8335EF32 D49D -8335EF33 D49E -8335EF34 D49F -8335EF35 D4A0 -8335EF36 D4A1 -8335EF37 D4A2 -8335EF38 D4A3 -8335EF39 D4A4 -8335F030 D4A5 -8335F031 D4A6 -8335F032 D4A7 -8335F033 D4A8 -8335F034 D4A9 -8335F035 D4AA -8335F036 D4AB -8335F037 D4AC -8335F038 D4AD -8335F039 D4AE -8335F130 D4AF -8335F131 D4B0 -8335F132 D4B1 -8335F133 D4B2 -8335F134 D4B3 -8335F135 D4B4 -8335F136 D4B5 -8335F137 D4B6 -8335F138 D4B7 -8335F139 D4B8 -8335F230 D4B9 -8335F231 D4BA -8335F232 D4BB -8335F233 D4BC -8335F234 D4BD -8335F235 D4BE -8335F236 D4BF -8335F237 D4C0 -8335F238 D4C1 -8335F239 D4C2 -8335F330 D4C3 -8335F331 D4C4 -8335F332 D4C5 -8335F333 D4C6 -8335F334 D4C7 -8335F335 D4C8 -8335F336 D4C9 -8335F337 D4CA -8335F338 D4CB -8335F339 D4CC -8335F430 D4CD -8335F431 D4CE -8335F432 D4CF -8335F433 D4D0 -8335F434 D4D1 -8335F435 D4D2 -8335F436 D4D3 -8335F437 D4D4 -8335F438 D4D5 -8335F439 D4D6 -8335F530 D4D7 -8335F531 D4D8 -8335F532 D4D9 -8335F533 D4DA -8335F534 D4DB -8335F535 D4DC -8335F536 D4DD -8335F537 D4DE -8335F538 D4DF -8335F539 D4E0 -8335F630 D4E1 -8335F631 D4E2 -8335F632 D4E3 -8335F633 D4E4 -8335F634 D4E5 -8335F635 D4E6 -8335F636 D4E7 -8335F637 D4E8 -8335F638 D4E9 -8335F639 D4EA -8335F730 D4EB -8335F731 D4EC -8335F732 D4ED -8335F733 D4EE -8335F734 D4EF -8335F735 D4F0 -8335F736 D4F1 -8335F737 D4F2 -8335F738 D4F3 -8335F739 D4F4 -8335F830 D4F5 -8335F831 D4F6 -8335F832 D4F7 -8335F833 D4F8 -8335F834 D4F9 -8335F835 D4FA -8335F836 D4FB -8335F837 D4FC -8335F838 D4FD -8335F839 D4FE -8335F930 D4FF -8335F931 D500 -8335F932 D501 -8335F933 D502 -8335F934 D503 -8335F935 D504 -8335F936 D505 -8335F937 D506 -8335F938 D507 -8335F939 D508 -8335FA30 D509 -8335FA31 D50A -8335FA32 D50B -8335FA33 D50C -8335FA34 D50D -8335FA35 D50E -8335FA36 D50F -8335FA37 D510 -8335FA38 D511 -8335FA39 D512 -8335FB30 D513 -8335FB31 D514 -8335FB32 D515 -8335FB33 D516 -8335FB34 D517 -8335FB35 D518 -8335FB36 D519 -8335FB37 D51A -8335FB38 D51B -8335FB39 D51C -8335FC30 D51D -8335FC31 D51E -8335FC32 D51F -8335FC33 D520 -8335FC34 D521 -8335FC35 D522 -8335FC36 D523 -8335FC37 D524 -8335FC38 D525 -8335FC39 D526 -8335FD30 D527 -8335FD31 D528 -8335FD32 D529 -8335FD33 D52A -8335FD34 D52B -8335FD35 D52C -8335FD36 D52D -8335FD37 D52E -8335FD38 D52F -8335FD39 D530 -8335FE30 D531 -8335FE31 D532 -8335FE32 D533 -8335FE33 D534 -8335FE34 D535 -8335FE35 D536 -8335FE36 D537 -8335FE37 D538 -8335FE38 D539 -8335FE39 D53A -83368130 D53B -83368131 D53C -83368132 D53D -83368133 D53E -83368134 D53F -83368135 D540 -83368136 D541 -83368137 D542 -83368138 D543 -83368139 D544 -83368230 D545 -83368231 D546 -83368232 D547 -83368233 D548 -83368234 D549 -83368235 D54A -83368236 D54B -83368237 D54C -83368238 D54D -83368239 D54E -83368330 D54F -83368331 D550 -83368332 D551 -83368333 D552 -83368334 D553 -83368335 D554 -83368336 D555 -83368337 D556 -83368338 D557 -83368339 D558 -83368430 D559 -83368431 D55A -83368432 D55B -83368433 D55C -83368434 D55D -83368435 D55E -83368436 D55F -83368437 D560 -83368438 D561 -83368439 D562 -83368530 D563 -83368531 D564 -83368532 D565 -83368533 D566 -83368534 D567 -83368535 D568 -83368536 D569 -83368537 D56A -83368538 D56B -83368539 D56C -83368630 D56D -83368631 D56E -83368632 D56F -83368633 D570 -83368634 D571 -83368635 D572 -83368636 D573 -83368637 D574 -83368638 D575 -83368639 D576 -83368730 D577 -83368731 D578 -83368732 D579 -83368733 D57A -83368734 D57B -83368735 D57C -83368736 D57D -83368737 D57E -83368738 D57F -83368739 D580 -83368830 D581 -83368831 D582 -83368832 D583 -83368833 D584 -83368834 D585 -83368835 D586 -83368836 D587 -83368837 D588 -83368838 D589 -83368839 D58A -83368930 D58B -83368931 D58C -83368932 D58D -83368933 D58E -83368934 D58F -83368935 D590 -83368936 D591 -83368937 D592 -83368938 D593 -83368939 D594 -83368A30 D595 -83368A31 D596 -83368A32 D597 -83368A33 D598 -83368A34 D599 -83368A35 D59A -83368A36 D59B -83368A37 D59C -83368A38 D59D -83368A39 D59E -83368B30 D59F -83368B31 D5A0 -83368B32 D5A1 -83368B33 D5A2 -83368B34 D5A3 -83368B35 D5A4 -83368B36 D5A5 -83368B37 D5A6 -83368B38 D5A7 -83368B39 D5A8 -83368C30 D5A9 -83368C31 D5AA -83368C32 D5AB -83368C33 D5AC -83368C34 D5AD -83368C35 D5AE -83368C36 D5AF -83368C37 D5B0 -83368C38 D5B1 -83368C39 D5B2 -83368D30 D5B3 -83368D31 D5B4 -83368D32 D5B5 -83368D33 D5B6 -83368D34 D5B7 -83368D35 D5B8 -83368D36 D5B9 -83368D37 D5BA -83368D38 D5BB -83368D39 D5BC -83368E30 D5BD -83368E31 D5BE -83368E32 D5BF -83368E33 D5C0 -83368E34 D5C1 -83368E35 D5C2 -83368E36 D5C3 -83368E37 D5C4 -83368E38 D5C5 -83368E39 D5C6 -83368F30 D5C7 -83368F31 D5C8 -83368F32 D5C9 -83368F33 D5CA -83368F34 D5CB -83368F35 D5CC -83368F36 D5CD -83368F37 D5CE -83368F38 D5CF -83368F39 D5D0 -83369030 D5D1 -83369031 D5D2 -83369032 D5D3 -83369033 D5D4 -83369034 D5D5 -83369035 D5D6 -83369036 D5D7 -83369037 D5D8 -83369038 D5D9 -83369039 D5DA -83369130 D5DB -83369131 D5DC -83369132 D5DD -83369133 D5DE -83369134 D5DF -83369135 D5E0 -83369136 D5E1 -83369137 D5E2 -83369138 D5E3 -83369139 D5E4 -83369230 D5E5 -83369231 D5E6 -83369232 D5E7 -83369233 D5E8 -83369234 D5E9 -83369235 D5EA -83369236 D5EB -83369237 D5EC -83369238 D5ED -83369239 D5EE -83369330 D5EF -83369331 D5F0 -83369332 D5F1 -83369333 D5F2 -83369334 D5F3 -83369335 D5F4 -83369336 D5F5 -83369337 D5F6 -83369338 D5F7 -83369339 D5F8 -83369430 D5F9 -83369431 D5FA -83369432 D5FB -83369433 D5FC -83369434 D5FD -83369435 D5FE -83369436 D5FF -83369437 D600 -83369438 D601 -83369439 D602 -83369530 D603 -83369531 D604 -83369532 D605 -83369533 D606 -83369534 D607 -83369535 D608 -83369536 D609 -83369537 D60A -83369538 D60B -83369539 D60C -83369630 D60D -83369631 D60E -83369632 D60F -83369633 D610 -83369634 D611 -83369635 D612 -83369636 D613 -83369637 D614 -83369638 D615 -83369639 D616 -83369730 D617 -83369731 D618 -83369732 D619 -83369733 D61A -83369734 D61B -83369735 D61C -83369736 D61D -83369737 D61E -83369738 D61F -83369739 D620 -83369830 D621 -83369831 D622 -83369832 D623 -83369833 D624 -83369834 D625 -83369835 D626 -83369836 D627 -83369837 D628 -83369838 D629 -83369839 D62A -83369930 D62B -83369931 D62C -83369932 D62D -83369933 D62E -83369934 D62F -83369935 D630 -83369936 D631 -83369937 D632 -83369938 D633 -83369939 D634 -83369A30 D635 -83369A31 D636 -83369A32 D637 -83369A33 D638 -83369A34 D639 -83369A35 D63A -83369A36 D63B -83369A37 D63C -83369A38 D63D -83369A39 D63E -83369B30 D63F -83369B31 D640 -83369B32 D641 -83369B33 D642 -83369B34 D643 -83369B35 D644 -83369B36 D645 -83369B37 D646 -83369B38 D647 -83369B39 D648 -83369C30 D649 -83369C31 D64A -83369C32 D64B -83369C33 D64C -83369C34 D64D -83369C35 D64E -83369C36 D64F -83369C37 D650 -83369C38 D651 -83369C39 D652 -83369D30 D653 -83369D31 D654 -83369D32 D655 -83369D33 D656 -83369D34 D657 -83369D35 D658 -83369D36 D659 -83369D37 D65A -83369D38 D65B -83369D39 D65C -83369E30 D65D -83369E31 D65E -83369E32 D65F -83369E33 D660 -83369E34 D661 -83369E35 D662 -83369E36 D663 -83369E37 D664 -83369E38 D665 -83369E39 D666 -83369F30 D667 -83369F31 D668 -83369F32 D669 -83369F33 D66A -83369F34 D66B -83369F35 D66C -83369F36 D66D -83369F37 D66E -83369F38 D66F -83369F39 D670 -8336A030 D671 -8336A031 D672 -8336A032 D673 -8336A033 D674 -8336A034 D675 -8336A035 D676 -8336A036 D677 -8336A037 D678 -8336A038 D679 -8336A039 D67A -8336A130 D67B -8336A131 D67C -8336A132 D67D -8336A133 D67E -8336A134 D67F -8336A135 D680 -8336A136 D681 -8336A137 D682 -8336A138 D683 -8336A139 D684 -8336A230 D685 -8336A231 D686 -8336A232 D687 -8336A233 D688 -8336A234 D689 -8336A235 D68A -8336A236 D68B -8336A237 D68C -8336A238 D68D -8336A239 D68E -8336A330 D68F -8336A331 D690 -8336A332 D691 -8336A333 D692 -8336A334 D693 -8336A335 D694 -8336A336 D695 -8336A337 D696 -8336A338 D697 -8336A339 D698 -8336A430 D699 -8336A431 D69A -8336A432 D69B -8336A433 D69C -8336A434 D69D -8336A435 D69E -8336A436 D69F -8336A437 D6A0 -8336A438 D6A1 -8336A439 D6A2 -8336A530 D6A3 -8336A531 D6A4 -8336A532 D6A5 -8336A533 D6A6 -8336A534 D6A7 -8336A535 D6A8 -8336A536 D6A9 -8336A537 D6AA -8336A538 D6AB -8336A539 D6AC -8336A630 D6AD -8336A631 D6AE -8336A632 D6AF -8336A633 D6B0 -8336A634 D6B1 -8336A635 D6B2 -8336A636 D6B3 -8336A637 D6B4 -8336A638 D6B5 -8336A639 D6B6 -8336A730 D6B7 -8336A731 D6B8 -8336A732 D6B9 -8336A733 D6BA -8336A734 D6BB -8336A735 D6BC -8336A736 D6BD -8336A737 D6BE -8336A738 D6BF -8336A739 D6C0 -8336A830 D6C1 -8336A831 D6C2 -8336A832 D6C3 -8336A833 D6C4 -8336A834 D6C5 -8336A835 D6C6 -8336A836 D6C7 -8336A837 D6C8 -8336A838 D6C9 -8336A839 D6CA -8336A930 D6CB -8336A931 D6CC -8336A932 D6CD -8336A933 D6CE -8336A934 D6CF -8336A935 D6D0 -8336A936 D6D1 -8336A937 D6D2 -8336A938 D6D3 -8336A939 D6D4 -8336AA30 D6D5 -8336AA31 D6D6 -8336AA32 D6D7 -8336AA33 D6D8 -8336AA34 D6D9 -8336AA35 D6DA -8336AA36 D6DB -8336AA37 D6DC -8336AA38 D6DD -8336AA39 D6DE -8336AB30 D6DF -8336AB31 D6E0 -8336AB32 D6E1 -8336AB33 D6E2 -8336AB34 D6E3 -8336AB35 D6E4 -8336AB36 D6E5 -8336AB37 D6E6 -8336AB38 D6E7 -8336AB39 D6E8 -8336AC30 D6E9 -8336AC31 D6EA -8336AC32 D6EB -8336AC33 D6EC -8336AC34 D6ED -8336AC35 D6EE -8336AC36 D6EF -8336AC37 D6F0 -8336AC38 D6F1 -8336AC39 D6F2 -8336AD30 D6F3 -8336AD31 D6F4 -8336AD32 D6F5 -8336AD33 D6F6 -8336AD34 D6F7 -8336AD35 D6F8 -8336AD36 D6F9 -8336AD37 D6FA -8336AD38 D6FB -8336AD39 D6FC -8336AE30 D6FD -8336AE31 D6FE -8336AE32 D6FF -8336AE33 D700 -8336AE34 D701 -8336AE35 D702 -8336AE36 D703 -8336AE37 D704 -8336AE38 D705 -8336AE39 D706 -8336AF30 D707 -8336AF31 D708 -8336AF32 D709 -8336AF33 D70A -8336AF34 D70B -8336AF35 D70C -8336AF36 D70D -8336AF37 D70E -8336AF38 D70F -8336AF39 D710 -8336B030 D711 -8336B031 D712 -8336B032 D713 -8336B033 D714 -8336B034 D715 -8336B035 D716 -8336B036 D717 -8336B037 D718 -8336B038 D719 -8336B039 D71A -8336B130 D71B -8336B131 D71C -8336B132 D71D -8336B133 D71E -8336B134 D71F -8336B135 D720 -8336B136 D721 -8336B137 D722 -8336B138 D723 -8336B139 D724 -8336B230 D725 -8336B231 D726 -8336B232 D727 -8336B233 D728 -8336B234 D729 -8336B235 D72A -8336B236 D72B -8336B237 D72C -8336B238 D72D -8336B239 D72E -8336B330 D72F -8336B331 D730 -8336B332 D731 -8336B333 D732 -8336B334 D733 -8336B335 D734 -8336B336 D735 -8336B337 D736 -8336B338 D737 -8336B339 D738 -8336B430 D739 -8336B431 D73A -8336B432 D73B -8336B433 D73C -8336B434 D73D -8336B435 D73E -8336B436 D73F -8336B437 D740 -8336B438 D741 -8336B439 D742 -8336B530 D743 -8336B531 D744 -8336B532 D745 -8336B533 D746 -8336B534 D747 -8336B535 D748 -8336B536 D749 -8336B537 D74A -8336B538 D74B -8336B539 D74C -8336B630 D74D -8336B631 D74E -8336B632 D74F -8336B633 D750 -8336B634 D751 -8336B635 D752 -8336B636 D753 -8336B637 D754 -8336B638 D755 -8336B639 D756 -8336B730 D757 -8336B731 D758 -8336B732 D759 -8336B733 D75A -8336B734 D75B -8336B735 D75C -8336B736 D75D -8336B737 D75E -8336B738 D75F -8336B739 D760 -8336B830 D761 -8336B831 D762 -8336B832 D763 -8336B833 D764 -8336B834 D765 -8336B835 D766 -8336B836 D767 -8336B837 D768 -8336B838 D769 -8336B839 D76A -8336B930 D76B -8336B931 D76C -8336B932 D76D -8336B933 D76E -8336B934 D76F -8336B935 D770 -8336B936 D771 -8336B937 D772 -8336B938 D773 -8336B939 D774 -8336BA30 D775 -8336BA31 D776 -8336BA32 D777 -8336BA33 D778 -8336BA34 D779 -8336BA35 D77A -8336BA36 D77B -8336BA37 D77C -8336BA38 D77D -8336BA39 D77E -8336BB30 D77F -8336BB31 D780 -8336BB32 D781 -8336BB33 D782 -8336BB34 D783 -8336BB35 D784 -8336BB36 D785 -8336BB37 D786 -8336BB38 D787 -8336BB39 D788 -8336BC30 D789 -8336BC31 D78A -8336BC32 D78B -8336BC33 D78C -8336BC34 D78D -8336BC35 D78E -8336BC36 D78F -8336BC37 D790 -8336BC38 D791 -8336BC39 D792 -8336BD30 D793 -8336BD31 D794 -8336BD32 D795 -8336BD33 D796 -8336BD34 D797 -8336BD35 D798 -8336BD36 D799 -8336BD37 D79A -8336BD38 D79B -8336BD39 D79C -8336BE30 D79D -8336BE31 D79E -8336BE32 D79F -8336BE33 D7A0 -8336BE34 D7A1 -8336BE35 D7A2 -8336BE36 D7A3 -8336BE37 D7A4 -8336BE38 D7A5 -8336BE39 D7A6 -8336BF30 D7A7 -8336BF31 D7A8 -8336BF32 D7A9 -8336BF33 D7AA -8336BF34 D7AB -8336BF35 D7AC -8336BF36 D7AD -8336BF37 D7AE -8336BF38 D7AF -8336BF39 D7B0 -8336C030 D7B1 -8336C031 D7B2 -8336C032 D7B3 -8336C033 D7B4 -8336C034 D7B5 -8336C035 D7B6 -8336C036 D7B7 -8336C037 D7B8 -8336C038 D7B9 -8336C039 D7BA -8336C130 D7BB -8336C131 D7BC -8336C132 D7BD -8336C133 D7BE -8336C134 D7BF -8336C135 D7C0 -8336C136 D7C1 -8336C137 D7C2 -8336C138 D7C3 -8336C139 D7C4 -8336C230 D7C5 -8336C231 D7C6 -8336C232 D7C7 -8336C233 D7C8 -8336C234 D7C9 -8336C235 D7CA -8336C236 D7CB -8336C237 D7CC -8336C238 D7CD -8336C239 D7CE -8336C330 D7CF -8336C331 D7D0 -8336C332 D7D1 -8336C333 D7D2 -8336C334 D7D3 -8336C335 D7D4 -8336C336 D7D5 -8336C337 D7D6 -8336C338 D7D7 -8336C339 D7D8 -8336C430 D7D9 -8336C431 D7DA -8336C432 D7DB -8336C433 D7DC -8336C434 D7DD -8336C435 D7DE -8336C436 D7DF -8336C437 D7E0 -8336C438 D7E1 -8336C439 D7E2 -8336C530 D7E3 -8336C531 D7E4 -8336C532 D7E5 -8336C533 D7E6 -8336C534 D7E7 -8336C535 D7E8 -8336C536 D7E9 -8336C537 D7EA -8336C538 D7EB -8336C539 D7EC -8336C630 D7ED -8336C631 D7EE -8336C632 D7EF -8336C633 D7F0 -8336C634 D7F1 -8336C635 D7F2 -8336C636 D7F3 -8336C637 D7F4 -8336C638 D7F5 -8336C639 D7F6 -8336C730 D7F7 -8336C731 D7F8 -8336C732 D7F9 -8336C733 D7FA -8336C734 D7FB -8336C735 D7FC -8336C736 D7FD -8336C737 D7FE -8336C738 D7FF -AAA1 E000 -AAA2 E001 -AAA3 E002 -AAA4 E003 -AAA5 E004 -AAA6 E005 -AAA7 E006 -AAA8 E007 -AAA9 E008 -AAAA E009 -AAAB E00A -AAAC E00B -AAAD E00C -AAAE E00D -AAAF E00E -AAB0 E00F -AAB1 E010 -AAB2 E011 -AAB3 E012 -AAB4 E013 -AAB5 E014 -AAB6 E015 -AAB7 E016 -AAB8 E017 -AAB9 E018 -AABA E019 -AABB E01A -AABC E01B -AABD E01C -AABE E01D -AABF E01E -AAC0 E01F -AAC1 E020 -AAC2 E021 -AAC3 E022 -AAC4 E023 -AAC5 E024 -AAC6 E025 -AAC7 E026 -AAC8 E027 -AAC9 E028 -AACA E029 -AACB E02A -AACC E02B -AACD E02C -AACE E02D -AACF E02E -AAD0 E02F -AAD1 E030 -AAD2 E031 -AAD3 E032 -AAD4 E033 -AAD5 E034 -AAD6 E035 -AAD7 E036 -AAD8 E037 -AAD9 E038 -AADA E039 -AADB E03A -AADC E03B -AADD E03C -AADE E03D -AADF E03E -AAE0 E03F -AAE1 E040 -AAE2 E041 -AAE3 E042 -AAE4 E043 -AAE5 E044 -AAE6 E045 -AAE7 E046 -AAE8 E047 -AAE9 E048 -AAEA E049 -AAEB E04A -AAEC E04B -AAED E04C -AAEE E04D -AAEF E04E -AAF0 E04F -AAF1 E050 -AAF2 E051 -AAF3 E052 -AAF4 E053 -AAF5 E054 -AAF6 E055 -AAF7 E056 -AAF8 E057 -AAF9 E058 -AAFA E059 -AAFB E05A -AAFC E05B -AAFD E05C -AAFE E05D -ABA1 E05E -ABA2 E05F -ABA3 E060 -ABA4 E061 -ABA5 E062 -ABA6 E063 -ABA7 E064 -ABA8 E065 -ABA9 E066 -ABAA E067 -ABAB E068 -ABAC E069 -ABAD E06A -ABAE E06B -ABAF E06C -ABB0 E06D -ABB1 E06E -ABB2 E06F -ABB3 E070 -ABB4 E071 -ABB5 E072 -ABB6 E073 -ABB7 E074 -ABB8 E075 -ABB9 E076 -ABBA E077 -ABBB E078 -ABBC E079 -ABBD E07A -ABBE E07B -ABBF E07C -ABC0 E07D -ABC1 E07E -ABC2 E07F -ABC3 E080 -ABC4 E081 -ABC5 E082 -ABC6 E083 -ABC7 E084 -ABC8 E085 -ABC9 E086 -ABCA E087 -ABCB E088 -ABCC E089 -ABCD E08A -ABCE E08B -ABCF E08C -ABD0 E08D -ABD1 E08E -ABD2 E08F -ABD3 E090 -ABD4 E091 -ABD5 E092 -ABD6 E093 -ABD7 E094 -ABD8 E095 -ABD9 E096 -ABDA E097 -ABDB E098 -ABDC E099 -ABDD E09A -ABDE E09B -ABDF E09C -ABE0 E09D -ABE1 E09E -ABE2 E09F -ABE3 E0A0 -ABE4 E0A1 -ABE5 E0A2 -ABE6 E0A3 -ABE7 E0A4 -ABE8 E0A5 -ABE9 E0A6 -ABEA E0A7 -ABEB E0A8 -ABEC E0A9 -ABED E0AA -ABEE E0AB -ABEF E0AC -ABF0 E0AD -ABF1 E0AE -ABF2 E0AF -ABF3 E0B0 -ABF4 E0B1 -ABF5 E0B2 -ABF6 E0B3 -ABF7 E0B4 -ABF8 E0B5 -ABF9 E0B6 -ABFA E0B7 -ABFB E0B8 -ABFC E0B9 -ABFD E0BA -ABFE E0BB -ACA1 E0BC -ACA2 E0BD -ACA3 E0BE -ACA4 E0BF -ACA5 E0C0 -ACA6 E0C1 -ACA7 E0C2 -ACA8 E0C3 -ACA9 E0C4 -ACAA E0C5 -ACAB E0C6 -ACAC E0C7 -ACAD E0C8 -ACAE E0C9 -ACAF E0CA -ACB0 E0CB -ACB1 E0CC -ACB2 E0CD -ACB3 E0CE -ACB4 E0CF -ACB5 E0D0 -ACB6 E0D1 -ACB7 E0D2 -ACB8 E0D3 -ACB9 E0D4 -ACBA E0D5 -ACBB E0D6 -ACBC E0D7 -ACBD E0D8 -ACBE E0D9 -ACBF E0DA -ACC0 E0DB -ACC1 E0DC -ACC2 E0DD -ACC3 E0DE -ACC4 E0DF -ACC5 E0E0 -ACC6 E0E1 -ACC7 E0E2 -ACC8 E0E3 -ACC9 E0E4 -ACCA E0E5 -ACCB E0E6 -ACCC E0E7 -ACCD E0E8 -ACCE E0E9 -ACCF E0EA -ACD0 E0EB -ACD1 E0EC -ACD2 E0ED -ACD3 E0EE -ACD4 E0EF -ACD5 E0F0 -ACD6 E0F1 -ACD7 E0F2 -ACD8 E0F3 -ACD9 E0F4 -ACDA E0F5 -ACDB E0F6 -ACDC E0F7 -ACDD E0F8 -ACDE E0F9 -ACDF E0FA -ACE0 E0FB -ACE1 E0FC -ACE2 E0FD -ACE3 E0FE -ACE4 E0FF -ACE5 E100 -ACE6 E101 -ACE7 E102 -ACE8 E103 -ACE9 E104 -ACEA E105 -ACEB E106 -ACEC E107 -ACED E108 -ACEE E109 -ACEF E10A -ACF0 E10B -ACF1 E10C -ACF2 E10D -ACF3 E10E -ACF4 E10F -ACF5 E110 -ACF6 E111 -ACF7 E112 -ACF8 E113 -ACF9 E114 -ACFA E115 -ACFB E116 -ACFC E117 -ACFD E118 -ACFE E119 -ADA1 E11A -ADA2 E11B -ADA3 E11C -ADA4 E11D -ADA5 E11E -ADA6 E11F -ADA7 E120 -ADA8 E121 -ADA9 E122 -ADAA E123 -ADAB E124 -ADAC E125 -ADAD E126 -ADAE E127 -ADAF E128 -ADB0 E129 -ADB1 E12A -ADB2 E12B -ADB3 E12C -ADB4 E12D -ADB5 E12E -ADB6 E12F -ADB7 E130 -ADB8 E131 -ADB9 E132 -ADBA E133 -ADBB E134 -ADBC E135 -ADBD E136 -ADBE E137 -ADBF E138 -ADC0 E139 -ADC1 E13A -ADC2 E13B -ADC3 E13C -ADC4 E13D -ADC5 E13E -ADC6 E13F -ADC7 E140 -ADC8 E141 -ADC9 E142 -ADCA E143 -ADCB E144 -ADCC E145 -ADCD E146 -ADCE E147 -ADCF E148 -ADD0 E149 -ADD1 E14A -ADD2 E14B -ADD3 E14C -ADD4 E14D -ADD5 E14E -ADD6 E14F -ADD7 E150 -ADD8 E151 -ADD9 E152 -ADDA E153 -ADDB E154 -ADDC E155 -ADDD E156 -ADDE E157 -ADDF E158 -ADE0 E159 -ADE1 E15A -ADE2 E15B -ADE3 E15C -ADE4 E15D -ADE5 E15E -ADE6 E15F -ADE7 E160 -ADE8 E161 -ADE9 E162 -ADEA E163 -ADEB E164 -ADEC E165 -ADED E166 -ADEE E167 -ADEF E168 -ADF0 E169 -ADF1 E16A -ADF2 E16B -ADF3 E16C -ADF4 E16D -ADF5 E16E -ADF6 E16F -ADF7 E170 -ADF8 E171 -ADF9 E172 -ADFA E173 -ADFB E174 -ADFC E175 -ADFD E176 -ADFE E177 -AEA1 E178 -AEA2 E179 -AEA3 E17A -AEA4 E17B -AEA5 E17C -AEA6 E17D -AEA7 E17E -AEA8 E17F -AEA9 E180 -AEAA E181 -AEAB E182 -AEAC E183 -AEAD E184 -AEAE E185 -AEAF E186 -AEB0 E187 -AEB1 E188 -AEB2 E189 -AEB3 E18A -AEB4 E18B -AEB5 E18C -AEB6 E18D -AEB7 E18E -AEB8 E18F -AEB9 E190 -AEBA E191 -AEBB E192 -AEBC E193 -AEBD E194 -AEBE E195 -AEBF E196 -AEC0 E197 -AEC1 E198 -AEC2 E199 -AEC3 E19A -AEC4 E19B -AEC5 E19C -AEC6 E19D -AEC7 E19E -AEC8 E19F -AEC9 E1A0 -AECA E1A1 -AECB E1A2 -AECC E1A3 -AECD E1A4 -AECE E1A5 -AECF E1A6 -AED0 E1A7 -AED1 E1A8 -AED2 E1A9 -AED3 E1AA -AED4 E1AB -AED5 E1AC -AED6 E1AD -AED7 E1AE -AED8 E1AF -AED9 E1B0 -AEDA E1B1 -AEDB E1B2 -AEDC E1B3 -AEDD E1B4 -AEDE E1B5 -AEDF E1B6 -AEE0 E1B7 -AEE1 E1B8 -AEE2 E1B9 -AEE3 E1BA -AEE4 E1BB -AEE5 E1BC -AEE6 E1BD -AEE7 E1BE -AEE8 E1BF -AEE9 E1C0 -AEEA E1C1 -AEEB E1C2 -AEEC E1C3 -AEED E1C4 -AEEE E1C5 -AEEF E1C6 -AEF0 E1C7 -AEF1 E1C8 -AEF2 E1C9 -AEF3 E1CA -AEF4 E1CB -AEF5 E1CC -AEF6 E1CD -AEF7 E1CE -AEF8 E1CF -AEF9 E1D0 -AEFA E1D1 -AEFB E1D2 -AEFC E1D3 -AEFD E1D4 -AEFE E1D5 -AFA1 E1D6 -AFA2 E1D7 -AFA3 E1D8 -AFA4 E1D9 -AFA5 E1DA -AFA6 E1DB -AFA7 E1DC -AFA8 E1DD -AFA9 E1DE -AFAA E1DF -AFAB E1E0 -AFAC E1E1 -AFAD E1E2 -AFAE E1E3 -AFAF E1E4 -AFB0 E1E5 -AFB1 E1E6 -AFB2 E1E7 -AFB3 E1E8 -AFB4 E1E9 -AFB5 E1EA -AFB6 E1EB -AFB7 E1EC -AFB8 E1ED -AFB9 E1EE -AFBA E1EF -AFBB E1F0 -AFBC E1F1 -AFBD E1F2 -AFBE E1F3 -AFBF E1F4 -AFC0 E1F5 -AFC1 E1F6 -AFC2 E1F7 -AFC3 E1F8 -AFC4 E1F9 -AFC5 E1FA -AFC6 E1FB -AFC7 E1FC -AFC8 E1FD -AFC9 E1FE -AFCA E1FF -AFCB E200 -AFCC E201 -AFCD E202 -AFCE E203 -AFCF E204 -AFD0 E205 -AFD1 E206 -AFD2 E207 -AFD3 E208 -AFD4 E209 -AFD5 E20A -AFD6 E20B -AFD7 E20C -AFD8 E20D -AFD9 E20E -AFDA E20F -AFDB E210 -AFDC E211 -AFDD E212 -AFDE E213 -AFDF E214 -AFE0 E215 -AFE1 E216 -AFE2 E217 -AFE3 E218 -AFE4 E219 -AFE5 E21A -AFE6 E21B -AFE7 E21C -AFE8 E21D -AFE9 E21E -AFEA E21F -AFEB E220 -AFEC E221 -AFED E222 -AFEE E223 -AFEF E224 -AFF0 E225 -AFF1 E226 -AFF2 E227 -AFF3 E228 -AFF4 E229 -AFF5 E22A -AFF6 E22B -AFF7 E22C -AFF8 E22D -AFF9 E22E -AFFA E22F -AFFB E230 -AFFC E231 -AFFD E232 -AFFE E233 -F8A1 E234 -F8A2 E235 -F8A3 E236 -F8A4 E237 -F8A5 E238 -F8A6 E239 -F8A7 E23A -F8A8 E23B -F8A9 E23C -F8AA E23D -F8AB E23E -F8AC E23F -F8AD E240 -F8AE E241 -F8AF E242 -F8B0 E243 -F8B1 E244 -F8B2 E245 -F8B3 E246 -F8B4 E247 -F8B5 E248 -F8B6 E249 -F8B7 E24A -F8B8 E24B -F8B9 E24C -F8BA E24D -F8BB E24E -F8BC E24F -F8BD E250 -F8BE E251 -F8BF E252 -F8C0 E253 -F8C1 E254 -F8C2 E255 -F8C3 E256 -F8C4 E257 -F8C5 E258 -F8C6 E259 -F8C7 E25A -F8C8 E25B -F8C9 E25C -F8CA E25D -F8CB E25E -F8CC E25F -F8CD E260 -F8CE E261 -F8CF E262 -F8D0 E263 -F8D1 E264 -F8D2 E265 -F8D3 E266 -F8D4 E267 -F8D5 E268 -F8D6 E269 -F8D7 E26A -F8D8 E26B -F8D9 E26C -F8DA E26D -F8DB E26E -F8DC E26F -F8DD E270 -F8DE E271 -F8DF E272 -F8E0 E273 -F8E1 E274 -F8E2 E275 -F8E3 E276 -F8E4 E277 -F8E5 E278 -F8E6 E279 -F8E7 E27A -F8E8 E27B -F8E9 E27C -F8EA E27D -F8EB E27E -F8EC E27F -F8ED E280 -F8EE E281 -F8EF E282 -F8F0 E283 -F8F1 E284 -F8F2 E285 -F8F3 E286 -F8F4 E287 -F8F5 E288 -F8F6 E289 -F8F7 E28A -F8F8 E28B -F8F9 E28C -F8FA E28D -F8FB E28E -F8FC E28F -F8FD E290 -F8FE E291 -F9A1 E292 -F9A2 E293 -F9A3 E294 -F9A4 E295 -F9A5 E296 -F9A6 E297 -F9A7 E298 -F9A8 E299 -F9A9 E29A -F9AA E29B -F9AB E29C -F9AC E29D -F9AD E29E -F9AE E29F -F9AF E2A0 -F9B0 E2A1 -F9B1 E2A2 -F9B2 E2A3 -F9B3 E2A4 -F9B4 E2A5 -F9B5 E2A6 -F9B6 E2A7 -F9B7 E2A8 -F9B8 E2A9 -F9B9 E2AA -F9BA E2AB -F9BB E2AC -F9BC E2AD -F9BD E2AE -F9BE E2AF -F9BF E2B0 -F9C0 E2B1 -F9C1 E2B2 -F9C2 E2B3 -F9C3 E2B4 -F9C4 E2B5 -F9C5 E2B6 -F9C6 E2B7 -F9C7 E2B8 -F9C8 E2B9 -F9C9 E2BA -F9CA E2BB -F9CB E2BC -F9CC E2BD -F9CD E2BE -F9CE E2BF -F9CF E2C0 -F9D0 E2C1 -F9D1 E2C2 -F9D2 E2C3 -F9D3 E2C4 -F9D4 E2C5 -F9D5 E2C6 -F9D6 E2C7 -F9D7 E2C8 -F9D8 E2C9 -F9D9 E2CA -F9DA E2CB -F9DB E2CC -F9DC E2CD -F9DD E2CE -F9DE E2CF -F9DF E2D0 -F9E0 E2D1 -F9E1 E2D2 -F9E2 E2D3 -F9E3 E2D4 -F9E4 E2D5 -F9E5 E2D6 -F9E6 E2D7 -F9E7 E2D8 -F9E8 E2D9 -F9E9 E2DA -F9EA E2DB -F9EB E2DC -F9EC E2DD -F9ED E2DE -F9EE E2DF -F9EF E2E0 -F9F0 E2E1 -F9F1 E2E2 -F9F2 E2E3 -F9F3 E2E4 -F9F4 E2E5 -F9F5 E2E6 -F9F6 E2E7 -F9F7 E2E8 -F9F8 E2E9 -F9F9 E2EA -F9FA E2EB -F9FB E2EC -F9FC E2ED -F9FD E2EE -F9FE E2EF -FAA1 E2F0 -FAA2 E2F1 -FAA3 E2F2 -FAA4 E2F3 -FAA5 E2F4 -FAA6 E2F5 -FAA7 E2F6 -FAA8 E2F7 -FAA9 E2F8 -FAAA E2F9 -FAAB E2FA -FAAC E2FB -FAAD E2FC -FAAE E2FD -FAAF E2FE -FAB0 E2FF -FAB1 E300 -FAB2 E301 -FAB3 E302 -FAB4 E303 -FAB5 E304 -FAB6 E305 -FAB7 E306 -FAB8 E307 -FAB9 E308 -FABA E309 -FABB E30A -FABC E30B -FABD E30C -FABE E30D -FABF E30E -FAC0 E30F -FAC1 E310 -FAC2 E311 -FAC3 E312 -FAC4 E313 -FAC5 E314 -FAC6 E315 -FAC7 E316 -FAC8 E317 -FAC9 E318 -FACA E319 -FACB E31A -FACC E31B -FACD E31C -FACE E31D -FACF E31E -FAD0 E31F -FAD1 E320 -FAD2 E321 -FAD3 E322 -FAD4 E323 -FAD5 E324 -FAD6 E325 -FAD7 E326 -FAD8 E327 -FAD9 E328 -FADA E329 -FADB E32A -FADC E32B -FADD E32C -FADE E32D -FADF E32E -FAE0 E32F -FAE1 E330 -FAE2 E331 -FAE3 E332 -FAE4 E333 -FAE5 E334 -FAE6 E335 -FAE7 E336 -FAE8 E337 -FAE9 E338 -FAEA E339 -FAEB E33A -FAEC E33B -FAED E33C -FAEE E33D -FAEF E33E -FAF0 E33F -FAF1 E340 -FAF2 E341 -FAF3 E342 -FAF4 E343 -FAF5 E344 -FAF6 E345 -FAF7 E346 -FAF8 E347 -FAF9 E348 -FAFA E349 -FAFB E34A -FAFC E34B -FAFD E34C -FAFE E34D -FBA1 E34E -FBA2 E34F -FBA3 E350 -FBA4 E351 -FBA5 E352 -FBA6 E353 -FBA7 E354 -FBA8 E355 -FBA9 E356 -FBAA E357 -FBAB E358 -FBAC E359 -FBAD E35A -FBAE E35B -FBAF E35C -FBB0 E35D -FBB1 E35E -FBB2 E35F -FBB3 E360 -FBB4 E361 -FBB5 E362 -FBB6 E363 -FBB7 E364 -FBB8 E365 -FBB9 E366 -FBBA E367 -FBBB E368 -FBBC E369 -FBBD E36A -FBBE E36B -FBBF E36C -FBC0 E36D -FBC1 E36E -FBC2 E36F -FBC3 E370 -FBC4 E371 -FBC5 E372 -FBC6 E373 -FBC7 E374 -FBC8 E375 -FBC9 E376 -FBCA E377 -FBCB E378 -FBCC E379 -FBCD E37A -FBCE E37B -FBCF E37C -FBD0 E37D -FBD1 E37E -FBD2 E37F -FBD3 E380 -FBD4 E381 -FBD5 E382 -FBD6 E383 -FBD7 E384 -FBD8 E385 -FBD9 E386 -FBDA E387 -FBDB E388 -FBDC E389 -FBDD E38A -FBDE E38B -FBDF E38C -FBE0 E38D -FBE1 E38E -FBE2 E38F -FBE3 E390 -FBE4 E391 -FBE5 E392 -FBE6 E393 -FBE7 E394 -FBE8 E395 -FBE9 E396 -FBEA E397 -FBEB E398 -FBEC E399 -FBED E39A -FBEE E39B -FBEF E39C -FBF0 E39D -FBF1 E39E -FBF2 E39F -FBF3 E3A0 -FBF4 E3A1 -FBF5 E3A2 -FBF6 E3A3 -FBF7 E3A4 -FBF8 E3A5 -FBF9 E3A6 -FBFA E3A7 -FBFB E3A8 -FBFC E3A9 -FBFD E3AA -FBFE E3AB -FCA1 E3AC -FCA2 E3AD -FCA3 E3AE -FCA4 E3AF -FCA5 E3B0 -FCA6 E3B1 -FCA7 E3B2 -FCA8 E3B3 -FCA9 E3B4 -FCAA E3B5 -FCAB E3B6 -FCAC E3B7 -FCAD E3B8 -FCAE E3B9 -FCAF E3BA -FCB0 E3BB -FCB1 E3BC -FCB2 E3BD -FCB3 E3BE -FCB4 E3BF -FCB5 E3C0 -FCB6 E3C1 -FCB7 E3C2 -FCB8 E3C3 -FCB9 E3C4 -FCBA E3C5 -FCBB E3C6 -FCBC E3C7 -FCBD E3C8 -FCBE E3C9 -FCBF E3CA -FCC0 E3CB -FCC1 E3CC -FCC2 E3CD -FCC3 E3CE -FCC4 E3CF -FCC5 E3D0 -FCC6 E3D1 -FCC7 E3D2 -FCC8 E3D3 -FCC9 E3D4 -FCCA E3D5 -FCCB E3D6 -FCCC E3D7 -FCCD E3D8 -FCCE E3D9 -FCCF E3DA -FCD0 E3DB -FCD1 E3DC -FCD2 E3DD -FCD3 E3DE -FCD4 E3DF -FCD5 E3E0 -FCD6 E3E1 -FCD7 E3E2 -FCD8 E3E3 -FCD9 E3E4 -FCDA E3E5 -FCDB E3E6 -FCDC E3E7 -FCDD E3E8 -FCDE E3E9 -FCDF E3EA -FCE0 E3EB -FCE1 E3EC -FCE2 E3ED -FCE3 E3EE -FCE4 E3EF -FCE5 E3F0 -FCE6 E3F1 -FCE7 E3F2 -FCE8 E3F3 -FCE9 E3F4 -FCEA E3F5 -FCEB E3F6 -FCEC E3F7 -FCED E3F8 -FCEE E3F9 -FCEF E3FA -FCF0 E3FB -FCF1 E3FC -FCF2 E3FD -FCF3 E3FE -FCF4 E3FF -FCF5 E400 -FCF6 E401 -FCF7 E402 -FCF8 E403 -FCF9 E404 -FCFA E405 -FCFB E406 -FCFC E407 -FCFD E408 -FCFE E409 -FDA1 E40A -FDA2 E40B -FDA3 E40C -FDA4 E40D -FDA5 E40E -FDA6 E40F -FDA7 E410 -FDA8 E411 -FDA9 E412 -FDAA E413 -FDAB E414 -FDAC E415 -FDAD E416 -FDAE E417 -FDAF E418 -FDB0 E419 -FDB1 E41A -FDB2 E41B -FDB3 E41C -FDB4 E41D -FDB5 E41E -FDB6 E41F -FDB7 E420 -FDB8 E421 -FDB9 E422 -FDBA E423 -FDBB E424 -FDBC E425 -FDBD E426 -FDBE E427 -FDBF E428 -FDC0 E429 -FDC1 E42A -FDC2 E42B -FDC3 E42C -FDC4 E42D -FDC5 E42E -FDC6 E42F -FDC7 E430 -FDC8 E431 -FDC9 E432 -FDCA E433 -FDCB E434 -FDCC E435 -FDCD E436 -FDCE E437 -FDCF E438 -FDD0 E439 -FDD1 E43A -FDD2 E43B -FDD3 E43C -FDD4 E43D -FDD5 E43E -FDD6 E43F -FDD7 E440 -FDD8 E441 -FDD9 E442 -FDDA E443 -FDDB E444 -FDDC E445 -FDDD E446 -FDDE E447 -FDDF E448 -FDE0 E449 -FDE1 E44A -FDE2 E44B -FDE3 E44C -FDE4 E44D -FDE5 E44E -FDE6 E44F -FDE7 E450 -FDE8 E451 -FDE9 E452 -FDEA E453 -FDEB E454 -FDEC E455 -FDED E456 -FDEE E457 -FDEF E458 -FDF0 E459 -FDF1 E45A -FDF2 E45B -FDF3 E45C -FDF4 E45D -FDF5 E45E -FDF6 E45F -FDF7 E460 -FDF8 E461 -FDF9 E462 -FDFA E463 -FDFB E464 -FDFC E465 -FDFD E466 -FDFE E467 -FEA1 E468 -FEA2 E469 -FEA3 E46A -FEA4 E46B -FEA5 E46C -FEA6 E46D -FEA7 E46E -FEA8 E46F -FEA9 E470 -FEAA E471 -FEAB E472 -FEAC E473 -FEAD E474 -FEAE E475 -FEAF E476 -FEB0 E477 -FEB1 E478 -FEB2 E479 -FEB3 E47A -FEB4 E47B -FEB5 E47C -FEB6 E47D -FEB7 E47E -FEB8 E47F -FEB9 E480 -FEBA E481 -FEBB E482 -FEBC E483 -FEBD E484 -FEBE E485 -FEBF E486 -FEC0 E487 -FEC1 E488 -FEC2 E489 -FEC3 E48A -FEC4 E48B -FEC5 E48C -FEC6 E48D -FEC7 E48E -FEC8 E48F -FEC9 E490 -FECA E491 -FECB E492 -FECC E493 -FECD E494 -FECE E495 -FECF E496 -FED0 E497 -FED1 E498 -FED2 E499 -FED3 E49A -FED4 E49B -FED5 E49C -FED6 E49D -FED7 E49E -FED8 E49F -FED9 E4A0 -FEDA E4A1 -FEDB E4A2 -FEDC E4A3 -FEDD E4A4 -FEDE E4A5 -FEDF E4A6 -FEE0 E4A7 -FEE1 E4A8 -FEE2 E4A9 -FEE3 E4AA -FEE4 E4AB -FEE5 E4AC -FEE6 E4AD -FEE7 E4AE -FEE8 E4AF -FEE9 E4B0 -FEEA E4B1 -FEEB E4B2 -FEEC E4B3 -FEED E4B4 -FEEE E4B5 -FEEF E4B6 -FEF0 E4B7 -FEF1 E4B8 -FEF2 E4B9 -FEF3 E4BA -FEF4 E4BB -FEF5 E4BC -FEF6 E4BD -FEF7 E4BE -FEF8 E4BF -FEF9 E4C0 -FEFA E4C1 -FEFB E4C2 -FEFC E4C3 -FEFD E4C4 -FEFE E4C5 -A140 E4C6 -A141 E4C7 -A142 E4C8 -A143 E4C9 -A144 E4CA -A145 E4CB -A146 E4CC -A147 E4CD -A148 E4CE -A149 E4CF -A14A E4D0 -A14B E4D1 -A14C E4D2 -A14D E4D3 -A14E E4D4 -A14F E4D5 -A150 E4D6 -A151 E4D7 -A152 E4D8 -A153 E4D9 -A154 E4DA -A155 E4DB -A156 E4DC -A157 E4DD -A158 E4DE -A159 E4DF -A15A E4E0 -A15B E4E1 -A15C E4E2 -A15D E4E3 -A15E E4E4 -A15F E4E5 -A160 E4E6 -A161 E4E7 -A162 E4E8 -A163 E4E9 -A164 E4EA -A165 E4EB -A166 E4EC -A167 E4ED -A168 E4EE -A169 E4EF -A16A E4F0 -A16B E4F1 -A16C E4F2 -A16D E4F3 -A16E E4F4 -A16F E4F5 -A170 E4F6 -A171 E4F7 -A172 E4F8 -A173 E4F9 -A174 E4FA -A175 E4FB -A176 E4FC -A177 E4FD -A178 E4FE -A179 E4FF -A17A E500 -A17B E501 -A17C E502 -A17D E503 -A17E E504 -A180 E505 -A181 E506 -A182 E507 -A183 E508 -A184 E509 -A185 E50A -A186 E50B -A187 E50C -A188 E50D -A189 E50E -A18A E50F -A18B E510 -A18C E511 -A18D E512 -A18E E513 -A18F E514 -A190 E515 -A191 E516 -A192 E517 -A193 E518 -A194 E519 -A195 E51A -A196 E51B -A197 E51C -A198 E51D -A199 E51E -A19A E51F -A19B E520 -A19C E521 -A19D E522 -A19E E523 -A19F E524 -A1A0 E525 -A240 E526 -A241 E527 -A242 E528 -A243 E529 -A244 E52A -A245 E52B -A246 E52C -A247 E52D -A248 E52E -A249 E52F -A24A E530 -A24B E531 -A24C E532 -A24D E533 -A24E E534 -A24F E535 -A250 E536 -A251 E537 -A252 E538 -A253 E539 -A254 E53A -A255 E53B -A256 E53C -A257 E53D -A258 E53E -A259 E53F -A25A E540 -A25B E541 -A25C E542 -A25D E543 -A25E E544 -A25F E545 -A260 E546 -A261 E547 -A262 E548 -A263 E549 -A264 E54A -A265 E54B -A266 E54C -A267 E54D -A268 E54E -A269 E54F -A26A E550 -A26B E551 -A26C E552 -A26D E553 -A26E E554 -A26F E555 -A270 E556 -A271 E557 -A272 E558 -A273 E559 -A274 E55A -A275 E55B -A276 E55C -A277 E55D -A278 E55E -A279 E55F -A27A E560 -A27B E561 -A27C E562 -A27D E563 -A27E E564 -A280 E565 -A281 E566 -A282 E567 -A283 E568 -A284 E569 -A285 E56A -A286 E56B -A287 E56C -A288 E56D -A289 E56E -A28A E56F -A28B E570 -A28C E571 -A28D E572 -A28E E573 -A28F E574 -A290 E575 -A291 E576 -A292 E577 -A293 E578 -A294 E579 -A295 E57A -A296 E57B -A297 E57C -A298 E57D -A299 E57E -A29A E57F -A29B E580 -A29C E581 -A29D E582 -A29E E583 -A29F E584 -A2A0 E585 -A340 E586 -A341 E587 -A342 E588 -A343 E589 -A344 E58A -A345 E58B -A346 E58C -A347 E58D -A348 E58E -A349 E58F -A34A E590 -A34B E591 -A34C E592 -A34D E593 -A34E E594 -A34F E595 -A350 E596 -A351 E597 -A352 E598 -A353 E599 -A354 E59A -A355 E59B -A356 E59C -A357 E59D -A358 E59E -A359 E59F -A35A E5A0 -A35B E5A1 -A35C E5A2 -A35D E5A3 -A35E E5A4 -A35F E5A5 -A360 E5A6 -A361 E5A7 -A362 E5A8 -A363 E5A9 -A364 E5AA -A365 E5AB -A366 E5AC -A367 E5AD -A368 E5AE -A369 E5AF -A36A E5B0 -A36B E5B1 -A36C E5B2 -A36D E5B3 -A36E E5B4 -A36F E5B5 -A370 E5B6 -A371 E5B7 -A372 E5B8 -A373 E5B9 -A374 E5BA -A375 E5BB -A376 E5BC -A377 E5BD -A378 E5BE -A379 E5BF -A37A E5C0 -A37B E5C1 -A37C E5C2 -A37D E5C3 -A37E E5C4 -A380 E5C5 -A381 E5C6 -A382 E5C7 -A383 E5C8 -A384 E5C9 -A385 E5CA -A386 E5CB -A387 E5CC -A388 E5CD -A389 E5CE -A38A E5CF -A38B E5D0 -A38C E5D1 -A38D E5D2 -A38E E5D3 -A38F E5D4 -A390 E5D5 -A391 E5D6 -A392 E5D7 -A393 E5D8 -A394 E5D9 -A395 E5DA -A396 E5DB -A397 E5DC -A398 E5DD -A399 E5DE -A39A E5DF -A39B E5E0 -A39C E5E1 -A39D E5E2 -A39E E5E3 -A39F E5E4 -A3A0 E5E5 -A440 E5E6 -A441 E5E7 -A442 E5E8 -A443 E5E9 -A444 E5EA -A445 E5EB -A446 E5EC -A447 E5ED -A448 E5EE -A449 E5EF -A44A E5F0 -A44B E5F1 -A44C E5F2 -A44D E5F3 -A44E E5F4 -A44F E5F5 -A450 E5F6 -A451 E5F7 -A452 E5F8 -A453 E5F9 -A454 E5FA -A455 E5FB -A456 E5FC -A457 E5FD -A458 E5FE -A459 E5FF -A45A E600 -A45B E601 -A45C E602 -A45D E603 -A45E E604 -A45F E605 -A460 E606 -A461 E607 -A462 E608 -A463 E609 -A464 E60A -A465 E60B -A466 E60C -A467 E60D -A468 E60E -A469 E60F -A46A E610 -A46B E611 -A46C E612 -A46D E613 -A46E E614 -A46F E615 -A470 E616 -A471 E617 -A472 E618 -A473 E619 -A474 E61A -A475 E61B -A476 E61C -A477 E61D -A478 E61E -A479 E61F -A47A E620 -A47B E621 -A47C E622 -A47D E623 -A47E E624 -A480 E625 -A481 E626 -A482 E627 -A483 E628 -A484 E629 -A485 E62A -A486 E62B -A487 E62C -A488 E62D -A489 E62E -A48A E62F -A48B E630 -A48C E631 -A48D E632 -A48E E633 -A48F E634 -A490 E635 -A491 E636 -A492 E637 -A493 E638 -A494 E639 -A495 E63A -A496 E63B -A497 E63C -A498 E63D -A499 E63E -A49A E63F -A49B E640 -A49C E641 -A49D E642 -A49E E643 -A49F E644 -A4A0 E645 -A540 E646 -A541 E647 -A542 E648 -A543 E649 -A544 E64A -A545 E64B -A546 E64C -A547 E64D -A548 E64E -A549 E64F -A54A E650 -A54B E651 -A54C E652 -A54D E653 -A54E E654 -A54F E655 -A550 E656 -A551 E657 -A552 E658 -A553 E659 -A554 E65A -A555 E65B -A556 E65C -A557 E65D -A558 E65E -A559 E65F -A55A E660 -A55B E661 -A55C E662 -A55D E663 -A55E E664 -A55F E665 -A560 E666 -A561 E667 -A562 E668 -A563 E669 -A564 E66A -A565 E66B -A566 E66C -A567 E66D -A568 E66E -A569 E66F -A56A E670 -A56B E671 -A56C E672 -A56D E673 -A56E E674 -A56F E675 -A570 E676 -A571 E677 -A572 E678 -A573 E679 -A574 E67A -A575 E67B -A576 E67C -A577 E67D -A578 E67E -A579 E67F -A57A E680 -A57B E681 -A57C E682 -A57D E683 -A57E E684 -A580 E685 -A581 E686 -A582 E687 -A583 E688 -A584 E689 -A585 E68A -A586 E68B -A587 E68C -A588 E68D -A589 E68E -A58A E68F -A58B E690 -A58C E691 -A58D E692 -A58E E693 -A58F E694 -A590 E695 -A591 E696 -A592 E697 -A593 E698 -A594 E699 -A595 E69A -A596 E69B -A597 E69C -A598 E69D -A599 E69E -A59A E69F -A59B E6A0 -A59C E6A1 -A59D E6A2 -A59E E6A3 -A59F E6A4 -A5A0 E6A5 -A640 E6A6 -A641 E6A7 -A642 E6A8 -A643 E6A9 -A644 E6AA -A645 E6AB -A646 E6AC -A647 E6AD -A648 E6AE -A649 E6AF -A64A E6B0 -A64B E6B1 -A64C E6B2 -A64D E6B3 -A64E E6B4 -A64F E6B5 -A650 E6B6 -A651 E6B7 -A652 E6B8 -A653 E6B9 -A654 E6BA -A655 E6BB -A656 E6BC -A657 E6BD -A658 E6BE -A659 E6BF -A65A E6C0 -A65B E6C1 -A65C E6C2 -A65D E6C3 -A65E E6C4 -A65F E6C5 -A660 E6C6 -A661 E6C7 -A662 E6C8 -A663 E6C9 -A664 E6CA -A665 E6CB -A666 E6CC -A667 E6CD -A668 E6CE -A669 E6CF -A66A E6D0 -A66B E6D1 -A66C E6D2 -A66D E6D3 -A66E E6D4 -A66F E6D5 -A670 E6D6 -A671 E6D7 -A672 E6D8 -A673 E6D9 -A674 E6DA -A675 E6DB -A676 E6DC -A677 E6DD -A678 E6DE -A679 E6DF -A67A E6E0 -A67B E6E1 -A67C E6E2 -A67D E6E3 -A67E E6E4 -A680 E6E5 -A681 E6E6 -A682 E6E7 -A683 E6E8 -A684 E6E9 -A685 E6EA -A686 E6EB -A687 E6EC -A688 E6ED -A689 E6EE -A68A E6EF -A68B E6F0 -A68C E6F1 -A68D E6F2 -A68E E6F3 -A68F E6F4 -A690 E6F5 -A691 E6F6 -A692 E6F7 -A693 E6F8 -A694 E6F9 -A695 E6FA -A696 E6FB -A697 E6FC -A698 E6FD -A699 E6FE -A69A E6FF -A69B E700 -A69C E701 -A69D E702 -A69E E703 -A69F E704 -A6A0 E705 -A740 E706 -A741 E707 -A742 E708 -A743 E709 -A744 E70A -A745 E70B -A746 E70C -A747 E70D -A748 E70E -A749 E70F -A74A E710 -A74B E711 -A74C E712 -A74D E713 -A74E E714 -A74F E715 -A750 E716 -A751 E717 -A752 E718 -A753 E719 -A754 E71A -A755 E71B -A756 E71C -A757 E71D -A758 E71E -A759 E71F -A75A E720 -A75B E721 -A75C E722 -A75D E723 -A75E E724 -A75F E725 -A760 E726 -A761 E727 -A762 E728 -A763 E729 -A764 E72A -A765 E72B -A766 E72C -A767 E72D -A768 E72E -A769 E72F -A76A E730 -A76B E731 -A76C E732 -A76D E733 -A76E E734 -A76F E735 -A770 E736 -A771 E737 -A772 E738 -A773 E739 -A774 E73A -A775 E73B -A776 E73C -A777 E73D -A778 E73E -A779 E73F -A77A E740 -A77B E741 -A77C E742 -A77D E743 -A77E E744 -A780 E745 -A781 E746 -A782 E747 -A783 E748 -A784 E749 -A785 E74A -A786 E74B -A787 E74C -A788 E74D -A789 E74E -A78A E74F -A78B E750 -A78C E751 -A78D E752 -A78E E753 -A78F E754 -A790 E755 -A791 E756 -A792 E757 -A793 E758 -A794 E759 -A795 E75A -A796 E75B -A797 E75C -A798 E75D -A799 E75E -A79A E75F -A79B E760 -A79C E761 -A79D E762 -A79E E763 -A79F E764 -A7A0 E765 -A2AB E766 -A2AC E767 -A2AD E768 -A2AE E769 -A2AF E76A -A2B0 E76B -8336C739 E76C -A2E4 E76D -A2EF E76E -A2F0 E76F -A2FD E770 -A2FE E771 -A4F4 E772 -A4F5 E773 -A4F6 E774 -A4F7 E775 -A4F8 E776 -A4F9 E777 -A4FA E778 -A4FB E779 -A4FC E77A -A4FD E77B -A4FE E77C -A5F7 E77D -A5F8 E77E -A5F9 E77F -A5FA E780 -A5FB E781 -A5FC E782 -A5FD E783 -A5FE E784 -A6B9 E785 -A6BA E786 -A6BB E787 -A6BC E788 -A6BD E789 -A6BE E78A -A6BF E78B -A6C0 E78C -A6D9 E78D -A6DA E78E -A6DB E78F -A6DC E790 -A6DD E791 -A6DE E792 -A6DF E793 -A6EC E794 -A6ED E795 -A6F3 E796 -A6F6 E797 -A6F7 E798 -A6F8 E799 -A6F9 E79A -A6FA E79B -A6FB E79C -A6FC E79D -A6FD E79E -A6FE E79F -A7C2 E7A0 -A7C3 E7A1 -A7C4 E7A2 -A7C5 E7A3 -A7C6 E7A4 -A7C7 E7A5 -A7C8 E7A6 -A7C9 E7A7 -A7CA E7A8 -A7CB E7A9 -A7CC E7AA -A7CD E7AB -A7CE E7AC -A7CF E7AD -A7D0 E7AE -A7F2 E7AF -A7F3 E7B0 -A7F4 E7B1 -A7F5 E7B2 -A7F6 E7B3 -A7F7 E7B4 -A7F8 E7B5 -A7F9 E7B6 -A7FA E7B7 -A7FB E7B8 -A7FC E7B9 -A7FD E7BA -A7FE E7BB -A896 E7BC -A897 E7BD -A898 E7BE -A899 E7BF -A89A E7C0 -A89B E7C1 -A89C E7C2 -A89D E7C3 -A89E E7C4 -A89F E7C5 -A8A0 E7C6 -A8BC E7C7 -8336C830 E7C8 -A8C1 E7C9 -A8C2 E7CA -A8C3 E7CB -A8C4 E7CC -A8EA E7CD -A8EB E7CE -A8EC E7CF -A8ED E7D0 -A8EE E7D1 -A8EF E7D2 -A8F0 E7D3 -A8F1 E7D4 -A8F2 E7D5 -A8F3 E7D6 -A8F4 E7D7 -A8F5 E7D8 -A8F6 E7D9 -A8F7 E7DA -A8F8 E7DB -A8F9 E7DC -A8FA E7DD -A8FB E7DE -A8FC E7DF -A8FD E7E0 -A8FE E7E1 -A958 E7E2 -A95B E7E3 -A95D E7E4 -A95E E7E5 -A95F E7E6 -8336C831 E7E7 -8336C832 E7E8 -8336C833 E7E9 -8336C834 E7EA -8336C835 E7EB -8336C836 E7EC -8336C837 E7ED -8336C838 E7EE -8336C839 E7EF -8336C930 E7F0 -8336C931 E7F1 -8336C932 E7F2 -8336C933 E7F3 -A997 E7F4 -A998 E7F5 -A999 E7F6 -A99A E7F7 -A99B E7F8 -A99C E7F9 -A99D E7FA -A99E E7FB -A99F E7FC -A9A0 E7FD -A9A1 E7FE -A9A2 E7FF -A9A3 E800 -A9F0 E801 -A9F1 E802 -A9F2 E803 -A9F3 E804 -A9F4 E805 -A9F5 E806 -A9F6 E807 -A9F7 E808 -A9F8 E809 -A9F9 E80A -A9FA E80B -A9FB E80C -A9FC E80D -A9FD E80E -A9FE E80F -D7FA E810 -D7FB E811 -D7FC E812 -D7FD E813 -D7FE E814 -8336C934 E815 -FE51 E816 -FE52 E817 -FE53 E818 -8336C935 E819 -8336C936 E81A -8336C937 E81B -8336C938 E81C -8336C939 E81D -FE59 E81E -8336CA30 E81F -8336CA31 E820 -8336CA32 E821 -8336CA33 E822 -8336CA34 E823 -8336CA35 E824 -8336CA36 E825 -FE61 E826 -8336CA37 E827 -8336CA38 E828 -8336CA39 E829 -8336CB30 E82A -FE66 E82B -FE67 E82C -8336CB31 E82D -8336CB32 E82E -8336CB33 E82F -8336CB34 E830 -FE6C E831 -FE6D E832 -8336CB35 E833 -8336CB36 E834 -8336CB37 E835 -8336CB38 E836 -8336CB39 E837 -8336CC30 E838 -8336CC31 E839 -8336CC32 E83A -FE76 E83B -8336CC33 E83C -8336CC34 E83D -8336CC35 E83E -8336CC36 E83F -8336CC37 E840 -8336CC38 E841 -8336CC39 E842 -FE7E E843 -8336CD30 E844 -8336CD31 E845 -8336CD32 E846 -8336CD33 E847 -8336CD34 E848 -8336CD35 E849 -8336CD36 E84A -8336CD37 E84B -8336CD38 E84C -8336CD39 E84D -8336CE30 E84E -8336CE31 E84F -8336CE32 E850 -8336CE33 E851 -8336CE34 E852 -8336CE35 E853 -FE90 E854 -FE91 E855 -8336CE36 E856 -8336CE37 E857 -8336CE38 E858 -8336CE39 E859 -8336CF30 E85A -8336CF31 E85B -8336CF32 E85C -8336CF33 E85D -8336CF34 E85E -8336CF35 E85F -8336CF36 E860 -8336CF37 E861 -8336CF38 E862 -8336CF39 E863 -FEA0 E864 -8336D030 E865 -8336D031 E866 -8336D032 E867 -8336D033 E868 -8336D034 E869 -8336D035 E86A -8336D036 E86B -8336D037 E86C -8336D038 E86D -8336D039 E86E -8336D130 E86F -8336D131 E870 -8336D132 E871 -8336D133 E872 -8336D134 E873 -8336D135 E874 -8336D136 E875 -8336D137 E876 -8336D138 E877 -8336D139 E878 -8336D230 E879 -8336D231 E87A -8336D232 E87B -8336D233 E87C -8336D234 E87D -8336D235 E87E -8336D236 E87F -8336D237 E880 -8336D238 E881 -8336D239 E882 -8336D330 E883 -8336D331 E884 -8336D332 E885 -8336D333 E886 -8336D334 E887 -8336D335 E888 -8336D336 E889 -8336D337 E88A -8336D338 E88B -8336D339 E88C -8336D430 E88D -8336D431 E88E -8336D432 E88F -8336D433 E890 -8336D434 E891 -8336D435 E892 -8336D436 E893 -8336D437 E894 -8336D438 E895 -8336D439 E896 -8336D530 E897 -8336D531 E898 -8336D532 E899 -8336D533 E89A -8336D534 E89B -8336D535 E89C -8336D536 E89D -8336D537 E89E -8336D538 E89F -8336D539 E8A0 -8336D630 E8A1 -8336D631 E8A2 -8336D632 E8A3 -8336D633 E8A4 -8336D634 E8A5 -8336D635 E8A6 -8336D636 E8A7 -8336D637 E8A8 -8336D638 E8A9 -8336D639 E8AA -8336D730 E8AB -8336D731 E8AC -8336D732 E8AD -8336D733 E8AE -8336D734 E8AF -8336D735 E8B0 -8336D736 E8B1 -8336D737 E8B2 -8336D738 E8B3 -8336D739 E8B4 -8336D830 E8B5 -8336D831 E8B6 -8336D832 E8B7 -8336D833 E8B8 -8336D834 E8B9 -8336D835 E8BA -8336D836 E8BB -8336D837 E8BC -8336D838 E8BD -8336D839 E8BE -8336D930 E8BF -8336D931 E8C0 -8336D932 E8C1 -8336D933 E8C2 -8336D934 E8C3 -8336D935 E8C4 -8336D936 E8C5 -8336D937 E8C6 -8336D938 E8C7 -8336D939 E8C8 -8336DA30 E8C9 -8336DA31 E8CA -8336DA32 E8CB -8336DA33 E8CC -8336DA34 E8CD -8336DA35 E8CE -8336DA36 E8CF -8336DA37 E8D0 -8336DA38 E8D1 -8336DA39 E8D2 -8336DB30 E8D3 -8336DB31 E8D4 -8336DB32 E8D5 -8336DB33 E8D6 -8336DB34 E8D7 -8336DB35 E8D8 -8336DB36 E8D9 -8336DB37 E8DA -8336DB38 E8DB -8336DB39 E8DC -8336DC30 E8DD -8336DC31 E8DE -8336DC32 E8DF -8336DC33 E8E0 -8336DC34 E8E1 -8336DC35 E8E2 -8336DC36 E8E3 -8336DC37 E8E4 -8336DC38 E8E5 -8336DC39 E8E6 -8336DD30 E8E7 -8336DD31 E8E8 -8336DD32 E8E9 -8336DD33 E8EA -8336DD34 E8EB -8336DD35 E8EC -8336DD36 E8ED -8336DD37 E8EE -8336DD38 E8EF -8336DD39 E8F0 -8336DE30 E8F1 -8336DE31 E8F2 -8336DE32 E8F3 -8336DE33 E8F4 -8336DE34 E8F5 -8336DE35 E8F6 -8336DE36 E8F7 -8336DE37 E8F8 -8336DE38 E8F9 -8336DE39 E8FA -8336DF30 E8FB -8336DF31 E8FC -8336DF32 E8FD -8336DF33 E8FE -8336DF34 E8FF -8336DF35 E900 -8336DF36 E901 -8336DF37 E902 -8336DF38 E903 -8336DF39 E904 -8336E030 E905 -8336E031 E906 -8336E032 E907 -8336E033 E908 -8336E034 E909 -8336E035 E90A -8336E036 E90B -8336E037 E90C -8336E038 E90D -8336E039 E90E -8336E130 E90F -8336E131 E910 -8336E132 E911 -8336E133 E912 -8336E134 E913 -8336E135 E914 -8336E136 E915 -8336E137 E916 -8336E138 E917 -8336E139 E918 -8336E230 E919 -8336E231 E91A -8336E232 E91B -8336E233 E91C -8336E234 E91D -8336E235 E91E -8336E236 E91F -8336E237 E920 -8336E238 E921 -8336E239 E922 -8336E330 E923 -8336E331 E924 -8336E332 E925 -8336E333 E926 -8336E334 E927 -8336E335 E928 -8336E336 E929 -8336E337 E92A -8336E338 E92B -8336E339 E92C -8336E430 E92D -8336E431 E92E -8336E432 E92F -8336E433 E930 -8336E434 E931 -8336E435 E932 -8336E436 E933 -8336E437 E934 -8336E438 E935 -8336E439 E936 -8336E530 E937 -8336E531 E938 -8336E532 E939 -8336E533 E93A -8336E534 E93B -8336E535 E93C -8336E536 E93D -8336E537 E93E -8336E538 E93F -8336E539 E940 -8336E630 E941 -8336E631 E942 -8336E632 E943 -8336E633 E944 -8336E634 E945 -8336E635 E946 -8336E636 E947 -8336E637 E948 -8336E638 E949 -8336E639 E94A -8336E730 E94B -8336E731 E94C -8336E732 E94D -8336E733 E94E -8336E734 E94F -8336E735 E950 -8336E736 E951 -8336E737 E952 -8336E738 E953 -8336E739 E954 -8336E830 E955 -8336E831 E956 -8336E832 E957 -8336E833 E958 -8336E834 E959 -8336E835 E95A -8336E836 E95B -8336E837 E95C -8336E838 E95D -8336E839 E95E -8336E930 E95F -8336E931 E960 -8336E932 E961 -8336E933 E962 -8336E934 E963 -8336E935 E964 -8336E936 E965 -8336E937 E966 -8336E938 E967 -8336E939 E968 -8336EA30 E969 -8336EA31 E96A -8336EA32 E96B -8336EA33 E96C -8336EA34 E96D -8336EA35 E96E -8336EA36 E96F -8336EA37 E970 -8336EA38 E971 -8336EA39 E972 -8336EB30 E973 -8336EB31 E974 -8336EB32 E975 -8336EB33 E976 -8336EB34 E977 -8336EB35 E978 -8336EB36 E979 -8336EB37 E97A -8336EB38 E97B -8336EB39 E97C -8336EC30 E97D -8336EC31 E97E -8336EC32 E97F -8336EC33 E980 -8336EC34 E981 -8336EC35 E982 -8336EC36 E983 -8336EC37 E984 -8336EC38 E985 -8336EC39 E986 -8336ED30 E987 -8336ED31 E988 -8336ED32 E989 -8336ED33 E98A -8336ED34 E98B -8336ED35 E98C -8336ED36 E98D -8336ED37 E98E -8336ED38 E98F -8336ED39 E990 -8336EE30 E991 -8336EE31 E992 -8336EE32 E993 -8336EE33 E994 -8336EE34 E995 -8336EE35 E996 -8336EE36 E997 -8336EE37 E998 -8336EE38 E999 -8336EE39 E99A -8336EF30 E99B -8336EF31 E99C -8336EF32 E99D -8336EF33 E99E -8336EF34 E99F -8336EF35 E9A0 -8336EF36 E9A1 -8336EF37 E9A2 -8336EF38 E9A3 -8336EF39 E9A4 -8336F030 E9A5 -8336F031 E9A6 -8336F032 E9A7 -8336F033 E9A8 -8336F034 E9A9 -8336F035 E9AA -8336F036 E9AB -8336F037 E9AC -8336F038 E9AD -8336F039 E9AE -8336F130 E9AF -8336F131 E9B0 -8336F132 E9B1 -8336F133 E9B2 -8336F134 E9B3 -8336F135 E9B4 -8336F136 E9B5 -8336F137 E9B6 -8336F138 E9B7 -8336F139 E9B8 -8336F230 E9B9 -8336F231 E9BA -8336F232 E9BB -8336F233 E9BC -8336F234 E9BD -8336F235 E9BE -8336F236 E9BF -8336F237 E9C0 -8336F238 E9C1 -8336F239 E9C2 -8336F330 E9C3 -8336F331 E9C4 -8336F332 E9C5 -8336F333 E9C6 -8336F334 E9C7 -8336F335 E9C8 -8336F336 E9C9 -8336F337 E9CA -8336F338 E9CB -8336F339 E9CC -8336F430 E9CD -8336F431 E9CE -8336F432 E9CF -8336F433 E9D0 -8336F434 E9D1 -8336F435 E9D2 -8336F436 E9D3 -8336F437 E9D4 -8336F438 E9D5 -8336F439 E9D6 -8336F530 E9D7 -8336F531 E9D8 -8336F532 E9D9 -8336F533 E9DA -8336F534 E9DB -8336F535 E9DC -8336F536 E9DD -8336F537 E9DE -8336F538 E9DF -8336F539 E9E0 -8336F630 E9E1 -8336F631 E9E2 -8336F632 E9E3 -8336F633 E9E4 -8336F634 E9E5 -8336F635 E9E6 -8336F636 E9E7 -8336F637 E9E8 -8336F638 E9E9 -8336F639 E9EA -8336F730 E9EB -8336F731 E9EC -8336F732 E9ED -8336F733 E9EE -8336F734 E9EF -8336F735 E9F0 -8336F736 E9F1 -8336F737 E9F2 -8336F738 E9F3 -8336F739 E9F4 -8336F830 E9F5 -8336F831 E9F6 -8336F832 E9F7 -8336F833 E9F8 -8336F834 E9F9 -8336F835 E9FA -8336F836 E9FB -8336F837 E9FC -8336F838 E9FD -8336F839 E9FE -8336F930 E9FF -8336F931 EA00 -8336F932 EA01 -8336F933 EA02 -8336F934 EA03 -8336F935 EA04 -8336F936 EA05 -8336F937 EA06 -8336F938 EA07 -8336F939 EA08 -8336FA30 EA09 -8336FA31 EA0A -8336FA32 EA0B -8336FA33 EA0C -8336FA34 EA0D -8336FA35 EA0E -8336FA36 EA0F -8336FA37 EA10 -8336FA38 EA11 -8336FA39 EA12 -8336FB30 EA13 -8336FB31 EA14 -8336FB32 EA15 -8336FB33 EA16 -8336FB34 EA17 -8336FB35 EA18 -8336FB36 EA19 -8336FB37 EA1A -8336FB38 EA1B -8336FB39 EA1C -8336FC30 EA1D -8336FC31 EA1E -8336FC32 EA1F -8336FC33 EA20 -8336FC34 EA21 -8336FC35 EA22 -8336FC36 EA23 -8336FC37 EA24 -8336FC38 EA25 -8336FC39 EA26 -8336FD30 EA27 -8336FD31 EA28 -8336FD32 EA29 -8336FD33 EA2A -8336FD34 EA2B -8336FD35 EA2C -8336FD36 EA2D -8336FD37 EA2E -8336FD38 EA2F -8336FD39 EA30 -8336FE30 EA31 -8336FE31 EA32 -8336FE32 EA33 -8336FE33 EA34 -8336FE34 EA35 -8336FE35 EA36 -8336FE36 EA37 -8336FE37 EA38 -8336FE38 EA39 -8336FE39 EA3A -83378130 EA3B -83378131 EA3C -83378132 EA3D -83378133 EA3E -83378134 EA3F -83378135 EA40 -83378136 EA41 -83378137 EA42 -83378138 EA43 -83378139 EA44 -83378230 EA45 -83378231 EA46 -83378232 EA47 -83378233 EA48 -83378234 EA49 -83378235 EA4A -83378236 EA4B -83378237 EA4C -83378238 EA4D -83378239 EA4E -83378330 EA4F -83378331 EA50 -83378332 EA51 -83378333 EA52 -83378334 EA53 -83378335 EA54 -83378336 EA55 -83378337 EA56 -83378338 EA57 -83378339 EA58 -83378430 EA59 -83378431 EA5A -83378432 EA5B -83378433 EA5C -83378434 EA5D -83378435 EA5E -83378436 EA5F -83378437 EA60 -83378438 EA61 -83378439 EA62 -83378530 EA63 -83378531 EA64 -83378532 EA65 -83378533 EA66 -83378534 EA67 -83378535 EA68 -83378536 EA69 -83378537 EA6A -83378538 EA6B -83378539 EA6C -83378630 EA6D -83378631 EA6E -83378632 EA6F -83378633 EA70 -83378634 EA71 -83378635 EA72 -83378636 EA73 -83378637 EA74 -83378638 EA75 -83378639 EA76 -83378730 EA77 -83378731 EA78 -83378732 EA79 -83378733 EA7A -83378734 EA7B -83378735 EA7C -83378736 EA7D -83378737 EA7E -83378738 EA7F -83378739 EA80 -83378830 EA81 -83378831 EA82 -83378832 EA83 -83378833 EA84 -83378834 EA85 -83378835 EA86 -83378836 EA87 -83378837 EA88 -83378838 EA89 -83378839 EA8A -83378930 EA8B -83378931 EA8C -83378932 EA8D -83378933 EA8E -83378934 EA8F -83378935 EA90 -83378936 EA91 -83378937 EA92 -83378938 EA93 -83378939 EA94 -83378A30 EA95 -83378A31 EA96 -83378A32 EA97 -83378A33 EA98 -83378A34 EA99 -83378A35 EA9A -83378A36 EA9B -83378A37 EA9C -83378A38 EA9D -83378A39 EA9E -83378B30 EA9F -83378B31 EAA0 -83378B32 EAA1 -83378B33 EAA2 -83378B34 EAA3 -83378B35 EAA4 -83378B36 EAA5 -83378B37 EAA6 -83378B38 EAA7 -83378B39 EAA8 -83378C30 EAA9 -83378C31 EAAA -83378C32 EAAB -83378C33 EAAC -83378C34 EAAD -83378C35 EAAE -83378C36 EAAF -83378C37 EAB0 -83378C38 EAB1 -83378C39 EAB2 -83378D30 EAB3 -83378D31 EAB4 -83378D32 EAB5 -83378D33 EAB6 -83378D34 EAB7 -83378D35 EAB8 -83378D36 EAB9 -83378D37 EABA -83378D38 EABB -83378D39 EABC -83378E30 EABD -83378E31 EABE -83378E32 EABF -83378E33 EAC0 -83378E34 EAC1 -83378E35 EAC2 -83378E36 EAC3 -83378E37 EAC4 -83378E38 EAC5 -83378E39 EAC6 -83378F30 EAC7 -83378F31 EAC8 -83378F32 EAC9 -83378F33 EACA -83378F34 EACB -83378F35 EACC -83378F36 EACD -83378F37 EACE -83378F38 EACF -83378F39 EAD0 -83379030 EAD1 -83379031 EAD2 -83379032 EAD3 -83379033 EAD4 -83379034 EAD5 -83379035 EAD6 -83379036 EAD7 -83379037 EAD8 -83379038 EAD9 -83379039 EADA -83379130 EADB -83379131 EADC -83379132 EADD -83379133 EADE -83379134 EADF -83379135 EAE0 -83379136 EAE1 -83379137 EAE2 -83379138 EAE3 -83379139 EAE4 -83379230 EAE5 -83379231 EAE6 -83379232 EAE7 -83379233 EAE8 -83379234 EAE9 -83379235 EAEA -83379236 EAEB -83379237 EAEC -83379238 EAED -83379239 EAEE -83379330 EAEF -83379331 EAF0 -83379332 EAF1 -83379333 EAF2 -83379334 EAF3 -83379335 EAF4 -83379336 EAF5 -83379337 EAF6 -83379338 EAF7 -83379339 EAF8 -83379430 EAF9 -83379431 EAFA -83379432 EAFB -83379433 EAFC -83379434 EAFD -83379435 EAFE -83379436 EAFF -83379437 EB00 -83379438 EB01 -83379439 EB02 -83379530 EB03 -83379531 EB04 -83379532 EB05 -83379533 EB06 -83379534 EB07 -83379535 EB08 -83379536 EB09 -83379537 EB0A -83379538 EB0B -83379539 EB0C -83379630 EB0D -83379631 EB0E -83379632 EB0F -83379633 EB10 -83379634 EB11 -83379635 EB12 -83379636 EB13 -83379637 EB14 -83379638 EB15 -83379639 EB16 -83379730 EB17 -83379731 EB18 -83379732 EB19 -83379733 EB1A -83379734 EB1B -83379735 EB1C -83379736 EB1D -83379737 EB1E -83379738 EB1F -83379739 EB20 -83379830 EB21 -83379831 EB22 -83379832 EB23 -83379833 EB24 -83379834 EB25 -83379835 EB26 -83379836 EB27 -83379837 EB28 -83379838 EB29 -83379839 EB2A -83379930 EB2B -83379931 EB2C -83379932 EB2D -83379933 EB2E -83379934 EB2F -83379935 EB30 -83379936 EB31 -83379937 EB32 -83379938 EB33 -83379939 EB34 -83379A30 EB35 -83379A31 EB36 -83379A32 EB37 -83379A33 EB38 -83379A34 EB39 -83379A35 EB3A -83379A36 EB3B -83379A37 EB3C -83379A38 EB3D -83379A39 EB3E -83379B30 EB3F -83379B31 EB40 -83379B32 EB41 -83379B33 EB42 -83379B34 EB43 -83379B35 EB44 -83379B36 EB45 -83379B37 EB46 -83379B38 EB47 -83379B39 EB48 -83379C30 EB49 -83379C31 EB4A -83379C32 EB4B -83379C33 EB4C -83379C34 EB4D -83379C35 EB4E -83379C36 EB4F -83379C37 EB50 -83379C38 EB51 -83379C39 EB52 -83379D30 EB53 -83379D31 EB54 -83379D32 EB55 -83379D33 EB56 -83379D34 EB57 -83379D35 EB58 -83379D36 EB59 -83379D37 EB5A -83379D38 EB5B -83379D39 EB5C -83379E30 EB5D -83379E31 EB5E -83379E32 EB5F -83379E33 EB60 -83379E34 EB61 -83379E35 EB62 -83379E36 EB63 -83379E37 EB64 -83379E38 EB65 -83379E39 EB66 -83379F30 EB67 -83379F31 EB68 -83379F32 EB69 -83379F33 EB6A -83379F34 EB6B -83379F35 EB6C -83379F36 EB6D -83379F37 EB6E -83379F38 EB6F -83379F39 EB70 -8337A030 EB71 -8337A031 EB72 -8337A032 EB73 -8337A033 EB74 -8337A034 EB75 -8337A035 EB76 -8337A036 EB77 -8337A037 EB78 -8337A038 EB79 -8337A039 EB7A -8337A130 EB7B -8337A131 EB7C -8337A132 EB7D -8337A133 EB7E -8337A134 EB7F -8337A135 EB80 -8337A136 EB81 -8337A137 EB82 -8337A138 EB83 -8337A139 EB84 -8337A230 EB85 -8337A231 EB86 -8337A232 EB87 -8337A233 EB88 -8337A234 EB89 -8337A235 EB8A -8337A236 EB8B -8337A237 EB8C -8337A238 EB8D -8337A239 EB8E -8337A330 EB8F -8337A331 EB90 -8337A332 EB91 -8337A333 EB92 -8337A334 EB93 -8337A335 EB94 -8337A336 EB95 -8337A337 EB96 -8337A338 EB97 -8337A339 EB98 -8337A430 EB99 -8337A431 EB9A -8337A432 EB9B -8337A433 EB9C -8337A434 EB9D -8337A435 EB9E -8337A436 EB9F -8337A437 EBA0 -8337A438 EBA1 -8337A439 EBA2 -8337A530 EBA3 -8337A531 EBA4 -8337A532 EBA5 -8337A533 EBA6 -8337A534 EBA7 -8337A535 EBA8 -8337A536 EBA9 -8337A537 EBAA -8337A538 EBAB -8337A539 EBAC -8337A630 EBAD -8337A631 EBAE -8337A632 EBAF -8337A633 EBB0 -8337A634 EBB1 -8337A635 EBB2 -8337A636 EBB3 -8337A637 EBB4 -8337A638 EBB5 -8337A639 EBB6 -8337A730 EBB7 -8337A731 EBB8 -8337A732 EBB9 -8337A733 EBBA -8337A734 EBBB -8337A735 EBBC -8337A736 EBBD -8337A737 EBBE -8337A738 EBBF -8337A739 EBC0 -8337A830 EBC1 -8337A831 EBC2 -8337A832 EBC3 -8337A833 EBC4 -8337A834 EBC5 -8337A835 EBC6 -8337A836 EBC7 -8337A837 EBC8 -8337A838 EBC9 -8337A839 EBCA -8337A930 EBCB -8337A931 EBCC -8337A932 EBCD -8337A933 EBCE -8337A934 EBCF -8337A935 EBD0 -8337A936 EBD1 -8337A937 EBD2 -8337A938 EBD3 -8337A939 EBD4 -8337AA30 EBD5 -8337AA31 EBD6 -8337AA32 EBD7 -8337AA33 EBD8 -8337AA34 EBD9 -8337AA35 EBDA -8337AA36 EBDB -8337AA37 EBDC -8337AA38 EBDD -8337AA39 EBDE -8337AB30 EBDF -8337AB31 EBE0 -8337AB32 EBE1 -8337AB33 EBE2 -8337AB34 EBE3 -8337AB35 EBE4 -8337AB36 EBE5 -8337AB37 EBE6 -8337AB38 EBE7 -8337AB39 EBE8 -8337AC30 EBE9 -8337AC31 EBEA -8337AC32 EBEB -8337AC33 EBEC -8337AC34 EBED -8337AC35 EBEE -8337AC36 EBEF -8337AC37 EBF0 -8337AC38 EBF1 -8337AC39 EBF2 -8337AD30 EBF3 -8337AD31 EBF4 -8337AD32 EBF5 -8337AD33 EBF6 -8337AD34 EBF7 -8337AD35 EBF8 -8337AD36 EBF9 -8337AD37 EBFA -8337AD38 EBFB -8337AD39 EBFC -8337AE30 EBFD -8337AE31 EBFE -8337AE32 EBFF -8337AE33 EC00 -8337AE34 EC01 -8337AE35 EC02 -8337AE36 EC03 -8337AE37 EC04 -8337AE38 EC05 -8337AE39 EC06 -8337AF30 EC07 -8337AF31 EC08 -8337AF32 EC09 -8337AF33 EC0A -8337AF34 EC0B -8337AF35 EC0C -8337AF36 EC0D -8337AF37 EC0E -8337AF38 EC0F -8337AF39 EC10 -8337B030 EC11 -8337B031 EC12 -8337B032 EC13 -8337B033 EC14 -8337B034 EC15 -8337B035 EC16 -8337B036 EC17 -8337B037 EC18 -8337B038 EC19 -8337B039 EC1A -8337B130 EC1B -8337B131 EC1C -8337B132 EC1D -8337B133 EC1E -8337B134 EC1F -8337B135 EC20 -8337B136 EC21 -8337B137 EC22 -8337B138 EC23 -8337B139 EC24 -8337B230 EC25 -8337B231 EC26 -8337B232 EC27 -8337B233 EC28 -8337B234 EC29 -8337B235 EC2A -8337B236 EC2B -8337B237 EC2C -8337B238 EC2D -8337B239 EC2E -8337B330 EC2F -8337B331 EC30 -8337B332 EC31 -8337B333 EC32 -8337B334 EC33 -8337B335 EC34 -8337B336 EC35 -8337B337 EC36 -8337B338 EC37 -8337B339 EC38 -8337B430 EC39 -8337B431 EC3A -8337B432 EC3B -8337B433 EC3C -8337B434 EC3D -8337B435 EC3E -8337B436 EC3F -8337B437 EC40 -8337B438 EC41 -8337B439 EC42 -8337B530 EC43 -8337B531 EC44 -8337B532 EC45 -8337B533 EC46 -8337B534 EC47 -8337B535 EC48 -8337B536 EC49 -8337B537 EC4A -8337B538 EC4B -8337B539 EC4C -8337B630 EC4D -8337B631 EC4E -8337B632 EC4F -8337B633 EC50 -8337B634 EC51 -8337B635 EC52 -8337B636 EC53 -8337B637 EC54 -8337B638 EC55 -8337B639 EC56 -8337B730 EC57 -8337B731 EC58 -8337B732 EC59 -8337B733 EC5A -8337B734 EC5B -8337B735 EC5C -8337B736 EC5D -8337B737 EC5E -8337B738 EC5F -8337B739 EC60 -8337B830 EC61 -8337B831 EC62 -8337B832 EC63 -8337B833 EC64 -8337B834 EC65 -8337B835 EC66 -8337B836 EC67 -8337B837 EC68 -8337B838 EC69 -8337B839 EC6A -8337B930 EC6B -8337B931 EC6C -8337B932 EC6D -8337B933 EC6E -8337B934 EC6F -8337B935 EC70 -8337B936 EC71 -8337B937 EC72 -8337B938 EC73 -8337B939 EC74 -8337BA30 EC75 -8337BA31 EC76 -8337BA32 EC77 -8337BA33 EC78 -8337BA34 EC79 -8337BA35 EC7A -8337BA36 EC7B -8337BA37 EC7C -8337BA38 EC7D -8337BA39 EC7E -8337BB30 EC7F -8337BB31 EC80 -8337BB32 EC81 -8337BB33 EC82 -8337BB34 EC83 -8337BB35 EC84 -8337BB36 EC85 -8337BB37 EC86 -8337BB38 EC87 -8337BB39 EC88 -8337BC30 EC89 -8337BC31 EC8A -8337BC32 EC8B -8337BC33 EC8C -8337BC34 EC8D -8337BC35 EC8E -8337BC36 EC8F -8337BC37 EC90 -8337BC38 EC91 -8337BC39 EC92 -8337BD30 EC93 -8337BD31 EC94 -8337BD32 EC95 -8337BD33 EC96 -8337BD34 EC97 -8337BD35 EC98 -8337BD36 EC99 -8337BD37 EC9A -8337BD38 EC9B -8337BD39 EC9C -8337BE30 EC9D -8337BE31 EC9E -8337BE32 EC9F -8337BE33 ECA0 -8337BE34 ECA1 -8337BE35 ECA2 -8337BE36 ECA3 -8337BE37 ECA4 -8337BE38 ECA5 -8337BE39 ECA6 -8337BF30 ECA7 -8337BF31 ECA8 -8337BF32 ECA9 -8337BF33 ECAA -8337BF34 ECAB -8337BF35 ECAC -8337BF36 ECAD -8337BF37 ECAE -8337BF38 ECAF -8337BF39 ECB0 -8337C030 ECB1 -8337C031 ECB2 -8337C032 ECB3 -8337C033 ECB4 -8337C034 ECB5 -8337C035 ECB6 -8337C036 ECB7 -8337C037 ECB8 -8337C038 ECB9 -8337C039 ECBA -8337C130 ECBB -8337C131 ECBC -8337C132 ECBD -8337C133 ECBE -8337C134 ECBF -8337C135 ECC0 -8337C136 ECC1 -8337C137 ECC2 -8337C138 ECC3 -8337C139 ECC4 -8337C230 ECC5 -8337C231 ECC6 -8337C232 ECC7 -8337C233 ECC8 -8337C234 ECC9 -8337C235 ECCA -8337C236 ECCB -8337C237 ECCC -8337C238 ECCD -8337C239 ECCE -8337C330 ECCF -8337C331 ECD0 -8337C332 ECD1 -8337C333 ECD2 -8337C334 ECD3 -8337C335 ECD4 -8337C336 ECD5 -8337C337 ECD6 -8337C338 ECD7 -8337C339 ECD8 -8337C430 ECD9 -8337C431 ECDA -8337C432 ECDB -8337C433 ECDC -8337C434 ECDD -8337C435 ECDE -8337C436 ECDF -8337C437 ECE0 -8337C438 ECE1 -8337C439 ECE2 -8337C530 ECE3 -8337C531 ECE4 -8337C532 ECE5 -8337C533 ECE6 -8337C534 ECE7 -8337C535 ECE8 -8337C536 ECE9 -8337C537 ECEA -8337C538 ECEB -8337C539 ECEC -8337C630 ECED -8337C631 ECEE -8337C632 ECEF -8337C633 ECF0 -8337C634 ECF1 -8337C635 ECF2 -8337C636 ECF3 -8337C637 ECF4 -8337C638 ECF5 -8337C639 ECF6 -8337C730 ECF7 -8337C731 ECF8 -8337C732 ECF9 -8337C733 ECFA -8337C734 ECFB -8337C735 ECFC -8337C736 ECFD -8337C737 ECFE -8337C738 ECFF -8337C739 ED00 -8337C830 ED01 -8337C831 ED02 -8337C832 ED03 -8337C833 ED04 -8337C834 ED05 -8337C835 ED06 -8337C836 ED07 -8337C837 ED08 -8337C838 ED09 -8337C839 ED0A -8337C930 ED0B -8337C931 ED0C -8337C932 ED0D -8337C933 ED0E -8337C934 ED0F -8337C935 ED10 -8337C936 ED11 -8337C937 ED12 -8337C938 ED13 -8337C939 ED14 -8337CA30 ED15 -8337CA31 ED16 -8337CA32 ED17 -8337CA33 ED18 -8337CA34 ED19 -8337CA35 ED1A -8337CA36 ED1B -8337CA37 ED1C -8337CA38 ED1D -8337CA39 ED1E -8337CB30 ED1F -8337CB31 ED20 -8337CB32 ED21 -8337CB33 ED22 -8337CB34 ED23 -8337CB35 ED24 -8337CB36 ED25 -8337CB37 ED26 -8337CB38 ED27 -8337CB39 ED28 -8337CC30 ED29 -8337CC31 ED2A -8337CC32 ED2B -8337CC33 ED2C -8337CC34 ED2D -8337CC35 ED2E -8337CC36 ED2F -8337CC37 ED30 -8337CC38 ED31 -8337CC39 ED32 -8337CD30 ED33 -8337CD31 ED34 -8337CD32 ED35 -8337CD33 ED36 -8337CD34 ED37 -8337CD35 ED38 -8337CD36 ED39 -8337CD37 ED3A -8337CD38 ED3B -8337CD39 ED3C -8337CE30 ED3D -8337CE31 ED3E -8337CE32 ED3F -8337CE33 ED40 -8337CE34 ED41 -8337CE35 ED42 -8337CE36 ED43 -8337CE37 ED44 -8337CE38 ED45 -8337CE39 ED46 -8337CF30 ED47 -8337CF31 ED48 -8337CF32 ED49 -8337CF33 ED4A -8337CF34 ED4B -8337CF35 ED4C -8337CF36 ED4D -8337CF37 ED4E -8337CF38 ED4F -8337CF39 ED50 -8337D030 ED51 -8337D031 ED52 -8337D032 ED53 -8337D033 ED54 -8337D034 ED55 -8337D035 ED56 -8337D036 ED57 -8337D037 ED58 -8337D038 ED59 -8337D039 ED5A -8337D130 ED5B -8337D131 ED5C -8337D132 ED5D -8337D133 ED5E -8337D134 ED5F -8337D135 ED60 -8337D136 ED61 -8337D137 ED62 -8337D138 ED63 -8337D139 ED64 -8337D230 ED65 -8337D231 ED66 -8337D232 ED67 -8337D233 ED68 -8337D234 ED69 -8337D235 ED6A -8337D236 ED6B -8337D237 ED6C -8337D238 ED6D -8337D239 ED6E -8337D330 ED6F -8337D331 ED70 -8337D332 ED71 -8337D333 ED72 -8337D334 ED73 -8337D335 ED74 -8337D336 ED75 -8337D337 ED76 -8337D338 ED77 -8337D339 ED78 -8337D430 ED79 -8337D431 ED7A -8337D432 ED7B -8337D433 ED7C -8337D434 ED7D -8337D435 ED7E -8337D436 ED7F -8337D437 ED80 -8337D438 ED81 -8337D439 ED82 -8337D530 ED83 -8337D531 ED84 -8337D532 ED85 -8337D533 ED86 -8337D534 ED87 -8337D535 ED88 -8337D536 ED89 -8337D537 ED8A -8337D538 ED8B -8337D539 ED8C -8337D630 ED8D -8337D631 ED8E -8337D632 ED8F -8337D633 ED90 -8337D634 ED91 -8337D635 ED92 -8337D636 ED93 -8337D637 ED94 -8337D638 ED95 -8337D639 ED96 -8337D730 ED97 -8337D731 ED98 -8337D732 ED99 -8337D733 ED9A -8337D734 ED9B -8337D735 ED9C -8337D736 ED9D -8337D737 ED9E -8337D738 ED9F -8337D739 EDA0 -8337D830 EDA1 -8337D831 EDA2 -8337D832 EDA3 -8337D833 EDA4 -8337D834 EDA5 -8337D835 EDA6 -8337D836 EDA7 -8337D837 EDA8 -8337D838 EDA9 -8337D839 EDAA -8337D930 EDAB -8337D931 EDAC -8337D932 EDAD -8337D933 EDAE -8337D934 EDAF -8337D935 EDB0 -8337D936 EDB1 -8337D937 EDB2 -8337D938 EDB3 -8337D939 EDB4 -8337DA30 EDB5 -8337DA31 EDB6 -8337DA32 EDB7 -8337DA33 EDB8 -8337DA34 EDB9 -8337DA35 EDBA -8337DA36 EDBB -8337DA37 EDBC -8337DA38 EDBD -8337DA39 EDBE -8337DB30 EDBF -8337DB31 EDC0 -8337DB32 EDC1 -8337DB33 EDC2 -8337DB34 EDC3 -8337DB35 EDC4 -8337DB36 EDC5 -8337DB37 EDC6 -8337DB38 EDC7 -8337DB39 EDC8 -8337DC30 EDC9 -8337DC31 EDCA -8337DC32 EDCB -8337DC33 EDCC -8337DC34 EDCD -8337DC35 EDCE -8337DC36 EDCF -8337DC37 EDD0 -8337DC38 EDD1 -8337DC39 EDD2 -8337DD30 EDD3 -8337DD31 EDD4 -8337DD32 EDD5 -8337DD33 EDD6 -8337DD34 EDD7 -8337DD35 EDD8 -8337DD36 EDD9 -8337DD37 EDDA -8337DD38 EDDB -8337DD39 EDDC -8337DE30 EDDD -8337DE31 EDDE -8337DE32 EDDF -8337DE33 EDE0 -8337DE34 EDE1 -8337DE35 EDE2 -8337DE36 EDE3 -8337DE37 EDE4 -8337DE38 EDE5 -8337DE39 EDE6 -8337DF30 EDE7 -8337DF31 EDE8 -8337DF32 EDE9 -8337DF33 EDEA -8337DF34 EDEB -8337DF35 EDEC -8337DF36 EDED -8337DF37 EDEE -8337DF38 EDEF -8337DF39 EDF0 -8337E030 EDF1 -8337E031 EDF2 -8337E032 EDF3 -8337E033 EDF4 -8337E034 EDF5 -8337E035 EDF6 -8337E036 EDF7 -8337E037 EDF8 -8337E038 EDF9 -8337E039 EDFA -8337E130 EDFB -8337E131 EDFC -8337E132 EDFD -8337E133 EDFE -8337E134 EDFF -8337E135 EE00 -8337E136 EE01 -8337E137 EE02 -8337E138 EE03 -8337E139 EE04 -8337E230 EE05 -8337E231 EE06 -8337E232 EE07 -8337E233 EE08 -8337E234 EE09 -8337E235 EE0A -8337E236 EE0B -8337E237 EE0C -8337E238 EE0D -8337E239 EE0E -8337E330 EE0F -8337E331 EE10 -8337E332 EE11 -8337E333 EE12 -8337E334 EE13 -8337E335 EE14 -8337E336 EE15 -8337E337 EE16 -8337E338 EE17 -8337E339 EE18 -8337E430 EE19 -8337E431 EE1A -8337E432 EE1B -8337E433 EE1C -8337E434 EE1D -8337E435 EE1E -8337E436 EE1F -8337E437 EE20 -8337E438 EE21 -8337E439 EE22 -8337E530 EE23 -8337E531 EE24 -8337E532 EE25 -8337E533 EE26 -8337E534 EE27 -8337E535 EE28 -8337E536 EE29 -8337E537 EE2A -8337E538 EE2B -8337E539 EE2C -8337E630 EE2D -8337E631 EE2E -8337E632 EE2F -8337E633 EE30 -8337E634 EE31 -8337E635 EE32 -8337E636 EE33 -8337E637 EE34 -8337E638 EE35 -8337E639 EE36 -8337E730 EE37 -8337E731 EE38 -8337E732 EE39 -8337E733 EE3A -8337E734 EE3B -8337E735 EE3C -8337E736 EE3D -8337E737 EE3E -8337E738 EE3F -8337E739 EE40 -8337E830 EE41 -8337E831 EE42 -8337E832 EE43 -8337E833 EE44 -8337E834 EE45 -8337E835 EE46 -8337E836 EE47 -8337E837 EE48 -8337E838 EE49 -8337E839 EE4A -8337E930 EE4B -8337E931 EE4C -8337E932 EE4D -8337E933 EE4E -8337E934 EE4F -8337E935 EE50 -8337E936 EE51 -8337E937 EE52 -8337E938 EE53 -8337E939 EE54 -8337EA30 EE55 -8337EA31 EE56 -8337EA32 EE57 -8337EA33 EE58 -8337EA34 EE59 -8337EA35 EE5A -8337EA36 EE5B -8337EA37 EE5C -8337EA38 EE5D -8337EA39 EE5E -8337EB30 EE5F -8337EB31 EE60 -8337EB32 EE61 -8337EB33 EE62 -8337EB34 EE63 -8337EB35 EE64 -8337EB36 EE65 -8337EB37 EE66 -8337EB38 EE67 -8337EB39 EE68 -8337EC30 EE69 -8337EC31 EE6A -8337EC32 EE6B -8337EC33 EE6C -8337EC34 EE6D -8337EC35 EE6E -8337EC36 EE6F -8337EC37 EE70 -8337EC38 EE71 -8337EC39 EE72 -8337ED30 EE73 -8337ED31 EE74 -8337ED32 EE75 -8337ED33 EE76 -8337ED34 EE77 -8337ED35 EE78 -8337ED36 EE79 -8337ED37 EE7A -8337ED38 EE7B -8337ED39 EE7C -8337EE30 EE7D -8337EE31 EE7E -8337EE32 EE7F -8337EE33 EE80 -8337EE34 EE81 -8337EE35 EE82 -8337EE36 EE83 -8337EE37 EE84 -8337EE38 EE85 -8337EE39 EE86 -8337EF30 EE87 -8337EF31 EE88 -8337EF32 EE89 -8337EF33 EE8A -8337EF34 EE8B -8337EF35 EE8C -8337EF36 EE8D -8337EF37 EE8E -8337EF38 EE8F -8337EF39 EE90 -8337F030 EE91 -8337F031 EE92 -8337F032 EE93 -8337F033 EE94 -8337F034 EE95 -8337F035 EE96 -8337F036 EE97 -8337F037 EE98 -8337F038 EE99 -8337F039 EE9A -8337F130 EE9B -8337F131 EE9C -8337F132 EE9D -8337F133 EE9E -8337F134 EE9F -8337F135 EEA0 -8337F136 EEA1 -8337F137 EEA2 -8337F138 EEA3 -8337F139 EEA4 -8337F230 EEA5 -8337F231 EEA6 -8337F232 EEA7 -8337F233 EEA8 -8337F234 EEA9 -8337F235 EEAA -8337F236 EEAB -8337F237 EEAC -8337F238 EEAD -8337F239 EEAE -8337F330 EEAF -8337F331 EEB0 -8337F332 EEB1 -8337F333 EEB2 -8337F334 EEB3 -8337F335 EEB4 -8337F336 EEB5 -8337F337 EEB6 -8337F338 EEB7 -8337F339 EEB8 -8337F430 EEB9 -8337F431 EEBA -8337F432 EEBB -8337F433 EEBC -8337F434 EEBD -8337F435 EEBE -8337F436 EEBF -8337F437 EEC0 -8337F438 EEC1 -8337F439 EEC2 -8337F530 EEC3 -8337F531 EEC4 -8337F532 EEC5 -8337F533 EEC6 -8337F534 EEC7 -8337F535 EEC8 -8337F536 EEC9 -8337F537 EECA -8337F538 EECB -8337F539 EECC -8337F630 EECD -8337F631 EECE -8337F632 EECF -8337F633 EED0 -8337F634 EED1 -8337F635 EED2 -8337F636 EED3 -8337F637 EED4 -8337F638 EED5 -8337F639 EED6 -8337F730 EED7 -8337F731 EED8 -8337F732 EED9 -8337F733 EEDA -8337F734 EEDB -8337F735 EEDC -8337F736 EEDD -8337F737 EEDE -8337F738 EEDF -8337F739 EEE0 -8337F830 EEE1 -8337F831 EEE2 -8337F832 EEE3 -8337F833 EEE4 -8337F834 EEE5 -8337F835 EEE6 -8337F836 EEE7 -8337F837 EEE8 -8337F838 EEE9 -8337F839 EEEA -8337F930 EEEB -8337F931 EEEC -8337F932 EEED -8337F933 EEEE -8337F934 EEEF -8337F935 EEF0 -8337F936 EEF1 -8337F937 EEF2 -8337F938 EEF3 -8337F939 EEF4 -8337FA30 EEF5 -8337FA31 EEF6 -8337FA32 EEF7 -8337FA33 EEF8 -8337FA34 EEF9 -8337FA35 EEFA -8337FA36 EEFB -8337FA37 EEFC -8337FA38 EEFD -8337FA39 EEFE -8337FB30 EEFF -8337FB31 EF00 -8337FB32 EF01 -8337FB33 EF02 -8337FB34 EF03 -8337FB35 EF04 -8337FB36 EF05 -8337FB37 EF06 -8337FB38 EF07 -8337FB39 EF08 -8337FC30 EF09 -8337FC31 EF0A -8337FC32 EF0B -8337FC33 EF0C -8337FC34 EF0D -8337FC35 EF0E -8337FC36 EF0F -8337FC37 EF10 -8337FC38 EF11 -8337FC39 EF12 -8337FD30 EF13 -8337FD31 EF14 -8337FD32 EF15 -8337FD33 EF16 -8337FD34 EF17 -8337FD35 EF18 -8337FD36 EF19 -8337FD37 EF1A -8337FD38 EF1B -8337FD39 EF1C -8337FE30 EF1D -8337FE31 EF1E -8337FE32 EF1F -8337FE33 EF20 -8337FE34 EF21 -8337FE35 EF22 -8337FE36 EF23 -8337FE37 EF24 -8337FE38 EF25 -8337FE39 EF26 -83388130 EF27 -83388131 EF28 -83388132 EF29 -83388133 EF2A -83388134 EF2B -83388135 EF2C -83388136 EF2D -83388137 EF2E -83388138 EF2F -83388139 EF30 -83388230 EF31 -83388231 EF32 -83388232 EF33 -83388233 EF34 -83388234 EF35 -83388235 EF36 -83388236 EF37 -83388237 EF38 -83388238 EF39 -83388239 EF3A -83388330 EF3B -83388331 EF3C -83388332 EF3D -83388333 EF3E -83388334 EF3F -83388335 EF40 -83388336 EF41 -83388337 EF42 -83388338 EF43 -83388339 EF44 -83388430 EF45 -83388431 EF46 -83388432 EF47 -83388433 EF48 -83388434 EF49 -83388435 EF4A -83388436 EF4B -83388437 EF4C -83388438 EF4D -83388439 EF4E -83388530 EF4F -83388531 EF50 -83388532 EF51 -83388533 EF52 -83388534 EF53 -83388535 EF54 -83388536 EF55 -83388537 EF56 -83388538 EF57 -83388539 EF58 -83388630 EF59 -83388631 EF5A -83388632 EF5B -83388633 EF5C -83388634 EF5D -83388635 EF5E -83388636 EF5F -83388637 EF60 -83388638 EF61 -83388639 EF62 -83388730 EF63 -83388731 EF64 -83388732 EF65 -83388733 EF66 -83388734 EF67 -83388735 EF68 -83388736 EF69 -83388737 EF6A -83388738 EF6B -83388739 EF6C -83388830 EF6D -83388831 EF6E -83388832 EF6F -83388833 EF70 -83388834 EF71 -83388835 EF72 -83388836 EF73 -83388837 EF74 -83388838 EF75 -83388839 EF76 -83388930 EF77 -83388931 EF78 -83388932 EF79 -83388933 EF7A -83388934 EF7B -83388935 EF7C -83388936 EF7D -83388937 EF7E -83388938 EF7F -83388939 EF80 -83388A30 EF81 -83388A31 EF82 -83388A32 EF83 -83388A33 EF84 -83388A34 EF85 -83388A35 EF86 -83388A36 EF87 -83388A37 EF88 -83388A38 EF89 -83388A39 EF8A -83388B30 EF8B -83388B31 EF8C -83388B32 EF8D -83388B33 EF8E -83388B34 EF8F -83388B35 EF90 -83388B36 EF91 -83388B37 EF92 -83388B38 EF93 -83388B39 EF94 -83388C30 EF95 -83388C31 EF96 -83388C32 EF97 -83388C33 EF98 -83388C34 EF99 -83388C35 EF9A -83388C36 EF9B -83388C37 EF9C -83388C38 EF9D -83388C39 EF9E -83388D30 EF9F -83388D31 EFA0 -83388D32 EFA1 -83388D33 EFA2 -83388D34 EFA3 -83388D35 EFA4 -83388D36 EFA5 -83388D37 EFA6 -83388D38 EFA7 -83388D39 EFA8 -83388E30 EFA9 -83388E31 EFAA -83388E32 EFAB -83388E33 EFAC -83388E34 EFAD -83388E35 EFAE -83388E36 EFAF -83388E37 EFB0 -83388E38 EFB1 -83388E39 EFB2 -83388F30 EFB3 -83388F31 EFB4 -83388F32 EFB5 -83388F33 EFB6 -83388F34 EFB7 -83388F35 EFB8 -83388F36 EFB9 -83388F37 EFBA -83388F38 EFBB -83388F39 EFBC -83389030 EFBD -83389031 EFBE -83389032 EFBF -83389033 EFC0 -83389034 EFC1 -83389035 EFC2 -83389036 EFC3 -83389037 EFC4 -83389038 EFC5 -83389039 EFC6 -83389130 EFC7 -83389131 EFC8 -83389132 EFC9 -83389133 EFCA -83389134 EFCB -83389135 EFCC -83389136 EFCD -83389137 EFCE -83389138 EFCF -83389139 EFD0 -83389230 EFD1 -83389231 EFD2 -83389232 EFD3 -83389233 EFD4 -83389234 EFD5 -83389235 EFD6 -83389236 EFD7 -83389237 EFD8 -83389238 EFD9 -83389239 EFDA -83389330 EFDB -83389331 EFDC -83389332 EFDD -83389333 EFDE -83389334 EFDF -83389335 EFE0 -83389336 EFE1 -83389337 EFE2 -83389338 EFE3 -83389339 EFE4 -83389430 EFE5 -83389431 EFE6 -83389432 EFE7 -83389433 EFE8 -83389434 EFE9 -83389435 EFEA -83389436 EFEB -83389437 EFEC -83389438 EFED -83389439 EFEE -83389530 EFEF -83389531 EFF0 -83389532 EFF1 -83389533 EFF2 -83389534 EFF3 -83389535 EFF4 -83389536 EFF5 -83389537 EFF6 -83389538 EFF7 -83389539 EFF8 -83389630 EFF9 -83389631 EFFA -83389632 EFFB -83389633 EFFC -83389634 EFFD -83389635 EFFE -83389636 EFFF -83389637 F000 -83389638 F001 -83389639 F002 -83389730 F003 -83389731 F004 -83389732 F005 -83389733 F006 -83389734 F007 -83389735 F008 -83389736 F009 -83389737 F00A -83389738 F00B -83389739 F00C -83389830 F00D -83389831 F00E -83389832 F00F -83389833 F010 -83389834 F011 -83389835 F012 -83389836 F013 -83389837 F014 -83389838 F015 -83389839 F016 -83389930 F017 -83389931 F018 -83389932 F019 -83389933 F01A -83389934 F01B -83389935 F01C -83389936 F01D -83389937 F01E -83389938 F01F -83389939 F020 -83389A30 F021 -83389A31 F022 -83389A32 F023 -83389A33 F024 -83389A34 F025 -83389A35 F026 -83389A36 F027 -83389A37 F028 -83389A38 F029 -83389A39 F02A -83389B30 F02B -83389B31 F02C -83389B32 F02D -83389B33 F02E -83389B34 F02F -83389B35 F030 -83389B36 F031 -83389B37 F032 -83389B38 F033 -83389B39 F034 -83389C30 F035 -83389C31 F036 -83389C32 F037 -83389C33 F038 -83389C34 F039 -83389C35 F03A -83389C36 F03B -83389C37 F03C -83389C38 F03D -83389C39 F03E -83389D30 F03F -83389D31 F040 -83389D32 F041 -83389D33 F042 -83389D34 F043 -83389D35 F044 -83389D36 F045 -83389D37 F046 -83389D38 F047 -83389D39 F048 -83389E30 F049 -83389E31 F04A -83389E32 F04B -83389E33 F04C -83389E34 F04D -83389E35 F04E -83389E36 F04F -83389E37 F050 -83389E38 F051 -83389E39 F052 -83389F30 F053 -83389F31 F054 -83389F32 F055 -83389F33 F056 -83389F34 F057 -83389F35 F058 -83389F36 F059 -83389F37 F05A -83389F38 F05B -83389F39 F05C -8338A030 F05D -8338A031 F05E -8338A032 F05F -8338A033 F060 -8338A034 F061 -8338A035 F062 -8338A036 F063 -8338A037 F064 -8338A038 F065 -8338A039 F066 -8338A130 F067 -8338A131 F068 -8338A132 F069 -8338A133 F06A -8338A134 F06B -8338A135 F06C -8338A136 F06D -8338A137 F06E -8338A138 F06F -8338A139 F070 -8338A230 F071 -8338A231 F072 -8338A232 F073 -8338A233 F074 -8338A234 F075 -8338A235 F076 -8338A236 F077 -8338A237 F078 -8338A238 F079 -8338A239 F07A -8338A330 F07B -8338A331 F07C -8338A332 F07D -8338A333 F07E -8338A334 F07F -8338A335 F080 -8338A336 F081 -8338A337 F082 -8338A338 F083 -8338A339 F084 -8338A430 F085 -8338A431 F086 -8338A432 F087 -8338A433 F088 -8338A434 F089 -8338A435 F08A -8338A436 F08B -8338A437 F08C -8338A438 F08D -8338A439 F08E -8338A530 F08F -8338A531 F090 -8338A532 F091 -8338A533 F092 -8338A534 F093 -8338A535 F094 -8338A536 F095 -8338A537 F096 -8338A538 F097 -8338A539 F098 -8338A630 F099 -8338A631 F09A -8338A632 F09B -8338A633 F09C -8338A634 F09D -8338A635 F09E -8338A636 F09F -8338A637 F0A0 -8338A638 F0A1 -8338A639 F0A2 -8338A730 F0A3 -8338A731 F0A4 -8338A732 F0A5 -8338A733 F0A6 -8338A734 F0A7 -8338A735 F0A8 -8338A736 F0A9 -8338A737 F0AA -8338A738 F0AB -8338A739 F0AC -8338A830 F0AD -8338A831 F0AE -8338A832 F0AF -8338A833 F0B0 -8338A834 F0B1 -8338A835 F0B2 -8338A836 F0B3 -8338A837 F0B4 -8338A838 F0B5 -8338A839 F0B6 -8338A930 F0B7 -8338A931 F0B8 -8338A932 F0B9 -8338A933 F0BA -8338A934 F0BB -8338A935 F0BC -8338A936 F0BD -8338A937 F0BE -8338A938 F0BF -8338A939 F0C0 -8338AA30 F0C1 -8338AA31 F0C2 -8338AA32 F0C3 -8338AA33 F0C4 -8338AA34 F0C5 -8338AA35 F0C6 -8338AA36 F0C7 -8338AA37 F0C8 -8338AA38 F0C9 -8338AA39 F0CA -8338AB30 F0CB -8338AB31 F0CC -8338AB32 F0CD -8338AB33 F0CE -8338AB34 F0CF -8338AB35 F0D0 -8338AB36 F0D1 -8338AB37 F0D2 -8338AB38 F0D3 -8338AB39 F0D4 -8338AC30 F0D5 -8338AC31 F0D6 -8338AC32 F0D7 -8338AC33 F0D8 -8338AC34 F0D9 -8338AC35 F0DA -8338AC36 F0DB -8338AC37 F0DC -8338AC38 F0DD -8338AC39 F0DE -8338AD30 F0DF -8338AD31 F0E0 -8338AD32 F0E1 -8338AD33 F0E2 -8338AD34 F0E3 -8338AD35 F0E4 -8338AD36 F0E5 -8338AD37 F0E6 -8338AD38 F0E7 -8338AD39 F0E8 -8338AE30 F0E9 -8338AE31 F0EA -8338AE32 F0EB -8338AE33 F0EC -8338AE34 F0ED -8338AE35 F0EE -8338AE36 F0EF -8338AE37 F0F0 -8338AE38 F0F1 -8338AE39 F0F2 -8338AF30 F0F3 -8338AF31 F0F4 -8338AF32 F0F5 -8338AF33 F0F6 -8338AF34 F0F7 -8338AF35 F0F8 -8338AF36 F0F9 -8338AF37 F0FA -8338AF38 F0FB -8338AF39 F0FC -8338B030 F0FD -8338B031 F0FE -8338B032 F0FF -8338B033 F100 -8338B034 F101 -8338B035 F102 -8338B036 F103 -8338B037 F104 -8338B038 F105 -8338B039 F106 -8338B130 F107 -8338B131 F108 -8338B132 F109 -8338B133 F10A -8338B134 F10B -8338B135 F10C -8338B136 F10D -8338B137 F10E -8338B138 F10F -8338B139 F110 -8338B230 F111 -8338B231 F112 -8338B232 F113 -8338B233 F114 -8338B234 F115 -8338B235 F116 -8338B236 F117 -8338B237 F118 -8338B238 F119 -8338B239 F11A -8338B330 F11B -8338B331 F11C -8338B332 F11D -8338B333 F11E -8338B334 F11F -8338B335 F120 -8338B336 F121 -8338B337 F122 -8338B338 F123 -8338B339 F124 -8338B430 F125 -8338B431 F126 -8338B432 F127 -8338B433 F128 -8338B434 F129 -8338B435 F12A -8338B436 F12B -8338B437 F12C -8338B438 F12D -8338B439 F12E -8338B530 F12F -8338B531 F130 -8338B532 F131 -8338B533 F132 -8338B534 F133 -8338B535 F134 -8338B536 F135 -8338B537 F136 -8338B538 F137 -8338B539 F138 -8338B630 F139 -8338B631 F13A -8338B632 F13B -8338B633 F13C -8338B634 F13D -8338B635 F13E -8338B636 F13F -8338B637 F140 -8338B638 F141 -8338B639 F142 -8338B730 F143 -8338B731 F144 -8338B732 F145 -8338B733 F146 -8338B734 F147 -8338B735 F148 -8338B736 F149 -8338B737 F14A -8338B738 F14B -8338B739 F14C -8338B830 F14D -8338B831 F14E -8338B832 F14F -8338B833 F150 -8338B834 F151 -8338B835 F152 -8338B836 F153 -8338B837 F154 -8338B838 F155 -8338B839 F156 -8338B930 F157 -8338B931 F158 -8338B932 F159 -8338B933 F15A -8338B934 F15B -8338B935 F15C -8338B936 F15D -8338B937 F15E -8338B938 F15F -8338B939 F160 -8338BA30 F161 -8338BA31 F162 -8338BA32 F163 -8338BA33 F164 -8338BA34 F165 -8338BA35 F166 -8338BA36 F167 -8338BA37 F168 -8338BA38 F169 -8338BA39 F16A -8338BB30 F16B -8338BB31 F16C -8338BB32 F16D -8338BB33 F16E -8338BB34 F16F -8338BB35 F170 -8338BB36 F171 -8338BB37 F172 -8338BB38 F173 -8338BB39 F174 -8338BC30 F175 -8338BC31 F176 -8338BC32 F177 -8338BC33 F178 -8338BC34 F179 -8338BC35 F17A -8338BC36 F17B -8338BC37 F17C -8338BC38 F17D -8338BC39 F17E -8338BD30 F17F -8338BD31 F180 -8338BD32 F181 -8338BD33 F182 -8338BD34 F183 -8338BD35 F184 -8338BD36 F185 -8338BD37 F186 -8338BD38 F187 -8338BD39 F188 -8338BE30 F189 -8338BE31 F18A -8338BE32 F18B -8338BE33 F18C -8338BE34 F18D -8338BE35 F18E -8338BE36 F18F -8338BE37 F190 -8338BE38 F191 -8338BE39 F192 -8338BF30 F193 -8338BF31 F194 -8338BF32 F195 -8338BF33 F196 -8338BF34 F197 -8338BF35 F198 -8338BF36 F199 -8338BF37 F19A -8338BF38 F19B -8338BF39 F19C -8338C030 F19D -8338C031 F19E -8338C032 F19F -8338C033 F1A0 -8338C034 F1A1 -8338C035 F1A2 -8338C036 F1A3 -8338C037 F1A4 -8338C038 F1A5 -8338C039 F1A6 -8338C130 F1A7 -8338C131 F1A8 -8338C132 F1A9 -8338C133 F1AA -8338C134 F1AB -8338C135 F1AC -8338C136 F1AD -8338C137 F1AE -8338C138 F1AF -8338C139 F1B0 -8338C230 F1B1 -8338C231 F1B2 -8338C232 F1B3 -8338C233 F1B4 -8338C234 F1B5 -8338C235 F1B6 -8338C236 F1B7 -8338C237 F1B8 -8338C238 F1B9 -8338C239 F1BA -8338C330 F1BB -8338C331 F1BC -8338C332 F1BD -8338C333 F1BE -8338C334 F1BF -8338C335 F1C0 -8338C336 F1C1 -8338C337 F1C2 -8338C338 F1C3 -8338C339 F1C4 -8338C430 F1C5 -8338C431 F1C6 -8338C432 F1C7 -8338C433 F1C8 -8338C434 F1C9 -8338C435 F1CA -8338C436 F1CB -8338C437 F1CC -8338C438 F1CD -8338C439 F1CE -8338C530 F1CF -8338C531 F1D0 -8338C532 F1D1 -8338C533 F1D2 -8338C534 F1D3 -8338C535 F1D4 -8338C536 F1D5 -8338C537 F1D6 -8338C538 F1D7 -8338C539 F1D8 -8338C630 F1D9 -8338C631 F1DA -8338C632 F1DB -8338C633 F1DC -8338C634 F1DD -8338C635 F1DE -8338C636 F1DF -8338C637 F1E0 -8338C638 F1E1 -8338C639 F1E2 -8338C730 F1E3 -8338C731 F1E4 -8338C732 F1E5 -8338C733 F1E6 -8338C734 F1E7 -8338C735 F1E8 -8338C736 F1E9 -8338C737 F1EA -8338C738 F1EB -8338C739 F1EC -8338C830 F1ED -8338C831 F1EE -8338C832 F1EF -8338C833 F1F0 -8338C834 F1F1 -8338C835 F1F2 -8338C836 F1F3 -8338C837 F1F4 -8338C838 F1F5 -8338C839 F1F6 -8338C930 F1F7 -8338C931 F1F8 -8338C932 F1F9 -8338C933 F1FA -8338C934 F1FB -8338C935 F1FC -8338C936 F1FD -8338C937 F1FE -8338C938 F1FF -8338C939 F200 -8338CA30 F201 -8338CA31 F202 -8338CA32 F203 -8338CA33 F204 -8338CA34 F205 -8338CA35 F206 -8338CA36 F207 -8338CA37 F208 -8338CA38 F209 -8338CA39 F20A -8338CB30 F20B -8338CB31 F20C -8338CB32 F20D -8338CB33 F20E -8338CB34 F20F -8338CB35 F210 -8338CB36 F211 -8338CB37 F212 -8338CB38 F213 -8338CB39 F214 -8338CC30 F215 -8338CC31 F216 -8338CC32 F217 -8338CC33 F218 -8338CC34 F219 -8338CC35 F21A -8338CC36 F21B -8338CC37 F21C -8338CC38 F21D -8338CC39 F21E -8338CD30 F21F -8338CD31 F220 -8338CD32 F221 -8338CD33 F222 -8338CD34 F223 -8338CD35 F224 -8338CD36 F225 -8338CD37 F226 -8338CD38 F227 -8338CD39 F228 -8338CE30 F229 -8338CE31 F22A -8338CE32 F22B -8338CE33 F22C -8338CE34 F22D -8338CE35 F22E -8338CE36 F22F -8338CE37 F230 -8338CE38 F231 -8338CE39 F232 -8338CF30 F233 -8338CF31 F234 -8338CF32 F235 -8338CF33 F236 -8338CF34 F237 -8338CF35 F238 -8338CF36 F239 -8338CF37 F23A -8338CF38 F23B -8338CF39 F23C -8338D030 F23D -8338D031 F23E -8338D032 F23F -8338D033 F240 -8338D034 F241 -8338D035 F242 -8338D036 F243 -8338D037 F244 -8338D038 F245 -8338D039 F246 -8338D130 F247 -8338D131 F248 -8338D132 F249 -8338D133 F24A -8338D134 F24B -8338D135 F24C -8338D136 F24D -8338D137 F24E -8338D138 F24F -8338D139 F250 -8338D230 F251 -8338D231 F252 -8338D232 F253 -8338D233 F254 -8338D234 F255 -8338D235 F256 -8338D236 F257 -8338D237 F258 -8338D238 F259 -8338D239 F25A -8338D330 F25B -8338D331 F25C -8338D332 F25D -8338D333 F25E -8338D334 F25F -8338D335 F260 -8338D336 F261 -8338D337 F262 -8338D338 F263 -8338D339 F264 -8338D430 F265 -8338D431 F266 -8338D432 F267 -8338D433 F268 -8338D434 F269 -8338D435 F26A -8338D436 F26B -8338D437 F26C -8338D438 F26D -8338D439 F26E -8338D530 F26F -8338D531 F270 -8338D532 F271 -8338D533 F272 -8338D534 F273 -8338D535 F274 -8338D536 F275 -8338D537 F276 -8338D538 F277 -8338D539 F278 -8338D630 F279 -8338D631 F27A -8338D632 F27B -8338D633 F27C -8338D634 F27D -8338D635 F27E -8338D636 F27F -8338D637 F280 -8338D638 F281 -8338D639 F282 -8338D730 F283 -8338D731 F284 -8338D732 F285 -8338D733 F286 -8338D734 F287 -8338D735 F288 -8338D736 F289 -8338D737 F28A -8338D738 F28B -8338D739 F28C -8338D830 F28D -8338D831 F28E -8338D832 F28F -8338D833 F290 -8338D834 F291 -8338D835 F292 -8338D836 F293 -8338D837 F294 -8338D838 F295 -8338D839 F296 -8338D930 F297 -8338D931 F298 -8338D932 F299 -8338D933 F29A -8338D934 F29B -8338D935 F29C -8338D936 F29D -8338D937 F29E -8338D938 F29F -8338D939 F2A0 -8338DA30 F2A1 -8338DA31 F2A2 -8338DA32 F2A3 -8338DA33 F2A4 -8338DA34 F2A5 -8338DA35 F2A6 -8338DA36 F2A7 -8338DA37 F2A8 -8338DA38 F2A9 -8338DA39 F2AA -8338DB30 F2AB -8338DB31 F2AC -8338DB32 F2AD -8338DB33 F2AE -8338DB34 F2AF -8338DB35 F2B0 -8338DB36 F2B1 -8338DB37 F2B2 -8338DB38 F2B3 -8338DB39 F2B4 -8338DC30 F2B5 -8338DC31 F2B6 -8338DC32 F2B7 -8338DC33 F2B8 -8338DC34 F2B9 -8338DC35 F2BA -8338DC36 F2BB -8338DC37 F2BC -8338DC38 F2BD -8338DC39 F2BE -8338DD30 F2BF -8338DD31 F2C0 -8338DD32 F2C1 -8338DD33 F2C2 -8338DD34 F2C3 -8338DD35 F2C4 -8338DD36 F2C5 -8338DD37 F2C6 -8338DD38 F2C7 -8338DD39 F2C8 -8338DE30 F2C9 -8338DE31 F2CA -8338DE32 F2CB -8338DE33 F2CC -8338DE34 F2CD -8338DE35 F2CE -8338DE36 F2CF -8338DE37 F2D0 -8338DE38 F2D1 -8338DE39 F2D2 -8338DF30 F2D3 -8338DF31 F2D4 -8338DF32 F2D5 -8338DF33 F2D6 -8338DF34 F2D7 -8338DF35 F2D8 -8338DF36 F2D9 -8338DF37 F2DA -8338DF38 F2DB -8338DF39 F2DC -8338E030 F2DD -8338E031 F2DE -8338E032 F2DF -8338E033 F2E0 -8338E034 F2E1 -8338E035 F2E2 -8338E036 F2E3 -8338E037 F2E4 -8338E038 F2E5 -8338E039 F2E6 -8338E130 F2E7 -8338E131 F2E8 -8338E132 F2E9 -8338E133 F2EA -8338E134 F2EB -8338E135 F2EC -8338E136 F2ED -8338E137 F2EE -8338E138 F2EF -8338E139 F2F0 -8338E230 F2F1 -8338E231 F2F2 -8338E232 F2F3 -8338E233 F2F4 -8338E234 F2F5 -8338E235 F2F6 -8338E236 F2F7 -8338E237 F2F8 -8338E238 F2F9 -8338E239 F2FA -8338E330 F2FB -8338E331 F2FC -8338E332 F2FD -8338E333 F2FE -8338E334 F2FF -8338E335 F300 -8338E336 F301 -8338E337 F302 -8338E338 F303 -8338E339 F304 -8338E430 F305 -8338E431 F306 -8338E432 F307 -8338E433 F308 -8338E434 F309 -8338E435 F30A -8338E436 F30B -8338E437 F30C -8338E438 F30D -8338E439 F30E -8338E530 F30F -8338E531 F310 -8338E532 F311 -8338E533 F312 -8338E534 F313 -8338E535 F314 -8338E536 F315 -8338E537 F316 -8338E538 F317 -8338E539 F318 -8338E630 F319 -8338E631 F31A -8338E632 F31B -8338E633 F31C -8338E634 F31D -8338E635 F31E -8338E636 F31F -8338E637 F320 -8338E638 F321 -8338E639 F322 -8338E730 F323 -8338E731 F324 -8338E732 F325 -8338E733 F326 -8338E734 F327 -8338E735 F328 -8338E736 F329 -8338E737 F32A -8338E738 F32B -8338E739 F32C -8338E830 F32D -8338E831 F32E -8338E832 F32F -8338E833 F330 -8338E834 F331 -8338E835 F332 -8338E836 F333 -8338E837 F334 -8338E838 F335 -8338E839 F336 -8338E930 F337 -8338E931 F338 -8338E932 F339 -8338E933 F33A -8338E934 F33B -8338E935 F33C -8338E936 F33D -8338E937 F33E -8338E938 F33F -8338E939 F340 -8338EA30 F341 -8338EA31 F342 -8338EA32 F343 -8338EA33 F344 -8338EA34 F345 -8338EA35 F346 -8338EA36 F347 -8338EA37 F348 -8338EA38 F349 -8338EA39 F34A -8338EB30 F34B -8338EB31 F34C -8338EB32 F34D -8338EB33 F34E -8338EB34 F34F -8338EB35 F350 -8338EB36 F351 -8338EB37 F352 -8338EB38 F353 -8338EB39 F354 -8338EC30 F355 -8338EC31 F356 -8338EC32 F357 -8338EC33 F358 -8338EC34 F359 -8338EC35 F35A -8338EC36 F35B -8338EC37 F35C -8338EC38 F35D -8338EC39 F35E -8338ED30 F35F -8338ED31 F360 -8338ED32 F361 -8338ED33 F362 -8338ED34 F363 -8338ED35 F364 -8338ED36 F365 -8338ED37 F366 -8338ED38 F367 -8338ED39 F368 -8338EE30 F369 -8338EE31 F36A -8338EE32 F36B -8338EE33 F36C -8338EE34 F36D -8338EE35 F36E -8338EE36 F36F -8338EE37 F370 -8338EE38 F371 -8338EE39 F372 -8338EF30 F373 -8338EF31 F374 -8338EF32 F375 -8338EF33 F376 -8338EF34 F377 -8338EF35 F378 -8338EF36 F379 -8338EF37 F37A -8338EF38 F37B -8338EF39 F37C -8338F030 F37D -8338F031 F37E -8338F032 F37F -8338F033 F380 -8338F034 F381 -8338F035 F382 -8338F036 F383 -8338F037 F384 -8338F038 F385 -8338F039 F386 -8338F130 F387 -8338F131 F388 -8338F132 F389 -8338F133 F38A -8338F134 F38B -8338F135 F38C -8338F136 F38D -8338F137 F38E -8338F138 F38F -8338F139 F390 -8338F230 F391 -8338F231 F392 -8338F232 F393 -8338F233 F394 -8338F234 F395 -8338F235 F396 -8338F236 F397 -8338F237 F398 -8338F238 F399 -8338F239 F39A -8338F330 F39B -8338F331 F39C -8338F332 F39D -8338F333 F39E -8338F334 F39F -8338F335 F3A0 -8338F336 F3A1 -8338F337 F3A2 -8338F338 F3A3 -8338F339 F3A4 -8338F430 F3A5 -8338F431 F3A6 -8338F432 F3A7 -8338F433 F3A8 -8338F434 F3A9 -8338F435 F3AA -8338F436 F3AB -8338F437 F3AC -8338F438 F3AD -8338F439 F3AE -8338F530 F3AF -8338F531 F3B0 -8338F532 F3B1 -8338F533 F3B2 -8338F534 F3B3 -8338F535 F3B4 -8338F536 F3B5 -8338F537 F3B6 -8338F538 F3B7 -8338F539 F3B8 -8338F630 F3B9 -8338F631 F3BA -8338F632 F3BB -8338F633 F3BC -8338F634 F3BD -8338F635 F3BE -8338F636 F3BF -8338F637 F3C0 -8338F638 F3C1 -8338F639 F3C2 -8338F730 F3C3 -8338F731 F3C4 -8338F732 F3C5 -8338F733 F3C6 -8338F734 F3C7 -8338F735 F3C8 -8338F736 F3C9 -8338F737 F3CA -8338F738 F3CB -8338F739 F3CC -8338F830 F3CD -8338F831 F3CE -8338F832 F3CF -8338F833 F3D0 -8338F834 F3D1 -8338F835 F3D2 -8338F836 F3D3 -8338F837 F3D4 -8338F838 F3D5 -8338F839 F3D6 -8338F930 F3D7 -8338F931 F3D8 -8338F932 F3D9 -8338F933 F3DA -8338F934 F3DB -8338F935 F3DC -8338F936 F3DD -8338F937 F3DE -8338F938 F3DF -8338F939 F3E0 -8338FA30 F3E1 -8338FA31 F3E2 -8338FA32 F3E3 -8338FA33 F3E4 -8338FA34 F3E5 -8338FA35 F3E6 -8338FA36 F3E7 -8338FA37 F3E8 -8338FA38 F3E9 -8338FA39 F3EA -8338FB30 F3EB -8338FB31 F3EC -8338FB32 F3ED -8338FB33 F3EE -8338FB34 F3EF -8338FB35 F3F0 -8338FB36 F3F1 -8338FB37 F3F2 -8338FB38 F3F3 -8338FB39 F3F4 -8338FC30 F3F5 -8338FC31 F3F6 -8338FC32 F3F7 -8338FC33 F3F8 -8338FC34 F3F9 -8338FC35 F3FA -8338FC36 F3FB -8338FC37 F3FC -8338FC38 F3FD -8338FC39 F3FE -8338FD30 F3FF -8338FD31 F400 -8338FD32 F401 -8338FD33 F402 -8338FD34 F403 -8338FD35 F404 -8338FD36 F405 -8338FD37 F406 -8338FD38 F407 -8338FD39 F408 -8338FE30 F409 -8338FE31 F40A -8338FE32 F40B -8338FE33 F40C -8338FE34 F40D -8338FE35 F40E -8338FE36 F40F -8338FE37 F410 -8338FE38 F411 -8338FE39 F412 -83398130 F413 -83398131 F414 -83398132 F415 -83398133 F416 -83398134 F417 -83398135 F418 -83398136 F419 -83398137 F41A -83398138 F41B -83398139 F41C -83398230 F41D -83398231 F41E -83398232 F41F -83398233 F420 -83398234 F421 -83398235 F422 -83398236 F423 -83398237 F424 -83398238 F425 -83398239 F426 -83398330 F427 -83398331 F428 -83398332 F429 -83398333 F42A -83398334 F42B -83398335 F42C -83398336 F42D -83398337 F42E -83398338 F42F -83398339 F430 -83398430 F431 -83398431 F432 -83398432 F433 -83398433 F434 -83398434 F435 -83398435 F436 -83398436 F437 -83398437 F438 -83398438 F439 -83398439 F43A -83398530 F43B -83398531 F43C -83398532 F43D -83398533 F43E -83398534 F43F -83398535 F440 -83398536 F441 -83398537 F442 -83398538 F443 -83398539 F444 -83398630 F445 -83398631 F446 -83398632 F447 -83398633 F448 -83398634 F449 -83398635 F44A -83398636 F44B -83398637 F44C -83398638 F44D -83398639 F44E -83398730 F44F -83398731 F450 -83398732 F451 -83398733 F452 -83398734 F453 -83398735 F454 -83398736 F455 -83398737 F456 -83398738 F457 -83398739 F458 -83398830 F459 -83398831 F45A -83398832 F45B -83398833 F45C -83398834 F45D -83398835 F45E -83398836 F45F -83398837 F460 -83398838 F461 -83398839 F462 -83398930 F463 -83398931 F464 -83398932 F465 -83398933 F466 -83398934 F467 -83398935 F468 -83398936 F469 -83398937 F46A -83398938 F46B -83398939 F46C -83398A30 F46D -83398A31 F46E -83398A32 F46F -83398A33 F470 -83398A34 F471 -83398A35 F472 -83398A36 F473 -83398A37 F474 -83398A38 F475 -83398A39 F476 -83398B30 F477 -83398B31 F478 -83398B32 F479 -83398B33 F47A -83398B34 F47B -83398B35 F47C -83398B36 F47D -83398B37 F47E -83398B38 F47F -83398B39 F480 -83398C30 F481 -83398C31 F482 -83398C32 F483 -83398C33 F484 -83398C34 F485 -83398C35 F486 -83398C36 F487 -83398C37 F488 -83398C38 F489 -83398C39 F48A -83398D30 F48B -83398D31 F48C -83398D32 F48D -83398D33 F48E -83398D34 F48F -83398D35 F490 -83398D36 F491 -83398D37 F492 -83398D38 F493 -83398D39 F494 -83398E30 F495 -83398E31 F496 -83398E32 F497 -83398E33 F498 -83398E34 F499 -83398E35 F49A -83398E36 F49B -83398E37 F49C -83398E38 F49D -83398E39 F49E -83398F30 F49F -83398F31 F4A0 -83398F32 F4A1 -83398F33 F4A2 -83398F34 F4A3 -83398F35 F4A4 -83398F36 F4A5 -83398F37 F4A6 -83398F38 F4A7 -83398F39 F4A8 -83399030 F4A9 -83399031 F4AA -83399032 F4AB -83399033 F4AC -83399034 F4AD -83399035 F4AE -83399036 F4AF -83399037 F4B0 -83399038 F4B1 -83399039 F4B2 -83399130 F4B3 -83399131 F4B4 -83399132 F4B5 -83399133 F4B6 -83399134 F4B7 -83399135 F4B8 -83399136 F4B9 -83399137 F4BA -83399138 F4BB -83399139 F4BC -83399230 F4BD -83399231 F4BE -83399232 F4BF -83399233 F4C0 -83399234 F4C1 -83399235 F4C2 -83399236 F4C3 -83399237 F4C4 -83399238 F4C5 -83399239 F4C6 -83399330 F4C7 -83399331 F4C8 -83399332 F4C9 -83399333 F4CA -83399334 F4CB -83399335 F4CC -83399336 F4CD -83399337 F4CE -83399338 F4CF -83399339 F4D0 -83399430 F4D1 -83399431 F4D2 -83399432 F4D3 -83399433 F4D4 -83399434 F4D5 -83399435 F4D6 -83399436 F4D7 -83399437 F4D8 -83399438 F4D9 -83399439 F4DA -83399530 F4DB -83399531 F4DC -83399532 F4DD -83399533 F4DE -83399534 F4DF -83399535 F4E0 -83399536 F4E1 -83399537 F4E2 -83399538 F4E3 -83399539 F4E4 -83399630 F4E5 -83399631 F4E6 -83399632 F4E7 -83399633 F4E8 -83399634 F4E9 -83399635 F4EA -83399636 F4EB -83399637 F4EC -83399638 F4ED -83399639 F4EE -83399730 F4EF -83399731 F4F0 -83399732 F4F1 -83399733 F4F2 -83399734 F4F3 -83399735 F4F4 -83399736 F4F5 -83399737 F4F6 -83399738 F4F7 -83399739 F4F8 -83399830 F4F9 -83399831 F4FA -83399832 F4FB -83399833 F4FC -83399834 F4FD -83399835 F4FE -83399836 F4FF -83399837 F500 -83399838 F501 -83399839 F502 -83399930 F503 -83399931 F504 -83399932 F505 -83399933 F506 -83399934 F507 -83399935 F508 -83399936 F509 -83399937 F50A -83399938 F50B -83399939 F50C -83399A30 F50D -83399A31 F50E -83399A32 F50F -83399A33 F510 -83399A34 F511 -83399A35 F512 -83399A36 F513 -83399A37 F514 -83399A38 F515 -83399A39 F516 -83399B30 F517 -83399B31 F518 -83399B32 F519 -83399B33 F51A -83399B34 F51B -83399B35 F51C -83399B36 F51D -83399B37 F51E -83399B38 F51F -83399B39 F520 -83399C30 F521 -83399C31 F522 -83399C32 F523 -83399C33 F524 -83399C34 F525 -83399C35 F526 -83399C36 F527 -83399C37 F528 -83399C38 F529 -83399C39 F52A -83399D30 F52B -83399D31 F52C -83399D32 F52D -83399D33 F52E -83399D34 F52F -83399D35 F530 -83399D36 F531 -83399D37 F532 -83399D38 F533 -83399D39 F534 -83399E30 F535 -83399E31 F536 -83399E32 F537 -83399E33 F538 -83399E34 F539 -83399E35 F53A -83399E36 F53B -83399E37 F53C -83399E38 F53D -83399E39 F53E -83399F30 F53F -83399F31 F540 -83399F32 F541 -83399F33 F542 -83399F34 F543 -83399F35 F544 -83399F36 F545 -83399F37 F546 -83399F38 F547 -83399F39 F548 -8339A030 F549 -8339A031 F54A -8339A032 F54B -8339A033 F54C -8339A034 F54D -8339A035 F54E -8339A036 F54F -8339A037 F550 -8339A038 F551 -8339A039 F552 -8339A130 F553 -8339A131 F554 -8339A132 F555 -8339A133 F556 -8339A134 F557 -8339A135 F558 -8339A136 F559 -8339A137 F55A -8339A138 F55B -8339A139 F55C -8339A230 F55D -8339A231 F55E -8339A232 F55F -8339A233 F560 -8339A234 F561 -8339A235 F562 -8339A236 F563 -8339A237 F564 -8339A238 F565 -8339A239 F566 -8339A330 F567 -8339A331 F568 -8339A332 F569 -8339A333 F56A -8339A334 F56B -8339A335 F56C -8339A336 F56D -8339A337 F56E -8339A338 F56F -8339A339 F570 -8339A430 F571 -8339A431 F572 -8339A432 F573 -8339A433 F574 -8339A434 F575 -8339A435 F576 -8339A436 F577 -8339A437 F578 -8339A438 F579 -8339A439 F57A -8339A530 F57B -8339A531 F57C -8339A532 F57D -8339A533 F57E -8339A534 F57F -8339A535 F580 -8339A536 F581 -8339A537 F582 -8339A538 F583 -8339A539 F584 -8339A630 F585 -8339A631 F586 -8339A632 F587 -8339A633 F588 -8339A634 F589 -8339A635 F58A -8339A636 F58B -8339A637 F58C -8339A638 F58D -8339A639 F58E -8339A730 F58F -8339A731 F590 -8339A732 F591 -8339A733 F592 -8339A734 F593 -8339A735 F594 -8339A736 F595 -8339A737 F596 -8339A738 F597 -8339A739 F598 -8339A830 F599 -8339A831 F59A -8339A832 F59B -8339A833 F59C -8339A834 F59D -8339A835 F59E -8339A836 F59F -8339A837 F5A0 -8339A838 F5A1 -8339A839 F5A2 -8339A930 F5A3 -8339A931 F5A4 -8339A932 F5A5 -8339A933 F5A6 -8339A934 F5A7 -8339A935 F5A8 -8339A936 F5A9 -8339A937 F5AA -8339A938 F5AB -8339A939 F5AC -8339AA30 F5AD -8339AA31 F5AE -8339AA32 F5AF -8339AA33 F5B0 -8339AA34 F5B1 -8339AA35 F5B2 -8339AA36 F5B3 -8339AA37 F5B4 -8339AA38 F5B5 -8339AA39 F5B6 -8339AB30 F5B7 -8339AB31 F5B8 -8339AB32 F5B9 -8339AB33 F5BA -8339AB34 F5BB -8339AB35 F5BC -8339AB36 F5BD -8339AB37 F5BE -8339AB38 F5BF -8339AB39 F5C0 -8339AC30 F5C1 -8339AC31 F5C2 -8339AC32 F5C3 -8339AC33 F5C4 -8339AC34 F5C5 -8339AC35 F5C6 -8339AC36 F5C7 -8339AC37 F5C8 -8339AC38 F5C9 -8339AC39 F5CA -8339AD30 F5CB -8339AD31 F5CC -8339AD32 F5CD -8339AD33 F5CE -8339AD34 F5CF -8339AD35 F5D0 -8339AD36 F5D1 -8339AD37 F5D2 -8339AD38 F5D3 -8339AD39 F5D4 -8339AE30 F5D5 -8339AE31 F5D6 -8339AE32 F5D7 -8339AE33 F5D8 -8339AE34 F5D9 -8339AE35 F5DA -8339AE36 F5DB -8339AE37 F5DC -8339AE38 F5DD -8339AE39 F5DE -8339AF30 F5DF -8339AF31 F5E0 -8339AF32 F5E1 -8339AF33 F5E2 -8339AF34 F5E3 -8339AF35 F5E4 -8339AF36 F5E5 -8339AF37 F5E6 -8339AF38 F5E7 -8339AF39 F5E8 -8339B030 F5E9 -8339B031 F5EA -8339B032 F5EB -8339B033 F5EC -8339B034 F5ED -8339B035 F5EE -8339B036 F5EF -8339B037 F5F0 -8339B038 F5F1 -8339B039 F5F2 -8339B130 F5F3 -8339B131 F5F4 -8339B132 F5F5 -8339B133 F5F6 -8339B134 F5F7 -8339B135 F5F8 -8339B136 F5F9 -8339B137 F5FA -8339B138 F5FB -8339B139 F5FC -8339B230 F5FD -8339B231 F5FE -8339B232 F5FF -8339B233 F600 -8339B234 F601 -8339B235 F602 -8339B236 F603 -8339B237 F604 -8339B238 F605 -8339B239 F606 -8339B330 F607 -8339B331 F608 -8339B332 F609 -8339B333 F60A -8339B334 F60B -8339B335 F60C -8339B336 F60D -8339B337 F60E -8339B338 F60F -8339B339 F610 -8339B430 F611 -8339B431 F612 -8339B432 F613 -8339B433 F614 -8339B434 F615 -8339B435 F616 -8339B436 F617 -8339B437 F618 -8339B438 F619 -8339B439 F61A -8339B530 F61B -8339B531 F61C -8339B532 F61D -8339B533 F61E -8339B534 F61F -8339B535 F620 -8339B536 F621 -8339B537 F622 -8339B538 F623 -8339B539 F624 -8339B630 F625 -8339B631 F626 -8339B632 F627 -8339B633 F628 -8339B634 F629 -8339B635 F62A -8339B636 F62B -8339B637 F62C -8339B638 F62D -8339B639 F62E -8339B730 F62F -8339B731 F630 -8339B732 F631 -8339B733 F632 -8339B734 F633 -8339B735 F634 -8339B736 F635 -8339B737 F636 -8339B738 F637 -8339B739 F638 -8339B830 F639 -8339B831 F63A -8339B832 F63B -8339B833 F63C -8339B834 F63D -8339B835 F63E -8339B836 F63F -8339B837 F640 -8339B838 F641 -8339B839 F642 -8339B930 F643 -8339B931 F644 -8339B932 F645 -8339B933 F646 -8339B934 F647 -8339B935 F648 -8339B936 F649 -8339B937 F64A -8339B938 F64B -8339B939 F64C -8339BA30 F64D -8339BA31 F64E -8339BA32 F64F -8339BA33 F650 -8339BA34 F651 -8339BA35 F652 -8339BA36 F653 -8339BA37 F654 -8339BA38 F655 -8339BA39 F656 -8339BB30 F657 -8339BB31 F658 -8339BB32 F659 -8339BB33 F65A -8339BB34 F65B -8339BB35 F65C -8339BB36 F65D -8339BB37 F65E -8339BB38 F65F -8339BB39 F660 -8339BC30 F661 -8339BC31 F662 -8339BC32 F663 -8339BC33 F664 -8339BC34 F665 -8339BC35 F666 -8339BC36 F667 -8339BC37 F668 -8339BC38 F669 -8339BC39 F66A -8339BD30 F66B -8339BD31 F66C -8339BD32 F66D -8339BD33 F66E -8339BD34 F66F -8339BD35 F670 -8339BD36 F671 -8339BD37 F672 -8339BD38 F673 -8339BD39 F674 -8339BE30 F675 -8339BE31 F676 -8339BE32 F677 -8339BE33 F678 -8339BE34 F679 -8339BE35 F67A -8339BE36 F67B -8339BE37 F67C -8339BE38 F67D -8339BE39 F67E -8339BF30 F67F -8339BF31 F680 -8339BF32 F681 -8339BF33 F682 -8339BF34 F683 -8339BF35 F684 -8339BF36 F685 -8339BF37 F686 -8339BF38 F687 -8339BF39 F688 -8339C030 F689 -8339C031 F68A -8339C032 F68B -8339C033 F68C -8339C034 F68D -8339C035 F68E -8339C036 F68F -8339C037 F690 -8339C038 F691 -8339C039 F692 -8339C130 F693 -8339C131 F694 -8339C132 F695 -8339C133 F696 -8339C134 F697 -8339C135 F698 -8339C136 F699 -8339C137 F69A -8339C138 F69B -8339C139 F69C -8339C230 F69D -8339C231 F69E -8339C232 F69F -8339C233 F6A0 -8339C234 F6A1 -8339C235 F6A2 -8339C236 F6A3 -8339C237 F6A4 -8339C238 F6A5 -8339C239 F6A6 -8339C330 F6A7 -8339C331 F6A8 -8339C332 F6A9 -8339C333 F6AA -8339C334 F6AB -8339C335 F6AC -8339C336 F6AD -8339C337 F6AE -8339C338 F6AF -8339C339 F6B0 -8339C430 F6B1 -8339C431 F6B2 -8339C432 F6B3 -8339C433 F6B4 -8339C434 F6B5 -8339C435 F6B6 -8339C436 F6B7 -8339C437 F6B8 -8339C438 F6B9 -8339C439 F6BA -8339C530 F6BB -8339C531 F6BC -8339C532 F6BD -8339C533 F6BE -8339C534 F6BF -8339C535 F6C0 -8339C536 F6C1 -8339C537 F6C2 -8339C538 F6C3 -8339C539 F6C4 -8339C630 F6C5 -8339C631 F6C6 -8339C632 F6C7 -8339C633 F6C8 -8339C634 F6C9 -8339C635 F6CA -8339C636 F6CB -8339C637 F6CC -8339C638 F6CD -8339C639 F6CE -8339C730 F6CF -8339C731 F6D0 -8339C732 F6D1 -8339C733 F6D2 -8339C734 F6D3 -8339C735 F6D4 -8339C736 F6D5 -8339C737 F6D6 -8339C738 F6D7 -8339C739 F6D8 -8339C830 F6D9 -8339C831 F6DA -8339C832 F6DB -8339C833 F6DC -8339C834 F6DD -8339C835 F6DE -8339C836 F6DF -8339C837 F6E0 -8339C838 F6E1 -8339C839 F6E2 -8339C930 F6E3 -8339C931 F6E4 -8339C932 F6E5 -8339C933 F6E6 -8339C934 F6E7 -8339C935 F6E8 -8339C936 F6E9 -8339C937 F6EA -8339C938 F6EB -8339C939 F6EC -8339CA30 F6ED -8339CA31 F6EE -8339CA32 F6EF -8339CA33 F6F0 -8339CA34 F6F1 -8339CA35 F6F2 -8339CA36 F6F3 -8339CA37 F6F4 -8339CA38 F6F5 -8339CA39 F6F6 -8339CB30 F6F7 -8339CB31 F6F8 -8339CB32 F6F9 -8339CB33 F6FA -8339CB34 F6FB -8339CB35 F6FC -8339CB36 F6FD -8339CB37 F6FE -8339CB38 F6FF -8339CB39 F700 -8339CC30 F701 -8339CC31 F702 -8339CC32 F703 -8339CC33 F704 -8339CC34 F705 -8339CC35 F706 -8339CC36 F707 -8339CC37 F708 -8339CC38 F709 -8339CC39 F70A -8339CD30 F70B -8339CD31 F70C -8339CD32 F70D -8339CD33 F70E -8339CD34 F70F -8339CD35 F710 -8339CD36 F711 -8339CD37 F712 -8339CD38 F713 -8339CD39 F714 -8339CE30 F715 -8339CE31 F716 -8339CE32 F717 -8339CE33 F718 -8339CE34 F719 -8339CE35 F71A -8339CE36 F71B -8339CE37 F71C -8339CE38 F71D -8339CE39 F71E -8339CF30 F71F -8339CF31 F720 -8339CF32 F721 -8339CF33 F722 -8339CF34 F723 -8339CF35 F724 -8339CF36 F725 -8339CF37 F726 -8339CF38 F727 -8339CF39 F728 -8339D030 F729 -8339D031 F72A -8339D032 F72B -8339D033 F72C -8339D034 F72D -8339D035 F72E -8339D036 F72F -8339D037 F730 -8339D038 F731 -8339D039 F732 -8339D130 F733 -8339D131 F734 -8339D132 F735 -8339D133 F736 -8339D134 F737 -8339D135 F738 -8339D136 F739 -8339D137 F73A -8339D138 F73B -8339D139 F73C -8339D230 F73D -8339D231 F73E -8339D232 F73F -8339D233 F740 -8339D234 F741 -8339D235 F742 -8339D236 F743 -8339D237 F744 -8339D238 F745 -8339D239 F746 -8339D330 F747 -8339D331 F748 -8339D332 F749 -8339D333 F74A -8339D334 F74B -8339D335 F74C -8339D336 F74D -8339D337 F74E -8339D338 F74F -8339D339 F750 -8339D430 F751 -8339D431 F752 -8339D432 F753 -8339D433 F754 -8339D434 F755 -8339D435 F756 -8339D436 F757 -8339D437 F758 -8339D438 F759 -8339D439 F75A -8339D530 F75B -8339D531 F75C -8339D532 F75D -8339D533 F75E -8339D534 F75F -8339D535 F760 -8339D536 F761 -8339D537 F762 -8339D538 F763 -8339D539 F764 -8339D630 F765 -8339D631 F766 -8339D632 F767 -8339D633 F768 -8339D634 F769 -8339D635 F76A -8339D636 F76B -8339D637 F76C -8339D638 F76D -8339D639 F76E -8339D730 F76F -8339D731 F770 -8339D732 F771 -8339D733 F772 -8339D734 F773 -8339D735 F774 -8339D736 F775 -8339D737 F776 -8339D738 F777 -8339D739 F778 -8339D830 F779 -8339D831 F77A -8339D832 F77B -8339D833 F77C -8339D834 F77D -8339D835 F77E -8339D836 F77F -8339D837 F780 -8339D838 F781 -8339D839 F782 -8339D930 F783 -8339D931 F784 -8339D932 F785 -8339D933 F786 -8339D934 F787 -8339D935 F788 -8339D936 F789 -8339D937 F78A -8339D938 F78B -8339D939 F78C -8339DA30 F78D -8339DA31 F78E -8339DA32 F78F -8339DA33 F790 -8339DA34 F791 -8339DA35 F792 -8339DA36 F793 -8339DA37 F794 -8339DA38 F795 -8339DA39 F796 -8339DB30 F797 -8339DB31 F798 -8339DB32 F799 -8339DB33 F79A -8339DB34 F79B -8339DB35 F79C -8339DB36 F79D -8339DB37 F79E -8339DB38 F79F -8339DB39 F7A0 -8339DC30 F7A1 -8339DC31 F7A2 -8339DC32 F7A3 -8339DC33 F7A4 -8339DC34 F7A5 -8339DC35 F7A6 -8339DC36 F7A7 -8339DC37 F7A8 -8339DC38 F7A9 -8339DC39 F7AA -8339DD30 F7AB -8339DD31 F7AC -8339DD32 F7AD -8339DD33 F7AE -8339DD34 F7AF -8339DD35 F7B0 -8339DD36 F7B1 -8339DD37 F7B2 -8339DD38 F7B3 -8339DD39 F7B4 -8339DE30 F7B5 -8339DE31 F7B6 -8339DE32 F7B7 -8339DE33 F7B8 -8339DE34 F7B9 -8339DE35 F7BA -8339DE36 F7BB -8339DE37 F7BC -8339DE38 F7BD -8339DE39 F7BE -8339DF30 F7BF -8339DF31 F7C0 -8339DF32 F7C1 -8339DF33 F7C2 -8339DF34 F7C3 -8339DF35 F7C4 -8339DF36 F7C5 -8339DF37 F7C6 -8339DF38 F7C7 -8339DF39 F7C8 -8339E030 F7C9 -8339E031 F7CA -8339E032 F7CB -8339E033 F7CC -8339E034 F7CD -8339E035 F7CE -8339E036 F7CF -8339E037 F7D0 -8339E038 F7D1 -8339E039 F7D2 -8339E130 F7D3 -8339E131 F7D4 -8339E132 F7D5 -8339E133 F7D6 -8339E134 F7D7 -8339E135 F7D8 -8339E136 F7D9 -8339E137 F7DA -8339E138 F7DB -8339E139 F7DC -8339E230 F7DD -8339E231 F7DE -8339E232 F7DF -8339E233 F7E0 -8339E234 F7E1 -8339E235 F7E2 -8339E236 F7E3 -8339E237 F7E4 -8339E238 F7E5 -8339E239 F7E6 -8339E330 F7E7 -8339E331 F7E8 -8339E332 F7E9 -8339E333 F7EA -8339E334 F7EB -8339E335 F7EC -8339E336 F7ED -8339E337 F7EE -8339E338 F7EF -8339E339 F7F0 -8339E430 F7F1 -8339E431 F7F2 -8339E432 F7F3 -8339E433 F7F4 -8339E434 F7F5 -8339E435 F7F6 -8339E436 F7F7 -8339E437 F7F8 -8339E438 F7F9 -8339E439 F7FA -8339E530 F7FB -8339E531 F7FC -8339E532 F7FD -8339E533 F7FE -8339E534 F7FF -8339E535 F800 -8339E536 F801 -8339E537 F802 -8339E538 F803 -8339E539 F804 -8339E630 F805 -8339E631 F806 -8339E632 F807 -8339E633 F808 -8339E634 F809 -8339E635 F80A -8339E636 F80B -8339E637 F80C -8339E638 F80D -8339E639 F80E -8339E730 F80F -8339E731 F810 -8339E732 F811 -8339E733 F812 -8339E734 F813 -8339E735 F814 -8339E736 F815 -8339E737 F816 -8339E738 F817 -8339E739 F818 -8339E830 F819 -8339E831 F81A -8339E832 F81B -8339E833 F81C -8339E834 F81D -8339E835 F81E -8339E836 F81F -8339E837 F820 -8339E838 F821 -8339E839 F822 -8339E930 F823 -8339E931 F824 -8339E932 F825 -8339E933 F826 -8339E934 F827 -8339E935 F828 -8339E936 F829 -8339E937 F82A -8339E938 F82B -8339E939 F82C -8339EA30 F82D -8339EA31 F82E -8339EA32 F82F -8339EA33 F830 -8339EA34 F831 -8339EA35 F832 -8339EA36 F833 -8339EA37 F834 -8339EA38 F835 -8339EA39 F836 -8339EB30 F837 -8339EB31 F838 -8339EB32 F839 -8339EB33 F83A -8339EB34 F83B -8339EB35 F83C -8339EB36 F83D -8339EB37 F83E -8339EB38 F83F -8339EB39 F840 -8339EC30 F841 -8339EC31 F842 -8339EC32 F843 -8339EC33 F844 -8339EC34 F845 -8339EC35 F846 -8339EC36 F847 -8339EC37 F848 -8339EC38 F849 -8339EC39 F84A -8339ED30 F84B -8339ED31 F84C -8339ED32 F84D -8339ED33 F84E -8339ED34 F84F -8339ED35 F850 -8339ED36 F851 -8339ED37 F852 -8339ED38 F853 -8339ED39 F854 -8339EE30 F855 -8339EE31 F856 -8339EE32 F857 -8339EE33 F858 -8339EE34 F859 -8339EE35 F85A -8339EE36 F85B -8339EE37 F85C -8339EE38 F85D -8339EE39 F85E -8339EF30 F85F -8339EF31 F860 -8339EF32 F861 -8339EF33 F862 -8339EF34 F863 -8339EF35 F864 -8339EF36 F865 -8339EF37 F866 -8339EF38 F867 -8339EF39 F868 -8339F030 F869 -8339F031 F86A -8339F032 F86B -8339F033 F86C -8339F034 F86D -8339F035 F86E -8339F036 F86F -8339F037 F870 -8339F038 F871 -8339F039 F872 -8339F130 F873 -8339F131 F874 -8339F132 F875 -8339F133 F876 -8339F134 F877 -8339F135 F878 -8339F136 F879 -8339F137 F87A -8339F138 F87B -8339F139 F87C -8339F230 F87D -8339F231 F87E -8339F232 F87F -8339F233 F880 -8339F234 F881 -8339F235 F882 -8339F236 F883 -8339F237 F884 -8339F238 F885 -8339F239 F886 -8339F330 F887 -8339F331 F888 -8339F332 F889 -8339F333 F88A -8339F334 F88B -8339F335 F88C -8339F336 F88D -8339F337 F88E -8339F338 F88F -8339F339 F890 -8339F430 F891 -8339F431 F892 -8339F432 F893 -8339F433 F894 -8339F434 F895 -8339F435 F896 -8339F436 F897 -8339F437 F898 -8339F438 F899 -8339F439 F89A -8339F530 F89B -8339F531 F89C -8339F532 F89D -8339F533 F89E -8339F534 F89F -8339F535 F8A0 -8339F536 F8A1 -8339F537 F8A2 -8339F538 F8A3 -8339F539 F8A4 -8339F630 F8A5 -8339F631 F8A6 -8339F632 F8A7 -8339F633 F8A8 -8339F634 F8A9 -8339F635 F8AA -8339F636 F8AB -8339F637 F8AC -8339F638 F8AD -8339F639 F8AE -8339F730 F8AF -8339F731 F8B0 -8339F732 F8B1 -8339F733 F8B2 -8339F734 F8B3 -8339F735 F8B4 -8339F736 F8B5 -8339F737 F8B6 -8339F738 F8B7 -8339F739 F8B8 -8339F830 F8B9 -8339F831 F8BA -8339F832 F8BB -8339F833 F8BC -8339F834 F8BD -8339F835 F8BE -8339F836 F8BF -8339F837 F8C0 -8339F838 F8C1 -8339F839 F8C2 -8339F930 F8C3 -8339F931 F8C4 -8339F932 F8C5 -8339F933 F8C6 -8339F934 F8C7 -8339F935 F8C8 -8339F936 F8C9 -8339F937 F8CA -8339F938 F8CB -8339F939 F8CC -8339FA30 F8CD -8339FA31 F8CE -8339FA32 F8CF -8339FA33 F8D0 -8339FA34 F8D1 -8339FA35 F8D2 -8339FA36 F8D3 -8339FA37 F8D4 -8339FA38 F8D5 -8339FA39 F8D6 -8339FB30 F8D7 -8339FB31 F8D8 -8339FB32 F8D9 -8339FB33 F8DA -8339FB34 F8DB -8339FB35 F8DC -8339FB36 F8DD -8339FB37 F8DE -8339FB38 F8DF -8339FB39 F8E0 -8339FC30 F8E1 -8339FC31 F8E2 -8339FC32 F8E3 -8339FC33 F8E4 -8339FC34 F8E5 -8339FC35 F8E6 -8339FC36 F8E7 -8339FC37 F8E8 -8339FC38 F8E9 -8339FC39 F8EA -8339FD30 F8EB -8339FD31 F8EC -8339FD32 F8ED -8339FD33 F8EE -8339FD34 F8EF -8339FD35 F8F0 -8339FD36 F8F1 -8339FD37 F8F2 -8339FD38 F8F3 -8339FD39 F8F4 -8339FE30 F8F5 -8339FE31 F8F6 -8339FE32 F8F7 -8339FE33 F8F8 -8339FE34 F8F9 -8339FE35 F8FA -8339FE36 F8FB -8339FE37 F8FC -8339FE38 F8FD -8339FE39 F8FE -84308130 F8FF -84308131 F900 -84308132 F901 -84308133 F902 -84308134 F903 -84308135 F904 -84308136 F905 -84308137 F906 -84308138 F907 -84308139 F908 -84308230 F909 -84308231 F90A -84308232 F90B -84308233 F90C -84308234 F90D -84308235 F90E -84308236 F90F -84308237 F910 -84308238 F911 -84308239 F912 -84308330 F913 -84308331 F914 -84308332 F915 -84308333 F916 -84308334 F917 -84308335 F918 -84308336 F919 -84308337 F91A -84308338 F91B -84308339 F91C -84308430 F91D -84308431 F91E -84308432 F91F -84308433 F920 -84308434 F921 -84308435 F922 -84308436 F923 -84308437 F924 -84308438 F925 -84308439 F926 -84308530 F927 -84308531 F928 -84308532 F929 -84308533 F92A -84308534 F92B -FD9C F92C -84308535 F92D -84308536 F92E -84308537 F92F -84308538 F930 -84308539 F931 -84308630 F932 -84308631 F933 -84308632 F934 -84308633 F935 -84308634 F936 -84308635 F937 -84308636 F938 -84308637 F939 -84308638 F93A -84308639 F93B -84308730 F93C -84308731 F93D -84308732 F93E -84308733 F93F -84308734 F940 -84308735 F941 -84308736 F942 -84308737 F943 -84308738 F944 -84308739 F945 -84308830 F946 -84308831 F947 -84308832 F948 -84308833 F949 -84308834 F94A -84308835 F94B -84308836 F94C -84308837 F94D -84308838 F94E -84308839 F94F -84308930 F950 -84308931 F951 -84308932 F952 -84308933 F953 -84308934 F954 -84308935 F955 -84308936 F956 -84308937 F957 -84308938 F958 -84308939 F959 -84308A30 F95A -84308A31 F95B -84308A32 F95C -84308A33 F95D -84308A34 F95E -84308A35 F95F -84308A36 F960 -84308A37 F961 -84308A38 F962 -84308A39 F963 -84308B30 F964 -84308B31 F965 -84308B32 F966 -84308B33 F967 -84308B34 F968 -84308B35 F969 -84308B36 F96A -84308B37 F96B -84308B38 F96C -84308B39 F96D -84308C30 F96E -84308C31 F96F -84308C32 F970 -84308C33 F971 -84308C34 F972 -84308C35 F973 -84308C36 F974 -84308C37 F975 -84308C38 F976 -84308C39 F977 -84308D30 F978 -FD9D F979 -84308D31 F97A -84308D32 F97B -84308D33 F97C -84308D34 F97D -84308D35 F97E -84308D36 F97F -84308D37 F980 -84308D38 F981 -84308D39 F982 -84308E30 F983 -84308E31 F984 -84308E32 F985 -84308E33 F986 -84308E34 F987 -84308E35 F988 -84308E36 F989 -84308E37 F98A -84308E38 F98B -84308E39 F98C -84308F30 F98D -84308F31 F98E -84308F32 F98F -84308F33 F990 -84308F34 F991 -84308F35 F992 -84308F36 F993 -84308F37 F994 -FD9E F995 -84308F38 F996 -84308F39 F997 -84309030 F998 -84309031 F999 -84309032 F99A -84309033 F99B -84309034 F99C -84309035 F99D -84309036 F99E -84309037 F99F -84309038 F9A0 -84309039 F9A1 -84309130 F9A2 -84309131 F9A3 -84309132 F9A4 -84309133 F9A5 -84309134 F9A6 -84309135 F9A7 -84309136 F9A8 -84309137 F9A9 -84309138 F9AA -84309139 F9AB -84309230 F9AC -84309231 F9AD -84309232 F9AE -84309233 F9AF -84309234 F9B0 -84309235 F9B1 -84309236 F9B2 -84309237 F9B3 -84309238 F9B4 -84309239 F9B5 -84309330 F9B6 -84309331 F9B7 -84309332 F9B8 -84309333 F9B9 -84309334 F9BA -84309335 F9BB -84309336 F9BC -84309337 F9BD -84309338 F9BE -84309339 F9BF -84309430 F9C0 -84309431 F9C1 -84309432 F9C2 -84309433 F9C3 -84309434 F9C4 -84309435 F9C5 -84309436 F9C6 -84309437 F9C7 -84309438 F9C8 -84309439 F9C9 -84309530 F9CA -84309531 F9CB -84309532 F9CC -84309533 F9CD -84309534 F9CE -84309535 F9CF -84309536 F9D0 -84309537 F9D1 -84309538 F9D2 -84309539 F9D3 -84309630 F9D4 -84309631 F9D5 -84309632 F9D6 -84309633 F9D7 -84309634 F9D8 -84309635 F9D9 -84309636 F9DA -84309637 F9DB -84309638 F9DC -84309639 F9DD -84309730 F9DE -84309731 F9DF -84309732 F9E0 -84309733 F9E1 -84309734 F9E2 -84309735 F9E3 -84309736 F9E4 -84309737 F9E5 -84309738 F9E6 -FD9F F9E7 -84309739 F9E8 -84309830 F9E9 -84309831 F9EA -84309832 F9EB -84309833 F9EC -84309834 F9ED -84309835 F9EE -84309836 F9EF -84309837 F9F0 -FDA0 F9F1 -84309838 F9F2 -84309839 F9F3 -84309930 F9F4 -84309931 F9F5 -84309932 F9F6 -84309933 F9F7 -84309934 F9F8 -84309935 F9F9 -84309936 F9FA -84309937 F9FB -84309938 F9FC -84309939 F9FD -84309A30 F9FE -84309A31 F9FF -84309A32 FA00 -84309A33 FA01 -84309A34 FA02 -84309A35 FA03 -84309A36 FA04 -84309A37 FA05 -84309A38 FA06 -84309A39 FA07 -84309B30 FA08 -84309B31 FA09 -84309B32 FA0A -84309B33 FA0B -FE40 FA0C -FE41 FA0D -FE42 FA0E -FE43 FA0F -84309B34 FA10 -FE44 FA11 -84309B35 FA12 -FE45 FA13 -FE46 FA14 -84309B36 FA15 -84309B37 FA16 -84309B38 FA17 -FE47 FA18 -84309B39 FA19 -84309C30 FA1A -84309C31 FA1B -84309C32 FA1C -84309C33 FA1D -84309C34 FA1E -FE48 FA1F -FE49 FA20 -FE4A FA21 -84309C35 FA22 -FE4B FA23 -FE4C FA24 -84309C36 FA25 -84309C37 FA26 -FE4D FA27 -FE4E FA28 -FE4F FA29 -84309C38 FA2A -84309C39 FA2B -84309D30 FA2C -84309D31 FA2D -84309D32 FA2E -84309D33 FA2F -84309D34 FA30 -84309D35 FA31 -84309D36 FA32 -84309D37 FA33 -84309D38 FA34 -84309D39 FA35 -84309E30 FA36 -84309E31 FA37 -84309E32 FA38 -84309E33 FA39 -84309E34 FA3A -84309E35 FA3B -84309E36 FA3C -84309E37 FA3D -84309E38 FA3E -84309E39 FA3F -84309F30 FA40 -84309F31 FA41 -84309F32 FA42 -84309F33 FA43 -84309F34 FA44 -84309F35 FA45 -84309F36 FA46 -84309F37 FA47 -84309F38 FA48 -84309F39 FA49 -8430A030 FA4A -8430A031 FA4B -8430A032 FA4C -8430A033 FA4D -8430A034 FA4E -8430A035 FA4F -8430A036 FA50 -8430A037 FA51 -8430A038 FA52 -8430A039 FA53 -8430A130 FA54 -8430A131 FA55 -8430A132 FA56 -8430A133 FA57 -8430A134 FA58 -8430A135 FA59 -8430A136 FA5A -8430A137 FA5B -8430A138 FA5C -8430A139 FA5D -8430A230 FA5E -8430A231 FA5F -8430A232 FA60 -8430A233 FA61 -8430A234 FA62 -8430A235 FA63 -8430A236 FA64 -8430A237 FA65 -8430A238 FA66 -8430A239 FA67 -8430A330 FA68 -8430A331 FA69 -8430A332 FA6A -8430A333 FA6B -8430A334 FA6C -8430A335 FA6D -8430A336 FA6E -8430A337 FA6F -8430A338 FA70 -8430A339 FA71 -8430A430 FA72 -8430A431 FA73 -8430A432 FA74 -8430A433 FA75 -8430A434 FA76 -8430A435 FA77 -8430A436 FA78 -8430A437 FA79 -8430A438 FA7A -8430A439 FA7B -8430A530 FA7C -8430A531 FA7D -8430A532 FA7E -8430A533 FA7F -8430A534 FA80 -8430A535 FA81 -8430A536 FA82 -8430A537 FA83 -8430A538 FA84 -8430A539 FA85 -8430A630 FA86 -8430A631 FA87 -8430A632 FA88 -8430A633 FA89 -8430A634 FA8A -8430A635 FA8B -8430A636 FA8C -8430A637 FA8D -8430A638 FA8E -8430A639 FA8F -8430A730 FA90 -8430A731 FA91 -8430A732 FA92 -8430A733 FA93 -8430A734 FA94 -8430A735 FA95 -8430A736 FA96 -8430A737 FA97 -8430A738 FA98 -8430A739 FA99 -8430A830 FA9A -8430A831 FA9B -8430A832 FA9C -8430A833 FA9D -8430A834 FA9E -8430A835 FA9F -8430A836 FAA0 -8430A837 FAA1 -8430A838 FAA2 -8430A839 FAA3 -8430A930 FAA4 -8430A931 FAA5 -8430A932 FAA6 -8430A933 FAA7 -8430A934 FAA8 -8430A935 FAA9 -8430A936 FAAA -8430A937 FAAB -8430A938 FAAC -8430A939 FAAD -8430AA30 FAAE -8430AA31 FAAF -8430AA32 FAB0 -8430AA33 FAB1 -8430AA34 FAB2 -8430AA35 FAB3 -8430AA36 FAB4 -8430AA37 FAB5 -8430AA38 FAB6 -8430AA39 FAB7 -8430AB30 FAB8 -8430AB31 FAB9 -8430AB32 FABA -8430AB33 FABB -8430AB34 FABC -8430AB35 FABD -8430AB36 FABE -8430AB37 FABF -8430AB38 FAC0 -8430AB39 FAC1 -8430AC30 FAC2 -8430AC31 FAC3 -8430AC32 FAC4 -8430AC33 FAC5 -8430AC34 FAC6 -8430AC35 FAC7 -8430AC36 FAC8 -8430AC37 FAC9 -8430AC38 FACA -8430AC39 FACB -8430AD30 FACC -8430AD31 FACD -8430AD32 FACE -8430AD33 FACF -8430AD34 FAD0 -8430AD35 FAD1 -8430AD36 FAD2 -8430AD37 FAD3 -8430AD38 FAD4 -8430AD39 FAD5 -8430AE30 FAD6 -8430AE31 FAD7 -8430AE32 FAD8 -8430AE33 FAD9 -8430AE34 FADA -8430AE35 FADB -8430AE36 FADC -8430AE37 FADD -8430AE38 FADE -8430AE39 FADF -8430AF30 FAE0 -8430AF31 FAE1 -8430AF32 FAE2 -8430AF33 FAE3 -8430AF34 FAE4 -8430AF35 FAE5 -8430AF36 FAE6 -8430AF37 FAE7 -8430AF38 FAE8 -8430AF39 FAE9 -8430B030 FAEA -8430B031 FAEB -8430B032 FAEC -8430B033 FAED -8430B034 FAEE -8430B035 FAEF -8430B036 FAF0 -8430B037 FAF1 -8430B038 FAF2 -8430B039 FAF3 -8430B130 FAF4 -8430B131 FAF5 -8430B132 FAF6 -8430B133 FAF7 -8430B134 FAF8 -8430B135 FAF9 -8430B136 FAFA -8430B137 FAFB -8430B138 FAFC -8430B139 FAFD -8430B230 FAFE -8430B231 FAFF -8430B232 FB00 -8430B233 FB01 -8430B234 FB02 -8430B235 FB03 -8430B236 FB04 -8430B237 FB05 -8430B238 FB06 -8430B239 FB07 -8430B330 FB08 -8430B331 FB09 -8430B332 FB0A -8430B333 FB0B -8430B334 FB0C -8430B335 FB0D -8430B336 FB0E -8430B337 FB0F -8430B338 FB10 -8430B339 FB11 -8430B430 FB12 -8430B431 FB13 -8430B432 FB14 -8430B433 FB15 -8430B434 FB16 -8430B435 FB17 -8430B436 FB18 -8430B437 FB19 -8430B438 FB1A -8430B439 FB1B -8430B530 FB1C -8430B531 FB1D -8430B532 FB1E -8430B533 FB1F -8430B534 FB20 -8430B535 FB21 -8430B536 FB22 -8430B537 FB23 -8430B538 FB24 -8430B539 FB25 -8430B630 FB26 -8430B631 FB27 -8430B632 FB28 -8430B633 FB29 -8430B634 FB2A -8430B635 FB2B -8430B636 FB2C -8430B637 FB2D -8430B638 FB2E -8430B639 FB2F -8430B730 FB30 -8430B731 FB31 -8430B732 FB32 -8430B733 FB33 -8430B734 FB34 -8430B735 FB35 -8430B736 FB36 -8430B737 FB37 -8430B738 FB38 -8430B739 FB39 -8430B830 FB3A -8430B831 FB3B -8430B832 FB3C -8430B833 FB3D -8430B834 FB3E -8430B835 FB3F -8430B836 FB40 -8430B837 FB41 -8430B838 FB42 -8430B839 FB43 -8430B930 FB44 -8430B931 FB45 -8430B932 FB46 -8430B933 FB47 -8430B934 FB48 -8430B935 FB49 -8430B936 FB4A -8430B937 FB4B -8430B938 FB4C -8430B939 FB4D -8430BA30 FB4E -8430BA31 FB4F -8430BA32 FB50 -8430BA33 FB51 -8430BA34 FB52 -8430BA35 FB53 -8430BA36 FB54 -8430BA37 FB55 -8430BA38 FB56 -8430BA39 FB57 -8430BB30 FB58 -8430BB31 FB59 -8430BB32 FB5A -8430BB33 FB5B -8430BB34 FB5C -8430BB35 FB5D -8430BB36 FB5E -8430BB37 FB5F -8430BB38 FB60 -8430BB39 FB61 -8430BC30 FB62 -8430BC31 FB63 -8430BC32 FB64 -8430BC33 FB65 -8430BC34 FB66 -8430BC35 FB67 -8430BC36 FB68 -8430BC37 FB69 -8430BC38 FB6A -8430BC39 FB6B -8430BD30 FB6C -8430BD31 FB6D -8430BD32 FB6E -8430BD33 FB6F -8430BD34 FB70 -8430BD35 FB71 -8430BD36 FB72 -8430BD37 FB73 -8430BD38 FB74 -8430BD39 FB75 -8430BE30 FB76 -8430BE31 FB77 -8430BE32 FB78 -8430BE33 FB79 -8430BE34 FB7A -8430BE35 FB7B -8430BE36 FB7C -8430BE37 FB7D -8430BE38 FB7E -8430BE39 FB7F -8430BF30 FB80 -8430BF31 FB81 -8430BF32 FB82 -8430BF33 FB83 -8430BF34 FB84 -8430BF35 FB85 -8430BF36 FB86 -8430BF37 FB87 -8430BF38 FB88 -8430BF39 FB89 -8430C030 FB8A -8430C031 FB8B -8430C032 FB8C -8430C033 FB8D -8430C034 FB8E -8430C035 FB8F -8430C036 FB90 -8430C037 FB91 -8430C038 FB92 -8430C039 FB93 -8430C130 FB94 -8430C131 FB95 -8430C132 FB96 -8430C133 FB97 -8430C134 FB98 -8430C135 FB99 -8430C136 FB9A -8430C137 FB9B -8430C138 FB9C -8430C139 FB9D -8430C230 FB9E -8430C231 FB9F -8430C232 FBA0 -8430C233 FBA1 -8430C234 FBA2 -8430C235 FBA3 -8430C236 FBA4 -8430C237 FBA5 -8430C238 FBA6 -8430C239 FBA7 -8430C330 FBA8 -8430C331 FBA9 -8430C332 FBAA -8430C333 FBAB -8430C334 FBAC -8430C335 FBAD -8430C336 FBAE -8430C337 FBAF -8430C338 FBB0 -8430C339 FBB1 -8430C430 FBB2 -8430C431 FBB3 -8430C432 FBB4 -8430C433 FBB5 -8430C434 FBB6 -8430C435 FBB7 -8430C436 FBB8 -8430C437 FBB9 -8430C438 FBBA -8430C439 FBBB -8430C530 FBBC -8430C531 FBBD -8430C532 FBBE -8430C533 FBBF -8430C534 FBC0 -8430C535 FBC1 -8430C536 FBC2 -8430C537 FBC3 -8430C538 FBC4 -8430C539 FBC5 -8430C630 FBC6 -8430C631 FBC7 -8430C632 FBC8 -8430C633 FBC9 -8430C634 FBCA -8430C635 FBCB -8430C636 FBCC -8430C637 FBCD -8430C638 FBCE -8430C639 FBCF -8430C730 FBD0 -8430C731 FBD1 -8430C732 FBD2 -8430C733 FBD3 -8430C734 FBD4 -8430C735 FBD5 -8430C736 FBD6 -8430C737 FBD7 -8430C738 FBD8 -8430C739 FBD9 -8430C830 FBDA -8430C831 FBDB -8430C832 FBDC -8430C833 FBDD -8430C834 FBDE -8430C835 FBDF -8430C836 FBE0 -8430C837 FBE1 -8430C838 FBE2 -8430C839 FBE3 -8430C930 FBE4 -8430C931 FBE5 -8430C932 FBE6 -8430C933 FBE7 -8430C934 FBE8 -8430C935 FBE9 -8430C936 FBEA -8430C937 FBEB -8430C938 FBEC -8430C939 FBED -8430CA30 FBEE -8430CA31 FBEF -8430CA32 FBF0 -8430CA33 FBF1 -8430CA34 FBF2 -8430CA35 FBF3 -8430CA36 FBF4 -8430CA37 FBF5 -8430CA38 FBF6 -8430CA39 FBF7 -8430CB30 FBF8 -8430CB31 FBF9 -8430CB32 FBFA -8430CB33 FBFB -8430CB34 FBFC -8430CB35 FBFD -8430CB36 FBFE -8430CB37 FBFF -8430CB38 FC00 -8430CB39 FC01 -8430CC30 FC02 -8430CC31 FC03 -8430CC32 FC04 -8430CC33 FC05 -8430CC34 FC06 -8430CC35 FC07 -8430CC36 FC08 -8430CC37 FC09 -8430CC38 FC0A -8430CC39 FC0B -8430CD30 FC0C -8430CD31 FC0D -8430CD32 FC0E -8430CD33 FC0F -8430CD34 FC10 -8430CD35 FC11 -8430CD36 FC12 -8430CD37 FC13 -8430CD38 FC14 -8430CD39 FC15 -8430CE30 FC16 -8430CE31 FC17 -8430CE32 FC18 -8430CE33 FC19 -8430CE34 FC1A -8430CE35 FC1B -8430CE36 FC1C -8430CE37 FC1D -8430CE38 FC1E -8430CE39 FC1F -8430CF30 FC20 -8430CF31 FC21 -8430CF32 FC22 -8430CF33 FC23 -8430CF34 FC24 -8430CF35 FC25 -8430CF36 FC26 -8430CF37 FC27 -8430CF38 FC28 -8430CF39 FC29 -8430D030 FC2A -8430D031 FC2B -8430D032 FC2C -8430D033 FC2D -8430D034 FC2E -8430D035 FC2F -8430D036 FC30 -8430D037 FC31 -8430D038 FC32 -8430D039 FC33 -8430D130 FC34 -8430D131 FC35 -8430D132 FC36 -8430D133 FC37 -8430D134 FC38 -8430D135 FC39 -8430D136 FC3A -8430D137 FC3B -8430D138 FC3C -8430D139 FC3D -8430D230 FC3E -8430D231 FC3F -8430D232 FC40 -8430D233 FC41 -8430D234 FC42 -8430D235 FC43 -8430D236 FC44 -8430D237 FC45 -8430D238 FC46 -8430D239 FC47 -8430D330 FC48 -8430D331 FC49 -8430D332 FC4A -8430D333 FC4B -8430D334 FC4C -8430D335 FC4D -8430D336 FC4E -8430D337 FC4F -8430D338 FC50 -8430D339 FC51 -8430D430 FC52 -8430D431 FC53 -8430D432 FC54 -8430D433 FC55 -8430D434 FC56 -8430D435 FC57 -8430D436 FC58 -8430D437 FC59 -8430D438 FC5A -8430D439 FC5B -8430D530 FC5C -8430D531 FC5D -8430D532 FC5E -8430D533 FC5F -8430D534 FC60 -8430D535 FC61 -8430D536 FC62 -8430D537 FC63 -8430D538 FC64 -8430D539 FC65 -8430D630 FC66 -8430D631 FC67 -8430D632 FC68 -8430D633 FC69 -8430D634 FC6A -8430D635 FC6B -8430D636 FC6C -8430D637 FC6D -8430D638 FC6E -8430D639 FC6F -8430D730 FC70 -8430D731 FC71 -8430D732 FC72 -8430D733 FC73 -8430D734 FC74 -8430D735 FC75 -8430D736 FC76 -8430D737 FC77 -8430D738 FC78 -8430D739 FC79 -8430D830 FC7A -8430D831 FC7B -8430D832 FC7C -8430D833 FC7D -8430D834 FC7E -8430D835 FC7F -8430D836 FC80 -8430D837 FC81 -8430D838 FC82 -8430D839 FC83 -8430D930 FC84 -8430D931 FC85 -8430D932 FC86 -8430D933 FC87 -8430D934 FC88 -8430D935 FC89 -8430D936 FC8A -8430D937 FC8B -8430D938 FC8C -8430D939 FC8D -8430DA30 FC8E -8430DA31 FC8F -8430DA32 FC90 -8430DA33 FC91 -8430DA34 FC92 -8430DA35 FC93 -8430DA36 FC94 -8430DA37 FC95 -8430DA38 FC96 -8430DA39 FC97 -8430DB30 FC98 -8430DB31 FC99 -8430DB32 FC9A -8430DB33 FC9B -8430DB34 FC9C -8430DB35 FC9D -8430DB36 FC9E -8430DB37 FC9F -8430DB38 FCA0 -8430DB39 FCA1 -8430DC30 FCA2 -8430DC31 FCA3 -8430DC32 FCA4 -8430DC33 FCA5 -8430DC34 FCA6 -8430DC35 FCA7 -8430DC36 FCA8 -8430DC37 FCA9 -8430DC38 FCAA -8430DC39 FCAB -8430DD30 FCAC -8430DD31 FCAD -8430DD32 FCAE -8430DD33 FCAF -8430DD34 FCB0 -8430DD35 FCB1 -8430DD36 FCB2 -8430DD37 FCB3 -8430DD38 FCB4 -8430DD39 FCB5 -8430DE30 FCB6 -8430DE31 FCB7 -8430DE32 FCB8 -8430DE33 FCB9 -8430DE34 FCBA -8430DE35 FCBB -8430DE36 FCBC -8430DE37 FCBD -8430DE38 FCBE -8430DE39 FCBF -8430DF30 FCC0 -8430DF31 FCC1 -8430DF32 FCC2 -8430DF33 FCC3 -8430DF34 FCC4 -8430DF35 FCC5 -8430DF36 FCC6 -8430DF37 FCC7 -8430DF38 FCC8 -8430DF39 FCC9 -8430E030 FCCA -8430E031 FCCB -8430E032 FCCC -8430E033 FCCD -8430E034 FCCE -8430E035 FCCF -8430E036 FCD0 -8430E037 FCD1 -8430E038 FCD2 -8430E039 FCD3 -8430E130 FCD4 -8430E131 FCD5 -8430E132 FCD6 -8430E133 FCD7 -8430E134 FCD8 -8430E135 FCD9 -8430E136 FCDA -8430E137 FCDB -8430E138 FCDC -8430E139 FCDD -8430E230 FCDE -8430E231 FCDF -8430E232 FCE0 -8430E233 FCE1 -8430E234 FCE2 -8430E235 FCE3 -8430E236 FCE4 -8430E237 FCE5 -8430E238 FCE6 -8430E239 FCE7 -8430E330 FCE8 -8430E331 FCE9 -8430E332 FCEA -8430E333 FCEB -8430E334 FCEC -8430E335 FCED -8430E336 FCEE -8430E337 FCEF -8430E338 FCF0 -8430E339 FCF1 -8430E430 FCF2 -8430E431 FCF3 -8430E432 FCF4 -8430E433 FCF5 -8430E434 FCF6 -8430E435 FCF7 -8430E436 FCF8 -8430E437 FCF9 -8430E438 FCFA -8430E439 FCFB -8430E530 FCFC -8430E531 FCFD -8430E532 FCFE -8430E533 FCFF -8430E534 FD00 -8430E535 FD01 -8430E536 FD02 -8430E537 FD03 -8430E538 FD04 -8430E539 FD05 -8430E630 FD06 -8430E631 FD07 -8430E632 FD08 -8430E633 FD09 -8430E634 FD0A -8430E635 FD0B -8430E636 FD0C -8430E637 FD0D -8430E638 FD0E -8430E639 FD0F -8430E730 FD10 -8430E731 FD11 -8430E732 FD12 -8430E733 FD13 -8430E734 FD14 -8430E735 FD15 -8430E736 FD16 -8430E737 FD17 -8430E738 FD18 -8430E739 FD19 -8430E830 FD1A -8430E831 FD1B -8430E832 FD1C -8430E833 FD1D -8430E834 FD1E -8430E835 FD1F -8430E836 FD20 -8430E837 FD21 -8430E838 FD22 -8430E839 FD23 -8430E930 FD24 -8430E931 FD25 -8430E932 FD26 -8430E933 FD27 -8430E934 FD28 -8430E935 FD29 -8430E936 FD2A -8430E937 FD2B -8430E938 FD2C -8430E939 FD2D -8430EA30 FD2E -8430EA31 FD2F -8430EA32 FD30 -8430EA33 FD31 -8430EA34 FD32 -8430EA35 FD33 -8430EA36 FD34 -8430EA37 FD35 -8430EA38 FD36 -8430EA39 FD37 -8430EB30 FD38 -8430EB31 FD39 -8430EB32 FD3A -8430EB33 FD3B -8430EB34 FD3C -8430EB35 FD3D -8430EB36 FD3E -8430EB37 FD3F -8430EB38 FD40 -8430EB39 FD41 -8430EC30 FD42 -8430EC31 FD43 -8430EC32 FD44 -8430EC33 FD45 -8430EC34 FD46 -8430EC35 FD47 -8430EC36 FD48 -8430EC37 FD49 -8430EC38 FD4A -8430EC39 FD4B -8430ED30 FD4C -8430ED31 FD4D -8430ED32 FD4E -8430ED33 FD4F -8430ED34 FD50 -8430ED35 FD51 -8430ED36 FD52 -8430ED37 FD53 -8430ED38 FD54 -8430ED39 FD55 -8430EE30 FD56 -8430EE31 FD57 -8430EE32 FD58 -8430EE33 FD59 -8430EE34 FD5A -8430EE35 FD5B -8430EE36 FD5C -8430EE37 FD5D -8430EE38 FD5E -8430EE39 FD5F -8430EF30 FD60 -8430EF31 FD61 -8430EF32 FD62 -8430EF33 FD63 -8430EF34 FD64 -8430EF35 FD65 -8430EF36 FD66 -8430EF37 FD67 -8430EF38 FD68 -8430EF39 FD69 -8430F030 FD6A -8430F031 FD6B -8430F032 FD6C -8430F033 FD6D -8430F034 FD6E -8430F035 FD6F -8430F036 FD70 -8430F037 FD71 -8430F038 FD72 -8430F039 FD73 -8430F130 FD74 -8430F131 FD75 -8430F132 FD76 -8430F133 FD77 -8430F134 FD78 -8430F135 FD79 -8430F136 FD7A -8430F137 FD7B -8430F138 FD7C -8430F139 FD7D -8430F230 FD7E -8430F231 FD7F -8430F232 FD80 -8430F233 FD81 -8430F234 FD82 -8430F235 FD83 -8430F236 FD84 -8430F237 FD85 -8430F238 FD86 -8430F239 FD87 -8430F330 FD88 -8430F331 FD89 -8430F332 FD8A -8430F333 FD8B -8430F334 FD8C -8430F335 FD8D -8430F336 FD8E -8430F337 FD8F -8430F338 FD90 -8430F339 FD91 -8430F430 FD92 -8430F431 FD93 -8430F432 FD94 -8430F433 FD95 -8430F434 FD96 -8430F435 FD97 -8430F436 FD98 -8430F437 FD99 -8430F438 FD9A -8430F439 FD9B -8430F530 FD9C -8430F531 FD9D -8430F532 FD9E -8430F533 FD9F -8430F534 FDA0 -8430F535 FDA1 -8430F536 FDA2 -8430F537 FDA3 -8430F538 FDA4 -8430F539 FDA5 -8430F630 FDA6 -8430F631 FDA7 -8430F632 FDA8 -8430F633 FDA9 -8430F634 FDAA -8430F635 FDAB -8430F636 FDAC -8430F637 FDAD -8430F638 FDAE -8430F639 FDAF -8430F730 FDB0 -8430F731 FDB1 -8430F732 FDB2 -8430F733 FDB3 -8430F734 FDB4 -8430F735 FDB5 -8430F736 FDB6 -8430F737 FDB7 -8430F738 FDB8 -8430F739 FDB9 -8430F830 FDBA -8430F831 FDBB -8430F832 FDBC -8430F833 FDBD -8430F834 FDBE -8430F835 FDBF -8430F836 FDC0 -8430F837 FDC1 -8430F838 FDC2 -8430F839 FDC3 -8430F930 FDC4 -8430F931 FDC5 -8430F932 FDC6 -8430F933 FDC7 -8430F934 FDC8 -8430F935 FDC9 -8430F936 FDCA -8430F937 FDCB -8430F938 FDCC -8430F939 FDCD -8430FA30 FDCE -8430FA31 FDCF -8430FA32 FDD0 -8430FA33 FDD1 -8430FA34 FDD2 -8430FA35 FDD3 -8430FA36 FDD4 -8430FA37 FDD5 -8430FA38 FDD6 -8430FA39 FDD7 -8430FB30 FDD8 -8430FB31 FDD9 -8430FB32 FDDA -8430FB33 FDDB -8430FB34 FDDC -8430FB35 FDDD -8430FB36 FDDE -8430FB37 FDDF -8430FB38 FDE0 -8430FB39 FDE1 -8430FC30 FDE2 -8430FC31 FDE3 -8430FC32 FDE4 -8430FC33 FDE5 -8430FC34 FDE6 -8430FC35 FDE7 -8430FC36 FDE8 -8430FC37 FDE9 -8430FC38 FDEA -8430FC39 FDEB -8430FD30 FDEC -8430FD31 FDED -8430FD32 FDEE -8430FD33 FDEF -8430FD34 FDF0 -8430FD35 FDF1 -8430FD36 FDF2 -8430FD37 FDF3 -8430FD38 FDF4 -8430FD39 FDF5 -8430FE30 FDF6 -8430FE31 FDF7 -8430FE32 FDF8 -8430FE33 FDF9 -8430FE34 FDFA -8430FE35 FDFB -8430FE36 FDFC -8430FE37 FDFD -8430FE38 FDFE -8430FE39 FDFF -84318130 FE00 -84318131 FE01 -84318132 FE02 -84318133 FE03 -84318134 FE04 -84318135 FE05 -84318136 FE06 -84318137 FE07 -84318138 FE08 -84318139 FE09 -84318230 FE0A -84318231 FE0B -84318232 FE0C -84318233 FE0D -84318234 FE0E -84318235 FE0F -84318236 FE10 -84318237 FE11 -84318238 FE12 -84318239 FE13 -84318330 FE14 -84318331 FE15 -84318332 FE16 -84318333 FE17 -84318334 FE18 -84318335 FE19 -84318336 FE1A -84318337 FE1B -84318338 FE1C -84318339 FE1D -84318430 FE1E -84318431 FE1F -84318432 FE20 -84318433 FE21 -84318434 FE22 -84318435 FE23 -84318436 FE24 -84318437 FE25 -84318438 FE26 -84318439 FE27 -84318530 FE28 -84318531 FE29 -84318532 FE2A -84318533 FE2B -84318534 FE2C -84318535 FE2D -84318536 FE2E -84318537 FE2F -A955 FE30 -A6F2 FE31 -84318538 FE32 -A6F4 FE33 -A6F5 FE34 -A6E0 FE35 -A6E1 FE36 -A6F0 FE37 -A6F1 FE38 -A6E2 FE39 -A6E3 FE3A -A6EE FE3B -A6EF FE3C -A6E6 FE3D -A6E7 FE3E -A6E4 FE3F -A6E5 FE40 -A6E8 FE41 -A6E9 FE42 -A6EA FE43 -A6EB FE44 -84318539 FE45 -84318630 FE46 -84318631 FE47 -84318632 FE48 -A968 FE49 -A969 FE4A -A96A FE4B -A96B FE4C -A96C FE4D -A96D FE4E -A96E FE4F -A96F FE50 -A970 FE51 -A971 FE52 -84318633 FE53 -A972 FE54 -A973 FE55 -A974 FE56 -A975 FE57 -84318634 FE58 -A976 FE59 -A977 FE5A -A978 FE5B -A979 FE5C -A97A FE5D -A97B FE5E -A97C FE5F -A97D FE60 -A97E FE61 -A980 FE62 -A981 FE63 -A982 FE64 -A983 FE65 -A984 FE66 -84318635 FE67 -A985 FE68 -A986 FE69 -A987 FE6A -A988 FE6B -84318636 FE6C -84318637 FE6D -84318638 FE6E -84318639 FE6F -84318730 FE70 -84318731 FE71 -84318732 FE72 -84318733 FE73 -84318734 FE74 -84318735 FE75 -84318736 FE76 -84318737 FE77 -84318738 FE78 -84318739 FE79 -84318830 FE7A -84318831 FE7B -84318832 FE7C -84318833 FE7D -84318834 FE7E -84318835 FE7F -84318836 FE80 -84318837 FE81 -84318838 FE82 -84318839 FE83 -84318930 FE84 -84318931 FE85 -84318932 FE86 -84318933 FE87 -84318934 FE88 -84318935 FE89 -84318936 FE8A -84318937 FE8B -84318938 FE8C -84318939 FE8D -84318A30 FE8E -84318A31 FE8F -84318A32 FE90 -84318A33 FE91 -84318A34 FE92 -84318A35 FE93 -84318A36 FE94 -84318A37 FE95 -84318A38 FE96 -84318A39 FE97 -84318B30 FE98 -84318B31 FE99 -84318B32 FE9A -84318B33 FE9B -84318B34 FE9C -84318B35 FE9D -84318B36 FE9E -84318B37 FE9F -84318B38 FEA0 -84318B39 FEA1 -84318C30 FEA2 -84318C31 FEA3 -84318C32 FEA4 -84318C33 FEA5 -84318C34 FEA6 -84318C35 FEA7 -84318C36 FEA8 -84318C37 FEA9 -84318C38 FEAA -84318C39 FEAB -84318D30 FEAC -84318D31 FEAD -84318D32 FEAE -84318D33 FEAF -84318D34 FEB0 -84318D35 FEB1 -84318D36 FEB2 -84318D37 FEB3 -84318D38 FEB4 -84318D39 FEB5 -84318E30 FEB6 -84318E31 FEB7 -84318E32 FEB8 -84318E33 FEB9 -84318E34 FEBA -84318E35 FEBB -84318E36 FEBC -84318E37 FEBD -84318E38 FEBE -84318E39 FEBF -84318F30 FEC0 -84318F31 FEC1 -84318F32 FEC2 -84318F33 FEC3 -84318F34 FEC4 -84318F35 FEC5 -84318F36 FEC6 -84318F37 FEC7 -84318F38 FEC8 -84318F39 FEC9 -84319030 FECA -84319031 FECB -84319032 FECC -84319033 FECD -84319034 FECE -84319035 FECF -84319036 FED0 -84319037 FED1 -84319038 FED2 -84319039 FED3 -84319130 FED4 -84319131 FED5 -84319132 FED6 -84319133 FED7 -84319134 FED8 -84319135 FED9 -84319136 FEDA -84319137 FEDB -84319138 FEDC -84319139 FEDD -84319230 FEDE -84319231 FEDF -84319232 FEE0 -84319233 FEE1 -84319234 FEE2 -84319235 FEE3 -84319236 FEE4 -84319237 FEE5 -84319238 FEE6 -84319239 FEE7 -84319330 FEE8 -84319331 FEE9 -84319332 FEEA -84319333 FEEB -84319334 FEEC -84319335 FEED -84319336 FEEE -84319337 FEEF -84319338 FEF0 -84319339 FEF1 -84319430 FEF2 -84319431 FEF3 -84319432 FEF4 -84319433 FEF5 -84319434 FEF6 -84319435 FEF7 -84319436 FEF8 -84319437 FEF9 -84319438 FEFA -84319439 FEFB -84319530 FEFC -84319531 FEFD -84319532 FEFE -84319533 FEFF -84319534 FF00 -A3A1 FF01 -A3A2 FF02 -A3A3 FF03 -A1E7 FF04 -A3A5 FF05 -A3A6 FF06 -A3A7 FF07 -A3A8 FF08 -A3A9 FF09 -A3AA FF0A -A3AB FF0B -A3AC FF0C -A3AD FF0D -A3AE FF0E -A3AF FF0F -A3B0 FF10 -A3B1 FF11 -A3B2 FF12 -A3B3 FF13 -A3B4 FF14 -A3B5 FF15 -A3B6 FF16 -A3B7 FF17 -A3B8 FF18 -A3B9 FF19 -A3BA FF1A -A3BB FF1B -A3BC FF1C -A3BD FF1D -A3BE FF1E -A3BF FF1F -A3C0 FF20 -A3C1 FF21 -A3C2 FF22 -A3C3 FF23 -A3C4 FF24 -A3C5 FF25 -A3C6 FF26 -A3C7 FF27 -A3C8 FF28 -A3C9 FF29 -A3CA FF2A -A3CB FF2B -A3CC FF2C -A3CD FF2D -A3CE FF2E -A3CF FF2F -A3D0 FF30 -A3D1 FF31 -A3D2 FF32 -A3D3 FF33 -A3D4 FF34 -A3D5 FF35 -A3D6 FF36 -A3D7 FF37 -A3D8 FF38 -A3D9 FF39 -A3DA FF3A -A3DB FF3B -A3DC FF3C -A3DD FF3D -A3DE FF3E -A3DF FF3F -A3E0 FF40 -A3E1 FF41 -A3E2 FF42 -A3E3 FF43 -A3E4 FF44 -A3E5 FF45 -A3E6 FF46 -A3E7 FF47 -A3E8 FF48 -A3E9 FF49 -A3EA FF4A -A3EB FF4B -A3EC FF4C -A3ED FF4D -A3EE FF4E -A3EF FF4F -A3F0 FF50 -A3F1 FF51 -A3F2 FF52 -A3F3 FF53 -A3F4 FF54 -A3F5 FF55 -A3F6 FF56 -A3F7 FF57 -A3F8 FF58 -A3F9 FF59 -A3FA FF5A -A3FB FF5B -A3FC FF5C -A3FD FF5D -A1AB FF5E -84319535 FF5F -84319536 FF60 -84319537 FF61 -84319538 FF62 -84319539 FF63 -84319630 FF64 -84319631 FF65 -84319632 FF66 -84319633 FF67 -84319634 FF68 -84319635 FF69 -84319636 FF6A -84319637 FF6B -84319638 FF6C -84319639 FF6D -84319730 FF6E -84319731 FF6F -84319732 FF70 -84319733 FF71 -84319734 FF72 -84319735 FF73 -84319736 FF74 -84319737 FF75 -84319738 FF76 -84319739 FF77 -84319830 FF78 -84319831 FF79 -84319832 FF7A -84319833 FF7B -84319834 FF7C -84319835 FF7D -84319836 FF7E -84319837 FF7F -84319838 FF80 -84319839 FF81 -84319930 FF82 -84319931 FF83 -84319932 FF84 -84319933 FF85 -84319934 FF86 -84319935 FF87 -84319936 FF88 -84319937 FF89 -84319938 FF8A -84319939 FF8B -84319A30 FF8C -84319A31 FF8D -84319A32 FF8E -84319A33 FF8F -84319A34 FF90 -84319A35 FF91 -84319A36 FF92 -84319A37 FF93 -84319A38 FF94 -84319A39 FF95 -84319B30 FF96 -84319B31 FF97 -84319B32 FF98 -84319B33 FF99 -84319B34 FF9A -84319B35 FF9B -84319B36 FF9C -84319B37 FF9D -84319B38 FF9E -84319B39 FF9F -84319C30 FFA0 -84319C31 FFA1 -84319C32 FFA2 -84319C33 FFA3 -84319C34 FFA4 -84319C35 FFA5 -84319C36 FFA6 -84319C37 FFA7 -84319C38 FFA8 -84319C39 FFA9 -84319D30 FFAA -84319D31 FFAB -84319D32 FFAC -84319D33 FFAD -84319D34 FFAE -84319D35 FFAF -84319D36 FFB0 -84319D37 FFB1 -84319D38 FFB2 -84319D39 FFB3 -84319E30 FFB4 -84319E31 FFB5 -84319E32 FFB6 -84319E33 FFB7 -84319E34 FFB8 -84319E35 FFB9 -84319E36 FFBA -84319E37 FFBB -84319E38 FFBC -84319E39 FFBD -84319F30 FFBE -84319F31 FFBF -84319F32 FFC0 -84319F33 FFC1 -84319F34 FFC2 -84319F35 FFC3 -84319F36 FFC4 -84319F37 FFC5 -84319F38 FFC6 -84319F39 FFC7 -8431A030 FFC8 -8431A031 FFC9 -8431A032 FFCA -8431A033 FFCB -8431A034 FFCC -8431A035 FFCD -8431A036 FFCE -8431A037 FFCF -8431A038 FFD0 -8431A039 FFD1 -8431A130 FFD2 -8431A131 FFD3 -8431A132 FFD4 -8431A133 FFD5 -8431A134 FFD6 -8431A135 FFD7 -8431A136 FFD8 -8431A137 FFD9 -8431A138 FFDA -8431A139 FFDB -8431A230 FFDC -8431A231 FFDD -8431A232 FFDE -8431A233 FFDF -A1E9 FFE0 -A1EA FFE1 -A956 FFE2 -A3FE FFE3 -A957 FFE4 -A3A4 FFE5 -8431A234 FFE6 -8431A235 FFE7 -8431A236 FFE8 -8431A237 FFE9 -8431A238 FFEA -8431A239 FFEB -8431A330 FFEC -8431A331 FFED -8431A332 FFEE -8431A333 FFEF -8431A334 FFF0 -8431A335 FFF1 -8431A336 FFF2 -8431A337 FFF3 -8431A338 FFF4 -8431A339 FFF5 -8431A430 FFF6 -8431A431 FFF7 -8431A432 FFF8 -8431A433 FFF9 -8431A434 FFFA -8431A435 FFFB -8431A436 FFFC -8431A437 FFFD -#8431A438 FFFE -#8431A439 FFFF diff -Nru openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-aix openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-aix --- openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-aix 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-aix 2023-07-05 07:11:54.000000000 +0000 @@ -7,7 +7,6 @@ EUC_CN EUC_KR GBK -GB18030 IBM856 IBM921 IBM922 diff -Nru openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-linux openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-linux --- openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-linux 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-linux 2023-07-05 07:11:54.000000000 +0000 @@ -11,7 +11,6 @@ EUC_JP_Open EUC_TW GBK -GB18030 ISO_8859_11 ISO_8859_3 ISO_8859_6 diff -Nru openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-solaris openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-solaris --- openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-solaris 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-solaris 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# -# generate these charsets into sun.nio.cs -# -Big5 -Big5_Solaris -Big5_HKSCS # always together with Big5 -EUC_CN -EUC_KR -EUC_JP -EUC_JP_LINUX -EUC_JP_Open -EUC_TW -GBK -GB18030 -ISO_8859_11 -ISO_8859_3 -ISO_8859_6 -ISO_8859_8 -Johab -PCK -TIS_620 -JIS_X_0201 -JIS_X_0208 -JIS_X_0212 -JIS_X_0208_Solaris -JIS_X_0212_Solaris diff -Nru openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-windows openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-windows --- openjdk-17-17.0.7+7~us1/make/data/charsetmapping/stdcs-windows 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/charsetmapping/stdcs-windows 2023-07-05 07:11:54.000000000 +0000 @@ -2,7 +2,6 @@ # generate these charsets into sun.nio.cs # GBK -GB18030 Johab MS1255 MS1256 diff -Nru openjdk-17-17.0.7+7~us1/make/data/currency/CurrencyData.properties openjdk-17-17.0.8+7/make/data/currency/CurrencyData.properties --- openjdk-17-17.0.7+7~us1/make/data/currency/CurrencyData.properties 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/currency/CurrencyData.properties 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ # Version of the currency code information in this class. # It is a serial number that accompanies with each amendment. -dataVersion=174 +dataVersion=175 # List of all valid ISO 4217 currency codes. # To ensure compatibility, do not remove codes. diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/africa openjdk-17-17.0.8+7/make/data/tzdata/africa --- openjdk-17-17.0.7+7~us1/make/data/tzdata/africa 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/africa 2023-07-05 07:11:54.000000000 +0000 @@ -344,6 +344,14 @@ # From Mina Samuel (2016-07-04): # Egyptian government took the decision to cancel the DST, +# From Ahmad ElDardiry (2023-03-01): +# Egypt officially announced today that daylight savings will be +# applied from last Friday of April to last Thursday of October. +# From Paul Eggert (2023-03-01): +# Assume transitions are at 00:00 and 24:00 respectively. +# From Amir Adib (2023-03-07): +# https://www.facebook.com/EgyptianCabinet/posts/638829614954129/ + Rule Egypt 2008 only - Aug lastThu 24:00 0 - Rule Egypt 2009 only - Aug 20 24:00 0 - Rule Egypt 2010 only - Aug 10 24:00 0 - @@ -353,6 +361,8 @@ Rule Egypt 2014 only - Jun 26 24:00 0 - Rule Egypt 2014 only - Jul 31 24:00 1:00 S Rule Egypt 2014 only - Sep lastThu 24:00 0 - +Rule Egypt 2023 max - Apr lastFri 0:00 1:00 S +Rule Egypt 2023 max - Oct lastThu 24:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] #STDOFF 2:05:08.9 @@ -452,7 +462,7 @@ # President William R. Tolbert, Jr., July 23, 1971-July 31, 1972. # Monrovia: Executive Mansion. # -# Use the abbreviation "MMT" before 1972, as the more-accurate numeric +# Use the abbreviation "MMT" before 1972, as the more accurate numeric # abbreviation "-004430" would be one byte over the POSIX limit. # # Zone NAME STDOFF RULES FORMAT [UNTIL] @@ -589,8 +599,8 @@ # DST the coming summer... # # Some sources, in French: -# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB -# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints- +# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-«-L%E2%80%99heure-d%E2%80%99été-ne-sera-pas-appliquée-cette-année-» +# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-économie-d-énergie-de-l-heure-d-été-ont-été-atteints- # # Our wrap-up: # https://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html @@ -721,7 +731,7 @@ # More articles in the press # https://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-leve.html # http://www.lematin.ma/Actualite/Express/Article.asp?id=148923 -# http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT%2B1-a-partir-de-dim +# http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT+1-a-partir-de-dim # From Petr Machata (2011-03-30): # They have it written in English here: @@ -736,7 +746,7 @@ # According to Infomédiaire web site from Morocco (infomediaire.ma), # on March 9, 2012, (in French) Heure légale: # Le Maroc adopte officiellement l'heure d'été -# http://www.infomediaire.ma/news/maroc/heure-l%C3%A9gale-le-maroc-adopte-officiellement-lheure-d%C3%A9t%C3%A9 +# http://www.infomediaire.ma/news/maroc/heure-légale-le-maroc-adopte-officiellement-lheure-dété # Governing Council adopted draft decree, that Morocco DST starts on # the last Sunday of March (March 25, 2012) and ends on # last Sunday of September (September 30, 2012) @@ -860,19 +870,28 @@ # Friday or Saturday (and so the 2 days off are on a weekend), the next time # shift will be the next weekend. # -# From Paul Eggert (2020-05-31): +# From Milamber (2021-03-31, 2022-03-10): +# https://www.mmsp.gov.ma/fr/actualites.aspx?id=2076 +# https://www.ecoactu.ma/horaires-administration-ramadan-gmtheure-gmt-a-partir-de-dimanche-27-mars/ +# +# From Milamber (2023-03-14, 2023-03-15): +# The return to legal GMT time will take place this Sunday, March 19 at 3 a.m. +# ... the return to GMT+1 will be made on Sunday April 23, 2023 at 2 a.m. +# https://www.mmsp.gov.ma/fr/actualites/passage-à-l%E2%80%99heure-gmt-à-partir-du-dimanche-19-mars-2023 +# +# From Paul Eggert (2023-03-14): # For now, guess that in the future Morocco will fall back at 03:00 # the last Sunday before Ramadan, and spring forward at 02:00 the -# first Sunday after two days after Ramadan. To implement this, +# first Sunday after one day after Ramadan. To implement this, # transition dates and times for 2019 through 2087 were determined by -# running the following program under GNU Emacs 26.3. (This algorithm +# running the following program under GNU Emacs 28.2. (This algorithm # also produces the correct transition dates for 2016 through 2018, # though the times differ due to Morocco's time zone change in 2018.) # (let ((islamic-year 1440)) # (require 'cal-islam) # (while (< islamic-year 1511) # (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year))) -# (b (+ 2 (calendar-islamic-to-absolute (list 10 1 islamic-year)))) +# (b (+ 1 (calendar-islamic-to-absolute (list 10 1 islamic-year)))) # (sunday 0)) # (while (/= sunday (mod (setq a (1- a)) 7))) # (while (/= sunday (mod b 7)) @@ -886,10 +905,6 @@ # (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a)) # (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b))))) # (setq islamic-year (+ 1 islamic-year)))) -# -# From Milamber (2021-03-31, 2022-03-10), confirming these predictions: -# https://www.mmsp.gov.ma/fr/actualites.aspx?id=2076 -# https://www.ecoactu.ma/horaires-administration-ramadan-gmtheure-gmt-a-partir-de-dimanche-27-mars/ # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Morocco 1939 only - Sep 12 0:00 1:00 - @@ -942,7 +957,7 @@ Rule Morocco 2022 only - Mar 27 3:00 -1:00 - Rule Morocco 2022 only - May 8 2:00 0 - Rule Morocco 2023 only - Mar 19 3:00 -1:00 - -Rule Morocco 2023 only - Apr 30 2:00 0 - +Rule Morocco 2023 only - Apr 23 2:00 0 - Rule Morocco 2024 only - Mar 10 3:00 -1:00 - Rule Morocco 2024 only - Apr 14 2:00 0 - Rule Morocco 2025 only - Feb 23 3:00 -1:00 - @@ -958,7 +973,7 @@ Rule Morocco 2029 only - Dec 30 3:00 -1:00 - Rule Morocco 2030 only - Feb 10 2:00 0 - Rule Morocco 2030 only - Dec 22 3:00 -1:00 - -Rule Morocco 2031 only - Feb 2 2:00 0 - +Rule Morocco 2031 only - Jan 26 2:00 0 - Rule Morocco 2031 only - Dec 14 3:00 -1:00 - Rule Morocco 2032 only - Jan 18 2:00 0 - Rule Morocco 2032 only - Nov 28 3:00 -1:00 - @@ -974,7 +989,7 @@ Rule Morocco 2037 only - Oct 4 3:00 -1:00 - Rule Morocco 2037 only - Nov 15 2:00 0 - Rule Morocco 2038 only - Sep 26 3:00 -1:00 - -Rule Morocco 2038 only - Nov 7 2:00 0 - +Rule Morocco 2038 only - Oct 31 2:00 0 - Rule Morocco 2039 only - Sep 18 3:00 -1:00 - Rule Morocco 2039 only - Oct 23 2:00 0 - Rule Morocco 2040 only - Sep 2 3:00 -1:00 - @@ -990,7 +1005,7 @@ Rule Morocco 2045 only - Jul 9 3:00 -1:00 - Rule Morocco 2045 only - Aug 20 2:00 0 - Rule Morocco 2046 only - Jul 1 3:00 -1:00 - -Rule Morocco 2046 only - Aug 12 2:00 0 - +Rule Morocco 2046 only - Aug 5 2:00 0 - Rule Morocco 2047 only - Jun 23 3:00 -1:00 - Rule Morocco 2047 only - Jul 28 2:00 0 - Rule Morocco 2048 only - Jun 7 3:00 -1:00 - @@ -1006,7 +1021,7 @@ Rule Morocco 2053 only - Apr 13 3:00 -1:00 - Rule Morocco 2053 only - May 25 2:00 0 - Rule Morocco 2054 only - Apr 5 3:00 -1:00 - -Rule Morocco 2054 only - May 17 2:00 0 - +Rule Morocco 2054 only - May 10 2:00 0 - Rule Morocco 2055 only - Mar 28 3:00 -1:00 - Rule Morocco 2055 only - May 2 2:00 0 - Rule Morocco 2056 only - Mar 12 3:00 -1:00 - @@ -1022,7 +1037,7 @@ Rule Morocco 2061 only - Jan 16 3:00 -1:00 - Rule Morocco 2061 only - Feb 27 2:00 0 - Rule Morocco 2062 only - Jan 8 3:00 -1:00 - -Rule Morocco 2062 only - Feb 19 2:00 0 - +Rule Morocco 2062 only - Feb 12 2:00 0 - Rule Morocco 2062 only - Dec 31 3:00 -1:00 - Rule Morocco 2063 only - Feb 4 2:00 0 - Rule Morocco 2063 only - Dec 16 3:00 -1:00 - @@ -1038,7 +1053,7 @@ Rule Morocco 2068 only - Oct 21 3:00 -1:00 - Rule Morocco 2068 only - Dec 2 2:00 0 - Rule Morocco 2069 only - Oct 13 3:00 -1:00 - -Rule Morocco 2069 only - Nov 24 2:00 0 - +Rule Morocco 2069 only - Nov 17 2:00 0 - Rule Morocco 2070 only - Oct 5 3:00 -1:00 - Rule Morocco 2070 only - Nov 9 2:00 0 - Rule Morocco 2071 only - Sep 20 3:00 -1:00 - @@ -1054,7 +1069,7 @@ Rule Morocco 2076 only - Jul 26 3:00 -1:00 - Rule Morocco 2076 only - Sep 6 2:00 0 - Rule Morocco 2077 only - Jul 18 3:00 -1:00 - -Rule Morocco 2077 only - Aug 29 2:00 0 - +Rule Morocco 2077 only - Aug 22 2:00 0 - Rule Morocco 2078 only - Jul 10 3:00 -1:00 - Rule Morocco 2078 only - Aug 14 2:00 0 - Rule Morocco 2079 only - Jun 25 3:00 -1:00 - @@ -1064,13 +1079,13 @@ Rule Morocco 2081 only - Jun 1 3:00 -1:00 - Rule Morocco 2081 only - Jul 13 2:00 0 - Rule Morocco 2082 only - May 24 3:00 -1:00 - -Rule Morocco 2082 only - Jul 5 2:00 0 - +Rule Morocco 2082 only - Jun 28 2:00 0 - Rule Morocco 2083 only - May 16 3:00 -1:00 - Rule Morocco 2083 only - Jun 20 2:00 0 - Rule Morocco 2084 only - Apr 30 3:00 -1:00 - Rule Morocco 2084 only - Jun 11 2:00 0 - Rule Morocco 2085 only - Apr 22 3:00 -1:00 - -Rule Morocco 2085 only - Jun 3 2:00 0 - +Rule Morocco 2085 only - May 27 2:00 0 - Rule Morocco 2086 only - Apr 14 3:00 -1:00 - Rule Morocco 2086 only - May 19 2:00 0 - Rule Morocco 2087 only - Mar 30 3:00 -1:00 - @@ -1213,15 +1228,15 @@ # From P Chan (2020-12-03): # GMT was adopted as the standard time of Lagos on 1905-07-01. # Lagos Weekly Record, 1905-06-24, p 3 -# http://ddsnext.crl.edu/titles/31558#?c=0&m=668&s=0&cv=2&r=0&xywh=1446%2C5221%2C1931%2C1235 +# http://ddsnext.crl.edu/titles/31558#?c=0&m=668&s=0&cv=2&r=0&xywh=1446,5221,1931,1235 # says "It is officially notified that on and after the 1st of July 1905 -# Greenwich Mean Solar Time will be adopted thought the Colony and +# Greenwich Mean Solar Time will be adopted throughout the Colony and # Protectorate, and that it will be necessary to put all clocks 13 minutes and # 35 seconds back, recording local mean time." # # It seemed that Lagos returned to LMT on 1908-07-01. # [The Lagos Standard], 1908-07-01, p 5 -# http://ddsnext.crl.edu/titles/31556#?c=0&m=78&s=0&cv=4&r=0&xywh=-92%2C3590%2C3944%2C2523 +# http://ddsnext.crl.edu/titles/31556#?c=0&m=78&s=0&cv=4&r=0&xywh=-92,3590,3944,2523 # says "Scarcely have the people become accustomed to this new time, when # another official notice has now appeared announcing that from and after the # 1st July next, return will be made to local mean time." @@ -1233,7 +1248,7 @@ # https://libsysdigi.library.illinois.edu/ilharvest/Africana/Books2011-05/3064634/3064634_1914/3064634_1914_opt.pdf#page=27 # "On January 1st [1914], a universal standard time for Nigeria was adopted, # viz., half an hour fast on Greenwich mean time, corresponding to the meridian -# 7 [degrees] 30' E. long." +# 7° 30' E. long." # Lloyd's Register of Shipping (1915) says "Hitherto the time observed in Lagos # was the local mean time. On 1st January, 1914, standard time for the whole of # Nigeria was introduced ... Lagos time has been advanced about 16 minutes @@ -1251,7 +1266,7 @@ # The Lagos Weekly Record, 1919-09-20, p 3 details discussion on the first # reading of this Bill by the Legislative Council of the Colony of Nigeria on # Thursday 1919-08-28: -# http://ddsnext.crl.edu/titles/31558?terms&item_id=303484#?m=1118&c=1&s=0&cv=2&r=0&xywh=1261%2C3408%2C2994%2C1915 +# http://ddsnext.crl.edu/titles/31558?terms&item_id=303484#?m=1118&c=1&s=0&cv=2&r=0&xywh=1261,3408,2994,1915 # "The proposal is that the Globe should be divided into twelve zones East and # West of Greenwich, of one hour each, Nigeria falling into the zone with a # standard of one hour fast on Greenwich Mean Time. Nigeria standard time is diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/antarctica openjdk-17-17.0.8+7/make/data/tzdata/antarctica --- openjdk-17-17.0.7+7~us1/make/data/tzdata/antarctica 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/antarctica 2023-07-05 07:11:54.000000000 +0000 @@ -315,7 +315,7 @@ # but that he found it more convenient to keep GMT+12 # as supplies for the station were coming from McMurdo Sound, # which was on GMT+12 because New Zealand was on GMT+12 all year -# at that time (1957). (Source: Siple's book 90 Degrees South.) +# at that time (1957). (Source: Siple's book 90° South.) # # From Susan Smith # http://www.cybertours.com/whs/pole10.html diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/asia openjdk-17-17.0.8+7/make/data/tzdata/asia --- openjdk-17-17.0.7+7~us1/make/data/tzdata/asia 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/asia 2023-07-05 07:11:54.000000000 +0000 @@ -2714,6 +2714,40 @@ # Lebanon +# +# From Saadallah Itani (2023-03-23): +# Lebanon ... announced today delay of Spring forward from March 25 to April 20. +# +# From Paul Eggert (2023-03-27): +# This announcement was by the Lebanese caretaker prime minister Najib Mikati. +# https://www.mtv.com.lb/en/News/Local/1352516/lebanon-postpones-daylight-saving-time-adoption +# A video was later leaked to the media of parliament speaker Nabih Berri +# asking Mikati to postpone DST to aid observance of Ramadan, Mikati objecting +# that this would cause problems such as scheduling airline flights, to which +# Berri interjected, "What flights?" +# +# The change was controversial and led to a partly-sectarian divide. +# Many Lebanese institutions, including the education ministry, the Maronite +# church, and two news channels LCBI and MTV, ignored the announcement and +# went ahead with the long-scheduled spring-forward on March 25/26, some +# arguing that the prime minister had not followed the law because the change +# had not been approved by the cabinet. Google went with the announcement; +# Apple ignored it. At least one bank followed the announcement for its doors, +# but ignored the announcement in internal computer systems. +# Beirut international airport listed two times for each departure. +# Dan Azzi wrote "My view is that this whole thing is a Dumb and Dumber movie." +# Eventually the prime minister backed down, said the cabinet had decided to +# stick with its 1998 decision, and that DST would begin midnight March 29/30. +# https://www.nna-leb.gov.lb/en/miscellaneous/604093/lebanon-has-two-times-of-day-amid-daylight-savings +# https://www.cnbc.com/2023/03/27/lebanon-in-two-different-time-zones-as-government-disagrees-on-daylight-savings.html +# +# Although we could model the chaos with two Zones, that would likely cause +# more trouble than it would cure. Since so many manual clocks and +# computer-based timestamps ignored the announcement, stick with official +# cabinet resolutions in the data while recording the prime minister's +# announcement as a comment. This is how we treated a similar situation in +# Rio de Janeiro in spring 1993. +# # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Lebanon 1920 only - Mar 28 0:00 1:00 S Rule Lebanon 1920 only - Oct 25 0:00 0 - @@ -2739,6 +2773,10 @@ Rule Lebanon 1993 max - Mar lastSun 0:00 1:00 S Rule Lebanon 1993 1998 - Sep lastSun 0:00 0 - Rule Lebanon 1999 max - Oct lastSun 0:00 0 - +# This one-time rule, announced by the prime minister first for April 21 +# then for March 30, is commented out for reasons described above. +#Rule Lebanon 2023 only - Mar 30 0:00 1:00 S + # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Beirut 2:22:00 - LMT 1880 2:00 Lebanon EE%sT @@ -2977,7 +3015,7 @@ # 9pm and moving clocks forward by one hour for the next three months. ...." # # http://www.worldtimezone.com/dst_news/dst_news_pakistan01.html -# http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4 +# http://www.dailytimes.com.pk/default.asp?page=2008\05\15\story_15-5-2008_pg1_4 # From Arthur David Olson (2008-05-19): # XXX--midnight transitions is a guess; 2008 only is a guess. @@ -3300,7 +3338,7 @@ # Some of many sources in Arabic: # http://www.samanews.com/index.php?act=Show&id=122638 # -# http://safa.ps/details/news/74352/%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-%D8%A8%D8%A7%D9%84%D8%B6%D9%81%D8%A9-%D9%88%D8%BA%D8%B2%D8%A9-%D9%84%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D8%AC%D9%85%D8%B9%D8%A9.html +# http://safa.ps/details/news/74352/بدء-التوقيت-الصيفي-بالضفة-وغزة-ليلة-الجمعة.html # # Our brief summary: # https://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html @@ -3310,7 +3348,7 @@ # time from midnight on Friday, March 29, 2013" (translated). # [These are in Arabic and are for Gaza and for Ramallah, respectively.] # http://www.samanews.com/index.php?act=Show&id=154120 -# http://safa.ps/details/news/99844/%D8%B1%D8%A7%D9%85-%D8%A7%D9%84%D9%84%D9%87-%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-29-%D8%A7%D9%84%D8%AC%D8%A7%D8%B1%D9%8A.html +# http://safa.ps/details/news/99844/رام-الله-بدء-التوقيت-الصيفي-29-الجاري.html # From Steffen Thorsen (2013-09-24): # The Gaza and West Bank are ending DST Thursday at midnight @@ -3408,9 +3446,41 @@ # (2022-08-31): ... the Saturday before the last Sunday in March and October # at 2:00 AM ,for the years from 2023 to 2026. # (2022-09-05): https://mtit.pna.ps/Site/New/1453 -# -# From Paul Eggert (2022-08-31): -# For now, assume that this rule will also be used after 2026. + +# From Heba Hamad (2023-03-22): +# ... summer time will begin in Palestine from Saturday 04-29-2023, +# 02:00 AM by 60 minutes forward. +# +# From Paul Eggert (2023-03-22): +# For now, guess that spring and fall transitions will normally +# continue to use 2022's rules, that during DST Palestine will switch +# to standard time at 02:00 the last Saturday before Ramadan and back +# to DST at 02:00 the first Saturday after Ramadan, and that +# if the normal spring-forward or fall-back transition occurs during +# Ramadan the former is delayed and the latter advanced. +# To implement this, I predicted Ramadan-oriented transition dates for +# 2023 through 2086 by running the following program under GNU Emacs 28.2, +# with the results integrated by hand into the table below. +# Predictions after 2086 are approximated without Ramadan. +# +# (let ((islamic-year 1444)) +# (require 'cal-islam) +# (while (< islamic-year 1510) +# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year))) +# (b (+ 1 (calendar-islamic-to-absolute (list 10 1 islamic-year)))) +# (saturday 6)) +# (while (/= saturday (mod (setq a (1- a)) 7))) +# (while (/= saturday (mod b 7)) +# (setq b (1+ b))) +# (setq a (calendar-gregorian-from-absolute a)) +# (setq b (calendar-gregorian-from-absolute b)) +# (insert +# (format +# (concat "Rule Palestine\t%d\tonly\t-\t%s\t%2d\t2:00\t0\t-\n" +# "Rule Palestine\t%d\tonly\t-\t%s\t%2d\t2:00\t1:00\tS\n") +# (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a)) +# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b))))) +# (setq islamic-year (+ 1 islamic-year)))) # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S @@ -3450,8 +3520,86 @@ Rule Palestine 2020 only - Oct 24 1:00 0 - Rule Palestine 2021 only - Oct 29 1:00 0 - Rule Palestine 2022 only - Mar 27 0:00 1:00 S -Rule Palestine 2022 max - Oct Sat<=30 2:00 0 - -Rule Palestine 2023 max - Mar Sat<=30 2:00 1:00 S +Rule Palestine 2022 2035 - Oct Sat<=30 2:00 0 - +Rule Palestine 2023 only - Apr 29 2:00 1:00 S +Rule Palestine 2024 only - Apr 13 2:00 1:00 S +Rule Palestine 2025 only - Apr 5 2:00 1:00 S +Rule Palestine 2026 2054 - Mar Sat<=30 2:00 1:00 S +Rule Palestine 2036 only - Oct 18 2:00 0 - +Rule Palestine 2037 only - Oct 10 2:00 0 - +Rule Palestine 2038 only - Sep 25 2:00 0 - +Rule Palestine 2039 only - Sep 17 2:00 0 - +Rule Palestine 2039 only - Oct 22 2:00 1:00 S +Rule Palestine 2039 2067 - Oct Sat<=30 2:00 0 - +Rule Palestine 2040 only - Sep 1 2:00 0 - +Rule Palestine 2040 only - Oct 13 2:00 1:00 S +Rule Palestine 2041 only - Aug 24 2:00 0 - +Rule Palestine 2041 only - Sep 28 2:00 1:00 S +Rule Palestine 2042 only - Aug 16 2:00 0 - +Rule Palestine 2042 only - Sep 20 2:00 1:00 S +Rule Palestine 2043 only - Aug 1 2:00 0 - +Rule Palestine 2043 only - Sep 12 2:00 1:00 S +Rule Palestine 2044 only - Jul 23 2:00 0 - +Rule Palestine 2044 only - Aug 27 2:00 1:00 S +Rule Palestine 2045 only - Jul 15 2:00 0 - +Rule Palestine 2045 only - Aug 19 2:00 1:00 S +Rule Palestine 2046 only - Jun 30 2:00 0 - +Rule Palestine 2046 only - Aug 11 2:00 1:00 S +Rule Palestine 2047 only - Jun 22 2:00 0 - +Rule Palestine 2047 only - Jul 27 2:00 1:00 S +Rule Palestine 2048 only - Jun 6 2:00 0 - +Rule Palestine 2048 only - Jul 18 2:00 1:00 S +Rule Palestine 2049 only - May 29 2:00 0 - +Rule Palestine 2049 only - Jul 3 2:00 1:00 S +Rule Palestine 2050 only - May 21 2:00 0 - +Rule Palestine 2050 only - Jun 25 2:00 1:00 S +Rule Palestine 2051 only - May 6 2:00 0 - +Rule Palestine 2051 only - Jun 17 2:00 1:00 S +Rule Palestine 2052 only - Apr 27 2:00 0 - +Rule Palestine 2052 only - Jun 1 2:00 1:00 S +Rule Palestine 2053 only - Apr 12 2:00 0 - +Rule Palestine 2053 only - May 24 2:00 1:00 S +Rule Palestine 2054 only - Apr 4 2:00 0 - +Rule Palestine 2054 only - May 16 2:00 1:00 S +Rule Palestine 2055 only - May 1 2:00 1:00 S +Rule Palestine 2056 only - Apr 22 2:00 1:00 S +Rule Palestine 2057 only - Apr 7 2:00 1:00 S +Rule Palestine 2058 max - Mar Sat<=30 2:00 1:00 S +Rule Palestine 2068 only - Oct 20 2:00 0 - +Rule Palestine 2069 only - Oct 12 2:00 0 - +Rule Palestine 2070 only - Oct 4 2:00 0 - +Rule Palestine 2071 only - Sep 19 2:00 0 - +Rule Palestine 2072 only - Sep 10 2:00 0 - +Rule Palestine 2072 only - Oct 15 2:00 1:00 S +Rule Palestine 2073 only - Sep 2 2:00 0 - +Rule Palestine 2073 only - Oct 7 2:00 1:00 S +Rule Palestine 2074 only - Aug 18 2:00 0 - +Rule Palestine 2074 only - Sep 29 2:00 1:00 S +Rule Palestine 2075 only - Aug 10 2:00 0 - +Rule Palestine 2075 only - Sep 14 2:00 1:00 S +Rule Palestine 2075 max - Oct Sat<=30 2:00 0 - +Rule Palestine 2076 only - Jul 25 2:00 0 - +Rule Palestine 2076 only - Sep 5 2:00 1:00 S +Rule Palestine 2077 only - Jul 17 2:00 0 - +Rule Palestine 2077 only - Aug 28 2:00 1:00 S +Rule Palestine 2078 only - Jul 9 2:00 0 - +Rule Palestine 2078 only - Aug 13 2:00 1:00 S +Rule Palestine 2079 only - Jun 24 2:00 0 - +Rule Palestine 2079 only - Aug 5 2:00 1:00 S +Rule Palestine 2080 only - Jun 15 2:00 0 - +Rule Palestine 2080 only - Jul 20 2:00 1:00 S +Rule Palestine 2081 only - Jun 7 2:00 0 - +Rule Palestine 2081 only - Jul 12 2:00 1:00 S +Rule Palestine 2082 only - May 23 2:00 0 - +Rule Palestine 2082 only - Jul 4 2:00 1:00 S +Rule Palestine 2083 only - May 15 2:00 0 - +Rule Palestine 2083 only - Jun 19 2:00 1:00 S +Rule Palestine 2084 only - Apr 29 2:00 0 - +Rule Palestine 2084 only - Jun 10 2:00 1:00 S +Rule Palestine 2085 only - Apr 21 2:00 0 - +Rule Palestine 2085 only - Jun 2 2:00 1:00 S +Rule Palestine 2086 only - Apr 13 2:00 0 - +Rule Palestine 2086 only - May 18 2:00 1:00 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct @@ -3655,7 +3803,7 @@ # standard time is SLST. # # From Paul Eggert (2016-10-18): -# "SLST" seems to be reasonably recent and rarely-used outside time +# "SLST" seems to be reasonably recent and rarely used outside time # zone nerd sources. I searched Google News and found three uses of # it in the International Business Times of India in February and # March of this year when discussing cricket match times, but nothing diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/australasia openjdk-17-17.0.8+7/make/data/tzdata/australasia --- openjdk-17-17.0.7+7~us1/make/data/tzdata/australasia 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/australasia 2023-07-05 07:11:54.000000000 +0000 @@ -346,7 +346,7 @@ # From Steffen Thorsen (2013-01-10): # Fiji will end DST on 2014-01-19 02:00: -# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-%281%29.aspx +# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-(1).aspx # From Ken Rylander (2014-10-20): # DST will start Nov. 2 this year. @@ -746,7 +746,7 @@ # # Samoa's Daylight Saving Time Act 2009 is available here, but does not # contain any dates: -# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf +# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20(English)%20-%20Final%207-7-091.pdf # From Laupue Raymond Hughes (2010-10-07): # Please see @@ -1831,7 +1831,7 @@ # period. It would probably be reasonable to assume Guam use GMT+9 during # that period of time like the surrounding area. -# From Paul Eggert (2018-11-18): +# From Paul Eggert (2023-01-23): # Howse writes (p 153) "The Spaniards, on the other hand, reached the # Philippines and the Ladrones from America," and implies that the Ladrones # (now called the Marianas) kept American date for quite some time. @@ -1844,7 +1844,7 @@ # they did as that avoids the need for a separate zone due to our 1970 cutoff. # # US Public Law 106-564 (2000-12-23) made UT +10 the official standard time, -# under the name "Chamorro Standard Time". There is no official abbreviation, +# under the name "Chamorro standard time". There is no official abbreviation, # but Congressman Robert A. Underwood, author of the bill that became law, # wrote in a press release (2000-12-27) that he will seek the use of "ChST". @@ -2222,24 +2222,18 @@ # an international standard, there are some places on the high seas where the # correct date is ambiguous. -# From Wikipedia (2005-08-31): -# Before 1920, all ships kept local apparent time on the high seas by setting -# their clocks at night or at the morning sight so that, given the ship's -# speed and direction, it would be 12 o'clock when the Sun crossed the ship's -# meridian (12 o'clock = local apparent noon). During 1917, at the -# Anglo-French Conference on Time-keeping at Sea, it was recommended that all -# ships, both military and civilian, should adopt hourly standard time zones -# on the high seas. Whenever a ship was within the territorial waters of any -# nation it would use that nation's standard time. The captain was permitted -# to change his ship's clocks at a time of his choice following his ship's -# entry into another zone time - he often chose midnight. These zones were -# adopted by all major fleets between 1920 and 1925 but not by many -# independent merchant ships until World War II. - -# From Paul Eggert, using references suggested by Oscar van Vlijmen -# (2005-03-20): -# -# The American Practical Navigator (2002) -# http://pollux.nss.nima.mil/pubs/pubs_j_apn_sections.html?rid=187 -# talks only about the 180-degree meridian with respect to ships in -# international waters; it ignores the international date line. +# From Wikipedia (2023-01-23): +# The nautical time zone system is analogous to the terrestrial time zone +# system for use on high seas. Under the system time changes are required for +# changes of longitude in one-hour steps. The one-hour step corresponds to a +# time zone width of 15° longitude. The 15° gore that is offset from GMT or +# UT1 (not UTC) by twelve hours is bisected by the nautical date line into two +# 7°30' gores that differ from GMT by ±12 hours. A nautical date line is +# implied but not explicitly drawn on time zone maps. It follows the 180th +# meridian except where it is interrupted by territorial waters adjacent to +# land, forming gaps: it is a pole-to-pole dashed line. + +# From Paul Eggert (2023-01-23): +# The American Practical Navigator , +# 2019 edition, merely says that the International Date Line +# "coincides with the 180th meridian over most of its length." diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/backward openjdk-17-17.0.8+7/make/data/tzdata/backward --- openjdk-17-17.0.7+7~us1/make/data/tzdata/backward 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/backward 2023-07-05 07:11:54.000000000 +0000 @@ -297,6 +297,7 @@ Link America/Tijuana America/Santa_Isabel Link America/Denver America/Shiprock Link America/Toronto America/Thunder_Bay +Link America/Edmonton America/Yellowknife Link Pacific/Auckland Antarctica/South_Pole Link Asia/Shanghai Asia/Chongqing Link Asia/Shanghai Asia/Harbin diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/europe openjdk-17-17.0.8+7/make/data/tzdata/europe --- openjdk-17-17.0.7+7~us1/make/data/tzdata/europe 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/europe 2023-07-05 07:11:54.000000000 +0000 @@ -540,9 +540,7 @@ # other form with a traditional approximation for Irish timestamps # after 1971-10-31 02:00 UTC; although this approximation has tm_isdst # flags that are reversed, its UTC offsets are correct and this often -# suffices. This source file currently uses only nonnegative SAVE -# values, but this is intended to change and downstream code should -# not rely on it. +# suffices.... # # The following is like GB-Eire and EU, except with standard time in # summer and negative daylight saving time in winter. It is for when @@ -1136,19 +1134,18 @@ # # From Jürgen Appel (2022-11-25): # https://ina.gl/samlinger/oversigt-over-samlinger/samling/dagsordener/dagsorden.aspx?lang=da&day=24-11-2022 -# If I understand this correctly, from the next planned switch to -# summer time, Greenland will permanently stay at that time, i.e. no -# switch back to winter time in 2023 will occur. -# -# From Paul Eggert (2022-11-28): -# The official document in Danish -# https://naalakkersuisut.gl/-/media/naalakkersuisut/filer/kundgoerelser/2022/11/2511/31_da_inatsisartutlov-om-tidens-bestemmelse.pdf?la=da&hash=A33597D8A38CC7038465241119EF34F3 -# says standard time for Greenland is -02, that Naalakkersuisut can lay down -# rules for DST and can require some areas to use a different time zone, -# and that this all takes effect 2023-03-25 22:00. The abovementioned -# "bekymringer" URL says the intent is no transition March 25, that -# Greenland will not go back to winter time in fall 2023, and that -# only America/Nuuk is affected (though further changes may occur). +# +# From Thomas M. Steenholdt (2022-12-02): +# - The bill to move America/Nuuk from UTC-03 to UTC-02 passed. +# - The bill to stop observing DST did not (Greenland will stop observing DST +# when EU does). +# Details on the implementation are here (section 6): +# https://ina.gl/dvd/EM%202022/pdf/media/2553529/pkt17_em2022_tidens_bestemmelse_bem_da.pdf +# This is how the change will be implemented: +# 1. The shift *to* DST in 2023 happens as normal. +# 2. The shift *from* DST in 2023 happens as normal, but coincides with the +# shift to UTC-02 normaltime (people will not change their clocks here). +# 3. After this, DST is still observed, but as -02/-01 instead of -03/-02. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Thule 1991 1992 - Mar lastSun 2:00 1:00 D @@ -1172,8 +1169,8 @@ -1:00 EU -01/+00 Zone America/Nuuk -3:26:56 - LMT 1916 Jul 28 # Godthåb -3:00 - -03 1980 Apr 6 2:00 - -3:00 EU -03/-02 2023 Mar 25 22:00 - -2:00 - -02 + -3:00 EU -03/-02 2023 Oct 29 1:00u + -2:00 EU -02/-01 Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik -4:00 Thule A%sT @@ -1509,9 +1506,9 @@ Rule Germany 1946 only - Apr 14 2:00s 1:00 S Rule Germany 1946 only - Oct 7 2:00s 0 - Rule Germany 1947 1949 - Oct Sun>=1 2:00s 0 - -# http://www.ptb.de/de/org/4/44/441/salt.htm says the following transition -# occurred at 3:00 MEZ, not the 2:00 MEZ given in Shanks & Pottenger. -# Go with the PTB. +# https://www.ptb.de/cms/en/ptb/fachabteilungen/abt4/fb-44/ag-441/realisation-of-legal-time-in-germany/dst-and-midsummer-dst-in-germany-until-1979.html +# says the following transition occurred at 3:00 MEZ, not the 2:00 MEZ +# given in Shanks & Pottenger. Go with the PTB. Rule Germany 1947 only - Apr 6 3:00s 1:00 S Rule Germany 1947 only - May 11 2:00s 2:00 M Rule Germany 1947 only - Jun 29 3:00 1:00 S @@ -2272,7 +2269,7 @@ # the State Duma has approved ... the draft bill on returning to # winter time standard and return Russia 11 time zones. The new # regulations will come into effect on October 26, 2014 at 02:00 ... -# http://asozd2.duma.gov.ru/main.nsf/%28Spravka%29?OpenAgent&RN=431985-6&02 +# http://asozd2.duma.gov.ru/main.nsf/(Spravka)?OpenAgent&RN=431985-6&02 # Here is a link where we put together table (based on approved Bill N # 431985-6) with proposed 11 Russian time zones and corresponding # areas/cities/administrative centers in the Russian Federation (in English): @@ -2682,13 +2679,13 @@ 3:00 - +03 1930 Jun 21 4:00 - +04 1961 Nov 11 4:00 Russia +04/+05 1988 Mar 27 2:00s - 3:00 Russia +03/+04 1991 Mar 31 2:00s + 3:00 Russia MSK/MSD 1991 Mar 31 2:00s 4:00 - +04 1992 Mar 29 2:00s - 3:00 Russia +03/+04 2011 Mar 27 2:00s - 4:00 - +04 2014 Oct 26 2:00s - 3:00 - +03 2018 Oct 28 2:00s + 3:00 Russia MSK/MSD 2011 Mar 27 2:00s + 4:00 - MSK 2014 Oct 26 2:00s + 3:00 - MSK 2018 Oct 28 2:00s 4:00 - +04 2020 Dec 27 2:00s - 3:00 - +03 + 3:00 - MSK # From Paul Eggert (2016-11-11): # Europe/Saratov covers: @@ -2719,11 +2716,11 @@ Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0:00u 3:00 - +03 1930 Jun 21 4:00 Russia +04/+05 1989 Mar 26 2:00s - 3:00 Russia +03/+04 1991 Mar 31 2:00s + 3:00 Russia MSK/MSD 1991 Mar 31 2:00s 4:00 - +04 1992 Mar 29 2:00s - 3:00 Russia +03/+04 2011 Mar 27 2:00s - 4:00 - +04 2014 Oct 26 2:00s - 3:00 - +03 + 3:00 Russia MSK/MSD 2011 Mar 27 2:00s + 4:00 - MSK 2014 Oct 26 2:00s + 3:00 - MSK # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): # Europe/Samara covers... diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/iso3166.tab openjdk-17-17.0.8+7/make/data/tzdata/iso3166.tab --- openjdk-17-17.0.7+7~us1/make/data/tzdata/iso3166.tab 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/iso3166.tab 2023-07-05 07:11:54.000000000 +0000 @@ -261,7 +261,7 @@ SZ Eswatini (Swaziland) TC Turks & Caicos Is TD Chad -TF French Southern Territories +TF French S. Terr. TG Togo TH Thailand TJ Tajikistan diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/leapseconds openjdk-17-17.0.8+7/make/data/tzdata/leapseconds --- openjdk-17-17.0.7+7~us1/make/data/tzdata/leapseconds 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/leapseconds 2023-07-05 07:11:54.000000000 +0000 @@ -95,11 +95,11 @@ # Any additional leap seconds will come after this. # This Expires line is commented out for now, # so that pre-2020a zic implementations do not reject this file. -#Expires 2023 Jun 28 00:00:00 +#Expires 2023 Dec 28 00:00:00 # POSIX timestamps for the data in this file: #updated 1467936000 (2016-07-08 00:00:00 UTC) -#expires 1687910400 (2023-06-28 00:00:00 UTC) +#expires 1703721600 (2023-12-28 00:00:00 UTC) -# Updated through IERS Bulletin C64 -# File expires on: 28 June 2023 +# Updated through IERS Bulletin C65 +# File expires on: 28 December 2023 diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/northamerica openjdk-17-17.0.8+7/make/data/tzdata/northamerica --- openjdk-17-17.0.7+7~us1/make/data/tzdata/northamerica 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/northamerica 2023-07-05 07:11:54.000000000 +0000 @@ -1,4 +1,3 @@ -# # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -299,9 +298,10 @@ # -10 Standard Alaska Time (AST) Alaska-Hawaii standard time (AHST) # -11 (unofficial) Nome (NST) Bering standard time (BST) # -# From Paul Eggert (2000-01-08), following a heads-up from Rives McDow: -# Public law 106-564 (2000-12-23) introduced ... "Chamorro Standard Time" +# From Paul Eggert (2023-01-23), from a 2001-01-08 heads-up from Rives McDow: +# Public law 106-564 (2000-12-23) introduced "Chamorro standard time" # for time in Guam and the Northern Marianas. See the file "australasia". +# Also see 15 U.S.C. §263 . # # From Paul Eggert (2015-04-17): # HST and HDT are standardized abbreviations for Hawaii-Aleutian @@ -618,7 +618,7 @@ # local times of other Alaskan locations so that they change simultaneously. # From Paul Eggert (2014-07-18): -# One opinion of the early-1980s turmoil in Alaska over time zones and +# One opinion of the early 1980s turmoil in Alaska over time zones and # daylight saving time appeared as graffiti on a Juneau airport wall: # "Welcome to Juneau. Please turn your watch back to the 19th century." # See: Turner W. Alaska's four time zones now two. NY Times 1983-11-01. @@ -690,6 +690,10 @@ # So they won't be waiting for Alaska to join them on 2019-03-10, but will # rather change their clocks twice in seven weeks. +# From Paul Eggert (2023-01-23): +# America/Adak is for the Aleutian Islands that are part of Alaska +# and are west of 169.5° W. + # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32 -8:57:41 - LMT 1900 Aug 20 12:00 @@ -2148,10 +2152,6 @@ # Nunavut ... moved ... to incorporate the whole territory into one time zone. # Nunavut moves to single time zone Oct. 31 # http://www.nunatsiaq.com/nunavut/nvt90903_13.html -# -# From Antoine Leca (1999-09-06): -# We then need to create a new timezone for the Kitikmeot region of Nunavut -# to differentiate it from the Yellowknife region. # From Paul Eggert (1999-09-20): # Basic Facts: The New Territory @@ -2345,9 +2345,6 @@ -5:00 - EST 2000 Nov 5 0:00 -6:00 - CST 2001 Apr 1 3:00 -7:00 Canada M%sT -Zone America/Yellowknife 0 - -00 1935 # Yellowknife founded? - -7:00 NT_YK M%sT 1980 - -7:00 Canada M%sT Zone America/Inuvik 0 - -00 1953 # Inuvik founded -8:00 NT_YK P%sT 1979 Apr lastSun 2:00 -7:00 NT_YK M%sT 1980 @@ -2584,7 +2581,7 @@ # and in addition changes all of Chihuahua to -06 with no DST. # From Heitor David Pinto (2022-11-28): -# Now the northern municipalities want to have the same time zone as the +# Now the northern [municipios] want to have the same time zone as the # respective neighboring cities in the US, for example Juárez in UTC-7 with # DST, matching El Paso, and Ojinaga in UTC-6 with DST, matching Presidio.... # the president authorized the publication of the decree for November 29, @@ -2621,7 +2618,7 @@ -5:00 - EST 1982 Dec 2 -6:00 Mexico C%sT # Coahuila, Nuevo León, Tamaulipas (near US border) -# This includes the following municipalities: +# This includes the following municipios: # in Coahuila: Acuña, Allende, Guerrero, Hidalgo, Jiménez, Morelos, Nava, # Ocampo, Piedras Negras, Villa Unión, Zaragoza # in Nuevo León: Anáhuac @@ -2647,8 +2644,8 @@ -6:00 - CST 2002 Feb 20 -6:00 Mexico C%sT # Chihuahua (near US border - western side) -# This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe, -# and Práxedis G Guerrero. +# This includes the municipios of Janos, Ascensión, Juárez, Guadalupe, and +# Práxedis G Guerrero. # http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf Zone America/Ciudad_Juarez -7:05:56 - LMT 1922 Jan 1 7:00u -7:00 - MST 1927 Jun 10 23:00 @@ -2662,7 +2659,8 @@ -6:00 - CST 2022 Nov 30 0:00 -7:00 US M%sT # Chihuahua (near US border - eastern side) -# The municipalities of Coyame del Sotol, Ojinaga, and Manuel Benavides. +# This includes the municipios of Coyame del Sotol, Ojinaga, and Manuel +# Benavides. # http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u -7:00 - MST 1927 Jun 10 23:00 @@ -3083,7 +3081,7 @@ # # He supplied these references: # -# http://www.prensalatina.com.mx/article.asp?ID=%7B4CC32C1B-A9F7-42FB-8A07-8631AFC923AF%7D&language=ES +# http://www.prensalatina.com.mx/article.asp?ID={4CC32C1B-A9F7-42FB-8A07-8631AFC923AF}&language=ES # http://actualidad.terra.es/sociedad/articulo/cuba_llama_ahorrar_energia_cambio_1957044.htm # # From Alex Krivenyshev (2007-10-25): diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/southamerica openjdk-17-17.0.8+7/make/data/tzdata/southamerica --- openjdk-17-17.0.7+7~us1/make/data/tzdata/southamerica 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/southamerica 2023-07-05 07:11:54.000000000 +0000 @@ -231,7 +231,7 @@ # Hora de verano para la República Argentina # http://buenasiembra.com.ar/esoterismo/astrologia/hora-de-verano-de-la-republica-argentina-27.html # says that standard time in Argentina from 1894-10-31 -# to 1920-05-01 was -4:16:48.25. Go with this more-precise value +# to 1920-05-01 was -4:16:48.25. Go with this more precise value # over Shanks & Pottenger. It is upward compatible with Milne, who # says Córdoba time was -4:16:48.2. diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/VERSION openjdk-17-17.0.8+7/make/data/tzdata/VERSION --- openjdk-17-17.0.7+7~us1/make/data/tzdata/VERSION 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/VERSION 2023-07-05 07:11:54.000000000 +0000 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2022g +tzdata2023c diff -Nru openjdk-17-17.0.7+7~us1/make/data/tzdata/zone.tab openjdk-17-17.0.8+7/make/data/tzdata/zone.tab --- openjdk-17-17.0.7+7~us1/make/data/tzdata/zone.tab 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/data/tzdata/zone.tab 2023-07-05 07:11:54.000000000 +0000 @@ -144,9 +144,8 @@ CA +624900-0920459 America/Rankin_Inlet Central - NU (central) CA +5024-10439 America/Regina CST - SK (most areas) CA +5017-10750 America/Swift_Current CST - SK (midwest) -CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W) +CA +5333-11328 America/Edmonton Mountain - AB; BC (E); NT (E); SK (W) CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) -CA +6227-11421 America/Yellowknife Mountain - NT (central) CA +682059-1334300 America/Inuvik Mountain - NT (west) CA +4906-11631 America/Creston MST - BC (Creston) CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) @@ -162,7 +161,7 @@ CH +4723+00832 Europe/Zurich CI +0519-00402 Africa/Abidjan CK -2114-15946 Pacific/Rarotonga -CL -3327-07040 America/Santiago Chile (most areas) +CL -3327-07040 America/Santiago most of Chile CL -5309-07055 America/Punta_Arenas Region of Magallanes CL -2709-10926 Pacific/Easter Easter Island CM +0403+00942 Africa/Douala @@ -174,10 +173,10 @@ CV +1455-02331 Atlantic/Cape_Verde CW +1211-06900 America/Curacao CX -1025+10543 Indian/Christmas -CY +3510+03322 Asia/Nicosia Cyprus (most areas) +CY +3510+03322 Asia/Nicosia most of Cyprus CY +3507+03357 Asia/Famagusta Northern Cyprus CZ +5005+01426 Europe/Prague -DE +5230+01322 Europe/Berlin Germany (most areas) +DE +5230+01322 Europe/Berlin most of Germany DE +4742+00841 Europe/Busingen Busingen DJ +1136+04309 Africa/Djibouti DK +5540+01235 Europe/Copenhagen @@ -210,7 +209,7 @@ GG +492717-0023210 Europe/Guernsey GH +0533-00013 Africa/Accra GI +3608-00521 Europe/Gibraltar -GL +6411-05144 America/Nuuk Greenland (most areas) +GL +6411-05144 America/Nuuk most of Greenland GL +7646-01840 America/Danmarkshavn National Park (east coast) GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit GL +7634-06847 America/Thule Thule/Pituffik @@ -258,7 +257,7 @@ KR +3733+12658 Asia/Seoul KW +2920+04759 Asia/Kuwait KY +1918-08123 America/Cayman -KZ +4315+07657 Asia/Almaty Kazakhstan (most areas) +KZ +4315+07657 Asia/Almaty most of Kazakhstan KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe @@ -282,12 +281,12 @@ ME +4226+01916 Europe/Podgorica MF +1804-06305 America/Marigot MG -1855+04731 Indian/Antananarivo -MH +0709+17112 Pacific/Majuro Marshall Islands (most areas) +MH +0709+17112 Pacific/Majuro most of Marshall Islands MH +0905+16720 Pacific/Kwajalein Kwajalein MK +4159+02126 Europe/Skopje ML +1239-00800 Africa/Bamako MM +1647+09610 Asia/Yangon -MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas) +MN +4755+10653 Asia/Ulaanbaatar most of Mongolia MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar MO +221150+1133230 Asia/Macau @@ -325,7 +324,7 @@ NP +2743+08519 Asia/Kathmandu NR -0031+16655 Pacific/Nauru NU -1901-16955 Pacific/Niue -NZ -3652+17446 Pacific/Auckland New Zealand (most areas) +NZ -3652+17446 Pacific/Auckland most of New Zealand NZ -4357-17633 Pacific/Chatham Chatham Islands OM +2336+05835 Asia/Muscat PA +0858-07932 America/Panama @@ -333,7 +332,7 @@ PF -1732-14934 Pacific/Tahiti Society Islands PF -0900-13930 Pacific/Marquesas Marquesas Islands PF -2308-13457 Pacific/Gambier Gambier Islands -PG -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas) +PG -0930+14710 Pacific/Port_Moresby most of Papua New Guinea PG -0613+15534 Pacific/Bougainville Bougainville PH +1435+12100 Asia/Manila PK +2452+06703 Asia/Karachi @@ -379,7 +378,7 @@ RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky RU +5934+15048 Asia/Magadan MSK+08 - Magadan RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island -RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is +RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); N Kuril Is RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea RW -0157+03004 Africa/Kigali @@ -420,7 +419,7 @@ TV -0831+17913 Pacific/Funafuti TW +2503+12130 Asia/Taipei TZ -0648+03917 Africa/Dar_es_Salaam -UA +5026+03031 Europe/Kyiv Ukraine (most areas) +UA +5026+03031 Europe/Kyiv most of Ukraine UG +0019+03225 Africa/Kampala UM +2813-17722 Pacific/Midway Midway Islands UM +1917+16637 Pacific/Wake Wake Island @@ -443,7 +442,7 @@ US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) US +394421-1045903 America/Denver Mountain (most areas) US +433649-1161209 America/Boise Mountain - ID (south); OR (east) -US +332654-1120424 America/Phoenix MST - Arizona (except Navajo) +US +332654-1120424 America/Phoenix MST - AZ (except Navajo) US +340308-1181434 America/Los_Angeles Pacific US +611305-1495401 America/Anchorage Alaska (most areas) US +581807-1342511 America/Juneau Alaska - Juneau area @@ -451,7 +450,7 @@ US +550737-1313435 America/Metlakatla Alaska - Annette Island US +593249-1394338 America/Yakutat Alaska - Yakutat US +643004-1652423 America/Nome Alaska (west) -US +515248-1763929 America/Adak Aleutian Islands +US +515248-1763929 America/Adak Alaska - western Aleutians US +211825-1575130 Pacific/Honolulu Hawaii UY -345433-0561245 America/Montevideo UZ +3940+06648 Asia/Samarkand Uzbekistan (west) diff -Nru openjdk-17-17.0.7+7~us1/make/devkit/Tools.gmk openjdk-17-17.0.8+7/make/devkit/Tools.gmk --- openjdk-17-17.0.7+7~us1/make/devkit/Tools.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/devkit/Tools.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -87,8 +87,17 @@ # Define external dependencies # Latest that could be made to work. -GCC_VER := 10.3.0 -ifeq ($(GCC_VER), 10.3.0) +GCC_VER := 11.2.0 +ifeq ($(GCC_VER), 11.2.0) + gcc_ver := gcc-11.2.0 + binutils_ver := binutils-2.37 + ccache_ver := ccache-3.7.12 + mpfr_ver := mpfr-4.1.0 + gmp_ver := gmp-6.2.1 + mpc_ver := mpc-1.2.1 + gdb_ver := gdb-11.1 + REQUIRED_MIN_MAKE_MAJOR_VERSION := 4 +else ifeq ($(GCC_VER), 10.3.0) gcc_ver := gcc-10.3.0 binutils_ver := binutils-2.36.1 ccache_ver := ccache-3.7.11 diff -Nru openjdk-17-17.0.7+7~us1/make/hotspot/lib/CompileGtest.gmk openjdk-17-17.0.8+7/make/hotspot/lib/CompileGtest.gmk --- openjdk-17-17.0.7+7~us1/make/hotspot/lib/CompileGtest.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/hotspot/lib/CompileGtest.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 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 @@ -49,7 +49,7 @@ $(GTEST_FRAMEWORK_SRC)/googletest/src \ $(GTEST_FRAMEWORK_SRC)/googlemock/src, \ INCLUDE_FILES := gtest-all.cc gmock-all.cc, \ - DISABLED_WARNINGS_gcc := undef unused-result format-nonliteral, \ + DISABLED_WARNINGS_gcc := undef unused-result format-nonliteral maybe-uninitialized, \ DISABLED_WARNINGS_clang := undef unused-result format-nonliteral, \ CFLAGS := $(JVM_CFLAGS) \ -I$(GTEST_FRAMEWORK_SRC)/googletest \ diff -Nru openjdk-17-17.0.7+7~us1/make/jdk/src/classes/build/tools/charsetmapping/SPI.java openjdk-17-17.0.8+7/make/jdk/src/classes/build/tools/charsetmapping/SPI.java --- openjdk-17-17.0.7+7~us1/make/jdk/src/classes/build/tools/charsetmapping/SPI.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/jdk/src/classes/build/tools/charsetmapping/SPI.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,18 +50,19 @@ out.println(line); } else { charsets.values() - .stream() - .filter(cs -> cs.pkgName.equals("sun.nio.cs.ext") && - !cs.isInternal && - (cs.os == null || cs.os.equals(os))) - .forEach( cs -> { - out.printf(" charset(\"%s\", \"%s\",%n", cs.csName, cs.clzName); - out.printf(" new String[] {%n"); - for (String alias : cs.aliases) { - out.printf(" \"%s\",%n", alias); - } - out.printf(" });%n%n"); - }); + .stream() + .filter(cs -> cs.pkgName.equals("sun.nio.cs.ext") && + !cs.isInternal && + (cs.os == null || cs.os.equals(os))) + .forEach( cs -> { + out.printf(" charset(\"%s\", \"%s\",%n", cs.csName, cs.clzName); + out.printf(" new String[] {%n"); + for (String alias : cs.aliases) { + out.printf(" \"%s\",%n", + alias); + } + out.printf(" });%n%n"); + }); } } } else if (type.startsWith("stdcs")) { // StandardCharsets.java @@ -93,8 +94,15 @@ .filter(cs -> cs.pkgName.equals("sun.nio.cs")) .forEach( cs -> { if (cs.aliases == null || cs.aliases.length == 0) { - out.printf(" static String[] aliases_%s() { return null; }%n%n", - cs.clzName); + if (cs.csName.equals("GB18030")) { + out.printf(" static String[] aliases_GB18030() { return new String[] {%n"); + out.printf(" GB18030.IS_2000 ? \"gb18030-2000\" : \"gb18030-2022\"%n"); + out.printf(" };%n"); + out.printf(" }%n%n"); + } else { + out.printf(" static String[] aliases_%s() { return null; }%n%n", + cs.clzName); + } } else { boolean methodEnd = true; // non-final for SJIS and MS932 to support sun.nio.cs.map diff -Nru openjdk-17-17.0.7+7~us1/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java openjdk-17-17.0.8+7/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java --- openjdk-17-17.0.7+7~us1/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java 2023-07-05 07:11:54.000000000 +0000 @@ -197,9 +197,7 @@ // parentsMap contains resources from id's parents. Map parentsMap = new HashMap<>(); for (int i = cldrBundles.length - 1; i > index; i--) { - if (!("no".equals(cldrBundles[i]) || cldrBundles[i].startsWith("no_"))) { - parentsMap.putAll(CLDRConverter.getCLDRBundle(cldrBundles[i])); - } + parentsMap.putAll(CLDRConverter.getCLDRBundle(cldrBundles[i])); } // Duplicate myMap as parentsMap for "root" so that the // fallback works. This is a hack, though. diff -Nru openjdk-17-17.0.7+7~us1/make/modules/java.base/lib/CoreLibraries.gmk openjdk-17-17.0.8+7/make/modules/java.base/lib/CoreLibraries.gmk --- openjdk-17-17.0.7+7~us1/make/modules/java.base/lib/CoreLibraries.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/modules/java.base/lib/CoreLibraries.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -49,6 +49,7 @@ CFLAGS_windows_debug := -DLOGGING, \ CFLAGS_aix := -qfloat=nomaf, \ DISABLED_WARNINGS_gcc := sign-compare misleading-indentation array-bounds, \ + DISABLED_WARNINGS_gcc_k_rem_pio2.c := maybe-uninitialized, \ DISABLED_WARNINGS_clang := sign-compare misleading-indentation, \ DISABLED_WARNINGS_microsoft := 4146 4244 4018, \ ARFLAGS := $(ARFLAGS), \ diff -Nru openjdk-17-17.0.7+7~us1/make/modules/java.desktop/lib/Awt2dLibraries.gmk openjdk-17-17.0.8+7/make/modules/java.desktop/lib/Awt2dLibraries.gmk --- openjdk-17-17.0.7+7~us1/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -446,7 +446,7 @@ -DHB_NO_PRAGMA_GCC_DIAGNOSTIC endif ifeq ($(call isTargetOs, linux macosx), true) - HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES + HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES -DHB_NO_VISIBILITY endif # Early re-canonizing has to be disabled to workaround an internal XlC compiler error @@ -459,8 +459,9 @@ LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing + # noexcept-type required for GCC 7 builds. Not required for GCC 8+. HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \ - maybe-uninitialized class-memaccess unused-result extra use-after-free + maybe-uninitialized class-memaccess unused-result extra use-after-free noexcept-type HARFBUZZ_DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \ tautological-constant-out-of-range-compare int-to-pointer-cast \ undef missing-field-initializers range-loop-analysis \ diff -Nru openjdk-17-17.0.7+7~us1/make/modules/jdk.internal.vm.ci/Java.gmk openjdk-17-17.0.8+7/make/modules/jdk.internal.vm.ci/Java.gmk --- openjdk-17-17.0.7+7~us1/make/modules/jdk.internal.vm.ci/Java.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/modules/jdk.internal.vm.ci/Java.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -26,13 +26,5 @@ # -parameters provides method's parameters information in class file, # JVMCI compilers make use of that information for various sanity checks. # Don't use Indy strings concatenation to have good JVMCI startup performance. -# The exports are needed since JVMCI is dynamically exported (see -# jdk.vm.ci.services.internal.ReflectionAccessJDK::openJVMCITo). JAVAC_FLAGS += -parameters -XDstringConcat=inline - -## WORKAROUND jdk.internal.vm.ci source structure issue -JVMCI_MODULESOURCEPATH := $(MODULESOURCEPATH) \ - $(subst /$(MODULE)/,/*/, $(filter-out %processor/src, \ - $(wildcard $(TOPDIR)/src/$(MODULE)/share/classes/*/src))) -MODULESOURCEPATH := $(call PathList, $(JVMCI_MODULESOURCEPATH)) diff -Nru openjdk-17-17.0.7+7~us1/make/ReleaseFile.gmk openjdk-17-17.0.8+7/make/ReleaseFile.gmk --- openjdk-17-17.0.7+7~us1/make/ReleaseFile.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/ReleaseFile.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -51,6 +51,7 @@ $(if $(VENDOR_VERSION_STRING), \ $(call info-file-item, "IMPLEMENTOR_VERSION", "$(VENDOR_VERSION_STRING)")) $(call info-file-item, "JAVA_VERSION_DATE", "$(VERSION_DATE)") + $(call info-file-item, "JAVA_RUNTIME_VERSION", "$(VERSION_STRING)") $(call info-file-item, "OS_NAME", "$(RELEASE_FILE_OS_NAME)") $(call info-file-item, "OS_ARCH", "$(RELEASE_FILE_OS_ARCH)") $(call info-file-item, "LIBC", "$(RELEASE_FILE_LIBC)") diff -Nru openjdk-17-17.0.7+7~us1/make/test/JtregNativeHotspot.gmk openjdk-17-17.0.8+7/make/test/JtregNativeHotspot.gmk --- openjdk-17-17.0.7+7~us1/make/test/JtregNativeHotspot.gmk 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/make/test/JtregNativeHotspot.gmk 2023-07-05 07:11:54.000000000 +0000 @@ -871,7 +871,7 @@ ifeq ($(call isTargetOs, windows), true) BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT - BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c + BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libnativeStack.c BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib else BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libbootclssearch_agent += -lpthread @@ -1508,6 +1508,7 @@ BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libgetphase002 += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libterminatedThread += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit += -ljvm + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack += -lpthread endif # This evaluation is expensive and should only be done if this target was diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/aarch64.ad openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/aarch64.ad --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/aarch64.ad 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/aarch64.ad 2023-07-05 07:11:54.000000000 +0000 @@ -8646,6 +8646,7 @@ instruct membar_storestore() %{ match(MemBarStoreStore); + match(StoreStoreFence); ins_cost(VOLATILE_REF_COST); format %{ "MEMBAR-store-store" %} @@ -17028,16 +17029,17 @@ iRegI_R0 result, rFlagsReg cr) %{ match(Set result (StrCompressedCopy src (Binary dst len))); - effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); + effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, + USE_KILL src, USE_KILL dst, USE len, KILL cr); - format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} + format %{ "String Compress $src,$dst,$len -> $result // KILL $src,$dst" %} ins_encode %{ __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, + $result$$Register, $tmp1$$FloatRegister, $tmp2$$FloatRegister, - $tmp3$$FloatRegister, $tmp4$$FloatRegister, - $result$$Register); + $tmp3$$FloatRegister, $tmp4$$FloatRegister); %} - ins_pipe( pipe_slow ); + ins_pipe(pipe_slow); %} // fast byte[] to char[] inflation @@ -17062,22 +17064,43 @@ // encode char[] to byte[] in ISO_8859_1 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, - vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, - vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, + vRegD_V2 vtmp2, vRegD_V3 vtmp3, iRegI_R0 result, rFlagsReg cr) %{ predicate(!((EncodeISOArrayNode*)n)->is_ascii()); match(Set result (EncodeISOArray src (Binary dst len))); - effect(USE_KILL src, USE_KILL dst, USE_KILL len, - KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); + effect(USE_KILL src, USE_KILL dst, USE len, + KILL vtmp0, KILL vtmp1, KILL vtmp2, KILL vtmp3, KILL cr); - format %{ "Encode array $src,$dst,$len -> $result" %} + format %{ "Encode ISO array $src,$dst,$len -> $result" %} ins_encode %{ __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, - $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, - $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); + $result$$Register, false, + $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, + $vtmp2$$FloatRegister, $vtmp3$$FloatRegister); %} - ins_pipe( pipe_class_memory ); + ins_pipe(pipe_class_memory); +%} + +instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, + vRegD_V2 vtmp2, vRegD_V3 vtmp3, + iRegI_R0 result, rFlagsReg cr) +%{ + predicate(((EncodeISOArrayNode*)n)->is_ascii()); + match(Set result (EncodeISOArray src (Binary dst len))); + effect(USE_KILL src, USE_KILL dst, USE len, + KILL vtmp0, KILL vtmp1, KILL vtmp2, KILL vtmp3, KILL cr); + + format %{ "Encode ASCII array $src,$dst,$len -> $result" %} + ins_encode %{ + __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, + $result$$Register, true, + $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, + $vtmp2$$FloatRegister, $vtmp3$$FloatRegister); + %} + ins_pipe(pipe_class_memory); %} // ============================================================================ diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/assembler_aarch64.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/assembler_aarch64.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/assembler_aarch64.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/assembler_aarch64.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -2448,6 +2448,12 @@ INSN(cnt, 0, 0b100000010110, 0); // accepted arrangements: T8B, T16B INSN(uaddlp, 1, 0b100000001010, 2); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S INSN(uaddlv, 1, 0b110000001110, 1); // accepted arrangements: T8B, T16B, T4H, T8H, T4S + // Zero compare. + INSN(cmeq, 0, 0b100000100110, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmge, 1, 0b100000100010, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmgt, 0, 0b100000100010, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmle, 1, 0b100000100110, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmlt, 0, 0b100000101010, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D #undef INSN diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/atomic_aarch64.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/atomic_aarch64.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/atomic_aarch64.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/atomic_aarch64.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -37,6 +37,8 @@ // Pointers to stubs extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_4_impl; extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_8_impl; +extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_4_relaxed_impl; +extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_8_relaxed_impl; extern aarch64_atomic_stub_t aarch64_atomic_xchg_4_impl; extern aarch64_atomic_stub_t aarch64_atomic_xchg_8_impl; extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_1_impl; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -138,21 +138,21 @@ assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc)); - call->trampoline_jump(cbuf, SharedRuntime::get_resolve_virtual_call_stub()); + call->trampoline_jump(cbuf, SharedRuntime::get_resolve_virtual_call_stub(), JVMCI_CHECK); break; } case INVOKESTATIC: { assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); _instructions->relocate(call->instruction_address(), relocInfo::static_call_type); - call->trampoline_jump(cbuf, SharedRuntime::get_resolve_static_call_stub()); + call->trampoline_jump(cbuf, SharedRuntime::get_resolve_static_call_stub(), JVMCI_CHECK); break; } case INVOKESPECIAL: { assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type); - call->trampoline_jump(cbuf, SharedRuntime::get_resolve_opt_virtual_call_stub()); + call->trampoline_jump(cbuf, SharedRuntime::get_resolve_opt_virtual_call_stub(), JVMCI_CHECK); break; } default: diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -5031,111 +5031,118 @@ bind(fini); } -// Intrinsic for sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray and -// java/lang/StringUTF16.compress. +// Intrinsic for +// +// - sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray +// return the number of characters copied. +// - java/lang/StringUTF16.compress +// return zero (0) if copy fails, otherwise 'len'. +// +// This version always returns the number of characters copied, and does not +// clobber the 'len' register. A successful copy will complete with the post- +// condition: 'res' == 'len', while an unsuccessful copy will exit with the +// post-condition: 0 <= 'res' < 'len'. +// +// NOTE: Attempts to use 'ld2' (and 'umaxv' in the ISO part) has proven to +// degrade performance (on Ampere Altra - Neoverse N1), to an extent +// beyond the acceptable, even though the footprint would be smaller. +// Using 'umaxv' in the ASCII-case comes with a small penalty but does +// avoid additional bloat. +// void MacroAssembler::encode_iso_array(Register src, Register dst, - Register len, Register result, - FloatRegister Vtmp1, FloatRegister Vtmp2, - FloatRegister Vtmp3, FloatRegister Vtmp4) + Register len, Register res, bool ascii, + FloatRegister vtmp0, FloatRegister vtmp1, + FloatRegister vtmp2, FloatRegister vtmp3) { - Label DONE, SET_RESULT, NEXT_32, NEXT_32_PRFM, LOOP_8, NEXT_8, LOOP_1, NEXT_1, - NEXT_32_START, NEXT_32_PRFM_START; - Register tmp1 = rscratch1, tmp2 = rscratch2; - - mov(result, len); // Save initial len - - cmp(len, (u1)8); // handle shortest strings first - br(LT, LOOP_1); - cmp(len, (u1)32); - br(LT, NEXT_8); - // The following code uses the SIMD 'uzp1' and 'uzp2' instructions - // to convert chars to bytes - if (SoftwarePrefetchHintDistance >= 0) { - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - subs(tmp2, len, SoftwarePrefetchHintDistance/2 + 16); - br(LE, NEXT_32_START); - b(NEXT_32_PRFM_START); - BIND(NEXT_32_PRFM); - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - BIND(NEXT_32_PRFM_START); - prfm(Address(src, SoftwarePrefetchHintDistance)); - orr(v4, T16B, Vtmp1, Vtmp2); - orr(v5, T16B, Vtmp3, Vtmp4); - uzp1(Vtmp1, T16B, Vtmp1, Vtmp2); - uzp1(Vtmp3, T16B, Vtmp3, Vtmp4); - uzp2(v5, T16B, v4, v5); // high bytes - umov(tmp2, v5, D, 1); - fmovd(tmp1, v5); - orr(tmp1, tmp1, tmp2); - cbnz(tmp1, LOOP_8); - stpq(Vtmp1, Vtmp3, dst); - sub(len, len, 32); - add(dst, dst, 32); - add(src, src, 64); - subs(tmp2, len, SoftwarePrefetchHintDistance/2 + 16); - br(GE, NEXT_32_PRFM); - cmp(len, (u1)32); - br(LT, LOOP_8); - BIND(NEXT_32); - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - BIND(NEXT_32_START); - } else { - BIND(NEXT_32); - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - } - prfm(Address(src, SoftwarePrefetchHintDistance)); - uzp1(v4, T16B, Vtmp1, Vtmp2); - uzp1(v5, T16B, Vtmp3, Vtmp4); - orr(Vtmp1, T16B, Vtmp1, Vtmp2); - orr(Vtmp3, T16B, Vtmp3, Vtmp4); - uzp2(Vtmp1, T16B, Vtmp1, Vtmp3); // high bytes - umov(tmp2, Vtmp1, D, 1); - fmovd(tmp1, Vtmp1); - orr(tmp1, tmp1, tmp2); - cbnz(tmp1, LOOP_8); - stpq(v4, v5, dst); - sub(len, len, 32); - add(dst, dst, 32); - add(src, src, 64); - cmp(len, (u1)32); - br(GE, NEXT_32); - cbz(len, DONE); - - BIND(LOOP_8); - cmp(len, (u1)8); - br(LT, LOOP_1); - BIND(NEXT_8); - ld1(Vtmp1, T8H, src); - uzp1(Vtmp2, T16B, Vtmp1, Vtmp1); // low bytes - uzp2(Vtmp3, T16B, Vtmp1, Vtmp1); // high bytes - fmovd(tmp1, Vtmp3); - cbnz(tmp1, NEXT_1); - strd(Vtmp2, dst); - - sub(len, len, 8); - add(dst, dst, 8); - add(src, src, 16); - cmp(len, (u1)8); - br(GE, NEXT_8); - - BIND(LOOP_1); - - cbz(len, DONE); - BIND(NEXT_1); - ldrh(tmp1, Address(post(src, 2))); - tst(tmp1, 0xff00); - br(NE, SET_RESULT); - strb(tmp1, Address(post(dst, 1))); - subs(len, len, 1); - br(GT, NEXT_1); - - BIND(SET_RESULT); - sub(result, result, len); // Return index where we stopped - // Return len == 0 if we processed all - // characters - BIND(DONE); -} + Register cnt = res; + Register max = rscratch1; + Register chk = rscratch2; + + prfm(Address(src), PLDL1STRM); + movw(cnt, len); + +#define ASCII(insn) do { if (ascii) { insn; } } while (0) + + Label LOOP_32, DONE_32, FAIL_32; + + BIND(LOOP_32); + { + cmpw(cnt, 32); + br(LT, DONE_32); + ld1(vtmp0, vtmp1, vtmp2, vtmp3, T8H, Address(post(src, 64))); + // Extract lower bytes. + FloatRegister vlo0 = v4; + FloatRegister vlo1 = v5; + uzp1(vlo0, T16B, vtmp0, vtmp1); + uzp1(vlo1, T16B, vtmp2, vtmp3); + // Merge bits... + orr(vtmp0, T16B, vtmp0, vtmp1); + orr(vtmp2, T16B, vtmp2, vtmp3); + // Extract merged upper bytes. + FloatRegister vhix = vtmp0; + uzp2(vhix, T16B, vtmp0, vtmp2); + // ISO-check on hi-parts (all zero). + // ASCII-check on lo-parts (no sign). + FloatRegister vlox = vtmp1; // Merge lower bytes. + ASCII(orr(vlox, T16B, vlo0, vlo1)); + umov(chk, vhix, D, 1); ASCII(cmlt(vlox, T16B, vlox)); + fmovd(max, vhix); ASCII(umaxv(vlox, T16B, vlox)); + orr(chk, chk, max); ASCII(umov(max, vlox, B, 0)); + ASCII(orr(chk, chk, max)); + cbnz(chk, FAIL_32); + subw(cnt, cnt, 32); + st1(vlo0, vlo1, T16B, Address(post(dst, 32))); + b(LOOP_32); + } + BIND(FAIL_32); + sub(src, src, 64); + BIND(DONE_32); + + Label LOOP_8, SKIP_8; + BIND(LOOP_8); + { + cmpw(cnt, 8); + br(LT, SKIP_8); + FloatRegister vhi = vtmp0; + FloatRegister vlo = vtmp1; + ld1(vtmp3, T8H, src); + uzp1(vlo, T16B, vtmp3, vtmp3); + uzp2(vhi, T16B, vtmp3, vtmp3); + // ISO-check on hi-parts (all zero). + // ASCII-check on lo-parts (no sign). + ASCII(cmlt(vtmp2, T16B, vlo)); + fmovd(chk, vhi); ASCII(umaxv(vtmp2, T16B, vtmp2)); + ASCII(umov(max, vtmp2, B, 0)); + ASCII(orr(chk, chk, max)); + cbnz(chk, SKIP_8); + + strd(vlo, Address(post(dst, 8))); + subw(cnt, cnt, 8); + add(src, src, 16); + b(LOOP_8); + } + BIND(SKIP_8); + +#undef ASCII + + Label LOOP, DONE; + + cbz(cnt, DONE); + BIND(LOOP); + { + Register chr = rscratch1; + ldrh(chr, Address(post(src, 2))); + tst(chr, ascii ? 0xff80 : 0xff00); + br(NE, DONE); + strb(chr, Address(post(dst, 1))); + subs(cnt, cnt, 1); + br(GT, LOOP); + } + BIND(DONE); + // Return index where we stopped. + subw(res, len, cnt); +} // Inflate byte[] array to char[]. address MacroAssembler::byte_array_inflate(Register src, Register dst, Register len, @@ -5244,13 +5251,13 @@ // Compress char[] array to byte[]. void MacroAssembler::char_array_compress(Register src, Register dst, Register len, - FloatRegister tmp1Reg, FloatRegister tmp2Reg, - FloatRegister tmp3Reg, FloatRegister tmp4Reg, - Register result) { - encode_iso_array(src, dst, len, result, - tmp1Reg, tmp2Reg, tmp3Reg, tmp4Reg); - cmp(len, zr); - csel(result, result, zr, EQ); + Register res, + FloatRegister tmp0, FloatRegister tmp1, + FloatRegister tmp2, FloatRegister tmp3) { + encode_iso_array(src, dst, len, res, false, tmp0, tmp1, tmp2, tmp3); + // Adjust result: res == len ? len : 0 + cmp(len, res); + csel(res, res, zr, EQ); } // get_thread() can be called anywhere inside generated code so we diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1273,14 +1273,15 @@ FloatRegister vtmp3, Register tmp4); void char_array_compress(Register src, Register dst, Register len, - FloatRegister tmp1Reg, FloatRegister tmp2Reg, - FloatRegister tmp3Reg, FloatRegister tmp4Reg, - Register result); + Register res, + FloatRegister vtmp0, FloatRegister vtmp1, + FloatRegister vtmp2, FloatRegister vtmp3); void encode_iso_array(Register src, Register dst, - Register len, Register result, - FloatRegister Vtmp1, FloatRegister Vtmp2, - FloatRegister Vtmp3, FloatRegister Vtmp4); + Register len, Register res, bool ascii, + FloatRegister vtmp0, FloatRegister vtmp1, + FloatRegister vtmp2, FloatRegister vtmp3); + void fast_log(FloatRegister vtmp0, FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, FloatRegister vtmp4, FloatRegister vtmp5, FloatRegister tmpC1, FloatRegister tmpC2, FloatRegister tmpC3, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/matcher_aarch64.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/matcher_aarch64.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/matcher_aarch64.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/matcher_aarch64.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -156,6 +156,6 @@ } // Implements a variant of EncodeISOArrayNode that encode ASCII only - static const bool supports_encode_ascii_array = false; + static const bool supports_encode_ascii_array = true; #endif // CPU_AARCH64_MATCHER_AARCH64_HPP diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -39,6 +39,9 @@ #ifdef COMPILER1 #include "c1/c1_Runtime1.hpp" #endif +#if INCLUDE_JVMCI +#include "jvmci/jvmciEnv.hpp" +#endif void NativeCall::verify() { assert(NativeCall::is_call_at((address)this), "unexpected code at call site"); @@ -524,23 +527,26 @@ OrderAccess::release(); } +#if INCLUDE_JVMCI // Generate a trampoline for a branch to dest. If there's no need for a // trampoline, simply patch the call directly to dest. -address NativeCall::trampoline_jump(CodeBuffer &cbuf, address dest) { +void NativeCall::trampoline_jump(CodeBuffer &cbuf, address dest, JVMCI_TRAPS) { MacroAssembler a(&cbuf); - address stub = NULL; - - if (a.far_branches() - && ! is_NativeCallTrampolineStub_at(instruction_address() + displacement())) { - stub = a.emit_trampoline_stub(instruction_address() - cbuf.insts()->start(), dest); - } - if (stub == NULL) { - // If we generated no stub, patch this call directly to dest. - // This will happen if we don't need far branches or if there - // already was a trampoline. + if (!a.far_branches()) { + // If not using far branches, patch this call directly to dest. set_destination(dest); + } else if (!is_NativeCallTrampolineStub_at(instruction_address() + displacement())) { + // If we want far branches and there isn't a trampoline stub, emit one. + address stub = a.emit_trampoline_stub(instruction_address() - cbuf.insts()->start(), dest); + if (stub == nullptr) { + JVMCI_ERROR("could not emit trampoline stub - code cache is full"); + } + // The relocation created while emitting the stub will ensure this + // call instruction is subsequently patched to call the stub. + } else { + // Not sure how this can be happen but be defensive + JVMCI_ERROR("single-use stub should not exist"); } - - return stub; } +#endif diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -29,6 +29,11 @@ #include "asm/assembler.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" +#include "runtime/os.hpp" +#if INCLUDE_JVMCI +#include "jvmci/jvmciExceptions.hpp" +#endif + // We have interfaces for the following instructions: // - NativeInstruction @@ -251,7 +256,9 @@ void set_destination_mt_safe(address dest, bool assert_lock = true); address get_trampoline(); - address trampoline_jump(CodeBuffer &cbuf, address dest); +#if INCLUDE_JVMCI + void trampoline_jump(CodeBuffer &cbuf, address dest, JVMCI_TRAPS); +#endif }; inline NativeCall* nativeCall_at(address address) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2359,10 +2359,9 @@ Label retaddr; __ set_last_Java_frame(sp, noreg, retaddr, rscratch1); -#ifdef ASSERT0 +#ifdef ASSERT { Label L; - __ ldr(rscratch1, Address(rthread, - JavaThread::last_Java_fp_offset())); + __ ldr(rscratch1, Address(rthread, JavaThread::last_Java_fp_offset())); __ cbz(rscratch1, L); __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared"); __ bind(L); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2964,6 +2964,22 @@ return start; } + // Big-endian 128-bit + 64-bit -> 128-bit addition. + // Inputs: 128-bits. in is preserved. + // The least-significant 64-bit word is in the upper dword of the vector + // inc (the 64-bit increment) is preserved. Its lower dword must be zero + // Output: result + void be_add_128_64(FloatRegister result, FloatRegister in, + FloatRegister inc, FloatRegister tmp) { + assert_different_registers(result, tmp, inc); + + __ addv(result, __ T2D, in, inc); // Add inc to the least-significant dword of input + __ cmhi(tmp, __ T2D, inc, result); // Check for result overflowing + __ ins(tmp, __ D, tmp, 0, 1); // Move LSD of comparison result to MSD + __ ins(tmp, __ D, inc, 1, 0); // Move 0 to LSD of comparison result + __ subv(result, __ T2D, result, tmp); // Subtract -1 from MSD if there was an overflow + } + // CTR AES crypt. // Arguments: // @@ -3073,13 +3089,16 @@ // Setup the counter __ movi(v4, __ T4S, 0); __ movi(v5, __ T4S, 1); - __ ins(v4, __ S, v5, 3, 3); // v4 contains { 0, 0, 0, 1 } + __ ins(v4, __ S, v5, 2, 2); // v4 contains { 0, 1 } - __ ld1(v0, __ T16B, counter); // Load the counter into v0 - __ rev32(v16, __ T16B, v0); - __ addv(v16, __ T4S, v16, v4); - __ rev32(v16, __ T16B, v16); - __ st1(v16, __ T16B, counter); // Save the incremented counter back + // 128-bit big-endian increment + __ ld1(v0, __ T16B, counter); + __ rev64(v16, __ T16B, v0); + be_add_128_64(v16, v16, v4, /*tmp*/v5); + __ rev64(v16, __ T16B, v16); + __ st1(v16, __ T16B, counter); + // Previous counter value is in v0 + // v4 contains { 0, 1 } { // We have fewer than bulk_width blocks of data left. Encrypt @@ -3111,9 +3130,9 @@ // Increment the counter, store it back __ orr(v0, __ T16B, v16, v16); - __ rev32(v16, __ T16B, v16); - __ addv(v16, __ T4S, v16, v4); - __ rev32(v16, __ T16B, v16); + __ rev64(v16, __ T16B, v16); + be_add_128_64(v16, v16, v4, /*tmp*/v5); + __ rev64(v16, __ T16B, v16); __ st1(v16, __ T16B, counter); // Save the incremented counter back __ b(inner_loop); @@ -3161,7 +3180,7 @@ // Keys should already be loaded into the correct registers __ ld1(v0, __ T16B, counter); // v0 contains the first counter - __ rev32(v16, __ T16B, v0); // v16 contains byte-reversed counter + __ rev64(v16, __ T16B, v0); // v16 contains byte-reversed counter // AES/CTR loop { @@ -3171,11 +3190,11 @@ // Setup the counters __ movi(v8, __ T4S, 0); __ movi(v9, __ T4S, 1); - __ ins(v8, __ S, v9, 3, 3); // v8 contains { 0, 0, 0, 1 } + __ ins(v8, __ S, v9, 2, 2); // v8 contains { 0, 1 } for (FloatRegister f = v0; f < v0 + bulk_width; f++) { - __ rev32(f, __ T16B, v16); - __ addv(v16, __ T4S, v16, v8); + __ rev64(f, __ T16B, v16); + be_add_128_64(v16, v16, v8, /*tmp*/v9); } __ ld1(v8, v9, v10, v11, __ T16B, __ post(in, 4 * 16)); @@ -3203,7 +3222,7 @@ } // Save the counter back where it goes - __ rev32(v16, __ T16B, v16); + __ rev64(v16, __ T16B, v16); __ st1(v16, __ T16B, counter); __ pop(saved_regs, sp); @@ -6481,10 +6500,16 @@ __ ret(lr); } - void gen_ldaddal_entry(Assembler::operand_size size) { + void gen_ldadd_entry(Assembler::operand_size size, atomic_memory_order order) { Register prev = r2, addr = c_rarg0, incr = c_rarg1; - __ ldaddal(size, incr, prev, addr); - __ membar(Assembler::StoreStore|Assembler::StoreLoad); + // If not relaxed, then default to conservative. Relaxed is the only + // case we use enough to be worth specializing. + if (order == memory_order_relaxed) { + __ ldadd(size, incr, prev, addr); + } else { + __ ldaddal(size, incr, prev, addr); + __ membar(Assembler::StoreStore|Assembler::StoreLoad); + } if (size == Assembler::xword) { __ mov(r0, prev); } else { @@ -6514,12 +6539,21 @@ StubCodeMark mark(this, "StubRoutines", "atomic entry points"); address first_entry = __ pc(); - // All memory_order_conservative + // ADD, memory_order_conservative AtomicStubMark mark_fetch_add_4(_masm, &aarch64_atomic_fetch_add_4_impl); - gen_ldaddal_entry(Assembler::word); + gen_ldadd_entry(Assembler::word, memory_order_conservative); AtomicStubMark mark_fetch_add_8(_masm, &aarch64_atomic_fetch_add_8_impl); - gen_ldaddal_entry(Assembler::xword); + gen_ldadd_entry(Assembler::xword, memory_order_conservative); + + // ADD, memory_order_relaxed + AtomicStubMark mark_fetch_add_4_relaxed + (_masm, &aarch64_atomic_fetch_add_4_relaxed_impl); + gen_ldadd_entry(MacroAssembler::word, memory_order_relaxed); + AtomicStubMark mark_fetch_add_8_relaxed + (_masm, &aarch64_atomic_fetch_add_8_relaxed_impl); + gen_ldadd_entry(MacroAssembler::xword, memory_order_relaxed); + // XCHG, memory_order_conservative AtomicStubMark mark_xchg_4(_masm, &aarch64_atomic_xchg_4_impl); gen_swpal_entry(Assembler::word); AtomicStubMark mark_xchg_8_impl(_masm, &aarch64_atomic_xchg_8_impl); @@ -7730,6 +7764,8 @@ DEFAULT_ATOMIC_OP(fetch_add, 4, ) DEFAULT_ATOMIC_OP(fetch_add, 8, ) +DEFAULT_ATOMIC_OP(fetch_add, 4, _relaxed) +DEFAULT_ATOMIC_OP(fetch_add, 8, _relaxed) DEFAULT_ATOMIC_OP(xchg, 4, ) DEFAULT_ATOMIC_OP(xchg, 8, ) DEFAULT_ATOMIC_OP(cmpxchg, 1, ) diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -493,36 +493,52 @@ UNSUPPORTED_OPTION(CriticalJNINatives); } -void VM_Version::check_virtualizations() { #if defined(LINUX) - const char* info_file = "/sys/devices/virtual/dmi/id/product_name"; - // check for various strings in the dmi data indicating virtualizations +static bool check_info_file(const char* fpath, + const char* virt1, VirtualizationType vt1, + const char* virt2, VirtualizationType vt2) { char line[500]; - FILE* fp = os::fopen(info_file, "r"); + FILE* fp = os::fopen(fpath, "r"); if (fp == nullptr) { - return; + return false; } while (fgets(line, sizeof(line), fp) != nullptr) { - if (strcasestr(line, "KVM") != 0) { - Abstract_VM_Version::_detected_virtualization = KVM; - break; + if (strcasestr(line, virt1) != 0) { + Abstract_VM_Version::_detected_virtualization = vt1; + fclose(fp); + return true; } - if (strcasestr(line, "VMware") != 0) { - Abstract_VM_Version::_detected_virtualization = VMWare; - break; + if (virt2 != NULL && strcasestr(line, virt2) != 0) { + Abstract_VM_Version::_detected_virtualization = vt2; + fclose(fp); + return true; } } fclose(fp); + return false; +} +#endif + +void VM_Version::check_virtualizations() { +#if defined(LINUX) + const char* pname_file = "/sys/devices/virtual/dmi/id/product_name"; + const char* tname_file = "/sys/hypervisor/type"; + if (check_info_file(pname_file, "KVM", KVM, "VMWare", VMWare)) { + return; + } + check_info_file(tname_file, "Xen", XenPVHVM, NULL, NoDetectedVirtualization); #endif } void VM_Version::print_platform_virtualization_info(outputStream* st) { #if defined(LINUX) - VirtualizationType vrt = VM_Version::get_detected_virtualization(); - if (vrt == KVM) { - st->print_cr("KVM virtualization detected"); - } else if (vrt == VMWare) { - st->print_cr("VMWare virtualization detected"); - } + VirtualizationType vrt = VM_Version::get_detected_virtualization(); + if (vrt == KVM) { + st->print_cr("KVM virtualization detected"); + } else if (vrt == VMWare) { + st->print_cr("VMWare virtualization detected"); + } else if (vrt == XenPVHVM) { + st->print_cr("Xen virtualization detected"); + } #endif } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/arm/arm.ad openjdk-17-17.0.8+7/src/hotspot/cpu/arm/arm.ad --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/arm/arm.ad 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/arm/arm.ad 2023-07-05 07:11:54.000000000 +0000 @@ -4511,6 +4511,7 @@ // pattern-match out unnecessary membars instruct membar_storestore() %{ match(MemBarStoreStore); + match(StoreStoreFence); ins_cost(4*MEMORY_REF_COST); size(4); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -160,7 +160,7 @@ // Restore the object header bool allow_fallthrough_on_failure = true; bool one_shot = true; - cas_for_lock_release(Rmark, Rbox, Roop, Rscratch, done, allow_fallthrough_on_failure, one_shot); + cas_for_lock_release(Rbox, Rmark, Roop, Rscratch, done, allow_fallthrough_on_failure, one_shot); bind(done); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -828,7 +828,6 @@ } else { __ ld(to_reg->as_register(), offset, base); } - __ verify_oop(to_reg->as_register(), FILE_AND_LINE); break; } case T_FLOAT: __ lfs(to_reg->as_float_reg(), offset, base); break; @@ -859,7 +858,6 @@ } else { __ ldx(to_reg->as_register(), base, disp); } - __ verify_oop(to_reg->as_register(), FILE_AND_LINE); break; } case T_FLOAT: __ lfsx(to_reg->as_float_reg() , base, disp); break; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/ppc/ppc.ad openjdk-17-17.0.8+7/src/hotspot/cpu/ppc/ppc.ad --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/ppc/ppc.ad 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/ppc/ppc.ad 2023-07-05 07:11:54.000000000 +0000 @@ -7152,6 +7152,7 @@ instruct membar_storestore() %{ match(MemBarStoreStore); + match(StoreStoreFence); ins_cost(4*MEMORY_REF_COST); format %{ "MEMBAR-store-store" %} diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/s390/s390.ad openjdk-17-17.0.8+7/src/hotspot/cpu/s390/s390.ad --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/s390/s390.ad 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/s390/s390.ad 2023-07-05 07:11:54.000000000 +0000 @@ -5048,6 +5048,7 @@ instruct membar_storestore() %{ match(MemBarStoreStore); + match(StoreStoreFence); ins_cost(0); size(0); format %{ "MEMBAR-storestore (empty)" %} diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/assembler_x86.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/assembler_x86.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/assembler_x86.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/assembler_x86.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2633,6 +2633,16 @@ emit_int16((unsigned char)0x99, (0xC0 | encode)); } + +void Assembler::kshiftlbl(KRegister dst, KRegister src, int imm8) { + assert(VM_Version::supports_avx512dq(), ""); + InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), 0 , src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int16(0x32, (0xC0 | encode)); + emit_int8(imm8); +} + + void Assembler::movb(Address dst, int imm8) { InstructionMark im(this); prefix(dst); @@ -3948,6 +3958,14 @@ emit_int24(0x3E, (0xC0 | encode), vcc); } +void Assembler::evpcmpuq(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) { + assert(VM_Version::supports_avx512vlbw(), ""); + InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int24(0x1E, (0xC0 | encode), vcc); +} + void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len) { assert(VM_Version::supports_avx512vlbw(), ""); InstructionMark im(this); @@ -6574,6 +6592,19 @@ emit_operand(dst, src); } +void Assembler::evpaddq(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) { + assert(VM_Version::supports_evex(), ""); + assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true); + attributes.set_is_evex_instruction(); + attributes.set_embedded_opmask_register_specifier(mask); + if (merge) { + attributes.reset_is_clear_context(); + } + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); + emit_int16((unsigned char)0xD4, (0xC0 | encode)); +} + void Assembler::psubb(XMMRegister dst, XMMRegister src) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); @@ -9683,7 +9714,7 @@ if (adr.index_needs_rex()) { assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X"); } else { - prefix(REX_B); + p = (Prefix)(p | REX_B); } } else { if (adr.index_needs_rex()) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/assembler_x86.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/assembler_x86.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/assembler_x86.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/assembler_x86.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1492,6 +1492,8 @@ void ktestql(KRegister dst, KRegister src); + void kshiftlbl(KRegister dst, KRegister src, int imm8); + void movdl(XMMRegister dst, Register src); void movdl(Register dst, XMMRegister src); void movdl(XMMRegister dst, Address src); @@ -1727,6 +1729,8 @@ void evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len); void evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len); + void evpcmpuq(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len); + void pcmpeqw(XMMRegister dst, XMMRegister src); void vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void evpcmpeqw(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len); @@ -2249,6 +2253,10 @@ void vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len); void vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len); + // Leaf level assembler routines for masked operations. + void evpaddq(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len); +// void evpaddq(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len); + // Sub packed integers void psubb(XMMRegister dst, XMMRegister src); void psubw(XMMRegister dst, XMMRegister src); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2094,6 +2094,14 @@ } } +void C2_MacroAssembler::movsxl(BasicType typ, Register dst) { + if (typ == T_BYTE) { + movsbl(dst, dst); + } else if (typ == T_SHORT) { + movswl(dst, dst); + } +} + void C2_MacroAssembler::get_elem(BasicType typ, Register dst, XMMRegister src, int elemindex) { int esize = type2aelembytes(typ); int elem_per_lane = 16/esize; @@ -2105,13 +2113,11 @@ movq(dst, src); } else { movdl(dst, src); - if (typ == T_BYTE) - movsbl(dst, dst); - else if (typ == T_SHORT) - movswl(dst, dst); + movsxl(typ, dst); } } else { extract(typ, dst, src, eindex); + movsxl(typ, dst); } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -132,6 +132,7 @@ XMMRegister get_lane(BasicType typ, XMMRegister dst, XMMRegister src, int elemindex); void get_elem(BasicType typ, Register dst, XMMRegister src, int elemindex); void get_elem(BasicType typ, XMMRegister dst, XMMRegister src, int elemindex, Register tmp = noreg, XMMRegister vtmp = xnoreg); + void movsxl(BasicType typ, Register dst); // vector test void vectortest(int bt, int vlen, XMMRegister src1, XMMRegister src2, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/crc32c.h openjdk-17-17.0.8+7/src/hotspot/cpu/x86/crc32c.h --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/crc32c.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/crc32c.h 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015, 2019, 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 @@ -39,15 +39,15 @@ // based on ubench study using methodology described in // V. Gopal et al. / Fast CRC Computation for iSCSI Polynomial Using CRC32 Instruction April 2011 8 // - // arbitrary value between 27 and 256 - CRC32C_MIDDLE = 8 * 86, + // arbitrary value between 9 and 256 + CRC32C_MIDDLE = 8 * 74, // V. Gopal et al. / Fast CRC Computation for iSCSI Polynomial Using CRC32 Instruction April 2011 9 - // shows that 240 and 1024 are equally good choices as the 216==8*27 + // shows that 240 and 1024 are equally good choices as the 216==8*9*3 // // Selecting the smallest value which resulted in a significant performance improvement over // sequential version - CRC32C_LOW = 8 * 27, + CRC32C_LOW = 8 * 9, CRC32C_NUM_ChunkSizeInBytes = 3, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/frame_x86.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/frame_x86.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/frame_x86.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/frame_x86.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -64,8 +64,11 @@ return false; } - // unextended sp must be within the stack and above or equal sp - if (!thread->is_in_stack_range_incl(unextended_sp, sp)) { + // unextended sp must be within the stack + // Note: sp can be greater than unextended_sp in the case of + // interpreted -> interpreted calls that go through a method handle linker, + // since those pop the last argument (the appendix) from the stack. + if (!thread->is_in_stack_range_incl(unextended_sp, sp - Interpreter::stackElementSize)) { return false; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -779,6 +779,19 @@ vpxor(xmm15, xmm15, xmm15, Assembler::AVX_128bit); } +// Add 128-bit integers in xmmsrc1 to xmmsrc2, then place the result in xmmdst. +// Clobber ktmp and rscratch. +// Used by aesctr_encrypt. +void MacroAssembler::ev_add128(XMMRegister xmmdst, XMMRegister xmmsrc1, XMMRegister xmmsrc2, + int vector_len, KRegister ktmp, Register rscratch) { + vpaddq(xmmdst, xmmsrc1, xmmsrc2, vector_len); + evpcmpuq(ktmp, xmmdst, xmmsrc2, lt, vector_len); // set mask[0/1] bit if addq to dst[0/1] wraps + kshiftlbl(ktmp, ktmp, 1); // mask[1] <- mask[0], mask[0] <- 0, etc + + evpaddq(xmmdst, ktmp, xmmdst, xmm17, /*merge*/true, + vector_len); // dst[1]++ if mask[1] set +} + // AES Counter Mode using VAES instructions void MacroAssembler::aesctr_encrypt(Register src_addr, Register dest_addr, Register key, Register counter, Register len_reg, Register used, Register used_addr, Register saved_encCounter_start) { @@ -831,19 +844,23 @@ //shuffle counter using lbswap_mask vpshufb(xmm8, xmm8, xmm16, Assembler::AVX_512bit); + // Vector value to propagate carries + evmovdquq(xmm17, ExternalAddress(StubRoutines::x86::counter_mask_ones_addr()), Assembler::AVX_512bit, r15); // pre-increment and propagate counter values to zmm9-zmm15 registers. // Linc0 increments the zmm8 by 1 (initial value being 0), Linc4 increments the counters zmm9-zmm15 by 4 // The counter is incremented after each block i.e. 16 bytes is processed; // each zmm register has 4 counter values as its MSB // the counters are incremented in parallel - vpaddd(xmm8, xmm8, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 64), Assembler::AVX_512bit, r15);//linc0 - vpaddd(xmm9, xmm8, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15);//linc4(rip) - vpaddd(xmm10, xmm9, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15);//Linc4(rip) - vpaddd(xmm11, xmm10, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15);//Linc4(rip) - vpaddd(xmm12, xmm11, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15);//Linc4(rip) - vpaddd(xmm13, xmm12, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15);//Linc4(rip) - vpaddd(xmm14, xmm13, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15);//Linc4(rip) - vpaddd(xmm15, xmm14, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15);//Linc4(rip) + evmovdquq(xmm19, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 64), Assembler::AVX_512bit, r15 /*rscratch*/);//linc0 + ev_add128(xmm8, xmm8, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); + evmovdquq(xmm19, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 128), Assembler::AVX_512bit, r15 /*rscratch*/);//linc4 + ev_add128(xmm9, xmm8, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); + ev_add128(xmm10, xmm9, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); + ev_add128(xmm11, xmm10, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); + ev_add128(xmm12, xmm11, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); + ev_add128(xmm13, xmm12, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); + ev_add128(xmm14, xmm13, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); + ev_add128(xmm15, xmm14, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15); // load linc32 mask in zmm register.linc32 increments counter by 32 evmovdquq(xmm19, ExternalAddress(StubRoutines::x86::counter_mask_addr() + 256), Assembler::AVX_512bit, r15);//Linc32 @@ -891,21 +908,21 @@ // This is followed by incrementing counter values in zmm8-zmm15. // Since we will be processing 32 blocks at a time, the counter is incremented by 32. roundEnc(xmm21, 7); - vpaddq(xmm8, xmm8, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm8, xmm8, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm22, 7); - vpaddq(xmm9, xmm9, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm9, xmm9, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm23, 7); - vpaddq(xmm10, xmm10, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm10, xmm10, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm24, 7); - vpaddq(xmm11, xmm11, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm11, xmm11, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm25, 7); - vpaddq(xmm12, xmm12, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm12, xmm12, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm26, 7); - vpaddq(xmm13, xmm13, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm13, xmm13, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm27, 7); - vpaddq(xmm14, xmm14, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm14, xmm14, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm28, 7); - vpaddq(xmm15, xmm15, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm15, xmm15, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); roundEnc(xmm29, 7); cmpl(rounds, 52); @@ -983,8 +1000,8 @@ vpshufb(xmm3, xmm11, xmm16, Assembler::AVX_512bit); evpxorq(xmm3, xmm3, xmm20, Assembler::AVX_512bit); // Increment counter values by 16 - vpaddq(xmm8, xmm8, xmm19, Assembler::AVX_512bit); - vpaddq(xmm9, xmm9, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm8, xmm8, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); + ev_add128/*!!!*/(xmm9, xmm9, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); // AES encode rounds roundEnc(xmm21, 3); roundEnc(xmm22, 3); @@ -1051,7 +1068,7 @@ vpshufb(xmm1, xmm9, xmm16, Assembler::AVX_512bit); evpxorq(xmm1, xmm1, xmm20, Assembler::AVX_512bit); // increment counter by 8 - vpaddq(xmm8, xmm8, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm8, xmm8, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); // AES encode roundEnc(xmm21, 1); roundEnc(xmm22, 1); @@ -1109,7 +1126,7 @@ vpshufb(xmm0, xmm8, xmm16, Assembler::AVX_512bit); evpxorq(xmm0, xmm0, xmm20, Assembler::AVX_512bit); // Increment counter - vpaddq(xmm8, xmm8, xmm19, Assembler::AVX_512bit); + ev_add128/*!!!*/(xmm8, xmm8, xmm19, Assembler::AVX_512bit, /*ktmp*/k1, r15 /*rscratch*/); vaesenc(xmm0, xmm0, xmm21, Assembler::AVX_512bit); vaesenc(xmm0, xmm0, xmm22, Assembler::AVX_512bit); vaesenc(xmm0, xmm0, xmm23, Assembler::AVX_512bit); @@ -1159,7 +1176,7 @@ evpxorq(xmm0, xmm0, xmm20, Assembler::AVX_128bit); vaesenc(xmm0, xmm0, xmm21, Assembler::AVX_128bit); // Increment counter by 1 - vpaddq(xmm8, xmm8, xmm19, Assembler::AVX_128bit); + ev_add128/*!!!*/(xmm8, xmm8, xmm19, Assembler::AVX_128bit, /*ktmp*/k1, r15 /*rscratch*/); vaesenc(xmm0, xmm0, xmm22, Assembler::AVX_128bit); vaesenc(xmm0, xmm0, xmm23, Assembler::AVX_128bit); vaesenc(xmm0, xmm0, xmm24, Assembler::AVX_128bit); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/macroAssembler_x86.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/macroAssembler_x86.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -7937,24 +7937,27 @@ addl(tmp1, in2); addq(tmp1, in1); - BIND(L_wordByWord); cmpq(in1, tmp1); - jcc(Assembler::greaterEqual, L_byteByByteProlog); - crc32(in_out, Address(in1, 0), 4); - addq(in1, 4); - jmp(L_wordByWord); + jccb(Assembler::greaterEqual, L_byteByByteProlog); + align(16); + BIND(L_wordByWord); + crc32(in_out, Address(in1, 0), 8); + addq(in1, 8); + cmpq(in1, tmp1); + jcc(Assembler::less, L_wordByWord); BIND(L_byteByByteProlog); andl(in2, 0x00000007); movl(tmp2, 1); - BIND(L_byteByByte); cmpl(tmp2, in2); jccb(Assembler::greater, L_exit); + BIND(L_byteByByte); crc32(in_out, Address(in1, 0), 1); incq(in1); incl(tmp2); - jmp(L_byteByByte); + cmpl(tmp2, in2); + jcc(Assembler::lessEqual, L_byteByByte); BIND(L_exit); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/macroAssembler_x86.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/macroAssembler_x86.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -964,6 +964,8 @@ void roundDec(XMMRegister key, int rnum); void lastroundDec(XMMRegister key, int rnum); void ev_load_key(XMMRegister xmmdst, Register key, int offset, XMMRegister xmm_shuf_mask); + void ev_add128(XMMRegister xmmdst, XMMRegister xmmsrc1, XMMRegister xmmsrc2, + int vector_len, KRegister ktmp, Register rscratch = noreg); public: void aesecb_encrypt(Register source_addr, Register dest_addr, Register key, Register len); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -4424,7 +4424,19 @@ return start; } - // Vector AES Counter implementation + // Vector AES Counter implementation + + address counter_mask_ones_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "counter_mask_addr"); + address start = __ pc(); + for (int i = 0; i < 4; i ++) { + __ emit_data64(0x0000000000000000, relocInfo::none); + __ emit_data64(0x0000000000000001, relocInfo::none); + } + return start; + } + address generate_counterMode_VectorAESCrypt() { __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt"); @@ -7641,6 +7653,7 @@ if (UseAESCTRIntrinsics) { if (VM_Version::supports_avx512_vaes() && VM_Version::supports_avx512bw() && VM_Version::supports_avx512vl()) { StubRoutines::x86::_counter_mask_addr = counter_mask_addr(); + StubRoutines::x86::_counter_mask_ones_addr = counter_mask_ones_addr(); StubRoutines::_counterMode_AESCrypt = generate_counterMode_VectorAESCrypt(); } else { StubRoutines::x86::_counter_shuffle_mask_addr = generate_counter_shuffle_mask(); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/stubRoutines_x86.cpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/stubRoutines_x86.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/stubRoutines_x86.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/stubRoutines_x86.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -71,6 +71,7 @@ address StubRoutines::x86::_avx2_input_mask_base64 = NULL; address StubRoutines::x86::_avx2_lut_base64 = NULL; address StubRoutines::x86::_counter_mask_addr = NULL; +address StubRoutines::x86::_counter_mask_ones_addr = NULL; address StubRoutines::x86::_lookup_lo_base64 = NULL; address StubRoutines::x86::_lookup_hi_base64 = NULL; address StubRoutines::x86::_lookup_lo_base64url = NULL; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/stubRoutines_x86.hpp openjdk-17-17.0.8+7/src/hotspot/cpu/x86/stubRoutines_x86.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/stubRoutines_x86.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/stubRoutines_x86.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -184,6 +184,7 @@ // byte flip mask for sha512 static address _pshuffle_byte_flip_mask_addr_sha512; static address _counter_mask_addr; + static address _counter_mask_ones_addr; // Masks for base64 static address _encoding_table_base64; static address _shuffle_base64; @@ -343,6 +344,7 @@ static address base64_avx2_input_mask_addr() { return _avx2_input_mask_base64; } static address base64_avx2_lut_addr() { return _avx2_lut_base64; } static address counter_mask_addr() { return _counter_mask_addr; } + static address counter_mask_ones_addr() { return _counter_mask_ones_addr; } static address base64_vbmi_lookup_lo_addr() { return _lookup_lo_base64; } static address base64_vbmi_lookup_hi_addr() { return _lookup_hi_base64; } static address base64_vbmi_lookup_lo_url_addr() { return _lookup_lo_base64url; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/x86_32.ad openjdk-17-17.0.8+7/src/hotspot/cpu/x86/x86_32.ad --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/x86_32.ad 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/x86_32.ad 2023-07-05 07:11:54.000000000 +0000 @@ -6646,6 +6646,7 @@ instruct membar_storestore() %{ match(MemBarStoreStore); + match(StoreStoreFence); ins_cost(0); size(0); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/x86_64.ad openjdk-17-17.0.8+7/src/hotspot/cpu/x86/x86_64.ad --- openjdk-17-17.0.7+7~us1/src/hotspot/cpu/x86/x86_64.ad 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/cpu/x86/x86_64.ad 2023-07-05 07:11:54.000000000 +0000 @@ -6765,6 +6765,7 @@ instruct membar_storestore() %{ match(MemBarStoreStore); + match(StoreStoreFence); ins_cost(0); size(0); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os/aix/os_aix.cpp openjdk-17-17.0.8+7/src/hotspot/os/aix/os_aix.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/os/aix/os_aix.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os/aix/os_aix.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -904,9 +904,9 @@ PosixSignals::hotspot_sigmask(thread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), (uintx) kernel_thread_id, - p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size()); + p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); return true; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os/bsd/os_bsd.cpp openjdk-17-17.0.8+7/src/hotspot/os/bsd/os_bsd.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/os/bsd/os_bsd.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os/bsd/os_bsd.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -729,9 +729,9 @@ PosixSignals::hotspot_sigmask(thread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), (uintx) pthread_self(), - p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size()); + p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); return true; } @@ -1377,8 +1377,34 @@ VM_Version::print_platform_virtualization_info(st); } +#ifdef __APPLE__ +static void print_sysctl_info_string(const char* sysctlkey, outputStream* st, char* buf, size_t size) { + if (sysctlbyname(sysctlkey, buf, &size, NULL, 0) >= 0) { + st->print_cr("%s:%s", sysctlkey, buf); + } +} + +static void print_sysctl_info_uint64(const char* sysctlkey, outputStream* st) { + uint64_t val; + size_t size=sizeof(uint64_t); + if (sysctlbyname(sysctlkey, &val, &size, NULL, 0) >= 0) { + st->print_cr("%s:%llu", sysctlkey, val); + } +} +#endif + void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { - // Nothing to do for now. +#ifdef __APPLE__ + print_sysctl_info_string("machdep.cpu.brand_string", st, buf, buflen); + print_sysctl_info_uint64("hw.cpufrequency", st); + print_sysctl_info_uint64("hw.cpufrequency_min", st); + print_sysctl_info_uint64("hw.cpufrequency_max", st); + print_sysctl_info_uint64("hw.cachelinesize", st); + print_sysctl_info_uint64("hw.l1icachesize", st); + print_sysctl_info_uint64("hw.l1dcachesize", st); + print_sysctl_info_uint64("hw.l2cachesize", st); + print_sysctl_info_uint64("hw.l3cachesize", st); +#endif } void os::get_summary_cpu_info(char* buf, size_t buflen) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp openjdk-17-17.0.8+7/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -38,40 +38,26 @@ * on the contents of the mountinfo and cgroup files. */ void CgroupV1Controller::set_subsystem_path(char *cgroup_path) { - char buf[MAXPATHLEN+1]; + stringStream ss; if (_root != NULL && cgroup_path != NULL) { if (strcmp(_root, "/") == 0) { - int buflen; - strncpy(buf, _mount_point, MAXPATHLEN); - buf[MAXPATHLEN-1] = '\0'; + ss.print_raw(_mount_point); if (strcmp(cgroup_path,"/") != 0) { - buflen = strlen(buf); - if ((buflen + strlen(cgroup_path)) > (MAXPATHLEN-1)) { - return; - } - strncat(buf, cgroup_path, MAXPATHLEN-buflen); - buf[MAXPATHLEN-1] = '\0'; + ss.print_raw(cgroup_path); } - _path = os::strdup(buf); + _path = os::strdup(ss.base()); } else { if (strcmp(_root, cgroup_path) == 0) { - strncpy(buf, _mount_point, MAXPATHLEN); - buf[MAXPATHLEN-1] = '\0'; - _path = os::strdup(buf); + ss.print_raw(_mount_point); + _path = os::strdup(ss.base()); } else { char *p = strstr(cgroup_path, _root); if (p != NULL && p == _root) { if (strlen(cgroup_path) > strlen(_root)) { - int buflen; - strncpy(buf, _mount_point, MAXPATHLEN); - buf[MAXPATHLEN-1] = '\0'; - buflen = strlen(buf); - if ((buflen + strlen(cgroup_path) - strlen(_root)) > (MAXPATHLEN-1)) { - return; - } - strncat(buf, cgroup_path + strlen(_root), MAXPATHLEN-buflen); - buf[MAXPATHLEN-1] = '\0'; - _path = os::strdup(buf); + ss.print_raw(_mount_point); + const char* cg_path_sub = cgroup_path + strlen(_root); + ss.print_raw(cg_path_sub); + _path = os::strdup(ss.base()); } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp openjdk-17-17.0.8+7/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -234,17 +234,12 @@ } char* CgroupV2Controller::construct_path(char* mount_path, char *cgroup_path) { - char buf[MAXPATHLEN+1]; - int buflen; - strncpy(buf, mount_path, MAXPATHLEN); - buf[MAXPATHLEN] = '\0'; - buflen = strlen(buf); - if ((buflen + strlen(cgroup_path)) > MAXPATHLEN) { - return NULL; + stringStream ss; + ss.print_raw(mount_path); + if (strcmp(cgroup_path, "/") != 0) { + ss.print_raw(cgroup_path); } - strncat(buf, cgroup_path, MAXPATHLEN-buflen); - buf[MAXPATHLEN] = '\0'; - return os::strdup(buf); + return os::strdup(ss.base()); } char* CgroupV2Subsystem::pids_max_val() { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os/linux/os_linux.cpp openjdk-17-17.0.8+7/src/hotspot/os/linux/os_linux.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/os/linux/os_linux.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os/linux/os_linux.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -984,7 +984,7 @@ PosixSignals::hotspot_sigmask(thread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), (uintx) pthread_self(), p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size()); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os/windows/os_windows.cpp openjdk-17-17.0.8+7/src/hotspot/os/windows/os_windows.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/os/windows/os_windows.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os/windows/os_windows.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -88,6 +88,7 @@ #include #include +#include #include #include #include @@ -625,9 +626,9 @@ thread->set_osthread(osthread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", stack: " - PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), p2i(thread->stack_base()), - p2i(thread->stack_end()), thread->stack_size()); + p2i(thread->stack_end()), thread->stack_size() / K); return true; } @@ -1925,8 +1926,65 @@ st->cr(); } +// Processor Power Information; missing from Windows headers +typedef struct _PROCESSOR_POWER_INFORMATION { + ULONG Number; + ULONG MaxMhz; // max specified clock frequency of the system processor + ULONG CurrentMhz; // max specified processor clock frequency mult. by current processor throttle + ULONG MhzLimit; // max specified processor clock frequency mult. by current processor thermal throttle limit + ULONG MaxIdleState; + ULONG CurrentIdleState; +} PROCESSOR_POWER_INFORMATION; + void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { - // Nothing to do for now. + int proc_count = os::processor_count(); + // handle potential early cases where processor count is not yet set + if (proc_count < 1) { + SYSTEM_INFO si; + GetSystemInfo(&si); + proc_count = si.dwNumberOfProcessors; + } + + size_t sz_check = sizeof(PROCESSOR_POWER_INFORMATION) * (size_t)proc_count; + NTSTATUS status = ::CallNtPowerInformation(ProcessorInformation, NULL, 0, buf, (ULONG) buflen); + int max_mhz = -1, current_mhz = -1, mhz_limit = -1; + bool same_vals_for_all_cpus = true; + + if (status == ERROR_SUCCESS) { + PROCESSOR_POWER_INFORMATION* pppi = (PROCESSOR_POWER_INFORMATION*) buf; + for (int i = 0; i < proc_count; i++) { + if (i == 0) { + max_mhz = (int) pppi->MaxMhz; + current_mhz = (int) pppi->CurrentMhz; + mhz_limit = (int) pppi->MhzLimit; + } else { + if (max_mhz != (int) pppi->MaxMhz || + current_mhz != (int) pppi->CurrentMhz || + mhz_limit != (int) pppi->MhzLimit) { + same_vals_for_all_cpus = false; + break; + } + } + // avoid iteration in case buf is too small to hold all proc infos + if (sz_check > buflen) break; + pppi++; + } + + if (same_vals_for_all_cpus && max_mhz != -1) { + st->print_cr("Processor Information for all %d processors :", proc_count); + st->print_cr(" Max Mhz: %d, Current Mhz: %d, Mhz Limit: %d", max_mhz, current_mhz, mhz_limit); + return; + } + // differing values, iterate again + pppi = (PROCESSOR_POWER_INFORMATION*) buf; + for (int i = 0; i < proc_count; i++) { + st->print_cr("Processor Information for processor %d", (int) pppi->Number); + st->print_cr(" Max Mhz: %d, Current Mhz: %d, Mhz Limit: %d", + (int) pppi->MaxMhz, (int) pppi->CurrentMhz, (int) pppi->MhzLimit); + if (sz_check > buflen) break; + pppi++; + } + } } void os::get_summary_cpu_info(char* buf, size_t buflen) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp openjdk-17-17.0.8+7/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -87,9 +87,14 @@ atomic_memory_order order) const { STATIC_ASSERT(4 == sizeof(I)); STATIC_ASSERT(4 == sizeof(D)); - D old_value - = atomic_fastcall(aarch64_atomic_fetch_add_4_impl, dest, add_value); - return old_value; + aarch64_atomic_stub_t stub; + switch (order) { + case memory_order_relaxed: + stub = aarch64_atomic_fetch_add_4_relaxed_impl; break; + default: + stub = aarch64_atomic_fetch_add_4_impl; break; + } + return atomic_fastcall(stub, dest, add_value); } template<> @@ -98,9 +103,14 @@ atomic_memory_order order) const { STATIC_ASSERT(8 == sizeof(I)); STATIC_ASSERT(8 == sizeof(D)); - D old_value - = atomic_fastcall(aarch64_atomic_fetch_add_8_impl, dest, add_value); - return old_value; + aarch64_atomic_stub_t stub; + switch (order) { + case memory_order_relaxed: + stub = aarch64_atomic_fetch_add_8_relaxed_impl; break; + default: + stub = aarch64_atomic_fetch_add_8_impl; break; + } + return atomic_fastcall(stub, dest, add_value); } template<> diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S openjdk-17-17.0.8+7/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S --- openjdk-17-17.0.7+7~us1/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S 2023-07-05 07:11:54.000000000 +0000 @@ -47,6 +47,28 @@ mov w0, w2 ret + .global aarch64_atomic_fetch_add_8_relaxed_default_impl + .align 5 +aarch64_atomic_fetch_add_8_relaxed_default_impl: + prfm pstl1strm, [x0] +0: ldxr x2, [x0] + add x8, x2, x1 + stxr w9, x8, [x0] + cbnz w9, 0b + mov x0, x2 + ret + + .global aarch64_atomic_fetch_add_4_relaxed_default_impl + .align 5 +aarch64_atomic_fetch_add_4_relaxed_default_impl: + prfm pstl1strm, [x0] +0: ldxr w2, [x0] + add w8, w2, w1 + stxr w9, w8, [x0] + cbnz w9, 0b + mov w0, w2 + ret + .globl aarch64_atomic_xchg_4_default_impl .align 5 aarch64_atomic_xchg_4_default_impl: diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/adlc/formssel.cpp openjdk-17-17.0.8+7/src/hotspot/share/adlc/formssel.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/adlc/formssel.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/adlc/formssel.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -4117,6 +4117,7 @@ !strcmp(_opType,"MemBarReleaseLock") || !strcmp(_opType,"LoadFence" ) || !strcmp(_opType,"StoreFence") || + !strcmp(_opType,"StoreStoreFence") || !strcmp(_opType,"MemBarVolatile") || !strcmp(_opType,"MemBarCPUOrder") || !strcmp(_opType,"MemBarStoreStore") || diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/c1/c1_Compiler.cpp openjdk-17-17.0.8+7/src/hotspot/share/c1/c1_Compiler.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/c1/c1_Compiler.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/c1/c1_Compiler.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -142,6 +142,7 @@ // since GC can change its value. case vmIntrinsics::_loadFence: case vmIntrinsics::_storeFence: + case vmIntrinsics::_storeStoreFence: case vmIntrinsics::_fullFence: case vmIntrinsics::_floatToRawIntBits: case vmIntrinsics::_intBitsToFloat: diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/c1/c1_LIRGenerator.cpp openjdk-17-17.0.8+7/src/hotspot/share/c1/c1_LIRGenerator.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/c1/c1_LIRGenerator.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/c1/c1_LIRGenerator.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -3149,6 +3149,9 @@ case vmIntrinsics::_storeFence: __ membar_release(); break; + case vmIntrinsics::_storeStoreFence: + __ membar_storestore(); + break; case vmIntrinsics::_fullFence : __ membar(); break; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/c1/c1_RangeCheckElimination.cpp openjdk-17-17.0.8+7/src/hotspot/share/c1/c1_RangeCheckElimination.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/c1/c1_RangeCheckElimination.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/c1/c1_RangeCheckElimination.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -228,24 +228,23 @@ Bound* y_bound = _rce->get_bound(y); if (x_bound->lower() >= 0 && x_bound->lower_instr() == NULL && y->as_ArrayLength() != NULL) { _bound = new Bound(0, NULL, -1, y); - } else if (y->type()->as_IntConstant() && y->type()->as_IntConstant()->value() != 0) { + } else if (x_bound->has_lower() && x_bound->lower() >= 0 && y->type()->as_IntConstant() && + y->type()->as_IntConstant()->value() != 0 && y->type()->as_IntConstant()->value() != min_jint) { // The binary % operator is said to yield the remainder of its operands from an implied division; the // left-hand operand is the dividend and the right-hand operand is the divisor. // - // % operator follows from this rule that the result of the remainder operation can be negative only + // It follows from this rule that the result of the remainder operation can be negative only // if the dividend is negative, and can be positive only if the dividend is positive. Moreover, the - // magnitude of the result is always less than the magnitude of the divisor(See JLS 15.17.3). + // magnitude of the result is always less than the magnitude of the divisor (see JLS 15.17.3). // // So if y is a constant integer and not equal to 0, then we can deduce the bound of remainder operation: // x % -y ==> [0, y - 1] Apply RCE // x % y ==> [0, y - 1] Apply RCE // -x % y ==> [-y + 1, 0] // -x % -y ==> [-y + 1, 0] - if (x_bound->has_lower() && x_bound->lower() >= 0) { - _bound = new Bound(0, NULL, y->type()->as_IntConstant()->value() - 1, NULL); - } else { - _bound = new Bound(); - } + // + // Use the absolute value of y as an upper bound. Skip min_jint because abs(min_jint) is undefined. + _bound = new Bound(0, NULL, abs(y->type()->as_IntConstant()->value()) - 1, NULL); } else { _bound = new Bound(); } @@ -270,17 +269,16 @@ Bound * bound = _rce->get_bound(y); if (bound->has_upper() && bound->has_lower()) { - int new_lower = bound->lower() + const_value; - jlong new_lowerl = ((jlong)bound->lower()) + const_value; - int new_upper = bound->upper() + const_value; - jlong new_upperl = ((jlong)bound->upper()) + const_value; - - if (((jlong)new_lower) == new_lowerl && ((jlong)new_upper == new_upperl)) { - Bound *newBound = new Bound(new_lower, bound->lower_instr(), new_upper, bound->upper_instr()); - _bound = newBound; - } else { - // overflow + jint t_lo = bound->lower(); + jint t_hi = bound->upper(); + jint new_lower = java_add(t_lo, const_value); + jint new_upper = java_add(t_hi, const_value); + bool overflow = ((const_value < 0 && (new_lower > t_lo)) || + (const_value > 0 && (new_upper < t_hi))); + if (overflow) { _bound = new Bound(); + } else { + _bound = new Bound(new_lower, bound->lower_instr(), new_upper, bound->upper_instr()); } } else { _bound = new Bound(); @@ -1558,7 +1556,6 @@ NOT_PRODUCT(ao->set_printable_bci(position->printable_bci())); result = result->insert_after(ao); compare_with = ao; - // TODO: Check that add operation does not overflow! } } assert(compare_with != NULL, "You have to compare with something!"); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/cds/filemap.cpp openjdk-17-17.0.8+7/src/hotspot/share/cds/filemap.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/cds/filemap.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/cds/filemap.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2347,28 +2347,28 @@ ClassPathEntry** FileMapInfo::_classpath_entries_for_jvmti = NULL; ClassPathEntry* FileMapInfo::get_classpath_entry_for_jvmti(int i, TRAPS) { + if (i == 0) { + // index 0 corresponds to the ClassPathImageEntry which is a globally shared object + // and should never be deleted. + return ClassLoader::get_jrt_entry(); + } ClassPathEntry* ent = _classpath_entries_for_jvmti[i]; if (ent == NULL) { - if (i == 0) { - ent = ClassLoader::get_jrt_entry(); - assert(ent != NULL, "must be"); - } else { - SharedClassPathEntry* scpe = shared_path(i); - assert(scpe->is_jar(), "must be"); // other types of scpe will not produce archived classes + SharedClassPathEntry* scpe = shared_path(i); + assert(scpe->is_jar(), "must be"); // other types of scpe will not produce archived classes - const char* path = scpe->name(); - struct stat st; - if (os::stat(path, &st) != 0) { + const char* path = scpe->name(); + struct stat st; + if (os::stat(path, &st) != 0) { + char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); + jio_snprintf(msg, strlen(path) + 127, "error in finding JAR file %s", path); + THROW_MSG_(vmSymbols::java_io_IOException(), msg, NULL); + } else { + ent = ClassLoader::create_class_path_entry(THREAD, path, &st, false, false); + if (ent == NULL) { char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); - jio_snprintf(msg, strlen(path) + 127, "error in finding JAR file %s", path); + jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path); THROW_MSG_(vmSymbols::java_io_IOException(), msg, NULL); - } else { - ent = ClassLoader::create_class_path_entry(THREAD, path, &st, false, false); - if (ent == NULL) { - char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); - jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path); - THROW_MSG_(vmSymbols::java_io_IOException(), msg, NULL); - } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -30,6 +30,7 @@ #include "classfile/javaClasses.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" +#include "runtime/orderAccess.hpp" inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader) { guarantee(loader() != NULL && oopDesc::is_oop(loader()), "Loader must be oop"); @@ -43,29 +44,29 @@ } size_t ClassLoaderDataGraph::num_instance_classes() { - return _num_instance_classes; + return Atomic::load(&_num_instance_classes); } size_t ClassLoaderDataGraph::num_array_classes() { - return _num_array_classes; + return Atomic::load(&_num_array_classes); } void ClassLoaderDataGraph::inc_instance_classes(size_t count) { - Atomic::add(&_num_instance_classes, count); + Atomic::add(&_num_instance_classes, count, memory_order_relaxed); } void ClassLoaderDataGraph::dec_instance_classes(size_t count) { - assert(count <= _num_instance_classes, "Sanity"); - Atomic::sub(&_num_instance_classes, count); + size_t old_count = Atomic::fetch_and_add(&_num_instance_classes, -count, memory_order_relaxed); + assert(old_count >= count, "Sanity"); } void ClassLoaderDataGraph::inc_array_classes(size_t count) { - Atomic::add(&_num_array_classes, count); + Atomic::add(&_num_array_classes, count, memory_order_relaxed); } void ClassLoaderDataGraph::dec_array_classes(size_t count) { - assert(count <= _num_array_classes, "Sanity"); - Atomic::sub(&_num_array_classes, count); + size_t old_count = Atomic::fetch_and_add(&_num_array_classes, -count, memory_order_relaxed); + assert(old_count >= count, "Sanity"); } bool ClassLoaderDataGraph::should_clean_metaspaces_and_reset() { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/javaClasses.cpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/javaClasses.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/javaClasses.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/javaClasses.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2719,49 +2719,57 @@ } } -Handle java_lang_Throwable::get_cause_with_stack_trace(Handle throwable, TRAPS) { - // Call to JVM to fill in the stack trace and clear declaringClassObject to - // not keep classes alive in the stack trace. - // call this: public StackTraceElement[] getStackTrace() +Handle java_lang_Throwable::create_initialization_error(JavaThread* current, Handle throwable) { + // Creates an ExceptionInInitializerError to be recorded as the initialization error when class initialization + // failed due to the passed in 'throwable'. We cannot save 'throwable' directly due to issues with keeping alive + // all objects referenced via its stacktrace. So instead we save a new EIIE instance, with the same message and + // symbolic stacktrace of 'throwable'. assert(throwable.not_null(), "shouldn't be"); - JavaValue result(T_ARRAY); - JavaCalls::call_virtual(&result, throwable, - vmClasses::Throwable_klass(), - vmSymbols::getStackTrace_name(), - vmSymbols::getStackTrace_signature(), - CHECK_NH); - Handle stack_trace(THREAD, result.get_oop()); - assert(stack_trace->is_objArray(), "Should be an array"); - - // Throw ExceptionInInitializerError as the cause with this exception in - // the message and stack trace. - - // Now create the message with the original exception and thread name. + // Now create the message from the original exception and thread name. Symbol* message = java_lang_Throwable::detail_message(throwable()); - ResourceMark rm(THREAD); + ResourceMark rm(current); stringStream st; st.print("Exception %s%s ", throwable()->klass()->name()->as_klass_external_name(), message == nullptr ? "" : ":"); if (message == NULL) { - st.print("[in thread \"%s\"]", THREAD->name()); + st.print("[in thread \"%s\"]", current->name()); } else { - st.print("%s [in thread \"%s\"]", message->as_C_string(), THREAD->name()); + st.print("%s [in thread \"%s\"]", message->as_C_string(), current->name()); } Symbol* exception_name = vmSymbols::java_lang_ExceptionInInitializerError(); - Handle h_cause = Exceptions::new_exception(THREAD, exception_name, st.as_string()); - - // If new_exception returns a different exception while creating the exception, return null. - if (h_cause->klass()->name() != exception_name) { + Handle init_error = Exceptions::new_exception(current, exception_name, st.as_string()); + // If new_exception returns a different exception while creating the exception, + // abandon the attempt to save the initialization error and return null. + if (init_error->klass()->name() != exception_name) { log_info(class, init)("Exception thrown while saving initialization exception %s", - h_cause->klass()->external_name()); + init_error->klass()->external_name()); return Handle(); } - java_lang_Throwable::set_stacktrace(h_cause(), stack_trace()); - // Clear backtrace because the stacktrace should be used instead. - set_backtrace(h_cause(), NULL); - return h_cause; + + // Call to java to fill in the stack trace and clear declaringClassObject to + // not keep classes alive in the stack trace. + // call this: public StackTraceElement[] getStackTrace() + JavaValue result(T_ARRAY); + JavaCalls::call_virtual(&result, throwable, + vmClasses::Throwable_klass(), + vmSymbols::getStackTrace_name(), + vmSymbols::getStackTrace_signature(), + current); + if (!current->has_pending_exception()){ + Handle stack_trace(current, result.get_oop()); + assert(stack_trace->is_objArray(), "Should be an array"); + java_lang_Throwable::set_stacktrace(init_error(), stack_trace()); + // Clear backtrace because the stacktrace should be used instead. + set_backtrace(init_error(), nullptr); + } else { + log_info(class, init)("Exception thrown while getting stack trace for initialization exception %s", + init_error->klass()->external_name()); + current->clear_pending_exception(); + } + + return init_error; } bool java_lang_Throwable::get_top_method_and_bci(oop throwable, Method** method, int* bci) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/javaClasses.hpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/javaClasses.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/javaClasses.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/javaClasses.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -569,7 +569,7 @@ static void get_stack_trace_elements(Handle throwable, objArrayHandle stack_trace, TRAPS); // For recreating class initialization error exceptions. - static Handle get_cause_with_stack_trace(Handle throwable, TRAPS); + static Handle create_initialization_error(JavaThread* current, Handle throwable); // Printing static void print(oop throwable, outputStream* st); @@ -925,6 +925,8 @@ static bool is_referent_field(oop obj, ptrdiff_t offset); static inline bool is_final(oop ref); static inline bool is_phantom(oop ref); + static inline bool is_weak(oop ref); + static inline bool is_soft(oop ref); static int referent_offset() { CHECK_INIT(_referent_offset); } static int queue_offset() { CHECK_INIT(_queue_offset); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/javaClasses.inline.hpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/javaClasses.inline.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/javaClasses.inline.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/javaClasses.inline.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -27,6 +27,7 @@ #include "classfile/javaClasses.hpp" +#include "memory/referenceType.hpp" #include "oops/access.inline.hpp" #include "oops/method.hpp" #include "oops/oop.inline.hpp" @@ -130,10 +131,12 @@ // Accessors oop java_lang_ref_Reference::weak_referent_no_keepalive(oop ref) { + assert(java_lang_ref_Reference::is_weak(ref) || java_lang_ref_Reference::is_soft(ref), "must be Weak or Soft Reference"); return ref->obj_field_access(_referent_offset); } oop java_lang_ref_Reference::phantom_referent_no_keepalive(oop ref) { + assert(java_lang_ref_Reference::is_phantom(ref), "must be Phantom Reference"); return ref->obj_field_access(_referent_offset); } @@ -189,6 +192,14 @@ return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM; } +bool java_lang_ref_Reference::is_weak(oop ref) { + return InstanceKlass::cast(ref->klass())->reference_type() == REF_WEAK; +} + +bool java_lang_ref_Reference::is_soft(oop ref) { + return InstanceKlass::cast(ref->klass())->reference_type() == REF_SOFT; +} + inline void java_lang_invoke_CallSite::set_target_volatile(oop site, oop target) { site->obj_field_put_volatile(_target_offset, target); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/verifier.cpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/verifier.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/verifier.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/verifier.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -594,7 +594,7 @@ ClassVerifier::ClassVerifier(JavaThread* current, InstanceKlass* klass) : _thread(current), _previous_symbol(NULL), _symbols(NULL), _exception_type(NULL), - _message(NULL), _method_signatures_table(NULL), _klass(klass) { + _message(NULL), _klass(klass) { _this_type = VerificationType::reference_type(klass->name()); } @@ -625,16 +625,12 @@ // Either verifying both local and remote classes or just remote classes. assert(BytecodeVerificationRemote, "Should not be here"); - // Create hash table containing method signatures. - method_signatures_table_type method_signatures_table; - set_method_signatures_table(&method_signatures_table); - Array* methods = _klass->methods(); int num_methods = methods->length(); for (int index = 0; index < num_methods; index++) { // Check for recursive re-verification before each method. - if (was_recursively_verified()) return; + if (was_recursively_verified()) return; Method* m = methods->at(index); if (m->is_native() || m->is_abstract() || m->is_overpass()) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/verifier.hpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/verifier.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/verifier.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/verifier.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -286,7 +286,7 @@ Symbol* _exception_type; char* _message; - method_signatures_table_type* _method_signatures_table; + method_signatures_table_type _method_signatures_table; ErrorContext _error_context; // contains information about an error @@ -438,12 +438,8 @@ Klass* load_class(Symbol* name, TRAPS); - method_signatures_table_type* method_signatures_table() const { - return _method_signatures_table; - } - - void set_method_signatures_table(method_signatures_table_type* method_signatures_table) { - _method_signatures_table = method_signatures_table; + method_signatures_table_type* method_signatures_table() { + return &_method_signatures_table; } int change_sig_to_verificationType( diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/vmIntrinsics.cpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/vmIntrinsics.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/vmIntrinsics.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/vmIntrinsics.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -397,6 +397,7 @@ case vmIntrinsics::_compareAndExchangeReference: case vmIntrinsics::_compareAndExchangeReferenceAcquire: case vmIntrinsics::_compareAndExchangeReferenceRelease: + case vmIntrinsics::_allocateInstance: if (!InlineUnsafeOps) return true; break; case vmIntrinsics::_getShortUnaligned: @@ -407,7 +408,6 @@ case vmIntrinsics::_putCharUnaligned: case vmIntrinsics::_putIntUnaligned: case vmIntrinsics::_putLongUnaligned: - case vmIntrinsics::_allocateInstance: if (!InlineUnsafeOps || !UseUnalignedAccesses) return true; break; case vmIntrinsics::_hashCode: diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/vmIntrinsics.hpp openjdk-17-17.0.8+7/src/hotspot/share/classfile/vmIntrinsics.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/classfile/vmIntrinsics.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/classfile/vmIntrinsics.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -520,6 +520,9 @@ do_intrinsic(_storeFence, jdk_internal_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \ do_name( storeFence_name, "storeFence") \ do_alias( storeFence_signature, void_method_signature) \ + do_intrinsic(_storeStoreFence, jdk_internal_misc_Unsafe, storeStoreFence_name, storeStoreFence_signature, F_R) \ + do_name( storeStoreFence_name, "storeStoreFence") \ + do_alias( storeStoreFence_signature, void_method_signature) \ do_intrinsic(_fullFence, jdk_internal_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \ do_name( fullFence_name, "fullFence") \ do_alias( fullFence_signature, void_method_signature) \ diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/code/codeHeapState.cpp openjdk-17-17.0.8+7/src/hotspot/share/code/codeHeapState.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/code/codeHeapState.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/code/codeHeapState.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "code/codeHeapState.hpp" +#include "code/codeBlob.hpp" #include "compiler/compileBroker.hpp" #include "runtime/safepoint.hpp" #include "runtime/sweeper.hpp" @@ -1152,10 +1153,9 @@ ast->cr(); int reset_val = NMethodSweeper::hotness_counter_reset_val(); - double reverse_free_ratio = (res_size > size) ? (double)res_size/(double)(res_size-size) : (double)res_size; printBox(ast, '-', "Method hotness information at time of this analysis", NULL); ast->print_cr("Highest possible method temperature: %12d", reset_val); - ast->print_cr("Threshold for method to be considered 'cold': %12.3f", -reset_val + reverse_free_ratio * NmethodSweepActivity); + ast->print_cr("Threshold for method to be considered 'cold': %12.3f", -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity)); if (n_methods > 0) { avgTemp = hotnessAccumulator/n_methods; ast->print_cr("min. hotness = %6d", minTemp); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/code/compiledIC.hpp openjdk-17-17.0.8+7/src/hotspot/share/code/compiledIC.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/code/compiledIC.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/code/compiledIC.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -338,6 +338,8 @@ class CompiledStaticCall : public ResourceObj { public: // Code + + // Returns NULL if CodeBuffer::expand fails static address emit_to_interp_stub(CodeBuffer &cbuf, address mark = NULL); static int to_interp_stub_size(); static int to_trampoline_stub_size(); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/code/nmethod.cpp openjdk-17-17.0.8+7/src/hotspot/share/code/nmethod.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/code/nmethod.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/code/nmethod.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1657,6 +1657,8 @@ if (is_not_entrant() && can_convert_to_zombie()) { return; } + // Ensure the sweeper can't collect this nmethod until it become "active" with JvmtiThreadState::nmethods_do. + mark_as_seen_on_stack(); } // This is a bad time for a safepoint. We don't want @@ -1829,7 +1831,8 @@ // oops in the CompiledMethod, by calling oops_do on it. state_unloading_cycle = current_cycle; - if (is_zombie() || method()->can_be_allocated_in_NonNMethod_space()) { + Method* m = method(); + if (is_zombie() || (m != nullptr && m->can_be_allocated_in_NonNMethod_space())) { // When the nmethod is in NonNMethod space, we may reach here without IsUnloadingBehaviour. // However, we only allow this for special methods which never get unloaded. diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/compiler/compilationPolicy.hpp openjdk-17-17.0.8+7/src/hotspot/share/compiler/compilationPolicy.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/compiler/compilationPolicy.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/compiler/compilationPolicy.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -251,7 +251,6 @@ static bool can_be_osr_compiled(const methodHandle& m, int comp_level = CompLevel_any); static bool is_compilation_enabled(); - static void do_safepoint_work() { } static CompileTask* select_task_helper(CompileQueue* compile_queue); // Return initial compile level to use with Xcomp (depends on compilation mode). static void reprofile(ScopeDesc* trap_scope, bool is_osr); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/compiler/compileBroker.cpp openjdk-17-17.0.8+7/src/hotspot/share/compiler/compileBroker.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/compiler/compileBroker.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/compiler/compileBroker.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -967,6 +967,21 @@ return new_thread; } +static bool trace_compiler_threads() { + LogTarget(Debug, jit, thread) lt; + return TraceCompilerThreads || lt.is_enabled(); +} + +static void print_compiler_threads(stringStream& msg) { + if (TraceCompilerThreads) { + tty->print_cr("%7d %s", (int)tty->time_stamp().milliseconds(), msg.as_string()); + } + LogTarget(Debug, jit, thread) lt; + if (lt.is_enabled()) { + LogStream ls(lt); + ls.print_cr("%s", msg.as_string()); + } +} void CompileBroker::init_compiler_sweeper_threads() { NMethodSweeper::set_sweep_threshold_bytes(static_cast(SweeperThreshold * ReservedCodeCacheSize / 100.0)); @@ -1009,11 +1024,13 @@ JavaThread *ct = make_thread(compiler_t, thread_handle, _c2_compile_queue, _compilers[1], THREAD); assert(ct != NULL, "should have been handled for initial thread"); _compilers[1]->set_num_compiler_threads(i + 1); - if (TraceCompilerThreads) { + if (trace_compiler_threads()) { ResourceMark rm; ThreadsListHandle tlh; // get_thread_name() depends on the TLH. assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct)); - tty->print_cr("Added initial compiler thread %s", ct->get_thread_name()); + stringStream msg; + msg.print("Added initial compiler thread %s", ct->get_thread_name()); + print_compiler_threads(msg); } } } @@ -1030,11 +1047,13 @@ JavaThread *ct = make_thread(compiler_t, thread_handle, _c1_compile_queue, _compilers[0], THREAD); assert(ct != NULL, "should have been handled for initial thread"); _compilers[0]->set_num_compiler_threads(i + 1); - if (TraceCompilerThreads) { + if (trace_compiler_threads()) { ResourceMark rm; ThreadsListHandle tlh; // get_thread_name() depends on the TLH. assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct)); - tty->print_cr("Added initial compiler thread %s", ct->get_thread_name()); + stringStream msg; + msg.print("Added initial compiler thread %s", ct->get_thread_name()); + print_compiler_threads(msg); } } } @@ -1099,10 +1118,12 @@ thread_oop = create_thread_oop(name_buffer, THREAD); } if (HAS_PENDING_EXCEPTION) { - if (TraceCompilerThreads) { + if (trace_compiler_threads()) { ResourceMark rm; - tty->print_cr("JVMCI compiler thread creation failed:"); - PENDING_EXCEPTION->print(); + stringStream msg; + msg.print_cr("JVMCI compiler thread creation failed:"); + PENDING_EXCEPTION->print_on(&msg); + print_compiler_threads(msg); } CLEAR_PENDING_EXCEPTION; break; @@ -1117,12 +1138,14 @@ JavaThread *ct = make_thread(compiler_t, compiler2_object(i), _c2_compile_queue, _compilers[1], THREAD); if (ct == NULL) break; _compilers[1]->set_num_compiler_threads(i + 1); - if (TraceCompilerThreads) { + if (trace_compiler_threads()) { ResourceMark rm; ThreadsListHandle tlh; // get_thread_name() depends on the TLH. assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct)); - tty->print_cr("Added compiler thread %s (available memory: %dMB, available non-profiled code cache: %dMB)", - ct->get_thread_name(), (int)(available_memory/M), (int)(available_cc_np/M)); + stringStream msg; + msg.print("Added compiler thread %s (available memory: %dMB, available non-profiled code cache: %dMB)", + ct->get_thread_name(), (int)(available_memory/M), (int)(available_cc_np/M)); + print_compiler_threads(msg); } } } @@ -1138,12 +1161,14 @@ JavaThread *ct = make_thread(compiler_t, compiler1_object(i), _c1_compile_queue, _compilers[0], THREAD); if (ct == NULL) break; _compilers[0]->set_num_compiler_threads(i + 1); - if (TraceCompilerThreads) { + if (trace_compiler_threads()) { ResourceMark rm; ThreadsListHandle tlh; // get_thread_name() depends on the TLH. assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct)); - tty->print_cr("Added compiler thread %s (available memory: %dMB, available profiled code cache: %dMB)", - ct->get_thread_name(), (int)(available_memory/M), (int)(available_cc_p/M)); + stringStream msg; + msg.print("Added compiler thread %s (available memory: %dMB, available profiled code cache: %dMB)", + ct->get_thread_name(), (int)(available_memory/M), (int)(available_cc_p/M)); + print_compiler_threads(msg); } } } @@ -1959,9 +1984,12 @@ // Access compiler_count under lock to enforce consistency. MutexLocker only_one(CompileThread_lock); if (can_remove(thread, true)) { - if (TraceCompilerThreads) { - tty->print_cr("Removing compiler thread %s after " JLONG_FORMAT " ms idle time", - thread->name(), thread->idle_time_millis()); + if (trace_compiler_threads()) { + ResourceMark rm; + stringStream msg; + msg.print("Removing compiler thread %s after " JLONG_FORMAT " ms idle time", + thread->name(), thread->idle_time_millis()); + print_compiler_threads(msg); } // Free buffer blob, if allocated if (thread->get_buffer_blob() != NULL) { @@ -2905,13 +2933,13 @@ ts.update(); // record starting point MutexLocker mu11(function_lock_1, Mutex::_safepoint_check_flag); MutexLocker mu22(function_lock_2, Mutex::_no_safepoint_check_flag); - if ((function_lock_1 != NULL) || (function_lock_1 != NULL)) { + if ((function_lock_1 != NULL) || (function_lock_2 != NULL)) { out->print_cr("\n__ Compile & CodeCache (function) lock wait took %10.3f seconds _________\n", ts.seconds()); } ts.update(); // record starting point CodeCache::aggregate(out, granularity); - if ((function_lock_1 != NULL) || (function_lock_1 != NULL)) { + if ((function_lock_1 != NULL) || (function_lock_2 != NULL)) { out->print_cr("\n__ Compile & CodeCache (function) lock hold took %10.3f seconds _________\n", ts.seconds()); } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/compiler/compilerOracle.cpp openjdk-17-17.0.8+7/src/hotspot/share/compiler/compilerOracle.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/compiler/compilerOracle.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/compiler/compilerOracle.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -308,6 +308,8 @@ if (option == CompileCommand::Blackhole && !UnlockExperimentalVMOptions) { warning("Blackhole compile option is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions"); + // Delete matcher as we don't keep it + delete matcher; return; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/epsilon/epsilonHeap.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/epsilon/epsilonHeap.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/epsilon/epsilonHeap.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/epsilon/epsilonHeap.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -52,7 +52,7 @@ static EpsilonHeap* heap(); EpsilonHeap() : - _memory_manager("Epsilon Heap", ""), + _memory_manager("Epsilon Heap"), _space(NULL) {}; virtual Name kind() const { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1BarrierSet.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1BarrierSet.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1BarrierSet.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1BarrierSet.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -62,21 +62,18 @@ _shared_dirty_card_queue(&_dirty_card_queue_set) {} -void G1BarrierSet::enqueue(oop pre_val) { - // Nulls should have been already filtered. - assert(oopDesc::is_oop(pre_val, true), "Error"); - SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(Thread::current()); - G1BarrierSet::satb_mark_queue_set().enqueue(queue, pre_val); -} - template void G1BarrierSet::write_ref_array_pre_work(T* dst, size_t count) { - if (!_satb_mark_queue_set.is_active()) return; + G1SATBMarkQueueSet& queue_set = G1BarrierSet::satb_mark_queue_set(); + if (!queue_set.is_active()) return; + + SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(Thread::current()); + T* elem_ptr = dst; for (size_t i = 0; i < count; i++, elem_ptr++) { T heap_oop = RawAccess<>::oop_load(elem_ptr); if (!CompressedOops::is_null(heap_oop)) { - enqueue(CompressedOops::decode_not_null(heap_oop)); + queue_set.enqueue_known_active(queue, CompressedOops::decode_not_null(heap_oop)); } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1BarrierSet.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1BarrierSet.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1BarrierSet.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1BarrierSet.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -58,10 +58,12 @@ } // Add "pre_val" to a set of objects that may have been disconnected from the - // pre-marking object graph. - static void enqueue(oop pre_val); + // pre-marking object graph. Prefer the version that takes location, as it + // can avoid touching the heap unnecessarily. + template static void enqueue(T* dst); + static void enqueue_preloaded(oop pre_val); - static void enqueue_if_weak(DecoratorSet decorators, oop value); + static void enqueue_preloaded_if_weak(DecoratorSet decorators, oop value); template void write_ref_array_pre_work(T* dst, size_t count); virtual void write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -28,11 +28,35 @@ #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1CardTable.hpp" +#include "gc/g1/g1ThreadLocalData.hpp" #include "gc/shared/accessBarrierSupport.inline.hpp" #include "oops/access.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/oop.hpp" +inline void G1BarrierSet::enqueue_preloaded(oop pre_val) { + // Nulls should have been already filtered. + assert(oopDesc::is_oop(pre_val, true), "Error"); + + G1SATBMarkQueueSet& queue_set = G1BarrierSet::satb_mark_queue_set(); + if (!queue_set.is_active()) return; + + SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(Thread::current()); + queue_set.enqueue_known_active(queue, pre_val); +} + +template +inline void G1BarrierSet::enqueue(T* dst) { + G1SATBMarkQueueSet& queue_set = G1BarrierSet::satb_mark_queue_set(); + if (!queue_set.is_active()) return; + + T heap_oop = RawAccess::oop_load(dst); + if (!CompressedOops::is_null(heap_oop)) { + SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(Thread::current()); + queue_set.enqueue_known_active(queue, CompressedOops::decode_not_null(heap_oop)); + } +} + template inline void G1BarrierSet::write_ref_field_pre(T* field) { if (HasDecorator::value || @@ -40,10 +64,7 @@ return; } - T heap_oop = RawAccess::oop_load(field); - if (!CompressedOops::is_null(heap_oop)) { - enqueue(CompressedOops::decode_not_null(heap_oop)); - } + enqueue(field); } template @@ -55,7 +76,7 @@ } } -inline void G1BarrierSet::enqueue_if_weak(DecoratorSet decorators, oop value) { +inline void G1BarrierSet::enqueue_preloaded_if_weak(DecoratorSet decorators, oop value) { assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known"); // Loading from a weak or phantom reference needs enqueueing, as // the object may not have been reachable (part of the snapshot) @@ -65,7 +86,7 @@ const bool needs_enqueue = (!peek && !on_strong_oop_ref); if (needs_enqueue && value != NULL) { - enqueue(value); + enqueue_preloaded(value); } } @@ -74,7 +95,7 @@ inline oop G1BarrierSet::AccessBarrier:: oop_load_not_in_heap(T* addr) { oop value = ModRef::oop_load_not_in_heap(addr); - enqueue_if_weak(decorators, value); + enqueue_preloaded_if_weak(decorators, value); return value; } @@ -83,7 +104,7 @@ inline oop G1BarrierSet::AccessBarrier:: oop_load_in_heap(T* addr) { oop value = ModRef::oop_load_in_heap(addr); - enqueue_if_weak(decorators, value); + enqueue_preloaded_if_weak(decorators, value); return value; } @@ -91,7 +112,7 @@ inline oop G1BarrierSet::AccessBarrier:: oop_load_in_heap_at(oop base, ptrdiff_t offset) { oop value = ModRef::oop_load_in_heap_at(base, offset); - enqueue_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength(base, offset), value); + enqueue_preloaded_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength(base, offset), value); return value; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1CollectedHeap.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1CollectedHeap.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2292,7 +2292,7 @@ } void G1CollectedHeap::keep_alive(oop obj) { - G1BarrierSet::enqueue(obj); + G1BarrierSet::enqueue_preloaded(obj); } void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -56,26 +56,6 @@ create_and_start(); } -class CMRemark : public VoidClosure { - G1ConcurrentMark* _cm; -public: - CMRemark(G1ConcurrentMark* cm) : _cm(cm) {} - - void do_void(){ - _cm->remark(); - } -}; - -class CMCleanup : public VoidClosure { - G1ConcurrentMark* _cm; -public: - CMCleanup(G1ConcurrentMark* cm) : _cm(cm) {} - - void do_void(){ - _cm->cleanup(); - } -}; - double G1ConcurrentMarkThread::mmu_delay_end(G1Policy* policy, bool remark) { // There are 3 reasons to use SuspendibleThreadSetJoiner. // 1. To avoid concurrency problem. @@ -239,8 +219,7 @@ bool G1ConcurrentMarkThread::subphase_remark() { ConcurrentGCBreakpoints::at("BEFORE MARKING COMPLETED"); - CMRemark cl(_cm); - VM_G1Concurrent op(&cl, "Pause Remark"); + VM_G1PauseRemark op; VMThread::execute(&op); return _cm->has_aborted(); } @@ -257,8 +236,7 @@ } bool G1ConcurrentMarkThread::phase_cleanup() { - CMCleanup cl(_cm); - VM_G1Concurrent op(&cl, "Pause Cleanup"); + VM_G1PauseCleanup op; VMThread::execute(&op); return _cm->has_aborted(); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1FullCollector.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1FullCollector.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1FullCollector.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1FullCollector.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -304,7 +304,10 @@ _heap->complete_cleaning(&_is_alive, purged_class); } - scope()->tracer()->report_object_count_after_gc(&_is_alive); + { + GCTraceTime(Debug, gc, phases) debug("Report Object Count", scope()->timer()); + scope()->tracer()->report_object_count_after_gc(&_is_alive); + } } void G1FullCollector::phase2_prepare_compaction() { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -86,8 +86,8 @@ G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) : _g1h(g1h), - _incremental_memory_manager("G1 Young Generation", "end of minor GC"), - _full_gc_memory_manager("G1 Old Generation", "end of major GC"), + _incremental_memory_manager("G1 Young Generation"), + _full_gc_memory_manager("G1 Old Generation"), _eden_space_pool(NULL), _survivor_space_pool(NULL), _old_gen_pool(NULL), @@ -345,5 +345,5 @@ G1MonitoringScope::G1MonitoringScope(G1MonitoringSupport* g1mm, bool full_gc, bool all_memory_pools_affected) : _tcs(full_gc ? g1mm->_full_collection_counters : g1mm->_incremental_collection_counters), _tms(full_gc ? &g1mm->_full_gc_memory_manager : &g1mm->_incremental_memory_manager, - G1CollectedHeap::heap()->gc_cause(), all_memory_pools_affected) { + G1CollectedHeap::heap()->gc_cause(), full_gc ? "end of major GC" : "end of minor GC", all_memory_pools_affected) { } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1ServiceThread.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1ServiceThread.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1ServiceThread.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1ServiceThread.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -112,12 +112,10 @@ } void G1ServiceThread::sleep_before_next_cycle() { + MonitorLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); if (should_terminate()) { return; - } - - MonitorLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); - if (_task_queue.is_empty()) { + } else if (_task_queue.is_empty()) { // Sleep until new task is registered if no tasks available. log_trace(gc, task)("G1 Service Thread (wait for new tasks)"); ml.wait(0); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1VMOperations.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1VMOperations.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1VMOperations.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1VMOperations.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -159,7 +159,7 @@ } } -void VM_G1Concurrent::doit() { +void VM_G1PauseConcurrent::doit() { GCIdMark gc_id_mark(_gc_id); GCTraceCPUTime tcpu; G1CollectedHeap* g1h = G1CollectedHeap::heap(); @@ -173,17 +173,28 @@ TraceCollectorStats tcs(g1h->g1mm()->conc_collection_counters()); SvcGCMarker sgcm(SvcGCMarker::CONCURRENT); IsGCActiveMark x; - _cl->do_void(); + + work(); } -bool VM_G1Concurrent::doit_prologue() { +bool VM_G1PauseConcurrent::doit_prologue() { Heap_lock->lock(); return true; } -void VM_G1Concurrent::doit_epilogue() { +void VM_G1PauseConcurrent::doit_epilogue() { if (Universe::has_reference_pending_list()) { Heap_lock->notify_all(); } Heap_lock->unlock(); } + +void VM_G1PauseRemark::work() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + g1h->concurrent_mark()->remark(); +} + +void VM_G1PauseCleanup::work() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + g1h->concurrent_mark()->cleanup(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1VMOperations.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1VMOperations.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/g1/g1VMOperations.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/g1/g1VMOperations.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -84,18 +84,33 @@ }; // Concurrent G1 stop-the-world operations such as remark and cleanup. -class VM_G1Concurrent : public VM_Operation { - VoidClosure* _cl; - const char* _message; +class VM_G1PauseConcurrent : public VM_Operation { uint _gc_id; + const char* _message; + +protected: + VM_G1PauseConcurrent(const char* message) : + _gc_id(GCId::current()), _message(message) { } + virtual void work() = 0; + +public: + bool doit_prologue() override; + void doit_epilogue() override; + void doit() override; +}; + +class VM_G1PauseRemark : public VM_G1PauseConcurrent { +public: + VM_G1PauseRemark() : VM_G1PauseConcurrent("Pause Remark") { } + VMOp_Type type() const override { return VMOp_G1PauseRemark; } + void work() override; +}; +class VM_G1PauseCleanup : public VM_G1PauseConcurrent { public: - VM_G1Concurrent(VoidClosure* cl, const char* message) : - _cl(cl), _message(message), _gc_id(GCId::current()) { } - virtual VMOp_Type type() const { return VMOp_G1Concurrent; } - virtual void doit(); - virtual bool doit_prologue(); - virtual void doit_epilogue(); + VM_G1PauseCleanup() : VM_G1PauseConcurrent("Pause Cleanup") { } + VMOp_Type type() const override { return VMOp_G1PauseCleanup; } + void work() override; }; #endif // SHARE_GC_G1_G1VMOPERATIONS_HPP diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -150,8 +150,8 @@ "PS Old Gen", true /* support_usage_threshold */); - _young_manager = new GCMemoryManager("PS Scavenge", "end of minor GC"); - _old_manager = new GCMemoryManager("PS MarkSweep", "end of major GC"); + _young_manager = new GCMemoryManager("PS Scavenge"); + _old_manager = new GCMemoryManager("PS MarkSweep"); _old_manager->add_pool(_eden_pool); _old_manager->add_pool(_survivor_pool); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/parallel/psParallelCompact.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/parallel/psParallelCompact.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/parallel/psParallelCompact.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/parallel/psParallelCompact.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1773,7 +1773,7 @@ heap->pre_full_gc_dump(&_gc_timer); TraceCollectorStats tcs(counters()); - TraceMemoryManagerStats tms(heap->old_gc_manager(), gc_cause); + TraceMemoryManagerStats tms(heap->old_gc_manager(), gc_cause, "end of major GC"); if (log_is_enabled(Debug, gc, heap, exit)) { accumulated_time()->start(); @@ -2137,7 +2137,10 @@ JVMCI_ONLY(JVMCI::do_unloading(purged_class)); } - _gc_tracer.report_object_count_after_gc(is_alive_closure()); + { + GCTraceTime(Debug, gc, phases) tm("Report Object Count", &_gc_timer); + _gc_tracer.report_object_count_after_gc(is_alive_closure()); + } } #ifdef ASSERT diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/parallel/psScavenge.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/parallel/psScavenge.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/parallel/psScavenge.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/parallel/psScavenge.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -420,7 +420,7 @@ GCTraceCPUTime tcpu; GCTraceTime(Info, gc) tm("Pause Young", NULL, gc_cause, true); TraceCollectorStats tcs(counters()); - TraceMemoryManagerStats tms(heap->young_gc_manager(), gc_cause); + TraceMemoryManagerStats tms(heap->young_gc_manager(), gc_cause, "end of minor GC"); if (log_is_enabled(Debug, gc, heap, exit)) { accumulated_time()->start(); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/serial/genMarkSweep.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/serial/genMarkSweep.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/serial/genMarkSweep.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/serial/genMarkSweep.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -230,7 +230,10 @@ JVMCI_ONLY(JVMCI::do_unloading(purged_class)); } - gc_tracer()->report_object_count_after_gc(&is_alive); + { + GCTraceTime(Debug, gc, phases) tm_m("Report Object Count", gc_timer()); + gc_tracer()->report_object_count_after_gc(&is_alive); + } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/serial/serialHeap.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/serial/serialHeap.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/serial/serialHeap.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/serial/serialHeap.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -42,8 +42,8 @@ _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) { - _young_manager = new GCMemoryManager("Copy", "end of minor GC"); - _old_manager = new GCMemoryManager("MarkSweepCompact", "end of major GC"); + _young_manager = new GCMemoryManager("Copy"); + _old_manager = new GCMemoryManager("MarkSweepCompact"); } void SerialHeap::initialize_serviceability() { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -290,7 +290,7 @@ virtual void verify_gc_barriers(Compile* compile, CompilePhase phase) const {} #endif - virtual bool final_graph_reshaping(Compile* compile, Node* n, uint opcode) const { return false; } + virtual bool final_graph_reshaping(Compile* compile, Node* n, uint opcode, Unique_Node_List& dead_nodes) const { return false; } virtual bool escape_add_to_con_graph(ConnectionGraph* conn_graph, PhaseGVN* gvn, Unique_Node_List* delayed_worklist, Node* n, uint opcode) const { return false; } virtual bool escape_add_final_edges(ConnectionGraph* conn_graph, PhaseGVN* gvn, Node* n, uint opcode) const { return false; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shared/genCollectedHeap.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shared/genCollectedHeap.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shared/genCollectedHeap.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shared/genCollectedHeap.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -444,7 +444,7 @@ FormatBuffer<> title("Collect gen: %s", gen->short_name()); GCTraceTime(Trace, gc, phases) t1(title); TraceCollectorStats tcs(gen->counters()); - TraceMemoryManagerStats tmms(gen->gc_manager(), gc_cause()); + TraceMemoryManagerStats tmms(gen->gc_manager(), gc_cause(), heap()->is_young_gen(gen) ? "end of minor GC" : "end of major GC"); gen->stat_record()->invocations++; gen->stat_record()->accumulated_time.start(); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1124,7 +1124,7 @@ return n->outcnt() > 0; } -bool ShenandoahBarrierSetC2::final_graph_reshaping(Compile* compile, Node* n, uint opcode) const { +bool ShenandoahBarrierSetC2::final_graph_reshaping(Compile* compile, Node* n, uint opcode, Unique_Node_List& dead_nodes) const { switch (opcode) { case Op_CallLeaf: case Op_CallLeafNoFP: { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -139,7 +139,7 @@ #endif virtual Node* ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const; - virtual bool final_graph_reshaping(Compile* compile, Node* n, uint opcode) const; + virtual bool final_graph_reshaping(Compile* compile, Node* n, uint opcode, Unique_Node_List& dead_nodes) const; virtual bool escape_add_to_con_graph(ConnectionGraph* conn_graph, PhaseGVN* gvn, Unique_Node_List* delayed_worklist, Node* n, uint opcode) const; virtual bool escape_add_final_edges(ConnectionGraph* conn_graph, PhaseGVN* gvn, Node* n, uint opcode) const; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -40,7 +40,6 @@ FLAG_SET_DEFAULT(ClassUnloadingWithConcurrentMark, false); if (ClassUnloading) { - FLAG_SET_DEFAULT(ShenandoahSuspendibleWorkers, true); FLAG_SET_DEFAULT(VerifyBeforeExit, false); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -35,7 +35,6 @@ void ShenandoahSATBMode::initialize_flags() const { if (ClassUnloading) { - FLAG_SET_DEFAULT(ShenandoahSuspendibleWorkers, true); FLAG_SET_DEFAULT(VerifyBeforeExit, false); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -54,7 +54,7 @@ fwd = _heap->evacuate_object(obj, _thread); } assert(obj != fwd || _heap->cancelled_gc(), "must be forwarded"); - ShenandoahHeap::cas_oop(fwd, p, o); + ShenandoahHeap::atomic_update_oop(fwd, p, o); obj = fwd; } if (ENQUEUE) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -70,7 +70,7 @@ if (load_addr != NULL && fwd != obj) { // Since we are here and we know the load address, update the reference. - ShenandoahHeap::cas_oop(fwd, load_addr, obj); + ShenandoahHeap::atomic_update_oop(fwd, load_addr, obj); } return fwd; @@ -125,7 +125,7 @@ oop fwd = load_reference_barrier(obj); if (ShenandoahSelfFixing && load_addr != NULL && fwd != obj) { // Since we are here and we know the load address, update the reference. - ShenandoahHeap::cas_oop(fwd, load_addr, obj); + ShenandoahHeap::atomic_update_oop(fwd, load_addr, obj); } return fwd; @@ -353,7 +353,7 @@ fwd = _heap->evacuate_object(obj, thread); } assert(obj != fwd || _heap->cancelled_gc(), "must be forwarded"); - oop witness = ShenandoahHeap::cas_oop(fwd, elem_ptr, o); + ShenandoahHeap::atomic_update_oop(fwd, elem_ptr, o); obj = fwd; } if (ENQUEUE && !ctx->is_marked_strong(obj)) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -161,7 +161,7 @@ if (resolved == obj) { resolved = _heap->evacuate_object(obj, t); } - _heap->cas_oop(resolved, p, o); + ShenandoahHeap::atomic_update_oop(resolved, p, o); } } } @@ -207,7 +207,7 @@ _keep_alive->do_oop(p); } else { if (CONCURRENT) { - Atomic::cmpxchg(p, obj, oop()); + ShenandoahHeap::atomic_clear_oop(p, obj); } else { RawAccess::oop_store(p, oop()); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -698,13 +698,13 @@ if (!CompressedOops::is_null(obj)) { if (!_mark_context->is_marked(obj)) { shenandoah_assert_correct(p, obj); - Atomic::cmpxchg(p, obj, oop(NULL)); + ShenandoahHeap::atomic_clear_oop(p, obj); } else if (_evac_in_progress && _heap->in_collection_set(obj)) { oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (resolved == obj) { resolved = _heap->evacuate_object(obj, _thread); } - Atomic::cmpxchg(p, obj, resolved); + ShenandoahHeap::atomic_update_oop(resolved, p, obj); assert(_heap->cancelled_gc() || _mark_context->is_marked(resolved) && !_heap->in_collection_set(resolved), "Sanity"); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -53,7 +53,7 @@ _requested_gc_cause(GCCause::_no_cause_specified), _degen_point(ShenandoahGC::_degenerated_outside_cycle), _allocs_seen(0) { - + set_name("Shenandoah Control Thread"); reset_gc_id(); create_and_start(); _periodic_task.enroll(); @@ -623,16 +623,6 @@ return Atomic::load(&_gc_id); } -void ShenandoahControlThread::print() const { - print_on(tty); -} - -void ShenandoahControlThread::print_on(outputStream* st) const { - st->print("Shenandoah Concurrent Thread"); - Thread::print_on(st); - st->cr(); -} - void ShenandoahControlThread::start() { create_and_start(); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -142,12 +142,6 @@ void start(); void prepare_for_graceful_shutdown(); bool in_graceful_shutdown(); - - char* name() const { return (char*)"ShenandoahControlThread";} - - // Printing - void print_on(outputStream* st) const; - void print() const; }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCONTROLTHREAD_HPP diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -334,7 +334,7 @@ "How many times to maximum attempt to flush SATB buffers at the " \ "end of concurrent marking.") \ \ - product(bool, ShenandoahSuspendibleWorkers, false, EXPERIMENTAL, \ + product(bool, ShenandoahSuspendibleWorkers, true, EXPERIMENTAL, \ "Suspend concurrent GC worker threads at safepoints") \ \ product(bool, ShenandoahSATBBarrier, true, DIAGNOSTIC, \ diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -475,8 +475,8 @@ _phase_timings(NULL), _monitoring_support(NULL), _memory_pool(NULL), - _stw_memory_manager("Shenandoah Pauses", "end of GC pause"), - _cycle_memory_manager("Shenandoah Cycles", "end of GC cycle"), + _stw_memory_manager("Shenandoah Pauses"), + _cycle_memory_manager("Shenandoah Cycles"), _gc_timer(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()), _soft_ref_policy(), _log_min_obj_alignment_in_bytes(LogMinObjAlignmentInBytes), @@ -1182,6 +1182,7 @@ } void ShenandoahHeap::gc_threads_do(ThreadClosure* tcl) const { + tcl->do_thread(_control_thread); workers()->threads_do(tcl); if (_safepoint_workers != NULL) { _safepoint_workers->threads_do(tcl); @@ -1740,20 +1741,8 @@ } bool ShenandoahHeap::try_cancel_gc() { - while (true) { - jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE); - if (prev == CANCELLABLE) return true; - else if (prev == CANCELLED) return false; - assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers"); - assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED"); - Thread* thread = Thread::current(); - if (thread->is_Java_thread()) { - // We need to provide a safepoint here, otherwise we might - // spin forever if a SP is pending. - ThreadBlockInVM sp(thread->as_Java_thread()); - SpinPause(); - } - } + jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE); + return prev == CANCELLABLE; } void ShenandoahHeap::cancel_gc(GCCause::Cause cause) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -326,12 +326,7 @@ // GC has been cancelled. Worker threads can not suspend for // safepoint but must finish their work as soon as possible. - CANCELLED, - - // GC has not been cancelled and must not be cancelled. At least - // one worker thread checks for pending safepoint and may suspend - // if a safepoint is pending. - NOT_CANCELLED + CANCELLED }; ShenandoahSharedEnumFlag _cancelled_gc; @@ -635,9 +630,17 @@ template inline void update_with_forwarded(T* p); - static inline oop cas_oop(oop n, narrowOop* addr, oop c); - static inline oop cas_oop(oop n, oop* addr, oop c); - static inline oop cas_oop(oop n, narrowOop* addr, narrowOop c); + static inline void atomic_update_oop(oop update, oop* addr, oop compare); + static inline void atomic_update_oop(oop update, narrowOop* addr, oop compare); + static inline void atomic_update_oop(oop update, narrowOop* addr, narrowOop compare); + + static inline bool atomic_update_oop_check(oop update, oop* addr, oop compare); + static inline bool atomic_update_oop_check(oop update, narrowOop* addr, oop compare); + static inline bool atomic_update_oop_check(oop update, narrowOop* addr, narrowOop compare); + + static inline void atomic_clear_oop( oop* addr, oop compare); + static inline void atomic_clear_oop(narrowOop* addr, oop compare); + static inline void atomic_clear_oop(narrowOop* addr, narrowOop compare); void trash_humongous_region_at(ShenandoahHeapRegion *r); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -132,29 +132,110 @@ // Either we succeed in updating the reference, or something else gets in our way. // We don't care if that is another concurrent GC update, or another mutator update. - // We only check that non-NULL store still updated with non-forwarded reference. - oop witness = cas_oop(fwd, p, obj); - shenandoah_assert_not_forwarded_except(p, witness, (witness == NULL) || (witness == obj)); + atomic_update_oop(fwd, p, obj); } } } -inline oop ShenandoahHeap::cas_oop(oop n, oop* addr, oop c) { +// Atomic updates of heap location. This is only expected to work with updating the same +// logical object with its forwardee. The reason why we need stronger-than-relaxed memory +// ordering has to do with coordination with GC barriers and mutator accesses. +// +// In essence, stronger CAS access is required to maintain the transitive chains that mutator +// accesses build by themselves. To illustrate this point, consider the following example. +// +// Suppose "o" is the object that has a field "x" and the reference to "o" is stored +// to field at "addr", which happens to be Java volatile field. Normally, the accesses to volatile +// field at "addr" would be matched with release/acquire barriers. This changes when GC moves +// the object under mutator feet. +// +// Thread 1 (Java) +// // --- previous access starts here +// ... +// T1.1: store(&o.x, 1, mo_relaxed) +// T1.2: store(&addr, o, mo_release) // volatile store +// +// // --- new access starts here +// // LRB: copy and install the new copy to fwdptr +// T1.3: var copy = copy(o) +// T1.4: cas(&fwd, t, copy, mo_release) // pointer-mediated publication +// +// +// Thread 2 (GC updater) +// T2.1: var f = load(&fwd, mo_{consume|acquire}) // pointer-mediated acquisition +// T2.2: cas(&addr, o, f, mo_release) // this method +// +// Thread 3 (Java) +// T3.1: var o = load(&addr, mo_acquire) // volatile read +// T3.2: if (o != null) +// T3.3: var r = load(&o.x, mo_relaxed) +// +// r is guaranteed to contain "1". +// +// Without GC involvement, there is synchronizes-with edge from T1.2 to T3.1, +// which guarantees this. With GC involvement, when LRB copies the object and +// another thread updates the reference to it, we need to have the transitive edge +// from T1.4 to T2.1 (that one is guaranteed by forwarding accesses), plus the edge +// from T2.2 to T3.1 (which is brought by this CAS). +// +// Note that we do not need to "acquire" in these methods, because we do not read the +// failure witnesses contents on any path, and "release" is enough. +// + +inline void ShenandoahHeap::atomic_update_oop(oop update, oop* addr, oop compare) { + assert(is_aligned(addr, HeapWordSize), "Address should be aligned: " PTR_FORMAT, p2i(addr)); + Atomic::cmpxchg(addr, compare, update, memory_order_release); +} + +inline void ShenandoahHeap::atomic_update_oop(oop update, narrowOop* addr, narrowOop compare) { + assert(is_aligned(addr, sizeof(narrowOop)), "Address should be aligned: " PTR_FORMAT, p2i(addr)); + narrowOop u = CompressedOops::encode(update); + Atomic::cmpxchg(addr, compare, u, memory_order_release); +} + +inline void ShenandoahHeap::atomic_update_oop(oop update, narrowOop* addr, oop compare) { + assert(is_aligned(addr, sizeof(narrowOop)), "Address should be aligned: " PTR_FORMAT, p2i(addr)); + narrowOop c = CompressedOops::encode(compare); + narrowOop u = CompressedOops::encode(update); + Atomic::cmpxchg(addr, c, u, memory_order_release); +} + +inline bool ShenandoahHeap::atomic_update_oop_check(oop update, oop* addr, oop compare) { + assert(is_aligned(addr, HeapWordSize), "Address should be aligned: " PTR_FORMAT, p2i(addr)); + return (oop) Atomic::cmpxchg(addr, compare, update, memory_order_release) == compare; +} + +inline bool ShenandoahHeap::atomic_update_oop_check(oop update, narrowOop* addr, narrowOop compare) { + assert(is_aligned(addr, sizeof(narrowOop)), "Address should be aligned: " PTR_FORMAT, p2i(addr)); + narrowOop u = CompressedOops::encode(update); + return (narrowOop) Atomic::cmpxchg(addr, compare, u, memory_order_release) == compare; +} + +inline bool ShenandoahHeap::atomic_update_oop_check(oop update, narrowOop* addr, oop compare) { + assert(is_aligned(addr, sizeof(narrowOop)), "Address should be aligned: " PTR_FORMAT, p2i(addr)); + narrowOop c = CompressedOops::encode(compare); + narrowOop u = CompressedOops::encode(update); + return CompressedOops::decode(Atomic::cmpxchg(addr, c, u, memory_order_release)) == compare; +} + +// The memory ordering discussion above does not apply for methods that store NULLs: +// then, there is no transitive reads in mutator (as we see NULLs), and we can do +// relaxed memory ordering there. + +inline void ShenandoahHeap::atomic_clear_oop(oop* addr, oop compare) { assert(is_aligned(addr, HeapWordSize), "Address should be aligned: " PTR_FORMAT, p2i(addr)); - return (oop) Atomic::cmpxchg(addr, c, n); + Atomic::cmpxchg(addr, compare, oop(), memory_order_relaxed); } -inline oop ShenandoahHeap::cas_oop(oop n, narrowOop* addr, narrowOop c) { +inline void ShenandoahHeap::atomic_clear_oop(narrowOop* addr, oop compare) { assert(is_aligned(addr, sizeof(narrowOop)), "Address should be aligned: " PTR_FORMAT, p2i(addr)); - narrowOop val = CompressedOops::encode(n); - return CompressedOops::decode(Atomic::cmpxchg(addr, c, val)); + narrowOop cmp = CompressedOops::encode(compare); + Atomic::cmpxchg(addr, cmp, narrowOop(), memory_order_relaxed); } -inline oop ShenandoahHeap::cas_oop(oop n, narrowOop* addr, oop c) { +inline void ShenandoahHeap::atomic_clear_oop(narrowOop* addr, narrowOop compare) { assert(is_aligned(addr, sizeof(narrowOop)), "Address should be aligned: " PTR_FORMAT, p2i(addr)); - narrowOop cmp = CompressedOops::encode(c); - narrowOop val = CompressedOops::encode(n); - return CompressedOops::decode(Atomic::cmpxchg(addr, cmp, val)); + Atomic::cmpxchg(addr, compare, narrowOop(), memory_order_relaxed); } inline bool ShenandoahHeap::cancelled_gc() const { @@ -162,25 +243,12 @@ } inline bool ShenandoahHeap::check_cancelled_gc_and_yield(bool sts_active) { - if (! (sts_active && ShenandoahSuspendibleWorkers)) { - return cancelled_gc(); - } - - jbyte prev = _cancelled_gc.cmpxchg(NOT_CANCELLED, CANCELLABLE); - if (prev == CANCELLABLE || prev == NOT_CANCELLED) { + if (sts_active && ShenandoahSuspendibleWorkers && !cancelled_gc()) { if (SuspendibleThreadSet::should_yield()) { SuspendibleThreadSet::yield(); } - - // Back to CANCELLABLE. The thread that poked NOT_CANCELLED first gets - // to restore to CANCELLABLE. - if (prev == CANCELLABLE) { - _cancelled_gc.set(CANCELLABLE); - } - return false; - } else { - return true; } + return cancelled_gc(); } inline void ShenandoahHeap::clear_cancelled_gc() { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -117,20 +117,9 @@ } template -static bool reference_cas_discovered(oop reference, oop discovered); - -template<> -bool reference_cas_discovered(oop reference, oop discovered) { - volatile narrowOop* addr = reinterpret_cast(java_lang_ref_Reference::discovered_addr_raw(reference)); - narrowOop compare = CompressedOops::encode(NULL); - narrowOop exchange = CompressedOops::encode(discovered); - return Atomic::cmpxchg(addr, compare, exchange) == compare; -} - -template<> -bool reference_cas_discovered(oop reference, oop discovered) { - volatile oop* addr = reinterpret_cast(java_lang_ref_Reference::discovered_addr_raw(reference)); - return Atomic::cmpxchg(addr, oop(NULL), discovered) == NULL; +static bool reference_cas_discovered(oop reference, oop discovered) { + T* addr = reinterpret_cast(java_lang_ref_Reference::discovered_addr_raw(reference)); + return ShenandoahHeap::atomic_update_oop_check(discovered, addr, NULL); } template diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -52,6 +52,7 @@ _heap->shenandoah_policy()->record_cycle_start(); _heap->heuristics()->record_cycle_start(); _trace_cycle.initialize(_heap->cycle_memory_manager(), cause, + "end of GC cycle", /* allMemoryPoolsAffected */ true, /* recordGCBeginTime = */ true, /* recordPreGCUsage = */ true, @@ -73,9 +74,10 @@ _heap->set_gc_cause(GCCause::_no_gc); } -ShenandoahGCPauseMark::ShenandoahGCPauseMark(uint gc_id, SvcGCMarker::reason_type type) : +ShenandoahGCPauseMark::ShenandoahGCPauseMark(uint gc_id, const char* notification_message, SvcGCMarker::reason_type type) : _heap(ShenandoahHeap::heap()), _gc_id_mark(gc_id), _svc_gc_mark(type), _is_gc_active_mark() { _trace_pause.initialize(_heap->stw_memory_manager(), _heap->gc_cause(), + notification_message, /* allMemoryPoolsAffected */ true, /* recordGCBeginTime = */ true, /* recordPreGCUsage = */ false, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -135,7 +135,7 @@ TraceMemoryManagerStats _trace_pause; public: - ShenandoahGCPauseMark(uint gc_id, SvcGCMarker::reason_type type); + ShenandoahGCPauseMark(uint gc_id, const char* notification_action, SvcGCMarker::reason_type type); }; class ShenandoahSafepoint : public AllStatic { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -47,36 +47,36 @@ } void VM_ShenandoahInitMark::doit() { - ShenandoahGCPauseMark mark(_gc_id, SvcGCMarker::CONCURRENT); + ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT); _gc->entry_init_mark(); } void VM_ShenandoahFinalMarkStartEvac::doit() { - ShenandoahGCPauseMark mark(_gc_id, SvcGCMarker::CONCURRENT); + ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT); _gc->entry_final_mark(); } void VM_ShenandoahFullGC::doit() { - ShenandoahGCPauseMark mark(_gc_id, SvcGCMarker::FULL); + ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL); _full_gc->entry_full(_gc_cause); } void VM_ShenandoahDegeneratedGC::doit() { - ShenandoahGCPauseMark mark(_gc_id, SvcGCMarker::CONCURRENT); + ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT); _gc->entry_degenerated(); } void VM_ShenandoahInitUpdateRefs::doit() { - ShenandoahGCPauseMark mark(_gc_id, SvcGCMarker::CONCURRENT); + ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_init_updaterefs(); } void VM_ShenandoahFinalUpdateRefs::doit() { - ShenandoahGCPauseMark mark(_gc_id, SvcGCMarker::CONCURRENT); + ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_final_updaterefs(); } void VM_ShenandoahFinalRoots::doit() { - ShenandoahGCPauseMark mark(_gc_id, SvcGCMarker::CONCURRENT); + ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT); _gc->entry_final_roots(); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/z/zServiceability.cpp openjdk-17-17.0.8+7/src/hotspot/share/gc/z/zServiceability.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/z/zServiceability.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/z/zServiceability.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -110,9 +110,8 @@ } ZServiceabilityMemoryManager::ZServiceabilityMemoryManager(const char* name, - const char* end_message, ZServiceabilityMemoryPool* pool) : - GCMemoryManager(name, end_message) { + GCMemoryManager(name) { add_pool(pool); } @@ -120,8 +119,8 @@ _min_capacity(min_capacity), _max_capacity(max_capacity), _memory_pool(_min_capacity, _max_capacity), - _cycle_memory_manager("ZGC Cycles", "end of GC cycle", &_memory_pool), - _pause_memory_manager("ZGC Pauses", "end of GC pause", &_memory_pool), + _cycle_memory_manager("ZGC Cycles", &_memory_pool), + _pause_memory_manager("ZGC Pauses", &_memory_pool), _counters(NULL) {} void ZServiceability::initialize() { @@ -147,6 +146,7 @@ ZServiceabilityCycleTracer::ZServiceabilityCycleTracer() : _memory_manager_stats(ZHeap::heap()->serviceability_cycle_memory_manager(), ZCollectedHeap::heap()->gc_cause(), + "end of GC cycle", true /* allMemoryPoolsAffected */, true /* recordGCBeginTime */, true /* recordPreGCUsage */, @@ -161,6 +161,7 @@ _counters_stats(ZHeap::heap()->serviceability_counters()->collector_counters()), _memory_manager_stats(ZHeap::heap()->serviceability_pause_memory_manager(), ZCollectedHeap::heap()->gc_cause(), + "end of GC pause", true /* allMemoryPoolsAffected */, true /* recordGCBeginTime */, false /* recordPreGCUsage */, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/z/zServiceability.hpp openjdk-17-17.0.8+7/src/hotspot/share/gc/z/zServiceability.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/gc/z/zServiceability.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/gc/z/zServiceability.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -44,7 +44,6 @@ class ZServiceabilityMemoryManager : public GCMemoryManager { public: ZServiceabilityMemoryManager(const char* name, - const char* end_message, ZServiceabilityMemoryPool* pool); }; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp openjdk-17-17.0.8+7/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" +#include "jfr/support/jfrThreadLocal.hpp" #include "logging/log.hpp" #include "logging/logConfiguration.hpp" #include "logging/logMessage.hpp" @@ -294,12 +295,10 @@ // we keep them in a thread local arena. The arena is reset between invocations. static THREAD_LOCAL Arena* dcmd_arena = NULL; -static void prepare_dcmd_string_arena() { - if (dcmd_arena == NULL) { - dcmd_arena = new (mtTracing) Arena(mtTracing); - } else { - dcmd_arena->destruct_contents(); // will grow on next allocation - } +static void prepare_dcmd_string_arena(JavaThread* jt) { + dcmd_arena = JfrThreadLocal::dcmd_arena(jt); + assert(dcmd_arena != nullptr, "invariant"); + dcmd_arena->destruct_contents(); // will grow on next allocation } static char* dcmd_arena_allocate(size_t size) { @@ -307,7 +306,7 @@ return (char*)dcmd_arena->Amalloc(size); } -static const char* get_as_dcmd_arena_string(oop string, JavaThread* t) { +static const char* get_as_dcmd_arena_string(oop string) { char* str = NULL; const typeArrayOop value = java_lang_String::value(string); if (value != NULL) { @@ -328,7 +327,7 @@ args.set_receiver(argument); JfrJavaSupport::get_field(&args, THREAD); const oop string_oop = result.get_oop(); - return string_oop != NULL ? get_as_dcmd_arena_string(string_oop, (JavaThread*)THREAD) : NULL; + return string_oop != NULL ? get_as_dcmd_arena_string(string_oop) : NULL; } static bool read_boolean_field(oop argument, const char* field_name, TRAPS) { @@ -377,7 +376,7 @@ assert(arguments->is_array(), "must be array"); const int num_arguments = arguments->length(); assert(num_arguments == _num_arguments, "invariant"); - prepare_dcmd_string_arena(); + prepare_dcmd_string_arena(thread); for (int i = 0; i < num_arguments; ++i) { DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread); assert(dai != NULL, "invariant"); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/metadata/metadata.xml openjdk-17-17.0.8+7/src/hotspot/share/jfr/metadata/metadata.xml --- openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/metadata/metadata.xml 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/jfr/metadata/metadata.xml 2023-07-05 07:11:54.000000000 +0000 @@ -709,7 +709,9 @@ - + @@ -717,14 +719,18 @@ - + - + diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp openjdk-17-17.0.8+7/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -253,6 +253,8 @@ VirtualizationType vrt = VM_Version::get_detected_virtualization(); if (vrt == XenHVM) { return "Xen hardware-assisted virtualization"; + } else if (vrt == XenPVHVM) { + return "Xen optimized paravirtualization"; } else if (vrt == KVM) { return "KVM virtualization"; } else if (vrt == VMWare) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/support/jfrThreadLocal.cpp openjdk-17-17.0.8+7/src/hotspot/share/jfr/support/jfrThreadLocal.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/support/jfrThreadLocal.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/jfr/support/jfrThreadLocal.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -34,6 +34,7 @@ #include "jfr/recorder/storage/jfrStorage.hpp" #include "jfr/support/jfrThreadLocal.hpp" #include "memory/allocation.inline.hpp" +#include "memory/arena.hpp" #include "runtime/os.hpp" #include "runtime/thread.inline.hpp" #include "utilities/sizes.hpp" @@ -46,6 +47,7 @@ _load_barrier_buffer_epoch_0(NULL), _load_barrier_buffer_epoch_1(NULL), _stackframes(NULL), + _dcmd_arena(nullptr), _trace_id(JfrTraceId::assign_thread_id()), _thread(), _data_lost(0), @@ -142,6 +144,10 @@ _load_barrier_buffer_epoch_1->set_retired(); _load_barrier_buffer_epoch_1 = NULL; } + if (_dcmd_arena != nullptr) { + delete _dcmd_arena; + _dcmd_arena = nullptr; + } } void JfrThreadLocal::release(JfrThreadLocal* tl, Thread* t) { @@ -218,3 +224,15 @@ u4 JfrThreadLocal::stackdepth() const { return _stackdepth != 0 ? _stackdepth : (u4)JfrOptionSet::stackdepth(); } + +Arena* JfrThreadLocal::dcmd_arena(JavaThread* jt) { + assert(jt != nullptr, "invariant"); + JfrThreadLocal* tl = jt->jfr_thread_local(); + Arena* arena = tl->_dcmd_arena; + if (arena != nullptr) { + return arena; + } + arena = new (mtTracing) Arena(mtTracing); + tl->_dcmd_arena = arena; + return arena; +} diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/support/jfrThreadLocal.hpp openjdk-17-17.0.8+7/src/hotspot/share/jfr/support/jfrThreadLocal.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/jfr/support/jfrThreadLocal.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/jfr/support/jfrThreadLocal.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -28,6 +28,7 @@ #include "jfr/utilities/jfrBlob.hpp" #include "jfr/utilities/jfrTypes.hpp" +class Arena; class JavaThread; class JfrBuffer; class JfrStackFrame; @@ -42,6 +43,7 @@ JfrBuffer* _load_barrier_buffer_epoch_0; JfrBuffer* _load_barrier_buffer_epoch_1; mutable JfrStackFrame* _stackframes; + Arena* _dcmd_arena; mutable traceid _trace_id; JfrBlobHandle _thread; u8 _data_lost; @@ -219,6 +221,8 @@ return _dead; } + static Arena* dcmd_arena(JavaThread* jt); + bool has_thread_blob() const; void set_thread_blob(const JfrBlobHandle& handle); const JfrBlobHandle& thread_blob() const; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp openjdk-17-17.0.8+7/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1147,7 +1147,9 @@ CodeInstaller::pd_relocate_JavaMethod(buffer, hotspot_method, pc_offset, JVMCI_CHECK); if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) { // Need a static call stub for transitions from compiled to interpreted. - CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset); + if (CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset) == nullptr) { + JVMCI_ERROR("could not emit to_interp stub - code cache is full"); + } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/memory/allocation.cpp openjdk-17-17.0.8+7/src/hotspot/share/memory/allocation.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/memory/allocation.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/memory/allocation.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -49,7 +49,7 @@ char* AllocateHeap(size_t size, MEMFLAGS flags, AllocFailType alloc_failmode /* = AllocFailStrategy::EXIT_OOM*/) { - return AllocateHeap(size, flags, CALLER_PC); + return AllocateHeap(size, flags, CALLER_PC, alloc_failmode); } char* ReallocateHeap(char *old, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/memory/metaspace.cpp openjdk-17-17.0.8+7/src/hotspot/share/memory/metaspace.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/memory/metaspace.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/memory/metaspace.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -590,8 +590,8 @@ #if defined(AARCH64) || defined(PPC64) const size_t alignment = Metaspace::reserve_alignment(); - // AArch64: Try to align metaspace so that we can decode a compressed - // klass with a single MOVK instruction. We can do this iff the + // AArch64: Try to align metaspace class space so that we can decode a + // compressed klass with a single MOVK instruction. We can do this iff the // compressed class base is a multiple of 4G. // Additionally, above 32G, ensure the lower LogKlassAlignmentInBytes bits // of the upper 32-bits of the address are zero so we can handle a shift @@ -614,19 +614,39 @@ { NULL, NULL, 0 } }; + // Calculate a list of all possible values for the starting address for the + // compressed class space. + ResourceMark rm; + GrowableArray
list(36); for (int i = 0; search_ranges[i].from != NULL; i ++) { address a = search_ranges[i].from; assert(CompressedKlassPointers::is_valid_base(a), "Sanity"); while (a < search_ranges[i].to) { - ReservedSpace rs(size, Metaspace::reserve_alignment(), - os::vm_page_size(), (char*)a); - if (rs.is_reserved()) { - assert(a == (address)rs.base(), "Sanity"); - return rs; - } + list.append(a); a += search_ranges[i].increment; } } + + int len = list.length(); + int r = 0; + if (!DumpSharedSpaces) { + // Starting from a random position in the list. If the address cannot be reserved + // (the OS already assigned it for something else), go to the next position, wrapping + // around if necessary, until we exhaust all the items. + os::init_random((int)os::javaTimeNanos()); + r = os::random(); + log_info(metaspace)("Randomizing compressed class space: start from %d out of %d locations", + r % len, len); + } + for (int i = 0; i < len; i++) { + address a = list.at((i + r) % len); + ReservedSpace rs(size, Metaspace::reserve_alignment(), + os::vm_page_size(), (char*)a); + if (rs.is_reserved()) { + assert(a == (address)rs.base(), "Sanity"); + return rs; + } + } #endif // defined(AARCH64) || defined(PPC64) #ifdef AARCH64 diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/oops/instanceKlass.cpp openjdk-17-17.0.8+7/src/hotspot/share/oops/instanceKlass.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/oops/instanceKlass.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/oops/instanceKlass.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1035,18 +1035,18 @@ // If the initialization error is OOM, this might not work, but if GC kicks in // this would be still be helpful. JavaThread* THREAD = current; - Handle cause = java_lang_Throwable::get_cause_with_stack_trace(exception, THREAD); - if (HAS_PENDING_EXCEPTION || cause.is_null()) { - CLEAR_PENDING_EXCEPTION; + Handle init_error = java_lang_Throwable::create_initialization_error(current, exception); + ResourceMark rm(THREAD); + if (init_error.is_null()) { + log_trace(class, init)("Initialization error is null for class %s", external_name()); return; } MutexLocker ml(THREAD, ClassInitError_lock); - OopHandle elem = OopHandle(Universe::vm_global(), cause()); - bool created = false; + OopHandle elem = OopHandle(Universe::vm_global(), init_error()); + bool created; _initialization_error_table.put_if_absent(this, elem, &created); assert(created, "Initialization is single threaded"); - ResourceMark rm(THREAD); log_trace(class, init)("Initialization error added for class %s", external_name()); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/oops/symbol.cpp openjdk-17-17.0.8+7/src/hotspot/share/oops/symbol.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/oops/symbol.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/oops/symbol.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -310,10 +310,8 @@ // this caller. void Symbol::increment_refcount() { if (!try_increment_refcount()) { -#ifdef ASSERT print(); fatal("refcount has gone to zero"); -#endif } #ifndef PRODUCT if (refcount() != PERM_REFCOUNT) { // not a permanent symbol @@ -333,10 +331,8 @@ if (refc == PERM_REFCOUNT) { return; // refcount is permanent, permanent is sticky } else if (refc == 0) { -#ifdef ASSERT print(); fatal("refcount underflow"); -#endif return; } else { found = Atomic::cmpxchg(&_hash_and_refcount, old_value, old_value - 1); @@ -356,10 +352,8 @@ if (refc == PERM_REFCOUNT) { return; // refcount is permanent, permanent is sticky } else if (refc == 0) { -#ifdef ASSERT print(); fatal("refcount underflow"); -#endif return; } else { int hash = extract_hash(old_value); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/block.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/block.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/block.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/block.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1378,7 +1378,13 @@ } } } - assert(is_loop || block->find_node(def) < j, "uses must follow definitions"); + // Uses must be before definition, except if: + // - We are in some kind of loop we already detected + // - We are in infinite loop, where Region may not have been turned into LoopNode + assert(block->find_node(def) < j || + is_loop || + (n->is_Phi() && block->head()->as_Region()->is_in_infinite_subgraph()), + "uses must follow definitions (except in loops)"); } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/c2compiler.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/c2compiler.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/c2compiler.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/c2compiler.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -601,6 +601,7 @@ case vmIntrinsics::_putLongUnaligned: case vmIntrinsics::_loadFence: case vmIntrinsics::_storeFence: + case vmIntrinsics::_storeStoreFence: case vmIntrinsics::_fullFence: case vmIntrinsics::_currentThread: #ifdef JFR_HAVE_INTRINSICS diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/callnode.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/callnode.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/callnode.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/callnode.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1654,6 +1654,7 @@ init_req( KlassNode , klass_node); init_req( InitialTest , initial_test); init_req( ALength , topnode); + init_req( ValidLengthTest , topnode); C->add_macro_node(this); } @@ -1686,54 +1687,6 @@ return mark_node; } -//============================================================================= -Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (remove_dead_region(phase, can_reshape)) return this; - // Don't bother trying to transform a dead node - if (in(0) && in(0)->is_top()) return NULL; - - const Type* type = phase->type(Ideal_length()); - if (type->isa_int() && type->is_int()->_hi < 0) { - if (can_reshape) { - PhaseIterGVN *igvn = phase->is_IterGVN(); - // Unreachable fall through path (negative array length), - // the allocation can only throw so disconnect it. - Node* proj = proj_out_or_null(TypeFunc::Control); - Node* catchproj = NULL; - if (proj != NULL) { - for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) { - Node *cn = proj->fast_out(i); - if (cn->is_Catch()) { - catchproj = cn->as_Multi()->proj_out_or_null(CatchProjNode::fall_through_index); - break; - } - } - } - if (catchproj != NULL && catchproj->outcnt() > 0 && - (catchproj->outcnt() > 1 || - catchproj->unique_out()->Opcode() != Op_Halt)) { - assert(catchproj->is_CatchProj(), "must be a CatchProjNode"); - Node* nproj = catchproj->clone(); - igvn->register_new_node_with_optimizer(nproj); - - Node *frame = new ParmNode( phase->C->start(), TypeFunc::FramePtr ); - frame = phase->transform(frame); - // Halt & Catch Fire - Node* halt = new HaltNode(nproj, frame, "unexpected negative array length"); - phase->C->root()->add_req(halt); - phase->transform(halt); - - igvn->replace_node(catchproj, phase->C->top()); - return this; - } - } else { - // Can't correct it during regular GVN so register for IGVN - phase->C->record_for_igvn(this); - } - } - return NULL; -} - // Retrieve the length from the AllocateArrayNode. Narrow the type with a // CastII, if appropriate. If we are not allowed to create new nodes, and // a CastII is appropriate, return NULL. diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/callnode.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/callnode.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/callnode.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/callnode.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -913,6 +913,7 @@ KlassNode, // type (maybe dynamic) of the obj. InitialTest, // slow-path test (may be constant) ALength, // array length (or TOP if none) + ValidLengthTest, ParmLimit }; @@ -922,6 +923,7 @@ fields[KlassNode] = TypeInstPtr::NOTNULL; fields[InitialTest] = TypeInt::BOOL; fields[ALength] = t; // length (can be a bad length) + fields[ValidLengthTest] = TypeInt::BOOL; const TypeTuple *domain = TypeTuple::make(ParmLimit, fields); @@ -1016,18 +1018,16 @@ // class AllocateArrayNode : public AllocateNode { public: - AllocateArrayNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio, - Node* size, Node* klass_node, Node* initial_test, - Node* count_val - ) + AllocateArrayNode(Compile* C, const TypeFunc* atype, Node* ctrl, Node* mem, Node* abio, Node* size, Node* klass_node, + Node* initial_test, Node* count_val, Node* valid_length_test) : AllocateNode(C, atype, ctrl, mem, abio, size, klass_node, initial_test) { init_class_id(Class_AllocateArray); set_req(AllocateNode::ALength, count_val); + set_req(AllocateNode::ValidLengthTest, valid_length_test); } virtual int Opcode() const; - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); // Dig the length operand out of a array allocation site. Node* Ideal_length() { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/cfgnode.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/cfgnode.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/cfgnode.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/cfgnode.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -39,6 +39,7 @@ #include "opto/narrowptrnode.hpp" #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" +#include "opto/regalloc.hpp" #include "opto/regmask.hpp" #include "opto/runtime.hpp" #include "opto/subnode.hpp" @@ -393,6 +394,47 @@ return true; // The Region node is unreachable - it is dead. } +#ifdef ASSERT +// Is this region in an infinite subgraph? +// (no path to root except through false NeverBranch exit) +bool RegionNode::is_in_infinite_subgraph() { + ResourceMark rm; + Unique_Node_List worklist; + worklist.push(this); + return RegionNode::are_all_nodes_in_infinite_subgraph(worklist); +} + +// Are all nodes in worklist in infinite subgraph? +// (no path to root except through false NeverBranch exit) +// worklist is directly used for the traversal +bool RegionNode::are_all_nodes_in_infinite_subgraph(Unique_Node_List& worklist) { + // BFS traversal down the CFG, except through NeverBranch exits + for (uint i = 0; i < worklist.size(); ++i) { + Node* n = worklist.at(i); + assert(n->is_CFG(), "only traverse CFG"); + if (n->is_Root()) { + // Found root -> there was an exit! + return false; + } else if (n->is_NeverBranch()) { + // Only follow the loop-internal projection, not the NeverBranch exit + ProjNode* proj = n->as_NeverBranch()->proj_out_or_null(0); + assert(proj != nullptr, "must find loop-internal projection of NeverBranch"); + worklist.push(proj); + } else { + // Traverse all CFG outputs + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* use = n->fast_out(i); + if (use->is_CFG()) { + worklist.push(use); + } + } + } + } + // No exit found for any loop -> all are infinite + return true; +} +#endif //ASSERT + bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) { // Incremental inlining + PhaseStringOpts sometimes produce: // @@ -2639,6 +2681,17 @@ // Rethrows always throw exceptions, never return if (call->entry_point() == OptoRuntime::rethrow_stub()) { f[CatchProjNode::fall_through_index] = Type::TOP; + } else if (call->is_AllocateArray()) { + Node* klass_node = call->in(AllocateNode::KlassNode); + Node* length = call->in(AllocateNode::ALength); + const Type* length_type = phase->type(length); + const Type* klass_type = phase->type(klass_node); + Node* valid_length_test = call->in(AllocateNode::ValidLengthTest); + const Type* valid_length_test_t = phase->type(valid_length_test); + if (length_type == Type::TOP || klass_type == Type::TOP || valid_length_test_t == Type::TOP || + valid_length_test_t->is_int()->is_con(0)) { + f[CatchProjNode::fall_through_index] = Type::TOP; + } } else if( call->req() > TypeFunc::Parms ) { const Type *arg0 = phase->type( call->in(TypeFunc::Parms) ); // Check for null receiver to virtual or interface calls @@ -2749,3 +2802,25 @@ st->print("%s", Name()); } #endif + +#ifndef PRODUCT +void BlackholeNode::format(PhaseRegAlloc* ra, outputStream* st) const { + st->print("blackhole "); + bool first = true; + for (uint i = 0; i < req(); i++) { + Node* n = in(i); + if (n != NULL && OptoReg::is_valid(ra->get_reg_first(n))) { + if (first) { + first = false; + } else { + st->print(", "); + } + char buf[128]; + ra->dump_register(n, buf); + st->print("%s", buf); + } + } + st->cr(); +} +#endif + diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/cfgnode.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/cfgnode.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/cfgnode.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/cfgnode.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -47,6 +47,7 @@ class JumpNode; class CatchNode; class NeverBranchNode; +class BlackholeNode; class ProjNode; class CProjNode; class IfTrueNode; @@ -90,6 +91,10 @@ PhiNode* has_unique_phi() const; // returns the unique phi user, or NULL // Is this region node unreachable from root? bool is_unreachable_region(const PhaseGVN* phase); +#ifdef ASSERT + bool is_in_infinite_subgraph(); + static bool are_all_nodes_in_infinite_subgraph(Unique_Node_List& worklist); +#endif //ASSERT virtual int Opcode() const; virtual uint size_of() const { return sizeof(*this); } virtual bool pinned() const { return (const Node*)in(0) == this; } @@ -619,4 +624,28 @@ #endif }; +//------------------------------BlackholeNode---------------------------- +// Blackhole all arguments. This node would survive through the compiler +// the effects on its arguments, and would be finally matched to nothing. +class BlackholeNode : public MultiNode { +public: + BlackholeNode(Node* ctrl) : MultiNode(1) { + init_req(TypeFunc::Control, ctrl); + } + virtual int Opcode() const; + virtual uint ideal_reg() const { return 0; } // not matched in the AD file + virtual const Type* bottom_type() const { return TypeTuple::MEMBAR; } + + const RegMask &in_RegMask(uint idx) const { + // Fake the incoming arguments mask for blackholes: accept all registers + // and all stack slots. This would avoid any redundant register moves + // for blackhole inputs. + return RegMask::All; + } +#ifndef PRODUCT + virtual void format(PhaseRegAlloc* ra, outputStream* st) const; +#endif +}; + + #endif // SHARE_OPTO_CFGNODE_HPP diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/classes.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/classes.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/classes.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/classes.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -219,6 +219,7 @@ macro(MemBarCPUOrder) macro(MemBarRelease) macro(StoreFence) +macro(StoreStoreFence) macro(MemBarReleaseLock) macro(MemBarVolatile) macro(MemBarStoreStore) diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/compile.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/compile.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/compile.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/compile.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -953,6 +953,12 @@ _immutable_memory = NULL; // filled in at first inquiry +#ifdef ASSERT + _type_verify_symmetry = true; + _phase_optimize_finished = false; + _exception_backedge = false; +#endif + // Globally visible Nodes // First set TOP to NULL to give safe behavior during creation of RootNode set_cached_top_node(NULL); @@ -1055,12 +1061,6 @@ Copy::zero_to_bytes(_alias_cache, sizeof(_alias_cache)); // A NULL adr_type hits in the cache right away. Preload the right answer. probe_alias_cache(NULL)->_index = AliasIdxTop; - -#ifdef ASSERT - _type_verify_symmetry = true; - _phase_optimize_finished = false; - _exception_backedge = false; -#endif } //---------------------------init_start---------------------------------------- @@ -2871,7 +2871,7 @@ //------------------------------final_graph_reshaping_impl---------------------- // Implement items 1-5 from final_graph_reshaping below. -void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) { +void Compile::final_graph_reshaping_impl(Node *n, Final_Reshape_Counts& frc, Unique_Node_List& dead_nodes) { if ( n->outcnt() == 0 ) return; // dead node uint nop = n->Opcode(); @@ -2922,9 +2922,9 @@ } #endif // Count FPU ops and common calls, implements item (3) - bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->final_graph_reshaping(this, n, nop); + bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->final_graph_reshaping(this, n, nop, dead_nodes); if (!gc_handled) { - final_graph_reshaping_main_switch(n, frc, nop); + final_graph_reshaping_main_switch(n, frc, nop, dead_nodes); } // Collect CFG split points @@ -2933,7 +2933,7 @@ } } -void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& frc, uint nop) { +void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& frc, uint nop, Unique_Node_List& dead_nodes) { switch( nop ) { // Count all float operations that may use FPU case Op_AddF: @@ -3518,22 +3518,8 @@ // that input may be a chain of Phis. If those phis have no // other use, then the MemBarAcquire keeps them alive and // register allocation can be confused. - ResourceMark rm; - Unique_Node_List wq; - wq.push(n->in(MemBarNode::Precedent)); + dead_nodes.push(n->in(MemBarNode::Precedent)); n->set_req(MemBarNode::Precedent, top()); - while (wq.size() > 0) { - Node* m = wq.pop(); - if (m->outcnt() == 0 && m != top()) { - for (uint j = 0; j < m->req(); j++) { - Node* in = m->in(j); - if (in != NULL) { - wq.push(in); - } - } - m->disconnect_inputs(this); - } - } } break; } @@ -3606,7 +3592,7 @@ //------------------------------final_graph_reshaping_walk--------------------- // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), // requires that the walk visits a node's inputs before visiting the node. -void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ) { +void Compile::final_graph_reshaping_walk(Node_Stack& nstack, Node* root, Final_Reshape_Counts& frc, Unique_Node_List& dead_nodes) { Unique_Node_List sfpt; frc._visited.set(root->_idx); // first, mark node as visited @@ -3632,7 +3618,7 @@ } } else { // Now do post-visit work - final_graph_reshaping_impl( n, frc ); + final_graph_reshaping_impl(n, frc, dead_nodes); if (nstack.is_empty()) break; // finished n = nstack.node(); // Get node from stack @@ -3732,7 +3718,8 @@ // Visit everybody reachable! // Allocate stack of size C->live_nodes()/2 to avoid frequent realloc Node_Stack nstack(live_nodes() >> 1); - final_graph_reshaping_walk(nstack, root(), frc); + Unique_Node_List dead_nodes; + final_graph_reshaping_walk(nstack, root(), frc, dead_nodes); // Check for unreachable (from below) code (i.e., infinite loops). for( uint i = 0; i < frc._tests.size(); i++ ) { @@ -3745,7 +3732,7 @@ // 'fall-thru' path, so expected kids is 1 less. if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { if (n->in(0)->in(0)->is_Call()) { - CallNode *call = n->in(0)->in(0)->as_Call(); + CallNode* call = n->in(0)->in(0)->as_Call(); if (call->entry_point() == OptoRuntime::rethrow_stub()) { required_outcnt--; // Rethrow always has 1 less kid } else if (call->req() > TypeFunc::Parms && @@ -3754,22 +3741,27 @@ // detected that the virtual call will always result in a null // pointer exception. The fall-through projection of this CatchNode // will not be populated. - Node *arg0 = call->in(TypeFunc::Parms); + Node* arg0 = call->in(TypeFunc::Parms); if (arg0->is_Type() && arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { required_outcnt--; } - } else if (call->entry_point() == OptoRuntime::new_array_Java() && - call->req() > TypeFunc::Parms+1 && - call->is_CallStaticJava()) { - // Check for negative array length. In such case, the optimizer has + } else if (call->entry_point() == OptoRuntime::new_array_Java() || + call->entry_point() == OptoRuntime::new_array_nozero_Java()) { + // Check for illegal array length. In such case, the optimizer has // detected that the allocation attempt will always result in an // exception. There is no fall-through projection of this CatchNode . - Node *arg1 = call->in(TypeFunc::Parms+1); - if (arg1->is_Type() && - arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { + assert(call->is_CallStaticJava(), "static call expected"); + assert(call->req() == call->jvms()->endoff() + 1, "missing extra input"); + uint valid_length_test_input = call->req() - 1; + Node* valid_length_test = call->in(valid_length_test_input); + call->del_req(valid_length_test_input); + if (valid_length_test->find_int_con(1) == 0) { required_outcnt--; } + dead_nodes.push(valid_length_test); + assert(n->outcnt() == required_outcnt, "malformed control flow"); + continue; } } } @@ -3778,6 +3770,16 @@ record_method_not_compilable("malformed control flow"); return true; // Not all targets reachable! } + } else if (n->is_PCTable() && n->in(0) && n->in(0)->in(0) && n->in(0)->in(0)->is_Call()) { + CallNode* call = n->in(0)->in(0)->as_Call(); + if (call->entry_point() == OptoRuntime::new_array_Java() || + call->entry_point() == OptoRuntime::new_array_nozero_Java()) { + assert(call->is_CallStaticJava(), "static call expected"); + assert(call->req() == call->jvms()->endoff() + 1, "missing extra input"); + uint valid_length_test_input = call->req() - 1; + dead_nodes.push(call->in(valid_length_test_input)); + call->del_req(valid_length_test_input); // valid length test useless now + } } // Check that I actually visited all kids. Unreached kids // must be infinite loops. @@ -3796,6 +3798,19 @@ } } + while (dead_nodes.size() > 0) { + Node* m = dead_nodes.pop(); + if (m->outcnt() == 0 && m != top()) { + for (uint j = 0; j < m->req(); j++) { + Node* in = m->in(j); + if (in != NULL) { + dead_nodes.push(in); + } + } + m->disconnect_inputs(this); + } + } + #ifdef IA32 // If original bytecodes contained a mixture of floats and doubles // check if the optimizer has made it homogenous, item (3). diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/compile.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/compile.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/compile.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/compile.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -921,7 +921,8 @@ // Parsing, optimization PhaseGVN* initial_gvn() { return _initial_gvn; } Unique_Node_List* for_igvn() { return _for_igvn; } - inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List. + inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp. + inline void remove_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp. void set_initial_gvn(PhaseGVN *gvn) { _initial_gvn = gvn; } void set_for_igvn(Unique_Node_List *for_igvn) { _for_igvn = for_igvn; } @@ -1113,9 +1114,9 @@ #endif // Function calls made by the public function final_graph_reshaping. // No need to be made public as they are not called elsewhere. - void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc); - void final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& frc, uint nop); - void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ); + void final_graph_reshaping_impl(Node *n, Final_Reshape_Counts& frc, Unique_Node_List& dead_nodes); + void final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& frc, uint nop, Unique_Node_List& dead_nodes); + void final_graph_reshaping_walk(Node_Stack& nstack, Node* root, Final_Reshape_Counts& frc, Unique_Node_List& dead_nodes); void eliminate_redundant_card_marks(Node* n); // Logic cone optimization. diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/graphKit.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/graphKit.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/graphKit.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/graphKit.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -738,6 +738,29 @@ return clonemap; } +//-----------------------------destruct_map_clone------------------------------ +// +// Order of destruct is important to increase the likelyhood that memory can be re-used. We need +// to destruct/free/delete in the exact opposite order as clone_map(). +void GraphKit::destruct_map_clone(SafePointNode* sfp) { + if (sfp == nullptr) return; + + Node* mem = sfp->memory(); + JVMState* jvms = sfp->jvms(); + + if (jvms != nullptr) { + delete jvms; + } + + remove_for_igvn(sfp); + gvn().clear_type(sfp); + sfp->destruct(&_gvn); + + if (mem != nullptr) { + gvn().clear_type(mem); + mem->destruct(&_gvn); + } +} //-----------------------------set_map_clone----------------------------------- void GraphKit::set_map_clone(SafePointNode* m) { @@ -2730,7 +2753,9 @@ // Make a catch node with just two handlers: fall-through and catch-all Node* i_o = _gvn.transform( new ProjNode(call, TypeFunc::I_O, separate_io_proj) ); Node* catc = _gvn.transform( new CatchNode(control(), i_o, 2) ); - Node* norm = _gvn.transform( new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) ); + Node* norm = new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci); + _gvn.set_type_bottom(norm); + C->record_for_igvn(norm); Node* excp = _gvn.transform( new CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) ); { PreserveJVMState pjvms(this); @@ -3969,20 +3994,28 @@ initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); } + const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type(); + Node* valid_length_test = _gvn.intcon(1); + if (ary_type->isa_aryptr()) { + BasicType bt = ary_type->isa_aryptr()->elem()->array_element_basic_type(); + jint max = TypeAryPtr::max_array_length(bt); + Node* valid_length_cmp = _gvn.transform(new CmpUNode(length, intcon(max))); + valid_length_test = _gvn.transform(new BoolNode(valid_length_cmp, BoolTest::le)); + } + // Create the AllocateArrayNode and its result projections AllocateArrayNode* alloc = new AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT), control(), mem, i_o(), size, klass_node, initial_slow_test, - length); + length, valid_length_test); // Cast to correct type. Note that the klass_node may be constant or not, // and in the latter case the actual array type will be inexact also. // (This happens via a non-constant argument to inline_native_newArray.) // In any case, the value of klass_node provides the desired array type. const TypeInt* length_type = _gvn.find_int_type(length); - const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type(); if (ary_type->isa_aryptr() && length_type != NULL) { // Try to get a better type than POS for the size ary_type = ary_type->is_aryptr()->cast_to_size(length_type); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/graphKit.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/graphKit.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/graphKit.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/graphKit.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -94,6 +94,7 @@ void* barrier_set_state() const { return C->barrier_set_state(); } void record_for_igvn(Node* n) const { C->record_for_igvn(n); } // delegate to Compile + void remove_for_igvn(Node* n) const { C->remove_for_igvn(n); } // Handy well-known nodes: Node* null() const { return zerocon(T_OBJECT); } @@ -170,6 +171,11 @@ // Clone the existing map state. (Implements PreserveJVMState.) SafePointNode* clone_map(); + // Reverses the work done by clone_map(). Should only be used when the node returned by + // clone_map() is ultimately not used. Calling Node::destruct directly in the previously + // mentioned circumstance instead of this method may result in use-after-free. + void destruct_map_clone(SafePointNode* sfp); + // Set the map to a clone of the given one. void set_map_clone(SafePointNode* m); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/library_call.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/library_call.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/library_call.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/library_call.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -466,6 +466,7 @@ case vmIntrinsics::_loadFence: case vmIntrinsics::_storeFence: + case vmIntrinsics::_storeStoreFence: case vmIntrinsics::_fullFence: return inline_unsafe_fence(intrinsic_id()); case vmIntrinsics::_onSpinWait: return inline_onspinwait(); @@ -1219,7 +1220,7 @@ } assert(callee()->signature()->size() == 4, "String.indexOfChar() has 4 arguments"); Node* src = argument(0); // byte[] - Node* tgt = argument(1); // tgt is int ch + Node* int_ch = argument(1); Node* from_index = argument(2); Node* max = argument(3); @@ -1231,6 +1232,15 @@ // Range checks generate_string_range_check(src, src_offset, src_count, ae == StrIntrinsicNode::U); + + // Check for int_ch >= 0 + Node* int_ch_cmp = _gvn.transform(new CmpINode(int_ch, intcon(0))); + Node* int_ch_bol = _gvn.transform(new BoolNode(int_ch_cmp, BoolTest::ge)); + { + BuildCutout unless(this, int_ch_bol, PROB_MAX); + uncommon_trap(Deoptimization::Reason_intrinsic, + Deoptimization::Action_maybe_recompile); + } if (stopped()) { return true; } @@ -1238,7 +1248,7 @@ RegionNode* region = new RegionNode(3); Node* phi = new PhiNode(region, TypeInt::INT); - Node* result = new StrIndexOfCharNode(control(), memory(TypeAryPtr::BYTES), src_start, src_count, tgt, ae); + Node* result = new StrIndexOfCharNode(control(), memory(TypeAryPtr::BYTES), src_start, src_count, int_ch, ae); C->set_has_split_ifs(true); // Has chance for split-if optimization _gvn.transform(result); @@ -1287,10 +1297,13 @@ AllocateArrayNode* alloc = tightly_coupled_allocation(dst); // Figure out the size and type of the elements we will be copying. - const Type* src_type = src->Value(&_gvn); - const Type* dst_type = dst->Value(&_gvn); - BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + const TypeAryPtr* src_type = src->Value(&_gvn)->isa_aryptr(); + const TypeAryPtr* dst_type = dst->Value(&_gvn)->isa_aryptr(); + if (src_type == nullptr || dst_type == nullptr) { + return false; + } + BasicType src_elem = src_type->klass()->as_array_klass()->element_type()->basic_type(); + BasicType dst_elem = dst_type->klass()->as_array_klass()->element_type()->basic_type(); assert((compress && dst_elem == T_BYTE && (src_elem == T_BYTE || src_elem == T_CHAR)) || (!compress && src_elem == T_BYTE && (dst_elem == T_BYTE || dst_elem == T_CHAR)), "Unsupported array types for inline_string_copy"); @@ -1563,7 +1576,7 @@ set_sp(old_sp); return false; } - old_map->destruct(&_gvn); + destruct_map_clone(old_map); if (is_store) { access_store_at(value, adr, TypeAryPtr::BYTES, ch, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED); } else { @@ -2346,7 +2359,7 @@ mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched } - old_map->destruct(&_gvn); + destruct_map_clone(old_map); assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched"); if (mismatched) { @@ -2597,7 +2610,7 @@ return false; } - old_map->destruct(&_gvn); + destruct_map_clone(old_map); // For CAS, unlike inline_unsafe_access, there seems no point in // trying to refine types. Just use the coarse types here. @@ -2690,6 +2703,9 @@ case vmIntrinsics::_storeFence: insert_mem_bar(Op_StoreFence); return true; + case vmIntrinsics::_storeStoreFence: + insert_mem_bar(Op_StoreStoreFence); + return true; case vmIntrinsics::_fullFence: insert_mem_bar(Op_MemBarVolatile); return true; @@ -4395,24 +4411,7 @@ } if (no_interfering_store) { - JVMState* old_jvms = alloc->jvms()->clone_shallow(C); - uint size = alloc->req(); - SafePointNode* sfpt = new SafePointNode(size, old_jvms); - old_jvms->set_map(sfpt); - for (uint i = 0; i < size; i++) { - sfpt->init_req(i, alloc->in(i)); - } - // re-push array length for deoptimization - sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength)); - old_jvms->set_sp(old_jvms->sp()+1); - old_jvms->set_monoff(old_jvms->monoff()+1); - old_jvms->set_scloff(old_jvms->scloff()+1); - old_jvms->set_endoff(old_jvms->endoff()+1); - old_jvms->set_should_reexecute(true); - - sfpt->set_i_o(map()->i_o()); - sfpt->set_memory(map()->memory()); - sfpt->set_control(map()->control()); + SafePointNode* sfpt = create_safepoint_with_state_before_array_allocation(alloc); JVMState* saved_jvms = jvms(); saved_reexecute_sp = _reexecute_sp; @@ -4427,6 +4426,30 @@ return NULL; } +// Clone the JVMState of the array allocation and create a new safepoint with it. Re-push the array length to the stack +// such that uncommon traps can be emitted to re-execute the array allocation in the interpreter. +SafePointNode* LibraryCallKit::create_safepoint_with_state_before_array_allocation(const AllocateArrayNode* alloc) const { + JVMState* old_jvms = alloc->jvms()->clone_shallow(C); + uint size = alloc->req(); + SafePointNode* sfpt = new SafePointNode(size, old_jvms); + old_jvms->set_map(sfpt); + for (uint i = 0; i < size; i++) { + sfpt->init_req(i, alloc->in(i)); + } + // re-push array length for deoptimization + sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength)); + old_jvms->set_sp(old_jvms->sp()+1); + old_jvms->set_monoff(old_jvms->monoff()+1); + old_jvms->set_scloff(old_jvms->scloff()+1); + old_jvms->set_endoff(old_jvms->endoff()+1); + old_jvms->set_should_reexecute(true); + + sfpt->set_i_o(map()->i_o()); + sfpt->set_memory(map()->memory()); + sfpt->set_control(map()->control()); + return sfpt; +} + // In case of a deoptimization, we restart execution at the // allocation, allocating a new array. We would leave an uninitialized // array in the heap that GCs wouldn't expect. Move the allocation @@ -4434,18 +4457,20 @@ // deoptimize. This is possible because tightly_coupled_allocation() // guarantees there's no observer of the allocated array at this point // and the control flow is simple enough. -void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms, +void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms_before_guards, int saved_reexecute_sp, uint new_idx) { - if (saved_jvms != NULL && !stopped()) { + if (saved_jvms_before_guards != NULL && !stopped()) { + replace_unrelated_uncommon_traps_with_alloc_state(alloc, saved_jvms_before_guards); + assert(alloc != NULL, "only with a tightly coupled allocation"); // restore JVM state to the state at the arraycopy - saved_jvms->map()->set_control(map()->control()); - assert(saved_jvms->map()->memory() == map()->memory(), "memory state changed?"); - assert(saved_jvms->map()->i_o() == map()->i_o(), "IO state changed?"); + saved_jvms_before_guards->map()->set_control(map()->control()); + assert(saved_jvms_before_guards->map()->memory() == map()->memory(), "memory state changed?"); + assert(saved_jvms_before_guards->map()->i_o() == map()->i_o(), "IO state changed?"); // If we've improved the types of some nodes (null check) while // emitting the guards, propagate them to the current state - map()->replaced_nodes().apply(saved_jvms->map(), new_idx); - set_jvms(saved_jvms); + map()->replaced_nodes().apply(saved_jvms_before_guards->map(), new_idx); + set_jvms(saved_jvms_before_guards); _reexecute_sp = saved_reexecute_sp; // Remove the allocation from above the guards @@ -4521,6 +4546,58 @@ } } +// Unrelated UCTs between the array allocation and the array copy, which are considered safe by tightly_coupled_allocation(), +// need to be replaced by an UCT with a state before the array allocation (including the array length). This is necessary +// because we could hit one of these UCTs (which are executed before the emitted array copy guards and the actual array +// allocation which is moved down in arraycopy_move_allocation_here()). When later resuming execution in the interpreter, +// we would have wrongly skipped the array allocation. To prevent this, we resume execution at the array allocation in +// the interpreter similar to what we are doing for the newly emitted guards for the array copy. +void LibraryCallKit::replace_unrelated_uncommon_traps_with_alloc_state(AllocateArrayNode* alloc, + JVMState* saved_jvms_before_guards) { + if (saved_jvms_before_guards->map()->control()->is_IfProj()) { + // There is at least one unrelated uncommon trap which needs to be replaced. + SafePointNode* sfpt = create_safepoint_with_state_before_array_allocation(alloc); + + JVMState* saved_jvms = jvms(); + const int saved_reexecute_sp = _reexecute_sp; + set_jvms(sfpt->jvms()); + _reexecute_sp = jvms()->sp(); + + replace_unrelated_uncommon_traps_with_alloc_state(saved_jvms_before_guards); + + // Restore state + set_jvms(saved_jvms); + _reexecute_sp = saved_reexecute_sp; + } +} + +// Replace the unrelated uncommon traps with new uncommon trap nodes by reusing the action and reason. The new uncommon +// traps will have the state of the array allocation. Let the old uncommon trap nodes die. +void LibraryCallKit::replace_unrelated_uncommon_traps_with_alloc_state(JVMState* saved_jvms_before_guards) { + Node* if_proj = saved_jvms_before_guards->map()->control(); // Start the search right before the newly emitted guards + while (if_proj->is_IfProj()) { + CallStaticJavaNode* uncommon_trap = get_uncommon_trap_from_success_proj(if_proj); + if (uncommon_trap != nullptr) { + create_new_uncommon_trap(uncommon_trap); + } + assert(if_proj->in(0)->is_If(), "must be If"); + if_proj = if_proj->in(0)->in(0); + } + assert(if_proj->is_Proj() && if_proj->in(0)->is_Initialize(), + "must have reached control projection of init node"); +} + +void LibraryCallKit::create_new_uncommon_trap(CallStaticJavaNode* uncommon_trap_call) { + const int trap_request = uncommon_trap_call->uncommon_trap_request(); + assert(trap_request != 0, "no valid UCT trap request"); + PreserveJVMState pjvms(this); + set_control(uncommon_trap_call->in(0)); + uncommon_trap(Deoptimization::trap_request_reason(trap_request), + Deoptimization::trap_request_action(trap_request)); + assert(stopped(), "Should be stopped"); + _gvn.hash_delete(uncommon_trap_call); + uncommon_trap_call->set_req(0, top()); // not used anymore, kill it +} //------------------------------inline_arraycopy----------------------- // public static native void java.lang.System.arraycopy(Object src, int srcPos, @@ -4541,12 +4618,12 @@ AllocateArrayNode* alloc = tightly_coupled_allocation(dest); int saved_reexecute_sp = -1; - JVMState* saved_jvms = arraycopy_restore_alloc_state(alloc, saved_reexecute_sp); + JVMState* saved_jvms_before_guards = arraycopy_restore_alloc_state(alloc, saved_reexecute_sp); // See arraycopy_restore_alloc_state() comment // if alloc == NULL we don't have to worry about a tightly coupled allocation so we can emit all needed guards - // if saved_jvms != NULL (then alloc != NULL) then we can handle guards and a tightly coupled allocation - // if saved_jvms == NULL and alloc != NULL, we can't emit any guards - bool can_emit_guards = (alloc == NULL || saved_jvms != NULL); + // if saved_jvms_before_guards != NULL (then alloc != NULL) then we can handle guards and a tightly coupled allocation + // if saved_jvms_before_guards == NULL and alloc != NULL, we can't emit any guards + bool can_emit_guards = (alloc == NULL || saved_jvms_before_guards != NULL); // The following tests must be performed // (1) src and dest are arrays. @@ -4562,12 +4639,12 @@ // (3) src and dest must not be null. // always do this here because we need the JVM state for uncommon traps Node* null_ctl = top(); - src = saved_jvms != NULL ? null_check_oop(src, &null_ctl, true, true) : null_check(src, T_ARRAY); + src = saved_jvms_before_guards != NULL ? null_check_oop(src, &null_ctl, true, true) : null_check(src, T_ARRAY); assert(null_ctl->is_top(), "no null control here"); dest = null_check(dest, T_ARRAY); if (!can_emit_guards) { - // if saved_jvms == NULL and alloc != NULL, we don't emit any + // if saved_jvms_before_guards == NULL and alloc != NULL, we don't emit any // guards but the arraycopy node could still take advantage of a // tightly allocated allocation. tightly_coupled_allocation() is // called again to make sure it takes the null check above into @@ -4681,7 +4758,7 @@ ciMethod* trap_method = method(); int trap_bci = bci(); - if (saved_jvms != NULL) { + if (saved_jvms_before_guards != NULL) { trap_method = alloc->jvms()->method(); trap_bci = alloc->jvms()->bci(); } @@ -4753,10 +4830,9 @@ const TypeKlassPtr* dest_klass_t = _gvn.type(dest_klass)->is_klassptr(); const Type *toop = TypeOopPtr::make_from_klass(dest_klass_t->klass()); src = _gvn.transform(new CheckCastPPNode(control(), src, toop)); + arraycopy_move_allocation_here(alloc, dest, saved_jvms_before_guards, saved_reexecute_sp, new_idx); } - arraycopy_move_allocation_here(alloc, dest, saved_jvms, saved_reexecute_sp, new_idx); - if (stopped()) { return true; } @@ -4821,28 +4897,15 @@ // There may be guards which feed into the slow_region. // Any other control flow means that we might not get a chance // to finish initializing the allocated object. - if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) { - IfNode* iff = ctl->in(0)->as_If(); - Node* not_ctl = iff->proj_out_or_null(1 - ctl->as_Proj()->_con); - assert(not_ctl != NULL && not_ctl != ctl, "found alternate"); - // One more try: Various low-level checks bottom out in - // uncommon traps. If the debug-info of the trap omits - // any reference to the allocation, as we've already - // observed, then there can be no objection to the trap. - bool found_trap = false; - for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) { - Node* obs = not_ctl->fast_out(j); - if (obs->in(0) == not_ctl && obs->is_Call() && - (obs->as_Call()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point())) { - found_trap = true; break; - } - } - if (found_trap) { - ctl = iff->in(0); // This test feeds a harmless uncommon trap. - continue; - } + // Various low-level checks bottom out in uncommon traps. These + // are considered safe since we've already checked above that + // there is no unexpected observer of this allocation. + if (get_uncommon_trap_from_success_proj(ctl) != nullptr) { + assert(ctl->in(0)->is_If(), "must be If"); + ctl = ctl->in(0)->in(0); + } else { + return nullptr; } - return NULL; } // If we get this far, we have an allocation which immediately @@ -4853,6 +4916,20 @@ return alloc; } +CallStaticJavaNode* LibraryCallKit::get_uncommon_trap_from_success_proj(Node* node) { + if (node->is_IfProj()) { + Node* other_proj = node->as_IfProj()->other_if_proj(); + for (DUIterator_Fast jmax, j = other_proj->fast_outs(jmax); j < jmax; j++) { + Node* obs = other_proj->fast_out(j); + if (obs->in(0) == other_proj && obs->is_CallStaticJava() && + (obs->as_CallStaticJava()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point())) { + return obs->as_CallStaticJava(); + } + } + } + return nullptr; +} + //-------------inline_encodeISOArray----------------------------------- // encode char[] to byte[] in ISO_8859_1 or ASCII bool LibraryCallKit::inline_encodeISOArray(bool ascii) { @@ -4878,8 +4955,8 @@ } // Figure out the size and type of the elements we will be copying. - BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); + BasicType dst_elem = top_dest->klass()->as_array_klass()->element_type()->basic_type(); if (!((src_elem == T_CHAR) || (src_elem== T_BYTE)) || dst_elem != T_BYTE) { return false; } @@ -4932,8 +5009,8 @@ return false; } - BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType x_elem = top_x->klass()->as_array_klass()->element_type()->basic_type(); + BasicType y_elem = top_y->klass()->as_array_klass()->element_type()->basic_type(); if (x_elem != T_INT || y_elem != T_INT) { return false; } @@ -5040,8 +5117,8 @@ return false; } - BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType z_elem = z_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType x_elem = top_x->klass()->as_array_klass()->element_type()->basic_type(); + BasicType z_elem = top_z->klass()->as_array_klass()->element_type()->basic_type(); if (x_elem != T_INT || z_elem != T_INT) { return false; } @@ -5089,8 +5166,8 @@ return false; } - BasicType out_elem = out_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType in_elem = in_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType out_elem = top_out->klass()->as_array_klass()->element_type()->basic_type(); + BasicType in_elem = top_in->klass()->as_array_klass()->element_type()->basic_type(); if (out_elem != T_INT || in_elem != T_INT) { return false; } @@ -5144,10 +5221,10 @@ return false; } - BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType b_elem = b_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType a_elem = top_a->klass()->as_array_klass()->element_type()->basic_type(); + BasicType b_elem = top_b->klass()->as_array_klass()->element_type()->basic_type(); + BasicType n_elem = top_n->klass()->as_array_klass()->element_type()->basic_type(); + BasicType m_elem = top_m->klass()->as_array_klass()->element_type()->basic_type(); if (a_elem != T_INT || b_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { return false; } @@ -5200,9 +5277,9 @@ return false; } - BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType a_elem = top_a->klass()->as_array_klass()->element_type()->basic_type(); + BasicType n_elem = top_n->klass()->as_array_klass()->element_type()->basic_type(); + BasicType m_elem = top_m->klass()->as_array_klass()->element_type()->basic_type(); if (a_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { return false; } @@ -5252,8 +5329,8 @@ return false; } - BasicType newArr_elem = newArr_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); - BasicType oldArr_elem = oldArr_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType newArr_elem = top_newArr->klass()->as_array_klass()->element_type()->basic_type(); + BasicType oldArr_elem = top_oldArr->klass()->as_array_klass()->element_type()->basic_type(); if (newArr_elem != T_INT || oldArr_elem != T_INT) { return false; } @@ -5466,7 +5543,7 @@ } // Figure out the size and type of the elements we will be copying. - BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); if (src_elem != T_BYTE) { return false; } @@ -5555,7 +5632,7 @@ } // Figure out the size and type of the elements we will be copying. - BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); if (src_elem != T_BYTE) { return false; } @@ -5648,7 +5725,7 @@ } // Figure out the size and type of the elements we will be copying. - BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); if (src_elem != T_BYTE) { return false; } @@ -6485,7 +6562,7 @@ return false; } // Figure out the size and type of the elements we will be copying. - BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); if (src_elem != T_BYTE) { return false; } @@ -6577,7 +6654,7 @@ return false; } // Figure out the size and type of the elements we will be copying. - BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); if (src_elem != T_BYTE) { return false; } @@ -7109,8 +7186,15 @@ assert(callee()->is_empty(), "Should have been checked before: only empty methods here"); assert(callee()->holder()->is_loaded(), "Should have been checked before: only methods for loaded classes here"); + // Blackhole node pinches only the control, not memory. This allows + // the blackhole to be pinned in the loop that computes blackholed + // values, but have no other side effects, like breaking the optimizations + // across the blackhole. + + Node* bh = _gvn.transform(new BlackholeNode(control())); + set_control(_gvn.transform(new ProjNode(bh, TypeFunc::Control))); + // Bind call arguments as blackhole arguments to keep them alive - Node* bh = insert_mem_bar(Op_Blackhole); uint nargs = callee()->arg_size(); for (uint i = 0; i < nargs; i++) { bh->add_req(argument(i)); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/library_call.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/library_call.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/library_call.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/library_call.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -253,8 +253,13 @@ // Helper functions for inlining arraycopy bool inline_arraycopy(); AllocateArrayNode* tightly_coupled_allocation(Node* ptr); + static CallStaticJavaNode* get_uncommon_trap_from_success_proj(Node* node); + SafePointNode* create_safepoint_with_state_before_array_allocation(const AllocateArrayNode* alloc) const; + void replace_unrelated_uncommon_traps_with_alloc_state(AllocateArrayNode* alloc, JVMState* saved_jvms_before_guards); + void replace_unrelated_uncommon_traps_with_alloc_state(JVMState* saved_jvms_before_guards); + void create_new_uncommon_trap(CallStaticJavaNode* uncommon_trap_call); JVMState* arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp); - void arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms, int saved_reexecute_sp, + void arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms_before_guards, int saved_reexecute_sp, uint new_idx); typedef enum { LS_get_add, LS_get_set, LS_cmp_swap, LS_cmp_swap_weak, LS_cmp_exchange } LoadStoreKind; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopnode.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/loopnode.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopnode.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/loopnode.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -3123,6 +3123,17 @@ // Skip to head of inner loop assert(_phase->is_dominator(_head, nlpt->_head), "inner head dominated by outer head"); n = nlpt->_head; + if (_head == n) { + // this and nlpt (inner loop) have the same loop head. This should not happen because + // during beautify_loops we call merge_many_backedges. However, infinite loops may not + // have been attached to the loop-tree during build_loop_tree before beautify_loops, + // but then attached in the build_loop_tree afterwards, and so still have unmerged + // backedges. Check if we are indeed in an infinite subgraph, and terminate the scan, + // since we have reached the loop head of this. + assert(_head->as_Region()->is_in_infinite_subgraph(), + "only expect unmerged backedges in infinite loops"); + break; + } } } } @@ -3704,30 +3715,7 @@ assert(head->is_Region(), ""); worklist.push(head); } - // BFS traversal down the CFG, except through NeverBranch exits - for (uint i = 0; i < worklist.size(); ++i) { - Node* n = worklist.at(i); - assert(n->is_CFG(), "only traverse CFG"); - if (n->is_Root()) { - // Found root -> there was an exit! - return false; - } else if (n->is_NeverBranch()) { - // Only follow the loop-internal projection, not the NeverBranch exit - ProjNode* proj = n->as_NeverBranch()->proj_out_or_null(0); - assert(proj != nullptr, "must find loop-internal projection of NeverBranch"); - worklist.push(proj); - } else { - // Traverse all CFG outputs - for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { - Node* use = n->fast_out(i); - if (use->is_CFG()) { - worklist.push(use); - } - } - } - } - // No exit found for any loop -> all are infinite - return true; + return RegionNode::are_all_nodes_in_infinite_subgraph(worklist); } #endif diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopnode.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/loopnode.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopnode.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/loopnode.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1506,6 +1506,9 @@ void try_move_store_after_loop(Node* n); bool identical_backtoback_ifs(Node *n); bool can_split_if(Node *n_ctrl); + bool cannot_split_division(const Node* n, const Node* region) const; + static bool is_divisor_counted_loop_phi(const Node* divisor, const Node* loop); + bool loop_phi_backedge_type_contains_zero(const Node* phi_divisor, const Type* zero) const; // Determine if a method is too big for a/another round of split-if, based on // a magic (approximate) ratio derived from the equally magic constant 35000, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopopts.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/loopopts.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopopts.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/loopopts.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, 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 @@ -61,19 +61,8 @@ return NULL; } - // Bail out if 'n' is a Div or Mod node whose zero check was removed earlier (i.e. control is NULL) and its divisor is an induction variable - // phi p of a trip-counted (integer) loop whose inputs could be zero (include zero in their type range). p could have a more precise type - // range that does not necessarily include all values of its inputs. Since each of these inputs will be a divisor of the newly cloned nodes - // of 'n', we need to bail out of one of these divisors could be zero (zero in its type range). - if ((n->Opcode() == Op_DivI || n->Opcode() == Op_ModI) && n->in(0) == NULL - && region->is_CountedLoop() && n->in(2) == region->as_CountedLoop()->phi()) { - Node* phi = region->as_CountedLoop()->phi(); - for (uint i = 1; i < phi->req(); i++) { - if (_igvn.type(phi->in(i))->filter_speculative(TypeInt::ZERO) != Type::TOP) { - // Zero could be a possible value but we already removed the zero check. Bail out to avoid a possible division by zero at a later point. - return NULL; - } - } + if (cannot_split_division(n, region)) { + return NULL; } int wins = 0; @@ -225,6 +214,42 @@ return phi; } +// Return true if 'n' is a Div or Mod node (without zero check If node which was removed earlier) with a loop phi divisor +// of a trip-counted (integer or long) loop with a backedge input that could be zero (include zero in its type range). In +// this case, we cannot split the division to the backedge as it could freely float above the loop exit check resulting in +// a division by zero. This situation is possible because the type of an increment node of an iv phi (trip-counter) could +// include zero while the iv phi does not (see PhiNode::Value() for trip-counted loops where we improve types of iv phis). +// We also need to check other loop phis as they could have been created in the same split-if pass when applying +// PhaseIdealLoop::split_thru_phi() to split nodes through an iv phi. +bool PhaseIdealLoop::cannot_split_division(const Node* n, const Node* region) const { + const Type* zero; + switch (n->Opcode()) { + case Op_DivI: + case Op_ModI: + zero = TypeInt::ZERO; + break; + case Op_DivL: + case Op_ModL: + zero = TypeLong::ZERO; + break; + default: + return false; + } + + assert(n->in(0) == NULL, "divisions with zero check should already have bailed out earlier in split-if"); + Node* divisor = n->in(2); + return is_divisor_counted_loop_phi(divisor, region) && + loop_phi_backedge_type_contains_zero(divisor, zero); +} + +bool PhaseIdealLoop::is_divisor_counted_loop_phi(const Node* divisor, const Node* loop) { + return loop->is_BaseCountedLoop() && divisor->is_Phi() && divisor->in(0) == loop; +} + +bool PhaseIdealLoop::loop_phi_backedge_type_contains_zero(const Node* phi_divisor, const Type* zero) const { + return _igvn.type(phi_divisor->in(LoopNode::LoopBackControl))->filter_speculative(zero) != Type::TOP; +} + //------------------------------dominated_by------------------------------------ // Replace the dominated test with an obvious true or false. Place it on the // IGVN worklist for later cleanup. Move control-dependent data Nodes on the @@ -484,7 +509,7 @@ n23_loop == n_loop ) { Node *add1 = new AddPNode( n->in(1), n->in(2)->in(2), n->in(3) ); // Stuff new AddP in the loop preheader - register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) ); + register_new_node( add1, n_loop->_head->as_Loop()->skip_strip_mined(1)->in(LoopNode::EntryControl) ); Node *add2 = new AddPNode( n->in(1), add1, n->in(2)->in(3) ); register_new_node( add2, n_ctrl ); _igvn.replace_node( n, add2 ); @@ -505,7 +530,7 @@ if (!is_member(n_loop,get_ctrl(I))) { Node *add1 = new AddPNode(n->in(1), n->in(2), I); // Stuff new AddP in the loop preheader - register_new_node(add1, n_loop->_head->in(LoopNode::EntryControl)); + register_new_node(add1, n_loop->_head->as_Loop()->skip_strip_mined(1)->in(LoopNode::EntryControl)); Node *add2 = new AddPNode(n->in(1), add1, V); register_new_node(add2, n_ctrl); _igvn.replace_node(n, add2); @@ -1309,8 +1334,8 @@ return; // Compare must be in same blk as if } } else if (iff->is_CMove()) { // Trying to split-up a CMOVE - // Can't split CMove with different control edge. - if (iff->in(0) != NULL && iff->in(0) != n_ctrl ) { + // Can't split CMove with different control. + if (get_ctrl(iff) != n_ctrl) { return; } if (get_ctrl(iff->in(2)) == n_ctrl || @@ -1928,7 +1953,13 @@ // in the loop to break the loop, then test is again outside of the // loop to determine which way the loop exited. // Loop predicate If node connects to Bool node through Opaque1 node. - if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use) || use->Opcode() == Op_Opaque4) { + // + // If the use is an AllocateArray through its ValidLengthTest input, + // make sure the Bool/Cmp input is cloned down to avoid a Phi between + // the AllocateArray node and its ValidLengthTest input that could cause + // split if to break. + if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use) || use->Opcode() == Op_Opaque4 || + (use->Opcode() == Op_AllocateArray && use->in(AllocateNode::ValidLengthTest) == old)) { // Since this code is highly unlikely, we lazily build the worklist // of such Nodes to go split. if (!split_if_set) { @@ -2442,9 +2473,10 @@ if (split_if_set) { while (split_if_set->size()) { Node *iff = split_if_set->pop(); - if (iff->in(1)->is_Phi()) { - Node *b = clone_iff(iff->in(1)->as_Phi(), loop); - _igvn.replace_input_of(iff, 1, b); + uint input = iff->Opcode() == Op_AllocateArray ? AllocateNode::ValidLengthTest : 1; + if (iff->in(input)->is_Phi()) { + Node *b = clone_iff(iff->in(input)->as_Phi(), loop); + _igvn.replace_input_of(iff, input, b); } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopPredicate.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/loopPredicate.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopPredicate.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/loopPredicate.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1343,11 +1343,13 @@ upper_bound_iff->set_req(1, upper_bound_bol); if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negate ? " negated" : "", lower_bound_iff->_idx); - // Fall through into rest of the cleanup code which will move any dependent nodes to the skeleton predicates of the - // upper bound test. We always need to create skeleton predicates in order to properly remove dead loops when later - // splitting the predicated loop into (unreachable) sub-loops (i.e. done by unrolling, peeling, pre/main/post etc.). - new_predicate_proj = insert_initial_skeleton_predicate(iff, loop, proj, predicate_proj, upper_bound_proj, scale, - offset, init, limit, stride, rng, overflow, reason); + // Fall through into rest of the clean up code which will move + // any dependent nodes onto the upper bound test. + new_predicate_proj = upper_bound_proj; + + if (iff->is_RangeCheck()) { + new_predicate_proj = insert_initial_skeleton_predicate(iff, loop, proj, predicate_proj, upper_bound_proj, scale, offset, init, limit, stride, rng, overflow, reason); + } #ifndef PRODUCT if (TraceLoopOpts && !TraceLoopPredicate) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopTransform.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/loopTransform.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/loopTransform.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/loopTransform.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2149,8 +2149,8 @@ // Verify that policy_unroll result is still valid. const TypeInt* limit_type = _igvn.type(limit)->is_int(); - assert(stride_con > 0 && ((limit_type->_hi - stride_con) < limit_type->_hi) || - stride_con < 0 && ((limit_type->_lo - stride_con) > limit_type->_lo), + assert((stride_con > 0 && ((min_jint + stride_con) <= limit_type->_hi)) || + (stride_con < 0 && ((max_jint + stride_con) >= limit_type->_lo)), "sanity"); if (limit->is_Con()) { @@ -3947,6 +3947,19 @@ Node* len = new SubINode(head->limit(), head->init_trip()); _igvn.register_new_node_with_optimizer(len); + // If the store is on the backedge, it is not executed in the last + // iteration, and we must subtract 1 from the len. + Node* backedge = head->loopexit()->proj_out(1); + if (store->in(0) == backedge) { + len = new SubINode(len, _igvn.intcon(1)); + _igvn.register_new_node_with_optimizer(len); +#ifndef PRODUCT + if (TraceOptimizeFill) { + tty->print_cr("ArrayFill store on backedge, subtract 1 from len."); + } +#endif + } + BasicType t = store->as_Mem()->memory_type(); bool aligned = false; if (offset != NULL && head->init_trip()->is_Con()) { @@ -4049,5 +4062,12 @@ _igvn.replace_node(n, C->top()); } +#ifndef PRODUCT + if (TraceOptimizeFill) { + tty->print("ArrayFill call "); + call->dump(); + } +#endif + return true; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/macro.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/macro.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/macro.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/macro.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1205,7 +1205,8 @@ AllocateNode* alloc, // allocation node to be expanded Node* length, // array length for an array allocation const TypeFunc* slow_call_type, // Type of slow call - address slow_call_address // Address of slow call + address slow_call_address, // Address of slow call + Node* valid_length_test // whether length is valid or not ) { Node* ctrl = alloc->in(TypeFunc::Control); @@ -1391,6 +1392,12 @@ // Copy debug information and adjust JVMState information, then replace // allocate node with the call call->copy_call_debug_info(&_igvn, alloc); + // For array allocations, copy the valid length check to the call node so Compile::final_graph_reshaping() can verify + // that the call has the expected number of CatchProj nodes (in case the allocation always fails and the fallthrough + // path dies). + if (valid_length_test != NULL) { + call->add_req(valid_length_test); + } if (expand_fast_path) { call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. } else { @@ -1872,11 +1879,12 @@ void PhaseMacroExpand::expand_allocate(AllocateNode *alloc) { expand_allocate_common(alloc, NULL, OptoRuntime::new_instance_Type(), - OptoRuntime::new_instance_Java()); + OptoRuntime::new_instance_Java(), NULL); } void PhaseMacroExpand::expand_allocate_array(AllocateArrayNode *alloc) { Node* length = alloc->in(AllocateNode::ALength); + Node* valid_length_test = alloc->in(AllocateNode::ValidLengthTest); InitializeNode* init = alloc->initialization(); Node* klass_node = alloc->in(AllocateNode::KlassNode); ciKlass* k = _igvn.type(klass_node)->is_klassptr()->klass(); @@ -1891,7 +1899,7 @@ } expand_allocate_common(alloc, length, OptoRuntime::new_array_Type(), - slow_call_address); + slow_call_address, valid_length_test); } //-------------------mark_eliminated_box---------------------------------- diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/macro.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/macro.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/macro.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/macro.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -92,8 +92,8 @@ void expand_allocate_common(AllocateNode* alloc, Node* length, const TypeFunc* slow_call_type, - address slow_call_address); - void yank_initalize_node(InitializeNode* node); + address slow_call_address, + Node* valid_length_test); void yank_alloc_node(AllocateNode* alloc); Node *value_from_mem(Node *mem, Node *ctl, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc); Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc, Node_Stack *value_phis, int level); diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/memnode.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/memnode.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/memnode.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/memnode.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1054,7 +1054,8 @@ opc == Op_MemBarRelease || opc == Op_StoreFence || opc == Op_MemBarReleaseLock || - opc == Op_MemBarStoreStore) { + opc == Op_MemBarStoreStore || + opc == Op_StoreStoreFence) { Node* mem = current->in(0)->in(TypeFunc::Memory); if (mem->is_MergeMem()) { MergeMemNode* merge = mem->as_MergeMem(); @@ -3286,14 +3287,14 @@ case Op_LoadFence: return new LoadFenceNode(C, atp, pn); case Op_MemBarRelease: return new MemBarReleaseNode(C, atp, pn); case Op_StoreFence: return new StoreFenceNode(C, atp, pn); + case Op_MemBarStoreStore: return new MemBarStoreStoreNode(C, atp, pn); + case Op_StoreStoreFence: return new StoreStoreFenceNode(C, atp, pn); case Op_MemBarAcquireLock: return new MemBarAcquireLockNode(C, atp, pn); case Op_MemBarReleaseLock: return new MemBarReleaseLockNode(C, atp, pn); case Op_MemBarVolatile: return new MemBarVolatileNode(C, atp, pn); case Op_MemBarCPUOrder: return new MemBarCPUOrderNode(C, atp, pn); case Op_OnSpinWait: return new OnSpinWaitNode(C, atp, pn); case Op_Initialize: return new InitializeNode(C, atp, pn); - case Op_MemBarStoreStore: return new MemBarStoreStoreNode(C, atp, pn); - case Op_Blackhole: return new BlackholeNode(C, atp, pn); default: ShouldNotReachHere(); return NULL; } } @@ -3533,26 +3534,6 @@ return mb; } -#ifndef PRODUCT -void BlackholeNode::format(PhaseRegAlloc* ra, outputStream* st) const { - st->print("blackhole "); - bool first = true; - for (uint i = 0; i < req(); i++) { - Node* n = in(i); - if (n != NULL && OptoReg::is_valid(ra->get_reg_first(n))) { - if (first) { - first = false; - } else { - st->print(", "); - } - char buf[128]; - ra->dump_register(n, buf); - st->print("%s", buf); - } - } - st->cr(); -} -#endif //===========================InitializeNode==================================== // SUMMARY: diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/memnode.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/memnode.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/memnode.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/memnode.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1309,6 +1309,13 @@ virtual int Opcode() const; }; +class StoreStoreFenceNode: public MemBarNode { +public: + StoreStoreFenceNode(Compile* C, int alias_idx, Node* precedent) + : MemBarNode(C, alias_idx, precedent) {} + virtual int Opcode() const; +}; + // Ordering between a volatile store and a following volatile load. // Requires multi-CPU visibility? class MemBarVolatileNode: public MemBarNode { @@ -1336,26 +1343,6 @@ virtual int Opcode() const; }; -//------------------------------BlackholeNode---------------------------- -// Blackhole all arguments. This node would survive through the compiler -// the effects on its arguments, and would be finally matched to nothing. -class BlackholeNode : public MemBarNode { -public: - BlackholeNode(Compile* C, int alias_idx, Node* precedent) - : MemBarNode(C, alias_idx, precedent) {} - virtual int Opcode() const; - virtual uint ideal_reg() const { return 0; } // not matched in the AD file - const RegMask &in_RegMask(uint idx) const { - // Fake the incoming arguments mask for blackholes: accept all registers - // and all stack slots. This would avoid any redundant register moves - // for blackhole inputs. - return RegMask::All; - } -#ifndef PRODUCT - virtual void format(PhaseRegAlloc* ra, outputStream* st) const; -#endif -}; - // Isolation of object setup after an AllocateNode and before next safepoint. // (See comment in memnode.cpp near InitializeNode::InitializeNode for semantics.) class InitializeNode: public MemBarNode { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/node.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/node.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/node.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/node.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -622,33 +622,7 @@ //assert(def->out(def->outcnt()-1) == (Node *)this,"bad def-use hacking in reclaim"); } assert(outcnt() == 0, "deleting a node must not leave a dangling use"); - // See if the input array was allocated just prior to the object - int edge_size = _max*sizeof(void*); - int out_edge_size = _outmax*sizeof(void*); - char *edge_end = ((char*)_in) + edge_size; - char *out_array = (char*)(_out == NO_OUT_ARRAY? NULL: _out); - int node_size = size_of(); - // Free the output edge array - if (out_edge_size > 0) { - compile->node_arena()->Afree(out_array, out_edge_size); - } - - // Free the input edge array and the node itself - if( edge_end == (char*)this ) { - // It was; free the input array and object all in one hit -#ifndef ASSERT - compile->node_arena()->Afree(_in,edge_size+node_size); -#endif - } else { - // Free just the input array - compile->node_arena()->Afree(_in,edge_size); - - // Free just the object -#ifndef ASSERT - compile->node_arena()->Afree(this,node_size); -#endif - } if (is_macro()) { compile->remove_macro_node(this); } @@ -667,13 +641,43 @@ } BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); bs->unregister_potential_barrier_node(this); + + // See if the input array was allocated just prior to the object + int edge_size = _max*sizeof(void*); + int out_edge_size = _outmax*sizeof(void*); + char *in_array = ((char*)_in); + char *edge_end = in_array + edge_size; + char *out_array = (char*)(_out == NO_OUT_ARRAY? NULL: _out); + int node_size = size_of(); + #ifdef ASSERT // We will not actually delete the storage, but we'll make the node unusable. + compile->remove_modified_node(this); *(address*)this = badAddress; // smash the C++ vtbl, probably _in = _out = (Node**) badAddress; _max = _cnt = _outmax = _outcnt = 0; - compile->remove_modified_node(this); #endif + + // Free the output edge array + if (out_edge_size > 0) { + compile->node_arena()->Afree(out_array, out_edge_size); + } + + // Free the input edge array and the node itself + if( edge_end == (char*)this ) { + // It was; free the input array and object all in one hit +#ifndef ASSERT + compile->node_arena()->Afree(in_array, edge_size+node_size); +#endif + } else { + // Free just the input array + compile->node_arena()->Afree(in_array, edge_size); + + // Free just the object +#ifndef ASSERT + compile->node_arena()->Afree(this, node_size); +#endif + } } //------------------------------grow------------------------------------------- diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/node.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/node.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/node.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/node.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1647,6 +1647,11 @@ _for_igvn->push(n); } +// Inline definition of Compile::remove_for_igvn must be deferred to this point. +inline void Compile::remove_for_igvn(Node* n) { + _for_igvn->remove(n); +} + //------------------------------Node_Stack------------------------------------- class Node_Stack { friend class VMStructs; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/parse1.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/parse1.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/parse1.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/parse1.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -613,8 +613,6 @@ // Parse all the basic blocks. do_all_blocks(); - C->set_default_node_notes(caller_nn); - // Check for bailouts during conversion to graph if (failing()) { if (log) log->done("parse"); @@ -625,6 +623,10 @@ set_map(entry_map); do_exits(); + // Only reset this now, to make sure that debug information emitted + // for exiting control flow still refers to the inlined method. + C->set_default_node_notes(caller_nn); + if (log) log->done("parse nodes='%d' live='%d' memory='" SIZE_FORMAT "'", C->unique(), C->live_nodes(), C->node_arena()->used()); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/phaseX.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/phaseX.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/phaseX.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/phaseX.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -469,6 +469,14 @@ uint worklist_size = worklist->size(); + GrowableArray* old_node_note_array = C->node_note_array(); + if (old_node_note_array != nullptr) { + int new_size = (_useful.size() >> 8) + 1; // The node note array uses blocks, see C->_log2_node_notes_block_size + new_size = MAX2(8, new_size); + C->set_node_note_array(new (C->comp_arena()) GrowableArray (C->comp_arena(), new_size, 0, nullptr)); + C->grow_node_notes(C->node_note_array(), new_size); + } + // Iterate over the set of live nodes. for (uint current_idx = 0; current_idx < _useful.size(); current_idx++) { Node* n = _useful.at(current_idx); @@ -484,6 +492,11 @@ assert(_old2new_map.at(n->_idx) == -1, "already seen"); _old2new_map.at_put(n->_idx, current_idx); + if (old_node_note_array != nullptr) { + Node_Notes* nn = C->locate_node_notes(old_node_note_array, n->_idx); + C->set_node_notes_at(current_idx, nn); + } + n->set_idx(current_idx); // Update node ID. if (in_worklist) { @@ -1642,6 +1655,16 @@ if (imem != NULL) add_users_to_worklist0(imem); } } + // If the ValidLengthTest input changes then the fallthrough path out of the AllocateArray may have become dead. + // CatchNode::Value() is responsible for killing that path. The CatchNode has to be explicitly enqueued for igvn + // to guarantee the change is not missed. + if (use_op == Op_AllocateArray && n == use->in(AllocateNode::ValidLengthTest)) { + Node* p = use->as_AllocateArray()->proj_out_or_null(TypeFunc::Control); + if (p != NULL) { + add_users_to_worklist0(p); + } + } + if (use_op == Op_Initialize) { Node* imem = use->as_Initialize()->proj_out_or_null(TypeFunc::Memory); if (imem != NULL) add_users_to_worklist0(imem); @@ -1808,6 +1831,7 @@ // the Catch following the call. It's looking for a non-NULL // receiver to know when to enable the regular fall-through path // in addition to the NullPtrException path + // Same is true if the type of a ValidLengthTest input to an AllocateArrayNode changes. if (m->is_Call()) { for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { Node* p = m->fast_out(i2); // Propagate changes to uses diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/phaseX.hpp openjdk-17-17.0.8+7/src/hotspot/share/opto/phaseX.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/phaseX.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/phaseX.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -238,6 +238,11 @@ assert(t != NULL, "type must not be null"); _types.map(n->_idx, t); } + void clear_type(const Node* n) { + if (n->_idx < _types.Size()) { + _types.map(n->_idx, NULL); + } + } // Record an initial type for a node, the node's bottom type. void set_type_bottom(const Node* n) { // Use this for initialization when bottom_type() (or better) is not handy. diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/split_if.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/split_if.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/split_if.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/split_if.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -128,8 +128,8 @@ } } else { // We might see an Opaque1 from a loop limit check here - assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type"); - Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use); + assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1 || use->is_AllocateArray(), "unexpected node type"); + Node *use_c = (use->is_If() || use->is_AllocateArray()) ? use->in(0) : get_ctrl(use); if (use_c == blk1 || use_c == blk2) { assert(use->is_CMove(), "unexpected node type"); continue; @@ -166,14 +166,15 @@ --j; } else { // We might see an Opaque1 from a loop limit check here - assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type"); - assert(u->in(1) == bol, ""); + assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1 || u->is_AllocateArray(), "unexpected node type"); + assert(u->is_AllocateArray() || u->in(1) == bol, ""); + assert(!u->is_AllocateArray() || u->in(AllocateNode::ValidLengthTest) == bol, "wrong input to AllocateArray"); // Get control block of either the CMove or the If input - Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u); + Node *u_ctrl = (u->is_If() || u->is_AllocateArray()) ? u->in(0) : get_ctrl(u); assert((u_ctrl != blk1 && u_ctrl != blk2) || u->is_CMove(), "won't converge"); Node *x = bol->clone(); register_new_node(x, u_ctrl); - _igvn.replace_input_of(u, 1, x); + _igvn.replace_input_of(u, u->is_AllocateArray() ? AllocateNode::ValidLengthTest : 1, x); --j; } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/subnode.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/subnode.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/subnode.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/subnode.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -683,6 +683,9 @@ if (t2 == TypeInt::INT) { // Compare to bottom? return bottom_type(); } + + const Type* t_sub = sub(t1, t2); // compare based on immediate inputs + uint in1_op = in1->Opcode(); if (in1_op == Op_AddI || in1_op == Op_SubI) { // The problem rise when result of AddI(SubI) may overflow @@ -735,13 +738,15 @@ const TypeInt* tr2 = TypeInt::make(lo_tr2, hi_tr2, w); const TypeInt* cmp1 = sub(tr1, t2)->is_int(); const TypeInt* cmp2 = sub(tr2, t2)->is_int(); - // compute union, so that cmp handles all possible results from the two cases - return cmp1->meet(cmp2); + // Compute union, so that cmp handles all possible results from the two cases + const Type* t_cmp = cmp1->meet(cmp2); + // Pick narrowest type, based on overflow computation and on immediate inputs + return t_sub->filter(t_cmp); } } } - return sub(t1, t2); // Local flavor of type subtraction + return t_sub; } bool CmpUNode::is_index_range_check() const { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/vectorIntrinsics.cpp openjdk-17-17.0.8+7/src/hotspot/share/opto/vectorIntrinsics.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/opto/vectorIntrinsics.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/opto/vectorIntrinsics.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -868,7 +868,7 @@ set_result(box); } - old_map->destruct(&_gvn); + destruct_map_clone(old_map); if (can_access_non_heap) { insert_mem_bar(Op_MemBarCPUOrder); @@ -1006,7 +1006,7 @@ set_result(box); } - old_map->destruct(&_gvn); + destruct_map_clone(old_map); C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); return true; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jniCheck.cpp openjdk-17-17.0.8+7/src/hotspot/share/prims/jniCheck.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jniCheck.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/prims/jniCheck.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -145,7 +145,7 @@ // When in VM state: static void ReportJNIWarning(JavaThread* thr, const char *msg) { tty->print_cr("WARNING in native method: %s", msg); - thr->print_stack(); + thr->print_jni_stack(); } // When in NATIVE state: @@ -196,7 +196,7 @@ IN_VM( tty->print_cr("WARNING in native method: JNI call made without checking exceptions when required to from %s", thr->get_pending_jni_exception_check()); - thr->print_stack(); + thr->print_jni_stack(); ) thr->clear_pending_jni_exception_check(); // Just complain once } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jniCheck.hpp openjdk-17-17.0.8+7/src/hotspot/share/prims/jniCheck.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jniCheck.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/prims/jniCheck.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -35,7 +35,7 @@ // When in VM state: static inline void ReportJNIFatalError(JavaThread* thr, const char *msg) { tty->print_cr("FATAL ERROR in native method: %s", msg); - thr->print_stack(); + thr->print_jni_stack(); os::abort(true); } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jni.cpp openjdk-17-17.0.8+7/src/hotspot/share/prims/jni.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jni.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/prims/jni.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -625,7 +625,7 @@ HOTSPOT_JNI_FATALERROR_ENTRY(env, (char *) msg); tty->print_cr("FATAL ERROR in native method: %s", msg); - thread->print_stack(); + thread->print_jni_stack(); os::abort(); // Dump core and abort JNI_END @@ -2234,7 +2234,7 @@ if (s_value != NULL) { size_t length = java_lang_String::utf8_length(java_string, s_value); /* JNI Specification states return NULL on OOM */ - result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL); + result = AllocateHeap(length + 1, mtInternal, AllocFailStrategy::RETURN_NULL); if (result != NULL) { java_lang_String::as_utf8_string(java_string, s_value, result, (int) length + 1); if (isCopy != NULL) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jvmtiExport.cpp openjdk-17-17.0.8+7/src/hotspot/share/prims/jvmtiExport.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jvmtiExport.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/prims/jvmtiExport.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2216,6 +2216,7 @@ ResourceMark rm(thread); HandleMark hm(thread); + assert(!nm->is_zombie(), "nmethod zombie in post_compiled_method_load"); // Add inlining information jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm); // Pass inlining information through the void pointer diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jvmtiImpl.cpp openjdk-17-17.0.8+7/src/hotspot/share/prims/jvmtiImpl.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/jvmtiImpl.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/prims/jvmtiImpl.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -960,10 +960,10 @@ } void JvmtiDeferredEventQueue::post(JvmtiEnv* env) { - // Post and destroy queue nodes + // Post events while nmethods are still in the queue and can't be unloaded or made zombie while (_queue_head != NULL) { - JvmtiDeferredEvent event = dequeue(); - event.post_compiled_method_load_event(env); + _queue_head->event().post_compiled_method_load_event(env); + dequeue(); } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/whitebox.cpp openjdk-17-17.0.8+7/src/hotspot/share/prims/whitebox.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/prims/whitebox.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/prims/whitebox.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -821,10 +821,9 @@ return true; } DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp); - if (directive->ExcludeOption) { - return true; - } - return false; + bool exclude = directive->ExcludeOption; + DirectivesStack::release(directive); + return exclude; } static bool can_be_compiled_at_level(methodHandle& mh, jboolean is_osr, int level) { diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/abstract_vm_version.hpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/abstract_vm_version.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/abstract_vm_version.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/abstract_vm_version.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ typedef enum { NoDetectedVirtualization, XenHVM, + XenPVHVM, // mix-mode on Linux aarch64 KVM, VMWare, HyperV, @@ -71,9 +72,10 @@ static int _vm_build_number; static unsigned int _data_cache_line_flush_size; + public: + static VirtualizationType _detected_virtualization; - public: // Called as part of the runtime services initialization which is // called from the management module initialization (via init_globals()) // after argument parsing and attaching of the main thread has diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/globals.hpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/globals.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/globals.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/globals.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -700,6 +700,13 @@ "MonitorUsedDeflationThreshold is exceeded (0 is off).") \ range(0, max_jint) \ \ + /* notice: the max range value here is max_jint, not max_intx */ \ + /* because of overflow issue */ \ + product(intx, GuaranteedAsyncDeflationInterval, 60000, DIAGNOSTIC, \ + "Async deflate idle monitors every so many milliseconds even " \ + "when MonitorUsedDeflationThreshold is NOT exceeded (0 is off).") \ + range(0, max_jint) \ + \ product(size_t, AvgMonitorsPerThreadEstimate, 1024, DIAGNOSTIC, \ "Used to estimate a variable ceiling based on number of threads " \ "for use with MonitorUsedDeflationThreshold (0 is off).") \ @@ -714,8 +721,9 @@ \ product(intx, MonitorUsedDeflationThreshold, 90, DIAGNOSTIC, \ "Percentage of used monitors before triggering deflation (0 is " \ - "off). The check is performed on GuaranteedSafepointInterval " \ - "or AsyncDeflationInterval.") \ + "off). The check is performed on GuaranteedSafepointInterval, " \ + "AsyncDeflationInterval or GuaranteedAsyncDeflationInterval, " \ + "whichever is lower.") \ range(0, 100) \ \ product(uintx, NoAsyncDeflationProgressMax, 3, DIAGNOSTIC, \ @@ -1998,10 +2006,10 @@ product(ccstr, ExtraSharedClassListFile, NULL, \ "Extra classlist for building the CDS archive file") \ \ - product(intx, ArchiveRelocationMode, 0, DIAGNOSTIC, \ + product(intx, ArchiveRelocationMode, 1, DIAGNOSTIC, \ "(0) first map at preferred address, and if " \ - "unsuccessful, map at alternative address (default); " \ - "(1) always map at alternative address; " \ + "unsuccessful, map at alternative address; " \ + "(1) always map at alternative address (default); " \ "(2) always map at preferred address, and if unsuccessful, " \ "do not map the archive") \ range(0, 2) \ diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/monitorDeflationThread.cpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/monitorDeflationThread.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/monitorDeflationThread.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/monitorDeflationThread.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -75,6 +75,38 @@ } void MonitorDeflationThread::monitor_deflation_thread_entry(JavaThread* jt, TRAPS) { + + // We wait for the lowest of these three intervals: + // - GuaranteedSafepointInterval + // While deflation is not related to safepoint anymore, this keeps compatibility with + // the old behavior when deflation also happened at safepoints. Users who set this + // option to get more/less frequent deflations would be served with this option. + // - AsyncDeflationInterval + // Normal threshold-based deflation heuristic checks the conditions at this interval. + // See is_async_deflation_needed(). + // - GuaranteedAsyncDeflationInterval + // Backup deflation heuristic checks the conditions at this interval. + // See is_async_deflation_needed(). + // + intx wait_time = max_intx; + if (GuaranteedSafepointInterval > 0) { + wait_time = MIN2(wait_time, GuaranteedSafepointInterval); + } + if (AsyncDeflationInterval > 0) { + wait_time = MIN2(wait_time, AsyncDeflationInterval); + } + if (GuaranteedAsyncDeflationInterval > 0) { + wait_time = MIN2(wait_time, GuaranteedAsyncDeflationInterval); + } + + // If all options are disabled, then wait time is not defined, and the deflation + // is effectively disabled. In that case, exit the thread immediately after printing + // a warning message. + if (wait_time == max_intx) { + warning("Async deflation is disabled"); + return; + } + while (true) { { // Need state transition ThreadBlockInVM so that this thread @@ -86,9 +118,7 @@ MonitorLocker ml(MonitorDeflation_lock, Mutex::_no_safepoint_check_flag); while (!ObjectSynchronizer::is_async_deflation_needed()) { // Wait until notified that there is some work to do. - // We wait for GuaranteedSafepointInterval so that - // is_async_deflation_needed() is checked at the same interval. - ml.wait(GuaranteedSafepointInterval); + ml.wait(wait_time); } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/nonJavaThread.cpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/nonJavaThread.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/nonJavaThread.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/nonJavaThread.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -270,8 +270,8 @@ os::die(); } - // Wait a second, then recheck for timeout. - os::naked_short_sleep(999); + // Wait a bit, then recheck for timeout. + os::naked_short_sleep(250); } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/relocator.cpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/relocator.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/relocator.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/relocator.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -413,11 +413,24 @@ } } +static void print_linenumber_table(unsigned char* table) { + CompressedLineNumberReadStream stream(table); + tty->print_cr("-------------------------------------------------"); + while (stream.read_pair()) { + tty->print_cr(" - line %d: %d", stream.line(), stream.bci()); + } + tty->print_cr("-------------------------------------------------"); +} // The width of instruction at "bci" is changing by "delta". Adjust the line number table. void Relocator::adjust_line_no_table(int bci, int delta) { if (method()->has_linenumber_table()) { - CompressedLineNumberReadStream reader(method()->compressed_linenumber_table()); + // if we already made adjustments then use the updated table + unsigned char *table = compressed_line_number_table(); + if (table == nullptr) { + table = method()->compressed_linenumber_table(); + } + CompressedLineNumberReadStream reader(table); CompressedLineNumberWriteStream writer(64); // plenty big for most line number tables while (reader.read_pair()) { int adjustment = (reader.bci() > bci) ? delta : 0; @@ -426,6 +439,10 @@ writer.write_terminator(); set_compressed_line_number_table(writer.buffer()); set_compressed_line_number_table_size(writer.position()); + if (TraceRelocator) { + tty->print_cr("Adjusted line number table"); + print_linenumber_table(compressed_line_number_table()); + } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/safepoint.cpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/safepoint.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/safepoint.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/safepoint.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -506,19 +506,9 @@ return false; } -class ParallelSPCleanupThreadClosure : public ThreadClosure { -public: - void do_thread(Thread* thread) { - if (thread->is_Java_thread()) { - StackWatermarkSet::start_processing(thread->as_Java_thread(), StackWatermarkKind::gc); - } - } -}; - -class ParallelSPCleanupTask : public AbstractGangTask { +class ParallelCleanupTask : public AbstractGangTask { private: SubTasksDone _subtasks; - uint _num_workers; bool _do_lazy_roots; class Tracer { @@ -538,32 +528,14 @@ }; public: - ParallelSPCleanupTask(uint num_workers) : + ParallelCleanupTask() : AbstractGangTask("Parallel Safepoint Cleanup"), _subtasks(SafepointSynchronize::SAFEPOINT_CLEANUP_NUM_TASKS), - _num_workers(num_workers), _do_lazy_roots(!VMThread::vm_operation()->skip_thread_oop_barriers() && Universe::heap()->uses_stack_watermark_barrier()) {} void work(uint worker_id) { - if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_LAZY_ROOT_PROCESSING)) { - if (_do_lazy_roots) { - Tracer t("lazy partial thread root processing"); - ParallelSPCleanupThreadClosure cl; - Threads::threads_do(&cl); - } - } - - if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_UPDATE_INLINE_CACHES)) { - Tracer t("updating inline caches"); - InlineCacheBuffer::update_inline_caches(); - } - - if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_COMPILATION_POLICY)) { - Tracer t("compilation policy safepoint handler"); - CompilationPolicy::do_safepoint_work(); - } - + // These tasks are ordered by relative length of time to execute so that potentially longer tasks start first. if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) { if (SymbolTable::needs_rehashing()) { Tracer t("rehashing symbol table"); @@ -585,6 +557,25 @@ } } + if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_LAZY_ROOT_PROCESSING)) { + if (_do_lazy_roots) { + Tracer t("lazy partial thread root processing"); + class LazyRootClosure : public ThreadClosure { + public: + void do_thread(Thread* thread) { + StackWatermarkSet::start_processing(thread->as_Java_thread(), StackWatermarkKind::gc); + } + }; + LazyRootClosure cl; + Threads::java_threads_do(&cl); + } + } + + if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_UPDATE_INLINE_CACHES)) { + Tracer t("updating inline caches"); + InlineCacheBuffer::update_inline_caches(); + } + if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP)) { // Don't bother reporting event or time for this very short operation. // To have any utility we'd also want to report whether needed. @@ -602,15 +593,13 @@ CollectedHeap* heap = Universe::heap(); assert(heap != NULL, "heap not initialized yet?"); + ParallelCleanupTask cleanup; WorkGang* cleanup_workers = heap->safepoint_workers(); if (cleanup_workers != NULL) { // Parallel cleanup using GC provided thread pool. - uint num_cleanup_workers = cleanup_workers->active_workers(); - ParallelSPCleanupTask cleanup(num_cleanup_workers); cleanup_workers->run_task(&cleanup); } else { // Serial cleanup using VMThread. - ParallelSPCleanupTask cleanup(1); cleanup.work(0); } @@ -1011,6 +1000,7 @@ int SafepointTracing::_page_trap = 0; VM_Operation::VMOp_Type SafepointTracing::_current_type; jlong SafepointTracing::_max_sync_time = 0; +jlong SafepointTracing::_max_cleanup_time = 0; jlong SafepointTracing::_max_vmop_time = 0; uint64_t SafepointTracing::_op_count[VM_Operation::VMOp_Terminating] = {0}; @@ -1080,6 +1070,8 @@ log_info(safepoint, stats)("Maximum sync time " INT64_FORMAT" ns", (int64_t)(_max_sync_time)); + log_info(safepoint, stats)("Maximum cleanup time " INT64_FORMAT" ns", + (int64_t)(_max_cleanup_time)); log_info(safepoint, stats)("Maximum vm operation time (except for Exit VM operation) " INT64_FORMAT " ns", (int64_t)(_max_vmop_time)); @@ -1118,6 +1110,9 @@ if (_max_sync_time < (_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns)) { _max_sync_time = _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns; } + if (_max_cleanup_time < (_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns)) { + _max_cleanup_time = _last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns; + } if (_max_vmop_time < (_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns)) { _max_vmop_time = _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns; } @@ -1129,14 +1124,16 @@ "Safepoint \"%s\", " "Time since last: " JLONG_FORMAT " ns, " "Reaching safepoint: " JLONG_FORMAT " ns, " + "Cleanup: " JLONG_FORMAT " ns, " "At safepoint: " JLONG_FORMAT " ns, " "Total: " JLONG_FORMAT " ns", VM_Operation::name(_current_type), _last_app_time_ns, - _last_safepoint_cleanup_time_ns - _last_safepoint_begin_time_ns, + _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns, + _last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns, _last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns, _last_safepoint_end_time_ns - _last_safepoint_begin_time_ns ); - RuntimeService::record_safepoint_end(_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns); + RuntimeService::record_safepoint_end(_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/safepoint.hpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/safepoint.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/safepoint.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/safepoint.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -72,7 +72,6 @@ enum SafepointCleanupTasks { SAFEPOINT_CLEANUP_LAZY_ROOT_PROCESSING, SAFEPOINT_CLEANUP_UPDATE_INLINE_CACHES, - SAFEPOINT_CLEANUP_COMPILATION_POLICY, SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH, SAFEPOINT_CLEANUP_STRING_TABLE_REHASH, SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE, @@ -261,6 +260,7 @@ static VM_Operation::VMOp_Type _current_type; static jlong _max_sync_time; + static jlong _max_cleanup_time; static jlong _max_vmop_time; static uint64_t _op_count[VM_Operation::VMOp_Terminating]; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/synchronizer.cpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/synchronizer.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/synchronizer.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/synchronizer.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -213,6 +213,9 @@ } // Start the ceiling with the estimate for one thread. set_in_use_list_ceiling(AvgMonitorsPerThreadEstimate); + + // Start the timer for deflations, so it does not trigger immediately. + _last_async_deflation_time_ns = os::javaTimeNanos(); } MonitorList ObjectSynchronizer::_in_use_list; @@ -241,6 +244,7 @@ bool volatile ObjectSynchronizer::_is_final_audit = false; jlong ObjectSynchronizer::_last_async_deflation_time_ns = 0; static uintx _no_progress_cnt = 0; +static bool _no_progress_skip_increment = false; // =====================> Quick functions @@ -1106,7 +1110,14 @@ // Check if our monitor usage is above the threshold: size_t monitor_usage = (monitors_used * 100LL) / ceiling; - return int(monitor_usage) > MonitorUsedDeflationThreshold; + if (int(monitor_usage) > MonitorUsedDeflationThreshold) { + log_info(monitorinflation)("monitors_used=" SIZE_FORMAT ", ceiling=" SIZE_FORMAT + ", monitor_usage=" SIZE_FORMAT ", threshold=" INTX_FORMAT, + monitors_used, ceiling, monitor_usage, MonitorUsedDeflationThreshold); + return true; + } + + return false; } size_t ObjectSynchronizer::in_use_list_ceiling() { @@ -1128,17 +1139,49 @@ bool ObjectSynchronizer::is_async_deflation_needed() { if (is_async_deflation_requested()) { // Async deflation request. + log_info(monitorinflation)("Async deflation needed: explicit request"); return true; } + + jlong time_since_last = time_since_last_async_deflation_ms(); + if (AsyncDeflationInterval > 0 && - time_since_last_async_deflation_ms() > AsyncDeflationInterval && + time_since_last > AsyncDeflationInterval && monitors_used_above_threshold(&_in_use_list)) { // It's been longer than our specified deflate interval and there // are too many monitors in use. We don't deflate more frequently // than AsyncDeflationInterval (unless is_async_deflation_requested) // in order to not swamp the MonitorDeflationThread. + log_info(monitorinflation)("Async deflation needed: monitors used are above the threshold"); return true; } + + if (GuaranteedAsyncDeflationInterval > 0 && + time_since_last > GuaranteedAsyncDeflationInterval) { + // It's been longer than our specified guaranteed deflate interval. + // We need to clean up the used monitors even if the threshold is + // not reached, to keep the memory utilization at bay when many threads + // touched many monitors. + log_info(monitorinflation)("Async deflation needed: guaranteed interval (" INTX_FORMAT " ms) " + "is greater than time since last deflation (" JLONG_FORMAT " ms)", + GuaranteedAsyncDeflationInterval, time_since_last); + + // If this deflation has no progress, then it should not affect the no-progress + // tracking, otherwise threshold heuristics would think it was triggered, experienced + // no progress, and needs to backoff more aggressively. In this "no progress" case, + // the generic code would bump the no-progress counter, and we compensate for that + // by telling it to skip the update. + // + // If this deflation has progress, then it should let non-progress tracking + // know about this, otherwise the threshold heuristics would kick in, potentially + // experience no-progress due to aggressive cleanup by this deflation, and think + // it is still in no-progress stride. In this "progress" case, the generic code would + // zero the counter, and we allow it to happen. + _no_progress_skip_increment = true; + + return true; + } + return false; } @@ -1533,6 +1576,8 @@ if (deflated_count != 0) { _no_progress_cnt = 0; + } else if (_no_progress_skip_increment) { + _no_progress_skip_increment = false; } else { _no_progress_cnt++; } @@ -1621,6 +1666,7 @@ return; } set_is_final_audit(); + log_info(monitorinflation)("Starting the final audit."); if (log_is_enabled(Info, monitorinflation)) { // Do a deflation in order to reduce the in-use monitor population @@ -1630,7 +1676,7 @@ ; // empty } // The other audit_and_print_stats() call is done at the Debug - // level at a safepoint in ObjectSynchronizer::do_safepoint_work(). + // level at a safepoint in SafepointSynchronize::do_cleanup_tasks. ObjectSynchronizer::audit_and_print_stats(true /* on_exit */); } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/thread.cpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/thread.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/thread.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/thread.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -2284,6 +2284,25 @@ return NULL; } +// Print current stack trace for checked JNI warnings and JNI fatal errors. +// This is the external format, selecting the platform +// as applicable, and allowing for a native-only stack. +void JavaThread::print_jni_stack() { + assert(this == JavaThread::current(), "Can't print stack of other threads"); + if (!has_last_Java_frame()) { + ResourceMark rm(this); + char* buf = NEW_RESOURCE_ARRAY_RETURN_NULL(char, O_BUFLEN); + if (buf == nullptr) { + tty->print_cr("Unable to print native stack - out of memory"); + return; + } + frame f = os::current_frame(); + VMError::print_native_stack(tty, f, this, + buf, O_BUFLEN); + } else { + print_stack_on(tty); + } +} void JavaThread::print_stack_on(outputStream* st) { if (!has_last_Java_frame()) return; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/thread.hpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/thread.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/thread.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/thread.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1428,6 +1428,10 @@ // Print stack trace in external format void print_stack_on(outputStream* st); void print_stack() { print_stack_on(tty); } + // Print current stack trace for checked JNI warnings and JNI fatal errors. + // This is the external format from above, but selecting the platform + // as applicable. + void print_jni_stack(); // Print stack traces in various internal formats void trace_stack() PRODUCT_RETURN; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/vmOperation.hpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/vmOperation.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/vmOperation.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/vmOperation.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -59,7 +59,8 @@ template(ParallelGCSystemGC) \ template(G1CollectForAllocation) \ template(G1CollectFull) \ - template(G1Concurrent) \ + template(G1PauseRemark) \ + template(G1PauseCleanup) \ template(G1TryInitiateConcMark) \ template(ZMarkStart) \ template(ZMarkEnd) \ diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/vmStructs.cpp openjdk-17-17.0.8+7/src/hotspot/share/runtime/vmStructs.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/runtime/vmStructs.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/runtime/vmStructs.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1598,7 +1598,7 @@ declare_c2_type(MemBarVolatileNode, MemBarNode) \ declare_c2_type(MemBarCPUOrderNode, MemBarNode) \ declare_c2_type(OnSpinWaitNode, MemBarNode) \ - declare_c2_type(BlackholeNode, MemBarNode) \ + declare_c2_type(BlackholeNode, MultiNode) \ declare_c2_type(InitializeNode, MemBarNode) \ declare_c2_type(ThreadLocalNode, Node) \ declare_c2_type(Opaque1Node, Node) \ diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/services/diagnosticCommand.cpp openjdk-17-17.0.8+7/src/hotspot/share/services/diagnosticCommand.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/services/diagnosticCommand.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/services/diagnosticCommand.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -800,7 +800,8 @@ if (str != NULL) { char* out = java_lang_String::as_utf8_string(str); if (out) { - output()->print_cr("%s", out); + // Avoid using print_cr() because length maybe longer than O_BUFLEN + output()->print_raw_cr(out); return; } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/services/heapDumperCompression.cpp openjdk-17-17.0.8+7/src/hotspot/share/services/heapDumperCompression.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/services/heapDumperCompression.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/services/heapDumperCompression.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -54,10 +54,14 @@ assert(_fd >= 0, "Must be open"); assert(size > 0, "Must write at least one byte"); - ssize_t n = (ssize_t) os::write(_fd, buf, (uint) size); + while (size > 0) { + ssize_t n = os::write(_fd, buf, (uint) size); + if (n <= 0) { + return os::strerror(errno); + } - if (n <= 0) { - return os::strerror(errno); + buf += n; + size -= n; } return NULL; diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryManager.cpp openjdk-17-17.0.8+7/src/hotspot/share/services/memoryManager.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryManager.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/services/memoryManager.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -170,8 +170,8 @@ } -GCMemoryManager::GCMemoryManager(const char* name, const char* gc_end_message) : - MemoryManager(name), _gc_end_message(gc_end_message) { +GCMemoryManager::GCMemoryManager(const char* name) : + MemoryManager(name) { _num_collections = 0; _last_gc_stat = NULL; _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true, @@ -236,9 +236,11 @@ // to ensure the current gc stat is placed in _last_gc_stat. void GCMemoryManager::gc_end(bool recordPostGCUsage, bool recordAccumulatedGCTime, - bool recordGCEndTime, bool countCollection, + bool recordGCEndTime, + bool countCollection, GCCause::Cause cause, - bool allMemoryPoolsAffected) { + bool allMemoryPoolsAffected, + const char* message) { if (recordAccumulatedGCTime) { _accumulated_timer.stop(); } @@ -288,7 +290,7 @@ } if (is_notification_enabled()) { - GCNotifier::pushNotification(this, _gc_end_message, GCCause::to_string(cause)); + GCNotifier::pushNotification(this, message, GCCause::to_string(cause)); } } } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryManager.hpp openjdk-17-17.0.8+7/src/hotspot/share/services/memoryManager.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryManager.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/services/memoryManager.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -140,11 +140,10 @@ GCStatInfo* _current_gc_stat; int _num_gc_threads; volatile bool _notification_enabled; - const char* _gc_end_message; bool _pool_always_affected_by_gc[MemoryManager::max_num_pools]; public: - GCMemoryManager(const char* name, const char* gc_end_message); + GCMemoryManager(const char* name); ~GCMemoryManager(); void add_pool(MemoryPool* pool); @@ -167,7 +166,7 @@ bool recordAccumulatedGCTime); void gc_end(bool recordPostGCUsage, bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection, GCCause::Cause cause, - bool allMemoryPoolsAffected); + bool allMemoryPoolsAffected, const char* message); void reset_gc_stat() { _num_collections = 0; _accumulated_timer.reset(); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryService.cpp openjdk-17-17.0.8+7/src/hotspot/share/services/memoryService.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryService.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/services/memoryService.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -182,10 +182,10 @@ bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection, GCCause::Cause cause, - bool allMemoryPoolsAffected) { + bool allMemoryPoolsAffected, const char* message) { // register the GC end statistics and memory usage manager->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime, - countCollection, cause, allMemoryPoolsAffected); + countCollection, cause, allMemoryPoolsAffected, message); } bool MemoryService::set_verbose(bool verbose) { @@ -219,6 +219,7 @@ TraceMemoryManagerStats::TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager, GCCause::Cause cause, + const char* end_message, bool allMemoryPoolsAffected, bool recordGCBeginTime, bool recordPreGCUsage, @@ -227,16 +228,17 @@ bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection) { - initialize(gc_memory_manager, cause, allMemoryPoolsAffected, - recordGCBeginTime, recordPreGCUsage, recordPeakUsage, - recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime, - countCollection); + initialize(gc_memory_manager, cause, end_message, + allMemoryPoolsAffected, recordGCBeginTime, recordPreGCUsage, + recordPeakUsage, recordPostGCUsage, recordAccumulatedGCTime, + recordGCEndTime, countCollection); } // for a subclass to create then initialize an instance before invoking // the MemoryService void TraceMemoryManagerStats::initialize(GCMemoryManager* gc_memory_manager, GCCause::Cause cause, + const char* end_message, bool allMemoryPoolsAffected, bool recordGCBeginTime, bool recordPreGCUsage, @@ -246,6 +248,8 @@ bool recordGCEndTime, bool countCollection) { _gc_memory_manager = gc_memory_manager; + _cause = cause; + _end_message = end_message; _allMemoryPoolsAffected = allMemoryPoolsAffected; _recordGCBeginTime = recordGCBeginTime; _recordPreGCUsage = recordPreGCUsage; @@ -254,7 +258,6 @@ _recordAccumulatedGCTime = recordAccumulatedGCTime; _recordGCEndTime = recordGCEndTime; _countCollection = countCollection; - _cause = cause; MemoryService::gc_begin(_gc_memory_manager, _recordGCBeginTime, _recordAccumulatedGCTime, _recordPreGCUsage, _recordPeakUsage); @@ -262,5 +265,6 @@ TraceMemoryManagerStats::~TraceMemoryManagerStats() { MemoryService::gc_end(_gc_memory_manager, _recordPostGCUsage, _recordAccumulatedGCTime, - _recordGCEndTime, _countCollection, _cause, _allMemoryPoolsAffected); + _recordGCEndTime, _countCollection, _cause, _allMemoryPoolsAffected, + _end_message); } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryService.hpp openjdk-17-17.0.8+7/src/hotspot/share/services/memoryService.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/services/memoryService.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/services/memoryService.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -104,7 +104,7 @@ bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection, GCCause::Cause cause, - bool allMemoryPoolsAffected); + bool allMemoryPoolsAffected, const char* notificationMessage = nullptr); static bool get_verbose() { return log_is_enabled(Info, gc); } static bool set_verbose(bool verbose); @@ -116,19 +116,21 @@ class TraceMemoryManagerStats : public StackObj { private: GCMemoryManager* _gc_memory_manager; - bool _allMemoryPoolsAffected; - bool _recordGCBeginTime; - bool _recordPreGCUsage; - bool _recordPeakUsage; - bool _recordPostGCUsage; - bool _recordAccumulatedGCTime; - bool _recordGCEndTime; - bool _countCollection; - GCCause::Cause _cause; + GCCause::Cause _cause; + const char* _end_message; + bool _allMemoryPoolsAffected; + bool _recordGCBeginTime; + bool _recordPreGCUsage; + bool _recordPeakUsage; + bool _recordPostGCUsage; + bool _recordAccumulatedGCTime; + bool _recordGCEndTime; + bool _countCollection; public: TraceMemoryManagerStats() {} TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager, GCCause::Cause cause, + const char* end_message, bool allMemoryPoolsAffected = true, bool recordGCBeginTime = true, bool recordPreGCUsage = true, @@ -140,6 +142,7 @@ void initialize(GCMemoryManager* gc_memory_manager, GCCause::Cause cause, + const char* end_message, bool allMemoryPoolsAffected, bool recordGCBeginTime, bool recordPreGCUsage, diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/utilities/nativeCallStack.hpp openjdk-17-17.0.8+7/src/hotspot/share/utilities/nativeCallStack.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/utilities/nativeCallStack.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/utilities/nativeCallStack.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -64,7 +64,7 @@ memset(_stack, 0, sizeof(_stack)); } - NativeCallStack(int toSkip); + explicit NativeCallStack(int toSkip); NativeCallStack(address* pc, int frameCount); static inline const NativeCallStack& empty_stack() { return _empty_stack; } diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/utilities/vmError.cpp openjdk-17-17.0.8+7/src/hotspot/share/utilities/vmError.cpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/utilities/vmError.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/utilities/vmError.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -1,6 +1,7 @@ /* * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2020 SAP SE. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1713,43 +1714,68 @@ } while (yes); } -// Timeout handling: check if a timeout happened (either a single step did -// timeout or the whole of error reporting hit ErrorLogTimeout). Interrupt -// the reporting thread if that is the case. +// Fatal error handling is subject to several timeouts: +// - a global timeout (controlled via ErrorLogTimeout) +// - local error reporting step timeouts. +// +// The latter aims to "give the JVM a kick" if it gets stuck in one particular place during +// error reporting. This prevents one error reporting step from hogging all the time allotted +// to error reporting under ErrorLogTimeout. +// +// VMError::check_timeout() is called from the watcher thread and checks for either global +// or step timeout. If a timeout happened, we interrupt the reporting thread and set either +// _reporting_did_timeout or _step_did_timeout to signal which timeout fired. Function returns +// true if the *global* timeout fired, which will cause WatcherThread to shut down the JVM +// immediately. bool VMError::check_timeout() { + // This function is supposed to be called from watcher thread during fatal error handling only. + assert(VMError::is_error_reported(), "Only call during error handling"); + assert(Thread::current()->is_Watcher_thread(), "Only call from watcher thread"); + if (ErrorLogTimeout == 0) { return false; } - // Do not check for timeouts if we still have a message box to show to the - // user or if there are OnError handlers to be run. - if (ShowMessageBoxOnError - || (OnError != NULL && OnError[0] != '\0') - || Arguments::abort_hook() != NULL) { - return false; - } + // There are three situations where we suppress the *global* error timeout: + // - if the JVM is embedded and the launcher has its abort hook installed. + // That must be allowed to run. + // - if the user specified one or more OnError commands to run, and these + // did not yet run. These must have finished. + // - if the user (typically developer) specified ShowMessageBoxOnError, + // and the error box has not yet been shown + const bool ignore_global_timeout = + (ShowMessageBoxOnError + || (OnError != nullptr && OnError[0] != '\0') + || Arguments::abort_hook() != nullptr); - const jlong reporting_start_time_l = get_reporting_start_time(); const jlong now = get_current_timestamp(); - // Timestamp is stored in nanos. - if (reporting_start_time_l > 0) { - const jlong end = reporting_start_time_l + (jlong)ErrorLogTimeout * TIMESTAMP_TO_SECONDS_FACTOR; - if (end <= now && !_reporting_did_timeout) { - // We hit ErrorLogTimeout and we haven't interrupted the reporting - // thread yet. - _reporting_did_timeout = true; - interrupt_reporting_thread(); - return true; // global timeout + + // Global timeout hit? + if (!ignore_global_timeout) { + const jlong reporting_start_time = get_reporting_start_time(); + // Timestamp is stored in nanos. + if (reporting_start_time > 0) { + const jlong end = reporting_start_time + (jlong)ErrorLogTimeout * TIMESTAMP_TO_SECONDS_FACTOR; + if (end <= now && !_reporting_did_timeout) { + // We hit ErrorLogTimeout and we haven't interrupted the reporting + // thread yet. + _reporting_did_timeout = true; + interrupt_reporting_thread(); + return true; // global timeout + } } } - const jlong step_start_time_l = get_step_start_time(); - if (step_start_time_l > 0) { + // Reporting step timeout? + const jlong step_start_time = get_step_start_time(); + if (step_start_time > 0) { // A step times out after a quarter of the total timeout. Steps are mostly fast unless they // hang for some reason, so this simple rule allows for three hanging step and still // hopefully leaves time enough for the rest of the steps to finish. - const jlong end = step_start_time_l + (jlong)ErrorLogTimeout * TIMESTAMP_TO_SECONDS_FACTOR / 4; + const int max_step_timeout_secs = 5; + const jlong timeout_duration = MAX2((jlong)max_step_timeout_secs, (jlong)ErrorLogTimeout * TIMESTAMP_TO_SECONDS_FACTOR / 4); + const jlong end = step_start_time + timeout_duration; if (end <= now && !_step_did_timeout) { // The step timed out and we haven't interrupted the reporting // thread yet. diff -Nru openjdk-17-17.0.7+7~us1/src/hotspot/share/utilities/vmError.hpp openjdk-17-17.0.8+7/src/hotspot/share/utilities/vmError.hpp --- openjdk-17-17.0.7+7~us1/src/hotspot/share/utilities/vmError.hpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/hotspot/share/utilities/vmError.hpp 2023-07-05 07:11:54.000000000 +0000 @@ -99,12 +99,6 @@ static void print_stack_trace(outputStream* st, JavaThread* jt, char* buf, int buflen, bool verbose = false); - // public for use by the internal non-product debugger. - NOT_PRODUCT(public:) - static void print_native_stack(outputStream* st, frame fr, Thread* t, - char* buf, int buf_size); - NOT_PRODUCT(private:) - static bool should_report_bug(unsigned int id) { return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR); } @@ -134,6 +128,12 @@ public: + // print_source_info: if true, we try to resolve the source information on platforms that support it + // (useful but may slow down, timeout or misfunction in error situations) + // max_frames: if not -1, overrides StackPrintLimit + static void print_native_stack(outputStream* st, frame fr, Thread* t, + char* buf, int buf_size); + // return a string to describe the error static char* error_string(char* buf, int buflen); diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/CgroupV1Subsystem.java openjdk-17-17.0.8+7/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/CgroupV1Subsystem.java --- openjdk-17-17.0.7+7~us1/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/CgroupV1Subsystem.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/CgroupV1Subsystem.java 2023-07-05 07:11:54.000000000 +0000 @@ -333,10 +333,6 @@ return getLongValue(memory, "memory.kmem.failcnt"); } - public long getKernelMemoryLimit() { - return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.kmem.limit_in_bytes")); - } - public long getKernelMemoryMaxUsage() { return getLongValue(memory, "memory.kmem.max_usage_in_bytes"); } @@ -349,10 +345,6 @@ return getLongValue(memory, "memory.kmem.tcp.failcnt"); } - public long getTcpMemoryLimit() { - return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.kmem.tcp.limit_in_bytes")); - } - public long getTcpMemoryMaxUsage() { return getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes"); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/linux/classes/jdk/internal/platform/CgroupV1MetricsImpl.java openjdk-17-17.0.8+7/src/java.base/linux/classes/jdk/internal/platform/CgroupV1MetricsImpl.java --- openjdk-17-17.0.7+7~us1/src/java.base/linux/classes/jdk/internal/platform/CgroupV1MetricsImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/linux/classes/jdk/internal/platform/CgroupV1MetricsImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -49,11 +49,6 @@ } @Override - public long getKernelMemoryLimit() { - return metrics.getKernelMemoryLimit(); - } - - @Override public long getKernelMemoryMaxUsage() { return metrics.getKernelMemoryMaxUsage(); } @@ -69,11 +64,6 @@ } @Override - public long getTcpMemoryLimit() { - return metrics.getTcpMemoryLimit(); - } - - @Override public long getTcpMemoryMaxUsage() { return metrics.getTcpMemoryMaxUsage(); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/linux/classes/jdk/internal/platform/CgroupV1Metrics.java openjdk-17-17.0.8+7/src/java.base/linux/classes/jdk/internal/platform/CgroupV1Metrics.java --- openjdk-17-17.0.7+7~us1/src/java.base/linux/classes/jdk/internal/platform/CgroupV1Metrics.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/linux/classes/jdk/internal/platform/CgroupV1Metrics.java 2023-07-05 07:11:54.000000000 +0000 @@ -54,16 +54,6 @@ public long getKernelMemoryFailCount(); /** - * Returns the maximum amount of kernel physical memory, in bytes, that - * can be allocated in the Isolation Group. - * - * @return The maximum amount of memory in bytes or -1 if - * there is no limit set. - * - */ - public long getKernelMemoryLimit(); - - /** * Returns the largest amount of kernel physical memory, in bytes, that * have been allocated in the Isolation Group. * @@ -94,16 +84,6 @@ public long getTcpMemoryFailCount(); /** - * Returns the maximum amount of networking physical memory, in bytes, - * that can be allocated in the Isolation Group. - * - * @return The maximum amount of memory in bytes or -1 if - * there is no limit. - * - */ - public long getTcpMemoryLimit(); - - /** * Returns the largest amount of networking physical memory, in bytes, * that have been allocated in the Isolation Group. * diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/macosx/classes/apple/security/KeychainStore.java openjdk-17-17.0.8+7/src/java.base/macosx/classes/apple/security/KeychainStore.java --- openjdk-17-17.0.7+7~us1/src/java.base/macosx/classes/apple/security/KeychainStore.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/macosx/classes/apple/security/KeychainStore.java 2023-07-05 07:11:54.000000000 +0000 @@ -69,7 +69,7 @@ Certificate cert; long certRef; // SecCertificateRef for this key - // Each KeyStore.TrustedCertificateEntry have 2 attributes: + // Each KeyStore.TrustedCertificateEntry has 2 attributes: // 1. "trustSettings" -> trustSettings.toString() // 2. "2.16.840.1.113894.746875.1.1" -> trustedKeyUsageValue // The 1st one is mainly for debugging use. The 2nd one is similar @@ -660,7 +660,6 @@ _releaseKeychainItemRef(((TrustedCertEntry)entry).certRef); } } else { - Certificate certElem; KeyEntry keyEntry = (KeyEntry)entry; if (keyEntry.chain != null) { @@ -812,8 +811,26 @@ tce.cert = cert; tce.certRef = keychainItemRef; + // Check whether a certificate with same alias already exists and is the same + // If yes, we can return here - the existing entry must have the same + // properties and trust settings + if (entries.contains(alias.toLowerCase())) { + int uniqueVal = 1; + String originalAlias = alias; + var co = entries.get(alias.toLowerCase()); + while (co != null) { + if (co instanceof TrustedCertEntry tco) { + if (tco.cert.equals(tce.cert)) { + return; + } + } + alias = originalAlias + " " + uniqueVal++; + co = entries.get(alias.toLowerCase()); + } + } + tce.trustSettings = new ArrayList<>(); - Map tmpMap = new LinkedHashMap<>(); + Map tmpMap = new LinkedHashMap<>(); for (int i = 0; i < inputTrust.size(); i++) { if (inputTrust.get(i) == null) { tce.trustSettings.add(tmpMap); @@ -836,9 +853,10 @@ } catch (Exception e) { isSelfSigned = false; } + if (tce.trustSettings.isEmpty()) { if (isSelfSigned) { - // If a self-signed certificate has an empty trust settings, + // If a self-signed certificate has trust settings without specific entries, // trust it for all purposes tce.trustedKeyUsageValue = KnownOIDs.anyExtendedKeyUsage.value(); } else { @@ -851,11 +869,19 @@ for (var oneTrust : tce.trustSettings) { var result = oneTrust.get("kSecTrustSettingsResult"); // https://developer.apple.com/documentation/security/sectrustsettingsresult?language=objc - // 1 = kSecTrustSettingsResultTrustRoot, 2 = kSecTrustSettingsResultTrustAsRoot + // 1 = kSecTrustSettingsResultTrustRoot, 2 = kSecTrustSettingsResultTrustAsRoot, + // 3 = kSecTrustSettingsResultDeny // If missing, a default value of kSecTrustSettingsResultTrustRoot is assumed - // for self-signed certificates (see doc for SecTrustSettingsCopyTrustSettings). + // (see doc for SecTrustSettingsCopyTrustSettings). // Note that the same SecPolicyOid can appear in multiple trust settings // for different kSecTrustSettingsAllowedError and/or kSecTrustSettingsPolicyString. + + // If we find explicit distrust in some record, we ignore the certificate + if ("3".equals(result)) { + return; + } + + // Trust, if explicitly trusted or result is null and certificate is self signed if ((result == null && isSelfSigned) || "1".equals(result) || "2".equals(result)) { // When no kSecTrustSettingsPolicy, it means everything @@ -875,20 +901,13 @@ tce.trustedKeyUsageValue = values.toString(); } } + // Make a creation date. if (creationDate != 0) tce.date = new Date(creationDate); else tce.date = new Date(); - int uniqueVal = 1; - String originalAlias = alias; - - while (entries.containsKey(alias.toLowerCase())) { - alias = originalAlias + " " + uniqueVal; - uniqueVal++; - } - entries.put(alias.toLowerCase(), tce); } catch (Exception e) { // The certificate will be skipped. diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m openjdk-17-17.0.8+7/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m --- openjdk-17-17.0.7+7~us1/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m 2023-07-05 07:11:54.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 @@ -285,9 +285,14 @@ OSErr searchResult = noErr; jclass jc_KeychainStore = (*env)->FindClass(env, "apple/security/KeychainStore"); - CHECK_NULL(jc_KeychainStore); + if (jc_KeychainStore == NULL) { + goto errOut; + } jmethodID jm_createKeyEntry = (*env)->GetMethodID(env, jc_KeychainStore, "createKeyEntry", "(Ljava/lang/String;JJ[J[[B)V"); - CHECK_NULL(jm_createKeyEntry); + if (jm_createKeyEntry == NULL) { + goto errOut; + } + do { searchResult = SecIdentitySearchCopyNext(identitySearch, &theIdentity); @@ -376,6 +381,35 @@ #define ADDNULL(list) (*env)->CallBooleanMethod(env, list, jm_listAdd, NULL) + +static void addTrustSettingsToInputTrust(JNIEnv *env, jmethodID jm_listAdd, CFArrayRef trustSettings, jobject inputTrust) +{ + CFIndex count = CFArrayGetCount(trustSettings); + for (int i = 0; i < count; i++) { + CFDictionaryRef oneTrust = (CFDictionaryRef) CFArrayGetValueAtIndex(trustSettings, i); + CFIndex size = CFDictionaryGetCount(oneTrust); + const void * keys [size]; + const void * values [size]; + CFDictionaryGetKeysAndValues(oneTrust, keys, values); + for (int j = 0; j < size; j++) { + NSString* s = [NSString stringWithFormat:@"%@", keys[j]]; + ADD(inputTrust, s); + s = [NSString stringWithFormat:@"%@", values[j]]; + ADD(inputTrust, s); + } + SecPolicyRef certPolicy; + certPolicy = (SecPolicyRef)CFDictionaryGetValue(oneTrust, kSecTrustSettingsPolicy); + if (certPolicy != NULL) { + CFDictionaryRef policyDict = SecPolicyCopyProperties(certPolicy); + ADD(inputTrust, @"SecPolicyOid"); + NSString* s = [NSString stringWithFormat:@"%@", CFDictionaryGetValue(policyDict, @"SecPolicyOid")]; + ADD(inputTrust, s); + CFRelease(policyDict); + } + ADDNULL(inputTrust); + } +} + static void addCertificatesToKeystore(JNIEnv *env, jobject keyStore) { // Search the user keychain list for all X509 certificates. @@ -385,16 +419,30 @@ OSErr searchResult = noErr; jclass jc_KeychainStore = (*env)->FindClass(env, "apple/security/KeychainStore"); - CHECK_NULL(jc_KeychainStore); + if (jc_KeychainStore == NULL) { + goto errOut; + } + jmethodID jm_createTrustedCertEntry = (*env)->GetMethodID( env, jc_KeychainStore, "createTrustedCertEntry", "(Ljava/lang/String;Ljava/util/List;JJ[B)V"); - CHECK_NULL(jm_createTrustedCertEntry); + if (jm_createTrustedCertEntry == NULL) { + goto errOut; + } + jclass jc_arrayListClass = (*env)->FindClass(env, "java/util/ArrayList"); - CHECK_NULL(jc_arrayListClass); + if (jc_arrayListClass == NULL) { + goto errOut; + } + jmethodID jm_arrayListCons = (*env)->GetMethodID(env, jc_arrayListClass, "", "()V"); - CHECK_NULL(jm_arrayListCons); + if (jm_arrayListCons == NULL) { + goto errOut; + } + jmethodID jm_listAdd = (*env)->GetMethodID(env, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z"); - CHECK_NULL(jm_listAdd); + if (jm_listAdd == NULL) { + goto errOut; + } do { searchResult = SecKeychainSearchCopyNext(keychainItemSearch, &theItem); @@ -416,43 +464,40 @@ goto errOut; } - // Only add certificates with trusted settings - CFArrayRef trustSettings; - if (SecTrustSettingsCopyTrustSettings(certRef, kSecTrustSettingsDomainUser, &trustSettings) - == errSecItemNotFound) { - continue; - } - // See KeychainStore::createTrustedCertEntry for content of inputTrust - jobject inputTrust = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons); - CHECK_NULL(inputTrust); - - // Dump everything inside trustSettings into inputTrust - CFIndex count = CFArrayGetCount(trustSettings); - for (int i = 0; i < count; i++) { - CFDictionaryRef oneTrust = (CFDictionaryRef) CFArrayGetValueAtIndex(trustSettings, i); - CFIndex size = CFDictionaryGetCount(oneTrust); - const void * keys [size]; - const void * values [size]; - CFDictionaryGetKeysAndValues(oneTrust, keys, values); - for (int j = 0; j < size; j++) { - NSString* s = [NSString stringWithFormat:@"%@", keys[j]]; - ADD(inputTrust, s); - s = [NSString stringWithFormat:@"%@", values[j]]; - ADD(inputTrust, s); + // We load trust settings from domains kSecTrustSettingsDomainUser and kSecTrustSettingsDomainAdmin + // kSecTrustSettingsDomainSystem is ignored because it seems to only contain data for root certificates + jobject inputTrust = NULL; + CFArrayRef trustSettings = NULL; + + // Load user trustSettings into inputTrust + if (SecTrustSettingsCopyTrustSettings(certRef, kSecTrustSettingsDomainUser, &trustSettings) == errSecSuccess && trustSettings != NULL) { + inputTrust = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons); + if (inputTrust == NULL) { + CFRelease(trustSettings); + goto errOut; } - SecPolicyRef certPolicy; - certPolicy = (SecPolicyRef)CFDictionaryGetValue(oneTrust, kSecTrustSettingsPolicy); - if (certPolicy != NULL) { - CFDictionaryRef policyDict = SecPolicyCopyProperties(certPolicy); - ADD(inputTrust, @"SecPolicyOid"); - NSString* s = [NSString stringWithFormat:@"%@", CFDictionaryGetValue(policyDict, @"SecPolicyOid")]; - ADD(inputTrust, s); - CFRelease(policyDict); + addTrustSettingsToInputTrust(env, jm_listAdd, trustSettings, inputTrust); + CFRelease(trustSettings); + } + // Load admin trustSettings into inputTrust + trustSettings = NULL; + if (SecTrustSettingsCopyTrustSettings(certRef, kSecTrustSettingsDomainAdmin, &trustSettings) == errSecSuccess && trustSettings != NULL) { + if (inputTrust == NULL) { + inputTrust = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons); } - ADDNULL(inputTrust); + if (inputTrust == NULL) { + CFRelease(trustSettings); + goto errOut; + } + addTrustSettingsToInputTrust(env, jm_listAdd, trustSettings, inputTrust); + CFRelease(trustSettings); + } + + // Only add certificates with trust settings + if (inputTrust == NULL) { + continue; } - CFRelease(trustSettings); // Find the creation date. jlong creationDate = getModDateFromItem(env, theItem); diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/ClassLoader.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/ClassLoader.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/ClassLoader.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/ClassLoader.java 2023-07-05 07:11:54.000000000 +0000 @@ -406,6 +406,11 @@ return nid; } + // Returns nameAndId string for exception message printing + String nameAndId() { + return nameAndId; + } + /** * Creates a new class loader of the specified name and using the * specified parent class loader for delegation. diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/reflect/Proxy.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/reflect/Proxy.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/reflect/Proxy.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/reflect/Proxy.java 2023-07-05 07:11:54.000000000 +0000 @@ -881,7 +881,7 @@ } if (type != c) { throw new IllegalArgumentException(c.getName() + - " referenced from a method is not visible from class loader"); + " referenced from a method is not visible from class loader: " + JLA.getLoaderNameID(ld)); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/String.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/String.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/String.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/String.java 2023-07-05 07:11:54.000000000 +0000 @@ -660,7 +660,13 @@ offset = 0; } - int caLen = decodeWithDecoder(cd, ca, bytes, offset, length); + int caLen; + try { + caLen = decodeWithDecoder(cd, ca, bytes, offset, length); + } catch (CharacterCodingException x) { + // Substitution is enabled, so this shouldn't happen + throw new Error(x); + } if (COMPACT_STRINGS) { byte[] bs = StringUTF16.compress(ca, 0, caLen); if (bs != null) { @@ -781,7 +787,13 @@ System.getSecurityManager() != null) { src = Arrays.copyOf(src, len); } - int caLen = decodeWithDecoder(cd, ca, src, 0, src.length); + int caLen; + try { + caLen = decodeWithDecoder(cd, ca, src, 0, src.length); + } catch (CharacterCodingException x) { + // throw via IAE + throw new IllegalArgumentException(x); + } if (COMPACT_STRINGS) { byte[] bs = StringUTF16.compress(ca, 0, caLen); if (bs != null) { @@ -835,7 +847,8 @@ CharsetEncoder ce = cs.newEncoder(); int len = val.length >> coder; // assume LATIN1=0/UTF16=1; int en = scale(len, ce.maxBytesPerChar()); - if (ce instanceof ArrayEncoder ae) { + // fastpath with ArrayEncoder implies `doReplace`. + if (doReplace && ce instanceof ArrayEncoder ae) { // fastpath for ascii compatible if (coder == LATIN1 && ae.isASCIICompatible() && @@ -846,10 +859,6 @@ if (len == 0) { return ba; } - if (doReplace) { - ce.onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - } int blen = (coder == LATIN1) ? ae.encodeFromLatin1(val, 0, len, ba) : ae.encodeFromUTF16(val, 0, len, ba); @@ -1194,21 +1203,16 @@ return dp; } - private static int decodeWithDecoder(CharsetDecoder cd, char[] dst, byte[] src, int offset, int length) { + private static int decodeWithDecoder(CharsetDecoder cd, char[] dst, byte[] src, int offset, int length) + throws CharacterCodingException { ByteBuffer bb = ByteBuffer.wrap(src, offset, length); CharBuffer cb = CharBuffer.wrap(dst, 0, dst.length); - try { - CoderResult cr = cd.decode(bb, cb, true); - if (!cr.isUnderflow()) - cr.throwException(); - cr = cd.flush(cb); - if (!cr.isUnderflow()) - cr.throwException(); - } catch (CharacterCodingException x) { - // Substitution is always enabled, - // so this shouldn't happen - throw new Error(x); - } + CoderResult cr = cd.decode(bb, cb, true); + if (!cr.isUnderflow()) + cr.throwException(); + cr = cd.flush(cb); + if (!cr.isUnderflow()) + cr.throwException(); return cb.position(); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/System.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/System.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/lang/System.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/lang/System.java 2023-07-05 07:11:54.000000000 +0000 @@ -2451,6 +2451,10 @@ public void exit(int statusCode) { Shutdown.exit(statusCode); } + + public String getLoaderNameID(ClassLoader loader) { + return loader.nameAndId(); + } }); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template openjdk-17-17.0.8+7/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -134,7 +134,14 @@ } else { address = base; } - cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); + try { + cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); + } catch (Throwable t) { + // Prevent leak if the Deallocator or Cleaner fail for any reason + UNSAFE.freeMemory(base); + Bits.unreserveMemory(size, cap); + throw t; + } att = null; #else[rw] super(cap); diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/security/Provider.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/security/Provider.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/security/Provider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/security/Provider.java 2023-07-05 07:11:54.000000000 +0000 @@ -25,6 +25,8 @@ package java.security; +import jdk.internal.event.SecurityProviderServiceEvent; + import java.io.*; import java.util.*; import static java.util.Locale.ENGLISH; @@ -1234,19 +1236,28 @@ key = new ServiceKey(type, algorithm, false); previousKey = key; } + Service s = null; if (!serviceMap.isEmpty()) { - Service s = serviceMap.get(key); - if (s != null) { - return s; - } + s = serviceMap.get(key); } - synchronized (this) { - ensureLegacyParsed(); - if (legacyMap != null && !legacyMap.isEmpty()) { - return legacyMap.get(key); + if (s == null) { + synchronized (this) { + ensureLegacyParsed(); + if (legacyMap != null && !legacyMap.isEmpty()) { + s = legacyMap.get(key); + } } } - return null; + + if (s != null && SecurityProviderServiceEvent.isTurnedOn()) { + var e = new SecurityProviderServiceEvent(); + e.provider = getName(); + e.type = type; + e.algorithm = algorithm; + e.commit(); + } + + return s; } // ServiceKey from previous getService() call diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java 2023-07-05 07:11:54.000000000 +0000 @@ -4321,8 +4321,10 @@ if (length >= position + 3 && context.charEquals(text.charAt(position + 2), 'C')) { // There are localized zone texts that start with "UTC", e.g. // "UTC\u221210:00" (MINUS SIGN instead of HYPHEN-MINUS) in French. - // Exclude those ZoneText cases. - if (!(this instanceof ZoneTextPrinterParser)) { + // Exclude those cases. + if (length == position + 3 || + context.charEquals(text.charAt(position + 3), '+') || + context.charEquals(text.charAt(position + 3), '-')) { return parseOffsetBased(context, text, position, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); } } else { diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java 2023-07-05 07:11:54.000000000 +0000 @@ -2759,8 +2759,10 @@ ForkJoinTask.cancelIgnoringExceptions(f); else { ((ForkJoinTask)f).awaitPoolInvoke(this, ns); - if ((ns = nanos - (System.nanoTime() - startTime)) < 0L) + if ((ns = nanos - (System.nanoTime() - startTime)) < 0L) { timedOut = true; + ForkJoinTask.cancelIgnoringExceptions(f); + } } } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java 2023-07-05 07:11:54.000000000 +0000 @@ -422,6 +422,10 @@ public long nextLong() { return ThreadLocalRandom.current().nextLong(); } + + public double nextDouble() { + return ThreadLocalRandom.current().nextDouble(); + } } /** diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/jar/JarFile.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/jar/JarFile.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/jar/JarFile.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/jar/JarFile.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import jdk.internal.access.JavaUtilZipFileAccess; import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; +import sun.security.util.SignatureFileVerifier; import java.io.ByteArrayInputStream; import java.io.EOFException; @@ -151,8 +152,6 @@ private static final boolean MULTI_RELEASE_ENABLED; private static final boolean MULTI_RELEASE_FORCED; private static final ThreadLocal isInitializing = new ThreadLocal<>(); - // The maximum size of array to allocate. Some VMs reserve some header words in an array. - private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private SoftReference manRef; private JarEntry manEntry; @@ -800,8 +799,11 @@ private byte[] getBytes(ZipEntry ze) throws IOException { try (InputStream is = super.getInputStream(ze)) { long uncompressedSize = ze.getSize(); - if (uncompressedSize > MAX_ARRAY_SIZE) { - throw new IOException("Unsupported size: " + uncompressedSize); + if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) { + throw new IOException("Unsupported size: " + uncompressedSize + + " for JarEntry " + ze.getName() + + ". Allowed max size: " + + SignatureFileVerifier.MAX_SIG_FILE_SIZE + " bytes"); } int len = (int)uncompressedSize; int bytesRead; diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/zip/ZipFile.java openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/zip/ZipFile.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/java/util/zip/ZipFile.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/java/util/zip/ZipFile.java 2023-07-05 07:11:54.000000000 +0000 @@ -69,6 +69,7 @@ import jdk.internal.ref.CleanerFactory; import jdk.internal.vm.annotation.Stable; import sun.nio.cs.UTF_8; +import sun.security.action.GetBooleanAction; import sun.security.util.SignatureFileVerifier; import static java.util.zip.ZipConstants64.*; @@ -122,6 +123,12 @@ public static final int OPEN_DELETE = 0x4; /** + * Flag which specifies whether the validation of the Zip64 extra + * fields should be disabled + */ + private static final boolean disableZip64ExtraFieldValidation = + GetBooleanAction.privilegedGetProperty("jdk.util.zip.disableZip64ExtraFieldValidation"); + /** * Opens a zip file for reading. * *

First, if there is a security manager, its {@code checkRead} @@ -1195,6 +1202,16 @@ if (entryPos + nlen > cen.length - ENDHDR) { zerror("invalid CEN header (bad header size)"); } + + int elen = CENEXT(cen, pos); + if (elen > 0 && !disableZip64ExtraFieldValidation) { + long extraStartingOffset = pos + CENHDR + nlen; + if ((int)extraStartingOffset != extraStartingOffset) { + zerror("invalid CEN header (bad extra offset)"); + } + checkExtraFields(pos, (int)extraStartingOffset, elen); + } + try { ZipCoder zcp = zipCoderForPos(pos); int hash = zcp.checkedHash(cen, entryPos, nlen); @@ -1211,6 +1228,119 @@ return nlen; } + /** + * Validate the Zip64 Extra block fields + * @param startingOffset Extra Field starting offset within the CEN + * @param extraFieldLen Length of this Extra field + * @throws ZipException If an error occurs validating the Zip64 Extra + * block + */ + private void checkExtraFields(int cenPos, int startingOffset, + int extraFieldLen) throws ZipException { + // Extra field Length cannot exceed 65,535 bytes per the PKWare + // APP.note 4.4.11 + if (extraFieldLen > 0xFFFF) { + zerror("invalid extra field length"); + } + // CEN Offset where this Extra field ends + int extraEndOffset = startingOffset + extraFieldLen; + if (extraEndOffset > cen.length) { + zerror("Invalid CEN header (extra data field size too long)"); + } + int currentOffset = startingOffset; + while (currentOffset < extraEndOffset) { + int tag = get16(cen, currentOffset); + currentOffset += Short.BYTES; + + int tagBlockSize = get16(cen, currentOffset); + int tagBlockEndingOffset = currentOffset + tagBlockSize; + + // The ending offset for this tag block should not go past the + // offset for the end of the extra field + if (tagBlockEndingOffset > extraEndOffset) { + zerror("Invalid CEN header (invalid zip64 extra data field size)"); + } + currentOffset += Short.BYTES; + + if (tag == ZIP64_EXTID) { + // Get the compressed size; + long csize = CENSIZ(cen, cenPos); + // Get the uncompressed size; + long size = CENLEN(cen, cenPos); + checkZip64ExtraFieldValues(currentOffset, tagBlockSize, + csize, size); + } + currentOffset += tagBlockSize; + } + } + + /** + * Validate the Zip64 Extended Information Extra Field (0x0001) block + * size and that the uncompressed size and compressed size field + * values are not negative. + * Note: As we do not use the LOC offset or Starting disk number + * field value we will not validate them + * @param off the starting offset for the Zip64 field value + * @param blockSize the size of the Zip64 Extended Extra Field + * @param csize CEN header compressed size value + * @param size CEN header uncompressed size value + * @throws ZipException if an error occurs + */ + private void checkZip64ExtraFieldValues(int off, int blockSize, long csize, + long size) + throws ZipException { + byte[] cen = this.cen; + // Validate the Zip64 Extended Information Extra Field (0x0001) + // length. + if (!isZip64ExtBlockSizeValid(blockSize)) { + zerror("Invalid CEN header (invalid zip64 extra data field size)"); + } + // Check the uncompressed size is not negative + // Note we do not need to check blockSize is >= 8 as + // we know its length is at least 8 from the call to + // isZip64ExtBlockSizeValid() + if ((size == ZIP64_MAGICVAL)) { + if(get64(cen, off) < 0) { + zerror("Invalid zip64 extra block size value"); + } + } + // Check the compressed size is not negative + if ((csize == ZIP64_MAGICVAL) && (blockSize >= 16)) { + if (get64(cen, off + 8) < 0) { + zerror("Invalid zip64 extra block compressed size value"); + } + } + } + + /** + * Validate the size and contents of a Zip64 extended information field + * The order of the Zip64 fields is fixed, but the fields MUST + * only appear if the corresponding LOC or CEN field is set to 0xFFFF: + * or 0xFFFFFFFF: + * Uncompressed Size - 8 bytes + * Compressed Size - 8 bytes + * LOC Header offset - 8 bytes + * Disk Start Number - 4 bytes + * See PKWare APP.Note Section 4.5.3 for more details + * + * @param blockSize the Zip64 Extended Information Extra Field size + * @return true if the extra block size is valid; false otherwise + */ + private static boolean isZip64ExtBlockSizeValid(int blockSize) { + /* + * As the fields must appear in order, the block size indicates which + * fields to expect: + * 8 - uncompressed size + * 16 - uncompressed size, compressed size + * 24 - uncompressed size, compressed sise, LOC Header offset + * 28 - uncompressed size, compressed sise, LOC Header offset, + * and Disk start number + */ + return switch(blockSize) { + case 8, 16, 24, 28 -> true; + default -> false; + }; + } private int getEntryHash(int index) { return entries[index]; } private int getEntryNext(int index) { return entries[index + 1]; } private int getEntryPos(int index) { return entries[index + 2]; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/javax/crypto/JceSecurity.java.template openjdk-17-17.0.8+7/src/java.base/share/classes/javax/crypto/JceSecurity.java.template --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/javax/crypto/JceSecurity.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/javax/crypto/JceSecurity.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -235,7 +235,11 @@ // return whether this provider is properly signed and can be used by JCE static boolean canUseProvider(Provider p) { - return getVerificationResult(p) == null; + Exception e = getVerificationResult(p); + if (debug != null && e != null) { + debug.println("Provider verification result: " + e); + } + return e == null; } // dummy object to represent null diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java openjdk-17-17.0.8+7/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java 2023-07-05 07:11:54.000000000 +0000 @@ -410,4 +410,10 @@ * @param statusCode the status code */ void exit(int statusCode); + + /** + * Returns '' @ if classloader has a name + * explicitly set otherwise @ + */ + String getLoaderNameID(ClassLoader loader); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/jdk/internal/event/SecurityProviderServiceEvent.java openjdk-17-17.0.8+7/src/java.base/share/classes/jdk/internal/event/SecurityProviderServiceEvent.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/jdk/internal/event/SecurityProviderServiceEvent.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/jdk/internal/event/SecurityProviderServiceEvent.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.event; + +/** + * Event recording details of Provider.getService(String type, String algorithm) calls + */ + +public final class SecurityProviderServiceEvent extends Event { + private final static SecurityProviderServiceEvent EVENT = new SecurityProviderServiceEvent(); + + /** + * Returns {@code true} if event is enabled, {@code false} otherwise. + */ + public static boolean isTurnedOn() { + return EVENT.isEnabled(); + } + + public String type; + public String algorithm; + public String provider; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/jdk/internal/misc/Unsafe.java openjdk-17-17.0.8+7/src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2023-07-05 07:11:54.000000000 +0000 @@ -3436,16 +3436,14 @@ * Ensures that stores before the fence will not be reordered with * stores after the fence. * - * @implNote - * This method is operationally equivalent to {@link #storeFence()}. - * * @since 9 */ + @IntrinsicCandidate public final void storeStoreFence() { + // If storeStoreFence intrinsic is not available, fall back to storeFence. storeFence(); } - /** * Throws IllegalAccessError; for use by the VM for access control * error support. diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/HeaderParser.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/HeaderParser.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/HeaderParser.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/HeaderParser.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package sun.net.www; import java.util.Iterator; +import java.util.OptionalInt; /* This is useful for the nightmare of parsing multi-part HTTP/RFC822 headers * sensibly: @@ -246,6 +247,19 @@ return Default; } } + + public OptionalInt findInt(String k) { + try { + String s = findValue(k); + if (s == null) { + return OptionalInt.empty(); + } + return OptionalInt.of(Integer.parseInt(s)); + } catch (Throwable t) { + return OptionalInt.empty(); + } + } + /* public static void main(String[] a) throws Exception { System.out.print("enter line to parse> "); diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/http/HttpClient.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/http/HttpClient.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/http/HttpClient.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/http/HttpClient.java 2023-07-05 07:11:54.000000000 +0000 @@ -29,6 +29,7 @@ import java.net.*; import java.util.Locale; import java.util.Objects; +import java.util.OptionalInt; import java.util.Properties; import java.util.concurrent.locks.ReentrantLock; @@ -127,6 +128,7 @@ * 0: the server specified no keep alive headers * -1: the server provided "Connection: keep-alive" but did not specify a * a particular time in a "Keep-Alive:" headers + * -2: the server provided "Connection: keep-alive" and timeout=0 * Positive values are the number of seconds specified by the server * in a "Keep-Alive" header */ @@ -897,7 +899,23 @@ responses.findValue("Keep-Alive")); /* default should be larger in case of proxy */ keepAliveConnections = p.findInt("max", usingProxy?50:5); - keepAliveTimeout = p.findInt("timeout", -1); + if (keepAliveConnections < 0) { + keepAliveConnections = usingProxy?50:5; + } + OptionalInt timeout = p.findInt("timeout"); + if (timeout.isEmpty()) { + keepAliveTimeout = -1; + } else { + keepAliveTimeout = timeout.getAsInt(); + if (keepAliveTimeout < 0) { + // if the server specified a negative (invalid) value + // then we set to -1, which is equivalent to no value + keepAliveTimeout = -1; + } else if (keepAliveTimeout == 0) { + // handled specially to mean close connection immediately + keepAliveTimeout = -2; + } + } } } else if (b[7] != '0') { /* diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java 2023-07-05 07:11:54.000000000 +0000 @@ -172,6 +172,8 @@ // different default for server and proxy keepAliveTimeout = http.getUsingProxy() ? 60 : 5; } + } else if (keepAliveTimeout == -2) { + keepAliveTimeout = 0; } // at this point keepAliveTimeout is the number of seconds to keep // alive, which could be 0, if the user specified 0 for the property diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java 2023-07-05 07:11:54.000000000 +0000 @@ -528,4 +528,13 @@ s2 = new String (pw.getPassword()); s.defaultWriteObject (); } + + /** + * Releases any system or cryptographic resources. + * It is up to implementors to override disposeContext() + * to take necessary action. + */ + public void disposeContext() { + // do nothing + } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java 2023-07-05 07:11:54.000000000 +0000 @@ -2029,6 +2029,12 @@ if (serverAuthKey != null) { AuthenticationInfo.endAuthRequest(serverAuthKey); } + if (proxyAuthentication != null) { + proxyAuthentication.disposeContext(); + } + if (serverAuthentication != null) { + serverAuthentication.disposeContext(); + } } } @@ -2274,6 +2280,9 @@ if (proxyAuthKey != null) { AuthenticationInfo.endAuthRequest(proxyAuthKey); } + if (proxyAuthentication != null) { + proxyAuthentication.disposeContext(); + } } // restore original request headers @@ -2525,6 +2534,7 @@ } if (ret != null) { if (!ret.setHeaders(this, p, raw)) { + ret.disposeContext(); ret = null; } } @@ -2699,6 +2709,7 @@ if (ret != null ) { if (!ret.setHeaders(this, p, raw)) { + ret.disposeContext(); ret = null; } } @@ -2725,6 +2736,7 @@ DigestAuthentication da = (DigestAuthentication) currentProxyCredentials; da.checkResponse (raw, method, getRequestURI()); + currentProxyCredentials.disposeContext(); currentProxyCredentials = null; } } @@ -2735,6 +2747,7 @@ DigestAuthentication da = (DigestAuthentication) currentServerCredentials; da.checkResponse (raw, method, url); + currentServerCredentials.disposeContext(); currentServerCredentials = null; } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java 2023-07-05 07:11:54.000000000 +0000 @@ -245,6 +245,22 @@ return negotiator.nextToken(token); } + /** + * Releases any system resources and cryptographic information stored in + * the context object and invalidates the context. + */ + @Override + public void disposeContext() { + if (negotiator != null) { + try { + negotiator.disposeContext(); + } catch (IOException ioEx) { + //do not rethrow IOException + } + negotiator = null; + } + } + // MS will send a final WWW-Authenticate even if the status is already // 200 OK. The token can be fed into initSecContext() again to determine // if the server can be trusted. This is not the same concept as Digest's diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java 2023-07-05 07:11:54.000000000 +0000 @@ -82,5 +82,7 @@ logger.finest("NegotiateAuthentication: " + e); } } + + public void disposeContext() throws IOException { }; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java 2023-07-05 07:11:54.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 @@ -177,6 +177,11 @@ millis = -1; } else { millis = NANOSECONDS.toMillis(nanos); + if (nanos > MILLISECONDS.toNanos(millis)) { + // Round up any excess nanos to the nearest millisecond to + // avoid parking for less than requested. + millis++; + } } Net.poll(fd, event, millis); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/ch/SelChImpl.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/ch/SelChImpl.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/ch/SelChImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/ch/SelChImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, 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 @@ -29,6 +29,7 @@ import java.io.FileDescriptor; import java.io.IOException; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; /** @@ -88,6 +89,11 @@ millis = -1; } else { millis = NANOSECONDS.toMillis(nanos); + if (nanos > MILLISECONDS.toNanos(millis)) { + // Round up any excess nanos to the nearest millisecond to + // avoid parking for less than requested. + millis++; + } } Net.poll(getFD(), event, millis); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/cs/GB18030.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/cs/GB18030.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/cs/GB18030.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/cs/GB18030.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,12839 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + */ + +package sun.nio.cs; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import jdk.internal.misc.VM; +import sun.nio.cs.Surrogate; +import sun.security.action.GetPropertyAction; + +public class GB18030 + extends Charset +{ + private static final int GB18030_SINGLE_BYTE = 1; + private static final int GB18030_DOUBLE_BYTE = 2; + private static final int GB18030_FOUR_BYTE = 3; + + // Assumes non-2000 standard if initialized during System.initPhase1(), + // as the system property is not ready to be read in that case. + static final boolean IS_2000 = + VM.initLevel() >= 1 && + "2000".equals(GetPropertyAction.privilegedGetProperty("jdk.charset.GB18030", "")); + + public GB18030() { + super("GB18030", StandardCharsets.aliases_GB18030()); + } + + public boolean contains(Charset cs) { + return ((cs.name().equals("US-ASCII")) + || (cs.name().equals("GBK")) + || (cs.name().equals("ISO-8859-1")) + || (cs.name().equals("ISO-8859-2")) + || (cs.name().equals("ISO-8859-3")) + || (cs.name().equals("ISO-8859-4")) + || (cs.name().equals("ISO-8859-5")) + || (cs.name().equals("ISO-8859-6")) + || (cs.name().equals("ISO-8859-7")) + || (cs.name().equals("ISO-8859-8")) + || (cs.name().equals("ISO-8859-9")) + || (cs.name().equals("ISO-8859-13")) + || (cs.name().equals("ISO-8859-15")) + || (cs.name().equals("ISO-8859-16")) + || (cs.name().equals("UTF-8")) + || (cs.name().equals("UTF-16")) + || (cs.name().equals("UTF-16LE")) + || (cs.name().equals("UTF-16BE")) + || (cs.name().equals("windows-1251")) + || (cs.name().equals("windows-1252")) + || (cs.name().equals("windows-1253")) + || (cs.name().equals("windows-1254")) + || (cs.name().equals("windows-1255")) + || (cs.name().equals("windows-1256")) + || (cs.name().equals("windows-1257")) + || (cs.name().equals("windows-1258")) + || (cs.name().equals("windows-932")) + || (cs.name().equals("x-mswin-936")) + || (cs.name().equals("x-windows-949")) + || (cs.name().equals("x-windows-950")) + || (cs.name().equals("windows-31j")) + || (cs.name().equals("JIS_X0201")) + || (cs.name().equals("JIS_X0208-1990")) + || (cs.name().equals("JIS_X0212")) + || (cs.name().equals("Shift_JIS")) + || (cs.name().equals("GB2312")) + || (cs.name().equals("EUC-KR")) + || (cs.name().equals("x-EUC-TW")) + || (cs.name().equals("EUC-JP")) + || (cs.name().equals("euc-jp-linux")) + || (cs.name().equals("KOI8-R")) + || (cs.name().equals("TIS-620")) + || (cs.name().equals("x-ISCII91")) + || (cs.name().equals("Big5")) + || (cs.name().equals("Big5-HKSCS")) + || (cs.name().equals("x-MS950-HKSCS")) + || (cs.name().equals("ISO-2022-JP")) + || (cs.name().equals("ISO-2022-KR")) + || (cs.name().equals("x-ISO-2022-CN-CNS")) + || (cs.name().equals("x-ISO-2022-CN-GB")) + || (cs.name().equals("x-Johab")) + || (cs instanceof GB18030)); + } + + public CharsetDecoder newDecoder() { + return new Decoder(this); + } + + public CharsetEncoder newEncoder() { + return new Encoder(this); + } + + private static final String innerDecoderIndex0= + "\u0080"+ + "\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088"+ + "\u0089\u008A\u008B\u008C\u008D\u008E\u008F\u0090"+ + "\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098"+ + "\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0"+ + "\u00A1\u00A2\u00A3\u00A5\u00A6\u00A9\u00AA\u00AB"+ + "\u00AC\u00AD\u00AE\u00AF\u00B2\u00B3\u00B4\u00B5"+ + "\u00B6\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE"+ + "\u00BF\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6"+ + "\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE"+ + "\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6"+ + "\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF"+ + "\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00EB\u00EE"+ + "\u00EF\u00F0\u00F1\u00F4\u00F5\u00F6\u00F8\u00FB"+ + "\u00FD\u00FE\u00FF\u0100\u0102\u0103\u0104\u0105"+ + "\u0106\u0107\u0108\u0109\u010A\u010B\u010C\u010D"+ + "\u010E\u010F\u0110\u0111\u0112\u0114\u0115\u0116"+ + "\u0117\u0118\u0119\u011A\u011C\u011D\u011E\u011F"+ + "\u0120\u0121\u0122\u0123\u0124\u0125\u0126\u0127"+ + "\u0128\u0129\u012A\u012C\u012D\u012E\u012F\u0130"+ + "\u0131\u0132\u0133\u0134\u0135\u0136\u0137\u0138"+ + "\u0139\u013A\u013B\u013C\u013D\u013E\u013F\u0140"+ + "\u0141\u0142\u0143\u0145\u0146\u0147\u0149\u014A"+ + "\u014B\u014C\u014E\u014F\u0150\u0151\u0152\u0153"+ + "\u0154\u0155\u0156\u0157\u0158\u0159\u015A\u015B"+ + "\u015C\u015D\u015E\u015F\u0160\u0161\u0162\u0163"+ + "\u0164\u0165\u0166\u0167\u0168\u0169\u016A\u016C"+ + "\u016D\u016E\u016F\u0170\u0171\u0172\u0173\u0174"+ + "\u0175\u0176\u0177\u0178\u0179\u017A\u017B\u017C"+ + "\u017D\u017E\u017F\u0180\u0181\u0182\u0183\u0184"+ + "\u0185\u0186\u0187\u0188\u0189\u018A\u018B\u018C"+ + "\u018D\u018E\u018F\u0190\u0191\u0192\u0193\u0194"+ + "\u0195\u0196\u0197\u0198\u0199\u019A\u019B"+ + "\u019C\u019D\u019E\u019F\u01A0\u01A1\u01A2\u01A3"+ + "\u01A4\u01A5\u01A6\u01A7\u01A8\u01A9\u01AA\u01AB"+ + "\u01AC\u01AD\u01AE\u01AF\u01B0\u01B1\u01B2\u01B3"+ + "\u01B4\u01B5\u01B6\u01B7\u01B8\u01B9\u01BA\u01BB"+ + "\u01BC\u01BD\u01BE\u01BF\u01C0\u01C1\u01C2\u01C3"+ + "\u01C4\u01C5\u01C6\u01C7\u01C8\u01C9\u01CA\u01CB"+ + "\u01CC\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9"+ + "\u01DB\u01DD\u01DE\u01DF\u01E0\u01E1\u01E2\u01E3"+ + "\u01E4\u01E5\u01E6\u01E7\u01E8\u01E9\u01EA\u01EB"+ + "\u01EC\u01ED\u01EE\u01EF\u01F0\u01F1\u01F2\u01F3"+ + "\u01F4\u01F5\u01F6\u01F7\u01F8\u01FA\u01FB\u01FC"+ + "\u01FD\u01FE\u01FF\u0200\u0201\u0202\u0203\u0204"+ + "\u0205\u0206\u0207\u0208\u0209\u020A\u020B\u020C"+ + "\u020D\u020E\u020F\u0210\u0211\u0212\u0213\u0214"+ + "\u0215\u0216\u0217\u0218\u0219\u021A\u021B\u021C"+ + "\u021D\u021E\u021F\u0220\u0221\u0222\u0223\u0224"+ + "\u0225\u0226\u0227\u0228\u0229\u022A\u022B\u022C"+ + "\u022D\u022E\u022F\u0230\u0231\u0232\u0233\u0234"+ + "\u0235\u0236\u0237\u0238\u0239\u023A\u023B\u023C"+ + "\u023D\u023E\u023F\u0240\u0241\u0242\u0243\u0244"+ + "\u0245\u0246\u0247\u0248\u0249\u024A\u024B\u024C"+ + "\u024D\u024E\u024F\u0250\u0252\u0253\u0254\u0255"+ + "\u0256\u0257\u0258\u0259\u025A\u025B\u025C\u025D"+ + "\u025E\u025F\u0260\u0262\u0263\u0264\u0265\u0266"+ + "\u0267\u0268\u0269\u026A\u026B\u026C\u026D\u026E"+ + "\u026F\u0270\u0271\u0272\u0273\u0274\u0275\u0276"+ + "\u0277\u0278\u0279\u027A\u027B\u027C\u027D\u027E"+ + "\u027F\u0280\u0281\u0282\u0283\u0284\u0285\u0286"+ + "\u0287\u0288\u0289\u028A\u028B\u028C\u028D\u028E"+ + "\u028F\u0290\u0291\u0292\u0293\u0294\u0295\u0296"+ + "\u0297\u0298\u0299\u029A\u029B\u029C\u029D\u029E"+ + "\u029F\u02A0\u02A1\u02A2\u02A3\u02A4\u02A5\u02A6"+ + "\u02A7\u02A8\u02A9\u02AA\u02AB\u02AC\u02AD\u02AE"+ + "\u02AF\u02B0\u02B1\u02B2\u02B3\u02B4\u02B5\u02B6"+ + "\u02B7\u02B8\u02B9\u02BA\u02BB\u02BC\u02BD\u02BE"+ + "\u02BF\u02C0\u02C1\u02C2\u02C3\u02C4\u02C5\u02C6"+ + "\u02C8\u02CC\u02CD\u02CE\u02CF\u02D0\u02D1\u02D2"+ + "\u02D3\u02D4\u02D5\u02D6\u02D7\u02D8\u02DA\u02DB"+ + "\u02DC\u02DD\u02DE\u02DF\u02E0\u02E1\u02E2\u02E3"+ + "\u02E4\u02E5\u02E6\u02E7\u02E8\u02E9\u02EA\u02EB"+ + "\u02EC\u02ED\u02EE\u02EF\u02F0\u02F1\u02F2\u02F3"+ + "\u02F4\u02F5\u02F6\u02F7\u02F8\u02F9\u02FA\u02FB"+ + "\u02FC\u02FD\u02FE\u02FF\u0300\u0301\u0302\u0303"+ + "\u0304\u0305\u0306\u0307\u0308\u0309\u030A\u030B"+ + "\u030C\u030D\u030E\u030F\u0310\u0311\u0312\u0313"+ + "\u0314\u0315\u0316\u0317\u0318\u0319\u031A\u031B"+ + "\u031C\u031D\u031E\u031F\u0320\u0321\u0322\u0323"+ + "\u0324\u0325\u0326\u0327\u0328\u0329\u032A\u032B"+ + "\u032C\u032D\u032E\u032F\u0330\u0331\u0332\u0333"+ + "\u0334\u0335\u0336\u0337\u0338\u0339\u033A\u033B"+ + "\u033C\u033D\u033E\u033F\u0340\u0341\u0342\u0343"+ + "\u0344\u0345\u0346\u0347\u0348\u0349\u034A\u034B"+ + "\u034C\u034D\u034E\u034F\u0350\u0351\u0352\u0353"+ + "\u0354\u0355\u0356\u0357\u0358\u0359\u035A\u035B"+ + "\u035C\u035D\u035E\u035F\u0360\u0361\u0362\u0363"+ + "\u0364\u0365\u0366\u0367\u0368\u0369\u036A\u036B"+ + "\u036C\u036D\u036E\u036F\u0370\u0371\u0372\u0373"+ + "\u0374\u0375\u0376\u0377\u0378\u0379\u037A\u037B"+ + "\u037C\u037D\u037E\u037F\u0380\u0381\u0382\u0383"+ + "\u0384\u0385\u0386\u0387\u0388\u0389\u038A\u038B"+ + "\u038C\u038D\u038E\u038F\u0390\u03A2\u03AA\u03AB"+ + "\u03AC\u03AD\u03AE\u03AF\u03B0\u03C2\u03CA\u03CB"+ + "\u03CC\u03CD\u03CE\u03CF\u03D0\u03D1\u03D2\u03D3"+ + "\u03D4\u03D5\u03D6\u03D7\u03D8\u03D9\u03DA\u03DB"+ + "\u03DC\u03DD\u03DE\u03DF\u03E0\u03E1\u03E2\u03E3"+ + "\u03E4\u03E5\u03E6\u03E7\u03E8\u03E9\u03EA\u03EB"+ + "\u03EC\u03ED\u03EE\u03EF\u03F0\u03F1\u03F2\u03F3"+ + "\u03F4\u03F5\u03F6\u03F7\u03F8\u03F9\u03FA\u03FB"+ + "\u03FC\u03FD\u03FE\u03FF\u0400\u0402\u0403\u0404"+ + "\u0405\u0406\u0407\u0408\u0409\u040A\u040B\u040C"+ + "\u040D\u040E\u040F\u0450\u0452\u0453\u0454\u0455"+ + "\u0456\u0457\u0458\u0459\u045A\u045B\u045C\u045D"+ + "\u045E\u045F\u0460\u0461\u0462\u0463\u0464\u0465"+ + "\u0466\u0467\u0468\u0469\u046A\u046B\u046C\u046D"+ + "\u046E\u046F\u0470\u0471\u0472\u0473\u0474\u0475"+ + "\u0476\u0477\u0478\u0479\u047A\u047B\u047C\u047D"+ + "\u047E\u047F\u0480\u0481\u0482\u0483\u0484\u0485"+ + "\u0486\u0487\u0488\u0489\u048A\u048B\u048C\u048D"+ + "\u048E\u048F\u0490\u0491\u0492\u0493\u0494\u0495"+ + "\u0496\u0497\u0498\u0499\u049A\u049B\u049C\u049D"+ + "\u049E\u049F\u04A0\u04A1\u04A2\u04A3\u04A4\u04A5"+ + "\u04A6\u04A7\u04A8\u04A9\u04AA\u04AB\u04AC\u04AD"+ + "\u04AE\u04AF\u04B0\u04B1\u04B2\u04B3\u04B4\u04B5"+ + "\u04B6\u04B7\u04B8\u04B9\u04BA\u04BB\u04BC\u04BD"+ + "\u04BE\u04BF\u04C0\u04C1\u04C2\u04C3\u04C4\u04C5"+ + "\u04C6\u04C7\u04C8\u04C9\u04CA\u04CB\u04CC\u04CD"+ + "\u04CE\u04CF\u04D0\u04D1\u04D2\u04D3\u04D4\u04D5"+ + "\u04D6\u04D7\u04D8\u04D9\u04DA\u04DB\u04DC\u04DD"+ + "\u04DE\u04DF\u04E0\u04E1\u04E2\u04E3\u04E4\u04E5"+ + "\u04E6\u04E7\u04E8\u04E9\u04EA\u04EB\u04EC\u04ED"+ + "\u04EE\u04EF\u04F0\u04F1\u04F2\u04F3\u04F4\u04F5"+ + "\u04F6\u04F7\u04F8\u04F9\u04FA\u04FB\u04FC\u04FD"+ + "\u04FE\u04FF\u0500\u0501\u0502\u0503\u0504\u0505"+ + "\u0506\u0507\u0508\u0509\u050A\u050B\u050C\u050D"+ + "\u050E\u050F\u0510\u0511\u0512\u0513\u0514\u0515"+ + "\u0516\u0517\u0518\u0519\u051A\u051B\u051C\u051D"+ + "\u051E\u051F\u0520\u0521\u0522\u0523\u0524\u0525"+ + "\u0526\u0527\u0528\u0529\u052A\u052B\u052C\u052D"+ + "\u052E\u052F\u0530\u0531\u0532\u0533\u0534\u0535"+ + "\u0536\u0537\u0538\u0539\u053A\u053B\u053C\u053D"+ + "\u053E\u053F\u0540\u0541\u0542\u0543\u0544\u0545"+ + "\u0546\u0547\u0548\u0549\u054A\u054B\u054C\u054D"+ + "\u054E\u054F\u0550\u0551\u0552\u0553\u0554\u0555"+ + "\u0556\u0557\u0558\u0559\u055A\u055B\u055C\u055D"+ + "\u055E\u055F\u0560\u0561\u0562\u0563\u0564\u0565"+ + "\u0566\u0567\u0568\u0569\u056A\u056B\u056C\u056D"+ + "\u056E\u056F\u0570\u0571\u0572\u0573\u0574\u0575"+ + "\u0576\u0577\u0578\u0579\u057A\u057B\u057C\u057D"+ + "\u057E\u057F\u0580\u0581\u0582\u0583\u0584\u0585"+ + "\u0586\u0587\u0588\u0589\u058A\u058B\u058C\u058D"+ + "\u058E\u058F\u0590\u0591\u0592\u0593\u0594\u0595"+ + "\u0596\u0597\u0598\u0599\u059A\u059B\u059C\u059D"+ + "\u059E\u059F\u05A0\u05A1\u05A2\u05A3\u05A4\u05A5"+ + "\u05A6\u05A7\u05A8\u05A9\u05AA\u05AB\u05AC\u05AD"+ + "\u05AE\u05AF\u05B0\u05B1\u05B2\u05B3\u05B4\u05B5"+ + "\u05B6\u05B7\u05B8\u05B9\u05BA\u05BB\u05BC\u05BD"+ + "\u05BE\u05BF\u05C0\u05C1\u05C2\u05C3\u05C4\u05C5"+ + "\u05C6\u05C7\u05C8\u05C9\u05CA\u05CB\u05CC\u05CD"+ + "\u05CE\u05CF\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5"+ + "\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD"+ + "\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5"+ + "\u05E6\u05E7\u05E8\u05E9\u05EA\u05EB\u05EC\u05ED"+ + "\u05EE\u05EF\u05F0\u05F1\u05F2\u05F3\u05F4\u05F5"+ + "\u05F6\u05F7\u05F8\u05F9\u05FA\u05FB\u05FC\u05FD"+ + "\u05FE\u05FF\u0600\u0601\u0602\u0603\u0604\u0605"+ + "\u0606\u0607\u0608\u0609\u060A\u060B\u060C\u060D"+ + "\u060E\u060F\u0610\u0611\u0612\u0613\u0614\u0615"+ + "\u0616\u0617\u0618\u0619\u061A\u061B\u061C\u061D"+ + "\u061E\u061F\u0620\u0621\u0622\u0623\u0624\u0625"+ + "\u0626\u0627\u0628\u0629\u062A\u062B\u062C\u062D"+ + "\u062E\u062F\u0630\u0631\u0632\u0633\u0634\u0635"+ + "\u0636\u0637\u0638\u0639\u063A\u063B\u063C\u063D"+ + "\u063E\u063F\u0640\u0641\u0642\u0643\u0644\u0645"+ + "\u0646\u0647\u0648\u0649\u064A\u064B\u064C\u064D"+ + "\u064E\u064F\u0650\u0651\u0652\u0653\u0654\u0655"+ + "\u0656\u0657\u0658\u0659\u065A\u065B\u065C\u065D"+ + "\u065E\u065F\u0660\u0661\u0662\u0663\u0664\u0665"+ + "\u0666\u0667\u0668\u0669\u066A\u066B\u066C\u066D"+ + "\u066E\u066F\u0670\u0671\u0672\u0673\u0674\u0675"+ + "\u0676\u0677\u0678\u0679\u067A\u067B\u067C\u067D"+ + "\u067E\u067F\u0680\u0681\u0682\u0683\u0684\u0685"+ + "\u0686\u0687\u0688\u0689\u068A\u068B\u068C\u068D"+ + "\u068E\u068F\u0690\u0691\u0692\u0693\u0694\u0695"+ + "\u0696\u0697\u0698\u0699\u069A\u069B\u069C\u069D"+ + "\u069E\u069F\u06A0\u06A1\u06A2\u06A3\u06A4\u06A5"+ + "\u06A6\u06A7\u06A8\u06A9\u06AA\u06AB\u06AC\u06AD"+ + "\u06AE\u06AF\u06B0\u06B1\u06B2\u06B3\u06B4\u06B5"+ + "\u06B6\u06B7\u06B8\u06B9\u06BA\u06BB\u06BC\u06BD"+ + "\u06BE\u06BF\u06C0\u06C1\u06C2\u06C3\u06C4\u06C5"+ + "\u06C6\u06C7\u06C8\u06C9\u06CA\u06CB\u06CC\u06CD"+ + "\u06CE\u06CF\u06D0\u06D1\u06D2\u06D3\u06D4\u06D5"+ + "\u06D6\u06D7\u06D8\u06D9\u06DA\u06DB\u06DC\u06DD"+ + "\u06DE\u06DF\u06E0\u06E1\u06E2\u06E3\u06E4\u06E5"+ + "\u06E6\u06E7\u06E8\u06E9\u06EA\u06EB\u06EC\u06ED"+ + "\u06EE\u06EF\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5"+ + "\u06F6\u06F7\u06F8\u06F9\u06FA\u06FB\u06FC\u06FD"+ + "\u06FE\u06FF\u0700\u0701\u0702\u0703\u0704\u0705"+ + "\u0706\u0707\u0708\u0709\u070A\u070B\u070C\u070D"+ + "\u070E\u070F\u0710\u0711\u0712\u0713\u0714\u0715"+ + "\u0716\u0717\u0718\u0719\u071A\u071B\u071C\u071D"+ + "\u071E\u071F\u0720\u0721\u0722\u0723\u0724\u0725"+ + "\u0726\u0727\u0728\u0729\u072A\u072B\u072C\u072D"+ + "\u072E\u072F\u0730\u0731\u0732\u0733\u0734\u0735"+ + "\u0736\u0737\u0738\u0739\u073A\u073B\u073C\u073D"+ + "\u073E\u073F\u0740\u0741\u0742\u0743\u0744\u0745"+ + "\u0746\u0747\u0748\u0749\u074A\u074B\u074C\u074D"+ + "\u074E\u074F\u0750\u0751\u0752\u0753\u0754\u0755"+ + "\u0756\u0757\u0758\u0759\u075A\u075B\u075C\u075D"+ + "\u075E\u075F\u0760\u0761\u0762\u0763\u0764\u0765"+ + "\u0766\u0767\u0768\u0769\u076A\u076B\u076C\u076D"+ + "\u076E\u076F\u0770\u0771\u0772\u0773\u0774\u0775"+ + "\u0776\u0777\u0778\u0779\u077A\u077B\u077C\u077D"+ + "\u077E\u077F\u0780\u0781\u0782\u0783\u0784\u0785"+ + "\u0786\u0787\u0788\u0789\u078A\u078B\u078C\u078D"+ + "\u078E\u078F\u0790\u0791\u0792\u0793\u0794\u0795"+ + "\u0796\u0797\u0798\u0799\u079A\u079B\u079C\u079D"+ + "\u079E\u079F\u07A0\u07A1\u07A2\u07A3\u07A4\u07A5"+ + "\u07A6\u07A7\u07A8\u07A9\u07AA\u07AB\u07AC\u07AD"+ + "\u07AE\u07AF\u07B0\u07B1\u07B2\u07B3\u07B4\u07B5"+ + "\u07B6\u07B7\u07B8\u07B9\u07BA\u07BB\u07BC\u07BD"+ + "\u07BE\u07BF\u07C0\u07C1\u07C2\u07C3\u07C4\u07C5"+ + "\u07C6\u07C7\u07C8\u07C9\u07CA\u07CB\u07CC\u07CD"+ + "\u07CE\u07CF\u07D0\u07D1\u07D2\u07D3\u07D4\u07D5"+ + "\u07D6\u07D7\u07D8\u07D9\u07DA\u07DB\u07DC\u07DD"+ + "\u07DE\u07DF\u07E0\u07E1\u07E2\u07E3\u07E4\u07E5"+ + "\u07E6\u07E7\u07E8\u07E9\u07EA\u07EB\u07EC\u07ED"+ + "\u07EE\u07EF\u07F0\u07F1\u07F2\u07F3\u07F4\u07F5"+ + "\u07F6\u07F7\u07F8\u07F9\u07FA\u07FB\u07FC\u07FD"+ + "\u07FE\u07FF\u0800\u0801\u0802\u0803\u0804\u0805"+ + "\u0806\u0807\u0808\u0809\u080A\u080B\u080C\u080D"+ + "\u080E\u080F\u0810\u0811\u0812\u0813\u0814\u0815"+ + "\u0816\u0817\u0818\u0819\u081A\u081B\u081C\u081D"+ + "\u081E\u081F\u0820\u0821\u0822\u0823\u0824\u0825"+ + "\u0826\u0827\u0828\u0829\u082A\u082B\u082C\u082D"+ + "\u082E\u082F\u0830\u0831\u0832\u0833\u0834\u0835"+ + "\u0836\u0837\u0838\u0839\u083A\u083B\u083C\u083D"+ + "\u083E\u083F\u0840\u0841\u0842\u0843\u0844\u0845"+ + "\u0846\u0847\u0848\u0849\u084A\u084B\u084C\u084D"+ + "\u084E\u084F\u0850\u0851\u0852\u0853\u0854\u0855"+ + "\u0856\u0857\u0858\u0859\u085A\u085B\u085C\u085D"+ + "\u085E\u085F\u0860\u0861\u0862\u0863\u0864\u0865"+ + "\u0866\u0867\u0868\u0869\u086A\u086B\u086C\u086D"+ + "\u086E\u086F\u0870\u0871\u0872\u0873\u0874\u0875"+ + "\u0876\u0877\u0878\u0879\u087A\u087B\u087C\u087D"+ + "\u087E\u087F\u0880\u0881\u0882\u0883\u0884\u0885"+ + "\u0886\u0887\u0888\u0889\u088A\u088B\u088C\u088D"+ + "\u088E\u088F\u0890\u0891\u0892\u0893\u0894\u0895"+ + "\u0896\u0897\u0898\u0899\u089A\u089B\u089C\u089D"+ + "\u089E\u089F\u08A0\u08A1\u08A2\u08A3\u08A4\u08A5"+ + "\u08A6\u08A7\u08A8\u08A9\u08AA\u08AB\u08AC\u08AD"+ + "\u08AE\u08AF\u08B0\u08B1\u08B2\u08B3\u08B4\u08B5"+ + "\u08B6\u08B7\u08B8\u08B9\u08BA\u08BB\u08BC\u08BD"+ + "\u08BE\u08BF\u08C0\u08C1\u08C2\u08C3\u08C4\u08C5"+ + "\u08C6\u08C7\u08C8\u08C9\u08CA\u08CB\u08CC\u08CD"+ + "\u08CE\u08CF\u08D0\u08D1\u08D2\u08D3\u08D4\u08D5"+ + "\u08D6\u08D7\u08D8\u08D9\u08DA\u08DB\u08DC\u08DD"+ + "\u08DE\u08DF\u08E0\u08E1\u08E2\u08E3\u08E4\u08E5"+ + "\u08E6\u08E7\u08E8\u08E9\u08EA\u08EB\u08EC\u08ED"+ + "\u08EE\u08EF\u08F0\u08F1\u08F2\u08F3\u08F4\u08F5"+ + "\u08F6\u08F7\u08F8\u08F9\u08FA\u08FB\u08FC\u08FD"+ + "\u08FE\u08FF\u0900\u0901\u0902\u0903\u0904\u0905"+ + "\u0906\u0907\u0908\u0909\u090A\u090B\u090C\u090D"+ + "\u090E\u090F\u0910\u0911\u0912\u0913\u0914\u0915"+ + "\u0916\u0917\u0918\u0919\u091A\u091B\u091C\u091D"+ + "\u091E\u091F\u0920\u0921\u0922\u0923\u0924\u0925"+ + "\u0926\u0927\u0928\u0929\u092A\u092B\u092C\u092D"+ + "\u092E\u092F\u0930\u0931\u0932\u0933\u0934\u0935"+ + "\u0936\u0937\u0938\u0939\u093A\u093B\u093C\u093D"+ + "\u093E\u093F\u0940\u0941\u0942\u0943\u0944\u0945"+ + "\u0946\u0947\u0948\u0949\u094A\u094B\u094C\u094D"+ + "\u094E\u094F\u0950\u0951\u0952\u0953\u0954\u0955"+ + "\u0956\u0957\u0958\u0959\u095A\u095B\u095C\u095D"+ + "\u095E\u095F\u0960\u0961\u0962\u0963\u0964\u0965"+ + "\u0966\u0967\u0968\u0969\u096A\u096B\u096C\u096D"+ + "\u096E\u096F\u0970\u0971\u0972\u0973\u0974\u0975"+ + "\u0976\u0977\u0978\u0979\u097A\u097B\u097C\u097D"+ + "\u097E\u097F\u0980\u0981\u0982\u0983\u0984\u0985"+ + "\u0986\u0987\u0988\u0989\u098A\u098B\u098C\u098D"+ + "\u098E\u098F\u0990\u0991\u0992\u0993\u0994\u0995"+ + "\u0996\u0997\u0998\u0999\u099A\u099B\u099C\u099D"+ + "\u099E\u099F\u09A0\u09A1\u09A2\u09A3\u09A4\u09A5"+ + "\u09A6\u09A7\u09A8\u09A9\u09AA\u09AB\u09AC\u09AD"+ + "\u09AE\u09AF\u09B0\u09B1\u09B2\u09B3\u09B4\u09B5"+ + "\u09B6\u09B7\u09B8\u09B9\u09BA\u09BB\u09BC\u09BD"+ + "\u09BE\u09BF\u09C0\u09C1\u09C2\u09C3\u09C4\u09C5"+ + "\u09C6\u09C7\u09C8\u09C9\u09CA\u09CB\u09CC\u09CD"+ + "\u09CE\u09CF\u09D0\u09D1\u09D2\u09D3\u09D4\u09D5"+ + "\u09D6\u09D7\u09D8\u09D9\u09DA\u09DB\u09DC\u09DD"+ + "\u09DE\u09DF\u09E0\u09E1\u09E2\u09E3\u09E4\u09E5"+ + "\u09E6\u09E7\u09E8\u09E9\u09EA\u09EB\u09EC\u09ED"+ + "\u09EE\u09EF\u09F0\u09F1\u09F2\u09F3\u09F4\u09F5"+ + "\u09F6\u09F7\u09F8\u09F9\u09FA\u09FB\u09FC\u09FD"+ + "\u09FE\u09FF\u0A00\u0A01\u0A02\u0A03\u0A04\u0A05"+ + "\u0A06\u0A07\u0A08\u0A09\u0A0A\u0A0B\u0A0C\u0A0D"+ + "\u0A0E\u0A0F\u0A10\u0A11\u0A12\u0A13\u0A14\u0A15"+ + "\u0A16\u0A17\u0A18\u0A19\u0A1A\u0A1B\u0A1C\u0A1D"+ + "\u0A1E\u0A1F\u0A20\u0A21\u0A22\u0A23\u0A24\u0A25"+ + "\u0A26\u0A27\u0A28\u0A29\u0A2A\u0A2B\u0A2C\u0A2D"+ + "\u0A2E\u0A2F\u0A30\u0A31\u0A32\u0A33\u0A34\u0A35"+ + "\u0A36\u0A37\u0A38\u0A39\u0A3A\u0A3B\u0A3C\u0A3D"+ + "\u0A3E\u0A3F\u0A40\u0A41\u0A42\u0A43\u0A44\u0A45"+ + "\u0A46\u0A47\u0A48\u0A49\u0A4A\u0A4B\u0A4C\u0A4D"+ + "\u0A4E\u0A4F\u0A50\u0A51\u0A52\u0A53\u0A54\u0A55"+ + "\u0A56\u0A57\u0A58\u0A59\u0A5A\u0A5B\u0A5C\u0A5D"+ + "\u0A5E\u0A5F\u0A60\u0A61\u0A62\u0A63\u0A64\u0A65"+ + "\u0A66\u0A67\u0A68\u0A69\u0A6A\u0A6B\u0A6C\u0A6D"+ + "\u0A6E\u0A6F\u0A70\u0A71\u0A72\u0A73\u0A74\u0A75"+ + "\u0A76\u0A77\u0A78\u0A79\u0A7A\u0A7B\u0A7C\u0A7D"+ + "\u0A7E\u0A7F\u0A80\u0A81\u0A82\u0A83\u0A84\u0A85"+ + "\u0A86\u0A87\u0A88\u0A89\u0A8A\u0A8B\u0A8C\u0A8D"+ + "\u0A8E\u0A8F\u0A90\u0A91\u0A92\u0A93\u0A94\u0A95"+ + "\u0A96\u0A97\u0A98\u0A99\u0A9A\u0A9B\u0A9C\u0A9D"+ + "\u0A9E\u0A9F\u0AA0\u0AA1\u0AA2\u0AA3\u0AA4\u0AA5"+ + "\u0AA6\u0AA7\u0AA8\u0AA9\u0AAA\u0AAB\u0AAC\u0AAD"+ + "\u0AAE\u0AAF\u0AB0\u0AB1\u0AB2\u0AB3\u0AB4\u0AB5"+ + "\u0AB6\u0AB7\u0AB8\u0AB9\u0ABA\u0ABB\u0ABC\u0ABD"+ + "\u0ABE\u0ABF\u0AC0\u0AC1\u0AC2\u0AC3\u0AC4\u0AC5"+ + "\u0AC6\u0AC7\u0AC8\u0AC9\u0ACA\u0ACB\u0ACC\u0ACD"+ + "\u0ACE\u0ACF\u0AD0\u0AD1\u0AD2\u0AD3\u0AD4\u0AD5"+ + "\u0AD6\u0AD7\u0AD8\u0AD9\u0ADA\u0ADB\u0ADC\u0ADD"+ + "\u0ADE\u0ADF\u0AE0\u0AE1\u0AE2\u0AE3\u0AE4\u0AE5"+ + "\u0AE6\u0AE7\u0AE8\u0AE9\u0AEA\u0AEB\u0AEC\u0AED"+ + "\u0AEE\u0AEF\u0AF0\u0AF1\u0AF2\u0AF3\u0AF4\u0AF5"+ + "\u0AF6\u0AF7\u0AF8\u0AF9\u0AFA\u0AFB\u0AFC\u0AFD"+ + "\u0AFE\u0AFF\u0B00\u0B01\u0B02\u0B03\u0B04\u0B05"+ + "\u0B06\u0B07\u0B08\u0B09\u0B0A\u0B0B\u0B0C\u0B0D"+ + "\u0B0E\u0B0F\u0B10\u0B11\u0B12\u0B13\u0B14\u0B15"+ + "\u0B16\u0B17\u0B18\u0B19\u0B1A\u0B1B\u0B1C\u0B1D"+ + "\u0B1E\u0B1F\u0B20\u0B21\u0B22\u0B23\u0B24\u0B25"+ + "\u0B26\u0B27\u0B28\u0B29\u0B2A\u0B2B\u0B2C\u0B2D"+ + "\u0B2E\u0B2F\u0B30\u0B31\u0B32\u0B33\u0B34\u0B35"+ + "\u0B36\u0B37\u0B38\u0B39\u0B3A\u0B3B\u0B3C\u0B3D"+ + "\u0B3E\u0B3F\u0B40\u0B41\u0B42\u0B43\u0B44\u0B45"+ + "\u0B46\u0B47\u0B48\u0B49\u0B4A\u0B4B\u0B4C\u0B4D"+ + "\u0B4E\u0B4F\u0B50\u0B51\u0B52\u0B53\u0B54\u0B55"+ + "\u0B56\u0B57\u0B58\u0B59\u0B5A\u0B5B\u0B5C\u0B5D"+ + "\u0B5E\u0B5F\u0B60\u0B61\u0B62\u0B63\u0B64\u0B65"+ + "\u0B66\u0B67\u0B68\u0B69\u0B6A\u0B6B\u0B6C\u0B6D"+ + "\u0B6E\u0B6F\u0B70\u0B71\u0B72\u0B73\u0B74\u0B75"+ + "\u0B76\u0B77\u0B78\u0B79\u0B7A\u0B7B\u0B7C\u0B7D"+ + "\u0B7E\u0B7F\u0B80\u0B81\u0B82\u0B83\u0B84\u0B85"+ + "\u0B86\u0B87\u0B88\u0B89\u0B8A\u0B8B\u0B8C\u0B8D"+ + "\u0B8E\u0B8F\u0B90\u0B91\u0B92\u0B93\u0B94\u0B95"+ + "\u0B96\u0B97\u0B98\u0B99\u0B9A\u0B9B\u0B9C\u0B9D"+ + "\u0B9E\u0B9F\u0BA0\u0BA1\u0BA2\u0BA3\u0BA4\u0BA5"+ + "\u0BA6\u0BA7\u0BA8\u0BA9\u0BAA\u0BAB\u0BAC\u0BAD"+ + "\u0BAE\u0BAF\u0BB0\u0BB1\u0BB2\u0BB3\u0BB4\u0BB5"+ + "\u0BB6\u0BB7\u0BB8\u0BB9\u0BBA\u0BBB\u0BBC\u0BBD"+ + "\u0BBE\u0BBF\u0BC0\u0BC1\u0BC2\u0BC3\u0BC4\u0BC5"+ + "\u0BC6\u0BC7\u0BC8\u0BC9\u0BCA\u0BCB\u0BCC\u0BCD"+ + "\u0BCE\u0BCF\u0BD0\u0BD1\u0BD2\u0BD3\u0BD4\u0BD5"+ + "\u0BD6\u0BD7\u0BD8\u0BD9\u0BDA\u0BDB\u0BDC\u0BDD"+ + "\u0BDE\u0BDF\u0BE0\u0BE1\u0BE2\u0BE3\u0BE4\u0BE5"+ + "\u0BE6\u0BE7\u0BE8\u0BE9\u0BEA\u0BEB\u0BEC\u0BED"+ + "\u0BEE\u0BEF\u0BF0\u0BF1\u0BF2\u0BF3\u0BF4\u0BF5"+ + "\u0BF6\u0BF7\u0BF8\u0BF9\u0BFA\u0BFB\u0BFC\u0BFD"+ + "\u0BFE\u0BFF\u0C00\u0C01\u0C02\u0C03\u0C04\u0C05"+ + "\u0C06\u0C07\u0C08\u0C09\u0C0A\u0C0B\u0C0C\u0C0D"+ + "\u0C0E\u0C0F\u0C10\u0C11\u0C12\u0C13\u0C14\u0C15"+ + "\u0C16\u0C17\u0C18\u0C19\u0C1A\u0C1B\u0C1C\u0C1D"+ + "\u0C1E\u0C1F\u0C20\u0C21\u0C22\u0C23\u0C24\u0C25"+ + "\u0C26\u0C27\u0C28\u0C29\u0C2A\u0C2B\u0C2C\u0C2D"+ + "\u0C2E\u0C2F\u0C30\u0C31\u0C32\u0C33\u0C34\u0C35"+ + "\u0C36\u0C37\u0C38\u0C39\u0C3A\u0C3B\u0C3C\u0C3D"+ + "\u0C3E\u0C3F\u0C40\u0C41\u0C42\u0C43\u0C44\u0C45"+ + "\u0C46\u0C47\u0C48\u0C49\u0C4A\u0C4B\u0C4C\u0C4D"+ + "\u0C4E\u0C4F\u0C50\u0C51\u0C52\u0C53\u0C54\u0C55"+ + "\u0C56\u0C57\u0C58\u0C59\u0C5A\u0C5B\u0C5C\u0C5D"+ + "\u0C5E\u0C5F\u0C60\u0C61\u0C62\u0C63\u0C64\u0C65"+ + "\u0C66\u0C67\u0C68\u0C69\u0C6A\u0C6B\u0C6C\u0C6D"+ + "\u0C6E\u0C6F\u0C70\u0C71\u0C72\u0C73\u0C74\u0C75"+ + "\u0C76\u0C77\u0C78\u0C79\u0C7A\u0C7B\u0C7C\u0C7D"+ + "\u0C7E\u0C7F\u0C80\u0C81\u0C82\u0C83\u0C84\u0C85"+ + "\u0C86\u0C87\u0C88\u0C89\u0C8A\u0C8B\u0C8C\u0C8D"+ + "\u0C8E\u0C8F\u0C90\u0C91\u0C92\u0C93\u0C94\u0C95"+ + "\u0C96\u0C97\u0C98\u0C99\u0C9A\u0C9B\u0C9C\u0C9D"+ + "\u0C9E\u0C9F\u0CA0\u0CA1\u0CA2\u0CA3\u0CA4\u0CA5"+ + "\u0CA6\u0CA7\u0CA8\u0CA9\u0CAA\u0CAB\u0CAC\u0CAD"+ + "\u0CAE\u0CAF\u0CB0\u0CB1\u0CB2\u0CB3\u0CB4\u0CB5"+ + "\u0CB6\u0CB7\u0CB8\u0CB9\u0CBA\u0CBB\u0CBC\u0CBD"+ + "\u0CBE\u0CBF\u0CC0\u0CC1\u0CC2\u0CC3\u0CC4\u0CC5"+ + "\u0CC6\u0CC7\u0CC8\u0CC9\u0CCA\u0CCB\u0CCC\u0CCD"+ + "\u0CCE\u0CCF\u0CD0\u0CD1\u0CD2\u0CD3\u0CD4\u0CD5"+ + "\u0CD6\u0CD7\u0CD8\u0CD9\u0CDA\u0CDB\u0CDC\u0CDD"+ + "\u0CDE\u0CDF\u0CE0\u0CE1\u0CE2\u0CE3\u0CE4\u0CE5"+ + "\u0CE6\u0CE7\u0CE8\u0CE9\u0CEA\u0CEB\u0CEC\u0CED"+ + "\u0CEE\u0CEF\u0CF0\u0CF1\u0CF2\u0CF3\u0CF4\u0CF5"+ + "\u0CF6\u0CF7\u0CF8\u0CF9\u0CFA\u0CFB\u0CFC\u0CFD"+ + "\u0CFE\u0CFF\u0D00\u0D01\u0D02\u0D03\u0D04\u0D05"+ + "\u0D06\u0D07\u0D08\u0D09\u0D0A\u0D0B\u0D0C\u0D0D"+ + "\u0D0E\u0D0F\u0D10\u0D11\u0D12\u0D13\u0D14\u0D15"+ + "\u0D16\u0D17\u0D18\u0D19\u0D1A\u0D1B\u0D1C\u0D1D"+ + "\u0D1E\u0D1F\u0D20\u0D21\u0D22\u0D23\u0D24\u0D25"+ + "\u0D26\u0D27\u0D28\u0D29\u0D2A\u0D2B\u0D2C\u0D2D"+ + "\u0D2E\u0D2F\u0D30\u0D31\u0D32\u0D33\u0D34\u0D35"+ + "\u0D36\u0D37\u0D38\u0D39\u0D3A\u0D3B\u0D3C\u0D3D"+ + "\u0D3E\u0D3F\u0D40\u0D41\u0D42\u0D43\u0D44\u0D45"+ + "\u0D46\u0D47\u0D48\u0D49\u0D4A\u0D4B\u0D4C\u0D4D"+ + "\u0D4E\u0D4F\u0D50\u0D51\u0D52\u0D53\u0D54\u0D55"+ + "\u0D56\u0D57\u0D58\u0D59\u0D5A\u0D5B\u0D5C\u0D5D"+ + "\u0D5E\u0D5F\u0D60\u0D61\u0D62\u0D63\u0D64\u0D65"+ + "\u0D66\u0D67\u0D68\u0D69\u0D6A\u0D6B\u0D6C\u0D6D"+ + "\u0D6E\u0D6F\u0D70\u0D71\u0D72\u0D73\u0D74\u0D75"+ + "\u0D76\u0D77\u0D78\u0D79\u0D7A\u0D7B\u0D7C\u0D7D"+ + "\u0D7E\u0D7F\u0D80\u0D81\u0D82\u0D83\u0D84\u0D85"+ + "\u0D86\u0D87\u0D88\u0D89\u0D8A\u0D8B\u0D8C\u0D8D"+ + "\u0D8E\u0D8F\u0D90\u0D91\u0D92\u0D93\u0D94\u0D95"+ + "\u0D96\u0D97\u0D98\u0D99\u0D9A\u0D9B\u0D9C\u0D9D"+ + "\u0D9E\u0D9F\u0DA0\u0DA1\u0DA2\u0DA3\u0DA4\u0DA5"+ + "\u0DA6\u0DA7\u0DA8\u0DA9\u0DAA\u0DAB\u0DAC\u0DAD"+ + "\u0DAE\u0DAF\u0DB0\u0DB1\u0DB2\u0DB3\u0DB4\u0DB5"+ + "\u0DB6\u0DB7\u0DB8\u0DB9\u0DBA\u0DBB\u0DBC\u0DBD"+ + "\u0DBE\u0DBF\u0DC0\u0DC1\u0DC2\u0DC3\u0DC4\u0DC5"+ + "\u0DC6\u0DC7\u0DC8\u0DC9\u0DCA\u0DCB\u0DCC\u0DCD"+ + "\u0DCE\u0DCF\u0DD0\u0DD1\u0DD2\u0DD3\u0DD4\u0DD5"+ + "\u0DD6\u0DD7\u0DD8\u0DD9\u0DDA\u0DDB\u0DDC\u0DDD"+ + "\u0DDE\u0DDF\u0DE0\u0DE1\u0DE2\u0DE3\u0DE4\u0DE5"+ + "\u0DE6\u0DE7\u0DE8\u0DE9\u0DEA\u0DEB\u0DEC\u0DED"+ + "\u0DEE\u0DEF\u0DF0\u0DF1\u0DF2\u0DF3\u0DF4\u0DF5"+ + "\u0DF6\u0DF7\u0DF8\u0DF9\u0DFA\u0DFB\u0DFC\u0DFD"+ + "\u0DFE\u0DFF\u0E00\u0E01\u0E02\u0E03\u0E04\u0E05"+ + "\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D"+ + "\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15"+ + "\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D"+ + "\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25"+ + "\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D"+ + "\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35"+ + "\u0E36\u0E37\u0E38\u0E39\u0E3A\u0E3B\u0E3C\u0E3D"+ + "\u0E3E\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45"+ + "\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D"+ + "\u0E4E\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55"+ + "\u0E56\u0E57\u0E58\u0E59\u0E5A\u0E5B\u0E5C\u0E5D"+ + "\u0E5E\u0E5F\u0E60\u0E61\u0E62\u0E63\u0E64\u0E65"+ + "\u0E66\u0E67\u0E68\u0E69\u0E6A\u0E6B\u0E6C\u0E6D"+ + "\u0E6E\u0E6F\u0E70\u0E71\u0E72\u0E73\u0E74\u0E75"+ + "\u0E76\u0E77\u0E78\u0E79\u0E7A\u0E7B\u0E7C\u0E7D"+ + "\u0E7E\u0E7F\u0E80\u0E81\u0E82\u0E83\u0E84\u0E85"+ + "\u0E86\u0E87\u0E88\u0E89\u0E8A\u0E8B\u0E8C\u0E8D"+ + "\u0E8E\u0E8F\u0E90\u0E91\u0E92\u0E93\u0E94\u0E95"+ + "\u0E96\u0E97\u0E98\u0E99\u0E9A\u0E9B\u0E9C\u0E9D"+ + "\u0E9E\u0E9F\u0EA0\u0EA1\u0EA2\u0EA3\u0EA4\u0EA5"+ + "\u0EA6\u0EA7\u0EA8\u0EA9\u0EAA\u0EAB\u0EAC\u0EAD"+ + "\u0EAE\u0EAF\u0EB0\u0EB1\u0EB2\u0EB3\u0EB4\u0EB5"+ + "\u0EB6\u0EB7\u0EB8\u0EB9\u0EBA\u0EBB\u0EBC\u0EBD"+ + "\u0EBE\u0EBF\u0EC0\u0EC1\u0EC2\u0EC3\u0EC4\u0EC5"+ + "\u0EC6\u0EC7\u0EC8\u0EC9\u0ECA\u0ECB\u0ECC\u0ECD"+ + "\u0ECE\u0ECF\u0ED0\u0ED1\u0ED2\u0ED3\u0ED4\u0ED5"+ + "\u0ED6\u0ED7\u0ED8\u0ED9\u0EDA\u0EDB\u0EDC\u0EDD"+ + "\u0EDE\u0EDF\u0EE0\u0EE1\u0EE2\u0EE3\u0EE4\u0EE5"+ + "\u0EE6\u0EE7\u0EE8\u0EE9\u0EEA\u0EEB\u0EEC\u0EED"+ + "\u0EEE\u0EEF\u0EF0\u0EF1\u0EF2\u0EF3\u0EF4\u0EF5"+ + "\u0EF6\u0EF7\u0EF8\u0EF9\u0EFA\u0EFB\u0EFC\u0EFD"+ + "\u0EFE\u0EFF\u0F00\u0F01\u0F02\u0F03\u0F04\u0F05"+ + "\u0F06\u0F07\u0F08\u0F09\u0F0A\u0F0B\u0F0C\u0F0D"+ + "\u0F0E\u0F0F\u0F10\u0F11\u0F12\u0F13\u0F14\u0F15"+ + "\u0F16\u0F17\u0F18\u0F19\u0F1A\u0F1B\u0F1C\u0F1D"+ + "\u0F1E\u0F1F\u0F20\u0F21\u0F22\u0F23\u0F24\u0F25"+ + "\u0F26\u0F27\u0F28\u0F29\u0F2A\u0F2B\u0F2C\u0F2D"+ + "\u0F2E\u0F2F\u0F30\u0F31\u0F32\u0F33\u0F34\u0F35"+ + "\u0F36\u0F37\u0F38\u0F39\u0F3A\u0F3B\u0F3C\u0F3D"+ + "\u0F3E\u0F3F\u0F40\u0F41\u0F42\u0F43\u0F44\u0F45"+ + "\u0F46\u0F47\u0F48\u0F49\u0F4A\u0F4B\u0F4C\u0F4D"+ + "\u0F4E\u0F4F\u0F50\u0F51\u0F52\u0F53\u0F54\u0F55"+ + "\u0F56\u0F57\u0F58\u0F59\u0F5A\u0F5B\u0F5C\u0F5D"+ + "\u0F5E\u0F5F\u0F60\u0F61\u0F62\u0F63\u0F64\u0F65"+ + "\u0F66\u0F67\u0F68\u0F69\u0F6A\u0F6B\u0F6C\u0F6D"+ + "\u0F6E\u0F6F\u0F70\u0F71\u0F72\u0F73\u0F74\u0F75"+ + "\u0F76\u0F77\u0F78\u0F79\u0F7A\u0F7B\u0F7C\u0F7D"+ + "\u0F7E\u0F7F\u0F80\u0F81\u0F82\u0F83\u0F84\u0F85"+ + "\u0F86\u0F87\u0F88\u0F89\u0F8A\u0F8B\u0F8C\u0F8D"+ + "\u0F8E\u0F8F\u0F90\u0F91\u0F92\u0F93\u0F94\u0F95"+ + "\u0F96\u0F97\u0F98\u0F99\u0F9A\u0F9B\u0F9C\u0F9D"+ + "\u0F9E\u0F9F\u0FA0\u0FA1\u0FA2\u0FA3\u0FA4\u0FA5"+ + "\u0FA6\u0FA7\u0FA8\u0FA9\u0FAA\u0FAB\u0FAC\u0FAD"+ + "\u0FAE\u0FAF\u0FB0\u0FB1\u0FB2\u0FB3\u0FB4\u0FB5"+ + "\u0FB6\u0FB7\u0FB8\u0FB9\u0FBA\u0FBB\u0FBC\u0FBD"+ + "\u0FBE\u0FBF\u0FC0\u0FC1\u0FC2\u0FC3\u0FC4\u0FC5"+ + "\u0FC6\u0FC7\u0FC8\u0FC9\u0FCA\u0FCB\u0FCC\u0FCD"+ + "\u0FCE\u0FCF\u0FD0\u0FD1\u0FD2\u0FD3\u0FD4\u0FD5"+ + "\u0FD6\u0FD7\u0FD8\u0FD9\u0FDA\u0FDB\u0FDC\u0FDD"+ + "\u0FDE\u0FDF\u0FE0\u0FE1\u0FE2\u0FE3\u0FE4\u0FE5"+ + "\u0FE6\u0FE7\u0FE8\u0FE9\u0FEA\u0FEB\u0FEC\u0FED"+ + "\u0FEE\u0FEF\u0FF0\u0FF1\u0FF2\u0FF3\u0FF4\u0FF5"+ + "\u0FF6\u0FF7\u0FF8\u0FF9\u0FFA\u0FFB\u0FFC\u0FFD"+ + "\u0FFE\u0FFF\u1000\u1001\u1002\u1003\u1004\u1005"+ + "\u1006\u1007\u1008\u1009\u100A\u100B\u100C\u100D"+ + "\u100E\u100F\u1010\u1011\u1012\u1013\u1014\u1015"+ + "\u1016\u1017\u1018\u1019\u101A\u101B\u101C\u101D"+ + "\u101E\u101F\u1020\u1021\u1022\u1023\u1024\u1025"+ + "\u1026\u1027\u1028\u1029\u102A\u102B\u102C\u102D"+ + "\u102E\u102F\u1030\u1031\u1032\u1033\u1034\u1035"+ + "\u1036\u1037\u1038\u1039\u103A\u103B\u103C\u103D"+ + "\u103E\u103F\u1040\u1041\u1042\u1043\u1044\u1045"+ + "\u1046\u1047\u1048\u1049\u104A\u104B\u104C\u104D"+ + "\u104E\u104F\u1050\u1051\u1052\u1053\u1054\u1055"+ + "\u1056\u1057\u1058\u1059\u105A\u105B\u105C\u105D"+ + "\u105E\u105F\u1060\u1061\u1062\u1063\u1064\u1065"+ + "\u1066\u1067\u1068\u1069\u106A\u106B\u106C\u106D"+ + "\u106E\u106F\u1070\u1071\u1072\u1073\u1074\u1075"+ + "\u1076\u1077\u1078\u1079\u107A\u107B\u107C\u107D"+ + "\u107E\u107F\u1080\u1081\u1082\u1083\u1084\u1085"+ + "\u1086\u1087\u1088\u1089\u108A\u108B\u108C\u108D"+ + "\u108E\u108F\u1090\u1091\u1092\u1093\u1094\u1095"+ + "\u1096\u1097\u1098\u1099\u109A\u109B\u109C\u109D"+ + "\u109E\u109F\u10A0\u10A1\u10A2\u10A3\u10A4\u10A5"+ + "\u10A6\u10A7\u10A8\u10A9\u10AA\u10AB\u10AC\u10AD"+ + "\u10AE\u10AF\u10B0\u10B1\u10B2\u10B3\u10B4\u10B5"+ + "\u10B6\u10B7\u10B8\u10B9\u10BA\u10BB\u10BC\u10BD"+ + "\u10BE\u10BF\u10C0\u10C1\u10C2\u10C3\u10C4\u10C5"+ + "\u10C6\u10C7\u10C8\u10C9\u10CA\u10CB\u10CC\u10CD"+ + "\u10CE\u10CF\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5"+ + "\u10D6\u10D7\u10D8\u10D9\u10DA\u10DB\u10DC\u10DD"+ + "\u10DE\u10DF\u10E0\u10E1\u10E2\u10E3\u10E4\u10E5"+ + "\u10E6\u10E7\u10E8\u10E9\u10EA\u10EB\u10EC\u10ED"+ + "\u10EE\u10EF\u10F0\u10F1\u10F2\u10F3\u10F4\u10F5"+ + "\u10F6\u10F7\u10F8\u10F9\u10FA\u10FB\u10FC\u10FD"+ + "\u10FE\u10FF\u1100\u1101\u1102\u1103\u1104\u1105"+ + "\u1106\u1107\u1108\u1109\u110A\u110B\u110C\u110D"+ + "\u110E\u110F\u1110\u1111\u1112\u1113\u1114\u1115"+ + "\u1116\u1117\u1118\u1119\u111A\u111B\u111C\u111D"; + + private static final String innerDecoderIndex1= + "\u111E\u111F\u1120\u1121\u1122\u1123\u1124\u1125"+ + "\u1126\u1127\u1128\u1129\u112A\u112B\u112C\u112D"+ + "\u112E\u112F\u1130\u1131\u1132\u1133\u1134\u1135"+ + "\u1136\u1137\u1138\u1139\u113A\u113B\u113C\u113D"+ + "\u113E\u113F\u1140\u1141\u1142\u1143\u1144\u1145"+ + "\u1146\u1147\u1148\u1149\u114A\u114B\u114C\u114D"+ + "\u114E\u114F\u1150\u1151\u1152\u1153\u1154\u1155"+ + "\u1156\u1157\u1158\u1159\u115A\u115B\u115C\u115D"+ + "\u115E\u115F\u1160\u1161\u1162\u1163\u1164\u1165"+ + "\u1166\u1167\u1168\u1169\u116A\u116B\u116C\u116D"+ + "\u116E\u116F\u1170\u1171\u1172\u1173\u1174\u1175"+ + "\u1176\u1177\u1178\u1179\u117A\u117B\u117C\u117D"+ + "\u117E\u117F\u1180\u1181\u1182\u1183\u1184\u1185"+ + "\u1186\u1187\u1188\u1189\u118A\u118B\u118C\u118D"+ + "\u118E\u118F\u1190\u1191\u1192\u1193\u1194\u1195"+ + "\u1196\u1197\u1198\u1199\u119A\u119B\u119C\u119D"+ + "\u119E\u119F\u11A0\u11A1\u11A2\u11A3\u11A4\u11A5"+ + "\u11A6\u11A7\u11A8\u11A9\u11AA\u11AB\u11AC\u11AD"+ + "\u11AE\u11AF\u11B0\u11B1\u11B2\u11B3\u11B4\u11B5"+ + "\u11B6\u11B7\u11B8\u11B9\u11BA\u11BB\u11BC\u11BD"+ + "\u11BE\u11BF\u11C0\u11C1\u11C2\u11C3\u11C4\u11C5"+ + "\u11C6\u11C7\u11C8\u11C9\u11CA\u11CB\u11CC\u11CD"+ + "\u11CE\u11CF\u11D0\u11D1\u11D2\u11D3\u11D4\u11D5"+ + "\u11D6\u11D7\u11D8\u11D9\u11DA\u11DB\u11DC\u11DD"+ + "\u11DE\u11DF\u11E0\u11E1\u11E2\u11E3\u11E4\u11E5"+ + "\u11E6\u11E7\u11E8\u11E9\u11EA\u11EB\u11EC\u11ED"+ + "\u11EE\u11EF\u11F0\u11F1\u11F2\u11F3\u11F4\u11F5"+ + "\u11F6\u11F7\u11F8\u11F9\u11FA\u11FB\u11FC\u11FD"+ + "\u11FE\u11FF\u1200\u1201\u1202\u1203\u1204\u1205"+ + "\u1206\u1207\u1208\u1209\u120A\u120B\u120C\u120D"+ + "\u120E\u120F\u1210\u1211\u1212\u1213\u1214\u1215"+ + "\u1216\u1217\u1218\u1219\u121A\u121B\u121C\u121D"+ + "\u121E\u121F\u1220\u1221\u1222\u1223\u1224\u1225"+ + "\u1226\u1227\u1228\u1229\u122A\u122B\u122C\u122D"+ + "\u122E\u122F\u1230\u1231\u1232\u1233\u1234\u1235"+ + "\u1236\u1237\u1238\u1239\u123A\u123B\u123C\u123D"+ + "\u123E\u123F\u1240\u1241\u1242\u1243\u1244\u1245"+ + "\u1246\u1247\u1248\u1249\u124A\u124B\u124C\u124D"+ + "\u124E\u124F\u1250\u1251\u1252\u1253\u1254\u1255"+ + "\u1256\u1257\u1258\u1259\u125A\u125B\u125C\u125D"+ + "\u125E\u125F\u1260\u1261\u1262\u1263\u1264\u1265"+ + "\u1266\u1267\u1268\u1269\u126A\u126B\u126C\u126D"+ + "\u126E\u126F\u1270\u1271\u1272\u1273\u1274\u1275"+ + "\u1276\u1277\u1278\u1279\u127A\u127B\u127C\u127D"+ + "\u127E\u127F\u1280\u1281\u1282\u1283\u1284\u1285"+ + "\u1286\u1287\u1288\u1289\u128A\u128B\u128C\u128D"+ + "\u128E\u128F\u1290\u1291\u1292\u1293\u1294\u1295"+ + "\u1296\u1297\u1298\u1299\u129A\u129B\u129C\u129D"+ + "\u129E\u129F\u12A0\u12A1\u12A2\u12A3\u12A4\u12A5"+ + "\u12A6\u12A7\u12A8\u12A9\u12AA\u12AB\u12AC\u12AD"+ + "\u12AE\u12AF\u12B0\u12B1\u12B2\u12B3\u12B4\u12B5"+ + "\u12B6\u12B7\u12B8\u12B9\u12BA\u12BB\u12BC\u12BD"+ + "\u12BE\u12BF\u12C0\u12C1\u12C2\u12C3\u12C4\u12C5"+ + "\u12C6\u12C7\u12C8\u12C9\u12CA\u12CB\u12CC\u12CD"+ + "\u12CE\u12CF\u12D0\u12D1\u12D2\u12D3\u12D4\u12D5"+ + "\u12D6\u12D7\u12D8\u12D9\u12DA\u12DB\u12DC\u12DD"+ + "\u12DE\u12DF\u12E0\u12E1\u12E2\u12E3\u12E4\u12E5"+ + "\u12E6\u12E7\u12E8\u12E9\u12EA\u12EB\u12EC\u12ED"+ + "\u12EE\u12EF\u12F0\u12F1\u12F2\u12F3\u12F4\u12F5"+ + "\u12F6\u12F7\u12F8\u12F9\u12FA\u12FB\u12FC\u12FD"+ + "\u12FE\u12FF\u1300\u1301\u1302\u1303\u1304\u1305"+ + "\u1306\u1307\u1308\u1309\u130A\u130B\u130C\u130D"+ + "\u130E\u130F\u1310\u1311\u1312\u1313\u1314\u1315"+ + "\u1316\u1317\u1318\u1319\u131A\u131B\u131C\u131D"+ + "\u131E\u131F\u1320\u1321\u1322\u1323\u1324\u1325"+ + "\u1326\u1327\u1328\u1329\u132A\u132B\u132C\u132D"+ + "\u132E\u132F\u1330\u1331\u1332\u1333\u1334\u1335"+ + "\u1336\u1337\u1338\u1339\u133A\u133B\u133C\u133D"+ + "\u133E\u133F\u1340\u1341\u1342\u1343\u1344\u1345"+ + "\u1346\u1347\u1348\u1349\u134A\u134B\u134C\u134D"+ + "\u134E\u134F\u1350\u1351\u1352\u1353\u1354\u1355"+ + "\u1356\u1357\u1358\u1359\u135A\u135B\u135C\u135D"+ + "\u135E\u135F\u1360\u1361\u1362\u1363\u1364\u1365"+ + "\u1366\u1367\u1368\u1369\u136A\u136B\u136C\u136D"+ + "\u136E\u136F\u1370\u1371\u1372\u1373\u1374\u1375"+ + "\u1376\u1377\u1378\u1379\u137A\u137B\u137C\u137D"+ + "\u137E\u137F\u1380\u1381\u1382\u1383\u1384\u1385"+ + "\u1386\u1387\u1388\u1389\u138A\u138B\u138C\u138D"+ + "\u138E\u138F\u1390\u1391\u1392\u1393\u1394\u1395"+ + "\u1396\u1397\u1398\u1399\u139A\u139B\u139C\u139D"+ + "\u139E\u139F\u13A0\u13A1\u13A2\u13A3\u13A4\u13A5"+ + "\u13A6\u13A7\u13A8\u13A9\u13AA\u13AB\u13AC\u13AD"+ + "\u13AE\u13AF\u13B0\u13B1\u13B2\u13B3\u13B4\u13B5"+ + "\u13B6\u13B7\u13B8\u13B9\u13BA\u13BB\u13BC\u13BD"+ + "\u13BE\u13BF\u13C0\u13C1\u13C2\u13C3\u13C4\u13C5"+ + "\u13C6\u13C7\u13C8\u13C9\u13CA\u13CB\u13CC\u13CD"+ + "\u13CE\u13CF\u13D0\u13D1\u13D2\u13D3\u13D4\u13D5"+ + "\u13D6\u13D7\u13D8\u13D9\u13DA\u13DB\u13DC\u13DD"+ + "\u13DE\u13DF\u13E0\u13E1\u13E2\u13E3\u13E4\u13E5"+ + "\u13E6\u13E7\u13E8\u13E9\u13EA\u13EB\u13EC\u13ED"+ + "\u13EE\u13EF\u13F0\u13F1\u13F2\u13F3\u13F4\u13F5"+ + "\u13F6\u13F7\u13F8\u13F9\u13FA\u13FB\u13FC\u13FD"+ + "\u13FE\u13FF\u1400\u1401\u1402\u1403\u1404\u1405"+ + "\u1406\u1407\u1408\u1409\u140A\u140B\u140C\u140D"+ + "\u140E\u140F\u1410\u1411\u1412\u1413\u1414\u1415"+ + "\u1416\u1417\u1418\u1419\u141A\u141B\u141C\u141D"+ + "\u141E\u141F\u1420\u1421\u1422\u1423\u1424\u1425"+ + "\u1426\u1427\u1428\u1429\u142A\u142B\u142C\u142D"+ + "\u142E\u142F\u1430\u1431\u1432\u1433\u1434\u1435"+ + "\u1436\u1437\u1438\u1439\u143A\u143B\u143C\u143D"+ + "\u143E\u143F\u1440\u1441\u1442\u1443\u1444\u1445"+ + "\u1446\u1447\u1448\u1449\u144A\u144B\u144C\u144D"+ + "\u144E\u144F\u1450\u1451\u1452\u1453\u1454\u1455"+ + "\u1456\u1457\u1458\u1459\u145A\u145B\u145C\u145D"+ + "\u145E\u145F\u1460\u1461\u1462\u1463\u1464\u1465"+ + "\u1466\u1467\u1468\u1469\u146A\u146B\u146C\u146D"+ + "\u146E\u146F\u1470\u1471\u1472\u1473\u1474\u1475"+ + "\u1476\u1477\u1478\u1479\u147A\u147B\u147C\u147D"+ + "\u147E\u147F\u1480\u1481\u1482\u1483\u1484\u1485"+ + "\u1486\u1487\u1488\u1489\u148A\u148B\u148C\u148D"+ + "\u148E\u148F\u1490\u1491\u1492\u1493\u1494\u1495"+ + "\u1496\u1497\u1498\u1499\u149A\u149B\u149C\u149D"+ + "\u149E\u149F\u14A0\u14A1\u14A2\u14A3\u14A4\u14A5"+ + "\u14A6\u14A7\u14A8\u14A9\u14AA\u14AB\u14AC\u14AD"+ + "\u14AE\u14AF\u14B0\u14B1\u14B2\u14B3\u14B4\u14B5"+ + "\u14B6\u14B7\u14B8\u14B9\u14BA\u14BB\u14BC\u14BD"+ + "\u14BE\u14BF\u14C0\u14C1\u14C2\u14C3\u14C4\u14C5"+ + "\u14C6\u14C7\u14C8\u14C9\u14CA\u14CB\u14CC\u14CD"+ + "\u14CE\u14CF\u14D0\u14D1\u14D2\u14D3\u14D4\u14D5"+ + "\u14D6\u14D7\u14D8\u14D9\u14DA\u14DB\u14DC\u14DD"+ + "\u14DE\u14DF\u14E0\u14E1\u14E2\u14E3\u14E4\u14E5"+ + "\u14E6\u14E7\u14E8\u14E9\u14EA\u14EB\u14EC\u14ED"+ + "\u14EE\u14EF\u14F0\u14F1\u14F2\u14F3\u14F4\u14F5"+ + "\u14F6\u14F7\u14F8\u14F9\u14FA\u14FB\u14FC\u14FD"+ + "\u14FE\u14FF\u1500\u1501\u1502\u1503\u1504\u1505"+ + "\u1506\u1507\u1508\u1509\u150A\u150B\u150C\u150D"+ + "\u150E\u150F\u1510\u1511\u1512\u1513\u1514\u1515"+ + "\u1516\u1517\u1518\u1519\u151A\u151B\u151C\u151D"+ + "\u151E\u151F\u1520\u1521\u1522\u1523\u1524\u1525"+ + "\u1526\u1527\u1528\u1529\u152A\u152B\u152C\u152D"+ + "\u152E\u152F\u1530\u1531\u1532\u1533\u1534\u1535"+ + "\u1536\u1537\u1538\u1539\u153A\u153B\u153C\u153D"+ + "\u153E\u153F\u1540\u1541\u1542\u1543\u1544\u1545"+ + "\u1546\u1547\u1548\u1549\u154A\u154B\u154C\u154D"+ + "\u154E\u154F\u1550\u1551\u1552\u1553\u1554\u1555"+ + "\u1556\u1557\u1558\u1559\u155A\u155B\u155C\u155D"+ + "\u155E\u155F\u1560\u1561\u1562\u1563\u1564\u1565"+ + "\u1566\u1567\u1568\u1569\u156A\u156B\u156C\u156D"+ + "\u156E\u156F\u1570\u1571\u1572\u1573\u1574\u1575"+ + "\u1576\u1577\u1578\u1579\u157A\u157B\u157C\u157D"+ + "\u157E\u157F\u1580\u1581\u1582\u1583\u1584\u1585"+ + "\u1586\u1587\u1588\u1589\u158A\u158B\u158C\u158D"+ + "\u158E\u158F\u1590\u1591\u1592\u1593\u1594\u1595"+ + "\u1596\u1597\u1598\u1599\u159A\u159B\u159C\u159D"+ + "\u159E\u159F\u15A0\u15A1\u15A2\u15A3\u15A4\u15A5"+ + "\u15A6\u15A7\u15A8\u15A9\u15AA\u15AB\u15AC\u15AD"+ + "\u15AE\u15AF\u15B0\u15B1\u15B2\u15B3\u15B4\u15B5"+ + "\u15B6\u15B7\u15B8\u15B9\u15BA\u15BB\u15BC\u15BD"+ + "\u15BE\u15BF\u15C0\u15C1\u15C2\u15C3\u15C4\u15C5"+ + "\u15C6\u15C7\u15C8\u15C9\u15CA\u15CB\u15CC\u15CD"+ + "\u15CE\u15CF\u15D0\u15D1\u15D2\u15D3\u15D4\u15D5"+ + "\u15D6\u15D7\u15D8\u15D9\u15DA\u15DB\u15DC\u15DD"+ + "\u15DE\u15DF\u15E0\u15E1\u15E2\u15E3\u15E4\u15E5"+ + "\u15E6\u15E7\u15E8\u15E9\u15EA\u15EB\u15EC\u15ED"+ + "\u15EE\u15EF\u15F0\u15F1\u15F2\u15F3\u15F4\u15F5"+ + "\u15F6\u15F7\u15F8\u15F9\u15FA\u15FB\u15FC\u15FD"+ + "\u15FE\u15FF\u1600\u1601\u1602\u1603\u1604\u1605"+ + "\u1606\u1607\u1608\u1609\u160A\u160B\u160C\u160D"+ + "\u160E\u160F\u1610\u1611\u1612\u1613\u1614\u1615"+ + "\u1616\u1617\u1618\u1619\u161A\u161B\u161C\u161D"+ + "\u161E\u161F\u1620\u1621\u1622\u1623\u1624\u1625"+ + "\u1626\u1627\u1628\u1629\u162A\u162B\u162C\u162D"+ + "\u162E\u162F\u1630\u1631\u1632\u1633\u1634\u1635"+ + "\u1636\u1637\u1638\u1639\u163A\u163B\u163C\u163D"+ + "\u163E\u163F\u1640\u1641\u1642\u1643\u1644\u1645"+ + "\u1646\u1647\u1648\u1649\u164A\u164B\u164C\u164D"+ + "\u164E\u164F\u1650\u1651\u1652\u1653\u1654\u1655"+ + "\u1656\u1657\u1658\u1659\u165A\u165B\u165C\u165D"+ + "\u165E\u165F\u1660\u1661\u1662\u1663\u1664\u1665"+ + "\u1666\u1667\u1668\u1669\u166A\u166B\u166C\u166D"+ + "\u166E\u166F\u1670\u1671\u1672\u1673\u1674\u1675"+ + "\u1676\u1677\u1678\u1679\u167A\u167B\u167C\u167D"+ + "\u167E\u167F\u1680\u1681\u1682\u1683\u1684\u1685"+ + "\u1686\u1687\u1688\u1689\u168A\u168B\u168C\u168D"+ + "\u168E\u168F\u1690\u1691\u1692\u1693\u1694\u1695"+ + "\u1696\u1697\u1698\u1699\u169A\u169B\u169C\u169D"+ + "\u169E\u169F\u16A0\u16A1\u16A2\u16A3\u16A4\u16A5"+ + "\u16A6\u16A7\u16A8\u16A9\u16AA\u16AB\u16AC\u16AD"+ + "\u16AE\u16AF\u16B0\u16B1\u16B2\u16B3\u16B4\u16B5"+ + "\u16B6\u16B7\u16B8\u16B9\u16BA\u16BB\u16BC\u16BD"+ + "\u16BE\u16BF\u16C0\u16C1\u16C2\u16C3\u16C4\u16C5"+ + "\u16C6\u16C7\u16C8\u16C9\u16CA\u16CB\u16CC\u16CD"+ + "\u16CE\u16CF\u16D0\u16D1\u16D2\u16D3\u16D4\u16D5"+ + "\u16D6\u16D7\u16D8\u16D9\u16DA\u16DB\u16DC\u16DD"+ + "\u16DE\u16DF\u16E0\u16E1\u16E2\u16E3\u16E4\u16E5"+ + "\u16E6\u16E7\u16E8\u16E9\u16EA\u16EB\u16EC\u16ED"+ + "\u16EE\u16EF\u16F0\u16F1\u16F2\u16F3\u16F4\u16F5"+ + "\u16F6\u16F7\u16F8\u16F9\u16FA\u16FB\u16FC\u16FD"+ + "\u16FE\u16FF\u1700\u1701\u1702\u1703\u1704\u1705"+ + "\u1706\u1707\u1708\u1709\u170A\u170B\u170C\u170D"+ + "\u170E\u170F\u1710\u1711\u1712\u1713\u1714\u1715"+ + "\u1716\u1717\u1718\u1719\u171A\u171B\u171C\u171D"+ + "\u171E\u171F\u1720\u1721\u1722\u1723\u1724\u1725"+ + "\u1726\u1727\u1728\u1729\u172A\u172B\u172C\u172D"+ + "\u172E\u172F\u1730\u1731\u1732\u1733\u1734\u1735"+ + "\u1736\u1737\u1738\u1739\u173A\u173B\u173C\u173D"+ + "\u173E\u173F\u1740\u1741\u1742\u1743\u1744\u1745"+ + "\u1746\u1747\u1748\u1749\u174A\u174B\u174C\u174D"+ + "\u174E\u174F\u1750\u1751\u1752\u1753\u1754\u1755"+ + "\u1756\u1757\u1758\u1759\u175A\u175B\u175C\u175D"+ + "\u175E\u175F\u1760\u1761\u1762\u1763\u1764\u1765"+ + "\u1766\u1767\u1768\u1769\u176A\u176B\u176C\u176D"+ + "\u176E\u176F\u1770\u1771\u1772\u1773\u1774\u1775"+ + "\u1776\u1777\u1778\u1779\u177A\u177B\u177C\u177D"+ + "\u177E\u177F\u1780\u1781\u1782\u1783\u1784\u1785"+ + "\u1786\u1787\u1788\u1789\u178A\u178B\u178C\u178D"+ + "\u178E\u178F\u1790\u1791\u1792\u1793\u1794\u1795"+ + "\u1796\u1797\u1798\u1799\u179A\u179B\u179C\u179D"+ + "\u179E\u179F\u17A0\u17A1\u17A2\u17A3\u17A4\u17A5"+ + "\u17A6\u17A7\u17A8\u17A9\u17AA\u17AB\u17AC\u17AD"+ + "\u17AE\u17AF\u17B0\u17B1\u17B2\u17B3\u17B4\u17B5"+ + "\u17B6\u17B7\u17B8\u17B9\u17BA\u17BB\u17BC\u17BD"+ + "\u17BE\u17BF\u17C0\u17C1\u17C2\u17C3\u17C4\u17C5"+ + "\u17C6\u17C7\u17C8\u17C9\u17CA\u17CB\u17CC\u17CD"+ + "\u17CE\u17CF\u17D0\u17D1\u17D2\u17D3\u17D4\u17D5"+ + "\u17D6\u17D7\u17D8\u17D9\u17DA\u17DB\u17DC\u17DD"+ + "\u17DE\u17DF\u17E0\u17E1\u17E2\u17E3\u17E4\u17E5"+ + "\u17E6\u17E7\u17E8\u17E9\u17EA\u17EB\u17EC\u17ED"+ + "\u17EE\u17EF\u17F0\u17F1\u17F2\u17F3\u17F4\u17F5"+ + "\u17F6\u17F7\u17F8\u17F9\u17FA\u17FB\u17FC\u17FD"+ + "\u17FE\u17FF\u1800\u1801\u1802\u1803\u1804\u1805"+ + "\u1806\u1807\u1808\u1809\u180A\u180B\u180C\u180D"+ + "\u180E\u180F\u1810\u1811\u1812\u1813\u1814\u1815"+ + "\u1816\u1817\u1818\u1819\u181A\u181B\u181C\u181D"+ + "\u181E\u181F\u1820\u1821\u1822\u1823\u1824\u1825"+ + "\u1826\u1827\u1828\u1829\u182A\u182B\u182C\u182D"+ + "\u182E\u182F\u1830\u1831\u1832\u1833\u1834\u1835"+ + "\u1836\u1837\u1838\u1839\u183A\u183B\u183C\u183D"+ + "\u183E\u183F\u1840\u1841\u1842\u1843\u1844\u1845"+ + "\u1846\u1847\u1848\u1849\u184A\u184B\u184C\u184D"+ + "\u184E\u184F\u1850\u1851\u1852\u1853\u1854\u1855"+ + "\u1856\u1857\u1858\u1859\u185A\u185B\u185C\u185D"+ + "\u185E\u185F\u1860\u1861\u1862\u1863\u1864\u1865"+ + "\u1866\u1867\u1868\u1869\u186A\u186B\u186C\u186D"+ + "\u186E\u186F\u1870\u1871\u1872\u1873\u1874\u1875"+ + "\u1876\u1877\u1878\u1879\u187A\u187B\u187C\u187D"+ + "\u187E\u187F\u1880\u1881\u1882\u1883\u1884\u1885"+ + "\u1886\u1887\u1888\u1889\u188A\u188B\u188C\u188D"+ + "\u188E\u188F\u1890\u1891\u1892\u1893\u1894\u1895"+ + "\u1896\u1897\u1898\u1899\u189A\u189B\u189C\u189D"+ + "\u189E\u189F\u18A0\u18A1\u18A2\u18A3\u18A4\u18A5"+ + "\u18A6\u18A7\u18A8\u18A9\u18AA\u18AB\u18AC\u18AD"+ + "\u18AE\u18AF\u18B0\u18B1\u18B2\u18B3\u18B4\u18B5"+ + "\u18B6\u18B7\u18B8\u18B9\u18BA\u18BB\u18BC\u18BD"+ + "\u18BE\u18BF\u18C0\u18C1\u18C2\u18C3\u18C4\u18C5"+ + "\u18C6\u18C7\u18C8\u18C9\u18CA\u18CB\u18CC\u18CD"+ + "\u18CE\u18CF\u18D0\u18D1\u18D2\u18D3\u18D4\u18D5"+ + "\u18D6\u18D7\u18D8\u18D9\u18DA\u18DB\u18DC\u18DD"+ + "\u18DE\u18DF\u18E0\u18E1\u18E2\u18E3\u18E4\u18E5"+ + "\u18E6\u18E7\u18E8\u18E9\u18EA\u18EB\u18EC\u18ED"+ + "\u18EE\u18EF\u18F0\u18F1\u18F2\u18F3\u18F4\u18F5"+ + "\u18F6\u18F7\u18F8\u18F9\u18FA\u18FB\u18FC\u18FD"+ + "\u18FE\u18FF\u1900\u1901\u1902\u1903\u1904\u1905"+ + "\u1906\u1907\u1908\u1909\u190A\u190B\u190C\u190D"+ + "\u190E\u190F\u1910\u1911\u1912\u1913\u1914\u1915"+ + "\u1916\u1917\u1918\u1919\u191A\u191B\u191C\u191D"+ + "\u191E\u191F\u1920\u1921\u1922\u1923\u1924\u1925"+ + "\u1926\u1927\u1928\u1929\u192A\u192B\u192C\u192D"+ + "\u192E\u192F\u1930\u1931\u1932\u1933\u1934\u1935"+ + "\u1936\u1937\u1938\u1939\u193A\u193B\u193C\u193D"+ + "\u193E\u193F\u1940\u1941\u1942\u1943\u1944\u1945"+ + "\u1946\u1947\u1948\u1949\u194A\u194B\u194C\u194D"+ + "\u194E\u194F\u1950\u1951\u1952\u1953\u1954\u1955"+ + "\u1956\u1957\u1958\u1959\u195A\u195B\u195C\u195D"+ + "\u195E\u195F\u1960\u1961\u1962\u1963\u1964\u1965"+ + "\u1966\u1967\u1968\u1969\u196A\u196B\u196C\u196D"+ + "\u196E\u196F\u1970\u1971\u1972\u1973\u1974\u1975"+ + "\u1976\u1977\u1978\u1979\u197A\u197B\u197C\u197D"+ + "\u197E\u197F\u1980\u1981\u1982\u1983\u1984\u1985"+ + "\u1986\u1987\u1988\u1989\u198A\u198B\u198C\u198D"+ + "\u198E\u198F\u1990\u1991\u1992\u1993\u1994\u1995"+ + "\u1996\u1997\u1998\u1999\u199A\u199B\u199C\u199D"+ + "\u199E\u199F\u19A0\u19A1\u19A2\u19A3\u19A4\u19A5"+ + "\u19A6\u19A7\u19A8\u19A9\u19AA\u19AB\u19AC\u19AD"+ + "\u19AE\u19AF\u19B0\u19B1\u19B2\u19B3\u19B4\u19B5"+ + "\u19B6\u19B7\u19B8\u19B9\u19BA\u19BB\u19BC\u19BD"+ + "\u19BE\u19BF\u19C0\u19C1\u19C2\u19C3\u19C4\u19C5"+ + "\u19C6\u19C7\u19C8\u19C9\u19CA\u19CB\u19CC\u19CD"+ + "\u19CE\u19CF\u19D0\u19D1\u19D2\u19D3\u19D4\u19D5"+ + "\u19D6\u19D7\u19D8\u19D9\u19DA\u19DB\u19DC\u19DD"+ + "\u19DE\u19DF\u19E0\u19E1\u19E2\u19E3\u19E4\u19E5"+ + "\u19E6\u19E7\u19E8\u19E9\u19EA\u19EB\u19EC\u19ED"+ + "\u19EE\u19EF\u19F0\u19F1\u19F2\u19F3\u19F4\u19F5"+ + "\u19F6\u19F7\u19F8\u19F9\u19FA\u19FB\u19FC\u19FD"+ + "\u19FE\u19FF\u1A00\u1A01\u1A02\u1A03\u1A04\u1A05"+ + "\u1A06\u1A07\u1A08\u1A09\u1A0A\u1A0B\u1A0C\u1A0D"+ + "\u1A0E\u1A0F\u1A10\u1A11\u1A12\u1A13\u1A14\u1A15"+ + "\u1A16\u1A17\u1A18\u1A19\u1A1A\u1A1B\u1A1C\u1A1D"+ + "\u1A1E\u1A1F\u1A20\u1A21\u1A22\u1A23\u1A24\u1A25"+ + "\u1A26\u1A27\u1A28\u1A29\u1A2A\u1A2B\u1A2C\u1A2D"+ + "\u1A2E\u1A2F\u1A30\u1A31\u1A32\u1A33\u1A34\u1A35"+ + "\u1A36\u1A37\u1A38\u1A39\u1A3A\u1A3B\u1A3C\u1A3D"+ + "\u1A3E\u1A3F\u1A40\u1A41\u1A42\u1A43\u1A44\u1A45"+ + "\u1A46\u1A47\u1A48\u1A49\u1A4A\u1A4B\u1A4C\u1A4D"+ + "\u1A4E\u1A4F\u1A50\u1A51\u1A52\u1A53\u1A54\u1A55"+ + "\u1A56\u1A57\u1A58\u1A59\u1A5A\u1A5B\u1A5C\u1A5D"+ + "\u1A5E\u1A5F\u1A60\u1A61\u1A62\u1A63\u1A64\u1A65"+ + "\u1A66\u1A67\u1A68\u1A69\u1A6A\u1A6B\u1A6C\u1A6D"+ + "\u1A6E\u1A6F\u1A70\u1A71\u1A72\u1A73\u1A74\u1A75"+ + "\u1A76\u1A77\u1A78\u1A79\u1A7A\u1A7B\u1A7C\u1A7D"+ + "\u1A7E\u1A7F\u1A80\u1A81\u1A82\u1A83\u1A84\u1A85"+ + "\u1A86\u1A87\u1A88\u1A89\u1A8A\u1A8B\u1A8C\u1A8D"+ + "\u1A8E\u1A8F\u1A90\u1A91\u1A92\u1A93\u1A94\u1A95"+ + "\u1A96\u1A97\u1A98\u1A99\u1A9A\u1A9B\u1A9C\u1A9D"+ + "\u1A9E\u1A9F\u1AA0\u1AA1\u1AA2\u1AA3\u1AA4\u1AA5"+ + "\u1AA6\u1AA7\u1AA8\u1AA9\u1AAA\u1AAB\u1AAC\u1AAD"+ + "\u1AAE\u1AAF\u1AB0\u1AB1\u1AB2\u1AB3\u1AB4\u1AB5"+ + "\u1AB6\u1AB7\u1AB8\u1AB9\u1ABA\u1ABB\u1ABC\u1ABD"+ + "\u1ABE\u1ABF\u1AC0\u1AC1\u1AC2\u1AC3\u1AC4\u1AC5"+ + "\u1AC6\u1AC7\u1AC8\u1AC9\u1ACA\u1ACB\u1ACC\u1ACD"+ + "\u1ACE\u1ACF\u1AD0\u1AD1\u1AD2\u1AD3\u1AD4\u1AD5"+ + "\u1AD6\u1AD7\u1AD8\u1AD9\u1ADA\u1ADB\u1ADC\u1ADD"+ + "\u1ADE\u1ADF\u1AE0\u1AE1\u1AE2\u1AE3\u1AE4\u1AE5"+ + "\u1AE6\u1AE7\u1AE8\u1AE9\u1AEA\u1AEB\u1AEC\u1AED"+ + "\u1AEE\u1AEF\u1AF0\u1AF1\u1AF2\u1AF3\u1AF4\u1AF5"+ + "\u1AF6\u1AF7\u1AF8\u1AF9\u1AFA\u1AFB\u1AFC\u1AFD"+ + "\u1AFE\u1AFF\u1B00\u1B01\u1B02\u1B03\u1B04\u1B05"+ + "\u1B06\u1B07\u1B08\u1B09\u1B0A\u1B0B\u1B0C\u1B0D"+ + "\u1B0E\u1B0F\u1B10\u1B11\u1B12\u1B13\u1B14\u1B15"+ + "\u1B16\u1B17\u1B18\u1B19\u1B1A\u1B1B\u1B1C\u1B1D"+ + "\u1B1E\u1B1F\u1B20\u1B21\u1B22\u1B23\u1B24\u1B25"+ + "\u1B26\u1B27\u1B28\u1B29\u1B2A\u1B2B\u1B2C\u1B2D"+ + "\u1B2E\u1B2F\u1B30\u1B31\u1B32\u1B33\u1B34\u1B35"+ + "\u1B36\u1B37\u1B38\u1B39\u1B3A\u1B3B\u1B3C\u1B3D"+ + "\u1B3E\u1B3F\u1B40\u1B41\u1B42\u1B43\u1B44\u1B45"+ + "\u1B46\u1B47\u1B48\u1B49\u1B4A\u1B4B\u1B4C\u1B4D"+ + "\u1B4E\u1B4F\u1B50\u1B51\u1B52\u1B53\u1B54\u1B55"+ + "\u1B56\u1B57\u1B58\u1B59\u1B5A\u1B5B\u1B5C\u1B5D"+ + "\u1B5E\u1B5F\u1B60\u1B61\u1B62\u1B63\u1B64\u1B65"+ + "\u1B66\u1B67\u1B68\u1B69\u1B6A\u1B6B\u1B6C\u1B6D"+ + "\u1B6E\u1B6F\u1B70\u1B71\u1B72\u1B73\u1B74\u1B75"+ + "\u1B76\u1B77\u1B78\u1B79\u1B7A\u1B7B\u1B7C\u1B7D"+ + "\u1B7E\u1B7F\u1B80\u1B81\u1B82\u1B83\u1B84\u1B85"+ + "\u1B86\u1B87\u1B88\u1B89\u1B8A\u1B8B\u1B8C\u1B8D"+ + "\u1B8E\u1B8F\u1B90\u1B91\u1B92\u1B93\u1B94\u1B95"+ + "\u1B96\u1B97\u1B98\u1B99\u1B9A\u1B9B\u1B9C\u1B9D"+ + "\u1B9E\u1B9F\u1BA0\u1BA1\u1BA2\u1BA3\u1BA4\u1BA5"+ + "\u1BA6\u1BA7\u1BA8\u1BA9\u1BAA\u1BAB\u1BAC\u1BAD"+ + "\u1BAE\u1BAF\u1BB0\u1BB1\u1BB2\u1BB3\u1BB4\u1BB5"+ + "\u1BB6\u1BB7\u1BB8\u1BB9\u1BBA\u1BBB\u1BBC\u1BBD"+ + "\u1BBE\u1BBF\u1BC0\u1BC1\u1BC2\u1BC3\u1BC4\u1BC5"+ + "\u1BC6\u1BC7\u1BC8\u1BC9\u1BCA\u1BCB\u1BCC\u1BCD"+ + "\u1BCE\u1BCF\u1BD0\u1BD1\u1BD2\u1BD3\u1BD4\u1BD5"+ + "\u1BD6\u1BD7\u1BD8\u1BD9\u1BDA\u1BDB\u1BDC\u1BDD"+ + "\u1BDE\u1BDF\u1BE0\u1BE1\u1BE2\u1BE3\u1BE4\u1BE5"+ + "\u1BE6\u1BE7\u1BE8\u1BE9\u1BEA\u1BEB\u1BEC\u1BED"+ + "\u1BEE\u1BEF\u1BF0\u1BF1\u1BF2\u1BF3\u1BF4\u1BF5"+ + "\u1BF6\u1BF7\u1BF8\u1BF9\u1BFA\u1BFB\u1BFC\u1BFD"+ + "\u1BFE\u1BFF\u1C00\u1C01\u1C02\u1C03\u1C04\u1C05"+ + "\u1C06\u1C07\u1C08\u1C09\u1C0A\u1C0B\u1C0C\u1C0D"+ + "\u1C0E\u1C0F\u1C10\u1C11\u1C12\u1C13\u1C14\u1C15"+ + "\u1C16\u1C17\u1C18\u1C19\u1C1A\u1C1B\u1C1C\u1C1D"+ + "\u1C1E\u1C1F\u1C20\u1C21\u1C22\u1C23\u1C24\u1C25"+ + "\u1C26\u1C27\u1C28\u1C29\u1C2A\u1C2B\u1C2C\u1C2D"+ + "\u1C2E\u1C2F\u1C30\u1C31\u1C32\u1C33\u1C34\u1C35"+ + "\u1C36\u1C37\u1C38\u1C39\u1C3A\u1C3B\u1C3C\u1C3D"+ + "\u1C3E\u1C3F\u1C40\u1C41\u1C42\u1C43\u1C44\u1C45"+ + "\u1C46\u1C47\u1C48\u1C49\u1C4A\u1C4B\u1C4C\u1C4D"+ + "\u1C4E\u1C4F\u1C50\u1C51\u1C52\u1C53\u1C54\u1C55"+ + "\u1C56\u1C57\u1C58\u1C59\u1C5A\u1C5B\u1C5C\u1C5D"+ + "\u1C5E\u1C5F\u1C60\u1C61\u1C62\u1C63\u1C64\u1C65"+ + "\u1C66\u1C67\u1C68\u1C69\u1C6A\u1C6B\u1C6C\u1C6D"+ + "\u1C6E\u1C6F\u1C70\u1C71\u1C72\u1C73\u1C74\u1C75"+ + "\u1C76\u1C77\u1C78\u1C79\u1C7A\u1C7B\u1C7C\u1C7D"+ + "\u1C7E\u1C7F\u1C80\u1C81\u1C82\u1C83\u1C84\u1C85"+ + "\u1C86\u1C87\u1C88\u1C89\u1C8A\u1C8B\u1C8C\u1C8D"+ + "\u1C8E\u1C8F\u1C90\u1C91\u1C92\u1C93\u1C94\u1C95"+ + "\u1C96\u1C97\u1C98\u1C99\u1C9A\u1C9B\u1C9C\u1C9D"+ + "\u1C9E\u1C9F\u1CA0\u1CA1\u1CA2\u1CA3\u1CA4\u1CA5"+ + "\u1CA6\u1CA7\u1CA8\u1CA9\u1CAA\u1CAB\u1CAC\u1CAD"+ + "\u1CAE\u1CAF\u1CB0\u1CB1\u1CB2\u1CB3\u1CB4\u1CB5"+ + "\u1CB6\u1CB7\u1CB8\u1CB9\u1CBA\u1CBB\u1CBC\u1CBD"+ + "\u1CBE\u1CBF\u1CC0\u1CC1\u1CC2\u1CC3\u1CC4\u1CC5"+ + "\u1CC6\u1CC7\u1CC8\u1CC9\u1CCA\u1CCB\u1CCC\u1CCD"+ + "\u1CCE\u1CCF\u1CD0\u1CD1\u1CD2\u1CD3\u1CD4\u1CD5"+ + "\u1CD6\u1CD7\u1CD8\u1CD9\u1CDA\u1CDB\u1CDC\u1CDD"+ + "\u1CDE\u1CDF\u1CE0\u1CE1\u1CE2\u1CE3\u1CE4\u1CE5"+ + "\u1CE6\u1CE7\u1CE8\u1CE9\u1CEA\u1CEB\u1CEC\u1CED"+ + "\u1CEE\u1CEF\u1CF0\u1CF1\u1CF2\u1CF3\u1CF4\u1CF5"+ + "\u1CF6\u1CF7\u1CF8\u1CF9\u1CFA\u1CFB\u1CFC\u1CFD"+ + "\u1CFE\u1CFF\u1D00\u1D01\u1D02\u1D03\u1D04\u1D05"+ + "\u1D06\u1D07\u1D08\u1D09\u1D0A\u1D0B\u1D0C\u1D0D"+ + "\u1D0E\u1D0F\u1D10\u1D11\u1D12\u1D13\u1D14\u1D15"+ + "\u1D16\u1D17\u1D18\u1D19\u1D1A\u1D1B\u1D1C\u1D1D"+ + "\u1D1E\u1D1F\u1D20\u1D21\u1D22\u1D23\u1D24\u1D25"+ + "\u1D26\u1D27\u1D28\u1D29\u1D2A\u1D2B\u1D2C\u1D2D"+ + "\u1D2E\u1D2F\u1D30\u1D31\u1D32\u1D33\u1D34\u1D35"+ + "\u1D36\u1D37\u1D38\u1D39\u1D3A\u1D3B\u1D3C\u1D3D"+ + "\u1D3E\u1D3F\u1D40\u1D41\u1D42\u1D43\u1D44\u1D45"+ + "\u1D46\u1D47\u1D48\u1D49\u1D4A\u1D4B\u1D4C\u1D4D"+ + "\u1D4E\u1D4F\u1D50\u1D51\u1D52\u1D53\u1D54\u1D55"+ + "\u1D56\u1D57\u1D58\u1D59\u1D5A\u1D5B\u1D5C\u1D5D"+ + "\u1D5E\u1D5F\u1D60\u1D61\u1D62\u1D63\u1D64\u1D65"+ + "\u1D66\u1D67\u1D68\u1D69\u1D6A\u1D6B\u1D6C\u1D6D"+ + "\u1D6E\u1D6F\u1D70\u1D71\u1D72\u1D73\u1D74\u1D75"+ + "\u1D76\u1D77\u1D78\u1D79\u1D7A\u1D7B\u1D7C\u1D7D"+ + "\u1D7E\u1D7F\u1D80\u1D81\u1D82\u1D83\u1D84\u1D85"+ + "\u1D86\u1D87\u1D88\u1D89\u1D8A\u1D8B\u1D8C\u1D8D"+ + "\u1D8E\u1D8F\u1D90\u1D91\u1D92\u1D93\u1D94\u1D95"+ + "\u1D96\u1D97\u1D98\u1D99\u1D9A\u1D9B\u1D9C\u1D9D"+ + "\u1D9E\u1D9F\u1DA0\u1DA1\u1DA2\u1DA3\u1DA4\u1DA5"+ + "\u1DA6\u1DA7\u1DA8\u1DA9\u1DAA\u1DAB\u1DAC\u1DAD"+ + "\u1DAE\u1DAF\u1DB0\u1DB1\u1DB2\u1DB3\u1DB4\u1DB5"+ + "\u1DB6\u1DB7\u1DB8\u1DB9\u1DBA\u1DBB\u1DBC\u1DBD"+ + "\u1DBE\u1DBF\u1DC0\u1DC1\u1DC2\u1DC3\u1DC4\u1DC5"+ + "\u1DC6\u1DC7\u1DC8\u1DC9\u1DCA\u1DCB\u1DCC\u1DCD"+ + "\u1DCE\u1DCF\u1DD0\u1DD1\u1DD2\u1DD3\u1DD4\u1DD5"+ + "\u1DD6\u1DD7\u1DD8\u1DD9\u1DDA\u1DDB\u1DDC\u1DDD"+ + "\u1DDE\u1DDF\u1DE0\u1DE1\u1DE2\u1DE3\u1DE4\u1DE5"+ + "\u1DE6\u1DE7\u1DE8\u1DE9\u1DEA\u1DEB\u1DEC\u1DED"+ + "\u1DEE\u1DEF\u1DF0\u1DF1\u1DF2\u1DF3\u1DF4\u1DF5"+ + "\u1DF6\u1DF7\u1DF8\u1DF9\u1DFA\u1DFB\u1DFC\u1DFD"+ + "\u1DFE\u1DFF\u1E00\u1E01\u1E02\u1E03\u1E04\u1E05"+ + "\u1E06\u1E07\u1E08\u1E09\u1E0A\u1E0B\u1E0C\u1E0D"+ + "\u1E0E\u1E0F\u1E10\u1E11\u1E12\u1E13\u1E14\u1E15"+ + "\u1E16\u1E17\u1E18\u1E19\u1E1A\u1E1B\u1E1C\u1E1D"+ + "\u1E1E\u1E1F\u1E20\u1E21\u1E22\u1E23\u1E24\u1E25"+ + "\u1E26\u1E27\u1E28\u1E29\u1E2A\u1E2B\u1E2C\u1E2D"+ + "\u1E2E\u1E2F\u1E30\u1E31\u1E32\u1E33\u1E34\u1E35"+ + "\u1E36\u1E37\u1E38\u1E39\u1E3A\u1E3B\u1E3C\u1E3D"+ + (IS_2000 ? "\u1E3E\u1E3F\u1E40\u1E41\u1E42\u1E43\u1E44\u1E45" : + "\u1E3E\uE7C7\u1E40\u1E41\u1E42\u1E43\u1E44\u1E45")+ + "\u1E46\u1E47\u1E48\u1E49\u1E4A\u1E4B\u1E4C\u1E4D"+ + "\u1E4E\u1E4F\u1E50\u1E51\u1E52\u1E53\u1E54\u1E55"+ + "\u1E56\u1E57\u1E58\u1E59\u1E5A\u1E5B\u1E5C\u1E5D"+ + "\u1E5E\u1E5F\u1E60\u1E61\u1E62\u1E63\u1E64\u1E65"+ + "\u1E66\u1E67\u1E68\u1E69\u1E6A\u1E6B\u1E6C\u1E6D"+ + "\u1E6E\u1E6F\u1E70\u1E71\u1E72\u1E73\u1E74\u1E75"+ + "\u1E76\u1E77\u1E78\u1E79\u1E7A\u1E7B\u1E7C\u1E7D"+ + "\u1E7E\u1E7F\u1E80\u1E81\u1E82\u1E83\u1E84\u1E85"+ + "\u1E86\u1E87\u1E88\u1E89\u1E8A\u1E8B\u1E8C\u1E8D"+ + "\u1E8E\u1E8F\u1E90\u1E91\u1E92\u1E93\u1E94\u1E95"+ + "\u1E96\u1E97\u1E98\u1E99\u1E9A\u1E9B\u1E9C\u1E9D"+ + "\u1E9E\u1E9F\u1EA0\u1EA1\u1EA2\u1EA3\u1EA4\u1EA5"+ + "\u1EA6\u1EA7\u1EA8\u1EA9\u1EAA\u1EAB\u1EAC\u1EAD"+ + "\u1EAE\u1EAF\u1EB0\u1EB1\u1EB2\u1EB3\u1EB4\u1EB5"+ + "\u1EB6\u1EB7\u1EB8\u1EB9\u1EBA\u1EBB\u1EBC\u1EBD"+ + "\u1EBE\u1EBF\u1EC0\u1EC1\u1EC2\u1EC3\u1EC4\u1EC5"+ + "\u1EC6\u1EC7\u1EC8\u1EC9\u1ECA\u1ECB\u1ECC\u1ECD"+ + "\u1ECE\u1ECF\u1ED0\u1ED1\u1ED2\u1ED3\u1ED4\u1ED5"+ + "\u1ED6\u1ED7\u1ED8\u1ED9\u1EDA\u1EDB\u1EDC\u1EDD"+ + "\u1EDE\u1EDF\u1EE0\u1EE1\u1EE2\u1EE3\u1EE4\u1EE5"+ + "\u1EE6\u1EE7\u1EE8\u1EE9\u1EEA\u1EEB\u1EEC\u1EED"+ + "\u1EEE\u1EEF\u1EF0\u1EF1\u1EF2\u1EF3\u1EF4\u1EF5"+ + "\u1EF6\u1EF7\u1EF8\u1EF9\u1EFA\u1EFB\u1EFC\u1EFD"+ + "\u1EFE\u1EFF\u1F00\u1F01\u1F02\u1F03\u1F04\u1F05"+ + "\u1F06\u1F07\u1F08\u1F09\u1F0A\u1F0B\u1F0C\u1F0D"+ + "\u1F0E\u1F0F\u1F10\u1F11\u1F12\u1F13\u1F14\u1F15"+ + "\u1F16\u1F17\u1F18\u1F19\u1F1A\u1F1B\u1F1C\u1F1D"+ + "\u1F1E\u1F1F\u1F20\u1F21\u1F22\u1F23\u1F24\u1F25"+ + "\u1F26\u1F27\u1F28\u1F29\u1F2A\u1F2B\u1F2C\u1F2D"+ + "\u1F2E\u1F2F\u1F30\u1F31\u1F32\u1F33\u1F34\u1F35"+ + "\u1F36\u1F37\u1F38\u1F39\u1F3A\u1F3B\u1F3C\u1F3D"+ + "\u1F3E\u1F3F\u1F40\u1F41\u1F42\u1F43\u1F44\u1F45"+ + "\u1F46\u1F47\u1F48\u1F49\u1F4A\u1F4B\u1F4C\u1F4D"+ + "\u1F4E\u1F4F\u1F50\u1F51\u1F52\u1F53\u1F54\u1F55"+ + "\u1F56\u1F57\u1F58\u1F59\u1F5A\u1F5B\u1F5C\u1F5D"+ + "\u1F5E\u1F5F\u1F60\u1F61\u1F62\u1F63\u1F64\u1F65"+ + "\u1F66\u1F67\u1F68\u1F69\u1F6A\u1F6B\u1F6C\u1F6D"+ + "\u1F6E\u1F6F\u1F70\u1F71\u1F72\u1F73\u1F74\u1F75"+ + "\u1F76\u1F77\u1F78\u1F79\u1F7A\u1F7B\u1F7C\u1F7D"+ + "\u1F7E\u1F7F\u1F80\u1F81\u1F82\u1F83\u1F84\u1F85"+ + "\u1F86\u1F87\u1F88\u1F89\u1F8A\u1F8B\u1F8C\u1F8D"+ + "\u1F8E\u1F8F\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95"+ + "\u1F96\u1F97\u1F98\u1F99\u1F9A\u1F9B\u1F9C\u1F9D"+ + "\u1F9E\u1F9F\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5"+ + "\u1FA6\u1FA7\u1FA8\u1FA9\u1FAA\u1FAB\u1FAC\u1FAD"+ + "\u1FAE\u1FAF\u1FB0\u1FB1\u1FB2\u1FB3\u1FB4\u1FB5"+ + "\u1FB6\u1FB7\u1FB8\u1FB9\u1FBA\u1FBB\u1FBC\u1FBD"+ + "\u1FBE\u1FBF\u1FC0\u1FC1\u1FC2\u1FC3\u1FC4\u1FC5"+ + "\u1FC6\u1FC7\u1FC8\u1FC9\u1FCA\u1FCB\u1FCC\u1FCD"+ + "\u1FCE\u1FCF\u1FD0\u1FD1\u1FD2\u1FD3\u1FD4\u1FD5"+ + "\u1FD6\u1FD7\u1FD8\u1FD9\u1FDA\u1FDB\u1FDC\u1FDD"+ + "\u1FDE\u1FDF\u1FE0\u1FE1\u1FE2\u1FE3\u1FE4\u1FE5"+ + "\u1FE6\u1FE7\u1FE8\u1FE9\u1FEA\u1FEB\u1FEC\u1FED"+ + "\u1FEE\u1FEF\u1FF0\u1FF1\u1FF2\u1FF3\u1FF4\u1FF5"+ + "\u1FF6\u1FF7\u1FF8\u1FF9\u1FFA\u1FFB\u1FFC\u1FFD"+ + "\u1FFE\u1FFF\u2000\u2001\u2002\u2003\u2004\u2005"+ + "\u2006\u2007\u2008\u2009\u200A\u200B\u200C\u200D"+ + "\u200E\u200F\u2011\u2012\u2017\u201A\u201B\u201E"+ + "\u201F\u2020\u2021\u2022\u2023\u2024\u2027\u2028"+ + "\u2029\u202A\u202B\u202C\u202D\u202E\u202F\u2031"+ + "\u2034\u2036\u2037\u2038\u2039\u203A\u203C\u203D"+ + "\u203E\u203F\u2040\u2041\u2042\u2043\u2044\u2045"+ + "\u2046\u2047\u2048\u2049\u204A\u204B\u204C\u204D"+ + "\u204E\u204F\u2050\u2051\u2052\u2053\u2054\u2055"+ + "\u2056\u2057\u2058\u2059\u205A\u205B\u205C\u205D"+ + "\u205E\u205F\u2060\u2061\u2062\u2063\u2064\u2065"+ + "\u2066\u2067\u2068\u2069\u206A\u206B\u206C\u206D"+ + "\u206E\u206F\u2070\u2071\u2072\u2073\u2074\u2075"+ + "\u2076\u2077\u2078\u2079\u207A\u207B\u207C\u207D"+ + "\u207E\u207F\u2080\u2081\u2082\u2083\u2084\u2085"+ + "\u2086\u2087\u2088\u2089\u208A\u208B\u208C\u208D"+ + "\u208E\u208F\u2090\u2091\u2092\u2093\u2094\u2095"+ + "\u2096\u2097\u2098\u2099\u209A\u209B\u209C\u209D"+ + "\u209E\u209F\u20A0\u20A1\u20A2\u20A3\u20A4\u20A5"+ + "\u20A6\u20A7\u20A8\u20A9\u20AA\u20AB\u20AD\u20AE"+ + "\u20AF\u20B0\u20B1\u20B2\u20B3\u20B4\u20B5\u20B6"+ + "\u20B7\u20B8\u20B9\u20BA\u20BB\u20BC\u20BD\u20BE"+ + "\u20BF\u20C0\u20C1\u20C2\u20C3\u20C4\u20C5\u20C6"+ + "\u20C7\u20C8\u20C9\u20CA\u20CB\u20CC\u20CD\u20CE"+ + "\u20CF\u20D0\u20D1\u20D2\u20D3\u20D4\u20D5\u20D6"+ + "\u20D7\u20D8\u20D9\u20DA\u20DB\u20DC\u20DD\u20DE"+ + "\u20DF\u20E0\u20E1\u20E2\u20E3\u20E4\u20E5\u20E6"+ + "\u20E7\u20E8\u20E9\u20EA\u20EB\u20EC\u20ED\u20EE"+ + "\u20EF\u20F0\u20F1\u20F2\u20F3\u20F4\u20F5\u20F6"+ + "\u20F7\u20F8\u20F9\u20FA\u20FB\u20FC\u20FD\u20FE"+ + "\u20FF\u2100\u2101\u2102\u2104\u2106\u2107\u2108"+ + "\u210A\u210B\u210C\u210D\u210E\u210F\u2110\u2111"+ + "\u2112\u2113\u2114\u2115\u2117\u2118\u2119\u211A"+ + "\u211B\u211C\u211D\u211E\u211F\u2120\u2122\u2123"+ + "\u2124\u2125\u2126\u2127\u2128\u2129\u212A\u212B"+ + "\u212C\u212D\u212E\u212F\u2130\u2131\u2132\u2133"; + + private static final String innerDecoderIndex2= + "\u2134\u2135\u2136\u2137\u2138\u2139\u213A\u213B"+ + "\u213C\u213D\u213E\u213F\u2140\u2141\u2142\u2143"+ + "\u2144\u2145\u2146\u2147\u2148\u2149\u214A\u214B"+ + "\u214C\u214D\u214E\u214F\u2150\u2151\u2152\u2153"+ + "\u2154\u2155\u2156\u2157\u2158\u2159\u215A\u215B"+ + "\u215C\u215D\u215E\u215F\u216C\u216D\u216E\u216F"+ + "\u217A\u217B\u217C\u217D\u217E\u217F\u2180\u2181"+ + "\u2182\u2183\u2184\u2185\u2186\u2187\u2188\u2189"+ + "\u218A\u218B\u218C\u218D\u218E\u218F\u2194\u2195"+ + "\u219A\u219B\u219C\u219D\u219E\u219F\u21A0\u21A1"+ + "\u21A2\u21A3\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9"+ + "\u21AA\u21AB\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1"+ + "\u21B2\u21B3\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9"+ + "\u21BA\u21BB\u21BC\u21BD\u21BE\u21BF\u21C0\u21C1"+ + "\u21C2\u21C3\u21C4\u21C5\u21C6\u21C7\u21C8\u21C9"+ + "\u21CA\u21CB\u21CC\u21CD\u21CE\u21CF\u21D0\u21D1"+ + "\u21D2\u21D3\u21D4\u21D5\u21D6\u21D7\u21D8\u21D9"+ + "\u21DA\u21DB\u21DC\u21DD\u21DE\u21DF\u21E0\u21E1"+ + "\u21E2\u21E3\u21E4\u21E5\u21E6\u21E7\u21E8\u21E9"+ + "\u21EA\u21EB\u21EC\u21ED\u21EE\u21EF\u21F0\u21F1"+ + "\u21F2\u21F3\u21F4\u21F5\u21F6\u21F7\u21F8\u21F9"+ + "\u21FA\u21FB\u21FC\u21FD\u21FE\u21FF\u2200\u2201"+ + "\u2202\u2203\u2204\u2205\u2206\u2207\u2209\u220A"+ + "\u220B\u220C\u220D\u220E\u2210\u2212\u2213\u2214"+ + "\u2216\u2217\u2218\u2219\u221B\u221C\u2221\u2222"+ + "\u2224\u2226\u222C\u222D\u222F\u2230\u2231\u2232"+ + "\u2233\u2238\u2239\u223A\u223B\u223C\u223E\u223F"+ + "\u2240\u2241\u2242\u2243\u2244\u2245\u2246\u2247"+ + "\u2249\u224A\u224B\u224D\u224E\u224F\u2250\u2251"+ + "\u2253\u2254\u2255\u2256\u2257\u2258\u2259\u225A"+ + "\u225B\u225C\u225D\u225E\u225F\u2262\u2263\u2268"+ + "\u2269\u226A\u226B\u226C\u226D\u2270\u2271\u2272"+ + "\u2273\u2274\u2275\u2276\u2277\u2278\u2279\u227A"+ + "\u227B\u227C\u227D\u227E\u227F\u2280\u2281\u2282"+ + "\u2283\u2284\u2285\u2286\u2287\u2288\u2289\u228A"+ + "\u228B\u228C\u228D\u228E\u228F\u2290\u2291\u2292"+ + "\u2293\u2294\u2296\u2297\u2298\u229A\u229B\u229C"+ + "\u229D\u229E\u229F\u22A0\u22A1\u22A2\u22A3\u22A4"+ + "\u22A6\u22A7\u22A8\u22A9\u22AA\u22AB\u22AC\u22AD"+ + "\u22AE\u22AF\u22B0\u22B1\u22B2\u22B3\u22B4\u22B5"+ + "\u22B6\u22B7\u22B8\u22B9\u22BA\u22BB\u22BC\u22BD"+ + "\u22BE\u22C0\u22C1\u22C2\u22C3\u22C4\u22C5\u22C6"+ + "\u22C7\u22C8\u22C9\u22CA\u22CB\u22CC\u22CD\u22CE"+ + "\u22CF\u22D0\u22D1\u22D2\u22D3\u22D4\u22D5\u22D6"+ + "\u22D7\u22D8\u22D9\u22DA\u22DB\u22DC\u22DD\u22DE"+ + "\u22DF\u22E0\u22E1\u22E2\u22E3\u22E4\u22E5\u22E6"+ + "\u22E7\u22E8\u22E9\u22EA\u22EB\u22EC\u22ED\u22EE"+ + "\u22EF\u22F0\u22F1\u22F2\u22F3\u22F4\u22F5\u22F6"+ + "\u22F7\u22F8\u22F9\u22FA\u22FB\u22FC\u22FD\u22FE"+ + "\u22FF\u2300\u2301\u2302\u2303\u2304\u2305\u2306"+ + "\u2307\u2308\u2309\u230A\u230B\u230C\u230D\u230E"+ + "\u230F\u2310\u2311\u2313\u2314\u2315\u2316\u2317"+ + "\u2318\u2319\u231A\u231B\u231C\u231D\u231E\u231F"+ + "\u2320\u2321\u2322\u2323\u2324\u2325\u2326\u2327"+ + "\u2328\u2329\u232A\u232B\u232C\u232D\u232E\u232F"+ + "\u2330\u2331\u2332\u2333\u2334\u2335\u2336\u2337"+ + "\u2338\u2339\u233A\u233B\u233C\u233D\u233E\u233F"+ + "\u2340\u2341\u2342\u2343\u2344\u2345\u2346\u2347"+ + "\u2348\u2349\u234A\u234B\u234C\u234D\u234E\u234F"+ + "\u2350\u2351\u2352\u2353\u2354\u2355\u2356\u2357"+ + "\u2358\u2359\u235A\u235B\u235C\u235D\u235E\u235F"+ + "\u2360\u2361\u2362\u2363\u2364\u2365\u2366\u2367"+ + "\u2368\u2369\u236A\u236B\u236C\u236D\u236E\u236F"+ + "\u2370\u2371\u2372\u2373\u2374\u2375\u2376\u2377"+ + "\u2378\u2379\u237A\u237B\u237C\u237D\u237E\u237F"+ + "\u2380\u2381\u2382\u2383\u2384\u2385\u2386\u2387"+ + "\u2388\u2389\u238A\u238B\u238C\u238D\u238E\u238F"+ + "\u2390\u2391\u2392\u2393\u2394\u2395\u2396\u2397"+ + "\u2398\u2399\u239A\u239B\u239C\u239D\u239E\u239F"+ + "\u23A0\u23A1\u23A2\u23A3\u23A4\u23A5\u23A6\u23A7"+ + "\u23A8\u23A9\u23AA\u23AB\u23AC\u23AD\u23AE\u23AF"+ + "\u23B0\u23B1\u23B2\u23B3\u23B4\u23B5\u23B6\u23B7"+ + "\u23B8\u23B9\u23BA\u23BB\u23BC\u23BD\u23BE\u23BF"+ + "\u23C0\u23C1\u23C2\u23C3\u23C4\u23C5\u23C6\u23C7"+ + "\u23C8\u23C9\u23CA\u23CB\u23CC\u23CD\u23CE\u23CF"+ + "\u23D0\u23D1\u23D2\u23D3\u23D4\u23D5\u23D6\u23D7"+ + "\u23D8\u23D9\u23DA\u23DB\u23DC\u23DD\u23DE\u23DF"+ + "\u23E0\u23E1\u23E2\u23E3\u23E4\u23E5\u23E6\u23E7"+ + "\u23E8\u23E9\u23EA\u23EB\u23EC\u23ED\u23EE\u23EF"+ + "\u23F0\u23F1\u23F2\u23F3\u23F4\u23F5\u23F6\u23F7"+ + "\u23F8\u23F9\u23FA\u23FB\u23FC\u23FD\u23FE\u23FF"+ + "\u2400\u2401\u2402\u2403\u2404\u2405\u2406\u2407"+ + "\u2408\u2409\u240A\u240B\u240C\u240D\u240E\u240F"+ + "\u2410\u2411\u2412\u2413\u2414\u2415\u2416\u2417"+ + "\u2418\u2419\u241A\u241B\u241C\u241D\u241E\u241F"+ + "\u2420\u2421\u2422\u2423\u2424\u2425\u2426\u2427"+ + "\u2428\u2429\u242A\u242B\u242C\u242D\u242E\u242F"+ + "\u2430\u2431\u2432\u2433\u2434\u2435\u2436\u2437"+ + "\u2438\u2439\u243A\u243B\u243C\u243D\u243E\u243F"+ + "\u2440\u2441\u2442\u2443\u2444\u2445\u2446\u2447"+ + "\u2448\u2449\u244A\u244B\u244C\u244D\u244E\u244F"+ + "\u2450\u2451\u2452\u2453\u2454\u2455\u2456\u2457"+ + "\u2458\u2459\u245A\u245B\u245C\u245D\u245E\u245F"+ + "\u246A\u246B\u246C\u246D\u246E\u246F\u2470\u2471"+ + "\u2472\u2473\u249C\u249D\u249E\u249F\u24A0\u24A1"+ + "\u24A2\u24A3\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9"+ + "\u24AA\u24AB\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1"+ + "\u24B2\u24B3\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9"+ + "\u24BA\u24BB\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1"+ + "\u24C2\u24C3\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9"+ + "\u24CA\u24CB\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1"+ + "\u24D2\u24D3\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9"+ + "\u24DA\u24DB\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1"+ + "\u24E2\u24E3\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9"+ + "\u24EA\u24EB\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1"+ + "\u24F2\u24F3\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9"+ + "\u24FA\u24FB\u24FC\u24FD\u24FE\u24FF\u254C\u254D"+ + "\u254E\u254F\u2574\u2575\u2576\u2577\u2578\u2579"+ + "\u257A\u257B\u257C\u257D\u257E\u257F\u2580\u2590"+ + "\u2591\u2592\u2596\u2597\u2598\u2599\u259A\u259B"+ + "\u259C\u259D\u259E\u259F\u25A2\u25A3\u25A4\u25A5"+ + "\u25A6\u25A7\u25A8\u25A9\u25AA\u25AB\u25AC\u25AD"+ + "\u25AE\u25AF\u25B0\u25B1\u25B4\u25B5\u25B6\u25B7"+ + "\u25B8\u25B9\u25BA\u25BB\u25BE\u25BF\u25C0\u25C1"+ + "\u25C2\u25C3\u25C4\u25C5\u25C8\u25C9\u25CA\u25CC"+ + "\u25CD\u25D0\u25D1\u25D2\u25D3\u25D4\u25D5\u25D6"+ + "\u25D7\u25D8\u25D9\u25DA\u25DB\u25DC\u25DD\u25DE"+ + "\u25DF\u25E0\u25E1\u25E6\u25E7\u25E8\u25E9\u25EA"+ + "\u25EB\u25EC\u25ED\u25EE\u25EF\u25F0\u25F1\u25F2"+ + "\u25F3\u25F4\u25F5\u25F6\u25F7\u25F8\u25F9\u25FA"+ + "\u25FB\u25FC\u25FD\u25FE\u25FF\u2600\u2601\u2602"+ + "\u2603\u2604\u2607\u2608\u260A\u260B\u260C\u260D"+ + "\u260E\u260F\u2610\u2611\u2612\u2613\u2614\u2615"+ + "\u2616\u2617\u2618\u2619\u261A\u261B\u261C\u261D"+ + "\u261E\u261F\u2620\u2621\u2622\u2623\u2624\u2625"+ + "\u2626\u2627\u2628\u2629\u262A\u262B\u262C\u262D"+ + "\u262E\u262F\u2630\u2631\u2632\u2633\u2634\u2635"+ + "\u2636\u2637\u2638\u2639\u263A\u263B\u263C\u263D"+ + "\u263E\u263F\u2641\u2643\u2644\u2645\u2646\u2647"+ + "\u2648\u2649\u264A\u264B\u264C\u264D\u264E\u264F"+ + "\u2650\u2651\u2652\u2653\u2654\u2655\u2656\u2657"+ + "\u2658\u2659\u265A\u265B\u265C\u265D\u265E\u265F"+ + "\u2660\u2661\u2662\u2663\u2664\u2665\u2666\u2667"+ + "\u2668\u2669\u266A\u266B\u266C\u266D\u266E\u266F"+ + "\u2670\u2671\u2672\u2673\u2674\u2675\u2676\u2677"+ + "\u2678\u2679\u267A\u267B\u267C\u267D\u267E\u267F"+ + "\u2680\u2681\u2682\u2683\u2684\u2685\u2686\u2687"+ + "\u2688\u2689\u268A\u268B\u268C\u268D\u268E\u268F"+ + "\u2690\u2691\u2692\u2693\u2694\u2695\u2696\u2697"+ + "\u2698\u2699\u269A\u269B\u269C\u269D\u269E\u269F"+ + "\u26A0\u26A1\u26A2\u26A3\u26A4\u26A5\u26A6\u26A7"+ + "\u26A8\u26A9\u26AA\u26AB\u26AC\u26AD\u26AE\u26AF"+ + "\u26B0\u26B1\u26B2\u26B3\u26B4\u26B5\u26B6\u26B7"+ + "\u26B8\u26B9\u26BA\u26BB\u26BC\u26BD\u26BE\u26BF"+ + "\u26C0\u26C1\u26C2\u26C3\u26C4\u26C5\u26C6\u26C7"+ + "\u26C8\u26C9\u26CA\u26CB\u26CC\u26CD\u26CE\u26CF"+ + "\u26D0\u26D1\u26D2\u26D3\u26D4\u26D5\u26D6\u26D7"+ + "\u26D8\u26D9\u26DA\u26DB\u26DC\u26DD\u26DE\u26DF"+ + "\u26E0\u26E1\u26E2\u26E3\u26E4\u26E5\u26E6\u26E7"+ + "\u26E8\u26E9\u26EA\u26EB\u26EC\u26ED\u26EE\u26EF"+ + "\u26F0\u26F1\u26F2\u26F3\u26F4\u26F5\u26F6\u26F7"+ + "\u26F8\u26F9\u26FA\u26FB\u26FC\u26FD\u26FE\u26FF"+ + "\u2700\u2701\u2702\u2703\u2704\u2705\u2706\u2707"+ + "\u2708\u2709\u270A\u270B\u270C\u270D\u270E\u270F"+ + "\u2710\u2711\u2712\u2713\u2714\u2715\u2716\u2717"+ + "\u2718\u2719\u271A\u271B\u271C\u271D\u271E\u271F"+ + "\u2720\u2721\u2722\u2723\u2724\u2725\u2726\u2727"+ + "\u2728\u2729\u272A\u272B\u272C\u272D\u272E\u272F"+ + "\u2730\u2731\u2732\u2733\u2734\u2735\u2736\u2737"+ + "\u2738\u2739\u273A\u273B\u273C\u273D\u273E\u273F"+ + "\u2740\u2741\u2742\u2743\u2744\u2745\u2746\u2747"+ + "\u2748\u2749\u274A\u274B\u274C\u274D\u274E\u274F"+ + "\u2750\u2751\u2752\u2753\u2754\u2755\u2756\u2757"+ + "\u2758\u2759\u275A\u275B\u275C\u275D\u275E\u275F"+ + "\u2760\u2761\u2762\u2763\u2764\u2765\u2766\u2767"+ + "\u2768\u2769\u276A\u276B\u276C\u276D\u276E\u276F"+ + "\u2770\u2771\u2772\u2773\u2774\u2775\u2776\u2777"+ + "\u2778\u2779\u277A\u277B\u277C\u277D\u277E\u277F"+ + "\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787"+ + "\u2788\u2789\u278A\u278B\u278C\u278D\u278E\u278F"+ + "\u2790\u2791\u2792\u2793\u2794\u2795\u2796\u2797"+ + "\u2798\u2799\u279A\u279B\u279C\u279D\u279E\u279F"+ + "\u27A0\u27A1\u27A2\u27A3\u27A4\u27A5\u27A6\u27A7"+ + "\u27A8\u27A9\u27AA\u27AB\u27AC\u27AD\u27AE\u27AF"+ + "\u27B0\u27B1\u27B2\u27B3\u27B4\u27B5\u27B6\u27B7"+ + "\u27B8\u27B9\u27BA\u27BB\u27BC\u27BD\u27BE\u27BF"+ + "\u27C0\u27C1\u27C2\u27C3\u27C4\u27C5\u27C6\u27C7"+ + "\u27C8\u27C9\u27CA\u27CB\u27CC\u27CD\u27CE\u27CF"+ + "\u27D0\u27D1\u27D2\u27D3\u27D4\u27D5\u27D6\u27D7"+ + "\u27D8\u27D9\u27DA\u27DB\u27DC\u27DD\u27DE\u27DF"+ + "\u27E0\u27E1\u27E2\u27E3\u27E4\u27E5\u27E6\u27E7"+ + "\u27E8\u27E9\u27EA\u27EB\u27EC\u27ED\u27EE\u27EF"+ + "\u27F0\u27F1\u27F2\u27F3\u27F4\u27F5\u27F6\u27F7"+ + "\u27F8\u27F9\u27FA\u27FB\u27FC\u27FD\u27FE\u27FF"+ + "\u2800\u2801\u2802\u2803\u2804\u2805\u2806\u2807"+ + "\u2808\u2809\u280A\u280B\u280C\u280D\u280E\u280F"+ + "\u2810\u2811\u2812\u2813\u2814\u2815\u2816\u2817"+ + "\u2818\u2819\u281A\u281B\u281C\u281D\u281E\u281F"+ + "\u2820\u2821\u2822\u2823\u2824\u2825\u2826\u2827"+ + "\u2828\u2829\u282A\u282B\u282C\u282D\u282E\u282F"+ + "\u2830\u2831\u2832\u2833\u2834\u2835\u2836\u2837"+ + "\u2838\u2839\u283A\u283B\u283C\u283D\u283E\u283F"+ + "\u2840\u2841\u2842\u2843\u2844\u2845\u2846\u2847"+ + "\u2848\u2849\u284A\u284B\u284C\u284D\u284E\u284F"+ + "\u2850\u2851\u2852\u2853\u2854\u2855\u2856\u2857"+ + "\u2858\u2859\u285A\u285B\u285C\u285D\u285E\u285F"+ + "\u2860\u2861\u2862\u2863\u2864\u2865\u2866\u2867"+ + "\u2868\u2869\u286A\u286B\u286C\u286D\u286E\u286F"+ + "\u2870\u2871\u2872\u2873\u2874\u2875\u2876\u2877"+ + "\u2878\u2879\u287A\u287B\u287C\u287D\u287E\u287F"+ + "\u2880\u2881\u2882\u2883\u2884\u2885\u2886\u2887"+ + "\u2888\u2889\u288A\u288B\u288C\u288D\u288E\u288F"+ + "\u2890\u2891\u2892\u2893\u2894\u2895\u2896\u2897"+ + "\u2898\u2899\u289A\u289B\u289C\u289D\u289E\u289F"+ + "\u28A0\u28A1\u28A2\u28A3\u28A4\u28A5\u28A6\u28A7"+ + "\u28A8\u28A9\u28AA\u28AB\u28AC\u28AD\u28AE\u28AF"+ + "\u28B0\u28B1\u28B2\u28B3\u28B4\u28B5\u28B6\u28B7"+ + "\u28B8\u28B9\u28BA\u28BB\u28BC\u28BD\u28BE\u28BF"+ + "\u28C0\u28C1\u28C2\u28C3\u28C4\u28C5\u28C6\u28C7"+ + "\u28C8\u28C9\u28CA\u28CB\u28CC\u28CD\u28CE\u28CF"+ + "\u28D0\u28D1\u28D2\u28D3\u28D4\u28D5\u28D6\u28D7"+ + "\u28D8\u28D9\u28DA\u28DB\u28DC\u28DD\u28DE\u28DF"+ + "\u28E0\u28E1\u28E2\u28E3\u28E4\u28E5\u28E6\u28E7"+ + "\u28E8\u28E9\u28EA\u28EB\u28EC\u28ED\u28EE\u28EF"+ + "\u28F0\u28F1\u28F2\u28F3\u28F4\u28F5\u28F6\u28F7"+ + "\u28F8\u28F9\u28FA\u28FB\u28FC\u28FD\u28FE\u28FF"+ + "\u2900\u2901\u2902\u2903\u2904\u2905\u2906\u2907"+ + "\u2908\u2909\u290A\u290B\u290C\u290D\u290E\u290F"+ + "\u2910\u2911\u2912\u2913\u2914\u2915\u2916\u2917"+ + "\u2918\u2919\u291A\u291B\u291C\u291D\u291E\u291F"+ + "\u2920\u2921\u2922\u2923\u2924\u2925\u2926\u2927"+ + "\u2928\u2929\u292A\u292B\u292C\u292D\u292E\u292F"+ + "\u2930\u2931\u2932\u2933\u2934\u2935\u2936\u2937"+ + "\u2938\u2939\u293A\u293B\u293C\u293D\u293E\u293F"+ + "\u2940\u2941\u2942\u2943\u2944\u2945\u2946\u2947"+ + "\u2948\u2949\u294A\u294B\u294C\u294D\u294E\u294F"+ + "\u2950\u2951\u2952\u2953\u2954\u2955\u2956\u2957"+ + "\u2958\u2959\u295A\u295B\u295C\u295D\u295E\u295F"+ + "\u2960\u2961\u2962\u2963\u2964\u2965\u2966\u2967"+ + "\u2968\u2969\u296A\u296B\u296C\u296D\u296E\u296F"+ + "\u2970\u2971\u2972\u2973\u2974\u2975\u2976\u2977"+ + "\u2978\u2979\u297A\u297B\u297C\u297D\u297E\u297F"+ + "\u2980\u2981\u2982\u2983\u2984\u2985\u2986\u2987"+ + "\u2988\u2989\u298A\u298B\u298C\u298D\u298E\u298F"+ + "\u2990\u2991\u2992\u2993\u2994\u2995\u2996\u2997"+ + "\u2998\u2999\u299A\u299B\u299C\u299D\u299E\u299F"+ + "\u29A0\u29A1\u29A2\u29A3\u29A4\u29A5\u29A6\u29A7"+ + "\u29A8\u29A9\u29AA\u29AB\u29AC\u29AD\u29AE\u29AF"+ + "\u29B0\u29B1\u29B2\u29B3\u29B4\u29B5\u29B6\u29B7"+ + "\u29B8\u29B9\u29BA\u29BB\u29BC\u29BD\u29BE\u29BF"+ + "\u29C0\u29C1\u29C2\u29C3\u29C4\u29C5\u29C6\u29C7"+ + "\u29C8\u29C9\u29CA\u29CB\u29CC\u29CD\u29CE\u29CF"+ + "\u29D0\u29D1\u29D2\u29D3\u29D4\u29D5\u29D6\u29D7"+ + "\u29D8\u29D9\u29DA\u29DB\u29DC\u29DD\u29DE\u29DF"+ + "\u29E0\u29E1\u29E2\u29E3\u29E4\u29E5\u29E6\u29E7"+ + "\u29E8\u29E9\u29EA\u29EB\u29EC\u29ED\u29EE\u29EF"+ + "\u29F0\u29F1\u29F2\u29F3\u29F4\u29F5\u29F6\u29F7"+ + "\u29F8\u29F9\u29FA\u29FB\u29FC\u29FD\u29FE\u29FF"+ + "\u2A00\u2A01\u2A02\u2A03\u2A04\u2A05\u2A06\u2A07"+ + "\u2A08\u2A09\u2A0A\u2A0B\u2A0C\u2A0D\u2A0E\u2A0F"+ + "\u2A10\u2A11\u2A12\u2A13\u2A14\u2A15\u2A16\u2A17"+ + "\u2A18\u2A19\u2A1A\u2A1B\u2A1C\u2A1D\u2A1E\u2A1F"+ + "\u2A20\u2A21\u2A22\u2A23\u2A24\u2A25\u2A26\u2A27"+ + "\u2A28\u2A29\u2A2A\u2A2B\u2A2C\u2A2D\u2A2E\u2A2F"+ + "\u2A30\u2A31\u2A32\u2A33\u2A34\u2A35\u2A36\u2A37"+ + "\u2A38\u2A39\u2A3A\u2A3B\u2A3C\u2A3D\u2A3E\u2A3F"+ + "\u2A40\u2A41\u2A42\u2A43\u2A44\u2A45\u2A46\u2A47"+ + "\u2A48\u2A49\u2A4A\u2A4B\u2A4C\u2A4D\u2A4E\u2A4F"+ + "\u2A50\u2A51\u2A52\u2A53\u2A54\u2A55\u2A56\u2A57"+ + "\u2A58\u2A59\u2A5A\u2A5B\u2A5C\u2A5D\u2A5E\u2A5F"+ + "\u2A60\u2A61\u2A62\u2A63\u2A64\u2A65\u2A66\u2A67"+ + "\u2A68\u2A69\u2A6A\u2A6B\u2A6C\u2A6D\u2A6E\u2A6F"+ + "\u2A70\u2A71\u2A72\u2A73\u2A74\u2A75\u2A76\u2A77"+ + "\u2A78\u2A79\u2A7A\u2A7B\u2A7C\u2A7D\u2A7E\u2A7F"+ + "\u2A80\u2A81\u2A82\u2A83\u2A84\u2A85\u2A86\u2A87"+ + "\u2A88\u2A89\u2A8A\u2A8B\u2A8C\u2A8D\u2A8E\u2A8F"+ + "\u2A90\u2A91\u2A92\u2A93\u2A94\u2A95\u2A96\u2A97"+ + "\u2A98\u2A99\u2A9A\u2A9B\u2A9C\u2A9D\u2A9E\u2A9F"+ + "\u2AA0\u2AA1\u2AA2\u2AA3\u2AA4\u2AA5\u2AA6\u2AA7"+ + "\u2AA8\u2AA9\u2AAA\u2AAB\u2AAC\u2AAD\u2AAE\u2AAF"+ + "\u2AB0\u2AB1\u2AB2\u2AB3\u2AB4\u2AB5\u2AB6\u2AB7"+ + "\u2AB8\u2AB9\u2ABA\u2ABB\u2ABC\u2ABD\u2ABE\u2ABF"+ + "\u2AC0\u2AC1\u2AC2\u2AC3\u2AC4\u2AC5\u2AC6\u2AC7"+ + "\u2AC8\u2AC9\u2ACA\u2ACB\u2ACC\u2ACD\u2ACE\u2ACF"+ + "\u2AD0\u2AD1\u2AD2\u2AD3\u2AD4\u2AD5\u2AD6\u2AD7"+ + "\u2AD8\u2AD9\u2ADA\u2ADB\u2ADC\u2ADD\u2ADE\u2ADF"+ + "\u2AE0\u2AE1\u2AE2\u2AE3\u2AE4\u2AE5\u2AE6\u2AE7"+ + "\u2AE8\u2AE9\u2AEA\u2AEB\u2AEC\u2AED\u2AEE\u2AEF"+ + "\u2AF0\u2AF1\u2AF2\u2AF3\u2AF4\u2AF5\u2AF6\u2AF7"+ + "\u2AF8\u2AF9\u2AFA\u2AFB\u2AFC\u2AFD\u2AFE\u2AFF"+ + "\u2B00\u2B01\u2B02\u2B03\u2B04\u2B05\u2B06\u2B07"+ + "\u2B08\u2B09\u2B0A\u2B0B\u2B0C\u2B0D\u2B0E\u2B0F"+ + "\u2B10\u2B11\u2B12\u2B13\u2B14\u2B15\u2B16\u2B17"+ + "\u2B18\u2B19\u2B1A\u2B1B\u2B1C\u2B1D\u2B1E\u2B1F"+ + "\u2B20\u2B21\u2B22\u2B23\u2B24\u2B25\u2B26\u2B27"+ + "\u2B28\u2B29\u2B2A\u2B2B\u2B2C\u2B2D\u2B2E\u2B2F"+ + "\u2B30\u2B31\u2B32\u2B33\u2B34\u2B35\u2B36\u2B37"+ + "\u2B38\u2B39\u2B3A\u2B3B\u2B3C\u2B3D\u2B3E\u2B3F"+ + "\u2B40\u2B41\u2B42\u2B43\u2B44\u2B45\u2B46\u2B47"+ + "\u2B48\u2B49\u2B4A\u2B4B\u2B4C\u2B4D\u2B4E\u2B4F"+ + "\u2B50\u2B51\u2B52\u2B53\u2B54\u2B55\u2B56\u2B57"+ + "\u2B58\u2B59\u2B5A\u2B5B\u2B5C\u2B5D\u2B5E\u2B5F"+ + "\u2B60\u2B61\u2B62\u2B63\u2B64\u2B65\u2B66\u2B67"+ + "\u2B68\u2B69\u2B6A\u2B6B\u2B6C\u2B6D\u2B6E\u2B6F"+ + "\u2B70\u2B71\u2B72\u2B73\u2B74\u2B75\u2B76\u2B77"+ + "\u2B78\u2B79\u2B7A\u2B7B\u2B7C\u2B7D\u2B7E\u2B7F"+ + "\u2B80\u2B81\u2B82\u2B83\u2B84\u2B85\u2B86\u2B87"+ + "\u2B88\u2B89\u2B8A\u2B8B\u2B8C\u2B8D\u2B8E\u2B8F"+ + "\u2B90\u2B91\u2B92\u2B93\u2B94\u2B95\u2B96\u2B97"+ + "\u2B98\u2B99\u2B9A\u2B9B\u2B9C\u2B9D\u2B9E\u2B9F"+ + "\u2BA0\u2BA1\u2BA2\u2BA3\u2BA4\u2BA5\u2BA6\u2BA7"+ + "\u2BA8\u2BA9\u2BAA\u2BAB\u2BAC\u2BAD\u2BAE\u2BAF"+ + "\u2BB0\u2BB1\u2BB2\u2BB3\u2BB4\u2BB5\u2BB6\u2BB7"+ + "\u2BB8\u2BB9\u2BBA\u2BBB\u2BBC\u2BBD\u2BBE\u2BBF"+ + "\u2BC0\u2BC1\u2BC2\u2BC3\u2BC4\u2BC5\u2BC6\u2BC7"+ + "\u2BC8\u2BC9\u2BCA\u2BCB\u2BCC\u2BCD\u2BCE\u2BCF"+ + "\u2BD0\u2BD1\u2BD2\u2BD3\u2BD4\u2BD5\u2BD6\u2BD7"+ + "\u2BD8\u2BD9\u2BDA\u2BDB\u2BDC\u2BDD\u2BDE\u2BDF"+ + "\u2BE0\u2BE1\u2BE2\u2BE3\u2BE4\u2BE5\u2BE6\u2BE7"+ + "\u2BE8\u2BE9\u2BEA\u2BEB\u2BEC\u2BED\u2BEE\u2BEF"+ + "\u2BF0\u2BF1\u2BF2\u2BF3\u2BF4\u2BF5\u2BF6\u2BF7"+ + "\u2BF8\u2BF9\u2BFA\u2BFB\u2BFC\u2BFD\u2BFE\u2BFF"+ + "\u2C00\u2C01\u2C02\u2C03\u2C04\u2C05\u2C06\u2C07"+ + "\u2C08\u2C09\u2C0A\u2C0B\u2C0C\u2C0D\u2C0E\u2C0F"+ + "\u2C10\u2C11\u2C12\u2C13\u2C14\u2C15\u2C16\u2C17"+ + "\u2C18\u2C19\u2C1A\u2C1B\u2C1C\u2C1D\u2C1E\u2C1F"+ + "\u2C20\u2C21\u2C22\u2C23\u2C24\u2C25\u2C26\u2C27"+ + "\u2C28\u2C29\u2C2A\u2C2B\u2C2C\u2C2D\u2C2E\u2C2F"+ + "\u2C30\u2C31\u2C32\u2C33\u2C34\u2C35\u2C36\u2C37"+ + "\u2C38\u2C39\u2C3A\u2C3B\u2C3C\u2C3D\u2C3E\u2C3F"+ + "\u2C40\u2C41\u2C42\u2C43\u2C44\u2C45\u2C46\u2C47"+ + "\u2C48\u2C49\u2C4A\u2C4B\u2C4C\u2C4D\u2C4E\u2C4F"+ + "\u2C50\u2C51\u2C52\u2C53\u2C54\u2C55\u2C56\u2C57"+ + "\u2C58\u2C59\u2C5A\u2C5B\u2C5C\u2C5D\u2C5E\u2C5F"+ + "\u2C60\u2C61\u2C62\u2C63\u2C64\u2C65\u2C66\u2C67"+ + "\u2C68\u2C69\u2C6A\u2C6B\u2C6C\u2C6D\u2C6E\u2C6F"+ + "\u2C70\u2C71\u2C72\u2C73\u2C74\u2C75\u2C76\u2C77"+ + "\u2C78\u2C79\u2C7A\u2C7B\u2C7C\u2C7D\u2C7E\u2C7F"+ + "\u2C80\u2C81\u2C82\u2C83\u2C84\u2C85\u2C86\u2C87"+ + "\u2C88\u2C89\u2C8A\u2C8B\u2C8C\u2C8D\u2C8E\u2C8F"+ + "\u2C90\u2C91\u2C92\u2C93\u2C94\u2C95\u2C96\u2C97"+ + "\u2C98\u2C99\u2C9A\u2C9B\u2C9C\u2C9D\u2C9E\u2C9F"+ + "\u2CA0\u2CA1\u2CA2\u2CA3\u2CA4\u2CA5\u2CA6\u2CA7"+ + "\u2CA8\u2CA9\u2CAA\u2CAB\u2CAC\u2CAD\u2CAE\u2CAF"+ + "\u2CB0\u2CB1\u2CB2\u2CB3\u2CB4\u2CB5\u2CB6\u2CB7"+ + "\u2CB8\u2CB9\u2CBA\u2CBB\u2CBC\u2CBD\u2CBE\u2CBF"+ + "\u2CC0\u2CC1\u2CC2\u2CC3\u2CC4\u2CC5\u2CC6\u2CC7"+ + "\u2CC8\u2CC9\u2CCA\u2CCB\u2CCC\u2CCD\u2CCE\u2CCF"+ + "\u2CD0\u2CD1\u2CD2\u2CD3\u2CD4\u2CD5\u2CD6\u2CD7"+ + "\u2CD8\u2CD9\u2CDA\u2CDB\u2CDC\u2CDD\u2CDE\u2CDF"+ + "\u2CE0\u2CE1\u2CE2\u2CE3\u2CE4\u2CE5\u2CE6\u2CE7"+ + "\u2CE8\u2CE9\u2CEA\u2CEB\u2CEC\u2CED\u2CEE\u2CEF"+ + "\u2CF0\u2CF1\u2CF2\u2CF3\u2CF4\u2CF5\u2CF6\u2CF7"+ + "\u2CF8\u2CF9\u2CFA\u2CFB\u2CFC\u2CFD\u2CFE\u2CFF"+ + "\u2D00\u2D01\u2D02\u2D03\u2D04\u2D05\u2D06\u2D07"+ + "\u2D08\u2D09\u2D0A\u2D0B\u2D0C\u2D0D\u2D0E\u2D0F"+ + "\u2D10\u2D11\u2D12\u2D13\u2D14\u2D15\u2D16\u2D17"+ + "\u2D18\u2D19\u2D1A\u2D1B\u2D1C\u2D1D\u2D1E\u2D1F"+ + "\u2D20\u2D21\u2D22\u2D23\u2D24\u2D25\u2D26\u2D27"+ + "\u2D28\u2D29\u2D2A\u2D2B\u2D2C\u2D2D\u2D2E\u2D2F"+ + "\u2D30\u2D31\u2D32\u2D33\u2D34\u2D35\u2D36\u2D37"+ + "\u2D38\u2D39\u2D3A\u2D3B\u2D3C\u2D3D\u2D3E\u2D3F"+ + "\u2D40\u2D41\u2D42\u2D43\u2D44\u2D45\u2D46\u2D47"+ + "\u2D48\u2D49\u2D4A\u2D4B\u2D4C\u2D4D\u2D4E\u2D4F"+ + "\u2D50\u2D51\u2D52\u2D53\u2D54\u2D55\u2D56\u2D57"+ + "\u2D58\u2D59\u2D5A\u2D5B\u2D5C\u2D5D\u2D5E\u2D5F"+ + "\u2D60\u2D61\u2D62\u2D63\u2D64\u2D65\u2D66\u2D67"+ + "\u2D68\u2D69\u2D6A\u2D6B\u2D6C\u2D6D\u2D6E\u2D6F"+ + "\u2D70\u2D71\u2D72\u2D73\u2D74\u2D75\u2D76\u2D77"+ + "\u2D78\u2D79\u2D7A\u2D7B\u2D7C\u2D7D\u2D7E\u2D7F"+ + "\u2D80\u2D81\u2D82\u2D83\u2D84\u2D85\u2D86\u2D87"+ + "\u2D88\u2D89\u2D8A\u2D8B\u2D8C\u2D8D\u2D8E\u2D8F"+ + "\u2D90\u2D91\u2D92\u2D93\u2D94\u2D95\u2D96\u2D97"+ + "\u2D98\u2D99\u2D9A\u2D9B\u2D9C\u2D9D\u2D9E\u2D9F"+ + "\u2DA0\u2DA1\u2DA2\u2DA3\u2DA4\u2DA5\u2DA6\u2DA7"+ + "\u2DA8\u2DA9\u2DAA\u2DAB\u2DAC\u2DAD\u2DAE\u2DAF"+ + "\u2DB0\u2DB1\u2DB2\u2DB3\u2DB4\u2DB5\u2DB6\u2DB7"+ + "\u2DB8\u2DB9\u2DBA\u2DBB\u2DBC\u2DBD\u2DBE\u2DBF"+ + "\u2DC0\u2DC1\u2DC2\u2DC3\u2DC4\u2DC5\u2DC6\u2DC7"+ + "\u2DC8\u2DC9\u2DCA\u2DCB\u2DCC\u2DCD\u2DCE\u2DCF"+ + "\u2DD0\u2DD1\u2DD2\u2DD3\u2DD4\u2DD5\u2DD6\u2DD7"+ + "\u2DD8\u2DD9\u2DDA\u2DDB\u2DDC\u2DDD\u2DDE\u2DDF"+ + "\u2DE0\u2DE1\u2DE2\u2DE3\u2DE4\u2DE5\u2DE6\u2DE7"+ + "\u2DE8\u2DE9\u2DEA\u2DEB\u2DEC\u2DED\u2DEE\u2DEF"+ + "\u2DF0\u2DF1\u2DF2\u2DF3\u2DF4\u2DF5\u2DF6\u2DF7"+ + "\u2DF8\u2DF9\u2DFA\u2DFB\u2DFC\u2DFD\u2DFE\u2DFF"+ + "\u2E00\u2E01\u2E02\u2E03\u2E04\u2E05\u2E06\u2E07"+ + "\u2E08\u2E09\u2E0A\u2E0B\u2E0C\u2E0D\u2E0E\u2E0F"+ + "\u2E10\u2E11\u2E12\u2E13\u2E14\u2E15\u2E16\u2E17"+ + "\u2E18\u2E19\u2E1A\u2E1B\u2E1C\u2E1D\u2E1E\u2E1F"+ + "\u2E20\u2E21\u2E22\u2E23\u2E24\u2E25\u2E26\u2E27"+ + "\u2E28\u2E29\u2E2A\u2E2B\u2E2C\u2E2D\u2E2E\u2E2F"+ + "\u2E30\u2E31\u2E32\u2E33\u2E34\u2E35\u2E36\u2E37"+ + "\u2E38\u2E39\u2E3A\u2E3B\u2E3C\u2E3D\u2E3E\u2E3F"+ + "\u2E40\u2E41\u2E42\u2E43\u2E44\u2E45\u2E46\u2E47"+ + "\u2E48\u2E49\u2E4A\u2E4B\u2E4C\u2E4D\u2E4E\u2E4F"+ + "\u2E50\u2E51\u2E52\u2E53\u2E54\u2E55\u2E56\u2E57"+ + "\u2E58\u2E59\u2E5A\u2E5B\u2E5C\u2E5D\u2E5E\u2E5F"+ + "\u2E60\u2E61\u2E62\u2E63\u2E64\u2E65\u2E66\u2E67"+ + "\u2E68\u2E69\u2E6A\u2E6B\u2E6C\u2E6D\u2E6E\u2E6F"+ + "\u2E70\u2E71\u2E72\u2E73\u2E74\u2E75\u2E76\u2E77"+ + "\u2E78\u2E79\u2E7A\u2E7B\u2E7C\u2E7D\u2E7E\u2E7F"+ + "\u2E80\u2E82\u2E83\u2E85\u2E86\u2E87\u2E89\u2E8A"+ + "\u2E8D\u2E8E\u2E8F\u2E90\u2E91\u2E92\u2E93\u2E94"+ + "\u2E95\u2E96\u2E98\u2E99\u2E9A\u2E9B\u2E9C\u2E9D"+ + "\u2E9E\u2E9F\u2EA0\u2EA1\u2EA2\u2EA3\u2EA4\u2EA5"+ + "\u2EA6\u2EA8\u2EA9\u2EAB\u2EAC\u2EAD\u2EAF\u2EB0"+ + "\u2EB1\u2EB2\u2EB4\u2EB5\u2EB8\u2EB9\u2EBA\u2EBC"+ + "\u2EBD\u2EBE\u2EBF\u2EC0\u2EC1\u2EC2\u2EC3\u2EC4"+ + "\u2EC5\u2EC6\u2EC7\u2EC8\u2EC9\u2ECB\u2ECC\u2ECD"+ + "\u2ECE\u2ECF\u2ED0\u2ED1\u2ED2\u2ED3\u2ED4\u2ED5"+ + "\u2ED6\u2ED7\u2ED8\u2ED9\u2EDA\u2EDB\u2EDC\u2EDD"+ + "\u2EDE\u2EDF\u2EE0\u2EE1\u2EE2\u2EE3\u2EE4\u2EE5"+ + "\u2EE6\u2EE7\u2EE8\u2EE9\u2EEA\u2EEB\u2EEC\u2EED"+ + "\u2EEE\u2EEF\u2EF0\u2EF1\u2EF2\u2EF3\u2EF4\u2EF5"+ + "\u2EF6\u2EF7\u2EF8\u2EF9\u2EFA\u2EFB\u2EFC\u2EFD"+ + "\u2EFE\u2EFF\u2F00\u2F01\u2F02\u2F03\u2F04\u2F05"+ + "\u2F06\u2F07\u2F08\u2F09\u2F0A\u2F0B\u2F0C\u2F0D"+ + "\u2F0E\u2F0F\u2F10\u2F11\u2F12\u2F13\u2F14\u2F15"+ + "\u2F16\u2F17\u2F18\u2F19\u2F1A\u2F1B\u2F1C\u2F1D"+ + "\u2F1E\u2F1F\u2F20\u2F21\u2F22\u2F23\u2F24\u2F25"+ + "\u2F26\u2F27\u2F28\u2F29\u2F2A\u2F2B\u2F2C\u2F2D"+ + "\u2F2E\u2F2F\u2F30\u2F31\u2F32\u2F33\u2F34\u2F35"+ + "\u2F36\u2F37\u2F38\u2F39\u2F3A\u2F3B\u2F3C\u2F3D"+ + "\u2F3E\u2F3F\u2F40\u2F41\u2F42\u2F43\u2F44\u2F45"+ + "\u2F46\u2F47\u2F48\u2F49\u2F4A\u2F4B\u2F4C\u2F4D"+ + "\u2F4E\u2F4F\u2F50\u2F51\u2F52\u2F53\u2F54\u2F55"+ + "\u2F56\u2F57\u2F58\u2F59\u2F5A\u2F5B\u2F5C\u2F5D"+ + "\u2F5E\u2F5F\u2F60\u2F61\u2F62\u2F63\u2F64\u2F65"+ + "\u2F66\u2F67\u2F68\u2F69\u2F6A\u2F6B\u2F6C\u2F6D"+ + "\u2F6E\u2F6F\u2F70\u2F71\u2F72\u2F73\u2F74\u2F75"+ + "\u2F76\u2F77\u2F78\u2F79\u2F7A\u2F7B\u2F7C\u2F7D"+ + "\u2F7E\u2F7F\u2F80\u2F81\u2F82\u2F83\u2F84\u2F85"+ + "\u2F86\u2F87\u2F88\u2F89\u2F8A\u2F8B\u2F8C\u2F8D"+ + "\u2F8E\u2F8F\u2F90\u2F91\u2F92\u2F93\u2F94\u2F95"+ + "\u2F96\u2F97\u2F98\u2F99\u2F9A\u2F9B\u2F9C\u2F9D"+ + "\u2F9E\u2F9F\u2FA0\u2FA1\u2FA2\u2FA3\u2FA4\u2FA5"+ + "\u2FA6\u2FA7\u2FA8\u2FA9\u2FAA\u2FAB\u2FAC\u2FAD"+ + "\u2FAE\u2FAF\u2FB0\u2FB1\u2FB2\u2FB3\u2FB4\u2FB5"+ + "\u2FB6\u2FB7\u2FB8\u2FB9\u2FBA\u2FBB\u2FBC\u2FBD"+ + "\u2FBE\u2FBF\u2FC0\u2FC1\u2FC2\u2FC3\u2FC4\u2FC5"+ + "\u2FC6\u2FC7\u2FC8\u2FC9\u2FCA\u2FCB\u2FCC\u2FCD"+ + "\u2FCE\u2FCF\u2FD0\u2FD1\u2FD2\u2FD3\u2FD4\u2FD5"+ + "\u2FD6\u2FD7\u2FD8\u2FD9\u2FDA\u2FDB\u2FDC\u2FDD"+ + "\u2FDE\u2FDF\u2FE0\u2FE1\u2FE2\u2FE3\u2FE4\u2FE5"+ + "\u2FE6\u2FE7\u2FE8\u2FE9\u2FEA\u2FEB\u2FEC\u2FED"+ + "\u2FEE\u2FEF\u2FFC\u2FFD\u2FFE\u2FFF\u3004\u3018"+ + "\u3019\u301A\u301B\u301C\u301F\u3020\u302A\u302B"+ + "\u302C\u302D\u302E\u302F\u3030\u3031\u3032\u3033"+ + "\u3034\u3035\u3036\u3037\u3038\u3039\u303A\u303B"+ + "\u303C\u303D\u303F\u3040\u3094\u3095\u3096\u3097"+ + "\u3098\u3099\u309A\u309F\u30A0\u30F7\u30F8\u30F9"+ + "\u30FA\u30FB\u30FF\u3100\u3101\u3102\u3103\u3104"+ + "\u312A\u312B\u312C\u312D\u312E\u312F\u3130\u3131"+ + "\u3132\u3133\u3134\u3135\u3136\u3137\u3138\u3139"+ + "\u313A\u313B\u313C\u313D\u313E\u313F\u3140\u3141"+ + "\u3142\u3143\u3144\u3145\u3146\u3147\u3148\u3149"+ + "\u314A\u314B\u314C\u314D\u314E\u314F\u3150\u3151"+ + "\u3152\u3153\u3154\u3155\u3156\u3157\u3158\u3159"+ + "\u315A\u315B\u315C\u315D\u315E\u315F\u3160\u3161"+ + "\u3162\u3163\u3164\u3165\u3166\u3167\u3168\u3169"+ + "\u316A\u316B\u316C\u316D\u316E\u316F\u3170\u3171"+ + "\u3172\u3173\u3174\u3175\u3176\u3177\u3178\u3179"+ + "\u317A\u317B\u317C\u317D\u317E\u317F\u3180\u3181"+ + "\u3182\u3183\u3184\u3185\u3186\u3187\u3188\u3189"+ + "\u318A\u318B\u318C\u318D\u318E\u318F\u3190\u3191"+ + "\u3192\u3193\u3194\u3195\u3196\u3197\u3198\u3199"+ + "\u319A\u319B\u319C\u319D\u319E\u319F\u31A0\u31A1"+ + "\u31A2\u31A3\u31A4\u31A5\u31A6\u31A7\u31A8\u31A9"+ + "\u31AA\u31AB\u31AC\u31AD\u31AE\u31AF\u31B0\u31B1"+ + "\u31B2\u31B3\u31B4\u31B5\u31B6\u31B7\u31B8\u31B9"+ + "\u31BA\u31BB\u31BC\u31BD\u31BE\u31BF\u31C0\u31C1"+ + "\u31C2\u31C3\u31C4\u31C5\u31C6\u31C7\u31C8\u31C9"+ + "\u31CA\u31CB\u31CC\u31CD\u31CE\u31CF\u31D0\u31D1"+ + "\u31D2\u31D3\u31D4\u31D5\u31D6\u31D7\u31D8\u31D9"+ + "\u31DA\u31DB\u31DC\u31DD\u31DE\u31DF\u31E0\u31E1"+ + "\u31E2\u31E3\u31E4\u31E5\u31E6\u31E7\u31E8\u31E9"+ + "\u31EA\u31EB\u31EC\u31ED\u31EE\u31EF\u31F0\u31F1"+ + "\u31F2\u31F3\u31F4\u31F5\u31F6\u31F7\u31F8\u31F9"+ + "\u31FA\u31FB\u31FC\u31FD\u31FE\u31FF\u3200\u3201"+ + "\u3202\u3203\u3204\u3205\u3206\u3207\u3208\u3209"+ + "\u320A\u320B\u320C\u320D\u320E\u320F\u3210\u3211"+ + "\u3212\u3213\u3214\u3215\u3216\u3217\u3218\u3219"+ + "\u321A\u321B\u321C\u321D\u321E\u321F\u322A\u322B"+ + "\u322C\u322D\u322E\u322F\u3230\u3232\u3233\u3234"+ + "\u3235\u3236\u3237\u3238\u3239\u323A\u323B\u323C"+ + "\u323D\u323E\u323F\u3240\u3241\u3242\u3243\u3244"+ + "\u3245\u3246\u3247\u3248\u3249\u324A\u324B\u324C"+ + "\u324D\u324E\u324F\u3250\u3251\u3252\u3253\u3254"+ + "\u3255\u3256\u3257\u3258\u3259\u325A\u325B\u325C"+ + "\u325D\u325E\u325F\u3260\u3261\u3262\u3263\u3264"+ + "\u3265\u3266\u3267\u3268\u3269\u326A\u326B\u326C"+ + "\u326D\u326E\u326F\u3270\u3271\u3272\u3273\u3274"+ + "\u3275\u3276\u3277\u3278\u3279\u327A\u327B\u327C"+ + "\u327D\u327E\u327F\u3280\u3281\u3282\u3283\u3284"+ + "\u3285\u3286\u3287\u3288\u3289\u328A\u328B\u328C"+ + "\u328D\u328E\u328F\u3290\u3291\u3292\u3293\u3294"+ + "\u3295\u3296\u3297\u3298\u3299\u329A\u329B\u329C"+ + "\u329D\u329E\u329F\u32A0\u32A1\u32A2\u32A4\u32A5"+ + "\u32A6\u32A7\u32A8\u32A9\u32AA\u32AB\u32AC\u32AD"+ + "\u32AE\u32AF\u32B0\u32B1\u32B2\u32B3\u32B4\u32B5"+ + "\u32B6\u32B7\u32B8\u32B9\u32BA\u32BB\u32BC\u32BD"+ + "\u32BE\u32BF\u32C0\u32C1\u32C2\u32C3\u32C4\u32C5"+ + "\u32C6\u32C7\u32C8\u32C9\u32CA\u32CB\u32CC\u32CD"+ + "\u32CE\u32CF\u32D0\u32D1\u32D2\u32D3\u32D4\u32D5"+ + "\u32D6\u32D7\u32D8\u32D9\u32DA\u32DB\u32DC\u32DD"+ + "\u32DE\u32DF\u32E0\u32E1\u32E2\u32E3\u32E4\u32E5"+ + "\u32E6\u32E7\u32E8\u32E9\u32EA\u32EB\u32EC\u32ED"+ + "\u32EE\u32EF\u32F0\u32F1\u32F2\u32F3\u32F4\u32F5"+ + "\u32F6\u32F7\u32F8\u32F9\u32FA\u32FB\u32FC\u32FD"+ + "\u32FE\u32FF\u3300\u3301\u3302\u3303\u3304\u3305"+ + "\u3306\u3307\u3308\u3309\u330A\u330B\u330C\u330D"+ + "\u330E\u330F\u3310\u3311\u3312\u3313\u3314\u3315"+ + "\u3316\u3317\u3318\u3319\u331A\u331B\u331C\u331D"+ + "\u331E\u331F\u3320\u3321\u3322\u3323\u3324\u3325"+ + "\u3326\u3327\u3328\u3329\u332A\u332B\u332C\u332D"+ + "\u332E\u332F\u3330\u3331\u3332\u3333\u3334\u3335"+ + "\u3336\u3337\u3338\u3339\u333A\u333B\u333C\u333D"+ + "\u333E\u333F\u3340\u3341\u3342\u3343\u3344\u3345"+ + "\u3346\u3347\u3348\u3349\u334A\u334B\u334C\u334D"+ + "\u334E\u334F\u3350\u3351\u3352\u3353\u3354\u3355"+ + "\u3356\u3357\u3358\u3359\u335A\u335B\u335C\u335D"; + + private static final String innerDecoderIndex3= + "\u335E\u335F\u3360\u3361\u3362\u3363\u3364\u3365"+ + "\u3366\u3367\u3368\u3369\u336A\u336B\u336C\u336D"+ + "\u336E\u336F\u3370\u3371\u3372\u3373\u3374\u3375"+ + "\u3376\u3377\u3378\u3379\u337A\u337B\u337C\u337D"+ + "\u337E\u337F\u3380\u3381\u3382\u3383\u3384\u3385"+ + "\u3386\u3387\u3388\u3389\u338A\u338B\u338C\u338D"+ + "\u3390\u3391\u3392\u3393\u3394\u3395\u3396\u3397"+ + "\u3398\u3399\u339A\u339B\u339F\u33A0\u33A2\u33A3"+ + "\u33A4\u33A5\u33A6\u33A7\u33A8\u33A9\u33AA\u33AB"+ + "\u33AC\u33AD\u33AE\u33AF\u33B0\u33B1\u33B2\u33B3"+ + "\u33B4\u33B5\u33B6\u33B7\u33B8\u33B9\u33BA\u33BB"+ + "\u33BC\u33BD\u33BE\u33BF\u33C0\u33C1\u33C2\u33C3"+ + "\u33C5\u33C6\u33C7\u33C8\u33C9\u33CA\u33CB\u33CC"+ + "\u33CD\u33CF\u33D0\u33D3\u33D4\u33D6\u33D7\u33D8"+ + "\u33D9\u33DA\u33DB\u33DC\u33DD\u33DE\u33DF\u33E0"+ + "\u33E1\u33E2\u33E3\u33E4\u33E5\u33E6\u33E7\u33E8"+ + "\u33E9\u33EA\u33EB\u33EC\u33ED\u33EE\u33EF\u33F0"+ + "\u33F1\u33F2\u33F3\u33F4\u33F5\u33F6\u33F7\u33F8"+ + "\u33F9\u33FA\u33FB\u33FC\u33FD\u33FE\u33FF\u3400"+ + "\u3401\u3402\u3403\u3404\u3405\u3406\u3407\u3408"+ + "\u3409\u340A\u340B\u340C\u340D\u340E\u340F\u3410"+ + "\u3411\u3412\u3413\u3414\u3415\u3416\u3417\u3418"+ + "\u3419\u341A\u341B\u341C\u341D\u341E\u341F\u3420"+ + "\u3421\u3422\u3423\u3424\u3425\u3426\u3427\u3428"+ + "\u3429\u342A\u342B\u342C\u342D\u342E\u342F\u3430"+ + "\u3431\u3432\u3433\u3434\u3435\u3436\u3437\u3438"+ + "\u3439\u343A\u343B\u343C\u343D\u343E\u343F\u3440"+ + "\u3441\u3442\u3443\u3444\u3445\u3446\u3448\u3449"+ + "\u344A\u344B\u344C\u344D\u344E\u344F\u3450\u3451"+ + "\u3452\u3453\u3454\u3455\u3456\u3457\u3458\u3459"+ + "\u345A\u345B\u345C\u345D\u345E\u345F\u3460\u3461"+ + "\u3462\u3463\u3464\u3465\u3466\u3467\u3468\u3469"+ + "\u346A\u346B\u346C\u346D\u346E\u346F\u3470\u3471"+ + "\u3472\u3474\u3475\u3476\u3477\u3478\u3479\u347A"+ + "\u347B\u347C\u347D\u347E\u347F\u3480\u3481\u3482"+ + "\u3483\u3484\u3485\u3486\u3487\u3488\u3489\u348A"+ + "\u348B\u348C\u348D\u348E\u348F\u3490\u3491\u3492"+ + "\u3493\u3494\u3495\u3496\u3497\u3498\u3499\u349A"+ + "\u349B\u349C\u349D\u349E\u349F\u34A0\u34A1\u34A2"+ + "\u34A3\u34A4\u34A5\u34A6\u34A7\u34A8\u34A9\u34AA"+ + "\u34AB\u34AC\u34AD\u34AE\u34AF\u34B0\u34B1\u34B2"+ + "\u34B3\u34B4\u34B5\u34B6\u34B7\u34B8\u34B9\u34BA"+ + "\u34BB\u34BC\u34BD\u34BE\u34BF\u34C0\u34C1\u34C2"+ + "\u34C3\u34C4\u34C5\u34C6\u34C7\u34C8\u34C9\u34CA"+ + "\u34CB\u34CC\u34CD\u34CE\u34CF\u34D0\u34D1\u34D2"+ + "\u34D3\u34D4\u34D5\u34D6\u34D7\u34D8\u34D9\u34DA"+ + "\u34DB\u34DC\u34DD\u34DE\u34DF\u34E0\u34E1\u34E2"+ + "\u34E3\u34E4\u34E5\u34E6\u34E7\u34E8\u34E9\u34EA"+ + "\u34EB\u34EC\u34ED\u34EE\u34EF\u34F0\u34F1\u34F2"+ + "\u34F3\u34F4\u34F5\u34F6\u34F7\u34F8\u34F9\u34FA"+ + "\u34FB\u34FC\u34FD\u34FE\u34FF\u3500\u3501\u3502"+ + "\u3503\u3504\u3505\u3506\u3507\u3508\u3509\u350A"+ + "\u350B\u350C\u350D\u350E\u350F\u3510\u3511\u3512"+ + "\u3513\u3514\u3515\u3516\u3517\u3518\u3519\u351A"+ + "\u351B\u351C\u351D\u351E\u351F\u3520\u3521\u3522"+ + "\u3523\u3524\u3525\u3526\u3527\u3528\u3529\u352A"+ + "\u352B\u352C\u352D\u352E\u352F\u3530\u3531\u3532"+ + "\u3533\u3534\u3535\u3536\u3537\u3538\u3539\u353A"+ + "\u353B\u353C\u353D\u353E\u353F\u3540\u3541\u3542"+ + "\u3543\u3544\u3545\u3546\u3547\u3548\u3549\u354A"+ + "\u354B\u354C\u354D\u354E\u354F\u3550\u3551\u3552"+ + "\u3553\u3554\u3555\u3556\u3557\u3558\u3559\u355A"+ + "\u355B\u355C\u355D\u355E\u355F\u3560\u3561\u3562"+ + "\u3563\u3564\u3565\u3566\u3567\u3568\u3569\u356A"+ + "\u356B\u356C\u356D\u356E\u356F\u3570\u3571\u3572"+ + "\u3573\u3574\u3575\u3576\u3577\u3578\u3579\u357A"+ + "\u357B\u357C\u357D\u357E\u357F\u3580\u3581\u3582"+ + "\u3583\u3584\u3585\u3586\u3587\u3588\u3589\u358A"+ + "\u358B\u358C\u358D\u358E\u358F\u3590\u3591\u3592"+ + "\u3593\u3594\u3595\u3596\u3597\u3598\u3599\u359A"+ + "\u359B\u359C\u359D\u359F\u35A0\u35A1\u35A2\u35A3"+ + "\u35A4\u35A5\u35A6\u35A7\u35A8\u35A9\u35AA\u35AB"+ + "\u35AC\u35AD\u35AE\u35AF\u35B0\u35B1\u35B2\u35B3"+ + "\u35B4\u35B5\u35B6\u35B7\u35B8\u35B9\u35BA\u35BB"+ + "\u35BC\u35BD\u35BE\u35BF\u35C0\u35C1\u35C2\u35C3"+ + "\u35C4\u35C5\u35C6\u35C7\u35C8\u35C9\u35CA\u35CB"+ + "\u35CC\u35CD\u35CE\u35CF\u35D0\u35D1\u35D2\u35D3"+ + "\u35D4\u35D5\u35D6\u35D7\u35D8\u35D9\u35DA\u35DB"+ + "\u35DC\u35DD\u35DE\u35DF\u35E0\u35E1\u35E2\u35E3"+ + "\u35E4\u35E5\u35E6\u35E7\u35E8\u35E9\u35EA\u35EB"+ + "\u35EC\u35ED\u35EE\u35EF\u35F0\u35F1\u35F2\u35F3"+ + "\u35F4\u35F5\u35F6\u35F7\u35F8\u35F9\u35FA\u35FB"+ + "\u35FC\u35FD\u35FE\u35FF\u3600\u3601\u3602\u3603"+ + "\u3604\u3605\u3606\u3607\u3608\u3609\u360A\u360B"+ + "\u360C\u360D\u360F\u3610\u3611\u3612\u3613\u3614"+ + "\u3615\u3616\u3617\u3618\u3619\u361B\u361C\u361D"+ + "\u361E\u361F\u3620\u3621\u3622\u3623\u3624\u3625"+ + "\u3626\u3627\u3628\u3629\u362A\u362B\u362C\u362D"+ + "\u362E\u362F\u3630\u3631\u3632\u3633\u3634\u3635"+ + "\u3636\u3637\u3638\u3639\u363A\u363B\u363C\u363D"+ + "\u363E\u363F\u3640\u3641\u3642\u3643\u3644\u3645"+ + "\u3646\u3647\u3648\u3649\u364A\u364B\u364C\u364D"+ + "\u364E\u364F\u3650\u3651\u3652\u3653\u3654\u3655"+ + "\u3656\u3657\u3658\u3659\u365A\u365B\u365C\u365D"+ + "\u365E\u365F\u3660\u3661\u3662\u3663\u3664\u3665"+ + "\u3666\u3667\u3668\u3669\u366A\u366B\u366C\u366D"+ + "\u366E\u366F\u3670\u3671\u3672\u3673\u3674\u3675"+ + "\u3676\u3677\u3678\u3679\u367A\u367B\u367C\u367D"+ + "\u367E\u367F\u3680\u3681\u3682\u3683\u3684\u3685"+ + "\u3686\u3687\u3688\u3689\u368A\u368B\u368C\u368D"+ + "\u368E\u368F\u3690\u3691\u3692\u3693\u3694\u3695"+ + "\u3696\u3697\u3698\u3699\u369A\u369B\u369C\u369D"+ + "\u369E\u369F\u36A0\u36A1\u36A2\u36A3\u36A4\u36A5"+ + "\u36A6\u36A7\u36A8\u36A9\u36AA\u36AB\u36AC\u36AD"+ + "\u36AE\u36AF\u36B0\u36B1\u36B2\u36B3\u36B4\u36B5"+ + "\u36B6\u36B7\u36B8\u36B9\u36BA\u36BB\u36BC\u36BD"+ + "\u36BE\u36BF\u36C0\u36C1\u36C2\u36C3\u36C4\u36C5"+ + "\u36C6\u36C7\u36C8\u36C9\u36CA\u36CB\u36CC\u36CD"+ + "\u36CE\u36CF\u36D0\u36D1\u36D2\u36D3\u36D4\u36D5"+ + "\u36D6\u36D7\u36D8\u36D9\u36DA\u36DB\u36DC\u36DD"+ + "\u36DE\u36DF\u36E0\u36E1\u36E2\u36E3\u36E4\u36E5"+ + "\u36E6\u36E7\u36E8\u36E9\u36EA\u36EB\u36EC\u36ED"+ + "\u36EE\u36EF\u36F0\u36F1\u36F2\u36F3\u36F4\u36F5"+ + "\u36F6\u36F7\u36F8\u36F9\u36FA\u36FB\u36FC\u36FD"+ + "\u36FE\u36FF\u3700\u3701\u3702\u3703\u3704\u3705"+ + "\u3706\u3707\u3708\u3709\u370A\u370B\u370C\u370D"+ + "\u370E\u370F\u3710\u3711\u3712\u3713\u3714\u3715"+ + "\u3716\u3717\u3718\u3719\u371A\u371B\u371C\u371D"+ + "\u371E\u371F\u3720\u3721\u3722\u3723\u3724\u3725"+ + "\u3726\u3727\u3728\u3729\u372A\u372B\u372C\u372D"+ + "\u372E\u372F\u3730\u3731\u3732\u3733\u3734\u3735"+ + "\u3736\u3737\u3738\u3739\u373A\u373B\u373C\u373D"+ + "\u373E\u373F\u3740\u3741\u3742\u3743\u3744\u3745"+ + "\u3746\u3747\u3748\u3749\u374A\u374B\u374C\u374D"+ + "\u374E\u374F\u3750\u3751\u3752\u3753\u3754\u3755"+ + "\u3756\u3757\u3758\u3759\u375A\u375B\u375C\u375D"+ + "\u375E\u375F\u3760\u3761\u3762\u3763\u3764\u3765"+ + "\u3766\u3767\u3768\u3769\u376A\u376B\u376C\u376D"+ + "\u376E\u376F\u3770\u3771\u3772\u3773\u3774\u3775"+ + "\u3776\u3777\u3778\u3779\u377A\u377B\u377C\u377D"+ + "\u377E\u377F\u3780\u3781\u3782\u3783\u3784\u3785"+ + "\u3786\u3787\u3788\u3789\u378A\u378B\u378C\u378D"+ + "\u378E\u378F\u3790\u3791\u3792\u3793\u3794\u3795"+ + "\u3796\u3797\u3798\u3799\u379A\u379B\u379C\u379D"+ + "\u379E\u379F\u37A0\u37A1\u37A2\u37A3\u37A4\u37A5"+ + "\u37A6\u37A7\u37A8\u37A9\u37AA\u37AB\u37AC\u37AD"+ + "\u37AE\u37AF\u37B0\u37B1\u37B2\u37B3\u37B4\u37B5"+ + "\u37B6\u37B7\u37B8\u37B9\u37BA\u37BB\u37BC\u37BD"+ + "\u37BE\u37BF\u37C0\u37C1\u37C2\u37C3\u37C4\u37C5"+ + "\u37C6\u37C7\u37C8\u37C9\u37CA\u37CB\u37CC\u37CD"+ + "\u37CE\u37CF\u37D0\u37D1\u37D2\u37D3\u37D4\u37D5"+ + "\u37D6\u37D7\u37D8\u37D9\u37DA\u37DB\u37DC\u37DD"+ + "\u37DE\u37DF\u37E0\u37E1\u37E2\u37E3\u37E4\u37E5"+ + "\u37E6\u37E7\u37E8\u37E9\u37EA\u37EB\u37EC\u37ED"+ + "\u37EE\u37EF\u37F0\u37F1\u37F2\u37F3\u37F4\u37F5"+ + "\u37F6\u37F7\u37F8\u37F9\u37FA\u37FB\u37FC\u37FD"+ + "\u37FE\u37FF\u3800\u3801\u3802\u3803\u3804\u3805"+ + "\u3806\u3807\u3808\u3809\u380A\u380B\u380C\u380D"+ + "\u380E\u380F\u3810\u3811\u3812\u3813\u3814\u3815"+ + "\u3816\u3817\u3818\u3819\u381A\u381B\u381C\u381D"+ + "\u381E\u381F\u3820\u3821\u3822\u3823\u3824\u3825"+ + "\u3826\u3827\u3828\u3829\u382A\u382B\u382C\u382D"+ + "\u382E\u382F\u3830\u3831\u3832\u3833\u3834\u3835"+ + "\u3836\u3837\u3838\u3839\u383A\u383B\u383C\u383D"+ + "\u383E\u383F\u3840\u3841\u3842\u3843\u3844\u3845"+ + "\u3846\u3847\u3848\u3849\u384A\u384B\u384C\u384D"+ + "\u384E\u384F\u3850\u3851\u3852\u3853\u3854\u3855"+ + "\u3856\u3857\u3858\u3859\u385A\u385B\u385C\u385D"+ + "\u385E\u385F\u3860\u3861\u3862\u3863\u3864\u3865"+ + "\u3866\u3867\u3868\u3869\u386A\u386B\u386C\u386D"+ + "\u386E\u386F\u3870\u3871\u3872\u3873\u3874\u3875"+ + "\u3876\u3877\u3878\u3879\u387A\u387B\u387C\u387D"+ + "\u387E\u387F\u3880\u3881\u3882\u3883\u3884\u3885"+ + "\u3886\u3887\u3888\u3889\u388A\u388B\u388C\u388D"+ + "\u388E\u388F\u3890\u3891\u3892\u3893\u3894\u3895"+ + "\u3896\u3897\u3898\u3899\u389A\u389B\u389C\u389D"+ + "\u389E\u389F\u38A0\u38A1\u38A2\u38A3\u38A4\u38A5"+ + "\u38A6\u38A7\u38A8\u38A9\u38AA\u38AB\u38AC\u38AD"+ + "\u38AE\u38AF\u38B0\u38B1\u38B2\u38B3\u38B4\u38B5"+ + "\u38B6\u38B7\u38B8\u38B9\u38BA\u38BB\u38BC\u38BD"+ + "\u38BE\u38BF\u38C0\u38C1\u38C2\u38C3\u38C4\u38C5"+ + "\u38C6\u38C7\u38C8\u38C9\u38CA\u38CB\u38CC\u38CD"+ + "\u38CE\u38CF\u38D0\u38D1\u38D2\u38D3\u38D4\u38D5"+ + "\u38D6\u38D7\u38D8\u38D9\u38DA\u38DB\u38DC\u38DD"+ + "\u38DE\u38DF\u38E0\u38E1\u38E2\u38E3\u38E4\u38E5"+ + "\u38E6\u38E7\u38E8\u38E9\u38EA\u38EB\u38EC\u38ED"+ + "\u38EE\u38EF\u38F0\u38F1\u38F2\u38F3\u38F4\u38F5"+ + "\u38F6\u38F7\u38F8\u38F9\u38FA\u38FB\u38FC\u38FD"+ + "\u38FE\u38FF\u3900\u3901\u3902\u3903\u3904\u3905"+ + "\u3906\u3907\u3908\u3909\u390A\u390B\u390C\u390D"+ + "\u390E\u390F\u3910\u3911\u3912\u3913\u3914\u3915"+ + "\u3916\u3917\u3919\u391A\u391B\u391C\u391D\u391E"+ + "\u391F\u3920\u3921\u3922\u3923\u3924\u3925\u3926"+ + "\u3927\u3928\u3929\u392A\u392B\u392C\u392D\u392E"+ + "\u392F\u3930\u3931\u3932\u3933\u3934\u3935\u3936"+ + "\u3937\u3938\u3939\u393A\u393B\u393C\u393D\u393E"+ + "\u393F\u3940\u3941\u3942\u3943\u3944\u3945\u3946"+ + "\u3947\u3948\u3949\u394A\u394B\u394C\u394D\u394E"+ + "\u394F\u3950\u3951\u3952\u3953\u3954\u3955\u3956"+ + "\u3957\u3958\u3959\u395A\u395B\u395C\u395D\u395E"+ + "\u395F\u3960\u3961\u3962\u3963\u3964\u3965\u3966"+ + "\u3967\u3968\u3969\u396A\u396B\u396C\u396D\u396F"+ + "\u3970\u3971\u3972\u3973\u3974\u3975\u3976\u3977"+ + "\u3978\u3979\u397A\u397B\u397C\u397D\u397E\u397F"+ + "\u3980\u3981\u3982\u3983\u3984\u3985\u3986\u3987"+ + "\u3988\u3989\u398A\u398B\u398C\u398D\u398E\u398F"+ + "\u3990\u3991\u3992\u3993\u3994\u3995\u3996\u3997"+ + "\u3998\u3999\u399A\u399B\u399C\u399D\u399E\u399F"+ + "\u39A0\u39A1\u39A2\u39A3\u39A4\u39A5\u39A6\u39A7"+ + "\u39A8\u39A9\u39AA\u39AB\u39AC\u39AD\u39AE\u39AF"+ + "\u39B0\u39B1\u39B2\u39B3\u39B4\u39B5\u39B6\u39B7"+ + "\u39B8\u39B9\u39BA\u39BB\u39BC\u39BD\u39BE\u39BF"+ + "\u39C0\u39C1\u39C2\u39C3\u39C4\u39C5\u39C6\u39C7"+ + "\u39C8\u39C9\u39CA\u39CB\u39CC\u39CD\u39CE\u39D1"+ + "\u39D2\u39D3\u39D4\u39D5\u39D6\u39D7\u39D8\u39D9"+ + "\u39DA\u39DB\u39DC\u39DD\u39DE\u39E0\u39E1\u39E2"+ + "\u39E3\u39E4\u39E5\u39E6\u39E7\u39E8\u39E9\u39EA"+ + "\u39EB\u39EC\u39ED\u39EE\u39EF\u39F0\u39F1\u39F2"+ + "\u39F3\u39F4\u39F5\u39F6\u39F7\u39F8\u39F9\u39FA"+ + "\u39FB\u39FC\u39FD\u39FE\u39FF\u3A00\u3A01\u3A02"+ + "\u3A03\u3A04\u3A05\u3A06\u3A07\u3A08\u3A09\u3A0A"+ + "\u3A0B\u3A0C\u3A0D\u3A0E\u3A0F\u3A10\u3A11\u3A12"+ + "\u3A13\u3A14\u3A15\u3A16\u3A17\u3A18\u3A19\u3A1A"+ + "\u3A1B\u3A1C\u3A1D\u3A1E\u3A1F\u3A20\u3A21\u3A22"+ + "\u3A23\u3A24\u3A25\u3A26\u3A27\u3A28\u3A29\u3A2A"+ + "\u3A2B\u3A2C\u3A2D\u3A2E\u3A2F\u3A30\u3A31\u3A32"+ + "\u3A33\u3A34\u3A35\u3A36\u3A37\u3A38\u3A39\u3A3A"+ + "\u3A3B\u3A3C\u3A3D\u3A3E\u3A3F\u3A40\u3A41\u3A42"+ + "\u3A43\u3A44\u3A45\u3A46\u3A47\u3A48\u3A49\u3A4A"+ + "\u3A4B\u3A4C\u3A4D\u3A4E\u3A4F\u3A50\u3A51\u3A52"+ + "\u3A53\u3A54\u3A55\u3A56\u3A57\u3A58\u3A59\u3A5A"+ + "\u3A5B\u3A5C\u3A5D\u3A5E\u3A5F\u3A60\u3A61\u3A62"+ + "\u3A63\u3A64\u3A65\u3A66\u3A67\u3A68\u3A69\u3A6A"+ + "\u3A6B\u3A6C\u3A6D\u3A6E\u3A6F\u3A70\u3A71\u3A72"+ + "\u3A74\u3A75\u3A76\u3A77\u3A78\u3A79\u3A7A\u3A7B"+ + "\u3A7C\u3A7D\u3A7E\u3A7F\u3A80\u3A81\u3A82\u3A83"+ + "\u3A84\u3A85\u3A86\u3A87\u3A88\u3A89\u3A8A\u3A8B"+ + "\u3A8C\u3A8D\u3A8E\u3A8F\u3A90\u3A91\u3A92\u3A93"+ + "\u3A94\u3A95\u3A96\u3A97\u3A98\u3A99\u3A9A\u3A9B"+ + "\u3A9C\u3A9D\u3A9E\u3A9F\u3AA0\u3AA1\u3AA2\u3AA3"+ + "\u3AA4\u3AA5\u3AA6\u3AA7\u3AA8\u3AA9\u3AAA\u3AAB"+ + "\u3AAC\u3AAD\u3AAE\u3AAF\u3AB0\u3AB1\u3AB2\u3AB3"+ + "\u3AB4\u3AB5\u3AB6\u3AB7\u3AB8\u3AB9\u3ABA\u3ABB"+ + "\u3ABC\u3ABD\u3ABE\u3ABF\u3AC0\u3AC1\u3AC2\u3AC3"+ + "\u3AC4\u3AC5\u3AC6\u3AC7\u3AC8\u3AC9\u3ACA\u3ACB"+ + "\u3ACC\u3ACD\u3ACE\u3ACF\u3AD0\u3AD1\u3AD2\u3AD3"+ + "\u3AD4\u3AD5\u3AD6\u3AD7\u3AD8\u3AD9\u3ADA\u3ADB"+ + "\u3ADC\u3ADD\u3ADE\u3ADF\u3AE0\u3AE1\u3AE2\u3AE3"+ + "\u3AE4\u3AE5\u3AE6\u3AE7\u3AE8\u3AE9\u3AEA\u3AEB"+ + "\u3AEC\u3AED\u3AEE\u3AEF\u3AF0\u3AF1\u3AF2\u3AF3"+ + "\u3AF4\u3AF5\u3AF6\u3AF7\u3AF8\u3AF9\u3AFA\u3AFB"+ + "\u3AFC\u3AFD\u3AFE\u3AFF\u3B00\u3B01\u3B02\u3B03"+ + "\u3B04\u3B05\u3B06\u3B07\u3B08\u3B09\u3B0A\u3B0B"+ + "\u3B0C\u3B0D\u3B0E\u3B0F\u3B10\u3B11\u3B12\u3B13"+ + "\u3B14\u3B15\u3B16\u3B17\u3B18\u3B19\u3B1A\u3B1B"+ + "\u3B1C\u3B1D\u3B1E\u3B1F\u3B20\u3B21\u3B22\u3B23"+ + "\u3B24\u3B25\u3B26\u3B27\u3B28\u3B29\u3B2A\u3B2B"+ + "\u3B2C\u3B2D\u3B2E\u3B2F\u3B30\u3B31\u3B32\u3B33"+ + "\u3B34\u3B35\u3B36\u3B37\u3B38\u3B39\u3B3A\u3B3B"+ + "\u3B3C\u3B3D\u3B3E\u3B3F\u3B40\u3B41\u3B42\u3B43"+ + "\u3B44\u3B45\u3B46\u3B47\u3B48\u3B49\u3B4A\u3B4B"+ + "\u3B4C\u3B4D\u3B4F\u3B50\u3B51\u3B52\u3B53\u3B54"+ + "\u3B55\u3B56\u3B57\u3B58\u3B59\u3B5A\u3B5B\u3B5C"+ + "\u3B5D\u3B5E\u3B5F\u3B60\u3B61\u3B62\u3B63\u3B64"+ + "\u3B65\u3B66\u3B67\u3B68\u3B69\u3B6A\u3B6B\u3B6C"+ + "\u3B6D\u3B6E\u3B6F\u3B70\u3B71\u3B72\u3B73\u3B74"+ + "\u3B75\u3B76\u3B77\u3B78\u3B79\u3B7A\u3B7B\u3B7C"+ + "\u3B7D\u3B7E\u3B7F\u3B80\u3B81\u3B82\u3B83\u3B84"+ + "\u3B85\u3B86\u3B87\u3B88\u3B89\u3B8A\u3B8B\u3B8C"+ + "\u3B8D\u3B8E\u3B8F\u3B90\u3B91\u3B92\u3B93\u3B94"+ + "\u3B95\u3B96\u3B97\u3B98\u3B99\u3B9A\u3B9B\u3B9C"+ + "\u3B9D\u3B9E\u3B9F\u3BA0\u3BA1\u3BA2\u3BA3\u3BA4"+ + "\u3BA5\u3BA6\u3BA7\u3BA8\u3BA9\u3BAA\u3BAB\u3BAC"+ + "\u3BAD\u3BAE\u3BAF\u3BB0\u3BB1\u3BB2\u3BB3\u3BB4"+ + "\u3BB5\u3BB6\u3BB7\u3BB8\u3BB9\u3BBA\u3BBB\u3BBC"+ + "\u3BBD\u3BBE\u3BBF\u3BC0\u3BC1\u3BC2\u3BC3\u3BC4"+ + "\u3BC5\u3BC6\u3BC7\u3BC8\u3BC9\u3BCA\u3BCB\u3BCC"+ + "\u3BCD\u3BCE\u3BCF\u3BD0\u3BD1\u3BD2\u3BD3\u3BD4"+ + "\u3BD5\u3BD6\u3BD7\u3BD8\u3BD9\u3BDA\u3BDB\u3BDC"+ + "\u3BDD\u3BDE\u3BDF\u3BE0\u3BE1\u3BE2\u3BE3\u3BE4"+ + "\u3BE5\u3BE6\u3BE7\u3BE8\u3BE9\u3BEA\u3BEB\u3BEC"+ + "\u3BED\u3BEE\u3BEF\u3BF0\u3BF1\u3BF2\u3BF3\u3BF4"+ + "\u3BF5\u3BF6\u3BF7\u3BF8\u3BF9\u3BFA\u3BFB\u3BFC"+ + "\u3BFD\u3BFE\u3BFF\u3C00\u3C01\u3C02\u3C03\u3C04"+ + "\u3C05\u3C06\u3C07\u3C08\u3C09\u3C0A\u3C0B\u3C0C"+ + "\u3C0D\u3C0E\u3C0F\u3C10\u3C11\u3C12\u3C13\u3C14"+ + "\u3C15\u3C16\u3C17\u3C18\u3C19\u3C1A\u3C1B\u3C1C"+ + "\u3C1D\u3C1E\u3C1F\u3C20\u3C21\u3C22\u3C23\u3C24"+ + "\u3C25\u3C26\u3C27\u3C28\u3C29\u3C2A\u3C2B\u3C2C"+ + "\u3C2D\u3C2E\u3C2F\u3C30\u3C31\u3C32\u3C33\u3C34"+ + "\u3C35\u3C36\u3C37\u3C38\u3C39\u3C3A\u3C3B\u3C3C"+ + "\u3C3D\u3C3E\u3C3F\u3C40\u3C41\u3C42\u3C43\u3C44"+ + "\u3C45\u3C46\u3C47\u3C48\u3C49\u3C4A\u3C4B\u3C4C"+ + "\u3C4D\u3C4E\u3C4F\u3C50\u3C51\u3C52\u3C53\u3C54"+ + "\u3C55\u3C56\u3C57\u3C58\u3C59\u3C5A\u3C5B\u3C5C"+ + "\u3C5D\u3C5E\u3C5F\u3C60\u3C61\u3C62\u3C63\u3C64"+ + "\u3C65\u3C66\u3C67\u3C68\u3C69\u3C6A\u3C6B\u3C6C"+ + "\u3C6D\u3C6F\u3C70\u3C71\u3C72\u3C73\u3C74\u3C75"+ + "\u3C76\u3C77\u3C78\u3C79\u3C7A\u3C7B\u3C7C\u3C7D"+ + "\u3C7E\u3C7F\u3C80\u3C81\u3C82\u3C83\u3C84\u3C85"+ + "\u3C86\u3C87\u3C88\u3C89\u3C8A\u3C8B\u3C8C\u3C8D"+ + "\u3C8E\u3C8F\u3C90\u3C91\u3C92\u3C93\u3C94\u3C95"+ + "\u3C96\u3C97\u3C98\u3C99\u3C9A\u3C9B\u3C9C\u3C9D"+ + "\u3C9E\u3C9F\u3CA0\u3CA1\u3CA2\u3CA3\u3CA4\u3CA5"+ + "\u3CA6\u3CA7\u3CA8\u3CA9\u3CAA\u3CAB\u3CAC\u3CAD"+ + "\u3CAE\u3CAF\u3CB0\u3CB1\u3CB2\u3CB3\u3CB4\u3CB5"+ + "\u3CB6\u3CB7\u3CB8\u3CB9\u3CBA\u3CBB\u3CBC\u3CBD"+ + "\u3CBE\u3CBF\u3CC0\u3CC1\u3CC2\u3CC3\u3CC4\u3CC5"+ + "\u3CC6\u3CC7\u3CC8\u3CC9\u3CCA\u3CCB\u3CCC\u3CCD"+ + "\u3CCE\u3CCF\u3CD0\u3CD1\u3CD2\u3CD3\u3CD4\u3CD5"+ + "\u3CD6\u3CD7\u3CD8\u3CD9\u3CDA\u3CDB\u3CDC\u3CDD"+ + "\u3CDE\u3CDF\u3CE1\u3CE2\u3CE3\u3CE4\u3CE5\u3CE6"+ + "\u3CE7\u3CE8\u3CE9\u3CEA\u3CEB\u3CEC\u3CED\u3CEE"+ + "\u3CEF\u3CF0\u3CF1\u3CF2\u3CF3\u3CF4\u3CF5\u3CF6"+ + "\u3CF7\u3CF8\u3CF9\u3CFA\u3CFB\u3CFC\u3CFD\u3CFE"+ + "\u3CFF\u3D00\u3D01\u3D02\u3D03\u3D04\u3D05\u3D06"+ + "\u3D07\u3D08\u3D09\u3D0A\u3D0B\u3D0C\u3D0D\u3D0E"+ + "\u3D0F\u3D10\u3D11\u3D12\u3D13\u3D14\u3D15\u3D16"+ + "\u3D17\u3D18\u3D19\u3D1A\u3D1B\u3D1C\u3D1D\u3D1E"+ + "\u3D1F\u3D20\u3D21\u3D22\u3D23\u3D24\u3D25\u3D26"+ + "\u3D27\u3D28\u3D29\u3D2A\u3D2B\u3D2C\u3D2D\u3D2E"+ + "\u3D2F\u3D30\u3D31\u3D32\u3D33\u3D34\u3D35\u3D36"+ + "\u3D37\u3D38\u3D39\u3D3A\u3D3B\u3D3C\u3D3D\u3D3E"+ + "\u3D3F\u3D40\u3D41\u3D42\u3D43\u3D44\u3D45\u3D46"+ + "\u3D47\u3D48\u3D49\u3D4A\u3D4B\u3D4C\u3D4D\u3D4E"+ + "\u3D4F\u3D50\u3D51\u3D52\u3D53\u3D54\u3D55\u3D56"+ + "\u3D57\u3D58\u3D59\u3D5A\u3D5B\u3D5C\u3D5D\u3D5E"+ + "\u3D5F\u3D60\u3D61\u3D62\u3D63\u3D64\u3D65\u3D66"+ + "\u3D67\u3D68\u3D69\u3D6A\u3D6B\u3D6C\u3D6D\u3D6E"+ + "\u3D6F\u3D70\u3D71\u3D72\u3D73\u3D74\u3D75\u3D76"+ + "\u3D77\u3D78\u3D79\u3D7A\u3D7B\u3D7C\u3D7D\u3D7E"+ + "\u3D7F\u3D80\u3D81\u3D82\u3D83\u3D84\u3D85\u3D86"+ + "\u3D87\u3D88\u3D89\u3D8A\u3D8B\u3D8C\u3D8D\u3D8E"+ + "\u3D8F\u3D90\u3D91\u3D92\u3D93\u3D94\u3D95\u3D96"+ + "\u3D97\u3D98\u3D99\u3D9A\u3D9B\u3D9C\u3D9D\u3D9E"+ + "\u3D9F\u3DA0\u3DA1\u3DA2\u3DA3\u3DA4\u3DA5\u3DA6"+ + "\u3DA7\u3DA8\u3DA9\u3DAA\u3DAB\u3DAC\u3DAD\u3DAE"+ + "\u3DAF\u3DB0\u3DB1\u3DB2\u3DB3\u3DB4\u3DB5\u3DB6"+ + "\u3DB7\u3DB8\u3DB9\u3DBA\u3DBB\u3DBC\u3DBD\u3DBE"+ + "\u3DBF\u3DC0\u3DC1\u3DC2\u3DC3\u3DC4\u3DC5\u3DC6"+ + "\u3DC7\u3DC8\u3DC9\u3DCA\u3DCB\u3DCC\u3DCD\u3DCE"+ + "\u3DCF\u3DD0\u3DD1\u3DD2\u3DD3\u3DD4\u3DD5\u3DD6"+ + "\u3DD7\u3DD8\u3DD9\u3DDA\u3DDB\u3DDC\u3DDD\u3DDE"+ + "\u3DDF\u3DE0\u3DE1\u3DE2\u3DE3\u3DE4\u3DE5\u3DE6"+ + "\u3DE7\u3DE8\u3DE9\u3DEA\u3DEB\u3DEC\u3DED\u3DEE"+ + "\u3DEF\u3DF0\u3DF1\u3DF2\u3DF3\u3DF4\u3DF5\u3DF6"+ + "\u3DF7\u3DF8\u3DF9\u3DFA\u3DFB\u3DFC\u3DFD\u3DFE"+ + "\u3DFF\u3E00\u3E01\u3E02\u3E03\u3E04\u3E05\u3E06"+ + "\u3E07\u3E08\u3E09\u3E0A\u3E0B\u3E0C\u3E0D\u3E0E"+ + "\u3E0F\u3E10\u3E11\u3E12\u3E13\u3E14\u3E15\u3E16"+ + "\u3E17\u3E18\u3E19\u3E1A\u3E1B\u3E1C\u3E1D\u3E1E"+ + "\u3E1F\u3E20\u3E21\u3E22\u3E23\u3E24\u3E25\u3E26"+ + "\u3E27\u3E28\u3E29\u3E2A\u3E2B\u3E2C\u3E2D\u3E2E"+ + "\u3E2F\u3E30\u3E31\u3E32\u3E33\u3E34\u3E35\u3E36"+ + "\u3E37\u3E38\u3E39\u3E3A\u3E3B\u3E3C\u3E3D\u3E3E"+ + "\u3E3F\u3E40\u3E41\u3E42\u3E43\u3E44\u3E45\u3E46"+ + "\u3E47\u3E48\u3E49\u3E4A\u3E4B\u3E4C\u3E4D\u3E4E"+ + "\u3E4F\u3E50\u3E51\u3E52\u3E53\u3E54\u3E55\u3E56"+ + "\u3E57\u3E58\u3E59\u3E5A\u3E5B\u3E5C\u3E5D\u3E5E"+ + "\u3E5F\u3E60\u3E61\u3E62\u3E63\u3E64\u3E65\u3E66"+ + "\u3E67\u3E68\u3E69\u3E6A\u3E6B\u3E6C\u3E6D\u3E6E"+ + "\u3E6F\u3E70\u3E71\u3E72\u3E73\u3E74\u3E75\u3E76"+ + "\u3E77\u3E78\u3E79\u3E7A\u3E7B\u3E7C\u3E7D\u3E7E"+ + "\u3E7F\u3E80\u3E81\u3E82\u3E83\u3E84\u3E85\u3E86"+ + "\u3E87\u3E88\u3E89\u3E8A\u3E8B\u3E8C\u3E8D\u3E8E"+ + "\u3E8F\u3E90\u3E91\u3E92\u3E93\u3E94\u3E95\u3E96"+ + "\u3E97\u3E98\u3E99\u3E9A\u3E9B\u3E9C\u3E9D\u3E9E"+ + "\u3E9F\u3EA0\u3EA1\u3EA2\u3EA3\u3EA4\u3EA5\u3EA6"+ + "\u3EA7\u3EA8\u3EA9\u3EAA\u3EAB\u3EAC\u3EAD\u3EAE"+ + "\u3EAF\u3EB0\u3EB1\u3EB2\u3EB3\u3EB4\u3EB5\u3EB6"+ + "\u3EB7\u3EB8\u3EB9\u3EBA\u3EBB\u3EBC\u3EBD\u3EBE"+ + "\u3EBF\u3EC0\u3EC1\u3EC2\u3EC3\u3EC4\u3EC5\u3EC6"+ + "\u3EC7\u3EC8\u3EC9\u3ECA\u3ECB\u3ECC\u3ECD\u3ECE"+ + "\u3ECF\u3ED0\u3ED1\u3ED2\u3ED3\u3ED4\u3ED5\u3ED6"+ + "\u3ED7\u3ED8\u3ED9\u3EDA\u3EDB\u3EDC\u3EDD\u3EDE"+ + "\u3EDF\u3EE0\u3EE1\u3EE2\u3EE3\u3EE4\u3EE5\u3EE6"+ + "\u3EE7\u3EE8\u3EE9\u3EEA\u3EEB\u3EEC\u3EED\u3EEE"+ + "\u3EEF\u3EF0\u3EF1\u3EF2\u3EF3\u3EF4\u3EF5\u3EF6"+ + "\u3EF7\u3EF8\u3EF9\u3EFA\u3EFB\u3EFC\u3EFD\u3EFE"+ + "\u3EFF\u3F00\u3F01\u3F02\u3F03\u3F04\u3F05\u3F06"+ + "\u3F07\u3F08\u3F09\u3F0A\u3F0B\u3F0C\u3F0D\u3F0E"+ + "\u3F0F\u3F10\u3F11\u3F12\u3F13\u3F14\u3F15\u3F16"+ + "\u3F17\u3F18\u3F19\u3F1A\u3F1B\u3F1C\u3F1D\u3F1E"+ + "\u3F1F\u3F20\u3F21\u3F22\u3F23\u3F24\u3F25\u3F26"+ + "\u3F27\u3F28\u3F29\u3F2A\u3F2B\u3F2C\u3F2D\u3F2E"+ + "\u3F2F\u3F30\u3F31\u3F32\u3F33\u3F34\u3F35\u3F36"+ + "\u3F37\u3F38\u3F39\u3F3A\u3F3B\u3F3C\u3F3D\u3F3E"+ + "\u3F3F\u3F40\u3F41\u3F42\u3F43\u3F44\u3F45\u3F46"+ + "\u3F47\u3F48\u3F49\u3F4A\u3F4B\u3F4C\u3F4D\u3F4E"+ + "\u3F4F\u3F50\u3F51\u3F52\u3F53\u3F54\u3F55\u3F56"+ + "\u3F57\u3F58\u3F59\u3F5A\u3F5B\u3F5C\u3F5D\u3F5E"+ + "\u3F5F\u3F60\u3F61\u3F62\u3F63\u3F64\u3F65\u3F66"+ + "\u3F67\u3F68\u3F69\u3F6A\u3F6B\u3F6C\u3F6D\u3F6E"+ + "\u3F6F\u3F70\u3F71\u3F72\u3F73\u3F74\u3F75\u3F76"+ + "\u3F77\u3F78\u3F79\u3F7A\u3F7B\u3F7C\u3F7D\u3F7E"+ + "\u3F7F\u3F80\u3F81\u3F82\u3F83\u3F84\u3F85\u3F86"+ + "\u3F87\u3F88\u3F89\u3F8A\u3F8B\u3F8C\u3F8D\u3F8E"+ + "\u3F8F\u3F90\u3F91\u3F92\u3F93\u3F94\u3F95\u3F96"+ + "\u3F97\u3F98\u3F99\u3F9A\u3F9B\u3F9C\u3F9D\u3F9E"+ + "\u3F9F\u3FA0\u3FA1\u3FA2\u3FA3\u3FA4\u3FA5\u3FA6"+ + "\u3FA7\u3FA8\u3FA9\u3FAA\u3FAB\u3FAC\u3FAD\u3FAE"+ + "\u3FAF\u3FB0\u3FB1\u3FB2\u3FB3\u3FB4\u3FB5\u3FB6"+ + "\u3FB7\u3FB8\u3FB9\u3FBA\u3FBB\u3FBC\u3FBD\u3FBE"+ + "\u3FBF\u3FC0\u3FC1\u3FC2\u3FC3\u3FC4\u3FC5\u3FC6"+ + "\u3FC7\u3FC8\u3FC9\u3FCA\u3FCB\u3FCC\u3FCD\u3FCE"+ + "\u3FCF\u3FD0\u3FD1\u3FD2\u3FD3\u3FD4\u3FD5\u3FD6"+ + "\u3FD7\u3FD8\u3FD9\u3FDA\u3FDB\u3FDC\u3FDD\u3FDE"+ + "\u3FDF\u3FE0\u3FE1\u3FE2\u3FE3\u3FE4\u3FE5\u3FE6"+ + "\u3FE7\u3FE8\u3FE9\u3FEA\u3FEB\u3FEC\u3FED\u3FEE"+ + "\u3FEF\u3FF0\u3FF1\u3FF2\u3FF3\u3FF4\u3FF5\u3FF6"+ + "\u3FF7\u3FF8\u3FF9\u3FFA\u3FFB\u3FFC\u3FFD\u3FFE"+ + "\u3FFF\u4000\u4001\u4002\u4003\u4004\u4005\u4006"+ + "\u4007\u4008\u4009\u400A\u400B\u400C\u400D\u400E"+ + "\u400F\u4010\u4011\u4012\u4013\u4014\u4015\u4016"+ + "\u4017\u4018\u4019\u401A\u401B\u401C\u401D\u401E"+ + "\u401F\u4020\u4021\u4022\u4023\u4024\u4025\u4026"+ + "\u4027\u4028\u4029\u402A\u402B\u402C\u402D\u402E"+ + "\u402F\u4030\u4031\u4032\u4033\u4034\u4035\u4036"+ + "\u4037\u4038\u4039\u403A\u403B\u403C\u403D\u403E"+ + "\u403F\u4040\u4041\u4042\u4043\u4044\u4045\u4046"+ + "\u4047\u4048\u4049\u404A\u404B\u404C\u404D\u404E"+ + "\u404F\u4050\u4051\u4052\u4053\u4054\u4055\u4057"+ + "\u4058\u4059\u405A\u405B\u405C\u405D\u405E\u405F"+ + "\u4060\u4061\u4062\u4063\u4064\u4065\u4066\u4067"+ + "\u4068\u4069\u406A\u406B\u406C\u406D\u406E\u406F"+ + "\u4070\u4071\u4072\u4073\u4074\u4075\u4076\u4077"+ + "\u4078\u4079\u407A\u407B\u407C\u407D\u407E\u407F"+ + "\u4080\u4081\u4082\u4083\u4084\u4085\u4086\u4087"+ + "\u4088\u4089\u408A\u408B\u408C\u408D\u408E\u408F"+ + "\u4090\u4091\u4092\u4093\u4094\u4095\u4096\u4097"+ + "\u4098\u4099\u409A\u409B\u409C\u409D\u409E\u409F"+ + "\u40A0\u40A1\u40A2\u40A3\u40A4\u40A5\u40A6\u40A7"+ + "\u40A8\u40A9\u40AA\u40AB\u40AC\u40AD\u40AE\u40AF"+ + "\u40B0\u40B1\u40B2\u40B3\u40B4\u40B5\u40B6\u40B7"+ + "\u40B8\u40B9\u40BA\u40BB\u40BC\u40BD\u40BE\u40BF"+ + "\u40C0\u40C1\u40C2\u40C3\u40C4\u40C5\u40C6\u40C7"+ + "\u40C8\u40C9\u40CA\u40CB\u40CC\u40CD\u40CE\u40CF"+ + "\u40D0\u40D1\u40D2\u40D3\u40D4\u40D5\u40D6\u40D7"+ + "\u40D8\u40D9\u40DA\u40DB\u40DC\u40DD\u40DE\u40DF"+ + "\u40E0\u40E1\u40E2\u40E3\u40E4\u40E5\u40E6\u40E7"+ + "\u40E8\u40E9\u40EA\u40EB\u40EC\u40ED\u40EE\u40EF"+ + "\u40F0\u40F1\u40F2\u40F3\u40F4\u40F5\u40F6\u40F7"+ + "\u40F8\u40F9\u40FA\u40FB\u40FC\u40FD\u40FE\u40FF"+ + "\u4100\u4101\u4102\u4103\u4104\u4105\u4106\u4107"+ + "\u4108\u4109\u410A\u410B\u410C\u410D\u410E\u410F"+ + "\u4110\u4111\u4112\u4113\u4114\u4115\u4116\u4117"+ + "\u4118\u4119\u411A\u411B\u411C\u411D\u411E\u411F"+ + "\u4120\u4121\u4122\u4123\u4124\u4125\u4126\u4127"+ + "\u4128\u4129\u412A\u412B\u412C\u412D\u412E\u412F"+ + "\u4130\u4131\u4132\u4133\u4134\u4135\u4136\u4137"+ + "\u4138\u4139\u413A\u413B\u413C\u413D\u413E\u413F"+ + "\u4140\u4141\u4142\u4143\u4144\u4145\u4146\u4147"+ + "\u4148\u4149\u414A\u414B\u414C\u414D\u414E\u414F"+ + "\u4150\u4151\u4152\u4153\u4154\u4155\u4156\u4157"+ + "\u4158\u4159\u415A\u415B\u415C\u415D\u415E\u4160"+ + "\u4161\u4162\u4163\u4164\u4165\u4166\u4167\u4168"+ + "\u4169\u416A\u416B\u416C\u416D\u416E\u416F\u4170"+ + "\u4171\u4172\u4173\u4174\u4175\u4176\u4177\u4178"+ + "\u4179\u417A\u417B\u417C\u417D\u417E\u417F\u4180"+ + "\u4181\u4182\u4183\u4184\u4185\u4186\u4187\u4188"+ + "\u4189\u418A\u418B\u418C\u418D\u418E\u418F\u4190"+ + "\u4191\u4192\u4193\u4194\u4195\u4196\u4197\u4198"+ + "\u4199\u419A\u419B\u419C\u419D\u419E\u419F\u41A0"+ + "\u41A1\u41A2\u41A3\u41A4\u41A5\u41A6\u41A7\u41A8"+ + "\u41A9\u41AA\u41AB\u41AC\u41AD\u41AE\u41AF\u41B0"+ + "\u41B1\u41B2\u41B3\u41B4\u41B5\u41B6\u41B7\u41B8"+ + "\u41B9\u41BA\u41BB\u41BC\u41BD\u41BE\u41BF\u41C0"+ + "\u41C1\u41C2\u41C3\u41C4\u41C5\u41C6\u41C7\u41C8"+ + "\u41C9\u41CA\u41CB\u41CC\u41CD\u41CE\u41CF\u41D0"+ + "\u41D1\u41D2\u41D3\u41D4\u41D5\u41D6\u41D7\u41D8"+ + "\u41D9\u41DA\u41DB\u41DC\u41DD\u41DE\u41DF\u41E0"+ + "\u41E1\u41E2\u41E3\u41E4\u41E5\u41E6\u41E7\u41E8"+ + "\u41E9\u41EA\u41EB\u41EC\u41ED\u41EE\u41EF\u41F0"+ + "\u41F1\u41F2\u41F3\u41F4\u41F5\u41F6\u41F7\u41F8"+ + "\u41F9\u41FA\u41FB\u41FC\u41FD\u41FE\u41FF\u4200"+ + "\u4201\u4202\u4203\u4204\u4205\u4206\u4207\u4208"+ + "\u4209\u420A\u420B\u420C\u420D\u420E\u420F\u4210"+ + "\u4211\u4212\u4213\u4214\u4215\u4216\u4217\u4218"+ + "\u4219\u421A\u421B\u421C\u421D\u421E\u421F\u4220"+ + "\u4221\u4222\u4223\u4224\u4225\u4226\u4227\u4228"+ + "\u4229\u422A\u422B\u422C\u422D\u422E\u422F\u4230"+ + "\u4231\u4232\u4233\u4234\u4235\u4236\u4237\u4238"+ + "\u4239\u423A\u423B\u423C\u423D\u423E\u423F\u4240"+ + "\u4241\u4242\u4243\u4244\u4245\u4246\u4247\u4248"+ + "\u4249\u424A\u424B\u424C\u424D\u424E\u424F\u4250"+ + "\u4251\u4252\u4253\u4254\u4255\u4256\u4257\u4258"+ + "\u4259\u425A\u425B\u425C\u425D\u425E\u425F\u4260"+ + "\u4261\u4262\u4263\u4264\u4265\u4266\u4267\u4268"+ + "\u4269\u426A\u426B\u426C\u426D\u426E\u426F\u4270"+ + "\u4271\u4272\u4273\u4274\u4275\u4276\u4277\u4278"+ + "\u4279\u427A\u427B\u427C\u427D\u427E\u427F\u4280"+ + "\u4281\u4282\u4283\u4284\u4285\u4286\u4287\u4288"+ + "\u4289\u428A\u428B\u428C\u428D\u428E\u428F\u4290"+ + "\u4291\u4292\u4293\u4294\u4295\u4296\u4297\u4298"+ + "\u4299\u429A\u429B\u429C\u429D\u429E\u429F\u42A0"+ + "\u42A1\u42A2\u42A3\u42A4\u42A5\u42A6\u42A7\u42A8"+ + "\u42A9\u42AA\u42AB\u42AC\u42AD\u42AE\u42AF\u42B0"+ + "\u42B1\u42B2\u42B3\u42B4\u42B5\u42B6\u42B7\u42B8"+ + "\u42B9\u42BA\u42BB\u42BC\u42BD\u42BE\u42BF\u42C0"+ + "\u42C1\u42C2\u42C3\u42C4\u42C5\u42C6\u42C7\u42C8"+ + "\u42C9\u42CA\u42CB\u42CC\u42CD\u42CE\u42CF\u42D0"+ + "\u42D1\u42D2\u42D3\u42D4\u42D5\u42D6\u42D7\u42D8"+ + "\u42D9\u42DA\u42DB\u42DC\u42DD\u42DE\u42DF\u42E0"+ + "\u42E1\u42E2\u42E3\u42E4\u42E5\u42E6\u42E7\u42E8"+ + "\u42E9\u42EA\u42EB\u42EC\u42ED\u42EE\u42EF\u42F0"+ + "\u42F1\u42F2\u42F3\u42F4\u42F5\u42F6\u42F7\u42F8"+ + "\u42F9\u42FA\u42FB\u42FC\u42FD\u42FE\u42FF\u4300"+ + "\u4301\u4302\u4303\u4304\u4305\u4306\u4307\u4308"+ + "\u4309\u430A\u430B\u430C\u430D\u430E\u430F\u4310"+ + "\u4311\u4312\u4313\u4314\u4315\u4316\u4317\u4318"+ + "\u4319\u431A\u431B\u431C\u431D\u431E\u431F\u4320"+ + "\u4321\u4322\u4323\u4324\u4325\u4326\u4327\u4328"+ + "\u4329\u432A\u432B\u432C\u432D\u432E\u432F\u4330"+ + "\u4331\u4332\u4333\u4334\u4335\u4336\u4338\u4339"+ + "\u433A\u433B\u433C\u433D\u433E\u433F\u4340\u4341"+ + "\u4342\u4343\u4344\u4345\u4346\u4347\u4348\u4349"+ + "\u434A\u434B\u434C\u434D\u434E\u434F\u4350\u4351"+ + "\u4352\u4353\u4354\u4355\u4356\u4357\u4358\u4359"+ + "\u435A\u435B\u435C\u435D\u435E\u435F\u4360\u4361"+ + "\u4362\u4363\u4364\u4365\u4366\u4367\u4368\u4369"+ + "\u436A\u436B\u436C\u436D\u436E\u436F\u4370\u4371"+ + "\u4372\u4373\u4374\u4375\u4376\u4377\u4378\u4379"; + + private static final String innerDecoderIndex4= + "\u437A\u437B\u437C\u437D\u437E\u437F\u4380\u4381"+ + "\u4382\u4383\u4384\u4385\u4386\u4387\u4388\u4389"+ + "\u438A\u438B\u438C\u438D\u438E\u438F\u4390\u4391"+ + "\u4392\u4393\u4394\u4395\u4396\u4397\u4398\u4399"+ + "\u439A\u439B\u439C\u439D\u439E\u439F\u43A0\u43A1"+ + "\u43A2\u43A3\u43A4\u43A5\u43A6\u43A7\u43A8\u43A9"+ + "\u43AA\u43AB\u43AD\u43AE\u43AF\u43B0\u43B2\u43B3"+ + "\u43B4\u43B5\u43B6\u43B7\u43B8\u43B9\u43BA\u43BB"+ + "\u43BC\u43BD\u43BE\u43BF\u43C0\u43C1\u43C2\u43C3"+ + "\u43C4\u43C5\u43C6\u43C7\u43C8\u43C9\u43CA\u43CB"+ + "\u43CC\u43CD\u43CE\u43CF\u43D0\u43D1\u43D2\u43D3"+ + "\u43D4\u43D5\u43D6\u43D7\u43D8\u43D9\u43DA\u43DB"+ + "\u43DC\u43DE\u43DF\u43E0\u43E1\u43E2\u43E3\u43E4"+ + "\u43E5\u43E6\u43E7\u43E8\u43E9\u43EA\u43EB\u43EC"+ + "\u43ED\u43EE\u43EF\u43F0\u43F1\u43F2\u43F3\u43F4"+ + "\u43F5\u43F6\u43F7\u43F8\u43F9\u43FA\u43FB\u43FC"+ + "\u43FD\u43FE\u43FF\u4400\u4401\u4402\u4403\u4404"+ + "\u4405\u4406\u4407\u4408\u4409\u440A\u440B\u440C"+ + "\u440D\u440E\u440F\u4410\u4411\u4412\u4413\u4414"+ + "\u4415\u4416\u4417\u4418\u4419\u441A\u441B\u441C"+ + "\u441D\u441E\u441F\u4420\u4421\u4422\u4423\u4424"+ + "\u4425\u4426\u4427\u4428\u4429\u442A\u442B\u442C"+ + "\u442D\u442E\u442F\u4430\u4431\u4432\u4433\u4434"+ + "\u4435\u4436\u4437\u4438\u4439\u443A\u443B\u443C"+ + "\u443D\u443E\u443F\u4440\u4441\u4442\u4443\u4444"+ + "\u4445\u4446\u4447\u4448\u4449\u444A\u444B\u444C"+ + "\u444D\u444E\u444F\u4450\u4451\u4452\u4453\u4454"+ + "\u4455\u4456\u4457\u4458\u4459\u445A\u445B\u445C"+ + "\u445D\u445E\u445F\u4460\u4461\u4462\u4463\u4464"+ + "\u4465\u4466\u4467\u4468\u4469\u446A\u446B\u446C"+ + "\u446D\u446E\u446F\u4470\u4471\u4472\u4473\u4474"+ + "\u4475\u4476\u4477\u4478\u4479\u447A\u447B\u447C"+ + "\u447D\u447E\u447F\u4480\u4481\u4482\u4483\u4484"+ + "\u4485\u4486\u4487\u4488\u4489\u448A\u448B\u448C"+ + "\u448D\u448E\u448F\u4490\u4491\u4492\u4493\u4494"+ + "\u4495\u4496\u4497\u4498\u4499\u449A\u449B\u449C"+ + "\u449D\u449E\u449F\u44A0\u44A1\u44A2\u44A3\u44A4"+ + "\u44A5\u44A6\u44A7\u44A8\u44A9\u44AA\u44AB\u44AC"+ + "\u44AD\u44AE\u44AF\u44B0\u44B1\u44B2\u44B3\u44B4"+ + "\u44B5\u44B6\u44B7\u44B8\u44B9\u44BA\u44BB\u44BC"+ + "\u44BD\u44BE\u44BF\u44C0\u44C1\u44C2\u44C3\u44C4"+ + "\u44C5\u44C6\u44C7\u44C8\u44C9\u44CA\u44CB\u44CC"+ + "\u44CD\u44CE\u44CF\u44D0\u44D1\u44D2\u44D3\u44D4"+ + "\u44D5\u44D7\u44D8\u44D9\u44DA\u44DB\u44DC\u44DD"+ + "\u44DE\u44DF\u44E0\u44E1\u44E2\u44E3\u44E4\u44E5"+ + "\u44E6\u44E7\u44E8\u44E9\u44EA\u44EB\u44EC\u44ED"+ + "\u44EE\u44EF\u44F0\u44F1\u44F2\u44F3\u44F4\u44F5"+ + "\u44F6\u44F7\u44F8\u44F9\u44FA\u44FB\u44FC\u44FD"+ + "\u44FE\u44FF\u4500\u4501\u4502\u4503\u4504\u4505"+ + "\u4506\u4507\u4508\u4509\u450A\u450B\u450C\u450D"+ + "\u450E\u450F\u4510\u4511\u4512\u4513\u4514\u4515"+ + "\u4516\u4517\u4518\u4519\u451A\u451B\u451C\u451D"+ + "\u451E\u451F\u4520\u4521\u4522\u4523\u4524\u4525"+ + "\u4526\u4527\u4528\u4529\u452A\u452B\u452C\u452D"+ + "\u452E\u452F\u4530\u4531\u4532\u4533\u4534\u4535"+ + "\u4536\u4537\u4538\u4539\u453A\u453B\u453C\u453D"+ + "\u453E\u453F\u4540\u4541\u4542\u4543\u4544\u4545"+ + "\u4546\u4547\u4548\u4549\u454A\u454B\u454C\u454D"+ + "\u454E\u454F\u4550\u4551\u4552\u4553\u4554\u4555"+ + "\u4556\u4557\u4558\u4559\u455A\u455B\u455C\u455D"+ + "\u455E\u455F\u4560\u4561\u4562\u4563\u4564\u4565"+ + "\u4566\u4567\u4568\u4569\u456A\u456B\u456C\u456D"+ + "\u456E\u456F\u4570\u4571\u4572\u4573\u4574\u4575"+ + "\u4576\u4577\u4578\u4579\u457A\u457B\u457C\u457D"+ + "\u457E\u457F\u4580\u4581\u4582\u4583\u4584\u4585"+ + "\u4586\u4587\u4588\u4589\u458A\u458B\u458C\u458D"+ + "\u458E\u458F\u4590\u4591\u4592\u4593\u4594\u4595"+ + "\u4596\u4597\u4598\u4599\u459A\u459B\u459C\u459D"+ + "\u459E\u459F\u45A0\u45A1\u45A2\u45A3\u45A4\u45A5"+ + "\u45A6\u45A7\u45A8\u45A9\u45AA\u45AB\u45AC\u45AD"+ + "\u45AE\u45AF\u45B0\u45B1\u45B2\u45B3\u45B4\u45B5"+ + "\u45B6\u45B7\u45B8\u45B9\u45BA\u45BB\u45BC\u45BD"+ + "\u45BE\u45BF\u45C0\u45C1\u45C2\u45C3\u45C4\u45C5"+ + "\u45C6\u45C7\u45C8\u45C9\u45CA\u45CB\u45CC\u45CD"+ + "\u45CE\u45CF\u45D0\u45D1\u45D2\u45D3\u45D4\u45D5"+ + "\u45D6\u45D7\u45D8\u45D9\u45DA\u45DB\u45DC\u45DD"+ + "\u45DE\u45DF\u45E0\u45E1\u45E2\u45E3\u45E4\u45E5"+ + "\u45E6\u45E7\u45E8\u45E9\u45EA\u45EB\u45EC\u45ED"+ + "\u45EE\u45EF\u45F0\u45F1\u45F2\u45F3\u45F4\u45F5"+ + "\u45F6\u45F7\u45F8\u45F9\u45FA\u45FB\u45FC\u45FD"+ + "\u45FE\u45FF\u4600\u4601\u4602\u4603\u4604\u4605"+ + "\u4606\u4607\u4608\u4609\u460A\u460B\u460C\u460D"+ + "\u460E\u460F\u4610\u4611\u4612\u4613\u4614\u4615"+ + "\u4616\u4617\u4618\u4619\u461A\u461B\u461C\u461D"+ + "\u461E\u461F\u4620\u4621\u4622\u4623\u4624\u4625"+ + "\u4626\u4627\u4628\u4629\u462A\u462B\u462C\u462D"+ + "\u462E\u462F\u4630\u4631\u4632\u4633\u4634\u4635"+ + "\u4636\u4637\u4638\u4639\u463A\u463B\u463C\u463D"+ + "\u463E\u463F\u4640\u4641\u4642\u4643\u4644\u4645"+ + "\u4646\u4647\u4648\u4649\u464A\u464B\u464D\u464E"+ + "\u464F\u4650\u4651\u4652\u4653\u4654\u4655\u4656"+ + "\u4657\u4658\u4659\u465A\u465B\u465C\u465D\u465E"+ + "\u465F\u4660\u4662\u4663\u4664\u4665\u4666\u4667"+ + "\u4668\u4669\u466A\u466B\u466C\u466D\u466E\u466F"+ + "\u4670\u4671\u4672\u4673\u4674\u4675\u4676\u4677"+ + "\u4678\u4679\u467A\u467B\u467C\u467D\u467E\u467F"+ + "\u4680\u4681\u4682\u4683\u4684\u4685\u4686\u4687"+ + "\u4688\u4689\u468A\u468B\u468C\u468D\u468E\u468F"+ + "\u4690\u4691\u4692\u4693\u4694\u4695\u4696\u4697"+ + "\u4698\u4699\u469A\u469B\u469C\u469D\u469E\u469F"+ + "\u46A0\u46A1\u46A2\u46A3\u46A4\u46A5\u46A6\u46A7"+ + "\u46A8\u46A9\u46AA\u46AB\u46AC\u46AD\u46AE\u46AF"+ + "\u46B0\u46B1\u46B2\u46B3\u46B4\u46B5\u46B6\u46B7"+ + "\u46B8\u46B9\u46BA\u46BB\u46BC\u46BD\u46BE\u46BF"+ + "\u46C0\u46C1\u46C2\u46C3\u46C4\u46C5\u46C6\u46C7"+ + "\u46C8\u46C9\u46CA\u46CB\u46CC\u46CD\u46CE\u46CF"+ + "\u46D0\u46D1\u46D2\u46D3\u46D4\u46D5\u46D6\u46D7"+ + "\u46D8\u46D9\u46DA\u46DB\u46DC\u46DD\u46DE\u46DF"+ + "\u46E0\u46E1\u46E2\u46E3\u46E4\u46E5\u46E6\u46E7"+ + "\u46E8\u46E9\u46EA\u46EB\u46EC\u46ED\u46EE\u46EF"+ + "\u46F0\u46F1\u46F2\u46F3\u46F4\u46F5\u46F6\u46F7"+ + "\u46F8\u46F9\u46FA\u46FB\u46FC\u46FD\u46FE\u46FF"+ + "\u4700\u4701\u4702\u4703\u4704\u4705\u4706\u4707"+ + "\u4708\u4709\u470A\u470B\u470C\u470D\u470E\u470F"+ + "\u4710\u4711\u4712\u4713\u4714\u4715\u4716\u4717"+ + "\u4718\u4719\u471A\u471B\u471C\u471D\u471E\u471F"+ + "\u4720\u4721\u4722\u4724\u4725\u4726\u4727\u4728"+ + "\u472A\u472B\u472C\u472D\u472E\u472F\u4730\u4731"+ + "\u4732\u4733\u4734\u4735\u4736\u4737\u4738\u4739"+ + "\u473A\u473B\u473C\u473D\u473E\u473F\u4740\u4741"+ + "\u4742\u4743\u4744\u4745\u4746\u4747\u4748\u4749"+ + "\u474A\u474B\u474C\u474D\u474E\u474F\u4750\u4751"+ + "\u4752\u4753\u4754\u4755\u4756\u4757\u4758\u4759"+ + "\u475A\u475B\u475C\u475D\u475E\u475F\u4760\u4761"+ + "\u4762\u4763\u4764\u4765\u4766\u4767\u4768\u4769"+ + "\u476A\u476B\u476C\u476D\u476E\u476F\u4770\u4771"+ + "\u4772\u4773\u4774\u4775\u4776\u4777\u4778\u4779"+ + "\u477A\u477B\u477D\u477E\u477F\u4780\u4781\u4782"+ + "\u4783\u4784\u4785\u4786\u4787\u4788\u4789\u478A"+ + "\u478B\u478C\u478E\u478F\u4790\u4791\u4792\u4793"+ + "\u4794\u4795\u4796\u4797\u4798\u4799\u479A\u479B"+ + "\u479C\u479D\u479E\u479F\u47A0\u47A1\u47A2\u47A3"+ + "\u47A4\u47A5\u47A6\u47A7\u47A8\u47A9\u47AA\u47AB"+ + "\u47AC\u47AD\u47AE\u47AF\u47B0\u47B1\u47B2\u47B3"+ + "\u47B4\u47B5\u47B6\u47B7\u47B8\u47B9\u47BA\u47BB"+ + "\u47BC\u47BD\u47BE\u47BF\u47C0\u47C1\u47C2\u47C3"+ + "\u47C4\u47C5\u47C6\u47C7\u47C8\u47C9\u47CA\u47CB"+ + "\u47CC\u47CD\u47CE\u47CF\u47D0\u47D1\u47D2\u47D3"+ + "\u47D4\u47D5\u47D6\u47D7\u47D8\u47D9\u47DA\u47DB"+ + "\u47DC\u47DD\u47DE\u47DF\u47E0\u47E1\u47E2\u47E3"+ + "\u47E4\u47E5\u47E6\u47E7\u47E8\u47E9\u47EA\u47EB"+ + "\u47EC\u47ED\u47EE\u47EF\u47F0\u47F1\u47F2\u47F3"+ + "\u47F4\u47F5\u47F6\u47F7\u47F8\u47F9\u47FA\u47FB"+ + "\u47FC\u47FD\u47FE\u47FF\u4800\u4801\u4802\u4803"+ + "\u4804\u4805\u4806\u4807\u4808\u4809\u480A\u480B"+ + "\u480C\u480D\u480E\u480F\u4810\u4811\u4812\u4813"+ + "\u4814\u4815\u4816\u4817\u4818\u4819\u481A\u481B"+ + "\u481C\u481D\u481E\u481F\u4820\u4821\u4822\u4823"+ + "\u4824\u4825\u4826\u4827\u4828\u4829\u482A\u482B"+ + "\u482C\u482D\u482E\u482F\u4830\u4831\u4832\u4833"+ + "\u4834\u4835\u4836\u4837\u4838\u4839\u483A\u483B"+ + "\u483C\u483D\u483E\u483F\u4840\u4841\u4842\u4843"+ + "\u4844\u4845\u4846\u4847\u4848\u4849\u484A\u484B"+ + "\u484C\u484D\u484E\u484F\u4850\u4851\u4852\u4853"+ + "\u4854\u4855\u4856\u4857\u4858\u4859\u485A\u485B"+ + "\u485C\u485D\u485E\u485F\u4860\u4861\u4862\u4863"+ + "\u4864\u4865\u4866\u4867\u4868\u4869\u486A\u486B"+ + "\u486C\u486D\u486E\u486F\u4870\u4871\u4872\u4873"+ + "\u4874\u4875\u4876\u4877\u4878\u4879\u487A\u487B"+ + "\u487C\u487D\u487E\u487F\u4880\u4881\u4882\u4883"+ + "\u4884\u4885\u4886\u4887\u4888\u4889\u488A\u488B"+ + "\u488C\u488D\u488E\u488F\u4890\u4891\u4892\u4893"+ + "\u4894\u4895\u4896\u4897\u4898\u4899\u489A\u489B"+ + "\u489C\u489D\u489E\u489F\u48A0\u48A1\u48A2\u48A3"+ + "\u48A4\u48A5\u48A6\u48A7\u48A8\u48A9\u48AA\u48AB"+ + "\u48AC\u48AD\u48AE\u48AF\u48B0\u48B1\u48B2\u48B3"+ + "\u48B4\u48B5\u48B6\u48B7\u48B8\u48B9\u48BA\u48BB"+ + "\u48BC\u48BD\u48BE\u48BF\u48C0\u48C1\u48C2\u48C3"+ + "\u48C4\u48C5\u48C6\u48C7\u48C8\u48C9\u48CA\u48CB"+ + "\u48CC\u48CD\u48CE\u48CF\u48D0\u48D1\u48D2\u48D3"+ + "\u48D4\u48D5\u48D6\u48D7\u48D8\u48D9\u48DA\u48DB"+ + "\u48DC\u48DD\u48DE\u48DF\u48E0\u48E1\u48E2\u48E3"+ + "\u48E4\u48E5\u48E6\u48E7\u48E8\u48E9\u48EA\u48EB"+ + "\u48EC\u48ED\u48EE\u48EF\u48F0\u48F1\u48F2\u48F3"+ + "\u48F4\u48F5\u48F6\u48F7\u48F8\u48F9\u48FA\u48FB"+ + "\u48FC\u48FD\u48FE\u48FF\u4900\u4901\u4902\u4903"+ + "\u4904\u4905\u4906\u4907\u4908\u4909\u490A\u490B"+ + "\u490C\u490D\u490E\u490F\u4910\u4911\u4912\u4913"+ + "\u4914\u4915\u4916\u4917\u4918\u4919\u491A\u491B"+ + "\u491C\u491D\u491E\u491F\u4920\u4921\u4922\u4923"+ + "\u4924\u4925\u4926\u4927\u4928\u4929\u492A\u492B"+ + "\u492C\u492D\u492E\u492F\u4930\u4931\u4932\u4933"+ + "\u4934\u4935\u4936\u4937\u4938\u4939\u493A\u493B"+ + "\u493C\u493D\u493E\u493F\u4940\u4941\u4942\u4943"+ + "\u4944\u4945\u4946\u4948\u4949\u494A\u494B\u494C"+ + "\u494D\u494E\u494F\u4950\u4951\u4952\u4953\u4954"+ + "\u4955\u4956\u4957\u4958\u4959\u495A\u495B\u495C"+ + "\u495D\u495E\u495F\u4960\u4961\u4962\u4963\u4964"+ + "\u4965\u4966\u4967\u4968\u4969\u496A\u496B\u496C"+ + "\u496D\u496E\u496F\u4970\u4971\u4972\u4973\u4974"+ + "\u4975\u4976\u4977\u4978\u4979\u497B\u497C\u497E"+ + "\u497F\u4980\u4981\u4984\u4987\u4988\u4989\u498A"+ + "\u498B\u498C\u498D\u498E\u498F\u4990\u4991\u4992"+ + "\u4993\u4994\u4995\u4996\u4997\u4998\u4999\u499A"+ + "\u499C\u499D\u499E\u49A0\u49A1\u49A2\u49A3\u49A4"+ + "\u49A5\u49A6\u49A7\u49A8\u49A9\u49AA\u49AB\u49AC"+ + "\u49AD\u49AE\u49AF\u49B0\u49B1\u49B2\u49B3\u49B4"+ + "\u49B5\u49B8\u49B9\u49BA\u49BB\u49BC\u49BD\u49BE"+ + "\u49BF\u49C0\u49C1\u49C2\u49C3\u49C4\u49C5\u49C6"+ + "\u49C7\u49C8\u49C9\u49CA\u49CB\u49CC\u49CD\u49CE"+ + "\u49CF\u49D0\u49D1\u49D2\u49D3\u49D4\u49D5\u49D6"+ + "\u49D7\u49D8\u49D9\u49DA\u49DB\u49DC\u49DD\u49DE"+ + "\u49DF\u49E0\u49E1\u49E2\u49E3\u49E4\u49E5\u49E6"+ + "\u49E7\u49E8\u49E9\u49EA\u49EB\u49EC\u49ED\u49EE"+ + "\u49EF\u49F0\u49F1\u49F2\u49F3\u49F4\u49F5\u49F6"+ + "\u49F7\u49F8\u49F9\u49FA\u49FB\u49FC\u49FD\u49FE"+ + "\u49FF\u4A00\u4A01\u4A02\u4A03\u4A04\u4A05\u4A06"+ + "\u4A07\u4A08\u4A09\u4A0A\u4A0B\u4A0C\u4A0D\u4A0E"+ + "\u4A0F\u4A10\u4A11\u4A12\u4A13\u4A14\u4A15\u4A16"+ + "\u4A17\u4A18\u4A19\u4A1A\u4A1B\u4A1C\u4A1D\u4A1E"+ + "\u4A1F\u4A20\u4A21\u4A22\u4A23\u4A24\u4A25\u4A26"+ + "\u4A27\u4A28\u4A29\u4A2A\u4A2B\u4A2C\u4A2D\u4A2E"+ + "\u4A2F\u4A30\u4A31\u4A32\u4A33\u4A34\u4A35\u4A36"+ + "\u4A37\u4A38\u4A39\u4A3A\u4A3B\u4A3C\u4A3D\u4A3E"+ + "\u4A3F\u4A40\u4A41\u4A42\u4A43\u4A44\u4A45\u4A46"+ + "\u4A47\u4A48\u4A49\u4A4A\u4A4B\u4A4C\u4A4D\u4A4E"+ + "\u4A4F\u4A50\u4A51\u4A52\u4A53\u4A54\u4A55\u4A56"+ + "\u4A57\u4A58\u4A59\u4A5A\u4A5B\u4A5C\u4A5D\u4A5E"+ + "\u4A5F\u4A60\u4A61\u4A62\u4A63\u4A64\u4A65\u4A66"+ + "\u4A67\u4A68\u4A69\u4A6A\u4A6B\u4A6C\u4A6D\u4A6E"+ + "\u4A6F\u4A70\u4A71\u4A72\u4A73\u4A74\u4A75\u4A76"+ + "\u4A77\u4A78\u4A79\u4A7A\u4A7B\u4A7C\u4A7D\u4A7E"+ + "\u4A7F\u4A80\u4A81\u4A82\u4A83\u4A84\u4A85\u4A86"+ + "\u4A87\u4A88\u4A89\u4A8A\u4A8B\u4A8C\u4A8D\u4A8E"+ + "\u4A8F\u4A90\u4A91\u4A92\u4A93\u4A94\u4A95\u4A96"+ + "\u4A97\u4A98\u4A99\u4A9A\u4A9B\u4A9C\u4A9D\u4A9E"+ + "\u4A9F\u4AA0\u4AA1\u4AA2\u4AA3\u4AA4\u4AA5\u4AA6"+ + "\u4AA7\u4AA8\u4AA9\u4AAA\u4AAB\u4AAC\u4AAD\u4AAE"+ + "\u4AAF\u4AB0\u4AB1\u4AB2\u4AB3\u4AB4\u4AB5\u4AB6"+ + "\u4AB7\u4AB8\u4AB9\u4ABA\u4ABB\u4ABC\u4ABD\u4ABE"+ + "\u4ABF\u4AC0\u4AC1\u4AC2\u4AC3\u4AC4\u4AC5\u4AC6"+ + "\u4AC7\u4AC8\u4AC9\u4ACA\u4ACB\u4ACC\u4ACD\u4ACE"+ + "\u4ACF\u4AD0\u4AD1\u4AD2\u4AD3\u4AD4\u4AD5\u4AD6"+ + "\u4AD7\u4AD8\u4AD9\u4ADA\u4ADB\u4ADC\u4ADD\u4ADE"+ + "\u4ADF\u4AE0\u4AE1\u4AE2\u4AE3\u4AE4\u4AE5\u4AE6"+ + "\u4AE7\u4AE8\u4AE9\u4AEA\u4AEB\u4AEC\u4AED\u4AEE"+ + "\u4AEF\u4AF0\u4AF1\u4AF2\u4AF3\u4AF4\u4AF5\u4AF6"+ + "\u4AF7\u4AF8\u4AF9\u4AFA\u4AFB\u4AFC\u4AFD\u4AFE"+ + "\u4AFF\u4B00\u4B01\u4B02\u4B03\u4B04\u4B05\u4B06"+ + "\u4B07\u4B08\u4B09\u4B0A\u4B0B\u4B0C\u4B0D\u4B0E"+ + "\u4B0F\u4B10\u4B11\u4B12\u4B13\u4B14\u4B15\u4B16"+ + "\u4B17\u4B18\u4B19\u4B1A\u4B1B\u4B1C\u4B1D\u4B1E"+ + "\u4B1F\u4B20\u4B21\u4B22\u4B23\u4B24\u4B25\u4B26"+ + "\u4B27\u4B28\u4B29\u4B2A\u4B2B\u4B2C\u4B2D\u4B2E"+ + "\u4B2F\u4B30\u4B31\u4B32\u4B33\u4B34\u4B35\u4B36"+ + "\u4B37\u4B38\u4B39\u4B3A\u4B3B\u4B3C\u4B3D\u4B3E"+ + "\u4B3F\u4B40\u4B41\u4B42\u4B43\u4B44\u4B45\u4B46"+ + "\u4B47\u4B48\u4B49\u4B4A\u4B4B\u4B4C\u4B4D\u4B4E"+ + "\u4B4F\u4B50\u4B51\u4B52\u4B53\u4B54\u4B55\u4B56"+ + "\u4B57\u4B58\u4B59\u4B5A\u4B5B\u4B5C\u4B5D\u4B5E"+ + "\u4B5F\u4B60\u4B61\u4B62\u4B63\u4B64\u4B65\u4B66"+ + "\u4B67\u4B68\u4B69\u4B6A\u4B6B\u4B6C\u4B6D\u4B6E"+ + "\u4B6F\u4B70\u4B71\u4B72\u4B73\u4B74\u4B75\u4B76"+ + "\u4B77\u4B78\u4B79\u4B7A\u4B7B\u4B7C\u4B7D\u4B7E"+ + "\u4B7F\u4B80\u4B81\u4B82\u4B83\u4B84\u4B85\u4B86"+ + "\u4B87\u4B88\u4B89\u4B8A\u4B8B\u4B8C\u4B8D\u4B8E"+ + "\u4B8F\u4B90\u4B91\u4B92\u4B93\u4B94\u4B95\u4B96"+ + "\u4B97\u4B98\u4B99\u4B9A\u4B9B\u4B9C\u4B9D\u4B9E"+ + "\u4B9F\u4BA0\u4BA1\u4BA2\u4BA3\u4BA4\u4BA5\u4BA6"+ + "\u4BA7\u4BA8\u4BA9\u4BAA\u4BAB\u4BAC\u4BAD\u4BAE"+ + "\u4BAF\u4BB0\u4BB1\u4BB2\u4BB3\u4BB4\u4BB5\u4BB6"+ + "\u4BB7\u4BB8\u4BB9\u4BBA\u4BBB\u4BBC\u4BBD\u4BBE"+ + "\u4BBF\u4BC0\u4BC1\u4BC2\u4BC3\u4BC4\u4BC5\u4BC6"+ + "\u4BC7\u4BC8\u4BC9\u4BCA\u4BCB\u4BCC\u4BCD\u4BCE"+ + "\u4BCF\u4BD0\u4BD1\u4BD2\u4BD3\u4BD4\u4BD5\u4BD6"+ + "\u4BD7\u4BD8\u4BD9\u4BDA\u4BDB\u4BDC\u4BDD\u4BDE"+ + "\u4BDF\u4BE0\u4BE1\u4BE2\u4BE3\u4BE4\u4BE5\u4BE6"+ + "\u4BE7\u4BE8\u4BE9\u4BEA\u4BEB\u4BEC\u4BED\u4BEE"+ + "\u4BEF\u4BF0\u4BF1\u4BF2\u4BF3\u4BF4\u4BF5\u4BF6"+ + "\u4BF7\u4BF8\u4BF9\u4BFA\u4BFB\u4BFC\u4BFD\u4BFE"+ + "\u4BFF\u4C00\u4C01\u4C02\u4C03\u4C04\u4C05\u4C06"+ + "\u4C07\u4C08\u4C09\u4C0A\u4C0B\u4C0C\u4C0D\u4C0E"+ + "\u4C0F\u4C10\u4C11\u4C12\u4C13\u4C14\u4C15\u4C16"+ + "\u4C17\u4C18\u4C19\u4C1A\u4C1B\u4C1C\u4C1D\u4C1E"+ + "\u4C1F\u4C20\u4C21\u4C22\u4C23\u4C24\u4C25\u4C26"+ + "\u4C27\u4C28\u4C29\u4C2A\u4C2B\u4C2C\u4C2D\u4C2E"+ + "\u4C2F\u4C30\u4C31\u4C32\u4C33\u4C34\u4C35\u4C36"+ + "\u4C37\u4C38\u4C39\u4C3A\u4C3B\u4C3C\u4C3D\u4C3E"+ + "\u4C3F\u4C40\u4C41\u4C42\u4C43\u4C44\u4C45\u4C46"+ + "\u4C47\u4C48\u4C49\u4C4A\u4C4B\u4C4C\u4C4D\u4C4E"+ + "\u4C4F\u4C50\u4C51\u4C52\u4C53\u4C54\u4C55\u4C56"+ + "\u4C57\u4C58\u4C59\u4C5A\u4C5B\u4C5C\u4C5D\u4C5E"+ + "\u4C5F\u4C60\u4C61\u4C62\u4C63\u4C64\u4C65\u4C66"+ + "\u4C67\u4C68\u4C69\u4C6A\u4C6B\u4C6C\u4C6D\u4C6E"+ + "\u4C6F\u4C70\u4C71\u4C72\u4C73\u4C74\u4C75\u4C76"+ + "\u4C78\u4C79\u4C7A\u4C7B\u4C7C\u4C7D\u4C7E\u4C7F"+ + "\u4C80\u4C81\u4C82\u4C83\u4C84\u4C85\u4C86\u4C87"+ + "\u4C88\u4C89\u4C8A\u4C8B\u4C8C\u4C8D\u4C8E\u4C8F"+ + "\u4C90\u4C91\u4C92\u4C93\u4C94\u4C95\u4C96\u4C97"+ + "\u4C98\u4C99\u4C9A\u4C9B\u4C9C\u4C9D\u4C9E\u4CA4"+ + "\u4CA5\u4CA6\u4CA7\u4CA8\u4CA9\u4CAA\u4CAB\u4CAC"+ + "\u4CAD\u4CAE\u4CAF\u4CB0\u4CB1\u4CB2\u4CB3\u4CB4"+ + "\u4CB5\u4CB6\u4CB7\u4CB8\u4CB9\u4CBA\u4CBB\u4CBC"+ + "\u4CBD\u4CBE\u4CBF\u4CC0\u4CC1\u4CC2\u4CC3\u4CC4"+ + "\u4CC5\u4CC6\u4CC7\u4CC8\u4CC9\u4CCA\u4CCB\u4CCC"+ + "\u4CCD\u4CCE\u4CCF\u4CD0\u4CD1\u4CD2\u4CD3\u4CD4"+ + "\u4CD5\u4CD6\u4CD7\u4CD8\u4CD9\u4CDA\u4CDB\u4CDC"+ + "\u4CDD\u4CDE\u4CDF\u4CE0\u4CE1\u4CE2\u4CE3\u4CE4"+ + "\u4CE5\u4CE6\u4CE7\u4CE8\u4CE9\u4CEA\u4CEB\u4CEC"+ + "\u4CED\u4CEE\u4CEF\u4CF0\u4CF1\u4CF2\u4CF3\u4CF4"+ + "\u4CF5\u4CF6\u4CF7\u4CF8\u4CF9\u4CFA\u4CFB\u4CFC"+ + "\u4CFD\u4CFE\u4CFF\u4D00\u4D01\u4D02\u4D03\u4D04"+ + "\u4D05\u4D06\u4D07\u4D08\u4D09\u4D0A\u4D0B\u4D0C"+ + "\u4D0D\u4D0E\u4D0F\u4D10\u4D11\u4D12\u4D1A\u4D1B"+ + "\u4D1C\u4D1D\u4D1E\u4D1F\u4D20\u4D21\u4D22\u4D23"+ + "\u4D24\u4D25\u4D26\u4D27\u4D28\u4D29\u4D2A\u4D2B"+ + "\u4D2C\u4D2D\u4D2E\u4D2F\u4D30\u4D31\u4D32\u4D33"+ + "\u4D34\u4D35\u4D36\u4D37\u4D38\u4D39\u4D3A\u4D3B"+ + "\u4D3C\u4D3D\u4D3E\u4D3F\u4D40\u4D41\u4D42\u4D43"+ + "\u4D44\u4D45\u4D46\u4D47\u4D48\u4D49\u4D4A\u4D4B"+ + "\u4D4C\u4D4D\u4D4E\u4D4F\u4D50\u4D51\u4D52\u4D53"+ + "\u4D54\u4D55\u4D56\u4D57\u4D58\u4D59\u4D5A\u4D5B"+ + "\u4D5C\u4D5D\u4D5E\u4D5F\u4D60\u4D61\u4D62\u4D63"+ + "\u4D64\u4D65\u4D66\u4D67\u4D68\u4D69\u4D6A\u4D6B"+ + "\u4D6C\u4D6D\u4D6E\u4D6F\u4D70\u4D71\u4D72\u4D73"+ + "\u4D74\u4D75\u4D76\u4D77\u4D78\u4D79\u4D7A\u4D7B"+ + "\u4D7C\u4D7D\u4D7E\u4D7F\u4D80\u4D81\u4D82\u4D83"+ + "\u4D84\u4D85\u4D86\u4D87\u4D88\u4D89\u4D8A\u4D8B"+ + "\u4D8C\u4D8D\u4D8E\u4D8F\u4D90\u4D91\u4D92\u4D93"+ + "\u4D94\u4D95\u4D96\u4D97\u4D98\u4D99\u4D9A\u4D9B"+ + "\u4D9C\u4D9D\u4D9E\u4D9F\u4DA0\u4DA1\u4DA2\u4DA3"+ + "\u4DA4\u4DA5\u4DA6\u4DA7\u4DA8\u4DA9\u4DAA\u4DAB"+ + "\u4DAC\u4DAD\u4DAF\u4DB0\u4DB1\u4DB2\u4DB3\u4DB4"+ + "\u4DB5\u4DB6\u4DB7\u4DB8\u4DB9\u4DBA\u4DBB\u4DBC"+ + "\u4DBD\u4DBE\u4DBF\u4DC0\u4DC1\u4DC2\u4DC3\u4DC4"+ + "\u4DC5\u4DC6\u4DC7\u4DC8\u4DC9\u4DCA\u4DCB\u4DCC"+ + "\u4DCD\u4DCE\u4DCF\u4DD0\u4DD1\u4DD2\u4DD3\u4DD4"+ + "\u4DD5\u4DD6\u4DD7\u4DD8\u4DD9\u4DDA\u4DDB\u4DDC"+ + "\u4DDD\u4DDE\u4DDF\u4DE0\u4DE1\u4DE2\u4DE3\u4DE4"+ + "\u4DE5\u4DE6\u4DE7\u4DE8\u4DE9\u4DEA\u4DEB\u4DEC"+ + "\u4DED\u4DEE\u4DEF\u4DF0\u4DF1\u4DF2\u4DF3\u4DF4"+ + "\u4DF5\u4DF6\u4DF7\u4DF8\u4DF9\u4DFA\u4DFB\u4DFC"+ + "\u4DFD\u4DFE\u4DFF\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + (IS_2000 ? "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" : + "\uFFFD\uE81E\uE826\uE82B\uE82C\uE832\uE843\uE854"+ + "\uE864\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD")+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uE76C\uE7C8\uE7E7"+ + "\uE7E8\uE7E9\uE7EA\uE7EB\uE7EC\uE7ED\uE7EE\uE7EF"+ + "\uE7F0\uE7F1\uE7F2\uE7F3\uE815\uE819\uE81A\uE81B"+ + "\uE81C\uE81D\uE81F\uE820\uE821\uE822\uE823\uE824"+ + "\uE825\uE827\uE828\uE829\uE82A\uE82D\uE82E\uE82F"+ + "\uE830\uE833\uE834\uE835\uE836\uE837\uE838\uE839"+ + "\uE83A\uE83C\uE83D\uE83E\uE83F\uE840\uE841\uE842"+ + "\uE844\uE845\uE846\uE847\uE848\uE849\uE84A\uE84B"+ + "\uE84C\uE84D\uE84E\uE84F\uE850\uE851\uE852\uE853"+ + "\uE856\uE857\uE858\uE859\uE85A\uE85B\uE85C\uE85D"+ + "\uE85E\uE85F\uE860\uE861\uE862\uE863\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uF900\uF901\uF902\uF903\uF904\uF905\uF906"+ + "\uF907\uF908\uF909\uF90A\uF90B\uF90C\uF90D\uF90E"+ + "\uF90F\uF910\uF911\uF912\uF913\uF914\uF915\uF916"+ + "\uF917\uF918\uF919\uF91A\uF91B\uF91C\uF91D\uF91E"+ + "\uF91F\uF920\uF921\uF922\uF923\uF924\uF925\uF926"+ + "\uF927\uF928\uF929\uF92A\uF92B\uF92D\uF92E\uF92F"+ + "\uF930\uF931\uF932\uF933\uF934\uF935\uF936\uF937"+ + "\uF938\uF939\uF93A\uF93B\uF93C\uF93D\uF93E\uF93F"+ + "\uF940\uF941\uF942\uF943\uF944\uF945\uF946\uF947"+ + "\uF948\uF949\uF94A\uF94B\uF94C\uF94D\uF94E\uF94F"+ + "\uF950\uF951\uF952\uF953\uF954\uF955\uF956\uF957"+ + "\uF958\uF959\uF95A\uF95B\uF95C\uF95D\uF95E\uF95F"+ + "\uF960\uF961\uF962\uF963\uF964\uF965\uF966\uF967"+ + "\uF968\uF969\uF96A\uF96B\uF96C\uF96D\uF96E\uF96F"+ + "\uF970\uF971\uF972\uF973\uF974\uF975\uF976\uF977"+ + "\uF978\uF97A\uF97B\uF97C\uF97D\uF97E\uF97F\uF980"+ + "\uF981\uF982\uF983\uF984\uF985\uF986\uF987\uF988"+ + "\uF989\uF98A\uF98B\uF98C\uF98D\uF98E\uF98F\uF990"+ + "\uF991\uF992\uF993\uF994\uF996\uF997\uF998\uF999"+ + "\uF99A\uF99B\uF99C\uF99D\uF99E\uF99F\uF9A0\uF9A1"+ + "\uF9A2\uF9A3\uF9A4\uF9A5\uF9A6\uF9A7\uF9A8\uF9A9"+ + "\uF9AA\uF9AB\uF9AC\uF9AD\uF9AE\uF9AF\uF9B0\uF9B1"+ + "\uF9B2\uF9B3\uF9B4\uF9B5\uF9B6\uF9B7\uF9B8\uF9B9"+ + "\uF9BA\uF9BB\uF9BC\uF9BD\uF9BE\uF9BF\uF9C0\uF9C1"+ + "\uF9C2\uF9C3\uF9C4\uF9C5\uF9C6\uF9C7\uF9C8\uF9C9"+ + "\uF9CA\uF9CB\uF9CC\uF9CD\uF9CE\uF9CF\uF9D0\uF9D1"+ + "\uF9D2\uF9D3\uF9D4\uF9D5\uF9D6\uF9D7\uF9D8\uF9D9"+ + "\uF9DA\uF9DB\uF9DC\uF9DD\uF9DE\uF9DF\uF9E0\uF9E1"+ + "\uF9E2\uF9E3\uF9E4\uF9E5\uF9E6\uF9E8\uF9E9\uF9EA"+ + "\uF9EB\uF9EC\uF9ED\uF9EE\uF9EF\uF9F0\uF9F2\uF9F3"+ + "\uF9F4\uF9F5\uF9F6\uF9F7\uF9F8\uF9F9\uF9FA\uF9FB"+ + "\uF9FC\uF9FD\uF9FE\uF9FF\uFA00\uFA01\uFA02\uFA03"+ + "\uFA04\uFA05\uFA06\uFA07\uFA08\uFA09\uFA0A\uFA0B"+ + "\uFA10\uFA12\uFA15\uFA16\uFA17\uFA19\uFA1A\uFA1B"+ + "\uFA1C\uFA1D\uFA1E\uFA22\uFA25\uFA26\uFA2A\uFA2B"+ + "\uFA2C\uFA2D\uFA2E\uFA2F\uFA30\uFA31\uFA32\uFA33"+ + "\uFA34\uFA35\uFA36\uFA37\uFA38\uFA39\uFA3A\uFA3B"+ + "\uFA3C\uFA3D\uFA3E\uFA3F\uFA40\uFA41\uFA42\uFA43"+ + "\uFA44\uFA45\uFA46\uFA47\uFA48\uFA49\uFA4A\uFA4B"+ + "\uFA4C\uFA4D\uFA4E\uFA4F\uFA50\uFA51\uFA52\uFA53"+ + "\uFA54\uFA55\uFA56\uFA57\uFA58\uFA59\uFA5A\uFA5B"+ + "\uFA5C\uFA5D\uFA5E\uFA5F\uFA60\uFA61\uFA62\uFA63"+ + "\uFA64\uFA65\uFA66\uFA67\uFA68\uFA69\uFA6A\uFA6B"+ + "\uFA6C\uFA6D\uFA6E\uFA6F\uFA70\uFA71\uFA72\uFA73"+ + "\uFA74\uFA75\uFA76\uFA77\uFA78\uFA79\uFA7A\uFA7B"+ + "\uFA7C\uFA7D\uFA7E\uFA7F\uFA80\uFA81\uFA82\uFA83"+ + "\uFA84\uFA85\uFA86\uFA87\uFA88\uFA89\uFA8A\uFA8B"+ + "\uFA8C\uFA8D\uFA8E\uFA8F\uFA90\uFA91\uFA92\uFA93"+ + "\uFA94\uFA95\uFA96\uFA97\uFA98\uFA99\uFA9A\uFA9B"+ + "\uFA9C\uFA9D\uFA9E\uFA9F\uFAA0\uFAA1\uFAA2\uFAA3"+ + "\uFAA4\uFAA5\uFAA6\uFAA7\uFAA8\uFAA9\uFAAA\uFAAB"+ + "\uFAAC\uFAAD\uFAAE\uFAAF\uFAB0\uFAB1\uFAB2\uFAB3"+ + "\uFAB4\uFAB5\uFAB6\uFAB7\uFAB8\uFAB9\uFABA\uFABB"+ + "\uFABC\uFABD\uFABE\uFABF\uFAC0\uFAC1\uFAC2\uFAC3"+ + "\uFAC4\uFAC5\uFAC6\uFAC7\uFAC8\uFAC9\uFACA\uFACB"+ + "\uFACC\uFACD\uFACE\uFACF\uFAD0\uFAD1\uFAD2\uFAD3"+ + "\uFAD4\uFAD5\uFAD6\uFAD7\uFAD8\uFAD9\uFADA\uFADB"+ + "\uFADC\uFADD\uFADE\uFADF\uFAE0\uFAE1\uFAE2\uFAE3"+ + "\uFAE4\uFAE5\uFAE6\uFAE7\uFAE8\uFAE9\uFAEA\uFAEB"+ + "\uFAEC\uFAED\uFAEE\uFAEF\uFAF0\uFAF1\uFAF2\uFAF3"+ + "\uFAF4\uFAF5\uFAF6\uFAF7\uFAF8\uFAF9\uFAFA\uFAFB"+ + "\uFAFC\uFAFD\uFAFE\uFAFF\uFB00\uFB01\uFB02\uFB03"+ + "\uFB04\uFB05\uFB06\uFB07\uFB08\uFB09\uFB0A\uFB0B"+ + "\uFB0C\uFB0D\uFB0E\uFB0F\uFB10\uFB11\uFB12\uFB13"+ + "\uFB14\uFB15\uFB16\uFB17\uFB18\uFB19\uFB1A\uFB1B"+ + "\uFB1C\uFB1D\uFB1E\uFB1F\uFB20\uFB21\uFB22\uFB23"+ + "\uFB24\uFB25\uFB26\uFB27\uFB28\uFB29\uFB2A\uFB2B"+ + "\uFB2C\uFB2D\uFB2E\uFB2F\uFB30\uFB31\uFB32\uFB33"+ + "\uFB34\uFB35\uFB36\uFB37\uFB38\uFB39\uFB3A\uFB3B"+ + "\uFB3C\uFB3D\uFB3E\uFB3F\uFB40\uFB41\uFB42\uFB43"+ + "\uFB44\uFB45\uFB46\uFB47\uFB48\uFB49\uFB4A\uFB4B"+ + "\uFB4C\uFB4D\uFB4E\uFB4F\uFB50\uFB51\uFB52\uFB53"+ + "\uFB54\uFB55\uFB56\uFB57\uFB58\uFB59\uFB5A\uFB5B"+ + "\uFB5C\uFB5D\uFB5E\uFB5F\uFB60\uFB61\uFB62\uFB63"+ + "\uFB64\uFB65\uFB66\uFB67\uFB68\uFB69\uFB6A\uFB6B"; + + private static final String innerDecoderIndex5= + "\uFB6C\uFB6D\uFB6E\uFB6F\uFB70\uFB71\uFB72\uFB73"+ + "\uFB74\uFB75\uFB76\uFB77\uFB78\uFB79\uFB7A\uFB7B"+ + "\uFB7C\uFB7D\uFB7E\uFB7F\uFB80\uFB81\uFB82\uFB83"+ + "\uFB84\uFB85\uFB86\uFB87\uFB88\uFB89\uFB8A\uFB8B"+ + "\uFB8C\uFB8D\uFB8E\uFB8F\uFB90\uFB91\uFB92\uFB93"+ + "\uFB94\uFB95\uFB96\uFB97\uFB98\uFB99\uFB9A\uFB9B"+ + "\uFB9C\uFB9D\uFB9E\uFB9F\uFBA0\uFBA1\uFBA2\uFBA3"+ + "\uFBA4\uFBA5\uFBA6\uFBA7\uFBA8\uFBA9\uFBAA\uFBAB"+ + "\uFBAC\uFBAD\uFBAE\uFBAF\uFBB0\uFBB1\uFBB2\uFBB3"+ + "\uFBB4\uFBB5\uFBB6\uFBB7\uFBB8\uFBB9\uFBBA\uFBBB"+ + "\uFBBC\uFBBD\uFBBE\uFBBF\uFBC0\uFBC1\uFBC2\uFBC3"+ + "\uFBC4\uFBC5\uFBC6\uFBC7\uFBC8\uFBC9\uFBCA\uFBCB"+ + "\uFBCC\uFBCD\uFBCE\uFBCF\uFBD0\uFBD1\uFBD2\uFBD3"+ + "\uFBD4\uFBD5\uFBD6\uFBD7\uFBD8\uFBD9\uFBDA\uFBDB"+ + "\uFBDC\uFBDD\uFBDE\uFBDF\uFBE0\uFBE1\uFBE2\uFBE3"+ + "\uFBE4\uFBE5\uFBE6\uFBE7\uFBE8\uFBE9\uFBEA\uFBEB"+ + "\uFBEC\uFBED\uFBEE\uFBEF\uFBF0\uFBF1\uFBF2\uFBF3"+ + "\uFBF4\uFBF5\uFBF6\uFBF7\uFBF8\uFBF9\uFBFA\uFBFB"+ + "\uFBFC\uFBFD\uFBFE\uFBFF\uFC00\uFC01\uFC02\uFC03"+ + "\uFC04\uFC05\uFC06\uFC07\uFC08\uFC09\uFC0A\uFC0B"+ + "\uFC0C\uFC0D\uFC0E\uFC0F\uFC10\uFC11\uFC12\uFC13"+ + "\uFC14\uFC15\uFC16\uFC17\uFC18\uFC19\uFC1A\uFC1B"+ + "\uFC1C\uFC1D\uFC1E\uFC1F\uFC20\uFC21\uFC22\uFC23"+ + "\uFC24\uFC25\uFC26\uFC27\uFC28\uFC29\uFC2A\uFC2B"+ + "\uFC2C\uFC2D\uFC2E\uFC2F\uFC30\uFC31\uFC32\uFC33"+ + "\uFC34\uFC35\uFC36\uFC37\uFC38\uFC39\uFC3A\uFC3B"+ + "\uFC3C\uFC3D\uFC3E\uFC3F\uFC40\uFC41\uFC42\uFC43"+ + "\uFC44\uFC45\uFC46\uFC47\uFC48\uFC49\uFC4A\uFC4B"+ + "\uFC4C\uFC4D\uFC4E\uFC4F\uFC50\uFC51\uFC52\uFC53"+ + "\uFC54\uFC55\uFC56\uFC57\uFC58\uFC59\uFC5A\uFC5B"+ + "\uFC5C\uFC5D\uFC5E\uFC5F\uFC60\uFC61\uFC62\uFC63"+ + "\uFC64\uFC65\uFC66\uFC67\uFC68\uFC69\uFC6A\uFC6B"+ + "\uFC6C\uFC6D\uFC6E\uFC6F\uFC70\uFC71\uFC72\uFC73"+ + "\uFC74\uFC75\uFC76\uFC77\uFC78\uFC79\uFC7A\uFC7B"+ + "\uFC7C\uFC7D\uFC7E\uFC7F\uFC80\uFC81\uFC82\uFC83"+ + "\uFC84\uFC85\uFC86\uFC87\uFC88\uFC89\uFC8A\uFC8B"+ + "\uFC8C\uFC8D\uFC8E\uFC8F\uFC90\uFC91\uFC92\uFC93"+ + "\uFC94\uFC95\uFC96\uFC97\uFC98\uFC99\uFC9A\uFC9B"+ + "\uFC9C\uFC9D\uFC9E\uFC9F\uFCA0\uFCA1\uFCA2\uFCA3"+ + "\uFCA4\uFCA5\uFCA6\uFCA7\uFCA8\uFCA9\uFCAA\uFCAB"+ + "\uFCAC\uFCAD\uFCAE\uFCAF\uFCB0\uFCB1\uFCB2\uFCB3"+ + "\uFCB4\uFCB5\uFCB6\uFCB7\uFCB8\uFCB9\uFCBA\uFCBB"+ + "\uFCBC\uFCBD\uFCBE\uFCBF\uFCC0\uFCC1\uFCC2\uFCC3"+ + "\uFCC4\uFCC5\uFCC6\uFCC7\uFCC8\uFCC9\uFCCA\uFCCB"+ + "\uFCCC\uFCCD\uFCCE\uFCCF\uFCD0\uFCD1\uFCD2\uFCD3"+ + "\uFCD4\uFCD5\uFCD6\uFCD7\uFCD8\uFCD9\uFCDA\uFCDB"+ + "\uFCDC\uFCDD\uFCDE\uFCDF\uFCE0\uFCE1\uFCE2\uFCE3"+ + "\uFCE4\uFCE5\uFCE6\uFCE7\uFCE8\uFCE9\uFCEA\uFCEB"+ + "\uFCEC\uFCED\uFCEE\uFCEF\uFCF0\uFCF1\uFCF2\uFCF3"+ + "\uFCF4\uFCF5\uFCF6\uFCF7\uFCF8\uFCF9\uFCFA\uFCFB"+ + "\uFCFC\uFCFD\uFCFE\uFCFF\uFD00\uFD01\uFD02\uFD03"+ + "\uFD04\uFD05\uFD06\uFD07\uFD08\uFD09\uFD0A\uFD0B"+ + "\uFD0C\uFD0D\uFD0E\uFD0F\uFD10\uFD11\uFD12\uFD13"+ + "\uFD14\uFD15\uFD16\uFD17\uFD18\uFD19\uFD1A\uFD1B"+ + "\uFD1C\uFD1D\uFD1E\uFD1F\uFD20\uFD21\uFD22\uFD23"+ + "\uFD24\uFD25\uFD26\uFD27\uFD28\uFD29\uFD2A\uFD2B"+ + "\uFD2C\uFD2D\uFD2E\uFD2F\uFD30\uFD31\uFD32\uFD33"+ + "\uFD34\uFD35\uFD36\uFD37\uFD38\uFD39\uFD3A\uFD3B"+ + "\uFD3C\uFD3D\uFD3E\uFD3F\uFD40\uFD41\uFD42\uFD43"+ + "\uFD44\uFD45\uFD46\uFD47\uFD48\uFD49\uFD4A\uFD4B"+ + "\uFD4C\uFD4D\uFD4E\uFD4F\uFD50\uFD51\uFD52\uFD53"+ + "\uFD54\uFD55\uFD56\uFD57\uFD58\uFD59\uFD5A\uFD5B"+ + "\uFD5C\uFD5D\uFD5E\uFD5F\uFD60\uFD61\uFD62\uFD63"+ + "\uFD64\uFD65\uFD66\uFD67\uFD68\uFD69\uFD6A\uFD6B"+ + "\uFD6C\uFD6D\uFD6E\uFD6F\uFD70\uFD71\uFD72\uFD73"+ + "\uFD74\uFD75\uFD76\uFD77\uFD78\uFD79\uFD7A\uFD7B"+ + "\uFD7C\uFD7D\uFD7E\uFD7F\uFD80\uFD81\uFD82\uFD83"+ + "\uFD84\uFD85\uFD86\uFD87\uFD88\uFD89\uFD8A\uFD8B"+ + "\uFD8C\uFD8D\uFD8E\uFD8F\uFD90\uFD91\uFD92\uFD93"+ + "\uFD94\uFD95\uFD96\uFD97\uFD98\uFD99\uFD9A\uFD9B"+ + "\uFD9C\uFD9D\uFD9E\uFD9F\uFDA0\uFDA1\uFDA2\uFDA3"+ + "\uFDA4\uFDA5\uFDA6\uFDA7\uFDA8\uFDA9\uFDAA\uFDAB"+ + "\uFDAC\uFDAD\uFDAE\uFDAF\uFDB0\uFDB1\uFDB2\uFDB3"+ + "\uFDB4\uFDB5\uFDB6\uFDB7\uFDB8\uFDB9\uFDBA\uFDBB"+ + "\uFDBC\uFDBD\uFDBE\uFDBF\uFDC0\uFDC1\uFDC2\uFDC3"+ + "\uFDC4\uFDC5\uFDC6\uFDC7\uFDC8\uFDC9\uFDCA\uFDCB"+ + "\uFDCC\uFDCD\uFDCE\uFDCF\uFDD0\uFDD1\uFDD2\uFDD3"+ + "\uFDD4\uFDD5\uFDD6\uFDD7\uFDD8\uFDD9\uFDDA\uFDDB"+ + "\uFDDC\uFDDD\uFDDE\uFDDF\uFDE0\uFDE1\uFDE2\uFDE3"+ + "\uFDE4\uFDE5\uFDE6\uFDE7\uFDE8\uFDE9\uFDEA\uFDEB"+ + "\uFDEC\uFDED\uFDEE\uFDEF\uFDF0\uFDF1\uFDF2\uFDF3"+ + "\uFDF4\uFDF5\uFDF6\uFDF7\uFDF8\uFDF9\uFDFA\uFDFB"+ + "\uFDFC\uFDFD\uFDFE\uFDFF\uFE00\uFE01\uFE02\uFE03"+ + "\uFE04\uFE05\uFE06\uFE07\uFE08\uFE09\uFE0A\uFE0B"+ + (IS_2000 ? "\uFE0C\uFE0D\uFE0E\uFE0F\uFE10\uFE11\uFE12\uFE13"+ + "\uFE14\uFE15\uFE16\uFE17\uFE18\uFE19\uFE1A\uFE1B" : + "\uFE0C\uFE0D\uFE0E\uFE0F\uE78D\uE78F\uE78E\uE790"+ + "\uE791\uE792\uE793\uE794\uE795\uE796\uFE1A\uFE1B")+ + "\uFE1C\uFE1D\uFE1E\uFE1F\uFE20\uFE21\uFE22\uFE23"+ + "\uFE24\uFE25\uFE26\uFE27\uFE28\uFE29\uFE2A\uFE2B"+ + "\uFE2C\uFE2D\uFE2E\uFE2F\uFE32\uFE45\uFE46\uFE47"+ + "\uFE48\uFE53\uFE58\uFE67\uFE6C\uFE6D\uFE6E\uFE6F"+ + "\uFE70\uFE71\uFE72\uFE73\uFE74\uFE75\uFE76\uFE77"+ + "\uFE78\uFE79\uFE7A\uFE7B\uFE7C\uFE7D\uFE7E\uFE7F"+ + "\uFE80\uFE81\uFE82\uFE83\uFE84\uFE85\uFE86\uFE87"+ + "\uFE88\uFE89\uFE8A\uFE8B\uFE8C\uFE8D\uFE8E\uFE8F"+ + "\uFE90\uFE91\uFE92\uFE93\uFE94\uFE95\uFE96\uFE97"+ + "\uFE98\uFE99\uFE9A\uFE9B\uFE9C\uFE9D\uFE9E\uFE9F"+ + "\uFEA0\uFEA1\uFEA2\uFEA3\uFEA4\uFEA5\uFEA6\uFEA7"+ + "\uFEA8\uFEA9\uFEAA\uFEAB\uFEAC\uFEAD\uFEAE\uFEAF"+ + "\uFEB0\uFEB1\uFEB2\uFEB3\uFEB4\uFEB5\uFEB6\uFEB7"+ + "\uFEB8\uFEB9\uFEBA\uFEBB\uFEBC\uFEBD\uFEBE\uFEBF"+ + "\uFEC0\uFEC1\uFEC2\uFEC3\uFEC4\uFEC5\uFEC6\uFEC7"+ + "\uFEC8\uFEC9\uFECA\uFECB\uFECC\uFECD\uFECE\uFECF"+ + "\uFED0\uFED1\uFED2\uFED3\uFED4\uFED5\uFED6\uFED7"+ + "\uFED8\uFED9\uFEDA\uFEDB\uFEDC\uFEDD\uFEDE\uFEDF"+ + "\uFEE0\uFEE1\uFEE2\uFEE3\uFEE4\uFEE5\uFEE6\uFEE7"+ + "\uFEE8\uFEE9\uFEEA\uFEEB\uFEEC\uFEED\uFEEE\uFEEF"+ + "\uFEF0\uFEF1\uFEF2\uFEF3\uFEF4\uFEF5\uFEF6\uFEF7"+ + "\uFEF8\uFEF9\uFEFA\uFEFB\uFEFC\uFEFD\uFEFE\uFEFF"+ + "\uFF00\uFF5F\uFF60\uFF61\uFF62\uFF63\uFF64\uFF65"+ + "\uFF66\uFF67\uFF68\uFF69\uFF6A\uFF6B\uFF6C\uFF6D"+ + "\uFF6E\uFF6F\uFF70\uFF71\uFF72\uFF73\uFF74\uFF75"+ + "\uFF76\uFF77\uFF78\uFF79\uFF7A\uFF7B\uFF7C\uFF7D"+ + "\uFF7E\uFF7F\uFF80\uFF81\uFF82\uFF83\uFF84\uFF85"+ + "\uFF86\uFF87\uFF88\uFF89\uFF8A\uFF8B\uFF8C\uFF8D"+ + "\uFF8E\uFF8F\uFF90\uFF91\uFF92\uFF93\uFF94\uFF95"+ + "\uFF96\uFF97\uFF98\uFF99\uFF9A\uFF9B\uFF9C\uFF9D"+ + "\uFF9E\uFF9F\uFFA0\uFFA1\uFFA2\uFFA3\uFFA4\uFFA5"+ + "\uFFA6\uFFA7\uFFA8\uFFA9\uFFAA\uFFAB\uFFAC\uFFAD"+ + "\uFFAE\uFFAF\uFFB0\uFFB1\uFFB2\uFFB3\uFFB4\uFFB5"+ + "\uFFB6\uFFB7\uFFB8\uFFB9\uFFBA\uFFBB\uFFBC\uFFBD"+ + "\uFFBE\uFFBF\uFFC0\uFFC1\uFFC2\uFFC3\uFFC4\uFFC5"+ + "\uFFC6\uFFC7\uFFC8\uFFC9\uFFCA\uFFCB\uFFCC\uFFCD"+ + "\uFFCE\uFFCF\uFFD0\uFFD1\uFFD2\uFFD3\uFFD4\uFFD5"+ + "\uFFD6\uFFD7\uFFD8\uFFD9\uFFDA\uFFDB\uFFDC\uFFDD"+ + "\uFFDE\uFFDF\uFFE6\uFFE7\uFFE8\uFFE9\uFFEA\uFFEB"+ + "\uFFEC\uFFED\uFFEE\uFFEF\uFFF0\uFFF1\uFFF2\uFFF3"+ + "\uFFF4\uFFF5\uFFF6\uFFF7\uFFF8\uFFF9\uFFFA\uFFFB"+ + "\uFFFC\uFFFD\uFFFE\uFFFF\uFFFD\uFFFD\uFFFD\uFFFD"; + + private static final short decoderIndex1[] = { + 0, 1, 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, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 77, 78, 79, 80, 81, 82, 83, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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 String decoderIndex2[] = { + innerDecoderIndex0, + innerDecoderIndex1, + innerDecoderIndex2, + innerDecoderIndex3, + innerDecoderIndex4, + innerDecoderIndex5 + }; + +/* + * + */ + private static final String innerIndex0= + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u4E02"+ + "\u4E04\u4E05\u4E06\u4E0F\u4E12\u4E17\u4E1F\u4E20"+ + "\u4E21\u4E23\u4E26\u4E29\u4E2E\u4E2F\u4E31\u4E33"+ + "\u4E35\u4E37\u4E3C\u4E40\u4E41\u4E42\u4E44\u4E46"+ + "\u4E4A\u4E51\u4E55\u4E57\u4E5A\u4E5B\u4E62\u4E63"+ + "\u4E64\u4E65\u4E67\u4E68\u4E6A\u4E6B\u4E6C\u4E6D"+ + "\u4E6E\u4E6F\u4E72\u4E74\u4E75\u4E76\u4E77\u4E78"+ + "\u4E79\u4E7A\u4E7B\u4E7C\u4E7D\u4E7F\u4E80\u4E81"+ + "\u4E82\u4E83\u4E84\u4E85\u4E87\u4E8A\uFFFD\u4E90"+ + "\u4E96\u4E97\u4E99\u4E9C\u4E9D\u4E9E\u4EA3\u4EAA"+ + "\u4EAF\u4EB0\u4EB1\u4EB4\u4EB6\u4EB7\u4EB8\u4EB9"+ + "\u4EBC\u4EBD\u4EBE\u4EC8\u4ECC\u4ECF\u4ED0\u4ED2"+ + "\u4EDA\u4EDB\u4EDC\u4EE0\u4EE2\u4EE6\u4EE7\u4EE9"+ + "\u4EED\u4EEE\u4EEF\u4EF1\u4EF4\u4EF8\u4EF9\u4EFA"+ + "\u4EFC\u4EFE\u4F00\u4F02\u4F03\u4F04\u4F05\u4F06"+ + "\u4F07\u4F08\u4F0B\u4F0C\u4F12\u4F13\u4F14\u4F15"+ + "\u4F16\u4F1C\u4F1D\u4F21\u4F23\u4F28\u4F29\u4F2C"+ + "\u4F2D\u4F2E\u4F31\u4F33\u4F35\u4F37\u4F39\u4F3B"+ + "\u4F3E\u4F3F\u4F40\u4F41\u4F42\u4F44\u4F45\u4F47"+ + "\u4F48\u4F49\u4F4A\u4F4B\u4F4C\u4F52\u4F54\u4F56"+ + "\u4F61\u4F62\u4F66\u4F68\u4F6A\u4F6B\u4F6D\u4F6E"+ + "\u4F71\u4F72\u4F75\u4F77\u4F78\u4F79\u4F7A\u4F7D"+ + "\u4F80\u4F81\u4F82\u4F85\u4F86\u4F87\u4F8A\u4F8C"+ + "\u4F8E\u4F90\u4F92\u4F93\u4F95\u4F96\u4F98\u4F99"+ + "\u4F9A\u4F9C\u4F9E\u4F9F\u4FA1\u4FA2\u4FA4\u4FAB"+ + "\u4FAD\u4FB0\u4FB1\u4FB2\u4FB3\u4FB4\u4FB6\u4FB7"+ + "\u4FB8\u4FB9\u4FBA\u4FBB\u4FBC\u4FBD\u4FBE\u4FC0"+ + "\u4FC1\u4FC2\u4FC6\u4FC7\u4FC8\u4FC9\u4FCB\u4FCC"+ + "\u4FCD\u4FD2\u4FD3\u4FD4\u4FD5\u4FD6\u4FD9\u4FDB"+ + "\u4FE0\u4FE2\u4FE4\u4FE5\u4FE7\u4FEB\u4FEC\u4FF0"+ + "\u4FF2\u4FF4\u4FF5\u4FF6\u4FF7\u4FF9\u4FFB\u4FFC"+ + "\u4FFD\u4FFF\u5000\u5001\u5002\u5003\u5004\u5005"+ + "\u5006\u5007\u5008\u5009\u500A\uFFFD\u500B\u500E"+ + "\u5010\u5011\u5013\u5015\u5016\u5017\u501B\u501D"+ + "\u501E\u5020\u5022\u5023\u5024\u5027\u502B\u502F"+ + "\u5030\u5031\u5032\u5033\u5034\u5035\u5036\u5037"+ + "\u5038\u5039\u503B\u503D\u503F\u5040\u5041\u5042"+ + "\u5044\u5045\u5046\u5049\u504A\u504B\u504D\u5050"+ + "\u5051\u5052\u5053\u5054\u5056\u5057\u5058\u5059"+ + "\u505B\u505D\u505E\u505F\u5060\u5061\u5062\u5063"+ + "\u5064\u5066\u5067\u5068\u5069\u506A\u506B\u506D"+ + "\u506E\u506F\u5070\u5071\u5072\u5073\u5074\u5075"+ + "\u5078\u5079\u507A\u507C\u507D\u5081\u5082\u5083"+ + "\u5084\u5086\u5087\u5089\u508A\u508B\u508C\u508E"+ + "\u508F\u5090\u5091\u5092\u5093\u5094\u5095\u5096"+ + "\u5097\u5098\u5099\u509A\u509B\u509C\u509D\u509E"+ + "\u509F\u50A0\u50A1\u50A2\u50A4\u50A6\u50AA\u50AB"+ + "\u50AD\u50AE\u50AF\u50B0\u50B1\u50B3\u50B4\u50B5"+ + "\u50B6\u50B7\u50B8\u50B9\u50BC\u50BD\u50BE\u50BF"+ + "\u50C0\u50C1\u50C2\u50C3\u50C4\u50C5\u50C6\u50C7"+ + "\u50C8\u50C9\u50CA\u50CB\u50CC\u50CD\u50CE\u50D0"+ + "\u50D1\u50D2\u50D3\u50D4\u50D5\u50D7\u50D8\u50D9"+ + "\u50DB\u50DC\u50DD\u50DE\u50DF\u50E0\u50E1\u50E2"+ + "\u50E3\u50E4\u50E5\u50E8\u50E9\u50EA\u50EB\u50EF"+ + "\u50F0\u50F1\u50F2\u50F4\u50F6\u50F7\u50F8\u50F9"+ + "\u50FA\u50FC\u50FD\u50FE\u50FF\u5100\u5101\u5102"+ + "\u5103\u5104\u5105\u5108\uFFFD\u5109\u510A\u510C"+ + "\u510D\u510E\u510F\u5110\u5111\u5113\u5114\u5115"+ + "\u5116\u5117\u5118\u5119\u511A\u511B\u511C\u511D"+ + "\u511E\u511F\u5120\u5122\u5123\u5124\u5125\u5126"+ + "\u5127\u5128\u5129\u512A\u512B\u512C\u512D\u512E"+ + "\u512F\u5130\u5131\u5132\u5133\u5134\u5135\u5136"+ + "\u5137\u5138\u5139\u513A\u513B\u513C\u513D\u513E"+ + "\u5142\u5147\u514A\u514C\u514E\u514F\u5150\u5152"+ + "\u5153\u5157\u5158\u5159\u515B\u515D\u515E\u515F"+ + "\u5160\u5161\u5163\u5164\u5166\u5167\u5169\u516A"+ + "\u516F\u5172\u517A\u517E\u517F\u5183\u5184\u5186"+ + "\u5187\u518A\u518B\u518E\u518F\u5190\u5191\u5193"+ + "\u5194\u5198\u519A\u519D\u519E\u519F\u51A1\u51A3"+ + "\u51A6\u51A7\u51A8\u51A9\u51AA\u51AD\u51AE\u51B4"+ + "\u51B8\u51B9\u51BA\u51BE\u51BF\u51C1\u51C2\u51C3"+ + "\u51C5\u51C8\u51CA\u51CD\u51CE\u51D0\u51D2\u51D3"+ + "\u51D4\u51D5\u51D6\u51D7\u51D8\u51D9\u51DA\u51DC"+ + "\u51DE\u51DF\u51E2\u51E3\u51E5\u51E6\u51E7\u51E8"+ + "\u51E9\u51EA\u51EC\u51EE\u51F1\u51F2\u51F4\u51F7"+ + "\u51FE\u5204\u5205\u5209\u520B\u520C\u520F\u5210"+ + "\u5213\u5214\u5215\u521C\u521E\u521F\u5221\u5222"+ + "\u5223\u5225\u5226\u5227\u522A\u522C\u522F\u5231"+ + "\u5232\u5234\u5235\u523C\u523E\u5244\u5245\u5246"+ + "\u5247\u5248\u5249\u524B\u524E\u524F\u5252\u5253"+ + "\u5255\u5257\u5258\uFFFD\u5259\u525A\u525B\u525D"+ + "\u525F\u5260\u5262\u5263\u5264\u5266\u5268\u526B"+ + "\u526C\u526D\u526E\u5270\u5271\u5273\u5274\u5275"+ + "\u5276\u5277\u5278\u5279\u527A\u527B\u527C\u527E"+ + "\u5280\u5283\u5284\u5285\u5286\u5287\u5289\u528A"+ + "\u528B\u528C\u528D\u528E\u528F\u5291\u5292\u5294"+ + "\u5295\u5296\u5297\u5298\u5299\u529A\u529C\u52A4"+ + "\u52A5\u52A6\u52A7\u52AE\u52AF\u52B0\u52B4\u52B5"+ + "\u52B6\u52B7\u52B8\u52B9\u52BA\u52BB\u52BC\u52BD"+ + "\u52C0\u52C1\u52C2\u52C4\u52C5\u52C6\u52C8\u52CA"+ + "\u52CC\u52CD\u52CE\u52CF\u52D1\u52D3\u52D4\u52D5"+ + "\u52D7\u52D9\u52DA\u52DB\u52DC\u52DD\u52DE\u52E0"+ + "\u52E1\u52E2\u52E3\u52E5\u52E6\u52E7\u52E8\u52E9"+ + "\u52EA\u52EB\u52EC\u52ED\u52EE\u52EF\u52F1\u52F2"+ + "\u52F3\u52F4\u52F5\u52F6\u52F7\u52F8\u52FB\u52FC"+ + "\u52FD\u5301\u5302\u5303\u5304\u5307\u5309\u530A"+ + "\u530B\u530C\u530E\u5311\u5312\u5313\u5314\u5318"+ + "\u531B\u531C\u531E\u531F\u5322\u5324\u5325\u5327"+ + "\u5328\u5329\u532B\u532C\u532D\u532F\u5330\u5331"+ + "\u5332\u5333\u5334\u5335\u5336\u5337\u5338\u533C"+ + "\u533D\u5340\u5342\u5344\u5346\u534B\u534C\u534D"+ + "\u5350\u5354\u5358\u5359\u535B\u535D\u5365\u5368"+ + "\u536A\u536C\u536D\u5372\u5376\u5379\u537B\u537C"+ + "\u537D\u537E\u5380\u5381\u5383\u5387\u5388\u538A"+ + "\u538E\u538F\uFFFD\u5390\u5391\u5392\u5393\u5394"+ + "\u5396\u5397\u5399\u539B\u539C\u539E\u53A0\u53A1"+ + "\u53A4\u53A7\u53AA\u53AB\u53AC\u53AD\u53AF\u53B0"+ + "\u53B1\u53B2\u53B3\u53B4\u53B5\u53B7\u53B8\u53B9"+ + "\u53BA\u53BC\u53BD\u53BE\u53C0\u53C3\u53C4\u53C5"+ + "\u53C6\u53C7\u53CE\u53CF\u53D0\u53D2\u53D3\u53D5"+ + "\u53DA\u53DC\u53DD\u53DE\u53E1\u53E2\u53E7\u53F4"+ + "\u53FA\u53FE\u53FF\u5400\u5402\u5405\u5407\u540B"+ + "\u5414\u5418\u5419\u541A\u541C\u5422\u5424\u5425"+ + "\u542A\u5430\u5433\u5436\u5437\u543A\u543D\u543F"+ + "\u5441\u5442\u5444\u5445\u5447\u5449\u544C\u544D"+ + "\u544E\u544F\u5451\u545A\u545D\u545E\u545F\u5460"+ + "\u5461\u5463\u5465\u5467\u5469\u546A\u546B\u546C"+ + "\u546D\u546E\u546F\u5470\u5474\u5479\u547A\u547E"+ + "\u547F\u5481\u5483\u5485\u5487\u5488\u5489\u548A"+ + "\u548D\u5491\u5493\u5497\u5498\u549C\u549E\u549F"+ + "\u54A0\u54A1\u54A2\u54A5\u54AE\u54B0\u54B2\u54B5"+ + "\u54B6\u54B7\u54B9\u54BA\u54BC\u54BE\u54C3\u54C5"+ + "\u54CA\u54CB\u54D6\u54D8\u54DB\u54E0\u54E1\u54E2"+ + "\u54E3\u54E4\u54EB\u54EC\u54EF\u54F0\u54F1\u54F4"+ + "\u54F5\u54F6\u54F7\u54F8\u54F9\u54FB\u54FE\u5500"+ + "\u5502\u5503\u5504\u5505\u5508\u550A\u550B\u550C"+ + "\u550D\u550E\u5512\u5513\u5515\u5516\u5517\u5518"+ + "\u5519\u551A\u551C\u551D\u551E\u551F\u5521\u5525"+ + "\u5526\uFFFD\u5528\u5529\u552B\u552D\u5532\u5534"+ + "\u5535\u5536\u5538\u5539\u553A\u553B\u553D\u5540"+ + "\u5542\u5545\u5547\u5548\u554B\u554C\u554D\u554E"+ + "\u554F\u5551\u5552\u5553\u5554\u5557\u5558\u5559"+ + "\u555A\u555B\u555D\u555E\u555F\u5560\u5562\u5563"+ + "\u5568\u5569\u556B\u556F\u5570\u5571\u5572\u5573"+ + "\u5574\u5579\u557A\u557D\u557F\u5585\u5586\u558C"+ + "\u558D\u558E\u5590\u5592\u5593\u5595\u5596\u5597"+ + "\u559A\u559B\u559E\u55A0\u55A1\u55A2\u55A3\u55A4"+ + "\u55A5\u55A6\u55A8\u55A9\u55AA\u55AB\u55AC\u55AD"+ + "\u55AE\u55AF\u55B0\u55B2\u55B4\u55B6\u55B8\u55BA"+ + "\u55BC\u55BF\u55C0\u55C1\u55C2\u55C3\u55C6\u55C7"+ + "\u55C8\u55CA\u55CB\u55CE\u55CF\u55D0\u55D5\u55D7"+ + "\u55D8\u55D9\u55DA\u55DB\u55DE\u55E0\u55E2\u55E7"+ + "\u55E9\u55ED\u55EE\u55F0\u55F1\u55F4\u55F6\u55F8"+ + "\u55F9\u55FA\u55FB\u55FC\u55FF\u5602\u5603\u5604"+ + "\u5605\u5606\u5607\u560A\u560B\u560D\u5610\u5611"+ + "\u5612\u5613\u5614\u5615\u5616\u5617\u5619\u561A"+ + "\u561C\u561D\u5620\u5621\u5622\u5625\u5626\u5628"+ + "\u5629\u562A\u562B\u562E\u562F\u5630\u5633\u5635"+ + "\u5637\u5638\u563A\u563C\u563D\u563E\u5640\u5641"+ + "\u5642\u5643\u5644\u5645\u5646\u5647\u5648\u5649"+ + "\u564A\u564B\u564F\u5650\u5651\u5652\u5653\u5655"+ + "\u5656\u565A\u565B\u565D\u565E\u565F\u5660\u5661"+ + "\uFFFD\u5663\u5665\u5666\u5667\u566D\u566E\u566F"+ + "\u5670\u5672\u5673\u5674\u5675\u5677\u5678\u5679"+ + "\u567A\u567D\u567E\u567F\u5680\u5681\u5682\u5683"+ + "\u5684\u5687\u5688\u5689\u568A\u568B\u568C\u568D"+ + "\u5690\u5691\u5692\u5694\u5695\u5696\u5697\u5698"+ + "\u5699\u569A\u569B\u569C\u569D\u569E\u569F\u56A0"+ + "\u56A1\u56A2\u56A4\u56A5\u56A6\u56A7\u56A8\u56A9"+ + "\u56AA\u56AB\u56AC\u56AD\u56AE\u56B0\u56B1\u56B2"+ + "\u56B3\u56B4\u56B5\u56B6\u56B8\u56B9\u56BA\u56BB"+ + "\u56BD\u56BE\u56BF\u56C0\u56C1\u56C2\u56C3\u56C4"+ + "\u56C5\u56C6\u56C7\u56C8\u56C9\u56CB\u56CC\u56CD"+ + "\u56CE\u56CF\u56D0\u56D1\u56D2\u56D3\u56D5\u56D6"+ + "\u56D8\u56D9\u56DC\u56E3\u56E5\u56E6\u56E7\u56E8"+ + "\u56E9\u56EA\u56EC\u56EE\u56EF\u56F2\u56F3\u56F6"+ + "\u56F7\u56F8\u56FB\u56FC\u5700\u5701\u5702\u5705"+ + "\u5707\u570B\u570C\u570D\u570E\u570F\u5710\u5711"+ + "\u5712\u5713\u5714\u5715\u5716\u5717\u5718\u5719"+ + "\u571A\u571B\u571D\u571E\u5720\u5721\u5722\u5724"+ + "\u5725\u5726\u5727\u572B\u5731\u5732\u5734\u5735"+ + "\u5736\u5737\u5738\u573C\u573D\u573F\u5741\u5743"+ + "\u5744\u5745\u5746\u5748\u5749\u574B\u5752\u5753"+ + "\u5754\u5755\u5756\u5758\u5759\u5762\u5763\u5765"+ + "\u5767\u576C\u576E\u5770\u5771\u5772\u5774\u5775"+ + "\u5778\u5779\u577A\u577D\u577E\u577F\u5780\uFFFD"+ + "\u5781\u5787\u5788\u5789\u578A\u578D\u578E\u578F"+ + "\u5790\u5791\u5794\u5795\u5796\u5797\u5798\u5799"+ + "\u579A\u579C\u579D\u579E\u579F\u57A5\u57A8\u57AA"+ + "\u57AC\u57AF\u57B0\u57B1\u57B3\u57B5\u57B6\u57B7"+ + "\u57B9\u57BA\u57BB\u57BC\u57BD\u57BE\u57BF\u57C0"+ + "\u57C1\u57C4\u57C5\u57C6\u57C7\u57C8\u57C9\u57CA"+ + "\u57CC\u57CD\u57D0\u57D1\u57D3\u57D6\u57D7\u57DB"+ + "\u57DC\u57DE\u57E1\u57E2\u57E3\u57E5\u57E6\u57E7"+ + "\u57E8\u57E9\u57EA\u57EB\u57EC\u57EE\u57F0\u57F1"+ + "\u57F2\u57F3\u57F5\u57F6\u57F7\u57FB\u57FC\u57FE"+ + "\u57FF\u5801\u5803\u5804\u5805\u5808\u5809\u580A"+ + "\u580C\u580E\u580F\u5810\u5812\u5813\u5814\u5816"+ + "\u5817\u5818\u581A\u581B\u581C\u581D\u581F\u5822"+ + "\u5823\u5825\u5826\u5827\u5828\u5829\u582B\u582C"+ + "\u582D\u582E\u582F\u5831\u5832\u5833\u5834\u5836"+ + "\u5837\u5838\u5839\u583A\u583B\u583C\u583D\u583E"+ + "\u583F\u5840\u5841\u5842\u5843\u5845\u5846\u5847"+ + "\u5848\u5849\u584A\u584B\u584E\u584F\u5850\u5852"+ + "\u5853\u5855\u5856\u5857\u5859\u585A\u585B\u585C"+ + "\u585D\u585F\u5860\u5861\u5862\u5863\u5864\u5866"+ + "\u5867\u5868\u5869\u586A\u586D\u586E\u586F\u5870"+ + "\u5871\u5872\u5873\u5874\u5875\u5876\u5877\u5878"+ + "\u5879\u587A\u587B\u587C\u587D\u587F\u5882\u5884"+ + "\u5886\u5887\u5888\u588A\u588B\u588C\uFFFD\u588D"+ + "\u588E\u588F\u5890\u5891\u5894\u5895\u5896\u5897"+ + "\u5898\u589B\u589C\u589D\u58A0\u58A1\u58A2\u58A3"+ + "\u58A4\u58A5\u58A6\u58A7\u58AA\u58AB\u58AC\u58AD"+ + "\u58AE\u58AF\u58B0\u58B1\u58B2\u58B3\u58B4\u58B5"+ + "\u58B6\u58B7\u58B8\u58B9\u58BA\u58BB\u58BD\u58BE"+ + "\u58BF\u58C0\u58C2\u58C3\u58C4\u58C6\u58C7\u58C8"+ + "\u58C9\u58CA\u58CB\u58CC\u58CD\u58CE\u58CF\u58D0"+ + "\u58D2\u58D3\u58D4\u58D6\u58D7\u58D8\u58D9\u58DA"+ + "\u58DB\u58DC\u58DD\u58DE\u58DF\u58E0\u58E1\u58E2"+ + "\u58E3\u58E5\u58E6\u58E7\u58E8\u58E9\u58EA\u58ED"+ + "\u58EF\u58F1\u58F2\u58F4\u58F5\u58F7\u58F8\u58FA"+ + "\u58FB\u58FC\u58FD\u58FE\u58FF\u5900\u5901\u5903"+ + "\u5905\u5906\u5908\u5909\u590A\u590B\u590C\u590E"+ + "\u5910\u5911\u5912\u5913\u5917\u5918\u591B\u591D"+ + "\u591E\u5920\u5921\u5922\u5923\u5926\u5928\u592C"+ + "\u5930\u5932\u5933\u5935\u5936\u593B\u593D\u593E"+ + "\u593F\u5940\u5943\u5945\u5946\u594A\u594C\u594D"+ + "\u5950\u5952\u5953\u5959\u595B\u595C\u595D\u595E"+ + "\u595F\u5961\u5963\u5964\u5966\u5967\u5968\u5969"+ + "\u596A\u596B\u596C\u596D\u596E\u596F\u5970\u5971"+ + "\u5972\u5975\u5977\u597A\u597B\u597C\u597E\u597F"+ + "\u5980\u5985\u5989\u598B\u598C\u598E\u598F\u5990"+ + "\u5991\u5994\u5995\u5998\u599A\u599B\u599C\u599D"+ + "\u599F\u59A0\u59A1\u59A2\u59A6\uFFFD\u59A7\u59AC"+ + "\u59AD\u59B0\u59B1\u59B3\u59B4\u59B5\u59B6\u59B7"+ + "\u59B8\u59BA\u59BC\u59BD\u59BF\u59C0\u59C1\u59C2"+ + "\u59C3\u59C4\u59C5\u59C7\u59C8\u59C9\u59CC\u59CD"+ + "\u59CE\u59CF\u59D5\u59D6\u59D9\u59DB\u59DE\u59DF"+ + "\u59E0\u59E1\u59E2\u59E4\u59E6\u59E7\u59E9\u59EA"+ + "\u59EB\u59ED\u59EE\u59EF\u59F0\u59F1\u59F2\u59F3"+ + "\u59F4\u59F5\u59F6\u59F7\u59F8\u59FA\u59FC\u59FD"+ + "\u59FE\u5A00\u5A02\u5A0A\u5A0B\u5A0D\u5A0E\u5A0F"+ + "\u5A10\u5A12\u5A14\u5A15\u5A16\u5A17\u5A19\u5A1A"+ + "\u5A1B\u5A1D\u5A1E\u5A21\u5A22\u5A24\u5A26\u5A27"+ + "\u5A28\u5A2A\u5A2B\u5A2C\u5A2D\u5A2E\u5A2F\u5A30"+ + "\u5A33\u5A35\u5A37\u5A38\u5A39\u5A3A\u5A3B\u5A3D"+ + "\u5A3E\u5A3F\u5A41\u5A42\u5A43\u5A44\u5A45\u5A47"+ + "\u5A48\u5A4B\u5A4C\u5A4D\u5A4E\u5A4F\u5A50\u5A51"+ + "\u5A52\u5A53\u5A54\u5A56\u5A57\u5A58\u5A59\u5A5B"+ + "\u5A5C\u5A5D\u5A5E\u5A5F\u5A60\u5A61\u5A63\u5A64"+ + "\u5A65\u5A66\u5A68\u5A69\u5A6B\u5A6C\u5A6D\u5A6E"+ + "\u5A6F\u5A70\u5A71\u5A72\u5A73\u5A78\u5A79\u5A7B"+ + "\u5A7C\u5A7D\u5A7E\u5A80\u5A81\u5A82\u5A83\u5A84"+ + "\u5A85\u5A86\u5A87\u5A88\u5A89\u5A8A\u5A8B\u5A8C"+ + "\u5A8D\u5A8E\u5A8F\u5A90\u5A91\u5A93\u5A94\u5A95"+ + "\u5A96\u5A97\u5A98\u5A99\u5A9C\u5A9D\u5A9E\u5A9F"+ + "\u5AA0\u5AA1\u5AA2\u5AA3\u5AA4\u5AA5\u5AA6\u5AA7"+ + "\u5AA8\u5AA9\u5AAB\u5AAC\uFFFD\u5AAD\u5AAE\u5AAF"+ + "\u5AB0\u5AB1\u5AB4\u5AB6\u5AB7\u5AB9\u5ABA\u5ABB"+ + "\u5ABC\u5ABD\u5ABF\u5AC0\u5AC3\u5AC4\u5AC5\u5AC6"+ + "\u5AC7\u5AC8\u5ACA\u5ACB\u5ACD\u5ACE\u5ACF\u5AD0"+ + "\u5AD1\u5AD3\u5AD5\u5AD7\u5AD9\u5ADA\u5ADB\u5ADD"+ + "\u5ADE\u5ADF\u5AE2\u5AE4\u5AE5\u5AE7\u5AE8\u5AEA"+ + "\u5AEC\u5AED\u5AEE\u5AEF\u5AF0\u5AF2\u5AF3\u5AF4"+ + "\u5AF5\u5AF6\u5AF7\u5AF8\u5AF9\u5AFA\u5AFB\u5AFC"+ + "\u5AFD\u5AFE\u5AFF\u5B00\u5B01\u5B02\u5B03\u5B04"+ + "\u5B05\u5B06\u5B07\u5B08\u5B0A\u5B0B\u5B0C\u5B0D"+ + "\u5B0E\u5B0F\u5B10\u5B11\u5B12\u5B13\u5B14\u5B15"+ + "\u5B18\u5B19\u5B1A\u5B1B\u5B1C\u5B1D\u5B1E\u5B1F"+ + "\u5B20\u5B21\u5B22\u5B23\u5B24\u5B25\u5B26\u5B27"+ + "\u5B28\u5B29\u5B2A\u5B2B\u5B2C\u5B2D\u5B2E\u5B2F"+ + "\u5B30\u5B31\u5B33\u5B35\u5B36\u5B38\u5B39\u5B3A"+ + "\u5B3B\u5B3C\u5B3D\u5B3E\u5B3F\u5B41\u5B42\u5B43"+ + "\u5B44\u5B45\u5B46\u5B47\u5B48\u5B49\u5B4A\u5B4B"+ + "\u5B4C\u5B4D\u5B4E\u5B4F\u5B52\u5B56\u5B5E\u5B60"+ + "\u5B61\u5B67\u5B68\u5B6B\u5B6D\u5B6E\u5B6F\u5B72"+ + "\u5B74\u5B76\u5B77\u5B78\u5B79\u5B7B\u5B7C\u5B7E"+ + "\u5B7F\u5B82\u5B86\u5B8A\u5B8D\u5B8E\u5B90\u5B91"+ + "\u5B92\u5B94\u5B96\u5B9F\u5BA7\u5BA8\u5BA9\u5BAC"+ + "\u5BAD\u5BAE\u5BAF\u5BB1\u5BB2\u5BB7\u5BBA\u5BBB"+ + "\u5BBC\u5BC0\u5BC1\u5BC3\u5BC8\u5BC9\u5BCA\u5BCB"+ + "\u5BCD\u5BCE\u5BCF\uFFFD\u5BD1\u5BD4\u5BD5\u5BD6"+ + "\u5BD7\u5BD8\u5BD9\u5BDA\u5BDB\u5BDC\u5BE0\u5BE2"+ + "\u5BE3\u5BE6\u5BE7\u5BE9\u5BEA\u5BEB\u5BEC\u5BED"+ + "\u5BEF\u5BF1\u5BF2\u5BF3\u5BF4\u5BF5\u5BF6\u5BF7"+ + "\u5BFD\u5BFE\u5C00\u5C02\u5C03\u5C05\u5C07\u5C08"+ + "\u5C0B\u5C0C\u5C0D\u5C0E\u5C10\u5C12\u5C13\u5C17"+ + "\u5C19\u5C1B\u5C1E\u5C1F\u5C20\u5C21\u5C23\u5C26"+ + "\u5C28\u5C29\u5C2A\u5C2B\u5C2D\u5C2E\u5C2F\u5C30"+ + "\u5C32\u5C33\u5C35\u5C36\u5C37\u5C43\u5C44\u5C46"+ + "\u5C47\u5C4C\u5C4D\u5C52\u5C53\u5C54\u5C56\u5C57"+ + "\u5C58\u5C5A\u5C5B\u5C5C\u5C5D\u5C5F\u5C62\u5C64"+ + "\u5C67\u5C68\u5C69\u5C6A\u5C6B\u5C6C\u5C6D\u5C70"+ + "\u5C72\u5C73\u5C74\u5C75\u5C76\u5C77\u5C78\u5C7B"+ + "\u5C7C\u5C7D\u5C7E\u5C80\u5C83\u5C84\u5C85\u5C86"+ + "\u5C87\u5C89\u5C8A\u5C8B\u5C8E\u5C8F\u5C92\u5C93"+ + "\u5C95\u5C9D\u5C9E\u5C9F\u5CA0\u5CA1\u5CA4\u5CA5"+ + "\u5CA6\u5CA7\u5CA8\u5CAA\u5CAE\u5CAF\u5CB0\u5CB2"+ + "\u5CB4\u5CB6\u5CB9\u5CBA\u5CBB\u5CBC\u5CBE\u5CC0"+ + "\u5CC2\u5CC3\u5CC5\u5CC6\u5CC7\u5CC8\u5CC9\u5CCA"+ + "\u5CCC\u5CCD\u5CCE\u5CCF\u5CD0\u5CD1\u5CD3\u5CD4"+ + "\u5CD5\u5CD6\u5CD7\u5CD8\u5CDA\u5CDB\u5CDC\u5CDD"+ + "\u5CDE\u5CDF\u5CE0\u5CE2\u5CE3\u5CE7\u5CE9\u5CEB"+ + "\u5CEC\u5CEE\u5CEF\u5CF1\u5CF2\u5CF3\u5CF4\u5CF5"+ + "\u5CF6\u5CF7\u5CF8\u5CF9\u5CFA\u5CFC\u5CFD\u5CFE"+ + "\u5CFF\u5D00\uFFFD\u5D01\u5D04\u5D05\u5D08\u5D09"+ + "\u5D0A\u5D0B\u5D0C\u5D0D\u5D0F\u5D10\u5D11\u5D12"+ + "\u5D13\u5D15\u5D17\u5D18\u5D19\u5D1A\u5D1C\u5D1D"+ + "\u5D1F\u5D20\u5D21\u5D22\u5D23\u5D25\u5D28\u5D2A"+ + "\u5D2B\u5D2C\u5D2F\u5D30\u5D31\u5D32\u5D33\u5D35"+ + "\u5D36\u5D37\u5D38\u5D39\u5D3A\u5D3B\u5D3C\u5D3F"+ + "\u5D40\u5D41\u5D42\u5D43\u5D44\u5D45\u5D46\u5D48"+ + "\u5D49\u5D4D\u5D4E\u5D4F\u5D50\u5D51\u5D52\u5D53"+ + "\u5D54\u5D55\u5D56\u5D57\u5D59\u5D5A\u5D5C\u5D5E"+ + "\u5D5F\u5D60\u5D61\u5D62\u5D63\u5D64\u5D65\u5D66"+ + "\u5D67\u5D68\u5D6A\u5D6D\u5D6E\u5D70\u5D71\u5D72"+ + "\u5D73\u5D75\u5D76\u5D77\u5D78\u5D79\u5D7A\u5D7B"+ + "\u5D7C\u5D7D\u5D7E\u5D7F\u5D80\u5D81\u5D83\u5D84"+ + "\u5D85\u5D86\u5D87\u5D88\u5D89\u5D8A\u5D8B\u5D8C"+ + "\u5D8D\u5D8E\u5D8F\u5D90\u5D91\u5D92\u5D93\u5D94"+ + "\u5D95\u5D96\u5D97\u5D98\u5D9A\u5D9B\u5D9C\u5D9E"+ + "\u5D9F\u5DA0\u5DA1\u5DA2\u5DA3\u5DA4\u5DA5\u5DA6"+ + "\u5DA7\u5DA8\u5DA9\u5DAA\u5DAB\u5DAC\u5DAD\u5DAE"+ + "\u5DAF\u5DB0\u5DB1\u5DB2\u5DB3\u5DB4\u5DB5\u5DB6"+ + "\u5DB8\u5DB9\u5DBA\u5DBB\u5DBC\u5DBD\u5DBE\u5DBF"+ + "\u5DC0\u5DC1\u5DC2\u5DC3\u5DC4\u5DC6\u5DC7\u5DC8"+ + "\u5DC9\u5DCA\u5DCB\u5DCC\u5DCE\u5DCF\u5DD0\u5DD1"+ + "\u5DD2\u5DD3\u5DD4\u5DD5\u5DD6\u5DD7\u5DD8\u5DD9"+ + "\u5DDA\u5DDC\u5DDF\u5DE0\u5DE3\u5DE4\u5DEA\u5DEC"+ + "\u5DED\uFFFD\u5DF0\u5DF5\u5DF6\u5DF8\u5DF9\u5DFA"+ + "\u5DFB\u5DFC\u5DFF\u5E00\u5E04\u5E07\u5E09\u5E0A"+ + "\u5E0B\u5E0D\u5E0E\u5E12\u5E13\u5E17\u5E1E\u5E1F"+ + "\u5E20\u5E21\u5E22\u5E23\u5E24\u5E25\u5E28\u5E29"+ + "\u5E2A\u5E2B\u5E2C\u5E2F\u5E30\u5E32\u5E33\u5E34"+ + "\u5E35\u5E36\u5E39\u5E3A\u5E3E\u5E3F\u5E40\u5E41"+ + "\u5E43\u5E46\u5E47\u5E48\u5E49\u5E4A\u5E4B\u5E4D"+ + "\u5E4E\u5E4F\u5E50\u5E51\u5E52\u5E53\u5E56\u5E57"+ + "\u5E58\u5E59\u5E5A\u5E5C\u5E5D\u5E5F\u5E60\u5E63"+ + "\u5E64\u5E65\u5E66\u5E67\u5E68\u5E69\u5E6A\u5E6B"+ + "\u5E6C\u5E6D\u5E6E\u5E6F\u5E70\u5E71\u5E75\u5E77"+ + "\u5E79\u5E7E\u5E81\u5E82\u5E83\u5E85\u5E88\u5E89"+ + "\u5E8C\u5E8D\u5E8E\u5E92\u5E98\u5E9B\u5E9D\u5EA1"+ + "\u5EA2\u5EA3\u5EA4\u5EA8\u5EA9\u5EAA\u5EAB\u5EAC"+ + "\u5EAE\u5EAF\u5EB0\u5EB1\u5EB2\u5EB4\u5EBA\u5EBB"+ + "\u5EBC\u5EBD\u5EBF\u5EC0\u5EC1\u5EC2\u5EC3\u5EC4"+ + "\u5EC5\u5EC6\u5EC7\u5EC8\u5ECB\u5ECC\u5ECD\u5ECE"+ + "\u5ECF\u5ED0\u5ED4\u5ED5\u5ED7\u5ED8\u5ED9\u5EDA"+ + "\u5EDC\u5EDD\u5EDE\u5EDF\u5EE0\u5EE1\u5EE2\u5EE3"+ + "\u5EE4\u5EE5\u5EE6\u5EE7\u5EE9\u5EEB\u5EEC\u5EED"+ + "\u5EEE\u5EEF\u5EF0\u5EF1\u5EF2\u5EF3\u5EF5\u5EF8"+ + "\u5EF9\u5EFB\u5EFC\u5EFD\u5F05\u5F06\u5F07\u5F09"+ + "\u5F0C\u5F0D\u5F0E\u5F10\u5F12\u5F14\u5F16\u5F19"+ + "\u5F1A\u5F1C\u5F1D\u5F1E\u5F21\u5F22\u5F23\u5F24"+ + "\uFFFD\u5F28\u5F2B\u5F2C\u5F2E\u5F30\u5F32\u5F33"+ + "\u5F34\u5F35\u5F36\u5F37\u5F38\u5F3B\u5F3D\u5F3E"+ + "\u5F3F\u5F41\u5F42\u5F43\u5F44\u5F45\u5F46\u5F47"+ + "\u5F48\u5F49\u5F4A\u5F4B\u5F4C\u5F4D\u5F4E\u5F4F"+ + "\u5F51\u5F54\u5F59\u5F5A\u5F5B\u5F5C\u5F5E\u5F5F"+ + "\u5F60\u5F63\u5F65\u5F67\u5F68\u5F6B\u5F6E\u5F6F"+ + "\u5F72\u5F74\u5F75\u5F76\u5F78\u5F7A\u5F7D\u5F7E"+ + "\u5F7F\u5F83\u5F86\u5F8D\u5F8E\u5F8F\u5F91\u5F93"+ + "\u5F94\u5F96\u5F9A\u5F9B\u5F9D\u5F9E\u5F9F\u5FA0"+ + "\u5FA2\u5FA3\u5FA4\u5FA5\u5FA6\u5FA7\u5FA9\u5FAB"+ + "\u5FAC\u5FAF\u5FB0\u5FB1\u5FB2\u5FB3\u5FB4\u5FB6"+ + "\u5FB8\u5FB9\u5FBA\u5FBB\u5FBE\u5FBF\u5FC0\u5FC1"+ + "\u5FC2\u5FC7\u5FC8\u5FCA\u5FCB\u5FCE\u5FD3\u5FD4"+ + "\u5FD5\u5FDA\u5FDB\u5FDC\u5FDE\u5FDF\u5FE2\u5FE3"+ + "\u5FE5\u5FE6\u5FE8\u5FE9\u5FEC\u5FEF\u5FF0\u5FF2"+ + "\u5FF3\u5FF4\u5FF6\u5FF7\u5FF9\u5FFA\u5FFC\u6007"; + + private static final String innerIndex1= + "\u6008\u6009\u600B\u600C\u6010\u6011\u6013\u6017"+ + "\u6018\u601A\u601E\u601F\u6022\u6023\u6024\u602C"+ + "\u602D\u602E\u6030\u6031\u6032\u6033\u6034\u6036"+ + "\u6037\u6038\u6039\u603A\u603D\u603E\u6040\u6044"+ + "\u6045\u6046\u6047\u6048\u6049\u604A\u604C\u604E"+ + "\u604F\u6051\u6053\u6054\u6056\u6057\u6058\u605B"+ + "\u605C\u605E\u605F\u6060\u6061\u6065\u6066\u606E"+ + "\u6071\u6072\u6074\u6075\u6077\u607E\u6080\uFFFD"+ + "\u6081\u6082\u6085\u6086\u6087\u6088\u608A\u608B"+ + "\u608E\u608F\u6090\u6091\u6093\u6095\u6097\u6098"+ + "\u6099\u609C\u609E\u60A1\u60A2\u60A4\u60A5\u60A7"+ + "\u60A9\u60AA\u60AE\u60B0\u60B3\u60B5\u60B6\u60B7"+ + "\u60B9\u60BA\u60BD\u60BE\u60BF\u60C0\u60C1\u60C2"+ + "\u60C3\u60C4\u60C7\u60C8\u60C9\u60CC\u60CD\u60CE"+ + "\u60CF\u60D0\u60D2\u60D3\u60D4\u60D6\u60D7\u60D9"+ + "\u60DB\u60DE\u60E1\u60E2\u60E3\u60E4\u60E5\u60EA"+ + "\u60F1\u60F2\u60F5\u60F7\u60F8\u60FB\u60FC\u60FD"+ + "\u60FE\u60FF\u6102\u6103\u6104\u6105\u6107\u610A"+ + "\u610B\u610C\u6110\u6111\u6112\u6113\u6114\u6116"+ + "\u6117\u6118\u6119\u611B\u611C\u611D\u611E\u6121"+ + "\u6122\u6125\u6128\u6129\u612A\u612C\u612D\u612E"+ + "\u612F\u6130\u6131\u6132\u6133\u6134\u6135\u6136"+ + "\u6137\u6138\u6139\u613A\u613B\u613C\u613D\u613E"+ + "\u6140\u6141\u6142\u6143\u6144\u6145\u6146\u6147"+ + "\u6149\u614B\u614D\u614F\u6150\u6152\u6153\u6154"+ + "\u6156\u6157\u6158\u6159\u615A\u615B\u615C\u615E"+ + "\u615F\u6160\u6161\u6163\u6164\u6165\u6166\u6169"+ + "\u616A\u616B\u616C\u616D\u616E\u616F\u6171\u6172"+ + "\u6173\u6174\u6176\u6178\u6179\u617A\u617B\u617C"+ + "\u617D\u617E\u617F\u6180\u6181\u6182\u6183\u6184"+ + "\u6185\u6186\u6187\u6188\u6189\u618A\u618C\u618D"+ + "\u618F\u6190\u6191\u6192\u6193\u6195\uFFFD\u6196"+ + "\u6197\u6198\u6199\u619A\u619B\u619C\u619E\u619F"+ + "\u61A0\u61A1\u61A2\u61A3\u61A4\u61A5\u61A6\u61AA"+ + "\u61AB\u61AD\u61AE\u61AF\u61B0\u61B1\u61B2\u61B3"+ + "\u61B4\u61B5\u61B6\u61B8\u61B9\u61BA\u61BB\u61BC"+ + "\u61BD\u61BF\u61C0\u61C1\u61C3\u61C4\u61C5\u61C6"+ + "\u61C7\u61C9\u61CC\u61CD\u61CE\u61CF\u61D0\u61D3"+ + "\u61D5\u61D6\u61D7\u61D8\u61D9\u61DA\u61DB\u61DC"+ + "\u61DD\u61DE\u61DF\u61E0\u61E1\u61E2\u61E3\u61E4"+ + "\u61E5\u61E7\u61E8\u61E9\u61EA\u61EB\u61EC\u61ED"+ + "\u61EE\u61EF\u61F0\u61F1\u61F2\u61F3\u61F4\u61F6"+ + "\u61F7\u61F8\u61F9\u61FA\u61FB\u61FC\u61FD\u61FE"+ + "\u6200\u6201\u6202\u6203\u6204\u6205\u6207\u6209"+ + "\u6213\u6214\u6219\u621C\u621D\u621E\u6220\u6223"+ + "\u6226\u6227\u6228\u6229\u622B\u622D\u622F\u6230"+ + "\u6231\u6232\u6235\u6236\u6238\u6239\u623A\u623B"+ + "\u623C\u6242\u6244\u6245\u6246\u624A\u624F\u6250"+ + "\u6255\u6256\u6257\u6259\u625A\u625C\u625D\u625E"+ + "\u625F\u6260\u6261\u6262\u6264\u6265\u6268\u6271"+ + "\u6272\u6274\u6275\u6277\u6278\u627A\u627B\u627D"+ + "\u6281\u6282\u6283\u6285\u6286\u6287\u6288\u628B"+ + "\u628C\u628D\u628E\u628F\u6290\u6294\u6299\u629C"+ + "\u629D\u629E\u62A3\u62A6\u62A7\u62A9\u62AA\u62AD"+ + "\u62AE\u62AF\u62B0\u62B2\u62B3\u62B4\u62B6\u62B7"+ + "\u62B8\u62BA\u62BE\u62C0\u62C1\uFFFD\u62C3\u62CB"+ + "\u62CF\u62D1\u62D5\u62DD\u62DE\u62E0\u62E1\u62E4"+ + "\u62EA\u62EB\u62F0\u62F2\u62F5\u62F8\u62F9\u62FA"+ + "\u62FB\u6300\u6303\u6304\u6305\u6306\u630A\u630B"+ + "\u630C\u630D\u630F\u6310\u6312\u6313\u6314\u6315"+ + "\u6317\u6318\u6319\u631C\u6326\u6327\u6329\u632C"+ + "\u632D\u632E\u6330\u6331\u6333\u6334\u6335\u6336"+ + "\u6337\u6338\u633B\u633C\u633E\u633F\u6340\u6341"+ + "\u6344\u6347\u6348\u634A\u6351\u6352\u6353\u6354"+ + "\u6356\u6357\u6358\u6359\u635A\u635B\u635C\u635D"+ + "\u6360\u6364\u6365\u6366\u6368\u636A\u636B\u636C"+ + "\u636F\u6370\u6372\u6373\u6374\u6375\u6378\u6379"+ + "\u637C\u637D\u637E\u637F\u6381\u6383\u6384\u6385"+ + "\u6386\u638B\u638D\u6391\u6393\u6394\u6395\u6397"+ + "\u6399\u639A\u639B\u639C\u639D\u639E\u639F\u63A1"+ + "\u63A4\u63A6\u63AB\u63AF\u63B1\u63B2\u63B5\u63B6"+ + "\u63B9\u63BB\u63BD\u63BF\u63C0\u63C1\u63C2\u63C3"+ + "\u63C5\u63C7\u63C8\u63CA\u63CB\u63CC\u63D1\u63D3"+ + "\u63D4\u63D5\u63D7\u63D8\u63D9\u63DA\u63DB\u63DC"+ + "\u63DD\u63DF\u63E2\u63E4\u63E5\u63E6\u63E7\u63E8"+ + "\u63EB\u63EC\u63EE\u63EF\u63F0\u63F1\u63F3\u63F5"+ + "\u63F7\u63F9\u63FA\u63FB\u63FC\u63FE\u6403\u6404"+ + "\u6406\u6407\u6408\u6409\u640A\u640D\u640E\u6411"+ + "\u6412\u6415\u6416\u6417\u6418\u6419\u641A\u641D"+ + "\u641F\u6422\u6423\u6424\uFFFD\u6425\u6427\u6428"+ + "\u6429\u642B\u642E\u642F\u6430\u6431\u6432\u6433"+ + "\u6435\u6436\u6437\u6438\u6439\u643B\u643C\u643E"+ + "\u6440\u6442\u6443\u6449\u644B\u644C\u644D\u644E"+ + "\u644F\u6450\u6451\u6453\u6455\u6456\u6457\u6459"+ + "\u645A\u645B\u645C\u645D\u645F\u6460\u6461\u6462"+ + "\u6463\u6464\u6465\u6466\u6468\u646A\u646B\u646C"+ + "\u646E\u646F\u6470\u6471\u6472\u6473\u6474\u6475"+ + "\u6476\u6477\u647B\u647C\u647D\u647E\u647F\u6480"+ + "\u6481\u6483\u6486\u6488\u6489\u648A\u648B\u648C"+ + "\u648D\u648E\u648F\u6490\u6493\u6494\u6497\u6498"+ + "\u649A\u649B\u649C\u649D\u649F\u64A0\u64A1\u64A2"+ + "\u64A3\u64A5\u64A6\u64A7\u64A8\u64AA\u64AB\u64AF"+ + "\u64B1\u64B2\u64B3\u64B4\u64B6\u64B9\u64BB\u64BD"+ + "\u64BE\u64BF\u64C1\u64C3\u64C4\u64C6\u64C7\u64C8"+ + "\u64C9\u64CA\u64CB\u64CC\u64CF\u64D1\u64D3\u64D4"+ + "\u64D5\u64D6\u64D9\u64DA\u64DB\u64DC\u64DD\u64DF"+ + "\u64E0\u64E1\u64E3\u64E5\u64E7\u64E8\u64E9\u64EA"+ + "\u64EB\u64EC\u64ED\u64EE\u64EF\u64F0\u64F1\u64F2"+ + "\u64F3\u64F4\u64F5\u64F6\u64F7\u64F8\u64F9\u64FA"+ + "\u64FB\u64FC\u64FD\u64FE\u64FF\u6501\u6502\u6503"+ + "\u6504\u6505\u6506\u6507\u6508\u650A\u650B\u650C"+ + "\u650D\u650E\u650F\u6510\u6511\u6513\u6514\u6515"+ + "\u6516\u6517\u6519\u651A\u651B\u651C\u651D\u651E"+ + "\u651F\u6520\u6521\uFFFD\u6522\u6523\u6524\u6526"+ + "\u6527\u6528\u6529\u652A\u652C\u652D\u6530\u6531"+ + "\u6532\u6533\u6537\u653A\u653C\u653D\u6540\u6541"+ + "\u6542\u6543\u6544\u6546\u6547\u654A\u654B\u654D"+ + "\u654E\u6550\u6552\u6553\u6554\u6557\u6558\u655A"+ + "\u655C\u655F\u6560\u6561\u6564\u6565\u6567\u6568"+ + "\u6569\u656A\u656D\u656E\u656F\u6571\u6573\u6575"+ + "\u6576\u6578\u6579\u657A\u657B\u657C\u657D\u657E"+ + "\u657F\u6580\u6581\u6582\u6583\u6584\u6585\u6586"+ + "\u6588\u6589\u658A\u658D\u658E\u658F\u6592\u6594"+ + "\u6595\u6596\u6598\u659A\u659D\u659E\u65A0\u65A2"+ + "\u65A3\u65A6\u65A8\u65AA\u65AC\u65AE\u65B1\u65B2"+ + "\u65B3\u65B4\u65B5\u65B6\u65B7\u65B8\u65BA\u65BB"+ + "\u65BE\u65BF\u65C0\u65C2\u65C7\u65C8\u65C9\u65CA"+ + "\u65CD\u65D0\u65D1\u65D3\u65D4\u65D5\u65D8\u65D9"+ + "\u65DA\u65DB\u65DC\u65DD\u65DE\u65DF\u65E1\u65E3"+ + "\u65E4\u65EA\u65EB\u65F2\u65F3\u65F4\u65F5\u65F8"+ + "\u65F9\u65FB\u65FC\u65FD\u65FE\u65FF\u6601\u6604"+ + "\u6605\u6607\u6608\u6609\u660B\u660D\u6610\u6611"+ + "\u6612\u6616\u6617\u6618\u661A\u661B\u661C\u661E"+ + "\u6621\u6622\u6623\u6624\u6626\u6629\u662A\u662B"+ + "\u662C\u662E\u6630\u6632\u6633\u6637\u6638\u6639"+ + "\u663A\u663B\u663D\u663F\u6640\u6642\u6644\u6645"+ + "\u6646\u6647\u6648\u6649\u664A\u664D\u664E\u6650"+ + "\u6651\u6658\uFFFD\u6659\u665B\u665C\u665D\u665E"+ + "\u6660\u6662\u6663\u6665\u6667\u6669\u666A\u666B"+ + "\u666C\u666D\u6671\u6672\u6673\u6675\u6678\u6679"+ + "\u667B\u667C\u667D\u667F\u6680\u6681\u6683\u6685"+ + "\u6686\u6688\u6689\u668A\u668B\u668D\u668E\u668F"+ + "\u6690\u6692\u6693\u6694\u6695\u6698\u6699\u669A"+ + "\u669B\u669C\u669E\u669F\u66A0\u66A1\u66A2\u66A3"+ + "\u66A4\u66A5\u66A6\u66A9\u66AA\u66AB\u66AC\u66AD"+ + "\u66AF\u66B0\u66B1\u66B2\u66B3\u66B5\u66B6\u66B7"+ + "\u66B8\u66BA\u66BB\u66BC\u66BD\u66BF\u66C0\u66C1"+ + "\u66C2\u66C3\u66C4\u66C5\u66C6\u66C7\u66C8\u66C9"+ + "\u66CA\u66CB\u66CC\u66CD\u66CE\u66CF\u66D0\u66D1"+ + "\u66D2\u66D3\u66D4\u66D5\u66D6\u66D7\u66D8\u66DA"+ + "\u66DE\u66DF\u66E0\u66E1\u66E2\u66E3\u66E4\u66E5"+ + "\u66E7\u66E8\u66EA\u66EB\u66EC\u66ED\u66EE\u66EF"+ + "\u66F1\u66F5\u66F6\u66F8\u66FA\u66FB\u66FD\u6701"+ + "\u6702\u6703\u6704\u6705\u6706\u6707\u670C\u670E"+ + "\u670F\u6711\u6712\u6713\u6716\u6718\u6719\u671A"+ + "\u671C\u671E\u6720\u6721\u6722\u6723\u6724\u6725"+ + "\u6727\u6729\u672E\u6730\u6732\u6733\u6736\u6737"+ + "\u6738\u6739\u673B\u673C\u673E\u673F\u6741\u6744"+ + "\u6745\u6747\u674A\u674B\u674D\u6752\u6754\u6755"+ + "\u6757\u6758\u6759\u675A\u675B\u675D\u6762\u6763"+ + "\u6764\u6766\u6767\u676B\u676C\u676E\u6771\u6774"+ + "\u6776\uFFFD\u6778\u6779\u677A\u677B\u677D\u6780"+ + "\u6782\u6783\u6785\u6786\u6788\u678A\u678C\u678D"+ + "\u678E\u678F\u6791\u6792\u6793\u6794\u6796\u6799"+ + "\u679B\u679F\u67A0\u67A1\u67A4\u67A6\u67A9\u67AC"+ + "\u67AE\u67B1\u67B2\u67B4\u67B9\u67BA\u67BB\u67BC"+ + "\u67BD\u67BE\u67BF\u67C0\u67C2\u67C5\u67C6\u67C7"+ + "\u67C8\u67C9\u67CA\u67CB\u67CC\u67CD\u67CE\u67D5"+ + "\u67D6\u67D7\u67DB\u67DF\u67E1\u67E3\u67E4\u67E6"+ + "\u67E7\u67E8\u67EA\u67EB\u67ED\u67EE\u67F2\u67F5"+ + "\u67F6\u67F7\u67F8\u67F9\u67FA\u67FB\u67FC\u67FE"+ + "\u6801\u6802\u6803\u6804\u6806\u680D\u6810\u6812"+ + "\u6814\u6815\u6818\u6819\u681A\u681B\u681C\u681E"+ + "\u681F\u6820\u6822\u6823\u6824\u6825\u6826\u6827"+ + "\u6828\u682B\u682C\u682D\u682E\u682F\u6830\u6831"+ + "\u6834\u6835\u6836\u683A\u683B\u683F\u6847\u684B"+ + "\u684D\u684F\u6852\u6856\u6857\u6858\u6859\u685A"+ + "\u685B\u685C\u685D\u685E\u685F\u686A\u686C\u686D"+ + "\u686E\u686F\u6870\u6871\u6872\u6873\u6875\u6878"+ + "\u6879\u687A\u687B\u687C\u687D\u687E\u687F\u6880"+ + "\u6882\u6884\u6887\u6888\u6889\u688A\u688B\u688C"+ + "\u688D\u688E\u6890\u6891\u6892\u6894\u6895\u6896"+ + "\u6898\u6899\u689A\u689B\u689C\u689D\u689E\u689F"+ + "\u68A0\u68A1\u68A3\u68A4\u68A5\u68A9\u68AA\u68AB"+ + "\u68AC\u68AE\u68B1\u68B2\u68B4\u68B6\u68B7\u68B8"+ + "\uFFFD\u68B9\u68BA\u68BB\u68BC\u68BD\u68BE\u68BF"+ + "\u68C1\u68C3\u68C4\u68C5\u68C6\u68C7\u68C8\u68CA"+ + "\u68CC\u68CE\u68CF\u68D0\u68D1\u68D3\u68D4\u68D6"+ + "\u68D7\u68D9\u68DB\u68DC\u68DD\u68DE\u68DF\u68E1"+ + "\u68E2\u68E4\u68E5\u68E6\u68E7\u68E8\u68E9\u68EA"+ + "\u68EB\u68EC\u68ED\u68EF\u68F2\u68F3\u68F4\u68F6"+ + "\u68F7\u68F8\u68FB\u68FD\u68FE\u68FF\u6900\u6902"+ + "\u6903\u6904\u6906\u6907\u6908\u6909\u690A\u690C"+ + "\u690F\u6911\u6913\u6914\u6915\u6916\u6917\u6918"+ + "\u6919\u691A\u691B\u691C\u691D\u691E\u6921\u6922"+ + "\u6923\u6925\u6926\u6927\u6928\u6929\u692A\u692B"+ + "\u692C\u692E\u692F\u6931\u6932\u6933\u6935\u6936"+ + "\u6937\u6938\u693A\u693B\u693C\u693E\u6940\u6941"+ + "\u6943\u6944\u6945\u6946\u6947\u6948\u6949\u694A"+ + "\u694B\u694C\u694D\u694E\u694F\u6950\u6951\u6952"+ + "\u6953\u6955\u6956\u6958\u6959\u695B\u695C\u695F"+ + "\u6961\u6962\u6964\u6965\u6967\u6968\u6969\u696A"+ + "\u696C\u696D\u696F\u6970\u6972\u6973\u6974\u6975"+ + "\u6976\u697A\u697B\u697D\u697E\u697F\u6981\u6983"+ + "\u6985\u698A\u698B\u698C\u698E\u698F\u6990\u6991"+ + "\u6992\u6993\u6996\u6997\u6999\u699A\u699D\u699E"+ + "\u699F\u69A0\u69A1\u69A2\u69A3\u69A4\u69A5\u69A6"+ + "\u69A9\u69AA\u69AC\u69AE\u69AF\u69B0\u69B2\u69B3"+ + "\u69B5\u69B6\u69B8\u69B9\u69BA\u69BC\u69BD\uFFFD"+ + "\u69BE\u69BF\u69C0\u69C2\u69C3\u69C4\u69C5\u69C6"+ + "\u69C7\u69C8\u69C9\u69CB\u69CD\u69CF\u69D1\u69D2"+ + "\u69D3\u69D5\u69D6\u69D7\u69D8\u69D9\u69DA\u69DC"+ + "\u69DD\u69DE\u69E1\u69E2\u69E3\u69E4\u69E5\u69E6"+ + "\u69E7\u69E8\u69E9\u69EA\u69EB\u69EC\u69EE\u69EF"+ + "\u69F0\u69F1\u69F3\u69F4\u69F5\u69F6\u69F7\u69F8"+ + "\u69F9\u69FA\u69FB\u69FC\u69FE\u6A00\u6A01\u6A02"+ + "\u6A03\u6A04\u6A05\u6A06\u6A07\u6A08\u6A09\u6A0B"+ + "\u6A0C\u6A0D\u6A0E\u6A0F\u6A10\u6A11\u6A12\u6A13"+ + "\u6A14\u6A15\u6A16\u6A19\u6A1A\u6A1B\u6A1C\u6A1D"+ + "\u6A1E\u6A20\u6A22\u6A23\u6A24\u6A25\u6A26\u6A27"+ + "\u6A29\u6A2B\u6A2C\u6A2D\u6A2E\u6A30\u6A32\u6A33"+ + "\u6A34\u6A36\u6A37\u6A38\u6A39\u6A3A\u6A3B\u6A3C"+ + "\u6A3F\u6A40\u6A41\u6A42\u6A43\u6A45\u6A46\u6A48"+ + "\u6A49\u6A4A\u6A4B\u6A4C\u6A4D\u6A4E\u6A4F\u6A51"+ + "\u6A52\u6A53\u6A54\u6A55\u6A56\u6A57\u6A5A\u6A5C"+ + "\u6A5D\u6A5E\u6A5F\u6A60\u6A62\u6A63\u6A64\u6A66"+ + "\u6A67\u6A68\u6A69\u6A6A\u6A6B\u6A6C\u6A6D\u6A6E"+ + "\u6A6F\u6A70\u6A72\u6A73\u6A74\u6A75\u6A76\u6A77"+ + "\u6A78\u6A7A\u6A7B\u6A7D\u6A7E\u6A7F\u6A81\u6A82"+ + "\u6A83\u6A85\u6A86\u6A87\u6A88\u6A89\u6A8A\u6A8B"+ + "\u6A8C\u6A8D\u6A8F\u6A92\u6A93\u6A94\u6A95\u6A96"+ + "\u6A98\u6A99\u6A9A\u6A9B\u6A9C\u6A9D\u6A9E\u6A9F"+ + "\u6AA1\u6AA2\u6AA3\u6AA4\u6AA5\u6AA6\uFFFD\u6AA7"+ + "\u6AA8\u6AAA\u6AAD\u6AAE\u6AAF\u6AB0\u6AB1\u6AB2"+ + "\u6AB3\u6AB4\u6AB5\u6AB6\u6AB7\u6AB8\u6AB9\u6ABA"+ + "\u6ABB\u6ABC\u6ABD\u6ABE\u6ABF\u6AC0\u6AC1\u6AC2"+ + "\u6AC3\u6AC4\u6AC5\u6AC6\u6AC7\u6AC8\u6AC9\u6ACA"+ + "\u6ACB\u6ACC\u6ACD\u6ACE\u6ACF\u6AD0\u6AD1\u6AD2"+ + "\u6AD3\u6AD4\u6AD5\u6AD6\u6AD7\u6AD8\u6AD9\u6ADA"+ + "\u6ADB\u6ADC\u6ADD\u6ADE\u6ADF\u6AE0\u6AE1\u6AE2"+ + "\u6AE3\u6AE4\u6AE5\u6AE6\u6AE7\u6AE8\u6AE9\u6AEA"+ + "\u6AEB\u6AEC\u6AED\u6AEE\u6AEF\u6AF0\u6AF1\u6AF2"+ + "\u6AF3\u6AF4\u6AF5\u6AF6\u6AF7\u6AF8\u6AF9\u6AFA"+ + "\u6AFB\u6AFC\u6AFD\u6AFE\u6AFF\u6B00\u6B01\u6B02"+ + "\u6B03\u6B04\u6B05\u6B06\u6B07\u6B08\u6B09\u6B0A"+ + "\u6B0B\u6B0C\u6B0D\u6B0E\u6B0F\u6B10\u6B11\u6B12"+ + "\u6B13\u6B14\u6B15\u6B16\u6B17\u6B18\u6B19\u6B1A"+ + "\u6B1B\u6B1C\u6B1D\u6B1E\u6B1F\u6B25\u6B26\u6B28"+ + "\u6B29\u6B2A\u6B2B\u6B2C\u6B2D\u6B2E\u6B2F\u6B30"+ + "\u6B31\u6B33\u6B34\u6B35\u6B36\u6B38\u6B3B\u6B3C"+ + "\u6B3D\u6B3F\u6B40\u6B41\u6B42\u6B44\u6B45\u6B48"+ + "\u6B4A\u6B4B\u6B4D\u6B4E\u6B4F\u6B50\u6B51\u6B52"+ + "\u6B53\u6B54\u6B55\u6B56\u6B57\u6B58\u6B5A\u6B5B"+ + "\u6B5C\u6B5D\u6B5E\u6B5F\u6B60\u6B61\u6B68\u6B69"+ + "\u6B6B\u6B6C\u6B6D\u6B6E\u6B6F\u6B70\u6B71\u6B72"+ + "\u6B73\u6B74\u6B75\u6B76\u6B77\u6B78\u6B7A\u6B7D"+ + "\u6B7E\u6B7F\u6B80\u6B85\u6B88\uFFFD\u6B8C\u6B8E"+ + "\u6B8F\u6B90\u6B91\u6B94\u6B95\u6B97\u6B98\u6B99"+ + "\u6B9C\u6B9D\u6B9E\u6B9F\u6BA0\u6BA2\u6BA3\u6BA4"+ + "\u6BA5\u6BA6\u6BA7\u6BA8\u6BA9\u6BAB\u6BAC\u6BAD"+ + "\u6BAE\u6BAF\u6BB0\u6BB1\u6BB2\u6BB6\u6BB8\u6BB9"+ + "\u6BBA\u6BBB\u6BBC\u6BBD\u6BBE\u6BC0\u6BC3\u6BC4"+ + "\u6BC6\u6BC7\u6BC8\u6BC9\u6BCA\u6BCC\u6BCE\u6BD0"+ + "\u6BD1\u6BD8\u6BDA\u6BDC\u6BDD\u6BDE\u6BDF\u6BE0"+ + "\u6BE2\u6BE3\u6BE4\u6BE5\u6BE6\u6BE7\u6BE8\u6BE9"+ + "\u6BEC\u6BED\u6BEE\u6BF0\u6BF1\u6BF2\u6BF4\u6BF6"+ + "\u6BF7\u6BF8\u6BFA\u6BFB\u6BFC\u6BFE\u6BFF\u6C00"+ + "\u6C01\u6C02\u6C03\u6C04\u6C08\u6C09\u6C0A\u6C0B"+ + "\u6C0C\u6C0E\u6C12\u6C17\u6C1C\u6C1D\u6C1E\u6C20"+ + "\u6C23\u6C25\u6C2B\u6C2C\u6C2D\u6C31\u6C33\u6C36"+ + "\u6C37\u6C39\u6C3A\u6C3B\u6C3C\u6C3E\u6C3F\u6C43"+ + "\u6C44\u6C45\u6C48\u6C4B\u6C4C\u6C4D\u6C4E\u6C4F"+ + "\u6C51\u6C52\u6C53\u6C56\u6C58\u6C59\u6C5A\u6C62"+ + "\u6C63\u6C65\u6C66\u6C67\u6C6B\u6C6C\u6C6D\u6C6E"+ + "\u6C6F\u6C71\u6C73\u6C75\u6C77\u6C78\u6C7A\u6C7B"+ + "\u6C7C\u6C7F\u6C80\u6C84\u6C87\u6C8A\u6C8B\u6C8D"+ + "\u6C8E\u6C91\u6C92\u6C95\u6C96\u6C97\u6C98\u6C9A"+ + "\u6C9C\u6C9D\u6C9E\u6CA0\u6CA2\u6CA8\u6CAC\u6CAF"+ + "\u6CB0\u6CB4\u6CB5\u6CB6\u6CB7\u6CBA\u6CC0\u6CC1"+ + "\u6CC2\u6CC3\u6CC6\u6CC7\u6CC8\u6CCB\u6CCD\u6CCE"+ + "\u6CCF\u6CD1\u6CD2\u6CD8\uFFFD\u6CD9\u6CDA\u6CDC"+ + "\u6CDD\u6CDF\u6CE4\u6CE6\u6CE7\u6CE9\u6CEC\u6CED"+ + "\u6CF2\u6CF4\u6CF9\u6CFF\u6D00\u6D02\u6D03\u6D05"+ + "\u6D06\u6D08\u6D09\u6D0A\u6D0D\u6D0F\u6D10\u6D11"+ + "\u6D13\u6D14\u6D15\u6D16\u6D18\u6D1C\u6D1D\u6D1F"+ + "\u6D20\u6D21\u6D22\u6D23\u6D24\u6D26\u6D28\u6D29"+ + "\u6D2C\u6D2D\u6D2F\u6D30\u6D34\u6D36\u6D37\u6D38"+ + "\u6D3A\u6D3F\u6D40\u6D42\u6D44\u6D49\u6D4C\u6D50"+ + "\u6D55\u6D56\u6D57\u6D58\u6D5B\u6D5D\u6D5F\u6D61"+ + "\u6D62\u6D64\u6D65\u6D67\u6D68\u6D6B\u6D6C\u6D6D"+ + "\u6D70\u6D71\u6D72\u6D73\u6D75\u6D76\u6D79\u6D7A"+ + "\u6D7B\u6D7D\u6D7E\u6D7F\u6D80\u6D81\u6D83\u6D84"+ + "\u6D86\u6D87\u6D8A\u6D8B\u6D8D\u6D8F\u6D90\u6D92"+ + "\u6D96\u6D97\u6D98\u6D99\u6D9A\u6D9C\u6DA2\u6DA5"+ + "\u6DAC\u6DAD\u6DB0\u6DB1\u6DB3\u6DB4\u6DB6\u6DB7"+ + "\u6DB9\u6DBA\u6DBB\u6DBC\u6DBD\u6DBE\u6DC1\u6DC2"+ + "\u6DC3\u6DC8\u6DC9\u6DCA\u6DCD\u6DCE\u6DCF\u6DD0"+ + "\u6DD2\u6DD3\u6DD4\u6DD5\u6DD7\u6DDA\u6DDB\u6DDC"+ + "\u6DDF\u6DE2\u6DE3\u6DE5\u6DE7\u6DE8\u6DE9\u6DEA"+ + "\u6DED\u6DEF\u6DF0\u6DF2\u6DF4\u6DF5\u6DF6\u6DF8"+ + "\u6DFA\u6DFD\u6DFE\u6DFF\u6E00\u6E01\u6E02\u6E03"+ + "\u6E04\u6E06\u6E07\u6E08\u6E09\u6E0B\u6E0F\u6E12"+ + "\u6E13\u6E15\u6E18\u6E19\u6E1B\u6E1C\u6E1E\u6E1F"+ + "\u6E22\u6E26\u6E27\u6E28\u6E2A\u6E2C\u6E2E\u6E30"+ + "\u6E31\u6E33\u6E35\uFFFD\u6E36\u6E37\u6E39\u6E3B"+ + "\u6E3C\u6E3D\u6E3E\u6E3F\u6E40\u6E41\u6E42\u6E45"+ + "\u6E46\u6E47\u6E48\u6E49\u6E4A\u6E4B\u6E4C\u6E4F"+ + "\u6E50\u6E51\u6E52\u6E55\u6E57\u6E59\u6E5A\u6E5C"+ + "\u6E5D\u6E5E\u6E60\u6E61\u6E62\u6E63\u6E64\u6E65"+ + "\u6E66\u6E67\u6E68\u6E69\u6E6A\u6E6C\u6E6D\u6E6F"+ + "\u6E70\u6E71\u6E72\u6E73\u6E74\u6E75\u6E76\u6E77"+ + "\u6E78\u6E79\u6E7A\u6E7B\u6E7C\u6E7D\u6E80\u6E81"+ + "\u6E82\u6E84\u6E87\u6E88\u6E8A\u6E8B\u6E8C\u6E8D"+ + "\u6E8E\u6E91\u6E92\u6E93\u6E94\u6E95\u6E96\u6E97"+ + "\u6E99\u6E9A\u6E9B\u6E9D\u6E9E\u6EA0\u6EA1\u6EA3"+ + "\u6EA4\u6EA6\u6EA8\u6EA9\u6EAB\u6EAC\u6EAD\u6EAE"+ + "\u6EB0\u6EB3\u6EB5\u6EB8\u6EB9\u6EBC\u6EBE\u6EBF"+ + "\u6EC0\u6EC3\u6EC4\u6EC5\u6EC6\u6EC8\u6EC9\u6ECA"+ + "\u6ECC\u6ECD\u6ECE\u6ED0\u6ED2\u6ED6\u6ED8\u6ED9"+ + "\u6EDB\u6EDC\u6EDD\u6EE3\u6EE7\u6EEA\u6EEB\u6EEC"+ + "\u6EED\u6EEE\u6EEF\u6EF0\u6EF1\u6EF2\u6EF3\u6EF5"+ + "\u6EF6\u6EF7\u6EF8\u6EFA\u6EFB\u6EFC\u6EFD\u6EFE"+ + "\u6EFF\u6F00\u6F01\u6F03\u6F04\u6F05\u6F07\u6F08"+ + "\u6F0A\u6F0B\u6F0C\u6F0D\u6F0E\u6F10\u6F11\u6F12"+ + "\u6F16\u6F17\u6F18\u6F19\u6F1A\u6F1B\u6F1C\u6F1D"+ + "\u6F1E\u6F1F\u6F21\u6F22\u6F23\u6F25\u6F26\u6F27"+ + "\u6F28\u6F2C\u6F2E\u6F30\u6F32\u6F34\u6F35\u6F37"+ + "\u6F38\u6F39\u6F3A\u6F3B\u6F3C\u6F3D\u6F3F\u6F40"+ + "\u6F41\u6F42\uFFFD\u6F43\u6F44\u6F45\u6F48\u6F49"+ + "\u6F4A\u6F4C\u6F4E\u6F4F\u6F50\u6F51\u6F52\u6F53"+ + "\u6F54\u6F55\u6F56\u6F57\u6F59\u6F5A\u6F5B\u6F5D"+ + "\u6F5F\u6F60\u6F61\u6F63\u6F64\u6F65\u6F67\u6F68"+ + "\u6F69\u6F6A\u6F6B\u6F6C\u6F6F\u6F70\u6F71\u6F73"+ + "\u6F75\u6F76\u6F77\u6F79\u6F7B\u6F7D\u6F7E\u6F7F"+ + "\u6F80\u6F81\u6F82\u6F83\u6F85\u6F86\u6F87\u6F8A"+ + "\u6F8B\u6F8F\u6F90\u6F91\u6F92\u6F93\u6F94\u6F95"+ + "\u6F96\u6F97\u6F98\u6F99\u6F9A\u6F9B\u6F9D\u6F9E"+ + "\u6F9F\u6FA0\u6FA2\u6FA3\u6FA4\u6FA5\u6FA6\u6FA8"+ + "\u6FA9\u6FAA\u6FAB\u6FAC\u6FAD\u6FAE\u6FAF\u6FB0"+ + "\u6FB1\u6FB2\u6FB4\u6FB5\u6FB7\u6FB8\u6FBA\u6FBB"+ + "\u6FBC\u6FBD\u6FBE\u6FBF\u6FC1\u6FC3\u6FC4\u6FC5"+ + "\u6FC6\u6FC7\u6FC8\u6FCA\u6FCB\u6FCC\u6FCD\u6FCE"+ + "\u6FCF\u6FD0\u6FD3\u6FD4\u6FD5\u6FD6\u6FD7\u6FD8"+ + "\u6FD9\u6FDA\u6FDB\u6FDC\u6FDD\u6FDF\u6FE2\u6FE3"+ + "\u6FE4\u6FE5\u6FE6\u6FE7\u6FE8\u6FE9\u6FEA\u6FEB"+ + "\u6FEC\u6FED\u6FF0\u6FF1\u6FF2\u6FF3\u6FF4\u6FF5"+ + "\u6FF6\u6FF7\u6FF8\u6FF9\u6FFA\u6FFB\u6FFC\u6FFD"+ + "\u6FFE\u6FFF\u7000\u7001\u7002\u7003\u7004\u7005"+ + "\u7006\u7007\u7008\u7009\u700A\u700B\u700C\u700D"+ + "\u700E\u700F\u7010\u7012\u7013\u7014\u7015\u7016"+ + "\u7017\u7018\u7019\u701C\u701D\u701E\u701F\u7020"+ + "\u7021\u7022\u7024\u7025\u7026\u7027\u7028\u7029"+ + "\u702A\uFFFD\u702B\u702C\u702D\u702E\u702F\u7030"+ + "\u7031\u7032\u7033\u7034\u7036\u7037\u7038\u703A"+ + "\u703B\u703C\u703D\u703E\u703F\u7040\u7041\u7042"+ + "\u7043\u7044\u7045\u7046\u7047\u7048\u7049\u704A"+ + "\u704B\u704D\u704E\u7050\u7051\u7052\u7053\u7054"+ + "\u7055\u7056\u7057\u7058\u7059\u705A\u705B\u705C"+ + "\u705D\u705F\u7060\u7061\u7062\u7063\u7064\u7065"+ + "\u7066\u7067\u7068\u7069\u706A\u706E\u7071\u7072"+ + "\u7073\u7074\u7077\u7079\u707A\u707B\u707D\u7081"+ + "\u7082\u7083\u7084\u7086\u7087\u7088\u708B\u708C"+ + "\u708D\u708F\u7090\u7091\u7093\u7097\u7098\u709A"+ + "\u709B\u709E\u709F\u70A0\u70A1\u70A2\u70A3\u70A4"+ + "\u70A5\u70A6\u70A7\u70A8\u70A9\u70AA\u70B0\u70B2"+ + "\u70B4\u70B5\u70B6\u70BA\u70BE\u70BF\u70C4\u70C5"+ + "\u70C6\u70C7\u70C9\u70CB\u70CC\u70CD\u70CE\u70CF"+ + "\u70D0\u70D1\u70D2\u70D3\u70D4\u70D5\u70D6\u70D7"+ + "\u70DA\u70DC\u70DD\u70DE\u70E0\u70E1\u70E2\u70E3"+ + "\u70E5\u70EA\u70EE\u70F0\u70F1\u70F2\u70F3\u70F4"+ + "\u70F5\u70F6\u70F8\u70FA\u70FB\u70FC\u70FE\u70FF"+ + "\u7100\u7101\u7102\u7103\u7104\u7105\u7106\u7107"+ + "\u7108\u710B\u710C\u710D\u710E\u710F\u7111\u7112"+ + "\u7114\u7117\u711B\u711C\u711D\u711E\u711F\u7120"+ + "\u7121\u7122\u7123\u7124\u7125\u7127\u7128\u7129"+ + "\u712A\u712B\u712C\u712D\u712E\u7132\u7133\u7134"+ + "\uFFFD\u7135\u7137\u7138\u7139\u713A\u713B\u713C"+ + "\u713D\u713E\u713F\u7140\u7141\u7142\u7143\u7144"+ + "\u7146\u7147\u7148\u7149\u714B\u714D\u714F\u7150"+ + "\u7151\u7152\u7153\u7154\u7155\u7156\u7157\u7158"+ + "\u7159\u715A\u715B\u715D\u715F\u7160\u7161\u7162"+ + "\u7163\u7165\u7169\u716A\u716B\u716C\u716D\u716F"+ + "\u7170\u7171\u7174\u7175\u7176\u7177\u7179\u717B"+ + "\u717C\u717E\u717F\u7180\u7181\u7182\u7183\u7185"+ + "\u7186\u7187\u7188\u7189\u718B\u718C\u718D\u718E"+ + "\u7190\u7191\u7192\u7193\u7195\u7196\u7197\u719A"+ + "\u719B\u719C\u719D\u719E\u71A1\u71A2\u71A3\u71A4"+ + "\u71A5\u71A6\u71A7\u71A9\u71AA\u71AB\u71AD\u71AE"+ + "\u71AF\u71B0\u71B1\u71B2\u71B4\u71B6\u71B7\u71B8"+ + "\u71BA\u71BB\u71BC\u71BD\u71BE\u71BF\u71C0\u71C1"+ + "\u71C2\u71C4\u71C5\u71C6\u71C7\u71C8\u71C9\u71CA"+ + "\u71CB\u71CC\u71CD\u71CF\u71D0\u71D1\u71D2\u71D3"; + + private static final String innerIndex2= + "\u71D6\u71D7\u71D8\u71D9\u71DA\u71DB\u71DC\u71DD"+ + "\u71DE\u71DF\u71E1\u71E2\u71E3\u71E4\u71E6\u71E8"+ + "\u71E9\u71EA\u71EB\u71EC\u71ED\u71EF\u71F0\u71F1"+ + "\u71F2\u71F3\u71F4\u71F5\u71F6\u71F7\u71F8\u71FA"+ + "\u71FB\u71FC\u71FD\u71FE\u71FF\u7200\u7201\u7202"+ + "\u7203\u7204\u7205\u7207\u7208\u7209\u720A\u720B"+ + "\u720C\u720D\u720E\u720F\u7210\u7211\u7212\u7213"+ + "\u7214\u7215\u7216\u7217\u7218\u7219\u721A\uFFFD"+ + "\u721B\u721C\u721E\u721F\u7220\u7221\u7222\u7223"+ + "\u7224\u7225\u7226\u7227\u7229\u722B\u722D\u722E"+ + "\u722F\u7232\u7233\u7234\u723A\u723C\u723E\u7240"+ + "\u7241\u7242\u7243\u7244\u7245\u7246\u7249\u724A"+ + "\u724B\u724E\u724F\u7250\u7251\u7253\u7254\u7255"+ + "\u7257\u7258\u725A\u725C\u725E\u7260\u7263\u7264"+ + "\u7265\u7268\u726A\u726B\u726C\u726D\u7270\u7271"+ + "\u7273\u7274\u7276\u7277\u7278\u727B\u727C\u727D"+ + "\u7282\u7283\u7285\u7286\u7287\u7288\u7289\u728C"+ + "\u728E\u7290\u7291\u7293\u7294\u7295\u7296\u7297"+ + "\u7298\u7299\u729A\u729B\u729C\u729D\u729E\u72A0"+ + "\u72A1\u72A2\u72A3\u72A4\u72A5\u72A6\u72A7\u72A8"+ + "\u72A9\u72AA\u72AB\u72AE\u72B1\u72B2\u72B3\u72B5"+ + "\u72BA\u72BB\u72BC\u72BD\u72BE\u72BF\u72C0\u72C5"+ + "\u72C6\u72C7\u72C9\u72CA\u72CB\u72CC\u72CF\u72D1"+ + "\u72D3\u72D4\u72D5\u72D6\u72D8\u72DA\u72DB\uE4C6"+ + "\uE4C7\uE4C8\uE4C9\uE4CA\uE4CB\uE4CC\uE4CD\uE4CE"+ + "\uE4CF\uE4D0\uE4D1\uE4D2\uE4D3\uE4D4\uE4D5\uE4D6"+ + "\uE4D7\uE4D8\uE4D9\uE4DA\uE4DB\uE4DC\uE4DD\uE4DE"+ + "\uE4DF\uE4E0\uE4E1\uE4E2\uE4E3\uE4E4\uE4E5\uE4E6"+ + "\uE4E7\uE4E8\uE4E9\uE4EA\uE4EB\uE4EC\uE4ED\uE4EE"+ + "\uE4EF\uE4F0\uE4F1\uE4F2\uE4F3\uE4F4\uE4F5\uE4F6"+ + "\uE4F7\uE4F8\uE4F9\uE4FA\uE4FB\uE4FC\uE4FD\uE4FE"+ + "\uE4FF\uE500\uE501\uE502\uE503\uE504\uFFFD\uE505"+ + "\uE506\uE507\uE508\uE509\uE50A\uE50B\uE50C\uE50D"+ + "\uE50E\uE50F\uE510\uE511\uE512\uE513\uE514\uE515"+ + "\uE516\uE517\uE518\uE519\uE51A\uE51B\uE51C\uE51D"+ + "\uE51E\uE51F\uE520\uE521\uE522\uE523\uE524\uE525"+ + "\u3000\u3001\u3002\u00B7\u02C9\u02C7\u00A8\u3003"+ + "\u3005\u2014\uFF5E\u2016\u2026\u2018\u2019\u201C"+ + "\u201D\u3014\u3015\u3008\u3009\u300A\u300B\u300C"+ + "\u300D\u300E\u300F\u3016\u3017\u3010\u3011\u00B1"+ + "\u00D7\u00F7\u2236\u2227\u2228\u2211\u220F\u222A"+ + "\u2229\u2208\u2237\u221A\u22A5\u2225\u2220\u2312"+ + "\u2299\u222B\u222E\u2261\u224C\u2248\u223D\u221D"+ + "\u2260\u226E\u226F\u2264\u2265\u221E\u2235\u2234"+ + "\u2642\u2640\u00B0\u2032\u2033\u2103\uFF04\u00A4"+ + "\uFFE0\uFFE1\u2030\u00A7\u2116\u2606\u2605\u25CB"+ + "\u25CF\u25CE\u25C7\u25C6\u25A1\u25A0\u25B3\u25B2"+ + "\u203B\u2192\u2190\u2191\u2193\u3013\uE526\uE527"+ + "\uE528\uE529\uE52A\uE52B\uE52C\uE52D\uE52E\uE52F"+ + "\uE530\uE531\uE532\uE533\uE534\uE535\uE536\uE537"+ + "\uE538\uE539\uE53A\uE53B\uE53C\uE53D\uE53E\uE53F"+ + "\uE540\uE541\uE542\uE543\uE544\uE545\uE546\uE547"+ + "\uE548\uE549\uE54A\uE54B\uE54C\uE54D\uE54E\uE54F"+ + "\uE550\uE551\uE552\uE553\uE554\uE555\uE556\uE557"+ + "\uE558\uE559\uE55A\uE55B\uE55C\uE55D\uE55E\uE55F"+ + "\uE560\uE561\uE562\uE563\uE564\uFFFD\uE565\uE566"+ + "\uE567\uE568\uE569\uE56A\uE56B\uE56C\uE56D\uE56E"+ + "\uE56F\uE570\uE571\uE572\uE573\uE574\uE575\uE576"+ + "\uE577\uE578\uE579\uE57A\uE57B\uE57C\uE57D\uE57E"+ + "\uE57F\uE580\uE581\uE582\uE583\uE584\uE585\u2170"+ + "\u2171\u2172\u2173\u2174\u2175\u2176\u2177\u2178"+ + "\u2179\uE766\uE767\uE768\uE769\uE76A\uE76B\u2488"+ + "\u2489\u248A\u248B\u248C\u248D\u248E\u248F\u2490"+ + "\u2491\u2492\u2493\u2494\u2495\u2496\u2497\u2498"+ + "\u2499\u249A\u249B\u2474\u2475\u2476\u2477\u2478"+ + "\u2479\u247A\u247B\u247C\u247D\u247E\u247F\u2480"+ + "\u2481\u2482\u2483\u2484\u2485\u2486\u2487\u2460"+ + "\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468"+ + "\u2469\u20AC\uE76D\u3220\u3221\u3222\u3223\u3224"+ + "\u3225\u3226\u3227\u3228\u3229\uE76E\uE76F\u2160"+ + "\u2161\u2162\u2163\u2164\u2165\u2166\u2167\u2168"+ + "\u2169\u216A\u216B\uE770\uE771\uE586\uE587\uE588"+ + "\uE589\uE58A\uE58B\uE58C\uE58D\uE58E\uE58F\uE590"+ + "\uE591\uE592\uE593\uE594\uE595\uE596\uE597\uE598"+ + "\uE599\uE59A\uE59B\uE59C\uE59D\uE59E\uE59F\uE5A0"+ + "\uE5A1\uE5A2\uE5A3\uE5A4\uE5A5\uE5A6\uE5A7\uE5A8"+ + "\uE5A9\uE5AA\uE5AB\uE5AC\uE5AD\uE5AE\uE5AF\uE5B0"+ + "\uE5B1\uE5B2\uE5B3\uE5B4\uE5B5\uE5B6\uE5B7\uE5B8"+ + "\uE5B9\uE5BA\uE5BB\uE5BC\uE5BD\uE5BE\uE5BF\uE5C0"+ + "\uE5C1\uE5C2\uE5C3\uE5C4\uFFFD\uE5C5\uE5C6\uE5C7"+ + "\uE5C8\uE5C9\uE5CA\uE5CB\uE5CC\uE5CD\uE5CE\uE5CF"+ + "\uE5D0\uE5D1\uE5D2\uE5D3\uE5D4\uE5D5\uE5D6\uE5D7"+ + "\uE5D8\uE5D9\uE5DA\uE5DB\uE5DC\uE5DD\uE5DE\uE5DF"+ + "\uE5E0\uE5E1\uE5E2\uE5E3\uE5E4\uE5E5\uFF01\uFF02"+ + "\uFF03\uFFE5\uFF05\uFF06\uFF07\uFF08\uFF09\uFF0A"+ + "\uFF0B\uFF0C\uFF0D\uFF0E\uFF0F\uFF10\uFF11\uFF12"+ + "\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF1A"+ + "\uFF1B\uFF1C\uFF1D\uFF1E\uFF1F\uFF20\uFF21\uFF22"+ + "\uFF23\uFF24\uFF25\uFF26\uFF27\uFF28\uFF29\uFF2A"+ + "\uFF2B\uFF2C\uFF2D\uFF2E\uFF2F\uFF30\uFF31\uFF32"+ + "\uFF33\uFF34\uFF35\uFF36\uFF37\uFF38\uFF39\uFF3A"+ + "\uFF3B\uFF3C\uFF3D\uFF3E\uFF3F\uFF40\uFF41\uFF42"+ + "\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48\uFF49\uFF4A"+ + "\uFF4B\uFF4C\uFF4D\uFF4E\uFF4F\uFF50\uFF51\uFF52"+ + "\uFF53\uFF54\uFF55\uFF56\uFF57\uFF58\uFF59\uFF5A"+ + "\uFF5B\uFF5C\uFF5D\uFFE3\uE5E6\uE5E7\uE5E8\uE5E9"+ + "\uE5EA\uE5EB\uE5EC\uE5ED\uE5EE\uE5EF\uE5F0\uE5F1"+ + "\uE5F2\uE5F3\uE5F4\uE5F5\uE5F6\uE5F7\uE5F8\uE5F9"+ + "\uE5FA\uE5FB\uE5FC\uE5FD\uE5FE\uE5FF\uE600\uE601"+ + "\uE602\uE603\uE604\uE605\uE606\uE607\uE608\uE609"+ + "\uE60A\uE60B\uE60C\uE60D\uE60E\uE60F\uE610\uE611"+ + "\uE612\uE613\uE614\uE615\uE616\uE617\uE618\uE619"+ + "\uE61A\uE61B\uE61C\uE61D\uE61E\uE61F\uE620\uE621"+ + "\uE622\uE623\uE624\uFFFD\uE625\uE626\uE627\uE628"+ + "\uE629\uE62A\uE62B\uE62C\uE62D\uE62E\uE62F\uE630"+ + "\uE631\uE632\uE633\uE634\uE635\uE636\uE637\uE638"+ + "\uE639\uE63A\uE63B\uE63C\uE63D\uE63E\uE63F\uE640"+ + "\uE641\uE642\uE643\uE644\uE645\u3041\u3042\u3043"+ + "\u3044\u3045\u3046\u3047\u3048\u3049\u304A\u304B"+ + "\u304C\u304D\u304E\u304F\u3050\u3051\u3052\u3053"+ + "\u3054\u3055\u3056\u3057\u3058\u3059\u305A\u305B"+ + "\u305C\u305D\u305E\u305F\u3060\u3061\u3062\u3063"+ + "\u3064\u3065\u3066\u3067\u3068\u3069\u306A\u306B"+ + "\u306C\u306D\u306E\u306F\u3070\u3071\u3072\u3073"+ + "\u3074\u3075\u3076\u3077\u3078\u3079\u307A\u307B"+ + "\u307C\u307D\u307E\u307F\u3080\u3081\u3082\u3083"+ + "\u3084\u3085\u3086\u3087\u3088\u3089\u308A\u308B"+ + "\u308C\u308D\u308E\u308F\u3090\u3091\u3092\u3093"+ + "\uE772\uE773\uE774\uE775\uE776\uE777\uE778\uE779"+ + "\uE77A\uE77B\uE77C\uE646\uE647\uE648\uE649\uE64A"+ + "\uE64B\uE64C\uE64D\uE64E\uE64F\uE650\uE651\uE652"+ + "\uE653\uE654\uE655\uE656\uE657\uE658\uE659\uE65A"+ + "\uE65B\uE65C\uE65D\uE65E\uE65F\uE660\uE661\uE662"+ + "\uE663\uE664\uE665\uE666\uE667\uE668\uE669\uE66A"+ + "\uE66B\uE66C\uE66D\uE66E\uE66F\uE670\uE671\uE672"+ + "\uE673\uE674\uE675\uE676\uE677\uE678\uE679\uE67A"+ + "\uE67B\uE67C\uE67D\uE67E\uE67F\uE680\uE681\uE682"+ + "\uE683\uE684\uFFFD\uE685\uE686\uE687\uE688\uE689"+ + "\uE68A\uE68B\uE68C\uE68D\uE68E\uE68F\uE690\uE691"+ + "\uE692\uE693\uE694\uE695\uE696\uE697\uE698\uE699"+ + "\uE69A\uE69B\uE69C\uE69D\uE69E\uE69F\uE6A0\uE6A1"+ + "\uE6A2\uE6A3\uE6A4\uE6A5\u30A1\u30A2\u30A3\u30A4"+ + "\u30A5\u30A6\u30A7\u30A8\u30A9\u30AA\u30AB\u30AC"+ + "\u30AD\u30AE\u30AF\u30B0\u30B1\u30B2\u30B3\u30B4"+ + "\u30B5\u30B6\u30B7\u30B8\u30B9\u30BA\u30BB\u30BC"+ + "\u30BD\u30BE\u30BF\u30C0\u30C1\u30C2\u30C3\u30C4"+ + "\u30C5\u30C6\u30C7\u30C8\u30C9\u30CA\u30CB\u30CC"+ + "\u30CD\u30CE\u30CF\u30D0\u30D1\u30D2\u30D3\u30D4"+ + "\u30D5\u30D6\u30D7\u30D8\u30D9\u30DA\u30DB\u30DC"+ + "\u30DD\u30DE\u30DF\u30E0\u30E1\u30E2\u30E3\u30E4"+ + "\u30E5\u30E6\u30E7\u30E8\u30E9\u30EA\u30EB\u30EC"+ + "\u30ED\u30EE\u30EF\u30F0\u30F1\u30F2\u30F3\u30F4"+ + "\u30F5\u30F6\uE77D\uE77E\uE77F\uE780\uE781\uE782"+ + "\uE783\uE784\uE6A6\uE6A7\uE6A8\uE6A9\uE6AA\uE6AB"+ + "\uE6AC\uE6AD\uE6AE\uE6AF\uE6B0\uE6B1\uE6B2\uE6B3"+ + "\uE6B4\uE6B5\uE6B6\uE6B7\uE6B8\uE6B9\uE6BA\uE6BB"+ + "\uE6BC\uE6BD\uE6BE\uE6BF\uE6C0\uE6C1\uE6C2\uE6C3"+ + "\uE6C4\uE6C5\uE6C6\uE6C7\uE6C8\uE6C9\uE6CA\uE6CB"+ + "\uE6CC\uE6CD\uE6CE\uE6CF\uE6D0\uE6D1\uE6D2\uE6D3"+ + "\uE6D4\uE6D5\uE6D6\uE6D7\uE6D8\uE6D9\uE6DA\uE6DB"+ + "\uE6DC\uE6DD\uE6DE\uE6DF\uE6E0\uE6E1\uE6E2\uE6E3"+ + "\uE6E4\uFFFD\uE6E5\uE6E6\uE6E7\uE6E8\uE6E9\uE6EA"+ + "\uE6EB\uE6EC\uE6ED\uE6EE\uE6EF\uE6F0\uE6F1\uE6F2"+ + "\uE6F3\uE6F4\uE6F5\uE6F6\uE6F7\uE6F8\uE6F9\uE6FA"+ + "\uE6FB\uE6FC\uE6FD\uE6FE\uE6FF\uE700\uE701\uE702"+ + "\uE703\uE704\uE705\u0391\u0392\u0393\u0394\u0395"+ + "\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D"+ + "\u039E\u039F\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6"+ + "\u03A7\u03A8\u03A9\uE785\uE786\uE787\uE788\uE789"+ + "\uE78A\uE78B\uE78C\u03B1\u03B2\u03B3\u03B4\u03B5"+ + "\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD"+ + "\u03BE\u03BF\u03C0\u03C1\u03C3\u03C4\u03C5\u03C6"+ + (IS_2000 ? "\u03C7\u03C8\u03C9\uE78D\uE78E\uE78F\uE790\uE791"+ + "\uE792\uE793\uFE35\uFE36\uFE39\uFE3A\uFE3F\uFE40"+ + "\uFE3D\uFE3E\uFE41\uFE42\uFE43\uFE44\uE794\uE795"+ + "\uFE3B\uFE3C\uFE37\uFE38\uFE31\uE796\uFE33\uFE34" : + "\u03C7\u03C8\u03C9\uFE10\uFE12\uFE11\uFE13\uFE14"+ + "\uFE15\uFE16\uFE35\uFE36\uFE39\uFE3A\uFE3F\uFE40"+ + "\uFE3D\uFE3E\uFE41\uFE42\uFE43\uFE44\uFE17\uFE18"+ + "\uFE3B\uFE3C\uFE37\uFE38\uFE31\uFE19\uFE33\uFE34")+ + "\uE797\uE798\uE799\uE79A\uE79B\uE79C\uE79D\uE79E"+ + "\uE79F\uE706\uE707\uE708\uE709\uE70A\uE70B\uE70C"+ + "\uE70D\uE70E\uE70F\uE710\uE711\uE712\uE713\uE714"+ + "\uE715\uE716\uE717\uE718\uE719\uE71A\uE71B\uE71C"+ + "\uE71D\uE71E\uE71F\uE720\uE721\uE722\uE723\uE724"+ + "\uE725\uE726\uE727\uE728\uE729\uE72A\uE72B\uE72C"+ + "\uE72D\uE72E\uE72F\uE730\uE731\uE732\uE733\uE734"+ + "\uE735\uE736\uE737\uE738\uE739\uE73A\uE73B\uE73C"+ + "\uE73D\uE73E\uE73F\uE740\uE741\uE742\uE743\uE744"+ + "\uFFFD\uE745\uE746\uE747\uE748\uE749\uE74A\uE74B"+ + "\uE74C\uE74D\uE74E\uE74F\uE750\uE751\uE752\uE753"+ + "\uE754\uE755\uE756\uE757\uE758\uE759\uE75A\uE75B"+ + "\uE75C\uE75D\uE75E\uE75F\uE760\uE761\uE762\uE763"+ + "\uE764\uE765\u0410\u0411\u0412\u0413\u0414\u0415"+ + "\u0401\u0416\u0417\u0418\u0419\u041A\u041B\u041C"+ + "\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424"+ + "\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C"+ + "\u042D\u042E\u042F\uE7A0\uE7A1\uE7A2\uE7A3\uE7A4"+ + "\uE7A5\uE7A6\uE7A7\uE7A8\uE7A9\uE7AA\uE7AB\uE7AC"+ + "\uE7AD\uE7AE\u0430\u0431\u0432\u0433\u0434\u0435"+ + "\u0451\u0436\u0437\u0438\u0439\u043A\u043B\u043C"+ + "\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444"+ + "\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C"+ + "\u044D\u044E\u044F\uE7AF\uE7B0\uE7B1\uE7B2\uE7B3"+ + "\uE7B4\uE7B5\uE7B6\uE7B7\uE7B8\uE7B9\uE7BA\uE7BB"+ + "\u02CA\u02CB\u02D9\u2013\u2015\u2025\u2035\u2105"+ + "\u2109\u2196\u2197\u2198\u2199\u2215\u221F\u2223"+ + "\u2252\u2266\u2267\u22BF\u2550\u2551\u2552\u2553"+ + "\u2554\u2555\u2556\u2557\u2558\u2559\u255A\u255B"+ + "\u255C\u255D\u255E\u255F\u2560\u2561\u2562\u2563"+ + "\u2564\u2565\u2566\u2567\u2568\u2569\u256A\u256B"+ + "\u256C\u256D\u256E\u256F\u2570\u2571\u2572\u2573"+ + "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\uFFFD"+ + "\u2588\u2589\u258A\u258B\u258C\u258D\u258E\u258F"+ + "\u2593\u2594\u2595\u25BC\u25BD\u25E2\u25E3\u25E4"+ + "\u25E5\u2609\u2295\u3012\u301D\u301E\uE7BC\uE7BD"+ + "\uE7BE\uE7BF\uE7C0\uE7C1\uE7C2\uE7C3\uE7C4\uE7C5"+ + "\uE7C6\u0101\u00E1\u01CE\u00E0\u0113\u00E9\u011B"+ + "\u00E8\u012B\u00ED\u01D0\u00EC\u014D\u00F3\u01D2"+ + "\u00F2\u016B\u00FA\u01D4\u00F9\u01D6\u01D8\u01DA"+ + (IS_2000 ? "\u01DC\u00FC\u00EA\u0251\uE7C7\u0144\u0148\u01F9" : + "\u01DC\u00FC\u00EA\u0251\u1E3F\u0144\u0148\u01F9")+ + "\u0261\uE7C9\uE7CA\uE7CB\uE7CC\u3105\u3106\u3107"+ + "\u3108\u3109\u310A\u310B\u310C\u310D\u310E\u310F"+ + "\u3110\u3111\u3112\u3113\u3114\u3115\u3116\u3117"+ + "\u3118\u3119\u311A\u311B\u311C\u311D\u311E\u311F"+ + "\u3120\u3121\u3122\u3123\u3124\u3125\u3126\u3127"+ + "\u3128\u3129\uE7CD\uE7CE\uE7CF\uE7D0\uE7D1\uE7D2"+ + "\uE7D3\uE7D4\uE7D5\uE7D6\uE7D7\uE7D8\uE7D9\uE7DA"+ + "\uE7DB\uE7DC\uE7DD\uE7DE\uE7DF\uE7E0\uE7E1\u3021"+ + "\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029"+ + "\u32A3\u338E\u338F\u339C\u339D\u339E\u33A1\u33C4"+ + "\u33CE\u33D1\u33D2\u33D5\uFE30\uFFE2\uFFE4\uE7E2"+ + "\u2121\u3231\uE7E3\u2010\uE7E4\uE7E5\uE7E6\u30FC"+ + "\u309B\u309C\u30FD\u30FE\u3006\u309D\u309E\uFE49"+ + "\uFE4A\uFE4B\uFE4C\uFE4D\uFE4E\uFE4F\uFE50\uFE51"+ + "\uFE52\uFE54\uFE55\uFE56\uFE57\uFE59\uFE5A\uFE5B"+ + "\uFE5C\uFE5D\uFE5E\uFE5F\uFE60\uFE61\uFFFD\uFE62"+ + "\uFE63\uFE64\uFE65\uFE66\uFE68\uFE69\uFE6A\uFE6B"+ + "\u303E\u2FF0\u2FF1\u2FF2\u2FF3\u2FF4\u2FF5\u2FF6"+ + "\u2FF7\u2FF8\u2FF9\u2FFA\u2FFB\u3007\uE7F4\uE7F5"+ + "\uE7F6\uE7F7\uE7F8\uE7F9\uE7FA\uE7FB\uE7FC\uE7FD"+ + "\uE7FE\uE7FF\uE800\u2500\u2501\u2502\u2503\u2504"+ + "\u2505\u2506\u2507\u2508\u2509\u250A\u250B\u250C"+ + "\u250D\u250E\u250F\u2510\u2511\u2512\u2513\u2514"+ + "\u2515\u2516\u2517\u2518\u2519\u251A\u251B\u251C"+ + "\u251D\u251E\u251F\u2520\u2521\u2522\u2523\u2524"+ + "\u2525\u2526\u2527\u2528\u2529\u252A\u252B\u252C"+ + "\u252D\u252E\u252F\u2530\u2531\u2532\u2533\u2534"+ + "\u2535\u2536\u2537\u2538\u2539\u253A\u253B\u253C"+ + "\u253D\u253E\u253F\u2540\u2541\u2542\u2543\u2544"+ + "\u2545\u2546\u2547\u2548\u2549\u254A\u254B\uE801"+ + "\uE802\uE803\uE804\uE805\uE806\uE807\uE808\uE809"+ + "\uE80A\uE80B\uE80C\uE80D\uE80E\uE80F\u72DC\u72DD"+ + "\u72DF\u72E2\u72E3\u72E4\u72E5\u72E6\u72E7\u72EA"+ + "\u72EB\u72F5\u72F6\u72F9\u72FD\u72FE\u72FF\u7300"+ + "\u7302\u7304\u7305\u7306\u7307\u7308\u7309\u730B"+ + "\u730C\u730D\u730F\u7310\u7311\u7312\u7314\u7318"+ + "\u7319\u731A\u731F\u7320\u7323\u7324\u7326\u7327"+ + "\u7328\u732D\u732F\u7330\u7332\u7333\u7335\u7336"+ + "\u733A\u733B\u733C\u733D\u7340\u7341\u7342\u7343"+ + "\u7344\u7345\u7346\u7347\u7348\uFFFD\u7349\u734A"+ + "\u734B\u734C\u734E\u734F\u7351\u7353\u7354\u7355"+ + "\u7356\u7358\u7359\u735A\u735B\u735C\u735D\u735E"+ + "\u735F\u7361\u7362\u7363\u7364\u7365\u7366\u7367"+ + "\u7368\u7369\u736A\u736B\u736E\u7370\u7371\uE000"+ + "\uE001\uE002\uE003\uE004\uE005\uE006\uE007\uE008"+ + "\uE009\uE00A\uE00B\uE00C\uE00D\uE00E\uE00F\uE010"+ + "\uE011\uE012\uE013\uE014\uE015\uE016\uE017\uE018"+ + "\uE019\uE01A\uE01B\uE01C\uE01D\uE01E\uE01F\uE020"+ + "\uE021\uE022\uE023\uE024\uE025\uE026\uE027\uE028"+ + "\uE029\uE02A\uE02B\uE02C\uE02D\uE02E\uE02F\uE030"+ + "\uE031\uE032\uE033\uE034\uE035\uE036\uE037\uE038"+ + "\uE039\uE03A\uE03B\uE03C\uE03D\uE03E\uE03F\uE040"+ + "\uE041\uE042\uE043\uE044\uE045\uE046\uE047\uE048"+ + "\uE049\uE04A\uE04B\uE04C\uE04D\uE04E\uE04F\uE050"+ + "\uE051\uE052\uE053\uE054\uE055\uE056\uE057\uE058"+ + "\uE059\uE05A\uE05B\uE05C\uE05D\u7372\u7373\u7374"+ + "\u7375\u7376\u7377\u7378\u7379\u737A\u737B\u737C"+ + "\u737D\u737F\u7380\u7381\u7382\u7383\u7385\u7386"+ + "\u7388\u738A\u738C\u738D\u738F\u7390\u7392\u7393"+ + "\u7394\u7395\u7397\u7398\u7399\u739A\u739C\u739D"+ + "\u739E\u73A0\u73A1\u73A3\u73A4\u73A5\u73A6\u73A7"+ + "\u73A8\u73AA\u73AC\u73AD\u73B1\u73B4\u73B5\u73B6"+ + "\u73B8\u73B9\u73BC\u73BD\u73BE\u73BF\u73C1\u73C3"+ + "\u73C4\u73C5\u73C6\u73C7\uFFFD\u73CB\u73CC\u73CE"+ + "\u73D2\u73D3\u73D4\u73D5\u73D6\u73D7\u73D8\u73DA"+ + "\u73DB\u73DC\u73DD\u73DF\u73E1\u73E2\u73E3\u73E4"+ + "\u73E6\u73E8\u73EA\u73EB\u73EC\u73EE\u73EF\u73F0"+ + "\u73F1\u73F3\u73F4\u73F5\u73F6\u73F7\uE05E\uE05F"+ + "\uE060\uE061\uE062\uE063\uE064\uE065\uE066\uE067"+ + "\uE068\uE069\uE06A\uE06B\uE06C\uE06D\uE06E\uE06F"+ + "\uE070\uE071\uE072\uE073\uE074\uE075\uE076\uE077"+ + "\uE078\uE079\uE07A\uE07B\uE07C\uE07D\uE07E\uE07F"+ + "\uE080\uE081\uE082\uE083\uE084\uE085\uE086\uE087"+ + "\uE088\uE089\uE08A\uE08B\uE08C\uE08D\uE08E\uE08F"+ + "\uE090\uE091\uE092\uE093\uE094\uE095\uE096\uE097"+ + "\uE098\uE099\uE09A\uE09B\uE09C\uE09D\uE09E\uE09F"+ + "\uE0A0\uE0A1\uE0A2\uE0A3\uE0A4\uE0A5\uE0A6\uE0A7"+ + "\uE0A8\uE0A9\uE0AA\uE0AB\uE0AC\uE0AD\uE0AE\uE0AF"+ + "\uE0B0\uE0B1\uE0B2\uE0B3\uE0B4\uE0B5\uE0B6\uE0B7"+ + "\uE0B8\uE0B9\uE0BA\uE0BB\u73F8\u73F9\u73FA\u73FB"+ + "\u73FC\u73FD\u73FE\u73FF\u7400\u7401\u7402\u7404"+ + "\u7407\u7408\u740B\u740C\u740D\u740E\u7411\u7412"+ + "\u7413\u7414\u7415\u7416\u7417\u7418\u7419\u741C"+ + "\u741D\u741E\u741F\u7420\u7421\u7423\u7424\u7427"+ + "\u7429\u742B\u742D\u742F\u7431\u7432\u7437\u7438"+ + "\u7439\u743A\u743B\u743D\u743E\u743F\u7440\u7442"+ + "\u7443\u7444\u7445\u7446\u7447\u7448\u7449\u744A"+ + "\u744B\u744C\u744D\uFFFD\u744E\u744F\u7450\u7451"+ + "\u7452\u7453\u7454\u7456\u7458\u745D\u7460\u7461"+ + "\u7462\u7463\u7464\u7465\u7466\u7467\u7468\u7469"+ + "\u746A\u746B\u746C\u746E\u746F\u7471\u7472\u7473"+ + "\u7474\u7475\u7478\u7479\u747A\uE0BC\uE0BD\uE0BE"+ + "\uE0BF\uE0C0\uE0C1\uE0C2\uE0C3\uE0C4\uE0C5\uE0C6"+ + "\uE0C7\uE0C8\uE0C9\uE0CA\uE0CB\uE0CC\uE0CD\uE0CE"+ + "\uE0CF\uE0D0\uE0D1\uE0D2\uE0D3\uE0D4\uE0D5\uE0D6"+ + "\uE0D7\uE0D8\uE0D9\uE0DA\uE0DB\uE0DC\uE0DD\uE0DE"+ + "\uE0DF\uE0E0\uE0E1\uE0E2\uE0E3\uE0E4\uE0E5\uE0E6"+ + "\uE0E7\uE0E8\uE0E9\uE0EA\uE0EB\uE0EC\uE0ED\uE0EE"+ + "\uE0EF\uE0F0\uE0F1\uE0F2\uE0F3\uE0F4\uE0F5\uE0F6"+ + "\uE0F7\uE0F8\uE0F9\uE0FA\uE0FB\uE0FC\uE0FD\uE0FE"+ + "\uE0FF\uE100\uE101\uE102\uE103\uE104\uE105\uE106"+ + "\uE107\uE108\uE109\uE10A\uE10B\uE10C\uE10D\uE10E"+ + "\uE10F\uE110\uE111\uE112\uE113\uE114\uE115\uE116"+ + "\uE117\uE118\uE119\u747B\u747C\u747D\u747F\u7482"+ + "\u7484\u7485\u7486\u7488\u7489\u748A\u748C\u748D"+ + "\u748F\u7491\u7492\u7493\u7494\u7495\u7496\u7497"+ + "\u7498\u7499\u749A\u749B\u749D\u749F\u74A0\u74A1"+ + "\u74A2\u74A3\u74A4\u74A5\u74A6\u74AA\u74AB\u74AC"+ + "\u74AD\u74AE\u74AF\u74B0\u74B1\u74B2\u74B3\u74B4"+ + "\u74B5\u74B6\u74B7\u74B8\u74B9\u74BB\u74BC\u74BD"+ + "\u74BE\u74BF\u74C0\u74C1\u74C2\u74C3\u74C4\u74C5"+ + "\u74C6\u74C7\uFFFD\u74C8\u74C9\u74CA\u74CB\u74CC"+ + "\u74CD\u74CE\u74CF\u74D0\u74D1\u74D3\u74D4\u74D5"+ + "\u74D6\u74D7\u74D8\u74D9\u74DA\u74DB\u74DD\u74DF"+ + "\u74E1\u74E5\u74E7\u74E8\u74E9\u74EA\u74EB\u74EC"+ + "\u74ED\u74F0\u74F1\u74F2\uE11A\uE11B\uE11C\uE11D"+ + "\uE11E\uE11F\uE120\uE121\uE122\uE123\uE124\uE125"+ + "\uE126\uE127\uE128\uE129\uE12A\uE12B\uE12C\uE12D"+ + "\uE12E\uE12F\uE130\uE131\uE132\uE133\uE134\uE135"+ + "\uE136\uE137\uE138\uE139\uE13A\uE13B\uE13C\uE13D"+ + "\uE13E\uE13F\uE140\uE141\uE142\uE143\uE144\uE145"+ + "\uE146\uE147\uE148\uE149\uE14A\uE14B\uE14C\uE14D"+ + "\uE14E\uE14F\uE150\uE151\uE152\uE153\uE154\uE155"+ + "\uE156\uE157\uE158\uE159\uE15A\uE15B\uE15C\uE15D"+ + "\uE15E\uE15F\uE160\uE161\uE162\uE163\uE164\uE165"+ + "\uE166\uE167\uE168\uE169\uE16A\uE16B\uE16C\uE16D"+ + "\uE16E\uE16F\uE170\uE171\uE172\uE173\uE174\uE175"+ + "\uE176\uE177\u74F3\u74F5\u74F8\u74F9\u74FA\u74FB"+ + "\u74FC\u74FD\u74FE\u7500\u7501\u7502\u7503\u7505"+ + "\u7506\u7507\u7508\u7509\u750A\u750B\u750C\u750E"+ + "\u7510\u7512\u7514\u7515\u7516\u7517\u751B\u751D"+ + "\u751E\u7520\u7521\u7522\u7523\u7524\u7526\u7527"+ + "\u752A\u752E\u7534\u7536\u7539\u753C\u753D\u753F"+ + "\u7541\u7542\u7543\u7544\u7546\u7547\u7549\u754A"+ + "\u754D\u7550\u7551\u7552\u7553\u7555\u7556\u7557"+ + "\u7558\uFFFD\u755D\u755E\u755F\u7560\u7561\u7562"+ + "\u7563\u7564\u7567\u7568\u7569\u756B\u756C\u756D"+ + "\u756E\u756F\u7570\u7571\u7573\u7575\u7576\u7577"+ + "\u757A\u757B\u757C\u757D\u757E\u7580\u7581\u7582"+ + "\u7584\u7585\u7587\uE178\uE179\uE17A\uE17B\uE17C"+ + "\uE17D\uE17E\uE17F\uE180\uE181\uE182\uE183\uE184"+ + "\uE185\uE186\uE187\uE188\uE189\uE18A\uE18B\uE18C"+ + "\uE18D\uE18E\uE18F\uE190\uE191\uE192\uE193\uE194"+ + "\uE195\uE196\uE197\uE198\uE199\uE19A\uE19B\uE19C"+ + "\uE19D\uE19E\uE19F\uE1A0\uE1A1\uE1A2\uE1A3\uE1A4"+ + "\uE1A5\uE1A6\uE1A7\uE1A8\uE1A9\uE1AA\uE1AB\uE1AC"+ + "\uE1AD\uE1AE\uE1AF\uE1B0\uE1B1\uE1B2\uE1B3\uE1B4"+ + "\uE1B5\uE1B6\uE1B7\uE1B8\uE1B9\uE1BA\uE1BB\uE1BC"+ + "\uE1BD\uE1BE\uE1BF\uE1C0\uE1C1\uE1C2\uE1C3\uE1C4"+ + "\uE1C5\uE1C6\uE1C7\uE1C8\uE1C9\uE1CA\uE1CB\uE1CC"+ + "\uE1CD\uE1CE\uE1CF\uE1D0\uE1D1\uE1D2\uE1D3\uE1D4"+ + "\uE1D5\u7588\u7589\u758A\u758C\u758D\u758E\u7590"+ + "\u7593\u7595\u7598\u759B\u759C\u759E\u75A2\u75A6"+ + "\u75A7\u75A8\u75A9\u75AA\u75AD\u75B6\u75B7\u75BA"+ + "\u75BB\u75BF\u75C0\u75C1\u75C6\u75CB\u75CC\u75CE"+ + "\u75CF\u75D0\u75D1\u75D3\u75D7\u75D9\u75DA\u75DC"+ + "\u75DD\u75DF\u75E0\u75E1\u75E5\u75E9\u75EC\u75ED"+ + "\u75EE\u75EF\u75F2\u75F3\u75F5\u75F6\u75F7\u75F8"+ + "\u75FA\u75FB\u75FD\u75FE\u7602\u7604\u7606\u7607"+ + "\uFFFD\u7608\u7609\u760B\u760D\u760E\u760F\u7611"+ + "\u7612\u7613\u7614\u7616\u761A\u761C\u761D\u761E"+ + "\u7621\u7623\u7627\u7628\u762C\u762E\u762F\u7631"+ + "\u7632\u7636\u7637\u7639\u763A\u763B\u763D\u7641"+ + "\u7642\u7644\uE1D6\uE1D7\uE1D8\uE1D9\uE1DA\uE1DB"+ + "\uE1DC\uE1DD\uE1DE\uE1DF\uE1E0\uE1E1\uE1E2\uE1E3"+ + "\uE1E4\uE1E5\uE1E6\uE1E7\uE1E8\uE1E9\uE1EA\uE1EB"+ + "\uE1EC\uE1ED\uE1EE\uE1EF\uE1F0\uE1F1\uE1F2\uE1F3"+ + "\uE1F4\uE1F5\uE1F6\uE1F7\uE1F8\uE1F9\uE1FA\uE1FB"+ + "\uE1FC\uE1FD\uE1FE\uE1FF\uE200\uE201\uE202\uE203"+ + "\uE204\uE205\uE206\uE207\uE208\uE209\uE20A\uE20B"+ + "\uE20C\uE20D\uE20E\uE20F\uE210\uE211\uE212\uE213"+ + "\uE214\uE215\uE216\uE217\uE218\uE219\uE21A\uE21B"+ + "\uE21C\uE21D\uE21E\uE21F\uE220\uE221\uE222\uE223"+ + "\uE224\uE225\uE226\uE227\uE228\uE229\uE22A\uE22B"+ + "\uE22C\uE22D\uE22E\uE22F\uE230\uE231\uE232\uE233"; + + private static final String innerIndex3= + "\u7645\u7646\u7647\u7648\u7649\u764A\u764B\u764E"+ + "\u764F\u7650\u7651\u7652\u7653\u7655\u7657\u7658"+ + "\u7659\u765A\u765B\u765D\u765F\u7660\u7661\u7662"+ + "\u7664\u7665\u7666\u7667\u7668\u7669\u766A\u766C"+ + "\u766D\u766E\u7670\u7671\u7672\u7673\u7674\u7675"+ + "\u7676\u7677\u7679\u767A\u767C\u767F\u7680\u7681"+ + "\u7683\u7685\u7689\u768A\u768C\u768D\u768F\u7690"+ + "\u7692\u7694\u7695\u7697\u7698\u769A\u769B\uFFFD"+ + "\u769C\u769D\u769E\u769F\u76A0\u76A1\u76A2\u76A3"+ + "\u76A5\u76A6\u76A7\u76A8\u76A9\u76AA\u76AB\u76AC"+ + "\u76AD\u76AF\u76B0\u76B3\u76B5\u76B6\u76B7\u76B8"+ + "\u76B9\u76BA\u76BB\u76BC\u76BD\u76BE\u76C0\u76C1"+ + "\u76C3\u554A\u963F\u57C3\u6328\u54CE\u5509\u54C0"+ + "\u7691\u764C\u853C\u77EE\u827E\u788D\u7231\u9698"+ + "\u978D\u6C28\u5B89\u4FFA\u6309\u6697\u5CB8\u80FA"+ + "\u6848\u80AE\u6602\u76CE\u51F9\u6556\u71AC\u7FF1"+ + "\u8884\u50B2\u5965\u61CA\u6FB3\u82AD\u634C\u6252"+ + "\u53ED\u5427\u7B06\u516B\u75A4\u5DF4\u62D4\u8DCB"+ + "\u9776\u628A\u8019\u575D\u9738\u7F62\u7238\u767D"+ + "\u67CF\u767E\u6446\u4F70\u8D25\u62DC\u7A17\u6591"+ + "\u73ED\u642C\u6273\u822C\u9881\u677F\u7248\u626E"+ + "\u62CC\u4F34\u74E3\u534A\u529E\u7ECA\u90A6\u5E2E"+ + "\u6886\u699C\u8180\u7ED1\u68D2\u78C5\u868C\u9551"+ + "\u508D\u8C24\u82DE\u80DE\u5305\u8912\u5265\u76C4"+ + "\u76C7\u76C9\u76CB\u76CC\u76D3\u76D5\u76D9\u76DA"+ + "\u76DC\u76DD\u76DE\u76E0\u76E1\u76E2\u76E3\u76E4"+ + "\u76E6\u76E7\u76E8\u76E9\u76EA\u76EB\u76EC\u76ED"+ + "\u76F0\u76F3\u76F5\u76F6\u76F7\u76FA\u76FB\u76FD"+ + "\u76FF\u7700\u7702\u7703\u7705\u7706\u770A\u770C"+ + "\u770E\u770F\u7710\u7711\u7712\u7713\u7714\u7715"+ + "\u7716\u7717\u7718\u771B\u771C\u771D\u771E\u7721"+ + "\u7723\u7724\u7725\u7727\u772A\u772B\uFFFD\u772C"+ + "\u772E\u7730\u7731\u7732\u7733\u7734\u7739\u773B"+ + "\u773D\u773E\u773F\u7742\u7744\u7745\u7746\u7748"+ + "\u7749\u774A\u774B\u774C\u774D\u774E\u774F\u7752"+ + "\u7753\u7754\u7755\u7756\u7757\u7758\u7759\u775C"+ + "\u8584\u96F9\u4FDD\u5821\u9971\u5B9D\u62B1\u62A5"+ + "\u66B4\u8C79\u9C8D\u7206\u676F\u7891\u60B2\u5351"+ + "\u5317\u8F88\u80CC\u8D1D\u94A1\u500D\u72C8\u5907"+ + "\u60EB\u7119\u88AB\u5954\u82EF\u672C\u7B28\u5D29"+ + "\u7EF7\u752D\u6CF5\u8E66\u8FF8\u903C\u9F3B\u6BD4"+ + "\u9119\u7B14\u5F7C\u78A7\u84D6\u853D\u6BD5\u6BD9"+ + "\u6BD6\u5E01\u5E87\u75F9\u95ED\u655D\u5F0A\u5FC5"+ + "\u8F9F\u58C1\u81C2\u907F\u965B\u97AD\u8FB9\u7F16"+ + "\u8D2C\u6241\u4FBF\u53D8\u535E\u8FA8\u8FA9\u8FAB"+ + "\u904D\u6807\u5F6A\u8198\u8868\u9CD6\u618B\u522B"+ + "\u762A\u5F6C\u658C\u6FD2\u6EE8\u5BBE\u6448\u5175"+ + "\u51B0\u67C4\u4E19\u79C9\u997C\u70B3\u775D\u775E"+ + "\u775F\u7760\u7764\u7767\u7769\u776A\u776D\u776E"+ + "\u776F\u7770\u7771\u7772\u7773\u7774\u7775\u7776"+ + "\u7777\u7778\u777A\u777B\u777C\u7781\u7782\u7783"+ + "\u7786\u7787\u7788\u7789\u778A\u778B\u778F\u7790"+ + "\u7793\u7794\u7795\u7796\u7797\u7798\u7799\u779A"+ + "\u779B\u779C\u779D\u779E\u77A1\u77A3\u77A4\u77A6"+ + "\u77A8\u77AB\u77AD\u77AE\u77AF\u77B1\u77B2\u77B4"+ + "\u77B6\u77B7\u77B8\u77B9\u77BA\uFFFD\u77BC\u77BE"+ + "\u77C0\u77C1\u77C2\u77C3\u77C4\u77C5\u77C6\u77C7"+ + "\u77C8\u77C9\u77CA\u77CB\u77CC\u77CE\u77CF\u77D0"+ + "\u77D1\u77D2\u77D3\u77D4\u77D5\u77D6\u77D8\u77D9"+ + "\u77DA\u77DD\u77DE\u77DF\u77E0\u77E1\u77E4\u75C5"+ + "\u5E76\u73BB\u83E0\u64AD\u62E8\u94B5\u6CE2\u535A"+ + "\u52C3\u640F\u94C2\u7B94\u4F2F\u5E1B\u8236\u8116"+ + "\u818A\u6E24\u6CCA\u9A73\u6355\u535C\u54FA\u8865"+ + "\u57E0\u4E0D\u5E03\u6B65\u7C3F\u90E8\u6016\u64E6"+ + "\u731C\u88C1\u6750\u624D\u8D22\u776C\u8E29\u91C7"+ + "\u5F69\u83DC\u8521\u9910\u53C2\u8695\u6B8B\u60ED"+ + "\u60E8\u707F\u82CD\u8231\u4ED3\u6CA7\u85CF\u64CD"+ + "\u7CD9\u69FD\u66F9\u8349\u5395\u7B56\u4FA7\u518C"+ + "\u6D4B\u5C42\u8E6D\u63D2\u53C9\u832C\u8336\u67E5"+ + "\u78B4\u643D\u5BDF\u5C94\u5DEE\u8BE7\u62C6\u67F4"+ + "\u8C7A\u6400\u63BA\u8749\u998B\u8C17\u7F20\u94F2"+ + "\u4EA7\u9610\u98A4\u660C\u7316\u77E6\u77E8\u77EA"+ + "\u77EF\u77F0\u77F1\u77F2\u77F4\u77F5\u77F7\u77F9"+ + "\u77FA\u77FB\u77FC\u7803\u7804\u7805\u7806\u7807"+ + "\u7808\u780A\u780B\u780E\u780F\u7810\u7813\u7815"+ + "\u7819\u781B\u781E\u7820\u7821\u7822\u7824\u7828"+ + "\u782A\u782B\u782E\u782F\u7831\u7832\u7833\u7835"+ + "\u7836\u783D\u783F\u7841\u7842\u7843\u7844\u7846"+ + "\u7848\u7849\u784A\u784B\u784D\u784F\u7851\u7853"+ + "\u7854\u7858\u7859\u785A\uFFFD\u785B\u785C\u785E"+ + "\u785F\u7860\u7861\u7862\u7863\u7864\u7865\u7866"+ + "\u7867\u7868\u7869\u786F\u7870\u7871\u7872\u7873"+ + "\u7874\u7875\u7876\u7878\u7879\u787A\u787B\u787D"+ + "\u787E\u787F\u7880\u7881\u7882\u7883\u573A\u5C1D"+ + "\u5E38\u957F\u507F\u80A0\u5382\u655E\u7545\u5531"+ + "\u5021\u8D85\u6284\u949E\u671D\u5632\u6F6E\u5DE2"+ + "\u5435\u7092\u8F66\u626F\u64A4\u63A3\u5F7B\u6F88"+ + "\u90F4\u81E3\u8FB0\u5C18\u6668\u5FF1\u6C89\u9648"+ + "\u8D81\u886C\u6491\u79F0\u57CE\u6A59\u6210\u5448"+ + "\u4E58\u7A0B\u60E9\u6F84\u8BDA\u627F\u901E\u9A8B"+ + "\u79E4\u5403\u75F4\u6301\u5319\u6C60\u8FDF\u5F1B"+ + "\u9A70\u803B\u9F7F\u4F88\u5C3A\u8D64\u7FC5\u65A5"+ + "\u70BD\u5145\u51B2\u866B\u5D07\u5BA0\u62BD\u916C"+ + "\u7574\u8E0C\u7A20\u6101\u7B79\u4EC7\u7EF8\u7785"+ + "\u4E11\u81ED\u521D\u51FA\u6A71\u53A8\u8E87\u9504"+ + "\u96CF\u6EC1\u9664\u695A\u7884\u7885\u7886\u7888"+ + "\u788A\u788B\u788F\u7890\u7892\u7894\u7895\u7896"+ + "\u7899\u789D\u789E\u78A0\u78A2\u78A4\u78A6\u78A8"+ + "\u78A9\u78AA\u78AB\u78AC\u78AD\u78AE\u78AF\u78B5"+ + "\u78B6\u78B7\u78B8\u78BA\u78BB\u78BC\u78BD\u78BF"+ + "\u78C0\u78C2\u78C3\u78C4\u78C6\u78C7\u78C8\u78CC"+ + "\u78CD\u78CE\u78CF\u78D1\u78D2\u78D3\u78D6\u78D7"+ + "\u78D8\u78DA\u78DB\u78DC\u78DD\u78DE\u78DF\u78E0"+ + "\u78E1\u78E2\u78E3\uFFFD\u78E4\u78E5\u78E6\u78E7"+ + "\u78E9\u78EA\u78EB\u78ED\u78EE\u78EF\u78F0\u78F1"+ + "\u78F3\u78F5\u78F6\u78F8\u78F9\u78FB\u78FC\u78FD"+ + "\u78FE\u78FF\u7900\u7902\u7903\u7904\u7906\u7907"+ + "\u7908\u7909\u790A\u790B\u790C\u7840\u50A8\u77D7"+ + "\u6410\u89E6\u5904\u63E3\u5DDD\u7A7F\u693D\u4F20"+ + "\u8239\u5598\u4E32\u75AE\u7A97\u5E62\u5E8A\u95EF"+ + "\u521B\u5439\u708A\u6376\u9524\u5782\u6625\u693F"+ + "\u9187\u5507\u6DF3\u7EAF\u8822\u6233\u7EF0\u75B5"+ + "\u8328\u78C1\u96CC\u8F9E\u6148\u74F7\u8BCD\u6B64"+ + "\u523A\u8D50\u6B21\u806A\u8471\u56F1\u5306\u4ECE"+ + "\u4E1B\u51D1\u7C97\u918B\u7C07\u4FC3\u8E7F\u7BE1"+ + "\u7A9C\u6467\u5D14\u50AC\u8106\u7601\u7CB9\u6DEC"+ + "\u7FE0\u6751\u5B58\u5BF8\u78CB\u64AE\u6413\u63AA"+ + "\u632B\u9519\u642D\u8FBE\u7B54\u7629\u6253\u5927"+ + "\u5446\u6B79\u50A3\u6234\u5E26\u6B86\u4EE3\u8D37"+ + "\u888B\u5F85\u902E\u790D\u790E\u790F\u7910\u7911"+ + "\u7912\u7914\u7915\u7916\u7917\u7918\u7919\u791A"+ + "\u791B\u791C\u791D\u791F\u7920\u7921\u7922\u7923"+ + "\u7925\u7926\u7927\u7928\u7929\u792A\u792B\u792C"+ + "\u792D\u792E\u792F\u7930\u7931\u7932\u7933\u7935"+ + "\u7936\u7937\u7938\u7939\u793D\u793F\u7942\u7943"+ + "\u7944\u7945\u7947\u794A\u794B\u794C\u794D\u794E"+ + "\u794F\u7950\u7951\u7952\u7954\u7955\u7958\u7959"+ + "\u7961\u7963\uFFFD\u7964\u7966\u7969\u796A\u796B"+ + "\u796C\u796E\u7970\u7971\u7972\u7973\u7974\u7975"+ + "\u7976\u7979\u797B\u797C\u797D\u797E\u797F\u7982"+ + "\u7983\u7986\u7987\u7988\u7989\u798B\u798C\u798D"+ + "\u798E\u7990\u7991\u7992\u6020\u803D\u62C5\u4E39"+ + "\u5355\u90F8\u63B8\u80C6\u65E6\u6C2E\u4F46\u60EE"+ + "\u6DE1\u8BDE\u5F39\u86CB\u5F53\u6321\u515A\u8361"+ + "\u6863\u5200\u6363\u8E48\u5012\u5C9B\u7977\u5BFC"+ + "\u5230\u7A3B\u60BC\u9053\u76D7\u5FB7\u5F97\u7684"+ + "\u8E6C\u706F\u767B\u7B49\u77AA\u51F3\u9093\u5824"+ + "\u4F4E\u6EF4\u8FEA\u654C\u7B1B\u72C4\u6DA4\u7FDF"+ + "\u5AE1\u62B5\u5E95\u5730\u8482\u7B2C\u5E1D\u5F1F"+ + "\u9012\u7F14\u98A0\u6382\u6EC7\u7898\u70B9\u5178"+ + "\u975B\u57AB\u7535\u4F43\u7538\u5E97\u60E6\u5960"+ + "\u6DC0\u6BBF\u7889\u53FC\u96D5\u51CB\u5201\u6389"+ + "\u540A\u9493\u8C03\u8DCC\u7239\u789F\u8776\u8FED"+ + "\u8C0D\u53E0\u7993\u7994\u7995\u7996\u7997\u7998"+ + "\u7999\u799B\u799C\u799D\u799E\u799F\u79A0\u79A1"+ + "\u79A2\u79A3\u79A4\u79A5\u79A6\u79A8\u79A9\u79AA"+ + "\u79AB\u79AC\u79AD\u79AE\u79AF\u79B0\u79B1\u79B2"+ + "\u79B4\u79B5\u79B6\u79B7\u79B8\u79BC\u79BF\u79C2"+ + "\u79C4\u79C5\u79C7\u79C8\u79CA\u79CC\u79CE\u79CF"+ + "\u79D0\u79D3\u79D4\u79D6\u79D7\u79D9\u79DA\u79DB"+ + "\u79DC\u79DD\u79DE\u79E0\u79E1\u79E2\u79E5\u79E8"+ + "\u79EA\uFFFD\u79EC\u79EE\u79F1\u79F2\u79F3\u79F4"+ + "\u79F5\u79F6\u79F7\u79F9\u79FA\u79FC\u79FE\u79FF"+ + "\u7A01\u7A04\u7A05\u7A07\u7A08\u7A09\u7A0A\u7A0C"+ + "\u7A0F\u7A10\u7A11\u7A12\u7A13\u7A15\u7A16\u7A18"+ + "\u7A19\u7A1B\u7A1C\u4E01\u76EF\u53EE\u9489\u9876"+ + "\u9F0E\u952D\u5B9A\u8BA2\u4E22\u4E1C\u51AC\u8463"+ + "\u61C2\u52A8\u680B\u4F97\u606B\u51BB\u6D1E\u515C"+ + "\u6296\u6597\u9661\u8C46\u9017\u75D8\u90FD\u7763"+ + "\u6BD2\u728A\u72EC\u8BFB\u5835\u7779\u8D4C\u675C"+ + "\u9540\u809A\u5EA6\u6E21\u5992\u7AEF\u77ED\u953B"+ + "\u6BB5\u65AD\u7F0E\u5806\u5151\u961F\u5BF9\u58A9"+ + "\u5428\u8E72\u6566\u987F\u56E4\u949D\u76FE\u9041"+ + "\u6387\u54C6\u591A\u593A\u579B\u8EB2\u6735\u8DFA"+ + "\u8235\u5241\u60F0\u5815\u86FE\u5CE8\u9E45\u4FC4"+ + "\u989D\u8BB9\u5A25\u6076\u5384\u627C\u904F\u9102"+ + "\u997F\u6069\u800C\u513F\u8033\u5C14\u9975\u6D31"+ + "\u4E8C\u7A1D\u7A1F\u7A21\u7A22\u7A24\u7A25\u7A26"+ + "\u7A27\u7A28\u7A29\u7A2A\u7A2B\u7A2C\u7A2D\u7A2E"+ + "\u7A2F\u7A30\u7A31\u7A32\u7A34\u7A35\u7A36\u7A38"+ + "\u7A3A\u7A3E\u7A40\u7A41\u7A42\u7A43\u7A44\u7A45"+ + "\u7A47\u7A48\u7A49\u7A4A\u7A4B\u7A4C\u7A4D\u7A4E"+ + "\u7A4F\u7A50\u7A52\u7A53\u7A54\u7A55\u7A56\u7A58"+ + "\u7A59\u7A5A\u7A5B\u7A5C\u7A5D\u7A5E\u7A5F\u7A60"+ + "\u7A61\u7A62\u7A63\u7A64\u7A65\u7A66\u7A67\u7A68"+ + "\uFFFD\u7A69\u7A6A\u7A6B\u7A6C\u7A6D\u7A6E\u7A6F"+ + "\u7A71\u7A72\u7A73\u7A75\u7A7B\u7A7C\u7A7D\u7A7E"+ + "\u7A82\u7A85\u7A87\u7A89\u7A8A\u7A8B\u7A8C\u7A8E"+ + "\u7A8F\u7A90\u7A93\u7A94\u7A99\u7A9A\u7A9B\u7A9E"+ + "\u7AA1\u7AA2\u8D30\u53D1\u7F5A\u7B4F\u4F10\u4E4F"+ + "\u9600\u6CD5\u73D0\u85E9\u5E06\u756A\u7FFB\u6A0A"+ + "\u77FE\u9492\u7E41\u51E1\u70E6\u53CD\u8FD4\u8303"+ + "\u8D29\u72AF\u996D\u6CDB\u574A\u82B3\u65B9\u80AA"+ + "\u623F\u9632\u59A8\u4EFF\u8BBF\u7EBA\u653E\u83F2"+ + "\u975E\u5561\u98DE\u80A5\u532A\u8BFD\u5420\u80BA"+ + "\u5E9F\u6CB8\u8D39\u82AC\u915A\u5429\u6C1B\u5206"+ + "\u7EB7\u575F\u711A\u6C7E\u7C89\u594B\u4EFD\u5FFF"+ + "\u6124\u7CAA\u4E30\u5C01\u67AB\u8702\u5CF0\u950B"+ + "\u98CE\u75AF\u70FD\u9022\u51AF\u7F1D\u8BBD\u5949"+ + "\u51E4\u4F5B\u5426\u592B\u6577\u80A4\u5B75\u6276"+ + "\u62C2\u8F90\u5E45\u6C1F\u7B26\u4F0F\u4FD8\u670D"+ + "\u7AA3\u7AA4\u7AA7\u7AA9\u7AAA\u7AAB\u7AAE\u7AAF"+ + "\u7AB0\u7AB1\u7AB2\u7AB4\u7AB5\u7AB6\u7AB7\u7AB8"+ + "\u7AB9\u7ABA\u7ABB\u7ABC\u7ABD\u7ABE\u7AC0\u7AC1"+ + "\u7AC2\u7AC3\u7AC4\u7AC5\u7AC6\u7AC7\u7AC8\u7AC9"+ + "\u7ACA\u7ACC\u7ACD\u7ACE\u7ACF\u7AD0\u7AD1\u7AD2"+ + "\u7AD3\u7AD4\u7AD5\u7AD7\u7AD8\u7ADA\u7ADB\u7ADC"+ + "\u7ADD\u7AE1\u7AE2\u7AE4\u7AE7\u7AE8\u7AE9\u7AEA"+ + "\u7AEB\u7AEC\u7AEE\u7AF0\u7AF1\u7AF2\u7AF3\uFFFD"+ + "\u7AF4\u7AF5\u7AF6\u7AF7\u7AF8\u7AFB\u7AFC\u7AFE"+ + "\u7B00\u7B01\u7B02\u7B05\u7B07\u7B09\u7B0C\u7B0D"+ + "\u7B0E\u7B10\u7B12\u7B13\u7B16\u7B17\u7B18\u7B1A"+ + "\u7B1C\u7B1D\u7B1F\u7B21\u7B22\u7B23\u7B27\u7B29"+ + "\u7B2D\u6D6E\u6DAA\u798F\u88B1\u5F17\u752B\u629A"+ + "\u8F85\u4FEF\u91DC\u65A7\u812F\u8151\u5E9C\u8150"+ + "\u8D74\u526F\u8986\u8D4B\u590D\u5085\u4ED8\u961C"+ + "\u7236\u8179\u8D1F\u5BCC\u8BA3\u9644\u5987\u7F1A"+ + "\u5490\u5676\u560E\u8BE5\u6539\u6982\u9499\u76D6"+ + "\u6E89\u5E72\u7518\u6746\u67D1\u7AFF\u809D\u8D76"+ + "\u611F\u79C6\u6562\u8D63\u5188\u521A\u94A2\u7F38"+ + "\u809B\u7EB2\u5C97\u6E2F\u6760\u7BD9\u768B\u9AD8"+ + "\u818F\u7F94\u7CD5\u641E\u9550\u7A3F\u544A\u54E5"+ + "\u6B4C\u6401\u6208\u9E3D\u80F3\u7599\u5272\u9769"+ + "\u845B\u683C\u86E4\u9601\u9694\u94EC\u4E2A\u5404"+ + "\u7ED9\u6839\u8DDF\u8015\u66F4\u5E9A\u7FB9\u7B2F"+ + "\u7B30\u7B32\u7B34\u7B35\u7B36\u7B37\u7B39\u7B3B"+ + "\u7B3D\u7B3F\u7B40\u7B41\u7B42\u7B43\u7B44\u7B46"+ + "\u7B48\u7B4A\u7B4D\u7B4E\u7B53\u7B55\u7B57\u7B59"+ + "\u7B5C\u7B5E\u7B5F\u7B61\u7B63\u7B64\u7B65\u7B66"+ + "\u7B67\u7B68\u7B69\u7B6A\u7B6B\u7B6C\u7B6D\u7B6F"+ + "\u7B70\u7B73\u7B74\u7B76\u7B78\u7B7A\u7B7C\u7B7D"+ + "\u7B7F\u7B81\u7B82\u7B83\u7B84\u7B86\u7B87\u7B88"+ + "\u7B89\u7B8A\u7B8B\u7B8C\u7B8E\u7B8F\uFFFD\u7B91"+ + "\u7B92\u7B93\u7B96\u7B98\u7B99\u7B9A\u7B9B\u7B9E"+ + "\u7B9F\u7BA0\u7BA3\u7BA4\u7BA5\u7BAE\u7BAF\u7BB0"+ + "\u7BB2\u7BB3\u7BB5\u7BB6\u7BB7\u7BB9\u7BBA\u7BBB"+ + "\u7BBC\u7BBD\u7BBE\u7BBF\u7BC0\u7BC2\u7BC3\u7BC4"+ + "\u57C2\u803F\u6897\u5DE5\u653B\u529F\u606D\u9F9A"+ + "\u4F9B\u8EAC\u516C\u5BAB\u5F13\u5DE9\u6C5E\u62F1"+ + "\u8D21\u5171\u94A9\u52FE\u6C9F\u82DF\u72D7\u57A2"+ + "\u6784\u8D2D\u591F\u8F9C\u83C7\u5495\u7B8D\u4F30"+ + "\u6CBD\u5B64\u59D1\u9F13\u53E4\u86CA\u9AA8\u8C37"+ + "\u80A1\u6545\u987E\u56FA\u96C7\u522E\u74DC\u5250"+ + "\u5BE1\u6302\u8902\u4E56\u62D0\u602A\u68FA\u5173"+ + "\u5B98\u51A0\u89C2\u7BA1\u9986\u7F50\u60EF\u704C"+ + "\u8D2F\u5149\u5E7F\u901B\u7470\u89C4\u572D\u7845"+ + "\u5F52\u9F9F\u95FA\u8F68\u9B3C\u8BE1\u7678\u6842"+ + "\u67DC\u8DEA\u8D35\u523D\u8F8A\u6EDA\u68CD\u9505"+ + "\u90ED\u56FD\u679C\u88F9\u8FC7\u54C8\u7BC5\u7BC8"+ + "\u7BC9\u7BCA\u7BCB\u7BCD\u7BCE\u7BCF\u7BD0\u7BD2"+ + "\u7BD4\u7BD5\u7BD6\u7BD7\u7BD8\u7BDB\u7BDC\u7BDE"+ + "\u7BDF\u7BE0\u7BE2\u7BE3\u7BE4\u7BE7\u7BE8\u7BE9"+ + "\u7BEB\u7BEC\u7BED\u7BEF\u7BF0\u7BF2\u7BF3\u7BF4"+ + "\u7BF5\u7BF6\u7BF8\u7BF9\u7BFA\u7BFB\u7BFD\u7BFF"+ + "\u7C00\u7C01\u7C02\u7C03\u7C04\u7C05\u7C06\u7C08"+ + "\u7C09\u7C0A\u7C0D\u7C0E\u7C10\u7C11\u7C12\u7C13"+ + "\u7C14\u7C15\u7C17\u7C18\u7C19\uFFFD\u7C1A\u7C1B"+ + "\u7C1C\u7C1D\u7C1E\u7C20\u7C21\u7C22\u7C23\u7C24"+ + "\u7C25\u7C28\u7C29\u7C2B\u7C2C\u7C2D\u7C2E\u7C2F"+ + "\u7C30\u7C31\u7C32\u7C33\u7C34\u7C35\u7C36\u7C37"+ + "\u7C39\u7C3A\u7C3B\u7C3C\u7C3D\u7C3E\u7C42\u9AB8"+ + "\u5B69\u6D77\u6C26\u4EA5\u5BB3\u9A87\u9163\u61A8"+ + "\u90AF\u97E9\u542B\u6DB5\u5BD2\u51FD\u558A\u7F55"+ + "\u7FF0\u64BC\u634D\u65F1\u61BE\u608D\u710A\u6C57"+ + "\u6C49\u592F\u676D\u822A\u58D5\u568E\u8C6A\u6BEB"+ + "\u90DD\u597D\u8017\u53F7\u6D69\u5475\u559D\u8377"+ + "\u83CF\u6838\u79BE\u548C\u4F55\u5408\u76D2\u8C89"+ + "\u9602\u6CB3\u6DB8\u8D6B\u8910\u9E64\u8D3A\u563F"+ + "\u9ED1\u75D5\u5F88\u72E0\u6068\u54FC\u4EA8\u6A2A"+ + "\u8861\u6052\u8F70\u54C4\u70D8\u8679\u9E3F\u6D2A"+ + "\u5B8F\u5F18\u7EA2\u5589\u4FAF\u7334\u543C\u539A"+ + "\u5019\u540E\u547C\u4E4E\u5FFD\u745A\u58F6\u846B"+ + "\u80E1\u8774\u72D0\u7CCA\u6E56\u7C43\u7C44\u7C45"+ + "\u7C46\u7C47\u7C48\u7C49\u7C4A\u7C4B\u7C4C\u7C4E"+ + "\u7C4F\u7C50\u7C51\u7C52\u7C53\u7C54\u7C55\u7C56"+ + "\u7C57\u7C58\u7C59\u7C5A\u7C5B\u7C5C\u7C5D\u7C5E"+ + "\u7C5F\u7C60\u7C61\u7C62\u7C63\u7C64\u7C65\u7C66"+ + "\u7C67\u7C68\u7C69\u7C6A\u7C6B\u7C6C\u7C6D\u7C6E"+ + "\u7C6F\u7C70\u7C71\u7C72\u7C75\u7C76\u7C77\u7C78"+ + "\u7C79\u7C7A\u7C7E\u7C7F\u7C80\u7C81\u7C82\u7C83"+ + "\u7C84\u7C85\u7C86\u7C87\uFFFD\u7C88\u7C8A\u7C8B"+ + "\u7C8C\u7C8D\u7C8E\u7C8F\u7C90\u7C93\u7C94\u7C96"+ + "\u7C99\u7C9A\u7C9B\u7CA0\u7CA1\u7CA3\u7CA6\u7CA7"+ + "\u7CA8\u7CA9\u7CAB\u7CAC\u7CAD\u7CAF\u7CB0\u7CB4"+ + "\u7CB5\u7CB6\u7CB7\u7CB8\u7CBA\u7CBB\u5F27\u864E"+ + "\u552C\u62A4\u4E92\u6CAA\u6237\u82B1\u54D7\u534E"+ + "\u733E\u6ED1\u753B\u5212\u5316\u8BDD\u69D0\u5F8A"+ + "\u6000\u6DEE\u574F\u6B22\u73AF\u6853\u8FD8\u7F13"+ + "\u6362\u60A3\u5524\u75EA\u8C62\u7115\u6DA3\u5BA6"+ + "\u5E7B\u8352\u614C\u9EC4\u78FA\u8757\u7C27\u7687"+ + "\u51F0\u60F6\u714C\u6643\u5E4C\u604D\u8C0E\u7070"+ + "\u6325\u8F89\u5FBD\u6062\u86D4\u56DE\u6BC1\u6094"+ + "\u6167\u5349\u60E0\u6666\u8D3F\u79FD\u4F1A\u70E9"+ + "\u6C47\u8BB3\u8BF2\u7ED8\u8364\u660F\u5A5A\u9B42"+ + "\u6D51\u6DF7\u8C41\u6D3B\u4F19\u706B\u83B7\u6216"+ + "\u60D1\u970D\u8D27\u7978\u51FB\u573E\u57FA\u673A"+ + "\u7578\u7A3D\u79EF\u7B95\u7CBF\u7CC0\u7CC2\u7CC3"+ + "\u7CC4\u7CC6\u7CC9\u7CCB\u7CCE\u7CCF\u7CD0\u7CD1"+ + "\u7CD2\u7CD3\u7CD4\u7CD8\u7CDA\u7CDB\u7CDD\u7CDE"+ + "\u7CE1\u7CE2\u7CE3\u7CE4\u7CE5\u7CE6\u7CE7\u7CE9"+ + "\u7CEA\u7CEB\u7CEC\u7CED\u7CEE\u7CF0\u7CF1\u7CF2"+ + "\u7CF3\u7CF4\u7CF5\u7CF6\u7CF7\u7CF9\u7CFA\u7CFC"+ + "\u7CFD\u7CFE\u7CFF\u7D00\u7D01\u7D02\u7D03\u7D04"+ + "\u7D05\u7D06\u7D07\u7D08\u7D09\u7D0B\u7D0C\u7D0D"+ + "\u7D0E\u7D0F\u7D10\uFFFD\u7D11\u7D12\u7D13\u7D14"+ + "\u7D15\u7D16\u7D17\u7D18\u7D19\u7D1A\u7D1B\u7D1C"+ + "\u7D1D\u7D1E\u7D1F\u7D21\u7D23\u7D24\u7D25\u7D26"+ + "\u7D28\u7D29\u7D2A\u7D2C\u7D2D\u7D2E\u7D30\u7D31"+ + "\u7D32\u7D33\u7D34\u7D35\u7D36\u808C\u9965\u8FF9"+ + "\u6FC0\u8BA5\u9E21\u59EC\u7EE9\u7F09\u5409\u6781"+ + "\u68D8\u8F91\u7C4D\u96C6\u53CA\u6025\u75BE\u6C72"+ + "\u5373\u5AC9\u7EA7\u6324\u51E0\u810A\u5DF1\u84DF"+ + "\u6280\u5180\u5B63\u4F0E\u796D\u5242\u60B8\u6D4E"+ + "\u5BC4\u5BC2\u8BA1\u8BB0\u65E2\u5FCC\u9645\u5993"+ + "\u7EE7\u7EAA\u5609\u67B7\u5939\u4F73\u5BB6\u52A0"+ + "\u835A\u988A\u8D3E\u7532\u94BE\u5047\u7A3C\u4EF7"+ + "\u67B6\u9A7E\u5AC1\u6B7C\u76D1\u575A\u5C16\u7B3A"+ + "\u95F4\u714E\u517C\u80A9\u8270\u5978\u7F04\u8327"+ + "\u68C0\u67EC\u78B1\u7877\u62E3\u6361\u7B80\u4FED"+ + "\u526A\u51CF\u8350\u69DB\u9274\u8DF5\u8D31\u89C1"+ + "\u952E\u7BAD\u4EF6\u7D37\u7D38\u7D39\u7D3A\u7D3B"+ + "\u7D3C\u7D3D\u7D3E\u7D3F\u7D40\u7D41\u7D42\u7D43"+ + "\u7D44\u7D45\u7D46\u7D47\u7D48\u7D49\u7D4A\u7D4B"+ + "\u7D4C\u7D4D\u7D4E\u7D4F\u7D50\u7D51\u7D52\u7D53"+ + "\u7D54\u7D55\u7D56\u7D57\u7D58\u7D59\u7D5A\u7D5B"+ + "\u7D5C\u7D5D\u7D5E\u7D5F\u7D60\u7D61\u7D62\u7D63"+ + "\u7D64\u7D65\u7D66\u7D67\u7D68\u7D69\u7D6A\u7D6B"+ + "\u7D6C\u7D6D\u7D6F\u7D70\u7D71\u7D72\u7D73\u7D74"+ + "\u7D75\u7D76\uFFFD\u7D78\u7D79\u7D7A\u7D7B\u7D7C"+ + "\u7D7D\u7D7E\u7D7F\u7D80\u7D81\u7D82\u7D83\u7D84"+ + "\u7D85\u7D86\u7D87\u7D88\u7D89\u7D8A\u7D8B\u7D8C"+ + "\u7D8D\u7D8E\u7D8F\u7D90\u7D91\u7D92\u7D93\u7D94"+ + "\u7D95\u7D96\u7D97\u7D98\u5065\u8230\u5251\u996F"+ + "\u6E10\u6E85\u6DA7\u5EFA\u50F5\u59DC\u5C06\u6D46"+ + "\u6C5F\u7586\u848B\u6868\u5956\u8BB2\u5320\u9171"+ + "\u964D\u8549\u6912\u7901\u7126\u80F6\u4EA4\u90CA"+ + "\u6D47\u9A84\u5A07\u56BC\u6405\u94F0\u77EB\u4FA5"+ + "\u811A\u72E1\u89D2\u997A\u7F34\u7EDE\u527F\u6559"+ + "\u9175\u8F7F\u8F83\u53EB\u7A96\u63ED\u63A5\u7686"+ + "\u79F8\u8857\u9636\u622A\u52AB\u8282\u6854\u6770"+ + "\u6377\u776B\u7AED\u6D01\u7ED3\u89E3\u59D0\u6212"+ + "\u85C9\u82A5\u754C\u501F\u4ECB\u75A5\u8BEB\u5C4A"+ + "\u5DFE\u7B4B\u65A4\u91D1\u4ECA\u6D25\u895F\u7D27"+ + "\u9526\u4EC5\u8C28\u8FDB\u9773\u664B\u7981\u8FD1"+ + "\u70EC\u6D78\u7D99\u7D9A\u7D9B\u7D9C\u7D9D\u7D9E"+ + "\u7D9F\u7DA0\u7DA1\u7DA2\u7DA3\u7DA4\u7DA5\u7DA7"+ + "\u7DA8\u7DA9\u7DAA\u7DAB\u7DAC\u7DAD\u7DAF\u7DB0"+ + "\u7DB1\u7DB2\u7DB3\u7DB4\u7DB5\u7DB6\u7DB7\u7DB8"+ + "\u7DB9\u7DBA\u7DBB\u7DBC\u7DBD\u7DBE\u7DBF\u7DC0"+ + "\u7DC1\u7DC2\u7DC3\u7DC4\u7DC5\u7DC6\u7DC7\u7DC8"+ + "\u7DC9\u7DCA\u7DCB\u7DCC\u7DCD\u7DCE\u7DCF\u7DD0"+ + "\u7DD1\u7DD2\u7DD3\u7DD4\u7DD5\u7DD6\u7DD7\u7DD8"+ + "\u7DD9\uFFFD\u7DDA\u7DDB\u7DDC\u7DDD\u7DDE\u7DDF"+ + "\u7DE0\u7DE1\u7DE2\u7DE3\u7DE4\u7DE5\u7DE6\u7DE7"+ + "\u7DE8\u7DE9\u7DEA\u7DEB\u7DEC\u7DED\u7DEE\u7DEF"+ + "\u7DF0\u7DF1\u7DF2\u7DF3\u7DF4\u7DF5\u7DF6\u7DF7"+ + "\u7DF8\u7DF9\u7DFA\u5C3D\u52B2\u8346\u5162\u830E"+ + "\u775B\u6676\u9CB8\u4EAC\u60CA\u7CBE\u7CB3\u7ECF"+ + "\u4E95\u8B66\u666F\u9888\u9759\u5883\u656C\u955C"+ + "\u5F84\u75C9\u9756\u7ADF\u7ADE\u51C0\u70AF\u7A98"+ + "\u63EA\u7A76\u7EA0\u7396\u97ED\u4E45\u7078\u4E5D"+ + "\u9152\u53A9\u6551\u65E7\u81FC\u8205\u548E\u5C31"+ + "\u759A\u97A0\u62D8\u72D9\u75BD\u5C45\u9A79\u83CA"+ + "\u5C40\u5480\u77E9\u4E3E\u6CAE\u805A\u62D2\u636E"+ + "\u5DE8\u5177\u8DDD\u8E1E\u952F\u4FF1\u53E5\u60E7"+ + "\u70AC\u5267\u6350\u9E43\u5A1F\u5026\u7737\u5377"+ + "\u7EE2\u6485\u652B\u6289\u6398\u5014\u7235\u89C9"+ + "\u51B3\u8BC0\u7EDD\u5747\u83CC\u94A7\u519B\u541B"+ + "\u5CFB\u7DFB\u7DFC\u7DFD\u7DFE\u7DFF\u7E00\u7E01"+ + "\u7E02\u7E03\u7E04\u7E05\u7E06\u7E07\u7E08\u7E09"+ + "\u7E0A\u7E0B\u7E0C\u7E0D\u7E0E\u7E0F\u7E10\u7E11"+ + "\u7E12\u7E13\u7E14\u7E15\u7E16\u7E17\u7E18\u7E19"+ + "\u7E1A\u7E1B\u7E1C\u7E1D\u7E1E\u7E1F\u7E20\u7E21"+ + "\u7E22\u7E23\u7E24\u7E25\u7E26\u7E27\u7E28\u7E29"+ + "\u7E2A\u7E2B\u7E2C\u7E2D\u7E2E\u7E2F\u7E30\u7E31"+ + "\u7E32\u7E33\u7E34\u7E35\u7E36\u7E37\u7E38\u7E39"+ + "\uFFFD\u7E3A\u7E3C\u7E3D\u7E3E\u7E3F\u7E40\u7E42"+ + "\u7E43\u7E44\u7E45\u7E46\u7E48\u7E49\u7E4A\u7E4B"+ + "\u7E4C\u7E4D\u7E4E\u7E4F\u7E50\u7E51\u7E52\u7E53"+ + "\u7E54\u7E55\u7E56\u7E57\u7E58\u7E59\u7E5A\u7E5B"+ + "\u7E5C\u7E5D\u4FCA\u7AE3\u6D5A\u90E1\u9A8F\u5580"+ + "\u5496\u5361\u54AF\u5F00\u63E9\u6977\u51EF\u6168"+ + "\u520A\u582A\u52D8\u574E\u780D\u770B\u5EB7\u6177"+ + "\u7CE0\u625B\u6297\u4EA2\u7095\u8003\u62F7\u70E4"+ + "\u9760\u5777\u82DB\u67EF\u68F5\u78D5\u9897\u79D1"+ + "\u58F3\u54B3\u53EF\u6E34\u514B\u523B\u5BA2\u8BFE"+ + "\u80AF\u5543\u57A6\u6073\u5751\u542D\u7A7A\u6050"+ + "\u5B54\u63A7\u62A0\u53E3\u6263\u5BC7\u67AF\u54ED"+ + "\u7A9F\u82E6\u9177\u5E93\u88E4\u5938\u57AE\u630E"+ + "\u8DE8\u80EF\u5757\u7B77\u4FA9\u5FEB\u5BBD\u6B3E"+ + "\u5321\u7B50\u72C2\u6846\u77FF\u7736\u65F7\u51B5"+ + "\u4E8F\u76D4\u5CBF\u7AA5\u8475\u594E\u9B41\u5080"; + + private static final String innerIndex4= + "\u7E5E\u7E5F\u7E60\u7E61\u7E62\u7E63\u7E64\u7E65"+ + "\u7E66\u7E67\u7E68\u7E69\u7E6A\u7E6B\u7E6C\u7E6D"+ + "\u7E6E\u7E6F\u7E70\u7E71\u7E72\u7E73\u7E74\u7E75"+ + "\u7E76\u7E77\u7E78\u7E79\u7E7A\u7E7B\u7E7C\u7E7D"+ + "\u7E7E\u7E7F\u7E80\u7E81\u7E83\u7E84\u7E85\u7E86"+ + "\u7E87\u7E88\u7E89\u7E8A\u7E8B\u7E8C\u7E8D\u7E8E"+ + "\u7E8F\u7E90\u7E91\u7E92\u7E93\u7E94\u7E95\u7E96"+ + "\u7E97\u7E98\u7E99\u7E9A\u7E9C\u7E9D\u7E9E\uFFFD"+ + "\u7EAE\u7EB4\u7EBB\u7EBC\u7ED6\u7EE4\u7EEC\u7EF9"+ + "\u7F0A\u7F10\u7F1E\u7F37\u7F39\u7F3B\u7F3C\u7F3D"+ + "\u7F3E\u7F3F\u7F40\u7F41\u7F43\u7F46\u7F47\u7F48"+ + "\u7F49\u7F4A\u7F4B\u7F4C\u7F4D\u7F4E\u7F4F\u7F52"+ + "\u7F53\u9988\u6127\u6E83\u5764\u6606\u6346\u56F0"+ + "\u62EC\u6269\u5ED3\u9614\u5783\u62C9\u5587\u8721"+ + "\u814A\u8FA3\u5566\u83B1\u6765\u8D56\u84DD\u5A6A"+ + "\u680F\u62E6\u7BEE\u9611\u5170\u6F9C\u8C30\u63FD"+ + "\u89C8\u61D2\u7F06\u70C2\u6EE5\u7405\u6994\u72FC"+ + "\u5ECA\u90CE\u6717\u6D6A\u635E\u52B3\u7262\u8001"+ + "\u4F6C\u59E5\u916A\u70D9\u6D9D\u52D2\u4E50\u96F7"+ + "\u956D\u857E\u78CA\u7D2F\u5121\u5792\u64C2\u808B"+ + "\u7C7B\u6CEA\u68F1\u695E\u51B7\u5398\u68A8\u7281"+ + "\u9ECE\u7BF1\u72F8\u79BB\u6F13\u7406\u674E\u91CC"+ + "\u9CA4\u793C\u8389\u8354\u540F\u6817\u4E3D\u5389"+ + "\u52B1\u783E\u5386\u5229\u5088\u4F8B\u4FD0\u7F56"+ + "\u7F59\u7F5B\u7F5C\u7F5D\u7F5E\u7F60\u7F63\u7F64"+ + "\u7F65\u7F66\u7F67\u7F6B\u7F6C\u7F6D\u7F6F\u7F70"+ + "\u7F73\u7F75\u7F76\u7F77\u7F78\u7F7A\u7F7B\u7F7C"+ + "\u7F7D\u7F7F\u7F80\u7F82\u7F83\u7F84\u7F85\u7F86"+ + "\u7F87\u7F88\u7F89\u7F8B\u7F8D\u7F8F\u7F90\u7F91"+ + "\u7F92\u7F93\u7F95\u7F96\u7F97\u7F98\u7F99\u7F9B"+ + "\u7F9C\u7FA0\u7FA2\u7FA3\u7FA5\u7FA6\u7FA8\u7FA9"+ + "\u7FAA\u7FAB\u7FAC\u7FAD\u7FAE\u7FB1\uFFFD\u7FB3"+ + "\u7FB4\u7FB5\u7FB6\u7FB7\u7FBA\u7FBB\u7FBE\u7FC0"+ + "\u7FC2\u7FC3\u7FC4\u7FC6\u7FC7\u7FC8\u7FC9\u7FCB"+ + "\u7FCD\u7FCF\u7FD0\u7FD1\u7FD2\u7FD3\u7FD6\u7FD7"+ + "\u7FD9\u7FDA\u7FDB\u7FDC\u7FDD\u7FDE\u7FE2\u7FE3"+ + "\u75E2\u7ACB\u7C92\u6CA5\u96B6\u529B\u7483\u54E9"+ + "\u4FE9\u8054\u83B2\u8FDE\u9570\u5EC9\u601C\u6D9F"+ + "\u5E18\u655B\u8138\u94FE\u604B\u70BC\u7EC3\u7CAE"+ + "\u51C9\u6881\u7CB1\u826F\u4E24\u8F86\u91CF\u667E"+ + "\u4EAE\u8C05\u64A9\u804A\u50DA\u7597\u71CE\u5BE5"+ + "\u8FBD\u6F66\u4E86\u6482\u9563\u5ED6\u6599\u5217"+ + "\u88C2\u70C8\u52A3\u730E\u7433\u6797\u78F7\u9716"+ + "\u4E34\u90BB\u9CDE\u6DCB\u51DB\u8D41\u541D\u62CE"+ + "\u73B2\u83F1\u96F6\u9F84\u94C3\u4F36\u7F9A\u51CC"+ + "\u7075\u9675\u5CAD\u9886\u53E6\u4EE4\u6E9C\u7409"+ + "\u69B4\u786B\u998F\u7559\u5218\u7624\u6D41\u67F3"+ + "\u516D\u9F99\u804B\u5499\u7B3C\u7ABF\u7FE4\u7FE7"+ + "\u7FE8\u7FEA\u7FEB\u7FEC\u7FED\u7FEF\u7FF2\u7FF4"+ + "\u7FF5\u7FF6\u7FF7\u7FF8\u7FF9\u7FFA\u7FFD\u7FFE"+ + "\u7FFF\u8002\u8007\u8008\u8009\u800A\u800E\u800F"+ + "\u8011\u8013\u801A\u801B\u801D\u801E\u801F\u8021"+ + "\u8023\u8024\u802B\u802C\u802D\u802E\u802F\u8030"+ + "\u8032\u8034\u8039\u803A\u803C\u803E\u8040\u8041"+ + "\u8044\u8045\u8047\u8048\u8049\u804E\u804F\u8050"+ + "\u8051\u8053\u8055\u8056\u8057\uFFFD\u8059\u805B"+ + "\u805C\u805D\u805E\u805F\u8060\u8061\u8062\u8063"+ + "\u8064\u8065\u8066\u8067\u8068\u806B\u806C\u806D"+ + "\u806E\u806F\u8070\u8072\u8073\u8074\u8075\u8076"+ + "\u8077\u8078\u8079\u807A\u807B\u807C\u807D\u9686"+ + "\u5784\u62E2\u9647\u697C\u5A04\u6402\u7BD3\u6F0F"+ + "\u964B\u82A6\u5362\u9885\u5E90\u7089\u63B3\u5364"+ + "\u864F\u9C81\u9E93\u788C\u9732\u8DEF\u8D42\u9E7F"+ + "\u6F5E\u7984\u5F55\u9646\u622E\u9A74\u5415\u94DD"+ + "\u4FA3\u65C5\u5C65\u5C61\u7F15\u8651\u6C2F\u5F8B"+ + "\u7387\u6EE4\u7EFF\u5CE6\u631B\u5B6A\u6EE6\u5375"+ + "\u4E71\u63A0\u7565\u62A1\u8F6E\u4F26\u4ED1\u6CA6"+ + "\u7EB6\u8BBA\u841D\u87BA\u7F57\u903B\u9523\u7BA9"+ + "\u9AA1\u88F8\u843D\u6D1B\u9A86\u7EDC\u5988\u9EBB"+ + "\u739B\u7801\u8682\u9A6C\u9A82\u561B\u5417\u57CB"+ + "\u4E70\u9EA6\u5356\u8FC8\u8109\u7792\u9992\u86EE"+ + "\u6EE1\u8513\u66FC\u6162\u6F2B\u807E\u8081\u8082"+ + "\u8085\u8088\u808A\u808D\u808E\u808F\u8090\u8091"+ + "\u8092\u8094\u8095\u8097\u8099\u809E\u80A3\u80A6"+ + "\u80A7\u80A8\u80AC\u80B0\u80B3\u80B5\u80B6\u80B8"+ + "\u80B9\u80BB\u80C5\u80C7\u80C8\u80C9\u80CA\u80CB"+ + "\u80CF\u80D0\u80D1\u80D2\u80D3\u80D4\u80D5\u80D8"+ + "\u80DF\u80E0\u80E2\u80E3\u80E6\u80EE\u80F5\u80F7"+ + "\u80F9\u80FB\u80FE\u80FF\u8100\u8101\u8103\u8104"+ + "\u8105\u8107\u8108\u810B\uFFFD\u810C\u8115\u8117"+ + "\u8119\u811B\u811C\u811D\u811F\u8120\u8121\u8122"+ + "\u8123\u8124\u8125\u8126\u8127\u8128\u8129\u812A"+ + "\u812B\u812D\u812E\u8130\u8133\u8134\u8135\u8137"+ + "\u8139\u813A\u813B\u813C\u813D\u813F\u8C29\u8292"+ + "\u832B\u76F2\u6C13\u5FD9\u83BD\u732B\u8305\u951A"+ + "\u6BDB\u77DB\u94C6\u536F\u8302\u5192\u5E3D\u8C8C"+ + "\u8D38\u4E48\u73AB\u679A\u6885\u9176\u9709\u7164"+ + "\u6CA1\u7709\u5A92\u9541\u6BCF\u7F8E\u6627\u5BD0"+ + "\u59B9\u5A9A\u95E8\u95F7\u4EEC\u840C\u8499\u6AAC"+ + "\u76DF\u9530\u731B\u68A6\u5B5F\u772F\u919A\u9761"+ + "\u7CDC\u8FF7\u8C1C\u5F25\u7C73\u79D8\u89C5\u6CCC"+ + "\u871C\u5BC6\u5E42\u68C9\u7720\u7EF5\u5195\u514D"+ + "\u52C9\u5A29\u7F05\u9762\u82D7\u63CF\u7784\u85D0"+ + "\u79D2\u6E3A\u5E99\u5999\u8511\u706D\u6C11\u62BF"+ + "\u76BF\u654F\u60AF\u95FD\u660E\u879F\u9E23\u94ED"+ + "\u540D\u547D\u8C2C\u6478\u8140\u8141\u8142\u8143"+ + "\u8144\u8145\u8147\u8149\u814D\u814E\u814F\u8152"+ + "\u8156\u8157\u8158\u815B\u815C\u815D\u815E\u815F"+ + "\u8161\u8162\u8163\u8164\u8166\u8168\u816A\u816B"+ + "\u816C\u816F\u8172\u8173\u8175\u8176\u8177\u8178"+ + "\u8181\u8183\u8184\u8185\u8186\u8187\u8189\u818B"+ + "\u818C\u818D\u818E\u8190\u8192\u8193\u8194\u8195"+ + "\u8196\u8197\u8199\u819A\u819E\u819F\u81A0\u81A1"+ + "\u81A2\u81A4\u81A5\uFFFD\u81A7\u81A9\u81AB\u81AC"+ + "\u81AD\u81AE\u81AF\u81B0\u81B1\u81B2\u81B4\u81B5"+ + "\u81B6\u81B7\u81B8\u81B9\u81BC\u81BD\u81BE\u81BF"+ + "\u81C4\u81C5\u81C7\u81C8\u81C9\u81CB\u81CD\u81CE"+ + "\u81CF\u81D0\u81D1\u81D2\u81D3\u6479\u8611\u6A21"+ + "\u819C\u78E8\u6469\u9B54\u62B9\u672B\u83AB\u58A8"+ + "\u9ED8\u6CAB\u6F20\u5BDE\u964C\u8C0B\u725F\u67D0"+ + "\u62C7\u7261\u4EA9\u59C6\u6BCD\u5893\u66AE\u5E55"+ + "\u52DF\u6155\u6728\u76EE\u7766\u7267\u7A46\u62FF"+ + "\u54EA\u5450\u94A0\u90A3\u5A1C\u7EB3\u6C16\u4E43"+ + "\u5976\u8010\u5948\u5357\u7537\u96BE\u56CA\u6320"+ + "\u8111\u607C\u95F9\u6DD6\u5462\u9981\u5185\u5AE9"+ + "\u80FD\u59AE\u9713\u502A\u6CE5\u5C3C\u62DF\u4F60"+ + "\u533F\u817B\u9006\u6EBA\u852B\u62C8\u5E74\u78BE"+ + "\u64B5\u637B\u5FF5\u5A18\u917F\u9E1F\u5C3F\u634F"+ + "\u8042\u5B7D\u556E\u954A\u954D\u6D85\u60A8\u67E0"+ + "\u72DE\u51DD\u5B81\u81D4\u81D5\u81D6\u81D7\u81D8"+ + "\u81D9\u81DA\u81DB\u81DC\u81DD\u81DE\u81DF\u81E0"+ + "\u81E1\u81E2\u81E4\u81E5\u81E6\u81E8\u81E9\u81EB"+ + "\u81EE\u81EF\u81F0\u81F1\u81F2\u81F5\u81F6\u81F7"+ + "\u81F8\u81F9\u81FA\u81FD\u81FF\u8203\u8207\u8208"+ + "\u8209\u820A\u820B\u820E\u820F\u8211\u8213\u8215"+ + "\u8216\u8217\u8218\u8219\u821A\u821D\u8220\u8224"+ + "\u8225\u8226\u8227\u8229\u822E\u8232\u823A\u823C"+ + "\u823D\u823F\uFFFD\u8240\u8241\u8242\u8243\u8245"+ + "\u8246\u8248\u824A\u824C\u824D\u824E\u8250\u8251"+ + "\u8252\u8253\u8254\u8255\u8256\u8257\u8259\u825B"+ + "\u825C\u825D\u825E\u8260\u8261\u8262\u8263\u8264"+ + "\u8265\u8266\u8267\u8269\u62E7\u6CDE\u725B\u626D"+ + "\u94AE\u7EBD\u8113\u6D53\u519C\u5F04\u5974\u52AA"+ + "\u6012\u5973\u6696\u8650\u759F\u632A\u61E6\u7CEF"+ + "\u8BFA\u54E6\u6B27\u9E25\u6BB4\u85D5\u5455\u5076"+ + "\u6CA4\u556A\u8DB4\u722C\u5E15\u6015\u7436\u62CD"+ + "\u6392\u724C\u5F98\u6E43\u6D3E\u6500\u6F58\u76D8"+ + "\u78D0\u76FC\u7554\u5224\u53DB\u4E53\u5E9E\u65C1"+ + "\u802A\u80D6\u629B\u5486\u5228\u70AE\u888D\u8DD1"+ + "\u6CE1\u5478\u80DA\u57F9\u88F4\u8D54\u966A\u914D"+ + "\u4F69\u6C9B\u55B7\u76C6\u7830\u62A8\u70F9\u6F8E"+ + "\u5F6D\u84EC\u68DA\u787C\u7BF7\u81A8\u670B\u9E4F"+ + "\u6367\u78B0\u576F\u7812\u9739\u6279\u62AB\u5288"+ + "\u7435\u6BD7\u826A\u826B\u826C\u826D\u8271\u8275"+ + "\u8276\u8277\u8278\u827B\u827C\u8280\u8281\u8283"+ + "\u8285\u8286\u8287\u8289\u828C\u8290\u8293\u8294"+ + "\u8295\u8296\u829A\u829B\u829E\u82A0\u82A2\u82A3"+ + "\u82A7\u82B2\u82B5\u82B6\u82BA\u82BB\u82BC\u82BF"+ + "\u82C0\u82C2\u82C3\u82C5\u82C6\u82C9\u82D0\u82D6"+ + "\u82D9\u82DA\u82DD\u82E2\u82E7\u82E8\u82E9\u82EA"+ + "\u82EC\u82ED\u82EE\u82F0\u82F2\u82F3\u82F5\u82F6"+ + "\u82F8\uFFFD\u82FA\u82FC\u82FD\u82FE\u82FF\u8300"+ + "\u830A\u830B\u830D\u8310\u8312\u8313\u8316\u8318"+ + "\u8319\u831D\u831E\u831F\u8320\u8321\u8322\u8323"+ + "\u8324\u8325\u8326\u8329\u832A\u832E\u8330\u8332"+ + "\u8337\u833B\u833D\u5564\u813E\u75B2\u76AE\u5339"+ + "\u75DE\u50FB\u5C41\u8B6C\u7BC7\u504F\u7247\u9A97"+ + "\u98D8\u6F02\u74E2\u7968\u6487\u77A5\u62FC\u9891"+ + "\u8D2B\u54C1\u8058\u4E52\u576A\u82F9\u840D\u5E73"+ + "\u51ED\u74F6\u8BC4\u5C4F\u5761\u6CFC\u9887\u5A46"+ + "\u7834\u9B44\u8FEB\u7C95\u5256\u6251\u94FA\u4EC6"+ + "\u8386\u8461\u83E9\u84B2\u57D4\u6734\u5703\u666E"+ + "\u6D66\u8C31\u66DD\u7011\u671F\u6B3A\u6816\u621A"+ + "\u59BB\u4E03\u51C4\u6F06\u67D2\u6C8F\u5176\u68CB"+ + "\u5947\u6B67\u7566\u5D0E\u8110\u9F50\u65D7\u7948"+ + "\u7941\u9A91\u8D77\u5C82\u4E5E\u4F01\u542F\u5951"+ + "\u780C\u5668\u6C14\u8FC4\u5F03\u6C7D\u6CE3\u8BAB"+ + "\u6390\u833E\u833F\u8341\u8342\u8344\u8345\u8348"+ + "\u834A\u834B\u834C\u834D\u834E\u8353\u8355\u8356"+ + "\u8357\u8358\u8359\u835D\u8362\u8370\u8371\u8372"+ + "\u8373\u8374\u8375\u8376\u8379\u837A\u837E\u837F"+ + "\u8380\u8381\u8382\u8383\u8384\u8387\u8388\u838A"+ + "\u838B\u838C\u838D\u838F\u8390\u8391\u8394\u8395"+ + "\u8396\u8397\u8399\u839A\u839D\u839F\u83A1\u83A2"+ + "\u83A3\u83A4\u83A5\u83A6\u83A7\u83AC\u83AD\u83AE"+ + "\uFFFD\u83AF\u83B5\u83BB\u83BE\u83BF\u83C2\u83C3"+ + "\u83C4\u83C6\u83C8\u83C9\u83CB\u83CD\u83CE\u83D0"+ + "\u83D1\u83D2\u83D3\u83D5\u83D7\u83D9\u83DA\u83DB"+ + "\u83DE\u83E2\u83E3\u83E4\u83E6\u83E7\u83E8\u83EB"+ + "\u83EC\u83ED\u6070\u6D3D\u7275\u6266\u948E\u94C5"+ + "\u5343\u8FC1\u7B7E\u4EDF\u8C26\u4E7E\u9ED4\u94B1"+ + "\u94B3\u524D\u6F5C\u9063\u6D45\u8C34\u5811\u5D4C"+ + "\u6B20\u6B49\u67AA\u545B\u8154\u7F8C\u5899\u8537"+ + "\u5F3A\u62A2\u6A47\u9539\u6572\u6084\u6865\u77A7"+ + "\u4E54\u4FA8\u5DE7\u9798\u64AC\u7FD8\u5CED\u4FCF"+ + "\u7A8D\u5207\u8304\u4E14\u602F\u7A83\u94A6\u4FB5"+ + "\u4EB2\u79E6\u7434\u52E4\u82B9\u64D2\u79BD\u5BDD"+ + "\u6C81\u9752\u8F7B\u6C22\u503E\u537F\u6E05\u64CE"+ + "\u6674\u6C30\u60C5\u9877\u8BF7\u5E86\u743C\u7A77"+ + "\u79CB\u4E18\u90B1\u7403\u6C42\u56DA\u914B\u6CC5"+ + "\u8D8B\u533A\u86C6\u66F2\u8EAF\u5C48\u9A71\u6E20"+ + "\u83EE\u83EF\u83F3\u83F4\u83F5\u83F6\u83F7\u83FA"+ + "\u83FB\u83FC\u83FE\u83FF\u8400\u8402\u8405\u8407"+ + "\u8408\u8409\u840A\u8410\u8412\u8413\u8414\u8415"+ + "\u8416\u8417\u8419\u841A\u841B\u841E\u841F\u8420"+ + "\u8421\u8422\u8423\u8429\u842A\u842B\u842C\u842D"+ + "\u842E\u842F\u8430\u8432\u8433\u8434\u8435\u8436"+ + "\u8437\u8439\u843A\u843B\u843E\u843F\u8440\u8441"+ + "\u8442\u8443\u8444\u8445\u8447\u8448\u8449\uFFFD"+ + "\u844A\u844B\u844C\u844D\u844E\u844F\u8450\u8452"+ + "\u8453\u8454\u8455\u8456\u8458\u845D\u845E\u845F"+ + "\u8460\u8462\u8464\u8465\u8466\u8467\u8468\u846A"+ + "\u846E\u846F\u8470\u8472\u8474\u8477\u8479\u847B"+ + "\u847C\u53D6\u5A36\u9F8B\u8DA3\u53BB\u5708\u98A7"+ + "\u6743\u919B\u6CC9\u5168\u75CA\u62F3\u72AC\u5238"+ + "\u529D\u7F3A\u7094\u7638\u5374\u9E4A\u69B7\u786E"+ + "\u96C0\u88D9\u7FA4\u7136\u71C3\u5189\u67D3\u74E4"+ + "\u58E4\u6518\u56B7\u8BA9\u9976\u6270\u7ED5\u60F9"+ + "\u70ED\u58EC\u4EC1\u4EBA\u5FCD\u97E7\u4EFB\u8BA4"+ + "\u5203\u598A\u7EAB\u6254\u4ECD\u65E5\u620E\u8338"+ + "\u84C9\u8363\u878D\u7194\u6EB6\u5BB9\u7ED2\u5197"+ + "\u63C9\u67D4\u8089\u8339\u8815\u5112\u5B7A\u5982"+ + "\u8FB1\u4E73\u6C5D\u5165\u8925\u8F6F\u962E\u854A"+ + "\u745E\u9510\u95F0\u6DA6\u82E5\u5F31\u6492\u6D12"+ + "\u8428\u816E\u9CC3\u585E\u8D5B\u4E09\u53C1\u847D"+ + "\u847E\u847F\u8480\u8481\u8483\u8484\u8485\u8486"+ + "\u848A\u848D\u848F\u8490\u8491\u8492\u8493\u8494"+ + "\u8495\u8496\u8498\u849A\u849B\u849D\u849E\u849F"+ + "\u84A0\u84A2\u84A3\u84A4\u84A5\u84A6\u84A7\u84A8"+ + "\u84A9\u84AA\u84AB\u84AC\u84AD\u84AE\u84B0\u84B1"+ + "\u84B3\u84B5\u84B6\u84B7\u84BB\u84BC\u84BE\u84C0"+ + "\u84C2\u84C3\u84C5\u84C6\u84C7\u84C8\u84CB\u84CC"+ + "\u84CE\u84CF\u84D2\u84D4\u84D5\u84D7\uFFFD\u84D8"+ + "\u84D9\u84DA\u84DB\u84DC\u84DE\u84E1\u84E2\u84E4"+ + "\u84E7\u84E8\u84E9\u84EA\u84EB\u84ED\u84EE\u84EF"+ + "\u84F1\u84F2\u84F3\u84F4\u84F5\u84F6\u84F7\u84F8"+ + "\u84F9\u84FA\u84FB\u84FD\u84FE\u8500\u8501\u8502"+ + "\u4F1E\u6563\u6851\u55D3\u4E27\u6414\u9A9A\u626B"+ + "\u5AC2\u745F\u8272\u6DA9\u68EE\u50E7\u838E\u7802"+ + "\u6740\u5239\u6C99\u7EB1\u50BB\u5565\u715E\u7B5B"+ + "\u6652\u73CA\u82EB\u6749\u5C71\u5220\u717D\u886B"+ + "\u95EA\u9655\u64C5\u8D61\u81B3\u5584\u6C55\u6247"+ + "\u7F2E\u5892\u4F24\u5546\u8D4F\u664C\u4E0A\u5C1A"+ + "\u88F3\u68A2\u634E\u7A0D\u70E7\u828D\u52FA\u97F6"+ + "\u5C11\u54E8\u90B5\u7ECD\u5962\u8D4A\u86C7\u820C"+ + "\u820D\u8D66\u6444\u5C04\u6151\u6D89\u793E\u8BBE"+ + "\u7837\u7533\u547B\u4F38\u8EAB\u6DF1\u5A20\u7EC5"+ + "\u795E\u6C88\u5BA1\u5A76\u751A\u80BE\u614E\u6E17"+ + "\u58F0\u751F\u7525\u7272\u5347\u7EF3\u8503\u8504"+ + "\u8505\u8506\u8507\u8508\u8509\u850A\u850B\u850D"+ + "\u850E\u850F\u8510\u8512\u8514\u8515\u8516\u8518"+ + "\u8519\u851B\u851C\u851D\u851E\u8520\u8522\u8523"+ + "\u8524\u8525\u8526\u8527\u8528\u8529\u852A\u852D"+ + "\u852E\u852F\u8530\u8531\u8532\u8533\u8534\u8535"+ + "\u8536\u853E\u853F\u8540\u8541\u8542\u8544\u8545"+ + "\u8546\u8547\u854B\u854C\u854D\u854E\u854F\u8550"+ + "\u8551\u8552\u8553\u8554\u8555\uFFFD\u8557\u8558"+ + "\u855A\u855B\u855C\u855D\u855F\u8560\u8561\u8562"+ + "\u8563\u8565\u8566\u8567\u8569\u856A\u856B\u856C"+ + "\u856D\u856E\u856F\u8570\u8571\u8573\u8575\u8576"+ + "\u8577\u8578\u857C\u857D\u857F\u8580\u8581\u7701"+ + "\u76DB\u5269\u80DC\u5723\u5E08\u5931\u72EE\u65BD"+ + "\u6E7F\u8BD7\u5C38\u8671\u5341\u77F3\u62FE\u65F6"+ + "\u4EC0\u98DF\u8680\u5B9E\u8BC6\u53F2\u77E2\u4F7F"+ + "\u5C4E\u9A76\u59CB\u5F0F\u793A\u58EB\u4E16\u67FF"+ + "\u4E8B\u62ED\u8A93\u901D\u52BF\u662F\u55DC\u566C"+ + "\u9002\u4ED5\u4F8D\u91CA\u9970\u6C0F\u5E02\u6043"+ + "\u5BA4\u89C6\u8BD5\u6536\u624B\u9996\u5B88\u5BFF"+ + "\u6388\u552E\u53D7\u7626\u517D\u852C\u67A2\u68B3"+ + "\u6B8A\u6292\u8F93\u53D4\u8212\u6DD1\u758F\u4E66"+ + "\u8D4E\u5B70\u719F\u85AF\u6691\u66D9\u7F72\u8700"+ + "\u9ECD\u9F20\u5C5E\u672F\u8FF0\u6811\u675F\u620D"+ + "\u7AD6\u5885\u5EB6\u6570\u6F31\u8582\u8583\u8586"+ + "\u8588\u8589\u858A\u858B\u858C\u858D\u858E\u8590"+ + "\u8591\u8592\u8593\u8594\u8595\u8596\u8597\u8598"+ + "\u8599\u859A\u859D\u859E\u859F\u85A0\u85A1\u85A2"+ + "\u85A3\u85A5\u85A6\u85A7\u85A9\u85AB\u85AC\u85AD"+ + "\u85B1\u85B2\u85B3\u85B4\u85B5\u85B6\u85B8\u85BA"+ + "\u85BB\u85BC\u85BD\u85BE\u85BF\u85C0\u85C2\u85C3"+ + "\u85C4\u85C5\u85C6\u85C7\u85C8\u85CA\u85CB\u85CC"+ + "\u85CD\u85CE\u85D1\u85D2\uFFFD\u85D4\u85D6\u85D7"+ + "\u85D8\u85D9\u85DA\u85DB\u85DD\u85DE\u85DF\u85E0"+ + "\u85E1\u85E2\u85E3\u85E5\u85E6\u85E7\u85E8\u85EA"+ + "\u85EB\u85EC\u85ED\u85EE\u85EF\u85F0\u85F1\u85F2"+ + "\u85F3\u85F4\u85F5\u85F6\u85F7\u85F8\u6055\u5237"+ + "\u800D\u6454\u8870\u7529\u5E05\u6813\u62F4\u971C"+ + "\u53CC\u723D\u8C01\u6C34\u7761\u7A0E\u542E\u77AC"+ + "\u987A\u821C\u8BF4\u7855\u6714\u70C1\u65AF\u6495"+ + "\u5636\u601D\u79C1\u53F8\u4E1D\u6B7B\u8086\u5BFA"+ + "\u55E3\u56DB\u4F3A\u4F3C\u9972\u5DF3\u677E\u8038"+ + "\u6002\u9882\u9001\u5B8B\u8BBC\u8BF5\u641C\u8258"+ + "\u64DE\u55FD\u82CF\u9165\u4FD7\u7D20\u901F\u7C9F"+ + "\u50F3\u5851\u6EAF\u5BBF\u8BC9\u8083\u9178\u849C"+ + "\u7B97\u867D\u968B\u968F\u7EE5\u9AD3\u788E\u5C81"+ + "\u7A57\u9042\u96A7\u795F\u5B59\u635F\u7B0B\u84D1"+ + "\u68AD\u5506\u7F29\u7410\u7D22\u9501\u6240\u584C"+ + "\u4ED6\u5B83\u5979\u5854\u85F9\u85FA\u85FC\u85FD"+ + "\u85FE\u8600\u8601\u8602\u8603\u8604\u8606\u8607"+ + "\u8608\u8609\u860A\u860B\u860C\u860D\u860E\u860F"+ + "\u8610\u8612\u8613\u8614\u8615\u8617\u8618\u8619"+ + "\u861A\u861B\u861C\u861D\u861E\u861F\u8620\u8621"+ + "\u8622\u8623\u8624\u8625\u8626\u8628\u862A\u862B"+ + "\u862C\u862D\u862E\u862F\u8630\u8631\u8632\u8633"+ + "\u8634\u8635\u8636\u8637\u8639\u863A\u863B\u863D"+ + "\u863E\u863F\u8640\uFFFD\u8641\u8642\u8643\u8644"+ + "\u8645\u8646\u8647\u8648\u8649\u864A\u864B\u864C"+ + "\u8652\u8653\u8655\u8656\u8657\u8658\u8659\u865B"+ + "\u865C\u865D\u865F\u8660\u8661\u8663\u8664\u8665"+ + "\u8666\u8667\u8668\u8669\u866A\u736D\u631E\u8E4B"+ + "\u8E0F\u80CE\u82D4\u62AC\u53F0\u6CF0\u915E\u592A"+ + "\u6001\u6C70\u574D\u644A\u8D2A\u762B\u6EE9\u575B"+ + "\u6A80\u75F0\u6F6D\u8C2D\u8C08\u5766\u6BEF\u8892"+ + "\u78B3\u63A2\u53F9\u70AD\u6C64\u5858\u642A\u5802"+ + "\u68E0\u819B\u5510\u7CD6\u5018\u8EBA\u6DCC\u8D9F"+ + "\u70EB\u638F\u6D9B\u6ED4\u7EE6\u8404\u6843\u9003"+ + "\u6DD8\u9676\u8BA8\u5957\u7279\u85E4\u817E\u75BC"+ + "\u8A8A\u68AF\u5254\u8E22\u9511\u63D0\u9898\u8E44"+ + "\u557C\u4F53\u66FF\u568F\u60D5\u6D95\u5243\u5C49"+ + "\u5929\u6DFB\u586B\u7530\u751C\u606C\u8214\u8146"+ + "\u6311\u6761\u8FE2\u773A\u8DF3\u8D34\u94C1\u5E16"+ + "\u5385\u542C\u70C3\u866D\u866F\u8670\u8672\u8673"+ + "\u8674\u8675\u8676\u8677\u8678\u8683\u8684\u8685"+ + "\u8686\u8687\u8688\u8689\u868E\u868F\u8690\u8691"+ + "\u8692\u8694\u8696\u8697\u8698\u8699\u869A\u869B"+ + "\u869E\u869F\u86A0\u86A1\u86A2\u86A5\u86A6\u86AB"+ + "\u86AD\u86AE\u86B2\u86B3\u86B7\u86B8\u86B9\u86BB"+ + "\u86BC\u86BD\u86BE\u86BF\u86C1\u86C2\u86C3\u86C5"+ + "\u86C8\u86CC\u86CD\u86D2\u86D3\u86D5\u86D6\u86D7"+ + "\u86DA\u86DC\uFFFD\u86DD\u86E0\u86E1\u86E2\u86E3"+ + "\u86E5\u86E6\u86E7\u86E8\u86EA\u86EB\u86EC\u86EF"+ + "\u86F5\u86F6\u86F7\u86FA\u86FB\u86FC\u86FD\u86FF"+ + "\u8701\u8704\u8705\u8706\u870B\u870C\u870E\u870F"+ + "\u8710\u8711\u8714\u8716\u6C40\u5EF7\u505C\u4EAD"+ + "\u5EAD\u633A\u8247\u901A\u6850\u916E\u77B3\u540C"+ + "\u94DC\u5F64\u7AE5\u6876\u6345\u7B52\u7EDF\u75DB"+ + "\u5077\u6295\u5934\u900F\u51F8\u79C3\u7A81\u56FE"+ + "\u5F92\u9014\u6D82\u5C60\u571F\u5410\u5154\u6E4D"+ + "\u56E2\u63A8\u9893\u817F\u8715\u892A\u9000\u541E"+ + "\u5C6F\u81C0\u62D6\u6258\u8131\u9E35\u9640\u9A6E"+ + "\u9A7C\u692D\u59A5\u62D3\u553E\u6316\u54C7\u86D9"+ + "\u6D3C\u5A03\u74E6\u889C\u6B6A\u5916\u8C4C\u5F2F"+ + "\u6E7E\u73A9\u987D\u4E38\u70F7\u5B8C\u7897\u633D"+ + "\u665A\u7696\u60CB\u5B9B\u5A49\u4E07\u8155\u6C6A"+ + "\u738B\u4EA1\u6789\u7F51\u5F80\u65FA\u671B\u5FD8"+ + "\u5984\u5A01\u8719\u871B\u871D\u871F\u8720\u8724"+ + "\u8726\u8727\u8728\u872A\u872B\u872C\u872D\u872F"+ + "\u8730\u8732\u8733\u8735\u8736\u8738\u8739\u873A"+ + "\u873C\u873D\u8740\u8741\u8742\u8743\u8744\u8745"+ + "\u8746\u874A\u874B\u874D\u874F\u8750\u8751\u8752"+ + "\u8754\u8755\u8756\u8758\u875A\u875B\u875C\u875D"+ + "\u875E\u875F\u8761\u8762\u8766\u8767\u8768\u8769"+ + "\u876A\u876B\u876C\u876D\u876F\u8771\u8772\u8773"+ + "\u8775\uFFFD\u8777\u8778\u8779\u877A\u877F\u8780"+ + "\u8781\u8784\u8786\u8787\u8789\u878A\u878C\u878E"+ + "\u878F\u8790\u8791\u8792\u8794\u8795\u8796\u8798"+ + "\u8799\u879A\u879B\u879C\u879D\u879E\u87A0\u87A1"+ + "\u87A2\u87A3\u87A4\u5DCD\u5FAE\u5371\u97E6\u8FDD"+ + "\u6845\u56F4\u552F\u60DF\u4E3A\u6F4D\u7EF4\u82C7"+ + "\u840E\u59D4\u4F1F\u4F2A\u5C3E\u7EAC\u672A\u851A"+ + "\u5473\u754F\u80C3\u5582\u9B4F\u4F4D\u6E2D\u8C13"+ + "\u5C09\u6170\u536B\u761F\u6E29\u868A\u6587\u95FB"+ + "\u7EB9\u543B\u7A33\u7D0A\u95EE\u55E1\u7FC1\u74EE"+ + "\u631D\u8717\u6DA1\u7A9D\u6211\u65A1\u5367\u63E1"+ + "\u6C83\u5DEB\u545C\u94A8\u4E4C\u6C61\u8BEC\u5C4B"+ + "\u65E0\u829C\u68A7\u543E\u5434\u6BCB\u6B66\u4E94"+ + "\u6342\u5348\u821E\u4F0D\u4FAE\u575E\u620A\u96FE"+ + "\u6664\u7269\u52FF\u52A1\u609F\u8BEF\u6614\u7199"+ + "\u6790\u897F\u7852\u77FD\u6670\u563B\u5438\u9521"+ + "\u727A\u87A5\u87A6\u87A7\u87A9\u87AA\u87AE\u87B0"+ + "\u87B1\u87B2\u87B4\u87B6\u87B7\u87B8\u87B9\u87BB"+ + "\u87BC\u87BE\u87BF\u87C1\u87C2\u87C3\u87C4\u87C5"+ + "\u87C7\u87C8\u87C9\u87CC\u87CD\u87CE\u87CF\u87D0"+ + "\u87D4\u87D5\u87D6\u87D7\u87D8\u87D9\u87DA\u87DC"+ + "\u87DD\u87DE\u87DF\u87E1\u87E2\u87E3\u87E4\u87E6"+ + "\u87E7\u87E8\u87E9\u87EB\u87EC\u87ED\u87EF\u87F0"+ + "\u87F1\u87F2\u87F3\u87F4\u87F5\u87F6\u87F7\u87F8"+ + "\uFFFD\u87FA\u87FB\u87FC\u87FD\u87FF\u8800\u8801"+ + "\u8802\u8804\u8805\u8806\u8807\u8808\u8809\u880B"+ + "\u880C\u880D\u880E\u880F\u8810\u8811\u8812\u8814"+ + "\u8817\u8818\u8819\u881A\u881C\u881D\u881E\u881F"+ + "\u8820\u8823\u7A00\u606F\u5E0C\u6089\u819D\u5915"+ + "\u60DC\u7184\u70EF\u6EAA\u6C50\u7280\u6A84\u88AD"+ + "\u5E2D\u4E60\u5AB3\u559C\u94E3\u6D17\u7CFB\u9699"+ + "\u620F\u7EC6\u778E\u867E\u5323\u971E\u8F96\u6687"+ + "\u5CE1\u4FA0\u72ED\u4E0B\u53A6\u590F\u5413\u6380"+ + "\u9528\u5148\u4ED9\u9C9C\u7EA4\u54B8\u8D24\u8854"+ + "\u8237\u95F2\u6D8E\u5F26\u5ACC\u663E\u9669\u73B0"+ + "\u732E\u53BF\u817A\u9985\u7FA1\u5BAA\u9677\u9650"+ + "\u7EBF\u76F8\u53A2\u9576\u9999\u7BB1\u8944\u6E58"+ + "\u4E61\u7FD4\u7965\u8BE6\u60F3\u54CD\u4EAB\u9879"+ + "\u5DF7\u6A61\u50CF\u5411\u8C61\u8427\u785D\u9704"+ + "\u524A\u54EE\u56A3\u9500\u6D88\u5BB5\u6DC6\u6653"; + + private static final String innerIndex5= + "\u8824\u8825\u8826\u8827\u8828\u8829\u882A\u882B"+ + "\u882C\u882D\u882E\u882F\u8830\u8831\u8833\u8834"+ + "\u8835\u8836\u8837\u8838\u883A\u883B\u883D\u883E"+ + "\u883F\u8841\u8842\u8843\u8846\u8847\u8848\u8849"+ + "\u884A\u884B\u884E\u884F\u8850\u8851\u8852\u8853"+ + "\u8855\u8856\u8858\u885A\u885B\u885C\u885D\u885E"+ + "\u885F\u8860\u8866\u8867\u886A\u886D\u886F\u8871"+ + "\u8873\u8874\u8875\u8876\u8878\u8879\u887A\uFFFD"+ + "\u887B\u887C\u8880\u8883\u8886\u8887\u8889\u888A"+ + "\u888C\u888E\u888F\u8890\u8891\u8893\u8894\u8895"+ + "\u8897\u8898\u8899\u889A\u889B\u889D\u889E\u889F"+ + "\u88A0\u88A1\u88A3\u88A5\u88A6\u88A7\u88A8\u88A9"+ + "\u88AA\u5C0F\u5B5D\u6821\u8096\u5578\u7B11\u6548"+ + "\u6954\u4E9B\u6B47\u874E\u978B\u534F\u631F\u643A"+ + "\u90AA\u659C\u80C1\u8C10\u5199\u68B0\u5378\u87F9"+ + "\u61C8\u6CC4\u6CFB\u8C22\u5C51\u85AA\u82AF\u950C"+ + "\u6B23\u8F9B\u65B0\u5FFB\u5FC3\u4FE1\u8845\u661F"+ + "\u8165\u7329\u60FA\u5174\u5211\u578B\u5F62\u90A2"+ + "\u884C\u9192\u5E78\u674F\u6027\u59D3\u5144\u51F6"+ + "\u80F8\u5308\u6C79\u96C4\u718A\u4F11\u4FEE\u7F9E"+ + "\u673D\u55C5\u9508\u79C0\u8896\u7EE3\u589F\u620C"+ + "\u9700\u865A\u5618\u987B\u5F90\u8BB8\u84C4\u9157"+ + "\u53D9\u65ED\u5E8F\u755C\u6064\u7D6E\u5A7F\u7EEA"+ + "\u7EED\u8F69\u55A7\u5BA3\u60AC\u65CB\u7384\u88AC"+ + "\u88AE\u88AF\u88B0\u88B2\u88B3\u88B4\u88B5\u88B6"+ + "\u88B8\u88B9\u88BA\u88BB\u88BD\u88BE\u88BF\u88C0"+ + "\u88C3\u88C4\u88C7\u88C8\u88CA\u88CB\u88CC\u88CD"+ + "\u88CF\u88D0\u88D1\u88D3\u88D6\u88D7\u88DA\u88DB"+ + "\u88DC\u88DD\u88DE\u88E0\u88E1\u88E6\u88E7\u88E9"+ + "\u88EA\u88EB\u88EC\u88ED\u88EE\u88EF\u88F2\u88F5"+ + "\u88F6\u88F7\u88FA\u88FB\u88FD\u88FF\u8900\u8901"+ + "\u8903\u8904\u8905\u8906\u8907\u8908\uFFFD\u8909"+ + "\u890B\u890C\u890D\u890E\u890F\u8911\u8914\u8915"+ + "\u8916\u8917\u8918\u891C\u891D\u891E\u891F\u8920"+ + "\u8922\u8923\u8924\u8926\u8927\u8928\u8929\u892C"+ + "\u892D\u892E\u892F\u8931\u8932\u8933\u8935\u8937"+ + "\u9009\u7663\u7729\u7EDA\u9774\u859B\u5B66\u7A74"+ + "\u96EA\u8840\u52CB\u718F\u5FAA\u65EC\u8BE2\u5BFB"+ + "\u9A6F\u5DE1\u6B89\u6C5B\u8BAD\u8BAF\u900A\u8FC5"+ + "\u538B\u62BC\u9E26\u9E2D\u5440\u4E2B\u82BD\u7259"+ + "\u869C\u5D16\u8859\u6DAF\u96C5\u54D1\u4E9A\u8BB6"+ + "\u7109\u54BD\u9609\u70DF\u6DF9\u76D0\u4E25\u7814"+ + "\u8712\u5CA9\u5EF6\u8A00\u989C\u960E\u708E\u6CBF"+ + "\u5944\u63A9\u773C\u884D\u6F14\u8273\u5830\u71D5"+ + "\u538C\u781A\u96C1\u5501\u5F66\u7130\u5BB4\u8C1A"+ + "\u9A8C\u6B83\u592E\u9E2F\u79E7\u6768\u626C\u4F6F"+ + "\u75A1\u7F8A\u6D0B\u9633\u6C27\u4EF0\u75D2\u517B"+ + "\u6837\u6F3E\u9080\u8170\u5996\u7476\u8938\u8939"+ + "\u893A\u893B\u893C\u893D\u893E\u893F\u8940\u8942"+ + "\u8943\u8945\u8946\u8947\u8948\u8949\u894A\u894B"+ + "\u894C\u894D\u894E\u894F\u8950\u8951\u8952\u8953"+ + "\u8954\u8955\u8956\u8957\u8958\u8959\u895A\u895B"+ + "\u895C\u895D\u8960\u8961\u8962\u8963\u8964\u8965"+ + "\u8967\u8968\u8969\u896A\u896B\u896C\u896D\u896E"+ + "\u896F\u8970\u8971\u8972\u8973\u8974\u8975\u8976"+ + "\u8977\u8978\u8979\u897A\u897C\uFFFD\u897D\u897E"+ + "\u8980\u8982\u8984\u8985\u8987\u8988\u8989\u898A"+ + "\u898B\u898C\u898D\u898E\u898F\u8990\u8991\u8992"+ + "\u8993\u8994\u8995\u8996\u8997\u8998\u8999\u899A"+ + "\u899B\u899C\u899D\u899E\u899F\u89A0\u89A1\u6447"+ + "\u5C27\u9065\u7A91\u8C23\u59DA\u54AC\u8200\u836F"+ + "\u8981\u8000\u6930\u564E\u8036\u7237\u91CE\u51B6"+ + "\u4E5F\u9875\u6396\u4E1A\u53F6\u66F3\u814B\u591C"+ + "\u6DB2\u4E00\u58F9\u533B\u63D6\u94F1\u4F9D\u4F0A"+ + "\u8863\u9890\u5937\u9057\u79FB\u4EEA\u80F0\u7591"+ + "\u6C82\u5B9C\u59E8\u5F5D\u6905\u8681\u501A\u5DF2"+ + "\u4E59\u77E3\u4EE5\u827A\u6291\u6613\u9091\u5C79"+ + "\u4EBF\u5F79\u81C6\u9038\u8084\u75AB\u4EA6\u88D4"+ + "\u610F\u6BC5\u5FC6\u4E49\u76CA\u6EA2\u8BE3\u8BAE"+ + "\u8C0A\u8BD1\u5F02\u7FFC\u7FCC\u7ECE\u8335\u836B"+ + "\u56E0\u6BB7\u97F3\u9634\u59FB\u541F\u94F6\u6DEB"+ + "\u5BC5\u996E\u5C39\u5F15\u9690\u89A2\u89A3\u89A4"+ + "\u89A5\u89A6\u89A7\u89A8\u89A9\u89AA\u89AB\u89AC"+ + "\u89AD\u89AE\u89AF\u89B0\u89B1\u89B2\u89B3\u89B4"+ + "\u89B5\u89B6\u89B7\u89B8\u89B9\u89BA\u89BB\u89BC"+ + "\u89BD\u89BE\u89BF\u89C0\u89C3\u89CD\u89D3\u89D4"+ + "\u89D5\u89D7\u89D8\u89D9\u89DB\u89DD\u89DF\u89E0"+ + "\u89E1\u89E2\u89E4\u89E7\u89E8\u89E9\u89EA\u89EC"+ + "\u89ED\u89EE\u89F0\u89F1\u89F2\u89F4\u89F5\u89F6"+ + "\u89F7\u89F8\u89F9\u89FA\uFFFD\u89FB\u89FC\u89FD"+ + "\u89FE\u89FF\u8A01\u8A02\u8A03\u8A04\u8A05\u8A06"+ + "\u8A08\u8A09\u8A0A\u8A0B\u8A0C\u8A0D\u8A0E\u8A0F"+ + "\u8A10\u8A11\u8A12\u8A13\u8A14\u8A15\u8A16\u8A17"+ + "\u8A18\u8A19\u8A1A\u8A1B\u8A1C\u8A1D\u5370\u82F1"+ + "\u6A31\u5A74\u9E70\u5E94\u7F28\u83B9\u8424\u8425"+ + "\u8367\u8747\u8FCE\u8D62\u76C8\u5F71\u9896\u786C"+ + "\u6620\u54DF\u62E5\u4F63\u81C3\u75C8\u5EB8\u96CD"+ + "\u8E0A\u86F9\u548F\u6CF3\u6D8C\u6C38\u607F\u52C7"+ + "\u7528\u5E7D\u4F18\u60A0\u5FE7\u5C24\u7531\u90AE"+ + "\u94C0\u72B9\u6CB9\u6E38\u9149\u6709\u53CB\u53F3"+ + "\u4F51\u91C9\u8BF1\u53C8\u5E7C\u8FC2\u6DE4\u4E8E"+ + "\u76C2\u6986\u865E\u611A\u8206\u4F59\u4FDE\u903E"+ + "\u9C7C\u6109\u6E1D\u6E14\u9685\u4E88\u5A31\u96E8"+ + "\u4E0E\u5C7F\u79B9\u5B87\u8BED\u7FBD\u7389\u57DF"+ + "\u828B\u90C1\u5401\u9047\u55BB\u5CEA\u5FA1\u6108"+ + "\u6B32\u72F1\u80B2\u8A89\u8A1E\u8A1F\u8A20\u8A21"+ + "\u8A22\u8A23\u8A24\u8A25\u8A26\u8A27\u8A28\u8A29"+ + "\u8A2A\u8A2B\u8A2C\u8A2D\u8A2E\u8A2F\u8A30\u8A31"+ + "\u8A32\u8A33\u8A34\u8A35\u8A36\u8A37\u8A38\u8A39"+ + "\u8A3A\u8A3B\u8A3C\u8A3D\u8A3F\u8A40\u8A41\u8A42"+ + "\u8A43\u8A44\u8A45\u8A46\u8A47\u8A49\u8A4A\u8A4B"+ + "\u8A4C\u8A4D\u8A4E\u8A4F\u8A50\u8A51\u8A52\u8A53"+ + "\u8A54\u8A55\u8A56\u8A57\u8A58\u8A59\u8A5A\u8A5B"+ + "\u8A5C\u8A5D\u8A5E\uFFFD\u8A5F\u8A60\u8A61\u8A62"+ + "\u8A63\u8A64\u8A65\u8A66\u8A67\u8A68\u8A69\u8A6A"+ + "\u8A6B\u8A6C\u8A6D\u8A6E\u8A6F\u8A70\u8A71\u8A72"+ + "\u8A73\u8A74\u8A75\u8A76\u8A77\u8A78\u8A7A\u8A7B"+ + "\u8A7C\u8A7D\u8A7E\u8A7F\u8A80\u6D74\u5BD3\u88D5"+ + "\u9884\u8C6B\u9A6D\u9E33\u6E0A\u51A4\u5143\u57A3"+ + "\u8881\u539F\u63F4\u8F95\u56ED\u5458\u5706\u733F"+ + "\u6E90\u7F18\u8FDC\u82D1\u613F\u6028\u9662\u66F0"+ + "\u7EA6\u8D8A\u8DC3\u94A5\u5CB3\u7CA4\u6708\u60A6"+ + "\u9605\u8018\u4E91\u90E7\u5300\u9668\u5141\u8FD0"+ + "\u8574\u915D\u6655\u97F5\u5B55\u531D\u7838\u6742"+ + "\u683D\u54C9\u707E\u5BB0\u8F7D\u518D\u5728\u54B1"+ + "\u6512\u6682\u8D5E\u8D43\u810F\u846C\u906D\u7CDF"+ + "\u51FF\u85FB\u67A3\u65E9\u6FA1\u86A4\u8E81\u566A"+ + "\u9020\u7682\u7076\u71E5\u8D23\u62E9\u5219\u6CFD"+ + "\u8D3C\u600E\u589E\u618E\u66FE\u8D60\u624E\u55B3"+ + "\u6E23\u672D\u8F67\u8A81\u8A82\u8A83\u8A84\u8A85"+ + "\u8A86\u8A87\u8A88\u8A8B\u8A8C\u8A8D\u8A8E\u8A8F"+ + "\u8A90\u8A91\u8A92\u8A94\u8A95\u8A96\u8A97\u8A98"+ + "\u8A99\u8A9A\u8A9B\u8A9C\u8A9D\u8A9E\u8A9F\u8AA0"+ + "\u8AA1\u8AA2\u8AA3\u8AA4\u8AA5\u8AA6\u8AA7\u8AA8"+ + "\u8AA9\u8AAA\u8AAB\u8AAC\u8AAD\u8AAE\u8AAF\u8AB0"+ + "\u8AB1\u8AB2\u8AB3\u8AB4\u8AB5\u8AB6\u8AB7\u8AB8"+ + "\u8AB9\u8ABA\u8ABB\u8ABC\u8ABD\u8ABE\u8ABF\u8AC0"+ + "\u8AC1\u8AC2\uFFFD\u8AC3\u8AC4\u8AC5\u8AC6\u8AC7"+ + "\u8AC8\u8AC9\u8ACA\u8ACB\u8ACC\u8ACD\u8ACE\u8ACF"+ + "\u8AD0\u8AD1\u8AD2\u8AD3\u8AD4\u8AD5\u8AD6\u8AD7"+ + "\u8AD8\u8AD9\u8ADA\u8ADB\u8ADC\u8ADD\u8ADE\u8ADF"+ + "\u8AE0\u8AE1\u8AE2\u8AE3\u94E1\u95F8\u7728\u6805"+ + "\u69A8\u548B\u4E4D\u70B8\u8BC8\u6458\u658B\u5B85"+ + "\u7A84\u503A\u5BE8\u77BB\u6BE1\u8A79\u7C98\u6CBE"+ + "\u76CF\u65A9\u8F97\u5D2D\u5C55\u8638\u6808\u5360"+ + "\u6218\u7AD9\u6E5B\u7EFD\u6A1F\u7AE0\u5F70\u6F33"+ + "\u5F20\u638C\u6DA8\u6756\u4E08\u5E10\u8D26\u4ED7"+ + "\u80C0\u7634\u969C\u62DB\u662D\u627E\u6CBC\u8D75"+ + "\u7167\u7F69\u5146\u8087\u53EC\u906E\u6298\u54F2"+ + "\u86F0\u8F99\u8005\u9517\u8517\u8FD9\u6D59\u73CD"+ + "\u659F\u771F\u7504\u7827\u81FB\u8D1E\u9488\u4FA6"+ + "\u6795\u75B9\u8BCA\u9707\u632F\u9547\u9635\u84B8"+ + "\u6323\u7741\u5F81\u72F0\u4E89\u6014\u6574\u62EF"+ + "\u6B63\u653F\u8AE4\u8AE5\u8AE6\u8AE7\u8AE8\u8AE9"+ + "\u8AEA\u8AEB\u8AEC\u8AED\u8AEE\u8AEF\u8AF0\u8AF1"+ + "\u8AF2\u8AF3\u8AF4\u8AF5\u8AF6\u8AF7\u8AF8\u8AF9"+ + "\u8AFA\u8AFB\u8AFC\u8AFD\u8AFE\u8AFF\u8B00\u8B01"+ + "\u8B02\u8B03\u8B04\u8B05\u8B06\u8B08\u8B09\u8B0A"+ + "\u8B0B\u8B0C\u8B0D\u8B0E\u8B0F\u8B10\u8B11\u8B12"+ + "\u8B13\u8B14\u8B15\u8B16\u8B17\u8B18\u8B19\u8B1A"+ + "\u8B1B\u8B1C\u8B1D\u8B1E\u8B1F\u8B20\u8B21\u8B22"+ + "\u8B23\uFFFD\u8B24\u8B25\u8B27\u8B28\u8B29\u8B2A"+ + "\u8B2B\u8B2C\u8B2D\u8B2E\u8B2F\u8B30\u8B31\u8B32"+ + "\u8B33\u8B34\u8B35\u8B36\u8B37\u8B38\u8B39\u8B3A"+ + "\u8B3B\u8B3C\u8B3D\u8B3E\u8B3F\u8B40\u8B41\u8B42"+ + "\u8B43\u8B44\u8B45\u5E27\u75C7\u90D1\u8BC1\u829D"+ + "\u679D\u652F\u5431\u8718\u77E5\u80A2\u8102\u6C41"+ + "\u4E4B\u7EC7\u804C\u76F4\u690D\u6B96\u6267\u503C"+ + "\u4F84\u5740\u6307\u6B62\u8DBE\u53EA\u65E8\u7EB8"+ + "\u5FD7\u631A\u63B7\u81F3\u81F4\u7F6E\u5E1C\u5CD9"+ + "\u5236\u667A\u79E9\u7A1A\u8D28\u7099\u75D4\u6EDE"+ + "\u6CBB\u7A92\u4E2D\u76C5\u5FE0\u949F\u8877\u7EC8"+ + "\u79CD\u80BF\u91CD\u4EF2\u4F17\u821F\u5468\u5DDE"+ + "\u6D32\u8BCC\u7CA5\u8F74\u8098\u5E1A\u5492\u76B1"+ + "\u5B99\u663C\u9AA4\u73E0\u682A\u86DB\u6731\u732A"+ + "\u8BF8\u8BDB\u9010\u7AF9\u70DB\u716E\u62C4\u77A9"+ + "\u5631\u4E3B\u8457\u67F1\u52A9\u86C0\u8D2E\u94F8"+ + "\u7B51\u8B46\u8B47\u8B48\u8B49\u8B4A\u8B4B\u8B4C"+ + "\u8B4D\u8B4E\u8B4F\u8B50\u8B51\u8B52\u8B53\u8B54"+ + "\u8B55\u8B56\u8B57\u8B58\u8B59\u8B5A\u8B5B\u8B5C"+ + "\u8B5D\u8B5E\u8B5F\u8B60\u8B61\u8B62\u8B63\u8B64"+ + "\u8B65\u8B67\u8B68\u8B69\u8B6A\u8B6B\u8B6D\u8B6E"+ + "\u8B6F\u8B70\u8B71\u8B72\u8B73\u8B74\u8B75\u8B76"+ + "\u8B77\u8B78\u8B79\u8B7A\u8B7B\u8B7C\u8B7D\u8B7E"+ + "\u8B7F\u8B80\u8B81\u8B82\u8B83\u8B84\u8B85\u8B86"+ + "\uFFFD\u8B87\u8B88\u8B89\u8B8A\u8B8B\u8B8C\u8B8D"+ + "\u8B8E\u8B8F\u8B90\u8B91\u8B92\u8B93\u8B94\u8B95"+ + "\u8B96\u8B97\u8B98\u8B99\u8B9A\u8B9B\u8B9C\u8B9D"+ + "\u8B9E\u8B9F\u8BAC\u8BB1\u8BBB\u8BC7\u8BD0\u8BEA"+ + "\u8C09\u8C1E\u4F4F\u6CE8\u795D\u9A7B\u6293\u722A"+ + "\u62FD\u4E13\u7816\u8F6C\u64B0\u8D5A\u7BC6\u6869"+ + "\u5E84\u88C5\u5986\u649E\u58EE\u72B6\u690E\u9525"+ + "\u8FFD\u8D58\u5760\u7F00\u8C06\u51C6\u6349\u62D9"+ + "\u5353\u684C\u7422\u8301\u914C\u5544\u7740\u707C"+ + "\u6D4A\u5179\u54A8\u8D44\u59FF\u6ECB\u6DC4\u5B5C"+ + "\u7D2B\u4ED4\u7C7D\u6ED3\u5B50\u81EA\u6E0D\u5B57"+ + "\u9B03\u68D5\u8E2A\u5B97\u7EFC\u603B\u7EB5\u90B9"+ + "\u8D70\u594F\u63CD\u79DF\u8DB3\u5352\u65CF\u7956"+ + "\u8BC5\u963B\u7EC4\u94BB\u7E82\u5634\u9189\u6700"+ + "\u7F6A\u5C0A\u9075\u6628\u5DE6\u4F50\u67DE\u505A"+ + "\u4F5C\u5750\u5EA7\uE810\uE811\uE812\uE813\uE814"+ + "\u8C38\u8C39\u8C3A\u8C3B\u8C3C\u8C3D\u8C3E\u8C3F"+ + "\u8C40\u8C42\u8C43\u8C44\u8C45\u8C48\u8C4A\u8C4B"+ + "\u8C4D\u8C4E\u8C4F\u8C50\u8C51\u8C52\u8C53\u8C54"+ + "\u8C56\u8C57\u8C58\u8C59\u8C5B\u8C5C\u8C5D\u8C5E"+ + "\u8C5F\u8C60\u8C63\u8C64\u8C65\u8C66\u8C67\u8C68"+ + "\u8C69\u8C6C\u8C6D\u8C6E\u8C6F\u8C70\u8C71\u8C72"+ + "\u8C74\u8C75\u8C76\u8C77\u8C7B\u8C7C\u8C7D\u8C7E"+ + "\u8C7F\u8C80\u8C81\u8C83\u8C84\u8C86\u8C87\uFFFD"+ + "\u8C88\u8C8B\u8C8D\u8C8E\u8C8F\u8C90\u8C91\u8C92"+ + "\u8C93\u8C95\u8C96\u8C97\u8C99\u8C9A\u8C9B\u8C9C"+ + "\u8C9D\u8C9E\u8C9F\u8CA0\u8CA1\u8CA2\u8CA3\u8CA4"+ + "\u8CA5\u8CA6\u8CA7\u8CA8\u8CA9\u8CAA\u8CAB\u8CAC"+ + "\u8CAD\u4E8D\u4E0C\u5140\u4E10\u5EFF\u5345\u4E15"+ + "\u4E98\u4E1E\u9B32\u5B6C\u5669\u4E28\u79BA\u4E3F"+ + "\u5315\u4E47\u592D\u723B\u536E\u6C10\u56DF\u80E4"+ + "\u9997\u6BD3\u777E\u9F17\u4E36\u4E9F\u9F10\u4E5C"+ + "\u4E69\u4E93\u8288\u5B5B\u556C\u560F\u4EC4\u538D"+ + "\u539D\u53A3\u53A5\u53AE\u9765\u8D5D\u531A\u53F5"+ + "\u5326\u532E\u533E\u8D5C\u5366\u5363\u5202\u5208"+ + "\u520E\u522D\u5233\u523F\u5240\u524C\u525E\u5261"+ + "\u525C\u84AF\u527D\u5282\u5281\u5290\u5293\u5182"+ + "\u7F54\u4EBB\u4EC3\u4EC9\u4EC2\u4EE8\u4EE1\u4EEB"+ + "\u4EDE\u4F1B\u4EF3\u4F22\u4F64\u4EF5\u4F25\u4F27"+ + "\u4F09\u4F2B\u4F5E\u4F67\u6538\u4F5A\u4F5D\u8CAE"+ + "\u8CAF\u8CB0\u8CB1\u8CB2\u8CB3\u8CB4\u8CB5\u8CB6"+ + "\u8CB7\u8CB8\u8CB9\u8CBA\u8CBB\u8CBC\u8CBD\u8CBE"+ + "\u8CBF\u8CC0\u8CC1\u8CC2\u8CC3\u8CC4\u8CC5\u8CC6"+ + "\u8CC7\u8CC8\u8CC9\u8CCA\u8CCB\u8CCC\u8CCD\u8CCE"+ + "\u8CCF\u8CD0\u8CD1\u8CD2\u8CD3\u8CD4\u8CD5\u8CD6"+ + "\u8CD7\u8CD8\u8CD9\u8CDA\u8CDB\u8CDC\u8CDD\u8CDE"+ + "\u8CDF\u8CE0\u8CE1\u8CE2\u8CE3\u8CE4\u8CE5\u8CE6"+ + "\u8CE7\u8CE8\u8CE9\u8CEA\u8CEB\u8CEC\uFFFD\u8CED"+ + "\u8CEE\u8CEF\u8CF0\u8CF1\u8CF2\u8CF3\u8CF4\u8CF5"+ + "\u8CF6\u8CF7\u8CF8\u8CF9\u8CFA\u8CFB\u8CFC\u8CFD"+ + "\u8CFE\u8CFF\u8D00\u8D01\u8D02\u8D03\u8D04\u8D05"+ + "\u8D06\u8D07\u8D08\u8D09\u8D0A\u8D0B\u8D0C\u8D0D"+ + "\u4F5F\u4F57\u4F32\u4F3D\u4F76\u4F74\u4F91\u4F89"+ + "\u4F83\u4F8F\u4F7E\u4F7B\u4FAA\u4F7C\u4FAC\u4F94"+ + "\u4FE6\u4FE8\u4FEA\u4FC5\u4FDA\u4FE3\u4FDC\u4FD1"+ + "\u4FDF\u4FF8\u5029\u504C\u4FF3\u502C\u500F\u502E"+ + "\u502D\u4FFE\u501C\u500C\u5025\u5028\u507E\u5043"+ + "\u5055\u5048\u504E\u506C\u507B\u50A5\u50A7\u50A9"+ + "\u50BA\u50D6\u5106\u50ED\u50EC\u50E6\u50EE\u5107"+ + "\u510B\u4EDD\u6C3D\u4F58\u4F65\u4FCE\u9FA0\u6C46"+ + "\u7C74\u516E\u5DFD\u9EC9\u9998\u5181\u5914\u52F9"+ + "\u530D\u8A07\u5310\u51EB\u5919\u5155\u4EA0\u5156"+ + "\u4EB3\u886E\u88A4\u4EB5\u8114\u88D2\u7980\u5B34"+ + "\u8803\u7FB8\u51AB\u51B1\u51BD\u51BC\u8D0E\u8D0F"+ + "\u8D10\u8D11\u8D12\u8D13\u8D14\u8D15\u8D16\u8D17"+ + "\u8D18\u8D19\u8D1A\u8D1B\u8D1C\u8D20\u8D51\u8D52"+ + "\u8D57\u8D5F\u8D65\u8D68\u8D69\u8D6A\u8D6C\u8D6E"+ + "\u8D6F\u8D71\u8D72\u8D78\u8D79\u8D7A\u8D7B\u8D7C"+ + "\u8D7D\u8D7E\u8D7F\u8D80\u8D82\u8D83\u8D86\u8D87"+ + "\u8D88\u8D89\u8D8C\u8D8D\u8D8E\u8D8F\u8D90\u8D92"+ + "\u8D93\u8D95\u8D96\u8D97\u8D98\u8D99\u8D9A\u8D9B"+ + "\u8D9C\u8D9D\u8D9E\u8DA0\u8DA1\uFFFD\u8DA2\u8DA4"+ + "\u8DA5\u8DA6\u8DA7\u8DA8\u8DA9\u8DAA\u8DAB\u8DAC"+ + "\u8DAD\u8DAE\u8DAF\u8DB0\u8DB2\u8DB6\u8DB7\u8DB9"+ + "\u8DBB\u8DBD\u8DC0\u8DC1\u8DC2\u8DC5\u8DC7\u8DC8"+ + "\u8DC9\u8DCA\u8DCD\u8DD0\u8DD2\u8DD3\u8DD4\u51C7"+ + "\u5196\u51A2\u51A5\u8BA0\u8BA6\u8BA7\u8BAA\u8BB4"+ + "\u8BB5\u8BB7\u8BC2\u8BC3\u8BCB\u8BCF\u8BCE\u8BD2"+ + "\u8BD3\u8BD4\u8BD6\u8BD8\u8BD9\u8BDC\u8BDF\u8BE0"+ + "\u8BE4\u8BE8\u8BE9\u8BEE\u8BF0\u8BF3\u8BF6\u8BF9"+ + "\u8BFC\u8BFF\u8C00\u8C02\u8C04\u8C07\u8C0C\u8C0F"+ + "\u8C11\u8C12\u8C14\u8C15\u8C16\u8C19\u8C1B\u8C18"+ + "\u8C1D\u8C1F\u8C20\u8C21\u8C25\u8C27\u8C2A\u8C2B"+ + "\u8C2E\u8C2F\u8C32\u8C33\u8C35\u8C36\u5369\u537A"+ + "\u961D\u9622\u9621\u9631\u962A\u963D\u963C\u9642"+ + "\u9649\u9654\u965F\u9667\u966C\u9672\u9674\u9688"+ + "\u968D\u9697\u96B0\u9097\u909B\u909D\u9099\u90AC"+ + "\u90A1\u90B4\u90B3\u90B6\u90BA\u8DD5\u8DD8\u8DD9"+ + "\u8DDC\u8DE0\u8DE1\u8DE2\u8DE5\u8DE6\u8DE7\u8DE9"+ + "\u8DED\u8DEE\u8DF0\u8DF1\u8DF2\u8DF4\u8DF6\u8DFC"+ + "\u8DFE\u8DFF\u8E00\u8E01\u8E02\u8E03\u8E04\u8E06"+ + "\u8E07\u8E08\u8E0B\u8E0D\u8E0E\u8E10\u8E11\u8E12"+ + "\u8E13\u8E15\u8E16\u8E17\u8E18\u8E19\u8E1A\u8E1B"+ + "\u8E1C\u8E20\u8E21\u8E24\u8E25\u8E26\u8E27\u8E28"+ + "\u8E2B\u8E2D\u8E30\u8E32\u8E33\u8E34\u8E36\u8E37"+ + "\u8E38\u8E3B\u8E3C\u8E3E\uFFFD\u8E3F\u8E43\u8E45"+ + "\u8E46\u8E4C\u8E4D\u8E4E\u8E4F\u8E50\u8E53\u8E54"+ + "\u8E55\u8E56\u8E57\u8E58\u8E5A\u8E5B\u8E5C\u8E5D"+ + "\u8E5E\u8E5F\u8E60\u8E61\u8E62\u8E63\u8E64\u8E65"+ + "\u8E67\u8E68\u8E6A\u8E6B\u8E6E\u8E71\u90B8\u90B0"+ + "\u90CF\u90C5\u90BE\u90D0\u90C4\u90C7\u90D3\u90E6"+ + "\u90E2\u90DC\u90D7\u90DB\u90EB\u90EF\u90FE\u9104"+ + "\u9122\u911E\u9123\u9131\u912F\u9139\u9143\u9146"+ + "\u520D\u5942\u52A2\u52AC\u52AD\u52BE\u54FF\u52D0"+ + "\u52D6\u52F0\u53DF\u71EE\u77CD\u5EF4\u51F5\u51FC"+ + "\u9B2F\u53B6\u5F01\u755A\u5DEF\u574C\u57A9\u57A1"+ + "\u587E\u58BC\u58C5\u58D1\u5729\u572C\u572A\u5733"+ + "\u5739\u572E\u572F\u575C\u573B\u5742\u5769\u5785"+ + "\u576B\u5786\u577C\u577B\u5768\u576D\u5776\u5773"+ + "\u57AD\u57A4\u578C\u57B2\u57CF\u57A7\u57B4\u5793"+ + "\u57A0\u57D5\u57D8\u57DA\u57D9\u57D2\u57B8\u57F4"+ + "\u57EF\u57F8\u57E4\u57DD\u8E73\u8E75\u8E77\u8E78"+ + "\u8E79\u8E7A\u8E7B\u8E7D\u8E7E\u8E80\u8E82\u8E83"+ + "\u8E84\u8E86\u8E88\u8E89\u8E8A\u8E8B\u8E8C\u8E8D"+ + "\u8E8E\u8E91\u8E92\u8E93\u8E95\u8E96\u8E97\u8E98"+ + "\u8E99\u8E9A\u8E9B\u8E9D\u8E9F\u8EA0\u8EA1\u8EA2"+ + "\u8EA3\u8EA4\u8EA5\u8EA6\u8EA7\u8EA8\u8EA9\u8EAA"+ + "\u8EAD\u8EAE\u8EB0\u8EB1\u8EB3\u8EB4\u8EB5\u8EB6"+ + "\u8EB7\u8EB8\u8EB9\u8EBB\u8EBC\u8EBD\u8EBE\u8EBF"+ + "\u8EC0\u8EC1\u8EC2\uFFFD\u8EC3\u8EC4\u8EC5\u8EC6"+ + "\u8EC7\u8EC8\u8EC9\u8ECA\u8ECB\u8ECC\u8ECD\u8ECF"+ + "\u8ED0\u8ED1\u8ED2\u8ED3\u8ED4\u8ED5\u8ED6\u8ED7"+ + "\u8ED8\u8ED9\u8EDA\u8EDB\u8EDC\u8EDD\u8EDE\u8EDF"+ + "\u8EE0\u8EE1\u8EE2\u8EE3\u8EE4\u580B\u580D\u57FD"+ + "\u57ED\u5800\u581E\u5819\u5844\u5820\u5865\u586C"+ + "\u5881\u5889\u589A\u5880\u99A8\u9F19\u61FF\u8279"+ + "\u827D\u827F\u828F\u828A\u82A8\u8284\u828E\u8291"+ + "\u8297\u8299\u82AB\u82B8\u82BE\u82B0\u82C8\u82CA"+ + "\u82E3\u8298\u82B7\u82AE\u82CB\u82CC\u82C1\u82A9"+ + "\u82B4\u82A1\u82AA\u829F\u82C4\u82CE\u82A4\u82E1"+ + "\u8309\u82F7\u82E4\u830F\u8307\u82DC\u82F4\u82D2"+ + "\u82D8\u830C\u82FB\u82D3\u8311\u831A\u8306\u8314"+ + "\u8315\u82E0\u82D5\u831C\u8351\u835B\u835C\u8308"+ + "\u8392\u833C\u8334\u8331\u839B\u835E\u832F\u834F"+ + "\u8347\u8343\u835F\u8340\u8317\u8360\u832D\u833A"+ + "\u8333\u8366\u8365\u8EE5\u8EE6\u8EE7\u8EE8\u8EE9"+ + "\u8EEA\u8EEB\u8EEC\u8EED\u8EEE\u8EEF\u8EF0\u8EF1"+ + "\u8EF2\u8EF3\u8EF4\u8EF5\u8EF6\u8EF7\u8EF8\u8EF9"+ + "\u8EFA\u8EFB\u8EFC\u8EFD\u8EFE\u8EFF\u8F00\u8F01"+ + "\u8F02\u8F03\u8F04\u8F05\u8F06\u8F07\u8F08\u8F09"+ + "\u8F0A\u8F0B\u8F0C\u8F0D\u8F0E\u8F0F\u8F10\u8F11"+ + "\u8F12\u8F13\u8F14\u8F15\u8F16\u8F17\u8F18\u8F19"+ + "\u8F1A\u8F1B\u8F1C\u8F1D\u8F1E\u8F1F\u8F20\u8F21"+ + "\u8F22\u8F23\uFFFD\u8F24\u8F25\u8F26\u8F27\u8F28"+ + "\u8F29\u8F2A\u8F2B\u8F2C\u8F2D\u8F2E\u8F2F\u8F30"+ + "\u8F31\u8F32\u8F33\u8F34\u8F35\u8F36\u8F37\u8F38"+ + "\u8F39\u8F3A\u8F3B\u8F3C\u8F3D\u8F3E\u8F3F\u8F40"+ + "\u8F41\u8F42\u8F43\u8F44\u8368\u831B\u8369\u836C"+ + "\u836A\u836D\u836E\u83B0\u8378\u83B3\u83B4\u83A0"+ + "\u83AA\u8393\u839C\u8385\u837C\u83B6\u83A9\u837D"+ + "\u83B8\u837B\u8398\u839E\u83A8\u83BA\u83BC\u83C1"+ + "\u8401\u83E5\u83D8\u5807\u8418\u840B\u83DD\u83FD"+ + "\u83D6\u841C\u8438\u8411\u8406\u83D4\u83DF\u840F"+ + "\u8403\u83F8\u83F9\u83EA\u83C5\u83C0\u8426\u83F0"+ + "\u83E1\u845C\u8451\u845A\u8459\u8473\u8487\u8488"+ + "\u847A\u8489\u8478\u843C\u8446\u8469\u8476\u848C"+ + "\u848E\u8431\u846D\u84C1\u84CD\u84D0\u84E6\u84BD"+ + "\u84D3\u84CA\u84BF\u84BA\u84E0\u84A1\u84B9\u84B4"+ + "\u8497\u84E5\u84E3\u850C\u750D\u8538\u84F0\u8539"+ + "\u851F\u853A\u8F45\u8F46\u8F47\u8F48\u8F49\u8F4A"+ + "\u8F4B\u8F4C\u8F4D\u8F4E\u8F4F\u8F50\u8F51\u8F52"+ + "\u8F53\u8F54\u8F55\u8F56\u8F57\u8F58\u8F59\u8F5A"+ + "\u8F5B\u8F5C\u8F5D\u8F5E\u8F5F\u8F60\u8F61\u8F62"+ + "\u8F63\u8F64\u8F65\u8F6A\u8F80\u8F8C\u8F92\u8F9D"+ + "\u8FA0\u8FA1\u8FA2\u8FA4\u8FA5\u8FA6\u8FA7\u8FAA"+ + "\u8FAC\u8FAD\u8FAE\u8FAF\u8FB2\u8FB3\u8FB4\u8FB5"+ + "\u8FB7\u8FB8\u8FBA\u8FBB\u8FBC\u8FBF\u8FC0\u8FC3"+ + "\u8FC6\uFFFD\u8FC9\u8FCA\u8FCB\u8FCC\u8FCD\u8FCF"+ + "\u8FD2\u8FD6\u8FD7\u8FDA\u8FE0\u8FE1\u8FE3\u8FE7"+ + "\u8FEC\u8FEF\u8FF1\u8FF2\u8FF4\u8FF5\u8FF6\u8FFA"+ + "\u8FFB\u8FFC\u8FFE\u8FFF\u9007\u9008\u900C\u900E"+ + "\u9013\u9015\u9018\u8556\u853B\u84FF\u84FC\u8559"+ + "\u8548\u8568\u8564\u855E\u857A\u77A2\u8543\u8572"+ + "\u857B\u85A4\u85A8\u8587\u858F\u8579\u85AE\u859C"+ + "\u8585\u85B9\u85B7\u85B0\u85D3\u85C1\u85DC\u85FF"+ + "\u8627\u8605\u8629\u8616\u863C\u5EFE\u5F08\u593C"+ + "\u5941\u8037\u5955\u595A\u5958\u530F\u5C22\u5C25"+ + "\u5C2C\u5C34\u624C\u626A\u629F\u62BB\u62CA\u62DA"+ + "\u62D7\u62EE\u6322\u62F6\u6339\u634B\u6343\u63AD"+ + "\u63F6\u6371\u637A\u638E\u63B4\u636D\u63AC\u638A"+ + "\u6369\u63AE\u63BC\u63F2\u63F8\u63E0\u63FF\u63C4"+ + "\u63DE\u63CE\u6452\u63C6\u63BE\u6445\u6441\u640B"+ + "\u641B\u6420\u640C\u6426\u6421\u645E\u6484\u646D"+ + "\u6496\u9019\u901C\u9023\u9024\u9025\u9027\u9028"+ + "\u9029\u902A\u902B\u902C\u9030\u9031\u9032\u9033"+ + "\u9034\u9037\u9039\u903A\u903D\u903F\u9040\u9043"+ + "\u9045\u9046\u9048\u9049\u904A\u904B\u904C\u904E"+ + "\u9054\u9055\u9056\u9059\u905A\u905C\u905D\u905E"+ + "\u905F\u9060\u9061\u9064\u9066\u9067\u9069\u906A"+ + "\u906B\u906C\u906F\u9070\u9071\u9072\u9073\u9076"+ + "\u9077\u9078\u9079\u907A\u907B\u907C\u907E\u9081"+ + "\uFFFD\u9084\u9085\u9086\u9087\u9089\u908A\u908C"+ + "\u908D\u908E\u908F\u9090\u9092\u9094\u9096\u9098"+ + "\u909A\u909C\u909E\u909F\u90A0\u90A4\u90A5\u90A7"+ + "\u90A8\u90A9\u90AB\u90AD\u90B2\u90B7\u90BC\u90BD"+ + "\u90BF\u90C0\u647A\u64B7\u64B8\u6499\u64BA\u64C0"+ + "\u64D0\u64D7\u64E4\u64E2\u6509\u6525\u652E\u5F0B"+ + "\u5FD2\u7519\u5F11\u535F\u53F1\u53FD\u53E9\u53E8"+ + "\u53FB\u5412\u5416\u5406\u544B\u5452\u5453\u5454"+ + "\u5456\u5443\u5421\u5457\u5459\u5423\u5432\u5482"+ + "\u5494\u5477\u5471\u5464\u549A\u549B\u5484\u5476"+ + "\u5466\u549D\u54D0\u54AD\u54C2\u54B4\u54D2\u54A7"+ + "\u54A6\u54D3\u54D4\u5472\u54A3\u54D5\u54BB\u54BF"+ + "\u54CC\u54D9\u54DA\u54DC\u54A9\u54AA\u54A4\u54DD"+ + "\u54CF\u54DE\u551B\u54E7\u5520\u54FD\u5514\u54F3"+ + "\u5522\u5523\u550F\u5511\u5527\u552A\u5567\u558F"+ + "\u55B5\u5549\u556D\u5541\u5555\u553F\u5550\u553C"; + + private static final String innerIndex6= + "\u90C2\u90C3\u90C6\u90C8\u90C9\u90CB\u90CC\u90CD"+ + "\u90D2\u90D4\u90D5\u90D6\u90D8\u90D9\u90DA\u90DE"+ + "\u90DF\u90E0\u90E3\u90E4\u90E5\u90E9\u90EA\u90EC"+ + "\u90EE\u90F0\u90F1\u90F2\u90F3\u90F5\u90F6\u90F7"+ + "\u90F9\u90FA\u90FB\u90FC\u90FF\u9100\u9101\u9103"+ + "\u9105\u9106\u9107\u9108\u9109\u910A\u910B\u910C"+ + "\u910D\u910E\u910F\u9110\u9111\u9112\u9113\u9114"+ + "\u9115\u9116\u9117\u9118\u911A\u911B\u911C\uFFFD"+ + "\u911D\u911F\u9120\u9121\u9124\u9125\u9126\u9127"+ + "\u9128\u9129\u912A\u912B\u912C\u912D\u912E\u9130"+ + "\u9132\u9133\u9134\u9135\u9136\u9137\u9138\u913A"+ + "\u913B\u913C\u913D\u913E\u913F\u9140\u9141\u9142"+ + "\u9144\u5537\u5556\u5575\u5576\u5577\u5533\u5530"+ + "\u555C\u558B\u55D2\u5583\u55B1\u55B9\u5588\u5581"+ + "\u559F\u557E\u55D6\u5591\u557B\u55DF\u55BD\u55BE"+ + "\u5594\u5599\u55EA\u55F7\u55C9\u561F\u55D1\u55EB"+ + "\u55EC\u55D4\u55E6\u55DD\u55C4\u55EF\u55E5\u55F2"+ + "\u55F3\u55CC\u55CD\u55E8\u55F5\u55E4\u8F94\u561E"+ + "\u5608\u560C\u5601\u5624\u5623\u55FE\u5600\u5627"+ + "\u562D\u5658\u5639\u5657\u562C\u564D\u5662\u5659"+ + "\u565C\u564C\u5654\u5686\u5664\u5671\u566B\u567B"+ + "\u567C\u5685\u5693\u56AF\u56D4\u56D7\u56DD\u56E1"+ + "\u56F5\u56EB\u56F9\u56FF\u5704\u570A\u5709\u571C"+ + "\u5E0F\u5E19\u5E14\u5E11\u5E31\u5E3B\u5E3C\u9145"+ + "\u9147\u9148\u9151\u9153\u9154\u9155\u9156\u9158"+ + "\u9159\u915B\u915C\u915F\u9160\u9166\u9167\u9168"+ + "\u916B\u916D\u9173\u917A\u917B\u917C\u9180\u9181"+ + "\u9182\u9183\u9184\u9186\u9188\u918A\u918E\u918F"+ + "\u9193\u9194\u9195\u9196\u9197\u9198\u9199\u919C"+ + "\u919D\u919E\u919F\u91A0\u91A1\u91A4\u91A5\u91A6"+ + "\u91A7\u91A8\u91A9\u91AB\u91AC\u91B0\u91B1\u91B2"+ + "\u91B3\u91B6\u91B7\u91B8\u91B9\u91BB\uFFFD\u91BC"+ + "\u91BD\u91BE\u91BF\u91C0\u91C1\u91C2\u91C3\u91C4"+ + "\u91C5\u91C6\u91C8\u91CB\u91D0\u91D2\u91D3\u91D4"+ + "\u91D5\u91D6\u91D7\u91D8\u91D9\u91DA\u91DB\u91DD"+ + "\u91DE\u91DF\u91E0\u91E1\u91E2\u91E3\u91E4\u91E5"+ + "\u5E37\u5E44\u5E54\u5E5B\u5E5E\u5E61\u5C8C\u5C7A"+ + "\u5C8D\u5C90\u5C96\u5C88\u5C98\u5C99\u5C91\u5C9A"+ + "\u5C9C\u5CB5\u5CA2\u5CBD\u5CAC\u5CAB\u5CB1\u5CA3"+ + "\u5CC1\u5CB7\u5CC4\u5CD2\u5CE4\u5CCB\u5CE5\u5D02"+ + "\u5D03\u5D27\u5D26\u5D2E\u5D24\u5D1E\u5D06\u5D1B"+ + "\u5D58\u5D3E\u5D34\u5D3D\u5D6C\u5D5B\u5D6F\u5D5D"+ + "\u5D6B\u5D4B\u5D4A\u5D69\u5D74\u5D82\u5D99\u5D9D"+ + "\u8C73\u5DB7\u5DC5\u5F73\u5F77\u5F82\u5F87\u5F89"+ + "\u5F8C\u5F95\u5F99\u5F9C\u5FA8\u5FAD\u5FB5\u5FBC"+ + "\u8862\u5F61\u72AD\u72B0\u72B4\u72B7\u72B8\u72C3"+ + "\u72C1\u72CE\u72CD\u72D2\u72E8\u72EF\u72E9\u72F2"+ + "\u72F4\u72F7\u7301\u72F3\u7303\u72FA\u91E6\u91E7"+ + "\u91E8\u91E9\u91EA\u91EB\u91EC\u91ED\u91EE\u91EF"+ + "\u91F0\u91F1\u91F2\u91F3\u91F4\u91F5\u91F6\u91F7"+ + "\u91F8\u91F9\u91FA\u91FB\u91FC\u91FD\u91FE\u91FF"+ + "\u9200\u9201\u9202\u9203\u9204\u9205\u9206\u9207"+ + "\u9208\u9209\u920A\u920B\u920C\u920D\u920E\u920F"+ + "\u9210\u9211\u9212\u9213\u9214\u9215\u9216\u9217"+ + "\u9218\u9219\u921A\u921B\u921C\u921D\u921E\u921F"+ + "\u9220\u9221\u9222\u9223\u9224\uFFFD\u9225\u9226"+ + "\u9227\u9228\u9229\u922A\u922B\u922C\u922D\u922E"+ + "\u922F\u9230\u9231\u9232\u9233\u9234\u9235\u9236"+ + "\u9237\u9238\u9239\u923A\u923B\u923C\u923D\u923E"+ + "\u923F\u9240\u9241\u9242\u9243\u9244\u9245\u72FB"+ + "\u7317\u7313\u7321\u730A\u731E\u731D\u7315\u7322"+ + "\u7339\u7325\u732C\u7338\u7331\u7350\u734D\u7357"+ + "\u7360\u736C\u736F\u737E\u821B\u5925\u98E7\u5924"+ + "\u5902\u9963\u9967\u9968\u9969\u996A\u996B\u996C"+ + "\u9974\u9977\u997D\u9980\u9984\u9987\u998A\u998D"+ + "\u9990\u9991\u9993\u9994\u9995\u5E80\u5E91\u5E8B"+ + "\u5E96\u5EA5\u5EA0\u5EB9\u5EB5\u5EBE\u5EB3\u8D53"+ + "\u5ED2\u5ED1\u5EDB\u5EE8\u5EEA\u81BA\u5FC4\u5FC9"+ + "\u5FD6\u5FCF\u6003\u5FEE\u6004\u5FE1\u5FE4\u5FFE"+ + "\u6005\u6006\u5FEA\u5FED\u5FF8\u6019\u6035\u6026"+ + "\u601B\u600F\u600D\u6029\u602B\u600A\u603F\u6021"+ + "\u6078\u6079\u607B\u607A\u6042\u9246\u9247\u9248"+ + "\u9249\u924A\u924B\u924C\u924D\u924E\u924F\u9250"+ + "\u9251\u9252\u9253\u9254\u9255\u9256\u9257\u9258"+ + "\u9259\u925A\u925B\u925C\u925D\u925E\u925F\u9260"+ + "\u9261\u9262\u9263\u9264\u9265\u9266\u9267\u9268"+ + "\u9269\u926A\u926B\u926C\u926D\u926E\u926F\u9270"+ + "\u9271\u9272\u9273\u9275\u9276\u9277\u9278\u9279"+ + "\u927A\u927B\u927C\u927D\u927E\u927F\u9280\u9281"+ + "\u9282\u9283\u9284\u9285\uFFFD\u9286\u9287\u9288"+ + "\u9289\u928A\u928B\u928C\u928D\u928F\u9290\u9291"+ + "\u9292\u9293\u9294\u9295\u9296\u9297\u9298\u9299"+ + "\u929A\u929B\u929C\u929D\u929E\u929F\u92A0\u92A1"+ + "\u92A2\u92A3\u92A4\u92A5\u92A6\u92A7\u606A\u607D"+ + "\u6096\u609A\u60AD\u609D\u6083\u6092\u608C\u609B"+ + "\u60EC\u60BB\u60B1\u60DD\u60D8\u60C6\u60DA\u60B4"+ + "\u6120\u6126\u6115\u6123\u60F4\u6100\u610E\u612B"+ + "\u614A\u6175\u61AC\u6194\u61A7\u61B7\u61D4\u61F5"+ + "\u5FDD\u96B3\u95E9\u95EB\u95F1\u95F3\u95F5\u95F6"+ + "\u95FC\u95FE\u9603\u9604\u9606\u9608\u960A\u960B"+ + "\u960C\u960D\u960F\u9612\u9615\u9616\u9617\u9619"+ + "\u961A\u4E2C\u723F\u6215\u6C35\u6C54\u6C5C\u6C4A"+ + "\u6CA3\u6C85\u6C90\u6C94\u6C8C\u6C68\u6C69\u6C74"+ + "\u6C76\u6C86\u6CA9\u6CD0\u6CD4\u6CAD\u6CF7\u6CF8"+ + "\u6CF1\u6CD7\u6CB2\u6CE0\u6CD6\u6CFA\u6CEB\u6CEE"+ + "\u6CB1\u6CD3\u6CEF\u6CFE\u92A8\u92A9\u92AA\u92AB"+ + "\u92AC\u92AD\u92AF\u92B0\u92B1\u92B2\u92B3\u92B4"+ + "\u92B5\u92B6\u92B7\u92B8\u92B9\u92BA\u92BB\u92BC"+ + "\u92BD\u92BE\u92BF\u92C0\u92C1\u92C2\u92C3\u92C4"+ + "\u92C5\u92C6\u92C7\u92C9\u92CA\u92CB\u92CC\u92CD"+ + "\u92CE\u92CF\u92D0\u92D1\u92D2\u92D3\u92D4\u92D5"+ + "\u92D6\u92D7\u92D8\u92D9\u92DA\u92DB\u92DC\u92DD"+ + "\u92DE\u92DF\u92E0\u92E1\u92E2\u92E3\u92E4\u92E5"+ + "\u92E6\u92E7\u92E8\uFFFD\u92E9\u92EA\u92EB\u92EC"+ + "\u92ED\u92EE\u92EF\u92F0\u92F1\u92F2\u92F3\u92F4"+ + "\u92F5\u92F6\u92F7\u92F8\u92F9\u92FA\u92FB\u92FC"+ + "\u92FD\u92FE\u92FF\u9300\u9301\u9302\u9303\u9304"+ + "\u9305\u9306\u9307\u9308\u9309\u6D39\u6D27\u6D0C"+ + "\u6D43\u6D48\u6D07\u6D04\u6D19\u6D0E\u6D2B\u6D4D"+ + "\u6D2E\u6D35\u6D1A\u6D4F\u6D52\u6D54\u6D33\u6D91"+ + "\u6D6F\u6D9E\u6DA0\u6D5E\u6D93\u6D94\u6D5C\u6D60"+ + "\u6D7C\u6D63\u6E1A\u6DC7\u6DC5\u6DDE\u6E0E\u6DBF"+ + "\u6DE0\u6E11\u6DE6\u6DDD\u6DD9\u6E16\u6DAB\u6E0C"+ + "\u6DAE\u6E2B\u6E6E\u6E4E\u6E6B\u6EB2\u6E5F\u6E86"+ + "\u6E53\u6E54\u6E32\u6E25\u6E44\u6EDF\u6EB1\u6E98"+ + "\u6EE0\u6F2D\u6EE2\u6EA5\u6EA7\u6EBD\u6EBB\u6EB7"+ + "\u6ED7\u6EB4\u6ECF\u6E8F\u6EC2\u6E9F\u6F62\u6F46"+ + "\u6F47\u6F24\u6F15\u6EF9\u6F2F\u6F36\u6F4B\u6F74"+ + "\u6F2A\u6F09\u6F29\u6F89\u6F8D\u6F8C\u6F78\u6F72"+ + "\u6F7C\u6F7A\u6FD1\u930A\u930B\u930C\u930D\u930E"+ + "\u930F\u9310\u9311\u9312\u9313\u9314\u9315\u9316"+ + "\u9317\u9318\u9319\u931A\u931B\u931C\u931D\u931E"+ + "\u931F\u9320\u9321\u9322\u9323\u9324\u9325\u9326"+ + "\u9327\u9328\u9329\u932A\u932B\u932C\u932D\u932E"+ + "\u932F\u9330\u9331\u9332\u9333\u9334\u9335\u9336"+ + "\u9337\u9338\u9339\u933A\u933B\u933C\u933D\u933F"+ + "\u9340\u9341\u9342\u9343\u9344\u9345\u9346\u9347"+ + "\u9348\u9349\uFFFD\u934A\u934B\u934C\u934D\u934E"+ + "\u934F\u9350\u9351\u9352\u9353\u9354\u9355\u9356"+ + "\u9357\u9358\u9359\u935A\u935B\u935C\u935D\u935E"+ + "\u935F\u9360\u9361\u9362\u9363\u9364\u9365\u9366"+ + "\u9367\u9368\u9369\u936B\u6FC9\u6FA7\u6FB9\u6FB6"+ + "\u6FC2\u6FE1\u6FEE\u6FDE\u6FE0\u6FEF\u701A\u7023"+ + "\u701B\u7039\u7035\u704F\u705E\u5B80\u5B84\u5B95"+ + "\u5B93\u5BA5\u5BB8\u752F\u9A9E\u6434\u5BE4\u5BEE"+ + "\u8930\u5BF0\u8E47\u8B07\u8FB6\u8FD3\u8FD5\u8FE5"+ + "\u8FEE\u8FE4\u8FE9\u8FE6\u8FF3\u8FE8\u9005\u9004"+ + "\u900B\u9026\u9011\u900D\u9016\u9021\u9035\u9036"+ + "\u902D\u902F\u9044\u9051\u9052\u9050\u9068\u9058"+ + "\u9062\u905B\u66B9\u9074\u907D\u9082\u9088\u9083"+ + "\u908B\u5F50\u5F57\u5F56\u5F58\u5C3B\u54AB\u5C50"+ + "\u5C59\u5B71\u5C63\u5C66\u7FBC\u5F2A\u5F29\u5F2D"+ + "\u8274\u5F3C\u9B3B\u5C6E\u5981\u5983\u598D\u59A9"+ + "\u59AA\u59A3\u936C\u936D\u936E\u936F\u9370\u9371"+ + "\u9372\u9373\u9374\u9375\u9376\u9377\u9378\u9379"+ + "\u937A\u937B\u937C\u937D\u937E\u937F\u9380\u9381"+ + "\u9382\u9383\u9384\u9385\u9386\u9387\u9388\u9389"+ + "\u938A\u938B\u938C\u938D\u938E\u9390\u9391\u9392"+ + "\u9393\u9394\u9395\u9396\u9397\u9398\u9399\u939A"+ + "\u939B\u939C\u939D\u939E\u939F\u93A0\u93A1\u93A2"+ + "\u93A3\u93A4\u93A5\u93A6\u93A7\u93A8\u93A9\u93AA"+ + "\u93AB\uFFFD\u93AC\u93AD\u93AE\u93AF\u93B0\u93B1"+ + "\u93B2\u93B3\u93B4\u93B5\u93B6\u93B7\u93B8\u93B9"+ + "\u93BA\u93BB\u93BC\u93BD\u93BE\u93BF\u93C0\u93C1"+ + "\u93C2\u93C3\u93C4\u93C5\u93C6\u93C7\u93C8\u93C9"+ + "\u93CB\u93CC\u93CD\u5997\u59CA\u59AB\u599E\u59A4"+ + "\u59D2\u59B2\u59AF\u59D7\u59BE\u5A05\u5A06\u59DD"+ + "\u5A08\u59E3\u59D8\u59F9\u5A0C\u5A09\u5A32\u5A34"+ + "\u5A11\u5A23\u5A13\u5A40\u5A67\u5A4A\u5A55\u5A3C"+ + "\u5A62\u5A75\u80EC\u5AAA\u5A9B\u5A77\u5A7A\u5ABE"+ + "\u5AEB\u5AB2\u5AD2\u5AD4\u5AB8\u5AE0\u5AE3\u5AF1"+ + "\u5AD6\u5AE6\u5AD8\u5ADC\u5B09\u5B17\u5B16\u5B32"+ + "\u5B37\u5B40\u5C15\u5C1C\u5B5A\u5B65\u5B73\u5B51"+ + "\u5B53\u5B62\u9A75\u9A77\u9A78\u9A7A\u9A7F\u9A7D"+ + "\u9A80\u9A81\u9A85\u9A88\u9A8A\u9A90\u9A92\u9A93"+ + "\u9A96\u9A98\u9A9B\u9A9C\u9A9D\u9A9F\u9AA0\u9AA2"+ + "\u9AA3\u9AA5\u9AA7\u7E9F\u7EA1\u7EA3\u7EA5\u7EA8"+ + "\u7EA9\u93CE\u93CF\u93D0\u93D1\u93D2\u93D3\u93D4"+ + "\u93D5\u93D7\u93D8\u93D9\u93DA\u93DB\u93DC\u93DD"+ + "\u93DE\u93DF\u93E0\u93E1\u93E2\u93E3\u93E4\u93E5"+ + "\u93E6\u93E7\u93E8\u93E9\u93EA\u93EB\u93EC\u93ED"+ + "\u93EE\u93EF\u93F0\u93F1\u93F2\u93F3\u93F4\u93F5"+ + "\u93F6\u93F7\u93F8\u93F9\u93FA\u93FB\u93FC\u93FD"+ + "\u93FE\u93FF\u9400\u9401\u9402\u9403\u9404\u9405"+ + "\u9406\u9407\u9408\u9409\u940A\u940B\u940C\u940D"+ + "\uFFFD\u940E\u940F\u9410\u9411\u9412\u9413\u9414"+ + "\u9415\u9416\u9417\u9418\u9419\u941A\u941B\u941C"+ + "\u941D\u941E\u941F\u9420\u9421\u9422\u9423\u9424"+ + "\u9425\u9426\u9427\u9428\u9429\u942A\u942B\u942C"+ + "\u942D\u942E\u7EAD\u7EB0\u7EBE\u7EC0\u7EC1\u7EC2"+ + "\u7EC9\u7ECB\u7ECC\u7ED0\u7ED4\u7ED7\u7EDB\u7EE0"+ + "\u7EE1\u7EE8\u7EEB\u7EEE\u7EEF\u7EF1\u7EF2\u7F0D"+ + "\u7EF6\u7EFA\u7EFB\u7EFE\u7F01\u7F02\u7F03\u7F07"+ + "\u7F08\u7F0B\u7F0C\u7F0F\u7F11\u7F12\u7F17\u7F19"+ + "\u7F1C\u7F1B\u7F1F\u7F21\u7F22\u7F23\u7F24\u7F25"+ + "\u7F26\u7F27\u7F2A\u7F2B\u7F2C\u7F2D\u7F2F\u7F30"+ + "\u7F31\u7F32\u7F33\u7F35\u5E7A\u757F\u5DDB\u753E"+ + "\u9095\u738E\u7391\u73AE\u73A2\u739F\u73CF\u73C2"+ + "\u73D1\u73B7\u73B3\u73C0\u73C9\u73C8\u73E5\u73D9"+ + "\u987C\u740A\u73E9\u73E7\u73DE\u73BA\u73F2\u740F"+ + "\u742A\u745B\u7426\u7425\u7428\u7430\u742E\u742C"+ + "\u942F\u9430\u9431\u9432\u9433\u9434\u9435\u9436"+ + "\u9437\u9438\u9439\u943A\u943B\u943C\u943D\u943F"+ + "\u9440\u9441\u9442\u9443\u9444\u9445\u9446\u9447"+ + "\u9448\u9449\u944A\u944B\u944C\u944D\u944E\u944F"+ + "\u9450\u9451\u9452\u9453\u9454\u9455\u9456\u9457"+ + "\u9458\u9459\u945A\u945B\u945C\u945D\u945E\u945F"+ + "\u9460\u9461\u9462\u9463\u9464\u9465\u9466\u9467"+ + "\u9468\u9469\u946A\u946C\u946D\u946E\u946F\uFFFD"+ + "\u9470\u9471\u9472\u9473\u9474\u9475\u9476\u9477"+ + "\u9478\u9479\u947A\u947B\u947C\u947D\u947E\u947F"+ + "\u9480\u9481\u9482\u9483\u9484\u9491\u9496\u9498"+ + "\u94C7\u94CF\u94D3\u94D4\u94DA\u94E6\u94FB\u951C"+ + "\u9520\u741B\u741A\u7441\u745C\u7457\u7455\u7459"+ + "\u7477\u746D\u747E\u749C\u748E\u7480\u7481\u7487"+ + "\u748B\u749E\u74A8\u74A9\u7490\u74A7\u74D2\u74BA"+ + "\u97EA\u97EB\u97EC\u674C\u6753\u675E\u6748\u6769"+ + "\u67A5\u6787\u676A\u6773\u6798\u67A7\u6775\u67A8"+ + "\u679E\u67AD\u678B\u6777\u677C\u67F0\u6809\u67D8"+ + "\u680A\u67E9\u67B0\u680C\u67D9\u67B5\u67DA\u67B3"+ + "\u67DD\u6800\u67C3\u67B8\u67E2\u680E\u67C1\u67FD"+ + "\u6832\u6833\u6860\u6861\u684E\u6862\u6844\u6864"+ + "\u6883\u681D\u6855\u6866\u6841\u6867\u6840\u683E"+ + "\u684A\u6849\u6829\u68B5\u688F\u6874\u6877\u6893"+ + "\u686B\u68C2\u696E\u68FC\u691F\u6920\u68F9\u9527"+ + "\u9533\u953D\u9543\u9548\u954B\u9555\u955A\u9560"+ + "\u956E\u9574\u9575\u9577\u9578\u9579\u957A\u957B"+ + "\u957C\u957D\u957E\u9580\u9581\u9582\u9583\u9584"+ + "\u9585\u9586\u9587\u9588\u9589\u958A\u958B\u958C"+ + "\u958D\u958E\u958F\u9590\u9591\u9592\u9593\u9594"+ + "\u9595\u9596\u9597\u9598\u9599\u959A\u959B\u959C"+ + "\u959D\u959E\u959F\u95A0\u95A1\u95A2\u95A3\u95A4"+ + "\u95A5\u95A6\u95A7\u95A8\u95A9\u95AA\uFFFD\u95AB"+ + "\u95AC\u95AD\u95AE\u95AF\u95B0\u95B1\u95B2\u95B3"+ + "\u95B4\u95B5\u95B6\u95B7\u95B8\u95B9\u95BA\u95BB"+ + "\u95BC\u95BD\u95BE\u95BF\u95C0\u95C1\u95C2\u95C3"+ + "\u95C4\u95C5\u95C6\u95C7\u95C8\u95C9\u95CA\u95CB"+ + "\u6924\u68F0\u690B\u6901\u6957\u68E3\u6910\u6971"+ + "\u6939\u6960\u6942\u695D\u6984\u696B\u6980\u6998"+ + "\u6978\u6934\u69CC\u6987\u6988\u69CE\u6989\u6966"+ + "\u6963\u6979\u699B\u69A7\u69BB\u69AB\u69AD\u69D4"+ + "\u69B1\u69C1\u69CA\u69DF\u6995\u69E0\u698D\u69FF"+ + "\u6A2F\u69ED\u6A17\u6A18\u6A65\u69F2\u6A44\u6A3E"+ + "\u6AA0\u6A50\u6A5B\u6A35\u6A8E\u6A79\u6A3D\u6A28"+ + "\u6A58\u6A7C\u6A91\u6A90\u6AA9\u6A97\u6AAB\u7337"+ + "\u7352\u6B81\u6B82\u6B87\u6B84\u6B92\u6B93\u6B8D"+ + "\u6B9A\u6B9B\u6BA1\u6BAA\u8F6B\u8F6D\u8F71\u8F72"+ + "\u8F73\u8F75\u8F76\u8F78\u8F77\u8F79\u8F7A\u8F7C"+ + "\u8F7E\u8F81\u8F82\u8F84\u8F87\u8F8B\u95CC\u95CD"+ + "\u95CE\u95CF\u95D0\u95D1\u95D2\u95D3\u95D4\u95D5"+ + "\u95D6\u95D7\u95D8\u95D9\u95DA\u95DB\u95DC\u95DD"+ + "\u95DE\u95DF\u95E0\u95E1\u95E2\u95E3\u95E4\u95E5"+ + "\u95E6\u95E7\u95EC\u95FF\u9607\u9613\u9618\u961B"+ + "\u961E\u9620\u9623\u9624\u9625\u9626\u9627\u9628"+ + "\u9629\u962B\u962C\u962D\u962F\u9630\u9637\u9638"+ + "\u9639\u963A\u963E\u9641\u9643\u964A\u964E\u964F"+ + "\u9651\u9652\u9653\u9656\u9657\uFFFD\u9658\u9659"+ + "\u965A\u965C\u965D\u965E\u9660\u9663\u9665\u9666"+ + "\u966B\u966D\u966E\u966F\u9670\u9671\u9673\u9678"+ + "\u9679\u967A\u967B\u967C\u967D\u967E\u967F\u9680"+ + "\u9681\u9682\u9683\u9684\u9687\u9689\u968A\u8F8D"+ + "\u8F8E\u8F8F\u8F98\u8F9A\u8ECE\u620B\u6217\u621B"+ + "\u621F\u6222\u6221\u6225\u6224\u622C\u81E7\u74EF"+ + "\u74F4\u74FF\u750F\u7511\u7513\u6534\u65EE\u65EF"+ + "\u65F0\u660A\u6619\u6772\u6603\u6615\u6600\u7085"+ + "\u66F7\u661D\u6634\u6631\u6636\u6635\u8006\u665F"+ + "\u6654\u6641\u664F\u6656\u6661\u6657\u6677\u6684"+ + "\u668C\u66A7\u669D\u66BE\u66DB\u66DC\u66E6\u66E9"+ + "\u8D32\u8D33\u8D36\u8D3B\u8D3D\u8D40\u8D45\u8D46"+ + "\u8D48\u8D49\u8D47\u8D4D\u8D55\u8D59\u89C7\u89CA"+ + "\u89CB\u89CC\u89CE\u89CF\u89D0\u89D1\u726E\u729F"+ + "\u725D\u7266\u726F\u727E\u727F\u7284\u728B\u728D"+ + "\u728F\u7292\u6308\u6332\u63B0\u968C\u968E\u9691"+ + "\u9692\u9693\u9695\u9696\u969A\u969B\u969D\u969E"+ + "\u969F\u96A0\u96A1\u96A2\u96A3\u96A4\u96A5\u96A6"+ + "\u96A8\u96A9\u96AA\u96AB\u96AC\u96AD\u96AE\u96AF"+ + "\u96B1\u96B2\u96B4\u96B5\u96B7\u96B8\u96BA\u96BB"+ + "\u96BF\u96C2\u96C3\u96C8\u96CA\u96CB\u96D0\u96D1"+ + "\u96D3\u96D4\u96D6\u96D7\u96D8\u96D9\u96DA\u96DB"+ + "\u96DC\u96DD\u96DE\u96DF\u96E1\u96E2\u96E3\u96E4"+ + "\u96E5\u96E6\u96E7\u96EB\uFFFD\u96EC\u96ED\u96EE"+ + "\u96F0\u96F1\u96F2\u96F4\u96F5\u96F8\u96FA\u96FB"+ + "\u96FC\u96FD\u96FF\u9702\u9703\u9705\u970A\u970B"+ + "\u970C\u9710\u9711\u9712\u9714\u9715\u9717\u9718"+ + "\u9719\u971A\u971B\u971D\u971F\u9720\u643F\u64D8"+ + "\u8004\u6BEA\u6BF3\u6BFD\u6BF5\u6BF9\u6C05\u6C07"+ + "\u6C06\u6C0D\u6C15\u6C18\u6C19\u6C1A\u6C21\u6C29"+ + "\u6C24\u6C2A\u6C32\u6535\u6555\u656B\u724D\u7252"+ + "\u7256\u7230\u8662\u5216\u809F\u809C\u8093\u80BC"+ + "\u670A\u80BD\u80B1\u80AB\u80AD\u80B4\u80B7\u80E7"+ + "\u80E8\u80E9\u80EA\u80DB\u80C2\u80C4\u80D9\u80CD"+ + "\u80D7\u6710\u80DD\u80EB\u80F1\u80F4\u80ED\u810D"+ + "\u810E\u80F2\u80FC\u6715\u8112\u8C5A\u8136\u811E"+ + "\u812C\u8118\u8132\u8148\u814C\u8153\u8174\u8159"+ + "\u815A\u8171\u8160\u8169\u817C\u817D\u816D\u8167"+ + "\u584D\u5AB5\u8188\u8182\u8191\u6ED5\u81A3\u81AA"+ + "\u81CC\u6726\u81CA\u81BB\u9721\u9722\u9723\u9724"+ + "\u9725\u9726\u9727\u9728\u9729\u972B\u972C\u972E"+ + "\u972F\u9731\u9733\u9734\u9735\u9736\u9737\u973A"+ + "\u973B\u973C\u973D\u973F\u9740\u9741\u9742\u9743"+ + "\u9744\u9745\u9746\u9747\u9748\u9749\u974A\u974B"+ + "\u974C\u974D\u974E\u974F\u9750\u9751\u9754\u9755"+ + "\u9757\u9758\u975A\u975C\u975D\u975F\u9763\u9764"+ + "\u9766\u9767\u9768\u976A\u976B\u976C\u976D\u976E"+ + "\u976F\u9770\u9771\uFFFD\u9772\u9775\u9777\u9778"+ + "\u9779\u977A\u977B\u977D\u977E\u977F\u9780\u9781"+ + "\u9782\u9783\u9784\u9786\u9787\u9788\u9789\u978A"+ + "\u978C\u978E\u978F\u9790\u9793\u9795\u9796\u9797"+ + "\u9799\u979A\u979B\u979C\u979D\u81C1\u81A6\u6B24"+ + "\u6B37\u6B39\u6B43\u6B46\u6B59\u98D1\u98D2\u98D3"+ + "\u98D5\u98D9\u98DA\u6BB3\u5F40\u6BC2\u89F3\u6590"+ + "\u9F51\u6593\u65BC\u65C6\u65C4\u65C3\u65CC\u65CE"+ + "\u65D2\u65D6\u7080\u709C\u7096\u709D\u70BB\u70C0"+ + "\u70B7\u70AB\u70B1\u70E8\u70CA\u7110\u7113\u7116"+ + "\u712F\u7131\u7173\u715C\u7168\u7145\u7172\u714A"+ + "\u7178\u717A\u7198\u71B3\u71B5\u71A8\u71A0\u71E0"+ + "\u71D4\u71E7\u71F9\u721D\u7228\u706C\u7118\u7166"+ + "\u71B9\u623E\u623D\u6243\u6248\u6249\u793B\u7940"+ + "\u7946\u7949\u795B\u795C\u7953\u795A\u7962\u7957"+ + "\u7960\u796F\u7967\u797A\u7985\u798A\u799A\u79A7"+ + "\u79B3\u5FD1\u5FD0\u979E\u979F\u97A1\u97A2\u97A4"+ + "\u97A5\u97A6\u97A7\u97A8\u97A9\u97AA\u97AC\u97AE"+ + "\u97B0\u97B1\u97B3\u97B5\u97B6\u97B7\u97B8\u97B9"+ + "\u97BA\u97BB\u97BC\u97BD\u97BE\u97BF\u97C0\u97C1"+ + "\u97C2\u97C3\u97C4\u97C5\u97C6\u97C7\u97C8\u97C9"+ + "\u97CA\u97CB\u97CC\u97CD\u97CE\u97CF\u97D0\u97D1"+ + "\u97D2\u97D3\u97D4\u97D5\u97D6\u97D7\u97D8\u97D9"+ + "\u97DA\u97DB\u97DC\u97DD\u97DE\u97DF\u97E0\u97E1"+ + "\u97E2\u97E3\uFFFD\u97E4\u97E5\u97E8\u97EE\u97EF"+ + "\u97F0\u97F1\u97F2\u97F4\u97F7\u97F8\u97F9\u97FA"+ + "\u97FB\u97FC\u97FD\u97FE\u97FF\u9800\u9801\u9802"+ + "\u9803\u9804\u9805\u9806\u9807\u9808\u9809\u980A"+ + "\u980B\u980C\u980D\u980E\u603C\u605D\u605A\u6067"+ + "\u6041\u6059\u6063\u60AB\u6106\u610D\u615D\u61A9"+ + "\u619D\u61CB\u61D1\u6206\u8080\u807F\u6C93\u6CF6"+ + "\u6DFC\u77F6\u77F8\u7800\u7809\u7817\u7818\u7811"+ + "\u65AB\u782D\u781C\u781D\u7839\u783A\u783B\u781F"+ + "\u783C\u7825\u782C\u7823\u7829\u784E\u786D\u7856"+ + "\u7857\u7826\u7850\u7847\u784C\u786A\u789B\u7893"+ + "\u789A\u7887\u789C\u78A1\u78A3\u78B2\u78B9\u78A5"+ + "\u78D4\u78D9\u78C9\u78EC\u78F2\u7905\u78F4\u7913"+ + "\u7924\u791E\u7934\u9F9B\u9EF9\u9EFB\u9EFC\u76F1"+ + "\u7704\u770D\u76F9\u7707\u7708\u771A\u7722\u7719"+ + "\u772D\u7726\u7735\u7738\u7750\u7751\u7747\u7743"+ + "\u775A\u7768\u980F\u9810\u9811\u9812\u9813\u9814"+ + "\u9815\u9816\u9817\u9818\u9819\u981A\u981B\u981C"+ + "\u981D\u981E\u981F\u9820\u9821\u9822\u9823\u9824"+ + "\u9825\u9826\u9827\u9828\u9829\u982A\u982B\u982C"+ + "\u982D\u982E\u982F\u9830\u9831\u9832\u9833\u9834"+ + "\u9835\u9836\u9837\u9838\u9839\u983A\u983B\u983C"+ + "\u983D\u983E\u983F\u9840\u9841\u9842\u9843\u9844"+ + "\u9845\u9846\u9847\u9848\u9849\u984A\u984B\u984C"+ + "\u984D\uFFFD\u984E\u984F\u9850\u9851\u9852\u9853"+ + "\u9854\u9855\u9856\u9857\u9858\u9859\u985A\u985B"+ + "\u985C\u985D\u985E\u985F\u9860\u9861\u9862\u9863"+ + "\u9864\u9865\u9866\u9867\u9868\u9869\u986A\u986B"+ + "\u986C\u986D\u986E\u7762\u7765\u777F\u778D\u777D"+ + "\u7780\u778C\u7791\u779F\u77A0\u77B0\u77B5\u77BD"+ + "\u753A\u7540\u754E\u754B\u7548\u755B\u7572\u7579"+ + "\u7583\u7F58\u7F61\u7F5F\u8A48\u7F68\u7F74\u7F71"+ + "\u7F79\u7F81\u7F7E\u76CD\u76E5\u8832\u9485\u9486"+ + "\u9487\u948B\u948A\u948C\u948D\u948F\u9490\u9494"+ + "\u9497\u9495\u949A\u949B\u949C\u94A3\u94A4\u94AB"+ + "\u94AA\u94AD\u94AC\u94AF\u94B0\u94B2\u94B4\u94B6"+ + "\u94B7\u94B8\u94B9\u94BA\u94BC\u94BD\u94BF\u94C4"+ + "\u94C8\u94C9\u94CA\u94CB\u94CC\u94CD\u94CE\u94D0"+ + "\u94D1\u94D2\u94D5\u94D6\u94D7\u94D9\u94D8\u94DB"+ + "\u94DE\u94DF\u94E0\u94E2\u94E4\u94E5\u94E7\u94E8"+ + "\u94EA\u986F\u9870\u9871\u9872\u9873\u9874\u988B"+ + "\u988E\u9892\u9895\u9899\u98A3\u98A8\u98A9\u98AA"+ + "\u98AB\u98AC\u98AD\u98AE\u98AF\u98B0\u98B1\u98B2"+ + "\u98B3\u98B4\u98B5\u98B6\u98B7\u98B8\u98B9\u98BA"+ + "\u98BB\u98BC\u98BD\u98BE\u98BF\u98C0\u98C1\u98C2"+ + "\u98C3\u98C4\u98C5\u98C6\u98C7\u98C8\u98C9\u98CA"+ + "\u98CB\u98CC\u98CD\u98CF\u98D0\u98D4\u98D6\u98D7"+ + "\u98DB\u98DC\u98DD\u98E0\u98E1\u98E2\u98E3\u98E4"+ + "\uFFFD\u98E5\u98E6\u98E9\u98EA\u98EB\u98EC\u98ED"+ + "\u98EE\u98EF\u98F0\u98F1\u98F2\u98F3\u98F4\u98F5"+ + "\u98F6\u98F7\u98F8\u98F9\u98FA\u98FB\u98FC\u98FD"+ + "\u98FE\u98FF\u9900\u9901\u9902\u9903\u9904\u9905"+ + "\u9906\u9907\u94E9\u94EB\u94EE\u94EF\u94F3\u94F4"+ + "\u94F5\u94F7\u94F9\u94FC\u94FD\u94FF\u9503\u9502"+ + "\u9506\u9507\u9509\u950A\u950D\u950E\u950F\u9512"+ + "\u9513\u9514\u9515\u9516\u9518\u951B\u951D\u951E"+ + "\u951F\u9522\u952A\u952B\u9529\u952C\u9531\u9532"+ + "\u9534\u9536\u9537\u9538\u953C\u953E\u953F\u9542"+ + "\u9535\u9544\u9545\u9546\u9549\u954C\u954E\u954F"+ + "\u9552\u9553\u9554\u9556\u9557\u9558\u9559\u955B"+ + "\u955E\u955F\u955D\u9561\u9562\u9564\u9565\u9566"+ + "\u9567\u9568\u9569\u956A\u956B\u956C\u956F\u9571"+ + "\u9572\u9573\u953A\u77E7\u77EC\u96C9\u79D5\u79ED"+ + "\u79E3\u79EB\u7A06\u5D47\u7A03\u7A02\u7A1E\u7A14"; + + private static final String innerIndex7= + "\u9908\u9909\u990A\u990B\u990C\u990E\u990F\u9911"+ + "\u9912\u9913\u9914\u9915\u9916\u9917\u9918\u9919"+ + "\u991A\u991B\u991C\u991D\u991E\u991F\u9920\u9921"+ + "\u9922\u9923\u9924\u9925\u9926\u9927\u9928\u9929"+ + "\u992A\u992B\u992C\u992D\u992F\u9930\u9931\u9932"+ + "\u9933\u9934\u9935\u9936\u9937\u9938\u9939\u993A"+ + "\u993B\u993C\u993D\u993E\u993F\u9940\u9941\u9942"+ + "\u9943\u9944\u9945\u9946\u9947\u9948\u9949\uFFFD"+ + "\u994A\u994B\u994C\u994D\u994E\u994F\u9950\u9951"+ + "\u9952\u9953\u9956\u9957\u9958\u9959\u995A\u995B"+ + "\u995C\u995D\u995E\u995F\u9960\u9961\u9962\u9964"+ + "\u9966\u9973\u9978\u9979\u997B\u997E\u9982\u9983"+ + "\u9989\u7A39\u7A37\u7A51\u9ECF\u99A5\u7A70\u7688"+ + "\u768E\u7693\u7699\u76A4\u74DE\u74E0\u752C\u9E20"+ + "\u9E22\u9E28\u9E29\u9E2A\u9E2B\u9E2C\u9E32\u9E31"+ + "\u9E36\u9E38\u9E37\u9E39\u9E3A\u9E3E\u9E41\u9E42"+ + "\u9E44\u9E46\u9E47\u9E48\u9E49\u9E4B\u9E4C\u9E4E"+ + "\u9E51\u9E55\u9E57\u9E5A\u9E5B\u9E5C\u9E5E\u9E63"+ + "\u9E66\u9E67\u9E68\u9E69\u9E6A\u9E6B\u9E6C\u9E71"+ + "\u9E6D\u9E73\u7592\u7594\u7596\u75A0\u759D\u75AC"+ + "\u75A3\u75B3\u75B4\u75B8\u75C4\u75B1\u75B0\u75C3"+ + "\u75C2\u75D6\u75CD\u75E3\u75E8\u75E6\u75E4\u75EB"+ + "\u75E7\u7603\u75F1\u75FC\u75FF\u7610\u7600\u7605"+ + "\u760C\u7617\u760A\u7625\u7618\u7615\u7619\u998C"+ + "\u998E\u999A\u999B\u999C\u999D\u999E\u999F\u99A0"+ + "\u99A1\u99A2\u99A3\u99A4\u99A6\u99A7\u99A9\u99AA"+ + "\u99AB\u99AC\u99AD\u99AE\u99AF\u99B0\u99B1\u99B2"+ + "\u99B3\u99B4\u99B5\u99B6\u99B7\u99B8\u99B9\u99BA"+ + "\u99BB\u99BC\u99BD\u99BE\u99BF\u99C0\u99C1\u99C2"+ + "\u99C3\u99C4\u99C5\u99C6\u99C7\u99C8\u99C9\u99CA"+ + "\u99CB\u99CC\u99CD\u99CE\u99CF\u99D0\u99D1\u99D2"+ + "\u99D3\u99D4\u99D5\u99D6\u99D7\u99D8\uFFFD\u99D9"+ + "\u99DA\u99DB\u99DC\u99DD\u99DE\u99DF\u99E0\u99E1"+ + "\u99E2\u99E3\u99E4\u99E5\u99E6\u99E7\u99E8\u99E9"+ + "\u99EA\u99EB\u99EC\u99ED\u99EE\u99EF\u99F0\u99F1"+ + "\u99F2\u99F3\u99F4\u99F5\u99F6\u99F7\u99F8\u99F9"+ + "\u761B\u763C\u7622\u7620\u7640\u762D\u7630\u763F"+ + "\u7635\u7643\u763E\u7633\u764D\u765E\u7654\u765C"+ + "\u7656\u766B\u766F\u7FCA\u7AE6\u7A78\u7A79\u7A80"+ + "\u7A86\u7A88\u7A95\u7AA6\u7AA0\u7AAC\u7AA8\u7AAD"+ + "\u7AB3\u8864\u8869\u8872\u887D\u887F\u8882\u88A2"+ + "\u88C6\u88B7\u88BC\u88C9\u88E2\u88CE\u88E3\u88E5"+ + "\u88F1\u891A\u88FC\u88E8\u88FE\u88F0\u8921\u8919"+ + "\u8913\u891B\u890A\u8934\u892B\u8936\u8941\u8966"+ + "\u897B\u758B\u80E5\u76B2\u76B4\u77DC\u8012\u8014"+ + "\u8016\u801C\u8020\u8022\u8025\u8026\u8027\u8029"+ + "\u8028\u8031\u800B\u8035\u8043\u8046\u804D\u8052"+ + "\u8069\u8071\u8983\u9878\u9880\u9883\u99FA\u99FB"+ + "\u99FC\u99FD\u99FE\u99FF\u9A00\u9A01\u9A02\u9A03"+ + "\u9A04\u9A05\u9A06\u9A07\u9A08\u9A09\u9A0A\u9A0B"+ + "\u9A0C\u9A0D\u9A0E\u9A0F\u9A10\u9A11\u9A12\u9A13"+ + "\u9A14\u9A15\u9A16\u9A17\u9A18\u9A19\u9A1A\u9A1B"+ + "\u9A1C\u9A1D\u9A1E\u9A1F\u9A20\u9A21\u9A22\u9A23"+ + "\u9A24\u9A25\u9A26\u9A27\u9A28\u9A29\u9A2A\u9A2B"+ + "\u9A2C\u9A2D\u9A2E\u9A2F\u9A30\u9A31\u9A32\u9A33"+ + "\u9A34\u9A35\u9A36\u9A37\u9A38\uFFFD\u9A39\u9A3A"+ + "\u9A3B\u9A3C\u9A3D\u9A3E\u9A3F\u9A40\u9A41\u9A42"+ + "\u9A43\u9A44\u9A45\u9A46\u9A47\u9A48\u9A49\u9A4A"+ + "\u9A4B\u9A4C\u9A4D\u9A4E\u9A4F\u9A50\u9A51\u9A52"+ + "\u9A53\u9A54\u9A55\u9A56\u9A57\u9A58\u9A59\u9889"+ + "\u988C\u988D\u988F\u9894\u989A\u989B\u989E\u989F"+ + "\u98A1\u98A2\u98A5\u98A6\u864D\u8654\u866C\u866E"+ + "\u867F\u867A\u867C\u867B\u86A8\u868D\u868B\u86AC"+ + "\u869D\u86A7\u86A3\u86AA\u8693\u86A9\u86B6\u86C4"+ + "\u86B5\u86CE\u86B0\u86BA\u86B1\u86AF\u86C9\u86CF"+ + "\u86B4\u86E9\u86F1\u86F2\u86ED\u86F3\u86D0\u8713"+ + "\u86DE\u86F4\u86DF\u86D8\u86D1\u8703\u8707\u86F8"+ + "\u8708\u870A\u870D\u8709\u8723\u873B\u871E\u8725"+ + "\u872E\u871A\u873E\u8748\u8734\u8731\u8729\u8737"+ + "\u873F\u8782\u8722\u877D\u877E\u877B\u8760\u8770"+ + "\u874C\u876E\u878B\u8753\u8763\u877C\u8764\u8759"+ + "\u8765\u8793\u87AF\u87A8\u87D2\u9A5A\u9A5B\u9A5C"+ + "\u9A5D\u9A5E\u9A5F\u9A60\u9A61\u9A62\u9A63\u9A64"+ + "\u9A65\u9A66\u9A67\u9A68\u9A69\u9A6A\u9A6B\u9A72"+ + "\u9A83\u9A89\u9A8D\u9A8E\u9A94\u9A95\u9A99\u9AA6"+ + "\u9AA9\u9AAA\u9AAB\u9AAC\u9AAD\u9AAE\u9AAF\u9AB2"+ + "\u9AB3\u9AB4\u9AB5\u9AB9\u9ABB\u9ABD\u9ABE\u9ABF"+ + "\u9AC3\u9AC4\u9AC6\u9AC7\u9AC8\u9AC9\u9ACA\u9ACD"+ + "\u9ACE\u9ACF\u9AD0\u9AD2\u9AD4\u9AD5\u9AD6\u9AD7"+ + "\u9AD9\u9ADA\u9ADB\u9ADC\uFFFD\u9ADD\u9ADE\u9AE0"+ + "\u9AE2\u9AE3\u9AE4\u9AE5\u9AE7\u9AE8\u9AE9\u9AEA"+ + "\u9AEC\u9AEE\u9AF0\u9AF1\u9AF2\u9AF3\u9AF4\u9AF5"+ + "\u9AF6\u9AF7\u9AF8\u9AFA\u9AFC\u9AFD\u9AFE\u9AFF"+ + "\u9B00\u9B01\u9B02\u9B04\u9B05\u9B06\u87C6\u8788"+ + "\u8785\u87AD\u8797\u8783\u87AB\u87E5\u87AC\u87B5"+ + "\u87B3\u87CB\u87D3\u87BD\u87D1\u87C0\u87CA\u87DB"+ + "\u87EA\u87E0\u87EE\u8816\u8813\u87FE\u880A\u881B"+ + "\u8821\u8839\u883C\u7F36\u7F42\u7F44\u7F45\u8210"+ + "\u7AFA\u7AFD\u7B08\u7B03\u7B04\u7B15\u7B0A\u7B2B"+ + "\u7B0F\u7B47\u7B38\u7B2A\u7B19\u7B2E\u7B31\u7B20"+ + "\u7B25\u7B24\u7B33\u7B3E\u7B1E\u7B58\u7B5A\u7B45"+ + "\u7B75\u7B4C\u7B5D\u7B60\u7B6E\u7B7B\u7B62\u7B72"+ + "\u7B71\u7B90\u7BA6\u7BA7\u7BB8\u7BAC\u7B9D\u7BA8"+ + "\u7B85\u7BAA\u7B9C\u7BA2\u7BAB\u7BB4\u7BD1\u7BC1"+ + "\u7BCC\u7BDD\u7BDA\u7BE5\u7BE6\u7BEA\u7C0C\u7BFE"+ + "\u7BFC\u7C0F\u7C16\u7C0B\u9B07\u9B09\u9B0A\u9B0B"+ + "\u9B0C\u9B0D\u9B0E\u9B10\u9B11\u9B12\u9B14\u9B15"+ + "\u9B16\u9B17\u9B18\u9B19\u9B1A\u9B1B\u9B1C\u9B1D"+ + "\u9B1E\u9B20\u9B21\u9B22\u9B24\u9B25\u9B26\u9B27"+ + "\u9B28\u9B29\u9B2A\u9B2B\u9B2C\u9B2D\u9B2E\u9B30"+ + "\u9B31\u9B33\u9B34\u9B35\u9B36\u9B37\u9B38\u9B39"+ + "\u9B3A\u9B3D\u9B3E\u9B3F\u9B40\u9B46\u9B4A\u9B4B"+ + "\u9B4C\u9B4E\u9B50\u9B52\u9B53\u9B55\u9B56\u9B57"+ + "\u9B58\u9B59\u9B5A\uFFFD\u9B5B\u9B5C\u9B5D\u9B5E"+ + "\u9B5F\u9B60\u9B61\u9B62\u9B63\u9B64\u9B65\u9B66"+ + "\u9B67\u9B68\u9B69\u9B6A\u9B6B\u9B6C\u9B6D\u9B6E"+ + "\u9B6F\u9B70\u9B71\u9B72\u9B73\u9B74\u9B75\u9B76"+ + "\u9B77\u9B78\u9B79\u9B7A\u9B7B\u7C1F\u7C2A\u7C26"+ + "\u7C38\u7C41\u7C40\u81FE\u8201\u8202\u8204\u81EC"+ + "\u8844\u8221\u8222\u8223\u822D\u822F\u8228\u822B"+ + "\u8238\u823B\u8233\u8234\u823E\u8244\u8249\u824B"+ + "\u824F\u825A\u825F\u8268\u887E\u8885\u8888\u88D8"+ + "\u88DF\u895E\u7F9D\u7F9F\u7FA7\u7FAF\u7FB0\u7FB2"+ + "\u7C7C\u6549\u7C91\u7C9D\u7C9C\u7C9E\u7CA2\u7CB2"+ + "\u7CBC\u7CBD\u7CC1\u7CC7\u7CCC\u7CCD\u7CC8\u7CC5"+ + "\u7CD7\u7CE8\u826E\u66A8\u7FBF\u7FCE\u7FD5\u7FE5"+ + "\u7FE1\u7FE6\u7FE9\u7FEE\u7FF3\u7CF8\u7D77\u7DA6"+ + "\u7DAE\u7E47\u7E9B\u9EB8\u9EB4\u8D73\u8D84\u8D94"+ + "\u8D91\u8DB1\u8D67\u8D6D\u8C47\u8C49\u914A\u9150"+ + "\u914E\u914F\u9164\u9B7C\u9B7D\u9B7E\u9B7F\u9B80"+ + "\u9B81\u9B82\u9B83\u9B84\u9B85\u9B86\u9B87\u9B88"+ + "\u9B89\u9B8A\u9B8B\u9B8C\u9B8D\u9B8E\u9B8F\u9B90"+ + "\u9B91\u9B92\u9B93\u9B94\u9B95\u9B96\u9B97\u9B98"+ + "\u9B99\u9B9A\u9B9B\u9B9C\u9B9D\u9B9E\u9B9F\u9BA0"+ + "\u9BA1\u9BA2\u9BA3\u9BA4\u9BA5\u9BA6\u9BA7\u9BA8"+ + "\u9BA9\u9BAA\u9BAB\u9BAC\u9BAD\u9BAE\u9BAF\u9BB0"+ + "\u9BB1\u9BB2\u9BB3\u9BB4\u9BB5\u9BB6\u9BB7\u9BB8"+ + "\u9BB9\u9BBA\uFFFD\u9BBB\u9BBC\u9BBD\u9BBE\u9BBF"+ + "\u9BC0\u9BC1\u9BC2\u9BC3\u9BC4\u9BC5\u9BC6\u9BC7"+ + "\u9BC8\u9BC9\u9BCA\u9BCB\u9BCC\u9BCD\u9BCE\u9BCF"+ + "\u9BD0\u9BD1\u9BD2\u9BD3\u9BD4\u9BD5\u9BD6\u9BD7"+ + "\u9BD8\u9BD9\u9BDA\u9BDB\u9162\u9161\u9170\u9169"+ + "\u916F\u917D\u917E\u9172\u9174\u9179\u918C\u9185"+ + "\u9190\u918D\u9191\u91A2\u91A3\u91AA\u91AD\u91AE"+ + "\u91AF\u91B5\u91B4\u91BA\u8C55\u9E7E\u8DB8\u8DEB"+ + "\u8E05\u8E59\u8E69\u8DB5\u8DBF\u8DBC\u8DBA\u8DC4"+ + "\u8DD6\u8DD7\u8DDA\u8DDE\u8DCE\u8DCF\u8DDB\u8DC6"+ + "\u8DEC\u8DF7\u8DF8\u8DE3\u8DF9\u8DFB\u8DE4\u8E09"+ + "\u8DFD\u8E14\u8E1D\u8E1F\u8E2C\u8E2E\u8E23\u8E2F"+ + "\u8E3A\u8E40\u8E39\u8E35\u8E3D\u8E31\u8E49\u8E41"+ + "\u8E42\u8E51\u8E52\u8E4A\u8E70\u8E76\u8E7C\u8E6F"+ + "\u8E74\u8E85\u8E8F\u8E94\u8E90\u8E9C\u8E9E\u8C78"+ + "\u8C82\u8C8A\u8C85\u8C98\u8C94\u659B\u89D6\u89DE"+ + "\u89DA\u89DC\u9BDC\u9BDD\u9BDE\u9BDF\u9BE0\u9BE1"+ + "\u9BE2\u9BE3\u9BE4\u9BE5\u9BE6\u9BE7\u9BE8\u9BE9"+ + "\u9BEA\u9BEB\u9BEC\u9BED\u9BEE\u9BEF\u9BF0\u9BF1"+ + "\u9BF2\u9BF3\u9BF4\u9BF5\u9BF6\u9BF7\u9BF8\u9BF9"+ + "\u9BFA\u9BFB\u9BFC\u9BFD\u9BFE\u9BFF\u9C00\u9C01"+ + "\u9C02\u9C03\u9C04\u9C05\u9C06\u9C07\u9C08\u9C09"+ + "\u9C0A\u9C0B\u9C0C\u9C0D\u9C0E\u9C0F\u9C10\u9C11"+ + "\u9C12\u9C13\u9C14\u9C15\u9C16\u9C17\u9C18\u9C19"+ + "\u9C1A\uFFFD\u9C1B\u9C1C\u9C1D\u9C1E\u9C1F\u9C20"+ + "\u9C21\u9C22\u9C23\u9C24\u9C25\u9C26\u9C27\u9C28"+ + "\u9C29\u9C2A\u9C2B\u9C2C\u9C2D\u9C2E\u9C2F\u9C30"+ + "\u9C31\u9C32\u9C33\u9C34\u9C35\u9C36\u9C37\u9C38"+ + "\u9C39\u9C3A\u9C3B\u89E5\u89EB\u89EF\u8A3E\u8B26"+ + "\u9753\u96E9\u96F3\u96EF\u9706\u9701\u9708\u970F"+ + "\u970E\u972A\u972D\u9730\u973E\u9F80\u9F83\u9F85"+ + "\u9F86\u9F87\u9F88\u9F89\u9F8A\u9F8C\u9EFE\u9F0B"+ + "\u9F0D\u96B9\u96BC\u96BD\u96CE\u96D2\u77BF\u96E0"+ + "\u928E\u92AE\u92C8\u933E\u936A\u93CA\u938F\u943E"+ + "\u946B\u9C7F\u9C82\u9C85\u9C86\u9C87\u9C88\u7A23"+ + "\u9C8B\u9C8E\u9C90\u9C91\u9C92\u9C94\u9C95\u9C9A"+ + "\u9C9B\u9C9E\u9C9F\u9CA0\u9CA1\u9CA2\u9CA3\u9CA5"+ + "\u9CA6\u9CA7\u9CA8\u9CA9\u9CAB\u9CAD\u9CAE\u9CB0"+ + "\u9CB1\u9CB2\u9CB3\u9CB4\u9CB5\u9CB6\u9CB7\u9CBA"+ + "\u9CBB\u9CBC\u9CBD\u9CC4\u9CC5\u9CC6\u9CC7\u9CCA"+ + "\u9CCB\u9C3C\u9C3D\u9C3E\u9C3F\u9C40\u9C41\u9C42"+ + "\u9C43\u9C44\u9C45\u9C46\u9C47\u9C48\u9C49\u9C4A"+ + "\u9C4B\u9C4C\u9C4D\u9C4E\u9C4F\u9C50\u9C51\u9C52"+ + "\u9C53\u9C54\u9C55\u9C56\u9C57\u9C58\u9C59\u9C5A"+ + "\u9C5B\u9C5C\u9C5D\u9C5E\u9C5F\u9C60\u9C61\u9C62"+ + "\u9C63\u9C64\u9C65\u9C66\u9C67\u9C68\u9C69\u9C6A"+ + "\u9C6B\u9C6C\u9C6D\u9C6E\u9C6F\u9C70\u9C71\u9C72"+ + "\u9C73\u9C74\u9C75\u9C76\u9C77\u9C78\u9C79\u9C7A"+ + "\uFFFD\u9C7B\u9C7D\u9C7E\u9C80\u9C83\u9C84\u9C89"+ + "\u9C8A\u9C8C\u9C8F\u9C93\u9C96\u9C97\u9C98\u9C99"+ + "\u9C9D\u9CAA\u9CAC\u9CAF\u9CB9\u9CBE\u9CBF\u9CC0"+ + "\u9CC1\u9CC2\u9CC8\u9CC9\u9CD1\u9CD2\u9CDA\u9CDB"+ + "\u9CE0\u9CE1\u9CCC\u9CCD\u9CCE\u9CCF\u9CD0\u9CD3"+ + "\u9CD4\u9CD5\u9CD7\u9CD8\u9CD9\u9CDC\u9CDD\u9CDF"+ + "\u9CE2\u977C\u9785\u9791\u9792\u9794\u97AF\u97AB"+ + "\u97A3\u97B2\u97B4\u9AB1\u9AB0\u9AB7\u9E58\u9AB6"+ + "\u9ABA\u9ABC\u9AC1\u9AC0\u9AC5\u9AC2\u9ACB\u9ACC"+ + "\u9AD1\u9B45\u9B43\u9B47\u9B49\u9B48\u9B4D\u9B51"+ + "\u98E8\u990D\u992E\u9955\u9954\u9ADF\u9AE1\u9AE6"+ + "\u9AEF\u9AEB\u9AFB\u9AED\u9AF9\u9B08\u9B0F\u9B13"+ + "\u9B1F\u9B23\u9EBD\u9EBE\u7E3B\u9E82\u9E87\u9E88"+ + "\u9E8B\u9E92\u93D6\u9E9D\u9E9F\u9EDB\u9EDC\u9EDD"+ + "\u9EE0\u9EDF\u9EE2\u9EE9\u9EE7\u9EE5\u9EEA\u9EEF"+ + "\u9F22\u9F2C\u9F2F\u9F39\u9F37\u9F3D\u9F3E\u9F44"+ + "\u9CE3\u9CE4\u9CE5\u9CE6\u9CE7\u9CE8\u9CE9\u9CEA"+ + "\u9CEB\u9CEC\u9CED\u9CEE\u9CEF\u9CF0\u9CF1\u9CF2"+ + "\u9CF3\u9CF4\u9CF5\u9CF6\u9CF7\u9CF8\u9CF9\u9CFA"+ + "\u9CFB\u9CFC\u9CFD\u9CFE\u9CFF\u9D00\u9D01\u9D02"+ + "\u9D03\u9D04\u9D05\u9D06\u9D07\u9D08\u9D09\u9D0A"+ + "\u9D0B\u9D0C\u9D0D\u9D0E\u9D0F\u9D10\u9D11\u9D12"+ + "\u9D13\u9D14\u9D15\u9D16\u9D17\u9D18\u9D19\u9D1A"+ + "\u9D1B\u9D1C\u9D1D\u9D1E\u9D1F\u9D20\u9D21\uFFFD"+ + "\u9D22\u9D23\u9D24\u9D25\u9D26\u9D27\u9D28\u9D29"+ + "\u9D2A\u9D2B\u9D2C\u9D2D\u9D2E\u9D2F\u9D30\u9D31"+ + "\u9D32\u9D33\u9D34\u9D35\u9D36\u9D37\u9D38\u9D39"+ + "\u9D3A\u9D3B\u9D3C\u9D3D\u9D3E\u9D3F\u9D40\u9D41"+ + "\u9D42\uE234\uE235\uE236\uE237\uE238\uE239\uE23A"+ + "\uE23B\uE23C\uE23D\uE23E\uE23F\uE240\uE241\uE242"+ + "\uE243\uE244\uE245\uE246\uE247\uE248\uE249\uE24A"+ + "\uE24B\uE24C\uE24D\uE24E\uE24F\uE250\uE251\uE252"+ + "\uE253\uE254\uE255\uE256\uE257\uE258\uE259\uE25A"+ + "\uE25B\uE25C\uE25D\uE25E\uE25F\uE260\uE261\uE262"+ + "\uE263\uE264\uE265\uE266\uE267\uE268\uE269\uE26A"+ + "\uE26B\uE26C\uE26D\uE26E\uE26F\uE270\uE271\uE272"+ + "\uE273\uE274\uE275\uE276\uE277\uE278\uE279\uE27A"+ + "\uE27B\uE27C\uE27D\uE27E\uE27F\uE280\uE281\uE282"+ + "\uE283\uE284\uE285\uE286\uE287\uE288\uE289\uE28A"+ + "\uE28B\uE28C\uE28D\uE28E\uE28F\uE290\uE291\u9D43"+ + "\u9D44\u9D45\u9D46\u9D47\u9D48\u9D49\u9D4A\u9D4B"+ + "\u9D4C\u9D4D\u9D4E\u9D4F\u9D50\u9D51\u9D52\u9D53"+ + "\u9D54\u9D55\u9D56\u9D57\u9D58\u9D59\u9D5A\u9D5B"+ + "\u9D5C\u9D5D\u9D5E\u9D5F\u9D60\u9D61\u9D62\u9D63"+ + "\u9D64\u9D65\u9D66\u9D67\u9D68\u9D69\u9D6A\u9D6B"+ + "\u9D6C\u9D6D\u9D6E\u9D6F\u9D70\u9D71\u9D72\u9D73"+ + "\u9D74\u9D75\u9D76\u9D77\u9D78\u9D79\u9D7A\u9D7B"+ + "\u9D7C\u9D7D\u9D7E\u9D7F\u9D80\u9D81\uFFFD\u9D82"+ + "\u9D83\u9D84\u9D85\u9D86\u9D87\u9D88\u9D89\u9D8A"+ + "\u9D8B\u9D8C\u9D8D\u9D8E\u9D8F\u9D90\u9D91\u9D92"+ + "\u9D93\u9D94\u9D95\u9D96\u9D97\u9D98\u9D99\u9D9A"+ + "\u9D9B\u9D9C\u9D9D\u9D9E\u9D9F\u9DA0\u9DA1\u9DA2"+ + "\uE292\uE293\uE294\uE295\uE296\uE297\uE298\uE299"+ + "\uE29A\uE29B\uE29C\uE29D\uE29E\uE29F\uE2A0\uE2A1"+ + "\uE2A2\uE2A3\uE2A4\uE2A5\uE2A6\uE2A7\uE2A8\uE2A9"+ + "\uE2AA\uE2AB\uE2AC\uE2AD\uE2AE\uE2AF\uE2B0\uE2B1"+ + "\uE2B2\uE2B3\uE2B4\uE2B5\uE2B6\uE2B7\uE2B8\uE2B9"+ + "\uE2BA\uE2BB\uE2BC\uE2BD\uE2BE\uE2BF\uE2C0\uE2C1"+ + "\uE2C2\uE2C3\uE2C4\uE2C5\uE2C6\uE2C7\uE2C8\uE2C9"+ + "\uE2CA\uE2CB\uE2CC\uE2CD\uE2CE\uE2CF\uE2D0\uE2D1"+ + "\uE2D2\uE2D3\uE2D4\uE2D5\uE2D6\uE2D7\uE2D8\uE2D9"+ + "\uE2DA\uE2DB\uE2DC\uE2DD\uE2DE\uE2DF\uE2E0\uE2E1"+ + "\uE2E2\uE2E3\uE2E4\uE2E5\uE2E6\uE2E7\uE2E8\uE2E9"+ + "\uE2EA\uE2EB\uE2EC\uE2ED\uE2EE\uE2EF\u9DA3\u9DA4"+ + "\u9DA5\u9DA6\u9DA7\u9DA8\u9DA9\u9DAA\u9DAB\u9DAC"+ + "\u9DAD\u9DAE\u9DAF\u9DB0\u9DB1\u9DB2\u9DB3\u9DB4"+ + "\u9DB5\u9DB6\u9DB7\u9DB8\u9DB9\u9DBA\u9DBB\u9DBC"+ + "\u9DBD\u9DBE\u9DBF\u9DC0\u9DC1\u9DC2\u9DC3\u9DC4"+ + "\u9DC5\u9DC6\u9DC7\u9DC8\u9DC9\u9DCA\u9DCB\u9DCC"+ + "\u9DCD\u9DCE\u9DCF\u9DD0\u9DD1\u9DD2\u9DD3\u9DD4"+ + "\u9DD5\u9DD6\u9DD7\u9DD8\u9DD9\u9DDA\u9DDB\u9DDC"+ + "\u9DDD\u9DDE\u9DDF\u9DE0\u9DE1\uFFFD\u9DE2\u9DE3"+ + "\u9DE4\u9DE5\u9DE6\u9DE7\u9DE8\u9DE9\u9DEA\u9DEB"+ + "\u9DEC\u9DED\u9DEE\u9DEF\u9DF0\u9DF1\u9DF2\u9DF3"+ + "\u9DF4\u9DF5\u9DF6\u9DF7\u9DF8\u9DF9\u9DFA\u9DFB"+ + "\u9DFC\u9DFD\u9DFE\u9DFF\u9E00\u9E01\u9E02\uE2F0"+ + "\uE2F1\uE2F2\uE2F3\uE2F4\uE2F5\uE2F6\uE2F7\uE2F8"+ + "\uE2F9\uE2FA\uE2FB\uE2FC\uE2FD\uE2FE\uE2FF\uE300"+ + "\uE301\uE302\uE303\uE304\uE305\uE306\uE307\uE308"+ + "\uE309\uE30A\uE30B\uE30C\uE30D\uE30E\uE30F\uE310"+ + "\uE311\uE312\uE313\uE314\uE315\uE316\uE317\uE318"+ + "\uE319\uE31A\uE31B\uE31C\uE31D\uE31E\uE31F\uE320"+ + "\uE321\uE322\uE323\uE324\uE325\uE326\uE327\uE328"+ + "\uE329\uE32A\uE32B\uE32C\uE32D\uE32E\uE32F\uE330"+ + "\uE331\uE332\uE333\uE334\uE335\uE336\uE337\uE338"+ + "\uE339\uE33A\uE33B\uE33C\uE33D\uE33E\uE33F\uE340"+ + "\uE341\uE342\uE343\uE344\uE345\uE346\uE347\uE348"+ + "\uE349\uE34A\uE34B\uE34C\uE34D\u9E03\u9E04\u9E05"+ + "\u9E06\u9E07\u9E08\u9E09\u9E0A\u9E0B\u9E0C\u9E0D"+ + "\u9E0E\u9E0F\u9E10\u9E11\u9E12\u9E13\u9E14\u9E15"+ + "\u9E16\u9E17\u9E18\u9E19\u9E1A\u9E1B\u9E1C\u9E1D"+ + "\u9E1E\u9E24\u9E27\u9E2E\u9E30\u9E34\u9E3B\u9E3C"+ + "\u9E40\u9E4D\u9E50\u9E52\u9E53\u9E54\u9E56\u9E59"+ + "\u9E5D\u9E5F\u9E60\u9E61\u9E62\u9E65\u9E6E\u9E6F"+ + "\u9E72\u9E74\u9E75\u9E76\u9E77\u9E78\u9E79\u9E7A"+ + "\u9E7B\u9E7C\u9E7D\u9E80\uFFFD\u9E81\u9E83\u9E84"+ + "\u9E85\u9E86\u9E89\u9E8A\u9E8C\u9E8D\u9E8E\u9E8F"+ + "\u9E90\u9E91\u9E94\u9E95\u9E96\u9E97\u9E98\u9E99"+ + "\u9E9A\u9E9B\u9E9C\u9E9E\u9EA0\u9EA1\u9EA2\u9EA3"+ + "\u9EA4\u9EA5\u9EA7\u9EA8\u9EA9\u9EAA\uE34E\uE34F"+ + "\uE350\uE351\uE352\uE353\uE354\uE355\uE356\uE357"+ + "\uE358\uE359\uE35A\uE35B\uE35C\uE35D\uE35E\uE35F"+ + "\uE360\uE361\uE362\uE363\uE364\uE365\uE366\uE367"+ + "\uE368\uE369\uE36A\uE36B\uE36C\uE36D\uE36E\uE36F"+ + "\uE370\uE371\uE372\uE373\uE374\uE375\uE376\uE377"+ + "\uE378\uE379\uE37A\uE37B\uE37C\uE37D\uE37E\uE37F"+ + "\uE380\uE381\uE382\uE383\uE384\uE385\uE386\uE387"+ + "\uE388\uE389\uE38A\uE38B\uE38C\uE38D\uE38E\uE38F"+ + "\uE390\uE391\uE392\uE393\uE394\uE395\uE396\uE397"+ + "\uE398\uE399\uE39A\uE39B\uE39C\uE39D\uE39E\uE39F"+ + "\uE3A0\uE3A1\uE3A2\uE3A3\uE3A4\uE3A5\uE3A6\uE3A7"+ + "\uE3A8\uE3A9\uE3AA\uE3AB\u9EAB\u9EAC\u9EAD\u9EAE"+ + "\u9EAF\u9EB0\u9EB1\u9EB2\u9EB3\u9EB5\u9EB6\u9EB7"+ + "\u9EB9\u9EBA\u9EBC\u9EBF\u9EC0\u9EC1\u9EC2\u9EC3"+ + "\u9EC5\u9EC6\u9EC7\u9EC8\u9ECA\u9ECB\u9ECC\u9ED0"+ + "\u9ED2\u9ED3\u9ED5\u9ED6\u9ED7\u9ED9\u9EDA\u9EDE"+ + "\u9EE1\u9EE3\u9EE4\u9EE6\u9EE8\u9EEB\u9EEC\u9EED"+ + "\u9EEE\u9EF0\u9EF1\u9EF2\u9EF3\u9EF4\u9EF5\u9EF6"+ + "\u9EF7\u9EF8\u9EFA\u9EFD\u9EFF\u9F00\u9F01\u9F02"+ + "\u9F03\u9F04\u9F05\uFFFD\u9F06\u9F07\u9F08\u9F09"+ + "\u9F0A\u9F0C\u9F0F\u9F11\u9F12\u9F14\u9F15\u9F16"+ + "\u9F18\u9F1A\u9F1B\u9F1C\u9F1D\u9F1E\u9F1F\u9F21"+ + "\u9F23\u9F24\u9F25\u9F26\u9F27\u9F28\u9F29\u9F2A"+ + "\u9F2B\u9F2D\u9F2E\u9F30\u9F31\uE3AC\uE3AD\uE3AE"+ + "\uE3AF\uE3B0\uE3B1\uE3B2\uE3B3\uE3B4\uE3B5\uE3B6"+ + "\uE3B7\uE3B8\uE3B9\uE3BA\uE3BB\uE3BC\uE3BD\uE3BE"+ + "\uE3BF\uE3C0\uE3C1\uE3C2\uE3C3\uE3C4\uE3C5\uE3C6"+ + "\uE3C7\uE3C8\uE3C9\uE3CA\uE3CB\uE3CC\uE3CD\uE3CE"+ + "\uE3CF\uE3D0\uE3D1\uE3D2\uE3D3\uE3D4\uE3D5\uE3D6"+ + "\uE3D7\uE3D8\uE3D9\uE3DA\uE3DB\uE3DC\uE3DD\uE3DE"+ + "\uE3DF\uE3E0\uE3E1\uE3E2\uE3E3\uE3E4\uE3E5\uE3E6"+ + "\uE3E7\uE3E8\uE3E9\uE3EA\uE3EB\uE3EC\uE3ED\uE3EE"+ + "\uE3EF\uE3F0\uE3F1\uE3F2\uE3F3\uE3F4\uE3F5\uE3F6"+ + "\uE3F7\uE3F8\uE3F9\uE3FA\uE3FB\uE3FC\uE3FD\uE3FE"+ + "\uE3FF\uE400\uE401\uE402\uE403\uE404\uE405\uE406"+ + "\uE407\uE408\uE409\u9F32\u9F33\u9F34\u9F35\u9F36"+ + "\u9F38\u9F3A\u9F3C\u9F3F\u9F40\u9F41\u9F42\u9F43"+ + "\u9F45\u9F46\u9F47\u9F48\u9F49\u9F4A\u9F4B\u9F4C"+ + "\u9F4D\u9F4E\u9F4F\u9F52\u9F53\u9F54\u9F55\u9F56"+ + "\u9F57\u9F58\u9F59\u9F5A\u9F5B\u9F5C\u9F5D\u9F5E"+ + "\u9F5F\u9F60\u9F61\u9F62\u9F63\u9F64\u9F65\u9F66"+ + "\u9F67\u9F68\u9F69\u9F6A\u9F6B\u9F6C\u9F6D\u9F6E"+ + "\u9F6F\u9F70\u9F71\u9F72\u9F73\u9F74\u9F75\u9F76"+ + "\u9F77\u9F78\uFFFD\u9F79\u9F7A\u9F7B\u9F7C\u9F7D"+ + "\u9F7E\u9F81\u9F82\u9F8D\u9F8E\u9F8F\u9F90\u9F91"+ + "\u9F92\u9F93\u9F94\u9F95\u9F96\u9F97\u9F98\u9F9C"+ + "\u9F9D\u9F9E\u9FA1\u9FA2\u9FA3\u9FA4\u9FA5\uF92C"+ + "\uF979\uF995\uF9E7\uF9F1\uE40A\uE40B\uE40C\uE40D"+ + "\uE40E\uE40F\uE410\uE411\uE412\uE413\uE414\uE415"+ + "\uE416\uE417\uE418\uE419\uE41A\uE41B\uE41C\uE41D"+ + "\uE41E\uE41F\uE420\uE421\uE422\uE423\uE424\uE425"+ + "\uE426\uE427\uE428\uE429\uE42A\uE42B\uE42C\uE42D"+ + "\uE42E\uE42F\uE430\uE431\uE432\uE433\uE434\uE435"+ + "\uE436\uE437\uE438\uE439\uE43A\uE43B\uE43C\uE43D"+ + "\uE43E\uE43F\uE440\uE441\uE442\uE443\uE444\uE445"+ + "\uE446\uE447\uE448\uE449\uE44A\uE44B\uE44C\uE44D"+ + "\uE44E\uE44F\uE450\uE451\uE452\uE453\uE454\uE455"+ + "\uE456\uE457\uE458\uE459\uE45A\uE45B\uE45C\uE45D"+ + "\uE45E\uE45F\uE460\uE461\uE462\uE463\uE464\uE465"+ + "\uE466\uE467\uFA0C\uFA0D\uFA0E\uFA0F\uFA11\uFA13"+ + "\uFA14\uFA18\uFA1F\uFA20\uFA21\uFA23\uFA24\uFA27"+ + "\uFA28\uFA29\u2E81\uE816\uE817\uE818\u2E84\u3473"+ + (IS_2000 ? "\u3447\u2E88\u2E8B\uE81E\u359E\u361A\u360E\u2E8C"+ + "\u2E97\u396E\u3918\uE826\u39CF\u39DF\u3A73\u39D0"+ + "\uE82B\uE82C\u3B4E\u3C6E\u3CE0\u2EA7\uE831\uE832" : + "\u3447\u2E88\u2E8B\u9FB4\u359E\u361A\u360E\u2E8C"+ + "\u2E97\u396E\u3918\u9FB5\u39CF\u39DF\u3A73\u39D0"+ + "\u9FB6\u9FB7\u3B4E\u3C6E\u3CE0\u2EA7\uE831\u9FB8")+ + "\u2EAA\u4056\u415F\u2EAE\u4337\u2EB3\u2EB6\u2EB7"+ + "\uE83B\u43B1\u43AC\u2EBB\u43DD\u44D6\u4661\u464C"+ + (IS_2000 ? "\uE843\uFFFD\u4723\u4729\u477C\u478D\u2ECA\u4947" : + "\u9FB9\uFFFD\u4723\u4729\u477C\u478D\u2ECA\u4947")+ + "\u497A\u497D\u4982\u4983\u4985\u4986\u499F\u499B"+ + (IS_2000 ? "\u49B7\u49B6\uE854\uE855\u4CA3\u4C9F\u4CA0\u4CA1" : + "\u49B7\u49B6\u9FBA\uE855\u4CA3\u4C9F\u4CA0\u4CA1")+ + "\u4C77\u4CA2\u4D13\u4D14\u4D15\u4D16\u4D17\u4D18"+ + (IS_2000 ? "\u4D19\u4DAE\uE864\uE468\uE469\uE46A\uE46B\uE46C" : + "\u4D19\u4DAE\u9FBB\uE468\uE469\uE46A\uE46B\uE46C")+ + "\uE46D\uE46E\uE46F\uE470\uE471\uE472\uE473\uE474"+ + "\uE475\uE476\uE477\uE478\uE479\uE47A\uE47B\uE47C"+ + "\uE47D\uE47E\uE47F\uE480\uE481\uE482\uE483\uE484"+ + "\uE485\uE486\uE487\uE488\uE489\uE48A\uE48B\uE48C"+ + "\uE48D\uE48E\uE48F\uE490\uE491\uE492\uE493\uE494"+ + "\uE495\uE496\uE497\uE498\uE499\uE49A\uE49B\uE49C"+ + "\uE49D\uE49E\uE49F\uE4A0\uE4A1\uE4A2\uE4A3\uE4A4"+ + "\uE4A5\uE4A6\uE4A7\uE4A8\uE4A9\uE4AA\uE4AB\uE4AC"+ + "\uE4AD\uE4AE\uE4AF\uE4B0\uE4B1\uE4B2\uE4B3\uE4B4"+ + "\uE4B5\uE4B6\uE4B7\uE4B8\uE4B9\uE4BA\uE4BB\uE4BC"+ + "\uE4BD\uE4BE\uE4BF\uE4C0\uE4C1\uE4C2\uE4C3\uE4C4"+ + "\uE4C5"; + + static final short index1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 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, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 0 + }; + + static String index2[] = { + innerIndex0, + innerIndex1, + innerIndex2, + innerIndex3, + innerIndex4, + innerIndex5, + innerIndex6, + innerIndex7 + }; + + + + + + private static final String innerEncoderIndex0= + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007"+ + "\u2008\u2009\u200A\u200B\u200C\u200D\u200E\u200F"+ + "\u2010\u2011\u2012\u2013\u2014\u2015\u2016\u2017"+ + "\u2018\u2019\u201A\u201B\u201C\u201D\u201E\u201F"+ + "\u2020\u2021\u2022\u2023\uA1E8\u2024\u2025\uA1EC"+ + "\uA1A7\u2026\u2027\u2028\u2029\u202A\u202B\u202C"+ + "\uA1E3\uA1C0\u202D\u202E\u202F\u2030\u2031\uA1A4"+ + "\u2032\u2033\u2034\u2035\u2036\u2037\u2038\u2039"+ + "\u203A\u203B\u203C\u203D\u203E\u203F\u2040\u2041"+ + "\u2042\u2043\u2044\u2045\u2046\u2047\u2048\u2049"+ + "\u204A\u204B\u204C\u204D\u204E\u204F\u2050\uA1C1"+ + "\u2051\u2052\u2053\u2054\u2055\u2056\u2057\u2058"+ + "\uA8A4\uA8A2\u2059\u205A\u205B\u205C\u205D\u205E"+ + "\uA8A8\uA8A6\uA8BA\u205F\uA8AC\uA8AA\u2060\u2061"+ + "\u2062\u2063\uA8B0\uA8AE\u2064\u2065\u2066\uA1C2"+ + "\u2067\uA8B4\uA8B2\u2068\uA8B9\u2069\u206A\u206B"+ + "\u206C\uA8A1\u206D\u206E\u206F\u2070\u2071\u2072"+ + "\u2073\u2074\u2075\u2076\u2077\u2078\u2079\u207A"+ + "\u207B\u207C\u207D\uA8A5\u207E\u207F\u2080\u2081"+ + "\u2082\u2083\u2084\uA8A7\u2085\u2086\u2087\u2088"+ + "\u2089\u208A\u208B\u208C\u208D\u208E\u208F\u2090"+ + "\u2091\u2092\u2093\uA8A9\u2094\u2095\u2096\u2097"+ + "\u2098\u2099\u209A\u209B\u209C\u209D\u209E\u209F"+ + "\u20A0\u20A1\u20A2\u20A3\u20A4\u20A5\u20A6\u20A7"+ + "\u20A8\u20A9\u20AA\u20AB\uA8BD\u20AC\u20AD\u20AE"+ + "\uA8BE\u20AF\u20B0\u20B1\u20B2\uA8AD\u20B3\u20B4"+ + "\u20B5\u20B6\u20B7\u20B8\u20B9\u20BA\u20BB\u20BC"+ + "\u20BD\u20BE\u20BF\u20C0\u20C1\u20C2\u20C3\u20C4"+ + "\u20C5\u20C6\u20C7\u20C8\u20C9\u20CA\u20CB\u20CC"+ + "\u20CD\u20CE\u20CF\uA8B1\u20D0\u20D1\u20D2\u20D3"+ + "\u20D4\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB"+ + "\u20DC\u20DD\u20DE\u20DF\u20E0\u20E1\u20E2\u20E3"+ + "\u20E4\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB"+ + "\u20EC\u20ED\u20EE\u20EF\u20F0\u20F1\u20F2\u20F3"+ + "\u20F4\u20F5\u20F6\u20F7\u20F8\u20F9\u20FA\u20FB"+ + "\u20FC\u20FD\u20FE\u20FF\u2100\u2101\u2102\u2103"+ + "\u2104\u2105\u2106\u2107\u2108\u2109\u210A\u210B"+ + "\u210C\u210D\u210E\u210F\u2110\u2111\u2112\u2113"+ + "\u2114\u2115\u2116\u2117\u2118\u2119\u211A\u211B"+ + "\u211C\u211D\u211E\u211F\u2120\u2121\u2122\u2123"+ + "\u2124\u2125\u2126\u2127\u2128\u2129\u212A\u212B"+ + "\u212C\u212D\u212E\u212F\u2130\u2131\uA8A3\u2132"+ + "\uA8AB\u2133\uA8AF\u2134\uA8B3\u2135\uA8B5\u2136"+ + "\uA8B6\u2137\uA8B7\u2138\uA8B8\u2139\u213A\u213B"+ + "\u213C\u213D\u213E\u213F\u2140\u2141\u2142\u2143"+ + "\u2144\u2145\u2146\u2147\u2148\u2149\u214A\u214B"+ + "\u214C\u214D\u214E\u214F\u2150\u2151\u2152\u2153"+ + "\u2154\uA8BF\u2155\u2156\u2157\u2158\u2159\u215A"+ + "\u215B\u215C\u215D\u215E\u215F\u2160\u2161\u2162"+ + "\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216A"+ + "\u216B\u216C\u216D\u216E\u216F\u2170\u2171\u2172"+ + "\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217A"+ + "\u217B\u217C\u217D\u217E\u217F\u2180\u2181\u2182"+ + "\u2183\u2184\u2185\u2186\u2187\u2188\u2189\u218A"+ + "\u218B\u218C\u218D\u218E\u218F\u2190\u2191\u2192"+ + "\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u219A"+ + "\u219B\u219C\u219D\u219E\u219F\u21A0\u21A1\u21A2"+ + "\u21A3\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9\u21AA"+ + "\u21AB\uA8BB\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1"+ + "\u21B2\u21B3\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9"+ + "\u21BA\uA8C0\u21BB\u21BC\u21BD\u21BE\u21BF\u21C0"+ + "\u21C1\u21C2\u21C3\u21C4\u21C5\u21C6\u21C7\u21C8"+ + "\u21C9\u21CA\u21CB\u21CC\u21CD\u21CE\u21CF\u21D0"+ + "\u21D1\u21D2\u21D3\u21D4\u21D5\u21D6\u21D7\u21D8"+ + "\u21D9\u21DA\u21DB\u21DC\u21DD\u21DE\u21DF\u21E0"+ + "\u21E1\u21E2\u21E3\u21E4\u21E5\u21E6\u21E7\u21E8"+ + "\u21E9\u21EA\u21EB\u21EC\u21ED\u21EE\u21EF\u21F0"+ + "\u21F1\u21F2\u21F3\u21F4\u21F5\u21F6\u21F7\u21F8"+ + "\u21F9\u21FA\u21FB\u21FC\u21FD\u21FE\u21FF\u2200"+ + "\u2201\u2202\u2203\u2204\u2205\u2206\u2207\u2208"+ + "\u2209\u220A\u220B\u220C\u220D\u220E\u220F\u2210"+ + "\u2211\u2212\u2213\u2214\u2215\u2216\u2217\u2218"+ + "\u2219\u221A\u221B\u221C\u221D\u221E\u221F\uA1A6"+ + "\u2220\uA1A5\uA840\uA841\u2221\u2222\u2223\u2224"+ + "\u2225\u2226\u2227\u2228\u2229\u222A\u222B\u222C"+ + "\u222D\uA842\u222E\u222F\u2230\u2231\u2232\u2233"+ + "\u2234\u2235\u2236\u2237\u2238\u2239\u223A\u223B"+ + "\u223C\u223D\u223E\u223F\u2240\u2241\u2242\u2243"+ + "\u2244\u2245\u2246\u2247\u2248\u2249\u224A\u224B"+ + "\u224C\u224D\u224E\u224F\u2250\u2251\u2252\u2253"+ + "\u2254\u2255\u2256\u2257\u2258\u2259\u225A\u225B"+ + "\u225C\u225D\u225E\u225F\u2260\u2261\u2262\u2263"+ + "\u2264\u2265\u2266\u2267\u2268\u2269\u226A\u226B"+ + "\u226C\u226D\u226E\u226F\u2270\u2271\u2272\u2273"+ + "\u2274\u2275\u2276\u2277\u2278\u2279\u227A\u227B"+ + "\u227C\u227D\u227E\u227F\u2280\u2281\u2282\u2283"+ + "\u2284\u2285\u2286\u2287\u2288\u2289\u228A\u228B"+ + "\u228C\u228D\u228E\u228F\u2290\u2291\u2292\u2293"+ + "\u2294\u2295\u2296\u2297\u2298\u2299\u229A\u229B"+ + "\u229C\u229D\u229E\u229F\u22A0\u22A1\u22A2\u22A3"+ + "\u22A4\u22A5\u22A6\u22A7\u22A8\u22A9\u22AA\u22AB"+ + "\u22AC\u22AD\u22AE\u22AF\u22B0\u22B1\u22B2\u22B3"+ + "\u22B4\u22B5\u22B6\u22B7\u22B8\u22B9\u22BA\u22BB"+ + "\u22BC\u22BD\u22BE\u22BF\u22C0\u22C1\u22C2\u22C3"+ + "\u22C4\u22C5\u22C6\u22C7\u22C8\u22C9\u22CA\u22CB"+ + "\u22CC\u22CD\u22CE\u22CF\u22D0\u22D1\u22D2\u22D3"+ + "\u22D4\u22D5\u22D6\u22D7\u22D8\u22D9\u22DA\u22DB"+ + "\u22DC\u22DD\u22DE\u22DF\u22E0\u22E1\u22E2\u22E3"+ + "\u22E4\uA6A1\uA6A2\uA6A3\uA6A4\uA6A5\uA6A6\uA6A7"+ + "\uA6A8\uA6A9\uA6AA\uA6AB\uA6AC\uA6AD\uA6AE\uA6AF"+ + "\uA6B0\uA6B1\u22E5\uA6B2\uA6B3\uA6B4\uA6B5\uA6B6"+ + "\uA6B7\uA6B8\u22E6\u22E7\u22E8\u22E9\u22EA\u22EB"+ + "\u22EC\uA6C1\uA6C2\uA6C3\uA6C4\uA6C5\uA6C6\uA6C7"+ + "\uA6C8\uA6C9\uA6CA\uA6CB\uA6CC\uA6CD\uA6CE\uA6CF"+ + "\uA6D0\uA6D1\u22ED\uA6D2\uA6D3\uA6D4\uA6D5\uA6D6"+ + "\uA6D7\uA6D8\u22EE\u22EF\u22F0\u22F1\u22F2\u22F3"+ + "\u22F4\u22F5\u22F6\u22F7\u22F8\u22F9\u22FA\u22FB"+ + "\u22FC\u22FD\u22FE\u22FF\u2300\u2301\u2302\u2303"+ + "\u2304\u2305\u2306\u2307\u2308\u2309\u230A\u230B"+ + "\u230C\u230D\u230E\u230F\u2310\u2311\u2312\u2313"+ + "\u2314\u2315\u2316\u2317\u2318\u2319\u231A\u231B"+ + "\u231C\u231D\u231E\u231F\u2320\u2321\u2322\u2323"+ + "\u2324\uA7A7\u2325\u2326\u2327\u2328\u2329\u232A"+ + "\u232B\u232C\u232D\u232E\u232F\u2330\u2331\u2332"+ + "\uA7A1\uA7A2\uA7A3\uA7A4\uA7A5\uA7A6\uA7A8\uA7A9"+ + "\uA7AA\uA7AB\uA7AC\uA7AD\uA7AE\uA7AF\uA7B0\uA7B1"+ + "\uA7B2\uA7B3\uA7B4\uA7B5\uA7B6\uA7B7\uA7B8\uA7B9"+ + "\uA7BA\uA7BB\uA7BC\uA7BD\uA7BE\uA7BF\uA7C0\uA7C1"+ + "\uA7D1\uA7D2\uA7D3\uA7D4\uA7D5\uA7D6\uA7D8\uA7D9"+ + "\uA7DA\uA7DB\uA7DC\uA7DD\uA7DE\uA7DF\uA7E0\uA7E1"+ + "\uA7E2\uA7E3\uA7E4\uA7E5\uA7E6\uA7E7\uA7E8\uA7E9"+ + "\uA7EA\uA7EB\uA7EC\uA7ED\uA7EE\uA7EF\uA7F0\uA7F1"+ + "\u2333\uA7D7\u2334\u2335\u2336\u2337\u2338\u2339"+ + "\u233A\u233B\u233C\u233D\u233E\u233F\u2340\u2341"+ + "\u2342\u2343\u2344\u2345\u2346\u2347\u2348\u2349"+ + "\u234A\u234B\u234C\u234D\u234E\u234F\u2350\u2351"+ + "\u2352\u2353\u2354\u2355\u2356\u2357\u2358\u2359"+ + "\u235A\u235B\u235C\u235D\u235E\u235F\u2360\u2361"+ + "\u2362\u2363\u2364\u2365\u2366\u2367\u2368\u2369"+ + "\u236A\u236B\u236C\u236D\u236E\u236F\u2370\u2371"+ + "\u2372\u2373\u2374\u2375\u2376\u2377\u2378\u2379"+ + "\u237A\u237B\u237C\u237D\u237E\u237F\u2380\u2381"+ + "\u2382\u2383\u2384\u2385\u2386\u2387\u2388\u2389"+ + "\u238A\u238B\u238C\u238D\u238E\u238F\u2390\u2391"+ + "\u2392\u2393\u2394\u2395\u2396\u2397\u2398\u2399"+ + "\u239A\u239B\u239C\u239D\u239E\u239F\u23A0\u23A1"+ + "\u23A2\u23A3\u23A4\u23A5\u23A6\u23A7\u23A8\u23A9"+ + "\u23AA\u23AB\u23AC\u23AD\u23AE\u23AF\u23B0\u23B1"+ + "\u23B2\u23B3\u23B4\u23B5\u23B6\u23B7\u23B8\u23B9"+ + "\u23BA\u23BB\u23BC\u23BD\u23BE\u23BF\u23C0\u23C1"+ + "\u23C2\u23C3\u23C4\u23C5\u23C6\u23C7\u23C8\u23C9"+ + "\u23CA\u23CB\u23CC\u23CD\u23CE\u23CF\u23D0\u23D1"+ + "\u23D2\u23D3\u23D4\u23D5\u23D6\u23D7\u23D8\u23D9"+ + "\u23DA\u23DB\u23DC\u23DD\u23DE\u23DF\u23E0\u23E1"+ + "\u23E2\u23E3\u23E4\u23E5\u23E6\u23E7\u23E8\u23E9"+ + "\u23EA\u23EB\u23EC\u23ED\u23EE\u23EF\u23F0\u23F1"+ + "\u23F2\u23F3\u23F4\u23F5\u23F6\u23F7\u23F8\u23F9"+ + "\u23FA\u23FB\u23FC\u23FD\u23FE\u23FF\u2400\u2401"+ + "\u2402\u2403\u2404\u2405\u2406\u2407\u2408\u2409"+ + "\u240A\u240B\u240C\u240D\u240E\u240F\u2410\u2411"+ + "\u2412\u2413\u2414\u2415\u2416\u2417\u2418\u2419"+ + "\u241A\u241B\u241C\u241D\u241E\u241F\u2420\u2421"+ + "\u2422\u2423\u2424\u2425\u2426\u2427\u2428\u2429"+ + "\u242A\u242B\u242C\u242D\u242E\u242F\u2430\u2431"+ + "\u2432\u2433\u2434\u2435\u2436\u2437\u2438\u2439"+ + "\u243A\u243B\u243C\u243D\u243E\u243F\u2440\u2441"+ + "\u2442\u2443\u2444\u2445\u2446\u2447\u2448\u2449"+ + "\u244A\u244B\u244C\u244D\u244E\u244F\u2450\u2451"+ + "\u2452\u2453\u2454\u2455\u2456\u2457\u2458\u2459"+ + "\u245A\u245B\u245C\u245D\u245E\u245F\u2460\u2461"+ + "\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2469"+ + "\u246A\u246B\u246C\u246D\u246E\u246F\u2470\u2471"+ + "\u2472\u2473\u2474\u2475\u2476\u2477\u2478\u2479"+ + "\u247A\u247B\u247C\u247D\u247E\u247F\u2480\u2481"+ + "\u2482\u2483\u2484\u2485\u2486\u2487\u2488\u2489"+ + "\u248A\u248B\u248C\u248D\u248E\u248F\u2490\u2491"+ + "\u2492\u2493\u2494\u2495\u2496\u2497\u2498\u2499"+ + "\u249A\u249B\u249C\u249D\u249E\u249F\u24A0\u24A1"+ + "\u24A2\u24A3\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9"+ + "\u24AA\u24AB\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1"+ + "\u24B2\u24B3\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9"+ + "\u24BA\u24BB\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1"+ + "\u24C2\u24C3\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9"+ + "\u24CA\u24CB\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1"+ + "\u24D2\u24D3\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9"+ + "\u24DA\u24DB\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1"+ + "\u24E2\u24E3\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9"+ + "\u24EA\u24EB\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1"+ + "\u24F2\u24F3\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9"+ + "\u24FA\u24FB\u24FC\u24FD\u24FE\u24FF\u2500\u2501"+ + "\u2502\u2503\u2504\u2505\u2506\u2507\u2508\u2509"+ + "\u250A\u250B\u250C\u250D\u250E\u250F\u2510\u2511"+ + "\u2512\u2513\u2514\u2515\u2516\u2517\u2518\u2519"+ + "\u251A\u251B\u251C\u251D\u251E\u251F\u2520\u2521"+ + "\u2522\u2523\u2524\u2525\u2526\u2527\u2528\u2529"+ + "\u252A\u252B\u252C\u252D\u252E\u252F\u2530\u2531"+ + "\u2532\u2533\u2534\u2535\u2536\u2537\u2538\u2539"+ + "\u253A\u253B\u253C\u253D\u253E\u253F\u2540\u2541"+ + "\u2542\u2543\u2544\u2545\u2546\u2547\u2548\u2549"+ + "\u254A\u254B\u254C\u254D\u254E\u254F\u2550\u2551"+ + "\u2552\u2553\u2554\u2555\u2556\u2557\u2558\u2559"+ + "\u255A\u255B\u255C\u255D\u255E\u255F\u2560\u2561"+ + "\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569"+ + "\u256A\u256B\u256C\u256D\u256E\u256F\u2570\u2571"+ + "\u2572\u2573\u2574\u2575\u2576\u2577\u2578\u2579"+ + "\u257A\u257B\u257C\u257D\u257E\u257F\u2580\u2581"+ + "\u2582\u2583\u2584\u2585\u2586\u2587\u2588\u2589"+ + "\u258A\u258B\u258C\u258D\u258E\u258F\u2590\u2591"+ + "\u2592\u2593\u2594\u2595\u2596\u2597\u2598\u2599"+ + "\u259A\u259B\u259C\u259D\u259E\u259F\u25A0\u25A1"+ + "\u25A2\u25A3\u25A4\u25A5\u25A6\u25A7\u25A8\u25A9"+ + "\u25AA\u25AB\u25AC\u25AD\u25AE\u25AF\u25B0\u25B1"+ + "\u25B2\u25B3\u25B4\u25B5\u25B6\u25B7\u25B8\u25B9"+ + "\u25BA\u25BB\u25BC\u25BD\u25BE\u25BF\u25C0\u25C1"+ + "\u25C2\u25C3\u25C4\u25C5\u25C6\u25C7\u25C8\u25C9"+ + "\u25CA\u25CB\u25CC\u25CD\u25CE\u25CF\u25D0\u25D1"+ + "\u25D2\u25D3\u25D4\u25D5\u25D6\u25D7\u25D8\u25D9"+ + "\u25DA\u25DB\u25DC\u25DD\u25DE\u25DF\u25E0\u25E1"+ + "\u25E2\u25E3\u25E4\u25E5\u25E6\u25E7\u25E8\u25E9"+ + "\u25EA\u25EB\u25EC\u25ED\u25EE\u25EF\u25F0\u25F1"+ + "\u25F2\u25F3\u25F4\u25F5\u25F6\u25F7\u25F8\u25F9"+ + "\u25FA\u25FB\u25FC\u25FD\u25FE\u25FF\u2600\u2601"+ + "\u2602\u2603\u2604\u2605\u2606\u2607\u2608\u2609"+ + "\u260A\u260B\u260C\u260D\u260E\u260F\u2610\u2611"+ + "\u2612\u2613\u2614\u2615\u2616\u2617\u2618\u2619"+ + "\u261A\u261B\u261C\u261D\u261E\u261F\u2620\u2621"+ + "\u2622\u2623\u2624\u2625\u2626\u2627\u2628\u2629"+ + "\u262A\u262B\u262C\u262D\u262E\u262F\u2630\u2631"+ + "\u2632\u2633\u2634\u2635\u2636\u2637\u2638\u2639"+ + "\u263A\u263B\u263C\u263D\u263E\u263F\u2640\u2641"+ + "\u2642\u2643\u2644\u2645\u2646\u2647\u2648\u2649"+ + "\u264A\u264B\u264C\u264D\u264E\u264F\u2650\u2651"+ + "\u2652\u2653\u2654\u2655\u2656\u2657\u2658\u2659"+ + "\u265A\u265B\u265C\u265D\u265E\u265F\u2660\u2661"+ + "\u2662\u2663\u2664\u2665\u2666\u2667\u2668\u2669"+ + "\u266A\u266B\u266C\u266D\u266E\u266F\u2670\u2671"+ + "\u2672\u2673\u2674\u2675\u2676\u2677\u2678\u2679"+ + "\u267A\u267B\u267C\u267D\u267E\u267F\u2680\u2681"+ + "\u2682\u2683\u2684\u2685\u2686\u2687\u2688\u2689"+ + "\u268A\u268B\u268C\u268D\u268E\u268F\u2690\u2691"+ + "\u2692\u2693\u2694\u2695\u2696\u2697\u2698\u2699"+ + "\u269A\u269B\u269C\u269D\u269E\u269F\u26A0\u26A1"+ + "\u26A2\u26A3\u26A4\u26A5\u26A6\u26A7\u26A8\u26A9"+ + "\u26AA\u26AB\u26AC\u26AD\u26AE\u26AF\u26B0\u26B1"+ + "\u26B2\u26B3\u26B4\u26B5\u26B6\u26B7\u26B8\u26B9"+ + "\u26BA\u26BB\u26BC\u26BD\u26BE\u26BF\u26C0\u26C1"+ + "\u26C2\u26C3\u26C4\u26C5\u26C6\u26C7\u26C8\u26C9"+ + "\u26CA\u26CB\u26CC\u26CD\u26CE\u26CF\u26D0\u26D1"+ + "\u26D2\u26D3\u26D4\u26D5\u26D6\u26D7\u26D8\u26D9"+ + "\u26DA\u26DB\u26DC\u26DD\u26DE\u26DF\u26E0\u26E1"+ + "\u26E2\u26E3\u26E4\u26E5\u26E6\u26E7\u26E8\u26E9"+ + "\u26EA\u26EB\u26EC\u26ED\u26EE\u26EF\u26F0\u26F1"+ + "\u26F2\u26F3\u26F4\u26F5\u26F6\u26F7\u26F8\u26F9"+ + "\u26FA\u26FB\u26FC\u26FD\u26FE\u26FF\u2700\u2701"+ + "\u2702\u2703\u2704\u2705\u2706\u2707\u2708\u2709"+ + "\u270A\u270B\u270C\u270D\u270E\u270F\u2710\u2711"+ + "\u2712\u2713\u2714\u2715\u2716\u2717\u2718\u2719"+ + "\u271A\u271B\u271C\u271D\u271E\u271F\u2720\u2721"+ + "\u2722\u2723\u2724\u2725\u2726\u2727\u2728\u2729"+ + "\u272A\u272B\u272C\u272D\u272E\u272F\u2730\u2731"+ + "\u2732\u2733\u2734\u2735\u2736\u2737\u2738\u2739"+ + "\u273A\u273B\u273C\u273D\u273E\u273F\u2740\u2741"+ + "\u2742\u2743\u2744\u2745\u2746\u2747\u2748\u2749"+ + "\u274A\u274B\u274C\u274D\u274E\u274F\u2750\u2751"+ + "\u2752\u2753\u2754\u2755\u2756\u2757\u2758\u2759"+ + "\u275A\u275B\u275C\u275D\u275E\u275F\u2760\u2761"+ + "\u2762\u2763\u2764\u2765\u2766\u2767\u2768\u2769"+ + "\u276A\u276B\u276C\u276D\u276E\u276F\u2770\u2771"+ + "\u2772\u2773\u2774\u2775\u2776\u2777\u2778\u2779"+ + "\u277A\u277B\u277C\u277D\u277E\u277F\u2780\u2781"+ + "\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u2789"+ + "\u278A\u278B\u278C\u278D\u278E\u278F\u2790\u2791"+ + "\u2792\u2793\u2794\u2795\u2796\u2797\u2798\u2799"+ + "\u279A\u279B\u279C\u279D\u279E\u279F\u27A0\u27A1"+ + "\u27A2\u27A3\u27A4\u27A5\u27A6\u27A7\u27A8\u27A9"+ + "\u27AA\u27AB\u27AC\u27AD\u27AE\u27AF\u27B0\u27B1"+ + "\u27B2\u27B3\u27B4\u27B5\u27B6\u27B7\u27B8\u27B9"+ + "\u27BA\u27BB\u27BC\u27BD\u27BE\u27BF\u27C0\u27C1"+ + "\u27C2\u27C3\u27C4\u27C5\u27C6\u27C7\u27C8\u27C9"+ + "\u27CA\u27CB\u27CC\u27CD\u27CE\u27CF\u27D0\u27D1"+ + "\u27D2\u27D3\u27D4\u27D5\u27D6\u27D7\u27D8\u27D9"+ + "\u27DA\u27DB\u27DC\u27DD\u27DE\u27DF\u27E0\u27E1"+ + "\u27E2\u27E3\u27E4\u27E5\u27E6\u27E7\u27E8\u27E9"+ + "\u27EA\u27EB\u27EC\u27ED\u27EE\u27EF\u27F0\u27F1"+ + "\u27F2\u27F3\u27F4\u27F5\u27F6\u27F7\u27F8\u27F9"+ + "\u27FA\u27FB\u27FC\u27FD\u27FE\u27FF\u2800\u2801"+ + "\u2802\u2803\u2804\u2805\u2806\u2807\u2808\u2809"+ + "\u280A\u280B\u280C\u280D\u280E\u280F\u2810\u2811"+ + "\u2812\u2813\u2814\u2815\u2816\u2817\u2818\u2819"+ + "\u281A\u281B\u281C\u281D\u281E\u281F\u2820\u2821"+ + "\u2822\u2823\u2824\u2825\u2826\u2827\u2828\u2829"+ + "\u282A\u282B\u282C\u282D\u282E\u282F\u2830\u2831"+ + "\u2832\u2833\u2834\u2835\u2836\u2837\u2838\u2839"+ + "\u283A\u283B\u283C\u283D\u283E\u283F\u2840\u2841"+ + "\u2842\u2843\u2844\u2845\u2846\u2847\u2848\u2849"+ + "\u284A\u284B\u284C\u284D\u284E\u284F\u2850\u2851"+ + "\u2852\u2853\u2854\u2855\u2856\u2857\u2858\u2859"+ + "\u285A\u285B\u285C\u285D\u285E\u285F\u2860\u2861"+ + "\u2862\u2863\u2864\u2865\u2866\u2867\u2868\u2869"+ + "\u286A\u286B\u286C\u286D\u286E\u286F\u2870\u2871"+ + "\u2872\u2873\u2874\u2875\u2876\u2877\u2878\u2879"+ + "\u287A\u287B\u287C\u287D\u287E\u287F\u2880\u2881"+ + "\u2882\u2883\u2884\u2885\u2886\u2887\u2888\u2889"+ + "\u288A\u288B\u288C\u288D\u288E\u288F\u2890\u2891"+ + "\u2892\u2893\u2894\u2895\u2896\u2897\u2898\u2899"+ + "\u289A\u289B\u289C\u289D\u289E\u289F\u28A0\u28A1"+ + "\u28A2\u28A3\u28A4\u28A5\u28A6\u28A7\u28A8\u28A9"+ + "\u28AA\u28AB\u28AC\u28AD\u28AE\u28AF\u28B0\u28B1"+ + "\u28B2\u28B3\u28B4\u28B5\u28B6\u28B7\u28B8\u28B9"+ + "\u28BA\u28BB\u28BC\u28BD\u28BE\u28BF\u28C0\u28C1"+ + "\u28C2\u28C3\u28C4\u28C5\u28C6\u28C7\u28C8\u28C9"+ + "\u28CA\u28CB\u28CC\u28CD\u28CE\u28CF\u28D0\u28D1"+ + "\u28D2\u28D3\u28D4\u28D5\u28D6\u28D7\u28D8\u28D9"+ + "\u28DA\u28DB\u28DC\u28DD\u28DE\u28DF\u28E0\u28E1"+ + "\u28E2\u28E3\u28E4\u28E5\u28E6\u28E7\u28E8\u28E9"+ + "\u28EA\u28EB\u28EC\u28ED\u28EE\u28EF\u28F0\u28F1"+ + "\u28F2\u28F3\u28F4\u28F5\u28F6\u28F7\u28F8\u28F9"+ + "\u28FA\u28FB\u28FC\u28FD\u28FE\u28FF\u2900\u2901"+ + "\u2902\u2903\u2904\u2905\u2906\u2907\u2908\u2909"+ + "\u290A\u290B\u290C\u290D\u290E\u290F\u2910\u2911"+ + "\u2912\u2913\u2914\u2915\u2916\u2917\u2918\u2919"+ + "\u291A\u291B\u291C\u291D\u291E\u291F\u2920\u2921"+ + "\u2922\u2923\u2924\u2925\u2926\u2927\u2928\u2929"+ + "\u292A\u292B\u292C\u292D\u292E\u292F\u2930\u2931"+ + "\u2932\u2933\u2934\u2935\u2936\u2937\u2938\u2939"+ + "\u293A\u293B\u293C\u293D\u293E\u293F\u2940\u2941"+ + "\u2942\u2943\u2944\u2945\u2946\u2947\u2948\u2949"+ + "\u294A\u294B\u294C\u294D\u294E\u294F\u2950\u2951"+ + "\u2952\u2953\u2954\u2955\u2956\u2957\u2958\u2959"+ + "\u295A\u295B\u295C\u295D\u295E\u295F\u2960\u2961"+ + "\u2962\u2963\u2964\u2965\u2966\u2967\u2968\u2969"+ + "\u296A\u296B\u296C\u296D\u296E\u296F\u2970\u2971"+ + "\u2972\u2973\u2974\u2975\u2976\u2977\u2978\u2979"+ + "\u297A\u297B\u297C\u297D\u297E\u297F\u2980\u2981"+ + "\u2982\u2983\u2984\u2985\u2986\u2987\u2988\u2989"+ + "\u298A\u298B\u298C\u298D\u298E\u298F\u2990\u2991"+ + "\u2992\u2993\u2994\u2995\u2996\u2997\u2998\u2999"+ + "\u299A\u299B\u299C\u299D\u299E\u299F\u29A0\u29A1"+ + "\u29A2\u29A3\u29A4\u29A5\u29A6\u29A7\u29A8\u29A9"+ + "\u29AA\u29AB\u29AC\u29AD\u29AE\u29AF\u29B0\u29B1"+ + "\u29B2\u29B3\u29B4\u29B5\u29B6\u29B7\u29B8\u29B9"+ + "\u29BA\u29BB\u29BC\u29BD\u29BE\u29BF\u29C0\u29C1"+ + "\u29C2\u29C3\u29C4\u29C5\u29C6\u29C7\u29C8\u29C9"+ + "\u29CA\u29CB\u29CC\u29CD\u29CE\u29CF\u29D0\u29D1"+ + "\u29D2\u29D3\u29D4\u29D5\u29D6\u29D7\u29D8\u29D9"+ + "\u29DA\u29DB\u29DC\u29DD\u29DE\u29DF\u29E0\u29E1"+ + "\u29E2\u29E3\u29E4\u29E5\u29E6\u29E7\u29E8\u29E9"+ + "\u29EA\u29EB\u29EC\u29ED\u29EE\u29EF\u29F0\u29F1"+ + "\u29F2\u29F3\u29F4\u29F5\u29F6\u29F7\u29F8\u29F9"+ + "\u29FA\u29FB\u29FC\u29FD\u29FE\u29FF\u2A00\u2A01"+ + "\u2A02\u2A03\u2A04\u2A05\u2A06\u2A07\u2A08\u2A09"+ + "\u2A0A\u2A0B\u2A0C\u2A0D\u2A0E\u2A0F\u2A10\u2A11"+ + "\u2A12\u2A13\u2A14\u2A15\u2A16\u2A17\u2A18\u2A19"+ + "\u2A1A\u2A1B\u2A1C\u2A1D\u2A1E\u2A1F\u2A20\u2A21"+ + "\u2A22\u2A23\u2A24\u2A25\u2A26\u2A27\u2A28\u2A29"+ + "\u2A2A\u2A2B\u2A2C\u2A2D\u2A2E\u2A2F\u2A30\u2A31"+ + "\u2A32\u2A33\u2A34\u2A35\u2A36\u2A37\u2A38\u2A39"+ + "\u2A3A\u2A3B\u2A3C\u2A3D\u2A3E\u2A3F\u2A40\u2A41"+ + "\u2A42\u2A43\u2A44\u2A45\u2A46\u2A47\u2A48\u2A49"+ + "\u2A4A\u2A4B\u2A4C\u2A4D\u2A4E\u2A4F\u2A50\u2A51"+ + "\u2A52\u2A53\u2A54\u2A55\u2A56\u2A57\u2A58\u2A59"+ + "\u2A5A\u2A5B\u2A5C\u2A5D\u2A5E\u2A5F\u2A60\u2A61"+ + "\u2A62\u2A63\u2A64\u2A65\u2A66\u2A67\u2A68\u2A69"+ + "\u2A6A\u2A6B\u2A6C\u2A6D\u2A6E\u2A6F\u2A70\u2A71"+ + "\u2A72\u2A73\u2A74\u2A75\u2A76\u2A77\u2A78\u2A79"+ + "\u2A7A\u2A7B\u2A7C\u2A7D\u2A7E\u2A7F\u2A80\u2A81"+ + "\u2A82\u2A83\u2A84\u2A85\u2A86\u2A87\u2A88\u2A89"+ + "\u2A8A\u2A8B\u2A8C\u2A8D\u2A8E\u2A8F\u2A90\u2A91"+ + "\u2A92\u2A93\u2A94\u2A95\u2A96\u2A97\u2A98\u2A99"+ + "\u2A9A\u2A9B\u2A9C\u2A9D\u2A9E\u2A9F\u2AA0\u2AA1"+ + "\u2AA2\u2AA3\u2AA4\u2AA5\u2AA6\u2AA7\u2AA8\u2AA9"+ + "\u2AAA\u2AAB\u2AAC\u2AAD\u2AAE\u2AAF\u2AB0\u2AB1"+ + "\u2AB2\u2AB3\u2AB4\u2AB5\u2AB6\u2AB7\u2AB8\u2AB9"+ + "\u2ABA\u2ABB\u2ABC\u2ABD\u2ABE\u2ABF\u2AC0\u2AC1"+ + "\u2AC2\u2AC3\u2AC4\u2AC5\u2AC6\u2AC7\u2AC8\u2AC9"+ + "\u2ACA\u2ACB\u2ACC\u2ACD\u2ACE\u2ACF\u2AD0\u2AD1"+ + "\u2AD2\u2AD3\u2AD4\u2AD5\u2AD6\u2AD7\u2AD8\u2AD9"+ + "\u2ADA\u2ADB\u2ADC\u2ADD\u2ADE\u2ADF\u2AE0\u2AE1"+ + "\u2AE2\u2AE3\u2AE4\u2AE5\u2AE6\u2AE7\u2AE8\u2AE9"+ + "\u2AEA\u2AEB\u2AEC\u2AED\u2AEE\u2AEF\u2AF0\u2AF1"+ + "\u2AF2\u2AF3\u2AF4\u2AF5\u2AF6\u2AF7\u2AF8\u2AF9"+ + "\u2AFA\u2AFB\u2AFC\u2AFD\u2AFE\u2AFF\u2B00\u2B01"+ + "\u2B02\u2B03\u2B04\u2B05\u2B06\u2B07\u2B08\u2B09"+ + "\u2B0A\u2B0B\u2B0C\u2B0D\u2B0E\u2B0F\u2B10\u2B11"+ + "\u2B12\u2B13\u2B14\u2B15\u2B16\u2B17\u2B18\u2B19"+ + "\u2B1A\u2B1B\u2B1C\u2B1D\u2B1E\u2B1F\u2B20\u2B21"+ + "\u2B22\u2B23\u2B24\u2B25\u2B26\u2B27\u2B28\u2B29"+ + "\u2B2A\u2B2B\u2B2C\u2B2D\u2B2E\u2B2F\u2B30\u2B31"+ + "\u2B32\u2B33\u2B34\u2B35\u2B36\u2B37\u2B38\u2B39"+ + "\u2B3A\u2B3B\u2B3C\u2B3D\u2B3E\u2B3F\u2B40\u2B41"+ + "\u2B42\u2B43\u2B44\u2B45\u2B46\u2B47\u2B48\u2B49"+ + "\u2B4A\u2B4B\u2B4C\u2B4D\u2B4E\u2B4F\u2B50\u2B51"+ + "\u2B52\u2B53\u2B54\u2B55\u2B56\u2B57\u2B58\u2B59"+ + "\u2B5A\u2B5B\u2B5C\u2B5D\u2B5E\u2B5F\u2B60\u2B61"+ + "\u2B62\u2B63\u2B64\u2B65\u2B66\u2B67\u2B68\u2B69"+ + "\u2B6A\u2B6B\u2B6C\u2B6D\u2B6E\u2B6F\u2B70\u2B71"+ + "\u2B72\u2B73\u2B74\u2B75\u2B76\u2B77\u2B78\u2B79"+ + "\u2B7A\u2B7B\u2B7C\u2B7D\u2B7E\u2B7F\u2B80\u2B81"+ + "\u2B82\u2B83\u2B84\u2B85\u2B86\u2B87\u2B88\u2B89"+ + "\u2B8A\u2B8B\u2B8C\u2B8D\u2B8E\u2B8F\u2B90\u2B91"+ + "\u2B92\u2B93\u2B94\u2B95\u2B96\u2B97\u2B98\u2B99"+ + "\u2B9A\u2B9B\u2B9C\u2B9D\u2B9E\u2B9F\u2BA0\u2BA1"+ + "\u2BA2\u2BA3\u2BA4\u2BA5\u2BA6\u2BA7\u2BA8\u2BA9"+ + "\u2BAA\u2BAB\u2BAC\u2BAD\u2BAE\u2BAF\u2BB0\u2BB1"+ + "\u2BB2\u2BB3\u2BB4\u2BB5\u2BB6\u2BB7\u2BB8\u2BB9"+ + "\u2BBA\u2BBB\u2BBC\u2BBD\u2BBE\u2BBF\u2BC0\u2BC1"+ + "\u2BC2\u2BC3\u2BC4\u2BC5\u2BC6\u2BC7\u2BC8\u2BC9"+ + "\u2BCA\u2BCB\u2BCC\u2BCD\u2BCE\u2BCF\u2BD0\u2BD1"+ + "\u2BD2\u2BD3\u2BD4\u2BD5\u2BD6\u2BD7\u2BD8\u2BD9"+ + "\u2BDA\u2BDB\u2BDC\u2BDD\u2BDE\u2BDF\u2BE0\u2BE1"+ + "\u2BE2\u2BE3\u2BE4\u2BE5\u2BE6\u2BE7\u2BE8\u2BE9"+ + "\u2BEA\u2BEB\u2BEC\u2BED\u2BEE\u2BEF\u2BF0\u2BF1"+ + "\u2BF2\u2BF3\u2BF4\u2BF5\u2BF6\u2BF7\u2BF8\u2BF9"+ + "\u2BFA\u2BFB\u2BFC\u2BFD\u2BFE\u2BFF\u2C00\u2C01"+ + "\u2C02\u2C03\u2C04\u2C05\u2C06\u2C07\u2C08\u2C09"+ + "\u2C0A\u2C0B\u2C0C\u2C0D\u2C0E\u2C0F\u2C10\u2C11"+ + "\u2C12\u2C13\u2C14\u2C15\u2C16\u2C17\u2C18\u2C19"+ + "\u2C1A\u2C1B\u2C1C\u2C1D\u2C1E\u2C1F\u2C20\u2C21"+ + "\u2C22\u2C23\u2C24\u2C25\u2C26\u2C27\u2C28\u2C29"+ + "\u2C2A\u2C2B\u2C2C\u2C2D\u2C2E\u2C2F\u2C30\u2C31"+ + "\u2C32\u2C33\u2C34\u2C35\u2C36\u2C37\u2C38\u2C39"+ + "\u2C3A\u2C3B\u2C3C\u2C3D\u2C3E\u2C3F\u2C40\u2C41"+ + "\u2C42\u2C43\u2C44\u2C45\u2C46\u2C47\u2C48\u2C49"+ + "\u2C4A\u2C4B\u2C4C\u2C4D\u2C4E\u2C4F\u2C50\u2C51"+ + "\u2C52\u2C53\u2C54\u2C55\u2C56\u2C57\u2C58\u2C59"+ + "\u2C5A\u2C5B\u2C5C\u2C5D\u2C5E\u2C5F\u2C60\u2C61"+ + "\u2C62\u2C63\u2C64\u2C65\u2C66\u2C67\u2C68\u2C69"+ + "\u2C6A\u2C6B\u2C6C\u2C6D\u2C6E\u2C6F\u2C70\u2C71"+ + "\u2C72\u2C73\u2C74\u2C75\u2C76\u2C77\u2C78\u2C79"+ + "\u2C7A\u2C7B\u2C7C\u2C7D\u2C7E\u2C7F\u2C80\u2C81"+ + "\u2C82\u2C83\u2C84\u2C85\u2C86\u2C87\u2C88\u2C89"+ + "\u2C8A\u2C8B\u2C8C\u2C8D\u2C8E\u2C8F\u2C90\u2C91"+ + "\u2C92\u2C93\u2C94\u2C95\u2C96\u2C97\u2C98\u2C99"+ + "\u2C9A\u2C9B\u2C9C\u2C9D\u2C9E\u2C9F\u2CA0\u2CA1"+ + "\u2CA2\u2CA3\u2CA4\u2CA5\u2CA6\u2CA7\u2CA8\u2CA9"+ + "\u2CAA\u2CAB\u2CAC\u2CAD\u2CAE\u2CAF\u2CB0\u2CB1"+ + "\u2CB2\u2CB3\u2CB4\u2CB5\u2CB6\u2CB7\u2CB8\u2CB9"+ + "\u2CBA\u2CBB\u2CBC\u2CBD\u2CBE\u2CBF\u2CC0\u2CC1"+ + "\u2CC2\u2CC3\u2CC4\u2CC5\u2CC6\u2CC7\u2CC8\u2CC9"+ + "\u2CCA\u2CCB\u2CCC\u2CCD\u2CCE\u2CCF\u2CD0\u2CD1"+ + "\u2CD2\u2CD3\u2CD4\u2CD5\u2CD6\u2CD7\u2CD8\u2CD9"+ + "\u2CDA\u2CDB\u2CDC\u2CDD\u2CDE\u2CDF\u2CE0\u2CE1"+ + "\u2CE2\u2CE3\u2CE4\u2CE5\u2CE6\u2CE7\u2CE8\u2CE9"+ + "\u2CEA\u2CEB\u2CEC\u2CED\u2CEE\u2CEF\u2CF0\u2CF1"+ + "\u2CF2\u2CF3\u2CF4\u2CF5\u2CF6\u2CF7\u2CF8\u2CF9"+ + "\u2CFA\u2CFB\u2CFC\u2CFD\u2CFE\u2CFF\u2D00\u2D01"+ + "\u2D02\u2D03\u2D04\u2D05\u2D06\u2D07\u2D08\u2D09"+ + "\u2D0A\u2D0B\u2D0C\u2D0D\u2D0E\u2D0F\u2D10\u2D11"+ + "\u2D12\u2D13\u2D14\u2D15\u2D16\u2D17\u2D18\u2D19"+ + "\u2D1A\u2D1B\u2D1C\u2D1D\u2D1E\u2D1F\u2D20\u2D21"+ + "\u2D22\u2D23\u2D24\u2D25\u2D26\u2D27\u2D28\u2D29"+ + "\u2D2A\u2D2B\u2D2C\u2D2D\u2D2E\u2D2F\u2D30\u2D31"+ + "\u2D32\u2D33\u2D34\u2D35\u2D36\u2D37\u2D38\u2D39"+ + "\u2D3A\u2D3B\u2D3C\u2D3D\u2D3E\u2D3F\u2D40\u2D41"+ + "\u2D42\u2D43\u2D44\u2D45\u2D46\u2D47\u2D48\u2D49"+ + "\u2D4A\u2D4B\u2D4C\u2D4D\u2D4E\u2D4F\u2D50\u2D51"+ + "\u2D52\u2D53\u2D54\u2D55\u2D56\u2D57\u2D58\u2D59"+ + "\u2D5A\u2D5B\u2D5C\u2D5D\u2D5E\u2D5F\u2D60\u2D61"+ + "\u2D62\u2D63\u2D64\u2D65\u2D66\u2D67\u2D68\u2D69"+ + "\u2D6A\u2D6B\u2D6C\u2D6D\u2D6E\u2D6F\u2D70\u2D71"+ + "\u2D72\u2D73\u2D74\u2D75\u2D76\u2D77\u2D78\u2D79"+ + "\u2D7A\u2D7B\u2D7C\u2D7D\u2D7E\u2D7F\u2D80\u2D81"+ + "\u2D82\u2D83\u2D84\u2D85\u2D86\u2D87\u2D88\u2D89"+ + "\u2D8A\u2D8B\u2D8C\u2D8D\u2D8E\u2D8F\u2D90\u2D91"+ + "\u2D92\u2D93\u2D94\u2D95\u2D96\u2D97\u2D98\u2D99"+ + "\u2D9A\u2D9B\u2D9C\u2D9D\u2D9E\u2D9F\u2DA0\u2DA1"+ + "\u2DA2\u2DA3\u2DA4\u2DA5\u2DA6\u2DA7\u2DA8\u2DA9"+ + "\u2DAA\u2DAB\u2DAC\u2DAD\u2DAE\u2DAF\u2DB0\u2DB1"+ + "\u2DB2\u2DB3\u2DB4\u2DB5\u2DB6\u2DB7\u2DB8\u2DB9"+ + "\u2DBA\u2DBB\u2DBC\u2DBD\u2DBE\u2DBF\u2DC0\u2DC1"+ + "\u2DC2\u2DC3\u2DC4\u2DC5\u2DC6\u2DC7\u2DC8\u2DC9"+ + "\u2DCA\u2DCB\u2DCC\u2DCD\u2DCE\u2DCF\u2DD0\u2DD1"+ + "\u2DD2\u2DD3\u2DD4\u2DD5\u2DD6\u2DD7\u2DD8\u2DD9"+ + "\u2DDA\u2DDB\u2DDC\u2DDD\u2DDE\u2DDF\u2DE0\u2DE1"+ + "\u2DE2\u2DE3\u2DE4\u2DE5\u2DE6\u2DE7\u2DE8\u2DE9"+ + "\u2DEA\u2DEB\u2DEC\u2DED\u2DEE\u2DEF\u2DF0\u2DF1"+ + "\u2DF2\u2DF3\u2DF4\u2DF5\u2DF6\u2DF7\u2DF8\u2DF9"+ + "\u2DFA\u2DFB\u2DFC\u2DFD\u2DFE\u2DFF\u2E00\u2E01"+ + "\u2E02\u2E03\u2E04\u2E05\u2E06\u2E07\u2E08\u2E09"+ + "\u2E0A\u2E0B\u2E0C\u2E0D\u2E0E\u2E0F\u2E10\u2E11"+ + "\u2E12\u2E13\u2E14\u2E15\u2E16\u2E17\u2E18\u2E19"+ + "\u2E1A\u2E1B\u2E1C\u2E1D\u2E1E\u2E1F\u2E20\u2E21"+ + "\u2E22\u2E23\u2E24\u2E25\u2E26\u2E27\u2E28\u2E29"+ + "\u2E2A\u2E2B\u2E2C\u2E2D\u2E2E\u2E2F\u2E30\u2E31"+ + "\u2E32\u2E33\u2E34\u2E35\u2E36\u2E37\u2E38\u2E39"+ + "\u2E3A\u2E3B\u2E3C\u2E3D\u2E3E\u2E3F\u2E40\u2E41"+ + "\u2E42\u2E43\u2E44\u2E45\u2E46\u2E47\u2E48\u2E49"+ + "\u2E4A\u2E4B\u2E4C\u2E4D\u2E4E\u2E4F\u2E50\u2E51"+ + "\u2E52\u2E53\u2E54\u2E55\u2E56\u2E57\u2E58\u2E59"+ + "\u2E5A\u2E5B\u2E5C\u2E5D\u2E5E\u2E5F\u2E60\u2E61"+ + "\u2E62\u2E63\u2E64\u2E65\u2E66\u2E67\u2E68\u2E69"+ + "\u2E6A\u2E6B\u2E6C\u2E6D\u2E6E\u2E6F\u2E70\u2E71"+ + "\u2E72\u2E73\u2E74\u2E75\u2E76\u2E77\u2E78\u2E79"+ + "\u2E7A\u2E7B\u2E7C\u2E7D\u2E7E\u2E7F\u2E80\u2E81"+ + "\u2E82\u2E83\u2E84\u2E85\u2E86\u2E87\u2E88\u2E89"+ + "\u2E8A\u2E8B\u2E8C\u2E8D\u2E8E\u2E8F\u2E90\u2E91"+ + "\u2E92\u2E93\u2E94\u2E95\u2E96\u2E97\u2E98\u2E99"+ + "\u2E9A\u2E9B\u2E9C\u2E9D\u2E9E\u2E9F\u2EA0\u2EA1"+ + "\u2EA2\u2EA3\u2EA4\u2EA5\u2EA6\u2EA7\u2EA8\u2EA9"+ + "\u2EAA\u2EAB\u2EAC\u2EAD\u2EAE\u2EAF\u2EB0\u2EB1"+ + "\u2EB2\u2EB3\u2EB4\u2EB5\u2EB6\u2EB7\u2EB8\u2EB9"+ + "\u2EBA\u2EBB\u2EBC\u2EBD\u2EBE\u2EBF\u2EC0\u2EC1"+ + "\u2EC2\u2EC3\u2EC4\u2EC5\u2EC6\u2EC7\u2EC8\u2EC9"+ + "\u2ECA\u2ECB\u2ECC\u2ECD\u2ECE\u2ECF\u2ED0\u2ED1"+ + "\u2ED2\u2ED3\u2ED4\u2ED5\u2ED6\u2ED7\u2ED8\u2ED9"+ + "\u2EDA\u2EDB\u2EDC\u2EDD\u2EDE\u2EDF\u2EE0\u2EE1"; + + private static final String innerEncoderIndex1= + "\u2EE2\u2EE3\u2EE4\u2EE5\u2EE6\u2EE7\u2EE8\u2EE9"+ + "\u2EEA\u2EEB\u2EEC\u2EED\u2EEE\u2EEF\u2EF0\u2EF1"+ + "\u2EF2\u2EF3\u2EF4\u2EF5\u2EF6\u2EF7\u2EF8\u2EF9"+ + "\u2EFA\u2EFB\u2EFC\u2EFD\u2EFE\u2EFF\u2F00\u2F01"+ + "\u2F02\u2F03\u2F04\u2F05\u2F06\u2F07\u2F08\u2F09"+ + "\u2F0A\u2F0B\u2F0C\u2F0D\u2F0E\u2F0F\u2F10\u2F11"+ + "\u2F12\u2F13\u2F14\u2F15\u2F16\u2F17\u2F18\u2F19"+ + "\u2F1A\u2F1B\u2F1C\u2F1D\u2F1E\u2F1F\u2F20\u2F21"+ + "\u2F22\u2F23\u2F24\u2F25\u2F26\u2F27\u2F28\u2F29"+ + "\u2F2A\u2F2B\u2F2C\u2F2D\u2F2E\u2F2F\u2F30\u2F31"+ + "\u2F32\u2F33\u2F34\u2F35\u2F36\u2F37\u2F38\u2F39"+ + "\u2F3A\u2F3B\u2F3C\u2F3D\u2F3E\u2F3F\u2F40\u2F41"+ + "\u2F42\u2F43\u2F44\u2F45\u2F46\u2F47\u2F48\u2F49"+ + "\u2F4A\u2F4B\u2F4C\u2F4D\u2F4E\u2F4F\u2F50\u2F51"+ + "\u2F52\u2F53\u2F54\u2F55\u2F56\u2F57\u2F58\u2F59"+ + "\u2F5A\u2F5B\u2F5C\u2F5D\u2F5E\u2F5F\u2F60\u2F61"+ + "\u2F62\u2F63\u2F64\u2F65\u2F66\u2F67\u2F68\u2F69"+ + "\u2F6A\u2F6B\u2F6C\u2F6D\u2F6E\u2F6F\u2F70\u2F71"+ + "\u2F72\u2F73\u2F74\u2F75\u2F76\u2F77\u2F78\u2F79"+ + "\u2F7A\u2F7B\u2F7C\u2F7D\u2F7E\u2F7F\u2F80\u2F81"+ + "\u2F82\u2F83\u2F84\u2F85\u2F86\u2F87\u2F88\u2F89"+ + "\u2F8A\u2F8B\u2F8C\u2F8D\u2F8E\u2F8F\u2F90\u2F91"+ + "\u2F92\u2F93\u2F94\u2F95\u2F96\u2F97\u2F98\u2F99"+ + "\u2F9A\u2F9B\u2F9C\u2F9D\u2F9E\u2F9F\u2FA0\u2FA1"+ + "\u2FA2\u2FA3\u2FA4\u2FA5\u2FA6\u2FA7\u2FA8\u2FA9"+ + "\u2FAA\u2FAB\u2FAC\u2FAD\u2FAE\u2FAF\u2FB0\u2FB1"+ + "\u2FB2\u2FB3\u2FB4\u2FB5\u2FB6\u2FB7\u2FB8\u2FB9"+ + "\u2FBA\u2FBB\u2FBC\u2FBD\u2FBE\u2FBF\u2FC0\u2FC1"+ + "\u2FC2\u2FC3\u2FC4\u2FC5\u2FC6\u2FC7\u2FC8\u2FC9"+ + "\u2FCA\u2FCB\u2FCC\u2FCD\u2FCE\u2FCF\u2FD0\u2FD1"+ + "\u2FD2\u2FD3\u2FD4\u2FD5\u2FD6\u2FD7\u2FD8\u2FD9"+ + "\u2FDA\u2FDB\u2FDC\u2FDD\u2FDE\u2FDF\u2FE0\u2FE1"+ + "\u2FE2\u2FE3\u2FE4\u2FE5\u2FE6\u2FE7\u2FE8\u2FE9"+ + "\u2FEA\u2FEB\u2FEC\u2FED\u2FEE\u2FEF\u2FF0\u2FF1"+ + "\u2FF2\u2FF3\u2FF4\u2FF5\u2FF6\u2FF7\u2FF8\u2FF9"+ + "\u2FFA\u2FFB\u2FFC\u2FFD\u2FFE\u2FFF\u3000\u3001"+ + "\u3002\u3003\u3004\u3005\u3006\u3007\u3008\u3009"+ + "\u300A\u300B\u300C\u300D\u300E\u300F\u3010\u3011"+ + "\u3012\u3013\u3014\u3015\u3016\u3017\u3018\u3019"+ + "\u301A\u301B\u301C\u301D\u301E\u301F\u3020\u3021"+ + "\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029"+ + "\u302A\u302B\u302C\u302D\u302E\u302F\u3030\u3031"+ + "\u3032\u3033\u3034\u3035\u3036\u3037\u3038\u3039"+ + "\u303A\u303B\u303C\u303D\u303E\u303F\u3040\u3041"+ + "\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049"+ + "\u304A\u304B\u304C\u304D\u304E\u304F\u3050\u3051"+ + "\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059"+ + "\u305A\u305B\u305C\u305D\u305E\u305F\u3060\u3061"+ + "\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069"+ + "\u306A\u306B\u306C\u306D\u306E\u306F\u3070\u3071"+ + "\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079"+ + "\u307A\u307B\u307C\u307D\u307E\u307F\u3080\u3081"+ + "\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089"+ + "\u308A\u308B\u308C\u308D\u308E\u308F\u3090\u3091"+ + "\u3092\u3093\u3094\u3095\u3096\u3097\u3098\u3099"+ + "\u309A\u309B\u309C\u309D\u309E\u309F\u30A0\u30A1"+ + "\u30A2\u30A3\u30A4\u30A5\u30A6\u30A7\u30A8\u30A9"+ + "\u30AA\u30AB\u30AC\u30AD\u30AE\u30AF\u30B0\u30B1"+ + "\u30B2\u30B3\u30B4\u30B5\u30B6\u30B7\u30B8\u30B9"+ + "\u30BA\u30BB\u30BC\u30BD\u30BE\u30BF\u30C0\u30C1"+ + "\u30C2\u30C3\u30C4\u30C5\u30C6\u30C7\u30C8\u30C9"+ + "\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D0\u30D1"+ + "\u30D2\u30D3\u30D4\u30D5\u30D6\u30D7\u30D8\u30D9"+ + "\u30DA\u30DB\u30DC\u30DD\u30DE\u30DF\u30E0\u30E1"+ + "\u30E2\u30E3\u30E4\u30E5\u30E6\u30E7\u30E8\u30E9"+ + "\u30EA\u30EB\u30EC\u30ED\u30EE\u30EF\u30F0\u30F1"+ + "\u30F2\u30F3\u30F4\u30F5\u30F6\u30F7\u30F8\u30F9"+ + "\u30FA\u30FB\u30FC\u30FD\u30FE\u30FF\u3100\u3101"+ + "\u3102\u3103\u3104\u3105\u3106\u3107\u3108\u3109"+ + "\u310A\u310B\u310C\u310D\u310E\u310F\u3110\u3111"+ + "\u3112\u3113\u3114\u3115\u3116\u3117\u3118\u3119"+ + "\u311A\u311B\u311C\u311D\u311E\u311F\u3120\u3121"+ + "\u3122\u3123\u3124\u3125\u3126\u3127\u3128\u3129"+ + "\u312A\u312B\u312C\u312D\u312E\u312F\u3130\u3131"+ + "\u3132\u3133\u3134\u3135\u3136\u3137\u3138\u3139"+ + "\u313A\u313B\u313C\u313D\u313E\u313F\u3140\u3141"+ + "\u3142\u3143\u3144\u3145\u3146\u3147\u3148\u3149"+ + "\u314A\u314B\u314C\u314D\u314E\u314F\u3150\u3151"+ + "\u3152\u3153\u3154\u3155\u3156\u3157\u3158\u3159"+ + "\u315A\u315B\u315C\u315D\u315E\u315F\u3160\u3161"+ + "\u3162\u3163\u3164\u3165\u3166\u3167\u3168\u3169"+ + "\u316A\u316B\u316C\u316D\u316E\u316F\u3170\u3171"+ + "\u3172\u3173\u3174\u3175\u3176\u3177\u3178\u3179"+ + "\u317A\u317B\u317C\u317D\u317E\u317F\u3180\u3181"+ + "\u3182\u3183\u3184\u3185\u3186\u3187\u3188\u3189"+ + "\u318A\u318B\u318C\u318D\u318E\u318F\u3190\u3191"+ + "\u3192\u3193\u3194\u3195\u3196\u3197\u3198\u3199"+ + "\u319A\u319B\u319C\u319D\u319E\u319F\u31A0\u31A1"+ + "\u31A2\u31A3\u31A4\u31A5\u31A6\u31A7\u31A8\u31A9"+ + "\u31AA\u31AB\u31AC\u31AD\u31AE\u31AF\u31B0\u31B1"+ + "\u31B2\u31B3\u31B4\u31B5\u31B6\u31B7\u31B8\u31B9"+ + "\u31BA\u31BB\u31BC\u31BD\u31BE\u31BF\u31C0\u31C1"+ + "\u31C2\u31C3\u31C4\u31C5\u31C6\u31C7\u31C8\u31C9"+ + "\u31CA\u31CB\u31CC\u31CD\u31CE\u31CF\u31D0\u31D1"+ + "\u31D2\u31D3\u31D4\u31D5\u31D6\u31D7\u31D8\u31D9"+ + "\u31DA\u31DB\u31DC\u31DD\u31DE\u31DF\u31E0\u31E1"+ + "\u31E2\u31E3\u31E4\u31E5\u31E6\u31E7\u31E8\u31E9"+ + "\u31EA\u31EB\u31EC\u31ED\u31EE\u31EF\u31F0\u31F1"+ + "\u31F2\u31F3\u31F4\u31F5\u31F6\u31F7\u31F8\u31F9"+ + "\u31FA\u31FB\u31FC\u31FD\u31FE\u31FF\u3200\u3201"+ + "\u3202\u3203\u3204\u3205\u3206\u3207\u3208\u3209"+ + "\u320A\u320B\u320C\u320D\u320E\u320F\u3210\u3211"+ + "\u3212\u3213\u3214\u3215\u3216\u3217\u3218\u3219"+ + "\u321A\u321B\u321C\u321D\u321E\u321F\u3220\u3221"+ + "\u3222\u3223\u3224\u3225\u3226\u3227\u3228\u3229"+ + "\u322A\u322B\u322C\u322D\u322E\u322F\u3230\u3231"+ + "\u3232\u3233\u3234\u3235\u3236\u3237\u3238\u3239"+ + "\u323A\u323B\u323C\u323D\u323E\u323F\u3240\u3241"+ + "\u3242\u3243\u3244\u3245\u3246\u3247\u3248\u3249"+ + "\u324A\u324B\u324C\u324D\u324E\u324F\u3250\u3251"+ + "\u3252\u3253\u3254\u3255\u3256\u3257\u3258\u3259"+ + "\u325A\u325B\u325C\u325D\u325E\u325F\u3260\u3261"+ + "\u3262\u3263\u3264\u3265\u3266\u3267\u3268\u3269"+ + "\u326A\u326B\u326C\u326D\u326E\u326F\u3270\u3271"+ + "\u3272\u3273\u3274\u3275\u3276\u3277\u3278\u3279"+ + "\u327A\u327B\u327C\u327D\u327E\u327F\u3280\u3281"+ + "\u3282\u3283\u3284\u3285\u3286\u3287\u3288\u3289"+ + "\u328A\u328B\u328C\u328D\u328E\u328F\u3290\u3291"+ + "\u3292\u3293\u3294\u3295\u3296\u3297\u3298\u3299"+ + "\u329A\u329B\u329C\u329D\u329E\u329F\u32A0\u32A1"+ + "\u32A2\u32A3\u32A4\u32A5\u32A6\u32A7\u32A8\u32A9"+ + "\u32AA\u32AB\u32AC\u32AD\u32AE\u32AF\u32B0\u32B1"+ + "\u32B2\u32B3\u32B4\u32B5\u32B6\u32B7\u32B8\u32B9"+ + "\u32BA\u32BB\u32BC\u32BD\u32BE\u32BF\u32C0\u32C1"+ + "\u32C2\u32C3\u32C4\u32C5\u32C6\u32C7\u32C8\u32C9"+ + "\u32CA\u32CB\u32CC\u32CD\u32CE\u32CF\u32D0\u32D1"+ + "\u32D2\u32D3\u32D4\u32D5\u32D6\u32D7\u32D8\u32D9"+ + "\u32DA\u32DB\u32DC\u32DD\u32DE\u32DF\u32E0\u32E1"+ + "\u32E2\u32E3\u32E4\u32E5\u32E6\u32E7\u32E8\u32E9"+ + "\u32EA\u32EB\u32EC\u32ED\u32EE\u32EF\u32F0\u32F1"+ + "\u32F2\u32F3\u32F4\u32F5\u32F6\u32F7\u32F8\u32F9"+ + "\u32FA\u32FB\u32FC\u32FD\u32FE\u32FF\u3300\u3301"+ + "\u3302\u3303\u3304\u3305\u3306\u3307\u3308\u3309"+ + "\u330A\u330B\u330C\u330D\u330E\u330F\u3310\u3311"+ + "\u3312\u3313\u3314\u3315\u3316\u3317\u3318\u3319"+ + "\u331A\u331B\u331C\u331D\u331E\u331F\u3320\u3321"+ + "\u3322\u3323\u3324\u3325\u3326\u3327\u3328\u3329"+ + "\u332A\u332B\u332C\u332D\u332E\u332F\u3330\u3331"+ + "\u3332\u3333\u3334\u3335\u3336\u3337\u3338\u3339"+ + "\u333A\u333B\u333C\u333D\u333E\u333F\u3340\u3341"+ + "\u3342\u3343\u3344\u3345\u3346\u3347\u3348\u3349"+ + "\u334A\u334B\u334C\u334D\u334E\u334F\u3350\u3351"+ + "\u3352\u3353\u3354\u3355\u3356\u3357\u3358\u3359"+ + "\u335A\u335B\u335C\u335D\u335E\u335F\u3360\u3361"+ + "\u3362\u3363\u3364\u3365\u3366\u3367\u3368\u3369"+ + "\u336A\u336B\u336C\u336D\u336E\u336F\u3370\u3371"+ + "\u3372\u3373\u3374\u3375\u3376\u3377\u3378\u3379"+ + "\u337A\u337B\u337C\u337D\u337E\u337F\u3380\u3381"+ + "\u3382\u3383\u3384\u3385\u3386\u3387\u3388\u3389"+ + "\u338A\u338B\u338C\u338D\u338E\u338F\u3390\u3391"+ + "\u3392\u3393\u3394\u3395\u3396\u3397\u3398\u3399"+ + "\u339A\u339B\u339C\u339D\u339E\u339F\u33A0\u33A1"+ + "\u33A2\u33A3\u33A4\u33A5\u33A6\u33A7\u33A8\u33A9"+ + "\u33AA\u33AB\u33AC\u33AD\u33AE\u33AF\u33B0\u33B1"+ + "\u33B2\u33B3\u33B4\u33B5\u33B6\u33B7\u33B8\u33B9"+ + "\u33BA\u33BB\u33BC\u33BD\u33BE\u33BF\u33C0\u33C1"+ + "\u33C2\u33C3\u33C4\u33C5\u33C6\u33C7\u33C8\u33C9"+ + "\u33CA\u33CB\u33CC\u33CD\u33CE\u33CF\u33D0\u33D1"+ + "\u33D2\u33D3\u33D4\u33D5\u33D6\u33D7\u33D8\u33D9"+ + "\u33DA\u33DB\u33DC\u33DD\u33DE\u33DF\u33E0\u33E1"+ + "\u33E2\u33E3\u33E4\u33E5\u33E6\u33E7\u33E8\u33E9"+ + "\u33EA\u33EB\u33EC\u33ED\u33EE\u33EF\u33F0\u33F1"+ + "\u33F2\u33F3\u33F4\u33F5\u33F6\u33F7\u33F8\u33F9"+ + "\u33FA\u33FB\u33FC\u33FD\u33FE\u33FF\u3400\u3401"+ + "\u3402\u3403\u3404\u3405\u3406\u3407\u3408\u3409"+ + "\u340A\u340B\u340C\u340D\u340E\u340F\u3410\u3411"+ + "\u3412\u3413\u3414\u3415\u3416\u3417\u3418\u3419"+ + "\u341A\u341B\u341C\u341D\u341E\u341F\u3420\u3421"+ + "\u3422\u3423\u3424\u3425\u3426\u3427\u3428\u3429"+ + "\u342A\u342B\u342C\u342D\u342E\u342F\u3430\u3431"+ + "\u3432\u3433\u3434\u3435\u3436\u3437\u3438\u3439"+ + "\u343A\u343B\u343C\u343D\u343E\u343F\u3440\u3441"+ + "\u3442\u3443\u3444\u3445\u3446\u3447\u3448\u3449"+ + "\u344A\u344B\u344C\u344D\u344E\u344F\u3450\u3451"+ + "\u3452\u3453\u3454\u3455\u3456\u3457\u3458\u3459"+ + "\u345A\u345B\u345C\u345D\u345E\u345F\u3460\u3461"+ + "\u3462\u3463\u3464\u3465\u3466\u3467\u3468\u3469"+ + "\u346A\u346B\u346C\u346D\u346E\u346F\u3470\u3471"+ + "\u3472\u3473\u3474\u3475\u3476\u3477\u3478\u3479"+ + "\u347A\u347B\u347C\u347D\u347E\u347F\u3480\u3481"+ + "\u3482\u3483\u3484\u3485\u3486\u3487\u3488\u3489"+ + "\u348A\u348B\u348C\u348D\u348E\u348F\u3490\u3491"+ + "\u3492\u3493\u3494\u3495\u3496\u3497\u3498\u3499"+ + "\u349A\u349B\u349C\u349D\u349E\u349F\u34A0\u34A1"+ + "\u34A2\u34A3\u34A4\u34A5\u34A6\u34A7\u34A8\u34A9"+ + "\u34AA\u34AB\u34AC\u34AD\u34AE\u34AF\u34B0\u34B1"+ + "\u34B2\u34B3\u34B4\u34B5\u34B6\u34B7\u34B8\u34B9"+ + "\u34BA\u34BB\u34BC\u34BD\u34BE\u34BF\u34C0\u34C1"+ + "\u34C2\u34C3\u34C4\u34C5\u34C6\u34C7\u34C8\u34C9"+ + "\u34CA\u34CB\u34CC\u34CD\u34CE\u34CF\u34D0\u34D1"+ + "\u34D2\u34D3\u34D4\u34D5\u34D6\u34D7\u34D8\u34D9"+ + "\u34DA\u34DB\u34DC\u34DD\u34DE\u34DF\u34E0\u34E1"+ + "\u34E2\u34E3\u34E4\u34E5\u34E6\u34E7\u34E8\u34E9"+ + "\u34EA\u34EB\u34EC\u34ED\u34EE\u34EF\u34F0\u34F1"+ + "\u34F2\u34F3\u34F4\u34F5\u34F6\u34F7\u34F8\u34F9"+ + "\u34FA\u34FB\u34FC\u34FD\u34FE\u34FF\u3500\u3501"+ + "\u3502\u3503\u3504\u3505\u3506\u3507\u3508\u3509"+ + "\u350A\u350B\u350C\u350D\u350E\u350F\u3510\u3511"+ + "\u3512\u3513\u3514\u3515\u3516\u3517\u3518\u3519"+ + "\u351A\u351B\u351C\u351D\u351E\u351F\u3520\u3521"+ + "\u3522\u3523\u3524\u3525\u3526\u3527\u3528\u3529"+ + "\u352A\u352B\u352C\u352D\u352E\u352F\u3530\u3531"+ + "\u3532\u3533\u3534\u3535\u3536\u3537\u3538\u3539"+ + "\u353A\u353B\u353C\u353D\u353E\u353F\u3540\u3541"+ + "\u3542\u3543\u3544\u3545\u3546\u3547\u3548\u3549"+ + "\u354A\u354B\u354C\u354D\u354E\u354F\u3550\u3551"+ + "\u3552\u3553\u3554\u3555\u3556\u3557\u3558\u3559"+ + "\u355A\u355B\u355C\u355D\u355E\u355F\u3560\u3561"+ + "\u3562\u3563\u3564\u3565\u3566\u3567\u3568\u3569"+ + "\u356A\u356B\u356C\u356D\u356E\u356F\u3570\u3571"+ + "\u3572\u3573\u3574\u3575\u3576\u3577\u3578\u3579"+ + "\u357A\u357B\u357C\u357D\u357E\u357F\u3580\u3581"+ + "\u3582\u3583\u3584\u3585\u3586\u3587\u3588\u3589"+ + "\u358A\u358B\u358C\u358D\u358E\u358F\u3590\u3591"+ + "\u3592\u3593\u3594\u3595\u3596\u3597\u3598\u3599"+ + "\u359A\u359B\u359C\u359D\u359E\u359F\u35A0\u35A1"+ + "\u35A2\u35A3\u35A4\u35A5\u35A6\u35A7\u35A8\u35A9"+ + "\u35AA\u35AB\u35AC\u35AD\u35AE\u35AF\u35B0\u35B1"+ + "\u35B2\u35B3\u35B4\u35B5\u35B6\u35B7\u35B8\u35B9"+ + "\u35BA\u35BB\u35BC\u35BD\u35BE\u35BF\u35C0\u35C1"+ + "\u35C2\u35C3\u35C4\u35C5\u35C6\u35C7\u35C8\u35C9"+ + "\u35CA\u35CB\u35CC\u35CD\u35CE\u35CF\u35D0\u35D1"+ + "\u35D2\u35D3\u35D4\u35D5\u35D6\u35D7\u35D8\u35D9"+ + "\u35DA\u35DB\u35DC\u35DD\u35DE\u35DF\u35E0\u35E1"+ + "\u35E2\u35E3\u35E4\u35E5\u35E6\u35E7\u35E8\u35E9"+ + "\u35EA\u35EB\u35EC\u35ED\u35EE\u35EF\u35F0\u35F1"+ + "\u35F2\u35F3\u35F4\u35F5\u35F6\u35F7\u35F8\u35F9"+ + "\u35FA\u35FB\u35FC\u35FD\u35FE\u35FF\u3600\u3601"+ + "\u3602\u3603\u3604\u3605\u3606\u3607\u3608\u3609"+ + "\u360A\u360B\u360C\u360D\u360E\u360F\u3610\u3611"+ + "\u3612\u3613\u3614\u3615\u3616\u3617\u3618\u3619"+ + "\u361A\u361B\u361C\u361D\u361E\u361F\u3620\u3621"+ + "\u3622\u3623\u3624\u3625\u3626\u3627\u3628\u3629"+ + "\u362A\u362B\u362C\u362D\u362E\u362F\u3630\u3631"+ + "\u3632\u3633\u3634\u3635\u3636\u3637\u3638\u3639"+ + "\u363A\u363B\u363C\u363D\u363E\u363F\u3640\u3641"+ + "\u3642\u3643\u3644\u3645\u3646\u3647\u3648\u3649"+ + "\u364A\u364B\u364C\u364D\u364E\u364F\u3650\u3651"+ + "\u3652\u3653\u3654\u3655\u3656\u3657\u3658\u3659"+ + "\u365A\u365B\u365C\u365D\u365E\u365F\u3660\u3661"+ + "\u3662\u3663\u3664\u3665\u3666\u3667\u3668\u3669"+ + "\u366A\u366B\u366C\u366D\u366E\u366F\u3670\u3671"+ + "\u3672\u3673\u3674\u3675\u3676\u3677\u3678\u3679"+ + "\u367A\u367B\u367C\u367D\u367E\u367F\u3680\u3681"+ + "\u3682\u3683\u3684\u3685\u3686\u3687\u3688\u3689"+ + "\u368A\u368B\u368C\u368D\u368E\u368F\u3690\u3691"+ + "\u3692\u3693\u3694\u3695\u3696\u3697\u3698\u3699"+ + "\u369A\u369B\u369C\u369D\u369E\u369F\u36A0\u36A1"+ + "\u36A2\u36A3\u36A4\u36A5\u36A6\u36A7\u36A8\u36A9"+ + "\u36AA\u36AB\u36AC\u36AD\u36AE\u36AF\u36B0\u36B1"+ + "\u36B2\u36B3\u36B4\u36B5\u36B6\u36B7\u36B8\u36B9"+ + "\u36BA\u36BB\u36BC\u36BD\u36BE\u36BF\u36C0\u36C1"+ + "\u36C2\u36C3\u36C4\u36C5\u36C6\u36C7\u36C8\u36C9"+ + "\u36CA\u36CB\u36CC\u36CD\u36CE\u36CF\u36D0\u36D1"+ + "\u36D2\u36D3\u36D4\u36D5\u36D6\u36D7\u36D8\u36D9"+ + "\u36DA\u36DB\u36DC\u36DD\u36DE\u36DF\u36E0\u36E1"+ + "\u36E2\u36E3\u36E4\u36E5\u36E6\u36E7\u36E8\u36E9"+ + "\u36EA\u36EB\u36EC\u36ED\u36EE\u36EF\u36F0\u36F1"+ + "\u36F2\u36F3\u36F4\u36F5\u36F6\u36F7\u36F8\u36F9"+ + "\u36FA\u36FB\u36FC\u36FD\u36FE\u36FF\u3700\u3701"+ + "\u3702\u3703\u3704\u3705\u3706\u3707\u3708\u3709"+ + "\u370A\u370B\u370C\u370D\u370E\u370F\u3710\u3711"+ + "\u3712\u3713\u3714\u3715\u3716\u3717\u3718\u3719"+ + "\u371A\u371B\u371C\u371D\u371E\u371F\u3720\u3721"+ + "\u3722\u3723\u3724\u3725\u3726\u3727\u3728\u3729"+ + "\u372A\u372B\u372C\u372D\u372E\u372F\u3730\u3731"+ + "\u3732\u3733\u3734\u3735\u3736\u3737\u3738\u3739"+ + "\u373A\u373B\u373C\u373D\u373E\u373F\u3740\u3741"+ + "\u3742\u3743\u3744\u3745\u3746\u3747\u3748\u3749"+ + "\u374A\u374B\u374C\u374D\u374E\u374F\u3750\u3751"+ + "\u3752\u3753\u3754\u3755\u3756\u3757\u3758\u3759"+ + "\u375A\u375B\u375C\u375D\u375E\u375F\u3760\u3761"+ + "\u3762\u3763\u3764\u3765\u3766\u3767\u3768\u3769"+ + "\u376A\u376B\u376C\u376D\u376E\u376F\u3770\u3771"+ + "\u3772\u3773\u3774\u3775\u3776\u3777\u3778\u3779"+ + "\u377A\u377B\u377C\u377D\u377E\u377F\u3780\u3781"+ + "\u3782\u3783\u3784\u3785\u3786\u3787\u3788\u3789"+ + "\u378A\u378B\u378C\u378D\u378E\u378F\u3790\u3791"+ + "\u3792\u3793\u3794\u3795\u3796\u3797\u3798\u3799"+ + "\u379A\u379B\u379C\u379D\u379E\u379F\u37A0\u37A1"+ + "\u37A2\u37A3\u37A4\u37A5\u37A6\u37A7\u37A8\u37A9"+ + "\u37AA\u37AB\u37AC\u37AD\u37AE\u37AF\u37B0\u37B1"+ + "\u37B2\u37B3\u37B4\u37B5\u37B6\u37B7\u37B8\u37B9"+ + "\u37BA\u37BB\u37BC\u37BD\u37BE\u37BF\u37C0\u37C1"+ + "\u37C2\u37C3\u37C4\u37C5\u37C6\u37C7\u37C8\u37C9"+ + "\u37CA\u37CB\u37CC\u37CD\u37CE\u37CF\u37D0\u37D1"+ + "\u37D2\u37D3\u37D4\u37D5\u37D6\u37D7\u37D8\u37D9"+ + "\u37DA\u37DB\u37DC\u37DD\u37DE\u37DF\u37E0\u37E1"+ + "\u37E2\u37E3\u37E4\u37E5\u37E6\u37E7\u37E8\u37E9"+ + "\u37EA\u37EB\u37EC\u37ED\u37EE\u37EF\u37F0\u37F1"+ + "\u37F2\u37F3\u37F4\u37F5\u37F6\u37F7\u37F8\u37F9"+ + "\u37FA\u37FB\u37FC\u37FD\u37FE\u37FF\u3800\u3801"+ + "\u3802\u3803\u3804\u3805\u3806\u3807\u3808\u3809"+ + "\u380A\u380B\u380C\u380D\u380E\u380F\u3810\u3811"+ + "\u3812\u3813\u3814\u3815\u3816\u3817\u3818\u3819"+ + "\u381A\u381B\u381C\u381D\u381E\u381F\u3820\u3821"+ + "\u3822\u3823\u3824\u3825\u3826\u3827\u3828\u3829"+ + "\u382A\u382B\u382C\u382D\u382E\u382F\u3830\u3831"+ + "\u3832\u3833\u3834\u3835\u3836\u3837\u3838\u3839"+ + "\u383A\u383B\u383C\u383D\u383E\u383F\u3840\u3841"+ + "\u3842\u3843\u3844\u3845\u3846\u3847\u3848\u3849"+ + "\u384A\u384B\u384C\u384D\u384E\u384F\u3850\u3851"+ + "\u3852\u3853\u3854\u3855\u3856\u3857\u3858\u3859"+ + "\u385A\u385B\u385C\u385D\u385E\u385F\u3860\u3861"+ + "\u3862\u3863\u3864\u3865\u3866\u3867\u3868\u3869"+ + "\u386A\u386B\u386C\u386D\u386E\u386F\u3870\u3871"+ + "\u3872\u3873\u3874\u3875\u3876\u3877\u3878\u3879"+ + "\u387A\u387B\u387C\u387D\u387E\u387F\u3880\u3881"+ + "\u3882\u3883\u3884\u3885\u3886\u3887\u3888\u3889"+ + "\u388A\u388B\u388C\u388D\u388E\u388F\u3890\u3891"+ + "\u3892\u3893\u3894\u3895\u3896\u3897\u3898\u3899"+ + "\u389A\u389B\u389C\u389D\u389E\u389F\u38A0\u38A1"+ + "\u38A2\u38A3\u38A4\u38A5\u38A6\u38A7\u38A8\u38A9"+ + "\u38AA\u38AB\u38AC\u38AD\u38AE\u38AF\u38B0\u38B1"+ + "\u38B2\u38B3\u38B4\u38B5\u38B6\u38B7\u38B8\u38B9"+ + "\u38BA\u38BB\u38BC\u38BD\u38BE\u38BF\u38C0\u38C1"+ + "\u38C2\u38C3\u38C4\u38C5\u38C6\u38C7\u38C8\u38C9"+ + "\u38CA\u38CB\u38CC\u38CD\u38CE\u38CF\u38D0\u38D1"+ + "\u38D2\u38D3\u38D4\u38D5\u38D6\u38D7\u38D8\u38D9"+ + "\u38DA\u38DB\u38DC\u38DD\u38DE\u38DF\u38E0\u38E1"+ + "\u38E2\u38E3\u38E4\u38E5\u38E6\u38E7\u38E8\u38E9"+ + "\u38EA\u38EB\u38EC\u38ED\u38EE\u38EF\u38F0\u38F1"+ + "\u38F2\u38F3\u38F4\u38F5\u38F6\u38F7\u38F8\u38F9"+ + "\u38FA\u38FB\u38FC\u38FD\u38FE\u38FF\u3900\u3901"+ + "\u3902\u3903\u3904\u3905\u3906\u3907\u3908\u3909"+ + "\u390A\u390B\u390C\u390D\u390E\u390F\u3910\u3911"+ + "\u3912\u3913\u3914\u3915\u3916\u3917\u3918\u3919"+ + "\u391A\u391B\u391C\u391D\u391E\u391F\u3920\u3921"+ + "\u3922\u3923\u3924\u3925\u3926\u3927\u3928\u3929"+ + "\u392A\u392B\u392C\u392D\u392E\u392F\u3930\u3931"+ + "\u3932\u3933\u3934\u3935\u3936\u3937\u3938\u3939"+ + "\u393A\u393B\u393C\u393D\u393E\u393F\u3940\u3941"+ + "\u3942\u3943\u3944\u3945\u3946\u3947\u3948\u3949"+ + "\u394A\u394B\u394C\u394D\u394E\u394F\u3950\u3951"+ + "\u3952\u3953\u3954\u3955\u3956\u3957\u3958\u3959"+ + "\u395A\u395B\u395C\u395D\u395E\u395F\u3960\u3961"+ + "\u3962\u3963\u3964\u3965\u3966\u3967\u3968\u3969"+ + "\u396A\u396B\u396C\u396D\u396E\u396F\u3970\u3971"+ + "\u3972\u3973\u3974\u3975\u3976\u3977\u3978\u3979"+ + "\u397A\u397B\u397C\u397D\u397E\u397F\u3980\u3981"+ + "\u3982\u3983\u3984\u3985\u3986\u3987\u3988\u3989"+ + "\u398A\u398B\u398C\u398D\u398E\u398F\u3990\u3991"+ + "\u3992\u3993\u3994\u3995\u3996\u3997\u3998\u3999"+ + "\u399A\u399B\u399C\u399D\u399E\u399F\u39A0\u39A1"+ + "\u39A2\u39A3\u39A4\u39A5\u39A6\u39A7\u39A8\u39A9"+ + "\u39AA\u39AB\u39AC\u39AD\u39AE\u39AF\u39B0\u39B1"+ + "\u39B2\u39B3\u39B4\u39B5\u39B6\u39B7\u39B8\u39B9"+ + "\u39BA\u39BB\u39BC\u39BD\u39BE\u39BF\u39C0\u39C1"+ + "\u39C2\u39C3\u39C4\u39C5\u39C6\u39C7\u39C8\u39C9"+ + "\u39CA\u39CB\u39CC\u39CD\u39CE\u39CF\u39D0\u39D1"+ + "\u39D2\u39D3\u39D4\u39D5\u39D6\u39D7\u39D8\u39D9"+ + "\u39DA\u39DB\u39DC\u39DD\u39DE\u39DF\u39E0\u39E1"+ + "\u39E2\u39E3\u39E4\u39E5\u39E6\u39E7\u39E8\u39E9"+ + "\u39EA\u39EB\u39EC\u39ED\u39EE\u39EF\u39F0\u39F1"+ + "\u39F2\u39F3\u39F4\u39F5\u39F6\u39F7\u39F8\u39F9"+ + "\u39FA\u39FB\u39FC\u39FD\u39FE\u39FF\u3A00\u3A01"+ + "\u3A02\u3A03\u3A04\u3A05\u3A06\u3A07\u3A08\u3A09"+ + "\u3A0A\u3A0B\u3A0C\u3A0D\u3A0E\u3A0F\u3A10\u3A11"+ + "\u3A12\u3A13\u3A14\u3A15\u3A16\u3A17\u3A18\u3A19"+ + "\u3A1A\u3A1B\u3A1C\u3A1D\u3A1E\u3A1F\u3A20\u3A21"+ + "\u3A22\u3A23\u3A24\u3A25\u3A26\u3A27\u3A28\u3A29"+ + "\u3A2A\u3A2B\u3A2C\u3A2D\u3A2E\u3A2F\u3A30\u3A31"+ + "\u3A32\u3A33\u3A34\u3A35\u3A36\u3A37\u3A38\u3A39"+ + "\u3A3A\u3A3B\u3A3C\u3A3D\u3A3E\u3A3F\u3A40\u3A41"+ + "\u3A42\u3A43\u3A44\u3A45\u3A46\u3A47\u3A48\u3A49"+ + "\u3A4A\u3A4B\u3A4C\u3A4D\u3A4E\u3A4F\u3A50\u3A51"+ + "\u3A52\u3A53\u3A54\u3A55\u3A56\u3A57\u3A58\u3A59"+ + "\u3A5A\u3A5B\u3A5C\u3A5D\u3A5E\u3A5F\u3A60\u3A61"+ + "\u3A62\u3A63\u3A64\u3A65\u3A66\u3A67\u3A68\u3A69"+ + "\u3A6A\u3A6B\u3A6C\u3A6D\u3A6E\u3A6F\u3A70\u3A71"+ + "\u3A72\u3A73\u3A74\u3A75\u3A76\u3A77\u3A78\u3A79"+ + "\u3A7A\u3A7B\u3A7C\u3A7D\u3A7E\u3A7F\u3A80\u3A81"+ + "\u3A82\u3A83\u3A84\u3A85\u3A86\u3A87\u3A88\u3A89"+ + "\u3A8A\u3A8B\u3A8C\u3A8D\u3A8E\u3A8F\u3A90\u3A91"+ + "\u3A92\u3A93\u3A94\u3A95\u3A96\u3A97\u3A98\u3A99"+ + "\u3A9A\u3A9B\u3A9C\u3A9D\u3A9E\u3A9F\u3AA0\u3AA1"+ + "\u3AA2\u3AA3\u3AA4\u3AA5\u3AA6\u3AA7\u3AA8\u3AA9"+ + "\u3AAA\u3AAB\u3AAC\u3AAD\u3AAE\u3AAF\u3AB0\u3AB1"+ + "\u3AB2\u3AB3\u3AB4\u3AB5\u3AB6\u3AB7\u3AB8\u3AB9"+ + "\u3ABA\u3ABB\u3ABC\u3ABD\u3ABE\u3ABF\u3AC0\u3AC1"+ + "\u3AC2\u3AC3\u3AC4\u3AC5\u3AC6\u3AC7\u3AC8\u3AC9"+ + "\u3ACA\u3ACB\u3ACC\u3ACD\u3ACE\u3ACF\u3AD0\u3AD1"+ + "\u3AD2\u3AD3\u3AD4\u3AD5\u3AD6\u3AD7\u3AD8\u3AD9"+ + "\u3ADA\u3ADB\u3ADC\u3ADD\u3ADE\u3ADF\u3AE0\u3AE1"+ + "\u3AE2\u3AE3\u3AE4\u3AE5\u3AE6\u3AE7\u3AE8\u3AE9"+ + "\u3AEA\u3AEB\u3AEC\u3AED\u3AEE\u3AEF\u3AF0\u3AF1"+ + "\u3AF2\u3AF3\u3AF4\u3AF5\u3AF6\u3AF7\u3AF8\u3AF9"+ + "\u3AFA\u3AFB\u3AFC\u3AFD\u3AFE\u3AFF\u3B00\u3B01"+ + "\u3B02\u3B03\u3B04\u3B05\u3B06\u3B07\u3B08\u3B09"+ + "\u3B0A\u3B0B\u3B0C\u3B0D\u3B0E\u3B0F\u3B10\u3B11"+ + "\u3B12\u3B13\u3B14\u3B15\u3B16\u3B17\u3B18\u3B19"+ + "\u3B1A\u3B1B\u3B1C\u3B1D\u3B1E\u3B1F\u3B20\u3B21"+ + "\u3B22\u3B23\u3B24\u3B25\u3B26\u3B27\u3B28\u3B29"+ + "\u3B2A\u3B2B\u3B2C\u3B2D\u3B2E\u3B2F\u3B30\u3B31"+ + "\u3B32\u3B33\u3B34\u3B35\u3B36\u3B37\u3B38\u3B39"+ + "\u3B3A\u3B3B\u3B3C\u3B3D\u3B3E\u3B3F\u3B40\u3B41"+ + "\u3B42\u3B43\u3B44\u3B45\u3B46\u3B47\u3B48\u3B49"+ + "\u3B4A\u3B4B\u3B4C\u3B4D\u3B4E\u3B4F\u3B50\u3B51"+ + "\u3B52\u3B53\u3B54\u3B55\u3B56\u3B57\u3B58\u3B59"+ + "\u3B5A\u3B5B\u3B5C\u3B5D\u3B5E\u3B5F\u3B60\u3B61"+ + "\u3B62\u3B63\u3B64\u3B65\u3B66\u3B67\u3B68\u3B69"+ + "\u3B6A\u3B6B\u3B6C\u3B6D\u3B6E\u3B6F\u3B70\u3B71"+ + "\u3B72\u3B73\u3B74\u3B75\u3B76\u3B77\u3B78\u3B79"+ + "\u3B7A\u3B7B\u3B7C\u3B7D\u3B7E\u3B7F\u3B80\u3B81"+ + "\u3B82\u3B83\u3B84\u3B85\u3B86\u3B87\u3B88\u3B89"+ + "\u3B8A\u3B8B\u3B8C\u3B8D\u3B8E\u3B8F\u3B90\u3B91"+ + "\u3B92\u3B93\u3B94\u3B95\u3B96\u3B97\u3B98\u3B99"+ + "\u3B9A\u3B9B\u3B9C\u3B9D\u3B9E\u3B9F\u3BA0\u3BA1"+ + "\u3BA2\u3BA3\u3BA4\u3BA5\u3BA6\u3BA7\u3BA8\u3BA9"+ + "\u3BAA\u3BAB\u3BAC\u3BAD\u3BAE\u3BAF\u3BB0\u3BB1"+ + "\u3BB2\u3BB3\u3BB4\u3BB5\u3BB6\u3BB7\u3BB8\u3BB9"+ + "\u3BBA\u3BBB\u3BBC\u3BBD\u3BBE\u3BBF\u3BC0\u3BC1"+ + "\u3BC2\u3BC3\u3BC4\u3BC5\u3BC6\u3BC7\u3BC8\u3BC9"+ + "\u3BCA\u3BCB\u3BCC\u3BCD\u3BCE\u3BCF\u3BD0\u3BD1"+ + "\u3BD2\u3BD3\u3BD4\u3BD5\u3BD6\u3BD7\u3BD8\u3BD9"+ + "\u3BDA\u3BDB\u3BDC\u3BDD\u3BDE\u3BDF\u3BE0\u3BE1"+ + "\u3BE2\u3BE3\u3BE4\u3BE5\u3BE6\u3BE7\u3BE8\u3BE9"+ + "\u3BEA\u3BEB\u3BEC\u3BED\u3BEE\u3BEF\u3BF0\u3BF1"+ + "\u3BF2\u3BF3\u3BF4\u3BF5\u3BF6\u3BF7\u3BF8\u3BF9"+ + "\u3BFA\u3BFB\u3BFC\u3BFD\u3BFE\u3BFF\u3C00\u3C01"+ + "\u3C02\u3C03\u3C04\u3C05\u3C06\u3C07\u3C08\u3C09"+ + "\u3C0A\u3C0B\u3C0C\u3C0D\u3C0E\u3C0F\u3C10\u3C11"+ + "\u3C12\u3C13\u3C14\u3C15\u3C16\u3C17\u3C18\u3C19"+ + "\u3C1A\u3C1B\u3C1C\u3C1D\u3C1E\u3C1F\u3C20\u3C21"+ + "\u3C22\u3C23\u3C24\u3C25\u3C26\u3C27\u3C28\u3C29"+ + "\u3C2A\u3C2B\u3C2C\u3C2D\u3C2E\u3C2F\u3C30\u3C31"+ + "\u3C32\u3C33\u3C34\u3C35\u3C36\u3C37\u3C38\u3C39"+ + "\u3C3A\u3C3B\u3C3C\u3C3D\u3C3E\u3C3F\u3C40\u3C41"+ + "\u3C42\u3C43\u3C44\u3C45\u3C46\u3C47\u3C48\u3C49"+ + "\u3C4A\u3C4B\u3C4C\u3C4D\u3C4E\u3C4F\u3C50\u3C51"+ + "\u3C52\u3C53\u3C54\u3C55\u3C56\u3C57\u3C58\u3C59"+ + "\u3C5A\u3C5B\u3C5C\u3C5D\u3C5E\u3C5F\u3C60\u3C61"+ + "\u3C62\u3C63\u3C64\u3C65\u3C66\u3C67\u3C68\u3C69"+ + "\u3C6A\u3C6B\u3C6C\u3C6D\u3C6E\u3C6F\u3C70\u3C71"+ + "\u3C72\u3C73\u3C74\u3C75\u3C76\u3C77\u3C78\u3C79"+ + "\u3C7A\u3C7B\u3C7C\u3C7D\u3C7E\u3C7F\u3C80\u3C81"+ + "\u3C82\u3C83\u3C84\u3C85\u3C86\u3C87\u3C88\u3C89"+ + "\u3C8A\u3C8B\u3C8C\u3C8D\u3C8E\u3C8F\u3C90\u3C91"+ + "\u3C92\u3C93\u3C94\u3C95\u3C96\u3C97\u3C98\u3C99"+ + "\u3C9A\u3C9B\u3C9C\u3C9D\u3C9E\u3C9F\u3CA0\u3CA1"+ + "\u3CA2\u3CA3\u3CA4\u3CA5\u3CA6\u3CA7\u3CA8\u3CA9"+ + "\u3CAA\u3CAB\u3CAC\u3CAD\u3CAE\u3CAF\u3CB0\u3CB1"+ + "\u3CB2\u3CB3\u3CB4\u3CB5\u3CB6\u3CB7\u3CB8\u3CB9"+ + "\u3CBA\u3CBB\u3CBC\u3CBD\u3CBE\u3CBF\u3CC0\u3CC1"+ + "\u3CC2\u3CC3\u3CC4\u3CC5\u3CC6\u3CC7\u3CC8\u3CC9"+ + "\u3CCA\u3CCB\u3CCC\u3CCD\u3CCE\u3CCF\u3CD0\u3CD1"+ + "\u3CD2\u3CD3\u3CD4\u3CD5\u3CD6\u3CD7\u3CD8\u3CD9"+ + "\u3CDA\u3CDB\u3CDC\u3CDD\u3CDE\u3CDF\u3CE0\u3CE1"+ + "\u3CE2\u3CE3\u3CE4\u3CE5\u3CE6\u3CE7\u3CE8\u3CE9"+ + "\u3CEA\u3CEB\u3CEC\u3CED\u3CEE\u3CEF\u3CF0\u3CF1"+ + "\u3CF2\u3CF3\u3CF4\u3CF5\u3CF6\u3CF7\u3CF8\u3CF9"+ + "\u3CFA\u3CFB\u3CFC\u3CFD\u3CFE\u3CFF\u3D00\u3D01"+ + "\u3D02\u3D03\u3D04\u3D05\u3D06\u3D07\u3D08\u3D09"+ + "\u3D0A\u3D0B\u3D0C\u3D0D\u3D0E\u3D0F\u3D10\u3D11"+ + "\u3D12\u3D13\u3D14\u3D15\u3D16\u3D17\u3D18\u3D19"+ + (IS_2000 ? "\u3D1A\u3D1B\u3D1C\u3D1D\u3D1E\u3D1F\u3D20\u3D21" : + "\u3D1A\u3D1B\u3D1C\u3D1D\u3D1E\u3D1F\u3D20\uA8BC")+ + "\u3D22\u3D23\u3D24\u3D25\u3D26\u3D27\u3D28\u3D29"+ + "\u3D2A\u3D2B\u3D2C\u3D2D\u3D2E\u3D2F\u3D30\u3D31"+ + "\u3D32\u3D33\u3D34\u3D35\u3D36\u3D37\u3D38\u3D39"+ + "\u3D3A\u3D3B\u3D3C\u3D3D\u3D3E\u3D3F\u3D40\u3D41"+ + "\u3D42\u3D43\u3D44\u3D45\u3D46\u3D47\u3D48\u3D49"+ + "\u3D4A\u3D4B\u3D4C\u3D4D\u3D4E\u3D4F\u3D50\u3D51"+ + "\u3D52\u3D53\u3D54\u3D55\u3D56\u3D57\u3D58\u3D59"+ + "\u3D5A\u3D5B\u3D5C\u3D5D\u3D5E\u3D5F\u3D60\u3D61"+ + "\u3D62\u3D63\u3D64\u3D65\u3D66\u3D67\u3D68\u3D69"+ + "\u3D6A\u3D6B\u3D6C\u3D6D\u3D6E\u3D6F\u3D70\u3D71"+ + "\u3D72\u3D73\u3D74\u3D75\u3D76\u3D77\u3D78\u3D79"+ + "\u3D7A\u3D7B\u3D7C\u3D7D\u3D7E\u3D7F\u3D80\u3D81"+ + "\u3D82\u3D83\u3D84\u3D85\u3D86\u3D87\u3D88\u3D89"+ + "\u3D8A\u3D8B\u3D8C\u3D8D\u3D8E\u3D8F\u3D90\u3D91"+ + "\u3D92\u3D93\u3D94\u3D95\u3D96\u3D97\u3D98\u3D99"+ + "\u3D9A\u3D9B\u3D9C\u3D9D\u3D9E\u3D9F\u3DA0\u3DA1"+ + "\u3DA2\u3DA3\u3DA4\u3DA5\u3DA6\u3DA7\u3DA8\u3DA9"+ + "\u3DAA\u3DAB\u3DAC\u3DAD\u3DAE\u3DAF\u3DB0\u3DB1"+ + "\u3DB2\u3DB3\u3DB4\u3DB5\u3DB6\u3DB7\u3DB8\u3DB9"+ + "\u3DBA\u3DBB\u3DBC\u3DBD\u3DBE\u3DBF\u3DC0\u3DC1"+ + "\u3DC2\u3DC3\u3DC4\u3DC5\u3DC6\u3DC7\u3DC8\u3DC9"+ + "\u3DCA\u3DCB\u3DCC\u3DCD\u3DCE\u3DCF\u3DD0\u3DD1"+ + "\u3DD2\u3DD3\u3DD4\u3DD5\u3DD6\u3DD7\u3DD8\u3DD9"+ + "\u3DDA\u3DDB\u3DDC\u3DDD\u3DDE\u3DDF\u3DE0\u3DE1"+ + "\u3DE2\u3DE3\u3DE4\u3DE5\u3DE6\u3DE7\u3DE8\u3DE9"+ + "\u3DEA\u3DEB\u3DEC\u3DED\u3DEE\u3DEF\u3DF0\u3DF1"+ + "\u3DF2\u3DF3\u3DF4\u3DF5\u3DF6\u3DF7\u3DF8\u3DF9"+ + "\u3DFA\u3DFB\u3DFC\u3DFD\u3DFE\u3DFF\u3E00\u3E01"+ + "\u3E02\u3E03\u3E04\u3E05\u3E06\u3E07\u3E08\u3E09"+ + "\u3E0A\u3E0B\u3E0C\u3E0D\u3E0E\u3E0F\u3E10\u3E11"+ + "\u3E12\u3E13\u3E14\u3E15\u3E16\u3E17\u3E18\u3E19"+ + "\u3E1A\u3E1B\u3E1C\u3E1D\u3E1E\u3E1F\u3E20\u3E21"+ + "\u3E22\u3E23\u3E24\u3E25\u3E26\u3E27\u3E28\u3E29"+ + "\u3E2A\u3E2B\u3E2C\u3E2D\u3E2E\u3E2F\u3E30\u3E31"+ + "\u3E32\u3E33\u3E34\u3E35\u3E36\u3E37\u3E38\u3E39"+ + "\u3E3A\u3E3B\u3E3C\u3E3D\u3E3E\u3E3F\u3E40\u3E41"+ + "\u3E42\u3E43\u3E44\u3E45\u3E46\u3E47\u3E48\u3E49"+ + "\u3E4A\u3E4B\u3E4C\u3E4D\u3E4E\u3E4F\u3E50\u3E51"+ + "\u3E52\u3E53\u3E54\u3E55\u3E56\u3E57\u3E58\u3E59"+ + "\u3E5A\u3E5B\u3E5C\u3E5D\u3E5E\u3E5F\u3E60\u3E61"+ + "\u3E62\u3E63\u3E64\u3E65\u3E66\u3E67\u3E68\u3E69"+ + "\u3E6A\u3E6B\u3E6C\u3E6D\u3E6E\u3E6F\u3E70\u3E71"+ + "\u3E72\u3E73\u3E74\u3E75\u3E76\u3E77\u3E78\u3E79"+ + "\u3E7A\u3E7B\u3E7C\u3E7D\u3E7E\u3E7F\u3E80\u3E81"+ + "\u3E82\u3E83\u3E84\u3E85\u3E86\u3E87\u3E88\u3E89"+ + "\u3E8A\u3E8B\u3E8C\u3E8D\u3E8E\u3E8F\u3E90\u3E91"+ + "\u3E92\u3E93\u3E94\u3E95\u3E96\u3E97\u3E98\u3E99"+ + "\u3E9A\u3E9B\u3E9C\u3E9D\u3E9E\u3E9F\u3EA0\u3EA1"+ + "\u3EA2\u3EA3\u3EA4\u3EA5\u3EA6\u3EA7\u3EA8\u3EA9"+ + "\u3EAA\u3EAB\u3EAC\u3EAD\u3EAE\u3EAF\u3EB0\u3EB1"+ + "\u3EB2\u3EB3\u3EB4\u3EB5\u3EB6\u3EB7\u3EB8\u3EB9"+ + "\u3EBA\u3EBB\u3EBC\u3EBD\u3EBE\u3EBF\u3EC0\u3EC1"+ + "\u3EC2\u3EC3\u3EC4\u3EC5\u3EC6\u3EC7\u3EC8\u3EC9"+ + "\u3ECA\u3ECB\u3ECC\u3ECD\u3ECE\u3ECF\u3ED0\u3ED1"+ + "\u3ED2\u3ED3\u3ED4\u3ED5\u3ED6\u3ED7\u3ED8\u3ED9"+ + "\u3EDA\u3EDB\u3EDC\u3EDD\u3EDE\u3EDF\u3EE0\u3EE1"; + + private static final String innerEncoderIndex2= + "\u3EE2\u3EE3\u3EE4\u3EE5\u3EE6\u3EE7\u3EE8\u3EE9"+ + "\u3EEA\u3EEB\u3EEC\u3EED\u3EEE\u3EEF\u3EF0\u3EF1"+ + "\uA95C\u3EF2\u3EF3\uA843\uA1AA\uA844\uA1AC\u3EF4"+ + "\uA1AE\uA1AF\u3EF5\u3EF6\uA1B0\uA1B1\u3EF7\u3EF8"+ + "\u3EF9\u3EFA\u3EFB\u3EFC\u3EFD\uA845\uA1AD\u3EFE"+ + "\u3EFF\u3F00\u3F01\u3F02\u3F03\u3F04\u3F05\u3F06"+ + "\uA1EB\u3F07\uA1E4\uA1E5\u3F08\uA846\u3F09\u3F0A"+ + "\u3F0B\u3F0C\u3F0D\uA1F9\u3F0E\u3F0F\u3F10\u3F11"+ + "\u3F12\u3F13\u3F14\u3F15\u3F16\u3F17\u3F18\u3F19"+ + "\u3F1A\u3F1B\u3F1C\u3F1D\u3F1E\u3F1F\u3F20\u3F21"+ + "\u3F22\u3F23\u3F24\u3F25\u3F26\u3F27\u3F28\u3F29"+ + "\u3F2A\u3F2B\u3F2C\u3F2D\u3F2E\u3F2F\u3F30\u3F31"+ + "\u3F32\u3F33\u3F34\u3F35\u3F36\u3F37\u3F38\u3F39"+ + "\u3F3A\u3F3B\u3F3C\u3F3D\u3F3E\u3F3F\u3F40\u3F41"+ + "\u3F42\u3F43\u3F44\u3F45\u3F46\u3F47\u3F48\u3F49"+ + "\u3F4A\u3F4B\u3F4C\u3F4D\u3F4E\u3F4F\u3F50\u3F51"+ + "\u3F52\u3F53\u3F54\u3F55\u3F56\u3F57\u3F58\u3F59"+ + "\u3F5A\u3F5B\u3F5C\u3F5D\u3F5E\u3F5F\u3F60\u3F61"+ + "\u3F62\u3F63\u3F64\u3F65\u3F66\u3F67\u3F68\u3F69"+ + "\u3F6A\u3F6B\u3F6C\u3F6D\u3F6E\u3F6F\u3F70\u3F71"+ + "\u3F72\u3F73\u3F74\u3F75\u3F76\u3F77\u3F78\u3F79"+ + "\u3F7A\u3F7B\u3F7C\u3F7D\uA2E3\u3F7E\u3F7F\u3F80"+ + "\u3F81\u3F82\u3F83\u3F84\u3F85\u3F86\u3F87\u3F88"+ + "\u3F89\u3F8A\u3F8B\u3F8C\u3F8D\u3F8E\u3F8F\u3F90"+ + "\u3F91\u3F92\u3F93\u3F94\u3F95\u3F96\u3F97\u3F98"+ + "\u3F99\u3F9A\u3F9B\u3F9C\u3F9D\u3F9E\u3F9F\u3FA0"+ + "\u3FA1\u3FA2\u3FA3\u3FA4\u3FA5\u3FA6\u3FA7\u3FA8"+ + "\u3FA9\u3FAA\u3FAB\u3FAC\u3FAD\u3FAE\u3FAF\u3FB0"+ + "\u3FB1\u3FB2\u3FB3\u3FB4\u3FB5\u3FB6\u3FB7\u3FB8"+ + "\u3FB9\u3FBA\u3FBB\u3FBC\u3FBD\u3FBE\u3FBF\u3FC0"+ + "\u3FC1\u3FC2\u3FC3\u3FC4\u3FC5\u3FC6\u3FC7\u3FC8"+ + "\u3FC9\u3FCA\u3FCB\u3FCC\u3FCD\u3FCE\u3FCF\u3FD0"+ + "\u3FD1\u3FD2\u3FD3\uA1E6\u3FD4\uA847\u3FD5\u3FD6"+ + "\u3FD7\uA848\u3FD8\u3FD9\u3FDA\u3FDB\u3FDC\u3FDD"+ + "\u3FDE\u3FDF\u3FE0\u3FE1\u3FE2\u3FE3\uA1ED\u3FE4"+ + "\u3FE5\u3FE6\u3FE7\u3FE8\u3FE9\u3FEA\u3FEB\u3FEC"+ + "\u3FED\uA959\u3FEE\u3FEF\u3FF0\u3FF1\u3FF2\u3FF3"+ + "\u3FF4\u3FF5\u3FF6\u3FF7\u3FF8\u3FF9\u3FFA\u3FFB"+ + "\u3FFC\u3FFD\u3FFE\u3FFF\u4000\u4001\u4002\u4003"+ + "\u4004\u4005\u4006\u4007\u4008\u4009\u400A\u400B"+ + "\u400C\u400D\u400E\u400F\u4010\u4011\u4012\u4013"+ + "\u4014\u4015\u4016\u4017\u4018\u4019\u401A\u401B"+ + "\u401C\u401D\u401E\u401F\u4020\u4021\u4022\u4023"+ + "\u4024\u4025\u4026\u4027\u4028\u4029\u402A\u402B"+ + "\uA2F1\uA2F2\uA2F3\uA2F4\uA2F5\uA2F6\uA2F7\uA2F8"+ + "\uA2F9\uA2FA\uA2FB\uA2FC\u402C\u402D\u402E\u402F"+ + "\uA2A1\uA2A2\uA2A3\uA2A4\uA2A5\uA2A6\uA2A7\uA2A8"+ + "\uA2A9\uA2AA\u4030\u4031\u4032\u4033\u4034\u4035"+ + "\u4036\u4037\u4038\u4039\u403A\u403B\u403C\u403D"+ + "\u403E\u403F\u4040\u4041\u4042\u4043\u4044\u4045"+ + "\uA1FB\uA1FC\uA1FA\uA1FD\u4046\u4047\uA849\uA84A"+ + "\uA84B\uA84C\u4048\u4049\u404A\u404B\u404C\u404D"+ + "\u404E\u404F\u4050\u4051\u4052\u4053\u4054\u4055"+ + "\u4056\u4057\u4058\u4059\u405A\u405B\u405C\u405D"+ + "\u405E\u405F\u4060\u4061\u4062\u4063\u4064\u4065"+ + "\u4066\u4067\u4068\u4069\u406A\u406B\u406C\u406D"+ + "\u406E\u406F\u4070\u4071\u4072\u4073\u4074\u4075"+ + "\u4076\u4077\u4078\u4079\u407A\u407B\u407C\u407D"+ + "\u407E\u407F\u4080\u4081\u4082\u4083\u4084\u4085"+ + "\u4086\u4087\u4088\u4089\u408A\u408B\u408C\u408D"+ + "\u408E\u408F\u4090\u4091\u4092\u4093\u4094\u4095"+ + "\u4096\u4097\u4098\u4099\u409A\u409B\u409C\u409D"+ + "\u409E\u409F\u40A0\u40A1\u40A2\u40A3\u40A4\u40A5"+ + "\u40A6\u40A7\u40A8\u40A9\u40AA\u40AB\u40AC\u40AD"+ + "\u40AE\u40AF\u40B0\u40B1\u40B2\u40B3\u40B4\u40B5"+ + "\uA1CA\u40B6\u40B7\u40B8\u40B9\u40BA\u40BB\uA1C7"+ + "\u40BC\uA1C6\u40BD\u40BE\u40BF\uA84D\u40C0\u40C1"+ + "\u40C2\u40C3\uA1CC\u40C4\u40C5\uA1D8\uA1DE\uA84E"+ + "\uA1CF\u40C6\u40C7\uA84F\u40C8\uA1CE\u40C9\uA1C4"+ + "\uA1C5\uA1C9\uA1C8\uA1D2\u40CA\u40CB\uA1D3\u40CC"+ + "\u40CD\u40CE\u40CF\u40D0\uA1E0\uA1DF\uA1C3\uA1CB"+ + "\u40D1\u40D2\u40D3\u40D4\u40D5\uA1D7\u40D6\u40D7"+ + "\u40D8\u40D9\u40DA\u40DB\u40DC\u40DD\u40DE\u40DF"+ + "\uA1D6\u40E0\u40E1\u40E2\uA1D5\u40E3\u40E4\u40E5"+ + "\u40E6\u40E7\uA850\u40E8\u40E9\u40EA\u40EB\u40EC"+ + "\u40ED\u40EE\u40EF\u40F0\u40F1\u40F2\u40F3\u40F4"+ + "\uA1D9\uA1D4\u40F5\u40F6\uA1DC\uA1DD\uA851\uA852"+ + "\u40F7\u40F8\u40F9\u40FA\u40FB\u40FC\uA1DA\uA1DB"+ + "\u40FD\u40FE\u40FF\u4100\u4101\u4102\u4103\u4104"+ + "\u4105\u4106\u4107\u4108\u4109\u410A\u410B\u410C"+ + "\u410D\u410E\u410F\u4110\u4111\u4112\u4113\u4114"+ + "\u4115\u4116\u4117\u4118\u4119\u411A\u411B\u411C"+ + "\u411D\u411E\u411F\u4120\u4121\uA892\u4122\u4123"+ + "\u4124\uA1D1\u4125\u4126\u4127\u4128\u4129\u412A"+ + "\u412B\u412C\u412D\u412E\u412F\uA1CD\u4130\u4131"+ + "\u4132\u4133\u4134\u4135\u4136\u4137\u4138\u4139"+ + "\u413A\u413B\u413C\u413D\u413E\u413F\u4140\u4141"+ + "\u4142\u4143\u4144\u4145\u4146\u4147\u4148\uA853"+ + "\u4149\u414A\u414B\u414C\u414D\u414E\u414F\u4150"+ + "\u4151\u4152\u4153\u4154\u4155\u4156\u4157\u4158"+ + "\u4159\u415A\u415B\u415C\u415D\u415E\u415F\u4160"+ + "\u4161\u4162\u4163\u4164\u4165\u4166\u4167\u4168"+ + "\u4169\u416A\u416B\u416C\u416D\u416E\u416F\u4170"+ + "\u4171\u4172\u4173\u4174\u4175\u4176\u4177\u4178"+ + "\u4179\u417A\u417B\u417C\u417D\u417E\u417F\u4180"+ + "\u4181\u4182\u4183\u4184\u4185\u4186\u4187\u4188"+ + "\u4189\u418A\u418B\u418C\u418D\u418E\u418F\u4190"+ + "\u4191\u4192\u4193\u4194\u4195\u4196\u4197\u4198"+ + "\u4199\u419A\uA1D0\u419B\u419C\u419D\u419E\u419F"+ + "\u41A0\u41A1\u41A2\u41A3\u41A4\u41A5\u41A6\u41A7"+ + "\u41A8\u41A9\u41AA\u41AB\u41AC\u41AD\u41AE\u41AF"+ + "\u41B0\u41B1\u41B2\u41B3\u41B4\u41B5\u41B6\u41B7"+ + "\u41B8\u41B9\u41BA\u41BB\u41BC\u41BD\u41BE\u41BF"+ + "\u41C0\u41C1\u41C2\u41C3\u41C4\u41C5\u41C6\u41C7"+ + "\u41C8\u41C9\u41CA\u41CB\u41CC\u41CD\u41CE\u41CF"+ + "\u41D0\u41D1\u41D2\u41D3\u41D4\u41D5\u41D6\u41D7"+ + "\u41D8\u41D9\u41DA\u41DB\u41DC\u41DD\u41DE\u41DF"+ + "\u41E0\u41E1\u41E2\u41E3\u41E4\u41E5\u41E6\u41E7"+ + "\u41E8\u41E9\u41EA\u41EB\u41EC\u41ED\u41EE\u41EF"+ + "\u41F0\u41F1\u41F2\u41F3\u41F4\u41F5\u41F6\u41F7"+ + "\u41F8\u41F9\u41FA\u41FB\u41FC\u41FD\u41FE\u41FF"+ + "\u4200\u4201\u4202\u4203\u4204\u4205\u4206\u4207"+ + "\u4208\u4209\u420A\u420B\u420C\u420D\u420E\u420F"+ + "\u4210\u4211\u4212\u4213\u4214\u4215\u4216\u4217"+ + "\u4218\u4219\u421A\u421B\u421C\u421D\u421E\u421F"+ + "\u4220\u4221\u4222\u4223\u4224\u4225\u4226\u4227"+ + "\u4228\u4229\u422A\u422B\u422C\u422D\u422E\u422F"+ + "\u4230\u4231\u4232\u4233\u4234\u4235\u4236\u4237"+ + "\u4238\u4239\u423A\u423B\u423C\u423D\u423E\u423F"+ + "\u4240\u4241\u4242\u4243\u4244\u4245\u4246\u4247"+ + "\u4248\u4249\u424A\u424B\u424C\u424D\u424E\u424F"+ + "\u4250\u4251\u4252\u4253\u4254\u4255\u4256\u4257"+ + "\u4258\u4259\u425A\u425B\u425C\u425D\u425E\u425F"+ + "\u4260\u4261\u4262\u4263\u4264\u4265\u4266\u4267"+ + "\u4268\u4269\u426A\u426B\u426C\u426D\u426E\u426F"+ + "\u4270\u4271\u4272\u4273\u4274\u4275\u4276\u4277"+ + "\u4278\u4279\u427A\u427B\u427C\u427D\u427E\u427F"+ + "\u4280\u4281\u4282\u4283\u4284\u4285\u4286\u4287"+ + "\u4288\u4289\u428A\u428B\u428C\u428D\u428E\u428F"+ + "\u4290\u4291\u4292\u4293\u4294\u4295\u4296\u4297"+ + "\u4298\u4299\u429A\u429B\u429C\u429D\u429E\u429F"+ + "\u42A0\u42A1\u42A2\u42A3\u42A4\u42A5\u42A6\u42A7"+ + "\u42A8\u42A9\u42AA\u42AB\u42AC\u42AD\u42AE\u42AF"+ + "\u42B0\u42B1\u42B2\u42B3\u42B4\u42B5\u42B6\u42B7"+ + "\u42B8\u42B9\u42BA\u42BB\u42BC\u42BD\u42BE\u42BF"+ + "\u42C0\u42C1\u42C2\u42C3\u42C4\u42C5\u42C6\u42C7"+ + "\u42C8\u42C9\u42CA\u42CB\u42CC\u42CD\u42CE\u42CF"+ + "\u42D0\u42D1\u42D2\u42D3\u42D4\u42D5\u42D6\u42D7"+ + "\u42D8\u42D9\u42DA\u42DB\u42DC\u42DD\u42DE\u42DF"+ + "\u42E0\u42E1\u42E2\u42E3\u42E4\u42E5\u42E6\u42E7"+ + "\uA2D9\uA2DA\uA2DB\uA2DC\uA2DD\uA2DE\uA2DF\uA2E0"+ + "\uA2E1\uA2E2\u42E8\u42E9\u42EA\u42EB\u42EC\u42ED"+ + "\u42EE\u42EF\u42F0\u42F1\uA2C5\uA2C6\uA2C7\uA2C8"+ + "\uA2C9\uA2CA\uA2CB\uA2CC\uA2CD\uA2CE\uA2CF\uA2D0"+ + "\uA2D1\uA2D2\uA2D3\uA2D4\uA2D5\uA2D6\uA2D7\uA2D8"+ + "\uA2B1\uA2B2\uA2B3\uA2B4\uA2B5\uA2B6\uA2B7\uA2B8"+ + "\uA2B9\uA2BA\uA2BB\uA2BC\uA2BD\uA2BE\uA2BF\uA2C0"+ + "\uA2C1\uA2C2\uA2C3\uA2C4\u42F2\u42F3\u42F4\u42F5"+ + "\u42F6\u42F7\u42F8\u42F9\u42FA\u42FB\u42FC\u42FD"+ + "\u42FE\u42FF\u4300\u4301\u4302\u4303\u4304\u4305"+ + "\u4306\u4307\u4308\u4309\u430A\u430B\u430C\u430D"+ + "\u430E\u430F\u4310\u4311\u4312\u4313\u4314\u4315"+ + "\u4316\u4317\u4318\u4319\u431A\u431B\u431C\u431D"+ + "\u431E\u431F\u4320\u4321\u4322\u4323\u4324\u4325"+ + "\u4326\u4327\u4328\u4329\u432A\u432B\u432C\u432D"+ + "\u432E\u432F\u4330\u4331\u4332\u4333\u4334\u4335"+ + "\u4336\u4337\u4338\u4339\u433A\u433B\u433C\u433D"+ + "\u433E\u433F\u4340\u4341\u4342\u4343\u4344\u4345"+ + "\u4346\u4347\u4348\u4349\u434A\u434B\u434C\u434D"+ + "\u434E\u434F\u4350\u4351\u4352\u4353\u4354\u4355"+ + "\uA9A4\uA9A5\uA9A6\uA9A7\uA9A8\uA9A9\uA9AA\uA9AB"+ + "\uA9AC\uA9AD\uA9AE\uA9AF\uA9B0\uA9B1\uA9B2\uA9B3"+ + "\uA9B4\uA9B5\uA9B6\uA9B7\uA9B8\uA9B9\uA9BA\uA9BB"+ + "\uA9BC\uA9BD\uA9BE\uA9BF\uA9C0\uA9C1\uA9C2\uA9C3"+ + "\uA9C4\uA9C5\uA9C6\uA9C7\uA9C8\uA9C9\uA9CA\uA9CB"+ + "\uA9CC\uA9CD\uA9CE\uA9CF\uA9D0\uA9D1\uA9D2\uA9D3"+ + "\uA9D4\uA9D5\uA9D6\uA9D7\uA9D8\uA9D9\uA9DA\uA9DB"+ + "\uA9DC\uA9DD\uA9DE\uA9DF\uA9E0\uA9E1\uA9E2\uA9E3"+ + "\uA9E4\uA9E5\uA9E6\uA9E7\uA9E8\uA9E9\uA9EA\uA9EB"+ + "\uA9EC\uA9ED\uA9EE\uA9EF\u4356\u4357\u4358\u4359"+ + "\uA854\uA855\uA856\uA857\uA858\uA859\uA85A\uA85B"+ + "\uA85C\uA85D\uA85E\uA85F\uA860\uA861\uA862\uA863"+ + "\uA864\uA865\uA866\uA867\uA868\uA869\uA86A\uA86B"+ + "\uA86C\uA86D\uA86E\uA86F\uA870\uA871\uA872\uA873"+ + "\uA874\uA875\uA876\uA877\u435A\u435B\u435C\u435D"+ + "\u435E\u435F\u4360\u4361\u4362\u4363\u4364\u4365"+ + "\u4366\uA878\uA879\uA87A\uA87B\uA87C\uA87D\uA87E"+ + "\uA880\uA881\uA882\uA883\uA884\uA885\uA886\uA887"+ + "\u4367\u4368\u4369\uA888\uA889\uA88A\u436A\u436B"+ + "\u436C\u436D\u436E\u436F\u4370\u4371\u4372\u4373"+ + "\uA1F6\uA1F5\u4374\u4375\u4376\u4377\u4378\u4379"+ + "\u437A\u437B\u437C\u437D\u437E\u437F\u4380\u4381"+ + "\u4382\u4383\uA1F8\uA1F7\u4384\u4385\u4386\u4387"+ + "\u4388\u4389\u438A\u438B\uA88B\uA88C\u438C\u438D"+ + "\u438E\u438F\u4390\u4391\u4392\u4393\uA1F4\uA1F3"+ + "\u4394\u4395\u4396\uA1F0\u4397\u4398\uA1F2\uA1F1"+ + "\u4399\u439A\u439B\u439C\u439D\u439E\u439F\u43A0"+ + "\u43A1\u43A2\u43A3\u43A4\u43A5\u43A6\u43A7\u43A8"+ + "\u43A9\u43AA\uA88D\uA88E\uA88F\uA890\u43AB\u43AC"+ + "\u43AD\u43AE\u43AF\u43B0\u43B1\u43B2\u43B3\u43B4"+ + "\u43B5\u43B6\u43B7\u43B8\u43B9\u43BA\u43BB\u43BC"+ + "\u43BD\u43BE\u43BF\u43C0\u43C1\u43C2\u43C3\u43C4"+ + "\u43C5\u43C6\u43C7\u43C8\u43C9\uA1EF\uA1EE\u43CA"+ + "\u43CB\uA891\u43CC\u43CD\u43CE\u43CF\u43D0\u43D1"+ + "\u43D2\u43D3\u43D4\u43D5\u43D6\u43D7\u43D8\u43D9"+ + "\u43DA\u43DB\u43DC\u43DD\u43DE\u43DF\u43E0\u43E1"+ + "\u43E2\u43E3\u43E4\u43E5\u43E6\u43E7\u43E8\u43E9"+ + "\u43EA\u43EB\u43EC\u43ED\u43EE\u43EF\u43F0\u43F1"+ + "\u43F2\u43F3\u43F4\u43F5\u43F6\u43F7\u43F8\u43F9"+ + "\u43FA\u43FB\u43FC\u43FD\u43FE\u43FF\u4400\u4401"+ + "\uA1E2\u4402\uA1E1\u4403\u4404\u4405\u4406\u4407"+ + "\u4408\u4409\u440A\u440B\u440C\u440D\u440E\u440F"+ + "\u4410\u4411\u4412\u4413\u4414\u4415\u4416\u4417"+ + "\u4418\u4419\u441A\u441B\u441C\u441D\u441E\u441F"+ + "\u4420\u4421\u4422\u4423\u4424\u4425\u4426\u4427"+ + "\u4428\u4429\u442A\u442B\u442C\u442D\u442E\u442F"+ + "\u4430\u4431\u4432\u4433\u4434\u4435\u4436\u4437"+ + "\u4438\u4439\u443A\u443B\u443C\u443D\u443E\u443F"+ + "\u4440\u4441\u4442\u4443\u4444\u4445\u4446\u4447"+ + "\u4448\u4449\u444A\u444B\u444C\u444D\u444E\u444F"+ + "\u4450\u4451\u4452\u4453\u4454\u4455\u4456\u4457"+ + "\u4458\u4459\u445A\u445B\u445C\u445D\u445E\u445F"+ + "\u4460\u4461\u4462\u4463\u4464\u4465\u4466\u4467"+ + "\u4468\u4469\u446A\u446B\u446C\u446D\u446E\u446F"+ + "\u4470\u4471\u4472\u4473\u4474\u4475\u4476\u4477"+ + "\u4478\u4479\u447A\u447B\u447C\u447D\u447E\u447F"+ + "\u4480\u4481\u4482\u4483\u4484\u4485\u4486\u4487"+ + "\u4488\u4489\u448A\u448B\u448C\u448D\u448E\u448F"+ + "\u4490\u4491\u4492\u4493\u4494\u4495\u4496\u4497"+ + "\u4498\u4499\u449A\u449B\u449C\u449D\u449E\u449F"+ + "\u44A0\u44A1\u44A2\u44A3\u44A4\u44A5\u44A6\u44A7"+ + "\u44A8\u44A9\u44AA\u44AB\u44AC\u44AD\u44AE\u44AF"+ + "\u44B0\u44B1\u44B2\u44B3\u44B4\u44B5\u44B6\u44B7"+ + "\u44B8\u44B9\u44BA\u44BB\u44BC\u44BD\u44BE\u44BF"+ + "\u44C0\u44C1\u44C2\u44C3\u44C4\u44C5\u44C6\u44C7"+ + "\u44C8\u44C9\u44CA\u44CB\u44CC\u44CD\u44CE\u44CF"+ + "\u44D0\u44D1\u44D2\u44D3\u44D4\u44D5\u44D6\u44D7"+ + "\u44D8\u44D9\u44DA\u44DB\u44DC\u44DD\u44DE\u44DF"+ + "\u44E0\u44E1\u44E2\u44E3\u44E4\u44E5\u44E6\u44E7"+ + "\u44E8\u44E9\u44EA\u44EB\u44EC\u44ED\u44EE\u44EF"+ + "\u44F0\u44F1\u44F2\u44F3\u44F4\u44F5\u44F6\u44F7"+ + "\u44F8\u44F9\u44FA\u44FB\u44FC\u44FD\u44FE\u44FF"+ + "\u4500\u4501\u4502\u4503\u4504\u4505\u4506\u4507"+ + "\u4508\u4509\u450A\u450B\u450C\u450D\u450E\u450F"+ + "\u4510\u4511\u4512\u4513\u4514\u4515\u4516\u4517"+ + "\u4518\u4519\u451A\u451B\u451C\u451D\u451E\u451F"+ + "\u4520\u4521\u4522\u4523\u4524\u4525\u4526\u4527"+ + "\u4528\u4529\u452A\u452B\u452C\u452D\u452E\u452F"+ + "\u4530\u4531\u4532\u4533\u4534\u4535\u4536\u4537"+ + "\u4538\u4539\u453A\u453B\u453C\u453D\u453E\u453F"+ + "\u4540\u4541\u4542\u4543\u4544\u4545\u4546\u4547"+ + "\u4548\u4549\u454A\u454B\u454C\u454D\u454E\u454F"+ + "\u4550\u4551\u4552\u4553\u4554\u4555\u4556\u4557"+ + "\u4558\u4559\u455A\u455B\u455C\u455D\u455E\u455F"+ + "\u4560\u4561\u4562\u4563\u4564\u4565\u4566\u4567"+ + "\u4568\u4569\u456A\u456B\u456C\u456D\u456E\u456F"+ + "\u4570\u4571\u4572\u4573\u4574\u4575\u4576\u4577"+ + "\u4578\u4579\u457A\u457B\u457C\u457D\u457E\u457F"+ + "\u4580\u4581\u4582\u4583\u4584\u4585\u4586\u4587"+ + "\u4588\u4589\u458A\u458B\u458C\u458D\u458E\u458F"+ + "\u4590\u4591\u4592\u4593\u4594\u4595\u4596\u4597"+ + "\u4598\u4599\u459A\u459B\u459C\u459D\u459E\u459F"+ + "\u45A0\u45A1\u45A2\u45A3\u45A4\u45A5\u45A6\u45A7"+ + "\u45A8\u45A9\u45AA\u45AB\u45AC\u45AD\u45AE\u45AF"+ + "\u45B0\u45B1\u45B2\u45B3\u45B4\u45B5\u45B6\u45B7"+ + "\u45B8\u45B9\u45BA\u45BB\u45BC\u45BD\u45BE\u45BF"+ + "\u45C0\u45C1\u45C2\u45C3\u45C4\u45C5\u45C6\u45C7"+ + "\u45C8\u45C9\u45CA\u45CB\u45CC\u45CD\u45CE\u45CF"+ + "\u45D0\u45D1\u45D2\u45D3\u45D4\u45D5\u45D6\u45D7"+ + "\u45D8\u45D9\u45DA\u45DB\u45DC\u45DD\u45DE\u45DF"+ + "\u45E0\u45E1\u45E2\u45E3\u45E4\u45E5\u45E6\u45E7"+ + "\u45E8\u45E9\u45EA\u45EB\u45EC\u45ED\u45EE\u45EF"+ + "\u45F0\u45F1\u45F2\u45F3\u45F4\u45F5\u45F6\u45F7"+ + "\u45F8\u45F9\u45FA\u45FB\u45FC\u45FD\u45FE\u45FF"+ + "\u4600\u4601\u4602\u4603\u4604\u4605\u4606\u4607"+ + "\u4608\u4609\u460A\u460B\u460C\u460D\u460E\u460F"+ + "\u4610\u4611\u4612\u4613\u4614\u4615\u4616\u4617"+ + "\u4618\u4619\u461A\u461B\u461C\u461D\u461E\u461F"+ + "\u4620\u4621\u4622\u4623\u4624\u4625\u4626\u4627"+ + "\u4628\u4629\u462A\u462B\u462C\u462D\u462E\u462F"+ + "\u4630\u4631\u4632\u4633\u4634\u4635\u4636\u4637"+ + "\u4638\u4639\u463A\u463B\u463C\u463D\u463E\u463F"+ + "\u4640\u4641\u4642\u4643\u4644\u4645\u4646\u4647"+ + "\u4648\u4649\u464A\u464B\u464C\u464D\u464E\u464F"+ + "\u4650\u4651\u4652\u4653\u4654\u4655\u4656\u4657"+ + "\u4658\u4659\u465A\u465B\u465C\u465D\u465E\u465F"+ + "\u4660\u4661\u4662\u4663\u4664\u4665\u4666\u4667"+ + "\u4668\u4669\u466A\u466B\u466C\u466D\u466E\u466F"+ + "\u4670\u4671\u4672\u4673\u4674\u4675\u4676\u4677"+ + "\u4678\u4679\u467A\u467B\u467C\u467D\u467E\u467F"+ + "\u4680\u4681\u4682\u4683\u4684\u4685\u4686\u4687"+ + "\u4688\u4689\u468A\u468B\u468C\u468D\u468E\u468F"+ + "\u4690\u4691\u4692\u4693\u4694\u4695\u4696\u4697"+ + "\u4698\u4699\u469A\u469B\u469C\u469D\u469E\u469F"+ + "\u46A0\u46A1\u46A2\u46A3\u46A4\u46A5\u46A6\u46A7"+ + "\u46A8\u46A9\u46AA\u46AB\u46AC\u46AD\u46AE\u46AF"+ + "\u46B0\u46B1\u46B2\u46B3\u46B4\u46B5\u46B6\u46B7"+ + "\u46B8\u46B9\u46BA\u46BB\u46BC\u46BD\u46BE\u46BF"+ + "\u46C0\u46C1\u46C2\u46C3\u46C4\u46C5\u46C6\u46C7"+ + "\u46C8\u46C9\u46CA\u46CB\u46CC\u46CD\u46CE\u46CF"+ + "\u46D0\u46D1\u46D2\u46D3\u46D4\u46D5\u46D6\u46D7"+ + "\u46D8\u46D9\u46DA\u46DB\u46DC\u46DD\u46DE\u46DF"+ + "\u46E0\u46E1\u46E2\u46E3\u46E4\u46E5\u46E6\u46E7"+ + "\u46E8\u46E9\u46EA\u46EB\u46EC\u46ED\u46EE\u46EF"+ + "\u46F0\u46F1\u46F2\u46F3\u46F4\u46F5\u46F6\u46F7"+ + "\u46F8\u46F9\u46FA\u46FB\u46FC\u46FD\u46FE\u46FF"+ + "\u4700\u4701\u4702\u4703\u4704\u4705\u4706\u4707"+ + "\u4708\u4709\u470A\u470B\u470C\u470D\u470E\u470F"+ + "\u4710\u4711\u4712\u4713\u4714\u4715\u4716\u4717"+ + "\u4718\u4719\u471A\u471B\u471C\u471D\u471E\u471F"+ + "\u4720\u4721\u4722\u4723\u4724\u4725\u4726\u4727"+ + "\u4728\u4729\u472A\u472B\u472C\u472D\u472E\u472F"+ + "\u4730\u4731\u4732\u4733\u4734\u4735\u4736\u4737"+ + "\u4738\u4739\u473A\u473B\u473C\u473D\u473E\u473F"+ + "\u4740\u4741\u4742\u4743\u4744\u4745\u4746\u4747"+ + "\u4748\u4749\u474A\u474B\u474C\u474D\u474E\u474F"+ + "\u4750\u4751\u4752\u4753\u4754\u4755\u4756\u4757"+ + "\u4758\u4759\u475A\u475B\u475C\u475D\u475E\u475F"+ + "\u4760\u4761\u4762\u4763\u4764\u4765\u4766\u4767"+ + "\u4768\u4769\u476A\u476B\u476C\u476D\u476E\u476F"+ + "\u4770\u4771\u4772\u4773\u4774\u4775\u4776\u4777"+ + "\u4778\u4779\u477A\u477B\u477C\u477D\u477E\u477F"+ + "\u4780\u4781\u4782\u4783\u4784\u4785\u4786\u4787"+ + "\u4788\u4789\u478A\u478B\u478C\u478D\u478E\u478F"+ + "\u4790\u4791\u4792\u4793\u4794\u4795\u4796\u4797"+ + "\u4798\u4799\u479A\u479B\u479C\u479D\u479E\u479F"+ + "\u47A0\u47A1\u47A2\u47A3\u47A4\u47A5\u47A6\u47A7"+ + "\u47A8\u47A9\u47AA\u47AB\u47AC\u47AD\u47AE\u47AF"+ + "\u47B0\u47B1\u47B2\u47B3\u47B4\u47B5\u47B6\u47B7"+ + "\u47B8\u47B9\u47BA\u47BB\u47BC\u47BD\u47BE\u47BF"+ + "\u47C0\u47C1\u47C2\u47C3\u47C4\u47C5\u47C6\u47C7"+ + "\u47C8\u47C9\u47CA\u47CB\u47CC\u47CD\u47CE\u47CF"+ + "\u47D0\u47D1\u47D2\u47D3\u47D4\u47D5\u47D6\u47D7"+ + "\u47D8\u47D9\u47DA\u47DB\u47DC\u47DD\u47DE\u47DF"+ + "\u47E0\u47E1\u47E2\u47E3\u47E4\u47E5\u47E6\u47E7"+ + "\u47E8\u47E9\u47EA\u47EB\u47EC\u47ED\u47EE\u47EF"+ + "\u47F0\u47F1\u47F2\u47F3\u47F4\u47F5\u47F6\u47F7"+ + "\u47F8\u47F9\u47FA\u47FB\u47FC\u47FD\u47FE\u47FF"+ + "\u4800\u4801\u4802\u4803\u4804\u4805\u4806\u4807"+ + "\u4808\u4809\u480A\u480B\u480C\u480D\u480E\u480F"+ + "\u4810\u4811\u4812\u4813\u4814\u4815\u4816\u4817"+ + "\u4818\u4819\u481A\u481B\u481C\u481D\u481E\u481F"+ + "\u4820\u4821\u4822\u4823\u4824\u4825\u4826\u4827"+ + "\u4828\u4829\u482A\u482B\u482C\u482D\u482E\u482F"+ + "\u4830\u4831\u4832\u4833\u4834\u4835\u4836\u4837"+ + "\u4838\u4839\u483A\u483B\u483C\u483D\u483E\u483F"+ + "\u4840\u4841\u4842\u4843\u4844\u4845\u4846\u4847"+ + "\u4848\u4849\u484A\u484B\u484C\u484D\u484E\u484F"+ + "\u4850\u4851\u4852\u4853\u4854\u4855\u4856\u4857"+ + "\u4858\u4859\u485A\u485B\u485C\u485D\u485E\u485F"+ + "\u4860\u4861\u4862\u4863\u4864\u4865\u4866\u4867"+ + "\u4868\u4869\u486A\u486B\u486C\u486D\u486E\u486F"+ + "\u4870\u4871\u4872\u4873\u4874\u4875\u4876\u4877"+ + "\u4878\u4879\u487A\u487B\u487C\u487D\u487E\u487F"+ + "\u4880\u4881\u4882\u4883\u4884\u4885\u4886\u4887"+ + "\u4888\u4889\u488A\u488B\u488C\u488D\u488E\u488F"+ + "\u4890\u4891\u4892\u4893\u4894\u4895\u4896\u4897"+ + "\u4898\u4899\u489A\u489B\u489C\u489D\u489E\u489F"+ + "\u48A0\u48A1\u48A2\u48A3\u48A4\u48A5\u48A6\u48A7"+ + "\u48A8\u48A9\u48AA\u48AB\u48AC\u48AD\u48AE\u48AF"+ + "\u48B0\u48B1\u48B2\u48B3\u48B4\u48B5\u48B6\u48B7"+ + "\u48B8\u48B9\u48BA\u48BB\u48BC\u48BD\u48BE\u48BF"+ + "\u48C0\u48C1\u48C2\u48C3\u48C4\u48C5\u48C6\u48C7"+ + "\u48C8\u48C9\u48CA\u48CB\u48CC\u48CD\u48CE\u48CF"+ + "\u48D0\u48D1\u48D2\u48D3\u48D4\u48D5\u48D6\u48D7"+ + "\u48D8\u48D9\u48DA\u48DB\u48DC\u48DD\u48DE\u48DF"+ + "\u48E0\u48E1\u48E2\u48E3\u48E4\u48E5\u48E6\u48E7"+ + "\u48E8\u48E9\u48EA\u48EB\u48EC\u48ED\u48EE\u48EF"+ + "\u48F0\u48F1\u48F2\u48F3\u48F4\u48F5\u48F6\u48F7"+ + "\u48F8\u48F9\u48FA\u48FB\u48FC\u48FD\u48FE\u48FF"+ + "\u4900\u4901\u4902\u4903\u4904\u4905\u4906\u4907"+ + "\u4908\u4909\u490A\u490B\u490C\u490D\u490E\u490F"+ + "\u4910\u4911\u4912\u4913\u4914\u4915\u4916\u4917"+ + "\u4918\u4919\u491A\u491B\u491C\u491D\u491E\u491F"+ + "\u4920\u4921\u4922\u4923\u4924\u4925\u4926\u4927"+ + "\u4928\u4929\u492A\u492B\u492C\u492D\u492E\u492F"+ + "\u4930\u4931\u4932\u4933\u4934\u4935\u4936\u4937"+ + "\u4938\u4939\u493A\u493B\u493C\u493D\u493E\u493F"+ + "\u4940\u4941\u4942\u4943\u4944\u4945\u4946\u4947"+ + "\u4948\u4949\u494A\u494B\u494C\u494D\u494E\u494F"+ + "\u4950\u4951\u4952\u4953\u4954\u4955\u4956\u4957"+ + "\u4958\u4959\u495A\u495B\u495C\u495D\u495E\u495F"+ + "\u4960\u4961\u4962\u4963\u4964\u4965\u4966\u4967"+ + "\u4968\u4969\u496A\u496B\u496C\u496D\u496E\u496F"+ + "\u4970\u4971\u4972\u4973\u4974\u4975\u4976\u4977"+ + "\u4978\u4979\u497A\u497B\u497C\u497D\u497E\u497F"+ + "\u4980\u4981\u4982\u4983\u4984\u4985\u4986\u4987"+ + "\u4988\u4989\u498A\u498B\u498C\u498D\u498E\u498F"+ + "\u4990\u4991\u4992\u4993\u4994\u4995\u4996\u4997"+ + "\u4998\u4999\u499A\u499B\u499C\u499D\u499E\u499F"+ + "\u49A0\u49A1\u49A2\u49A3\u49A4\u49A5\u49A6\u49A7"+ + "\u49A8\u49A9\u49AA\u49AB\u49AC\u49AD\u49AE\u49AF"+ + "\u49B0\u49B1\u49B2\u49B3\u49B4\u49B5\u49B6\u49B7"+ + "\u49B8\u49B9\u49BA\u49BB\u49BC\u49BD\u49BE\u49BF"+ + "\u49C0\u49C1\u49C2\u49C3\u49C4\u49C5\u49C6\u49C7"+ + "\u49C8\u49C9\u49CA\u49CB\u49CC\u49CD\u49CE\u49CF"+ + "\u49D0\u49D1\u49D2\u49D3\u49D4\u49D5\u49D6\u49D7"+ + "\u49D8\u49D9\u49DA\u49DB\u49DC\u49DD\u49DE\u49DF"+ + "\u49E0\u49E1\u49E2\u49E3\u49E4\u49E5\u49E6\u49E7"+ + "\u49E8\u49E9\u49EA\u49EB\u49EC\u49ED\u49EE\u49EF"+ + "\u49F0\u49F1\u49F2\u49F3\u49F4\u49F5\u49F6\u49F7"+ + "\u49F8\u49F9\u49FA\u49FB\u49FC\u49FD\u49FE\u49FF"+ + "\u4A00\u4A01\u4A02\u4A03\u4A04\u4A05\u4A06\u4A07"+ + "\u4A08\u4A09\u4A0A\u4A0B\u4A0C\u4A0D\u4A0E\u4A0F"+ + "\u4A10\u4A11\u4A12\u4A13\u4A14\u4A15\u4A16\u4A17"+ + "\u4A18\u4A19\u4A1A\u4A1B\u4A1C\u4A1D\u4A1E\u4A1F"+ + "\u4A20\u4A21\u4A22\u4A23\u4A24\u4A25\u4A26\u4A27"+ + "\u4A28\u4A29\u4A2A\u4A2B\u4A2C\u4A2D\u4A2E\u4A2F"+ + "\u4A30\u4A31\u4A32\u4A33\u4A34\u4A35\u4A36\u4A37"+ + "\u4A38\u4A39\u4A3A\u4A3B\u4A3C\u4A3D\u4A3E\u4A3F"+ + "\u4A40\u4A41\u4A42\u4A43\u4A44\u4A45\u4A46\u4A47"+ + "\u4A48\u4A49\u4A4A\u4A4B\u4A4C\u4A4D\u4A4E\u4A4F"+ + "\u4A50\u4A51\u4A52\u4A53\u4A54\u4A55\u4A56\u4A57"+ + "\u4A58\u4A59\u4A5A\u4A5B\u4A5C\u4A5D\u4A5E\u4A5F"+ + "\u4A60\u4A61\u4A62\u4A63\u4A64\u4A65\u4A66\u4A67"+ + "\u4A68\u4A69\u4A6A\u4A6B\u4A6C\u4A6D\u4A6E\u4A6F"+ + "\u4A70\u4A71\u4A72\u4A73\u4A74\u4A75\u4A76\u4A77"+ + "\u4A78\u4A79\u4A7A\u4A7B\u4A7C\u4A7D\u4A7E\u4A7F"+ + "\u4A80\u4A81\u4A82\u4A83\u4A84\u4A85\u4A86\u4A87"+ + "\u4A88\u4A89\u4A8A\u4A8B\u4A8C\u4A8D\u4A8E\u4A8F"+ + "\u4A90\u4A91\u4A92\u4A93\u4A94\u4A95\u4A96\u4A97"+ + "\u4A98\u4A99\u4A9A\u4A9B\u4A9C\u4A9D\u4A9E\u4A9F"+ + "\u4AA0\u4AA1\u4AA2\u4AA3\u4AA4\u4AA5\u4AA6\u4AA7"+ + "\u4AA8\u4AA9\u4AAA\u4AAB\u4AAC\u4AAD\u4AAE\u4AAF"+ + "\u4AB0\u4AB1\u4AB2\u4AB3\u4AB4\u4AB5\u4AB6\u4AB7"+ + "\u4AB8\u4AB9\u4ABA\u4ABB\u4ABC\u4ABD\u4ABE\u4ABF"+ + "\u4AC0\u4AC1\u4AC2\u4AC3\u4AC4\u4AC5\u4AC6\u4AC7"+ + "\u4AC8\u4AC9\u4ACA\u4ACB\u4ACC\u4ACD\u4ACE\u4ACF"+ + "\u4AD0\u4AD1\u4AD2\u4AD3\u4AD4\u4AD5\u4AD6\u4AD7"+ + "\u4AD8\u4AD9\u4ADA\u4ADB\u4ADC\u4ADD\u4ADE\u4ADF"+ + "\u4AE0\u4AE1\u4AE2\u4AE3\u4AE4\u4AE5\u4AE6\u4AE7"+ + "\u4AE8\u4AE9\u4AEA\u4AEB\u4AEC\u4AED\u4AEE\u4AEF"+ + "\u4AF0\u4AF1\u4AF2\u4AF3\u4AF4\u4AF5\u4AF6\u4AF7"+ + "\u4AF8\u4AF9\u4AFA\u4AFB\u4AFC\u4AFD\u4AFE\u4AFF"+ + "\u4B00\u4B01\u4B02\u4B03\u4B04\u4B05\u4B06\u4B07"+ + "\u4B08\u4B09\u4B0A\u4B0B\u4B0C\u4B0D\u4B0E\u4B0F"+ + "\u4B10\u4B11\u4B12\u4B13\u4B14\u4B15\u4B16\u4B17"+ + "\u4B18\u4B19\u4B1A\u4B1B\u4B1C\u4B1D\u4B1E\u4B1F"+ + "\u4B20\u4B21\u4B22\u4B23\u4B24\u4B25\u4B26\u4B27"+ + "\u4B28\u4B29\u4B2A\u4B2B\u4B2C\u4B2D\u4B2E\u4B2F"+ + "\u4B30\u4B31\u4B32\u4B33\u4B34\u4B35\u4B36\u4B37"+ + "\u4B38\u4B39\u4B3A\u4B3B\u4B3C\u4B3D\u4B3E\u4B3F"+ + "\u4B40\u4B41\u4B42\u4B43\u4B44\u4B45\u4B46\u4B47"+ + "\u4B48\u4B49\u4B4A\u4B4B\u4B4C\u4B4D\u4B4E\u4B4F"+ + "\u4B50\u4B51\u4B52\u4B53\u4B54\u4B55\u4B56\u4B57"+ + "\u4B58\u4B59\u4B5A\u4B5B\u4B5C\u4B5D\u4B5E\u4B5F"+ + "\u4B60\u4B61\u4B62\u4B63\u4B64\u4B65\u4B66\u4B67"+ + "\u4B68\u4B69\u4B6A\u4B6B\u4B6C\u4B6D\u4B6E\u4B6F"+ + "\u4B70\u4B71\u4B72\u4B73\u4B74\u4B75\u4B76\u4B77"+ + "\u4B78\u4B79\u4B7A\u4B7B\u4B7C\u4B7D\u4B7E\u4B7F"+ + "\u4B80\u4B81\u4B82\u4B83\u4B84\u4B85\u4B86\u4B87"+ + "\u4B88\u4B89\u4B8A\u4B8B\u4B8C\u4B8D\u4B8E\u4B8F"+ + "\u4B90\u4B91\u4B92\u4B93\u4B94\u4B95\u4B96\u4B97"+ + "\u4B98\u4B99\u4B9A\u4B9B\u4B9C\u4B9D\u4B9E\u4B9F"+ + "\u4BA0\u4BA1\u4BA2\u4BA3\u4BA4\u4BA5\u4BA6\u4BA7"+ + "\u4BA8\u4BA9\u4BAA\u4BAB\u4BAC\u4BAD\u4BAE\u4BAF"+ + "\u4BB0\u4BB1\u4BB2\u4BB3\u4BB4\u4BB5\u4BB6\u4BB7"+ + "\u4BB8\u4BB9\u4BBA\u4BBB\u4BBC\u4BBD\u4BBE\u4BBF"+ + "\u4BC0\u4BC1\u4BC2\u4BC3\u4BC4\u4BC5\u4BC6\u4BC7"+ + "\u4BC8\u4BC9\u4BCA\u4BCB\u4BCC\u4BCD\u4BCE\u4BCF"+ + "\u4BD0\u4BD1\u4BD2\u4BD3\u4BD4\u4BD5\u4BD6\u4BD7"+ + "\u4BD8\u4BD9\u4BDA\u4BDB\u4BDC\u4BDD\u4BDE\u4BDF"+ + "\u4BE0\u4BE1\u4BE2\u4BE3\u4BE4\u4BE5\u4BE6\u4BE7"+ + "\u4BE8\u4BE9\u4BEA\u4BEB\u4BEC\u4BED\u4BEE\u4BEF"+ + "\u4BF0\u4BF1\u4BF2\u4BF3\u4BF4\u4BF5\u4BF6\u4BF7"+ + "\u4BF8\u4BF9\u4BFA\u4BFB\u4BFC\u4BFD\u4BFE\u4BFF"+ + "\u4C00\u4C01\u4C02\u4C03\u4C04\u4C05\u4C06\u4C07"+ + "\u4C08\u4C09\u4C0A\u4C0B\u4C0C\u4C0D\u4C0E\u4C0F"+ + "\u4C10\u4C11\u4C12\u4C13\u4C14\u4C15\u4C16\u4C17"+ + "\u4C18\u4C19\u4C1A\u4C1B\u4C1C\u4C1D\u4C1E\u4C1F"+ + "\u4C20\u4C21\u4C22\u4C23\u4C24\u4C25\u4C26\u4C27"+ + "\u4C28\u4C29\u4C2A\u4C2B\u4C2C\u4C2D\u4C2E\u4C2F"+ + "\u4C30\u4C31\u4C32\u4C33\u4C34\u4C35\u4C36\u4C37"+ + "\u4C38\u4C39\u4C3A\u4C3B\u4C3C\u4C3D\u4C3E\u4C3F"+ + "\u4C40\uFE50\u4C41\u4C42\uFE54\u4C43\u4C44\u4C45"+ + "\uFE57\u4C46\u4C47\uFE58\uFE5D\u4C48\u4C49\u4C4A"+ + "\u4C4B\u4C4C\u4C4D\u4C4E\u4C4F\u4C50\u4C51\uFE5E"+ + "\u4C52\u4C53\u4C54\u4C55\u4C56\u4C57\u4C58\u4C59"+ + "\u4C5A\u4C5B\u4C5C\u4C5D\u4C5E\u4C5F\u4C60\uFE6B"+ + "\u4C61\u4C62\uFE6E\u4C63\u4C64\u4C65\uFE71\u4C66"+ + "\u4C67\u4C68\u4C69\uFE73\u4C6A\u4C6B\uFE74\uFE75"+ + "\u4C6C\u4C6D\u4C6E\uFE79\u4C6F\u4C70\u4C71\u4C72"+ + "\u4C73\u4C74\u4C75\u4C76\u4C77\u4C78\u4C79\u4C7A"+ + "\u4C7B\u4C7C\uFE84\u4C7D\u4C7E\u4C7F\u4C80\u4C81"+ + "\u4C82\u4C83\u4C84\u4C85\u4C86\u4C87\u4C88\u4C89"+ + "\u4C8A\u4C8B\u4C8C\u4C8D\u4C8E\u4C8F\u4C90\u4C91"+ + "\u4C92\u4C93\u4C94\u4C95\u4C96\u4C97\u4C98\u4C99"+ + "\u4C9A\u4C9B\u4C9C\u4C9D\u4C9E\u4C9F\u4CA0\u4CA1"+ + "\u4CA2\u4CA3\u4CA4\u4CA5\u4CA6\u4CA7\u4CA8\u4CA9"+ + "\u4CAA\u4CAB\u4CAC\u4CAD\u4CAE\u4CAF\u4CB0\u4CB1"+ + "\u4CB2\u4CB3\u4CB4\u4CB5\u4CB6\u4CB7\u4CB8\u4CB9"+ + "\u4CBA\u4CBB\u4CBC\u4CBD\u4CBE\u4CBF\u4CC0\u4CC1"+ + "\u4CC2\u4CC3\u4CC4\u4CC5\u4CC6\u4CC7\u4CC8\u4CC9"+ + "\u4CCA\u4CCB\u4CCC\u4CCD\u4CCE\u4CCF\u4CD0\u4CD1"+ + "\u4CD2\u4CD3\u4CD4\u4CD5\u4CD6\u4CD7\u4CD8\u4CD9"+ + "\u4CDA\u4CDB\u4CDC\u4CDD\u4CDE\u4CDF\u4CE0\u4CE1"+ + "\u4CE2\u4CE3\u4CE4\u4CE5\u4CE6\u4CE7\u4CE8\u4CE9"+ + "\u4CEA\u4CEB\u4CEC\u4CED\u4CEE\u4CEF\u4CF0\u4CF1"+ + "\u4CF2\u4CF3\u4CF4\u4CF5\u4CF6\u4CF7\u4CF8\u4CF9"+ + "\u4CFA\u4CFB\u4CFC\u4CFD\u4CFE\u4CFF\u4D00\u4D01"+ + "\u4D02\u4D03\u4D04\u4D05\u4D06\u4D07\u4D08\u4D09"+ + "\u4D0A\u4D0B\u4D0C\u4D0D\u4D0E\u4D0F\u4D10\u4D11"+ + "\u4D12\u4D13\u4D14\u4D15\u4D16\u4D17\u4D18\u4D19"+ + "\u4D1A\u4D1B\u4D1C\u4D1D\u4D1E\u4D1F\u4D20\u4D21"+ + "\u4D22\u4D23\u4D24\u4D25\u4D26\u4D27\u4D28\u4D29"+ + "\u4D2A\u4D2B\u4D2C\u4D2D\u4D2E\u4D2F\u4D30\u4D31"+ + "\u4D32\u4D33\u4D34\u4D35\u4D36\u4D37\u4D38\u4D39"+ + "\u4D3A\u4D3B\u4D3C\u4D3D\u4D3E\u4D3F\u4D40\u4D41"+ + "\u4D42\u4D43\u4D44\u4D45\u4D46\u4D47\u4D48\u4D49"+ + "\u4D4A\u4D4B\u4D4C\u4D4D\u4D4E\u4D4F\u4D50\u4D51"+ + "\u4D52\u4D53\u4D54\u4D55\u4D56\u4D57\u4D58\u4D59"+ + "\u4D5A\u4D5B\u4D5C\u4D5D\u4D5E\u4D5F\u4D60\u4D61"+ + "\u4D62\u4D63\u4D64\u4D65\u4D66\u4D67\u4D68\u4D69"+ + "\u4D6A\u4D6B\u4D6C\u4D6D\u4D6E\u4D6F\u4D70\u4D71"+ + "\u4D72\u4D73\u4D74\u4D75\u4D76\u4D77\u4D78\u4D79"+ + "\u4D7A\u4D7B\u4D7C\u4D7D\u4D7E\u4D7F\u4D80\u4D81"+ + "\u4D82\u4D83\u4D84\u4D85\u4D86\u4D87\u4D88\u4D89"+ + "\u4D8A\u4D8B\u4D8C\u4D8D\u4D8E\u4D8F\u4D90\u4D91"+ + "\u4D92\u4D93\u4D94\u4D95\u4D96\u4D97\u4D98\u4D99"+ + "\u4D9A\u4D9B\u4D9C\u4D9D\u4D9E\u4D9F\u4DA0\u4DA1"+ + "\uA98A\uA98B\uA98C\uA98D\uA98E\uA98F\uA990\uA991"+ + "\uA992\uA993\uA994\uA995\u4DA2\u4DA3\u4DA4\u4DA5"; + + private static final String innerEncoderIndex3= + "\uA1A1\uA1A2\uA1A3\uA1A8\u4DA6\uA1A9\uA965\uA996"+ + "\uA1B4\uA1B5\uA1B6\uA1B7\uA1B8\uA1B9\uA1BA\uA1BB"+ + "\uA1BE\uA1BF\uA893\uA1FE\uA1B2\uA1B3\uA1BC\uA1BD"+ + "\u4DA7\u4DA8\u4DA9\u4DAA\u4DAB\uA894\uA895\u4DAC"+ + "\u4DAD\uA940\uA941\uA942\uA943\uA944\uA945\uA946"+ + "\uA947\uA948\u4DAE\u4DAF\u4DB0\u4DB1\u4DB2\u4DB3"+ + "\u4DB4\u4DB5\u4DB6\u4DB7\u4DB8\u4DB9\u4DBA\u4DBB"+ + "\u4DBC\u4DBD\u4DBE\u4DBF\u4DC0\u4DC1\uA989\u4DC2"+ + "\u4DC3\uA4A1\uA4A2\uA4A3\uA4A4\uA4A5\uA4A6\uA4A7"+ + "\uA4A8\uA4A9\uA4AA\uA4AB\uA4AC\uA4AD\uA4AE\uA4AF"+ + "\uA4B0\uA4B1\uA4B2\uA4B3\uA4B4\uA4B5\uA4B6\uA4B7"+ + "\uA4B8\uA4B9\uA4BA\uA4BB\uA4BC\uA4BD\uA4BE\uA4BF"+ + "\uA4C0\uA4C1\uA4C2\uA4C3\uA4C4\uA4C5\uA4C6\uA4C7"+ + "\uA4C8\uA4C9\uA4CA\uA4CB\uA4CC\uA4CD\uA4CE\uA4CF"+ + "\uA4D0\uA4D1\uA4D2\uA4D3\uA4D4\uA4D5\uA4D6\uA4D7"+ + "\uA4D8\uA4D9\uA4DA\uA4DB\uA4DC\uA4DD\uA4DE\uA4DF"+ + "\uA4E0\uA4E1\uA4E2\uA4E3\uA4E4\uA4E5\uA4E6\uA4E7"+ + "\uA4E8\uA4E9\uA4EA\uA4EB\uA4EC\uA4ED\uA4EE\uA4EF"+ + "\uA4F0\uA4F1\uA4F2\uA4F3\u4DC4\u4DC5\u4DC6\u4DC7"+ + "\u4DC8\u4DC9\u4DCA\uA961\uA962\uA966\uA967\u4DCB"+ + "\u4DCC\uA5A1\uA5A2\uA5A3\uA5A4\uA5A5\uA5A6\uA5A7"+ + "\uA5A8\uA5A9\uA5AA\uA5AB\uA5AC\uA5AD\uA5AE\uA5AF"+ + "\uA5B0\uA5B1\uA5B2\uA5B3\uA5B4\uA5B5\uA5B6\uA5B7"+ + "\uA5B8\uA5B9\uA5BA\uA5BB\uA5BC\uA5BD\uA5BE\uA5BF"+ + "\uA5C0\uA5C1\uA5C2\uA5C3\uA5C4\uA5C5\uA5C6\uA5C7"+ + "\uA5C8\uA5C9\uA5CA\uA5CB\uA5CC\uA5CD\uA5CE\uA5CF"+ + "\uA5D0\uA5D1\uA5D2\uA5D3\uA5D4\uA5D5\uA5D6\uA5D7"+ + "\uA5D8\uA5D9\uA5DA\uA5DB\uA5DC\uA5DD\uA5DE\uA5DF"+ + "\uA5E0\uA5E1\uA5E2\uA5E3\uA5E4\uA5E5\uA5E6\uA5E7"+ + "\uA5E8\uA5E9\uA5EA\uA5EB\uA5EC\uA5ED\uA5EE\uA5EF"+ + "\uA5F0\uA5F1\uA5F2\uA5F3\uA5F4\uA5F5\uA5F6\u4DCD"+ + "\u4DCE\u4DCF\u4DD0\u4DD1\uA960\uA963\uA964\u4DD2"+ + "\u4DD3\u4DD4\u4DD5\u4DD6\u4DD7\uA8C5\uA8C6\uA8C7"+ + "\uA8C8\uA8C9\uA8CA\uA8CB\uA8CC\uA8CD\uA8CE\uA8CF"+ + "\uA8D0\uA8D1\uA8D2\uA8D3\uA8D4\uA8D5\uA8D6\uA8D7"+ + "\uA8D8\uA8D9\uA8DA\uA8DB\uA8DC\uA8DD\uA8DE\uA8DF"+ + "\uA8E0\uA8E1\uA8E2\uA8E3\uA8E4\uA8E5\uA8E6\uA8E7"+ + "\uA8E8\uA8E9\u4DD8\u4DD9\u4DDA\u4DDB\u4DDC\u4DDD"+ + "\u4DDE\u4DDF\u4DE0\u4DE1\u4DE2\u4DE3\u4DE4\u4DE5"+ + "\u4DE6\u4DE7\u4DE8\u4DE9\u4DEA\u4DEB\u4DEC\u4DED"+ + "\u4DEE\u4DEF\u4DF0\u4DF1\u4DF2\u4DF3\u4DF4\u4DF5"+ + "\u4DF6\u4DF7\u4DF8\u4DF9\u4DFA\u4DFB\u4DFC\u4DFD"+ + "\u4DFE\u4DFF\u4E00\u4E01\u4E02\u4E03\u4E04\u4E05"+ + "\u4E06\u4E07\u4E08\u4E09\u4E0A\u4E0B\u4E0C\u4E0D"+ + "\u4E0E\u4E0F\u4E10\u4E11\u4E12\u4E13\u4E14\u4E15"+ + "\u4E16\u4E17\u4E18\u4E19\u4E1A\u4E1B\u4E1C\u4E1D"+ + "\u4E1E\u4E1F\u4E20\u4E21\u4E22\u4E23\u4E24\u4E25"+ + "\u4E26\u4E27\u4E28\u4E29\u4E2A\u4E2B\u4E2C\u4E2D"+ + "\u4E2E\u4E2F\u4E30\u4E31\u4E32\u4E33\u4E34\u4E35"+ + "\u4E36\u4E37\u4E38\u4E39\u4E3A\u4E3B\u4E3C\u4E3D"+ + "\u4E3E\u4E3F\u4E40\u4E41\u4E42\u4E43\u4E44\u4E45"+ + "\u4E46\u4E47\u4E48\u4E49\u4E4A\u4E4B\u4E4C\u4E4D"+ + "\u4E4E\u4E4F\u4E50\u4E51\u4E52\u4E53\u4E54\u4E55"+ + "\u4E56\u4E57\u4E58\u4E59\u4E5A\u4E5B\u4E5C\u4E5D"+ + "\u4E5E\u4E5F\u4E60\u4E61\u4E62\u4E63\u4E64\u4E65"+ + "\u4E66\u4E67\u4E68\u4E69\u4E6A\u4E6B\u4E6C\u4E6D"+ + "\u4E6E\u4E6F\u4E70\u4E71\u4E72\u4E73\u4E74\u4E75"+ + "\u4E76\u4E77\u4E78\u4E79\u4E7A\u4E7B\u4E7C\u4E7D"+ + "\u4E7E\u4E7F\u4E80\u4E81\u4E82\u4E83\u4E84\u4E85"+ + "\u4E86\u4E87\u4E88\u4E89\u4E8A\u4E8B\u4E8C\u4E8D"+ + "\u4E8E\u4E8F\u4E90\u4E91\u4E92\u4E93\u4E94\u4E95"+ + "\u4E96\u4E97\u4E98\u4E99\u4E9A\u4E9B\u4E9C\u4E9D"+ + "\u4E9E\u4E9F\u4EA0\u4EA1\u4EA2\u4EA3\u4EA4\u4EA5"+ + "\u4EA6\u4EA7\u4EA8\u4EA9\u4EAA\u4EAB\u4EAC\u4EAD"+ + "\u4EAE\u4EAF\u4EB0\u4EB1\u4EB2\u4EB3\u4EB4\u4EB5"+ + "\u4EB6\u4EB7\u4EB8\u4EB9\u4EBA\u4EBB\u4EBC\u4EBD"+ + "\u4EBE\u4EBF\u4EC0\u4EC1\u4EC2\u4EC3\u4EC4\u4EC5"+ + "\u4EC6\u4EC7\u4EC8\u4EC9\u4ECA\u4ECB\u4ECC\u4ECD"+ + "\uA2E5\uA2E6\uA2E7\uA2E8\uA2E9\uA2EA\uA2EB\uA2EC"+ + "\uA2ED\uA2EE\u4ECE\u4ECF\u4ED0\u4ED1\u4ED2\u4ED3"+ + "\u4ED4\uA95A\u4ED5\u4ED6\u4ED7\u4ED8\u4ED9\u4EDA"+ + "\u4EDB\u4EDC\u4EDD\u4EDE\u4EDF\u4EE0\u4EE1\u4EE2"+ + "\u4EE3\u4EE4\u4EE5\u4EE6\u4EE7\u4EE8\u4EE9\u4EEA"+ + "\u4EEB\u4EEC\u4EED\u4EEE\u4EEF\u4EF0\u4EF1\u4EF2"+ + "\u4EF3\u4EF4\u4EF5\u4EF6\u4EF7\u4EF8\u4EF9\u4EFA"+ + "\u4EFB\u4EFC\u4EFD\u4EFE\u4EFF\u4F00\u4F01\u4F02"+ + "\u4F03\u4F04\u4F05\u4F06\u4F07\u4F08\u4F09\u4F0A"+ + "\u4F0B\u4F0C\u4F0D\u4F0E\u4F0F\u4F10\u4F11\u4F12"+ + "\u4F13\u4F14\u4F15\u4F16\u4F17\u4F18\u4F19\u4F1A"+ + "\u4F1B\u4F1C\u4F1D\u4F1E\u4F1F\u4F20\u4F21\u4F22"+ + "\u4F23\u4F24\u4F25\u4F26\u4F27\u4F28\u4F29\u4F2A"+ + "\u4F2B\u4F2C\u4F2D\u4F2E\u4F2F\u4F30\u4F31\u4F32"+ + "\u4F33\u4F34\u4F35\u4F36\u4F37\u4F38\u4F39\u4F3A"+ + "\u4F3B\u4F3C\u4F3D\u4F3E\u4F3F\u4F40\u4F41\u4F42"+ + "\u4F43\u4F44\u4F45\uA949\u4F46\u4F47\u4F48\u4F49"+ + "\u4F4A\u4F4B\u4F4C\u4F4D\u4F4E\u4F4F\u4F50\u4F51"+ + "\u4F52\u4F53\u4F54\u4F55\u4F56\u4F57\u4F58\u4F59"+ + "\u4F5A\u4F5B\u4F5C\u4F5D\u4F5E\u4F5F\u4F60\u4F61"+ + "\u4F62\u4F63\u4F64\u4F65\u4F66\u4F67\u4F68\u4F69"+ + "\u4F6A\u4F6B\u4F6C\u4F6D\u4F6E\u4F6F\u4F70\u4F71"+ + "\u4F72\u4F73\u4F74\u4F75\u4F76\u4F77\u4F78\u4F79"+ + "\u4F7A\u4F7B\u4F7C\u4F7D\u4F7E\u4F7F\u4F80\u4F81"+ + "\u4F82\u4F83\u4F84\u4F85\u4F86\u4F87\u4F88\u4F89"+ + "\u4F8A\u4F8B\u4F8C\u4F8D\u4F8E\u4F8F\u4F90\u4F91"+ + "\u4F92\u4F93\u4F94\u4F95\u4F96\u4F97\u4F98\u4F99"+ + "\u4F9A\u4F9B\u4F9C\u4F9D\u4F9E\u4F9F\u4FA0\u4FA1"+ + "\u4FA2\u4FA3\u4FA4\u4FA5\u4FA6\u4FA7\u4FA8\u4FA9"+ + "\u4FAA\u4FAB\u4FAC\u4FAD\u4FAE\u4FAF\u4FB0\u4FB1"+ + "\u4FB2\u4FB3\u4FB4\u4FB5\u4FB6\u4FB7\u4FB8\u4FB9"+ + "\u4FBA\u4FBB\u4FBC\u4FBD\u4FBE\u4FBF\u4FC0\u4FC1"+ + "\u4FC2\u4FC3\u4FC4\u4FC5\u4FC6\u4FC7\u4FC8\u4FC9"+ + "\u4FCA\u4FCB\u4FCC\u4FCD\u4FCE\u4FCF\u4FD0\u4FD1"+ + "\u4FD2\u4FD3\u4FD4\u4FD5\u4FD6\u4FD7\u4FD8\u4FD9"+ + "\u4FDA\u4FDB\u4FDC\u4FDD\u4FDE\u4FDF\u4FE0\u4FE1"+ + "\u4FE2\u4FE3\u4FE4\u4FE5\u4FE6\u4FE7\u4FE8\u4FE9"+ + "\u4FEA\u4FEB\u4FEC\u4FED\u4FEE\u4FEF\u4FF0\u4FF1"+ + "\u4FF2\u4FF3\u4FF4\u4FF5\u4FF6\u4FF7\u4FF8\u4FF9"+ + "\u4FFA\u4FFB\u4FFC\u4FFD\u4FFE\u4FFF\u5000\u5001"+ + "\u5002\u5003\u5004\u5005\u5006\u5007\u5008\u5009"+ + "\u500A\u500B\u500C\u500D\u500E\u500F\u5010\u5011"+ + "\u5012\u5013\u5014\u5015\u5016\u5017\u5018\u5019"+ + "\u501A\u501B\u501C\u501D\u501E\u501F\u5020\u5021"+ + "\u5022\u5023\u5024\u5025\u5026\u5027\u5028\u5029"+ + "\u502A\u502B\u502C\u502D\u502E\u502F\uA94A\uA94B"+ + "\u5030\u5031\u5032\u5033\u5034\u5035\u5036\u5037"+ + "\u5038\u5039\u503A\u503B\uA94C\uA94D\uA94E\u503C"+ + "\u503D\uA94F\u503E\u503F\u5040\u5041\u5042\u5043"+ + "\u5044\u5045\u5046\u5047\u5048\u5049\u504A\u504B"+ + "\u504C\u504D\u504E\u504F\u5050\u5051\u5052\u5053"+ + "\u5054\u5055\u5056\u5057\u5058\u5059\u505A\u505B"+ + "\u505C\u505D\u505E\u505F\uA950\u5060\u5061\u5062"+ + "\u5063\u5064\u5065\u5066\u5067\u5068\uA951\u5069"+ + "\u506A\uA952\uA953\u506B\u506C\uA954\u506D\u506E"+ + "\u506F\u5070\u5071\u5072\u5073\u5074\u5075\u5076"+ + "\u5077\u5078\u5079\u507A\u507B\u507C\u507D\u507E"+ + "\u507F\u5080\u5081\u5082\u5083\u5084\u5085\u5086"+ + "\u5087\u5088\u5089\u508A\u508B\u508C\u508D\u508E"+ + "\u508F\u5090\u5091\u5092\u5093\u5094\u5095\u5096"+ + "\u5097\u5098\u5099\u509A\u509B\u509C\u509D\u509E"+ + "\u509F\u50A0\u50A1\u50A2\u50A3\u50A4\u50A5\u50A6"+ + "\u50A7\u50A8\u50A9\u50AA\u50AB\u50AC\u50AD\u50AE"+ + "\u50AF\u50B0\u50B1\u50B2\u50B3\u50B4\u50B5\u50B6"+ + "\u50B7\u50B8\u50B9\u50BA\u50BB\u50BC\u50BD\u50BE"+ + "\u50BF\u50C0\u50C1\u50C2\u50C3\u50C4\u50C5\u50C6"+ + "\u50C7\u50C8\u50C9\u50CA\u50CB\u50CC\u50CD\u50CE"+ + "\u50CF\u50D0\u50D1\u50D2\u50D3\u50D4\u50D5\u50D6"+ + "\u50D7\u50D8\u50D9\u50DA\u50DB\u50DC\u50DD\uFE56"+ + "\u50DE\u50DF\u50E0\u50E1\u50E2\u50E3\u50E4\u50E5"+ + "\u50E6\u50E7\u50E8\u50E9\u50EA\u50EB\u50EC\u50ED"+ + "\u50EE\u50EF\u50F0\u50F1\u50F2\u50F3\u50F4\u50F5"+ + "\u50F6\u50F7\u50F8\u50F9\u50FA\u50FB\u50FC\u50FD"+ + "\u50FE\u50FF\u5100\u5101\u5102\u5103\u5104\u5105"+ + "\u5106\u5107\u5108\uFE55\u5109\u510A\u510B\u510C"+ + "\u510D\u510E\u510F\u5110\u5111\u5112\u5113\u5114"+ + "\u5115\u5116\u5117\u5118\u5119\u511A\u511B\u511C"+ + "\u511D\u511E\u511F\u5120\u5121\u5122\u5123\u5124"+ + "\u5125\u5126\u5127\u5128\u5129\u512A\u512B\u512C"+ + "\u512D\u512E\u512F\u5130\u5131\u5132\u5133\u5134"+ + "\u5135\u5136\u5137\u5138\u5139\u513A\u513B\u513C"+ + "\u513D\u513E\u513F\u5140\u5141\u5142\u5143\u5144"+ + "\u5145\u5146\u5147\u5148\u5149\u514A\u514B\u514C"+ + "\u514D\u514E\u514F\u5150\u5151\u5152\u5153\u5154"+ + "\u5155\u5156\u5157\u5158\u5159\u515A\u515B\u515C"+ + "\u515D\u515E\u515F\u5160\u5161\u5162\u5163\u5164"+ + "\u5165\u5166\u5167\u5168\u5169\u516A\u516B\u516C"+ + "\u516D\u516E\u516F\u5170\u5171\u5172\u5173\u5174"+ + "\u5175\u5176\u5177\u5178\u5179\u517A\u517B\u517C"+ + "\u517D\u517E\u517F\u5180\u5181\u5182\u5183\u5184"+ + "\u5185\u5186\u5187\u5188\u5189\u518A\u518B\u518C"+ + "\u518D\u518E\u518F\u5190\u5191\u5192\u5193\u5194"+ + "\u5195\u5196\u5197\u5198\u5199\u519A\u519B\u519C"+ + "\u519D\u519E\u519F\u51A0\u51A1\u51A2\u51A3\u51A4"+ + "\u51A5\u51A6\u51A7\u51A8\u51A9\u51AA\u51AB\u51AC"+ + "\u51AD\u51AE\u51AF\u51B0\u51B1\u51B2\u51B3\u51B4"+ + "\u51B5\u51B6\u51B7\u51B8\u51B9\u51BA\u51BB\u51BC"+ + "\u51BD\u51BE\u51BF\u51C0\u51C1\u51C2\u51C3\u51C4"+ + "\u51C5\u51C6\u51C7\u51C8\u51C9\u51CA\u51CB\u51CC"+ + "\u51CD\u51CE\u51CF\u51D0\u51D1\u51D2\u51D3\u51D4"+ + "\u51D5\u51D6\u51D7\u51D8\u51D9\u51DA\u51DB\u51DC"+ + "\u51DD\u51DE\u51DF\u51E0\u51E1\u51E2\u51E3\u51E4"+ + "\u51E5\u51E6\u51E7\u51E8\u51E9\u51EA\u51EB\u51EC"+ + "\u51ED\u51EE\u51EF\u51F0\u51F1\u51F2\u51F3\u51F4"+ + "\u51F5\u51F6\u51F7\u51F8\u51F9\u51FA\u51FB\u51FC"+ + "\u51FD\u51FE\u51FF\u5200\u5201\u5202\u5203\u5204"+ + "\u5205\u5206\u5207\u5208\u5209\u520A\u520B\u520C"+ + "\u520D\u520E\u520F\u5210\u5211\u5212\u5213\u5214"+ + "\u5215\u5216\u5217\u5218\u5219\u521A\u521B\u521C"+ + "\u521D\u521E\u521F\u5220\u5221\u5222\u5223\u5224"+ + "\u5225\u5226\u5227\u5228\u5229\u522A\u522B\u522C"+ + "\u522D\u522E\u522F\u5230\u5231\u5232\uFE5A\u5233"+ + "\u5234\u5235\u5236\u5237\u5238\u5239\u523A\u523B"+ + "\u523C\u523D\u523E\u523F\u5240\u5241\u5242\u5243"+ + "\u5244\u5245\u5246\u5247\u5248\u5249\u524A\u524B"+ + "\u524C\u524D\u524E\u524F\u5250\u5251\u5252\u5253"+ + "\u5254\u5255\u5256\u5257\u5258\u5259\u525A\u525B"+ + "\u525C\u525D\u525E\u525F\u5260\u5261\u5262\u5263"+ + "\u5264\u5265\u5266\u5267\u5268\u5269\u526A\u526B"+ + "\u526C\u526D\u526E\u526F\u5270\u5271\u5272\u5273"+ + "\u5274\u5275\u5276\u5277\u5278\u5279\u527A\u527B"+ + "\u527C\u527D\u527E\u527F\u5280\u5281\u5282\u5283"+ + "\u5284\u5285\u5286\u5287\u5288\u5289\u528A\u528B"+ + "\u528C\u528D\u528E\u528F\u5290\u5291\u5292\u5293"+ + "\u5294\u5295\u5296\u5297\u5298\u5299\u529A\u529B"+ + "\u529C\u529D\u529E\u529F\u52A0\u52A1\uFE5C\u52A2"+ + "\u52A3\u52A4\u52A5\u52A6\u52A7\u52A8\u52A9\u52AA"+ + "\u52AB\u52AC\uFE5B\u52AD\u52AE\u52AF\u52B0\u52B1"+ + "\u52B2\u52B3\u52B4\u52B5\u52B6\u52B7\u52B8\u52B9"+ + "\u52BA\u52BB\u52BC\u52BD\u52BE\u52BF\u52C0\u52C1"+ + "\u52C2\u52C3\u52C4\u52C5\u52C6\u52C7\u52C8\u52C9"+ + "\u52CA\u52CB\u52CC\u52CD\u52CE\u52CF\u52D0\u52D1"+ + "\u52D2\u52D3\u52D4\u52D5\u52D6\u52D7\u52D8\u52D9"+ + "\u52DA\u52DB\u52DC\u52DD\u52DE\u52DF\u52E0\u52E1"+ + "\u52E2\u52E3\u52E4\u52E5\u52E6\u52E7\u52E8\u52E9"+ + "\u52EA\u52EB\u52EC\u52ED\u52EE\u52EF\u52F0\u52F1"+ + "\u52F2\u52F3\u52F4\u52F5\u52F6\u52F7\u52F8\u52F9"+ + "\u52FA\u52FB\u52FC\u52FD\u52FE\u52FF\u5300\u5301"+ + "\u5302\u5303\u5304\u5305\u5306\u5307\u5308\u5309"+ + "\u530A\u530B\u530C\u530D\u530E\u530F\u5310\u5311"+ + "\u5312\u5313\u5314\u5315\u5316\u5317\u5318\u5319"+ + "\u531A\u531B\u531C\u531D\u531E\u531F\u5320\u5321"+ + "\u5322\u5323\u5324\u5325\u5326\u5327\u5328\u5329"+ + "\u532A\u532B\u532C\u532D\u532E\u532F\u5330\u5331"+ + "\u5332\u5333\u5334\u5335\u5336\u5337\u5338\u5339"+ + "\u533A\u533B\u533C\u533D\u533E\u533F\u5340\u5341"+ + "\u5342\u5343\u5344\u5345\u5346\u5347\u5348\u5349"+ + "\u534A\u534B\u534C\u534D\u534E\u534F\u5350\u5351"+ + "\u5352\u5353\u5354\u5355\u5356\u5357\u5358\u5359"+ + "\u535A\u535B\u535C\u535D\u535E\u535F\u5360\u5361"+ + "\u5362\u5363\u5364\u5365\u5366\u5367\u5368\u5369"+ + "\u536A\u536B\u536C\u536D\u536E\u536F\u5370\u5371"+ + "\u5372\u5373\u5374\u5375\u5376\u5377\u5378\u5379"+ + "\u537A\u537B\u537C\u537D\u537E\u537F\u5380\u5381"+ + "\u5382\u5383\u5384\u5385\u5386\u5387\u5388\u5389"+ + "\u538A\u538B\u538C\u538D\u538E\u538F\u5390\u5391"+ + "\u5392\u5393\u5394\u5395\u5396\u5397\u5398\u5399"+ + "\u539A\u539B\u539C\u539D\u539E\u539F\u53A0\u53A1"+ + "\u53A2\u53A3\u53A4\u53A5\u53A6\u53A7\u53A8\u53A9"+ + "\u53AA\u53AB\u53AC\u53AD\u53AE\u53AF\u53B0\u53B1"+ + "\u53B2\u53B3\u53B4\u53B5\u53B6\u53B7\u53B8\u53B9"+ + "\u53BA\u53BB\u53BC\u53BD\u53BE\u53BF\u53C0\u53C1"+ + "\u53C2\u53C3\u53C4\u53C5\u53C6\u53C7\u53C8\u53C9"+ + "\u53CA\u53CB\u53CC\u53CD\u53CE\u53CF\u53D0\u53D1"+ + "\u53D2\u53D3\u53D4\u53D5\u53D6\u53D7\u53D8\u53D9"+ + "\u53DA\u53DB\u53DC\u53DD\u53DE\u53DF\u53E0\u53E1"+ + "\u53E2\u53E3\u53E4\u53E5\u53E6\u53E7\u53E8\u53E9"+ + "\u53EA\u53EB\u53EC\u53ED\u53EE\u53EF\u53F0\u53F1"+ + "\u53F2\u53F3\u53F4\u53F5\u53F6\u53F7\u53F8\u53F9"+ + "\u53FA\u53FB\u53FC\u53FD\u53FE\u53FF\u5400\u5401"+ + "\u5402\u5403\u5404\u5405\u5406\u5407\u5408\u5409"+ + "\u540A\u540B\u540C\u540D\u540E\u540F\u5410\u5411"+ + "\u5412\u5413\u5414\u5415\u5416\u5417\u5418\u5419"+ + "\u541A\u541B\u541C\u541D\u541E\u541F\u5420\u5421"+ + "\u5422\u5423\u5424\u5425\u5426\u5427\u5428\u5429"+ + "\u542A\u542B\u542C\u542D\u542E\u542F\u5430\u5431"+ + "\u5432\u5433\u5434\u5435\u5436\u5437\u5438\u5439"+ + "\u543A\u543B\u543C\u543D\u543E\u543F\u5440\u5441"+ + "\u5442\u5443\u5444\u5445\u5446\u5447\u5448\u5449"+ + "\u544A\u544B\u544C\u544D\u544E\u544F\u5450\u5451"+ + "\u5452\u5453\u5454\u5455\u5456\u5457\u5458\u5459"+ + "\u545A\u545B\u545C\u545D\u545E\u545F\u5460\u5461"+ + "\u5462\u5463\u5464\u5465\u5466\u5467\u5468\u5469"+ + "\u546A\u546B\u546C\u546D\u546E\u546F\u5470\u5471"+ + "\u5472\u5473\u5474\u5475\u5476\u5477\u5478\u5479"+ + "\u547A\u547B\u547C\u547D\u547E\u547F\u5480\u5481"+ + "\u5482\u5483\u5484\u5485\u5486\u5487\u5488\u5489"+ + "\u548A\u548B\u548C\u548D\u548E\u548F\u5490\u5491"+ + "\u5492\u5493\u5494\u5495\u5496\u5497\u5498\u5499"+ + "\u549A\u549B\u549C\u549D\u549E\u549F\u54A0\u54A1"+ + "\u54A2\u54A3\u54A4\u54A5\u54A6\u54A7\u54A8\u54A9"+ + "\u54AA\u54AB\u54AC\u54AD\u54AE\u54AF\u54B0\u54B1"+ + "\u54B2\u54B3\u54B4\u54B5\u54B6\u54B7\u54B8\u54B9"+ + "\u54BA\u54BB\u54BC\u54BD\u54BE\u54BF\u54C0\u54C1"+ + "\u54C2\u54C3\u54C4\u54C5\u54C6\u54C7\u54C8\u54C9"+ + "\u54CA\u54CB\u54CC\u54CD\u54CE\u54CF\u54D0\u54D1"+ + "\u54D2\u54D3\u54D4\u54D5\u54D6\u54D7\u54D8\u54D9"+ + "\u54DA\u54DB\u54DC\u54DD\u54DE\u54DF\u54E0\u54E1"+ + "\u54E2\u54E3\u54E4\u54E5\u54E6\u54E7\u54E8\u54E9"+ + "\u54EA\u54EB\u54EC\u54ED\u54EE\u54EF\u54F0\u54F1"+ + "\u54F2\u54F3\u54F4\u54F5\u54F6\u54F7\u54F8\u54F9"+ + "\u54FA\u54FB\u54FC\u54FD\u54FE\u54FF\u5500\u5501"+ + "\u5502\u5503\u5504\u5505\u5506\u5507\u5508\u5509"+ + "\u550A\u550B\u550C\u550D\u550E\u550F\u5510\u5511"+ + "\u5512\u5513\u5514\u5515\u5516\u5517\u5518\u5519"+ + "\u551A\u551B\u551C\u551D\u551E\u551F\u5520\u5521"+ + "\u5522\u5523\u5524\u5525\u5526\u5527\u5528\u5529"+ + "\u552A\u552B\u552C\u552D\u552E\u552F\u5530\u5531"+ + "\u5532\u5533\u5534\u5535\u5536\u5537\u5538\u5539"+ + "\u553A\u553B\u553C\u553D\u553E\u553F\u5540\u5541"+ + "\u5542\u5543\u5544\u5545\u5546\u5547\u5548\u5549"+ + "\u554A\u554B\u554C\u554D\u554E\u554F\u5550\u5551"+ + "\u5552\u5553\u5554\u5555\u5556\u5557\u5558\u5559"+ + "\u555A\u555B\u555C\u555D\u555E\u555F\u5560\u5561"+ + "\u5562\u5563\u5564\u5565\u5566\u5567\u5568\u5569"+ + "\u556A\u556B\u556C\u556D\u556E\u556F\u5570\u5571"+ + "\u5572\u5573\u5574\u5575\u5576\u5577\u5578\u5579"+ + "\u557A\u557B\u557C\u557D\u557E\u557F\u5580\u5581"+ + "\u5582\u5583\u5584\u5585\u5586\u5587\u5588\u5589"+ + "\u558A\u558B\u558C\u558D\u558E\u558F\u5590\u5591"+ + "\u5592\u5593\u5594\u5595\u5596\u5597\u5598\u5599"+ + "\u559A\u559B\u559C\u559D\u559E\u559F\u55A0\u55A1"+ + "\u55A2\u55A3\u55A4\u55A5\u55A6\u55A7\u55A8\u55A9"+ + "\uFE60\u55AA\u55AB\u55AC\u55AD\u55AE\u55AF\u55B0"+ + "\u55B1\u55B2\u55B3\u55B4\u55B5\u55B6\u55B7\u55B8"+ + "\u55B9\u55BA\u55BB\u55BC\u55BD\u55BE\u55BF\u55C0"+ + "\u55C1\u55C2\u55C3\u55C4\u55C5\u55C6\u55C7\u55C8"+ + "\u55C9\u55CA\u55CB\u55CC\u55CD\u55CE\u55CF\u55D0"+ + "\u55D1\u55D2\u55D3\u55D4\u55D5\u55D6\u55D7\u55D8"+ + "\u55D9\u55DA\u55DB\u55DC\u55DD\u55DE\u55DF\u55E0"+ + "\u55E1\u55E2\u55E3\u55E4\u55E5\u55E6\u55E7\u55E8"+ + "\u55E9\u55EA\u55EB\u55EC\u55ED\u55EE\u55EF\u55F0"+ + "\u55F1\u55F2\u55F3\u55F4\u55F5\u55F6\u55F7\u55F8"+ + "\u55F9\u55FA\u55FB\u55FC\u55FD\u55FE\uFE5F\u55FF"+ + "\u5600\u5601\u5602\u5603\u5604\u5605\u5606\u5607"+ + "\u5608\u5609\u560A\u560B\u560C\u560D\u560E\u560F"+ + "\u5610\u5611\u5612\u5613\u5614\u5615\u5616\u5617"+ + "\u5618\u5619\u561A\u561B\u561C\u561D\u561E\u561F"+ + "\u5620\u5621\u5622\u5623\u5624\u5625\u5626\u5627"+ + "\u5628\u5629\u562A\u562B\u562C\u562D\u562E\u562F"+ + "\u5630\u5631\u5632\u5633\u5634\u5635\u5636\u5637"+ + "\u5638\u5639\u563A\u563B\u563C\u563D\u563E\u563F"+ + "\u5640\u5641\u5642\u5643\u5644\u5645\u5646\u5647"+ + "\u5648\u5649\u564A\u564B\u564C\u564D\u564E\u564F"+ + "\u5650\u5651\u5652\u5653\u5654\u5655\u5656\u5657"+ + "\u5658\u5659\u565A\u565B\u565C\u565D\u565E\uFE62"+ + "\uFE65\u565F\u5660\u5661\u5662\u5663\u5664\u5665"+ + "\u5666\u5667\u5668\u5669\u566A\u566B\u566C\uFE63"+ + "\u566D\u566E\u566F\u5670\u5671\u5672\u5673\u5674"+ + "\u5675\u5676\u5677\u5678\u5679\u567A\u567B\u567C"+ + "\u567D\u567E\u567F\u5680\u5681\u5682\u5683\u5684"+ + "\u5685\u5686\u5687\u5688\u5689\u568A\u568B\u568C"+ + "\u568D\u568E\u568F\u5690\u5691\u5692\u5693\u5694"+ + "\u5695\u5696\u5697\u5698\u5699\u569A\u569B\u569C"+ + "\u569D\u569E\u569F\u56A0\u56A1\u56A2\u56A3\u56A4"+ + "\u56A5\u56A6\u56A7\u56A8\u56A9\u56AA\u56AB\u56AC"+ + "\u56AD\u56AE\u56AF\u56B0\u56B1\u56B2\u56B3\u56B4"+ + "\u56B5\u56B6\u56B7\u56B8\u56B9\u56BA\u56BB\u56BC"+ + "\u56BD\u56BE\u56BF\u56C0\u56C1\u56C2\u56C3\u56C4"+ + "\u56C5\u56C6\u56C7\u56C8\u56C9\u56CA\u56CB\u56CC"+ + "\u56CD\u56CE\u56CF\u56D0\u56D1\u56D2\u56D3\u56D4"+ + "\u56D5\u56D6\u56D7\u56D8\u56D9\u56DA\u56DB\u56DC"+ + "\u56DD\u56DE\u56DF\u56E0\u56E1\u56E2\u56E3\u56E4"+ + "\u56E5\u56E6\u56E7\u56E8\u56E9\u56EA\u56EB\u56EC"+ + "\u56ED\u56EE\u56EF\u56F0\u56F1\u56F2\u56F3\u56F4"+ + "\u56F5\u56F6\u56F7\u56F8\u56F9\u56FA\u56FB\u56FC"+ + "\u56FD\u56FE\u56FF\uFE64\u5700\u5701\u5702\u5703"+ + "\u5704\u5705\u5706\u5707\u5708\u5709\u570A\u570B"+ + "\u570C\u570D\u570E\u570F\u5710\u5711\u5712\u5713"+ + "\u5714\u5715\u5716\u5717\u5718\u5719\u571A\u571B"+ + "\u571C\u571D\u571E\u571F\u5720\u5721\u5722\u5723"+ + "\u5724\u5725\u5726\u5727\u5728\u5729\u572A\u572B"+ + "\u572C\u572D\u572E\u572F\u5730\u5731\u5732\u5733"+ + "\u5734\u5735\u5736\u5737\u5738\u5739\u573A\u573B"+ + "\u573C\u573D\u573E\u573F\u5740\u5741\u5742\u5743"+ + "\u5744\u5745\u5746\u5747\u5748\u5749\u574A\u574B"+ + "\u574C\u574D\u574E\u574F\u5750\u5751\u5752\u5753"+ + "\u5754\u5755\u5756\u5757\u5758\u5759\u575A\u575B"+ + "\u575C\u575D\u575E\u575F\u5760\u5761\u5762\u5763"+ + "\u5764\u5765\u5766\u5767\u5768\u5769\u576A\u576B"+ + "\u576C\u576D\u576E\u576F\u5770\u5771\u5772\u5773"+ + "\u5774\u5775\u5776\u5777\u5778\u5779\u577A\u577B"+ + "\u577C\u577D\u577E\u577F\u5780\u5781\u5782\u5783"+ + "\u5784\u5785\u5786\u5787\u5788\u5789\u578A\u578B"+ + "\u578C\u578D\u578E\u578F\u5790\u5791\u5792\u5793"+ + "\u5794\u5795\u5796\u5797\u5798\u5799\u579A\u579B"+ + "\u579C\u579D\u579E\u579F\u57A0\u57A1\u57A2\u57A3"+ + "\u57A4\u57A5\u57A6\u57A7\u57A8\u57A9\u57AA\u57AB"+ + "\u57AC\u57AD\u57AE\u57AF\u57B0\u57B1\u57B2\u57B3"+ + "\u57B4\u57B5\u57B6\u57B7\u57B8\u57B9\u57BA\u57BB"+ + "\u57BC\u57BD\u57BE\u57BF\u57C0\u57C1\u57C2\u57C3"+ + "\u57C4\u57C5\u57C6\u57C7\u57C8\u57C9\u57CA\u57CB"+ + "\u57CC\u57CD\u57CE\u57CF\u57D0\u57D1\u57D2\u57D3"+ + "\u57D4\u57D5\u57D6\u57D7\u57D8\u57D9\uFE68\u57DA"+ + "\u57DB\u57DC\u57DD\u57DE\u57DF\u57E0\u57E1\u57E2"+ + "\u57E3\u57E4\u57E5\u57E6\u57E7\u57E8\u57E9\u57EA"+ + "\u57EB\u57EC\u57ED\u57EE\u57EF\u57F0\u57F1\u57F2"+ + "\u57F3\u57F4\u57F5\u57F6\u57F7\u57F8\u57F9\u57FA"+ + "\u57FB\u57FC\u57FD\u57FE\u57FF\u5800\u5801\u5802"+ + "\u5803\u5804\u5805\u5806\u5807\u5808\u5809\u580A"+ + "\u580B\u580C\u580D\u580E\u580F\u5810\u5811\u5812"+ + "\u5813\u5814\u5815\u5816\u5817\u5818\u5819\u581A"+ + "\u581B\u581C\u581D\u581E\u581F\u5820\u5821\u5822"+ + "\u5823\u5824\u5825\u5826\u5827\u5828\u5829\u582A"+ + "\u582B\u582C\u582D\u582E\u582F\u5830\u5831\u5832"+ + "\u5833\u5834\u5835\u5836\u5837\u5838\u5839\u583A"+ + "\u583B\u583C\u583D\u583E\u583F\u5840\u5841\u5842"+ + "\u5843\u5844\u5845\u5846\u5847\u5848\u5849\u584A"+ + "\u584B\u584C\u584D\u584E\u584F\u5850\u5851\u5852"+ + "\u5853\u5854\u5855\u5856\u5857\u5858\u5859\u585A"+ + "\u585B\u585C\u585D\u585E\u585F\u5860\u5861\u5862"+ + "\u5863\u5864\u5865\u5866\u5867\u5868\u5869\u586A"+ + "\u586B\u586C\u586D\u586E\u586F\u5870\u5871\u5872"+ + "\u5873\u5874\u5875\u5876\u5877\u5878\u5879\u587A"+ + "\u587B\u587C\u587D\u587E\u587F\u5880\u5881\u5882"+ + "\u5883\u5884\u5885\u5886\u5887\u5888\u5889\u588A"+ + "\u588B\u588C\u588D\u588E\u588F\u5890\u5891\u5892"+ + "\u5893\u5894\u5895\u5896\u5897\u5898\u5899\u589A"+ + "\u589B\u589C\u589D\u589E\u589F\u58A0\u58A1\u58A2"+ + "\u58A3\u58A4\u58A5\u58A6\u58A7\u58A8\u58A9\u58AA"+ + "\u58AB\u58AC\u58AD\u58AE\u58AF\u58B0\u58B1\u58B2"+ + "\u58B3\u58B4\u58B5\u58B6\u58B7\u58B8\u58B9\u58BA"+ + "\u58BB\u58BC\u58BD\u58BE\u58BF\u58C0\u58C1\u58C2"+ + "\u58C3\u58C4\u58C5\u58C6\u58C7\u58C8\u58C9\u58CA"+ + "\u58CB\u58CC\u58CD\u58CE\u58CF\u58D0\u58D1\u58D2"+ + "\u58D3\u58D4\u58D5\u58D6\u58D7\u58D8\u58D9\u58DA"+ + "\u58DB\u58DC\u58DD\u58DE\u58DF\u58E0\u58E1\u58E2"+ + "\u58E3\u58E4\u58E5\u58E6\u58E7\u58E8\u58E9\u58EA"+ + "\u58EB\u58EC\u58ED\u58EE\u58EF\u58F0\u58F1\u58F2"+ + "\u58F3\u58F4\u58F5\u58F6\u58F7\u58F8\uFE69\u58F9"+ + "\u58FA\u58FB\u58FC\u58FD\u58FE\u58FF\u5900\u5901"+ + "\u5902\u5903\u5904\u5905\u5906\u5907\u5908\u5909"+ + "\u590A\u590B\u590C\u590D\u590E\u590F\u5910\u5911"+ + "\u5912\u5913\u5914\u5915\u5916\u5917\u5918\u5919"+ + "\u591A\u591B\u591C\u591D\u591E\u591F\u5920\u5921"+ + "\u5922\u5923\u5924\u5925\u5926\u5927\u5928\u5929"+ + "\u592A\u592B\u592C\u592D\u592E\u592F\u5930\u5931"+ + "\u5932\u5933\u5934\u5935\u5936\u5937\u5938\u5939"+ + "\u593A\u593B\u593C\u593D\u593E\u593F\u5940\u5941"+ + "\u5942\u5943\u5944\u5945\u5946\u5947\u5948\u5949"+ + "\u594A\u594B\u594C\u594D\u594E\u594F\u5950\u5951"+ + "\u5952\u5953\u5954\u5955\u5956\u5957\u5958\u5959"+ + "\u595A\u595B\u595C\u595D\u595E\u595F\u5960\u5961"+ + "\u5962\u5963\u5964\u5965\u5966\u5967\u5968\u5969"+ + "\uFE6A\u596A\u596B\u596C\u596D\u596E\u596F\u5970"+ + "\u5971\u5972\u5973\u5974\u5975\u5976\u5977\u5978"+ + "\u5979\u597A\u597B\u597C\u597D\u597E\u597F\u5980"+ + "\u5981\u5982\u5983\u5984\u5985\u5986\u5987\u5988"+ + "\u5989\u598A\u598B\u598C\u598D\u598E\u598F\u5990"+ + "\u5991\u5992\u5993\u5994\u5995\u5996\u5997\u5998"+ + "\u5999\u599A\u599B\u599C\u599D\u599E\u599F\u59A0"+ + "\u59A1\u59A2\u59A3\u59A4\u59A5\u59A6\u59A7\u59A8"+ + "\u59A9\u59AA\u59AB\u59AC\u59AD\u59AE\u59AF\u59B0"+ + "\u59B1\u59B2\u59B3\u59B4\u59B5\u59B6\u59B7\u59B8"+ + "\u59B9\u59BA\u59BB\u59BC\u59BD\u59BE\u59BF\u59C0"+ + "\u59C1\u59C2\u59C3\u59C4\u59C5\u59C6\u59C7\u59C8"+ + "\u59C9\u59CA\u59CB\u59CC\u59CD\u59CE\u59CF\u59D0"+ + "\u59D1\u59D2\u59D3\u59D4\u59D5\u59D6\u59D7\u59D8"+ + "\u59D9\u59DA\u59DB\u59DC\u59DD\u59DE\u59DF\u59E0"+ + "\u59E1\u59E2\u59E3\u59E4\u59E5\u59E6\u59E7\u59E8"+ + "\u59E9\u59EA\u59EB\u59EC\u59ED\u59EE\u59EF\u59F0"+ + "\u59F1\u59F2\u59F3\u59F4\u59F5\u59F6\u59F7\u59F8"+ + "\u59F9\u59FA\u59FB\u59FC\u59FD\u59FE\u59FF\u5A00"+ + "\u5A01\u5A02\u5A03\u5A04\u5A05\u5A06\u5A07\u5A08"+ + "\u5A09\u5A0A\u5A0B\u5A0C\u5A0D\u5A0E\u5A0F\u5A10"+ + "\u5A11\u5A12\u5A13\u5A14\u5A15\u5A16\u5A17\u5A18"+ + "\u5A19\u5A1A\u5A1B\u5A1C\u5A1D\u5A1E\u5A1F\u5A20"+ + "\u5A21\u5A22\u5A23\u5A24\u5A25\u5A26\u5A27\u5A28"+ + "\u5A29\u5A2A\u5A2B\u5A2C\u5A2D\u5A2E\u5A2F\u5A30"+ + "\u5A31\u5A32\u5A33\u5A34\u5A35\u5A36\u5A37\u5A38"+ + "\u5A39\u5A3A\u5A3B\u5A3C\u5A3D\u5A3E\u5A3F\u5A40"+ + "\u5A41\u5A42\u5A43\u5A44\u5A45\u5A46\u5A47\u5A48"+ + "\u5A49\u5A4A\u5A4B\u5A4C\u5A4D\u5A4E\u5A4F\u5A50"+ + "\u5A51\u5A52\u5A53\u5A54\u5A55\u5A56\u5A57\u5A58"+ + "\u5A59\u5A5A\u5A5B\u5A5C\u5A5D\u5A5E\u5A5F\u5A60"+ + "\u5A61\u5A62\u5A63\u5A64\u5A65\u5A66\u5A67\u5A68"+ + "\u5A69\u5A6A\u5A6B\u5A6C\u5A6D\u5A6E\u5A6F\u5A70"+ + "\u5A71\u5A72\u5A73\u5A74\u5A75\u5A76\u5A77\u5A78"+ + "\u5A79\u5A7A\u5A7B\u5A7C\u5A7D\u5A7E\u5A7F\u5A80"+ + "\u5A81\u5A82\u5A83\u5A84\u5A85\u5A86\u5A87\u5A88"+ + "\u5A89\u5A8A\u5A8B\u5A8C\u5A8D\u5A8E\u5A8F\u5A90"+ + "\u5A91\u5A92\u5A93\u5A94\u5A95\u5A96\u5A97\u5A98"+ + "\u5A99\u5A9A\u5A9B\u5A9C\u5A9D\u5A9E\u5A9F\u5AA0"+ + "\u5AA1\u5AA2\u5AA3\u5AA4\u5AA5\u5AA6\u5AA7\u5AA8"+ + "\u5AA9\u5AAA\u5AAB\u5AAC\u5AAD\u5AAE\u5AAF\u5AB0"+ + "\u5AB1\u5AB2\u5AB3\u5AB4\u5AB5\u5AB6\u5AB7\u5AB8"+ + "\u5AB9\u5ABA\u5ABB\u5ABC\u5ABD\u5ABE\u5ABF\u5AC0"+ + "\u5AC1\u5AC2\u5AC3\u5AC4\u5AC5\u5AC6\u5AC7\u5AC8"+ + "\u5AC9\u5ACA\u5ACB\u5ACC\u5ACD\u5ACE\u5ACF\u5AD0"+ + "\u5AD1\u5AD2\u5AD3\u5AD4\u5AD5\u5AD6\u5AD7\u5AD8"+ + "\u5AD9\u5ADA\u5ADB\u5ADC\u5ADD\u5ADE\u5ADF\u5AE0"+ + "\u5AE1\u5AE2\u5AE3\u5AE4\u5AE5\u5AE6\u5AE7\u5AE8"+ + "\u5AE9\u5AEA\u5AEB\u5AEC\u5AED\u5AEE\u5AEF\u5AF0"+ + "\u5AF1\u5AF2\u5AF3\u5AF4\u5AF5\u5AF6\u5AF7\u5AF8"+ + "\u5AF9\u5AFA\u5AFB\u5AFC\u5AFD\u5AFE\u5AFF\u5B00"+ + "\u5B01\u5B02\u5B03\u5B04\u5B05\u5B06\u5B07\u5B08"+ + "\u5B09\u5B0A\u5B0B\u5B0C\u5B0D\u5B0E\u5B0F\u5B10"+ + "\u5B11\u5B12\u5B13\u5B14\u5B15\u5B16\u5B17\u5B18"+ + "\u5B19\u5B1A\u5B1B\u5B1C\u5B1D\u5B1E\u5B1F\u5B20"+ + "\u5B21\u5B22\u5B23\u5B24\u5B25\u5B26\u5B27\u5B28"+ + "\u5B29\u5B2A\u5B2B\u5B2C\u5B2D\u5B2E\u5B2F\u5B30"+ + "\u5B31\u5B32\u5B33\u5B34\u5B35\u5B36\u5B37\u5B38"+ + "\u5B39\u5B3A\u5B3B\u5B3C\u5B3D\u5B3E\u5B3F\u5B40"+ + "\u5B41\u5B42\u5B43\u5B44\u5B45\u5B46\u5B47\u5B48"+ + "\u5B49\u5B4A\u5B4B\u5B4C\u5B4D\u5B4E\u5B4F\u5B50"+ + "\u5B51\u5B52\u5B53\u5B54\u5B55\u5B56\u5B57\u5B58"+ + "\u5B59\u5B5A\u5B5B\u5B5C\u5B5D\u5B5E\u5B5F\u5B60"+ + "\u5B61\u5B62\u5B63\u5B64\u5B65\u5B66\u5B67\u5B68"+ + "\u5B69\u5B6A\u5B6B\u5B6C\u5B6D\u5B6E\u5B6F\u5B70"+ + "\u5B71\u5B72\u5B73\u5B74\u5B75\u5B76\u5B77\u5B78"+ + "\u5B79\u5B7A\u5B7B\u5B7C\u5B7D\u5B7E\u5B7F\u5B80"+ + "\u5B81\u5B82\u5B83\u5B84\u5B85\u5B86\u5B87\u5B88"+ + "\u5B89\u5B8A\u5B8B\u5B8C\u5B8D\u5B8E\u5B8F\u5B90"+ + "\u5B91\u5B92\u5B93\u5B94\u5B95\u5B96\u5B97\u5B98"+ + "\u5B99\u5B9A\u5B9B\u5B9C\u5B9D\u5B9E\u5B9F\u5BA0"+ + "\u5BA1\u5BA2\u5BA3\u5BA4\u5BA5\u5BA6\u5BA7\u5BA8"+ + "\u5BA9\u5BAA\u5BAB\u5BAC\u5BAD\u5BAE\u5BAF\u5BB0"+ + "\u5BB1\u5BB2\u5BB3\u5BB4\u5BB5\u5BB6\u5BB7\u5BB8"+ + "\u5BB9\u5BBA\u5BBB\u5BBC\u5BBD\u5BBE\u5BBF\u5BC0"+ + "\u5BC1\u5BC2\u5BC3\u5BC4\u5BC5\u5BC6\u5BC7\u5BC8"+ + "\u5BC9\u5BCA\u5BCB\u5BCC\u5BCD\u5BCE\u5BCF\u5BD0"+ + "\u5BD1\u5BD2\u5BD3\u5BD4\u5BD5\u5BD6\u5BD7\u5BD8"+ + "\u5BD9\u5BDA\u5BDB\u5BDC\u5BDD\u5BDE\u5BDF\u5BE0"+ + "\u5BE1\u5BE2\u5BE3\u5BE4\u5BE5\u5BE6\u5BE7\u5BE8"+ + "\u5BE9\u5BEA\u5BEB\u5BEC\u5BED\u5BEE\u5BEF\u5BF0"+ + "\u5BF1\u5BF2\u5BF3\u5BF4\u5BF5\u5BF6\u5BF7\u5BF8"+ + "\u5BF9\u5BFA\u5BFB\u5BFC\u5BFD\u5BFE\u5BFF\u5C00"+ + "\u5C01\u5C02\u5C03\u5C04\u5C05\u5C06\u5C07\u5C08"+ + "\u5C09\u5C0A\u5C0B\u5C0C\u5C0D\u5C0E\u5C0F\u5C10"+ + "\u5C11\u5C12\u5C13\u5C14\u5C15\u5C16\u5C17\u5C18"+ + "\u5C19\u5C1A\u5C1B\u5C1C\u5C1D\u5C1E\u5C1F\u5C20"+ + "\u5C21\u5C22\u5C23\u5C24\u5C25\u5C26\u5C27\u5C28"+ + "\u5C29\u5C2A\u5C2B\u5C2C\u5C2D\u5C2E\u5C2F\u5C30"+ + "\u5C31\u5C32\u5C33\u5C34\u5C35\u5C36\u5C37\u5C38"+ + "\u5C39\u5C3A\u5C3B\u5C3C\u5C3D\u5C3E\u5C3F\u5C40"+ + "\u5C41\u5C42\u5C43\u5C44\u5C45\u5C46\u5C47\u5C48"+ + "\u5C49\u5C4A\u5C4B\u5C4C\u5C4D\u5C4E\u5C4F\u5C50"+ + "\u5C51\u5C52\u5C53\u5C54\u5C55\u5C56\u5C57\u5C58"+ + "\u5C59\u5C5A\u5C5B\u5C5C\u5C5D\u5C5E\u5C5F\u5C60"+ + "\u5C61\u5C62\u5C63\u5C64\u5C65\u5C66\u5C67\u5C68"+ + "\u5C69\u5C6A\u5C6B\u5C6C\u5C6D\u5C6E\u5C6F\u5C70"+ + "\u5C71\u5C72\u5C73\u5C74\u5C75\u5C76\u5C77\u5C78"+ + "\u5C79\u5C7A\u5C7B\u5C7C\u5C7D\u5C7E\u5C7F\u5C80"+ + "\u5C81\u5C82\u5C83\u5C84\u5C85\u5C86\u5C87\u5C88"; + + private static final String innerEncoderIndex4= + "\u5C89\u5C8A\u5C8B\u5C8C\u5C8D\u5C8E\u5C8F\u5C90"+ + "\u5C91\u5C92\u5C93\u5C94\u5C95\u5C96\u5C97\u5C98"+ + "\u5C99\u5C9A\u5C9B\u5C9C\u5C9D\u5C9E\u5C9F\u5CA0"+ + "\u5CA1\u5CA2\u5CA3\u5CA4\u5CA5\u5CA6\u5CA7\u5CA8"+ + "\u5CA9\u5CAA\u5CAB\u5CAC\u5CAD\u5CAE\u5CAF\u5CB0"+ + "\u5CB1\u5CB2\u5CB3\u5CB4\u5CB5\u5CB6\u5CB7\u5CB8"+ + "\u5CB9\u5CBA\u5CBB\u5CBC\u5CBD\u5CBE\u5CBF\u5CC0"+ + "\u5CC1\u5CC2\u5CC3\u5CC4\u5CC5\u5CC6\u5CC7\u5CC8"+ + "\u5CC9\u5CCA\u5CCB\u5CCC\u5CCD\u5CCE\u5CCF\u5CD0"+ + "\u5CD1\u5CD2\u5CD3\u5CD4\u5CD5\u5CD6\u5CD7\u5CD8"+ + "\u5CD9\u5CDA\u5CDB\u5CDC\u5CDD\u5CDE\uFE6F\u5CDF"+ + "\u5CE0\u5CE1\u5CE2\u5CE3\u5CE4\u5CE5\u5CE6\u5CE7"+ + "\u5CE8\u5CE9\u5CEA\u5CEB\u5CEC\u5CED\u5CEE\u5CEF"+ + "\u5CF0\u5CF1\u5CF2\u5CF3\u5CF4\u5CF5\u5CF6\u5CF7"+ + "\u5CF8\u5CF9\u5CFA\u5CFB\u5CFC\u5CFD\u5CFE\u5CFF"+ + "\u5D00\u5D01\u5D02\u5D03\u5D04\u5D05\u5D06\u5D07"+ + "\u5D08\u5D09\u5D0A\u5D0B\u5D0C\u5D0D\u5D0E\u5D0F"+ + "\u5D10\u5D11\u5D12\u5D13\u5D14\u5D15\u5D16\u5D17"+ + "\u5D18\u5D19\u5D1A\u5D1B\u5D1C\u5D1D\u5D1E\u5D1F"+ + "\u5D20\u5D21\u5D22\u5D23\u5D24\u5D25\u5D26\u5D27"+ + "\u5D28\u5D29\u5D2A\u5D2B\u5D2C\u5D2D\u5D2E\u5D2F"+ + "\u5D30\u5D31\u5D32\u5D33\u5D34\u5D35\u5D36\u5D37"+ + "\u5D38\u5D39\u5D3A\u5D3B\u5D3C\u5D3D\u5D3E\u5D3F"+ + "\u5D40\u5D41\u5D42\u5D43\u5D44\u5D45\u5D46\u5D47"+ + "\u5D48\u5D49\u5D4A\u5D4B\u5D4C\u5D4D\u5D4E\u5D4F"+ + "\u5D50\u5D51\u5D52\u5D53\u5D54\u5D55\u5D56\u5D57"+ + "\u5D58\u5D59\u5D5A\u5D5B\u5D5C\u5D5D\u5D5E\u5D5F"+ + "\u5D60\u5D61\u5D62\u5D63\u5D64\u5D65\u5D66\u5D67"+ + "\u5D68\u5D69\u5D6A\u5D6B\u5D6C\u5D6D\u5D6E\u5D6F"+ + "\u5D70\u5D71\u5D72\u5D73\u5D74\u5D75\u5D76\u5D77"+ + "\u5D78\u5D79\u5D7A\u5D7B\u5D7C\u5D7D\u5D7E\u5D7F"+ + "\u5D80\u5D81\u5D82\u5D83\u5D84\u5D85\u5D86\u5D87"+ + "\u5D88\u5D89\u5D8A\u5D8B\u5D8C\u5D8D\u5D8E\u5D8F"+ + "\u5D90\u5D91\u5D92\u5D93\u5D94\u5D95\u5D96\u5D97"+ + "\u5D98\u5D99\u5D9A\u5D9B\u5D9C\u5D9D\u5D9E\u5D9F"+ + "\u5DA0\u5DA1\u5DA2\u5DA3\u5DA4\u5DA5\u5DA6\u5DA7"+ + "\u5DA8\u5DA9\u5DAA\u5DAB\u5DAC\u5DAD\u5DAE\u5DAF"+ + "\u5DB0\u5DB1\u5DB2\u5DB3\u5DB4\u5DB5\u5DB6\u5DB7"+ + "\u5DB8\u5DB9\u5DBA\u5DBB\u5DBC\u5DBD\u5DBE\u5DBF"+ + "\u5DC0\u5DC1\u5DC2\u5DC3\u5DC4\u5DC5\u5DC6\u5DC7"+ + "\u5DC8\u5DC9\u5DCA\u5DCB\u5DCC\u5DCD\u5DCE\u5DCF"+ + "\u5DD0\u5DD1\u5DD2\u5DD3\u5DD4\u5DD5\u5DD6\u5DD7"+ + "\u5DD8\u5DD9\u5DDA\u5DDB\u5DDC\u5DDD\u5DDE\u5DDF"+ + "\u5DE0\u5DE1\u5DE2\u5DE3\u5DE4\u5DE5\u5DE6\uFE70"+ + "\u5DE7\u5DE8\u5DE9\u5DEA\u5DEB\u5DEC\u5DED\u5DEE"+ + "\u5DEF\u5DF0\u5DF1\u5DF2\u5DF3\u5DF4\u5DF5\u5DF6"+ + "\u5DF7\u5DF8\u5DF9\u5DFA\u5DFB\u5DFC\u5DFD\u5DFE"+ + "\u5DFF\u5E00\u5E01\u5E02\u5E03\u5E04\u5E05\u5E06"+ + "\u5E07\u5E08\u5E09\u5E0A\u5E0B\u5E0C\u5E0D\u5E0E"+ + "\u5E0F\u5E10\u5E11\u5E12\u5E13\u5E14\u5E15\u5E16"+ + "\u5E17\u5E18\u5E19\u5E1A\u5E1B\u5E1C\u5E1D\u5E1E"+ + "\u5E1F\u5E20\u5E21\u5E22\u5E23\u5E24\u5E25\u5E26"+ + "\u5E27\u5E28\u5E29\u5E2A\u5E2B\u5E2C\u5E2D\u5E2E"+ + "\u5E2F\u5E30\u5E31\u5E32\u5E33\u5E34\u5E35\u5E36"+ + "\u5E37\u5E38\u5E39\u5E3A\u5E3B\u5E3C\u5E3D\u5E3E"+ + "\u5E3F\u5E40\u5E41\u5E42\u5E43\u5E44\u5E45\u5E46"+ + "\u5E47\u5E48\u5E49\u5E4A\u5E4B\u5E4C\u5E4D\u5E4E"+ + "\u5E4F\u5E50\u5E51\u5E52\u5E53\u5E54\u5E55\u5E56"+ + "\u5E57\u5E58\u5E59\u5E5A\u5E5B\u5E5C\u5E5D\u5E5E"+ + "\u5E5F\u5E60\u5E61\u5E62\u5E63\u5E64\u5E65\u5E66"+ + "\u5E67\u5E68\u5E69\u5E6A\u5E6B\u5E6C\u5E6D\u5E6E"+ + "\u5E6F\u5E70\u5E71\u5E72\u5E73\u5E74\u5E75\u5E76"+ + "\u5E77\u5E78\u5E79\u5E7A\u5E7B\u5E7C\u5E7D\u5E7E"+ + "\u5E7F\u5E80\u5E81\u5E82\u5E83\u5E84\u5E85\u5E86"+ + "\u5E87\u5E88\u5E89\u5E8A\u5E8B\u5E8C\u5E8D\u5E8E"+ + "\u5E8F\u5E90\u5E91\u5E92\u5E93\u5E94\u5E95\u5E96"+ + "\u5E97\u5E98\u5E99\u5E9A\u5E9B\u5E9C\u5E9D\u5E9E"+ + "\u5E9F\u5EA0\u5EA1\u5EA2\u5EA3\u5EA4\u5EA5\u5EA6"+ + "\u5EA7\u5EA8\u5EA9\u5EAA\u5EAB\u5EAC\u5EAD\u5EAE"+ + "\u5EAF\u5EB0\u5EB1\u5EB2\u5EB3\u5EB4\u5EB5\u5EB6"+ + "\u5EB7\u5EB8\u5EB9\u5EBA\u5EBB\u5EBC\u5EBD\u5EBE"+ + "\u5EBF\u5EC0\u5EC1\u5EC2\u5EC3\u5EC4\u5EC5\u5EC6"+ + "\u5EC7\u5EC8\u5EC9\u5ECA\u5ECB\u5ECC\u5ECD\u5ECE"+ + "\u5ECF\u5ED0\u5ED1\u5ED2\u5ED3\u5ED4\u5ED5\u5ED6"+ + "\u5ED7\u5ED8\u5ED9\u5EDA\u5EDB\u5EDC\u5EDD\u5EDE"+ + "\u5EDF\u5EE0\u5EE1\u5EE2\u5EE3\u5EE4\u5EE5\u5EE6"+ + "\u5EE7\u5EE8\u5EE9\u5EEA\u5EEB\u5EEC\u5EED\u5EEE"+ + "\u5EEF\u5EF0\u5EF1\u5EF2\u5EF3\u5EF4\u5EF5\u5EF6"+ + "\u5EF7\u5EF8\u5EF9\u5EFA\u5EFB\u5EFC\u5EFD\u5EFE"+ + "\u5EFF\u5F00\u5F01\u5F02\u5F03\u5F04\u5F05\u5F06"+ + "\u5F07\u5F08\u5F09\u5F0A\u5F0B\u5F0C\u5F0D\u5F0E"+ + "\u5F0F\u5F10\u5F11\u5F12\u5F13\u5F14\u5F15\u5F16"+ + "\u5F17\u5F18\u5F19\u5F1A\u5F1B\u5F1C\u5F1D\u5F1E"+ + "\u5F1F\u5F20\u5F21\u5F22\u5F23\u5F24\u5F25\u5F26"+ + "\u5F27\u5F28\u5F29\u5F2A\u5F2B\u5F2C\u5F2D\u5F2E"+ + "\u5F2F\u5F30\u5F31\u5F32\u5F33\u5F34\u5F35\u5F36"+ + "\u5F37\u5F38\u5F39\u5F3A\u5F3B\u5F3C\u5F3D\u5F3E"+ + "\u5F3F\u5F40\u5F41\u5F42\u5F43\u5F44\u5F45\u5F46"+ + "\u5F47\u5F48\u5F49\u5F4A\u5F4B\u5F4C\u5F4D\u5F4E"+ + "\u5F4F\u5F50\u5F51\u5F52\u5F53\u5F54\u5F55\u5F56"+ + "\u5F57\u5F58\u5F59\u5F5A\u5F5B\u5F5C\u5F5D\u5F5E"+ + "\u5F5F\u5F60\u5F61\u5F62\u5F63\u5F64\u5F65\u5F66"+ + "\u5F67\u5F68\u5F69\u5F6A\u5F6B\u5F6C\u5F6D\u5F6E"+ + "\u5F6F\u5F70\u5F71\u5F72\u5F73\u5F74\u5F75\u5F76"+ + "\u5F77\u5F78\u5F79\u5F7A\u5F7B\u5F7C\u5F7D\u5F7E"+ + "\u5F7F\u5F80\u5F81\u5F82\u5F83\u5F84\u5F85\u5F86"+ + "\u5F87\u5F88\u5F89\u5F8A\u5F8B\u5F8C\u5F8D\u5F8E"+ + "\u5F8F\u5F90\u5F91\u5F92\u5F93\u5F94\u5F95\u5F96"+ + "\u5F97\u5F98\u5F99\u5F9A\u5F9B\u5F9C\u5F9D\u5F9E"+ + "\u5F9F\u5FA0\u5FA1\u5FA2\u5FA3\u5FA4\u5FA5\u5FA6"+ + "\u5FA7\u5FA8\u5FA9\u5FAA\u5FAB\u5FAC\u5FAD\u5FAE"+ + "\u5FAF\u5FB0\u5FB1\u5FB2\u5FB3\u5FB4\u5FB5\u5FB6"+ + "\u5FB7\u5FB8\u5FB9\u5FBA\u5FBB\u5FBC\u5FBD\uFE72"+ + "\u5FBE\u5FBF\u5FC0\u5FC1\u5FC2\u5FC3\u5FC4\u5FC5"+ + "\u5FC6\u5FC7\u5FC8\u5FC9\u5FCA\u5FCB\u5FCC\u5FCD"+ + "\u5FCE\u5FCF\u5FD0\u5FD1\u5FD2\u5FD3\u5FD4\u5FD5"+ + "\u5FD6\u5FD7\u5FD8\u5FD9\u5FDA\u5FDB\u5FDC\u5FDD"+ + "\u5FDE\u5FDF\u5FE0\u5FE1\u5FE2\u5FE3\u5FE4\u5FE5"+ + "\u5FE6\u5FE7\u5FE8\u5FE9\u5FEA\u5FEB\u5FEC\u5FED"+ + "\u5FEE\u5FEF\u5FF0\u5FF1\u5FF2\u5FF3\u5FF4\u5FF5"+ + "\u5FF6\u5FF7\u5FF8\u5FF9\u5FFA\u5FFB\u5FFC\u5FFD"+ + "\u5FFE\u5FFF\u6000\u6001\u6002\u6003\u6004\u6005"+ + "\u6006\u6007\u6008\u6009\u600A\u600B\u600C\u600D"+ + "\u600E\u600F\u6010\u6011\u6012\u6013\u6014\u6015"+ + "\u6016\u6017\u6018\u6019\u601A\u601B\u601C\u601D"+ + "\u601E\u601F\u6020\u6021\u6022\u6023\u6024\u6025"+ + "\u6026\u6027\u6028\u6029\u602A\u602B\u602C\u602D"+ + "\u602E\u602F\u6030\u6031\uFE78\u6032\u6033\u6034"+ + "\u6035\uFE77\u6036\u6037\u6038\u6039\u603A\u603B"+ + "\u603C\u603D\u603E\u603F\u6040\u6041\u6042\u6043"+ + "\u6044\u6045\u6046\u6047\u6048\u6049\u604A\u604B"+ + "\u604C\u604D\u604E\u604F\u6050\u6051\u6052\u6053"+ + "\u6054\u6055\u6056\u6057\u6058\u6059\u605A\u605B"+ + "\u605C\u605D\u605E\u605F\u6060\uFE7A\u6061\u6062"+ + "\u6063\u6064\u6065\u6066\u6067\u6068\u6069\u606A"+ + "\u606B\u606C\u606D\u606E\u606F\u6070\u6071\u6072"+ + "\u6073\u6074\u6075\u6076\u6077\u6078\u6079\u607A"+ + "\u607B\u607C\u607D\u607E\u607F\u6080\u6081\u6082"+ + "\u6083\u6084\u6085\u6086\u6087\u6088\u6089\u608A"+ + "\u608B\u608C\u608D\u608E\u608F\u6090\u6091\u6092"+ + "\u6093\u6094\u6095\u6096\u6097\u6098\u6099\u609A"+ + "\u609B\u609C\u609D\u609E\u609F\u60A0\u60A1\u60A2"+ + "\u60A3\u60A4\u60A5\u60A6\u60A7\u60A8\u60A9\u60AA"+ + "\u60AB\u60AC\u60AD\u60AE\u60AF\u60B0\u60B1\u60B2"+ + "\u60B3\u60B4\u60B5\u60B6\u60B7\u60B8\u60B9\u60BA"+ + "\u60BB\u60BC\u60BD\u60BE\u60BF\u60C0\u60C1\u60C2"+ + "\u60C3\u60C4\u60C5\u60C6\u60C7\u60C8\u60C9\u60CA"+ + "\u60CB\u60CC\u60CD\u60CE\u60CF\u60D0\u60D1\u60D2"+ + "\u60D3\u60D4\u60D5\u60D6\u60D7\u60D8\u60D9\u60DA"+ + "\u60DB\u60DC\u60DD\u60DE\u60DF\u60E0\u60E1\u60E2"+ + "\u60E3\u60E4\u60E5\u60E6\u60E7\u60E8\u60E9\u60EA"+ + "\u60EB\u60EC\u60ED\u60EE\u60EF\u60F0\u60F1\u60F2"+ + "\u60F3\u60F4\u60F5\u60F6\u60F7\u60F8\u60F9\u60FA"+ + "\u60FB\u60FC\u60FD\u60FE\u60FF\u6100\u6101\u6102"+ + "\u6103\u6104\u6105\u6106\u6107\u6108\u6109\u610A"+ + "\u610B\u610C\u610D\u610E\u610F\u6110\u6111\u6112"+ + "\u6113\u6114\u6115\u6116\u6117\u6118\u6119\u611A"+ + "\u611B\u611C\u611D\u611E\u611F\u6120\u6121\u6122"+ + "\u6123\u6124\u6125\u6126\u6127\u6128\u6129\u612A"+ + "\u612B\u612C\u612D\u612E\u612F\u6130\u6131\u6132"+ + "\u6133\u6134\u6135\u6136\u6137\u6138\u6139\u613A"+ + "\u613B\u613C\u613D\u613E\u613F\u6140\u6141\u6142"+ + "\u6143\u6144\u6145\u6146\u6147\u6148\u6149\u614A"+ + "\u614B\u614C\u614D\u614E\u614F\u6150\u6151\u6152"+ + "\u6153\u6154\u6155\u6156\u6157\u6158\uFE7B\u6159"+ + "\u615A\u615B\u615C\u615D\u615E\u615F\u6160\u6161"+ + "\u6162\u6163\u6164\u6165\u6166\u6167\u6168\u6169"+ + "\u616A\u616B\u616C\u616D\u616E\u616F\u6170\u6171"+ + "\u6172\u6173\u6174\u6175\u6176\u6177\u6178\u6179"+ + "\u617A\u617B\u617C\u617D\u617E\u617F\u6180\u6181"+ + "\u6182\u6183\u6184\u6185\u6186\u6187\u6188\u6189"+ + "\u618A\u618B\u618C\u618D\u618E\u618F\u6190\u6191"+ + "\u6192\u6193\u6194\u6195\u6196\u6197\u6198\u6199"+ + "\u619A\u619B\u619C\u619D\u619E\u619F\u61A0\u61A1"+ + "\u61A2\u61A3\u61A4\u61A5\u61A6\u61A7\u61A8\u61A9"+ + "\u61AA\u61AB\u61AC\u61AD\u61AE\u61AF\u61B0\u61B1"+ + "\u61B2\u61B3\u61B4\u61B5\u61B6\u61B7\u61B8\u61B9"+ + "\u61BA\u61BB\u61BC\u61BD\u61BE\u61BF\u61C0\u61C1"+ + "\u61C2\u61C3\u61C4\u61C5\u61C6\u61C7\u61C8\u61C9"+ + "\u61CA\u61CB\u61CC\u61CD\u61CE\u61CF\u61D0\u61D1"+ + "\u61D2\u61D3\u61D4\u61D5\u61D6\u61D7\u61D8\u61D9"+ + "\u61DA\u61DB\u61DC\u61DD\u61DE\u61DF\u61E0\u61E1"+ + "\u61E2\u61E3\u61E4\u61E5\u61E6\u61E7\u61E8\u61E9"+ + "\u61EA\u61EB\u61EC\u61ED\u61EE\u61EF\u61F0\u61F1"+ + "\u61F2\u61F3\u61F4\u61F5\u61F6\u61F7\u61F8\u61F9"+ + "\u61FA\u61FB\u61FC\u61FD\u61FE\u61FF\u6200\u6201"+ + "\u6202\u6203\u6204\u6205\u6206\u6207\u6208\u6209"+ + "\u620A\u620B\u620C\u620D\u620E\u620F\u6210\u6211"+ + "\u6212\u6213\u6214\u6215\u6216\u6217\u6218\u6219"+ + "\u621A\u621B\u621C\u621D\u621E\u621F\u6220\u6221"+ + "\u6222\u6223\u6224\u6225\u6226\u6227\u6228\u6229"+ + "\u622A\u622B\u622C\u622D\u622E\u622F\u6230\u6231"+ + "\u6232\u6233\u6234\u6235\u6236\u6237\u6238\u6239"+ + "\u623A\u623B\u623C\u623D\u623E\u623F\u6240\u6241"+ + "\u6242\u6243\u6244\u6245\u6246\u6247\u6248\u6249"+ + "\u624A\u624B\u624C\u624D\u624E\u624F\u6250\u6251"+ + "\u6252\u6253\u6254\u6255\u6256\u6257\u6258\u6259"+ + "\u625A\u625B\u625C\u625D\u625E\u625F\u6260\u6261"+ + "\u6262\u6263\u6264\u6265\u6266\u6267\u6268\u6269"+ + "\u626A\u626B\u626C\u626D\u626E\u626F\u6270\u6271"+ + "\u6272\u6273\u6274\u6275\u6276\u6277\u6278\u6279"+ + "\u627A\u627B\u627C\u627D\u627E\u627F\u6280\u6281"+ + "\u6282\u6283\u6284\u6285\u6286\u6287\u6288\u6289"+ + "\u628A\u628B\u628C\u628D\u628E\u628F\u6290\u6291"+ + "\u6292\u6293\u6294\u6295\u6296\u6297\u6298\u6299"+ + "\u629A\u629B\u629C\u629D\u629E\u629F\u62A0\u62A1"+ + "\u62A2\u62A3\u62A4\u62A5\u62A6\u62A7\u62A8\u62A9"+ + "\u62AA\u62AB\u62AC\u62AD\u62AE\u62AF\u62B0\u62B1"+ + "\u62B2\u62B3\u62B4\u62B5\u62B6\u62B7\u62B8\u62B9"+ + "\u62BA\u62BB\u62BC\u62BD\u62BE\u62BF\u62C0\u62C1"+ + "\u62C2\u62C3\u62C4\u62C5\u62C6\u62C7\u62C8\u62C9"+ + "\u62CA\u62CB\u62CC\u62CD\uFE7D\u62CE\u62CF\u62D0"+ + "\u62D1\u62D2\u62D3\u62D4\u62D5\u62D6\u62D7\u62D8"+ + "\u62D9\u62DA\u62DB\u62DC\u62DD\u62DE\u62DF\u62E0"+ + "\u62E1\uFE7C\u62E2\u62E3\u62E4\u62E5\u62E6\u62E7"+ + "\u62E8\u62E9\u62EA\u62EB\u62EC\u62ED\u62EE\u62EF"+ + "\u62F0\u62F1\u62F2\u62F3\u62F4\u62F5\u62F6\u62F7"+ + "\u62F8\u62F9\u62FA\u62FB\u62FC\u62FD\u62FE\u62FF"+ + "\u6300\u6301\u6302\u6303\u6304\u6305\u6306\u6307"+ + "\u6308\u6309\u630A\u630B\u630C\u630D\u630E\u630F"+ + "\u6310\u6311\u6312\u6313\u6314\u6315\u6316\u6317"+ + "\u6318\u6319\u631A\u631B\u631C\u631D\u631E\u631F"+ + "\u6320\u6321\u6322\u6323\u6324\u6325\u6326\u6327"+ + "\u6328\u6329\u632A\u632B\u632C\u632D\u632E\u632F"+ + "\u6330\u6331\u6332\u6333\u6334\u6335\u6336\u6337"+ + "\u6338\u6339\u633A\u633B\u633C\u633D\u633E\u633F"+ + "\u6340\u6341\u6342\u6343\u6344\u6345\u6346\u6347"+ + "\u6348\u6349\u634A\u634B\u634C\u634D\u634E\u634F"+ + "\u6350\u6351\u6352\u6353\u6354\u6355\u6356\u6357"+ + "\u6358\u6359\u635A\u635B\u635C\u635D\u635E\u635F"+ + "\u6360\u6361\u6362\u6363\u6364\u6365\u6366\u6367"+ + "\u6368\u6369\u636A\u636B\u636C\u636D\u636E\u636F"+ + "\u6370\u6371\u6372\u6373\u6374\u6375\u6376\u6377"+ + "\u6378\u6379\u637A\u637B\u637C\u637D\u637E\u637F"+ + "\u6380\u6381\u6382\u6383\u6384\u6385\u6386\u6387"+ + "\u6388\u6389\u638A\u638B\u638C\u638D\u638E\u638F"+ + "\u6390\u6391\u6392\u6393\u6394\u6395\u6396\u6397"+ + "\u6398\u6399\u639A\u639B\u639C\u639D\u639E\u639F"+ + "\u63A0\u63A1\u63A2\uFE80\u63A3\u63A4\u63A5\u63A6"+ + "\u63A7\uFE81\u63A8\u63A9\u63AA\u63AB\u63AC\u63AD"+ + "\u63AE\u63AF\u63B0\u63B1\u63B2\u63B3\u63B4\u63B5"+ + "\u63B6\u63B7\u63B8\u63B9\u63BA\u63BB\u63BC\u63BD"+ + "\u63BE\u63BF\u63C0\u63C1\u63C2\u63C3\u63C4\u63C5"+ + "\u63C6\u63C7\u63C8\u63C9\u63CA\u63CB\u63CC\u63CD"+ + "\u63CE\u63CF\u63D0\u63D1\u63D2\u63D3\u63D4\u63D5"+ + "\u63D6\u63D7\u63D8\u63D9\u63DA\u63DB\u63DC\u63DD"+ + "\u63DE\u63DF\u63E0\u63E1\u63E2\u63E3\u63E4\u63E5"+ + "\u63E6\u63E7\u63E8\u63E9\u63EA\u63EB\u63EC\u63ED"+ + "\u63EE\u63EF\u63F0\u63F1\u63F2\u63F3\u63F4\u63F5"+ + "\u63F6\u63F7\u63F8\u63F9\uFE82\u63FA\u63FB\u63FC"+ + "\u63FD\u63FE\u63FF\u6400\u6401\u6402\u6403\u6404"+ + "\u6405\u6406\u6407\u6408\u6409\uFE83\u640A\u640B"+ + "\u640C\u640D\u640E\u640F\u6410\u6411\u6412\u6413"+ + "\u6414\u6415\u6416\u6417\u6418\u6419\u641A\u641B"+ + "\u641C\u641D\u641E\u641F\u6420\u6421\u6422\u6423"+ + "\u6424\u6425\u6426\u6427\u6428\u6429\u642A\u642B"+ + "\u642C\u642D\u642E\u642F\u6430\u6431\u6432\u6433"+ + "\u6434\u6435\u6436\u6437\u6438\u6439\u643A\u643B"+ + "\u643C\u643D\u643E\u643F\u6440\u6441\u6442\u6443"+ + "\u6444\u6445\u6446\u6447\u6448\u6449\u644A\u644B"+ + "\u644C\u644D\u644E\u644F\u6450\u6451\u6452\u6453"+ + "\u6454\u6455\u6456\u6457\u6458\u6459\u645A\u645B"+ + "\u645C\u645D\u645E\u645F\u6460\u6461\u6462\u6463"+ + "\u6464\u6465\u6466\u6467\u6468\u6469\u646A\u646B"+ + "\u646C\u646D\u646E\u646F\u6470\u6471\u6472\u6473"+ + "\u6474\u6475\u6476\u6477\u6478\u6479\u647A\u647B"+ + "\u647C\u647D\u647E\u647F\u6480\u6481\u6482\u6483"+ + "\u6484\u6485\u6486\u6487\u6488\u6489\u648A\u648B"+ + "\u648C\u648D\u648E\u648F\u6490\u6491\u6492\u6493"+ + "\u6494\u6495\u6496\u6497\u6498\u6499\u649A\u649B"+ + "\u649C\u649D\u649E\u649F\u64A0\u64A1\u64A2\u64A3"+ + "\u64A4\u64A5\u64A6\u64A7\u64A8\u64A9\u64AA\u64AB"+ + "\u64AC\u64AD\u64AE\u64AF\u64B0\u64B1\u64B2\u64B3"+ + "\u64B4\u64B5\u64B6\u64B7\u64B8\u64B9\u64BA\u64BB"+ + "\u64BC\u64BD\u64BE\u64BF\u64C0\u64C1\u64C2\u64C3"+ + "\u64C4\u64C5\u64C6\u64C7\u64C8\u64C9\u64CA\u64CB"+ + "\u64CC\u64CD\u64CE\u64CF\u64D0\u64D1\u64D2\u64D3"+ + "\u64D4\u64D5\u64D6\u64D7\u64D8\u64D9\u64DA\u64DB"+ + "\u64DC\u64DD\u64DE\u64DF\u64E0\u64E1\u64E2\u64E3"+ + "\u64E4\u64E5\u64E6\u64E7\u64E8\u64E9\u64EA\u64EB"+ + "\u64EC\u64ED\u64EE\u64EF\u64F0\u64F1\u64F2\u64F3"+ + "\u64F4\u64F5\u64F6\u64F7\u64F8\u64F9\u64FA\u64FB"+ + "\u64FC\u64FD\u64FE\u64FF\u6500\u6501\u6502\u6503"+ + "\u6504\u6505\u6506\u6507\u6508\u6509\u650A\u650B"+ + "\u650C\u650D\u650E\u650F\u6510\u6511\u6512\u6513"+ + "\u6514\u6515\u6516\u6517\u6518\u6519\u651A\u651B"+ + "\u651C\u651D\u651E\u651F\u6520\u6521\u6522\u6523"+ + "\u6524\u6525\u6526\u6527\u6528\u6529\u652A\u652B"+ + "\u652C\u652D\u652E\u652F\u6530\u6531\u6532\u6533"+ + "\u6534\u6535\u6536\u6537\u6538\u6539\u653A\u653B"+ + "\u653C\u653D\u653E\u653F\u6540\u6541\u6542\u6543"+ + "\u6544\u6545\u6546\u6547\u6548\u6549\u654A\u654B"+ + "\u654C\u654D\u654E\u654F\u6550\u6551\u6552\u6553"+ + "\u6554\u6555\u6556\u6557\u6558\u6559\u655A\u655B"+ + "\u655C\u655D\u655E\u655F\u6560\u6561\u6562\u6563"+ + "\u6564\u6565\u6566\u6567\u6568\u6569\u656A\u656B"+ + "\u656C\u656D\u656E\u656F\u6570\u6571\u6572\u6573"+ + "\u6574\u6575\u6576\u6577\u6578\u6579\u657A\u657B"+ + "\u657C\u657D\u657E\u657F\u6580\u6581\u6582\u6583"+ + "\u6584\u6585\u6586\u6587\u6588\u6589\u658A\u658B"+ + "\u658C\u658D\u658E\u658F\u6590\u6591\u6592\u6593"+ + "\u6594\u6595\u6596\u6597\u6598\u6599\u659A\u659B"+ + "\u659C\u659D\u659E\u659F\u65A0\u65A1\u65A2\u65A3"+ + "\u65A4\u65A5\u65A6\u65A7\u65A8\u65A9\u65AA\u65AB"+ + "\u65AC\u65AD\u65AE\u65AF\u65B0\u65B1\u65B2\u65B3"+ + "\u65B4\u65B5\u65B6\u65B7\u65B8\u65B9\u65BA\u65BB"+ + "\u65BC\u65BD\u65BE\u65BF\u65C0\u65C1\u65C2\uFE85"+ + "\u65C3\u65C4\u65C5\u65C6\u65C7\u65C8\u65C9\u65CA"+ + "\u65CB\u65CC\u65CD\u65CE\u65CF\u65D0\u65D1\u65D2"+ + "\u65D3\u65D4\u65D5\u65D6\u65D7\u65D8\u65D9\u65DA"+ + "\u65DB\u65DC\u65DD\u65DE\u65DF\u65E0\u65E1\u65E2"+ + "\u65E3\u65E4\u65E5\u65E6\u65E7\u65E8\u65E9\u65EA"+ + "\u65EB\u65EC\u65ED\u65EE\u65EF\u65F0\u65F1\u65F2"+ + "\u65F3\u65F4\uFE86\u65F5\u65F6\uFE87\u65F7\u65F8"+ + "\u65F9\u65FA\uFE88\uFE89\u65FB\uFE8A\uFE8B\u65FC"+ + "\u65FD\u65FE\u65FF\u6600\u6601\u6602\u6603\u6604"+ + "\u6605\u6606\u6607\u6608\u6609\u660A\u660B\u660C"+ + "\u660D\u660E\u660F\uFE8D\u6610\u6611\u6612\uFE8C"+ + "\u6613\u6614\u6615\u6616\u6617\u6618\u6619\u661A"+ + "\u661B\u661C\u661D\u661E\u661F\u6620\u6621\u6622"+ + "\u6623\u6624\u6625\u6626\u6627\u6628\uFE8F\uFE8E"+ + "\u6629\u662A\u662B\u662C\u662D\u662E\u662F\u6630"+ + "\u6631\u6632\u6633\u6634\u6635\u6636\u6637\u6638"+ + "\u6639\u663A\u663B\u663C\u663D\u663E\u663F\u6640"+ + "\u6641\u6642\u6643\u6644\u6645\u6646\u6647\u6648"+ + "\u6649\u664A\u664B\u664C\u664D\u664E\u664F\u6650"+ + "\u6651\u6652\u6653\u6654\u6655\u6656\u6657\u6658"+ + "\u6659\u665A\u665B\u665C\u665D\u665E\u665F\u6660"+ + "\u6661\u6662\u6663\u6664\u6665\u6666\u6667\u6668"+ + "\u6669\u666A\u666B\u666C\u666D\u666E\u666F\u6670"+ + "\u6671\u6672\u6673\u6674\u6675\u6676\u6677\u6678"+ + "\u6679\u667A\u667B\u667C\u667D\u667E\u667F\u6680"+ + "\u6681\u6682\u6683\u6684\u6685\u6686\u6687\u6688"+ + "\u6689\u668A\u668B\u668C\u668D\u668E\u668F\u6690"+ + "\u6691\u6692\u6693\u6694\u6695\u6696\u6697\u6698"+ + "\u6699\u669A\u669B\u669C\u669D\u669E\u669F\u66A0"+ + "\u66A1\u66A2\u66A3\u66A4\u66A5\u66A6\u66A7\u66A8"+ + "\u66A9\u66AA\u66AB\u66AC\u66AD\u66AE\u66AF\u66B0"+ + "\u66B1\u66B2\u66B3\u66B4\u66B5\u66B6\u66B7\u66B8"+ + "\u66B9\u66BA\u66BB\u66BC\u66BD\u66BE\u66BF\u66C0"+ + "\u66C1\u66C2\u66C3\u66C4\u66C5\u66C6\u66C7\u66C8"+ + "\u66C9\u66CA\u66CB\u66CC\u66CD\u66CE\u66CF\u66D0"+ + "\u66D1\u66D2\u66D3\u66D4\u66D5\u66D6\u66D7\u66D8"+ + "\u66D9\u66DA\u66DB\u66DC\u66DD\u66DE\u66DF\u66E0"+ + "\u66E1\u66E2\u66E3\u66E4\u66E5\u66E6\u66E7\u66E8"+ + "\u66E9\u66EA\u66EB\u66EC\u66ED\u66EE\u66EF\u66F0"+ + "\u66F1\u66F2\u66F3\u66F4\u66F5\u66F6\u66F7\u66F8"+ + "\u66F9\u66FA\u66FB\u66FC\u66FD\u66FE\u66FF\u6700"+ + "\u6701\u6702\u6703\u6704\u6705\u6706\u6707\u6708"+ + "\u6709\u670A\u670B\u670C\u670D\u670E\u670F\u6710"+ + "\u6711\u6712\u6713\u6714\u6715\u6716\u6717\u6718"+ + "\u6719\u671A\u671B\u671C\u671D\u671E\u671F\u6720"+ + "\u6721\u6722\u6723\u6724\u6725\u6726\u6727\u6728"+ + "\u6729\u672A\u672B\u672C\u672D\u672E\u672F\u6730"+ + "\u6731\u6732\u6733\u6734\u6735\u6736\u6737\u6738"+ + "\u6739\u673A\u673B\u673C\u673D\u673E\u673F\u6740"+ + "\u6741\u6742\u6743\u6744\u6745\u6746\u6747\u6748"+ + "\u6749\u674A\u674B\u674C\u674D\u674E\u674F\u6750"+ + "\u6751\u6752\u6753\u6754\u6755\u6756\u6757\u6758"+ + "\u6759\u675A\u675B\u675C\u675D\u675E\u675F\u6760"+ + "\u6761\u6762\u6763\u6764\u6765\u6766\u6767\u6768"+ + "\u6769\u676A\u676B\u676C\u676D\u676E\u676F\u6770"+ + "\u6771\u6772\u6773\u6774\u6775\u6776\u6777\u6778"+ + "\u6779\u677A\u677B\u677C\u677D\u677E\u677F\u6780"+ + "\u6781\u6782\u6783\u6784\u6785\u6786\u6787\u6788"+ + "\u6789\u678A\u678B\u678C\u678D\u678E\u678F\u6790"+ + "\u6791\u6792\u6793\u6794\u6795\u6796\u6797\u6798"+ + "\u6799\u679A\u679B\u679C\u679D\u679E\u679F\u67A0"+ + "\u67A1\u67A2\u67A3\u67A4\u67A5\u67A6\u67A7\u67A8"+ + "\u67A9\u67AA\u67AB\u67AC\u67AD\u67AE\u67AF\u67B0"+ + "\u67B1\u67B2\u67B3\u67B4\u67B5\u67B6\u67B7\u67B8"+ + "\u67B9\u67BA\u67BB\u67BC\u67BD\u67BE\u67BF\u67C0"+ + "\u67C1\u67C2\u67C3\u67C4\u67C5\u67C6\u67C7\u67C8"+ + "\u67C9\u67CA\u67CB\u67CC\u67CD\u67CE\u67CF\u67D0"+ + "\u67D1\u67D2\u67D3\u67D4\u67D5\u67D6\u67D7\u67D8"+ + "\u67D9\u67DA\u67DB\u67DC\u67DD\u67DE\u67DF\u67E0"+ + "\u67E1\u67E2\u67E3\u67E4\u67E5\u67E6\u67E7\u67E8"+ + "\u67E9\u67EA\u67EB\u67EC\u67ED\u67EE\u67EF\u67F0"+ + "\u67F1\u67F2\u67F3\u67F4\u67F5\u67F6\u67F7\u67F8"+ + "\u67F9\u67FA\u67FB\u67FC\u67FD\u67FE\u67FF\u6800"+ + "\u6801\u6802\u6803\u6804\u6805\u6806\u6807\u6808"+ + "\u6809\u680A\u680B\u680C\u680D\u680E\u680F\u6810"+ + "\u6811\u6812\u6813\u6814\u6815\u6816\u6817\u6818"+ + "\u6819\u681A\u681B\u681C\u681D\u681E\u681F\u6820"+ + "\u6821\u6822\u6823\u6824\u6825\u6826\u6827\u6828"+ + "\u6829\u682A\u682B\u682C\u682D\u682E\u682F\u6830"+ + "\u6831\u6832\u6833\u6834\u6835\u6836\u6837\u6838"+ + "\u6839\u683A\u683B\u683C\u683D\u683E\u683F\u6840"+ + "\u6841\u6842\u6843\u6844\u6845\u6846\u6847\u6848"+ + "\u6849\u684A\u684B\u684C\u684D\u684E\u684F\u6850"+ + "\u6851\u6852\u6853\u6854\u6855\u6856\u6857\u6858"+ + "\u6859\u685A\u685B\u685C\u685D\u685E\u685F\u6860"+ + "\u6861\u6862\u6863\u6864\u6865\u6866\u6867\u6868"+ + "\u6869\u686A\u686B\u686C\u686D\u686E\u686F\u6870"+ + "\u6871\u6872\u6873\u6874\u6875\u6876\u6877\u6878"+ + "\u6879\u687A\u687B\u687C\u687D\u687E\u687F\u6880"+ + "\u6881\u6882\u6883\u6884\u6885\u6886\u6887\u6888"+ + "\u6889\u688A\u688B\u688C\u688D\u688E\u688F\u6890"+ + "\u6891\u6892\u6893\u6894\u6895\u6896\u6897\u6898"+ + "\u6899\u689A\u689B\u689C\u689D\u689E\u689F\u68A0"+ + "\u68A1\u68A2\u68A3\u68A4\u68A5\u68A6\u68A7\u68A8"+ + "\u68A9\u68AA\u68AB\u68AC\u68AD\u68AE\u68AF\u68B0"+ + "\u68B1\u68B2\u68B3\u68B4\u68B5\u68B6\u68B7\u68B8"+ + "\u68B9\u68BA\u68BB\u68BC\u68BD\u68BE\u68BF\u68C0"+ + "\u68C1\u68C2\u68C3\u68C4\u68C5\u68C6\u68C7\u68C8"+ + "\u68C9\u68CA\u68CB\u68CC\u68CD\u68CE\u68CF\u68D0"+ + "\u68D1\u68D2\u68D3\u68D4\u68D5\u68D6\u68D7\u68D8"+ + "\u68D9\u68DA\u68DB\u68DC\u68DD\u68DE\u68DF\u68E0"+ + "\u68E1\u68E2\u68E3\u68E4\u68E5\u68E6\u68E7\uFE96"+ + "\u68E8\u68E9\u68EA\u68EB\u68EC\u68ED\u68EE\u68EF"+ + "\u68F0\u68F1\u68F2\u68F3\u68F4\u68F5\u68F6\u68F7"+ + "\u68F8\u68F9\u68FA\u68FB\u68FC\u68FD\u68FE\u68FF"+ + "\u6900\u6901\u6902\u6903\u6904\u6905\u6906\u6907"+ + "\u6908\u6909\u690A\u690B\u690C\u690D\u690E\uFE93"+ + "\uFE94\uFE95\uFE97\uFE92\u690F\u6910\u6911\u6912"+ + "\u6913\u6914\u6915\u6916\u6917\u6918\u6919\u691A"+ + "\u691B\u691C\u691D\u691E\u691F\u6920\u6921\u6922"+ + "\u6923\u6924\u6925\u6926\u6927\u6928\u6929\u692A"+ + "\u692B\u692C\u692D\u692E\u692F\u6930\u6931\u6932"+ + "\u6933\u6934\u6935\u6936\u6937\u6938\u6939\u693A"+ + "\u693B\u693C\u693D\u693E\u693F\u6940\u6941\u6942"+ + "\u6943\u6944\u6945\u6946\u6947\u6948\u6949\u694A"+ + "\u694B\u694C\u694D\u694E\u694F\u6950\u6951\u6952"+ + "\u6953\u6954\u6955\u6956\u6957\u6958\u6959\u695A"+ + "\u695B\u695C\u695D\u695E\u695F\u6960\u6961\u6962"+ + "\u6963\u6964\u6965\u6966\u6967\u6968\u6969\u696A"+ + "\u696B\u696C\u696D\u696E\u696F\u6970\u6971\u6972"+ + "\u6973\u6974\u6975\u6976\u6977\u6978\u6979\u697A"+ + "\u697B\u697C\u697D\uFE98\uFE99\uFE9A\uFE9B\uFE9C"+ + "\uFE9D\uFE9E\u697E\u697F\u6980\u6981\u6982\u6983"+ + "\u6984\u6985\u6986\u6987\u6988\u6989\u698A\u698B"+ + "\u698C\u698D\u698E\u698F\u6990\u6991\u6992\u6993"+ + "\u6994\u6995\u6996\u6997\u6998\u6999\u699A\u699B"+ + "\u699C\u699D\u699E\u699F\u69A0\u69A1\u69A2\u69A3"+ + "\u69A4\u69A5\u69A6\u69A7\u69A8\u69A9\u69AA\u69AB"+ + "\u69AC\u69AD\u69AE\u69AF\u69B0\u69B1\u69B2\u69B3"+ + "\u69B4\u69B5\u69B6\u69B7\u69B8\u69B9\u69BA\u69BB"+ + "\u69BC\u69BD\u69BE\u69BF\u69C0\u69C1\u69C2\u69C3"+ + "\u69C4\u69C5\u69C6\u69C7\u69C8\u69C9\u69CA\u69CB"+ + "\u69CC\u69CD\u69CE\u69CF\u69D0\u69D1\u69D2\u69D3"+ + "\u69D4\u69D5\u69D6\u69D7\u69D8\u69D9\u69DA\u69DB"+ + "\u69DC\u69DD\u69DE\u69DF\u69E0\u69E1\u69E2\u69E3"+ + "\u69E4\u69E5\u69E6\u69E7\u69E8\u69E9\u69EA\u69EB"+ + "\u69EC\u69ED\u69EE\u69EF\u69F0\u69F1\u69F2\u69F3"+ + "\u69F4\u69F5\u69F6\u69F7\u69F8\u69F9\u69FA\u69FB"+ + "\u69FC\u69FD\u69FE\u69FF\u6A00\u6A01\u6A02\u6A03"+ + "\u6A04\u6A05\u6A06\u6A07\u6A08\u6A09\u6A0A\u6A0B"+ + "\u6A0C\u6A0D\u6A0E\u6A0F\u6A10\u6A11\uFE9F\u6A12"+ + "\u6A13\u6A14\u6A15\u6A16\u6A17\u6A18\u6A19\u6A1A"+ + "\u6A1B\u6A1C\u6A1D\u6A1E\u6A1F\u6A20\u6A21\u6A22"+ + "\u6A23\u6A24\u6A25\u6A26\u6A27\u6A28\u6A29\u6A2A"+ + "\u6A2B\u6A2C\u6A2D\u6A2E\u6A2F\u6A30\u6A31\u6A32"+ + "\u6A33\u6A34\u6A35\u6A36\u6A37\u6A38\u6A39\u6A3A"+ + "\u6A3B\u6A3C\u6A3D\u6A3E\u6A3F\u6A40\u6A41\u6A42"+ + "\u6A43\u6A44\u6A45\u6A46\u6A47\u6A48\u6A49\u6A4A"+ + "\u6A4B\u6A4C\u6A4D\u6A4E\u6A4F\u6A50\u6A51\u6A52"+ + "\u6A53\u6A54\u6A55\u6A56\u6A57\u6A58\u6A59\u6A5A"+ + "\u6A5B\u6A5C\u6A5D\u6A5E\u6A5F\u6A60\u6A61\u6A62"+ + "\uD2BB\uB6A1\u8140\uC6DF\u8141\u8142\u8143\uCDF2"+ + "\uD5C9\uC8FD\uC9CF\uCFC2\uD8A2\uB2BB\uD3EB\u8144"+ + "\uD8A4\uB3F3\u8145\uD7A8\uC7D2\uD8A7\uCAC0\u8146"+ + "\uC7F0\uB1FB\uD2B5\uB4D4\uB6AB\uCBBF\uD8A9\u8147"+ + "\u8148\u8149\uB6AA\u814A\uC1BD\uD1CF\u814B\uC9A5"+ + "\uD8AD\u814C\uB8F6\uD1BE\uE3DC\uD6D0\u814D\u814E"+ + "\uB7E1\u814F\uB4AE\u8150\uC1D9\u8151\uD8BC\u8152"+ + "\uCDE8\uB5A4\uCEAA\uD6F7\u8153\uC0F6\uBED9\uD8AF"+ + "\u8154\u8155\u8156\uC4CB\u8157\uBEC3\u8158\uD8B1"+ + "\uC3B4\uD2E5\u8159\uD6AE\uCEDA\uD5A7\uBAF5\uB7A6"+ + "\uC0D6\u815A\uC6B9\uC5D2\uC7C7\u815B\uB9D4\u815C"+ + "\uB3CB\uD2D2\u815D\u815E\uD8BF\uBEC5\uC6F2\uD2B2"+ + "\uCFB0\uCFE7\u815F\u8160\u8161\u8162\uCAE9\u8163"+ + "\u8164\uD8C0\u8165\u8166\u8167\u8168\u8169\u816A"+ + "\uC2F2\uC2D2\u816B\uC8E9\u816C\u816D\u816E\u816F"+ + "\u8170\u8171\u8172\u8173\u8174\u8175\uC7AC\u8176"+ + "\u8177\u8178\u8179\u817A\u817B\u817C\uC1CB\u817D"+ + "\uD3E8\uD5F9\u817E\uCAC2\uB6FE\uD8A1\uD3DA\uBFF7"+ + "\u8180\uD4C6\uBBA5\uD8C1\uCEE5\uBEAE\u8181\u8182"+ + "\uD8A8\u8183\uD1C7\uD0A9\u8184\u8185\u8186\uD8BD"+ + "\uD9EF\uCDF6\uBFBA\u8187\uBDBB\uBAA5\uD2E0\uB2FA"+ + "\uBAE0\uC4B6\u8188\uCFED\uBEA9\uCDA4\uC1C1\u8189"+ + "\u818A\u818B\uC7D7\uD9F1\u818C\uD9F4\u818D\u818E"+ + "\u818F\u8190\uC8CB\uD8E9\u8191\u8192\u8193\uD2DA"+ + "\uCAB2\uC8CA\uD8EC\uD8EA\uD8C6\uBDF6\uC6CD\uB3F0"+ + "\u8194\uD8EB\uBDF1\uBDE9\u8195\uC8D4\uB4D3\u8196"+ + "\u8197\uC2D8\u8198\uB2D6\uD7D0\uCACB\uCBFB\uD5CC"+ + "\uB8B6\uCFC9\u8199\u819A\u819B\uD9DA\uD8F0\uC7AA"+ + "\u819C\uD8EE\u819D\uB4FA\uC1EE\uD2D4\u819E\u819F"+ + "\uD8ED\u81A0\uD2C7\uD8EF\uC3C7\u81A1\u81A2\u81A3"+ + "\uD1F6\u81A4\uD6D9\uD8F2\u81A5\uD8F5\uBCFE\uBCDB"+ + "\u81A6\u81A7\u81A8\uC8CE\u81A9\uB7DD\u81AA\uB7C2"+ + "\u81AB\uC6F3\u81AC\u81AD\u81AE\u81AF\u81B0\u81B1"+ + "\u81B2\uD8F8\uD2C1\u81B3\u81B4\uCEE9\uBCBF\uB7FC"+ + "\uB7A5\uD0DD\u81B5\u81B6\u81B7\u81B8\u81B9\uD6DA"+ + "\uD3C5\uBBEF\uBBE1\uD8F1\u81BA\u81BB\uC9A1\uCEB0"+ + "\uB4AB\u81BC\uD8F3\u81BD\uC9CB\uD8F6\uC2D7\uD8F7"+ + "\u81BE\u81BF\uCEB1\uD8F9\u81C0\u81C1\u81C2\uB2AE"+ + "\uB9C0\u81C3\uD9A3\u81C4\uB0E9\u81C5\uC1E6\u81C6"+ + "\uC9EC\u81C7\uCBC5\u81C8\uCBC6\uD9A4\u81C9\u81CA"+ + "\u81CB\u81CC\u81CD\uB5E8\u81CE\u81CF\uB5AB\u81D0"+ + "\u81D1\u81D2\u81D3\u81D4\u81D5\uCEBB\uB5CD\uD7A1"+ + "\uD7F4\uD3D3\u81D6\uCCE5\u81D7\uBACE\u81D8\uD9A2"+ + "\uD9DC\uD3E0\uD8FD\uB7F0\uD7F7\uD8FE\uD8FA\uD9A1"+ + "\uC4E3\u81D9\u81DA\uD3B6\uD8F4\uD9DD\u81DB\uD8FB"+ + "\u81DC\uC5E5\u81DD\u81DE\uC0D0\u81DF\u81E0\uD1F0"+ + "\uB0DB\u81E1\u81E2\uBCD1\uD9A6\u81E3\uD9A5\u81E4"+ + "\u81E5\u81E6\u81E7\uD9AC\uD9AE\u81E8\uD9AB\uCAB9"+ + "\u81E9\u81EA\u81EB\uD9A9\uD6B6\u81EC\u81ED\u81EE"+ + "\uB3DE\uD9A8\u81EF\uC0FD\u81F0\uCACC\u81F1\uD9AA"+ + "\u81F2\uD9A7\u81F3\u81F4\uD9B0\u81F5\u81F6\uB6B1"+ + "\u81F7\u81F8\u81F9\uB9A9\u81FA\uD2C0\u81FB\u81FC"+ + "\uCFC0\u81FD\u81FE\uC2C2\u8240\uBDC4\uD5EC\uB2E0"+ + "\uC7C8\uBFEB\uD9AD\u8241\uD9AF\u8242\uCEEA\uBAEE"+ + "\u8243\u8244\u8245\u8246\u8247\uC7D6\u8248\u8249"+ + "\u824A\u824B\u824C\u824D\u824E\u824F\u8250\uB1E3"+ + "\u8251\u8252\u8253\uB4D9\uB6ED\uD9B4\u8254\u8255"+ + "\u8256\u8257\uBFA1\u8258\u8259\u825A\uD9DE\uC7CE"+ + "\uC0FE\uD9B8\u825B\u825C\u825D\u825E\u825F\uCBD7"+ + "\uB7FD\u8260\uD9B5\u8261\uD9B7\uB1A3\uD3E1\uD9B9"+ + "\u8262\uD0C5\u8263\uD9B6\u8264\u8265\uD9B1\u8266"+ + "\uD9B2\uC1A9\uD9B3\u8267\u8268\uBCF3\uD0DE\uB8A9"+ + "\u8269\uBEE3\u826A\uD9BD\u826B\u826C\u826D\u826E"+ + "\uD9BA\u826F\uB0B3\u8270\u8271\u8272\uD9C2\u8273"; + + private static final String innerEncoderIndex5= + "\u8274\u8275\u8276\u8277\u8278\u8279\u827A\u827B"+ + "\u827C\u827D\u827E\u8280\uD9C4\uB1B6\u8281\uD9BF"+ + "\u8282\u8283\uB5B9\u8284\uBEF3\u8285\u8286\u8287"+ + "\uCCC8\uBAF2\uD2D0\u8288\uD9C3\u8289\u828A\uBDE8"+ + "\u828B\uB3AB\u828C\u828D\u828E\uD9C5\uBEEB\u828F"+ + "\uD9C6\uD9BB\uC4DF\u8290\uD9BE\uD9C1\uD9C0\u8291"+ + "\u8292\u8293\u8294\u8295\u8296\u8297\u8298\u8299"+ + "\u829A\u829B\uD5AE\u829C\uD6B5\u829D\uC7E3\u829E"+ + "\u829F\u82A0\u82A1\uD9C8\u82A2\u82A3\u82A4\uBCD9"+ + "\uD9CA\u82A5\u82A6\u82A7\uD9BC\u82A8\uD9CB\uC6AB"+ + "\u82A9\u82AA\u82AB\u82AC\u82AD\uD9C9\u82AE\u82AF"+ + "\u82B0\u82B1\uD7F6\u82B2\uCDA3\u82B3\u82B4\u82B5"+ + "\u82B6\u82B7\u82B8\u82B9\u82BA\uBDA1\u82BB\u82BC"+ + "\u82BD\u82BE\u82BF\u82C0\uD9CC\u82C1\u82C2\u82C3"+ + "\u82C4\u82C5\u82C6\u82C7\u82C8\u82C9\uC5BC\uCDB5"+ + "\u82CA\u82CB\u82CC\uD9CD\u82CD\u82CE\uD9C7\uB3A5"+ + "\uBFFE\u82CF\u82D0\u82D1\u82D2\uB8B5\u82D3\u82D4"+ + "\uC0FC\u82D5\u82D6\u82D7\u82D8\uB0F8\u82D9\u82DA"+ + "\u82DB\u82DC\u82DD\u82DE\u82DF\u82E0\u82E1\u82E2"+ + "\u82E3\u82E4\u82E5\u82E6\u82E7\u82E8\u82E9\u82EA"+ + "\u82EB\u82EC\u82ED\uB4F6\u82EE\uD9CE\u82EF\uD9CF"+ + "\uB4A2\uD9D0\u82F0\u82F1\uB4DF\u82F2\u82F3\u82F4"+ + "\u82F5\u82F6\uB0C1\u82F7\u82F8\u82F9\u82FA\u82FB"+ + "\u82FC\u82FD\uD9D1\uC9B5\u82FE\u8340\u8341\u8342"+ + "\u8343\u8344\u8345\u8346\u8347\u8348\u8349\u834A"+ + "\u834B\u834C\u834D\u834E\u834F\u8350\u8351\uCFF1"+ + "\u8352\u8353\u8354\u8355\u8356\u8357\uD9D2\u8358"+ + "\u8359\u835A\uC1C5\u835B\u835C\u835D\u835E\u835F"+ + "\u8360\u8361\u8362\u8363\u8364\u8365\uD9D6\uC9AE"+ + "\u8366\u8367\u8368\u8369\uD9D5\uD9D4\uD9D7\u836A"+ + "\u836B\u836C\u836D\uCBDB\u836E\uBDA9\u836F\u8370"+ + "\u8371\u8372\u8373\uC6A7\u8374\u8375\u8376\u8377"+ + "\u8378\u8379\u837A\u837B\u837C\u837D\uD9D3\uD9D8"+ + "\u837E\u8380\u8381\uD9D9\u8382\u8383\u8384\u8385"+ + "\u8386\u8387\uC8E5\u8388\u8389\u838A\u838B\u838C"+ + "\u838D\u838E\u838F\u8390\u8391\u8392\u8393\u8394"+ + "\u8395\uC0DC\u8396\u8397\u8398\u8399\u839A\u839B"+ + "\u839C\u839D\u839E\u839F\u83A0\u83A1\u83A2\u83A3"+ + "\u83A4\u83A5\u83A6\u83A7\u83A8\u83A9\u83AA\u83AB"+ + "\u83AC\u83AD\u83AE\u83AF\u83B0\u83B1\u83B2\uB6F9"+ + "\uD8A3\uD4CA\u83B3\uD4AA\uD0D6\uB3E4\uD5D7\u83B4"+ + "\uCFC8\uB9E2\u83B5\uBFCB\u83B6\uC3E2\u83B7\u83B8"+ + "\u83B9\uB6D2\u83BA\u83BB\uCDC3\uD9EE\uD9F0\u83BC"+ + "\u83BD\u83BE\uB5B3\u83BF\uB6B5\u83C0\u83C1\u83C2"+ + "\u83C3\u83C4\uBEA4\u83C5\u83C6\uC8EB\u83C7\u83C8"+ + "\uC8AB\u83C9\u83CA\uB0CB\uB9AB\uC1F9\uD9E2\u83CB"+ + "\uC0BC\uB9B2\u83CC\uB9D8\uD0CB\uB1F8\uC6E4\uBEDF"+ + "\uB5E4\uD7C8\u83CD\uD1F8\uBCE6\uCADE\u83CE\u83CF"+ + "\uBCBD\uD9E6\uD8E7\u83D0\u83D1\uC4DA\u83D2\u83D3"+ + "\uB8D4\uC8BD\u83D4\u83D5\uB2E1\uD4D9\u83D6\u83D7"+ + "\u83D8\u83D9\uC3B0\u83DA\u83DB\uC3E1\uDAA2\uC8DF"+ + "\u83DC\uD0B4\u83DD\uBEFC\uC5A9\u83DE\u83DF\u83E0"+ + "\uB9DA\u83E1\uDAA3\u83E2\uD4A9\uDAA4\u83E3\u83E4"+ + "\u83E5\u83E6\u83E7\uD9FB\uB6AC\u83E8\u83E9\uB7EB"+ + "\uB1F9\uD9FC\uB3E5\uBEF6\u83EA\uBFF6\uD2B1\uC0E4"+ + "\u83EB\u83EC\u83ED\uB6B3\uD9FE\uD9FD\u83EE\u83EF"+ + "\uBEBB\u83F0\u83F1\u83F2\uC6E0\u83F3\uD7BC\uDAA1"+ + "\u83F4\uC1B9\u83F5\uB5F2\uC1E8\u83F6\u83F7\uBCF5"+ + "\u83F8\uB4D5\u83F9\u83FA\u83FB\u83FC\u83FD\u83FE"+ + "\u8440\u8441\u8442\uC1DD\u8443\uC4FD\u8444\u8445"+ + "\uBCB8\uB7B2\u8446\u8447\uB7EF\u8448\u8449\u844A"+ + "\u844B\u844C\u844D\uD9EC\u844E\uC6BE\u844F\uBFAD"+ + "\uBBCB\u8450\u8451\uB5CA\u8452\uDBC9\uD0D7\u8453"+ + "\uCDB9\uB0BC\uB3F6\uBBF7\uDBCA\uBAAF\u8454\uD4E4"+ + "\uB5B6\uB5F3\uD8D6\uC8D0\u8455\u8456\uB7D6\uC7D0"+ + "\uD8D7\u8457\uBFAF\u8458\u8459\uDBBB\uD8D8\u845A"+ + "\u845B\uD0CC\uBBAE\u845C\u845D\u845E\uEBBE\uC1D0"+ + "\uC1F5\uD4F2\uB8D5\uB4B4\u845F\uB3F5\u8460\u8461"+ + "\uC9BE\u8462\u8463\u8464\uC5D0\u8465\u8466\u8467"+ + "\uC5D9\uC0FB\u8468\uB1F0\u8469\uD8D9\uB9CE\u846A"+ + "\uB5BD\u846B\u846C\uD8DA\u846D\u846E\uD6C6\uCBA2"+ + "\uC8AF\uC9B2\uB4CC\uBFCC\u846F\uB9F4\u8470\uD8DB"+ + "\uD8DC\uB6E7\uBCC1\uCCEA\u8471\u8472\u8473\u8474"+ + "\u8475\u8476\uCFF7\u8477\uD8DD\uC7B0\u8478\u8479"+ + "\uB9D0\uBDA3\u847A\u847B\uCCDE\u847C\uC6CA\u847D"+ + "\u847E\u8480\u8481\u8482\uD8E0\u8483\uD8DE\u8484"+ + "\u8485\uD8DF\u8486\u8487\u8488\uB0FE\u8489\uBEE7"+ + "\u848A\uCAA3\uBCF4\u848B\u848C\u848D\u848E\uB8B1"+ + "\u848F\u8490\uB8EE\u8491\u8492\u8493\u8494\u8495"+ + "\u8496\u8497\u8498\u8499\u849A\uD8E2\u849B\uBDCB"+ + "\u849C\uD8E4\uD8E3\u849D\u849E\u849F\u84A0\u84A1"+ + "\uC5FC\u84A2\u84A3\u84A4\u84A5\u84A6\u84A7\u84A8"+ + "\uD8E5\u84A9\u84AA\uD8E6\u84AB\u84AC\u84AD\u84AE"+ + "\u84AF\u84B0\u84B1\uC1A6\u84B2\uC8B0\uB0EC\uB9A6"+ + "\uBCD3\uCEF1\uDBBD\uC1D3\u84B3\u84B4\u84B5\u84B6"+ + "\uB6AF\uD6FA\uC5AC\uBDD9\uDBBE\uDBBF\u84B7\u84B8"+ + "\u84B9\uC0F8\uBEA2\uC0CD\u84BA\u84BB\u84BC\u84BD"+ + "\u84BE\u84BF\u84C0\u84C1\u84C2\u84C3\uDBC0\uCAC6"+ + "\u84C4\u84C5\u84C6\uB2AA\u84C7\u84C8\u84C9\uD3C2"+ + "\u84CA\uC3E3\u84CB\uD1AB\u84CC\u84CD\u84CE\u84CF"+ + "\uDBC2\u84D0\uC0D5\u84D1\u84D2\u84D3\uDBC3\u84D4"+ + "\uBFB1\u84D5\u84D6\u84D7\u84D8\u84D9\u84DA\uC4BC"+ + "\u84DB\u84DC\u84DD\u84DE\uC7DA\u84DF\u84E0\u84E1"+ + "\u84E2\u84E3\u84E4\u84E5\u84E6\u84E7\u84E8\u84E9"+ + "\uDBC4\u84EA\u84EB\u84EC\u84ED\u84EE\u84EF\u84F0"+ + "\u84F1\uD9E8\uC9D7\u84F2\u84F3\u84F4\uB9B4\uCEF0"+ + "\uD4C8\u84F5\u84F6\u84F7\u84F8\uB0FC\uB4D2\u84F9"+ + "\uD0D9\u84FA\u84FB\u84FC\u84FD\uD9E9\u84FE\uDECB"+ + "\uD9EB\u8540\u8541\u8542\u8543\uD8B0\uBBAF\uB1B1"+ + "\u8544\uB3D7\uD8CE\u8545\u8546\uD4D1\u8547\u8548"+ + "\uBDB3\uBFEF\u8549\uCFBB\u854A\u854B\uD8D0\u854C"+ + "\u854D\u854E\uB7CB\u854F\u8550\u8551\uD8D1\u8552"+ + "\u8553\u8554\u8555\u8556\u8557\u8558\u8559\u855A"+ + "\u855B\uC6A5\uC7F8\uD2BD\u855C\u855D\uD8D2\uC4E4"+ + "\u855E\uCAAE\u855F\uC7A7\u8560\uD8A6\u8561\uC9FD"+ + "\uCEE7\uBBDC\uB0EB\u8562\u8563\u8564\uBBAA\uD0AD"+ + "\u8565\uB1B0\uD7E4\uD7BF\u8566\uB5A5\uC2F4\uC4CF"+ + "\u8567\u8568\uB2A9\u8569\uB2B7\u856A\uB1E5\uDFB2"+ + "\uD5BC\uBFA8\uC2AC\uD8D5\uC2B1\u856B\uD8D4\uCED4"+ + "\u856C\uDAE0\u856D\uCEC0\u856E\u856F\uD8B4\uC3AE"+ + "\uD3A1\uCEA3\u8570\uBCB4\uC8B4\uC2D1\u8571\uBEED"+ + "\uD0B6\u8572\uDAE1\u8573\u8574\u8575\u8576\uC7E4"+ + "\u8577\u8578\uB3A7\u8579\uB6F2\uCCFC\uC0FA\u857A"+ + "\u857B\uC0F7\u857C\uD1B9\uD1E1\uD8C7\u857D\u857E"+ + "\u8580\u8581\u8582\u8583\u8584\uB2DE\u8585\u8586"+ + "\uC0E5\u8587\uBAF1\u8588\u8589\uD8C8\u858A\uD4AD"+ + "\u858B\u858C\uCFE1\uD8C9\u858D\uD8CA\uCFC3\u858E"+ + "\uB3F8\uBEC7\u858F\u8590\u8591\u8592\uD8CB\u8593"+ + "\u8594\u8595\u8596\u8597\u8598\u8599\uDBCC\u859A"+ + "\u859B\u859C\u859D\uC8A5\u859E\u859F\u85A0\uCFD8"+ + "\u85A1\uC8FE\uB2CE\u85A2\u85A3\u85A4\u85A5\u85A6"+ + "\uD3D6\uB2E6\uBCB0\uD3D1\uCBAB\uB7B4\u85A7\u85A8"+ + "\u85A9\uB7A2\u85AA\u85AB\uCAE5\u85AC\uC8A1\uCADC"+ + "\uB1E4\uD0F0\u85AD\uC5D1\u85AE\u85AF\u85B0\uDBC5"+ + "\uB5FE\u85B1\u85B2\uBFDA\uB9C5\uBEE4\uC1ED\u85B3"+ + "\uDFB6\uDFB5\uD6BB\uBDD0\uD5D9\uB0C8\uB6A3\uBFC9"+ + "\uCCA8\uDFB3\uCAB7\uD3D2\u85B4\uD8CF\uD2B6\uBAC5"+ + "\uCBBE\uCCBE\u85B5\uDFB7\uB5F0\uDFB4\u85B6\u85B7"+ + "\u85B8\uD3F5\u85B9\uB3D4\uB8F7\u85BA\uDFBA\u85BB"+ + "\uBACF\uBCAA\uB5F5\u85BC\uCDAC\uC3FB\uBAF3\uC0F4"+ + "\uCDC2\uCFF2\uDFB8\uCFC5\u85BD\uC2C0\uDFB9\uC2F0"+ + "\u85BE\u85BF\u85C0\uBEFD\u85C1\uC1DF\uCDCC\uD2F7"+ + "\uB7CD\uDFC1\u85C2\uDFC4\u85C3\u85C4\uB7F1\uB0C9"+ + "\uB6D6\uB7D4\u85C5\uBAAC\uCCFD\uBFD4\uCBB1\uC6F4"+ + "\u85C6\uD6A8\uDFC5\u85C7\uCEE2\uB3B3\u85C8\u85C9"+ + "\uCEFC\uB4B5\u85CA\uCEC7\uBAF0\u85CB\uCEE1\u85CC"+ + "\uD1BD\u85CD\u85CE\uDFC0\u85CF\u85D0\uB4F4\u85D1"+ + "\uB3CA\u85D2\uB8E6\uDFBB\u85D3\u85D4\u85D5\u85D6"+ + "\uC4C5\u85D7\uDFBC\uDFBD\uDFBE\uC5BB\uDFBF\uDFC2"+ + "\uD4B1\uDFC3\u85D8\uC7BA\uCED8\u85D9\u85DA\u85DB"+ + "\u85DC\u85DD\uC4D8\u85DE\uDFCA\u85DF\uDFCF\u85E0"+ + "\uD6DC\u85E1\u85E2\u85E3\u85E4\u85E5\u85E6\u85E7"+ + "\u85E8\uDFC9\uDFDA\uCEB6\u85E9\uBAC7\uDFCE\uDFC8"+ + "\uC5DE\u85EA\u85EB\uC9EB\uBAF4\uC3FC\u85EC\u85ED"+ + "\uBED7\u85EE\uDFC6\u85EF\uDFCD\u85F0\uC5D8\u85F1"+ + "\u85F2\u85F3\u85F4\uD5A6\uBACD\u85F5\uBECC\uD3BD"+ + "\uB8C0\u85F6\uD6E4\u85F7\uDFC7\uB9BE\uBFA7\u85F8"+ + "\u85F9\uC1FC\uDFCB\uDFCC\u85FA\uDFD0\u85FB\u85FC"+ + "\u85FD\u85FE\u8640\uDFDB\uDFE5\u8641\uDFD7\uDFD6"+ + "\uD7C9\uDFE3\uDFE4\uE5EB\uD2A7\uDFD2\u8642\uBFA9"+ + "\u8643\uD4DB\u8644\uBFC8\uDFD4\u8645\u8646\u8647"+ + "\uCFCC\u8648\u8649\uDFDD\u864A\uD1CA\u864B\uDFDE"+ + "\uB0A7\uC6B7\uDFD3\u864C\uBAE5\u864D\uB6DF\uCDDB"+ + "\uB9FE\uD4D5\u864E\u864F\uDFDF\uCFEC\uB0A5\uDFE7"+ + "\uDFD1\uD1C6\uDFD5\uDFD8\uDFD9\uDFDC\u8650\uBBA9"+ + "\u8651\uDFE0\uDFE1\u8652\uDFE2\uDFE6\uDFE8\uD3B4"+ + "\u8653\u8654\u8655\u8656\u8657\uB8E7\uC5B6\uDFEA"+ + "\uC9DA\uC1A8\uC4C4\u8658\u8659\uBFDE\uCFF8\u865A"+ + "\u865B\u865C\uD5DC\uDFEE\u865D\u865E\u865F\u8660"+ + "\u8661\u8662\uB2B8\u8663\uBADF\uDFEC\u8664\uDBC1"+ + "\u8665\uD1E4\u8666\u8667\u8668\u8669\uCBF4\uB4BD"+ + "\u866A\uB0A6\u866B\u866C\u866D\u866E\u866F\uDFF1"+ + "\uCCC6\uDFF2\u8670\u8671\uDFED\u8672\u8673\u8674"+ + "\u8675\u8676\u8677\uDFE9\u8678\u8679\u867A\u867B"+ + "\uDFEB\u867C\uDFEF\uDFF0\uBBBD\u867D\u867E\uDFF3"+ + "\u8680\u8681\uDFF4\u8682\uBBA3\u8683\uCADB\uCEA8"+ + "\uE0A7\uB3AA\u8684\uE0A6\u8685\u8686\u8687\uE0A1"+ + "\u8688\u8689\u868A\u868B\uDFFE\u868C\uCDD9\uDFFC"+ + "\u868D\uDFFA\u868E\uBFD0\uD7C4\u868F\uC9CC\u8690"+ + "\u8691\uDFF8\uB0A1\u8692\u8693\u8694\u8695\u8696"+ + "\uDFFD\u8697\u8698\u8699\u869A\uDFFB\uE0A2\u869B"+ + "\u869C\u869D\u869E\u869F\uE0A8\u86A0\u86A1\u86A2"+ + "\u86A3\uB7C8\u86A4\u86A5\uC6A1\uC9B6\uC0B2\uDFF5"+ + "\u86A6\u86A7\uC5BE\u86A8\uD8C4\uDFF9\uC4F6\u86A9"+ + "\u86AA\u86AB\u86AC\u86AD\u86AE\uE0A3\uE0A4\uE0A5"+ + "\uD0A5\u86AF\u86B0\uE0B4\uCCE4\u86B1\uE0B1\u86B2"+ + "\uBFA6\uE0AF\uCEB9\uE0AB\uC9C6\u86B3\u86B4\uC0AE"+ + "\uE0AE\uBAED\uBAB0\uE0A9\u86B5\u86B6\u86B7\uDFF6"+ + "\u86B8\uE0B3\u86B9\u86BA\uE0B8\u86BB\u86BC\u86BD"+ + "\uB4AD\uE0B9\u86BE\u86BF\uCFB2\uBAC8\u86C0\uE0B0"+ + "\u86C1\u86C2\u86C3\u86C4\u86C5\u86C6\u86C7\uD0FA"+ + "\u86C8\u86C9\u86CA\u86CB\u86CC\u86CD\u86CE\u86CF"+ + "\u86D0\uE0AC\u86D1\uD4FB\u86D2\uDFF7\u86D3\uC5E7"+ + "\u86D4\uE0AD\u86D5\uD3F7\u86D6\uE0B6\uE0B7\u86D7"+ + "\u86D8\u86D9\u86DA\u86DB\uE0C4\uD0E1\u86DC\u86DD"+ + "\u86DE\uE0BC\u86DF\u86E0\uE0C9\uE0CA\u86E1\u86E2"+ + "\u86E3\uE0BE\uE0AA\uC9A4\uE0C1\u86E4\uE0B2\u86E5"+ + "\u86E6\u86E7\u86E8\u86E9\uCAC8\uE0C3\u86EA\uE0B5"+ + "\u86EB\uCECB\u86EC\uCBC3\uE0CD\uE0C6\uE0C2\u86ED"+ + "\uE0CB\u86EE\uE0BA\uE0BF\uE0C0\u86EF\u86F0\uE0C5"+ + "\u86F1\u86F2\uE0C7\uE0C8\u86F3\uE0CC\u86F4\uE0BB"+ + "\u86F5\u86F6\u86F7\u86F8\u86F9\uCBD4\uE0D5\u86FA"+ + "\uE0D6\uE0D2\u86FB\u86FC\u86FD\u86FE\u8740\u8741"+ + "\uE0D0\uBCCE\u8742\u8743\uE0D1\u8744\uB8C2\uD8C5"+ + "\u8745\u8746\u8747\u8748\u8749\u874A\u874B\u874C"+ + "\uD0EA\u874D\u874E\uC2EF\u874F\u8750\uE0CF\uE0BD"+ + "\u8751\u8752\u8753\uE0D4\uE0D3\u8754\u8755\uE0D7"+ + "\u8756\u8757\u8758\u8759\uE0DC\uE0D8\u875A\u875B"+ + "\u875C\uD6F6\uB3B0\u875D\uD7EC\u875E\uCBBB\u875F"+ + "\u8760\uE0DA\u8761\uCEFB\u8762\u8763\u8764\uBAD9"+ + "\u8765\u8766\u8767\u8768\u8769\u876A\u876B\u876C"+ + "\u876D\u876E\u876F\u8770\uE0E1\uE0DD\uD2AD\u8771"+ + "\u8772\u8773\u8774\u8775\uE0E2\u8776\u8777\uE0DB"+ + "\uE0D9\uE0DF\u8778\u8779\uE0E0\u877A\u877B\u877C"+ + "\u877D\u877E\uE0DE\u8780\uE0E4\u8781\u8782\u8783"+ + "\uC6F7\uD8AC\uD4EB\uE0E6\uCAC9\u8784\u8785\u8786"+ + "\u8787\uE0E5\u8788\u8789\u878A\u878B\uB8C1\u878C"+ + "\u878D\u878E\u878F\uE0E7\uE0E8\u8790\u8791\u8792"+ + "\u8793\u8794\u8795\u8796\u8797\uE0E9\uE0E3\u8798"+ + "\u8799\u879A\u879B\u879C\u879D\u879E\uBABF\uCCE7"+ + "\u879F\u87A0\u87A1\uE0EA\u87A2\u87A3\u87A4\u87A5"+ + "\u87A6\u87A7\u87A8\u87A9\u87AA\u87AB\u87AC\u87AD"+ + "\u87AE\u87AF\u87B0\uCFF9\u87B1\u87B2\u87B3\u87B4"+ + "\u87B5\u87B6\u87B7\u87B8\u87B9\u87BA\u87BB\uE0EB"+ + "\u87BC\u87BD\u87BE\u87BF\u87C0\u87C1\u87C2\uC8C2"+ + "\u87C3\u87C4\u87C5\u87C6\uBDC0\u87C7\u87C8\u87C9"+ + "\u87CA\u87CB\u87CC\u87CD\u87CE\u87CF\u87D0\u87D1"+ + "\u87D2\u87D3\uC4D2\u87D4\u87D5\u87D6\u87D7\u87D8"+ + "\u87D9\u87DA\u87DB\u87DC\uE0EC\u87DD\u87DE\uE0ED"+ + "\u87DF\u87E0\uC7F4\uCBC4\u87E1\uE0EE\uBBD8\uD8B6"+ + "\uD2F2\uE0EF\uCDC5\u87E2\uB6DA\u87E3\u87E4\u87E5"+ + "\u87E6\u87E7\u87E8\uE0F1\u87E9\uD4B0\u87EA\u87EB"+ + "\uC0A7\uB4D1\u87EC\u87ED\uCEA7\uE0F0\u87EE\u87EF"+ + "\u87F0\uE0F2\uB9CC\u87F1\u87F2\uB9FA\uCDBC\uE0F3"+ + "\u87F3\u87F4\u87F5\uC6D4\uE0F4\u87F6\uD4B2\u87F7"+ + "\uC8A6\uE0F6\uE0F5\u87F8\u87F9\u87FA\u87FB\u87FC"+ + "\u87FD\u87FE\u8840\u8841\u8842\u8843\u8844\u8845"+ + "\u8846\u8847\u8848\u8849\uE0F7\u884A\u884B\uCDC1"+ + "\u884C\u884D\u884E\uCAA5\u884F\u8850\u8851\u8852"+ + "\uD4DA\uDBD7\uDBD9\u8853\uDBD8\uB9E7\uDBDC\uDBDD"+ + "\uB5D8\u8854\u8855\uDBDA\u8856\u8857\u8858\u8859"+ + "\u885A\uDBDB\uB3A1\uDBDF\u885B\u885C\uBBF8\u885D"+ + "\uD6B7\u885E\uDBE0\u885F\u8860\u8861\u8862\uBEF9"+ + "\u8863\u8864\uB7BB\u8865\uDBD0\uCCAE\uBFB2\uBBB5"+ + "\uD7F8\uBFD3\u8866\u8867\u8868\u8869\u886A\uBFE9"+ + "\u886B\u886C\uBCE1\uCCB3\uDBDE\uB0D3\uCEEB\uB7D8"+ + "\uD7B9\uC6C2\u886D\u886E\uC0A4\u886F\uCCB9\u8870"+ + "\uDBE7\uDBE1\uC6BA\uDBE3\u8871\uDBE8\u8872\uC5F7"+ + "\u8873\u8874\u8875\uDBEA\u8876\u8877\uDBE9\uBFC0"+ + "\u8878\u8879\u887A\uDBE6\uDBE5\u887B\u887C\u887D"+ + "\u887E\u8880\uB4B9\uC0AC\uC2A2\uDBE2\uDBE4\u8881"+ + "\u8882\u8883\u8884\uD0CD\uDBED\u8885\u8886\u8887"+ + "\u8888\u8889\uC0DD\uDBF2\u888A\u888B\u888C\u888D"+ + "\u888E\u888F\u8890\uB6E2\u8891\u8892\u8893\u8894"+ + "\uDBF3\uDBD2\uB9B8\uD4AB\uDBEC\u8895\uBFD1\uDBF0"+ + "\u8896\uDBD1\u8897\uB5E6\u8898\uDBEB\uBFE5\u8899"+ + "\u889A\u889B\uDBEE\u889C\uDBF1\u889D\u889E\u889F"+ + "\uDBF9\u88A0\u88A1\u88A2\u88A3\u88A4\u88A5\u88A6"+ + "\u88A7\u88A8\uB9A1\uB0A3\u88A9\u88AA\u88AB\u88AC"+ + "\u88AD\u88AE\u88AF\uC2F1\u88B0\u88B1\uB3C7\uDBEF"+ + "\u88B2\u88B3\uDBF8\u88B4\uC6D2\uDBF4\u88B5\u88B6"+ + "\uDBF5\uDBF7\uDBF6\u88B7\u88B8\uDBFE\u88B9\uD3F2"+ + "\uB2BA\u88BA\u88BB\u88BC\uDBFD\u88BD\u88BE\u88BF"+ + "\u88C0\u88C1\u88C2\u88C3\u88C4\uDCA4\u88C5\uDBFB"+ + "\u88C6\u88C7\u88C8\u88C9\uDBFA\u88CA\u88CB\u88CC"+ + "\uDBFC\uC5E0\uBBF9\u88CD\u88CE\uDCA3\u88CF\u88D0"+ + "\uDCA5\u88D1\uCCC3\u88D2\u88D3\u88D4\uB6D1\uDDC0"+ + "\u88D5\u88D6\u88D7\uDCA1\u88D8\uDCA2\u88D9\u88DA"+ + "\u88DB\uC7B5\u88DC\u88DD\u88DE\uB6E9\u88DF\u88E0"+ + "\u88E1\uDCA7\u88E2\u88E3\u88E4\u88E5\uDCA6\u88E6"+ + "\uDCA9\uB1A4\u88E7\u88E8\uB5CC\u88E9\u88EA\u88EB"+ + "\u88EC\u88ED\uBFB0\u88EE\u88EF\u88F0\u88F1\u88F2"+ + "\uD1DF\u88F3\u88F4\u88F5\u88F6\uB6C2\u88F7\u88F8"+ + "\u88F9\u88FA\u88FB\u88FC\u88FD\u88FE\u8940\u8941"+ + "\u8942\u8943\u8944\u8945\uDCA8\u8946\u8947\u8948"+ + "\u8949\u894A\u894B\u894C\uCBFA\uEBF3\u894D\u894E"+ + "\u894F\uCBDC\u8950\u8951\uCBFE\u8952\u8953\u8954"+ + "\uCCC1\u8955\u8956\u8957\u8958\u8959\uC8FB\u895A"+ + "\u895B\u895C\u895D\u895E\u895F\uDCAA\u8960\u8961"+ + "\u8962\u8963\u8964\uCCEE\uDCAB\u8965\u8966\u8967"+ + "\u8968\u8969\u896A\u896B\u896C\u896D\u896E\u896F"+ + "\u8970\u8971\u8972\u8973\u8974\u8975\uDBD3\u8976"+ + "\uDCAF\uDCAC\u8977\uBEB3\u8978\uCAFB\u8979\u897A"+ + "\u897B\uDCAD\u897C\u897D\u897E\u8980\u8981\u8982"+ + "\u8983\u8984\uC9CA\uC4B9\u8985\u8986\u8987\u8988"+ + "\u8989\uC7BD\uDCAE\u898A\u898B\u898C\uD4F6\uD0E6"+ + "\u898D\u898E\u898F\u8990\u8991\u8992\u8993\u8994"+ + "\uC4AB\uB6D5\u8995\u8996\u8997\u8998\u8999\u899A"+ + "\u899B\u899C\u899D\u899E\u899F\u89A0\u89A1\u89A2"+ + "\u89A3\u89A4\u89A5\u89A6\uDBD4\u89A7\u89A8\u89A9"+ + "\u89AA\uB1DA\u89AB\u89AC\u89AD\uDBD5\u89AE\u89AF"+ + "\u89B0\u89B1\u89B2\u89B3\u89B4\u89B5\u89B6\u89B7"+ + "\u89B8\uDBD6\u89B9\u89BA\u89BB\uBABE\u89BC\u89BD"+ + "\u89BE\u89BF\u89C0\u89C1\u89C2\u89C3\u89C4\u89C5"+ + "\u89C6\u89C7\u89C8\u89C9\uC8C0\u89CA\u89CB\u89CC"+ + "\u89CD\u89CE\u89CF\uCABF\uC8C9\u89D0\uD7B3\u89D1"+ + "\uC9F9\u89D2\u89D3\uBFC7\u89D4\u89D5\uBAF8\u89D6"+ + "\u89D7\uD2BC\u89D8\u89D9\u89DA\u89DB\u89DC\u89DD"+ + "\u89DE\u89DF\uE2BA\u89E0\uB4A6\u89E1\u89E2\uB1B8"+ + "\u89E3\u89E4\u89E5\u89E6\u89E7\uB8B4\u89E8\uCFC4"+ + "\u89E9\u89EA\u89EB\u89EC\uD9E7\uCFA6\uCDE2\u89ED"+ + "\u89EE\uD9ED\uB6E0\u89EF\uD2B9\u89F0\u89F1\uB9BB"+ + "\u89F2\u89F3\u89F4\u89F5\uE2B9\uE2B7\u89F6\uB4F3"+ + "\u89F7\uCCEC\uCCAB\uB7F2\u89F8\uD8B2\uD1EB\uBABB"+ + "\u89F9\uCAA7\u89FA\u89FB\uCDB7\u89FC\u89FD\uD2C4"+ + "\uBFE4\uBCD0\uB6E1\u89FE\uDEC5\u8A40\u8A41\u8A42"+ + "\u8A43\uDEC6\uDBBC\u8A44\uD1D9\u8A45\u8A46\uC6E6"+ + "\uC4CE\uB7EE\u8A47\uB7DC\u8A48\u8A49\uBFFC\uD7E0"+ + "\u8A4A\uC6F5\u8A4B\u8A4C\uB1BC\uDEC8\uBDB1\uCCD7"+ + "\uDECA\u8A4D\uDEC9\u8A4E\u8A4F\u8A50\u8A51\u8A52"+ + "\uB5EC\u8A53\uC9DD\u8A54\u8A55\uB0C2\u8A56\u8A57"+ + "\u8A58\u8A59\u8A5A\u8A5B\u8A5C\u8A5D\u8A5E\u8A5F"+ + "\u8A60\u8A61\u8A62\uC5AE\uC5AB\u8A63\uC4CC\u8A64"+ + "\uBCE9\uCBFD\u8A65\u8A66\u8A67\uBAC3\u8A68\u8A69"+ + "\u8A6A\uE5F9\uC8E7\uE5FA\uCDFD\u8A6B\uD7B1\uB8BE"+ + "\uC2E8\u8A6C\uC8D1\u8A6D\u8A6E\uE5FB\u8A6F\u8A70"+ + "\u8A71\u8A72\uB6CA\uBCCB\u8A73\u8A74\uD1FD\uE6A1"+ + "\u8A75\uC3EE\u8A76\u8A77\u8A78\u8A79\uE6A4\u8A7A"+ + "\u8A7B\u8A7C\u8A7D\uE5FE\uE6A5\uCDD7\u8A7E\u8A80"+ + "\uB7C1\uE5FC\uE5FD\uE6A3\u8A81\u8A82\uC4DD\uE6A8"+ + "\u8A83\u8A84\uE6A7\u8A85\u8A86\u8A87\u8A88\u8A89"+ + "\u8A8A\uC3C3\u8A8B\uC6DE\u8A8C\u8A8D\uE6AA\u8A8E"+ + "\u8A8F\u8A90\u8A91\u8A92\u8A93\u8A94\uC4B7\u8A95"+ + "\u8A96\u8A97\uE6A2\uCABC\u8A98\u8A99\u8A9A\u8A9B"+ + "\uBDE3\uB9C3\uE6A6\uD0D5\uCEAF\u8A9C\u8A9D\uE6A9"+ + "\uE6B0\u8A9E\uD2A6\u8A9F\uBDAA\uE6AD\u8AA0\u8AA1"+ + "\u8AA2\u8AA3\u8AA4\uE6AF\u8AA5\uC0D1\u8AA6\u8AA7"+ + "\uD2CC\u8AA8\u8AA9\u8AAA\uBCA7\u8AAB\u8AAC\u8AAD"+ + "\u8AAE\u8AAF\u8AB0\u8AB1\u8AB2\u8AB3\u8AB4\u8AB5"+ + "\u8AB6\uE6B1\u8AB7\uD2F6\u8AB8\u8AB9\u8ABA\uD7CB"+ + "\u8ABB\uCDFE\u8ABC\uCDDE\uC2A6\uE6AB\uE6AC\uBDBF"+ + "\uE6AE\uE6B3\u8ABD\u8ABE\uE6B2\u8ABF\u8AC0\u8AC1"+ + "\u8AC2\uE6B6\u8AC3\uE6B8\u8AC4\u8AC5\u8AC6\u8AC7"+ + "\uC4EF\u8AC8\u8AC9\u8ACA\uC4C8\u8ACB\u8ACC\uBEEA"+ + "\uC9EF\u8ACD\u8ACE\uE6B7\u8ACF\uB6F0\u8AD0\u8AD1"+ + "\u8AD2\uC3E4\u8AD3\u8AD4\u8AD5\u8AD6\u8AD7\u8AD8"+ + "\u8AD9\uD3E9\uE6B4\u8ADA\uE6B5\u8ADB\uC8A2\u8ADC"+ + "\u8ADD\u8ADE\u8ADF\u8AE0\uE6BD\u8AE1\u8AE2\u8AE3"+ + "\uE6B9\u8AE4\u8AE5\u8AE6\u8AE7\u8AE8\uC6C5\u8AE9"+ + "\u8AEA\uCDF1\uE6BB\u8AEB\u8AEC\u8AED\u8AEE\u8AEF"+ + "\u8AF0\u8AF1\u8AF2\u8AF3\u8AF4\uE6BC\u8AF5\u8AF6"+ + "\u8AF7\u8AF8\uBBE9\u8AF9\u8AFA\u8AFB\u8AFC\u8AFD"+ + "\u8AFE\u8B40\uE6BE\u8B41\u8B42\u8B43\u8B44\uE6BA"+ + "\u8B45\u8B46\uC0B7\u8B47\u8B48\u8B49\u8B4A\u8B4B"+ + "\u8B4C\u8B4D\u8B4E\u8B4F\uD3A4\uE6BF\uC9F4\uE6C3"+ + "\u8B50\u8B51\uE6C4\u8B52\u8B53\u8B54\u8B55\uD0F6"+ + "\u8B56\u8B57\u8B58\u8B59\u8B5A\u8B5B\u8B5C\u8B5D"+ + "\u8B5E\u8B5F\u8B60\u8B61\u8B62\u8B63\u8B64\u8B65"+ + "\u8B66\u8B67\uC3BD\u8B68\u8B69\u8B6A\u8B6B\u8B6C"+ + "\u8B6D\u8B6E\uC3C4\uE6C2\u8B6F\u8B70\u8B71\u8B72"+ + "\u8B73\u8B74\u8B75\u8B76\u8B77\u8B78\u8B79\u8B7A"+ + "\u8B7B\u8B7C\uE6C1\u8B7D\u8B7E\u8B80\u8B81\u8B82"+ + "\u8B83\u8B84\uE6C7\uCFB1\u8B85\uEBF4\u8B86\u8B87"+ + "\uE6CA\u8B88\u8B89\u8B8A\u8B8B\u8B8C\uE6C5\u8B8D"+ + "\u8B8E\uBCDE\uC9A9\u8B8F\u8B90\u8B91\u8B92\u8B93"+ + "\u8B94\uBCB5\u8B95\u8B96\uCFD3\u8B97\u8B98\u8B99"+ + "\u8B9A\u8B9B\uE6C8\u8B9C\uE6C9\u8B9D\uE6CE\u8B9E"+ + "\uE6D0\u8B9F\u8BA0\u8BA1\uE6D1\u8BA2\u8BA3\u8BA4"+ + "\uE6CB\uB5D5\u8BA5\uE6CC\u8BA6\u8BA7\uE6CF\u8BA8"+ + "\u8BA9\uC4DB\u8BAA\uE6C6\u8BAB\u8BAC\u8BAD\u8BAE"+ + "\u8BAF\uE6CD\u8BB0\u8BB1\u8BB2\u8BB3\u8BB4\u8BB5"+ + "\u8BB6\u8BB7\u8BB8\u8BB9\u8BBA\u8BBB\u8BBC\u8BBD"+ + "\u8BBE\u8BBF\u8BC0\u8BC1\u8BC2\u8BC3\u8BC4\u8BC5"+ + "\u8BC6\uE6D2\u8BC7\u8BC8\u8BC9\u8BCA\u8BCB\u8BCC"+ + "\u8BCD\u8BCE\u8BCF\u8BD0\u8BD1\u8BD2\uE6D4\uE6D3"+ + "\u8BD3\u8BD4\u8BD5\u8BD6\u8BD7\u8BD8\u8BD9\u8BDA"+ + "\u8BDB\u8BDC\u8BDD\u8BDE\u8BDF\u8BE0\u8BE1\u8BE2"+ + "\u8BE3\u8BE4\u8BE5\u8BE6\u8BE7\u8BE8\u8BE9\u8BEA"+ + "\u8BEB\u8BEC\uE6D5\u8BED\uD9F8\u8BEE\u8BEF\uE6D6"+ + "\u8BF0\u8BF1\u8BF2\u8BF3\u8BF4\u8BF5\u8BF6\u8BF7"+ + "\uE6D7\u8BF8\u8BF9\u8BFA\u8BFB\u8BFC\u8BFD\u8BFE"+ + "\u8C40\u8C41\u8C42\u8C43\u8C44\u8C45\u8C46\u8C47"+ + "\uD7D3\uE6DD\u8C48\uE6DE\uBFD7\uD4D0\u8C49\uD7D6"+ + "\uB4E6\uCBEF\uE6DA\uD8C3\uD7CE\uD0A2\u8C4A\uC3CF"+ + "\u8C4B\u8C4C\uE6DF\uBCBE\uB9C2\uE6DB\uD1A7\u8C4D"+ + "\u8C4E\uBAA2\uC2CF\u8C4F\uD8AB\u8C50\u8C51\u8C52"+ + "\uCAEB\uE5EE\u8C53\uE6DC\u8C54\uB7F5\u8C55\u8C56"+ + "\u8C57\u8C58\uC8E6\u8C59\u8C5A\uC4F5\u8C5B\u8C5C"+ + "\uE5B2\uC4FE\u8C5D\uCBFC\uE5B3\uD5AC\u8C5E\uD3EE"+ + "\uCAD8\uB0B2\u8C5F\uCBCE\uCDEA\u8C60\u8C61\uBAEA"+ + "\u8C62\u8C63\u8C64\uE5B5\u8C65\uE5B4\u8C66\uD7DA"+ + "\uB9D9\uD6E6\uB6A8\uCDF0\uD2CB\uB1A6\uCAB5\u8C67"+ + "\uB3E8\uC9F3\uBFCD\uD0FB\uCAD2\uE5B6\uBBC2\u8C68"+ + "\u8C69\u8C6A\uCFDC\uB9AC\u8C6B\u8C6C\u8C6D\u8C6E"+ + "\uD4D7\u8C6F\u8C70\uBAA6\uD1E7\uCFFC\uBCD2\u8C71"+ + "\uE5B7\uC8DD\u8C72\u8C73\u8C74\uBFED\uB1F6\uCBDE"+ + "\u8C75\u8C76\uBCC5\u8C77\uBCC4\uD2FA\uC3DC\uBFDC"+ + "\u8C78\u8C79\u8C7A\u8C7B\uB8BB\u8C7C\u8C7D\u8C7E"+ + "\uC3C2\u8C80\uBAAE\uD4A2\u8C81\u8C82\u8C83\u8C84"+ + "\u8C85\u8C86\u8C87\u8C88\u8C89\uC7DE\uC4AF\uB2EC"+ + "\u8C8A\uB9D1\u8C8B\u8C8C\uE5BB\uC1C8\u8C8D\u8C8E"+ + "\uD5AF\u8C8F\u8C90\u8C91\u8C92\u8C93\uE5BC\u8C94"+ + "\uE5BE\u8C95\u8C96\u8C97\u8C98\u8C99\u8C9A\u8C9B"+ + "\uB4E7\uB6D4\uCBC2\uD1B0\uB5BC\u8C9C\u8C9D\uCAD9"+ + "\u8C9E\uB7E2\u8C9F\u8CA0\uC9E4\u8CA1\uBDAB\u8CA2"+ + "\u8CA3\uCEBE\uD7F0\u8CA4\u8CA5\u8CA6\u8CA7\uD0A1"+ + "\u8CA8\uC9D9\u8CA9\u8CAA\uB6FB\uE6D8\uBCE2\u8CAB"+ + "\uB3BE\u8CAC\uC9D0\u8CAD\uE6D9\uB3A2\u8CAE\u8CAF"+ + "\u8CB0\u8CB1\uDECC\u8CB2\uD3C8\uDECD\u8CB3\uD2A2"+ + "\u8CB4\u8CB5\u8CB6\u8CB7\uDECE\u8CB8\u8CB9\u8CBA"+ + "\u8CBB\uBECD\u8CBC\u8CBD\uDECF\u8CBE\u8CBF\u8CC0"+ + "\uCAAC\uD2FC\uB3DF\uE5EA\uC4E1\uBEA1\uCEB2\uC4F2"+ + "\uBED6\uC6A8\uB2E3\u8CC1\u8CC2\uBED3\u8CC3\u8CC4"+ + "\uC7FC\uCCEB\uBDEC\uCEDD\u8CC5\u8CC6\uCABA\uC6C1"+ + "\uE5EC\uD0BC\u8CC7\u8CC8\u8CC9\uD5B9\u8CCA\u8CCB"+ + "\u8CCC\uE5ED\u8CCD\u8CCE\u8CCF\u8CD0\uCAF4\u8CD1"+ + "\uCDC0\uC2C5\u8CD2\uE5EF\u8CD3\uC2C4\uE5F0\u8CD4"+ + "\u8CD5\u8CD6\u8CD7\u8CD8\u8CD9\u8CDA\uE5F8\uCDCD"+ + "\u8CDB\uC9BD\u8CDC\u8CDD\u8CDE\u8CDF\u8CE0\u8CE1"+ + "\u8CE2\uD2D9\uE1A8\u8CE3\u8CE4\u8CE5\u8CE6\uD3EC"+ + "\u8CE7\uCBEA\uC6F1\u8CE8\u8CE9\u8CEA\u8CEB\u8CEC"+ + "\uE1AC\u8CED\u8CEE\u8CEF\uE1A7\uE1A9\u8CF0\u8CF1"+ + "\uE1AA\uE1AF\u8CF2\u8CF3\uB2ED\u8CF4\uE1AB\uB8DA"+ + "\uE1AD\uE1AE\uE1B0\uB5BA\uE1B1\u8CF5\u8CF6\u8CF7"+ + "\u8CF8\u8CF9\uE1B3\uE1B8\u8CFA\u8CFB\u8CFC\u8CFD"+ + "\u8CFE\uD1D2\u8D40\uE1B6\uE1B5\uC1EB\u8D41\u8D42"+ + "\u8D43\uE1B7\u8D44\uD4C0\u8D45\uE1B2\u8D46\uE1BA"+ + "\uB0B6\u8D47\u8D48\u8D49\u8D4A\uE1B4\u8D4B\uBFF9"+ + "\u8D4C\uE1B9\u8D4D\u8D4E\uE1BB\u8D4F\u8D50\u8D51"+ + "\u8D52\u8D53\u8D54\uE1BE\u8D55\u8D56\u8D57\u8D58"+ + "\u8D59\u8D5A\uE1BC\u8D5B\u8D5C\u8D5D\u8D5E\u8D5F"+ + "\u8D60\uD6C5\u8D61\u8D62\u8D63\u8D64\u8D65\u8D66"+ + "\u8D67\uCFBF\u8D68\u8D69\uE1BD\uE1BF\uC2CD\u8D6A"+ + "\uB6EB\u8D6B\uD3F8\u8D6C\u8D6D\uC7CD\u8D6E\u8D6F"+ + "\uB7E5\u8D70\u8D71\u8D72\u8D73\u8D74\u8D75\u8D76"+ + "\u8D77\u8D78\u8D79\uBEFE\u8D7A\u8D7B\u8D7C\u8D7D"+ + "\u8D7E\u8D80\uE1C0\uE1C1\u8D81\u8D82\uE1C7\uB3E7"+ + "\u8D83\u8D84\u8D85\u8D86\u8D87\u8D88\uC6E9\u8D89"+ + "\u8D8A\u8D8B\u8D8C\u8D8D\uB4DE\u8D8E\uD1C2\u8D8F"+ + "\u8D90\u8D91\u8D92\uE1C8\u8D93\u8D94\uE1C6\u8D95"+ + "\u8D96\u8D97\u8D98\u8D99\uE1C5\u8D9A\uE1C3\uE1C2"+ + "\u8D9B\uB1C0\u8D9C\u8D9D\u8D9E\uD5B8\uE1C4\u8D9F"+ + "\u8DA0\u8DA1\u8DA2\u8DA3\uE1CB\u8DA4\u8DA5\u8DA6"+ + "\u8DA7\u8DA8\u8DA9\u8DAA\u8DAB\uE1CC\uE1CA\u8DAC"+ + "\u8DAD\u8DAE\u8DAF\u8DB0\u8DB1\u8DB2\u8DB3\uEFFA"+ + "\u8DB4\u8DB5\uE1D3\uE1D2\uC7B6\u8DB6\u8DB7\u8DB8"+ + "\u8DB9\u8DBA\u8DBB\u8DBC\u8DBD\u8DBE\u8DBF\u8DC0"+ + "\uE1C9\u8DC1\u8DC2\uE1CE\u8DC3\uE1D0\u8DC4\u8DC5"+ + "\u8DC6\u8DC7\u8DC8\u8DC9\u8DCA\u8DCB\u8DCC\u8DCD"+ + "\u8DCE\uE1D4\u8DCF\uE1D1\uE1CD\u8DD0\u8DD1\uE1CF"+ + "\u8DD2\u8DD3\u8DD4\u8DD5\uE1D5\u8DD6\u8DD7\u8DD8"+ + "\u8DD9\u8DDA\u8DDB\u8DDC\u8DDD\u8DDE\u8DDF\u8DE0"+ + "\u8DE1\u8DE2\uE1D6\u8DE3\u8DE4\u8DE5\u8DE6\u8DE7"+ + "\u8DE8\u8DE9\u8DEA\u8DEB\u8DEC\u8DED\u8DEE\u8DEF"+ + "\u8DF0\u8DF1\u8DF2\u8DF3\u8DF4\u8DF5\u8DF6\u8DF7"+ + "\u8DF8\uE1D7\u8DF9\u8DFA\u8DFB\uE1D8\u8DFC\u8DFD"+ + "\u8DFE\u8E40\u8E41\u8E42\u8E43\u8E44\u8E45\u8E46"+ + "\u8E47\u8E48\u8E49\u8E4A\u8E4B\u8E4C\u8E4D\u8E4E"+ + "\u8E4F\u8E50\u8E51\u8E52\u8E53\u8E54\u8E55\uE1DA"+ + "\u8E56\u8E57\u8E58\u8E59\u8E5A\u8E5B\u8E5C\u8E5D"+ + "\u8E5E\u8E5F\u8E60\u8E61\u8E62\uE1DB\u8E63\u8E64"+ + "\u8E65\u8E66\u8E67\u8E68\u8E69\uCEA1\u8E6A\u8E6B"+ + "\u8E6C\u8E6D\u8E6E\u8E6F\u8E70\u8E71\u8E72\u8E73"+ + "\u8E74\u8E75\u8E76\uE7DD\u8E77\uB4A8\uD6DD\u8E78"+ + "\u8E79\uD1B2\uB3B2\u8E7A\u8E7B\uB9A4\uD7F3\uC7C9"+ + "\uBEDE\uB9AE\u8E7C\uCED7\u8E7D\u8E7E\uB2EE\uDBCF"+ + "\u8E80\uBCBA\uD2D1\uCBC8\uB0CD\u8E81\u8E82\uCFEF"+ + "\u8E83\u8E84\u8E85\u8E86\u8E87\uD9E3\uBDED\u8E88"+ + "\u8E89\uB1D2\uCAD0\uB2BC\u8E8A\uCBA7\uB7AB\u8E8B"+ + "\uCAA6\u8E8C\u8E8D\u8E8E\uCFA3\u8E8F\u8E90\uE0F8"+ + "\uD5CA\uE0FB\u8E91\u8E92\uE0FA\uC5C1\uCCFB\u8E93"+ + "\uC1B1\uE0F9\uD6E3\uB2AF\uD6C4\uB5DB\u8E94\u8E95"+ + "\u8E96\u8E97\u8E98\u8E99\u8E9A\u8E9B\uB4F8\uD6A1"+ + "\u8E9C\u8E9D\u8E9E\u8E9F\u8EA0\uCFAF\uB0EF\u8EA1"+ + "\u8EA2\uE0FC\u8EA3\u8EA4\u8EA5\u8EA6\u8EA7\uE1A1"+ + "\uB3A3\u8EA8\u8EA9\uE0FD\uE0FE\uC3B1\u8EAA\u8EAB"+ + "\u8EAC\u8EAD\uC3DD\u8EAE\uE1A2\uB7F9\u8EAF\u8EB0"+ + "\u8EB1\u8EB2\u8EB3\u8EB4\uBBCF\u8EB5\u8EB6\u8EB7"+ + "\u8EB8\u8EB9\u8EBA\u8EBB\uE1A3\uC4BB\u8EBC\u8EBD"+ + "\u8EBE\u8EBF\u8EC0\uE1A4\u8EC1\u8EC2\uE1A5\u8EC3"+ + "\u8EC4\uE1A6\uB4B1\u8EC5\u8EC6\u8EC7\u8EC8\u8EC9"+ + "\u8ECA\u8ECB\u8ECC\u8ECD\u8ECE\u8ECF\u8ED0\u8ED1"+ + "\u8ED2\u8ED3\uB8C9\uC6BD\uC4EA\u8ED4\uB2A2\u8ED5"+ + "\uD0D2\u8ED6\uE7DB\uBBC3\uD3D7\uD3C4\u8ED7\uB9E3"+ + "\uE2CF\u8ED8\u8ED9\u8EDA\uD7AF\u8EDB\uC7EC\uB1D3"+ + "\u8EDC\u8EDD\uB4B2\uE2D1\u8EDE\u8EDF\u8EE0\uD0F2"+ + "\uC2AE\uE2D0\u8EE1\uBFE2\uD3A6\uB5D7\uE2D2\uB5EA"+ + "\u8EE2\uC3ED\uB8FD\u8EE3\uB8AE\u8EE4\uC5D3\uB7CF"+ + "\uE2D4\u8EE5\u8EE6\u8EE7\u8EE8\uE2D3\uB6C8\uD7F9"+ + "\u8EE9\u8EEA\u8EEB\u8EEC\u8EED\uCDA5\u8EEE\u8EEF"+ + "\u8EF0\u8EF1\u8EF2\uE2D8\u8EF3\uE2D6\uCAFC\uBFB5"+ + "\uD3B9\uE2D5\u8EF4\u8EF5\u8EF6\u8EF7\uE2D7\u8EF8"+ + "\u8EF9\u8EFA\u8EFB\u8EFC\u8EFD\u8EFE\u8F40\u8F41"+ + "\u8F42\uC1AE\uC0C8\u8F43\u8F44\u8F45\u8F46\u8F47"+ + "\u8F48\uE2DB\uE2DA\uC0AA\u8F49\u8F4A\uC1CE\u8F4B"+ + "\u8F4C\u8F4D\u8F4E\uE2DC\u8F4F\u8F50\u8F51\u8F52"+ + "\u8F53\u8F54\u8F55\u8F56\u8F57\u8F58\u8F59\u8F5A"+ + "\uE2DD\u8F5B\uE2DE\u8F5C\u8F5D\u8F5E\u8F5F\u8F60"+ + "\u8F61\u8F62\u8F63\u8F64\uDBC8\u8F65\uD1D3\uCDA2"+ + "\u8F66\u8F67\uBDA8\u8F68\u8F69\u8F6A\uDEC3\uD8A5"+ + "\uBFAA\uDBCD\uD2EC\uC6FA\uC5AA\u8F6B\u8F6C\u8F6D"+ + "\uDEC4\u8F6E\uB1D7\uDFAE\u8F6F\u8F70\u8F71\uCABD"+ + "\u8F72\uDFB1\u8F73\uB9AD\u8F74\uD2FD\u8F75\uB8A5"+ + "\uBAEB\u8F76\u8F77\uB3DA\u8F78\u8F79\u8F7A\uB5DC"+ + "\uD5C5\u8F7B\u8F7C\u8F7D\u8F7E\uC3D6\uCFD2\uBBA1"+ + "\u8F80\uE5F3\uE5F2\u8F81\u8F82\uE5F4\u8F83\uCDE4"+ + "\u8F84\uC8F5\u8F85\u8F86\u8F87\u8F88\u8F89\u8F8A"+ + "\u8F8B\uB5AF\uC7BF\u8F8C\uE5F6\u8F8D\u8F8E\u8F8F"+ + "\uECB0\u8F90\u8F91\u8F92\u8F93\u8F94\u8F95\u8F96"+ + "\u8F97\u8F98\u8F99\u8F9A\u8F9B\u8F9C\u8F9D\u8F9E"+ + "\uE5E6\u8F9F\uB9E9\uB5B1\u8FA0\uC2BC\uE5E8\uE5E7"+ + "\uE5E9\u8FA1\u8FA2\u8FA3\u8FA4\uD2CD\u8FA5\u8FA6"+ + "\u8FA7\uE1EA\uD0CE\u8FA8\uCDAE\u8FA9\uD1E5\u8FAA"+ + "\u8FAB\uB2CA\uB1EB\u8FAC\uB1F2\uC5ED\u8FAD\u8FAE"+ + "\uD5C3\uD3B0\u8FAF\uE1DC\u8FB0\u8FB1\u8FB2\uE1DD"+ + "\u8FB3\uD2DB\u8FB4\uB3B9\uB1CB\u8FB5\u8FB6\u8FB7"+ + "\uCDF9\uD5F7\uE1DE\u8FB8\uBEB6\uB4FD\u8FB9\uE1DF"+ + "\uBADC\uE1E0\uBBB2\uC2C9\uE1E1\u8FBA\u8FBB\u8FBC"+ + "\uD0EC\u8FBD\uCDBD\u8FBE\u8FBF\uE1E2\u8FC0\uB5C3"+ + "\uC5C7\uE1E3\u8FC1\u8FC2\uE1E4\u8FC3\u8FC4\u8FC5"+ + "\u8FC6\uD3F9\u8FC7\u8FC8\u8FC9\u8FCA\u8FCB\u8FCC"+ + "\uE1E5\u8FCD\uD1AD\u8FCE\u8FCF\uE1E6\uCEA2\u8FD0"+ + "\u8FD1\u8FD2\u8FD3\u8FD4\u8FD5\uE1E7\u8FD6\uB5C2"+ + "\u8FD7\u8FD8\u8FD9\u8FDA\uE1E8\uBBD5\u8FDB\u8FDC"+ + "\u8FDD\u8FDE\u8FDF\uD0C4\uE2E0\uB1D8\uD2E4\u8FE0"+ + "\u8FE1\uE2E1\u8FE2\u8FE3\uBCC9\uC8CC\u8FE4\uE2E3"+ + "\uECFE\uECFD\uDFAF\u8FE5\u8FE6\u8FE7\uE2E2\uD6BE"+ + "\uCDFC\uC3A6\u8FE8\u8FE9\u8FEA\uE3C3\u8FEB\u8FEC"+ + "\uD6D2\uE2E7\u8FED\u8FEE\uE2E8\u8FEF\u8FF0\uD3C7"+ + "\u8FF1\u8FF2\uE2EC\uBFEC\u8FF3\uE2ED\uE2E5\u8FF4"+ + "\u8FF5\uB3C0\u8FF6\u8FF7\u8FF8\uC4EE\u8FF9\u8FFA"+ + "\uE2EE\u8FFB\u8FFC\uD0C3\u8FFD\uBAF6\uE2E9\uB7DE"; + + private static final String innerEncoderIndex6= + "\uBBB3\uCCAC\uCBCB\uE2E4\uE2E6\uE2EA\uE2EB\u8FFE"+ + "\u9040\u9041\uE2F7\u9042\u9043\uE2F4\uD4F5\uE2F3"+ + "\u9044\u9045\uC5AD\u9046\uD5FA\uC5C2\uB2C0\u9047"+ + "\u9048\uE2EF\u9049\uE2F2\uC1AF\uCBBC\u904A\u904B"+ + "\uB5A1\uE2F9\u904C\u904D\u904E\uBCB1\uE2F1\uD0D4"+ + "\uD4B9\uE2F5\uB9D6\uE2F6\u904F\u9050\u9051\uC7D3"+ + "\u9052\u9053\u9054\u9055\u9056\uE2F0\u9057\u9058"+ + "\u9059\u905A\u905B\uD7DC\uEDA1\u905C\u905D\uE2F8"+ + "\u905E\uEDA5\uE2FE\uCAD1\u905F\u9060\u9061\u9062"+ + "\u9063\u9064\u9065\uC1B5\u9066\uBBD0\u9067\u9068"+ + "\uBFD6\u9069\uBAE3\u906A\u906B\uCBA1\u906C\u906D"+ + "\u906E\uEDA6\uEDA3\u906F\u9070\uEDA2\u9071\u9072"+ + "\u9073\u9074\uBBD6\uEDA7\uD0F4\u9075\u9076\uEDA4"+ + "\uBADE\uB6F7\uE3A1\uB6B2\uCCF1\uB9A7\u9077\uCFA2"+ + "\uC7A1\u9078\u9079\uBFD2\u907A\u907B\uB6F1\u907C"+ + "\uE2FA\uE2FB\uE2FD\uE2FC\uC4D5\uE3A2\u907D\uD3C1"+ + "\u907E\u9080\u9081\uE3A7\uC7C4\u9082\u9083\u9084"+ + "\u9085\uCFA4\u9086\u9087\uE3A9\uBAB7\u9088\u9089"+ + "\u908A\u908B\uE3A8\u908C\uBBDA\u908D\uE3A3\u908E"+ + "\u908F\u9090\uE3A4\uE3AA\u9091\uE3A6\u9092\uCEF2"+ + "\uD3C6\u9093\u9094\uBBBC\u9095\u9096\uD4C3\u9097"+ + "\uC4FA\u9098\u9099\uEDA8\uD0FC\uE3A5\u909A\uC3F5"+ + "\u909B\uE3AD\uB1AF\u909C\uE3B2\u909D\u909E\u909F"+ + "\uBCC2\u90A0\u90A1\uE3AC\uB5BF\u90A2\u90A3\u90A4"+ + "\u90A5\u90A6\u90A7\u90A8\u90A9\uC7E9\uE3B0\u90AA"+ + "\u90AB\u90AC\uBEAA\uCDEF\u90AD\u90AE\u90AF\u90B0"+ + "\u90B1\uBBF3\u90B2\u90B3\u90B4\uCCE8\u90B5\u90B6"+ + "\uE3AF\u90B7\uE3B1\u90B8\uCFA7\uE3AE\u90B9\uCEA9"+ + "\uBBDD\u90BA\u90BB\u90BC\u90BD\u90BE\uB5EB\uBEE5"+ + "\uB2D2\uB3CD\u90BF\uB1B9\uE3AB\uB2D1\uB5AC\uB9DF"+ + "\uB6E8\u90C0\u90C1\uCFEB\uE3B7\u90C2\uBBCC\u90C3"+ + "\u90C4\uC8C7\uD0CA\u90C5\u90C6\u90C7\u90C8\u90C9"+ + "\uE3B8\uB3EE\u90CA\u90CB\u90CC\u90CD\uEDA9\u90CE"+ + "\uD3FA\uD3E4\u90CF\u90D0\u90D1\uEDAA\uE3B9\uD2E2"+ + "\u90D2\u90D3\u90D4\u90D5\u90D6\uE3B5\u90D7\u90D8"+ + "\u90D9\u90DA\uD3DE\u90DB\u90DC\u90DD\u90DE\uB8D0"+ + "\uE3B3\u90DF\u90E0\uE3B6\uB7DF\u90E1\uE3B4\uC0A2"+ + "\u90E2\u90E3\u90E4\uE3BA\u90E5\u90E6\u90E7\u90E8"+ + "\u90E9\u90EA\u90EB\u90EC\u90ED\u90EE\u90EF\u90F0"+ + "\u90F1\u90F2\u90F3\u90F4\u90F5\u90F6\u90F7\uD4B8"+ + "\u90F8\u90F9\u90FA\u90FB\u90FC\u90FD\u90FE\u9140"+ + "\uB4C8\u9141\uE3BB\u9142\uBBC5\u9143\uC9F7\u9144"+ + "\u9145\uC9E5\u9146\u9147\u9148\uC4BD\u9149\u914A"+ + "\u914B\u914C\u914D\u914E\u914F\uEDAB\u9150\u9151"+ + "\u9152\u9153\uC2FD\u9154\u9155\u9156\u9157\uBBDB"+ + "\uBFAE\u9158\u9159\u915A\u915B\u915C\u915D\u915E"+ + "\uCEBF\u915F\u9160\u9161\u9162\uE3BC\u9163\uBFB6"+ + "\u9164\u9165\u9166\u9167\u9168\u9169\u916A\u916B"+ + "\u916C\u916D\u916E\u916F\u9170\u9171\u9172\u9173"+ + "\u9174\u9175\u9176\uB1EF\u9177\u9178\uD4F7\u9179"+ + "\u917A\u917B\u917C\u917D\uE3BE\u917E\u9180\u9181"+ + "\u9182\u9183\u9184\u9185\u9186\uEDAD\u9187\u9188"+ + "\u9189\u918A\u918B\u918C\u918D\u918E\u918F\uE3BF"+ + "\uBAA9\uEDAC\u9190\u9191\uE3BD\u9192\u9193\u9194"+ + "\u9195\u9196\u9197\u9198\u9199\u919A\u919B\uE3C0"+ + "\u919C\u919D\u919E\u919F\u91A0\u91A1\uBAB6\u91A2"+ + "\u91A3\u91A4\uB6AE\u91A5\u91A6\u91A7\u91A8\u91A9"+ + "\uD0B8\u91AA\uB0C3\uEDAE\u91AB\u91AC\u91AD\u91AE"+ + "\u91AF\uEDAF\uC0C1\u91B0\uE3C1\u91B1\u91B2\u91B3"+ + "\u91B4\u91B5\u91B6\u91B7\u91B8\u91B9\u91BA\u91BB"+ + "\u91BC\u91BD\u91BE\u91BF\u91C0\u91C1\uC5B3\u91C2"+ + "\u91C3\u91C4\u91C5\u91C6\u91C7\u91C8\u91C9\u91CA"+ + "\u91CB\u91CC\u91CD\u91CE\u91CF\uE3C2\u91D0\u91D1"+ + "\u91D2\u91D3\u91D4\u91D5\u91D6\u91D7\u91D8\uDCB2"+ + "\u91D9\u91DA\u91DB\u91DC\u91DD\u91DE\uEDB0\u91DF"+ + "\uB8EA\u91E0\uCEEC\uEAA7\uD0E7\uCAF9\uC8D6\uCFB7"+ + "\uB3C9\uCED2\uBDE4\u91E1\u91E2\uE3DE\uBBF2\uEAA8"+ + "\uD5BD\u91E3\uC6DD\uEAA9\u91E4\u91E5\u91E6\uEAAA"+ + "\u91E7\uEAAC\uEAAB\u91E8\uEAAE\uEAAD\u91E9\u91EA"+ + "\u91EB\u91EC\uBDD8\u91ED\uEAAF\u91EE\uC2BE\u91EF"+ + "\u91F0\u91F1\u91F2\uB4C1\uB4F7\u91F3\u91F4\uBBA7"+ + "\u91F5\u91F6\u91F7\u91F8\u91F9\uECE6\uECE5\uB7BF"+ + "\uCBF9\uB1E2\u91FA\uECE7\u91FB\u91FC\u91FD\uC9C8"+ + "\uECE8\uECE9\u91FE\uCAD6\uDED0\uB2C5\uD4FA\u9240"+ + "\u9241\uC6CB\uB0C7\uB4F2\uC8D3\u9242\u9243\u9244"+ + "\uCDD0\u9245\u9246\uBFB8\u9247\u9248\u9249\u924A"+ + "\u924B\u924C\u924D\uBFDB\u924E\u924F\uC7A4\uD6B4"+ + "\u9250\uC0A9\uDED1\uC9A8\uD1EF\uC5A4\uB0E7\uB3B6"+ + "\uC8C5\u9251\u9252\uB0E2\u9253\u9254\uB7F6\u9255"+ + "\u9256\uC5FA\u9257\u9258\uB6F3\u9259\uD5D2\uB3D0"+ + "\uBCBC\u925A\u925B\u925C\uB3AD\u925D\u925E\u925F"+ + "\u9260\uBEF1\uB0D1\u9261\u9262\u9263\u9264\u9265"+ + "\u9266\uD2D6\uCAE3\uD7A5\u9267\uCDB6\uB6B6\uBFB9"+ + "\uD5DB\u9268\uB8A7\uC5D7\u9269\u926A\u926B\uDED2"+ + "\uBFD9\uC2D5\uC7C0\u926C\uBBA4\uB1A8\u926D\u926E"+ + "\uC5EA\u926F\u9270\uC5FB\uCCA7\u9271\u9272\u9273"+ + "\u9274\uB1A7\u9275\u9276\u9277\uB5D6\u9278\u9279"+ + "\u927A\uC4A8\u927B\uDED3\uD1BA\uB3E9\u927C\uC3F2"+ + "\u927D\u927E\uB7F7\u9280\uD6F4\uB5A3\uB2F0\uC4B4"+ + "\uC4E9\uC0AD\uDED4\u9281\uB0E8\uC5C4\uC1E0\u9282"+ + "\uB9D5\u9283\uBEDC\uCDD8\uB0CE\u9284\uCDCF\uDED6"+ + "\uBED0\uD7BE\uDED5\uD5D0\uB0DD\u9285\u9286\uC4E2"+ + "\u9287\u9288\uC2A3\uBCF0\u9289\uD3B5\uC0B9\uC5A1"+ + "\uB2A6\uD4F1\u928A\u928B\uC0A8\uCAC3\uDED7\uD5FC"+ + "\u928C\uB9B0\u928D\uC8AD\uCBA9\u928E\uDED9\uBFBD"+ + "\u928F\u9290\u9291\u9292\uC6B4\uD7A7\uCAB0\uC4C3"+ + "\u9293\uB3D6\uB9D2\u9294\u9295\u9296\u9297\uD6B8"+ + "\uEAFC\uB0B4\u9298\u9299\u929A\u929B\uBFE6\u929C"+ + "\u929D\uCCF4\u929E\u929F\u92A0\u92A1\uCDDA\u92A2"+ + "\u92A3\u92A4\uD6BF\uC2CE\u92A5\uCECE\uCCA2\uD0AE"+ + "\uC4D3\uB5B2\uDED8\uD5F5\uBCB7\uBBD3\u92A6\u92A7"+ + "\uB0A4\u92A8\uC5B2\uB4EC\u92A9\u92AA\u92AB\uD5F1"+ + "\u92AC\u92AD\uEAFD\u92AE\u92AF\u92B0\u92B1\u92B2"+ + "\u92B3\uDEDA\uCDA6\u92B4\u92B5\uCDEC\u92B6\u92B7"+ + "\u92B8\u92B9\uCEE6\uDEDC\u92BA\uCDB1\uC0A6\u92BB"+ + "\u92BC\uD7BD\u92BD\uDEDB\uB0C6\uBAB4\uC9D3\uC4F3"+ + "\uBEE8\u92BE\u92BF\u92C0\u92C1\uB2B6\u92C2\u92C3"+ + "\u92C4\u92C5\u92C6\u92C7\u92C8\u92C9\uC0CC\uCBF0"+ + "\u92CA\uBCF1\uBBBB\uB5B7\u92CB\u92CC\u92CD\uC5F5"+ + "\u92CE\uDEE6\u92CF\u92D0\u92D1\uDEE3\uBEDD\u92D2"+ + "\u92D3\uDEDF\u92D4\u92D5\u92D6\u92D7\uB4B7\uBDDD"+ + "\u92D8\u92D9\uDEE0\uC4ED\u92DA\u92DB\u92DC\u92DD"+ + "\uCFC6\u92DE\uB5E0\u92DF\u92E0\u92E1\u92E2\uB6DE"+ + "\uCADA\uB5F4\uDEE5\u92E3\uD5C6\u92E4\uDEE1\uCCCD"+ + "\uC6FE\u92E5\uC5C5\u92E6\u92E7\u92E8\uD2B4\u92E9"+ + "\uBEF2\u92EA\u92EB\u92EC\u92ED\u92EE\u92EF\u92F0"+ + "\uC2D3\u92F1\uCCBD\uB3B8\u92F2\uBDD3\u92F3\uBFD8"+ + "\uCDC6\uD1DA\uB4EB\u92F4\uDEE4\uDEDD\uDEE7\u92F5"+ + "\uEAFE\u92F6\u92F7\uC2B0\uDEE2\u92F8\u92F9\uD6C0"+ + "\uB5A7\u92FA\uB2F4\u92FB\uDEE8\u92FC\uDEF2\u92FD"+ + "\u92FE\u9340\u9341\u9342\uDEED\u9343\uDEF1\u9344"+ + "\u9345\uC8E0\u9346\u9347\u9348\uD7E1\uDEEF\uC3E8"+ + "\uCCE1\u9349\uB2E5\u934A\u934B\u934C\uD2BE\u934D"+ + "\u934E\u934F\u9350\u9351\u9352\u9353\uDEEE\u9354"+ + "\uDEEB\uCED5\u9355\uB4A7\u9356\u9357\u9358\u9359"+ + "\u935A\uBFAB\uBEBE\u935B\u935C\uBDD2\u935D\u935E"+ + "\u935F\u9360\uDEE9\u9361\uD4AE\u9362\uDEDE\u9363"+ + "\uDEEA\u9364\u9365\u9366\u9367\uC0BF\u9368\uDEEC"+ + "\uB2F3\uB8E9\uC2A7\u9369\u936A\uBDC1\u936B\u936C"+ + "\u936D\u936E\u936F\uDEF5\uDEF8\u9370\u9371\uB2AB"+ + "\uB4A4\u9372\u9373\uB4EA\uC9A6\u9374\u9375\u9376"+ + "\u9377\u9378\u9379\uDEF6\uCBD1\u937A\uB8E3\u937B"+ + "\uDEF7\uDEFA\u937C\u937D\u937E\u9380\uDEF9\u9381"+ + "\u9382\u9383\uCCC2\u9384\uB0E1\uB4EE\u9385\u9386"+ + "\u9387\u9388\u9389\u938A\uE5BA\u938B\u938C\u938D"+ + "\u938E\u938F\uD0AF\u9390\u9391\uB2EB\u9392\uEBA1"+ + "\u9393\uDEF4\u9394\u9395\uC9E3\uDEF3\uB0DA\uD2A1"+ + "\uB1F7\u9396\uCCAF\u9397\u9398\u9399\u939A\u939B"+ + "\u939C\u939D\uDEF0\u939E\uCBA4\u939F\u93A0\u93A1"+ + "\uD5AA\u93A2\u93A3\u93A4\u93A5\u93A6\uDEFB\u93A7"+ + "\u93A8\u93A9\u93AA\u93AB\u93AC\u93AD\u93AE\uB4DD"+ + "\u93AF\uC4A6\u93B0\u93B1\u93B2\uDEFD\u93B3\u93B4"+ + "\u93B5\u93B6\u93B7\u93B8\u93B9\u93BA\u93BB\u93BC"+ + "\uC3FE\uC4A1\uDFA1\u93BD\u93BE\u93BF\u93C0\u93C1"+ + "\u93C2\u93C3\uC1CC\u93C4\uDEFC\uBEEF\u93C5\uC6B2"+ + "\u93C6\u93C7\u93C8\u93C9\u93CA\u93CB\u93CC\u93CD"+ + "\u93CE\uB3C5\uC8F6\u93CF\u93D0\uCBBA\uDEFE\u93D1"+ + "\u93D2\uDFA4\u93D3\u93D4\u93D5\u93D6\uD7B2\u93D7"+ + "\u93D8\u93D9\u93DA\u93DB\uB3B7\u93DC\u93DD\u93DE"+ + "\u93DF\uC1C3\u93E0\u93E1\uC7CB\uB2A5\uB4E9\u93E2"+ + "\uD7AB\u93E3\u93E4\u93E5\u93E6\uC4EC\u93E7\uDFA2"+ + "\uDFA3\u93E8\uDFA5\u93E9\uBAB3\u93EA\u93EB\u93EC"+ + "\uDFA6\u93ED\uC0DE\u93EE\u93EF\uC9C3\u93F0\u93F1"+ + "\u93F2\u93F3\u93F4\u93F5\u93F6\uB2D9\uC7E6\u93F7"+ + "\uDFA7\u93F8\uC7DC\u93F9\u93FA\u93FB\u93FC\uDFA8"+ + "\uEBA2\u93FD\u93FE\u9440\u9441\u9442\uCBD3\u9443"+ + "\u9444\u9445\uDFAA\u9446\uDFA9\u9447\uB2C1\u9448"+ + "\u9449\u944A\u944B\u944C\u944D\u944E\u944F\u9450"+ + "\u9451\u9452\u9453\u9454\u9455\u9456\u9457\u9458"+ + "\u9459\u945A\u945B\u945C\u945D\u945E\u945F\u9460"+ + "\uC5CA\u9461\u9462\u9463\u9464\u9465\u9466\u9467"+ + "\u9468\uDFAB\u9469\u946A\u946B\u946C\u946D\u946E"+ + "\u946F\u9470\uD4DC\u9471\u9472\u9473\u9474\u9475"+ + "\uC8C1\u9476\u9477\u9478\u9479\u947A\u947B\u947C"+ + "\u947D\u947E\u9480\u9481\u9482\uDFAC\u9483\u9484"+ + "\u9485\u9486\u9487\uBEF0\u9488\u9489\uDFAD\uD6A7"+ + "\u948A\u948B\u948C\u948D\uEAB7\uEBB6\uCAD5\u948E"+ + "\uD8FC\uB8C4\u948F\uB9A5\u9490\u9491\uB7C5\uD5FE"+ + "\u9492\u9493\u9494\u9495\u9496\uB9CA\u9497\u9498"+ + "\uD0A7\uF4CD\u9499\u949A\uB5D0\u949B\u949C\uC3F4"+ + "\u949D\uBEC8\u949E\u949F\u94A0\uEBB7\uB0BD\u94A1"+ + "\u94A2\uBDCC\u94A3\uC1B2\u94A4\uB1D6\uB3A8\u94A5"+ + "\u94A6\u94A7\uB8D2\uC9A2\u94A8\u94A9\uB6D8\u94AA"+ + "\u94AB\u94AC\u94AD\uEBB8\uBEB4\u94AE\u94AF\u94B0"+ + "\uCAFD\u94B1\uC7C3\u94B2\uD5FB\u94B3\u94B4\uB7F3"+ + "\u94B5\u94B6\u94B7\u94B8\u94B9\u94BA\u94BB\u94BC"+ + "\u94BD\u94BE\u94BF\u94C0\u94C1\u94C2\u94C3\uCEC4"+ + "\u94C4\u94C5\u94C6\uD5AB\uB1F3\u94C7\u94C8\u94C9"+ + "\uECB3\uB0DF\u94CA\uECB5\u94CB\u94CC\u94CD\uB6B7"+ + "\u94CE\uC1CF\u94CF\uF5FA\uD0B1\u94D0\u94D1\uD5E5"+ + "\u94D2\uCED3\u94D3\u94D4\uBDEF\uB3E2\u94D5\uB8AB"+ + "\u94D6\uD5B6\u94D7\uEDBD\u94D8\uB6CF\u94D9\uCBB9"+ + "\uD0C2\u94DA\u94DB\u94DC\u94DD\u94DE\u94DF\u94E0"+ + "\u94E1\uB7BD\u94E2\u94E3\uECB6\uCAA9\u94E4\u94E5"+ + "\u94E6\uC5D4\u94E7\uECB9\uECB8\uC2C3\uECB7\u94E8"+ + "\u94E9\u94EA\u94EB\uD0FD\uECBA\u94EC\uECBB\uD7E5"+ + "\u94ED\u94EE\uECBC\u94EF\u94F0\u94F1\uECBD\uC6EC"+ + "\u94F2\u94F3\u94F4\u94F5\u94F6\u94F7\u94F8\u94F9"+ + "\uCEDE\u94FA\uBCC8\u94FB\u94FC\uC8D5\uB5A9\uBEC9"+ + "\uD6BC\uD4E7\u94FD\u94FE\uD1AE\uD0F1\uEAB8\uEAB9"+ + "\uEABA\uBAB5\u9540\u9541\u9542\u9543\uCAB1\uBFF5"+ + "\u9544\u9545\uCDFA\u9546\u9547\u9548\u9549\u954A"+ + "\uEAC0\u954B\uB0BA\uEABE\u954C\u954D\uC0A5\u954E"+ + "\u954F\u9550\uEABB\u9551\uB2FD\u9552\uC3F7\uBBE8"+ + "\u9553\u9554\u9555\uD2D7\uCEF4\uEABF\u9556\u9557"+ + "\u9558\uEABC\u9559\u955A\u955B\uEAC3\u955C\uD0C7"+ + "\uD3B3\u955D\u955E\u955F\u9560\uB4BA\u9561\uC3C1"+ + "\uD7F2\u9562\u9563\u9564\u9565\uD5D1\u9566\uCAC7"+ + "\u9567\uEAC5\u9568\u9569\uEAC4\uEAC7\uEAC6\u956A"+ + "\u956B\u956C\u956D\u956E\uD6E7\u956F\uCFD4\u9570"+ + "\u9571\uEACB\u9572\uBBCE\u9573\u9574\u9575\u9576"+ + "\u9577\u9578\u9579\uBDFA\uC9CE\u957A\u957B\uEACC"+ + "\u957C\u957D\uC9B9\uCFFE\uEACA\uD4CE\uEACD\uEACF"+ + "\u957E\u9580\uCDED\u9581\u9582\u9583\u9584\uEAC9"+ + "\u9585\uEACE\u9586\u9587\uCEEE\u9588\uBBDE\u9589"+ + "\uB3BF\u958A\u958B\u958C\u958D\u958E\uC6D5\uBEB0"+ + "\uCEFA\u958F\u9590\u9591\uC7E7\u9592\uBEA7\uEAD0"+ + "\u9593\u9594\uD6C7\u9595\u9596\u9597\uC1C0\u9598"+ + "\u9599\u959A\uD4DD\u959B\uEAD1\u959C\u959D\uCFBE"+ + "\u959E\u959F\u95A0\u95A1\uEAD2\u95A2\u95A3\u95A4"+ + "\u95A5\uCAEE\u95A6\u95A7\u95A8\u95A9\uC5AF\uB0B5"+ + "\u95AA\u95AB\u95AC\u95AD\u95AE\uEAD4\u95AF\u95B0"+ + "\u95B1\u95B2\u95B3\u95B4\u95B5\u95B6\u95B7\uEAD3"+ + "\uF4DF\u95B8\u95B9\u95BA\u95BB\u95BC\uC4BA\u95BD"+ + "\u95BE\u95BF\u95C0\u95C1\uB1A9\u95C2\u95C3\u95C4"+ + "\u95C5\uE5DF\u95C6\u95C7\u95C8\u95C9\uEAD5\u95CA"+ + "\u95CB\u95CC\u95CD\u95CE\u95CF\u95D0\u95D1\u95D2"+ + "\u95D3\u95D4\u95D5\u95D6\u95D7\u95D8\u95D9\u95DA"+ + "\u95DB\u95DC\u95DD\u95DE\u95DF\u95E0\u95E1\u95E2"+ + "\u95E3\uCAEF\u95E4\uEAD6\uEAD7\uC6D8\u95E5\u95E6"+ + "\u95E7\u95E8\u95E9\u95EA\u95EB\u95EC\uEAD8\u95ED"+ + "\u95EE\uEAD9\u95EF\u95F0\u95F1\u95F2\u95F3\u95F4"+ + "\uD4BB\u95F5\uC7FA\uD2B7\uB8FC\u95F6\u95F7\uEAC2"+ + "\u95F8\uB2DC\u95F9\u95FA\uC2FC\u95FB\uD4F8\uCCE6"+ + "\uD7EE\u95FC\u95FD\u95FE\u9640\u9641\u9642\u9643"+ + "\uD4C2\uD3D0\uEBC3\uC5F3\u9644\uB7FE\u9645\u9646"+ + "\uEBD4\u9647\u9648\u9649\uCBB7\uEBDE\u964A\uC0CA"+ + "\u964B\u964C\u964D\uCDFB\u964E\uB3AF\u964F\uC6DA"+ + "\u9650\u9651\u9652\u9653\u9654\u9655\uEBFC\u9656"+ + "\uC4BE\u9657\uCEB4\uC4A9\uB1BE\uD4FD\u9658\uCAF5"+ + "\u9659\uD6EC\u965A\u965B\uC6D3\uB6E4\u965C\u965D"+ + "\u965E\u965F\uBBFA\u9660\u9661\uD0E0\u9662\u9663"+ + "\uC9B1\u9664\uD4D3\uC8A8\u9665\u9666\uB8CB\u9667"+ + "\uE8BE\uC9BC\u9668\u9669\uE8BB\u966A\uC0EE\uD0D3"+ + "\uB2C4\uB4E5\u966B\uE8BC\u966C\u966D\uD5C8\u966E"+ + "\u966F\u9670\u9671\u9672\uB6C5\u9673\uE8BD\uCAF8"+ + "\uB8DC\uCCF5\u9674\u9675\u9676\uC0B4\u9677\u9678"+ + "\uD1EE\uE8BF\uE8C2\u9679\u967A\uBABC\u967B\uB1AD"+ + "\uBDDC\u967C\uEABD\uE8C3\u967D\uE8C6\u967E\uE8CB"+ + "\u9680\u9681\u9682\u9683\uE8CC\u9684\uCBC9\uB0E5"+ + "\u9685\uBCAB\u9686\u9687\uB9B9\u9688\u9689\uE8C1"+ + "\u968A\uCDF7\u968B\uE8CA\u968C\u968D\u968E\u968F"+ + "\uCEF6\u9690\u9691\u9692\u9693\uD5ED\u9694\uC1D6"+ + "\uE8C4\u9695\uC3B6\u9696\uB9FB\uD6A6\uE8C8\u9697"+ + "\u9698\u9699\uCAE0\uD4E6\u969A\uE8C0\u969B\uE8C5"+ + "\uE8C7\u969C\uC7B9\uB7E3\u969D\uE8C9\u969E\uBFDD"+ + "\uE8D2\u969F\u96A0\uE8D7\u96A1\uE8D5\uBCDC\uBCCF"+ + "\uE8DB\u96A2\u96A3\u96A4\u96A5\u96A6\u96A7\u96A8"+ + "\u96A9\uE8DE\u96AA\uE8DA\uB1FA\u96AB\u96AC\u96AD"+ + "\u96AE\u96AF\u96B0\u96B1\u96B2\u96B3\u96B4\uB0D8"+ + "\uC4B3\uB8CC\uC6E2\uC8BE\uC8E1\u96B5\u96B6\u96B7"+ + "\uE8CF\uE8D4\uE8D6\u96B8\uB9F1\uE8D8\uD7F5\u96B9"+ + "\uC4FB\u96BA\uE8DC\u96BB\u96BC\uB2E9\u96BD\u96BE"+ + "\u96BF\uE8D1\u96C0\u96C1\uBCED\u96C2\u96C3\uBFC2"+ + "\uE8CD\uD6F9\u96C4\uC1F8\uB2F1\u96C5\u96C6\u96C7"+ + "\u96C8\u96C9\u96CA\u96CB\u96CC\uE8DF\u96CD\uCAC1"+ + "\uE8D9\u96CE\u96CF\u96D0\u96D1\uD5A4\u96D2\uB1EA"+ + "\uD5BB\uE8CE\uE8D0\uB6B0\uE8D3\u96D3\uE8DD\uC0B8"+ + "\u96D4\uCAF7\u96D5\uCBA8\u96D6\u96D7\uC6DC\uC0F5"+ + "\u96D8\u96D9\u96DA\u96DB\u96DC\uE8E9\u96DD\u96DE"+ + "\u96DF\uD0A3\u96E0\u96E1\u96E2\u96E3\u96E4\u96E5"+ + "\u96E6\uE8F2\uD6EA\u96E7\u96E8\u96E9\u96EA\u96EB"+ + "\u96EC\u96ED\uE8E0\uE8E1\u96EE\u96EF\u96F0\uD1F9"+ + "\uBACB\uB8F9\u96F1\u96F2\uB8F1\uD4D4\uE8EF\u96F3"+ + "\uE8EE\uE8EC\uB9F0\uCCD2\uE8E6\uCEA6\uBFF2\u96F4"+ + "\uB0B8\uE8F1\uE8F0\u96F5\uD7C0\u96F6\uE8E4\u96F7"+ + "\uCDA9\uC9A3\u96F8\uBBB8\uBDDB\uE8EA\u96F9\u96FA"+ + "\u96FB\u96FC\u96FD\u96FE\u9740\u9741\u9742\u9743"+ + "\uE8E2\uE8E3\uE8E5\uB5B5\uE8E7\uC7C5\uE8EB\uE8ED"+ + "\uBDB0\uD7AE\u9744\uE8F8\u9745\u9746\u9747\u9748"+ + "\u9749\u974A\u974B\u974C\uE8F5\u974D\uCDB0\uE8F6"+ + "\u974E\u974F\u9750\u9751\u9752\u9753\u9754\u9755"+ + "\u9756\uC1BA\u9757\uE8E8\u9758\uC3B7\uB0F0\u9759"+ + "\u975A\u975B\u975C\u975D\u975E\u975F\u9760\uE8F4"+ + "\u9761\u9762\u9763\uE8F7\u9764\u9765\u9766\uB9A3"+ + "\u9767\u9768\u9769\u976A\u976B\u976C\u976D\u976E"+ + "\u976F\u9770\uC9D2\u9771\u9772\u9773\uC3CE\uCEE0"+ + "\uC0E6\u9774\u9775\u9776\u9777\uCBF3\u9778\uCCDD"+ + "\uD0B5\u9779\u977A\uCAE1\u977B\uE8F3\u977C\u977D"+ + "\u977E\u9780\u9781\u9782\u9783\u9784\u9785\u9786"+ + "\uBCEC\u9787\uE8F9\u9788\u9789\u978A\u978B\u978C"+ + "\u978D\uC3DE\u978E\uC6E5\u978F\uB9F7\u9790\u9791"+ + "\u9792\u9793\uB0F4\u9794\u9795\uD7D8\u9796\u9797"+ + "\uBCAC\u9798\uC5EF\u9799\u979A\u979B\u979C\u979D"+ + "\uCCC4\u979E\u979F\uE9A6\u97A0\u97A1\u97A2\u97A3"+ + "\u97A4\u97A5\u97A6\u97A7\u97A8\u97A9\uC9AD\u97AA"+ + "\uE9A2\uC0E2\u97AB\u97AC\u97AD\uBFC3\u97AE\u97AF"+ + "\u97B0\uE8FE\uB9D7\u97B1\uE8FB\u97B2\u97B3\u97B4"+ + "\u97B5\uE9A4\u97B6\u97B7\u97B8\uD2CE\u97B9\u97BA"+ + "\u97BB\u97BC\u97BD\uE9A3\u97BE\uD6B2\uD7B5\u97BF"+ + "\uE9A7\u97C0\uBDB7\u97C1\u97C2\u97C3\u97C4\u97C5"+ + "\u97C6\u97C7\u97C8\u97C9\u97CA\u97CB\u97CC\uE8FC"+ + "\uE8FD\u97CD\u97CE\u97CF\uE9A1\u97D0\u97D1\u97D2"+ + "\u97D3\u97D4\u97D5\u97D6\u97D7\uCDD6\u97D8\u97D9"+ + "\uD2AC\u97DA\u97DB\u97DC\uE9B2\u97DD\u97DE\u97DF"+ + "\u97E0\uE9A9\u97E1\u97E2\u97E3\uB4AA\u97E4\uB4BB"+ + "\u97E5\u97E6\uE9AB\u97E7\u97E8\u97E9\u97EA\u97EB"+ + "\u97EC\u97ED\u97EE\u97EF\u97F0\u97F1\u97F2\u97F3"+ + "\u97F4\u97F5\u97F6\u97F7\uD0A8\u97F8\u97F9\uE9A5"+ + "\u97FA\u97FB\uB3FE\u97FC\u97FD\uE9AC\uC0E3\u97FE"+ + "\uE9AA\u9840\u9841\uE9B9\u9842\u9843\uE9B8\u9844"+ + "\u9845\u9846\u9847\uE9AE\u9848\u9849\uE8FA\u984A"+ + "\u984B\uE9A8\u984C\u984D\u984E\u984F\u9850\uBFAC"+ + "\uE9B1\uE9BA\u9851\u9852\uC2A5\u9853\u9854\u9855"+ + "\uE9AF\u9856\uB8C5\u9857\uE9AD\u9858\uD3DC\uE9B4"+ + "\uE9B5\uE9B7\u9859\u985A\u985B\uE9C7\u985C\u985D"+ + "\u985E\u985F\u9860\u9861\uC0C6\uE9C5\u9862\u9863"+ + "\uE9B0\u9864\u9865\uE9BB\uB0F1\u9866\u9867\u9868"+ + "\u9869\u986A\u986B\u986C\u986D\u986E\u986F\uE9BC"+ + "\uD5A5\u9870\u9871\uE9BE\u9872\uE9BF\u9873\u9874"+ + "\u9875\uE9C1\u9876\u9877\uC1F1\u9878\u9879\uC8B6"+ + "\u987A\u987B\u987C\uE9BD\u987D\u987E\u9880\u9881"+ + "\u9882\uE9C2\u9883\u9884\u9885\u9886\u9887\u9888"+ + "\u9889\u988A\uE9C3\u988B\uE9B3\u988C\uE9B6\u988D"+ + "\uBBB1\u988E\u988F\u9890\uE9C0\u9891\u9892\u9893"+ + "\u9894\u9895\u9896\uBCF7\u9897\u9898\u9899\uE9C4"+ + "\uE9C6\u989A\u989B\u989C\u989D\u989E\u989F\u98A0"+ + "\u98A1\u98A2\u98A3\u98A4\u98A5\uE9CA\u98A6\u98A7"+ + "\u98A8\u98A9\uE9CE\u98AA\u98AB\u98AC\u98AD\u98AE"+ + "\u98AF\u98B0\u98B1\u98B2\u98B3\uB2DB\u98B4\uE9C8"+ + "\u98B5\u98B6\u98B7\u98B8\u98B9\u98BA\u98BB\u98BC"+ + "\u98BD\u98BE\uB7AE\u98BF\u98C0\u98C1\u98C2\u98C3"+ + "\u98C4\u98C5\u98C6\u98C7\u98C8\u98C9\u98CA\uE9CB"+ + "\uE9CC\u98CB\u98CC\u98CD\u98CE\u98CF\u98D0\uD5C1"+ + "\u98D1\uC4A3\u98D2\u98D3\u98D4\u98D5\u98D6\u98D7"+ + "\uE9D8\u98D8\uBAE1\u98D9\u98DA\u98DB\u98DC\uE9C9"+ + "\u98DD\uD3A3\u98DE\u98DF\u98E0\uE9D4\u98E1\u98E2"+ + "\u98E3\u98E4\u98E5\u98E6\u98E7\uE9D7\uE9D0\u98E8"+ + "\u98E9\u98EA\u98EB\u98EC\uE9CF\u98ED\u98EE\uC7C1"+ + "\u98EF\u98F0\u98F1\u98F2\u98F3\u98F4\u98F5\u98F6"+ + "\uE9D2\u98F7\u98F8\u98F9\u98FA\u98FB\u98FC\u98FD"+ + "\uE9D9\uB3C8\u98FE\uE9D3\u9940\u9941\u9942\u9943"+ + "\u9944\uCFF0\u9945\u9946\u9947\uE9CD\u9948\u9949"+ + "\u994A\u994B\u994C\u994D\u994E\u994F\u9950\u9951"+ + "\u9952\uB3F7\u9953\u9954\u9955\u9956\u9957\u9958"+ + "\u9959\uE9D6\u995A\u995B\uE9DA\u995C\u995D\u995E"+ + "\uCCB4\u995F\u9960\u9961\uCFAD\u9962\u9963\u9964"+ + "\u9965\u9966\u9967\u9968\u9969\u996A\uE9D5\u996B"+ + "\uE9DC\uE9DB\u996C\u996D\u996E\u996F\u9970\uE9DE"+ + "\u9971\u9972\u9973\u9974\u9975\u9976\u9977\u9978"+ + "\uE9D1\u9979\u997A\u997B\u997C\u997D\u997E\u9980"+ + "\u9981\uE9DD\u9982\uE9DF\uC3CA\u9983\u9984\u9985"+ + "\u9986\u9987\u9988\u9989\u998A\u998B\u998C\u998D"+ + "\u998E\u998F\u9990\u9991\u9992\u9993\u9994\u9995"+ + "\u9996\u9997\u9998\u9999\u999A\u999B\u999C\u999D"+ + "\u999E\u999F\u99A0\u99A1\u99A2\u99A3\u99A4\u99A5"+ + "\u99A6\u99A7\u99A8\u99A9\u99AA\u99AB\u99AC\u99AD"+ + "\u99AE\u99AF\u99B0\u99B1\u99B2\u99B3\u99B4\u99B5"+ + "\u99B6\u99B7\u99B8\u99B9\u99BA\u99BB\u99BC\u99BD"+ + "\u99BE\u99BF\u99C0\u99C1\u99C2\u99C3\u99C4\u99C5"+ + "\u99C6\u99C7\u99C8\u99C9\u99CA\u99CB\u99CC\u99CD"+ + "\u99CE\u99CF\u99D0\u99D1\u99D2\u99D3\u99D4\u99D5"+ + "\u99D6\u99D7\u99D8\u99D9\u99DA\u99DB\u99DC\u99DD"+ + "\u99DE\u99DF\u99E0\u99E1\u99E2\u99E3\u99E4\u99E5"+ + "\u99E6\u99E7\u99E8\u99E9\u99EA\u99EB\u99EC\u99ED"+ + "\u99EE\u99EF\u99F0\u99F1\u99F2\u99F3\u99F4\u99F5"+ + "\uC7B7\uB4CE\uBBB6\uD0C0\uECA3\u99F6\u99F7\uC5B7"+ + "\u99F8\u99F9\u99FA\u99FB\u99FC\u99FD\u99FE\u9A40"+ + "\u9A41\u9A42\uD3FB\u9A43\u9A44\u9A45\u9A46\uECA4"+ + "\u9A47\uECA5\uC6DB\u9A48\u9A49\u9A4A\uBFEE\u9A4B"+ + "\u9A4C\u9A4D\u9A4E\uECA6\u9A4F\u9A50\uECA7\uD0AA"+ + "\u9A51\uC7B8\u9A52\u9A53\uB8E8\u9A54\u9A55\u9A56"+ + "\u9A57\u9A58\u9A59\u9A5A\u9A5B\u9A5C\u9A5D\u9A5E"+ + "\u9A5F\uECA8\u9A60\u9A61\u9A62\u9A63\u9A64\u9A65"+ + "\u9A66\u9A67\uD6B9\uD5FD\uB4CB\uB2BD\uCEE4\uC6E7"+ + "\u9A68\u9A69\uCDE1\u9A6A\u9A6B\u9A6C\u9A6D\u9A6E"+ + "\u9A6F\u9A70\u9A71\u9A72\u9A73\u9A74\u9A75\u9A76"+ + "\u9A77\uB4F5\u9A78\uCBC0\uBCDF\u9A79\u9A7A\u9A7B"+ + "\u9A7C\uE9E2\uE9E3\uD1EA\uE9E5\u9A7D\uB4F9\uE9E4"+ + "\u9A7E\uD1B3\uCAE2\uB2D0\u9A80\uE9E8\u9A81\u9A82"+ + "\u9A83\u9A84\uE9E6\uE9E7\u9A85\u9A86\uD6B3\u9A87"+ + "\u9A88\u9A89\uE9E9\uE9EA\u9A8A\u9A8B\u9A8C\u9A8D"+ + "\u9A8E\uE9EB\u9A8F\u9A90\u9A91\u9A92\u9A93\u9A94"+ + "\u9A95\u9A96\uE9EC\u9A97\u9A98\u9A99\u9A9A\u9A9B"+ + "\u9A9C\u9A9D\u9A9E\uECAF\uC5B9\uB6CE\u9A9F\uD2F3"+ + "\u9AA0\u9AA1\u9AA2\u9AA3\u9AA4\u9AA5\u9AA6\uB5EE"+ + "\u9AA7\uBBD9\uECB1\u9AA8\u9AA9\uD2E3\u9AAA\u9AAB"+ + "\u9AAC\u9AAD\u9AAE\uCEE3\u9AAF\uC4B8\u9AB0\uC3BF"+ + "\u9AB1\u9AB2\uB6BE\uD8B9\uB1C8\uB1CF\uB1D1\uC5FE"+ + "\u9AB3\uB1D0\u9AB4\uC3AB\u9AB5\u9AB6\u9AB7\u9AB8"+ + "\u9AB9\uD5B1\u9ABA\u9ABB\u9ABC\u9ABD\u9ABE\u9ABF"+ + "\u9AC0\u9AC1\uEBA4\uBAC1\u9AC2\u9AC3\u9AC4\uCCBA"+ + "\u9AC5\u9AC6\u9AC7\uEBA5\u9AC8\uEBA7\u9AC9\u9ACA"+ + "\u9ACB\uEBA8\u9ACC\u9ACD\u9ACE\uEBA6\u9ACF\u9AD0"+ + "\u9AD1\u9AD2\u9AD3\u9AD4\u9AD5\uEBA9\uEBAB\uEBAA"+ + "\u9AD6\u9AD7\u9AD8\u9AD9\u9ADA\uEBAC\u9ADB\uCACF"+ + "\uD8B5\uC3F1\u9ADC\uC3A5\uC6F8\uEBAD\uC4CA\u9ADD"+ + "\uEBAE\uEBAF\uEBB0\uB7D5\u9ADE\u9ADF\u9AE0\uB7FA"+ + "\u9AE1\uEBB1\uC7E2\u9AE2\uEBB3\u9AE3\uBAA4\uD1F5"+ + "\uB0B1\uEBB2\uEBB4\u9AE4\u9AE5\u9AE6\uB5AA\uC2C8"+ + "\uC7E8\u9AE7\uEBB5\u9AE8\uCBAE\uE3DF\u9AE9\u9AEA"+ + "\uD3C0\u9AEB\u9AEC\u9AED\u9AEE\uD9DB\u9AEF\u9AF0"+ + "\uCDA1\uD6AD\uC7F3\u9AF1\u9AF2\u9AF3\uD9E0\uBBE3"+ + "\u9AF4\uBABA\uE3E2\u9AF5\u9AF6\u9AF7\u9AF8\u9AF9"+ + "\uCFAB\u9AFA\u9AFB\u9AFC\uE3E0\uC9C7\u9AFD\uBAB9"+ + "\u9AFE\u9B40\u9B41\uD1B4\uE3E1\uC8EA\uB9AF\uBDAD"+ + "\uB3D8\uCEDB\u9B42\u9B43\uCCC0\u9B44\u9B45\u9B46"+ + "\uE3E8\uE3E9\uCDF4\u9B47\u9B48\u9B49\u9B4A\u9B4B"+ + "\uCCAD\u9B4C\uBCB3\u9B4D\uE3EA\u9B4E\uE3EB\u9B4F"+ + "\u9B50\uD0DA\u9B51\u9B52\u9B53\uC6FB\uB7DA\u9B54"+ + "\u9B55\uC7DF\uD2CA\uCED6\u9B56\uE3E4\uE3EC\u9B57"+ + "\uC9F2\uB3C1\u9B58\u9B59\uE3E7\u9B5A\u9B5B\uC6E3"+ + "\uE3E5\u9B5C\u9B5D\uEDB3\uE3E6\u9B5E\u9B5F\u9B60"+ + "\u9B61\uC9B3\u9B62\uC5E6\u9B63\u9B64\u9B65\uB9B5"+ + "\u9B66\uC3BB\u9B67\uE3E3\uC5BD\uC1A4\uC2D9\uB2D7"+ + "\u9B68\uE3ED\uBBA6\uC4AD\u9B69\uE3F0\uBEDA\u9B6A"+ + "\u9B6B\uE3FB\uE3F5\uBAD3\u9B6C\u9B6D\u9B6E\u9B6F"+ + "\uB7D0\uD3CD\u9B70\uD6CE\uD5D3\uB9C1\uD5B4\uD1D8"+ + "\u9B71\u9B72\u9B73\u9B74\uD0B9\uC7F6\u9B75\u9B76"+ + "\u9B77\uC8AA\uB2B4\u9B78\uC3DA\u9B79\u9B7A\u9B7B"+ + "\uE3EE\u9B7C\u9B7D\uE3FC\uE3EF\uB7A8\uE3F7\uE3F4"+ + "\u9B7E\u9B80\u9B81\uB7BA\u9B82\u9B83\uC5A2\u9B84"+ + "\uE3F6\uC5DD\uB2A8\uC6FC\u9B85\uC4E0\u9B86\u9B87"+ + "\uD7A2\u9B88\uC0E1\uE3F9\u9B89\u9B8A\uE3FA\uE3FD"+ + "\uCCA9\uE3F3\u9B8B\uD3BE\u9B8C\uB1C3\uEDB4\uE3F1"+ + "\uE3F2\u9B8D\uE3F8\uD0BA\uC6C3\uD4F3\uE3FE\u9B8E"+ + "\u9B8F\uBDE0\u9B90\u9B91\uE4A7\u9B92\u9B93\uE4A6"+ + "\u9B94\u9B95\u9B96\uD1F3\uE4A3\u9B97\uE4A9\u9B98"+ + "\u9B99\u9B9A\uC8F7\u9B9B\u9B9C\u9B9D\u9B9E\uCFB4"+ + "\u9B9F\uE4A8\uE4AE\uC2E5\u9BA0\u9BA1\uB6B4\u9BA2"+ + "\u9BA3\u9BA4\u9BA5\u9BA6\u9BA7\uBDF2\u9BA8\uE4A2"+ + "\u9BA9\u9BAA\uBAE9\uE4AA\u9BAB\u9BAC\uE4AC\u9BAD"+ + "\u9BAE\uB6FD\uD6DE\uE4B2\u9BAF\uE4AD\u9BB0\u9BB1"+ + "\u9BB2\uE4A1\u9BB3\uBBEE\uCDDD\uC7A2\uC5C9\u9BB4"+ + "\u9BB5\uC1F7\u9BB6\uE4A4\u9BB7\uC7B3\uBDAC\uBDBD"+ + "\uE4A5\u9BB8\uD7C7\uB2E2\u9BB9\uE4AB\uBCC3\uE4AF"+ + "\u9BBA\uBBEB\uE4B0\uC5A8\uE4B1\u9BBB\u9BBC\u9BBD"+ + "\u9BBE\uD5E3\uBFA3\u9BBF\uE4BA\u9BC0\uE4B7\u9BC1"+ + "\uE4BB\u9BC2\u9BC3\uE4BD\u9BC4\u9BC5\uC6D6\u9BC6"+ + "\u9BC7\uBAC6\uC0CB\u9BC8\u9BC9\u9BCA\uB8A1\uE4B4"+ + "\u9BCB\u9BCC\u9BCD\u9BCE\uD4A1\u9BCF\u9BD0\uBAA3"+ + "\uBDFE\u9BD1\u9BD2\u9BD3\uE4BC\u9BD4\u9BD5\u9BD6"+ + "\u9BD7\u9BD8\uCDBF\u9BD9\u9BDA\uC4F9\u9BDB\u9BDC"+ + "\uCFFB\uC9E6\u9BDD\u9BDE\uD3BF\u9BDF\uCFD1\u9BE0"+ + "\u9BE1\uE4B3\u9BE2\uE4B8\uE4B9\uCCE9\u9BE3\u9BE4"+ + "\u9BE5\u9BE6\u9BE7\uCCCE\u9BE8\uC0D4\uE4B5\uC1B0"+ + "\uE4B6\uCED0\u9BE9\uBBC1\uB5D3\u9BEA\uC8F3\uBDA7"+ + "\uD5C7\uC9AC\uB8A2\uE4CA\u9BEB\u9BEC\uE4CC\uD1C4"+ + "\u9BED\u9BEE\uD2BA\u9BEF\u9BF0\uBAAD\u9BF1\u9BF2"+ + "\uBAD4\u9BF3\u9BF4\u9BF5\u9BF6\u9BF7\u9BF8\uE4C3"+ + "\uB5ED\u9BF9\u9BFA\u9BFB\uD7CD\uE4C0\uCFFD\uE4BF"+ + "\u9BFC\u9BFD\u9BFE\uC1DC\uCCCA\u9C40\u9C41\u9C42"+ + "\u9C43\uCAE7\u9C44\u9C45\u9C46\u9C47\uC4D7\u9C48"+ + "\uCCD4\uE4C8\u9C49\u9C4A\u9C4B\uE4C7\uE4C1\u9C4C"+ + "\uE4C4\uB5AD\u9C4D\u9C4E\uD3D9\u9C4F\uE4C6\u9C50"+ + "\u9C51\u9C52\u9C53\uD2F9\uB4E3\u9C54\uBBB4\u9C55"+ + "\u9C56\uC9EE\u9C57\uB4BE\u9C58\u9C59\u9C5A\uBBEC"+ + "\u9C5B\uD1CD\u9C5C\uCCED\uEDB5\u9C5D\u9C5E\u9C5F"+ + "\u9C60\u9C61\u9C62\u9C63\u9C64\uC7E5\u9C65\u9C66"+ + "\u9C67\u9C68\uD4A8\u9C69\uE4CB\uD7D5\uE4C2\u9C6A"+ + "\uBDA5\uE4C5\u9C6B\u9C6C\uD3E6\u9C6D\uE4C9\uC9F8"+ + "\u9C6E\u9C6F\uE4BE\u9C70\u9C71\uD3E5\u9C72\u9C73"+ + "\uC7FE\uB6C9\u9C74\uD4FC\uB2B3\uE4D7\u9C75\u9C76"+ + "\u9C77\uCEC2\u9C78\uE4CD\u9C79\uCEBC\u9C7A\uB8DB"+ + "\u9C7B\u9C7C\uE4D6\u9C7D\uBFCA\u9C7E\u9C80\u9C81"+ + "\uD3CE\u9C82\uC3EC\u9C83\u9C84\u9C85\u9C86\u9C87"+ + "\u9C88\u9C89\u9C8A\uC5C8\uE4D8\u9C8B\u9C8C\u9C8D"+ + "\u9C8E\u9C8F\u9C90\u9C91\u9C92\uCDC4\uE4CF\u9C93"+ + "\u9C94\u9C95\u9C96\uE4D4\uE4D5\u9C97\uBAFE\u9C98"+ + "\uCFE6\u9C99\u9C9A\uD5BF\u9C9B\u9C9C\u9C9D\uE4D2"+ + "\u9C9E\u9C9F\u9CA0\u9CA1\u9CA2\u9CA3\u9CA4\u9CA5"+ + "\u9CA6\u9CA7\u9CA8\uE4D0\u9CA9\u9CAA\uE4CE\u9CAB"+ + "\u9CAC\u9CAD\u9CAE\u9CAF\u9CB0\u9CB1\u9CB2\u9CB3"+ + "\u9CB4\u9CB5\u9CB6\u9CB7\u9CB8\u9CB9\uCDE5\uCAAA"+ + "\u9CBA\u9CBB\u9CBC\uC0A3\u9CBD\uBDA6\uE4D3\u9CBE"+ + "\u9CBF\uB8C8\u9CC0\u9CC1\u9CC2\u9CC3\u9CC4\uE4E7"+ + "\uD4B4\u9CC5\u9CC6\u9CC7\u9CC8\u9CC9\u9CCA\u9CCB"+ + "\uE4DB\u9CCC\u9CCD\u9CCE\uC1EF\u9CCF\u9CD0\uE4E9"+ + "\u9CD1\u9CD2\uD2E7\u9CD3\u9CD4\uE4DF\u9CD5\uE4E0"+ + "\u9CD6\u9CD7\uCFAA\u9CD8\u9CD9\u9CDA\u9CDB\uCBDD"+ + "\u9CDC\uE4DA\uE4D1\u9CDD\uE4E5\u9CDE\uC8DC\uE4E3"+ + "\u9CDF\u9CE0\uC4E7\uE4E2\u9CE1\uE4E1\u9CE2\u9CE3"+ + "\u9CE4\uB3FC\uE4E8\u9CE5\u9CE6\u9CE7\u9CE8\uB5E1"+ + "\u9CE9\u9CEA\u9CEB\uD7CC\u9CEC\u9CED\u9CEE\uE4E6"+ + "\u9CEF\uBBAC\u9CF0\uD7D2\uCCCF\uEBF8\u9CF1\uE4E4"+ + "\u9CF2\u9CF3\uB9F6\u9CF4\u9CF5\u9CF6\uD6CD\uE4D9"+ + "\uE4DC\uC2FA\uE4DE\u9CF7\uC2CB\uC0C4\uC2D0\u9CF8"+ + "\uB1F5\uCCB2\u9CF9\u9CFA\u9CFB\u9CFC\u9CFD\u9CFE"+ + "\u9D40\u9D41\u9D42\u9D43\uB5CE\u9D44\u9D45\u9D46"+ + "\u9D47\uE4EF\u9D48\u9D49\u9D4A\u9D4B\u9D4C\u9D4D"+ + "\u9D4E\u9D4F\uC6AF\u9D50\u9D51\u9D52\uC6E1\u9D53"+ + "\u9D54\uE4F5\u9D55\u9D56\u9D57\u9D58\u9D59\uC2A9"+ + "\u9D5A\u9D5B\u9D5C\uC0EC\uD1DD\uE4EE\u9D5D\u9D5E"+ + "\u9D5F\u9D60\u9D61\u9D62\u9D63\u9D64\u9D65\u9D66"+ + "\uC4AE\u9D67\u9D68\u9D69\uE4ED\u9D6A\u9D6B\u9D6C"+ + "\u9D6D\uE4F6\uE4F4\uC2FE\u9D6E\uE4DD\u9D6F\uE4F0"+ + "\u9D70\uCAFE\u9D71\uD5C4\u9D72\u9D73\uE4F1\u9D74"+ + "\u9D75\u9D76\u9D77\u9D78\u9D79\u9D7A\uD1FA\u9D7B"+ + "\u9D7C\u9D7D\u9D7E\u9D80\u9D81\u9D82\uE4EB\uE4EC"+ + "\u9D83\u9D84\u9D85\uE4F2\u9D86\uCEAB\u9D87\u9D88"+ + "\u9D89\u9D8A\u9D8B\u9D8C\u9D8D\u9D8E\u9D8F\u9D90"+ + "\uC5CB\u9D91\u9D92\u9D93\uC7B1\u9D94\uC2BA\u9D95"+ + "\u9D96\u9D97\uE4EA\u9D98\u9D99\u9D9A\uC1CA\u9D9B"+ + "\u9D9C\u9D9D\u9D9E\u9D9F\u9DA0\uCCB6\uB3B1\u9DA1"+ + "\u9DA2\u9DA3\uE4FB\u9DA4\uE4F3\u9DA5\u9DA6\u9DA7"+ + "\uE4FA\u9DA8\uE4FD\u9DA9\uE4FC\u9DAA\u9DAB\u9DAC"+ + "\u9DAD\u9DAE\u9DAF\u9DB0\uB3CE\u9DB1\u9DB2\u9DB3"+ + "\uB3BA\uE4F7\u9DB4\u9DB5\uE4F9\uE4F8\uC5EC\u9DB6"+ + "\u9DB7\u9DB8\u9DB9\u9DBA\u9DBB\u9DBC\u9DBD\u9DBE"+ + "\u9DBF\u9DC0\u9DC1\u9DC2\uC0BD\u9DC3\u9DC4\u9DC5"+ + "\u9DC6\uD4E8\u9DC7\u9DC8\u9DC9\u9DCA\u9DCB\uE5A2"+ + "\u9DCC\u9DCD\u9DCE\u9DCF\u9DD0\u9DD1\u9DD2\u9DD3"+ + "\u9DD4\u9DD5\u9DD6\uB0C4\u9DD7\u9DD8\uE5A4\u9DD9"+ + "\u9DDA\uE5A3\u9DDB\u9DDC\u9DDD\u9DDE\u9DDF\u9DE0"+ + "\uBCA4\u9DE1\uE5A5\u9DE2\u9DE3\u9DE4\u9DE5\u9DE6"+ + "\u9DE7\uE5A1\u9DE8\u9DE9\u9DEA\u9DEB\u9DEC\u9DED"+ + "\u9DEE\uE4FE\uB1F4\u9DEF\u9DF0\u9DF1\u9DF2\u9DF3"+ + "\u9DF4\u9DF5\u9DF6\u9DF7\u9DF8\u9DF9\uE5A8\u9DFA"+ + "\uE5A9\uE5A6\u9DFB\u9DFC\u9DFD\u9DFE\u9E40\u9E41"+ + "\u9E42\u9E43\u9E44\u9E45\u9E46\u9E47\uE5A7\uE5AA"+ + "\u9E48\u9E49\u9E4A\u9E4B\u9E4C\u9E4D\u9E4E\u9E4F"+ + "\u9E50\u9E51\u9E52\u9E53\u9E54\u9E55\u9E56\u9E57"; + + private static final String innerEncoderIndex7= + "\u9E58\u9E59\u9E5A\u9E5B\u9E5C\u9E5D\u9E5E\u9E5F"+ + "\u9E60\u9E61\u9E62\u9E63\u9E64\u9E65\u9E66\u9E67"+ + "\u9E68\uC6D9\u9E69\u9E6A\u9E6B\u9E6C\u9E6D\u9E6E"+ + "\u9E6F\u9E70\uE5AB\uE5AD\u9E71\u9E72\u9E73\u9E74"+ + "\u9E75\u9E76\u9E77\uE5AC\u9E78\u9E79\u9E7A\u9E7B"+ + "\u9E7C\u9E7D\u9E7E\u9E80\u9E81\u9E82\u9E83\u9E84"+ + "\u9E85\u9E86\u9E87\u9E88\u9E89\uE5AF\u9E8A\u9E8B"+ + "\u9E8C\uE5AE\u9E8D\u9E8E\u9E8F\u9E90\u9E91\u9E92"+ + "\u9E93\u9E94\u9E95\u9E96\u9E97\u9E98\u9E99\u9E9A"+ + "\u9E9B\u9E9C\u9E9D\u9E9E\uB9E0\u9E9F\u9EA0\uE5B0"+ + "\u9EA1\u9EA2\u9EA3\u9EA4\u9EA5\u9EA6\u9EA7\u9EA8"+ + "\u9EA9\u9EAA\u9EAB\u9EAC\u9EAD\u9EAE\uE5B1\u9EAF"+ + "\u9EB0\u9EB1\u9EB2\u9EB3\u9EB4\u9EB5\u9EB6\u9EB7"+ + "\u9EB8\u9EB9\u9EBA\uBBF0\uECE1\uC3F0\u9EBB\uB5C6"+ + "\uBBD2\u9EBC\u9EBD\u9EBE\u9EBF\uC1E9\uD4EE\u9EC0"+ + "\uBEC4\u9EC1\u9EC2\u9EC3\uD7C6\u9EC4\uD4D6\uB2D3"+ + "\uECBE\u9EC5\u9EC6\u9EC7\u9EC8\uEAC1\u9EC9\u9ECA"+ + "\u9ECB\uC2AF\uB4B6\u9ECC\u9ECD\u9ECE\uD1D7\u9ECF"+ + "\u9ED0\u9ED1\uB3B4\u9ED2\uC8B2\uBFBB\uECC0\u9ED3"+ + "\u9ED4\uD6CB\u9ED5\u9ED6\uECBF\uECC1\u9ED7\u9ED8"+ + "\u9ED9\u9EDA\u9EDB\u9EDC\u9EDD\u9EDE\u9EDF\u9EE0"+ + "\u9EE1\u9EE2\u9EE3\uECC5\uBEE6\uCCBF\uC5DA\uBEBC"+ + "\u9EE4\uECC6\u9EE5\uB1FE\u9EE6\u9EE7\u9EE8\uECC4"+ + "\uD5A8\uB5E3\u9EE9\uECC2\uC1B6\uB3E3\u9EEA\u9EEB"+ + "\uECC3\uCBB8\uC0C3\uCCFE\u9EEC\u9EED\u9EEE\u9EEF"+ + "\uC1D2\u9EF0\uECC8\u9EF1\u9EF2\u9EF3\u9EF4\u9EF5"+ + "\u9EF6\u9EF7\u9EF8\u9EF9\u9EFA\u9EFB\u9EFC\u9EFD"+ + "\uBAE6\uC0D3\u9EFE\uD6F2\u9F40\u9F41\u9F42\uD1CC"+ + "\u9F43\u9F44\u9F45\u9F46\uBFBE\u9F47\uB7B3\uC9D5"+ + "\uECC7\uBBE2\u9F48\uCCCC\uBDFD\uC8C8\u9F49\uCFA9"+ + "\u9F4A\u9F4B\u9F4C\u9F4D\u9F4E\u9F4F\u9F50\uCDE9"+ + "\u9F51\uC5EB\u9F52\u9F53\u9F54\uB7E9\u9F55\u9F56"+ + "\u9F57\u9F58\u9F59\u9F5A\u9F5B\u9F5C\u9F5D\u9F5E"+ + "\u9F5F\uD1C9\uBAB8\u9F60\u9F61\u9F62\u9F63\u9F64"+ + "\uECC9\u9F65\u9F66\uECCA\u9F67\uBBC0\uECCB\u9F68"+ + "\uECE2\uB1BA\uB7D9\u9F69\u9F6A\u9F6B\u9F6C\u9F6D"+ + "\u9F6E\u9F6F\u9F70\u9F71\u9F72\u9F73\uBDB9\u9F74"+ + "\u9F75\u9F76\u9F77\u9F78\u9F79\u9F7A\u9F7B\uECCC"+ + "\uD1E6\uECCD\u9F7C\u9F7D\u9F7E\u9F80\uC8BB\u9F81"+ + "\u9F82\u9F83\u9F84\u9F85\u9F86\u9F87\u9F88\u9F89"+ + "\u9F8A\u9F8B\u9F8C\u9F8D\u9F8E\uECD1\u9F8F\u9F90"+ + "\u9F91\u9F92\uECD3\u9F93\uBBCD\u9F94\uBCE5\u9F95"+ + "\u9F96\u9F97\u9F98\u9F99\u9F9A\u9F9B\u9F9C\u9F9D"+ + "\u9F9E\u9F9F\u9FA0\u9FA1\uECCF\u9FA2\uC9B7\u9FA3"+ + "\u9FA4\u9FA5\u9FA6\u9FA7\uC3BA\u9FA8\uECE3\uD5D5"+ + "\uECD0\u9FA9\u9FAA\u9FAB\u9FAC\u9FAD\uD6F3\u9FAE"+ + "\u9FAF\u9FB0\uECD2\uECCE\u9FB1\u9FB2\u9FB3\u9FB4"+ + "\uECD4\u9FB5\uECD5\u9FB6\u9FB7\uC9BF\u9FB8\u9FB9"+ + "\u9FBA\u9FBB\u9FBC\u9FBD\uCFA8\u9FBE\u9FBF\u9FC0"+ + "\u9FC1\u9FC2\uD0DC\u9FC3\u9FC4\u9FC5\u9FC6\uD1AC"+ + "\u9FC7\u9FC8\u9FC9\u9FCA\uC8DB\u9FCB\u9FCC\u9FCD"+ + "\uECD6\uCEF5\u9FCE\u9FCF\u9FD0\u9FD1\u9FD2\uCAEC"+ + "\uECDA\u9FD3\u9FD4\u9FD5\u9FD6\u9FD7\u9FD8\u9FD9"+ + "\uECD9\u9FDA\u9FDB\u9FDC\uB0BE\u9FDD\u9FDE\u9FDF"+ + "\u9FE0\u9FE1\u9FE2\uECD7\u9FE3\uECD8\u9FE4\u9FE5"+ + "\u9FE6\uECE4\u9FE7\u9FE8\u9FE9\u9FEA\u9FEB\u9FEC"+ + "\u9FED\u9FEE\u9FEF\uC8BC\u9FF0\u9FF1\u9FF2\u9FF3"+ + "\u9FF4\u9FF5\u9FF6\u9FF7\u9FF8\u9FF9\uC1C7\u9FFA"+ + "\u9FFB\u9FFC\u9FFD\u9FFE\uECDC\uD1E0\uA040\uA041"+ + "\uA042\uA043\uA044\uA045\uA046\uA047\uA048\uA049"+ + "\uECDB\uA04A\uA04B\uA04C\uA04D\uD4EF\uA04E\uECDD"+ + "\uA04F\uA050\uA051\uA052\uA053\uA054\uDBC6\uA055"+ + "\uA056\uA057\uA058\uA059\uA05A\uA05B\uA05C\uA05D"+ + "\uA05E\uECDE\uA05F\uA060\uA061\uA062\uA063\uA064"+ + "\uA065\uA066\uA067\uA068\uA069\uA06A\uB1AC\uA06B"+ + "\uA06C\uA06D\uA06E\uA06F\uA070\uA071\uA072\uA073"+ + "\uA074\uA075\uA076\uA077\uA078\uA079\uA07A\uA07B"+ + "\uA07C\uA07D\uA07E\uA080\uA081\uECDF\uA082\uA083"+ + "\uA084\uA085\uA086\uA087\uA088\uA089\uA08A\uA08B"+ + "\uECE0\uA08C\uD7A6\uA08D\uC5C0\uA08E\uA08F\uA090"+ + "\uEBBC\uB0AE\uA091\uA092\uA093\uBEF4\uB8B8\uD2AF"+ + "\uB0D6\uB5F9\uA094\uD8B3\uA095\uCBAC\uA096\uE3DD"+ + "\uA097\uA098\uA099\uA09A\uA09B\uA09C\uA09D\uC6AC"+ + "\uB0E6\uA09E\uA09F\uA0A0\uC5C6\uEBB9\uA0A1\uA0A2"+ + "\uA0A3\uA0A4\uEBBA\uA0A5\uA0A6\uA0A7\uEBBB\uA0A8"+ + "\uA0A9\uD1C0\uA0AA\uC5A3\uA0AB\uEAF2\uA0AC\uC4B2"+ + "\uA0AD\uC4B5\uC0CE\uA0AE\uA0AF\uA0B0\uEAF3\uC4C1"+ + "\uA0B1\uCEEF\uA0B2\uA0B3\uA0B4\uA0B5\uEAF0\uEAF4"+ + "\uA0B6\uA0B7\uC9FC\uA0B8\uA0B9\uC7A3\uA0BA\uA0BB"+ + "\uA0BC\uCCD8\uCEFE\uA0BD\uA0BE\uA0BF\uEAF5\uEAF6"+ + "\uCFAC\uC0E7\uA0C0\uA0C1\uEAF7\uA0C2\uA0C3\uA0C4"+ + "\uA0C5\uA0C6\uB6BF\uEAF8\uA0C7\uEAF9\uA0C8\uEAFA"+ + "\uA0C9\uA0CA\uEAFB\uA0CB\uA0CC\uA0CD\uA0CE\uA0CF"+ + "\uA0D0\uA0D1\uA0D2\uA0D3\uA0D4\uA0D5\uA0D6\uEAF1"+ + "\uA0D7\uA0D8\uA0D9\uA0DA\uA0DB\uA0DC\uA0DD\uA0DE"+ + "\uA0DF\uA0E0\uA0E1\uA0E2\uC8AE\uE1EB\uA0E3\uB7B8"+ + "\uE1EC\uA0E4\uA0E5\uA0E6\uE1ED\uA0E7\uD7B4\uE1EE"+ + "\uE1EF\uD3CC\uA0E8\uA0E9\uA0EA\uA0EB\uA0EC\uA0ED"+ + "\uA0EE\uE1F1\uBFF1\uE1F0\uB5D2\uA0EF\uA0F0\uA0F1"+ + "\uB1B7\uA0F2\uA0F3\uA0F4\uA0F5\uE1F3\uE1F2\uA0F6"+ + "\uBAFC\uA0F7\uE1F4\uA0F8\uA0F9\uA0FA\uA0FB\uB9B7"+ + "\uA0FC\uBED1\uA0FD\uA0FE\uAA40\uAA41\uC4FC\uAA42"+ + "\uBADD\uBDC6\uAA43\uAA44\uAA45\uAA46\uAA47\uAA48"+ + "\uE1F5\uE1F7\uAA49\uAA4A\uB6C0\uCFC1\uCAA8\uE1F6"+ + "\uD5F8\uD3FC\uE1F8\uE1FC\uE1F9\uAA4B\uAA4C\uE1FA"+ + "\uC0EA\uAA4D\uE1FE\uE2A1\uC0C7\uAA4E\uAA4F\uAA50"+ + "\uAA51\uE1FB\uAA52\uE1FD\uAA53\uAA54\uAA55\uAA56"+ + "\uAA57\uAA58\uE2A5\uAA59\uAA5A\uAA5B\uC1D4\uAA5C"+ + "\uAA5D\uAA5E\uAA5F\uE2A3\uAA60\uE2A8\uB2FE\uE2A2"+ + "\uAA61\uAA62\uAA63\uC3CD\uB2C2\uE2A7\uE2A6\uAA64"+ + "\uAA65\uE2A4\uE2A9\uAA66\uAA67\uE2AB\uAA68\uAA69"+ + "\uAA6A\uD0C9\uD6ED\uC3A8\uE2AC\uAA6B\uCFD7\uAA6C"+ + "\uAA6D\uE2AE\uAA6E\uAA6F\uBAEF\uAA70\uAA71\uE9E0"+ + "\uE2AD\uE2AA\uAA72\uAA73\uAA74\uAA75\uBBAB\uD4B3"+ + "\uAA76\uAA77\uAA78\uAA79\uAA7A\uAA7B\uAA7C\uAA7D"+ + "\uAA7E\uAA80\uAA81\uAA82\uAA83\uE2B0\uAA84\uAA85"+ + "\uE2AF\uAA86\uE9E1\uAA87\uAA88\uAA89\uAA8A\uE2B1"+ + "\uAA8B\uAA8C\uAA8D\uAA8E\uAA8F\uAA90\uAA91\uAA92"+ + "\uE2B2\uAA93\uAA94\uAA95\uAA96\uAA97\uAA98\uAA99"+ + "\uAA9A\uAA9B\uAA9C\uAA9D\uE2B3\uCCA1\uAA9E\uE2B4"+ + "\uAA9F\uAAA0\uAB40\uAB41\uAB42\uAB43\uAB44\uAB45"+ + "\uAB46\uAB47\uAB48\uAB49\uAB4A\uAB4B\uE2B5\uAB4C"+ + "\uAB4D\uAB4E\uAB4F\uAB50\uD0FE\uAB51\uAB52\uC2CA"+ + "\uAB53\uD3F1\uAB54\uCDF5\uAB55\uAB56\uE7E0\uAB57"+ + "\uAB58\uE7E1\uAB59\uAB5A\uAB5B\uAB5C\uBEC1\uAB5D"+ + "\uAB5E\uAB5F\uAB60\uC2EA\uAB61\uAB62\uAB63\uE7E4"+ + "\uAB64\uAB65\uE7E3\uAB66\uAB67\uAB68\uAB69\uAB6A"+ + "\uAB6B\uCDE6\uAB6C\uC3B5\uAB6D\uAB6E\uE7E2\uBBB7"+ + "\uCFD6\uAB6F\uC1E1\uE7E9\uAB70\uAB71\uAB72\uE7E8"+ + "\uAB73\uAB74\uE7F4\uB2A3\uAB75\uAB76\uAB77\uAB78"+ + "\uE7EA\uAB79\uE7E6\uAB7A\uAB7B\uAB7C\uAB7D\uAB7E"+ + "\uE7EC\uE7EB\uC9BA\uAB80\uAB81\uD5E4\uAB82\uE7E5"+ + "\uB7A9\uE7E7\uAB83\uAB84\uAB85\uAB86\uAB87\uAB88"+ + "\uAB89\uE7EE\uAB8A\uAB8B\uAB8C\uAB8D\uE7F3\uAB8E"+ + "\uD6E9\uAB8F\uAB90\uAB91\uAB92\uE7ED\uAB93\uE7F2"+ + "\uAB94\uE7F1\uAB95\uAB96\uAB97\uB0E0\uAB98\uAB99"+ + "\uAB9A\uAB9B\uE7F5\uAB9C\uAB9D\uAB9E\uAB9F\uABA0"+ + "\uAC40\uAC41\uAC42\uAC43\uAC44\uAC45\uAC46\uAC47"+ + "\uAC48\uAC49\uAC4A\uC7F2\uAC4B\uC0C5\uC0ED\uAC4C"+ + "\uAC4D\uC1F0\uE7F0\uAC4E\uAC4F\uAC50\uAC51\uE7F6"+ + "\uCBF6\uAC52\uAC53\uAC54\uAC55\uAC56\uAC57\uAC58"+ + "\uAC59\uAC5A\uE8A2\uE8A1\uAC5B\uAC5C\uAC5D\uAC5E"+ + "\uAC5F\uAC60\uD7C1\uAC61\uAC62\uE7FA\uE7F9\uAC63"+ + "\uE7FB\uAC64\uE7F7\uAC65\uE7FE\uAC66\uE7FD\uAC67"+ + "\uE7FC\uAC68\uAC69\uC1D5\uC7D9\uC5FD\uC5C3\uAC6A"+ + "\uAC6B\uAC6C\uAC6D\uAC6E\uC7ED\uAC6F\uAC70\uAC71"+ + "\uAC72\uE8A3\uAC73\uAC74\uAC75\uAC76\uAC77\uAC78"+ + "\uAC79\uAC7A\uAC7B\uAC7C\uAC7D\uAC7E\uAC80\uAC81"+ + "\uAC82\uAC83\uAC84\uAC85\uAC86\uE8A6\uAC87\uE8A5"+ + "\uAC88\uE8A7\uBAF7\uE7F8\uE8A4\uAC89\uC8F0\uC9AA"+ + "\uAC8A\uAC8B\uAC8C\uAC8D\uAC8E\uAC8F\uAC90\uAC91"+ + "\uAC92\uAC93\uAC94\uAC95\uAC96\uE8A9\uAC97\uAC98"+ + "\uB9E5\uAC99\uAC9A\uAC9B\uAC9C\uAC9D\uD1FE\uE8A8"+ + "\uAC9E\uAC9F\uACA0\uAD40\uAD41\uAD42\uE8AA\uAD43"+ + "\uE8AD\uE8AE\uAD44\uC1A7\uAD45\uAD46\uAD47\uE8AF"+ + "\uAD48\uAD49\uAD4A\uE8B0\uAD4B\uAD4C\uE8AC\uAD4D"+ + "\uE8B4\uAD4E\uAD4F\uAD50\uAD51\uAD52\uAD53\uAD54"+ + "\uAD55\uAD56\uAD57\uAD58\uE8AB\uAD59\uE8B1\uAD5A"+ + "\uAD5B\uAD5C\uAD5D\uAD5E\uAD5F\uAD60\uAD61\uE8B5"+ + "\uE8B2\uE8B3\uAD62\uAD63\uAD64\uAD65\uAD66\uAD67"+ + "\uAD68\uAD69\uAD6A\uAD6B\uAD6C\uAD6D\uAD6E\uAD6F"+ + "\uAD70\uAD71\uE8B7\uAD72\uAD73\uAD74\uAD75\uAD76"+ + "\uAD77\uAD78\uAD79\uAD7A\uAD7B\uAD7C\uAD7D\uAD7E"+ + "\uAD80\uAD81\uAD82\uAD83\uAD84\uAD85\uAD86\uAD87"+ + "\uAD88\uAD89\uE8B6\uAD8A\uAD8B\uAD8C\uAD8D\uAD8E"+ + "\uAD8F\uAD90\uAD91\uAD92\uB9CF\uAD93\uF0AC\uAD94"+ + "\uF0AD\uAD95\uC6B0\uB0EA\uC8BF\uAD96\uCDDF\uAD97"+ + "\uAD98\uAD99\uAD9A\uAD9B\uAD9C\uAD9D\uCECD\uEAB1"+ + "\uAD9E\uAD9F\uADA0\uAE40\uEAB2\uAE41\uC6BF\uB4C9"+ + "\uAE42\uAE43\uAE44\uAE45\uAE46\uAE47\uAE48\uEAB3"+ + "\uAE49\uAE4A\uAE4B\uAE4C\uD5E7\uAE4D\uAE4E\uAE4F"+ + "\uAE50\uAE51\uAE52\uAE53\uAE54\uDDF9\uAE55\uEAB4"+ + "\uAE56\uEAB5\uAE57\uEAB6\uAE58\uAE59\uAE5A\uAE5B"+ + "\uB8CA\uDFB0\uC9F5\uAE5C\uCCF0\uAE5D\uAE5E\uC9FA"+ + "\uAE5F\uAE60\uAE61\uAE62\uAE63\uC9FB\uAE64\uAE65"+ + "\uD3C3\uCBA6\uAE66\uB8A6\uF0AE\uB1C2\uAE67\uE5B8"+ + "\uCCEF\uD3C9\uBCD7\uC9EA\uAE68\uB5E7\uAE69\uC4D0"+ + "\uB5E9\uAE6A\uEEAE\uBBAD\uAE6B\uAE6C\uE7DE\uAE6D"+ + "\uEEAF\uAE6E\uAE6F\uAE70\uAE71\uB3A9\uAE72\uAE73"+ + "\uEEB2\uAE74\uAE75\uEEB1\uBDE7\uAE76\uEEB0\uCEB7"+ + "\uAE77\uAE78\uAE79\uAE7A\uC5CF\uAE7B\uAE7C\uAE7D"+ + "\uAE7E\uC1F4\uDBCE\uEEB3\uD0F3\uAE80\uAE81\uAE82"+ + "\uAE83\uAE84\uAE85\uAE86\uAE87\uC2D4\uC6E8\uAE88"+ + "\uAE89\uAE8A\uB7AC\uAE8B\uAE8C\uAE8D\uAE8E\uAE8F"+ + "\uAE90\uAE91\uEEB4\uAE92\uB3EB\uAE93\uAE94\uAE95"+ + "\uBBFB\uEEB5\uAE96\uAE97\uAE98\uAE99\uAE9A\uE7DC"+ + "\uAE9B\uAE9C\uAE9D\uEEB6\uAE9E\uAE9F\uBDAE\uAEA0"+ + "\uAF40\uAF41\uAF42\uF1E2\uAF43\uAF44\uAF45\uCAE8"+ + "\uAF46\uD2C9\uF0DA\uAF47\uF0DB\uAF48\uF0DC\uC1C6"+ + "\uAF49\uB8ED\uBECE\uAF4A\uAF4B\uF0DE\uAF4C\uC5B1"+ + "\uF0DD\uD1F1\uAF4D\uF0E0\uB0CC\uBDEA\uAF4E\uAF4F"+ + "\uAF50\uAF51\uAF52\uD2DF\uF0DF\uAF53\uB4AF\uB7E8"+ + "\uF0E6\uF0E5\uC6A3\uF0E1\uF0E2\uB4C3\uAF54\uAF55"+ + "\uF0E3\uD5EE\uAF56\uAF57\uCCDB\uBED2\uBCB2\uAF58"+ + "\uAF59\uAF5A\uF0E8\uF0E7\uF0E4\uB2A1\uAF5B\uD6A2"+ + "\uD3B8\uBEB7\uC8AC\uAF5C\uAF5D\uF0EA\uAF5E\uAF5F"+ + "\uAF60\uAF61\uD1F7\uAF62\uD6CC\uBADB\uF0E9\uAF63"+ + "\uB6BB\uAF64\uAF65\uCDB4\uAF66\uAF67\uC6A6\uAF68"+ + "\uAF69\uAF6A\uC1A1\uF0EB\uF0EE\uAF6B\uF0ED\uF0F0"+ + "\uF0EC\uAF6C\uBBBE\uF0EF\uAF6D\uAF6E\uAF6F\uAF70"+ + "\uCCB5\uF0F2\uAF71\uAF72\uB3D5\uAF73\uAF74\uAF75"+ + "\uAF76\uB1D4\uAF77\uAF78\uF0F3\uAF79\uAF7A\uF0F4"+ + "\uF0F6\uB4E1\uAF7B\uF0F1\uAF7C\uF0F7\uAF7D\uAF7E"+ + "\uAF80\uAF81\uF0FA\uAF82\uF0F8\uAF83\uAF84\uAF85"+ + "\uF0F5\uAF86\uAF87\uAF88\uAF89\uF0FD\uAF8A\uF0F9"+ + "\uF0FC\uF0FE\uAF8B\uF1A1\uAF8C\uAF8D\uAF8E\uCEC1"+ + "\uF1A4\uAF8F\uF1A3\uAF90\uC1F6\uF0FB\uCADD\uAF91"+ + "\uAF92\uB4F1\uB1F1\uCCB1\uAF93\uF1A6\uAF94\uAF95"+ + "\uF1A7\uAF96\uAF97\uF1AC\uD5CE\uF1A9\uAF98\uAF99"+ + "\uC8B3\uAF9A\uAF9B\uAF9C\uF1A2\uAF9D\uF1AB\uF1A8"+ + "\uF1A5\uAF9E\uAF9F\uF1AA\uAFA0\uB040\uB041\uB042"+ + "\uB043\uB044\uB045\uB046\uB0A9\uF1AD\uB047\uB048"+ + "\uB049\uB04A\uB04B\uB04C\uF1AF\uB04D\uF1B1\uB04E"+ + "\uB04F\uB050\uB051\uB052\uF1B0\uB053\uF1AE\uB054"+ + "\uB055\uB056\uB057\uD1A2\uB058\uB059\uB05A\uB05B"+ + "\uB05C\uB05D\uB05E\uF1B2\uB05F\uB060\uB061\uF1B3"+ + "\uB062\uB063\uB064\uB065\uB066\uB067\uB068\uB069"+ + "\uB9EF\uB06A\uB06B\uB5C7\uB06C\uB0D7\uB0D9\uB06D"+ + "\uB06E\uB06F\uD4ED\uB070\uB5C4\uB071\uBDD4\uBBCA"+ + "\uF0A7\uB072\uB073\uB8DE\uB074\uB075\uF0A8\uB076"+ + "\uB077\uB0A8\uB078\uF0A9\uB079\uB07A\uCDEE\uB07B"+ + "\uB07C\uF0AA\uB07D\uB07E\uB080\uB081\uB082\uB083"+ + "\uB084\uB085\uB086\uB087\uF0AB\uB088\uB089\uB08A"+ + "\uB08B\uB08C\uB08D\uB08E\uB08F\uB090\uC6A4\uB091"+ + "\uB092\uD6E5\uF1E4\uB093\uF1E5\uB094\uB095\uB096"+ + "\uB097\uB098\uB099\uB09A\uB09B\uB09C\uB09D\uC3F3"+ + "\uB09E\uB09F\uD3DB\uB0A0\uB140\uD6D1\uC5E8\uB141"+ + "\uD3AF\uB142\uD2E6\uB143\uB144\uEEC1\uB0BB\uD5B5"+ + "\uD1CE\uBCE0\uBAD0\uB145\uBFF8\uB146\uB8C7\uB5C1"+ + "\uC5CC\uB147\uB148\uCAA2\uB149\uB14A\uB14B\uC3CB"+ + "\uB14C\uB14D\uB14E\uB14F\uB150\uEEC2\uB151\uB152"+ + "\uB153\uB154\uB155\uB156\uB157\uB158\uC4BF\uB6A2"+ + "\uB159\uEDEC\uC3A4\uB15A\uD6B1\uB15B\uB15C\uB15D"+ + "\uCFE0\uEDEF\uB15E\uB15F\uC5CE\uB160\uB6DC\uB161"+ + "\uB162\uCAA1\uB163\uB164\uEDED\uB165\uB166\uEDF0"+ + "\uEDF1\uC3BC\uB167\uBFB4\uB168\uEDEE\uB169\uB16A"+ + "\uB16B\uB16C\uB16D\uB16E\uB16F\uB170\uB171\uB172"+ + "\uB173\uEDF4\uEDF2\uB174\uB175\uB176\uB177\uD5E6"+ + "\uC3DF\uB178\uEDF3\uB179\uB17A\uB17B\uEDF6\uB17C"+ + "\uD5A3\uD1A3\uB17D\uB17E\uB180\uEDF5\uB181\uC3D0"+ + "\uB182\uB183\uB184\uB185\uB186\uEDF7\uBFF4\uBEEC"+ + "\uEDF8\uB187\uCCF7\uB188\uD1DB\uB189\uB18A\uB18B"+ + "\uD7C5\uD5F6\uB18C\uEDFC\uB18D\uB18E\uB18F\uEDFB"+ + "\uB190\uB191\uB192\uB193\uB194\uB195\uB196\uB197"+ + "\uEDF9\uEDFA\uB198\uB199\uB19A\uB19B\uB19C\uB19D"+ + "\uB19E\uB19F\uEDFD\uBEA6\uB1A0\uB240\uB241\uB242"+ + "\uB243\uCBAF\uEEA1\uB6BD\uB244\uEEA2\uC4C0\uB245"+ + "\uEDFE\uB246\uB247\uBDDE\uB2C7\uB248\uB249\uB24A"+ + "\uB24B\uB24C\uB24D\uB24E\uB24F\uB250\uB251\uB252"+ + "\uB253\uB6C3\uB254\uB255\uB256\uEEA5\uD8BA\uEEA3"+ + "\uEEA6\uB257\uB258\uB259\uC3E9\uB3F2\uB25A\uB25B"+ + "\uB25C\uB25D\uB25E\uB25F\uEEA7\uEEA4\uCFB9\uB260"+ + "\uB261\uEEA8\uC2F7\uB262\uB263\uB264\uB265\uB266"+ + "\uB267\uB268\uB269\uB26A\uB26B\uB26C\uB26D\uEEA9"+ + "\uEEAA\uB26E\uDEAB\uB26F\uB270\uC6B3\uB271\uC7C6"+ + "\uB272\uD6F5\uB5C9\uB273\uCBB2\uB274\uB275\uB276"+ + "\uEEAB\uB277\uB278\uCDAB\uB279\uEEAC\uB27A\uB27B"+ + "\uB27C\uB27D\uB27E\uD5B0\uB280\uEEAD\uB281\uF6C4"+ + "\uB282\uB283\uB284\uB285\uB286\uB287\uB288\uB289"+ + "\uB28A\uB28B\uB28C\uB28D\uB28E\uDBC7\uB28F\uB290"+ + "\uB291\uB292\uB293\uB294\uB295\uB296\uB297\uB4A3"+ + "\uB298\uB299\uB29A\uC3AC\uF1E6\uB29B\uB29C\uB29D"+ + "\uB29E\uB29F\uCAB8\uD2D3\uB2A0\uD6AA\uB340\uEFF2"+ + "\uB341\uBED8\uB342\uBDC3\uEFF3\uB6CC\uB0AB\uB343"+ + "\uB344\uB345\uB346\uCAAF\uB347\uB348\uEDB6\uB349"+ + "\uEDB7\uB34A\uB34B\uB34C\uB34D\uCEF9\uB7AF\uBFF3"+ + "\uEDB8\uC2EB\uC9B0\uB34E\uB34F\uB350\uB351\uB352"+ + "\uB353\uEDB9\uB354\uB355\uC6F6\uBFB3\uB356\uB357"+ + "\uB358\uEDBC\uC5F8\uB359\uD1D0\uB35A\uD7A9\uEDBA"+ + "\uEDBB\uB35B\uD1E2\uB35C\uEDBF\uEDC0\uB35D\uEDC4"+ + "\uB35E\uB35F\uB360\uEDC8\uB361\uEDC6\uEDCE\uD5E8"+ + "\uB362\uEDC9\uB363\uB364\uEDC7\uEDBE\uB365\uB366"+ + "\uC5E9\uB367\uB368\uB369\uC6C6\uB36A\uB36B\uC9E9"+ + "\uD4D2\uEDC1\uEDC2\uEDC3\uEDC5\uB36C\uC0F9\uB36D"+ + "\uB4A1\uB36E\uB36F\uB370\uB371\uB9E8\uB372\uEDD0"+ + "\uB373\uB374\uB375\uB376\uEDD1\uB377\uEDCA\uB378"+ + "\uEDCF\uB379\uCEF8\uB37A\uB37B\uCBB6\uEDCC\uEDCD"+ + "\uB37C\uB37D\uB37E\uB380\uB381\uCFF5\uB382\uB383"+ + "\uB384\uB385\uB386\uB387\uB388\uB389\uB38A\uB38B"+ + "\uB38C\uB38D\uEDD2\uC1F2\uD3B2\uEDCB\uC8B7\uB38E"+ + "\uB38F\uB390\uB391\uB392\uB393\uB394\uB395\uBCEF"+ + "\uB396\uB397\uB398\uB399\uC5F0\uB39A\uB39B\uB39C"+ + "\uB39D\uB39E\uB39F\uB3A0\uB440\uB441\uB442\uEDD6"+ + "\uB443\uB5EF\uB444\uB445\uC2B5\uB0AD\uCBE9\uB446"+ + "\uB447\uB1AE\uB448\uEDD4\uB449\uB44A\uB44B\uCDEB"+ + "\uB5E2\uB44C\uEDD5\uEDD3\uEDD7\uB44D\uB44E\uB5FA"+ + "\uB44F\uEDD8\uB450\uEDD9\uB451\uEDDC\uB452\uB1CC"+ + "\uB453\uB454\uB455\uB456\uB457\uB458\uB459\uB45A"+ + "\uC5F6\uBCEE\uEDDA\uCCBC\uB2EA\uB45B\uB45C\uB45D"+ + "\uB45E\uEDDB\uB45F\uB460\uB461\uB462\uC4EB\uB463"+ + "\uB464\uB4C5\uB465\uB466\uB467\uB0F5\uB468\uB469"+ + "\uB46A\uEDDF\uC0DA\uB4E8\uB46B\uB46C\uB46D\uB46E"+ + "\uC5CD\uB46F\uB470\uB471\uEDDD\uBFC4\uB472\uB473"+ + "\uB474\uEDDE\uB475\uB476\uB477\uB478\uB479\uB47A"+ + "\uB47B\uB47C\uB47D\uB47E\uB480\uB481\uB482\uB483"+ + "\uC4A5\uB484\uB485\uB486\uEDE0\uB487\uB488\uB489"+ + "\uB48A\uB48B\uEDE1\uB48C\uEDE3\uB48D\uB48E\uC1D7"+ + "\uB48F\uB490\uBBC7\uB491\uB492\uB493\uB494\uB495"+ + "\uB496\uBDB8\uB497\uB498\uB499\uEDE2\uB49A\uB49B"+ + "\uB49C\uB49D\uB49E\uB49F\uB4A0\uB540\uB541\uB542"+ + "\uB543\uB544\uB545\uEDE4\uB546\uB547\uB548\uB549"+ + "\uB54A\uB54B\uB54C\uB54D\uB54E\uB54F\uEDE6\uB550"+ + "\uB551\uB552\uB553\uB554\uEDE5\uB555\uB556\uB557"+ + "\uB558\uB559\uB55A\uB55B\uB55C\uB55D\uB55E\uB55F"+ + "\uB560\uB561\uB562\uB563\uEDE7\uB564\uB565\uB566"+ + "\uB567\uB568\uCABE\uECEA\uC0F1\uB569\uC9E7\uB56A"+ + "\uECEB\uC6EE\uB56B\uB56C\uB56D\uB56E\uECEC\uB56F"+ + "\uC6ED\uECED\uB570\uB571\uB572\uB573\uB574\uB575"+ + "\uB576\uB577\uB578\uECF0\uB579\uB57A\uD7E6\uECF3"+ + "\uB57B\uB57C\uECF1\uECEE\uECEF\uD7A3\uC9F1\uCBEE"+ + "\uECF4\uB57D\uECF2\uB57E\uB580\uCFE9\uB581\uECF6"+ + "\uC6B1\uB582\uB583\uB584\uB585\uBCC0\uB586\uECF5"+ + "\uB587\uB588\uB589\uB58A\uB58B\uB58C\uB58D\uB5BB"+ + "\uBBF6\uB58E\uECF7\uB58F\uB590\uB591\uB592\uB593"+ + "\uD9F7\uBDFB\uB594\uB595\uC2BB\uECF8\uB596\uB597"+ + "\uB598\uB599\uECF9\uB59A\uB59B\uB59C\uB59D\uB8A3"+ + "\uB59E\uB59F\uB5A0\uB640\uB641\uB642\uB643\uB644"+ + "\uB645\uB646\uECFA\uB647\uB648\uB649\uB64A\uB64B"+ + "\uB64C\uB64D\uB64E\uB64F\uB650\uB651\uB652\uECFB"+ + "\uB653\uB654\uB655\uB656\uB657\uB658\uB659\uB65A"+ + "\uB65B\uB65C\uB65D\uECFC\uB65E\uB65F\uB660\uB661"+ + "\uB662\uD3ED\uD8AE\uC0EB\uB663\uC7DD\uBACC\uB664"+ + "\uD0E3\uCBBD\uB665\uCDBA\uB666\uB667\uB8D1\uB668"+ + "\uB669\uB1FC\uB66A\uC7EF\uB66B\uD6D6\uB66C\uB66D"+ + "\uB66E\uBFC6\uC3EB\uB66F\uB670\uEFF5\uB671\uB672"+ + "\uC3D8\uB673\uB674\uB675\uB676\uB677\uB678\uD7E2"+ + "\uB679\uB67A\uB67B\uEFF7\uB3D3\uB67C\uC7D8\uD1ED"+ + "\uB67D\uD6C8\uB67E\uEFF8\uB680\uEFF6\uB681\uBBFD"+ + "\uB3C6\uB682\uB683\uB684\uB685\uB686\uB687\uB688"+ + "\uBDD5\uB689\uB68A\uD2C6\uB68B\uBBE0\uB68C\uB68D"+ + "\uCFA1\uB68E\uEFFC\uEFFB\uB68F\uB690\uEFF9\uB691"+ + "\uB692\uB693\uB694\uB3CC\uB695\uC9D4\uCBB0\uB696"+ + "\uB697\uB698\uB699\uB69A\uEFFE\uB69B\uB69C\uB0DE"+ + "\uB69D\uB69E\uD6C9\uB69F\uB6A0\uB740\uEFFD\uB741"+ + "\uB3ED\uB742\uB743\uF6D5\uB744\uB745\uB746\uB747"+ + "\uB748\uB749\uB74A\uB74B\uB74C\uB74D\uB74E\uB74F"+ + "\uB750\uB751\uB752\uCEC8\uB753\uB754\uB755\uF0A2"+ + "\uB756\uF0A1\uB757\uB5BE\uBCDA\uBBFC\uB758\uB8E5"+ + "\uB759\uB75A\uB75B\uB75C\uB75D\uB75E\uC4C2\uB75F"+ + "\uB760\uB761\uB762\uB763\uB764\uB765\uB766\uB767"+ + "\uB768\uF0A3\uB769\uB76A\uB76B\uB76C\uB76D\uCBEB"+ + "\uB76E\uB76F\uB770\uB771\uB772\uB773\uB774\uB775"+ + "\uB776\uB777\uB778\uB779\uB77A\uB77B\uB77C\uB77D"+ + "\uB77E\uB780\uB781\uB782\uB783\uB784\uB785\uB786"+ + "\uF0A6\uB787\uB788\uB789\uD1A8\uB78A\uBEBF\uC7EE"+ + "\uF1B6\uF1B7\uBFD5\uB78B\uB78C\uB78D\uB78E\uB4A9"+ + "\uF1B8\uCDBB\uB78F\uC7D4\uD5AD\uB790\uF1B9\uB791"+ + "\uF1BA\uB792\uB793\uB794\uB795\uC7CF\uB796\uB797"+ + "\uB798\uD2A4\uD6CF\uB799\uB79A\uF1BB\uBDD1\uB4B0"+ + "\uBEBD\uB79B\uB79C\uB79D\uB4DC\uCED1\uB79E\uBFDF"+ + "\uF1BD\uB79F\uB7A0\uB840\uB841\uBFFA\uF1BC\uB842"+ + "\uF1BF\uB843\uB844\uB845\uF1BE\uF1C0\uB846\uB847"+ + "\uB848\uB849\uB84A\uF1C1\uB84B\uB84C\uB84D\uB84E"+ + "\uB84F\uB850\uB851\uB852\uB853\uB854\uB855\uC1FE"+ + "\uB856\uB857\uB858\uB859\uB85A\uB85B\uB85C\uB85D"+ + "\uB85E\uB85F\uB860\uC1A2\uB861\uB862\uB863\uB864"+ + "\uB865\uB866\uB867\uB868\uB869\uB86A\uCAFA\uB86B"+ + "\uB86C\uD5BE\uB86D\uB86E\uB86F\uB870\uBEBA\uBEB9"+ + "\uD5C2\uB871\uB872\uBFA2\uB873\uCDAF\uF1B5\uB874"+ + "\uB875\uB876\uB877\uB878\uB879\uBDDF\uB87A\uB6CB"+ + "\uB87B\uB87C\uB87D\uB87E\uB880\uB881\uB882\uB883"+ + "\uB884\uD6F1\uF3C3\uB885\uB886\uF3C4\uB887\uB8CD"+ + "\uB888\uB889\uB88A\uF3C6\uF3C7\uB88B\uB0CA\uB88C"+ + "\uF3C5\uB88D\uF3C9\uCBF1\uB88E\uB88F\uB890\uF3CB"+ + "\uB891\uD0A6\uB892\uB893\uB1CA\uF3C8\uB894\uB895"+ + "\uB896\uF3CF\uB897\uB5D1\uB898\uB899\uF3D7\uB89A"+ + "\uF3D2\uB89B\uB89C\uB89D\uF3D4\uF3D3\uB7FB\uB89E"+ + "\uB1BF\uB89F\uF3CE\uF3CA\uB5DA\uB8A0\uF3D0\uB940"+ + "\uB941\uF3D1\uB942\uF3D5\uB943\uB944\uB945\uB946"+ + "\uF3CD\uB947\uBCE3\uB948\uC1FD\uB949\uF3D6\uB94A"+ + "\uB94B\uB94C\uB94D\uB94E\uB94F\uF3DA\uB950\uF3CC"+ + "\uB951\uB5C8\uB952\uBDEE\uF3DC\uB953\uB954\uB7A4"+ + "\uBFF0\uD6FE\uCDB2\uB955\uB4F0\uB956\uB2DF\uB957"+ + "\uF3D8\uB958\uF3D9\uC9B8\uB959\uF3DD\uB95A\uB95B"+ + "\uF3DE\uB95C\uF3E1\uB95D\uB95E\uB95F\uB960\uB961"+ + "\uB962\uB963\uB964\uB965\uB966\uB967\uF3DF\uB968"+ + "\uB969\uF3E3\uF3E2\uB96A\uB96B\uF3DB\uB96C\uBFEA"+ + "\uB96D\uB3EF\uB96E\uF3E0\uB96F\uB970\uC7A9\uB971"+ + "\uBCF2\uB972\uB973\uB974\uB975\uF3EB\uB976\uB977"+ + "\uB978\uB979\uB97A\uB97B\uB97C\uB9BF\uB97D\uB97E"+ + "\uF3E4\uB980\uB981\uB982\uB2AD\uBBFE\uB983\uCBE3"+ + "\uB984\uB985\uB986\uB987\uF3ED\uF3E9\uB988\uB989"+ + "\uB98A\uB9DC\uF3EE\uB98B\uB98C\uB98D\uF3E5\uF3E6"+ + "\uF3EA\uC2E1\uF3EC\uF3EF\uF3E8\uBCFD\uB98E\uB98F"+ + "\uB990\uCFE4\uB991\uB992\uF3F0\uB993\uB994\uB995"+ + "\uF3E7\uB996\uB997\uB998\uB999\uB99A\uB99B\uB99C"+ + "\uB99D\uF3F2\uB99E\uB99F\uB9A0\uBA40\uD7AD\uC6AA"+ + "\uBA41\uBA42\uBA43\uBA44\uF3F3\uBA45\uBA46\uBA47"+ + "\uBA48\uF3F1\uBA49\uC2A8\uBA4A\uBA4B\uBA4C\uBA4D"+ + "\uBA4E\uB8DD\uF3F5\uBA4F\uBA50\uF3F4\uBA51\uBA52"+ + "\uBA53\uB4DB\uBA54\uBA55\uBA56\uF3F6\uF3F7\uBA57"+ + "\uBA58\uBA59\uF3F8\uBA5A\uBA5B\uBA5C\uC0BA\uBA5D"+ + "\uBA5E\uC0E9\uBA5F\uBA60\uBA61\uBA62\uBA63\uC5F1"+ + "\uBA64\uBA65\uBA66\uBA67\uF3FB\uBA68\uF3FA\uBA69"+ + "\uBA6A\uBA6B\uBA6C\uBA6D\uBA6E\uBA6F\uBA70\uB4D8"+ + "\uBA71\uBA72\uBA73\uF3FE\uF3F9\uBA74\uBA75\uF3FC"+ + "\uBA76\uBA77\uBA78\uBA79\uBA7A\uBA7B\uF3FD\uBA7C"+ + "\uBA7D\uBA7E\uBA80\uBA81\uBA82\uBA83\uBA84\uF4A1"+ + "\uBA85\uBA86\uBA87\uBA88\uBA89\uBA8A\uF4A3\uBBC9"+ + "\uBA8B\uBA8C\uF4A2\uBA8D\uBA8E\uBA8F\uBA90\uBA91"+ + "\uBA92\uBA93\uBA94\uBA95\uBA96\uBA97\uBA98\uBA99"+ + "\uF4A4\uBA9A\uBA9B\uBA9C\uBA9D\uBA9E\uBA9F\uB2BE"+ + "\uF4A6\uF4A5\uBAA0\uBB40\uBB41\uBB42\uBB43\uBB44"+ + "\uBB45\uBB46\uBB47\uBB48\uBB49\uBCAE\uBB4A\uBB4B"+ + "\uBB4C\uBB4D\uBB4E\uBB4F\uBB50\uBB51\uBB52\uBB53"+ + "\uBB54\uBB55\uBB56\uBB57\uBB58\uBB59\uBB5A\uBB5B"+ + "\uBB5C\uBB5D\uBB5E\uBB5F\uBB60\uBB61\uBB62\uBB63"+ + "\uBB64\uBB65\uBB66\uBB67\uBB68\uBB69\uBB6A\uBB6B"+ + "\uBB6C\uBB6D\uBB6E\uC3D7\uD9E1\uBB6F\uBB70\uBB71"+ + "\uBB72\uBB73\uBB74\uC0E0\uF4CC\uD7D1\uBB75\uBB76"+ + "\uBB77\uBB78\uBB79\uBB7A\uBB7B\uBB7C\uBB7D\uBB7E"+ + "\uBB80\uB7DB\uBB81\uBB82\uBB83\uBB84\uBB85\uBB86"+ + "\uBB87\uF4CE\uC1A3\uBB88\uBB89\uC6C9\uBB8A\uB4D6"+ + "\uD5B3\uBB8B\uBB8C\uBB8D\uF4D0\uF4CF\uF4D1\uCBDA"+ + "\uBB8E\uBB8F\uF4D2\uBB90\uD4C1\uD6E0\uBB91\uBB92"+ + "\uBB93\uBB94\uB7E0\uBB95\uBB96\uBB97\uC1B8\uBB98"+ + "\uBB99\uC1BB\uF4D3\uBEAC\uBB9A\uBB9B\uBB9C\uBB9D"+ + "\uBB9E\uB4E2\uBB9F\uBBA0\uF4D4\uF4D5\uBEAB\uBC40"+ + "\uBC41\uF4D6\uBC42\uBC43\uBC44\uF4DB\uBC45\uF4D7"+ + "\uF4DA\uBC46\uBAFD\uBC47\uF4D8\uF4D9\uBC48\uBC49"+ + "\uBC4A\uBC4B\uBC4C\uBC4D\uBC4E\uB8E2\uCCC7\uF4DC"+ + "\uBC4F\uB2DA\uBC50\uBC51\uC3D3\uBC52\uBC53\uD4E3"+ + "\uBFB7\uBC54\uBC55\uBC56\uBC57\uBC58\uBC59\uBC5A"+ + "\uF4DD\uBC5B\uBC5C\uBC5D\uBC5E\uBC5F\uBC60\uC5B4"+ + "\uBC61\uBC62\uBC63\uBC64\uBC65\uBC66\uBC67\uBC68"+ + "\uF4E9\uBC69\uBC6A\uCFB5\uBC6B\uBC6C\uBC6D\uBC6E"+ + "\uBC6F\uBC70\uBC71\uBC72\uBC73\uBC74\uBC75\uBC76"+ + "\uBC77\uBC78\uCEC9\uBC79\uBC7A\uBC7B\uBC7C\uBC7D"+ + "\uBC7E\uBC80\uBC81\uBC82\uBC83\uBC84\uBC85\uBC86"+ + "\uBC87\uBC88\uBC89\uBC8A\uBC8B\uBC8C\uBC8D\uBC8E"+ + "\uCBD8\uBC8F\uCBF7\uBC90\uBC91\uBC92\uBC93\uBDF4"+ + "\uBC94\uBC95\uBC96\uD7CF\uBC97\uBC98\uBC99\uC0DB"+ + "\uBC9A\uBC9B\uBC9C\uBC9D\uBC9E\uBC9F\uBCA0\uBD40"+ + "\uBD41\uBD42\uBD43\uBD44\uBD45\uBD46\uBD47\uBD48"+ + "\uBD49\uBD4A\uBD4B\uBD4C\uBD4D\uBD4E\uBD4F\uBD50"+ + "\uBD51\uBD52\uBD53\uBD54\uBD55\uBD56\uBD57\uBD58"+ + "\uBD59\uBD5A\uBD5B\uBD5C\uBD5D\uBD5E\uBD5F\uBD60"+ + "\uBD61\uBD62\uBD63\uBD64\uBD65\uBD66\uBD67\uBD68"+ + "\uBD69\uBD6A\uBD6B\uBD6C\uBD6D\uBD6E\uBD6F\uBD70"+ + "\uBD71\uBD72\uBD73\uBD74\uBD75\uBD76\uD0F5\uBD77"+ + "\uBD78\uBD79\uBD7A\uBD7B\uBD7C\uBD7D\uBD7E\uF4EA"+ + "\uBD80\uBD81\uBD82\uBD83\uBD84\uBD85\uBD86\uBD87"+ + "\uBD88\uBD89\uBD8A\uBD8B\uBD8C\uBD8D\uBD8E\uBD8F"+ + "\uBD90\uBD91\uBD92\uBD93\uBD94\uBD95\uBD96\uBD97"+ + "\uBD98\uBD99\uBD9A\uBD9B\uBD9C\uBD9D\uBD9E\uBD9F"+ + "\uBDA0\uBE40\uBE41\uBE42\uBE43\uBE44\uBE45\uBE46"+ + "\uBE47\uBE48\uBE49\uBE4A\uBE4B\uBE4C\uF4EB\uBE4D"+ + "\uBE4E\uBE4F\uBE50\uBE51\uBE52\uBE53\uF4EC\uBE54"+ + "\uBE55\uBE56\uBE57\uBE58\uBE59\uBE5A\uBE5B\uBE5C"+ + "\uBE5D\uBE5E\uBE5F\uBE60\uBE61\uBE62\uBE63\uBE64"+ + "\uBE65\uBE66\uBE67\uBE68\uBE69\uBE6A\uBE6B\uBE6C"+ + "\uBE6D\uBE6E\uBE6F\uBE70\uBE71\uBE72\uBE73\uBE74"+ + "\uBE75\uBE76\uBE77\uBE78\uBE79\uBE7A\uBE7B\uBE7C"+ + "\uBE7D\uBE7E\uBE80\uBE81\uBE82\uBE83\uBE84\uBE85"+ + "\uBE86\uBE87\uBE88\uBE89\uBE8A\uBE8B\uBE8C\uBE8D"+ + "\uBE8E\uBE8F\uBE90\uBE91\uBE92\uBE93\uBE94\uBE95"+ + "\uBE96\uBE97\uBE98\uBE99\uBE9A\uBE9B\uBE9C\uBE9D"+ + "\uBE9E\uBE9F\uBEA0\uBF40\uBF41\uBF42\uBF43\uBF44"+ + "\uBF45\uBF46\uBF47\uBF48\uBF49\uBF4A\uBF4B\uBF4C"+ + "\uBF4D\uBF4E\uBF4F\uBF50\uBF51\uBF52\uBF53\uBF54"+ + "\uBF55\uBF56\uBF57\uBF58\uBF59\uBF5A\uBF5B\uBF5C"+ + "\uBF5D\uBF5E\uBF5F\uBF60\uBF61\uBF62\uBF63\uBF64"+ + "\uBF65\uBF66\uBF67\uBF68\uBF69\uBF6A\uBF6B\uBF6C"+ + "\uBF6D\uBF6E\uBF6F\uBF70\uBF71\uBF72\uBF73\uBF74"+ + "\uBF75\uBF76\uBF77\uBF78\uBF79\uBF7A\uBF7B\uBF7C"+ + "\uBF7D\uBF7E\uBF80\uF7E3\uBF81\uBF82\uBF83\uBF84"+ + "\uBF85\uB7B1\uBF86\uBF87\uBF88\uBF89\uBF8A\uF4ED"+ + "\uBF8B\uBF8C\uBF8D\uBF8E\uBF8F\uBF90\uBF91\uBF92"+ + "\uBF93\uBF94\uBF95\uBF96\uBF97\uBF98\uBF99\uBF9A"+ + "\uBF9B\uBF9C\uBF9D\uBF9E\uBF9F\uBFA0\uC040\uC041"+ + "\uC042\uC043\uC044\uC045\uC046\uC047\uC048\uC049"+ + "\uC04A\uC04B\uC04C\uC04D\uC04E\uC04F\uC050\uC051"+ + "\uC052\uC053\uC054\uC055\uC056\uC057\uC058\uC059"+ + "\uC05A\uC05B\uC05C\uC05D\uC05E\uC05F\uC060\uC061"+ + "\uC062\uC063\uD7EB\uC064\uC065\uC066\uC067\uC068"+ + "\uC069\uC06A\uC06B\uC06C\uC06D\uC06E\uC06F\uC070"+ + "\uC071\uC072\uC073\uC074\uC075\uC076\uC077\uC078"+ + "\uC079\uC07A\uC07B\uF4EE\uC07C\uC07D\uC07E\uE6F9"+ + "\uBEC0\uE6FA\uBAEC\uE6FB\uCFCB\uE6FC\uD4BC\uBCB6"+ + "\uE6FD\uE6FE\uBCCD\uC8D2\uCEB3\uE7A1\uC080\uB4BF"+ + "\uE7A2\uC9B4\uB8D9\uC4C9\uC081\uD7DD\uC2DA\uB7D7"+ + "\uD6BD\uCEC6\uB7C4\uC082\uC083\uC5A6\uE7A3\uCFDF"+ + "\uE7A4\uE7A5\uE7A6\uC1B7\uD7E9\uC9F0\uCFB8\uD6AF"+ + "\uD6D5\uE7A7\uB0ED\uE7A8\uE7A9\uC9DC\uD2EF\uBEAD"+ + "\uE7AA\uB0F3\uC8DE\uBDE1\uE7AB\uC8C6\uC084\uE7AC"+ + "\uBBE6\uB8F8\uD1A4\uE7AD\uC2E7\uBEF8\uBDCA\uCDB3"+ + "\uE7AE\uE7AF\uBEEE\uD0E5\uC085\uCBE7\uCCD0\uBCCC"+ + "\uE7B0\uBCA8\uD0F7\uE7B1\uC086\uD0F8\uE7B2\uE7B3"+ + "\uB4C2\uE7B4\uE7B5\uC9FE\uCEAC\uC3E0\uE7B7\uB1C1"+ + "\uB3F1\uC087\uE7B8\uE7B9\uD7DB\uD5C0\uE7BA\uC2CC"+ + "\uD7BA\uE7BB\uE7BC\uE7BD\uBCEA\uC3E5\uC0C2\uE7BE"+ + "\uE7BF\uBCA9\uC088\uE7C0\uE7C1\uE7B6\uB6D0\uE7C2"+ + "\uC089\uE7C3\uE7C4\uBBBA\uB5DE\uC2C6\uB1E0\uE7C5"+ + "\uD4B5\uE7C6\uB8BF\uE7C8\uE7C7\uB7EC\uC08A\uE7C9"+ + "\uB2F8\uE7CA\uE7CB\uE7CC\uE7CD\uE7CE\uE7CF\uE7D0"+ + "\uD3A7\uCBF5\uE7D1\uE7D2\uE7D3\uE7D4\uC9C9\uE7D5"+ + "\uE7D6\uE7D7\uE7D8\uE7D9\uBDC9\uE7DA\uF3BE\uC08B"+ + "\uB8D7\uC08C\uC8B1\uC08D\uC08E\uC08F\uC090\uC091"+ + "\uC092\uC093\uF3BF\uC094\uF3C0\uF3C1\uC095\uC096"+ + "\uC097\uC098\uC099\uC09A\uC09B\uC09C\uC09D\uC09E"+ + "\uB9DE\uCDF8\uC09F\uC0A0\uD8E8\uBAB1\uC140\uC2DE"+ + "\uEEB7\uC141\uB7A3\uC142\uC143\uC144\uC145\uEEB9"+ + "\uC146\uEEB8\uB0D5\uC147\uC148\uC149\uC14A\uC14B"+ + "\uEEBB\uD5D6\uD7EF\uC14C\uC14D\uC14E\uD6C3\uC14F"+ + "\uC150\uEEBD\uCAF0\uC151\uEEBC\uC152\uC153\uC154"+ + "\uC155\uEEBE\uC156\uC157\uC158\uC159\uEEC0\uC15A"+ + "\uC15B\uEEBF\uC15C\uC15D\uC15E\uC15F\uC160\uC161"+ + "\uC162\uC163\uD1F2\uC164\uC7BC\uC165\uC3C0\uC166"+ + "\uC167\uC168\uC169\uC16A\uB8E1\uC16B\uC16C\uC16D"+ + "\uC16E\uC16F\uC1E7\uC170\uC171\uF4C6\uD0DF\uF4C7"+ + "\uC172\uCFDB\uC173\uC174\uC8BA\uC175\uC176\uF4C8"+ + "\uC177\uC178\uC179\uC17A\uC17B\uC17C\uC17D\uF4C9"+ + "\uF4CA\uC17E\uF4CB\uC180\uC181\uC182\uC183\uC184"+ + "\uD9FA\uB8FE\uC185\uC186\uE5F1\uD3F0\uC187\uF4E0"+ + "\uC188\uCECC\uC189\uC18A\uC18B\uB3E1\uC18C\uC18D"+ + "\uC18E\uC18F\uF1B4\uC190\uD2EE\uC191\uF4E1\uC192"+ + "\uC193\uC194\uC195\uC196\uCFE8\uF4E2\uC197\uC198"+ + "\uC7CC\uC199\uC19A\uC19B\uC19C\uC19D\uC19E\uB5D4"+ + "\uB4E4\uF4E4\uC19F\uC1A0\uC240\uF4E3\uF4E5\uC241"+ + "\uC242\uF4E6\uC243\uC244\uC245\uC246\uF4E7\uC247"+ + "\uBAB2\uB0BF\uC248\uF4E8\uC249\uC24A\uC24B\uC24C"+ + "\uC24D\uC24E\uC24F\uB7AD\uD2ED\uC250\uC251\uC252"; + + private static final String innerEncoderIndex8= + "\uD2AB\uC0CF\uC253\uBFBC\uEBA3\uD5DF\uEAC8\uC254"+ + "\uC255\uC256\uC257\uF1F3\uB6F8\uCBA3\uC258\uC259"+ + "\uC4CD\uC25A\uF1E7\uC25B\uF1E8\uB8FB\uF1E9\uBAC4"+ + "\uD4C5\uB0D2\uC25C\uC25D\uF1EA\uC25E\uC25F\uC260"+ + "\uF1EB\uC261\uF1EC\uC262\uC263\uF1ED\uF1EE\uF1EF"+ + "\uF1F1\uF1F0\uC5D5\uC264\uC265\uC266\uC267\uC268"+ + "\uC269\uF1F2\uC26A\uB6FA\uC26B\uF1F4\uD2AE\uDEC7"+ + "\uCBCA\uC26C\uC26D\uB3DC\uC26E\uB5A2\uC26F\uB9A2"+ + "\uC270\uC271\uC4F4\uF1F5\uC272\uC273\uF1F6\uC274"+ + "\uC275\uC276\uC1C4\uC1FB\uD6B0\uF1F7\uC277\uC278"+ + "\uC279\uC27A\uF1F8\uC27B\uC1AA\uC27C\uC27D\uC27E"+ + "\uC6B8\uC280\uBEDB\uC281\uC282\uC283\uC284\uC285"+ + "\uC286\uC287\uC288\uC289\uC28A\uC28B\uC28C\uC28D"+ + "\uC28E\uF1F9\uB4CF\uC28F\uC290\uC291\uC292\uC293"+ + "\uC294\uF1FA\uC295\uC296\uC297\uC298\uC299\uC29A"+ + "\uC29B\uC29C\uC29D\uC29E\uC29F\uC2A0\uC340\uEDB2"+ + "\uEDB1\uC341\uC342\uCBE0\uD2DE\uC343\uCBC1\uD5D8"+ + "\uC344\uC8E2\uC345\uC0DF\uBCA1\uC346\uC347\uC348"+ + "\uC349\uC34A\uC34B\uEBC1\uC34C\uC34D\uD0A4\uC34E"+ + "\uD6E2\uC34F\uB6C7\uB8D8\uEBC0\uB8CE\uC350\uEBBF"+ + "\uB3A6\uB9C9\uD6AB\uC351\uB7F4\uB7CA\uC352\uC353"+ + "\uC354\uBCE7\uB7BE\uEBC6\uC355\uEBC7\uB0B9\uBFCF"+ + "\uC356\uEBC5\uD3FD\uC357\uEBC8\uC358\uC359\uEBC9"+ + "\uC35A\uC35B\uB7CE\uC35C\uEBC2\uEBC4\uC9F6\uD6D7"+ + "\uD5CD\uD0B2\uEBCF\uCEB8\uEBD0\uC35D\uB5A8\uC35E"+ + "\uC35F\uC360\uC361\uC362\uB1B3\uEBD2\uCCA5\uC363"+ + "\uC364\uC365\uC366\uC367\uC368\uC369\uC5D6\uEBD3"+ + "\uC36A\uEBD1\uC5DF\uEBCE\uCAA4\uEBD5\uB0FB\uC36B"+ + "\uC36C\uBAFA\uC36D\uC36E\uD8B7\uF1E3\uC36F\uEBCA"+ + "\uEBCB\uEBCC\uEBCD\uEBD6\uE6C0\uEBD9\uC370\uBFE8"+ + "\uD2C8\uEBD7\uEBDC\uB8EC\uEBD8\uC371\uBDBA\uC372"+ + "\uD0D8\uC373\uB0B7\uC374\uEBDD\uC4DC\uC375\uC376"+ + "\uC377\uC378\uD6AC\uC379\uC37A\uC37B\uB4E0\uC37C"+ + "\uC37D\uC2F6\uBCB9\uC37E\uC380\uEBDA\uEBDB\uD4E0"+ + "\uC6EA\uC4D4\uEBDF\uC5A7\uD9F5\uC381\uB2B1\uC382"+ + "\uEBE4\uC383\uBDC5\uC384\uC385\uC386\uEBE2\uC387"+ + "\uC388\uC389\uC38A\uC38B\uC38C\uC38D\uC38E\uC38F"+ + "\uC390\uC391\uC392\uC393\uEBE3\uC394\uC395\uB8AC"+ + "\uC396\uCDD1\uEBE5\uC397\uC398\uC399\uEBE1\uC39A"+ + "\uC1B3\uC39B\uC39C\uC39D\uC39E\uC39F\uC6A2\uC3A0"+ + "\uC440\uC441\uC442\uC443\uC444\uC445\uCCF3\uC446"+ + "\uEBE6\uC447\uC0B0\uD2B8\uEBE7\uC448\uC449\uC44A"+ + "\uB8AF\uB8AD\uC44B\uEBE8\uC7BB\uCDF3\uC44C\uC44D"+ + "\uC44E\uEBEA\uEBEB\uC44F\uC450\uC451\uC452\uC453"+ + "\uEBED\uC454\uC455\uC456\uC457\uD0C8\uC458\uEBF2"+ + "\uC459\uEBEE\uC45A\uC45B\uC45C\uEBF1\uC8F9\uC45D"+ + "\uD1FC\uEBEC\uC45E\uC45F\uEBE9\uC460\uC461\uC462"+ + "\uC463\uB8B9\uCFD9\uC4E5\uEBEF\uEBF0\uCCDA\uCDC8"+ + "\uB0F2\uC464\uEBF6\uC465\uC466\uC467\uC468\uC469"+ + "\uEBF5\uC46A\uB2B2\uC46B\uC46C\uC46D\uC46E\uB8E0"+ + "\uC46F\uEBF7\uC470\uC471\uC472\uC473\uC474\uC475"+ + "\uB1EC\uC476\uC477\uCCC5\uC4A4\uCFA5\uC478\uC479"+ + "\uC47A\uC47B\uC47C\uEBF9\uC47D\uC47E\uECA2\uC480"+ + "\uC5F2\uC481\uEBFA\uC482\uC483\uC484\uC485\uC486"+ + "\uC487\uC488\uC489\uC9C5\uC48A\uC48B\uC48C\uC48D"+ + "\uC48E\uC48F\uE2DF\uEBFE\uC490\uC491\uC492\uC493"+ + "\uCDCE\uECA1\uB1DB\uD3B7\uC494\uC495\uD2DC\uC496"+ + "\uC497\uC498\uEBFD\uC499\uEBFB\uC49A\uC49B\uC49C"+ + "\uC49D\uC49E\uC49F\uC4A0\uC540\uC541\uC542\uC543"+ + "\uC544\uC545\uC546\uC547\uC548\uC549\uC54A\uC54B"+ + "\uC54C\uC54D\uC54E\uB3BC\uC54F\uC550\uC551\uEAB0"+ + "\uC552\uC553\uD7D4\uC554\uF4AB\uB3F4\uC555\uC556"+ + "\uC557\uC558\uC559\uD6C1\uD6C2\uC55A\uC55B\uC55C"+ + "\uC55D\uC55E\uC55F\uD5E9\uBECA\uC560\uF4A7\uC561"+ + "\uD2A8\uF4A8\uF4A9\uC562\uF4AA\uBECB\uD3DF\uC563"+ + "\uC564\uC565\uC566\uC567\uC9E0\uC9E1\uC568\uC569"+ + "\uF3C2\uC56A\uCAE6\uC56B\uCCF2\uC56C\uC56D\uC56E"+ + "\uC56F\uC570\uC571\uE2B6\uCBB4\uC572\uCEE8\uD6DB"+ + "\uC573\uF4AD\uF4AE\uF4AF\uC574\uC575\uC576\uC577"+ + "\uF4B2\uC578\uBABD\uF4B3\uB0E3\uF4B0\uC579\uF4B1"+ + "\uBDA2\uB2D5\uC57A\uF4B6\uF4B7\uB6E6\uB2B0\uCFCF"+ + "\uF4B4\uB4AC\uC57B\uF4B5\uC57C\uC57D\uF4B8\uC57E"+ + "\uC580\uC581\uC582\uC583\uF4B9\uC584\uC585\uCDA7"+ + "\uC586\uF4BA\uC587\uF4BB\uC588\uC589\uC58A\uF4BC"+ + "\uC58B\uC58C\uC58D\uC58E\uC58F\uC590\uC591\uC592"+ + "\uCBD2\uC593\uF4BD\uC594\uC595\uC596\uC597\uF4BE"+ + "\uC598\uC599\uC59A\uC59B\uC59C\uC59D\uC59E\uC59F"+ + "\uF4BF\uC5A0\uC640\uC641\uC642\uC643\uF4DE\uC1BC"+ + "\uBCE8\uC644\uC9AB\uD1DE\uE5F5\uC645\uC646\uC647"+ + "\uC648\uDCB3\uD2D5\uC649\uC64A\uDCB4\uB0AC\uDCB5"+ + "\uC64B\uC64C\uBDDA\uC64D\uDCB9\uC64E\uC64F\uC650"+ + "\uD8C2\uC651\uDCB7\uD3F3\uC652\uC9D6\uDCBA\uDCB6"+ + "\uC653\uDCBB\uC3A2\uC654\uC655\uC656\uC657\uDCBC"+ + "\uDCC5\uDCBD\uC658\uC659\uCEDF\uD6A5\uC65A\uDCCF"+ + "\uC65B\uDCCD\uC65C\uC65D\uDCD2\uBDE6\uC2AB\uC65E"+ + "\uDCB8\uDCCB\uDCCE\uDCBE\uB7D2\uB0C5\uDCC7\uD0BE"+ + "\uDCC1\uBBA8\uC65F\uB7BC\uDCCC\uC660\uC661\uDCC6"+ + "\uDCBF\uC7DB\uC662\uC663\uC664\uD1BF\uDCC0\uC665"+ + "\uC666\uDCCA\uC667\uC668\uDCD0\uC669\uC66A\uCEAD"+ + "\uDCC2\uC66B\uDCC3\uDCC8\uDCC9\uB2D4\uDCD1\uCBD5"+ + "\uC66C\uD4B7\uDCDB\uDCDF\uCCA6\uDCE6\uC66D\uC3E7"+ + "\uDCDC\uC66E\uC66F\uBFC1\uDCD9\uC670\uB0FA\uB9B6"+ + "\uDCE5\uDCD3\uC671\uDCC4\uDCD6\uC8F4\uBFE0\uC672"+ + "\uC673\uC674\uC675\uC9BB\uC676\uC677\uC678\uB1BD"+ + "\uC679\uD3A2\uC67A\uC67B\uDCDA\uC67C\uC67D\uDCD5"+ + "\uC67E\uC6BB\uC680\uDCDE\uC681\uC682\uC683\uC684"+ + "\uC685\uD7C2\uC3AF\uB7B6\uC7D1\uC3A9\uDCE2\uDCD8"+ + "\uDCEB\uDCD4\uC686\uC687\uDCDD\uC688\uBEA5\uDCD7"+ + "\uC689\uDCE0\uC68A\uC68B\uDCE3\uDCE4\uC68C\uDCF8"+ + "\uC68D\uC68E\uDCE1\uDDA2\uDCE7\uC68F\uC690\uC691"+ + "\uC692\uC693\uC694\uC695\uC696\uC697\uC698\uBCEB"+ + "\uB4C4\uC699\uC69A\uC3A3\uB2E7\uDCFA\uC69B\uDCF2"+ + "\uC69C\uDCEF\uC69D\uDCFC\uDCEE\uD2F0\uB2E8\uC69E"+ + "\uC8D7\uC8E3\uDCFB\uC69F\uDCED\uC6A0\uC740\uC741"+ + "\uDCF7\uC742\uC743\uDCF5\uC744\uC745\uBEA3\uDCF4"+ + "\uC746\uB2DD\uC747\uC748\uC749\uC74A\uC74B\uDCF3"+ + "\uBCF6\uDCE8\uBBC4\uC74C\uC0F3\uC74D\uC74E\uC74F"+ + "\uC750\uC751\uBCD4\uDCE9\uDCEA\uC752\uDCF1\uDCF6"+ + "\uDCF9\uB5B4\uC753\uC8D9\uBBE7\uDCFE\uDCFD\uD3AB"+ + "\uDDA1\uDDA3\uDDA5\uD2F1\uDDA4\uDDA6\uDDA7\uD2A9"+ + "\uC754\uC755\uC756\uC757\uC758\uC759\uC75A\uBAC9"+ + "\uDDA9\uC75B\uC75C\uDDB6\uDDB1\uDDB4\uC75D\uC75E"+ + "\uC75F\uC760\uC761\uC762\uC763\uDDB0\uC6CE\uC764"+ + "\uC765\uC0F2\uC766\uC767\uC768\uC769\uC9AF\uC76A"+ + "\uC76B\uC76C\uDCEC\uDDAE\uC76D\uC76E\uC76F\uC770"+ + "\uDDB7\uC771\uC772\uDCF0\uDDAF\uC773\uDDB8\uC774"+ + "\uDDAC\uC775\uC776\uC777\uC778\uC779\uC77A\uC77B"+ + "\uDDB9\uDDB3\uDDAD\uC4AA\uC77C\uC77D\uC77E\uC780"+ + "\uDDA8\uC0B3\uC1AB\uDDAA\uDDAB\uC781\uDDB2\uBBF1"+ + "\uDDB5\uD3A8\uDDBA\uC782\uDDBB\uC3A7\uC783\uC784"+ + "\uDDD2\uDDBC\uC785\uC786\uC787\uDDD1\uC788\uB9BD"+ + "\uC789\uC78A\uBED5\uC78B\uBEFA\uC78C\uC78D\uBACA"+ + "\uC78E\uC78F\uC790\uC791\uDDCA\uC792\uDDC5\uC793"+ + "\uDDBF\uC794\uC795\uC796\uB2CB\uDDC3\uC797\uDDCB"+ + "\uB2A4\uDDD5\uC798\uC799\uC79A\uDDBE\uC79B\uC79C"+ + "\uC79D\uC6D0\uDDD0\uC79E\uC79F\uC7A0\uC840\uC841"+ + "\uDDD4\uC1E2\uB7C6\uC842\uC843\uC844\uC845\uC846"+ + "\uDDCE\uDDCF\uC847\uC848\uC849\uDDC4\uC84A\uC84B"+ + "\uC84C\uDDBD\uC84D\uDDCD\uCCD1\uC84E\uDDC9\uC84F"+ + "\uC850\uC851\uC852\uDDC2\uC3C8\uC6BC\uCEAE\uDDCC"+ + "\uC853\uDDC8\uC854\uC855\uC856\uC857\uC858\uC859"+ + "\uDDC1\uC85A\uC85B\uC85C\uDDC6\uC2DC\uC85D\uC85E"+ + "\uC85F\uC860\uC861\uC862\uD3A9\uD3AA\uDDD3\uCFF4"+ + "\uC8F8\uC863\uC864\uC865\uC866\uC867\uC868\uC869"+ + "\uC86A\uDDE6\uC86B\uC86C\uC86D\uC86E\uC86F\uC870"+ + "\uDDC7\uC871\uC872\uC873\uDDE0\uC2E4\uC874\uC875"+ + "\uC876\uC877\uC878\uC879\uC87A\uC87B\uDDE1\uC87C"+ + "\uC87D\uC87E\uC880\uC881\uC882\uC883\uC884\uC885"+ + "\uC886\uDDD7\uC887\uC888\uC889\uC88A\uC88B\uD6F8"+ + "\uC88C\uDDD9\uDDD8\uB8F0\uDDD6\uC88D\uC88E\uC88F"+ + "\uC890\uC6CF\uC891\uB6AD\uC892\uC893\uC894\uC895"+ + "\uC896\uDDE2\uC897\uBAF9\uD4E1\uDDE7\uC898\uC899"+ + "\uC89A\uB4D0\uC89B\uDDDA\uC89C\uBFFB\uDDE3\uC89D"+ + "\uDDDF\uC89E\uDDDD\uC89F\uC8A0\uC940\uC941\uC942"+ + "\uC943\uC944\uB5D9\uC945\uC946\uC947\uC948\uDDDB"+ + "\uDDDC\uDDDE\uC949\uBDAF\uDDE4\uC94A\uDDE5\uC94B"+ + "\uC94C\uC94D\uC94E\uC94F\uC950\uC951\uC952\uDDF5"+ + "\uC953\uC3C9\uC954\uC955\uCBE2\uC956\uC957\uC958"+ + "\uC959\uDDF2\uC95A\uC95B\uC95C\uC95D\uC95E\uC95F"+ + "\uC960\uC961\uC962\uC963\uC964\uC965\uC966\uD8E1"+ + "\uC967\uC968\uC6D1\uC969\uDDF4\uC96A\uC96B\uC96C"+ + "\uD5F4\uDDF3\uDDF0\uC96D\uC96E\uDDEC\uC96F\uDDEF"+ + "\uC970\uDDE8\uC971\uC972\uD0EE\uC973\uC974\uC975"+ + "\uC976\uC8D8\uDDEE\uC977\uC978\uDDE9\uC979\uC97A"+ + "\uDDEA\uCBF2\uC97B\uDDED\uC97C\uC97D\uB1CD\uC97E"+ + "\uC980\uC981\uC982\uC983\uC984\uC0B6\uC985\uBCBB"+ + "\uDDF1\uC986\uC987\uDDF7\uC988\uDDF6\uDDEB\uC989"+ + "\uC98A\uC98B\uC98C\uC98D\uC5EE\uC98E\uC98F\uC990"+ + "\uDDFB\uC991\uC992\uC993\uC994\uC995\uC996\uC997"+ + "\uC998\uC999\uC99A\uC99B\uDEA4\uC99C\uC99D\uDEA3"+ + "\uC99E\uC99F\uC9A0\uCA40\uCA41\uCA42\uCA43\uCA44"+ + "\uCA45\uCA46\uCA47\uCA48\uDDF8\uCA49\uCA4A\uCA4B"+ + "\uCA4C\uC3EF\uCA4D\uC2FB\uCA4E\uCA4F\uCA50\uD5E1"+ + "\uCA51\uCA52\uCEB5\uCA53\uCA54\uCA55\uCA56\uDDFD"+ + "\uCA57\uB2CC\uCA58\uCA59\uCA5A\uCA5B\uCA5C\uCA5D"+ + "\uCA5E\uCA5F\uCA60\uC4E8\uCADF\uCA61\uCA62\uCA63"+ + "\uCA64\uCA65\uCA66\uCA67\uCA68\uCA69\uCA6A\uC7BE"+ + "\uDDFA\uDDFC\uDDFE\uDEA2\uB0AA\uB1CE\uCA6B\uCA6C"+ + "\uCA6D\uCA6E\uCA6F\uDEAC\uCA70\uCA71\uCA72\uCA73"+ + "\uDEA6\uBDB6\uC8EF\uCA74\uCA75\uCA76\uCA77\uCA78"+ + "\uCA79\uCA7A\uCA7B\uCA7C\uCA7D\uCA7E\uDEA1\uCA80"+ + "\uCA81\uDEA5\uCA82\uCA83\uCA84\uCA85\uDEA9\uCA86"+ + "\uCA87\uCA88\uCA89\uCA8A\uDEA8\uCA8B\uCA8C\uCA8D"+ + "\uDEA7\uCA8E\uCA8F\uCA90\uCA91\uCA92\uCA93\uCA94"+ + "\uCA95\uCA96\uDEAD\uCA97\uD4CC\uCA98\uCA99\uCA9A"+ + "\uCA9B\uDEB3\uDEAA\uDEAE\uCA9C\uCA9D\uC0D9\uCA9E"+ + "\uCA9F\uCAA0\uCB40\uCB41\uB1A1\uDEB6\uCB42\uDEB1"+ + "\uCB43\uCB44\uCB45\uCB46\uCB47\uCB48\uCB49\uDEB2"+ + "\uCB4A\uCB4B\uCB4C\uCB4D\uCB4E\uCB4F\uCB50\uCB51"+ + "\uCB52\uCB53\uCB54\uD1A6\uDEB5\uCB55\uCB56\uCB57"+ + "\uCB58\uCB59\uCB5A\uCB5B\uDEAF\uCB5C\uCB5D\uCB5E"+ + "\uDEB0\uCB5F\uD0BD\uCB60\uCB61\uCB62\uDEB4\uCAED"+ + "\uDEB9\uCB63\uCB64\uCB65\uCB66\uCB67\uCB68\uDEB8"+ + "\uCB69\uDEB7\uCB6A\uCB6B\uCB6C\uCB6D\uCB6E\uCB6F"+ + "\uCB70\uDEBB\uCB71\uCB72\uCB73\uCB74\uCB75\uCB76"+ + "\uCB77\uBDE5\uCB78\uCB79\uCB7A\uCB7B\uCB7C\uB2D8"+ + "\uC3EA\uCB7D\uCB7E\uDEBA\uCB80\uC5BA\uCB81\uCB82"+ + "\uCB83\uCB84\uCB85\uCB86\uDEBC\uCB87\uCB88\uCB89"+ + "\uCB8A\uCB8B\uCB8C\uCB8D\uCCD9\uCB8E\uCB8F\uCB90"+ + "\uCB91\uB7AA\uCB92\uCB93\uCB94\uCB95\uCB96\uCB97"+ + "\uCB98\uCB99\uCB9A\uCB9B\uCB9C\uCB9D\uCB9E\uCB9F"+ + "\uCBA0\uCC40\uCC41\uD4E5\uCC42\uCC43\uCC44\uDEBD"+ + "\uCC45\uCC46\uCC47\uCC48\uCC49\uDEBF\uCC4A\uCC4B"+ + "\uCC4C\uCC4D\uCC4E\uCC4F\uCC50\uCC51\uCC52\uCC53"+ + "\uCC54\uC4A2\uCC55\uCC56\uCC57\uCC58\uDEC1\uCC59"+ + "\uCC5A\uCC5B\uCC5C\uCC5D\uCC5E\uCC5F\uCC60\uCC61"+ + "\uCC62\uCC63\uCC64\uCC65\uCC66\uCC67\uCC68\uDEBE"+ + "\uCC69\uDEC0\uCC6A\uCC6B\uCC6C\uCC6D\uCC6E\uCC6F"+ + "\uCC70\uCC71\uCC72\uCC73\uCC74\uCC75\uCC76\uCC77"+ + "\uD5BA\uCC78\uCC79\uCC7A\uDEC2\uCC7B\uCC7C\uCC7D"+ + "\uCC7E\uCC80\uCC81\uCC82\uCC83\uCC84\uCC85\uCC86"+ + "\uCC87\uCC88\uCC89\uCC8A\uCC8B\uF2AE\uBBA2\uC2B2"+ + "\uC5B0\uC2C7\uCC8C\uCC8D\uF2AF\uCC8E\uCC8F\uCC90"+ + "\uCC91\uCC92\uD0E9\uCC93\uCC94\uCC95\uD3DD\uCC96"+ + "\uCC97\uCC98\uEBBD\uCC99\uCC9A\uCC9B\uCC9C\uCC9D"+ + "\uCC9E\uCC9F\uCCA0\uB3E6\uF2B0\uCD40\uF2B1\uCD41"+ + "\uCD42\uCAAD\uCD43\uCD44\uCD45\uCD46\uCD47\uCD48"+ + "\uCD49\uBAE7\uF2B3\uF2B5\uF2B4\uCBE4\uCFBA\uF2B2"+ + "\uCAB4\uD2CF\uC2EC\uCD4A\uCD4B\uCD4C\uCD4D\uCD4E"+ + "\uCD4F\uCD50\uCEC3\uF2B8\uB0F6\uF2B7\uCD51\uCD52"+ + "\uCD53\uCD54\uCD55\uF2BE\uCD56\uB2CF\uCD57\uCD58"+ + "\uCD59\uCD5A\uCD5B\uCD5C\uD1C1\uF2BA\uCD5D\uCD5E"+ + "\uCD5F\uCD60\uCD61\uF2BC\uD4E9\uCD62\uCD63\uF2BB"+ + "\uF2B6\uF2BF\uF2BD\uCD64\uF2B9\uCD65\uCD66\uF2C7"+ + "\uF2C4\uF2C6\uCD67\uCD68\uF2CA\uF2C2\uF2C0\uCD69"+ + "\uCD6A\uCD6B\uF2C5\uCD6C\uCD6D\uCD6E\uCD6F\uCD70"+ + "\uD6FB\uCD71\uCD72\uCD73\uF2C1\uCD74\uC7F9\uC9DF"+ + "\uCD75\uF2C8\uB9C6\uB5B0\uCD76\uCD77\uF2C3\uF2C9"+ + "\uF2D0\uF2D6\uCD78\uCD79\uBBD7\uCD7A\uCD7B\uCD7C"+ + "\uF2D5\uCDDC\uCD7D\uD6EB\uCD7E\uCD80\uF2D2\uF2D4"+ + "\uCD81\uCD82\uCD83\uCD84\uB8F2\uCD85\uCD86\uCD87"+ + "\uCD88\uF2CB\uCD89\uCD8A\uCD8B\uF2CE\uC2F9\uCD8C"+ + "\uD5DD\uF2CC\uF2CD\uF2CF\uF2D3\uCD8D\uCD8E\uCD8F"+ + "\uF2D9\uD3BC\uCD90\uCD91\uCD92\uCD93\uB6EA\uCD94"+ + "\uCAF1\uCD95\uB7E4\uF2D7\uCD96\uCD97\uCD98\uF2D8"+ + "\uF2DA\uF2DD\uF2DB\uCD99\uCD9A\uF2DC\uCD9B\uCD9C"+ + "\uCD9D\uCD9E\uD1D1\uF2D1\uCD9F\uCDC9\uCDA0\uCECF"+ + "\uD6A9\uCE40\uF2E3\uCE41\uC3DB\uCE42\uF2E0\uCE43"+ + "\uCE44\uC0AF\uF2EC\uF2DE\uCE45\uF2E1\uCE46\uCE47"+ + "\uCE48\uF2E8\uCE49\uCE4A\uCE4B\uCE4C\uF2E2\uCE4D"+ + "\uCE4E\uF2E7\uCE4F\uCE50\uF2E6\uCE51\uCE52\uF2E9"+ + "\uCE53\uCE54\uCE55\uF2DF\uCE56\uCE57\uF2E4\uF2EA"+ + "\uCE58\uCE59\uCE5A\uCE5B\uCE5C\uCE5D\uCE5E\uD3AC"+ + "\uF2E5\uB2F5\uCE5F\uCE60\uF2F2\uCE61\uD0AB\uCE62"+ + "\uCE63\uCE64\uCE65\uF2F5\uCE66\uCE67\uCE68\uBBC8"+ + "\uCE69\uF2F9\uCE6A\uCE6B\uCE6C\uCE6D\uCE6E\uCE6F"+ + "\uF2F0\uCE70\uCE71\uF2F6\uF2F8\uF2FA\uCE72\uCE73"+ + "\uCE74\uCE75\uCE76\uCE77\uCE78\uCE79\uF2F3\uCE7A"+ + "\uF2F1\uCE7B\uCE7C\uCE7D\uBAFB\uCE7E\uB5FB\uCE80"+ + "\uCE81\uCE82\uCE83\uF2EF\uF2F7\uF2ED\uF2EE\uCE84"+ + "\uCE85\uCE86\uF2EB\uF3A6\uCE87\uF3A3\uCE88\uCE89"+ + "\uF3A2\uCE8A\uCE8B\uF2F4\uCE8C\uC8DA\uCE8D\uCE8E"+ + "\uCE8F\uCE90\uCE91\uF2FB\uCE92\uCE93\uCE94\uF3A5"+ + "\uCE95\uCE96\uCE97\uCE98\uCE99\uCE9A\uCE9B\uC3F8"+ + "\uCE9C\uCE9D\uCE9E\uCE9F\uCEA0\uCF40\uCF41\uCF42"+ + "\uF2FD\uCF43\uCF44\uF3A7\uF3A9\uF3A4\uCF45\uF2FC"+ + "\uCF46\uCF47\uCF48\uF3AB\uCF49\uF3AA\uCF4A\uCF4B"+ + "\uCF4C\uCF4D\uC2DD\uCF4E\uCF4F\uF3AE\uCF50\uCF51"+ + "\uF3B0\uCF52\uCF53\uCF54\uCF55\uCF56\uF3A1\uCF57"+ + "\uCF58\uCF59\uF3B1\uF3AC\uCF5A\uCF5B\uCF5C\uCF5D"+ + "\uCF5E\uF3AF\uF2FE\uF3AD\uCF5F\uCF60\uCF61\uCF62"+ + "\uCF63\uCF64\uCF65\uF3B2\uCF66\uCF67\uCF68\uCF69"+ + "\uF3B4\uCF6A\uCF6B\uCF6C\uCF6D\uF3A8\uCF6E\uCF6F"+ + "\uCF70\uCF71\uF3B3\uCF72\uCF73\uCF74\uF3B5\uCF75"+ + "\uCF76\uCF77\uCF78\uCF79\uCF7A\uCF7B\uCF7C\uCF7D"+ + "\uCF7E\uD0B7\uCF80\uCF81\uCF82\uCF83\uF3B8\uCF84"+ + "\uCF85\uCF86\uCF87\uD9F9\uCF88\uCF89\uCF8A\uCF8B"+ + "\uCF8C\uCF8D\uF3B9\uCF8E\uCF8F\uCF90\uCF91\uCF92"+ + "\uCF93\uCF94\uCF95\uF3B7\uCF96\uC8E4\uF3B6\uCF97"+ + "\uCF98\uCF99\uCF9A\uF3BA\uCF9B\uCF9C\uCF9D\uCF9E"+ + "\uCF9F\uF3BB\uB4C0\uCFA0\uD040\uD041\uD042\uD043"+ + "\uD044\uD045\uD046\uD047\uD048\uD049\uD04A\uD04B"+ + "\uD04C\uD04D\uEEC3\uD04E\uD04F\uD050\uD051\uD052"+ + "\uD053\uF3BC\uD054\uD055\uF3BD\uD056\uD057\uD058"+ + "\uD1AA\uD059\uD05A\uD05B\uF4AC\uD0C6\uD05C\uD05D"+ + "\uD05E\uD05F\uD060\uD061\uD0D0\uD1DC\uD062\uD063"+ + "\uD064\uD065\uD066\uD067\uCFCE\uD068\uD069\uBDD6"+ + "\uD06A\uD1C3\uD06B\uD06C\uD06D\uD06E\uD06F\uD070"+ + "\uD071\uBAE2\uE1E9\uD2C2\uF1C2\uB2B9\uD072\uD073"+ + "\uB1ED\uF1C3\uD074\uC9C0\uB3C4\uD075\uD9F2\uD076"+ + "\uCBA5\uD077\uF1C4\uD078\uD079\uD07A\uD07B\uD6D4"+ + "\uD07C\uD07D\uD07E\uD080\uD081\uF1C5\uF4C0\uF1C6"+ + "\uD082\uD4AC\uF1C7\uD083\uB0C0\uF4C1\uD084\uD085"+ + "\uF4C2\uD086\uD087\uB4FC\uD088\uC5DB\uD089\uD08A"+ + "\uD08B\uD08C\uCCBB\uD08D\uD08E\uD08F\uD0E4\uD090"+ + "\uD091\uD092\uD093\uD094\uCDE0\uD095\uD096\uD097"+ + "\uD098\uD099\uF1C8\uD09A\uD9F3\uD09B\uD09C\uD09D"+ + "\uD09E\uD09F\uD0A0\uB1BB\uD140\uCFAE\uD141\uD142"+ + "\uD143\uB8A4\uD144\uD145\uD146\uD147\uD148\uF1CA"+ + "\uD149\uD14A\uD14B\uD14C\uF1CB\uD14D\uD14E\uD14F"+ + "\uD150\uB2C3\uC1D1\uD151\uD152\uD7B0\uF1C9\uD153"+ + "\uD154\uF1CC\uD155\uD156\uD157\uD158\uF1CE\uD159"+ + "\uD15A\uD15B\uD9F6\uD15C\uD2E1\uD4A3\uD15D\uD15E"+ + "\uF4C3\uC8B9\uD15F\uD160\uD161\uD162\uD163\uF4C4"+ + "\uD164\uD165\uF1CD\uF1CF\uBFE3\uF1D0\uD166\uD167"+ + "\uF1D4\uD168\uD169\uD16A\uD16B\uD16C\uD16D\uD16E"+ + "\uF1D6\uF1D1\uD16F\uC9D1\uC5E1\uD170\uD171\uD172"+ + "\uC2E3\uB9FC\uD173\uD174\uF1D3\uD175\uF1D5\uD176"+ + "\uD177\uD178\uB9D3\uD179\uD17A\uD17B\uD17C\uD17D"+ + "\uD17E\uD180\uF1DB\uD181\uD182\uD183\uD184\uD185"+ + "\uBAD6\uD186\uB0FD\uF1D9\uD187\uD188\uD189\uD18A"+ + "\uD18B\uF1D8\uF1D2\uF1DA\uD18C\uD18D\uD18E\uD18F"+ + "\uD190\uF1D7\uD191\uD192\uD193\uC8EC\uD194\uD195"+ + "\uD196\uD197\uCDCA\uF1DD\uD198\uD199\uD19A\uD19B"+ + "\uE5BD\uD19C\uD19D\uD19E\uF1DC\uD19F\uF1DE\uD1A0"+ + "\uD240\uD241\uD242\uD243\uD244\uD245\uD246\uD247"+ + "\uD248\uF1DF\uD249\uD24A\uCFE5\uD24B\uD24C\uD24D"+ + "\uD24E\uD24F\uD250\uD251\uD252\uD253\uD254\uD255"+ + "\uD256\uD257\uD258\uD259\uD25A\uD25B\uD25C\uD25D"+ + "\uD25E\uD25F\uD260\uD261\uD262\uD263\uF4C5\uBDF3"+ + "\uD264\uD265\uD266\uD267\uD268\uD269\uF1E0\uD26A"+ + "\uD26B\uD26C\uD26D\uD26E\uD26F\uD270\uD271\uD272"+ + "\uD273\uD274\uD275\uD276\uD277\uD278\uD279\uD27A"+ + "\uD27B\uD27C\uD27D\uF1E1\uD27E\uD280\uD281\uCEF7"+ + "\uD282\uD2AA\uD283\uF1FB\uD284\uD285\uB8B2\uD286"+ + "\uD287\uD288\uD289\uD28A\uD28B\uD28C\uD28D\uD28E"+ + "\uD28F\uD290\uD291\uD292\uD293\uD294\uD295\uD296"+ + "\uD297\uD298\uD299\uD29A\uD29B\uD29C\uD29D\uD29E"+ + "\uD29F\uD2A0\uD340\uD341\uD342\uD343\uD344\uD345"+ + "\uD346\uD347\uD348\uD349\uD34A\uD34B\uD34C\uD34D"+ + "\uD34E\uD34F\uD350\uD351\uD352\uD353\uD354\uD355"+ + "\uD356\uD357\uD358\uD359\uD35A\uD35B\uD35C\uD35D"+ + "\uD35E\uBCFB\uB9DB\uD35F\uB9E6\uC3D9\uCAD3\uEAE8"+ + "\uC0C0\uBEF5\uEAE9\uEAEA\uEAEB\uD360\uEAEC\uEAED"+ + "\uEAEE\uEAEF\uBDC7\uD361\uD362\uD363\uF5FB\uD364"+ + "\uD365\uD366\uF5FD\uD367\uF5FE\uD368\uF5FC\uD369"+ + "\uD36A\uD36B\uD36C\uBDE2\uD36D\uF6A1\uB4A5\uD36E"+ + "\uD36F\uD370\uD371\uF6A2\uD372\uD373\uD374\uF6A3"+ + "\uD375\uD376\uD377\uECB2\uD378\uD379\uD37A\uD37B"+ + "\uD37C\uD37D\uD37E\uD380\uD381\uD382\uD383\uD384"+ + "\uD1D4\uD385\uD386\uD387\uD388\uD389\uD38A\uD9EA"+ + "\uD38B\uD38C\uD38D\uD38E\uD38F\uD390\uD391\uD392"+ + "\uD393\uD394\uD395\uD396\uD397\uD398\uD399\uD39A"+ + "\uD39B\uD39C\uD39D\uD39E\uD39F\uD3A0\uD440\uD441"+ + "\uD442\uD443\uD444\uD445\uD446\uD447\uD448\uD449"+ + "\uD44A\uD44B\uD44C\uD44D\uD44E\uD44F\uD450\uD451"+ + "\uD452\uD453\uD454\uD455\uD456\uD457\uD458\uD459"+ + "\uD45A\uD45B\uD45C\uD45D\uD45E\uD45F\uF6A4\uD460"+ + "\uD461\uD462\uD463\uD464\uD465\uD466\uD467\uD468"+ + "\uEEBA\uD469\uD46A\uD46B\uD46C\uD46D\uD46E\uD46F"+ + "\uD470\uD471\uD472\uD473\uD474\uD475\uD476\uD477"+ + "\uD478\uD479\uD47A\uD47B\uD47C\uD47D\uD47E\uD480"+ + "\uD481\uD482\uD483\uD484\uD485\uD486\uD487\uD488"+ + "\uD489\uD48A\uD48B\uD48C\uD48D\uD48E\uD48F\uD490"+ + "\uD491\uD492\uD493\uD494\uD495\uD496\uD497\uD498"+ + "\uD499\uD5B2\uD49A\uD49B\uD49C\uD49D\uD49E\uD49F"+ + "\uD4A0\uD540\uD541\uD542\uD543\uD544\uD545\uD546"+ + "\uD547\uD3FE\uCCDC\uD548\uD549\uD54A\uD54B\uD54C"+ + "\uD54D\uD54E\uD54F\uCAC4\uD550\uD551\uD552\uD553"+ + "\uD554\uD555\uD556\uD557\uD558\uD559\uD55A\uD55B"+ + "\uD55C\uD55D\uD55E\uD55F\uD560\uD561\uD562\uD563"+ + "\uD564\uD565\uD566\uD567\uD568\uD569\uD56A\uD56B"+ + "\uD56C\uD56D\uD56E\uD56F\uD570\uD571\uD572\uD573"+ + "\uD574\uD575\uD576\uD577\uD578\uD579\uD57A\uD57B"+ + "\uD57C\uD57D\uD57E\uD580\uD581\uD582\uD583\uD584"+ + "\uD585\uD586\uD587\uD588\uD589\uD58A\uD58B\uD58C"+ + "\uD58D\uD58E\uD58F\uD590\uD591\uD592\uD593\uD594"+ + "\uD595\uD596\uD597\uD598\uD599\uD59A\uD59B\uD59C"+ + "\uD59D\uD59E\uD59F\uD5A0\uD640\uD641\uD642\uD643"+ + "\uD644\uD645\uD646\uD647\uD648\uD649\uD64A\uD64B"+ + "\uD64C\uD64D\uD64E\uD64F\uD650\uD651\uD652\uD653"+ + "\uD654\uD655\uD656\uD657\uD658\uD659\uD65A\uD65B"+ + "\uD65C\uD65D\uD65E\uD65F\uD660\uD661\uD662\uE5C0"+ + "\uD663\uD664\uD665\uD666\uD667\uD668\uD669\uD66A"+ + "\uD66B\uD66C\uD66D\uD66E\uD66F\uD670\uD671\uD672"+ + "\uD673\uD674\uD675\uD676\uD677\uD678\uD679\uD67A"+ + "\uD67B\uD67C\uD67D\uD67E\uD680\uD681\uF6A5\uD682"+ + "\uD683\uD684\uD685\uD686\uD687\uD688\uD689\uD68A"+ + "\uD68B\uD68C\uD68D\uD68E\uD68F\uD690\uD691\uD692"+ + "\uD693\uD694\uD695\uD696\uD697\uD698\uD699\uD69A"+ + "\uD69B\uD69C\uD69D\uD69E\uD69F\uD6A0\uD740\uD741"+ + "\uD742\uD743\uD744\uD745\uD746\uD747\uD748\uD749"+ + "\uD74A\uD74B\uD74C\uD74D\uD74E\uD74F\uD750\uD751"+ + "\uD752\uD753\uD754\uD755\uD756\uD757\uD758\uD759"+ + "\uD75A\uD75B\uD75C\uD75D\uD75E\uD75F\uBEAF\uD760"+ + "\uD761\uD762\uD763\uD764\uC6A9\uD765\uD766\uD767"+ + "\uD768\uD769\uD76A\uD76B\uD76C\uD76D\uD76E\uD76F"+ + "\uD770\uD771\uD772\uD773\uD774\uD775\uD776\uD777"+ + "\uD778\uD779\uD77A\uD77B\uD77C\uD77D\uD77E\uD780"+ + "\uD781\uD782\uD783\uD784\uD785\uD786\uD787\uD788"+ + "\uD789\uD78A\uD78B\uD78C\uD78D\uD78E\uD78F\uD790"+ + "\uD791\uD792\uD793\uD794\uD795\uD796\uD797\uD798"+ + "\uDAA5\uBCC6\uB6A9\uB8BC\uC8CF\uBCA5\uDAA6\uDAA7"+ + "\uCCD6\uC8C3\uDAA8\uC6FD\uD799\uD1B5\uD2E9\uD1B6"+ + "\uBCC7\uD79A\uBDB2\uBBE4\uDAA9\uDAAA\uD1C8\uDAAB"+ + "\uD0ED\uB6EF\uC2DB\uD79B\uCBCF\uB7ED\uC9E8\uB7C3"+ + "\uBEF7\uD6A4\uDAAC\uDAAD\uC6C0\uD7E7\uCAB6\uD79C"+ + "\uD5A9\uCBDF\uD5EF\uDAAE\uD6DF\uB4CA\uDAB0\uDAAF"+ + "\uD79D\uD2EB\uDAB1\uDAB2\uDAB3\uCAD4\uDAB4\uCAAB"+ + "\uDAB5\uDAB6\uB3CF\uD6EF\uDAB7\uBBB0\uB5AE\uDAB8"+ + "\uDAB9\uB9EE\uD1AF\uD2E8\uDABA\uB8C3\uCFEA\uB2EF"+ + "\uDABB\uDABC\uD79E\uBDEB\uCEDC\uD3EF\uDABD\uCEF3"+ + "\uDABE\uD3D5\uBBE5\uDABF\uCBB5\uCBD0\uDAC0\uC7EB"+ + "\uD6EE\uDAC1\uC5B5\uB6C1\uDAC2\uB7CC\uBFCE\uDAC3"+ + "\uDAC4\uCBAD\uDAC5\uB5F7\uDAC6\uC1C2\uD7BB\uDAC7"+ + "\uCCB8\uD79F\uD2EA\uC4B1\uDAC8\uB5FD\uBBD1\uDAC9"+ + "\uD0B3\uDACA\uDACB\uCEBD\uDACC\uDACD\uDACE\uB2F7"+ + "\uDAD1\uDACF\uD1E8\uDAD0\uC3D5\uDAD2\uD7A0\uDAD3"+ + "\uDAD4\uDAD5\uD0BB\uD2A5\uB0F9\uDAD6\uC7AB\uDAD7"+ + "\uBDF7\uC3A1\uDAD8\uDAD9\uC3FD\uCCB7\uDADA\uDADB"+ + "\uC0BE\uC6D7\uDADC\uDADD\uC7B4\uDADE\uDADF\uB9C8"+ + "\uD840\uD841\uD842\uD843\uD844\uD845\uD846\uD847"+ + "\uD848\uBBED\uD849\uD84A\uD84B\uD84C\uB6B9\uF4F8"+ + "\uD84D\uF4F9\uD84E\uD84F\uCDE3\uD850\uD851\uD852"+ + "\uD853\uD854\uD855\uD856\uD857\uF5B9\uD858\uD859"+ + "\uD85A\uD85B\uEBE0\uD85C\uD85D\uD85E\uD85F\uD860"+ + "\uD861\uCFF3\uBBBF\uD862\uD863\uD864\uD865\uD866"+ + "\uD867\uD868\uBAC0\uD4A5\uD869\uD86A\uD86B\uD86C"+ + "\uD86D\uD86E\uD86F\uE1D9\uD870\uD871\uD872\uD873"+ + "\uF5F4\uB1AA\uB2F2\uD874\uD875\uD876\uD877\uD878"+ + "\uD879\uD87A\uF5F5\uD87B\uD87C\uF5F7\uD87D\uD87E"+ + "\uD880\uBAD1\uF5F6\uD881\uC3B2\uD882\uD883\uD884"+ + "\uD885\uD886\uD887\uD888\uF5F9\uD889\uD88A\uD88B"+ + "\uF5F8\uD88C\uD88D\uD88E\uD88F\uD890\uD891\uD892"+ + "\uD893\uD894\uD895\uD896\uD897\uD898\uD899\uD89A"+ + "\uD89B\uD89C\uD89D\uD89E\uD89F\uD8A0\uD940\uD941"+ + "\uD942\uD943\uD944\uD945\uD946\uD947\uD948\uD949"+ + "\uD94A\uD94B\uD94C\uD94D\uD94E\uD94F\uD950\uD951"+ + "\uD952\uD953\uD954\uD955\uD956\uD957\uD958\uD959"+ + "\uD95A\uD95B\uD95C\uD95D\uD95E\uD95F\uD960\uD961"+ + "\uD962\uD963\uD964\uD965\uD966\uD967\uD968\uD969"+ + "\uD96A\uD96B\uD96C\uD96D\uD96E\uD96F\uD970\uD971"+ + "\uD972\uD973\uD974\uD975\uD976\uD977\uD978\uD979"+ + "\uD97A\uD97B\uD97C\uD97D\uD97E\uD980\uD981\uD982"+ + "\uD983\uD984\uD985\uD986\uD987\uD988\uD989\uD98A"+ + "\uD98B\uD98C\uD98D\uD98E\uD98F\uD990\uD991\uD992"+ + "\uD993\uD994\uD995\uD996\uD997\uD998\uD999\uD99A"+ + "\uD99B\uD99C\uD99D\uD99E\uD99F\uD9A0\uDA40\uDA41"+ + "\uDA42\uDA43\uDA44\uDA45\uDA46\uDA47\uDA48\uDA49"+ + "\uDA4A\uDA4B\uDA4C\uDA4D\uDA4E\uB1B4\uD5EA\uB8BA"+ + "\uDA4F\uB9B1\uB2C6\uD4F0\uCFCD\uB0DC\uD5CB\uBBF5"+ + "\uD6CA\uB7B7\uCCB0\uC6B6\uB1E1\uB9BA\uD6FC\uB9E1"+ + "\uB7A1\uBCFA\uEADA\uEADB\uCCF9\uB9F3\uEADC\uB4FB"+ + "\uC3B3\uB7D1\uBAD8\uEADD\uD4F4\uEADE\uBCD6\uBBDF"+ + "\uEADF\uC1DE\uC2B8\uD4DF\uD7CA\uEAE0\uEAE1\uEAE4"+ + "\uEAE2\uEAE3\uC9DE\uB8B3\uB6C4\uEAE5\uCAEA\uC9CD"+ + "\uB4CD\uDA50\uDA51\uE2D9\uC5E2\uEAE6\uC0B5\uDA52"+ + "\uD7B8\uEAE7\uD7AC\uC8FC\uD8D3\uD8CD\uD4DE\uDA53"+ + "\uD4F9\uC9C4\uD3AE\uB8D3\uB3E0\uDA54\uC9E2\uF4F6"+ + "\uDA55\uDA56\uDA57\uBAD5\uDA58\uF4F7\uDA59\uDA5A"+ + "\uD7DF\uDA5B\uDA5C\uF4F1\uB8B0\uD5D4\uB8CF\uC6F0"+ + "\uDA5D\uDA5E\uDA5F\uDA60\uDA61\uDA62\uDA63\uDA64"+ + "\uDA65\uB3C3\uDA66\uDA67\uF4F2\uB3AC\uDA68\uDA69"+ + "\uDA6A\uDA6B\uD4BD\uC7F7\uDA6C\uDA6D\uDA6E\uDA6F"+ + "\uDA70\uF4F4\uDA71\uDA72\uF4F3\uDA73\uDA74\uDA75"+ + "\uDA76\uDA77\uDA78\uDA79\uDA7A\uDA7B\uDA7C\uCCCB"+ + "\uDA7D\uDA7E\uDA80\uC8A4\uDA81\uDA82\uDA83\uDA84"+ + "\uDA85\uDA86\uDA87\uDA88\uDA89\uDA8A\uDA8B\uDA8C"+ + "\uDA8D\uF4F5\uDA8E\uD7E3\uC5BF\uF5C0\uDA8F\uDA90"+ + "\uF5BB\uDA91\uF5C3\uDA92\uF5C2\uDA93\uD6BA\uF5C1"+ + "\uDA94\uDA95\uDA96\uD4BE\uF5C4\uDA97\uF5CC\uDA98"+ + "\uDA99\uDA9A\uDA9B\uB0CF\uB5F8\uDA9C\uF5C9\uF5CA"+ + "\uDA9D\uC5DC\uDA9E\uDA9F\uDAA0\uDB40\uF5C5\uF5C6"+ + "\uDB41\uDB42\uF5C7\uF5CB\uDB43\uBEE0\uF5C8\uB8FA"+ + "\uDB44\uDB45\uDB46\uF5D0\uF5D3\uDB47\uDB48\uDB49"+ + "\uBFE7\uDB4A\uB9F2\uF5BC\uF5CD\uDB4B\uDB4C\uC2B7"+ + "\uDB4D\uDB4E\uDB4F\uCCF8\uDB50\uBCF9\uDB51\uF5CE"+ + "\uF5CF\uF5D1\uB6E5\uF5D2\uDB52\uF5D5\uDB53\uDB54"+ + "\uDB55\uDB56\uDB57\uDB58\uDB59\uF5BD\uDB5A\uDB5B"+ + "\uDB5C\uF5D4\uD3BB\uDB5D\uB3EC\uDB5E\uDB5F\uCCA4"+ + "\uDB60\uDB61\uDB62\uDB63\uF5D6\uDB64\uDB65\uDB66"+ + "\uDB67\uDB68\uDB69\uDB6A\uDB6B\uF5D7\uBEE1\uF5D8"+ + "\uDB6C\uDB6D\uCCDF\uF5DB\uDB6E\uDB6F\uDB70\uDB71"+ + "\uDB72\uB2C8\uD7D9\uDB73\uF5D9\uDB74\uF5DA\uF5DC"+ + "\uDB75\uF5E2\uDB76\uDB77\uDB78\uF5E0\uDB79\uDB7A"+ + "\uDB7B\uF5DF\uF5DD\uDB7C\uDB7D\uF5E1\uDB7E\uDB80"+ + "\uF5DE\uF5E4\uF5E5\uDB81\uCCE3\uDB82\uDB83\uE5BF"+ + "\uB5B8\uF5E3\uF5E8\uCCA3\uDB84\uDB85\uDB86\uDB87"+ + "\uDB88\uF5E6\uF5E7\uDB89\uDB8A\uDB8B\uDB8C\uDB8D"+ + "\uDB8E\uF5BE\uDB8F\uDB90\uDB91\uDB92\uDB93\uDB94"+ + "\uDB95\uDB96\uDB97\uDB98\uDB99\uDB9A\uB1C4\uDB9B"+ + "\uDB9C\uF5BF\uDB9D\uDB9E\uB5C5\uB2E4\uDB9F\uF5EC"+ + "\uF5E9\uDBA0\uB6D7\uDC40\uF5ED\uDC41\uF5EA\uDC42"+ + "\uDC43\uDC44\uDC45\uDC46\uF5EB\uDC47\uDC48\uB4DA"+ + "\uDC49\uD4EA\uDC4A\uDC4B\uDC4C\uF5EE\uDC4D\uB3F9"+ + "\uDC4E\uDC4F\uDC50\uDC51\uDC52\uDC53\uDC54\uF5EF"+ + "\uF5F1\uDC55\uDC56\uDC57\uF5F0\uDC58\uDC59\uDC5A"+ + "\uDC5B\uDC5C\uDC5D\uDC5E\uF5F2\uDC5F\uF5F3\uDC60"+ + "\uDC61\uDC62\uDC63\uDC64\uDC65\uDC66\uDC67\uDC68"+ + "\uDC69\uDC6A\uDC6B\uC9ED\uB9AA\uDC6C\uDC6D\uC7FB"+ + "\uDC6E\uDC6F\uB6E3\uDC70\uDC71\uDC72\uDC73\uDC74"+ + "\uDC75\uDC76\uCCC9\uDC77\uDC78\uDC79\uDC7A\uDC7B"+ + "\uDC7C\uDC7D\uDC7E\uDC80\uDC81\uDC82\uDC83\uDC84"+ + "\uDC85\uDC86\uDC87\uDC88\uDC89\uDC8A\uEAA6\uDC8B"+ + "\uDC8C\uDC8D\uDC8E\uDC8F\uDC90\uDC91\uDC92\uDC93"+ + "\uDC94\uDC95\uDC96\uDC97\uDC98\uDC99\uDC9A\uDC9B"+ + "\uDC9C\uDC9D\uDC9E\uDC9F\uDCA0\uDD40\uDD41\uDD42"+ + "\uDD43\uDD44\uDD45\uDD46\uDD47\uDD48\uDD49\uDD4A"+ + "\uDD4B\uDD4C\uDD4D\uDD4E\uDD4F\uDD50\uDD51\uDD52"+ + "\uDD53\uDD54\uDD55\uDD56\uDD57\uDD58\uDD59\uDD5A"+ + "\uDD5B\uDD5C\uDD5D\uDD5E\uDD5F\uDD60\uDD61\uDD62"+ + "\uDD63\uDD64\uDD65\uDD66\uDD67\uDD68\uDD69\uDD6A"+ + "\uDD6B\uDD6C\uDD6D\uDD6E\uDD6F\uDD70\uDD71\uDD72"+ + "\uDD73\uDD74\uDD75\uDD76\uDD77\uDD78\uDD79\uDD7A"+ + "\uDD7B\uDD7C\uDD7D\uDD7E\uDD80\uDD81\uDD82\uDD83"+ + "\uDD84\uDD85\uDD86\uDD87\uDD88\uDD89\uDD8A\uDD8B"+ + "\uDD8C\uDD8D\uDD8E\uDD8F\uDD90\uDD91\uDD92\uDD93"+ + "\uDD94\uDD95\uDD96\uDD97\uDD98\uDD99\uDD9A\uDD9B"+ + "\uDD9C\uDD9D\uDD9E\uDD9F\uDDA0\uDE40\uDE41\uDE42"+ + "\uDE43\uDE44\uDE45\uDE46\uDE47\uDE48\uDE49\uDE4A"+ + "\uDE4B\uDE4C\uDE4D\uDE4E\uDE4F\uDE50\uDE51\uDE52"+ + "\uDE53\uDE54\uDE55\uDE56\uDE57\uDE58\uDE59\uDE5A"+ + "\uDE5B\uDE5C\uDE5D\uDE5E\uDE5F\uDE60\uB3B5\uD4FE"+ + "\uB9EC\uD0F9\uDE61\uE9ED\uD7AA\uE9EE\uC2D6\uC8ED"+ + "\uBAE4\uE9EF\uE9F0\uE9F1\uD6E1\uE9F2\uE9F3\uE9F5"+ + "\uE9F4\uE9F6\uE9F7\uC7E1\uE9F8\uD4D8\uE9F9\uBDCE"+ + "\uDE62\uE9FA\uE9FB\uBDCF\uE9FC\uB8A8\uC1BE\uE9FD"+ + "\uB1B2\uBBD4\uB9F5\uE9FE\uDE63\uEAA1\uEAA2\uEAA3"+ + "\uB7F8\uBCAD\uDE64\uCAE4\uE0CE\uD4AF\uCFBD\uD5B7"+ + "\uEAA4\uD5DE\uEAA5\uD0C1\uB9BC\uDE65\uB4C7\uB1D9"+ + "\uDE66\uDE67\uDE68\uC0B1\uDE69\uDE6A\uDE6B\uDE6C"+ + "\uB1E6\uB1E7\uDE6D\uB1E8\uDE6E\uDE6F\uDE70\uDE71"+ + "\uB3BD\uC8E8\uDE72\uDE73\uDE74\uDE75\uE5C1\uDE76"+ + "\uDE77\uB1DF\uDE78\uDE79\uDE7A\uC1C9\uB4EF\uDE7B"+ + "\uDE7C\uC7A8\uD3D8\uDE7D\uC6F9\uD1B8\uDE7E\uB9FD"+ + "\uC2F5\uDE80\uDE81\uDE82\uDE83\uDE84\uD3AD\uDE85"+ + "\uD4CB\uBDFC\uDE86\uE5C2\uB7B5\uE5C3\uDE87\uDE88"+ + "\uBBB9\uD5E2\uDE89\uBDF8\uD4B6\uCEA5\uC1AC\uB3D9"+ + "\uDE8A\uDE8B\uCCF6\uDE8C\uE5C6\uE5C4\uE5C8\uDE8D"+ + "\uE5CA\uE5C7\uB5CF\uC6C8\uDE8E\uB5FC\uE5C5\uDE8F"+ + "\uCAF6\uDE90\uDE91\uE5C9\uDE92\uDE93\uDE94\uC3D4"+ + "\uB1C5\uBCA3\uDE95\uDE96\uDE97\uD7B7\uDE98\uDE99"; + + private static final String innerEncoderIndex9= + "\uCDCB\uCBCD\uCACA\uCCD3\uE5CC\uE5CB\uC4E6\uDE9A"+ + "\uDE9B\uD1A1\uD1B7\uE5CD\uDE9C\uE5D0\uDE9D\uCDB8"+ + "\uD6F0\uE5CF\uB5DD\uDE9E\uCDBE\uDE9F\uE5D1\uB6BA"+ + "\uDEA0\uDF40\uCDA8\uB9E4\uDF41\uCAC5\uB3D1\uCBD9"+ + "\uD4EC\uE5D2\uB7EA\uDF42\uDF43\uDF44\uE5CE\uDF45"+ + "\uDF46\uDF47\uDF48\uDF49\uDF4A\uE5D5\uB4FE\uE5D6"+ + "\uDF4B\uDF4C\uDF4D\uDF4E\uDF4F\uE5D3\uE5D4\uDF50"+ + "\uD2DD\uDF51\uDF52\uC2DF\uB1C6\uDF53\uD3E2\uDF54"+ + "\uDF55\uB6DD\uCBEC\uDF56\uE5D7\uDF57\uDF58\uD3F6"+ + "\uDF59\uDF5A\uDF5B\uDF5C\uDF5D\uB1E9\uDF5E\uB6F4"+ + "\uE5DA\uE5D8\uE5D9\uB5C0\uDF5F\uDF60\uDF61\uD2C5"+ + "\uE5DC\uDF62\uDF63\uE5DE\uDF64\uDF65\uDF66\uDF67"+ + "\uDF68\uDF69\uE5DD\uC7B2\uDF6A\uD2A3\uDF6B\uDF6C"+ + "\uE5DB\uDF6D\uDF6E\uDF6F\uDF70\uD4E2\uD5DA\uDF71"+ + "\uDF72\uDF73\uDF74\uDF75\uE5E0\uD7F1\uDF76\uDF77"+ + "\uDF78\uDF79\uDF7A\uDF7B\uDF7C\uE5E1\uDF7D\uB1DC"+ + "\uD1FB\uDF7E\uE5E2\uE5E4\uDF80\uDF81\uDF82\uDF83"+ + "\uE5E3\uDF84\uDF85\uE5E5\uDF86\uDF87\uDF88\uDF89"+ + "\uDF8A\uD2D8\uDF8B\uB5CB\uDF8C\uE7DF\uDF8D\uDAF5"+ + "\uDF8E\uDAF8\uDF8F\uDAF6\uDF90\uDAF7\uDF91\uDF92"+ + "\uDF93\uDAFA\uD0CF\uC4C7\uDF94\uDF95\uB0EE\uDF96"+ + "\uDF97\uDF98\uD0B0\uDF99\uDAF9\uDF9A\uD3CA\uBAAA"+ + "\uDBA2\uC7F1\uDF9B\uDAFC\uDAFB\uC9DB\uDAFD\uDF9C"+ + "\uDBA1\uD7DE\uDAFE\uC1DA\uDF9D\uDF9E\uDBA5\uDF9F"+ + "\uDFA0\uD3F4\uE040\uE041\uDBA7\uDBA4\uE042\uDBA8"+ + "\uE043\uE044\uBDBC\uE045\uE046\uE047\uC0C9\uDBA3"+ + "\uDBA6\uD6A3\uE048\uDBA9\uE049\uE04A\uE04B\uDBAD"+ + "\uE04C\uE04D\uE04E\uDBAE\uDBAC\uBAC2\uE04F\uE050"+ + "\uE051\uBFA4\uDBAB\uE052\uE053\uE054\uDBAA\uD4C7"+ + "\uB2BF\uE055\uE056\uDBAF\uE057\uB9F9\uE058\uDBB0"+ + "\uE059\uE05A\uE05B\uE05C\uB3BB\uE05D\uE05E\uE05F"+ + "\uB5A6\uE060\uE061\uE062\uE063\uB6BC\uDBB1\uE064"+ + "\uE065\uE066\uB6F5\uE067\uDBB2\uE068\uE069\uE06A"+ + "\uE06B\uE06C\uE06D\uE06E\uE06F\uE070\uE071\uE072"+ + "\uE073\uE074\uE075\uE076\uE077\uE078\uE079\uE07A"+ + "\uE07B\uB1C9\uE07C\uE07D\uE07E\uE080\uDBB4\uE081"+ + "\uE082\uE083\uDBB3\uDBB5\uE084\uE085\uE086\uE087"+ + "\uE088\uE089\uE08A\uE08B\uE08C\uE08D\uE08E\uDBB7"+ + "\uE08F\uDBB6\uE090\uE091\uE092\uE093\uE094\uE095"+ + "\uE096\uDBB8\uE097\uE098\uE099\uE09A\uE09B\uE09C"+ + "\uE09D\uE09E\uE09F\uDBB9\uE0A0\uE140\uDBBA\uE141"+ + "\uE142\uD3CF\uF4FA\uC7F5\uD7C3\uC5E4\uF4FC\uF4FD"+ + "\uF4FB\uE143\uBEC6\uE144\uE145\uE146\uE147\uD0EF"+ + "\uE148\uE149\uB7D3\uE14A\uE14B\uD4CD\uCCAA\uE14C"+ + "\uE14D\uF5A2\uF5A1\uBAA8\uF4FE\uCBD6\uE14E\uE14F"+ + "\uE150\uF5A4\uC0D2\uE151\uB3EA\uE152\uCDAA\uF5A5"+ + "\uF5A3\uBDB4\uF5A8\uE153\uF5A9\uBDCD\uC3B8\uBFE1"+ + "\uCBE1\uF5AA\uE154\uE155\uE156\uF5A6\uF5A7\uC4F0"+ + "\uE157\uE158\uE159\uE15A\uE15B\uF5AC\uE15C\uB4BC"+ + "\uE15D\uD7ED\uE15E\uB4D7\uF5AB\uF5AE\uE15F\uE160"+ + "\uF5AD\uF5AF\uD0D1\uE161\uE162\uE163\uE164\uE165"+ + "\uE166\uE167\uC3D1\uC8A9\uE168\uE169\uE16A\uE16B"+ + "\uE16C\uE16D\uF5B0\uF5B1\uE16E\uE16F\uE170\uE171"+ + "\uE172\uE173\uF5B2\uE174\uE175\uF5B3\uF5B4\uF5B5"+ + "\uE176\uE177\uE178\uE179\uF5B7\uF5B6\uE17A\uE17B"+ + "\uE17C\uE17D\uF5B8\uE17E\uE180\uE181\uE182\uE183"+ + "\uE184\uE185\uE186\uE187\uE188\uE189\uE18A\uB2C9"+ + "\uE18B\uD3D4\uCACD\uE18C\uC0EF\uD6D8\uD2B0\uC1BF"+ + "\uE18D\uBDF0\uE18E\uE18F\uE190\uE191\uE192\uE193"+ + "\uE194\uE195\uE196\uE197\uB8AA\uE198\uE199\uE19A"+ + "\uE19B\uE19C\uE19D\uE19E\uE19F\uE1A0\uE240\uE241"+ + "\uE242\uE243\uE244\uE245\uE246\uE247\uE248\uE249"+ + "\uE24A\uE24B\uE24C\uE24D\uE24E\uE24F\uE250\uE251"+ + "\uE252\uE253\uE254\uE255\uE256\uE257\uE258\uE259"+ + "\uE25A\uE25B\uE25C\uE25D\uE25E\uE25F\uE260\uE261"+ + "\uE262\uE263\uE264\uE265\uE266\uE267\uE268\uE269"+ + "\uE26A\uE26B\uE26C\uE26D\uE26E\uE26F\uE270\uE271"+ + "\uE272\uE273\uE274\uE275\uE276\uE277\uE278\uE279"+ + "\uE27A\uE27B\uE27C\uE27D\uE27E\uE280\uE281\uE282"+ + "\uE283\uE284\uE285\uE286\uE287\uE288\uE289\uE28A"+ + "\uE28B\uE28C\uE28D\uE28E\uE28F\uE290\uE291\uE292"+ + "\uE293\uE294\uE295\uE296\uE297\uE298\uE299\uE29A"+ + "\uE29B\uE29C\uE29D\uE29E\uE29F\uE2A0\uE340\uE341"+ + "\uE342\uE343\uE344\uE345\uE346\uE347\uE348\uE349"+ + "\uE34A\uE34B\uE34C\uE34D\uE34E\uE34F\uE350\uE351"+ + "\uE352\uE353\uE354\uE355\uE356\uE357\uE358\uE359"+ + "\uE35A\uE35B\uE35C\uE35D\uE35E\uE35F\uE360\uE361"+ + "\uE362\uE363\uE364\uE365\uE366\uE367\uE368\uE369"+ + "\uE36A\uE36B\uE36C\uE36D\uBCF8\uE36E\uE36F\uE370"+ + "\uE371\uE372\uE373\uE374\uE375\uE376\uE377\uE378"+ + "\uE379\uE37A\uE37B\uE37C\uE37D\uE37E\uE380\uE381"+ + "\uE382\uE383\uE384\uE385\uE386\uE387\uF6C6\uE388"+ + "\uE389\uE38A\uE38B\uE38C\uE38D\uE38E\uE38F\uE390"+ + "\uE391\uE392\uE393\uE394\uE395\uE396\uE397\uE398"+ + "\uE399\uE39A\uE39B\uE39C\uE39D\uE39E\uE39F\uE3A0"+ + "\uE440\uE441\uE442\uE443\uE444\uE445\uF6C7\uE446"+ + "\uE447\uE448\uE449\uE44A\uE44B\uE44C\uE44D\uE44E"+ + "\uE44F\uE450\uE451\uE452\uE453\uE454\uE455\uE456"+ + "\uE457\uE458\uE459\uE45A\uE45B\uE45C\uE45D\uE45E"+ + "\uF6C8\uE45F\uE460\uE461\uE462\uE463\uE464\uE465"+ + "\uE466\uE467\uE468\uE469\uE46A\uE46B\uE46C\uE46D"+ + "\uE46E\uE46F\uE470\uE471\uE472\uE473\uE474\uE475"+ + "\uE476\uE477\uE478\uE479\uE47A\uE47B\uE47C\uE47D"+ + "\uE47E\uE480\uE481\uE482\uE483\uE484\uE485\uE486"+ + "\uE487\uE488\uE489\uE48A\uE48B\uE48C\uE48D\uE48E"+ + "\uE48F\uE490\uE491\uE492\uE493\uE494\uE495\uE496"+ + "\uE497\uE498\uE499\uE49A\uE49B\uE49C\uE49D\uE49E"+ + "\uE49F\uE4A0\uE540\uE541\uE542\uE543\uE544\uE545"+ + "\uE546\uE547\uE548\uE549\uE54A\uE54B\uE54C\uE54D"+ + "\uE54E\uE54F\uE550\uE551\uE552\uE553\uE554\uE555"+ + "\uE556\uE557\uE558\uE559\uE55A\uE55B\uE55C\uE55D"+ + "\uE55E\uE55F\uE560\uE561\uE562\uE563\uE564\uE565"+ + "\uE566\uE567\uE568\uE569\uE56A\uE56B\uE56C\uE56D"+ + "\uE56E\uE56F\uE570\uE571\uE572\uE573\uF6C9\uE574"+ + "\uE575\uE576\uE577\uE578\uE579\uE57A\uE57B\uE57C"+ + "\uE57D\uE57E\uE580\uE581\uE582\uE583\uE584\uE585"+ + "\uE586\uE587\uE588\uE589\uE58A\uE58B\uE58C\uE58D"+ + "\uE58E\uE58F\uE590\uE591\uE592\uE593\uE594\uE595"+ + "\uE596\uE597\uE598\uE599\uE59A\uE59B\uE59C\uE59D"+ + "\uE59E\uE59F\uF6CA\uE5A0\uE640\uE641\uE642\uE643"+ + "\uE644\uE645\uE646\uE647\uE648\uE649\uE64A\uE64B"+ + "\uE64C\uE64D\uE64E\uE64F\uE650\uE651\uE652\uE653"+ + "\uE654\uE655\uE656\uE657\uE658\uE659\uE65A\uE65B"+ + "\uE65C\uE65D\uE65E\uE65F\uE660\uE661\uE662\uF6CC"+ + "\uE663\uE664\uE665\uE666\uE667\uE668\uE669\uE66A"+ + "\uE66B\uE66C\uE66D\uE66E\uE66F\uE670\uE671\uE672"+ + "\uE673\uE674\uE675\uE676\uE677\uE678\uE679\uE67A"+ + "\uE67B\uE67C\uE67D\uE67E\uE680\uE681\uE682\uE683"+ + "\uE684\uE685\uE686\uE687\uE688\uE689\uE68A\uE68B"+ + "\uE68C\uE68D\uE68E\uE68F\uE690\uE691\uE692\uE693"+ + "\uE694\uE695\uE696\uE697\uE698\uE699\uE69A\uE69B"+ + "\uE69C\uE69D\uF6CB\uE69E\uE69F\uE6A0\uE740\uE741"+ + "\uE742\uE743\uE744\uE745\uE746\uE747\uF7E9\uE748"+ + "\uE749\uE74A\uE74B\uE74C\uE74D\uE74E\uE74F\uE750"+ + "\uE751\uE752\uE753\uE754\uE755\uE756\uE757\uE758"+ + "\uE759\uE75A\uE75B\uE75C\uE75D\uE75E\uE75F\uE760"+ + "\uE761\uE762\uE763\uE764\uE765\uE766\uE767\uE768"+ + "\uE769\uE76A\uE76B\uE76C\uE76D\uE76E\uE76F\uE770"+ + "\uE771\uE772\uE773\uE774\uE775\uE776\uE777\uE778"+ + "\uE779\uE77A\uE77B\uE77C\uE77D\uE77E\uE780\uE781"+ + "\uE782\uE783\uE784\uE785\uE786\uE787\uE788\uE789"+ + "\uE78A\uE78B\uE78C\uE78D\uE78E\uE78F\uE790\uE791"+ + "\uE792\uE793\uE794\uE795\uE796\uE797\uE798\uE799"+ + "\uE79A\uE79B\uE79C\uE79D\uE79E\uE79F\uE7A0\uE840"+ + "\uE841\uE842\uE843\uE844\uE845\uE846\uE847\uE848"+ + "\uE849\uE84A\uE84B\uE84C\uE84D\uE84E\uF6CD\uE84F"+ + "\uE850\uE851\uE852\uE853\uE854\uE855\uE856\uE857"+ + "\uE858\uE859\uE85A\uE85B\uE85C\uE85D\uE85E\uE85F"+ + "\uE860\uE861\uE862\uE863\uE864\uE865\uE866\uE867"+ + "\uE868\uE869\uE86A\uE86B\uE86C\uE86D\uE86E\uE86F"+ + "\uE870\uE871\uE872\uE873\uE874\uE875\uE876\uE877"+ + "\uE878\uE879\uE87A\uF6CE\uE87B\uE87C\uE87D\uE87E"+ + "\uE880\uE881\uE882\uE883\uE884\uE885\uE886\uE887"+ + "\uE888\uE889\uE88A\uE88B\uE88C\uE88D\uE88E\uE88F"+ + "\uE890\uE891\uE892\uE893\uE894\uEEC4\uEEC5\uEEC6"+ + "\uD5EB\uB6A4\uEEC8\uEEC7\uEEC9\uEECA\uC7A5\uEECB"+ + "\uEECC\uE895\uB7B0\uB5F6\uEECD\uEECF\uE896\uEECE"+ + "\uE897\uB8C6\uEED0\uEED1\uEED2\uB6DB\uB3AE\uD6D3"+ + "\uC4C6\uB1B5\uB8D6\uEED3\uEED4\uD4BF\uC7D5\uBEFB"+ + "\uCED9\uB9B3\uEED6\uEED5\uEED8\uEED7\uC5A5\uEED9"+ + "\uEEDA\uC7AE\uEEDB\uC7AF\uEEDC\uB2A7\uEEDD\uEEDE"+ + "\uEEDF\uEEE0\uEEE1\uD7EA\uEEE2\uEEE3\uBCD8\uEEE4"+ + "\uD3CB\uCCFA\uB2AC\uC1E5\uEEE5\uC7A6\uC3AD\uE898"+ + "\uEEE6\uEEE7\uEEE8\uEEE9\uEEEA\uEEEB\uEEEC\uE899"+ + "\uEEED\uEEEE\uEEEF\uE89A\uE89B\uEEF0\uEEF1\uEEF2"+ + "\uEEF4\uEEF3\uE89C\uEEF5\uCDAD\uC2C1\uEEF6\uEEF7"+ + "\uEEF8\uD5A1\uEEF9\uCFB3\uEEFA\uEEFB\uE89D\uEEFC"+ + "\uEEFD\uEFA1\uEEFE\uEFA2\uB8F5\uC3FA\uEFA3\uEFA4"+ + "\uBDC2\uD2BF\uB2F9\uEFA5\uEFA6\uEFA7\uD2F8\uEFA8"+ + "\uD6FD\uEFA9\uC6CC\uE89E\uEFAA\uEFAB\uC1B4\uEFAC"+ + "\uCFFA\uCBF8\uEFAE\uEFAD\uB3FA\uB9F8\uEFAF\uEFB0"+ + "\uD0E2\uEFB1\uEFB2\uB7E6\uD0BF\uEFB3\uEFB4\uEFB5"+ + "\uC8F1\uCCE0\uEFB6\uEFB7\uEFB8\uEFB9\uEFBA\uD5E0"+ + "\uEFBB\uB4ED\uC3AA\uEFBC\uE89F\uEFBD\uEFBE\uEFBF"+ + "\uE8A0\uCEFD\uEFC0\uC2E0\uB4B8\uD7B6\uBDF5\uE940"+ + "\uCFC7\uEFC3\uEFC1\uEFC2\uEFC4\uB6A7\uBCFC\uBEE2"+ + "\uC3CC\uEFC5\uEFC6\uE941\uEFC7\uEFCF\uEFC8\uEFC9"+ + "\uEFCA\uC7C2\uEFF1\uB6CD\uEFCB\uE942\uEFCC\uEFCD"+ + "\uB6C6\uC3BE\uEFCE\uE943\uEFD0\uEFD1\uEFD2\uD5F2"+ + "\uE944\uEFD3\uC4F7\uE945\uEFD4\uC4F8\uEFD5\uEFD6"+ + "\uB8E4\uB0F7\uEFD7\uEFD8\uEFD9\uE946\uEFDA\uEFDB"+ + "\uEFDC\uEFDD\uE947\uEFDE\uBEB5\uEFE1\uEFDF\uEFE0"+ + "\uE948\uEFE2\uEFE3\uC1CD\uEFE4\uEFE5\uEFE6\uEFE7"+ + "\uEFE8\uEFE9\uEFEA\uEFEB\uEFEC\uC0D8\uE949\uEFED"+ + "\uC1AD\uEFEE\uEFEF\uEFF0\uE94A\uE94B\uCFE2\uE94C"+ + "\uE94D\uE94E\uE94F\uE950\uE951\uE952\uE953\uB3A4"+ + "\uE954\uE955\uE956\uE957\uE958\uE959\uE95A\uE95B"+ + "\uE95C\uE95D\uE95E\uE95F\uE960\uE961\uE962\uE963"+ + "\uE964\uE965\uE966\uE967\uE968\uE969\uE96A\uE96B"+ + "\uE96C\uE96D\uE96E\uE96F\uE970\uE971\uE972\uE973"+ + "\uE974\uE975\uE976\uE977\uE978\uE979\uE97A\uE97B"+ + "\uE97C\uE97D\uE97E\uE980\uE981\uE982\uE983\uE984"+ + "\uE985\uE986\uE987\uE988\uE989\uE98A\uE98B\uE98C"+ + "\uE98D\uE98E\uE98F\uE990\uE991\uE992\uE993\uE994"+ + "\uE995\uE996\uE997\uE998\uE999\uE99A\uE99B\uE99C"+ + "\uE99D\uE99E\uE99F\uE9A0\uEA40\uEA41\uEA42\uEA43"+ + "\uEA44\uEA45\uEA46\uEA47\uEA48\uEA49\uEA4A\uEA4B"+ + "\uEA4C\uEA4D\uEA4E\uEA4F\uEA50\uEA51\uEA52\uEA53"+ + "\uEA54\uEA55\uEA56\uEA57\uEA58\uEA59\uEA5A\uEA5B"+ + "\uC3C5\uE3C5\uC9C1\uE3C6\uEA5C\uB1D5\uCECA\uB4B3"+ + "\uC8F2\uE3C7\uCFD0\uE3C8\uBCE4\uE3C9\uE3CA\uC3C6"+ + "\uD5A2\uC4D6\uB9EB\uCEC5\uE3CB\uC3F6\uE3CC\uEA5D"+ + "\uB7A7\uB8F3\uBAD2\uE3CD\uE3CE\uD4C4\uE3CF\uEA5E"+ + "\uE3D0\uD1CB\uE3D1\uE3D2\uE3D3\uE3D4\uD1D6\uE3D5"+ + "\uB2FB\uC0BB\uE3D6\uEA5F\uC0AB\uE3D7\uE3D8\uE3D9"+ + "\uEA60\uE3DA\uE3DB\uEA61\uB8B7\uDAE2\uEA62\uB6D3"+ + "\uEA63\uDAE4\uDAE3\uEA64\uEA65\uEA66\uEA67\uEA68"+ + "\uEA69\uEA6A\uDAE6\uEA6B\uEA6C\uEA6D\uC8EE\uEA6E"+ + "\uEA6F\uDAE5\uB7C0\uD1F4\uD2F5\uD5F3\uBDD7\uEA70"+ + "\uEA71\uEA72\uEA73\uD7E8\uDAE8\uDAE7\uEA74\uB0A2"+ + "\uCDD3\uEA75\uDAE9\uEA76\uB8BD\uBCCA\uC2BD\uC2A4"+ + "\uB3C2\uDAEA\uEA77\uC2AA\uC4B0\uBDB5\uEA78\uEA79"+ + "\uCFDE\uEA7A\uEA7B\uEA7C\uDAEB\uC9C2\uEA7D\uEA7E"+ + "\uEA80\uEA81\uEA82\uB1DD\uEA83\uEA84\uEA85\uDAEC"+ + "\uEA86\uB6B8\uD4BA\uEA87\uB3FD\uEA88\uEA89\uDAED"+ + "\uD4C9\uCFD5\uC5E3\uEA8A\uDAEE\uEA8B\uEA8C\uEA8D"+ + "\uEA8E\uEA8F\uDAEF\uEA90\uDAF0\uC1EA\uCCD5\uCFDD"+ + "\uEA91\uEA92\uEA93\uEA94\uEA95\uEA96\uEA97\uEA98"+ + "\uEA99\uEA9A\uEA9B\uEA9C\uEA9D\uD3E7\uC2A1\uEA9E"+ + "\uDAF1\uEA9F\uEAA0\uCBE5\uEB40\uDAF2\uEB41\uCBE6"+ + "\uD2FE\uEB42\uEB43\uEB44\uB8F4\uEB45\uEB46\uDAF3"+ + "\uB0AF\uCFB6\uEB47\uEB48\uD5CF\uEB49\uEB4A\uEB4B"+ + "\uEB4C\uEB4D\uEB4E\uEB4F\uEB50\uEB51\uEB52\uCBED"+ + "\uEB53\uEB54\uEB55\uEB56\uEB57\uEB58\uEB59\uEB5A"+ + "\uDAF4\uEB5B\uEB5C\uE3C4\uEB5D\uEB5E\uC1A5\uEB5F"+ + "\uEB60\uF6BF\uEB61\uEB62\uF6C0\uF6C1\uC4D1\uEB63"+ + "\uC8B8\uD1E3\uEB64\uEB65\uD0DB\uD1C5\uBCAF\uB9CD"+ + "\uEB66\uEFF4\uEB67\uEB68\uB4C6\uD3BA\uF6C2\uB3FB"+ + "\uEB69\uEB6A\uF6C3\uEB6B\uEB6C\uB5F1\uEB6D\uEB6E"+ + "\uEB6F\uEB70\uEB71\uEB72\uEB73\uEB74\uEB75\uEB76"+ + "\uF6C5\uEB77\uEB78\uEB79\uEB7A\uEB7B\uEB7C\uEB7D"+ + "\uD3EA\uF6A7\uD1A9\uEB7E\uEB80\uEB81\uEB82\uF6A9"+ + "\uEB83\uEB84\uEB85\uF6A8\uEB86\uEB87\uC1E3\uC0D7"+ + "\uEB88\uB1A2\uEB89\uEB8A\uEB8B\uEB8C\uCEED\uEB8D"+ + "\uD0E8\uF6AB\uEB8E\uEB8F\uCFF6\uEB90\uF6AA\uD5F0"+ + "\uF6AC\uC3B9\uEB91\uEB92\uEB93\uBBF4\uF6AE\uF6AD"+ + "\uEB94\uEB95\uEB96\uC4DE\uEB97\uEB98\uC1D8\uEB99"+ + "\uEB9A\uEB9B\uEB9C\uEB9D\uCBAA\uEB9E\uCFBC\uEB9F"+ + "\uEBA0\uEC40\uEC41\uEC42\uEC43\uEC44\uEC45\uEC46"+ + "\uEC47\uEC48\uF6AF\uEC49\uEC4A\uF6B0\uEC4B\uEC4C"+ + "\uF6B1\uEC4D\uC2B6\uEC4E\uEC4F\uEC50\uEC51\uEC52"+ + "\uB0D4\uC5F9\uEC53\uEC54\uEC55\uEC56\uF6B2\uEC57"+ + "\uEC58\uEC59\uEC5A\uEC5B\uEC5C\uEC5D\uEC5E\uEC5F"+ + "\uEC60\uEC61\uEC62\uEC63\uEC64\uEC65\uEC66\uEC67"+ + "\uEC68\uEC69\uC7E0\uF6A6\uEC6A\uEC6B\uBEB8\uEC6C"+ + "\uEC6D\uBEB2\uEC6E\uB5E5\uEC6F\uEC70\uB7C7\uEC71"+ + "\uBFBF\uC3D2\uC3E6\uEC72\uEC73\uD8CC\uEC74\uEC75"+ + "\uEC76\uB8EF\uEC77\uEC78\uEC79\uEC7A\uEC7B\uEC7C"+ + "\uEC7D\uEC7E\uEC80\uBDF9\uD1A5\uEC81\uB0D0\uEC82"+ + "\uEC83\uEC84\uEC85\uEC86\uF7B0\uEC87\uEC88\uEC89"+ + "\uEC8A\uEC8B\uEC8C\uEC8D\uEC8E\uF7B1\uEC8F\uEC90"+ + "\uEC91\uEC92\uEC93\uD0AC\uEC94\uB0B0\uEC95\uEC96"+ + "\uEC97\uF7B2\uF7B3\uEC98\uF7B4\uEC99\uEC9A\uEC9B"+ + "\uC7CA\uEC9C\uEC9D\uEC9E\uEC9F\uECA0\uED40\uED41"+ + "\uBECF\uED42\uED43\uF7B7\uED44\uED45\uED46\uED47"+ + "\uED48\uED49\uED4A\uF7B6\uED4B\uB1DE\uED4C\uF7B5"+ + "\uED4D\uED4E\uF7B8\uED4F\uF7B9\uED50\uED51\uED52"+ + "\uED53\uED54\uED55\uED56\uED57\uED58\uED59\uED5A"+ + "\uED5B\uED5C\uED5D\uED5E\uED5F\uED60\uED61\uED62"+ + "\uED63\uED64\uED65\uED66\uED67\uED68\uED69\uED6A"+ + "\uED6B\uED6C\uED6D\uED6E\uED6F\uED70\uED71\uED72"+ + "\uED73\uED74\uED75\uED76\uED77\uED78\uED79\uED7A"+ + "\uED7B\uED7C\uED7D\uED7E\uED80\uED81\uCEA4\uC8CD"+ + "\uED82\uBAAB\uE8B8\uE8B9\uE8BA\uBEC2\uED83\uED84"+ + "\uED85\uED86\uED87\uD2F4\uED88\uD4CF\uC9D8\uED89"+ + "\uED8A\uED8B\uED8C\uED8D\uED8E\uED8F\uED90\uED91"+ + "\uED92\uED93\uED94\uED95\uED96\uED97\uED98\uED99"+ + "\uED9A\uED9B\uED9C\uED9D\uED9E\uED9F\uEDA0\uEE40"+ + "\uEE41\uEE42\uEE43\uEE44\uEE45\uEE46\uEE47\uEE48"+ + "\uEE49\uEE4A\uEE4B\uEE4C\uEE4D\uEE4E\uEE4F\uEE50"+ + "\uEE51\uEE52\uEE53\uEE54\uEE55\uEE56\uEE57\uEE58"+ + "\uEE59\uEE5A\uEE5B\uEE5C\uEE5D\uEE5E\uEE5F\uEE60"+ + "\uEE61\uEE62\uEE63\uEE64\uEE65\uEE66\uEE67\uEE68"+ + "\uEE69\uEE6A\uEE6B\uEE6C\uEE6D\uEE6E\uEE6F\uEE70"+ + "\uEE71\uEE72\uEE73\uEE74\uEE75\uEE76\uEE77\uEE78"+ + "\uEE79\uEE7A\uEE7B\uEE7C\uEE7D\uEE7E\uEE80\uEE81"+ + "\uEE82\uEE83\uEE84\uEE85\uEE86\uEE87\uEE88\uEE89"+ + "\uEE8A\uEE8B\uEE8C\uEE8D\uEE8E\uEE8F\uEE90\uEE91"+ + "\uEE92\uEE93\uEE94\uEE95\uEE96\uEE97\uEE98\uEE99"+ + "\uEE9A\uEE9B\uEE9C\uEE9D\uEE9E\uEE9F\uEEA0\uEF40"+ + "\uEF41\uEF42\uEF43\uEF44\uEF45\uD2B3\uB6A5\uC7EA"+ + "\uF1FC\uCFEE\uCBB3\uD0EB\uE7EF\uCDE7\uB9CB\uB6D9"+ + "\uF1FD\uB0E4\uCBCC\uF1FE\uD4A4\uC2AD\uC1EC\uC6C4"+ + "\uBEB1\uF2A1\uBCD5\uEF46\uF2A2\uF2A3\uEF47\uF2A4"+ + "\uD2C3\uC6B5\uEF48\uCDC7\uF2A5\uEF49\uD3B1\uBFC5"+ + "\uCCE2\uEF4A\uF2A6\uF2A7\uD1D5\uB6EE\uF2A8\uF2A9"+ + "\uB5DF\uF2AA\uF2AB\uEF4B\uB2FC\uF2AC\uF2AD\uC8A7"+ + "\uEF4C\uEF4D\uEF4E\uEF4F\uEF50\uEF51\uEF52\uEF53"+ + "\uEF54\uEF55\uEF56\uEF57\uEF58\uEF59\uEF5A\uEF5B"+ + "\uEF5C\uEF5D\uEF5E\uEF5F\uEF60\uEF61\uEF62\uEF63"+ + "\uEF64\uEF65\uEF66\uEF67\uEF68\uEF69\uEF6A\uEF6B"+ + "\uEF6C\uEF6D\uEF6E\uEF6F\uEF70\uEF71\uB7E7\uEF72"+ + "\uEF73\uECA9\uECAA\uECAB\uEF74\uECAC\uEF75\uEF76"+ + "\uC6AE\uECAD\uECAE\uEF77\uEF78\uEF79\uB7C9\uCAB3"+ + "\uEF7A\uEF7B\uEF7C\uEF7D\uEF7E\uEF80\uEF81\uE2B8"+ + "\uF7CF\uEF82\uEF83\uEF84\uEF85\uEF86\uEF87\uEF88"+ + "\uEF89\uEF8A\uEF8B\uEF8C\uEF8D\uEF8E\uEF8F\uEF90"+ + "\uEF91\uEF92\uEF93\uEF94\uEF95\uEF96\uEF97\uEF98"+ + "\uEF99\uEF9A\uEF9B\uEF9C\uEF9D\uEF9E\uEF9F\uEFA0"+ + "\uF040\uF041\uF042\uF043\uF044\uF7D0\uF045\uF046"+ + "\uB2CD\uF047\uF048\uF049\uF04A\uF04B\uF04C\uF04D"+ + "\uF04E\uF04F\uF050\uF051\uF052\uF053\uF054\uF055"+ + "\uF056\uF057\uF058\uF059\uF05A\uF05B\uF05C\uF05D"+ + "\uF05E\uF05F\uF060\uF061\uF062\uF063\uF7D1\uF064"+ + "\uF065\uF066\uF067\uF068\uF069\uF06A\uF06B\uF06C"+ + "\uF06D\uF06E\uF06F\uF070\uF071\uF072\uF073\uF074"+ + "\uF075\uF076\uF077\uF078\uF079\uF07A\uF07B\uF07C"+ + "\uF07D\uF07E\uF080\uF081\uF082\uF083\uF084\uF085"+ + "\uF086\uF087\uF088\uF089\uF7D3\uF7D2\uF08A\uF08B"+ + "\uF08C\uF08D\uF08E\uF08F\uF090\uF091\uF092\uF093"+ + "\uF094\uF095\uF096\uE2BB\uF097\uBCA2\uF098\uE2BC"+ + "\uE2BD\uE2BE\uE2BF\uE2C0\uE2C1\uB7B9\uD2FB\uBDA4"+ + "\uCACE\uB1A5\uCBC7\uF099\uE2C2\uB6FC\uC8C4\uE2C3"+ + "\uF09A\uF09B\uBDC8\uF09C\uB1FD\uE2C4\uF09D\uB6F6"+ + "\uE2C5\uC4D9\uF09E\uF09F\uE2C6\uCFDA\uB9DD\uE2C7"+ + "\uC0A1\uF0A0\uE2C8\uB2F6\uF140\uE2C9\uF141\uC1F3"+ + "\uE2CA\uE2CB\uC2F8\uE2CC\uE2CD\uE2CE\uCAD7\uD8B8"+ + "\uD9E5\uCFE3\uF142\uF143\uF144\uF145\uF146\uF147"+ + "\uF148\uF149\uF14A\uF14B\uF14C\uF0A5\uF14D\uF14E"+ + "\uDCB0\uF14F\uF150\uF151\uF152\uF153\uF154\uF155"+ + "\uF156\uF157\uF158\uF159\uF15A\uF15B\uF15C\uF15D"+ + "\uF15E\uF15F\uF160\uF161\uF162\uF163\uF164\uF165"+ + "\uF166\uF167\uF168\uF169\uF16A\uF16B\uF16C\uF16D"+ + "\uF16E\uF16F\uF170\uF171\uF172\uF173\uF174\uF175"+ + "\uF176\uF177\uF178\uF179\uF17A\uF17B\uF17C\uF17D"+ + "\uF17E\uF180\uF181\uF182\uF183\uF184\uF185\uF186"+ + "\uF187\uF188\uF189\uF18A\uF18B\uF18C\uF18D\uF18E"+ + "\uF18F\uF190\uF191\uF192\uF193\uF194\uF195\uF196"+ + "\uF197\uF198\uF199\uF19A\uF19B\uF19C\uF19D\uF19E"+ + "\uF19F\uF1A0\uF240\uF241\uF242\uF243\uF244\uF245"+ + "\uF246\uF247\uF248\uF249\uF24A\uF24B\uF24C\uF24D"+ + "\uF24E\uF24F\uF250\uF251\uF252\uF253\uF254\uF255"+ + "\uF256\uF257\uF258\uF259\uF25A\uF25B\uF25C\uF25D"+ + "\uF25E\uF25F\uF260\uF261\uF262\uF263\uF264\uF265"+ + "\uF266\uF267\uF268\uF269\uF26A\uF26B\uF26C\uF26D"+ + "\uF26E\uF26F\uF270\uF271\uF272\uF273\uF274\uF275"+ + "\uF276\uF277\uF278\uF279\uF27A\uF27B\uF27C\uF27D"+ + "\uF27E\uF280\uF281\uF282\uF283\uF284\uF285\uF286"+ + "\uF287\uF288\uF289\uF28A\uF28B\uF28C\uF28D\uF28E"+ + "\uF28F\uF290\uF291\uF292\uF293\uF294\uF295\uF296"+ + "\uF297\uF298\uF299\uF29A\uF29B\uF29C\uF29D\uF29E"+ + "\uF29F\uF2A0\uF340\uF341\uF342\uF343\uF344\uF345"+ + "\uF346\uF347\uF348\uF349\uF34A\uF34B\uF34C\uF34D"+ + "\uF34E\uF34F\uF350\uF351\uC2ED\uD4A6\uCDD4\uD1B1"+ + "\uB3DB\uC7FD\uF352\uB2B5\uC2BF\uE6E0\uCABB\uE6E1"+ + "\uE6E2\uBED4\uE6E3\uD7A4\uCDD5\uE6E5\uBCDD\uE6E4"+ + "\uE6E6\uE6E7\uC2EE\uF353\uBDBE\uE6E8\uC2E6\uBAA7"+ + "\uE6E9\uF354\uE6EA\uB3D2\uD1E9\uF355\uF356\uBFA5"+ + "\uE6EB\uC6EF\uE6EC\uE6ED\uF357\uF358\uE6EE\uC6AD"+ + "\uE6EF\uF359\uC9A7\uE6F0\uE6F1\uE6F2\uE5B9\uE6F3"+ + "\uE6F4\uC2E2\uE6F5\uE6F6\uD6E8\uE6F7\uF35A\uE6F8"+ + "\uB9C7\uF35B\uF35C\uF35D\uF35E\uF35F\uF360\uF361"+ + "\uF7BB\uF7BA\uF362\uF363\uF364\uF365\uF7BE\uF7BC"+ + "\uBAA1\uF366\uF7BF\uF367\uF7C0\uF368\uF369\uF36A"+ + "\uF7C2\uF7C1\uF7C4\uF36B\uF36C\uF7C3\uF36D\uF36E"+ + "\uF36F\uF370\uF371\uF7C5\uF7C6\uF372\uF373\uF374"+ + "\uF375\uF7C7\uF376\uCBE8\uF377\uF378\uF379\uF37A"+ + "\uB8DF\uF37B\uF37C\uF37D\uF37E\uF380\uF381\uF7D4"+ + "\uF382\uF7D5\uF383\uF384\uF385\uF386\uF7D6\uF387"+ + "\uF388\uF389\uF38A\uF7D8\uF38B\uF7DA\uF38C\uF7D7"+ + "\uF38D\uF38E\uF38F\uF390\uF391\uF392\uF393\uF394"+ + "\uF395\uF7DB\uF396\uF7D9\uF397\uF398\uF399\uF39A"+ + "\uF39B\uF39C\uF39D\uD7D7\uF39E\uF39F\uF3A0\uF440"+ + "\uF7DC\uF441\uF442\uF443\uF444\uF445\uF446\uF7DD"+ + "\uF447\uF448\uF449\uF7DE\uF44A\uF44B\uF44C\uF44D"+ + "\uF44E\uF44F\uF450\uF451\uF452\uF453\uF454\uF7DF"+ + "\uF455\uF456\uF457\uF7E0\uF458\uF459\uF45A\uF45B"+ + "\uF45C\uF45D\uF45E\uF45F\uF460\uF461\uF462\uDBCB"+ + "\uF463\uF464\uD8AA\uF465\uF466\uF467\uF468\uF469"+ + "\uF46A\uF46B\uF46C\uE5F7\uB9ED\uF46D\uF46E\uF46F"+ + "\uF470\uBFFD\uBBEA\uF7C9\uC6C7\uF7C8\uF471\uF7CA"+ + "\uF7CC\uF7CB\uF472\uF473\uF474\uF7CD\uF475\uCEBA"+ + "\uF476\uF7CE\uF477\uF478\uC4A7\uF479\uF47A\uF47B"+ + "\uF47C\uF47D\uF47E\uF480\uF481\uF482\uF483\uF484"+ + "\uF485\uF486\uF487\uF488\uF489\uF48A\uF48B\uF48C"+ + "\uF48D\uF48E\uF48F\uF490\uF491\uF492\uF493\uF494"+ + "\uF495\uF496\uF497\uF498\uF499\uF49A\uF49B\uF49C"+ + "\uF49D\uF49E\uF49F\uF4A0\uF540\uF541\uF542\uF543"+ + "\uF544\uF545\uF546\uF547\uF548\uF549\uF54A\uF54B"+ + "\uF54C\uF54D\uF54E\uF54F\uF550\uF551\uF552\uF553"+ + "\uF554\uF555\uF556\uF557\uF558\uF559\uF55A\uF55B"+ + "\uF55C\uF55D\uF55E\uF55F\uF560\uF561\uF562\uF563"+ + "\uF564\uF565\uF566\uF567\uF568\uF569\uF56A\uF56B"+ + "\uF56C\uF56D\uF56E\uF56F\uF570\uF571\uF572\uF573"+ + "\uF574\uF575\uF576\uF577\uF578\uF579\uF57A\uF57B"+ + "\uF57C\uF57D\uF57E\uF580\uF581\uF582\uF583\uF584"+ + "\uF585\uF586\uF587\uF588\uF589\uF58A\uF58B\uF58C"+ + "\uF58D\uF58E\uF58F\uF590\uF591\uF592\uF593\uF594"+ + "\uF595\uF596\uF597\uF598\uF599\uF59A\uF59B\uF59C"+ + "\uF59D\uF59E\uF59F\uF5A0\uF640\uF641\uF642\uF643"+ + "\uF644\uF645\uF646\uF647\uF648\uF649\uF64A\uF64B"+ + "\uF64C\uF64D\uF64E\uF64F\uF650\uF651\uF652\uF653"+ + "\uF654\uF655\uF656\uF657\uF658\uF659\uF65A\uF65B"+ + "\uF65C\uF65D\uF65E\uF65F\uF660\uF661\uF662\uF663"+ + "\uF664\uF665\uF666\uF667\uF668\uF669\uF66A\uF66B"+ + "\uF66C\uF66D\uF66E\uF66F\uF670\uF671\uF672\uF673"+ + "\uF674\uF675\uF676\uF677\uF678\uF679\uF67A\uF67B"+ + "\uF67C\uF67D\uF67E\uF680\uF681\uF682\uF683\uF684"+ + "\uF685\uF686\uF687\uF688\uF689\uF68A\uF68B\uF68C"+ + "\uF68D\uF68E\uF68F\uF690\uF691\uF692\uF693\uF694"+ + "\uF695\uF696\uF697\uF698\uF699\uF69A\uF69B\uF69C"+ + "\uF69D\uF69E\uF69F\uF6A0\uF740\uF741\uF742\uF743"+ + "\uF744\uF745\uF746\uF747\uF748\uF749\uF74A\uF74B"+ + "\uF74C\uF74D\uF74E\uF74F\uF750\uF751\uF752\uF753"+ + "\uF754\uF755\uF756\uF757\uF758\uF759\uF75A\uF75B"+ + "\uF75C\uF75D\uF75E\uF75F\uF760\uF761\uF762\uF763"+ + "\uF764\uF765\uF766\uF767\uF768\uF769\uF76A\uF76B"+ + "\uF76C\uF76D\uF76E\uF76F\uF770\uF771\uF772\uF773"+ + "\uF774\uF775\uF776\uF777\uF778\uF779\uF77A\uF77B"+ + "\uF77C\uF77D\uF77E\uF780\uD3E3\uF781\uF782\uF6CF"+ + "\uF783\uC2B3\uF6D0\uF784\uF785\uF6D1\uF6D2\uF6D3"+ + "\uF6D4\uF786\uF787\uF6D6\uF788\uB1AB\uF6D7\uF789"+ + "\uF6D8\uF6D9\uF6DA\uF78A\uF6DB\uF6DC\uF78B\uF78C"+ + "\uF78D\uF78E\uF6DD\uF6DE\uCFCA\uF78F\uF6DF\uF6E0"+ + "\uF6E1\uF6E2\uF6E3\uF6E4\uC0F0\uF6E5\uF6E6\uF6E7"+ + "\uF6E8\uF6E9\uF790\uF6EA\uF791\uF6EB\uF6EC\uF792"+ + "\uF6ED\uF6EE\uF6EF\uF6F0\uF6F1\uF6F2\uF6F3\uF6F4"+ + "\uBEA8\uF793\uF6F5\uF6F6\uF6F7\uF6F8\uF794\uF795"+ + "\uF796\uF797\uF798\uC8FA\uF6F9\uF6FA\uF6FB\uF6FC"+ + "\uF799\uF79A\uF6FD\uF6FE\uF7A1\uF7A2\uF7A3\uF7A4"+ + "\uF7A5\uF79B\uF79C\uF7A6\uF7A7\uF7A8\uB1EE\uF7A9"+ + "\uF7AA\uF7AB\uF79D\uF79E\uF7AC\uF7AD\uC1DB\uF7AE"+ + "\uF79F\uF7A0\uF7AF\uF840\uF841\uF842\uF843\uF844"+ + "\uF845\uF846\uF847\uF848\uF849\uF84A\uF84B\uF84C"+ + "\uF84D\uF84E\uF84F\uF850\uF851\uF852\uF853\uF854"+ + "\uF855\uF856\uF857\uF858\uF859\uF85A\uF85B\uF85C"+ + "\uF85D\uF85E\uF85F\uF860\uF861\uF862\uF863\uF864"+ + "\uF865\uF866\uF867\uF868\uF869\uF86A\uF86B\uF86C"+ + "\uF86D\uF86E\uF86F\uF870\uF871\uF872\uF873\uF874"+ + "\uF875\uF876\uF877\uF878\uF879\uF87A\uF87B\uF87C"+ + "\uF87D\uF87E\uF880\uF881\uF882\uF883\uF884\uF885"+ + "\uF886\uF887\uF888\uF889\uF88A\uF88B\uF88C\uF88D"+ + "\uF88E\uF88F\uF890\uF891\uF892\uF893\uF894\uF895"+ + "\uF896\uF897\uF898\uF899\uF89A\uF89B\uF89C\uF89D"+ + "\uF89E\uF89F\uF8A0\uF940\uF941\uF942\uF943\uF944"+ + "\uF945\uF946\uF947\uF948\uF949\uF94A\uF94B\uF94C"+ + "\uF94D\uF94E\uF94F\uF950\uF951\uF952\uF953\uF954"+ + "\uF955\uF956\uF957\uF958\uF959\uF95A\uF95B\uF95C"+ + "\uF95D\uF95E\uF95F\uF960\uF961\uF962\uF963\uF964"+ + "\uF965\uF966\uF967\uF968\uF969\uF96A\uF96B\uF96C"+ + "\uF96D\uF96E\uF96F\uF970\uF971\uF972\uF973\uF974"+ + "\uF975\uF976\uF977\uF978\uF979\uF97A\uF97B\uF97C"+ + "\uF97D\uF97E\uF980\uF981\uF982\uF983\uF984\uF985"+ + "\uF986\uF987\uF988\uF989\uF98A\uF98B\uF98C\uF98D"+ + "\uF98E\uF98F\uF990\uF991\uF992\uF993\uF994\uF995"+ + "\uF996\uF997\uF998\uF999\uF99A\uF99B\uF99C\uF99D"+ + "\uF99E\uF99F\uF9A0\uFA40\uFA41\uFA42\uFA43\uFA44"+ + "\uFA45\uFA46\uFA47\uFA48\uFA49\uFA4A\uFA4B\uFA4C"+ + "\uFA4D\uFA4E\uFA4F\uFA50\uFA51\uFA52\uFA53\uFA54"+ + "\uFA55\uFA56\uFA57\uFA58\uFA59\uFA5A\uFA5B\uFA5C"+ + "\uFA5D\uFA5E\uFA5F\uFA60\uFA61\uFA62\uFA63\uFA64"+ + "\uFA65\uFA66\uFA67\uFA68\uFA69\uFA6A\uFA6B\uFA6C"+ + "\uFA6D\uFA6E\uFA6F\uFA70\uFA71\uFA72\uFA73\uFA74"+ + "\uFA75\uFA76\uFA77\uFA78\uFA79\uFA7A\uFA7B\uFA7C"+ + "\uFA7D\uFA7E\uFA80\uFA81\uFA82\uFA83\uFA84\uFA85"+ + "\uFA86\uFA87\uFA88\uFA89\uFA8A\uFA8B\uFA8C\uFA8D"+ + "\uFA8E\uFA8F\uFA90\uFA91\uFA92\uFA93\uFA94\uFA95"+ + "\uFA96\uFA97\uFA98\uFA99\uFA9A\uFA9B\uFA9C\uFA9D"+ + "\uFA9E\uFA9F\uFAA0\uFB40\uFB41\uFB42\uFB43\uFB44"+ + "\uFB45\uFB46\uFB47\uFB48\uFB49\uFB4A\uFB4B\uFB4C"+ + "\uFB4D\uFB4E\uFB4F\uFB50\uFB51\uFB52\uFB53\uFB54"+ + "\uFB55\uFB56\uFB57\uFB58\uFB59\uFB5A\uFB5B\uC4F1"+ + "\uF0AF\uBCA6\uF0B0\uC3F9\uFB5C\uC5B8\uD1BB\uFB5D"+ + "\uF0B1\uF0B2\uF0B3\uF0B4\uF0B5\uD1BC\uFB5E\uD1EC"+ + "\uFB5F\uF0B7\uF0B6\uD4A7\uFB60\uCDD2\uF0B8\uF0BA"+ + "\uF0B9\uF0BB\uF0BC\uFB61\uFB62\uB8EB\uF0BD\uBAE8"+ + "\uFB63\uF0BE\uF0BF\uBEE9\uF0C0\uB6EC\uF0C1\uF0C2"+ + "\uF0C3\uF0C4\uC8B5\uF0C5\uF0C6\uFB64\uF0C7\uC5F4"+ + "\uFB65\uF0C8\uFB66\uFB67\uFB68\uF0C9\uFB69\uF0CA"+ + "\uF7BD\uFB6A\uF0CB\uF0CC\uF0CD\uFB6B\uF0CE\uFB6C"+ + "\uFB6D\uFB6E\uFB6F\uF0CF\uBAD7\uFB70\uF0D0\uF0D1"+ + "\uF0D2\uF0D3\uF0D4\uF0D5\uF0D6\uF0D8\uFB71\uFB72"+ + "\uD3A5\uF0D7\uFB73\uF0D9\uFB74\uFB75\uFB76\uFB77"+ + "\uFB78\uFB79\uFB7A\uFB7B\uFB7C\uFB7D\uF5BA\uC2B9"+ + "\uFB7E\uFB80\uF7E4\uFB81\uFB82\uFB83\uFB84\uF7E5"+ + "\uF7E6\uFB85\uFB86\uF7E7\uFB87\uFB88\uFB89\uFB8A"+ + "\uFB8B\uFB8C\uF7E8\uC2B4\uFB8D\uFB8E\uFB8F\uFB90"+ + "\uFB91\uFB92\uFB93\uFB94\uFB95\uF7EA\uFB96\uF7EB"+ + "\uFB97\uFB98\uFB99\uFB9A\uFB9B\uFB9C\uC2F3\uFB9D"+ + "\uFB9E\uFB9F\uFBA0\uFC40\uFC41\uFC42\uFC43\uFC44"+ + "\uFC45\uFC46\uFC47\uFC48\uF4F0\uFC49\uFC4A\uFC4B"+ + "\uF4EF\uFC4C\uFC4D\uC2E9\uFC4E\uF7E1\uF7E2\uFC4F"+ + "\uFC50\uFC51\uFC52\uFC53\uBBC6\uFC54\uFC55\uFC56"+ + "\uFC57\uD9E4\uFC58\uFC59\uFC5A\uCAF2\uC0E8\uF0A4"+ + "\uFC5B\uBADA\uFC5C\uFC5D\uC7AD\uFC5E\uFC5F\uFC60"+ + "\uC4AC\uFC61\uFC62\uF7EC\uF7ED\uF7EE\uFC63\uF7F0"+ + "\uF7EF\uFC64\uF7F1\uFC65\uFC66\uF7F4\uFC67\uF7F3"+ + "\uFC68\uF7F2\uF7F5\uFC69\uFC6A\uFC6B\uFC6C\uF7F6"+ + "\uFC6D\uFC6E\uFC6F\uFC70\uFC71\uFC72\uFC73\uFC74"+ + "\uFC75\uEDE9\uFC76\uEDEA\uEDEB\uFC77\uF6BC\uFC78"+ + "\uFC79\uFC7A\uFC7B\uFC7C\uFC7D\uFC7E\uFC80\uFC81"+ + "\uFC82\uFC83\uFC84\uF6BD\uFC85\uF6BE\uB6A6\uFC86"+ + "\uD8BE\uFC87\uFC88\uB9C4\uFC89\uFC8A\uFC8B\uD8BB"+ + "\uFC8C\uDCB1\uFC8D\uFC8E\uFC8F\uFC90\uFC91\uFC92"+ + "\uCAF3\uFC93\uF7F7\uFC94\uFC95\uFC96\uFC97\uFC98"+ + "\uFC99\uFC9A\uFC9B\uFC9C\uF7F8\uFC9D\uFC9E\uF7F9"+ + "\uFC9F\uFCA0\uFD40\uFD41\uFD42\uFD43\uFD44\uF7FB"+ + "\uFD45\uF7FA\uFD46\uB1C7\uFD47\uF7FC\uF7FD\uFD48"+ + "\uFD49\uFD4A\uFD4B\uFD4C\uF7FE\uFD4D\uFD4E\uFD4F"+ + "\uFD50\uFD51\uFD52\uFD53\uFD54\uFD55\uFD56\uFD57"+ + "\uC6EB\uECB4\uFD58\uFD59\uFD5A\uFD5B\uFD5C\uFD5D"+ + "\uFD5E\uFD5F\uFD60\uFD61\uFD62\uFD63\uFD64\uFD65"+ + "\uFD66\uFD67\uFD68\uFD69\uFD6A\uFD6B\uFD6C\uFD6D"+ + "\uFD6E\uFD6F\uFD70\uFD71\uFD72\uFD73\uFD74\uFD75"+ + "\uFD76\uFD77\uFD78\uFD79\uFD7A\uFD7B\uFD7C\uFD7D"+ + "\uFD7E\uFD80\uFD81\uFD82\uFD83\uFD84\uFD85\uB3DD"+ + "\uF6B3\uFD86\uFD87\uF6B4\uC1E4\uF6B5\uF6B6\uF6B7"+ + "\uF6B8\uF6B9\uF6BA\uC8A3\uF6BB\uFD88\uFD89\uFD8A"+ + "\uFD8B\uFD8C\uFD8D\uFD8E\uFD8F\uFD90\uFD91\uFD92"+ + "\uFD93\uC1FA\uB9A8\uEDE8\uFD94\uFD95\uFD96\uB9EA"+ + "\uD9DF\uFD97\uFD98\uFD99\uFD9A\uFD9B\u6A63\u6A64"+ + "\u6A65\u6A66\u6A67\u6A68\u6A69\u6A6A\u6A6B\u6A6C"+ + (IS_2000 ? "\u6A6D\u6A6E\u6A6F\u6A70\u6A71\u6A72\u6A73\u6A74"+ + "\u6A75\u6A76\u6A77\u6A78\u6A79\u6A7A\u6A7B\u6A7C" : + "\u6A6D\u6A6E\u6A6F\u6A70\uFE59\uFE61\uFE66\uFE67"+ + "\uFE6D\uFE7E\uFE90\uFEA0\u6A79\u6A7A\u6A7B\u6A7C")+ + "\u6A7D\u6A7E\u6A7F\u6A80\u6A81\u6A82\u6A83\u6A84"+ + "\u6A85\u6A86\u6A87\u6A88\u6A89\u6A8A\u6A8B\u6A8C"+ + "\u6A8D\u6A8E\u6A8F\u6A90\u6A91\u6A92\u6A93\u6A94"+ + "\u6A95\u6A96\u6A97\u6A98\u6A99\u6A9A\u6A9B\u6A9C"+ + "\u6A9D\u6A9E\u6A9F\u6AA0\u6AA1\u6AA2\u6AA3\u6AA4"+ + "\u6AA5\u6AA6\u6AA7\u6AA8\u6AA9\u6AAA\u6AAB\u6AAC"+ + "\u6AAD\u6AAE\u6AAF\u6AB0\u6AB1\u6AB2\u6AB3\u6AB4"+ + "\u6AB5\u6AB6\u6AB7\u6AB8\u6AB9\u6ABA\u6ABB\u6ABC"; + + private static final String innerEncoderIndex10= + "\u6ABD\u6ABE\u6ABF\u6AC0\u6AC1\u6AC2\u6AC3\u6AC4"+ + "\u6AC5\u6AC6\u6AC7\u6AC8\u6AC9\u6ACA\u6ACB\u6ACC"+ + "\u6ACD\u6ACE\u6ACF\u6AD0\u6AD1\u6AD2\u6AD3\u6AD4"+ + "\u6AD5\u6AD6\u6AD7\u6AD8\u6AD9\u6ADA\u6ADB\u6ADC"+ + "\u6ADD\u6ADE\u6ADF\u6AE0\u6AE1\u6AE2\u6AE3\u6AE4"+ + "\u6AE5\u6AE6\u6AE7\u6AE8\u6AE9\u6AEA\u6AEB\u6AEC"+ + "\u6AED\u6AEE\u6AEF\u6AF0\u6AF1\u6AF2\u6AF3\u6AF4"+ + "\u6AF5\u6AF6\u6AF7\u6AF8\u6AF9\u6AFA\u6AFB\u6AFC"+ + "\u6AFD\u6AFE\u6AFF\u6B00\u6B01\u6B02\u6B03\u6B04"+ + "\u6B05\u6B06\u6B07\u6B08\u6B09\u6B0A\u6B0B\u6B0C"+ + "\u6B0D\u6B0E\u6B0F\u6B10\u6B11\u6B12\u6B13\u6B14"+ + "\u6B15\u6B16\u6B17\u6B18\u6B19\u6B1A\u6B1B\u6B1C"+ + "\u6B1D\u6B1E\u6B1F\u6B20\u6B21\u6B22\u6B23\u6B24"+ + "\u6B25\u6B26\u6B27\u6B28\u6B29\u6B2A\u6B2B\u6B2C"+ + "\u6B2D\u6B2E\u6B2F\u6B30\u6B31\u6B32\u6B33\u6B34"+ + "\u6B35\u6B36\u6B37\u6B38\u6B39\u6B3A\u6B3B\u6B3C"+ + "\u6B3D\u6B3E\u6B3F\u6B40\u6B41\u6B42\u6B43\u6B44"+ + "\u6B45\u6B46\u6B47\u6B48\u6B49\u6B4A\u6B4B\u6B4C"+ + "\u6B4D\u6B4E\u6B4F\u6B50\u6B51\u6B52\u6B53\u6B54"+ + "\u6B55\u6B56\u6B57\u6B58\u6B59\u6B5A\u6B5B\u6B5C"+ + "\u6B5D\u6B5E\u6B5F\u6B60\u6B61\u6B62\u6B63\u6B64"+ + "\u6B65\u6B66\u6B67\u6B68\u6B69\u6B6A\u6B6B\u6B6C"+ + "\u6B6D\u6B6E\u6B6F\u6B70\u6B71\u6B72\u6B73\u6B74"+ + "\u6B75\u6B76\u6B77\u6B78\u6B79\u6B7A\u6B7B\u6B7C"+ + "\u6B7D\u6B7E\u6B7F\u6B80\u6B81\u6B82\u6B83\u6B84"+ + "\u6B85\u6B86\u6B87\u6B88\u6B89\u6B8A\u6B8B\u6B8C"+ + "\u6B8D\u6B8E\u6B8F\u6B90\u6B91\u6B92\u6B93\u6B94"+ + "\u6B95\u6B96\u6B97\u6B98\u6B99\u6B9A\u6B9B\u6B9C"+ + "\u6B9D\u6B9E\u6B9F\u6BA0\u6BA1\u6BA2\u6BA3\u6BA4"+ + "\u6BA5\u6BA6\u6BA7\u6BA8\u6BA9\u6BAA\u6BAB\u6BAC"+ + "\u6BAD\u6BAE\u6BAF\u6BB0\u6BB1\u6BB2\u6BB3\u6BB4"+ + "\u6BB5\u6BB6\u6BB7\u6BB8\u6BB9\u6BBA\u6BBB\u6BBC"+ + "\u6BBD\u6BBE\u6BBF\u6BC0\u6BC1\u6BC2\u6BC3\u6BC4"+ + "\u6BC5\u6BC6\u6BC7\u6BC8\u6BC9\u6BCA\u6BCB\u6BCC"+ + "\u6BCD\u6BCE\u6BCF\u6BD0\u6BD1\u6BD2\u6BD3\u6BD4"+ + "\u6BD5\u6BD6\u6BD7\u6BD8\u6BD9\u6BDA\u6BDB\u6BDC"+ + "\u6BDD\u6BDE\u6BDF\u6BE0\u6BE1\u6BE2\u6BE3\u6BE4"+ + "\u6BE5\u6BE6\u6BE7\u6BE8\u6BE9\u6BEA\u6BEB\u6BEC"+ + "\u6BED\u6BEE\u6BEF\u6BF0\u6BF1\u6BF2\u6BF3\u6BF4"+ + "\u6BF5\u6BF6\u6BF7\u6BF8\u6BF9\u6BFA\u6BFB\u6BFC"+ + "\u6BFD\u6BFE\u6BFF\u6C00\u6C01\u6C02\u6C03\u6C04"+ + "\u6C05\u6C06\u6C07\u6C08\u6C09\u6C0A\u6C0B\u6C0C"+ + "\u6C0D\u6C0E\u6C0F\u6C10\u6C11\u6C12\u6C13\u6C14"+ + "\u6C15\u6C16\u6C17\u6C18\u6C19\u6C1A\u6C1B\u6C1C"+ + "\u6C1D\u6C1E\u6C1F\u6C20\u6C21\u6C22\u6C23\u6C24"+ + "\u6C25\u6C26\u6C27\u6C28\u6C29\u6C2A\u6C2B\u6C2C"+ + "\u6C2D\u6C2E\u6C2F\u6C30\u6C31\u6C32\u6C33\u6C34"+ + "\u6C35\u6C36\u6C37\u6C38\u6C39\u6C3A\u6C3B\u6C3C"+ + "\u6C3D\u6C3E\u6C3F\u6C40\u6C41\u6C42\u6C43\u6C44"+ + "\u6C45\u6C46\u6C47\u6C48\u6C49\u6C4A\u6C4B\u6C4C"+ + "\u6C4D\u6C4E\u6C4F\u6C50\u6C51\u6C52\u6C53\u6C54"+ + "\u6C55\u6C56\u6C57\u6C58\u6C59\u6C5A\u6C5B\u6C5C"+ + "\u6C5D\u6C5E\u6C5F\u6C60\u6C61\u6C62\u6C63\u6C64"+ + "\u6C65\u6C66\u6C67\u6C68\u6C69\u6C6A\u6C6B\u6C6C"+ + "\u6C6D\u6C6E\u6C6F\u6C70\u6C71\u6C72\u6C73\u6C74"+ + "\u6C75\u6C76\u6C77\u6C78\u6C79\u6C7A\u6C7B\u6C7C"+ + "\u6C7D\u6C7E\u6C7F\u6C80\u6C81\u6C82\u6C83\u6C84"+ + "\u6C85\u6C86\u6C87\u6C88\u6C89\u6C8A\u6C8B\u6C8C"+ + "\u6C8D\u6C8E\u6C8F\u6C90\u6C91\u6C92\u6C93\u6C94"+ + "\u6C95\u6C96\u6C97\u6C98\u6C99\u6C9A\u6C9B\u6C9C"+ + "\u6C9D\u6C9E\u6C9F\u6CA0\u6CA1\u6CA2\u6CA3\u6CA4"+ + "\u6CA5\u6CA6\u6CA7\u6CA8\u6CA9\u6CAA\u6CAB\u6CAC"+ + "\u6CAD\u6CAE\u6CAF\u6CB0\u6CB1\u6CB2\u6CB3\u6CB4"+ + "\u6CB5\u6CB6\u6CB7\u6CB8\u6CB9\u6CBA\u6CBB\u6CBC"+ + "\u6CBD\u6CBE\u6CBF\u6CC0\u6CC1\u6CC2\u6CC3\u6CC4"+ + "\u6CC5\u6CC6\u6CC7\u6CC8\u6CC9\u6CCA\u6CCB\u6CCC"+ + "\u6CCD\u6CCE\u6CCF\u6CD0\u6CD1\u6CD2\u6CD3\u6CD4"+ + "\u6CD5\u6CD6\u6CD7\u6CD8\u6CD9\u6CDA\u6CDB\u6CDC"+ + "\u6CDD\u6CDE\u6CDF\u6CE0\u6CE1\u6CE2\u6CE3\u6CE4"+ + "\u6CE5\u6CE6\u6CE7\u6CE8\u6CE9\u6CEA\u6CEB\u6CEC"+ + "\u6CED\u6CEE\u6CEF\u6CF0\u6CF1\u6CF2\u6CF3\u6CF4"+ + "\u6CF5\u6CF6\u6CF7\u6CF8\u6CF9\u6CFA\u6CFB\u6CFC"+ + "\u6CFD\u6CFE\u6CFF\u6D00\u6D01\u6D02\u6D03\u6D04"+ + "\u6D05\u6D06\u6D07\u6D08\u6D09\u6D0A\u6D0B\u6D0C"+ + "\u6D0D\u6D0E\u6D0F\u6D10\u6D11\u6D12\u6D13\u6D14"+ + "\u6D15\u6D16\u6D17\u6D18\u6D19\u6D1A\u6D1B\u6D1C"+ + "\u6D1D\u6D1E\u6D1F\u6D20\u6D21\u6D22\u6D23\u6D24"+ + "\u6D25\u6D26\u6D27\u6D28\u6D29\u6D2A\u6D2B\u6D2C"+ + "\u6D2D\u6D2E\u6D2F\u6D30\u6D31\u6D32\u6D33\u6D34"+ + "\u6D35\u6D36\u6D37\u6D38\u6D39\u6D3A\u6D3B\u6D3C"+ + "\u6D3D\u6D3E\u6D3F\u6D40\u6D41\u6D42\u6D43\u6D44"+ + "\u6D45\u6D46\u6D47\u6D48\u6D49\u6D4A\u6D4B\u6D4C"+ + "\u6D4D\u6D4E\u6D4F\u6D50\u6D51\u6D52\u6D53\u6D54"+ + "\u6D55\u6D56\u6D57\u6D58\u6D59\u6D5A\u6D5B\u6D5C"+ + "\u6D5D\u6D5E\u6D5F\u6D60\u6D61\u6D62\u6D63\u6D64"+ + "\u6D65\u6D66\u6D67\u6D68\u6D69\u6D6A\u6D6B\u6D6C"+ + "\u6D6D\u6D6E\u6D6F\u6D70\u6D71\u6D72\u6D73\u6D74"+ + "\u6D75\u6D76\u6D77\u6D78\u6D79\u6D7A\u6D7B\u6D7C"+ + "\u6D7D\u6D7E\u6D7F\u6D80\u6D81\u6D82\u6D83\u6D84"+ + "\u6D85\u6D86\u6D87\u6D88\u6D89\u6D8A\u6D8B\u6D8C"+ + "\u6D8D\u6D8E\u6D8F\u6D90\u6D91\u6D92\u6D93\u6D94"+ + "\u6D95\u6D96\u6D97\u6D98\u6D99\u6D9A\u6D9B\u6D9C"+ + "\u6D9D\u6D9E\u6D9F\u6DA0\u6DA1\u6DA2\u6DA3\u6DA4"+ + "\u6DA5\u6DA6\u6DA7\u6DA8\u6DA9\u6DAA\u6DAB\u6DAC"+ + "\u6DAD\u6DAE\u6DAF\u6DB0\u6DB1\u6DB2\u6DB3\u6DB4"+ + "\u6DB5\u6DB6\u6DB7\u6DB8\u6DB9\u6DBA\u6DBB\u6DBC"+ + "\u6DBD\u6DBE\u6DBF\u6DC0\u6DC1\u6DC2\u6DC3\u6DC4"+ + "\u6DC5\u6DC6\u6DC7\u6DC8\u6DC9\u6DCA\u6DCB\u6DCC"+ + "\u6DCD\u6DCE\u6DCF\u6DD0\u6DD1\u6DD2\u6DD3\u6DD4"+ + "\u6DD5\u6DD6\u6DD7\u6DD8\u6DD9\u6DDA\u6DDB\u6DDC"+ + "\u6DDD\u6DDE\u6DDF\u6DE0\u6DE1\u6DE2\u6DE3\u6DE4"+ + "\u6DE5\u6DE6\u6DE7\u6DE8\u6DE9\u6DEA\u6DEB\u6DEC"+ + "\u6DED\u6DEE\u6DEF\u6DF0\u6DF1\u6DF2\u6DF3\u6DF4"+ + "\u6DF5\u6DF6\u6DF7\u6DF8\u6DF9\u6DFA\u6DFB\u6DFC"+ + "\u6DFD\u6DFE\u6DFF\u6E00\u6E01\u6E02\u6E03\u6E04"+ + "\u6E05\u6E06\u6E07\u6E08\u6E09\u6E0A\u6E0B\u6E0C"+ + "\u6E0D\u6E0E\u6E0F\u6E10\u6E11\u6E12\u6E13\u6E14"+ + "\u6E15\u6E16\u6E17\u6E18\u6E19\u6E1A\u6E1B\u6E1C"+ + "\u6E1D\u6E1E\u6E1F\u6E20\u6E21\u6E22\u6E23\u6E24"+ + "\u6E25\u6E26\u6E27\u6E28\u6E29\u6E2A\u6E2B\u6E2C"+ + "\u6E2D\u6E2E\u6E2F\u6E30\u6E31\u6E32\u6E33\u6E34"+ + "\u6E35\u6E36\u6E37\u6E38\u6E39\u6E3A\u6E3B\u6E3C"+ + "\u6E3D\u6E3E\u6E3F\u6E40\u6E41\u6E42\u6E43\u6E44"+ + "\u6E45\u6E46\u6E47\u6E48\u6E49\u6E4A\u6E4B\u6E4C"+ + "\u6E4D\u6E4E\u6E4F\u6E50\u6E51\u6E52\u6E53\u6E54"+ + "\u6E55\u6E56\u6E57\u6E58\u6E59\u6E5A\u6E5B\u6E5C"+ + "\u6E5D\u6E5E\u6E5F\u6E60\u6E61\u6E62\u6E63\u6E64"+ + "\u6E65\u6E66\u6E67\u6E68\u6E69\u6E6A\u6E6B\u6E6C"+ + "\u6E6D\u6E6E\u6E6F\u6E70\u6E71\u6E72\u6E73\u6E74"+ + "\u6E75\u6E76\u6E77\u6E78\u6E79\u6E7A\u6E7B\u6E7C"+ + "\u6E7D\u6E7E\u6E7F\u6E80\u6E81\u6E82\u6E83\u6E84"+ + "\u6E85\u6E86\u6E87\u6E88\u6E89\u6E8A\u6E8B\u6E8C"+ + "\u6E8D\u6E8E\u6E8F\u6E90\u6E91\u6E92\u6E93\u6E94"+ + "\u6E95\u6E96\u6E97\u6E98\u6E99\u6E9A\u6E9B\u6E9C"+ + "\u6E9D\u6E9E\u6E9F\u6EA0\u6EA1\u6EA2\u6EA3\u6EA4"+ + "\u6EA5\u6EA6\u6EA7\u6EA8\u6EA9\u6EAA\u6EAB\u6EAC"+ + "\u6EAD\u6EAE\u6EAF\u6EB0\u6EB1\u6EB2\u6EB3\u6EB4"+ + "\u6EB5\u6EB6\u6EB7\u6EB8\u6EB9\u6EBA\u6EBB\u6EBC"+ + "\u6EBD\u6EBE\u6EBF\u6EC0\u6EC1\u6EC2\u6EC3\u6EC4"+ + "\u6EC5\u6EC6\u6EC7\u6EC8\u6EC9\u6ECA\u6ECB\u6ECC"+ + "\u6ECD\u6ECE\u6ECF\u6ED0\u6ED1\u6ED2\u6ED3\u6ED4"+ + "\u6ED5\u6ED6\u6ED7\u6ED8\u6ED9\u6EDA\u6EDB\u6EDC"+ + "\u6EDD\u6EDE\u6EDF\u6EE0\u6EE1\u6EE2\u6EE3\u6EE4"+ + "\u6EE5\u6EE6\u6EE7\u6EE8\u6EE9\u6EEA\u6EEB\u6EEC"+ + "\u6EED\u6EEE\u6EEF\u6EF0\u6EF1\u6EF2\u6EF3\u6EF4"+ + "\u6EF5\u6EF6\u6EF7\u6EF8\u6EF9\u6EFA\u6EFB\u6EFC"+ + "\u6EFD\u6EFE\u6EFF\u6F00\u6F01\u6F02\u6F03\u6F04"+ + "\u6F05\u6F06\u6F07\u6F08\u6F09\u6F0A\u6F0B\u6F0C"+ + "\u6F0D\u6F0E\u6F0F\u6F10\u6F11\u6F12\u6F13\u6F14"+ + "\u6F15\u6F16\u6F17\u6F18\u6F19\u6F1A\u6F1B\u6F1C"+ + "\u6F1D\u6F1E\u6F1F\u6F20\u6F21\u6F22\u6F23\u6F24"+ + "\u6F25\u6F26\u6F27\u6F28\u6F29\u6F2A\u6F2B\u6F2C"+ + "\u6F2D\u6F2E\u6F2F\u6F30\u6F31\u6F32\u6F33\u6F34"+ + "\u6F35\u6F36\u6F37\u6F38\u6F39\u6F3A\u6F3B\u6F3C"+ + "\u6F3D\u6F3E\u6F3F\u6F40\u6F41\u6F42\u6F43\u6F44"+ + "\u6F45\u6F46\u6F47\u6F48\u6F49\u6F4A\u6F4B\u6F4C"+ + "\u6F4D\u6F4E\u6F4F\u6F50\u6F51\u6F52\u6F53\u6F54"+ + "\u6F55\u6F56\u6F57\u6F58\u6F59\u6F5A\u6F5B\u6F5C"+ + "\u6F5D\u6F5E\u6F5F\u6F60\u6F61\u6F62\u6F63\u6F64"+ + "\u6F65\u6F66\u6F67\u6F68\u6F69\u6F6A\u6F6B\u6F6C"+ + "\u6F6D\u6F6E\u6F6F\u6F70\u6F71\u6F72\u6F73\u6F74"+ + "\u6F75\u6F76\u6F77\u6F78\u6F79\u6F7A\u6F7B\u6F7C"+ + "\u6F7D\u6F7E\u6F7F\u6F80\u6F81\u6F82\u6F83\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ + "\uAAA1\uAAA2\uAAA3\uAAA4\uAAA5\uAAA6\uAAA7\uAAA8"+ + "\uAAA9\uAAAA\uAAAB\uAAAC\uAAAD\uAAAE\uAAAF\uAAB0"+ + "\uAAB1\uAAB2\uAAB3\uAAB4\uAAB5\uAAB6\uAAB7\uAAB8"+ + "\uAAB9\uAABA\uAABB\uAABC\uAABD\uAABE\uAABF\uAAC0"+ + "\uAAC1\uAAC2\uAAC3\uAAC4\uAAC5\uAAC6\uAAC7\uAAC8"+ + "\uAAC9\uAACA\uAACB\uAACC\uAACD\uAACE\uAACF\uAAD0"+ + "\uAAD1\uAAD2\uAAD3\uAAD4\uAAD5\uAAD6\uAAD7\uAAD8"+ + "\uAAD9\uAADA\uAADB\uAADC\uAADD\uAADE\uAADF\uAAE0"+ + "\uAAE1\uAAE2\uAAE3\uAAE4\uAAE5\uAAE6\uAAE7\uAAE8"+ + "\uAAE9\uAAEA\uAAEB\uAAEC\uAAED\uAAEE\uAAEF\uAAF0"+ + "\uAAF1\uAAF2\uAAF3\uAAF4\uAAF5\uAAF6\uAAF7\uAAF8"+ + "\uAAF9\uAAFA\uAAFB\uAAFC\uAAFD\uAAFE\uABA1\uABA2"+ + "\uABA3\uABA4\uABA5\uABA6\uABA7\uABA8\uABA9\uABAA"+ + "\uABAB\uABAC\uABAD\uABAE\uABAF\uABB0\uABB1\uABB2"+ + "\uABB3\uABB4\uABB5\uABB6\uABB7\uABB8\uABB9\uABBA"+ + "\uABBB\uABBC\uABBD\uABBE\uABBF\uABC0\uABC1\uABC2"+ + "\uABC3\uABC4\uABC5\uABC6\uABC7\uABC8\uABC9\uABCA"+ + "\uABCB\uABCC\uABCD\uABCE\uABCF\uABD0\uABD1\uABD2"+ + "\uABD3\uABD4\uABD5\uABD6\uABD7\uABD8\uABD9\uABDA"+ + "\uABDB\uABDC\uABDD\uABDE\uABDF\uABE0\uABE1\uABE2"+ + "\uABE3\uABE4\uABE5\uABE6\uABE7\uABE8\uABE9\uABEA"+ + "\uABEB\uABEC\uABED\uABEE\uABEF\uABF0\uABF1\uABF2"+ + "\uABF3\uABF4\uABF5\uABF6\uABF7\uABF8\uABF9\uABFA"+ + "\uABFB\uABFC\uABFD\uABFE\uACA1\uACA2\uACA3\uACA4"+ + "\uACA5\uACA6\uACA7\uACA8\uACA9\uACAA\uACAB\uACAC"+ + "\uACAD\uACAE\uACAF\uACB0\uACB1\uACB2\uACB3\uACB4"+ + "\uACB5\uACB6\uACB7\uACB8\uACB9\uACBA\uACBB\uACBC"+ + "\uACBD\uACBE\uACBF\uACC0\uACC1\uACC2\uACC3\uACC4"+ + "\uACC5\uACC6\uACC7\uACC8\uACC9\uACCA\uACCB\uACCC"+ + "\uACCD\uACCE\uACCF\uACD0\uACD1\uACD2\uACD3\uACD4"+ + "\uACD5\uACD6\uACD7\uACD8\uACD9\uACDA\uACDB\uACDC"+ + "\uACDD\uACDE\uACDF\uACE0\uACE1\uACE2\uACE3\uACE4"+ + "\uACE5\uACE6\uACE7\uACE8\uACE9\uACEA\uACEB\uACEC"+ + "\uACED\uACEE\uACEF\uACF0\uACF1\uACF2\uACF3\uACF4"+ + "\uACF5\uACF6\uACF7\uACF8\uACF9\uACFA\uACFB\uACFC"+ + "\uACFD\uACFE\uADA1\uADA2\uADA3\uADA4\uADA5\uADA6"+ + "\uADA7\uADA8\uADA9\uADAA\uADAB\uADAC\uADAD\uADAE"+ + "\uADAF\uADB0\uADB1\uADB2\uADB3\uADB4\uADB5\uADB6"+ + "\uADB7\uADB8\uADB9\uADBA\uADBB\uADBC\uADBD\uADBE"+ + "\uADBF\uADC0\uADC1\uADC2\uADC3\uADC4\uADC5\uADC6"+ + "\uADC7\uADC8\uADC9\uADCA\uADCB\uADCC\uADCD\uADCE"+ + "\uADCF\uADD0\uADD1\uADD2\uADD3\uADD4\uADD5\uADD6"+ + "\uADD7\uADD8\uADD9\uADDA\uADDB\uADDC\uADDD\uADDE"+ + "\uADDF\uADE0\uADE1\uADE2\uADE3\uADE4\uADE5\uADE6"+ + "\uADE7\uADE8\uADE9\uADEA\uADEB\uADEC\uADED\uADEE"+ + "\uADEF\uADF0\uADF1\uADF2\uADF3\uADF4\uADF5\uADF6"+ + "\uADF7\uADF8\uADF9\uADFA\uADFB\uADFC\uADFD\uADFE"+ + "\uAEA1\uAEA2\uAEA3\uAEA4\uAEA5\uAEA6\uAEA7\uAEA8"+ + "\uAEA9\uAEAA\uAEAB\uAEAC\uAEAD\uAEAE\uAEAF\uAEB0"+ + "\uAEB1\uAEB2\uAEB3\uAEB4\uAEB5\uAEB6\uAEB7\uAEB8"+ + "\uAEB9\uAEBA\uAEBB\uAEBC\uAEBD\uAEBE\uAEBF\uAEC0"+ + "\uAEC1\uAEC2\uAEC3\uAEC4\uAEC5\uAEC6\uAEC7\uAEC8"+ + "\uAEC9\uAECA\uAECB\uAECC\uAECD\uAECE\uAECF\uAED0"+ + "\uAED1\uAED2\uAED3\uAED4\uAED5\uAED6\uAED7\uAED8"+ + "\uAED9\uAEDA\uAEDB\uAEDC\uAEDD\uAEDE\uAEDF\uAEE0"+ + "\uAEE1\uAEE2\uAEE3\uAEE4\uAEE5\uAEE6\uAEE7\uAEE8"+ + "\uAEE9\uAEEA\uAEEB\uAEEC\uAEED\uAEEE\uAEEF\uAEF0"+ + "\uAEF1\uAEF2\uAEF3\uAEF4\uAEF5\uAEF6\uAEF7\uAEF8"+ + "\uAEF9\uAEFA\uAEFB\uAEFC\uAEFD\uAEFE\uAFA1\uAFA2"+ + "\uAFA3\uAFA4\uAFA5\uAFA6\uAFA7\uAFA8\uAFA9\uAFAA"+ + "\uAFAB\uAFAC\uAFAD\uAFAE\uAFAF\uAFB0\uAFB1\uAFB2"+ + "\uAFB3\uAFB4\uAFB5\uAFB6\uAFB7\uAFB8\uAFB9\uAFBA"+ + "\uAFBB\uAFBC\uAFBD\uAFBE\uAFBF\uAFC0\uAFC1\uAFC2"+ + "\uAFC3\uAFC4\uAFC5\uAFC6\uAFC7\uAFC8\uAFC9\uAFCA"+ + "\uAFCB\uAFCC\uAFCD\uAFCE\uAFCF\uAFD0\uAFD1\uAFD2"+ + "\uAFD3\uAFD4\uAFD5\uAFD6\uAFD7\uAFD8\uAFD9\uAFDA"+ + "\uAFDB\uAFDC\uAFDD\uAFDE\uAFDF\uAFE0\uAFE1\uAFE2"+ + "\uAFE3\uAFE4\uAFE5\uAFE6\uAFE7\uAFE8\uAFE9\uAFEA"+ + "\uAFEB\uAFEC\uAFED\uAFEE\uAFEF\uAFF0\uAFF1\uAFF2"+ + "\uAFF3\uAFF4\uAFF5\uAFF6\uAFF7\uAFF8\uAFF9\uAFFA"+ + "\uAFFB\uAFFC\uAFFD\uAFFE\uF8A1\uF8A2\uF8A3\uF8A4"+ + "\uF8A5\uF8A6\uF8A7\uF8A8\uF8A9\uF8AA\uF8AB\uF8AC"+ + "\uF8AD\uF8AE\uF8AF\uF8B0\uF8B1\uF8B2\uF8B3\uF8B4"+ + "\uF8B5\uF8B6\uF8B7\uF8B8\uF8B9\uF8BA\uF8BB\uF8BC"+ + "\uF8BD\uF8BE\uF8BF\uF8C0\uF8C1\uF8C2\uF8C3\uF8C4"+ + "\uF8C5\uF8C6\uF8C7\uF8C8\uF8C9\uF8CA\uF8CB\uF8CC"+ + "\uF8CD\uF8CE\uF8CF\uF8D0\uF8D1\uF8D2\uF8D3\uF8D4"+ + "\uF8D5\uF8D6\uF8D7\uF8D8\uF8D9\uF8DA\uF8DB\uF8DC"+ + "\uF8DD\uF8DE\uF8DF\uF8E0\uF8E1\uF8E2\uF8E3\uF8E4"+ + "\uF8E5\uF8E6\uF8E7\uF8E8\uF8E9\uF8EA\uF8EB\uF8EC"+ + "\uF8ED\uF8EE\uF8EF\uF8F0\uF8F1\uF8F2\uF8F3\uF8F4"+ + "\uF8F5\uF8F6\uF8F7\uF8F8\uF8F9\uF8FA\uF8FB\uF8FC"+ + "\uF8FD\uF8FE\uF9A1\uF9A2\uF9A3\uF9A4\uF9A5\uF9A6"+ + "\uF9A7\uF9A8\uF9A9\uF9AA\uF9AB\uF9AC\uF9AD\uF9AE"+ + "\uF9AF\uF9B0\uF9B1\uF9B2\uF9B3\uF9B4\uF9B5\uF9B6"+ + "\uF9B7\uF9B8\uF9B9\uF9BA\uF9BB\uF9BC\uF9BD\uF9BE"+ + "\uF9BF\uF9C0\uF9C1\uF9C2\uF9C3\uF9C4\uF9C5\uF9C6"+ + "\uF9C7\uF9C8\uF9C9\uF9CA\uF9CB\uF9CC\uF9CD\uF9CE"+ + "\uF9CF\uF9D0\uF9D1\uF9D2\uF9D3\uF9D4\uF9D5\uF9D6"+ + "\uF9D7\uF9D8\uF9D9\uF9DA\uF9DB\uF9DC\uF9DD\uF9DE"+ + "\uF9DF\uF9E0\uF9E1\uF9E2\uF9E3\uF9E4\uF9E5\uF9E6"+ + "\uF9E7\uF9E8\uF9E9\uF9EA\uF9EB\uF9EC\uF9ED\uF9EE"+ + "\uF9EF\uF9F0\uF9F1\uF9F2\uF9F3\uF9F4\uF9F5\uF9F6"+ + "\uF9F7\uF9F8\uF9F9\uF9FA\uF9FB\uF9FC\uF9FD\uF9FE"+ + "\uFAA1\uFAA2\uFAA3\uFAA4\uFAA5\uFAA6\uFAA7\uFAA8"+ + "\uFAA9\uFAAA\uFAAB\uFAAC\uFAAD\uFAAE\uFAAF\uFAB0"+ + "\uFAB1\uFAB2\uFAB3\uFAB4\uFAB5\uFAB6\uFAB7\uFAB8"+ + "\uFAB9\uFABA\uFABB\uFABC\uFABD\uFABE\uFABF\uFAC0"+ + "\uFAC1\uFAC2\uFAC3\uFAC4\uFAC5\uFAC6\uFAC7\uFAC8"+ + "\uFAC9\uFACA\uFACB\uFACC\uFACD\uFACE\uFACF\uFAD0"+ + "\uFAD1\uFAD2\uFAD3\uFAD4\uFAD5\uFAD6\uFAD7\uFAD8"+ + "\uFAD9\uFADA\uFADB\uFADC\uFADD\uFADE\uFADF\uFAE0"+ + "\uFAE1\uFAE2\uFAE3\uFAE4\uFAE5\uFAE6\uFAE7\uFAE8"+ + "\uFAE9\uFAEA\uFAEB\uFAEC\uFAED\uFAEE\uFAEF\uFAF0"+ + "\uFAF1\uFAF2\uFAF3\uFAF4\uFAF5\uFAF6\uFAF7\uFAF8"+ + "\uFAF9\uFAFA\uFAFB\uFAFC\uFAFD\uFAFE\uFBA1\uFBA2"+ + "\uFBA3\uFBA4\uFBA5\uFBA6\uFBA7\uFBA8\uFBA9\uFBAA"+ + "\uFBAB\uFBAC\uFBAD\uFBAE\uFBAF\uFBB0\uFBB1\uFBB2"+ + "\uFBB3\uFBB4\uFBB5\uFBB6\uFBB7\uFBB8\uFBB9\uFBBA"+ + "\uFBBB\uFBBC\uFBBD\uFBBE\uFBBF\uFBC0\uFBC1\uFBC2"+ + "\uFBC3\uFBC4\uFBC5\uFBC6\uFBC7\uFBC8\uFBC9\uFBCA"+ + "\uFBCB\uFBCC\uFBCD\uFBCE\uFBCF\uFBD0\uFBD1\uFBD2"+ + "\uFBD3\uFBD4\uFBD5\uFBD6\uFBD7\uFBD8\uFBD9\uFBDA"+ + "\uFBDB\uFBDC\uFBDD\uFBDE\uFBDF\uFBE0\uFBE1\uFBE2"+ + "\uFBE3\uFBE4\uFBE5\uFBE6\uFBE7\uFBE8\uFBE9\uFBEA"+ + "\uFBEB\uFBEC\uFBED\uFBEE\uFBEF\uFBF0\uFBF1\uFBF2"+ + "\uFBF3\uFBF4\uFBF5\uFBF6\uFBF7\uFBF8\uFBF9\uFBFA"+ + "\uFBFB\uFBFC\uFBFD\uFBFE\uFCA1\uFCA2\uFCA3\uFCA4"+ + "\uFCA5\uFCA6\uFCA7\uFCA8\uFCA9\uFCAA\uFCAB\uFCAC"+ + "\uFCAD\uFCAE\uFCAF\uFCB0\uFCB1\uFCB2\uFCB3\uFCB4"+ + "\uFCB5\uFCB6\uFCB7\uFCB8\uFCB9\uFCBA\uFCBB\uFCBC"+ + "\uFCBD\uFCBE\uFCBF\uFCC0\uFCC1\uFCC2\uFCC3\uFCC4"+ + "\uFCC5\uFCC6\uFCC7\uFCC8\uFCC9\uFCCA\uFCCB\uFCCC"+ + "\uFCCD\uFCCE\uFCCF\uFCD0\uFCD1\uFCD2\uFCD3\uFCD4"+ + "\uFCD5\uFCD6\uFCD7\uFCD8\uFCD9\uFCDA\uFCDB\uFCDC"+ + "\uFCDD\uFCDE\uFCDF\uFCE0\uFCE1\uFCE2\uFCE3\uFCE4"+ + "\uFCE5\uFCE6\uFCE7\uFCE8\uFCE9\uFCEA\uFCEB\uFCEC"+ + "\uFCED\uFCEE\uFCEF\uFCF0\uFCF1\uFCF2\uFCF3\uFCF4"+ + "\uFCF5\uFCF6\uFCF7\uFCF8\uFCF9\uFCFA\uFCFB\uFCFC"+ + "\uFCFD\uFCFE\uFDA1\uFDA2\uFDA3\uFDA4\uFDA5\uFDA6"+ + "\uFDA7\uFDA8\uFDA9\uFDAA\uFDAB\uFDAC\uFDAD\uFDAE"+ + "\uFDAF\uFDB0\uFDB1\uFDB2\uFDB3\uFDB4\uFDB5\uFDB6"+ + "\uFDB7\uFDB8\uFDB9\uFDBA\uFDBB\uFDBC\uFDBD\uFDBE"+ + "\uFDBF\uFDC0\uFDC1\uFDC2\uFDC3\uFDC4\uFDC5\uFDC6"+ + "\uFDC7\uFDC8\uFDC9\uFDCA\uFDCB\uFDCC\uFDCD\uFDCE"+ + "\uFDCF\uFDD0\uFDD1\uFDD2\uFDD3\uFDD4\uFDD5\uFDD6"+ + "\uFDD7\uFDD8\uFDD9\uFDDA\uFDDB\uFDDC\uFDDD\uFDDE"+ + "\uFDDF\uFDE0\uFDE1\uFDE2\uFDE3\uFDE4\uFDE5\uFDE6"+ + "\uFDE7\uFDE8\uFDE9\uFDEA\uFDEB\uFDEC\uFDED\uFDEE"+ + "\uFDEF\uFDF0\uFDF1\uFDF2\uFDF3\uFDF4\uFDF5\uFDF6"+ + "\uFDF7\uFDF8\uFDF9\uFDFA\uFDFB\uFDFC\uFDFD\uFDFE"+ + "\uFEA1\uFEA2\uFEA3\uFEA4\uFEA5\uFEA6\uFEA7\uFEA8"+ + "\uFEA9\uFEAA\uFEAB\uFEAC\uFEAD\uFEAE\uFEAF\uFEB0"+ + "\uFEB1\uFEB2\uFEB3\uFEB4\uFEB5\uFEB6\uFEB7\uFEB8"+ + "\uFEB9\uFEBA\uFEBB\uFEBC\uFEBD\uFEBE\uFEBF\uFEC0"+ + "\uFEC1\uFEC2\uFEC3\uFEC4\uFEC5\uFEC6\uFEC7\uFEC8"+ + "\uFEC9\uFECA\uFECB\uFECC\uFECD\uFECE\uFECF\uFED0"+ + "\uFED1\uFED2\uFED3\uFED4\uFED5\uFED6\uFED7\uFED8"+ + "\uFED9\uFEDA\uFEDB\uFEDC\uFEDD\uFEDE\uFEDF\uFEE0"+ + "\uFEE1\uFEE2\uFEE3\uFEE4\uFEE5\uFEE6\uFEE7\uFEE8"+ + "\uFEE9\uFEEA\uFEEB\uFEEC\uFEED\uFEEE\uFEEF\uFEF0"+ + "\uFEF1\uFEF2\uFEF3\uFEF4\uFEF5\uFEF6\uFEF7\uFEF8"+ + "\uFEF9\uFEFA\uFEFB\uFEFC\uFEFD\uFEFE\uA140\uA141"+ + "\uA142\uA143\uA144\uA145\uA146\uA147\uA148\uA149"+ + "\uA14A\uA14B\uA14C\uA14D\uA14E\uA14F\uA150\uA151"+ + "\uA152\uA153\uA154\uA155\uA156\uA157\uA158\uA159"+ + "\uA15A\uA15B\uA15C\uA15D\uA15E\uA15F\uA160\uA161"+ + "\uA162\uA163\uA164\uA165\uA166\uA167\uA168\uA169"+ + "\uA16A\uA16B\uA16C\uA16D\uA16E\uA16F\uA170\uA171"+ + "\uA172\uA173\uA174\uA175\uA176\uA177\uA178\uA179"+ + "\uA17A\uA17B\uA17C\uA17D\uA17E\uA180\uA181\uA182"+ + "\uA183\uA184\uA185\uA186\uA187\uA188\uA189\uA18A"+ + "\uA18B\uA18C\uA18D\uA18E\uA18F\uA190\uA191\uA192"+ + "\uA193\uA194\uA195\uA196\uA197\uA198\uA199\uA19A"+ + "\uA19B\uA19C\uA19D\uA19E\uA19F\uA1A0\uA240\uA241"+ + "\uA242\uA243\uA244\uA245\uA246\uA247\uA248\uA249"+ + "\uA24A\uA24B\uA24C\uA24D\uA24E\uA24F\uA250\uA251"+ + "\uA252\uA253\uA254\uA255\uA256\uA257\uA258\uA259"+ + "\uA25A\uA25B\uA25C\uA25D\uA25E\uA25F\uA260\uA261"+ + "\uA262\uA263\uA264\uA265\uA266\uA267\uA268\uA269"+ + "\uA26A\uA26B\uA26C\uA26D\uA26E\uA26F\uA270\uA271"+ + "\uA272\uA273\uA274\uA275\uA276\uA277\uA278\uA279"+ + "\uA27A\uA27B\uA27C\uA27D\uA27E\uA280\uA281\uA282"+ + "\uA283\uA284\uA285\uA286\uA287\uA288\uA289\uA28A"+ + "\uA28B\uA28C\uA28D\uA28E\uA28F\uA290\uA291\uA292"+ + "\uA293\uA294\uA295\uA296\uA297\uA298\uA299\uA29A"+ + "\uA29B\uA29C\uA29D\uA29E\uA29F\uA2A0\uA340\uA341"+ + "\uA342\uA343\uA344\uA345\uA346\uA347\uA348\uA349"+ + "\uA34A\uA34B\uA34C\uA34D\uA34E\uA34F\uA350\uA351"+ + "\uA352\uA353\uA354\uA355\uA356\uA357\uA358\uA359"+ + "\uA35A\uA35B\uA35C\uA35D\uA35E\uA35F\uA360\uA361"+ + "\uA362\uA363\uA364\uA365\uA366\uA367\uA368\uA369"+ + "\uA36A\uA36B\uA36C\uA36D\uA36E\uA36F\uA370\uA371"+ + "\uA372\uA373\uA374\uA375\uA376\uA377\uA378\uA379"+ + "\uA37A\uA37B\uA37C\uA37D\uA37E\uA380\uA381\uA382"+ + "\uA383\uA384\uA385\uA386\uA387\uA388\uA389\uA38A"+ + "\uA38B\uA38C\uA38D\uA38E\uA38F\uA390\uA391\uA392"+ + "\uA393\uA394\uA395\uA396\uA397\uA398\uA399\uA39A"+ + "\uA39B\uA39C\uA39D\uA39E\uA39F\uA3A0\uA440\uA441"+ + "\uA442\uA443\uA444\uA445\uA446\uA447\uA448\uA449"+ + "\uA44A\uA44B\uA44C\uA44D\uA44E\uA44F\uA450\uA451"+ + "\uA452\uA453\uA454\uA455\uA456\uA457\uA458\uA459"+ + "\uA45A\uA45B\uA45C\uA45D\uA45E\uA45F\uA460\uA461"+ + "\uA462\uA463\uA464\uA465\uA466\uA467\uA468\uA469"+ + "\uA46A\uA46B\uA46C\uA46D\uA46E\uA46F\uA470\uA471"+ + "\uA472\uA473\uA474\uA475\uA476\uA477\uA478\uA479"+ + "\uA47A\uA47B\uA47C\uA47D\uA47E\uA480\uA481\uA482"+ + "\uA483\uA484\uA485\uA486\uA487\uA488\uA489\uA48A"+ + "\uA48B\uA48C\uA48D\uA48E\uA48F\uA490\uA491\uA492"+ + "\uA493\uA494\uA495\uA496\uA497\uA498\uA499\uA49A"+ + "\uA49B\uA49C\uA49D\uA49E\uA49F\uA4A0\uA540\uA541"+ + "\uA542\uA543\uA544\uA545\uA546\uA547\uA548\uA549"+ + "\uA54A\uA54B\uA54C\uA54D\uA54E\uA54F\uA550\uA551"+ + "\uA552\uA553\uA554\uA555\uA556\uA557\uA558\uA559"+ + "\uA55A\uA55B\uA55C\uA55D\uA55E\uA55F\uA560\uA561"+ + "\uA562\uA563\uA564\uA565\uA566\uA567\uA568\uA569"+ + "\uA56A\uA56B\uA56C\uA56D\uA56E\uA56F\uA570\uA571"+ + "\uA572\uA573\uA574\uA575\uA576\uA577\uA578\uA579"+ + "\uA57A\uA57B\uA57C\uA57D\uA57E\uA580\uA581\uA582"+ + "\uA583\uA584\uA585\uA586\uA587\uA588\uA589\uA58A"+ + "\uA58B\uA58C\uA58D\uA58E\uA58F\uA590\uA591\uA592"+ + "\uA593\uA594\uA595\uA596\uA597\uA598\uA599\uA59A"+ + "\uA59B\uA59C\uA59D\uA59E\uA59F\uA5A0\uA640\uA641"+ + "\uA642\uA643\uA644\uA645\uA646\uA647\uA648\uA649"+ + "\uA64A\uA64B\uA64C\uA64D\uA64E\uA64F\uA650\uA651"+ + "\uA652\uA653\uA654\uA655\uA656\uA657\uA658\uA659"+ + "\uA65A\uA65B\uA65C\uA65D\uA65E\uA65F\uA660\uA661"+ + "\uA662\uA663\uA664\uA665\uA666\uA667\uA668\uA669"+ + "\uA66A\uA66B\uA66C\uA66D\uA66E\uA66F\uA670\uA671"+ + "\uA672\uA673\uA674\uA675\uA676\uA677\uA678\uA679"+ + "\uA67A\uA67B\uA67C\uA67D\uA67E\uA680\uA681\uA682"+ + "\uA683\uA684\uA685\uA686\uA687\uA688\uA689\uA68A"+ + "\uA68B\uA68C\uA68D\uA68E\uA68F\uA690\uA691\uA692"+ + "\uA693\uA694\uA695\uA696\uA697\uA698\uA699\uA69A"+ + "\uA69B\uA69C\uA69D\uA69E\uA69F\uA6A0\uA740\uA741"+ + "\uA742\uA743\uA744\uA745\uA746\uA747\uA748\uA749"+ + "\uA74A\uA74B\uA74C\uA74D\uA74E\uA74F\uA750\uA751"+ + "\uA752\uA753\uA754\uA755\uA756\uA757\uA758\uA759"+ + "\uA75A\uA75B\uA75C\uA75D\uA75E\uA75F\uA760\uA761"+ + "\uA762\uA763\uA764\uA765\uA766\uA767\uA768\uA769"+ + "\uA76A\uA76B\uA76C\uA76D\uA76E\uA76F\uA770\uA771"+ + "\uA772\uA773\uA774\uA775\uA776\uA777\uA778\uA779"+ + "\uA77A\uA77B\uA77C\uA77D\uA77E\uA780\uA781\uA782"+ + "\uA783\uA784\uA785\uA786\uA787\uA788\uA789\uA78A"+ + "\uA78B\uA78C\uA78D\uA78E\uA78F\uA790\uA791\uA792"+ + "\uA793\uA794\uA795\uA796\uA797\uA798\uA799\uA79A"+ + "\uA79B\uA79C\uA79D\uA79E\uA79F\uA7A0\uA2AB\uA2AC"+ + "\uA2AD\uA2AE\uA2AF\uA2B0\u2000\uA2E4\uA2EF\uA2F0"+ + "\uA2FD\uA2FE\uA4F4\uA4F5\uA4F6\uA4F7\uA4F8\uA4F9"+ + "\uA4FA\uA4FB\uA4FC\uA4FD\uA4FE\uA5F7\uA5F8\uA5F9"+ + "\uA5FA\uA5FB\uA5FC\uA5FD\uA5FE\uA6B9\uA6BA\uA6BB"+ + (IS_2000 ? "\uA6BC\uA6BD\uA6BE\uA6BF\uA6C0\uA6D9\uA6DA\uA6DB"+ + "\uA6DC\uA6DD\uA6DE\uA6DF\uA6EC\uA6ED\uA6F3\uA6F6" : + "\uA6BC\uA6BD\uA6BE\uA6BF\uA6C0\u35E7\u35E9\u35E8"+ + "\u35EA\u35EB\u35EC\u35ED\u35EE\u35EF\u35F0\uA6F6")+ + "\uA6F7\uA6F8\uA6F9\uA6FA\uA6FB\uA6FC\uA6FD\uA6FE"+ + "\uA7C2\uA7C3\uA7C4\uA7C5\uA7C6\uA7C7\uA7C8\uA7C9"+ + "\uA7CA\uA7CB\uA7CC\uA7CD\uA7CE\uA7CF\uA7D0\uA7F2"+ + "\uA7F3\uA7F4\uA7F5\uA7F6\uA7F7\uA7F8\uA7F9\uA7FA"+ + "\uA7FB\uA7FC\uA7FD\uA7FE\uA896\uA897\uA898\uA899"+ + (IS_2000 ? "\uA89A\uA89B\uA89C\uA89D\uA89E\uA89F\uA8A0\uA8BC" : + "\uA89A\uA89B\uA89C\uA89D\uA89E\uA89F\uA8A0\u3D21")+ + "\u2001\uA8C1\uA8C2\uA8C3\uA8C4\uA8EA\uA8EB\uA8EC"+ + "\uA8ED\uA8EE\uA8EF\uA8F0\uA8F1\uA8F2\uA8F3\uA8F4"+ + "\uA8F5\uA8F6\uA8F7\uA8F8\uA8F9\uA8FA\uA8FB\uA8FC"+ + "\uA8FD\uA8FE\uA958\uA95B\uA95D\uA95E\uA95F\u2002"+ + "\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A"+ + "\u200B\u200C\u200D\u200E\uA997\uA998\uA999\uA99A"+ + "\uA99B\uA99C\uA99D\uA99E\uA99F\uA9A0\uA9A1\uA9A2"+ + "\uA9A3\uA9F0\uA9F1\uA9F2\uA9F3\uA9F4\uA9F5\uA9F6"+ + "\uA9F7\uA9F8\uA9F9\uA9FA\uA9FB\uA9FC\uA9FD\uA9FE"+ + "\uD7FA\uD7FB\uD7FC\uD7FD\uD7FE\u200F\uFE51\uFE52"+ + (IS_2000 ? "\uFE53\u2010\u2011\u2012\u2013\u2014\uFE59\u2015"+ + "\u2016\u2017\u2018\u2019\u201A\u201B\uFE61\u201C"+ + "\u201D\u201E\u201F\uFE66\uFE67\u2020\u2021\u2022"+ + "\u2023\uFE6C\uFE6D\u2024\u2025\u2026\u2027\u2028" : + "\uFE53\u2010\u2011\u2012\u2013\u2014\u6A71\u2015"+ + "\u2016\u2017\u2018\u2019\u201A\u201B\u6A72\u201C"+ + "\u201D\u201E\u201F\u6A73\u6A74\u2020\u2021\u2022"+ + "\u2023\uFE6C\u6A75\u2024\u2025\u2026\u2027\u2028")+ + "\u2029\u202A\u202B\uFE76\u202C\u202D\u202E\u202F"+ + (IS_2000 ? "\u2030\u2031\u2032\uFE7E\u2033\u2034\u2035\u2036" : + "\u2030\u2031\u2032\u6A76\u2033\u2034\u2035\u2036")+ + "\u2037\u2038\u2039\u203A\u203B\u203C\u203D\u203E"+ + (IS_2000 ? "\u203F\u2040\u2041\u2042\uFE90\uFE91\u2043\u2044" : + "\u203F\u2040\u2041\u2042\u6A77\uFE91\u2043\u2044")+ + "\u2045\u2046\u2047\u2048\u2049\u204A\u204B\u204C"+ + (IS_2000 ? "\u204D\u204E\u204F\u2050\uFEA0\u2051\u2052\u2053" : + "\u204D\u204E\u204F\u2050\u6A78\u2051\u2052\u2053")+ + "\u2054\u2055\u2056\u2057\u2058\u2059\u205A\u205B"+ + "\u205C\u205D\u205E\u205F\u2060\u2061\u2062\u2063"+ + "\u2064\u2065\u2066\u2067\u2068\u2069\u206A\u206B"+ + "\u206C\u206D\u206E\u206F\u2070\u2071\u2072\u2073"+ + "\u2074\u2075\u2076\u2077\u2078\u2079\u207A\u207B"+ + "\u207C\u207D\u207E\u207F\u2080\u2081\u2082\u2083"+ + "\u2084\u2085\u2086\u2087\u2088\u2089\u208A\u208B"+ + "\u208C\u208D\u208E\u208F\u2090\u2091\u2092\u2093"+ + "\u2094\u2095\u2096\u2097\u2098\u2099\u209A\u209B"+ + "\u209C\u209D\u209E\u209F\u20A0\u20A1\u20A2\u20A3"+ + "\u20A4\u20A5\u20A6\u20A7\u20A8\u20A9\u20AA\u20AB"+ + "\u20AC\u20AD\u20AE\u20AF\u20B0\u20B1\u20B2\u20B3"+ + "\u20B4\u20B5\u20B6\u20B7\u20B8\u20B9\u20BA\u20BB"+ + "\u20BC\u20BD\u20BE\u20BF\u20C0\u20C1\u20C2\u20C3"+ + "\u20C4\u20C5\u20C6\u20C7\u20C8\u20C9\u20CA\u20CB"+ + "\u20CC\u20CD\u20CE\u20CF\u20D0\u20D1\u20D2\u20D3"+ + "\u20D4\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB"+ + "\u20DC\u20DD\u20DE\u20DF\u20E0\u20E1\u20E2\u20E3"+ + "\u20E4\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB"+ + "\u20EC\u20ED\u20EE\u20EF\u20F0\u20F1\u20F2\u20F3"+ + "\u20F4\u20F5\u20F6\u20F7\u20F8\u20F9\u20FA\u20FB"+ + "\u20FC\u20FD\u20FE\u20FF\u2100\u2101\u2102\u2103"+ + "\u2104\u2105\u2106\u2107\u2108\u2109\u210A\u210B"+ + "\u210C\u210D\u210E\u210F\u2110\u2111\u2112\u2113"+ + "\u2114\u2115\u2116\u2117\u2118\u2119\u211A\u211B"+ + "\u211C\u211D\u211E\u211F\u2120\u2121\u2122\u2123"+ + "\u2124\u2125\u2126\u2127\u2128\u2129\u212A\u212B"+ + "\u212C\u212D\u212E\u212F\u2130\u2131\u2132\u2133"+ + "\u2134\u2135\u2136\u2137\u2138\u2139\u213A\u213B"+ + "\u213C\u213D\u213E\u213F\u2140\u2141\u2142\u2143"+ + "\u2144\u2145\u2146\u2147\u2148\u2149\u214A\u214B"+ + "\u214C\u214D\u214E\u214F\u2150\u2151\u2152\u2153"+ + "\u2154\u2155\u2156\u2157\u2158\u2159\u215A\u215B"+ + "\u215C\u215D\u215E\u215F\u2160\u2161\u2162\u2163"+ + "\u2164\u2165\u2166\u2167\u2168\u2169\u216A\u216B"+ + "\u216C\u216D\u216E\u216F\u2170\u2171\u2172\u2173"+ + "\u2174\u2175\u2176\u2177\u2178\u2179\u217A\u217B"+ + "\u217C\u217D\u217E\u217F\u2180\u2181\u2182\u2183"+ + "\u2184\u2185\u2186\u2187\u2188\u2189\u218A\u218B"+ + "\u218C\u218D\u218E\u218F\u2190\u2191\u2192\u2193"+ + "\u2194\u2195\u2196\u2197\u2198\u2199\u219A\u219B"+ + "\u219C\u219D\u219E\u219F\u21A0\u21A1\u21A2\u21A3"+ + "\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9\u21AA\u21AB"+ + "\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1\u21B2\u21B3"+ + "\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9\u21BA\u21BB"+ + "\u21BC\u21BD\u21BE\u21BF\u21C0\u21C1\u21C2\u21C3"+ + "\u21C4\u21C5\u21C6\u21C7\u21C8\u21C9\u21CA\u21CB"+ + "\u21CC\u21CD\u21CE\u21CF\u21D0\u21D1\u21D2\u21D3"+ + "\u21D4\u21D5\u21D6\u21D7\u21D8\u21D9\u21DA\u21DB"+ + "\u21DC\u21DD\u21DE\u21DF\u21E0\u21E1\u21E2\u21E3"+ + "\u21E4\u21E5\u21E6\u21E7\u21E8\u21E9\u21EA\u21EB"+ + "\u21EC\u21ED\u21EE\u21EF\u21F0\u21F1\u21F2\u21F3"+ + "\u21F4\u21F5\u21F6\u21F7\u21F8\u21F9\u21FA\u21FB"+ + "\u21FC\u21FD\u21FE\u21FF\u2200\u2201\u2202\u2203"+ + "\u2204\u2205\u2206\u2207\u2208\u2209\u220A\u220B"+ + "\u220C\u220D\u220E\u220F\u2210\u2211\u2212\u2213"+ + "\u2214\u2215\u2216\u2217\u2218\u2219\u221A\u221B"+ + "\u221C\u221D\u221E\u221F\u2220\u2221\u2222\u2223"+ + "\u2224\u2225\u2226\u2227\u2228\u2229\u222A\u222B"+ + "\u222C\u222D\u222E\u222F\u2230\u2231\u2232\u2233"+ + "\u2234\u2235\u2236\u2237\u2238\u2239\u223A\u223B"+ + "\u223C\u223D\u223E\u223F\u2240\u2241\u2242\u2243"+ + "\u2244\u2245\u2246\u2247\u2248\u2249\u224A\u224B"+ + "\u224C\u224D\u224E\u224F\u2250\u2251\u2252\u2253"+ + "\u2254\u2255\u2256\u2257\u2258\u2259\u225A\u225B"+ + "\u225C\u225D\u225E\u225F\u2260\u2261\u2262\u2263"+ + "\u2264\u2265\u2266\u2267\u2268\u2269\u226A\u226B"+ + "\u226C\u226D\u226E\u226F\u2270\u2271\u2272\u2273"+ + "\u2274\u2275\u2276\u2277\u2278\u2279\u227A\u227B"+ + "\u227C\u227D\u227E\u227F\u2280\u2281\u2282\u2283"+ + "\u2284\u2285\u2286\u2287\u2288\u2289\u228A\u228B"+ + "\u228C\u228D\u228E\u228F\u2290\u2291\u2292\u2293"+ + "\u2294\u2295\u2296\u2297\u2298\u2299\u229A\u229B"+ + "\u229C\u229D\u229E\u229F\u22A0\u22A1\u22A2\u22A3"+ + "\u22A4\u22A5\u22A6\u22A7\u22A8\u22A9\u22AA\u22AB"+ + "\u22AC\u22AD\u22AE\u22AF\u22B0\u22B1\u22B2\u22B3"+ + "\u22B4\u22B5\u22B6\u22B7\u22B8\u22B9\u22BA\u22BB"+ + "\u22BC\u22BD\u22BE\u22BF\u22C0\u22C1\u22C2\u22C3"+ + "\u22C4\u22C5\u22C6\u22C7\u22C8\u22C9\u22CA\u22CB"+ + "\u22CC\u22CD\u22CE\u22CF\u22D0\u22D1\u22D2\u22D3"+ + "\u22D4\u22D5\u22D6\u22D7\u22D8\u22D9\u22DA\u22DB"+ + "\u22DC\u22DD\u22DE\u22DF\u22E0\u22E1\u22E2\u22E3"+ + "\u22E4\u22E5\u22E6\u22E7\u22E8\u22E9\u22EA\u22EB"; + + private static final String innerEncoderIndex11= + "\u22EC\u22ED\u22EE\u22EF\u22F0\u22F1\u22F2\u22F3"+ + "\u22F4\u22F5\u22F6\u22F7\u22F8\u22F9\u22FA\u22FB"+ + "\u22FC\u22FD\u22FE\u22FF\u2300\u2301\u2302\u2303"+ + "\u2304\u2305\u2306\u2307\u2308\u2309\u230A\u230B"+ + "\u230C\u230D\u230E\u230F\u2310\u2311\u2312\u2313"+ + "\u2314\u2315\u2316\u2317\u2318\u2319\u231A\u231B"+ + "\u231C\u231D\u231E\u231F\u2320\u2321\u2322\u2323"+ + "\u2324\u2325\u2326\u2327\u2328\u2329\u232A\u232B"+ + "\u232C\u232D\u232E\u232F\u2330\u2331\u2332\u2333"+ + "\u2334\u2335\u2336\u2337\u2338\u2339\u233A\u233B"+ + "\u233C\u233D\u233E\u233F\u2340\u2341\u2342\u2343"+ + "\u2344\u2345\u2346\u2347\u2348\u2349\u234A\u234B"+ + "\u234C\u234D\u234E\u234F\u2350\u2351\u2352\u2353"+ + "\u2354\u2355\u2356\u2357\u2358\u2359\u235A\u235B"+ + "\u235C\u235D\u235E\u235F\u2360\u2361\u2362\u2363"+ + "\u2364\u2365\u2366\u2367\u2368\u2369\u236A\u236B"+ + "\u236C\u236D\u236E\u236F\u2370\u2371\u2372\u2373"+ + "\u2374\u2375\u2376\u2377\u2378\u2379\u237A\u237B"+ + "\u237C\u237D\u237E\u237F\u2380\u2381\u2382\u2383"+ + "\u2384\u2385\u2386\u2387\u2388\u2389\u238A\u238B"+ + "\u238C\u238D\u238E\u238F\u2390\u2391\u2392\u2393"+ + "\u2394\u2395\u2396\u2397\u2398\u2399\u239A\u239B"+ + "\u239C\u239D\u239E\u239F\u23A0\u23A1\u23A2\u23A3"+ + "\u23A4\u23A5\u23A6\u23A7\u23A8\u23A9\u23AA\u23AB"+ + "\u23AC\u23AD\u23AE\u23AF\u23B0\u23B1\u23B2\u23B3"+ + "\u23B4\u23B5\u23B6\u23B7\u23B8\u23B9\u23BA\u23BB"+ + "\u23BC\u23BD\u23BE\u23BF\u23C0\u23C1\u23C2\u23C3"+ + "\u23C4\u23C5\u23C6\u23C7\u23C8\u23C9\u23CA\u23CB"+ + "\u23CC\u23CD\u23CE\u23CF\u23D0\u23D1\u23D2\u23D3"+ + "\u23D4\u23D5\u23D6\u23D7\u23D8\u23D9\u23DA\u23DB"+ + "\u23DC\u23DD\u23DE\u23DF\u23E0\u23E1\u23E2\u23E3"+ + "\u23E4\u23E5\u23E6\u23E7\u23E8\u23E9\u23EA\u23EB"+ + "\u23EC\u23ED\u23EE\u23EF\u23F0\u23F1\u23F2\u23F3"+ + "\u23F4\u23F5\u23F6\u23F7\u23F8\u23F9\u23FA\u23FB"+ + "\u23FC\u23FD\u23FE\u23FF\u2400\u2401\u2402\u2403"+ + "\u2404\u2405\u2406\u2407\u2408\u2409\u240A\u240B"+ + "\u240C\u240D\u240E\u240F\u2410\u2411\u2412\u2413"+ + "\u2414\u2415\u2416\u2417\u2418\u2419\u241A\u241B"+ + "\u241C\u241D\u241E\u241F\u2420\u2421\u2422\u2423"+ + "\u2424\u2425\u2426\u2427\u2428\u2429\u242A\u242B"+ + "\u242C\u242D\u242E\u242F\u2430\u2431\u2432\u2433"+ + "\u2434\u2435\u2436\u2437\u2438\u2439\u243A\u243B"+ + "\u243C\u243D\u243E\u243F\u2440\u2441\u2442\u2443"+ + "\u2444\u2445\u2446\u2447\u2448\u2449\u244A\u244B"+ + "\u244C\u244D\u244E\u244F\u2450\u2451\u2452\u2453"+ + "\u2454\u2455\u2456\u2457\u2458\u2459\u245A\u245B"+ + "\u245C\u245D\u245E\u245F\u2460\u2461\u2462\u2463"+ + "\u2464\u2465\u2466\u2467\u2468\u2469\u246A\u246B"+ + "\u246C\u246D\u246E\u246F\u2470\u2471\u2472\u2473"+ + "\u2474\u2475\u2476\u2477\u2478\u2479\u247A\u247B"+ + "\u247C\u247D\u247E\u247F\u2480\u2481\u2482\u2483"+ + "\u2484\u2485\u2486\u2487\u2488\u2489\u248A\u248B"+ + "\u248C\u248D\u248E\u248F\u2490\u2491\u2492\u2493"+ + "\u2494\u2495\u2496\u2497\u2498\u2499\u249A\u249B"+ + "\u249C\u249D\u249E\u249F\u24A0\u24A1\u24A2\u24A3"+ + "\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9\u24AA\u24AB"+ + "\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1\u24B2\u24B3"+ + "\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9\u24BA\u24BB"+ + "\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1\u24C2\u24C3"+ + "\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9\u24CA\u24CB"+ + "\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1\u24D2\u24D3"+ + "\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9\u24DA\u24DB"+ + "\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1\u24E2\u24E3"+ + "\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9\u24EA\u24EB"+ + "\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1\u24F2\u24F3"+ + "\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9\u24FA\u24FB"+ + "\u24FC\u24FD\u24FE\u24FF\u2500\u2501\u2502\u2503"+ + "\u2504\u2505\u2506\u2507\u2508\u2509\u250A\u250B"+ + "\u250C\u250D\u250E\u250F\u2510\u2511\u2512\u2513"+ + "\u2514\u2515\u2516\u2517\u2518\u2519\u251A\u251B"+ + "\u251C\u251D\u251E\u251F\u2520\u2521\u2522\u2523"+ + "\u2524\u2525\u2526\u2527\u2528\u2529\u252A\u252B"+ + "\u252C\u252D\u252E\u252F\u2530\u2531\u2532\u2533"+ + "\u2534\u2535\u2536\u2537\u2538\u2539\u253A\u253B"+ + "\u253C\u253D\u253E\u253F\u2540\u2541\u2542\u2543"+ + "\u2544\u2545\u2546\u2547\u2548\u2549\u254A\u254B"+ + "\u254C\u254D\u254E\u254F\u2550\u2551\u2552\u2553"+ + "\u2554\u2555\u2556\u2557\u2558\u2559\u255A\u255B"+ + "\u255C\u255D\u255E\u255F\u2560\u2561\u2562\u2563"+ + "\u2564\u2565\u2566\u2567\u2568\u2569\u256A\u256B"+ + "\u256C\u256D\u256E\u256F\u2570\u2571\u2572\u2573"+ + "\u2574\u2575\u2576\u2577\u2578\u2579\u257A\u257B"+ + "\u257C\u257D\u257E\u257F\u2580\u2581\u2582\u2583"+ + "\u2584\u2585\u2586\u2587\u2588\u2589\u258A\u258B"+ + "\u258C\u258D\u258E\u258F\u2590\u2591\u2592\u2593"+ + "\u2594\u2595\u2596\u2597\u2598\u2599\u259A\u259B"+ + "\u259C\u259D\u259E\u259F\u25A0\u25A1\u25A2\u25A3"+ + "\u25A4\u25A5\u25A6\u25A7\u25A8\u25A9\u25AA\u25AB"+ + "\u25AC\u25AD\u25AE\u25AF\u25B0\u25B1\u25B2\u25B3"+ + "\u25B4\u25B5\u25B6\u25B7\u25B8\u25B9\u25BA\u25BB"+ + "\u25BC\u25BD\u25BE\u25BF\u25C0\u25C1\u25C2\u25C3"+ + "\u25C4\u25C5\u25C6\u25C7\u25C8\u25C9\u25CA\u25CB"+ + "\u25CC\u25CD\u25CE\u25CF\u25D0\u25D1\u25D2\u25D3"+ + "\u25D4\u25D5\u25D6\u25D7\u25D8\u25D9\u25DA\u25DB"+ + "\u25DC\u25DD\u25DE\u25DF\u25E0\u25E1\u25E2\u25E3"+ + "\u25E4\u25E5\u25E6\u25E7\u25E8\u25E9\u25EA\u25EB"+ + "\u25EC\u25ED\u25EE\u25EF\u25F0\u25F1\u25F2\u25F3"+ + "\u25F4\u25F5\u25F6\u25F7\u25F8\u25F9\u25FA\u25FB"+ + "\u25FC\u25FD\u25FE\u25FF\u2600\u2601\u2602\u2603"+ + "\u2604\u2605\u2606\u2607\u2608\u2609\u260A\u260B"+ + "\u260C\u260D\u260E\u260F\u2610\u2611\u2612\u2613"+ + "\u2614\u2615\u2616\u2617\u2618\u2619\u261A\u261B"+ + "\u261C\u261D\u261E\u261F\u2620\u2621\u2622\u2623"+ + "\u2624\u2625\u2626\u2627\u2628\u2629\u262A\u262B"+ + "\u262C\u262D\u262E\u262F\u2630\u2631\u2632\u2633"+ + "\u2634\u2635\u2636\u2637\u2638\u2639\u263A\u263B"+ + "\u263C\u263D\u263E\u263F\u2640\u2641\u2642\u2643"+ + "\u2644\u2645\u2646\u2647\u2648\u2649\u264A\u264B"+ + "\u264C\u264D\u264E\u264F\u2650\u2651\u2652\u2653"+ + "\u2654\u2655\u2656\u2657\u2658\u2659\u265A\u265B"+ + "\u265C\u265D\u265E\u265F\u2660\u2661\u2662\u2663"+ + "\u2664\u2665\u2666\u2667\u2668\u2669\u266A\u266B"+ + "\u266C\u266D\u266E\u266F\u2670\u2671\u2672\u2673"+ + "\u2674\u2675\u2676\u2677\u2678\u2679\u267A\u267B"+ + "\u267C\u267D\u267E\u267F\u2680\u2681\u2682\u2683"+ + "\u2684\u2685\u2686\u2687\u2688\u2689\u268A\u268B"+ + "\u268C\u268D\u268E\u268F\u2690\u2691\u2692\u2693"+ + "\u2694\u2695\u2696\u2697\u2698\u2699\u269A\u269B"+ + "\u269C\u269D\u269E\u269F\u26A0\u26A1\u26A2\u26A3"+ + "\u26A4\u26A5\u26A6\u26A7\u26A8\u26A9\u26AA\u26AB"+ + "\u26AC\u26AD\u26AE\u26AF\u26B0\u26B1\u26B2\u26B3"+ + "\u26B4\u26B5\u26B6\u26B7\u26B8\u26B9\u26BA\u26BB"+ + "\u26BC\u26BD\u26BE\u26BF\u26C0\u26C1\u26C2\u26C3"+ + "\u26C4\u26C5\u26C6\u26C7\u26C8\u26C9\u26CA\u26CB"+ + "\u26CC\u26CD\u26CE\u26CF\u26D0\u26D1\u26D2\u26D3"+ + "\u26D4\u26D5\u26D6\u26D7\u26D8\u26D9\u26DA\u26DB"+ + "\u26DC\u26DD\u26DE\u26DF\u26E0\u26E1\u26E2\u26E3"+ + "\u26E4\u26E5\u26E6\u26E7\u26E8\u26E9\u26EA\u26EB"+ + "\u26EC\u26ED\u26EE\u26EF\u26F0\u26F1\u26F2\u26F3"+ + "\u26F4\u26F5\u26F6\u26F7\u26F8\u26F9\u26FA\u26FB"+ + "\u26FC\u26FD\u26FE\u26FF\u2700\u2701\u2702\u2703"+ + "\u2704\u2705\u2706\u2707\u2708\u2709\u270A\u270B"+ + "\u270C\u270D\u270E\u270F\u2710\u2711\u2712\u2713"+ + "\u2714\u2715\u2716\u2717\u2718\u2719\u271A\u271B"+ + "\u271C\u271D\u271E\u271F\u2720\u2721\u2722\u2723"+ + "\u2724\u2725\u2726\u2727\u2728\u2729\u272A\u272B"+ + "\u272C\u272D\u272E\u272F\u2730\u2731\u2732\u2733"+ + "\u2734\u2735\u2736\u2737\u2738\u2739\u273A\u273B"+ + "\u273C\u273D\u273E\u273F\u2740\u2741\u2742\u2743"+ + "\u2744\u2745\u2746\u2747\u2748\u2749\u274A\u274B"+ + "\u274C\u274D\u274E\u274F\u2750\u2751\u2752\u2753"+ + "\u2754\u2755\u2756\u2757\u2758\u2759\u275A\u275B"+ + "\u275C\u275D\u275E\u275F\u2760\u2761\u2762\u2763"+ + "\u2764\u2765\u2766\u2767\u2768\u2769\u276A\u276B"+ + "\u276C\u276D\u276E\u276F\u2770\u2771\u2772\u2773"+ + "\u2774\u2775\u2776\u2777\u2778\u2779\u277A\u277B"+ + "\u277C\u277D\u277E\u277F\u2780\u2781\u2782\u2783"+ + "\u2784\u2785\u2786\u2787\u2788\u2789\u278A\u278B"+ + "\u278C\u278D\u278E\u278F\u2790\u2791\u2792\u2793"+ + "\u2794\u2795\u2796\u2797\u2798\u2799\u279A\u279B"+ + "\u279C\u279D\u279E\u279F\u27A0\u27A1\u27A2\u27A3"+ + "\u27A4\u27A5\u27A6\u27A7\u27A8\u27A9\u27AA\u27AB"+ + "\u27AC\u27AD\u27AE\u27AF\u27B0\u27B1\u27B2\u27B3"+ + "\u27B4\u27B5\u27B6\u27B7\u27B8\u27B9\u27BA\u27BB"+ + "\u27BC\u27BD\u27BE\u27BF\u27C0\u27C1\u27C2\u27C3"+ + "\u27C4\u27C5\u27C6\u27C7\u27C8\u27C9\u27CA\u27CB"+ + "\u27CC\u27CD\u27CE\u27CF\u27D0\u27D1\u27D2\u27D3"+ + "\u27D4\u27D5\u27D6\u27D7\u27D8\u27D9\u27DA\u27DB"+ + "\u27DC\u27DD\u27DE\u27DF\u27E0\u27E1\u27E2\u27E3"+ + "\u27E4\u27E5\u27E6\u27E7\u27E8\u27E9\u27EA\u27EB"+ + "\u27EC\u27ED\u27EE\u27EF\u27F0\u27F1\u27F2\u27F3"+ + "\u27F4\u27F5\u27F6\u27F7\u27F8\u27F9\u27FA\u27FB"+ + "\u27FC\u27FD\u27FE\u27FF\u2800\u2801\u2802\u2803"+ + "\u2804\u2805\u2806\u2807\u2808\u2809\u280A\u280B"+ + "\u280C\u280D\u280E\u280F\u2810\u2811\u2812\u2813"+ + "\u2814\u2815\u2816\u2817\u2818\u2819\u281A\u281B"+ + "\u281C\u281D\u281E\u281F\u2820\u2821\u2822\u2823"+ + "\u2824\u2825\u2826\u2827\u2828\u2829\u282A\u282B"+ + "\u282C\u282D\u282E\u282F\u2830\u2831\u2832\u2833"+ + "\u2834\u2835\u2836\u2837\u2838\u2839\u283A\u283B"+ + "\u283C\u283D\u283E\u283F\u2840\u2841\u2842\u2843"+ + "\u2844\u2845\u2846\u2847\u2848\u2849\u284A\u284B"+ + "\u284C\u284D\u284E\u284F\u2850\u2851\u2852\u2853"+ + "\u2854\u2855\u2856\u2857\u2858\u2859\u285A\u285B"+ + "\u285C\u285D\u285E\u285F\u2860\u2861\u2862\u2863"+ + "\u2864\u2865\u2866\u2867\u2868\u2869\u286A\u286B"+ + "\u286C\u286D\u286E\u286F\u2870\u2871\u2872\u2873"+ + "\u2874\u2875\u2876\u2877\u2878\u2879\u287A\u287B"+ + "\u287C\u287D\u287E\u287F\u2880\u2881\u2882\u2883"+ + "\u2884\u2885\u2886\u2887\u2888\u2889\u288A\u288B"+ + "\u288C\u288D\u288E\u288F\u2890\u2891\u2892\u2893"+ + "\u2894\u2895\u2896\u2897\u2898\u2899\u289A\u289B"+ + "\u289C\u289D\u289E\u289F\u28A0\u28A1\u28A2\u28A3"+ + "\u28A4\u28A5\u28A6\u28A7\u28A8\u28A9\u28AA\u28AB"+ + "\u28AC\u28AD\u28AE\u28AF\u28B0\u28B1\u28B2\u28B3"+ + "\u28B4\u28B5\u28B6\u28B7\u28B8\u28B9\u28BA\u28BB"+ + "\u28BC\u28BD\u28BE\u28BF\u28C0\u28C1\u28C2\u28C3"+ + "\u28C4\u28C5\u28C6\u28C7\u28C8\u28C9\u28CA\u28CB"+ + "\u28CC\u28CD\u28CE\u28CF\u28D0\u28D1\u28D2\u28D3"+ + "\u28D4\u28D5\u28D6\u28D7\u28D8\u28D9\u28DA\u28DB"+ + "\u28DC\u28DD\u28DE\u28DF\u28E0\u28E1\u28E2\u28E3"+ + "\u28E4\u28E5\u28E6\u28E7\u28E8\u28E9\u28EA\u28EB"+ + "\u28EC\u28ED\u28EE\u28EF\u28F0\u28F1\u28F2\u28F3"+ + "\u28F4\u28F5\u28F6\u28F7\u28F8\u28F9\u28FA\u28FB"+ + "\u28FC\u28FD\u28FE\u28FF\u2900\u2901\u2902\u2903"+ + "\u2904\u2905\u2906\u2907\u2908\u2909\u290A\u290B"+ + "\u290C\u290D\u290E\u290F\u2910\u2911\u2912\u2913"+ + "\u2914\u2915\u2916\u2917\u2918\u2919\u291A\u291B"+ + "\u291C\u291D\u291E\u291F\u2920\u2921\u2922\u2923"+ + "\u2924\u2925\u2926\u2927\u2928\u2929\u292A\u292B"+ + "\u292C\u292D\u292E\u292F\u2930\u2931\u2932\u2933"+ + "\u2934\u2935\u2936\u2937\u2938\u2939\u293A\u293B"+ + "\u293C\u293D\u293E\u293F\u2940\u2941\u2942\u2943"+ + "\u2944\u2945\u2946\u2947\u2948\u2949\u294A\u294B"+ + "\u294C\u294D\u294E\u294F\u2950\u2951\u2952\u2953"+ + "\u2954\u2955\u2956\u2957\u2958\u2959\u295A\u295B"+ + "\u295C\u295D\u295E\u295F\u2960\u2961\u2962\u2963"+ + "\u2964\u2965\u2966\u2967\u2968\u2969\u296A\u296B"+ + "\u296C\u296D\u296E\u296F\u2970\u2971\u2972\u2973"+ + "\u2974\u2975\u2976\u2977\u2978\u2979\u297A\u297B"+ + "\u297C\u297D\u297E\u297F\u2980\u2981\u2982\u2983"+ + "\u2984\u2985\u2986\u2987\u2988\u2989\u298A\u298B"+ + "\u298C\u298D\u298E\u298F\u2990\u2991\u2992\u2993"+ + "\u2994\u2995\u2996\u2997\u2998\u2999\u299A\u299B"+ + "\u299C\u299D\u299E\u299F\u29A0\u29A1\u29A2\u29A3"+ + "\u29A4\u29A5\u29A6\u29A7\u29A8\u29A9\u29AA\u29AB"+ + "\u29AC\u29AD\u29AE\u29AF\u29B0\u29B1\u29B2\u29B3"+ + "\u29B4\u29B5\u29B6\u29B7\u29B8\u29B9\u29BA\u29BB"+ + "\u29BC\u29BD\u29BE\u29BF\u29C0\u29C1\u29C2\u29C3"+ + "\u29C4\u29C5\u29C6\u29C7\u29C8\u29C9\u29CA\u29CB"+ + "\u29CC\u29CD\u29CE\u29CF\u29D0\u29D1\u29D2\u29D3"+ + "\u29D4\u29D5\u29D6\u29D7\u29D8\u29D9\u29DA\u29DB"+ + "\u29DC\u29DD\u29DE\u29DF\u29E0\u29E1\u29E2\u29E3"+ + "\u29E4\u29E5\u29E6\u29E7\u29E8\u29E9\u29EA\u29EB"+ + "\u29EC\u29ED\u29EE\u29EF\u29F0\u29F1\u29F2\u29F3"+ + "\u29F4\u29F5\u29F6\u29F7\u29F8\u29F9\u29FA\u29FB"+ + "\u29FC\u29FD\u29FE\u29FF\u2A00\u2A01\u2A02\u2A03"+ + "\u2A04\u2A05\u2A06\u2A07\u2A08\u2A09\u2A0A\u2A0B"+ + "\u2A0C\u2A0D\u2A0E\u2A0F\u2A10\u2A11\u2A12\u2A13"+ + "\u2A14\u2A15\u2A16\u2A17\u2A18\u2A19\u2A1A\u2A1B"+ + "\u2A1C\u2A1D\u2A1E\u2A1F\u2A20\u2A21\u2A22\u2A23"+ + "\u2A24\u2A25\u2A26\u2A27\u2A28\u2A29\u2A2A\u2A2B"+ + "\u2A2C\u2A2D\u2A2E\u2A2F\u2A30\u2A31\u2A32\u2A33"+ + "\u2A34\u2A35\u2A36\u2A37\u2A38\u2A39\u2A3A\u2A3B"+ + "\u2A3C\u2A3D\u2A3E\u2A3F\u2A40\u2A41\u2A42\u2A43"+ + "\u2A44\u2A45\u2A46\u2A47\u2A48\u2A49\u2A4A\u2A4B"+ + "\u2A4C\u2A4D\u2A4E\u2A4F\u2A50\u2A51\u2A52\u2A53"+ + "\u2A54\u2A55\u2A56\u2A57\u2A58\u2A59\u2A5A\u2A5B"+ + "\u2A5C\u2A5D\u2A5E\u2A5F\u2A60\u2A61\u2A62\u2A63"+ + "\u2A64\u2A65\u2A66\u2A67\u2A68\u2A69\u2A6A\u2A6B"+ + "\u2A6C\u2A6D\u2A6E\u2A6F\u2A70\u2A71\u2A72\u2A73"+ + "\u2A74\u2A75\u2A76\u2A77\u2A78\u2A79\u2A7A\u2A7B"+ + "\u2A7C\u2A7D\u2A7E\u2A7F\u2A80\u2A81\u2A82\u2A83"+ + "\u2A84\u2A85\u2A86\u2A87\u2A88\u2A89\u2A8A\u2A8B"+ + "\u2A8C\u2A8D\u2A8E\u2A8F\u2A90\u2A91\u2A92\u2A93"+ + "\u2A94\u2A95\u2A96\u2A97\u2A98\u2A99\u2A9A\u2A9B"+ + "\u2A9C\u2A9D\u2A9E\u2A9F\u2AA0\u2AA1\u2AA2\u2AA3"+ + "\u2AA4\u2AA5\u2AA6\u2AA7\u2AA8\u2AA9\u2AAA\u2AAB"+ + "\u2AAC\u2AAD\u2AAE\u2AAF\u2AB0\u2AB1\u2AB2\u2AB3"+ + "\u2AB4\u2AB5\u2AB6\u2AB7\u2AB8\u2AB9\u2ABA\u2ABB"+ + "\u2ABC\u2ABD\u2ABE\u2ABF\u2AC0\u2AC1\u2AC2\u2AC3"+ + "\u2AC4\u2AC5\u2AC6\u2AC7\u2AC8\u2AC9\u2ACA\u2ACB"+ + "\u2ACC\u2ACD\u2ACE\u2ACF\u2AD0\u2AD1\u2AD2\u2AD3"+ + "\u2AD4\u2AD5\u2AD6\u2AD7\u2AD8\u2AD9\u2ADA\u2ADB"+ + "\u2ADC\u2ADD\u2ADE\u2ADF\u2AE0\u2AE1\u2AE2\u2AE3"+ + "\u2AE4\u2AE5\u2AE6\u2AE7\u2AE8\u2AE9\u2AEA\u2AEB"+ + "\u2AEC\u2AED\u2AEE\u2AEF\u2AF0\u2AF1\u2AF2\u2AF3"+ + "\u2AF4\u2AF5\u2AF6\u2AF7\u2AF8\u2AF9\u2AFA\u2AFB"+ + "\u2AFC\u2AFD\u2AFE\u2AFF\u2B00\u2B01\u2B02\u2B03"+ + "\u2B04\u2B05\u2B06\u2B07\u2B08\u2B09\u2B0A\u2B0B"+ + "\u2B0C\u2B0D\u2B0E\u2B0F\u2B10\u2B11\u2B12\u2B13"+ + "\u2B14\u2B15\u2B16\u2B17\u2B18\u2B19\u2B1A\u2B1B"+ + "\u2B1C\u2B1D\u2B1E\u2B1F\u2B20\u2B21\u2B22\u2B23"+ + "\u2B24\u2B25\u2B26\u2B27\u2B28\u2B29\u2B2A\u2B2B"+ + "\u2B2C\u2B2D\u2B2E\u2B2F\u2B30\u2B31\u2B32\u2B33"+ + "\u2B34\u2B35\u2B36\u2B37\u2B38\u2B39\u2B3A\u2B3B"+ + "\u2B3C\u2B3D\u2B3E\u2B3F\u2B40\u2B41\u2B42\u2B43"+ + "\u2B44\u2B45\u2B46\u2B47\u2B48\u2B49\u2B4A\u2B4B"+ + "\u2B4C\u2B4D\u2B4E\u2B4F\u2B50\u2B51\u2B52\u2B53"+ + "\u2B54\u2B55\u2B56\u2B57\u2B58\u2B59\u2B5A\u2B5B"+ + "\u2B5C\u2B5D\u2B5E\u2B5F\u2B60\u2B61\u2B62\u2B63"+ + "\u2B64\u2B65\u2B66\u2B67\u2B68\u2B69\u2B6A\u2B6B"+ + "\u2B6C\u2B6D\u2B6E\u2B6F\u2B70\u2B71\u2B72\u2B73"+ + "\u2B74\u2B75\u2B76\u2B77\u2B78\u2B79\u2B7A\u2B7B"+ + "\u2B7C\u2B7D\u2B7E\u2B7F\u2B80\u2B81\u2B82\u2B83"+ + "\u2B84\u2B85\u2B86\u2B87\u2B88\u2B89\u2B8A\u2B8B"+ + "\u2B8C\u2B8D\u2B8E\u2B8F\u2B90\u2B91\u2B92\u2B93"+ + "\u2B94\u2B95\u2B96\u2B97\u2B98\u2B99\u2B9A\u2B9B"+ + "\u2B9C\u2B9D\u2B9E\u2B9F\u2BA0\u2BA1\u2BA2\u2BA3"+ + "\u2BA4\u2BA5\u2BA6\u2BA7\u2BA8\u2BA9\u2BAA\u2BAB"+ + "\u2BAC\u2BAD\u2BAE\u2BAF\u2BB0\u2BB1\u2BB2\u2BB3"+ + "\u2BB4\u2BB5\u2BB6\u2BB7\u2BB8\u2BB9\u2BBA\u2BBB"+ + "\u2BBC\u2BBD\u2BBE\u2BBF\u2BC0\u2BC1\u2BC2\u2BC3"+ + "\u2BC4\u2BC5\u2BC6\u2BC7\u2BC8\u2BC9\u2BCA\u2BCB"+ + "\u2BCC\u2BCD\u2BCE\u2BCF\u2BD0\u2BD1\u2BD2\u2BD3"+ + "\u2BD4\u2BD5\u2BD6\u2BD7\u2BD8\u2BD9\u2BDA\u2BDB"+ + "\u2BDC\u2BDD\u2BDE\u2BDF\u2BE0\u2BE1\u2BE2\u2BE3"+ + "\u2BE4\u2BE5\u2BE6\u2BE7\u2BE8\u2BE9\u2BEA\u2BEB"+ + "\u2BEC\u2BED\u2BEE\u2BEF\u2BF0\u2BF1\u2BF2\u2BF3"+ + "\u2BF4\u2BF5\u2BF6\u2BF7\u2BF8\u2BF9\u2BFA\u2BFB"+ + "\u2BFC\u2BFD\u2BFE\u2BFF\u2C00\u2C01\u2C02\u2C03"+ + "\u2C04\u2C05\u2C06\u2C07\u2C08\u2C09\u2C0A\u2C0B"+ + "\u2C0C\u2C0D\u2C0E\u2C0F\u2C10\u2C11\u2C12\u2C13"+ + "\u2C14\u2C15\u2C16\u2C17\u2C18\u2C19\u2C1A\u2C1B"+ + "\u2C1C\u2C1D\u2C1E\u2C1F\u2C20\u2C21\u2C22\u2C23"+ + "\u2C24\u2C25\u2C26\u2C27\u2C28\u2C29\u2C2A\u2C2B"+ + "\u2C2C\u2C2D\u2C2E\u2C2F\u2C30\u2C31\u2C32\u2C33"+ + "\u2C34\u2C35\u2C36\u2C37\u2C38\u2C39\u2C3A\u2C3B"+ + "\u2C3C\u2C3D\u2C3E\u2C3F\u2C40\u2C41\u2C42\u2C43"+ + "\u2C44\u2C45\u2C46\u2C47\u2C48\u2C49\u2C4A\u2C4B"+ + "\u2C4C\u2C4D\u2C4E\u2C4F\u2C50\u2C51\u2C52\u2C53"+ + "\u2C54\u2C55\u2C56\u2C57\u2C58\u2C59\u2C5A\u2C5B"+ + "\u2C5C\u2C5D\u2C5E\u2C5F\u2C60\u2C61\u2C62\u2C63"+ + "\u2C64\u2C65\u2C66\u2C67\u2C68\u2C69\u2C6A\u2C6B"+ + "\u2C6C\u2C6D\u2C6E\u2C6F\u2C70\u2C71\u2C72\u2C73"+ + "\u2C74\u2C75\u2C76\u2C77\u2C78\u2C79\u2C7A\u2C7B"+ + "\u2C7C\u2C7D\u2C7E\u2C7F\u2C80\u2C81\u2C82\u2C83"+ + "\u2C84\u2C85\u2C86\u2C87\u2C88\u2C89\u2C8A\u2C8B"+ + "\u2C8C\u2C8D\u2C8E\u2C8F\u2C90\u2C91\u2C92\u2C93"+ + "\u2C94\u2C95\u2C96\u2C97\u2C98\u2C99\u2C9A\u2C9B"+ + "\u2C9C\u2C9D\u2C9E\u2C9F\u2CA0\u2CA1\u2CA2\u2CA3"+ + "\u2CA4\u2CA5\u2CA6\u2CA7\u2CA8\u2CA9\u2CAA\u2CAB"+ + "\u2CAC\u2CAD\u2CAE\u2CAF\u2CB0\u2CB1\u2CB2\u2CB3"+ + "\u2CB4\u2CB5\u2CB6\u2CB7\u2CB8\u2CB9\u2CBA\u2CBB"+ + "\u2CBC\u2CBD\u2CBE\u2CBF\u2CC0\u2CC1\u2CC2\u2CC3"+ + "\u2CC4\u2CC5\u2CC6\u2CC7\u2CC8\u2CC9\u2CCA\u2CCB"+ + "\u2CCC\u2CCD\u2CCE\u2CCF\u2CD0\u2CD1\u2CD2\u2CD3"+ + "\u2CD4\u2CD5\u2CD6\u2CD7\u2CD8\u2CD9\u2CDA\u2CDB"+ + "\u2CDC\u2CDD\u2CDE\u2CDF\u2CE0\u2CE1\u2CE2\u2CE3"+ + "\u2CE4\u2CE5\u2CE6\u2CE7\u2CE8\u2CE9\u2CEA\u2CEB"+ + "\u2CEC\u2CED\u2CEE\u2CEF\u2CF0\u2CF1\u2CF2\u2CF3"+ + "\u2CF4\u2CF5\u2CF6\u2CF7\u2CF8\u2CF9\u2CFA\u2CFB"+ + "\u2CFC\u2CFD\u2CFE\u2CFF\u2D00\u2D01\u2D02\u2D03"+ + "\u2D04\u2D05\u2D06\u2D07\u2D08\u2D09\u2D0A\u2D0B"+ + "\u2D0C\u2D0D\u2D0E\u2D0F\u2D10\u2D11\u2D12\u2D13"+ + "\u2D14\u2D15\u2D16\u2D17\u2D18\u2D19\u2D1A\u2D1B"+ + "\u2D1C\u2D1D\u2D1E\u2D1F\u2D20\u2D21\u2D22\u2D23"+ + "\u2D24\u2D25\u2D26\u2D27\u2D28\u2D29\u2D2A\u2D2B"+ + "\u2D2C\u2D2D\u2D2E\u2D2F\u2D30\u2D31\u2D32\u2D33"+ + "\u2D34\u2D35\u2D36\u2D37\u2D38\u2D39\u2D3A\u2D3B"+ + "\u2D3C\u2D3D\u2D3E\u2D3F\u2D40\u2D41\u2D42\u2D43"+ + "\u2D44\u2D45\u2D46\u2D47\u2D48\u2D49\u2D4A\u2D4B"+ + "\u2D4C\u2D4D\u2D4E\u2D4F\u2D50\u2D51\u2D52\u2D53"+ + "\u2D54\u2D55\u2D56\u2D57\u2D58\u2D59\u2D5A\u2D5B"+ + "\u2D5C\u2D5D\u2D5E\u2D5F\u2D60\u2D61\u2D62\u2D63"+ + "\u2D64\u2D65\u2D66\u2D67\u2D68\u2D69\u2D6A\u2D6B"+ + "\u2D6C\u2D6D\u2D6E\u2D6F\u2D70\u2D71\u2D72\u2D73"+ + "\u2D74\u2D75\u2D76\u2D77\u2D78\u2D79\u2D7A\u2D7B"+ + "\u2D7C\u2D7D\u2D7E\u2D7F\u2D80\u2D81\u2D82\u2D83"+ + "\u2D84\u2D85\u2D86\u2D87\u2D88\u2D89\u2D8A\u2D8B"+ + "\u2D8C\u2D8D\u2D8E\u2D8F\u2D90\u2D91\u2D92\u2D93"+ + "\u2D94\u2D95\u2D96\u2D97\u2D98\u2D99\u2D9A\u2D9B"+ + "\u2D9C\u2D9D\u2D9E\u2D9F\u2DA0\u2DA1\u2DA2\u2DA3"+ + "\u2DA4\u2DA5\u2DA6\u2DA7\u2DA8\u2DA9\u2DAA\u2DAB"+ + "\u2DAC\u2DAD\u2DAE\u2DAF\u2DB0\u2DB1\u2DB2\u2DB3"+ + "\u2DB4\u2DB5\u2DB6\u2DB7\u2DB8\u2DB9\u2DBA\u2DBB"+ + "\u2DBC\u2DBD\u2DBE\u2DBF\u2DC0\u2DC1\u2DC2\u2DC3"+ + "\u2DC4\u2DC5\u2DC6\u2DC7\u2DC8\u2DC9\u2DCA\u2DCB"+ + "\u2DCC\u2DCD\u2DCE\u2DCF\u2DD0\u2DD1\u2DD2\u2DD3"+ + "\u2DD4\u2DD5\u2DD6\u2DD7\u2DD8\u2DD9\u2DDA\u2DDB"+ + "\u2DDC\u2DDD\u2DDE\u2DDF\u2DE0\u2DE1\u2DE2\u2DE3"+ + "\u2DE4\u2DE5\u2DE6\u2DE7\u2DE8\u2DE9\u2DEA\u2DEB"+ + "\u2DEC\u2DED\u2DEE\u2DEF\u2DF0\u2DF1\u2DF2\u2DF3"+ + "\u2DF4\u2DF5\u2DF6\u2DF7\u2DF8\u2DF9\u2DFA\u2DFB"+ + "\u2DFC\u2DFD\u2DFE\u2DFF\u2E00\u2E01\u2E02\u2E03"+ + "\u2E04\u2E05\u2E06\u2E07\u2E08\u2E09\u2E0A\u2E0B"+ + "\u2E0C\u2E0D\u2E0E\u2E0F\u2E10\u2E11\u2E12\u2E13"+ + "\u2E14\u2E15\u2E16\u2E17\u2E18\u2E19\u2E1A\u2E1B"+ + "\u2E1C\u2E1D\u2E1E\u2E1F\u2E20\u2E21\u2E22\u2E23"+ + "\u2E24\u2E25\u2E26\u2E27\u2E28\u2E29\u2E2A\u2E2B"+ + "\u2E2C\u2E2D\u2E2E\u2E2F\u2E30\u2E31\u2E32\u2E33"+ + "\u2E34\u2E35\u2E36\u2E37\u2E38\u2E39\u2E3A\u2E3B"+ + "\u2E3C\u2E3D\u2E3E\u2E3F\u2E40\u2E41\u2E42\u2E43"+ + "\u2E44\u2E45\u2E46\u2E47\u2E48\u2E49\u2E4A\u2E4B"+ + "\u2E4C\u2E4D\u2E4E\u2E4F\u2E50\u2E51\u2E52\u2E53"+ + "\u2E54\u2E55\u2E56\u2E57\u2E58\u2E59\u2E5A\u2E5B"+ + "\u2E5C\u2E5D\u2E5E\u2E5F\u2E60\u2E61\u2E62\u2E63"+ + "\u2E64\u2E65\u2E66\u2E67\u2E68\u2E69\u2E6A\u2E6B"+ + "\u2E6C\u2E6D\u2E6E\u2E6F\u2E70\u2E71\u2E72\u2E73"+ + "\u2E74\u2E75\u2E76\u2E77\u2E78\u2E79\u2E7A\u2E7B"+ + "\u2E7C\u2E7D\u2E7E\u2E7F\u2E80\u2E81\u2E82\u2E83"+ + "\u2E84\u2E85\u2E86\u2E87\u2E88\u2E89\u2E8A\u2E8B"+ + "\u2E8C\u2E8D\u2E8E\u2E8F\u2E90\u2E91\u2E92\u2E93"+ + "\u2E94\u2E95\u2E96\u2E97\u2E98\u2E99\u2E9A\u2E9B"+ + "\u2E9C\u2E9D\u2E9E\u2E9F\u2EA0\u2EA1\u2EA2\u2EA3"+ + "\u2EA4\u2EA5\u2EA6\u2EA7\u2EA8\u2EA9\u2EAA\u2EAB"+ + "\u2EAC\u2EAD\u2EAE\u2EAF\u2EB0\u2EB1\u2EB2\u2EB3"+ + "\u2EB4\u2EB5\u2EB6\u2EB7\u2EB8\u2EB9\u2EBA\u2EBB"+ + "\u2EBC\u2EBD\u2EBE\u2EBF\u2EC0\u2EC1\u2EC2\u2EC3"+ + "\u2EC4\u2EC5\u2EC6\u2EC7\u2EC8\u2EC9\u2ECA\u2ECB"+ + "\u2ECC\u2ECD\u2ECE\u2ECF\u2ED0\u2ED1\u2ED2\u2ED3"+ + "\u2ED4\u2ED5\u2ED6\u2ED7\u2ED8\u2ED9\u2EDA\u2EDB"+ + "\u2EDC\u2EDD\u2EDE\u2EDF\u2EE0\u2EE1\u2EE2\u2EE3"+ + "\u2EE4\u2EE5\u2EE6\u2EE7\u2EE8\u2EE9\u2EEA\u2EEB"+ + "\u2EEC\u2EED\u2EEE\u2EEF\u2EF0\u2EF1\u2EF2\u2EF3"+ + "\u2EF4\u2EF5\u2EF6\u2EF7\u2EF8\u2EF9\u2EFA\u2EFB"+ + "\u2EFC\u2EFD\u2EFE\u2EFF\u2F00\u2F01\u2F02\u2F03"+ + "\u2F04\u2F05\u2F06\u2F07\u2F08\u2F09\u2F0A\u2F0B"+ + "\u2F0C\u2F0D\u2F0E\u2F0F\u2F10\u2F11\u2F12\u2F13"+ + "\u2F14\u2F15\u2F16\u2F17\u2F18\u2F19\u2F1A\u2F1B"+ + "\u2F1C\u2F1D\u2F1E\u2F1F\u2F20\u2F21\u2F22\u2F23"+ + "\u2F24\u2F25\u2F26\u2F27\u2F28\u2F29\u2F2A\u2F2B"+ + "\u2F2C\u2F2D\u2F2E\u2F2F\u2F30\u2F31\u2F32\u2F33"+ + "\u2F34\u2F35\u2F36\u2F37\u2F38\u2F39\u2F3A\u2F3B"+ + "\u2F3C\u2F3D\u2F3E\u2F3F\u2F40\u2F41\u2F42\u2F43"+ + "\u2F44\u2F45\u2F46\u2F47\u2F48\u2F49\u2F4A\u2F4B"+ + "\u2F4C\u2F4D\u2F4E\u2F4F\u2F50\u2F51\u2F52\u2F53"+ + "\u2F54\u2F55\u2F56\u2F57\u2F58\u2F59\u2F5A\u2F5B"+ + "\u2F5C\u2F5D\u2F5E\u2F5F\u2F60\u2F61\u2F62\u2F63"+ + "\u2F64\u2F65\u2F66\u2F67\u2F68\u2F69\u2F6A\u2F6B"+ + "\u2F6C\u2F6D\u2F6E\u2F6F\u2F70\u2F71\u2F72\u2F73"+ + "\u2F74\u2F75\u2F76\u2F77\u2F78\u2F79\u2F7A\u2F7B"+ + "\u2F7C\u2F7D\u2F7E\u2F7F\u2F80\u2F81\u2F82\u2F83"+ + "\u2F84\u2F85\u2F86\u2F87\u2F88\u2F89\u2F8A\u2F8B"+ + "\u2F8C\u2F8D\u2F8E\u2F8F\u2F90\u2F91\u2F92\u2F93"+ + "\u2F94\u2F95\u2F96\u2F97\u2F98\u2F99\u2F9A\u2F9B"+ + "\u2F9C\u2F9D\u2F9E\u2F9F\u2FA0\u2FA1\u2FA2\u2FA3"+ + "\u2FA4\u2FA5\u2FA6\u2FA7\u2FA8\u2FA9\u2FAA\u2FAB"+ + "\u2FAC\u2FAD\u2FAE\u2FAF\u2FB0\u2FB1\u2FB2\u2FB3"+ + "\u2FB4\u2FB5\u2FB6\u2FB7\u2FB8\u2FB9\u2FBA\u2FBB"+ + "\u2FBC\u2FBD\u2FBE\u2FBF\u2FC0\u2FC1\u2FC2\u2FC3"+ + "\u2FC4\u2FC5\u2FC6\u2FC7\u2FC8\u2FC9\u2FCA\u2FCB"+ + "\u2FCC\u2FCD\u2FCE\u2FCF\u2FD0\u2FD1\u2FD2\u2FD3"+ + "\u2FD4\u2FD5\u2FD6\u2FD7\u2FD8\u2FD9\u2FDA\u2FDB"+ + "\u2FDC\u2FDD\u2FDE\u2FDF\u2FE0\u2FE1\u2FE2\u2FE3"+ + "\u2FE4\u2FE5\u2FE6\u2FE7\u2FE8\u2FE9\u2FEA\u2FEB"+ + "\u2FEC\u2FED\u2FEE\u2FEF\u2FF0\u2FF1\u2FF2\u2FF3"+ + "\u2FF4\u2FF5\u2FF6\u2FF7\u2FF8\u2FF9\u2FFA\u2FFB"+ + "\u2FFC\u2FFD\u2FFE\u2FFF\u3000\u3001\u3002\u3003"+ + "\u3004\u3005\u3006\u3007\u3008\u3009\u300A\u300B"+ + "\u300C\u300D\u300E\u300F\u3010\u3011\u3012\u3013"+ + "\u3014\u3015\u3016\u3017\u3018\u3019\u301A\u301B"+ + "\u301C\u301D\u301E\u301F\u3020\u3021\u3022\u3023"+ + "\u3024\u3025\u3026\u3027\u3028\u3029\u302A\u302B"+ + "\u302C\u302D\u302E\u302F\u3030\u3031\u3032\u3033"+ + "\u3034\u3035\u3036\u3037\u3038\u3039\u303A\u303B"+ + "\u303C\u303D\u303E\u303F\u3040\u3041\u3042\u3043"+ + "\u3044\u3045\u3046\u3047\u3048\u3049\u304A\u304B"+ + "\u304C\u304D\u304E\u304F\u3050\u3051\u3052\u3053"+ + "\u3054\u3055\u3056\u3057\u3058\u3059\u305A\u305B"+ + "\u305C\u305D\u305E\u305F\u3060\u3061\u3062\u3063"+ + "\u3064\u3065\u3066\u3067\u3068\u3069\u306A\u306B"+ + "\u306C\u306D\u306E\u306F\u3070\u3071\u3072\u3073"+ + "\u3074\u3075\u3076\u3077\u3078\u3079\u307A\u307B"+ + "\u307C\u307D\u307E\u307F\u3080\u3081\u3082\u3083"+ + "\u3084\u3085\u3086\u3087\u3088\u3089\u308A\u308B"+ + "\u308C\u308D\u308E\u308F\u3090\u3091\u3092\u3093"+ + "\u3094\u3095\u3096\u3097\u3098\u3099\u309A\u309B"+ + "\u309C\u309D\u309E\u309F\u30A0\u30A1\u30A2\u30A3"+ + "\u30A4\u30A5\u30A6\u30A7\u30A8\u30A9\u30AA\u30AB"+ + "\u30AC\u30AD\u30AE\u30AF\u30B0\u30B1\u30B2\u30B3"+ + "\u30B4\u30B5\u30B6\u30B7\u30B8\u30B9\u30BA\u30BB"+ + "\u30BC\u30BD\u30BE\u30BF\u30C0\u30C1\u30C2\u30C3"+ + "\u30C4\u30C5\u30C6\u30C7\u30C8\u30C9\u30CA\u30CB"+ + "\u30CC\u30CD\u30CE\u30CF\u30D0\u30D1\u30D2\u30D3"+ + "\u30D4\u30D5\u30D6\u30D7\u30D8\u30D9\u30DA\u30DB"+ + "\u30DC\u30DD\u30DE\u30DF\u30E0\u30E1\u30E2\u30E3"+ + "\u30E4\u30E5\u30E6\u30E7\u30E8\u30E9\u30EA\u30EB"+ + "\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007"+ + "\u2008\u2009\u200A\u200B\u200C\u200D\u200E\u200F"+ + "\u2010\u2011\u2012\u2013\u2014\u2015\u2016\u2017"+ + "\u2018\u2019\u201A\u201B\u201C\u201D\u201E\u201F"+ + "\u2020\u2021\u2022\u2023\u2024\u2025\u2026\u2027"+ + "\u2028\u2029\u202A\u202B\uFD9C\u202C\u202D\u202E"+ + "\u202F\u2030\u2031\u2032\u2033\u2034\u2035\u2036"+ + "\u2037\u2038\u2039\u203A\u203B\u203C\u203D\u203E"+ + "\u203F\u2040\u2041\u2042\u2043\u2044\u2045\u2046"+ + "\u2047\u2048\u2049\u204A\u204B\u204C\u204D\u204E"+ + "\u204F\u2050\u2051\u2052\u2053\u2054\u2055\u2056"+ + "\u2057\u2058\u2059\u205A\u205B\u205C\u205D\u205E"+ + "\u205F\u2060\u2061\u2062\u2063\u2064\u2065\u2066"+ + "\u2067\u2068\u2069\u206A\u206B\u206C\u206D\u206E"+ + "\u206F\u2070\u2071\u2072\u2073\u2074\u2075\u2076"+ + "\u2077\uFD9D\u2078\u2079\u207A\u207B\u207C\u207D"+ + "\u207E\u207F\u2080\u2081\u2082\u2083\u2084\u2085"+ + "\u2086\u2087\u2088\u2089\u208A\u208B\u208C\u208D"+ + "\u208E\u208F\u2090\u2091\u2092\uFD9E\u2093\u2094"+ + "\u2095\u2096\u2097\u2098\u2099\u209A\u209B\u209C"+ + "\u209D\u209E\u209F\u20A0\u20A1\u20A2\u20A3\u20A4"+ + "\u20A5\u20A6\u20A7\u20A8\u20A9\u20AA\u20AB\u20AC"+ + "\u20AD\u20AE\u20AF\u20B0\u20B1\u20B2\u20B3\u20B4"+ + "\u20B5\u20B6\u20B7\u20B8\u20B9\u20BA\u20BB\u20BC"+ + "\u20BD\u20BE\u20BF\u20C0\u20C1\u20C2\u20C3\u20C4"+ + "\u20C5\u20C6\u20C7\u20C8\u20C9\u20CA\u20CB\u20CC"+ + "\u20CD\u20CE\u20CF\u20D0\u20D1\u20D2\u20D3\u20D4"+ + "\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB\u20DC"+ + "\u20DD\u20DE\u20DF\u20E0\u20E1\u20E2\u20E3\uFD9F"+ + "\u20E4\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB"+ + "\u20EC\uFDA0\u20ED\u20EE\u20EF\u20F0\u20F1\u20F2"+ + "\u20F3\u20F4\u20F5\u20F6\u20F7\u20F8\u20F9\u20FA"+ + "\u20FB\u20FC\u20FD\u20FE\u20FF\u2100\u2101\u2102"+ + "\u2103\u2104\u2105\u2106\uFE40\uFE41\uFE42\uFE43"+ + "\u2107\uFE44\u2108\uFE45\uFE46\u2109\u210A\u210B"+ + "\uFE47\u210C\u210D\u210E\u210F\u2110\u2111\uFE48"+ + "\uFE49\uFE4A\u2112\uFE4B\uFE4C\u2113\u2114\uFE4D"+ + "\uFE4E\uFE4F\u2115\u2116\u2117\u2118\u2119\u211A"+ + "\u211B\u211C\u211D\u211E\u211F\u2120\u2121\u2122"+ + "\u2123\u2124\u2125\u2126\u2127\u2128\u2129\u212A"+ + "\u212B\u212C\u212D\u212E\u212F\u2130\u2131\u2132"+ + "\u2133\u2134\u2135\u2136\u2137\u2138\u2139\u213A"+ + "\u213B\u213C\u213D\u213E\u213F\u2140\u2141\u2142"+ + "\u2143\u2144\u2145\u2146\u2147\u2148\u2149\u214A"+ + "\u214B\u214C\u214D\u214E\u214F\u2150\u2151\u2152"+ + "\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215A"+ + "\u215B\u215C\u215D\u215E\u215F\u2160\u2161\u2162"+ + "\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216A"+ + "\u216B\u216C\u216D\u216E\u216F\u2170\u2171\u2172"+ + "\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217A"+ + "\u217B\u217C\u217D\u217E\u217F\u2180\u2181\u2182"+ + "\u2183\u2184\u2185\u2186\u2187\u2188\u2189\u218A"+ + "\u218B\u218C\u218D\u218E\u218F\u2190\u2191\u2192"+ + "\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u219A"+ + "\u219B\u219C\u219D\u219E\u219F\u21A0\u21A1\u21A2"+ + "\u21A3\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9\u21AA"+ + "\u21AB\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1\u21B2"+ + "\u21B3\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9\u21BA"+ + "\u21BB\u21BC\u21BD\u21BE\u21BF\u21C0\u21C1\u21C2"+ + "\u21C3\u21C4\u21C5\u21C6\u21C7\u21C8\u21C9\u21CA"+ + "\u21CB\u21CC\u21CD\u21CE\u21CF\u21D0\u21D1\u21D2"+ + "\u21D3\u21D4\u21D5\u21D6\u21D7\u21D8\u21D9\u21DA"+ + "\u21DB\u21DC\u21DD\u21DE\u21DF\u21E0\u21E1\u21E2"+ + "\u21E3\u21E4\u21E5\u21E6\u21E7\u21E8\u21E9\u21EA"; + + private static final String innerEncoderIndex12= + "\u21EB\u21EC\u21ED\u21EE\u21EF\u21F0\u21F1\u21F2"+ + "\u21F3\u21F4\u21F5\u21F6\u21F7\u21F8\u21F9\u21FA"+ + "\u21FB\u21FC\u21FD\u21FE\u21FF\u2200\u2201\u2202"+ + "\u2203\u2204\u2205\u2206\u2207\u2208\u2209\u220A"+ + "\u220B\u220C\u220D\u220E\u220F\u2210\u2211\u2212"+ + "\u2213\u2214\u2215\u2216\u2217\u2218\u2219\u221A"+ + "\u221B\u221C\u221D\u221E\u221F\u2220\u2221\u2222"+ + "\u2223\u2224\u2225\u2226\u2227\u2228\u2229\u222A"+ + "\u222B\u222C\u222D\u222E\u222F\u2230\u2231\u2232"+ + "\u2233\u2234\u2235\u2236\u2237\u2238\u2239\u223A"+ + "\u223B\u223C\u223D\u223E\u223F\u2240\u2241\u2242"+ + "\u2243\u2244\u2245\u2246\u2247\u2248\u2249\u224A"+ + "\u224B\u224C\u224D\u224E\u224F\u2250\u2251\u2252"+ + "\u2253\u2254\u2255\u2256\u2257\u2258\u2259\u225A"+ + "\u225B\u225C\u225D\u225E\u225F\u2260\u2261\u2262"+ + "\u2263\u2264\u2265\u2266\u2267\u2268\u2269\u226A"+ + "\u226B\u226C\u226D\u226E\u226F\u2270\u2271\u2272"+ + "\u2273\u2274\u2275\u2276\u2277\u2278\u2279\u227A"+ + "\u227B\u227C\u227D\u227E\u227F\u2280\u2281\u2282"+ + "\u2283\u2284\u2285\u2286\u2287\u2288\u2289\u228A"+ + "\u228B\u228C\u228D\u228E\u228F\u2290\u2291\u2292"+ + "\u2293\u2294\u2295\u2296\u2297\u2298\u2299\u229A"+ + "\u229B\u229C\u229D\u229E\u229F\u22A0\u22A1\u22A2"+ + "\u22A3\u22A4\u22A5\u22A6\u22A7\u22A8\u22A9\u22AA"+ + "\u22AB\u22AC\u22AD\u22AE\u22AF\u22B0\u22B1\u22B2"+ + "\u22B3\u22B4\u22B5\u22B6\u22B7\u22B8\u22B9\u22BA"+ + "\u22BB\u22BC\u22BD\u22BE\u22BF\u22C0\u22C1\u22C2"+ + "\u22C3\u22C4\u22C5\u22C6\u22C7\u22C8\u22C9\u22CA"+ + "\u22CB\u22CC\u22CD\u22CE\u22CF\u22D0\u22D1\u22D2"+ + "\u22D3\u22D4\u22D5\u22D6\u22D7\u22D8\u22D9\u22DA"+ + "\u22DB\u22DC\u22DD\u22DE\u22DF\u22E0\u22E1\u22E2"+ + "\u22E3\u22E4\u22E5\u22E6\u22E7\u22E8\u22E9\u22EA"+ + "\u22EB\u22EC\u22ED\u22EE\u22EF\u22F0\u22F1\u22F2"+ + "\u22F3\u22F4\u22F5\u22F6\u22F7\u22F8\u22F9\u22FA"+ + "\u22FB\u22FC\u22FD\u22FE\u22FF\u2300\u2301\u2302"+ + "\u2303\u2304\u2305\u2306\u2307\u2308\u2309\u230A"+ + "\u230B\u230C\u230D\u230E\u230F\u2310\u2311\u2312"+ + "\u2313\u2314\u2315\u2316\u2317\u2318\u2319\u231A"+ + "\u231B\u231C\u231D\u231E\u231F\u2320\u2321\u2322"+ + "\u2323\u2324\u2325\u2326\u2327\u2328\u2329\u232A"+ + "\u232B\u232C\u232D\u232E\u232F\u2330\u2331\u2332"+ + "\u2333\u2334\u2335\u2336\u2337\u2338\u2339\u233A"+ + "\u233B\u233C\u233D\u233E\u233F\u2340\u2341\u2342"+ + "\u2343\u2344\u2345\u2346\u2347\u2348\u2349\u234A"+ + "\u234B\u234C\u234D\u234E\u234F\u2350\u2351\u2352"+ + "\u2353\u2354\u2355\u2356\u2357\u2358\u2359\u235A"+ + "\u235B\u235C\u235D\u235E\u235F\u2360\u2361\u2362"+ + "\u2363\u2364\u2365\u2366\u2367\u2368\u2369\u236A"+ + "\u236B\u236C\u236D\u236E\u236F\u2370\u2371\u2372"+ + "\u2373\u2374\u2375\u2376\u2377\u2378\u2379\u237A"+ + "\u237B\u237C\u237D\u237E\u237F\u2380\u2381\u2382"+ + "\u2383\u2384\u2385\u2386\u2387\u2388\u2389\u238A"+ + "\u238B\u238C\u238D\u238E\u238F\u2390\u2391\u2392"+ + "\u2393\u2394\u2395\u2396\u2397\u2398\u2399\u239A"+ + "\u239B\u239C\u239D\u239E\u239F\u23A0\u23A1\u23A2"+ + "\u23A3\u23A4\u23A5\u23A6\u23A7\u23A8\u23A9\u23AA"+ + "\u23AB\u23AC\u23AD\u23AE\u23AF\u23B0\u23B1\u23B2"+ + "\u23B3\u23B4\u23B5\u23B6\u23B7\u23B8\u23B9\u23BA"+ + "\u23BB\u23BC\u23BD\u23BE\u23BF\u23C0\u23C1\u23C2"+ + "\u23C3\u23C4\u23C5\u23C6\u23C7\u23C8\u23C9\u23CA"+ + "\u23CB\u23CC\u23CD\u23CE\u23CF\u23D0\u23D1\u23D2"+ + "\u23D3\u23D4\u23D5\u23D6\u23D7\u23D8\u23D9\u23DA"+ + "\u23DB\u23DC\u23DD\u23DE\u23DF\u23E0\u23E1\u23E2"+ + "\u23E3\u23E4\u23E5\u23E6\u23E7\u23E8\u23E9\u23EA"+ + "\u23EB\u23EC\u23ED\u23EE\u23EF\u23F0\u23F1\u23F2"+ + "\u23F3\u23F4\u23F5\u23F6\u23F7\u23F8\u23F9\u23FA"+ + "\u23FB\u23FC\u23FD\u23FE\u23FF\u2400\u2401\u2402"+ + "\u2403\u2404\u2405\u2406\u2407\u2408\u2409\u240A"+ + "\u240B\u240C\u240D\u240E\u240F\u2410\u2411\u2412"+ + "\u2413\u2414\u2415\u2416\u2417\u2418\u2419\u241A"+ + "\u241B\u241C\u241D\u241E\u241F\u2420\u2421\u2422"+ + "\u2423\u2424\u2425\u2426\u2427\u2428\u2429\u242A"+ + "\u242B\u242C\u242D\u242E\u242F\u2430\u2431\u2432"+ + "\u2433\u2434\u2435\u2436\u2437\u2438\u2439\u243A"+ + "\u243B\u243C\u243D\u243E\u243F\u2440\u2441\u2442"+ + "\u2443\u2444\u2445\u2446\u2447\u2448\u2449\u244A"+ + "\u244B\u244C\u244D\u244E\u244F\u2450\u2451\u2452"+ + "\u2453\u2454\u2455\u2456\u2457\u2458\u2459\u245A"+ + "\u245B\u245C\u245D\u245E\u245F\u2460\u2461\u2462"+ + "\u2463\u2464\u2465\u2466\u2467\u2468\u2469\u246A"+ + "\u246B\u246C\u246D\u246E\u246F\u2470\u2471\u2472"+ + "\u2473\u2474\u2475\u2476\u2477\u2478\u2479\u247A"+ + "\u247B\u247C\u247D\u247E\u247F\u2480\u2481\u2482"+ + "\u2483\u2484\u2485\u2486\u2487\u2488\u2489\u248A"+ + "\u248B\u248C\u248D\u248E\u248F\u2490\u2491\u2492"+ + "\u2493\u2494\u2495\u2496\u2497\u2498\u2499\u249A"+ + "\u249B\u249C\u249D\u249E\u249F\u24A0\u24A1\u24A2"+ + "\u24A3\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9\u24AA"+ + "\u24AB\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1\u24B2"+ + "\u24B3\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9\u24BA"+ + "\u24BB\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1\u24C2"+ + "\u24C3\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9\u24CA"+ + "\u24CB\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1\u24D2"+ + "\u24D3\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9\u24DA"+ + "\u24DB\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1\u24E2"+ + "\u24E3\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9\u24EA"+ + "\u24EB\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1\u24F2"+ + "\u24F3\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9\u24FA"+ + (IS_2000 ? "\u24FB\u24FC\u24FD\u24FE\u24FF\u2500\u2501\u2502"+ + "\u2503\u2504\u2505\u2506\u2507\u2508\u2509\u250A" : + "\uA6D9\uA6DB\uA6DA\uA6DC\uA6DD\uA6DE\uA6DF\uA6EC"+ + "\uA6ED\uA6F3\u2505\u2506\u2507\u2508\u2509\u250A")+ + "\u250B\u250C\u250D\u250E\u250F\u2510\u2511\u2512"+ + "\u2513\u2514\u2515\u2516\u2517\u2518\u2519\u251A"+ + "\uA955\uA6F2\u251B\uA6F4\uA6F5\uA6E0\uA6E1\uA6F0"+ + "\uA6F1\uA6E2\uA6E3\uA6EE\uA6EF\uA6E6\uA6E7\uA6E4"+ + "\uA6E5\uA6E8\uA6E9\uA6EA\uA6EB\u251C\u251D\u251E"+ + "\u251F\uA968\uA969\uA96A\uA96B\uA96C\uA96D\uA96E"+ + "\uA96F\uA970\uA971\u2520\uA972\uA973\uA974\uA975"+ + "\u2521\uA976\uA977\uA978\uA979\uA97A\uA97B\uA97C"+ + "\uA97D\uA97E\uA980\uA981\uA982\uA983\uA984\u2522"+ + "\uA985\uA986\uA987\uA988\u2523\u2524\u2525\u2526"+ + "\u2527\u2528\u2529\u252A\u252B\u252C\u252D\u252E"+ + "\u252F\u2530\u2531\u2532\u2533\u2534\u2535\u2536"+ + "\u2537\u2538\u2539\u253A\u253B\u253C\u253D\u253E"+ + "\u253F\u2540\u2541\u2542\u2543\u2544\u2545\u2546"+ + "\u2547\u2548\u2549\u254A\u254B\u254C\u254D\u254E"+ + "\u254F\u2550\u2551\u2552\u2553\u2554\u2555\u2556"+ + "\u2557\u2558\u2559\u255A\u255B\u255C\u255D\u255E"+ + "\u255F\u2560\u2561\u2562\u2563\u2564\u2565\u2566"+ + "\u2567\u2568\u2569\u256A\u256B\u256C\u256D\u256E"+ + "\u256F\u2570\u2571\u2572\u2573\u2574\u2575\u2576"+ + "\u2577\u2578\u2579\u257A\u257B\u257C\u257D\u257E"+ + "\u257F\u2580\u2581\u2582\u2583\u2584\u2585\u2586"+ + "\u2587\u2588\u2589\u258A\u258B\u258C\u258D\u258E"+ + "\u258F\u2590\u2591\u2592\u2593\u2594\u2595\u2596"+ + "\u2597\u2598\u2599\u259A\u259B\u259C\u259D\u259E"+ + "\u259F\u25A0\u25A1\u25A2\u25A3\u25A4\u25A5\u25A6"+ + "\u25A7\u25A8\u25A9\u25AA\u25AB\u25AC\u25AD\u25AE"+ + "\u25AF\u25B0\u25B1\u25B2\u25B3\u25B4\u25B5\u25B6"+ + "\u25B7\uA3A1\uA3A2\uA3A3\uA1E7\uA3A5\uA3A6\uA3A7"+ + "\uA3A8\uA3A9\uA3AA\uA3AB\uA3AC\uA3AD\uA3AE\uA3AF"+ + "\uA3B0\uA3B1\uA3B2\uA3B3\uA3B4\uA3B5\uA3B6\uA3B7"+ + "\uA3B8\uA3B9\uA3BA\uA3BB\uA3BC\uA3BD\uA3BE\uA3BF"+ + "\uA3C0\uA3C1\uA3C2\uA3C3\uA3C4\uA3C5\uA3C6\uA3C7"+ + "\uA3C8\uA3C9\uA3CA\uA3CB\uA3CC\uA3CD\uA3CE\uA3CF"+ + "\uA3D0\uA3D1\uA3D2\uA3D3\uA3D4\uA3D5\uA3D6\uA3D7"+ + "\uA3D8\uA3D9\uA3DA\uA3DB\uA3DC\uA3DD\uA3DE\uA3DF"+ + "\uA3E0\uA3E1\uA3E2\uA3E3\uA3E4\uA3E5\uA3E6\uA3E7"+ + "\uA3E8\uA3E9\uA3EA\uA3EB\uA3EC\uA3ED\uA3EE\uA3EF"+ + "\uA3F0\uA3F1\uA3F2\uA3F3\uA3F4\uA3F5\uA3F6\uA3F7"+ + "\uA3F8\uA3F9\uA3FA\uA3FB\uA3FC\uA3FD\uA1AB\u25B8"+ + "\u25B9\u25BA\u25BB\u25BC\u25BD\u25BE\u25BF\u25C0"+ + "\u25C1\u25C2\u25C3\u25C4\u25C5\u25C6\u25C7\u25C8"+ + "\u25C9\u25CA\u25CB\u25CC\u25CD\u25CE\u25CF\u25D0"+ + "\u25D1\u25D2\u25D3\u25D4\u25D5\u25D6\u25D7\u25D8"+ + "\u25D9\u25DA\u25DB\u25DC\u25DD\u25DE\u25DF\u25E0"+ + "\u25E1\u25E2\u25E3\u25E4\u25E5\u25E6\u25E7\u25E8"+ + "\u25E9\u25EA\u25EB\u25EC\u25ED\u25EE\u25EF\u25F0"+ + "\u25F1\u25F2\u25F3\u25F4\u25F5\u25F6\u25F7\u25F8"+ + "\u25F9\u25FA\u25FB\u25FC\u25FD\u25FE\u25FF\u2600"+ + "\u2601\u2602\u2603\u2604\u2605\u2606\u2607\u2608"+ + "\u2609\u260A\u260B\u260C\u260D\u260E\u260F\u2610"+ + "\u2611\u2612\u2613\u2614\u2615\u2616\u2617\u2618"+ + "\u2619\u261A\u261B\u261C\u261D\u261E\u261F\u2620"+ + "\u2621\u2622\u2623\u2624\u2625\u2626\u2627\u2628"+ + "\u2629\u262A\u262B\u262C\u262D\u262E\u262F\u2630"+ + "\u2631\u2632\u2633\u2634\u2635\u2636\u2637\u2638"+ + "\uA1E9\uA1EA\uA956\uA3FE\uA957\uA3A4\u2639\u263A"+ + "\u263B\u263C\u263D\u263E\u263F\u2640\u2641\u2642"+ + "\u2643\u2644\u2645\u2646\u2647\u2648\u2649\u264A"+ + "\u264B\u264C\u264D\u264E\u264F\u2650\u2651\u2652"; + + private static final short encoderIndex1[] = { + 0, 1, 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, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 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, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 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, 158, 159, + 160, 161, 162, 163, 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, 0, 0, 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, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196 + }; + + static String encoderIndex2[] = { + innerEncoderIndex0, + innerEncoderIndex1, + innerEncoderIndex2, + innerEncoderIndex3, + innerEncoderIndex4, + innerEncoderIndex5, + innerEncoderIndex6, + innerEncoderIndex7, + innerEncoderIndex8, + innerEncoderIndex9, + innerEncoderIndex10, + innerEncoderIndex11, + innerEncoderIndex12 + }; + private static class Decoder extends CharsetDecoder { + + private static final char REPLACE_CHAR = '\uFFFD'; + private int currentState = GB18030_DOUBLE_BYTE; + + private Decoder(Charset cs) { + super(cs, 1.0f, 2.0f); + } + + private char getChar(int offset) { + int byte1 = (offset >>8) & 0xFF; + int byte2 = (offset & 0xFF); + int start = 0, end = 0xFF; + + if (((byte1 < 0) || (byte1 > decoderIndex1.length)) + || ((byte2 < start) || (byte2 > end))) { + return REPLACE_CHAR; + } + + int n = (decoderIndex1[byte1] & 0xf) * (end - start + 1) + (byte2 - start); + return decoderIndex2[decoderIndex1[byte1] >> 4].charAt(n); + } + + protected char decodeDouble(int byte1, int byte2) { + int start = 0x40, end = 0xFE; + if (((byte1 < 0) || (byte1 > index1.length)) + || ((byte2 < start) || (byte2 > end))) + return '\uFFFD'; + + int n = (index1[byte1] & 0xf) * (end - start + 1) + (byte2 - start); + return index2[index1[byte1] >> 4].charAt(n); + } + + protected void implReset() { + currentState = GB18030_DOUBLE_BYTE; + } + + private CoderResult decodeArrayLoop(ByteBuffer src, + CharBuffer dst) + { + byte[] sa = src.array(); + int sp = src.arrayOffset() + src.position(); + int sl = src.arrayOffset() + src.limit(); + + char[] da = dst.array(); + int dp = dst.arrayOffset() + dst.position(); + int dl = dst.arrayOffset() + dst.limit(); + + int inputSize = 1; + + try { + while (sp < sl) { + int byte1 = 0 , byte2 = 0, byte3 = 0, byte4 = 0; + // Get the input byte + byte1 = sa[sp] & 0xFF; + inputSize = 1; + + if ((byte1 & (byte)0x80) == 0){ // US-ASCII range + currentState = GB18030_SINGLE_BYTE; + } + else if (byte1 < 0x81 || byte1 > 0xfe) { + return CoderResult.malformedForLength(1); + } + else { // Either 2 or 4 byte sequence follows + if ( sl - sp < 2 ) + return CoderResult.UNDERFLOW; + byte2 = sa[sp + 1] & 0xFF; + inputSize = 2; + + if (byte2 < 0x30) + return CoderResult.malformedForLength(1); + else if (byte2 >= 0x30 && byte2 <= 0x39) { + currentState = GB18030_FOUR_BYTE; + + if (sl - sp < 4) + return CoderResult.UNDERFLOW; + + byte3 = sa[sp + 2] & 0xFF; + if (byte3 < 0x81 || byte3 > 0xfe) + return CoderResult.malformedForLength(3); + + byte4 = sa[sp + 3] & 0xFF; + inputSize = 4; + + if (byte4 < 0x30 || byte4 > 0x39) + return CoderResult.malformedForLength(4); + } + else if (byte2 == 0x7f || byte2 == 0xff || + (byte2 < 0x40 )) { + return CoderResult.malformedForLength(2); + } + else + currentState = GB18030_DOUBLE_BYTE; + } + + if (dl - dp < 1) + return CoderResult.OVERFLOW; + switch (currentState){ + case GB18030_SINGLE_BYTE: + da[dp++] = (char)byte1; + break; + case GB18030_DOUBLE_BYTE: + da[dp++] = decodeDouble(byte1, byte2); + break; + case GB18030_FOUR_BYTE: + int offset = (((byte1 - 0x81) * 10 + + (byte2 - 0x30)) * 126 + + byte3 - 0x81) * 10 + byte4 - 0x30; + int hiByte = (offset >>8) & 0xFF; + int lowByte = (offset & 0xFF); + + // Mixture of table lookups and algorithmic calculation + // of character values. + + // BMP Ranges + if (offset <= 0x4A62) + da[dp++] = getChar(offset); + else if (offset > 0x4A62 && offset <= 0x82BC) { + if (offset >= 0x4A71 && offset <= 0x4A78 && !IS_2000) { + da[dp++] = getChar(offset); + } else { + da[dp++] = (char)(offset + 0x5543); + } + } + else if (offset >= 0x82BD && offset <= 0x830D) + da[dp++] = getChar(offset); + else if (offset >= 0x830D && offset <= 0x93A8) + da[dp++] = (char)(offset + 0x6557); + else if (offset >= 0x93A9 && offset <= 0x99FB) + da[dp++] = getChar(offset); + // Supplemental UCS planes handled via surrogates + else if (offset >= 0x2E248 && offset < 0x12E248) { + if (offset >= 0x12E248) + return CoderResult.malformedForLength(4); + offset -= 0x1e248; + if ( dl - dp < 2) + return CoderResult.OVERFLOW; + // emit high + low surrogate + da[dp++] = (char)((offset - 0x10000) / 0x400 + 0xD800); + da[dp++] = (char)((offset - 0x10000) % 0x400 + 0xDC00); + } + else + return CoderResult.malformedForLength(inputSize); + break; + } + sp += inputSize; + } + return CoderResult.UNDERFLOW; + } finally { + src.position(sp - src.arrayOffset()); + dst.position(dp - dst.arrayOffset()); + } + } + + private CoderResult decodeBufferLoop(ByteBuffer src, + CharBuffer dst) + { + int mark = src.position(); + + try { + while (src.hasRemaining()) { + int byte1 = 0, byte2 = 0, byte3 = 0, byte4 = 0; + byte1 = src.get() & 0xFF; + int inputSize = 1; + + if ((byte1 & (byte)0x80) == 0){ // US-ASCII range + currentState = GB18030_SINGLE_BYTE; + } + else if (byte1 < 0x81 || byte1 > 0xfe) { + return CoderResult.malformedForLength(1); + } + else { // Either 2 or 4 byte sequence follows + if ( src.remaining() < 1 ) + return CoderResult.UNDERFLOW; + byte2 = src.get() & 0xFF; + inputSize = 2; + + if (byte2 < 0x30) + return CoderResult.malformedForLength(1); + else if (byte2 >= 0x30 && byte2 <= 0x39) { + currentState = GB18030_FOUR_BYTE; + + if (src.remaining() < 2) + return CoderResult.UNDERFLOW; + + byte3 = src.get() & 0xFF; + if (byte3 < 0x81 || byte3 > 0xfe) + return CoderResult.malformedForLength(3); + + byte4 = src.get() & 0xFF; + inputSize = 4; + + if (byte4 < 0x30 || byte4 > 0x39) + return CoderResult.malformedForLength(4); + } + else if (byte2 == 0x7f || byte2 == 0xff || + (byte2 < 0x40 )) { + return CoderResult.malformedForLength(2); + } + else + currentState = GB18030_DOUBLE_BYTE; + } + + if (dst.remaining() < 1) + return CoderResult.OVERFLOW; + switch (currentState){ + case GB18030_SINGLE_BYTE: + dst.put((char)byte1); + break; + case GB18030_DOUBLE_BYTE: + dst.put(decodeDouble(byte1, byte2)); + break; + case GB18030_FOUR_BYTE: + int offset = (((byte1 - 0x81) * 10 + + (byte2 - 0x30)) * 126 + + byte3 - 0x81) * 10 + byte4 - 0x30; + int hiByte = (offset >>8) & 0xFF; + int lowByte = (offset & 0xFF); + + // Mixture of table lookups and algorithmic calculation + // of character values. + + // BMP Ranges + if (offset <= 0x4A62) + dst.put(getChar(offset)); + else if (offset > 0x4A62 && offset <= 0x82BC) { + if (offset >= 0x4A71 && offset <= 0x4A78 && !IS_2000) { + dst.put(getChar(offset)); + } else { + dst.put((char)(offset + 0x5543)); + } + } + else if (offset >= 0x82BD && offset <= 0x830D) + dst.put(getChar(offset)); + else if (offset >= 0x830D && offset <= 0x93A8) + dst.put((char)(offset + 0x6557)); + else if (offset >= 0x93A9 && offset <= 0x99FB) + dst.put(getChar(offset)); + // Supplemental UCS planes handled via surrogates + else if (offset >= 0x2E248 && offset < 0x12E248) { + if (offset >= 0x12E248) + return CoderResult.malformedForLength(4); + offset -= 0x1e248; + if ( dst.remaining() < 2) + return CoderResult.OVERFLOW; + // emit high + low surrogate + dst.put((char)((offset - 0x10000) / 0x400 + 0xD800)); + dst.put((char)((offset - 0x10000) % 0x400 + 0xDC00)); + } else { + return CoderResult.malformedForLength(inputSize); + } + } + mark += inputSize; + } + return CoderResult.UNDERFLOW; + } finally { + src.position(mark); + } + } + + + protected CoderResult decodeLoop(ByteBuffer src, + CharBuffer dst) + { + if (src.hasArray() && dst.hasArray()) + return decodeArrayLoop(src, dst); + else + return decodeBufferLoop(src, dst); + } + } + + private static class Encoder extends CharsetEncoder { + + private int currentState = GB18030_DOUBLE_BYTE; + + private Encoder(Charset cs) { + super(cs, 4.0f, 4.0f); // max of 4 bytes per char + } + + public boolean canEncode(char c) { + return ! Character.isSurrogate(c); + } + + private final Surrogate.Parser sgp = new Surrogate.Parser(); + + private int getGB18030(short[] outerIndex, String[] innerEncoderIndex, + char ch) { + int offset = outerIndex[((ch & 0xff00) >> 8 )] << 8; + return innerEncoderIndex[offset >> 12].charAt((offset & 0xfff) + + (ch & 0xff)); + } + + protected void implReset() { + currentState = GB18030_DOUBLE_BYTE; + } + + private CoderResult encodeArrayLoop(CharBuffer src, + ByteBuffer dst) + { + char[] sa = src.array(); + int sp = src.arrayOffset() + src.position(); + int sl = src.arrayOffset() + src.limit(); + + byte[] da = dst.array(); + int dp = dst.arrayOffset() + dst.position(); + int dl = dst.arrayOffset() + dst.limit(); + + int condensedKey = 0; // expands to a four byte sequence + int hiByte = 0, loByte = 0; + currentState = GB18030_DOUBLE_BYTE; + + try { + while (sp < sl) { + int inputSize = 1; + char c = sa[sp]; + + if (Character.isSurrogate(c)) { + if ((condensedKey=sgp.parse(c, sa, sp, sl)) < 0) + return sgp.error(); + // Character.toCodePoint looks like + // (((high & 0x3ff) << 10) | (low & 0x3ff)) + 0x10000; + // so we add (0x2e248 - 0x10000) to get the "key". + condensedKey += 0x1E248; + currentState = GB18030_FOUR_BYTE; + inputSize = sgp.increment(); + } + else if (c >= 0x0000 && c <= 0x007F) { + currentState = GB18030_SINGLE_BYTE; + } + else if (c <= 0xA4C6 || c >= 0xE000) { + int outByteVal = getGB18030(encoderIndex1, + encoderIndex2, + c); + if (outByteVal == 0xFFFD ) + return CoderResult.unmappableForLength(1); + + hiByte = (outByteVal & 0xFF00) >> 8; + loByte = (outByteVal & 0xFF); + + condensedKey = (hiByte - 0x20) * 256 + loByte; + + if (c >= 0xE000 && c < 0xF900) { + if (IS_2000) { + condensedKey += 0x82BD; + } else { + condensedKey = switch (c) { + case 0xE7C7, 0xE81E, 0xE826, 0xE82B, 0xE82C, 0xE832, + 0xE843, 0xE854, 0xE864 -> condensedKey; + default -> condensedKey + 0x82BD; + }; + } + } + else if (c >= 0xF900) + condensedKey += 0x93A9; + + if (hiByte > 0x80) + currentState = GB18030_DOUBLE_BYTE; + else + currentState = GB18030_FOUR_BYTE; + } + else if (c >= 0xA4C7 && c <= 0xD7FF) { + condensedKey = c - 0x5543; + currentState = GB18030_FOUR_BYTE; + } + + switch(currentState) { + case GB18030_SINGLE_BYTE: + if (dl - dp < 1) + return CoderResult.OVERFLOW; + da[dp++] = (byte)c; + break; + + case GB18030_DOUBLE_BYTE: + if (dl - dp < 2) + return CoderResult.OVERFLOW; + da[dp++] = (byte)hiByte; + da[dp++] = (byte)loByte; + break; + + case GB18030_FOUR_BYTE: // Four Byte encoding + byte b1, b2, b3, b4; + + if (dl - dp < 4) + return CoderResult.OVERFLOW; + // Decompose the condensed key into its 4 byte equivalent + b4 = (byte)((condensedKey % 10) + 0x30); + condensedKey /= 10; + b3 = (byte)((condensedKey % 126) + 0x81); + condensedKey /= 126; + b2 = (byte)((condensedKey % 10) + 0x30); + b1 = (byte)((condensedKey / 10) + 0x81); + da[dp++] = b1; + da[dp++] = b2; + da[dp++] = b3; + da[dp++] = b4; + break; + default: + assert(false); + } + sp += inputSize; + } + return CoderResult.UNDERFLOW; + } finally { + src.position(sp - src.arrayOffset()); + dst.position(dp - dst.arrayOffset()); + } + } + + private CoderResult encodeBufferLoop(CharBuffer src, + ByteBuffer dst) + { + int condensedKey = 0; + int hiByte = 0, loByte = 0; + currentState = GB18030_DOUBLE_BYTE; + int mark = src.position(); + try { + while (src.hasRemaining()) { + char c = src.get(); + int inputSize = 1; + if (Character.isSurrogate(c)) { + if ((condensedKey = sgp.parse(c, src))<0) + return sgp.error(); + condensedKey += 0x1e248; + currentState = GB18030_FOUR_BYTE; + inputSize = 2; + } + else if (c >= 0x0000 && c <= 0x007F) { + currentState = GB18030_SINGLE_BYTE; + } + else if (c <= 0xA4C6 || c >= 0xE000) { + int outByteVal = getGB18030(encoderIndex1, + encoderIndex2, + c); + if (outByteVal == 0xFFFD ) + return CoderResult.unmappableForLength(1); + + hiByte = (outByteVal & 0xFF00) >> 8; + loByte = (outByteVal & 0xFF); + + condensedKey = (hiByte - 0x20) * 256 + loByte; + + if (c >= 0xE000 && c < 0xF900) { + if (IS_2000) { + condensedKey += 0x82BD; + } else { + condensedKey = switch (c) { + case 0xE7C7, 0xE81E, 0xE826, 0xE82B, 0xE82C, 0xE832, + 0xE843, 0xE854, 0xE864 -> condensedKey; + default -> condensedKey + 0x82BD; + }; + } + } + else if (c >= 0xF900) + condensedKey += 0x93A9; + + if (hiByte > 0x80) + currentState = GB18030_DOUBLE_BYTE; + else + currentState = GB18030_FOUR_BYTE; + } + else if (c >= 0xA4C7 && c <= 0xD7FF) { + condensedKey = c - 0x5543; + currentState = GB18030_FOUR_BYTE; + } + + if (currentState == GB18030_SINGLE_BYTE) { + if (dst.remaining() < 1) + return CoderResult.OVERFLOW; + dst.put((byte)c); + } else if (currentState == GB18030_DOUBLE_BYTE) { + if (dst.remaining() < 2) + return CoderResult.OVERFLOW; + dst.put((byte)hiByte); + dst.put((byte)loByte); + } + else { // Four Byte encoding + byte b1, b2, b3, b4; + + if (dst.remaining() < 4) + return CoderResult.OVERFLOW; + // Decompose the condensed key into its 4 byte equivalent + b4 = (byte)((condensedKey % 10) + 0x30); + condensedKey /= 10; + b3 = (byte)((condensedKey % 126) + 0x81); + condensedKey /= 126; + b2 = (byte)((condensedKey % 10) + 0x30); + b1 = (byte)((condensedKey / 10) + 0x81); + dst.put(b1); + dst.put(b2); + dst.put(b3); + dst.put(b4); + } + mark += inputSize; + } + return CoderResult.UNDERFLOW; + } finally { + src.position(mark); + } + } + protected CoderResult encodeLoop(CharBuffer src, + ByteBuffer dst) + { + if (src.hasArray() && dst.hasArray()) + return encodeArrayLoop(src, dst); + else + return encodeBufferLoop(src, dst); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, 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. * @@ -58,8 +58,13 @@ } private String canonicalize(String csn) { - String acn = aliasMap().get(csn); - return (acn != null) ? acn : csn; + if (csn.startsWith("gb18030-")) { + return csn.equals("gb18030-2022") && !GB18030.IS_2000 || + csn.equals("gb18030-2000") && GB18030.IS_2000 ? "gb18030" : csn; + } else { + String acn = aliasMap().get(csn); + return (acn != null) ? acn : csn; + } } private Map aliasMap() { diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/security/pkcs/PKCS7.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/security/pkcs/PKCS7.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/security/pkcs/PKCS7.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/security/pkcs/PKCS7.java 2023-07-05 07:11:54.000000000 +0000 @@ -37,6 +37,7 @@ import java.security.*; import java.util.function.Function; +import sun.security.jca.JCAUtil; import sun.security.provider.SHAKE256; import sun.security.timestamp.*; import sun.security.util.*; @@ -67,23 +68,6 @@ private Principal[] certIssuerNames; - /* - * Random number generator for creating nonce values - * (Lazy initialization) - */ - private static class SecureRandomHolder { - static final SecureRandom RANDOM; - static { - SecureRandom tmp = null; - try { - tmp = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - // should not happen - } - RANDOM = tmp; - } - } - /** * Unmarshals a PKCS7 block from its encoded form, parsing the * encoded bytes from the InputStream. @@ -1027,11 +1011,9 @@ } // Generate a nonce - BigInteger nonce = null; - if (SecureRandomHolder.RANDOM != null) { - nonce = new BigInteger(64, SecureRandomHolder.RANDOM); - tsQuery.setNonce(nonce); - } + BigInteger nonce = new BigInteger(64, JCAUtil.getDefSecureRandom()); + tsQuery.setNonce(nonce); + tsQuery.requestCertificate(true); TSResponse tsReply = tsa.generateTimestamp(tsQuery); diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -267,20 +267,23 @@ out.flush(); } - // Check the response - if (debug != null && - con.getResponseCode() != HttpURLConnection.HTTP_OK) { - debug.println("Received HTTP error: " + con.getResponseCode() - + " - " + con.getResponseMessage()); + // Check the response. Non-200 codes will generate an exception + // but path validation may complete successfully if revocation info + // can be obtained elsewhere (e.g. CRL). + int respCode = con.getResponseCode(); + if (respCode != HttpURLConnection.HTTP_OK) { + String msg = "Received HTTP error: " + respCode + " - " + + con.getResponseMessage(); + if (debug != null) { + debug.println(msg); + } + throw new IOException(msg); } int contentLength = con.getContentLength(); - if (contentLength == -1) { - contentLength = Integer.MAX_VALUE; - } - - return IOUtils.readExactlyNBytes(con.getInputStream(), - contentLength); + return (contentLength == -1) ? con.getInputStream().readAllBytes() : + IOUtils.readExactlyNBytes(con.getInputStream(), + contentLength); } finally { if (con != null) { con.disconnect(); diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,6 +52,7 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; +import sun.security.action.GetIntegerAction; import sun.security.jca.Providers; import sun.security.pkcs.PKCS7; import sun.security.pkcs.SignerInfo; @@ -97,6 +98,12 @@ /** ConstraintsParameters for checking disabled algorithms */ private JarConstraintsParameters params; + // the maximum allowed size in bytes for the signature-related files + public static final int MAX_SIG_FILE_SIZE = initializeMaxSigFileSize(); + + // The maximum size of array to allocate. Some VMs reserve some header words in an array. + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + /** * Create the named SignatureFileVerifier. * @@ -842,4 +849,24 @@ signerCache.add(cachedSigners); signers.put(name, cachedSigners); } + + private static int initializeMaxSigFileSize() { + /* + * System property "jdk.jar.maxSignatureFileSize" used to configure + * the maximum allowed number of bytes for the signature-related files + * in a JAR file. + */ + Integer tmp = GetIntegerAction.privilegedGetProperty( + "jdk.jar.maxSignatureFileSize", 8000000); + if (tmp < 0 || tmp > MAX_ARRAY_SIZE) { + if (debug != null) { + debug.println("Default signature file size 8000000 bytes " + + "is used as the specified size for the " + + "jdk.jar.maxSignatureFileSize system property " + + "is out of range: " + tmp); + } + tmp = 8000000; + } + return tmp; + } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java 2023-07-05 07:11:54.000000000 +0000 @@ -609,33 +609,16 @@ params[9] = toSTZTime[endRule.timeDefinition]; dstSavings = (startRule.offsetAfter - startRule.offsetBefore) * 1000; - // Note: known mismatching -> Asia/Amman + // Note: known mismatching -> Africa/Cairo // ZoneInfo : startDayOfWeek=5 <= Thursday - // startTime=86400000 <= 24 hours - // This: startDayOfWeek=6 - // startTime=0 - // Similar workaround needs to be applied to Africa/Cairo and - // its endDayOfWeek and endTime - // Below is the workarounds, it probably slows down everyone a little - if (params[2] == 6 && params[3] == 0 && - (zoneId.equals("Asia/Amman"))) { - params[2] = 5; - params[3] = 86400000; + // startTime=86400000 <= 24:00 + // This: startDayOfWeek=6 <= Friday + // startTime=0 <= 0:00 + if (zoneId.equals("Africa/Cairo") && + params[7] == Calendar.FRIDAY && params[8] == 0) { + params[7] = Calendar.THURSDAY; + params[8] = SECONDS_PER_DAY * 1000; } - // Additional check for startDayOfWeek=6 and starTime=86400000 - // is needed for Asia/Amman; - if (params[2] == 7 && params[3] == 0 && - (zoneId.equals("Asia/Amman"))) { - params[2] = 6; // Friday - params[3] = 86400000; // 24h - } - //endDayOfWeek and endTime workaround - if (params[7] == 6 && params[8] == 0 && - (zoneId.equals("Africa/Cairo"))) { - params[7] = 5; - params[8] = 86400000; - } - } else if (nTrans > 0) { // only do this if there is something in table already if (lastyear < LASTYEAR) { // ZoneInfo has an ending entry for 2037 @@ -908,7 +891,6 @@ this.dow = dowByte == 0 ? -1 : dowByte; this.secondOfDay = timeByte == 31 ? in.readInt() : timeByte * 3600; this.timeDefinition = (data & (3 << 12)) >>> 12; - this.standardOffset = stdByte == 255 ? in.readInt() : (stdByte - 128) * 900; this.offsetBefore = beforeByte == 3 ? in.readInt() : standardOffset + beforeByte * 1800; this.offsetAfter = afterByte == 3 ? in.readInt() : standardOffset + afterByte * 1800; diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -238,6 +238,8 @@ return applyParentLocales(baseName, candidates); } + private static final Locale NB = Locale.forLanguageTag("nb"); + private static final Locale NO = Locale.forLanguageTag("no"); private List applyParentLocales(String baseName, List candidates) { // check irregular parents for (int i = 0; i < candidates.size(); i++) { @@ -247,11 +249,15 @@ if (p != null && !candidates.get(i+1).equals(p)) { List applied = candidates.subList(0, i+1); - if (applied.contains(p)) { - // avoid circular recursion (could happen with nb/no case) - continue; + // Tweak for Norwegian locales, CLDR switched the canonical form of + // Norwegian Bokmal language code from "nb" to "no" in CLDR 39 + // (https://unicode-org.atlassian.net/browse/CLDR-2698) + if (p.equals(NB) || p.equals(NO)) { + applied.add(NO); + applied.add(Locale.ROOT); + } else { + applied.addAll(applyParentLocales(baseName, super.getCandidateLocales(baseName, p))); } - applied.addAll(applyParentLocales(baseName, super.getCandidateLocales(baseName, p))); return applied; } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ } if (namesSuper != null) { - // CLDR's resource bundle has an translated entry for this id. + // CLDR's resource bundle has a translated entry for this id. // Fix up names if needed, either missing or no-inheritance namesSuper[INDEX_TZID] = id; @@ -91,7 +91,7 @@ case "": // Fill in empty elements deriveFallbackName(namesSuper, i, locale, - !TimeZone.getTimeZone(id).useDaylightTime()); + TimeZone.getTimeZone(id).toZoneId().getRules().isFixedOffset()); break; case NO_INHERITANCE_MARKER: // CLDR's "no inheritance marker" @@ -129,7 +129,7 @@ // Derive fallback time zone name according to LDML's logic private void deriveFallbackNames(String[] names, Locale locale) { - boolean noDST = !TimeZone.getTimeZone(names[0]).useDaylightTime(); + boolean noDST = TimeZone.getTimeZone(names[0]).toZoneId().getRules().isFixedOffset(); for (int i = INDEX_STD_LONG; i <= INDEX_GEN_SHORT; i++) { deriveFallbackName(names, i, locale, noDST); @@ -149,13 +149,12 @@ return; } - // Check parent locale first + // Check parent locales first if (!exists(names, index)) { - CLDRLocaleProviderAdapter clpa = (CLDRLocaleProviderAdapter)LocaleProviderAdapter.forType(Type.CLDR); - var cands = clpa.getCandidateLocales("", locale); - if (cands.size() > 1) { - var parentLoc = cands.get(1); // immediate parent locale - String[] parentNames = super.getDisplayNameArray(id, parentLoc); + var cands = ((CLDRLocaleProviderAdapter)LocaleProviderAdapter.forType(Type.CLDR)) + .getCandidateLocales("", locale); + for (int i = 1; i < cands.size() ; i++) { + String[] parentNames = super.getDisplayNameArray(id, cands.get(i)); if (parentNames != null && !parentNames[index].isEmpty()) { names[index] = parentNames[index]; return; @@ -163,18 +162,20 @@ } } + // Type Fallback + if (noDST && typeFallback(names, index)) { + return; + } + // Check if COMPAT can substitute the name - if (LocaleProviderAdapter.getAdapterPreference().contains(Type.JRE)) { + if (!exists(names, index) && + LocaleProviderAdapter.getAdapterPreference().contains(Type.JRE)) { String[] compatNames = (String[])LocaleProviderAdapter.forJRE() - .getLocaleResources(mapChineseLocale(locale)) - .getTimeZoneNames(id); + .getLocaleResources(mapChineseLocale(locale)) + .getTimeZoneNames(id); if (compatNames != null) { - for (int i = INDEX_STD_LONG; i <= INDEX_GEN_SHORT; i++) { - // Assumes COMPAT has no empty slots - if (i == index || !exists(names, i)) { - names[i] = compatNames[i]; - } - } + // Assumes COMPAT has no empty slots + names[index] = compatNames[index]; return; } } @@ -184,11 +185,6 @@ return; } - // Type Fallback - if (noDST && typeFallback(names, index)) { - return; - } - // last resort names[index] = toGMTFormat(id, index == INDEX_DST_LONG || index == INDEX_DST_SHORT, @@ -234,6 +230,11 @@ } private boolean regionFormatFallback(String[] names, int index, Locale l) { + if (index % 2 == 0) { + // ignore short names + return false; + } + String id = names[INDEX_TZID]; LocaleResources lr = LocaleProviderAdapter.forType(Type.CLDR).getLocaleResources(l); ResourceBundle fd = lr.getJavaTimeFormatData(); diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java --- openjdk-17-17.0.7+7~us1/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -845,9 +845,7 @@ {"Europe/Jersey", GMTBST}, {"Europe/Kaliningrad", EET}, {"Europe/Kiev", EET}, - {"Europe/Kirov", new String[] {"Kirov Standard Time", "GMT+03:00", - "Kirov Daylight Time", "GMT+03:00", - "Kirov Time", "GMT+03:00"}}, + {"Europe/Kirov", MSK}, {"Europe/Lisbon", WET}, {"Europe/Ljubljana", CET}, {"Europe/London", GMTBST}, diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/share/conf/security/java.security openjdk-17-17.0.8+7/src/java.base/share/conf/security/java.security --- openjdk-17-17.0.7+7~us1/src/java.base/share/conf/security/java.security 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/share/conf/security/java.security 2023-07-05 07:11:54.000000000 +0000 @@ -888,7 +888,8 @@ # Note: This property is currently used by OpenJDK's JSSE implementation. It # is not guaranteed to be examined and used by other implementations. # -jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37 +jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37, \ + ChaCha20-Poly1305 KeyUpdate 2^37 # # Cryptographic Jurisdiction Policy defaults diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java openjdk-17-17.0.8+7/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java --- openjdk-17-17.0.7+7~us1/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java 2023-07-05 07:11:54.000000000 +0000 @@ -75,10 +75,6 @@ int pos = 0; while (pos < len) { char c = p.charAt(pos++); - if ((c == '/') && (pos < len) && (p.charAt(pos) == '/')) { - // skip redundant slashes - continue; - } byte b; if (c == '%') { assert (pos+2) <= len; @@ -92,6 +88,10 @@ throw new IllegalArgumentException("Bad escape"); b = (byte)c; } + if (b == '/' && rlen > 0 && result[rlen-1] == '/') { + // skip redundant slashes + continue; + } result[rlen++] = b; } if (rlen != result.length) diff -Nru openjdk-17-17.0.7+7~us1/src/java.base/unix/native/libnio/ch/Net.c openjdk-17-17.0.8+7/src/java.base/unix/native/libnio/ch/Net.c --- openjdk-17-17.0.7+7~us1/src/java.base/unix/native/libnio/ch/Net.c 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.base/unix/native/libnio/ch/Net.c 2023-07-05 07:11:54.000000000 +0000 @@ -122,6 +122,51 @@ static jclass isa_class; /* java.net.InetSocketAddress */ static jmethodID isa_ctorID; /* InetSocketAddress(InetAddress, int) */ +static jint handleSocketErrorWithMessage(JNIEnv *env, jint errorValue, + const char* message) +{ + char *xn; + switch (errorValue) { + case EINPROGRESS: /* Non-blocking connect */ + return 0; +#ifdef EPROTO + case EPROTO: + xn = JNU_JAVANETPKG "ProtocolException"; + break; +#endif + case ECONNREFUSED: + case ETIMEDOUT: + case ENOTCONN: + xn = JNU_JAVANETPKG "ConnectException"; + break; + + case EHOSTUNREACH: + xn = JNU_JAVANETPKG "NoRouteToHostException"; + break; + case EADDRINUSE: /* Fall through */ + case EADDRNOTAVAIL: + case EACCES: + xn = JNU_JAVANETPKG "BindException"; + break; + default: + xn = JNU_JAVANETPKG "SocketException"; + break; + } + errno = errorValue; + if (message == NULL) { + JNU_ThrowByNameWithLastError(env, xn, "NioSocketError"); + } else { + JNU_ThrowByNameWithMessageAndLastError(env, xn, message); + } + return IOS_THROWN; +} + +/* Declared in nio_util.h */ +jint handleSocketError(JNIEnv *env, jint errorValue) +{ + return handleSocketErrorWithMessage(env, errorValue, NULL); +} + JNIEXPORT void JNICALL Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz) { @@ -615,7 +660,7 @@ if (n < 0) { if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) return IOS_UNAVAILABLE; - handleSocketError(env, errno); + handleSocketErrorWithMessage(env, errno, "setsockopt failed"); } return 0; } @@ -692,7 +737,7 @@ if (n < 0) { if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) return IOS_UNAVAILABLE; - handleSocketError(env, errno); + handleSocketErrorWithMessage(env, errno, "setsockopt failed"); } return 0; } @@ -913,38 +958,3 @@ return convertReturnVal(env, n, JNI_FALSE); } -/* Declared in nio_util.h */ - -jint handleSocketError(JNIEnv *env, jint errorValue) -{ - char *xn; - switch (errorValue) { - case EINPROGRESS: /* Non-blocking connect */ - return 0; -#ifdef EPROTO - case EPROTO: - xn = JNU_JAVANETPKG "ProtocolException"; - break; -#endif - case ECONNREFUSED: - case ETIMEDOUT: - case ENOTCONN: - xn = JNU_JAVANETPKG "ConnectException"; - break; - - case EHOSTUNREACH: - xn = JNU_JAVANETPKG "NoRouteToHostException"; - break; - case EADDRINUSE: /* Fall through */ - case EADDRNOTAVAIL: - case EACCES: - xn = JNU_JAVANETPKG "BindException"; - break; - default: - xn = JNU_JAVANETPKG "SocketException"; - break; - } - errno = errorValue; - JNU_ThrowByNameWithLastError(env, xn, "NioSocketError"); - return IOS_THROWN; -} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java 2023-07-05 07:11:54.000000000 +0000 @@ -53,9 +53,13 @@ * * @since 1.4 */ -@SuppressWarnings("removal") public class FileManager { static { + loadOSXLibrary(); + } + + @SuppressWarnings("removal") + private static void loadOSXLibrary() { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { @@ -132,6 +136,7 @@ * @since 1.4 */ public static void setFileTypeAndCreator(String filename, int type, int creator) throws IOException { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(filename); @@ -146,6 +151,7 @@ * @since 1.4 */ public static void setFileType(String filename, int type) throws IOException { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(filename); @@ -160,6 +166,7 @@ * @since 1.4 */ public static void setFileCreator(String filename, int creator) throws IOException { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(filename); @@ -174,6 +181,7 @@ * @since 1.4 */ public static int getFileType(String filename) throws IOException { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(filename); @@ -188,6 +196,7 @@ * @since 1.4 */ public static int getFileCreator(String filename) throws IOException { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(filename); @@ -251,6 +260,7 @@ * @since 1.4 */ public static String findFolder(short domain, int folderType, boolean createIfNeeded) throws FileNotFoundException { + @SuppressWarnings("removal") final SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPermission(new RuntimePermission("canExamineFileSystem")); @@ -278,6 +288,7 @@ */ @Deprecated public static void openURL(String url) throws IOException { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPermission(new RuntimePermission("canOpenURLs")); @@ -329,6 +340,7 @@ private static native String getNativeResourceFromBundle(String resourceName, String subDirName, String type) throws FileNotFoundException; private static String getResourceFromBundle(String resourceName, String subDirName, String type) throws FileNotFoundException { + @SuppressWarnings("removal") final SecurityManager security = System.getSecurityManager(); if (security != null) security.checkPermission(new RuntimePermission("canReadBundle")); @@ -347,6 +359,7 @@ * @since Java for Mac OS X 10.5 Update 2 - 1.5 */ public static String getPathToApplicationBundle() { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) security.checkPermission(new RuntimePermission("canReadBundle")); return getNativePathToApplicationBundle(); @@ -368,6 +381,7 @@ if (file == null) throw new FileNotFoundException(); final String fileName = file.getAbsolutePath(); + @SuppressWarnings("removal") final SecurityManager security = System.getSecurityManager(); if (security != null) security.checkDelete(fileName); @@ -391,6 +405,7 @@ if (file == null || !file.exists()) throw new FileNotFoundException(); final String fileName = file.getAbsolutePath(); + @SuppressWarnings("removal") final SecurityManager security = System.getSecurityManager(); if (security != null) security.checkRead(fileName); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java 2023-07-05 07:11:54.000000000 +0000 @@ -34,7 +34,7 @@ import com.apple.laf.AquaUtils.RecyclableSingleton; -@SuppressWarnings({"removal","serial"}) // JDK implementation class +@SuppressWarnings("serial") // JDK implementation class class AquaFileView extends FileView { private static final boolean DEBUG = false; @@ -57,6 +57,11 @@ static final int kLSItemInfoExtensionIsHidden = 0x00100000; /* Item has a hidden extension*/ static { + loadOSXUILibrary(); + } + + @SuppressWarnings("removal") + private static void loadOSXUILibrary() { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java 2023-07-05 07:11:54.000000000 +0000 @@ -36,12 +36,17 @@ import sun.lwawt.LWToolkit; import sun.lwawt.macosx.*; -@SuppressWarnings({"removal","serial"}) // JDK implementation class +@SuppressWarnings("serial") // JDK implementation class final class ScreenMenu extends Menu implements ContainerListener, ComponentListener, ScreenMenuPropertyHandler { static { + loadAWTLibrary(); + } + + @SuppressWarnings("removal") + private static void loadAWTLibrary() { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java 2023-07-05 07:11:54.000000000 +0000 @@ -67,12 +67,16 @@ import sun.awt.AWTAccessor; import sun.lwawt.LWWindowPeer; -@SuppressWarnings("removal") class CAccessibility implements PropertyChangeListener { private static Set ignoredRoles; static { - // Need to load the native library for this code. + loadAWTLibrary(); + } + + @SuppressWarnings("removal") + private static void loadAWTLibrary() { + // Need to load the native library for this code. java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2023-07-05 07:11:54.000000000 +0000 @@ -131,7 +131,6 @@ /** * Mac OS X Cocoa-based AWT Toolkit. */ -@SuppressWarnings("removal") public final class LWCToolkit extends LWToolkit { // While it is possible to enumerate all mouse devices // and query them for the number of buttons, the code @@ -147,6 +146,7 @@ static { System.err.flush(); + @SuppressWarnings("removal") ResourceBundle platformResources = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { @Override @@ -176,20 +176,23 @@ if (!GraphicsEnvironment.isHeadless()) { initIDs(); } - inAWT = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - return !Boolean.parseBoolean(System.getProperty("javafx.embed.singleThread", "false")); - } - }); } /* * If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode * If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode */ - private static final boolean inAWT; + @SuppressWarnings("removal") + private static final boolean inAWT + = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Boolean run() { + return !Boolean.parseBoolean( + System.getProperty("javafx.embed.singleThread", "false")); + } + }); + @SuppressWarnings("removal") public LWCToolkit() { final String extraButtons = "sun.awt.enableExtraMouseButtons"; AccessController.doPrivileged((PrivilegedAction) () -> { @@ -248,6 +251,7 @@ } // This is only called from native code. + @SuppressWarnings("removal") static void systemColorsChanged() { EventQueue.invokeLater(() -> { AccessController.doPrivileged( (PrivilegedAction) () -> { @@ -586,6 +590,7 @@ private static final String APPKIT_THREAD_NAME = "AppKit Thread"; // Intended to be called from the LWCToolkit.m only. + @SuppressWarnings("removal") private static void installToolkitThreadInJava() { Thread.currentThread().setName(APPKIT_THREAD_NAME); AccessController.doPrivileged((PrivilegedAction) () -> { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m openjdk-17-17.0.8+7/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m --- openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m 2023-07-05 07:11:54.000000000 +0000 @@ -47,10 +47,6 @@ #define k_JAVA_ROBOT_WHEEL_COUNT 1 -#if !defined(kCGBitmapByteOrder32Host) -#define kCGBitmapByteOrder32Host 0 -#endif - // In OS X, left and right mouse button share the same click count. // That is, if one starts clicking the left button rapidly and then // switches to the right button, then the click count will continue @@ -355,7 +351,7 @@ 8, picWidth * sizeof(jint), picColorSpace, kCGBitmapByteOrder32Host | - kCGImageAlphaPremultipliedFirst); + kCGImageAlphaNoneSkipFirst); CGColorSpaceRelease(picColorSpace); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.h openjdk-17-17.0.8+7/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.h 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -29,14 +29,6 @@ #import #import "JNIUtilities.h" -// these flags are not defined on Tiger on PPC, so we need to make them a no-op -#if !defined(kCGBitmapByteOrder32Host) -#define kCGBitmapByteOrder32Host 0 -#endif -#if !defined(kCGBitmapByteOrder16Host) -#define kCGBitmapByteOrder16Host 0 -#endif - // NOTE : Modify the printSurfaceDataDiagnostics API if you change this enum enum SDRenderType { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java 2023-07-05 07:11:54.000000000 +0000 @@ -615,8 +615,10 @@ height = Math.abs(height); } - if (metadata.compression == BI_RGB) { - long imageDataSize = ((long)width * height * (bitsPerPixel / 8)); + if (metadata.compression == BI_RGB && + metadata.paletteSize == 0 && + metadata.bitsPerPixel >= 16) { + long imageDataSize = (((long)width * height * bitsPerPixel) / 8); if (imageDataSize > (bitmapFileSize - bitmapOffset)) { throw new IIOException(I18N.getString("BMPImageReader9")); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/java/awt/EventQueue.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/java/awt/EventQueue.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/java/awt/EventQueue.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/java/awt/EventQueue.java 2023-07-05 07:11:54.000000000 +0000 @@ -94,7 +94,6 @@ * * @since 1.1 */ -@SuppressWarnings("removal") public class EventQueue { private static final AtomicInteger threadInitNumber = new AtomicInteger(); @@ -192,8 +191,6 @@ return eventLog; } - private static boolean fxAppThreadIsDispatchThread; - static { AWTAccessor.setEventQueueAccessor( new AWTAccessor.EventQueueAccessor() { @@ -230,15 +227,16 @@ return eventQueue.getMostRecentEventTimeImpl(); } }); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - fxAppThreadIsDispatchThread = - "true".equals(System.getProperty("javafx.embed.singleThread")); - return null; - } - }); } + @SuppressWarnings("removal") + private static boolean fxAppThreadIsDispatchThread = + AccessController.doPrivileged(new PrivilegedAction() { + public Boolean run() { + return "true".equals(System.getProperty("javafx.embed.singleThread")); + } + }); + /** * Initializes a new instance of {@code EventQueue}. */ @@ -734,8 +732,11 @@ } }; + @SuppressWarnings("removal") final AccessControlContext stack = AccessController.getContext(); + @SuppressWarnings("removal") final AccessControlContext srcAcc = getAccessControlContextFrom(src); + @SuppressWarnings("removal") final AccessControlContext eventAcc = event.getAccessControlContext(); if (srcAcc == null) { javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc); @@ -750,6 +751,7 @@ } } + @SuppressWarnings("removal") private static AccessControlContext getAccessControlContextFrom(Object src) { return src instanceof Component ? ((Component)src).getAccessControlContext() : diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/java/awt/Font.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/java/awt/Font.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/java/awt/Font.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/java/awt/Font.java 2023-07-05 07:11:54.000000000 +0000 @@ -2633,8 +2633,10 @@ // quick check for simple text, assume GV ok to use if simple boolean simple = values == null || - (values.getKerning() == 0 && values.getLigatures() == 0 && - values.getBaselineTransform() == null); + (values.getKerning() == 0 + && values.getLigatures() == 0 + && values.getTracking() == 0 + && values.getBaselineTransform() == null); if (simple) { simple = ! FontUtilities.isComplexText(chars, beginIndex, limit); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/print/DocFlavor.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/print/DocFlavor.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/print/DocFlavor.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/print/DocFlavor.java 2023-07-05 07:11:54.000000000 +0000 @@ -385,7 +385,6 @@ * * @author Alan Kaminsky */ -@SuppressWarnings("removal") public class DocFlavor implements Serializable, Cloneable { /** @@ -405,13 +404,10 @@ * This is the charset for all the "HOST" pre-defined {@code DocFlavors} in * the executing VM. */ - public static final String hostEncoding; - - static { - hostEncoding = + @SuppressWarnings("removal") + public static final String hostEncoding = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("file.encoding")); - } /** * MIME type. diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/ImageIcon.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/ImageIcon.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/ImageIcon.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/ImageIcon.java 2023-07-05 07:11:54.000000000 +0000 @@ -85,7 +85,7 @@ * @author Lynn Monsanto * @since 1.2 */ -@SuppressWarnings({"removal","serial"}) // Same-version serialization only +@SuppressWarnings("serial") // Same-version serialization only public class ImageIcon implements Icon, Serializable, Accessible { /* Keep references to the filename and location so that * alternate persistence schemes have the option to archive @@ -105,8 +105,27 @@ * It is left for backward compatibility only. * @deprecated since 1.8 */ + @SuppressWarnings("removal") @Deprecated - protected static final Component component; + protected static final Component component + = AccessController.doPrivileged(new PrivilegedAction() { + public Component run() { + try { + final Component component = createNoPermsComponent(); + + // 6482575 - clear the appContext field so as not to leak it + AWTAccessor.getComponentAccessor(). + setAppContext(component, null); + + return component; + } catch (Throwable e) { + // We don't care about component. + // So don't prevent class initialisation. + e.printStackTrace(); + return null; + } + } + }); /** * Do not use this shared media tracker, which is used to load images. @@ -114,30 +133,9 @@ * @deprecated since 1.8 */ @Deprecated - protected static final MediaTracker tracker; - - static { - component = AccessController.doPrivileged(new PrivilegedAction() { - public Component run() { - try { - final Component component = createNoPermsComponent(); - - // 6482575 - clear the appContext field so as not to leak it - AWTAccessor.getComponentAccessor(). - setAppContext(component, null); - - return component; - } catch (Throwable e) { - // We don't care about component. - // So don't prevent class initialisation. - e.printStackTrace(); - return null; - } - } - }); - tracker = new MediaTracker(component); - } + protected static final MediaTracker tracker = new MediaTracker(component); + @SuppressWarnings("removal") private static Component createNoPermsComponent() { // 7020198 - set acc field to no permissions and no subject // Note, will have appContext set. diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/JPopupMenu.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/JPopupMenu.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/JPopupMenu.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/JPopupMenu.java 2023-07-05 07:11:54.000000000 +0000 @@ -101,7 +101,7 @@ */ @JavaBean(defaultProperty = "UI", description = "A small window that pops up and displays a series of choices.") @SwingContainer(false) -@SuppressWarnings({"removal","serial"}) +@SuppressWarnings("serial") public class JPopupMenu extends JComponent implements Accessible,MenuElement { /** @@ -117,14 +117,11 @@ new StringBuffer("JPopupMenu.defaultLWPopupEnabledKey"); /** Bug#4425878-Property javax.swing.adjustPopupLocationToFit introduced */ - static boolean popupPostionFixDisabled = false; - - static { - popupPostionFixDisabled = java.security.AccessController.doPrivileged( + @SuppressWarnings("removal") + static boolean popupPostionFixDisabled = + java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction( - "javax.swing.adjustPopupLocationToFit","")).equals("false"); - - } + "javax.swing.adjustPopupLocationToFit","")).equals("false"); transient Component invoker; transient Popup popup; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/JRootPane.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/JRootPane.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/JRootPane.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/JRootPane.java 2023-07-05 07:11:54.000000000 +0000 @@ -199,7 +199,7 @@ * @since 1.2 */ /// PENDING(klobad) Who should be opaque in this component? -@SuppressWarnings({"removal","serial"}) +@SuppressWarnings("serial") public class JRootPane extends JComponent implements Accessible { private static final String uiClassID = "RootPaneUI"; @@ -208,13 +208,19 @@ * Whether or not we should dump the stack when true double buffering * is disabled. Default is false. */ - private static final boolean LOG_DISABLE_TRUE_DOUBLE_BUFFERING; + @SuppressWarnings("removal") + private static final boolean LOG_DISABLE_TRUE_DOUBLE_BUFFERING + = AccessController.doPrivileged(new GetBooleanAction( + "swing.logDoubleBufferingDisable")); /** * Whether or not we should ignore requests to disable true double * buffering. Default is false. */ - private static final boolean IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING; + @SuppressWarnings("removal") + private static final boolean IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING + = AccessController.doPrivileged(new GetBooleanAction( + "swing.ignoreDoubleBufferingDisable")); /** * Constant used for the windowDecorationStyle property. Indicates that @@ -326,15 +332,6 @@ */ boolean useTrueDoubleBuffering = true; - static { - LOG_DISABLE_TRUE_DOUBLE_BUFFERING = - AccessController.doPrivileged(new GetBooleanAction( - "swing.logDoubleBufferingDisable")); - IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING = - AccessController.doPrivileged(new GetBooleanAction( - "swing.ignoreDoubleBufferingDisable")); - } - /** * Creates a JRootPane, setting up its * glassPane, layeredPane, diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html 2023-07-05 07:11:54.000000000 +0000 @@ -70,6 +70,8 @@

This example loads the look and feel from an input stream, using the specified class as the resource base to resolve paths. +

+

It is also possible to load a look and feel from an arbitrary URL as in the following example.

@@ -94,6 +96,11 @@
  • Remote JAR file, e.g. jar:http://host/synth-laf.jar!/laf.xml
  • +

    Note: Synth's file format allows for the definition of code to be executed. + Loading any code from a remote location should be used only + with extreme caution from a trusted source over a secure connection. + It is strongly discouraged for an application or a LookAndFeel to do so. +

    While the DTD for synth is specified, the parser is not validating. Parsing will fail only if a necessary attribute is not diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java 2023-07-05 07:11:54.000000000 +0000 @@ -615,6 +615,18 @@ * new URL(synthFile, path). Refer to * Synth File Format for more * information. + *

    + * Whilst this API may be safe for loading local resources that are + * delivered with a {@code LookAndFeel} or application, and so have an + * equal level of trust with application code, using it to load from + * remote resources, particularly any which may have a lower level of + * trust, is strongly discouraged. + * The alternative mechanisms to load styles from an {@code InputStream} + * {@linkplain #load(InputStream, Class)} + * using resources co-located with the application or by providing a + * {@code SynthStyleFactory} to + * {@linkplain #setStyleFactory setStyleFactory(SynthStyleFactory)} + * are preferred. * * @param url the URL to load the set of * SynthStyle from diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/SortingFocusTraversalPolicy.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/SortingFocusTraversalPolicy.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/javax/swing/SortingFocusTraversalPolicy.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/javax/swing/SortingFocusTraversalPolicy.java 2023-07-05 07:11:54.000000000 +0000 @@ -59,7 +59,6 @@ * @see java.util.Comparator * @since 1.4 */ -@SuppressWarnings("removal") public class SortingFocusTraversalPolicy extends InternalFrameFocusTraversalPolicy { @@ -96,12 +95,10 @@ * When false, the default (tim-sort) algo is used, which may lead to an exception. * See: JDK-8048887 */ - private static final boolean legacySortingFTPEnabled; - - static { - legacySortingFTPEnabled = "true".equals(AccessController.doPrivileged( - new GetPropertyAction("swing.legacySortingFTPEnabled", "true"))); - } + @SuppressWarnings("removal") + private static final boolean legacySortingFTPEnabled = "true".equals( + AccessController.doPrivileged( + new GetPropertyAction("swing.legacySortingFTPEnabled", "true"))); /** * Constructs a SortingFocusTraversalPolicy without a Comparator. diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/awt/FontConfiguration.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/awt/FontConfiguration.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/awt/FontConfiguration.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/awt/FontConfiguration.java 2023-07-05 07:11:54.000000000 +0000 @@ -1252,15 +1252,24 @@ return filenamesMap.get(platformName); } + private static final String fontconfigErrorMessage = + "Fontconfig head is null, check your fonts or fonts configuration"; + /** * Returns a configuration specific path to be appended to the font * search path. */ public String getExtraFontPath() { + if (head == null) { + throw new RuntimeException(fontconfigErrorMessage); + } return getString(head[INDEX_appendedfontpath]); } public String getVersion() { + if (head == null) { + throw new RuntimeException(fontconfigErrorMessage); + } return getString(head[INDEX_version]); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/awt/image/SurfaceManager.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/awt/image/SurfaceManager.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/awt/image/SurfaceManager.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/awt/image/SurfaceManager.java 2023-07-05 07:11:54.000000000 +0000 @@ -89,7 +89,7 @@ imgaccessor.setSurfaceManager(img, mgr); } - private ConcurrentHashMap cacheMap; + private volatile ConcurrentHashMap cacheMap; /** * Return an arbitrary cached object for an arbitrary cache key. diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/font/FontUtilities.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/font/FontUtilities.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/font/FontUtilities.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/font/FontUtilities.java 2023-07-05 07:11:54.000000000 +0000 @@ -38,7 +38,6 @@ /** * A collection of utility methods. */ -@SuppressWarnings("removal") public final class FontUtilities { public static boolean isLinux; @@ -56,7 +55,11 @@ // This static initializer block figures out the OS constants. static { + initStatic(); + } + @SuppressWarnings("removal") + private static void initStatic() { AccessController.doPrivileged(new PrivilegedAction() { @SuppressWarnings("deprecation") // PlatformLogger.setLevel is deprecated. @Override diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/font/StrikeCache.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/font/StrikeCache.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/font/StrikeCache.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/font/StrikeCache.java 2023-07-05 07:11:54.000000000 +0000 @@ -61,7 +61,6 @@ */ -@SuppressWarnings("removal") public final class StrikeCache { static final Unsafe unsafe = Unsafe.getUnsafe(); @@ -135,6 +134,11 @@ static native void getGlyphCacheDescription(long[] infoArray); static { + initStatic(); + } + + @SuppressWarnings("removal") + private static void initStatic() { long[] nativeInfo = new long[13]; getGlyphCacheDescription(nativeInfo); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java 2023-07-05 07:11:54.000000000 +0000 @@ -59,21 +59,19 @@ * @see GraphicsDevice * @see GraphicsConfiguration */ -@SuppressWarnings("removal") public abstract class SunGraphicsEnvironment extends GraphicsEnvironment implements DisplayChangedListener { /** Establish the default font to be used by SG2D. */ private final Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); - private static final boolean uiScaleEnabled; - private static final double debugScale; + @SuppressWarnings("removal") + private static final boolean uiScaleEnabled + = "true".equals(AccessController.doPrivileged( + new GetPropertyAction("sun.java2d.uiScale.enabled", "true"))); - static { - uiScaleEnabled = "true".equals(AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.uiScale.enabled", "true"))); - debugScale = uiScaleEnabled ? getScaleFactor("sun.java2d.uiScale") : -1; - } + private static final double debugScale = + uiScaleEnabled ? getScaleFactor("sun.java2d.uiScale") : -1; protected GraphicsDevice[] screens; @@ -299,6 +297,7 @@ public static double getScaleFactor(String propertyName) { + @SuppressWarnings("removal") String scaleFactor = AccessController.doPrivileged( new GetPropertyAction(propertyName, "-1")); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java 2023-07-05 07:11:54.000000000 +0000 @@ -68,7 +68,7 @@ * @author Artem Ananiev * @author Anton Tarasov */ -@SuppressWarnings({"removal","serial"}) // JDK-implementation class +@SuppressWarnings("serial") // JDK-implementation class public final class JLightweightFrame extends LightweightFrame implements RootPaneContainer { private final JRootPane rootPane = new JRootPane(); @@ -83,19 +83,6 @@ private volatile double scaleFactorX; private volatile double scaleFactorY; - /** - * {@code copyBufferEnabled}, true by default, defines the following strategy. - * A duplicating (copy) buffer is created for the original pixel buffer. - * The copy buffer is synchronized with the original buffer every time the - * latter changes. {@code JLightweightFrame} passes the copy buffer array - * to the {@link LightweightContent#imageBufferReset} method. The code spot - * which synchronizes two buffers becomes the only critical section guarded - * by the lock (managed with the {@link LightweightContent#paintLock()}, - * {@link LightweightContent#paintUnlock()} methods). - */ - private static boolean copyBufferEnabled; - private int[] copyBuffer; - private PropertyChangeListener layoutSizeListener; private RepaintListener repaintListener; @@ -106,14 +93,28 @@ frame.updateClientCursor(); } }); - copyBufferEnabled = "true".equals(AccessController. - doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true"))); } /** + * {@code copyBufferEnabled}, true by default, defines the following strategy. + * A duplicating (copy) buffer is created for the original pixel buffer. + * The copy buffer is synchronized with the original buffer every time the + * latter changes. {@code JLightweightFrame} passes the copy buffer array + * to the {@link LightweightContent#imageBufferReset} method. The code spot + * which synchronizes two buffers becomes the only critical section guarded + * by the lock (managed with the {@link LightweightContent#paintLock()}, + * {@link LightweightContent#paintUnlock()} methods). + */ + @SuppressWarnings("removal") + private static boolean copyBufferEnabled = "true".equals(AccessController. + doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true"))); + private int[] copyBuffer; + + /** * Constructs a new, initially invisible {@code JLightweightFrame} * instance. */ + @SuppressWarnings("removal") public JLightweightFrame() { super(); AffineTransform defaultTransform = @@ -330,7 +331,7 @@ content.imageUpdated(x, y, width, height); } - @SuppressWarnings("serial") // anonymous class inside + @SuppressWarnings({"removal","serial"}) // anonymous class inside private void initInterior() { contentPane = new JPanel() { @Override diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/legal/harfbuzz.md openjdk-17-17.0.8+7/src/java.desktop/share/legal/harfbuzz.md --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/legal/harfbuzz.md 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/legal/harfbuzz.md 2023-07-05 07:11:54.000000000 +0000 @@ -1,8 +1,8 @@ -## Harfbuzz v4.4.1 +## Harfbuzz v7.0.1 ### Harfbuzz License -https://github.com/harfbuzz/harfbuzz/blob/4.4.1/COPYING +https://github.com/harfbuzz/harfbuzz/blob/7.0.1/COPYING
     
    @@ -12,21 +12,22 @@
     
     Copyright © 2010-2022  Google, Inc.
     Copyright © 2018-2020  Ebrahim Byagowi
    -Copyright © 2019-2020  Facebook, Inc.
    -Copyright © 2012-2015  Mozilla Foundation.
    -Copyright © 2011  Codethink Limited
    -Copyright © 2008-2010  Nokia Corporation and/or its subsidiary(-ies)
    -Copyright © 2009  Keith Stribley
    -Copyright © 2009  Martin Hosken and SIL International
    -Copyright © 2007  Chris Wilson
    -Copyright © 2005-2022 Behdad Esfahbod
    -Copyright © 2005  David Turner
     Copyright © 2004-2013  Red Hat, Inc.
    -Copyright © 1998-2004  David Turner and Werner Lemberg
    -Copyright © 2016  Elie Roux 
    +Copyright © 2019  Facebook, Inc.
    +Copyright © 2007  Chris Wilson
     Copyright © 2018-2019 Adobe Inc.
    +Copyright © 2006-2023 Behdad Esfahbod
    +Copyright © 1998-2004  David Turner and Werner Lemberg
    +Copyright © 2009  Keith Stribley
     Copyright © 2018  Khaled Hosny
    +Copyright © 2016  Elie Roux 
     Copyright © 2016  Igalia S.L.
    +Copyright © 2015  Mozilla Foundation.
    +Copyright © 1999  David Turner
    +Copyright © 2005  Werner Lemberg
    +Copyright © 2013-2015  Alexei Podtelezhnikov
    +Copyright © 2022 Matthias Clasen
    +Copyright © 2011  Codethink Limited
     
     For full copyright notices consult the individual files in the package.
     
    @@ -72,3 +73,23 @@
     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     
     
    + +### AUTHORS File Information +``` + +Behdad Esfahbod +David Corbett +David Turner +Ebrahim Byagowi +Garret Rieger +Jonathan Kew +Khaled Hosny +Lars Knoll +Martin Hosken +Owen Taylor +Roderick Sheeter +Roozbeh Pournader +Simon Hausmann +Werner Lemberg + +``` diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/legal/lcms.md openjdk-17-17.0.8+7/src/java.desktop/share/legal/lcms.md --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/legal/lcms.md 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/legal/lcms.md 2023-07-05 07:11:54.000000000 +0000 @@ -1,8 +1,7 @@ -## Little Color Management System (LCMS) v2.14 +## Little Color Management System (LCMS) v2.15 ### LCMS License
    -
     README.1ST file information
     
     LittleCMS core is released under MIT License
    @@ -10,7 +9,7 @@
     ---------------------------------
     
     Little CMS
    -Copyright (c) 1998-2022 Marti Maria Saguer
    +Copyright (c) 1998-2023 Marti Maria Saguer
     
     Permission is hereby granted, free of charge, to any person obtaining
     a copy of this software and associated documentation files (the
    @@ -32,7 +31,6 @@
     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     
     ---------------------------------
    -
     The below license applies to the following files:
     liblcms/cmssm.c
     
    @@ -44,12 +42,12 @@
     liable for any real or imagined damage resulting from its use.
     Users of this code must verify correctness for their application.
     
    -
     
    ### AUTHORS File Information ``` + Main Author ------------ Marti Maria @@ -90,11 +88,15 @@ Noel Carboni Sergei Trofimovic Philipp Knechtges +Amyspark +Lovell Fuller +Eli Schwartz Special Thanks -------------- Artifex software AlienSkin software +libVIPS Jan Morovic Jos Vernon (WebSupergoo) Harald Schneider (Maxon) @@ -103,5 +105,4 @@ Lemke Software Tim Zaman - ``` diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,216 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#include "graph.hh" +#include "../hb-ot-layout-common.hh" + +#ifndef GRAPH_CLASSDEF_GRAPH_HH +#define GRAPH_CLASSDEF_GRAPH_HH + +namespace graph { + +struct ClassDefFormat1 : public OT::ClassDefFormat1_3 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::ClassDefFormat1_3::min_size; + if (vertex_len < min_size) return false; + return vertex_len >= min_size + classValue.get_size () - classValue.len.get_size (); + } +}; + +struct ClassDefFormat2 : public OT::ClassDefFormat2_4 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::ClassDefFormat2_4::min_size; + if (vertex_len < min_size) return false; + return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); + } +}; + +struct ClassDef : public OT::ClassDef +{ + template + static bool add_class_def (gsubgpos_graph_context_t& c, + unsigned parent_id, + unsigned link_position, + It glyph_and_class, + unsigned max_size) + { + unsigned class_def_prime_id = c.graph.new_node (nullptr, nullptr); + auto& class_def_prime_vertex = c.graph.vertices_[class_def_prime_id]; + if (!make_class_def (c, glyph_and_class, class_def_prime_id, max_size)) + return false; + + auto* class_def_link = c.graph.vertices_[parent_id].obj.real_links.push (); + 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); + + return true; + } + + template + static bool make_class_def (gsubgpos_graph_context_t& c, + It glyph_and_class, + unsigned dest_obj, + unsigned max_size) + { + char* buffer = (char*) hb_calloc (1, max_size); + hb_serialize_context_t serializer (buffer, max_size); + OT::ClassDef_serialize (&serializer, glyph_and_class); + serializer.end_serialize (); + if (serializer.in_error ()) + { + hb_free (buffer); + return false; + } + + 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. + + auto& obj = c.graph.vertices_[dest_obj].obj; + obj.head = (char *) class_def_copy.arrayZ; + obj.tail = obj.head + class_def_copy.length; + + hb_free (buffer); + return true; + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::ClassDef::min_size) return false; + switch (u.format) + { + case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); + case 2: return ((ClassDefFormat2*)this)->sanitize (vertex); +#ifndef HB_NO_BEYOND_64K + // Not currently supported + case 3: + case 4: +#endif + default: return false; + } + } +}; + + +struct class_def_size_estimator_t +{ + template + class_def_size_estimator_t (It glyph_and_class) + : gids_consecutive (true), num_ranges_per_class (), glyphs_per_class () + { + unsigned last_gid = (unsigned) -1; + for (auto p : + glyph_and_class) + { + unsigned gid = p.first; + unsigned klass = p.second; + + if (last_gid != (unsigned) -1 && gid != last_gid + 1) + gids_consecutive = false; + last_gid = gid; + + hb_set_t* glyphs; + if (glyphs_per_class.has (klass, &glyphs) && glyphs) { + glyphs->add (gid); + continue; + } + + hb_set_t new_glyphs; + new_glyphs.add (gid); + glyphs_per_class.set (klass, std::move (new_glyphs)); + } + + if (in_error ()) return; + + for (unsigned klass : glyphs_per_class.keys ()) + { + if (!klass) continue; // class 0 doesn't get encoded. + + const hb_set_t& glyphs = glyphs_per_class.get (klass); + hb_codepoint_t start = HB_SET_VALUE_INVALID; + hb_codepoint_t end = HB_SET_VALUE_INVALID; + + unsigned count = 0; + while (glyphs.next_range (&start, &end)) + count++; + + num_ranges_per_class.set (klass, count); + } + } + + // Incremental increase in the Coverage and ClassDef table size + // (worst case) if all glyphs associated with 'klass' were added. + unsigned incremental_coverage_size (unsigned klass) const + { + // Coverage takes 2 bytes per glyph worst case, + return 2 * glyphs_per_class.get (klass).get_population (); + } + + // Incremental increase in the Coverage and ClassDef table size + // (worst case) if all glyphs associated with 'klass' were added. + unsigned incremental_class_def_size (unsigned klass) const + { + // ClassDef takes 6 bytes per range + unsigned class_def_2_size = 6 * num_ranges_per_class.get (klass); + if (gids_consecutive) + { + // ClassDef1 takes 2 bytes per glyph, but only can be used + // when gids are consecutive. + return hb_min (2 * glyphs_per_class.get (klass).get_population (), class_def_2_size); + } + + return class_def_2_size; + } + + bool in_error () + { + if (num_ranges_per_class.in_error ()) return true; + if (glyphs_per_class.in_error ()) return true; + + for (const hb_set_t& s : glyphs_per_class.values ()) + { + if (s.in_error ()) return true; + } + return false; + } + + private: + bool gids_consecutive; + hb_hashmap_t num_ranges_per_class; + hb_hashmap_t glyphs_per_class; +}; + + +} + +#endif // GRAPH_CLASSDEF_GRAPH_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,152 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#include "graph.hh" +#include "../OT/Layout/Common/Coverage.hh" + +#ifndef GRAPH_COVERAGE_GRAPH_HH +#define GRAPH_COVERAGE_GRAPH_HH + +namespace graph { + +struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3::min_size; + if (vertex_len < min_size) return false; + return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); + } +}; + +struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4::min_size; + if (vertex_len < min_size) return false; + return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); + } +}; + +struct Coverage : public OT::Layout::Common::Coverage +{ + static Coverage* clone_coverage (gsubgpos_graph_context_t& c, + unsigned coverage_id, + unsigned new_parent_id, + unsigned link_position, + unsigned start, unsigned end) + + { + unsigned coverage_size = c.graph.vertices_[coverage_id].table_size (); + auto& coverage_v = c.graph.vertices_[coverage_id]; + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + if (!coverage_table || !coverage_table->sanitize (coverage_v)) + return nullptr; + + auto new_coverage = + + hb_zip (coverage_table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t p) { + return p.second >= start && p.second < end; + }) + | hb_map_retains_sorting (hb_first) + ; + + return add_coverage (c, new_parent_id, link_position, new_coverage, coverage_size); + } + + template + static Coverage* add_coverage (gsubgpos_graph_context_t& c, + unsigned parent_id, + unsigned link_position, + It glyphs, + unsigned max_size) + { + unsigned coverage_prime_id = c.graph.new_node (nullptr, nullptr); + auto& coverage_prime_vertex = c.graph.vertices_[coverage_prime_id]; + if (!make_coverage (c, glyphs, coverage_prime_id, max_size)) + return nullptr; + + auto* coverage_link = c.graph.vertices_[parent_id].obj.real_links.push (); + coverage_link->width = SmallTypes::size; + coverage_link->objidx = coverage_prime_id; + coverage_link->position = link_position; + coverage_prime_vertex.parents.push (parent_id); + + return (Coverage*) coverage_prime_vertex.obj.head; + } + + template + static bool make_coverage (gsubgpos_graph_context_t& c, + It glyphs, + unsigned dest_obj, + unsigned max_size) + { + char* buffer = (char*) hb_calloc (1, max_size); + hb_serialize_context_t serializer (buffer, max_size); + OT::Layout::Common::Coverage_serialize (&serializer, glyphs); + serializer.end_serialize (); + if (serializer.in_error ()) + { + hb_free (buffer); + return false; + } + + 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. + + auto& obj = c.graph.vertices_[dest_obj].obj; + obj.head = (char *) coverage_copy.arrayZ; + obj.tail = obj.head + coverage_copy.length; + + hb_free (buffer); + return true; + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; + switch (u.format) + { + case 1: return ((CoverageFormat1*)this)->sanitize (vertex); + case 2: return ((CoverageFormat2*)this)->sanitize (vertex); +#ifndef HB_NO_BEYOND_64K + // Not currently supported + case 3: + case 4: +#endif + default: return false; + } + } +}; + + +} + +#endif // GRAPH_COVERAGE_GRAPH_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/graph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/graph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/graph.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/graph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -24,6 +24,10 @@ * Google Author(s): Garret Rieger */ +#include "../hb-set.hh" +#include "../hb-priority-queue.hh" +#include "../hb-serialize.hh" + #ifndef GRAPH_GRAPH_HH #define GRAPH_GRAPH_HH @@ -45,6 +49,95 @@ unsigned end = 0; unsigned priority = 0; + + bool link_positions_valid (unsigned num_objects, bool removed_nil) + { + hb_set_t assigned_bytes; + for (const auto& l : obj.real_links) + { + if (l.objidx >= num_objects + || (removed_nil && !l.objidx)) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Invalid object index."); + return false; + } + + unsigned start = l.position; + unsigned end = start + l.width - 1; + + if (unlikely (l.width < 2 || l.width > 4)) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Invalid link width."); + return false; + } + + if (unlikely (end >= table_size ())) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Link position is out of bounds."); + return false; + } + + if (unlikely (assigned_bytes.intersects (start, end))) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Found offsets whose positions overlap."); + return false; + } + + assigned_bytes.add_range (start, end); + } + + return !assigned_bytes.in_error (); + } + + void normalize () + { + obj.real_links.qsort (); + for (auto& l : obj.real_links) + { + for (unsigned i = 0; i < l.width; i++) + { + obj.head[l.position + i] = 0; + } + } + } + + bool equals (const vertex_t& other, + const graph_t& graph, + const graph_t& other_graph, + unsigned depth) const + { + if (!(as_bytes () == other.as_bytes ())) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "vertex [%lu] bytes != [%lu] bytes, depth = %u", + (unsigned long) table_size (), + (unsigned long) other.table_size (), + depth); + + auto a = as_bytes (); + auto b = other.as_bytes (); + while (a || b) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " 0x%x %s 0x%x", (unsigned) *a, (*a == *b) ? "==" : "!=", (unsigned) *b); + a++; + b++; + } + return false; + } + + return links_equal (obj.real_links, other.obj.real_links, graph, other_graph, depth); + } + + hb_bytes_t as_bytes () const + { + return hb_bytes_t (obj.head, table_size ()); + } + friend void swap (vertex_t& a, vertex_t& b) { hb_swap (a.obj, b.obj); @@ -56,6 +149,18 @@ hb_swap (a.priority, b.priority); } + hb_hashmap_t + position_to_index_map () const + { + hb_hashmap_t result; + + for (const auto& l : obj.real_links) { + result.set (l.position, l.objidx); + } + + return result; + } + bool is_shared () const { return parents.length > 1; @@ -71,11 +176,27 @@ for (unsigned i = 0; i < parents.length; i++) { if (parents[i] != parent_index) continue; - parents.remove (i); + parents.remove_unordered (i); break; } } + void remove_real_link (unsigned child_index, const void* offset) + { + for (unsigned i = 0; i < obj.real_links.length; i++) + { + auto& link = obj.real_links.arrayZ[i]; + if (link.objidx != child_index) + continue; + + if ((obj.head + link.position) != offset) + continue; + + obj.real_links.remove_unordered (i); + return; + } + } + void remap_parents (const hb_vector_t& id_map) { for (unsigned i = 0; i < parents.length; i++) @@ -107,6 +228,10 @@ return priority >= 3; } + size_t table_size () const { + return obj.tail - obj.head; + } + int64_t modified_distance (unsigned order) const { // TODO(garretrieger): once priority is high enough, should try @@ -131,6 +256,57 @@ return -table_size; } + + private: + bool links_equal (const hb_vector_t& this_links, + const hb_vector_t& other_links, + const graph_t& graph, + const graph_t& other_graph, + unsigned depth) const + { + auto a = this_links.iter (); + auto b = other_links.iter (); + + while (a && b) + { + const auto& link_a = *a; + const auto& link_b = *b; + + if (link_a.width != link_b.width || + link_a.is_signed != link_b.is_signed || + link_a.whence != link_b.whence || + link_a.position != link_b.position || + link_a.bias != link_b.bias) + return false; + + if (!graph.vertices_[link_a.objidx].equals ( + other_graph.vertices_[link_b.objidx], graph, other_graph, depth + 1)) + return false; + + a++; + b++; + } + + if (bool (a) != bool (b)) + return false; + + return true; + } + }; + + template + struct vertex_and_table_t + { + vertex_and_table_t () : index (0), vertex (nullptr), table (nullptr) + {} + + unsigned index; + vertex_t* vertex; + T* table; + + operator bool () { + return table && vertex; + } }; /* @@ -145,7 +321,8 @@ : parents_invalid (true), distance_invalid (true), positions_invalid (true), - successful (true) + successful (true), + buffers () { num_roots_for_space_.push (1); bool removed_nil = false; @@ -153,8 +330,6 @@ vertices_scratch_.alloc (objects.length); for (unsigned i = 0; i < objects.length; i++) { - // TODO(grieger): check all links point to valid objects. - // 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]) @@ -166,6 +341,9 @@ vertex_t* v = vertices_.push (); if (check_success (!vertices_.in_error ())) v->obj = *objects[i]; + + check_success (v->link_positions_valid (objects.length, removed_nil)); + if (!removed_nil) continue; // Fix indices to account for removed nil object. for (auto& l : v->obj.all_links_writer ()) { @@ -177,6 +355,20 @@ ~graph_t () { vertices_.fini (); + for (char* b : buffers) + hb_free (b); + } + + bool operator== (const graph_t& other) const + { + return root ().equals (other.root (), *this, other, 0); + } + + // Sorts links of all objects in a consistent manner and zeroes all offsets. + void normalize () + { + for (auto& v : vertices_.writer ()) + v.normalize (); } bool in_error () const @@ -199,11 +391,43 @@ return vertices_.length - 1; } - const hb_serialize_context_t::object_t& object(unsigned i) const + const hb_serialize_context_t::object_t& object (unsigned i) const { return vertices_[i].obj; } + void add_buffer (char* buffer) + { + buffers.push (buffer); + } + + /* + * Adds a 16 bit link from parent_id to child_id + */ + template + void add_link (T* offset, + unsigned parent_id, + unsigned child_id) + { + auto& v = vertices_[parent_id]; + auto* link = v.obj.real_links.push (); + link->width = 2; + link->objidx = child_id; + link->position = (char*) offset - (char*) v.obj.head; + vertices_[child_id].parents.push (parent_id); + } + + /* + * Generates a new topological sorting of graph ordered by the shortest + * distance to each node if positions are marked as invalid. + */ + void sort_shortest_distance_if_needed () + { + if (!positions_invalid) return; + sort_shortest_distance (); + } + + /* * Generates a new topological sorting of graph ordered by the shortest * distance to each node. @@ -239,6 +463,13 @@ hb_swap (sorted_graph[new_id], vertices_[next_id]); const vertex_t& next = sorted_graph[new_id]; + if (unlikely (!check_success(new_id >= 0))) { + // We are out of ids. Which means we've visited a node more than once. + // This graph contains a cycle which is not allowed. + DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle."); + return; + } + id_map[next_id] = new_id--; for (const auto& link : next.obj.all_links ()) { @@ -256,44 +487,152 @@ check_success (!queue.in_error ()); check_success (!sorted_graph.in_error ()); - if (!check_success (new_id == -1)) - print_orphaned_nodes (); remap_all_obj_indices (id_map, &sorted_graph); - hb_swap (vertices_, sorted_graph); + + if (!check_success (new_id == -1)) + print_orphaned_nodes (); } /* - * Assign unique space numbers to each connected subgraph of 32 bit offset(s). + * Finds the set of nodes (placed into roots) that should be assigned unique spaces. + * More specifically this looks for the top most 24 bit or 32 bit links in the graph. + * Some special casing is done that is specific to the layout of GSUB/GPOS tables. */ - bool assign_32bit_spaces () + void find_space_roots (hb_set_t& visited, hb_set_t& roots) { - unsigned root_index = root_idx (); - hb_set_t visited; - hb_set_t roots; - for (unsigned i = 0; i <= root_index; i++) + int root_index = (int) root_idx (); + for (int i = root_index; i >= 0; i--) { + if (visited.has (i)) continue; + // Only real links can form 32 bit spaces for (auto& l : vertices_[i].obj.real_links) { - if (l.width == 4 && !l.is_signed) + if (l.is_signed || l.width < 3) + continue; + + if (i == root_index && l.width == 3) + // Ignore 24bit links from the root node, this skips past the single 24bit + // pointer to the lookup list. + continue; + + if (l.width == 3) { - roots.add (l.objidx); - find_subgraph (l.objidx, visited); + // A 24bit offset forms a root, unless there is 32bit offsets somewhere + // in it's subgraph, then those become the roots instead. This is to make sure + // that extension subtables beneath a 24bit lookup become the spaces instead + // of the offset to the lookup. + hb_set_t sub_roots; + find_32bit_roots (l.objidx, sub_roots); + if (sub_roots) { + for (unsigned sub_root_idx : sub_roots) { + roots.add (sub_root_idx); + find_subgraph (sub_root_idx, visited); + } + continue; + } } + + roots.add (l.objidx); + find_subgraph (l.objidx, visited); } } + } - // Mark everything not in the subgraphs of 32 bit roots as visited. - // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs. + template + vertex_and_table_t as_table (unsigned parent, const void* offset, Ts... ds) + { + return as_table_from_index (index_for_offset (parent, offset), std::forward(ds)...); + } + + template + vertex_and_table_t as_mutable_table (unsigned parent, const void* offset, Ts... ds) + { + return as_table_from_index (mutable_index_for_offset (parent, offset), std::forward(ds)...); + } + + template + vertex_and_table_t as_table_from_index (unsigned index, Ts... ds) + { + if (index >= vertices_.length) + return vertex_and_table_t (); + + vertex_and_table_t r; + r.vertex = &vertices_[index]; + r.table = (T*) r.vertex->obj.head; + r.index = index; + if (!r.table) + return vertex_and_table_t (); + + if (!r.table->sanitize (*(r.vertex), std::forward(ds)...)) + return vertex_and_table_t (); + + return r; + } + + // Finds the object id of the object pointed to by the offset at 'offset' + // within object[node_idx]. + unsigned index_for_offset (unsigned node_idx, const void* offset) const + { + 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++) + { + // Use direct access for increased performance, this is a hot method. + const auto& link = node.real_links.arrayZ[i]; + if (offset != node.head + link.position) + continue; + return link.objidx; + } + + return -1; + } + + // Finds the object id of the object pointed to by the offset at 'offset' + // within object[node_idx]. Ensures that the returned object is safe to mutate. + // That is, if the original child object is shared by parents other than node_idx + // it will be duplicated and the duplicate will be returned instead. + unsigned mutable_index_for_offset (unsigned node_idx, const void* offset) + { + unsigned child_idx = index_for_offset (node_idx, offset); + auto& child = vertices_[child_idx]; + for (unsigned p : child.parents) + { + if (p != node_idx) { + return duplicate (node_idx, child_idx); + } + } + + return child_idx; + } + + + /* + * Assign unique space numbers to each connected subgraph of 24 bit and/or 32 bit offset(s). + * Currently, this is implemented specifically tailored to the structure of a GPOS/GSUB + * (including with 24bit offsets) table. + */ + bool assign_spaces () + { + update_parents (); + + hb_set_t visited; + hb_set_t roots; + find_space_roots (visited, roots); + + // Mark everything not in the subgraphs of the roots as visited. This prevents + // subgraphs from being connected via nodes not in those subgraphs. visited.invert (); if (!roots) return false; while (roots) { - unsigned next = HB_SET_VALUE_INVALID; + uint32_t next = HB_SET_VALUE_INVALID; if (unlikely (!check_success (!roots.in_error ()))) break; if (!roots.next (&next)) break; @@ -361,6 +700,9 @@ } } + if (in_error ()) + return false; + if (!made_changes) return false; @@ -374,8 +716,8 @@ auto new_subgraph = + subgraph.keys () - | hb_map([&] (unsigned node_idx) { - const unsigned *v; + | hb_map([&] (uint32_t node_idx) { + const uint32_t *v; if (index_map.has (node_idx, &v)) return *v; return node_idx; }) @@ -385,10 +727,10 @@ remap_obj_indices (index_map, parents.iter (), true); // Update roots set with new indices as needed. - unsigned next = HB_SET_VALUE_INVALID; + uint32_t next = HB_SET_VALUE_INVALID; while (roots.next (&next)) { - const unsigned *v; + const uint32_t *v; if (index_map.has (next, &v)) { roots.del (next); @@ -403,7 +745,7 @@ { for (const auto& link : vertices_[node_idx].obj.all_links ()) { - const unsigned *v; + const uint32_t *v; if (subgraph.has (link.objidx, &v)) { subgraph.set (link.objidx, *v + 1); @@ -422,6 +764,68 @@ find_subgraph (link.objidx, subgraph); } + size_t find_subgraph_size (unsigned node_idx, hb_set_t& subgraph, unsigned max_depth = -1) + { + if (subgraph.has (node_idx)) return 0; + subgraph.add (node_idx); + + const auto& o = vertices_[node_idx].obj; + size_t size = o.tail - o.head; + if (max_depth == 0) + return size; + + for (const auto& link : o.all_links ()) + size += find_subgraph_size (link.objidx, subgraph, max_depth - 1); + return size; + } + + /* + * Finds the topmost children of 32bit offsets in the subgraph starting + * at node_idx. Found indices are placed into 'found'. + */ + void find_32bit_roots (unsigned node_idx, hb_set_t& found) + { + for (const auto& link : vertices_[node_idx].obj.all_links ()) + { + if (!link.is_signed && link.width == 4) { + found.add (link.objidx); + continue; + } + find_32bit_roots (link.objidx, found); + } + } + + /* + * Moves the child of old_parent_idx pointed to by old_offset to a new + * vertex at the new_offset. + */ + template + void move_child (unsigned old_parent_idx, + const O* old_offset, + unsigned new_parent_idx, + const O* new_offset) + { + distance_invalid = true; + positions_invalid = true; + + auto& old_v = vertices_[old_parent_idx]; + auto& new_v = vertices_[new_parent_idx]; + + unsigned child_id = index_for_offset (old_parent_idx, + old_offset); + + auto* new_link = new_v.obj.real_links.push (); + new_link->width = O::static_size; + new_link->objidx = child_id; + new_link->position = (const char*) new_offset - (const char*) new_v.obj.head; + + auto& child = vertices_[child_id]; + child.parents.push (new_parent_idx); + + old_v.remove_real_link (child_id, old_offset); + child.remove_parent (old_parent_idx); + } + /* * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign * links. index_map is updated with mappings from old id to new id. If a duplication has already @@ -432,7 +836,11 @@ if (index_map.has (node_idx)) return; - index_map.set (node_idx, duplicate (node_idx)); + unsigned clone_idx = duplicate (node_idx); + if (!check_success (clone_idx != (unsigned) -1)) + return; + + index_map.set (node_idx, clone_idx); for (const auto& l : object (node_idx).all_links ()) { duplicate_subgraph (l.objidx, index_map); } @@ -490,7 +898,20 @@ * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. */ - bool duplicate (unsigned parent_idx, unsigned child_idx) + unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) + { + unsigned new_idx = duplicate (parent_idx, child_idx); + if (new_idx == (unsigned) -1) return child_idx; + return new_idx; + } + + + /* + * Creates a copy of child and re-assigns the link from + * parent to the clone. The copy is a shallow copy, objects + * linked from child are not duplicated. + */ + unsigned duplicate (unsigned parent_idx, unsigned child_idx) { update_parents (); @@ -504,12 +925,12 @@ { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. - DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %d => %d", + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u => %u", parent_idx, child_idx); - return false; + return -1; } - DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d", + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %u => %u", parent_idx, child_idx); unsigned clone_idx = duplicate (child_idx); @@ -526,7 +947,40 @@ reassign_link (l, parent_idx, clone_idx); } - return true; + return clone_idx; + } + + + /* + * Adds a new node to the graph, not connected to anything. + */ + unsigned new_node (char* head, char* tail) + { + positions_invalid = true; + distance_invalid = true; + + auto* clone = vertices_.push (); + if (vertices_.in_error ()) { + return -1; + } + + clone->obj.head = head; + clone->obj.tail = tail; + clone->distance = 0; + clone->space = 0; + + unsigned clone_idx = vertices_.length - 2; + + // The last object is the root of the graph, so swap back the root to the end. + // The root's obj idx does change, however since it's root nothing else refers to it. + // all other obj idx's will be unaffected. + hb_swap (vertices_[vertices_.length - 2], *clone); + + // Since the root moved, update the parents arrays of all children on the root. + for (const auto& l : root ().obj.all_links ()) + vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); + + return clone_idx; } /* @@ -534,7 +988,7 @@ */ bool raise_childrens_priority (unsigned parent_idx) { - DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d", + DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %u", parent_idx); // This operation doesn't change ordering until a sort is run, so no need // to invalidate positions. It does not change graph structure so no need @@ -546,6 +1000,72 @@ return made_change; } + bool is_fully_connected () + { + update_parents(); + + if (root().parents) + // Root cannot have parents. + return false; + + for (unsigned i = 0; i < root_idx (); i++) + { + if (!vertices_[i].parents) + return false; + } + return true; + } + +#if 0 + /* + * Saves the current graph to a packed binary format which the repacker fuzzer takes + * as a seed. + */ + void save_fuzzer_seed (hb_tag_t tag) const + { + FILE* f = fopen ("./repacker_fuzzer_seed", "w"); + fwrite ((void*) &tag, sizeof (tag), 1, f); + + uint16_t num_objects = vertices_.length; + fwrite ((void*) &num_objects, sizeof (num_objects), 1, f); + + for (const auto& v : vertices_) + { + uint16_t blob_size = v.table_size (); + fwrite ((void*) &blob_size, sizeof (blob_size), 1, f); + fwrite ((const void*) v.obj.head, blob_size, 1, f); + } + + uint16_t link_count = 0; + for (const auto& v : vertices_) + link_count += v.obj.real_links.length; + + fwrite ((void*) &link_count, sizeof (link_count), 1, f); + + typedef struct + { + uint16_t parent; + uint16_t child; + uint16_t position; + uint8_t width; + } link_t; + + for (unsigned i = 0; i < vertices_.length; i++) + { + for (const auto& l : vertices_[i].obj.real_links) + { + link_t link { + (uint16_t) i, (uint16_t) l.objidx, + (uint16_t) l.position, (uint8_t) l.width + }; + fwrite ((void*) &link, sizeof (link), 1, f); + } + } + + fclose (f); + } +#endif + void print_orphaned_nodes () { if (!DEBUG_ENABLED(SUBSET_REPACK)) return; @@ -554,6 +1074,10 @@ parents_invalid = true; update_parents(); + if (root().parents) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges."); + } + for (unsigned i = 0; i < root_idx (); i++) { const auto& v = vertices_[i]; @@ -622,7 +1146,7 @@ private: /* - * Returns the numbers of incoming edges that are 32bits wide. + * Returns the numbers of incoming edges that are 24 or 32 bits wide. */ unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const { @@ -636,7 +1160,9 @@ // Only real links can be wide for (const auto& l : vertices_[p].obj.real_links) { - if (l.objidx == node_idx && l.width == 4 && !l.is_signed) + if (l.objidx == node_idx + && (l.width == 3 || l.width == 4) + && !l.is_signed) { count++; parents.add (p); @@ -668,6 +1194,11 @@ } } + for (unsigned i = 0; i < vertices_.length; 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 ()); + parents_invalid = false; } @@ -786,7 +1317,7 @@ { for (auto& link : vertices_[i].obj.all_links_writer ()) { - const unsigned *v; + const uint32_t *v; if (!id_map.has (link.objidx, &v)) continue; if (only_wide && !(link.width == 4 && !link.is_signed)) continue; @@ -853,6 +1384,7 @@ bool positions_invalid; bool successful; hb_vector_t num_roots_for_space_; + hb_vector_t buffers; }; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,70 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#include "gsubgpos-graph.hh" + +namespace graph { + +gsubgpos_graph_context_t::gsubgpos_graph_context_t (hb_tag_t table_tag_, + graph_t& graph_) + : table_tag (table_tag_), + graph (graph_), + lookup_list_index (0), + lookups () +{ + if (table_tag_ != HB_OT_TAG_GPOS + && table_tag_ != HB_OT_TAG_GSUB) + return; + + GSTAR* gstar = graph::GSTAR::graph_to_gstar (graph_); + if (gstar) { + gstar->find_lookups (graph, lookups); + lookup_list_index = gstar->get_lookup_list_index (graph_); + } +} + +unsigned gsubgpos_graph_context_t::create_node (unsigned size) +{ + char* buffer = (char*) hb_calloc (1, size); + if (!buffer) + return -1; + + add_buffer (buffer); + + return graph.new_node (buffer, buffer + size); +} + +unsigned gsubgpos_graph_context_t::num_non_ext_subtables () { + unsigned count = 0; + for (auto l : lookups.values ()) + { + if (l->is_extension (table_tag)) continue; + count += l->number_of_subtables (); + } + return count; +} + +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#include "graph.hh" +#include "../hb-ot-layout-gsubgpos.hh" + +#ifndef GRAPH_GSUBGPOS_CONTEXT_HH +#define GRAPH_GSUBGPOS_CONTEXT_HH + +namespace graph { + +struct Lookup; + +struct gsubgpos_graph_context_t +{ + hb_tag_t table_tag; + graph_t& graph; + unsigned lookup_list_index; + hb_hashmap_t lookups; + + + 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) + { + graph.add_buffer (buffer); + } + + private: + HB_INTERNAL unsigned num_non_ext_subtables (); +}; + +} + +#endif // GRAPH_GSUBGPOS_CONTEXT diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,414 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#include "graph.hh" +#include "../hb-ot-layout-gsubgpos.hh" +#include "../OT/Layout/GSUB/ExtensionSubst.hh" +#include "gsubgpos-context.hh" +#include "pairpos-graph.hh" +#include "markbasepos-graph.hh" + +#ifndef GRAPH_GSUBGPOS_GRAPH_HH +#define GRAPH_GSUBGPOS_GRAPH_HH + +namespace graph { + +struct Lookup; + +template +struct ExtensionFormat1 : public OT::ExtensionFormat1 +{ + void reset(unsigned type) + { + this->format = 1; + this->extensionLookupType = type; + this->extensionOffset = 0; + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + return vertex_len >= OT::ExtensionFormat1::static_size; + } + + unsigned get_lookup_type () const + { + return this->extensionLookupType; + } + + unsigned get_subtable_index (graph_t& graph, unsigned this_index) const + { + return graph.index_for_offset (this_index, &this->extensionOffset); + } +}; + +struct Lookup : public OT::Lookup +{ + unsigned number_of_subtables () const + { + return subTable.len; + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::Lookup::min_size) return false; + return vertex_len >= this->get_size (); + } + + bool is_extension (hb_tag_t table_tag) const + { + return lookupType == extension_type (table_tag); + } + + bool make_extension (gsubgpos_graph_context_t& c, + unsigned this_index) + { + unsigned type = lookupType; + unsigned ext_type = extension_type (c.table_tag); + if (!ext_type || is_extension (c.table_tag)) + { + // NOOP + return true; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Promoting lookup type %u (obj %u) to extension.", + type, + this_index); + + for (unsigned i = 0; i < subTable.len; i++) + { + unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]); + if (!make_subtable_extension (c, + this_index, + subtable_index)) + return false; + } + + lookupType = ext_type; + return true; + } + + bool split_subtables_if_needed (gsubgpos_graph_context_t& c, + unsigned this_index) + { + unsigned type = lookupType; + bool is_ext = is_extension (c.table_tag); + + if (c.table_tag != HB_OT_TAG_GPOS) + return true; + + if (!is_ext && + type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair && + type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + return true; + + hb_vector_t>> all_new_subtables; + for (unsigned i = 0; i < subTable.len; i++) + { + unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]); + unsigned parent_index = this_index; + if (is_ext) { + unsigned ext_subtable_index = subtable_index; + parent_index = ext_subtable_index; + ExtensionFormat1* extension = + (ExtensionFormat1*) + c.graph.object (ext_subtable_index).head; + if (!extension || !extension->sanitize (c.graph.vertices_[ext_subtable_index])) + continue; + + subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index); + type = extension->get_lookup_type (); + if (type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair + && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + continue; + } + + hb_vector_t new_sub_tables; + switch (type) + { + case 2: + new_sub_tables = split_subtable (c, parent_index, subtable_index); break; + case 4: + new_sub_tables = split_subtable (c, parent_index, subtable_index); break; + default: + break; + } + if (new_sub_tables.in_error ()) return false; + if (!new_sub_tables) continue; + hb_pair_t>* entry = all_new_subtables.push (); + entry->first = i; + entry->second = std::move (new_sub_tables); + } + + if (all_new_subtables) { + add_sub_tables (c, this_index, type, all_new_subtables); + } + + return true; + } + + template + hb_vector_t split_subtable (gsubgpos_graph_context_t& c, + unsigned parent_idx, + unsigned objidx) + { + T* sub_table = (T*) c.graph.object (objidx).head; + if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx])) + return hb_vector_t (); + + return sub_table->split_subtables (c, parent_idx, objidx); + } + + void add_sub_tables (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned type, + hb_vector_t>>& subtable_ids) + { + bool is_ext = is_extension (c.table_tag); + auto& v = c.graph.vertices_[this_index]; + fix_existing_subtable_links (c, this_index, subtable_ids); + + unsigned new_subtable_count = 0; + for (const auto& p : subtable_ids) + new_subtable_count += p.second.length; + + 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); + hb_memcpy (buffer, v.obj.head, v.table_size()); + + v.obj.head = buffer; + v.obj.tail = buffer + new_size; + + Lookup* new_lookup = (Lookup*) buffer; + + unsigned shift = 0; + new_lookup->subTable.len = subTable.len + new_subtable_count; + for (const auto& p : subtable_ids) + { + unsigned offset_index = p.first + shift + 1; + shift += p.second.length; + + for (unsigned subtable_id : p.second) + { + if (is_ext) + { + unsigned ext_id = create_extension_subtable (c, subtable_id, type); + c.graph.vertices_[subtable_id].parents.push (ext_id); + subtable_id = ext_id; + } + + auto* link = v.obj.real_links.push (); + link->width = 2; + link->objidx = subtable_id; + link->position = (char*) &new_lookup->subTable[offset_index++] - + (char*) new_lookup; + c.graph.vertices_[subtable_id].parents.push (this_index); + } + } + + // Repacker sort order depends on link order, which we've messed up so resort it. + v.obj.real_links.qsort (); + + // 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); + } + + void fix_existing_subtable_links (gsubgpos_graph_context_t& c, + unsigned this_index, + hb_vector_t>>& subtable_ids) + { + auto& v = c.graph.vertices_[this_index]; + Lookup* lookup = (Lookup*) v.obj.head; + + unsigned shift = 0; + for (const auto& p : subtable_ids) + { + unsigned insert_index = p.first + shift; + unsigned pos_offset = p.second.length * OT::Offset16::static_size; + unsigned insert_offset = (char*) &lookup->subTable[insert_index] - (char*) lookup; + shift += p.second.length; + + for (auto& l : v.obj.all_links_writer ()) + { + if (l.position > insert_offset) l.position += pos_offset; + } + } + } + + unsigned create_extension_subtable (gsubgpos_graph_context_t& c, + unsigned subtable_index, + unsigned type) + { + unsigned extension_size = OT::ExtensionFormat1::static_size; + + unsigned ext_index = c.create_node (extension_size); + if (ext_index == (unsigned) -1) + return -1; + + auto& ext_vertex = c.graph.vertices_[ext_index]; + ExtensionFormat1* extension = + (ExtensionFormat1*) ext_vertex.obj.head; + extension->reset (type); + + // Make extension point at the subtable. + auto* l = ext_vertex.obj.real_links.push (); + + l->width = 4; + l->objidx = subtable_index; + l->position = 4; + + return ext_index; + } + + bool make_subtable_extension (gsubgpos_graph_context_t& c, + unsigned lookup_index, + unsigned subtable_index) + { + unsigned type = lookupType; + + unsigned ext_index = create_extension_subtable(c, subtable_index, type); + if (ext_index == (unsigned) -1) + return false; + + auto& lookup_vertex = c.graph.vertices_[lookup_index]; + for (auto& l : lookup_vertex.obj.real_links.writer ()) + { + if (l.objidx == subtable_index) + // Change lookup to point at the extension. + l.objidx = ext_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); + + return true; + } + + private: + unsigned extension_type (hb_tag_t table_tag) const + { + switch (table_tag) + { + case HB_OT_TAG_GPOS: return 9; + case HB_OT_TAG_GSUB: return 7; + default: return 0; + } + } +}; + +template +struct LookupList : public OT::LookupList +{ + bool sanitize (const graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::LookupList::min_size) return false; + return vertex_len >= OT::LookupList::item_size * this->len; + } +}; + +struct GSTAR : public OT::GSUBGPOS +{ + static GSTAR* graph_to_gstar (graph_t& graph) + { + const auto& r = graph.root (); + + GSTAR* gstar = (GSTAR*) r.obj.head; + if (!gstar || !gstar->sanitize (r)) + return nullptr; + + return gstar; + } + + const void* get_lookup_list_field_offset () const + { + switch (u.version.major) { + case 1: return u.version1.get_lookup_list_offset (); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.get_lookup_list_offset (); +#endif + default: return 0; + } + } + + bool sanitize (const graph_t::vertex_t& vertex) + { + int64_t len = vertex.obj.tail - vertex.obj.head; + if (len < OT::GSUBGPOS::min_size) return false; + return len >= get_size (); + } + + void find_lookups (graph_t& graph, + hb_hashmap_t& lookups /* OUT */) + { + switch (u.version.major) { + case 1: find_lookups (graph, lookups); break; +#ifndef HB_NO_BEYOND_64K + case 2: find_lookups (graph, lookups); break; +#endif + } + } + + unsigned get_lookup_list_index (graph_t& graph) + { + return graph.index_for_offset (graph.root_idx (), + get_lookup_list_field_offset()); + } + + template + void find_lookups (graph_t& graph, + hb_hashmap_t& lookups /* OUT */) + { + unsigned lookup_list_idx = get_lookup_list_index (graph); + const LookupList* lookupList = + (const LookupList*) graph.object (lookup_list_idx).head; + if (!lookupList || !lookupList->sanitize (graph.vertices_[lookup_list_idx])) + return; + + for (unsigned i = 0; i < lookupList->len; i++) + { + unsigned lookup_idx = graph.index_for_offset (lookup_list_idx, &(lookupList->arrayZ[i])); + Lookup* lookup = (Lookup*) graph.object (lookup_idx).head; + if (!lookup || !lookup->sanitize (graph.vertices_[lookup_idx])) continue; + lookups.set (lookup_idx, lookup); + } + } +}; + + + + +} + +#endif /* GRAPH_GSUBGPOS_GRAPH_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,510 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_MARKBASEPOS_GRAPH_HH +#define GRAPH_MARKBASEPOS_GRAPH_HH + +#include "split-helpers.hh" +#include "coverage-graph.hh" +#include "../OT/Layout/GPOS/MarkBasePos.hh" +#include "../OT/Layout/GPOS/PosLookupSubTable.hh" + +namespace graph { + +struct AnchorMatrix : public OT::Layout::GPOS_impl::AnchorMatrix +{ + bool sanitize (graph_t::vertex_t& vertex, unsigned class_count) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < AnchorMatrix::min_size) return false; + + return vertex_len >= AnchorMatrix::min_size + + OT::Offset16::static_size * class_count * this->rows; + } + + bool shrink (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned old_class_count, + unsigned new_class_count) + { + if (new_class_count >= old_class_count) return false; + auto& o = c.graph.vertices_[this_index].obj; + unsigned base_count = rows; + o.tail = o.head + + AnchorMatrix::min_size + + OT::Offset16::static_size * base_count * new_class_count; + + // Reposition links into the new indexing scheme. + for (auto& link : o.real_links.writer ()) + { + unsigned index = (link.position - 2) / 2; + unsigned base = index / old_class_count; + unsigned klass = index % old_class_count; + if (klass >= new_class_count) + // should have already been removed + return false; + + unsigned new_index = base * new_class_count + klass; + + link.position = (char*) &(this->matrixZ[new_index]) - (char*) this; + } + + return true; + } + + unsigned clone (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned start, + unsigned end, + unsigned class_count) + { + unsigned base_count = rows; + unsigned new_class_count = end - start; + unsigned size = AnchorMatrix::min_size + + OT::Offset16::static_size * new_class_count * rows; + unsigned prime_id = c.create_node (size); + if (prime_id == (unsigned) -1) return -1; + AnchorMatrix* prime = (AnchorMatrix*) c.graph.object (prime_id).head; + prime->rows = base_count; + + auto& o = c.graph.vertices_[this_index].obj; + int num_links = o.real_links.length; + for (int i = 0; i < num_links; i++) + { + const auto& link = o.real_links[i]; + unsigned old_index = (link.position - 2) / OT::Offset16::static_size; + unsigned klass = old_index % class_count; + if (klass < start || klass >= end) continue; + + unsigned base = old_index / class_count; + unsigned new_klass = klass - start; + unsigned new_index = base * new_class_count + new_klass; + + + unsigned child_idx = link.objidx; + c.graph.add_link (&(prime->matrixZ[new_index]), + prime_id, + child_idx); + + auto& child = c.graph.vertices_[child_idx]; + child.remove_parent (this_index); + + o.real_links.remove_unordered (i); + num_links--; + i--; + } + + return prime_id; + } +}; + +struct MarkArray : public OT::Layout::GPOS_impl::MarkArray +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + unsigned min_size = MarkArray::min_size; + if (vertex_len < min_size) return false; + + return vertex_len >= get_size (); + } + + bool shrink (gsubgpos_graph_context_t& c, + const hb_hashmap_t& mark_array_links, + unsigned this_index, + unsigned new_class_count) + { + auto& o = c.graph.vertices_[this_index].obj; + for (const auto& link : o.real_links) + c.graph.vertices_[link.objidx].remove_parent (this_index); + o.real_links.reset (); + + unsigned new_index = 0; + for (const auto& record : this->iter ()) + { + unsigned klass = record.klass; + if (klass >= new_class_count) continue; + + (*this)[new_index].klass = klass; + unsigned position = (char*) &record.markAnchor - (char*) this; + unsigned* objidx; + if (!mark_array_links.has (position, &objidx)) + { + new_index++; + continue; + } + + c.graph.add_link (&(*this)[new_index].markAnchor, this_index, *objidx); + new_index++; + } + + this->len = new_index; + o.tail = o.head + MarkArray::min_size + + OT::Layout::GPOS_impl::MarkRecord::static_size * new_index; + return true; + } + + unsigned clone (gsubgpos_graph_context_t& c, + unsigned this_index, + const hb_hashmap_t& pos_to_index, + hb_set_t& marks, + unsigned start_class) + { + unsigned size = MarkArray::min_size + + OT::Layout::GPOS_impl::MarkRecord::static_size * + marks.get_population (); + unsigned prime_id = c.create_node (size); + if (prime_id == (unsigned) -1) return -1; + MarkArray* prime = (MarkArray*) c.graph.object (prime_id).head; + prime->len = marks.get_population (); + + + unsigned i = 0; + for (hb_codepoint_t mark : marks) + { + (*prime)[i].klass = (*this)[mark].klass - start_class; + unsigned offset_pos = (char*) &((*this)[mark].markAnchor) - (char*) this; + unsigned* anchor_index; + if (pos_to_index.has (offset_pos, &anchor_index)) + c.graph.move_child (this_index, + &((*this)[mark].markAnchor), + prime_id, + &((*prime)[i].markAnchor)); + + i++; + } + + return prime_id; + } +}; + +struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + return vertex_len >= MarkBasePosFormat1::static_size; + } + + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) + { + hb_set_t visited; + + 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 + + MarkArray::min_size + + AnchorMatrix::min_size + + c.graph.vertices_[base_coverage_id].table_size (); + + hb_vector_t class_to_info = get_class_info (c, this_index); + + unsigned class_count = classCount; + auto base_array = c.graph.as_table (this_index, + &baseArray, + class_count); + if (!base_array) return hb_vector_t (); + unsigned base_count = base_array.table->rows; + + unsigned partial_coverage_size = 4; + unsigned accumulated = base_size; + hb_vector_t split_points; + + for (unsigned klass = 0; klass < class_count; klass++) + { + class_info_t& info = class_to_info[klass]; + partial_coverage_size += OT::HBUINT16::static_size * info.marks.get_population (); + unsigned accumulated_delta = + OT::Layout::GPOS_impl::MarkRecord::static_size * info.marks.get_population () + + OT::Offset16::static_size * base_count; + + for (unsigned objidx : info.child_indices) + accumulated_delta += c.graph.find_subgraph_size (objidx, visited); + + accumulated += accumulated_delta; + unsigned total = accumulated + partial_coverage_size; + + if (total >= (1 << 16)) + { + split_points.push (klass); + accumulated = base_size + accumulated_delta; + partial_coverage_size = 4 + OT::HBUINT16::static_size * info.marks.get_population (); + visited.clear (); // node sharing isn't allowed between splits. + } + } + + + const unsigned mark_array_id = c.graph.index_for_offset (this_index, &markArray); + split_context_t split_context { + c, + this, + c.graph.duplicate_if_shared (parent_index, this_index), + std::move (class_to_info), + c.graph.vertices_[mark_array_id].position_to_index_map (), + }; + + return actuate_subtable_split (split_context, split_points); + } + + private: + + struct class_info_t { + hb_set_t marks; + hb_vector_t child_indices; + }; + + struct split_context_t { + gsubgpos_graph_context_t& c; + MarkBasePosFormat1* thiz; + unsigned this_index; + hb_vector_t class_to_info; + hb_hashmap_t mark_array_links; + + hb_set_t marks_for (unsigned start, unsigned end) + { + hb_set_t marks; + for (unsigned klass = start; klass < end; klass++) + { + + class_to_info[klass].marks.iter () + | hb_sink (marks) + ; + } + return marks; + } + + unsigned original_count () + { + return thiz->classCount; + } + + unsigned clone_range (unsigned start, unsigned end) + { + return thiz->clone_range (*this, this->this_index, start, end); + } + + bool shrink (unsigned count) + { + return thiz->shrink (*this, this->this_index, count); + } + }; + + hb_vector_t get_class_info (gsubgpos_graph_context_t& c, + unsigned this_index) + { + hb_vector_t class_to_info; + + unsigned class_count= classCount; + class_to_info.resize (class_count); + + auto mark_array = c.graph.as_table (this_index, &markArray); + if (!mark_array) return hb_vector_t (); + unsigned mark_count = mark_array.table->len; + for (unsigned mark = 0; mark < mark_count; mark++) + { + unsigned klass = (*mark_array.table)[mark].get_class (); + class_to_info[klass].marks.add (mark); + } + + for (const auto& link : mark_array.vertex->obj.real_links) + { + unsigned mark = (link.position - 2) / + OT::Layout::GPOS_impl::MarkRecord::static_size; + unsigned klass = (*mark_array.table)[mark].get_class (); + class_to_info[klass].child_indices.push (link.objidx); + } + + unsigned base_array_id = + c.graph.index_for_offset (this_index, &baseArray); + auto& base_array_v = c.graph.vertices_[base_array_id]; + + for (const auto& link : base_array_v.obj.real_links) + { + unsigned index = (link.position - 2) / OT::Offset16::static_size; + unsigned klass = index % class_count; + class_to_info[klass].child_indices.push (link.objidx); + } + + return class_to_info; + } + + bool shrink (split_context_t& sc, + unsigned this_index, + unsigned count) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Shrinking MarkBasePosFormat1 (%u) to [0, %u).", + this_index, + count); + + unsigned old_count = classCount; + if (count >= old_count) + return true; + + classCount = count; + + auto mark_coverage = sc.c.graph.as_mutable_table (this_index, + &markCoverage); + if (!mark_coverage) return false; + hb_set_t marks = sc.marks_for (0, count); + auto new_coverage = + + hb_enumerate (mark_coverage.table->iter ()) + | hb_filter (marks, hb_first) + | hb_map_retains_sorting (hb_second) + ; + if (!Coverage::make_coverage (sc.c, + new_coverage, + mark_coverage.index, + 4 + 2 * marks.get_population ())) + return false; + + + auto base_array = sc.c.graph.as_mutable_table (this_index, + &baseArray, + old_count); + if (!base_array || !base_array.table->shrink (sc.c, + base_array.index, + old_count, + count)) + return false; + + auto mark_array = sc.c.graph.as_mutable_table (this_index, + &markArray); + if (!mark_array || !mark_array.table->shrink (sc.c, + sc.mark_array_links, + mark_array.index, + count)) + return false; + + return true; + } + + // Create a new MarkBasePos that has all of the data for classes from [start, end). + unsigned clone_range (split_context_t& sc, + unsigned this_index, + unsigned start, unsigned end) const + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Cloning MarkBasePosFormat1 (%u) range [%u, %u).", this_index, start, end); + + graph_t& graph = sc.c.graph; + unsigned prime_size = OT::Layout::GPOS_impl::MarkBasePosFormat1_2::static_size; + + unsigned prime_id = sc.c.create_node (prime_size); + if (prime_id == (unsigned) -1) return -1; + + MarkBasePosFormat1* prime = (MarkBasePosFormat1*) graph.object (prime_id).head; + prime->format = this->format; + unsigned new_class_count = end - start; + prime->classCount = new_class_count; + + unsigned base_coverage_id = + graph.index_for_offset (sc.this_index, &baseCoverage); + graph.add_link (&(prime->baseCoverage), prime_id, base_coverage_id); + graph.duplicate (prime_id, base_coverage_id); + + auto mark_coverage = sc.c.graph.as_table (this_index, + &markCoverage); + if (!mark_coverage) return false; + hb_set_t marks = sc.marks_for (start, end); + auto new_coverage = + + hb_enumerate (mark_coverage.table->iter ()) + | hb_filter (marks, hb_first) + | hb_map_retains_sorting (hb_second) + ; + if (!Coverage::add_coverage (sc.c, + prime_id, + 2, + + new_coverage, + marks.get_population () * 2 + 4)) + return -1; + + auto mark_array = + graph.as_table (sc.this_index, &markArray); + if (!mark_array) return -1; + unsigned new_mark_array = + mark_array.table->clone (sc.c, + mark_array.index, + sc.mark_array_links, + marks, + start); + graph.add_link (&(prime->markArray), prime_id, new_mark_array); + + unsigned class_count = classCount; + auto base_array = + graph.as_table (sc.this_index, &baseArray, class_count); + if (!base_array) return -1; + unsigned new_base_array = + base_array.table->clone (sc.c, + base_array.index, + start, end, this->classCount); + graph.add_link (&(prime->baseArray), prime_id, new_base_array); + + return prime_id; + } +}; + + +struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos +{ + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) + { + switch (u.format) { + case 1: + 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. +#endif + default: + return hb_vector_t (); + } + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < u.format.get_size ()) return false; + + switch (u.format) { + case 1: + return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex); +#ifndef HB_NO_BEYOND_64K + case 2: HB_FALLTHROUGH; +#endif + default: + // We don't handle format 3 and 4 here. + return false; + } + } +}; + + +} + +#endif // GRAPH_MARKBASEPOS_GRAPH_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,647 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_PAIRPOS_GRAPH_HH +#define GRAPH_PAIRPOS_GRAPH_HH + +#include "split-helpers.hh" +#include "coverage-graph.hh" +#include "classdef-graph.hh" +#include "../OT/Layout/GPOS/PairPos.hh" +#include "../OT/Layout/GPOS/PosLookupSubTable.hh" + +namespace graph { + +struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + unsigned min_size = OT::Layout::GPOS_impl::PairPosFormat1_3::min_size; + if (vertex_len < min_size) return false; + + return vertex_len >= + min_size + pairSet.get_size () - pairSet.len.get_size(); + } + + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) + { + hb_set_t visited; + + const unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + const unsigned coverage_size = c.graph.vertices_[coverage_id].table_size (); + const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat1_3::min_size; + + unsigned partial_coverage_size = 4; + unsigned accumulated = base_size; + hb_vector_t split_points; + for (unsigned i = 0; i < pairSet.len; i++) + { + unsigned pair_set_index = pair_set_graph_index (c, this_index, i); + unsigned accumulated_delta = + c.graph.find_subgraph_size (pair_set_index, visited) + + SmallTypes::size; // for PairSet offset. + partial_coverage_size += OT::HBUINT16::static_size; + + accumulated += accumulated_delta; + unsigned total = accumulated + hb_min (partial_coverage_size, coverage_size); + + if (total >= (1 << 16)) + { + split_points.push (i); + accumulated = base_size + accumulated_delta; + partial_coverage_size = 6; + visited.clear (); // node sharing isn't allowed between splits. + } + } + + split_context_t split_context { + c, + this, + c.graph.duplicate_if_shared (parent_index, this_index), + }; + + return actuate_subtable_split (split_context, split_points); + } + + private: + + struct split_context_t { + gsubgpos_graph_context_t& c; + PairPosFormat1* thiz; + unsigned this_index; + + unsigned original_count () + { + return thiz->pairSet.len; + } + + unsigned clone_range (unsigned start, unsigned end) + { + return thiz->clone_range (this->c, this->this_index, start, end); + } + + bool shrink (unsigned count) + { + return thiz->shrink (this->c, this->this_index, count); + } + }; + + bool shrink (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned count) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Shrinking PairPosFormat1 (%u) to [0, %u).", + this_index, + count); + unsigned old_count = pairSet.len; + if (count >= old_count) + return true; + + pairSet.len = count; + c.graph.vertices_[this_index].obj.tail -= (old_count - count) * SmallTypes::size; + + auto coverage = c.graph.as_mutable_table (this_index, &this->coverage); + if (!coverage) return false; + + unsigned coverage_size = coverage.vertex->table_size (); + auto new_coverage = + + hb_zip (coverage.table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t p) { + return p.second < count; + }) + | hb_map_retains_sorting (hb_first) + ; + + return Coverage::make_coverage (c, new_coverage, coverage.index, coverage_size); + } + + // Create a new PairPos including PairSet's from start (inclusive) to end (exclusive). + // Returns object id of the new object. + unsigned clone_range (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned start, unsigned end) const + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Cloning PairPosFormat1 (%u) range [%u, %u).", this_index, start, end); + + unsigned num_pair_sets = end - start; + unsigned prime_size = OT::Layout::GPOS_impl::PairPosFormat1_3::min_size + + num_pair_sets * SmallTypes::size; + + unsigned pair_pos_prime_id = c.create_node (prime_size); + if (pair_pos_prime_id == (unsigned) -1) return -1; + + PairPosFormat1* pair_pos_prime = (PairPosFormat1*) c.graph.object (pair_pos_prime_id).head; + pair_pos_prime->format = this->format; + pair_pos_prime->valueFormat[0] = this->valueFormat[0]; + pair_pos_prime->valueFormat[1] = this->valueFormat[1]; + pair_pos_prime->pairSet.len = num_pair_sets; + + for (unsigned i = start; i < end; i++) + { + c.graph.move_child<> (this_index, + &pairSet[i], + pair_pos_prime_id, + &pair_pos_prime->pairSet[i - start]); + } + + unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + if (!Coverage::clone_coverage (c, + coverage_id, + pair_pos_prime_id, + 2, + start, end)) + return -1; + + return pair_pos_prime_id; + } + + + + unsigned pair_set_graph_index (gsubgpos_graph_context_t& c, unsigned this_index, unsigned i) const + { + return c.graph.index_for_offset (this_index, &pairSet[i]); + } +}; + +struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + size_t vertex_len = vertex.table_size (); + unsigned min_size = OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; + if (vertex_len < min_size) return false; + + const unsigned class1_count = class1Count; + return vertex_len >= + min_size + class1_count * get_class1_record_size (); + } + + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) + { + const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; + const unsigned class_def_2_size = size_of (c, this_index, &classDef2); + const Coverage* coverage = get_coverage (c, this_index); + const ClassDef* class_def_1 = get_class_def_1 (c, this_index); + 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)); + }) + ; + class_def_size_estimator_t estimator (gid_and_class); + + const unsigned class1_count = class1Count; + const unsigned class2_count = class2Count; + const unsigned class1_record_size = get_class1_record_size (); + + const unsigned value_1_len = valueFormat1.get_len (); + const unsigned value_2_len = valueFormat2.get_len (); + const unsigned total_value_len = value_1_len + value_2_len; + + unsigned accumulated = base_size; + unsigned coverage_size = 4; + unsigned class_def_1_size = 4; + unsigned max_coverage_size = coverage_size; + unsigned max_class_def_1_size = class_def_1_size; + + hb_vector_t split_points; + + hb_hashmap_t device_tables = get_all_device_tables (c, this_index); + hb_vector_t format1_device_table_indices = valueFormat1.get_device_table_indices (); + hb_vector_t format2_device_table_indices = valueFormat2.get_device_table_indices (); + bool has_device_tables = bool(format1_device_table_indices) || bool(format2_device_table_indices); + + hb_set_t visited; + for (unsigned i = 0; i < class1_count; i++) + { + unsigned accumulated_delta = class1_record_size; + coverage_size += estimator.incremental_coverage_size (i); + class_def_1_size += estimator.incremental_class_def_size (i); + max_coverage_size = hb_max (max_coverage_size, coverage_size); + max_class_def_1_size = hb_max (max_class_def_1_size, class_def_1_size); + + if (has_device_tables) { + for (unsigned j = 0; j < class2_count; j++) + { + unsigned value1_index = total_value_len * (class2_count * i + j); + unsigned value2_index = value1_index + value_1_len; + accumulated_delta += size_of_value_record_children (c, + device_tables, + format1_device_table_indices, + value1_index, + visited); + accumulated_delta += size_of_value_record_children (c, + device_tables, + format2_device_table_indices, + value2_index, + visited); + } + } + + accumulated += accumulated_delta; + unsigned total = accumulated + + coverage_size + class_def_1_size + class_def_2_size + // The largest object will pack last and can exceed the size limit. + - hb_max (hb_max (coverage_size, class_def_1_size), class_def_2_size); + if (total >= (1 << 16)) + { + split_points.push (i); + // split does not include i, so add the size for i when we reset the size counters. + accumulated = base_size + accumulated_delta; + coverage_size = 4 + estimator.incremental_coverage_size (i); + class_def_1_size = 4 + estimator.incremental_class_def_size (i); + visited.clear (); // node sharing isn't allowed between splits. + } + } + + split_context_t split_context { + c, + this, + c.graph.duplicate_if_shared (parent_index, this_index), + class1_record_size, + total_value_len, + value_1_len, + value_2_len, + max_coverage_size, + max_class_def_1_size, + device_tables, + format1_device_table_indices, + format2_device_table_indices + }; + + return actuate_subtable_split (split_context, split_points); + } + private: + + struct split_context_t + { + gsubgpos_graph_context_t& c; + PairPosFormat2* thiz; + unsigned this_index; + unsigned class1_record_size; + unsigned value_record_len; + unsigned value1_record_len; + unsigned value2_record_len; + unsigned max_coverage_size; + unsigned max_class_def_size; + + const hb_hashmap_t& device_tables; + const hb_vector_t& format1_device_table_indices; + const hb_vector_t& format2_device_table_indices; + + unsigned original_count () + { + return thiz->class1Count; + } + + unsigned clone_range (unsigned start, unsigned end) + { + return thiz->clone_range (*this, start, end); + } + + bool shrink (unsigned count) + { + return thiz->shrink (*this, count); + } + }; + + size_t get_class1_record_size () const + { + const size_t class2_count = class2Count; + return + class2_count * (valueFormat1.get_size () + valueFormat2.get_size ()); + } + + unsigned clone_range (split_context_t& split_context, + unsigned start, unsigned end) const + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Cloning PairPosFormat2 (%u) range [%u, %u).", split_context.this_index, start, end); + + graph_t& graph = split_context.c.graph; + + unsigned num_records = end - start; + unsigned prime_size = OT::Layout::GPOS_impl::PairPosFormat2_4::min_size + + num_records * split_context.class1_record_size; + + unsigned pair_pos_prime_id = split_context.c.create_node (prime_size); + if (pair_pos_prime_id == (unsigned) -1) return -1; + + PairPosFormat2* pair_pos_prime = + (PairPosFormat2*) graph.object (pair_pos_prime_id).head; + pair_pos_prime->format = this->format; + pair_pos_prime->valueFormat1 = this->valueFormat1; + pair_pos_prime->valueFormat2 = this->valueFormat2; + pair_pos_prime->class1Count = num_records; + pair_pos_prime->class2Count = this->class2Count; + clone_class1_records (split_context, + pair_pos_prime_id, + start, + end); + + unsigned coverage_id = + graph.index_for_offset (split_context.this_index, &coverage); + unsigned class_def_1_id = + graph.index_for_offset (split_context.this_index, &classDef1); + auto& coverage_v = graph.vertices_[coverage_id]; + auto& class_def_1_v = graph.vertices_[class_def_1_id]; + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + ClassDef* class_def_1_table = (ClassDef*) class_def_1_v.obj.head; + if (!coverage_table + || !coverage_table->sanitize (coverage_v) + || !class_def_1_table + || !class_def_1_table->sanitize (class_def_1_v)) + return -1; + + 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)); + }) + | hb_filter ([&] (hb_codepoint_t klass) { + return klass >= start && klass < end; + }, hb_second) + | hb_map_retains_sorting ([&] (hb_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); + }) + ; + + if (!Coverage::add_coverage (split_context.c, + pair_pos_prime_id, + 2, + + klass_map | hb_map_retains_sorting (hb_first), + split_context.max_coverage_size)) + return -1; + + // classDef1 + if (!ClassDef::add_class_def (split_context.c, + pair_pos_prime_id, + 8, + + klass_map, + split_context.max_class_def_size)) + return -1; + + // classDef2 + unsigned class_def_2_id = + graph.index_for_offset (split_context.this_index, &classDef2); + auto* class_def_link = graph.vertices_[pair_pos_prime_id].obj.real_links.push (); + 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.duplicate (pair_pos_prime_id, class_def_2_id); + + return pair_pos_prime_id; + } + + void clone_class1_records (split_context_t& split_context, + unsigned pair_pos_prime_id, + unsigned start, unsigned end) const + { + PairPosFormat2* pair_pos_prime = + (PairPosFormat2*) split_context.c.graph.object (pair_pos_prime_id).head; + + char* start_addr = ((char*)&values[0]) + start * split_context.class1_record_size; + unsigned num_records = end - start; + hb_memcpy (&pair_pos_prime->values[0], + start_addr, + num_records * split_context.class1_record_size); + + if (!split_context.format1_device_table_indices + && !split_context.format2_device_table_indices) + // No device tables to move over. + return; + + unsigned class2_count = class2Count; + for (unsigned i = start; i < end; i++) + { + for (unsigned j = 0; j < class2_count; j++) + { + unsigned value1_index = split_context.value_record_len * (class2_count * i + j); + unsigned value2_index = value1_index + split_context.value1_record_len; + + unsigned new_value1_index = split_context.value_record_len * (class2_count * (i - start) + j); + unsigned new_value2_index = new_value1_index + split_context.value1_record_len; + + transfer_device_tables (split_context, + pair_pos_prime_id, + split_context.format1_device_table_indices, + value1_index, + new_value1_index); + + transfer_device_tables (split_context, + pair_pos_prime_id, + split_context.format2_device_table_indices, + value2_index, + new_value2_index); + } + } + } + + void transfer_device_tables (split_context_t& split_context, + unsigned pair_pos_prime_id, + const hb_vector_t& device_table_indices, + unsigned old_value_record_index, + unsigned new_value_record_index) const + { + PairPosFormat2* pair_pos_prime = + (PairPosFormat2*) split_context.c.graph.object (pair_pos_prime_id).head; + + for (unsigned i : device_table_indices) + { + OT::Offset16* record = (OT::Offset16*) &values[old_value_record_index + i]; + unsigned record_position = ((char*) record) - ((char*) this); + if (!split_context.device_tables.has (record_position)) continue; + + split_context.c.graph.move_child ( + split_context.this_index, + record, + pair_pos_prime_id, + (OT::Offset16*) &pair_pos_prime->values[new_value_record_index + i]); + } + } + + bool shrink (split_context_t& split_context, + unsigned count) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Shrinking PairPosFormat2 (%u) to [0, %u).", + split_context.this_index, + count); + unsigned old_count = class1Count; + if (count >= old_count) + return true; + + graph_t& graph = split_context.c.graph; + class1Count = count; + graph.vertices_[split_context.this_index].obj.tail -= + (old_count - count) * split_context.class1_record_size; + + auto coverage = + graph.as_mutable_table (split_context.this_index, &this->coverage); + if (!coverage) return false; + + auto class_def_1 = + graph.as_mutable_table (split_context.this_index, &classDef1); + if (!class_def_1) return false; + + 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)); + }) + | hb_filter ([&] (hb_codepoint_t klass) { + return klass < count; + }, hb_second) + ; + + auto new_coverage = + klass_map | hb_map_retains_sorting (hb_first); + if (!Coverage::make_coverage (split_context.c, + + new_coverage, + coverage.index, + // existing ranges my not be kept, worst case size is a format 1 + // coverage table. + 4 + new_coverage.len() * 2)) + return false; + + return ClassDef::make_class_def (split_context.c, + + klass_map, + class_def_1.index, + class_def_1.vertex->table_size ()); + } + + hb_hashmap_t + get_all_device_tables (gsubgpos_graph_context_t& c, + unsigned this_index) const + { + const auto& v = c.graph.vertices_[this_index]; + return v.position_to_index_map (); + } + + const Coverage* get_coverage (gsubgpos_graph_context_t& c, + unsigned this_index) const + { + unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + auto& coverage_v = c.graph.vertices_[coverage_id]; + + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + if (!coverage_table || !coverage_table->sanitize (coverage_v)) + return &Null(Coverage); + return coverage_table; + } + + const ClassDef* get_class_def_1 (gsubgpos_graph_context_t& c, + unsigned this_index) const + { + unsigned class_def_1_id = c.graph.index_for_offset (this_index, &classDef1); + auto& class_def_1_v = c.graph.vertices_[class_def_1_id]; + + ClassDef* class_def_1_table = (ClassDef*) class_def_1_v.obj.head; + if (!class_def_1_table || !class_def_1_table->sanitize (class_def_1_v)) + return &Null(ClassDef); + return class_def_1_table; + } + + unsigned size_of_value_record_children (gsubgpos_graph_context_t& c, + const hb_hashmap_t& device_tables, + const hb_vector_t device_table_indices, + unsigned value_record_index, + hb_set_t& visited) + { + unsigned size = 0; + for (unsigned i : device_table_indices) + { + OT::Layout::GPOS_impl::Value* record = &values[value_record_index + i]; + unsigned record_position = ((char*) record) - ((char*) this); + unsigned* obj_idx; + if (!device_tables.has (record_position, &obj_idx)) continue; + size += c.graph.find_subgraph_size (*obj_idx, visited); + } + return size; + } + + unsigned size_of (gsubgpos_graph_context_t& c, + unsigned this_index, + const void* offset) const + { + const unsigned id = c.graph.index_for_offset (this_index, offset); + return c.graph.vertices_[id].table_size (); + } +}; + +struct PairPos : public OT::Layout::GPOS_impl::PairPos +{ + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) + { + switch (u.format) { + case 1: + return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); + case 2: + return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index); +#ifndef HB_NO_BEYOND_64K + case 3: HB_FALLTHROUGH; + case 4: HB_FALLTHROUGH; + // Don't split 24bit PairPos's. +#endif + default: + return hb_vector_t (); + } + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < u.format.get_size ()) return false; + + switch (u.format) { + case 1: + return ((PairPosFormat1*)(&u.format1))->sanitize (vertex); + case 2: + return ((PairPosFormat2*)(&u.format2))->sanitize (vertex); +#ifndef HB_NO_BEYOND_64K + case 3: HB_FALLTHROUGH; + case 4: HB_FALLTHROUGH; +#endif + default: + // We don't handle format 3 and 4 here. + return false; + } + } +}; + +} + +#endif // GRAPH_PAIRPOS_GRAPH_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh 2023-07-05 07:11:54.000000000 +0000 @@ -33,6 +33,23 @@ { unsigned parent; unsigned child; + + bool operator != (const overflow_record_t o) const + { return !(*this == o); } + + inline bool operator == (const overflow_record_t& o) const + { + return parent == o.parent && + child == o.child; + } + + inline uint32_t hash () const + { + uint32_t current = 0; + current = current * 31 + hb_hash (parent); + current = current * 31 + hb_hash (child); + return current; + } }; inline @@ -94,6 +111,7 @@ if (overflows) overflows->resize (0); graph.update_positions (); + hb_hashmap_t record_set; const auto& vertices = graph.vertices_; for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--) { @@ -109,7 +127,10 @@ overflow_record_t r; r.parent = parent_idx; r.child = link.objidx; + if (record_set.has(&r)) continue; // don't keep duplicate overflows. + overflows->push (r); + record_set.set(&r, true); } } @@ -132,8 +153,8 @@ const auto& child = graph.vertices_[o.child]; DEBUG_MSG (SUBSET_REPACK, nullptr, " overflow from " - "%4d (%4d in, %4d out, space %2d) => " - "%4d (%4d in, %4d out, space %2d)", + "%4u (%4u in, %4u out, space %2u) => " + "%4u (%4u in, %4u out, space %2u)", o.parent, parent.incoming_edges (), parent.obj.real_links.length + parent.obj.virtual_links.length, @@ -144,7 +165,7 @@ graph.space_for (o.child)); } if (overflows.length > 10) { - DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10); + DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %u more overflows.", overflows.length - 10); } } @@ -223,7 +244,7 @@ return nullptr; } - memcpy (start, vertices[i].obj.head, size); + hb_memcpy (start, vertices[i].obj.head, size); // Only real links needs to be serialized. for (const auto& link : vertices[i].obj.real_links) diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright © 2022 Google, 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. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_SPLIT_HELPERS_HH +#define GRAPH_SPLIT_HELPERS_HH + +namespace graph { + +template +HB_INTERNAL +hb_vector_t actuate_subtable_split (Context& split_context, + const hb_vector_t& split_points) +{ + hb_vector_t new_objects; + if (!split_points) + return new_objects; + + for (unsigned i = 0; i < split_points.length; i++) + { + unsigned start = split_points[i]; + unsigned end = (i < split_points.length - 1) + ? split_points[i + 1] + : split_context.original_count (); + unsigned id = split_context.clone_range (start, end); + + if (id == (unsigned) -1) + { + new_objects.reset (); + new_objects.allocated = -1; // mark error + return new_objects; + } + new_objects.push (id); + } + + if (!split_context.shrink (split_points[0])) + { + new_objects.reset (); + new_objects.allocated = -1; // mark error + } + + return new_objects; +} + +} + +#endif // GRAPH_SPLIT_HELPERS_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -42,7 +42,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -78,7 +78,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc 2023-07-05 07:11:54.000000000 +0000 @@ -131,6 +131,7 @@ {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('r','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF}, {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF}, {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE}, @@ -229,7 +230,7 @@ * * Note: does not examine the `GSUB` table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ @@ -243,15 +244,23 @@ void hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, - hb_buffer_t *buffer) -{ + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned num_features) +{ + hb_aat_map_builder_t builder (font->face, plan->props); + for (unsigned i = 0; i < num_features; i++) + builder.add_feature (features[i]); + hb_aat_map_t map; + builder.compile (map); + hb_blob_t *morx_blob = font->face->table.morx.get_blob (); const AAT::morx& morx = *morx_blob->as (); if (morx.has_data ()) { AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob); if (!buffer->message (font, "start table morx")) return; - morx.apply (&c); + morx.apply (&c, map); (void) buffer->message (font, "end table morx"); return; } @@ -262,7 +271,7 @@ { AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob); if (!buffer->message (font, "start table mort")) return; - mort.apply (&c); + mort.apply (&c, map); (void) buffer->message (font, "end table mort"); return; } @@ -288,7 +297,7 @@ void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) { - hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph); + buffer->delete_glyphs_inplace (is_deleted_glyph); } /** @@ -300,7 +309,7 @@ * * Note: does not examine the `GPOS` table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ @@ -333,7 +342,7 @@ * Tests whether the specified face includes any tracking information * in the `trak` table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -28,6 +28,7 @@ #define HB_AAT_LAYOUT_COMMON_HH #include "hb-aat-layout.hh" +#include "hb-aat-map.hh" #include "hb-open-type.hh" namespace OT { @@ -39,6 +40,43 @@ using namespace OT; +struct ankr; + +struct hb_aat_apply_context_t : + hb_dispatch_context_t +{ + const char *get_name () { return "APPLY"; } + template + return_t dispatch (const T &obj) { return obj.apply (this); } + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return r; } + + const hb_ot_shape_plan_t *plan; + hb_font_t *font; + hb_face_t *face; + hb_buffer_t *buffer; + hb_sanitize_context_t sanitizer; + const ankr *ankr_table; + const OT::GDEF *gdef_table; + const hb_sorted_vector_t *range_flags = nullptr; + hb_mask_t subtable_flags = 0; + + /* Unused. For debug tracing only. */ + unsigned int lookup_index; + + HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_, + hb_font_t *font_, + hb_buffer_t *buffer_, + hb_blob_t *blob = const_cast (&Null (hb_blob_t))); + + HB_INTERNAL ~hb_aat_apply_context_t (); + + HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_); + + void set_lookup_index (unsigned int i) { lookup_index = i; } +}; + + /* * Lookup Table */ @@ -415,18 +453,7 @@ public: DEFINE_SIZE_UNION (2, format); }; -/* Lookup 0 has unbounded size (dependant on num_glyphs). So we need to defined - * special NULL objects for Lookup<> objects, but since it's template our macros - * don't work. So we have to hand-code them here. UGLY. */ -} /* Close namespace. */ -/* Ugly hand-coded null objects for template Lookup<> :(. */ -extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2]; -template -struct Null> { - static AAT::Lookup const & get_null () - { return *reinterpret_cast *> (_hb_Null_AAT_Lookup); } -}; -namespace AAT { +DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); enum { DELETED_GLYPH = 0xFFFF }; @@ -681,6 +708,13 @@ const void *base, const T *array) { + /* https://github.com/harfbuzz/harfbuzz/issues/3483 */ + /* If offset is less than base, return an offset that would + * result in an address half a 32bit address-space away, + * to make sure sanitize fails even on 32bit builds. */ + if (unlikely (offset < unsigned ((const char *) array - (const char *) base))) + return INT_MAX / T::static_size; + /* https://github.com/harfbuzz/harfbuzz/issues/2816 */ return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size; } @@ -744,16 +778,44 @@ num_glyphs (face_->get_num_glyphs ()) {} template - void drive (context_t *c) + void drive (context_t *c, hb_aat_apply_context_t *ac) { if (!c->in_place) buffer->clear_output (); int state = StateTableT::STATE_START_OF_TEXT; + // If there's only one range, we already checked the flag. + auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr; for (buffer->idx = 0; buffer->successful;) { + /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */ + if (last_range) + { + auto *range = last_range; + if (buffer->idx < buffer->len) + { + unsigned cluster = buffer->cur().cluster; + while (cluster < range->cluster_first) + range--; + while (cluster > range->cluster_last) + range++; + + + last_range = range; + } + if (!(range->flags & ac->subtable_flags)) + { + if (buffer->idx == buffer->len || unlikely (!buffer->successful)) + break; + + state = StateTableT::STATE_START_OF_TEXT; + (void) buffer->next_glyph (); + continue; + } + } + unsigned int klass = buffer->idx < buffer->len ? - machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) : + machine.get_class (buffer->cur().codepoint, num_glyphs) : (unsigned) StateTableT::CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); const EntryT &entry = machine.get_entry (state, klass); @@ -849,41 +911,6 @@ }; -struct ankr; - -struct hb_aat_apply_context_t : - hb_dispatch_context_t -{ - const char *get_name () { return "APPLY"; } - template - return_t dispatch (const T &obj) { return obj.apply (this); } - static return_t default_return_value () { return false; } - bool stop_sublookup_iteration (return_t r) const { return r; } - - const hb_ot_shape_plan_t *plan; - hb_font_t *font; - hb_face_t *face; - hb_buffer_t *buffer; - hb_sanitize_context_t sanitizer; - const ankr *ankr_table; - const OT::GDEF *gdef_table; - - /* Unused. For debug tracing only. */ - unsigned int lookup_index; - - HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_, - hb_font_t *font_, - hb_buffer_t *buffer_, - hb_blob_t *blob = const_cast (&Null (hb_blob_t))); - - HB_INTERNAL ~hb_aat_apply_context_t (); - - HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_); - - void set_lookup_index (unsigned int i) { lookup_index = i; } -}; - - } /* namespace AAT */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -62,7 +62,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh 2023-07-05 07:11:54.000000000 +0000 @@ -53,7 +53,9 @@ HB_INTERNAL void hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, - hb_buffer_t *buffer); + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned num_features); HB_INTERNAL void hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -48,7 +48,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } HBUINT16 actionClass; /* The JustClass value associated with this @@ -65,14 +65,14 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } ActionSubrecordHeader header; - HBFixed lowerLimit; /* If the distance factor is less than this value, + F16DOT16 lowerLimit; /* If the distance factor is less than this value, * then the ligature is decomposed. */ - HBFixed upperLimit; /* If the distance factor is greater than this value, + F16DOT16 upperLimit; /* If the distance factor is greater than this value, * then the ligature is decomposed. */ HBUINT16 order; /* Numerical order in which this ligature will * be decomposed; you may want infrequent ligatures @@ -112,13 +112,13 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: ActionSubrecordHeader header; - HBFixed substThreshold; /* Distance growth factor (in ems) at which + F16DOT16 substThreshold; /* Distance growth factor (in ems) at which * this glyph is replaced and the growth factor * recalculated. */ HBGlyphID16 addGlyph; /* Glyph to be added as kashida. If this value is @@ -137,7 +137,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -146,13 +146,13 @@ HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis. * This would normally be 0x64756374 ('duct'), * but you may use any axis the font contains. */ - HBFixed minimumLimit; /* The lowest value for the ductility axis that + F16DOT16 minimumLimit; /* The lowest value for the ductility axis that * still yields an acceptable appearance. Normally * this will be 1.0. */ - HBFixed noStretchValue; /* This is the default value that corresponds to + F16DOT16 noStretchValue; /* This is the default value that corresponds to * no change in appearance. Normally, this will * be 1.0. */ - HBFixed maximumLimit; /* The highest value for the ductility axis that + F16DOT16 maximumLimit; /* The highest value for the ductility axis that * still yields an acceptable appearance. */ public: DEFINE_SIZE_STATIC (22); @@ -163,7 +163,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -271,14 +271,14 @@ }; protected: - HBFixed beforeGrowLimit;/* The ratio by which the advance width of the + F16DOT16 beforeGrowLimit;/* The ratio by which the advance width of the * glyph is permitted to grow on the left or top side. */ - HBFixed beforeShrinkLimit; + F16DOT16 beforeShrinkLimit; /* The ratio by which the advance width of the * glyph is permitted to shrink on the left or top side. */ - HBFixed afterGrowLimit; /* The ratio by which the advance width of the glyph + F16DOT16 afterGrowLimit; /* The ratio by which the advance width of the glyph * is permitted to shrink on the left or top side. */ - HBFixed afterShrinkLimit; + F16DOT16 afterShrinkLimit; /* The ratio by which the advance width of the glyph * is at most permitted to shrink on the right or * bottom side. */ @@ -294,7 +294,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -350,7 +350,7 @@ driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->font->face); - driver.drive (&dc); + driver.drive (&dc, c); return_trace (true); } @@ -594,7 +594,7 @@ driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->font->face); - driver.drive (&dc); + driver.drive (&dc, c); return_trace (true); } @@ -751,7 +751,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } public: @@ -869,6 +869,8 @@ bool apply (AAT::hb_aat_apply_context_t *c) const { + c->buffer->unsafe_to_concat (); + typedef typename T::SubTable SubTable; bool ret = false; @@ -889,7 +891,7 @@ reverse = bool (st->u.header.coverage & st->u.header.Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); - if (!c->buffer->message (c->font, "start subtable %d", c->lookup_index)) + if (!c->buffer->message (c->font, "start subtable %u", c->lookup_index)) goto skip; if (!seenCrossStream && @@ -921,7 +923,7 @@ if (reverse) c->buffer->reverse (); - (void) c->buffer->message (c->font, "end subtable %d", c->lookup_index); + (void) c->buffer->message (c->font, "end subtable %u", c->lookup_index); skip: st = &StructAfter (*st); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -131,14 +131,14 @@ hb_glyph_info_t *info = buffer->info; hb_glyph_info_t buf[4]; - memcpy (buf, info + start, l * sizeof (buf[0])); - memcpy (buf + 2, info + end - r, r * sizeof (buf[0])); + hb_memcpy (buf, info + start, l * sizeof (buf[0])); + hb_memcpy (buf + 2, info + end - r, r * sizeof (buf[0])); if (l != r) memmove (info + start + r, info + start + l, (end - start - l - r) * sizeof (buf[0])); - memcpy (info + start, buf + 2, r * sizeof (buf[0])); - memcpy (info + end - l, buf, l * sizeof (buf[0])); + hb_memcpy (info + start, buf + 2, r * sizeof (buf[0])); + hb_memcpy (info + end - l, buf, l * sizeof (buf[0])); if (reverse_l) { buf[0] = info[end - 1]; @@ -169,7 +169,7 @@ driver_context_t dc (this); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c); return_trace (dc.ret); } @@ -325,7 +325,7 @@ driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c); return_trace (dc.ret); } @@ -525,7 +525,7 @@ if (unlikely (!componentData.sanitize (&c->sanitizer))) break; ligature_idx += componentData; - DEBUG_MSG (APPLY, nullptr, "Action store %u last %u", + DEBUG_MSG (APPLY, nullptr, "Action store %d last %d", bool (action & LigActionStore), bool (action & LigActionLast)); if (action & (LigActionStore | LigActionLast)) @@ -577,7 +577,7 @@ driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c); return_trace (dc.ret); } @@ -618,8 +618,27 @@ hb_glyph_info_t *info = c->buffer->info; unsigned int count = c->buffer->len; + // If there's only one range, we already checked the flag. + auto *last_range = c->range_flags && (c->range_flags->length > 1) ? &(*c->range_flags)[0] : nullptr; for (unsigned int i = 0; i < count; i++) { + /* This block copied from StateTableDriver::drive. Keep in sync. */ + if (last_range) + { + auto *range = last_range; + { + unsigned cluster = info[i].cluster; + while (cluster < range->cluster_first) + range--; + while (cluster > range->cluster_last) + range++; + + last_range = range; + } + if (!(range->flags & c->subtable_flags)) + continue; + } + const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { @@ -820,7 +839,7 @@ driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c); return_trace (dc.ret); } @@ -968,7 +987,7 @@ // Check whether this type/setting pair was requested in the map, and if so, apply its flags. // (The search here only looks at the type and setting fields of feature_info_t.) hb_aat_map_builder_t::feature_info_t info = { type, setting, false, 0 }; - if (map->features.bsearch (info)) + if (map->current_features.bsearch (info)) { flags &= feature.disableFlags; flags |= feature.enableFlags; @@ -980,13 +999,21 @@ setting = HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS; goto retry; } +#ifndef HB_NO_AAT + else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE && setting && + /* TODO: Rudimentary language matching. */ + hb_language_matches (map->face->table.ltag->get_language (setting - 1), map->props.language)) + { + flags &= feature.disableFlags; + flags |= feature.enableFlags; + } +#endif } } return flags; } - void apply (hb_aat_apply_context_t *c, - hb_mask_t flags) const + void apply (hb_aat_apply_context_t *c) const { const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); unsigned int count = subtableCount; @@ -994,8 +1021,10 @@ { bool reverse; - if (!(subtable->subFeatureFlags & flags)) + if (hb_none (hb_iter (c->range_flags) | + hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); }))) goto skip; + c->subtable_flags = subtable->subFeatureFlags; if (!(subtable->get_coverage() & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != @@ -1034,7 +1063,7 @@ bool (subtable->get_coverage () & ChainSubtable::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); - if (!c->buffer->message (c->font, "start chainsubtable %d", c->lookup_index)) + if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) goto skip; if (reverse) @@ -1045,7 +1074,7 @@ if (reverse) c->buffer->reverse (); - (void) c->buffer->message (c->font, "end chainsubtable %d", c->lookup_index); + (void) c->buffer->message (c->font, "end chainsubtable %u", c->lookup_index); if (unlikely (!c->buffer->successful)) return; @@ -1111,22 +1140,31 @@ { const Chain *chain = &firstChain; unsigned int count = chainCount; + if (unlikely (!map->chain_flags.resize (count))) + return; for (unsigned int i = 0; i < count; i++) { - map->chain_flags.push (chain->compile_flags (mapper)); + map->chain_flags[i].push (hb_aat_map_t::range_flags_t {chain->compile_flags (mapper), + mapper->range_first, + mapper->range_last}); chain = &StructAfter> (*chain); } } - void apply (hb_aat_apply_context_t *c) const + void apply (hb_aat_apply_context_t *c, + const hb_aat_map_t &map) const { if (unlikely (!c->buffer->successful)) return; + + c->buffer->unsafe_to_concat (); + c->set_lookup_index (0); const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { - chain->apply (c, c->plan->aat_map.chain_flags[i]); + c->range_flags = &map.chain_flags[i]; + chain->apply (c); if (unlikely (!c->buffer->successful)) return; chain = &StructAfter> (*chain); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -42,7 +42,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } FWORD leftSide; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -62,7 +62,7 @@ } protected: - HBFixed track; /* Track value for this record. */ + F16DOT16 track; /* Track value for this record. */ NameID trackNameID; /* The 'name' table index for this track. * (a short word or phrase like "loose" * or "very tight") */ @@ -82,7 +82,7 @@ const void *base) const { unsigned int sizes = nSizes; - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); + hb_array_t size_table ((base+sizeTable).arrayZ, sizes); float s0 = size_table[idx].to_float (); float s1 = size_table[idx + 1].to_float (); @@ -120,7 +120,7 @@ if (!sizes) return 0.; if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); + hb_array_t size_table ((base+sizeTable).arrayZ, sizes); unsigned int size_index; for (size_index = 0; size_index < sizes - 1; size_index++) if (size_table[size_index].to_float () >= ptem) @@ -141,7 +141,7 @@ protected: HBUINT16 nTracks; /* Number of separate tracks included in this table. */ HBUINT16 nSizes; /* Number of point sizes included in this table. */ - NNOffset32To> + NNOffset32To> sizeTable; /* Offset from start of the tracking table to * Array[nSizes] of size values.. */ UnsizedArrayOf diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc 2023-07-05 07:11:54.000000000 +0000 @@ -36,27 +36,29 @@ #include "hb-aat-layout-feat-table.hh" -void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value) +void hb_aat_map_builder_t::add_feature (const hb_feature_t &feature) { if (!face->table.feat->has_data ()) return; - if (tag == HB_TAG ('a','a','l','t')) + if (feature.tag == HB_TAG ('a','a','l','t')) { if (!face->table.feat->exposes_feature (HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES)) return; - feature_info_t *info = features.push(); - info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; - info->setting = (hb_aat_layout_feature_selector_t) value; - info->seq = features.length; - info->is_exclusive = true; + feature_range_t *range = features.push(); + range->start = feature.start; + range->end = feature.end; + range->info.type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; + range->info.setting = (hb_aat_layout_feature_selector_t) feature.value; + range->info.seq = features.length; + range->info.is_exclusive = true; return; } - const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (tag); + const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (feature.tag); if (!mapping) return; - const AAT::FeatureName* feature = &face->table.feat->get_feature (mapping->aatFeatureType); - if (!feature->has_data ()) + const AAT::FeatureName* feature_name = &face->table.feat->get_feature (mapping->aatFeatureType); + if (!feature_name->has_data ()) { /* Special case: Chain::compile_flags will fall back to the deprecated version of * small-caps if necessary, so we need to check for that possibility. @@ -64,38 +66,106 @@ if (mapping->aatFeatureType == HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE && mapping->selectorToEnable == HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS) { - feature = &face->table.feat->get_feature (HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE); - if (!feature->has_data ()) return; + feature_name = &face->table.feat->get_feature (HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE); + if (!feature_name->has_data ()) return; } else return; } - feature_info_t *info = features.push(); - info->type = mapping->aatFeatureType; - info->setting = value ? mapping->selectorToEnable : mapping->selectorToDisable; - info->seq = features.length; - info->is_exclusive = feature->is_exclusive (); + feature_range_t *range = features.push(); + range->start = feature.start; + range->end = feature.end; + range->info.type = mapping->aatFeatureType; + range->info.setting = feature.value ? mapping->selectorToEnable : mapping->selectorToDisable; + range->info.seq = features.length; + range->info.is_exclusive = feature_name->is_exclusive (); } void hb_aat_map_builder_t::compile (hb_aat_map_t &m) { - /* Sort features and merge duplicates */ - if (features.length) + /* Compute active features per range, and compile each. */ + + /* Sort features by start/end events. */ + hb_vector_t feature_events; + for (unsigned int i = 0; i < features.length; i++) + { + auto &feature = features[i]; + + if (features[i].start == features[i].end) + continue; + + feature_event_t *event; + + event = feature_events.push (); + event->index = features[i].start; + event->start = true; + event->feature = feature.info; + + event = feature_events.push (); + event->index = features[i].end; + event->start = false; + event->feature = feature.info; + } + feature_events.qsort (); + /* Add a strategic final event. */ + { + feature_info_t feature; + feature.seq = features.length + 1; + + feature_event_t *event = feature_events.push (); + event->index = -1; /* This value does magic. */ + event->start = false; + event->feature = feature; + } + + /* Scan events and save features for each range. */ + hb_sorted_vector_t active_features; + unsigned int last_index = 0; + for (unsigned int i = 0; i < feature_events.length; i++) { - features.qsort (); - unsigned int j = 0; - for (unsigned int i = 1; i < features.length; i++) - if (features[i].type != features[j].type || - /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off - * respectively, so we mask out the low-order bit when checking for "duplicates" - * (selectors referring to the same feature setting) here. */ - (!features[i].is_exclusive && ((features[i].setting & ~1) != (features[j].setting & ~1)))) - features[++j] = features[i]; - features.shrink (j + 1); + feature_event_t *event = &feature_events[i]; + + if (event->index != last_index) + { + /* Save a snapshot of active features and the range. */ + + /* Sort features and merge duplicates */ + current_features = active_features; + range_first = last_index; + range_last = event->index - 1; + if (current_features.length) + { + current_features.qsort (); + unsigned int j = 0; + for (unsigned int i = 1; i < current_features.length; i++) + if (current_features[i].type != current_features[j].type || + /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off + * respectively, so we mask out the low-order bit when checking for "duplicates" + * (selectors referring to the same feature setting) here. */ + (!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1)))) + current_features[++j] = current_features[i]; + current_features.shrink (j + 1); + } + + hb_aat_layout_compile_map (this, &m); + + last_index = event->index; + } + + if (event->start) + { + active_features.push (event->feature); + } else { + feature_info_t *feature = active_features.lsearch (event->feature); + if (feature) + active_features.remove_ordered (feature - active_features.arrayZ); + } } - hb_aat_layout_compile_map (this, &m); + for (auto &chain_flags : m.chain_flags) + // With our above setup this value is one less than desired; adjust it. + chain_flags.tail().cluster_last = HB_FEATURE_GLOBAL_END; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-map.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-map.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-aat-map.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-aat-map.hh 2023-07-05 07:11:54.000000000 +0000 @@ -35,16 +35,15 @@ friend struct hb_aat_map_builder_t; public: - - void init () + struct range_flags_t { - memset (this, 0, sizeof (*this)); - chain_flags.init (); - } - void fini () { chain_flags.fini (); } + hb_mask_t flags; + unsigned cluster_first; + unsigned cluster_last; // end - 1 + }; public: - hb_vector_t chain_flags; + hb_vector_t> chain_flags; }; struct hb_aat_map_builder_t @@ -52,10 +51,11 @@ public: HB_INTERNAL hb_aat_map_builder_t (hb_face_t *face_, - const hb_segment_properties_t *props_ HB_UNUSED) : - face (face_) {} + const hb_segment_properties_t props_) : + face (face_), + props (props_) {} - HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1); + HB_INTERNAL void add_feature (const hb_feature_t &feature); HB_INTERNAL void compile (hb_aat_map_t &m); @@ -77,7 +77,7 @@ return (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); } - /* compares type & setting only, not is_exclusive flag or seq number */ + /* compares type & setting only */ int cmp (const feature_info_t& f) const { return (f.type != type) ? (f.type < type ? -1 : 1) : @@ -85,11 +85,38 @@ } }; + struct feature_range_t + { + feature_info_t info; + unsigned start; + unsigned end; + }; + + private: + struct feature_event_t + { + unsigned int index; + bool start; + feature_info_t feature; + + HB_INTERNAL static int cmp (const void *pa, const void *pb) { + const feature_event_t *a = (const feature_event_t *) pa; + const feature_event_t *b = (const feature_event_t *) pb; + return a->index < b->index ? -1 : a->index > b->index ? 1 : + a->start < b->start ? -1 : a->start > b->start ? 1 : + feature_info_t::cmp (&a->feature, &b->feature); + } + }; + public: hb_face_t *face; + hb_segment_properties_t props; public: - hb_sorted_vector_t features; + hb_sorted_vector_t features; + hb_sorted_vector_t current_features; + unsigned range_first = HB_FEATURE_GLOBAL_START; + unsigned range_last = HB_FEATURE_GLOBAL_END; }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-algs.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-algs.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-algs.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-algs.hh 2023-07-05 07:11:54.000000000 +0000 @@ -109,15 +109,16 @@ struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; constexpr operator Type () const { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) /* Spoon-feed the compiler a big-endian integer with alignment 1. * https://github.com/harfbuzz/harfbuzz/pull/1398 */ #if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) this)->v); + return __builtin_bswap16 (((packed_uint16_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) this)->v; + return ((packed_uint16_t *) v)->v; #endif #else return (v[0] << 8) @@ -153,15 +154,16 @@ struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; constexpr operator Type () const { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) /* Spoon-feed the compiler a big-endian integer with alignment 1. * https://github.com/harfbuzz/harfbuzz/pull/1398 */ #if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap32 (((packed_uint32_t *) this)->v); + return __builtin_bswap32 (((packed_uint32_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint32_t *) this)->v; + return ((packed_uint32_t *) v)->v; #endif #else return (v[0] << 24) @@ -234,17 +236,6 @@ template constexpr auto impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) - template constexpr uint32_t - impl (const hb::shared_ptr& v, hb_priority<1>) const - { - return v.get () ? v.get ()->hash () : 0; - } - template constexpr uint32_t - impl (const hb::unique_ptr& v, hb_priority<1>) const - { - return v.get () ? v.get ()->hash () : 0; - } - template constexpr auto impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash>{} (hb_deref (v))) @@ -493,6 +484,17 @@ } HB_FUNCOBJ (hb_equal); +struct +{ + template void + operator () (T& a, T& b) const + { + using std::swap; // allow ADL + swap (a, b); + } +} +HB_FUNCOBJ (hb_swap); + template struct hb_pair_t @@ -505,7 +507,7 @@ hb_enable_if (std::is_default_constructible::value && std::is_default_constructible::value)> hb_pair_t () : first (), second () {} - hb_pair_t (T1 a, T2 b) : first (a), second (b) {} + hb_pair_t (T1 a, T2 b) : first (std::forward (a)), second (std::forward (b)) {} template (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); } bool operator <= (const pair_t& o) const { return !(*this > o); } + static int cmp (const void *pa, const void *pb) + { + pair_t *a = (pair_t *) pa; + pair_t *b = (pair_t *) pb; + + if (a->first < b->first) return -1; + if (a->first > b->first) return +1; + if (a->second < b->second) return -1; + if (a->second > b->second) return +1; + return 0; + } + + friend void swap (hb_pair_t& a, hb_pair_t& b) + { + hb_swap (a.first, b.first); + hb_swap (a.second, b.second); + } + + T1 first; T2 second; }; -#define hb_pair_t(T1,T2) hb_pair_t template static inline hb_pair_t hb_pair (T1&& a, T2&& b) { return hb_pair_t (a, b); } @@ -551,14 +571,14 @@ { template constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a <= b ? std::forward (a) : std::forward (b)) + (a <= b ? a : b) } HB_FUNCOBJ (hb_min); struct { template constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a >= b ? std::forward (a) : std::forward (b)) + (a >= b ? a : b) } HB_FUNCOBJ (hb_max); struct @@ -569,17 +589,6 @@ } HB_FUNCOBJ (hb_clamp); -struct -{ - template void - operator () (T& a, T& b) const - { - using std::swap; // allow ADL - swap (a, b); - } -} -HB_FUNCOBJ (hb_swap); - /* * Bithacks. */ @@ -848,19 +857,14 @@ return (T)(u - lo) <= (T)(hi - lo); } template static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) -{ - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); -} -template static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) +hb_in_ranges (T u, T lo1, T hi1) { - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); + return hb_in_range (u, lo1, hi1); } -template static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3, T lo4, T hi4) +template static inline bool +hb_in_ranges (T u, T lo1, T hi1, Ts... ds) { - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3) || hb_in_range (u, lo4, hi4); + return hb_in_range (u, lo1, hi1) || hb_in_ranges (u, ds...); } @@ -868,10 +872,19 @@ * Overflow checking. */ -/* Consider __builtin_mul_overflow use here also */ static inline bool -hb_unsigned_mul_overflows (unsigned int count, unsigned int size) +hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr) { +/* avoid with xlc16 clang on AIX; it sets the gcc macros */ +#if (defined(__GNUC__) && !defined(AIX) && (__GNUC__ >= 4)) || (defined(__clang__) && (__clang_major__ >= 8)) + unsigned stack_result; + if (!result) + result = &stack_result; + return __builtin_mul_overflow (count, size, result); +#endif + + if (result) + *result = count * size; return (size > 0) && (count >= ((unsigned int) -1) / size); } @@ -972,7 +985,7 @@ [void *arg]); */ -#define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp)) +#define SORT_R_SWAP(a,b,tmp) ((void) ((tmp) = (a)), (void) ((a) = (b)), (b) = (tmp)) /* swap a and b */ /* a and b must not be equal! */ @@ -1163,9 +1176,12 @@ } -template static inline void -hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2) +template static inline void +hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2 = nullptr) { + static_assert (hb_is_trivially_copy_assignable (T), ""); + static_assert (hb_is_trivially_copy_assignable (T3), ""); + for (unsigned int i = 1; i < len; i++) { unsigned int j = i; @@ -1188,12 +1204,6 @@ } } -template static inline void -hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) -{ - hb_stable_sort (array, len, compar, (int *) nullptr); -} - static inline hb_bool_t hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out) { @@ -1321,47 +1331,4 @@ HB_FUNCOBJ (hb_dec); -/* Compiler-assisted vectorization. */ - -/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))), - * basically a fixed-size bitset. */ -template -struct hb_vector_size_t -{ - elt_t& operator [] (unsigned int i) { return v[i]; } - const elt_t& operator [] (unsigned int i) const { return v[i]; } - - void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); } - - template - hb_vector_size_t process (const Op& op) const - { - hb_vector_size_t r; - for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) - r.v[i] = op (v[i]); - return r; - } - template - hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const - { - hb_vector_size_t r; - for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) - r.v[i] = op (v[i], o.v[i]); - return r; - } - hb_vector_size_t operator | (const hb_vector_size_t &o) const - { return process (hb_bitwise_or, o); } - hb_vector_size_t operator & (const hb_vector_size_t &o) const - { return process (hb_bitwise_and, o); } - hb_vector_size_t operator ^ (const hb_vector_size_t &o) const - { return process (hb_bitwise_xor, o); } - hb_vector_size_t operator ~ () const - { return process (hb_bitwise_neg); } - - private: - static_assert (0 == byte_size % sizeof (elt_t), ""); - elt_t v[byte_size / sizeof (elt_t)]; -}; - - #endif /* HB_ALGS_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-array.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-array.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-array.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-array.hh 2023-07-05 07:11:54.000000000 +0000 @@ -100,10 +100,17 @@ /* Ouch. The operator== compares the contents of the array. For range-based for loops, * it's best if we can just compare arrayZ, though comparing contents is still fast, * but also would require that Type has operator==. As such, we optimize this operator - * for range-based for loop and just compare arrayZ. No need to compare length, as we - * assume we're only compared to .end(). */ + * for range-based for loop and just compare arrayZ and length. + * + * The above comment is outdated now because we implemented separate begin/end to + * objects that were using hb_array_t for range-based loop before. */ bool operator != (const hb_array_t& o) const - { return arrayZ != o.arrayZ; } + { return this->arrayZ != o.arrayZ || this->length != o.length; } + + /* Faster range-based for loop without bounds-check. */ + Type *begin () const { return arrayZ; } + Type *end () const { return arrayZ + length; } + /* Extra operators. */ @@ -113,11 +120,11 @@ HB_INTERNAL bool operator == (const hb_array_t &o) const; - uint32_t hash () const { + uint32_t hash () const + { uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) { - current = current * 31 + hb_hash (this->arrayZ[i]); - } + for (auto &v : *this) + current = current * 31 + hb_hash (v); return current; } @@ -185,23 +192,18 @@ hb_sorted_array_t qsort (int (*cmp_)(const void*, const void*)) { + //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), ""); if (likely (length)) hb_qsort (arrayZ, length, this->get_item_size (), cmp_); return hb_sorted_array_t (*this); } hb_sorted_array_t qsort () { + //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), ""); if (likely (length)) hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp); return hb_sorted_array_t (*this); } - void qsort (unsigned int start, unsigned int end) - { - end = hb_min (end, length); - assert (start <= end); - if (likely (start < end)) - hb_qsort (arrayZ + start, end - start, this->get_item_size (), Type::cmp); - } /* * Other methods. @@ -220,11 +222,8 @@ if (end < start + 2) return; - for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) { - Type temp = arrayZ[rhs]; - arrayZ[rhs] = arrayZ[lhs]; - arrayZ[lhs] = temp; - } + for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) + hb_swap (arrayZ[rhs], arrayZ[lhs]); } hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const @@ -266,17 +265,31 @@ void fini () { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; } - template + template )))> hb_array_t copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto* out = c->start_embed (arrayZ); - if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ()); + if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ()); for (unsigned i = 0; i < length; i++) out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ return_trace (hb_array_t (out, length)); } + template ))> + hb_array_t copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + auto* out = c->start_embed (arrayZ); + if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ()); + hb_memcpy (out, arrayZ, get_size ()); + return_trace (hb_array_t (out, length)); + } + template bool sanitize (hb_sanitize_context_t *c) const { return c->check_array (arrayZ, length); } @@ -291,6 +304,9 @@ unsigned int backwards_length = 0; }; template inline hb_array_t +hb_array () +{ return hb_array_t (); } +template inline hb_array_t hb_array (T *array, unsigned int length) { return hb_array_t (array, length); } template inline hb_array_t @@ -299,8 +315,8 @@ template struct hb_sorted_array_t : - hb_iter_t, Type&>, - hb_array_t + hb_array_t, + hb_iter_t, Type&> { typedef hb_iter_t iter_base_t; HB_ITER_USING (iter_base_t); @@ -320,17 +336,24 @@ template constexpr hb_sorted_array_t (const hb_array_t &o) : - hb_iter_t (), - hb_array_t (o) {} + hb_array_t (o), + hb_iter_t () {} template hb_sorted_array_t& operator = (const hb_array_t &o) { hb_array_t (*this) = o; return *this; } /* Iterator implementation. */ + + /* See comment in hb_array_of::operator != */ bool operator != (const hb_sorted_array_t& o) const { return this->arrayZ != o.arrayZ || this->length != o.length; } + /* Faster range-based for loop without bounds-check. */ + Type *begin () const { return this->arrayZ; } + Type *end () const { return this->arrayZ + this->length; } + + hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const { return hb_sorted_array_t (((const hb_array_t *) (this))->sub_array (start_offset, seg_count)); } hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const @@ -344,7 +367,7 @@ unsigned int i; return bfind (x, &i) ? &this->arrayZ[i] : not_found; } - template + template const Type *bsearch (const T &x, const Type *not_found = nullptr) const { unsigned int i; @@ -391,7 +414,7 @@ this->length, sizeof (Type), _hb_cmp_method, - ds...); + std::forward (ds)...); } }; template inline hb_sorted_array_t @@ -423,18 +446,42 @@ return 0 == hb_memcmp (arrayZ, o.arrayZ, length); } + +/* Specialize hash() for byte arrays. */ + template <> -inline uint32_t hb_array_t::hash () const { +inline uint32_t hb_array_t::hash () const +{ uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) - current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u); + 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; } + template <> -inline uint32_t hb_array_t::hash () const { +inline uint32_t hb_array_t::hash () const +{ uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) - current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u); + 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; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh 2023-07-05 07:11:54.000000000 +0000 @@ -84,11 +84,11 @@ #define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) #define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) -#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) -#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast *> (AI)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast *> (AI)->store ((V), std::memory_order_release)) -#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast const *> (AI)->load (std::memory_order_relaxed)) -#define hb_atomic_int_impl_get(AI) (reinterpret_cast const *> (AI)->load (std::memory_order_acquire)) +#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) +#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) +#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) +#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) +#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) #define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast *> (P)->store ((V), std::memory_order_relaxed)) #define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast const *> (P)->load (std::memory_order_relaxed)) @@ -111,6 +111,24 @@ #endif +/* This should never be disabled, even under HB_NO_MT. + * except that MSVC gives me an internal compiler error, so disabled there. + * + * https://github.com/harfbuzz/harfbuzz/pull/4119 + */ +#ifndef _hb_compiler_memory_r_barrier +#if defined(__ATOMIC_ACQUIRE) // gcc-like +#define _hb_compiler_memory_r_barrier() asm volatile("": : :"memory") +#elif !defined(_MSC_VER) +#include +#define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire) +#else +#define _hb_compiler_memory_r_barrier() do {} while (0) +#endif +#endif + + + #ifndef _hb_memory_r_barrier #define _hb_memory_r_barrier() _hb_memory_barrier () #endif @@ -132,24 +150,47 @@ #endif #ifndef hb_atomic_int_impl_set inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; } +inline void hb_atomic_int_impl_set (short *AI, short v) { _hb_memory_w_barrier (); *AI = v; } #endif #ifndef hb_atomic_int_impl_get inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; } +inline short hb_atomic_int_impl_get (const short *AI) { short v = *AI; _hb_memory_r_barrier (); return v; } #endif #ifndef hb_atomic_ptr_impl_get inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif +struct hb_atomic_short_t +{ + hb_atomic_short_t () = default; + constexpr hb_atomic_short_t (short v) : v (v) {} + + hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; } + operator short () const { return get_relaxed (); } + + void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } + void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); } + short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } + short get_acquire () const { return hb_atomic_int_impl_get (&v); } + short inc () { return hb_atomic_int_impl_add (&v, 1); } + short dec () { return hb_atomic_int_impl_add (&v, -1); } + + short v = 0; +}; + struct hb_atomic_int_t { hb_atomic_int_t () = default; constexpr hb_atomic_int_t (int v) : v (v) {} + hb_atomic_int_t& operator = (int v_) { set_relaxed (v_); return *this; } + operator int () const { return get_relaxed (); } + void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } - void set (int v_) { hb_atomic_int_impl_set (&v, v_); } + void set_release (int v_) { hb_atomic_int_impl_set (&v, v_); } int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } - int get () const { return hb_atomic_int_impl_get (&v); } + int get_acquire () const { return hb_atomic_int_impl_get (&v); } int inc () { return hb_atomic_int_impl_add (&v, 1); } int dec () { return hb_atomic_int_impl_add (&v, -1); } @@ -167,11 +208,11 @@ void init (T* v_ = nullptr) { set_relaxed (v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } - T *get () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } + T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } - T * operator -> () const { return get (); } - template operator C * () const { return get (); } + T * operator -> () const { return get_acquire (); } + template operator C * () const { return get_acquire (); } T *v = nullptr; }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh 2023-07-05 07:11:54.000000000 +0000 @@ -30,32 +30,89 @@ #include "hb.hh" + +/* Compiler-assisted vectorization. */ + +/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))), + * basically a fixed-size bitset. We can't use the compiler type because hb_vector_t cannot + * guarantee alignment requirements. */ +template +struct hb_vector_size_t +{ + elt_t& operator [] (unsigned int i) { return v[i]; } + const elt_t& operator [] (unsigned int i) const { return v[i]; } + + void init0 () + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + v[i] = 0; + } + void init1 () + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + v[i] = (elt_t) -1; + } + + template + hb_vector_size_t process (const Op& op) const + { + hb_vector_size_t r; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r.v[i] = op (v[i]); + return r; + } + template + hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const + { + hb_vector_size_t r; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r.v[i] = op (v[i], o.v[i]); + return r; + } + hb_vector_size_t operator | (const hb_vector_size_t &o) const + { return process (hb_bitwise_or, o); } + hb_vector_size_t operator & (const hb_vector_size_t &o) const + { return process (hb_bitwise_and, o); } + hb_vector_size_t operator ^ (const hb_vector_size_t &o) const + { return process (hb_bitwise_xor, o); } + hb_vector_size_t operator ~ () const + { return process (hb_bitwise_neg); } + + hb_array_t iter () const + { return hb_array (v); } + + private: + static_assert (0 == byte_size % sizeof (elt_t), ""); + elt_t v[byte_size / sizeof (elt_t)]; +}; + + struct hb_bit_page_t { - void init0 () { v.clear (); } - void init1 () { v.clear (0xFF); } + void init0 () { v.init0 (); } + void init1 () { v.init1 (); } - constexpr unsigned len () const + static inline constexpr unsigned len () { return ARRAY_LENGTH_CONST (v); } bool is_empty () const { - for (unsigned i = 0; i < len (); i++) - if (v[i]) - return false; - return true; + return + + hb_iter (v) + | hb_none + ; } uint32_t hash () const { - uint32_t h = 0; - for (unsigned i = 0; i < len (); i++) - h = h * 31 + hb_hash (v[i]); - return h; + return + + hb_iter (v) + | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u) + ; } void add (hb_codepoint_t g) { elt (g) |= mask (g); } void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } - void set (hb_codepoint_t g, bool v) { if (v) add (g); else del (g); } + 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); } void add_range (hb_codepoint_t a, hb_codepoint_t b) @@ -69,7 +126,7 @@ *la |= ~(mask (a) - 1); la++; - memset (la, 0xff, (char *) lb - (char *) la); + hb_memset (la, 0xff, (char *) lb - (char *) la); *lb |= ((mask (b) << 1) - 1); } @@ -85,7 +142,7 @@ *la &= mask (a) - 1; la++; - memset (la, 0, (char *) lb - (char *) la); + hb_memset (la, 0, (char *) lb - (char *) la); *lb &= ~((mask (b) << 1) - 1); } @@ -101,13 +158,13 @@ hb_codepoint_t *p, unsigned int size) const { - unsigned int start_v = start_value >> ELT_BITS_LOG_2; + unsigned int start_v = start_value / ELT_BITS; unsigned int start_bit = start_value & ELT_MASK; unsigned int count = 0; for (unsigned i = start_v; i < len () && count < size; i++) { elt_t bits = v[i]; - uint32_t v_base = base | (i << ELT_BITS_LOG_2); + uint32_t v_base = base | (i * ELT_BITS); for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++) { if ((elt_t(1) << j) & bits) { @@ -132,13 +189,13 @@ unsigned int size, hb_codepoint_t *next_value) const { - unsigned int start_v = start_value >> ELT_BITS_LOG_2; + unsigned int start_v = start_value / ELT_BITS; unsigned int start_bit = start_value & ELT_MASK; unsigned int count = 0; for (unsigned i = start_v; i < len () && count < size; i++) { elt_t bits = v[i]; - uint32_t v_offset = i << ELT_BITS_LOG_2; + uint32_t v_offset = i * ELT_BITS; for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++) { if ((elt_t(1) << j) & bits) @@ -161,7 +218,10 @@ bool is_equal (const hb_bit_page_t &other) const { - return 0 == hb_memcmp (&v, &other.v, sizeof (v)); + for (unsigned i = 0; i < len (); i++) + if (v[i] != other.v[i]) + return false; + return true; } bool is_subset (const hb_bit_page_t &larger_page) const { @@ -173,10 +233,10 @@ unsigned int get_population () const { - unsigned int pop = 0; - for (unsigned int i = 0; i < len (); i++) - pop += hb_popcount (v[i]); - return pop; + return + + hb_iter (v) + | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u) + ; } bool next (hb_codepoint_t *codepoint) const @@ -250,10 +310,10 @@ static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; typedef unsigned long long elt_t; - static constexpr unsigned PAGE_BITS = 512; - static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, ""); - static constexpr unsigned PAGE_BITS_LOG_2 = 9; + static constexpr unsigned PAGE_BITS_LOG_2 = 9; // 512 bits + static constexpr unsigned PAGE_BITS = 1 << PAGE_BITS_LOG_2; static_assert (1 << PAGE_BITS_LOG_2 == PAGE_BITS, ""); + static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, ""); static constexpr unsigned PAGE_BITMASK = PAGE_BITS - 1; static unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); } @@ -262,8 +322,6 @@ typedef hb_vector_size_t vector_t; static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8; - static constexpr unsigned ELT_BITS_LOG_2 = 6; - static_assert (1 << ELT_BITS_LOG_2 == ELT_BITS, ""); static constexpr unsigned ELT_MASK = ELT_BITS - 1; static constexpr unsigned BITS = sizeof (vector_t) * 8; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh 2023-07-05 07:11:54.000000000 +0000 @@ -38,7 +38,7 @@ hb_bit_set_t () = default; ~hb_bit_set_t () = default; - hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other); } + hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other, true); } hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); } hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; } hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; } @@ -56,7 +56,7 @@ { successful = true; population = 0; - last_page_lookup.set_relaxed (0); + last_page_lookup = 0; page_map.init (); pages.init (); } @@ -85,12 +85,16 @@ void err () { if (successful) successful = false; } /* TODO Remove */ bool in_error () const { return !successful; } - bool resize (unsigned int count) + bool resize (unsigned int count, bool clear = true, bool exact_size = false) { if (unlikely (!successful)) return false; - if (unlikely (!pages.resize (count) || !page_map.resize (count))) + + if (pages.length == 0 && count == 1) + exact_size = true; // Most sets are small and local + + if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size))) { - pages.resize (page_map.length); + pages.resize (page_map.length, clear, exact_size); successful = false; return false; } @@ -330,10 +334,8 @@ } /* Has interface. */ - static constexpr bool SENTINEL = false; - typedef bool value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + bool operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k]; } /* Predicate. */ bool operator () (hb_codepoint_t k) const { return has (k); } @@ -348,11 +350,11 @@ hb_codepoint_t c = first - 1; return next (&c) && c <= last; } - void set (const hb_bit_set_t &other) + void set (const hb_bit_set_t &other, bool exact_size = false) { if (unlikely (!successful)) return; unsigned int count = other.pages.length; - if (unlikely (!resize (count))) + if (unlikely (!resize (count, false, exact_size))) return; population = other.population; @@ -391,7 +393,7 @@ bool is_subset (const hb_bit_set_t &larger_set) const { if (has_population () && larger_set.has_population () && - population != larger_set.population) + population > larger_set.population) return false; uint32_t spi = 0; @@ -424,7 +426,7 @@ private: bool allocate_compact_workspace (hb_vector_t& workspace) { - if (unlikely (!workspace.resize (pages.length))) + if (unlikely (!workspace.resize_exact (pages.length))) { successful = false; return false; @@ -465,12 +467,10 @@ } public: - template - void process (const Op& op, const hb_bit_set_t &other) + void process_ (hb_bit_page_t::vector_t (*op) (const hb_bit_page_t::vector_t &, const hb_bit_page_t::vector_t &), + bool passthru_left, bool passthru_right, + const hb_bit_set_t &other) { - const bool passthru_left = op (1, 0); - const bool passthru_right = op (0, 1); - if (unlikely (!successful)) return; dirty (); @@ -542,21 +542,21 @@ b = nb; for (; a && b; ) { - if (page_map[a - 1].major == other.page_map[b - 1].major) + if (page_map.arrayZ[a - 1].major == other.page_map.arrayZ[b - 1].major) { a--; b--; count--; - page_map[count] = page_map[a]; + page_map.arrayZ[count] = page_map.arrayZ[a]; page_at (count).v = op (page_at (a).v, other.page_at (b).v); } - else if (page_map[a - 1].major > other.page_map[b - 1].major) + else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major) { a--; if (passthru_left) { count--; - page_map[count] = page_map[a]; + page_map.arrayZ[count] = page_map.arrayZ[a]; } } else @@ -565,8 +565,8 @@ if (passthru_right) { count--; - page_map[count].major = other.page_map[b].major; - page_map[count].index = next_page++; + 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; } } @@ -576,20 +576,29 @@ { a--; count--; - page_map[count] = page_map [a]; + page_map.arrayZ[count] = page_map.arrayZ[a]; } if (passthru_right) while (b) { b--; count--; - page_map[count].major = other.page_map[b].major; - page_map[count].index = next_page++; + 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; } assert (!count); resize (newCount); } + template + static hb_bit_page_t::vector_t + op_ (const hb_bit_page_t::vector_t &a, const hb_bit_page_t::vector_t &b) + { return Op{} (a, b); } + template + void process (const Op& op, const hb_bit_set_t &other) + { + process_ (op_, op (1, 0), op (0, 1), other); + } void union_ (const hb_bit_set_t &other) { process (hb_bitwise_or, other); } void intersect (const hb_bit_set_t &other) { process (hb_bitwise_and, other); } @@ -598,8 +607,6 @@ bool next (hb_codepoint_t *codepoint) const { - // TODO: this should be merged with prev() as both implementations - // are very similar. if (unlikely (*codepoint == INVALID)) { *codepoint = get_min (); return *codepoint != INVALID; @@ -607,7 +614,7 @@ const auto* page_map_array = page_map.arrayZ; unsigned int major = get_major (*codepoint); - unsigned int i = last_page_lookup.get_relaxed (); + unsigned int i = last_page_lookup; if (unlikely (i >= page_map.length || page_map_array[i].major != major)) { @@ -625,7 +632,7 @@ if (pages_array[current.index].next (codepoint)) { *codepoint += current.major * page_t::PAGE_BITS; - last_page_lookup.set_relaxed (i); + last_page_lookup = i; return true; } i++; @@ -633,16 +640,16 @@ for (; i < page_map.length; i++) { - const page_map_t ¤t = page_map.arrayZ[i]; + const page_map_t ¤t = page_map_array[i]; hb_codepoint_t m = pages_array[current.index].get_min (); if (m != INVALID) { *codepoint = current.major * page_t::PAGE_BITS + m; - last_page_lookup.set_relaxed (i); + last_page_lookup = i; return true; } } - last_page_lookup.set_relaxed (0); + last_page_lookup = 0; *codepoint = INVALID; return false; } @@ -656,21 +663,21 @@ page_map_t map = {get_major (*codepoint), 0}; unsigned int i; page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST); - if (i < page_map.length && page_map[i].major == map.major) + if (i < page_map.length && page_map.arrayZ[i].major == map.major) { - if (pages[page_map[i].index].previous (codepoint)) + if (pages[page_map.arrayZ[i].index].previous (codepoint)) { - *codepoint += page_map[i].major * page_t::PAGE_BITS; + *codepoint += page_map.arrayZ[i].major * page_t::PAGE_BITS; return true; } } i--; for (; (int) i >= 0; i--) { - hb_codepoint_t m = pages[page_map[i].index].get_max (); + hb_codepoint_t m = pages.arrayZ[page_map.arrayZ[i].index].get_max (); if (m != INVALID) { - *codepoint = page_map[i].major * page_t::PAGE_BITS + m; + *codepoint = page_map.arrayZ[i].major * page_t::PAGE_BITS + m; return true; } } @@ -725,7 +732,7 @@ { const auto* page_map_array = page_map.arrayZ; unsigned int major = get_major (codepoint); - unsigned int i = last_page_lookup.get_relaxed (); + unsigned int i = last_page_lookup; if (unlikely (i >= page_map.length || page_map_array[i].major != major)) { page_map.bfind (major, &i, HB_NOT_FOUND_STORE_CLOSEST); @@ -766,7 +773,7 @@ { const auto* page_map_array = page_map.arrayZ; unsigned int major = get_major (codepoint); - unsigned int i = last_page_lookup.get_relaxed (); + unsigned int i = last_page_lookup; if (unlikely (i >= page_map.length || page_map_array[i].major != major)) { page_map.bfind(major, &i, HB_NOT_FOUND_STORE_CLOSEST); @@ -893,12 +900,12 @@ /* 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... */ - unsigned i = last_page_lookup.get_relaxed (); + unsigned i = last_page_lookup; if (likely (i < page_map.length)) { auto &cached_page = page_map.arrayZ[i]; if (cached_page.major == major) - return &pages[cached_page.index]; + return &pages.arrayZ[cached_page.index]; } page_map_t map = {major, pages.length}; @@ -910,15 +917,15 @@ if (unlikely (!resize (pages.length + 1))) return nullptr; - pages[map.index].init0 (); - memmove (page_map + i + 1, - page_map + i, + pages.arrayZ[map.index].init0 (); + memmove (page_map.arrayZ + i + 1, + page_map.arrayZ + i, (page_map.length - 1 - i) * page_map.item_size); page_map[i] = map; } - last_page_lookup.set_relaxed (i); - return &pages[page_map[i].index]; + last_page_lookup = i; + return &pages.arrayZ[page_map.arrayZ[i].index]; } const page_t *page_for (hb_codepoint_t g) const { @@ -927,23 +934,31 @@ /* 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... */ - unsigned i = last_page_lookup.get_relaxed (); + unsigned i = last_page_lookup; if (likely (i < page_map.length)) { auto &cached_page = page_map.arrayZ[i]; if (cached_page.major == major) - return &pages[cached_page.index]; + return &pages.arrayZ[cached_page.index]; } page_map_t key = {major}; if (!page_map.bfind (key, &i)) return nullptr; - last_page_lookup.set_relaxed (i); - return &pages[page_map[i].index]; + last_page_lookup = i; + return &pages.arrayZ[page_map[i].index]; + } + page_t &page_at (unsigned int i) + { + assert (i < page_map.length); + return pages.arrayZ[page_map.arrayZ[i].index]; + } + const page_t &page_at (unsigned int i) const + { + assert (i < page_map.length); + return pages.arrayZ[page_map.arrayZ[i].index]; } - page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } - const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; } unsigned int get_major (hb_codepoint_t g) const { return g >> page_t::PAGE_BITS_LOG_2; } unsigned int page_remainder (hb_codepoint_t g) const { return g & page_t::PAGE_BITMASK; } hb_codepoint_t major_start (unsigned int major) const { return major << page_t::PAGE_BITS_LOG_2; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh 2023-07-05 07:11:54.000000000 +0000 @@ -74,6 +74,11 @@ inverted = !inverted; } + bool is_inverted () const + { + return inverted; + } + bool is_empty () const { hb_codepoint_t v = INVALID; @@ -123,10 +128,8 @@ bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; } /* Has interface. */ - static constexpr bool SENTINEL = false; - typedef bool value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + bool operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k]; } /* Predicate. */ bool operator () (hb_codepoint_t k) const { return has (k); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-blob.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-blob.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-blob.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-blob.cc 2023-07-05 07:11:54.000000000 +0000 @@ -99,7 +99,7 @@ * is zero. This is in contrast to hb_blob_create(), which returns the singleton * empty blob (as returned by hb_blob_get_empty()) if @length is zero. * - * Return value: New blob, or %NULL if failed. Destroy with hb_blob_destroy(). + * Return value: New blob, or `NULL` if failed. Destroy with hb_blob_destroy(). * * Since: 2.8.2 **/ @@ -263,8 +263,6 @@ { if (!hb_object_destroy (blob)) return; - blob->fini_shallow (); - hb_free (blob); } @@ -278,7 +276,7 @@ * * Attaches a user-data key/data pair to the specified blob. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -305,7 +303,7 @@ * Since: 0.9.2 **/ void * -hb_blob_get_user_data (hb_blob_t *blob, +hb_blob_get_user_data (const hb_blob_t *blob, hb_user_data_key_t *key) { return hb_object_get_user_data (blob, key); @@ -335,7 +333,7 @@ * * Tests whether a blob is immutable. * - * Return value: %true if @blob is immutable, %false otherwise + * Return value: `true` if @blob is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -394,7 +392,7 @@ * fails. * * Returns: (transfer none) (array length=length): Writable blob data, - * or %NULL if failed. + * or `NULL` if failed. * * Since: 0.9.2 **/ @@ -497,7 +495,7 @@ DEBUG_MSG_FUNC (BLOB, this, "dupped successfully -> %p\n", this->data); - memcpy (new_data, this->data, this->length); + hb_memcpy (new_data, this->data, this->length); this->destroy_user_data (); this->mode = HB_MEMORY_MODE_WRITABLE; this->data = new_data; @@ -620,7 +618,7 @@ * specified binary font file. * * Returns: An #hb_blob_t pointer with the content of the file, - * or %NULL if failed. + * or `NULL` if failed. * * Since: 2.8.2 **/ @@ -678,7 +676,7 @@ wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size); if (unlikely (!wchar_file_name)) goto fail_without_close; mbstowcs (wchar_file_name, file_name, size); -#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) { CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 }; ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); @@ -699,7 +697,7 @@ if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close; -#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) { LARGE_INTEGER length; GetFileSizeEx (fd, &length); @@ -712,7 +710,7 @@ #endif if (unlikely (!file->mapping)) goto fail; -#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) file->contents = (char *) MapViewOfFileFromApp (file->mapping, FILE_MAP_READ, 0, 0); #else file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-blob.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-blob.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-blob.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-blob.h 2023-07-05 07:11:54.000000000 +0000 @@ -135,7 +135,7 @@ HB_EXTERN void * -hb_blob_get_user_data (hb_blob_t *blob, +hb_blob_get_user_data (const hb_blob_t *blob, hb_user_data_key_t *key); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-blob.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-blob.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-blob.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-blob.hh 2023-07-05 07:11:54.000000000 +0000 @@ -38,7 +38,7 @@ struct hb_blob_t { - void fini_shallow () { destroy_user_data (); } + ~hb_blob_t () { destroy_user_data (); } void destroy_user_data () { @@ -61,12 +61,12 @@ public: hb_object_header_t header; - const char *data; - unsigned int length; - hb_memory_mode_t mode; + const char *data = nullptr; + unsigned int length = 0; + hb_memory_mode_t mode = (hb_memory_mode_t) 0; - void *user_data; - hb_destroy_func_t destroy; + void *user_data = nullptr; + hb_destroy_func_t destroy = nullptr; }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc 2023-07-05 07:11:54.000000000 +0000 @@ -51,7 +51,7 @@ * Checks the equality of two #hb_segment_properties_t's. * * Return value: - * %true if all properties of @a equal those of @b, %false otherwise. + * `true` if all properties of @a equal those of @b, `false` otherwise. * * Since: 0.9.7 **/ @@ -172,12 +172,13 @@ while (size >= new_allocated) new_allocated += (new_allocated >> 1) + 32; - static_assert ((sizeof (info[0]) == sizeof (pos[0])), ""); - if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0])))) + unsigned new_bytes; + if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes))) goto done; - new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0])); - new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0])); + static_assert (sizeof (info[0]) == sizeof (pos[0]), ""); + new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes); + new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes); done: if (unlikely (!new_pos || !new_info)) @@ -208,7 +209,7 @@ assert (have_output); out_info = (hb_glyph_info_t *) pos; - memcpy (out_info, info, out_len * sizeof (out_info[0])); + hb_memcpy (out_info, info, out_len * sizeof (out_info[0])); } return true; @@ -229,7 +230,7 @@ * Ideally, we should at least set Default_Ignorable bits on * these, as well as consistent cluster values. But the former * is layering violation... */ - memset (info + len, 0, (idx + count - len) * sizeof (info[0])); + hb_memset (info + len, 0, (idx + count - len) * sizeof (info[0])); } len += count; idx += count; @@ -298,8 +299,8 @@ out_len = 0; out_info = info; - memset (context, 0, sizeof context); - memset (context_len, 0, sizeof context_len); + hb_memset (context, 0, sizeof context); + hb_memset (context_len, 0, sizeof context_len); deallocate_var_all (); serial = 0; @@ -313,15 +314,14 @@ serial = 0; shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; - if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR))) + unsigned mul; + if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul))) { - max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR, - (unsigned) HB_BUFFER_MAX_LEN_MIN); + max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN); } - if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR))) + if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR, &mul))) { - max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR, - (unsigned) HB_BUFFER_MAX_OPS_MIN); + max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN); } } void @@ -345,7 +345,7 @@ glyph = &info[len]; - memset (glyph, 0, sizeof (*glyph)); + hb_memset (glyph, 0, sizeof (*glyph)); glyph->codepoint = codepoint; glyph->mask = 0; glyph->cluster = cluster; @@ -387,9 +387,11 @@ hb_memset (pos, 0, sizeof (pos[0]) * len); } -void +bool hb_buffer_t::sync () { + bool ret = false; + assert (have_output); assert (idx <= len); @@ -403,12 +405,39 @@ info = out_info; } len = out_len; + ret = true; reset: have_output = false; out_len = 0; out_info = info; idx = 0; + + return ret; +} + +int +hb_buffer_t::sync_so_far () +{ + bool had_output = have_output; + unsigned out_i = out_len; + unsigned i = idx; + unsigned old_idx = idx; + + if (sync ()) + idx = out_i; + else + idx = i; + + if (had_output) + { + have_output = true; + out_len = idx; + } + + assert (idx <= len); + + return idx - old_idx; } bool @@ -493,15 +522,17 @@ cluster = hb_min (cluster, info[i].cluster); /* Extend end */ - while (end < len && info[end - 1].cluster == info[end].cluster) - end++; + if (cluster != info[end - 1].cluster) + while (end < len && info[end - 1].cluster == info[end].cluster) + end++; /* Extend start */ - while (idx < start && info[start - 1].cluster == info[start].cluster) - start--; + if (cluster != info[start].cluster) + while (idx < start && info[start - 1].cluster == info[start].cluster) + start--; /* If we hit the start of buffer, continue in out-buffer. */ - if (idx == start) + if (idx == start && info[start].cluster != cluster) for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) set_cluster (out_info[i - 1], cluster); @@ -577,6 +608,53 @@ } void +hb_buffer_t::delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info)) +{ + /* Merge clusters and delete filtered glyphs. + * NOTE! We can't use out-buffer as we have positioning data. */ + unsigned int j = 0; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + { + if (filter (&info[i])) + { + /* Merge clusters. + * Same logic as delete_glyph(), but for in-place removal. */ + + unsigned int cluster = info[i].cluster; + if (i + 1 < count && cluster == info[i + 1].cluster) + continue; /* Cluster survives; do nothing. */ + + if (j) + { + /* Merge cluster backward. */ + if (cluster < info[j - 1].cluster) + { + unsigned int mask = info[i].mask; + unsigned int old_cluster = info[j - 1].cluster; + for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) + set_cluster (info[k - 1], cluster, mask); + } + continue; + } + + if (i + 1 < count) + merge_clusters (i, i + 2); /* Merge cluster forward. */ + + continue; + } + + if (j != i) + { + info[j] = info[i]; + pos[j] = pos[i]; + } + j++; + } + len = j; +} + +void hb_buffer_t::guess_segment_properties () { assert_unicode (); @@ -643,9 +721,9 @@ * Return value: (transfer full): * A newly allocated #hb_buffer_t with a reference count of 1. The initial * reference count should be released with hb_buffer_destroy() when you are done - * using the #hb_buffer_t. This function never returns %NULL. If memory cannot + * using the #hb_buffer_t. This function never returns `NULL`. If memory cannot * be allocated, a special #hb_buffer_t object will be returned on which - * hb_buffer_allocation_successful() returns %false. + * hb_buffer_allocation_successful() returns `false`. * * Since: 0.9.2 **/ @@ -775,7 +853,7 @@ * * Attaches a user-data key/data pair to the specified buffer. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -802,7 +880,7 @@ * Since: 0.9.2 **/ void * -hb_buffer_get_user_data (hb_buffer_t *buffer, +hb_buffer_get_user_data (const hb_buffer_t *buffer, hb_user_data_key_t *key) { return hb_object_get_user_data (buffer, key); @@ -817,6 +895,32 @@ * Sets the type of @buffer contents. Buffers are either empty, contain * characters (before shaping), or contain glyphs (the result of shaping). * + * You rarely need to call this function, since a number of other + * functions transition the content type for you. Namely: + * + * - A newly created buffer starts with content type + * %HB_BUFFER_CONTENT_TYPE_INVALID. Calling hb_buffer_reset(), + * hb_buffer_clear_contents(), as well as calling hb_buffer_set_length() + * with an argument of zero all set the buffer content type to invalid + * as well. + * + * - Calling hb_buffer_add_utf8(), hb_buffer_add_utf16(), + * hb_buffer_add_utf32(), hb_buffer_add_codepoints() and + * hb_buffer_add_latin1() expect that buffer is either empty and + * have a content type of invalid, or that buffer content type is + * %HB_BUFFER_CONTENT_TYPE_UNICODE, and they also set the content + * type to Unicode if they added anything to an empty buffer. + * + * - Finally hb_shape() and hb_shape_full() expect that the buffer + * is either empty and have content type of invalid, or that buffer + * content type is %HB_BUFFER_CONTENT_TYPE_UNICODE, and upon + * success they set the buffer content type to + * %HB_BUFFER_CONTENT_TYPE_GLYPHS. + * + * The above transitions are designed such that one can use a buffer + * in a loop of "reset : add-text : shape" without needing to ever + * modify the content type manually. + * * Since: 0.9.5 **/ void @@ -904,7 +1008,6 @@ void hb_buffer_set_direction (hb_buffer_t *buffer, hb_direction_t direction) - { if (unlikely (hb_object_is_immutable (buffer))) return; @@ -1278,7 +1381,7 @@ * Pre allocates memory for @buffer to fit at least @size number of items. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise + * `true` if @buffer memory allocation succeeded, `false` otherwise * * Since: 0.9.2 **/ @@ -1295,7 +1398,7 @@ * Check if allocating memory for the buffer succeeded. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise. + * `true` if @buffer memory allocation succeeded, `false` otherwise. * * Since: 0.9.2 **/ @@ -1340,7 +1443,7 @@ * end. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise. + * `true` if @buffer memory allocation succeeded, `false` otherwise. * * Since: 0.9.2 **/ @@ -1356,9 +1459,9 @@ /* Wipe the new space */ if (length > buffer->len) { - memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); + hb_memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); if (buffer->have_positions) - memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); + hb_memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); } buffer->len = length; @@ -1426,7 +1529,7 @@ * If buffer did not have positions before, the positions will be * initialized to zeros, unless this function is called from * within a buffer message callback (see hb_buffer_set_message_func()), - * in which case %NULL is returned. + * in which case `NULL` is returned. * * Return value: (transfer none) (array length=length): * The @buffer glyph position array. @@ -1461,7 +1564,7 @@ * and cleared of position data when hb_buffer_clear_contents() is called. * * Return value: - * %true if the @buffer has position array, %false otherwise. + * `true` if the @buffer has position array, `false` otherwise. * * Since: 2.7.3 **/ @@ -1645,10 +1748,10 @@ * @buffer: An #hb_buffer_t * @text: (array length=text_length) (element-type uint8_t): An array of UTF-8 * characters to append. - * @text_length: The length of the @text, or -1 if it is %NULL terminated. + * @text_length: The length of the @text, or -1 if it is `NULL` terminated. * @item_offset: The offset of the first character to add to the @buffer. * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * end of @text (assuming it is `NULL` terminated). * * See hb_buffer_add_codepoints(). * @@ -1671,10 +1774,10 @@ * hb_buffer_add_utf16: * @buffer: An #hb_buffer_t * @text: (array length=text_length): An array of UTF-16 characters to append - * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @text_length: The length of the @text, or -1 if it is `NULL` terminated * @item_offset: The offset of the first character to add to the @buffer * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * See hb_buffer_add_codepoints(). * @@ -1697,10 +1800,10 @@ * hb_buffer_add_utf32: * @buffer: An #hb_buffer_t * @text: (array length=text_length): An array of UTF-32 characters to append - * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @text_length: The length of the @text, or -1 if it is `NULL` terminated * @item_offset: The offset of the first character to add to the @buffer * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * See hb_buffer_add_codepoints(). * @@ -1724,10 +1827,10 @@ * @buffer: An #hb_buffer_t * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 * characters to append - * @text_length: the length of the @text, or -1 if it is %NULL terminated + * @text_length: the length of the @text, or -1 if it is `NULL` terminated * @item_offset: the offset of the first character to add to the @buffer * @item_length: the number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * Similar to hb_buffer_add_codepoints(), but allows only access to first 256 * Unicode code points that can fit in 8-bit strings. @@ -1750,10 +1853,10 @@ * hb_buffer_add_codepoints: * @buffer: a #hb_buffer_t to append characters to. * @text: (array length=text_length): an array of Unicode code points to append. - * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @text_length: the length of the @text, or -1 if it is `NULL` terminated. * @item_offset: the offset of the first code point to add to the @buffer. * @item_length: the number of code points to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * end of @text (assuming it is `NULL` terminated). * * Appends characters from @text array to @buffer. The @item_offset is the * position of the first character from @text that will be appended, and @@ -1766,7 +1869,9 @@ * marks at stat of run. * * This function does not check the validity of @text, it is up to the caller - * to ensure it contains a valid Unicode code points. + * to ensure it contains a valid Unicode scalar values. In contrast, + * hb_buffer_add_utf32() can be used that takes similar input but performs + * sanity-check on the input. * * Since: 0.9.31 **/ @@ -1829,9 +1934,9 @@ hb_segment_properties_overlay (&buffer->props, &source->props); - memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); + hb_memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); if (buffer->have_positions) - memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); + hb_memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); if (source->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) { @@ -2019,7 +2124,7 @@ result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH; if (buf_info->cluster != ref_info->cluster) result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH; - if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED)) + if ((buf_info->mask ^ ref_info->mask) & HB_GLYPH_FLAG_DEFINED) result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH; if (contains && ref_info->codepoint == dottedcircle_glyph) result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; @@ -2074,6 +2179,13 @@ hb_buffer_message_func_t func, void *user_data, hb_destroy_func_t destroy) { + if (unlikely (hb_object_is_immutable (buffer))) + { + if (destroy) + destroy (user_data); + return; + } + if (buffer->message_destroy) buffer->message_destroy (buffer->message_data); @@ -2090,8 +2202,16 @@ bool hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap) { + assert (!have_output || (out_info == info && out_len == idx)); + + message_depth++; + char buf[100]; vsnprintf (buf, sizeof (buf), fmt, ap); - return (bool) this->message_func (this, font, buf, this->message_data); + bool ret = (bool) this->message_func (this, font, buf, this->message_data); + + message_depth--; + + return ret; } #endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh 2023-07-05 07:11:54.000000000 +0000 @@ -32,35 +32,38 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" +#line 33 "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, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, - 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, - 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, - 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 34u, 92u, 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 + 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, + 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, + 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, + 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, + 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, + 9u, 123u, 0u, 0u, 0 }; static const char _deserialize_json_key_spans[] = { 0, 115, 26, 21, 2, 1, 50, 49, - 10, 117, 117, 117, 1, 50, 49, 10, - 117, 117, 1, 1, 50, 49, 117, 117, - 2, 1, 50, 49, 10, 117, 117, 1, - 50, 49, 10, 117, 117, 1, 50, 49, - 59, 117, 59, 117, 117, 1, 50, 49, - 117, 85, 115, 0 + 10, 117, 117, 85, 117, 1, 50, 49, + 10, 117, 117, 1, 1, 50, 49, 117, + 117, 2, 1, 50, 49, 10, 117, 117, + 1, 50, 49, 10, 117, 117, 1, 1, + 50, 49, 117, 117, 1, 50, 49, 59, + 117, 59, 117, 117, 1, 50, 49, 117, + 115, 0 }; static const short _deserialize_json_index_offsets[] = { 0, 0, 116, 143, 165, 168, 170, 221, - 271, 282, 400, 518, 636, 638, 689, 739, - 750, 868, 986, 988, 990, 1041, 1091, 1209, - 1327, 1330, 1332, 1383, 1433, 1444, 1562, 1680, - 1682, 1733, 1783, 1794, 1912, 2030, 2032, 2083, - 2133, 2193, 2311, 2371, 2489, 2607, 2609, 2660, - 2710, 2828, 2914, 3030 + 271, 282, 400, 518, 604, 722, 724, 775, + 825, 836, 954, 1072, 1074, 1076, 1127, 1177, + 1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648, + 1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118, + 2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560, + 2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137, + 3255, 3371 }; static const char _deserialize_json_indicies[] = { @@ -82,28 +85,28 @@ 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 1, 8, 1, + 5, 1, 6, 7, 1, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 9, 1, 10, 11, - 1, 12, 1, 12, 12, 12, 12, 12, + 1, 1, 1, 1, 10, 1, 11, 12, + 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 12, 1, 1, 1, 1, 1, + 1, 1, 13, 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, 13, 1, 13, 13, - 13, 13, 13, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 14, 1, 14, 14, + 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 13, 1, 1, + 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 14, 1, 1, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 1, - 17, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 1, 19, 19, 19, 19, 19, + 1, 1, 15, 1, 1, 16, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 1, + 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 19, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 20, 1, + 1, 1, 20, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 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, @@ -113,11 +116,11 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 21, - 1, 22, 22, 22, 22, 22, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 1, 23, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 22, 1, 1, 1, 1, 1, 1, 1, + 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -128,85 +131,94 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 23, 1, 19, - 19, 19, 19, 19, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 24, 1, 25, + 25, 25, 25, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 19, 1, + 1, 1, 1, 1, 1, 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 20, 1, 1, 1, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, + 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 27, 1, 20, 20, 20, + 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 21, 1, 1, 1, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 21, 1, 24, 1, 24, - 24, 24, 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 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, - 25, 1, 25, 25, 25, 25, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 25, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 26, 1, - 1, 27, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 1, 29, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 1, 31, - 31, 31, 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 31, 1, + 1, 22, 1, 28, 1, 28, 28, 28, + 28, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 32, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 28, 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, 29, 1, + 29, 29, 29, 29, 29, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 30, 1, 1, 31, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 1, 33, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 1, 35, 35, 35, + 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 33, 1, 31, 31, 31, - 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 32, 1, 1, 1, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 37, 1, 35, 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 35, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 36, 1, + 1, 1, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 33, 1, 34, 1, 35, 1, 35, - 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 35, 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, - 36, 1, 36, 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 37, + 1, 38, 1, 39, 1, 39, 39, 39, + 39, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 36, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 37, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 1, 39, 39, 39, 39, - 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 39, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 40, 1, + 40, 40, 40, 40, 40, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 40, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 41, + 42, 42, 42, 42, 42, 42, 42, 42, + 42, 1, 43, 43, 43, 43, 43, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 43, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -215,43 +227,42 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 41, 1, 39, 39, 39, 39, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 45, 1, + 43, 43, 43, 43, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 40, 1, 1, - 1, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 43, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 44, 1, 1, 1, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 41, 1, - 43, 44, 1, 45, 1, 45, 45, 45, - 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 45, 1, 1, 1, + 1, 1, 1, 1, 45, 1, 47, 48, + 1, 49, 1, 49, 49, 49, 49, 49, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 46, 46, 46, 46, 46, 1, 1, 1, + 1, 1, 49, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 47, 1, 1, 48, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 1, 50, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 1, 52, 52, 52, - 52, 52, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 50, 1, 50, 50, + 50, 50, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 52, 1, 1, 1, + 1, 1, 1, 1, 1, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 53, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 51, 1, 1, 52, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 1, + 54, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 1, 56, 56, 56, 56, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 56, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 57, 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, @@ -259,42 +270,43 @@ 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, 54, 1, 52, 52, 52, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 52, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 53, 1, - 1, 1, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 58, + 1, 56, 56, 56, 56, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 56, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 57, 1, 1, 1, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 54, - 1, 55, 1, 55, 55, 55, 55, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 55, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 58, 1, 59, + 1, 59, 59, 59, 59, 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 56, 1, 56, 56, - 56, 56, 56, 1, 1, 1, 1, 1, + 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 57, 1, 1, 58, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 1, - 60, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 1, 62, 62, 62, 62, 62, + 1, 1, 60, 1, 60, 60, 60, 60, + 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 62, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 63, 1, + 61, 1, 1, 62, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 1, 64, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 1, 66, 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 66, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -302,48 +314,42 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 64, - 1, 62, 62, 62, 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 62, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 63, 1, 1, 1, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 68, 1, 66, + 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 67, 1, 1, 1, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 64, 1, 65, - 1, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 68, 1, 69, 1, 70, + 1, 70, 70, 70, 70, 70, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 66, 1, 66, 66, 66, 66, - 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 66, 1, 67, 1, 1, + 1, 1, 71, 1, 71, 71, 71, 71, + 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 68, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 1, 71, 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, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 72, 70, 73, 73, 73, 73, 73, 1, + 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 72, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 1, 74, 74, + 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -352,86 +358,126 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 75, 1, - 70, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 76, 1, 74, 74, 74, 74, + 74, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 74, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 75, + 1, 1, 1, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 76, 1, 78, 1, 78, 78, 78, 78, + 78, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 78, 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, 79, 1, 79, + 79, 79, 79, 79, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 79, 1, + 80, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 81, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 1, 84, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 85, 83, 86, 86, 86, + 86, 86, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 86, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 87, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 70, 1, 76, 76, 76, 76, - 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 76, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 88, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 83, 1, 89, + 89, 89, 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 78, 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 76, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 77, 1, 1, - 1, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 91, 1, 89, 89, 89, + 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 78, 1, - 80, 1, 80, 80, 80, 80, 80, 1, + 1, 1, 1, 1, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 90, 1, 1, 1, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 80, 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, 81, 1, 81, 81, 81, - 81, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 82, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 1, 76, - 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 77, 1, 1, 1, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 91, 1, 93, 1, 93, 93, 93, + 93, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 93, 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, 94, 1, + 94, 94, 94, 94, 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 94, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 95, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 1, 89, 89, 89, 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 78, 1, 85, 85, 85, - 85, 85, 1, 1, 1, 1, 1, 1, + 1, 89, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 90, 1, 1, + 1, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 87, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 91, 1, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -442,46 +488,49 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, - 0 + 1, 1, 2, 1, 1, 0 }; static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 18, 24, - 37, 45, 5, 12, 6, 7, 8, 9, - 11, 9, 11, 10, 2, 49, 10, 49, - 13, 14, 15, 16, 17, 16, 17, 10, - 2, 49, 19, 20, 21, 22, 23, 10, - 2, 49, 23, 25, 31, 26, 27, 28, - 29, 30, 29, 30, 10, 2, 49, 32, - 33, 34, 35, 36, 35, 36, 10, 2, - 49, 38, 39, 40, 43, 44, 40, 41, - 42, 10, 2, 49, 10, 2, 49, 44, - 46, 47, 43, 48, 48, 49, 50, 51 + 1, 0, 2, 2, 3, 4, 19, 25, + 38, 44, 52, 5, 13, 6, 7, 8, + 9, 12, 9, 12, 10, 2, 11, 10, + 11, 11, 56, 57, 14, 15, 16, 17, + 18, 17, 18, 10, 2, 11, 20, 21, + 22, 23, 24, 10, 2, 11, 24, 26, + 32, 27, 28, 29, 30, 31, 30, 31, + 10, 2, 11, 33, 34, 35, 36, 37, + 36, 37, 10, 2, 11, 39, 40, 41, + 42, 43, 10, 2, 11, 43, 45, 46, + 47, 50, 51, 47, 48, 49, 10, 2, + 11, 10, 2, 11, 51, 53, 54, 50, + 55, 55 }; static const char _deserialize_json_trans_actions[] = { 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 3, 3, 4, 0, 5, - 0, 0, 2, 2, 2, 0, 0, 6, - 6, 7, 0, 0, 0, 2, 2, 8, - 8, 9, 0, 0, 0, 0, 0, 2, - 2, 2, 0, 0, 10, 10, 11, 0, - 0, 2, 2, 2, 0, 0, 12, 12, - 13, 0, 0, 2, 14, 14, 0, 15, - 0, 16, 16, 17, 18, 18, 19, 15, - 0, 0, 20, 20, 21, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 2, + 2, 2, 0, 0, 3, 3, 4, 0, + 5, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 6, 6, 7, 0, 0, + 0, 2, 2, 8, 8, 9, 0, 0, + 0, 0, 0, 2, 2, 2, 0, 0, + 10, 10, 11, 0, 0, 2, 2, 2, + 0, 0, 12, 12, 13, 0, 0, 0, + 2, 2, 14, 14, 15, 0, 0, 0, + 2, 16, 16, 0, 17, 0, 18, 18, + 19, 20, 20, 21, 17, 0, 0, 22, + 22, 23 }; static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 49; +static const int deserialize_json_first_final = 56; static const int deserialize_json_error = 0; static const int deserialize_json_en_main = 1; -#line 108 "hb-buffer-deserialize-json.rl" +#line 111 "hb-buffer-deserialize-json.rl" static hb_bool_t @@ -499,21 +548,19 @@ while (p < pe && ISSPACE (*p)) p++; if (p < pe && *p == (buffer->len ? ',' : '[')) - { *end_ptr = ++p; - } const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 512 "hb-buffer-deserialize-json.hh" +#line 552 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 517 "hb-buffer-deserialize-json.hh" +#line 555 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -541,8 +588,8 @@ case 1: #line 38 "hb-buffer-deserialize-json.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } break; case 5: @@ -561,25 +608,25 @@ tok = p; } break; - case 15: + case 17: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 21: + case 23: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 16: + case 18: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ if (!hb_font_glyph_from_string (font, - tok, p - tok, + tok+1, p - tok - 2, /* Skip "" */ &info.codepoint)) return false; } break; - case 18: + case 20: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } break; @@ -604,6 +651,10 @@ { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; case 14: +#line 72 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } + break; + case 16: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -611,7 +662,7 @@ #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 20: + case 22: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -619,12 +670,12 @@ #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 17: + case 19: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ if (!hb_font_glyph_from_string (font, - tok, p - tok, + tok+1, p - tok - 2, /* Skip "" */ &info.codepoint)) return false; } @@ -637,7 +688,7 @@ *end_ptr = p; } break; - case 19: + case 21: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } #line 43 "hb-buffer-deserialize-json.rl" @@ -709,7 +760,19 @@ *end_ptr = p; } break; -#line 713 "hb-buffer-deserialize-json.hh" + case 15: +#line 72 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 733 "hb-buffer-deserialize-json.hh" } _again: @@ -721,7 +784,7 @@ _out: {} } -#line 136 "hb-buffer-deserialize-json.rl" +#line 137 "hb-buffer-deserialize-json.rl" *end_ptr = p; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,692 @@ + +#line 1 "hb-buffer-deserialize-text-glyphs.rl" +/* + * Copyright © 2013 Google, 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH +#define HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH + +#include "hb.hh" + + +#line 33 "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, + 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, + 9u, 124u, 9u, 124u, 9u, 124u, 0 +}; + +static const char _deserialize_text_glyphs_key_spans[] = { + 0, 10, 13, 10, 13, 10, 10, 13, + 10, 1, 13, 10, 14, 82, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116 +}; + +static const short _deserialize_text_glyphs_index_offsets[] = { + 0, 0, 11, 25, 36, 50, 61, 72, + 86, 97, 99, 113, 124, 139, 222, 339, + 456, 573, 690, 807, 924, 1041, 1158, 1275, + 1392, 1509, 1626 +}; + +static const char _deserialize_text_glyphs_indicies[] = { + 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 3, 1, 1, 4, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 1, 6, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 1, 8, 1, 1, + 9, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 1, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 1, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 1, 15, 1, 1, 16, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 1, 18, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 1, 20, 1, 21, 1, 1, 22, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 1, 24, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 1, 20, 1, 1, + 1, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 1, 26, 26, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 26, 1, + 1, 26, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 26, 26, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 26, 1, 28, + 28, 28, 28, 28, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 28, 27, + 27, 29, 27, 27, 27, 27, 27, 27, + 27, 30, 1, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 31, 27, 27, 32, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 33, 1, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 28, 27, 34, 34, 34, 34, + 34, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 34, 26, 26, 35, 26, + 26, 26, 26, 26, 26, 26, 36, 1, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 37, 26, 26, 38, 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, 39, + 1, 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, 26, 26, 40, + 26, 41, 41, 41, 41, 41, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 41, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 42, 1, 43, 43, + 43, 43, 43, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 43, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 44, 1, 41, 41, 41, 41, 41, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 41, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 42, 1, + 46, 46, 46, 46, 46, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 46, + 1, 1, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 48, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 49, 1, 50, 50, 50, + 50, 50, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 50, 1, 1, 51, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 52, 1, 50, 50, 50, 50, 50, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 50, 1, 1, 51, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 52, 1, 46, + 46, 46, 46, 46, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 46, 1, + 1, 47, 1, 1, 1, 1, 1, 1, + 1, 1, 48, 1, 1, 1, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 49, 1, 53, 53, 53, 53, + 53, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 53, 1, 1, 54, 1, + 1, 1, 1, 1, 1, 1, 55, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 56, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 57, + 1, 58, 58, 58, 58, 58, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 58, 1, 1, 59, 1, 1, 1, 1, + 1, 1, 1, 60, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 61, 1, 58, 58, + 58, 58, 58, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 58, 1, 1, + 59, 1, 1, 1, 1, 1, 1, 1, + 60, 1, 1, 1, 1, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 61, 1, 53, 53, 53, 53, 53, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 53, 1, 1, 54, 1, 1, + 1, 1, 1, 1, 1, 55, 1, 1, + 1, 1, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 1, 1, 1, 1, + 1, 1, 56, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 57, 1, + 0 +}; + +static const char _deserialize_text_glyphs_trans_targs[] = { + 16, 0, 18, 3, 19, 22, 19, 22, + 5, 20, 21, 20, 21, 23, 26, 8, + 9, 12, 9, 12, 10, 11, 24, 25, + 24, 25, 15, 15, 14, 1, 2, 6, + 7, 13, 15, 1, 2, 6, 7, 13, + 14, 17, 14, 17, 14, 18, 17, 1, + 4, 14, 17, 1, 14, 17, 1, 2, + 7, 14, 17, 1, 2, 14, 26 +}; + +static const char _deserialize_text_glyphs_trans_actions[] = { + 1, 0, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, 1, 1, 1, + 1, 1, 0, 0, 2, 1, 1, 1, + 0, 0, 0, 4, 3, 5, 5, 5, + 5, 4, 6, 7, 7, 7, 7, 0, + 6, 8, 8, 0, 0, 0, 9, 10, + 10, 9, 11, 12, 11, 13, 14, 14, + 14, 13, 15, 16, 16, 15, 0 +}; + +static const char _deserialize_text_glyphs_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 6, + 8, 0, 8, 9, 11, 11, 9, 13, + 15, 15, 13 +}; + +static const int deserialize_text_glyphs_start = 14; +static const int deserialize_text_glyphs_first_final = 14; +static const int deserialize_text_glyphs_error = 0; + +static const int deserialize_text_glyphs_en_main = 14; + + +#line 98 "hb-buffer-deserialize-text-glyphs.rl" + + +static hb_bool_t +_hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) +{ + const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? '|' : '[')) + *end_ptr = ++p; + + const char *end = strchr ((char *) p, ']'); + if (end) + pe = eof = end; + else + { + end = strrchr ((char *) p, '|'); + if (end) + pe = eof = end; + else + pe = eof = p; + } + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 346 "hb-buffer-deserialize-text-glyphs.hh" + { + cs = deserialize_text_glyphs_start; + } + +#line 349 "hb-buffer-deserialize-text-glyphs.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _deserialize_text_glyphs_trans_keys + (cs<<1); + _inds = _deserialize_text_glyphs_indicies + _deserialize_text_glyphs_index_offsets[cs]; + + _slen = _deserialize_text_glyphs_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && + (*p) <= _keys[1] ? + (*p) - _keys[0] : _slen ]; + + cs = _deserialize_text_glyphs_trans_targs[_trans]; + + if ( _deserialize_text_glyphs_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_text_glyphs_trans_actions[_trans] ) { + case 1: +#line 51 "hb-buffer-deserialize-text-glyphs.rl" + { + tok = p; +} + break; + case 7: +#line 55 "hb-buffer-deserialize-text-glyphs.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 14: +#line 63 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 2: +#line 64 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 16: +#line 65 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 10: +#line 66 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 12: +#line 67 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } + break; + case 4: +#line 38 "hb-buffer-deserialize-text-glyphs.rl" + { + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text-glyphs.rl" + { + tok = p; +} + break; + case 6: +#line 55 "hb-buffer-deserialize-text-glyphs.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 13: +#line 63 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 15: +#line 65 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 9: +#line 66 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: +#line 67 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 8: +#line 68 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 5: +#line 38 "hb-buffer-deserialize-text-glyphs.rl" + { + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text-glyphs.rl" + { + tok = p; +} +#line 55 "hb-buffer-deserialize-text-glyphs.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 3: +#line 38 "hb-buffer-deserialize-text-glyphs.rl" + { + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text-glyphs.rl" + { + tok = p; +} +#line 55 "hb-buffer-deserialize-text-glyphs.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 516 "hb-buffer-deserialize-text-glyphs.hh" + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + switch ( _deserialize_text_glyphs_eof_actions[cs] ) { + case 6: +#line 55 "hb-buffer-deserialize-text-glyphs.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 13: +#line 63 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 15: +#line 65 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 9: +#line 66 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: +#line 67 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 8: +#line 68 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 3: +#line 38 "hb-buffer-deserialize-text-glyphs.rl" + { + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text-glyphs.rl" + { + tok = p; +} +#line 55 "hb-buffer-deserialize-text-glyphs.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text-glyphs.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 616 "hb-buffer-deserialize-text-glyphs.hh" + } + } + + _out: {} + } + +#line 136 "hb-buffer-deserialize-text-glyphs.rl" + + + if (pe < orig_pe && *pe == ']') + { + pe++; + if (p == pe) + p++; + } + + *end_ptr = p; + + return p == pe; +} + +#endif /* HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,853 +0,0 @@ - -#line 1 "hb-buffer-deserialize-text.rl" -/* - * Copyright © 2013 Google, 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. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH -#define HB_BUFFER_DESERIALIZE_TEXT_HH - -#include "hb.hh" - - -#line 36 "hb-buffer-deserialize-text.hh" -static const unsigned char _deserialize_text_trans_keys[] = { - 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 45u, 57u, - 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, - 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 0 -}; - -static const char _deserialize_text_key_spans[] = { - 0, 83, 1, 1, 55, 77, 10, 13, - 10, 10, 13, 10, 1, 13, 10, 14, - 82, 13, 10, 116, 116, 0, 77, 116, - 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116 -}; - -static const short _deserialize_text_index_offsets[] = { - 0, 0, 84, 86, 88, 144, 222, 233, - 247, 258, 269, 283, 294, 296, 310, 321, - 336, 419, 433, 444, 561, 678, 679, 757, - 874, 991, 1108, 1225, 1342, 1459, 1576, 1693, - 1810, 1927, 2044, 2161, 2278 -}; - -static const char _deserialize_text_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 4, 1, 5, - 1, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 1, 1, 1, 1, 1, - 1, 1, 6, 6, 6, 6, 6, 6, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 6, 6, 6, 6, 6, 6, - 1, 7, 7, 7, 7, 7, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 7, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 1, 8, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 1, 10, 1, 1, 11, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 1, - 13, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 1, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 1, 17, 1, - 1, 18, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 1, 20, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 1, 22, - 1, 23, 1, 1, 24, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 1, 26, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 1, 22, 1, 1, 1, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 1, 28, 28, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 28, 1, 1, 28, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 28, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 1, 29, 1, 1, 30, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 1, 32, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 1, 34, 34, 34, - 34, 34, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 34, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 1, 1, - 1, 36, 37, 1, 1, 35, 35, 35, - 35, 35, 35, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 35, 35, - 35, 35, 35, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 38, 1, 39, 39, 39, 39, 39, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 41, 1, 1, - 7, 7, 7, 7, 7, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 7, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 1, 42, 42, - 42, 42, 42, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 42, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 43, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 44, 1, 42, 42, 42, 42, 42, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 42, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 1, 1, 1, 1, - 43, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 44, 1, - 47, 47, 47, 47, 47, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 47, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 48, 1, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 49, 46, 46, 50, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 51, 52, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 53, 46, 54, 54, 54, - 54, 54, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 54, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 55, - 1, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 56, 28, 28, 57, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 58, 59, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 60, 28, 61, 61, 61, 61, 61, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 61, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 62, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 63, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 64, 1, 65, - 65, 65, 65, 65, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 65, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 40, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 66, 1, 67, 67, 67, 67, - 67, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 67, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 48, 1, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 49, 46, 46, 50, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 51, - 52, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 53, - 46, 68, 68, 68, 68, 68, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 68, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 69, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 70, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 71, 1, 72, 72, - 72, 72, 72, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 72, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 73, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 74, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 72, 72, 72, 72, 72, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 72, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 73, 1, 1, - 1, 1, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 74, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 75, 1, - 68, 68, 68, 68, 68, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 68, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 69, 1, 1, 1, 1, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 1, 1, 1, 1, 1, 1, 70, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 43, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 77, 77, 77, - 77, 77, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 78, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 79, 1, 77, 77, 77, 77, 77, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 77, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 78, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 61, - 61, 61, 61, 61, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 61, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 62, 1, 1, 1, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 63, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 1, 0 -}; - -static const char _deserialize_text_trans_targs[] = { - 1, 0, 2, 25, 3, 4, 19, 5, - 23, 24, 8, 27, 36, 27, 36, 30, - 33, 11, 12, 15, 12, 15, 13, 14, - 31, 32, 31, 32, 26, 18, 34, 35, - 34, 35, 20, 19, 6, 21, 22, 20, - 21, 22, 20, 21, 22, 24, 26, 26, - 7, 9, 10, 16, 21, 29, 26, 7, - 9, 10, 16, 21, 29, 28, 17, 21, - 29, 28, 29, 29, 28, 7, 10, 29, - 28, 7, 21, 29, 33, 28, 21, 29 -}; - -static const char _deserialize_text_trans_actions[] = { - 0, 0, 0, 0, 1, 0, 2, 0, - 2, 2, 3, 4, 4, 5, 5, 4, - 4, 3, 3, 3, 0, 0, 6, 3, - 4, 4, 5, 5, 5, 3, 4, 4, - 5, 5, 7, 8, 9, 7, 7, 0, - 0, 0, 10, 10, 10, 8, 12, 13, - 14, 14, 14, 15, 11, 11, 17, 18, - 18, 18, 0, 16, 16, 19, 20, 19, - 19, 0, 0, 13, 10, 21, 21, 10, - 22, 23, 22, 22, 5, 24, 24, 24 -}; - -static const char _deserialize_text_eof_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 0, 10, - 10, 11, 16, 19, 0, 11, 10, 22, - 22, 10, 24, 24, 19 -}; - -static const int deserialize_text_start = 1; -static const int deserialize_text_first_final = 19; -static const int deserialize_text_error = 0; - -static const int deserialize_text_en_main = 1; - - -#line 114 "hb-buffer-deserialize-text.rl" - - -static hb_bool_t -_hb_buffer_deserialize_text (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) -{ - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - - const char *eof = pe, *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 428 "hb-buffer-deserialize-text.hh" - { - cs = deserialize_text_start; - } - -#line 433 "hb-buffer-deserialize-text.hh" - { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _deserialize_text_trans_keys + (cs<<1); - _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs]; - - _slen = _deserialize_text_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && - (*p) <= _keys[1] ? - (*p) - _keys[0] : _slen ]; - - cs = _deserialize_text_trans_targs[_trans]; - - if ( _deserialize_text_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _deserialize_text_trans_actions[_trans] ) { - case 1: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} - break; - case 3: -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} - break; - case 5: -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } - break; - case 8: -#line 56 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_unicode ())) return false; } - break; - case 18: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - break; - case 9: -#line 66 "hb-buffer-deserialize-text.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } - break; - case 21: -#line 68 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 6: -#line 69 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 23: -#line 70 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 20: -#line 71 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 15: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} - break; - case 4: -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } - break; - case 2: -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 56 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_unicode ())) return false; } - break; - case 16: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 66 "hb-buffer-deserialize-text.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 10: -#line 68 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 22: -#line 70 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 19: -#line 71 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 24: -#line 72 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 12: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } - break; - case 14: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - break; - case 17: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 722 "hb-buffer-deserialize-text.hh" - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - switch ( _deserialize_text_eof_actions[cs] ) { - case 16: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 66 "hb-buffer-deserialize-text.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 10: -#line 68 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 22: -#line 70 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 19: -#line 71 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 24: -#line 72 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 839 "hb-buffer-deserialize-text.hh" - } - } - - _out: {} - } - -#line 138 "hb-buffer-deserialize-text.rl" - - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; -} - -#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,332 @@ + +#line 1 "hb-buffer-deserialize-text-unicode.rl" +/* + * Copyright © 2013 Google, 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH +#define HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH + +#include "hb.hh" + + +#line 33 "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 +}; + +static const char _deserialize_text_unicode_key_spans[] = { + 0, 109, 60, 55, 10, 116, 116, 116, + 116 +}; + +static const short _deserialize_text_unicode_index_offsets[] = { + 0, 0, 110, 171, 227, 238, 355, 472, + 589 +}; + +static const char _deserialize_text_unicode_indicies[] = { + 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 3, + 1, 1, 1, 1, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 1, 1, + 1, 1, 1, 1, 1, 4, 4, 4, + 4, 4, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 4, 4, 4, + 4, 4, 4, 1, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 1, 1, + 1, 1, 1, 1, 1, 4, 4, 4, + 4, 4, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 4, 4, 4, + 4, 4, 4, 1, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 1, 7, + 7, 7, 7, 7, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 7, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 1, 1, 1, 9, 1, 1, 1, 8, + 8, 8, 8, 8, 8, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 8, + 8, 8, 8, 8, 8, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 10, 1, 11, 11, 11, 11, + 11, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 11, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 12, 12, 12, 12, 12, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 12, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 13, 1, 12, 12, + 12, 12, 12, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 12, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 13, 1, 0 +}; + +static const char _deserialize_text_unicode_trans_targs[] = { + 1, 0, 2, 3, 5, 7, 8, 6, + 5, 4, 1, 6, 6, 1, 8 +}; + +static const char _deserialize_text_unicode_trans_actions[] = { + 0, 0, 1, 0, 2, 2, 2, 3, + 0, 4, 3, 0, 5, 5, 0 +}; + +static const char _deserialize_text_unicode_eof_actions[] = { + 0, 0, 0, 0, 0, 3, 0, 5, + 5 +}; + +static const int deserialize_text_unicode_start = 1; +static const int deserialize_text_unicode_first_final = 5; +static const int deserialize_text_unicode_error = 0; + +static const int deserialize_text_unicode_en_main = 1; + + +#line 79 "hb-buffer-deserialize-text-unicode.rl" + + +static hb_bool_t +_hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) +{ + const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? '|' : '<')) + *end_ptr = ++p; + + const char *end = strchr ((char *) p, '>'); + if (end) + pe = eof = end; + else + { + end = strrchr ((char *) p, '|'); + if (end) + pe = eof = end; + else + pe = eof = p; + } + + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + const hb_glyph_position_t pos = {0}; + +#line 194 "hb-buffer-deserialize-text-unicode.hh" + { + cs = deserialize_text_unicode_start; + } + +#line 197 "hb-buffer-deserialize-text-unicode.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _deserialize_text_unicode_trans_keys + (cs<<1); + _inds = _deserialize_text_unicode_indicies + _deserialize_text_unicode_index_offsets[cs]; + + _slen = _deserialize_text_unicode_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && + (*p) <= _keys[1] ? + (*p) - _keys[0] : _slen ]; + + cs = _deserialize_text_unicode_trans_targs[_trans]; + + if ( _deserialize_text_unicode_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_text_unicode_trans_actions[_trans] ) { + case 1: +#line 38 "hb-buffer-deserialize-text-unicode.rl" + { + hb_memset (&info, 0, sizeof (info)); +} + break; + case 2: +#line 51 "hb-buffer-deserialize-text-unicode.rl" + { + tok = p; +} + break; + case 4: +#line 55 "hb-buffer-deserialize-text-unicode.rl" + {if (!parse_hex (tok, p, &info.codepoint )) return false; } + break; + case 3: +#line 55 "hb-buffer-deserialize-text-unicode.rl" + {if (!parse_hex (tok, p, &info.codepoint )) return false; } +#line 42 "hb-buffer-deserialize-text-unicode.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + if (buffer->have_positions) + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 5: +#line 57 "hb-buffer-deserialize-text-unicode.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 42 "hb-buffer-deserialize-text-unicode.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + if (buffer->have_positions) + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 256 "hb-buffer-deserialize-text-unicode.hh" + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + switch ( _deserialize_text_unicode_eof_actions[cs] ) { + case 3: +#line 55 "hb-buffer-deserialize-text-unicode.rl" + {if (!parse_hex (tok, p, &info.codepoint )) return false; } +#line 42 "hb-buffer-deserialize-text-unicode.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + if (buffer->have_positions) + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 5: +#line 57 "hb-buffer-deserialize-text-unicode.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 42 "hb-buffer-deserialize-text-unicode.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + if (buffer->have_positions) + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 289 "hb-buffer-deserialize-text-unicode.hh" + } + } + + _out: {} + } + +#line 115 "hb-buffer-deserialize-text-unicode.rl" + + + if (pe < orig_pe && *pe == '>') + { + pe++; + if (p == pe) + p++; + } + + *end_ptr = p; + + return p == pe; +} + +#endif /* HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer.h 2023-07-05 07:11:54.000000000 +0000 @@ -142,6 +142,15 @@ * shaping, otherwise the buffer flag will not be * reliably produced. * Since: 4.0.0 + * @HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL: In scripts that use elongation (Arabic, + Mongolian, Syriac, etc.), this flag signifies + that it is safe to insert a U+0640 TATWEEL + character before this cluster for elongation. + This flag does not determine the + script-specific elongation places, but only + when it is safe to do the elongation without + interrupting text shaping. + Since: 5.1.0 * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags. * * Flags for #hb_glyph_info_t. @@ -149,10 +158,11 @@ * Since: 1.5.0 */ typedef enum { /*< flags >*/ - HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, - HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002, + HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, + HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002, + HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL = 0x00000004, - HB_GLYPH_FLAG_DEFINED = 0x00000003 /* OR of all defined flags */ + HB_GLYPH_FLAG_DEFINED = 0x00000007 /* OR of all defined flags */ } hb_glyph_flags_t; HB_EXTERN hb_glyph_flags_t @@ -266,7 +276,7 @@ hb_bool_t replace); HB_EXTERN void * -hb_buffer_get_user_data (hb_buffer_t *buffer, +hb_buffer_get_user_data (const hb_buffer_t *buffer, hb_user_data_key_t *key); @@ -373,6 +383,10 @@ * flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT * glyph-flag should be produced by the shaper. By default * it will not be produced since it incurs a cost. Since: 4.0.0 + * @HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL: + * flag indicating that the @HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL + * glyph-flag should be produced by the shaper. By default + * it will not be produced. Since: 5.1.0 * @HB_BUFFER_FLAG_DEFINED: All currently defined flags: Since: 4.4.0 * * Flags for #hb_buffer_t. @@ -388,8 +402,9 @@ HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u, HB_BUFFER_FLAG_VERIFY = 0x00000020u, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u, + HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL = 0x00000080u, - HB_BUFFER_FLAG_DEFINED = 0x0000007Fu + HB_BUFFER_FLAG_DEFINED = 0x000000FFu } hb_buffer_flags_t; HB_EXTERN void @@ -748,23 +763,23 @@ /* - * Debugging. + * Tracing. */ /** * hb_buffer_message_func_t: * @buffer: An #hb_buffer_t to work upon * @font: The #hb_font_t the @buffer is shaped with - * @message: %NULL-terminated message passed to the function + * @message: `NULL`-terminated message passed to the function * @user_data: User data pointer passed by the caller * * A callback method for #hb_buffer_t. The method gets called with the * #hb_buffer_t it was set on, the #hb_font_t the buffer is shaped with and a * message describing what step of the shaping process will be performed. - * Returning %false from this method will skip this shaping step and move to + * Returning `false` from this method will skip this shaping step and move to * the next one. * - * Return value: %true to perform the shaping step, %false to skip it. + * Return value: `true` to perform the shaping step, `false` to skip it. * * Since: 1.1.3 */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh 2023-07-05 07:11:54.000000000 +0000 @@ -32,28 +32,9 @@ #include "hb.hh" #include "hb-unicode.hh" +#include "hb-set-digest.hh" -#ifndef HB_BUFFER_MAX_LEN_FACTOR -#define HB_BUFFER_MAX_LEN_FACTOR 64 -#endif -#ifndef HB_BUFFER_MAX_LEN_MIN -#define HB_BUFFER_MAX_LEN_MIN 16384 -#endif -#ifndef HB_BUFFER_MAX_LEN_DEFAULT -#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ -#endif - -#ifndef HB_BUFFER_MAX_OPS_FACTOR -#define HB_BUFFER_MAX_OPS_FACTOR 1024 -#endif -#ifndef HB_BUFFER_MAX_OPS_MIN -#define HB_BUFFER_MAX_OPS_MIN 16384 -#endif -#ifndef HB_BUFFER_MAX_OPS_DEFAULT -#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ -#endif - static_assert ((sizeof (hb_glyph_info_t) == 20), ""); static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), ""); @@ -207,6 +188,14 @@ hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } + hb_set_digest_t digest () const + { + hb_set_digest_t d; + d.init (); + d.add_array (&info[0].codepoint, len, sizeof (info[0])); + return d; + } + HB_INTERNAL void similar (const hb_buffer_t &src); HB_INTERNAL void reset (); HB_INTERNAL void clear (); @@ -288,7 +277,8 @@ HB_INTERNAL void guess_segment_properties (); - HB_INTERNAL void sync (); + HB_INTERNAL bool sync (); + HB_INTERNAL int sync_so_far (); HB_INTERNAL void clear_output (); HB_INTERNAL void clear_positions (); @@ -401,6 +391,8 @@ HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); /* Merge clusters for deleting current glyph, and skip it. */ HB_INTERNAL void delete_glyph (); + HB_INTERNAL void delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info)); + /* Adds glyph flags in mask to infos with clusters between start and end. @@ -461,6 +453,17 @@ start, end, true); } + void safe_to_insert_tatweel (unsigned int start = 0, unsigned int end = -1) + { + if ((flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL) == 0) + { + unsafe_to_break (start, end); + return; + } + _set_glyph_flags (HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL, + start, end, + true); + } void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1) { if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0)) @@ -555,15 +558,11 @@ if (likely (!messaging ())) return true; - message_depth++; - va_list ap; va_start (ap, fmt); bool ret = message_impl (font, fmt, ap); va_end (ap); - message_depth--; - return ret; #endif } @@ -582,21 +581,59 @@ unsigned int cluster, hb_mask_t mask) { - for (unsigned int i = start; i < end; i++) - if (cluster != infos[i].cluster) + if (unlikely (start == end)) + return; + + unsigned cluster_first = infos[start].cluster; + unsigned cluster_last = infos[end - 1].cluster; + + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS || + (cluster != cluster_first && cluster != cluster_last)) + { + for (unsigned int i = start; i < end; i++) + if (cluster != infos[i].cluster) + { + scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; + infos[i].mask |= mask; + } + return; + } + + /* Monotone clusters */ + + if (cluster == cluster_first) + { + for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--) + { + scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; + infos[i - 1].mask |= mask; + } + } + else /* cluster == cluster_last */ + { + for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++) { scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i].mask |= mask; } + } } - static unsigned + unsigned _infos_find_min_cluster (const hb_glyph_info_t *infos, unsigned start, unsigned end, unsigned cluster = UINT_MAX) { - for (unsigned int i = start; i < end; i++) - cluster = hb_min (cluster, infos[i].cluster); - return cluster; + if (unlikely (start == end)) + return cluster; + + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + { + for (unsigned int i = start; i < end; i++) + cluster = hb_min (cluster, infos[i].cluster); + return cluster; + } + + return hb_min (cluster, hb_min (infos[start].cluster, infos[end - 1].cluster)); } void clear_glyph_flags (hb_mask_t mask = 0) diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc 2023-07-05 07:11:54.000000000 +0000 @@ -56,7 +56,7 @@ /** * hb_buffer_serialize_format_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * * Parses a string into an #hb_buffer_serialize_format_t. Does not check if * @str is a valid buffer serialization format, use @@ -78,11 +78,11 @@ * hb_buffer_serialize_format_to_string: * @format: an #hb_buffer_serialize_format_t to convert. * - * Converts @format to the string corresponding it, or %NULL if it is not a valid + * Converts @format to the string corresponding it, or `NULL` if it is not a valid * #hb_buffer_serialize_format_t. * * Return value: (transfer none): - * A %NULL terminated string corresponding to @format. Should not be freed. + * A `NULL` terminated string corresponding to @format. Should not be freed. * * Since: 0.9.7 **/ @@ -183,7 +183,7 @@ unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; @@ -241,7 +241,7 @@ unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; @@ -329,7 +329,7 @@ unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; @@ -381,7 +381,7 @@ unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; @@ -400,9 +400,9 @@ * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, an empty font will be used. + * read glyph names and extents. If `NULL`, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -514,7 +514,7 @@ * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -637,9 +637,9 @@ * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, an empty font will be used. + * read glyph names and extents. If `NULL`, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -721,13 +721,14 @@ } #include "hb-buffer-deserialize-json.hh" -#include "hb-buffer-deserialize-text.hh" +#include "hb-buffer-deserialize-text-glyphs.hh" +#include "hb-buffer-deserialize-text-unicode.hh" /** * hb_buffer_deserialize_glyphs: * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): string to deserialize - * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated * @end_ptr: (out) (optional): output pointer to the character after last * consumed one. * @font: (nullable): font for getting glyph IDs @@ -736,7 +737,8 @@ * Deserializes glyphs @buffer from textual representation in the format * produced by hb_buffer_serialize_glyphs(). * - * Return value: %true if @buf is not fully consumed, %false otherwise. + * Return value: `true` if parse was successful, `false` if an error + * occurred. * * Since: 0.9.7 **/ @@ -779,9 +781,9 @@ switch (format) { case HB_BUFFER_SERIALIZE_FORMAT_TEXT: - return _hb_buffer_deserialize_text (buffer, - buf, buf_len, end_ptr, - font); + return _hb_buffer_deserialize_text_glyphs (buffer, + buf, buf_len, end_ptr, + font); case HB_BUFFER_SERIALIZE_FORMAT_JSON: return _hb_buffer_deserialize_json (buffer, @@ -800,7 +802,7 @@ * hb_buffer_deserialize_unicode: * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): string to deserialize - * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated * @end_ptr: (out) (optional): output pointer to the character after last * consumed one. * @format: the #hb_buffer_serialize_format_t of the input @buf @@ -808,7 +810,8 @@ * Deserializes Unicode @buffer from textual representation in the format * produced by hb_buffer_serialize_unicode(). * - * Return value: %true if @buf is not fully consumed, %false otherwise. + * Return value: `true` if parse was successful, `false` if an error + * occurred. * * Since: 2.7.3 **/ @@ -849,9 +852,9 @@ switch (format) { case HB_BUFFER_SERIALIZE_FORMAT_TEXT: - return _hb_buffer_deserialize_text (buffer, - buf, buf_len, end_ptr, - font); + return _hb_buffer_deserialize_text_unicode (buffer, + buf, buf_len, end_ptr, + font); case HB_BUFFER_SERIALIZE_FORMAT_JSON: return _hb_buffer_deserialize_json (buffer, diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc 2023-07-05 07:11:54.000000000 +0000 @@ -150,7 +150,7 @@ assert (text_start < text_end); if (0) - printf("start %d end %d text start %d end %d\n", start, end, text_start, text_end); + printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); hb_buffer_clear_contents (fragment); @@ -186,7 +186,7 @@ bool ret = true; hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); - if (diff) + if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) { buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed."); ret = false; @@ -292,7 +292,7 @@ assert (text_start < text_end); if (0) - printf("start %d end %d text start %d end %d\n", start, end, text_start, text_end); + printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); #if 0 hb_buffer_flags_t flags = hb_buffer_get_flags (fragment); @@ -313,7 +313,6 @@ bool ret = true; hb_buffer_diff_flags_t diff; - /* * Shape the two fragment streams. */ @@ -382,7 +381,7 @@ * Diff results. */ diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); - if (diff) + if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) { buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed."); ret = false; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cache.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cache.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cache.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cache.hh 2023-07-05 07:11:54.000000000 +0000 @@ -32,27 +32,39 @@ /* Implements a lockfree cache for int->int functions. */ -template +template struct hb_cache_t { + using item_t = typename std::conditional::type, + typename std::conditional::type + >::type; + static_assert ((key_bits >= cache_bits), ""); - static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (hb_atomic_int_t)), ""); - static_assert (sizeof (hb_atomic_int_t) == sizeof (unsigned int), ""); + static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), ""); + + hb_cache_t () { init (); } void init () { clear (); } - void fini () {} void clear () { for (unsigned i = 0; i < ARRAY_LENGTH (values); i++) - values[i].set_relaxed (-1); + values[i] = -1; } bool get (unsigned int key, unsigned int *value) const { unsigned int k = key & ((1u<> value_bits) != (key >> cache_bits)) return false; *value = v & ((1u<>cache_bits)< hb_cmap_cache_t; -typedef hb_cache_t<16, 24, 8> hb_advance_cache_t; - #endif /* HB_CACHE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff1-interp-cs.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff1-interp-cs.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff1-interp-cs.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff1-interp-cs.hh 2023-07-05 07:11:54.000000000 +0000 @@ -38,7 +38,8 @@ struct cff1_cs_interp_env_t : cs_interp_env_t { template - cff1_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd) + cff1_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd, + const int *coords_=nullptr, unsigned int num_coords_=0) : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs) { processed_width = false; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh 2023-07-05 07:11:54.000000000 +0000 @@ -40,20 +40,22 @@ void set_real (double v) { reset_blends (); number_t::set_real (v); } void set_blends (unsigned int numValues_, unsigned int valueIndex_, - unsigned int numBlends, hb_array_t blends_) + hb_array_t blends_) { numValues = numValues_; valueIndex = valueIndex_; - deltas.resize (numBlends); + unsigned numBlends = blends_.length; + if (unlikely (!deltas.resize_exact (numBlends))) + return; for (unsigned int i = 0; i < numBlends; i++) - deltas[i] = blends_[i]; + deltas.arrayZ[i] = blends_.arrayZ[i]; } bool blending () const { return deltas.length > 0; } void reset_blends () { numValues = valueIndex = 0; - deltas.resize (0); + deltas.shrink (0); } unsigned int numValues; @@ -61,7 +63,6 @@ hb_vector_t deltas; }; -typedef interp_env_t BlendInterpEnv; typedef biased_subrs_t cff2_biased_subrs_t; template @@ -117,7 +118,7 @@ region_count = varStore->varStore.get_region_index_count (get_ivs ()); if (do_blend) { - if (unlikely (!scalars.resize (region_count))) + if (unlikely (!scalars.resize_exact (region_count))) SUPER::set_error (); else varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, @@ -154,13 +155,16 @@ { if (likely (scalars.length == deltas.length)) { - for (unsigned int i = 0; i < scalars.length; i++) - v += (double) scalars[i] * deltas[i].to_real (); + unsigned count = scalars.length; + for (unsigned i = 0; i < count; i++) + v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real (); } } return v; } + bool have_coords () const { return num_coords; } + protected: const int *coords; unsigned int num_coords; @@ -220,7 +224,10 @@ const hb_array_t blends, unsigned n, unsigned i) { - arg.set_blends (n, i, blends.length, blends); + if (env.have_coords ()) + arg.set_int (round (arg.to_real () + env.blend_deltas (blends))); + else + arg.set_blends (n, i, blends); } template diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -284,65 +284,56 @@ /* A byte string associated with the current offset and an error condition */ struct byte_str_ref_t { - byte_str_ref_t () { init (); } - - void init () - { - str = hb_ubytes_t (); - offset = 0; - error = false; - } - - void fini () {} + byte_str_ref_t () + : str () {} byte_str_ref_t (const hb_ubytes_t &str_, unsigned int offset_ = 0) - : str (str_), offset (offset_), error (false) {} + : str (str_) { set_offset (offset_); } void reset (const hb_ubytes_t &str_, unsigned int offset_ = 0) { str = str_; - offset = offset_; - error = false; + set_offset (offset_); } const unsigned char& operator [] (int i) { - if (unlikely ((unsigned int) (offset + i) >= str.length)) + if (unlikely ((unsigned int) (get_offset () + i) >= str.length)) { set_error (); return Null (unsigned char); } - return str[offset + i]; + return str.arrayZ[get_offset () + i]; } + unsigned char head_unchecked () const { return str.arrayZ[get_offset ()]; } + /* Conversion to hb_ubytes_t */ - operator hb_ubytes_t () const { return str.sub_array (offset, str.length - offset); } + operator hb_ubytes_t () const { return str.sub_array (get_offset ()); } hb_ubytes_t sub_array (unsigned int offset_, unsigned int len_) const { return str.sub_array (offset_, len_); } bool avail (unsigned int count=1) const - { return (!in_error () && offset + count <= str.length); } + { return get_offset () + count <= str.length; } void inc (unsigned int count=1) { - if (likely (!in_error () && (offset <= str.length) && (offset + count <= str.length))) - { - offset += count; - } - else - { - offset = str.length; - set_error (); - } + /* Automatically puts us in error if count is out-of-range. */ + set_offset (get_offset () + count); } - void set_error () { error = true; } - bool in_error () const { return error; } + /* We (ab)use ubytes backwards_length as a cursor (called offset), + * as well as to store error condition. */ - hb_ubytes_t str; - unsigned int offset; /* beginning of the sub-string within str */ + unsigned get_offset () const { return str.backwards_length; } + void set_offset (unsigned offset) { str.backwards_length = offset; } + + void set_error () { str.backwards_length = str.length + 1; } + bool in_error () const { return str.backwards_length > str.length; } + + unsigned total_size () const { return str.length; } protected: - bool error; + hb_ubytes_t str; }; using byte_str_array_t = hb_vector_t; @@ -491,8 +482,15 @@ /* an operator prefixed by its operands in a byte string */ struct op_str_t { - hb_ubytes_t str; - op_code_t op; + /* This used to have a hb_ubytes_t. Using a pointer and length + * in a particular order, saves 8 bytes in this struct and more + * in our parsed_cs_op_t subclass. */ + + const unsigned char *ptr = nullptr; + + op_code_t op = OpCode_Invalid; + + uint8_t length = 0; }; /* base of OP_SERIALIZER */ @@ -503,9 +501,11 @@ { TRACE_SERIALIZE (this); - HBUINT8 *d = c->allocate_size (opstr.str.length); + unsigned char *d = c->allocate_size (opstr.length); if (unlikely (!d)) return_trace (false); - memcpy (d, &opstr.str[0], opstr.str.length); + /* Faster than hb_memcpy for small strings. */ + for (unsigned i = 0; i < opstr.length; i++) + d[i] = opstr.ptr[i]; return_trace (true); } }; @@ -522,23 +522,17 @@ void alloc (unsigned n) { - values.alloc (n); + values.alloc (n, true); } - void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t ()) - { - VAL *val = values.push (); - val->op = op; - val->str = str_ref.str.sub_array (opStart, str_ref.offset - opStart); - opStart = str_ref.offset; - } - - void add_op (op_code_t op, const byte_str_ref_t& str_ref, const VAL &v) + void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t (), const VAL &v = VAL ()) { VAL *val = values.push (v); val->op = op; - val->str = str_ref.sub_array ( opStart, str_ref.offset - opStart); - opStart = str_ref.offset; + auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart); + val->ptr = arr.arrayZ; + val->length = arr.length; + opStart = str_ref.get_offset (); } bool has_op (op_code_t op) const @@ -549,8 +543,7 @@ } unsigned get_count () const { return values.length; } - const VAL &get_value (unsigned int i) const { return values[i]; } - const VAL &operator [] (unsigned int i) const { return get_value (i); } + const VAL &operator [] (unsigned int i) const { return values[i]; } unsigned int opStart; hb_vector_t values; @@ -565,23 +558,23 @@ str_ref.reset (str_); } bool in_error () const - { return error || str_ref.in_error () || argStack.in_error (); } + { return str_ref.in_error () || argStack.in_error (); } - void set_error () { error = true; } + void set_error () { str_ref.set_error (); } op_code_t fetch_op () { op_code_t op = OpCode_Invalid; if (unlikely (!str_ref.avail ())) return OpCode_Invalid; - op = (op_code_t)(unsigned char)str_ref[0]; + op = (op_code_t) str_ref.head_unchecked (); + str_ref.inc (); if (op == OpCode_escape) { if (unlikely (!str_ref.avail ())) return OpCode_Invalid; - op = Make_OpCode_ESC(str_ref[1]); + op = Make_OpCode_ESC (str_ref.head_unchecked ()); str_ref.inc (); } - str_ref.inc (); return op; } @@ -596,8 +589,6 @@ str_ref; arg_stack_t argStack; - protected: - bool error = false; }; using num_interp_env_t = interp_env_t<>; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -881,7 +881,13 @@ { SUPER::env.set_endchar (false); + unsigned max_ops = HB_CFF_MAX_OPS; for (;;) { + if (unlikely (!--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; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -35,10 +35,8 @@ /* an opstr and the parsed out dict value(s) */ struct dict_val_t : op_str_t { - void init () { single_val.set_int (0); } + void init () {} void fini () {} - - number_t single_val; }; typedef dict_val_t num_dict_val_t; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-common.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-common.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-common.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-common.cc 2023-07-05 07:11:54.000000000 +0000 @@ -29,32 +29,6 @@ #include "hb.hh" #include "hb-machinery.hh" -#if !defined(HB_NO_SETLOCALE) && (!defined(HAVE_NEWLOCALE) || !defined(HAVE_USELOCALE)) -#define HB_NO_SETLOCALE 1 -#endif - -#ifndef HB_NO_SETLOCALE - -#include -#ifdef HAVE_XLOCALE_H -#include // Needed on BSD/OS X for uselocale -#endif - -#ifdef WIN32 -#define hb_locale_t _locale_t -#else -#define hb_locale_t locale_t -#endif -#define hb_setlocale setlocale -#define hb_uselocale uselocale - -#else - -#define hb_locale_t void * -#define hb_setlocale(Category, Locale) "C" -#define hb_uselocale(Locale) ((hb_locale_t) 0) - -#endif /** * SECTION:hb-common @@ -99,7 +73,7 @@ } /* This is idempotent and threadsafe. */ - _hb_options.set_relaxed (u.i); + _hb_options = u.i; } @@ -108,7 +82,7 @@ /** * hb_tag_from_string: * @str: (array length=len) (element-type uint8_t): String to convert - * @len: Length of @str, or -1 if it is %NULL-terminated + * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string into an #hb_tag_t. Valid tags * are four characters. Shorter input strings will be @@ -170,7 +144,7 @@ /** * hb_direction_from_string: * @str: (array length=len) (element-type uint8_t): String to convert - * @len: Length of @str, or -1 if it is %NULL-terminated + * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string to an #hb_direction_t. * @@ -285,7 +259,7 @@ lang = (hb_language_t) hb_malloc(len); if (likely (lang)) { - memcpy((unsigned char *) lang, s, len); + hb_memcpy((unsigned char *) lang, s, len); for (unsigned char *p = (unsigned char *) lang; *p; p++) *p = canon_map[*p]; } @@ -357,7 +331,7 @@ * hb_language_from_string: * @str: (array length=len) (element-type uint8_t): a string representing * a BCP 47 language tag - * @len: length of the @str, or -1 if it is %NULL-terminated. + * @len: length of the @str, or -1 if it is `NULL`-terminated. * * Converts @str representing a BCP 47 language tag to the corresponding * #hb_language_t. @@ -379,7 +353,7 @@ /* NUL-terminate it. */ char strbuf[64]; len = hb_min (len, (int) sizeof (strbuf) - 1); - memcpy (strbuf, str, len); + hb_memcpy (strbuf, str, len); strbuf[len] = '\0'; item = lang_find_or_insert (strbuf); } @@ -396,7 +370,7 @@ * Converts an #hb_language_t to a string. * * Return value: (transfer none): - * A %NULL-terminated string representing the @language. Must not be freed by + * A `NULL`-terminated string representing the @language. Must not be freed by * the caller. * * Since: 0.9.2 @@ -441,6 +415,38 @@ return language; } +/** + * hb_language_matches: + * @language: The #hb_language_t to work on + * @specific: Another #hb_language_t + * + * Check whether a second language tag is the same or a more + * specific version of the provided language tag. For example, + * "fa_IR.utf8" is a more specific tag for "fa" or for "fa_IR". + * + * Return value: `true` if languages match, `false` otherwise. + * + * Since: 5.0.0 + **/ +hb_bool_t +hb_language_matches (hb_language_t language, + hb_language_t specific) +{ + if (language == specific) return true; + if (!language || !specific) return false; + + const char *l = language->s; + const char *s = specific->s; + unsigned ll = strlen (l); + unsigned sl = strlen (s); + + if (ll > sl) + return false; + + return strncmp (l, s, ll) == 0 && + (s[ll] == '\0' || s[ll] == '-'); +} + /* hb_script_t */ @@ -498,7 +504,7 @@ * hb_script_from_string: * @str: (array length=len) (element-type uint8_t): a string representing an * ISO 15924 tag. - * @len: length of the @str, or -1 if it is %NULL-terminated. + * @len: length of the @str, or -1 if it is `NULL`-terminated. * * Converts a string @str representing an ISO 15924 script tag to a * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then @@ -693,8 +699,8 @@ * Tests the library version against a minimum value, * as three integer components. * - * Return value: %true if the library is equal to or greater than - * the test value, %false otherwise + * Return value: `true` if the library is equal to or greater than + * the test value, `false` otherwise * * Since: 0.9.30 **/ @@ -881,7 +887,7 @@ /** * hb_feature_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * @feature: (out): the #hb_feature_t to initialize with the parsed values * * Parses a string into a #hb_feature_t. @@ -923,7 +929,7 @@ * * * Return value: - * %true if @str is successfully parsed, %false otherwise + * `true` if @str is successfully parsed, `false` otherwise * * Since: 0.9.5 **/ @@ -944,7 +950,7 @@ } if (feature) - memset (feature, 0, sizeof (*feature)); + hb_memset (feature, 0, sizeof (*feature)); return false; } @@ -954,7 +960,7 @@ * @buf: (array length=size) (out): output string * @size: the allocated size of @buf * - * Converts a #hb_feature_t into a %NULL-terminated string in the format + * Converts a #hb_feature_t into a `NULL`-terminated string in the format * understood by hb_feature_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * @@ -993,7 +999,7 @@ } assert (len < ARRAY_LENGTH (s)); len = hb_min (len, size - 1); - memcpy (buf, s, len); + hb_memcpy (buf, s, len); buf[len] = '\0'; } @@ -1022,7 +1028,7 @@ /** * hb_variation_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * @variation: (out): the #hb_variation_t to initialize with the parsed values * * Parses a string into a #hb_variation_t. @@ -1035,7 +1041,7 @@ * number. For example `wght=500`, or `slnt=-7.5`. * * Return value: - * %true if @str is successfully parsed, %false otherwise + * `true` if @str is successfully parsed, `false` otherwise * * Since: 1.4.2 */ @@ -1056,7 +1062,7 @@ } if (variation) - memset (variation, 0, sizeof (*variation)); + hb_memset (variation, 0, sizeof (*variation)); return false; } @@ -1104,10 +1110,10 @@ /** * hb_variation_to_string: * @variation: an #hb_variation_t to convert - * @buf: (array length=size) (out): output string + * @buf: (array length=size) (out caller-allocates): output string * @size: the allocated size of @buf * - * Converts an #hb_variation_t into a %NULL-terminated string in the format + * Converts an #hb_variation_t into a `NULL`-terminated string in the format * understood by hb_variation_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * @@ -1134,7 +1140,7 @@ assert (len < ARRAY_LENGTH (s)); len = hb_min (len, size - 1); - memcpy (buf, s, len); + hb_memcpy (buf, s, len); buf[len] = '\0'; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-common.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-common.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-common.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-common.h 2023-07-05 07:11:54.000000000 +0000 @@ -326,6 +326,9 @@ HB_EXTERN hb_language_t hb_language_get_default (void); +HB_EXTERN hb_bool_t +hb_language_matches (hb_language_t language, + hb_language_t specific); /** * hb_script_t: @@ -492,6 +495,8 @@ * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0 * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0 * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 + * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 + * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 * @HB_SCRIPT_INVALID: No script set * * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding @@ -713,6 +718,12 @@ */ HB_SCRIPT_MATH = HB_TAG ('Z','m','t','h'), + /* + * Since 5.2.0 + */ + HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ + HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, @@ -886,6 +897,32 @@ hb_color_get_blue (hb_color_t color); #define hb_color_get_blue(color) (((color) >> 24) & 0xFF) +/** + * hb_glyph_extents_t: + * @x_bearing: Distance from the x-origin to the left extremum of the glyph. + * @y_bearing: Distance from the top extremum of the glyph to the y-origin. + * @width: Distance from the left extremum of the glyph to the right extremum. + * @height: Distance from the top extremum of the glyph to the bottom extremum. + * + * Glyph extent values, measured in font units. + * + * Note that @height is negative, in coordinate systems that grow up. + **/ +typedef struct hb_glyph_extents_t { + hb_position_t x_bearing; + hb_position_t y_bearing; + hb_position_t width; + hb_position_t height; +} hb_glyph_extents_t; + +/** + * hb_font_t: + * + * Data type for holding fonts. + * + */ +typedef struct hb_font_t hb_font_t; + HB_END_DECLS #endif /* HB_COMMON_H */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-config.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-config.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-config.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-config.hh 2023-07-05 07:11:54.000000000 +0000 @@ -35,6 +35,11 @@ #include "config.h" #endif +#ifndef HB_EXPERIMENTAL_API +#define HB_NO_BEYOND_64K +#define HB_NO_CUBIC_GLYF +#define HB_NO_VAR_COMPOSITES +#endif #ifdef HB_TINY #define HB_LEAN @@ -68,6 +73,7 @@ #define HB_NO_LANGUAGE_PRIVATE_SUBTAG #define HB_NO_LAYOUT_FEATURE_PARAMS #define HB_NO_LAYOUT_COLLECT_GLYPHS +#define HB_NO_LAYOUT_RARELY_USED #define HB_NO_LAYOUT_UNUSED #define HB_NO_MATH #define HB_NO_META @@ -75,11 +81,13 @@ #define HB_NO_MMAP #define HB_NO_NAME #define HB_NO_OPEN -#define HB_NO_SETLOCALE #define HB_NO_OT_FONT_GLYPH_NAMES #define HB_NO_OT_SHAPE_FRACTIONS +#define HB_NO_PAINT +#define HB_NO_SETLOCALE #define HB_NO_STYLE #define HB_NO_SUBSET_LAYOUT +#define HB_NO_VERTICAL #define HB_NO_VAR #endif @@ -98,12 +106,22 @@ /* Closure of options. */ +#ifdef HB_NO_BORING_EXPANSION +#define HB_NO_BEYOND_64K +#define HB_NO_AVAR2 +#endif + #ifdef HB_DISABLE_DEPRECATED #define HB_IF_NOT_DEPRECATED(x) #else #define HB_IF_NOT_DEPRECATED(x) x #endif +#ifdef HB_NO_SHAPER +#define HB_NO_OT_SHAPE +#define HB_NO_AAT_SHAPE +#endif + #ifdef HB_NO_AAT #define HB_NO_OT_NAME_LANGUAGE_AAT #define HB_NO_AAT_SHAPE @@ -150,6 +168,7 @@ #define HB_NO_OT_SHAPER_HEBREW_FALLBACK #define HB_NO_OT_SHAPER_THAI_FALLBACK #define HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS +#define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI #endif #ifdef NDEBUG diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh 2023-07-05 07:11:54.000000000 +0000 @@ -69,9 +69,9 @@ operator T * () const { return p; } T& operator * () const { return *get (); } T* operator -> () const { return get (); } - operator bool () { return p; } - bool operator == (const shared_ptr &o) { return p == o.p; } - bool operator != (const shared_ptr &o) { return p != o.p; } + operator bool () const { return p; } + bool operator == (const shared_ptr &o) const { return p == o.p; } + bool operator != (const shared_ptr &o) const { return p != o.p; } static T* get_empty() { return v::get_empty (); } T* reference() { return v::reference (p); } @@ -130,7 +130,7 @@ void *, hb_destroy_func_t, hb_bool_t), - void * (*_get_user_data) (T *, + void * (*_get_user_data) (const T *, hb_user_data_key_t *)> struct vtable_t { @@ -160,14 +160,43 @@ HB_DEFINE_VTABLE (set); HB_DEFINE_VTABLE (shape_plan); HB_DEFINE_VTABLE (unicode_funcs); +HB_DEFINE_VTABLE (draw_funcs); +HB_DEFINE_VTABLE (paint_funcs); + +#undef HB_DEFINE_VTABLE + + +#ifdef HB_SUBSET_H + +#define HB_DEFINE_VTABLE(name) \ + template<> \ + struct vtable \ + : vtable_t {} + + +HB_DEFINE_VTABLE (subset_input); +HB_DEFINE_VTABLE (subset_plan); #undef HB_DEFINE_VTABLE +#endif + } // namespace hb +/* Workaround for GCC < 7, see: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480 + * https://stackoverflow.com/a/25594741 */ +namespace std { + + template -struct std::hash> +struct hash> { std::size_t operator()(const hb::shared_ptr& v) const noexcept { @@ -177,7 +206,7 @@ }; template -struct std::hash> +struct hash> { std::size_t operator()(const hb::unique_ptr& v) const noexcept { @@ -187,6 +216,8 @@ }; +} // namespace std + #endif /* __cplusplus */ #endif /* HB_CPLUSPLUS_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-debug.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-debug.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-debug.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-debug.hh 2023-07-05 07:11:54.000000000 +0000 @@ -67,12 +67,12 @@ #endif /* Make a local copy, so we can access bitfield threadsafely. */ hb_options_union_t u; - u.i = _hb_options.get_relaxed (); + u.i = _hb_options; if (unlikely (!u.i)) { _hb_options_init (); - u.i = _hb_options.get_relaxed (); + u.i = _hb_options; } return u.opts; @@ -113,7 +113,7 @@ const char *paren = strchr (func, '('); if (paren) func_len = paren - func; - fprintf (stderr, "%.*s", func_len, func); + fprintf (stderr, "%.*s", (int) func_len, func); } } @@ -142,9 +142,9 @@ fprintf (stderr, "%-10s", what ? what : ""); if (obj) - fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj); + fprintf (stderr, "(%*p) ", (int) (2 * sizeof (void *)), obj); else - fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), ""); + fprintf (stderr, " %*s ", (int) (2 * sizeof (void *)), ""); if (indented) { #define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ @@ -306,7 +306,7 @@ } _hb_debug_msg (what, obj, func, true, plevel ? *plevel : 1, -1, - "return %s (line %d)", + "return %s (line %u)", hb_printer_t>().print (v), line); if (plevel) --*plevel; plevel = nullptr; @@ -396,7 +396,7 @@ #define TRACE_APPLY(this) \ hb_auto_trace_t trace \ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "idx %d gid %u lookup %d", \ + "idx %u gid %u lookup %d", \ c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index) #else #define TRACE_APPLY(this) hb_no_trace_t trace @@ -454,10 +454,15 @@ #define TRACE_DISPATCH(this, format) \ hb_auto_trace_t trace \ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "format %d", (int) format) + "format %u", (unsigned) format) #else #define TRACE_DISPATCH(this, format) hb_no_trace_t trace #endif +#ifndef HB_BUFFER_MESSAGE_MORE +#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1) +#endif + + #endif /* HB_DEBUG_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h 2023-07-05 07:11:54.000000000 +0000 @@ -93,7 +93,7 @@ * This method should retrieve the glyph ID for a specified Unicode code point * font, with an optional variation selector. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * Deprecated: 1.2.3 * **/ @@ -102,7 +102,8 @@ hb_codepoint_t *glyph, void *user_data); -HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func and hb_font_funcs_set_variation_glyph_func) void +HB_DEPRECATED_FOR (hb_font_funcs_set_nominal_glyph_func and hb_font_funcs_set_variation_glyph_func) +HB_EXTERN void hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_func_t func, void *user_data, hb_destroy_func_t destroy); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-draw.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-draw.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-draw.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-draw.cc 2023-07-05 07:11:54.000000000 +0000 @@ -35,6 +35,8 @@ * @include: hb.h * * Functions for drawing (extracting) glyph shapes. + * + * The #hb_draw_funcs_t struct can be used with hb_font_draw_glyph(). **/ static void @@ -80,6 +82,56 @@ void *user_data HB_UNUSED) {} +static bool +_hb_draw_funcs_set_preamble (hb_draw_funcs_t *dfuncs, + bool func_is_null, + void **user_data, + hb_destroy_func_t *destroy) +{ + if (hb_object_is_immutable (dfuncs)) + { + if (*destroy) + (*destroy) (*user_data); + return false; + } + + if (func_is_null) + { + if (*destroy) + (*destroy) (*user_data); + *destroy = nullptr; + *user_data = nullptr; + } + + return true; +} + +static bool +_hb_draw_funcs_set_middle (hb_draw_funcs_t *dfuncs, + void *user_data, + hb_destroy_func_t destroy) +{ + if (user_data && !dfuncs->user_data) + { + dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); + if (unlikely (!dfuncs->user_data)) + goto fail; + } + if (destroy && !dfuncs->destroy) + { + dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); + if (unlikely (!dfuncs->destroy)) + goto fail; + } + + return true; + +fail: + if (destroy) + (destroy) (user_data); + return false; +} + #define HB_DRAW_FUNC_IMPLEMENT(name) \ \ void \ @@ -88,42 +140,24 @@ void *user_data, \ hb_destroy_func_t destroy) \ { \ - if (hb_object_is_immutable (dfuncs)) \ - return; \ + if (!_hb_draw_funcs_set_preamble (dfuncs, !func, &user_data, &destroy))\ + return; \ \ if (dfuncs->destroy && dfuncs->destroy->name) \ dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \ \ - if (user_data && !dfuncs->user_data) \ - { \ - dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \ - if (unlikely (!dfuncs->user_data)) \ - goto fail; \ - } \ - if (destroy && !dfuncs->destroy) \ - { \ - dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \ - if (unlikely (!dfuncs->destroy)) \ - goto fail; \ - } \ + if (!_hb_draw_funcs_set_middle (dfuncs, user_data, destroy)) \ + return; \ \ - if (func) { \ + if (func) \ dfuncs->func.name = func; \ - if (dfuncs->user_data) \ - dfuncs->user_data->name = user_data; \ - if (dfuncs->destroy) \ - dfuncs->destroy->name = destroy; \ - } else { \ + else \ dfuncs->func.name = hb_draw_##name##_nil; \ - if (dfuncs->user_data) \ - dfuncs->user_data->name = nullptr; \ - if (dfuncs->destroy) \ - dfuncs->destroy->name = nullptr; \ - } \ - \ -fail: \ - if (destroy) \ - destroy (user_data); \ + \ + if (dfuncs->user_data) \ + dfuncs->user_data->name = user_data; \ + if (dfuncs->destroy) \ + dfuncs->destroy->name = destroy; \ } HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS @@ -137,7 +171,7 @@ * Return value: (transfer full): * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial * reference count should be released with hb_draw_funcs_destroy when you are - * done using the #hb_draw_funcs_t. This function never returns %NULL. If + * done using the #hb_draw_funcs_t. This function never returns `NULL`. If * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will * be returned. * @@ -166,13 +200,29 @@ } }; +/** + * hb_draw_funcs_get_empty: + * + * Fetches the singleton empty draw-functions structure. + * + * Return value: (transfer full): The empty draw-functions structure + * + * Since: 7.0.0 + **/ +hb_draw_funcs_t * +hb_draw_funcs_get_empty () +{ + return const_cast (&Null (hb_draw_funcs_t)); +} /** * hb_draw_funcs_reference: (skip) * @dfuncs: draw functions * - * Increases the reference count on @dfuncs by one. This prevents @buffer from - * being destroyed until a matching call to hb_draw_funcs_destroy() is made. + * Increases the reference count on @dfuncs by one. + * + * This prevents @dfuncs from being destroyed until a matching + * call to hb_draw_funcs_destroy() is made. * * Return value: (transfer full): * The referenced #hb_draw_funcs_t. @@ -208,10 +258,56 @@ #undef HB_DRAW_FUNC_IMPLEMENT } + hb_free (dfuncs->destroy); + hb_free (dfuncs->user_data); + hb_free (dfuncs); } /** + * hb_draw_funcs_set_user_data: (skip) + * @dfuncs: The draw-functions structure + * @key: The user-data key + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the specified draw-functions structure. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 7.0.0 + **/ +hb_bool_t +hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (dfuncs, key, data, destroy, replace); +} + +/** + * hb_draw_funcs_get_user_data: (skip) + * @dfuncs: The draw-functions structure + * @key: The user-data key to query + * + * Fetches the user-data associated with the specified key, + * attached to the specified draw-functions structure. + * + * Return value: (transfer none): A pointer to the user data + * + * Since: 7.0.0 + **/ +void * +hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (dfuncs, key); +} + +/** * hb_draw_funcs_make_immutable: * @dfuncs: draw functions * @@ -234,7 +330,7 @@ * * Checks whether @dfuncs is immutable. * - * Return value: %true if @dfuncs is immutable, %false otherwise + * Return value: `true` if @dfuncs is immutable, `false` otherwise * * Since: 4.0.0 **/ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-draw.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-draw.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-draw.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-draw.h 2023-07-05 07:11:54.000000000 +0000 @@ -92,11 +92,11 @@ /** * hb_draw_move_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @to_x: X component of target point * @to_y: Y component of target point - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_draw_funcs_set_move_to_func() * * A virtual method for the #hb_draw_funcs_t to perform a "move-to" draw * operation. @@ -112,11 +112,11 @@ /** * hb_draw_line_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @to_x: X component of target point * @to_y: Y component of target point - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_draw_funcs_set_line_to_func() * * A virtual method for the #hb_draw_funcs_t to perform a "line-to" draw * operation. @@ -132,13 +132,13 @@ /** * hb_draw_quadratic_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @control_x: X component of control point * @control_y: Y component of control point * @to_x: X component of target point * @to_y: Y component of target point - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_draw_funcs_set_quadratic_to_func() * * A virtual method for the #hb_draw_funcs_t to perform a "quadratic-to" draw * operation. @@ -155,7 +155,7 @@ /** * hb_draw_cubic_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @control1_x: X component of first control point * @control1_y: Y component of first control point @@ -163,7 +163,7 @@ * @control2_y: Y component of second control point * @to_x: X component of target point * @to_y: Y component of target point - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_draw_funcs_set_cubic_to_func() * * A virtual method for the #hb_draw_funcs_t to perform a "cubic-to" draw * operation. @@ -181,9 +181,9 @@ /** * hb_draw_close_path_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_draw_funcs_set_close_path_func() * * A virtual method for the #hb_draw_funcs_t to perform a "close-path" draw * operation. @@ -280,11 +280,26 @@ hb_draw_funcs_create (void); HB_EXTERN hb_draw_funcs_t * +hb_draw_funcs_get_empty (void); + +HB_EXTERN hb_draw_funcs_t * hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs); HB_EXTERN void hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs); +HB_EXTERN hb_bool_t +hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace); + + +HB_EXTERN void * +hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key); + HB_EXTERN void hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,246 @@ +/* + * Copyright © 2009 Red Hat, Inc. + * Copyright © 2012 Google, 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-face.hh" + +#include "hb-map.hh" +#include "hb-open-file.hh" +#include "hb-serialize.hh" + + +/* + * face-builder: A face that has add_table(). + */ + +struct face_table_info_t +{ + hb_blob_t* data; + signed order; +}; + +struct hb_face_builder_data_t +{ + hb_hashmap_t tables; +}; + +static int compare_entries (const void* pa, const void* pb) +{ + const auto& a = * (const hb_pair_t *) pa; + const auto& b = * (const hb_pair_t *) pb; + + /* Order by blob size first (smallest to largest) and then table tag */ + + if (a.second.order != b.second.order) + return a.second.order < b.second.order ? -1 : +1; + + if (a.second.data->length != b.second.data->length) + return a.second.data->length < b.second.data->length ? -1 : +1; + + return a.first < b.first ? -1 : a.first == b.first ? 0 : +1; +} + +static hb_face_builder_data_t * +_hb_face_builder_data_create () +{ + hb_face_builder_data_t *data = (hb_face_builder_data_t *) hb_calloc (1, sizeof (hb_face_builder_data_t)); + if (unlikely (!data)) + return nullptr; + + data->tables.init (); + + return data; +} + +static void +_hb_face_builder_data_destroy (void *user_data) +{ + hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; + + for (auto info : data->tables.values()) + hb_blob_destroy (info.data); + + data->tables.fini (); + + hb_free (data); +} + +static hb_blob_t * +_hb_face_builder_data_reference_blob (hb_face_builder_data_t *data) +{ + + unsigned int table_count = data->tables.get_population (); + unsigned int face_length = table_count * 16 + 12; + + for (auto info : data->tables.values()) + face_length += hb_ceil_to_4 (hb_blob_get_length (info.data)); + + char *buf = (char *) hb_malloc (face_length); + if (unlikely (!buf)) + return nullptr; + + hb_serialize_context_t c (buf, face_length); + c.propagate_error (data->tables); + OT::OpenTypeFontFile *f = c.start_serialize (); + + bool is_cff = (data->tables.has (HB_TAG ('C','F','F',' ')) + || data->tables.has (HB_TAG ('C','F','F','2'))); + hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag; + + // Sort the tags so that produced face is deterministic. + hb_vector_t> sorted_entries; + data->tables.iter () | hb_sink (sorted_entries); + if (unlikely (sorted_entries.in_error ())) + { + hb_free (buf); + return nullptr; + } + + sorted_entries.qsort (compare_entries); + + bool ret = f->serialize_single (&c, + sfnt_tag, + + sorted_entries.iter() + | hb_map ([&] (hb_pair_t _) { + return hb_pair_t (_.first, _.second.data); + })); + + c.end_serialize (); + + if (unlikely (!ret)) + { + hb_free (buf); + return nullptr; + } + + return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, hb_free); +} + +static hb_blob_t * +_hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +{ + hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; + + if (!tag) + return _hb_face_builder_data_reference_blob (data); + + return hb_blob_reference (data->tables[tag].data); +} + + +/** + * hb_face_builder_create: + * + * Creates a #hb_face_t that can be used with hb_face_builder_add_table(). + * After tables are added to the face, it can be compiled to a binary + * font file by calling hb_face_reference_blob(). + * + * Return value: (transfer full): New face. + * + * Since: 1.9.0 + **/ +hb_face_t * +hb_face_builder_create () +{ + hb_face_builder_data_t *data = _hb_face_builder_data_create (); + if (unlikely (!data)) return hb_face_get_empty (); + + return hb_face_create_for_tables (_hb_face_builder_reference_table, + data, + _hb_face_builder_data_destroy); +} + +/** + * hb_face_builder_add_table: + * @face: A face object created with hb_face_builder_create() + * @tag: The #hb_tag_t of the table to add + * @blob: The blob containing the table data to add + * + * Add table for @tag with data provided by @blob to the face. @face must + * be created using hb_face_builder_create(). + * + * Since: 1.9.0 + **/ +hb_bool_t +hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) +{ + if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy)) + return false; + + if (tag == HB_MAP_VALUE_INVALID) + return false; + + hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; + + hb_blob_t* previous = data->tables.get (tag).data; + if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1})) + { + hb_blob_destroy (blob); + return false; + } + + hb_blob_destroy (previous); + return true; +} + +/** + * hb_face_builder_sort_tables: + * @face: A face object created with hb_face_builder_create() + * @tags: (array zero-terminated=1): ordered list of table tags terminated by + * %HB_TAG_NONE + * + * Set the ordering of tables for serialization. Any tables not + * specified in the tags list will be ordered after the tables in + * tags, ordered by the default sort ordering. + * + * Since: 5.3.0 + **/ +void +hb_face_builder_sort_tables (hb_face_t *face, + const hb_tag_t *tags) +{ + if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy)) + return; + + hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; + + // Sort all unspecified tables after any specified tables. + for (auto& info : data->tables.values_ref()) + info.order = (unsigned) -1; + + signed order = 0; + for (const hb_tag_t* tag = tags; + *tag; + tag++) + { + face_table_info_t* info; + if (!data->tables.has (*tag, &info)) continue; + info->order = order++; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face.cc 2023-07-05 07:11:54.000000000 +0000 @@ -33,7 +33,6 @@ #include "hb-open-file.hh" #include "hb-ot-face.hh" #include "hb-ot-cmap-table.hh" -#include "hb-map.hh" /** @@ -132,7 +131,7 @@ face->user_data = user_data; face->destroy = destroy; - face->num_glyphs.set_relaxed (-1); + face->num_glyphs = -1; face->data.init0 (face); face->table.init0 (face); @@ -288,6 +287,7 @@ { if (!hb_object_destroy (face)) return; +#ifndef HB_NO_SHAPER for (hb_face_t::plan_node_t *node = face->shape_plans; node; ) { hb_face_t::plan_node_t *next = node->next; @@ -295,6 +295,7 @@ hb_free (node); node = next; } +#endif face->data.fini (); face->table.fini (); @@ -315,7 +316,7 @@ * * Attaches a user-data key/data pair to the given face object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -342,7 +343,7 @@ * Since: 0.9.2 **/ void * -hb_face_get_user_data (hb_face_t *face, +hb_face_get_user_data (const hb_face_t *face, hb_user_data_key_t *key) { return hb_object_get_user_data (face, key); @@ -371,7 +372,7 @@ * * Tests whether the given face object is immutable. * - * Return value: %true is @face is immutable, %false otherwise + * Return value: `true` is @face is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -470,6 +471,8 @@ * * Sets the units-per-em (upem) for a face object to the specified value. * + * This API is used in rare circumstances. + * * Since: 0.9.2 **/ void @@ -479,14 +482,17 @@ if (hb_object_is_immutable (face)) return; - face->upem.set_relaxed (upem); + face->upem = upem; } /** * hb_face_get_upem: * @face: A face object * - * Fetches the units-per-em (upem) value of the specified face object. + * Fetches the units-per-em (UPEM) value of the specified face object. + * + * Typical UPEM values for fonts are 1000, or 2048, but any value + * in between 16 and 16,384 is allowed for OpenType fonts. * * Return value: The upem value of @face * @@ -505,6 +511,8 @@ * * Sets the glyph count for a face object to the specified value. * + * This API is used in rare circumstances. + * * Since: 0.9.7 **/ void @@ -514,7 +522,7 @@ if (hb_object_is_immutable (face)) return; - face->num_glyphs.set_relaxed (glyph_count); + face->num_glyphs = glyph_count; } /** @@ -579,7 +587,7 @@ /** * hb_face_collect_unicodes: * @face: A face object - * @out: The set to add Unicode characters to + * @out: (out): The set to add Unicode characters to * * Collects all of the Unicode characters covered by @face and adds * them to the #hb_set_t set @out. @@ -593,9 +601,30 @@ face->table.cmap->collect_unicodes (out, face->get_num_glyphs ()); } /** + * hb_face_collect_nominal_glyph_mapping: + * @face: A face object + * @mapping: (out): The map to add Unicode-to-glyph mapping to + * @unicodes: (nullable) (out): The set to add Unicode characters to, or `NULL` + * + * Collects the mapping from Unicode characters to nominal glyphs of the @face, + * and optionally all of the Unicode characters covered by @face. + * + * Since: 7.0.0 + */ +void +hb_face_collect_nominal_glyph_mapping (hb_face_t *face, + hb_map_t *mapping, + hb_set_t *unicodes) +{ + hb_set_t stack_unicodes; + if (!unicodes) + unicodes = &stack_unicodes; + face->table.cmap->collect_mapping (unicodes, mapping, face->get_num_glyphs ()); +} +/** * hb_face_collect_variation_selectors: * @face: A face object - * @out: The set to add Variation Selector characters to + * @out: (out): The set to add Variation Selector characters to * * Collects all Unicode "Variation Selector" characters covered by @face and adds * them to the #hb_set_t set @out. @@ -612,7 +641,7 @@ * hb_face_collect_variation_unicodes: * @face: A face object * @variation_selector: The Variation Selector to query - * @out: The set to add Unicode characters to + * @out: (out): The set to add Unicode characters to * * Collects all Unicode characters for @variation_selector covered by @face and adds * them to the #hb_set_t set @out. @@ -627,163 +656,3 @@ face->table.cmap->collect_variation_unicodes (variation_selector, out); } #endif - - -/* - * face-builder: A face that has add_table(). - */ - -struct hb_face_builder_data_t -{ - hb_hashmap_t tables; -}; - -static int compare_entries (const void* pa, const void* pb) -{ - const auto& a = * (const hb_pair_t *) pa; - const auto& b = * (const hb_pair_t *) pb; - - /* Order by blob size first (smallest to largest) and then table tag */ - - if (a.second->length != b.second->length) - return a.second->length < b.second->length ? -1 : +1; - - return a.first < b.first ? -1 : a.first == b.first ? 0 : +1; -} - -static hb_face_builder_data_t * -_hb_face_builder_data_create () -{ - hb_face_builder_data_t *data = (hb_face_builder_data_t *) hb_calloc (1, sizeof (hb_face_builder_data_t)); - if (unlikely (!data)) - return nullptr; - - data->tables.init (); - - return data; -} - -static void -_hb_face_builder_data_destroy (void *user_data) -{ - hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; - - for (hb_blob_t* b : data->tables.values()) - hb_blob_destroy (b); - - data->tables.fini (); - - hb_free (data); -} - -static hb_blob_t * -_hb_face_builder_data_reference_blob (hb_face_builder_data_t *data) -{ - - unsigned int table_count = data->tables.get_population (); - unsigned int face_length = table_count * 16 + 12; - - for (hb_blob_t* b : data->tables.values()) - face_length += hb_ceil_to_4 (hb_blob_get_length (b)); - - char *buf = (char *) hb_malloc (face_length); - if (unlikely (!buf)) - return nullptr; - - hb_serialize_context_t c (buf, face_length); - c.propagate_error (data->tables); - OT::OpenTypeFontFile *f = c.start_serialize (); - - bool is_cff = (data->tables.has (HB_TAG ('C','F','F',' ')) - || data->tables.has (HB_TAG ('C','F','F','2'))); - hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag; - - // Sort the tags so that produced face is deterministic. - hb_vector_t> sorted_entries; - data->tables.iter () | hb_sink (sorted_entries); - if (unlikely (sorted_entries.in_error ())) - { - hb_free (buf); - return nullptr; - } - - sorted_entries.qsort (compare_entries); - bool ret = f->serialize_single (&c, sfnt_tag, + sorted_entries.iter()); - - c.end_serialize (); - - if (unlikely (!ret)) - { - hb_free (buf); - return nullptr; - } - - return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, hb_free); -} - -static hb_blob_t * -_hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) -{ - hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; - - if (!tag) - return _hb_face_builder_data_reference_blob (data); - - return hb_blob_reference (data->tables[tag]); -} - - -/** - * hb_face_builder_create: - * - * Creates a #hb_face_t that can be used with hb_face_builder_add_table(). - * After tables are added to the face, it can be compiled to a binary - * font file by calling hb_face_reference_blob(). - * - * Return value: (transfer full): New face. - * - * Since: 1.9.0 - **/ -hb_face_t * -hb_face_builder_create () -{ - hb_face_builder_data_t *data = _hb_face_builder_data_create (); - if (unlikely (!data)) return hb_face_get_empty (); - - return hb_face_create_for_tables (_hb_face_builder_reference_table, - data, - _hb_face_builder_data_destroy); -} - -/** - * hb_face_builder_add_table: - * @face: A face object created with hb_face_builder_create() - * @tag: The #hb_tag_t of the table to add - * @blob: The blob containing the table data to add - * - * Add table for @tag with data provided by @blob to the face. @face must - * be created using hb_face_builder_create(). - * - * Since: 1.9.0 - **/ -hb_bool_t -hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) -{ - if (tag == HB_MAP_VALUE_INVALID) - return false; - - if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy)) - return false; - - hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; - - hb_blob_t* previous = data->tables.get (tag); - if (!data->tables.set (tag, hb_blob_reference (blob))) - { - hb_blob_destroy (blob); - return false; - } - - hb_blob_destroy (previous); - return true; -} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face.h 2023-07-05 07:11:54.000000000 +0000 @@ -33,6 +33,7 @@ #include "hb-common.h" #include "hb-blob.h" +#include "hb-map.h" #include "hb-set.h" HB_BEGIN_DECLS @@ -96,7 +97,7 @@ hb_bool_t replace); HB_EXTERN void * -hb_face_get_user_data (hb_face_t *face, +hb_face_get_user_data (const hb_face_t *face, hb_user_data_key_t *key); HB_EXTERN void @@ -150,6 +151,11 @@ hb_set_t *out); HB_EXTERN void +hb_face_collect_nominal_glyph_mapping (hb_face_t *face, + hb_map_t *mapping, + hb_set_t *unicodes); + +HB_EXTERN void hb_face_collect_variation_selectors (hb_face_t *face, hb_set_t *out); @@ -171,6 +177,10 @@ hb_tag_t tag, hb_blob_t *blob); +HB_EXTERN void +hb_face_builder_sort_tables (hb_face_t *face, + const hb_tag_t *tags); + HB_END_DECLS diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-face.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-face.hh 2023-07-05 07:11:54.000000000 +0000 @@ -65,7 +65,9 @@ hb_shape_plan_t *shape_plan; plan_node_t *next; }; +#ifndef HB_NO_SHAPER hb_atomic_ptr_t shape_plans; +#endif hb_blob_t *reference_table (hb_tag_t tag) const { @@ -83,7 +85,7 @@ unsigned int get_upem () const { - unsigned int ret = upem.get_relaxed (); + unsigned int ret = upem; if (unlikely (!ret)) { return load_upem (); @@ -93,7 +95,7 @@ unsigned int get_num_glyphs () const { - unsigned int ret = num_glyphs.get_relaxed (); + unsigned int ret = num_glyphs; if (unlikely (ret == UINT_MAX)) return load_num_glyphs (); return ret; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-fallback-shape.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-fallback-shape.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-fallback-shape.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-fallback-shape.cc 2023-07-05 07:11:54.000000000 +0000 @@ -75,16 +75,6 @@ const hb_feature_t *features HB_UNUSED, unsigned int num_features HB_UNUSED) { - /* TODO - * - * - Apply fallback kern. - * - Handle Variation Selectors? - * - Apply normalization? - * - * This will make the fallback shaper into a dumb "TrueType" - * shaper which many people unfortunately still request. - */ - hb_codepoint_t space; bool has_space = (bool) font->get_nominal_glyph (' ', &space); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-font.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-font.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-font.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-font.cc 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ #include "hb-font.hh" #include "hb-draw.hh" +#include "hb-paint.hh" #include "hb-machinery.hh" #include "hb-ot.h" @@ -71,7 +72,7 @@ hb_font_extents_t *extents, void *user_data HB_UNUSED) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return false; } @@ -96,7 +97,7 @@ hb_font_extents_t *extents, void *user_data HB_UNUSED) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return false; } @@ -409,7 +410,7 @@ hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return false; } @@ -503,22 +504,34 @@ } static void -hb_font_get_glyph_shape_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, - void *draw_data, - void *user_data HB_UNUSED) +hb_font_draw_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data HB_UNUSED) { } +static void +hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_paint_funcs_t *paint_funcs HB_UNUSED, + void *paint_data HB_UNUSED, + unsigned int palette HB_UNUSED, + hb_color_t foreground HB_UNUSED, + void *user_data HB_UNUSED) +{ +} -typedef struct hb_font_get_glyph_shape_default_adaptor_t { +typedef struct hb_font_draw_glyph_default_adaptor_t { hb_draw_funcs_t *draw_funcs; void *draw_data; float x_scale; float y_scale; -} hb_font_get_glyph_shape_default_adaptor_t; + float slant; +} hb_font_draw_glyph_default_adaptor_t; static void hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, @@ -527,12 +540,13 @@ float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st, - x_scale * to_x, y_scale * to_y); + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -541,15 +555,16 @@ float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; - st->current_x *= x_scale; - st->current_y *= y_scale; + st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st, - x_scale * to_x, y_scale * to_y); + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -559,16 +574,17 @@ float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; - st->current_x *= x_scale; - st->current_y *= y_scale; + st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st, - x_scale * control_x, y_scale * control_y, - x_scale * to_x, y_scale * to_y); + x_scale * control_x + slant * control_y, y_scale * control_y, + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -579,17 +595,18 @@ float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; - st->current_x *= x_scale; - st->current_y *= y_scale; + st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st, - x_scale * control1_x, y_scale * control1_y, - x_scale * control2_x, y_scale * control2_y, - x_scale * to_x, y_scale * to_y); + x_scale * control1_x + slant * control1_y, y_scale * control1_y, + x_scale * control2_x + slant * control2_y, y_scale * control2_y, + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -597,7 +614,7 @@ hb_draw_state_t *st, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st); } @@ -613,25 +630,50 @@ }; static void -hb_font_get_glyph_shape_default (hb_font_t *font, +hb_font_draw_glyph_default (hb_font_t *font, void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t adaptor = { + hb_font_draw_glyph_default_adaptor_t adaptor = { draw_funcs, draw_data, - (float) font->x_scale / (float) font->parent->x_scale, - (float) font->y_scale / (float) font->parent->y_scale + font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, + font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, + font->parent->y_scale ? (font->slant - font->parent->slant) * + (float) font->x_scale / (float) font->parent->y_scale : 0.f }; - font->parent->get_glyph_shape (glyph, + font->parent->draw_glyph (glyph, const_cast (&_hb_draw_funcs_default), &adaptor); } +static void +hb_font_paint_glyph_default (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, + void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) +{ + paint_funcs->push_transform (paint_data, + font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, + font->parent->y_scale ? (font->slant - font->parent->slant) * + (float) font->x_scale / (float) font->parent->y_scale : 0.f, + 0.f, + font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, + 0.f, 0.f); + + font->parent->paint_glyph (glyph, paint_funcs, paint_data, palette, foreground); + + paint_funcs->pop_transform (paint_data); +} + DEFINE_NULL_INSTANCE (hb_font_funcs_t) = { HB_OBJECT_HEADER_STATIC, @@ -640,7 +682,7 @@ nullptr, { { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_nil, HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } @@ -654,7 +696,7 @@ nullptr, { { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default, +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_default, HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } @@ -732,7 +774,7 @@ if (ffuncs->destroy) { -#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy->name) \ +#define HB_FONT_FUNC_IMPLEMENT(get_,name) if (ffuncs->destroy->name) \ ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT @@ -754,7 +796,7 @@ * * Attaches a user-data key/data pair to the specified font-functions structure. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -781,8 +823,8 @@ * Since: 0.9.2 **/ void * -hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, - hb_user_data_key_t *key) +hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs, + hb_user_data_key_t *key) { return hb_object_get_user_data (ffuncs, key); } @@ -811,7 +853,7 @@ * * Tests whether a font-functions structure is immutable. * - * Return value: %true if @ffuncs is immutable, %false otherwise + * Return value: `true` if @ffuncs is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -822,59 +864,82 @@ } -#define HB_FONT_FUNC_IMPLEMENT(name) \ +static bool +_hb_font_funcs_set_preamble (hb_font_funcs_t *ffuncs, + bool func_is_null, + void **user_data, + hb_destroy_func_t *destroy) +{ + if (hb_object_is_immutable (ffuncs)) + { + if (*destroy) + (*destroy) (*user_data); + return false; + } + + if (func_is_null) + { + if (*destroy) + (*destroy) (*user_data); + *destroy = nullptr; + *user_data = nullptr; + } + + return true; +} + +static bool +_hb_font_funcs_set_middle (hb_font_funcs_t *ffuncs, + void *user_data, + hb_destroy_func_t destroy) +{ + if (user_data && !ffuncs->user_data) + { + ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); + if (unlikely (!ffuncs->user_data)) + goto fail; + } + if (destroy && !ffuncs->destroy) + { + ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); + if (unlikely (!ffuncs->destroy)) + goto fail; + } + + return true; + +fail: + if (destroy) + (destroy) (user_data); + return false; +} + +#define HB_FONT_FUNC_IMPLEMENT(get_,name) \ \ void \ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ - hb_font_get_##name##_func_t func, \ + hb_font_##get_##name##_func_t func, \ void *user_data, \ hb_destroy_func_t destroy) \ { \ - if (hb_object_is_immutable (ffuncs)) \ - goto fail; \ - \ - if (!func) \ - { \ - if (destroy) \ - destroy (user_data); \ - destroy = nullptr; \ - user_data = nullptr; \ - } \ + if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\ + return; \ \ if (ffuncs->destroy && ffuncs->destroy->name) \ ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \ \ - if (user_data && !ffuncs->user_data) \ - { \ - ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); \ - if (unlikely (!ffuncs->user_data)) \ - goto fail; \ - } \ - if (destroy && !ffuncs->destroy) \ - { \ - ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); \ - if (unlikely (!ffuncs->destroy)) \ - goto fail; \ - } \ + if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy)) \ + return; \ \ - if (func) { \ + if (func) \ ffuncs->get.f.name = func; \ - if (ffuncs->user_data) \ - ffuncs->user_data->name = user_data; \ - if (ffuncs->destroy) \ - ffuncs->destroy->name = destroy; \ - } else { \ - ffuncs->get.f.name = hb_font_get_##name##_default; \ - if (ffuncs->user_data) \ - ffuncs->user_data->name = nullptr; \ - if (ffuncs->destroy) \ - ffuncs->destroy->name = nullptr; \ - } \ - return; \ + else \ + ffuncs->get.f.name = hb_font_##get_##name##_default; \ \ -fail: \ - if (destroy) \ - destroy (user_data); \ + if (ffuncs->user_data) \ + ffuncs->user_data->name = user_data; \ + if (ffuncs->destroy) \ + ffuncs->destroy->name = destroy; \ } HB_FONT_FUNCS_IMPLEMENT_CALLBACKS @@ -903,7 +968,7 @@ * Fetches the extents for a specified font, for horizontal * text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.1.3 **/ @@ -922,7 +987,7 @@ * Fetches the extents for a specified font, for vertical * text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.1.3 **/ @@ -946,7 +1011,7 @@ * If @variation_selector is 0, calls hb_font_get_nominal_glyph(); * otherwise calls hb_font_get_variation_glyph(). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -974,7 +1039,7 @@ * for code points modified by variation selectors. For variation-selector * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph(). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.2.3 **/ @@ -996,7 +1061,8 @@ * @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. + * IDs must be returned in a #hb_codepoint_t output parameter. Stopes at the + * first unsupported glyph ID. * * Return value: the number of code points processed * @@ -1026,7 +1092,7 @@ * by the specified variation-selector code point, in the specified * font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.2.3 **/ @@ -1136,7 +1202,7 @@ * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for horizontal text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1159,7 +1225,7 @@ * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for vertical text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1232,7 +1298,7 @@ * Fetches the #hb_glyph_extents_t data for a glyph ID * in the specified font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1255,7 +1321,7 @@ * Fetches the (x,y) coordinates of a specified contour-point index * in the specified glyph, within the specified font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1278,7 +1344,10 @@ * * Fetches the glyph-name string for a glyph ID in the specified @font. * - * Return value: %true if data found, %false otherwise + * According to the OpenType specification, glyph names are limited to 63 + * characters and can only contain (a subset of) ASCII. + * + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1302,7 +1371,7 @@ * * Note: @len == -1 means the name string is null-terminated. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1323,17 +1392,71 @@ * @draw_data: User data to pass to draw callbacks * * Fetches the glyph shape that corresponds to a glyph in the specified @font. - * The shape is returned by way of calls to the callsbacks of the @dfuncs + * The shape is returned by way of calls to the callbacks of the @dfuncs * objects, with @draw_data passed to them. * * Since: 4.0.0 - **/ + * Deprecated: 7.0.0: Use hb_font_draw_glyph() instead + */ void hb_font_get_glyph_shape (hb_font_t *font, hb_codepoint_t glyph, hb_draw_funcs_t *dfuncs, void *draw_data) { - font->get_glyph_shape (glyph, dfuncs, draw_data); + hb_font_draw_glyph (font, glyph, dfuncs, draw_data); +} + +/** + * hb_font_draw_glyph: + * @font: #hb_font_t to work upon + * @glyph: : The glyph ID + * @dfuncs: #hb_draw_funcs_t to draw to + * @draw_data: User data to pass to draw callbacks + * + * Draws the outline that corresponds to a glyph in the specified @font. + * + * The outline is returned by way of calls to the callbacks of the @dfuncs + * objects, with @draw_data passed to them. + * + * Since: 7.0.0 + **/ +void +hb_font_draw_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + font->draw_glyph (glyph, dfuncs, draw_data); +} + +/** + * hb_font_paint_glyph: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID + * @pfuncs: #hb_paint_funcs_t to paint with + * @paint_data: User data to pass to paint callbacks + * @palette_index: The index of the font's color palette to use + * @foreground: The foreground color, unpremultipled + * + * Paints the glyph. + * + * The painting instructions are returned by way of calls to + * the callbacks of the @funcs object, with @paint_data passed + * to them. + * + * If the font has color palettes (see hb_ot_color_has_palettes()), + * then @palette_index selects the palette to use. If the font only + * has one palette, this will be 0. + * + * Since: 7.0.0 + */ +void +hb_font_paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground) +{ + font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground); } /* A bit higher-level, and with fallback */ @@ -1537,7 +1660,7 @@ * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1566,7 +1689,7 @@ * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1594,6 +1717,9 @@ * If the glyph ID has no name in @font, a string of the form `gidDDD` is * generated, with `DDD` being the glyph ID. * + * According to the OpenType specification, glyph names are limited to 63 + * characters and can only contain (a subset of) ASCII. + * * Since: 0.9.2 **/ void @@ -1617,7 +1743,7 @@ * * Note: @len == -1 means the string is null-terminated. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1647,8 +1773,13 @@ 1000, /* x_scale */ 1000, /* y_scale */ - 0., /* slant */ - 0., /* slant_xy; */ + 0.f, /* x_embolden */ + 0.f, /* y_embolden */ + true, /* embolden_in_place */ + 0, /* x_strength */ + 0, /* y_strength */ + 0.f, /* slant */ + 0.f, /* slant_xy; */ 1.f, /* x_multf */ 1.f, /* y_multf */ 1<<16, /* x_mult */ @@ -1658,6 +1789,7 @@ 0, /* y_ppem */ 0, /* ptem */ + HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */ 0, /* num_coords */ nullptr, /* coords */ nullptr, /* design_coords */ @@ -1675,6 +1807,7 @@ if (unlikely (!face)) face = hb_face_get_empty (); + if (!(font = hb_object_create ())) return hb_font_get_empty (); @@ -1684,8 +1817,10 @@ font->klass = hb_font_funcs_get_empty (); font->data.init0 (font); font->x_scale = font->y_scale = face->get_upem (); + font->embolden_in_place = true; font->x_multf = font->y_multf = 1.f; font->x_mult = font->y_mult = 1 << 16; + font->instance_index = HB_FONT_NO_VAR_NAMED_INSTANCE; return font; } @@ -1767,6 +1902,9 @@ font->x_scale = parent->x_scale; font->y_scale = parent->y_scale; + font->x_embolden = parent->x_embolden; + font->y_embolden = parent->y_embolden; + font->embolden_in_place = parent->embolden_in_place; font->slant = parent->slant; font->x_ppem = parent->x_ppem; font->y_ppem = parent->y_ppem; @@ -1779,8 +1917,8 @@ float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0])); if (likely (coords && design_coords)) { - memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0])); - memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0])); + hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0])); + hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0])); _hb_font_adopt_var_coords (font, coords, design_coords, num_coords); } else @@ -1866,7 +2004,7 @@ * * Attaches a user-data key/data pair to the specified font object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -1896,7 +2034,7 @@ * Since: 0.9.2 **/ void * -hb_font_get_user_data (hb_font_t *font, +hb_font_get_user_data (const hb_font_t *font, hb_user_data_key_t *key) { return hb_object_get_user_data (font, key); @@ -1928,7 +2066,7 @@ * * Tests whether a font object is immutable. * - * Return value: %true if @font is immutable, %false otherwise + * Return value: `true` if @font is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -1948,7 +2086,7 @@ * * Return value: serial number * - * Since: 4.4.0. + * Since: 4.4.0 **/ unsigned int hb_font_get_serial (hb_font_t *font) @@ -1964,7 +2102,7 @@ * This has the effect of increasing the serial as returned * by hb_font_get_serial(), which invalidates internal caches. * - * Since: 4.4.0. + * Since: 4.4.0 **/ void hb_font_changed (hb_font_t *font) @@ -2156,6 +2294,31 @@ * * Sets the horizontal and vertical scale of a font. * + * The font scale is a number related to, but not the same as, + * font size. Typically the client establishes a scale factor + * to be used between the two. For example, 64, or 256, which + * would be the fractional-precision part of the font scale. + * This is necessary because #hb_position_t values are integer + * types and you need to leave room for fractional values + * in there. + * + * For example, to set the font size to 20, with 64 + * levels of fractional precision you would call + * `hb_font_set_scale(font, 20 * 64, 20 * 64)`. + * + * In the example above, even what font size 20 means is up to + * you. It might be 20 pixels, or 20 points, or 20 millimeters. + * HarfBuzz does not care about that. You can set the point + * size of the font using hb_font_set_ptem(), and the pixel + * size using hb_font_set_ppem(). + * + * The choice of scale is yours but needs to be consistent between + * what you set here, and what you expect out of #hb_position_t + * as well has draw / paint API output values. + * + * Fonts default to a scale equal to the UPEM value of their face. + * A font with this setting is sometimes called an "unscaled" font. + * * Since: 0.9.2 **/ void @@ -2201,7 +2364,11 @@ * @x_ppem: Horizontal ppem value to assign * @y_ppem: Vertical ppem value to assign * - * Sets the horizontal and vertical pixels-per-em (ppem) of a font. + * Sets the horizontal and vertical pixels-per-em (PPEM) of a font. + * + * These values are used for pixel-size-specific adjustment to + * shaping and draw results, though for the most part they are + * unused and can be left unset. * * Since: 0.9.2 **/ @@ -2286,6 +2453,76 @@ } /** + * hb_font_set_synthetic_bold: + * @font: #hb_font_t to work upon + * @x_embolden: the amount to embolden horizontally + * @y_embolden: the amount to embolden vertically + * @in_place: whether to embolden glyphs in-place + * + * Sets the "synthetic boldness" of a font. + * + * Positive values for @x_embolden / @y_embolden make a font + * bolder, negative values thinner. Typical values are in the + * 0.01 to 0.05 range. The default value is zero. + * + * Synthetic boldness is applied by offsetting the contour + * points of the glyph shape. + * + * Synthetic boldness is applied when rendering a glyph via + * hb_font_draw_glyph(). + * + * If @in_place is `false`, then glyph advance-widths are also + * adjusted, otherwise they are not. The in-place mode is + * useful for simulating [font grading](https://fonts.google.com/knowledge/glossary/grade). + * + * + * Since: 7.0.0 + **/ +void +hb_font_set_synthetic_bold (hb_font_t *font, + float x_embolden, + float y_embolden, + hb_bool_t in_place) +{ + if (hb_object_is_immutable (font)) + return; + + if (font->x_embolden == x_embolden && + font->y_embolden == y_embolden && + font->embolden_in_place == (bool) in_place) + return; + + font->serial++; + + font->x_embolden = x_embolden; + font->y_embolden = y_embolden; + font->embolden_in_place = in_place; + font->mults_changed (); +} + +/** + * hb_font_get_synthetic_bold: + * @font: #hb_font_t to work upon + * @x_embolden: (out): return location for horizontal value + * @y_embolden: (out): return location for vertical value + * @in_place: (out): return location for in-place value + * + * Fetches the "synthetic boldness" parameters of a font. + * + * Since: 7.0.0 + **/ +void +hb_font_get_synthetic_bold (hb_font_t *font, + float *x_embolden, + float *y_embolden, + hb_bool_t *in_place) +{ + if (x_embolden) *x_embolden = font->x_embolden; + if (y_embolden) *y_embolden = font->y_embolden; + if (in_place) *in_place = font->embolden_in_place; +} + +/** * hb_font_set_synthetic_slant: * @font: #hb_font_t to work upon * @slant: synthetic slant value. @@ -2297,9 +2534,8 @@ * HarfBuzz needs to know this value to adjust shaping results, * metrics, and style values to match the slanted rendering. * - * Note: The glyph shape fetched via the - * hb_font_get_glyph_shape() is slanted to reflect this value - * as well. + * Note: The glyph shape fetched via the hb_font_draw_glyph() + * function is slanted to reflect this value as well. * * Note: The slant value is a ratio. For example, a * 20% slant would be represented as a 0.2 value. @@ -2366,7 +2602,7 @@ font->serial_coords = ++font->serial; - if (!variations_length) + if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE) { hb_font_set_var_coords_normalized (font, nullptr, 0); return; @@ -2386,19 +2622,30 @@ return; } + /* Initialize design coords. */ + for (unsigned int i = 0; i < coords_length; i++) + design_coords[i] = axes[i].get_default (); + if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE) + { + unsigned count = coords_length; + /* This may fail if index is out-of-range; + * That's why we initialize design_coords from fvar above + * unconditionally. */ + hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index, + &count, design_coords); + } + for (unsigned int i = 0; i < variations_length; i++) { const auto tag = variations[i].tag; const auto v = variations[i].value; for (unsigned axis_index = 0; axis_index < coords_length; axis_index++) if (axes[axis_index].axisTag == tag) - { design_coords[axis_index] = v; - normalized[axis_index] = fvar.normalize_axis_value (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); } @@ -2438,7 +2685,7 @@ } if (coords_length) - memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); + hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); @@ -2449,28 +2696,40 @@ * @font: a font. * @instance_index: named instance index. * - * Sets design coords of a font from a named instance index. + * Sets design coords of a font from a named-instance index. * * Since: 2.6.0 */ void hb_font_set_var_named_instance (hb_font_t *font, - unsigned instance_index) + unsigned int instance_index) { if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; + if (font->instance_index == instance_index) + return; - unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr); + font->serial_coords = ++font->serial; - float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; - if (unlikely (coords_length && !coords)) - return; + font->instance_index = instance_index; + hb_font_set_variations (font, nullptr, 0); +} - hb_ot_var_named_instance_get_design_coords (font->face, instance_index, &coords_length, coords); - hb_font_set_var_coords_design (font, coords, coords_length); - hb_free (coords); +/** + * hb_font_get_var_named_instance: + * @font: a font. + * + * Returns the currently-set named-instance index of the font. + * + * Return value: Named-instance index or %HB_FONT_NO_VAR_NAMED_INSTANCE. + * + * Since: 7.0.0 + **/ +unsigned int +hb_font_get_var_named_instance (hb_font_t *font) +{ + return font->instance_index; } /** @@ -2514,8 +2773,8 @@ if (coords_length) { - memcpy (copy, coords, coords_length * sizeof (coords[0])); - memcpy (unmapped, coords, coords_length * sizeof (coords[0])); + hb_memcpy (copy, coords, coords_length * sizeof (coords[0])); + hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0])); } /* Best effort design coords simulation */ @@ -2719,3 +2978,13 @@ trampoline_destroy); } #endif + + +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 /* May be NULL. */) +{ + hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-font.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-font.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-font.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-font.h 2023-07-05 07:11:54.000000000 +0000 @@ -34,18 +34,10 @@ #include "hb-common.h" #include "hb-face.h" #include "hb-draw.h" +#include "hb-paint.h" HB_BEGIN_DECLS -/** - * hb_font_t: - * - * Data type for holding fonts. - * - */ -typedef struct hb_font_t hb_font_t; - - /* * hb_font_funcs_t */ @@ -86,8 +78,8 @@ HB_EXTERN void * -hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, - hb_user_data_key_t *key); +hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs, + hb_user_data_key_t *key); HB_EXTERN void @@ -97,7 +89,7 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); -/* font and glyph extents */ +/* font extents */ /** * hb_font_extents_t: @@ -126,24 +118,6 @@ hb_position_t reserved1; } hb_font_extents_t; -/** - * hb_glyph_extents_t: - * @x_bearing: Distance from the x-origin to the left extremum of the glyph. - * @y_bearing: Distance from the top extremum of the glyph to the y-origin. - * @width: Distance from the left extremum of the glyph to the right extremum. - * @height: Distance from the top extremum of the glyph to the bottom extremum. - * - * Glyph extent values, measured in font units. - * - * Note that @height is negative, in coordinate systems that grow up. - **/ -typedef struct hb_glyph_extents_t { - hb_position_t x_bearing; - hb_position_t y_bearing; - hb_position_t width; - hb_position_t height; -} hb_glyph_extents_t; - /* func types */ /** @@ -198,7 +172,7 @@ * This method should retrieve the nominal glyph ID for a specified Unicode code * point. Glyph IDs must be returned in a #hb_codepoint_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data, @@ -221,7 +195,7 @@ * followed by a specified Variation Selector code point. Glyph IDs must be * returned in a #hb_codepoint_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data, @@ -362,7 +336,7 @@ * origin for a glyph. Each coordinate must be returned in an #hb_position_t * output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data, @@ -434,7 +408,7 @@ * This method should retrieve the extents for a specified glyph. Extents must be * returned in an #hb_glyph_extents output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data, @@ -458,7 +432,7 @@ * specified contour point in a glyph. Each coordinate must be returned as * an #hb_position_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data, @@ -481,7 +455,7 @@ * This method should retrieve the glyph name that corresponds to a * glyph ID. The name should be returned in a string output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data, @@ -503,7 +477,7 @@ * This method should retrieve the glyph ID that corresponds to a glyph-name * string. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data, @@ -523,13 +497,53 @@ * 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 + * @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: 7.0.0 + * + **/ +typedef void (*hb_font_draw_glyph_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_paint_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @paint_funcs: The paint functions to use + * @paint_data: The data accompanying the paint functions + * @palette_index: The color palette to use + * @foreground: The foreground color + * @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: 7.0.0 + */ +typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data); /* func setters */ @@ -796,15 +810,50 @@ * @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. + * 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. + * + * Since: 7.0.0 + **/ +HB_EXTERN void +hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_paint_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 no longer needed + * + * Sets the implementation function for #hb_font_paint_glyph_func_t. + * + * Since: 7.0.0 + */ +HB_EXTERN void +hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + /* func dispatch */ HB_EXTERN hb_bool_t @@ -890,6 +939,17 @@ 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); + +HB_EXTERN void +hb_font_paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground); /* high-level funcs, with fallback */ @@ -993,7 +1053,7 @@ HB_EXTERN void * -hb_font_get_user_data (hb_font_t *font, +hb_font_get_user_data (const hb_font_t *font, hb_user_data_key_t *key); HB_EXTERN void @@ -1070,6 +1130,16 @@ hb_font_get_ptem (hb_font_t *font); HB_EXTERN void +hb_font_set_synthetic_bold (hb_font_t *font, + float x_embolden, float y_embolden, + hb_bool_t in_place); + +HB_EXTERN void +hb_font_get_synthetic_bold (hb_font_t *font, + float *x_embolden, float *y_embolden, + hb_bool_t *in_place); + +HB_EXTERN void hb_font_set_synthetic_slant (hb_font_t *font, float slant); HB_EXTERN float @@ -1098,10 +1168,23 @@ hb_font_get_var_coords_normalized (hb_font_t *font, unsigned int *length); +/** + * HB_FONT_NO_VAR_NAMED_INSTANCE: + * + * Constant signifying that a font does not have any + * named-instance index set. This is the default of + * a font. + * + * Since: 7.0.0 + */ +#define HB_FONT_NO_VAR_NAMED_INSTANCE 0xFFFFFFFF + HB_EXTERN void hb_font_set_var_named_instance (hb_font_t *font, - unsigned instance_index); + unsigned int instance_index); +HB_EXTERN unsigned int +hb_font_get_var_named_instance (hb_font_t *font); HB_END_DECLS diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-font.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-font.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-font.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-font.hh 2023-07-05 07:11:54.000000000 +0000 @@ -40,24 +40,25 @@ */ #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ - HB_FONT_FUNC_IMPLEMENT (font_h_extents) \ - HB_FONT_FUNC_IMPLEMENT (font_v_extents) \ - HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \ - HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \ - HB_FONT_FUNC_IMPLEMENT (variation_glyph) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_advances) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \ - HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \ - HB_FONT_FUNC_IMPLEMENT (glyph_extents) \ - HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \ - HB_FONT_FUNC_IMPLEMENT (glyph_name) \ - HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ - HB_FONT_FUNC_IMPLEMENT (glyph_shape) \ + HB_FONT_FUNC_IMPLEMENT (get_,font_h_extents) \ + HB_FONT_FUNC_IMPLEMENT (get_,font_v_extents) \ + HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyph) \ + HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyphs) \ + HB_FONT_FUNC_IMPLEMENT (get_,variation_glyph) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advance) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advance) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advances) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \ + HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \ + HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \ + HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \ /* ^--- Add new callbacks here */ struct hb_font_funcs_t @@ -65,13 +66,13 @@ hb_object_header_t header; struct { -#define HB_FONT_FUNC_IMPLEMENT(name) void *name; +#define HB_FONT_FUNC_IMPLEMENT(get_,name) void *name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } *user_data; struct { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name; +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_destroy_func_t name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } *destroy; @@ -79,12 +80,12 @@ /* Don't access these directly. Call font->get_*() instead. */ union get_t { struct get_funcs_t { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_func_t name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } f; void (*array[0 -#define HB_FONT_FUNC_IMPLEMENT(name) +1 +#define HB_FONT_FUNC_IMPLEMENT(get_,name) +1 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT ]) (); @@ -112,8 +113,16 @@ int32_t x_scale; int32_t y_scale; + + float x_embolden; + float y_embolden; + bool embolden_in_place; + int32_t x_strength; /* x_embolden, in scaled units. */ + int32_t y_strength; /* y_embolden, in scaled units. */ + float slant; float slant_xy; + float x_multf; float y_multf; int64_t x_mult; @@ -125,6 +134,7 @@ float ptem; /* Font variation coordinates. */ + unsigned int instance_index; unsigned int num_coords; int *coords; float *design_coords; @@ -179,6 +189,42 @@ *y = parent_scale_y_position (*y); } + void scale_glyph_extents (hb_glyph_extents_t *extents) + { + float x1 = em_fscale_x (extents->x_bearing); + float y1 = em_fscale_y (extents->y_bearing); + float x2 = em_fscale_x (extents->x_bearing + extents->width); + float y2 = em_fscale_y (extents->y_bearing + extents->height); + + /* Apply slant. */ + if (slant_xy) + { + x1 += hb_min (y1 * slant_xy, y2 * slant_xy); + x2 += hb_max (y1 * slant_xy, y2 * slant_xy); + } + + extents->x_bearing = floorf (x1); + extents->y_bearing = floorf (y1); + extents->width = ceilf (x2) - extents->x_bearing; + extents->height = ceilf (y2) - extents->y_bearing; + + if (x_strength || y_strength) + { + /* Y */ + int y_shift = y_strength; + if (y_scale < 0) y_shift = -y_shift; + extents->y_bearing += y_shift; + extents->height -= y_shift; + + /* X */ + int x_shift = x_strength; + if (x_scale < 0) x_shift = -x_shift; + if (embolden_in_place) + extents->x_bearing -= x_shift / 2; + extents->width += x_shift; + } + } + /* Public getters */ @@ -186,7 +232,7 @@ HB_INTERNAL bool has_func_set (unsigned int i); /* has_* ... */ -#define HB_FONT_FUNC_IMPLEMENT(name) \ +#define HB_FONT_FUNC_IMPLEMENT(get_,name) \ bool \ has_##name##_func () \ { \ @@ -206,14 +252,14 @@ hb_bool_t get_font_h_extents (hb_font_extents_t *extents) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return klass->get.f.font_h_extents (this, user_data, extents, !klass->user_data ? nullptr : klass->user_data->font_h_extents); } hb_bool_t get_font_v_extents (hb_font_extents_t *extents) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return klass->get.f.font_v_extents (this, user_data, extents, !klass->user_data ? nullptr : klass->user_data->font_v_extents); @@ -342,7 +388,7 @@ hb_bool_t get_glyph_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return klass->get.f.glyph_extents (this, user_data, glyph, extents, @@ -380,15 +426,26 @@ !klass->user_data ? nullptr : klass->user_data->glyph_from_name); } - void get_glyph_shape (hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data) + void draw_glyph (hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data) { - klass->get.f.glyph_shape (this, user_data, - glyph, - draw_funcs, draw_data, - !klass->user_data ? nullptr : klass->user_data->glyph_shape); + klass->get.f.draw_glyph (this, user_data, + glyph, + draw_funcs, draw_data, + !klass->user_data ? nullptr : klass->user_data->draw_glyph); } + void paint_glyph (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground) + { + klass->get.f.paint_glyph (this, user_data, + glyph, + paint_funcs, paint_data, + palette, foreground, + !klass->user_data ? nullptr : klass->user_data->paint_glyph); + } /* A bit higher-level, and with fallback */ @@ -632,12 +689,17 @@ void mults_changed () { float upem = face->get_upem (); + x_multf = x_scale / upem; y_multf = y_scale / upem; bool x_neg = x_scale < 0; x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem; bool y_neg = y_scale < 0; y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; + + x_strength = fabsf (roundf (x_scale * x_embolden)); + y_strength = fabsf (roundf (y_scale * y_embolden)); + slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; data.fini (); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ft.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ft.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ft.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ft.cc 2023-07-05 07:11:54.000000000 +0000 @@ -33,17 +33,22 @@ #include "hb-ft.h" +#include "hb-cache.hh" #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" -#include "hb-cache.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-shaper-arabic-pua.hh" +#include "hb-paint.hh" #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H #include FT_OUTLINE_H #include FT_TRUETYPE_TABLES_H +#include FT_SYNTHESIS_H +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300 +#include FT_COLOR_H +#endif /** @@ -80,16 +85,19 @@ */ +using hb_ft_advance_cache_t = hb_cache_t<16, 8, 8, false>; + struct hb_ft_font_t { int load_flags; bool symbol; /* Whether selected cmap is symbol cmap. */ bool unref; /* Whether to destroy ft_face when done. */ + bool transform; /* Whether to apply FT_Face's transform. */ - mutable hb_mutex_t lock; + mutable hb_mutex_t lock; /* Protects members below. */ FT_Face ft_face; mutable unsigned cached_serial; - mutable hb_advance_cache_t advance_cache; + mutable hb_ft_advance_cache_t advance_cache; }; static hb_ft_font_t * @@ -122,8 +130,6 @@ { hb_ft_font_t *ft_font = (hb_ft_font_t *) data; - ft_font->advance_cache.fini (); - if (ft_font->unref) _hb_ft_face_destroy (ft_font->ft_face); @@ -136,32 +142,59 @@ /* hb_font changed, update FT_Face. */ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) { + hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; + + float x_mult = 1.f, y_mult = 1.f; + + if (font->x_scale < 0) x_mult = -x_mult; + if (font->y_scale < 0) y_mult = -y_mult; - FT_Set_Char_Size (ft_face, - abs (font->x_scale), abs (font->y_scale), - 0, 0); + if (FT_Set_Char_Size (ft_face, + abs (font->x_scale), abs (font->y_scale), + 0, 0 #if 0 font->x_ppem * 72 * 64 / font->x_scale, - font->y_ppem * 72 * 64 / font->y_scale); + font->y_ppem * 72 * 64 / font->y_scale #endif - if (font->x_scale < 0 || font->y_scale < 0) + ) && ft_face->num_fixed_sizes) { - FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, - 0, font->y_scale < 0 ? -1 : +1}; +#ifdef HAVE_FT_GET_TRANSFORM + /* Bitmap font, eg. bitmap color emoji. */ + /* Pick largest size? */ + int x_scale = ft_face->available_sizes[ft_face->num_fixed_sizes - 1].x_ppem; + int y_scale = ft_face->available_sizes[ft_face->num_fixed_sizes - 1].y_ppem; + FT_Set_Char_Size (ft_face, + x_scale, y_scale, + 0, 0); + + /* This contains the sign that was previously in x_mult/y_mult. */ + x_mult = (float) font->x_scale / x_scale; + y_mult = (float) font->y_scale / y_scale; +#endif + } + else + { /* Shrug */ } + + + if (x_mult != 1.f || y_mult != 1.f) + { + FT_Matrix matrix = { (int) roundf (x_mult * (1<<16)), 0, + 0, (int) roundf (y_mult * (1<<16))}; FT_Set_Transform (ft_face, &matrix, nullptr); + ft_font->transform = true; } #if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) unsigned int num_coords; - const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); + const float *coords = hb_font_get_var_coords_design (font, &num_coords); if (num_coords) { FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); if (ft_coords) { for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] * 4; - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + ft_coords[i] = coords[i] * 65536.f; + FT_Set_Var_Design_Coordinates (ft_face, num_coords, ft_coords); hb_free (ft_coords); } } @@ -194,6 +227,9 @@ * For more information, see * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx * + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * * Since: 1.0.5 **/ void @@ -219,7 +255,10 @@ * For more information, see * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx * - * Return value: FT_Load_Glyph flags found + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * + * Return value: FT_Load_Glyph flags found, or 0 * * Since: 1.0.5 **/ @@ -241,7 +280,10 @@ * Fetches the FT_Face associated with the specified #hb_font_t * font object. * - * Return value: (nullable): the FT_Face found or %NULL + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * + * Return value: (nullable): the FT_Face found or `NULL` * * Since: 0.9.2 **/ @@ -260,10 +302,15 @@ * hb_ft_font_lock_face: (skip) * @font: #hb_font_t to work upon * - * Gets the FT_Face associated with @font, This face will be kept around until - * you call hb_ft_font_unlock_face(). + * Gets the FT_Face associated with @font. + * + * This face will be kept around and access to the FT_Face object + * from other HarfBuzz API wil be blocked until you call hb_ft_font_unlock_face(). * - * Return value: (nullable): the FT_Face associated with @font or %NULL + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * + * Return value: (nullable) (transfer none): the FT_Face associated with @font or `NULL` * Since: 2.6.5 **/ FT_Face @@ -280,7 +327,7 @@ } /** - * hb_ft_font_unlock_face: + * hb_ft_font_unlock_face: (skip) * @font: #hb_font_t to work upon * * Releases an FT_Face previously obtained with hb_ft_font_lock_face(). @@ -401,10 +448,24 @@ void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_position_t *orig_first_advance = first_advance; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; int load_flags = ft_font->load_flags; - int mult = font->x_scale < 0 ? -1 : +1; + float x_mult; +#ifdef HAVE_FT_GET_TRANSFORM + if (ft_font->transform) + { + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f; + x_mult *= font->x_scale < 0 ? -1 : +1; + } + else +#endif + { + x_mult = font->x_scale < 0 ? -1 : +1; + } for (unsigned int i = 0; i < count; i++) { @@ -417,13 +478,29 @@ else { FT_Get_Advance (ft_face, glyph, load_flags, &v); + /* Work around bug that FreeType seems to return negative advance + * for variable-set fonts if x_scale is negative! */ + v = abs (v); + v = (int) (v * x_mult + (1<<9)) >> 10; ft_font->advance_cache.set (glyph, v); } - *first_advance = (v * mult + (1<<9)) >> 10; + *first_advance = v; first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + + if (font->x_strength && !font->embolden_in_place) + { + /* Emboldening. */ + hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? x_strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } #ifndef HB_NO_VERTICAL @@ -436,17 +513,31 @@ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Fixed v; + float y_mult; +#ifdef HAVE_FT_GET_TRANSFORM + if (ft_font->transform) + { + FT_Matrix matrix; + FT_Get_Transform (ft_font->ft_face, &matrix, nullptr); + y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f; + y_mult *= font->y_scale < 0 ? -1 : +1; + } + else +#endif + { + y_mult = font->y_scale < 0 ? -1 : +1; + } if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) return 0; - if (font->y_scale < 0) - v = -v; + v = (int) (y_mult * v); /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates * have a Y growing upward. Hence the extra negation. */ - return (-v + (1<<9)) >> 10; + hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; + return ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); } #endif @@ -462,6 +553,23 @@ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + float x_mult, y_mult; +#ifdef HAVE_FT_GET_TRANSFORM + if (ft_font->transform) + { + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f; + x_mult *= font->x_scale < 0 ? -1 : +1; + y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f; + y_mult *= font->y_scale < 0 ? -1 : +1; + } + else +#endif + { + x_mult = font->x_scale < 0 ? -1 : +1; + y_mult = font->y_scale < 0 ? -1 : +1; + } if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) return false; @@ -471,10 +579,8 @@ *x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX; *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY); - if (font->x_scale < 0) - *x = -*x; - if (font->y_scale < 0) - *y = -*y; + *x = (hb_position_t) (x_mult * *x); + *y = (hb_position_t) (y_mult * *y); return true; } @@ -510,24 +616,63 @@ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + float x_mult, y_mult; + float slant_xy = font->slant_xy; +#ifdef HAVE_FT_GET_TRANSFORM + if (ft_font->transform) + { + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f; + x_mult *= font->x_scale < 0 ? -1 : +1; + y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f; + y_mult *= font->y_scale < 0 ? -1 : +1; + } + else +#endif + { + x_mult = font->x_scale < 0 ? -1 : +1; + y_mult = font->y_scale < 0 ? -1 : +1; + } if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) return false; - extents->x_bearing = ft_face->glyph->metrics.horiBearingX; - extents->y_bearing = ft_face->glyph->metrics.horiBearingY; - extents->width = ft_face->glyph->metrics.width; - extents->height = -ft_face->glyph->metrics.height; - if (font->x_scale < 0) + /* Copied from hb_font_t::scale_glyph_extents. */ + + float x1 = x_mult * ft_face->glyph->metrics.horiBearingX; + float y1 = y_mult * ft_face->glyph->metrics.horiBearingY; + float x2 = x1 + x_mult * ft_face->glyph->metrics.width; + float y2 = y1 + y_mult * -ft_face->glyph->metrics.height; + + /* Apply slant. */ + if (slant_xy) { - extents->x_bearing = -extents->x_bearing; - extents->width = -extents->width; + x1 += hb_min (y1 * slant_xy, y2 * slant_xy); + x2 += hb_max (y1 * slant_xy, y2 * slant_xy); } - if (font->y_scale < 0) + + extents->x_bearing = floorf (x1); + extents->y_bearing = floorf (y1); + extents->width = ceilf (x2) - extents->x_bearing; + extents->height = ceilf (y2) - extents->y_bearing; + + if (font->x_strength || font->y_strength) { - extents->y_bearing = -extents->y_bearing; - extents->height = -extents->height; + /* Y */ + int y_shift = font->y_strength; + if (font->y_scale < 0) y_shift = -y_shift; + extents->y_bearing += y_shift; + extents->height -= y_shift; + + /* X */ + int x_shift = font->x_strength; + if (font->x_scale < 0) x_shift = -x_shift; + if (font->embolden_in_place) + extents->x_bearing -= x_shift / 2; + extents->width += x_shift; } + return true; } @@ -620,16 +765,39 @@ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + float y_mult; +#ifdef HAVE_FT_GET_TRANSFORM + if (ft_font->transform) + { + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f; + y_mult *= font->y_scale < 0 ? -1 : +1; + } + else +#endif + { + y_mult = font->y_scale < 0 ? -1 : +1; + } - metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); - metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); - metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); - if (font->y_scale < 0) - { - metrics->ascender = -metrics->ascender; - metrics->descender = -metrics->descender; - metrics->line_gap = -metrics->line_gap; + if (ft_face->units_per_EM != 0) + { + metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); + metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); + metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); } + else + { + /* Bitmap-only font, eg. color bitmap font. */ + metrics->ascender = ft_face->size->metrics.ascender; + metrics->descender = ft_face->size->metrics.descender; + metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender); + } + + metrics->ascender = (hb_position_t) (y_mult * (metrics->ascender + font->y_strength)); + metrics->descender = (hb_position_t) (y_mult * metrics->descender); + metrics->line_gap = (hb_position_t) (y_mult * metrics->line_gap); + return true; } @@ -637,16 +805,18 @@ static int _hb_ft_move_to (const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->move_to (to->x, to->y); return FT_Err_Ok; } static int _hb_ft_line_to (const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->line_to (to->x, to->y); return FT_Err_Ok; } @@ -654,8 +824,9 @@ static int _hb_ft_conic_to (const FT_Vector *control, const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->quadratic_to (control->x, control->y, to->x, to->y); return FT_Err_Ok; @@ -665,8 +836,9 @@ _hb_ft_cubic_to (const FT_Vector *control1, const FT_Vector *control2, const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->cubic_to (control1->x, control1->y, control2->x, control2->y, to->x, to->y); @@ -674,18 +846,16 @@ } static void -hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data HB_UNUSED) +hb_ft_draw_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; - _hb_ft_hb_font_check_changed (font, ft_font); - if (unlikely (FT_Load_Glyph (ft_face, glyph, FT_LOAD_NO_BITMAP | ft_font->load_flags))) return; @@ -694,22 +864,139 @@ return; const FT_Outline_Funcs outline_funcs = { - (FT_Outline_MoveToFunc) _hb_ft_move_to, - (FT_Outline_LineToFunc) _hb_ft_line_to, - (FT_Outline_ConicToFunc) _hb_ft_conic_to, - (FT_Outline_CubicToFunc) _hb_ft_cubic_to, + _hb_ft_move_to, + _hb_ft_line_to, + _hb_ft_conic_to, + _hb_ft_cubic_to, 0, /* shift */ 0, /* delta */ }; hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); + /* Embolden */ + if (font->x_strength || font->y_strength) + { + FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_strength, font->y_strength); + + int x_shift = 0; + int y_shift = 0; + if (font->embolden_in_place) + { + /* Undo the FreeType shift. */ + x_shift = -font->x_strength / 2; + y_shift = 0; + if (font->y_scale < 0) y_shift = -font->y_strength; + } + else + { + /* FreeType applied things in the wrong direction for negative scale; fix up. */ + if (font->x_scale < 0) x_shift = -font->x_strength; + if (font->y_scale < 0) y_shift = -font->y_strength; + } + if (x_shift || y_shift) + { + auto &outline = ft_face->glyph->outline; + for (auto &point : hb_iter (outline.points, outline.contours[outline.n_contours - 1] + 1)) + { + point.x += x_shift; + point.y += y_shift; + } + } + } + + FT_Outline_Decompose (&ft_face->glyph->outline, &outline_funcs, &draw_session); } #endif +#ifndef HB_NO_PAINT +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300 + +#include "hb-ft-colr.hh" + +static void +hb_ft_paint_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t gid, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data) +{ + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); + FT_Face ft_face = ft_font->ft_face; + + /* We release the lock before calling into glyph callbacks, such that + * eg. draw API can call back into the face.*/ + + if (unlikely (FT_Load_Glyph (ft_face, gid, + ft_font->load_flags | FT_LOAD_COLOR))) + return; + + if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) + { + if (hb_ft_paint_glyph_colr (font, font_data, gid, + paint_funcs, paint_data, + palette_index, foreground, + user_data)) + return; + + /* Simple outline. */ + ft_font->lock.unlock (); + paint_funcs->push_clip_glyph (paint_data, gid, font); + ft_font->lock.lock (); + paint_funcs->color (paint_data, true, foreground); + paint_funcs->pop_clip (paint_data); + + return; + } + + auto *glyph = ft_face->glyph; + if (glyph->format == FT_GLYPH_FORMAT_BITMAP) + { + auto &bitmap = glyph->bitmap; + if (bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) + { + if (bitmap.pitch != (signed) bitmap.width * 4) + return; + + ft_font->lock.unlock (); + + hb_blob_t *blob = hb_blob_create ((const char *) bitmap.buffer, + bitmap.pitch * bitmap.rows, + HB_MEMORY_MODE_DUPLICATE, + nullptr, nullptr); + + hb_glyph_extents_t extents; + if (!hb_font_get_glyph_extents (font, gid, &extents)) + goto out; + + if (!paint_funcs->image (paint_data, + blob, + bitmap.width, + bitmap.rows, + HB_PAINT_IMAGE_FORMAT_BGRA, + font->slant_xy, + &extents)) + { + /* TODO Try a forced outline load and paint? */ + } + + out: + hb_blob_destroy (blob); + ft_font->lock.lock (); + } + + return; + } +} +#endif +#endif + static inline void free_static_ft_funcs (); @@ -743,7 +1030,13 @@ hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, nullptr, nullptr); #ifndef HB_NO_DRAW - hb_font_funcs_set_glyph_shape_func (funcs, hb_ft_get_glyph_shape, nullptr, nullptr); + hb_font_funcs_set_draw_glyph_func (funcs, hb_ft_draw_glyph, nullptr, nullptr); +#endif + +#ifndef HB_NO_PAINT +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300 + hb_font_funcs_set_paint_glyph_func (funcs, hb_ft_paint_glyph, nullptr, nullptr); +#endif #endif hb_font_funcs_make_immutable (funcs); @@ -818,6 +1111,10 @@ * * Creates an #hb_face_t face object from the specified FT_Face. * + * Note that this is using the FT_Face object just to get at the underlying + * font data, and fonts created from the returned #hb_face_t will use the native + * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them. + * * This variant of the function does not provide any life-cycle management. * * Most client programs should use hb_ft_face_create_referenced() @@ -862,6 +1159,10 @@ * * Creates an #hb_face_t face object from the specified FT_Face. * + * Note that this is using the FT_Face object just to get at the underlying + * font data, and fonts created from the returned #hb_face_t will use the native + * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them. + * * This is the preferred variant of the hb_ft_face_create* * function family, because it calls FT_Reference_Face() on @ft_face, * ensuring that @ft_face remains alive as long as the resulting @@ -882,8 +1183,9 @@ } static void -hb_ft_face_finalize (FT_Face ft_face) +hb_ft_face_finalize (void *arg) { + FT_Face ft_face = (FT_Face) arg; hb_face_destroy ((hb_face_t *) ft_face->generic.data); } @@ -893,6 +1195,10 @@ * * Creates an #hb_face_t face object from the specified FT_Face. * + * Note that this is using the FT_Face object just to get at the underlying + * font data, and fonts created from the returned #hb_face_t will use the native + * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them. + * * This variant of the function caches the newly created #hb_face_t * face object, using the @generic pointer of @ft_face. Subsequent function * calls that are passed the same @ft_face parameter will have the same @@ -915,7 +1221,7 @@ ft_face->generic.finalizer (ft_face); ft_face->generic.data = hb_ft_face_create (ft_face, nullptr); - ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize; + ft_face->generic.finalizer = hb_ft_face_finalize; } return hb_face_reference ((hb_face_t *) ft_face->generic.data); @@ -1028,6 +1334,9 @@ #endif } #endif + + ft_font->advance_cache.clear (); + ft_font->cached_serial = font->serial; } /** @@ -1121,8 +1430,9 @@ } static void -_release_blob (FT_Face ft_face) +_release_blob (void *arg) { + FT_Face ft_face = (FT_Face) arg; hb_blob_destroy ((hb_blob_t *) ft_face->generic.data); } @@ -1139,10 +1449,14 @@ * created with hb_face_create(), and therefore was not * initially configured to use FreeType font functions. * - * An #hb_face_t face object created with hb_ft_face_create() + * An #hb_font_t object created with hb_ft_font_create() * is preconfigured for FreeType font functions and does not * require this function to be used. * + * Note that if you modify the underlying #hb_font_t after + * calling this function, you need to call hb_ft_hb_font_changed() + * to update the underlying FT_Face. + * * Note: Internally, this function creates an FT_Face. * * @@ -1173,14 +1487,14 @@ if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL)) FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE); - _hb_ft_hb_font_changed (font, ft_face); ft_face->generic.data = blob; - ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; + ft_face->generic.finalizer = _release_blob; _hb_ft_font_set_funcs (font, ft_face, true); hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); -} + _hb_ft_hb_font_changed (font, ft_face); +} #endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb.h 2023-07-05 07:11:54.000000000 +0000 @@ -36,6 +36,7 @@ #include "hb-face.h" #include "hb-font.h" #include "hb-map.h" +#include "hb-paint.h" #include "hb-set.h" #include "hb-shape.h" #include "hb-shape-plan.h" diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb.hh 2023-07-05 07:11:54.000000000 +0000 @@ -103,20 +103,20 @@ #pragma GCC diagnostic warning "-Wdisabled-optimization" #pragma GCC diagnostic warning "-Wdouble-promotion" #pragma GCC diagnostic warning "-Wformat=2" +#pragma GCC diagnostic warning "-Wformat-signedness" #pragma GCC diagnostic warning "-Wignored-pragma-optimize" #pragma GCC diagnostic warning "-Wlogical-op" #pragma GCC diagnostic warning "-Wmaybe-uninitialized" #pragma GCC diagnostic warning "-Wmissing-format-attribute" #pragma GCC diagnostic warning "-Wundef" +#pragma GCC diagnostic warning "-Wunsafe-loop-optimizations" #pragma GCC diagnostic warning "-Wunused-but-set-variable" #endif /* Ignored currently, but should be fixed at some point. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED #pragma GCC diagnostic ignored "-Wconversion" // TODO fix -#pragma GCC diagnostic ignored "-Wformat-signedness" // TODO fix #pragma GCC diagnostic ignored "-Wshadow" // TODO fix -#pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations" // TODO fix #pragma GCC diagnostic ignored "-Wunused-parameter" // TODO fix #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wunused-result" // TODO fix @@ -126,6 +126,8 @@ /* Ignored intentionally. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED #pragma GCC diagnostic ignored "-Wclass-memaccess" +#pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126 +#pragma GCC diagnostic ignored "-Wdangling-reference" // https://github.com/harfbuzz/harfbuzz/issues/4043 #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -141,6 +143,7 @@ #include "hb-config.hh" +#include "hb-limits.hh" /* @@ -460,6 +463,37 @@ #endif #endif + +// Locale business + +#if !defined(HB_NO_SETLOCALE) && (!defined(HAVE_NEWLOCALE) || !defined(HAVE_USELOCALE)) +#define HB_NO_SETLOCALE 1 +#endif + +#ifndef HB_NO_SETLOCALE + +#include +#ifdef HAVE_XLOCALE_H +#include // Needed on BSD/OS X for uselocale +#endif + +#ifdef WIN32 +#define hb_locale_t _locale_t +#else +#define hb_locale_t locale_t +#endif +#define hb_setlocale setlocale +#define hb_uselocale uselocale + +#else + +#define hb_locale_t void * +#define hb_setlocale(Category, Locale) "C" +#define hb_uselocale(Locale) ((hb_locale_t) 0) + +#endif + + /* Lets assert int types. Saves trouble down the road. */ static_assert ((sizeof (hb_codepoint_t) == 4), ""); static_assert ((sizeof (hb_position_t) == 4), ""); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-iter.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-iter.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-iter.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-iter.hh 2023-07-05 07:11:54.000000000 +0000 @@ -73,8 +73,10 @@ /* Operators. */ iter_t iter () const { return *thiz(); } iter_t operator + () const { return *thiz(); } - iter_t begin () const { return *thiz(); } - iter_t end () const { return thiz()->__end__ (); } + iter_t _begin () const { return *thiz(); } + iter_t begin () const { return _begin (); } + iter_t _end () const { return thiz()->__end__ (); } + iter_t end () const { return _end (); } explicit operator bool () const { return thiz()->__more__ (); } unsigned len () const { return thiz()->__len__ (); } /* The following can only be enabled if item_t is reference type. Otherwise @@ -118,7 +120,9 @@ #define HB_ITER_USING(Name) \ using item_t = typename Name::item_t; \ + using Name::_begin; \ using Name::begin; \ + using Name::_end; \ using Name::end; \ using Name::get_item_size; \ using Name::is_iterator; \ @@ -168,10 +172,16 @@ HB_FUNCOBJ (hb_iter); struct { - template unsigned - operator () (T&& c) const - { return c.len (); } + template auto + impl (T&& c, hb_priority<1>) const HB_RETURN (unsigned, c.len ()) + + template auto + impl (T&& c, hb_priority<0>) const HB_RETURN (unsigned, c.len) + + public: + template auto + operator () (T&& c) const HB_RETURN (unsigned, impl (std::forward (c), hb_prioritize)) } HB_FUNCOBJ (hb_len); @@ -253,6 +263,8 @@ }; #define hb_is_iterator_of(Iter, Item) hb_is_iterator_of::value #define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) +#define hb_is_sorted_iterator_of(Iter, Item) (hb_is_iterator_of::value && Iter::is_sorted_iterator) +#define hb_is_sorted_iterator(Iter) hb_is_sorted_iterator_of (Iter, typename Iter::item_t) /* hb_is_iterable() */ @@ -375,7 +387,7 @@ void __forward__ (unsigned n) { it += n; } void __prev__ () { --it; } void __rewind__ (unsigned n) { it -= n; } - hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); } + hb_map_iter_t __end__ () const { return hb_map_iter_t (it._end (), f); } bool operator != (const hb_map_iter_t& o) const { return it != o.it; } @@ -438,7 +450,7 @@ bool __more__ () const { return bool (it); } void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } - hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); } + hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it._end (), p, f); } bool operator != (const hb_filter_iter_t& o) const { return it != o.it; } @@ -551,7 +563,7 @@ void __forward__ (unsigned n) { a += n; b += n; } void __prev__ () { --a; --b; } void __rewind__ (unsigned n) { a -= n; b -= n; } - hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); } + hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a._end (), b._end ()); } /* Note, we should stop if ANY of the iters reaches end. As such two compare * unequal if both items are unequal, NOT if either is unequal. */ bool operator != (const hb_zip_iter_t& o) const @@ -635,7 +647,7 @@ } } - hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); } + hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a._end (), b._end ()); } bool operator != (const hb_concat_iter_t& o) const { return a != o.a diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-limits.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-limits.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-limits.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-limits.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,109 @@ +/* + * Copyright © 2022 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_LIMITS_HH +#define HB_LIMITS_HH + +#include "hb.hh" + + +#ifndef HB_BUFFER_MAX_LEN_FACTOR +#define HB_BUFFER_MAX_LEN_FACTOR 64 +#endif +#ifndef HB_BUFFER_MAX_LEN_MIN +#define HB_BUFFER_MAX_LEN_MIN 16384 +#endif +#ifndef HB_BUFFER_MAX_LEN_DEFAULT +#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ +#endif + +#ifndef HB_BUFFER_MAX_OPS_FACTOR +#define HB_BUFFER_MAX_OPS_FACTOR 1024 +#endif +#ifndef HB_BUFFER_MAX_OPS_MIN +#define HB_BUFFER_MAX_OPS_MIN 16384 +#endif +#ifndef HB_BUFFER_MAX_OPS_DEFAULT +#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ +#endif + + +#ifndef HB_MAX_NESTING_LEVEL +#define HB_MAX_NESTING_LEVEL 64 +#endif + + +#ifndef HB_MAX_CONTEXT_LENGTH +#define HB_MAX_CONTEXT_LENGTH 64 +#endif + +#ifndef HB_CLOSURE_MAX_STAGES +/* + * The maximum number of times a lookup can be applied during shaping. + * Used to limit the number of iterations of the closure algorithm. + * This must be larger than the number of times add_gsub_pause() is + * called in a collect_features call of any shaper. + */ +#define HB_CLOSURE_MAX_STAGES 12 +#endif + +#ifndef HB_MAX_SCRIPTS +#define HB_MAX_SCRIPTS 500 +#endif + +#ifndef HB_MAX_LANGSYS +#define HB_MAX_LANGSYS 2000 +#endif + +#ifndef HB_MAX_LANGSYS_FEATURE_COUNT +#define HB_MAX_LANGSYS_FEATURE_COUNT 50000 +#endif + +#ifndef HB_MAX_FEATURE_INDICES +#define HB_MAX_FEATURE_INDICES 1500 +#endif + +#ifndef HB_MAX_LOOKUP_VISIT_COUNT +#define HB_MAX_LOOKUP_VISIT_COUNT 35000 +#endif + + +#ifndef HB_GLYF_MAX_POINTS +#define HB_GLYF_MAX_POINTS 20000 +#endif + +#ifndef HB_GLYF_MAX_EDGE_COUNT +#define HB_GLYF_MAX_EDGE_COUNT 1024 +#endif + +#ifndef HB_CFF_MAX_OPS +#define HB_CFF_MAX_OPS 10000 +#endif + +#ifndef HB_COLRV1_MAX_EDGE_COUNT +#define HB_COLRV1_MAX_EDGE_COUNT 1024 +#endif + + +#endif /* HB_LIMITS_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh 2023-07-05 07:11:54.000000000 +0000 @@ -34,7 +34,6 @@ #include "hb-dispatch.hh" #include "hb-sanitize.hh" -#include "hb-serialize.hh" /* @@ -136,6 +135,13 @@ /* * Lazy loaders. + * + * The lazy-loaders are thread-safe pointer-like objects that create their + * instead on-demand. They also support access to a "data" object that is + * necessary for creating their instance. The data object, if specified, + * is accessed via pointer math, located at a location before the position + * of the loader itself. This avoids having to store a pointer to data + * for every lazy-loader. Multiple lazy-loaders can access the same data. */ template @@ -176,12 +182,12 @@ 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 ()); init (); } + void fini () { do_destroy (instance.get_acquire ()); init (); } void free_instance () { retry: - Stored *p = instance.get (); + Stored *p = instance.get_acquire (); if (unlikely (p && !cmpexch (p, nullptr))) goto retry; do_destroy (p); @@ -203,7 +209,7 @@ Stored * get_stored () const { retry: - Stored *p = this->instance.get (); + Stored *p = this->instance.get_acquire (); if (unlikely (!p)) { if (unlikely (this->is_inert ())) @@ -228,7 +234,8 @@ bool cmpexch (Stored *current, Stored *value) const { - /* This *must* be called when there are no other threads accessing. */ + /* This function can only be safely called directly if no + * other thread is accessing. */ return this->instance.cmpexch (current, value); } @@ -261,7 +268,7 @@ hb_free (p); } -// private: + private: /* Must only have one pointer. */ hb_atomic_ptr_t instance; }; @@ -283,7 +290,7 @@ { auto c = hb_sanitize_context_t (); if (core) - c.set_num_glyphs (0); // So we don't recurse ad infinitum... + c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs return c.reference_table (face); } static void destroy (hb_blob_t *p) { hb_blob_destroy (p); } @@ -297,22 +304,22 @@ hb_blob_t* get_blob () const { return this->get_stored (); } }; -template -struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t -{ - static void destroy (hb_font_funcs_t *p) - { hb_font_funcs_destroy (p); } - static const hb_font_funcs_t *get_null () - { return hb_font_funcs_get_empty (); } -}; -template -struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t -{ - static void destroy (hb_unicode_funcs_t *p) - { hb_unicode_funcs_destroy (p); } - static const hb_unicode_funcs_t *get_null () - { return hb_unicode_funcs_get_empty (); } -}; +#define HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T(Type) \ + template \ + struct hb_##Type##_funcs_lazy_loader_t : hb_lazy_loader_t \ + { \ + static void destroy (hb_##Type##_funcs_t *p) \ + { hb_##Type##_funcs_destroy (p); } \ + static const hb_##Type##_funcs_t *get_null () \ + { return hb_##Type##_funcs_get_empty (); } \ + } + +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (font); +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (unicode); +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (draw); +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (paint); + +#undef HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T #endif /* HB_MACHINERY_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-map.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-map.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-map.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-map.cc 2023-07-05 07:11:54.000000000 +0000 @@ -56,8 +56,6 @@ if (!(map = hb_object_create ())) return hb_map_get_empty (); - map->init_shallow (); - return map; } @@ -107,8 +105,6 @@ { if (!hb_object_destroy (map)) return; - map->fini_shallow (); - hb_free (map); } @@ -122,7 +118,7 @@ * * Attaches a user-data key/data pair to the specified map. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 1.7.7 **/ @@ -149,7 +145,7 @@ * Since: 1.7.7 **/ void * -hb_map_get_user_data (hb_map_t *map, +hb_map_get_user_data (const hb_map_t *map, hb_user_data_key_t *key) { return hb_object_get_user_data (map, key); @@ -162,7 +158,7 @@ * * Tests whether memory allocation for a set was successful. * - * Return value: %true if allocation succeeded, %false otherwise + * Return value: `true` if allocation succeeded, `false` otherwise * * Since: 1.7.7 **/ @@ -178,7 +174,7 @@ * * Allocate a copy of @map. * - * Return value: Newly-allocated map. + * Return value: (transfer full): Newly-allocated map. * * Since: 4.4.0 **/ @@ -186,9 +182,10 @@ hb_map_copy (const hb_map_t *map) { hb_map_t *copy = hb_map_create (); - if (unlikely (!copy)) return nullptr; - copy->resize (map->population); - hb_copy (*map, *copy); + if (unlikely (copy->in_error ())) + return hb_map_get_empty (); + + *copy = *map; return copy; } @@ -251,7 +248,7 @@ * * Tests whether @key is an element of @map. * - * Return value: %true if @key is found in @map, %false otherwise + * Return value: `true` if @key is found in @map, `false` otherwise * * Since: 1.7.7 **/ @@ -283,7 +280,7 @@ * * Tests whether @map is empty (contains no elements). * - * Return value: %true if @map is empty + * Return value: `true` if @map is empty * * Since: 1.7.7 **/ @@ -317,7 +314,7 @@ * Tests whether @map and @other are equal (contain the same * elements). * - * Return value: %true if the two maps are equal, %false otherwise. + * Return value: `true` if the two maps are equal, `false` otherwise. * * Since: 4.3.0 **/ @@ -339,9 +336,84 @@ * * Since: 4.4.0 **/ -HB_EXTERN unsigned int +unsigned int hb_map_hash (const hb_map_t *map) { return map->hash (); } +/** + * hb_map_update: + * @map: A map + * @other: Another map + * + * Add the contents of @other to @map. + * + * Since: 7.0.0 + **/ +HB_EXTERN void +hb_map_update (hb_map_t *map, + const hb_map_t *other) +{ + map->update (*other); +} + +/** + * hb_map_next: + * @map: A map + * @idx: (inout): Iterator internal state + * @key: (out): Key retrieved + * @value: (out): Value retrieved + * + * Fetches the next key/value paire in @map. + * + * Set @idx to -1 to get started. + * + * If the map is modified during iteration, the behavior is undefined. + * + * The order in which the key/values are returned is undefined. + * + * Return value: `true` if there was a next value, `false` otherwise + * + * Since: 7.0.0 + **/ +hb_bool_t +hb_map_next (const hb_map_t *map, + int *idx, + hb_codepoint_t *key, + hb_codepoint_t *value) +{ + return map->next (idx, key, value); +} + +/** + * hb_map_keys: + * @map: A map + * @keys: A set + * + * Add the keys of @map to @keys. + * + * Since: 7.0.0 + **/ +void +hb_map_keys (const hb_map_t *map, + hb_set_t *keys) +{ + map->keys (*keys); +} + +/** + * hb_map_values: + * @map: A map + * @values: A set + * + * Add the values of @map to @values. + * + * Since: 7.0.0 + **/ +void +hb_map_values (const hb_map_t *map, + hb_set_t *values) +{ + map->values (*values); +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-map.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-map.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-map.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-map.h 2023-07-05 07:11:54.000000000 +0000 @@ -32,6 +32,7 @@ #define HB_MAP_H #include "hb-common.h" +#include "hb-set.h" HB_BEGIN_DECLS @@ -74,7 +75,7 @@ hb_bool_t replace); HB_EXTERN void * -hb_map_get_user_data (hb_map_t *map, +hb_map_get_user_data (const hb_map_t *map, hb_user_data_key_t *key); @@ -118,6 +119,24 @@ hb_map_has (const hb_map_t *map, hb_codepoint_t key); +HB_EXTERN void +hb_map_update (hb_map_t *map, + const hb_map_t *other); + +/* Pass -1 in for idx to get started. */ +HB_EXTERN hb_bool_t +hb_map_next (const hb_map_t *map, + int *idx, + hb_codepoint_t *key, + hb_codepoint_t *value); + +HB_EXTERN void +hb_map_keys (const hb_map_t *map, + hb_set_t *keys); + +HB_EXTERN void +hb_map_values (const hb_map_t *map, + hb_set_t *values); HB_END_DECLS diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-map.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-map.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-map.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-map.hh 2023-07-05 07:11:54.000000000 +0000 @@ -29,6 +29,8 @@ #include "hb.hh" +#include "hb-set.hh" + /* * hb_hashmap_t @@ -43,9 +45,9 @@ hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (population); hb_copy (o, *this); } + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (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) { resize (population); hb_copy (o, *this); return *this; } + hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); resize (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 () @@ -71,6 +73,11 @@ uint32_t is_tombstone_ : 1; V value; + item_t () : key (), + hash (0), + is_used_ (false), is_tombstone_ (false), + 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_; } @@ -88,17 +95,8 @@ return minus_1; }; - void clear () - { - new (std::addressof (key)) K (); - new (std::addressof (value)) V (); - hash = 0; - is_used_ = false; - is_tombstone_ = false; - } - - bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); } - bool operator == (const item_t &o) { return *this == o.key; } + 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); } @@ -107,8 +105,8 @@ }; hb_object_header_t header; - bool successful; /* Allocations successful */ - unsigned int population; /* Not including tombstones. */ + unsigned int successful : 1; /* Allocations successful */ + unsigned int population : 31; /* Not including tombstones. */ unsigned int occupancy; /* Including tombstones. */ unsigned int mask; unsigned int prime; @@ -118,27 +116,29 @@ { if (unlikely (!a.successful || !b.successful)) return; - hb_swap (a.population, b.population); + unsigned tmp = a.population; + a.population = b.population; + b.population = tmp; + //hb_swap (a.population, b.population); hb_swap (a.occupancy, b.occupancy); hb_swap (a.mask, b.mask); hb_swap (a.prime, b.prime); hb_swap (a.items, b.items); } - void init_shallow () + void init () { + hb_object_init (this); + successful = true; population = occupancy = 0; mask = 0; prime = 0; items = nullptr; } - void init () - { - hb_object_init (this); - init_shallow (); - } - void fini_shallow () + void fini () { + hb_object_fini (this); + if (likely (items)) { unsigned size = mask + 1; for (unsigned i = 0; i < size; i++) @@ -148,11 +148,6 @@ } population = occupancy = 0; } - void fini () - { - hb_object_fini (this); - fini_shallow (); - } void reset () { @@ -166,7 +161,9 @@ { if (unlikely (!successful)) return false; - unsigned int power = hb_bit_storage (hb_max (population, new_population) * 2 + 8); + if (new_population != 0 && (new_population + new_population / 2) < mask) return true; + + unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8); unsigned int new_size = 1u << power; item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t)); if (unlikely (!new_items)) @@ -175,9 +172,9 @@ return false; } for (auto &_ : hb_iter (new_items, new_size)) - _.clear (); + new (&_) item_t (); - unsigned int old_size = mask + 1; + unsigned int old_size = size (); item_t *old_items = items; /* Switch to new, empty, array. */ @@ -187,67 +184,102 @@ items = new_items; /* Insert back old items. */ - if (old_items) - for (unsigned int i = 0; i < old_size; i++) + for (unsigned int i = 0; i < old_size; i++) + { + if (old_items[i].is_real ()) { - if (old_items[i].is_real ()) - { - set_with_hash (old_items[i].key, - old_items[i].hash, - std::move (old_items[i].value)); - } - old_items[i].~item_t (); + set_with_hash (std::move (old_items[i].key), + old_items[i].hash, + std::move (old_items[i].value)); } + old_items[i].~item_t (); + } hb_free (old_items); return true; } + template + bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false) + { + if (unlikely (!successful)) return false; + if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; + item_t &item = item_for_hash (key, hash); + + if (is_delete && !(item == key)) + return true; /* Trying to delete non-existent key. */ + + if (item.is_used ()) + { + occupancy--; + if (!item.is_tombstone ()) + population--; + } + + item.key = std::forward (key); + item.value = std::forward (value); + item.hash = hash; + item.set_used (true); + item.set_tombstone (is_delete); + + occupancy++; + if (!is_delete) + population++; + + return true; + } + + template + bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward (value)); } template - bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward (value)); } + bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward (value)); } - const V& get (K key) const + const V& get_with_hash (const K &key, uint32_t hash) const { if (unlikely (!items)) return item_t::default_value (); - unsigned int i = bucket_for (key); - return items[i].is_real () && items[i] == key ? items[i].value : item_t::default_value (); + auto &item = item_for_hash (key, hash); + return item.is_real () && item == key ? item.value : item_t::default_value (); + } + const V& get (const K &key) const + { + if (unlikely (!items)) return item_t::default_value (); + return get_with_hash (key, hb_hash (key)); } - void del (K key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); } + void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); } /* Has interface. */ - typedef const V& value_t; - value_t operator [] (K k) const { return get (k); } - bool has (K key, const V **vp = nullptr) const + const V& operator [] (K k) const { return get (k); } + template + bool has (K key, VV **vp = nullptr) const { if (unlikely (!items)) - { - if (vp) *vp = &item_t::default_value (); return false; - } - unsigned int i = bucket_for (key); - if (items[i].is_real () && items[i] == key) + auto &item = item_for_hash (key, hb_hash (key)); + if (item.is_real () && item == key) { - if (vp) *vp = &items[i].value; + if (vp) *vp = std::addressof (item.value); return true; } else - { - if (vp) *vp = &item_t::default_value (); return false; - } } /* Projection. */ V operator () (K k) const { return get (k); } + unsigned size () const { return mask ? mask + 1 : 0; } + void clear () { if (unlikely (!successful)) return; - if (items) - for (auto &_ : hb_iter (items, mask + 1)) - _.clear (); + for (auto &_ : hb_iter (items, size ())) + { + /* Reconstruct items. */ + _.~item_t (); + new (&_) item_t (); + } population = occupancy = 0; } @@ -257,11 +289,10 @@ uint32_t hash () const { - uint32_t h = 0; - for (const auto &item : + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real)) - h ^= item.total_hash (); - return h; + return + + iter_items () + | hb_reduce ([] (uint32_t h, const item_t &_) { return h ^ _.total_hash (); }, (uint32_t) 0u) + ; } bool is_equal (const hb_hashmap_t &other) const @@ -269,7 +300,7 @@ if (population != other.population) return false; for (auto pair : iter ()) - if (get (pair.first) != pair.second) + if (other.get (pair.first) != pair.second) return false; return true; @@ -279,78 +310,98 @@ unsigned int get_population () const { return population; } + void update (const hb_hashmap_t &other) + { + if (unlikely (!successful)) return; + + hb_copy (other, *this); + } + + void keys (hb_set_t &keys_) const + { + hb_copy (keys() , keys_); + } + + void values (hb_set_t &values_) const + { + hb_copy (values() , values_); + } + /* * Iterator */ - auto iter () const HB_AUTO_RETURN + + auto iter_items () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) + + hb_iter (items, size ()) | hb_filter (&item_t::is_real) - | hb_map (&item_t::get_pair) ) auto iter_ref () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) + + iter_items () | hb_map (&item_t::get_pair_ref) ) - auto keys () const HB_AUTO_RETURN + auto iter () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) + + iter_items () + | hb_map (&item_t::get_pair) + ) + auto keys_ref () const HB_AUTO_RETURN + ( + + iter_items () | hb_map (&item_t::key) + ) + auto keys () const HB_AUTO_RETURN + ( + + keys_ref () | hb_map (hb_ridentity) ) - auto values () const HB_AUTO_RETURN + auto values_ref () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) + + iter_items () | hb_map (&item_t::value) + ) + auto values () const HB_AUTO_RETURN + ( + + values_ref () | hb_map (hb_ridentity) ) - /* Sink interface. */ - hb_hashmap_t& operator << (const hb_pair_t& v) - { set (v.first, v.second); return *this; } - - protected: - - template - bool set_with_hash (K key, uint32_t hash, VV&& value, bool is_delete=false) - { - if (unlikely (!successful)) return false; - if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; - unsigned int i = bucket_for_hash (key, hash); - - if (is_delete && items[i].key != key) - return true; /* Trying to delete non-existent key. */ + /* C iterator. */ + bool next (int *idx, + K *key, + V *value) const + { + unsigned i = (unsigned) (*idx + 1); + + unsigned count = size (); + while (i < count && !items[i].is_real ()) + i++; - if (items[i].is_used ()) + if (i >= count) { - occupancy--; - if (!items[i].is_tombstone ()) - population--; + *idx = -1; + return false; } - items[i].key = key; - items[i].value = std::forward (value); - items[i].hash = hash; - items[i].set_used (true); - items[i].set_tombstone (is_delete); - - occupancy++; - if (!is_delete) - population++; + *key = items[i].key; + *value = items[i].value; + *idx = (signed) i; return true; } - unsigned int bucket_for (const K &key) const - { - return bucket_for_hash (key, hb_hash (key)); - } + /* Sink interface. */ + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (v.first, v.second); return *this; } + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (v.first, std::move (v.second)); return *this; } + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (std::move (v.first), v.second); return *this; } + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (std::move (v.first), std::move (v.second)); return *this; } - unsigned int bucket_for_hash (const K &key, uint32_t hash) const + 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; @@ -359,12 +410,12 @@ while (items[i].is_used ()) { if (items[i].hash == hash && items[i] == key) - return i; + return items[i]; if (tombstone == (unsigned) -1 && items[i].is_tombstone ()) tombstone = i; i = (i + ++step) & mask; } - return tombstone == (unsigned) -1 ? i : tombstone; + return items[tombstone == (unsigned) -1 ? i : tombstone]; } static unsigned int prime_for (unsigned int shift) @@ -443,4 +494,5 @@ hb_map_t (const Iterable &o) : hashmap (o) {} }; + #endif /* HB_MAP_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-meta.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-meta.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-meta.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-meta.hh 2023-07-05 07:11:54.000000000 +0000 @@ -112,8 +112,7 @@ template using hb_add_pointer = decltype (_hb_try_add_pointer (hb_prioritize)); -/* TODO Add feature-parity to std::decay. */ -template using hb_decay = hb_remove_const>; +template using hb_decay = typename std::decay::type; #define hb_is_convertible(From,To) std::is_convertible::value @@ -133,6 +132,18 @@ template constexpr auto operator () (T *v) const HB_AUTO_RETURN (*v) + + template constexpr auto + operator () (const hb::shared_ptr& v) const HB_AUTO_RETURN (*v) + + template constexpr auto + operator () (hb::shared_ptr& v) const HB_AUTO_RETURN (*v) + + template constexpr auto + operator () (const hb::unique_ptr& v) const HB_AUTO_RETURN (*v) + + template constexpr auto + operator () (hb::unique_ptr& v) const HB_AUTO_RETURN (*v) } HB_FUNCOBJ (hb_deref); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright © 2022 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_MULTIMAP_HH +#define HB_MULTIMAP_HH + +#include "hb.hh" +#include "hb-map.hh" +#include "hb-vector.hh" + + +/* + * hb_multimap_t + */ + +struct hb_multimap_t +{ + void add (hb_codepoint_t k, hb_codepoint_t v) + { + hb_codepoint_t *i; + if (multiples_indices.has (k, &i)) + { + multiples_values[*i].push (v); + return; + } + + hb_codepoint_t *old_v; + if (singulars.has (k, &old_v)) + { + 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); + + return; + } + + singulars.set (k, v); + } + + hb_array_t get (hb_codepoint_t k) const + { + const hb_codepoint_t *v; + 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 (); + + return hb_array_t (); + } + + bool in_error () const + { + return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error (); + } + + protected: + hb_map_t singulars; + hb_map_t multiples_indices; + hb_vector_t> multiples_values; +}; + + + +#endif /* HB_MULTIMAP_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh 2023-07-05 07:11:54.000000000 +0000 @@ -60,7 +60,7 @@ #elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && defined(_WIN32) typedef CRITICAL_SECTION hb_mutex_impl_t; -#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) #define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0) #else #define hb_mutex_impl_init(M) InitializeCriticalSection (M) @@ -97,6 +97,9 @@ /* Create space for, but do not initialize m. */ alignas(hb_mutex_impl_t) char m[sizeof (hb_mutex_impl_t)]; + hb_mutex_t () { init (); } + ~hb_mutex_t () { fini (); } + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" void init () { hb_mutex_impl_init ((hb_mutex_impl_t *) m); } @@ -108,10 +111,11 @@ struct hb_lock_t { - hb_lock_t (hb_mutex_t &mutex_) : mutex (mutex_) { mutex.lock (); } - ~hb_lock_t () { mutex.unlock (); } + hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); } + hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); } + ~hb_lock_t () { if (mutex) mutex->unlock (); } private: - hb_mutex_t &mutex; + hb_mutex_t *mutex; }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-null.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-null.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-null.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-null.hh 2023-07-05 07:11:54.000000000 +0000 @@ -39,6 +39,24 @@ #define HB_NULL_POOL_SIZE 448 +template +struct _hb_has_min_size : hb_false_type {}; +template +struct _hb_has_min_size> + : hb_true_type {}; +template +using hb_has_min_size = _hb_has_min_size; +#define hb_has_min_size(T) hb_has_min_size::value + +template +struct _hb_has_null_size : hb_false_type {}; +template +struct _hb_has_null_size> + : hb_true_type {}; +template +using hb_has_null_size = _hb_has_null_size; +#define hb_has_null_size(T) hb_has_null_size::value + /* Use SFINAE to sniff whether T has min_size; in which case return the larger * of sizeof(T) and T::null_size, otherwise return sizeof(T). * @@ -117,8 +135,19 @@ }; \ namespace Namespace { \ static_assert (true, "") /* Require semicolon after. */ +#define DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1(Namespace, Type, Size) \ + } /* Close namespace. */ \ + extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Size]; \ + template \ + struct Null> { \ + static Namespace::Type const & get_null () { \ + return *reinterpret_cast *> (_hb_Null_##Namespace##_##Type); \ + } \ + }; \ + namespace Namespace { \ + static_assert (true, "") /* Require semicolon after. */ #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ - const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)] + const unsigned char _hb_Null_##Namespace##_##Type[sizeof (_hb_Null_##Namespace##_##Type)] /* Specializations for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-number.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-number.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-number.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-number.cc 2023-07-05 07:11:54.000000000 +0000 @@ -24,7 +24,6 @@ */ #include "hb.hh" -#include "hb-machinery.hh" #include "hb-number.hh" #include "hb-number-parser.hh" diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh 2023-07-05 07:11:54.000000000 +0000 @@ -31,7 +31,7 @@ #include "hb.hh" -#line 35 "hb-number-parser.hh" +#line 32 "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 139 "hb-number-parser.hh" +#line 132 "hb-number-parser.hh" { cs = double_parser_start; } -#line 144 "hb-number-parser.hh" +#line 135 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ exp_overflow = true; } break; -#line 202 "hb-number-parser.hh" +#line 187 "hb-number-parser.hh" } _again: diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-object.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-object.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-object.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-object.hh 2023-07-05 07:11:54.000000000 +0000 @@ -69,7 +69,7 @@ item = items.push (v); l.unlock (); } - return item; + return items.in_error () ? nullptr : item; } template @@ -80,7 +80,7 @@ if (item) { item_t old = *item; - *item = items[items.length - 1]; + *item = std::move (items.tail ()); items.pop (); l.unlock (); old.fini (); @@ -123,7 +123,7 @@ l.lock (); while (items.length) { - item_t old = items[items.length - 1]; + item_t old = items.tail (); items.pop (); l.unlock (); old.fini (); @@ -144,14 +144,14 @@ { mutable hb_atomic_int_t ref_count; - void init (int v = 1) { ref_count.set_relaxed (v); } - int get_relaxed () const { return ref_count.get_relaxed (); } + void init (int v = 1) { ref_count = v; } + int get_relaxed () const { return ref_count; } int inc () const { return ref_count.inc (); } int dec () const { return ref_count.dec (); } - void fini () { ref_count.set_relaxed (-0x0000DEAD); } + void fini () { ref_count = -0x0000DEAD; } - bool is_inert () const { return !ref_count.get_relaxed (); } - bool is_valid () const { return ref_count.get_relaxed () > 0; } + bool is_inert () const { return !ref_count; } + bool is_valid () const { return ref_count > 0; } }; @@ -175,14 +175,34 @@ void init () { lock.init (); items.init (); } - HB_INTERNAL bool set (hb_user_data_key_t *key, - void * data, - hb_destroy_func_t destroy, - hb_bool_t replace); + void fini () { items.fini (lock); lock.fini (); } - HB_INTERNAL void *get (hb_user_data_key_t *key); + bool set (hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) + { + if (!key) + return false; - void fini () { items.fini (lock); lock.fini (); } + if (replace) { + if (!data && !destroy) { + items.remove (key, lock); + return true; + } + } + hb_user_data_item_t item = {key, data, destroy}; + bool ret = !!items.replace_or_insert (item, lock, (bool) replace); + + return ret; + } + + void *get (hb_user_data_key_t *key) + { + hb_user_data_item_t item = {nullptr, nullptr, nullptr}; + + return items.find (key, &item, lock) ? item.data : nullptr; + } }; @@ -214,23 +234,26 @@ obj ? obj->header.ref_count.get_relaxed () : 0); } -template -static inline Type *hb_object_create () +template +static inline Type *hb_object_create (Ts... ds) { Type *obj = (Type *) hb_calloc (1, sizeof (Type)); if (unlikely (!obj)) return obj; + new (obj) Type (std::forward (ds)...); + hb_object_init (obj); hb_object_trace (obj, HB_FUNC); + return obj; } template static inline void hb_object_init (Type *obj) { obj->header.ref_count.init (); - obj->header.writable.set_relaxed (true); + obj->header.writable = true; obj->header.user_data.init (); } template @@ -241,12 +264,12 @@ template static inline bool hb_object_is_immutable (const Type *obj) { - return !obj->header.writable.get_relaxed (); + return !obj->header.writable; } template static inline void hb_object_make_immutable (const Type *obj) { - obj->header.writable.set_relaxed (false); + obj->header.writable = false; } template static inline Type *hb_object_reference (Type *obj) @@ -269,18 +292,22 @@ return false; hb_object_fini (obj); + + if (!std::is_trivially_destructible::value) + obj->~Type (); + return true; } template static inline void hb_object_fini (Type *obj) { obj->header.ref_count.fini (); /* Do this before user_data */ - hb_user_data_array_t *user_data = obj->header.user_data.get (); + hb_user_data_array_t *user_data = obj->header.user_data.get_acquire (); if (user_data) { user_data->fini (); hb_free (user_data); - user_data = nullptr; + obj->header.user_data.set_relaxed (nullptr); } } template @@ -295,7 +322,7 @@ assert (hb_object_is_valid (obj)); retry: - hb_user_data_array_t *user_data = obj->header.user_data.get (); + hb_user_data_array_t *user_data = obj->header.user_data.get_acquire (); if (unlikely (!user_data)) { user_data = (hb_user_data_array_t *) hb_calloc (sizeof (hb_user_data_array_t), 1); @@ -320,7 +347,7 @@ if (unlikely (!obj || obj->header.is_inert ())) return nullptr; assert (hb_object_is_valid (obj)); - hb_user_data_array_t *user_data = obj->header.user_data.get (); + hb_user_data_array_t *user_data = obj->header.user_data.get_acquire (); if (!user_data) return nullptr; return user_data->get (key); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh 2023-07-05 07:11:54.000000000 +0000 @@ -90,7 +90,7 @@ { if (table_count) { - + tables.sub_array (start_offset, table_count) + + tables.as_array ().sub_array (start_offset, table_count) | hb_map (&TableRecord::tag) | hb_sink (hb_array (table_tags, *table_count)) ; @@ -158,7 +158,7 @@ return_trace (false); if (likely (len)) - memcpy (start, blob->data, len); + hb_memcpy (start, blob->data, len); /* 4-byte alignment. */ c->align (4); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh 2023-07-05 07:11:54.000000000 +0000 @@ -105,7 +105,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: BEInt v; @@ -141,27 +141,29 @@ /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */ typedef HBUINT16 UFWORD; -/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ -struct F2DOT14 : HBINT16 +template +struct HBFixed : Type { - F2DOT14& operator = (uint16_t i ) { HBINT16::operator= (i); return *this; } - // 16384 means 1<<14 - float to_float () const { return ((int32_t) v) / 16384.f; } - void set_float (float f) { v = roundf (f * 16384.f); } + static constexpr float shift = (float) (1 << fraction_bits); + static_assert (Type::static_size * 8 > fraction_bits, ""); + + operator signed () const = delete; + operator unsigned () const = delete; + typename Type::type to_int () const { return Type::v; } + void set_int (typename Type::type i ) { Type::v = i; } + float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; } + void set_float (float f) { Type::v = roundf (f * shift); } public: - DEFINE_SIZE_STATIC (2); + DEFINE_SIZE_STATIC (Type::static_size); }; +/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ +using F2DOT14 = HBFixed; +using F4DOT12 = HBFixed; +using F6DOT10 = HBFixed; + /* 32-bit signed fixed-point number (16.16). */ -struct HBFixed : HBINT32 -{ - HBFixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; } - // 65536 means 1<<16 - float to_float () const { return ((int32_t) v) / 65536.f; } - void set_float (float f) { v = roundf (f * 65536.f); } - public: - DEFINE_SIZE_STATIC (4); -}; +using F16DOT16 = HBFixed; /* Date represented in number of seconds since 12:00 midnight, January 1, * 1904. The value is represented as a signed 64-bit integer. */ @@ -170,7 +172,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: HBINT32 major; @@ -196,6 +198,10 @@ { HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } }; +struct HBGlyphID24 : HBUINT24 +{ + HBGlyphID24& operator = (uint32_t i) { HBUINT24::operator= (i); return *this; } +}; /* Script/language-system/feature index */ struct Index : HBUINT16 { @@ -208,6 +214,12 @@ struct VarIdx : HBUINT32 { static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu; + static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, ""); + static uint32_t add (uint32_t i, unsigned short v) + { + if (i == NO_VARIATION) return i; + return i + v; + } VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; } }; DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx); @@ -300,6 +312,10 @@ template struct OffsetTo : Offset { + // 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)), ""); + HB_DELETE_COPY_ASSIGN (OffsetTo); OffsetTo () = default; @@ -450,14 +466,16 @@ { unsigned int i = (unsigned int) i_; const Type *p = &arrayZ[i]; - if (unlikely (p < arrayZ)) return Null (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) arrayZ)) return Null (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return *p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; Type *p = &arrayZ[i]; - if (unlikely (p < arrayZ)) return Crap (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) arrayZ)) return Crap (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return *p; } @@ -486,10 +504,10 @@ void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array (len).qsort (start, end); } - bool serialize (hb_serialize_context_t *c, unsigned int items_len) + bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend (this, items_len))) return_trace (false); + if (unlikely (!c->extend_size (this, get_size (items_len), clear))) return_trace (false); return_trace (true); } template *p = &this->arrayZ[i]; - if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return this+*p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; const OffsetTo *p = &this->arrayZ[i]; - if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return this+*p; } @@ -608,12 +628,14 @@ { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } @@ -635,14 +657,9 @@ operator iter_t () const { return iter (); } operator writer_t () { return writer (); } - hb_array_t sub_array (unsigned int start_offset, unsigned int count) const - { return as_array ().sub_array (start_offset, count); } - hb_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const - { return as_array ().sub_array (start_offset, count); } - hb_array_t sub_array (unsigned int start_offset, unsigned int count) - { return as_array ().sub_array (start_offset, count); } - hb_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) - { return as_array ().sub_array (start_offset, count); } + /* Faster range-based for loop. */ + const Type *begin () const { return arrayZ; } + const Type *end () const { return arrayZ + len; } template Type &lsearch (const T &x, Type ¬_found = Crap (Type)) @@ -656,15 +673,15 @@ unsigned int to_store = (unsigned int) -1) const { return as_array ().lfind (x, i, not_found, to_store); } - void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) - { as_array ().qsort (start, end); } + void qsort () + { as_array ().qsort (); } - HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len) + HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len, bool clear = true) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW); - if (unlikely (!c->extend (this))) return_trace (false); + if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false); return_trace (true); } template using Array16Of = ArrayOf; +template using Array24Of = ArrayOf; template using Array32Of = ArrayOf; using PString = ArrayOf; @@ -738,26 +756,28 @@ template using Array32OfOffset32To = ArrayOf, HBUINT32>; /* Array of offsets relative to the beginning of the array itself. */ -template -struct List16OfOffset16To : Array16OfOffset16To +template +struct List16OfOffsetTo : ArrayOf, HBUINT16> { const Type& operator [] (int i_) const { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Null (Type); + _hb_compiler_memory_r_barrier (); return this+this->arrayZ[i]; } const Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return this+this->arrayZ[i]; } bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct List16OfOffset16To *out = c->serializer->embed (*this); + struct List16OfOffsetTo *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); unsigned int count = this->len; for (unsigned int i = 0; i < count; i++) @@ -769,10 +789,13 @@ bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); - return_trace (Array16OfOffset16To::sanitize (c, this, std::forward (ds)...)); + return_trace ((Array16Of>::sanitize (c, this, std::forward (ds)...))); } }; +template +using List16OfOffset16To = List16OfOffsetTo; + /* An array starting at second element. */ template struct HeadlessArrayOf @@ -785,12 +808,14 @@ { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i-1]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i-1]; } unsigned int get_size () const @@ -809,21 +834,25 @@ operator iter_t () const { return iter (); } operator writer_t () { return writer (); } - bool serialize (hb_serialize_context_t *c, unsigned int items_len) + /* Faster range-based for loop. */ + const Type *begin () const { return arrayZ; } + const Type *end () const { return arrayZ + get_length (); } + + HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW); - if (unlikely (!c->extend (this))) return_trace (false); + if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false); return_trace (true); } template - bool serialize (hb_serialize_context_t *c, Iterator items) + HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); - unsigned count = items.len (); - if (unlikely (!serialize (c, count))) return_trace (false); + unsigned count = hb_len (items); + if (unlikely (!serialize (c, count, false))) return_trace (false); /* TODO Umm. Just exhaust the iterator instead? Being extra * cautious right now.. */ for (unsigned i = 0; i < count; i++, ++items) @@ -869,12 +898,14 @@ { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } unsigned int get_size () const @@ -923,14 +954,9 @@ operator iter_t () const { return iter (); } operator writer_t () { return writer (); } - hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int count) const - { return as_array ().sub_array (start_offset, count); } - hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const - { return as_array ().sub_array (start_offset, count); } - hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int count) - { return as_array ().sub_array (start_offset, count); } - hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) - { return as_array ().sub_array (start_offset, count); } + /* Faster range-based for loop. */ + const Type *begin () const { return this->arrayZ; } + const Type *end () const { return this->arrayZ + this->len; } bool serialize (hb_serialize_context_t *c, unsigned int items_len) { @@ -961,6 +987,7 @@ }; template using SortedArray16Of = SortedArrayOf; +template using SortedArray24Of = SortedArrayOf; template using SortedArray32Of = SortedArrayOf; /* @@ -1053,12 +1080,14 @@ { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Null (Type); + _hb_compiler_memory_r_barrier (); return StructAtOffset (&bytesZ, i * header.unitSize); } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Crap (Type); + _hb_compiler_memory_r_barrier (); return StructAtOffset (&bytesZ, i * header.unitSize); } unsigned int get_length () const diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc 2023-07-05 07:11:54.000000000 +0000 @@ -422,8 +422,8 @@ } else { - extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ()); - extents->width = font->em_scalef_x (bounds.max.x.to_real ()) - extents->x_bearing; + extents->x_bearing = roundf (bounds.min.x.to_real ()); + extents->width = roundf (bounds.max.x.to_real () - extents->x_bearing); } if (bounds.min.y >= bounds.max.y) { @@ -432,10 +432,12 @@ } else { - extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ()); - extents->height = font->em_scalef_y (bounds.min.y.to_real ()) - extents->y_bearing; + extents->y_bearing = roundf (bounds.max.y.to_real ()); + extents->height = roundf (bounds.min.y.to_real () - extents->y_bearing); } + font->scale_glyph_extents (extents); + return true; } @@ -550,6 +552,15 @@ return true; } + +bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const +{ + funcs->push_clip_glyph (data, glyph, font); + funcs->color (data, true, foreground); + funcs->pop_clip (data); + + return true; +} bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ #include "hb-ot-cff-common.hh" #include "hb-subset-cff1.hh" #include "hb-draw.hh" +#include "hb-paint.hh" #define HB_STRING_ARRAY_NAME cff1_std_strings #define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh" @@ -175,7 +176,7 @@ unsigned int size = src.get_size (); Encoding *dest = c->allocate_size (size); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } @@ -471,7 +472,7 @@ unsigned int size = src.get_size (num_glyphs); Charset *dest = c->allocate_size (size); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } @@ -617,7 +618,6 @@ } byte_str_array_t bytesArray; - bytesArray.init (); if (!bytesArray.resize (sidmap.get_population ())) return_trace (false); for (unsigned int i = 0; i < strings.count; i++) @@ -628,7 +628,6 @@ } bool result = CFF1Index::serialize (c, bytesArray); - bytesArray.fini (); return_trace (result); } }; @@ -813,7 +812,7 @@ break; default: - env.last_offset = env.str_ref.offset; + env.last_offset = env.str_ref.get_offset (); top_dict_opset_t::process_op (op, env, dictval); /* Record this operand below if stack is empty, otherwise done */ if (!env.argStack.is_empty ()) return; @@ -903,8 +902,6 @@ case OpCode_FamilyOtherBlues: case OpCode_StemSnapH: case OpCode_StemSnapV: - env.clear_args (); - break; case OpCode_StdHW: case OpCode_StdVW: case OpCode_BlueScale: @@ -916,7 +913,6 @@ case OpCode_initialRandomSeed: case OpCode_defaultWidthX: case OpCode_nominalWidthX: - val.single_val = env.argStack.pop_num (); env.clear_args (); break; case OpCode_Subrs: @@ -1295,10 +1291,10 @@ } protected: - hb_blob_t *blob = nullptr; hb_sanitize_context_t sc; public: + hb_blob_t *blob = nullptr; const Encoding *encoding = nullptr; const Charset *charset = nullptr; const CFF1NameIndex *nameIndex = nullptr; @@ -1345,6 +1341,7 @@ bool get_glyph_name (hb_codepoint_t glyph, char *buf, unsigned int buf_len) const { + if (unlikely (glyph >= num_glyphs)) return false; if (unlikely (!is_valid ())) return false; if (is_CID()) return false; if (unlikely (!buf_len)) return true; @@ -1379,7 +1376,7 @@ if (unlikely (!len)) return false; retry: - hb_sorted_vector_t *names = glyph_names.get (); + hb_sorted_vector_t *names = glyph_names.get_acquire (); if (unlikely (!names)) { names = (hb_sorted_vector_t *) hb_calloc (sizeof (hb_sorted_vector_t), 1); @@ -1428,6 +1425,7 @@ } 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; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc 2023-07-05 07:11:54.000000000 +0000 @@ -124,8 +124,8 @@ } else { - extents->x_bearing = font->em_scalef_x (param.min_x.to_real ()); - extents->width = font->em_scalef_x (param.max_x.to_real ()) - extents->x_bearing; + extents->x_bearing = roundf (param.min_x.to_real ()); + extents->width = roundf (param.max_x.to_real () - extents->x_bearing); } if (param.min_y >= param.max_y) { @@ -134,10 +134,21 @@ } else { - extents->y_bearing = font->em_scalef_y (param.max_y.to_real ()); - extents->height = font->em_scalef_y (param.min_y.to_real ()) - extents->y_bearing; + extents->y_bearing = roundf (param.max_y.to_real ()); + extents->height = roundf (param.min_y.to_real () - extents->y_bearing); } + font->scale_glyph_extents (extents); + + return true; +} + +bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const +{ + funcs->push_clip_glyph (data, glyph, font); + funcs->color (data, true, foreground); + funcs->pop_clip (data); + return true; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ #include "hb-ot-cff-common.hh" #include "hb-subset-cff2.hh" #include "hb-draw.hh" +#include "hb-paint.hh" namespace CFF { @@ -56,7 +57,7 @@ unsigned int size = src.get_size (num_glyphs); CFF2FDSelect *dest = c->allocate_size (size); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } @@ -124,7 +125,7 @@ unsigned int size_ = varStore->get_size (); CFF2VariationStore *dest = c->allocate_size (size_); if (unlikely (!dest)) return_trace (false); - memcpy (dest, varStore, size_); + hb_memcpy (dest, varStore, size_); return_trace (true); } @@ -282,9 +283,6 @@ case OpCode_BlueFuzz: case OpCode_ExpansionFactor: case OpCode_LanguageGroup: - val.single_val = env.argStack.pop_num (); - env.clear_args (); - break; case OpCode_BlueValues: case OpCode_OtherBlues: case OpCode_FamilyBlues: @@ -483,13 +481,18 @@ blob = nullptr; } + hb_map_t *create_glyph_to_sid_map () const + { + return nullptr; + } + bool is_valid () const { return blob; } protected: - hb_blob_t *blob = nullptr; hb_sanitize_context_t sc; public: + hb_blob_t *blob = nullptr; cff2_top_dict_values_t topDict; const CFF2Subrs *globalSubrs = nullptr; const CFF2VariationStore *varStore = nullptr; @@ -511,6 +514,7 @@ 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_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -66,95 +66,25 @@ { TRACE_SERIALIZE (this); unsigned int size = get_size (); - CFFIndex *out = c->allocate_size (size); + CFFIndex *out = c->allocate_size (size, false); if (likely (out)) - memcpy (out, this, size); + hb_memcpy (out, this, size); return_trace (out); } + template bool serialize (hb_serialize_context_t *c, - unsigned int offSize_, - const byte_str_array_t &byteArray) + const Iterable &iterable) { TRACE_SERIALIZE (this); - - if (byteArray.length == 0) - { - COUNT *dest = c->allocate_min (); - if (unlikely (!dest)) return_trace (false); - *dest = 0; - return_trace (true); - } - - /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (this))) return_trace (false); - this->count = byteArray.length; - this->offSize = offSize_; - if (unlikely (!c->allocate_size (offSize_ * (byteArray.length + 1)))) - return_trace (false); - - /* serialize indices */ - unsigned int offset = 1; - unsigned int i = 0; - for (; i < byteArray.length; i++) - { - set_offset_at (i, offset); - offset += byteArray[i].get_size (); - } - set_offset_at (i, offset); - - /* serialize data */ - for (unsigned int i = 0; i < byteArray.length; i++) - { - const hb_ubytes_t &bs = byteArray[i]; - unsigned char *dest = c->allocate_size (bs.length); - if (unlikely (!dest)) return_trace (false); - memcpy (dest, &bs[0], bs.length); - } - - return_trace (true); - } - - bool serialize (hb_serialize_context_t *c, - unsigned int offSize_, - const str_buff_vec_t &buffArray) - { - byte_str_array_t byteArray; - byteArray.init (); - byteArray.resize (buffArray.length); - for (unsigned int i = 0; i < byteArray.length; i++) - byteArray[i] = hb_ubytes_t (buffArray[i].arrayZ, buffArray[i].length); - bool result = this->serialize (c, offSize_, byteArray); - byteArray.fini (); - return result; - } - - template - bool serialize (hb_serialize_context_t *c, - Iterator it) - { - TRACE_SERIALIZE (this); - serialize_header(c, + it | hb_map ([] (const hb_ubytes_t &_) { return _.length; })); + auto it = hb_iter (iterable); + serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len)); for (const auto &_ : +it) - _.copy (c); + hb_iter (_).copy (c); return_trace (true); } - bool serialize (hb_serialize_context_t *c, - const byte_str_array_t &byteArray) - { return serialize (c, + hb_iter (byteArray)); } - - bool serialize (hb_serialize_context_t *c, - const str_buff_vec_t &buffArray) - { - auto it = - + hb_iter (buffArray) - | hb_map ([] (const str_buff_t &_) { return hb_ubytes_t (_.arrayZ, _.length); }) - ; - return serialize (c, it); - } - template bool serialize_header (hb_serialize_context_t *c, @@ -171,7 +101,7 @@ if (!this->count) return_trace (true); if (unlikely (!c->extend (this->offSize))) return_trace (false); this->offSize = off_size; - if (unlikely (!c->allocate_size (off_size * (this->count + 1)))) + if (unlikely (!c->allocate_size (off_size * (this->count + 1), false))) return_trace (false); /* serialize indices */ @@ -179,14 +109,27 @@ unsigned int i = 0; for (unsigned _ : +it) { - CFFIndex::set_offset_at (i++, offset); + set_offset_at (i++, offset); offset += _; } - CFFIndex::set_offset_at (i, offset); + set_offset_at (i, offset); return_trace (true); } + template + static unsigned total_size (const Iterable &iterable) + { + auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len); + if (!it) return 0; + + 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; + } + void set_offset_at (unsigned int index, unsigned int offset) { assert (index <= count); @@ -207,10 +150,14 @@ unsigned int size = offSize; const HBUINT8 *p = offsets + size * index; - unsigned int offset = 0; - for (; size; size--) - offset = (offset << 8) + *p++; - return offset; + switch (size) + { + case 1: return * (HBUINT8 *) p; + case 2: return * (HBUINT16 *) p; + case 3: return * (HBUINT24 *) p; + case 4: return * (HBUINT32 *) p; + default: return 0; + } } unsigned int length_at (unsigned int index) const @@ -229,6 +176,7 @@ 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); @@ -280,7 +228,7 @@ if (unlikely (!c->extend_min (this))) return_trace (false); this->count = dataArrayLen; this->offSize = offSize_; - if (unlikely (!c->allocate_size (offSize_ * (dataArrayLen + 1)))) + if (unlikely (!c->allocate_size (offSize_ * (dataArrayLen + 1), false))) return_trace (false); /* serialize indices */ @@ -288,10 +236,10 @@ unsigned int i = 0; for (; i < dataArrayLen; i++) { - CFFIndex::set_offset_at (i, offset); + this->set_offset_at (i, offset); offset += dataSizeArray[i]; } - CFFIndex::set_offset_at (i, offset); + this->set_offset_at (i, offset); /* serialize data */ for (unsigned int i = 0; i < dataArrayLen; i++) @@ -324,13 +272,12 @@ template static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp) { - // XXX: not sure why but LLVM fails to compile the following 'unlikely' macro invocation - if (/*unlikely*/ (!serialize_int (c, intOp, value))) + if (unlikely ((!serialize_int (c, intOp, value)))) return false; TRACE_SERIALIZE (this); /* serialize the opcode */ - HBUINT8 *p = c->allocate_size (OpCode_Size (op)); + HBUINT8 *p = c->allocate_size (OpCode_Size (op), false); if (unlikely (!p)) return_trace (false); if (Is_OpCode_ESC (op)) { @@ -415,9 +362,8 @@ TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this)))) return_trace (false); - for (unsigned int i = 0; i < c->get_num_glyphs (); i++) - if (unlikely (!fds[i].sanitize (c))) - return_trace (false); + if (unlikely (!c->check_array (fds, c->get_num_glyphs ()))) + return_trace (false); return_trace (true); } @@ -471,14 +417,20 @@ return_trace (true); } - hb_codepoint_t get_fd (hb_codepoint_t glyph) const + static int _cmp_range (const void *_key, const void *_item) { - unsigned int i; - for (i = 1; i < nRanges (); i++) - if (glyph < ranges[i].first) - break; + hb_codepoint_t glyph = * (hb_codepoint_t *) _key; + FDSelect3_4_Range *range = (FDSelect3_4_Range *) _item; - return (hb_codepoint_t) ranges[i - 1].fd; + if (glyph < range[0].first) return -1; + if (glyph < range[1].first) return 0; + return +1; + } + + hb_codepoint_t 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; } GID_TYPE &nRanges () { return ranges.len; } @@ -501,9 +453,9 @@ { TRACE_SERIALIZE (this); unsigned int size = src.get_size (num_glyphs); - FDSelect *dest = c->allocate_size (size); + FDSelect *dest = c->allocate_size (size, false); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -31,6 +31,7 @@ #include "hb-ot-shaper-arabic-pua.hh" #include "hb-open-type.hh" #include "hb-set.hh" +#include "hb-cache.hh" /* * cmap -- Character to Glyph Index Mapping @@ -909,7 +910,7 @@ hb_codepoint_t first = arrayZ[i].startUnicodeValue; hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount), (hb_codepoint_t) HB_UNICODE_MAX); - out->add_range (first, hb_min (last, 0x10FFFFu)); + out->add_range (first, last); } } @@ -925,37 +926,75 @@ if (unlikely (!c->copy (len))) return nullptr; unsigned init_len = c->length (); - hb_codepoint_t lastCode = HB_MAP_VALUE_INVALID; - int count = -1; - - for (const UnicodeValueRange& _ : as_array ()) + if (this->len > unicodes->get_population () * hb_bit_storage ((unsigned) this->len)) { - for (const unsigned addcnt : hb_range ((unsigned) _.additionalCount + 1)) + 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);) { - unsigned curEntry = (unsigned) _.startUnicodeValue + addcnt; - if (!unicodes->has (curEntry)) continue; - count += 1; - if (lastCode == HB_MAP_VALUE_INVALID) - lastCode = curEntry; - else if (lastCode + count != curEntry) + if (!as_array ().bsearch (u)) + continue; + if (start == HB_SET_VALUE_INVALID) + { + start = u; + end = start - 1; + } + if (end + 1 != u || end - start == 255) { UnicodeValueRange rec; - rec.startUnicodeValue = lastCode; - rec.additionalCount = count - 1; + rec.startUnicodeValue = start; + rec.additionalCount = end - start; c->copy (rec); - - lastCode = curEntry; - count = 0; + start = u; } + end = u; + } + if (start != HB_SET_VALUE_INVALID) + { + UnicodeValueRange rec; + rec.startUnicodeValue = start; + rec.additionalCount = end - start; + c->copy (rec); } - } - if (lastCode != HB_MAP_VALUE_INVALID) + } + else { - UnicodeValueRange rec; - rec.startUnicodeValue = lastCode; - rec.additionalCount = count; - c->copy (rec); + hb_codepoint_t lastCode = HB_SET_VALUE_INVALID; + int count = -1; + + for (const UnicodeValueRange& _ : *this) + { + hb_codepoint_t curEntry = (hb_codepoint_t) (_.startUnicodeValue - 1); + hb_codepoint_t end = curEntry + _.additionalCount + 2; + + for (; unicodes->next (&curEntry) && curEntry < end;) + { + count += 1; + if (lastCode == HB_SET_VALUE_INVALID) + lastCode = curEntry; + else if (lastCode + count != curEntry) + { + UnicodeValueRange rec; + rec.startUnicodeValue = lastCode; + rec.additionalCount = count - 1; + c->copy (rec); + + lastCode = curEntry; + count = 0; + } + } + } + + if (lastCode != HB_MAP_VALUE_INVALID) + { + UnicodeValueRange rec; + rec.startUnicodeValue = lastCode; + rec.additionalCount = count; + c->copy (rec); + } } if (c->length () - init_len == 0) @@ -1376,7 +1415,7 @@ switch (format) { case 4: return u.format4.serialize (c, it); case 12: return u.format12.serialize (c, it); - case 14: return u.format14.serialize (c, plan->unicodes, plan->glyphs_requested, plan->glyph_map, base); + case 14: return u.format14.serialize (c, &plan->unicodes, &plan->glyphs_requested, plan->glyph_map, base); default: return; } } @@ -1474,19 +1513,67 @@ DEFINE_SIZE_STATIC (8); }; +struct cmap; + struct SubtableUnicodesCache { private: - const void* base; - hb_hashmap_t> cached_unicodes; + hb_blob_ptr_t base_blob; + const char* base; + hb_hashmap_t> cached_unicodes; public: + + static SubtableUnicodesCache* create (hb_blob_ptr_t source_table) + { + SubtableUnicodesCache* cache = + (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache)); + new (cache) SubtableUnicodesCache (source_table); + return cache; + } + + static void destroy (void* value) { + if (!value) return; + + SubtableUnicodesCache* cache = (SubtableUnicodesCache*) value; + cache->~SubtableUnicodesCache (); + hb_free (cache); + } + SubtableUnicodesCache(const void* cmap_base) - : base(cmap_base), cached_unicodes() {} + : base_blob(), + base ((const char*) cmap_base), + cached_unicodes () + {} + + SubtableUnicodesCache(hb_blob_ptr_t base_blob_) + : base_blob(base_blob_), + base ((const char *) base_blob.get()), + cached_unicodes () + {} - hb_set_t* set_for (const EncodingRecord* record) + ~SubtableUnicodesCache() { - if (!cached_unicodes.has ((intptr_t) record)) + base_blob.destroy (); + } + + bool same_base(const void* other) const + { + return other == (const void*) base; + } + + const hb_set_t* set_for (const EncodingRecord* record, + SubtableUnicodesCache& mutable_cache) const + { + if (cached_unicodes.has ((unsigned) ((const char *) record - base))) + return cached_unicodes.get ((unsigned) ((const char *) record - base)); + + return mutable_cache.set_for (record); + } + + const hb_set_t* set_for (const EncodingRecord* record) + { + if (!cached_unicodes.has ((unsigned) ((const char *) record - base))) { hb_set_t *s = hb_set_create (); if (unlikely (s->in_error ())) @@ -1494,12 +1581,12 @@ (base+record->subtable).collect_unicodes (s); - if (unlikely (!cached_unicodes.set ((intptr_t) record, hb::unique_ptr {s}))) + if (unlikely (!cached_unicodes.set ((unsigned) ((const char *) record - base), hb::unique_ptr {s}))) return hb_set_get_empty (); return s; } - return cached_unicodes.get ((intptr_t) record); + return cached_unicodes.get ((unsigned) ((const char *) record - base)); } }; @@ -1523,13 +1610,30 @@ { static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap; + + static SubtableUnicodesCache* create_filled_cache(hb_blob_ptr_t source_table) { + const cmap* cmap = source_table.get(); + auto it = + + hb_iter (cmap->encodingRecord) + | hb_filter ([&](const EncodingRecord& _) { + return cmap::filter_encoding_records_for_subset (cmap, _); + }) + ; + + SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table); + for (const EncodingRecord& _ : it) + cache->set_for(&_); // populate the cache for this encoding record. + + return cache; + } + template bool serialize (hb_serialize_context_t *c, Iterator it, EncodingRecIter encodingrec_iter, const void *base, - const hb_subset_plan_t *plan, + hb_subset_plan_t *plan, bool drop_format_4 = false) { if (unlikely (!c->extend_min ((*this)))) return false; @@ -1538,7 +1642,14 @@ unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0; auto snap = c->snapshot (); - SubtableUnicodesCache unicodes_cache (base); + SubtableUnicodesCache local_unicodes_cache (base); + const SubtableUnicodesCache* unicodes_cache = &local_unicodes_cache; + + if (plan->accelerator && + plan->accelerator->cmap_cache && + plan->accelerator->cmap_cache->same_base (base)) + unicodes_cache = plan->accelerator->cmap_cache; + for (const EncodingRecord& _ : encodingrec_iter) { if (c->in_error ()) @@ -1547,7 +1658,7 @@ unsigned format = (base+_.subtable).u.format; if (format != 4 && format != 12 && format != 14) continue; - hb_set_t* unicodes_set = unicodes_cache.set_for (&_); + const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache); if (!drop_format_4 && format == 4) { @@ -1566,7 +1677,13 @@ else if (format == 12) { - if (_can_drop (_, *unicodes_set, base, unicodes_cache, + it | hb_map (hb_first), encodingrec_iter)) continue; + if (_can_drop (_, + *unicodes_set, + base, + *unicodes_cache, + local_unicodes_cache, + + it | hb_map (hb_first), encodingrec_iter)) + continue; c->copy (_, + it | hb_filter (*unicodes_set, hb_first), 12u, base, plan, &format12objidx); } else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx); @@ -1585,7 +1702,8 @@ bool _can_drop (const EncodingRecord& cmap12, const hb_set_t& cmap12_unicodes, const void* base, - SubtableUnicodesCache& unicodes_cache, + const SubtableUnicodesCache& unicodes_cache, + SubtableUnicodesCache& local_unicodes_cache, Iterator subset_unicodes, EncodingRecordIterator encoding_records) { @@ -1616,7 +1734,7 @@ || (base+_.subtable).get_language() != target_language) continue; - hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_); + const hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_, local_unicodes_cache); auto cmap12 = + subset_unicodes | hb_filter (cmap12_unicodes); auto sibling = + subset_unicodes | hb_filter (*sibling_unicodes); @@ -1653,17 +1771,9 @@ auto encodingrec_iter = + hb_iter (encodingRecord) - | hb_filter ([&] (const EncodingRecord& _) - { - if ((_.platformID == 0 && _.encodingID == 3) || - (_.platformID == 0 && _.encodingID == 4) || - (_.platformID == 3 && _.encodingID == 1) || - (_.platformID == 3 && _.encodingID == 10) || - (this + _.subtable).u.format == 14) - return true; - - return false; - }) + | hb_filter ([&](const EncodingRecord& _) { + return cmap::filter_encoding_records_for_subset (this, _); + }) ; if (unlikely (!encodingrec_iter.len ())) return_trace (false); @@ -1692,7 +1802,11 @@ { return (_.second != HB_MAP_VALUE_INVALID); }) ; - return_trace (cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan)); + return_trace (cmap_prime->serialize (c->serializer, + it, + encodingrec_iter, + this, + c->plan)); } const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const @@ -1728,6 +1842,8 @@ struct accelerator_t { + using cache_t = hb_cache_t<21, 16, 8, true>; + accelerator_t (hb_face_t *face) { this->table = hb_sanitize_context_t ().reference_table (face); @@ -1782,26 +1898,43 @@ } ~accelerator_t () { this->table.destroy (); } + inline bool _cached_get (hb_codepoint_t unicode, + hb_codepoint_t *glyph, + cache_t *cache) const + { + unsigned v; + if (cache && cache->get (unicode, &v)) + { + *glyph = v; + return true; + } + bool ret = this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph); + + if (cache && ret) + cache->set (unicode, *glyph); + return ret; + } + bool get_nominal_glyph (hb_codepoint_t unicode, - hb_codepoint_t *glyph) const + hb_codepoint_t *glyph, + cache_t *cache = nullptr) const { - if (unlikely (!this->get_glyph_funcZ)) return false; - return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph); + if (unlikely (!this->get_glyph_funcZ)) return 0; + return _cached_get (unicode, glyph, cache); } + unsigned int get_nominal_glyphs (unsigned int count, const hb_codepoint_t *first_unicode, unsigned int unicode_stride, hb_codepoint_t *first_glyph, - unsigned int glyph_stride) const + unsigned int glyph_stride, + cache_t *cache = nullptr) const { if (unlikely (!this->get_glyph_funcZ)) return 0; - hb_cmap_get_glyph_func_t get_glyph_funcZ = this->get_glyph_funcZ; - const void *get_glyph_data = this->get_glyph_data; - unsigned int done; for (done = 0; - done < count && get_glyph_funcZ (get_glyph_data, *first_unicode, first_glyph); + done < count && _cached_get (*first_unicode, first_glyph, cache); done++) { first_unicode = &StructAtOffsetUnaligned (first_unicode, unicode_stride); @@ -1812,7 +1945,8 @@ bool get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph) const + hb_codepoint_t *glyph, + cache_t *cache = nullptr) const { switch (this->subtable_uvs->get_glyph_variant (unicode, variation_selector, @@ -1823,7 +1957,7 @@ case GLYPH_VARIANT_USE_DEFAULT: break; } - return get_nominal_glyph (unicode, glyph); + return get_nominal_glyph (unicode, glyph, cache); } void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const @@ -1928,6 +2062,19 @@ encodingRecord.sanitize (c, this)); } + private: + + static bool filter_encoding_records_for_subset(const cmap* cmap, + const EncodingRecord& _) + { + return + (_.platformID == 0 && _.encodingID == 3) || + (_.platformID == 0 && _.encodingID == 4) || + (_.platformID == 3 && _.encodingID == 1) || + (_.platformID == 3 && _.encodingID == 10) || + (cmap + _.subtable).u.format == 14; + } + protected: HBUINT16 version; /* Table version number (0). */ SortedArray16Of diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cbdt-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cbdt-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cbdt-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cbdt-table.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,997 +0,0 @@ -/* - * Copyright © 2016 Google, 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. - * - * Google Author(s): Seigo Nonaka, Calder Kitagawa - */ - -#ifndef HB_OT_COLOR_CBDT_TABLE_HH -#define HB_OT_COLOR_CBDT_TABLE_HH - -#include "hb-open-type.hh" - -/* - * CBLC -- Color Bitmap Location - * https://docs.microsoft.com/en-us/typography/opentype/spec/cblc - * https://docs.microsoft.com/en-us/typography/opentype/spec/eblc - * CBDT -- Color Bitmap Data - * https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt - * https://docs.microsoft.com/en-us/typography/opentype/spec/ebdt - */ -#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C') -#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T') - - -namespace OT { - -struct cblc_bitmap_size_subset_context_t -{ - const char *cbdt; - unsigned int cbdt_length; - hb_vector_t *cbdt_prime; - unsigned int size; /* INOUT - * Input: old size of IndexSubtable - * Output: new size of IndexSubtable - */ - unsigned int num_tables; /* INOUT - * Input: old number of subtables. - * Output: new number of subtables. - */ - hb_codepoint_t start_glyph; /* OUT */ - hb_codepoint_t end_glyph; /* OUT */ -}; - -static inline bool -_copy_data_to_cbdt (hb_vector_t *cbdt_prime, - const void *data, - unsigned length) -{ - unsigned int new_len = cbdt_prime->length + length; - if (unlikely (!cbdt_prime->alloc (new_len))) return false; - memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length); - cbdt_prime->length = new_len; - return true; -} - -struct SmallGlyphMetrics -{ - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const - { - extents->x_bearing = font->em_scale_x (bearingX); - extents->y_bearing = font->em_scale_y (bearingY); - extents->width = font->em_scale_x (width); - extents->height = font->em_scale_y (-static_cast(height)); - } - - HBUINT8 height; - HBUINT8 width; - HBINT8 bearingX; - HBINT8 bearingY; - HBUINT8 advance; - public: - DEFINE_SIZE_STATIC (5); -}; - -struct BigGlyphMetrics : SmallGlyphMetrics -{ - HBINT8 vertBearingX; - HBINT8 vertBearingY; - HBUINT8 vertAdvance; - public: - DEFINE_SIZE_STATIC (8); -}; - -struct SBitLineMetrics -{ - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBINT8 ascender; - HBINT8 decender; - HBUINT8 widthMax; - HBINT8 caretSlopeNumerator; - HBINT8 caretSlopeDenominator; - HBINT8 caretOffset; - HBINT8 minOriginSB; - HBINT8 minAdvanceSB; - HBINT8 maxBeforeBL; - HBINT8 minAfterBL; - HBINT8 padding1; - HBINT8 padding2; - public: - DEFINE_SIZE_STATIC (12); -}; - - -/* - * Index Subtables. - */ - -struct IndexSubtableHeader -{ - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBUINT16 indexFormat; - HBUINT16 imageFormat; - HBUINT32 imageDataOffset; - public: - DEFINE_SIZE_STATIC (8); -}; - -template -struct IndexSubtableFormat1Or3 -{ - bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - offsetArrayZ.sanitize (c, glyph_count + 1)); - } - - bool get_image_data (unsigned int idx, - unsigned int *offset, - unsigned int *length) const - { - if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx])) - return false; - - *offset = header.imageDataOffset + offsetArrayZ[idx]; - *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx]; - return true; - } - - bool add_offset (hb_serialize_context_t *c, - unsigned int offset, - unsigned int *size /* OUT (accumulated) */) - { - TRACE_SERIALIZE (this); - Offset embedded_offset; - embedded_offset = offset; - *size += sizeof (OffsetType); - auto *o = c->embed (embedded_offset); - return_trace ((bool) o); - } - - IndexSubtableHeader header; - UnsizedArrayOf> - offsetArrayZ; - public: - DEFINE_SIZE_ARRAY (8, offsetArrayZ); -}; - -struct IndexSubtableFormat1 : IndexSubtableFormat1Or3 {}; -struct IndexSubtableFormat3 : IndexSubtableFormat1Or3 {}; - -struct IndexSubtable -{ - bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const - { - TRACE_SANITIZE (this); - if (!u.header.sanitize (c)) return_trace (false); - switch (u.header.indexFormat) - { - case 1: return_trace (u.format1.sanitize (c, glyph_count)); - case 3: return_trace (u.format3.sanitize (c, glyph_count)); - default:return_trace (true); - } - } - - bool - finish_subtable (hb_serialize_context_t *c, - unsigned int cbdt_prime_len, - unsigned int num_glyphs, - unsigned int *size /* OUT (accumulated) */) - { - TRACE_SERIALIZE (this); - - unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset; - switch (u.header.indexFormat) - { - case 1: return_trace (u.format1.add_offset (c, local_offset, size)); - case 3: { - if (!u.format3.add_offset (c, local_offset, size)) - return_trace (false); - if (!(num_glyphs & 0x01)) // Pad to 32-bit alignment if needed. - return_trace (u.format3.add_offset (c, 0, size)); - return_trace (true); - } - // TODO: implement 2, 4, 5. - case 2: case 4: // No-op. - case 5: // Pad to 32-bit aligned. - default: return_trace (false); - } - } - - bool - fill_missing_glyphs (hb_serialize_context_t *c, - unsigned int cbdt_prime_len, - unsigned int num_missing, - unsigned int *size /* OUT (accumulated) */, - unsigned int *num_glyphs /* OUT (accumulated) */) - { - TRACE_SERIALIZE (this); - - unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset; - switch (u.header.indexFormat) - { - case 1: { - for (unsigned int i = 0; i < num_missing; i++) - { - if (unlikely (!u.format1.add_offset (c, local_offset, size))) - return_trace (false); - *num_glyphs += 1; - } - return_trace (true); - } - case 3: { - for (unsigned int i = 0; i < num_missing; i++) - { - if (unlikely (!u.format3.add_offset (c, local_offset, size))) - return_trace (false); - *num_glyphs += 1; - } - return_trace (true); - } - // TODO: implement 2, 4, 5. - case 2: // Add empty space in cbdt_prime?. - case 4: case 5: // No-op as sparse is supported. - default: return_trace (false); - } - } - - bool - copy_glyph_at_idx (hb_serialize_context_t *c, unsigned int idx, - const char *cbdt, unsigned int cbdt_length, - hb_vector_t *cbdt_prime /* INOUT */, - IndexSubtable *subtable_prime /* INOUT */, - unsigned int *size /* OUT (accumulated) */) const - { - TRACE_SERIALIZE (this); - - unsigned int offset, length, format; - if (unlikely (!get_image_data (idx, &offset, &length, &format))) return_trace (false); - if (unlikely (offset > cbdt_length || cbdt_length - offset < length)) return_trace (false); - - auto *header_prime = subtable_prime->get_header (); - unsigned int new_local_offset = cbdt_prime->length - (unsigned int) header_prime->imageDataOffset; - if (unlikely (!_copy_data_to_cbdt (cbdt_prime, cbdt + offset, length))) return_trace (false); - - return_trace (subtable_prime->add_offset (c, new_local_offset, size)); - } - - bool - add_offset (hb_serialize_context_t *c, unsigned int local_offset, - unsigned int *size /* OUT (accumulated) */) - { - TRACE_SERIALIZE (this); - switch (u.header.indexFormat) - { - case 1: return_trace (u.format1.add_offset (c, local_offset, size)); - case 3: return_trace (u.format3.add_offset (c, local_offset, size)); - // TODO: Implement tables 2, 4, 5 - case 2: // Should be a no-op. - case 4: case 5: // Handle sparse cases. - default: return_trace (false); - } - } - - bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const - { - switch (u.header.indexFormat) - { - case 2: case 5: /* TODO */ - case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */ - default:return (false); - } - } - - bool - get_image_data (unsigned int idx, unsigned int *offset, - unsigned int *length, unsigned int *format) const - { - *format = u.header.imageFormat; - switch (u.header.indexFormat) - { - case 1: return u.format1.get_image_data (idx, offset, length); - case 3: return u.format3.get_image_data (idx, offset, length); - default: return false; - } - } - - const IndexSubtableHeader* get_header () const { return &u.header; } - - void populate_header (unsigned index_format, - unsigned image_format, - unsigned int image_data_offset, - unsigned int *size) - { - u.header.indexFormat = index_format; - u.header.imageFormat = image_format; - u.header.imageDataOffset = image_data_offset; - switch (u.header.indexFormat) - { - case 1: *size += IndexSubtableFormat1::min_size; break; - case 3: *size += IndexSubtableFormat3::min_size; break; - } - } - - protected: - union { - IndexSubtableHeader header; - IndexSubtableFormat1 format1; - IndexSubtableFormat3 format3; - /* TODO: Format 2, 4, 5. */ - } u; - public: - DEFINE_SIZE_UNION (8, header); -}; - -struct IndexSubtableRecord -{ - /* XXX Remove this and fix by not inserting it into vector. */ - IndexSubtableRecord& operator = (const IndexSubtableRecord &o) - { - firstGlyphIndex = o.firstGlyphIndex; - lastGlyphIndex = o.lastGlyphIndex; - offsetToSubtable = (unsigned) o.offsetToSubtable; - assert (offsetToSubtable.is_null ()); - return *this; - } - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - firstGlyphIndex <= lastGlyphIndex && - offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1)); - } - - const IndexSubtable* get_subtable (const void *base) const - { - return &(base+offsetToSubtable); - } - - bool add_new_subtable (hb_subset_context_t* c, - cblc_bitmap_size_subset_context_t *bitmap_size_context, - IndexSubtableRecord *record, - const hb_vector_t> *lookup, /* IN */ - const void *base, - unsigned int *start /* INOUT */) const - { - 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); - auto *old_header = old_subtable->get_header (); - - subtable->populate_header (old_header->indexFormat, - old_header->imageFormat, - bitmap_size_context->cbdt_prime->length, - &bitmap_size_context->size); - - unsigned int num_glyphs = 0; - bool early_exit = false; - for (unsigned int i = *start; i < lookup->length; i++) - { - hb_codepoint_t new_gid = (*lookup)[i].first; - const IndexSubtableRecord *next_record = (*lookup)[i].second; - const IndexSubtable *next_subtable = next_record->get_subtable (base); - auto *next_header = next_subtable->get_header (); - if (next_header != old_header) - { - *start = i; - early_exit = true; - break; - } - unsigned int num_missing = record->add_glyph_for_subset (new_gid); - if (unlikely (!subtable->fill_missing_glyphs (c->serializer, - bitmap_size_context->cbdt_prime->length, - num_missing, - &bitmap_size_context->size, - &num_glyphs))) - return_trace (false); - - hb_codepoint_t old_gid = 0; - c->plan->old_gid_for_new_gid (new_gid, &old_gid); - if (old_gid < next_record->firstGlyphIndex) - return_trace (false); - - unsigned int old_idx = (unsigned int) old_gid - next_record->firstGlyphIndex; - if (unlikely (!next_subtable->copy_glyph_at_idx (c->serializer, - old_idx, - bitmap_size_context->cbdt, - bitmap_size_context->cbdt_length, - bitmap_size_context->cbdt_prime, - subtable, - &bitmap_size_context->size))) - return_trace (false); - num_glyphs += 1; - } - if (!early_exit) - *start = lookup->length; - if (unlikely (!subtable->finish_subtable (c->serializer, - bitmap_size_context->cbdt_prime->length, - num_glyphs, - &bitmap_size_context->size))) - return_trace (false); - return_trace (true); - } - - bool add_new_record (hb_subset_context_t *c, - cblc_bitmap_size_subset_context_t *bitmap_size_context, - const hb_vector_t> *lookup, /* IN */ - const void *base, - unsigned int *start, /* INOUT */ - hb_vector_t* records /* INOUT */) const - { - TRACE_SERIALIZE (this); - auto snap = c->serializer->snapshot (); - unsigned int old_size = bitmap_size_context->size; - unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length; - - // Set to invalid state to indicate filling glyphs is not yet started. - if (unlikely (!c->serializer->check_success (records->resize (records->length + 1)))) - return_trace (false); - - (*records)[records->length - 1].firstGlyphIndex = 1; - (*records)[records->length - 1].lastGlyphIndex = 0; - bitmap_size_context->size += IndexSubtableRecord::min_size; - - c->serializer->push (); - - if (unlikely (!add_new_subtable (c, bitmap_size_context, &((*records)[records->length - 1]), lookup, base, start))) - { - c->serializer->pop_discard (); - c->serializer->revert (snap); - bitmap_size_context->cbdt_prime->shrink (old_cbdt_prime_length); - bitmap_size_context->size = old_size; - records->resize (records->length - 1); - return_trace (false); - } - - bitmap_size_context->num_tables += 1; - return_trace (true); - } - - unsigned int add_glyph_for_subset (hb_codepoint_t gid) - { - if (firstGlyphIndex > lastGlyphIndex) - { - firstGlyphIndex = gid; - lastGlyphIndex = gid; - return 0; - } - // TODO maybe assert? this shouldn't occur. - if (lastGlyphIndex > gid) - return 0; - unsigned int num_missing = (unsigned int) (gid - lastGlyphIndex - 1); - lastGlyphIndex = gid; - return num_missing; - } - - bool get_extents (hb_glyph_extents_t *extents, const void *base) const - { return (base+offsetToSubtable).get_extents (extents); } - - bool get_image_data (unsigned int gid, - const void *base, - unsigned int *offset, - unsigned int *length, - unsigned int *format) const - { - if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false; - return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex, - offset, length, format); - } - - HBGlyphID16 firstGlyphIndex; - HBGlyphID16 lastGlyphIndex; - Offset32To offsetToSubtable; - public: - DEFINE_SIZE_STATIC (8); -}; - -struct IndexSubtableArray -{ - friend struct CBDT; - - bool sanitize (hb_sanitize_context_t *c, unsigned int count) const - { - TRACE_SANITIZE (this); - return_trace (indexSubtablesZ.sanitize (c, count, this)); - } - - void - build_lookup (hb_subset_context_t *c, cblc_bitmap_size_subset_context_t *bitmap_size_context, - hb_vector_t> *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++) - { - hb_codepoint_t old_gid; - if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue; - - const IndexSubtableRecord* record = find_table (old_gid, bitmap_size_context->num_tables); - if (unlikely (!record)) continue; - - // Don't add gaps to the lookup. The best way to determine if a glyph is a - // gap is that it has no image data. - unsigned int offset, length, format; - if (unlikely (!record->get_image_data (old_gid, this, &offset, &length, &format))) continue; - - lookup->push (hb_pair_t (new_gid, record)); - - if (!start_glyph_is_set) - { - bitmap_size_context->start_glyph = new_gid; - start_glyph_is_set = true; - } - - bitmap_size_context->end_glyph = new_gid; - } - } - - bool - subset (hb_subset_context_t *c, - cblc_bitmap_size_subset_context_t *bitmap_size_context) const - { - 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))) - return false; - - bitmap_size_context->size = 0; - bitmap_size_context->num_tables = 0; - hb_vector_t records; - for (unsigned int start = 0; start < lookup.length;) - { - if (unlikely (!lookup[start].second->add_new_record (c, bitmap_size_context, &lookup, this, &start, &records))) - { - // Discard any leftover pushes to the serializer from successful records. - for (unsigned int i = 0; i < records.length; i++) - c->serializer->pop_discard (); - return_trace (false); - } - } - - /* Workaround to ensure offset ordering is from least to greatest when - * resolving links. */ - hb_vector_t objidxs; - for (unsigned int i = 0; i < records.length; i++) - objidxs.push (c->serializer->pop_pack ()); - for (unsigned int i = 0; i < records.length; i++) - { - IndexSubtableRecord* record = c->serializer->embed (records[i]); - if (unlikely (!record)) return_trace (false); - c->serializer->add_link (record->offsetToSubtable, objidxs[records.length - 1 - i]); - } - return_trace (true); - } - - public: - const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const - { - for (unsigned int i = 0; i < numTables; ++i) - { - unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex; - unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex; - if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) - return &indexSubtablesZ[i]; - } - return nullptr; - } - - protected: - UnsizedArrayOf indexSubtablesZ; -}; - -struct BitmapSizeTable -{ - friend struct CBLC; - friend struct CBDT; - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && - horizontal.sanitize (c) && - vertical.sanitize (c)); - } - - const IndexSubtableRecord * - find_table (hb_codepoint_t glyph, const void *base, const void **out_base) const - { - *out_base = &(base+indexSubtableArrayOffset); - return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables); - } - - bool - subset (hb_subset_context_t *c, const void *base, - const char *cbdt, unsigned int cbdt_length, - hb_vector_t *cbdt_prime /* INOUT */) const - { - TRACE_SUBSET (this); - auto *out_table = c->serializer->embed (this); - if (unlikely (!out_table)) return_trace (false); - - cblc_bitmap_size_subset_context_t bitmap_size_context; - bitmap_size_context.cbdt = cbdt; - bitmap_size_context.cbdt_length = cbdt_length; - bitmap_size_context.cbdt_prime = cbdt_prime; - bitmap_size_context.size = indexTablesSize; - bitmap_size_context.num_tables = numberOfIndexSubtables; - bitmap_size_context.start_glyph = 1; - bitmap_size_context.end_glyph = 0; - - if (!out_table->indexSubtableArrayOffset.serialize_subset (c, - indexSubtableArrayOffset, - base, - &bitmap_size_context)) - return_trace (false); - if (!bitmap_size_context.size || - !bitmap_size_context.num_tables || - bitmap_size_context.start_glyph > bitmap_size_context.end_glyph) - return_trace (false); - - out_table->indexTablesSize = bitmap_size_context.size; - out_table->numberOfIndexSubtables = bitmap_size_context.num_tables; - out_table->startGlyphIndex = bitmap_size_context.start_glyph; - out_table->endGlyphIndex = bitmap_size_context.end_glyph; - return_trace (true); - } - - protected: - NNOffset32To - indexSubtableArrayOffset; - HBUINT32 indexTablesSize; - HBUINT32 numberOfIndexSubtables; - HBUINT32 colorRef; - SBitLineMetrics horizontal; - SBitLineMetrics vertical; - HBGlyphID16 startGlyphIndex; - HBGlyphID16 endGlyphIndex; - HBUINT8 ppemX; - HBUINT8 ppemY; - HBUINT8 bitDepth; - HBINT8 flags; - public: - DEFINE_SIZE_STATIC (48); -}; - - -/* - * Glyph Bitmap Data Formats. - */ - -struct GlyphBitmapDataFormat17 -{ - SmallGlyphMetrics glyphMetrics; - Array32Of data; - public: - DEFINE_SIZE_ARRAY (9, data); -}; - -struct GlyphBitmapDataFormat18 -{ - BigGlyphMetrics glyphMetrics; - Array32Of data; - public: - DEFINE_SIZE_ARRAY (12, data); -}; - -struct GlyphBitmapDataFormat19 -{ - Array32Of data; - public: - DEFINE_SIZE_ARRAY (4, data); -}; - -struct CBLC -{ - friend struct CBDT; - - static constexpr hb_tag_t tableTag = HB_OT_TAG_CBLC; - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version.major == 2 || version.major == 3) && - sizeTables.sanitize (c, this)); - } - - static bool - sink_cbdt (hb_subset_context_t *c, hb_vector_t* cbdt_prime) - { - hb_blob_t *cbdt_prime_blob = hb_blob_create (cbdt_prime->arrayZ, - cbdt_prime->length, - HB_MEMORY_MODE_WRITABLE, - cbdt_prime->arrayZ, - hb_free); - cbdt_prime->init (); // Leak arrayZ to the blob. - bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob); - hb_blob_destroy (cbdt_prime_blob); - return ret; - } - - bool - subset_size_table (hb_subset_context_t *c, const BitmapSizeTable& table, - const char *cbdt /* IN */, unsigned int cbdt_length, - CBLC *cblc_prime /* INOUT */, hb_vector_t *cbdt_prime /* INOUT */) const - { - TRACE_SUBSET (this); - cblc_prime->sizeTables.len++; - - auto snap = c->serializer->snapshot (); - auto cbdt_prime_len = cbdt_prime->length; - - if (!table.subset (c, this, cbdt, cbdt_length, cbdt_prime)) - { - cblc_prime->sizeTables.len--; - c->serializer->revert (snap); - cbdt_prime->shrink (cbdt_prime_len); - return_trace (false); - } - return_trace (true); - } - - // Implemented in cc file as it depends on definition of CBDT. - HB_INTERNAL bool subset (hb_subset_context_t *c) const; - - protected: - const BitmapSizeTable &choose_strike (hb_font_t *font) const - { - unsigned count = sizeTables.len; - if (unlikely (!count)) - return Null (BitmapSizeTable); - - unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem); - if (!requested_ppem) - requested_ppem = 1<<30; /* Choose largest strike. */ - unsigned int best_i = 0; - unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY); - - for (unsigned int i = 1; i < count; i++) - { - unsigned int ppem = hb_max (sizeTables[i].ppemX, sizeTables[i].ppemY); - if ((requested_ppem <= ppem && ppem < best_ppem) || - (requested_ppem > best_ppem && ppem > best_ppem)) - { - best_i = i; - best_ppem = ppem; - } - } - - return sizeTables[best_i]; - } - - protected: - FixedVersion<> version; - Array32Of sizeTables; - public: - DEFINE_SIZE_ARRAY (8, sizeTables); -}; - -struct CBDT -{ - static constexpr hb_tag_t tableTag = HB_OT_TAG_CBDT; - - struct accelerator_t - { - accelerator_t (hb_face_t *face) - { - this->cblc = hb_sanitize_context_t ().reference_table (face); - this->cbdt = hb_sanitize_context_t ().reference_table (face); - - upem = hb_face_get_upem (face); - } - ~accelerator_t () - { - this->cblc.destroy (); - this->cbdt.destroy (); - } - - bool - get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const - { - const void *base; - const BitmapSizeTable &strike = this->cblc->choose_strike (font); - const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); - if (!subtable_record || !strike.ppemX || !strike.ppemY) - return false; - - if (subtable_record->get_extents (extents, base)) - return true; - - unsigned int image_offset = 0, image_length = 0, image_format = 0; - if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format)) - return false; - - unsigned int cbdt_len = cbdt.get_length (); - if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) - return false; - - switch (image_format) - { - case 17: { - if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) - return false; - auto &glyphFormat17 = StructAtOffset (this->cbdt, image_offset); - glyphFormat17.glyphMetrics.get_extents (font, extents); - break; - } - case 18: { - if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) - return false; - auto &glyphFormat18 = StructAtOffset (this->cbdt, image_offset); - glyphFormat18.glyphMetrics.get_extents (font, extents); - break; - } - default: return false; /* TODO: Support other image formats. */ - } - - /* Convert to font units. */ - float x_scale = upem / (float) strike.ppemX; - float y_scale = upem / (float) strike.ppemY; - extents->x_bearing = roundf (extents->x_bearing * x_scale); - extents->y_bearing = roundf (extents->y_bearing * y_scale); - extents->width = roundf (extents->width * x_scale); - extents->height = roundf (extents->height * y_scale); - - return true; - } - - hb_blob_t* - reference_png (hb_font_t *font, hb_codepoint_t glyph) const - { - const void *base; - const BitmapSizeTable &strike = this->cblc->choose_strike (font); - const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); - if (!subtable_record || !strike.ppemX || !strike.ppemY) - return hb_blob_get_empty (); - - unsigned int image_offset = 0, image_length = 0, image_format = 0; - if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format)) - return hb_blob_get_empty (); - - unsigned int cbdt_len = cbdt.get_length (); - if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) - return hb_blob_get_empty (); - - switch (image_format) - { - case 17: - { - if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) - return hb_blob_get_empty (); - auto &glyphFormat17 = StructAtOffset (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt.get_blob (), - image_offset + GlyphBitmapDataFormat17::min_size, - glyphFormat17.data.len); - } - case 18: - { - if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) - return hb_blob_get_empty (); - auto &glyphFormat18 = StructAtOffset (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt.get_blob (), - image_offset + GlyphBitmapDataFormat18::min_size, - glyphFormat18.data.len); - } - case 19: - { - if (unlikely (image_length < GlyphBitmapDataFormat19::min_size)) - return hb_blob_get_empty (); - auto &glyphFormat19 = StructAtOffset (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt.get_blob (), - image_offset + GlyphBitmapDataFormat19::min_size, - glyphFormat19.data.len); - } - default: return hb_blob_get_empty (); /* TODO: Support other image formats. */ - } - } - - bool has_data () const { return cbdt.get_length (); } - - private: - hb_blob_ptr_t cblc; - hb_blob_ptr_t cbdt; - - unsigned int upem; - }; - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version.major == 2 || version.major == 3)); - } - - protected: - FixedVersion<> version; - UnsizedArrayOf dataZ; - public: - DEFINE_SIZE_ARRAY (4, dataZ); -}; - -inline bool -CBLC::subset (hb_subset_context_t *c) const -{ - 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); - if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false); - cblc_prime->version = version; - - hb_blob_t* cbdt_blob = hb_sanitize_context_t ().reference_table (c->plan->source); - unsigned int cbdt_length; - CBDT* cbdt = (CBDT *) hb_blob_get_data (cbdt_blob, &cbdt_length); - if (unlikely (cbdt_length < CBDT::min_size)) - { - hb_blob_destroy (cbdt_blob); - return_trace (false); - } - _copy_data_to_cbdt (&cbdt_prime, cbdt, CBDT::min_size); - - for (const BitmapSizeTable& table : + sizeTables.iter ()) - subset_size_table (c, table, (const char *) cbdt, cbdt_length, cblc_prime, &cbdt_prime); - - hb_blob_destroy (cbdt_blob); - - return_trace (CBLC::sink_cbdt (c, &cbdt_prime)); -} - -struct CBDT_accelerator_t : CBDT::accelerator_t { - CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {} -}; - - -} /* namespace OT */ - -#endif /* HB_OT_COLOR_CBDT_TABLE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc 2023-07-05 07:11:54.000000000 +0000 @@ -31,11 +31,11 @@ #include "hb-ot.h" -#include "hb-ot-color-cbdt-table.hh" -#include "hb-ot-color-colr-table.hh" -#include "hb-ot-color-cpal-table.hh" -#include "hb-ot-color-sbix-table.hh" -#include "hb-ot-color-svg-table.hh" +#include "OT/Color/CBDT/CBDT.hh" +#include "OT/Color/COLR/COLR.hh" +#include "OT/Color/CPAL/CPAL.hh" +#include "OT/Color/sbix/sbix.hh" +#include "OT/Color/svg/svg.hh" /** @@ -61,7 +61,7 @@ * * Tests whether a face includes a `CPAL` color-palette table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ @@ -167,6 +167,10 @@ * for allocating a buffer of suitable size before calling * hb_ot_color_palette_get_colors() a second time. * + * The RGBA values in the palette are unpremultiplied. See the + * OpenType spec [CPAL](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal) + * section for details. + * * Return value: the total number of colors in the palette * * Since: 2.1.0 @@ -190,16 +194,53 @@ * hb_ot_color_has_layers: * @face: #hb_face_t to work upon * - * Tests whether a face includes any `COLR` color layers. + * Tests whether a face includes a `COLR` table + * with data according to COLRv0. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ hb_bool_t hb_ot_color_has_layers (hb_face_t *face) { - return face->table.COLR->has_data (); + return face->table.COLR->has_v0_data (); +} + +/** + * hb_ot_color_has_paint: + * @face: #hb_face_t to work upon + * + * Tests where a face includes a `COLR` table + * with data according to COLRv1. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 7.0.0 + */ +hb_bool_t +hb_ot_color_has_paint (hb_face_t *face) +{ + return face->table.COLR->has_v1_data (); +} + +/** + * hb_ot_color_glyph_has_paint: + * @face: #hb_face_t to work upon + * @glyph: The glyph index to query + * + * Tests where a face includes COLRv1 paint + * data for @glyph. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 7.0.0 + */ +hb_bool_t +hb_ot_color_glyph_has_paint (hb_face_t *face, + hb_codepoint_t glyph) +{ + return face->table.COLR->has_paint_for_glyph (glyph); } /** @@ -239,7 +280,7 @@ * * Tests whether a face includes any `SVG` glyph images. * - * Return value: %true if data found, %false otherwise. + * Return value: `true` if data found, `false` otherwise. * * Since: 2.1.0 */ @@ -279,7 +320,7 @@ * * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ @@ -295,8 +336,8 @@ * @glyph: a glyph index * * Fetches the PNG image for a glyph. This function takes a font object, not a face object, - * as input. To get an optimally sized PNG blob, the UPEM value must be set on the @font - * object. If UPEM is unset, the blob returned will be the largest PNG available. + * as input. To get an optimally sized PNG blob, the PPEM values must be set on the @font + * object. If PPEM is unset, the blob returned will be the largest PNG available. * * If the glyph has no PNG image, the singleton empty blob is returned. * diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colr-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colr-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colr-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colr-table.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,1541 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * Copyright © 2020 Google, 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. - * - * Google Author(s): Calder Kitagawa - */ - -#ifndef HB_OT_COLOR_COLR_TABLE_HH -#define HB_OT_COLOR_COLR_TABLE_HH - -#include "hb-open-type.hh" -#include "hb-ot-layout-common.hh" -#include "hb-ot-var-common.hh" - -/* - * COLR -- Color - * https://docs.microsoft.com/en-us/typography/opentype/spec/colr - */ -#define HB_OT_TAG_COLR HB_TAG('C','O','L','R') - -#ifndef HB_COLRV1_MAX_NESTING_LEVEL -#define HB_COLRV1_MAX_NESTING_LEVEL 100 -#endif - -#ifndef COLRV1_ENABLE_SUBSETTING -#define COLRV1_ENABLE_SUBSETTING 1 -#endif - -namespace OT { - -struct COLR; -struct hb_colrv1_closure_context_t : - hb_dispatch_context_t -{ - template - return_t dispatch (const T &obj) - { - if (unlikely (nesting_level_left == 0)) - return hb_empty_t (); - - if (paint_visited (&obj)) - return hb_empty_t (); - - nesting_level_left--; - obj.closurev1 (this); - nesting_level_left++; - return hb_empty_t (); - } - static return_t default_return_value () { return hb_empty_t (); } - - bool paint_visited (const void *paint) - { - hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base); - if (visited_paint.in_error() || visited_paint.has (delta)) - return true; - - visited_paint.add (delta); - return false; - } - - const COLR* get_colr_table () const - { return reinterpret_cast (base); } - - void add_glyph (unsigned glyph_id) - { glyphs->add (glyph_id); } - - void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers) - { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); } - - void add_palette_index (unsigned palette_index) - { palette_indices->add (palette_index); } - - public: - const void *base; - hb_set_t visited_paint; - hb_set_t *glyphs; - hb_set_t *layer_indices; - hb_set_t *palette_indices; - unsigned nesting_level_left; - - hb_colrv1_closure_context_t (const void *base_, - hb_set_t *glyphs_, - hb_set_t *layer_indices_, - hb_set_t *palette_indices_, - unsigned nesting_level_left_ = HB_COLRV1_MAX_NESTING_LEVEL) : - base (base_), - glyphs (glyphs_), - layer_indices (layer_indices_), - palette_indices (palette_indices_), - nesting_level_left (nesting_level_left_) - {} -}; - -struct LayerRecord -{ - operator hb_ot_color_layer_t () const { return {glyphId, colorIdx}; } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - public: - HBGlyphID16 glyphId; /* Glyph ID of layer glyph */ - Index colorIdx; /* Index value to use with a - * selected color palette. - * An index value of 0xFFFF - * is a special case indicating - * that the text foreground - * color (defined by a - * higher-level client) should - * be used and shall not be - * treated as actual index - * into CPAL ColorRecord array. */ - public: - DEFINE_SIZE_STATIC (4); -}; - -struct BaseGlyphRecord -{ - int cmp (hb_codepoint_t g) const - { return g < glyphId ? -1 : g > glyphId ? 1 : 0; } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); - } - - public: - HBGlyphID16 glyphId; /* Glyph ID of reference glyph */ - HBUINT16 firstLayerIdx; /* Index (from beginning of - * the Layer Records) to the - * layer record. There will be - * numLayers consecutive entries - * for this base glyph. */ - HBUINT16 numLayers; /* Number of color layers - * associated with this glyph */ - public: - DEFINE_SIZE_STATIC (6); -}; - -template -struct Variable -{ - Variable* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - return_trace (c->embed (this)); - } - - void closurev1 (hb_colrv1_closure_context_t* c) const - { value.closurev1 (c); } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - if (!value.subset (c)) return_trace (false); - return_trace (c->serializer->embed (varIdxBase)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && value.sanitize (c)); - } - - protected: - T value; - VarIdx varIdxBase; - public: - DEFINE_SIZE_STATIC (4 + T::static_size); -}; - -template -struct NoVariable -{ - NoVariable* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - return_trace (c->embed (this)); - } - - void closurev1 (hb_colrv1_closure_context_t* c) const - { value.closurev1 (c); } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - return_trace (value.subset (c)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && value.sanitize (c)); - } - - T value; - public: - DEFINE_SIZE_STATIC (T::static_size); -}; - -// Color structures - -struct ColorStop -{ - void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - F2DOT14 stopOffset; - HBUINT16 paletteIndex; - F2DOT14 alpha; - public: - DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size); -}; - -struct Extend : HBUINT8 -{ - enum { - EXTEND_PAD = 0, - EXTEND_REPEAT = 1, - EXTEND_REFLECT = 2, - }; - public: - DEFINE_SIZE_STATIC (1); -}; - -template class Var> -struct ColorLine -{ - void closurev1 (hb_colrv1_closure_context_t* c) const - { - for (const auto &stop : stops.iter ()) - stop.closurev1 (c); - } - - 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 (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); - if (!c->serializer->check_assign (out->stops.len, stops.len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)) return_trace (false); - - for (const auto& stop : stops.iter ()) - { - if (!stop.subset (c)) return_trace (false); - } - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - stops.sanitize (c)); - } - - Extend extend; - Array16Of> stops; - public: - DEFINE_SIZE_ARRAY_SIZED (3, stops); -}; - -// Composition modes - -// Compositing modes are taken from https://www.w3.org/TR/compositing-1/ -// NOTE: a brief audit of major implementations suggests most support most -// or all of the specified modes. -struct CompositeMode : HBUINT8 -{ - enum { - // Porter-Duff modes - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators - COMPOSITE_CLEAR = 0, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_clear - COMPOSITE_SRC = 1, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_src - COMPOSITE_DEST = 2, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dst - COMPOSITE_SRC_OVER = 3, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcover - COMPOSITE_DEST_OVER = 4, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstover - COMPOSITE_SRC_IN = 5, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin - COMPOSITE_DEST_IN = 6, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin - COMPOSITE_SRC_OUT = 7, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout - COMPOSITE_DEST_OUT = 8, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout - COMPOSITE_SRC_ATOP = 9, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop - COMPOSITE_DEST_ATOP = 10, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop - COMPOSITE_XOR = 11, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor - COMPOSITE_PLUS = 12, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_plus - - // Blend modes - // https://www.w3.org/TR/compositing-1/#blending - COMPOSITE_SCREEN = 13, // https://www.w3.org/TR/compositing-1/#blendingscreen - COMPOSITE_OVERLAY = 14, // https://www.w3.org/TR/compositing-1/#blendingoverlay - COMPOSITE_DARKEN = 15, // https://www.w3.org/TR/compositing-1/#blendingdarken - COMPOSITE_LIGHTEN = 16, // https://www.w3.org/TR/compositing-1/#blendinglighten - COMPOSITE_COLOR_DODGE = 17, // https://www.w3.org/TR/compositing-1/#blendingcolordodge - COMPOSITE_COLOR_BURN = 18, // https://www.w3.org/TR/compositing-1/#blendingcolorburn - COMPOSITE_HARD_LIGHT = 19, // https://www.w3.org/TR/compositing-1/#blendinghardlight - COMPOSITE_SOFT_LIGHT = 20, // https://www.w3.org/TR/compositing-1/#blendingsoftlight - COMPOSITE_DIFFERENCE = 21, // https://www.w3.org/TR/compositing-1/#blendingdifference - COMPOSITE_EXCLUSION = 22, // https://www.w3.org/TR/compositing-1/#blendingexclusion - COMPOSITE_MULTIPLY = 23, // https://www.w3.org/TR/compositing-1/#blendingmultiply - - // Modes that, uniquely, do not operate on components - // https://www.w3.org/TR/compositing-1/#blendingnonseparable - COMPOSITE_HSL_HUE = 24, // https://www.w3.org/TR/compositing-1/#blendinghue - COMPOSITE_HSL_SATURATION = 25, // https://www.w3.org/TR/compositing-1/#blendingsaturation - COMPOSITE_HSL_COLOR = 26, // https://www.w3.org/TR/compositing-1/#blendingcolor - COMPOSITE_HSL_LUMINOSITY = 27, // https://www.w3.org/TR/compositing-1/#blendingluminosity - }; - public: - DEFINE_SIZE_STATIC (1); -}; - -struct Affine2x3 -{ - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBFixed xx; - HBFixed yx; - HBFixed xy; - HBFixed yy; - HBFixed dx; - HBFixed dy; - public: - DEFINE_SIZE_STATIC (6 * HBFixed::static_size); -}; - -struct PaintColrLayers -{ - void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers->get (firstLayerIndex), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); - - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBUINT8 format; /* format = 1 */ - HBUINT8 numLayers; - HBUINT32 firstLayerIndex; /* index into COLRv1::layerList */ - public: - DEFINE_SIZE_STATIC (6); -}; - -struct PaintSolid -{ - void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ - HBUINT16 paletteIndex; - F2DOT14 alpha; - public: - DEFINE_SIZE_STATIC (3 + F2DOT14::static_size); -}; - -template class Var> -struct PaintLinearGradient -{ - void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->colorLine.serialize_subset (c, colorLine, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); - } - - HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ - Offset24To> colorLine; /* Offset (from beginning of PaintLinearGradient - * table) to ColorLine subtable. */ - FWORD x0; - FWORD y0; - FWORD x1; - FWORD y1; - FWORD x2; - FWORD y2; - public: - DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size); -}; - -template class Var> -struct PaintRadialGradient -{ - void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->colorLine.serialize_subset (c, colorLine, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); - } - - HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ - Offset24To> colorLine; /* Offset (from beginning of PaintRadialGradient - * table) to ColorLine subtable. */ - FWORD x0; - FWORD y0; - UFWORD radius0; - FWORD x1; - FWORD y1; - UFWORD radius1; - public: - DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size); -}; - -template class Var> -struct PaintSweepGradient -{ - void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->colorLine.serialize_subset (c, colorLine, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); - } - - HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ - Offset24To> colorLine; /* Offset (from beginning of PaintSweepGradient - * table) to ColorLine subtable. */ - FWORD centerX; - FWORD centerY; - F2DOT14 startAngle; - F2DOT14 endAngle; - public: - DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size); -}; - -struct Paint; -// Paint a non-COLR glyph, filled as indicated by paint. -struct PaintGlyph -{ - void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - if (! c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid), - HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); - - return_trace (out->paint.serialize_subset (c, paint, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && paint.sanitize (c, this)); - } - - HBUINT8 format; /* format = 10 */ - Offset24To paint; /* Offset (from beginning of PaintGlyph table) to Paint subtable. */ - HBUINT16 gid; - public: - DEFINE_SIZE_STATIC (6); -}; - -struct PaintColrGlyph -{ - void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBUINT8 format; /* format = 11 */ - HBUINT16 gid; - public: - DEFINE_SIZE_STATIC (3); -}; - -template class Var> -struct PaintTransform -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - src.sanitize (c, this) && - transform.sanitize (c, this)); - } - - HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ - Offset24To src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */ - Offset24To> transform; - public: - DEFINE_SIZE_STATIC (7); -}; - -struct PaintTranslate -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ - Offset24To src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */ - FWORD dx; - FWORD dy; - public: - DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size); -}; - -struct PaintScale -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ - Offset24To src; /* Offset (from beginning of PaintScale table) to Paint subtable. */ - F2DOT14 scaleX; - F2DOT14 scaleY; - public: - DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size); -}; - -struct PaintScaleAroundCenter -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ - Offset24To src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */ - F2DOT14 scaleX; - F2DOT14 scaleY; - FWORD centerX; - FWORD centerY; - public: - DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size); -}; - -struct PaintScaleUniform -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ - Offset24To src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */ - F2DOT14 scale; - public: - DEFINE_SIZE_STATIC (4 + F2DOT14::static_size); -}; - -struct PaintScaleUniformAroundCenter -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ - Offset24To src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */ - F2DOT14 scale; - FWORD centerX; - FWORD centerY; - public: - DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size); -}; - -struct PaintRotate -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ - Offset24To src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */ - F2DOT14 angle; - public: - DEFINE_SIZE_STATIC (4 + F2DOT14::static_size); -}; - -struct PaintRotateAroundCenter -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ - Offset24To src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */ - F2DOT14 angle; - FWORD centerX; - FWORD centerY; - public: - DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size); -}; - -struct PaintSkew -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ - Offset24To src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */ - F2DOT14 xSkewAngle; - F2DOT14 ySkewAngle; - public: - DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size); -}; - -struct PaintSkewAroundCenter -{ - HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - return_trace (out->src.serialize_subset (c, src, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); - } - - HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ - Offset24To src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */ - F2DOT14 xSkewAngle; - F2DOT14 ySkewAngle; - FWORD centerX; - FWORD centerY; - public: - DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size); -}; - -struct PaintComposite -{ - void closurev1 (hb_colrv1_closure_context_t* c) const; - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - - if (!out->src.serialize_subset (c, src, this)) return_trace (false); - return_trace (out->backdrop.serialize_subset (c, backdrop, this)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - src.sanitize (c, this) && - backdrop.sanitize (c, this)); - } - - HBUINT8 format; /* format = 32 */ - Offset24To src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */ - CompositeMode mode; /* If mode is unrecognized use COMPOSITE_CLEAR */ - Offset24To backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */ - public: - DEFINE_SIZE_STATIC (8); -}; - -struct ClipBoxFormat1 -{ - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - public: - HBUINT8 format; /* format = 1(noVar) or 2(Var)*/ - FWORD xMin; - FWORD yMin; - FWORD xMax; - FWORD yMax; - public: - DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size); -}; - -struct ClipBoxFormat2 : Variable {}; - -struct ClipBox -{ - ClipBox* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - switch (u.format) { - case 1: return_trace (reinterpret_cast (c->embed (u.format1))); - case 2: return_trace (reinterpret_cast (c->embed (u.format2))); - default:return_trace (nullptr); - } - } - - template - typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const - { - TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); - default:return_trace (c->default_return_value ()); - } - } - - protected: - union { - HBUINT8 format; /* Format identifier */ - ClipBoxFormat1 format1; - ClipBoxFormat2 format2; - } u; -}; - -struct ClipRecord -{ - ClipRecord* copy (hb_serialize_context_t *c, const void *base) const - { - TRACE_SERIALIZE (this); - auto *out = c->embed (this); - if (unlikely (!out)) return_trace (nullptr); - if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr); - return_trace (out); - } - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && clipBox.sanitize (c, base)); - } - - public: - HBUINT16 startGlyphID; // first gid clip applies to - HBUINT16 endGlyphID; // last gid clip applies to, inclusive - Offset24To clipBox; // Box or VarBox - public: - DEFINE_SIZE_STATIC (7); -}; - -struct ClipList -{ - unsigned serialize_clip_records (hb_serialize_context_t *c, - const hb_set_t& gids, - const hb_map_t& gid_offset_map) const - { - TRACE_SERIALIZE (this); - if (gids.is_empty () || - gid_offset_map.get_population () != gids.get_population ()) - return_trace (0); - - unsigned count = 0; - - hb_codepoint_t start_gid= gids.get_min (); - hb_codepoint_t prev_gid = start_gid; - - unsigned offset = gid_offset_map.get (start_gid); - unsigned prev_offset = offset; - for (const hb_codepoint_t _ : gids.iter ()) - { - if (_ == start_gid) continue; - - offset = gid_offset_map.get (_); - if (_ == prev_gid + 1 && offset == prev_offset) - { - prev_gid = _; - continue; - } - - ClipRecord record; - record.startGlyphID = start_gid; - record.endGlyphID = prev_gid; - record.clipBox = prev_offset; - - if (!c->copy (record, this)) return_trace (0); - count++; - - start_gid = _; - prev_gid = _; - prev_offset = offset; - } - - //last one - { - ClipRecord record; - record.startGlyphID = start_gid; - record.endGlyphID = prev_gid; - record.clipBox = prev_offset; - if (!c->copy (record, this)) return_trace (0); - count++; - } - return_trace (count); - } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - - const hb_set_t& glyphset = *c->plan->_glyphset_colred; - const hb_map_t &glyph_map = *c->plan->glyph_map; - - hb_map_t new_gid_offset_map; - hb_set_t new_gids; - for (const ClipRecord& record : clips.iter ()) - { - unsigned start_gid = record.startGlyphID; - unsigned end_gid = record.endGlyphID; - for (unsigned gid = start_gid; gid <= end_gid; gid++) - { - if (!glyphset.has (gid) || !glyph_map.has (gid)) continue; - unsigned new_gid = glyph_map.get (gid); - new_gid_offset_map.set (new_gid, record.clipBox); - new_gids.add (new_gid); - } - } - - unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map); - if (!count) return_trace (false); - return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && clips.sanitize (c, this)); - } - - HBUINT8 format; // Set to 1. - Array32Of clips; // Clip records, sorted by startGlyphID - public: - DEFINE_SIZE_ARRAY_SIZED (5, clips); -}; - -struct Paint -{ - - template - bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const - { - TRACE_SANITIZE (this); - - if (unlikely (!c->check_start_recursion (HB_COLRV1_MAX_NESTING_LEVEL))) - return_trace (c->no_dispatch_return_value ()); - - return_trace (c->end_recursion (this->dispatch (c, std::forward (ds)...))); - } - - template - typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const - { - TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { - case 1: return_trace (c->dispatch (u.paintformat1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.paintformat2, std::forward (ds)...)); - case 3: return_trace (c->dispatch (u.paintformat3, std::forward (ds)...)); - case 4: return_trace (c->dispatch (u.paintformat4, std::forward (ds)...)); - case 5: return_trace (c->dispatch (u.paintformat5, std::forward (ds)...)); - case 6: return_trace (c->dispatch (u.paintformat6, std::forward (ds)...)); - case 7: return_trace (c->dispatch (u.paintformat7, std::forward (ds)...)); - case 8: return_trace (c->dispatch (u.paintformat8, std::forward (ds)...)); - case 9: return_trace (c->dispatch (u.paintformat9, std::forward (ds)...)); - case 10: return_trace (c->dispatch (u.paintformat10, std::forward (ds)...)); - case 11: return_trace (c->dispatch (u.paintformat11, std::forward (ds)...)); - case 12: return_trace (c->dispatch (u.paintformat12, std::forward (ds)...)); - case 13: return_trace (c->dispatch (u.paintformat13, std::forward (ds)...)); - case 14: return_trace (c->dispatch (u.paintformat14, std::forward (ds)...)); - case 15: return_trace (c->dispatch (u.paintformat15, std::forward (ds)...)); - case 16: return_trace (c->dispatch (u.paintformat16, std::forward (ds)...)); - case 17: return_trace (c->dispatch (u.paintformat17, std::forward (ds)...)); - case 18: return_trace (c->dispatch (u.paintformat18, std::forward (ds)...)); - case 19: return_trace (c->dispatch (u.paintformat19, std::forward (ds)...)); - case 20: return_trace (c->dispatch (u.paintformat20, std::forward (ds)...)); - case 21: return_trace (c->dispatch (u.paintformat21, std::forward (ds)...)); - case 22: return_trace (c->dispatch (u.paintformat22, std::forward (ds)...)); - case 23: return_trace (c->dispatch (u.paintformat23, std::forward (ds)...)); - case 24: return_trace (c->dispatch (u.paintformat24, std::forward (ds)...)); - case 25: return_trace (c->dispatch (u.paintformat25, std::forward (ds)...)); - case 26: return_trace (c->dispatch (u.paintformat26, std::forward (ds)...)); - case 27: return_trace (c->dispatch (u.paintformat27, std::forward (ds)...)); - case 28: return_trace (c->dispatch (u.paintformat28, std::forward (ds)...)); - case 29: return_trace (c->dispatch (u.paintformat29, std::forward (ds)...)); - case 30: return_trace (c->dispatch (u.paintformat30, std::forward (ds)...)); - case 31: return_trace (c->dispatch (u.paintformat31, std::forward (ds)...)); - case 32: return_trace (c->dispatch (u.paintformat32, std::forward (ds)...)); - default:return_trace (c->default_return_value ()); - } - } - - protected: - union { - HBUINT8 format; - PaintColrLayers paintformat1; - PaintSolid paintformat2; - Variable paintformat3; - PaintLinearGradient paintformat4; - Variable> paintformat5; - PaintRadialGradient paintformat6; - Variable> paintformat7; - PaintSweepGradient paintformat8; - Variable> paintformat9; - PaintGlyph paintformat10; - PaintColrGlyph paintformat11; - PaintTransform paintformat12; - PaintTransform paintformat13; - PaintTranslate paintformat14; - Variable paintformat15; - PaintScale paintformat16; - Variable paintformat17; - PaintScaleAroundCenter paintformat18; - Variable paintformat19; - PaintScaleUniform paintformat20; - Variable paintformat21; - PaintScaleUniformAroundCenter paintformat22; - Variable paintformat23; - PaintRotate paintformat24; - Variable paintformat25; - PaintRotateAroundCenter paintformat26; - Variable paintformat27; - PaintSkew paintformat28; - Variable paintformat29; - PaintSkewAroundCenter paintformat30; - Variable paintformat31; - PaintComposite paintformat32; - } u; -}; - -struct BaseGlyphPaintRecord -{ - int cmp (hb_codepoint_t g) const - { return g < glyphId ? -1 : g > glyphId ? 1 : 0; } - - bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map, - const void* src_base, hb_subset_context_t *c) const - { - TRACE_SERIALIZE (this); - auto *out = s->embed (this); - if (unlikely (!out)) return_trace (false); - if (!s->check_assign (out->glyphId, glyph_map->get (glyphId), - HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); - - return_trace (out->paint.serialize_subset (c, paint, src_base)); - } - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && paint.sanitize (c, base))); - } - - public: - HBGlyphID16 glyphId; /* Glyph ID of reference glyph */ - Offset32To paint; /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint, - * Typically PaintColrLayers */ - public: - DEFINE_SIZE_STATIC (6); -}; - -struct BaseGlyphList : SortedArray32Of -{ - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - const hb_set_t* glyphset = c->plan->_glyphset_colred; - - for (const auto& _ : as_array ()) - { - unsigned gid = _.glyphId; - if (!glyphset->has (gid)) continue; - - if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++; - else return_trace (false); - } - - return_trace (out->len != 0); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (SortedArray32Of::sanitize (c, this)); - } -}; - -struct LayerList : Array32OfOffset32To -{ - const Paint& get_paint (unsigned i) const - { return this+(*this)[i]; } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (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)) - return_trace (false); - } - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (Array32OfOffset32To::sanitize (c, this)); - } -}; - -struct COLR -{ - static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; - - bool has_data () const { return numBaseGlyphs; } - - unsigned int get_glyph_layers (hb_codepoint_t glyph, - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const - { - const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph); - - hb_array_t all_layers = (this+layersZ).as_array (numLayers); - hb_array_t glyph_layers = all_layers.sub_array (record.firstLayerIdx, - record.numLayers); - if (count) - { - + glyph_layers.sub_array (start_offset, count) - | hb_sink (hb_array (layers, *count)) - ; - } - return glyph_layers.length; - } - - struct accelerator_t - { - accelerator_t (hb_face_t *face) - { colr = hb_sanitize_context_t ().reference_table (face); } - ~accelerator_t () { this->colr.destroy (); } - - bool is_valid () { return colr.get_blob ()->length; } - - void closure_glyphs (hb_codepoint_t glyph, - hb_set_t *related_ids /* OUT */) const - { colr->closure_glyphs (glyph, related_ids); } - - void closure_V0palette_indices (const hb_set_t *glyphs, - hb_set_t *palettes /* OUT */) const - { colr->closure_V0palette_indices (glyphs, palettes); } - - void closure_forV1 (hb_set_t *glyphset, - hb_set_t *layer_indices, - hb_set_t *palette_indices) const - { colr->closure_forV1 (glyphset, layer_indices, palette_indices); } - - private: - hb_blob_ptr_t colr; - }; - - void closure_glyphs (hb_codepoint_t glyph, - hb_set_t *related_ids /* OUT */) const - { - const BaseGlyphRecord *record = get_base_glyph_record (glyph); - if (!record) return; - - auto glyph_layers = (this+layersZ).as_array (numLayers).sub_array (record->firstLayerIdx, - record->numLayers); - if (!glyph_layers.length) return; - related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size); - } - - void closure_V0palette_indices (const hb_set_t *glyphs, - hb_set_t *palettes /* OUT */) const - { - if (!numBaseGlyphs || !numLayers) return; - hb_array_t baseGlyphs = (this+baseGlyphsZ).as_array (numBaseGlyphs); - hb_array_t all_layers = (this+layersZ).as_array (numLayers); - - for (const BaseGlyphRecord record : baseGlyphs) - { - if (!glyphs->has (record.glyphId)) continue; - hb_array_t glyph_layers = all_layers.sub_array (record.firstLayerIdx, - record.numLayers); - for (const LayerRecord layer : glyph_layers) - palettes->add (layer.colorIdx); - } - } - - void closure_forV1 (hb_set_t *glyphset, - hb_set_t *layer_indices, - hb_set_t *palette_indices) const - { - if (version != 1) return; - hb_set_t visited_glyphs; - - hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); - const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; - - for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ()) - { - unsigned gid = baseglyph_paintrecord.glyphId; - if (!glyphset->has (gid)) continue; - - const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint; - paint.dispatch (&c); - } - hb_set_union (glyphset, &visited_glyphs); - } - - const LayerList& get_layerList () const - { return (this+layerList); } - - const BaseGlyphList& get_baseglyphList () const - { return (this+baseGlyphList); } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && - (this+layersZ).sanitize (c, numLayers) && - (version == 0 || - (COLRV1_ENABLE_SUBSETTING && version == 1 && - baseGlyphList.sanitize (c, this) && - layerList.sanitize (c, this) && - clipList.sanitize (c, this) && - varIdxMap.sanitize (c, this) && - varStore.sanitize (c, this)))); - } - - template - bool serialize_V0 (hb_serialize_context_t *c, - unsigned version, - BaseIterator base_it, - LayerIterator layer_it) - { - TRACE_SERIALIZE (this); - if (unlikely (base_it.len () != layer_it.len ())) - return_trace (false); - - this->version = version; - numLayers = 0; - numBaseGlyphs = base_it.len (); - if (numBaseGlyphs == 0) - { - baseGlyphsZ = 0; - layersZ = 0; - return_trace (true); - } - - c->push (); - for (const hb_item_type _ : + base_it.iter ()) - { - auto* record = c->embed (_); - if (unlikely (!record)) return_trace (false); - record->firstLayerIdx = numLayers; - numLayers += record->numLayers; - } - c->add_link (baseGlyphsZ, c->pop_pack ()); - - c->push (); - for (const hb_item_type& _ : + layer_it.iter ()) - _.as_array ().copy (c); - - c->add_link (layersZ, c->pop_pack ()); - - return_trace (true); - } - - const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const - { - const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid); - if (record == &Null (BaseGlyphRecord) || - (record && (hb_codepoint_t) record->glyphId != gid)) - record = nullptr; - return record; - } - - const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const - { - const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid); - if ((record && (hb_codepoint_t) record->glyphId != gid)) - record = nullptr; - return record; - } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - - const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map; - const hb_set_t& glyphset = *c->plan->_glyphset_colred; - - auto base_it = - + hb_range (c->plan->num_output_glyphs ()) - | hb_filter ([&](hb_codepoint_t new_gid) - { - hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); - if (glyphset.has (old_gid)) return true; - return false; - }) - | hb_map_retains_sorting ([&](hb_codepoint_t new_gid) - { - hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); - - const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); - if (unlikely (!old_record)) - return hb_pair_t (false, Null (BaseGlyphRecord)); - BaseGlyphRecord new_record = {}; - new_record.glyphId = new_gid; - new_record.numLayers = old_record->numLayers; - return hb_pair_t (true, new_record); - }) - | hb_filter (hb_first) - | hb_map_retains_sorting (hb_second) - ; - - auto layer_it = - + hb_range (c->plan->num_output_glyphs ()) - | hb_map (reverse_glyph_map) - | hb_filter (glyphset) - | hb_map_retains_sorting ([&](hb_codepoint_t old_gid) - { - const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); - hb_vector_t out_layers; - - if (unlikely (!old_record || - old_record->firstLayerIdx >= numLayers || - old_record->firstLayerIdx + old_record->numLayers > numLayers)) - return hb_pair_t> (false, out_layers); - - auto layers = (this+layersZ).as_array (numLayers).sub_array (old_record->firstLayerIdx, - old_record->numLayers); - out_layers.resize (layers.length); - for (unsigned int i = 0; i < layers.length; i++) { - out_layers[i] = layers[i]; - hb_codepoint_t new_gid = 0; - if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid))) - return hb_pair_t> (false, out_layers); - out_layers[i].glyphId = new_gid; - out_layers[i].colorIdx = c->plan->colr_palettes->get (layers[i].colorIdx); - } - - return hb_pair_t> (true, out_layers); - }) - | hb_filter (hb_first) - | hb_map_retains_sorting (hb_second) - ; - - if (version == 0 && (!base_it || !layer_it)) - return_trace (false); - - COLR *colr_prime = c->serializer->start_embed (); - if (unlikely (!c->serializer->extend_min (colr_prime))) return_trace (false); - - if (version == 0) - return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)); - - auto snap = c->serializer->snapshot (); - if (!c->serializer->allocate_size (5 * HBUINT32::static_size)) return_trace (false); - if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this)) - { - if (c->serializer->in_error ()) return_trace (false); - //no more COLRv1 glyphs: downgrade to version 0 - c->serializer->revert (snap); - return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it)); - } - - if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false); - - colr_prime->layerList.serialize_subset (c, layerList, this); - colr_prime->clipList.serialize_subset (c, clipList, this); - colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this); - //TODO: subset varStore once it's implemented in fonttools - return_trace (true); - } - - protected: - HBUINT16 version; /* Table version number (starts at 0). */ - HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ - NNOffset32To> - baseGlyphsZ; /* Offset to Base Glyph records. */ - NNOffset32To> - layersZ; /* Offset to Layer Records. */ - HBUINT16 numLayers; /* Number of Layer Records. */ - // Version-1 additions - Offset32To baseGlyphList; - Offset32To layerList; - Offset32To clipList; // Offset to ClipList table (may be NULL) - Offset32To varIdxMap; // Offset to DeltaSetIndexMap table (may be NULL) - Offset32To varStore; - public: - DEFINE_SIZE_MIN (14); -}; - -struct COLR_accelerator_t : COLR::accelerator_t { - COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {} -}; - -} /* namespace OT */ - - -#endif /* HB_OT_COLOR_COLR_TABLE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colrv1-closure.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colrv1-closure.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colrv1-closure.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colrv1-closure.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * Copyright © 2020 Google, 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. - * - */ - -#ifndef HB_OT_COLR_COLRV1_CLOSURE_HH -#define HB_OT_COLR_COLRV1_CLOSURE_HH - -#include "hb-open-type.hh" -#include "hb-ot-layout-common.hh" -#include "hb-ot-color-colr-table.hh" - -/* - * COLR -- Color - * https://docs.microsoft.com/en-us/typography/opentype/spec/colr - */ -namespace OT { - -HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const -{ - c->add_layer_indices (firstLayerIndex, numLayers); - const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); - for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) - { - const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i]; - paint.dispatch (c); - } -} - -HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const -{ - c->add_glyph (gid); - (this+paint).dispatch (c); -} - -HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const -{ - const COLR *colr_table = c->get_colr_table (); - const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid); - if (!baseglyph_paintrecord) return; - c->add_glyph (gid); - - const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList (); - (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c); -} - -template class Var> -HB_INTERNAL void PaintTransform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } - -HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const -{ - (this+src).dispatch (c); - (this+backdrop).dispatch (c); -} - -} /* namespace OT */ - - -#endif /* HB_OT_COLR_COLRV1_CLOSURE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cpal-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cpal-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cpal-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cpal-table.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,322 +0,0 @@ -/* - * Copyright © 2016 Google, Inc. - * Copyright © 2018 Ebrahim Byagowi - * - * 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): Sascha Brawer - */ - -#ifndef HB_OT_COLOR_CPAL_TABLE_HH -#define HB_OT_COLOR_CPAL_TABLE_HH - -#include "hb-open-type.hh" -#include "hb-ot-color.h" -#include "hb-ot-name.h" - - -/* - * CPAL -- Color Palette - * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal - */ -#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L') - -namespace OT { - - -struct CPALV1Tail -{ - friend struct CPAL; - - private: - hb_ot_color_palette_flags_t get_palette_flags (const void *base, - unsigned int palette_index, - unsigned int palette_count) const - { - if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; - return (hb_ot_color_palette_flags_t) (uint32_t) - (base+paletteFlagsZ).as_array (palette_count)[palette_index]; - } - - hb_ot_name_id_t get_palette_name_id (const void *base, - unsigned int palette_index, - unsigned int palette_count) const - { - if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID; - return (base+paletteLabelsZ).as_array (palette_count)[palette_index]; - } - - hb_ot_name_id_t get_color_name_id (const void *base, - unsigned int color_index, - unsigned int color_count) const - { - if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID; - return (base+colorLabelsZ).as_array (color_count)[color_index]; - } - - public: - bool serialize (hb_serialize_context_t *c, - unsigned palette_count, - unsigned color_count, - const void *base, - const hb_map_t *color_index_map) const - { - TRACE_SERIALIZE (this); - auto *out = c->allocate_size (static_size); - if (unlikely (!out)) return_trace (false); - - out->paletteFlagsZ = 0; - if (paletteFlagsZ) - out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count); - - out->paletteLabelsZ = 0; - if (paletteLabelsZ) - out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count); - - const hb_array_t colorLabels = (base+colorLabelsZ).as_array (color_count); - if (colorLabelsZ) - { - c->push (); - for (const auto _ : colorLabels) - { - const hb_codepoint_t *v; - if (!color_index_map->has (_, &v)) continue; - NameID new_color_idx; - new_color_idx = *v; - if (!c->copy (new_color_idx)) - { - c->pop_discard (); - return_trace (false); - } - } - c->add_link (out->colorLabelsZ, c->pop_pack ()); - } - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c, - const void *base, - unsigned int palette_count, - unsigned int color_count) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - (!paletteFlagsZ || (base+paletteFlagsZ).sanitize (c, palette_count)) && - (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) && - (!colorLabelsZ || (base+colorLabelsZ).sanitize (c, color_count))); - } - - protected: - // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets - // here. Currently they are needed since UnsizedArrayOf doesn't define null_size - NNOffset32To> - paletteFlagsZ; /* Offset from the beginning of CPAL table to - * the Palette Type Array. Set to 0 if no array - * is provided. */ - NNOffset32To> - paletteLabelsZ; /* Offset from the beginning of CPAL table to - * the palette labels array. Set to 0 if no - * array is provided. */ - NNOffset32To> - colorLabelsZ; /* Offset from the beginning of CPAL table to - * the color labels array. Set to 0 - * if no array is provided. */ - public: - DEFINE_SIZE_STATIC (12); -}; - -typedef HBUINT32 BGRAColor; - -struct CPAL -{ - static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL; - - bool has_data () const { return numPalettes; } - - unsigned int get_size () const - { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); } - - unsigned int get_palette_count () const { return numPalettes; } - unsigned int get_color_count () const { return numColors; } - - hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const - { return v1 ().get_palette_flags (this, palette_index, numPalettes); } - - hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const - { return v1 ().get_palette_name_id (this, palette_index, numPalettes); } - - hb_ot_name_id_t get_color_name_id (unsigned int color_index) const - { return v1 ().get_color_name_id (this, color_index, numColors); } - - unsigned int get_palette_colors (unsigned int palette_index, - unsigned int start_offset, - unsigned int *color_count, /* IN/OUT. May be NULL. */ - hb_color_t *colors /* OUT. May be NULL. */) const - { - if (unlikely (palette_index >= numPalettes)) - { - if (color_count) *color_count = 0; - return 0; - } - unsigned int start_index = colorRecordIndicesZ[palette_index]; - hb_array_t all_colors ((this+colorRecordsZ).arrayZ, numColorRecords); - hb_array_t palette_colors = all_colors.sub_array (start_index, - numColors); - if (color_count) - { - + palette_colors.sub_array (start_offset, color_count) - | hb_sink (hb_array (colors, *color_count)) - ; - } - return numColors; - } - - private: - const CPALV1Tail& v1 () const - { - if (version == 0) return Null (CPALV1Tail); - return StructAfter (*this); - } - - public: - bool serialize (hb_serialize_context_t *c, - const hb_array_t &color_record_indices, - const hb_array_t &color_records, - const hb_vector_t& first_color_index_for_layer, - const hb_map_t& first_color_to_layer_index, - const hb_set_t &retained_color_indices) const - { - TRACE_SERIALIZE (this); - - // TODO(grieger): limit total final size. - - for (const auto idx : color_record_indices) - { - hb_codepoint_t layer_index = first_color_to_layer_index[idx]; - - HBUINT16 new_idx; - new_idx = layer_index * retained_color_indices.get_population (); - if (!c->copy (new_idx)) return_trace (false); - } - - c->push (); - for (unsigned first_color_index : first_color_index_for_layer) - { - for (hb_codepoint_t color_index : retained_color_indices) - { - if (!c->copy (color_records[first_color_index + color_index])) - { - c->pop_discard (); - return_trace (false); - } - } - } - - c->add_link (colorRecordsZ, c->pop_pack ()); - return_trace (true); - } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - if (!numPalettes) return_trace (false); - - const hb_map_t *color_index_map = c->plan->colr_palettes; - if (color_index_map->is_empty ()) return_trace (false); - - hb_set_t retained_color_indices; - for (const auto _ : color_index_map->keys ()) - { - if (_ == 0xFFFF) continue; - retained_color_indices.add (_); - } - if (retained_color_indices.is_empty ()) return_trace (false); - - auto *out = c->serializer->start_embed (*this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - - - out->version = version; - out->numColors = retained_color_indices.get_population (); - out->numPalettes = numPalettes; - - hb_vector_t first_color_index_for_layer; - hb_map_t first_color_to_layer_index; - - const hb_array_t colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes); - for (const auto first_color_record_idx : colorRecordIndices) - { - if (first_color_to_layer_index.has (first_color_record_idx)) continue; - - first_color_index_for_layer.push (first_color_record_idx); - first_color_to_layer_index.set (first_color_record_idx, - first_color_index_for_layer.length - 1); - } - - out->numColorRecords = first_color_index_for_layer.length - * retained_color_indices.get_population (); - - const hb_array_t color_records = (this+colorRecordsZ).as_array (numColorRecords); - if (!out->serialize (c->serializer, - colorRecordIndices, - color_records, - first_color_index_for_layer, - first_color_to_layer_index, - retained_color_indices)) - return_trace (false); - - if (version == 1) - return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map)); - - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - (this+colorRecordsZ).sanitize (c, numColorRecords) && - colorRecordIndicesZ.sanitize (c, numPalettes) && - (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors))); - } - - protected: - HBUINT16 version; /* Table version number */ - /* Version 0 */ - HBUINT16 numColors; /* Number of colors in each palette. */ - HBUINT16 numPalettes; /* Number of palettes in the table. */ - HBUINT16 numColorRecords; /* Total number of color records, combined for - * all palettes. */ - NNOffset32To> - colorRecordsZ; /* Offset from the beginning of CPAL table to - * the first ColorRecord. */ - UnsizedArrayOf - colorRecordIndicesZ; /* Index of each palette’s first color record in - * the combined color record array. */ -/*CPALV1Tail v1;*/ - public: - DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ); -}; - -} /* namespace OT */ - - -#endif /* HB_OT_COLOR_CPAL_TABLE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color.h 2023-07-05 07:11:54.000000000 +0000 @@ -102,6 +102,10 @@ * * Pairs of glyph and color index. * + * A color index of 0xFFFF does not refer to a palette + * color, but indicates that the foreground color should + * be used. + * * Since: 2.1.0 **/ typedef struct hb_ot_color_layer_t { @@ -116,6 +120,15 @@ unsigned int *layer_count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */); +/* COLRv1 */ + +HB_EXTERN hb_bool_t +hb_ot_color_has_paint (hb_face_t *face); + +HB_EXTERN hb_bool_t +hb_ot_color_glyph_has_paint (hb_face_t *face, + hb_codepoint_t glyph); + /* * SVG */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-sbix-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-sbix-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-sbix-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-sbix-table.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,423 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * Copyright © 2020 Google, 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. - * - * Google Author(s): Calder Kitagawa - */ - -#ifndef HB_OT_COLOR_SBIX_TABLE_HH -#define HB_OT_COLOR_SBIX_TABLE_HH - -#include "hb-open-type.hh" -#include "hb-ot-layout-common.hh" - -/* - * sbix -- Standard Bitmap Graphics - * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix - * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html - */ -#define HB_OT_TAG_sbix HB_TAG('s','b','i','x') - - -namespace OT { - - -struct SBIXGlyph -{ - SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const - { - 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; - new_glyph->yOffset = yOffset; - new_glyph->graphicType = graphicType; - data.copy (c, data_length); - return_trace (new_glyph); - } - - HBINT16 xOffset; /* The horizontal (x-axis) offset from the left - * edge of the graphic to the glyph’s origin. - * That is, the x-coordinate of the point on the - * baseline at the left edge of the glyph. */ - HBINT16 yOffset; /* The vertical (y-axis) offset from the bottom - * edge of the graphic to the glyph’s origin. - * That is, the y-coordinate of the point on the - * baseline at the left edge of the glyph. */ - Tag graphicType; /* Indicates the format of the embedded graphic - * data: one of 'jpg ', 'png ' or 'tiff', or the - * special format 'dupe'. */ - UnsizedArrayOf - data; /* The actual embedded graphic data. The total - * length is inferred from sequential entries in - * the glyphDataOffsets array and the fixed size - * (8 bytes) of the preceding fields. */ - public: - DEFINE_SIZE_ARRAY (8, data); -}; - -struct SBIXStrike -{ - static unsigned int get_size (unsigned num_glyphs) - { return min_size + num_glyphs * HBUINT32::static_size; } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1)); - } - - hb_blob_t *get_glyph_blob (unsigned int glyph_id, - hb_blob_t *sbix_blob, - hb_tag_t file_type, - int *x_offset, - int *y_offset, - unsigned int num_glyphs, - unsigned int *strike_ppem) const - { - if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */ - - unsigned int retry_count = 8; - unsigned int sbix_len = sbix_blob->length; - unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; - assert (strike_offset < sbix_len); - - retry: - if (unlikely (glyph_id >= num_glyphs || - imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] || - imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size || - (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset)) - return hb_blob_get_empty (); - - unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size; - unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size; - - const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); - - if (glyph->graphicType == HB_TAG ('d','u','p','e')) - { - if (glyph_length >= 2) - { - glyph_id = *((HBUINT16 *) &glyph->data); - if (retry_count--) - goto retry; - } - return hb_blob_get_empty (); - } - - if (unlikely (file_type != glyph->graphicType)) - return hb_blob_get_empty (); - - if (strike_ppem) *strike_ppem = ppem; - if (x_offset) *x_offset = glyph->xOffset; - if (y_offset) *y_offset = glyph->yOffset; - return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length); - } - - bool subset (hb_subset_context_t *c, unsigned int available_len) const - { - TRACE_SUBSET (this); - 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; - out->resolution = resolution; - HBUINT32 head; - head = get_size (num_output_glyphs + 1); - - bool has_glyphs = false; - for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++) - { - hb_codepoint_t old_gid; - if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) || - unlikely (imageOffsetsZ[old_gid].is_null () || - imageOffsetsZ[old_gid + 1].is_null () || - imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] || - imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) || - (unsigned int) imageOffsetsZ[old_gid + 1] > available_len) - { - out->imageOffsetsZ[new_gid] = head; - continue; - } - has_glyphs = true; - unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid]; - unsigned int glyph_data_length = delta - SBIXGlyph::min_size; - if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length)) - return_trace (false); - out->imageOffsetsZ[new_gid] = head; - head += delta; - } - if (has_glyphs) - out->imageOffsetsZ[num_output_glyphs] = head; - else - c->serializer->revert (snap); - return_trace (has_glyphs); - } - - public: - HBUINT16 ppem; /* The PPEM size for which this strike was designed. */ - HBUINT16 resolution; /* The device pixel density (in PPI) for which this - * strike was designed. (E.g., 96 PPI, 192 PPI.) */ - protected: - UnsizedArrayOf> - imageOffsetsZ; /* Offset from the beginning of the strike data header - * to bitmap data for an individual glyph ID. */ - public: - DEFINE_SIZE_ARRAY (4, imageOffsetsZ); -}; - -struct sbix -{ - static constexpr hb_tag_t tableTag = HB_OT_TAG_sbix; - - bool has_data () const { return version; } - - const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; } - - struct accelerator_t - { - accelerator_t (hb_face_t *face) - { - table = hb_sanitize_context_t ().reference_table (face); - num_glyphs = face->get_num_glyphs (); - } - ~accelerator_t () { table.destroy (); } - - bool has_data () const { return table->has_data (); } - - bool get_extents (hb_font_t *font, - hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const - { - /* We only support PNG right now, and following function checks type. */ - return get_png_extents (font, glyph, extents); - } - - hb_blob_t *reference_png (hb_font_t *font, - hb_codepoint_t glyph_id, - int *x_offset, - int *y_offset, - unsigned int *available_ppem) const - { - return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (), - HB_TAG ('p','n','g',' '), - x_offset, y_offset, - num_glyphs, available_ppem); - } - - private: - - const SBIXStrike &choose_strike (hb_font_t *font) const - { - unsigned count = table->strikes.len; - if (unlikely (!count)) - return Null (SBIXStrike); - - unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem); - if (!requested_ppem) - requested_ppem = 1<<30; /* Choose largest strike. */ - /* TODO Add DPI sensitivity as well? */ - unsigned int best_i = 0; - unsigned int best_ppem = table->get_strike (0).ppem; - - for (unsigned int i = 1; i < count; i++) - { - unsigned int ppem = (table->get_strike (i)).ppem; - if ((requested_ppem <= ppem && ppem < best_ppem) || - (requested_ppem > best_ppem && ppem > best_ppem)) - { - best_i = i; - best_ppem = ppem; - } - } - - return table->get_strike (best_i); - } - - struct PNGHeader - { - HBUINT8 signature[8]; - struct - { - struct - { - HBUINT32 length; - Tag type; - } header; - HBUINT32 width; - HBUINT32 height; - HBUINT8 bitDepth; - HBUINT8 colorType; - HBUINT8 compressionMethod; - HBUINT8 filterMethod; - HBUINT8 interlaceMethod; - } IHDR; - - public: - DEFINE_SIZE_STATIC (29); - }; - - bool get_png_extents (hb_font_t *font, - hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const - { - /* Following code is safe to call even without data. - * But faster to short-circuit. */ - if (!has_data ()) - return false; - - int x_offset = 0, y_offset = 0; - unsigned int strike_ppem = 0; - hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); - - const PNGHeader &png = *blob->as(); - - if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536) - { - hb_blob_destroy (blob); - return false; - } - - extents->x_bearing = x_offset; - extents->y_bearing = png.IHDR.height + y_offset; - extents->width = png.IHDR.width; - extents->height = -1 * png.IHDR.height; - - /* Convert to font units. */ - if (strike_ppem) - { - float scale = font->face->get_upem () / (float) strike_ppem; - extents->x_bearing = font->em_scalef_x (extents->x_bearing * scale); - extents->y_bearing = font->em_scalef_y (extents->y_bearing * scale); - extents->width = font->em_scalef_x (extents->width * scale); - extents->height = font->em_scalef_y (extents->height * scale); - } - else - { - extents->x_bearing = font->em_scale_x (extents->x_bearing); - extents->y_bearing = font->em_scale_y (extents->y_bearing); - extents->width = font->em_scale_x (extents->width); - extents->height = font->em_scale_y (extents->height); - } - - hb_blob_destroy (blob); - - return strike_ppem; - } - - private: - hb_blob_ptr_t table; - - unsigned int num_glyphs; - }; - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - version >= 1 && - strikes.sanitize (c, this))); - } - - bool - add_strike (hb_subset_context_t *c, unsigned i) const - { - if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i]) - return false; - - return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]); - } - - bool serialize_strike_offsets (hb_subset_context_t *c) const - { - 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; - hb_vector_t objidxs; - for (int i = strikes.len - 1; i >= 0; --i) - { - auto* o = out->serialize_append (c->serializer); - if (unlikely (!o)) return_trace (false); - *o = 0; - auto snap = c->serializer->snapshot (); - c->serializer->push (); - bool ret = add_strike (c, i); - if (!ret) - { - c->serializer->pop_discard (); - out->pop (); - c->serializer->revert (snap); - } - else - { - objidxs.push (c->serializer->pop_pack ()); - new_strikes.push (o); - } - } - for (unsigned int i = 0; i < new_strikes.length; ++i) - c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]); - - return_trace (true); - } - - bool subset (hb_subset_context_t* c) const - { - 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); - - return_trace (serialize_strike_offsets (c)); - } - - protected: - HBUINT16 version; /* Table version number — set to 1 */ - HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. - * Bits 2 to 15: reserved (set to 0). */ - Array32OfOffset32To - strikes; /* Offsets from the beginning of the 'sbix' - * table to data for each individual bitmap strike. */ - public: - DEFINE_SIZE_ARRAY (8, strikes); -}; - -struct sbix_accelerator_t : sbix::accelerator_t { - sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {} -}; - - -} /* namespace OT */ - -#endif /* HB_OT_COLOR_SBIX_TABLE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-svg-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-svg-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-color-svg-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-color-svg-table.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * - * 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_OT_COLOR_SVG_TABLE_HH -#define HB_OT_COLOR_SVG_TABLE_HH - -#include "hb-open-type.hh" - -/* - * SVG -- SVG (Scalable Vector Graphics) - * https://docs.microsoft.com/en-us/typography/opentype/spec/svg - */ - -#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ') - - -namespace OT { - - -struct SVGDocumentIndexEntry -{ - int cmp (hb_codepoint_t g) const - { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; } - - hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const - { - return hb_blob_create_sub_blob (svg_blob, - index_offset + (unsigned int) svgDoc, - svgDocLength); - } - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - svgDoc.sanitize (c, base, svgDocLength)); - } - - protected: - HBUINT16 startGlyphID; /* The first glyph ID in the range described by - * this index entry. */ - HBUINT16 endGlyphID; /* The last glyph ID in the range described by - * this index entry. Must be >= startGlyphID. */ - NNOffset32To> - svgDoc; /* Offset from the beginning of the SVG Document Index - * to an SVG document. Must be non-zero. */ - HBUINT32 svgDocLength; /* Length of the SVG document. - * Must be non-zero. */ - public: - DEFINE_SIZE_STATIC (12); -}; - -struct SVG -{ - static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG; - - bool has_data () const { return svgDocEntries; } - - struct accelerator_t - { - accelerator_t (hb_face_t *face) - { table = hb_sanitize_context_t ().reference_table (face); } - ~accelerator_t () { table.destroy (); } - - hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const - { - return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (), - table->svgDocEntries); - } - - bool has_data () const { return table->has_data (); } - - private: - hb_blob_ptr_t table; - }; - - const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const - { return (this+svgDocEntries).bsearch (glyph_id); } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (this+svgDocEntries).sanitize_shallow (c))); - } - - protected: - HBUINT16 version; /* Table version (starting at 0). */ - Offset32To> - svgDocEntries; /* Offset (relative to the start of the SVG table) to the - * SVG Documents Index. Must be non-zero. */ - /* Array of SVG Document Index Entries. */ - HBUINT32 reserved; /* Set to 0. */ - public: - DEFINE_SIZE_STATIC (10); -}; - -struct SVG_accelerator_t : SVG::accelerator_t { - SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {} -}; - -} /* namespace OT */ - - -#endif /* HB_OT_COLOR_SVG_TABLE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-deprecated.h openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-deprecated.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-deprecated.h 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-deprecated.h 2023-07-05 07:11:54.000000000 +0000 @@ -67,26 +67,30 @@ /* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */ -HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t +HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) +HB_EXTERN hb_bool_t hb_ot_layout_table_choose_script (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *script_tags, unsigned int *script_index, hb_tag_t *chosen_script); -HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) hb_bool_t +HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) +HB_EXTERN hb_bool_t hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, hb_tag_t language_tag, unsigned int *language_index); -HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) void +HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) +HB_EXTERN void hb_ot_tags_from_script (hb_script_t script, hb_tag_t *script_tag_1, hb_tag_t *script_tag_2); -HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t +HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) +HB_EXTERN hb_tag_t hb_ot_tag_from_language (hb_language_t language); @@ -121,13 +125,15 @@ float max_value; } hb_ot_var_axis_t; -HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos) unsigned int +HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos) +HB_EXTERN unsigned int hb_ot_var_get_axes (hb_face_t *face, unsigned int start_offset, unsigned int *axes_count /* IN/OUT */, hb_ot_var_axis_t *axes_array /* OUT */); -HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_find_axis_info) hb_bool_t +HB_DEPRECATED_FOR (hb_ot_var_find_axis_info) +HB_EXTERN hb_bool_t hb_ot_var_find_axis (hb_face_t *face, hb_tag_t axis_tag, unsigned int *axis_index, diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc 2023-07-05 07:11:54.000000000 +0000 @@ -35,9 +35,9 @@ #include "hb-ot-meta-table.hh" #include "hb-ot-name-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-color-cbdt-table.hh" -#include "hb-ot-color-sbix-table.hh" -#include "hb-ot-color-svg-table.hh" +#include "OT/Color/CBDT/CBDT.hh" +#include "OT/Color/sbix/sbix.hh" +#include "OT/Color/svg/svg.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh 2023-07-05 07:11:54.000000000 +0000 @@ -56,9 +56,9 @@ #if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT) HB_OT_ACCELERATOR (OT, cmap) #endif -HB_OT_TABLE (OT, hhea) +HB_OT_CORE_TABLE (OT, hhea) HB_OT_ACCELERATOR (OT, hmtx) -HB_OT_TABLE (OT, OS2) +HB_OT_CORE_TABLE (OT, OS2) #if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) || !defined(HB_NO_STYLE) HB_OT_ACCELERATOR (OT, post) #endif @@ -66,7 +66,7 @@ HB_OT_ACCELERATOR (OT, name) #endif #ifndef HB_NO_STYLE -HB_OT_TABLE (OT, STAT) +HB_OT_CORE_TABLE (OT, STAT) #endif #ifndef HB_NO_META HB_OT_ACCELERATOR (OT, meta) @@ -74,9 +74,9 @@ /* Vertical layout. */ #ifndef HB_NO_VERTICAL -HB_OT_TABLE (OT, vhea) +HB_OT_CORE_TABLE (OT, vhea) HB_OT_ACCELERATOR (OT, vmtx) -HB_OT_TABLE (OT, VORG) +HB_OT_CORE_TABLE (OT, VORG) #endif /* TrueType outlines. */ @@ -91,15 +91,15 @@ /* OpenType variations. */ #ifndef HB_NO_VAR -HB_OT_TABLE (OT, fvar) -HB_OT_TABLE (OT, avar) +HB_OT_CORE_TABLE (OT, fvar) +HB_OT_CORE_TABLE (OT, avar) HB_OT_ACCELERATOR (OT, gvar) -HB_OT_TABLE (OT, MVAR) +HB_OT_CORE_TABLE (OT, MVAR) #endif /* Legacy kern. */ #ifndef HB_NO_OT_KERN -HB_OT_TABLE (OT, kern) +HB_OT_CORE_TABLE (OT, kern) #endif /* OpenType shaping. */ @@ -107,12 +107,12 @@ HB_OT_ACCELERATOR (OT, GDEF) HB_OT_ACCELERATOR (OT, GSUB) HB_OT_ACCELERATOR (OT, GPOS) -//HB_OT_TABLE (OT, JSTF) +//HB_OT_CORE_TABLE (OT, JSTF) #endif /* OpenType baseline. */ #ifndef HB_NO_BASE -HB_OT_TABLE (OT, BASE) +HB_OT_CORE_TABLE (OT, BASE) #endif /* AAT shaping. */ @@ -129,8 +129,8 @@ /* OpenType color fonts. */ #ifndef HB_NO_COLOR -HB_OT_TABLE (OT, COLR) -HB_OT_TABLE (OT, CPAL) +HB_OT_CORE_TABLE (OT, COLR) +HB_OT_CORE_TABLE (OT, CPAL) HB_OT_ACCELERATOR (OT, CBDT) HB_OT_ACCELERATOR (OT, sbix) HB_OT_ACCELERATOR (OT, SVG) @@ -138,7 +138,7 @@ /* OpenType math. */ #ifndef HB_NO_MATH -HB_OT_TABLE (OT, MATH) +HB_OT_CORE_TABLE (OT, MATH) #endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc 2023-07-05 07:11:54.000000000 +0000 @@ -34,18 +34,20 @@ #include "hb-font.hh" #include "hb-machinery.hh" #include "hb-ot-face.hh" +#include "hb-outline.hh" #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-hmtx-table.hh" -#include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. #include "hb-ot-vorg-table.hh" -#include "hb-ot-color-cbdt-table.hh" -#include "hb-ot-color-sbix-table.hh" +#include "OT/Color/CBDT/CBDT.hh" +#include "OT/Color/COLR/COLR.hh" +#include "OT/Color/sbix/sbix.hh" +#include "OT/Color/svg/svg.hh" /** @@ -59,13 +61,20 @@ * never need to call these functions directly. **/ +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>; + +static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key; + struct hb_ot_font_t { const hb_ot_face_t *ot_face; + hb_ot_font_cmap_cache_t *cmap_cache; + /* h_advance caching */ mutable hb_atomic_int_t cached_coords_serial; - mutable hb_atomic_ptr_t advance_cache; + mutable hb_atomic_ptr_t advance_cache; }; static hb_ot_font_t * @@ -77,6 +86,33 @@ ot_font->ot_face = &font->face->table; + // 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); + if (!cmap_cache) + { + 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 (); + if (unlikely (!hb_face_set_user_data (font->face, + &hb_ot_font_cmap_cache_user_data_key, + cmap_cache, + hb_free, + false))) + { + hb_free (cmap_cache); + cmap_cache = nullptr; + /* Normally we would retry here, but that would + * infinite-loop if the face is the empty-face. + * Just let it go and this font will be uncached if it + * happened to collide with another thread creating the + * cache at the same time. */ + // goto retry; + } + } + out: + ot_font->cmap_cache = cmap_cache; + return ot_font; } @@ -86,11 +122,7 @@ hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data; auto *cache = ot_font->advance_cache.get_relaxed (); - if (cache) - { - cache->fini (); - hb_free (cache); - } + hb_free (cache); hb_free (ot_font); } @@ -104,7 +136,7 @@ { 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); + return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache); } static unsigned int @@ -121,7 +153,8 @@ const hb_ot_face_t *ot_face = ot_font->ot_face; return ot_face->cmap->get_nominal_glyphs (count, first_unicode, unicode_stride, - first_glyph, glyph_stride); + first_glyph, glyph_stride, + ot_font->cmap_cache); } static hb_bool_t @@ -134,7 +167,9 @@ { 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_variation_glyph (unicode, variation_selector, glyph); + return ot_face->cmap->get_variation_glyph (unicode, + variation_selector, glyph, + ot_font->cmap_cache); } static void @@ -146,12 +181,15 @@ unsigned advance_stride, void *user_data HB_UNUSED) { + 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; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; + hb_position_t *orig_first_advance = first_advance; + #ifndef HB_NO_VAR - const OT::HVARVVAR &HVAR = *hmtx.var_table; + 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; @@ -161,14 +199,14 @@ bool use_cache = false; #endif - hb_advance_cache_t *cache = nullptr; + hb_ot_font_advance_cache_t *cache = nullptr; if (use_cache) { retry: - cache = ot_font->advance_cache.get (); + cache = ot_font->advance_cache.get_acquire (); if (unlikely (!cache)) { - cache = (hb_advance_cache_t *) hb_malloc (sizeof (hb_advance_cache_t)); + cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); if (unlikely (!cache)) { use_cache = false; @@ -181,7 +219,7 @@ hb_free (cache); goto retry; } - ot_font->cached_coords_serial.set (font->serial_coords); + ot_font->cached_coords_serial.set_release (font->serial_coords); } } out: @@ -190,17 +228,17 @@ { for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } else { /* Use cache. */ - if (ot_font->cached_coords_serial.get () != (int) font->serial_coords) + if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords) { ot_font->advance_cache->init (); - ot_font->cached_coords_serial.set (font->serial_coords); + ot_font->cached_coords_serial.set_release (font->serial_coords); } for (unsigned int i = 0; i < count; i++) @@ -211,7 +249,7 @@ v = cv; else { - v = hmtx.get_advance (*first_glyph, font, varStore_cache); + v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); ot_font->advance_cache->set (*first_glyph, v); } *first_advance = font->em_scale_x (v); @@ -223,6 +261,18 @@ #ifndef HB_NO_VAR OT::VariationStore::destroy_cache (varStore_cache); #endif + + if (font->x_strength && !font->embolden_in_place) + { + /* Emboldening. */ + hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? x_strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } #ifndef HB_NO_VERTICAL @@ -239,10 +289,12 @@ const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; + hb_position_t *orig_first_advance = first_advance; + if (vmtx.has_data ()) { #ifndef HB_NO_VAR - const OT::HVARVVAR &VVAR = *vmtx.var_table; + 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; #else @@ -251,7 +303,7 @@ for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } @@ -273,6 +325,18 @@ first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } + + if (font->y_strength && !font->embolden_in_place) + { + /* Emboldening. */ + hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? y_strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } #endif @@ -293,17 +357,28 @@ const OT::VORG &VORG = *ot_face->VORG; if (VORG.has_data ()) { - *y = font->em_scale_y (VORG.get_y_origin (glyph)); + float delta = 0; + +#ifndef HB_NO_VAR + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; + const OT::VVAR &VVAR = *vmtx.var_table; + if (font->num_coords) + VVAR.get_vorg_delta_unscaled (glyph, + font->coords, font->num_coords, + &delta); +#endif + + *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); return true; } hb_glyph_extents_t extents = {0}; if (ot_face->glyf->get_extents (font, glyph, &extents)) { - if (ot_face->vmtx->has_data ()) + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; + int tsb = 0; + if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb)) { - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - hb_position_t tsb = vmtx.get_side_bearing (font, glyph); *y = extents.y_bearing + font->em_scale_y (tsb); return true; } @@ -336,17 +411,17 @@ #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) if (ot_face->sbix->get_extents (font, glyph, extents)) return true; + if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; +#endif +#if !defined(HB_NO_COLOR) + if (ot_face->COLR->get_extents (font, glyph, extents)) return true; #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; #endif -#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) - if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; -#endif - // TODO Hook up side-bearings variations. return false; } @@ -391,9 +466,16 @@ hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) && - _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) && - _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); + bool ret = _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) && + _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) && + _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); + + /* Embolden */ + int y_shift = font->y_strength; + if (font->y_scale < 0) y_shift = -y_shift; + metrics->ascender += y_shift; + + return ret; } #ifndef HB_NO_VERTICAL @@ -411,17 +493,62 @@ #ifndef HB_NO_DRAW static void -hb_ot_get_glyph_shape (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data) -{ - hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); - if (font->face->table.glyf->get_path (font, glyph, draw_session)) return; +hb_ot_draw_glyph (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) +{ + bool embolden = font->x_strength || font->y_strength; + hb_outline_t outline; + + { // Need draw_session to be destructed before emboldening. + hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs, + 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)) return; - if (font->face->table.cff2->get_path (font, glyph, draw_session)) return; + if (!font->face->table.cff1->get_path (font, glyph, draw_session)) + if (!font->face->table.cff2->get_path (font, glyph, draw_session)) +#endif + {} + } + + if (embolden) + { + float x_shift = font->embolden_in_place ? 0 : (float) font->x_strength / 2; + float y_shift = (float) font->y_strength / 2; + if (font->x_scale < 0) x_shift = -x_shift; + if (font->y_scale < 0) y_shift = -y_shift; + outline.embolden (font->x_strength, font->y_strength, + x_shift, y_shift); + + outline.replay (draw_funcs, draw_data); + } +} +#endif + +#ifndef HB_NO_PAINT +static void +hb_ot_paint_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) +{ +#ifndef HB_NO_COLOR + if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return; + if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return; +#ifndef HB_NO_OT_FONT_BITMAP + if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; +#endif +#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; #endif } #endif @@ -449,7 +576,11 @@ #endif #ifndef HB_NO_DRAW - hb_font_funcs_set_glyph_shape_func (funcs, hb_ot_get_glyph_shape, nullptr, nullptr); + hb_font_funcs_set_draw_glyph_func (funcs, hb_ot_draw_glyph, nullptr, nullptr); +#endif + +#ifndef HB_NO_PAINT + hb_font_funcs_set_paint_glyph_func (funcs, hb_ot_paint_glyph, nullptr, nullptr); #endif hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); @@ -503,16 +634,17 @@ } #ifndef HB_NO_VAR -int -_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +bool +_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, + int *lsb) { - return font->face->table.glyf->get_side_bearing_var (font, glyph, is_vertical); + return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); } unsigned -_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) { - return font->face->table.glyf->get_advance_var (font, glyph, is_vertical); + return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); } #endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -156,6 +156,7 @@ TRACE_SANITIZE (this); return_trace (c->check_struct (this) && !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) && + min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord && sizeDeviceRecord >= DeviceRecord::min_size && c->check_range (this, get_size ())); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -97,6 +97,7 @@ * entire font as HBUINT32, then store * 0xB1B0AFBAu - sum. */ HBUINT32 magicNumber; /* Set to 0x5F0F3CF5u. */ + public: HBUINT16 flags; /* Bit 0: Baseline for font at y=0; * Bit 1: Left sidebearing point at x=0; * Bit 2: Instructions may depend on point size; @@ -141,6 +142,7 @@ * encoded in the cmap subtables represent proper * support for those code points. * Bit 15: Reserved, set to 0. */ + protected: HBUINT16 unitsPerEm; /* Valid range is from 16 to 16384. This value * should be a power of 2 for fonts that have * TrueType outlines. */ @@ -148,10 +150,12 @@ January 1, 1904. 64-bit integer */ LONGDATETIME modified; /* Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer */ + public: HBINT16 xMin; /* For all glyph bounding boxes. */ HBINT16 yMin; /* For all glyph bounding boxes. */ HBINT16 xMax; /* For all glyph bounding boxes. */ HBINT16 yMax; /* For all glyph bounding boxes. */ + protected: HBUINT16 macStyle; /* Bit 0: Bold (if set to 1); * Bit 1: Italic (if set to 1) * Bit 2: Underline (if set to 1) diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -31,6 +31,7 @@ #include "hb-ot-maxp-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-var-hvar-table.hh" +#include "hb-ot-var-mvar-table.hh" #include "hb-ot-metrics.hh" /* @@ -43,11 +44,11 @@ #define HB_OT_TAG_vmtx HB_TAG('v','m','t','x') -HB_INTERNAL int -_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); +HB_INTERNAL bool +_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, int *lsb); HB_INTERNAL unsigned -_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); namespace OT { @@ -62,7 +63,7 @@ }; -template +template struct hmtxvmtx { bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const @@ -73,11 +74,15 @@ return_trace (true); } + const hb_hashmap_t>* get_mtx_map (const hb_subset_plan_t *plan) const + { return T::is_horizontal ? &plan->hmtx_map : &plan->vmtx_map; } - bool subset_update_header (hb_subset_plan_t *plan, - unsigned int num_hmetrics) const + 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 { - hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table (plan->source, H::tableTag); + 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); hb_blob_destroy (src_blob); @@ -89,7 +94,56 @@ H *table = (H *) hb_blob_get_data (dest_blob, &length); table->numberOfLongMetrics = num_hmetrics; - bool result = plan->add_table (H::tableTag, dest_blob); +#ifndef HB_NO_VAR + if (c->plan->normalized_coords) + { + auto &MVAR = *c->plan->source->table.MVAR; + if (T::is_horizontal) + { + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE, caretSlopeRise); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN, caretSlopeRun); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET, caretOffset); + } + else + { + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RISE, caretSlopeRise); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RUN, caretSlopeRun); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET, caretOffset); + } + + int min_lsb = 0x7FFF; + int min_rsb = 0x7FFF; + int max_extent = -0x7FFF; + unsigned max_adv = 0; + for (const auto _ : *mtx_map) + { + hb_codepoint_t gid = _.first; + unsigned adv = _.second.first; + int lsb = _.second.second; + max_adv = hb_max (max_adv, adv); + + if (bounds_map->has (gid)) + { + unsigned bound_width = bounds_map->get (gid); + int rsb = adv - lsb - bound_width; + int extent = lsb + bound_width; + min_lsb = hb_min (min_lsb, lsb); + min_rsb = hb_min (min_rsb, rsb); + max_extent = hb_max (max_extent, extent); + } + } + + table->advanceMax = max_adv; + if (!bounds_map->is_empty ()) + { + table->minLeadingBearing = min_lsb; + table->minTrailingBearing = min_rsb; + table->maxExtent = max_extent; + } + } +#endif + + bool result = c->plan->add_table (H::tableTag, dest_blob); hb_blob_destroy (dest_blob); return result; @@ -130,14 +184,15 @@ accelerator_t _mtx (c->plan->source); unsigned num_long_metrics; + const hb_hashmap_t> *mtx_map = get_mtx_map (c->plan); { /* Determine num_long_metrics to encode. */ auto& plan = c->plan; + num_long_metrics = plan->num_output_glyphs (); - hb_codepoint_t old_gid = 0; - unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0; + unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx); while (num_long_metrics > 1 && - last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0)) + last_advance == get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 2, _mtx)) { num_long_metrics--; } @@ -145,12 +200,18 @@ auto it = + hb_range (c->plan->num_output_glyphs ()) - | hb_map ([c, &_mtx] (unsigned _) + | hb_map ([c, &_mtx, mtx_map] (unsigned _) { - hb_codepoint_t old_gid; - if (!c->plan->old_gid_for_new_gid (_, &old_gid)) - return hb_pair (0u, 0); - return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid)); + if (!mtx_map->has (_)) + { + hb_codepoint_t old_gid; + if (!c->plan->old_gid_for_new_gid (_, &old_gid)) + return hb_pair (0u, 0); + int lsb = 0; + (void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); + return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); + } + return mtx_map->get (_); }) ; @@ -160,7 +221,8 @@ return_trace (false); // Amend header num hmetrics - if (unlikely (!subset_update_header (c->plan, num_long_metrics))) + if (unlikely (!subset_update_header (c, num_long_metrics, mtx_map, + T::is_horizontal ? &c->plan->bounds_width_map : &c->plan->bounds_height_map))) return_trace (false); return_trace (true); @@ -173,7 +235,7 @@ accelerator_t (hb_face_t *face) { table = hb_sanitize_context_t ().reference_table (face, T::tableTag); - var_table = hb_sanitize_context_t ().reference_table (face, T::variationsTag); + var_table = hb_sanitize_context_t ().reference_table (face, T::variationsTag); default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face); @@ -221,36 +283,46 @@ bool has_data () const { return (bool) num_bearings; } - int get_side_bearing (hb_codepoint_t glyph) const + bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, + int *lsb) const { if (glyph < num_long_metrics) - return table->longMetricZ[glyph].sb; + { + *lsb = table->longMetricZ[glyph].sb; + return true; + } if (unlikely (glyph >= num_bearings)) - return 0; + return false; const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; - return bearings[glyph - num_long_metrics]; + *lsb = bearings[glyph - num_long_metrics]; + return true; } - int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const + bool get_leading_bearing_with_var_unscaled (hb_font_t *font, + hb_codepoint_t glyph, + int *lsb) const { - int side_bearing = get_side_bearing (glyph); + if (!font->num_coords) + return get_leading_bearing_without_var_unscaled (glyph, lsb); #ifndef HB_NO_VAR - if (unlikely (glyph >= num_bearings) || !font->num_coords) - return side_bearing; - - if (var_table.get_length ()) - return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); + float delta; + if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) && + get_leading_bearing_without_var_unscaled (glyph, lsb)) + { + *lsb += roundf (delta); + return true; + } - return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb); #else - return side_bearing; + return false; #endif } - unsigned int get_advance (hb_codepoint_t glyph) const + unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const { /* OpenType case. */ if (glyph < num_bearings) @@ -262,7 +334,7 @@ if (unlikely (!num_advances)) return default_advance; -#ifdef HB_NO_BORING_EXPANSION +#ifdef HB_NO_BEYOND_64K return 0; #endif @@ -272,10 +344,8 @@ /* num_bearings <= glyph < num_glyphs; * num_bearings <= num_advances */ - /* TODO Optimize */ - if (num_bearings == num_advances) - return get_advance (num_bearings - 1); + return get_advance_without_var_unscaled (num_bearings - 1); const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics]; @@ -283,20 +353,22 @@ return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)]; } - unsigned int get_advance (hb_codepoint_t glyph, - hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, + hb_font_t *font, + VariationStore::cache_t *store_cache = nullptr) const { - unsigned int advance = get_advance (glyph); + unsigned int advance = get_advance_without_var_unscaled (glyph); #ifndef HB_NO_VAR if (unlikely (glyph >= num_bearings) || !font->num_coords) return advance; if (var_table.get_length ()) - return advance + roundf (var_table->get_advance_var (glyph, font, store_cache)); // TODO Optimize?! + return advance + roundf (var_table->get_advance_delta_unscaled (glyph, + font->coords, font->num_coords, + store_cache)); - return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else return advance; #endif @@ -313,9 +385,25 @@ public: hb_blob_ptr_t table; - hb_blob_ptr_t var_table; + hb_blob_ptr_t var_table; }; + /* get advance: when no variations, call get_advance_without_var_unscaled. + * when there're variations, get advance value from mtx_map in subset_plan*/ + unsigned get_new_gid_advance_unscaled (const hb_subset_plan_t *plan, + const hb_hashmap_t> *mtx_map, + unsigned new_gid, + const accelerator_t &_mtx) const + { + if (mtx_map->is_empty ()) + { + hb_codepoint_t old_gid = 0; + return plan->old_gid_for_new_gid (new_gid, &old_gid) ? + _mtx.get_advance_without_var_unscaled (old_gid) : 0; + } + return mtx_map->get (new_gid).first; + } + protected: UnsizedArrayOf longMetricZ; /* Paired advance width and leading @@ -346,12 +434,12 @@ DEFINE_SIZE_ARRAY (0, longMetricZ); }; -struct hmtx : hmtxvmtx { +struct hmtx : hmtxvmtx { static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx; static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR; static constexpr bool is_horizontal = true; }; -struct vmtx : hmtxvmtx { +struct vmtx : hmtxvmtx { static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx; static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR; static constexpr bool is_horizontal = false; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh 2023-07-05 07:11:54.000000000 +0000 @@ -49,7 +49,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc 2023-07-05 07:11:54.000000000 +0000 @@ -54,7 +54,7 @@ #include "hb-aat-layout-morx-table.hh" #include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise. -using OT::Layout::GSUB::GSUB; +using OT::Layout::GSUB; using OT::Layout::GPOS; /** @@ -79,7 +79,7 @@ * Tests whether a face includes any kerning data in the 'kern' table. * Does NOT test for kerning lookups in the GPOS table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ bool @@ -95,7 +95,7 @@ * Tests whether a face includes any state-machine kerning in the 'kern' table. * Does NOT examine the GPOS table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ bool @@ -115,7 +115,7 @@ * * Does NOT examine the GPOS table. * - * Return value: %true is data found, %false otherwise + * Return value: `true` is data found, `false` otherwise * **/ bool @@ -272,7 +272,7 @@ * * Tests whether a face has any glyph classes defined in its GDEF table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ hb_bool_t @@ -461,7 +461,7 @@ * Fetches the index if a given script tag in the specified face's GSUB table * or GPOS table. * - * Return value: %true if the script is found, %false otherwise + * Return value: `true` if the script is found, `false` otherwise * **/ hb_bool_t @@ -500,8 +500,8 @@ * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_tags: Array of #hb_tag_t script tags - * @script_index: (out): The index of the requested script tag - * @chosen_script: (out): #hb_tag_t of the script tag requested + * @script_index: (out): The index of the chosen script + * @chosen_script: (out): #hb_tag_t of the chosen script * * Deprecated since 2.0.0 **/ @@ -531,11 +531,11 @@ * * If the table does not have any of the requested scripts, then `DFLT`, * `dflt`, and `latn` tags are tried in that order. If the table still does not - * have any of these scripts, @script_index and @chosen_script are set to - * #HB_OT_LAYOUT_NO_SCRIPT_INDEX. + * have any of these scripts, @script_index is set to + * #HB_OT_LAYOUT_NO_SCRIPT_INDEX and @chosen_script is set to #HB_TAG_NONE. * * Return value: - * %true if one of the requested scripts is selected, %false if a fallback + * `true` if one of the requested scripts is selected, `false` if a fallback * script is selected or if no scripts are selected. * * Since: 2.0.0 @@ -586,7 +586,7 @@ if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; if (chosen_script) - *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX; + *chosen_script = HB_TAG_NONE; return false; } @@ -601,9 +601,13 @@ * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table * * Fetches a list of all feature tags in the given face's GSUB or GPOS table. + * Note that there might be duplicate feature tags, belonging to different + * script/language-system pairs of the table. * * Return value: Total number of feature tags. * + * Since: 0.6.0 + * **/ unsigned int hb_ot_layout_table_get_feature_tags (hb_face_t *face, @@ -628,7 +632,10 @@ * Fetches the index for a given feature tag in the specified face's GSUB table * or GPOS table. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise + * + * Since: 0.6.0 + * **/ bool hb_ot_layout_table_find_feature (hb_face_t *face, @@ -668,6 +675,8 @@ * * Return value: Total number of language tags. * + * Since: 0.6.0 + * **/ unsigned int hb_ot_layout_script_get_language_tags (hb_face_t *face, @@ -695,7 +704,7 @@ * Fetches the index of a given language tag in the specified face's GSUB table * or GPOS table, underneath the specified script tag. * - * Return value: %true if the language tag is found, %false otherwise + * Return value: `true` if the language tag is found, `false` otherwise * * Since: 0.6.0 * Deprecated: 2.0.0 @@ -718,32 +727,35 @@ /** - * hb_ot_layout_script_select_language: + * hb_ot_layout_script_select_language2: * @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_count: The number of languages in the specified script * @language_tags: The array of language tags - * @language_index: (out): The index of the requested language + * @language_index: (out): The index of the chosen language + * @chosen_language: (out): #hb_tag_t of the chosen language * * Fetches the index of the first language tag fom @language_tags that is present * in the specified face's GSUB or GPOS table, underneath the specified script * index. * - * If none of the given language tags is found, %false is returned and - * @language_index is set to the default language index. + * If none of the given language tags is found, `false` is returned and + * @language_index is set to #HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX and + * @chosen_language is set to #HB_TAG_NONE. * - * Return value: %true if one of the given language tags is found, %false otherwise + * Return value: `true` if one of the given language tags is found, `false` otherwise * - * Since: 2.0.0 + * Since: 7.0.0 **/ hb_bool_t -hb_ot_layout_script_select_language (hb_face_t *face, +hb_ot_layout_script_select_language2 (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, unsigned int language_count, const hb_tag_t *language_tags, - unsigned int *language_index /* OUT */) + unsigned int *language_index /* OUT */, + hb_tag_t *chosen_language /* OUT */) { static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX), ""); const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); @@ -752,18 +764,61 @@ for (i = 0; i < language_count; i++) { if (s.find_lang_sys_index (language_tags[i], language_index)) + { + if (chosen_language) + *chosen_language = language_tags[i]; return true; + } } /* try finding 'dflt' */ if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) + { + if (chosen_language) + *chosen_language = HB_OT_TAG_DEFAULT_LANGUAGE; return false; + } if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; + if (chosen_language) + *chosen_language = HB_TAG_NONE; return false; } +/** + * hb_ot_layout_script_select_language: + * @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_count: The number of languages in the specified script + * @language_tags: The array of language tags + * @language_index: (out): The index of the requested language + * + * Fetches the index of the first language tag fom @language_tags that is present + * in the specified face's GSUB or GPOS table, underneath the specified script + * index. + * + * If none of the given language tags is found, `false` is returned and + * @language_index is set to the default language index. + * + * Return value: `true` if one of the given language tags is found, `false` otherwise + * + * Since: 2.0.0 + **/ +hb_bool_t +hb_ot_layout_script_select_language (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_index, + unsigned int language_count, + const hb_tag_t *language_tags, + unsigned int *language_index /* OUT */) +{ + return hb_ot_layout_script_select_language2 (face, table_tag, + script_index, + language_count, language_tags, + language_index, nullptr); +} /** * hb_ot_layout_language_get_required_feature_index: @@ -776,7 +831,9 @@ * Fetches the index of a requested feature in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise + * + * Since: 0.6.0 * **/ hb_bool_t @@ -807,7 +864,7 @@ * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise * * Since: 0.9.30 **/ @@ -846,6 +903,9 @@ * returned will begin at the offset provided. * * Return value: Total number of features. + * + * Since: 0.6.0 + * **/ unsigned int hb_ot_layout_language_get_feature_indexes (hb_face_t *face, @@ -879,6 +939,9 @@ * returned will begin at the offset provided. * * Return value: Total number of feature tags. + * + * Since: 0.6.0 + * **/ unsigned int hb_ot_layout_language_get_feature_tags (hb_face_t *face, @@ -917,7 +980,9 @@ * Fetches the index of a given feature tag in the specified face's GSUB table * or GPOS table, underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise + * + * Since: 0.6.0 * **/ hb_bool_t @@ -1167,9 +1232,12 @@ * hb_ot_layout_collect_features: * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS - * @scripts: The array of scripts to collect features for - * @languages: The array of languages to collect features for - * @features: The array of features to collect + * @scripts: (nullable) (array zero-terminated=1): The array of scripts to collect features for, + * terminated by %HB_TAG_NONE + * @languages: (nullable) (array zero-terminated=1): The array of languages to collect features for, + * 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 * * Fetches a list of all feature indexes in the specified face's GSUB table @@ -1216,9 +1284,12 @@ * hb_ot_layout_collect_lookups: * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS - * @scripts: The array of scripts to collect lookups for - * @languages: The array of languages to collect lookups for - * @features: The array of features to collect lookups for + * @scripts: (nullable) (array zero-terminated=1): The array of scripts to collect lookups for, + * terminated by %HB_TAG_NONE + * @languages: (nullable) (array zero-terminated=1): The array of languages to collect lookups for, + * terminated by %HB_TAG_NONE + * @features: (nullable) (array zero-terminated=1): The array of features to collect lookups for, + * terminated by %HB_TAG_NONE * @lookup_indexes: (out): The array of lookup indexes found for the query * * Fetches a list of all feature-lookup indexes in the specified face's GSUB @@ -1246,7 +1317,7 @@ hb_set_next (&feature_indexes, &feature_index);) g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes); - g.feature_variation_collect_lookups (&feature_indexes, lookup_indexes); + g.feature_variation_collect_lookups (&feature_indexes, nullptr, lookup_indexes); } @@ -1314,7 +1385,9 @@ * Fetches a list of feature variations in the specified face's GSUB table * or GPOS table, at the specified variation coordinates. * - * Return value: %true if feature variations were found, %false otherwise. + * Return value: `true` if feature variations were found, `false` otherwise. + * + * Since: 1.4.0 * **/ hb_bool_t @@ -1347,6 +1420,8 @@ * * Return value: Total number of lookups. * + * Since: 1.4.0 + * **/ unsigned int hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, @@ -1377,7 +1452,9 @@ * * Tests whether the specified face includes any GSUB substitutions. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise + * + * Since: 0.6.0 * **/ hb_bool_t @@ -1399,7 +1476,7 @@ * Tests whether a specified lookup in the specified face would * trigger a substitution on the given glyph sequence. * - * Return value: %true if a substitution would be triggered, %false otherwise + * Return value: `true` if a substitution would be triggered, `false` otherwise * * Since: 0.9.7 **/ @@ -1410,11 +1487,13 @@ unsigned int glyphs_length, hb_bool_t zero_context) { - if (unlikely (lookup_index >= face->table.GSUB->lookup_count)) return false; + auto &gsub = face->table.GSUB; + if (unlikely (lookup_index >= gsub->lookup_count)) return false; OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context); - const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); - return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]); + const OT::SubstLookup& l = gsub->table->get_lookup (lookup_index); + auto *accel = gsub->get_accel (lookup_index); + return accel && l.would_apply (&c, accel); } @@ -1434,56 +1513,6 @@ _hb_ot_layout_set_glyph_props (font, buffer); } -void -hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer, - bool (*filter) (const hb_glyph_info_t *info)) -{ - /* Merge clusters and delete filtered glyphs. - * NOTE! We can't use out-buffer as we have positioning data. */ - unsigned int j = 0; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int i = 0; i < count; i++) - { - if (filter (&info[i])) - { - /* Merge clusters. - * Same logic as buffer->delete_glyph(), but for in-place removal. */ - - unsigned int cluster = info[i].cluster; - if (i + 1 < count && cluster == info[i + 1].cluster) - continue; /* Cluster survives; do nothing. */ - - if (j) - { - /* Merge cluster backward. */ - if (cluster < info[j - 1].cluster) - { - unsigned int mask = info[i].mask; - unsigned int old_cluster = info[j - 1].cluster; - for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) - buffer->set_cluster (info[k - 1], cluster, mask); - } - continue; - } - - if (i + 1 < count) - buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */ - - continue; - } - - if (j != i) - { - info[j] = info[i]; - pos[j] = pos[i]; - } - j++; - } - buffer->len = j; -} - /** * hb_ot_layout_lookup_substitute_closure: * @face: #hb_face_t to work upon @@ -1561,7 +1590,7 @@ * * Tests whether the specified face includes any GPOS positioning. * - * Return value: %true if the face has GPOS data, %false otherwise + * Return value: `true` if the face has GPOS data, `false` otherwise * **/ hb_bool_t @@ -1634,7 +1663,7 @@ * For more information on this distinction, see the [`size` feature documentation]( * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.10 **/ @@ -1678,6 +1707,8 @@ return false; } + + /** * hb_ot_layout_feature_get_name_ids: * @face: #hb_face_t to work upon @@ -1698,7 +1729,7 @@ * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or * "Character Variant" ('cvXX') features. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.0.0 **/ @@ -1801,11 +1832,9 @@ typedef OT::SubstLookup Lookup; GSUBProxy (hb_face_t *face) : - table (*face->table.GSUB->table), - accels (face->table.GSUB->accels) {} + accel (*face->table.GSUB) {} - const GSUB &table; - const OT::hb_ot_layout_lookup_accelerator_t *accels; + const GSUB::accelerator_t &accel; }; struct GPOSProxy @@ -1815,17 +1844,16 @@ typedef OT::PosLookup Lookup; GPOSProxy (hb_face_t *face) : - table (*face->table.GPOS->table), - accels (face->table.GPOS->accels) {} + accel (*face->table.GPOS) {} - const GPOS &table; - const OT::hb_ot_layout_lookup_accelerator_t *accels; + const GPOS::accelerator_t &accel; }; static inline bool apply_forward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel) + const OT::hb_ot_layout_lookup_accelerator_t &accel, + unsigned subtable_count) { bool use_cache = accel.cache_enter (c); @@ -1834,11 +1862,11 @@ while (buffer->idx < buffer->len && buffer->successful) { bool applied = false; - if (accel.may_have (buffer->cur().codepoint) && + if (accel.digest.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) { - applied = accel.apply (c, use_cache); + applied = accel.apply (c, subtable_count, use_cache); } if (applied) @@ -1855,16 +1883,17 @@ static inline bool apply_backward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel) + const OT::hb_ot_layout_lookup_accelerator_t &accel, + unsigned subtable_count) { bool ret = false; hb_buffer_t *buffer = c->buffer; do { - if (accel.may_have (buffer->cur().codepoint) && + 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, false); + ret |= accel.apply (c, subtable_count, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -1875,15 +1904,18 @@ } template -static inline void +static inline bool apply_string (OT::hb_ot_apply_context_t *c, const typename Proxy::Lookup &lookup, const OT::hb_ot_layout_lookup_accelerator_t &accel) { hb_buffer_t *buffer = c->buffer; + unsigned subtable_count = lookup.get_subtable_count (); if (unlikely (!buffer->len || !c->lookup_mask)) - return; + return false; + + bool ret = false; c->set_lookup_props (lookup.get_props ()); @@ -1894,7 +1926,7 @@ buffer->clear_output (); buffer->idx = 0; - apply_forward (c, accel); + ret = apply_forward (c, accel, subtable_count); if (!Proxy::always_inplace) buffer->sync (); @@ -1904,8 +1936,10 @@ /* in-place backward substitution/positioning */ assert (!buffer->have_output); buffer->idx = buffer->len - 1; - apply_backward (c, accel); + ret = apply_backward (c, accel, subtable_count); } + + return ret; } template @@ -1924,40 +1958,69 @@ const stage_map_t *stage = &stages[table_index][stage_index]; for (; i < stage->last_lookup; i++) { - unsigned int lookup_index = lookups[table_index][i].index; - if (!buffer->message (font, "start lookup %d", lookup_index)) continue; - c.set_lookup_index (lookup_index); - c.set_lookup_mask (lookups[table_index][i].mask); - c.set_auto_zwj (lookups[table_index][i].auto_zwj); - c.set_auto_zwnj (lookups[table_index][i].auto_zwnj); - c.set_random (lookups[table_index][i].random); - c.set_per_syllable (lookups[table_index][i].per_syllable); - - apply_string (&c, - proxy.table.get_lookup (lookup_index), - proxy.accels[lookup_index]); - (void) buffer->message (font, "end lookup %d", lookup_index); + auto &lookup = lookups[table_index][i]; + + unsigned int lookup_index = lookup.index; + + auto *accel = proxy.accel.get_accel (lookup_index); + if (unlikely (!accel)) continue; + + if (buffer->messaging () && + !buffer->message (font, "start lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue; + + /* c.digest is a digest of all the current glyphs in the buffer + * (plus some past glyphs). + * + * Only try applying the lookup if there is any overlap. */ + 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_random (lookup.random); + c.set_per_syllable (lookup.per_syllable); + + apply_string (&c, + proxy.accel.table->get_lookup (lookup_index), + *accel); + } + else if (buffer->messaging ()) + (void) buffer->message (font, "skipped lookup %u feature '%c%c%c%c' because no glyph matches", lookup_index, HB_UNTAG (lookup.feature_tag)); + + if (buffer->messaging ()) + (void) buffer->message (font, "end lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag)); } if (stage->pause_func) - stage->pause_func (plan, font, buffer); + { + if (stage->pause_func (plan, font, buffer)) + { + /* Refresh working buffer digest since buffer changed. */ + c.digest = buffer->digest (); + } + } } } void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { GSUBProxy proxy (font->face); - if (!buffer->message (font, "start table GSUB")) return; + if (buffer->messaging () && + !buffer->message (font, "start table GSUB")) return; apply (proxy, plan, font, buffer); - (void) buffer->message (font, "end table GSUB"); + if (buffer->messaging ()) + (void) buffer->message (font, "end table GSUB"); } 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->message (font, "start table GPOS")) return; + if (buffer->messaging () && + !buffer->message (font, "start table GPOS")) return; apply (proxy, plan, font, buffer); - (void) buffer->message (font, "end table GPOS"); + if (buffer->messaging ()) + (void) buffer->message (font, "end table GPOS"); } void @@ -2051,7 +2114,7 @@ * * Fetches a baseline value from the face. * - * Return value: %true if found baseline value in the font. + * Return value: `true` if found baseline value in the font. * * Since: 2.6.0 **/ @@ -2297,11 +2360,6 @@ static return_t default_return_value () { return 0; } bool stop_sublookup_iteration (return_t r) const { return r; } - hb_face_t *face; - - hb_get_glyph_alternates_dispatch_t (hb_face_t *face) : - face (face) {} - private: template auto _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN @@ -2315,6 +2373,7 @@ ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) }; +#ifndef HB_NO_LAYOUT_RARELY_USED /** * hb_ot_layout_lookup_get_glyph_alternates: * @face: a face. @@ -2340,11 +2399,79 @@ unsigned *alternate_count /* IN/OUT. May be NULL. */, hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) { - hb_get_glyph_alternates_dispatch_t c (face); + hb_get_glyph_alternates_dispatch_t c; const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index); auto ret = lookup.dispatch (&c, glyph, start_offset, alternate_count, alternate_glyphs); if (!ret && alternate_count) *alternate_count = 0; return ret; } + +struct hb_position_single_dispatch_t : + hb_dispatch_context_t +{ + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return r; } + + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN + ( obj.position_single (std::forward (ds)...) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN + ( default_return_value () ) + public: + template auto + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) +}; + +/** + * hb_ot_layout_lookup_get_optical_bound: + * @font: a font. + * @lookup_index: index of the feature lookup to query. + * @direction: edge of the glyph to query. + * @glyph: a glyph id. + * + * Fetches the optical bound of a glyph positioned at the margin of text. + * The direction identifies which edge of the glyph to query. + * + * Return value: Adjustment value. Negative values mean the glyph will stick out of the margin. + * + * Since: 5.3.0 + **/ +hb_position_t +hb_ot_layout_lookup_get_optical_bound (hb_font_t *font, + unsigned lookup_index, + hb_direction_t direction, + hb_codepoint_t glyph) +{ + const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index); + hb_glyph_position_t pos = {0}; + hb_position_single_dispatch_t c; + lookup.dispatch (&c, font, direction, glyph, pos); + hb_position_t ret = 0; + switch (direction) + { + case HB_DIRECTION_LTR: + ret = pos.x_offset; + break; + case HB_DIRECTION_RTL: + ret = pos.x_advance - pos.x_offset; + break; + case HB_DIRECTION_TTB: + ret = pos.y_offset; + break; + case HB_DIRECTION_BTT: + ret = pos.y_advance - pos.y_offset; + break; + case HB_DIRECTION_INVALID: + default: + break; + } + return ret; +} +#endif + + #endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -35,69 +35,42 @@ #include "hb-set.hh" #include "hb-bimap.hh" +#include "OT/Layout/Common/Coverage.hh" +#include "OT/Layout/types.hh" -#ifndef HB_MAX_NESTING_LEVEL -#define HB_MAX_NESTING_LEVEL 64 -#endif -#ifndef HB_MAX_CONTEXT_LENGTH -#define HB_MAX_CONTEXT_LENGTH 64 -#endif -#ifndef HB_CLOSURE_MAX_STAGES -/* - * The maximum number of times a lookup can be applied during shaping. - * Used to limit the number of iterations of the closure algorithm. - * This must be larger than the number of times add_pause() is - * called in a collect_features call of any shaper. - */ -#define HB_CLOSURE_MAX_STAGES 32 -#endif - -#ifndef HB_MAX_SCRIPTS -#define HB_MAX_SCRIPTS 500 -#endif - -#ifndef HB_MAX_LANGSYS -#define HB_MAX_LANGSYS 2000 -#endif - -#ifndef HB_MAX_LANGSYS_FEATURE_COUNT -#define HB_MAX_LANGSYS_FEATURE_COUNT 50000 -#endif - -#ifndef HB_MAX_FEATURES -#define HB_MAX_FEATURES 750 -#endif - -#ifndef HB_MAX_FEATURE_INDICES -#define HB_MAX_FEATURE_INDICES 1500 -#endif - -#ifndef HB_MAX_LOOKUP_VISIT_COUNT -#define HB_MAX_LOOKUP_VISIT_COUNT 35000 -#endif +// TODO(garretrieger): cleanup these after migration. +using OT::Layout::Common::Coverage; +using OT::Layout::Common::RangeRecord; +using OT::Layout::SmallTypes; +using OT::Layout::MediumTypes; namespace OT { - -#define NOT_COVERED ((unsigned int) -1) - - template -static inline void Coverage_serialize (hb_serialize_context_t *c, +static inline bool ClassDef_serialize (hb_serialize_context_t *c, Iterator it); -template -static inline void ClassDef_serialize (hb_serialize_context_t *c, - Iterator it); - -static void ClassDef_remap_and_serialize ( +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_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; + hb_hashmap_t> *record_cond_idx_map; + hb_hashmap_t *feature_substitutes_map; + + // not stored in subset_plan + hb_set_t *feature_indices; + bool apply; + unsigned cur_record_idx; + hb_hashmap_t, unsigned> *conditionset_map; +}; struct hb_prune_langsys_context_t { @@ -164,24 +137,40 @@ const hb_map_t *lookup_index_map; const hb_hashmap_t> *script_langsys_map; const hb_map_t *feature_index_map; + const hb_hashmap_t *feature_substitutes_map; + hb_hashmap_t> *feature_record_cond_idx_map; + unsigned cur_script_index; + unsigned cur_feature_var_record_idx; hb_subset_layout_context_t (hb_subset_context_t *c_, - hb_tag_t tag_, - hb_map_t *lookup_map_, - hb_hashmap_t> *script_langsys_map_, - hb_map_t *feature_index_map_) : + hb_tag_t tag_) : subset_context (c_), table_tag (tag_), - lookup_index_map (lookup_map_), - script_langsys_map (script_langsys_map_), - feature_index_map (feature_index_map_), cur_script_index (0xFFFFu), + cur_feature_var_record_idx (0u), script_count (0), langsys_count (0), feature_index_count (0), lookup_index_count (0) - {} + { + if (tag_ == HB_OT_TAG_GSUB) + { + lookup_index_map = &c_->plan->gsub_lookups; + script_langsys_map = &c_->plan->gsub_langsys; + feature_index_map = &c_->plan->gsub_features; + feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; + feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; + } + else + { + lookup_index_map = &c_->plan->gpos_lookups; + script_langsys_map = &c_->plan->gpos_langsys; + feature_index_map = &c_->plan->gpos_features; + feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; + feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; + } + } private: unsigned script_count; @@ -190,6 +179,7 @@ unsigned lookup_index_count; }; +struct VariationStore; struct hb_collect_variation_indices_context_t : hb_dispatch_context_t { @@ -198,15 +188,27 @@ 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_) : + const hb_map_t *gpos_lookups_, + float *store_cache_) : 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_) {} + gpos_lookups (gpos_lookups_), + store_cache (store_cache_) {} }; template @@ -315,6 +317,31 @@ const void *base; }; +template +struct subset_record_array_arg_t +{ + subset_record_array_arg_t (hb_subset_layout_context_t *c_, OutputArray* out_, + const void *base_, + Arg &&arg_) : subset_layout_context (c_), + out (out_), base (base_), arg (arg_) {} + + template + void + operator () (T&& record) + { + auto snap = subset_layout_context->subset_context->serializer->snapshot (); + bool ret = record.subset (subset_layout_context, base, arg); + if (!ret) subset_layout_context->subset_context->serializer->revert (snap); + else out->len++; + } + + private: + hb_subset_layout_context_t *subset_layout_context; + OutputArray *out; + const void *base; + Arg &&arg; +}; + /* * Helper to subset a RecordList/record array. Subsets each Record in the array and * discards the record if the subset operation returns false. @@ -326,6 +353,13 @@ operator () (hb_subset_layout_context_t *c, OutputArray* out, const void *base) const { return subset_record_array_t (c, out, base); } + + /* Variant with one extra argument passed to subset */ + template + subset_record_array_arg_t + operator () (hb_subset_layout_context_t *c, OutputArray* out, + const void *base, Arg &&arg) const + { return subset_record_array_arg_t (c, out, base, arg); } } HB_FUNCOBJ (subset_record_array); @@ -377,166 +411,6 @@ * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList */ -struct Record_sanitize_closure_t { - hb_tag_t tag; - const void *list_base; -}; - -template -struct Record -{ - int cmp (hb_tag_t a) const { return tag.cmp (a); } - - bool subset (hb_subset_layout_context_t *c, const void *base) const - { - TRACE_SUBSET (this); - auto *out = c->subset_context->serializer->embed (this); - if (unlikely (!out)) return_trace (false); - bool ret = out->offset.serialize_subset (c->subset_context, offset, base, c, &tag); - return_trace (ret); - } - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - const Record_sanitize_closure_t closure = {tag, base}; - return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); - } - - Tag tag; /* 4-byte Tag identifier */ - Offset16To - offset; /* Offset from beginning of object holding - * the Record */ - public: - DEFINE_SIZE_STATIC (6); -}; - -template -struct RecordArrayOf : SortedArray16Of> -{ - const Offset16To& get_offset (unsigned int i) const - { return (*this)[i].offset; } - Offset16To& get_offset (unsigned int i) - { return (*this)[i].offset; } - const Tag& get_tag (unsigned int i) const - { return (*this)[i].tag; } - unsigned int get_tags (unsigned int start_offset, - unsigned int *record_count /* IN/OUT */, - hb_tag_t *record_tags /* OUT */) const - { - if (record_count) - { - + this->sub_array (start_offset, record_count) - | hb_map (&Record::tag) - | hb_sink (hb_array (record_tags, *record_count)) - ; - } - return this->len; - } - bool find_index (hb_tag_t tag, unsigned int *index) const - { - return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); - } -}; - -template -struct RecordListOf : RecordArrayOf -{ - const Type& operator [] (unsigned int i) const - { return this+this->get_offset (i); } - - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - - + this->iter () - | hb_apply (subset_record_array (l, out, this)) - ; - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (RecordArrayOf::sanitize (c, this)); - } -}; - -struct Feature; - -struct RecordListOfFeature : RecordListOf -{ - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - unsigned count = this->len; - + hb_zip (*this, hb_range (count)) - | hb_filter (l->feature_index_map, hb_second) - | hb_map (hb_first) - | hb_apply (subset_record_array (l, out, this)) - ; - return_trace (true); - } -}; - -struct Script; -struct RecordListOfScript : RecordListOf::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const +{ + (this+src).dispatch (c); + (this+backdrop).dispatch (c); +} + +} /* namespace OT */ + + +#endif /* OT_COLOR_COLR_COLRV1_CLOSURE_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,322 @@ +/* + * Copyright © 2016 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi + * + * 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): Sascha Brawer + */ + +#ifndef OT_COLOR_CPAL_CPAL_HH +#define OT_COLOR_CPAL_CPAL_HH + +#include "../../../hb-open-type.hh" +#include "../../../hb-ot-color.h" +#include "../../../hb-ot-name.h" + + +/* + * CPAL -- Color Palette + * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal + */ +#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L') + +namespace OT { + + +struct CPALV1Tail +{ + friend struct CPAL; + + private: + hb_ot_color_palette_flags_t get_palette_flags (const void *base, + unsigned int palette_index, + unsigned int palette_count) const + { + if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; + return (hb_ot_color_palette_flags_t) (uint32_t) + (base+paletteFlagsZ).as_array (palette_count)[palette_index]; + } + + hb_ot_name_id_t get_palette_name_id (const void *base, + unsigned int palette_index, + unsigned int palette_count) const + { + if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID; + return (base+paletteLabelsZ).as_array (palette_count)[palette_index]; + } + + hb_ot_name_id_t get_color_name_id (const void *base, + unsigned int color_index, + unsigned int color_count) const + { + if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID; + return (base+colorLabelsZ).as_array (color_count)[color_index]; + } + + public: + bool serialize (hb_serialize_context_t *c, + unsigned palette_count, + unsigned color_count, + const void *base, + const hb_map_t *color_index_map) const + { + TRACE_SERIALIZE (this); + auto *out = c->allocate_size (static_size); + if (unlikely (!out)) return_trace (false); + + out->paletteFlagsZ = 0; + if (paletteFlagsZ) + out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count); + + out->paletteLabelsZ = 0; + if (paletteLabelsZ) + out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count); + + const hb_array_t colorLabels = (base+colorLabelsZ).as_array (color_count); + if (colorLabelsZ) + { + c->push (); + for (const auto _ : colorLabels) + { + const hb_codepoint_t *v; + if (!color_index_map->has (_, &v)) continue; + NameID new_color_idx; + new_color_idx = *v; + if (!c->copy (new_color_idx)) + { + c->pop_discard (); + return_trace (false); + } + } + c->add_link (out->colorLabelsZ, c->pop_pack ()); + } + return_trace (true); + } + + bool sanitize (hb_sanitize_context_t *c, + const void *base, + unsigned int palette_count, + unsigned int color_count) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + (!paletteFlagsZ || (base+paletteFlagsZ).sanitize (c, palette_count)) && + (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) && + (!colorLabelsZ || (base+colorLabelsZ).sanitize (c, color_count))); + } + + protected: + // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets + // here. Currently they are needed since UnsizedArrayOf doesn't define null_size + NNOffset32To> + paletteFlagsZ; /* Offset from the beginning of CPAL table to + * the Palette Type Array. Set to 0 if no array + * is provided. */ + NNOffset32To> + paletteLabelsZ; /* Offset from the beginning of CPAL table to + * the palette labels array. Set to 0 if no + * array is provided. */ + NNOffset32To> + colorLabelsZ; /* Offset from the beginning of CPAL table to + * the color labels array. Set to 0 + * if no array is provided. */ + public: + DEFINE_SIZE_STATIC (12); +}; + +typedef HBUINT32 BGRAColor; + +struct CPAL +{ + static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL; + + bool has_data () const { return numPalettes; } + + unsigned int get_size () const + { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); } + + unsigned int get_palette_count () const { return numPalettes; } + unsigned int get_color_count () const { return numColors; } + + hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const + { return v1 ().get_palette_flags (this, palette_index, numPalettes); } + + hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const + { return v1 ().get_palette_name_id (this, palette_index, numPalettes); } + + hb_ot_name_id_t get_color_name_id (unsigned int color_index) const + { return v1 ().get_color_name_id (this, color_index, numColors); } + + unsigned int get_palette_colors (unsigned int palette_index, + unsigned int start_offset, + unsigned int *color_count, /* IN/OUT. May be NULL. */ + hb_color_t *colors /* OUT. May be NULL. */) const + { + if (unlikely (palette_index >= numPalettes)) + { + if (color_count) *color_count = 0; + return 0; + } + unsigned int start_index = colorRecordIndicesZ[palette_index]; + hb_array_t all_colors ((this+colorRecordsZ).arrayZ, numColorRecords); + hb_array_t palette_colors = all_colors.sub_array (start_index, + numColors); + if (color_count) + { + + palette_colors.sub_array (start_offset, color_count) + | hb_sink (hb_array (colors, *color_count)) + ; + } + return numColors; + } + + private: + const CPALV1Tail& v1 () const + { + if (version == 0) return Null (CPALV1Tail); + return StructAfter (*this); + } + + public: + bool serialize (hb_serialize_context_t *c, + const hb_array_t &color_record_indices, + const hb_array_t &color_records, + const hb_vector_t& first_color_index_for_layer, + const hb_map_t& first_color_to_layer_index, + const hb_set_t &retained_color_indices) const + { + TRACE_SERIALIZE (this); + + // TODO(grieger): limit total final size. + + for (const auto idx : color_record_indices) + { + hb_codepoint_t layer_index = first_color_to_layer_index[idx]; + + HBUINT16 new_idx; + new_idx = layer_index * retained_color_indices.get_population (); + if (!c->copy (new_idx)) return_trace (false); + } + + c->push (); + for (unsigned first_color_index : first_color_index_for_layer) + { + for (hb_codepoint_t color_index : retained_color_indices) + { + if (!c->copy (color_records[first_color_index + color_index])) + { + c->pop_discard (); + return_trace (false); + } + } + } + + c->add_link (colorRecordsZ, c->pop_pack ()); + return_trace (true); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + if (!numPalettes) return_trace (false); + + const hb_map_t *color_index_map = &c->plan->colr_palettes; + if (color_index_map->is_empty ()) return_trace (false); + + hb_set_t retained_color_indices; + for (const auto _ : color_index_map->keys ()) + { + if (_ == 0xFFFF) continue; + retained_color_indices.add (_); + } + if (retained_color_indices.is_empty ()) return_trace (false); + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + + out->version = version; + out->numColors = retained_color_indices.get_population (); + out->numPalettes = numPalettes; + + hb_vector_t first_color_index_for_layer; + hb_map_t first_color_to_layer_index; + + const hb_array_t colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes); + for (const auto first_color_record_idx : colorRecordIndices) + { + if (first_color_to_layer_index.has (first_color_record_idx)) continue; + + first_color_index_for_layer.push (first_color_record_idx); + first_color_to_layer_index.set (first_color_record_idx, + first_color_index_for_layer.length - 1); + } + + out->numColorRecords = first_color_index_for_layer.length + * retained_color_indices.get_population (); + + const hb_array_t color_records = (this+colorRecordsZ).as_array (numColorRecords); + if (!out->serialize (c->serializer, + colorRecordIndices, + color_records, + first_color_index_for_layer, + first_color_to_layer_index, + retained_color_indices)) + return_trace (false); + + if (version == 1) + return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map)); + + return_trace (true); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + (this+colorRecordsZ).sanitize (c, numColorRecords) && + colorRecordIndicesZ.sanitize (c, numPalettes) && + (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors))); + } + + protected: + HBUINT16 version; /* Table version number */ + /* Version 0 */ + HBUINT16 numColors; /* Number of colors in each palette. */ + HBUINT16 numPalettes; /* Number of palettes in the table. */ + HBUINT16 numColorRecords; /* Total number of color records, combined for + * all palettes. */ + NNOffset32To> + colorRecordsZ; /* Offset from the beginning of CPAL table to + * the first ColorRecord. */ + UnsizedArrayOf + colorRecordIndicesZ; /* Index of each palette’s first color record in + * the combined color record array. */ +/*CPALV1Tail v1;*/ + public: + DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ); +}; + +} /* namespace OT */ + + +#endif /* OT_COLOR_CPAL_CPAL_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,452 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * Copyright © 2020 Google, 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. + * + * Google Author(s): Calder Kitagawa + */ + +#ifndef OT_COLOR_SBIX_SBIX_HH +#define OT_COLOR_SBIX_SBIX_HH + +#include "../../../hb-open-type.hh" +#include "../../../hb-paint.hh" + +/* + * sbix -- Standard Bitmap Graphics + * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html + */ +#define HB_OT_TAG_sbix HB_TAG('s','b','i','x') + + +namespace OT { + + +struct SBIXGlyph +{ + SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const + { + 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; + new_glyph->yOffset = yOffset; + new_glyph->graphicType = graphicType; + data.copy (c, data_length); + return_trace (new_glyph); + } + + HBINT16 xOffset; /* The horizontal (x-axis) offset from the left + * edge of the graphic to the glyph’s origin. + * That is, the x-coordinate of the point on the + * baseline at the left edge of the glyph. */ + HBINT16 yOffset; /* The vertical (y-axis) offset from the bottom + * edge of the graphic to the glyph’s origin. + * That is, the y-coordinate of the point on the + * baseline at the left edge of the glyph. */ + Tag graphicType; /* Indicates the format of the embedded graphic + * data: one of 'jpg ', 'png ' or 'tiff', or the + * special format 'dupe'. */ + UnsizedArrayOf + data; /* The actual embedded graphic data. The total + * length is inferred from sequential entries in + * the glyphDataOffsets array and the fixed size + * (8 bytes) of the preceding fields. */ + public: + DEFINE_SIZE_ARRAY (8, data); +}; + +struct SBIXStrike +{ + static unsigned int get_size (unsigned num_glyphs) + { return min_size + num_glyphs * HBUINT32::static_size; } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1)); + } + + hb_blob_t *get_glyph_blob (unsigned int glyph_id, + hb_blob_t *sbix_blob, + hb_tag_t file_type, + int *x_offset, + int *y_offset, + unsigned int num_glyphs, + unsigned int *strike_ppem) const + { + if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */ + + unsigned int retry_count = 8; + unsigned int sbix_len = sbix_blob->length; + unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; + assert (strike_offset < sbix_len); + + retry: + if (unlikely (glyph_id >= num_glyphs || + imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] || + imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size || + (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset)) + return hb_blob_get_empty (); + + unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size; + unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size; + + const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); + + if (glyph->graphicType == HB_TAG ('d','u','p','e')) + { + if (glyph_length >= 2) + { + glyph_id = *((HBUINT16 *) &glyph->data); + if (retry_count--) + goto retry; + } + return hb_blob_get_empty (); + } + + if (unlikely (file_type != glyph->graphicType)) + return hb_blob_get_empty (); + + if (strike_ppem) *strike_ppem = ppem; + if (x_offset) *x_offset = glyph->xOffset; + if (y_offset) *y_offset = glyph->yOffset; + return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length); + } + + bool subset (hb_subset_context_t *c, unsigned int available_len) const + { + TRACE_SUBSET (this); + 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; + out->resolution = resolution; + HBUINT32 head; + head = get_size (num_output_glyphs + 1); + + bool has_glyphs = false; + for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++) + { + hb_codepoint_t old_gid; + if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) || + unlikely (imageOffsetsZ[old_gid].is_null () || + imageOffsetsZ[old_gid + 1].is_null () || + imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] || + imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) || + (unsigned int) imageOffsetsZ[old_gid + 1] > available_len) + { + out->imageOffsetsZ[new_gid] = head; + continue; + } + has_glyphs = true; + unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid]; + unsigned int glyph_data_length = delta - SBIXGlyph::min_size; + if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length)) + return_trace (false); + out->imageOffsetsZ[new_gid] = head; + head += delta; + } + if (has_glyphs) + out->imageOffsetsZ[num_output_glyphs] = head; + else + c->serializer->revert (snap); + return_trace (has_glyphs); + } + + public: + HBUINT16 ppem; /* The PPEM size for which this strike was designed. */ + HBUINT16 resolution; /* The device pixel density (in PPI) for which this + * strike was designed. (E.g., 96 PPI, 192 PPI.) */ + protected: + UnsizedArrayOf> + imageOffsetsZ; /* Offset from the beginning of the strike data header + * to bitmap data for an individual glyph ID. */ + public: + DEFINE_SIZE_ARRAY (4, imageOffsetsZ); +}; + +struct sbix +{ + static constexpr hb_tag_t tableTag = HB_OT_TAG_sbix; + + bool has_data () const { return version; } + + const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; } + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + table = hb_sanitize_context_t ().reference_table (face); + num_glyphs = face->get_num_glyphs (); + } + ~accelerator_t () { table.destroy (); } + + bool has_data () const { return table->has_data (); } + + bool get_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + bool scale = true) const + { + /* We only support PNG right now, and following function checks type. */ + return get_png_extents (font, glyph, extents, scale); + } + + hb_blob_t *reference_png (hb_font_t *font, + hb_codepoint_t glyph_id, + int *x_offset, + int *y_offset, + unsigned int *available_ppem) const + { + return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (), + HB_TAG ('p','n','g',' '), + x_offset, y_offset, + num_glyphs, available_ppem); + } + + bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const + { + if (!has_data ()) + return false; + + int x_offset = 0, y_offset = 0; + unsigned int strike_ppem = 0; + hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); + hb_glyph_extents_t extents; + hb_glyph_extents_t pixel_extents; + + if (blob == hb_blob_get_empty ()) + return false; + + if (!hb_font_get_glyph_extents (font, glyph, &extents)) + return false; + + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) + return false; + + bool ret = funcs->image (data, + blob, + pixel_extents.width, -pixel_extents.height, + HB_PAINT_IMAGE_FORMAT_PNG, + font->slant_xy, + &extents); + + hb_blob_destroy (blob); + return ret; + } + + private: + + const SBIXStrike &choose_strike (hb_font_t *font) const + { + unsigned count = table->strikes.len; + if (unlikely (!count)) + return Null (SBIXStrike); + + unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem); + if (!requested_ppem) + requested_ppem = 1<<30; /* Choose largest strike. */ + /* TODO Add DPI sensitivity as well? */ + unsigned int best_i = 0; + unsigned int best_ppem = table->get_strike (0).ppem; + + for (unsigned int i = 1; i < count; i++) + { + unsigned int ppem = (table->get_strike (i)).ppem; + if ((requested_ppem <= ppem && ppem < best_ppem) || + (requested_ppem > best_ppem && ppem > best_ppem)) + { + best_i = i; + best_ppem = ppem; + } + } + + return table->get_strike (best_i); + } + + struct PNGHeader + { + HBUINT8 signature[8]; + struct + { + struct + { + HBUINT32 length; + Tag type; + } header; + HBUINT32 width; + HBUINT32 height; + HBUINT8 bitDepth; + HBUINT8 colorType; + HBUINT8 compressionMethod; + HBUINT8 filterMethod; + HBUINT8 interlaceMethod; + } IHDR; + + public: + DEFINE_SIZE_STATIC (29); + }; + + bool get_png_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + bool scale = true) const + { + /* Following code is safe to call even without data. + * But faster to short-circuit. */ + if (!has_data ()) + return false; + + int x_offset = 0, y_offset = 0; + unsigned int strike_ppem = 0; + hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); + + const PNGHeader &png = *blob->as(); + + if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536) + { + hb_blob_destroy (blob); + return false; + } + + extents->x_bearing = x_offset; + extents->y_bearing = png.IHDR.height + y_offset; + extents->width = png.IHDR.width; + extents->height = -1 * png.IHDR.height; + + /* Convert to font units. */ + if (strike_ppem && scale) + { + float scale = font->face->get_upem () / (float) strike_ppem; + extents->x_bearing = roundf (extents->x_bearing * scale); + extents->y_bearing = roundf (extents->y_bearing * scale); + extents->width = roundf (extents->width * scale); + extents->height = roundf (extents->height * scale); + } + + if (scale) + font->scale_glyph_extents (extents); + + hb_blob_destroy (blob); + + return strike_ppem; + } + + private: + hb_blob_ptr_t table; + + unsigned int num_glyphs; + }; + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + version >= 1 && + strikes.sanitize (c, this))); + } + + bool + add_strike (hb_subset_context_t *c, unsigned i) const + { + if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i]) + return false; + + return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]); + } + + bool serialize_strike_offsets (hb_subset_context_t *c) const + { + 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; + hb_vector_t objidxs; + for (int i = strikes.len - 1; i >= 0; --i) + { + auto* o = out->serialize_append (c->serializer); + if (unlikely (!o)) return_trace (false); + *o = 0; + auto snap = c->serializer->snapshot (); + c->serializer->push (); + bool ret = add_strike (c, i); + if (!ret) + { + c->serializer->pop_discard (); + out->pop (); + c->serializer->revert (snap); + } + else + { + objidxs.push (c->serializer->pop_pack ()); + new_strikes.push (o); + } + } + for (unsigned int i = 0; i < new_strikes.length; ++i) + c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]); + + return_trace (true); + } + + bool subset (hb_subset_context_t* c) const + { + 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); + + return_trace (serialize_strike_offsets (c)); + } + + protected: + HBUINT16 version; /* Table version number — set to 1 */ + HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. + * Bits 2 to 15: reserved (set to 0). */ + Array32OfOffset32To + strikes; /* Offsets from the beginning of the 'sbix' + * table to data for each individual bitmap strike. */ + public: + DEFINE_SIZE_ARRAY (8, strikes); +}; + +struct sbix_accelerator_t : sbix::accelerator_t { + sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {} +}; + + +} /* namespace OT */ + +#endif /* OT_COLOR_SBIX_SBIX_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * 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 OT_COLOR_SVG_SVG_HH +#define OT_COLOR_SVG_SVG_HH + +#include "../../../hb-open-type.hh" +#include "../../../hb-blob.hh" +#include "../../../hb-paint.hh" + +/* + * SVG -- SVG (Scalable Vector Graphics) + * https://docs.microsoft.com/en-us/typography/opentype/spec/svg + */ + +#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ') + + +namespace OT { + + +struct SVGDocumentIndexEntry +{ + int cmp (hb_codepoint_t g) const + { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; } + + hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const + { + return hb_blob_create_sub_blob (svg_blob, + index_offset + (unsigned int) svgDoc, + svgDocLength); + } + + bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + svgDoc.sanitize (c, base, svgDocLength)); + } + + protected: + HBUINT16 startGlyphID; /* The first glyph ID in the range described by + * this index entry. */ + HBUINT16 endGlyphID; /* The last glyph ID in the range described by + * this index entry. Must be >= startGlyphID. */ + NNOffset32To> + svgDoc; /* Offset from the beginning of the SVG Document Index + * to an SVG document. Must be non-zero. */ + HBUINT32 svgDocLength; /* Length of the SVG document. + * Must be non-zero. */ + public: + DEFINE_SIZE_STATIC (12); +}; + +struct SVG +{ + static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG; + + bool has_data () const { return svgDocEntries; } + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { table = hb_sanitize_context_t ().reference_table (face); } + ~accelerator_t () { table.destroy (); } + + hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const + { + return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (), + table->svgDocEntries); + } + + bool has_data () const { return table->has_data (); } + + bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const + { + if (!has_data ()) + return false; + + hb_blob_t *blob = reference_blob_for_glyph (glyph); + + if (blob == hb_blob_get_empty ()) + return false; + + funcs->image (data, + blob, + 0, 0, + HB_PAINT_IMAGE_FORMAT_SVG, + font->slant_xy, + nullptr); + + hb_blob_destroy (blob); + return true; + } + + private: + hb_blob_ptr_t table; + public: + DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t)); + }; + + const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const + { return (this+svgDocEntries).bsearch (glyph_id); } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (this+svgDocEntries).sanitize_shallow (c))); + } + + protected: + HBUINT16 version; /* Table version (starting at 0). */ + Offset32To> + svgDocEntries; /* Offset (relative to the start of the SVG table) to the + * SVG Documents Index. Must be non-zero. */ + /* Array of SVG Document Index Entries. */ + HBUINT32 reserved; /* Set to 0. */ + public: + DEFINE_SIZE_STATIC (10); +}; + +struct SVG_accelerator_t : SVG::accelerator_t { + SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {} +}; + +} /* namespace OT */ + + +#endif /* OT_COLOR_SVG_SVG_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -3,6 +3,7 @@ #include "../../hb-open-type.hh" +#include "composite-iter.hh" namespace OT { @@ -25,13 +26,20 @@ USE_MY_METRICS = 0x0200, OVERLAP_COMPOUND = 0x0400, SCALED_COMPONENT_OFFSET = 0x0800, - UNSCALED_COMPONENT_OFFSET = 0x1000 + UNSCALED_COMPONENT_OFFSET = 0x1000, +#ifndef HB_NO_BEYOND_64K + GID_IS_24BIT = 0x2000 +#endif }; public: unsigned int get_size () const { unsigned int size = min_size; + /* glyphIndex is 24bit instead of 16bit */ +#ifndef HB_NO_BEYOND_64K + if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size; +#endif /* arg1 and 2 are int16 */ if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; /* arg1 and 2 are int8 */ @@ -60,7 +68,13 @@ bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); } void get_anchor_points (unsigned int &point1, unsigned int &point2) const { - const HBUINT8 *p = &StructAfter (glyphIndex); + const auto *p = &StructAfter (flags); +#ifndef HB_NO_BEYOND_64K + if (flags & GID_IS_24BIT) + p += HBGlyphID24::static_size; + else +#endif + p += HBGlyphID16::static_size; if (flags & ARG_1_AND_2_ARE_WORDS) { point1 = ((const HBUINT16 *) p)[0]; @@ -92,6 +106,67 @@ } } + unsigned compile_with_deltas (const contour_point_t &p_delta, + char *out) const + { + const HBINT8 *p = &StructAfter (flags); +#ifndef HB_NO_BEYOND_64K + if (flags & GID_IS_24BIT) + p += HBGlyphID24::static_size; + else +#endif + p += HBGlyphID16::static_size; + + unsigned len = get_size (); + unsigned len_before_val = (const char *)p - (const char *)this; + if (flags & ARG_1_AND_2_ARE_WORDS) + { + // no overflow, copy and update value with deltas + hb_memcpy (out, this, len); + + const HBINT16 *px = reinterpret_cast (p); + HBINT16 *o = reinterpret_cast (out + len_before_val); + o[0] = px[0] + roundf (p_delta.x); + o[1] = px[1] + roundf (p_delta.y); + } + else + { + int new_x = p[0] + roundf (p_delta.x); + int new_y = p[1] + roundf (p_delta.y); + if (new_x <= 127 && new_x >= -128 && + new_y <= 127 && new_y >= -128) + { + hb_memcpy (out, this, len); + HBINT8 *o = reinterpret_cast (out + len_before_val); + o[0] = new_x; + o[1] = new_y; + } + else + { + // int8 overflows after deltas applied + hb_memcpy (out, this, len_before_val); + + //update flags + CompositeGlyphRecord *o = reinterpret_cast (out); + o->flags = flags | ARG_1_AND_2_ARE_WORDS; + out += len_before_val; + + HBINT16 new_value; + new_value = new_x; + hb_memcpy (out, &new_value, HBINT16::static_size); + out += HBINT16::static_size; + + new_value = new_y; + hb_memcpy (out, &new_value, HBINT16::static_size); + out += HBINT16::static_size; + + hb_memcpy (out, p+2, len - len_before_val - 2); + len += 2; + } + } + return len; + } + protected: bool scaled_offsets () const { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; } @@ -101,8 +176,14 @@ matrix[0] = matrix[3] = 1.f; matrix[1] = matrix[2] = 0.f; + const auto *p = &StructAfter (flags); +#ifndef HB_NO_BEYOND_64K + if (flags & GID_IS_24BIT) + p += HBGlyphID24::static_size; + else +#endif + p += HBGlyphID16::static_size; int tx, ty; - const HBINT8 *p = &StructAfter (glyphIndex); if (flags & ARG_1_AND_2_ARE_WORDS) { tx = *(const HBINT16 *) p; @@ -145,62 +226,35 @@ } public: - HBUINT16 flags; - HBGlyphID16 glyphIndex; - public: - DEFINE_SIZE_MIN (4); -}; - -struct composite_iter_t : hb_iter_with_fallback_t -{ - typedef const CompositeGlyphRecord *__item_t__; - composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : - glyph (glyph_), current (nullptr), current_size (0) + hb_codepoint_t get_gid () const { - set_current (current_); +#ifndef HB_NO_BEYOND_64K + if (flags & GID_IS_24BIT) + return StructAfter (flags); + else +#endif + return StructAfter (flags); } - - composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {} - - item_t __item__ () const { return *current; } - bool __more__ () const { return current; } - void __next__ () + void set_gid (hb_codepoint_t gid) { - if (!current->has_more ()) { current = nullptr; return; } - - set_current (&StructAtOffset (current, current_size)); - } - composite_iter_t __end__ () const { return composite_iter_t (); } - bool operator != (const composite_iter_t& o) const - { return current != o.current; } - - - void set_current (__item_t__ current_) - { - if (!glyph.check_range (current_, CompositeGlyphRecord::min_size)) - { - current = nullptr; - current_size = 0; - return; - } - unsigned size = current_->get_size (); - if (!glyph.check_range (current_, size)) - { - current = nullptr; - current_size = 0; - return; - } - - current = current_; - current_size = size; +#ifndef HB_NO_BEYOND_64K + if (flags & GID_IS_24BIT) + StructAfter (flags) = gid; + else +#endif + /* TODO assert? */ + StructAfter (flags) = gid; } - private: - hb_bytes_t glyph; - __item_t__ current; - unsigned current_size; + protected: + HBUINT16 flags; + HBUINT24 pad; + public: + DEFINE_SIZE_MIN (4); }; +using composite_iter_t = composite_iter_tmpl; + struct CompositeGlyph { const GlyphHeader &header; @@ -248,6 +302,63 @@ return; glyph_chain.set_overlaps_flag (); } + + bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes, + const contour_point_vector_t &deltas, + hb_bytes_t &dest_bytes /* OUT */) + { + if (source_bytes.length <= GlyphHeader::static_size || + header.numberOfContours != -1) + { + dest_bytes = hb_bytes_t (); + return true; + } + + unsigned source_len = source_bytes.length - GlyphHeader::static_size; + + /* try to allocate more memories than source glyph bytes + * in case that there might be an overflow for int8 value + * and we would need to use int16 instead */ + char *o = (char *) hb_calloc (source_len + source_len/2, sizeof (char)); + if (unlikely (!o)) return false; + + const CompositeGlyphRecord *c = reinterpret_cast (source_bytes.arrayZ + GlyphHeader::static_size); + auto it = composite_iter_t (hb_bytes_t ((const char *)c, source_len), c); + + char *p = o; + unsigned i = 0, source_comp_len = 0; + for (const auto &component : it) + { + /* last 4 points in deltas are phantom points and should not be included */ + if (i >= deltas.length - 4) return false; + + unsigned comp_len = component.get_size (); + if (component.is_anchored ()) + { + hb_memcpy (p, &component, comp_len); + p += comp_len; + } + else + { + unsigned new_len = component.compile_with_deltas (deltas[i], p); + p += new_len; + } + i++; + source_comp_len += comp_len; + } + + //copy instructions if any + if (source_len > source_comp_len) + { + unsigned instr_len = source_len - source_comp_len; + hb_memcpy (p, (const char *)c + source_comp_len, instr_len); + p += instr_len; + } + + unsigned len = p - o; + dest_bytes = hb_bytes_t (o, len); + return true; + } }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/composite-iter.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/composite-iter.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/composite-iter.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/composite-iter.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,68 @@ +#ifndef OT_GLYF_COMPOSITE_ITER_HH +#define OT_GLYF_COMPOSITE_ITER_HH + + +#include "../../hb.hh" + + +namespace OT { +namespace glyf_impl { + + +template +struct composite_iter_tmpl : hb_iter_with_fallback_t, + const CompositeGlyphRecord &> +{ + typedef const CompositeGlyphRecord *__item_t__; + composite_iter_tmpl (hb_bytes_t glyph_, __item_t__ current_) : + glyph (glyph_), current (nullptr), current_size (0) + { + set_current (current_); + } + + composite_iter_tmpl () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {} + + const CompositeGlyphRecord & __item__ () const { return *current; } + bool __more__ () const { return current; } + void __next__ () + { + if (!current->has_more ()) { current = nullptr; return; } + + set_current (&StructAtOffset (current, current_size)); + } + composite_iter_tmpl __end__ () const { return composite_iter_tmpl (); } + bool operator != (const composite_iter_tmpl& o) const + { return current != o.current; } + + + void set_current (__item_t__ current_) + { + if (!glyph.check_range (current_, CompositeGlyphRecord::min_size)) + { + current = nullptr; + current_size = 0; + return; + } + unsigned size = current_->get_size (); + if (!glyph.check_range (current_, size)) + { + current = nullptr; + current_size = 0; + return; + } + + current = current_; + current_size = size; + } + + private: + hb_bytes_t glyph; + __item_t__ current; + unsigned current_size; +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + +#endif /* OT_GLYF_COMPOSITE_ITER_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,34 @@ +#ifndef OT_GLYF_COORD_SETTER_HH +#define OT_GLYF_COORD_SETTER_HH + + +#include "../../hb.hh" + + +namespace OT { +namespace glyf_impl { + + +struct coord_setter_t +{ + coord_setter_t (hb_array_t coords) : + coords (coords) {} + + int& operator [] (unsigned idx) + { + if (coords.length < idx + 1) + coords.resize (idx + 1); + return coords[idx]; + } + + hb_array_t get_coords () + { return coords.as_array (); } + + hb_vector_t coords; +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + +#endif /* OT_GLYF_COORD_SETTER_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh 2023-07-05 07:11:54.000000000 +0000 @@ -16,7 +16,7 @@ hb_requires (hb_is_source_of (IteratorIn, unsigned int)), hb_requires (hb_is_sink_of (IteratorOut, unsigned))> static void -_write_loca (IteratorIn it, bool short_offsets, IteratorOut dest) +_write_loca (IteratorIn&& it, bool short_offsets, IteratorOut&& dest) { unsigned right_shift = short_offsets ? 1 : 0; unsigned int offset = 0; @@ -25,7 +25,7 @@ | hb_map ([=, &offset] (unsigned int padded_size) { offset += padded_size; - DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset); + DEBUG_MSG (SUBSET, nullptr, "loca entry offset %u", offset); return offset >> right_shift; }) | hb_sink (dest) @@ -44,6 +44,20 @@ head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr); head_prime->indexToLocFormat = use_short_loca ? 0 : 1; + if (plan->normalized_coords) + { + head_prime->xMin = plan->head_maxp_info.xMin; + head_prime->xMax = plan->head_maxp_info.xMax; + head_prime->yMin = plan->head_maxp_info.yMin; + head_prime->yMax = plan->head_maxp_info.yMax; + + unsigned orig_flag = head_prime->flags; + if (plan->head_maxp_info.allXMinIsLsb) + orig_flag |= 1 << 1; + else + orig_flag &= ~(1 << 1); + head_prime->flags = orig_flag; + } bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob); hb_blob_destroy (head_prime_blob); @@ -61,7 +75,7 @@ if (unlikely (!loca_prime_data)) return false; - DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d", + DEBUG_MSG (SUBSET, nullptr, "loca entry_size %u num_offsets %u size %u", entry_size, num_offsets, entry_size * num_offsets); if (use_short_loca) diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh 2023-07-05 07:11:54.000000000 +0000 @@ -7,6 +7,7 @@ #include "../../hb-ot-hmtx-table.hh" #include "../../hb-ot-var-gvar-table.hh" #include "../../hb-draw.hh" +#include "../../hb-paint.hh" #include "glyf-helpers.hh" #include "Glyph.hh" @@ -24,7 +25,6 @@ */ #define HB_OT_TAG_glyf HB_TAG('g','l','y','f') - struct glyf { friend struct glyf_accelerator_t; @@ -46,8 +46,11 @@ const hb_subset_plan_t *plan) { TRACE_SERIALIZE (this); + unsigned init_len = c->length (); - for (const auto &_ : it) _.serialize (c, use_short_loca, plan); + for (auto &_ : it) + if (unlikely (!_.serialize (c, use_short_loca, plan))) + return false; /* As a special case when all glyph in the font are empty, add a zero byte * to the table, so that OTS doesn’t reject it, and to make the table work @@ -72,36 +75,67 @@ 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; + } + + hb_vector_t padded_offsets; + unsigned num_glyphs = c->plan->num_output_glyphs (); + if (unlikely (!padded_offsets.resize (num_glyphs))) + return false; + hb_vector_t glyphs; - _populate_subset_glyphs (c->plan, &glyphs); + if (!_populate_subset_glyphs (c->plan, font, glyphs)) + return false; - auto padded_offsets = - + hb_iter (glyphs) - | hb_map (&glyf_impl::SubsetGlyph::padded_size) - ; + if (font) + hb_font_destroy (font); - unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0); - bool use_short_loca = max_offset < 0x1FFFF; + unsigned max_offset = 0; + for (unsigned i = 0; i < num_glyphs; i++) + { + padded_offsets[i] = glyphs[i].padded_size (); + max_offset += padded_offsets[i]; + } + bool use_short_loca = false; + if (likely (!c->plan->force_long_loca)) + use_short_loca = max_offset < 0x1FFFF; - glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan); if (!use_short_loca) { - padded_offsets = - + hb_iter (glyphs) - | hb_map (&glyf_impl::SubsetGlyph::length) - ; + for (unsigned i = 0; i < num_glyphs; i++) + padded_offsets[i] = glyphs[i].length (); } + bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan); + if (c->plan->normalized_coords && !c->plan->pinned_at_default) + _free_compiled_subset_glyphs (glyphs, glyphs.length - 1); + + if (!result) return false; if (unlikely (c->serializer->in_error ())) return_trace (false); + return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan, - padded_offsets, + padded_offsets.iter (), use_short_loca))); } - void + bool _populate_subset_glyphs (const hb_subset_plan_t *plan, - hb_vector_t *glyphs /* OUT */) const; + hb_font_t *font, + 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, unsigned index) const + { + for (unsigned i = 0; i <= index && i < glyphs.length; i++) + glyphs[i].free_compiled_bytes (); + } protected: UnsizedArrayOf @@ -166,7 +200,7 @@ contour_point_vector_t all_points; bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, phantom_only))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only))) return false; if (consumer.is_consuming_contour_points ()) @@ -194,6 +228,7 @@ hb_font_t *font; hb_glyph_extents_t *extents; contour_point_t *phantoms; + bool scaled; struct contour_bounds_t { @@ -209,7 +244,7 @@ bool empty () const { return (min_x >= max_x) || (min_y >= max_y); } - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) + void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scaled) { if (unlikely (empty ())) { @@ -219,26 +254,32 @@ extents->y_bearing = 0; return; } - extents->x_bearing = font->em_scalef_x (min_x); - extents->width = font->em_scalef_x (max_x) - extents->x_bearing; - extents->y_bearing = font->em_scalef_y (max_y); - extents->height = font->em_scalef_y (min_y) - extents->y_bearing; + { + extents->x_bearing = roundf (min_x); + extents->width = roundf (max_x - extents->x_bearing); + extents->y_bearing = roundf (max_y); + extents->height = roundf (min_y - extents->y_bearing); + + if (scaled) + font->scale_glyph_extents (extents); + } } protected: float min_x, min_y, max_x, max_y; } bounds; - points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_) + points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_, bool scaled_) { font = font_; extents = extents_; phantoms = phantoms_; + scaled = scaled_; if (extents) bounds = contour_bounds_t (); } void consume_point (const contour_point_t &point) { bounds.add (point); } - void points_end () { bounds.get_extents (font, extents); } + void points_end () { bounds.get_extents (font, extents, scaled); } bool is_consuming_contour_points () { return extents; } contour_point_t *get_phantoms_sink () { return phantoms; } @@ -246,22 +287,22 @@ public: unsigned - get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const { if (unlikely (gid >= num_glyphs)) return 0; bool success = false; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (likely (font->num_coords == gvar->get_axis_count ())) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); + if (font->num_coords) + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false)); if (unlikely (!success)) return #ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_advance (gid) : + is_vertical ? vmtx->get_advance_without_var_unscaled (gid) : #endif - hmtx->get_advance (gid); + hmtx->get_advance_without_var_unscaled (gid); float result = is_vertical ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y @@ -269,23 +310,20 @@ return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); } - int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const { - if (unlikely (gid >= num_glyphs)) return 0; + if (unlikely (gid >= num_glyphs)) return false; hb_glyph_extents_t extents; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_side_bearing (gid) : -#endif - hmtx->get_side_bearing (gid); + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false)))) + return false; - return is_vertical - ? ceilf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing - : floorf (phantoms[glyf_impl::PHANTOM_LEFT].x); + *lsb = is_vertical + ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing + : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x); + return true; } #endif @@ -296,9 +334,18 @@ #ifndef HB_NO_VAR if (font->num_coords) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr)); + return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true)); #endif - return glyph_for_gid (gid).get_extents (font, *this, extents); + return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); + } + + bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const + { + funcs->push_clip_glyph (data, gid, font); + funcs->color (data, true, foreground); + funcs->pop_clip (data); + + return true; } const glyf_impl::Glyph @@ -349,37 +396,76 @@ }; -inline void +inline bool glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, - hb_vector_t *glyphs /* OUT */) const + hb_font_t *font, + 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; - + hb_range (plan->num_output_glyphs ()) - | hb_map ([&] (hb_codepoint_t new_gid) - { - glyf_impl::SubsetGlyph subset_glyph = {0}; - subset_glyph.new_gid = new_gid; + unsigned idx = 0; + for (auto p : plan->glyph_map->iter ()) + { + unsigned new_gid = p.second; + glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid]; + subset_glyph.old_gid = p.first; + + if (unlikely (new_gid == 0 && + !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) && + !plan->normalized_coords) + subset_glyph.source_glyph = glyf_impl::Glyph (); + else + { + /* If plan has an accelerator, the preprocessing step already trimmed glyphs. + * Don't trim them again! */ + subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, !plan->accelerator); + } + + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + subset_glyph.drop_hints_bytes (); + else + subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); - /* should never fail: all old gids should be mapped */ - if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) - return subset_glyph; - - if (new_gid == 0 && - !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) - subset_glyph.source_glyph = glyf_impl::Glyph (); - else - subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); - if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - subset_glyph.drop_hints_bytes (); - else - subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); - return subset_glyph; - }) - | hb_sink (glyphs) - ; + if (font) + { + if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf))) + { + // when pinned at default, only bounds are updated, thus no need to free + if (!plan->pinned_at_default && idx > 0) + _free_compiled_subset_glyphs (glyphs, idx - 1); + return false; + } + idx++; + } + } + return true; } +inline hb_font_t * +glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const +{ + hb_font_t *font = hb_font_create (plan->source); + if (unlikely (font == hb_font_get_empty ())) return nullptr; + + hb_vector_t vars; + if (unlikely (!vars.alloc (plan->user_axes_location.get_population (), true))) + return nullptr; + + for (auto _ : plan->user_axes_location) + { + hb_variation_t var; + var.tag = _.first; + var.value = _.second; + vars.push (var); + } + +#ifndef HB_NO_VAR + hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ()); +#endif + return font; +} } /* namespace OT */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/GlyphHeader.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/GlyphHeader.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/GlyphHeader.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/GlyphHeader.hh 2023-07-05 07:11:54.000000000 +0000 @@ -14,15 +14,19 @@ bool has_data () const { return numberOfContours; } template - bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, - hb_codepoint_t gid, hb_glyph_extents_t *extents) const + bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator, + hb_codepoint_t gid, hb_glyph_extents_t *extents) const { /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */ /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */ - extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid)); - extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax)); - extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax)); - extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax)); + int lsb = hb_min (xMin, xMax); + (void) glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + extents->x_bearing = lsb; + extents->y_bearing = hb_max (yMin, yMax); + extents->width = hb_max (xMin, xMax) - hb_min (xMin, xMax); + extents->height = hb_min (yMin, yMax) - hb_max (yMin, yMax); + + font->scale_glyph_extents (extents); return true; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -7,6 +7,8 @@ #include "GlyphHeader.hh" #include "SimpleGlyph.hh" #include "CompositeGlyph.hh" +#include "VarCompositeGlyph.hh" +#include "coord-setter.hh" namespace OT { @@ -27,7 +29,7 @@ struct Glyph { - enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE }; + enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE }; public: composite_iter_t get_composite_iterator () const @@ -35,6 +37,11 @@ if (type != COMPOSITE) return composite_iter_t (); return CompositeGlyph (*header, bytes).iter (); } + var_composite_iter_t get_var_composite_iterator () const + { + if (type != VAR_COMPOSITE) return var_composite_iter_t (); + return VarCompositeGlyph (*header, bytes).iter (); + } const hb_bytes_t trim_padding () const { @@ -72,22 +79,212 @@ } } + void update_mtx (const hb_subset_plan_t *plan, + int xMin, int xMax, + int yMin, int yMax, + const contour_point_vector_t &all_points) const + { + hb_codepoint_t new_gid = 0; + if (!plan->new_gid_for_old_gid (gid, &new_gid)) + return; + + if (type != EMPTY) + { + plan->bounds_width_map.set (new_gid, xMax - xMin); + plan->bounds_height_map.set (new_gid, yMax - yMin); + } + + unsigned len = all_points.length; + float leftSideX = all_points[len - 4].x; + float rightSideX = all_points[len - 3].x; + float topSideY = all_points[len - 2].y; + float bottomSideY = all_points[len - 1].y; + + 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)); + //flag value should be computed using non-empty glyphs + if (type != EMPTY && lsb != xMin) + plan->head_maxp_info.allXMinIsLsb = false; + + 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)); + } + + bool compile_header_bytes (const hb_subset_plan_t *plan, + const contour_point_vector_t &all_points, + hb_bytes_t &dest_bytes /* OUT */) const + { + GlyphHeader *glyph_header = nullptr; + if (!plan->pinned_at_default && type != EMPTY && all_points.length >= 4) + { + glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size); + if (unlikely (!glyph_header)) return false; + } + + float xMin = 0, xMax = 0; + float yMin = 0, yMax = 0; + if (all_points.length > 4) + { + xMin = xMax = all_points[0].x; + yMin = yMax = all_points[0].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); + + if (type != EMPTY) + { + plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, rounded_xMin); + plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, rounded_yMin); + plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, rounded_xMax); + plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, rounded_yMax); + } + + /* when pinned at default, no need to compile glyph header + * and for empty glyphs: all_points only include phantom points. + * just update metrics and then return */ + if (!glyph_header) + return true; + + glyph_header->numberOfContours = header->numberOfContours; + + glyph_header->xMin = rounded_xMin; + glyph_header->yMin = rounded_yMin; + glyph_header->xMax = rounded_xMax; + glyph_header->yMax = rounded_yMax; + + dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size); + return true; + } + + bool compile_bytes_with_deltas (const hb_subset_plan_t *plan, + hb_font_t *font, + const glyf_accelerator_t &glyf, + hb_bytes_t &dest_start, /* IN/OUT */ + hb_bytes_t &dest_end /* OUT */) + { + contour_point_vector_t all_points, deltas; + unsigned composite_contours = 0; + head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info; + unsigned *composite_contours_p = &composite_contours; + + // don't compute head/maxp values when glyph has no contours(type is EMPTY) + // also ignore .notdef glyph when --notdef-outline is not enabled + if (type == EMPTY || + (gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))) + { + head_maxp_info_p = nullptr; + composite_contours_p = nullptr; + } + + if (!get_points (font, glyf, all_points, &deltas, head_maxp_info_p, composite_contours_p, false, false)) + return false; + + // .notdef, set type to empty so we only update metrics and don't compile bytes for + // it + if (gid == 0 && + !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + { + type = EMPTY; + dest_start = hb_bytes_t (); + dest_end = hb_bytes_t (); + } + + //dont compile bytes when pinned at default, just recalculate bounds + if (!plan->pinned_at_default) { + switch (type) { + case COMPOSITE: + if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start, + deltas, + dest_end)) + return false; + break; + case SIMPLE: + if (!SimpleGlyph (*header, bytes).compile_bytes_with_deltas (all_points, + plan->flags & HB_SUBSET_FLAGS_NO_HINTING, + dest_end)) + return false; + break; + default: + /* set empty bytes for empty glyph + * do not use source glyph's pointers */ + dest_start = hb_bytes_t (); + dest_end = hb_bytes_t (); + break; + } + } + + if (!compile_header_bytes (plan, all_points, dest_start)) + { + dest_end.fini (); + return false; + } + return true; + } + + /* Note: Recursively calls itself. * all_points includes phantom points */ template bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points /* OUT */, + contour_point_vector_t *deltas = nullptr, /* OUT */ + head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ + unsigned *composite_contours = nullptr, /* OUT */ + bool shift_points_hori = true, + bool use_my_metrics = true, bool phantom_only = false, - unsigned int depth = 0) const + hb_array_t coords = hb_array_t (), + unsigned int depth = 0, + unsigned *edge_count = nullptr) const { if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false; + unsigned stack_edge_count = 0; + if (!edge_count) edge_count = &stack_edge_count; + if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false; + (*edge_count)++; + + if (head_maxp_info) + { + head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); + } + + if (!coords) + 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; switch (type) { + case SIMPLE: + if (depth == 0 && head_maxp_info) + 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))) + return false; + break; case COMPOSITE: { /* pseudo component points for each component in composite glyph */ @@ -95,29 +292,36 @@ if (unlikely (!points.resize (num_points))) return false; break; } - case SIMPLE: - if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only))) - return false; +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: + { + for (auto &item : get_var_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; + } +#endif + default: break; } /* Init phantom points */ if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; - hb_array_t phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { - int h_delta = (int) header->xMin - - glyf_accelerator.hmtx->get_side_bearing (gid); + int lsb = 0; + int h_delta = glyf_accelerator.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 - glyf_accelerator.vmtx->get_side_bearing (gid) + ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) #else 0 #endif ; - unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); + unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_advance (gid) + glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid) #else - font->face->get_upem () #endif @@ -128,12 +332,33 @@ phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; } + if (deltas != nullptr && depth == 0 && type == COMPOSITE) + { + if (unlikely (!deltas->resize (points.length))) return false; + deltas->copy_vector (points); + } + #ifndef HB_NO_VAR - glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ()); + glyf_accelerator.gvar->apply_deltas_to_points (gid, + coords, + points.as_array ()); #endif + // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it + // with child glyphs' points + if (deltas != nullptr && depth == 0 && type == COMPOSITE) + { + for (unsigned i = 0 ; i < points.length; i++) + { + deltas->arrayZ[i].x = points.arrayZ[i].x - deltas->arrayZ[i].x; + deltas->arrayZ[i].y = points.arrayZ[i].y - deltas->arrayZ[i].y; + } + } + 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 ()); break; @@ -144,13 +369,23 @@ for (auto &item : get_composite_iterator ()) { comp_points.reset (); - if (unlikely (!glyf_accelerator.glyph_for_gid (item.glyphIndex) - .get_points (font, glyf_accelerator, comp_points, - phantom_only, depth + 1))) + if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) + .get_points (font, + glyf_accelerator, + comp_points, + deltas, + head_maxp_info, + composite_contours, + shift_points_hori, + use_my_metrics, + phantom_only, + coords, + depth + 1, + edge_count))) return false; /* Copy phantom points from component if USE_MY_METRICS flag set */ - if (item.is_use_my_metrics ()) + 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]; @@ -174,18 +409,80 @@ } } - all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); + all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT)); + + if (all_points.length > HB_GLYF_MAX_POINTS) + return false; comp_index++; } + if (head_maxp_info && depth == 0) + { + if (composite_contours) + head_maxp_info->maxCompositeContours = hb_max (head_maxp_info->maxCompositeContours, *composite_contours); + head_maxp_info->maxCompositePoints = hb_max (head_maxp_info->maxCompositePoints, all_points.length); + head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index); + } all_points.extend (phantoms); } break; +#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_array_t record_points = points_left.sub_array (0, item.get_num_points ()); + + comp_points.reset (); + + auto component_coords = coords; + if (item.is_reset_unspecified_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 ()) + .get_points (font, + glyf_accelerator, + comp_points, + deltas, + head_maxp_info, + nullptr, + shift_points_hori, + use_my_metrics, + phantom_only, + coord_setter.get_coords (), + depth + 1, + edge_count))) + return false; + + /* Apply component transformation */ + 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)); + + if (all_points.length > HB_GLYF_MAX_POINTS) + return false; + + points_left += item.get_num_points (); + } + all_points.extend (phantoms); + } break; +#endif default: all_points.extend (phantoms); + break; } - if (depth == 0) /* Apply at top level */ + if (depth == 0 && shift_points_hori) /* Apply at top level */ { /* Undocumented rasterizer behavior: * Shift points horizontally by the updated left side bearing @@ -198,23 +495,30 @@ return !all_points.in_error (); } - bool get_extents (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, - hb_glyph_extents_t *extents) const + bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, + hb_glyph_extents_t *extents) const { if (type == EMPTY) return true; /* Empty glyph; zero extents. */ - return header->get_extents (font, glyf_accelerator, gid, extents); + return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents); } hb_bytes_t get_bytes () const { return bytes; } - Glyph (hb_bytes_t bytes_ = hb_bytes_t (), - hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), - header (bytes.as ()), - gid (gid_) + Glyph () : bytes (), + header (bytes.as ()), + gid (-1), + type(EMPTY) + {} + + Glyph (hb_bytes_t bytes_, + hb_codepoint_t gid_ = (unsigned) -1) : bytes (bytes_), + header (bytes.as ()), + gid (gid_) { int num_contours = header->numberOfContours; if (unlikely (num_contours == 0)) type = EMPTY; else if (num_contours > 0) type = SIMPLE; + else if (num_contours == -2) type = VAR_COMPOSITE; else type = COMPOSITE; /* negative numbers */ } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh 2023-07-05 07:11:54.000000000 +0000 @@ -26,22 +26,29 @@ optional_point_t lerp (optional_point_t p, float t) { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); } - } first_oncurve, first_offcurve, last_offcurve; + } first_oncurve, first_offcurve, 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 = last_offcurve = optional_point_t (); + first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); } /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287 See also: * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html - * https://stackoverflow.com/a/20772557 */ + * https://stackoverflow.com/a/20772557 + * + * Cubic support added (incomplete). */ void consume_point (const contour_point_t &point) { bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE; +#ifdef HB_NO_CUBIC_GLYF + bool is_cubic = false; +#else + 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) { @@ -69,16 +76,41 @@ { if (is_on_curve) { - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - p.x, p.y); + if (last_offcurve2) + { + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + p.x, p.y); + last_offcurve2 = optional_point_t (); + } + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + p.x, p.y); last_offcurve = optional_point_t (); } else { - optional_point_t mid = last_offcurve.lerp (p, .5f); - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - last_offcurve = p; + if (is_cubic && !last_offcurve2) + { + last_offcurve2 = last_offcurve; + last_offcurve = p; + } + else + { + optional_point_t mid = last_offcurve.lerp (p, .5f); + + if (is_cubic) + { + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + last_offcurve2 = optional_point_t (); + } + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + last_offcurve = p; + } } } else @@ -105,8 +137,15 @@ draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, first_oncurve.x, first_oncurve.y); else if (last_offcurve && first_oncurve) - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); + { + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + } else if (first_oncurve) draw_session->line_to (first_oncurve.x, first_oncurve.y); else if (first_offcurve) @@ -117,7 +156,7 @@ } /* Getting ready for the next contour */ - first_oncurve = first_offcurve = last_offcurve = optional_point_t (); + first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); draw_session->close_path (); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -20,7 +20,7 @@ FLAG_X_SAME = 0x10, FLAG_Y_SAME = 0x20, FLAG_OVERLAP_SIMPLE = 0x40, - FLAG_RESERVED2 = 0x80 + FLAG_CUBIC = 0x80 }; const GlyphHeader &header; @@ -132,8 +132,8 @@ if (unlikely (p + 1 > end)) return false; unsigned int repeat_count = *p++; unsigned stop = hb_min (i + repeat_count, count); - for (; i < stop;) - points_.arrayZ[i++].flag = flag; + for (; i < stop; i++) + points_.arrayZ[i].flag = flag; } } return true; @@ -184,7 +184,7 @@ if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours]))) return false; unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; - points_.alloc (num_points + 4); // Allocate for phantom points, to avoid a possible copy + points_.alloc (num_points + 4, true); // Allocate for phantom points, to avoid a possible copy if (!points_.resize (num_points)) return false; if (phantom_only) return true; @@ -206,6 +206,129 @@ && read_points (p, points_, end, &contour_point_t::y, FLAG_Y_SHORT, FLAG_Y_SAME); } + + static void encode_coord (int value, + uint8_t &flag, + const simple_glyph_flag_t short_flag, + const simple_glyph_flag_t same_flag, + hb_vector_t &coords /* OUT */) + { + if (value == 0) + { + flag |= same_flag; + } + else if (value >= -255 && value <= 255) + { + flag |= short_flag; + if (value > 0) flag |= same_flag; + else value = -value; + + coords.arrayZ[coords.length++] = (uint8_t) value; + } + else + { + int16_t val = value; + coords.arrayZ[coords.length++] = val >> 8; + coords.arrayZ[coords.length++] = val & 0xff; + } + } + + static void encode_flag (uint8_t &flag, + uint8_t &repeat, + uint8_t lastflag, + hb_vector_t &flags /* OUT */) + { + if (flag == lastflag && repeat != 255) + { + repeat++; + if (repeat == 1) + { + /* We know there's room. */ + flags.arrayZ[flags.length++] = flag; + } + else + { + unsigned len = flags.length; + flags.arrayZ[len-2] = flag | FLAG_REPEAT; + flags.arrayZ[len-1] = repeat; + } + } + else + { + repeat = 0; + flags.push (flag); + } + } + + bool compile_bytes_with_deltas (const contour_point_vector_t &all_points, + bool no_hinting, + hb_bytes_t &dest_bytes /* OUT */) + { + if (header.numberOfContours == 0 || all_points.length <= 4) + { + dest_bytes = hb_bytes_t (); + return true; + } + unsigned num_points = all_points.length - 4; + + hb_vector_t flags, x_coords, y_coords; + if (unlikely (!flags.alloc (num_points, true))) return false; + 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; + 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; + + int cur_x = roundf (all_points.arrayZ[i].x); + int cur_y = roundf (all_points.arrayZ[i].y); + encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords); + encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords); + encode_flag (flag, repeat, lastflag, flags); + + prev_x = cur_x; + prev_y = cur_y; + lastflag = flag; + } + + unsigned len_before_instrs = 2 * header.numberOfContours + 2; + unsigned len_instrs = instructions_length (); + unsigned total_len = len_before_instrs + flags.length + x_coords.length + y_coords.length; + + if (!no_hinting) + total_len += len_instrs; + + char *p = (char *) hb_malloc (total_len); + if (unlikely (!p)) return false; + + const char *src = bytes.arrayZ + GlyphHeader::static_size; + char *cur = p; + hb_memcpy (p, src, len_before_instrs); + + cur += len_before_instrs; + src += len_before_instrs; + + if (!no_hinting) + { + hb_memcpy (cur, src, len_instrs); + cur += len_instrs; + } + + hb_memcpy (cur, flags.arrayZ, flags.length); + cur += flags.length; + + hb_memcpy (cur, x_coords.arrayZ, x_coords.length); + cur += x_coords.length; + + hb_memcpy (cur, y_coords.arrayZ, y_coords.length); + + dest_bytes = hb_bytes_t (p, total_len); + return true; + } }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,12 +6,14 @@ namespace OT { + +struct glyf_accelerator_t; + namespace glyf_impl { struct SubsetGlyph { - hb_codepoint_t new_gid; hb_codepoint_t old_gid; Glyph source_glyph; hb_bytes_t dest_start; /* region of source_glyph to copy first */ @@ -19,14 +21,14 @@ bool serialize (hb_serialize_context_t *c, bool use_short_loca, - const hb_subset_plan_t *plan) const + const hb_subset_plan_t *plan) { TRACE_SERIALIZE (this); hb_bytes_t dest_glyph = dest_start.copy (c); dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); unsigned int pad_length = use_short_loca ? padding () : 0; - DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); + DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length); HBUINT8 pad; pad = 0; @@ -42,8 +44,8 @@ for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) { hb_codepoint_t new_gid; - if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid)) - const_cast (_).glyphIndex = new_gid; + if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) + const_cast (_).set_gid (new_gid); } if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) @@ -55,6 +57,17 @@ return_trace (true); } + bool compile_bytes_with_deltas (const hb_subset_plan_t *plan, + hb_font_t *font, + const glyf_accelerator_t &glyf) + { return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); } + + void free_compiled_bytes () + { + dest_start.fini (); + dest_end.fini (); + } + void drop_hints_bytes () { source_glyph.drop_hints_bytes (dest_start, dest_end); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,354 @@ +#ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH +#define OT_GLYF_VARCOMPOSITEGLYPH_HH + + +#include "../../hb-open-type.hh" +#include "coord-setter.hh" + + +namespace OT { +namespace glyf_impl { + + +struct VarCompositeGlyphRecord +{ + protected: + enum var_composite_glyph_flag_t + { + USE_MY_METRICS = 0x0001, + AXIS_INDICES_ARE_SHORT = 0x0002, + UNIFORM_SCALE = 0x0004, + HAVE_TRANSLATE_X = 0x0008, + HAVE_TRANSLATE_Y = 0x0010, + HAVE_ROTATION = 0x0020, + HAVE_SCALE_X = 0x0040, + HAVE_SCALE_Y = 0x0080, + HAVE_SKEW_X = 0x0100, + HAVE_SKEW_Y = 0x0200, + HAVE_TCENTER_X = 0x0400, + HAVE_TCENTER_Y = 0x0800, + GID_IS_24 = 0x1000, + AXES_HAVE_VARIATION = 0x2000, + RESET_UNSPECIFIED_AXES = 0x4000, + }; + + public: + + unsigned int get_size () const + { + unsigned int size = min_size; + + unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3; + size += numAxes * axis_width; + + // gid + size += 2; + if (flags & GID_IS_24) 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; + + return size; + } + + bool has_more () const { return true; } + + bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } + bool is_reset_unspecified_axes () const { return flags & RESET_UNSPECIFIED_AXES; } + + hb_codepoint_t get_gid () const + { + if (flags & GID_IS_24) + return StructAfter (numAxes); + else + return StructAfter (numAxes); + } + + unsigned get_numAxes () const + { + return numAxes; + } + + unsigned get_num_points () const + { + 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++; + return num; + } + + void transform_points (hb_array_t record_points, + contour_point_vector_t &points) const + { + float matrix[4]; + contour_point_t trans; + + get_transformation_from_points (record_points, matrix, trans); + + points.transform (matrix); + points.translate (trans); + } + + static inline void transform (float (&matrix)[4], contour_point_t &trans, + float (other)[6]) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268 + float xx1 = other[0]; + float xy1 = other[1]; + float yx1 = other[2]; + float yy1 = other[3]; + float dx1 = other[4]; + float dy1 = other[5]; + float xx2 = matrix[0]; + float xy2 = matrix[1]; + float yx2 = matrix[2]; + float yy2 = matrix[3]; + float dx2 = trans.x; + float dy2 = trans.y; + + matrix[0] = xx1*xx2 + xy1*yx2; + matrix[1] = xx1*xy2 + xy1*yy2; + matrix[2] = yx1*xx2 + yy1*yx2; + matrix[3] = yx1*xy2 + yy1*yy2; + trans.x = xx2*dx1 + yx2*dy1 + dx2; + trans.y = xy2*dx1 + yy2*dy1 + dy2; + } + + 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); + } + + 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); + } + + static void rotate (float (&matrix)[4], contour_point_t &trans, + float rotation) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 + rotation = rotation * float (M_PI); + float c = cosf (rotation); + float s = sinf (rotation); + float other[6] = {c, s, -s, c, 0.f, 0.f}; + transform (matrix, trans, other); + } + + static void skew (float (&matrix)[4], contour_point_t &trans, + float skewX, float skewY) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 + skewX = skewX * float (M_PI); + skewY = skewY * float (M_PI); + float other[6] = {1.f, tanf (skewY), tanf (skewX), 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; + + if (unlikely (!points.resize (points.length + get_num_points ()))) return false; + + unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; + unsigned axes_size = numAxes * axis_width; + + const F2DOT14 *q = (const F2DOT14 *) (axes_size + + (flags & GID_IS_24 ? 3 : 2) + + &StructAfter (numAxes)); + + hb_array_t rec_points = points.as_array ().sub_array (points.length - get_num_points ()); + + unsigned count = numAxes; + if (flags & AXES_HAVE_VARIATION) + { + for (unsigned i = 0; i < count; i++) + rec_points[i].x = q++->to_int (); + rec_points += count; + } + 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)) + { + rec_points[0].x = translateX; + rec_points[0].y = translateY; + rec_points++; + } + if (flags & HAVE_ROTATION) + { + rec_points[0].x = rotation; + rec_points++; + } + if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) + { + rec_points[0].x = scaleX; + rec_points[0].y = scaleY; + rec_points++; + } + if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) + { + rec_points[0].x = skewX; + rec_points[0].y = skewY; + rec_points++; + } + if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) + { + rec_points[0].x = tCenterX; + rec_points[0].y = tCenterY; + rec_points++; + } + assert (!rec_points); + + return true; + } + + void get_transformation_from_points (hb_array_t rec_points, + float (&matrix)[4], contour_point_t &trans) const + { + if (flags & AXES_HAVE_VARIATION) + rec_points += numAxes; + + matrix[0] = matrix[3] = 1.f; + matrix[1] = matrix[2] = 0.f; + trans.init (0.f, 0.f); + + float translateX = 0.f; + float translateY = 0.f; + float rotation = 0.f; + float scaleX = 1.f; + float scaleY = 1.f; + float skewX = 0.f; + float skewY = 0.f; + float tCenterX = 0.f; + float tCenterY = 0.f; + + if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) + { + translateX = rec_points[0].x; + translateY = rec_points[0].y; + rec_points++; + } + if (flags & HAVE_ROTATION) + { + rotation = rec_points[0].x / (1 << 12); + rec_points++; + } + if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) + { + scaleX = rec_points[0].x / (1 << 10); + scaleY = rec_points[0].y / (1 << 10); + rec_points++; + } + if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) + { + skewX = rec_points[0].x / (1 << 12); + skewY = rec_points[0].y / (1 << 12); + rec_points++; + } + if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) + { + tCenterX = rec_points[0].x; + tCenterY = rec_points[0].y; + rec_points++; + } + assert (!rec_points); + + translate (matrix, trans, translateX + tCenterX, translateY + tCenterY); + rotate (matrix, trans, rotation); + scale (matrix, trans, scaleX, scaleY); + skew (matrix, trans, -skewX, skewY); + translate (matrix, trans, -tCenterX, -tCenterY); + } + + void set_variations (coord_setter_t &setter, + hb_array_t rec_points) const + { + bool have_variations = flags & AXES_HAVE_VARIATION; + unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; + + const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); + const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); + + const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes))); + + unsigned count = numAxes; + 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 (); + + v = hb_clamp (v, -(1<<14), (1<<14)); + setter[axis_index] = v; + } + } + + protected: + HBUINT16 flags; + HBUINT8 numAxes; + public: + DEFINE_SIZE_MIN (3); +}; + +using var_composite_iter_t = composite_iter_tmpl; + +struct VarCompositeGlyph +{ + const GlyphHeader &header; + hb_bytes_t bytes; + VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : + header (header_), bytes (bytes_) {} + + var_composite_iter_t iter () const + { return var_composite_iter_t (bytes, &StructAfter (header)); } + +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + + +#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH +#define OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH + +namespace OT { +namespace Layout { +namespace Common { + +#define NOT_COVERED ((unsigned int) -1) + +template +struct CoverageFormat1_3 +{ + friend struct Coverage; + + protected: + HBUINT16 coverageFormat; /* Format identifier--format = 1 */ + SortedArray16Of + glyphArray; /* Array of GlyphIDs--in numerical order */ + public: + DEFINE_SIZE_ARRAY (4, glyphArray); + + private: + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (glyphArray.sanitize (c)); + } + + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + unsigned int i; + glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED); + return i; + } + + unsigned get_population () const + { + return glyphArray.len; + } + + template + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + return_trace (glyphArray.serialize (c, glyphs)); + } + + bool intersects (const hb_set_t *glyphs) const + { + 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);) + if (get_coverage (g) != NOT_COVERED) + return true; + return false; + } + + for (const auto& g : glyphArray.as_array ()) + if (glyphs->has (g)) + return true; + return false; + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { return glyphs->has (glyphArray[index]); } + + template + void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const + { + unsigned count = glyphArray.len; + for (unsigned i = 0; i < count; i++) + if (glyphs.has (glyphArray[i])) + intersect_glyphs << glyphArray[i]; + } + + template + bool collect_coverage (set_t *glyphs) const + { return glyphs->add_sorted_array (glyphArray.as_array ()); } + + public: + /* Older compilers need this to be public. */ + struct iter_t + { + void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; } + bool __more__ () const { return i < c->glyphArray.len; } + void __next__ () { i++; } + hb_codepoint_t get_glyph () const { return c->glyphArray[i]; } + bool operator != (const iter_t& o) const + { return i != o.i; } + iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; } + + private: + const struct CoverageFormat1_3 *c; + unsigned int i; + }; + private: +}; + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,232 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH +#define OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH + +#include "RangeRecord.hh" + +namespace OT { +namespace Layout { +namespace Common { + +template +struct CoverageFormat2_4 +{ + friend struct Coverage; + + protected: + HBUINT16 coverageFormat; /* Format identifier--format = 2 */ + SortedArray16Of> + rangeRecord; /* Array of glyph ranges--ordered by + * Start GlyphID. rangeCount entries + * long */ + public: + DEFINE_SIZE_ARRAY (4, rangeRecord); + + private: + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (rangeRecord.sanitize (c)); + } + + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + const RangeRecord &range = rangeRecord.bsearch (glyph_id); + return likely (range.first <= range.last) + ? (unsigned int) range.value + (glyph_id - range.first) + : NOT_COVERED; + } + + unsigned get_population () const + { + typename Types::large_int ret = 0; + for (const auto &r : rangeRecord) + ret += r.get_population (); + return ret > UINT_MAX ? UINT_MAX : (unsigned) ret; + } + + template + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + num_ranges++; + last = g; + } + + if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false); + if (!num_ranges) return_trace (true); + + unsigned count = 0; + unsigned range = (unsigned) -1; + last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + { + range++; + rangeRecord[range].first = g; + rangeRecord[range].value = count; + } + rangeRecord[range].last = g; + last = g; + count++; + } + + return_trace (true); + } + + bool intersects (const hb_set_t *glyphs) const + { + 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);) + if (get_coverage (g) != NOT_COVERED) + return true; + return false; + } + + return hb_any (+ hb_iter (rangeRecord) + | hb_map ([glyphs] (const RangeRecord &range) { return range.intersects (*glyphs); })); + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { + auto *range = rangeRecord.as_array ().bsearch (index); + if (range) + return range->intersects (*glyphs); + return false; + } + + template + void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const + { + /* Break out of loop for overlapping, broken, tables, + * to avoid fuzzer timouts. */ + hb_codepoint_t last = 0; + for (const auto& range : rangeRecord) + { + if (unlikely (range.first < last)) + break; + last = range.last; + for (hb_codepoint_t g = range.first - 1; + glyphs.next (&g) && g <= last;) + intersect_glyphs << g; + } + } + + template + bool collect_coverage (set_t *glyphs) const + { + for (const auto& range: rangeRecord) + if (unlikely (!range.collect_coverage (glyphs))) + return false; + return true; + } + + public: + /* Older compilers need this to be public. */ + struct iter_t + { + void init (const CoverageFormat2_4 &c_) + { + c = &c_; + coverage = 0; + i = 0; + j = c->rangeRecord.len ? c->rangeRecord[0].first : 0; + if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last)) + { + /* Broken table. Skip. */ + i = c->rangeRecord.len; + j = 0; + } + } + bool __more__ () const { return i < c->rangeRecord.len; } + void __next__ () + { + if (j >= c->rangeRecord[i].last) + { + i++; + if (__more__ ()) + { + unsigned int old = coverage; + j = c->rangeRecord[i].first; + coverage = c->rangeRecord[i].value; + if (unlikely (coverage != old + 1)) + { + /* Broken table. Skip. Important to avoid DoS. + * Also, our callers depend on coverage being + * consecutive and monotonically increasing, + * ie. iota(). */ + i = c->rangeRecord.len; + j = 0; + return; + } + } + else + j = 0; + return; + } + coverage++; + j++; + } + hb_codepoint_t get_glyph () const { return j; } + bool operator != (const iter_t& o) const + { return i != o.i || j != o.j; } + iter_t __end__ () const + { + iter_t it; + it.init (*c); + it.i = c->rangeRecord.len; + it.j = 0; + return it; + } + + private: + const struct CoverageFormat2_4 *c; + unsigned int i, coverage; + hb_codepoint_t j; + }; + private: +}; + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,337 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_COVERAGE_HH +#define OT_LAYOUT_COMMON_COVERAGE_HH + +#include "../types.hh" +#include "CoverageFormat1.hh" +#include "CoverageFormat2.hh" + +namespace OT { +namespace Layout { +namespace Common { + +template +static inline void Coverage_serialize (hb_serialize_context_t *c, + Iterator it); + +struct Coverage +{ + + protected: + union { + HBUINT16 format; /* Format identifier */ + CoverageFormat1_3 format1; + CoverageFormat2_4 format2; +#ifndef HB_NO_BEYOND_64K + CoverageFormat1_3format3; + CoverageFormat2_4format4; +#endif + } u; + public: + DEFINE_SIZE_UNION (2, format); + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) + { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); +#endif + default:return_trace (true); + } + } + + /* Has interface. */ + unsigned operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k] != NOT_COVERED; } + /* Predicate. */ + bool operator () (hb_codepoint_t k) const { return has (k); } + + unsigned int get (hb_codepoint_t k) const { return get_coverage (k); } + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + switch (u.format) { + case 1: return u.format1.get_coverage (glyph_id); + case 2: return u.format2.get_coverage (glyph_id); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.get_coverage (glyph_id); + case 4: return u.format4.get_coverage (glyph_id); +#endif + default:return NOT_COVERED; + } + } + + unsigned get_population () const + { + switch (u.format) { + case 1: return u.format1.get_population (); + case 2: return u.format2.get_population (); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.get_population (); + case 4: return u.format4.get_population (); +#endif + default:return NOT_COVERED; + } + } + + template + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + + unsigned count = 0; + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + num_ranges++; + last = g; + count++; + } + u.format = count <= num_ranges * 3 ? 1 : 2; + +#ifndef HB_NO_BEYOND_64K + if (count && last > 0xFFFFu) + u.format += 2; +#endif + + switch (u.format) + { + case 1: return_trace (u.format1.serialize (c, glyphs)); + case 2: return_trace (u.format2.serialize (c, glyphs)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.serialize (c, glyphs)); + case 4: return_trace (u.format4.serialize (c, glyphs)); +#endif + default:return_trace (false); + } + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + 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) + ; + + // Cache the iterator result as it will be iterated multiple times + // by the serialize code below. + hb_sorted_vector_t glyphs (it); + Coverage_serialize (c->serializer, glyphs.iter ()); + return_trace (bool (glyphs)); + } + + bool intersects (const hb_set_t *glyphs) const + { + switch (u.format) + { + case 1: return u.format1.intersects (glyphs); + case 2: return u.format2.intersects (glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersects (glyphs); + case 4: return u.format4.intersects (glyphs); +#endif + default:return false; + } + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { + switch (u.format) + { + case 1: return u.format1.intersects_coverage (glyphs, index); + case 2: return u.format2.intersects_coverage (glyphs, index); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersects_coverage (glyphs, index); + case 4: return u.format4.intersects_coverage (glyphs, index); +#endif + default:return false; + } + } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template + bool collect_coverage (set_t *glyphs) const + { + switch (u.format) + { + case 1: return u.format1.collect_coverage (glyphs); + case 2: return u.format2.collect_coverage (glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.collect_coverage (glyphs); + case 4: return u.format4.collect_coverage (glyphs); +#endif + default:return false; + } + } + + template + void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const + { + switch (u.format) + { + case 1: return u.format1.intersect_set (glyphs, intersect_glyphs); + case 2: return u.format2.intersect_set (glyphs, intersect_glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersect_set (glyphs, intersect_glyphs); + case 4: return u.format4.intersect_set (glyphs, intersect_glyphs); +#endif + default:return ; + } + } + + struct iter_t : hb_iter_with_fallback_t + { + static constexpr bool is_sorted_iterator = true; + iter_t (const Coverage &c_ = Null (Coverage)) + { + hb_memset (this, 0, sizeof (*this)); + format = c_.u.format; + switch (format) + { + case 1: u.format1.init (c_.u.format1); return; + case 2: u.format2.init (c_.u.format2); return; +#ifndef HB_NO_BEYOND_64K + case 3: u.format3.init (c_.u.format3); return; + case 4: u.format4.init (c_.u.format4); return; +#endif + default: return; + } + } + bool __more__ () const + { + switch (format) + { + case 1: return u.format1.__more__ (); + case 2: return u.format2.__more__ (); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.__more__ (); + case 4: return u.format4.__more__ (); +#endif + default:return false; + } + } + void __next__ () + { + switch (format) + { + case 1: u.format1.__next__ (); break; + case 2: u.format2.__next__ (); break; +#ifndef HB_NO_BEYOND_64K + case 3: u.format3.__next__ (); break; + case 4: u.format4.__next__ (); break; +#endif + default: break; + } + } + typedef hb_codepoint_t __item_t__; + __item_t__ __item__ () const { return get_glyph (); } + + hb_codepoint_t get_glyph () const + { + switch (format) + { + case 1: return u.format1.get_glyph (); + case 2: return u.format2.get_glyph (); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.get_glyph (); + case 4: return u.format4.get_glyph (); +#endif + default:return 0; + } + } + bool operator != (const iter_t& o) const + { + if (unlikely (format != o.format)) return true; + switch (format) + { + case 1: return u.format1 != o.u.format1; + case 2: return u.format2 != o.u.format2; +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3 != o.u.format3; + case 4: return u.format4 != o.u.format4; +#endif + default:return false; + } + } + iter_t __end__ () const + { + iter_t it = {}; + it.format = format; + switch (format) + { + case 1: it.u.format1 = u.format1.__end__ (); break; + case 2: it.u.format2 = u.format2.__end__ (); break; +#ifndef HB_NO_BEYOND_64K + case 3: it.u.format3 = u.format3.__end__ (); break; + case 4: it.u.format4 = u.format4.__end__ (); break; +#endif + default: break; + } + return it; + } + + private: + unsigned int format; + union { +#ifndef HB_NO_BEYOND_64K + CoverageFormat2_4::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */ + CoverageFormat1_3::iter_t format3; +#endif + CoverageFormat2_4::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */ + CoverageFormat1_3::iter_t format1; + } u; + }; + iter_t iter () const { return iter_t (*this); } +}; + +template +static inline void +Coverage_serialize (hb_serialize_context_t *c, + Iterator it) +{ c->start_embed ()->serialize (c, it); } + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGE_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_RANGERECORD_HH +#define OT_LAYOUT_COMMON_RANGERECORD_HH + +namespace OT { +namespace Layout { +namespace Common { + +template +struct RangeRecord +{ + typename Types::HBGlyphID first; /* First GlyphID in the range */ + typename Types::HBGlyphID last; /* Last GlyphID in the range */ + HBUINT16 value; /* Value */ + + DEFINE_SIZE_STATIC (2 + 2 * Types::size); + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + int cmp (hb_codepoint_t g) const + { return g < first ? -1 : g <= last ? 0 : +1; } + + unsigned get_population () const + { + if (unlikely (last < first)) return 0; + return (last - first + 1); + } + + bool intersects (const hb_set_t &glyphs) const + { return glyphs.intersects (first, last); } + + template + bool collect_coverage (set_t *glyphs) const + { return glyphs->add_range (first, last); } +}; + +} +} +} + +// TODO(garretrieger): This was previously implemented using +// DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9); +// but that only works when there is only a single namespace level. +// The macro should probably be fixed so it can work in this situation. +extern HB_INTERNAL const unsigned char _hb_Null_OT_RangeRecord[9]; +template +struct Null> { + static OT::Layout::Common::RangeRecord const & get_null () { + return *reinterpret_cast *> (_hb_Null_OT_RangeRecord); + } +}; + + +#endif // #ifndef OT_LAYOUT_COMMON_RANGERECORD_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,918 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2011,2012 Google, 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#ifndef OT_LAYOUT_GDEF_GDEF_HH +#define OT_LAYOUT_GDEF_GDEF_HH + +#include "../../../hb-ot-layout-common.hh" + +#include "../../../hb-font.hh" + + +namespace OT { + + +/* + * Attachment List Table + */ + +/* Array of contour point indices--in increasing numerical order */ +struct AttachPoint : Array16Of +{ + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->serialize (c->serializer, + iter ())); + } +}; + +struct AttachList +{ + unsigned int get_attach_points (hb_codepoint_t glyph_id, + unsigned int start_offset, + unsigned int *point_count /* IN/OUT */, + unsigned int *point_array /* OUT */) const + { + unsigned int index = (this+coverage).get_coverage (glyph_id); + if (index == NOT_COVERED) + { + if (point_count) + *point_count = 0; + return 0; + } + + const AttachPoint &points = this+attachPoint[index]; + + if (point_count) + { + + points.as_array ().sub_array (start_offset, point_count) + | hb_sink (hb_array (point_array, *point_count)) + ; + } + + return points.len; + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_sorted_vector_t new_coverage; + + hb_zip (this+coverage, attachPoint) + | hb_filter (glyphset, hb_first) + | hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); + return_trace (bool (new_coverage)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this)); + } + + protected: + Offset16To + coverage; /* Offset to Coverage table -- from + * beginning of AttachList table */ + Array16OfOffset16To + attachPoint; /* Array of AttachPoint tables + * in Coverage Index order */ + public: + DEFINE_SIZE_ARRAY (4, attachPoint); +}; + +/* + * Ligature Caret Table + */ + +struct CaretValueFormat1 +{ + friend struct CaretValue; + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + return_trace (true); + } + + private: + hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const + { + return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 caretValueFormat; /* Format identifier--format = 1 */ + FWORD coordinate; /* X or Y value, in design units */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct CaretValueFormat2 +{ + friend struct CaretValue; + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + return_trace (true); + } + + private: + hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const + { + hb_position_t x, y; + font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y); + return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 caretValueFormat; /* Format identifier--format = 2 */ + HBUINT16 caretValuePoint; /* Contour point index on glyph */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct CaretValueFormat3 +{ + friend struct CaretValue; + + hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, + const VariationStore &var_store) const + { + return HB_DIRECTION_IS_HORIZONTAL (direction) ? + font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) : + font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store); + } + + 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->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)) + { + 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->plan->all_axes_pinned) + return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); + + if (!c->serializer->embed (deviceTable)) + return_trace (false); + + return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, c->serializer->to_bias (out), + hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map)); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { (this+deviceTable).collect_variation_indices (c); } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && deviceTable.sanitize (c, this)); + } + + protected: + HBUINT16 caretValueFormat; /* Format identifier--format = 3 */ + FWORD coordinate; /* X or Y value, in design units */ + Offset16To + deviceTable; /* Offset to Device table for X or Y + * value--from beginning of CaretValue + * table */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct CaretValue +{ + hb_position_t get_caret_value (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph_id, + const VariationStore &var_store) const + { + switch (u.format) { + case 1: return u.format1.get_caret_value (font, direction); + case 2: return u.format2.get_caret_value (font, direction, glyph_id); + case 3: return u.format3.get_caret_value (font, direction, var_store); + default:return 0; + } + } + + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format); + switch (u.format) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + switch (u.format) { + case 1: + case 2: + return; + case 3: + u.format3.collect_variation_indices (c); + return; + default: return; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + default:return_trace (true); + } + } + + protected: + union { + HBUINT16 format; /* Format identifier */ + CaretValueFormat1 format1; + CaretValueFormat2 format2; + CaretValueFormat3 format3; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + +struct LigGlyph +{ + unsigned get_lig_carets (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph_id, + const VariationStore &var_store, + unsigned start_offset, + unsigned *caret_count /* IN/OUT */, + hb_position_t *caret_array /* OUT */) const + { + if (caret_count) + { + + carets.as_array ().sub_array (start_offset, caret_count) + | hb_map (hb_add (this)) + | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); }) + | hb_sink (hb_array (caret_array, *caret_count)) + ; + } + + return carets.len; + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + + hb_iter (carets) + | hb_apply (subset_offset_array (c, out->carets, this)) + ; + + return_trace (bool (out->carets)); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + for (const Offset16To& offset : carets.iter ()) + (this+offset).collect_variation_indices (c); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (carets.sanitize (c, this)); + } + + protected: + Array16OfOffset16To + carets; /* Offset array of CaretValue tables + * --from beginning of LigGlyph table + * --in increasing coordinate order */ + public: + DEFINE_SIZE_ARRAY (2, carets); +}; + +struct LigCaretList +{ + unsigned int get_lig_carets (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph_id, + const VariationStore &var_store, + unsigned int start_offset, + unsigned int *caret_count /* IN/OUT */, + hb_position_t *caret_array /* OUT */) const + { + unsigned int index = (this+coverage).get_coverage (glyph_id); + if (index == NOT_COVERED) + { + if (caret_count) + *caret_count = 0; + return 0; + } + const LigGlyph &lig_glyph = this+ligGlyph[index]; + return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_sorted_vector_t new_coverage; + + hb_zip (this+coverage, ligGlyph) + | hb_filter (glyphset, hb_first) + | hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); + return_trace (bool (new_coverage)); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + + hb_zip (this+coverage, ligGlyph) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); }) + ; + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this)); + } + + protected: + Offset16To + coverage; /* Offset to Coverage table--from + * beginning of LigCaretList table */ + Array16OfOffset16To + ligGlyph; /* Array of LigGlyph tables + * in Coverage Index order */ + public: + DEFINE_SIZE_ARRAY (4, ligGlyph); +}; + + +struct MarkGlyphSetsFormat1 +{ + bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const + { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + + bool ret = true; + for (const Offset32To& offset : coverage.iter ()) + { + auto *o = out->coverage.serialize_append (c->serializer); + if (unlikely (!o)) + { + ret = false; + break; + } + + //not using o->serialize_subset (c, offset, this, out) here because + //OTS doesn't allow null offset. + //See issue: https://github.com/khaledhosny/ots/issues/172 + c->serializer->push (); + c->dispatch (this+offset); + c->serializer->add_link (*o, c->serializer->pop_pack ()); + } + + return_trace (ret && out->coverage.len); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (coverage.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 1 */ + Array16Of> + coverage; /* Array of long offsets to mark set + * coverage tables */ + public: + DEFINE_SIZE_ARRAY (4, coverage); +}; + +struct MarkGlyphSets +{ + bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const + { + switch (u.format) { + case 1: return u.format1.covers (set_index, glyph_id); + default:return false; + } + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + switch (u.format) { + case 1: return_trace (u.format1.subset (c)); + default:return_trace (false); + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) { + case 1: return_trace (u.format1.sanitize (c)); + default:return_trace (true); + } + } + + protected: + union { + HBUINT16 format; /* Format identifier */ + MarkGlyphSetsFormat1 format1; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + + +/* + * GDEF -- Glyph Definition + * https://docs.microsoft.com/en-us/typography/opentype/spec/gdef + */ + + +template +struct GDEFVersion1_2 +{ + friend struct GDEF; + + protected: + FixedVersion<>version; /* Version of the GDEF table--currently + * 0x00010003u */ + typename Types::template OffsetTo + glyphClassDef; /* Offset to class definition table + * for glyph type--from beginning of + * GDEF header (may be Null) */ + typename Types::template OffsetTo + attachList; /* Offset to list of glyphs with + * attachment points--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo + ligCaretList; /* Offset to list of positioning points + * for ligature carets--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo + markAttachClassDef; /* Offset to class definition table for + * mark attachment type--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo + markGlyphSetsDef; /* Offset to the table of mark set + * definitions--from beginning of GDEF + * header (may be NULL). Introduced + * in version 0x00010002. */ + Offset32To + varStore; /* Offset to the table of Item Variation + * Store--from beginning of GDEF + * header (may be NULL). Introduced + * in version 0x00010003. */ + public: + DEFINE_SIZE_MIN (4 + 4 * Types::size); + + unsigned int get_size () const + { + return min_size + + (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) + + (version.to_int () >= 0x00010003u ? varStore.static_size : 0); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + glyphClassDef.sanitize (c, this) && + attachList.sanitize (c, this) && + ligCaretList.sanitize (c, this) && + markAttachClassDef.sanitize (c, this) && + (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && + (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); + bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); + bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); + + bool subset_markglyphsetsdef = false; + if (version.to_int () >= 0x00010002u) + { + subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); + } + + bool subset_varstore = false; + if (version.to_int () >= 0x00010003u) + { + if (c->plan->all_axes_pinned) + out->varStore = 0; + else + subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ()); + } + + if (subset_varstore) + { + out->version.minor = 3; + } else if (subset_markglyphsetsdef) { + out->version.minor = 2; + } else { + out->version.minor = 0; + } + + return_trace (subset_glyphclassdef || subset_attachlist || + subset_ligcaretlist || subset_markattachclassdef || + (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || + (out->version.to_int () >= 0x00010003u && subset_varstore)); + } +}; + +struct GDEF +{ + static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF; + + enum GlyphClasses { + UnclassifiedGlyph = 0, + BaseGlyph = 1, + LigatureGlyph = 2, + MarkGlyph = 3, + ComponentGlyph = 4 + }; + + unsigned int get_size () const + { + switch (u.version.major) { + case 1: return u.version1.get_size (); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.get_size (); +#endif + default: return u.version.static_size; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!u.version.sanitize (c))) return_trace (false); + switch (u.version.major) { + case 1: return_trace (u.version1.sanitize (c)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (u.version2.sanitize (c)); +#endif + default: return_trace (true); + } + } + + bool subset (hb_subset_context_t *c) const + { + switch (u.version.major) { + case 1: return u.version1.subset (c); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.subset (c); +#endif + default: return false; + } + } + + bool has_glyph_classes () const + { + switch (u.version.major) { + case 1: return u.version1.glyphClassDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.glyphClassDef != 0; +#endif + default: return false; + } + } + const ClassDef &get_glyph_class_def () const + { + switch (u.version.major) { + case 1: return this+u.version1.glyphClassDef; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.glyphClassDef; +#endif + default: return Null(ClassDef); + } + } + bool has_attach_list () const + { + switch (u.version.major) { + case 1: return u.version1.attachList != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.attachList != 0; +#endif + default: return false; + } + } + const AttachList &get_attach_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.attachList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.attachList; +#endif + default: return Null(AttachList); + } + } + bool has_lig_carets () const + { + switch (u.version.major) { + case 1: return u.version1.ligCaretList != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.ligCaretList != 0; +#endif + default: return false; + } + } + const LigCaretList &get_lig_caret_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.ligCaretList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.ligCaretList; +#endif + default: return Null(LigCaretList); + } + } + bool has_mark_attachment_types () const + { + switch (u.version.major) { + case 1: return u.version1.markAttachClassDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.markAttachClassDef != 0; +#endif + default: return false; + } + } + const ClassDef &get_mark_attach_class_def () const + { + switch (u.version.major) { + case 1: return this+u.version1.markAttachClassDef; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.markAttachClassDef; +#endif + default: return Null(ClassDef); + } + } + bool has_mark_glyph_sets () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.markGlyphSetsDef != 0; +#endif + default: return false; + } + } + const MarkGlyphSets &get_mark_glyph_sets () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.markGlyphSetsDef; +#endif + default: return Null(MarkGlyphSets); + } + } + bool has_var_store () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.varStore != 0; +#endif + default: return false; + } + } + const VariationStore &get_var_store () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.varStore; +#endif + default: return Null(VariationStore); + } + } + + + bool has_data () const { return u.version.to_int (); } + unsigned int get_glyph_class (hb_codepoint_t glyph) const + { return get_glyph_class_def ().get_class (glyph); } + void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const + { get_glyph_class_def ().collect_class (glyphs, klass); } + + unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const + { return get_mark_attach_class_def ().get_class (glyph); } + + unsigned int get_attach_points (hb_codepoint_t glyph_id, + unsigned int start_offset, + unsigned int *point_count /* IN/OUT */, + unsigned int *point_array /* OUT */) const + { return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); } + + unsigned int get_lig_carets (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph_id, + unsigned int start_offset, + unsigned int *caret_count /* IN/OUT */, + hb_position_t *caret_array /* OUT */) const + { return get_lig_caret_list ().get_lig_carets (font, + direction, glyph_id, get_var_store(), + start_offset, caret_count, caret_array); } + + bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const + { return get_mark_glyph_sets ().covers (set_index, glyph_id); } + + /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing + * glyph class and other bits, and high 8-bit the mark attachment type (if any). + * Not to be confused with lookup_props which is very similar. */ + unsigned int get_glyph_props (hb_codepoint_t glyph) const + { + unsigned int klass = get_glyph_class (glyph); + + static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs), ""); + static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures), ""); + static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), ""); + + switch (klass) { + default: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED; + case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH; + case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; + case MarkGlyph: + klass = get_mark_attachment_type (glyph); + return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8); + } + } + + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + table = hb_sanitize_context_t ().reference_table (face); + if (unlikely (table->is_blocklisted (table.get_blob (), face))) + { + hb_blob_destroy (table.get_blob ()); + table = hb_blob_get_empty (); + } + } + ~accelerator_t () { table.destroy (); } + + hb_blob_ptr_t table; + }; + + 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, + hb_hashmap_t> *layout_variation_idx_delta_map /* OUT */) const + { + if (!has_var_store ()) return; + if (layout_variation_indices->is_empty ()) return; + + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (layout_variation_indices->get_min ()) >> 16; + for (unsigned idx : layout_variation_indices->iter ()) + { + uint16_t major = idx >> 16; + if (major >= get_var_store ().get_sub_table_count ()) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + 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; + } + } + + protected: + union { + FixedVersion<> version; /* Version identifier */ + GDEFVersion1_2 version1; +#ifndef HB_NO_BEYOND_64K + GDEFVersion1_2 version2; +#endif + } u; + public: + DEFINE_SIZE_MIN (4); +}; + +struct GDEF_accelerator_t : GDEF::accelerator_t { + GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {} +}; + +} /* namespace OT */ + + +#endif /* OT_LAYOUT_GDEF_GDEF_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh 2023-07-05 07:11:54.000000000 +0000 @@ -41,24 +41,54 @@ *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); } - AnchorFormat3* copy (hb_serialize_context_t *c, - const hb_map_t *layout_variation_idx_map) const + bool subset (hb_subset_context_t *c) const { - TRACE_SERIALIZE (this); - if (!layout_variation_idx_map) return_trace (nullptr); + 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); - auto *out = c->embed (this); - if (unlikely (!out)) return_trace (nullptr); + 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)) + { + int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx)); + if (delta != 0) + { + if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta, + HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + } + } - out->xDeviceTable.serialize_copy (c, xDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map); - out->yDeviceTable.serialize_copy (c, yDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map); + 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)) + { + int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx)); + if (delta != 0) + { + if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta, + HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + } + } + + if (c->plan->all_axes_pinned) + return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); + + if (!c->serializer->embed (xDeviceTable)) return_trace (false); + if (!c->serializer->embed (yDeviceTable)) return_trace (false); + + out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map); + out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map); return_trace (out); } void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { - (this+xDeviceTable).collect_variation_indices (c->layout_variation_indices); - (this+yDeviceTable).collect_variation_indices (c->layout_variation_indices); + (this+xDeviceTable).collect_variation_indices (c); + (this+yDeviceTable).collect_variation_indices (c); } }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh 2023-07-05 07:11:54.000000000 +0000 @@ -58,8 +58,7 @@ return_trace (bool (reinterpret_cast (u.format1.copy (c->serializer)))); } return_trace (bool (reinterpret_cast (u.format2.copy (c->serializer)))); - case 3: return_trace (bool (reinterpret_cast (u.format3.copy (c->serializer, - c->plan->layout_variation_idx_map)))); + case 3: return_trace (u.format3.subset (c)); default:return_trace (false); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -22,7 +22,8 @@ static void SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, - const hb_map_t *layout_variation_idx_map); + const hb_hashmap_t> *layout_variation_idx_delta_map, + bool all_axes_pinned); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -140,7 +140,14 @@ unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; - buffer->unsafe_to_break (i, j); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "cursive attaching glyph at %u to glyph at %u", + i, j); + } + + buffer->unsafe_to_break (i, j + 1); float entry_x, entry_y, exit_x, exit_y; (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y); @@ -223,7 +230,20 @@ * https://github.com/harfbuzz/harfbuzz/issues/2469 */ if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain())) + { pos[parent].attach_chain() = 0; + if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) + pos[parent].y_offset = 0; + else + pos[parent].x_offset = 0; + } + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "cursive attached glyph at %u to glyph at %u", + i, j); + } buffer->idx++; return_trace (true); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh 2023-07-05 07:11:54.000000000 +0000 @@ -19,8 +19,8 @@ template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); default:return_trace (c->default_return_value ()); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,171 @@ +#ifndef OT_LAYOUT_GPOS_GPOS_HH +#define OT_LAYOUT_GPOS_GPOS_HH + +#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-layout-gsubgpos.hh" +#include "Common.hh" +#include "PosLookup.hh" + +namespace OT { + +using Layout::GPOS_impl::PosLookup; + +namespace Layout { + +static void +propagate_attachment_offsets (hb_glyph_position_t *pos, + unsigned int len, + unsigned int i, + hb_direction_t direction, + unsigned nesting_level = HB_MAX_NESTING_LEVEL); + +/* + * GPOS -- Glyph Positioning + * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos + */ + +struct GPOS : GSUBGPOS +{ + static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS; + + using Lookup = PosLookup; + + const PosLookup& get_lookup (unsigned int i) const + { return static_cast (GSUBGPOS::get_lookup (i)); } + + static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); + static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); + static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer); + + bool subset (hb_subset_context_t *c) const + { + hb_subset_layout_context_t l (c, tableTag); + return GSUBGPOS::subset (&l); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (GSUBGPOS::sanitize (c)); + } + + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++) + { + if (!c->gpos_lookups->has (i)) continue; + const PosLookup &l = get_lookup (i); + l.dispatch (c); + } + } + + void closure_lookups (hb_face_t *face, + const hb_set_t *glyphs, + hb_set_t *lookup_indexes /* IN/OUT */) const + { GSUBGPOS::closure_lookups (face, glyphs, lookup_indexes); } + + typedef GSUBGPOS::accelerator_t accelerator_t; +}; + + +static void +propagate_attachment_offsets (hb_glyph_position_t *pos, + unsigned int len, + unsigned int i, + hb_direction_t direction, + unsigned nesting_level) +{ + /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate + * offset of glyph they are attached to. */ + int chain = pos[i].attach_chain(), type = pos[i].attach_type(); + if (likely (!chain)) + return; + + pos[i].attach_chain() = 0; + + unsigned int j = (int) i + chain; + + if (unlikely (j >= len)) + return; + + if (unlikely (!nesting_level)) + return; + + propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); + + assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE)); + + if (type & GPOS_impl::ATTACH_TYPE_CURSIVE) + { + if (HB_DIRECTION_IS_HORIZONTAL (direction)) + pos[i].y_offset += pos[j].y_offset; + else + pos[i].x_offset += pos[j].x_offset; + } + else /*if (type & GPOS_impl::ATTACH_TYPE_MARK)*/ + { + pos[i].x_offset += pos[j].x_offset; + pos[i].y_offset += pos[j].y_offset; + + assert (j < i); + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = j; k < i; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + else + for (unsigned int k = j + 1; k < i + 1; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + } +} + +void +GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) +{ + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0; +} + +void +GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED) +{ + //_hb_buffer_assert_gsubgpos_vars (buffer); +} + +void +GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) +{ + _hb_buffer_assert_gsubgpos_vars (buffer); + + unsigned int len; + hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); + hb_direction_t direction = buffer->props.direction; + + /* Handle attachments */ + if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) + for (unsigned i = 0; i < len; i++) + propagate_attachment_offsets (pos, len, i, direction); + + if (unlikely (font->slant)) + { + 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); + } +} + +} + +struct GPOS_accelerator_t : Layout::GPOS::accelerator_t { + GPOS_accelerator_t (hb_face_t *face) : Layout::GPOS::accelerator_t (face) {} +}; + +} + +#endif /* OT_LAYOUT_GPOS_GPOS_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,56 @@ +#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH +#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +typedef AnchorMatrix LigatureAttach; /* component-major-- + * in order of writing direction--, + * mark-minor-- + * ordered by class--zero-based. */ + +/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ +struct LigatureArray : List16OfOffset16To +{ + template + bool subset (hb_subset_context_t *c, + Iterator coverage, + unsigned class_count, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + for (const auto _ : + hb_zip (coverage, *this) + | hb_filter (glyphset, hb_first)) + { + auto *matrix = out->serialize_append (c->serializer); + if (unlikely (!matrix)) return_trace (false); + + const LigatureAttach& src = (this + _.second); + auto indexes = + + 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); + } + return_trace (this->len); + } +}; + + +} +} +} + +#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh 2023-07-05 07:11:54.000000000 +0000 @@ -39,6 +39,13 @@ mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y); glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "attaching mark glyph at %u to glyph at %u", + c->buffer->idx, glyph_pos); + } + hb_glyph_position_t &o = buffer->cur_pos(); o.x_offset = roundf (base_x - mark_x); o.y_offset = roundf (base_y - mark_y); @@ -46,6 +53,13 @@ o.attach_chain() = (int) glyph_pos - (int) buffer->idx; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "attached mark glyph at %u to glyph at %u", + c->buffer->idx, glyph_pos); + } + buffer->idx++; return_trace (true); } @@ -83,10 +97,11 @@ } }; -static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, - const MarkArray &mark_array, - const hb_set_t &glyphset, - hb_map_t* klass_mapping /* INOUT */) +HB_INTERNAL inline +void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, + const MarkArray &mark_array, + const hb_set_t &glyphset, + hb_map_t* klass_mapping /* INOUT */) { hb_set_t orig_classes; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -12,26 +12,27 @@ * mark-minor-- * ordered by class--zero-based. */ -struct MarkBasePosFormat1 +template +struct MarkBasePosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo markCoverage; /* Offset to MarkCoverage table--from * beginning of MarkBasePos subtable */ - Offset16To + typename Types::template OffsetTo baseCoverage; /* Offset to BaseCoverage table--from * beginning of MarkBasePos subtable */ HBUINT16 classCount; /* Number of classes defined for marks */ - Offset16To + typename Types::template OffsetTo markArray; /* Offset to MarkArray table--from * beginning of MarkBasePos subtable */ - Offset16To + typename Types::template OffsetTo baseArray; /* Offset to BaseArray table--from * beginning of MarkBasePos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -89,6 +90,25 @@ const Coverage &get_coverage () const { return this+markCoverage; } + static inline bool accept (hb_buffer_t *buffer, unsigned idx) + { + /* We only want to attach to the first of a MultipleSubst sequence. + * https://github.com/harfbuzz/harfbuzz/issues/740 + * Reject others... + * ...but stop if we find a mark in the MultipleSubst sequence: + * https://github.com/harfbuzz/harfbuzz/issues/1020 */ + return !_hb_glyph_info_multiplied (&buffer->info[idx]) || + 0 == _hb_glyph_info_get_lig_comp (&buffer->info[idx]) || + (idx == 0 || + _hb_glyph_info_is_mark (&buffer->info[idx - 1]) || + !_hb_glyph_info_multiplied (&buffer->info[idx - 1]) || + _hb_glyph_info_get_lig_id (&buffer->info[idx]) != + _hb_glyph_info_get_lig_id (&buffer->info[idx - 1]) || + _hb_glyph_info_get_lig_comp (&buffer->info[idx]) != + _hb_glyph_info_get_lig_comp (&buffer->info[idx - 1]) + 1 + ); + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); @@ -96,47 +116,54 @@ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); if (likely (mark_index == NOT_COVERED)) return_trace (false); - /* Now we search backwards for a non-mark glyph */ + /* Now we search backwards for a non-mark glyph. + * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */ + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); - do { - unsigned unsafe_from; - if (!skippy_iter.prev (&unsafe_from)) + + if (c->last_base_until > buffer->idx) + { + c->last_base_until = 0; + c->last_base = -1; + } + unsigned j; + for (j = buffer->idx; j > c->last_base_until; j--) + { + auto match = skippy_iter.match (buffer->info[j - 1]); + if (match == skippy_iter.MATCH) { - buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1); - return_trace (false); + // https://github.com/harfbuzz/harfbuzz/issues/4124 + if (!accept (buffer, j - 1) && + NOT_COVERED == (this+baseCoverage).get_coverage (buffer->info[j - 1].codepoint)) + match = skippy_iter.SKIP; } - - /* We only want to attach to the first of a MultipleSubst sequence. - * https://github.com/harfbuzz/harfbuzz/issues/740 - * Reject others... - * ...but stop if we find a mark in the MultipleSubst sequence: - * https://github.com/harfbuzz/harfbuzz/issues/1020 */ - if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) || - 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) || - (skippy_iter.idx == 0 || - _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) || - _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) != - _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) || - _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) != - _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx - 1]) + 1 - )) + if (match == skippy_iter.MATCH) + { + c->last_base = (signed) j - 1; break; - skippy_iter.reject (); - } while (true); + } + } + c->last_base_until = buffer->idx; + if (c->last_base == -1) + { + buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1); + return_trace (false); + } + + unsigned idx = (unsigned) c->last_base; /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ - //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); } + //if (!_hb_glyph_info_is_base_glyph (&buffer->info[idx])) { return_trace (false); } - unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); + unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[idx].codepoint); if (base_index == NOT_COVERED) { - buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); + buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1); return_trace (false); } - return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); + return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, idx)); } bool subset (hb_subset_context_t *c) const diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh 2023-07-05 07:11:54.000000000 +0000 @@ -11,18 +11,24 @@ { protected: union { - HBUINT16 format; /* Format identifier */ - MarkBasePosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkBasePosFormat1_2 format1; +#ifndef HB_NO_BEYOND_64K + MarkBasePosFormat1_2 format2; +#endif } u; public: template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -1,72 +1,34 @@ #ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH #define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH +#include "LigatureArray.hh" + namespace OT { namespace Layout { namespace GPOS_impl { -typedef AnchorMatrix LigatureAttach; /* component-major-- - * in order of writing direction--, - * mark-minor-- - * ordered by class--zero-based. */ - -/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ -struct LigatureArray : List16OfOffset16To -{ - template - bool subset (hb_subset_context_t *c, - Iterator coverage, - unsigned class_count, - const hb_map_t *klass_mapping) const - { - TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - - auto *out = c->serializer->start_embed (this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - - for (const auto _ : + hb_zip (coverage, *this) - | hb_filter (glyphset, hb_first)) - { - auto *matrix = out->serialize_append (c->serializer); - if (unlikely (!matrix)) return_trace (false); - - const LigatureAttach& src = (this + _.second); - auto indexes = - + 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); - } - return_trace (this->len); - } -}; -struct MarkLigPosFormat1 +template +struct MarkLigPosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo markCoverage; /* Offset to Mark Coverage table--from * beginning of MarkLigPos subtable */ - Offset16To + typename Types::template OffsetTo ligatureCoverage; /* Offset to Ligature Coverage * table--from beginning of MarkLigPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - Offset16To + typename Types::template OffsetTo markArray; /* Offset to MarkArray table--from * beginning of MarkLigPos subtable */ - Offset16To + typename Types::template OffsetTo ligatureArray; /* Offset to LigatureArray table--from * beginning of MarkLigPos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -138,20 +100,37 @@ if (likely (mark_index == NOT_COVERED)) return_trace (false); /* Now we search backwards for 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.set_lookup_props (LookupFlag::IgnoreMarks); - unsigned unsafe_from; - if (!skippy_iter.prev (&unsafe_from)) + + if (c->last_base_until > buffer->idx) { - buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1); + c->last_base_until = 0; + c->last_base = -1; + } + unsigned j; + for (j = buffer->idx; j > c->last_base_until; j--) + { + auto match = skippy_iter.match (buffer->info[j - 1]); + if (match == skippy_iter.MATCH) + { + c->last_base = (signed) j - 1; + break; + } + } + c->last_base_until = buffer->idx; + if (c->last_base == -1) + { + buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1); return_trace (false); } + j = (unsigned) c->last_base; + /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ - //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); } + //if (!_hb_glyph_info_is_ligature (&buffer->info[j])) { return_trace (false); } - unsigned int j = skippy_iter.idx; unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); if (lig_index == NOT_COVERED) { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh 2023-07-05 07:11:54.000000000 +0000 @@ -11,18 +11,24 @@ { protected: union { - HBUINT16 format; /* Format identifier */ - MarkLigPosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkLigPosFormat1_2 format1; +#ifndef HB_NO_BEYOND_64K + MarkLigPosFormat1_2 format2; +#endif } u; public: template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -12,27 +12,28 @@ * mark1-minor-- * ordered by class--zero-based. */ -struct MarkMarkPosFormat1 +template +struct MarkMarkPosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo mark1Coverage; /* Offset to Combining Mark1 Coverage * table--from beginning of MarkMarkPos * subtable */ - Offset16To + typename Types::template OffsetTo mark2Coverage; /* Offset to Combining Mark2 Coverage * table--from beginning of MarkMarkPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - Offset16To + typename Types::template OffsetTo mark1Array; /* Offset to Mark1Array table--from * beginning of MarkMarkPos subtable */ - Offset16To + typename Types::template OffsetTo mark2Array; /* Offset to Mark2Array table--from * beginning of MarkMarkPos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -100,7 +101,7 @@ /* 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.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); + skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); unsigned unsafe_from; if (!skippy_iter.prev (&unsafe_from)) { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh 2023-07-05 07:11:54.000000000 +0000 @@ -11,18 +11,24 @@ { protected: union { - HBUINT16 format; /* Format identifier */ - MarkMarkPosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkMarkPosFormat1_2 format1; +#ifndef HB_NO_BEYOND_64K + MarkMarkPosFormat1_2 format2; +#endif } u; public: template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh 2023-07-05 07:11:54.000000000 +0000 @@ -9,7 +9,7 @@ { friend struct MarkArray; - protected: + public: HBUINT16 klass; /* Class defined for this mark */ Offset16To markAnchor; /* Offset to Anchor table--from diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -1,248 +1,22 @@ #ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH #define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH +#include "PairSet.hh" + namespace OT { namespace Layout { namespace GPOS_impl { -struct PairValueRecord -{ - friend struct PairSet; - - int cmp (hb_codepoint_t k) const - { return secondGlyph.cmp (k); } - - struct context_t - { - const void *base; - const ValueFormat *valueFormats; - const ValueFormat *newFormats; - unsigned len1; /* valueFormats[0].get_len() */ - const hb_map_t *glyph_map; - const hb_map_t *layout_variation_idx_map; - }; - - bool subset (hb_subset_context_t *c, - context_t *closure) const - { - TRACE_SERIALIZE (this); - auto *s = c->serializer; - auto *out = s->start_embed (*this); - if (unlikely (!s->extend_min (out))) return_trace (false); - - out->secondGlyph = (*closure->glyph_map)[secondGlyph]; - - closure->valueFormats[0].copy_values (s, - closure->newFormats[0], - closure->base, &values[0], - closure->layout_variation_idx_map); - closure->valueFormats[1].copy_values (s, - closure->newFormats[1], - closure->base, - &values[closure->len1], - closure->layout_variation_idx_map); - - return_trace (true); - } - - void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const ValueFormat *valueFormats, - const void *base) const - { - unsigned record1_len = valueFormats[0].get_len (); - unsigned record2_len = valueFormats[1].get_len (); - const hb_array_t values_array = values.as_array (record1_len + record2_len); - - if (valueFormats[0].has_device ()) - valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len)); - - if (valueFormats[1].has_device ()) - valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); - } - - bool intersects (const hb_set_t& glyphset) const - { - return glyphset.has(secondGlyph); - } - - const Value* get_values_1 () const - { - return &values[0]; - } - - const Value* get_values_2 (ValueFormat format1) const - { - return &values[format1.get_len ()]; - } - - protected: - HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the - * pair--first glyph is listed in the - * Coverage table */ - ValueRecord values; /* Positioning data for the first glyph - * followed by for second glyph */ - public: - DEFINE_SIZE_ARRAY (2, values); -}; -struct PairSet +template +struct PairPosFormat1_3 { - friend struct PairPosFormat1; - - bool intersects (const hb_set_t *glyphs, - const ValueFormat *valueFormats) const - { - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - { - if (glyphs->has (record->secondGlyph)) - return true; - record = &StructAtOffset (record, record_size); - } - return false; - } - - void collect_glyphs (hb_collect_glyphs_context_t *c, - const ValueFormat *valueFormats) const - { - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - c->input->add_array (&record->secondGlyph, len, record_size); - } - - void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const ValueFormat *valueFormats) const - { - unsigned len1 = valueFormats[0].get_len (); - unsigned len2 = valueFormats[1].get_len (); - unsigned record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - unsigned count = len; - for (unsigned i = 0; i < count; i++) - { - if (c->glyph_set->has (record->secondGlyph)) - { record->collect_variation_indices (c, valueFormats, this); } - - record = &StructAtOffset (record, record_size); - } - } - - bool apply (hb_ot_apply_context_t *c, - const ValueFormat *valueFormats, - unsigned int pos) const - { - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint, - &firstPairValueRecord, - len, - record_size); - if (record) - { - 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]); - if (applied_first || applied_second) - buffer->unsafe_to_break (buffer->idx, pos + 1); - if (len2) - pos++; - buffer->idx = pos; - return_trace (true); - } - buffer->unsafe_to_concat (buffer->idx, pos + 1); - return_trace (false); - } - - bool subset (hb_subset_context_t *c, - const ValueFormat valueFormats[2], - const ValueFormat newFormats[2]) const - { - TRACE_SUBSET (this); - auto snap = c->serializer->snapshot (); - - auto *out = c->serializer->start_embed (*this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - out->len = 0; - - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; - - unsigned len1 = valueFormats[0].get_len (); - unsigned len2 = valueFormats[1].get_len (); - unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); - - PairValueRecord::context_t context = - { - this, - valueFormats, - newFormats, - len1, - &glyph_map, - c->plan->layout_variation_idx_map - }; - - const PairValueRecord *record = &firstPairValueRecord; - unsigned count = len, num = 0; - for (unsigned i = 0; i < count; i++) - { - if (glyphset.has (record->secondGlyph) - && record->subset (c, &context)) num++; - record = &StructAtOffset (record, record_size); - } - - out->len = num; - if (!num) c->serializer->revert (snap); - return_trace (num); - } - - struct sanitize_closure_t - { - const ValueFormat *valueFormats; - unsigned int len1; /* valueFormats[0].get_len() */ - unsigned int stride; /* 1 + len1 + len2 */ - }; - - bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const - { - TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && c->check_range (&firstPairValueRecord, - len, - HBUINT16::static_size, - closure->stride))) return_trace (false); - - 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)); - } + using PairSet = GPOS_impl::PairSet; + using PairValueRecord = GPOS_impl::PairValueRecord; protected: - HBUINT16 len; /* Number of PairValueRecords */ - PairValueRecord firstPairValueRecord; - /* Array of PairValueRecords--ordered - * by GlyphID of the second glyph */ - public: - DEFINE_SIZE_MIN (2); -}; - -struct PairPosFormat1 -{ - protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat[2]; /* [0] Defines the types of data in @@ -251,11 +25,11 @@ /* [1] Defines the types of data in * ValueRecord2--for the second glyph * in the pair--may be zero (0) */ - Array16OfOffset16To + Array16Of> pairSet; /* Array of PairSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (10, pairSet); + DEFINE_SIZE_ARRAY (8 + Types::size, pairSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -265,24 +39,36 @@ unsigned int len1 = valueFormat[0].get_len (); unsigned int len2 = valueFormat[1].get_len (); - PairSet::sanitize_closure_t closure = + typename PairSet::sanitize_closure_t closure = { valueFormat, len1, - 1 + len1 + len2 + PairSet::get_size (len1, len2) }; return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); } - bool intersects (const hb_set_t *glyphs) const { + auto &cov = this+coverage; + + if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4) + { + for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + { + unsigned i = cov.get_coverage (g); + if ((this+pairSet[i]).intersects (glyphs, valueFormat)) + return true; + } + return false; + } + return - + hb_zip (this+coverage, pairSet) + + hb_zip (cov, pairSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([glyphs, this] (const Offset16To &_) + | hb_map ([glyphs, this] (const typename Types::template OffsetTo &_) { return (this+_).intersects (glyphs, valueFormat); }) | hb_any ; @@ -354,11 +140,17 @@ out->valueFormat[1] = newFormats.second; } + if (c->plan->all_axes_pinned) + { + out->valueFormat[0] = out->valueFormat[0].drop_device_table_flags (); + out->valueFormat[1] = out->valueFormat[1].drop_device_table_flags (); + } + hb_sorted_vector_t new_coverage; + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) - | hb_filter ([this, c, out] (const Offset16To& _) + | hb_filter ([this, c, out] (const typename Types::template OffsetTo& _) { auto snap = c->serializer->snapshot (); auto *o = out->pairSet.serialize_append (c->serializer); @@ -385,19 +177,21 @@ hb_pair_t compute_effective_value_formats (const hb_set_t& glyphset) const { - unsigned len1 = valueFormat[0].get_len (); - unsigned len2 = valueFormat[1].get_len (); - unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); + unsigned record_size = PairSet::get_size (valueFormat); unsigned format1 = 0; unsigned format2 = 0; - for (const Offset16To& _ : - + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second)) + for (const auto & _ : + + hb_zip (this+coverage, pairSet) + | hb_filter (glyphset, hb_first) + | hb_map (hb_second) + ) { const PairSet& set = (this + _); const PairValueRecord *record = &set.firstPairValueRecord; - for (unsigned i = 0; i < set.len; i++) + unsigned count = set.len; + for (unsigned i = 0; i < count; i++) { if (record->intersects (glyphset)) { @@ -406,6 +200,9 @@ } record = &StructAtOffset (record, record_size); } + + if (format1 == valueFormat[0] && format2 == valueFormat[1]) + break; } return hb_pair (format1, format2); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh 2023-07-05 07:11:54.000000000 +0000 @@ -7,11 +7,12 @@ namespace Layout { namespace GPOS_impl { -struct PairPosFormat2 +template +struct PairPosFormat2_4 { protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To + typename Types::template OffsetTo coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat1; /* ValueRecord definition--for the @@ -20,11 +21,11 @@ ValueFormat valueFormat2; /* ValueRecord definition--for the * second glyph of the pair--may be * zero (0) */ - Offset16To + typename Types::template OffsetTo classDef1; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the first glyph of the pair */ - Offset16To + typename Types::template OffsetTo classDef2; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the second glyph of the pair */ @@ -36,7 +37,7 @@ * class1-major, class2-minor, * Each entry has value1 and value2 */ public: - DEFINE_SIZE_ARRAY (16, values); + DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values); bool sanitize (hb_sanitize_context_t *c) const { @@ -48,7 +49,7 @@ unsigned int len1 = valueFormat1.get_len (); unsigned int len2 = valueFormat2.get_len (); - unsigned int stride = len1 + len2; + 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, @@ -216,10 +217,31 @@ } bail: + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "try kerning glyphs at %u,%u", + 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]); + if (applied_first || applied_second) + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %u,%u", + c->buffer->idx, skippy_iter.idx); + } + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "tried kerning glyphs at %u,%u", + c->buffer->idx, skippy_iter.idx); + } + success: if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); @@ -227,10 +249,15 @@ boring: buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); + if (len2) + { + skippy_iter.idx++; + // https://github.com/harfbuzz/harfbuzz/issues/3824 + // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116 + buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); + } buffer->idx = skippy_iter.idx; - if (len2) - buffer->idx++; return_trace (true); } @@ -260,13 +287,19 @@ out->valueFormat1 = newFormats.first; out->valueFormat2 = newFormats.second; + if (c->plan->all_axes_pinned) + { + out->valueFormat1 = out->valueFormat1.drop_device_table_flags (); + out->valueFormat2 = out->valueFormat2.drop_device_table_flags (); + } + for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) { for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) { unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); - valueFormat1.copy_values (c->serializer, newFormats.first, this, &values[idx], c->plan->layout_variation_idx_map); - valueFormat2.copy_values (c->serializer, newFormats.second, this, &values[idx + len1], c->plan->layout_variation_idx_map); + 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); } } @@ -289,6 +322,7 @@ { unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); + unsigned record_size = len1 + len2; unsigned format1 = 0; unsigned format2 = 0; @@ -297,10 +331,13 @@ { for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) { - unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); + unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size; format1 = format1 | valueFormat1.get_effective_format (&values[idx]); format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]); } + + if (format1 == valueFormat1 && format2 == valueFormat2) + break; } return hb_pair (format1, format2); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh 2023-07-05 07:11:54.000000000 +0000 @@ -12,20 +12,28 @@ { protected: union { - HBUINT16 format; /* Format identifier */ - PairPosFormat1 format1; - PairPosFormat2 format2; + HBUINT16 format; /* Format identifier */ + PairPosFormat1_3 format1; + PairPosFormat2_4 format2; +#ifndef HB_NO_BEYOND_64K + PairPosFormat1_3 format3; + PairPosFormat2_4 format4; +#endif } u; public: template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,207 @@ +#ifndef OT_LAYOUT_GPOS_PAIRSET_HH +#define OT_LAYOUT_GPOS_PAIRSET_HH + +#include "PairValueRecord.hh" + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +template +struct PairSet +{ + template + friend struct PairPosFormat1_3; + + using PairValueRecord = GPOS_impl::PairValueRecord; + + protected: + HBUINT16 len; /* Number of PairValueRecords */ + PairValueRecord firstPairValueRecord; + /* Array of PairValueRecords--ordered + * by GlyphID of the second glyph */ + public: + DEFINE_SIZE_MIN (2); + + static unsigned get_size (unsigned len1, unsigned len2) + { + return Types::HBGlyphID::static_size + Value::static_size * (len1 + len2); + } + static unsigned get_size (const ValueFormat valueFormats[2]) + { + unsigned len1 = valueFormats[0].get_len (); + unsigned len2 = valueFormats[1].get_len (); + return get_size (len1, len2); + } + + struct sanitize_closure_t + { + const ValueFormat *valueFormats; + unsigned int len1; /* valueFormats[0].get_len() */ + unsigned int stride; /* bytes */ + }; + + bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const + { + TRACE_SANITIZE (this); + if (!(c->check_struct (this) + && c->check_range (&firstPairValueRecord, + len, + closure->stride))) return_trace (false); + + 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)); + } + + bool intersects (const hb_set_t *glyphs, + const ValueFormat *valueFormats) const + { + unsigned record_size = get_size (valueFormats); + + const PairValueRecord *record = &firstPairValueRecord; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + { + if (glyphs->has (record->secondGlyph)) + return true; + record = &StructAtOffset (record, record_size); + } + return false; + } + + void collect_glyphs (hb_collect_glyphs_context_t *c, + const ValueFormat *valueFormats) const + { + unsigned record_size = get_size (valueFormats); + + const PairValueRecord *record = &firstPairValueRecord; + c->input->add_array (&record->secondGlyph, len, record_size); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats) const + { + unsigned record_size = get_size (valueFormats); + + const PairValueRecord *record = &firstPairValueRecord; + unsigned count = len; + for (unsigned i = 0; i < count; i++) + { + if (c->glyph_set->has (record->secondGlyph)) + { record->collect_variation_indices (c, valueFormats, this); } + + record = &StructAtOffset (record, record_size); + } + } + + bool apply (hb_ot_apply_context_t *c, + const ValueFormat *valueFormats, + unsigned int pos) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + unsigned int len1 = valueFormats[0].get_len (); + unsigned int len2 = valueFormats[1].get_len (); + unsigned record_size = get_size (len1, len2); + + const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint, + &firstPairValueRecord, + len, + record_size); + if (record) + { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "try kerning glyphs at %u,%u", + 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]); + + if (applied_first || applied_second) + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %u,%u", + c->buffer->idx, pos); + } + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "tried kerning glyphs at %u,%u", + c->buffer->idx, pos); + } + + if (applied_first || applied_second) + buffer->unsafe_to_break (buffer->idx, pos + 1); + + if (len2) + { + pos++; + // https://github.com/harfbuzz/harfbuzz/issues/3824 + // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116 + buffer->unsafe_to_break (buffer->idx, pos + 1); + } + + buffer->idx = pos; + return_trace (true); + } + buffer->unsafe_to_concat (buffer->idx, pos + 1); + return_trace (false); + } + + bool subset (hb_subset_context_t *c, + const ValueFormat valueFormats[2], + const ValueFormat newFormats[2]) const + { + TRACE_SUBSET (this); + auto snap = c->serializer->snapshot (); + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->len = 0; + + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + unsigned len1 = valueFormats[0].get_len (); + unsigned len2 = valueFormats[1].get_len (); + unsigned record_size = get_size (len1, len2); + + typename PairValueRecord::context_t context = + { + this, + valueFormats, + newFormats, + len1, + &glyph_map, + &c->plan->layout_variation_idx_delta_map + }; + + const PairValueRecord *record = &firstPairValueRecord; + unsigned count = len, num = 0; + for (unsigned i = 0; i < count; i++) + { + if (glyphset.has (record->secondGlyph) + && record->subset (c, &context)) num++; + record = &StructAtOffset (record, record_size); + } + + out->len = num; + if (!num) c->serializer->revert (snap); + return_trace (num); + } +}; + + +} +} +} + +#endif // OT_LAYOUT_GPOS_PAIRSET_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,99 @@ +#ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH +#define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH + +#include "ValueFormat.hh" + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +template +struct PairValueRecord +{ + template + friend struct PairSet; + + protected: + typename Types::HBGlyphID + secondGlyph; /* GlyphID of second glyph in the + * pair--first glyph is listed in the + * Coverage table */ + ValueRecord values; /* Positioning data for the first glyph + * followed by for second glyph */ + public: + DEFINE_SIZE_ARRAY (Types::size, values); + + int cmp (hb_codepoint_t k) const + { return secondGlyph.cmp (k); } + + struct context_t + { + const void *base; + const ValueFormat *valueFormats; + const ValueFormat *newFormats; + unsigned len1; /* valueFormats[0].get_len() */ + const hb_map_t *glyph_map; + const hb_hashmap_t> *layout_variation_idx_delta_map; + }; + + bool subset (hb_subset_context_t *c, + context_t *closure) const + { + TRACE_SERIALIZE (this); + auto *s = c->serializer; + auto *out = s->start_embed (*this); + if (unlikely (!s->extend_min (out))) return_trace (false); + + out->secondGlyph = (*closure->glyph_map)[secondGlyph]; + + closure->valueFormats[0].copy_values (s, + closure->newFormats[0], + closure->base, &values[0], + closure->layout_variation_idx_delta_map); + closure->valueFormats[1].copy_values (s, + closure->newFormats[1], + closure->base, + &values[closure->len1], + closure->layout_variation_idx_delta_map); + + return_trace (true); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats, + const void *base) const + { + unsigned record1_len = valueFormats[0].get_len (); + unsigned record2_len = valueFormats[1].get_len (); + const hb_array_t values_array = values.as_array (record1_len + record2_len); + + if (valueFormats[0].has_device ()) + valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len)); + + if (valueFormats[1].has_device ()) + valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); + } + + bool intersects (const hb_set_t& glyphset) const + { + return glyphset.has(secondGlyph); + } + + const Value* get_values_1 () const + { + return &values[0]; + } + + const Value* get_values_2 (ValueFormat format1) const + { + return &values[format1.get_len ()]; + } +}; + + +} +} +} + +#endif // OT_LAYOUT_GPOS_PAIRVALUERECORD_HH diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -39,12 +39,10 @@ { if (!valueFormat.has_device ()) return; - auto it = - + hb_iter (this+coverage) - | hb_filter (c->glyph_set) - ; + hb_set_t intersection; + (this+coverage).intersect_set (*c->glyph_set, intersection); + if (!intersection) return; - if (!it) return; valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ())); } @@ -62,12 +60,44 @@ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioning glyph at %u", + c->buffer->idx); + } + valueFormat.apply_value (c, this, values, buffer->cur_pos()); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioned glyph at %u", + c->buffer->idx); + } + buffer->idx++; return_trace (true); } + bool + position_single (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t gid, + hb_glyph_position_t &pos) const + { + unsigned int index = (this+coverage).get_coverage (gid); + if (likely (index == NOT_COVERED)) return false; + + /* This is ugly... */ + hb_buffer_t buffer; + buffer.props.direction = direction; + OT::hb_ot_apply_context_t c (1, font, &buffer); + + valueFormat.apply_value (&c, this, values, pos); + return true; + } + template @@ -75,7 +105,7 @@ const SrcLookup *src, Iterator it, ValueFormat newFormat, - const hb_map_t *layout_variation_idx_map) + const hb_hashmap_t> *layout_variation_idx_delta_map) { if (unlikely (!c->extend_min (this))) return; if (unlikely (!c->check_assign (valueFormat, @@ -84,7 +114,7 @@ for (const hb_array_t& _ : + it | hb_map (hb_second)) { - src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); + src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map); // Only serialize the first entry in the iterator, the rest are assumed to // be the same. break; @@ -104,15 +134,17 @@ const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; + hb_set_t intersection; + (this+coverage).intersect_set (glyphset, intersection); + auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) + + hb_iter (intersection) | hb_map_retains_sorting (glyph_map) | hb_zip (hb_repeat (values.as_array (valueFormat.get_len ()))) ; bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); return_trace (ret); } }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh 2023-07-05 07:11:54.000000000 +0000 @@ -68,16 +68,52 @@ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - if (likely (index >= valueCount)) return_trace (false); + if (unlikely (index >= valueCount)) return_trace (false); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioning glyph at %u", + c->buffer->idx); + } valueFormat.apply_value (c, this, &values[index * valueFormat.get_len ()], buffer->cur_pos()); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioned glyph at %u", + c->buffer->idx); + } + buffer->idx++; return_trace (true); } + bool + position_single (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t gid, + hb_glyph_position_t &pos) const + { + unsigned int index = (this+coverage).get_coverage (gid); + if (likely (index == NOT_COVERED)) return false; + if (unlikely (index >= valueCount)) return false; + + /* This is ugly... */ + hb_buffer_t buffer; + buffer.props.direction = direction; + OT::hb_ot_apply_context_t c (1, font, &buffer); + + valueFormat.apply_value (&c, this, + &values[index * valueFormat.get_len ()], + pos); + return true; + } + + template @@ -85,7 +121,7 @@ const SrcLookup *src, Iterator it, ValueFormat newFormat, - const hb_map_t *layout_variation_idx_map) + const hb_hashmap_t> *layout_variation_idx_delta_map) { auto out = c->extend_min (this); if (unlikely (!out)) return; @@ -95,7 +131,7 @@ + it | hb_map (hb_second) | hb_apply ([&] (hb_array_t _) - { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); }) + { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map); }) ; auto glyphs = @@ -127,7 +163,7 @@ ; bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); return_trace (ret); } }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh 2023-07-05 07:11:54.000000000 +0000 @@ -38,17 +38,18 @@ void serialize (hb_serialize_context_t *c, const SrcLookup* src, Iterator glyph_val_iter_pairs, - const hb_map_t *layout_variation_idx_map) + const hb_hashmap_t> *layout_variation_idx_delta_map, + bool all_axes_pinned) { if (unlikely (!c->extend_min (u.format))) return; unsigned format = 2; ValueFormat new_format = src->get_value_format (); + if (all_axes_pinned) + new_format = new_format.drop_device_table_flags (); + if (glyph_val_iter_pairs) - { format = get_format (glyph_val_iter_pairs); - new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second)); - } u.format = format; switch (u.format) { @@ -56,13 +57,13 @@ src, glyph_val_iter_pairs, new_format, - layout_variation_idx_map); + layout_variation_idx_delta_map); return; case 2: u.format2.serialize (c, src, glyph_val_iter_pairs, new_format, - layout_variation_idx_map); + layout_variation_idx_delta_map); return; default:return; } @@ -71,8 +72,8 @@ template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); @@ -87,8 +88,9 @@ SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, - const hb_map_t *layout_variation_idx_map) -{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_map); } + const hb_hashmap_t> *layout_variation_idx_delta_map, + bool all_axes_pinned) +{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh 2023-07-05 07:11:54.000000000 +0000 @@ -59,6 +59,24 @@ unsigned int get_len () const { return hb_popcount ((unsigned int) *this); } unsigned int get_size () const { return get_len () * Value::static_size; } + hb_vector_t get_device_table_indices () const { + unsigned i = 0; + hb_vector_t result; + unsigned format = *this; + + if (format & xPlacement) i++; + if (format & yPlacement) i++; + if (format & xAdvance) i++; + if (format & yAdvance) i++; + + if (format & xPlaDevice) result.push (i++); + if (format & yPlaDevice) result.push (i++); + if (format & xAdvDevice) result.push (i++); + if (format & yAdvDevice) result.push (i++); + + return result; + } + bool apply_value (hb_ot_apply_context_t *c, const void *base, const Value *values, @@ -145,30 +163,50 @@ unsigned int new_format, const void *base, const Value *values, - const hb_map_t *layout_variation_idx_map) const + const hb_hashmap_t> *layout_variation_idx_delta_map) const { unsigned int format = *this; if (!format) return; - if (format & xPlacement) copy_value (c, new_format, xPlacement, *values++); - if (format & yPlacement) copy_value (c, new_format, yPlacement, *values++); - if (format & xAdvance) copy_value (c, new_format, xAdvance, *values++); - if (format & yAdvance) copy_value (c, new_format, yAdvance, *values++); - - if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); - if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); - if (format & xAdvDevice) copy_device (c, base, values++, layout_variation_idx_map); - if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map); + HBINT16 *x_placement = nullptr, *y_placement = nullptr, *x_adv = nullptr, *y_adv = nullptr; + if (format & xPlacement) x_placement = copy_value (c, new_format, xPlacement, *values++); + if (format & yPlacement) y_placement = copy_value (c, new_format, yPlacement, *values++); + 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 (format & xPlaDevice) + { + add_delta_to_value (x_placement, base, values, layout_variation_idx_delta_map); + copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xPlaDevice); + } + + if (format & yPlaDevice) + { + add_delta_to_value (y_placement, base, values, layout_variation_idx_delta_map); + copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yPlaDevice); + } + + if (format & xAdvDevice) + { + add_delta_to_value (x_adv, base, values, layout_variation_idx_delta_map); + copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xAdvDevice); + } + + if (format & yAdvDevice) + { + add_delta_to_value (y_adv, base, values, layout_variation_idx_delta_map); + copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yAdvDevice); + } } - void copy_value (hb_serialize_context_t *c, - unsigned int new_format, - Flags flag, - Value value) const + HBINT16* copy_value (hb_serialize_context_t *c, + unsigned int new_format, + Flags flag, + Value value) const { // Filter by new format. - if (!(new_format & flag)) return; - c->copy (value); + if (!(new_format & flag)) return nullptr; + return reinterpret_cast (c->copy (value)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c, @@ -183,31 +221,40 @@ if (format & yAdvance) i++; if (format & xPlaDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } if (format & ValueFormat::yPlaDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } if (format & ValueFormat::xAdvDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } if (format & ValueFormat::yAdvDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } } + unsigned drop_device_table_flags () const + { + unsigned format = *this; + for (unsigned flag = xPlaDevice; flag <= yAdvDevice; flag = flag << 1) + format = format & ~flag; + + return format; + } + private: bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const { @@ -236,9 +283,27 @@ return *static_cast *> (value); } + void add_delta_to_value (HBINT16 *value, + const void *base, + const Value *src_value, + const hb_hashmap_t> *layout_variation_idx_delta_map) const + { + if (!value) return; + unsigned varidx = (base + get_device (src_value)).get_variation_index (); + hb_pair_t *varidx_delta; + if (!layout_variation_idx_delta_map->has (varidx, &varidx_delta)) return; + + *value += hb_second (*varidx_delta); + } + bool copy_device (hb_serialize_context_t *c, const void *base, - const Value *src_value, const hb_map_t *layout_variation_idx_map) const + const Value *src_value, + const hb_hashmap_t> *layout_variation_idx_delta_map, + unsigned int new_format, Flags flag) const { + // Filter by new format. + if (!(new_format & flag)) return true; + Value *dst_value = c->copy (*src_value); if (!dst_value) return false; @@ -246,7 +311,7 @@ *dst_value = 0; c->push (); - if ((base + get_device (src_value)).copy (c, layout_variation_idx_map)) + if ((base + get_device (src_value)).copy (c, layout_variation_idx_delta_map)) { c->add_link (*dst_value, c->pop_pack ()); return true; @@ -306,7 +371,7 @@ for (unsigned int i = 0; i < count; i++) { if (!sanitize_value_devices (c, base, values)) return_trace (false); - values += stride; + values = &StructAtOffset (values, stride); } return_trace (true); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS.hh 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -#ifndef OT_LAYOUT_GPOS_HH -#define OT_LAYOUT_GPOS_HH - -#include "../../hb-ot-layout-common.hh" -#include "../../hb-ot-layout-gsubgpos.hh" -#include "GPOS/Common.hh" -#include "GPOS/PosLookup.hh" - -namespace OT { -namespace Layout { - -static void -propagate_attachment_offsets (hb_glyph_position_t *pos, - unsigned int len, - unsigned int i, - hb_direction_t direction, - unsigned nesting_level = HB_MAX_NESTING_LEVEL); - -/* - * GPOS -- Glyph Positioning - * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos - */ - -struct GPOS : GSUBGPOS -{ - static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS; - - using Lookup = GPOS_impl::PosLookup; - - const GPOS_impl::PosLookup& get_lookup (unsigned int i) const - { return static_cast (GSUBGPOS::get_lookup (i)); } - - static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); - static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer); - - bool subset (hb_subset_context_t *c) const - { - hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features); - return GSUBGPOS::subset (&l); - } - - bool sanitize (hb_sanitize_context_t *c) const - { return GSUBGPOS::sanitize (c); } - - HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, - hb_face_t *face) const; - - void collect_variation_indices (hb_collect_variation_indices_context_t *c) const - { - for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++) - { - if (!c->gpos_lookups->has (i)) continue; - const GPOS_impl::PosLookup &l = get_lookup (i); - l.dispatch (c); - } - } - - void closure_lookups (hb_face_t *face, - const hb_set_t *glyphs, - hb_set_t *lookup_indexes /* IN/OUT */) const - { GSUBGPOS::closure_lookups (face, glyphs, lookup_indexes); } - - typedef GSUBGPOS::accelerator_t accelerator_t; -}; - - -static void -propagate_attachment_offsets (hb_glyph_position_t *pos, - unsigned int len, - unsigned int i, - hb_direction_t direction, - unsigned nesting_level) -{ - /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate - * offset of glyph they are attached to. */ - int chain = pos[i].attach_chain(), type = pos[i].attach_type(); - if (likely (!chain)) - return; - - pos[i].attach_chain() = 0; - - unsigned int j = (int) i + chain; - - if (unlikely (j >= len)) - return; - - if (unlikely (!nesting_level)) - return; - - propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); - - assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE)); - - if (type & GPOS_impl::ATTACH_TYPE_CURSIVE) - { - if (HB_DIRECTION_IS_HORIZONTAL (direction)) - pos[i].y_offset += pos[j].y_offset; - else - pos[i].x_offset += pos[j].x_offset; - } - else /*if (type & GPOS_impl::ATTACH_TYPE_MARK)*/ - { - pos[i].x_offset += pos[j].x_offset; - pos[i].y_offset += pos[j].y_offset; - - assert (j < i); - if (HB_DIRECTION_IS_FORWARD (direction)) - for (unsigned int k = j; k < i; k++) { - pos[i].x_offset -= pos[k].x_advance; - pos[i].y_offset -= pos[k].y_advance; - } - else - for (unsigned int k = j + 1; k < i + 1; k++) { - pos[i].x_offset += pos[k].x_advance; - pos[i].y_offset += pos[k].y_advance; - } - } -} - -void -GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) -{ - unsigned int count = buffer->len; - for (unsigned int i = 0; i < count; i++) - buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0; -} - -void -GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED) -{ - //_hb_buffer_assert_gsubgpos_vars (buffer); -} - -void -GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) -{ - _hb_buffer_assert_gsubgpos_vars (buffer); - - unsigned int len; - hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); - hb_direction_t direction = buffer->props.direction; - - /* Handle attachments */ - if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) - for (unsigned i = 0; i < len; i++) - propagate_attachment_offsets (pos, len, i, direction); - - if (unlikely (font->slant)) - { - 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); - } -} - -} - -struct GPOS_accelerator_t : Layout::GPOS::accelerator_t { - GPOS_accelerator_t (hb_face_t *face) : Layout::GPOS::accelerator_t (face) {} -}; - -} - -#endif /* OT_LAYOUT_GPOS_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh 2023-07-05 07:11:54.000000000 +0000 @@ -5,12 +5,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template struct AlternateSet { protected: - Array16Of + Array16Of alternates; /* Array of alternate GlyphIDs--in * arbitrary order */ public: @@ -56,8 +57,23 @@ if (unlikely (alt_index > count || alt_index == 0)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %u (alternate substitution)", + c->buffer->idx); + } + c->replace_glyph (alternates[alt_index - 1]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %u (alternate substitution)", + c->buffer->idx - 1u); + } + return_trace (true); } @@ -68,7 +84,7 @@ { if (alternates.len && alternate_count) { - + alternates.sub_array (start_offset, alternate_count) + + alternates.as_array ().sub_array (start_offset, alternate_count) | hb_sink (hb_array (alternate_glyphs, *alternate_count)) ; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct AlternateSubstFormat1 +template +struct AlternateSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To + Array16Of>> alternateSet; /* Array of AlternateSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, alternateSet); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -39,9 +40,8 @@ | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const AlternateSet &_) { _.closure (c); }) + | hb_apply ([c] (const AlternateSet &_) { _.closure (c); }) ; - } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -52,7 +52,7 @@ + hb_zip (this+coverage, alternateSet) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); }) ; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,28 +6,36 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct AlternateSubst { protected: union { - HBUINT16 format; /* Format identifier */ - AlternateSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + AlternateSubstFormat1_2 format1; +#ifndef HB_NO_BEYOND_64K + AlternateSubstFormat1_2 format2; +#endif } u; public: template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using + * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t glyphs, hb_array_t alternate_len_list, @@ -42,6 +50,9 @@ default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ChainContextSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ChainContextSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ChainContextSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ChainContextSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ChainContextSubst : ChainContext {}; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { typedef hb_pair_t hb_codepoint_pair_t; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ContextSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ContextSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ContextSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ContextSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ContextSubst : Context {}; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ExtensionSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ExtensionSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ExtensionSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ExtensionSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ExtensionSubst : Extension { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/GSUB.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/GSUB.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/GSUB.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/GSUB.hh 2023-07-05 07:11:54.000000000 +0000 @@ -1,16 +1,15 @@ #ifndef OT_LAYOUT_GSUB_GSUB_HH #define OT_LAYOUT_GSUB_GSUB_HH -// TODO(garretrieger): move to new layout. #include "../../../hb-ot-layout-gsubgpos.hh" #include "Common.hh" #include "SubstLookup.hh" -using OT::Layout::GSUB::SubstLookup; - namespace OT { + +using Layout::GSUB_impl::SubstLookup; + namespace Layout { -namespace GSUB { /* * GSUB -- Glyph Substitution @@ -28,12 +27,15 @@ bool subset (hb_subset_context_t *c) const { - hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features); + hb_subset_layout_context_t l (c, tableTag); return GSUBGPOS::subset (&l); } bool sanitize (hb_sanitize_context_t *c) const - { return GSUBGPOS::sanitize (c); } + { + TRACE_SANITIZE (this); + return_trace (GSUBGPOS::sanitize (c)); + } HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; @@ -48,10 +50,9 @@ } -} -struct GSUB_accelerator_t : Layout::GSUB::GSUB::accelerator_t { - GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::GSUB::accelerator_t (face) {} +struct GSUB_accelerator_t : Layout::GSUB::accelerator_t { + GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::accelerator_t (face) {} }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh 2023-07-05 07:11:54.000000000 +0000 @@ -5,18 +5,20 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template struct Ligature { protected: - HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */ - HeadlessArrayOf + typename Types::HBGlyphID + ligGlyph; /* GlyphID of ligature to substitute */ + HeadlessArrayOf component; /* Array of component GlyphIDs--start * with the second component--ordered * in writing direction */ public: - DEFINE_SIZE_ARRAY (4, component); + DEFINE_SIZE_ARRAY (Types::size + 2, component); bool sanitize (hb_sanitize_context_t *c) const { @@ -62,7 +64,24 @@ * as a "ligated" substitution. */ if (unlikely (count == 1)) { + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %u (ligature substitution)", + c->buffer->idx); + } + c->replace_glyph (ligGlyph); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %u (ligature substitution)", + c->buffer->idx - 1u); + } + return_trace (true); } @@ -83,6 +102,31 @@ return_trace (false); } + unsigned pos = 0; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + unsigned delta = c->buffer->sync_so_far (); + + pos = c->buffer->idx; + + char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; + char *p = buf; + + match_end += delta; + for (unsigned i = 0; i < count; i++) + { + match_positions[i] += delta; + if (i) + *p++ = ','; + snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]); + p += strlen(p); + } + + c->buffer->message (c->font, + "ligating glyphs at %s", + buf); + } + ligate_input (c, count, match_positions, @@ -90,6 +134,14 @@ ligGlyph, total_component_count); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "ligated glyph at %u", + pos); + } + return_trace (true); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,12 +6,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template struct LigatureSet { protected: - Array16OfOffset16To + Array16OfOffset16To> ligature; /* Array LigatureSet tables * ordered by preference */ public: @@ -28,7 +29,7 @@ return + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); }) + | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); }) | hb_any ; } @@ -37,7 +38,7 @@ { + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_apply ([c] (const Ligature &_) { _.closure (c); }) + | hb_apply ([c] (const Ligature &_) { _.closure (c); }) ; } @@ -45,7 +46,7 @@ { + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); }) ; } @@ -54,7 +55,7 @@ return + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_map ([c] (const Ligature &_) { return _.would_apply (c); }) + | hb_map ([c] (const Ligature &_) { return _.would_apply (c); }) | hb_any ; } @@ -65,7 +66,7 @@ unsigned int num_ligs = ligature.len; for (unsigned int i = 0; i < num_ligs; i++) { - const Ligature &lig = this+ligature[i]; + const auto &lig = this+ligature[i]; if (lig.apply (c)) return_trace (true); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct LigatureSubstFormat1 +template +struct LigatureSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To + Array16Of>> ligatureSet; /* Array LigatureSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, ligatureSet); + DEFINE_SIZE_ARRAY (4 + Types::size, ligatureSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -33,7 +34,7 @@ + hb_zip (this+coverage, ligatureSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([this, glyphs] (const Offset16To &_) + | hb_map ([this, glyphs] (const typename Types::template OffsetTo> &_) { return (this+_).intersects (glyphs); }) | hb_any ; @@ -48,7 +49,7 @@ | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const LigatureSet &_) { _.closure (c); }) + | hb_apply ([c] (const LigatureSet &_) { _.closure (c); }) ; } @@ -62,7 +63,7 @@ + hb_zip (this+coverage, ligatureSet) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); }) ; } @@ -73,7 +74,7 @@ unsigned int index = (this+coverage).get_coverage (c->glyphs[0]); if (likely (index == NOT_COVERED)) return false; - const LigatureSet &lig_set = this+ligatureSet[index]; + const auto &lig_set = this+ligatureSet[index]; return lig_set.would_apply (c); } @@ -84,7 +85,7 @@ unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const LigatureSet &lig_set = this+ligatureSet[index]; + const auto &lig_set = this+ligatureSet[index]; return_trace (lig_set.apply (c)); } @@ -128,7 +129,7 @@ hb_set_t new_coverage; + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this))) | hb_filter (glyphset, hb_first) - | hb_filter ([&] (const LigatureSet& _) { + | hb_filter ([&] (const LigatureSet& _) { return _.intersects (&glyphset); }, hb_second) | hb_map (hb_first) diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,28 +6,37 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct LigatureSubst { protected: union { - HBUINT16 format; /* Format identifier */ - LigatureSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + LigatureSubstFormat1_2 format1; +#ifndef HB_NO_BEYOND_64K + LigatureSubstFormat1_2 format2; +#endif } u; public: template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is only used by small GIDs, and not updated to 24bit GIDs. Should + * be done by using iterators. While at it perhaps using iterator of arrays of hb_codepoint_t + * instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t first_glyphs, hb_array_t ligature_per_first_glyph_count_list, @@ -49,6 +58,9 @@ default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct MultipleSubstFormat1 +template +struct MultipleSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To + Array16Of>> sequence; /* Array of Sequence tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, sequence); + DEFINE_SIZE_ARRAY (4 + Types::size, sequence); bool sanitize (hb_sanitize_context_t *c) const { @@ -39,7 +40,7 @@ | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const Sequence &_) { _.closure (c); }) + | hb_apply ([c] (const Sequence &_) { _.closure (c); }) ; } @@ -51,7 +52,7 @@ + hb_zip (this+coverage, sequence) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); }) ; } @@ -70,22 +71,31 @@ return_trace ((this+sequence[index]).apply (c)); } + template bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t glyphs, - hb_array_t substitute_len_list, - hb_array_t substitute_glyphs_list) + Iterator it) { TRACE_SERIALIZE (this); + auto sequences = + + it + | hb_map (hb_second) + ; + auto glyphs = + + it + | hb_map_retains_sorting (hb_first) + ; if (unlikely (!c->extend_min (this))) return_trace (false); - if (unlikely (!sequence.serialize (c, glyphs.length))) return_trace (false); - for (unsigned int i = 0; i < glyphs.length; i++) + + if (unlikely (!sequence.serialize (c, sequences.length))) return_trace (false); + + for (auto& pair : hb_zip (sequences, sequence)) { - unsigned int substitute_len = substitute_len_list[i]; - if (unlikely (!sequence[i] - .serialize_serialize (c, substitute_glyphs_list.sub_array (0, substitute_len)))) + if (unlikely (!pair.second + .serialize_serialize (c, pair.first))) return_trace (false); - substitute_glyphs_list += substitute_len; } + return_trace (coverage.serialize_serialize (c, glyphs)); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,14 +6,17 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct MultipleSubst { protected: union { - HBUINT16 format; /* Format identifier */ - MultipleSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + MultipleSubstFormat1_2 format1; +#ifndef HB_NO_BEYOND_64K + MultipleSubstFormat1_2 format2; +#endif } u; public: @@ -21,28 +24,34 @@ template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + template bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t glyphs, - hb_array_t substitute_len_list, - hb_array_t substitute_glyphs_list) + Iterator it) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 1; u.format = format; switch (u.format) { - case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, substitute_glyphs_list)); + case 1: return_trace (u.format1.serialize (c, it)); default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -5,7 +5,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ReverseChainSingleSubstFormat1 { @@ -33,10 +33,10 @@ TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); - const Array16OfOffset16To &lookahead = StructAfter> (backtrack); + const auto &lookahead = StructAfter (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); - const Array16Of &substitute = StructAfter> (lookahead); + const auto &substitute = StructAfter (lookahead); return_trace (substitute.sanitize (c)); } @@ -45,7 +45,7 @@ if (!(this+coverage).intersects (glyphs)) return false; - const Array16OfOffset16To &lookahead = StructAfter> (backtrack); + const auto &lookahead = StructAfter (backtrack); unsigned int count; @@ -69,8 +69,8 @@ { if (!intersects (c->glyphs)) return; - const Array16OfOffset16To &lookahead = StructAfter> (backtrack); - const Array16Of &substitute = StructAfter> (lookahead); + const auto &lookahead = StructAfter (backtrack); + const auto &substitute = StructAfter (lookahead); + hb_zip (this+coverage, substitute) | hb_filter (c->parent_active_glyphs (), hb_first) @@ -91,12 +91,12 @@ for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return; - const Array16OfOffset16To &lookahead = StructAfter> (backtrack); + const auto &lookahead = StructAfter (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return; - const Array16Of &substitute = StructAfter> (lookahead); + const auto &substitute = StructAfter (lookahead); count = substitute.len; c->output->add_array (substitute.arrayZ, substitute.len); } @@ -115,8 +115,8 @@ unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const Array16OfOffset16To &lookahead = StructAfter> (backtrack); - const Array16Of &substitute = StructAfter> (lookahead); + const auto &lookahead = StructAfter (backtrack); + const auto &substitute = StructAfter (lookahead); if (unlikely (index >= substitute.len)) return_trace (false); @@ -131,7 +131,23 @@ c->buffer->idx + 1, &end_index)) { c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replacing glyph at %u (reverse chaining substitution)", + c->buffer->idx); + } + c->replace_glyph_inplace (substitute[index]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %u (reverse chaining substitution)", + c->buffer->idx); + } + /* Note: We DON'T decrease buffer->idx. The main loop does it * for us. This is useful for preventing surprises if someone * calls us through a Context lookup. */ @@ -206,8 +222,8 @@ const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - const Array16OfOffset16To &lookahead = StructAfter> (backtrack); - const Array16Of &substitute = StructAfter> (lookahead); + const auto &lookahead = StructAfter (backtrack); + const auto &substitute = StructAfter (lookahead); auto it = + hb_zip (this+coverage, substitute) diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ReverseChainSingleSubst { @@ -20,8 +20,8 @@ template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); default:return_trace (c->default_return_value ()); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh 2023-07-05 07:11:54.000000000 +0000 @@ -5,12 +5,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template struct Sequence { protected: - Array16Of + Array16Of substitute; /* String of GlyphIDs to substitute */ public: DEFINE_SIZE_ARRAY (2, substitute); @@ -39,17 +40,58 @@ * as a "multiplied" substitution. */ if (unlikely (count == 1)) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %u (multiple substitution)", + c->buffer->idx); + } + c->replace_glyph (substitute.arrayZ[0]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %u (multiple subtitution)", + c->buffer->idx - 1u); + } + return_trace (true); } /* Spec disallows this, but Uniscribe allows it. * https://github.com/harfbuzz/harfbuzz/issues/253 */ else if (unlikely (count == 0)) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "deleting glyph at %u (multiple substitution)", + c->buffer->idx); + } + c->buffer->delete_glyph (); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "deleted glyph at %u (multiple substitution)", + c->buffer->idx); + } + return_trace (true); } + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "multiplying glyph at %u", + c->buffer->idx); + } + unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur()); @@ -64,6 +106,26 @@ } c->buffer->skip_glyph (); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + + char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; + char *p = buf; + + for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) + { + if (buf < p) + *p++ = ','; + snprintf (p, sizeof(buf) - (p - buf), "%u", i); + p += strlen(p); + } + + c->buffer->message (c->font, + "multiplied glyphs at %s", + buf); + } + return_trace (true); } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh 2023-07-05 07:11:54.000000000 +0000 @@ -5,20 +5,22 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct SingleSubstFormat1 +template +struct SingleSubstFormat1_3 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To + typename Types::template OffsetTo coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - HBUINT16 deltaGlyphID; /* Add to original GlyphID to get + typename Types::HBUINT + deltaGlyphID; /* Add to original GlyphID to get * substitute GlyphID, modulo 0x10000 */ public: - DEFINE_SIZE_STATIC (6); + DEFINE_SIZE_STATIC (2 + 2 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -26,6 +28,9 @@ return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); } + hb_codepoint_t get_mask () const + { return (1 << (8 * Types::size)) - 1; } + bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } @@ -34,14 +39,33 @@ void closure (hb_closure_context_t *c) const { - unsigned d = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); - + hb_iter (this+coverage) - | hb_filter (c->parent_active_glyphs ()) - | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + /* Help fuzzer avoid this function as much. */ + unsigned pop = (this+coverage).get_population (); + if (pop >= mask) + return; + + hb_set_t intersection; + (this+coverage).intersect_set (c->parent_active_glyphs (), intersection); + + /* In degenerate fuzzer-found fonts, but not real fonts, + * this table can keep adding new glyphs in each round of closure. + * Refuse to close-over, if it maps glyph range to overlapping range. */ + hb_codepoint_t min_before = intersection.get_min (); + hb_codepoint_t max_before = intersection.get_max (); + hb_codepoint_t min_after = (min_before + d) & mask; + hb_codepoint_t max_after = (max_before + d) & mask; + if (intersection.get_population () == max_before - min_before + 1 && + ((min_before <= min_after && min_after <= max_before) || + (min_before <= max_after && max_after <= max_before))) + return; + + + hb_iter (intersection) + | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) ; - } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -49,9 +73,11 @@ void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; - unsigned d = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + hb_iter (this+coverage) - | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) ; } @@ -68,11 +94,28 @@ unsigned int index = (this+coverage).get_coverage (glyph_id); if (likely (index == NOT_COVERED)) return_trace (false); - /* According to the Adobe Annotated OpenType Suite, result is always - * limited to 16bit. */ - glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + glyph_id = (glyph_id + d) & mask; + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %u (single substitution)", + c->buffer->idx); + } + c->replace_glyph (glyph_id); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %u (single substitution)", + c->buffer->idx - 1u); + } + return_trace (true); } @@ -95,14 +138,17 @@ const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - hb_codepoint_t delta = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + hb_set_t intersection; + (this+coverage).intersect_set (glyphset, intersection); auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) - | hb_map_retains_sorting ([&] (hb_codepoint_t g) { + + hb_iter (intersection) + | hb_map_retains_sorting ([d, mask] (hb_codepoint_t g) { return hb_codepoint_pair_t (g, - (g + delta) & 0xFFFF); }) + (g + d) & mask); }) | hb_filter (glyphset, hb_second) | hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh 2023-07-05 07:11:54.000000000 +0000 @@ -5,21 +5,22 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct SingleSubstFormat2 +template +struct SingleSubstFormat2_4 { protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To + typename Types::template OffsetTo coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16Of + Array16Of substitute; /* Array of substitute * GlyphIDs--ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, substitute); + DEFINE_SIZE_ARRAY (4 + Types::size, substitute); bool sanitize (hb_sanitize_context_t *c) const { @@ -35,12 +36,27 @@ void closure (hb_closure_context_t *c) const { - + hb_zip (this+coverage, substitute) - | hb_filter (c->parent_active_glyphs (), hb_first) + auto &cov = this+coverage; + auto &glyph_set = c->parent_active_glyphs (); + + if (substitute.len > glyph_set.get_population () * 4) + { + for (auto g : glyph_set) + { + unsigned i = cov.get_coverage (g); + if (i == NOT_COVERED || i >= substitute.len) + continue; + c->output->add (substitute.arrayZ[i]); + } + + return; + } + + + hb_zip (cov, substitute) + | hb_filter (glyph_set, hb_first) | hb_map (hb_second) | hb_sink (c->output) ; - } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -67,8 +83,23 @@ if (unlikely (index >= substitute.len)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %u (single substitution)", + c->buffer->idx); + } + c->replace_glyph (substitute[index]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %u (single substitution)", + c->buffer->idx - 1u); + } + return_trace (true); } @@ -103,7 +134,7 @@ + hb_zip (this+coverage, substitute) | hb_filter (glyphset, hb_first) | hb_filter (glyphset, hb_second) - | hb_map_retains_sorting ([&] (hb_pair_t p) -> hb_codepoint_pair_t + | hb_map_retains_sorting ([&] (hb_pair_t p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) ; diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh 2023-07-05 07:11:54.000000000 +0000 @@ -7,15 +7,19 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SingleSubst { protected: union { - HBUINT16 format; /* Format identifier */ - SingleSubstFormat1 format1; - SingleSubstFormat2 format2; + HBUINT16 format; /* Format identifier */ + SingleSubstFormat1_3 format1; + SingleSubstFormat2_4 format2; +#ifndef HB_NO_BEYOND_64K + SingleSubstFormat1_3 format3; + SingleSubstFormat2_4 format4; +#endif } u; public: @@ -23,11 +27,15 @@ template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } @@ -45,11 +53,24 @@ if (glyphs) { format = 1; + hb_codepoint_t mask = 0xFFFFu; + +#ifndef HB_NO_BEYOND_64K + if (+ glyphs + | hb_map_retains_sorting (hb_first) + | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; })) + { + format += 2; + mask = 0xFFFFFFu; + } +#endif + auto get_delta = [=] (hb_codepoint_pair_t _) - { return (unsigned) (_.second - _.first) & 0xFFFF; }; + { return (unsigned) (_.second - _.first) & mask; }; delta = get_delta (*glyphs); - if (!hb_all (++(+glyphs), delta, get_delta)) format = 2; + if (!hb_all (++(+glyphs), delta, get_delta)) format += 1; } + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, @@ -57,6 +78,13 @@ | hb_map_retains_sorting (hb_first), delta)); case 2: return_trace (u.format2.serialize (c, glyphs)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.serialize (c, + + glyphs + | hb_map_retains_sorting (hb_first), + delta)); + case 4: return_trace (u.format4.serialize (c, glyphs)); +#endif default:return_trace (false); } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookup.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookup.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookup.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookup.hh 2023-07-05 07:11:54.000000000 +0000 @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookup : Lookup { @@ -25,7 +25,7 @@ { unsigned int type = get_type (); if (unlikely (type == SubTable::Extension)) - return reinterpret_cast (get_subtable (0)).is_reverse (); + return get_subtable (0).u.extension.is_reverse (); return lookup_type_is_reverse (type); } @@ -98,10 +98,15 @@ return dispatch (c); } + template bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, - hb_sorted_array_t glyphs, - hb_array_t substitutes) + Glyphs glyphs, + Substitutes substitutes) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false); @@ -114,19 +119,16 @@ return_trace (false); } - bool serialize_multiple (hb_serialize_context_t *c, - uint32_t lookup_props, - hb_sorted_array_t glyphs, - hb_array_t substitute_len_list, - hb_array_t substitute_glyphs_list) + template + bool serialize (hb_serialize_context_t *c, + uint32_t lookup_props, + Iterator it) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false); if (c->push ()->u.multiple. - serialize (c, - glyphs, - substitute_len_list, - substitute_glyphs_list)) + serialize (c, it)) { c->add_link (get_subtables ()[0], c->pop_pack ()); return_trace (true); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookupSubTable.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookupSubTable.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookupSubTable.hh 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SubstLookupSubTable.hh 2023-07-05 07:11:54.000000000 +0000 @@ -13,7 +13,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookupSubTable { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_TYPES_HH +#define OT_LAYOUT_TYPES_HH + +namespace OT { +namespace Layout { + +struct SmallTypes { + static constexpr unsigned size = 2; + using large_int = uint32_t; + using HBUINT = HBUINT16; + using HBGlyphID = HBGlyphID16; + using Offset = Offset16; + template + using OffsetTo = OT::Offset16To; + template + using ArrayOf = OT::Array16Of; + template + using SortedArrayOf = OT::SortedArray16Of; +}; + +struct MediumTypes { + static constexpr unsigned size = 3; + using large_int = uint64_t; + using HBUINT = HBUINT24; + using HBGlyphID = HBGlyphID24; + using Offset = Offset24; + template + using OffsetTo = OT::Offset24To; + template + using ArrayOf = OT::Array24Of; + template + using SortedArrayOf = OT::SortedArray24Of; +}; + +} +} + +#endif /* OT_LAYOUT_TYPES_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,589 @@ +/* + * Copyright © 2011,2012 Google, 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef OT_NAME_NAME_HH +#define OT_NAME_NAME_HH + +#include "../../hb-open-type.hh" +#include "../../hb-ot-name-language.hh" +#include "../../hb-aat-layout.hh" +#include "../../hb-utf.hh" + + +namespace OT { + +template +inline unsigned int +hb_ot_name_convert_utf (hb_bytes_t bytes, + unsigned int *text_size /* IN/OUT */, + typename out_utf_t::codepoint_t *text /* OUT */) +{ + unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t); + const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ; + const typename in_utf_t::codepoint_t *src_end = src + src_len; + + typename out_utf_t::codepoint_t *dst = text; + + hb_codepoint_t unicode; + const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; + + if (text_size && *text_size) + { + (*text_size)--; /* Save room for NUL-termination. */ + const typename out_utf_t::codepoint_t *dst_end = text + *text_size; + + while (src < src_end && dst < dst_end) + { + const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement); + typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode); + if (dst_next == dst) + break; /* Out-of-room. */ + + dst = dst_next; + src = src_next; + } + + *text_size = dst - text; + *dst = 0; /* NUL-terminate. */ + } + + /* Accumulate length of rest. */ + unsigned int dst_len = dst - text; + while (src < src_end) + { + src = in_utf_t::next (src, src_end, &unicode, replacement); + dst_len += out_utf_t::encode_len (unicode); + } + return dst_len; +} + +#define entry_score var.u16[0] +#define entry_index var.u16[1] + + +/* + * name -- Naming + * https://docs.microsoft.com/en-us/typography/opentype/spec/name + */ +#define HB_OT_TAG_name HB_TAG('n','a','m','e') + +#define UNSUPPORTED 42 + +struct NameRecord +{ + hb_language_t language (hb_face_t *face) const + { +#ifndef HB_NO_OT_NAME_LANGUAGE + unsigned int p = platformID; + unsigned int l = languageID; + + if (p == 3) + return _hb_ot_name_language_for_ms_code (l); + + if (p == 1) + return _hb_ot_name_language_for_mac_code (l); + +#ifndef HB_NO_OT_NAME_LANGUAGE_AAT + if (p == 0) + return face->table.ltag->get_language (l); +#endif + +#endif + return HB_LANGUAGE_INVALID; + } + + uint16_t score () const + { + /* Same order as in cmap::find_best_subtable(). */ + unsigned int p = platformID; + unsigned int e = encodingID; + + /* 32-bit. */ + if (p == 3 && e == 10) return 0; + if (p == 0 && e == 6) return 1; + if (p == 0 && e == 4) return 2; + + /* 16-bit. */ + if (p == 3 && e == 1) return 3; + if (p == 0 && e == 3) return 4; + if (p == 0 && e == 2) return 5; + if (p == 0 && e == 1) return 6; + if (p == 0 && e == 0) return 7; + + /* Symbol. */ + if (p == 3 && e == 0) return 8; + + /* We treat all Mac Latin names as ASCII only. */ + if (p == 1 && e == 0) return 10; /* 10 is magic number :| */ + + return UNSUPPORTED; + } + + NameRecord* copy (hb_serialize_context_t *c, const void *base +#ifdef HB_EXPERIMENTAL_API + , const hb_hashmap_t *name_table_overrides +#endif + ) const + { + TRACE_SERIALIZE (this); + HB_UNUSED auto snap = c->snapshot (); + auto *out = c->embed (this); + if (unlikely (!out)) return_trace (nullptr); +#ifdef HB_EXPERIMENTAL_API + hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID); + hb_bytes_t* name_bytes; + + if (name_table_overrides->has (record_ids, &name_bytes)) { + hb_bytes_t encoded_bytes = *name_bytes; + char *name_str_utf16_be = nullptr; + + if (platformID != 1) + { + unsigned text_size = hb_ot_name_convert_utf (*name_bytes, nullptr, nullptr); + + text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf() + unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; + name_str_utf16_be = (char *) hb_calloc (byte_len, 1); + if (!name_str_utf16_be) + { + c->revert (snap); + return_trace (nullptr); + } + hb_ot_name_convert_utf (*name_bytes, &text_size, + (hb_utf16_be_t::codepoint_t *) name_str_utf16_be); + + unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; + if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) { + c->revert (snap); + hb_free (name_str_utf16_be); + return_trace (nullptr); + } + + encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len); + } + else + { + // mac platform, copy the UTF-8 string(all ascii characters) as is + if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) { + c->revert (snap); + return_trace (nullptr); + } + } + + out->offset = 0; + c->push (); + encoded_bytes.copy (c); + c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0); + hb_free (name_str_utf16_be); + } + else +#endif + { + out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length); + } + return_trace (out); + } + + bool isUnicode () const + { + unsigned int p = platformID; + unsigned int e = encodingID; + + return (p == 0 || + (p == 3 && (e == 0 || e == 1 || e == 10))); + } + + static int cmp (const void *pa, const void *pb) + { + const NameRecord *a = (const NameRecord *)pa; + const NameRecord *b = (const NameRecord *)pb; + + if (a->platformID != b->platformID) + return a->platformID - b->platformID; + + if (a->encodingID != b->encodingID) + return a->encodingID - b->encodingID; + + if (a->languageID != b->languageID) + return a->languageID - b->languageID; + + if (a->nameID != b->nameID) + return a->nameID - b->nameID; + + if (a->length != b->length) + return a->length - b->length; + + return 0; + } + + bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && offset.sanitize (c, base, length)); + } + + HBUINT16 platformID; /* Platform ID. */ + HBUINT16 encodingID; /* Platform-specific encoding ID. */ + HBUINT16 languageID; /* Language ID. */ + HBUINT16 nameID; /* Name ID. */ + HBUINT16 length; /* String length (in bytes). */ + NNOffset16To> + offset; /* String offset from start of storage area (in bytes). */ + public: + DEFINE_SIZE_STATIC (12); +}; + +static int +_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact) +{ + const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; + const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; + + /* Compare by name_id, then language. */ + + if (a->name_id != b->name_id) + return a->name_id - b->name_id; + + if (a->language == b->language) return 0; + if (!a->language) return -1; + if (!b->language) return +1; + + const char *astr = hb_language_to_string (a->language); + const char *bstr = hb_language_to_string (b->language); + + signed c = strcmp (astr, bstr); + + // 'a' is the user request, and 'b' is string in the font. + // If eg. user asks for "en-us" and font has "en", approve. + if (!exact && c && + hb_language_matches (b->language, a->language)) + return 0; + + return c; +} + +static int +_hb_ot_name_entry_cmp (const void *pa, const void *pb) +{ + /* Compare by name_id, then language, then score, then index. */ + + int v = _hb_ot_name_entry_cmp_key (pa, pb, true); + if (v) + return v; + + const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; + const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; + + if (a->entry_score != b->entry_score) + return a->entry_score - b->entry_score; + + if (a->entry_index != b->entry_index) + return a->entry_index - b->entry_index; + + return 0; +} + +struct name +{ + static constexpr hb_tag_t tableTag = HB_OT_TAG_name; + + unsigned int get_size () const + { return min_size + count * nameRecordZ.item_size; } + + template + bool serialize (hb_serialize_context_t *c, + Iterator it, + const void *src_string_pool +#ifdef HB_EXPERIMENTAL_API + , const hb_vector_t& insert_name_records + , const hb_hashmap_t *name_table_overrides +#endif + ) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + + unsigned total_count = it.len () +#ifdef HB_EXPERIMENTAL_API + + insert_name_records.length +#endif + ; + this->format = 0; + if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return false; + + NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size); + if (unlikely (!name_records)) return_trace (false); + + hb_array_t records (name_records, total_count); + + for (const NameRecord& record : it) + { + hb_memcpy (name_records, &record, NameRecord::static_size); + name_records++; + } + +#ifdef HB_EXPERIMENTAL_API + for (unsigned i = 0; i < insert_name_records.length; i++) + { + const hb_ot_name_record_ids_t& ids = insert_name_records[i]; + NameRecord record; + record.platformID = ids.platform_id; + record.encodingID = ids.encoding_id; + record.languageID = ids.language_id; + record.nameID = ids.name_id; + record.length = 0; // handled in NameRecord copy() + record.offset = 0; + memcpy (name_records, &record, NameRecord::static_size); + name_records++; + } +#endif + + records.qsort (); + + c->copy_all (records, + src_string_pool +#ifdef HB_EXPERIMENTAL_API + , name_table_overrides +#endif + ); + hb_free (records.arrayZ); + + + if (unlikely (c->ran_out_of_room ())) return_trace (false); + + this->stringOffset = c->length (); + + return_trace (true); + } + + 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); + +#ifdef HB_EXPERIMENTAL_API + const hb_hashmap_t *name_table_overrides = + &c->plan->name_table_overrides; +#endif + + auto it = + + nameRecordZ.as_array (count) + | hb_filter (c->plan->name_ids, &NameRecord::nameID) + | hb_filter (c->plan->name_languages, &NameRecord::languageID) + | hb_filter ([&] (const NameRecord& namerecord) { + return + (c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY) + || namerecord.isUnicode (); + }) +#ifdef HB_EXPERIMENTAL_API + | hb_filter ([&] (const NameRecord& namerecord) { + if (name_table_overrides->is_empty ()) + return true; + hb_ot_name_record_ids_t rec_ids (namerecord.platformID, + namerecord.encodingID, + namerecord.languageID, + namerecord.nameID); + + hb_bytes_t *p; + if (name_table_overrides->has (rec_ids, &p) && + (*p).length == 0) + return false; + return true; + }) +#endif + ; + +#ifdef HB_EXPERIMENTAL_API + hb_hashmap_t retained_name_record_ids; + for (const NameRecord& rec : it) + { + hb_ot_name_record_ids_t rec_ids (rec.platformID, + rec.encodingID, + rec.languageID, + rec.nameID); + retained_name_record_ids.set (rec_ids, 1); + } + + hb_vector_t insert_name_records; + if (!name_table_overrides->is_empty ()) + { + if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population (), true))) + return_trace (false); + for (const auto& record_ids : name_table_overrides->keys ()) + { + if (name_table_overrides->get (record_ids).length == 0) + continue; + if (retained_name_record_ids.has (record_ids)) + continue; + insert_name_records.push (record_ids); + } + } +#endif + + return (name_prime->serialize (c->serializer, it, + std::addressof (this + stringOffset) +#ifdef HB_EXPERIMENTAL_API + , insert_name_records + , name_table_overrides +#endif + )); + } + + bool sanitize_records (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + const void *string_pool = (this+stringOffset).arrayZ; + return_trace (nameRecordZ.sanitize (c, count, string_pool)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (format == 0 || format == 1) && + c->check_array (nameRecordZ.arrayZ, count) && + c->check_range (this, stringOffset) && + sanitize_records (c)); + } + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + this->table = hb_sanitize_context_t ().reference_table (face); + assert (this->table.get_length () >= this->table->stringOffset); + this->pool = (const char *) (const void *) (this->table+this->table->stringOffset); + this->pool_len = this->table.get_length () - this->table->stringOffset; + const hb_array_t all_names (this->table->nameRecordZ.arrayZ, + this->table->count); + + this->names.alloc (all_names.length, true); + + for (unsigned int i = 0; i < all_names.length; i++) + { + hb_ot_name_entry_t *entry = this->names.push (); + + entry->name_id = all_names[i].nameID; + entry->language = all_names[i].language (face); + entry->entry_score = all_names[i].score (); + entry->entry_index = i; + } + + this->names.qsort (_hb_ot_name_entry_cmp); + /* Walk and pick best only for each name_id,language pair, + * while dropping unsupported encodings. */ + unsigned int j = 0; + for (unsigned int i = 0; i < this->names.length; i++) + { + if (this->names[i].entry_score == UNSUPPORTED || + this->names[i].language == HB_LANGUAGE_INVALID) + continue; + if (i && + this->names[i - 1].name_id == this->names[i].name_id && + this->names[i - 1].language == this->names[i].language) + continue; + this->names[j++] = this->names[i]; + } + this->names.resize (j); + } + ~accelerator_t () + { + this->table.destroy (); + } + + int get_index (hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *width=nullptr) const + { + const hb_ot_name_entry_t key = {name_id, {0}, language}; + const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names, + this->names.length, + sizeof (hb_ot_name_entry_t), + _hb_ot_name_entry_cmp_key, + true); + + if (!entry) + { + entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names, + this->names.length, + sizeof (hb_ot_name_entry_t), + _hb_ot_name_entry_cmp_key, + false); + } + + if (!entry) + return -1; + + if (width) + *width = entry->entry_score < 10 ? 2 : 1; + + return entry->entry_index; + } + + hb_bytes_t get_name (unsigned int idx) const + { + const hb_array_t all_names (table->nameRecordZ.arrayZ, table->count); + const NameRecord &record = all_names[idx]; + const hb_bytes_t string_pool (pool, pool_len); + return string_pool.sub_array (record.offset, record.length); + } + + private: + const char *pool; + unsigned int pool_len; + public: + hb_blob_ptr_t table; + hb_vector_t names; + }; + + public: + /* We only implement format 0 for now. */ + HBUINT16 format; /* Format selector (=0/1). */ + HBUINT16 count; /* Number of name records. */ + NNOffset16To> + stringOffset; /* Offset to start of string storage (from start of table). */ + UnsizedArrayOf + nameRecordZ; /* The name records where count is the number of records. */ + public: + DEFINE_SIZE_ARRAY (6, nameRecordZ); +}; + +#undef entry_index +#undef entry_score + +struct name_accelerator_t : name::accelerator_t { + name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {} +}; + +} /* namespace OT */ + + +#endif /* OT_NAME_NAME_HH */ diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/UPDATING.txt openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/UPDATING.txt --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/libharfbuzz/UPDATING.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/libharfbuzz/UPDATING.txt 2023-07-05 07:11:54.000000000 +0000 @@ -1,53 +1,118 @@ Tips and tasks when updating harfbuzz sources to a newer version. ----------------------------------------------------------------- +STEP 1: UPDATING FILES +---------------------- +Download and unzip the latest version from https://github.com/harfbuzz/harfbuzz/releases We only use files from the src directory and even then only the ones we need. So just C++ include and source files and only the ones needed for the library, -and even then just the ones we use. Do NOT just copy everything. +and even then just the ones we use. +IMPORTANT! DO NOT just copy everything. -So one way to update is to - -- copy over from the updated harfbuzz the exact same files we already have -- it isn't a flat directory so watch out for that -- any that are no longer available (copy fails) we remove but these may come - back later if they were actually renamed -- look for files in the destination that were NOT updated - perhaps they - are gone in the upstream - or renamed. Remove them if they are really - obsolete, or add their replacements/renames. -- iterate over : build and see what new file is missing that causes a build failure -- when this is done we have something buildable -- make sure it builds on all supported platforms. -- Harfbuzz is not modular so it is not easy, +- Harfbuzz is not modular, so the update is not a straightforward process. - The main thing is we do NOT want any * "test" programs (test in the name, have a main are clues) * support for (eg) GLib, DirectWrite, Graphite, GDI, ICU, Uniscribe * aggregators like harfbuzz.cc - since it includes things from the above as well as hb-ft.cc which we specifically exclude in the Makefile - * but we do use core text support on macOS. - * I really wish that "src" were just library source but I expect the authors + * but we do use core text support on macOS. + * I really wish that "src" were just library source, but I expect the authors have their reasons. -- we do not apply any header file changes so this is not an issue +So one way to update is to + +- copy over from the updated harfbuzz the exact same files we already have +- it isn't a flat directory so watch out for that. + +- For files that are no longer available (for which copy fails), we remove such files, + but these may come back later if they were actually renamed. + +- look for files in the destination that were NOT updated - perhaps they + are removed or renamed in the upstream. Remove them if they are really + obsolete, or add their replacements/renames. + In IntelliJ IDE: + Newly added files are shown in RED + Modified in BLUE + NOT Updated in WHITE + This feature might be helpful to keep track of new, modified and unchanged files. + + +STEP 2: BUILD CHANGES INCREMENTALLY +----------------------------------- +- iterate over : build and see what new file is missing that causes a build failure. + Sometimes just running a build does not show up any failures due to stale files. + Clean followed by build would be helpful in this situation. + +- You might run into compiler warnings that are treated as errors or the requirement + to set certain compiler flags if the build fails on a specific platform. + Check "COMPILER WARNINGS AND SETTING FLAGS" section for more details. + +- when this is done we have something buildable, make sure it builds + on all supported platforms. + + +STEP 3: COMPILER WARNINGS AND SETTING FLAGS +------------------------------------------- +- Update make parameters in Awt2DLibraries.gmk + Since we don't use configure we need to manually specify the options + we need in the Harfbuzz section of Awt2DLibraries.gmk. + As well as adding new options, we may need to clean up obsolete options. + Note there may be platform variations in the flags. + +- As with other 3rd party libs we do not fix the code to eliminate compiler + warnings unless they are critical and clearly avoiding a bug. Even then + we'd report it upstream and apply the patch once it is made available. + The usual practice is do just disable the warnings. + + +STEP 4: UPDATING .md FILE +------------------------- +- we do not apply any header file changes so this is not an issue. + - verify the license text is unchanged (extra steps are needed if it is) and update - src/java.desktop/share/legal/harfbuzz.md with the new version + src/java.desktop/share/legal/harfbuzz.md with the new version. + + +STEP 5: REPLACE TABS & REMOVE TRAILING SPACES +--------------------------------------------- - clean up trailing white space and tabs to follow jcheck rules. Use "expand" and "sed" to remove tabs and trailing white space from the imported sources. -- test using all the automated jtreg tests on all platforms -- do manual verification of Arabic, Hebrew, Thai, Indic against previous releases. - Look for manual related layout jtreg tests and run on Windows,Linux and Mac. + To clean up the extra spaces and tabs run the following script at + each folder level within libharfbuzz. + + for f in *.c *.h *.cc *.hh; + do + # replace tabs with spaces + expand ${f} > ${f}.tmp; + mv ${f}.tmp $f; + + # fix line endings to LF + sed -e 's/\r$//g' ${f} > ${f}.tmp; + mv ${f}.tmp $f; + + # remove trailing spaces + sed -e 's/[ ]* $//g' ${f} > ${f}.tmp; + mv ${f}.tmp $f; + done + + +STEP 6: TESTING +--------------- +- test using all the automated jtreg tests on all platforms. + +- do MANUAL verification of Arabic, Hebrew, Thai, Indic against previous releases. + 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 be checked. -- Update make parameters as needed - Since we don't use configure we need to manually specify the options - we need in the harfbuzz section of Awt2DLibraries.gmk. - As well as adding new options, we may need to clean up obsolete options. - Note there may be platform variations in the flags. + Different unicode combinations can be checked using Font2DTest. + Run Font2DTest, select 'UserText' option for 'Text to use'. + Paste unicodes of different languages (Arabic, Hebrew, Thai, Indic) + and compare the glyphs with previous versions. + It should look the same in both cases. -- As with other 3rd party libs we do not fix the code to eliminate compiler - warnings unless they are critical and clearly avoiding a bug. Even then - we'd report it upstream. The usual practice is do just disable the warnings -- Update THIS UPDATING.txt file too if it is outdated. +- FINALLY, Do update THIS UPDATING.txt file too if it is outdated. diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsalpha.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsalpha.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsalpha.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsalpha.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,675 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// Alpha copy ------------------------------------------------------------------------------------------------------------------ + +// This macro return words stored as big endian +#define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8)) + + +// Floor to byte, taking care of saturation +cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d) +{ + d += 0.5; + if (d <= 0) return 0; + if (d >= 255.0) return 255; + + return (cmsUInt8Number) _cmsQuickFloorWord(d); +} + + +// Return the size in bytes of a given formatter +static +cmsUInt32Number trueBytesSize(cmsUInt32Number Format) +{ + cmsUInt32Number fmt_bytes = T_BYTES(Format); + + // For double, the T_BYTES field returns zero + if (fmt_bytes == 0) + return sizeof(double); + + // Otherwise, it is already correct for all formats + return fmt_bytes; +} + + +// Several format converters + +typedef void(*cmsFormatterAlphaFn)(void* dst, const void* src); + + +// From 8 + +static +void copy8(void* dst, const void* src) +{ + memmove(dst, src, 1); +} + +static +void from8to16(void* dst, const void* src) +{ + cmsUInt8Number n = *(cmsUInt8Number*)src; + *(cmsUInt16Number*) dst = (cmsUInt16Number) FROM_8_TO_16(n); +} + +static +void from8to16SE(void* dst, const void* src) +{ + cmsUInt8Number n = *(cmsUInt8Number*)src; + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(FROM_8_TO_16(n)); +} + +static +void from8toFLT(void* dst, const void* src) +{ + *(cmsFloat32Number*)dst = (cmsFloat32Number) (*(cmsUInt8Number*)src) / 255.0f; +} + +static +void from8toDBL(void* dst, const void* src) +{ + *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt8Number*)src) / 255.0; +} + +static +void from8toHLF(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f; + *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + +// From 16 + +static +void from16to8(void* dst, const void* src) +{ + cmsUInt16Number n = *(cmsUInt16Number*)src; + *(cmsUInt8Number*) dst = FROM_16_TO_8(n); +} + +static +void from16SEto8(void* dst, const void* src) +{ + cmsUInt16Number n = *(cmsUInt16Number*)src; + *(cmsUInt8Number*)dst = FROM_16_TO_8(CHANGE_ENDIAN(n)); +} + +static +void copy16(void* dst, const void* src) +{ + memmove(dst, src, 2); +} + +static +void from16to16(void* dst, const void* src) +{ + cmsUInt16Number n = *(cmsUInt16Number*)src; + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(n); +} + +static +void from16toFLT(void* dst, const void* src) +{ + *(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f; +} + +static +void from16SEtoFLT(void* dst, const void* src) +{ + *(cmsFloat32Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f; +} + +static +void from16toDBL(void* dst, const void* src) +{ + *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt16Number*)src) / 65535.0; +} + +static +void from16SEtoDBL(void* dst, const void* src) +{ + *(cmsFloat64Number*)dst = (cmsFloat64Number) (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0; +} + +static +void from16toHLF(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f; + *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + +static +void from16SEtoHLF(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f; + *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} +// From Float + +static +void fromFLTto8(void* dst, const void* src) +{ + cmsFloat32Number n = *(cmsFloat32Number*)src; + *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0); +} + +static +void fromFLTto16(void* dst, const void* src) +{ + cmsFloat32Number n = *(cmsFloat32Number*)src; + *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0); +} + +static +void fromFLTto16SE(void* dst, const void* src) +{ + cmsFloat32Number n = *(cmsFloat32Number*)src; + cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0); + + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i); +} + +static +void copy32(void* dst, const void* src) +{ + memmove(dst, src, sizeof(cmsFloat32Number)); +} + +static +void fromFLTtoDBL(void* dst, const void* src) +{ + cmsFloat32Number n = *(cmsFloat32Number*)src; + *(cmsFloat64Number*)dst = (cmsFloat64Number)n; +} + +static +void fromFLTtoHLF(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = *(cmsFloat32Number*)src; + *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + + +// From HALF + +static +void fromHLFto8(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); + *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif + +} + +static +void fromHLFto16(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); + *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + +static +void fromHLFto16SE(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); + cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0); + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + +static +void fromHLFtoFLT(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + +static +void fromHLFtoDBL(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + *(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + +// From double +static +void fromDBLto8(void* dst, const void* src) +{ + cmsFloat64Number n = *(cmsFloat64Number*)src; + *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0); +} + +static +void fromDBLto16(void* dst, const void* src) +{ + cmsFloat64Number n = *(cmsFloat64Number*)src; + *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f); +} + +static +void fromDBLto16SE(void* dst, const void* src) +{ + cmsFloat64Number n = *(cmsFloat64Number*)src; + cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0f); + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i); +} + +static +void fromDBLtoFLT(void* dst, const void* src) +{ + cmsFloat64Number n = *(cmsFloat64Number*)src; + *(cmsFloat32Number*)dst = (cmsFloat32Number) n; +} + +static +void fromDBLtoHLF(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src; + *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} + +static +void copy64(void* dst, const void* src) +{ + memmove(dst, src, sizeof(cmsFloat64Number)); +} + + +// Returns the position (x or y) of the formatter in the table of functions +static +int FormatterPos(cmsUInt32Number frm) +{ + cmsUInt32Number b = T_BYTES(frm); + + if (b == 0 && T_FLOAT(frm)) + return 5; // DBL +#ifndef CMS_NO_HALF_SUPPORT + if (b == 2 && T_FLOAT(frm)) + return 3; // HLF +#endif + if (b == 4 && T_FLOAT(frm)) + return 4; // FLT + if (b == 2 && !T_FLOAT(frm)) + { + if (T_ENDIAN16(frm)) + return 2; // 16SE + else + return 1; // 16 + } + if (b == 1 && !T_FLOAT(frm)) + return 0; // 8 + return -1; // not recognized +} + +// Obtains an alpha-to-alpha function formatter +static +cmsFormatterAlphaFn _cmsGetFormatterAlpha(cmsContext id, cmsUInt32Number in, cmsUInt32Number out) +{ +static cmsFormatterAlphaFn FormattersAlpha[6][6] = { + + /* from 8 */ { copy8, from8to16, from8to16SE, from8toHLF, from8toFLT, from8toDBL }, + /* from 16*/ { from16to8, copy16, from16to16, from16toHLF, from16toFLT, from16toDBL }, + /* from 16SE*/{ from16SEto8, from16to16, copy16, from16SEtoHLF,from16SEtoFLT, from16SEtoDBL }, + /* from HLF*/ { fromHLFto8, fromHLFto16, fromHLFto16SE, copy16, fromHLFtoFLT, fromHLFtoDBL }, + /* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTto16SE, fromFLTtoHLF, copy32, fromFLTtoDBL }, + /* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLto16SE, fromDBLtoHLF, fromDBLtoFLT, copy64 }}; + + int in_n = FormatterPos(in); + int out_n = FormatterPos(out); + + if (in_n < 0 || out_n < 0 || in_n > 5 || out_n > 5) { + + cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width"); + return NULL; + } + + return FormattersAlpha[in_n][out_n]; +} + + + +// This function computes the distance from each component to the next one in bytes. +static +void ComputeIncrementsForChunky(cmsUInt32Number Format, + cmsUInt32Number ComponentStartingOrder[], + cmsUInt32Number ComponentPointerIncrements[]) +{ + cmsUInt32Number channels[cmsMAXCHANNELS]; + cmsUInt32Number extra = T_EXTRA(Format); + cmsUInt32Number nchannels = T_CHANNELS(Format); + cmsUInt32Number total_chans = nchannels + extra; + cmsUInt32Number i; + cmsUInt32Number channelSize = trueBytesSize(Format); + cmsUInt32Number pixelSize = channelSize * total_chans; + + // Sanity check + if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS) + return; + + memset(channels, 0, sizeof(channels)); + + // Separation is independent of starting point and only depends on channel size + for (i = 0; i < extra; i++) + ComponentPointerIncrements[i] = pixelSize; + + // Handle do swap + for (i = 0; i < total_chans; i++) + { + if (T_DOSWAP(Format)) { + channels[i] = total_chans - i - 1; + } + else { + channels[i] = i; + } + } + + // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012 + if (T_SWAPFIRST(Format) && total_chans > 1) { + + cmsUInt32Number tmp = channels[0]; + for (i = 0; i < total_chans-1; i++) + channels[i] = channels[i + 1]; + + channels[total_chans - 1] = tmp; + } + + // Handle size + if (channelSize > 1) + for (i = 0; i < total_chans; i++) { + channels[i] *= channelSize; + } + + for (i = 0; i < extra; i++) + ComponentStartingOrder[i] = channels[i + nchannels]; +} + + + +// On planar configurations, the distance is the stride added to any non-negative +static +void ComputeIncrementsForPlanar(cmsUInt32Number Format, + cmsUInt32Number BytesPerPlane, + cmsUInt32Number ComponentStartingOrder[], + cmsUInt32Number ComponentPointerIncrements[]) +{ + cmsUInt32Number channels[cmsMAXCHANNELS]; + cmsUInt32Number extra = T_EXTRA(Format); + cmsUInt32Number nchannels = T_CHANNELS(Format); + cmsUInt32Number total_chans = nchannels + extra; + cmsUInt32Number i; + cmsUInt32Number channelSize = trueBytesSize(Format); + + // Sanity check + if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS) + return; + + memset(channels, 0, sizeof(channels)); + + // Separation is independent of starting point and only depends on channel size + for (i = 0; i < extra; i++) + ComponentPointerIncrements[i] = channelSize; + + // Handle do swap + for (i = 0; i < total_chans; i++) + { + if (T_DOSWAP(Format)) { + channels[i] = total_chans - i - 1; + } + else { + channels[i] = i; + } + } + + // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012 + if (T_SWAPFIRST(Format) && total_chans > 0) { + + cmsUInt32Number tmp = channels[0]; + for (i = 0; i < total_chans - 1; i++) + channels[i] = channels[i + 1]; + + channels[total_chans - 1] = tmp; + } + + // Handle size + for (i = 0; i < total_chans; i++) { + channels[i] *= BytesPerPlane; + } + + for (i = 0; i < extra; i++) + ComponentStartingOrder[i] = channels[i + nchannels]; +} + + + +// Dispatcher por chunky and planar RGB +static +void ComputeComponentIncrements(cmsUInt32Number Format, + cmsUInt32Number BytesPerPlane, + cmsUInt32Number ComponentStartingOrder[], + cmsUInt32Number ComponentPointerIncrements[]) +{ + if (T_PLANAR(Format)) { + + ComputeIncrementsForPlanar(Format, BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements); + } + else { + ComputeIncrementsForChunky(Format, ComponentStartingOrder, ComponentPointerIncrements); + } + +} + + + +// Handles extra channels copying alpha if requested by the flags +void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsUInt32Number i, j, k; + cmsUInt32Number nExtra; + cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS]; + cmsUInt32Number SourceIncrements[cmsMAXCHANNELS]; + cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS]; + cmsUInt32Number DestIncrements[cmsMAXCHANNELS]; + + cmsFormatterAlphaFn copyValueFn; + + // Make sure we need some copy + if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA)) + return; + + // Exit early if in-place color-management is occurring - no need to copy extra channels to themselves. + if (p->InputFormat == p->OutputFormat && in == out) + return; + + // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time. + nExtra = T_EXTRA(p->InputFormat); + if (nExtra != T_EXTRA(p->OutputFormat)) + return; + + // Anything to do? + if (nExtra == 0) + return; + + // Compute the increments + ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements); + ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements); + + // Check for conversions 8, 16, half, float, dbl + copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat); + if (copyValueFn == NULL) + return; + + if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly + + cmsUInt8Number* SourcePtr; + cmsUInt8Number* DestPtr; + + cmsUInt32Number SourceStrideIncrement = 0; + cmsUInt32Number DestStrideIncrement = 0; + + // The loop itself + for (i = 0; i < LineCount; i++) { + + // Prepare pointers for the loop + SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement; + DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement; + + for (j = 0; j < PixelsPerLine; j++) { + + copyValueFn(DestPtr, SourcePtr); + + SourcePtr += SourceIncrements[0]; + DestPtr += DestIncrements[0]; + } + + SourceStrideIncrement += Stride->BytesPerLineIn; + DestStrideIncrement += Stride->BytesPerLineOut; + } + + } + else { // General case with more than one extra channel + + cmsUInt8Number* SourcePtr[cmsMAXCHANNELS]; + cmsUInt8Number* DestPtr[cmsMAXCHANNELS]; + + cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS]; + cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS]; + + memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements)); + memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements)); + + // The loop itself + for (i = 0; i < LineCount; i++) { + + // Prepare pointers for the loop + for (j = 0; j < nExtra; j++) { + + SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j]; + DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j]; + } + + for (j = 0; j < PixelsPerLine; j++) { + + for (k = 0; k < nExtra; k++) { + + copyValueFn(DestPtr[k], SourcePtr[k]); + + SourcePtr[k] += SourceIncrements[k]; + DestPtr[k] += DestIncrements[k]; + } + } + + for (j = 0; j < nExtra; j++) { + + SourceStrideIncrements[j] += Stride->BytesPerLineIn; + DestStrideIncrements[j] += Stride->BytesPerLineOut; + } + } + } +} + + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmscam02.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmscam02.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmscam02.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmscam02.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,515 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging. + +// ---------- Implementation -------------------------------------------- + +typedef struct { + + cmsFloat64Number XYZ[3]; + cmsFloat64Number RGB[3]; + cmsFloat64Number RGBc[3]; + cmsFloat64Number RGBp[3]; + cmsFloat64Number RGBpa[3]; + cmsFloat64Number a, b, h, e, H, A, J, Q, s, t, C, M; + cmsFloat64Number abC[2]; + cmsFloat64Number abs[2]; + cmsFloat64Number abM[2]; + +} CAM02COLOR; + +typedef struct { + + CAM02COLOR adoptedWhite; + cmsFloat64Number LA, Yb; + cmsFloat64Number F, c, Nc; + cmsUInt32Number surround; + cmsFloat64Number n, Nbb, Ncb, z, FL, D; + + cmsContext ContextID; + +} cmsCIECAM02; + + +static +cmsFloat64Number compute_n(cmsCIECAM02* pMod) +{ + return (pMod -> Yb / pMod -> adoptedWhite.XYZ[1]); +} + +static +cmsFloat64Number compute_z(cmsCIECAM02* pMod) +{ + return (1.48 + pow(pMod -> n, 0.5)); +} + +static +cmsFloat64Number computeNbb(cmsCIECAM02* pMod) +{ + return (0.725 * pow((1.0 / pMod -> n), 0.2)); +} + +static +cmsFloat64Number computeFL(cmsCIECAM02* pMod) +{ + cmsFloat64Number k, FL; + + k = 1.0 / ((5.0 * pMod->LA) + 1.0); + FL = 0.2 * pow(k, 4.0) * (5.0 * pMod->LA) + 0.1 * + (pow((1.0 - pow(k, 4.0)), 2.0)) * + (pow((5.0 * pMod->LA), (1.0 / 3.0))); + + return FL; +} + +static +cmsFloat64Number computeD(cmsCIECAM02* pMod) +{ + cmsFloat64Number D; + + D = pMod->F - (1.0/3.6)*(exp(((-pMod ->LA-42) / 92.0))); + + return D; +} + + +static +CAM02COLOR XYZtoCAT02(CAM02COLOR clr) +{ + clr.RGB[0] = (clr.XYZ[0] * 0.7328) + (clr.XYZ[1] * 0.4296) + (clr.XYZ[2] * -0.1624); + clr.RGB[1] = (clr.XYZ[0] * -0.7036) + (clr.XYZ[1] * 1.6975) + (clr.XYZ[2] * 0.0061); + clr.RGB[2] = (clr.XYZ[0] * 0.0030) + (clr.XYZ[1] * 0.0136) + (clr.XYZ[2] * 0.9834); + + return clr; +} + +static +CAM02COLOR ChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod) +{ + cmsUInt32Number i; + + for (i = 0; i < 3; i++) { + clr.RGBc[i] = ((pMod -> adoptedWhite.XYZ[1] * + (pMod->D / pMod -> adoptedWhite.RGB[i])) + + (1.0 - pMod->D)) * clr.RGB[i]; + } + + return clr; +} + + +static +CAM02COLOR CAT02toHPE(CAM02COLOR clr) +{ + cmsFloat64Number M[9]; + + M[0] =(( 0.38971 * 1.096124) + (0.68898 * 0.454369) + (-0.07868 * -0.009628)); + M[1] =(( 0.38971 * -0.278869) + (0.68898 * 0.473533) + (-0.07868 * -0.005698)); + M[2] =(( 0.38971 * 0.182745) + (0.68898 * 0.072098) + (-0.07868 * 1.015326)); + M[3] =((-0.22981 * 1.096124) + (1.18340 * 0.454369) + ( 0.04641 * -0.009628)); + M[4] =((-0.22981 * -0.278869) + (1.18340 * 0.473533) + ( 0.04641 * -0.005698)); + M[5] =((-0.22981 * 0.182745) + (1.18340 * 0.072098) + ( 0.04641 * 1.015326)); + M[6] =(-0.009628); + M[7] =(-0.005698); + M[8] =( 1.015326); + + clr.RGBp[0] = (clr.RGBc[0] * M[0]) + (clr.RGBc[1] * M[1]) + (clr.RGBc[2] * M[2]); + clr.RGBp[1] = (clr.RGBc[0] * M[3]) + (clr.RGBc[1] * M[4]) + (clr.RGBc[2] * M[5]); + clr.RGBp[2] = (clr.RGBc[0] * M[6]) + (clr.RGBc[1] * M[7]) + (clr.RGBc[2] * M[8]); + + return clr; +} + +static +CAM02COLOR NonlinearCompression(CAM02COLOR clr, cmsCIECAM02* pMod) +{ + cmsUInt32Number i; + cmsFloat64Number temp; + + for (i = 0; i < 3; i++) { + if (clr.RGBp[i] < 0) { + + temp = pow((-1.0 * pMod->FL * clr.RGBp[i] / 100.0), 0.42); + clr.RGBpa[i] = (-1.0 * 400.0 * temp) / (temp + 27.13) + 0.1; + } + else { + temp = pow((pMod->FL * clr.RGBp[i] / 100.0), 0.42); + clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1; + } + } + + clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] + + (clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb; + + return clr; +} + +static +CAM02COLOR ComputeCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod) +{ + cmsFloat64Number a, b, temp, e, t, r2d, d2r; + + a = clr.RGBpa[0] - (12.0 * clr.RGBpa[1] / 11.0) + (clr.RGBpa[2] / 11.0); + b = (clr.RGBpa[0] + clr.RGBpa[1] - (2.0 * clr.RGBpa[2])) / 9.0; + + r2d = (180.0 / 3.141592654); + if (a == 0) { + if (b == 0) clr.h = 0; + else if (b > 0) clr.h = 90; + else clr.h = 270; + } + else if (a > 0) { + temp = b / a; + if (b > 0) clr.h = (r2d * atan(temp)); + else if (b == 0) clr.h = 0; + else clr.h = (r2d * atan(temp)) + 360; + } + else { + temp = b / a; + clr.h = (r2d * atan(temp)) + 180; + } + + d2r = (3.141592654 / 180.0); + e = ((12500.0 / 13.0) * pMod->Nc * pMod->Ncb) * + (cos((clr.h * d2r + 2.0)) + 3.8); + + if (clr.h < 20.14) { + temp = ((clr.h + 122.47)/1.2) + ((20.14 - clr.h)/0.8); + clr.H = 300 + (100*((clr.h + 122.47)/1.2)) / temp; + } + else if (clr.h < 90.0) { + temp = ((clr.h - 20.14)/0.8) + ((90.00 - clr.h)/0.7); + clr.H = (100*((clr.h - 20.14)/0.8)) / temp; + } + else if (clr.h < 164.25) { + temp = ((clr.h - 90.00)/0.7) + ((164.25 - clr.h)/1.0); + clr.H = 100 + ((100*((clr.h - 90.00)/0.7)) / temp); + } + else if (clr.h < 237.53) { + temp = ((clr.h - 164.25)/1.0) + ((237.53 - clr.h)/1.2); + clr.H = 200 + ((100*((clr.h - 164.25)/1.0)) / temp); + } + else { + temp = ((clr.h - 237.53)/1.2) + ((360 - clr.h + 20.14)/0.8); + clr.H = 300 + ((100*((clr.h - 237.53)/1.2)) / temp); + } + + clr.J = 100.0 * pow((clr.A / pMod->adoptedWhite.A), + (pMod->c * pMod->z)); + + clr.Q = (4.0 / pMod->c) * pow((clr.J / 100.0), 0.5) * + (pMod->adoptedWhite.A + 4.0) * pow(pMod->FL, 0.25); + + t = (e * pow(((a * a) + (b * b)), 0.5)) / + (clr.RGBpa[0] + clr.RGBpa[1] + + ((21.0 / 20.0) * clr.RGBpa[2])); + + clr.C = pow(t, 0.9) * pow((clr.J / 100.0), 0.5) * + pow((1.64 - pow(0.29, pMod->n)), 0.73); + + clr.M = clr.C * pow(pMod->FL, 0.25); + clr.s = 100.0 * pow((clr.M / clr.Q), 0.5); + + return clr; +} + + +static +CAM02COLOR InverseCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod) +{ + + cmsFloat64Number t, e, p1, p2, p3, p4, p5, hr, d2r; + d2r = 3.141592654 / 180.0; + + t = pow( (clr.C / (pow((clr.J / 100.0), 0.5) * + (pow((1.64 - pow(0.29, pMod->n)), 0.73)))), + (1.0 / 0.9) ); + e = ((12500.0 / 13.0) * pMod->Nc * pMod->Ncb) * + (cos((clr.h * d2r + 2.0)) + 3.8); + + clr.A = pMod->adoptedWhite.A * pow( + (clr.J / 100.0), + (1.0 / (pMod->c * pMod->z))); + + p1 = e / t; + p2 = (clr.A / pMod->Nbb) + 0.305; + p3 = 21.0 / 20.0; + + hr = clr.h * d2r; + + if (fabs(sin(hr)) >= fabs(cos(hr))) { + p4 = p1 / sin(hr); + clr.b = (p2 * (2.0 + p3) * (460.0 / 1403.0)) / + (p4 + (2.0 + p3) * (220.0 / 1403.0) * + (cos(hr) / sin(hr)) - (27.0 / 1403.0) + + p3 * (6300.0 / 1403.0)); + clr.a = clr.b * (cos(hr) / sin(hr)); + } + else { + p5 = p1 / cos(hr); + clr.a = (p2 * (2.0 + p3) * (460.0 / 1403.0)) / + (p5 + (2.0 + p3) * (220.0 / 1403.0) - + ((27.0 / 1403.0) - p3 * (6300.0 / 1403.0)) * + (sin(hr) / cos(hr))); + clr.b = clr.a * (sin(hr) / cos(hr)); + } + + clr.RGBpa[0] = ((460.0 / 1403.0) * p2) + + ((451.0 / 1403.0) * clr.a) + + ((288.0 / 1403.0) * clr.b); + clr.RGBpa[1] = ((460.0 / 1403.0) * p2) - + ((891.0 / 1403.0) * clr.a) - + ((261.0 / 1403.0) * clr.b); + clr.RGBpa[2] = ((460.0 / 1403.0) * p2) - + ((220.0 / 1403.0) * clr.a) - + ((6300.0 / 1403.0) * clr.b); + + return clr; +} + +static +CAM02COLOR InverseNonlinearity(CAM02COLOR clr, cmsCIECAM02* pMod) +{ + cmsUInt32Number i; + cmsFloat64Number c1; + + for (i = 0; i < 3; i++) { + if ((clr.RGBpa[i] - 0.1) < 0) c1 = -1; + else c1 = 1; + clr.RGBp[i] = c1 * (100.0 / pMod->FL) * + pow(((27.13 * fabs(clr.RGBpa[i] - 0.1)) / + (400.0 - fabs(clr.RGBpa[i] - 0.1))), + (1.0 / 0.42)); + } + + return clr; +} + +static +CAM02COLOR HPEtoCAT02(CAM02COLOR clr) +{ + cmsFloat64Number M[9]; + + M[0] = (( 0.7328 * 1.910197) + (0.4296 * 0.370950)); + M[1] = (( 0.7328 * -1.112124) + (0.4296 * 0.629054)); + M[2] = (( 0.7328 * 0.201908) + (0.4296 * 0.000008) - 0.1624); + M[3] = ((-0.7036 * 1.910197) + (1.6975 * 0.370950)); + M[4] = ((-0.7036 * -1.112124) + (1.6975 * 0.629054)); + M[5] = ((-0.7036 * 0.201908) + (1.6975 * 0.000008) + 0.0061); + M[6] = (( 0.0030 * 1.910197) + (0.0136 * 0.370950)); + M[7] = (( 0.0030 * -1.112124) + (0.0136 * 0.629054)); + M[8] = (( 0.0030 * 0.201908) + (0.0136 * 0.000008) + 0.9834); + + clr.RGBc[0] = (clr.RGBp[0] * M[0]) + (clr.RGBp[1] * M[1]) + (clr.RGBp[2] * M[2]); + clr.RGBc[1] = (clr.RGBp[0] * M[3]) + (clr.RGBp[1] * M[4]) + (clr.RGBp[2] * M[5]); + clr.RGBc[2] = (clr.RGBp[0] * M[6]) + (clr.RGBp[1] * M[7]) + (clr.RGBp[2] * M[8]); + return clr; +} + + +static +CAM02COLOR InverseChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod) +{ + cmsUInt32Number i; + for (i = 0; i < 3; i++) { + clr.RGB[i] = clr.RGBc[i] / + ((pMod->adoptedWhite.XYZ[1] * pMod->D / pMod->adoptedWhite.RGB[i]) + 1.0 - pMod->D); + } + return clr; +} + + +static +CAM02COLOR CAT02toXYZ(CAM02COLOR clr) +{ + clr.XYZ[0] = (clr.RGB[0] * 1.096124) + (clr.RGB[1] * -0.278869) + (clr.RGB[2] * 0.182745); + clr.XYZ[1] = (clr.RGB[0] * 0.454369) + (clr.RGB[1] * 0.473533) + (clr.RGB[2] * 0.072098); + clr.XYZ[2] = (clr.RGB[0] * -0.009628) + (clr.RGB[1] * -0.005698) + (clr.RGB[2] * 1.015326); + + return clr; +} + + +cmsHANDLE CMSEXPORT cmsCIECAM02Init(cmsContext ContextID, const cmsViewingConditions* pVC) +{ + cmsCIECAM02* lpMod; + + _cmsAssert(pVC != NULL); + + if((lpMod = (cmsCIECAM02*) _cmsMallocZero(ContextID, sizeof(cmsCIECAM02))) == NULL) { + return NULL; + } + + lpMod ->ContextID = ContextID; + + lpMod ->adoptedWhite.XYZ[0] = pVC ->whitePoint.X; + lpMod ->adoptedWhite.XYZ[1] = pVC ->whitePoint.Y; + lpMod ->adoptedWhite.XYZ[2] = pVC ->whitePoint.Z; + + lpMod -> LA = pVC ->La; + lpMod -> Yb = pVC ->Yb; + lpMod -> D = pVC ->D_value; + lpMod -> surround = pVC ->surround; + + switch (lpMod -> surround) { + + + case CUTSHEET_SURROUND: + lpMod->F = 0.8; + lpMod->c = 0.41; + lpMod->Nc = 0.8; + break; + + case DARK_SURROUND: + lpMod -> F = 0.8; + lpMod -> c = 0.525; + lpMod -> Nc = 0.8; + break; + + case DIM_SURROUND: + lpMod -> F = 0.9; + lpMod -> c = 0.59; + lpMod -> Nc = 0.95; + break; + + default: + // Average surround + lpMod -> F = 1.0; + lpMod -> c = 0.69; + lpMod -> Nc = 1.0; + } + + lpMod -> n = compute_n(lpMod); + lpMod -> z = compute_z(lpMod); + lpMod -> Nbb = computeNbb(lpMod); + lpMod -> FL = computeFL(lpMod); + + if (lpMod -> D == D_CALCULATE) { + lpMod -> D = computeD(lpMod); + } + + lpMod -> Ncb = lpMod -> Nbb; + + lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite); + lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod); + lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite); + lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod); + + return (cmsHANDLE) lpMod; + +} + +void CMSEXPORT cmsCIECAM02Done(cmsHANDLE hModel) +{ + cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; + + if (lpMod) _cmsFree(lpMod ->ContextID, lpMod); +} + + +void CMSEXPORT cmsCIECAM02Forward(cmsHANDLE hModel, const cmsCIEXYZ* pIn, cmsJCh* pOut) +{ + CAM02COLOR clr; + cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; + + _cmsAssert(lpMod != NULL); + _cmsAssert(pIn != NULL); + _cmsAssert(pOut != NULL); + + memset(&clr, 0, sizeof(clr)); + + clr.XYZ[0] = pIn ->X; + clr.XYZ[1] = pIn ->Y; + clr.XYZ[2] = pIn ->Z; + + clr = XYZtoCAT02(clr); + clr = ChromaticAdaptation(clr, lpMod); + clr = CAT02toHPE(clr); + clr = NonlinearCompression(clr, lpMod); + clr = ComputeCorrelates(clr, lpMod); + + pOut ->J = clr.J; + pOut ->C = clr.C; + pOut ->h = clr.h; +} + +void CMSEXPORT cmsCIECAM02Reverse(cmsHANDLE hModel, const cmsJCh* pIn, cmsCIEXYZ* pOut) +{ + CAM02COLOR clr; + cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; + + _cmsAssert(lpMod != NULL); + _cmsAssert(pIn != NULL); + _cmsAssert(pOut != NULL); + + memset(&clr, 0, sizeof(clr)); + + clr.J = pIn -> J; + clr.C = pIn -> C; + clr.h = pIn -> h; + + clr = InverseCorrelates(clr, lpMod); + clr = InverseNonlinearity(clr, lpMod); + clr = HPEtoCAT02(clr); + clr = InverseChromaticAdaptation(clr, lpMod); + clr = CAT02toXYZ(clr); + + pOut ->X = clr.XYZ[0]; + pOut ->Y = clr.XYZ[1]; + pOut ->Z = clr.XYZ[2]; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmscgats.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmscgats.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmscgats.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmscgats.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,2974 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// IT8.7 / CGATS.17-200x handling ----------------------------------------------------------------------------- + + +#define MAXID 128 // Max length of identifier +#define MAXSTR 1024 // Max length of string +#define MAXTABLES 255 // Max Number of tables in a single stream +#define MAXINCLUDE 20 // Max number of nested includes + +#define DEFAULT_DBL_FORMAT "%.10g" // Double formatting + +#ifdef CMS_IS_WINDOWS_ +# include +# define DIR_CHAR '\\' +#else +# define DIR_CHAR '/' +#endif + + +// Symbols +typedef enum { + + SUNDEFINED, + SINUM, // Integer + SDNUM, // Real + SIDENT, // Identifier + SSTRING, // string + SCOMMENT, // comment + SEOLN, // End of line + SEOF, // End of stream + SSYNERROR, // Syntax error found on stream + + // Keywords + + SBEGIN_DATA, + SBEGIN_DATA_FORMAT, + SEND_DATA, + SEND_DATA_FORMAT, + SKEYWORD, + SDATA_FORMAT_ID, + SINCLUDE + + } SYMBOL; + + +// How to write the value +typedef enum { + + WRITE_UNCOOKED, + WRITE_STRINGIFY, + WRITE_HEXADECIMAL, + WRITE_BINARY, + WRITE_PAIR + + } WRITEMODE; + +// Linked list of variable names +typedef struct _KeyVal { + + struct _KeyVal* Next; + char* Keyword; // Name of variable + struct _KeyVal* NextSubkey; // If key is a dictionary, points to the next item + char* Subkey; // If key is a dictionary, points to the subkey name + char* Value; // Points to value + WRITEMODE WriteAs; // How to write the value + + } KEYVALUE; + + +// Linked list of memory chunks (Memory sink) +typedef struct _OwnedMem { + + struct _OwnedMem* Next; + void * Ptr; // Point to value + + } OWNEDMEM; + +// Suballocator +typedef struct _SubAllocator { + + cmsUInt8Number* Block; + cmsUInt32Number BlockSize; + cmsUInt32Number Used; + + } SUBALLOCATOR; + +// Table. Each individual table can hold properties and rows & cols +typedef struct _Table { + + char SheetType[MAXSTR]; // The first row of the IT8 (the type) + + int nSamples, nPatches; // Cols, Rows + int SampleID; // Pos of ID + + KEYVALUE* HeaderList; // The properties + + char** DataFormat; // The binary stream descriptor + char** Data; // The binary stream + + } TABLE; + +// File stream being parsed +typedef struct _FileContext { + char FileName[cmsMAX_PATH]; // File name if being read from file + FILE* Stream; // File stream or NULL if holded in memory + } FILECTX; + +//Very simple string +typedef struct { + + struct struct_it8* it8; + cmsInt32Number max; + cmsInt32Number len; + char* begin; + } string; + + +// This struct hold all information about an open IT8 handler. +typedef struct struct_it8 { + + cmsUInt32Number TablesCount; // How many tables in this stream + cmsUInt32Number nTable; // The actual table + + TABLE Tab[MAXTABLES]; + + // Memory management + OWNEDMEM* MemorySink; // The storage backend + SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast + + // Parser state machine + SYMBOL sy; // Current symbol + int ch; // Current character + + cmsInt32Number inum; // integer value + cmsFloat64Number dnum; // real value + + string* id; // identifier + string* str; // string + + // Allowed keywords & datasets. They have visibility on whole stream + KEYVALUE* ValidKeywords; + KEYVALUE* ValidSampleID; + + char* Source; // Points to loc. being parsed + cmsInt32Number lineno; // line counter for error reporting + + FILECTX* FileStack[MAXINCLUDE]; // Stack of files being parsed + cmsInt32Number IncludeSP; // Include Stack Pointer + + char* MemoryBlock; // The stream if holded in memory + + char DoubleFormatter[MAXID];// Printf-like 'cmsFloat64Number' formatter + + cmsContext ContextID; // The threading context + + } cmsIT8; + + +// The stream for save operations +typedef struct { + + FILE* stream; // For save-to-file behaviour + + cmsUInt8Number* Base; + cmsUInt8Number* Ptr; // For save-to-mem behaviour + cmsUInt32Number Used; + cmsUInt32Number Max; + + } SAVESTREAM; + + +// ------------------------------------------------------ cmsIT8 parsing routines + + +// A keyword +typedef struct { + + const char *id; + SYMBOL sy; + + } KEYWORD; + +// The keyword->symbol translation table. Sorting is required. +static const KEYWORD TabKeys[] = { + + {"$INCLUDE", SINCLUDE}, // This is an extension! + {".INCLUDE", SINCLUDE}, // This is an extension! + + {"BEGIN_DATA", SBEGIN_DATA }, + {"BEGIN_DATA_FORMAT", SBEGIN_DATA_FORMAT }, + {"DATA_FORMAT_IDENTIFIER", SDATA_FORMAT_ID}, + {"END_DATA", SEND_DATA}, + {"END_DATA_FORMAT", SEND_DATA_FORMAT}, + {"KEYWORD", SKEYWORD} + }; + +#define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD)) + +// Predefined properties + +// A property +typedef struct { + const char *id; // The identifier + WRITEMODE as; // How is supposed to be written + } PROPERTY; + +static PROPERTY PredefinedProperties[] = { + + {"NUMBER_OF_FIELDS", WRITE_UNCOOKED}, // Required - NUMBER OF FIELDS + {"NUMBER_OF_SETS", WRITE_UNCOOKED}, // Required - NUMBER OF SETS + {"ORIGINATOR", WRITE_STRINGIFY}, // Required - Identifies the specific system, organization or individual that created the data file. + {"FILE_DESCRIPTOR", WRITE_STRINGIFY}, // Required - Describes the purpose or contents of the data file. + {"CREATED", WRITE_STRINGIFY}, // Required - Indicates date of creation of the data file. + {"DESCRIPTOR", WRITE_STRINGIFY}, // Required - Describes the purpose or contents of the data file. + {"DIFFUSE_GEOMETRY", WRITE_STRINGIFY}, // The diffuse geometry used. Allowed values are "sphere" or "opal". + {"MANUFACTURER", WRITE_STRINGIFY}, + {"MANUFACTURE", WRITE_STRINGIFY}, // Some broken Fuji targets does store this value + {"PROD_DATE", WRITE_STRINGIFY}, // Identifies year and month of production of the target in the form yyyy:mm. + {"SERIAL", WRITE_STRINGIFY}, // Uniquely identifies individual physical target. + + {"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code + // uniquely identifying th e material. This is intend ed to be used for IT8.7 + // physical targets only (i.e . IT8.7/1 and IT8.7/2). + + {"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and + // model number) to generate the data reported. This data will often + // provide more information about the particular data collected than an + // extensive list of specific details. This is particularly important for + // spectral data or data derived from spectrophotometry. + + {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide + // a guide to the potential for issues of paper fluorescence, etc. + + {"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported. + // Where standard conditions have been defined (e.g., SWOP at nominal) + // named conditions may suffice. Otherwise, detailed information is + // needed. + + {"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during + // measurement. Allowed values are "black", "white", or {"na". + + {"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic + // below properties are new in recent specs: + + {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated + // along with details of the geometry and the aperture size and shape. For example, + // for transmission measurements it is important to identify 0/diffuse, diffuse/0, + // opal or integrating sphere, etc. For reflection it is important to identify 0/45, + // 45/0, sphere (specular included or excluded), etc. + + {"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to + // denote the use of filters such as none, D65, Red, Green or Blue. + + {"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed + // values are {"yes", "white", "none" or "na". + + {"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the + // calculation of various data parameters (2 degree and 10 degree), CIE standard + // illuminant functions used in the calculation of various data parameters (e.g., D50, + // D65, etc.), density status response, etc. If used there shall be at least one + // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute + // in the set shall be {"name" and shall identify the particular parameter used. + // The second shall be {"value" and shall provide the value associated with that name. + // For ASCII data, a string containing the Name and Value attribute pairs shall follow + // the weighting function keyword. A semi-colon separates attribute pairs from each + // other and within the attribute the name and value are separated by a comma. + + {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name + // of the calculation, parameter is the name of the parameter used in the calculation + // and value is the value of the parameter. + + {"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc. + + {"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target. + + {"TABLE_DESCRIPTOR", WRITE_STRINGIFY}, // Describes the purpose or contents of a data table. + + {"TABLE_NAME", WRITE_STRINGIFY} // Provides a short name for a data table. +}; + +#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY)) + + +// Predefined sample types on dataset +static const char* PredefinedSampleID[] = { + "SAMPLE_ID", // Identifies sample that data represents + "STRING", // Identifies label, or other non-machine readable value. + // Value must begin and end with a " symbol + + "CMYK_C", // Cyan component of CMYK data expressed as a percentage + "CMYK_M", // Magenta component of CMYK data expressed as a percentage + "CMYK_Y", // Yellow component of CMYK data expressed as a percentage + "CMYK_K", // Black component of CMYK data expressed as a percentage + "D_RED", // Red filter density + "D_GREEN", // Green filter density + "D_BLUE", // Blue filter density + "D_VIS", // Visual filter density + "D_MAJOR_FILTER", // Major filter d ensity + "RGB_R", // Red component of RGB data + "RGB_G", // Green component of RGB data + "RGB_B", // Blue com ponent of RGB data + "SPECTRAL_NM", // Wavelength of measurement expressed in nanometers + "SPECTRAL_PCT", // Percentage reflectance/transmittance + "SPECTRAL_DEC", // Reflectance/transmittance + "XYZ_X", // X component of tristimulus data + "XYZ_Y", // Y component of tristimulus data + "XYZ_Z", // Z component of tristimulus data + "XYY_X", // x component of chromaticity data + "XYY_Y", // y component of chromaticity data + "XYY_CAPY", // Y component of tristimulus data + "LAB_L", // L* component of Lab data + "LAB_A", // a* component of Lab data + "LAB_B", // b* component of Lab data + "LAB_C", // C*ab component of Lab data + "LAB_H", // hab component of Lab data + "LAB_DE", // CIE dE + "LAB_DE_94", // CIE dE using CIE 94 + "LAB_DE_CMC", // dE using CMC + "LAB_DE_2000", // CIE dE using CIE DE 2000 + "MEAN_DE", // Mean Delta E (LAB_DE) of samples compared to batch average + // (Used for data files for ANSI IT8.7/1 and IT8.7/2 targets) + "STDEV_X", // Standard deviation of X (tristimulus data) + "STDEV_Y", // Standard deviation of Y (tristimulus data) + "STDEV_Z", // Standard deviation of Z (tristimulus data) + "STDEV_L", // Standard deviation of L* + "STDEV_A", // Standard deviation of a* + "STDEV_B", // Standard deviation of b* + "STDEV_DE", // Standard deviation of CIE dE + "CHI_SQD_PAR"}; // The average of the standard deviations of L*, a* and b*. It is + // used to derive an estimate of the chi-squared parameter which is + // recommended as the predictor of the variability of dE + +#define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *)) + +//Forward declaration of some internal functions +static void* AllocChunk(cmsIT8* it8, cmsUInt32Number size); + +static +string* StringAlloc(cmsIT8* it8, int max) +{ + string* s = (string*) AllocChunk(it8, sizeof(string)); + if (s == NULL) return NULL; + + s->it8 = it8; + s->max = max; + s->len = 0; + s->begin = (char*) AllocChunk(it8, s->max); + + return s; +} + +static +void StringClear(string* s) +{ + s->len = 0; +} + +static +void StringAppend(string* s, char c) +{ + if (s->len + 1 >= s->max) + { + char* new_ptr; + + s->max *= 10; + new_ptr = (char*) AllocChunk(s->it8, s->max); + if (new_ptr != NULL && s->begin != NULL) + memcpy(new_ptr, s->begin, s->len); + + s->begin = new_ptr; + } + + if (s->begin != NULL) + { + s->begin[s->len++] = c; + s->begin[s->len] = 0; + } +} + +static +char* StringPtr(string* s) +{ + return s->begin; +} + +static +void StringCat(string* s, const char* c) +{ + while (*c) + { + StringAppend(s, *c); + c++; + } +} + + +// Checks whatever c is a separator +static +cmsBool isseparator(int c) +{ + return (c == ' ') || (c == '\t') ; +} + +// Checks whatever c is a valid identifier char +static +cmsBool ismiddle(int c) +{ + return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127)); +} + +// Checks whatsever c is a valid identifier middle char. +static +cmsBool isidchar(int c) +{ + return isalnum(c) || ismiddle(c); +} + +// Checks whatsever c is a valid identifier first char. +static +cmsBool isfirstidchar(int c) +{ + return !isdigit(c) && ismiddle(c); +} + +// Guess whether the supplied path looks like an absolute path +static +cmsBool isabsolutepath(const char *path) +{ + char ThreeChars[4]; + + if(path == NULL) + return FALSE; + if (path[0] == 0) + return FALSE; + + strncpy(ThreeChars, path, 3); + ThreeChars[3] = 0; + + if(ThreeChars[0] == DIR_CHAR) + return TRUE; + +#ifdef CMS_IS_WINDOWS_ + if (isalpha((int) ThreeChars[0]) && ThreeChars[1] == ':') + return TRUE; +#endif + return FALSE; +} + + +// Makes a file path based on a given reference path +// NOTE: this function doesn't check if the path exists or even if it's legal +static +cmsBool BuildAbsolutePath(const char *relPath, const char *basePath, char *buffer, cmsUInt32Number MaxLen) +{ + char *tail; + cmsUInt32Number len; + + // Already absolute? + if (isabsolutepath(relPath)) { + + strncpy(buffer, relPath, MaxLen); + buffer[MaxLen-1] = 0; + return TRUE; + } + + // No, search for last + strncpy(buffer, basePath, MaxLen); + buffer[MaxLen-1] = 0; + + tail = strrchr(buffer, DIR_CHAR); + if (tail == NULL) return FALSE; // Is not absolute and has no separators?? + + len = (cmsUInt32Number) (tail - buffer); + if (len >= MaxLen) return FALSE; + + // No need to assure zero terminator over here + strncpy(tail + 1, relPath, MaxLen - len); + + return TRUE; +} + + +// Make sure no exploit is being even tried +static +const char* NoMeta(const char* str) +{ + if (strchr(str, '%') != NULL) + return "**** CORRUPTED FORMAT STRING ***"; + + return str; +} + +// Syntax error +static +cmsBool SynError(cmsIT8* it8, const char *Txt, ...) +{ + char Buffer[256], ErrMsg[1024]; + va_list args; + + va_start(args, Txt); + vsnprintf(Buffer, 255, Txt, args); + Buffer[255] = 0; + va_end(args); + + snprintf(ErrMsg, 1023, "%s: Line %d, %s", it8->FileStack[it8 ->IncludeSP]->FileName, it8->lineno, Buffer); + ErrMsg[1023] = 0; + it8->sy = SSYNERROR; + cmsSignalError(it8 ->ContextID, cmsERROR_CORRUPTION_DETECTED, "%s", ErrMsg); + return FALSE; +} + +// Check if current symbol is same as specified. issue an error else. +static +cmsBool Check(cmsIT8* it8, SYMBOL sy, const char* Err) +{ + if (it8 -> sy != sy) + return SynError(it8, NoMeta(Err)); + return TRUE; +} + +// Read Next character from stream +static +void NextCh(cmsIT8* it8) +{ + if (it8 -> FileStack[it8 ->IncludeSP]->Stream) { + + it8 ->ch = fgetc(it8 ->FileStack[it8 ->IncludeSP]->Stream); + + if (feof(it8 -> FileStack[it8 ->IncludeSP]->Stream)) { + + if (it8 ->IncludeSP > 0) { + + fclose(it8 ->FileStack[it8->IncludeSP--]->Stream); + it8 -> ch = ' '; // Whitespace to be ignored + + } else + it8 ->ch = 0; // EOF + } + } + else { + it8->ch = *it8->Source; + if (it8->ch) it8->Source++; + } +} + + +// Try to see if current identifier is a keyword, if so return the referred symbol +static +SYMBOL BinSrchKey(const char *id) +{ + int l = 1; + int r = NUMKEYS; + int x, res; + + while (r >= l) + { + x = (l+r)/2; + res = cmsstrcasecmp(id, TabKeys[x-1].id); + if (res == 0) return TabKeys[x-1].sy; + if (res < 0) r = x - 1; + else l = x + 1; + } + + return SUNDEFINED; +} + + +// 10 ^n +static +cmsFloat64Number xpow10(int n) +{ + return pow(10, (cmsFloat64Number) n); +} + + +// Reads a Real number, tries to follow from integer number +static +void ReadReal(cmsIT8* it8, cmsInt32Number inum) +{ + it8->dnum = (cmsFloat64Number)inum; + + while (isdigit(it8->ch)) { + + it8->dnum = (cmsFloat64Number)it8->dnum * 10.0 + (cmsFloat64Number)(it8->ch - '0'); + NextCh(it8); + } + + if (it8->ch == '.') { // Decimal point + + cmsFloat64Number frac = 0.0; // fraction + int prec = 0; // precision + + NextCh(it8); // Eats dec. point + + while (isdigit(it8->ch)) { + + frac = frac * 10.0 + (cmsFloat64Number)(it8->ch - '0'); + prec++; + NextCh(it8); + } + + it8->dnum = it8->dnum + (frac / xpow10(prec)); + } + + // Exponent, example 34.00E+20 + if (toupper(it8->ch) == 'E') { + + cmsInt32Number e; + cmsInt32Number sgn; + + NextCh(it8); sgn = 1; + + if (it8->ch == '-') { + + sgn = -1; NextCh(it8); + } + else + if (it8->ch == '+') { + + sgn = +1; + NextCh(it8); + } + + e = 0; + while (isdigit(it8->ch)) { + + cmsInt32Number digit = (it8->ch - '0'); + + if ((cmsFloat64Number)e * 10.0 + (cmsFloat64Number)digit < (cmsFloat64Number)+2147483647.0) + e = e * 10 + digit; + + NextCh(it8); + } + + e = sgn*e; + it8->dnum = it8->dnum * xpow10(e); + } +} + +// Parses a float number +// This can not call directly atof because it uses locale dependent +// parsing, while CCMX files always use . as decimal separator +static +cmsFloat64Number ParseFloatNumber(const char *Buffer) +{ + cmsFloat64Number dnum = 0.0; + int sign = 1; + + // keep safe + if (Buffer == NULL) return 0.0; + + if (*Buffer == '-' || *Buffer == '+') { + + sign = (*Buffer == '-') ? -1 : 1; + Buffer++; + } + + + while (*Buffer && isdigit((int)*Buffer)) { + + dnum = dnum * 10.0 + (*Buffer - '0'); + if (*Buffer) Buffer++; + } + + if (*Buffer == '.') { + + cmsFloat64Number frac = 0.0; // fraction + int prec = 0; // precision + + if (*Buffer) Buffer++; + + while (*Buffer && isdigit((int)*Buffer)) { + + frac = frac * 10.0 + (*Buffer - '0'); + prec++; + if (*Buffer) Buffer++; + } + + dnum = dnum + (frac / xpow10(prec)); + } + + // Exponent, example 34.00E+20 + if (*Buffer && toupper(*Buffer) == 'E') { + + int e; + int sgn; + + if (*Buffer) Buffer++; + sgn = 1; + + if (*Buffer == '-') { + + sgn = -1; + if (*Buffer) Buffer++; + } + else + if (*Buffer == '+') { + + sgn = +1; + if (*Buffer) Buffer++; + } + + e = 0; + while (*Buffer && isdigit((int)*Buffer)) { + + cmsInt32Number digit = (*Buffer - '0'); + + if ((cmsFloat64Number)e * 10.0 + digit < (cmsFloat64Number)+2147483647.0) + e = e * 10 + digit; + + if (*Buffer) Buffer++; + } + + e = sgn*e; + dnum = dnum * xpow10(e); + } + + return sign * dnum; +} + + +// Reads a string, special case to avoid infinite resursion on .include +static +void InStringSymbol(cmsIT8* it8) +{ + while (isseparator(it8->ch)) + NextCh(it8); + + if (it8->ch == '\'' || it8->ch == '\"') + { + int sng; + + sng = it8->ch; + StringClear(it8->str); + + NextCh(it8); + + while (it8->ch != sng) { + + if (it8->ch == '\n' || it8->ch == '\r' || it8->ch == 0) break; + else { + StringAppend(it8->str, (char)it8->ch); + NextCh(it8); + } + } + + it8->sy = SSTRING; + NextCh(it8); + } + else + SynError(it8, "String expected"); + +} + +// Reads next symbol +static +void InSymbol(cmsIT8* it8) +{ + SYMBOL key; + + do { + + while (isseparator(it8->ch)) + NextCh(it8); + + if (isfirstidchar(it8->ch)) { // Identifier + + StringClear(it8->id); + + do { + + StringAppend(it8->id, (char) it8->ch); + + NextCh(it8); + + } while (isidchar(it8->ch)); + + + key = BinSrchKey(StringPtr(it8->id)); + if (key == SUNDEFINED) it8->sy = SIDENT; + else it8->sy = key; + + } + else // Is a number? + if (isdigit(it8->ch) || it8->ch == '.' || it8->ch == '-' || it8->ch == '+') + { + int sign = 1; + + if (it8->ch == '-') { + sign = -1; + NextCh(it8); + } + + it8->inum = 0; + it8->sy = SINUM; + + if (it8->ch == '0') { // 0xnnnn (Hexa) or 0bnnnn (Binary) + + NextCh(it8); + if (toupper(it8->ch) == 'X') { + + int j; + + NextCh(it8); + while (isxdigit(it8->ch)) + { + it8->ch = toupper(it8->ch); + if (it8->ch >= 'A' && it8->ch <= 'F') j = it8->ch -'A'+10; + else j = it8->ch - '0'; + + if ((cmsFloat64Number) it8->inum * 16.0 + (cmsFloat64Number) j > (cmsFloat64Number)+2147483647.0) + { + SynError(it8, "Invalid hexadecimal number"); + it8->sy = SEOF; + return; + } + + it8->inum = it8->inum * 16 + j; + NextCh(it8); + } + return; + } + + if (toupper(it8->ch) == 'B') { // Binary + + int j; + + NextCh(it8); + while (it8->ch == '0' || it8->ch == '1') + { + j = it8->ch - '0'; + + if ((cmsFloat64Number) it8->inum * 2.0 + j > (cmsFloat64Number)+2147483647.0) + { + SynError(it8, "Invalid binary number"); + it8->sy = SEOF; + return; + } + + it8->inum = it8->inum * 2 + j; + NextCh(it8); + } + return; + } + } + + + while (isdigit(it8->ch)) { + + cmsInt32Number digit = (it8->ch - '0'); + + if ((cmsFloat64Number) it8->inum * 10.0 + (cmsFloat64Number) digit > (cmsFloat64Number) +2147483647.0) { + ReadReal(it8, it8->inum); + it8->sy = SDNUM; + it8->dnum *= sign; + return; + } + + it8->inum = it8->inum * 10 + digit; + NextCh(it8); + } + + if (it8->ch == '.') { + + ReadReal(it8, it8->inum); + it8->sy = SDNUM; + it8->dnum *= sign; + return; + } + + it8 -> inum *= sign; + + // Special case. Numbers followed by letters are taken as identifiers + + if (isidchar(it8 ->ch)) { + + char buffer[127]; + + if (it8 ->sy == SINUM) { + + snprintf(buffer, sizeof(buffer), "%d", it8->inum); + } + else { + + snprintf(buffer, sizeof(buffer), it8 ->DoubleFormatter, it8->dnum); + } + + StringCat(it8->id, buffer); + + do { + + StringAppend(it8->id, (char) it8->ch); + + NextCh(it8); + + } while (isidchar(it8->ch)); + + it8->sy = SIDENT; + } + return; + + } + else + switch ((int) it8->ch) { + + // Eof stream markers + case '\x1a': + case 0: + case -1: + it8->sy = SEOF; + break; + + + // Next line + case '\r': + NextCh(it8); + if (it8 ->ch == '\n') + NextCh(it8); + it8->sy = SEOLN; + it8->lineno++; + break; + + case '\n': + NextCh(it8); + it8->sy = SEOLN; + it8->lineno++; + break; + + // Comment + case '#': + NextCh(it8); + while (it8->ch && it8->ch != '\n' && it8->ch != '\r') + NextCh(it8); + + it8->sy = SCOMMENT; + break; + + // String. + case '\'': + case '\"': + InStringSymbol(it8); + break; + + + default: + SynError(it8, "Unrecognized character: 0x%x", it8 ->ch); + it8->sy = SEOF; + return; + } + + } while (it8->sy == SCOMMENT); + + // Handle the include special token + + if (it8 -> sy == SINCLUDE) { + + FILECTX* FileNest; + + if(it8 -> IncludeSP >= (MAXINCLUDE-1)) { + + SynError(it8, "Too many recursion levels"); + it8->sy = SEOF; + return; + } + + InStringSymbol(it8); + if (!Check(it8, SSTRING, "Filename expected")) + { + it8->sy = SEOF; + return; + } + + FileNest = it8 -> FileStack[it8 -> IncludeSP + 1]; + if(FileNest == NULL) { + + FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX)); + if (FileNest == NULL) { + SynError(it8, "Out of memory"); + it8->sy = SEOF; + return; + } + } + + if (BuildAbsolutePath(StringPtr(it8->str), + it8->FileStack[it8->IncludeSP]->FileName, + FileNest->FileName, cmsMAX_PATH-1) == FALSE) { + SynError(it8, "File path too long"); + it8->sy = SEOF; + return; + } + + FileNest->Stream = fopen(FileNest->FileName, "rt"); + if (FileNest->Stream == NULL) { + + SynError(it8, "File %s not found", FileNest->FileName); + it8->sy = SEOF; + return; + } + it8->IncludeSP++; + + it8 ->ch = ' '; + InSymbol(it8); + } + +} + +// Checks end of line separator +static +cmsBool CheckEOLN(cmsIT8* it8) +{ + if (!Check(it8, SEOLN, "Expected separator")) return FALSE; + while (it8 -> sy == SEOLN) + InSymbol(it8); + return TRUE; + +} + +// Skip a symbol + +static +void Skip(cmsIT8* it8, SYMBOL sy) +{ + if (it8->sy == sy && it8->sy != SEOF) + InSymbol(it8); +} + + +// Skip multiple EOLN +static +void SkipEOLN(cmsIT8* it8) +{ + while (it8->sy == SEOLN) { + InSymbol(it8); + } +} + + +// Returns a string holding current value +static +cmsBool GetVal(cmsIT8* it8, char* Buffer, cmsUInt32Number max, const char* ErrorTitle) +{ + switch (it8->sy) { + + case SEOLN: // Empty value + Buffer[0]=0; + break; + case SIDENT: strncpy(Buffer, StringPtr(it8->id), max); + Buffer[max-1]=0; + break; + case SINUM: snprintf(Buffer, max, "%d", it8 -> inum); break; + case SDNUM: snprintf(Buffer, max, it8->DoubleFormatter, it8 -> dnum); break; + case SSTRING: strncpy(Buffer, StringPtr(it8->str), max); + Buffer[max-1] = 0; + break; + + + default: + return SynError(it8, "%s", ErrorTitle); + } + + Buffer[max] = 0; + return TRUE; +} + +// ---------------------------------------------------------- Table + +static +TABLE* GetTable(cmsIT8* it8) +{ + if ((it8 -> nTable >= it8 ->TablesCount)) { + + SynError(it8, "Table %d out of sequence", it8 -> nTable); + return it8 -> Tab; + } + + return it8 ->Tab + it8 ->nTable; +} + +// ---------------------------------------------------------- Memory management + + +// Frees an allocator and owned memory +void CMSEXPORT cmsIT8Free(cmsHANDLE hIT8) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + if (it8 == NULL) + return; + + if (it8->MemorySink) { + + OWNEDMEM* p; + OWNEDMEM* n; + + for (p = it8->MemorySink; p != NULL; p = n) { + + n = p->Next; + if (p->Ptr) _cmsFree(it8 ->ContextID, p->Ptr); + _cmsFree(it8 ->ContextID, p); + } + } + + if (it8->MemoryBlock) + _cmsFree(it8 ->ContextID, it8->MemoryBlock); + + _cmsFree(it8 ->ContextID, it8); +} + + +// Allocates a chunk of data, keep linked list +static +void* AllocBigBlock(cmsIT8* it8, cmsUInt32Number size) +{ + OWNEDMEM* ptr1; + void* ptr = _cmsMallocZero(it8->ContextID, size); + + if (ptr != NULL) { + + ptr1 = (OWNEDMEM*) _cmsMallocZero(it8 ->ContextID, sizeof(OWNEDMEM)); + + if (ptr1 == NULL) { + + _cmsFree(it8 ->ContextID, ptr); + return NULL; + } + + ptr1-> Ptr = ptr; + ptr1-> Next = it8 -> MemorySink; + it8 -> MemorySink = ptr1; + } + + return ptr; +} + + +// Suballocator. +static +void* AllocChunk(cmsIT8* it8, cmsUInt32Number size) +{ + cmsUInt32Number Free = it8 ->Allocator.BlockSize - it8 ->Allocator.Used; + cmsUInt8Number* ptr; + + size = _cmsALIGNMEM(size); + + if (size > Free) { + + if (it8 -> Allocator.BlockSize == 0) + + it8 -> Allocator.BlockSize = 20*1024; + else + it8 ->Allocator.BlockSize *= 2; + + if (it8 ->Allocator.BlockSize < size) + it8 ->Allocator.BlockSize = size; + + it8 ->Allocator.Used = 0; + it8 ->Allocator.Block = (cmsUInt8Number*) AllocBigBlock(it8, it8 ->Allocator.BlockSize); + } + + if (it8->Allocator.Block == NULL) + return NULL; + + ptr = it8 ->Allocator.Block + it8 ->Allocator.Used; + it8 ->Allocator.Used += size; + + return (void*) ptr; + +} + + +// Allocates a string +static +char *AllocString(cmsIT8* it8, const char* str) +{ + cmsUInt32Number Size = (cmsUInt32Number) strlen(str)+1; + char *ptr; + + + ptr = (char *) AllocChunk(it8, Size); + if (ptr) memcpy(ptr, str, Size-1); + + return ptr; +} + +// Searches through linked list + +static +cmsBool IsAvailableOnList(KEYVALUE* p, const char* Key, const char* Subkey, KEYVALUE** LastPtr) +{ + if (LastPtr) *LastPtr = p; + + for (; p != NULL; p = p->Next) { + + if (LastPtr) *LastPtr = p; + + if (*Key != '#') { // Comments are ignored + + if (cmsstrcasecmp(Key, p->Keyword) == 0) + break; + } + } + + if (p == NULL) + return FALSE; + + if (Subkey == 0) + return TRUE; + + for (; p != NULL; p = p->NextSubkey) { + + if (p ->Subkey == NULL) continue; + + if (LastPtr) *LastPtr = p; + + if (cmsstrcasecmp(Subkey, p->Subkey) == 0) + return TRUE; + } + + return FALSE; +} + + + +// Add a property into a linked list +static +KEYVALUE* AddToList(cmsIT8* it8, KEYVALUE** Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs) +{ + KEYVALUE* p; + KEYVALUE* last; + + + // Check if property is already in list + + if (IsAvailableOnList(*Head, Key, Subkey, &p)) { + + // This may work for editing properties + + // return SynError(it8, "duplicate key <%s>", Key); + } + else { + + last = p; + + // Allocate the container + p = (KEYVALUE*) AllocChunk(it8, sizeof(KEYVALUE)); + if (p == NULL) + { + SynError(it8, "AddToList: out of memory"); + return NULL; + } + + // Store name and value + p->Keyword = AllocString(it8, Key); + p->Subkey = (Subkey == NULL) ? NULL : AllocString(it8, Subkey); + + // Keep the container in our list + if (*Head == NULL) { + *Head = p; + } + else + { + if (Subkey != NULL && last != NULL) { + + last->NextSubkey = p; + + // If Subkey is not null, then last is the last property with the same key, + // but not necessarily is the last property in the list, so we need to move + // to the actual list end + while (last->Next != NULL) + last = last->Next; + } + + if (last != NULL) last->Next = p; + } + + p->Next = NULL; + p->NextSubkey = NULL; + } + + p->WriteAs = WriteAs; + + if (xValue != NULL) { + + p->Value = AllocString(it8, xValue); + } + else { + p->Value = NULL; + } + + return p; +} + +static +KEYVALUE* AddAvailableProperty(cmsIT8* it8, const char* Key, WRITEMODE as) +{ + return AddToList(it8, &it8->ValidKeywords, Key, NULL, NULL, as); +} + + +static +KEYVALUE* AddAvailableSampleID(cmsIT8* it8, const char* Key) +{ + return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED); +} + + +static +void AllocTable(cmsIT8* it8) +{ + TABLE* t; + + t = it8 ->Tab + it8 ->TablesCount; + + t->HeaderList = NULL; + t->DataFormat = NULL; + t->Data = NULL; + + it8 ->TablesCount++; +} + + +cmsInt32Number CMSEXPORT cmsIT8SetTable(cmsHANDLE IT8, cmsUInt32Number nTable) +{ + cmsIT8* it8 = (cmsIT8*) IT8; + + if (nTable >= it8 ->TablesCount) { + + if (nTable == it8 ->TablesCount) { + + AllocTable(it8); + } + else { + SynError(it8, "Table %d is out of sequence", nTable); + return -1; + } + } + + it8 ->nTable = nTable; + + return (cmsInt32Number) nTable; +} + + + +// Init an empty container +cmsHANDLE CMSEXPORT cmsIT8Alloc(cmsContext ContextID) +{ + cmsIT8* it8; + cmsUInt32Number i; + + it8 = (cmsIT8*) _cmsMallocZero(ContextID, sizeof(cmsIT8)); + if (it8 == NULL) return NULL; + + AllocTable(it8); + + it8->MemoryBlock = NULL; + it8->MemorySink = NULL; + + it8 ->nTable = 0; + + it8->ContextID = ContextID; + it8->Allocator.Used = 0; + it8->Allocator.Block = NULL; + it8->Allocator.BlockSize = 0; + + it8->ValidKeywords = NULL; + it8->ValidSampleID = NULL; + + it8 -> sy = SUNDEFINED; + it8 -> ch = ' '; + it8 -> Source = NULL; + it8 -> inum = 0; + it8 -> dnum = 0.0; + + it8->FileStack[0] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX)); + it8->IncludeSP = 0; + it8 -> lineno = 1; + + it8->id = StringAlloc(it8, MAXSTR); + it8->str = StringAlloc(it8, MAXSTR); + + strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT); + cmsIT8SetSheetType((cmsHANDLE) it8, "CGATS.17"); + + // Initialize predefined properties & data + + for (i=0; i < NUMPREDEFINEDPROPS; i++) + AddAvailableProperty(it8, PredefinedProperties[i].id, PredefinedProperties[i].as); + + for (i=0; i < NUMPREDEFINEDSAMPLEID; i++) + AddAvailableSampleID(it8, PredefinedSampleID[i]); + + + return (cmsHANDLE) it8; +} + + +const char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8) +{ + return GetTable((cmsIT8*) hIT8)->SheetType; +} + +cmsBool CMSEXPORT cmsIT8SetSheetType(cmsHANDLE hIT8, const char* Type) +{ + TABLE* t = GetTable((cmsIT8*) hIT8); + + strncpy(t ->SheetType, Type, MAXSTR-1); + t ->SheetType[MAXSTR-1] = 0; + return TRUE; +} + +cmsBool CMSEXPORT cmsIT8SetComment(cmsHANDLE hIT8, const char* Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + if (!Val) return FALSE; + if (!*Val) return FALSE; + + return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL; +} + +// Sets a property +cmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* Key, const char *Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + if (!Val) return FALSE; + if (!*Val) return FALSE; + + return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL; +} + +cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + char Buffer[1024]; + + snprintf(Buffer, 1023, it8->DoubleFormatter, Val); + + return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL; +} + +cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + char Buffer[1024]; + + snprintf(Buffer, 1023, "%u", Val); + + return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL; +} + +cmsBool CMSEXPORT cmsIT8SetPropertyUncooked(cmsHANDLE hIT8, const char* Key, const char* Buffer) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Buffer, WRITE_UNCOOKED) != NULL; +} + +cmsBool CMSEXPORT cmsIT8SetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + return AddToList(it8, &GetTable(it8)->HeaderList, Key, SubKey, Buffer, WRITE_PAIR) != NULL; +} + +// Gets a property +const char* CMSEXPORT cmsIT8GetProperty(cmsHANDLE hIT8, const char* Key) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + KEYVALUE* p; + + if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, NULL, &p)) + { + return p -> Value; + } + return NULL; +} + + +cmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp) +{ + const char *v = cmsIT8GetProperty(hIT8, cProp); + + if (v == NULL) return 0.0; + + return ParseFloatNumber(v); +} + +const char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + KEYVALUE* p; + + if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, SubKey, &p)) { + return p -> Value; + } + return NULL; +} + +// ----------------------------------------------------------------- Datasets + +// A safe atoi that returns 0 when NULL input is given +static +cmsInt32Number satoi(const char* b) +{ + int n; + + if (b == NULL) return 0; + + n = atoi(b); + if (n > 0x7fffffffL) return 0x7fffffffL; + if (n < -0x7ffffffeL) return -0x7ffffffeL; + + return (cmsInt32Number)n; +} + + +static +cmsBool AllocateDataFormat(cmsIT8* it8) +{ + TABLE* t = GetTable(it8); + + if (t -> DataFormat) return TRUE; // Already allocated + + t -> nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS")); + + if (t -> nSamples <= 0) { + + SynError(it8, "AllocateDataFormat: Unknown NUMBER_OF_FIELDS"); + return FALSE; + } + + t -> DataFormat = (char**) AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * sizeof(char *)); + if (t->DataFormat == NULL) { + + SynError(it8, "AllocateDataFormat: Unable to allocate dataFormat array"); + return FALSE; + } + + return TRUE; +} + +static +const char *GetDataFormat(cmsIT8* it8, int n) +{ + TABLE* t = GetTable(it8); + + if (t->DataFormat) + return t->DataFormat[n]; + + return NULL; +} + +static +cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label) +{ + TABLE* t = GetTable(it8); + + if (!t->DataFormat) { + + if (!AllocateDataFormat(it8)) + return FALSE; + } + + if (n > t -> nSamples) { + SynError(it8, "More than NUMBER_OF_FIELDS fields."); + return FALSE; + } + + if (t->DataFormat) { + t->DataFormat[n] = AllocString(it8, label); + if (t->DataFormat[n] == NULL) return FALSE; + } + + return TRUE; +} + + +cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample) +{ + cmsIT8* it8 = (cmsIT8*)h; + return SetDataFormat(it8, n, Sample); +} + +// Convert to binary +static +const char* satob(const char* v) +{ + cmsUInt32Number x; + static char buf[33]; + char *s = buf + 33; + + if (v == NULL) return "0"; + + x = atoi(v); + *--s = 0; + if (!x) *--s = '0'; + for (; x; x /= 2) *--s = '0' + x%2; + + return s; +} + + +static +cmsBool AllocateDataSet(cmsIT8* it8) +{ + TABLE* t = GetTable(it8); + + if (t -> Data) return TRUE; // Already allocated + + t-> nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS")); + t-> nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS")); + + if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe) + { + SynError(it8, "AllocateDataSet: too much data"); + return FALSE; + } + else { + // Some dumb analizers warns of possible overflow here, just take a look couple of lines above. + t->Data = (char**)AllocChunk(it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*)); + if (t->Data == NULL) { + + SynError(it8, "AllocateDataSet: Unable to allocate data array"); + return FALSE; + } + } + + return TRUE; +} + +static +char* GetData(cmsIT8* it8, int nSet, int nField) +{ + TABLE* t = GetTable(it8); + int nSamples = t -> nSamples; + int nPatches = t -> nPatches; + + if (nSet >= nPatches || nField >= nSamples) + return NULL; + + if (!t->Data) return NULL; + return t->Data [nSet * nSamples + nField]; +} + +static +cmsBool SetData(cmsIT8* it8, int nSet, int nField, const char *Val) +{ + TABLE* t = GetTable(it8); + + if (!t->Data) { + if (!AllocateDataSet(it8)) return FALSE; + } + + if (!t->Data) return FALSE; + + if (nSet > t -> nPatches || nSet < 0) { + + return SynError(it8, "Patch %d out of range, there are %d patches", nSet, t -> nPatches); + } + + if (nField > t ->nSamples || nField < 0) { + return SynError(it8, "Sample %d out of range, there are %d samples", nField, t ->nSamples); + + } + + t->Data [nSet * t -> nSamples + nField] = AllocString(it8, Val); + return TRUE; +} + + +// --------------------------------------------------------------- File I/O + + +// Writes a string to file +static +void WriteStr(SAVESTREAM* f, const char *str) +{ + cmsUInt32Number len; + + if (str == NULL) + str = " "; + + // Length to write + len = (cmsUInt32Number) strlen(str); + f ->Used += len; + + + if (f ->stream) { // Should I write it to a file? + + if (fwrite(str, 1, len, f->stream) != len) { + cmsSignalError(0, cmsERROR_WRITE, "Write to file error in CGATS parser"); + return; + } + + } + else { // Or to a memory block? + + if (f ->Base) { // Am I just counting the bytes? + + if (f ->Used > f ->Max) { + + cmsSignalError(0, cmsERROR_WRITE, "Write to memory overflows in CGATS parser"); + return; + } + + memmove(f ->Ptr, str, len); + f->Ptr += len; + } + + } +} + + +// Write formatted + +static +void Writef(SAVESTREAM* f, const char* frm, ...) +{ + char Buffer[4096]; + va_list args; + + va_start(args, frm); + vsnprintf(Buffer, 4095, frm, args); + Buffer[4095] = 0; + WriteStr(f, Buffer); + va_end(args); + +} + +// Writes full header +static +void WriteHeader(cmsIT8* it8, SAVESTREAM* fp) +{ + KEYVALUE* p; + TABLE* t = GetTable(it8); + + // Writes the type + WriteStr(fp, t->SheetType); + WriteStr(fp, "\n"); + + for (p = t->HeaderList; (p != NULL); p = p->Next) + { + if (*p ->Keyword == '#') { + + char* Pt; + + WriteStr(fp, "#\n# "); + for (Pt = p ->Value; *Pt; Pt++) { + + + Writef(fp, "%c", *Pt); + + if (*Pt == '\n') { + WriteStr(fp, "# "); + } + } + + WriteStr(fp, "\n#\n"); + continue; + } + + + if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL, NULL)) { + +#ifdef CMS_STRICT_CGATS + WriteStr(fp, "KEYWORD\t\""); + WriteStr(fp, p->Keyword); + WriteStr(fp, "\"\n"); +#endif + + AddAvailableProperty(it8, p->Keyword, WRITE_UNCOOKED); + } + + WriteStr(fp, p->Keyword); + if (p->Value) { + + switch (p ->WriteAs) { + + case WRITE_UNCOOKED: + Writef(fp, "\t%s", p ->Value); + break; + + case WRITE_STRINGIFY: + Writef(fp, "\t\"%s\"", p->Value ); + break; + + case WRITE_HEXADECIMAL: + Writef(fp, "\t0x%X", satoi(p ->Value)); + break; + + case WRITE_BINARY: + Writef(fp, "\t0b%s", satob(p ->Value)); + break; + + case WRITE_PAIR: + Writef(fp, "\t\"%s,%s\"", p->Subkey, p->Value); + break; + + default: SynError(it8, "Unknown write mode %d", p ->WriteAs); + return; + } + } + + WriteStr (fp, "\n"); + } + +} + + +// Writes the data format +static +void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8) +{ + int i, nSamples; + TABLE* t = GetTable(it8); + + if (!t -> DataFormat) return; + + WriteStr(fp, "BEGIN_DATA_FORMAT\n"); + WriteStr(fp, " "); + nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS")); + + for (i = 0; i < nSamples; i++) { + + WriteStr(fp, t->DataFormat[i]); + WriteStr(fp, ((i == (nSamples-1)) ? "\n" : "\t")); + } + + WriteStr (fp, "END_DATA_FORMAT\n"); +} + + +// Writes data array +static +void WriteData(SAVESTREAM* fp, cmsIT8* it8) +{ + int i, j; + TABLE* t = GetTable(it8); + + if (!t->Data) return; + + WriteStr (fp, "BEGIN_DATA\n"); + + t->nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS")); + + for (i = 0; i < t-> nPatches; i++) { + + WriteStr(fp, " "); + + for (j = 0; j < t->nSamples; j++) { + + char *ptr = t->Data[i*t->nSamples+j]; + + if (ptr == NULL) WriteStr(fp, "\"\""); + else { + // If value contains whitespace, enclose within quote + + if (strchr(ptr, ' ') != NULL) { + + WriteStr(fp, "\""); + WriteStr(fp, ptr); + WriteStr(fp, "\""); + } + else + WriteStr(fp, ptr); + } + + WriteStr(fp, ((j == (t->nSamples-1)) ? "\n" : "\t")); + } + } + WriteStr (fp, "END_DATA\n"); +} + + + +// Saves whole file +cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName) +{ + SAVESTREAM sd; + cmsUInt32Number i; + cmsIT8* it8 = (cmsIT8*) hIT8; + + memset(&sd, 0, sizeof(sd)); + + sd.stream = fopen(cFileName, "wt"); + if (!sd.stream) return FALSE; + + for (i=0; i < it8 ->TablesCount; i++) { + + cmsIT8SetTable(hIT8, i); + WriteHeader(it8, &sd); + WriteDataFormat(&sd, it8); + WriteData(&sd, it8); + } + + if (fclose(sd.stream) != 0) return FALSE; + + return TRUE; +} + + +// Saves to memory +cmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number* BytesNeeded) +{ + SAVESTREAM sd; + cmsUInt32Number i; + cmsIT8* it8 = (cmsIT8*) hIT8; + + memset(&sd, 0, sizeof(sd)); + + sd.stream = NULL; + sd.Base = (cmsUInt8Number*) MemPtr; + sd.Ptr = sd.Base; + + sd.Used = 0; + + if (sd.Base && (*BytesNeeded > 0)) { + + sd.Max = (*BytesNeeded) - 1; // Write to memory? + } + else + sd.Max = 0; // Just counting the needed bytes + + for (i=0; i < it8 ->TablesCount; i++) { + + cmsIT8SetTable(hIT8, i); + WriteHeader(it8, &sd); + WriteDataFormat(&sd, it8); + WriteData(&sd, it8); + } + + sd.Used++; // The \0 at the very end + + if (sd.Base) + *sd.Ptr = 0; + + *BytesNeeded = sd.Used; + + return TRUE; +} + + +// -------------------------------------------------------------- Higher level parsing + +static +cmsBool DataFormatSection(cmsIT8* it8) +{ + int iField = 0; + TABLE* t = GetTable(it8); + + InSymbol(it8); // Eats "BEGIN_DATA_FORMAT" + CheckEOLN(it8); + + while (it8->sy != SEND_DATA_FORMAT && + it8->sy != SEOLN && + it8->sy != SEOF && + it8->sy != SSYNERROR) { + + if (it8->sy != SIDENT) { + + return SynError(it8, "Sample type expected"); + } + + if (!SetDataFormat(it8, iField, StringPtr(it8->id))) return FALSE; + iField++; + + InSymbol(it8); + SkipEOLN(it8); + } + + SkipEOLN(it8); + Skip(it8, SEND_DATA_FORMAT); + SkipEOLN(it8); + + if (iField != t ->nSamples) { + SynError(it8, "Count mismatch. NUMBER_OF_FIELDS was %d, found %d\n", t ->nSamples, iField); + + + } + + return TRUE; +} + + + +static +cmsBool DataSection (cmsIT8* it8) +{ + int iField = 0; + int iSet = 0; + char Buffer[256]; + TABLE* t = GetTable(it8); + + InSymbol(it8); // Eats "BEGIN_DATA" + CheckEOLN(it8); + + if (!t->Data) { + if (!AllocateDataSet(it8)) return FALSE; + } + + while (it8->sy != SEND_DATA && it8->sy != SEOF) + { + if (iField >= t -> nSamples) { + iField = 0; + iSet++; + + } + + if (it8->sy != SEND_DATA && it8->sy != SEOF) { + + switch (it8->sy) + { + + // To keep very long data + case SIDENT: + if (!SetData(it8, iSet, iField, StringPtr(it8->id))) + return FALSE; + break; + + case SSTRING: + if (!SetData(it8, iSet, iField, StringPtr(it8->str))) + return FALSE; + break; + + default: + + if (!GetVal(it8, Buffer, 255, "Sample data expected")) + return FALSE; + + if (!SetData(it8, iSet, iField, Buffer)) + return FALSE; + } + + iField++; + + InSymbol(it8); + SkipEOLN(it8); + } + } + + SkipEOLN(it8); + Skip(it8, SEND_DATA); + SkipEOLN(it8); + + // Check for data completion. + + if ((iSet+1) != t -> nPatches) + return SynError(it8, "Count mismatch. NUMBER_OF_SETS was %d, found %d\n", t ->nPatches, iSet+1); + + return TRUE; +} + + + + +static +cmsBool HeaderSection(cmsIT8* it8) +{ + char VarName[MAXID]; + char Buffer[MAXSTR]; + KEYVALUE* Key; + + while (it8->sy != SEOF && + it8->sy != SSYNERROR && + it8->sy != SBEGIN_DATA_FORMAT && + it8->sy != SBEGIN_DATA) { + + + switch (it8 -> sy) { + + case SKEYWORD: + InSymbol(it8); + if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE; + if (!AddAvailableProperty(it8, Buffer, WRITE_UNCOOKED)) return FALSE; + InSymbol(it8); + break; + + + case SDATA_FORMAT_ID: + InSymbol(it8); + if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE; + if (!AddAvailableSampleID(it8, Buffer)) return FALSE; + InSymbol(it8); + break; + + + case SIDENT: + strncpy(VarName, StringPtr(it8->id), MAXID - 1); + VarName[MAXID - 1] = 0; + + if (!IsAvailableOnList(it8->ValidKeywords, VarName, NULL, &Key)) { + +#ifdef CMS_STRICT_CGATS + return SynError(it8, "Undefined keyword '%s'", VarName); +#else + Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED); + if (Key == NULL) return FALSE; +#endif + } + + InSymbol(it8); + if (!GetVal(it8, Buffer, MAXSTR - 1, "Property data expected")) return FALSE; + + if (Key->WriteAs != WRITE_PAIR) { + AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer, + (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED); + } + else { + const char *Subkey; + char *Nextkey; + if (it8->sy != SSTRING) + return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName); + + // chop the string as a list of "subkey, value" pairs, using ';' as a separator + for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey) + { + char *Value, *temp; + + // identify token pair boundary + Nextkey = (char*)strchr(Subkey, ';'); + if (Nextkey) + *Nextkey++ = '\0'; + + // for each pair, split the subkey and the value + Value = (char*)strrchr(Subkey, ','); + if (Value == NULL) + return SynError(it8, "Invalid value for property '%s'.", VarName); + + // gobble the spaces before the coma, and the coma itself + temp = Value++; + do *temp-- = '\0'; while (temp >= Subkey && *temp == ' '); + + // gobble any space at the right + temp = Value + strlen(Value) - 1; + while (*temp == ' ') *temp-- = '\0'; + + // trim the strings from the left + Subkey += strspn(Subkey, " "); + Value += strspn(Value, " "); + + if (Subkey[0] == 0 || Value[0] == 0) + return SynError(it8, "Invalid value for property '%s'.", VarName); + AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR); + } + } + + InSymbol(it8); + break; + + + case SEOLN: break; + + default: + return SynError(it8, "expected keyword or identifier"); + } + + SkipEOLN(it8); + } + + return TRUE; + +} + + +static +void ReadType(cmsIT8* it8, char* SheetTypePtr) +{ + cmsInt32Number cnt = 0; + + // First line is a very special case. + + while (isseparator(it8->ch)) + NextCh(it8); + + while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) { + + if (cnt++ < MAXSTR) + *SheetTypePtr++= (char) it8 ->ch; + NextCh(it8); + } + + *SheetTypePtr = 0; +} + + +static +cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet) +{ + char* SheetTypePtr = it8 ->Tab[0].SheetType; + + if (nosheet == 0) { + ReadType(it8, SheetTypePtr); + } + + InSymbol(it8); + + SkipEOLN(it8); + + while (it8-> sy != SEOF && + it8-> sy != SSYNERROR) { + + switch (it8 -> sy) { + + case SBEGIN_DATA_FORMAT: + if (!DataFormatSection(it8)) return FALSE; + break; + + case SBEGIN_DATA: + + if (!DataSection(it8)) return FALSE; + + if (it8 -> sy != SEOF) { + + AllocTable(it8); + it8 ->nTable = it8 ->TablesCount - 1; + + // Read sheet type if present. We only support identifier and string. + // is a type string + // anything else, is not a type string + if (nosheet == 0) { + + if (it8 ->sy == SIDENT) { + + // May be a type sheet or may be a prop value statement. We cannot use insymbol in + // this special case... + while (isseparator(it8->ch)) + NextCh(it8); + + // If a newline is found, then this is a type string + if (it8 ->ch == '\n' || it8->ch == '\r') { + + cmsIT8SetSheetType(it8, StringPtr(it8 ->id)); + InSymbol(it8); + } + else + { + // It is not. Just continue + cmsIT8SetSheetType(it8, ""); + } + } + else + // Validate quoted strings + if (it8 ->sy == SSTRING) { + cmsIT8SetSheetType(it8, StringPtr(it8 ->str)); + InSymbol(it8); + } + } + + } + break; + + case SEOLN: + SkipEOLN(it8); + break; + + default: + if (!HeaderSection(it8)) return FALSE; + } + + } + + return (it8 -> sy != SSYNERROR); +} + + + +// Init useful pointers + +static +void CookPointers(cmsIT8* it8) +{ + int idField, i; + char* Fld; + cmsUInt32Number j; + cmsUInt32Number nOldTable = it8 ->nTable; + + for (j=0; j < it8 ->TablesCount; j++) { + + TABLE* t = it8 ->Tab + j; + + t -> SampleID = 0; + it8 ->nTable = j; + + for (idField = 0; idField < t -> nSamples; idField++) + { + if (t ->DataFormat == NULL){ + SynError(it8, "Undefined DATA_FORMAT"); + return; + } + + Fld = t->DataFormat[idField]; + if (!Fld) continue; + + + if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) { + + t -> SampleID = idField; + } + + // "LABEL" is an extension. It keeps references to forward tables + + if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$') { + + // Search for table references... + for (i = 0; i < t->nPatches; i++) { + + char* Label = GetData(it8, i, idField); + + if (Label) { + + cmsUInt32Number k; + + // This is the label, search for a table containing + // this property + + for (k = 0; k < it8->TablesCount; k++) { + + TABLE* Table = it8->Tab + k; + KEYVALUE* p; + + if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) { + + // Available, keep type and table + char Buffer[256]; + + char* Type = p->Value; + int nTable = (int)k; + + snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type); + + SetData(it8, i, idField, Buffer); + } + } + + + } + + } + + + } + + } + } + + it8 ->nTable = nOldTable; +} + +// Try to infere if the file is a CGATS/IT8 file at all. Read first line +// that should be something like some printable characters plus a \n +// returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line? +static +int IsMyBlock(const cmsUInt8Number* Buffer, cmsUInt32Number n) +{ + int words = 1, space = 0, quot = 0; + cmsUInt32Number i; + + if (n < 10) return 0; // Too small + + if (n > 132) + n = 132; + + for (i = 1; i < n; i++) { + + switch(Buffer[i]) + { + case '\n': + case '\r': + return ((quot == 1) || (words > 2)) ? 0 : words; + case '\t': + case ' ': + if(!quot && !space) + space = 1; + break; + case '\"': + quot = !quot; + break; + default: + if (Buffer[i] < 32) return 0; + if (Buffer[i] > 127) return 0; + words += space; + space = 0; + break; + } + } + + return 0; +} + + +static +cmsBool IsMyFile(const char* FileName) +{ + FILE *fp; + cmsUInt32Number Size; + cmsUInt8Number Ptr[133]; + + fp = fopen(FileName, "rt"); + if (!fp) { + cmsSignalError(0, cmsERROR_FILE, "File '%s' not found", FileName); + return FALSE; + } + + Size = (cmsUInt32Number) fread(Ptr, 1, 132, fp); + + if (fclose(fp) != 0) + return FALSE; + + Ptr[Size] = '\0'; + + return IsMyBlock(Ptr, Size); +} + +// ---------------------------------------------------------- Exported routines + + +cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len) +{ + cmsHANDLE hIT8; + cmsIT8* it8; + int type; + + _cmsAssert(Ptr != NULL); + _cmsAssert(len != 0); + + type = IsMyBlock((const cmsUInt8Number*)Ptr, len); + if (type == 0) return NULL; + + hIT8 = cmsIT8Alloc(ContextID); + if (!hIT8) return NULL; + + it8 = (cmsIT8*) hIT8; + it8 ->MemoryBlock = (char*) _cmsMalloc(ContextID, len + 1); + if (it8->MemoryBlock == NULL) + { + cmsIT8Free(hIT8); + return FALSE; + } + + strncpy(it8 ->MemoryBlock, (const char*) Ptr, len); + it8 ->MemoryBlock[len] = 0; + + strncpy(it8->FileStack[0]->FileName, "", cmsMAX_PATH-1); + it8-> Source = it8 -> MemoryBlock; + + if (!ParseIT8(it8, type-1)) { + + cmsIT8Free(hIT8); + return FALSE; + } + + CookPointers(it8); + it8 ->nTable = 0; + + _cmsFree(ContextID, it8->MemoryBlock); + it8 -> MemoryBlock = NULL; + + return hIT8; + + +} + + +cmsHANDLE CMSEXPORT cmsIT8LoadFromFile(cmsContext ContextID, const char* cFileName) +{ + + cmsHANDLE hIT8; + cmsIT8* it8; + int type; + + _cmsAssert(cFileName != NULL); + + type = IsMyFile(cFileName); + if (type == 0) return NULL; + + hIT8 = cmsIT8Alloc(ContextID); + it8 = (cmsIT8*) hIT8; + if (!hIT8) return NULL; + + + it8 ->FileStack[0]->Stream = fopen(cFileName, "rt"); + + if (!it8 ->FileStack[0]->Stream) { + cmsIT8Free(hIT8); + return NULL; + } + + + strncpy(it8->FileStack[0]->FileName, cFileName, cmsMAX_PATH-1); + it8->FileStack[0]->FileName[cmsMAX_PATH-1] = 0; + + if (!ParseIT8(it8, type-1)) { + + fclose(it8 ->FileStack[0]->Stream); + cmsIT8Free(hIT8); + return NULL; + } + + CookPointers(it8); + it8 ->nTable = 0; + + if (fclose(it8 ->FileStack[0]->Stream)!= 0) { + cmsIT8Free(hIT8); + return NULL; + } + + return hIT8; + +} + +int CMSEXPORT cmsIT8EnumDataFormat(cmsHANDLE hIT8, char ***SampleNames) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + TABLE* t; + + _cmsAssert(hIT8 != NULL); + + t = GetTable(it8); + + if (SampleNames) + *SampleNames = t -> DataFormat; + return t -> nSamples; +} + + +cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyNames) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + KEYVALUE* p; + cmsUInt32Number n; + char **Props; + TABLE* t; + + _cmsAssert(hIT8 != NULL); + + t = GetTable(it8); + + // Pass#1 - count properties + + n = 0; + for (p = t -> HeaderList; p != NULL; p = p->Next) { + n++; + } + + + Props = (char**)AllocChunk(it8, sizeof(char*) * n); + if (Props != NULL) { + + // Pass#2 - Fill pointers + n = 0; + for (p = t->HeaderList; p != NULL; p = p->Next) { + Props[n++] = p->Keyword; + } + + } + *PropertyNames = Props; + + return n; +} + +cmsUInt32Number CMSEXPORT cmsIT8EnumPropertyMulti(cmsHANDLE hIT8, const char* cProp, const char ***SubpropertyNames) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + KEYVALUE *p, *tmp; + cmsUInt32Number n; + const char **Props; + TABLE* t; + + _cmsAssert(hIT8 != NULL); + + + t = GetTable(it8); + + if(!IsAvailableOnList(t->HeaderList, cProp, NULL, &p)) { + *SubpropertyNames = 0; + return 0; + } + + // Pass#1 - count properties + + n = 0; + for (tmp = p; tmp != NULL; tmp = tmp->NextSubkey) { + if(tmp->Subkey != NULL) + n++; + } + + + Props = (const char **) AllocChunk(it8, sizeof(char *) * n); + if (Props != NULL) { + + // Pass#2 - Fill pointers + n = 0; + for (tmp = p; tmp != NULL; tmp = tmp->NextSubkey) { + if (tmp->Subkey != NULL) + Props[n++] = p->Subkey; + } + } + + *SubpropertyNames = Props; + return n; +} + +static +int LocatePatch(cmsIT8* it8, const char* cPatch) +{ + int i; + const char *data; + TABLE* t = GetTable(it8); + + for (i=0; i < t-> nPatches; i++) { + + data = GetData(it8, i, t->SampleID); + + if (data != NULL) { + + if (cmsstrcasecmp(data, cPatch) == 0) + return i; + } + } + + // SynError(it8, "Couldn't find patch '%s'\n", cPatch); + return -1; +} + + +static +int LocateEmptyPatch(cmsIT8* it8) +{ + int i; + const char *data; + TABLE* t = GetTable(it8); + + for (i=0; i < t-> nPatches; i++) { + + data = GetData(it8, i, t->SampleID); + + if (data == NULL) + return i; + + } + + return -1; +} + +static +int LocateSample(cmsIT8* it8, const char* cSample) +{ + int i; + const char *fld; + TABLE* t = GetTable(it8); + + for (i=0; i < t->nSamples; i++) { + + fld = GetDataFormat(it8, i); + if (fld != NULL) { + if (cmsstrcasecmp(fld, cSample) == 0) + return i; + } + } + + return -1; + +} + + +int CMSEXPORT cmsIT8FindDataFormat(cmsHANDLE hIT8, const char* cSample) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + _cmsAssert(hIT8 != NULL); + + return LocateSample(it8, cSample); +} + + + +const char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + _cmsAssert(hIT8 != NULL); + + return GetData(it8, row, col); +} + + +cmsFloat64Number CMSEXPORT cmsIT8GetDataRowColDbl(cmsHANDLE hIT8, int row, int col) +{ + const char* Buffer; + + Buffer = cmsIT8GetDataRowCol(hIT8, row, col); + + if (Buffer == NULL) return 0.0; + + return ParseFloatNumber(Buffer); +} + + +cmsBool CMSEXPORT cmsIT8SetDataRowCol(cmsHANDLE hIT8, int row, int col, const char* Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + _cmsAssert(hIT8 != NULL); + + return SetData(it8, row, col, Val); +} + + +cmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, cmsFloat64Number Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + char Buff[256]; + + _cmsAssert(hIT8 != NULL); + + snprintf(Buff, 255, it8->DoubleFormatter, Val); + + return SetData(it8, row, col, Buff); +} + + + +const char* CMSEXPORT cmsIT8GetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + int iField, iSet; + + _cmsAssert(hIT8 != NULL); + + iField = LocateSample(it8, cSample); + if (iField < 0) { + return NULL; + } + + iSet = LocatePatch(it8, cPatch); + if (iSet < 0) { + return NULL; + } + + return GetData(it8, iSet, iField); +} + + +cmsFloat64Number CMSEXPORT cmsIT8GetDataDbl(cmsHANDLE it8, const char* cPatch, const char* cSample) +{ + const char* Buffer; + + Buffer = cmsIT8GetData(it8, cPatch, cSample); + + return ParseFloatNumber(Buffer); +} + + + +cmsBool CMSEXPORT cmsIT8SetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample, const char *Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + int iField, iSet; + TABLE* t; + + _cmsAssert(hIT8 != NULL); + + t = GetTable(it8); + + iField = LocateSample(it8, cSample); + + if (iField < 0) + return FALSE; + + if (t-> nPatches == 0) { + + if (!AllocateDataFormat(it8)) + return FALSE; + + if (!AllocateDataSet(it8)) + return FALSE; + + CookPointers(it8); + } + + if (cmsstrcasecmp(cSample, "SAMPLE_ID") == 0) { + + iSet = LocateEmptyPatch(it8); + if (iSet < 0) { + return SynError(it8, "Couldn't add more patches '%s'\n", cPatch); + } + + iField = t -> SampleID; + } + else { + iSet = LocatePatch(it8, cPatch); + if (iSet < 0) { + return FALSE; + } + } + + return SetData(it8, iSet, iField, Val); +} + + +cmsBool CMSEXPORT cmsIT8SetDataDbl(cmsHANDLE hIT8, const char* cPatch, + const char* cSample, + cmsFloat64Number Val) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + char Buff[256]; + + _cmsAssert(hIT8 != NULL); + + snprintf(Buff, 255, it8->DoubleFormatter, Val); + return cmsIT8SetData(hIT8, cPatch, cSample, Buff); +} + +// Buffer should get MAXSTR at least + +const char* CMSEXPORT cmsIT8GetPatchName(cmsHANDLE hIT8, int nPatch, char* buffer) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + TABLE* t; + char* Data; + + _cmsAssert(hIT8 != NULL); + + t = GetTable(it8); + Data = GetData(it8, nPatch, t->SampleID); + + if (!Data) return NULL; + if (!buffer) return Data; + + strncpy(buffer, Data, MAXSTR-1); + buffer[MAXSTR-1] = 0; + return buffer; +} + +int CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch) +{ + _cmsAssert(hIT8 != NULL); + + return LocatePatch((cmsIT8*)hIT8, cPatch); +} + +cmsUInt32Number CMSEXPORT cmsIT8TableCount(cmsHANDLE hIT8) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + _cmsAssert(hIT8 != NULL); + + return it8 ->TablesCount; +} + +// This handles the "LABEL" extension. +// Label, nTable, Type + +int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType) +{ + const char* cLabelFld; + char Type[256], Label[256]; + cmsUInt32Number nTable; + + _cmsAssert(hIT8 != NULL); + + if (cField != NULL && *cField == 0) + cField = "LABEL"; + + if (cField == NULL) + cField = "LABEL"; + + cLabelFld = cmsIT8GetData(hIT8, cSet, cField); + if (!cLabelFld) return -1; + + if (sscanf(cLabelFld, "%255s %u %255s", Label, &nTable, Type) != 3) + return -1; + + if (ExpectedType != NULL && *ExpectedType == 0) + ExpectedType = NULL; + + if (ExpectedType) { + + if (cmsstrcasecmp(Type, ExpectedType) != 0) return -1; + } + + return cmsIT8SetTable(hIT8, nTable); +} + + +cmsBool CMSEXPORT cmsIT8SetIndexColumn(cmsHANDLE hIT8, const char* cSample) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + int pos; + + _cmsAssert(hIT8 != NULL); + + pos = LocateSample(it8, cSample); + if(pos == -1) + return FALSE; + + it8->Tab[it8->nTable].SampleID = pos; + return TRUE; +} + + +void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter) +{ + cmsIT8* it8 = (cmsIT8*) hIT8; + + _cmsAssert(hIT8 != NULL); + + if (Formatter == NULL) + strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT); + else + strncpy(it8->DoubleFormatter, Formatter, sizeof(it8->DoubleFormatter)); + + it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0; +} + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmscnvrt.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmscnvrt.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmscnvrt.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmscnvrt.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1243 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// This is the default routine for ICC-style intents. A user may decide to override it by using a plugin. +// Supported intents are perceptual, relative colorimetric, saturation and ICC-absolute colorimetric +static +cmsPipeline* DefaultICCintents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number Intents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + +//--------------------------------------------------------------------------------- + +// This is the entry for black-preserving K-only intents, which are non-ICC. Last profile have to be a output profile +// to do the trick (no devicelinks allowed at that position) +static +cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number Intents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + +//--------------------------------------------------------------------------------- + +// This is the entry for black-plane preserving, which are non-ICC. Again, Last profile have to be a output profile +// to do the trick (no devicelinks allowed at that position) +static +cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number Intents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + +//--------------------------------------------------------------------------------- + + +// This is a structure holding implementations for all supported intents. +typedef struct _cms_intents_list { + + cmsUInt32Number Intent; + char Description[256]; + cmsIntentFn Link; + struct _cms_intents_list* Next; + +} cmsIntentsList; + + +// Built-in intents +static cmsIntentsList DefaultIntents[] = { + + { INTENT_PERCEPTUAL, "Perceptual", DefaultICCintents, &DefaultIntents[1] }, + { INTENT_RELATIVE_COLORIMETRIC, "Relative colorimetric", DefaultICCintents, &DefaultIntents[2] }, + { INTENT_SATURATION, "Saturation", DefaultICCintents, &DefaultIntents[3] }, + { INTENT_ABSOLUTE_COLORIMETRIC, "Absolute colorimetric", DefaultICCintents, &DefaultIntents[4] }, + { INTENT_PRESERVE_K_ONLY_PERCEPTUAL, "Perceptual preserving black ink", BlackPreservingKOnlyIntents, &DefaultIntents[5] }, + { INTENT_PRESERVE_K_ONLY_RELATIVE_COLORIMETRIC, "Relative colorimetric preserving black ink", BlackPreservingKOnlyIntents, &DefaultIntents[6] }, + { INTENT_PRESERVE_K_ONLY_SATURATION, "Saturation preserving black ink", BlackPreservingKOnlyIntents, &DefaultIntents[7] }, + { INTENT_PRESERVE_K_PLANE_PERCEPTUAL, "Perceptual preserving black plane", BlackPreservingKPlaneIntents, &DefaultIntents[8] }, + { INTENT_PRESERVE_K_PLANE_RELATIVE_COLORIMETRIC,"Relative colorimetric preserving black plane", BlackPreservingKPlaneIntents, &DefaultIntents[9] }, + { INTENT_PRESERVE_K_PLANE_SATURATION, "Saturation preserving black plane", BlackPreservingKPlaneIntents, NULL } +}; + + +// A pointer to the beginning of the list +_cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL }; + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginIntentsList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsIntentsPluginChunkType newHead = { NULL }; + cmsIntentsList* entry; + cmsIntentsList* Anterior = NULL; + _cmsIntentsPluginChunkType* head = (_cmsIntentsPluginChunkType*) src->chunks[IntentPlugin]; + + // Walk the list copying all nodes + for (entry = head->Intents; + entry != NULL; + entry = entry ->Next) { + + cmsIntentsList *newEntry = ( cmsIntentsList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsIntentsList)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.Intents == NULL) + newHead.Intents = newEntry; + } + + ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsIntentsPluginChunkType)); +} + +void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Copy all linked list + DupPluginIntentsList(ctx, src); + } + else { + static _cmsIntentsPluginChunkType IntentsPluginChunkType = { NULL }; + ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx ->MemPool, &IntentsPluginChunkType, sizeof(_cmsIntentsPluginChunkType)); + } +} + + +// Search the list for a suitable intent. Returns NULL if not found +static +cmsIntentsList* SearchIntent(cmsContext ContextID, cmsUInt32Number Intent) +{ + _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin); + cmsIntentsList* pt; + + for (pt = ctx -> Intents; pt != NULL; pt = pt -> Next) + if (pt ->Intent == Intent) return pt; + + for (pt = DefaultIntents; pt != NULL; pt = pt -> Next) + if (pt ->Intent == Intent) return pt; + + return NULL; +} + +// Black point compensation. Implemented as a linear scaling in XYZ. Black points +// should come relative to the white point. Fills an matrix/offset element m +// which is organized as a 4x4 matrix. +static +void ComputeBlackPointCompensation(const cmsCIEXYZ* BlackPointIn, + const cmsCIEXYZ* BlackPointOut, + cmsMAT3* m, cmsVEC3* off) +{ + cmsFloat64Number ax, ay, az, bx, by, bz, tx, ty, tz; + + // Now we need to compute a matrix plus an offset m and of such of + // [m]*bpin + off = bpout + // [m]*D50 + off = D50 + // + // This is a linear scaling in the form ax+b, where + // a = (bpout - D50) / (bpin - D50) + // b = - D50* (bpout - bpin) / (bpin - D50) + + tx = BlackPointIn->X - cmsD50_XYZ()->X; + ty = BlackPointIn->Y - cmsD50_XYZ()->Y; + tz = BlackPointIn->Z - cmsD50_XYZ()->Z; + + ax = (BlackPointOut->X - cmsD50_XYZ()->X) / tx; + ay = (BlackPointOut->Y - cmsD50_XYZ()->Y) / ty; + az = (BlackPointOut->Z - cmsD50_XYZ()->Z) / tz; + + bx = - cmsD50_XYZ()-> X * (BlackPointOut->X - BlackPointIn->X) / tx; + by = - cmsD50_XYZ()-> Y * (BlackPointOut->Y - BlackPointIn->Y) / ty; + bz = - cmsD50_XYZ()-> Z * (BlackPointOut->Z - BlackPointIn->Z) / tz; + + _cmsVEC3init(&m ->v[0], ax, 0, 0); + _cmsVEC3init(&m ->v[1], 0, ay, 0); + _cmsVEC3init(&m ->v[2], 0, 0, az); + _cmsVEC3init(off, bx, by, bz); + +} + + +// Approximate a blackbody illuminant based on CHAD information +static +cmsFloat64Number CHAD2Temp(const cmsMAT3* Chad) +{ + // Convert D50 across inverse CHAD to get the absolute white point + cmsVEC3 d, s; + cmsCIEXYZ Dest; + cmsCIExyY DestChromaticity; + cmsFloat64Number TempK; + cmsMAT3 m1, m2; + + m1 = *Chad; + if (!_cmsMAT3inverse(&m1, &m2)) return FALSE; + + s.n[VX] = cmsD50_XYZ() -> X; + s.n[VY] = cmsD50_XYZ() -> Y; + s.n[VZ] = cmsD50_XYZ() -> Z; + + _cmsMAT3eval(&d, &m2, &s); + + Dest.X = d.n[VX]; + Dest.Y = d.n[VY]; + Dest.Z = d.n[VZ]; + + cmsXYZ2xyY(&DestChromaticity, &Dest); + + if (!cmsTempFromWhitePoint(&TempK, &DestChromaticity)) + return -1.0; + + return TempK; +} + +// Compute a CHAD based on a given temperature +static + void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp) +{ + cmsCIEXYZ White; + cmsCIExyY ChromaticityOfWhite; + + cmsWhitePointFromTemp(&ChromaticityOfWhite, Temp); + cmsxyY2XYZ(&White, &ChromaticityOfWhite); + _cmsAdaptationMatrix(Chad, NULL, &White, cmsD50_XYZ()); +} + +// Join scalings to obtain relative input to absolute and then to relative output. +// Result is stored in a 3x3 matrix +static +cmsBool ComputeAbsoluteIntent(cmsFloat64Number AdaptationState, + const cmsCIEXYZ* WhitePointIn, + const cmsMAT3* ChromaticAdaptationMatrixIn, + const cmsCIEXYZ* WhitePointOut, + const cmsMAT3* ChromaticAdaptationMatrixOut, + cmsMAT3* m) +{ + cmsMAT3 Scale, m1, m2, m3, m4; + + // TODO: Follow Marc Mahy's recommendation to check if CHAD is same by using M1*M2 == M2*M1. If so, do nothing. + // TODO: Add support for ArgyllArts tag + + // Adaptation state + if (AdaptationState == 1.0) { + + // Observer is fully adapted. Keep chromatic adaptation. + // That is the standard V4 behaviour + _cmsVEC3init(&m->v[0], WhitePointIn->X / WhitePointOut->X, 0, 0); + _cmsVEC3init(&m->v[1], 0, WhitePointIn->Y / WhitePointOut->Y, 0); + _cmsVEC3init(&m->v[2], 0, 0, WhitePointIn->Z / WhitePointOut->Z); + + } + else { + + // Incomplete adaptation. This is an advanced feature. + _cmsVEC3init(&Scale.v[0], WhitePointIn->X / WhitePointOut->X, 0, 0); + _cmsVEC3init(&Scale.v[1], 0, WhitePointIn->Y / WhitePointOut->Y, 0); + _cmsVEC3init(&Scale.v[2], 0, 0, WhitePointIn->Z / WhitePointOut->Z); + + + if (AdaptationState == 0.0) { + + m1 = *ChromaticAdaptationMatrixOut; + _cmsMAT3per(&m2, &m1, &Scale); + // m2 holds CHAD from output white to D50 times abs. col. scaling + + // Observer is not adapted, undo the chromatic adaptation + _cmsMAT3per(m, &m2, ChromaticAdaptationMatrixOut); + + m3 = *ChromaticAdaptationMatrixIn; + if (!_cmsMAT3inverse(&m3, &m4)) return FALSE; + _cmsMAT3per(m, &m2, &m4); + + } else { + + cmsMAT3 MixedCHAD; + cmsFloat64Number TempSrc, TempDest, Temp; + + m1 = *ChromaticAdaptationMatrixIn; + if (!_cmsMAT3inverse(&m1, &m2)) return FALSE; + _cmsMAT3per(&m3, &m2, &Scale); + // m3 holds CHAD from input white to D50 times abs. col. scaling + + TempSrc = CHAD2Temp(ChromaticAdaptationMatrixIn); + TempDest = CHAD2Temp(ChromaticAdaptationMatrixOut); + + if (TempSrc < 0.0 || TempDest < 0.0) return FALSE; // Something went wrong + + if (_cmsMAT3isIdentity(&Scale) && fabs(TempSrc - TempDest) < 0.01) { + + _cmsMAT3identity(m); + return TRUE; + } + + Temp = (1.0 - AdaptationState) * TempDest + AdaptationState * TempSrc; + + // Get a CHAD from whatever output temperature to D50. This replaces output CHAD + Temp2CHAD(&MixedCHAD, Temp); + + _cmsMAT3per(m, &m3, &MixedCHAD); + } + + } + return TRUE; + +} + +// Just to see if m matrix should be applied +static +cmsBool IsEmptyLayer(cmsMAT3* m, cmsVEC3* off) +{ + cmsFloat64Number diff = 0; + cmsMAT3 Ident; + int i; + + if (m == NULL && off == NULL) return TRUE; // NULL is allowed as an empty layer + if (m == NULL && off != NULL) return FALSE; // This is an internal error + + _cmsMAT3identity(&Ident); + + for (i=0; i < 3*3; i++) + diff += fabs(((cmsFloat64Number*)m)[i] - ((cmsFloat64Number*)&Ident)[i]); + + for (i=0; i < 3; i++) + diff += fabs(((cmsFloat64Number*)off)[i]); + + + return (diff < 0.002); +} + + +// Compute the conversion layer +static +cmsBool ComputeConversion(cmsUInt32Number i, + cmsHPROFILE hProfiles[], + cmsUInt32Number Intent, + cmsBool BPC, + cmsFloat64Number AdaptationState, + cmsMAT3* m, cmsVEC3* off) +{ + + int k; + + // m and off are set to identity and this is detected latter on + _cmsMAT3identity(m); + _cmsVEC3init(off, 0, 0, 0); + + // If intent is abs. colorimetric, + if (Intent == INTENT_ABSOLUTE_COLORIMETRIC) { + + cmsCIEXYZ WhitePointIn, WhitePointOut; + cmsMAT3 ChromaticAdaptationMatrixIn, ChromaticAdaptationMatrixOut; + + if (!_cmsReadMediaWhitePoint(&WhitePointIn, hProfiles[i - 1])) return FALSE; + if (!_cmsReadCHAD(&ChromaticAdaptationMatrixIn, hProfiles[i - 1])) return FALSE; + + if (!_cmsReadMediaWhitePoint(&WhitePointOut, hProfiles[i])) return FALSE; + if (!_cmsReadCHAD(&ChromaticAdaptationMatrixOut, hProfiles[i])) return FALSE; + + if (!ComputeAbsoluteIntent(AdaptationState, + &WhitePointIn, &ChromaticAdaptationMatrixIn, + &WhitePointOut, &ChromaticAdaptationMatrixOut, m)) return FALSE; + + } + else { + // Rest of intents may apply BPC. + + if (BPC) { + + cmsCIEXYZ BlackPointIn = { 0, 0, 0}, BlackPointOut = { 0, 0, 0 }; + + cmsDetectBlackPoint(&BlackPointIn, hProfiles[i-1], Intent, 0); + cmsDetectDestinationBlackPoint(&BlackPointOut, hProfiles[i], Intent, 0); + + // If black points are equal, then do nothing + if (BlackPointIn.X != BlackPointOut.X || + BlackPointIn.Y != BlackPointOut.Y || + BlackPointIn.Z != BlackPointOut.Z) + ComputeBlackPointCompensation(&BlackPointIn, &BlackPointOut, m, off); + } + } + + // Offset should be adjusted because the encoding. We encode XYZ normalized to 0..1.0, + // to do that, we divide by MAX_ENCODEABLE_XZY. The conversion stage goes XYZ -> XYZ so + // we have first to convert from encoded to XYZ and then convert back to encoded. + // y = Mx + Off + // x = x'c + // y = M x'c + Off + // y = y'c; y' = y / c + // y' = (Mx'c + Off) /c = Mx' + (Off / c) + + for (k=0; k < 3; k++) { + off ->n[k] /= MAX_ENCODEABLE_XYZ; + } + + return TRUE; +} + + +// Add a conversion stage if needed. If a matrix/offset m is given, it applies to XYZ space +static +cmsBool AddConversion(cmsPipeline* Result, cmsColorSpaceSignature InPCS, cmsColorSpaceSignature OutPCS, cmsMAT3* m, cmsVEC3* off) +{ + cmsFloat64Number* m_as_dbl = (cmsFloat64Number*) m; + cmsFloat64Number* off_as_dbl = (cmsFloat64Number*) off; + + // Handle PCS mismatches. A specialized stage is added to the LUT in such case + switch (InPCS) { + + case cmsSigXYZData: // Input profile operates in XYZ + + switch (OutPCS) { + + case cmsSigXYZData: // XYZ -> XYZ + if (!IsEmptyLayer(m, off) && + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl))) + return FALSE; + break; + + case cmsSigLabData: // XYZ -> Lab + if (!IsEmptyLayer(m, off) && + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl))) + return FALSE; + if (!cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocXYZ2Lab(Result ->ContextID))) + return FALSE; + break; + + default: + return FALSE; // Colorspace mismatch + } + break; + + case cmsSigLabData: // Input profile operates in Lab + + switch (OutPCS) { + + case cmsSigXYZData: // Lab -> XYZ + + if (!cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocLab2XYZ(Result ->ContextID))) + return FALSE; + if (!IsEmptyLayer(m, off) && + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl))) + return FALSE; + break; + + case cmsSigLabData: // Lab -> Lab + + if (!IsEmptyLayer(m, off)) { + if (!cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocLab2XYZ(Result ->ContextID)) || + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl)) || + !cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocXYZ2Lab(Result ->ContextID))) + return FALSE; + } + break; + + default: + return FALSE; // Mismatch + } + break; + + // On colorspaces other than PCS, check for same space + default: + if (InPCS != OutPCS) return FALSE; + break; + } + + return TRUE; +} + + +// Is a given space compatible with another? +static +cmsBool ColorSpaceIsCompatible(cmsColorSpaceSignature a, cmsColorSpaceSignature b) +{ + // If they are same, they are compatible. + if (a == b) return TRUE; + + // Check for MCH4 substitution of CMYK + if ((a == cmsSig4colorData) && (b == cmsSigCmykData)) return TRUE; + if ((a == cmsSigCmykData) && (b == cmsSig4colorData)) return TRUE; + + // Check for XYZ/Lab. Those spaces are interchangeable as they can be computed one from other. + if ((a == cmsSigXYZData) && (b == cmsSigLabData)) return TRUE; + if ((a == cmsSigLabData) && (b == cmsSigXYZData)) return TRUE; + + return FALSE; +} + + +// Default handler for ICC-style intents +static +cmsPipeline* DefaultICCintents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number TheIntents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsPipeline* Lut = NULL; + cmsPipeline* Result; + cmsHPROFILE hProfile; + cmsMAT3 m; + cmsVEC3 off; + cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut = cmsSigLabData, CurrentColorSpace; + cmsProfileClassSignature ClassSig; + cmsUInt32Number i, Intent; + + // For safety + if (nProfiles == 0) return NULL; + + // Allocate an empty LUT for holding the result. 0 as channel count means 'undefined' + Result = cmsPipelineAlloc(ContextID, 0, 0); + if (Result == NULL) return NULL; + + CurrentColorSpace = cmsGetColorSpace(hProfiles[0]); + + for (i=0; i < nProfiles; i++) { + + cmsBool lIsDeviceLink, lIsInput; + + hProfile = hProfiles[i]; + ClassSig = cmsGetDeviceClass(hProfile); + lIsDeviceLink = (ClassSig == cmsSigLinkClass || ClassSig == cmsSigAbstractClass ); + + // First profile is used as input unless devicelink or abstract + if ((i == 0) && !lIsDeviceLink) { + lIsInput = TRUE; + } + else { + // Else use profile in the input direction if current space is not PCS + lIsInput = (CurrentColorSpace != cmsSigXYZData) && + (CurrentColorSpace != cmsSigLabData); + } + + Intent = TheIntents[i]; + + if (lIsInput || lIsDeviceLink) { + + ColorSpaceIn = cmsGetColorSpace(hProfile); + ColorSpaceOut = cmsGetPCS(hProfile); + } + else { + + ColorSpaceIn = cmsGetPCS(hProfile); + ColorSpaceOut = cmsGetColorSpace(hProfile); + } + + if (!ColorSpaceIsCompatible(ColorSpaceIn, CurrentColorSpace)) { + + cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "ColorSpace mismatch"); + goto Error; + } + + // If devicelink is found, then no custom intent is allowed and we can + // read the LUT to be applied. Settings don't apply here. + if (lIsDeviceLink || ((ClassSig == cmsSigNamedColorClass) && (nProfiles == 1))) { + + // Get the involved LUT from the profile + Lut = _cmsReadDevicelinkLUT(hProfile, Intent); + if (Lut == NULL) goto Error; + + // What about abstract profiles? + if (ClassSig == cmsSigAbstractClass && i > 0) { + if (!ComputeConversion(i, hProfiles, Intent, BPC[i], AdaptationStates[i], &m, &off)) goto Error; + } + else { + _cmsMAT3identity(&m); + _cmsVEC3init(&off, 0, 0, 0); + } + + + if (!AddConversion(Result, CurrentColorSpace, ColorSpaceIn, &m, &off)) goto Error; + + } + else { + + if (lIsInput) { + // Input direction means non-pcs connection, so proceed like devicelinks + Lut = _cmsReadInputLUT(hProfile, Intent); + if (Lut == NULL) goto Error; + } + else { + + // Output direction means PCS connection. Intent may apply here + Lut = _cmsReadOutputLUT(hProfile, Intent); + if (Lut == NULL) goto Error; + + + if (!ComputeConversion(i, hProfiles, Intent, BPC[i], AdaptationStates[i], &m, &off)) goto Error; + if (!AddConversion(Result, CurrentColorSpace, ColorSpaceIn, &m, &off)) goto Error; + + } + } + + // Concatenate to the output LUT + if (!cmsPipelineCat(Result, Lut)) + goto Error; + + cmsPipelineFree(Lut); + Lut = NULL; + + // Update current space + CurrentColorSpace = ColorSpaceOut; + } + + // Check for non-negatives clip + if (dwFlags & cmsFLAGS_NONEGATIVES) { + + if (ColorSpaceOut == cmsSigGrayData || + ColorSpaceOut == cmsSigRgbData || + ColorSpaceOut == cmsSigCmykData) { + + cmsStage* clip = _cmsStageClipNegatives(Result->ContextID, cmsChannelsOfColorSpace(ColorSpaceOut)); + if (clip == NULL) goto Error; + + if (!cmsPipelineInsertStage(Result, cmsAT_END, clip)) + goto Error; + } + + } + + return Result; + +Error: + + if (Lut != NULL) cmsPipelineFree(Lut); + if (Result != NULL) cmsPipelineFree(Result); + return NULL; + + cmsUNUSED_PARAMETER(dwFlags); +} + + +// Wrapper for DLL calling convention +cmsPipeline* CMSEXPORT _cmsDefaultICCintents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number TheIntents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + return DefaultICCintents(ContextID, nProfiles, TheIntents, hProfiles, BPC, AdaptationStates, dwFlags); +} + +// Black preserving intents --------------------------------------------------------------------------------------------- + +// Translate black-preserving intents to ICC ones +static +cmsUInt32Number TranslateNonICCIntents(cmsUInt32Number Intent) +{ + switch (Intent) { + case INTENT_PRESERVE_K_ONLY_PERCEPTUAL: + case INTENT_PRESERVE_K_PLANE_PERCEPTUAL: + return INTENT_PERCEPTUAL; + + case INTENT_PRESERVE_K_ONLY_RELATIVE_COLORIMETRIC: + case INTENT_PRESERVE_K_PLANE_RELATIVE_COLORIMETRIC: + return INTENT_RELATIVE_COLORIMETRIC; + + case INTENT_PRESERVE_K_ONLY_SATURATION: + case INTENT_PRESERVE_K_PLANE_SATURATION: + return INTENT_SATURATION; + + default: return Intent; + } +} + +// Sampler for Black-only preserving CMYK->CMYK transforms + +typedef struct { + cmsPipeline* cmyk2cmyk; // The original transform + cmsToneCurve* KTone; // Black-to-black tone curve + +} GrayOnlyParams; + + +// Preserve black only if that is the only ink used +static +int BlackPreservingGrayOnlySampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo) +{ + GrayOnlyParams* bp = (GrayOnlyParams*) Cargo; + + // If going across black only, keep black only + if (In[0] == 0 && In[1] == 0 && In[2] == 0) { + + // TAC does not apply because it is black ink! + Out[0] = Out[1] = Out[2] = 0; + Out[3] = cmsEvalToneCurve16(bp->KTone, In[3]); + return TRUE; + } + + // Keep normal transform for other colors + bp ->cmyk2cmyk ->Eval16Fn(In, Out, bp ->cmyk2cmyk->Data); + return TRUE; +} + +// This is the entry for black-preserving K-only intents, which are non-ICC +static +cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number TheIntents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + GrayOnlyParams bp; + cmsPipeline* Result; + cmsUInt32Number ICCIntents[256]; + cmsStage* CLUT; + cmsUInt32Number i, nGridPoints; + cmsUInt32Number lastProfilePos; + cmsUInt32Number preservationProfilesCount; + cmsHPROFILE hLastProfile; + + + // Sanity check + if (nProfiles < 1 || nProfiles > 255) return NULL; + + // Translate black-preserving intents to ICC ones + for (i=0; i < nProfiles; i++) + ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]); + + + // Trim all CMYK devicelinks at the end + lastProfilePos = nProfiles - 1; + hLastProfile = hProfiles[lastProfilePos]; + + while (lastProfilePos > 1) + { + hLastProfile = hProfiles[--lastProfilePos]; + if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData || + cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass) + break; + } + + preservationProfilesCount = lastProfilePos + 1; + + // Check for non-cmyk profiles + if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData || + !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData || + cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass)) + return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags); + + // Allocate an empty LUT for holding the result + Result = cmsPipelineAlloc(ContextID, 4, 4); + if (Result == NULL) return NULL; + + memset(&bp, 0, sizeof(bp)); + + // Create a LUT holding normal ICC transform + bp.cmyk2cmyk = DefaultICCintents(ContextID, + preservationProfilesCount, + ICCIntents, + hProfiles, + BPC, + AdaptationStates, + dwFlags); + + if (bp.cmyk2cmyk == NULL) goto Error; + + // Now, compute the tone curve + bp.KTone = _cmsBuildKToneCurve(ContextID, + 4096, + preservationProfilesCount, + ICCIntents, + hProfiles, + BPC, + AdaptationStates, + dwFlags); + + if (bp.KTone == NULL) goto Error; + + + // How many gridpoints are we going to use? + nGridPoints = _cmsReasonableGridpointsByColorspace(cmsSigCmykData, dwFlags); + + // Create the CLUT. 16 bits + CLUT = cmsStageAllocCLut16bit(ContextID, nGridPoints, 4, 4, NULL); + if (CLUT == NULL) goto Error; + + // This is the one and only MPE in this LUT + if (!cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT)) + goto Error; + + // Sample it. We cannot afford pre/post linearization this time. + if (!cmsStageSampleCLut16bit(CLUT, BlackPreservingGrayOnlySampler, (void*) &bp, 0)) + goto Error; + + + // Insert possible devicelinks at the end + for (i = lastProfilePos + 1; i < nProfiles; i++) + { + cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]); + if (devlink == NULL) + goto Error; + + if (!cmsPipelineCat(Result, devlink)) + goto Error; + } + + + // Get rid of xform and tone curve + cmsPipelineFree(bp.cmyk2cmyk); + cmsFreeToneCurve(bp.KTone); + + return Result; + +Error: + + if (bp.cmyk2cmyk != NULL) cmsPipelineFree(bp.cmyk2cmyk); + if (bp.KTone != NULL) cmsFreeToneCurve(bp.KTone); + if (Result != NULL) cmsPipelineFree(Result); + return NULL; + +} + +// K Plane-preserving CMYK to CMYK ------------------------------------------------------------------------------------ + +typedef struct { + + cmsPipeline* cmyk2cmyk; // The original transform + cmsHTRANSFORM hProofOutput; // Output CMYK to Lab (last profile) + cmsHTRANSFORM cmyk2Lab; // The input chain + cmsToneCurve* KTone; // Black-to-black tone curve + cmsPipeline* LabK2cmyk; // The output profile + cmsFloat64Number MaxError; + + cmsHTRANSFORM hRoundTrip; + cmsFloat64Number MaxTAC; + + +} PreserveKPlaneParams; + + +// The CLUT will be stored at 16 bits, but calculations are performed at cmsFloat32Number precision +static +int BlackPreservingSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo) +{ + int i; + cmsFloat32Number Inf[4], Outf[4]; + cmsFloat32Number LabK[4]; + cmsFloat64Number SumCMY, SumCMYK, Error, Ratio; + cmsCIELab ColorimetricLab, BlackPreservingLab; + PreserveKPlaneParams* bp = (PreserveKPlaneParams*) Cargo; + + // Convert from 16 bits to floating point + for (i=0; i < 4; i++) + Inf[i] = (cmsFloat32Number) (In[i] / 65535.0); + + // Get the K across Tone curve + LabK[3] = cmsEvalToneCurveFloat(bp ->KTone, Inf[3]); + + // If going across black only, keep black only + if (In[0] == 0 && In[1] == 0 && In[2] == 0) { + + Out[0] = Out[1] = Out[2] = 0; + Out[3] = _cmsQuickSaturateWord(LabK[3] * 65535.0); + return TRUE; + } + + // Try the original transform, + cmsPipelineEvalFloat(Inf, Outf, bp ->cmyk2cmyk); + + // Store a copy of the floating point result into 16-bit + for (i=0; i < 4; i++) + Out[i] = _cmsQuickSaturateWord(Outf[i] * 65535.0); + + // Maybe K is already ok (mostly on K=0) + if (fabsf(Outf[3] - LabK[3]) < (3.0 / 65535.0)) { + return TRUE; + } + + // K differ, measure and keep Lab measurement for further usage + // this is done in relative colorimetric intent + cmsDoTransform(bp->hProofOutput, Out, &ColorimetricLab, 1); + + // Is not black only and the transform doesn't keep black. + // Obtain the Lab of output CMYK. After that we have Lab + K + cmsDoTransform(bp ->cmyk2Lab, Outf, LabK, 1); + + // Obtain the corresponding CMY using reverse interpolation + // (K is fixed in LabK[3]) + if (!cmsPipelineEvalReverseFloat(LabK, Outf, Outf, bp ->LabK2cmyk)) { + + // Cannot find a suitable value, so use colorimetric xform + // which is already stored in Out[] + return TRUE; + } + + // Make sure to pass through K (which now is fixed) + Outf[3] = LabK[3]; + + // Apply TAC if needed + SumCMY = (cmsFloat64Number) Outf[0] + Outf[1] + Outf[2]; + SumCMYK = SumCMY + Outf[3]; + + if (SumCMYK > bp ->MaxTAC) { + + Ratio = 1 - ((SumCMYK - bp->MaxTAC) / SumCMY); + if (Ratio < 0) + Ratio = 0; + } + else + Ratio = 1.0; + + Out[0] = _cmsQuickSaturateWord(Outf[0] * Ratio * 65535.0); // C + Out[1] = _cmsQuickSaturateWord(Outf[1] * Ratio * 65535.0); // M + Out[2] = _cmsQuickSaturateWord(Outf[2] * Ratio * 65535.0); // Y + Out[3] = _cmsQuickSaturateWord(Outf[3] * 65535.0); + + // Estimate the error (this goes 16 bits to Lab DBL) + cmsDoTransform(bp->hProofOutput, Out, &BlackPreservingLab, 1); + Error = cmsDeltaE(&ColorimetricLab, &BlackPreservingLab); + if (Error > bp -> MaxError) + bp->MaxError = Error; + + return TRUE; +} + + + +// This is the entry for black-plane preserving, which are non-ICC +static +cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number TheIntents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + PreserveKPlaneParams bp; + + cmsPipeline* Result = NULL; + cmsUInt32Number ICCIntents[256]; + cmsStage* CLUT; + cmsUInt32Number i, nGridPoints; + cmsUInt32Number lastProfilePos; + cmsUInt32Number preservationProfilesCount; + cmsHPROFILE hLastProfile; + cmsHPROFILE hLab; + + // Sanity check + if (nProfiles < 1 || nProfiles > 255) return NULL; + + // Translate black-preserving intents to ICC ones + for (i=0; i < nProfiles; i++) + ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]); + + // Trim all CMYK devicelinks at the end + lastProfilePos = nProfiles - 1; + hLastProfile = hProfiles[lastProfilePos]; + + while (lastProfilePos > 1) + { + hLastProfile = hProfiles[--lastProfilePos]; + if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData || + cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass) + break; + } + + preservationProfilesCount = lastProfilePos + 1; + + // Check for non-cmyk profiles + if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData || + !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData || + cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass)) + return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags); + + // Allocate an empty LUT for holding the result + Result = cmsPipelineAlloc(ContextID, 4, 4); + if (Result == NULL) return NULL; + + memset(&bp, 0, sizeof(bp)); + + // We need the input LUT of the last profile, assuming this one is responsible of + // black generation. This LUT will be searched in inverse order. + bp.LabK2cmyk = _cmsReadInputLUT(hLastProfile, INTENT_RELATIVE_COLORIMETRIC); + if (bp.LabK2cmyk == NULL) goto Cleanup; + + // Get total area coverage (in 0..1 domain) + bp.MaxTAC = cmsDetectTAC(hLastProfile) / 100.0; + if (bp.MaxTAC <= 0) goto Cleanup; + + + // Create a LUT holding normal ICC transform + bp.cmyk2cmyk = DefaultICCintents(ContextID, + preservationProfilesCount, + ICCIntents, + hProfiles, + BPC, + AdaptationStates, + dwFlags); + if (bp.cmyk2cmyk == NULL) goto Cleanup; + + // Now the tone curve + bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, preservationProfilesCount, + ICCIntents, + hProfiles, + BPC, + AdaptationStates, + dwFlags); + if (bp.KTone == NULL) goto Cleanup; + + // To measure the output, Last profile to Lab + hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + bp.hProofOutput = cmsCreateTransformTHR(ContextID, hLastProfile, + CHANNELS_SH(4)|BYTES_SH(2), hLab, TYPE_Lab_DBL, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE); + if ( bp.hProofOutput == NULL) goto Cleanup; + + // Same as anterior, but lab in the 0..1 range + bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hLastProfile, + FLOAT_SH(1)|CHANNELS_SH(4)|BYTES_SH(4), hLab, + FLOAT_SH(1)|CHANNELS_SH(3)|BYTES_SH(4), + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE); + if (bp.cmyk2Lab == NULL) goto Cleanup; + cmsCloseProfile(hLab); + + // Error estimation (for debug only) + bp.MaxError = 0; + + // How many gridpoints are we going to use? + nGridPoints = _cmsReasonableGridpointsByColorspace(cmsSigCmykData, dwFlags); + + + CLUT = cmsStageAllocCLut16bit(ContextID, nGridPoints, 4, 4, NULL); + if (CLUT == NULL) goto Cleanup; + + if (!cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT)) + goto Cleanup; + + cmsStageSampleCLut16bit(CLUT, BlackPreservingSampler, (void*) &bp, 0); + + // Insert possible devicelinks at the end + for (i = lastProfilePos + 1; i < nProfiles; i++) + { + cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]); + if (devlink == NULL) + goto Cleanup; + + if (!cmsPipelineCat(Result, devlink)) + goto Cleanup; + } + + +Cleanup: + + if (bp.cmyk2cmyk) cmsPipelineFree(bp.cmyk2cmyk); + if (bp.cmyk2Lab) cmsDeleteTransform(bp.cmyk2Lab); + if (bp.hProofOutput) cmsDeleteTransform(bp.hProofOutput); + + if (bp.KTone) cmsFreeToneCurve(bp.KTone); + if (bp.LabK2cmyk) cmsPipelineFree(bp.LabK2cmyk); + + return Result; +} + + + +// Link routines ------------------------------------------------------------------------------------------------------ + +// Chain several profiles into a single LUT. It just checks the parameters and then calls the handler +// for the first intent in chain. The handler may be user-defined. Is up to the handler to deal with the +// rest of intents in chain. A maximum of 255 profiles at time are supported, which is pretty reasonable. +cmsPipeline* _cmsLinkProfiles(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number TheIntents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsUInt32Number i; + cmsIntentsList* Intent; + + // Make sure a reasonable number of profiles is provided + if (nProfiles <= 0 || nProfiles > 255) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't link '%d' profiles", nProfiles); + return NULL; + } + + for (i=0; i < nProfiles; i++) { + + // Check if black point is really needed or allowed. Note that + // following Adobe's document: + // BPC does not apply to devicelink profiles, nor to abs colorimetric, + // and applies always on V4 perceptual and saturation. + + if (TheIntents[i] == INTENT_ABSOLUTE_COLORIMETRIC) + BPC[i] = FALSE; + + if (TheIntents[i] == INTENT_PERCEPTUAL || TheIntents[i] == INTENT_SATURATION) { + + // Force BPC for V4 profiles in perceptual and saturation + if (cmsGetEncodedICCversion(hProfiles[i]) >= 0x4000000) + BPC[i] = TRUE; + } + } + + // Search for a handler. The first intent in the chain defines the handler. That would + // prevent using multiple custom intents in a multiintent chain, but the behaviour of + // this case would present some issues if the custom intent tries to do things like + // preserve primaries. This solution is not perfect, but works well on most cases. + + Intent = SearchIntent(ContextID, TheIntents[0]); + if (Intent == NULL) { + cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported intent '%d'", TheIntents[0]); + return NULL; + } + + // Call the handler + return Intent ->Link(ContextID, nProfiles, TheIntents, hProfiles, BPC, AdaptationStates, dwFlags); +} + +// ------------------------------------------------------------------------------------------------- + +// Get information about available intents. nMax is the maximum space for the supplied "Codes" +// and "Descriptions" the function returns the total number of intents, which may be greater +// than nMax, although the matrices are not populated beyond this level. +cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions) +{ + _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin); + cmsIntentsList* pt; + cmsUInt32Number nIntents; + + + for (nIntents=0, pt = ctx->Intents; pt != NULL; pt = pt -> Next) + { + if (nIntents < nMax) { + if (Codes != NULL) + Codes[nIntents] = pt ->Intent; + + if (Descriptions != NULL) + Descriptions[nIntents] = pt ->Description; + } + + nIntents++; + } + + for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next) + { + if (nIntents < nMax) { + if (Codes != NULL) + Codes[nIntents] = pt ->Intent; + + if (Descriptions != NULL) + Descriptions[nIntents] = pt ->Description; + } + + nIntents++; + } + return nIntents; +} + +cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions) +{ + return cmsGetSupportedIntentsTHR(NULL, nMax, Codes, Descriptions); +} + +// The plug-in registration. User can add new intents or override default routines +cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext id, cmsPluginBase* Data) +{ + _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(id, IntentPlugin); + cmsPluginRenderingIntent* Plugin = (cmsPluginRenderingIntent*) Data; + cmsIntentsList* fl; + + // Do we have to reset the custom intents? + if (Data == NULL) { + + ctx->Intents = NULL; + return TRUE; + } + + fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList)); + if (fl == NULL) return FALSE; + + + fl ->Intent = Plugin ->Intent; + strncpy(fl ->Description, Plugin ->Description, sizeof(fl ->Description)-1); + fl ->Description[sizeof(fl ->Description)-1] = 0; + + fl ->Link = Plugin ->Link; + + fl ->Next = ctx ->Intents; + ctx ->Intents = fl; + + return TRUE; +} + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmserr.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmserr.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmserr.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmserr.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,735 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- + +#include "lcms2_internal.h" + + +// This function is here to help applications to prevent mixing lcms versions on header and shared objects. +int CMSEXPORT cmsGetEncodedCMMversion(void) +{ + return LCMS_VERSION; +} + +// I am so tired about incompatibilities on those functions that here are some replacements +// that hopefully would be fully portable. + +// compare two strings ignoring case +int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2) +{ + CMSREGISTER const unsigned char *us1 = (const unsigned char *)s1, + *us2 = (const unsigned char *)s2; + + while (toupper(*us1) == toupper(*us2++)) + if (*us1++ == '\0') + return 0; + + return (toupper(*us1) - toupper(*--us2)); +} + +// long int because C99 specifies ftell in such way (7.19.9.2) +long int CMSEXPORT cmsfilelength(FILE* f) +{ + long int p , n; + + p = ftell(f); // register current file position + if (p == -1L) + return -1L; + + if (fseek(f, 0, SEEK_END) != 0) { + return -1L; + } + + n = ftell(f); + fseek(f, p, SEEK_SET); // file position restored + + return n; +} + + +// Memory handling ------------------------------------------------------------------ +// +// This is the interface to low-level memory management routines. By default a simple +// wrapping to malloc/free/realloc is provided, although there is a limit on the max +// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent +// bogus or evil code to allocate huge blocks that otherwise lcms would never need. + +#define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*512U)) + +// User may override this behaviour by using a memory plug-in, which basically replaces +// the default memory management functions. In this case, no check is performed and it +// is up to the plug-in writer to keep in the safe side. There are only three functions +// required to be implemented: malloc, realloc and free, although the user may want to +// replace the optional mallocZero, calloc and dup as well. + +cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// ********************************************************************************* + +// This is the default memory allocation function. It does a very coarse +// check of amount of memory, just to prevent exploits +static +void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size) +{ + if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never allow over maximum + + return (void*) malloc(size); + + cmsUNUSED_PARAMETER(ContextID); +} + +// Generic allocate & zero +static +void* _cmsMallocZeroDefaultFn(cmsContext ContextID, cmsUInt32Number size) +{ + void *pt = _cmsMalloc(ContextID, size); + if (pt == NULL) return NULL; + + memset(pt, 0, size); + return pt; +} + + +// The default free function. The only check proformed is against NULL pointers +static +void _cmsFreeDefaultFn(cmsContext ContextID, void *Ptr) +{ + // free(NULL) is defined a no-op by C99, therefore it is safe to + // avoid the check, but it is here just in case... + + if (Ptr) free(Ptr); + + cmsUNUSED_PARAMETER(ContextID); +} + +// The default realloc function. Again it checks for exploits. If Ptr is NULL, +// realloc behaves the same way as malloc and allocates a new block of size bytes. +static +void* _cmsReallocDefaultFn(cmsContext ContextID, void* Ptr, cmsUInt32Number size) +{ + + if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never realloc over 512Mb + + return realloc(Ptr, size); + + cmsUNUSED_PARAMETER(ContextID); +} + + +// The default calloc function. Allocates an array of num elements, each one of size bytes +// all memory is initialized to zero. +static +void* _cmsCallocDefaultFn(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size) +{ + cmsUInt32Number Total = num * size; + + // Preserve calloc behaviour + if (Total == 0) return NULL; + + // Safe check for overflow. + if (num >= UINT_MAX / size) return NULL; + + // Check for overflow + if (Total < num || Total < size) { + return NULL; + } + + if (Total > MAX_MEMORY_FOR_ALLOC) return NULL; // Never alloc over 512Mb + + return _cmsMallocZero(ContextID, Total); +} + +// Generic block duplication +static +void* _cmsDupDefaultFn(cmsContext ContextID, const void* Org, cmsUInt32Number size) +{ + void* mem; + + if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never dup over 512Mb + + mem = _cmsMalloc(ContextID, size); + + if (mem != NULL && Org != NULL) + memmove(mem, Org, size); + + return mem; +} + + +// Pointers to memory manager functions in Context0 +_cmsMemPluginChunkType _cmsMemPluginChunk = { _cmsMallocDefaultFn, _cmsMallocZeroDefaultFn, _cmsFreeDefaultFn, + _cmsReallocDefaultFn, _cmsCallocDefaultFn, _cmsDupDefaultFn + }; + + +// Reset and duplicate memory manager +void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src) +{ + _cmsAssert(ctx != NULL); + + if (src != NULL) { + + // Duplicate + ctx ->chunks[MemPlugin] = _cmsSubAllocDup(ctx ->MemPool, src ->chunks[MemPlugin], sizeof(_cmsMemPluginChunkType)); + } + else { + + // To reset it, we use the default allocators, which cannot be overridden + ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager; + } +} + +// Auxiliary to fill memory management functions from plugin (or context 0 defaults) +void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr) +{ + if (Plugin == NULL) { + + memcpy(ptr, &_cmsMemPluginChunk, sizeof(_cmsMemPluginChunk)); + } + else { + + ptr ->MallocPtr = Plugin -> MallocPtr; + ptr ->FreePtr = Plugin -> FreePtr; + ptr ->ReallocPtr = Plugin -> ReallocPtr; + + // Make sure we revert to defaults + ptr ->MallocZeroPtr= _cmsMallocZeroDefaultFn; + ptr ->CallocPtr = _cmsCallocDefaultFn; + ptr ->DupPtr = _cmsDupDefaultFn; + + if (Plugin ->MallocZeroPtr != NULL) ptr ->MallocZeroPtr = Plugin -> MallocZeroPtr; + if (Plugin ->CallocPtr != NULL) ptr ->CallocPtr = Plugin -> CallocPtr; + if (Plugin ->DupPtr != NULL) ptr ->DupPtr = Plugin -> DupPtr; + + } +} + + +// Plug-in replacement entry +cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data) +{ + cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data; + _cmsMemPluginChunkType* ptr; + + // NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure. + // Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the + // context internal data should be malloce'd by using those functions. + if (Data == NULL) { + + struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID; + + // Return to the default allocators + if (ContextID != NULL) { + ctx->chunks[MemPlugin] = (void*) &ctx->DefaultMemoryManager; + } + return TRUE; + } + + // Check for required callbacks + if (Plugin -> MallocPtr == NULL || + Plugin -> FreePtr == NULL || + Plugin -> ReallocPtr == NULL) return FALSE; + + // Set replacement functions + ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + if (ptr == NULL) + return FALSE; + + _cmsInstallAllocFunctions(Plugin, ptr); + return TRUE; +} + +// Generic allocate +void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size) +{ + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr ->MallocPtr(ContextID, size); +} + +// Generic allocate & zero +void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size) +{ + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr->MallocZeroPtr(ContextID, size); +} + +// Generic calloc +void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size) +{ + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr->CallocPtr(ContextID, num, size); +} + +// Generic reallocate +void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size) +{ + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr->ReallocPtr(ContextID, Ptr, size); +} + +// Generic free memory +void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr) +{ + if (Ptr != NULL) { + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + ptr ->FreePtr(ContextID, Ptr); + } +} + +// Generic block duplication +void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size) +{ + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr ->DupPtr(ContextID, Org, size); +} + +// ******************************************************************************************** + +// Sub allocation takes care of many pointers of small size. The memory allocated in +// this way have be freed at once. Next function allocates a single chunk for linked list +// I prefer this method over realloc due to the big impact on xput realloc may have if +// memory is being swapped to disk. This approach is safer (although that may not be true on all platforms) +static +_cmsSubAllocator_chunk* _cmsCreateSubAllocChunk(cmsContext ContextID, cmsUInt32Number Initial) +{ + _cmsSubAllocator_chunk* chunk; + + // 20K by default + if (Initial == 0) + Initial = 20*1024; + + // Create the container + chunk = (_cmsSubAllocator_chunk*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator_chunk)); + if (chunk == NULL) return NULL; + + // Initialize values + chunk ->Block = (cmsUInt8Number*) _cmsMalloc(ContextID, Initial); + if (chunk ->Block == NULL) { + + // Something went wrong + _cmsFree(ContextID, chunk); + return NULL; + } + + chunk ->BlockSize = Initial; + chunk ->Used = 0; + chunk ->next = NULL; + + return chunk; +} + +// The suballocated is nothing but a pointer to the first element in the list. We also keep +// the thread ID in this structure. +_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial) +{ + _cmsSubAllocator* sub; + + // Create the container + sub = (_cmsSubAllocator*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator)); + if (sub == NULL) return NULL; + + sub ->ContextID = ContextID; + + sub ->h = _cmsCreateSubAllocChunk(ContextID, Initial); + if (sub ->h == NULL) { + _cmsFree(ContextID, sub); + return NULL; + } + + return sub; +} + + +// Get rid of whole linked list +void _cmsSubAllocDestroy(_cmsSubAllocator* sub) +{ + _cmsSubAllocator_chunk *chunk, *n; + + for (chunk = sub ->h; chunk != NULL; chunk = n) { + + n = chunk->next; + if (chunk->Block != NULL) _cmsFree(sub ->ContextID, chunk->Block); + _cmsFree(sub ->ContextID, chunk); + } + + // Free the header + _cmsFree(sub ->ContextID, sub); +} + + +// Get a pointer to small memory block. +void* _cmsSubAlloc(_cmsSubAllocator* sub, cmsUInt32Number size) +{ + cmsUInt32Number Free = sub -> h ->BlockSize - sub -> h -> Used; + cmsUInt8Number* ptr; + + size = _cmsALIGNMEM(size); + + // Check for memory. If there is no room, allocate a new chunk of double memory size. + if (size > Free) { + + _cmsSubAllocator_chunk* chunk; + cmsUInt32Number newSize; + + newSize = sub -> h ->BlockSize * 2; + if (newSize < size) newSize = size; + + chunk = _cmsCreateSubAllocChunk(sub -> ContextID, newSize); + if (chunk == NULL) return NULL; + + // Link list + chunk ->next = sub ->h; + sub ->h = chunk; + + } + + ptr = sub -> h ->Block + sub -> h ->Used; + sub -> h -> Used += size; + + return (void*) ptr; +} + +// Duplicate in pool +void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size) +{ + void *NewPtr; + + // Dup of null pointer is also NULL + if (ptr == NULL) + return NULL; + + NewPtr = _cmsSubAlloc(s, size); + + if (ptr != NULL && NewPtr != NULL) { + memcpy(NewPtr, ptr, size); + } + + return NewPtr; +} + + + +// Error logging ****************************************************************** + +// There is no error handling at all. When a function fails, it returns proper value. +// For example, all create functions does return NULL on failure. Other return FALSE +// It may be interesting, for the developer, to know why the function is failing. +// for that reason, lcms2 does offer a logging function. This function does receive +// a ENGLISH string with some clues on what is going wrong. You can show this +// info to the end user, or just create some sort of log. +// The logging function should NOT terminate the program, as this obviously can leave +// resources. It is the programmer's responsibility to check each function return code +// to make sure it didn't fail. + +// Error messages are limited to MAX_ERROR_MESSAGE_LEN + +#define MAX_ERROR_MESSAGE_LEN 1024 + +// --------------------------------------------------------------------------------------------------------- + +// This is our default log error +static void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text); + +// Context0 storage, which is global +_cmsLogErrorChunkType _cmsLogErrorChunk = { DefaultLogErrorHandlerFunction }; + +// Allocates and inits error logger container for a given context. If src is NULL, only initializes the value +// to the default. Otherwise, it duplicates the value. The interface is standard across all context clients +void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsLogErrorChunkType LogErrorChunk = { DefaultLogErrorHandlerFunction }; + void* from; + + if (src != NULL) { + from = src ->chunks[Logger]; + } + else { + from = &LogErrorChunk; + } + + ctx ->chunks[Logger] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsLogErrorChunkType)); +} + +// The default error logger does nothing. +static +void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text) +{ + // fprintf(stderr, "[lcms]: %s\n", Text); + // fflush(stderr); + + cmsUNUSED_PARAMETER(ContextID); + cmsUNUSED_PARAMETER(ErrorCode); + cmsUNUSED_PARAMETER(Text); +} + +// Change log error, context based +void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn) +{ + _cmsLogErrorChunkType* lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger); + + if (lhg != NULL) { + + if (Fn == NULL) + lhg -> LogErrorHandler = DefaultLogErrorHandlerFunction; + else + lhg -> LogErrorHandler = Fn; + } +} + +// Change log error, legacy +void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn) +{ + cmsSetLogErrorHandlerTHR(NULL, Fn); +} + +// Log an error +// ErrorText is a text holding an english description of error. +void CMSEXPORT cmsSignalError(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *ErrorText, ...) +{ + va_list args; + char Buffer[MAX_ERROR_MESSAGE_LEN]; + _cmsLogErrorChunkType* lhg; + + + va_start(args, ErrorText); + vsnprintf(Buffer, MAX_ERROR_MESSAGE_LEN-1, ErrorText, args); + va_end(args); + + // Check for the context, if specified go there. If not, go for the global + lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger); + if (lhg ->LogErrorHandler) { + lhg ->LogErrorHandler(ContextID, ErrorCode, Buffer); + } +} + +// Utility function to print signatures +void _cmsTagSignature2String(char String[5], cmsTagSignature sig) +{ + cmsUInt32Number be; + + // Convert to big endian + be = _cmsAdjustEndianess32((cmsUInt32Number) sig); + + // Move chars + memmove(String, &be, 4); + + // Make sure of terminator + String[4] = 0; +} + +//-------------------------------------------------------------------------------------------------- + + +static +void* defMtxCreate(cmsContext id) +{ + _cmsMutex* ptr_mutex = (_cmsMutex*) _cmsMalloc(id, sizeof(_cmsMutex)); + _cmsInitMutexPrimitive(ptr_mutex); + return (void*) ptr_mutex; +} + +static +void defMtxDestroy(cmsContext id, void* mtx) +{ + _cmsDestroyMutexPrimitive((_cmsMutex *) mtx); + _cmsFree(id, mtx); +} + +static +cmsBool defMtxLock(cmsContext id, void* mtx) +{ + cmsUNUSED_PARAMETER(id); + return _cmsLockPrimitive((_cmsMutex *) mtx) == 0; +} + +static +void defMtxUnlock(cmsContext id, void* mtx) +{ + cmsUNUSED_PARAMETER(id); + _cmsUnlockPrimitive((_cmsMutex *) mtx); +} + + + +// Pointers to memory manager functions in Context0 +_cmsMutexPluginChunkType _cmsMutexPluginChunk = { defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock }; + +// Allocate and init mutex container. +void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsMutexPluginChunkType MutexChunk = {defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock }; + void* from; + + if (src != NULL) { + from = src ->chunks[MutexPlugin]; + } + else { + from = &MutexChunk; + } + + ctx ->chunks[MutexPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsMutexPluginChunkType)); +} + +// Register new ways to transform +cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + cmsPluginMutex* Plugin = (cmsPluginMutex*) Data; + _cmsMutexPluginChunkType* ctx = ( _cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (Data == NULL) { + + // No lock routines + ctx->CreateMutexPtr = NULL; + ctx->DestroyMutexPtr = NULL; + ctx->LockMutexPtr = NULL; + ctx ->UnlockMutexPtr = NULL; + return TRUE; + } + + // Factory callback is required + if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL || + Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE; + + ctx->CreateMutexPtr = Plugin->CreateMutexPtr; + ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr; + ctx ->LockMutexPtr = Plugin ->LockMutexPtr; + ctx ->UnlockMutexPtr = Plugin ->UnlockMutexPtr; + + // All is ok + return TRUE; +} + +// Generic Mutex fns +void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->CreateMutexPtr == NULL) return NULL; + + return ptr ->CreateMutexPtr(ContextID); +} + +void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->DestroyMutexPtr != NULL) { + + ptr ->DestroyMutexPtr(ContextID, mtx); + } +} + +cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->LockMutexPtr == NULL) return TRUE; + + return ptr ->LockMutexPtr(ContextID, mtx); +} + +void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->UnlockMutexPtr != NULL) { + + ptr ->UnlockMutexPtr(ContextID, mtx); + } +} + +// The global Context0 storage for parallelization plug-in + _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk = { 0 }; + +// Allocate parallelization container. +void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + void* from = src->chunks[ParallelizationPlugin]; + ctx->chunks[ParallelizationPlugin] = _cmsSubAllocDup(ctx->MemPool, from, sizeof(_cmsParallelizationPluginChunkType)); + } + else { + _cmsParallelizationPluginChunkType ParallelizationPluginChunk = { 0 }; + ctx->chunks[ParallelizationPlugin] = _cmsSubAllocDup(ctx->MemPool, &ParallelizationPluginChunk, sizeof(_cmsParallelizationPluginChunkType)); + } +} + +// Register parallel processing +cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + cmsPluginParalellization* Plugin = (cmsPluginParalellization*)Data; + _cmsParallelizationPluginChunkType* ctx = (_cmsParallelizationPluginChunkType*)_cmsContextGetClientChunk(ContextID, ParallelizationPlugin); + + if (Data == NULL) { + + // No parallelization routines + ctx->MaxWorkers = 0; + ctx->WorkerFlags = 0; + ctx->SchedulerFn = NULL; + return TRUE; + } + + // callback is required + if (Plugin->SchedulerFn == NULL) return FALSE; + + ctx->MaxWorkers = Plugin->MaxWorkers; + ctx->WorkerFlags = Plugin->WorkerFlags; + ctx->SchedulerFn = Plugin->SchedulerFn; + + // All is ok + return TRUE; +} + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsgamma.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsgamma.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsgamma.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsgamma.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1532 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// +#include "lcms2_internal.h" + +// Tone curves are powerful constructs that can contain curves specified in diverse ways. +// The curve is stored in segments, where each segment can be sampled or specified by parameters. +// a 16.bit simplification of the *whole* curve is kept for optimization purposes. For float operation, +// each segment is evaluated separately. Plug-ins may be used to define new parametric schemes, +// each plug-in may define up to MAX_TYPES_IN_LCMS_PLUGIN functions types. For defining a function, +// the plug-in should provide the type id, how many parameters each type has, and a pointer to +// a procedure that evaluates the function. In the case of reverse evaluation, the evaluator will +// be called with the type id as a negative value, and a sampled version of the reversed curve +// will be built. + +// ----------------------------------------------------------------- Implementation +// Maxim number of nodes +#define MAX_NODES_IN_CURVE 4097 +#define MINUS_INF (-1E22F) +#define PLUS_INF (+1E22F) + +// The list of supported parametric curves +typedef struct _cmsParametricCurvesCollection_st { + + cmsUInt32Number nFunctions; // Number of supported functions in this chunk + cmsInt32Number FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types + cmsUInt32Number ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function + + cmsParametricCurveEvaluator Evaluator; // The evaluator + + struct _cmsParametricCurvesCollection_st* Next; // Next in list + +} _cmsParametricCurvesCollection; + +// This is the default (built-in) evaluator +static cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R); + +// The built-in list +static _cmsParametricCurvesCollection DefaultCurves = { + 10, // # of curve types + { 1, 2, 3, 4, 5, 6, 7, 8, 108, 109 }, // Parametric curve ID + { 1, 3, 4, 5, 7, 4, 5, 5, 1, 1 }, // Parameters by type + DefaultEvalParametricFn, // Evaluator + NULL // Next in chain +}; + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginCurvesList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsCurvesPluginChunkType newHead = { NULL }; + _cmsParametricCurvesCollection* entry; + _cmsParametricCurvesCollection* Anterior = NULL; + _cmsCurvesPluginChunkType* head = (_cmsCurvesPluginChunkType*) src->chunks[CurvesPlugin]; + + _cmsAssert(head != NULL); + + // Walk the list copying all nodes + for (entry = head->ParametricCurves; + entry != NULL; + entry = entry ->Next) { + + _cmsParametricCurvesCollection *newEntry = ( _cmsParametricCurvesCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsParametricCurvesCollection)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.ParametricCurves == NULL) + newHead.ParametricCurves = newEntry; + } + + ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsCurvesPluginChunkType)); +} + +// The allocator have to follow the chain +void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsAssert(ctx != NULL); + + if (src != NULL) { + + // Copy all linked list + DupPluginCurvesList(ctx, src); + } + else { + static _cmsCurvesPluginChunkType CurvesPluginChunk = { NULL }; + ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx ->MemPool, &CurvesPluginChunk, sizeof(_cmsCurvesPluginChunkType)); + } +} + + +// The linked list head +_cmsCurvesPluginChunkType _cmsCurvesPluginChunk = { NULL }; + +// As a way to install new parametric curves +cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin); + cmsPluginParametricCurves* Plugin = (cmsPluginParametricCurves*) Data; + _cmsParametricCurvesCollection* fl; + + if (Data == NULL) { + + ctx -> ParametricCurves = NULL; + return TRUE; + } + + fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsParametricCurvesCollection)); + if (fl == NULL) return FALSE; + + // Copy the parameters + fl ->Evaluator = Plugin ->Evaluator; + fl ->nFunctions = Plugin ->nFunctions; + + // Make sure no mem overwrites + if (fl ->nFunctions > MAX_TYPES_IN_LCMS_PLUGIN) + fl ->nFunctions = MAX_TYPES_IN_LCMS_PLUGIN; + + // Copy the data + memmove(fl->FunctionTypes, Plugin ->FunctionTypes, fl->nFunctions * sizeof(cmsUInt32Number)); + memmove(fl->ParameterCount, Plugin ->ParameterCount, fl->nFunctions * sizeof(cmsUInt32Number)); + + // Keep linked list + fl ->Next = ctx->ParametricCurves; + ctx->ParametricCurves = fl; + + // All is ok + return TRUE; +} + + +// Search in type list, return position or -1 if not found +static +int IsInSet(int Type, _cmsParametricCurvesCollection* c) +{ + int i; + + for (i=0; i < (int) c ->nFunctions; i++) + if (abs(Type) == c ->FunctionTypes[i]) return i; + + return -1; +} + + +// Search for the collection which contains a specific type +static +_cmsParametricCurvesCollection *GetParametricCurveByType(cmsContext ContextID, int Type, int* index) +{ + _cmsParametricCurvesCollection* c; + int Position; + _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin); + + for (c = ctx->ParametricCurves; c != NULL; c = c ->Next) { + + Position = IsInSet(Type, c); + + if (Position != -1) { + if (index != NULL) + *index = Position; + return c; + } + } + // If none found, revert for defaults + for (c = &DefaultCurves; c != NULL; c = c ->Next) { + + Position = IsInSet(Type, c); + + if (Position != -1) { + if (index != NULL) + *index = Position; + return c; + } + } + + return NULL; +} + +// Low level allocate, which takes care of memory details. nEntries may be zero, and in this case +// no optimization curve is computed. nSegments may also be zero in the inverse case, where only the +// optimization curve is given. Both features simultaneously is an error +static +cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsUInt32Number nEntries, + cmsUInt32Number nSegments, const cmsCurveSegment* Segments, + const cmsUInt16Number* Values) +{ + cmsToneCurve* p; + cmsUInt32Number i; + + // We allow huge tables, which are then restricted for smoothing operations + if (nEntries > 65530) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve of more than 65530 entries"); + return NULL; + } + + if (nEntries == 0 && nSegments == 0) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve with zero segments and no table"); + return NULL; + } + + // Allocate all required pointers, etc. + p = (cmsToneCurve*) _cmsMallocZero(ContextID, sizeof(cmsToneCurve)); + if (!p) return NULL; + + // In this case, there are no segments + if (nSegments == 0) { + p ->Segments = NULL; + p ->Evals = NULL; + } + else { + p ->Segments = (cmsCurveSegment*) _cmsCalloc(ContextID, nSegments, sizeof(cmsCurveSegment)); + if (p ->Segments == NULL) goto Error; + + p ->Evals = (cmsParametricCurveEvaluator*) _cmsCalloc(ContextID, nSegments, sizeof(cmsParametricCurveEvaluator)); + if (p ->Evals == NULL) goto Error; + } + + p -> nSegments = nSegments; + + // This 16-bit table contains a limited precision representation of the whole curve and is kept for + // increasing xput on certain operations. + if (nEntries == 0) { + p ->Table16 = NULL; + } + else { + p ->Table16 = (cmsUInt16Number*) _cmsCalloc(ContextID, nEntries, sizeof(cmsUInt16Number)); + if (p ->Table16 == NULL) goto Error; + } + + p -> nEntries = nEntries; + + // Initialize members if requested + if (Values != NULL && (nEntries > 0)) { + + for (i=0; i < nEntries; i++) + p ->Table16[i] = Values[i]; + } + + // Initialize the segments stuff. The evaluator for each segment is located and a pointer to it + // is placed in advance to maximize performance. + if (Segments != NULL && (nSegments > 0)) { + + _cmsParametricCurvesCollection *c; + + p ->SegInterp = (cmsInterpParams**) _cmsCalloc(ContextID, nSegments, sizeof(cmsInterpParams*)); + if (p ->SegInterp == NULL) goto Error; + + for (i=0; i < nSegments; i++) { + + // Type 0 is a special marker for table-based curves + if (Segments[i].Type == 0) + p ->SegInterp[i] = _cmsComputeInterpParams(ContextID, Segments[i].nGridPoints, 1, 1, NULL, CMS_LERP_FLAGS_FLOAT); + + memmove(&p ->Segments[i], &Segments[i], sizeof(cmsCurveSegment)); + + if (Segments[i].Type == 0 && Segments[i].SampledPoints != NULL) + p ->Segments[i].SampledPoints = (cmsFloat32Number*) _cmsDupMem(ContextID, Segments[i].SampledPoints, sizeof(cmsFloat32Number) * Segments[i].nGridPoints); + else + p ->Segments[i].SampledPoints = NULL; + + + c = GetParametricCurveByType(ContextID, Segments[i].Type, NULL); + if (c != NULL) + p ->Evals[i] = c ->Evaluator; + } + } + + p ->InterpParams = _cmsComputeInterpParams(ContextID, p ->nEntries, 1, 1, p->Table16, CMS_LERP_FLAGS_16BITS); + if (p->InterpParams != NULL) + return p; + +Error: + if (p -> SegInterp) _cmsFree(ContextID, p -> SegInterp); + if (p -> Segments) _cmsFree(ContextID, p -> Segments); + if (p -> Evals) _cmsFree(ContextID, p -> Evals); + if (p ->Table16) _cmsFree(ContextID, p ->Table16); + _cmsFree(ContextID, p); + return NULL; +} + + +// Generates a sigmoidal function with desired steepness. +cmsINLINE double sigmoid_base(double k, double t) +{ + return (1.0 / (1.0 + exp(-k * t))) - 0.5; +} + +cmsINLINE double inverted_sigmoid_base(double k, double t) +{ + return -log((1.0 / (t + 0.5)) - 1.0) / k; +} + +cmsINLINE double sigmoid_factory(double k, double t) +{ + double correction = 0.5 / sigmoid_base(k, 1); + + return correction * sigmoid_base(k, 2.0 * t - 1.0) + 0.5; +} + +cmsINLINE double inverse_sigmoid_factory(double k, double t) +{ + double correction = 0.5 / sigmoid_base(k, 1); + + return (inverted_sigmoid_base(k, (t - 0.5) / correction) + 1.0) / 2.0; +} + + +// Parametric Fn using floating point +static +cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R) +{ + cmsFloat64Number e, Val, disc; + + switch (Type) { + + // X = Y ^ Gamma + case 1: + if (R < 0) { + + if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE) + Val = R; + else + Val = 0; + } + else + Val = pow(R, Params[0]); + break; + + // Type 1 Reversed: X = Y ^1/gamma + case -1: + if (R < 0) { + + if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE) + Val = R; + else + Val = 0; + } + else + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE) + Val = PLUS_INF; + else + Val = pow(R, 1 / Params[0]); + } + break; + + // CIE 122-1966 + // Y = (aX + b)^Gamma | X >= -b/a + // Y = 0 | else + case 2: + { + + if (fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + disc = -Params[2] / Params[1]; + + if (R >= disc) { + + e = Params[1] * R + Params[2]; + + if (e > 0) + Val = pow(e, Params[0]); + else + Val = 0; + } + else + Val = 0; + } + } + break; + + // Type 2 Reversed + // X = (Y ^1/g - b) / a + case -2: + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + if (R < 0) + Val = 0; + else + Val = (pow(R, 1.0 / Params[0]) - Params[2]) / Params[1]; + + if (Val < 0) + Val = 0; + } + } + break; + + + // IEC 61966-3 + // Y = (aX + b)^Gamma + c | X <= -b/a + // Y = c | else + case 3: + { + if (fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + disc = -Params[2] / Params[1]; + if (disc < 0) + disc = 0; + + if (R >= disc) { + + e = Params[1] * R + Params[2]; + + if (e > 0) + Val = pow(e, Params[0]) + Params[3]; + else + Val = 0; + } + else + Val = Params[3]; + } + } + break; + + + // Type 3 reversed + // X=((Y-c)^1/g - b)/a | (Y>=c) + // X=-b/a | (Y= Params[3]) { + + e = R - Params[3]; + + if (e > 0) + Val = (pow(e, 1 / Params[0]) - Params[2]) / Params[1]; + else + Val = 0; + } + else { + Val = -Params[2] / Params[1]; + } + } + } + break; + + + // IEC 61966-2.1 (sRGB) + // Y = (aX + b)^Gamma | X >= d + // Y = cX | X < d + case 4: + if (R >= Params[4]) { + + e = Params[1]*R + Params[2]; + + if (e > 0) + Val = pow(e, Params[0]); + else + Val = 0; + } + else + Val = R * Params[3]; + break; + + // Type 4 reversed + // X=((Y^1/g-b)/a) | Y >= (ad+b)^g + // X=Y/c | Y< (ad+b)^g + case -4: + { + + e = Params[1] * Params[4] + Params[2]; + if (e < 0) + disc = 0; + else + disc = pow(e, Params[0]); + + if (R >= disc) { + + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE) + + Val = 0; + + else + Val = (pow(R, 1.0 / Params[0]) - Params[2]) / Params[1]; + } + else { + + if (fabs(Params[3]) < MATRIX_DET_TOLERANCE) + Val = 0; + else + Val = R / Params[3]; + } + + } + break; + + + // Y = (aX + b)^Gamma + e | X >= d + // Y = cX + f | X < d + case 5: + if (R >= Params[4]) { + + e = Params[1]*R + Params[2]; + + if (e > 0) + Val = pow(e, Params[0]) + Params[5]; + else + Val = Params[5]; + } + else + Val = R*Params[3] + Params[6]; + break; + + + // Reversed type 5 + // X=((Y-e)1/g-b)/a | Y >=(ad+b)^g+e), cd+f + // X=(Y-f)/c | else + case -5: + { + disc = Params[3] * Params[4] + Params[6]; + if (R >= disc) { + + e = R - Params[5]; + if (e < 0) + Val = 0; + else + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE) + + Val = 0; + else + Val = (pow(e, 1.0 / Params[0]) - Params[2]) / Params[1]; + } + } + else { + if (fabs(Params[3]) < MATRIX_DET_TOLERANCE) + Val = 0; + else + Val = (R - Params[6]) / Params[3]; + } + + } + break; + + + // Types 6,7,8 comes from segmented curves as described in ICCSpecRevision_02_11_06_Float.pdf + // Type 6 is basically identical to type 5 without d + + // Y = (a * X + b) ^ Gamma + c + case 6: + e = Params[1]*R + Params[2]; + + if (e < 0) + Val = Params[3]; + else + Val = pow(e, Params[0]) + Params[3]; + break; + + // ((Y - c) ^1/Gamma - b) / a + case -6: + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + e = R - Params[3]; + if (e < 0) + Val = 0; + else + Val = (pow(e, 1.0 / Params[0]) - Params[2]) / Params[1]; + } + } + break; + + + // Y = a * log (b * X^Gamma + c) + d + case 7: + + e = Params[2] * pow(R, Params[0]) + Params[3]; + if (e <= 0) + Val = Params[4]; + else + Val = Params[1]*log10(e) + Params[4]; + break; + + // (Y - d) / a = log(b * X ^Gamma + c) + // pow(10, (Y-d) / a) = b * X ^Gamma + c + // pow((pow(10, (Y-d) / a) - c) / b, 1/g) = X + case -7: + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE || + fabs(Params[2]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + Val = pow((pow(10.0, (R - Params[4]) / Params[1]) - Params[3]) / Params[2], 1.0 / Params[0]); + } + } + break; + + + //Y = a * b^(c*X+d) + e + case 8: + Val = (Params[0] * pow(Params[1], Params[2] * R + Params[3]) + Params[4]); + break; + + + // Y = (log((y-e) / a) / log(b) - d ) / c + // a=0, b=1, c=2, d=3, e=4, + case -8: + + disc = R - Params[4]; + if (disc < 0) Val = 0; + else + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[2]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + Val = (log(disc / Params[0]) / log(Params[1]) - Params[3]) / Params[2]; + } + } + break; + + + // S-Shaped: (1 - (1-x)^1/g)^1/g + case 108: + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE) + Val = 0; + else + Val = pow(1.0 - pow(1 - R, 1/Params[0]), 1/Params[0]); + break; + + // y = (1 - (1-x)^1/g)^1/g + // y^g = (1 - (1-x)^1/g) + // 1 - y^g = (1-x)^1/g + // (1 - y^g)^g = 1 - x + // 1 - (1 - y^g)^g + case -108: + Val = 1 - pow(1 - pow(R, Params[0]), Params[0]); + break; + + // Sigmoidals + case 109: + Val = sigmoid_factory(Params[0], R); + break; + + case -109: + Val = inverse_sigmoid_factory(Params[0], R); + break; + + default: + // Unsupported parametric curve. Should never reach here + return 0; + } + + return Val; +} + +// Evaluate a segmented function for a single value. Return -Inf if no valid segment found . +// If fn type is 0, perform an interpolation on the table +static +cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R) +{ + int i; + cmsFloat32Number Out32; + cmsFloat64Number Out; + + for (i = (int) g->nSegments - 1; i >= 0; --i) { + + // Check for domain + if ((R > g->Segments[i].x0) && (R <= g->Segments[i].x1)) { + + // Type == 0 means segment is sampled + if (g->Segments[i].Type == 0) { + + cmsFloat32Number R1 = (cmsFloat32Number)(R - g->Segments[i].x0) / (g->Segments[i].x1 - g->Segments[i].x0); + + // Setup the table (TODO: clean that) + g->SegInterp[i]->Table = g->Segments[i].SampledPoints; + + g->SegInterp[i]->Interpolation.LerpFloat(&R1, &Out32, g->SegInterp[i]); + Out = (cmsFloat64Number) Out32; + + } + else { + Out = g->Evals[i](g->Segments[i].Type, g->Segments[i].Params, R); + } + + if (isinf(Out)) + return PLUS_INF; + else + { + if (isinf(-Out)) + return MINUS_INF; + } + + return Out; + } + } + + return MINUS_INF; +} + +// Access to estimated low-res table +cmsUInt32Number CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + return t ->nEntries; +} + +const cmsUInt16Number* CMSEXPORT cmsGetToneCurveEstimatedTable(const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + return t ->Table16; +} + + +// Create an empty gamma curve, by using tables. This specifies only the limited-precision part, and leaves the +// floating point description empty. +cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsUInt32Number nEntries, const cmsUInt16Number Values[]) +{ + return AllocateToneCurveStruct(ContextID, nEntries, 0, NULL, Values); +} + +static +cmsUInt32Number EntriesByGamma(cmsFloat64Number Gamma) +{ + if (fabs(Gamma - 1.0) < 0.001) return 2; + return 4096; +} + + +// Create a segmented gamma, fill the table +cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, + cmsUInt32Number nSegments, const cmsCurveSegment Segments[]) +{ + cmsUInt32Number i; + cmsFloat64Number R, Val; + cmsToneCurve* g; + cmsUInt32Number nGridPoints = 4096; + + _cmsAssert(Segments != NULL); + + // Optimizatin for identity curves. + if (nSegments == 1 && Segments[0].Type == 1) { + + nGridPoints = EntriesByGamma(Segments[0].Params[0]); + } + + g = AllocateToneCurveStruct(ContextID, nGridPoints, nSegments, Segments, NULL); + if (g == NULL) return NULL; + + // Once we have the floating point version, we can approximate a 16 bit table of 4096 entries + // for performance reasons. This table would normally not be used except on 8/16 bits transforms. + for (i = 0; i < nGridPoints; i++) { + + R = (cmsFloat64Number) i / (nGridPoints-1); + + Val = EvalSegmentedFn(g, R); + + // Round and saturate + g ->Table16[i] = _cmsQuickSaturateWord(Val * 65535.0); + } + + return g; +} + +// Use a segmented curve to store the floating point table +cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[]) +{ + cmsCurveSegment Seg[3]; + + // Do some housekeeping + if (nEntries == 0 || values == NULL) + return NULL; + + // A segmented tone curve should have function segments in the first and last positions + // Initialize segmented curve part up to 0 to constant value = samples[0] + Seg[0].x0 = MINUS_INF; + Seg[0].x1 = 0; + Seg[0].Type = 6; + + Seg[0].Params[0] = 1; + Seg[0].Params[1] = 0; + Seg[0].Params[2] = 0; + Seg[0].Params[3] = values[0]; + Seg[0].Params[4] = 0; + + // From zero to 1 + Seg[1].x0 = 0; + Seg[1].x1 = 1.0; + Seg[1].Type = 0; + + Seg[1].nGridPoints = nEntries; + Seg[1].SampledPoints = (cmsFloat32Number*) values; + + // Final segment is constant = lastsample + Seg[2].x0 = 1.0; + Seg[2].x1 = PLUS_INF; + Seg[2].Type = 6; + + Seg[2].Params[0] = 1; + Seg[2].Params[1] = 0; + Seg[2].Params[2] = 0; + Seg[2].Params[3] = values[nEntries-1]; + Seg[2].Params[4] = 0; + + + return cmsBuildSegmentedToneCurve(ContextID, 3, Seg); +} + +// Parametric curves +// +// Parameters goes as: Curve, a, b, c, d, e, f +// Type is the ICC type +1 +// if type is negative, then the curve is analytically inverted +cmsToneCurve* CMSEXPORT cmsBuildParametricToneCurve(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[]) +{ + cmsCurveSegment Seg0; + int Pos = 0; + cmsUInt32Number size; + _cmsParametricCurvesCollection* c = GetParametricCurveByType(ContextID, Type, &Pos); + + _cmsAssert(Params != NULL); + + if (c == NULL) { + cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type); + return NULL; + } + + memset(&Seg0, 0, sizeof(Seg0)); + + Seg0.x0 = MINUS_INF; + Seg0.x1 = PLUS_INF; + Seg0.Type = Type; + + size = c->ParameterCount[Pos] * sizeof(cmsFloat64Number); + memmove(Seg0.Params, Params, size); + + return cmsBuildSegmentedToneCurve(ContextID, 1, &Seg0); +} + + + +// Build a gamma table based on gamma constant +cmsToneCurve* CMSEXPORT cmsBuildGamma(cmsContext ContextID, cmsFloat64Number Gamma) +{ + return cmsBuildParametricToneCurve(ContextID, 1, &Gamma); +} + + +// Free all memory taken by the gamma curve +void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve) +{ + cmsContext ContextID; + + if (Curve == NULL) return; + + ContextID = Curve ->InterpParams->ContextID; + + _cmsFreeInterpParams(Curve ->InterpParams); + + if (Curve -> Table16) + _cmsFree(ContextID, Curve ->Table16); + + if (Curve ->Segments) { + + cmsUInt32Number i; + + for (i=0; i < Curve ->nSegments; i++) { + + if (Curve ->Segments[i].SampledPoints) { + _cmsFree(ContextID, Curve ->Segments[i].SampledPoints); + } + + if (Curve ->SegInterp[i] != 0) + _cmsFreeInterpParams(Curve->SegInterp[i]); + } + + _cmsFree(ContextID, Curve ->Segments); + _cmsFree(ContextID, Curve ->SegInterp); + } + + if (Curve -> Evals) + _cmsFree(ContextID, Curve -> Evals); + + _cmsFree(ContextID, Curve); +} + +// Utility function, free 3 gamma tables +void CMSEXPORT cmsFreeToneCurveTriple(cmsToneCurve* Curve[3]) +{ + + _cmsAssert(Curve != NULL); + + if (Curve[0] != NULL) cmsFreeToneCurve(Curve[0]); + if (Curve[1] != NULL) cmsFreeToneCurve(Curve[1]); + if (Curve[2] != NULL) cmsFreeToneCurve(Curve[2]); + + Curve[0] = Curve[1] = Curve[2] = NULL; +} + + +// Duplicate a gamma table +cmsToneCurve* CMSEXPORT cmsDupToneCurve(const cmsToneCurve* In) +{ + if (In == NULL) return NULL; + + return AllocateToneCurveStruct(In ->InterpParams ->ContextID, In ->nEntries, In ->nSegments, In ->Segments, In ->Table16); +} + +// Joins two curves for X and Y. Curves should be monotonic. +// We want to get +// +// y = Y^-1(X(t)) +// +cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, + const cmsToneCurve* X, + const cmsToneCurve* Y, cmsUInt32Number nResultingPoints) +{ + cmsToneCurve* out = NULL; + cmsToneCurve* Yreversed = NULL; + cmsFloat32Number t, x; + cmsFloat32Number* Res = NULL; + cmsUInt32Number i; + + + _cmsAssert(X != NULL); + _cmsAssert(Y != NULL); + + Yreversed = cmsReverseToneCurveEx(nResultingPoints, Y); + if (Yreversed == NULL) goto Error; + + Res = (cmsFloat32Number*) _cmsCalloc(ContextID, nResultingPoints, sizeof(cmsFloat32Number)); + if (Res == NULL) goto Error; + + //Iterate + for (i=0; i < nResultingPoints; i++) { + + t = (cmsFloat32Number) i / (cmsFloat32Number)(nResultingPoints-1); + x = cmsEvalToneCurveFloat(X, t); + Res[i] = cmsEvalToneCurveFloat(Yreversed, x); + } + + // Allocate space for output + out = cmsBuildTabulatedToneCurveFloat(ContextID, nResultingPoints, Res); + +Error: + + if (Res != NULL) _cmsFree(ContextID, Res); + if (Yreversed != NULL) cmsFreeToneCurve(Yreversed); + + return out; +} + + + +// Get the surrounding nodes. This is tricky on non-monotonic tables +static +int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const struct _cms_interp_struc* p) +{ + int i; + int y0, y1; + + // A 1 point table is not allowed + if (p -> Domain[0] < 1) return -1; + + // Let's see if ascending or descending. + if (LutTable[0] < LutTable[p ->Domain[0]]) { + + // Table is overall ascending + for (i = (int) p->Domain[0] - 1; i >= 0; --i) { + + y0 = LutTable[i]; + y1 = LutTable[i+1]; + + if (y0 <= y1) { // Increasing + if (In >= y0 && In <= y1) return i; + } + else + if (y1 < y0) { // Decreasing + if (In >= y1 && In <= y0) return i; + } + } + } + else { + // Table is overall descending + for (i=0; i < (int) p -> Domain[0]; i++) { + + y0 = LutTable[i]; + y1 = LutTable[i+1]; + + if (y0 <= y1) { // Increasing + if (In >= y0 && In <= y1) return i; + } + else + if (y1 < y0) { // Decreasing + if (In >= y1 && In <= y0) return i; + } + } + } + + return -1; +} + +// Reverse a gamma table +cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsUInt32Number nResultSamples, const cmsToneCurve* InCurve) +{ + cmsToneCurve *out; + cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2; + int i, j; + int Ascending; + + _cmsAssert(InCurve != NULL); + + // Try to reverse it analytically whatever possible + + if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 && + /* InCurve -> Segments[0].Type <= 5 */ + GetParametricCurveByType(InCurve ->InterpParams->ContextID, InCurve ->Segments[0].Type, NULL) != NULL) { + + return cmsBuildParametricToneCurve(InCurve ->InterpParams->ContextID, + -(InCurve -> Segments[0].Type), + InCurve -> Segments[0].Params); + } + + // Nope, reverse the table. + out = cmsBuildTabulatedToneCurve16(InCurve ->InterpParams->ContextID, nResultSamples, NULL); + if (out == NULL) + return NULL; + + // We want to know if this is an ascending or descending table + Ascending = !cmsIsToneCurveDescending(InCurve); + + // Iterate across Y axis + for (i=0; i < (int) nResultSamples; i++) { + + y = (cmsFloat64Number) i * 65535.0 / (nResultSamples - 1); + + // Find interval in which y is within. + j = GetInterval(y, InCurve->Table16, InCurve->InterpParams); + if (j >= 0) { + + + // Get limits of interval + x1 = InCurve ->Table16[j]; + x2 = InCurve ->Table16[j+1]; + + y1 = (cmsFloat64Number) (j * 65535.0) / (InCurve ->nEntries - 1); + y2 = (cmsFloat64Number) ((j+1) * 65535.0 ) / (InCurve ->nEntries - 1); + + // If collapsed, then use any + if (x1 == x2) { + + out ->Table16[i] = _cmsQuickSaturateWord(Ascending ? y2 : y1); + continue; + + } else { + + // Interpolate + a = (y2 - y1) / (x2 - x1); + b = y2 - a * x2; + } + } + + out ->Table16[i] = _cmsQuickSaturateWord(a* y + b); + } + + + return out; +} + +// Reverse a gamma table +cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma) +{ + _cmsAssert(InGamma != NULL); + + return cmsReverseToneCurveEx(4096, InGamma); +} + +// From: Eilers, P.H.C. (1994) Smoothing and interpolation with finite +// differences. in: Graphic Gems IV, Heckbert, P.S. (ed.), Academic press. +// +// Smoothing and interpolation with second differences. +// +// Input: weights (w), data (y): vector from 1 to m. +// Input: smoothing parameter (lambda), length (m). +// Output: smoothed vector (z): vector from 1 to m. + +static +cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[], + cmsFloat32Number z[], cmsFloat32Number lambda, int m) +{ + int i, i1, i2; + cmsFloat32Number *c, *d, *e; + cmsBool st; + + + c = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number)); + d = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number)); + e = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number)); + + if (c != NULL && d != NULL && e != NULL) { + + + d[1] = w[1] + lambda; + c[1] = -2 * lambda / d[1]; + e[1] = lambda /d[1]; + z[1] = w[1] * y[1]; + d[2] = w[2] + 5 * lambda - d[1] * c[1] * c[1]; + c[2] = (-4 * lambda - d[1] * c[1] * e[1]) / d[2]; + e[2] = lambda / d[2]; + z[2] = w[2] * y[2] - c[1] * z[1]; + + for (i = 3; i < m - 1; i++) { + i1 = i - 1; i2 = i - 2; + d[i]= w[i] + 6 * lambda - c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2]; + c[i] = (-4 * lambda -d[i1] * c[i1] * e[i1])/ d[i]; + e[i] = lambda / d[i]; + z[i] = w[i] * y[i] - c[i1] * z[i1] - e[i2] * z[i2]; + } + + i1 = m - 2; i2 = m - 3; + + d[m - 1] = w[m - 1] + 5 * lambda -c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2]; + c[m - 1] = (-2 * lambda - d[i1] * c[i1] * e[i1]) / d[m - 1]; + z[m - 1] = w[m - 1] * y[m - 1] - c[i1] * z[i1] - e[i2] * z[i2]; + i1 = m - 1; i2 = m - 2; + + d[m] = w[m] + lambda - c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2]; + z[m] = (w[m] * y[m] - c[i1] * z[i1] - e[i2] * z[i2]) / d[m]; + z[m - 1] = z[m - 1] / d[m - 1] - c[m - 1] * z[m]; + + for (i = m - 2; 1<= i; i--) + z[i] = z[i] / d[i] - c[i] * z[i + 1] - e[i] * z[i + 2]; + + st = TRUE; + } + else st = FALSE; + + if (c != NULL) _cmsFree(ContextID, c); + if (d != NULL) _cmsFree(ContextID, d); + if (e != NULL) _cmsFree(ContextID, e); + + return st; +} + +// Smooths a curve sampled at regular intervals. +cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda) +{ + cmsBool SuccessStatus = TRUE; + cmsFloat32Number *w, *y, *z; + cmsUInt32Number i, nItems, Zeros, Poles; + cmsBool notCheck = FALSE; + + if (Tab != NULL && Tab->InterpParams != NULL) + { + cmsContext ContextID = Tab->InterpParams->ContextID; + + if (!cmsIsToneCurveLinear(Tab)) // Only non-linear curves need smoothing + { + nItems = Tab->nEntries; + if (nItems < MAX_NODES_IN_CURVE) + { + // Allocate one more item than needed + w = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number)); + y = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number)); + z = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number)); + + if (w != NULL && y != NULL && z != NULL) // Ensure no memory allocation failure + { + memset(w, 0, (nItems + 1) * sizeof(cmsFloat32Number)); + memset(y, 0, (nItems + 1) * sizeof(cmsFloat32Number)); + memset(z, 0, (nItems + 1) * sizeof(cmsFloat32Number)); + + for (i = 0; i < nItems; i++) + { + y[i + 1] = (cmsFloat32Number)Tab->Table16[i]; + w[i + 1] = 1.0; + } + + if (lambda < 0) + { + notCheck = TRUE; + lambda = -lambda; + } + + if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems)) + { + // Do some reality - checking... + + Zeros = Poles = 0; + for (i = nItems; i > 1; --i) + { + if (z[i] == 0.) Zeros++; + if (z[i] >= 65535.) Poles++; + if (z[i] < z[i - 1]) + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic."); + SuccessStatus = notCheck; + break; + } + } + + if (SuccessStatus && Zeros > (nItems / 3)) + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros."); + SuccessStatus = notCheck; + } + + if (SuccessStatus && Poles > (nItems / 3)) + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles."); + SuccessStatus = notCheck; + } + + if (SuccessStatus) // Seems ok + { + for (i = 0; i < nItems; i++) + { + // Clamp to cmsUInt16Number + Tab->Table16[i] = _cmsQuickSaturateWord(z[i + 1]); + } + } + } + else // Could not smooth + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Function smooth2 failed."); + SuccessStatus = FALSE; + } + } + else // One or more buffers could not be allocated + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Could not allocate memory."); + SuccessStatus = FALSE; + } + + if (z != NULL) + _cmsFree(ContextID, z); + + if (y != NULL) + _cmsFree(ContextID, y); + + if (w != NULL) + _cmsFree(ContextID, w); + } + else // too many items in the table + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Too many points."); + SuccessStatus = FALSE; + } + } + } + else // Tab parameter or Tab->InterpParams is NULL + { + // Can't signal an error here since the ContextID is not known at this point + SuccessStatus = FALSE; + } + + return SuccessStatus; +} + +// Is a table linear? Do not use parametric since we cannot guarantee some weird parameters resulting +// in a linear table. This way assures it is linear in 12 bits, which should be enough in most cases. +cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve) +{ + int i; + int diff; + + _cmsAssert(Curve != NULL); + + for (i=0; i < (int) Curve ->nEntries; i++) { + + diff = abs((int) Curve->Table16[i] - (int) _cmsQuantizeVal(i, Curve ->nEntries)); + if (diff > 0x0f) + return FALSE; + } + + return TRUE; +} + +// Same, but for monotonicity +cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t) +{ + cmsUInt32Number n; + int i, last; + cmsBool lDescending; + + _cmsAssert(t != NULL); + + // Degenerated curves are monotonic? Ok, let's pass them + n = t ->nEntries; + if (n < 2) return TRUE; + + // Curve direction + lDescending = cmsIsToneCurveDescending(t); + + if (lDescending) { + + last = t ->Table16[0]; + + for (i = 1; i < (int) n; i++) { + + if (t ->Table16[i] - last > 2) // We allow some ripple + return FALSE; + else + last = t ->Table16[i]; + + } + } + else { + + last = t ->Table16[n-1]; + + for (i = (int) n - 2; i >= 0; --i) { + + if (t ->Table16[i] - last > 2) + return FALSE; + else + last = t ->Table16[i]; + + } + } + + return TRUE; +} + +// Same, but for descending tables +cmsBool CMSEXPORT cmsIsToneCurveDescending(const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + + return t ->Table16[0] > t ->Table16[t ->nEntries-1]; +} + + +// Another info fn: is out gamma table multisegment? +cmsBool CMSEXPORT cmsIsToneCurveMultisegment(const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + + return t -> nSegments > 1; +} + +cmsInt32Number CMSEXPORT cmsGetToneCurveParametricType(const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + + if (t -> nSegments != 1) return 0; + return t ->Segments[0].Type; +} + +// We need accuracy this time +cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v) +{ + _cmsAssert(Curve != NULL); + + // Check for 16 bits table. If so, this is a limited-precision tone curve + if (Curve ->nSegments == 0) { + + cmsUInt16Number In, Out; + + In = (cmsUInt16Number) _cmsQuickSaturateWord(v * 65535.0); + Out = cmsEvalToneCurve16(Curve, In); + + return (cmsFloat32Number) (Out / 65535.0); + } + + return (cmsFloat32Number) EvalSegmentedFn(Curve, v); +} + +// We need xput over here +cmsUInt16Number CMSEXPORT cmsEvalToneCurve16(const cmsToneCurve* Curve, cmsUInt16Number v) +{ + cmsUInt16Number out; + + _cmsAssert(Curve != NULL); + + Curve ->InterpParams ->Interpolation.Lerp16(&v, &out, Curve ->InterpParams); + return out; +} + + +// Least squares fitting. +// A mathematical procedure for finding the best-fitting curve to a given set of points by +// minimizing the sum of the squares of the offsets ("the residuals") of the points from the curve. +// The sum of the squares of the offsets is used instead of the offset absolute values because +// this allows the residuals to be treated as a continuous differentiable quantity. +// +// y = f(x) = x ^ g +// +// R = (yi - (xi^g)) +// R2 = (yi - (xi^g))2 +// SUM R2 = SUM (yi - (xi^g))2 +// +// dR2/dg = -2 SUM x^g log(x)(y - x^g) +// solving for dR2/dg = 0 +// +// g = 1/n * SUM(log(y) / log(x)) + +cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Number Precision) +{ + cmsFloat64Number gamma, sum, sum2; + cmsFloat64Number n, x, y, Std; + cmsUInt32Number i; + + _cmsAssert(t != NULL); + + sum = sum2 = n = 0; + + // Excluding endpoints + for (i=1; i < (MAX_NODES_IN_CURVE-1); i++) { + + x = (cmsFloat64Number) i / (MAX_NODES_IN_CURVE-1); + y = (cmsFloat64Number) cmsEvalToneCurveFloat(t, (cmsFloat32Number) x); + + // Avoid 7% on lower part to prevent + // artifacts due to linear ramps + + if (y > 0. && y < 1. && x > 0.07) { + + gamma = log(y) / log(x); + sum += gamma; + sum2 += gamma * gamma; + n++; + } + } + + // We need enough valid samples + if (n <= 1) return -1.0; + + // Take a look on SD to see if gamma isn't exponential at all + Std = sqrt((n * sum2 - sum * sum) / (n*(n-1))); + + if (Std > Precision) + return -1.0; + + return (sum / n); // The mean +} + + +// Retrieve parameters on one-segment tone curves + +cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + + if (t->nSegments != 1) return NULL; + return t->Segments[0].Params; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsgmt.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsgmt.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsgmt.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsgmt.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,688 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2021 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// Auxiliary: append a Lab identity after the given sequence of profiles +// and return the transform. Lab profile is closed, rest of profiles are kept open. +cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsHTRANSFORM xform; + cmsHPROFILE hLab; + cmsHPROFILE ProfileList[256]; + cmsBool BPCList[256]; + cmsFloat64Number AdaptationList[256]; + cmsUInt32Number IntentList[256]; + cmsUInt32Number i; + + // This is a rather big number and there is no need of dynamic memory + // since we are adding a profile, 254 + 1 = 255 and this is the limit + if (nProfiles > 254) return NULL; + + // The output space + hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + if (hLab == NULL) return NULL; + + // Create a copy of parameters + for (i=0; i < nProfiles; i++) { + + ProfileList[i] = hProfiles[i]; + BPCList[i] = BPC[i]; + AdaptationList[i] = AdaptationStates[i]; + IntentList[i] = Intents[i]; + } + + // Place Lab identity at chain's end. + ProfileList[nProfiles] = hLab; + BPCList[nProfiles] = 0; + AdaptationList[nProfiles] = 1.0; + IntentList[nProfiles] = INTENT_RELATIVE_COLORIMETRIC; + + // Create the transform + xform = cmsCreateExtendedTransform(ContextID, nProfiles + 1, ProfileList, + BPCList, + IntentList, + AdaptationList, + NULL, 0, + InputFormat, + OutputFormat, + dwFlags); + + cmsCloseProfile(hLab); + + return xform; +} + + +// Compute K -> L* relationship. Flags may include black point compensation. In this case, +// the relationship is assumed from the profile with BPC to a black point zero. +static +cmsToneCurve* ComputeKToLstar(cmsContext ContextID, + cmsUInt32Number nPoints, + cmsUInt32Number nProfiles, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsToneCurve* out = NULL; + cmsUInt32Number i; + cmsHTRANSFORM xform; + cmsCIELab Lab; + cmsFloat32Number cmyk[4]; + cmsFloat32Number* SampledPoints; + + xform = _cmsChain2Lab(ContextID, nProfiles, TYPE_CMYK_FLT, TYPE_Lab_DBL, Intents, hProfiles, BPC, AdaptationStates, dwFlags); + if (xform == NULL) return NULL; + + SampledPoints = (cmsFloat32Number*) _cmsCalloc(ContextID, nPoints, sizeof(cmsFloat32Number)); + if (SampledPoints == NULL) goto Error; + + for (i=0; i < nPoints; i++) { + + cmyk[0] = 0; + cmyk[1] = 0; + cmyk[2] = 0; + cmyk[3] = (cmsFloat32Number) ((i * 100.0) / (nPoints-1)); + + cmsDoTransform(xform, cmyk, &Lab, 1); + SampledPoints[i]= (cmsFloat32Number) (1.0 - Lab.L / 100.0); // Negate K for easier operation + } + + out = cmsBuildTabulatedToneCurveFloat(ContextID, nPoints, SampledPoints); + +Error: + + cmsDeleteTransform(xform); + if (SampledPoints) _cmsFree(ContextID, SampledPoints); + + return out; +} + + +// Compute Black tone curve on a CMYK -> CMYK transform. This is done by +// using the proof direction on both profiles to find K->L* relationship +// then joining both curves. dwFlags may include black point compensation. +cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID, + cmsUInt32Number nPoints, + cmsUInt32Number nProfiles, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsToneCurve *in, *out, *KTone; + + // Make sure CMYK -> CMYK + if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData || + cmsGetColorSpace(hProfiles[nProfiles-1])!= cmsSigCmykData) return NULL; + + + // Make sure last is an output profile + if (cmsGetDeviceClass(hProfiles[nProfiles - 1]) != cmsSigOutputClass) return NULL; + + // Create individual curves. BPC works also as each K to L* is + // computed as a BPC to zero black point in case of L* + in = ComputeKToLstar(ContextID, nPoints, nProfiles - 1, Intents, hProfiles, BPC, AdaptationStates, dwFlags); + if (in == NULL) return NULL; + + out = ComputeKToLstar(ContextID, nPoints, 1, + Intents + (nProfiles - 1), + &hProfiles [nProfiles - 1], + BPC + (nProfiles - 1), + AdaptationStates + (nProfiles - 1), + dwFlags); + if (out == NULL) { + cmsFreeToneCurve(in); + return NULL; + } + + // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but + // since this is used on black-preserving LUTs, we are not losing accuracy in any case + KTone = cmsJoinToneCurve(ContextID, in, out, nPoints); + + // Get rid of components + cmsFreeToneCurve(in); cmsFreeToneCurve(out); + + // Something went wrong... + if (KTone == NULL) return NULL; + + // Make sure it is monotonic + if (!cmsIsToneCurveMonotonic(KTone)) { + cmsFreeToneCurve(KTone); + return NULL; + } + + return KTone; +} + + +// Gamut LUT Creation ----------------------------------------------------------------------------------------- + +// Used by gamut & softproofing + +typedef struct { + + cmsHTRANSFORM hInput; // From whatever input color space. 16 bits to DBL + cmsHTRANSFORM hForward, hReverse; // Transforms going from Lab to colorant and back + cmsFloat64Number Threshold; // The threshold after which is considered out of gamut + + } GAMUTCHAIN; + +// This sampler does compute gamut boundaries by comparing original +// values with a transform going back and forth. Values above ERR_THRESHOLD +// of maximum are considered out of gamut. + +#define ERR_THRESHOLD 5 + + +static +int GamutSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo) +{ + GAMUTCHAIN* t = (GAMUTCHAIN* ) Cargo; + cmsCIELab LabIn1, LabOut1; + cmsCIELab LabIn2, LabOut2; + cmsUInt16Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS]; + cmsFloat64Number dE1, dE2, ErrorRatio; + + // Assume in-gamut by default. + ErrorRatio = 1.0; + + // Convert input to Lab + cmsDoTransform(t -> hInput, In, &LabIn1, 1); + + // converts from PCS to colorant. This always + // does return in-gamut values, + cmsDoTransform(t -> hForward, &LabIn1, Proof, 1); + + // Now, do the inverse, from colorant to PCS. + cmsDoTransform(t -> hReverse, Proof, &LabOut1, 1); + + memmove(&LabIn2, &LabOut1, sizeof(cmsCIELab)); + + // Try again, but this time taking Check as input + cmsDoTransform(t -> hForward, &LabOut1, Proof2, 1); + cmsDoTransform(t -> hReverse, Proof2, &LabOut2, 1); + + // Take difference of direct value + dE1 = cmsDeltaE(&LabIn1, &LabOut1); + + // Take difference of converted value + dE2 = cmsDeltaE(&LabIn2, &LabOut2); + + + // if dE1 is small and dE2 is small, value is likely to be in gamut + if (dE1 < t->Threshold && dE2 < t->Threshold) + Out[0] = 0; + else { + + // if dE1 is small and dE2 is big, undefined. Assume in gamut + if (dE1 < t->Threshold && dE2 > t->Threshold) + Out[0] = 0; + else + // dE1 is big and dE2 is small, clearly out of gamut + if (dE1 > t->Threshold && dE2 < t->Threshold) + Out[0] = (cmsUInt16Number) _cmsQuickFloor((dE1 - t->Threshold) + .5); + else { + + // dE1 is big and dE2 is also big, could be due to perceptual mapping + // so take error ratio + if (dE2 == 0.0) + ErrorRatio = dE1; + else + ErrorRatio = dE1 / dE2; + + if (ErrorRatio > t->Threshold) + Out[0] = (cmsUInt16Number) _cmsQuickFloor((ErrorRatio - t->Threshold) + .5); + else + Out[0] = 0; + } + } + + + return TRUE; +} + +// Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs +// the dE obtained is then annotated on the LUT. Values truly out of gamut are clipped to dE = 0xFFFE +// and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well. +// +// **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors, +// of course, many perceptual and saturation intents does not work in such way, but relativ. ones should. + +cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID, + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsUInt32Number Intents[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number nGamutPCSposition, + cmsHPROFILE hGamut) +{ + cmsHPROFILE hLab; + cmsPipeline* Gamut; + cmsStage* CLUT; + cmsUInt32Number dwFormat; + GAMUTCHAIN Chain; + cmsUInt32Number nGridpoints; + cmsInt32Number nChannels; + cmsColorSpaceSignature ColorSpace; + cmsUInt32Number i; + cmsHPROFILE ProfileList[256]; + cmsBool BPCList[256]; + cmsFloat64Number AdaptationList[256]; + cmsUInt32Number IntentList[256]; + + memset(&Chain, 0, sizeof(GAMUTCHAIN)); + + + if (nGamutPCSposition <= 0 || nGamutPCSposition > 255) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong position of PCS. 1..255 expected, %d found.", nGamutPCSposition); + return NULL; + } + + hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + if (hLab == NULL) return NULL; + + + // The figure of merit. On matrix-shaper profiles, should be almost zero as + // the conversion is pretty exact. On LUT based profiles, different resolutions + // of input and output CLUT may result in differences. + + if (cmsIsMatrixShaper(hGamut)) { + + Chain.Threshold = 1.0; + } + else { + Chain.Threshold = ERR_THRESHOLD; + } + + + // Create a copy of parameters + for (i=0; i < nGamutPCSposition; i++) { + ProfileList[i] = hProfiles[i]; + BPCList[i] = BPC[i]; + AdaptationList[i] = AdaptationStates[i]; + IntentList[i] = Intents[i]; + } + + // Fill Lab identity + ProfileList[nGamutPCSposition] = hLab; + BPCList[nGamutPCSposition] = 0; + AdaptationList[nGamutPCSposition] = 1.0; + IntentList[nGamutPCSposition] = INTENT_RELATIVE_COLORIMETRIC; + + + ColorSpace = cmsGetColorSpace(hGamut); + nChannels = cmsChannelsOfColorSpace(ColorSpace); + nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC); + dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); + + // 16 bits to Lab double + Chain.hInput = cmsCreateExtendedTransform(ContextID, + nGamutPCSposition + 1, + ProfileList, + BPCList, + IntentList, + AdaptationList, + NULL, 0, + dwFormat, TYPE_Lab_DBL, + cmsFLAGS_NOCACHE); + + + // Does create the forward step. Lab double to device + dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); + Chain.hForward = cmsCreateTransformTHR(ContextID, + hLab, TYPE_Lab_DBL, + hGamut, dwFormat, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE); + + // Does create the backwards step + Chain.hReverse = cmsCreateTransformTHR(ContextID, hGamut, dwFormat, + hLab, TYPE_Lab_DBL, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE); + + + // All ok? + if (Chain.hInput && Chain.hForward && Chain.hReverse) { + + // Go on, try to compute gamut LUT from PCS. This consist on a single channel containing + // dE when doing a transform back and forth on the colorimetric intent. + + Gamut = cmsPipelineAlloc(ContextID, 3, 1); + if (Gamut != NULL) { + + CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL); + if (!cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT)) { + cmsPipelineFree(Gamut); + Gamut = NULL; + } + else { + cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0); + } + } + } + else + Gamut = NULL; // Didn't work... + + // Free all needed stuff. + if (Chain.hInput) cmsDeleteTransform(Chain.hInput); + if (Chain.hForward) cmsDeleteTransform(Chain.hForward); + if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse); + if (hLab) cmsCloseProfile(hLab); + + // And return computed hull + return Gamut; +} + +// Total Area Coverage estimation ---------------------------------------------------------------- + +typedef struct { + cmsUInt32Number nOutputChans; + cmsHTRANSFORM hRoundTrip; + cmsFloat32Number MaxTAC; + cmsFloat32Number MaxInput[cmsMAXCHANNELS]; + +} cmsTACestimator; + + +// This callback just accounts the maximum ink dropped in the given node. It does not populate any +// memory, as the destination table is NULL. Its only purpose it to know the global maximum. +static +int EstimateTAC(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void * Cargo) +{ + cmsTACestimator* bp = (cmsTACestimator*) Cargo; + cmsFloat32Number RoundTrip[cmsMAXCHANNELS]; + cmsUInt32Number i; + cmsFloat32Number Sum; + + + // Evaluate the xform + cmsDoTransform(bp->hRoundTrip, In, RoundTrip, 1); + + // All all amounts of ink + for (Sum=0, i=0; i < bp ->nOutputChans; i++) + Sum += RoundTrip[i]; + + // If above maximum, keep track of input values + if (Sum > bp ->MaxTAC) { + + bp ->MaxTAC = Sum; + + for (i=0; i < bp ->nOutputChans; i++) { + bp ->MaxInput[i] = In[i]; + } + } + + return TRUE; + + cmsUNUSED_PARAMETER(Out); +} + + +// Detect Total area coverage of the profile +cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile) +{ + cmsTACestimator bp; + cmsUInt32Number dwFormatter; + cmsUInt32Number GridPoints[MAX_INPUT_DIMENSIONS]; + cmsHPROFILE hLab; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + // TAC only works on output profiles + if (cmsGetDeviceClass(hProfile) != cmsSigOutputClass) { + return 0; + } + + // Create a fake formatter for result + dwFormatter = cmsFormatterForColorspaceOfProfile(hProfile, 4, TRUE); + + // Unsupported color space? + if (dwFormatter == 0) return 0; + + bp.nOutputChans = T_CHANNELS(dwFormatter); + bp.MaxTAC = 0; // Initial TAC is 0 + + // for safety + if (bp.nOutputChans >= cmsMAXCHANNELS) return 0; + + hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + if (hLab == NULL) return 0; + // Setup a roundtrip on perceptual intent in output profile for TAC estimation + bp.hRoundTrip = cmsCreateTransformTHR(ContextID, hLab, TYPE_Lab_16, + hProfile, dwFormatter, INTENT_PERCEPTUAL, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE); + + cmsCloseProfile(hLab); + if (bp.hRoundTrip == NULL) return 0; + + // For L* we only need black and white. For C* we need many points + GridPoints[0] = 6; + GridPoints[1] = 74; + GridPoints[2] = 74; + + + if (!cmsSliceSpace16(3, GridPoints, EstimateTAC, &bp)) { + bp.MaxTAC = 0; + } + + cmsDeleteTransform(bp.hRoundTrip); + + // Results in % + return bp.MaxTAC; +} + + +// Carefully, clamp on CIELab space. + +cmsBool CMSEXPORT cmsDesaturateLab(cmsCIELab* Lab, + double amax, double amin, + double bmax, double bmin) +{ + + // Whole Luma surface to zero + + if (Lab -> L < 0) { + + Lab-> L = Lab->a = Lab-> b = 0.0; + return FALSE; + } + + // Clamp white, DISCARD HIGHLIGHTS. This is done + // in such way because icc spec doesn't allow the + // use of L>100 as a highlight means. + + if (Lab->L > 100) + Lab -> L = 100; + + // Check out gamut prism, on a, b faces + + if (Lab -> a < amin || Lab->a > amax|| + Lab -> b < bmin || Lab->b > bmax) { + + cmsCIELCh LCh; + double h, slope; + + // Falls outside a, b limits. Transports to LCh space, + // and then do the clipping + + + if (Lab -> a == 0.0) { // Is hue exactly 90? + + // atan will not work, so clamp here + Lab -> b = Lab->b < 0 ? bmin : bmax; + return TRUE; + } + + cmsLab2LCh(&LCh, Lab); + + slope = Lab -> b / Lab -> a; + h = LCh.h; + + // There are 4 zones + + if ((h >= 0. && h < 45.) || + (h >= 315 && h <= 360.)) { + + // clip by amax + Lab -> a = amax; + Lab -> b = amax * slope; + } + else + if (h >= 45. && h < 135.) + { + // clip by bmax + Lab -> b = bmax; + Lab -> a = bmax / slope; + } + else + if (h >= 135. && h < 225.) { + // clip by amin + Lab -> a = amin; + Lab -> b = amin * slope; + + } + else + if (h >= 225. && h < 315.) { + // clip by bmin + Lab -> b = bmin; + Lab -> a = bmin / slope; + } + else { + cmsSignalError(0, cmsERROR_RANGE, "Invalid angle"); + return FALSE; + } + + } + + return TRUE; +} + +// Detect whatever a given ICC profile works in linear (gamma 1.0) space +// Actually, doing that "well" is quite hard, since every component may behave completely different. +// Since the true point of this function is to detect suitable optimizations, I am imposing some requirements +// that simplifies things: only RGB, and only profiles that can got in both directions. +// The algorithm obtains Y from a syntetical gray R=G=B. Then least squares fitting is used to estimate gamma. +// For gamma close to 1.0, RGB is linear. On profiles not supported, -1 is returned. + +cmsFloat64Number CMSEXPORT cmsDetectRGBProfileGamma(cmsHPROFILE hProfile, cmsFloat64Number threshold) +{ + cmsContext ContextID; + cmsHPROFILE hXYZ; + cmsHTRANSFORM xform; + cmsToneCurve* Y_curve; + cmsUInt16Number rgb[256][3]; + cmsCIEXYZ XYZ[256]; + cmsFloat32Number Y_normalized[256]; + cmsFloat64Number gamma; + cmsProfileClassSignature cl; + int i; + + if (cmsGetColorSpace(hProfile) != cmsSigRgbData) + return -1; + + cl = cmsGetDeviceClass(hProfile); + if (cl != cmsSigInputClass && cl != cmsSigDisplayClass && + cl != cmsSigOutputClass && cl != cmsSigColorSpaceClass) + return -1; + + ContextID = cmsGetProfileContextID(hProfile); + hXYZ = cmsCreateXYZProfileTHR(ContextID); + if (hXYZ == NULL) + return -1; + xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_RGB_16, hXYZ, TYPE_XYZ_DBL, + INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE); + + if (xform == NULL) { // If not RGB or forward direction is not supported, regret with the previous error + + cmsCloseProfile(hXYZ); + return -1; + } + + for (i = 0; i < 256; i++) { + rgb[i][0] = rgb[i][1] = rgb[i][2] = FROM_8_TO_16(i); + } + + cmsDoTransform(xform, rgb, XYZ, 256); + + cmsDeleteTransform(xform); + cmsCloseProfile(hXYZ); + + for (i = 0; i < 256; i++) { + Y_normalized[i] = (cmsFloat32Number) XYZ[i].Y; + } + + Y_curve = cmsBuildTabulatedToneCurveFloat(ContextID, 256, Y_normalized); + if (Y_curve == NULL) + return -1; + + gamma = cmsEstimateGamma(Y_curve, threshold); + + cmsFreeToneCurve(Y_curve); + + return gamma; +} + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmshalf.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmshalf.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmshalf.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmshalf.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,564 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// +// +#include "lcms2_internal.h" + +#ifndef CMS_NO_HALF_SUPPORT + +// This code is inspired in the paper "Fast Half Float Conversions" +// by Jeroen van der Zijp + +static const cmsUInt32Number Mantissa[2048] = { + +0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34a00000, +0x34c00000, 0x34e00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, +0x35400000, 0x35500000, 0x35600000, 0x35700000, 0x35800000, 0x35880000, +0x35900000, 0x35980000, 0x35a00000, 0x35a80000, 0x35b00000, 0x35b80000, +0x35c00000, 0x35c80000, 0x35d00000, 0x35d80000, 0x35e00000, 0x35e80000, +0x35f00000, 0x35f80000, 0x36000000, 0x36040000, 0x36080000, 0x360c0000, +0x36100000, 0x36140000, 0x36180000, 0x361c0000, 0x36200000, 0x36240000, +0x36280000, 0x362c0000, 0x36300000, 0x36340000, 0x36380000, 0x363c0000, +0x36400000, 0x36440000, 0x36480000, 0x364c0000, 0x36500000, 0x36540000, +0x36580000, 0x365c0000, 0x36600000, 0x36640000, 0x36680000, 0x366c0000, +0x36700000, 0x36740000, 0x36780000, 0x367c0000, 0x36800000, 0x36820000, +0x36840000, 0x36860000, 0x36880000, 0x368a0000, 0x368c0000, 0x368e0000, +0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369a0000, +0x369c0000, 0x369e0000, 0x36a00000, 0x36a20000, 0x36a40000, 0x36a60000, +0x36a80000, 0x36aa0000, 0x36ac0000, 0x36ae0000, 0x36b00000, 0x36b20000, +0x36b40000, 0x36b60000, 0x36b80000, 0x36ba0000, 0x36bc0000, 0x36be0000, +0x36c00000, 0x36c20000, 0x36c40000, 0x36c60000, 0x36c80000, 0x36ca0000, +0x36cc0000, 0x36ce0000, 0x36d00000, 0x36d20000, 0x36d40000, 0x36d60000, +0x36d80000, 0x36da0000, 0x36dc0000, 0x36de0000, 0x36e00000, 0x36e20000, +0x36e40000, 0x36e60000, 0x36e80000, 0x36ea0000, 0x36ec0000, 0x36ee0000, +0x36f00000, 0x36f20000, 0x36f40000, 0x36f60000, 0x36f80000, 0x36fa0000, +0x36fc0000, 0x36fe0000, 0x37000000, 0x37010000, 0x37020000, 0x37030000, +0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, +0x370a0000, 0x370b0000, 0x370c0000, 0x370d0000, 0x370e0000, 0x370f0000, +0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, +0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371a0000, 0x371b0000, +0x371c0000, 0x371d0000, 0x371e0000, 0x371f0000, 0x37200000, 0x37210000, +0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, +0x37280000, 0x37290000, 0x372a0000, 0x372b0000, 0x372c0000, 0x372d0000, +0x372e0000, 0x372f0000, 0x37300000, 0x37310000, 0x37320000, 0x37330000, +0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, +0x373a0000, 0x373b0000, 0x373c0000, 0x373d0000, 0x373e0000, 0x373f0000, +0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, +0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374a0000, 0x374b0000, +0x374c0000, 0x374d0000, 0x374e0000, 0x374f0000, 0x37500000, 0x37510000, +0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, +0x37580000, 0x37590000, 0x375a0000, 0x375b0000, 0x375c0000, 0x375d0000, +0x375e0000, 0x375f0000, 0x37600000, 0x37610000, 0x37620000, 0x37630000, +0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, +0x376a0000, 0x376b0000, 0x376c0000, 0x376d0000, 0x376e0000, 0x376f0000, +0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, +0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377a0000, 0x377b0000, +0x377c0000, 0x377d0000, 0x377e0000, 0x377f0000, 0x37800000, 0x37808000, +0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, +0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, +0x37870000, 0x37878000, 0x37880000, 0x37888000, 0x37890000, 0x37898000, +0x378a0000, 0x378a8000, 0x378b0000, 0x378b8000, 0x378c0000, 0x378c8000, +0x378d0000, 0x378d8000, 0x378e0000, 0x378e8000, 0x378f0000, 0x378f8000, +0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, +0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, +0x37960000, 0x37968000, 0x37970000, 0x37978000, 0x37980000, 0x37988000, +0x37990000, 0x37998000, 0x379a0000, 0x379a8000, 0x379b0000, 0x379b8000, +0x379c0000, 0x379c8000, 0x379d0000, 0x379d8000, 0x379e0000, 0x379e8000, +0x379f0000, 0x379f8000, 0x37a00000, 0x37a08000, 0x37a10000, 0x37a18000, +0x37a20000, 0x37a28000, 0x37a30000, 0x37a38000, 0x37a40000, 0x37a48000, +0x37a50000, 0x37a58000, 0x37a60000, 0x37a68000, 0x37a70000, 0x37a78000, +0x37a80000, 0x37a88000, 0x37a90000, 0x37a98000, 0x37aa0000, 0x37aa8000, +0x37ab0000, 0x37ab8000, 0x37ac0000, 0x37ac8000, 0x37ad0000, 0x37ad8000, +0x37ae0000, 0x37ae8000, 0x37af0000, 0x37af8000, 0x37b00000, 0x37b08000, +0x37b10000, 0x37b18000, 0x37b20000, 0x37b28000, 0x37b30000, 0x37b38000, +0x37b40000, 0x37b48000, 0x37b50000, 0x37b58000, 0x37b60000, 0x37b68000, +0x37b70000, 0x37b78000, 0x37b80000, 0x37b88000, 0x37b90000, 0x37b98000, +0x37ba0000, 0x37ba8000, 0x37bb0000, 0x37bb8000, 0x37bc0000, 0x37bc8000, +0x37bd0000, 0x37bd8000, 0x37be0000, 0x37be8000, 0x37bf0000, 0x37bf8000, +0x37c00000, 0x37c08000, 0x37c10000, 0x37c18000, 0x37c20000, 0x37c28000, +0x37c30000, 0x37c38000, 0x37c40000, 0x37c48000, 0x37c50000, 0x37c58000, +0x37c60000, 0x37c68000, 0x37c70000, 0x37c78000, 0x37c80000, 0x37c88000, +0x37c90000, 0x37c98000, 0x37ca0000, 0x37ca8000, 0x37cb0000, 0x37cb8000, +0x37cc0000, 0x37cc8000, 0x37cd0000, 0x37cd8000, 0x37ce0000, 0x37ce8000, +0x37cf0000, 0x37cf8000, 0x37d00000, 0x37d08000, 0x37d10000, 0x37d18000, +0x37d20000, 0x37d28000, 0x37d30000, 0x37d38000, 0x37d40000, 0x37d48000, +0x37d50000, 0x37d58000, 0x37d60000, 0x37d68000, 0x37d70000, 0x37d78000, +0x37d80000, 0x37d88000, 0x37d90000, 0x37d98000, 0x37da0000, 0x37da8000, +0x37db0000, 0x37db8000, 0x37dc0000, 0x37dc8000, 0x37dd0000, 0x37dd8000, +0x37de0000, 0x37de8000, 0x37df0000, 0x37df8000, 0x37e00000, 0x37e08000, +0x37e10000, 0x37e18000, 0x37e20000, 0x37e28000, 0x37e30000, 0x37e38000, +0x37e40000, 0x37e48000, 0x37e50000, 0x37e58000, 0x37e60000, 0x37e68000, +0x37e70000, 0x37e78000, 0x37e80000, 0x37e88000, 0x37e90000, 0x37e98000, +0x37ea0000, 0x37ea8000, 0x37eb0000, 0x37eb8000, 0x37ec0000, 0x37ec8000, +0x37ed0000, 0x37ed8000, 0x37ee0000, 0x37ee8000, 0x37ef0000, 0x37ef8000, +0x37f00000, 0x37f08000, 0x37f10000, 0x37f18000, 0x37f20000, 0x37f28000, +0x37f30000, 0x37f38000, 0x37f40000, 0x37f48000, 0x37f50000, 0x37f58000, +0x37f60000, 0x37f68000, 0x37f70000, 0x37f78000, 0x37f80000, 0x37f88000, +0x37f90000, 0x37f98000, 0x37fa0000, 0x37fa8000, 0x37fb0000, 0x37fb8000, +0x37fc0000, 0x37fc8000, 0x37fd0000, 0x37fd8000, 0x37fe0000, 0x37fe8000, +0x37ff0000, 0x37ff8000, 0x38000000, 0x38004000, 0x38008000, 0x3800c000, +0x38010000, 0x38014000, 0x38018000, 0x3801c000, 0x38020000, 0x38024000, +0x38028000, 0x3802c000, 0x38030000, 0x38034000, 0x38038000, 0x3803c000, +0x38040000, 0x38044000, 0x38048000, 0x3804c000, 0x38050000, 0x38054000, +0x38058000, 0x3805c000, 0x38060000, 0x38064000, 0x38068000, 0x3806c000, +0x38070000, 0x38074000, 0x38078000, 0x3807c000, 0x38080000, 0x38084000, +0x38088000, 0x3808c000, 0x38090000, 0x38094000, 0x38098000, 0x3809c000, +0x380a0000, 0x380a4000, 0x380a8000, 0x380ac000, 0x380b0000, 0x380b4000, +0x380b8000, 0x380bc000, 0x380c0000, 0x380c4000, 0x380c8000, 0x380cc000, +0x380d0000, 0x380d4000, 0x380d8000, 0x380dc000, 0x380e0000, 0x380e4000, +0x380e8000, 0x380ec000, 0x380f0000, 0x380f4000, 0x380f8000, 0x380fc000, +0x38100000, 0x38104000, 0x38108000, 0x3810c000, 0x38110000, 0x38114000, +0x38118000, 0x3811c000, 0x38120000, 0x38124000, 0x38128000, 0x3812c000, +0x38130000, 0x38134000, 0x38138000, 0x3813c000, 0x38140000, 0x38144000, +0x38148000, 0x3814c000, 0x38150000, 0x38154000, 0x38158000, 0x3815c000, +0x38160000, 0x38164000, 0x38168000, 0x3816c000, 0x38170000, 0x38174000, +0x38178000, 0x3817c000, 0x38180000, 0x38184000, 0x38188000, 0x3818c000, +0x38190000, 0x38194000, 0x38198000, 0x3819c000, 0x381a0000, 0x381a4000, +0x381a8000, 0x381ac000, 0x381b0000, 0x381b4000, 0x381b8000, 0x381bc000, +0x381c0000, 0x381c4000, 0x381c8000, 0x381cc000, 0x381d0000, 0x381d4000, +0x381d8000, 0x381dc000, 0x381e0000, 0x381e4000, 0x381e8000, 0x381ec000, +0x381f0000, 0x381f4000, 0x381f8000, 0x381fc000, 0x38200000, 0x38204000, +0x38208000, 0x3820c000, 0x38210000, 0x38214000, 0x38218000, 0x3821c000, +0x38220000, 0x38224000, 0x38228000, 0x3822c000, 0x38230000, 0x38234000, +0x38238000, 0x3823c000, 0x38240000, 0x38244000, 0x38248000, 0x3824c000, +0x38250000, 0x38254000, 0x38258000, 0x3825c000, 0x38260000, 0x38264000, +0x38268000, 0x3826c000, 0x38270000, 0x38274000, 0x38278000, 0x3827c000, +0x38280000, 0x38284000, 0x38288000, 0x3828c000, 0x38290000, 0x38294000, +0x38298000, 0x3829c000, 0x382a0000, 0x382a4000, 0x382a8000, 0x382ac000, +0x382b0000, 0x382b4000, 0x382b8000, 0x382bc000, 0x382c0000, 0x382c4000, +0x382c8000, 0x382cc000, 0x382d0000, 0x382d4000, 0x382d8000, 0x382dc000, +0x382e0000, 0x382e4000, 0x382e8000, 0x382ec000, 0x382f0000, 0x382f4000, +0x382f8000, 0x382fc000, 0x38300000, 0x38304000, 0x38308000, 0x3830c000, +0x38310000, 0x38314000, 0x38318000, 0x3831c000, 0x38320000, 0x38324000, +0x38328000, 0x3832c000, 0x38330000, 0x38334000, 0x38338000, 0x3833c000, +0x38340000, 0x38344000, 0x38348000, 0x3834c000, 0x38350000, 0x38354000, +0x38358000, 0x3835c000, 0x38360000, 0x38364000, 0x38368000, 0x3836c000, +0x38370000, 0x38374000, 0x38378000, 0x3837c000, 0x38380000, 0x38384000, +0x38388000, 0x3838c000, 0x38390000, 0x38394000, 0x38398000, 0x3839c000, +0x383a0000, 0x383a4000, 0x383a8000, 0x383ac000, 0x383b0000, 0x383b4000, +0x383b8000, 0x383bc000, 0x383c0000, 0x383c4000, 0x383c8000, 0x383cc000, +0x383d0000, 0x383d4000, 0x383d8000, 0x383dc000, 0x383e0000, 0x383e4000, +0x383e8000, 0x383ec000, 0x383f0000, 0x383f4000, 0x383f8000, 0x383fc000, +0x38400000, 0x38404000, 0x38408000, 0x3840c000, 0x38410000, 0x38414000, +0x38418000, 0x3841c000, 0x38420000, 0x38424000, 0x38428000, 0x3842c000, +0x38430000, 0x38434000, 0x38438000, 0x3843c000, 0x38440000, 0x38444000, +0x38448000, 0x3844c000, 0x38450000, 0x38454000, 0x38458000, 0x3845c000, +0x38460000, 0x38464000, 0x38468000, 0x3846c000, 0x38470000, 0x38474000, +0x38478000, 0x3847c000, 0x38480000, 0x38484000, 0x38488000, 0x3848c000, +0x38490000, 0x38494000, 0x38498000, 0x3849c000, 0x384a0000, 0x384a4000, +0x384a8000, 0x384ac000, 0x384b0000, 0x384b4000, 0x384b8000, 0x384bc000, +0x384c0000, 0x384c4000, 0x384c8000, 0x384cc000, 0x384d0000, 0x384d4000, +0x384d8000, 0x384dc000, 0x384e0000, 0x384e4000, 0x384e8000, 0x384ec000, +0x384f0000, 0x384f4000, 0x384f8000, 0x384fc000, 0x38500000, 0x38504000, +0x38508000, 0x3850c000, 0x38510000, 0x38514000, 0x38518000, 0x3851c000, +0x38520000, 0x38524000, 0x38528000, 0x3852c000, 0x38530000, 0x38534000, +0x38538000, 0x3853c000, 0x38540000, 0x38544000, 0x38548000, 0x3854c000, +0x38550000, 0x38554000, 0x38558000, 0x3855c000, 0x38560000, 0x38564000, +0x38568000, 0x3856c000, 0x38570000, 0x38574000, 0x38578000, 0x3857c000, +0x38580000, 0x38584000, 0x38588000, 0x3858c000, 0x38590000, 0x38594000, +0x38598000, 0x3859c000, 0x385a0000, 0x385a4000, 0x385a8000, 0x385ac000, +0x385b0000, 0x385b4000, 0x385b8000, 0x385bc000, 0x385c0000, 0x385c4000, +0x385c8000, 0x385cc000, 0x385d0000, 0x385d4000, 0x385d8000, 0x385dc000, +0x385e0000, 0x385e4000, 0x385e8000, 0x385ec000, 0x385f0000, 0x385f4000, +0x385f8000, 0x385fc000, 0x38600000, 0x38604000, 0x38608000, 0x3860c000, +0x38610000, 0x38614000, 0x38618000, 0x3861c000, 0x38620000, 0x38624000, +0x38628000, 0x3862c000, 0x38630000, 0x38634000, 0x38638000, 0x3863c000, +0x38640000, 0x38644000, 0x38648000, 0x3864c000, 0x38650000, 0x38654000, +0x38658000, 0x3865c000, 0x38660000, 0x38664000, 0x38668000, 0x3866c000, +0x38670000, 0x38674000, 0x38678000, 0x3867c000, 0x38680000, 0x38684000, +0x38688000, 0x3868c000, 0x38690000, 0x38694000, 0x38698000, 0x3869c000, +0x386a0000, 0x386a4000, 0x386a8000, 0x386ac000, 0x386b0000, 0x386b4000, +0x386b8000, 0x386bc000, 0x386c0000, 0x386c4000, 0x386c8000, 0x386cc000, +0x386d0000, 0x386d4000, 0x386d8000, 0x386dc000, 0x386e0000, 0x386e4000, +0x386e8000, 0x386ec000, 0x386f0000, 0x386f4000, 0x386f8000, 0x386fc000, +0x38700000, 0x38704000, 0x38708000, 0x3870c000, 0x38710000, 0x38714000, +0x38718000, 0x3871c000, 0x38720000, 0x38724000, 0x38728000, 0x3872c000, +0x38730000, 0x38734000, 0x38738000, 0x3873c000, 0x38740000, 0x38744000, +0x38748000, 0x3874c000, 0x38750000, 0x38754000, 0x38758000, 0x3875c000, +0x38760000, 0x38764000, 0x38768000, 0x3876c000, 0x38770000, 0x38774000, +0x38778000, 0x3877c000, 0x38780000, 0x38784000, 0x38788000, 0x3878c000, +0x38790000, 0x38794000, 0x38798000, 0x3879c000, 0x387a0000, 0x387a4000, +0x387a8000, 0x387ac000, 0x387b0000, 0x387b4000, 0x387b8000, 0x387bc000, +0x387c0000, 0x387c4000, 0x387c8000, 0x387cc000, 0x387d0000, 0x387d4000, +0x387d8000, 0x387dc000, 0x387e0000, 0x387e4000, 0x387e8000, 0x387ec000, +0x387f0000, 0x387f4000, 0x387f8000, 0x387fc000, 0x38000000, 0x38002000, +0x38004000, 0x38006000, 0x38008000, 0x3800a000, 0x3800c000, 0x3800e000, +0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801a000, +0x3801c000, 0x3801e000, 0x38020000, 0x38022000, 0x38024000, 0x38026000, +0x38028000, 0x3802a000, 0x3802c000, 0x3802e000, 0x38030000, 0x38032000, +0x38034000, 0x38036000, 0x38038000, 0x3803a000, 0x3803c000, 0x3803e000, +0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804a000, +0x3804c000, 0x3804e000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, +0x38058000, 0x3805a000, 0x3805c000, 0x3805e000, 0x38060000, 0x38062000, +0x38064000, 0x38066000, 0x38068000, 0x3806a000, 0x3806c000, 0x3806e000, +0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807a000, +0x3807c000, 0x3807e000, 0x38080000, 0x38082000, 0x38084000, 0x38086000, +0x38088000, 0x3808a000, 0x3808c000, 0x3808e000, 0x38090000, 0x38092000, +0x38094000, 0x38096000, 0x38098000, 0x3809a000, 0x3809c000, 0x3809e000, +0x380a0000, 0x380a2000, 0x380a4000, 0x380a6000, 0x380a8000, 0x380aa000, +0x380ac000, 0x380ae000, 0x380b0000, 0x380b2000, 0x380b4000, 0x380b6000, +0x380b8000, 0x380ba000, 0x380bc000, 0x380be000, 0x380c0000, 0x380c2000, +0x380c4000, 0x380c6000, 0x380c8000, 0x380ca000, 0x380cc000, 0x380ce000, +0x380d0000, 0x380d2000, 0x380d4000, 0x380d6000, 0x380d8000, 0x380da000, +0x380dc000, 0x380de000, 0x380e0000, 0x380e2000, 0x380e4000, 0x380e6000, +0x380e8000, 0x380ea000, 0x380ec000, 0x380ee000, 0x380f0000, 0x380f2000, +0x380f4000, 0x380f6000, 0x380f8000, 0x380fa000, 0x380fc000, 0x380fe000, +0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810a000, +0x3810c000, 0x3810e000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, +0x38118000, 0x3811a000, 0x3811c000, 0x3811e000, 0x38120000, 0x38122000, +0x38124000, 0x38126000, 0x38128000, 0x3812a000, 0x3812c000, 0x3812e000, +0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813a000, +0x3813c000, 0x3813e000, 0x38140000, 0x38142000, 0x38144000, 0x38146000, +0x38148000, 0x3814a000, 0x3814c000, 0x3814e000, 0x38150000, 0x38152000, +0x38154000, 0x38156000, 0x38158000, 0x3815a000, 0x3815c000, 0x3815e000, +0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816a000, +0x3816c000, 0x3816e000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, +0x38178000, 0x3817a000, 0x3817c000, 0x3817e000, 0x38180000, 0x38182000, +0x38184000, 0x38186000, 0x38188000, 0x3818a000, 0x3818c000, 0x3818e000, +0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819a000, +0x3819c000, 0x3819e000, 0x381a0000, 0x381a2000, 0x381a4000, 0x381a6000, +0x381a8000, 0x381aa000, 0x381ac000, 0x381ae000, 0x381b0000, 0x381b2000, +0x381b4000, 0x381b6000, 0x381b8000, 0x381ba000, 0x381bc000, 0x381be000, +0x381c0000, 0x381c2000, 0x381c4000, 0x381c6000, 0x381c8000, 0x381ca000, +0x381cc000, 0x381ce000, 0x381d0000, 0x381d2000, 0x381d4000, 0x381d6000, +0x381d8000, 0x381da000, 0x381dc000, 0x381de000, 0x381e0000, 0x381e2000, +0x381e4000, 0x381e6000, 0x381e8000, 0x381ea000, 0x381ec000, 0x381ee000, +0x381f0000, 0x381f2000, 0x381f4000, 0x381f6000, 0x381f8000, 0x381fa000, +0x381fc000, 0x381fe000, 0x38200000, 0x38202000, 0x38204000, 0x38206000, +0x38208000, 0x3820a000, 0x3820c000, 0x3820e000, 0x38210000, 0x38212000, +0x38214000, 0x38216000, 0x38218000, 0x3821a000, 0x3821c000, 0x3821e000, +0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822a000, +0x3822c000, 0x3822e000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, +0x38238000, 0x3823a000, 0x3823c000, 0x3823e000, 0x38240000, 0x38242000, +0x38244000, 0x38246000, 0x38248000, 0x3824a000, 0x3824c000, 0x3824e000, +0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825a000, +0x3825c000, 0x3825e000, 0x38260000, 0x38262000, 0x38264000, 0x38266000, +0x38268000, 0x3826a000, 0x3826c000, 0x3826e000, 0x38270000, 0x38272000, +0x38274000, 0x38276000, 0x38278000, 0x3827a000, 0x3827c000, 0x3827e000, +0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828a000, +0x3828c000, 0x3828e000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, +0x38298000, 0x3829a000, 0x3829c000, 0x3829e000, 0x382a0000, 0x382a2000, +0x382a4000, 0x382a6000, 0x382a8000, 0x382aa000, 0x382ac000, 0x382ae000, +0x382b0000, 0x382b2000, 0x382b4000, 0x382b6000, 0x382b8000, 0x382ba000, +0x382bc000, 0x382be000, 0x382c0000, 0x382c2000, 0x382c4000, 0x382c6000, +0x382c8000, 0x382ca000, 0x382cc000, 0x382ce000, 0x382d0000, 0x382d2000, +0x382d4000, 0x382d6000, 0x382d8000, 0x382da000, 0x382dc000, 0x382de000, +0x382e0000, 0x382e2000, 0x382e4000, 0x382e6000, 0x382e8000, 0x382ea000, +0x382ec000, 0x382ee000, 0x382f0000, 0x382f2000, 0x382f4000, 0x382f6000, +0x382f8000, 0x382fa000, 0x382fc000, 0x382fe000, 0x38300000, 0x38302000, +0x38304000, 0x38306000, 0x38308000, 0x3830a000, 0x3830c000, 0x3830e000, +0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831a000, +0x3831c000, 0x3831e000, 0x38320000, 0x38322000, 0x38324000, 0x38326000, +0x38328000, 0x3832a000, 0x3832c000, 0x3832e000, 0x38330000, 0x38332000, +0x38334000, 0x38336000, 0x38338000, 0x3833a000, 0x3833c000, 0x3833e000, +0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834a000, +0x3834c000, 0x3834e000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, +0x38358000, 0x3835a000, 0x3835c000, 0x3835e000, 0x38360000, 0x38362000, +0x38364000, 0x38366000, 0x38368000, 0x3836a000, 0x3836c000, 0x3836e000, +0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837a000, +0x3837c000, 0x3837e000, 0x38380000, 0x38382000, 0x38384000, 0x38386000, +0x38388000, 0x3838a000, 0x3838c000, 0x3838e000, 0x38390000, 0x38392000, +0x38394000, 0x38396000, 0x38398000, 0x3839a000, 0x3839c000, 0x3839e000, +0x383a0000, 0x383a2000, 0x383a4000, 0x383a6000, 0x383a8000, 0x383aa000, +0x383ac000, 0x383ae000, 0x383b0000, 0x383b2000, 0x383b4000, 0x383b6000, +0x383b8000, 0x383ba000, 0x383bc000, 0x383be000, 0x383c0000, 0x383c2000, +0x383c4000, 0x383c6000, 0x383c8000, 0x383ca000, 0x383cc000, 0x383ce000, +0x383d0000, 0x383d2000, 0x383d4000, 0x383d6000, 0x383d8000, 0x383da000, +0x383dc000, 0x383de000, 0x383e0000, 0x383e2000, 0x383e4000, 0x383e6000, +0x383e8000, 0x383ea000, 0x383ec000, 0x383ee000, 0x383f0000, 0x383f2000, +0x383f4000, 0x383f6000, 0x383f8000, 0x383fa000, 0x383fc000, 0x383fe000, +0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840a000, +0x3840c000, 0x3840e000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, +0x38418000, 0x3841a000, 0x3841c000, 0x3841e000, 0x38420000, 0x38422000, +0x38424000, 0x38426000, 0x38428000, 0x3842a000, 0x3842c000, 0x3842e000, +0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843a000, +0x3843c000, 0x3843e000, 0x38440000, 0x38442000, 0x38444000, 0x38446000, +0x38448000, 0x3844a000, 0x3844c000, 0x3844e000, 0x38450000, 0x38452000, +0x38454000, 0x38456000, 0x38458000, 0x3845a000, 0x3845c000, 0x3845e000, +0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846a000, +0x3846c000, 0x3846e000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, +0x38478000, 0x3847a000, 0x3847c000, 0x3847e000, 0x38480000, 0x38482000, +0x38484000, 0x38486000, 0x38488000, 0x3848a000, 0x3848c000, 0x3848e000, +0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849a000, +0x3849c000, 0x3849e000, 0x384a0000, 0x384a2000, 0x384a4000, 0x384a6000, +0x384a8000, 0x384aa000, 0x384ac000, 0x384ae000, 0x384b0000, 0x384b2000, +0x384b4000, 0x384b6000, 0x384b8000, 0x384ba000, 0x384bc000, 0x384be000, +0x384c0000, 0x384c2000, 0x384c4000, 0x384c6000, 0x384c8000, 0x384ca000, +0x384cc000, 0x384ce000, 0x384d0000, 0x384d2000, 0x384d4000, 0x384d6000, +0x384d8000, 0x384da000, 0x384dc000, 0x384de000, 0x384e0000, 0x384e2000, +0x384e4000, 0x384e6000, 0x384e8000, 0x384ea000, 0x384ec000, 0x384ee000, +0x384f0000, 0x384f2000, 0x384f4000, 0x384f6000, 0x384f8000, 0x384fa000, +0x384fc000, 0x384fe000, 0x38500000, 0x38502000, 0x38504000, 0x38506000, +0x38508000, 0x3850a000, 0x3850c000, 0x3850e000, 0x38510000, 0x38512000, +0x38514000, 0x38516000, 0x38518000, 0x3851a000, 0x3851c000, 0x3851e000, +0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852a000, +0x3852c000, 0x3852e000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, +0x38538000, 0x3853a000, 0x3853c000, 0x3853e000, 0x38540000, 0x38542000, +0x38544000, 0x38546000, 0x38548000, 0x3854a000, 0x3854c000, 0x3854e000, +0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855a000, +0x3855c000, 0x3855e000, 0x38560000, 0x38562000, 0x38564000, 0x38566000, +0x38568000, 0x3856a000, 0x3856c000, 0x3856e000, 0x38570000, 0x38572000, +0x38574000, 0x38576000, 0x38578000, 0x3857a000, 0x3857c000, 0x3857e000, +0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858a000, +0x3858c000, 0x3858e000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, +0x38598000, 0x3859a000, 0x3859c000, 0x3859e000, 0x385a0000, 0x385a2000, +0x385a4000, 0x385a6000, 0x385a8000, 0x385aa000, 0x385ac000, 0x385ae000, +0x385b0000, 0x385b2000, 0x385b4000, 0x385b6000, 0x385b8000, 0x385ba000, +0x385bc000, 0x385be000, 0x385c0000, 0x385c2000, 0x385c4000, 0x385c6000, +0x385c8000, 0x385ca000, 0x385cc000, 0x385ce000, 0x385d0000, 0x385d2000, +0x385d4000, 0x385d6000, 0x385d8000, 0x385da000, 0x385dc000, 0x385de000, +0x385e0000, 0x385e2000, 0x385e4000, 0x385e6000, 0x385e8000, 0x385ea000, +0x385ec000, 0x385ee000, 0x385f0000, 0x385f2000, 0x385f4000, 0x385f6000, +0x385f8000, 0x385fa000, 0x385fc000, 0x385fe000, 0x38600000, 0x38602000, +0x38604000, 0x38606000, 0x38608000, 0x3860a000, 0x3860c000, 0x3860e000, +0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861a000, +0x3861c000, 0x3861e000, 0x38620000, 0x38622000, 0x38624000, 0x38626000, +0x38628000, 0x3862a000, 0x3862c000, 0x3862e000, 0x38630000, 0x38632000, +0x38634000, 0x38636000, 0x38638000, 0x3863a000, 0x3863c000, 0x3863e000, +0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864a000, +0x3864c000, 0x3864e000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, +0x38658000, 0x3865a000, 0x3865c000, 0x3865e000, 0x38660000, 0x38662000, +0x38664000, 0x38666000, 0x38668000, 0x3866a000, 0x3866c000, 0x3866e000, +0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867a000, +0x3867c000, 0x3867e000, 0x38680000, 0x38682000, 0x38684000, 0x38686000, +0x38688000, 0x3868a000, 0x3868c000, 0x3868e000, 0x38690000, 0x38692000, +0x38694000, 0x38696000, 0x38698000, 0x3869a000, 0x3869c000, 0x3869e000, +0x386a0000, 0x386a2000, 0x386a4000, 0x386a6000, 0x386a8000, 0x386aa000, +0x386ac000, 0x386ae000, 0x386b0000, 0x386b2000, 0x386b4000, 0x386b6000, +0x386b8000, 0x386ba000, 0x386bc000, 0x386be000, 0x386c0000, 0x386c2000, +0x386c4000, 0x386c6000, 0x386c8000, 0x386ca000, 0x386cc000, 0x386ce000, +0x386d0000, 0x386d2000, 0x386d4000, 0x386d6000, 0x386d8000, 0x386da000, +0x386dc000, 0x386de000, 0x386e0000, 0x386e2000, 0x386e4000, 0x386e6000, +0x386e8000, 0x386ea000, 0x386ec000, 0x386ee000, 0x386f0000, 0x386f2000, +0x386f4000, 0x386f6000, 0x386f8000, 0x386fa000, 0x386fc000, 0x386fe000, +0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870a000, +0x3870c000, 0x3870e000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, +0x38718000, 0x3871a000, 0x3871c000, 0x3871e000, 0x38720000, 0x38722000, +0x38724000, 0x38726000, 0x38728000, 0x3872a000, 0x3872c000, 0x3872e000, +0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873a000, +0x3873c000, 0x3873e000, 0x38740000, 0x38742000, 0x38744000, 0x38746000, +0x38748000, 0x3874a000, 0x3874c000, 0x3874e000, 0x38750000, 0x38752000, +0x38754000, 0x38756000, 0x38758000, 0x3875a000, 0x3875c000, 0x3875e000, +0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876a000, +0x3876c000, 0x3876e000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, +0x38778000, 0x3877a000, 0x3877c000, 0x3877e000, 0x38780000, 0x38782000, +0x38784000, 0x38786000, 0x38788000, 0x3878a000, 0x3878c000, 0x3878e000, +0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879a000, +0x3879c000, 0x3879e000, 0x387a0000, 0x387a2000, 0x387a4000, 0x387a6000, +0x387a8000, 0x387aa000, 0x387ac000, 0x387ae000, 0x387b0000, 0x387b2000, +0x387b4000, 0x387b6000, 0x387b8000, 0x387ba000, 0x387bc000, 0x387be000, +0x387c0000, 0x387c2000, 0x387c4000, 0x387c6000, 0x387c8000, 0x387ca000, +0x387cc000, 0x387ce000, 0x387d0000, 0x387d2000, 0x387d4000, 0x387d6000, +0x387d8000, 0x387da000, 0x387dc000, 0x387de000, 0x387e0000, 0x387e2000, +0x387e4000, 0x387e6000, 0x387e8000, 0x387ea000, 0x387ec000, 0x387ee000, +0x387f0000, 0x387f2000, 0x387f4000, 0x387f6000, 0x387f8000, 0x387fa000, +0x387fc000, 0x387fe000 +}; + +static const cmsUInt16Number Offset[64] = { +0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0000, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, +0x0400, 0x0400, 0x0400, 0x0400 +}; + +static const cmsUInt32Number Exponent[64] = { +0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, +0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, +0x06000000, 0x06800000, 0x07000000, 0x07800000, 0x08000000, 0x08800000, +0x09000000, 0x09800000, 0x0a000000, 0x0a800000, 0x0b000000, 0x0b800000, +0x0c000000, 0x0c800000, 0x0d000000, 0x0d800000, 0x0e000000, 0x0e800000, +0x0f000000, 0x47800000, 0x80000000, 0x80800000, 0x81000000, 0x81800000, +0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, +0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000, +0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8a000000, 0x8a800000, +0x8b000000, 0x8b800000, 0x8c000000, 0x8c800000, 0x8d000000, 0x8d800000, +0x8e000000, 0x8e800000, 0x8f000000, 0xc7800000 +}; + +static const cmsUInt16Number Base[512] = { +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, +0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00, +0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400, +0x4800, 0x4c00, 0x5000, 0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00, +0x7000, 0x7400, 0x7800, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, +0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, +0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400, +0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00, +0xb000, 0xb400, 0xb800, 0xbc00, 0xc000, 0xc400, 0xc800, 0xcc00, 0xd000, 0xd400, +0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00, 0xf000, 0xf400, 0xf800, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, +0xfc00, 0xfc00 +}; + +static const cmsUInt8Number Shift[512] = { +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, +0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, +0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, +0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0d, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, +0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, +0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, +0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x0d +}; + +cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h) +{ + union { + cmsFloat32Number flt; + cmsUInt32Number num; + } out; + + int n = h >> 10; + + out.num = Mantissa[ (h & 0x3ff) + Offset[ n ] ] + Exponent[ n ]; + return out.flt; +} + +cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt) +{ + union { + cmsFloat32Number flt; + cmsUInt32Number num; + } in; + + cmsUInt32Number n, j; + + in.flt = flt; + n = in.num; + j = (n >> 23) & 0x1ff; + + return (cmsUInt16Number) ((cmsUInt32Number) Base[ j ] + (( n & 0x007fffff) >> Shift[ j ])); +} + +#endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsintrp.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsintrp.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsintrp.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsintrp.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1359 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// This module incorporates several interpolation routines, for 1 to 8 channels on input and +// up to 65535 channels on output. The user may change those by using the interpolation plug-in + +// Some people may want to compile as C++ with all warnings on, in this case make compiler silent +#ifdef _MSC_VER +# if (_MSC_VER >= 1400) +# pragma warning( disable : 4365 ) +# endif +#endif + +// Interpolation routines by default +static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags); + +// This is the default factory +_cmsInterpPluginChunkType _cmsInterpPluginChunk = { NULL }; + +// The interpolation plug-in memory chunk allocator/dup +void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src) +{ + void* from; + + _cmsAssert(ctx != NULL); + + if (src != NULL) { + from = src ->chunks[InterpPlugin]; + } + else { + static _cmsInterpPluginChunkType InterpPluginChunk = { NULL }; + + from = &InterpPluginChunk; + } + + _cmsAssert(from != NULL); + ctx ->chunks[InterpPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsInterpPluginChunkType)); +} + + +// Main plug-in entry +cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + cmsPluginInterpolation* Plugin = (cmsPluginInterpolation*) Data; + _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin); + + if (Data == NULL) { + + ptr ->Interpolators = NULL; + return TRUE; + } + + // Set replacement functions + ptr ->Interpolators = Plugin ->InterpolatorsFactory; + return TRUE; +} + + +// Set the interpolation method +cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p) +{ + _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin); + + p ->Interpolation.Lerp16 = NULL; + + // Invoke factory, possibly in the Plug-in + if (ptr ->Interpolators != NULL) + p ->Interpolation = ptr->Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags); + + // If unsupported by the plug-in, go for the LittleCMS default. + // If happens only if an extern plug-in is being used + if (p ->Interpolation.Lerp16 == NULL) + p ->Interpolation = DefaultInterpolatorsFactory(p ->nInputs, p ->nOutputs, p ->dwFlags); + + // Check for valid interpolator (we just check one member of the union) + if (p ->Interpolation.Lerp16 == NULL) { + return FALSE; + } + + return TRUE; +} + + +// This function precalculates as many parameters as possible to speed up the interpolation. +cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, + const cmsUInt32Number nSamples[], + cmsUInt32Number InputChan, cmsUInt32Number OutputChan, + const void *Table, + cmsUInt32Number dwFlags) +{ + cmsInterpParams* p; + cmsUInt32Number i; + + // Check for maximum inputs + if (InputChan > MAX_INPUT_DIMENSIONS) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Too many input channels (%d channels, max=%d)", InputChan, MAX_INPUT_DIMENSIONS); + return NULL; + } + + // Creates an empty object + p = (cmsInterpParams*) _cmsMallocZero(ContextID, sizeof(cmsInterpParams)); + if (p == NULL) return NULL; + + // Keep original parameters + p -> dwFlags = dwFlags; + p -> nInputs = InputChan; + p -> nOutputs = OutputChan; + p ->Table = Table; + p ->ContextID = ContextID; + + // Fill samples per input direction and domain (which is number of nodes minus one) + for (i=0; i < InputChan; i++) { + + p -> nSamples[i] = nSamples[i]; + p -> Domain[i] = nSamples[i] - 1; + } + + // Compute factors to apply to each component to index the grid array + p -> opta[0] = p -> nOutputs; + for (i=1; i < InputChan; i++) + p ->opta[i] = p ->opta[i-1] * nSamples[InputChan-i]; + + + if (!_cmsSetInterpolationRoutine(ContextID, p)) { + cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported interpolation (%d->%d channels)", InputChan, OutputChan); + _cmsFree(ContextID, p); + return NULL; + } + + // All seems ok + return p; +} + + +// This one is a wrapper on the anterior, but assuming all directions have same number of nodes +cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, + cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags) +{ + int i; + cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS]; + + // Fill the auxiliary array + for (i=0; i < MAX_INPUT_DIMENSIONS; i++) + Samples[i] = nSamples; + + // Call the extended function + return _cmsComputeInterpParamsEx(ContextID, Samples, InputChan, OutputChan, Table, dwFlags); +} + + +// Free all associated memory +void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p) +{ + if (p != NULL) _cmsFree(p ->ContextID, p); +} + + +// Inline fixed point interpolation +cmsINLINE CMS_NO_SANITIZE cmsUInt16Number LinearInterp(cmsS15Fixed16Number a, cmsS15Fixed16Number l, cmsS15Fixed16Number h) +{ + cmsUInt32Number dif = (cmsUInt32Number) (h - l) * a + 0x8000; + dif = (dif >> 16) + l; + return (cmsUInt16Number) (dif); +} + + +// Linear interpolation (Fixed-point optimized) +static +void LinLerp1D(CMSREGISTER const cmsUInt16Number Value[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const cmsInterpParams* p) +{ + cmsUInt16Number y1, y0; + int cell0, rest; + int val3; + const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table; + + // if last value or just one point + if (Value[0] == 0xffff || p->Domain[0] == 0) { + + Output[0] = LutTable[p -> Domain[0]]; + } + else + { + val3 = p->Domain[0] * Value[0]; + val3 = _cmsToFixedDomain(val3); // To fixed 15.16 + + cell0 = FIXED_TO_INT(val3); // Cell is 16 MSB bits + rest = FIXED_REST_TO_INT(val3); // Rest is 16 LSB bits + + y0 = LutTable[cell0]; + y1 = LutTable[cell0 + 1]; + + Output[0] = LinearInterp(rest, y0, y1); + } +} + +// To prevent out of bounds indexing +cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v) +{ + return ((v < 1.0e-9f) || isnan(v)) ? 0.0f : (v > 1.0f ? 1.0f : v); +} + +// Floating-point version of 1D interpolation +static +void LinLerp1Dfloat(const cmsFloat32Number Value[], + cmsFloat32Number Output[], + const cmsInterpParams* p) +{ + cmsFloat32Number y1, y0; + cmsFloat32Number val2, rest; + int cell0, cell1; + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; + + val2 = fclamp(Value[0]); + + // if last value... + if (val2 == 1.0 || p->Domain[0] == 0) { + Output[0] = LutTable[p -> Domain[0]]; + } + else + { + val2 *= p->Domain[0]; + + cell0 = (int)floor(val2); + cell1 = (int)ceil(val2); + + // Rest is 16 LSB bits + rest = val2 - cell0; + + y0 = LutTable[cell0]; + y1 = LutTable[cell1]; + + Output[0] = y0 + (y1 - y0) * rest; + } +} + + + +// Eval gray LUT having only one input channel +static CMS_NO_SANITIZE +void Eval1Input(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const cmsInterpParams* p16) +{ + cmsS15Fixed16Number fk; + cmsS15Fixed16Number k0, k1, rk, K0, K1; + int v; + cmsUInt32Number OutChan; + const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table; + + + // if last value... + if (Input[0] == 0xffff || p16->Domain[0] == 0) { + + cmsUInt32Number y0 = p16->Domain[0] * p16->opta[0]; + + for (OutChan = 0; OutChan < p16->nOutputs; OutChan++) { + Output[OutChan] = LutTable[y0 + OutChan]; + } + } + else + { + + v = Input[0] * p16->Domain[0]; + fk = _cmsToFixedDomain(v); + + k0 = FIXED_TO_INT(fk); + rk = (cmsUInt16Number)FIXED_REST_TO_INT(fk); + + k1 = k0 + (Input[0] != 0xFFFFU ? 1 : 0); + + K0 = p16->opta[0] * k0; + K1 = p16->opta[0] * k1; + + for (OutChan = 0; OutChan < p16->nOutputs; OutChan++) { + + Output[OutChan] = LinearInterp(rk, LutTable[K0 + OutChan], LutTable[K1 + OutChan]); + } + } +} + + + +// Eval gray LUT having only one input channel +static +void Eval1InputFloat(const cmsFloat32Number Value[], + cmsFloat32Number Output[], + const cmsInterpParams* p) +{ + cmsFloat32Number y1, y0; + cmsFloat32Number val2, rest; + int cell0, cell1; + cmsUInt32Number OutChan; + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; + + val2 = fclamp(Value[0]); + + // if last value... + if (val2 == 1.0 || p->Domain[0] == 0) { + + cmsUInt32Number start = p->Domain[0] * p->opta[0]; + + for (OutChan = 0; OutChan < p->nOutputs; OutChan++) { + Output[OutChan] = LutTable[start + OutChan]; + } + } + else + { + val2 *= p->Domain[0]; + + cell0 = (int)floor(val2); + cell1 = (int)ceil(val2); + + // Rest is 16 LSB bits + rest = val2 - cell0; + + cell0 *= p->opta[0]; + cell1 *= p->opta[0]; + + for (OutChan = 0; OutChan < p->nOutputs; OutChan++) { + + y0 = LutTable[cell0 + OutChan]; + y1 = LutTable[cell1 + OutChan]; + + Output[OutChan] = y0 + (y1 - y0) * rest; + } + } +} + +// Bilinear interpolation (16 bits) - cmsFloat32Number version +static +void BilinearInterpFloat(const cmsFloat32Number Input[], + cmsFloat32Number Output[], + const cmsInterpParams* p) + +{ +# define LERP(a,l,h) (cmsFloat32Number) ((l)+(((h)-(l))*(a))) +# define DENS(i,j) (LutTable[(i)+(j)+OutChan]) + + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; + cmsFloat32Number px, py; + int x0, y0, + X0, Y0, X1, Y1; + int TotalOut, OutChan; + cmsFloat32Number fx, fy, + d00, d01, d10, d11, + dx0, dx1, + dxy; + + TotalOut = p -> nOutputs; + px = fclamp(Input[0]) * p->Domain[0]; + py = fclamp(Input[1]) * p->Domain[1]; + + x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0; + y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; + + X0 = p -> opta[1] * x0; + X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[1]); + + Y0 = p -> opta[0] * y0; + Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[0]); + + for (OutChan = 0; OutChan < TotalOut; OutChan++) { + + d00 = DENS(X0, Y0); + d01 = DENS(X0, Y1); + d10 = DENS(X1, Y0); + d11 = DENS(X1, Y1); + + dx0 = LERP(fx, d00, d10); + dx1 = LERP(fx, d01, d11); + + dxy = LERP(fy, dx0, dx1); + + Output[OutChan] = dxy; + } + + +# undef LERP +# undef DENS +} + +// Bilinear interpolation (16 bits) - optimized version +static CMS_NO_SANITIZE +void BilinearInterp16(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const cmsInterpParams* p) + +{ +#define DENS(i,j) (LutTable[(i)+(j)+OutChan]) +#define LERP(a,l,h) (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a))) + + const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table; + int OutChan, TotalOut; + cmsS15Fixed16Number fx, fy; + CMSREGISTER int rx, ry; + int x0, y0; + CMSREGISTER int X0, X1, Y0, Y1; + + int d00, d01, d10, d11, + dx0, dx1, + dxy; + + TotalOut = p -> nOutputs; + + fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]); + x0 = FIXED_TO_INT(fx); + rx = FIXED_REST_TO_INT(fx); // Rest in 0..1.0 domain + + + fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]); + y0 = FIXED_TO_INT(fy); + ry = FIXED_REST_TO_INT(fy); + + + X0 = p -> opta[1] * x0; + X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[1]); + + Y0 = p -> opta[0] * y0; + Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[0]); + + for (OutChan = 0; OutChan < TotalOut; OutChan++) { + + d00 = DENS(X0, Y0); + d01 = DENS(X0, Y1); + d10 = DENS(X1, Y0); + d11 = DENS(X1, Y1); + + dx0 = LERP(rx, d00, d10); + dx1 = LERP(rx, d01, d11); + + dxy = LERP(ry, dx0, dx1); + + Output[OutChan] = (cmsUInt16Number) dxy; + } + + +# undef LERP +# undef DENS +} + + +// Trilinear interpolation (16 bits) - cmsFloat32Number version +static +void TrilinearInterpFloat(const cmsFloat32Number Input[], + cmsFloat32Number Output[], + const cmsInterpParams* p) + +{ +# define LERP(a,l,h) (cmsFloat32Number) ((l)+(((h)-(l))*(a))) +# define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan]) + + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; + cmsFloat32Number px, py, pz; + int x0, y0, z0, + X0, Y0, Z0, X1, Y1, Z1; + int TotalOut, OutChan; + + cmsFloat32Number fx, fy, fz, + d000, d001, d010, d011, + d100, d101, d110, d111, + dx00, dx01, dx10, dx11, + dxy0, dxy1, dxyz; + + TotalOut = p -> nOutputs; + + // We need some clipping here + px = fclamp(Input[0]) * p->Domain[0]; + py = fclamp(Input[1]) * p->Domain[1]; + pz = fclamp(Input[2]) * p->Domain[2]; + + x0 = (int) floor(px); fx = px - (cmsFloat32Number) x0; // We need full floor funcionality here + y0 = (int) floor(py); fy = py - (cmsFloat32Number) y0; + z0 = (int) floor(pz); fz = pz - (cmsFloat32Number) z0; + + X0 = p -> opta[2] * x0; + X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]); + + Y0 = p -> opta[1] * y0; + Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]); + + Z0 = p -> opta[0] * z0; + Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]); + + for (OutChan = 0; OutChan < TotalOut; OutChan++) { + + d000 = DENS(X0, Y0, Z0); + d001 = DENS(X0, Y0, Z1); + d010 = DENS(X0, Y1, Z0); + d011 = DENS(X0, Y1, Z1); + + d100 = DENS(X1, Y0, Z0); + d101 = DENS(X1, Y0, Z1); + d110 = DENS(X1, Y1, Z0); + d111 = DENS(X1, Y1, Z1); + + + dx00 = LERP(fx, d000, d100); + dx01 = LERP(fx, d001, d101); + dx10 = LERP(fx, d010, d110); + dx11 = LERP(fx, d011, d111); + + dxy0 = LERP(fy, dx00, dx10); + dxy1 = LERP(fy, dx01, dx11); + + dxyz = LERP(fz, dxy0, dxy1); + + Output[OutChan] = dxyz; + } + + +# undef LERP +# undef DENS +} + +// Trilinear interpolation (16 bits) - optimized version +static CMS_NO_SANITIZE +void TrilinearInterp16(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const cmsInterpParams* p) + +{ +#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan]) +#define LERP(a,l,h) (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a))) + + const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table; + int OutChan, TotalOut; + cmsS15Fixed16Number fx, fy, fz; + CMSREGISTER int rx, ry, rz; + int x0, y0, z0; + CMSREGISTER int X0, X1, Y0, Y1, Z0, Z1; + int d000, d001, d010, d011, + d100, d101, d110, d111, + dx00, dx01, dx10, dx11, + dxy0, dxy1, dxyz; + + TotalOut = p -> nOutputs; + + fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]); + x0 = FIXED_TO_INT(fx); + rx = FIXED_REST_TO_INT(fx); // Rest in 0..1.0 domain + + + fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]); + y0 = FIXED_TO_INT(fy); + ry = FIXED_REST_TO_INT(fy); + + fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]); + z0 = FIXED_TO_INT(fz); + rz = FIXED_REST_TO_INT(fz); + + + X0 = p -> opta[2] * x0; + X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[2]); + + Y0 = p -> opta[1] * y0; + Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[1]); + + Z0 = p -> opta[0] * z0; + Z1 = Z0 + (Input[2] == 0xFFFFU ? 0 : p->opta[0]); + + for (OutChan = 0; OutChan < TotalOut; OutChan++) { + + d000 = DENS(X0, Y0, Z0); + d001 = DENS(X0, Y0, Z1); + d010 = DENS(X0, Y1, Z0); + d011 = DENS(X0, Y1, Z1); + + d100 = DENS(X1, Y0, Z0); + d101 = DENS(X1, Y0, Z1); + d110 = DENS(X1, Y1, Z0); + d111 = DENS(X1, Y1, Z1); + + + dx00 = LERP(rx, d000, d100); + dx01 = LERP(rx, d001, d101); + dx10 = LERP(rx, d010, d110); + dx11 = LERP(rx, d011, d111); + + dxy0 = LERP(ry, dx00, dx10); + dxy1 = LERP(ry, dx01, dx11); + + dxyz = LERP(rz, dxy0, dxy1); + + Output[OutChan] = (cmsUInt16Number) dxyz; + } + + +# undef LERP +# undef DENS +} + + +// Tetrahedral interpolation, using Sakamoto algorithm. +#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan]) +static +void TetrahedralInterpFloat(const cmsFloat32Number Input[], + cmsFloat32Number Output[], + const cmsInterpParams* p) +{ + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table; + cmsFloat32Number px, py, pz; + int x0, y0, z0, + X0, Y0, Z0, X1, Y1, Z1; + cmsFloat32Number rx, ry, rz; + cmsFloat32Number c0, c1=0, c2=0, c3=0; + int OutChan, TotalOut; + + TotalOut = p -> nOutputs; + + // We need some clipping here + px = fclamp(Input[0]) * p->Domain[0]; + py = fclamp(Input[1]) * p->Domain[1]; + pz = fclamp(Input[2]) * p->Domain[2]; + + x0 = (int) floor(px); rx = (px - (cmsFloat32Number) x0); // We need full floor functionality here + y0 = (int) floor(py); ry = (py - (cmsFloat32Number) y0); + z0 = (int) floor(pz); rz = (pz - (cmsFloat32Number) z0); + + + X0 = p -> opta[2] * x0; + X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]); + + Y0 = p -> opta[1] * y0; + Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]); + + Z0 = p -> opta[0] * z0; + Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]); + + for (OutChan=0; OutChan < TotalOut; OutChan++) { + + // These are the 6 Tetrahedral + + c0 = DENS(X0, Y0, Z0); + + if (rx >= ry && ry >= rz) { + + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0); + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + + } + else + if (rx >= rz && rz >= ry) { + + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0); + + } + else + if (rz >= rx && rx >= ry) { + + c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1); + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + + } + else + if (ry >= rx && rx >= rz) { + + c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + + } + else + if (ry >= rz && rz >= rx) { + + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0); + + } + else + if (rz >= ry && ry >= rx) { + + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + + } + else { + c1 = c2 = c3 = 0; + } + + Output[OutChan] = c0 + c1 * rx + c2 * ry + c3 * rz; + } + +} + +#undef DENS + +static CMS_NO_SANITIZE +void TetrahedralInterp16(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const cmsInterpParams* p) +{ + const cmsUInt16Number* LutTable = (cmsUInt16Number*) p -> Table; + cmsS15Fixed16Number fx, fy, fz; + cmsS15Fixed16Number rx, ry, rz; + int x0, y0, z0; + cmsS15Fixed16Number c0, c1, c2, c3, Rest; + cmsUInt32Number X0, X1, Y0, Y1, Z0, Z1; + cmsUInt32Number TotalOut = p -> nOutputs; + + fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]); + fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]); + fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]); + + x0 = FIXED_TO_INT(fx); + y0 = FIXED_TO_INT(fy); + z0 = FIXED_TO_INT(fz); + + rx = FIXED_REST_TO_INT(fx); + ry = FIXED_REST_TO_INT(fy); + rz = FIXED_REST_TO_INT(fz); + + X0 = p -> opta[2] * x0; + X1 = (Input[0] == 0xFFFFU ? 0 : p->opta[2]); + + Y0 = p -> opta[1] * y0; + Y1 = (Input[1] == 0xFFFFU ? 0 : p->opta[1]); + + Z0 = p -> opta[0] * z0; + Z1 = (Input[2] == 0xFFFFU ? 0 : p->opta[0]); + + LutTable += X0+Y0+Z0; + + // Output should be computed as x = ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)) + // which expands as: x = (Rest + ((Rest+0x7fff)/0xFFFF) + 0x8000)>>16 + // This can be replaced by: t = Rest+0x8001, x = (t + (t>>16))>>16 + // at the cost of being off by one at 7fff and 17ffe. + + if (rx >= ry) { + if (ry >= rz) { + Y1 += X1; + Z1 += Y1; + for (; TotalOut; TotalOut--) { + c1 = LutTable[X1]; + c2 = LutTable[Y1]; + c3 = LutTable[Z1]; + c0 = *LutTable++; + c3 -= c2; + c2 -= c1; + c1 -= c0; + Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; + *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16); + } + } else if (rz >= rx) { + X1 += Z1; + Y1 += X1; + for (; TotalOut; TotalOut--) { + c1 = LutTable[X1]; + c2 = LutTable[Y1]; + c3 = LutTable[Z1]; + c0 = *LutTable++; + c2 -= c1; + c1 -= c3; + c3 -= c0; + Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; + *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16); + } + } else { + Z1 += X1; + Y1 += Z1; + for (; TotalOut; TotalOut--) { + c1 = LutTable[X1]; + c2 = LutTable[Y1]; + c3 = LutTable[Z1]; + c0 = *LutTable++; + c2 -= c3; + c3 -= c1; + c1 -= c0; + Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; + *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16); + } + } + } else { + if (rx >= rz) { + X1 += Y1; + Z1 += X1; + for (; TotalOut; TotalOut--) { + c1 = LutTable[X1]; + c2 = LutTable[Y1]; + c3 = LutTable[Z1]; + c0 = *LutTable++; + c3 -= c1; + c1 -= c2; + c2 -= c0; + Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; + *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16); + } + } else if (ry >= rz) { + Z1 += Y1; + X1 += Z1; + for (; TotalOut; TotalOut--) { + c1 = LutTable[X1]; + c2 = LutTable[Y1]; + c3 = LutTable[Z1]; + c0 = *LutTable++; + c1 -= c3; + c3 -= c2; + c2 -= c0; + Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; + *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16); + } + } else { + Y1 += Z1; + X1 += Y1; + for (; TotalOut; TotalOut--) { + c1 = LutTable[X1]; + c2 = LutTable[Y1]; + c3 = LutTable[Z1]; + c0 = *LutTable++; + c1 -= c2; + c2 -= c3; + c3 -= c0; + Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; + *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16); + } + } + } +} + + +#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan]) +static CMS_NO_SANITIZE +void Eval4Inputs(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const cmsInterpParams* p16) +{ + const cmsUInt16Number* LutTable; + cmsS15Fixed16Number fk; + cmsS15Fixed16Number k0, rk; + int K0, K1; + cmsS15Fixed16Number fx, fy, fz; + cmsS15Fixed16Number rx, ry, rz; + int x0, y0, z0; + cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1; + cmsUInt32Number i; + cmsS15Fixed16Number c0, c1, c2, c3, Rest; + cmsUInt32Number OutChan; + cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; + + + fk = _cmsToFixedDomain((int) Input[0] * p16 -> Domain[0]); + fx = _cmsToFixedDomain((int) Input[1] * p16 -> Domain[1]); + fy = _cmsToFixedDomain((int) Input[2] * p16 -> Domain[2]); + fz = _cmsToFixedDomain((int) Input[3] * p16 -> Domain[3]); + + k0 = FIXED_TO_INT(fk); + x0 = FIXED_TO_INT(fx); + y0 = FIXED_TO_INT(fy); + z0 = FIXED_TO_INT(fz); + + rk = FIXED_REST_TO_INT(fk); + rx = FIXED_REST_TO_INT(fx); + ry = FIXED_REST_TO_INT(fy); + rz = FIXED_REST_TO_INT(fz); + + K0 = p16 -> opta[3] * k0; + K1 = K0 + (Input[0] == 0xFFFFU ? 0 : p16->opta[3]); + + X0 = p16 -> opta[2] * x0; + X1 = X0 + (Input[1] == 0xFFFFU ? 0 : p16->opta[2]); + + Y0 = p16 -> opta[1] * y0; + Y1 = Y0 + (Input[2] == 0xFFFFU ? 0 : p16->opta[1]); + + Z0 = p16 -> opta[0] * z0; + Z1 = Z0 + (Input[3] == 0xFFFFU ? 0 : p16->opta[0]); + + LutTable = (cmsUInt16Number*) p16 -> Table; + LutTable += K0; + + for (OutChan=0; OutChan < p16 -> nOutputs; OutChan++) { + + c0 = DENS(X0, Y0, Z0); + + if (rx >= ry && ry >= rz) { + + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0); + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + + } + else + if (rx >= rz && rz >= ry) { + + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0); + + } + else + if (rz >= rx && rx >= ry) { + + c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1); + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + + } + else + if (ry >= rx && rx >= rz) { + + c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + + } + else + if (ry >= rz && rz >= rx) { + + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0); + + } + else + if (rz >= ry && ry >= rx) { + + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + + } + else { + c1 = c2 = c3 = 0; + } + + Rest = c1 * rx + c2 * ry + c3 * rz; + + Tmp1[OutChan] = (cmsUInt16Number)(c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))); + } + + + LutTable = (cmsUInt16Number*) p16 -> Table; + LutTable += K1; + + for (OutChan=0; OutChan < p16 -> nOutputs; OutChan++) { + + c0 = DENS(X0, Y0, Z0); + + if (rx >= ry && ry >= rz) { + + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0); + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + + } + else + if (rx >= rz && rz >= ry) { + + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0); + + } + else + if (rz >= rx && rx >= ry) { + + c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1); + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + + } + else + if (ry >= rx && rx >= rz) { + + c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + + } + else + if (ry >= rz && rz >= rx) { + + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0); + + } + else + if (rz >= ry && ry >= rx) { + + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + + } + else { + c1 = c2 = c3 = 0; + } + + Rest = c1 * rx + c2 * ry + c3 * rz; + + Tmp2[OutChan] = (cmsUInt16Number) (c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))); + } + + + + for (i=0; i < p16 -> nOutputs; i++) { + Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]); + } +} +#undef DENS + + +// For more that 3 inputs (i.e., CMYK) +// evaluate two 3-dimensional interpolations and then linearly interpolate between them. +static +void Eval4InputsFloat(const cmsFloat32Number Input[], + cmsFloat32Number Output[], + const cmsInterpParams* p) +{ + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table; + cmsFloat32Number rest; + cmsFloat32Number pk; + int k0, K0, K1; + const cmsFloat32Number* T; + cmsUInt32Number i; + cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; + cmsInterpParams p1; + + pk = fclamp(Input[0]) * p->Domain[0]; + k0 = _cmsQuickFloor(pk); + rest = pk - (cmsFloat32Number) k0; + + K0 = p -> opta[3] * k0; + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[3]); + + p1 = *p; + memmove(&p1.Domain[0], &p ->Domain[1], 3*sizeof(cmsUInt32Number)); + + T = LutTable + K0; + p1.Table = T; + + TetrahedralInterpFloat(Input + 1, Tmp1, &p1); + + T = LutTable + K1; + p1.Table = T; + TetrahedralInterpFloat(Input + 1, Tmp2, &p1); + + for (i=0; i < p -> nOutputs; i++) + { + cmsFloat32Number y0 = Tmp1[i]; + cmsFloat32Number y1 = Tmp2[i]; + + Output[i] = y0 + (y1 - y0) * rest; + } +} + +#define EVAL_FNS(N,NM) static CMS_NO_SANITIZE \ +void Eval##N##Inputs(CMSREGISTER const cmsUInt16Number Input[], CMSREGISTER cmsUInt16Number Output[], CMSREGISTER const cmsInterpParams* p16)\ +{\ + const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;\ + cmsS15Fixed16Number fk;\ + cmsS15Fixed16Number k0, rk;\ + int K0, K1;\ + const cmsUInt16Number* T;\ + cmsUInt32Number i;\ + cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\ + cmsInterpParams p1;\ +\ + fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);\ + k0 = FIXED_TO_INT(fk);\ + rk = FIXED_REST_TO_INT(fk);\ +\ + K0 = p16 -> opta[NM] * k0;\ + K1 = p16 -> opta[NM] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));\ +\ + p1 = *p16;\ + memmove(&p1.Domain[0], &p16 ->Domain[1], NM*sizeof(cmsUInt32Number));\ +\ + T = LutTable + K0;\ + p1.Table = T;\ +\ + Eval##NM##Inputs(Input + 1, Tmp1, &p1);\ +\ + T = LutTable + K1;\ + p1.Table = T;\ +\ + Eval##NM##Inputs(Input + 1, Tmp2, &p1);\ +\ + for (i=0; i < p16 -> nOutputs; i++) {\ +\ + Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);\ + }\ +}\ +\ +static void Eval##N##InputsFloat(const cmsFloat32Number Input[], \ + cmsFloat32Number Output[],\ + const cmsInterpParams * p)\ +{\ + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;\ + cmsFloat32Number rest;\ + cmsFloat32Number pk;\ + int k0, K0, K1;\ + const cmsFloat32Number* T;\ + cmsUInt32Number i;\ + cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\ + cmsInterpParams p1;\ +\ + pk = fclamp(Input[0]) * p->Domain[0];\ + k0 = _cmsQuickFloor(pk);\ + rest = pk - (cmsFloat32Number) k0;\ +\ + K0 = p -> opta[NM] * k0;\ + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[NM]);\ +\ + p1 = *p;\ + memmove(&p1.Domain[0], &p ->Domain[1], NM*sizeof(cmsUInt32Number));\ +\ + T = LutTable + K0;\ + p1.Table = T;\ +\ + Eval##NM##InputsFloat(Input + 1, Tmp1, &p1);\ +\ + T = LutTable + K1;\ + p1.Table = T;\ +\ + Eval##NM##InputsFloat(Input + 1, Tmp2, &p1);\ +\ + for (i=0; i < p -> nOutputs; i++) {\ +\ + cmsFloat32Number y0 = Tmp1[i];\ + cmsFloat32Number y1 = Tmp2[i];\ +\ + Output[i] = y0 + (y1 - y0) * rest;\ + }\ +} + + +/** +* Thanks to Carles Llopis for the templating idea +*/ +EVAL_FNS(5, 4) +EVAL_FNS(6, 5) +EVAL_FNS(7, 6) +EVAL_FNS(8, 7) +EVAL_FNS(9, 8) +EVAL_FNS(10, 9) +EVAL_FNS(11, 10) +EVAL_FNS(12, 11) +EVAL_FNS(13, 12) +EVAL_FNS(14, 13) +EVAL_FNS(15, 14) + + +// The default factory +static +cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags) +{ + + cmsInterpFunction Interpolation; + cmsBool IsFloat = (dwFlags & CMS_LERP_FLAGS_FLOAT); + cmsBool IsTrilinear = (dwFlags & CMS_LERP_FLAGS_TRILINEAR); + + memset(&Interpolation, 0, sizeof(Interpolation)); + + // Safety check + if (nInputChannels >= 4 && nOutputChannels >= MAX_STAGE_CHANNELS) + return Interpolation; + + switch (nInputChannels) { + + case 1: // Gray LUT / linear + + if (nOutputChannels == 1) { + + if (IsFloat) + Interpolation.LerpFloat = LinLerp1Dfloat; + else + Interpolation.Lerp16 = LinLerp1D; + + } + else { + + if (IsFloat) + Interpolation.LerpFloat = Eval1InputFloat; + else + Interpolation.Lerp16 = Eval1Input; + } + break; + + case 2: // Duotone + if (IsFloat) + Interpolation.LerpFloat = BilinearInterpFloat; + else + Interpolation.Lerp16 = BilinearInterp16; + break; + + case 3: // RGB et al + + if (IsTrilinear) { + + if (IsFloat) + Interpolation.LerpFloat = TrilinearInterpFloat; + else + Interpolation.Lerp16 = TrilinearInterp16; + } + else { + + if (IsFloat) + Interpolation.LerpFloat = TetrahedralInterpFloat; + else { + + Interpolation.Lerp16 = TetrahedralInterp16; + } + } + break; + + case 4: // CMYK lut + + if (IsFloat) + Interpolation.LerpFloat = Eval4InputsFloat; + else + Interpolation.Lerp16 = Eval4Inputs; + break; + + case 5: // 5 Inks + if (IsFloat) + Interpolation.LerpFloat = Eval5InputsFloat; + else + Interpolation.Lerp16 = Eval5Inputs; + break; + + case 6: // 6 Inks + if (IsFloat) + Interpolation.LerpFloat = Eval6InputsFloat; + else + Interpolation.Lerp16 = Eval6Inputs; + break; + + case 7: // 7 inks + if (IsFloat) + Interpolation.LerpFloat = Eval7InputsFloat; + else + Interpolation.Lerp16 = Eval7Inputs; + break; + + case 8: // 8 inks + if (IsFloat) + Interpolation.LerpFloat = Eval8InputsFloat; + else + Interpolation.Lerp16 = Eval8Inputs; + break; + + case 9: + if (IsFloat) + Interpolation.LerpFloat = Eval9InputsFloat; + else + Interpolation.Lerp16 = Eval9Inputs; + break; + + case 10: + if (IsFloat) + Interpolation.LerpFloat = Eval10InputsFloat; + else + Interpolation.Lerp16 = Eval10Inputs; + break; + + case 11: + if (IsFloat) + Interpolation.LerpFloat = Eval11InputsFloat; + else + Interpolation.Lerp16 = Eval11Inputs; + break; + + case 12: + if (IsFloat) + Interpolation.LerpFloat = Eval12InputsFloat; + else + Interpolation.Lerp16 = Eval12Inputs; + break; + + case 13: + if (IsFloat) + Interpolation.LerpFloat = Eval13InputsFloat; + else + Interpolation.Lerp16 = Eval13Inputs; + break; + + case 14: + if (IsFloat) + Interpolation.LerpFloat = Eval14InputsFloat; + else + Interpolation.Lerp16 = Eval14Inputs; + break; + + case 15: + if (IsFloat) + Interpolation.LerpFloat = Eval15InputsFloat; + else + Interpolation.Lerp16 = Eval15Inputs; + break; + + default: + Interpolation.Lerp16 = NULL; + } + + return Interpolation; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsio0.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsio0.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsio0.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsio0.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,2115 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// Generic I/O, tag dictionary management, profile struct + +// IOhandlers are abstractions used by littleCMS to read from whatever file, stream, +// memory block or any storage. Each IOhandler provides implementations for read, +// write, seek and tell functions. LittleCMS code deals with IO across those objects. +// In this way, is easier to add support for new storage media. + +// NULL stream, for taking care of used space ------------------------------------- + +// NULL IOhandler basically does nothing but keep track on how many bytes have been +// written. This is handy when creating profiles, where the file size is needed in the +// header. Then, whole profile is serialized across NULL IOhandler and a second pass +// writes the bytes to the pertinent IOhandler. + +typedef struct { + cmsUInt32Number Pointer; // Points to current location +} FILENULL; + +static +cmsUInt32Number NULLRead(cmsIOHANDLER* iohandler, void *Buffer, cmsUInt32Number size, cmsUInt32Number count) +{ + FILENULL* ResData = (FILENULL*) iohandler ->stream; + + cmsUInt32Number len = size * count; + ResData -> Pointer += len; + return count; + + cmsUNUSED_PARAMETER(Buffer); +} + +static +cmsBool NULLSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset) +{ + FILENULL* ResData = (FILENULL*) iohandler ->stream; + + ResData ->Pointer = offset; + return TRUE; +} + +static +cmsUInt32Number NULLTell(cmsIOHANDLER* iohandler) +{ + FILENULL* ResData = (FILENULL*) iohandler ->stream; + return ResData -> Pointer; +} + +static +cmsBool NULLWrite(cmsIOHANDLER* iohandler, cmsUInt32Number size, const void *Ptr) +{ + FILENULL* ResData = (FILENULL*) iohandler ->stream; + + ResData ->Pointer += size; + if (ResData ->Pointer > iohandler->UsedSpace) + iohandler->UsedSpace = ResData ->Pointer; + + return TRUE; + + cmsUNUSED_PARAMETER(Ptr); +} + +static +cmsBool NULLClose(cmsIOHANDLER* iohandler) +{ + FILENULL* ResData = (FILENULL*) iohandler ->stream; + + _cmsFree(iohandler ->ContextID, ResData); + _cmsFree(iohandler ->ContextID, iohandler); + return TRUE; +} + +// The NULL IOhandler creator +cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromNULL(cmsContext ContextID) +{ + struct _cms_io_handler* iohandler = NULL; + FILENULL* fm = NULL; + + iohandler = (struct _cms_io_handler*) _cmsMallocZero(ContextID, sizeof(struct _cms_io_handler)); + if (iohandler == NULL) return NULL; + + fm = (FILENULL*) _cmsMallocZero(ContextID, sizeof(FILENULL)); + if (fm == NULL) goto Error; + + fm ->Pointer = 0; + + iohandler ->ContextID = ContextID; + iohandler ->stream = (void*) fm; + iohandler ->UsedSpace = 0; + iohandler ->ReportedSize = 0; + iohandler ->PhysicalFile[0] = 0; + + iohandler ->Read = NULLRead; + iohandler ->Seek = NULLSeek; + iohandler ->Close = NULLClose; + iohandler ->Tell = NULLTell; + iohandler ->Write = NULLWrite; + + return iohandler; + +Error: + if (iohandler) _cmsFree(ContextID, iohandler); + return NULL; + +} + + +// Memory-based stream -------------------------------------------------------------- + +// Those functions implements an iohandler which takes a block of memory as storage medium. + +typedef struct { + cmsUInt8Number* Block; // Points to allocated memory + cmsUInt32Number Size; // Size of allocated memory + cmsUInt32Number Pointer; // Points to current location + int FreeBlockOnClose; // As title + +} FILEMEM; + +static +cmsUInt32Number MemoryRead(struct _cms_io_handler* iohandler, void *Buffer, cmsUInt32Number size, cmsUInt32Number count) +{ + FILEMEM* ResData = (FILEMEM*) iohandler ->stream; + cmsUInt8Number* Ptr; + cmsUInt32Number len = size * count; + + if (ResData -> Pointer + len > ResData -> Size){ + + len = (ResData -> Size - ResData -> Pointer); + cmsSignalError(iohandler ->ContextID, cmsERROR_READ, "Read from memory error. Got %d bytes, block should be of %d bytes", len, count * size); + return 0; + } + + Ptr = ResData -> Block; + Ptr += ResData -> Pointer; + memmove(Buffer, Ptr, len); + ResData -> Pointer += len; + + return count; +} + +// SEEK_CUR is assumed +static +cmsBool MemorySeek(struct _cms_io_handler* iohandler, cmsUInt32Number offset) +{ + FILEMEM* ResData = (FILEMEM*) iohandler ->stream; + + if (offset > ResData ->Size) { + cmsSignalError(iohandler ->ContextID, cmsERROR_SEEK, "Too few data; probably corrupted profile"); + return FALSE; + } + + ResData ->Pointer = offset; + return TRUE; +} + +// Tell for memory +static +cmsUInt32Number MemoryTell(struct _cms_io_handler* iohandler) +{ + FILEMEM* ResData = (FILEMEM*) iohandler ->stream; + + if (ResData == NULL) return 0; + return ResData -> Pointer; +} + + +// Writes data to memory, also keeps used space for further reference. +static +cmsBool MemoryWrite(struct _cms_io_handler* iohandler, cmsUInt32Number size, const void *Ptr) +{ + FILEMEM* ResData = (FILEMEM*) iohandler ->stream; + + if (ResData == NULL) return FALSE; // Housekeeping + + // Check for available space. Clip. + if (ResData->Pointer + size > ResData->Size) { + size = ResData ->Size - ResData->Pointer; + } + + if (size == 0) return TRUE; // Write zero bytes is ok, but does nothing + + memmove(ResData ->Block + ResData ->Pointer, Ptr, size); + ResData ->Pointer += size; + + if (ResData ->Pointer > iohandler->UsedSpace) + iohandler->UsedSpace = ResData ->Pointer; + + return TRUE; +} + + +static +cmsBool MemoryClose(struct _cms_io_handler* iohandler) +{ + FILEMEM* ResData = (FILEMEM*) iohandler ->stream; + + if (ResData ->FreeBlockOnClose) { + + if (ResData ->Block) _cmsFree(iohandler ->ContextID, ResData ->Block); + } + + _cmsFree(iohandler ->ContextID, ResData); + _cmsFree(iohandler ->ContextID, iohandler); + + return TRUE; +} + +// Create a iohandler for memory block. AccessMode=='r' assumes the iohandler is going to read, and makes +// a copy of the memory block for letting user to free the memory after invoking open profile. In write +// mode ("w"), Buffer points to the begin of memory block to be written. +cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buffer, cmsUInt32Number size, const char* AccessMode) +{ + cmsIOHANDLER* iohandler = NULL; + FILEMEM* fm = NULL; + + _cmsAssert(AccessMode != NULL); + + iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER)); + if (iohandler == NULL) return NULL; + + switch (*AccessMode) { + + case 'r': + fm = (FILEMEM*) _cmsMallocZero(ContextID, sizeof(FILEMEM)); + if (fm == NULL) goto Error; + + if (Buffer == NULL) { + cmsSignalError(ContextID, cmsERROR_READ, "Couldn't read profile from NULL pointer"); + goto Error; + } + + fm ->Block = (cmsUInt8Number*) _cmsMalloc(ContextID, size); + if (fm ->Block == NULL) { + + _cmsFree(ContextID, fm); + _cmsFree(ContextID, iohandler); + cmsSignalError(ContextID, cmsERROR_READ, "Couldn't allocate %ld bytes for profile", (long) size); + return NULL; + } + + + memmove(fm->Block, Buffer, size); + fm ->FreeBlockOnClose = TRUE; + fm ->Size = size; + fm ->Pointer = 0; + iohandler -> ReportedSize = size; + break; + + case 'w': + fm = (FILEMEM*) _cmsMallocZero(ContextID, sizeof(FILEMEM)); + if (fm == NULL) goto Error; + + fm ->Block = (cmsUInt8Number*) Buffer; + fm ->FreeBlockOnClose = FALSE; + fm ->Size = size; + fm ->Pointer = 0; + iohandler -> ReportedSize = 0; + break; + + default: + cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown access mode '%c'", *AccessMode); + return NULL; + } + + iohandler ->ContextID = ContextID; + iohandler ->stream = (void*) fm; + iohandler ->UsedSpace = 0; + iohandler ->PhysicalFile[0] = 0; + + iohandler ->Read = MemoryRead; + iohandler ->Seek = MemorySeek; + iohandler ->Close = MemoryClose; + iohandler ->Tell = MemoryTell; + iohandler ->Write = MemoryWrite; + + return iohandler; + +Error: + if (fm) _cmsFree(ContextID, fm); + if (iohandler) _cmsFree(ContextID, iohandler); + return NULL; +} + +// File-based stream ------------------------------------------------------- + +// Read count elements of size bytes each. Return number of elements read +static +cmsUInt32Number FileRead(cmsIOHANDLER* iohandler, void *Buffer, cmsUInt32Number size, cmsUInt32Number count) +{ + cmsUInt32Number nReaded = (cmsUInt32Number) fread(Buffer, size, count, (FILE*) iohandler->stream); + + if (nReaded != count) { + cmsSignalError(iohandler ->ContextID, cmsERROR_FILE, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size); + return 0; + } + + return nReaded; +} + +// Position file pointer in the file +static +cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset) +{ + if (fseek((FILE*) iohandler ->stream, (long) offset, SEEK_SET) != 0) { + + cmsSignalError(iohandler ->ContextID, cmsERROR_FILE, "Seek error; probably corrupted file"); + return FALSE; + } + + return TRUE; +} + +// Returns file pointer position or 0 on error, which is also a valid position. +static +cmsUInt32Number FileTell(cmsIOHANDLER* iohandler) +{ + long t = ftell((FILE*)iohandler ->stream); + if (t == -1L) { + cmsSignalError(iohandler->ContextID, cmsERROR_FILE, "Tell error; probably corrupted file"); + return 0; + } + + return (cmsUInt32Number)t; +} + +// Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error +static +cmsBool FileWrite(cmsIOHANDLER* iohandler, cmsUInt32Number size, const void* Buffer) +{ + if (size == 0) return TRUE; // We allow to write 0 bytes, but nothing is written + + iohandler->UsedSpace += size; + return (fwrite(Buffer, size, 1, (FILE*)iohandler->stream) == 1); +} + +// Closes the file +static +cmsBool FileClose(cmsIOHANDLER* iohandler) +{ + if (fclose((FILE*) iohandler ->stream) != 0) return FALSE; + _cmsFree(iohandler ->ContextID, iohandler); + return TRUE; +} + +// Create a iohandler for disk based files. +cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const char* FileName, const char* AccessMode) +{ + cmsIOHANDLER* iohandler = NULL; + FILE* fm = NULL; + cmsInt32Number fileLen; + char mode[4] = { 0,0,0,0 }; + + _cmsAssert(FileName != NULL); + _cmsAssert(AccessMode != NULL); + + iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER)); + if (iohandler == NULL) return NULL; + + // Validate access mode + while (*AccessMode) { + + switch (*AccessMode) + { + case 'r': + case 'w': + + if (mode[0] == 0) { + mode[0] = *AccessMode; + mode[1] = 'b'; + } + else { + _cmsFree(ContextID, iohandler); + cmsSignalError(ContextID, cmsERROR_FILE, "Access mode already specified '%c'", *AccessMode); + return NULL; + } + break; + + // Close on exec. Not all runtime supports that. Up to the caller to decide. + case 'e': + mode[2] = 'e'; + break; + + default: + _cmsFree(ContextID, iohandler); + cmsSignalError(ContextID, cmsERROR_FILE, "Wrong access mode '%c'", *AccessMode); + return NULL; + } + + AccessMode++; + } + + switch (mode[0]) { + + case 'r': + fm = fopen(FileName, mode); + if (fm == NULL) { + _cmsFree(ContextID, iohandler); + cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName); + return NULL; + } + fileLen = (cmsInt32Number)cmsfilelength(fm); + if (fileLen < 0) + { + fclose(fm); + _cmsFree(ContextID, iohandler); + cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName); + return NULL; + } + iohandler -> ReportedSize = (cmsUInt32Number) fileLen; + break; + + case 'w': + fm = fopen(FileName, mode); + if (fm == NULL) { + _cmsFree(ContextID, iohandler); + cmsSignalError(ContextID, cmsERROR_FILE, "Couldn't create '%s'", FileName); + return NULL; + } + iohandler -> ReportedSize = 0; + break; + + default: + _cmsFree(ContextID, iohandler); // Would never reach + return NULL; + } + + iohandler ->ContextID = ContextID; + iohandler ->stream = (void*) fm; + iohandler ->UsedSpace = 0; + + // Keep track of the original file + strncpy(iohandler -> PhysicalFile, FileName, sizeof(iohandler -> PhysicalFile)-1); + iohandler -> PhysicalFile[sizeof(iohandler -> PhysicalFile)-1] = 0; + + iohandler ->Read = FileRead; + iohandler ->Seek = FileSeek; + iohandler ->Close = FileClose; + iohandler ->Tell = FileTell; + iohandler ->Write = FileWrite; + + return iohandler; +} + +// Create a iohandler for stream based files +cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream) +{ + cmsIOHANDLER* iohandler = NULL; + cmsInt32Number fileSize; + + fileSize = (cmsInt32Number)cmsfilelength(Stream); + if (fileSize < 0) + { + cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream"); + return NULL; + } + + iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER)); + if (iohandler == NULL) return NULL; + + iohandler -> ContextID = ContextID; + iohandler -> stream = (void*) Stream; + iohandler -> UsedSpace = 0; + iohandler -> ReportedSize = (cmsUInt32Number) fileSize; + iohandler -> PhysicalFile[0] = 0; + + iohandler ->Read = FileRead; + iohandler ->Seek = FileSeek; + iohandler ->Close = FileClose; + iohandler ->Tell = FileTell; + iohandler ->Write = FileWrite; + + return iohandler; +} + + + +// Close an open IO handler +cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io) +{ + return io -> Close(io); +} + +// ------------------------------------------------------------------------------------------------------- + +cmsIOHANDLER* CMSEXPORT cmsGetProfileIOhandler(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile; + + if (Icc == NULL) return NULL; + return Icc->IOhandler; +} + +// Creates an empty structure holding all required parameters +cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) _cmsMallocZero(ContextID, sizeof(_cmsICCPROFILE)); + if (Icc == NULL) return NULL; + + Icc ->ContextID = ContextID; + + // Set it to empty + Icc -> TagCount = 0; + + // Set default version + Icc ->Version = 0x02100000; + + // Set default device class + Icc->DeviceClass = cmsSigDisplayClass; + + // Set creation date/time + if (!_cmsGetTime(&Icc->Created)) + goto Error; + + // Create a mutex if the user provided proper plugin. NULL otherwise + Icc ->UsrMutex = _cmsCreateMutex(ContextID); + + // Return the handle + return (cmsHPROFILE) Icc; + +Error: + _cmsFree(ContextID, Icc); + return NULL; +} + +cmsContext CMSEXPORT cmsGetProfileContextID(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + + if (Icc == NULL) return NULL; + return Icc -> ContextID; +} + + +// Return the number of tags +cmsInt32Number CMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + if (Icc == NULL) return -1; + + return (cmsInt32Number) Icc->TagCount; +} + +// Return the tag signature of a given tag number +cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Number n) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + + if (n > Icc->TagCount) return (cmsTagSignature) 0; // Mark as not available + if (n >= MAX_TABLE_TAG) return (cmsTagSignature) 0; // As double check + + return Icc ->TagNames[n]; +} + + +static +int SearchOneTag(_cmsICCPROFILE* Profile, cmsTagSignature sig) +{ + int i; + + for (i=0; i < (int) Profile -> TagCount; i++) { + + if (sig == Profile -> TagNames[i]) + return i; + } + + return -1; +} + +// Search for a specific tag in tag dictionary. Returns position or -1 if tag not found. +// If followlinks is turned on, then the position of the linked tag is returned +int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks) +{ + int n; + cmsTagSignature LinkedSig; + + do { + + // Search for given tag in ICC profile directory + n = SearchOneTag(Icc, sig); + if (n < 0) + return -1; // Not found + + if (!lFollowLinks) + return n; // Found, don't follow links + + // Is this a linked tag? + LinkedSig = Icc ->TagLinked[n]; + + // Yes, follow link + if (LinkedSig != (cmsTagSignature) 0) { + sig = LinkedSig; + } + + } while (LinkedSig != (cmsTagSignature) 0); + + return n; +} + +// Deletes a tag entry + +static +void _cmsDeleteTagByPos(_cmsICCPROFILE* Icc, int i) +{ + _cmsAssert(Icc != NULL); + _cmsAssert(i >= 0); + + + if (Icc -> TagPtrs[i] != NULL) { + + // Free previous version + if (Icc ->TagSaveAsRaw[i]) { + _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]); + } + else { + cmsTagTypeHandler* TypeHandler = Icc ->TagTypeHandlers[i]; + + if (TypeHandler != NULL) { + + cmsTagTypeHandler LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; // As an additional parameter + LocalTypeHandler.ICCVersion = Icc ->Version; + LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]); + Icc ->TagPtrs[i] = NULL; + } + } + + } +} + + +// Creates a new tag entry +static +cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos) +{ + int i; + + // Search for the tag + i = _cmsSearchTag(Icc, sig, FALSE); + if (i >= 0) { + + // Already exists? delete it + _cmsDeleteTagByPos(Icc, i); + *NewPos = i; + } + else { + + // No, make a new one + if (Icc -> TagCount >= MAX_TABLE_TAG) { + cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG); + return FALSE; + } + + *NewPos = (int) Icc ->TagCount; + Icc -> TagCount++; + } + + return TRUE; +} + + +// Check existence +cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) (void*) hProfile; + return _cmsSearchTag(Icc, sig, FALSE) >= 0; +} + + + +// Checks for link compatibility +static +cmsBool CompatibleTypes(const cmsTagDescriptor* desc1, const cmsTagDescriptor* desc2) +{ + cmsUInt32Number i; + + if (desc1 == NULL || desc2 == NULL) return FALSE; + + if (desc1->nSupportedTypes != desc2->nSupportedTypes) return FALSE; + if (desc1->ElemCount != desc2->ElemCount) return FALSE; + + for (i = 0; i < desc1->nSupportedTypes; i++) + { + if (desc1->SupportedTypes[i] != desc2->SupportedTypes[i]) return FALSE; + } + + return TRUE; +} + +// Enforces that the profile version is per. spec. +// Operates on the big endian bytes from the profile. +// Called before converting to platform endianness. +// Byte 0 is BCD major version, so max 9. +// Byte 1 is 2 BCD digits, one per nibble. +// Reserved bytes 2 & 3 must be 0. +static +cmsUInt32Number _validatedVersion(cmsUInt32Number DWord) +{ + cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord; + cmsUInt8Number temp1; + cmsUInt8Number temp2; + + if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09; + temp1 = (cmsUInt8Number) (*(pByte+1) & 0xf0); + temp2 = (cmsUInt8Number) (*(pByte+1) & 0x0f); + if (temp1 > 0x90U) temp1 = 0x90U; + if (temp2 > 0x09U) temp2 = 0x09U; + *(pByte+1) = (cmsUInt8Number)(temp1 | temp2); + *(pByte+2) = (cmsUInt8Number)0; + *(pByte+3) = (cmsUInt8Number)0; + + return DWord; +} + +// Check device class +static +cmsBool validDeviceClass(cmsProfileClassSignature cl) +{ + if ((int)cl == 0) return TRUE; // We allow zero because older lcms versions defaulted to that. + + switch (cl) + { + case cmsSigInputClass: + case cmsSigDisplayClass: + case cmsSigOutputClass: + case cmsSigLinkClass: + case cmsSigAbstractClass: + case cmsSigColorSpaceClass: + case cmsSigNamedColorClass: + return TRUE; + + default: + return FALSE; + } + +} + +// Read profile header and validate it +cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc) +{ + cmsTagEntry Tag; + cmsICCHeader Header; + cmsUInt32Number i, j; + cmsUInt32Number HeaderSize; + cmsIOHANDLER* io = Icc ->IOhandler; + cmsUInt32Number TagCount; + + + // Read the header + if (io -> Read(io, &Header, sizeof(cmsICCHeader), 1) != 1) { + return FALSE; + } + + // Validate file as an ICC profile + if (_cmsAdjustEndianess32(Header.magic) != cmsMagicNumber) { + cmsSignalError(Icc ->ContextID, cmsERROR_BAD_SIGNATURE, "not an ICC profile, invalid signature"); + return FALSE; + } + + // Adjust endianness of the used parameters + Icc -> DeviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass); + Icc -> ColorSpace = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.colorSpace); + Icc -> PCS = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.pcs); + + Icc -> RenderingIntent = _cmsAdjustEndianess32(Header.renderingIntent); + Icc -> flags = _cmsAdjustEndianess32(Header.flags); + Icc -> manufacturer = _cmsAdjustEndianess32(Header.manufacturer); + Icc -> model = _cmsAdjustEndianess32(Header.model); + Icc -> creator = _cmsAdjustEndianess32(Header.creator); + + _cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes); + Icc -> Version = _cmsAdjustEndianess32(_validatedVersion(Header.version)); + + if (Icc->Version > 0x5000000) { + cmsSignalError(Icc->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported profile version '0x%x'", Icc->Version); + return FALSE; + } + + if (!validDeviceClass(Icc->DeviceClass)) { + cmsSignalError(Icc->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported device class '0x%x'", Icc->DeviceClass); + return FALSE; + } + + // Get size as reported in header + HeaderSize = _cmsAdjustEndianess32(Header.size); + + // Make sure HeaderSize is lower than profile size + if (HeaderSize >= Icc ->IOhandler ->ReportedSize) + HeaderSize = Icc ->IOhandler ->ReportedSize; + + + // Get creation date/time + _cmsDecodeDateTimeNumber(&Header.date, &Icc ->Created); + + // The profile ID are 32 raw bytes + memmove(Icc ->ProfileID.ID32, Header.profileID.ID32, 16); + + + // Read tag directory + if (!_cmsReadUInt32Number(io, &TagCount)) return FALSE; + if (TagCount > MAX_TABLE_TAG) { + + cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", TagCount); + return FALSE; + } + + + // Read tag directory + Icc -> TagCount = 0; + for (i=0; i < TagCount; i++) { + + if (!_cmsReadUInt32Number(io, (cmsUInt32Number *) &Tag.sig)) return FALSE; + if (!_cmsReadUInt32Number(io, &Tag.offset)) return FALSE; + if (!_cmsReadUInt32Number(io, &Tag.size)) return FALSE; + + // Perform some sanity check. Offset + size should fall inside file. + if (Tag.size == 0 || Tag.offset == 0) continue; + if (Tag.offset + Tag.size > HeaderSize || + Tag.offset + Tag.size < Tag.offset) + continue; + + Icc -> TagNames[Icc ->TagCount] = Tag.sig; + Icc -> TagOffsets[Icc ->TagCount] = Tag.offset; + Icc -> TagSizes[Icc ->TagCount] = Tag.size; + + // Search for links + for (j=0; j < Icc ->TagCount; j++) { + + if ((Icc ->TagOffsets[j] == Tag.offset) && + (Icc ->TagSizes[j] == Tag.size)) { + + // Check types. + if (CompatibleTypes(_cmsGetTagDescriptor(Icc->ContextID, Icc->TagNames[j]), + _cmsGetTagDescriptor(Icc->ContextID, Tag.sig))) { + + Icc->TagLinked[Icc->TagCount] = Icc->TagNames[j]; + } + } + + } + + Icc ->TagCount++; + } + + + for (i = 0; i < Icc->TagCount; i++) { + for (j = 0; j < Icc->TagCount; j++) { + + // Tags cannot be duplicate + if ((i != j) && (Icc->TagNames[i] == Icc->TagNames[j])) { + cmsSignalError(Icc->ContextID, cmsERROR_RANGE, "Duplicate tag found"); + return FALSE; + } + + } + } + + return TRUE; +} + +// Saves profile header +cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace) +{ + cmsICCHeader Header; + cmsUInt32Number i; + cmsTagEntry Tag; + cmsUInt32Number Count; + + Header.size = _cmsAdjustEndianess32(UsedSpace); + Header.cmmId = _cmsAdjustEndianess32(lcmsSignature); + Header.version = _cmsAdjustEndianess32(Icc ->Version); + + Header.deviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Icc -> DeviceClass); + Header.colorSpace = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Icc -> ColorSpace); + Header.pcs = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Icc -> PCS); + + // NOTE: in v4 Timestamp must be in UTC rather than in local time + _cmsEncodeDateTimeNumber(&Header.date, &Icc ->Created); + + Header.magic = _cmsAdjustEndianess32(cmsMagicNumber); + +#ifdef CMS_IS_WINDOWS_ + Header.platform = (cmsPlatformSignature) _cmsAdjustEndianess32(cmsSigMicrosoft); +#else + Header.platform = (cmsPlatformSignature) _cmsAdjustEndianess32(cmsSigMacintosh); +#endif + + Header.flags = _cmsAdjustEndianess32(Icc -> flags); + Header.manufacturer = _cmsAdjustEndianess32(Icc -> manufacturer); + Header.model = _cmsAdjustEndianess32(Icc -> model); + + _cmsAdjustEndianess64(&Header.attributes, &Icc -> attributes); + + // Rendering intent in the header (for embedded profiles) + Header.renderingIntent = _cmsAdjustEndianess32(Icc -> RenderingIntent); + + // Illuminant is always D50 + Header.illuminant.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->X)); + Header.illuminant.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y)); + Header.illuminant.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z)); + + // Created by LittleCMS (that's me!) + Header.creator = _cmsAdjustEndianess32(lcmsSignature); + + memset(&Header.reserved, 0, sizeof(Header.reserved)); + + // Set profile ID. Endianness is always big endian + memmove(&Header.profileID, &Icc ->ProfileID, 16); + + // Dump the header + if (!Icc -> IOhandler->Write(Icc->IOhandler, sizeof(cmsICCHeader), &Header)) return FALSE; + + // Saves Tag directory + + // Get true count + Count = 0; + for (i=0; i < Icc -> TagCount; i++) { + if (Icc ->TagNames[i] != (cmsTagSignature) 0) + Count++; + } + + // Store number of tags + if (!_cmsWriteUInt32Number(Icc ->IOhandler, Count)) return FALSE; + + for (i=0; i < Icc -> TagCount; i++) { + + if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // It is just a placeholder + + Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagNames[i]); + Tag.offset = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagOffsets[i]); + Tag.size = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagSizes[i]); + + if (!Icc ->IOhandler -> Write(Icc-> IOhandler, sizeof(cmsTagEntry), &Tag)) return FALSE; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- Set/Get several struct members + + +cmsUInt32Number CMSEXPORT cmsGetHeaderRenderingIntent(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc -> RenderingIntent; +} + +void CMSEXPORT cmsSetHeaderRenderingIntent(cmsHPROFILE hProfile, cmsUInt32Number RenderingIntent) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> RenderingIntent = RenderingIntent; +} + +cmsUInt32Number CMSEXPORT cmsGetHeaderFlags(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return (cmsUInt32Number) Icc -> flags; +} + +void CMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, cmsUInt32Number Flags) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> flags = (cmsUInt32Number) Flags; +} + +cmsUInt32Number CMSEXPORT cmsGetHeaderManufacturer(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc ->manufacturer; +} + +void CMSEXPORT cmsSetHeaderManufacturer(cmsHPROFILE hProfile, cmsUInt32Number manufacturer) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> manufacturer = manufacturer; +} + +cmsUInt32Number CMSEXPORT cmsGetHeaderCreator(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc ->creator; +} + +cmsUInt32Number CMSEXPORT cmsGetHeaderModel(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc ->model; +} + +void CMSEXPORT cmsSetHeaderModel(cmsHPROFILE hProfile, cmsUInt32Number model) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> model = model; +} + +void CMSEXPORT cmsGetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number* Flags) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + memmove(Flags, &Icc -> attributes, sizeof(cmsUInt64Number)); +} + +void CMSEXPORT cmsSetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number Flags) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + memmove(&Icc -> attributes, &Flags, sizeof(cmsUInt64Number)); +} + +void CMSEXPORT cmsGetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + memmove(ProfileID, Icc ->ProfileID.ID8, 16); +} + +void CMSEXPORT cmsSetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + memmove(&Icc -> ProfileID, ProfileID, 16); +} + +cmsBool CMSEXPORT cmsGetHeaderCreationDateTime(cmsHPROFILE hProfile, struct tm *Dest) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + memmove(Dest, &Icc ->Created, sizeof(struct tm)); + return TRUE; +} + +cmsColorSpaceSignature CMSEXPORT cmsGetPCS(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc -> PCS; +} + +void CMSEXPORT cmsSetPCS(cmsHPROFILE hProfile, cmsColorSpaceSignature pcs) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> PCS = pcs; +} + +cmsColorSpaceSignature CMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc -> ColorSpace; +} + +void CMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, cmsColorSpaceSignature sig) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> ColorSpace = sig; +} + +cmsProfileClassSignature CMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc -> DeviceClass; +} + +void CMSEXPORT cmsSetDeviceClass(cmsHPROFILE hProfile, cmsProfileClassSignature sig) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> DeviceClass = sig; +} + +cmsUInt32Number CMSEXPORT cmsGetEncodedICCversion(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc -> Version; +} + +void CMSEXPORT cmsSetEncodedICCversion(cmsHPROFILE hProfile, cmsUInt32Number Version) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + Icc -> Version = Version; +} + +// Get an hexadecimal number with same digits as v +static +cmsUInt32Number BaseToBase(cmsUInt32Number in, int BaseIn, int BaseOut) +{ + char Buff[100]; + int i, len; + cmsUInt32Number out; + + for (len=0; in > 0 && len < 100; len++) { + + Buff[len] = (char) (in % BaseIn); + in /= BaseIn; + } + + for (i=len-1, out=0; i >= 0; --i) { + out = out * BaseOut + Buff[i]; + } + + return out; +} + +void CMSEXPORT cmsSetProfileVersion(cmsHPROFILE hProfile, cmsFloat64Number Version) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + + // 4.2 -> 0x4200000 + + Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0 + 0.5), 10, 16) << 16; +} + +cmsFloat64Number CMSEXPORT cmsGetProfileVersion(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + cmsUInt32Number n = Icc -> Version >> 16; + + return BaseToBase(n, 16, 10) / 100.0; +} +// -------------------------------------------------------------------------------------------------------------- + + +// Create profile from IOhandler +cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandlerTHR(cmsContext ContextID, cmsIOHANDLER* io) +{ + _cmsICCPROFILE* NewIcc; + cmsHPROFILE hEmpty = cmsCreateProfilePlaceholder(ContextID); + + if (hEmpty == NULL) return NULL; + + NewIcc = (_cmsICCPROFILE*) hEmpty; + + NewIcc ->IOhandler = io; + if (!_cmsReadHeader(NewIcc)) goto Error; + return hEmpty; + +Error: + cmsCloseProfile(hEmpty); + return NULL; +} + +// Create profile from IOhandler +cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write) +{ + _cmsICCPROFILE* NewIcc; + cmsHPROFILE hEmpty = cmsCreateProfilePlaceholder(ContextID); + + if (hEmpty == NULL) return NULL; + + NewIcc = (_cmsICCPROFILE*) hEmpty; + + NewIcc ->IOhandler = io; + if (write) { + + NewIcc -> IsWrite = TRUE; + return hEmpty; + } + + if (!_cmsReadHeader(NewIcc)) goto Error; + return hEmpty; + +Error: + cmsCloseProfile(hEmpty); + return NULL; +} + + +// Create profile from disk file +cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *lpFileName, const char *sAccess) +{ + _cmsICCPROFILE* NewIcc; + cmsHPROFILE hEmpty = cmsCreateProfilePlaceholder(ContextID); + + if (hEmpty == NULL) return NULL; + + NewIcc = (_cmsICCPROFILE*) hEmpty; + + NewIcc ->IOhandler = cmsOpenIOhandlerFromFile(ContextID, lpFileName, sAccess); + if (NewIcc ->IOhandler == NULL) goto Error; + + if (*sAccess == 'W' || *sAccess == 'w') { + + NewIcc -> IsWrite = TRUE; + + return hEmpty; + } + + if (!_cmsReadHeader(NewIcc)) goto Error; + return hEmpty; + +Error: + cmsCloseProfile(hEmpty); + return NULL; +} + + +cmsHPROFILE CMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess) +{ + return cmsOpenProfileFromFileTHR(NULL, ICCProfile, sAccess); +} + + +cmsHPROFILE CMSEXPORT cmsOpenProfileFromStreamTHR(cmsContext ContextID, FILE* ICCProfile, const char *sAccess) +{ + _cmsICCPROFILE* NewIcc; + cmsHPROFILE hEmpty = cmsCreateProfilePlaceholder(ContextID); + + if (hEmpty == NULL) return NULL; + + NewIcc = (_cmsICCPROFILE*) hEmpty; + + NewIcc ->IOhandler = cmsOpenIOhandlerFromStream(ContextID, ICCProfile); + if (NewIcc ->IOhandler == NULL) goto Error; + + if (*sAccess == 'w') { + + NewIcc -> IsWrite = TRUE; + return hEmpty; + } + + if (!_cmsReadHeader(NewIcc)) goto Error; + return hEmpty; + +Error: + cmsCloseProfile(hEmpty); + return NULL; + +} + +cmsHPROFILE CMSEXPORT cmsOpenProfileFromStream(FILE* ICCProfile, const char *sAccess) +{ + return cmsOpenProfileFromStreamTHR(NULL, ICCProfile, sAccess); +} + + +// Open from memory block +cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void* MemPtr, cmsUInt32Number dwSize) +{ + _cmsICCPROFILE* NewIcc; + cmsHPROFILE hEmpty; + + hEmpty = cmsCreateProfilePlaceholder(ContextID); + if (hEmpty == NULL) return NULL; + + NewIcc = (_cmsICCPROFILE*) hEmpty; + + // Ok, in this case const void* is casted to void* just because open IO handler + // shares read and writing modes. Don't abuse this feature! + NewIcc ->IOhandler = cmsOpenIOhandlerFromMem(ContextID, (void*) MemPtr, dwSize, "r"); + if (NewIcc ->IOhandler == NULL) goto Error; + + if (!_cmsReadHeader(NewIcc)) goto Error; + + return hEmpty; + +Error: + cmsCloseProfile(hEmpty); + return NULL; +} + +cmsHPROFILE CMSEXPORT cmsOpenProfileFromMem(const void* MemPtr, cmsUInt32Number dwSize) +{ + return cmsOpenProfileFromMemTHR(NULL, MemPtr, dwSize); +} + + + +// Dump tag contents. If the profile is being modified, untouched tags are copied from FileOrig +static +cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig) +{ + cmsUInt8Number* Data; + cmsUInt32Number i; + cmsUInt32Number Begin; + cmsIOHANDLER* io = Icc ->IOhandler; + cmsTagDescriptor* TagDescriptor; + cmsTagTypeSignature TypeBase; + cmsTagTypeSignature Type; + cmsTagTypeHandler* TypeHandler; + cmsFloat64Number Version = cmsGetProfileVersion((cmsHPROFILE) Icc); + cmsTagTypeHandler LocalTypeHandler; + + for (i=0; i < Icc -> TagCount; i++) { + + if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; + + // Linked tags are not written + if (Icc ->TagLinked[i] != (cmsTagSignature) 0) continue; + + Icc -> TagOffsets[i] = Begin = io ->UsedSpace; + + Data = (cmsUInt8Number*) Icc -> TagPtrs[i]; + + if (!Data) { + + // Reach here if we are copying a tag from a disk-based ICC profile which has not been modified by user. + // In this case a blind copy of the block data is performed + if (FileOrig != NULL && Icc -> TagOffsets[i]) { + + if (FileOrig->IOhandler != NULL) + { + cmsUInt32Number TagSize = FileOrig->TagSizes[i]; + cmsUInt32Number TagOffset = FileOrig->TagOffsets[i]; + void* Mem; + + if (!FileOrig->IOhandler->Seek(FileOrig->IOhandler, TagOffset)) return FALSE; + + Mem = _cmsMalloc(Icc->ContextID, TagSize); + if (Mem == NULL) return FALSE; + + if (FileOrig->IOhandler->Read(FileOrig->IOhandler, Mem, TagSize, 1) != 1) return FALSE; + if (!io->Write(io, TagSize, Mem)) return FALSE; + _cmsFree(Icc->ContextID, Mem); + + Icc->TagSizes[i] = (io->UsedSpace - Begin); + + + // Align to 32 bit boundary. + if (!_cmsWriteAlignment(io)) + return FALSE; + } + } + + continue; + } + + + // Should this tag be saved as RAW? If so, tagsizes should be specified in advance (no further cooking is done) + if (Icc ->TagSaveAsRaw[i]) { + + if (io -> Write(io, Icc ->TagSizes[i], Data) != 1) return FALSE; + } + else { + + // Search for support on this tag + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, Icc -> TagNames[i]); + if (TagDescriptor == NULL) continue; // Unsupported, ignore it + + if (TagDescriptor ->DecideType != NULL) { + + Type = TagDescriptor ->DecideType(Version, Data); + } + else { + + Type = TagDescriptor ->SupportedTypes[0]; + } + + TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, Type); + + if (TypeHandler == NULL) { + cmsSignalError(Icc ->ContextID, cmsERROR_INTERNAL, "(Internal) no handler for tag %x", Icc -> TagNames[i]); + continue; + } + + TypeBase = TypeHandler ->Signature; + if (!_cmsWriteTypeBase(io, TypeBase)) + return FALSE; + + LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; + if (!LocalTypeHandler.WritePtr(&LocalTypeHandler, io, Data, TagDescriptor ->ElemCount)) { + + char String[5]; + + _cmsTagSignature2String(String, (cmsTagSignature) TypeBase); + cmsSignalError(Icc ->ContextID, cmsERROR_WRITE, "Couldn't write type '%s'", String); + return FALSE; + } + } + + + Icc -> TagSizes[i] = (io ->UsedSpace - Begin); + + // Align to 32 bit boundary. + if (! _cmsWriteAlignment(io)) + return FALSE; + } + + + return TRUE; +} + + +// Fill the offset and size fields for all linked tags +static +cmsBool SetLinks( _cmsICCPROFILE* Icc) +{ + cmsUInt32Number i; + + for (i=0; i < Icc -> TagCount; i++) { + + cmsTagSignature lnk = Icc ->TagLinked[i]; + if (lnk != (cmsTagSignature) 0) { + + int j = _cmsSearchTag(Icc, lnk, FALSE); + if (j >= 0) { + + Icc ->TagOffsets[i] = Icc ->TagOffsets[j]; + Icc ->TagSizes[i] = Icc ->TagSizes[j]; + } + + } + } + + return TRUE; +} + +// Low-level save to IOHANDLER. It returns the number of bytes used to +// store the profile, or zero on error. io may be NULL and in this case +// no data is written--only sizes are calculated +cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOHANDLER* io) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + _cmsICCPROFILE Keep; + cmsIOHANDLER* PrevIO = NULL; + cmsUInt32Number UsedSpace; + cmsContext ContextID; + + _cmsAssert(hProfile != NULL); + + if (!_cmsLockMutex(Icc->ContextID, Icc->UsrMutex)) return 0; + memmove(&Keep, Icc, sizeof(_cmsICCPROFILE)); + + ContextID = cmsGetProfileContextID(hProfile); + PrevIO = Icc ->IOhandler = cmsOpenIOhandlerFromNULL(ContextID); + if (PrevIO == NULL) { + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); + return 0; + } + + // Pass #1 does compute offsets + + if (!_cmsWriteHeader(Icc, 0)) goto Error; + if (!SaveTags(Icc, &Keep)) goto Error; + + UsedSpace = PrevIO ->UsedSpace; + + // Pass #2 does save to iohandler + + if (io != NULL) { + + Icc ->IOhandler = io; + if (!SetLinks(Icc)) goto Error; + if (!_cmsWriteHeader(Icc, UsedSpace)) goto Error; + if (!SaveTags(Icc, &Keep)) goto Error; + } + + memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); + if (!cmsCloseIOhandler(PrevIO)) + UsedSpace = 0; // As a error marker + + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); + + return UsedSpace; + + +Error: + cmsCloseIOhandler(PrevIO); + memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); + + return 0; +} + + +// Low-level save to disk. +cmsBool CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName) +{ + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsIOHANDLER* io = cmsOpenIOhandlerFromFile(ContextID, FileName, "w"); + cmsBool rc; + + if (io == NULL) return FALSE; + + rc = (cmsSaveProfileToIOhandler(hProfile, io) != 0); + rc &= cmsCloseIOhandler(io); + + if (rc == FALSE) { // remove() is C99 per 7.19.4.1 + remove(FileName); // We have to IGNORE return value in this case + } + return rc; +} + +// Same as anterior, but for streams +cmsBool CMSEXPORT cmsSaveProfileToStream(cmsHPROFILE hProfile, FILE* Stream) +{ + cmsBool rc; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsIOHANDLER* io = cmsOpenIOhandlerFromStream(ContextID, Stream); + + if (io == NULL) return FALSE; + + rc = (cmsSaveProfileToIOhandler(hProfile, io) != 0); + rc &= cmsCloseIOhandler(io); + + return rc; +} + + +// Same as anterior, but for memory blocks. In this case, a NULL as MemPtr means calculate needed space only +cmsBool CMSEXPORT cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, cmsUInt32Number* BytesNeeded) +{ + cmsBool rc; + cmsIOHANDLER* io; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + _cmsAssert(BytesNeeded != NULL); + + // Should we just calculate the needed space? + if (MemPtr == NULL) { + + *BytesNeeded = cmsSaveProfileToIOhandler(hProfile, NULL); + return (*BytesNeeded == 0) ? FALSE : TRUE; + } + + // That is a real write operation + io = cmsOpenIOhandlerFromMem(ContextID, MemPtr, *BytesNeeded, "w"); + if (io == NULL) return FALSE; + + rc = (cmsSaveProfileToIOhandler(hProfile, io) != 0); + rc &= cmsCloseIOhandler(io); + + return rc; +} + +// Free one tag contents +static +void freeOneTag(_cmsICCPROFILE* Icc, cmsUInt32Number i) +{ + if (Icc->TagPtrs[i]) { + + cmsTagTypeHandler* TypeHandler = Icc->TagTypeHandlers[i]; + + if (TypeHandler != NULL) { + cmsTagTypeHandler LocalTypeHandler = *TypeHandler; + + LocalTypeHandler.ContextID = Icc->ContextID; + LocalTypeHandler.ICCVersion = Icc->Version; + LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc->TagPtrs[i]); + } + else + _cmsFree(Icc->ContextID, Icc->TagPtrs[i]); + } +} + +// Closes a profile freeing any involved resources +cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + cmsBool rc = TRUE; + cmsUInt32Number i; + + if (!Icc) return FALSE; + + // Was open in write mode? + if (Icc ->IsWrite) { + + Icc ->IsWrite = FALSE; // Assure no further writing + rc &= cmsSaveProfileToFile(hProfile, Icc ->IOhandler->PhysicalFile); + } + + for (i=0; i < Icc -> TagCount; i++) { + + freeOneTag(Icc, i); + } + + if (Icc ->IOhandler != NULL) { + rc &= cmsCloseIOhandler(Icc->IOhandler); + } + + _cmsDestroyMutex(Icc->ContextID, Icc->UsrMutex); + + _cmsFree(Icc ->ContextID, Icc); // Free placeholder memory + + return rc; +} + + +// ------------------------------------------------------------------------------------------------------------------- + + +// Returns TRUE if a given tag is supported by a plug-in +static +cmsBool IsTypeSupported(cmsTagDescriptor* TagDescriptor, cmsTagTypeSignature Type) +{ + cmsUInt32Number i, nMaxTypes; + + nMaxTypes = TagDescriptor->nSupportedTypes; + if (nMaxTypes >= MAX_TYPES_IN_LCMS_PLUGIN) + nMaxTypes = MAX_TYPES_IN_LCMS_PLUGIN; + + for (i=0; i < nMaxTypes; i++) { + if (Type == TagDescriptor ->SupportedTypes[i]) return TRUE; + } + + return FALSE; +} + + +// That's the main read function +void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + cmsIOHANDLER* io; + cmsTagTypeHandler* TypeHandler; + cmsTagTypeHandler LocalTypeHandler; + cmsTagDescriptor* TagDescriptor; + cmsTagTypeSignature BaseType; + cmsUInt32Number Offset, TagSize; + cmsUInt32Number ElemCount; + int n; + + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return NULL; + + n = _cmsSearchTag(Icc, sig, TRUE); + if (n < 0) + { + // Not found, return NULL + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); + return NULL; + } + + // If the element is already in memory, return the pointer + if (Icc -> TagPtrs[n]) { + + if (Icc->TagTypeHandlers[n] == NULL) goto Error; + + // Sanity check + BaseType = Icc->TagTypeHandlers[n]->Signature; + if (BaseType == 0) goto Error; + + TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig); + if (TagDescriptor == NULL) goto Error; + + if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error; + + if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return Icc -> TagPtrs[n]; + } + + // We need to read it. Get the offset and size to the file + Offset = Icc -> TagOffsets[n]; + TagSize = Icc -> TagSizes[n]; + + if (TagSize < 8) goto Error; + + io = Icc ->IOhandler; + + if (io == NULL) { // This is a built-in profile that has been manipulated, abort early + + cmsSignalError(Icc->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted built-in profile."); + goto Error; + } + + // Seek to its location + if (!io -> Seek(io, Offset)) + goto Error; + + // Search for support on this tag + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig); + if (TagDescriptor == NULL) { + + char String[5]; + + _cmsTagSignature2String(String, sig); + + // An unknown element was found. + cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String); + goto Error; // Unsupported. + } + + // if supported, get type and check if in list + BaseType = _cmsReadTypeBase(io); + if (BaseType == 0) goto Error; + + if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error; + + TagSize -= 8; // Already read by the type base logic + + // Get type handler + TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType); + if (TypeHandler == NULL) goto Error; + LocalTypeHandler = *TypeHandler; + + + // Read the tag + Icc -> TagTypeHandlers[n] = TypeHandler; + + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; + Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize); + + // The tag type is supported, but something wrong happened and we cannot read the tag. + // let know the user about this (although it is just a warning) + if (Icc -> TagPtrs[n] == NULL) { + + char String[5]; + + _cmsTagSignature2String(String, sig); + cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String); + goto Error; + } + + // This is a weird error that may be a symptom of something more serious, the number of + // stored item is actually less than the number of required elements. + if (ElemCount < TagDescriptor ->ElemCount) { + + char String[5]; + + _cmsTagSignature2String(String, sig); + cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d", + String, TagDescriptor ->ElemCount, ElemCount); + goto Error; + } + + + // Return the data + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return Icc -> TagPtrs[n]; + + + // Return error and unlock the data +Error: + + freeOneTag(Icc, n); + Icc->TagPtrs[n] = NULL; + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return NULL; +} + + +// Get true type of data +cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + cmsTagTypeHandler* TypeHandler; + int n; + + // Search for given tag in ICC profile directory + n = _cmsSearchTag(Icc, sig, TRUE); + if (n < 0) return (cmsTagTypeSignature) 0; // Not found, return NULL + + // Get the handler. The true type is there + TypeHandler = Icc -> TagTypeHandlers[n]; + return TypeHandler ->Signature; +} + + +// Write a single tag. This just keeps track of the tak into a list of "to be written". If the tag is already +// in that list, the previous version is deleted. +cmsBool CMSEXPORT cmsWriteTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + cmsTagTypeHandler* TypeHandler = NULL; + cmsTagTypeHandler LocalTypeHandler; + cmsTagDescriptor* TagDescriptor = NULL; + cmsTagTypeSignature Type; + int i; + cmsFloat64Number Version; + char TypeString[5], SigString[5]; + + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE; + + // To delete tags. + if (data == NULL) { + + // Delete the tag + i = _cmsSearchTag(Icc, sig, FALSE); + if (i >= 0) { + + // Use zero as a mark of deleted + _cmsDeleteTagByPos(Icc, i); + Icc ->TagNames[i] = (cmsTagSignature) 0; + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return TRUE; + } + // Didn't find the tag + goto Error; + } + + if (!_cmsNewTag(Icc, sig, &i)) goto Error; + + // This is not raw + Icc ->TagSaveAsRaw[i] = FALSE; + + // This is not a link + Icc ->TagLinked[i] = (cmsTagSignature) 0; + + // Get information about the TAG. + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig); + if (TagDescriptor == NULL){ + cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported tag '%x'", sig); + goto Error; + } + + + // Now we need to know which type to use. It depends on the version. + Version = cmsGetProfileVersion(hProfile); + + if (TagDescriptor ->DecideType != NULL) { + + // Let the tag descriptor to decide the type base on depending on + // the data. This is useful for example on parametric curves, where + // curves specified by a table cannot be saved as parametric and needs + // to be casted to single v2-curves, even on v4 profiles. + + Type = TagDescriptor ->DecideType(Version, data); + } + else { + + Type = TagDescriptor ->SupportedTypes[0]; + } + + // Does the tag support this type? + if (!IsTypeSupported(TagDescriptor, Type)) { + + _cmsTagSignature2String(TypeString, (cmsTagSignature) Type); + _cmsTagSignature2String(SigString, sig); + + cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString); + goto Error; + } + + // Does we have a handler for this type? + TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, Type); + if (TypeHandler == NULL) { + + _cmsTagSignature2String(TypeString, (cmsTagSignature) Type); + _cmsTagSignature2String(SigString, sig); + + cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString); + goto Error; // Should never happen + } + + + // Fill fields on icc structure + Icc ->TagTypeHandlers[i] = TypeHandler; + Icc ->TagNames[i] = sig; + Icc ->TagSizes[i] = 0; + Icc ->TagOffsets[i] = 0; + + LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; + Icc ->TagPtrs[i] = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount); + + if (Icc ->TagPtrs[i] == NULL) { + + _cmsTagSignature2String(TypeString, (cmsTagSignature) Type); + _cmsTagSignature2String(SigString, sig); + cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Malformed struct in type '%s' for tag '%s'", TypeString, SigString); + + goto Error; + } + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return TRUE; + +Error: + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return FALSE; + +} + +// Read and write raw data. Read/Write Raw/cooked pairs try to maintain consistency within the pair. Some sequences +// raw/cooked would work, but at a cost. Data "cooked" may be converted to "raw" by using the "write" serialization logic. +// In general it is better to avoid mixing pairs. + +cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* data, cmsUInt32Number BufferSize) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + void *Object; + int i; + cmsIOHANDLER* MemIO; + cmsTagTypeHandler* TypeHandler = NULL; + cmsTagTypeHandler LocalTypeHandler; + cmsTagDescriptor* TagDescriptor = NULL; + cmsUInt32Number rc; + cmsUInt32Number Offset, TagSize; + + // Sanity check + if (data != NULL && BufferSize == 0) return 0; + + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0; + + // Search for given tag in ICC profile directory + + i = _cmsSearchTag(Icc, sig, TRUE); + if (i < 0) goto Error; // Not found, + + // It is already read? + if (Icc -> TagPtrs[i] == NULL) { + + // Not yet, get original position + Offset = Icc ->TagOffsets[i]; + TagSize = Icc ->TagSizes[i]; + + // read the data directly, don't keep copy + + if (data != NULL) { + + if (BufferSize < TagSize) + TagSize = BufferSize; + + if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error; + if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error; + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return TagSize; + } + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return Icc ->TagSizes[i]; + } + + // The data has been already read, or written. But wait!, maybe the user choose to save as + // raw data. In this case, return the raw data directly + + if (Icc ->TagSaveAsRaw[i]) { + + if (data != NULL) { + + TagSize = Icc ->TagSizes[i]; + if (BufferSize < TagSize) + TagSize = BufferSize; + + memmove(data, Icc ->TagPtrs[i], TagSize); + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return TagSize; + } + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return Icc ->TagSizes[i]; + } + + // Already read, or previously set by cmsWriteTag(). We need to serialize that + // data to raw to get something that makes sense + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + Object = cmsReadTag(hProfile, sig); + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0; + + if (Object == NULL) goto Error; + + // Now we need to serialize to a memory block: just use a memory iohandler + + if (data == NULL) { + MemIO = cmsOpenIOhandlerFromNULL(cmsGetProfileContextID(hProfile)); + } else{ + MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w"); + } + if (MemIO == NULL) goto Error; + + // Obtain type handling for the tag + TypeHandler = Icc ->TagTypeHandlers[i]; + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig); + if (TagDescriptor == NULL) { + cmsCloseIOhandler(MemIO); + goto Error; + } + + if (TypeHandler == NULL) goto Error; + + // Serialize + LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; + + if (!_cmsWriteTypeBase(MemIO, TypeHandler ->Signature)) { + cmsCloseIOhandler(MemIO); + goto Error; + } + + if (!LocalTypeHandler.WritePtr(&LocalTypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) { + cmsCloseIOhandler(MemIO); + goto Error; + } + + // Get Size and close + rc = MemIO ->Tell(MemIO); + cmsCloseIOhandler(MemIO); // Ignore return code this time + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return rc; + +Error: + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return 0; +} + +// Similar to the anterior. This function allows to write directly to the ICC profile any data, without +// checking anything. As a rule, mixing Raw with cooked doesn't work, so writing a tag as raw and then reading +// it as cooked without serializing does result into an error. If that is what you want, you will need to dump +// the profile to memry or disk and then reopen it. +cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + int i; + + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0; + + if (!_cmsNewTag(Icc, sig, &i)) { + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return FALSE; + } + + // Mark the tag as being written as RAW + Icc ->TagSaveAsRaw[i] = TRUE; + Icc ->TagNames[i] = sig; + Icc ->TagLinked[i] = (cmsTagSignature) 0; + + // Keep a copy of the block + Icc ->TagPtrs[i] = _cmsDupMem(Icc ->ContextID, data, Size); + Icc ->TagSizes[i] = Size; + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + + if (Icc->TagPtrs[i] == NULL) { + Icc->TagNames[i] = (cmsTagSignature) 0; + return FALSE; + } + return TRUE; +} + +// Using this function you can collapse several tag entries to the same block in the profile +cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignature sig, cmsTagSignature dest) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + int i; + + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE; + + if (!_cmsNewTag(Icc, sig, &i)) { + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return FALSE; + } + + // Keep necessary information + Icc ->TagSaveAsRaw[i] = FALSE; + Icc ->TagNames[i] = sig; + Icc ->TagLinked[i] = dest; + + Icc ->TagPtrs[i] = NULL; + Icc ->TagSizes[i] = 0; + Icc ->TagOffsets[i] = 0; + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return TRUE; +} + + +// Returns the tag linked to sig, in the case two tags are sharing same resource +cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + int i; + + // Search for given tag in ICC profile directory + i = _cmsSearchTag(Icc, sig, FALSE); + if (i < 0) return (cmsTagSignature) 0; // Not found, return 0 + + return Icc -> TagLinked[i]; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsio1.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsio1.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsio1.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsio1.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1058 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// Read tags using low-level functions, provides necessary glue code to adapt versions, etc. + +// LUT tags +static const cmsTagSignature Device2PCS16[] = {cmsSigAToB0Tag, // Perceptual + cmsSigAToB1Tag, // Relative colorimetric + cmsSigAToB2Tag, // Saturation + cmsSigAToB1Tag }; // Absolute colorimetric + +static const cmsTagSignature Device2PCSFloat[] = {cmsSigDToB0Tag, // Perceptual + cmsSigDToB1Tag, // Relative colorimetric + cmsSigDToB2Tag, // Saturation + cmsSigDToB3Tag }; // Absolute colorimetric + +static const cmsTagSignature PCS2Device16[] = {cmsSigBToA0Tag, // Perceptual + cmsSigBToA1Tag, // Relative colorimetric + cmsSigBToA2Tag, // Saturation + cmsSigBToA1Tag }; // Absolute colorimetric + +static const cmsTagSignature PCS2DeviceFloat[] = {cmsSigBToD0Tag, // Perceptual + cmsSigBToD1Tag, // Relative colorimetric + cmsSigBToD2Tag, // Saturation + cmsSigBToD3Tag }; // Absolute colorimetric + + +// Factors to convert from 1.15 fixed point to 0..1.0 range and vice-versa +#define InpAdj (1.0/MAX_ENCODEABLE_XYZ) // (65536.0/(65535.0*2.0)) +#define OutpAdj (MAX_ENCODEABLE_XYZ) // ((2.0*65535.0)/65536.0) + +// Several resources for gray conversions. +static const cmsFloat64Number GrayInputMatrix[] = { (InpAdj*cmsD50X), (InpAdj*cmsD50Y), (InpAdj*cmsD50Z) }; +static const cmsFloat64Number OneToThreeInputMatrix[] = { 1, 1, 1 }; +static const cmsFloat64Number PickYMatrix[] = { 0, (OutpAdj*cmsD50Y), 0 }; +static const cmsFloat64Number PickLstarMatrix[] = { 1, 0, 0 }; + +// Get a media white point fixing some issues found in certain old profiles +cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile) +{ + cmsCIEXYZ* Tag; + + _cmsAssert(Dest != NULL); + + Tag = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag); + + // If no wp, take D50 + if (Tag == NULL) { + *Dest = *cmsD50_XYZ(); + return TRUE; + } + + // V2 display profiles should give D50 + if (cmsGetEncodedICCversion(hProfile) < 0x4000000) { + + if (cmsGetDeviceClass(hProfile) == cmsSigDisplayClass) { + *Dest = *cmsD50_XYZ(); + return TRUE; + } + } + + // All seems ok + *Dest = *Tag; + return TRUE; +} + + +// Chromatic adaptation matrix. Fix some issues as well +cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile) +{ + cmsMAT3* Tag; + + _cmsAssert(Dest != NULL); + + Tag = (cmsMAT3*) cmsReadTag(hProfile, cmsSigChromaticAdaptationTag); + + if (Tag != NULL) { + *Dest = *Tag; + return TRUE; + } + + // No CHAD available, default it to identity + _cmsMAT3identity(Dest); + + // V2 display profiles should give D50 + if (cmsGetEncodedICCversion(hProfile) < 0x4000000) { + + if (cmsGetDeviceClass(hProfile) == cmsSigDisplayClass) { + + cmsCIEXYZ* White = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag); + + if (White == NULL) { + + _cmsMAT3identity(Dest); + return TRUE; + } + + return _cmsAdaptationMatrix(Dest, NULL, White, cmsD50_XYZ()); + } + } + + return TRUE; +} + + +// Auxiliary, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper +static +cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile) +{ + cmsCIEXYZ *PtrRed, *PtrGreen, *PtrBlue; + + _cmsAssert(r != NULL); + + PtrRed = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigRedColorantTag); + PtrGreen = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigGreenColorantTag); + PtrBlue = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigBlueColorantTag); + + if (PtrRed == NULL || PtrGreen == NULL || PtrBlue == NULL) + return FALSE; + + _cmsVEC3init(&r -> v[0], PtrRed -> X, PtrGreen -> X, PtrBlue -> X); + _cmsVEC3init(&r -> v[1], PtrRed -> Y, PtrGreen -> Y, PtrBlue -> Y); + _cmsVEC3init(&r -> v[2], PtrRed -> Z, PtrGreen -> Z, PtrBlue -> Z); + + return TRUE; +} + + +// Gray input pipeline +static +cmsPipeline* BuildGrayInputMatrixPipeline(cmsHPROFILE hProfile) +{ + cmsToneCurve *GrayTRC; + cmsPipeline* Lut; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + GrayTRC = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGrayTRCTag); + if (GrayTRC == NULL) return NULL; + + Lut = cmsPipelineAlloc(ContextID, 1, 3); + if (Lut == NULL) + goto Error; + + if (cmsGetPCS(hProfile) == cmsSigLabData) { + + // In this case we implement the profile as an identity matrix plus 3 tone curves + cmsUInt16Number Zero[2] = { 0x8080, 0x8080 }; + cmsToneCurve* EmptyTab; + cmsToneCurve* LabCurves[3]; + + EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero); + + if (EmptyTab == NULL) + goto Error; + + LabCurves[0] = GrayTRC; + LabCurves[1] = EmptyTab; + LabCurves[2] = EmptyTab; + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, OneToThreeInputMatrix, NULL)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, LabCurves))) { + cmsFreeToneCurve(EmptyTab); + goto Error; + } + + cmsFreeToneCurve(EmptyTab); + + } + else { + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &GrayTRC)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, GrayInputMatrix, NULL))) + goto Error; + } + + return Lut; + +Error: + cmsPipelineFree(Lut); + return NULL; +} + +// RGB Matrix shaper +static +cmsPipeline* BuildRGBInputMatrixShaper(cmsHPROFILE hProfile) +{ + cmsPipeline* Lut; + cmsMAT3 Mat; + cmsToneCurve *Shapes[3]; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + int i, j; + + if (!ReadICCMatrixRGB2XYZ(&Mat, hProfile)) return NULL; + + // XYZ PCS in encoded in 1.15 format, and the matrix output comes in 0..0xffff range, so + // we need to adjust the output by a factor of (0x10000/0xffff) to put data in + // a 1.16 range, and then a >> 1 to obtain 1.15. The total factor is (65536.0)/(65535.0*2) + + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + Mat.v[i].n[j] *= InpAdj; + + + Shapes[0] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigRedTRCTag); + Shapes[1] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGreenTRCTag); + Shapes[2] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigBlueTRCTag); + + if (!Shapes[0] || !Shapes[1] || !Shapes[2]) + return NULL; + + Lut = cmsPipelineAlloc(ContextID, 3, 3); + if (Lut != NULL) { + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, Shapes)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Mat, NULL))) + goto Error; + + // Note that it is certainly possible a single profile would have a LUT based + // tag for output working in lab and a matrix-shaper for the fallback cases. + // This is not allowed by the spec, but this code is tolerant to those cases + if (cmsGetPCS(hProfile) == cmsSigLabData) { + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocXYZ2Lab(ContextID))) + goto Error; + } + + } + + return Lut; + +Error: + cmsPipelineFree(Lut); + return NULL; +} + + + +// Read the DToAX tag, adjusting the encoding of Lab or XYZ if needed +static +cmsPipeline* _cmsReadFloatInputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) +{ + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat)); + cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile); + cmsColorSpaceSignature PCS = cmsGetPCS(hProfile); + + if (Lut == NULL) return NULL; + + // input and output of transform are in lcms 0..1 encoding. If XYZ or Lab spaces are used, + // these need to be normalized into the appropriate ranges (Lab = 100,0,0, XYZ=1.0,1.0,1.0) + if ( spc == cmsSigLabData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID))) + goto Error; + } + else if (spc == cmsSigXYZData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID))) + goto Error; + } + + if ( PCS == cmsSigLabData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + goto Error; + } + else if( PCS == cmsSigXYZData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) + goto Error; + } + + return Lut; + +Error: + cmsPipelineFree(Lut); + return NULL; +} + + +// Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc +// is adjusted here in order to create a LUT that takes care of all those details. +// We add intent = 0xffffffff as a way to read matrix shaper always, no matter of other LUT +cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent) +{ + cmsTagTypeSignature OriginalType; + cmsTagSignature tag16; + cmsTagSignature tagFloat; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + // On named color, take the appropriate tag + if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) { + + cmsPipeline* Lut; + cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag); + + if (nc == NULL) return NULL; + + Lut = cmsPipelineAlloc(ContextID, 0, 0); + if (Lut == NULL) + return NULL; + + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) { + cmsPipelineFree(Lut); + return NULL; + } + return Lut; + } + + // This is an attempt to reuse this function to retrieve the matrix-shaper as pipeline no + // matter other LUT are present and have precedence. Intent = 0xffffffff can be used for that. + if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { + + tag16 = Device2PCS16[Intent]; + tagFloat = Device2PCSFloat[Intent]; + + if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence + + // Floating point LUT are always V4, but the encoding range is no + // longer 0..1.0, so we need to add an stage depending on the color space + return _cmsReadFloatInputTag(hProfile, tagFloat); + } + + // Revert to perceptual if no tag is found + if (!cmsIsTag(hProfile, tag16)) { + tag16 = Device2PCS16[0]; + } + + if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? + + // Check profile version and LUT type. Do the necessary adjustments if needed + + // First read the tag + cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16); + if (Lut == NULL) return NULL; + + // After reading it, we have now info about the original type + OriginalType = _cmsGetTagTrueType(hProfile, tag16); + + // The profile owns the Lut, so we need to copy it + Lut = cmsPipelineDup(Lut); + + // We need to adjust data only for Lab16 on output + if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData) + return Lut; + + // If the input is Lab, add also a conversion at the begin + if (cmsGetColorSpace(hProfile) == cmsSigLabData && + !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error; + + // Add a matrix for conversion V2 to V4 Lab PCS + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; + + return Lut; +Error: + cmsPipelineFree(Lut); + return NULL; + } + } + + // Lut was not found, try to create a matrix-shaper + + // Check if this is a grayscale profile. + if (cmsGetColorSpace(hProfile) == cmsSigGrayData) { + + // if so, build appropriate conversion tables. + // The tables are the PCS iluminant, scaled across GrayTRC + return BuildGrayInputMatrixPipeline(hProfile); + } + + // Not gray, create a normal matrix-shaper + return BuildRGBInputMatrixShaper(hProfile); +} + +// --------------------------------------------------------------------------------------------------------------- + +// Gray output pipeline. +// XYZ -> Gray or Lab -> Gray. Since we only know the GrayTRC, we need to do some assumptions. Gray component will be +// given by Y on XYZ PCS and by L* on Lab PCS, Both across inverse TRC curve. +// The complete pipeline on XYZ is Matrix[3:1] -> Tone curve and in Lab Matrix[3:1] -> Tone Curve as well. + +static +cmsPipeline* BuildGrayOutputPipeline(cmsHPROFILE hProfile) +{ + cmsToneCurve *GrayTRC, *RevGrayTRC; + cmsPipeline* Lut; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + GrayTRC = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGrayTRCTag); + if (GrayTRC == NULL) return NULL; + + RevGrayTRC = cmsReverseToneCurve(GrayTRC); + if (RevGrayTRC == NULL) return NULL; + + Lut = cmsPipelineAlloc(ContextID, 3, 1); + if (Lut == NULL) { + cmsFreeToneCurve(RevGrayTRC); + return NULL; + } + + if (cmsGetPCS(hProfile) == cmsSigLabData) { + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL))) + goto Error; + } + else { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickYMatrix, NULL))) + goto Error; + } + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &RevGrayTRC))) + goto Error; + + cmsFreeToneCurve(RevGrayTRC); + return Lut; + +Error: + cmsFreeToneCurve(RevGrayTRC); + cmsPipelineFree(Lut); + return NULL; +} + + +static +cmsPipeline* BuildRGBOutputMatrixShaper(cmsHPROFILE hProfile) +{ + cmsPipeline* Lut; + cmsToneCurve *Shapes[3], *InvShapes[3]; + cmsMAT3 Mat, Inv; + int i, j; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + if (!ReadICCMatrixRGB2XYZ(&Mat, hProfile)) + return NULL; + + if (!_cmsMAT3inverse(&Mat, &Inv)) + return NULL; + + // XYZ PCS in encoded in 1.15 format, and the matrix input should come in 0..0xffff range, so + // we need to adjust the input by a << 1 to obtain a 1.16 fixed and then by a factor of + // (0xffff/0x10000) to put data in 0..0xffff range. Total factor is (2.0*65535.0)/65536.0; + + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + Inv.v[i].n[j] *= OutpAdj; + + Shapes[0] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigRedTRCTag); + Shapes[1] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGreenTRCTag); + Shapes[2] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigBlueTRCTag); + + if (!Shapes[0] || !Shapes[1] || !Shapes[2]) + return NULL; + + InvShapes[0] = cmsReverseToneCurve(Shapes[0]); + InvShapes[1] = cmsReverseToneCurve(Shapes[1]); + InvShapes[2] = cmsReverseToneCurve(Shapes[2]); + + if (!InvShapes[0] || !InvShapes[1] || !InvShapes[2]) { + return NULL; + } + + Lut = cmsPipelineAlloc(ContextID, 3, 3); + if (Lut != NULL) { + + // Note that it is certainly possible a single profile would have a LUT based + // tag for output working in lab and a matrix-shaper for the fallback cases. + // This is not allowed by the spec, but this code is tolerant to those cases + if (cmsGetPCS(hProfile) == cmsSigLabData) { + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLab2XYZ(ContextID))) + goto Error; + } + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Inv, NULL)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, InvShapes))) + goto Error; + } + + cmsFreeToneCurveTriple(InvShapes); + return Lut; +Error: + cmsFreeToneCurveTriple(InvShapes); + cmsPipelineFree(Lut); + return NULL; +} + + +// Change CLUT interpolation to trilinear +static +void ChangeInterpolationToTrilinear(cmsPipeline* Lut) +{ + cmsStage* Stage; + + for (Stage = cmsPipelineGetPtrToFirstStage(Lut); + Stage != NULL; + Stage = cmsStageNext(Stage)) { + + if (cmsStageType(Stage) == cmsSigCLutElemType) { + + _cmsStageCLutData* CLUT = (_cmsStageCLutData*) Stage ->Data; + + CLUT ->Params->dwFlags |= CMS_LERP_FLAGS_TRILINEAR; + _cmsSetInterpolationRoutine(Lut->ContextID, CLUT ->Params); + } + } +} + + +// Read the DToAX tag, adjusting the encoding of Lab or XYZ if needed +static +cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) +{ + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat)); + cmsColorSpaceSignature PCS = cmsGetPCS(hProfile); + cmsColorSpaceSignature dataSpace = cmsGetColorSpace(hProfile); + + if (Lut == NULL) return NULL; + + // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding, + // and since the formatter has already accommodated to 0..1.0, we should undo this change + if ( PCS == cmsSigLabData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID))) + goto Error; + } + else + if (PCS == cmsSigXYZData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID))) + goto Error; + } + + // the output can be Lab or XYZ, in which case normalisation is needed on the end of the pipeline + if ( dataSpace == cmsSigLabData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + goto Error; + } + else if (dataSpace == cmsSigXYZData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) + goto Error; + } + + return Lut; + +Error: + cmsPipelineFree(Lut); + return NULL; +} + +// Create an output MPE LUT from agiven profile. Version mismatches are handled here +cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent) +{ + cmsTagTypeSignature OriginalType; + cmsTagSignature tag16; + cmsTagSignature tagFloat; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + + if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { + + tag16 = PCS2Device16[Intent]; + tagFloat = PCS2DeviceFloat[Intent]; + + if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence + + // Floating point LUT are always V4 + return _cmsReadFloatOutputTag(hProfile, tagFloat); + } + + // Revert to perceptual if no tag is found + if (!cmsIsTag(hProfile, tag16)) { + tag16 = PCS2Device16[0]; + } + + if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? + + // Check profile version and LUT type. Do the necessary adjustments if needed + + // First read the tag + cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16); + if (Lut == NULL) return NULL; + + // After reading it, we have info about the original type + OriginalType = _cmsGetTagTrueType(hProfile, tag16); + + // The profile owns the Lut, so we need to copy it + Lut = cmsPipelineDup(Lut); + if (Lut == NULL) return NULL; + + // Now it is time for a controversial stuff. I found that for 3D LUTS using + // Lab used as indexer space, trilinear interpolation should be used + if (cmsGetPCS(hProfile) == cmsSigLabData) + ChangeInterpolationToTrilinear(Lut); + + // We need to adjust data only for Lab and Lut16 type + if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData) + return Lut; + + // Add a matrix for conversion V4 to V2 Lab PCS + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error; + + // If the output is Lab, add also a conversion at the end + if (cmsGetColorSpace(hProfile) == cmsSigLabData) + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; + + return Lut; +Error: + cmsPipelineFree(Lut); + return NULL; + } + } + + // Lut not found, try to create a matrix-shaper + + // Check if this is a grayscale profile. + if (cmsGetColorSpace(hProfile) == cmsSigGrayData) { + + // if so, build appropriate conversion tables. + // The tables are the PCS iluminant, scaled across GrayTRC + return BuildGrayOutputPipeline(hProfile); + } + + // Not gray, create a normal matrix-shaper, which only operates in XYZ space + return BuildRGBOutputMatrixShaper(hProfile); +} + +// --------------------------------------------------------------------------------------------------------------- + +// Read the AToD0 tag, adjusting the encoding of Lab or XYZ if needed +static +cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) +{ + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat)); + cmsColorSpaceSignature PCS = cmsGetPCS(hProfile); + cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile); + + if (Lut == NULL) return NULL; + + if (spc == cmsSigLabData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID))) + goto Error; + } + else + if (spc == cmsSigXYZData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID))) + goto Error; + } + + if (PCS == cmsSigLabData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + goto Error; + } + else + if (PCS == cmsSigXYZData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) + goto Error; + } + + return Lut; +Error: + cmsPipelineFree(Lut); + return NULL; +} + +// This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The +// tag name here may default to AToB0 +cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent) +{ + cmsPipeline* Lut; + cmsTagTypeSignature OriginalType; + cmsTagSignature tag16; + cmsTagSignature tagFloat; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + + if (Intent > INTENT_ABSOLUTE_COLORIMETRIC) + return NULL; + + tag16 = Device2PCS16[Intent]; + tagFloat = Device2PCSFloat[Intent]; + + // On named color, take the appropriate tag + if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) { + + cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*)cmsReadTag(hProfile, cmsSigNamedColor2Tag); + + if (nc == NULL) return NULL; + + Lut = cmsPipelineAlloc(ContextID, 0, 0); + if (Lut == NULL) + goto Error; + + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, FALSE))) + goto Error; + + if (cmsGetColorSpace(hProfile) == cmsSigLabData) + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; + + return Lut; + Error: + cmsPipelineFree(Lut); + return NULL; + } + + + if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence + + // Floating point LUT are always V + return _cmsReadFloatDevicelinkTag(hProfile, tagFloat); + } + + tagFloat = Device2PCSFloat[0]; + if (cmsIsTag(hProfile, tagFloat)) { + + return cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat)); + } + + if (!cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? + + tag16 = Device2PCS16[0]; + if (!cmsIsTag(hProfile, tag16)) return NULL; + } + + // Check profile version and LUT type. Do the necessary adjustments if needed + + // Read the tag + Lut = (cmsPipeline*)cmsReadTag(hProfile, tag16); + if (Lut == NULL) return NULL; + + // The profile owns the Lut, so we need to copy it + Lut = cmsPipelineDup(Lut); + if (Lut == NULL) return NULL; + + // Now it is time for a controversial stuff. I found that for 3D LUTS using + // Lab used as indexer space, trilinear interpolation should be used + if (cmsGetPCS(hProfile) == cmsSigLabData) + ChangeInterpolationToTrilinear(Lut); + + // After reading it, we have info about the original type + OriginalType = _cmsGetTagTrueType(hProfile, tag16); + + // We need to adjust data for Lab16 on output + if (OriginalType != cmsSigLut16Type) return Lut; + + // Here it is possible to get Lab on both sides + + if (cmsGetColorSpace(hProfile) == cmsSigLabData) { + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error2; + } + + if (cmsGetPCS(hProfile) == cmsSigLabData) { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error2; + } + + return Lut; + +Error2: + cmsPipelineFree(Lut); + return NULL; +} + +// --------------------------------------------------------------------------------------------------------------- + +// Returns TRUE if the profile is implemented as matrix-shaper +cmsBool CMSEXPORT cmsIsMatrixShaper(cmsHPROFILE hProfile) +{ + switch (cmsGetColorSpace(hProfile)) { + + case cmsSigGrayData: + + return cmsIsTag(hProfile, cmsSigGrayTRCTag); + + case cmsSigRgbData: + + return (cmsIsTag(hProfile, cmsSigRedColorantTag) && + cmsIsTag(hProfile, cmsSigGreenColorantTag) && + cmsIsTag(hProfile, cmsSigBlueColorantTag) && + cmsIsTag(hProfile, cmsSigRedTRCTag) && + cmsIsTag(hProfile, cmsSigGreenTRCTag) && + cmsIsTag(hProfile, cmsSigBlueTRCTag)); + + default: + + return FALSE; + } +} + +// Returns TRUE if the intent is implemented as CLUT +cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection) +{ + const cmsTagSignature* TagTable; + + // For devicelinks, the supported intent is that one stated in the header + if (cmsGetDeviceClass(hProfile) == cmsSigLinkClass) { + return (cmsGetHeaderRenderingIntent(hProfile) == Intent); + } + + switch (UsedDirection) { + + case LCMS_USED_AS_INPUT: TagTable = Device2PCS16; break; + case LCMS_USED_AS_OUTPUT:TagTable = PCS2Device16; break; + + // For proofing, we need rel. colorimetric in output. Let's do some recursion + case LCMS_USED_AS_PROOF: + return cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_INPUT) && + cmsIsIntentSupported(hProfile, INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_OUTPUT); + + default: + cmsSignalError(cmsGetProfileContextID(hProfile), cmsERROR_RANGE, "Unexpected direction (%d)", UsedDirection); + return FALSE; + } + + // Extended intents are not strictly CLUT-based + if (Intent > INTENT_ABSOLUTE_COLORIMETRIC) + return FALSE; + + return cmsIsTag(hProfile, TagTable[Intent]); + +} + + +// Return info about supported intents +cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, + cmsUInt32Number Intent, cmsUInt32Number UsedDirection) +{ + + if (cmsIsCLUT(hProfile, Intent, UsedDirection)) return TRUE; + + // Is there any matrix-shaper? If so, the intent is supported. This is a bit odd, since V2 matrix shaper + // does not fully support relative colorimetric because they cannot deal with non-zero black points, but + // many profiles claims that, and this is certainly not true for V4 profiles. Lets answer "yes" no matter + // the accuracy would be less than optimal in rel.col and v2 case. + + return cmsIsMatrixShaper(hProfile); +} + + +// --------------------------------------------------------------------------------------------------------------- + +// Read both, profile sequence description and profile sequence id if present. Then combine both to +// create qa unique structure holding both. Shame on ICC to store things in such complicated way. +cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile) +{ + cmsSEQ* ProfileSeq; + cmsSEQ* ProfileId; + cmsSEQ* NewSeq; + cmsUInt32Number i; + + // Take profile sequence description first + ProfileSeq = (cmsSEQ*) cmsReadTag(hProfile, cmsSigProfileSequenceDescTag); + + // Take profile sequence ID + ProfileId = (cmsSEQ*) cmsReadTag(hProfile, cmsSigProfileSequenceIdTag); + + if (ProfileSeq == NULL && ProfileId == NULL) return NULL; + + if (ProfileSeq == NULL) return cmsDupProfileSequenceDescription(ProfileId); + if (ProfileId == NULL) return cmsDupProfileSequenceDescription(ProfileSeq); + + // We have to mix both together. For that they must agree + if (ProfileSeq ->n != ProfileId ->n) return cmsDupProfileSequenceDescription(ProfileSeq); + + NewSeq = cmsDupProfileSequenceDescription(ProfileSeq); + + // Ok, proceed to the mixing + if (NewSeq != NULL) { + for (i=0; i < ProfileSeq ->n; i++) { + + memmove(&NewSeq ->seq[i].ProfileID, &ProfileId ->seq[i].ProfileID, sizeof(cmsProfileID)); + NewSeq ->seq[i].Description = cmsMLUdup(ProfileId ->seq[i].Description); + } + } + return NewSeq; +} + +// Dump the contents of profile sequence in both tags (if v4 available) +cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq) +{ + if (!cmsWriteTag(hProfile, cmsSigProfileSequenceDescTag, seq)) return FALSE; + + if (cmsGetEncodedICCversion(hProfile) >= 0x4000000) { + + if (!cmsWriteTag(hProfile, cmsSigProfileSequenceIdTag, seq)) return FALSE; + } + + return TRUE; +} + + +// Auxiliary, read and duplicate a MLU if found. +static +cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig) +{ + cmsMLU* mlu = (cmsMLU*) cmsReadTag(h, sig); + if (mlu == NULL) return NULL; + + return cmsMLUdup(mlu); +} + +// Create a sequence description out of an array of profiles +cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]) +{ + cmsUInt32Number i; + cmsSEQ* seq = cmsAllocProfileSequenceDescription(ContextID, nProfiles); + + if (seq == NULL) return NULL; + + for (i=0; i < nProfiles; i++) { + + cmsPSEQDESC* ps = &seq ->seq[i]; + cmsHPROFILE h = hProfiles[i]; + cmsTechnologySignature* techpt; + + cmsGetHeaderAttributes(h, &ps ->attributes); + cmsGetHeaderProfileID(h, ps ->ProfileID.ID8); + ps ->deviceMfg = cmsGetHeaderManufacturer(h); + ps ->deviceModel = cmsGetHeaderModel(h); + + techpt = (cmsTechnologySignature*) cmsReadTag(h, cmsSigTechnologyTag); + if (techpt == NULL) + ps ->technology = (cmsTechnologySignature) 0; + else + ps ->technology = *techpt; + + ps ->Manufacturer = GetMLUFromProfile(h, cmsSigDeviceMfgDescTag); + ps ->Model = GetMLUFromProfile(h, cmsSigDeviceModelDescTag); + ps ->Description = GetMLUFromProfile(h, cmsSigProfileDescriptionTag); + + } + + return seq; +} + +// ------------------------------------------------------------------------------------------------------------------- + + +static +const cmsMLU* GetInfo(cmsHPROFILE hProfile, cmsInfoType Info) +{ + cmsTagSignature sig; + + switch (Info) { + + case cmsInfoDescription: + sig = cmsSigProfileDescriptionTag; + break; + + case cmsInfoManufacturer: + sig = cmsSigDeviceMfgDescTag; + break; + + case cmsInfoModel: + sig = cmsSigDeviceModelDescTag; + break; + + case cmsInfoCopyright: + sig = cmsSigCopyrightTag; + break; + + default: return NULL; + } + + + return (cmsMLU*) cmsReadTag(hProfile, sig); +} + + + +cmsUInt32Number CMSEXPORT cmsGetProfileInfo(cmsHPROFILE hProfile, cmsInfoType Info, + const char LanguageCode[3], const char CountryCode[3], + wchar_t* Buffer, cmsUInt32Number BufferSize) +{ + const cmsMLU* mlu = GetInfo(hProfile, Info); + if (mlu == NULL) return 0; + + return cmsMLUgetWide(mlu, LanguageCode, CountryCode, Buffer, BufferSize); +} + + +cmsUInt32Number CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile, cmsInfoType Info, + const char LanguageCode[3], const char CountryCode[3], + char* Buffer, cmsUInt32Number BufferSize) +{ + const cmsMLU* mlu = GetInfo(hProfile, Info); + if (mlu == NULL) return 0; + + return cmsMLUgetASCII(mlu, LanguageCode, CountryCode, Buffer, BufferSize); +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmslut.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmslut.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmslut.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmslut.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1871 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// Allocates an empty multi profile element +cmsStage* CMSEXPORT _cmsStageAllocPlaceholder(cmsContext ContextID, + cmsStageSignature Type, + cmsUInt32Number InputChannels, + cmsUInt32Number OutputChannels, + _cmsStageEvalFn EvalPtr, + _cmsStageDupElemFn DupElemPtr, + _cmsStageFreeElemFn FreePtr, + void* Data) +{ + cmsStage* ph = (cmsStage*) _cmsMallocZero(ContextID, sizeof(cmsStage)); + + if (ph == NULL) return NULL; + + + ph ->ContextID = ContextID; + + ph ->Type = Type; + ph ->Implements = Type; // By default, no clue on what is implementing + + ph ->InputChannels = InputChannels; + ph ->OutputChannels = OutputChannels; + ph ->EvalPtr = EvalPtr; + ph ->DupElemPtr = DupElemPtr; + ph ->FreePtr = FreePtr; + ph ->Data = Data; + + return ph; +} + + +static +void EvaluateIdentity(const cmsFloat32Number In[], + cmsFloat32Number Out[], + const cmsStage *mpe) +{ + memmove(Out, In, mpe ->InputChannels * sizeof(cmsFloat32Number)); +} + + +cmsStage* CMSEXPORT cmsStageAllocIdentity(cmsContext ContextID, cmsUInt32Number nChannels) +{ + return _cmsStageAllocPlaceholder(ContextID, + cmsSigIdentityElemType, + nChannels, nChannels, + EvaluateIdentity, + NULL, + NULL, + NULL); + } + +// Conversion functions. From floating point to 16 bits +static +void FromFloatTo16(const cmsFloat32Number In[], cmsUInt16Number Out[], cmsUInt32Number n) +{ + cmsUInt32Number i; + + for (i=0; i < n; i++) { + Out[i] = _cmsQuickSaturateWord(In[i] * 65535.0); + } +} + +// From 16 bits to floating point +static +void From16ToFloat(const cmsUInt16Number In[], cmsFloat32Number Out[], cmsUInt32Number n) +{ + cmsUInt32Number i; + + for (i=0; i < n; i++) { + Out[i] = (cmsFloat32Number) In[i] / 65535.0F; + } +} + + +// This function is quite useful to analyze the structure of a LUT and retrieve the MPE elements +// that conform the LUT. It should be called with the LUT, the number of expected elements and +// then a list of expected types followed with a list of cmsFloat64Number pointers to MPE elements. If +// the function founds a match with current pipeline, it fills the pointers and returns TRUE +// if not, returns FALSE without touching anything. Setting pointers to NULL does bypass +// the storage process. +cmsBool CMSEXPORT cmsPipelineCheckAndRetreiveStages(const cmsPipeline* Lut, cmsUInt32Number n, ...) +{ + va_list args; + cmsUInt32Number i; + cmsStage* mpe; + cmsStageSignature Type; + void** ElemPtr; + + // Make sure same number of elements + if (cmsPipelineStageCount(Lut) != n) return FALSE; + + va_start(args, n); + + // Iterate across asked types + mpe = Lut ->Elements; + for (i=0; i < n; i++) { + + // Get asked type. cmsStageSignature is promoted to int by compiler + Type = (cmsStageSignature)va_arg(args, int); + if (mpe ->Type != Type) { + + va_end(args); // Mismatch. We are done. + return FALSE; + } + mpe = mpe ->Next; + } + + // Found a combination, fill pointers if not NULL + mpe = Lut ->Elements; + for (i=0; i < n; i++) { + + ElemPtr = va_arg(args, void**); + if (ElemPtr != NULL) + *ElemPtr = mpe; + + mpe = mpe ->Next; + } + + va_end(args); + return TRUE; +} + +// Below there are implementations for several types of elements. Each type may be implemented by a +// evaluation function, a duplication function, a function to free resources and a constructor. + +// ************************************************************************************************* +// Type cmsSigCurveSetElemType (curves) +// ************************************************************************************************* + +cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe) +{ + _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) mpe ->Data; + + return Data ->TheCurves; +} + +static +void EvaluateCurves(const cmsFloat32Number In[], + cmsFloat32Number Out[], + const cmsStage *mpe) +{ + _cmsStageToneCurvesData* Data; + cmsUInt32Number i; + + _cmsAssert(mpe != NULL); + + Data = (_cmsStageToneCurvesData*) mpe ->Data; + if (Data == NULL) return; + + if (Data ->TheCurves == NULL) return; + + for (i=0; i < Data ->nCurves; i++) { + Out[i] = cmsEvalToneCurveFloat(Data ->TheCurves[i], In[i]); + } +} + +static +void CurveSetElemTypeFree(cmsStage* mpe) +{ + _cmsStageToneCurvesData* Data; + cmsUInt32Number i; + + _cmsAssert(mpe != NULL); + + Data = (_cmsStageToneCurvesData*) mpe ->Data; + if (Data == NULL) return; + + if (Data ->TheCurves != NULL) { + for (i=0; i < Data ->nCurves; i++) { + if (Data ->TheCurves[i] != NULL) + cmsFreeToneCurve(Data ->TheCurves[i]); + } + } + _cmsFree(mpe ->ContextID, Data ->TheCurves); + _cmsFree(mpe ->ContextID, Data); +} + + +static +void* CurveSetDup(cmsStage* mpe) +{ + _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) mpe ->Data; + _cmsStageToneCurvesData* NewElem; + cmsUInt32Number i; + + NewElem = (_cmsStageToneCurvesData*) _cmsMallocZero(mpe ->ContextID, sizeof(_cmsStageToneCurvesData)); + if (NewElem == NULL) return NULL; + + NewElem ->nCurves = Data ->nCurves; + NewElem ->TheCurves = (cmsToneCurve**) _cmsCalloc(mpe ->ContextID, NewElem ->nCurves, sizeof(cmsToneCurve*)); + + if (NewElem ->TheCurves == NULL) goto Error; + + for (i=0; i < NewElem ->nCurves; i++) { + + // Duplicate each curve. It may fail. + NewElem ->TheCurves[i] = cmsDupToneCurve(Data ->TheCurves[i]); + if (NewElem ->TheCurves[i] == NULL) goto Error; + + + } + return (void*) NewElem; + +Error: + + if (NewElem ->TheCurves != NULL) { + for (i=0; i < NewElem ->nCurves; i++) { + if (NewElem ->TheCurves[i]) + cmsFreeToneCurve(NewElem ->TheCurves[i]); + } + } + _cmsFree(mpe ->ContextID, NewElem ->TheCurves); + _cmsFree(mpe ->ContextID, NewElem); + return NULL; +} + + +// Curves == NULL forces identity curves +cmsStage* CMSEXPORT cmsStageAllocToneCurves(cmsContext ContextID, cmsUInt32Number nChannels, cmsToneCurve* const Curves[]) +{ + cmsUInt32Number i; + _cmsStageToneCurvesData* NewElem; + cmsStage* NewMPE; + + + NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCurveSetElemType, nChannels, nChannels, + EvaluateCurves, CurveSetDup, CurveSetElemTypeFree, NULL ); + if (NewMPE == NULL) return NULL; + + NewElem = (_cmsStageToneCurvesData*) _cmsMallocZero(ContextID, sizeof(_cmsStageToneCurvesData)); + if (NewElem == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + NewMPE ->Data = (void*) NewElem; + + NewElem ->nCurves = nChannels; + NewElem ->TheCurves = (cmsToneCurve**) _cmsCalloc(ContextID, nChannels, sizeof(cmsToneCurve*)); + if (NewElem ->TheCurves == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + for (i=0; i < nChannels; i++) { + + if (Curves == NULL) { + NewElem ->TheCurves[i] = cmsBuildGamma(ContextID, 1.0); + } + else { + NewElem ->TheCurves[i] = cmsDupToneCurve(Curves[i]); + } + + if (NewElem ->TheCurves[i] == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + } + + return NewMPE; +} + + +// Create a bunch of identity curves +cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels) +{ + cmsStage* mpe = cmsStageAllocToneCurves(ContextID, nChannels, NULL); + + if (mpe == NULL) return NULL; + mpe ->Implements = cmsSigIdentityElemType; + return mpe; +} + + +// ************************************************************************************************* +// Type cmsSigMatrixElemType (Matrices) +// ************************************************************************************************* + + +// Special care should be taken here because precision loss. A temporary cmsFloat64Number buffer is being used +static +void EvaluateMatrix(const cmsFloat32Number In[], + cmsFloat32Number Out[], + const cmsStage *mpe) +{ + cmsUInt32Number i, j; + _cmsStageMatrixData* Data = (_cmsStageMatrixData*) mpe ->Data; + cmsFloat64Number Tmp; + + // Input is already in 0..1.0 notation + for (i=0; i < mpe ->OutputChannels; i++) { + + Tmp = 0; + for (j=0; j < mpe->InputChannels; j++) { + Tmp += In[j] * Data->Double[i*mpe->InputChannels + j]; + } + + if (Data ->Offset != NULL) + Tmp += Data->Offset[i]; + + Out[i] = (cmsFloat32Number) Tmp; + } + + + // Output in 0..1.0 domain +} + + +// Duplicate a yet-existing matrix element +static +void* MatrixElemDup(cmsStage* mpe) +{ + _cmsStageMatrixData* Data = (_cmsStageMatrixData*) mpe ->Data; + _cmsStageMatrixData* NewElem; + cmsUInt32Number sz; + + NewElem = (_cmsStageMatrixData*) _cmsMallocZero(mpe ->ContextID, sizeof(_cmsStageMatrixData)); + if (NewElem == NULL) return NULL; + + sz = mpe ->InputChannels * mpe ->OutputChannels; + + NewElem ->Double = (cmsFloat64Number*) _cmsDupMem(mpe ->ContextID, Data ->Double, sz * sizeof(cmsFloat64Number)) ; + + if (Data ->Offset) + NewElem ->Offset = (cmsFloat64Number*) _cmsDupMem(mpe ->ContextID, + Data ->Offset, mpe -> OutputChannels * sizeof(cmsFloat64Number)) ; + + return (void*) NewElem; +} + + +static +void MatrixElemTypeFree(cmsStage* mpe) +{ + _cmsStageMatrixData* Data = (_cmsStageMatrixData*) mpe ->Data; + if (Data == NULL) + return; + if (Data ->Double) + _cmsFree(mpe ->ContextID, Data ->Double); + + if (Data ->Offset) + _cmsFree(mpe ->ContextID, Data ->Offset); + + _cmsFree(mpe ->ContextID, mpe ->Data); +} + + + +cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number Rows, cmsUInt32Number Cols, + const cmsFloat64Number* Matrix, const cmsFloat64Number* Offset) +{ + cmsUInt32Number i, n; + _cmsStageMatrixData* NewElem; + cmsStage* NewMPE; + + n = Rows * Cols; + + // Check for overflow + if (n == 0) return NULL; + if (n >= UINT_MAX / Cols) return NULL; + if (n >= UINT_MAX / Rows) return NULL; + if (n < Rows || n < Cols) return NULL; + + NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigMatrixElemType, Cols, Rows, + EvaluateMatrix, MatrixElemDup, MatrixElemTypeFree, NULL ); + if (NewMPE == NULL) return NULL; + + + NewElem = (_cmsStageMatrixData*) _cmsMallocZero(ContextID, sizeof(_cmsStageMatrixData)); + if (NewElem == NULL) goto Error; + NewMPE->Data = (void*)NewElem; + + NewElem ->Double = (cmsFloat64Number*) _cmsCalloc(ContextID, n, sizeof(cmsFloat64Number)); + if (NewElem->Double == NULL) goto Error; + + for (i=0; i < n; i++) { + NewElem ->Double[i] = Matrix[i]; + } + + if (Offset != NULL) { + + NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Rows, sizeof(cmsFloat64Number)); + if (NewElem->Offset == NULL) goto Error; + + for (i=0; i < Rows; i++) { + NewElem ->Offset[i] = Offset[i]; + } + } + + return NewMPE; + +Error: + cmsStageFree(NewMPE); + return NULL; +} + + +// ************************************************************************************************* +// Type cmsSigCLutElemType +// ************************************************************************************************* + + +// Evaluate in true floating point +static +void EvaluateCLUTfloat(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) +{ + _cmsStageCLutData* Data = (_cmsStageCLutData*) mpe ->Data; + + Data -> Params ->Interpolation.LerpFloat(In, Out, Data->Params); +} + + +// Convert to 16 bits, evaluate, and back to floating point +static +void EvaluateCLUTfloatIn16(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) +{ + _cmsStageCLutData* Data = (_cmsStageCLutData*) mpe ->Data; + cmsUInt16Number In16[MAX_STAGE_CHANNELS], Out16[MAX_STAGE_CHANNELS]; + + _cmsAssert(mpe ->InputChannels <= MAX_STAGE_CHANNELS); + _cmsAssert(mpe ->OutputChannels <= MAX_STAGE_CHANNELS); + + FromFloatTo16(In, In16, mpe ->InputChannels); + Data -> Params ->Interpolation.Lerp16(In16, Out16, Data->Params); + From16ToFloat(Out16, Out, mpe ->OutputChannels); +} + + +// Given an hypercube of b dimensions, with Dims[] number of nodes by dimension, calculate the total amount of nodes +static +cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b) +{ + cmsUInt32Number rv, dim; + + _cmsAssert(Dims != NULL); + + for (rv = 1; b > 0; b--) { + + dim = Dims[b-1]; + if (dim <= 1) return 0; // Error + + rv *= dim; + + // Check for overflow + if (rv > UINT_MAX / dim) return 0; + } + + return rv; +} + +static +void* CLUTElemDup(cmsStage* mpe) +{ + _cmsStageCLutData* Data = (_cmsStageCLutData*) mpe ->Data; + _cmsStageCLutData* NewElem; + + + NewElem = (_cmsStageCLutData*) _cmsMallocZero(mpe ->ContextID, sizeof(_cmsStageCLutData)); + if (NewElem == NULL) return NULL; + + NewElem ->nEntries = Data ->nEntries; + NewElem ->HasFloatValues = Data ->HasFloatValues; + + if (Data ->Tab.T) { + + if (Data ->HasFloatValues) { + NewElem ->Tab.TFloat = (cmsFloat32Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.TFloat, Data ->nEntries * sizeof (cmsFloat32Number)); + if (NewElem ->Tab.TFloat == NULL) + goto Error; + } else { + NewElem ->Tab.T = (cmsUInt16Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.T, Data ->nEntries * sizeof (cmsUInt16Number)); + if (NewElem ->Tab.T == NULL) + goto Error; + } + } + + NewElem ->Params = _cmsComputeInterpParamsEx(mpe ->ContextID, + Data ->Params ->nSamples, + Data ->Params ->nInputs, + Data ->Params ->nOutputs, + NewElem ->Tab.T, + Data ->Params ->dwFlags); + if (NewElem->Params != NULL) + return (void*) NewElem; + Error: + if (NewElem->Tab.T) + // This works for both types + _cmsFree(mpe ->ContextID, NewElem -> Tab.T); + _cmsFree(mpe ->ContextID, NewElem); + return NULL; +} + + +static +void CLutElemTypeFree(cmsStage* mpe) +{ + + _cmsStageCLutData* Data = (_cmsStageCLutData*) mpe ->Data; + + // Already empty + if (Data == NULL) return; + + // This works for both types + if (Data -> Tab.T) + _cmsFree(mpe ->ContextID, Data -> Tab.T); + + _cmsFreeInterpParams(Data ->Params); + _cmsFree(mpe ->ContextID, mpe ->Data); +} + + +// Allocates a 16-bit multidimensional CLUT. This is evaluated at 16-bit precision. Table may have different +// granularity on each dimension. +cmsStage* CMSEXPORT cmsStageAllocCLut16bitGranular(cmsContext ContextID, + const cmsUInt32Number clutPoints[], + cmsUInt32Number inputChan, + cmsUInt32Number outputChan, + const cmsUInt16Number* Table) +{ + cmsUInt32Number i, n; + _cmsStageCLutData* NewElem; + cmsStage* NewMPE; + + _cmsAssert(clutPoints != NULL); + + if (inputChan > MAX_INPUT_DIMENSIONS) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Too many input channels (%d channels, max=%d)", inputChan, MAX_INPUT_DIMENSIONS); + return NULL; + } + + NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCLutElemType, inputChan, outputChan, + EvaluateCLUTfloatIn16, CLUTElemDup, CLutElemTypeFree, NULL ); + + if (NewMPE == NULL) return NULL; + + NewElem = (_cmsStageCLutData*) _cmsMallocZero(ContextID, sizeof(_cmsStageCLutData)); + if (NewElem == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + NewMPE ->Data = (void*) NewElem; + + NewElem -> nEntries = n = outputChan * CubeSize(clutPoints, inputChan); + NewElem -> HasFloatValues = FALSE; + + if (n == 0) { + cmsStageFree(NewMPE); + return NULL; + } + + + NewElem ->Tab.T = (cmsUInt16Number*) _cmsCalloc(ContextID, n, sizeof(cmsUInt16Number)); + if (NewElem ->Tab.T == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + if (Table != NULL) { + for (i=0; i < n; i++) { + NewElem ->Tab.T[i] = Table[i]; + } + } + + NewElem ->Params = _cmsComputeInterpParamsEx(ContextID, clutPoints, inputChan, outputChan, NewElem ->Tab.T, CMS_LERP_FLAGS_16BITS); + if (NewElem ->Params == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + return NewMPE; +} + +cmsStage* CMSEXPORT cmsStageAllocCLut16bit(cmsContext ContextID, + cmsUInt32Number nGridPoints, + cmsUInt32Number inputChan, + cmsUInt32Number outputChan, + const cmsUInt16Number* Table) +{ + cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; + int i; + + // Our resulting LUT would be same gridpoints on all dimensions + for (i=0; i < MAX_INPUT_DIMENSIONS; i++) + Dimensions[i] = nGridPoints; + + return cmsStageAllocCLut16bitGranular(ContextID, Dimensions, inputChan, outputChan, Table); +} + + +cmsStage* CMSEXPORT cmsStageAllocCLutFloat(cmsContext ContextID, + cmsUInt32Number nGridPoints, + cmsUInt32Number inputChan, + cmsUInt32Number outputChan, + const cmsFloat32Number* Table) +{ + cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; + int i; + + // Our resulting LUT would be same gridpoints on all dimensions + for (i=0; i < MAX_INPUT_DIMENSIONS; i++) + Dimensions[i] = nGridPoints; + + return cmsStageAllocCLutFloatGranular(ContextID, Dimensions, inputChan, outputChan, Table); +} + + + +cmsStage* CMSEXPORT cmsStageAllocCLutFloatGranular(cmsContext ContextID, const cmsUInt32Number clutPoints[], cmsUInt32Number inputChan, cmsUInt32Number outputChan, const cmsFloat32Number* Table) +{ + cmsUInt32Number i, n; + _cmsStageCLutData* NewElem; + cmsStage* NewMPE; + + _cmsAssert(clutPoints != NULL); + + if (inputChan > MAX_INPUT_DIMENSIONS) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Too many input channels (%d channels, max=%d)", inputChan, MAX_INPUT_DIMENSIONS); + return NULL; + } + + NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCLutElemType, inputChan, outputChan, + EvaluateCLUTfloat, CLUTElemDup, CLutElemTypeFree, NULL); + if (NewMPE == NULL) return NULL; + + + NewElem = (_cmsStageCLutData*) _cmsMallocZero(ContextID, sizeof(_cmsStageCLutData)); + if (NewElem == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + NewMPE ->Data = (void*) NewElem; + + // There is a potential integer overflow on conputing n and nEntries. + NewElem -> nEntries = n = outputChan * CubeSize(clutPoints, inputChan); + NewElem -> HasFloatValues = TRUE; + + if (n == 0) { + cmsStageFree(NewMPE); + return NULL; + } + + NewElem ->Tab.TFloat = (cmsFloat32Number*) _cmsCalloc(ContextID, n, sizeof(cmsFloat32Number)); + if (NewElem ->Tab.TFloat == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + if (Table != NULL) { + for (i=0; i < n; i++) { + NewElem ->Tab.TFloat[i] = Table[i]; + } + } + + NewElem ->Params = _cmsComputeInterpParamsEx(ContextID, clutPoints, inputChan, outputChan, NewElem ->Tab.TFloat, CMS_LERP_FLAGS_FLOAT); + if (NewElem ->Params == NULL) { + cmsStageFree(NewMPE); + return NULL; + } + + return NewMPE; +} + + +static +int IdentitySampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void * Cargo) +{ + int nChan = *(int*) Cargo; + int i; + + for (i=0; i < nChan; i++) + Out[i] = In[i]; + + return 1; +} + +// Creates an MPE that just copies input to output +cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan) +{ + cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; + cmsStage* mpe ; + int i; + + for (i=0; i < MAX_INPUT_DIMENSIONS; i++) + Dimensions[i] = 2; + + mpe = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, nChan, nChan, NULL); + if (mpe == NULL) return NULL; + + if (!cmsStageSampleCLut16bit(mpe, IdentitySampler, &nChan, 0)) { + cmsStageFree(mpe); + return NULL; + } + + mpe ->Implements = cmsSigIdentityElemType; + return mpe; +} + + + +// Quantize a value 0 <= i < MaxSamples to 0..0xffff +cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples) +{ + cmsFloat64Number x; + + x = ((cmsFloat64Number) i * 65535.) / (cmsFloat64Number) (MaxSamples - 1); + return _cmsQuickSaturateWord(x); +} + + +// This routine does a sweep on whole input space, and calls its callback +// function on knots. returns TRUE if all ok, FALSE otherwise. +cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void * Cargo, cmsUInt32Number dwFlags) +{ + int i, t, index, rest; + cmsUInt32Number nTotalPoints; + cmsUInt32Number nInputs, nOutputs; + cmsUInt32Number* nSamples; + cmsUInt16Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; + _cmsStageCLutData* clut; + + if (mpe == NULL) return FALSE; + + clut = (_cmsStageCLutData*) mpe->Data; + + if (clut == NULL) return FALSE; + + nSamples = clut->Params ->nSamples; + nInputs = clut->Params ->nInputs; + nOutputs = clut->Params ->nOutputs; + + if (nInputs <= 0) return FALSE; + if (nOutputs <= 0) return FALSE; + if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE; + if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE; + + memset(In, 0, sizeof(In)); + memset(Out, 0, sizeof(Out)); + + nTotalPoints = CubeSize(nSamples, nInputs); + if (nTotalPoints == 0) return FALSE; + + index = 0; + for (i = 0; i < (int) nTotalPoints; i++) { + + rest = i; + for (t = (int)nInputs - 1; t >= 0; --t) { + + cmsUInt32Number Colorant = rest % nSamples[t]; + + rest /= nSamples[t]; + + In[t] = _cmsQuantizeVal(Colorant, nSamples[t]); + } + + if (clut ->Tab.T != NULL) { + for (t = 0; t < (int)nOutputs; t++) + Out[t] = clut->Tab.T[index + t]; + } + + if (!Sampler(In, Out, Cargo)) + return FALSE; + + if (!(dwFlags & SAMPLER_INSPECT)) { + + if (clut ->Tab.T != NULL) { + for (t=0; t < (int) nOutputs; t++) + clut->Tab.T[index + t] = Out[t]; + } + } + + index += nOutputs; + } + + return TRUE; +} + +// Same as anterior, but for floating point +cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void * Cargo, cmsUInt32Number dwFlags) +{ + int i, t, index, rest; + cmsUInt32Number nTotalPoints; + cmsUInt32Number nInputs, nOutputs; + cmsUInt32Number* nSamples; + cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; + _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data; + + nSamples = clut->Params ->nSamples; + nInputs = clut->Params ->nInputs; + nOutputs = clut->Params ->nOutputs; + + if (nInputs <= 0) return FALSE; + if (nOutputs <= 0) return FALSE; + if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE; + if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE; + + nTotalPoints = CubeSize(nSamples, nInputs); + if (nTotalPoints == 0) return FALSE; + + index = 0; + for (i = 0; i < (int)nTotalPoints; i++) { + + rest = i; + for (t = (int) nInputs-1; t >=0; --t) { + + cmsUInt32Number Colorant = rest % nSamples[t]; + + rest /= nSamples[t]; + + In[t] = (cmsFloat32Number) (_cmsQuantizeVal(Colorant, nSamples[t]) / 65535.0); + } + + if (clut ->Tab.TFloat != NULL) { + for (t=0; t < (int) nOutputs; t++) + Out[t] = clut->Tab.TFloat[index + t]; + } + + if (!Sampler(In, Out, Cargo)) + return FALSE; + + if (!(dwFlags & SAMPLER_INSPECT)) { + + if (clut ->Tab.TFloat != NULL) { + for (t=0; t < (int) nOutputs; t++) + clut->Tab.TFloat[index + t] = Out[t]; + } + } + + index += nOutputs; + } + + return TRUE; +} + + + +// This routine does a sweep on whole input space, and calls its callback +// function on knots. returns TRUE if all ok, FALSE otherwise. +cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], + cmsSAMPLER16 Sampler, void * Cargo) +{ + int i, t, rest; + cmsUInt32Number nTotalPoints; + cmsUInt16Number In[cmsMAXCHANNELS]; + + if (nInputs >= cmsMAXCHANNELS) return FALSE; + + nTotalPoints = CubeSize(clutPoints, nInputs); + if (nTotalPoints == 0) return FALSE; + + for (i = 0; i < (int) nTotalPoints; i++) { + + rest = i; + for (t = (int) nInputs-1; t >=0; --t) { + + cmsUInt32Number Colorant = rest % clutPoints[t]; + + rest /= clutPoints[t]; + In[t] = _cmsQuantizeVal(Colorant, clutPoints[t]); + + } + + if (!Sampler(In, NULL, Cargo)) + return FALSE; + } + + return TRUE; +} + +cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], + cmsSAMPLERFLOAT Sampler, void * Cargo) +{ + int i, t, rest; + cmsUInt32Number nTotalPoints; + cmsFloat32Number In[cmsMAXCHANNELS]; + + if (nInputs >= cmsMAXCHANNELS) return FALSE; + + nTotalPoints = CubeSize(clutPoints, nInputs); + if (nTotalPoints == 0) return FALSE; + + for (i = 0; i < (int) nTotalPoints; i++) { + + rest = i; + for (t = (int) nInputs-1; t >=0; --t) { + + cmsUInt32Number Colorant = rest % clutPoints[t]; + + rest /= clutPoints[t]; + In[t] = (cmsFloat32Number) (_cmsQuantizeVal(Colorant, clutPoints[t]) / 65535.0); + + } + + if (!Sampler(In, NULL, Cargo)) + return FALSE; + } + + return TRUE; +} + +// ******************************************************************************** +// Type cmsSigLab2XYZElemType +// ******************************************************************************** + + +static +void EvaluateLab2XYZ(const cmsFloat32Number In[], + cmsFloat32Number Out[], + const cmsStage *mpe) +{ + cmsCIELab Lab; + cmsCIEXYZ XYZ; + const cmsFloat64Number XYZadj = MAX_ENCODEABLE_XYZ; + + // V4 rules + Lab.L = In[0] * 100.0; + Lab.a = In[1] * 255.0 - 128.0; + Lab.b = In[2] * 255.0 - 128.0; + + cmsLab2XYZ(NULL, &XYZ, &Lab); + + // From XYZ, range 0..19997 to 0..1.0, note that 1.99997 comes from 0xffff + // encoded as 1.15 fixed point, so 1 + (32767.0 / 32768.0) + + Out[0] = (cmsFloat32Number) ((cmsFloat64Number) XYZ.X / XYZadj); + Out[1] = (cmsFloat32Number) ((cmsFloat64Number) XYZ.Y / XYZadj); + Out[2] = (cmsFloat32Number) ((cmsFloat64Number) XYZ.Z / XYZadj); + return; + + cmsUNUSED_PARAMETER(mpe); +} + + +// No dup or free routines needed, as the structure has no pointers in it. +cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID) +{ + return _cmsStageAllocPlaceholder(ContextID, cmsSigLab2XYZElemType, 3, 3, EvaluateLab2XYZ, NULL, NULL, NULL); +} + +// ******************************************************************************** + +// v2 L=100 is supposed to be placed on 0xFF00. There is no reasonable +// number of gridpoints that would make exact match. However, a prelinearization +// of 258 entries, would map 0xFF00 exactly on entry 257, and this is good to avoid scum dot. +// Almost all what we need but unfortunately, the rest of entries should be scaled by +// (255*257/256) and this is not exact. + +cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID) +{ + cmsStage* mpe; + cmsToneCurve* LabTable[3]; + int i, j; + + LabTable[0] = cmsBuildTabulatedToneCurve16(ContextID, 258, NULL); + LabTable[1] = cmsBuildTabulatedToneCurve16(ContextID, 258, NULL); + LabTable[2] = cmsBuildTabulatedToneCurve16(ContextID, 258, NULL); + + for (j=0; j < 3; j++) { + + if (LabTable[j] == NULL) { + cmsFreeToneCurveTriple(LabTable); + return NULL; + } + + // We need to map * (0xffff / 0xff00), that's same as (257 / 256) + // So we can use 258-entry tables to do the trick (i / 257) * (255 * 257) * (257 / 256); + for (i=0; i < 257; i++) { + + LabTable[j]->Table16[i] = (cmsUInt16Number) ((i * 0xffff + 0x80) >> 8); + } + + LabTable[j] ->Table16[257] = 0xffff; + } + + mpe = cmsStageAllocToneCurves(ContextID, 3, LabTable); + cmsFreeToneCurveTriple(LabTable); + + if (mpe == NULL) return NULL; + mpe ->Implements = cmsSigLabV2toV4; + return mpe; +} + +// ******************************************************************************** + +// Matrix-based conversion, which is more accurate, but slower and cannot properly be saved in devicelink profiles +cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID) +{ + static const cmsFloat64Number V2ToV4[] = { 65535.0/65280.0, 0, 0, + 0, 65535.0/65280.0, 0, + 0, 0, 65535.0/65280.0 + }; + + cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, V2ToV4, NULL); + + if (mpe == NULL) return mpe; + mpe ->Implements = cmsSigLabV2toV4; + return mpe; +} + + +// Reverse direction +cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID) +{ + static const cmsFloat64Number V4ToV2[] = { 65280.0/65535.0, 0, 0, + 0, 65280.0/65535.0, 0, + 0, 0, 65280.0/65535.0 + }; + + cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, V4ToV2, NULL); + + if (mpe == NULL) return mpe; + mpe ->Implements = cmsSigLabV4toV2; + return mpe; +} + + +// To Lab to float. Note that the MPE gives numbers in normal Lab range +// and we need 0..1.0 range for the formatters +// L* : 0...100 => 0...1.0 (L* / 100) +// ab* : -128..+127 to 0..1 ((ab* + 128) / 255) + +cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID) +{ + static const cmsFloat64Number a1[] = { + 1.0/100.0, 0, 0, + 0, 1.0/255.0, 0, + 0, 0, 1.0/255.0 + }; + + static const cmsFloat64Number o1[] = { + 0, + 128.0/255.0, + 128.0/255.0 + }; + + cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, o1); + + if (mpe == NULL) return mpe; + mpe ->Implements = cmsSigLab2FloatPCS; + return mpe; +} + +// Fom XYZ to floating point PCS +cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID) +{ +#define n (32768.0/65535.0) + static const cmsFloat64Number a1[] = { + n, 0, 0, + 0, n, 0, + 0, 0, n + }; +#undef n + + cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, NULL); + + if (mpe == NULL) return mpe; + mpe ->Implements = cmsSigXYZ2FloatPCS; + return mpe; +} + +cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID) +{ + static const cmsFloat64Number a1[] = { + 100.0, 0, 0, + 0, 255.0, 0, + 0, 0, 255.0 + }; + + static const cmsFloat64Number o1[] = { + 0, + -128.0, + -128.0 + }; + + cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, o1); + if (mpe == NULL) return mpe; + mpe ->Implements = cmsSigFloatPCS2Lab; + return mpe; +} + +cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID) +{ +#define n (65535.0/32768.0) + + static const cmsFloat64Number a1[] = { + n, 0, 0, + 0, n, 0, + 0, 0, n + }; +#undef n + + cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, NULL); + if (mpe == NULL) return mpe; + mpe ->Implements = cmsSigFloatPCS2XYZ; + return mpe; +} + +// Clips values smaller than zero +static +void Clipper(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) +{ + cmsUInt32Number i; + for (i = 0; i < mpe->InputChannels; i++) { + + cmsFloat32Number n = In[i]; + Out[i] = n < 0 ? 0 : n; + } +} + +cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels) +{ + return _cmsStageAllocPlaceholder(ContextID, cmsSigClipNegativesElemType, + nChannels, nChannels, Clipper, NULL, NULL, NULL); +} + +// ******************************************************************************** +// Type cmsSigXYZ2LabElemType +// ******************************************************************************** + +static +void EvaluateXYZ2Lab(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) +{ + cmsCIELab Lab; + cmsCIEXYZ XYZ; + const cmsFloat64Number XYZadj = MAX_ENCODEABLE_XYZ; + + // From 0..1.0 to XYZ + + XYZ.X = In[0] * XYZadj; + XYZ.Y = In[1] * XYZadj; + XYZ.Z = In[2] * XYZadj; + + cmsXYZ2Lab(NULL, &Lab, &XYZ); + + // From V4 Lab to 0..1.0 + + Out[0] = (cmsFloat32Number) (Lab.L / 100.0); + Out[1] = (cmsFloat32Number) ((Lab.a + 128.0) / 255.0); + Out[2] = (cmsFloat32Number) ((Lab.b + 128.0) / 255.0); + return; + + cmsUNUSED_PARAMETER(mpe); +} + +cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID) +{ + return _cmsStageAllocPlaceholder(ContextID, cmsSigXYZ2LabElemType, 3, 3, EvaluateXYZ2Lab, NULL, NULL, NULL); + +} + +// ******************************************************************************** + +// For v4, S-Shaped curves are placed in a/b axis to increase resolution near gray + +cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID) +{ + cmsToneCurve* LabTable[3]; + cmsFloat64Number Params[1] = {2.4} ; + + LabTable[0] = cmsBuildGamma(ContextID, 1.0); + LabTable[1] = cmsBuildParametricToneCurve(ContextID, 108, Params); + LabTable[2] = cmsBuildParametricToneCurve(ContextID, 108, Params); + + return cmsStageAllocToneCurves(ContextID, 3, LabTable); +} + + +// Free a single MPE +void CMSEXPORT cmsStageFree(cmsStage* mpe) +{ + if (mpe ->FreePtr) + mpe ->FreePtr(mpe); + + _cmsFree(mpe ->ContextID, mpe); +} + + +cmsUInt32Number CMSEXPORT cmsStageInputChannels(const cmsStage* mpe) +{ + return mpe ->InputChannels; +} + +cmsUInt32Number CMSEXPORT cmsStageOutputChannels(const cmsStage* mpe) +{ + return mpe ->OutputChannels; +} + +cmsStageSignature CMSEXPORT cmsStageType(const cmsStage* mpe) +{ + return mpe -> Type; +} + +void* CMSEXPORT cmsStageData(const cmsStage* mpe) +{ + return mpe -> Data; +} + +cmsContext CMSEXPORT cmsGetStageContextID(const cmsStage* mpe) +{ + return mpe -> ContextID; +} + +cmsStage* CMSEXPORT cmsStageNext(const cmsStage* mpe) +{ + return mpe -> Next; +} + + +// Duplicates an MPE +cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe) +{ + cmsStage* NewMPE; + + if (mpe == NULL) return NULL; + NewMPE = _cmsStageAllocPlaceholder(mpe ->ContextID, + mpe ->Type, + mpe ->InputChannels, + mpe ->OutputChannels, + mpe ->EvalPtr, + mpe ->DupElemPtr, + mpe ->FreePtr, + NULL); + if (NewMPE == NULL) return NULL; + + NewMPE ->Implements = mpe ->Implements; + + if (mpe ->DupElemPtr) { + + NewMPE ->Data = mpe ->DupElemPtr(mpe); + + if (NewMPE->Data == NULL) { + + cmsStageFree(NewMPE); + return NULL; + } + + } else { + + NewMPE ->Data = NULL; + } + + return NewMPE; +} + + +// *********************************************************************************************************** + +// This function sets up the channel count +static +cmsBool BlessLUT(cmsPipeline* lut) +{ + // We can set the input/output channels only if we have elements. + if (lut ->Elements != NULL) { + + cmsStage* prev; + cmsStage* next; + cmsStage* First; + cmsStage* Last; + + First = cmsPipelineGetPtrToFirstStage(lut); + Last = cmsPipelineGetPtrToLastStage(lut); + + if (First == NULL || Last == NULL) return FALSE; + + lut->InputChannels = First->InputChannels; + lut->OutputChannels = Last->OutputChannels; + + // Check chain consistency + prev = First; + next = prev->Next; + + while (next != NULL) + { + if (next->InputChannels != prev->OutputChannels) + return FALSE; + + next = next->Next; + prev = prev->Next; + } +} + + return TRUE; +} + + +// Default to evaluate the LUT on 16 bit-basis. Precision is retained. +static +void _LUTeval16(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER const void* D) +{ + cmsPipeline* lut = (cmsPipeline*) D; + cmsStage *mpe; + cmsFloat32Number Storage[2][MAX_STAGE_CHANNELS]; + int Phase = 0, NextPhase; + + From16ToFloat(In, &Storage[Phase][0], lut ->InputChannels); + + for (mpe = lut ->Elements; + mpe != NULL; + mpe = mpe ->Next) { + + NextPhase = Phase ^ 1; + mpe ->EvalPtr(&Storage[Phase][0], &Storage[NextPhase][0], mpe); + Phase = NextPhase; + } + + + FromFloatTo16(&Storage[Phase][0], Out, lut ->OutputChannels); +} + + + +// Does evaluate the LUT on cmsFloat32Number-basis. +static +void _LUTevalFloat(const cmsFloat32Number In[], cmsFloat32Number Out[], const void* D) +{ + cmsPipeline* lut = (cmsPipeline*) D; + cmsStage *mpe; + cmsFloat32Number Storage[2][MAX_STAGE_CHANNELS]; + int Phase = 0, NextPhase; + + memmove(&Storage[Phase][0], In, lut ->InputChannels * sizeof(cmsFloat32Number)); + + for (mpe = lut ->Elements; + mpe != NULL; + mpe = mpe ->Next) { + + NextPhase = Phase ^ 1; + mpe ->EvalPtr(&Storage[Phase][0], &Storage[NextPhase][0], mpe); + Phase = NextPhase; + } + + memmove(Out, &Storage[Phase][0], lut ->OutputChannels * sizeof(cmsFloat32Number)); +} + + +// LUT Creation & Destruction +cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels) +{ + cmsPipeline* NewLUT; + + // A value of zero in channels is allowed as placeholder + if (InputChannels >= cmsMAXCHANNELS || + OutputChannels >= cmsMAXCHANNELS) return NULL; + + NewLUT = (cmsPipeline*) _cmsMallocZero(ContextID, sizeof(cmsPipeline)); + if (NewLUT == NULL) return NULL; + + NewLUT -> InputChannels = InputChannels; + NewLUT -> OutputChannels = OutputChannels; + + NewLUT ->Eval16Fn = _LUTeval16; + NewLUT ->EvalFloatFn = _LUTevalFloat; + NewLUT ->DupDataFn = NULL; + NewLUT ->FreeDataFn = NULL; + NewLUT ->Data = NewLUT; + NewLUT ->ContextID = ContextID; + + if (!BlessLUT(NewLUT)) + { + _cmsFree(ContextID, NewLUT); + return NULL; + } + + return NewLUT; +} + +cmsContext CMSEXPORT cmsGetPipelineContextID(const cmsPipeline* lut) +{ + _cmsAssert(lut != NULL); + return lut ->ContextID; +} + +cmsUInt32Number CMSEXPORT cmsPipelineInputChannels(const cmsPipeline* lut) +{ + _cmsAssert(lut != NULL); + return lut ->InputChannels; +} + +cmsUInt32Number CMSEXPORT cmsPipelineOutputChannels(const cmsPipeline* lut) +{ + _cmsAssert(lut != NULL); + return lut ->OutputChannels; +} + +// Free a profile elements LUT +void CMSEXPORT cmsPipelineFree(cmsPipeline* lut) +{ + cmsStage *mpe, *Next; + + if (lut == NULL) return; + + for (mpe = lut ->Elements; + mpe != NULL; + mpe = Next) { + + Next = mpe ->Next; + cmsStageFree(mpe); + } + + if (lut ->FreeDataFn) lut ->FreeDataFn(lut ->ContextID, lut ->Data); + + _cmsFree(lut ->ContextID, lut); +} + + +// Default to evaluate the LUT on 16 bit-basis. +void CMSEXPORT cmsPipelineEval16(const cmsUInt16Number In[], cmsUInt16Number Out[], const cmsPipeline* lut) +{ + _cmsAssert(lut != NULL); + lut ->Eval16Fn(In, Out, lut->Data); +} + + +// Does evaluate the LUT on cmsFloat32Number-basis. +void CMSEXPORT cmsPipelineEvalFloat(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsPipeline* lut) +{ + _cmsAssert(lut != NULL); + lut ->EvalFloatFn(In, Out, lut); +} + + + +// Duplicates a LUT +cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut) +{ + cmsPipeline* NewLUT; + cmsStage *NewMPE, *Anterior = NULL, *mpe; + cmsBool First = TRUE; + + if (lut == NULL) return NULL; + + NewLUT = cmsPipelineAlloc(lut ->ContextID, lut ->InputChannels, lut ->OutputChannels); + if (NewLUT == NULL) return NULL; + + for (mpe = lut ->Elements; + mpe != NULL; + mpe = mpe ->Next) { + + NewMPE = cmsStageDup(mpe); + + if (NewMPE == NULL) { + cmsPipelineFree(NewLUT); + return NULL; + } + + if (First) { + NewLUT ->Elements = NewMPE; + First = FALSE; + } + else { + if (Anterior != NULL) + Anterior ->Next = NewMPE; + } + + Anterior = NewMPE; + } + + NewLUT ->Eval16Fn = lut ->Eval16Fn; + NewLUT ->EvalFloatFn = lut ->EvalFloatFn; + NewLUT ->DupDataFn = lut ->DupDataFn; + NewLUT ->FreeDataFn = lut ->FreeDataFn; + + if (NewLUT ->DupDataFn != NULL) + NewLUT ->Data = NewLUT ->DupDataFn(lut ->ContextID, lut->Data); + + + NewLUT ->SaveAs8Bits = lut ->SaveAs8Bits; + + if (!BlessLUT(NewLUT)) + { + _cmsFree(lut->ContextID, NewLUT); + return NULL; + } + + return NewLUT; +} + + +int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe) +{ + cmsStage* Anterior = NULL, *pt; + + if (lut == NULL || mpe == NULL) + return FALSE; + + switch (loc) { + + case cmsAT_BEGIN: + mpe ->Next = lut ->Elements; + lut ->Elements = mpe; + break; + + case cmsAT_END: + + if (lut ->Elements == NULL) + lut ->Elements = mpe; + else { + + for (pt = lut ->Elements; + pt != NULL; + pt = pt -> Next) Anterior = pt; + + Anterior ->Next = mpe; + mpe ->Next = NULL; + } + break; + default:; + return FALSE; + } + + return BlessLUT(lut); +} + +// Unlink an element and return the pointer to it +void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage** mpe) +{ + cmsStage *Anterior, *pt, *Last; + cmsStage *Unlinked = NULL; + + + // If empty LUT, there is nothing to remove + if (lut ->Elements == NULL) { + if (mpe) *mpe = NULL; + return; + } + + // On depending on the strategy... + switch (loc) { + + case cmsAT_BEGIN: + { + cmsStage* elem = lut ->Elements; + + lut ->Elements = elem -> Next; + elem ->Next = NULL; + Unlinked = elem; + + } + break; + + case cmsAT_END: + Anterior = Last = NULL; + for (pt = lut ->Elements; + pt != NULL; + pt = pt -> Next) { + Anterior = Last; + Last = pt; + } + + Unlinked = Last; // Next already points to NULL + + // Truncate the chain + if (Anterior) + Anterior ->Next = NULL; + else + lut ->Elements = NULL; + break; + default:; + } + + if (mpe) + *mpe = Unlinked; + else + cmsStageFree(Unlinked); + + // May fail, but we ignore it + BlessLUT(lut); +} + + +// Concatenate two LUT into a new single one +cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2) +{ + cmsStage* mpe; + + // If both LUTS does not have elements, we need to inherit + // the number of channels + if (l1 ->Elements == NULL && l2 ->Elements == NULL) { + l1 ->InputChannels = l2 ->InputChannels; + l1 ->OutputChannels = l2 ->OutputChannels; + } + + // Cat second + for (mpe = l2 ->Elements; + mpe != NULL; + mpe = mpe ->Next) { + + // We have to dup each element + if (!cmsPipelineInsertStage(l1, cmsAT_END, cmsStageDup(mpe))) + return FALSE; + } + + return BlessLUT(l1); +} + + +cmsBool CMSEXPORT cmsPipelineSetSaveAs8bitsFlag(cmsPipeline* lut, cmsBool On) +{ + cmsBool Anterior = lut ->SaveAs8Bits; + + lut ->SaveAs8Bits = On; + return Anterior; +} + + +cmsStage* CMSEXPORT cmsPipelineGetPtrToFirstStage(const cmsPipeline* lut) +{ + return lut ->Elements; +} + +cmsStage* CMSEXPORT cmsPipelineGetPtrToLastStage(const cmsPipeline* lut) +{ + cmsStage *mpe, *Anterior = NULL; + + for (mpe = lut ->Elements; mpe != NULL; mpe = mpe ->Next) + Anterior = mpe; + + return Anterior; +} + +cmsUInt32Number CMSEXPORT cmsPipelineStageCount(const cmsPipeline* lut) +{ + cmsStage *mpe; + cmsUInt32Number n; + + for (n=0, mpe = lut ->Elements; mpe != NULL; mpe = mpe ->Next) + n++; + + return n; +} + +// This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional +// duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality. +void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut, + _cmsPipelineEval16Fn Eval16, + void* PrivateData, + _cmsFreeUserDataFn FreePrivateDataFn, + _cmsDupUserDataFn DupPrivateDataFn) +{ + + Lut ->Eval16Fn = Eval16; + Lut ->DupDataFn = DupPrivateDataFn; + Lut ->FreeDataFn = FreePrivateDataFn; + Lut ->Data = PrivateData; +} + + +// ----------------------------------------------------------- Reverse interpolation +// Here's how it goes. The derivative Df(x) of the function f is the linear +// transformation that best approximates f near the point x. It can be represented +// by a matrix A whose entries are the partial derivatives of the components of f +// with respect to all the coordinates. This is know as the Jacobian +// +// The best linear approximation to f is given by the matrix equation: +// +// y-y0 = A (x-x0) +// +// So, if x0 is a good "guess" for the zero of f, then solving for the zero of this +// linear approximation will give a "better guess" for the zero of f. Thus let y=0, +// and since y0=f(x0) one can solve the above equation for x. This leads to the +// Newton's method formula: +// +// xn+1 = xn - A-1 f(xn) +// +// where xn+1 denotes the (n+1)-st guess, obtained from the n-th guess xn in the +// fashion described above. Iterating this will give better and better approximations +// if you have a "good enough" initial guess. + + +#define JACOBIAN_EPSILON 0.001f +#define INVERSION_MAX_ITERATIONS 30 + +// Increment with reflexion on boundary +static +void IncDelta(cmsFloat32Number *Val) +{ + if (*Val < (1.0 - JACOBIAN_EPSILON)) + + *Val += JACOBIAN_EPSILON; + + else + *Val -= JACOBIAN_EPSILON; + +} + + + +// Euclidean distance between two vectors of n elements each one +static +cmsFloat32Number EuclideanDistance(cmsFloat32Number a[], cmsFloat32Number b[], int n) +{ + cmsFloat32Number sum = 0; + int i; + + for (i=0; i < n; i++) { + cmsFloat32Number dif = b[i] - a[i]; + sum += dif * dif; + } + + return sqrtf(sum); +} + + +// Evaluate a LUT in reverse direction. It only searches on 3->3 LUT. Uses Newton method +// +// x1 <- x - [J(x)]^-1 * f(x) +// +// lut: The LUT on where to do the search +// Target: LabK, 3 values of Lab plus destination K which is fixed +// Result: The obtained CMYK +// Hint: Location where begin the search + +cmsBool CMSEXPORT cmsPipelineEvalReverseFloat(cmsFloat32Number Target[], + cmsFloat32Number Result[], + cmsFloat32Number Hint[], + const cmsPipeline* lut) +{ + cmsUInt32Number i, j; + cmsFloat64Number error, LastError = 1E20; + cmsFloat32Number fx[4], x[4], xd[4], fxd[4]; + cmsVEC3 tmp, tmp2; + cmsMAT3 Jacobian; + + // Only 3->3 and 4->3 are supported + if (lut ->InputChannels != 3 && lut ->InputChannels != 4) return FALSE; + if (lut ->OutputChannels != 3) return FALSE; + + // Take the hint as starting point if specified + if (Hint == NULL) { + + // Begin at any point, we choose 1/3 of CMY axis + x[0] = x[1] = x[2] = 0.3f; + } + else { + + // Only copy 3 channels from hint... + for (j=0; j < 3; j++) + x[j] = Hint[j]; + } + + // If Lut is 4-dimensions, then grab target[3], which is fixed + if (lut ->InputChannels == 4) { + x[3] = Target[3]; + } + else x[3] = 0; // To keep lint happy + + + // Iterate + for (i = 0; i < INVERSION_MAX_ITERATIONS; i++) { + + // Get beginning fx + cmsPipelineEvalFloat(x, fx, lut); + + // Compute error + error = EuclideanDistance(fx, Target, 3); + + // If not convergent, return last safe value + if (error >= LastError) + break; + + // Keep latest values + LastError = error; + for (j=0; j < lut ->InputChannels; j++) + Result[j] = x[j]; + + // Found an exact match? + if (error <= 0) + break; + + // Obtain slope (the Jacobian) + for (j = 0; j < 3; j++) { + + xd[0] = x[0]; + xd[1] = x[1]; + xd[2] = x[2]; + xd[3] = x[3]; // Keep fixed channel + + IncDelta(&xd[j]); + + cmsPipelineEvalFloat(xd, fxd, lut); + + Jacobian.v[0].n[j] = ((fxd[0] - fx[0]) / JACOBIAN_EPSILON); + Jacobian.v[1].n[j] = ((fxd[1] - fx[1]) / JACOBIAN_EPSILON); + Jacobian.v[2].n[j] = ((fxd[2] - fx[2]) / JACOBIAN_EPSILON); + } + + // Solve system + tmp2.n[0] = fx[0] - Target[0]; + tmp2.n[1] = fx[1] - Target[1]; + tmp2.n[2] = fx[2] - Target[2]; + + if (!_cmsMAT3solve(&tmp, &Jacobian, &tmp2)) + return FALSE; + + // Move our guess + x[0] -= (cmsFloat32Number) tmp.n[0]; + x[1] -= (cmsFloat32Number) tmp.n[1]; + x[2] -= (cmsFloat32Number) tmp.n[2]; + + // Some clipping.... + for (j=0; j < 3; j++) { + if (x[j] < 0) x[j] = 0; + else + if (x[j] > 1.0) x[j] = 1.0; + } + } + + return TRUE; +} + + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsmd5.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsmd5.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsmd5.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsmd5.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,342 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- + + +#include "lcms2_internal.h" + +#ifdef CMS_USE_BIG_ENDIAN + +static +void byteReverse(cmsUInt8Number * buf, cmsUInt32Number longs) +{ + do { + + cmsUInt32Number t = _cmsAdjustEndianess32(*(cmsUInt32Number *) buf); + *(cmsUInt32Number *) buf = t; + buf += sizeof(cmsUInt32Number); + + } while (--longs); + +} + +#else +#define byteReverse(buf, len) +#endif + + +typedef struct { + + cmsUInt32Number buf[4]; + cmsUInt32Number bits[2]; + cmsUInt8Number in[64]; + cmsContext ContextID; + +} _cmsMD5; + +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + + +static +void cmsMD5_Transform(cmsUInt32Number buf[4], cmsUInt32Number in[16]) +{ + CMSREGISTER cmsUInt32Number a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + + +// Create a MD5 object + +cmsHANDLE CMSEXPORT cmsMD5alloc(cmsContext ContextID) +{ + _cmsMD5* ctx = (_cmsMD5*) _cmsMallocZero(ContextID, sizeof(_cmsMD5)); + if (ctx == NULL) return NULL; + + ctx ->ContextID = ContextID; + + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; + + return (cmsHANDLE) ctx; +} + +void CMSEXPORT cmsMD5add(cmsHANDLE Handle, const cmsUInt8Number* buf, cmsUInt32Number len) +{ + _cmsMD5* ctx = (_cmsMD5*) Handle; + cmsUInt32Number t; + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + (len << 3)) < t) + ctx->bits[1]++; + + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; + + if (t) { + + cmsUInt8Number *p = (cmsUInt8Number *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memmove(p, buf, len); + return; + } + + memmove(p, buf, t); + byteReverse(ctx->in, 16); + + cmsMD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in); + buf += t; + len -= t; + } + + while (len >= 64) { + memmove(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + cmsMD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in); + buf += 64; + len -= 64; + } + + memmove(ctx->in, buf, len); +} + +// Destroy the object and return the checksum +void CMSEXPORT cmsMD5finish(cmsProfileID* ProfileID, cmsHANDLE Handle) +{ + _cmsMD5* ctx = (_cmsMD5*) Handle; + cmsUInt32Number count; + cmsUInt8Number *p; + + count = (ctx->bits[0] >> 3) & 0x3F; + + p = ctx->in + count; + *p++ = 0x80; + + count = 64 - 1 - count; + + if (count < 8) { + + memset(p, 0, count); + byteReverse(ctx->in, 16); + cmsMD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in); + + memset(ctx->in, 0, 56); + } else { + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + ((cmsUInt32Number *) ctx->in)[14] = ctx->bits[0]; + ((cmsUInt32Number *) ctx->in)[15] = ctx->bits[1]; + + cmsMD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in); + + byteReverse((cmsUInt8Number *) ctx->buf, 4); + memmove(ProfileID ->ID8, ctx->buf, 16); + + _cmsFree(ctx ->ContextID, ctx); +} + + + +// Assuming io points to an ICC profile, compute and store MD5 checksum +// In the header, rendering intentent, attributes and ID should be set to zero +// before computing MD5 checksum (per 6.1.13 in ICC spec) + +cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile) +{ + cmsContext ContextID; + cmsUInt32Number BytesNeeded; + cmsUInt8Number* Mem = NULL; + cmsHANDLE MD5 = NULL; + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + _cmsICCPROFILE Keep; + + _cmsAssert(hProfile != NULL); + + ContextID = cmsGetProfileContextID(hProfile); + + // Save a copy of the profile header + memmove(&Keep, Icc, sizeof(_cmsICCPROFILE)); + + // Set RI, attributes and ID + memset(&Icc ->attributes, 0, sizeof(Icc ->attributes)); + Icc ->RenderingIntent = 0; + memset(&Icc ->ProfileID, 0, sizeof(Icc ->ProfileID)); + + // Compute needed storage + if (!cmsSaveProfileToMem(hProfile, NULL, &BytesNeeded)) goto Error; + + // Allocate memory + Mem = (cmsUInt8Number*) _cmsMalloc(ContextID, BytesNeeded); + if (Mem == NULL) goto Error; + + // Save to temporary storage + if (!cmsSaveProfileToMem(hProfile, Mem, &BytesNeeded)) goto Error; + + // Create MD5 object + MD5 = cmsMD5alloc(ContextID); + if (MD5 == NULL) goto Error; + + // Add all bytes + cmsMD5add(MD5, Mem, BytesNeeded); + + // Temp storage is no longer needed + _cmsFree(ContextID, Mem); + + // Restore header + memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); + + // And store the ID + cmsMD5finish(&Icc ->ProfileID, MD5); + return TRUE; + +Error: + + // Free resources as something went wrong + // "MD5" cannot be other than NULL here, so no need to free it + if (Mem != NULL) _cmsFree(ContextID, Mem); + memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); + return FALSE; +} + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsmtrx.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsmtrx.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsmtrx.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsmtrx.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,205 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +#define DSWAP(x, y) {cmsFloat64Number tmp = (x); (x)=(y); (y)=tmp;} + + +// Initiate a vector +void CMSEXPORT _cmsVEC3init(cmsVEC3* r, cmsFloat64Number x, cmsFloat64Number y, cmsFloat64Number z) +{ + r -> n[VX] = x; + r -> n[VY] = y; + r -> n[VZ] = z; +} + +// Vector subtraction +void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b) +{ + r -> n[VX] = a -> n[VX] - b -> n[VX]; + r -> n[VY] = a -> n[VY] - b -> n[VY]; + r -> n[VZ] = a -> n[VZ] - b -> n[VZ]; +} + +// Vector cross product +void CMSEXPORT _cmsVEC3cross(cmsVEC3* r, const cmsVEC3* u, const cmsVEC3* v) +{ + r ->n[VX] = u->n[VY] * v->n[VZ] - v->n[VY] * u->n[VZ]; + r ->n[VY] = u->n[VZ] * v->n[VX] - v->n[VZ] * u->n[VX]; + r ->n[VZ] = u->n[VX] * v->n[VY] - v->n[VX] * u->n[VY]; +} + +// Vector dot product +cmsFloat64Number CMSEXPORT _cmsVEC3dot(const cmsVEC3* u, const cmsVEC3* v) +{ + return u->n[VX] * v->n[VX] + u->n[VY] * v->n[VY] + u->n[VZ] * v->n[VZ]; +} + +// Euclidean length +cmsFloat64Number CMSEXPORT _cmsVEC3length(const cmsVEC3* a) +{ + return sqrt(a ->n[VX] * a ->n[VX] + + a ->n[VY] * a ->n[VY] + + a ->n[VZ] * a ->n[VZ]); +} + +// Euclidean distance +cmsFloat64Number CMSEXPORT _cmsVEC3distance(const cmsVEC3* a, const cmsVEC3* b) +{ + cmsFloat64Number d1 = a ->n[VX] - b ->n[VX]; + cmsFloat64Number d2 = a ->n[VY] - b ->n[VY]; + cmsFloat64Number d3 = a ->n[VZ] - b ->n[VZ]; + + return sqrt(d1*d1 + d2*d2 + d3*d3); +} + + + +// 3x3 Identity +void CMSEXPORT _cmsMAT3identity(cmsMAT3* a) +{ + _cmsVEC3init(&a-> v[0], 1.0, 0.0, 0.0); + _cmsVEC3init(&a-> v[1], 0.0, 1.0, 0.0); + _cmsVEC3init(&a-> v[2], 0.0, 0.0, 1.0); +} + +static +cmsBool CloseEnough(cmsFloat64Number a, cmsFloat64Number b) +{ + return fabs(b - a) < (1.0 / 65535.0); +} + + +cmsBool CMSEXPORT _cmsMAT3isIdentity(const cmsMAT3* a) +{ + cmsMAT3 Identity; + int i, j; + + _cmsMAT3identity(&Identity); + + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + if (!CloseEnough(a ->v[i].n[j], Identity.v[i].n[j])) return FALSE; + + return TRUE; +} + + +// Multiply two matrices +void CMSEXPORT _cmsMAT3per(cmsMAT3* r, const cmsMAT3* a, const cmsMAT3* b) +{ +#define ROWCOL(i, j) \ + a->v[i].n[0]*b->v[0].n[j] + a->v[i].n[1]*b->v[1].n[j] + a->v[i].n[2]*b->v[2].n[j] + + _cmsVEC3init(&r-> v[0], ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)); + _cmsVEC3init(&r-> v[1], ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)); + _cmsVEC3init(&r-> v[2], ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)); + +#undef ROWCOL //(i, j) +} + + + +// Inverse of a matrix b = a^(-1) +cmsBool CMSEXPORT _cmsMAT3inverse(const cmsMAT3* a, cmsMAT3* b) +{ + cmsFloat64Number det, c0, c1, c2; + + c0 = a -> v[1].n[1]*a -> v[2].n[2] - a -> v[1].n[2]*a -> v[2].n[1]; + c1 = -a -> v[1].n[0]*a -> v[2].n[2] + a -> v[1].n[2]*a -> v[2].n[0]; + c2 = a -> v[1].n[0]*a -> v[2].n[1] - a -> v[1].n[1]*a -> v[2].n[0]; + + det = a -> v[0].n[0]*c0 + a -> v[0].n[1]*c1 + a -> v[0].n[2]*c2; + + if (fabs(det) < MATRIX_DET_TOLERANCE) return FALSE; // singular matrix; can't invert + + b -> v[0].n[0] = c0/det; + b -> v[0].n[1] = (a -> v[0].n[2]*a -> v[2].n[1] - a -> v[0].n[1]*a -> v[2].n[2])/det; + b -> v[0].n[2] = (a -> v[0].n[1]*a -> v[1].n[2] - a -> v[0].n[2]*a -> v[1].n[1])/det; + b -> v[1].n[0] = c1/det; + b -> v[1].n[1] = (a -> v[0].n[0]*a -> v[2].n[2] - a -> v[0].n[2]*a -> v[2].n[0])/det; + b -> v[1].n[2] = (a -> v[0].n[2]*a -> v[1].n[0] - a -> v[0].n[0]*a -> v[1].n[2])/det; + b -> v[2].n[0] = c2/det; + b -> v[2].n[1] = (a -> v[0].n[1]*a -> v[2].n[0] - a -> v[0].n[0]*a -> v[2].n[1])/det; + b -> v[2].n[2] = (a -> v[0].n[0]*a -> v[1].n[1] - a -> v[0].n[1]*a -> v[1].n[0])/det; + + return TRUE; +} + + +// Solve a system in the form Ax = b +cmsBool CMSEXPORT _cmsMAT3solve(cmsVEC3* x, cmsMAT3* a, cmsVEC3* b) +{ + cmsMAT3 m, a_1; + + memmove(&m, a, sizeof(cmsMAT3)); + + if (!_cmsMAT3inverse(&m, &a_1)) return FALSE; // Singular matrix + + _cmsMAT3eval(x, &a_1, b); + return TRUE; +} + +// Evaluate a vector across a matrix +void CMSEXPORT _cmsMAT3eval(cmsVEC3* r, const cmsMAT3* a, const cmsVEC3* v) +{ + r->n[VX] = a->v[0].n[VX]*v->n[VX] + a->v[0].n[VY]*v->n[VY] + a->v[0].n[VZ]*v->n[VZ]; + r->n[VY] = a->v[1].n[VX]*v->n[VX] + a->v[1].n[VY]*v->n[VY] + a->v[1].n[VZ]*v->n[VZ]; + r->n[VZ] = a->v[2].n[VX]*v->n[VX] + a->v[2].n[VY]*v->n[VY] + a->v[2].n[VZ]*v->n[VZ]; +} + + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsnamed.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsnamed.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsnamed.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsnamed.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1021 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// Multilocalized unicode objects. That is an attempt to encapsulate i18n. + + +// Allocates an empty multi localizad unicode object +cmsMLU* CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems) +{ + cmsMLU* mlu; + + // nItems should be positive if given + if (nItems <= 0) nItems = 2; + + // Create the container + mlu = (cmsMLU*) _cmsMallocZero(ContextID, sizeof(cmsMLU)); + if (mlu == NULL) return NULL; + + mlu ->ContextID = ContextID; + + // Create entry array + mlu ->Entries = (_cmsMLUentry*) _cmsCalloc(ContextID, nItems, sizeof(_cmsMLUentry)); + if (mlu ->Entries == NULL) { + _cmsFree(ContextID, mlu); + return NULL; + } + + // Ok, keep indexes up to date + mlu ->AllocatedEntries = nItems; + mlu ->UsedEntries = 0; + + return mlu; +} + + +// Grows a mempool table for a MLU. Each time this function is called, mempool size is multiplied times two. +static +cmsBool GrowMLUpool(cmsMLU* mlu) +{ + cmsUInt32Number size; + void *NewPtr; + + // Sanity check + if (mlu == NULL) return FALSE; + + if (mlu ->PoolSize == 0) + size = 256; + else + size = mlu ->PoolSize * 2; + + // Check for overflow + if (size < mlu ->PoolSize) return FALSE; + + // Reallocate the pool + NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size); + if (NewPtr == NULL) return FALSE; + + + mlu ->MemPool = NewPtr; + mlu ->PoolSize = size; + + return TRUE; +} + + +// Grows a entry table for a MLU. Each time this function is called, table size is multiplied times two. +static +cmsBool GrowMLUtable(cmsMLU* mlu) +{ + cmsUInt32Number AllocatedEntries; + _cmsMLUentry *NewPtr; + + // Sanity check + if (mlu == NULL) return FALSE; + + AllocatedEntries = mlu ->AllocatedEntries * 2; + + // Check for overflow + if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE; + + // Reallocate the memory + NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry)); + if (NewPtr == NULL) return FALSE; + + mlu ->Entries = NewPtr; + mlu ->AllocatedEntries = AllocatedEntries; + + return TRUE; +} + + +// Search for a specific entry in the structure. Language and Country are used. +static +int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode) +{ + cmsUInt32Number i; + + // Sanity check + if (mlu == NULL) return -1; + + // Iterate whole table + for (i=0; i < mlu ->UsedEntries; i++) { + + if (mlu ->Entries[i].Country == CountryCode && + mlu ->Entries[i].Language == LanguageCode) return (int) i; + } + + // Not found + return -1; +} + +// Add a block of characters to the intended MLU. Language and country are specified. +// Only one entry for Language/country pair is allowed. +static +cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block, + cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode) +{ + cmsUInt32Number Offset; + cmsUInt8Number* Ptr; + + // Sanity check + if (mlu == NULL) return FALSE; + + // Is there any room available? + if (mlu ->UsedEntries >= mlu ->AllocatedEntries) { + if (!GrowMLUtable(mlu)) return FALSE; + } + + // Only one ASCII string + if (SearchMLUEntry(mlu, LanguageCode, CountryCode) >= 0) return FALSE; // Only one is allowed! + + // Check for size + while ((mlu ->PoolSize - mlu ->PoolUsed) < size) { + + if (!GrowMLUpool(mlu)) return FALSE; + } + + Offset = mlu ->PoolUsed; + + Ptr = (cmsUInt8Number*) mlu ->MemPool; + if (Ptr == NULL) return FALSE; + + // Set the entry + memmove(Ptr + Offset, Block, size); + mlu ->PoolUsed += size; + + mlu ->Entries[mlu ->UsedEntries].StrW = Offset; + mlu ->Entries[mlu ->UsedEntries].Len = size; + mlu ->Entries[mlu ->UsedEntries].Country = CountryCode; + mlu ->Entries[mlu ->UsedEntries].Language = LanguageCode; + mlu ->UsedEntries++; + + return TRUE; +} + +// Convert from a 3-char code to a cmsUInt16Number. It is done in this way because some +// compilers don't properly align beginning of strings +static +cmsUInt16Number strTo16(const char str[3]) +{ + const cmsUInt8Number* ptr8; + cmsUInt16Number n; + + // For non-existent strings + if (str == NULL) return 0; + ptr8 = (const cmsUInt8Number*)str; + n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]); + + return n; +} + +static +void strFrom16(char str[3], cmsUInt16Number n) +{ + str[0] = (char)(n >> 8); + str[1] = (char)n; + str[2] = (char)0; + +} + +// Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61) +// In the case the user explicitly sets an empty string, we force a \0 +cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString) +{ + cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString); + wchar_t* WStr; + cmsBool rc; + cmsUInt16Number Lang = strTo16(LanguageCode); + cmsUInt16Number Cntry = strTo16(CountryCode); + + if (mlu == NULL) return FALSE; + + // len == 0 would prevent operation, so we set a empty string pointing to zero + if (len == 0) + { + len = 1; + } + + WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len, sizeof(wchar_t)); + if (WStr == NULL) return FALSE; + + for (i=0; i < len; i++) + WStr[i] = (wchar_t) ASCIIString[i]; + + rc = AddMLUBlock(mlu, len * sizeof(wchar_t), WStr, Lang, Cntry); + + _cmsFree(mlu ->ContextID, WStr); + return rc; + +} + +// We don't need any wcs support library +static +cmsUInt32Number mywcslen(const wchar_t *s) +{ + const wchar_t *p; + + p = s; + while (*p) + p++; + + return (cmsUInt32Number)(p - s); +} + +// Add a wide entry. Do not add any \0 terminator (ICC1v43_2010-12.pdf page 61) +cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString) +{ + cmsUInt16Number Lang = strTo16(Language); + cmsUInt16Number Cntry = strTo16(Country); + cmsUInt32Number len; + + if (mlu == NULL) return FALSE; + if (WideString == NULL) return FALSE; + + len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t); + if (len == 0) + len = sizeof(wchar_t); + + return AddMLUBlock(mlu, len, WideString, Lang, Cntry); +} + +// Duplicating a MLU is as easy as copying all members +cmsMLU* CMSEXPORT cmsMLUdup(const cmsMLU* mlu) +{ + cmsMLU* NewMlu = NULL; + + // Duplicating a NULL obtains a NULL + if (mlu == NULL) return NULL; + + NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries); + if (NewMlu == NULL) return NULL; + + // Should never happen + if (NewMlu ->AllocatedEntries < mlu ->UsedEntries) + goto Error; + + // Sanitize... + if (NewMlu ->Entries == NULL || mlu ->Entries == NULL) goto Error; + + memmove(NewMlu ->Entries, mlu ->Entries, mlu ->UsedEntries * sizeof(_cmsMLUentry)); + NewMlu ->UsedEntries = mlu ->UsedEntries; + + // The MLU may be empty + if (mlu ->PoolUsed == 0) { + NewMlu ->MemPool = NULL; + } + else { + // It is not empty + NewMlu ->MemPool = _cmsMalloc(mlu ->ContextID, mlu ->PoolUsed); + if (NewMlu ->MemPool == NULL) goto Error; + } + + NewMlu ->PoolSize = mlu ->PoolUsed; + + if (NewMlu ->MemPool == NULL || mlu ->MemPool == NULL) goto Error; + + memmove(NewMlu ->MemPool, mlu->MemPool, mlu ->PoolUsed); + NewMlu ->PoolUsed = mlu ->PoolUsed; + + return NewMlu; + +Error: + + if (NewMlu != NULL) cmsMLUfree(NewMlu); + return NULL; +} + +// Free any used memory +void CMSEXPORT cmsMLUfree(cmsMLU* mlu) +{ + if (mlu) { + + if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries); + if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool); + + _cmsFree(mlu ->ContextID, mlu); + } +} + + +// The algorithm first searches for an exact match of country and language, if not found it uses +// the Language. If none is found, first entry is used instead. +static +const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu, + cmsUInt32Number *len, + cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode, + cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode) +{ + cmsUInt32Number i; + int Best = -1; + _cmsMLUentry* v; + + if (mlu == NULL) return NULL; + + if (mlu -> AllocatedEntries <= 0) return NULL; + + for (i=0; i < mlu ->UsedEntries; i++) { + + v = mlu ->Entries + i; + + if (v -> Language == LanguageCode) { + + if (Best == -1) Best = (int) i; + + if (v -> Country == CountryCode) { + + if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; + if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country; + + if (len != NULL) *len = v ->Len; + + return (wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v -> StrW); // Found exact match + } + } + } + + // No string found. Return First one + if (Best == -1) + Best = 0; + + v = mlu ->Entries + Best; + + if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; + if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country; + + if (len != NULL) *len = v ->Len; + + if (v->StrW + v->Len > mlu->PoolSize) return NULL; + + return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW); +} + + +// Obtain an ASCII representation of the wide string. Setting buffer to NULL returns the len +cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + char* Buffer, cmsUInt32Number BufferSize) +{ + const wchar_t *Wide; + cmsUInt32Number StrLen = 0; + cmsUInt32Number ASCIIlen, i; + + cmsUInt16Number Lang = strTo16(LanguageCode); + cmsUInt16Number Cntry = strTo16(CountryCode); + + // Sanitize + if (mlu == NULL) return 0; + + // Get WideChar + Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL); + if (Wide == NULL) return 0; + + ASCIIlen = StrLen / sizeof(wchar_t); + + // Maybe we want only to know the len? + if (Buffer == NULL) return ASCIIlen + 1; // Note the zero at the end + + // No buffer size means no data + if (BufferSize <= 0) return 0; + + // Some clipping may be required + if (BufferSize < ASCIIlen + 1) + ASCIIlen = BufferSize - 1; + + // Precess each character + for (i=0; i < ASCIIlen; i++) { + + if (Wide[i] == 0) + Buffer[i] = 0; + else + Buffer[i] = (char) Wide[i]; + } + + // We put a termination "\0" + Buffer[ASCIIlen] = 0; + return ASCIIlen + 1; +} + +// Obtain a wide representation of the MLU, on depending on current locale settings +cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + wchar_t* Buffer, cmsUInt32Number BufferSize) +{ + const wchar_t *Wide; + cmsUInt32Number StrLen = 0; + + cmsUInt16Number Lang = strTo16(LanguageCode); + cmsUInt16Number Cntry = strTo16(CountryCode); + + // Sanitize + if (mlu == NULL) return 0; + + Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL); + if (Wide == NULL) return 0; + + // Maybe we want only to know the len? + if (Buffer == NULL) return StrLen + sizeof(wchar_t); + + // No buffer size means no data + if (BufferSize <= 0) return 0; + + // Some clipping may be required + if (BufferSize < StrLen + sizeof(wchar_t)) + StrLen = BufferSize - + sizeof(wchar_t); + + memmove(Buffer, Wide, StrLen); + Buffer[StrLen / sizeof(wchar_t)] = 0; + + return StrLen + sizeof(wchar_t); +} + + +// Get also the language and country +CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + char ObtainedLanguage[3], char ObtainedCountry[3]) +{ + const wchar_t *Wide; + + cmsUInt16Number Lang = strTo16(LanguageCode); + cmsUInt16Number Cntry = strTo16(CountryCode); + cmsUInt16Number ObtLang, ObtCode; + + // Sanitize + if (mlu == NULL) return FALSE; + + Wide = _cmsMLUgetWide(mlu, NULL, Lang, Cntry, &ObtLang, &ObtCode); + if (Wide == NULL) return FALSE; + + // Get used language and code + strFrom16(ObtainedLanguage, ObtLang); + strFrom16(ObtainedCountry, ObtCode); + + return TRUE; +} + + + +// Get the number of translations in the MLU object +cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu) +{ + if (mlu == NULL) return 0; + return mlu->UsedEntries; +} + +// Get the language and country codes for a specific MLU index +cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu, + cmsUInt32Number idx, + char LanguageCode[3], + char CountryCode[3]) +{ + _cmsMLUentry *entry; + + if (mlu == NULL) return FALSE; + + if (idx >= mlu->UsedEntries) return FALSE; + + entry = &mlu->Entries[idx]; + + strFrom16(LanguageCode, entry->Language); + strFrom16(CountryCode, entry->Country); + + return TRUE; +} + + +// Named color lists -------------------------------------------------------------------------------------------- + +// Grow the list to keep at least NumElements +static +cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v) +{ + cmsUInt32Number size; + _cmsNAMEDCOLOR * NewPtr; + + if (v == NULL) return FALSE; + + if (v ->Allocated == 0) + size = 64; // Initial guess + else + size = v ->Allocated * 2; + + // Keep a maximum color lists can grow, 100K entries seems reasonable + if (size > 1024 * 100) { + _cmsFree(v->ContextID, (void*) v->List); + v->List = NULL; + return FALSE; + } + + NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR)); + if (NewPtr == NULL) + return FALSE; + + v ->List = NewPtr; + v ->Allocated = size; + return TRUE; +} + +// Allocate a list for n elements +cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUInt32Number n, cmsUInt32Number ColorantCount, const char* Prefix, const char* Suffix) +{ + cmsNAMEDCOLORLIST* v; + + if (ColorantCount > cmsMAXCHANNELS) + return NULL; + + v = (cmsNAMEDCOLORLIST*)_cmsMallocZero(ContextID, sizeof(cmsNAMEDCOLORLIST)); + if (v == NULL) return NULL; + + v ->List = NULL; + v ->nColors = 0; + v ->ContextID = ContextID; + + while (v -> Allocated < n) { + if (!GrowNamedColorList(v)) { + cmsFreeNamedColorList(v); + return NULL; + } + } + + strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1); + strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix)-1); + v->Prefix[32] = v->Suffix[32] = 0; + + v -> ColorantCount = ColorantCount; + + return v; +} + +// Free a list +void CMSEXPORT cmsFreeNamedColorList(cmsNAMEDCOLORLIST* v) +{ + if (v == NULL) return; + if (v ->List) _cmsFree(v ->ContextID, v ->List); + _cmsFree(v ->ContextID, v); +} + +cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v) +{ + cmsNAMEDCOLORLIST* NewNC; + + if (v == NULL) return NULL; + + NewNC= cmsAllocNamedColorList(v ->ContextID, v -> nColors, v ->ColorantCount, v ->Prefix, v ->Suffix); + if (NewNC == NULL) return NULL; + + // For really large tables we need this + while (NewNC ->Allocated < v ->Allocated){ + if (!GrowNamedColorList(NewNC)) + { + cmsFreeNamedColorList(NewNC); + return NULL; + } + } + + memmove(NewNC ->Prefix, v ->Prefix, sizeof(v ->Prefix)); + memmove(NewNC ->Suffix, v ->Suffix, sizeof(v ->Suffix)); + NewNC ->ColorantCount = v ->ColorantCount; + memmove(NewNC->List, v ->List, v->nColors * sizeof(_cmsNAMEDCOLOR)); + NewNC ->nColors = v ->nColors; + return NewNC; +} + + +// Append a color to a list. List pointer may change if reallocated +cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList, + const char* Name, + cmsUInt16Number PCS[3], cmsUInt16Number Colorant[cmsMAXCHANNELS]) +{ + cmsUInt32Number i; + + if (NamedColorList == NULL) return FALSE; + + if (NamedColorList ->nColors + 1 > NamedColorList ->Allocated) { + if (!GrowNamedColorList(NamedColorList)) return FALSE; + } + + for (i=0; i < NamedColorList ->ColorantCount; i++) + NamedColorList ->List[NamedColorList ->nColors].DeviceColorant[i] = Colorant == NULL ? (cmsUInt16Number)0 : Colorant[i]; + + for (i=0; i < 3; i++) + NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? (cmsUInt16Number) 0 : PCS[i]; + + if (Name != NULL) { + + strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name, cmsMAX_PATH-1); + NamedColorList ->List[NamedColorList ->nColors].Name[cmsMAX_PATH-1] = 0; + + } + else + NamedColorList ->List[NamedColorList ->nColors].Name[0] = 0; + + + NamedColorList ->nColors++; + return TRUE; +} + +// Returns number of elements +cmsUInt32Number CMSEXPORT cmsNamedColorCount(const cmsNAMEDCOLORLIST* NamedColorList) +{ + if (NamedColorList == NULL) return 0; + return NamedColorList ->nColors; +} + +// Info about a given color +cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cmsUInt32Number nColor, + char* Name, + char* Prefix, + char* Suffix, + cmsUInt16Number* PCS, + cmsUInt16Number* Colorant) +{ + if (NamedColorList == NULL) return FALSE; + + if (nColor >= cmsNamedColorCount(NamedColorList)) return FALSE; + + // strcpy instead of strncpy because many apps are using small buffers + if (Name) strcpy(Name, NamedColorList->List[nColor].Name); + if (Prefix) strcpy(Prefix, NamedColorList->Prefix); + if (Suffix) strcpy(Suffix, NamedColorList->Suffix); + if (PCS) + memmove(PCS, NamedColorList ->List[nColor].PCS, 3*sizeof(cmsUInt16Number)); + + if (Colorant) + memmove(Colorant, NamedColorList ->List[nColor].DeviceColorant, + sizeof(cmsUInt16Number) * NamedColorList ->ColorantCount); + + + return TRUE; +} + +// Search for a given color name (no prefix or suffix) +cmsInt32Number CMSEXPORT cmsNamedColorIndex(const cmsNAMEDCOLORLIST* NamedColorList, const char* Name) +{ + cmsUInt32Number i; + cmsUInt32Number n; + + if (NamedColorList == NULL) return -1; + n = cmsNamedColorCount(NamedColorList); + for (i=0; i < n; i++) { + if (cmsstrcasecmp(Name, NamedColorList->List[i].Name) == 0) + return (cmsInt32Number) i; + } + + return -1; +} + +// MPE support ----------------------------------------------------------------------------------------------------------------- + +static +void FreeNamedColorList(cmsStage* mpe) +{ + cmsNAMEDCOLORLIST* List = (cmsNAMEDCOLORLIST*) mpe ->Data; + cmsFreeNamedColorList(List); +} + +static +void* DupNamedColorList(cmsStage* mpe) +{ + cmsNAMEDCOLORLIST* List = (cmsNAMEDCOLORLIST*) mpe ->Data; + return cmsDupNamedColorList(List); +} + +static +void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) +{ + cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data; + cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0); + + if (index >= NamedColorList-> nColors) { + cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range", index); + Out[0] = Out[1] = Out[2] = 0.0f; + } + else { + + // Named color always uses Lab + Out[0] = (cmsFloat32Number) (NamedColorList->List[index].PCS[0] / 65535.0); + Out[1] = (cmsFloat32Number) (NamedColorList->List[index].PCS[1] / 65535.0); + Out[2] = (cmsFloat32Number) (NamedColorList->List[index].PCS[2] / 65535.0); + } +} + +static +void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) +{ + cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data; + cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0); + cmsUInt32Number j; + + if (index >= NamedColorList-> nColors) { + cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range", index); + for (j = 0; j < NamedColorList->ColorantCount; j++) + Out[j] = 0.0f; + + } + else { + for (j=0; j < NamedColorList ->ColorantCount; j++) + Out[j] = (cmsFloat32Number) (NamedColorList->List[index].DeviceColorant[j] / 65535.0); + } +} + + +// Named color lookup element +cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS) +{ + return _cmsStageAllocPlaceholder(NamedColorList ->ContextID, + cmsSigNamedColorElemType, + 1, UsePCS ? 3 : NamedColorList ->ColorantCount, + UsePCS ? EvalNamedColorPCS : EvalNamedColor, + DupNamedColorList, + FreeNamedColorList, + cmsDupNamedColorList(NamedColorList)); + +} + + +// Retrieve the named color list from a transform. Should be first element in the LUT +cmsNAMEDCOLORLIST* CMSEXPORT cmsGetNamedColorList(cmsHTRANSFORM xform) +{ + _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform; + cmsStage* mpe; + + if (v == NULL) return NULL; + if (v->Lut == NULL) return NULL; + + mpe = v->Lut->Elements; + if (mpe == NULL) return NULL; + + if (mpe ->Type != cmsSigNamedColorElemType) return NULL; + return (cmsNAMEDCOLORLIST*) mpe ->Data; +} + + +// Profile sequence description routines ------------------------------------------------------------------------------------- + +cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext ContextID, cmsUInt32Number n) +{ + cmsSEQ* Seq; + cmsUInt32Number i; + + if (n == 0) return NULL; + + // In a absolutely arbitrary way, I hereby decide to allow a maxim of 255 profiles linked + // in a devicelink. It makes not sense anyway and may be used for exploits, so let's close the door! + if (n > 255) return NULL; + + Seq = (cmsSEQ*) _cmsMallocZero(ContextID, sizeof(cmsSEQ)); + if (Seq == NULL) return NULL; + + Seq -> ContextID = ContextID; + Seq -> seq = (cmsPSEQDESC*) _cmsCalloc(ContextID, n, sizeof(cmsPSEQDESC)); + Seq -> n = n; + + if (Seq -> seq == NULL) { + _cmsFree(ContextID, Seq); + return NULL; + } + + for (i=0; i < n; i++) { + Seq -> seq[i].Manufacturer = NULL; + Seq -> seq[i].Model = NULL; + Seq -> seq[i].Description = NULL; + } + + return Seq; +} + +void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq) +{ + cmsUInt32Number i; + + for (i=0; i < pseq ->n; i++) { + if (pseq ->seq[i].Manufacturer != NULL) cmsMLUfree(pseq ->seq[i].Manufacturer); + if (pseq ->seq[i].Model != NULL) cmsMLUfree(pseq ->seq[i].Model); + if (pseq ->seq[i].Description != NULL) cmsMLUfree(pseq ->seq[i].Description); + } + + if (pseq ->seq != NULL) _cmsFree(pseq ->ContextID, pseq ->seq); + _cmsFree(pseq -> ContextID, pseq); +} + +cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq) +{ + cmsSEQ *NewSeq; + cmsUInt32Number i; + + if (pseq == NULL) + return NULL; + + NewSeq = (cmsSEQ*) _cmsMalloc(pseq -> ContextID, sizeof(cmsSEQ)); + if (NewSeq == NULL) return NULL; + + + NewSeq -> seq = (cmsPSEQDESC*) _cmsCalloc(pseq ->ContextID, pseq ->n, sizeof(cmsPSEQDESC)); + if (NewSeq ->seq == NULL) goto Error; + + NewSeq -> ContextID = pseq ->ContextID; + NewSeq -> n = pseq ->n; + + for (i=0; i < pseq->n; i++) { + + memmove(&NewSeq ->seq[i].attributes, &pseq ->seq[i].attributes, sizeof(cmsUInt64Number)); + + NewSeq ->seq[i].deviceMfg = pseq ->seq[i].deviceMfg; + NewSeq ->seq[i].deviceModel = pseq ->seq[i].deviceModel; + memmove(&NewSeq ->seq[i].ProfileID, &pseq ->seq[i].ProfileID, sizeof(cmsProfileID)); + NewSeq ->seq[i].technology = pseq ->seq[i].technology; + + NewSeq ->seq[i].Manufacturer = cmsMLUdup(pseq ->seq[i].Manufacturer); + NewSeq ->seq[i].Model = cmsMLUdup(pseq ->seq[i].Model); + NewSeq ->seq[i].Description = cmsMLUdup(pseq ->seq[i].Description); + + } + + return NewSeq; + +Error: + + cmsFreeProfileSequenceDescription(NewSeq); + return NULL; +} + +// Dictionaries -------------------------------------------------------------------------------------------------------- + +// Dictionaries are just very simple linked lists + + +typedef struct _cmsDICT_struct { + cmsDICTentry* head; + cmsContext ContextID; +} _cmsDICT; + + +// Allocate an empty dictionary +cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID) +{ + _cmsDICT* dict = (_cmsDICT*) _cmsMallocZero(ContextID, sizeof(_cmsDICT)); + if (dict == NULL) return NULL; + + dict ->ContextID = ContextID; + return (cmsHANDLE) dict; + +} + +// Dispose resources +void CMSEXPORT cmsDictFree(cmsHANDLE hDict) +{ + _cmsDICT* dict = (_cmsDICT*) hDict; + cmsDICTentry *entry, *next; + + _cmsAssert(dict != NULL); + + // Walk the list freeing all nodes + entry = dict ->head; + while (entry != NULL) { + + if (entry ->DisplayName != NULL) cmsMLUfree(entry ->DisplayName); + if (entry ->DisplayValue != NULL) cmsMLUfree(entry ->DisplayValue); + if (entry ->Name != NULL) _cmsFree(dict ->ContextID, entry -> Name); + if (entry ->Value != NULL) _cmsFree(dict ->ContextID, entry -> Value); + + // Don't fall in the habitual trap... + next = entry ->Next; + _cmsFree(dict ->ContextID, entry); + + entry = next; + } + + _cmsFree(dict ->ContextID, dict); +} + + +// Duplicate a wide char string +static +wchar_t* DupWcs(cmsContext ContextID, const wchar_t* ptr) +{ + if (ptr == NULL) return NULL; + return (wchar_t*) _cmsDupMem(ContextID, ptr, (mywcslen(ptr) + 1) * sizeof(wchar_t)); +} + +// Add a new entry to the linked list +cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue) +{ + _cmsDICT* dict = (_cmsDICT*) hDict; + cmsDICTentry *entry; + + _cmsAssert(dict != NULL); + _cmsAssert(Name != NULL); + + entry = (cmsDICTentry*) _cmsMallocZero(dict ->ContextID, sizeof(cmsDICTentry)); + if (entry == NULL) return FALSE; + + entry ->DisplayName = cmsMLUdup(DisplayName); + entry ->DisplayValue = cmsMLUdup(DisplayValue); + entry ->Name = DupWcs(dict ->ContextID, Name); + entry ->Value = DupWcs(dict ->ContextID, Value); + + entry ->Next = dict ->head; + dict ->head = entry; + + return TRUE; +} + + +// Duplicates an existing dictionary +cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict) +{ + _cmsDICT* old_dict = (_cmsDICT*) hDict; + cmsHANDLE hNew; + cmsDICTentry *entry; + + _cmsAssert(old_dict != NULL); + + hNew = cmsDictAlloc(old_dict ->ContextID); + if (hNew == NULL) return NULL; + + // Walk the list freeing all nodes + entry = old_dict ->head; + while (entry != NULL) { + + if (!cmsDictAddEntry(hNew, entry ->Name, entry ->Value, entry ->DisplayName, entry ->DisplayValue)) { + + cmsDictFree(hNew); + return NULL; + } + + entry = entry -> Next; + } + + return hNew; +} + +// Get a pointer to the linked list +const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict) +{ + _cmsDICT* dict = (_cmsDICT*) hDict; + + if (dict == NULL) return NULL; + return dict ->head; +} + +// Helper For external languages +const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e) +{ + if (e == NULL) return NULL; + return e ->Next; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsopt.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsopt.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsopt.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsopt.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,2001 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +//---------------------------------------------------------------------------------- + +// Optimization for 8 bits, Shaper-CLUT (3 inputs only) +typedef struct { + + cmsContext ContextID; + + const cmsInterpParams* p; // Tetrahedrical interpolation parameters. This is a not-owned pointer. + + cmsUInt16Number rx[256], ry[256], rz[256]; + cmsUInt32Number X0[256], Y0[256], Z0[256]; // Precomputed nodes and offsets for 8-bit input data + + +} Prelin8Data; + + +// Generic optimization for 16 bits Shaper-CLUT-Shaper (any inputs) +typedef struct { + + cmsContext ContextID; + + // Number of channels + cmsUInt32Number nInputs; + cmsUInt32Number nOutputs; + + _cmsInterpFn16 EvalCurveIn16[MAX_INPUT_DIMENSIONS]; // The maximum number of input channels is known in advance + cmsInterpParams* ParamsCurveIn16[MAX_INPUT_DIMENSIONS]; + + _cmsInterpFn16 EvalCLUT; // The evaluator for 3D grid + const cmsInterpParams* CLUTparams; // (not-owned pointer) + + + _cmsInterpFn16* EvalCurveOut16; // Points to an array of curve evaluators in 16 bits (not-owned pointer) + cmsInterpParams** ParamsCurveOut16; // Points to an array of references to interpolation params (not-owned pointer) + + +} Prelin16Data; + + +// Optimization for matrix-shaper in 8 bits. Numbers are operated in n.14 signed, tables are stored in 1.14 fixed + +typedef cmsInt32Number cmsS1Fixed14Number; // Note that this may hold more than 16 bits! + +#define DOUBLE_TO_1FIXED14(x) ((cmsS1Fixed14Number) floor((x) * 16384.0 + 0.5)) + +typedef struct { + + cmsContext ContextID; + + cmsS1Fixed14Number Shaper1R[256]; // from 0..255 to 1.14 (0.0...1.0) + cmsS1Fixed14Number Shaper1G[256]; + cmsS1Fixed14Number Shaper1B[256]; + + cmsS1Fixed14Number Mat[3][3]; // n.14 to n.14 (needs a saturation after that) + cmsS1Fixed14Number Off[3]; + + cmsUInt16Number Shaper2R[16385]; // 1.14 to 0..255 + cmsUInt16Number Shaper2G[16385]; + cmsUInt16Number Shaper2B[16385]; + +} MatShaper8Data; + +// Curves, optimization is shared between 8 and 16 bits +typedef struct { + + cmsContext ContextID; + + cmsUInt32Number nCurves; // Number of curves + cmsUInt32Number nElements; // Elements in curves + cmsUInt16Number** Curves; // Points to a dynamically allocated array + +} Curves16Data; + + +// Simple optimizations ---------------------------------------------------------------------------------------------------------- + + +// Remove an element in linked chain +static +void _RemoveElement(cmsStage** head) +{ + cmsStage* mpe = *head; + cmsStage* next = mpe ->Next; + *head = next; + cmsStageFree(mpe); +} + +// Remove all identities in chain. Note that pt actually is a double pointer to the element that holds the pointer. +static +cmsBool _Remove1Op(cmsPipeline* Lut, cmsStageSignature UnaryOp) +{ + cmsStage** pt = &Lut ->Elements; + cmsBool AnyOpt = FALSE; + + while (*pt != NULL) { + + if ((*pt) ->Implements == UnaryOp) { + _RemoveElement(pt); + AnyOpt = TRUE; + } + else + pt = &((*pt) -> Next); + } + + return AnyOpt; +} + +// Same, but only if two adjacent elements are found +static +cmsBool _Remove2Op(cmsPipeline* Lut, cmsStageSignature Op1, cmsStageSignature Op2) +{ + cmsStage** pt1; + cmsStage** pt2; + cmsBool AnyOpt = FALSE; + + pt1 = &Lut ->Elements; + if (*pt1 == NULL) return AnyOpt; + + while (*pt1 != NULL) { + + pt2 = &((*pt1) -> Next); + if (*pt2 == NULL) return AnyOpt; + + if ((*pt1) ->Implements == Op1 && (*pt2) ->Implements == Op2) { + _RemoveElement(pt2); + _RemoveElement(pt1); + AnyOpt = TRUE; + } + else + pt1 = &((*pt1) -> Next); + } + + return AnyOpt; +} + + +static +cmsBool CloseEnoughFloat(cmsFloat64Number a, cmsFloat64Number b) +{ + return fabs(b - a) < 0.00001f; +} + +static +cmsBool isFloatMatrixIdentity(const cmsMAT3* a) +{ + cmsMAT3 Identity; + int i, j; + + _cmsMAT3identity(&Identity); + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + if (!CloseEnoughFloat(a->v[i].n[j], Identity.v[i].n[j])) return FALSE; + + return TRUE; +} +// if two adjacent matrices are found, multiply them. +static +cmsBool _MultiplyMatrix(cmsPipeline* Lut) +{ + cmsStage** pt1; + cmsStage** pt2; + cmsStage* chain; + cmsBool AnyOpt = FALSE; + + pt1 = &Lut->Elements; + if (*pt1 == NULL) return AnyOpt; + + while (*pt1 != NULL) { + + pt2 = &((*pt1)->Next); + if (*pt2 == NULL) return AnyOpt; + + if ((*pt1)->Implements == cmsSigMatrixElemType && (*pt2)->Implements == cmsSigMatrixElemType) { + + // Get both matrices + _cmsStageMatrixData* m1 = (_cmsStageMatrixData*) cmsStageData(*pt1); + _cmsStageMatrixData* m2 = (_cmsStageMatrixData*) cmsStageData(*pt2); + cmsMAT3 res; + + // Input offset and output offset should be zero to use this optimization + if (m1->Offset != NULL || m2 ->Offset != NULL || + cmsStageInputChannels(*pt1) != 3 || cmsStageOutputChannels(*pt1) != 3 || + cmsStageInputChannels(*pt2) != 3 || cmsStageOutputChannels(*pt2) != 3) + return FALSE; + + // Multiply both matrices to get the result + _cmsMAT3per(&res, (cmsMAT3*)m2->Double, (cmsMAT3*)m1->Double); + + // Get the next in chain after the matrices + chain = (*pt2)->Next; + + // Remove both matrices + _RemoveElement(pt2); + _RemoveElement(pt1); + + // Now what if the result is a plain identity? + if (!isFloatMatrixIdentity(&res)) { + + // We can not get rid of full matrix + cmsStage* Multmat = cmsStageAllocMatrix(Lut->ContextID, 3, 3, (const cmsFloat64Number*) &res, NULL); + if (Multmat == NULL) return FALSE; // Should never happen + + // Recover the chain + Multmat->Next = chain; + *pt1 = Multmat; + } + + AnyOpt = TRUE; + } + else + pt1 = &((*pt1)->Next); + } + + return AnyOpt; +} + + +// Preoptimize just gets rif of no-ops coming paired. Conversion from v2 to v4 followed +// by a v4 to v2 and vice-versa. The elements are then discarded. +static +cmsBool PreOptimize(cmsPipeline* Lut) +{ + cmsBool AnyOpt = FALSE, Opt; + + do { + + Opt = FALSE; + + // Remove all identities + Opt |= _Remove1Op(Lut, cmsSigIdentityElemType); + + // Remove XYZ2Lab followed by Lab2XYZ + Opt |= _Remove2Op(Lut, cmsSigXYZ2LabElemType, cmsSigLab2XYZElemType); + + // Remove Lab2XYZ followed by XYZ2Lab + Opt |= _Remove2Op(Lut, cmsSigLab2XYZElemType, cmsSigXYZ2LabElemType); + + // Remove V4 to V2 followed by V2 to V4 + Opt |= _Remove2Op(Lut, cmsSigLabV4toV2, cmsSigLabV2toV4); + + // Remove V2 to V4 followed by V4 to V2 + Opt |= _Remove2Op(Lut, cmsSigLabV2toV4, cmsSigLabV4toV2); + + // Remove float pcs Lab conversions + Opt |= _Remove2Op(Lut, cmsSigLab2FloatPCS, cmsSigFloatPCS2Lab); + + // Remove float pcs Lab conversions + Opt |= _Remove2Op(Lut, cmsSigXYZ2FloatPCS, cmsSigFloatPCS2XYZ); + + // Simplify matrix. + Opt |= _MultiplyMatrix(Lut); + + if (Opt) AnyOpt = TRUE; + + } while (Opt); + + return AnyOpt; +} + +static +void Eval16nop1D(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const struct _cms_interp_struc* p) +{ + Output[0] = Input[0]; + + cmsUNUSED_PARAMETER(p); +} + +static +void PrelinEval16(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const void* D) +{ + Prelin16Data* p16 = (Prelin16Data*) D; + cmsUInt16Number StageABC[MAX_INPUT_DIMENSIONS]; + cmsUInt16Number StageDEF[cmsMAXCHANNELS]; + cmsUInt32Number i; + + for (i=0; i < p16 ->nInputs; i++) { + + p16 ->EvalCurveIn16[i](&Input[i], &StageABC[i], p16 ->ParamsCurveIn16[i]); + } + + p16 ->EvalCLUT(StageABC, StageDEF, p16 ->CLUTparams); + + for (i=0; i < p16 ->nOutputs; i++) { + + p16 ->EvalCurveOut16[i](&StageDEF[i], &Output[i], p16 ->ParamsCurveOut16[i]); + } +} + + +static +void PrelinOpt16free(cmsContext ContextID, void* ptr) +{ + Prelin16Data* p16 = (Prelin16Data*) ptr; + + _cmsFree(ContextID, p16 ->EvalCurveOut16); + _cmsFree(ContextID, p16 ->ParamsCurveOut16); + + _cmsFree(ContextID, p16); +} + +static +void* Prelin16dup(cmsContext ContextID, const void* ptr) +{ + Prelin16Data* p16 = (Prelin16Data*) ptr; + Prelin16Data* Duped = (Prelin16Data*) _cmsDupMem(ContextID, p16, sizeof(Prelin16Data)); + + if (Duped == NULL) return NULL; + + Duped->EvalCurveOut16 = (_cmsInterpFn16*) _cmsDupMem(ContextID, p16->EvalCurveOut16, p16->nOutputs * sizeof(_cmsInterpFn16)); + Duped->ParamsCurveOut16 = (cmsInterpParams**)_cmsDupMem(ContextID, p16->ParamsCurveOut16, p16->nOutputs * sizeof(cmsInterpParams*)); + + return Duped; +} + + +static +Prelin16Data* PrelinOpt16alloc(cmsContext ContextID, + const cmsInterpParams* ColorMap, + cmsUInt32Number nInputs, cmsToneCurve** In, + cmsUInt32Number nOutputs, cmsToneCurve** Out ) +{ + cmsUInt32Number i; + Prelin16Data* p16 = (Prelin16Data*)_cmsMallocZero(ContextID, sizeof(Prelin16Data)); + if (p16 == NULL) return NULL; + + p16 ->nInputs = nInputs; + p16 ->nOutputs = nOutputs; + + + for (i=0; i < nInputs; i++) { + + if (In == NULL) { + p16 -> ParamsCurveIn16[i] = NULL; + p16 -> EvalCurveIn16[i] = Eval16nop1D; + + } + else { + p16 -> ParamsCurveIn16[i] = In[i] ->InterpParams; + p16 -> EvalCurveIn16[i] = p16 ->ParamsCurveIn16[i]->Interpolation.Lerp16; + } + } + + p16 ->CLUTparams = ColorMap; + p16 ->EvalCLUT = ColorMap ->Interpolation.Lerp16; + + + p16 -> EvalCurveOut16 = (_cmsInterpFn16*) _cmsCalloc(ContextID, nOutputs, sizeof(_cmsInterpFn16)); + if (p16->EvalCurveOut16 == NULL) + { + _cmsFree(ContextID, p16); + return NULL; + } + + p16 -> ParamsCurveOut16 = (cmsInterpParams**) _cmsCalloc(ContextID, nOutputs, sizeof(cmsInterpParams* )); + if (p16->ParamsCurveOut16 == NULL) + { + + _cmsFree(ContextID, p16->EvalCurveOut16); + _cmsFree(ContextID, p16); + return NULL; + } + + for (i=0; i < nOutputs; i++) { + + if (Out == NULL) { + p16 ->ParamsCurveOut16[i] = NULL; + p16 -> EvalCurveOut16[i] = Eval16nop1D; + } + else { + + p16 ->ParamsCurveOut16[i] = Out[i] ->InterpParams; + p16 -> EvalCurveOut16[i] = p16 ->ParamsCurveOut16[i]->Interpolation.Lerp16; + } + } + + return p16; +} + + + +// Resampling --------------------------------------------------------------------------------- + +#define PRELINEARIZATION_POINTS 4096 + +// Sampler implemented by another LUT. This is a clean way to precalculate the devicelink 3D CLUT for +// almost any transform. We use floating point precision and then convert from floating point to 16 bits. +static +cmsInt32Number XFormSampler16(CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + CMSREGISTER void* Cargo) +{ + cmsPipeline* Lut = (cmsPipeline*) Cargo; + cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS]; + cmsUInt32Number i; + + _cmsAssert(Lut -> InputChannels < cmsMAXCHANNELS); + _cmsAssert(Lut -> OutputChannels < cmsMAXCHANNELS); + + // From 16 bit to floating point + for (i=0; i < Lut ->InputChannels; i++) + InFloat[i] = (cmsFloat32Number) (In[i] / 65535.0); + + // Evaluate in floating point + cmsPipelineEvalFloat(InFloat, OutFloat, Lut); + + // Back to 16 bits representation + for (i=0; i < Lut ->OutputChannels; i++) + Out[i] = _cmsQuickSaturateWord(OutFloat[i] * 65535.0); + + // Always succeed + return TRUE; +} + +// Try to see if the curves of a given MPE are linear +static +cmsBool AllCurvesAreLinear(cmsStage* mpe) +{ + cmsToneCurve** Curves; + cmsUInt32Number i, n; + + Curves = _cmsStageGetPtrToCurveSet(mpe); + if (Curves == NULL) return FALSE; + + n = cmsStageOutputChannels(mpe); + + for (i=0; i < n; i++) { + if (!cmsIsToneCurveLinear(Curves[i])) return FALSE; + } + + return TRUE; +} + +// This function replaces a specific node placed in "At" by the "Value" numbers. Its purpose +// is to fix scum dot on broken profiles/transforms. Works on 1, 3 and 4 channels +static +cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[], + cmsUInt32Number nChannelsOut, cmsUInt32Number nChannelsIn) +{ + _cmsStageCLutData* Grid = (_cmsStageCLutData*) CLUT ->Data; + cmsInterpParams* p16 = Grid ->Params; + cmsFloat64Number px, py, pz, pw; + int x0, y0, z0, w0; + int i, index; + + if (CLUT -> Type != cmsSigCLutElemType) { + cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) Attempt to PatchLUT on non-lut stage"); + return FALSE; + } + + if (nChannelsIn == 4) { + + px = ((cmsFloat64Number) At[0] * (p16->Domain[0])) / 65535.0; + py = ((cmsFloat64Number) At[1] * (p16->Domain[1])) / 65535.0; + pz = ((cmsFloat64Number) At[2] * (p16->Domain[2])) / 65535.0; + pw = ((cmsFloat64Number) At[3] * (p16->Domain[3])) / 65535.0; + + x0 = (int) floor(px); + y0 = (int) floor(py); + z0 = (int) floor(pz); + w0 = (int) floor(pw); + + if (((px - x0) != 0) || + ((py - y0) != 0) || + ((pz - z0) != 0) || + ((pw - w0) != 0)) return FALSE; // Not on exact node + + index = (int) p16 -> opta[3] * x0 + + (int) p16 -> opta[2] * y0 + + (int) p16 -> opta[1] * z0 + + (int) p16 -> opta[0] * w0; + } + else + if (nChannelsIn == 3) { + + px = ((cmsFloat64Number) At[0] * (p16->Domain[0])) / 65535.0; + py = ((cmsFloat64Number) At[1] * (p16->Domain[1])) / 65535.0; + pz = ((cmsFloat64Number) At[2] * (p16->Domain[2])) / 65535.0; + + x0 = (int) floor(px); + y0 = (int) floor(py); + z0 = (int) floor(pz); + + if (((px - x0) != 0) || + ((py - y0) != 0) || + ((pz - z0) != 0)) return FALSE; // Not on exact node + + index = (int) p16 -> opta[2] * x0 + + (int) p16 -> opta[1] * y0 + + (int) p16 -> opta[0] * z0; + } + else + if (nChannelsIn == 1) { + + px = ((cmsFloat64Number) At[0] * (p16->Domain[0])) / 65535.0; + + x0 = (int) floor(px); + + if (((px - x0) != 0)) return FALSE; // Not on exact node + + index = (int) p16 -> opta[0] * x0; + } + else { + cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) %d Channels are not supported on PatchLUT", nChannelsIn); + return FALSE; + } + + for (i = 0; i < (int) nChannelsOut; i++) + Grid->Tab.T[index + i] = Value[i]; + + return TRUE; +} + +// Auxiliary, to see if two values are equal or very different +static +cmsBool WhitesAreEqual(cmsUInt32Number n, cmsUInt16Number White1[], cmsUInt16Number White2[] ) +{ + cmsUInt32Number i; + + for (i=0; i < n; i++) { + + if (abs(White1[i] - White2[i]) > 0xf000) return TRUE; // Values are so extremely different that the fixup should be avoided + if (White1[i] != White2[i]) return FALSE; + } + return TRUE; +} + + +// Locate the node for the white point and fix it to pure white in order to avoid scum dot. +static +cmsBool FixWhiteMisalignment(cmsPipeline* Lut, cmsColorSpaceSignature EntryColorSpace, cmsColorSpaceSignature ExitColorSpace) +{ + cmsUInt16Number *WhitePointIn, *WhitePointOut; + cmsUInt16Number WhiteIn[cmsMAXCHANNELS], WhiteOut[cmsMAXCHANNELS], ObtainedOut[cmsMAXCHANNELS]; + cmsUInt32Number i, nOuts, nIns; + cmsStage *PreLin = NULL, *CLUT = NULL, *PostLin = NULL; + + if (!_cmsEndPointsBySpace(EntryColorSpace, + &WhitePointIn, NULL, &nIns)) return FALSE; + + if (!_cmsEndPointsBySpace(ExitColorSpace, + &WhitePointOut, NULL, &nOuts)) return FALSE; + + // It needs to be fixed? + if (Lut ->InputChannels != nIns) return FALSE; + if (Lut ->OutputChannels != nOuts) return FALSE; + + cmsPipelineEval16(WhitePointIn, ObtainedOut, Lut); + + if (WhitesAreEqual(nOuts, WhitePointOut, ObtainedOut)) return TRUE; // whites already match + + // Check if the LUT comes as Prelin, CLUT or Postlin. We allow all combinations + if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, &PreLin, &CLUT, &PostLin)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 2, cmsSigCurveSetElemType, cmsSigCLutElemType, &PreLin, &CLUT)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 2, cmsSigCLutElemType, cmsSigCurveSetElemType, &CLUT, &PostLin)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 1, cmsSigCLutElemType, &CLUT)) + return FALSE; + + // We need to interpolate white points of both, pre and post curves + if (PreLin) { + + cmsToneCurve** Curves = _cmsStageGetPtrToCurveSet(PreLin); + + for (i=0; i < nIns; i++) { + WhiteIn[i] = cmsEvalToneCurve16(Curves[i], WhitePointIn[i]); + } + } + else { + for (i=0; i < nIns; i++) + WhiteIn[i] = WhitePointIn[i]; + } + + // If any post-linearization, we need to find how is represented white before the curve, do + // a reverse interpolation in this case. + if (PostLin) { + + cmsToneCurve** Curves = _cmsStageGetPtrToCurveSet(PostLin); + + for (i=0; i < nOuts; i++) { + + cmsToneCurve* InversePostLin = cmsReverseToneCurve(Curves[i]); + if (InversePostLin == NULL) { + WhiteOut[i] = WhitePointOut[i]; + + } else { + + WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]); + cmsFreeToneCurve(InversePostLin); + } + } + } + else { + for (i=0; i < nOuts; i++) + WhiteOut[i] = WhitePointOut[i]; + } + + // Ok, proceed with patching. May fail and we don't care if it fails + PatchLUT(CLUT, WhiteIn, WhiteOut, nOuts, nIns); + + return TRUE; +} + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +// This function creates simple LUT from complex ones. The generated LUT has an optional set of +// prelinearization curves, a CLUT of nGridPoints and optional postlinearization tables. +// These curves have to exist in the original LUT in order to be used in the simplified output. +// Caller may also use the flags to allow this feature. +// LUTS with all curves will be simplified to a single curve. Parametric curves are lost. +// This function should be used on 16-bits LUTS only, as floating point losses precision when simplified +// ----------------------------------------------------------------------------------------------------------------------------------------------- + +static +cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) +{ + cmsPipeline* Src = NULL; + cmsPipeline* Dest = NULL; + cmsStage* CLUT; + cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL; + cmsUInt32Number nGridPoints; + cmsColorSpaceSignature ColorSpace, OutputColorSpace; + cmsStage *NewPreLin = NULL; + cmsStage *NewPostLin = NULL; + _cmsStageCLutData* DataCLUT; + cmsToneCurve** DataSetIn; + cmsToneCurve** DataSetOut; + Prelin16Data* p16; + + // This is a lossy optimization! does not apply in floating-point cases + if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE; + + ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat)); + OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat)); + + // Color space must be specified + if (ColorSpace == (cmsColorSpaceSignature)0 || + OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE; + + nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags); + + // For empty LUTs, 2 points are enough + if (cmsPipelineStageCount(*Lut) == 0) + nGridPoints = 2; + + Src = *Lut; + + // Allocate an empty LUT + Dest = cmsPipelineAlloc(Src ->ContextID, Src ->InputChannels, Src ->OutputChannels); + if (!Dest) return FALSE; + + // Prelinearization tables are kept unless indicated by flags + if (*dwFlags & cmsFLAGS_CLUT_PRE_LINEARIZATION) { + + // Get a pointer to the prelinearization element + cmsStage* PreLin = cmsPipelineGetPtrToFirstStage(Src); + + // Check if suitable + if (PreLin && PreLin ->Type == cmsSigCurveSetElemType) { + + // Maybe this is a linear tram, so we can avoid the whole stuff + if (!AllCurvesAreLinear(PreLin)) { + + // All seems ok, proceed. + NewPreLin = cmsStageDup(PreLin); + if(!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, NewPreLin)) + goto Error; + + // Remove prelinearization. Since we have duplicated the curve + // in destination LUT, the sampling should be applied after this stage. + cmsPipelineUnlinkStage(Src, cmsAT_BEGIN, &KeepPreLin); + } + } + } + + // Allocate the CLUT + CLUT = cmsStageAllocCLut16bit(Src ->ContextID, nGridPoints, Src ->InputChannels, Src->OutputChannels, NULL); + if (CLUT == NULL) goto Error; + + // Add the CLUT to the destination LUT + if (!cmsPipelineInsertStage(Dest, cmsAT_END, CLUT)) { + goto Error; + } + + // Postlinearization tables are kept unless indicated by flags + if (*dwFlags & cmsFLAGS_CLUT_POST_LINEARIZATION) { + + // Get a pointer to the postlinearization if present + cmsStage* PostLin = cmsPipelineGetPtrToLastStage(Src); + + // Check if suitable + if (PostLin && cmsStageType(PostLin) == cmsSigCurveSetElemType) { + + // Maybe this is a linear tram, so we can avoid the whole stuff + if (!AllCurvesAreLinear(PostLin)) { + + // All seems ok, proceed. + NewPostLin = cmsStageDup(PostLin); + if (!cmsPipelineInsertStage(Dest, cmsAT_END, NewPostLin)) + goto Error; + + // In destination LUT, the sampling should be applied after this stage. + cmsPipelineUnlinkStage(Src, cmsAT_END, &KeepPostLin); + } + } + } + + // Now its time to do the sampling. We have to ignore pre/post linearization + // The source LUT without pre/post curves is passed as parameter. + if (!cmsStageSampleCLut16bit(CLUT, XFormSampler16, (void*) Src, 0)) { +Error: + // Ops, something went wrong, Restore stages + if (KeepPreLin != NULL) { + if (!cmsPipelineInsertStage(Src, cmsAT_BEGIN, KeepPreLin)) { + _cmsAssert(0); // This never happens + } + } + if (KeepPostLin != NULL) { + if (!cmsPipelineInsertStage(Src, cmsAT_END, KeepPostLin)) { + _cmsAssert(0); // This never happens + } + } + cmsPipelineFree(Dest); + return FALSE; + } + + // Done. + + if (KeepPreLin != NULL) cmsStageFree(KeepPreLin); + if (KeepPostLin != NULL) cmsStageFree(KeepPostLin); + cmsPipelineFree(Src); + + DataCLUT = (_cmsStageCLutData*) CLUT ->Data; + + if (NewPreLin == NULL) DataSetIn = NULL; + else DataSetIn = ((_cmsStageToneCurvesData*) NewPreLin ->Data) ->TheCurves; + + if (NewPostLin == NULL) DataSetOut = NULL; + else DataSetOut = ((_cmsStageToneCurvesData*) NewPostLin ->Data) ->TheCurves; + + + if (DataSetIn == NULL && DataSetOut == NULL) { + + _cmsPipelineSetOptimizationParameters(Dest, (_cmsPipelineEval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL); + } + else { + + p16 = PrelinOpt16alloc(Dest ->ContextID, + DataCLUT ->Params, + Dest ->InputChannels, + DataSetIn, + Dest ->OutputChannels, + DataSetOut); + + _cmsPipelineSetOptimizationParameters(Dest, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup); + } + + + // Don't fix white on absolute colorimetric + if (Intent == INTENT_ABSOLUTE_COLORIMETRIC) + *dwFlags |= cmsFLAGS_NOWHITEONWHITEFIXUP; + + if (!(*dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) { + + FixWhiteMisalignment(Dest, ColorSpace, OutputColorSpace); + } + + *Lut = Dest; + return TRUE; + + cmsUNUSED_PARAMETER(Intent); +} + + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +// Fixes the gamma balancing of transform. This is described in my paper "Prelinearization Stages on +// Color-Management Application-Specific Integrated Circuits (ASICs)" presented at NIP24. It only works +// for RGB transforms. See the paper for more details +// ----------------------------------------------------------------------------------------------------------------------------------------------- + + +// Normalize endpoints by slope limiting max and min. This assures endpoints as well. +// Descending curves are handled as well. +static +void SlopeLimiting(cmsToneCurve* g) +{ + int BeginVal, EndVal; + int AtBegin = (int) floor((cmsFloat64Number) g ->nEntries * 0.02 + 0.5); // Cutoff at 2% + int AtEnd = (int) g ->nEntries - AtBegin - 1; // And 98% + cmsFloat64Number Val, Slope, beta; + int i; + + if (cmsIsToneCurveDescending(g)) { + BeginVal = 0xffff; EndVal = 0; + } + else { + BeginVal = 0; EndVal = 0xffff; + } + + // Compute slope and offset for begin of curve + Val = g ->Table16[AtBegin]; + Slope = (Val - BeginVal) / AtBegin; + beta = Val - Slope * AtBegin; + + for (i=0; i < AtBegin; i++) + g ->Table16[i] = _cmsQuickSaturateWord(i * Slope + beta); + + // Compute slope and offset for the end + Val = g ->Table16[AtEnd]; + Slope = (EndVal - Val) / AtBegin; // AtBegin holds the X interval, which is same in both cases + beta = Val - Slope * AtEnd; + + for (i = AtEnd; i < (int) g ->nEntries; i++) + g ->Table16[i] = _cmsQuickSaturateWord(i * Slope + beta); +} + + +// Precomputes tables for 8-bit on input devicelink. +static +Prelin8Data* PrelinOpt8alloc(cmsContext ContextID, const cmsInterpParams* p, cmsToneCurve* G[3]) +{ + int i; + cmsUInt16Number Input[3]; + cmsS15Fixed16Number v1, v2, v3; + Prelin8Data* p8; + + p8 = (Prelin8Data*)_cmsMallocZero(ContextID, sizeof(Prelin8Data)); + if (p8 == NULL) return NULL; + + // Since this only works for 8 bit input, values comes always as x * 257, + // we can safely take msb byte (x << 8 + x) + + for (i=0; i < 256; i++) { + + if (G != NULL) { + + // Get 16-bit representation + Input[0] = cmsEvalToneCurve16(G[0], FROM_8_TO_16(i)); + Input[1] = cmsEvalToneCurve16(G[1], FROM_8_TO_16(i)); + Input[2] = cmsEvalToneCurve16(G[2], FROM_8_TO_16(i)); + } + else { + Input[0] = FROM_8_TO_16(i); + Input[1] = FROM_8_TO_16(i); + Input[2] = FROM_8_TO_16(i); + } + + + // Move to 0..1.0 in fixed domain + v1 = _cmsToFixedDomain((int) (Input[0] * p -> Domain[0])); + v2 = _cmsToFixedDomain((int) (Input[1] * p -> Domain[1])); + v3 = _cmsToFixedDomain((int) (Input[2] * p -> Domain[2])); + + // Store the precalculated table of nodes + p8 ->X0[i] = (p->opta[2] * FIXED_TO_INT(v1)); + p8 ->Y0[i] = (p->opta[1] * FIXED_TO_INT(v2)); + p8 ->Z0[i] = (p->opta[0] * FIXED_TO_INT(v3)); + + // Store the precalculated table of offsets + p8 ->rx[i] = (cmsUInt16Number) FIXED_REST_TO_INT(v1); + p8 ->ry[i] = (cmsUInt16Number) FIXED_REST_TO_INT(v2); + p8 ->rz[i] = (cmsUInt16Number) FIXED_REST_TO_INT(v3); + } + + p8 ->ContextID = ContextID; + p8 ->p = p; + + return p8; +} + +static +void Prelin8free(cmsContext ContextID, void* ptr) +{ + _cmsFree(ContextID, ptr); +} + +static +void* Prelin8dup(cmsContext ContextID, const void* ptr) +{ + return _cmsDupMem(ContextID, ptr, sizeof(Prelin8Data)); +} + + + +// A optimized interpolation for 8-bit input. +#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan]) +static CMS_NO_SANITIZE +void PrelinEval8(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const void* D) +{ + + cmsUInt8Number r, g, b; + cmsS15Fixed16Number rx, ry, rz; + cmsS15Fixed16Number c0, c1, c2, c3, Rest; + int OutChan; + CMSREGISTER cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1; + Prelin8Data* p8 = (Prelin8Data*) D; + CMSREGISTER const cmsInterpParams* p = p8 ->p; + int TotalOut = (int) p -> nOutputs; + const cmsUInt16Number* LutTable = (const cmsUInt16Number*) p->Table; + + r = (cmsUInt8Number) (Input[0] >> 8); + g = (cmsUInt8Number) (Input[1] >> 8); + b = (cmsUInt8Number) (Input[2] >> 8); + + X0 = (cmsS15Fixed16Number) p8->X0[r]; + Y0 = (cmsS15Fixed16Number) p8->Y0[g]; + Z0 = (cmsS15Fixed16Number) p8->Z0[b]; + + rx = p8 ->rx[r]; + ry = p8 ->ry[g]; + rz = p8 ->rz[b]; + + X1 = X0 + (cmsS15Fixed16Number)((rx == 0) ? 0 : p ->opta[2]); + Y1 = Y0 + (cmsS15Fixed16Number)((ry == 0) ? 0 : p ->opta[1]); + Z1 = Z0 + (cmsS15Fixed16Number)((rz == 0) ? 0 : p ->opta[0]); + + + // These are the 6 Tetrahedral + for (OutChan=0; OutChan < TotalOut; OutChan++) { + + c0 = DENS(X0, Y0, Z0); + + if (rx >= ry && ry >= rz) + { + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0); + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + } + else + if (rx >= rz && rz >= ry) + { + c1 = DENS(X1, Y0, Z0) - c0; + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0); + } + else + if (rz >= rx && rx >= ry) + { + c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1); + c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + } + else + if (ry >= rx && rx >= rz) + { + c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0); + } + else + if (ry >= rz && rz >= rx) + { + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z0) - c0; + c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0); + } + else + if (rz >= ry && ry >= rx) + { + c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1); + c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1); + c3 = DENS(X0, Y0, Z1) - c0; + } + else { + c1 = c2 = c3 = 0; + } + + Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; + Output[OutChan] = (cmsUInt16Number) (c0 + ((Rest + (Rest >> 16)) >> 16)); + + } +} + +#undef DENS + + +// Curves that contain wide empty areas are not optimizeable +static +cmsBool IsDegenerated(const cmsToneCurve* g) +{ + cmsUInt32Number i, Zeros = 0, Poles = 0; + cmsUInt32Number nEntries = g ->nEntries; + + for (i=0; i < nEntries; i++) { + + if (g ->Table16[i] == 0x0000) Zeros++; + if (g ->Table16[i] == 0xffff) Poles++; + } + + if (Zeros == 1 && Poles == 1) return FALSE; // For linear tables + if (Zeros > (nEntries / 20)) return TRUE; // Degenerated, many zeros + if (Poles > (nEntries / 20)) return TRUE; // Degenerated, many poles + + return FALSE; +} + +// -------------------------------------------------------------------------------------------------------------- +// We need xput over here + +static +cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) +{ + cmsPipeline* OriginalLut; + cmsUInt32Number nGridPoints; + cmsToneCurve *Trans[cmsMAXCHANNELS], *TransReverse[cmsMAXCHANNELS]; + cmsUInt32Number t, i; + cmsFloat32Number v, In[cmsMAXCHANNELS], Out[cmsMAXCHANNELS]; + cmsBool lIsSuitable, lIsLinear; + cmsPipeline* OptimizedLUT = NULL, *LutPlusCurves = NULL; + cmsStage* OptimizedCLUTmpe; + cmsColorSpaceSignature ColorSpace, OutputColorSpace; + cmsStage* OptimizedPrelinMpe; + cmsToneCurve** OptimizedPrelinCurves; + _cmsStageCLutData* OptimizedPrelinCLUT; + + + // This is a lossy optimization! does not apply in floating-point cases + if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE; + + // Only on chunky RGB + if (T_COLORSPACE(*InputFormat) != PT_RGB) return FALSE; + if (T_PLANAR(*InputFormat)) return FALSE; + + if (T_COLORSPACE(*OutputFormat) != PT_RGB) return FALSE; + if (T_PLANAR(*OutputFormat)) return FALSE; + + // On 16 bits, user has to specify the feature + if (!_cmsFormatterIs8bit(*InputFormat)) { + if (!(*dwFlags & cmsFLAGS_CLUT_PRE_LINEARIZATION)) return FALSE; + } + + OriginalLut = *Lut; + + ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat)); + OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat)); + + // Color space must be specified + if (ColorSpace == (cmsColorSpaceSignature)0 || + OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE; + + nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags); + + // Empty gamma containers + memset(Trans, 0, sizeof(Trans)); + memset(TransReverse, 0, sizeof(TransReverse)); + + // If the last stage of the original lut are curves, and those curves are + // degenerated, it is likely the transform is squeezing and clipping + // the output from previous CLUT. We cannot optimize this case + { + cmsStage* last = cmsPipelineGetPtrToLastStage(OriginalLut); + + if (last == NULL) goto Error; + if (cmsStageType(last) == cmsSigCurveSetElemType) { + + _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*)cmsStageData(last); + for (i = 0; i < Data->nCurves; i++) { + if (IsDegenerated(Data->TheCurves[i])) + goto Error; + } + } + } + + for (t = 0; t < OriginalLut ->InputChannels; t++) { + Trans[t] = cmsBuildTabulatedToneCurve16(OriginalLut ->ContextID, PRELINEARIZATION_POINTS, NULL); + if (Trans[t] == NULL) goto Error; + } + + // Populate the curves + for (i=0; i < PRELINEARIZATION_POINTS; i++) { + + v = (cmsFloat32Number) ((cmsFloat64Number) i / (PRELINEARIZATION_POINTS - 1)); + + // Feed input with a gray ramp + for (t=0; t < OriginalLut ->InputChannels; t++) + In[t] = v; + + // Evaluate the gray value + cmsPipelineEvalFloat(In, Out, OriginalLut); + + // Store result in curve + for (t=0; t < OriginalLut ->InputChannels; t++) + Trans[t] ->Table16[i] = _cmsQuickSaturateWord(Out[t] * 65535.0); + } + + // Slope-limit the obtained curves + for (t = 0; t < OriginalLut ->InputChannels; t++) + SlopeLimiting(Trans[t]); + + // Check for validity + lIsSuitable = TRUE; + lIsLinear = TRUE; + for (t=0; (lIsSuitable && (t < OriginalLut ->InputChannels)); t++) { + + // Exclude if already linear + if (!cmsIsToneCurveLinear(Trans[t])) + lIsLinear = FALSE; + + // Exclude if non-monotonic + if (!cmsIsToneCurveMonotonic(Trans[t])) + lIsSuitable = FALSE; + + if (IsDegenerated(Trans[t])) + lIsSuitable = FALSE; + } + + // If it is not suitable, just quit + if (!lIsSuitable) goto Error; + + // Invert curves if possible + for (t = 0; t < OriginalLut ->InputChannels; t++) { + TransReverse[t] = cmsReverseToneCurveEx(PRELINEARIZATION_POINTS, Trans[t]); + if (TransReverse[t] == NULL) goto Error; + } + + // Now inset the reversed curves at the begin of transform + LutPlusCurves = cmsPipelineDup(OriginalLut); + if (LutPlusCurves == NULL) goto Error; + + if (!cmsPipelineInsertStage(LutPlusCurves, cmsAT_BEGIN, cmsStageAllocToneCurves(OriginalLut ->ContextID, OriginalLut ->InputChannels, TransReverse))) + goto Error; + + // Create the result LUT + OptimizedLUT = cmsPipelineAlloc(OriginalLut ->ContextID, OriginalLut ->InputChannels, OriginalLut ->OutputChannels); + if (OptimizedLUT == NULL) goto Error; + + OptimizedPrelinMpe = cmsStageAllocToneCurves(OriginalLut ->ContextID, OriginalLut ->InputChannels, Trans); + + // Create and insert the curves at the beginning + if (!cmsPipelineInsertStage(OptimizedLUT, cmsAT_BEGIN, OptimizedPrelinMpe)) + goto Error; + + // Allocate the CLUT for result + OptimizedCLUTmpe = cmsStageAllocCLut16bit(OriginalLut ->ContextID, nGridPoints, OriginalLut ->InputChannels, OriginalLut ->OutputChannels, NULL); + + // Add the CLUT to the destination LUT + if (!cmsPipelineInsertStage(OptimizedLUT, cmsAT_END, OptimizedCLUTmpe)) + goto Error; + + // Resample the LUT + if (!cmsStageSampleCLut16bit(OptimizedCLUTmpe, XFormSampler16, (void*) LutPlusCurves, 0)) goto Error; + + // Free resources + for (t = 0; t < OriginalLut ->InputChannels; t++) { + + if (Trans[t]) cmsFreeToneCurve(Trans[t]); + if (TransReverse[t]) cmsFreeToneCurve(TransReverse[t]); + } + + cmsPipelineFree(LutPlusCurves); + + + OptimizedPrelinCurves = _cmsStageGetPtrToCurveSet(OptimizedPrelinMpe); + OptimizedPrelinCLUT = (_cmsStageCLutData*) OptimizedCLUTmpe ->Data; + + // Set the evaluator if 8-bit + if (_cmsFormatterIs8bit(*InputFormat)) { + + Prelin8Data* p8 = PrelinOpt8alloc(OptimizedLUT ->ContextID, + OptimizedPrelinCLUT ->Params, + OptimizedPrelinCurves); + if (p8 == NULL) return FALSE; + + _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval8, (void*) p8, Prelin8free, Prelin8dup); + + } + else + { + Prelin16Data* p16 = PrelinOpt16alloc(OptimizedLUT ->ContextID, + OptimizedPrelinCLUT ->Params, + 3, OptimizedPrelinCurves, 3, NULL); + if (p16 == NULL) return FALSE; + + _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup); + + } + + // Don't fix white on absolute colorimetric + if (Intent == INTENT_ABSOLUTE_COLORIMETRIC) + *dwFlags |= cmsFLAGS_NOWHITEONWHITEFIXUP; + + if (!(*dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) { + + if (!FixWhiteMisalignment(OptimizedLUT, ColorSpace, OutputColorSpace)) { + + return FALSE; + } + } + + // And return the obtained LUT + + cmsPipelineFree(OriginalLut); + *Lut = OptimizedLUT; + return TRUE; + +Error: + + for (t = 0; t < OriginalLut ->InputChannels; t++) { + + if (Trans[t]) cmsFreeToneCurve(Trans[t]); + if (TransReverse[t]) cmsFreeToneCurve(TransReverse[t]); + } + + if (LutPlusCurves != NULL) cmsPipelineFree(LutPlusCurves); + if (OptimizedLUT != NULL) cmsPipelineFree(OptimizedLUT); + + return FALSE; + + cmsUNUSED_PARAMETER(Intent); + cmsUNUSED_PARAMETER(lIsLinear); +} + + +// Curves optimizer ------------------------------------------------------------------------------------------------------------------ + +static +void CurvesFree(cmsContext ContextID, void* ptr) +{ + Curves16Data* Data = (Curves16Data*) ptr; + cmsUInt32Number i; + + for (i=0; i < Data -> nCurves; i++) { + + _cmsFree(ContextID, Data ->Curves[i]); + } + + _cmsFree(ContextID, Data ->Curves); + _cmsFree(ContextID, ptr); +} + +static +void* CurvesDup(cmsContext ContextID, const void* ptr) +{ + Curves16Data* Data = (Curves16Data*)_cmsDupMem(ContextID, ptr, sizeof(Curves16Data)); + cmsUInt32Number i; + + if (Data == NULL) return NULL; + + Data->Curves = (cmsUInt16Number**) _cmsDupMem(ContextID, Data->Curves, Data->nCurves * sizeof(cmsUInt16Number*)); + + for (i=0; i < Data -> nCurves; i++) { + Data->Curves[i] = (cmsUInt16Number*) _cmsDupMem(ContextID, Data->Curves[i], Data->nElements * sizeof(cmsUInt16Number)); + } + + return (void*) Data; +} + +// Precomputes tables for 8-bit on input devicelink. +static +Curves16Data* CurvesAlloc(cmsContext ContextID, cmsUInt32Number nCurves, cmsUInt32Number nElements, cmsToneCurve** G) +{ + cmsUInt32Number i, j; + Curves16Data* c16; + + c16 = (Curves16Data*)_cmsMallocZero(ContextID, sizeof(Curves16Data)); + if (c16 == NULL) return NULL; + + c16 ->nCurves = nCurves; + c16 ->nElements = nElements; + + c16->Curves = (cmsUInt16Number**) _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*)); + if (c16->Curves == NULL) { + _cmsFree(ContextID, c16); + return NULL; + } + + for (i=0; i < nCurves; i++) { + + c16->Curves[i] = (cmsUInt16Number*) _cmsCalloc(ContextID, nElements, sizeof(cmsUInt16Number)); + + if (c16->Curves[i] == NULL) { + + for (j=0; j < i; j++) { + _cmsFree(ContextID, c16->Curves[j]); + } + _cmsFree(ContextID, c16->Curves); + _cmsFree(ContextID, c16); + return NULL; + } + + if (nElements == 256U) { + + for (j=0; j < nElements; j++) { + + c16 ->Curves[i][j] = cmsEvalToneCurve16(G[i], FROM_8_TO_16(j)); + } + } + else { + + for (j=0; j < nElements; j++) { + c16 ->Curves[i][j] = cmsEvalToneCurve16(G[i], (cmsUInt16Number) j); + } + } + } + + return c16; +} + +static +void FastEvaluateCurves8(CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + CMSREGISTER const void* D) +{ + Curves16Data* Data = (Curves16Data*) D; + int x; + cmsUInt32Number i; + + for (i=0; i < Data ->nCurves; i++) { + + x = (In[i] >> 8); + Out[i] = Data -> Curves[i][x]; + } +} + + +static +void FastEvaluateCurves16(CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + CMSREGISTER const void* D) +{ + Curves16Data* Data = (Curves16Data*) D; + cmsUInt32Number i; + + for (i=0; i < Data ->nCurves; i++) { + Out[i] = Data -> Curves[i][In[i]]; + } +} + + +static +void FastIdentity16(CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + CMSREGISTER const void* D) +{ + cmsPipeline* Lut = (cmsPipeline*) D; + cmsUInt32Number i; + + for (i=0; i < Lut ->InputChannels; i++) { + Out[i] = In[i]; + } +} + + +// If the target LUT holds only curves, the optimization procedure is to join all those +// curves together. That only works on curves and does not work on matrices. +static +cmsBool OptimizeByJoiningCurves(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) +{ + cmsToneCurve** GammaTables = NULL; + cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS]; + cmsUInt32Number i, j; + cmsPipeline* Src = *Lut; + cmsPipeline* Dest = NULL; + cmsStage* mpe; + cmsStage* ObtainedCurves = NULL; + + + // This is a lossy optimization! does not apply in floating-point cases + if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE; + + // Only curves in this LUT? + for (mpe = cmsPipelineGetPtrToFirstStage(Src); + mpe != NULL; + mpe = cmsStageNext(mpe)) { + if (cmsStageType(mpe) != cmsSigCurveSetElemType) return FALSE; + } + + // Allocate an empty LUT + Dest = cmsPipelineAlloc(Src ->ContextID, Src ->InputChannels, Src ->OutputChannels); + if (Dest == NULL) return FALSE; + + // Create target curves + GammaTables = (cmsToneCurve**) _cmsCalloc(Src ->ContextID, Src ->InputChannels, sizeof(cmsToneCurve*)); + if (GammaTables == NULL) goto Error; + + for (i=0; i < Src ->InputChannels; i++) { + GammaTables[i] = cmsBuildTabulatedToneCurve16(Src ->ContextID, PRELINEARIZATION_POINTS, NULL); + if (GammaTables[i] == NULL) goto Error; + } + + // Compute 16 bit result by using floating point + for (i=0; i < PRELINEARIZATION_POINTS; i++) { + + for (j=0; j < Src ->InputChannels; j++) + InFloat[j] = (cmsFloat32Number) ((cmsFloat64Number) i / (PRELINEARIZATION_POINTS - 1)); + + cmsPipelineEvalFloat(InFloat, OutFloat, Src); + + for (j=0; j < Src ->InputChannels; j++) + GammaTables[j] -> Table16[i] = _cmsQuickSaturateWord(OutFloat[j] * 65535.0); + } + + ObtainedCurves = cmsStageAllocToneCurves(Src ->ContextID, Src ->InputChannels, GammaTables); + if (ObtainedCurves == NULL) goto Error; + + for (i=0; i < Src ->InputChannels; i++) { + cmsFreeToneCurve(GammaTables[i]); + GammaTables[i] = NULL; + } + + if (GammaTables != NULL) { + _cmsFree(Src->ContextID, GammaTables); + GammaTables = NULL; + } + + // Maybe the curves are linear at the end + if (!AllCurvesAreLinear(ObtainedCurves)) { + _cmsStageToneCurvesData* Data; + + if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, ObtainedCurves)) + goto Error; + Data = (_cmsStageToneCurvesData*) cmsStageData(ObtainedCurves); + ObtainedCurves = NULL; + + // If the curves are to be applied in 8 bits, we can save memory + if (_cmsFormatterIs8bit(*InputFormat)) { + Curves16Data* c16 = CurvesAlloc(Dest ->ContextID, Data ->nCurves, 256, Data ->TheCurves); + + if (c16 == NULL) goto Error; + *dwFlags |= cmsFLAGS_NOCACHE; + _cmsPipelineSetOptimizationParameters(Dest, FastEvaluateCurves8, c16, CurvesFree, CurvesDup); + + } + else { + Curves16Data* c16 = CurvesAlloc(Dest ->ContextID, Data ->nCurves, 65536, Data ->TheCurves); + + if (c16 == NULL) goto Error; + *dwFlags |= cmsFLAGS_NOCACHE; + _cmsPipelineSetOptimizationParameters(Dest, FastEvaluateCurves16, c16, CurvesFree, CurvesDup); + } + } + else { + + // LUT optimizes to nothing. Set the identity LUT + cmsStageFree(ObtainedCurves); + ObtainedCurves = NULL; + + if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageAllocIdentity(Dest ->ContextID, Src ->InputChannels))) + goto Error; + + *dwFlags |= cmsFLAGS_NOCACHE; + _cmsPipelineSetOptimizationParameters(Dest, FastIdentity16, (void*) Dest, NULL, NULL); + } + + // We are done. + cmsPipelineFree(Src); + *Lut = Dest; + return TRUE; + +Error: + + if (ObtainedCurves != NULL) cmsStageFree(ObtainedCurves); + if (GammaTables != NULL) { + for (i=0; i < Src ->InputChannels; i++) { + if (GammaTables[i] != NULL) cmsFreeToneCurve(GammaTables[i]); + } + + _cmsFree(Src ->ContextID, GammaTables); + } + + if (Dest != NULL) cmsPipelineFree(Dest); + return FALSE; + + cmsUNUSED_PARAMETER(Intent); + cmsUNUSED_PARAMETER(InputFormat); + cmsUNUSED_PARAMETER(OutputFormat); + cmsUNUSED_PARAMETER(dwFlags); +} + +// ------------------------------------------------------------------------------------------------------------------------------------- +// LUT is Shaper - Matrix - Matrix - Shaper, which is very frequent when combining two matrix-shaper profiles + + +static +void FreeMatShaper(cmsContext ContextID, void* Data) +{ + if (Data != NULL) _cmsFree(ContextID, Data); +} + +static +void* DupMatShaper(cmsContext ContextID, const void* Data) +{ + return _cmsDupMem(ContextID, Data, sizeof(MatShaper8Data)); +} + + +// A fast matrix-shaper evaluator for 8 bits. This is a bit tricky since I'm using 1.14 signed fixed point +// to accomplish some performance. Actually it takes 256x3 16 bits tables and 16385 x 3 tables of 8 bits, +// in total about 50K, and the performance boost is huge! +static CMS_NO_SANITIZE +void MatShaperEval16(CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + CMSREGISTER const void* D) +{ + MatShaper8Data* p = (MatShaper8Data*) D; + cmsS1Fixed14Number l1, l2, l3, r, g, b; + cmsUInt32Number ri, gi, bi; + + // In this case (and only in this case!) we can use this simplification since + // In[] is assured to come from a 8 bit number. (a << 8 | a) + ri = In[0] & 0xFFU; + gi = In[1] & 0xFFU; + bi = In[2] & 0xFFU; + + // Across first shaper, which also converts to 1.14 fixed point + r = p->Shaper1R[ri]; + g = p->Shaper1G[gi]; + b = p->Shaper1B[bi]; + + // Evaluate the matrix in 1.14 fixed point + l1 = (p->Mat[0][0] * r + p->Mat[0][1] * g + p->Mat[0][2] * b + p->Off[0] + 0x2000) >> 14; + l2 = (p->Mat[1][0] * r + p->Mat[1][1] * g + p->Mat[1][2] * b + p->Off[1] + 0x2000) >> 14; + l3 = (p->Mat[2][0] * r + p->Mat[2][1] * g + p->Mat[2][2] * b + p->Off[2] + 0x2000) >> 14; + + // Now we have to clip to 0..1.0 range + ri = (l1 < 0) ? 0 : ((l1 > 16384) ? 16384U : (cmsUInt32Number) l1); + gi = (l2 < 0) ? 0 : ((l2 > 16384) ? 16384U : (cmsUInt32Number) l2); + bi = (l3 < 0) ? 0 : ((l3 > 16384) ? 16384U : (cmsUInt32Number) l3); + + // And across second shaper, + Out[0] = p->Shaper2R[ri]; + Out[1] = p->Shaper2G[gi]; + Out[2] = p->Shaper2B[bi]; + +} + +// This table converts from 8 bits to 1.14 after applying the curve +static +void FillFirstShaper(cmsS1Fixed14Number* Table, cmsToneCurve* Curve) +{ + int i; + cmsFloat32Number R, y; + + for (i=0; i < 256; i++) { + + R = (cmsFloat32Number) (i / 255.0); + y = cmsEvalToneCurveFloat(Curve, R); + + if (y < 131072.0) + Table[i] = DOUBLE_TO_1FIXED14(y); + else + Table[i] = 0x7fffffff; + } +} + +// This table converts form 1.14 (being 0x4000 the last entry) to 8 bits after applying the curve +static +void FillSecondShaper(cmsUInt16Number* Table, cmsToneCurve* Curve, cmsBool Is8BitsOutput) +{ + int i; + cmsFloat32Number R, Val; + + for (i=0; i < 16385; i++) { + + R = (cmsFloat32Number) (i / 16384.0); + Val = cmsEvalToneCurveFloat(Curve, R); // Val comes 0..1.0 + + if (Val < 0) + Val = 0; + + if (Val > 1.0) + Val = 1.0; + + if (Is8BitsOutput) { + + // If 8 bits output, we can optimize further by computing the / 257 part. + // first we compute the resulting byte and then we store the byte times + // 257. This quantization allows to round very quick by doing a >> 8, but + // since the low byte is always equal to msb, we can do a & 0xff and this works! + cmsUInt16Number w = _cmsQuickSaturateWord(Val * 65535.0); + cmsUInt8Number b = FROM_16_TO_8(w); + + Table[i] = FROM_8_TO_16(b); + } + else Table[i] = _cmsQuickSaturateWord(Val * 65535.0); + } +} + +// Compute the matrix-shaper structure +static +cmsBool SetMatShaper(cmsPipeline* Dest, cmsToneCurve* Curve1[3], cmsMAT3* Mat, cmsVEC3* Off, cmsToneCurve* Curve2[3], cmsUInt32Number* OutputFormat) +{ + MatShaper8Data* p; + int i, j; + cmsBool Is8Bits = _cmsFormatterIs8bit(*OutputFormat); + + // Allocate a big chuck of memory to store precomputed tables + p = (MatShaper8Data*) _cmsMalloc(Dest ->ContextID, sizeof(MatShaper8Data)); + if (p == NULL) return FALSE; + + p -> ContextID = Dest -> ContextID; + + // Precompute tables + FillFirstShaper(p ->Shaper1R, Curve1[0]); + FillFirstShaper(p ->Shaper1G, Curve1[1]); + FillFirstShaper(p ->Shaper1B, Curve1[2]); + + FillSecondShaper(p ->Shaper2R, Curve2[0], Is8Bits); + FillSecondShaper(p ->Shaper2G, Curve2[1], Is8Bits); + FillSecondShaper(p ->Shaper2B, Curve2[2], Is8Bits); + + // Convert matrix to nFixed14. Note that those values may take more than 16 bits + for (i=0; i < 3; i++) { + for (j=0; j < 3; j++) { + p ->Mat[i][j] = DOUBLE_TO_1FIXED14(Mat->v[i].n[j]); + } + } + + for (i=0; i < 3; i++) { + + if (Off == NULL) { + p ->Off[i] = 0; + } + else { + p ->Off[i] = DOUBLE_TO_1FIXED14(Off->n[i]); + } + } + + // Mark as optimized for faster formatter + if (Is8Bits) + *OutputFormat |= OPTIMIZED_SH(1); + + // Fill function pointers + _cmsPipelineSetOptimizationParameters(Dest, MatShaperEval16, (void*) p, FreeMatShaper, DupMatShaper); + return TRUE; +} + +// 8 bits on input allows matrix-shaper boot up to 25 Mpixels per second on RGB. That's fast! +static +cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) +{ + cmsStage* Curve1, *Curve2; + cmsStage* Matrix1, *Matrix2; + cmsMAT3 res; + cmsBool IdentityMat; + cmsPipeline* Dest, *Src; + cmsFloat64Number* Offset; + + // Only works on RGB to RGB + if (T_CHANNELS(*InputFormat) != 3 || T_CHANNELS(*OutputFormat) != 3) return FALSE; + + // Only works on 8 bit input + if (!_cmsFormatterIs8bit(*InputFormat)) return FALSE; + + // Seems suitable, proceed + Src = *Lut; + + // Check for: + // + // shaper-matrix-matrix-shaper + // shaper-matrix-shaper + // + // Both of those constructs are possible (first because abs. colorimetric). + // additionally, In the first case, the input matrix offset should be zero. + + IdentityMat = FALSE; + if (cmsPipelineCheckAndRetreiveStages(Src, 4, + cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, + &Curve1, &Matrix1, &Matrix2, &Curve2)) { + + // Get both matrices + _cmsStageMatrixData* Data1 = (_cmsStageMatrixData*)cmsStageData(Matrix1); + _cmsStageMatrixData* Data2 = (_cmsStageMatrixData*)cmsStageData(Matrix2); + + // Only RGB to RGB + if (Matrix1->InputChannels != 3 || Matrix1->OutputChannels != 3 || + Matrix2->InputChannels != 3 || Matrix2->OutputChannels != 3) return FALSE; + + // Input offset should be zero + if (Data1->Offset != NULL) return FALSE; + + // Multiply both matrices to get the result + _cmsMAT3per(&res, (cmsMAT3*)Data2->Double, (cmsMAT3*)Data1->Double); + + // Only 2nd matrix has offset, or it is zero + Offset = Data2->Offset; + + // Now the result is in res + Data2 -> Offset. Maybe is a plain identity? + if (_cmsMAT3isIdentity(&res) && Offset == NULL) { + + // We can get rid of full matrix + IdentityMat = TRUE; + } + + } + else { + + if (cmsPipelineCheckAndRetreiveStages(Src, 3, + cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, + &Curve1, &Matrix1, &Curve2)) { + + _cmsStageMatrixData* Data = (_cmsStageMatrixData*)cmsStageData(Matrix1); + + // Copy the matrix to our result + memcpy(&res, Data->Double, sizeof(res)); + + // Preserve the Odffset (may be NULL as a zero offset) + Offset = Data->Offset; + + if (_cmsMAT3isIdentity(&res) && Offset == NULL) { + + // We can get rid of full matrix + IdentityMat = TRUE; + } + } + else + return FALSE; // Not optimizeable this time + + } + + // Allocate an empty LUT + Dest = cmsPipelineAlloc(Src ->ContextID, Src ->InputChannels, Src ->OutputChannels); + if (!Dest) return FALSE; + + // Assamble the new LUT + if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageDup(Curve1))) + goto Error; + + if (!IdentityMat) { + + if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageAllocMatrix(Dest->ContextID, 3, 3, (const cmsFloat64Number*)&res, Offset))) + goto Error; + } + + if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageDup(Curve2))) + goto Error; + + // If identity on matrix, we can further optimize the curves, so call the join curves routine + if (IdentityMat) { + + OptimizeByJoiningCurves(&Dest, Intent, InputFormat, OutputFormat, dwFlags); + } + else { + _cmsStageToneCurvesData* mpeC1 = (_cmsStageToneCurvesData*) cmsStageData(Curve1); + _cmsStageToneCurvesData* mpeC2 = (_cmsStageToneCurvesData*) cmsStageData(Curve2); + + // In this particular optimization, cache does not help as it takes more time to deal with + // the cache that with the pixel handling + *dwFlags |= cmsFLAGS_NOCACHE; + + // Setup the optimizarion routines + SetMatShaper(Dest, mpeC1 ->TheCurves, &res, (cmsVEC3*) Offset, mpeC2->TheCurves, OutputFormat); + } + + cmsPipelineFree(Src); + *Lut = Dest; + return TRUE; +Error: + // Leave Src unchanged + cmsPipelineFree(Dest); + return FALSE; +} + + +// ------------------------------------------------------------------------------------------------------------------------------------- +// Optimization plug-ins + +// List of optimizations +typedef struct _cmsOptimizationCollection_st { + + _cmsOPToptimizeFn OptimizePtr; + + struct _cmsOptimizationCollection_st *Next; + +} _cmsOptimizationCollection; + + +// The built-in list. We currently implement 4 types of optimizations. Joining of curves, matrix-shaper, linearization and resampling +static _cmsOptimizationCollection DefaultOptimization[] = { + + { OptimizeByJoiningCurves, &DefaultOptimization[1] }, + { OptimizeMatrixShaper, &DefaultOptimization[2] }, + { OptimizeByComputingLinearization, &DefaultOptimization[3] }, + { OptimizeByResampling, NULL } +}; + +// The linked list head +_cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginOptimizationList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsOptimizationPluginChunkType newHead = { NULL }; + _cmsOptimizationCollection* entry; + _cmsOptimizationCollection* Anterior = NULL; + _cmsOptimizationPluginChunkType* head = (_cmsOptimizationPluginChunkType*) src->chunks[OptimizationPlugin]; + + _cmsAssert(ctx != NULL); + _cmsAssert(head != NULL); + + // Walk the list copying all nodes + for (entry = head->OptimizationCollection; + entry != NULL; + entry = entry ->Next) { + + _cmsOptimizationCollection *newEntry = ( _cmsOptimizationCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsOptimizationCollection)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.OptimizationCollection == NULL) + newHead.OptimizationCollection = newEntry; + } + + ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsOptimizationPluginChunkType)); +} + +void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Copy all linked list + DupPluginOptimizationList(ctx, src); + } + else { + static _cmsOptimizationPluginChunkType OptimizationPluginChunkType = { NULL }; + ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx ->MemPool, &OptimizationPluginChunkType, sizeof(_cmsOptimizationPluginChunkType)); + } +} + + +// Register new ways to optimize +cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + cmsPluginOptimization* Plugin = (cmsPluginOptimization*) Data; + _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin); + _cmsOptimizationCollection* fl; + + if (Data == NULL) { + + ctx->OptimizationCollection = NULL; + return TRUE; + } + + // Optimizer callback is required + if (Plugin ->OptimizePtr == NULL) return FALSE; + + fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsOptimizationCollection)); + if (fl == NULL) return FALSE; + + // Copy the parameters + fl ->OptimizePtr = Plugin ->OptimizePtr; + + // Keep linked list + fl ->Next = ctx->OptimizationCollection; + + // Set the head + ctx ->OptimizationCollection = fl; + + // All is ok + return TRUE; +} + +// The entry point for LUT optimization +cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID, + cmsPipeline** PtrLut, + cmsUInt32Number Intent, + cmsUInt32Number* InputFormat, + cmsUInt32Number* OutputFormat, + cmsUInt32Number* dwFlags) +{ + _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin); + _cmsOptimizationCollection* Opts; + cmsBool AnySuccess = FALSE; + cmsStage* mpe; + + // A CLUT is being asked, so force this specific optimization + if (*dwFlags & cmsFLAGS_FORCE_CLUT) { + + PreOptimize(*PtrLut); + return OptimizeByResampling(PtrLut, Intent, InputFormat, OutputFormat, dwFlags); + } + + // Anything to optimize? + if ((*PtrLut) ->Elements == NULL) { + _cmsPipelineSetOptimizationParameters(*PtrLut, FastIdentity16, (void*) *PtrLut, NULL, NULL); + return TRUE; + } + + // Named color pipelines cannot be optimized + for (mpe = cmsPipelineGetPtrToFirstStage(*PtrLut); + mpe != NULL; + mpe = cmsStageNext(mpe)) { + if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE; + } + + // Try to get rid of identities and trivial conversions. + AnySuccess = PreOptimize(*PtrLut); + + // After removal do we end with an identity? + if ((*PtrLut) ->Elements == NULL) { + _cmsPipelineSetOptimizationParameters(*PtrLut, FastIdentity16, (void*) *PtrLut, NULL, NULL); + return TRUE; + } + + // Do not optimize, keep all precision + if (*dwFlags & cmsFLAGS_NOOPTIMIZE) + return FALSE; + + // Try plug-in optimizations + for (Opts = ctx->OptimizationCollection; + Opts != NULL; + Opts = Opts ->Next) { + + // If one schema succeeded, we are done + if (Opts ->OptimizePtr(PtrLut, Intent, InputFormat, OutputFormat, dwFlags)) { + + return TRUE; // Optimized! + } + } + + // Try built-in optimizations + for (Opts = DefaultOptimization; + Opts != NULL; + Opts = Opts ->Next) { + + if (Opts ->OptimizePtr(PtrLut, Intent, InputFormat, OutputFormat, dwFlags)) { + + return TRUE; + } + } + + // Only simple optimizations succeeded + return AnySuccess; +} + + + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmspack.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmspack.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmspack.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmspack.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,3902 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// This module handles all formats supported by lcms. There are two flavors, 16 bits and +// floating point. Floating point is supported only in a subset, those formats holding +// cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component +// as special case) + +// --------------------------------------------------------------------------- + + +// This macro return words stored as big endian +#define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8)) + +// These macros handles reversing (negative) +#define REVERSE_FLAVOR_8(x) ((cmsUInt8Number) (0xff-(x))) +#define REVERSE_FLAVOR_16(x) ((cmsUInt16Number)(0xffff-(x))) + +// * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256 +cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x) +{ + int a = (x << 8 | x) >> 8; // * 257 / 256 + if ( a > 0xffff) return 0xffff; + return (cmsUInt16Number) a; +} + +// * 0xf00 / 0xffff = * 256 / 257 +cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x) +{ + return (cmsUInt16Number) (((x << 8) + 0x80) / 257); +} + + +typedef struct { + cmsUInt32Number Type; + cmsUInt32Number Mask; + cmsFormatter16 Frm; + +} cmsFormatters16; + +typedef struct { + cmsUInt32Number Type; + cmsUInt32Number Mask; + cmsFormatterFloat Frm; + +} cmsFormattersFloat; + + +#define ANYSPACE COLORSPACE_SH(31) +#define ANYCHANNELS CHANNELS_SH(15) +#define ANYEXTRA EXTRA_SH(7) +#define ANYPLANAR PLANAR_SH(1) +#define ANYENDIAN ENDIAN16_SH(1) +#define ANYSWAP DOSWAP_SH(1) +#define ANYSWAPFIRST SWAPFIRST_SH(1) +#define ANYFLAVOR FLAVOR_SH(1) +#define ANYPREMUL PREMUL_SH(1) + + +// Suppress waning about info never being used + +#ifdef _MSC_VER +#pragma warning(disable : 4100) +#endif + +// Unpacking routines (16 bits) ---------------------------------------------------------------------------------------- + + +// Does almost everything but is slow +static +cmsUInt8Number* UnrollChunkyBytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number Premul = T_PREMUL(info->InputFormat); + + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number v; + cmsUInt32Number i; + cmsUInt32Number alpha_factor = 1; + + if (ExtraFirst) { + + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[0])); + + accum += Extra; + } + else + { + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[nChan])); + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = FROM_8_TO_16(*accum); + v = Reverse ? REVERSE_FLAVOR_16(v) : v; + + if (Premul && alpha_factor > 0) + { + v = ((cmsUInt32Number)((cmsUInt32Number)v << 16) / alpha_factor); + if (v > 0xffff) v = 0xffff; + } + + wIn[index] = (cmsUInt16Number) v; + accum++; + } + + if (!ExtraFirst) { + accum += Extra; + } + + if (Extra == 0 && SwapFirst) { + cmsUInt16Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number)); + wIn[nChan-1] = tmp; + } + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); + +} + + +// Extra channels are just ignored because come in the next planes +static +cmsUInt8Number* UnrollPlanarBytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number i; + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Extra = T_EXTRA(info->InputFormat); + cmsUInt32Number Premul = T_PREMUL(info->InputFormat); + cmsUInt8Number* Init = accum; + cmsUInt32Number alpha_factor = 1; + + if (ExtraFirst) { + + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[0])); + + + accum += Extra * Stride; + } + else + { + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[(nChan) * Stride])); + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number v = FROM_8_TO_16(*accum); + + v = Reverse ? REVERSE_FLAVOR_16(v) : v; + + if (Premul && alpha_factor > 0) + { + v = ((cmsUInt32Number)((cmsUInt32Number)v << 16) / alpha_factor); + if (v > 0xffff) v = 0xffff; + } + + wIn[index] = (cmsUInt16Number) v; + accum += Stride; + } + + return (Init + 1); +} + + +// Special cases, provided for performance +static +cmsUInt8Number* Unroll4Bytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = FROM_8_TO_16(*accum); accum++; // C + wIn[1] = FROM_8_TO_16(*accum); accum++; // M + wIn[2] = FROM_8_TO_16(*accum); accum++; // Y + wIn[3] = FROM_8_TO_16(*accum); accum++; // K + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll4BytesReverse(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C + wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M + wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y + wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[3] = FROM_8_TO_16(*accum); accum++; // K + wIn[0] = FROM_8_TO_16(*accum); accum++; // C + wIn[1] = FROM_8_TO_16(*accum); accum++; // M + wIn[2] = FROM_8_TO_16(*accum); accum++; // Y + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// KYMC +static +cmsUInt8Number* Unroll4BytesSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[3] = FROM_8_TO_16(*accum); accum++; // K + wIn[2] = FROM_8_TO_16(*accum); accum++; // Y + wIn[1] = FROM_8_TO_16(*accum); accum++; // M + wIn[0] = FROM_8_TO_16(*accum); accum++; // C + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[2] = FROM_8_TO_16(*accum); accum++; // K + wIn[1] = FROM_8_TO_16(*accum); accum++; // Y + wIn[0] = FROM_8_TO_16(*accum); accum++; // M + wIn[3] = FROM_8_TO_16(*accum); accum++; // C + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3Bytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = FROM_8_TO_16(*accum); accum++; // R + wIn[1] = FROM_8_TO_16(*accum); accum++; // G + wIn[2] = FROM_8_TO_16(*accum); accum++; // B + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3BytesSkip1Swap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + accum++; // A + wIn[2] = FROM_8_TO_16(*accum); accum++; // B + wIn[1] = FROM_8_TO_16(*accum); accum++; // G + wIn[0] = FROM_8_TO_16(*accum); accum++; // R + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[2] = FROM_8_TO_16(*accum); accum++; // B + wIn[1] = FROM_8_TO_16(*accum); accum++; // G + wIn[0] = FROM_8_TO_16(*accum); accum++; // R + accum++; // A + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3BytesSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + accum++; // A + wIn[0] = FROM_8_TO_16(*accum); accum++; // R + wIn[1] = FROM_8_TO_16(*accum); accum++; // G + wIn[2] = FROM_8_TO_16(*accum); accum++; // B + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +// BRG +static +cmsUInt8Number* Unroll3BytesSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[2] = FROM_8_TO_16(*accum); accum++; // B + wIn[1] = FROM_8_TO_16(*accum); accum++; // G + wIn[0] = FROM_8_TO_16(*accum); accum++; // R + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* UnrollLabV2_8(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L + wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a + wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* UnrollALabV2_8(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + accum++; // A + wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L + wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a + wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* UnrollLabV2_16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L + wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a + wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// for duplex +static +cmsUInt8Number* Unroll2Bytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1 + wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2 + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + + + +// Monochrome duplicates L into RGB for null-transforms +static +cmsUInt8Number* Unroll1Byte(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Unroll1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L + accum += 1; + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll1ByteSkip2(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L + accum += 2; + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll1ByteReversed(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* UnrollAnyWords(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number i; + + if (ExtraFirst) { + accum += Extra * sizeof(cmsUInt16Number); + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + cmsUInt16Number v = *(cmsUInt16Number*) accum; + + if (SwapEndian) + v = CHANGE_ENDIAN(v); + + wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v; + + accum += sizeof(cmsUInt16Number); + } + + if (!ExtraFirst) { + accum += Extra * sizeof(cmsUInt16Number); + } + + if (Extra == 0 && SwapFirst) { + + cmsUInt16Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number)); + wIn[nChan-1] = tmp; + } + + return accum; + + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* UnrollAnyWordsPremul(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number i; + + cmsUInt16Number alpha = (ExtraFirst ? accum[0] : accum[nChan - 1]); + cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha)); + + if (ExtraFirst) { + accum += sizeof(cmsUInt16Number); + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number v = *(cmsUInt16Number*) accum; + + if (SwapEndian) + v = CHANGE_ENDIAN(v); + + if (alpha_factor > 0) { + + v = (v << 16) / alpha_factor; + if (v > 0xffff) v = 0xffff; + } + + wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v); + + accum += sizeof(cmsUInt16Number); + } + + if (!ExtraFirst) { + accum += sizeof(cmsUInt16Number); + } + + return accum; + + cmsUNUSED_PARAMETER(Stride); +} + + + +static +cmsUInt8Number* UnrollPlanarWords(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat); + cmsUInt32Number i; + cmsUInt8Number* Init = accum; + + if (DoSwap) { + accum += T_EXTRA(info -> InputFormat) * Stride; + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + cmsUInt16Number v = *(cmsUInt16Number*) accum; + + if (SwapEndian) + v = CHANGE_ENDIAN(v); + + wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v; + + accum += Stride; + } + + return (Init + sizeof(cmsUInt16Number)); +} + +static +cmsUInt8Number* UnrollPlanarWordsPremul(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat); + cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat); + cmsUInt32Number i; + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt8Number* Init = accum; + + cmsUInt16Number alpha = (ExtraFirst ? accum[0] : accum[(nChan - 1) * Stride]); + cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha)); + + if (ExtraFirst) { + accum += Stride; + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number v = (cmsUInt32Number) *(cmsUInt16Number*) accum; + + if (SwapEndian) + v = CHANGE_ENDIAN(v); + + if (alpha_factor > 0) { + + v = (v << 16) / alpha_factor; + if (v > 0xffff) v = 0xffff; + } + + wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v); + + accum += Stride; + } + + return (Init + sizeof(cmsUInt16Number)); +} + +static +cmsUInt8Number* Unroll4Words(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C + wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M + wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y + wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll4WordsReverse(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C + wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M + wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y + wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll4WordsSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K + wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C + wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M + wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// KYMC +static +cmsUInt8Number* Unroll4WordsSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K + wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y + wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M + wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll4WordsSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K + wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y + wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M + wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3Words(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R + wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G + wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3WordsSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R + wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G + wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3WordsSkip1Swap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + accum += 2; // A + wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R + wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G + wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll3WordsSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + accum += 2; // A + wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R + wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G + wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll1Word(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll1WordReversed(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll1WordSkip3(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; + + accum += 8; + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Unroll2Words(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1 + wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2 + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +// This is a conversion of Lab double to 16 bits +static +cmsUInt8Number* UnrollLabDoubleTo16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + if (T_PLANAR(info -> InputFormat)) { + + cmsCIELab Lab; + cmsUInt8Number* pos_L; + cmsUInt8Number* pos_a; + cmsUInt8Number* pos_b; + + pos_L = accum; + pos_a = accum + Stride; + pos_b = accum + Stride * 2; + + Lab.L = *(cmsFloat64Number*) pos_L; + Lab.a = *(cmsFloat64Number*) pos_a; + Lab.b = *(cmsFloat64Number*) pos_b; + + cmsFloat2LabEncoded(wIn, &Lab); + return accum + sizeof(cmsFloat64Number); + } + else { + + cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum); + accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number); + return accum; + } +} + + +// This is a conversion of Lab float to 16 bits +static +cmsUInt8Number* UnrollLabFloatTo16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsCIELab Lab; + + if (T_PLANAR(info -> InputFormat)) { + + cmsUInt8Number* pos_L; + cmsUInt8Number* pos_a; + cmsUInt8Number* pos_b; + + pos_L = accum; + pos_a = accum + Stride; + pos_b = accum + Stride * 2; + + Lab.L = *(cmsFloat32Number*)pos_L; + Lab.a = *(cmsFloat32Number*)pos_a; + Lab.b = *(cmsFloat32Number*)pos_b; + + cmsFloat2LabEncoded(wIn, &Lab); + return accum + sizeof(cmsFloat32Number); + } + else { + + Lab.L = ((cmsFloat32Number*) accum)[0]; + Lab.a = ((cmsFloat32Number*) accum)[1]; + Lab.b = ((cmsFloat32Number*) accum)[2]; + + cmsFloat2LabEncoded(wIn, &Lab); + accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number); + return accum; + } +} + +// This is a conversion of XYZ double to 16 bits +static +cmsUInt8Number* UnrollXYZDoubleTo16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + if (T_PLANAR(info -> InputFormat)) { + + cmsCIEXYZ XYZ; + cmsUInt8Number* pos_X; + cmsUInt8Number* pos_Y; + cmsUInt8Number* pos_Z; + + pos_X = accum; + pos_Y = accum + Stride; + pos_Z = accum + Stride * 2; + + XYZ.X = *(cmsFloat64Number*)pos_X; + XYZ.Y = *(cmsFloat64Number*)pos_Y; + XYZ.Z = *(cmsFloat64Number*)pos_Z; + + cmsFloat2XYZEncoded(wIn, &XYZ); + + return accum + sizeof(cmsFloat64Number); + + } + + else { + cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum); + accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number); + + return accum; + } +} + +// This is a conversion of XYZ float to 16 bits +static +cmsUInt8Number* UnrollXYZFloatTo16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + if (T_PLANAR(info -> InputFormat)) { + + cmsCIEXYZ XYZ; + cmsUInt8Number* pos_X; + cmsUInt8Number* pos_Y; + cmsUInt8Number* pos_Z; + + pos_X = accum; + pos_Y = accum + Stride; + pos_Z = accum + Stride * 2; + + XYZ.X = *(cmsFloat32Number*)pos_X; + XYZ.Y = *(cmsFloat32Number*)pos_Y; + XYZ.Z = *(cmsFloat32Number*)pos_Z; + + cmsFloat2XYZEncoded(wIn, &XYZ); + + return accum + sizeof(cmsFloat32Number); + + } + + else { + cmsFloat32Number* Pt = (cmsFloat32Number*) accum; + cmsCIEXYZ XYZ; + + XYZ.X = Pt[0]; + XYZ.Y = Pt[1]; + XYZ.Z = Pt[2]; + cmsFloat2XYZEncoded(wIn, &XYZ); + + accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number); + + return accum; + } +} + +// Check if space is marked as ink +cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type) +{ + switch (T_COLORSPACE(Type)) { + + case PT_CMY: + case PT_CMYK: + case PT_MCH5: + case PT_MCH6: + case PT_MCH7: + case PT_MCH8: + case PT_MCH9: + case PT_MCH10: + case PT_MCH11: + case PT_MCH12: + case PT_MCH13: + case PT_MCH14: + case PT_MCH15: return TRUE; + + default: return FALSE; + } +} + +// Return the size in bytes of a given formatter +static +cmsUInt32Number PixelSize(cmsUInt32Number Format) +{ + cmsUInt32Number fmt_bytes = T_BYTES(Format); + + // For double, the T_BYTES field is zero + if (fmt_bytes == 0) + return sizeof(cmsUInt64Number); + + // Otherwise, it is already correct for all formats + return fmt_bytes; +} + +// Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits +static +cmsUInt8Number* UnrollDoubleTo16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); + cmsFloat64Number v; + cmsUInt16Number vi; + cmsUInt32Number i, start = 0; + cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; + + + Stride /= PixelSize(info->InputFormat); + + if (ExtraFirst) + start = Extra; + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride]; + else + v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start]; + + vi = _cmsQuickSaturateWord(v * maximum); + + if (Reverse) + vi = REVERSE_FLAVOR_16(vi); + + wIn[index] = vi; + } + + + if (Extra == 0 && SwapFirst) { + cmsUInt16Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number)); + wIn[nChan-1] = tmp; + } + + if (T_PLANAR(info -> InputFormat)) + return accum + sizeof(cmsFloat64Number); + else + return accum + (nChan + Extra) * sizeof(cmsFloat64Number); +} + + + +static +cmsUInt8Number* UnrollFloatTo16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); + cmsFloat32Number v; + cmsUInt16Number vi; + cmsUInt32Number i, start = 0; + cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; + + Stride /= PixelSize(info->InputFormat); + + if (ExtraFirst) + start = Extra; + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride]; + else + v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start]; + + vi = _cmsQuickSaturateWord(v * maximum); + + if (Reverse) + vi = REVERSE_FLAVOR_16(vi); + + wIn[index] = vi; + } + + + if (Extra == 0 && SwapFirst) { + cmsUInt16Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number)); + wIn[nChan-1] = tmp; + } + + if (T_PLANAR(info -> InputFormat)) + return accum + sizeof(cmsFloat32Number); + else + return accum + (nChan + Extra) * sizeof(cmsFloat32Number); +} + + + + +// For 1 channel, we need to duplicate data (it comes in 0..1.0 range) +static +cmsUInt8Number* UnrollDouble1Chan(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsFloat64Number* Inks = (cmsFloat64Number*) accum; + + wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0); + + return accum + sizeof(cmsFloat64Number); + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +//------------------------------------------------------------------------------------------------------------------- + +// For anything going from cmsUInt8Number +static +cmsUInt8Number* Unroll8ToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info->InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat); + cmsUInt32Number Extra = T_EXTRA(info->InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info->InputFormat); + cmsFloat32Number v; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->InputFormat); + + if (ExtraFirst) + start = Extra; + + for (i = 0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = (cmsFloat32Number) ((cmsUInt8Number *)accum)[(i + start) * Stride]; + else + v = (cmsFloat32Number) ((cmsUInt8Number *)accum)[i + start]; + + v /= 255.0F; + + wIn[index] = Reverse ? 1 - v : v; + } + + + if (Extra == 0 && SwapFirst) { + cmsFloat32Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan - 1) * sizeof(cmsFloat32Number)); + wIn[nChan - 1] = tmp; + } + + if (T_PLANAR(info->InputFormat)) + return accum + sizeof(cmsUInt8Number); + else + return accum + (nChan + Extra) * sizeof(cmsUInt8Number); +} + + +// For anything going from cmsUInt16Number +static +cmsUInt8Number* Unroll16ToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info->InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat); + cmsUInt32Number Extra = T_EXTRA(info->InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info->InputFormat); + cmsFloat32Number v; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->InputFormat); + + if (ExtraFirst) + start = Extra; + + for (i = 0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = (cmsFloat32Number)((cmsUInt16Number*)accum)[(i + start) * Stride]; + else + v = (cmsFloat32Number)((cmsUInt16Number*)accum)[i + start]; + + v /= 65535.0F; + + wIn[index] = Reverse ? 1 - v : v; + } + + + if (Extra == 0 && SwapFirst) { + cmsFloat32Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan - 1) * sizeof(cmsFloat32Number)); + wIn[nChan - 1] = tmp; + } + + if (T_PLANAR(info->InputFormat)) + return accum + sizeof(cmsUInt16Number); + else + return accum + (nChan + Extra) * sizeof(cmsUInt16Number); +} + + +// For anything going from cmsFloat32Number +static +cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info->InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat); + cmsUInt32Number Extra = T_EXTRA(info->InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info->InputFormat); + cmsUInt32Number Premul = T_PREMUL(info->InputFormat); + cmsFloat32Number v; + cmsUInt32Number i, start = 0; + cmsFloat32Number maximum = IsInkSpace(info->InputFormat) ? 100.0F : 1.0F; + cmsFloat32Number alpha_factor = 1.0f; + cmsFloat32Number* ptr = (cmsFloat32Number*)accum; + + Stride /= PixelSize(info->InputFormat); + + if (Premul && Extra) + { + if (Planar) + alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan * Stride]) / maximum; + else + alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan]) / maximum; + } + + if (ExtraFirst) + start = Extra; + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = ptr[(i + start) * Stride]; + else + v = ptr[i + start]; + + if (Premul && alpha_factor > 0) + v /= alpha_factor; + + v /= maximum; + + wIn[index] = Reverse ? 1 - v : v; + } + + + if (Extra == 0 && SwapFirst) { + cmsFloat32Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number)); + wIn[nChan-1] = tmp; + } + + if (T_PLANAR(info -> InputFormat)) + return accum + sizeof(cmsFloat32Number); + else + return accum + (nChan + Extra) * sizeof(cmsFloat32Number); +} + +// For anything going from double + +static +cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info->InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat); + cmsUInt32Number Extra = T_EXTRA(info->InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info->InputFormat); + cmsUInt32Number Premul = T_PREMUL(info->InputFormat); + cmsFloat64Number v; + cmsUInt32Number i, start = 0; + cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0; + cmsFloat64Number alpha_factor = 1.0; + cmsFloat64Number* ptr = (cmsFloat64Number*)accum; + + Stride /= PixelSize(info->InputFormat); + + if (Premul && Extra) + { + if (Planar) + alpha_factor = (ExtraFirst ? ptr[0] : ptr[(nChan) * Stride]) / maximum; + else + alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan]) / maximum; + } + + if (ExtraFirst) + start = Extra; + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride]; + else + v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start]; + + + if (Premul && alpha_factor > 0) + v /= alpha_factor; + + v /= maximum; + + wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v); + } + + + if (Extra == 0 && SwapFirst) { + cmsFloat32Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number)); + wIn[nChan-1] = tmp; + } + + if (T_PLANAR(info -> InputFormat)) + return accum + sizeof(cmsFloat64Number); + else + return accum + (nChan + Extra) * sizeof(cmsFloat64Number); +} + + + +// From Lab double to cmsFloat32Number +static +cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + cmsFloat64Number* Pt = (cmsFloat64Number*) accum; + + if (T_PLANAR(info -> InputFormat)) { + + Stride /= PixelSize(info->InputFormat); + + wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 + wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1 + wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0); + + return accum + sizeof(cmsFloat64Number); + } + else { + + wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 + wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1 + wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0); + + accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat)); + return accum; + } +} + +// From Lab double to cmsFloat32Number +static +cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + cmsFloat32Number* Pt = (cmsFloat32Number*) accum; + + if (T_PLANAR(info -> InputFormat)) { + + Stride /= PixelSize(info->InputFormat); + + wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 + wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1 + wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0); + + return accum + sizeof(cmsFloat32Number); + } + else { + + wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 + wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1 + wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0); + + accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat)); + return accum; + } +} + +// 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF) +static +cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + cmsFloat64Number* Pt = (cmsFloat64Number*) accum; + + if (T_PLANAR(info -> InputFormat)) { + + Stride /= PixelSize(info->InputFormat); + + wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); + wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ); + wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ); + + return accum + sizeof(cmsFloat64Number); + } + else { + + wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); + wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ); + wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ); + + accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat)); + return accum; + } +} + +static +cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + cmsFloat32Number* Pt = (cmsFloat32Number*) accum; + + if (T_PLANAR(info -> InputFormat)) { + + Stride /= PixelSize(info->InputFormat); + + wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); + wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ); + wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ); + + return accum + sizeof(cmsFloat32Number); + } + else { + + wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); + wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ); + wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ); + + accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat)); + return accum; + } +} + + +cmsINLINE void lab4toFloat(cmsFloat32Number wIn[], cmsUInt16Number lab4[3]) +{ + cmsFloat32Number L = (cmsFloat32Number) lab4[0] / 655.35F; + cmsFloat32Number a = ((cmsFloat32Number) lab4[1] / 257.0F) - 128.0F; + cmsFloat32Number b = ((cmsFloat32Number) lab4[2] / 257.0F) - 128.0F; + + wIn[0] = (L / 100.0F); // from 0..100 to 0..1 + wIn[1] = ((a + 128.0F) / 255.0F); // form -128..+127 to 0..1 + wIn[2] = ((b + 128.0F) / 255.0F); + +} + +static +cmsUInt8Number* UnrollLabV2_8ToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + cmsUInt16Number lab4[3]; + + lab4[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L + lab4[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a + lab4[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b + + lab4toFloat(wIn, lab4); + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* UnrollALabV2_8ToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + cmsUInt16Number lab4[3]; + + accum++; // A + lab4[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L + lab4[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a + lab4[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b + + lab4toFloat(wIn, lab4); + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* UnrollLabV2_16ToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + cmsUInt16Number lab4[3]; + + lab4[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L + lab4[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a + lab4[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b + + lab4toFloat(wIn, lab4); + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +// Packing routines ----------------------------------------------------------------------------------------------------------- + + +// Generic chunky for byte +static +cmsUInt8Number* PackChunkyBytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Premul = T_PREMUL(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt8Number* swap1; + cmsUInt16Number v = 0; + cmsUInt32Number i; + cmsUInt32Number alpha_factor = 0; + + swap1 = output; + + if (ExtraFirst) { + + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[0])); + + output += Extra; + } + else + { + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[nChan])); + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = wOut[index]; + + if (Reverse) + v = REVERSE_FLAVOR_16(v); + + if (Premul) + { + v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16); + } + + *output++ = FROM_16_TO_8(v); + } + + if (!ExtraFirst) { + output += Extra; + } + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, nChan-1); + *swap1 = FROM_16_TO_8(v); + } + + return output; + + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* PackChunkyWords(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Premul = T_PREMUL(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt16Number* swap1; + cmsUInt16Number v = 0; + cmsUInt32Number i; + cmsUInt32Number alpha_factor = 0; + + swap1 = (cmsUInt16Number*) output; + + if (ExtraFirst) { + + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(*(cmsUInt16Number*) output); + + output += Extra * sizeof(cmsUInt16Number); + } + else + { + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*) output)[nChan]); + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = wOut[index]; + + if (SwapEndian) + v = CHANGE_ENDIAN(v); + + if (Reverse) + v = REVERSE_FLAVOR_16(v); + + if (Premul) + { + v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16); + } + + *(cmsUInt16Number*) output = v; + + output += sizeof(cmsUInt16Number); + } + + if (!ExtraFirst) { + output += Extra * sizeof(cmsUInt16Number); + } + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number)); + *swap1 = v; + } + + return output; + + cmsUNUSED_PARAMETER(Stride); +} + + + +static +cmsUInt8Number* PackPlanarBytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Premul = T_PREMUL(info->OutputFormat); + cmsUInt32Number i; + cmsUInt8Number* Init = output; + cmsUInt32Number alpha_factor = 0; + + + if (ExtraFirst) { + + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[0])); + + output += Extra * Stride; + } + else + { + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[nChan * Stride])); + } + + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + cmsUInt16Number v = wOut[index]; + + if (Reverse) + v = REVERSE_FLAVOR_16(v); + + if (Premul) + { + v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16); + } + + *(cmsUInt8Number*)output = FROM_16_TO_8(v); + + output += Stride; + } + + return (Init + 1); + + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* PackPlanarWords(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Premul = T_PREMUL(info->OutputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info->OutputFormat); + cmsUInt32Number i; + cmsUInt8Number* Init = output; + cmsUInt16Number v; + cmsUInt32Number alpha_factor = 0; + + if (ExtraFirst) { + + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*) output)[0]); + + output += Extra * Stride; + } + else + { + if (Premul && Extra) + alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*)output)[nChan * Stride]); + } + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = wOut[index]; + + if (SwapEndian) + v = CHANGE_ENDIAN(v); + + if (Reverse) + v = REVERSE_FLAVOR_16(v); + + if (Premul) + { + v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16); + } + + *(cmsUInt16Number*) output = v; + output += Stride; + } + + return (Init + sizeof(cmsUInt16Number)); +} + +// CMYKcm (unrolled for speed) + +static +cmsUInt8Number* Pack6Bytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[0]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[3]); + *output++ = FROM_16_TO_8(wOut[4]); + *output++ = FROM_16_TO_8(wOut[5]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// KCMYcm + +static +cmsUInt8Number* Pack6BytesSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[5]); + *output++ = FROM_16_TO_8(wOut[4]); + *output++ = FROM_16_TO_8(wOut[3]); + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[0]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// CMYKcm +static +cmsUInt8Number* Pack6Words(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + *(cmsUInt16Number*) output = wOut[3]; + output+= 2; + *(cmsUInt16Number*) output = wOut[4]; + output+= 2; + *(cmsUInt16Number*) output = wOut[5]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// KCMYcm +static +cmsUInt8Number* Pack6WordsSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[5]; + output+= 2; + *(cmsUInt16Number*) output = wOut[4]; + output+= 2; + *(cmsUInt16Number*) output = wOut[3]; + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack4Bytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[0]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[3]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack4BytesReverse(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0])); + *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1])); + *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2])); + *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3])); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[3]); + *output++ = FROM_16_TO_8(wOut[0]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[2]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// ABGR +static +cmsUInt8Number* Pack4BytesSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[3]); + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[0]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[0]); + *output++ = FROM_16_TO_8(wOut[3]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack4Words(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + *(cmsUInt16Number*) output = wOut[3]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack4WordsReverse(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]); + output+= 2; + *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]); + output+= 2; + *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]); + output+= 2; + *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]); + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// ABGR +static +cmsUInt8Number* Pack4WordsSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[3]; + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +// CMYK +static +cmsUInt8Number* Pack4WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]); + output+= 2; + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]); + output+= 2; + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]); + output+= 2; + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]); + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* PackLabV2_8(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0])); + *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1])); + *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2])); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* PackALabV2_8(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output++; + *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0])); + *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1])); + *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2])); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* PackLabV2_16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]); + output += 2; + *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]); + output += 2; + *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]); + output += 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3Bytes(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[0]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[2]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesOptimized(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = (wOut[0] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[2] & 0xFFU); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[0]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesSwapOptimized(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = (wOut[2] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[0] & 0xFFU); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack3Words(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3WordsSwap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]); + output+= 2; + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]); + output+= 2; + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]); + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesAndSkip1(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[0]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[2]); + output++; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesAndSkip1Optimized(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = (wOut[0] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[2] & 0xFFU); + output++; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output++; + *output++ = FROM_16_TO_8(wOut[0]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[2]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output++; + *output++ = (wOut[0] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[2] & 0xFFU); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output++; + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[0]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output++; + *output++ = (wOut[2] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[0] & 0xFFU); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[2]); + *output++ = FROM_16_TO_8(wOut[1]); + *output++ = FROM_16_TO_8(wOut[0]); + output++; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = (wOut[2] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[0] & 0xFFU); + output++; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3WordsAndSkip1(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack3WordsAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output+= 2; + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[2]; + output+= 2; + *(cmsUInt16Number*) output = wOut[1]; + output+= 2; + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + + +static +cmsUInt8Number* Pack1Byte(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[0]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack1ByteReversed(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0])); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *output++ = FROM_16_TO_8(wOut[0]); + output++; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack1ByteSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output++; + *output++ = FROM_16_TO_8(wOut[0]); + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack1Word(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack1WordReversed(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]); + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack1WordBigEndian(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]); + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +static +cmsUInt8Number* Pack1WordSkip1(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + *(cmsUInt16Number*) output = wOut[0]; + output+= 4; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* Pack1WordSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + output += 2; + *(cmsUInt16Number*) output = wOut[0]; + output+= 2; + + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + + +// Unencoded Float values -- don't try optimize speed +static +cmsUInt8Number* PackLabDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + + if (T_PLANAR(info -> OutputFormat)) { + + cmsCIELab Lab; + cmsFloat64Number* Out = (cmsFloat64Number*) output; + cmsLabEncoded2Float(&Lab, wOut); + + Out[0] = Lab.L; + Out[Stride] = Lab.a; + Out[Stride*2] = Lab.b; + + return output + sizeof(cmsFloat64Number); + } + else { + + cmsLabEncoded2Float((cmsCIELab*) output, wOut); + return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number)); + } +} + + +static +cmsUInt8Number* PackLabFloatFrom16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsCIELab Lab; + cmsLabEncoded2Float(&Lab, wOut); + + if (T_PLANAR(info -> OutputFormat)) { + + cmsFloat32Number* Out = (cmsFloat32Number*) output; + + Stride /= PixelSize(info->OutputFormat); + + Out[0] = (cmsFloat32Number)Lab.L; + Out[Stride] = (cmsFloat32Number)Lab.a; + Out[Stride*2] = (cmsFloat32Number)Lab.b; + + return output + sizeof(cmsFloat32Number); + } + else { + + ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L; + ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a; + ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b; + + return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number); + } +} + +static +cmsUInt8Number* PackXYZDoubleFrom16(CMSREGISTER _cmsTRANSFORM* Info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + if (T_PLANAR(Info -> OutputFormat)) { + + cmsCIEXYZ XYZ; + cmsFloat64Number* Out = (cmsFloat64Number*) output; + cmsXYZEncoded2Float(&XYZ, wOut); + + Stride /= PixelSize(Info->OutputFormat); + + Out[0] = XYZ.X; + Out[Stride] = XYZ.Y; + Out[Stride*2] = XYZ.Z; + + return output + sizeof(cmsFloat64Number); + + } + else { + + cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut); + + return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number)); + } +} + +static +cmsUInt8Number* PackXYZFloatFrom16(CMSREGISTER _cmsTRANSFORM* Info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + if (T_PLANAR(Info -> OutputFormat)) { + + cmsCIEXYZ XYZ; + cmsFloat32Number* Out = (cmsFloat32Number*) output; + cmsXYZEncoded2Float(&XYZ, wOut); + + Stride /= PixelSize(Info->OutputFormat); + + Out[0] = (cmsFloat32Number) XYZ.X; + Out[Stride] = (cmsFloat32Number) XYZ.Y; + Out[Stride*2] = (cmsFloat32Number) XYZ.Z; + + return output + sizeof(cmsFloat32Number); + + } + else { + + cmsCIEXYZ XYZ; + cmsFloat32Number* Out = (cmsFloat32Number*) output; + cmsXYZEncoded2Float(&XYZ, wOut); + + Out[0] = (cmsFloat32Number) XYZ.X; + Out[1] = (cmsFloat32Number) XYZ.Y; + Out[2] = (cmsFloat32Number) XYZ.Z; + + return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number)); + } +} + +static +cmsUInt8Number* PackDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info -> OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0; + cmsFloat64Number v = 0; + cmsFloat64Number* swap1 = (cmsFloat64Number*) output; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = (cmsFloat64Number) wOut[index] / maximum; + + if (Reverse) + v = maximum - v; + + if (Planar) + ((cmsFloat64Number*) output)[(i + start) * Stride]= v; + else + ((cmsFloat64Number*) output)[i + start] = v; + } + + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number)); + *swap1 = v; + } + + if (T_PLANAR(info -> OutputFormat)) + return output + sizeof(cmsFloat64Number); + else + return output + (nChan + Extra) * sizeof(cmsFloat64Number); + +} + + +static +cmsUInt8Number* PackFloatFrom16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0; + cmsFloat64Number v = 0; + cmsFloat32Number* swap1 = (cmsFloat32Number*)output; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i = 0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = (cmsFloat64Number)wOut[index] / maximum; + + if (Reverse) + v = maximum - v; + + if (Planar) + ((cmsFloat32Number*)output)[(i + start) * Stride] = (cmsFloat32Number)v; + else + ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v; + } + + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number)); + *swap1 = (cmsFloat32Number)v; + } + + if (T_PLANAR(info->OutputFormat)) + return output + sizeof(cmsFloat32Number); + else + return output + (nChan + Extra) * sizeof(cmsFloat32Number); +} + + + +// -------------------------------------------------------------------------------------------------------- + +static +cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info, + cmsFloat32Number wOut[], + cmsUInt8Number* output, + cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0; + cmsFloat32Number* swap1 = (cmsFloat32Number*)output; + cmsFloat64Number v = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i = 0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = wOut[index] * maximum; + + if (Reverse) + v = maximum - v; + + if (Planar) + ((cmsFloat32Number*)output)[(i + start)* Stride] = (cmsFloat32Number)v; + else + ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v; + } + + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number)); + *swap1 = (cmsFloat32Number)v; + } + + if (T_PLANAR(info->OutputFormat)) + return output + sizeof(cmsFloat32Number); + else + return output + (nChan + Extra) * sizeof(cmsFloat32Number); +} + +static +cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info, + cmsFloat32Number wOut[], + cmsUInt8Number* output, + cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0; + cmsFloat64Number v = 0; + cmsFloat64Number* swap1 = (cmsFloat64Number*)output; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i = 0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = wOut[index] * maximum; + + if (Reverse) + v = maximum - v; + + if (Planar) + ((cmsFloat64Number*)output)[(i + start) * Stride] = v; + else + ((cmsFloat64Number*)output)[i + start] = v; + } + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat64Number)); + *swap1 = v; + } + + + if (T_PLANAR(info->OutputFormat)) + return output + sizeof(cmsFloat64Number); + else + return output + (nChan + Extra) * sizeof(cmsFloat64Number); + +} + +static +cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info, + cmsFloat32Number wOut[], + cmsUInt8Number* output, + cmsUInt32Number Stride) +{ + cmsFloat32Number* Out = (cmsFloat32Number*) output; + + if (T_PLANAR(Info -> OutputFormat)) { + + Stride /= PixelSize(Info->OutputFormat); + + Out[0] = (cmsFloat32Number) (wOut[0] * 100.0); + Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0); + Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0); + + return output + sizeof(cmsFloat32Number); + } + else { + + Out[0] = (cmsFloat32Number) (wOut[0] * 100.0); + Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0); + Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0); + + return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number)); + } + +} + + +static +cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info, + cmsFloat32Number wOut[], + cmsUInt8Number* output, + cmsUInt32Number Stride) +{ + cmsFloat64Number* Out = (cmsFloat64Number*) output; + + if (T_PLANAR(Info -> OutputFormat)) { + + Stride /= PixelSize(Info->OutputFormat); + + Out[0] = (cmsFloat64Number) (wOut[0] * 100.0); + Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0); + Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0); + + return output + sizeof(cmsFloat64Number); + } + else { + + Out[0] = (cmsFloat64Number) (wOut[0] * 100.0); + Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0); + Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0); + + return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number)); + } + +} + + +// From 0..1 range to 0..MAX_ENCODEABLE_XYZ +static +cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info, + cmsFloat32Number wOut[], + cmsUInt8Number* output, + cmsUInt32Number Stride) +{ + cmsFloat32Number* Out = (cmsFloat32Number*) output; + + if (T_PLANAR(Info -> OutputFormat)) { + + Stride /= PixelSize(Info->OutputFormat); + + Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ); + Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ); + Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ); + + return output + sizeof(cmsFloat32Number); + } + else { + + Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ); + Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ); + Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ); + + return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number)); + } + +} + +// Same, but convert to double +static +cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info, + cmsFloat32Number wOut[], + cmsUInt8Number* output, + cmsUInt32Number Stride) +{ + cmsFloat64Number* Out = (cmsFloat64Number*) output; + + if (T_PLANAR(Info -> OutputFormat)) { + + Stride /= PixelSize(Info->OutputFormat); + + Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ); + Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ); + Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ); + + return output + sizeof(cmsFloat64Number); + } + else { + + Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ); + Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ); + Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ); + + return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number)); + } + +} + + +// ---------------------------------------------------------------------------------------------------------------- + +#ifndef CMS_NO_HALF_SUPPORT + +// Decodes an stream of half floats to wIn[] described by input format + +static +cmsUInt8Number* UnrollHalfTo16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); + cmsFloat32Number v; + cmsUInt32Number i, start = 0; + cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F; + + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] ); + else + v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ; + + if (Reverse) v = maximum - v; + + wIn[index] = _cmsQuickSaturateWord((cmsFloat64Number) v * maximum); + } + + + if (Extra == 0 && SwapFirst) { + cmsUInt16Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number)); + wIn[nChan-1] = tmp; + } + + if (T_PLANAR(info -> InputFormat)) + return accum + sizeof(cmsUInt16Number); + else + return accum + (nChan + Extra) * sizeof(cmsUInt16Number); +} + +// Decodes an stream of half floats to wIn[] described by input format + +static +cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info, + cmsFloat32Number wIn[], + cmsUInt8Number* accum, + cmsUInt32Number Stride) +{ + + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); + cmsFloat32Number v; + cmsUInt32Number i, start = 0; + cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F; + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i=0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + if (Planar) + v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] ); + else + v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ; + + v /= maximum; + + wIn[index] = Reverse ? 1 - v : v; + } + + + if (Extra == 0 && SwapFirst) { + cmsFloat32Number tmp = wIn[0]; + + memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number)); + wIn[nChan-1] = tmp; + } + + if (T_PLANAR(info -> InputFormat)) + return accum + sizeof(cmsUInt16Number); + else + return accum + (nChan + Extra) * sizeof(cmsUInt16Number); +} + + +static +cmsUInt8Number* PackHalfFrom16(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F; + cmsFloat32Number v = 0; + cmsUInt16Number* swap1 = (cmsUInt16Number*)output; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i = 0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = (cmsFloat32Number)wOut[index] / maximum; + + if (Reverse) + v = maximum - v; + + if (Planar) + ((cmsUInt16Number*)output)[(i + start) * Stride] = _cmsFloat2Half(v); + else + ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v); + } + + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number)); + *swap1 = _cmsFloat2Half(v); + } + + if (T_PLANAR(info->OutputFormat)) + return output + sizeof(cmsUInt16Number); + else + return output + (nChan + Extra) * sizeof(cmsUInt16Number); +} + + + +static +cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info, + cmsFloat32Number wOut[], + cmsUInt8Number* output, + cmsUInt32Number Stride) +{ + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F; + cmsUInt16Number* swap1 = (cmsUInt16Number*)output; + cmsFloat32Number v = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); + + if (ExtraFirst) + start = Extra; + + for (i = 0; i < nChan; i++) { + + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; + + v = wOut[index] * maximum; + + if (Reverse) + v = maximum - v; + + if (Planar) + ((cmsUInt16Number*)output)[(i + start)* Stride] = _cmsFloat2Half(v); + else + ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v); + } + + + if (Extra == 0 && SwapFirst) { + + memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number)); + *swap1 = (cmsUInt16Number)_cmsFloat2Half(v); + } + + if (T_PLANAR(info->OutputFormat)) + return output + sizeof(cmsUInt16Number); + else + return output + (nChan + Extra)* sizeof(cmsUInt16Number); +} + +#endif + +// ---------------------------------------------------------------------------------------------------------------- + + +static const cmsFormatters16 InputFormatters16[] = { + + // Type Mask Function + // ---------------------------- ------------------------------------ ---------------------------- + { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16}, + { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16}, + { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16}, + { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatTo16}, + { TYPE_GRAY_DBL, 0, UnrollDouble1Chan}, + { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR| + ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16}, + { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR| + ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16}, +#ifndef CMS_NO_HALF_SUPPORT + { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR| + ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16}, +#endif + + { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte}, + { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1}, + { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2}, + { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed}, + { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes}, + + { TYPE_LabV2_8, 0, UnrollLabV2_8 }, + { TYPE_ALabV2_8, 0, UnrollALabV2_8 }, + { TYPE_LabV2_16, 0, UnrollLabV2_16 }, + + { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes}, + { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap}, + { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap}, + { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst}, + + { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), + ANYSPACE, Unroll3BytesSkip1SwapSwapFirst}, + + { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes}, + { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse}, + { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst}, + { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap}, + { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst}, + + { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYPREMUL| + ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes}, + + { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYPREMUL| + ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes}, + + { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word}, + { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed}, + { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3}, + + { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words}, + { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words}, + { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words}, + + { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap}, + { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst}, + { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap}, + { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse}, + { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst}, + { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap}, + { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst}, + + + { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords}, + { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords}, + + { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE|PREMUL_SH(1), UnrollPlanarWordsPremul}, + { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE|PREMUL_SH(1), UnrollAnyWordsPremul} + +}; + + + +static const cmsFormattersFloat InputFormattersFloat[] = { + + // Type Mask Function + // ---------------------------- ------------------------------------ ---------------------------- + { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat}, + { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat}, + + { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat}, + { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat}, + + { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA| + ANYPREMUL|ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat}, + + { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA| + ANYCHANNELS|ANYSPACE|ANYPREMUL, UnrollDoublesToFloat}, + + { TYPE_LabV2_8, 0, UnrollLabV2_8ToFloat }, + { TYPE_ALabV2_8, 0, UnrollALabV2_8ToFloat }, + { TYPE_LabV2_16, 0, UnrollLabV2_16ToFloat }, + + { BYTES_SH(1), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA| + ANYCHANNELS|ANYSPACE, Unroll8ToFloat}, + + { BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA| + ANYCHANNELS|ANYSPACE, Unroll16ToFloat}, +#ifndef CMS_NO_HALF_SUPPORT + { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA| + ANYCHANNELS|ANYSPACE, UnrollHalfToFloat}, +#endif +}; + + +// Bit fields set to one in the mask are not compared +static +cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags) +{ + cmsUInt32Number i; + cmsFormatter fr; + + switch (dwFlags) { + + case CMS_PACK_FLAGS_16BITS: { + for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) { + const cmsFormatters16* f = InputFormatters16 + i; + + if ((dwInput & ~f ->Mask) == f ->Type) { + fr.Fmt16 = f ->Frm; + return fr; + } + } + } + break; + + case CMS_PACK_FLAGS_FLOAT: { + for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) { + const cmsFormattersFloat* f = InputFormattersFloat + i; + + if ((dwInput & ~f ->Mask) == f ->Type) { + fr.FmtFloat = f ->Frm; + return fr; + } + } + } + break; + + default:; + + } + + fr.Fmt16 = NULL; + return fr; +} + +static const cmsFormatters16 OutputFormatters16[] = { + // Type Mask Function + // ---------------------------- ------------------------------------ ---------------------------- + + { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16}, + { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16}, + + { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16}, + { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFrom16}, + + { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP| + ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16}, + { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP| + ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16}, +#ifndef CMS_NO_HALF_SUPPORT + { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP| + ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16}, +#endif + + { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte}, + { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1}, + { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst}, + + { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed}, + + { TYPE_LabV2_8, 0, PackLabV2_8 }, + { TYPE_ALabV2_8, 0, PackALabV2_8 }, + { TYPE_LabV2_16, 0, PackLabV2_16 }, + + { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized}, + { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized}, + { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1), + ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized}, + { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1), + ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized}, + { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), + ANYSPACE, Pack3BytesAndSkip1SwapOptimized}, + { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized}, + + + + { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes}, + { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1}, + { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst}, + { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), + ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst}, + { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap}, + { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap}, + { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes}, + { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse}, + { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst}, + { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap}, + { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst}, + { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes}, + { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap}, + + { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS| + ANYSPACE|ANYPREMUL, PackChunkyBytes}, + + { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA| + ANYCHANNELS|ANYSPACE|ANYPREMUL, PackPlanarBytes}, + + + { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word}, + { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1}, + { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst}, + { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed}, + { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian}, + { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words}, + { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap}, + { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian}, + { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1}, + { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap}, + { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst}, + + { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), + ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst}, + + { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words}, + { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse}, + { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap}, + { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian}, + + { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words}, + { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap}, + + { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN| + ANYEXTRA|ANYCHANNELS|ANYSPACE|ANYPREMUL, PackChunkyWords}, + { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA| + ANYCHANNELS|ANYSPACE|ANYPREMUL, PackPlanarWords} + +}; + + +static const cmsFormattersFloat OutputFormattersFloat[] = { + // Type Mask Function + // ---------------------------- --------------------------------------------------- ---------------------------- + { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat}, + { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat}, + + { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat}, + { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat}, + + { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR| + ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat }, + { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR| + ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat }, +#ifndef CMS_NO_HALF_SUPPORT + { FLOAT_SH(1)|BYTES_SH(2), + ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat }, +#endif + +}; + + +// Bit fields set to one in the mask are not compared +static +cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags) +{ + cmsUInt32Number i; + cmsFormatter fr; + + // Optimization is only a hint + dwInput &= ~OPTIMIZED_SH(1); + + switch (dwFlags) + { + + case CMS_PACK_FLAGS_16BITS: { + + for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) { + const cmsFormatters16* f = OutputFormatters16 + i; + + if ((dwInput & ~f ->Mask) == f ->Type) { + fr.Fmt16 = f ->Frm; + return fr; + } + } + } + break; + + case CMS_PACK_FLAGS_FLOAT: { + + for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) { + const cmsFormattersFloat* f = OutputFormattersFloat + i; + + if ((dwInput & ~f ->Mask) == f ->Type) { + fr.FmtFloat = f ->Frm; + return fr; + } + } + } + break; + + default:; + + } + + fr.Fmt16 = NULL; + return fr; +} + + +typedef struct _cms_formatters_factory_list { + + cmsFormatterFactory Factory; + struct _cms_formatters_factory_list *Next; + +} cmsFormattersFactoryList; + +_cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupFormatterFactoryList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsFormattersPluginChunkType newHead = { NULL }; + cmsFormattersFactoryList* entry; + cmsFormattersFactoryList* Anterior = NULL; + _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin]; + + _cmsAssert(head != NULL); + + // Walk the list copying all nodes + for (entry = head->FactoryList; + entry != NULL; + entry = entry ->Next) { + + cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.FactoryList == NULL) + newHead.FactoryList = newEntry; + } + + ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType)); +} + +// The interpolation plug-in memory chunk allocator/dup +void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsAssert(ctx != NULL); + + if (src != NULL) { + + // Duplicate the LIST + DupFormatterFactoryList(ctx, src); + } + else { + static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL }; + ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType)); + } +} + + + +// Formatters management +cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin); + cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data; + cmsFormattersFactoryList* fl ; + + // Reset to built-in defaults + if (Data == NULL) { + + ctx ->FactoryList = NULL; + return TRUE; + } + + fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList)); + if (fl == NULL) return FALSE; + + fl ->Factory = Plugin ->FormattersFactory; + + fl ->Next = ctx -> FactoryList; + ctx ->FactoryList = fl; + + return TRUE; +} + +cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID, + cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags) +{ + _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin); + cmsFormattersFactoryList* f; + + if (T_CHANNELS(Type) == 0) { + static const cmsFormatter nullFormatter = { 0 }; + return nullFormatter; + } + + for (f =ctx->FactoryList; f != NULL; f = f ->Next) { + + cmsFormatter fn = f ->Factory(Type, Dir, dwFlags); + if (fn.Fmt16 != NULL) return fn; + } + + // Revert to default + if (Dir == cmsFormatterInput) + return _cmsGetStockInputFormatter(Type, dwFlags); + else + return _cmsGetStockOutputFormatter(Type, dwFlags); +} + + +// Return whatever given formatter refers to float values +cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type) +{ + return T_FLOAT(Type) ? TRUE : FALSE; +} + +// Return whatever given formatter refers to 8 bits +cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type) +{ + cmsUInt32Number Bytes = T_BYTES(Type); + + return (Bytes == 1); +} + +// Build a suitable formatter for the colorspace of this profile +cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat) +{ + + cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile); + cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace); + cmsInt32Number nOutputChans = cmsChannelsOfColorSpace(ColorSpace); + cmsUInt32Number Float = lIsFloat ? 1U : 0; + + // Unsupported color space? + if (nOutputChans < 0) return 0; + + // Create a fake formatter for result + return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans); +} + +// Build a suitable formatter for the colorspace of this profile +cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat) +{ + + cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile); + + cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace); + cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace); + cmsUInt32Number Float = lIsFloat ? 1U : 0; + + // Unsupported color space? + if (nOutputChans < 0) return 0; + + // Create a fake formatter for result + return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans); +} + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmspcs.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmspcs.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmspcs.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmspcs.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,979 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// inter PCS conversions XYZ <-> CIE L* a* b* +/* + + + CIE 15:2004 CIELab is defined as: + + L* = 116*f(Y/Yn) - 16 0 <= L* <= 100 + a* = 500*[f(X/Xn) - f(Y/Yn)] + b* = 200*[f(Y/Yn) - f(Z/Zn)] + + and + + f(t) = t^(1/3) 1 >= t > (24/116)^3 + (841/108)*t + (16/116) 0 <= t <= (24/116)^3 + + + Reverse transform is: + + X = Xn*[a* / 500 + (L* + 16) / 116] ^ 3 if (X/Xn) > (24/116) + = Xn*(a* / 500 + L* / 116) / 7.787 if (X/Xn) <= (24/116) + + + + PCS in Lab2 is encoded as: + + 8 bit Lab PCS: + + L* 0..100 into a 0..ff byte. + a* t + 128 range is -128.0 +127.0 + b* + + 16 bit Lab PCS: + + L* 0..100 into a 0..ff00 word. + a* t + 128 range is -128.0 +127.9961 + b* + + + +Interchange Space Component Actual Range Encoded Range +CIE XYZ X 0 -> 1.99997 0x0000 -> 0xffff +CIE XYZ Y 0 -> 1.99997 0x0000 -> 0xffff +CIE XYZ Z 0 -> 1.99997 0x0000 -> 0xffff + +Version 2,3 +----------- + +CIELAB (16 bit) L* 0 -> 100.0 0x0000 -> 0xff00 +CIELAB (16 bit) a* -128.0 -> +127.996 0x0000 -> 0x8000 -> 0xffff +CIELAB (16 bit) b* -128.0 -> +127.996 0x0000 -> 0x8000 -> 0xffff + + +Version 4 +--------- + +CIELAB (16 bit) L* 0 -> 100.0 0x0000 -> 0xffff +CIELAB (16 bit) a* -128.0 -> +127 0x0000 -> 0x8080 -> 0xffff +CIELAB (16 bit) b* -128.0 -> +127 0x0000 -> 0x8080 -> 0xffff + +*/ + +// Conversions +void CMSEXPORT cmsXYZ2xyY(cmsCIExyY* Dest, const cmsCIEXYZ* Source) +{ + cmsFloat64Number ISum; + + ISum = 1./(Source -> X + Source -> Y + Source -> Z); + + Dest -> x = (Source -> X) * ISum; + Dest -> y = (Source -> Y) * ISum; + Dest -> Y = Source -> Y; +} + +void CMSEXPORT cmsxyY2XYZ(cmsCIEXYZ* Dest, const cmsCIExyY* Source) +{ + Dest -> X = (Source -> x / Source -> y) * Source -> Y; + Dest -> Y = Source -> Y; + Dest -> Z = ((1 - Source -> x - Source -> y) / Source -> y) * Source -> Y; +} + +/* + The break point (24/116)^3 = (6/29)^3 is a very small amount of tristimulus + primary (0.008856). Generally, this only happens for + nearly ideal blacks and for some orange / amber colors in transmission mode. + For example, the Z value of the orange turn indicator lamp lens on an + automobile will often be below this value. But the Z does not + contribute to the perceived color directly. +*/ + +static +cmsFloat64Number f(cmsFloat64Number t) +{ + const cmsFloat64Number Limit = (24.0/116.0) * (24.0/116.0) * (24.0/116.0); + + if (t <= Limit) + return (841.0/108.0) * t + (16.0/116.0); + else + return pow(t, 1.0/3.0); +} + +static +cmsFloat64Number f_1(cmsFloat64Number t) +{ + const cmsFloat64Number Limit = (24.0/116.0); + + if (t <= Limit) { + return (108.0/841.0) * (t - (16.0/116.0)); + } + + return t * t * t; +} + + +// Standard XYZ to Lab. it can handle negative XZY numbers in some cases +void CMSEXPORT cmsXYZ2Lab(const cmsCIEXYZ* WhitePoint, cmsCIELab* Lab, const cmsCIEXYZ* xyz) +{ + cmsFloat64Number fx, fy, fz; + + if (WhitePoint == NULL) + WhitePoint = cmsD50_XYZ(); + + fx = f(xyz->X / WhitePoint->X); + fy = f(xyz->Y / WhitePoint->Y); + fz = f(xyz->Z / WhitePoint->Z); + + Lab->L = 116.0*fy - 16.0; + Lab->a = 500.0*(fx - fy); + Lab->b = 200.0*(fy - fz); +} + + +// Standard XYZ to Lab. It can return negative XYZ in some cases +void CMSEXPORT cmsLab2XYZ(const cmsCIEXYZ* WhitePoint, cmsCIEXYZ* xyz, const cmsCIELab* Lab) +{ + cmsFloat64Number x, y, z; + + if (WhitePoint == NULL) + WhitePoint = cmsD50_XYZ(); + + y = (Lab-> L + 16.0) / 116.0; + x = y + 0.002 * Lab -> a; + z = y - 0.005 * Lab -> b; + + xyz -> X = f_1(x) * WhitePoint -> X; + xyz -> Y = f_1(y) * WhitePoint -> Y; + xyz -> Z = f_1(z) * WhitePoint -> Z; + +} + +static +cmsFloat64Number L2float2(cmsUInt16Number v) +{ + return (cmsFloat64Number) v / 652.800; +} + +// the a/b part +static +cmsFloat64Number ab2float2(cmsUInt16Number v) +{ + return ((cmsFloat64Number) v / 256.0) - 128.0; +} + +static +cmsUInt16Number L2Fix2(cmsFloat64Number L) +{ + return _cmsQuickSaturateWord(L * 652.8); +} + +static +cmsUInt16Number ab2Fix2(cmsFloat64Number ab) +{ + return _cmsQuickSaturateWord((ab + 128.0) * 256.0); +} + + +static +cmsFloat64Number L2float4(cmsUInt16Number v) +{ + return (cmsFloat64Number) v / 655.35; +} + +// the a/b part +static +cmsFloat64Number ab2float4(cmsUInt16Number v) +{ + return ((cmsFloat64Number) v / 257.0) - 128.0; +} + + +void CMSEXPORT cmsLabEncoded2FloatV2(cmsCIELab* Lab, const cmsUInt16Number wLab[3]) +{ + Lab->L = L2float2(wLab[0]); + Lab->a = ab2float2(wLab[1]); + Lab->b = ab2float2(wLab[2]); +} + + +void CMSEXPORT cmsLabEncoded2Float(cmsCIELab* Lab, const cmsUInt16Number wLab[3]) +{ + Lab->L = L2float4(wLab[0]); + Lab->a = ab2float4(wLab[1]); + Lab->b = ab2float4(wLab[2]); +} + +static +cmsFloat64Number Clamp_L_doubleV2(cmsFloat64Number L) +{ + const cmsFloat64Number L_max = (cmsFloat64Number) (0xFFFF * 100.0) / 0xFF00; + + if (L < 0) L = 0; + if (L > L_max) L = L_max; + + return L; +} + + +static +cmsFloat64Number Clamp_ab_doubleV2(cmsFloat64Number ab) +{ + if (ab < MIN_ENCODEABLE_ab2) ab = MIN_ENCODEABLE_ab2; + if (ab > MAX_ENCODEABLE_ab2) ab = MAX_ENCODEABLE_ab2; + + return ab; +} + +void CMSEXPORT cmsFloat2LabEncodedV2(cmsUInt16Number wLab[3], const cmsCIELab* fLab) +{ + cmsCIELab Lab; + + Lab.L = Clamp_L_doubleV2(fLab ->L); + Lab.a = Clamp_ab_doubleV2(fLab ->a); + Lab.b = Clamp_ab_doubleV2(fLab ->b); + + wLab[0] = L2Fix2(Lab.L); + wLab[1] = ab2Fix2(Lab.a); + wLab[2] = ab2Fix2(Lab.b); +} + + +static +cmsFloat64Number Clamp_L_doubleV4(cmsFloat64Number L) +{ + if (L < 0) L = 0; + if (L > 100.0) L = 100.0; + + return L; +} + +static +cmsFloat64Number Clamp_ab_doubleV4(cmsFloat64Number ab) +{ + if (ab < MIN_ENCODEABLE_ab4) ab = MIN_ENCODEABLE_ab4; + if (ab > MAX_ENCODEABLE_ab4) ab = MAX_ENCODEABLE_ab4; + + return ab; +} + +static +cmsUInt16Number L2Fix4(cmsFloat64Number L) +{ + return _cmsQuickSaturateWord(L * 655.35); +} + +static +cmsUInt16Number ab2Fix4(cmsFloat64Number ab) +{ + return _cmsQuickSaturateWord((ab + 128.0) * 257.0); +} + +void CMSEXPORT cmsFloat2LabEncoded(cmsUInt16Number wLab[3], const cmsCIELab* fLab) +{ + cmsCIELab Lab; + + Lab.L = Clamp_L_doubleV4(fLab ->L); + Lab.a = Clamp_ab_doubleV4(fLab ->a); + Lab.b = Clamp_ab_doubleV4(fLab ->b); + + wLab[0] = L2Fix4(Lab.L); + wLab[1] = ab2Fix4(Lab.a); + wLab[2] = ab2Fix4(Lab.b); +} + +// Auxiliary: convert to Radians +static +cmsFloat64Number RADIANS(cmsFloat64Number deg) +{ + return (deg * M_PI) / 180.; +} + + +// Auxiliary: atan2 but operating in degrees and returning 0 if a==b==0 +static +cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b) +{ + cmsFloat64Number h; + + if (a == 0 && b == 0) + h = 0; + else + h = atan2(a, b); + + h *= (180. / M_PI); + + while (h > 360.) + h -= 360.; + + while ( h < 0) + h += 360.; + + return h; +} + + +// Auxiliary: Square +static +cmsFloat64Number Sqr(cmsFloat64Number v) +{ + return v * v; +} +// From cylindrical coordinates. No check is performed, then negative values are allowed +void CMSEXPORT cmsLab2LCh(cmsCIELCh* LCh, const cmsCIELab* Lab) +{ + LCh -> L = Lab -> L; + LCh -> C = pow(Sqr(Lab ->a) + Sqr(Lab ->b), 0.5); + LCh -> h = atan2deg(Lab ->b, Lab ->a); +} + + +// To cylindrical coordinates. No check is performed, then negative values are allowed +void CMSEXPORT cmsLCh2Lab(cmsCIELab* Lab, const cmsCIELCh* LCh) +{ + cmsFloat64Number h = (LCh -> h * M_PI) / 180.0; + + Lab -> L = LCh -> L; + Lab -> a = LCh -> C * cos(h); + Lab -> b = LCh -> C * sin(h); +} + +// In XYZ All 3 components are encoded using 1.15 fixed point +static +cmsUInt16Number XYZ2Fix(cmsFloat64Number d) +{ + return _cmsQuickSaturateWord(d * 32768.0); +} + +void CMSEXPORT cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3], const cmsCIEXYZ* fXYZ) +{ + cmsCIEXYZ xyz; + + xyz.X = fXYZ -> X; + xyz.Y = fXYZ -> Y; + xyz.Z = fXYZ -> Z; + + // Clamp to encodeable values. + if (xyz.Y <= 0) { + + xyz.X = 0; + xyz.Y = 0; + xyz.Z = 0; + } + + if (xyz.X > MAX_ENCODEABLE_XYZ) + xyz.X = MAX_ENCODEABLE_XYZ; + + if (xyz.X < 0) + xyz.X = 0; + + if (xyz.Y > MAX_ENCODEABLE_XYZ) + xyz.Y = MAX_ENCODEABLE_XYZ; + + if (xyz.Y < 0) + xyz.Y = 0; + + if (xyz.Z > MAX_ENCODEABLE_XYZ) + xyz.Z = MAX_ENCODEABLE_XYZ; + + if (xyz.Z < 0) + xyz.Z = 0; + + + XYZ[0] = XYZ2Fix(xyz.X); + XYZ[1] = XYZ2Fix(xyz.Y); + XYZ[2] = XYZ2Fix(xyz.Z); +} + + +// To convert from Fixed 1.15 point to cmsFloat64Number +static +cmsFloat64Number XYZ2float(cmsUInt16Number v) +{ + cmsS15Fixed16Number fix32; + + // From 1.15 to 15.16 + fix32 = v << 1; + + // From fixed 15.16 to cmsFloat64Number + return _cms15Fixed16toDouble(fix32); +} + + +void CMSEXPORT cmsXYZEncoded2Float(cmsCIEXYZ* fXYZ, const cmsUInt16Number XYZ[3]) +{ + fXYZ -> X = XYZ2float(XYZ[0]); + fXYZ -> Y = XYZ2float(XYZ[1]); + fXYZ -> Z = XYZ2float(XYZ[2]); +} + + +// Returns dE on two Lab values +cmsFloat64Number CMSEXPORT cmsDeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2) +{ + cmsFloat64Number dL, da, db; + + dL = fabs(Lab1 -> L - Lab2 -> L); + da = fabs(Lab1 -> a - Lab2 -> a); + db = fabs(Lab1 -> b - Lab2 -> b); + + return pow(Sqr(dL) + Sqr(da) + Sqr(db), 0.5); +} + + +// Return the CIE94 Delta E +cmsFloat64Number CMSEXPORT cmsCIE94DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2) +{ + cmsCIELCh LCh1, LCh2; + cmsFloat64Number dE, dL, dC, dh, dhsq; + cmsFloat64Number c12, sc, sh; + + dL = fabs(Lab1 ->L - Lab2 ->L); + + cmsLab2LCh(&LCh1, Lab1); + cmsLab2LCh(&LCh2, Lab2); + + dC = fabs(LCh1.C - LCh2.C); + dE = cmsDeltaE(Lab1, Lab2); + + dhsq = Sqr(dE) - Sqr(dL) - Sqr(dC); + if (dhsq < 0) + dh = 0; + else + dh = pow(dhsq, 0.5); + + c12 = sqrt(LCh1.C * LCh2.C); + + sc = 1.0 + (0.048 * c12); + sh = 1.0 + (0.014 * c12); + + return sqrt(Sqr(dL) + Sqr(dC) / Sqr(sc) + Sqr(dh) / Sqr(sh)); +} + + +// Auxiliary +static +cmsFloat64Number ComputeLBFD(const cmsCIELab* Lab) +{ + cmsFloat64Number yt; + + if (Lab->L > 7.996969) + yt = (Sqr((Lab->L+16)/116)*((Lab->L+16)/116))*100; + else + yt = 100 * (Lab->L / 903.3); + + return (54.6 * (M_LOG10E * (log(yt + 1.5))) - 9.6); +} + + + +// bfd - gets BFD(1:1) difference between Lab1, Lab2 +cmsFloat64Number CMSEXPORT cmsBFDdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2) +{ + cmsFloat64Number lbfd1,lbfd2,AveC,Aveh,dE,deltaL, + deltaC,deltah,dc,t,g,dh,rh,rc,rt,bfd; + cmsCIELCh LCh1, LCh2; + + + lbfd1 = ComputeLBFD(Lab1); + lbfd2 = ComputeLBFD(Lab2); + deltaL = lbfd2 - lbfd1; + + cmsLab2LCh(&LCh1, Lab1); + cmsLab2LCh(&LCh2, Lab2); + + deltaC = LCh2.C - LCh1.C; + AveC = (LCh1.C+LCh2.C)/2; + Aveh = (LCh1.h+LCh2.h)/2; + + dE = cmsDeltaE(Lab1, Lab2); + + if (Sqr(dE)>(Sqr(Lab2->L-Lab1->L)+Sqr(deltaC))) + deltah = sqrt(Sqr(dE)-Sqr(Lab2->L-Lab1->L)-Sqr(deltaC)); + else + deltah =0; + + + dc = 0.035 * AveC / (1 + 0.00365 * AveC)+0.521; + g = sqrt(Sqr(Sqr(AveC))/(Sqr(Sqr(AveC))+14000)); + t = 0.627+(0.055*cos((Aveh-254)/(180/M_PI))- + 0.040*cos((2*Aveh-136)/(180/M_PI))+ + 0.070*cos((3*Aveh-31)/(180/M_PI))+ + 0.049*cos((4*Aveh+114)/(180/M_PI))- + 0.015*cos((5*Aveh-103)/(180/M_PI))); + + dh = dc*(g*t+1-g); + rh = -0.260*cos((Aveh-308)/(180/M_PI))- + 0.379*cos((2*Aveh-160)/(180/M_PI))- + 0.636*cos((3*Aveh+254)/(180/M_PI))+ + 0.226*cos((4*Aveh+140)/(180/M_PI))- + 0.194*cos((5*Aveh+280)/(180/M_PI)); + + rc = sqrt((AveC*AveC*AveC*AveC*AveC*AveC)/((AveC*AveC*AveC*AveC*AveC*AveC)+70000000)); + rt = rh*rc; + + bfd = sqrt(Sqr(deltaL)+Sqr(deltaC/dc)+Sqr(deltah/dh)+(rt*(deltaC/dc)*(deltah/dh))); + + return bfd; +} + + +// cmc - CMC(l:c) difference between Lab1, Lab2 +cmsFloat64Number CMSEXPORT cmsCMCdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2, cmsFloat64Number l, cmsFloat64Number c) +{ + cmsFloat64Number dE,dL,dC,dh,sl,sc,sh,t,f,cmc; + cmsCIELCh LCh1, LCh2; + + if (Lab1 ->L == 0 && Lab2 ->L == 0) return 0; + + cmsLab2LCh(&LCh1, Lab1); + cmsLab2LCh(&LCh2, Lab2); + + + dL = Lab2->L-Lab1->L; + dC = LCh2.C-LCh1.C; + + dE = cmsDeltaE(Lab1, Lab2); + + if (Sqr(dE)>(Sqr(dL)+Sqr(dC))) + dh = sqrt(Sqr(dE)-Sqr(dL)-Sqr(dC)); + else + dh =0; + + if ((LCh1.h > 164) && (LCh1.h < 345)) + t = 0.56 + fabs(0.2 * cos(((LCh1.h + 168)/(180/M_PI)))); + else + t = 0.36 + fabs(0.4 * cos(((LCh1.h + 35 )/(180/M_PI)))); + + sc = 0.0638 * LCh1.C / (1 + 0.0131 * LCh1.C) + 0.638; + sl = 0.040975 * Lab1->L /(1 + 0.01765 * Lab1->L); + + if (Lab1->L<16) + sl = 0.511; + + f = sqrt((LCh1.C * LCh1.C * LCh1.C * LCh1.C)/((LCh1.C * LCh1.C * LCh1.C * LCh1.C)+1900)); + sh = sc*(t*f+1-f); + cmc = sqrt(Sqr(dL/(l*sl))+Sqr(dC/(c*sc))+Sqr(dh/sh)); + + return cmc; +} + +// dE2000 The weightings KL, KC and KH can be modified to reflect the relative +// importance of lightness, chroma and hue in different industrial applications +cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2, + cmsFloat64Number Kl, cmsFloat64Number Kc, cmsFloat64Number Kh) +{ + cmsFloat64Number L1 = Lab1->L; + cmsFloat64Number a1 = Lab1->a; + cmsFloat64Number b1 = Lab1->b; + cmsFloat64Number C = sqrt( Sqr(a1) + Sqr(b1) ); + + cmsFloat64Number Ls = Lab2 ->L; + cmsFloat64Number as = Lab2 ->a; + cmsFloat64Number bs = Lab2 ->b; + cmsFloat64Number Cs = sqrt( Sqr(as) + Sqr(bs) ); + + cmsFloat64Number G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) )); + + cmsFloat64Number a_p = (1 + G ) * a1; + cmsFloat64Number b_p = b1; + cmsFloat64Number C_p = sqrt( Sqr(a_p) + Sqr(b_p)); + cmsFloat64Number h_p = atan2deg(b_p, a_p); + + + cmsFloat64Number a_ps = (1 + G) * as; + cmsFloat64Number b_ps = bs; + cmsFloat64Number C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps)); + cmsFloat64Number h_ps = atan2deg(b_ps, a_ps); + + cmsFloat64Number meanC_p =(C_p + C_ps) / 2; + + cmsFloat64Number hps_plus_hp = h_ps + h_p; + cmsFloat64Number hps_minus_hp = h_ps - h_p; + + cmsFloat64Number meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 : + (hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 : + (hps_plus_hp - 360)/2; + + cmsFloat64Number delta_h = (hps_minus_hp) <= -180.000001 ? (hps_minus_hp + 360) : + (hps_minus_hp) > 180 ? (hps_minus_hp - 360) : + (hps_minus_hp); + cmsFloat64Number delta_L = (Ls - L1); + cmsFloat64Number delta_C = (C_ps - C_p ); + + + cmsFloat64Number delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANS(delta_h) / 2); + + cmsFloat64Number T = 1 - 0.17 * cos(RADIANS(meanh_p-30)) + + 0.24 * cos(RADIANS(2*meanh_p)) + + 0.32 * cos(RADIANS(3*meanh_p + 6)) + - 0.2 * cos(RADIANS(4*meanh_p - 63)); + + cmsFloat64Number Sl = 1 + (0.015 * Sqr((Ls + L1) /2- 50) )/ sqrt(20 + Sqr( (Ls+L1)/2 - 50) ); + + cmsFloat64Number Sc = 1 + 0.045 * (C_p + C_ps)/2; + cmsFloat64Number Sh = 1 + 0.015 * ((C_ps + C_p)/2) * T; + + cmsFloat64Number delta_ro = 30 * exp( -Sqr(((meanh_p - 275 ) / 25))); + + cmsFloat64Number Rc = 2 * sqrt(( pow(meanC_p, 7.0) )/( pow(meanC_p, 7.0) + pow(25.0, 7.0))); + + cmsFloat64Number Rt = -sin(2 * RADIANS(delta_ro)) * Rc; + + cmsFloat64Number deltaE00 = sqrt( Sqr(delta_L /(Sl * Kl)) + + Sqr(delta_C/(Sc * Kc)) + + Sqr(delta_H/(Sh * Kh)) + + Rt*(delta_C/(Sc * Kc)) * (delta_H / (Sh * Kh))); + + return deltaE00; +} + +// This function returns a number of gridpoints to be used as LUT table. It assumes same number +// of gripdpoints in all dimensions. Flags may override the choice. +cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags) +{ + cmsUInt32Number nChannels; + + // Already specified? + if (dwFlags & 0x00FF0000) { + // Yes, grab'em + return (dwFlags >> 16) & 0xFF; + } + + nChannels = cmsChannelsOf(Colorspace); + + // HighResPrecalc is maximum resolution + if (dwFlags & cmsFLAGS_HIGHRESPRECALC) { + + if (nChannels > 4) + return 7; // 7 for Hifi + + if (nChannels == 4) // 23 for CMYK + return 23; + + return 49; // 49 for RGB and others + } + + + // LowResPrecal is lower resolution + if (dwFlags & cmsFLAGS_LOWRESPRECALC) { + + if (nChannels > 4) + return 6; // 6 for more than 4 channels + + if (nChannels == 1) + return 33; // For monochrome + + return 17; // 17 for remaining + } + + // Default values + if (nChannels > 4) + return 7; // 7 for Hifi + + if (nChannels == 4) + return 17; // 17 for CMYK + + return 33; // 33 for RGB +} + + +cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, + cmsUInt16Number **White, + cmsUInt16Number **Black, + cmsUInt32Number *nOutputs) +{ + // Only most common spaces + + static cmsUInt16Number RGBblack[4] = { 0, 0, 0 }; + static cmsUInt16Number RGBwhite[4] = { 0xffff, 0xffff, 0xffff }; + static cmsUInt16Number CMYKblack[4] = { 0xffff, 0xffff, 0xffff, 0xffff }; // 400% of ink + static cmsUInt16Number CMYKwhite[4] = { 0, 0, 0, 0 }; + static cmsUInt16Number LABblack[4] = { 0, 0x8080, 0x8080 }; // V4 Lab encoding + static cmsUInt16Number LABwhite[4] = { 0xFFFF, 0x8080, 0x8080 }; + static cmsUInt16Number CMYblack[4] = { 0xffff, 0xffff, 0xffff }; + static cmsUInt16Number CMYwhite[4] = { 0, 0, 0 }; + static cmsUInt16Number Grayblack[4] = { 0 }; + static cmsUInt16Number GrayWhite[4] = { 0xffff }; + + switch (Space) { + + case cmsSigGrayData: if (White) *White = GrayWhite; + if (Black) *Black = Grayblack; + if (nOutputs) *nOutputs = 1; + return TRUE; + + case cmsSigRgbData: if (White) *White = RGBwhite; + if (Black) *Black = RGBblack; + if (nOutputs) *nOutputs = 3; + return TRUE; + + case cmsSigLabData: if (White) *White = LABwhite; + if (Black) *Black = LABblack; + if (nOutputs) *nOutputs = 3; + return TRUE; + + case cmsSigCmykData: if (White) *White = CMYKwhite; + if (Black) *Black = CMYKblack; + if (nOutputs) *nOutputs = 4; + return TRUE; + + case cmsSigCmyData: if (White) *White = CMYwhite; + if (Black) *Black = CMYblack; + if (nOutputs) *nOutputs = 3; + return TRUE; + + default:; + } + + return FALSE; +} + + + +// Several utilities ------------------------------------------------------- + +// Translate from our colorspace to ICC representation + +cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation) +{ + switch (OurNotation) { + + case 1: + case PT_GRAY: return cmsSigGrayData; + + case 2: + case PT_RGB: return cmsSigRgbData; + + case PT_CMY: return cmsSigCmyData; + case PT_CMYK: return cmsSigCmykData; + case PT_YCbCr:return cmsSigYCbCrData; + case PT_YUV: return cmsSigLuvData; + case PT_XYZ: return cmsSigXYZData; + + case PT_LabV2: + case PT_Lab: return cmsSigLabData; + + case PT_YUVK: return cmsSigLuvKData; + case PT_HSV: return cmsSigHsvData; + case PT_HLS: return cmsSigHlsData; + case PT_Yxy: return cmsSigYxyData; + + case PT_MCH1: return cmsSigMCH1Data; + case PT_MCH2: return cmsSigMCH2Data; + case PT_MCH3: return cmsSigMCH3Data; + case PT_MCH4: return cmsSigMCH4Data; + case PT_MCH5: return cmsSigMCH5Data; + case PT_MCH6: return cmsSigMCH6Data; + case PT_MCH7: return cmsSigMCH7Data; + case PT_MCH8: return cmsSigMCH8Data; + + case PT_MCH9: return cmsSigMCH9Data; + case PT_MCH10: return cmsSigMCHAData; + case PT_MCH11: return cmsSigMCHBData; + case PT_MCH12: return cmsSigMCHCData; + case PT_MCH13: return cmsSigMCHDData; + case PT_MCH14: return cmsSigMCHEData; + case PT_MCH15: return cmsSigMCHFData; + + default: return (cmsColorSpaceSignature) 0; + } +} + + +int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace) +{ + switch (ProfileSpace) { + + case cmsSigGrayData: return PT_GRAY; + case cmsSigRgbData: return PT_RGB; + case cmsSigCmyData: return PT_CMY; + case cmsSigCmykData: return PT_CMYK; + case cmsSigYCbCrData:return PT_YCbCr; + case cmsSigLuvData: return PT_YUV; + case cmsSigXYZData: return PT_XYZ; + case cmsSigLabData: return PT_Lab; + case cmsSigLuvKData: return PT_YUVK; + case cmsSigHsvData: return PT_HSV; + case cmsSigHlsData: return PT_HLS; + case cmsSigYxyData: return PT_Yxy; + + case cmsSig1colorData: + case cmsSigMCH1Data: return PT_MCH1; + + case cmsSig2colorData: + case cmsSigMCH2Data: return PT_MCH2; + + case cmsSig3colorData: + case cmsSigMCH3Data: return PT_MCH3; + + case cmsSig4colorData: + case cmsSigMCH4Data: return PT_MCH4; + + case cmsSig5colorData: + case cmsSigMCH5Data: return PT_MCH5; + + case cmsSig6colorData: + case cmsSigMCH6Data: return PT_MCH6; + + case cmsSigMCH7Data: + case cmsSig7colorData:return PT_MCH7; + + case cmsSigMCH8Data: + case cmsSig8colorData:return PT_MCH8; + + case cmsSigMCH9Data: + case cmsSig9colorData:return PT_MCH9; + + case cmsSigMCHAData: + case cmsSig10colorData:return PT_MCH10; + + case cmsSigMCHBData: + case cmsSig11colorData:return PT_MCH11; + + case cmsSigMCHCData: + case cmsSig12colorData:return PT_MCH12; + + case cmsSigMCHDData: + case cmsSig13colorData:return PT_MCH13; + + case cmsSigMCHEData: + case cmsSig14colorData:return PT_MCH14; + + case cmsSigMCHFData: + case cmsSig15colorData:return PT_MCH15; + + default: return (cmsColorSpaceSignature) 0; + } +} + + +cmsInt32Number CMSEXPORT cmsChannelsOfColorSpace(cmsColorSpaceSignature ColorSpace) +{ + switch (ColorSpace) { + + case cmsSigMCH1Data: + case cmsSig1colorData: + case cmsSigGrayData: return 1; + + case cmsSigMCH2Data: + case cmsSig2colorData: return 2; + + case cmsSigXYZData: + case cmsSigLabData: + case cmsSigLuvData: + case cmsSigYCbCrData: + case cmsSigYxyData: + case cmsSigRgbData: + case cmsSigHsvData: + case cmsSigHlsData: + case cmsSigCmyData: + case cmsSigMCH3Data: + case cmsSig3colorData: return 3; + + case cmsSigLuvKData: + case cmsSigCmykData: + case cmsSigMCH4Data: + case cmsSig4colorData: return 4; + + case cmsSigMCH5Data: + case cmsSig5colorData: return 5; + + case cmsSigMCH6Data: + case cmsSig6colorData: return 6; + + case cmsSigMCH7Data: + case cmsSig7colorData: return 7; + + case cmsSigMCH8Data: + case cmsSig8colorData: return 8; + + case cmsSigMCH9Data: + case cmsSig9colorData: return 9; + + case cmsSigMCHAData: + case cmsSig10colorData: return 10; + + case cmsSigMCHBData: + case cmsSig11colorData: return 11; + + case cmsSigMCHCData: + case cmsSig12colorData: return 12; + + case cmsSigMCHDData: + case cmsSig13colorData: return 13; + + case cmsSigMCHEData: + case cmsSig14colorData: return 14; + + case cmsSigMCHFData: + case cmsSig15colorData: return 15; + + default: return -1; + } +} + +/** +* DEPRECATED: Provided for compatibility only +*/ +cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace) +{ + int n = cmsChannelsOfColorSpace(ColorSpace); + if (n < 0) return 3; + return (cmsUInt32Number)n; +} \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsplugin.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsplugin.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsplugin.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsplugin.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1098 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// ---------------------------------------------------------------------------------- +// Encoding & Decoding support functions +// ---------------------------------------------------------------------------------- + +// Little-Endian to Big-Endian + +// Adjust a word value after being read/ before being written from/to an ICC profile +cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word) +{ +#ifndef CMS_USE_BIG_ENDIAN + + cmsUInt8Number* pByte = (cmsUInt8Number*) &Word; + cmsUInt8Number tmp; + + tmp = pByte[0]; + pByte[0] = pByte[1]; + pByte[1] = tmp; +#endif + + return Word; +} + + +// Transports to properly encoded values - note that icc profiles does use big endian notation. + +// 1 2 3 4 +// 4 3 2 1 + +cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number DWord) +{ +#ifndef CMS_USE_BIG_ENDIAN + + cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord; + cmsUInt8Number temp1; + cmsUInt8Number temp2; + + temp1 = *pByte++; + temp2 = *pByte++; + *(pByte-1) = *pByte; + *pByte++ = temp2; + *(pByte-3) = *pByte; + *pByte = temp1; +#endif + return DWord; +} + +// 1 2 3 4 5 6 7 8 +// 8 7 6 5 4 3 2 1 + +void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord) +{ + +#ifndef CMS_USE_BIG_ENDIAN + + cmsUInt8Number* pIn = (cmsUInt8Number*) QWord; + cmsUInt8Number* pOut = (cmsUInt8Number*) Result; + + _cmsAssert(Result != NULL); + + pOut[7] = pIn[0]; + pOut[6] = pIn[1]; + pOut[5] = pIn[2]; + pOut[4] = pIn[3]; + pOut[3] = pIn[4]; + pOut[2] = pIn[5]; + pOut[1] = pIn[6]; + pOut[0] = pIn[7]; + +#else + _cmsAssert(Result != NULL); + +# ifdef CMS_DONT_USE_INT64 + (*Result)[0] = (*QWord)[0]; + (*Result)[1] = (*QWord)[1]; +# else + *Result = *QWord; +# endif +#endif +} + +// Auxiliary -- read 8, 16 and 32-bit numbers +cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n) +{ + cmsUInt8Number tmp; + + _cmsAssert(io != NULL); + + if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1) + return FALSE; + + if (n != NULL) *n = tmp; + return TRUE; +} + +cmsBool CMSEXPORT _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n) +{ + cmsUInt16Number tmp; + + _cmsAssert(io != NULL); + + if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1) + return FALSE; + + if (n != NULL) *n = _cmsAdjustEndianess16(tmp); + return TRUE; +} + +cmsBool CMSEXPORT _cmsReadUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, cmsUInt16Number* Array) +{ + cmsUInt32Number i; + + _cmsAssert(io != NULL); + + for (i=0; i < n; i++) { + + if (Array != NULL) { + if (!_cmsReadUInt16Number(io, Array + i)) return FALSE; + } + else { + if (!_cmsReadUInt16Number(io, NULL)) return FALSE; + } + + } + return TRUE; +} + +cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n) +{ + cmsUInt32Number tmp; + + _cmsAssert(io != NULL); + + if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1) + return FALSE; + + if (n != NULL) *n = _cmsAdjustEndianess32(tmp); + return TRUE; +} + +cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n) +{ + union typeConverter { + cmsUInt32Number integer; + cmsFloat32Number floating_point; + } tmp; + + _cmsAssert(io != NULL); + + if (io->Read(io, &tmp.integer, sizeof(cmsUInt32Number), 1) != 1) + return FALSE; + + if (n != NULL) { + + tmp.integer = _cmsAdjustEndianess32(tmp.integer); + *n = tmp.floating_point; + + // Safeguard which covers against absurd values + if (*n > 1E+20 || *n < -1E+20) return FALSE; + + #if defined(_MSC_VER) && _MSC_VER < 1800 + return TRUE; + #elif defined (__BORLANDC__) + return TRUE; + #elif !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L) + return TRUE; + #else + + // fpclassify() required by C99 (only provided by MSVC >= 1800, VS2013 onwards) + return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL)); + #endif + } + + return TRUE; +} + + +cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n) +{ + cmsUInt64Number tmp; + + _cmsAssert(io != NULL); + + if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1) + return FALSE; + + if (n != NULL) { + + _cmsAdjustEndianess64(n, &tmp); + } + + return TRUE; +} + + +cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n) +{ + cmsUInt32Number tmp; + + _cmsAssert(io != NULL); + + if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1) + return FALSE; + + if (n != NULL) { + *n = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32(tmp)); + } + + return TRUE; +} + + +cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ) +{ + cmsEncodedXYZNumber xyz; + + _cmsAssert(io != NULL); + + if (io ->Read(io, &xyz, sizeof(cmsEncodedXYZNumber), 1) != 1) return FALSE; + + if (XYZ != NULL) { + + XYZ->X = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.X)); + XYZ->Y = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Y)); + XYZ->Z = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Z)); + } + return TRUE; +} + +cmsBool CMSEXPORT _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n) +{ + _cmsAssert(io != NULL); + + if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1) + return FALSE; + + return TRUE; +} + +cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n) +{ + cmsUInt16Number tmp; + + _cmsAssert(io != NULL); + + tmp = _cmsAdjustEndianess16(n); + if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1) + return FALSE; + + return TRUE; +} + +cmsBool CMSEXPORT _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array) +{ + cmsUInt32Number i; + + _cmsAssert(io != NULL); + _cmsAssert(Array != NULL); + + for (i=0; i < n; i++) { + if (!_cmsWriteUInt16Number(io, Array[i])) return FALSE; + } + + return TRUE; +} + +cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n) +{ + cmsUInt32Number tmp; + + _cmsAssert(io != NULL); + + tmp = _cmsAdjustEndianess32(n); + if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1) + return FALSE; + + return TRUE; +} + + +cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n) +{ + union typeConverter { + cmsUInt32Number integer; + cmsFloat32Number floating_point; + } tmp; + + tmp.floating_point = n; + tmp.integer = _cmsAdjustEndianess32(tmp.integer); + if (io -> Write(io, sizeof(cmsUInt32Number), &tmp.integer) != 1) + return FALSE; + + return TRUE; +} + +cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n) +{ + cmsUInt64Number tmp; + + _cmsAssert(io != NULL); + + _cmsAdjustEndianess64(&tmp, n); + if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1) + return FALSE; + + return TRUE; +} + +cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n) +{ + cmsUInt32Number tmp; + + _cmsAssert(io != NULL); + + tmp = _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(n)); + if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1) + return FALSE; + + return TRUE; +} + +cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ) +{ + cmsEncodedXYZNumber xyz; + + _cmsAssert(io != NULL); + _cmsAssert(XYZ != NULL); + + xyz.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->X)); + xyz.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Y)); + xyz.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Z)); + + return io -> Write(io, sizeof(cmsEncodedXYZNumber), &xyz); +} + +// from Fixed point 8.8 to double +cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8) +{ + cmsUInt8Number msb, lsb; + + lsb = (cmsUInt8Number) (fixed8 & 0xff); + msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff); + + return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0)); +} + +cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val) +{ + cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val); + return (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF); +} + +// from Fixed point 15.16 to double +cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32) +{ + cmsFloat64Number floater, sign, mid; + int Whole, FracPart; + + sign = (fix32 < 0 ? -1 : 1); + fix32 = abs(fix32); + + Whole = (cmsUInt16Number)(fix32 >> 16) & 0xffff; + FracPart = (cmsUInt16Number)(fix32 & 0xffff); + + mid = (cmsFloat64Number) FracPart / 65536.0; + floater = (cmsFloat64Number) Whole + mid; + + return sign * floater; +} + +// from double to Fixed point 15.16 +cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v) +{ + return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5)); +} + +// Date/Time functions + +void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest) +{ + + _cmsAssert(Dest != NULL); + _cmsAssert(Source != NULL); + + Dest->tm_sec = _cmsAdjustEndianess16(Source->seconds); + Dest->tm_min = _cmsAdjustEndianess16(Source->minutes); + Dest->tm_hour = _cmsAdjustEndianess16(Source->hours); + Dest->tm_mday = _cmsAdjustEndianess16(Source->day); + Dest->tm_mon = _cmsAdjustEndianess16(Source->month) - 1; + Dest->tm_year = _cmsAdjustEndianess16(Source->year) - 1900; + Dest->tm_wday = -1; + Dest->tm_yday = -1; + Dest->tm_isdst = 0; +} + +void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source) +{ + _cmsAssert(Dest != NULL); + _cmsAssert(Source != NULL); + + Dest->seconds = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_sec); + Dest->minutes = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_min); + Dest->hours = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_hour); + Dest->day = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_mday); + Dest->month = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_mon + 1)); + Dest->year = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_year + 1900)); +} + +// Read base and return type base +cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io) +{ + _cmsTagBase Base; + + _cmsAssert(io != NULL); + + if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1) + return (cmsTagTypeSignature) 0; + + return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig); +} + +// Setup base marker +cmsBool CMSEXPORT _cmsWriteTypeBase(cmsIOHANDLER* io, cmsTagTypeSignature sig) +{ + _cmsTagBase Base; + + _cmsAssert(io != NULL); + + Base.sig = (cmsTagTypeSignature) _cmsAdjustEndianess32(sig); + memset(&Base.reserved, 0, sizeof(Base.reserved)); + return io -> Write(io, sizeof(_cmsTagBase), &Base); +} + +cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io) +{ + cmsUInt8Number Buffer[4]; + cmsUInt32Number NextAligned, At; + cmsUInt32Number BytesToNextAlignedPos; + + _cmsAssert(io != NULL); + + At = io -> Tell(io); + NextAligned = _cmsALIGNLONG(At); + BytesToNextAlignedPos = NextAligned - At; + if (BytesToNextAlignedPos == 0) return TRUE; + if (BytesToNextAlignedPos > 4) return FALSE; + + return (io ->Read(io, Buffer, BytesToNextAlignedPos, 1) == 1); +} + +cmsBool CMSEXPORT _cmsWriteAlignment(cmsIOHANDLER* io) +{ + cmsUInt8Number Buffer[4]; + cmsUInt32Number NextAligned, At; + cmsUInt32Number BytesToNextAlignedPos; + + _cmsAssert(io != NULL); + + At = io -> Tell(io); + NextAligned = _cmsALIGNLONG(At); + BytesToNextAlignedPos = NextAligned - At; + if (BytesToNextAlignedPos == 0) return TRUE; + if (BytesToNextAlignedPos > 4) return FALSE; + + memset(Buffer, 0, BytesToNextAlignedPos); + return io -> Write(io, BytesToNextAlignedPos, Buffer); +} + + +// To deal with text streams. 2K at most +cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...) +{ + va_list args; + int len; + cmsUInt8Number Buffer[2048]; + cmsBool rc; + cmsUInt8Number* ptr; + + _cmsAssert(io != NULL); + _cmsAssert(frm != NULL); + + va_start(args, frm); + + len = vsnprintf((char*) Buffer, 2047, frm, args); + if (len < 0) { + va_end(args); + return FALSE; // Truncated, which is a fatal error for us + } + + // setlocale may be active, no commas are needed in PS generator + // and PS generator is our only client + for (ptr = Buffer; *ptr; ptr++) + { + if (*ptr == ',') *ptr = '.'; + } + + rc = io ->Write(io, (cmsUInt32Number) len, Buffer); + + va_end(args); + + return rc; +} + + +// Plugin memory management ------------------------------------------------------------------------------------------------- + +// Specialized malloc for plug-ins, that is freed upon exit. +void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size) +{ + struct _cmsContext_struct* ctx = _cmsGetContext(ContextID); + + if (ctx ->MemPool == NULL) { + + if (ContextID == NULL) { + + ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024); + if (ctx->MemPool == NULL) return NULL; + } + else { + cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context"); + return NULL; + } + } + + return _cmsSubAlloc(ctx->MemPool, size); +} + + +// Main plug-in dispatcher +cmsBool CMSEXPORT cmsPlugin(void* Plug_in) +{ + return cmsPluginTHR(NULL, Plug_in); +} + +cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in) +{ + cmsPluginBase* Plugin; + + for (Plugin = (cmsPluginBase*) Plug_in; + Plugin != NULL; + Plugin = Plugin -> Next) { + + if (Plugin -> Magic != cmsPluginMagicNumber) { + cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin"); + return FALSE; + } + + if (Plugin ->ExpectedVersion > LCMS_VERSION) { + cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d", + Plugin ->ExpectedVersion, LCMS_VERSION); + return FALSE; + } + + switch (Plugin -> Type) { + + case cmsPluginMemHandlerSig: + if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginInterpolationSig: + if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginTagTypeSig: + if (!_cmsRegisterTagTypePlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginTagSig: + if (!_cmsRegisterTagPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginFormattersSig: + if (!_cmsRegisterFormattersPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginRenderingIntentSig: + if (!_cmsRegisterRenderingIntentPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginParametricCurveSig: + if (!_cmsRegisterParametricCurvesPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginMultiProcessElementSig: + if (!_cmsRegisterMultiProcessElementPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginOptimizationSig: + if (!_cmsRegisterOptimizationPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginTransformSig: + if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginMutexSig: + if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE; + break; + + case cmsPluginParalellizationSig: + if (!_cmsRegisterParallelizationPlugin(id, Plugin)) return FALSE; + break; + + default: + cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type); + return FALSE; + } + } + + // Keep a reference to the plug-in + return TRUE; +} + + +// Revert all plug-ins to default +void CMSEXPORT cmsUnregisterPlugins(void) +{ + cmsUnregisterPluginsTHR(NULL); +} + + +// The Global storage for system context. This is the one and only global variable +// pointers structure. All global vars are referenced here. +static struct _cmsContext_struct globalContext = { + + NULL, // Not in the linked list + NULL, // No suballocator + { + NULL, // UserPtr, + &_cmsLogErrorChunk, // Logger, + &_cmsAlarmCodesChunk, // AlarmCodes, + &_cmsAdaptationStateChunk, // AdaptationState, + &_cmsMemPluginChunk, // MemPlugin, + &_cmsInterpPluginChunk, // InterpPlugin, + &_cmsCurvesPluginChunk, // CurvesPlugin, + &_cmsFormattersPluginChunk, // FormattersPlugin, + &_cmsTagTypePluginChunk, // TagTypePlugin, + &_cmsTagPluginChunk, // TagPlugin, + &_cmsIntentsPluginChunk, // IntentPlugin, + &_cmsMPETypePluginChunk, // MPEPlugin, + &_cmsOptimizationPluginChunk, // OptimizationPlugin, + &_cmsTransformPluginChunk, // TransformPlugin, + &_cmsMutexPluginChunk, // MutexPlugin, + &_cmsParallelizationPluginChunk // ParallelizationPlugin + }, + + { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0 +}; + + +// The context pool (linked list head) +static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER; +static struct _cmsContext_struct* _cmsContextPoolHead = NULL; + + +// Make sure context is initialized (needed on windows) +static +cmsBool InitContextMutex(void) +{ + // See the comments regarding locking in lcms2_internal.h + // for an explanation of why we need the following code. +#ifndef CMS_NO_PTHREADS +#ifdef CMS_IS_WINDOWS_ +#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT + + static cmsBool already_initialized = FALSE; + + if (!already_initialized) + { + static HANDLE _cmsWindowsInitMutex = NULL; + static volatile HANDLE* mutex = &_cmsWindowsInitMutex; + + if (*mutex == NULL) + { + HANDLE p = CreateMutex(NULL, FALSE, NULL); + if (p && InterlockedCompareExchangePointer((void**)mutex, (void*)p, NULL) != NULL) + CloseHandle(p); + } + if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED) + { + cmsSignalError(0, cmsERROR_INTERNAL, "Mutex lock failed"); + return FALSE; + } + if (((void**)&_cmsContextPoolHeadMutex)[0] == NULL) + InitializeCriticalSection(&_cmsContextPoolHeadMutex); + if (*mutex == NULL || !ReleaseMutex(*mutex)) + { + cmsSignalError(0, cmsERROR_INTERNAL, "Mutex unlock failed"); + return FALSE; + } + already_initialized = TRUE; + } +#endif +#endif +#endif + + return TRUE; +} + + + +// Internal, get associated pointer, with guessing. Never returns NULL. +struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID) +{ + struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID; + struct _cmsContext_struct* ctx; + + // On 0, use global settings + if (id == NULL) + return &globalContext; + + InitContextMutex(); + + // Search + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + + for (ctx = _cmsContextPoolHead; + ctx != NULL; + ctx = ctx ->Next) { + + // Found it? + if (id == ctx) + { + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + return ctx; // New-style context + } + } + + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + return &globalContext; +} + + +// Internal: get the memory area associanted with each context client +// Returns the block assigned to the specific zone. Never return NULL. +void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc) +{ + struct _cmsContext_struct* ctx; + void *ptr; + + if ((int) mc < 0 || mc >= MemoryClientMax) { + + cmsSignalError(ContextID, cmsERROR_INTERNAL, "Bad context client -- possible corruption"); + + // This is catastrophic. Should never reach here + _cmsAssert(0); + + // Reverts to global context + return globalContext.chunks[UserPtr]; + } + + ctx = _cmsGetContext(ContextID); + ptr = ctx ->chunks[mc]; + + if (ptr != NULL) + return ptr; + + // A null ptr means no special settings for that context, and this + // reverts to Context0 globals + return globalContext.chunks[mc]; +} + + +// This function returns the given context its default pristine state, +// as no plug-ins were declared. There is no way to unregister a single +// plug-in, as a single call to cmsPluginTHR() function may register +// many different plug-ins simultaneously, then there is no way to +// identify which plug-in to unregister. +void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID) +{ + _cmsRegisterMemHandlerPlugin(ContextID, NULL); + _cmsRegisterInterpPlugin(ContextID, NULL); + _cmsRegisterTagTypePlugin(ContextID, NULL); + _cmsRegisterTagPlugin(ContextID, NULL); + _cmsRegisterFormattersPlugin(ContextID, NULL); + _cmsRegisterRenderingIntentPlugin(ContextID, NULL); + _cmsRegisterParametricCurvesPlugin(ContextID, NULL); + _cmsRegisterMultiProcessElementPlugin(ContextID, NULL); + _cmsRegisterOptimizationPlugin(ContextID, NULL); + _cmsRegisterTransformPlugin(ContextID, NULL); + _cmsRegisterMutexPlugin(ContextID, NULL); + _cmsRegisterParallelizationPlugin(ContextID, NULL); + +} + + +// Returns the memory manager plug-in, if any, from the Plug-in bundle +static +cmsPluginMemHandler* _cmsFindMemoryPlugin(void* PluginBundle) +{ + cmsPluginBase* Plugin; + + for (Plugin = (cmsPluginBase*) PluginBundle; + Plugin != NULL; + Plugin = Plugin -> Next) { + + if (Plugin -> Magic == cmsPluginMagicNumber && + Plugin -> ExpectedVersion <= LCMS_VERSION && + Plugin -> Type == cmsPluginMemHandlerSig) { + + // Found! + return (cmsPluginMemHandler*) Plugin; + } + } + + // Nope, revert to defaults + return NULL; +} + + +// Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined +// data that will be forwarded to plug-ins and logger. +cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData) +{ + struct _cmsContext_struct* ctx; + struct _cmsContext_struct fakeContext; + + if (!InitContextMutex()) return NULL; + + _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager); + + fakeContext.chunks[UserPtr] = UserData; + fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager; + + // Create the context structure. + ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct)); + if (ctx == NULL) + return NULL; // Something very wrong happened! + + // Init the structure and the memory manager + memset(ctx, 0, sizeof(struct _cmsContext_struct)); + + // Keep memory manager + memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk)); + + // Maintain the linked list (with proper locking) + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + ctx ->Next = _cmsContextPoolHead; + _cmsContextPoolHead = ctx; + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + + ctx ->chunks[UserPtr] = UserData; + ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager; + + // Now we can allocate the pool by using default memory manager + ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); // default size about 22 pointers + if (ctx ->MemPool == NULL) { + + cmsDeleteContext(ctx); + return NULL; + } + + _cmsAllocLogErrorChunk(ctx, NULL); + _cmsAllocAlarmCodesChunk(ctx, NULL); + _cmsAllocAdaptationStateChunk(ctx, NULL); + _cmsAllocMemPluginChunk(ctx, NULL); + _cmsAllocInterpPluginChunk(ctx, NULL); + _cmsAllocCurvesPluginChunk(ctx, NULL); + _cmsAllocFormattersPluginChunk(ctx, NULL); + _cmsAllocTagTypePluginChunk(ctx, NULL); + _cmsAllocMPETypePluginChunk(ctx, NULL); + _cmsAllocTagPluginChunk(ctx, NULL); + _cmsAllocIntentsPluginChunk(ctx, NULL); + _cmsAllocOptimizationPluginChunk(ctx, NULL); + _cmsAllocTransformPluginChunk(ctx, NULL); + _cmsAllocMutexPluginChunk(ctx, NULL); + _cmsAllocParallelizationPluginChunk(ctx, NULL); + + // Setup the plug-ins + if (!cmsPluginTHR(ctx, Plugin)) { + + cmsDeleteContext(ctx); + return NULL; + } + + return (cmsContext) ctx; +} + +// Duplicates a context with all associated plug-ins. +// Caller may specify an optional pointer to user-defined +// data that will be forwarded to plug-ins and logger. +cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData) +{ + int i; + struct _cmsContext_struct* ctx; + const struct _cmsContext_struct* src = _cmsGetContext(ContextID); + + void* userData = (NewUserData != NULL) ? NewUserData : src -> chunks[UserPtr]; + + + ctx = (struct _cmsContext_struct*) _cmsMalloc(ContextID, sizeof(struct _cmsContext_struct)); + if (ctx == NULL) + return NULL; // Something very wrong happened + + if (!InitContextMutex()) return NULL; + + // Setup default memory allocators + memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager)); + + // Maintain the linked list + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + ctx ->Next = _cmsContextPoolHead; + _cmsContextPoolHead = ctx; + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + + ctx ->chunks[UserPtr] = userData; + ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager; + + ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); + if (ctx ->MemPool == NULL) { + + cmsDeleteContext(ctx); + return NULL; + } + + // Allocate all required chunks. + _cmsAllocLogErrorChunk(ctx, src); + _cmsAllocAlarmCodesChunk(ctx, src); + _cmsAllocAdaptationStateChunk(ctx, src); + _cmsAllocMemPluginChunk(ctx, src); + _cmsAllocInterpPluginChunk(ctx, src); + _cmsAllocCurvesPluginChunk(ctx, src); + _cmsAllocFormattersPluginChunk(ctx, src); + _cmsAllocTagTypePluginChunk(ctx, src); + _cmsAllocMPETypePluginChunk(ctx, src); + _cmsAllocTagPluginChunk(ctx, src); + _cmsAllocIntentsPluginChunk(ctx, src); + _cmsAllocOptimizationPluginChunk(ctx, src); + _cmsAllocTransformPluginChunk(ctx, src); + _cmsAllocMutexPluginChunk(ctx, src); + _cmsAllocParallelizationPluginChunk(ctx, src); + + // Make sure no one failed + for (i=Logger; i < MemoryClientMax; i++) { + + if (src ->chunks[i] == NULL) { + cmsDeleteContext((cmsContext) ctx); + return NULL; + } + } + + return (cmsContext) ctx; +} + + +// Frees any resources associated with the given context, +// and destroys the context placeholder. +// The ContextID can no longer be used in any THR operation. +void CMSEXPORT cmsDeleteContext(cmsContext ContextID) +{ + if (ContextID == NULL) { + + cmsUnregisterPlugins(); + if (globalContext.MemPool != NULL) + _cmsSubAllocDestroy(globalContext.MemPool); + globalContext.MemPool = NULL; + } + else { + + struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID; + struct _cmsContext_struct fakeContext; + struct _cmsContext_struct* prev; + + + InitContextMutex(); + + memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager)); + + fakeContext.chunks[UserPtr] = ctx ->chunks[UserPtr]; + fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager; + + // Get rid of plugins + cmsUnregisterPluginsTHR(ContextID); + + // Since all memory is allocated in the private pool, all what we need to do is destroy the pool + if (ctx -> MemPool != NULL) + _cmsSubAllocDestroy(ctx ->MemPool); + ctx -> MemPool = NULL; + + // Maintain list + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + if (_cmsContextPoolHead == ctx) { + + _cmsContextPoolHead = ctx->Next; + } + else { + + // Search for previous + for (prev = _cmsContextPoolHead; + prev != NULL; + prev = prev ->Next) + { + if (prev -> Next == ctx) { + prev -> Next = ctx ->Next; + break; + } + } + } + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + + // free the memory block itself + _cmsFree(&fakeContext, ctx); + } +} + +// Returns the user data associated to the given ContextID, or NULL if no user data was attached on context creation +void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID) +{ + return _cmsContextGetClientChunk(ContextID, UserPtr); +} + + +// Use context mutex to provide thread-safe time +cmsBool _cmsGetTime(struct tm* ptr_time) +{ + struct tm* t; +#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S) + struct tm tm; +#endif + + time_t now = time(NULL); + +#ifdef HAVE_GMTIME_R + t = gmtime_r(&now, &tm); +#elif defined(HAVE_GMTIME_S) + t = gmtime_s(&tm, &now) == 0 ? &tm : NULL; +#else + if (!InitContextMutex()) return FALSE; + + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + t = gmtime(&now); + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); +#endif + + if (t == NULL) + return FALSE; + else { + *ptr_time = *t; + return TRUE; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsps2.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsps2.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsps2.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsps2.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1647 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// PostScript ColorRenderingDictionary and ColorSpaceArray + + +#define MAXPSCOLS 60 // Columns on tables + +/* + Implementation + -------------- + + PostScript does use XYZ as its internal PCS. But since PostScript + interpolation tables are limited to 8 bits, I use Lab as a way to + improve the accuracy, favoring perceptual results. So, for the creation + of each CRD, CSA the profiles are converted to Lab via a device + link between profile -> Lab or Lab -> profile. The PS code necessary to + convert Lab <-> XYZ is also included. + + + + Color Space Arrays (CSA) + ================================================================================== + + In order to obtain precision, code chooses between three ways to implement + the device -> XYZ transform. These cases identifies monochrome profiles (often + implemented as a set of curves), matrix-shaper and Pipeline-based. + + Monochrome + ----------- + + This is implemented as /CIEBasedA CSA. The prelinearization curve is + placed into /DecodeA section, and matrix equals to D50. Since here is + no interpolation tables, I do the conversion directly to XYZ + + NOTE: CLUT-based monochrome profiles are NOT supported. So, cmsFLAGS_MATRIXINPUT + flag is forced on such profiles. + + [ /CIEBasedA + << + /DecodeA { transfer function } bind + /MatrixA [D50] + /RangeLMN [ 0.0 cmsD50X 0.0 cmsD50Y 0.0 cmsD50Z ] + /WhitePoint [D50] + /BlackPoint [BP] + /RenderingIntent (intent) + >> + ] + + On simpler profiles, the PCS is already XYZ, so no conversion is required. + + + Matrix-shaper based + ------------------- + + This is implemented both with /CIEBasedABC or /CIEBasedDEF depending on the + profile implementation. Since here there are no interpolation tables, I do + the conversion directly to XYZ + + + + [ /CIEBasedABC + << + /DecodeABC [ {transfer1} {transfer2} {transfer3} ] + /MatrixABC [Matrix] + /RangeLMN [ 0.0 cmsD50X 0.0 cmsD50Y 0.0 cmsD50Z ] + /DecodeLMN [ { / 2} dup dup ] + /WhitePoint [D50] + /BlackPoint [BP] + /RenderingIntent (intent) + >> + ] + + + CLUT based + ---------- + + Lab is used in such cases. + + [ /CIEBasedDEF + << + /DecodeDEF [ ] + /Table [ p p p [<...>]] + /RangeABC [ 0 1 0 1 0 1] + /DecodeABC[ ] + /RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ] + % -128/500 1+127/500 0 1 -127/200 1+128/200 + /MatrixABC [ 1 1 1 1 0 0 0 0 -1] + /WhitePoint [D50] + /BlackPoint [BP] + /RenderingIntent (intent) + ] + + + Color Rendering Dictionaries (CRD) + ================================== + These are always implemented as CLUT, and always are using Lab. Since CRD are expected to + be used as resources, the code adds the definition as well. + + << + /ColorRenderingType 1 + /WhitePoint [ D50 ] + /BlackPoint [BP] + /MatrixPQR [ Bradford ] + /RangePQR [-0.125 1.375 -0.125 1.375 -0.125 1.375 ] + /TransformPQR [ + {4 index 3 get div 2 index 3 get mul exch pop exch pop exch pop exch pop } bind + {4 index 4 get div 2 index 4 get mul exch pop exch pop exch pop exch pop } bind + {4 index 5 get div 2 index 5 get mul exch pop exch pop exch pop exch pop } bind + ] + /MatrixABC <...> + /EncodeABC <...> + /RangeABC <.. used for XYZ -> Lab> + /EncodeLMN + /RenderTable [ p p p [<...>]] + + /RenderingIntent (Perceptual) + >> + /Current exch /ColorRendering defineresource pop + + + The following stages are used to convert from XYZ to Lab + -------------------------------------------------------- + + Input is given at LMN stage on X, Y, Z + + Encode LMN gives us f(X/Xn), f(Y/Yn), f(Z/Zn) + + /EncodeLMN [ + + { 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind + { 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind + { 0.824900 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind + + ] + + + MatrixABC is used to compute f(Y/Yn), f(X/Xn) - f(Y/Yn), f(Y/Yn) - f(Z/Zn) + + | 0 1 0| + | 1 -1 0| + | 0 1 -1| + + /MatrixABC [ 0 1 0 1 -1 1 0 0 -1 ] + + EncodeABC finally gives Lab values. + + /EncodeABC [ + { 116 mul 16 sub 100 div } bind + { 500 mul 128 add 255 div } bind + { 200 mul 128 add 255 div } bind + ] + + The following stages are used to convert Lab to XYZ + ---------------------------------------------------- + + /RangeABC [ 0 1 0 1 0 1] + /DecodeABC [ { 100 mul 16 add 116 div } bind + { 255 mul 128 sub 500 div } bind + { 255 mul 128 sub 200 div } bind + ] + + /MatrixABC [ 1 1 1 1 0 0 0 0 -1] + /DecodeLMN [ + {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind + {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind + {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.824900 mul} bind + ] + + +*/ + +/* + + PostScript algorithms discussion. + ========================================================================================================= + + 1D interpolation algorithm + + + 1D interpolation (float) + ------------------------ + + val2 = Domain * Value; + + cell0 = (int) floor(val2); + cell1 = (int) ceil(val2); + + rest = val2 - cell0; + + y0 = LutTable[cell0] ; + y1 = LutTable[cell1] ; + + y = y0 + (y1 - y0) * rest; + + + + PostScript code Stack + ================================================ + + { % v + + [array] % v tab + dup % v tab tab + length 1 sub % v tab dom + + 3 -1 roll % tab dom v + + mul % tab val2 + dup % tab val2 val2 + dup % tab val2 val2 val2 + floor cvi % tab val2 val2 cell0 + exch % tab val2 cell0 val2 + ceiling cvi % tab val2 cell0 cell1 + + 3 index % tab val2 cell0 cell1 tab + exch % tab val2 cell0 tab cell1 + get % tab val2 cell0 y1 + + 4 -1 roll % val2 cell0 y1 tab + 3 -1 roll % val2 y1 tab cell0 + get % val2 y1 y0 + + dup % val2 y1 y0 y0 + 3 1 roll % val2 y0 y1 y0 + + sub % val2 y0 (y1-y0) + 3 -1 roll % y0 (y1-y0) val2 + dup % y0 (y1-y0) val2 val2 + floor cvi % y0 (y1-y0) val2 floor(val2) + sub % y0 (y1-y0) rest + mul % y0 t1 + add % y + 65535 div % result + + } bind + + +*/ + + +// This struct holds the memory block currently being write +typedef struct { + _cmsStageCLutData* Pipeline; + cmsIOHANDLER* m; + + int FirstComponent; + int SecondComponent; + + const char* PreMaj; + const char* PostMaj; + const char* PreMin; + const char* PostMin; + + int FixWhite; // Force mapping of pure white + + cmsColorSpaceSignature ColorSpace; // ColorSpace of profile + + +} cmsPsSamplerCargo; + +static int _cmsPSActualColumn = 0; + + +// Convert to byte +static +cmsUInt8Number Word2Byte(cmsUInt16Number w) +{ + return (cmsUInt8Number) floor((cmsFloat64Number) w / 257.0 + 0.5); +} + + +// Write a cooked byte +static +void WriteByte(cmsIOHANDLER* m, cmsUInt8Number b) +{ + _cmsIOPrintf(m, "%02x", b); + _cmsPSActualColumn += 2; + + if (_cmsPSActualColumn > MAXPSCOLS) { + + _cmsIOPrintf(m, "\n"); + _cmsPSActualColumn = 0; + } +} + +// ----------------------------------------------------------------- PostScript generation + + +// Removes offending carriage returns + +static +char* RemoveCR(const char* txt) +{ + static char Buffer[2048]; + char* pt; + + strncpy(Buffer, txt, 2047); + Buffer[2047] = 0; + for (pt = Buffer; *pt; pt++) + if (*pt == '\n' || *pt == '\r') *pt = ' '; + + return Buffer; + +} + +static +void EmitHeader(cmsIOHANDLER* m, const char* Title, cmsHPROFILE hProfile) +{ + time_t timer; + cmsMLU *Description, *Copyright; + char DescASCII[256], CopyrightASCII[256]; + + time(&timer); + + Description = (cmsMLU*) cmsReadTag(hProfile, cmsSigProfileDescriptionTag); + Copyright = (cmsMLU*) cmsReadTag(hProfile, cmsSigCopyrightTag); + + DescASCII[0] = DescASCII[255] = 0; + CopyrightASCII[0] = CopyrightASCII[255] = 0; + + if (Description != NULL) cmsMLUgetASCII(Description, cmsNoLanguage, cmsNoCountry, DescASCII, 255); + if (Copyright != NULL) cmsMLUgetASCII(Copyright, cmsNoLanguage, cmsNoCountry, CopyrightASCII, 255); + + _cmsIOPrintf(m, "%%!PS-Adobe-3.0\n"); + _cmsIOPrintf(m, "%%\n"); + _cmsIOPrintf(m, "%% %s\n", Title); + _cmsIOPrintf(m, "%% Source: %s\n", RemoveCR(DescASCII)); + _cmsIOPrintf(m, "%% %s\n", RemoveCR(CopyrightASCII)); + _cmsIOPrintf(m, "%% Created: %s", ctime(&timer)); // ctime appends a \n!!! + _cmsIOPrintf(m, "%%\n"); + _cmsIOPrintf(m, "%%%%BeginResource\n"); + +} + + +// Emits White & Black point. White point is always D50, Black point is the device +// Black point adapted to D50. + +static +void EmitWhiteBlackD50(cmsIOHANDLER* m, cmsCIEXYZ* BlackPoint) +{ + + _cmsIOPrintf(m, "/BlackPoint [%f %f %f]\n", BlackPoint -> X, + BlackPoint -> Y, + BlackPoint -> Z); + + _cmsIOPrintf(m, "/WhitePoint [%f %f %f]\n", cmsD50_XYZ()->X, + cmsD50_XYZ()->Y, + cmsD50_XYZ()->Z); +} + + +static +void EmitRangeCheck(cmsIOHANDLER* m) +{ + _cmsIOPrintf(m, "dup 0.0 lt { pop 0.0 } if " + "dup 1.0 gt { pop 1.0 } if "); + +} + +// Does write the intent + +static +void EmitIntent(cmsIOHANDLER* m, cmsUInt32Number RenderingIntent) +{ + const char *intent; + + switch (RenderingIntent) { + + case INTENT_PERCEPTUAL: intent = "Perceptual"; break; + case INTENT_RELATIVE_COLORIMETRIC: intent = "RelativeColorimetric"; break; + case INTENT_ABSOLUTE_COLORIMETRIC: intent = "AbsoluteColorimetric"; break; + case INTENT_SATURATION: intent = "Saturation"; break; + + default: intent = "Undefined"; break; + } + + _cmsIOPrintf(m, "/RenderingIntent (%s)\n", intent ); +} + +// +// Convert L* to Y +// +// Y = Yn*[ (L* + 16) / 116] ^ 3 if (L*) >= 6 / 29 +// = Yn*( L* / 116) / 7.787 if (L*) < 6 / 29 +// + +// Lab -> XYZ, see the discussion above + +static +void EmitLab2XYZ(cmsIOHANDLER* m) +{ + _cmsIOPrintf(m, "/RangeABC [ 0 1 0 1 0 1]\n"); + _cmsIOPrintf(m, "/DecodeABC [\n"); + _cmsIOPrintf(m, "{100 mul 16 add 116 div } bind\n"); + _cmsIOPrintf(m, "{255 mul 128 sub 500 div } bind\n"); + _cmsIOPrintf(m, "{255 mul 128 sub 200 div } bind\n"); + _cmsIOPrintf(m, "]\n"); + _cmsIOPrintf(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n"); + _cmsIOPrintf(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n"); + _cmsIOPrintf(m, "/DecodeLMN [\n"); + _cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n"); + _cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n"); + _cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.824900 mul} bind\n"); + _cmsIOPrintf(m, "]\n"); +} + +static +void EmitSafeGuardBegin(cmsIOHANDLER* m, const char* name) +{ + _cmsIOPrintf(m, "%%LCMS2: Save previous definition of %s on the operand stack\n", name); + _cmsIOPrintf(m, "currentdict /%s known { /%s load } { null } ifelse\n", name, name); +} + +static +void EmitSafeGuardEnd(cmsIOHANDLER* m, const char* name, int depth) +{ + _cmsIOPrintf(m, "%%LCMS2: Restore previous definition of %s\n", name); + if (depth > 1) { + // cycle topmost items on the stack to bring the previous definition to the front + _cmsIOPrintf(m, "%d -1 roll ", depth); + } + _cmsIOPrintf(m, "dup null eq { pop currentdict /%s undef } { /%s exch def } ifelse\n", name, name); +} + +// Outputs a table of words. It does use 16 bits + +static +void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name) +{ + cmsUInt32Number i; + cmsFloat64Number gamma; + + if (Table == NULL) return; // Error + + if (Table ->nEntries <= 0) return; // Empty table + + // Suppress whole if identity + if (cmsIsToneCurveLinear(Table)) return; + + // Check if is really an exponential. If so, emit "exp" + gamma = cmsEstimateGamma(Table, 0.001); + if (gamma > 0) { + _cmsIOPrintf(m, "/%s { %g exp } bind def\n", name, gamma); + return; + } + + EmitSafeGuardBegin(m, "lcms2gammatable"); + _cmsIOPrintf(m, "/lcms2gammatable ["); + + for (i=0; i < Table->nEntries; i++) { + if (i % 10 == 0) + _cmsIOPrintf(m, "\n "); + _cmsIOPrintf(m, "%d ", Table->Table16[i]); + } + + _cmsIOPrintf(m, "] def\n"); + + + // Emit interpolation code + + // PostScript code Stack + // =============== ======================== + // v + _cmsIOPrintf(m, "/%s {\n ", name); + + // Bounds check + EmitRangeCheck(m); + + _cmsIOPrintf(m, "\n //lcms2gammatable "); // v tab + _cmsIOPrintf(m, "dup "); // v tab tab + _cmsIOPrintf(m, "length 1 sub "); // v tab dom + _cmsIOPrintf(m, "3 -1 roll "); // tab dom v + _cmsIOPrintf(m, "mul "); // tab val2 + _cmsIOPrintf(m, "dup "); // tab val2 val2 + _cmsIOPrintf(m, "dup "); // tab val2 val2 val2 + _cmsIOPrintf(m, "floor cvi "); // tab val2 val2 cell0 + _cmsIOPrintf(m, "exch "); // tab val2 cell0 val2 + _cmsIOPrintf(m, "ceiling cvi "); // tab val2 cell0 cell1 + _cmsIOPrintf(m, "3 index "); // tab val2 cell0 cell1 tab + _cmsIOPrintf(m, "exch "); // tab val2 cell0 tab cell1 + _cmsIOPrintf(m, "get\n "); // tab val2 cell0 y1 + _cmsIOPrintf(m, "4 -1 roll "); // val2 cell0 y1 tab + _cmsIOPrintf(m, "3 -1 roll "); // val2 y1 tab cell0 + _cmsIOPrintf(m, "get "); // val2 y1 y0 + _cmsIOPrintf(m, "dup "); // val2 y1 y0 y0 + _cmsIOPrintf(m, "3 1 roll "); // val2 y0 y1 y0 + _cmsIOPrintf(m, "sub "); // val2 y0 (y1-y0) + _cmsIOPrintf(m, "3 -1 roll "); // y0 (y1-y0) val2 + _cmsIOPrintf(m, "dup "); // y0 (y1-y0) val2 val2 + _cmsIOPrintf(m, "floor cvi "); // y0 (y1-y0) val2 floor(val2) + _cmsIOPrintf(m, "sub "); // y0 (y1-y0) rest + _cmsIOPrintf(m, "mul "); // y0 t1 + _cmsIOPrintf(m, "add "); // y + _cmsIOPrintf(m, "65535 div\n"); // result + + _cmsIOPrintf(m, "} bind def\n"); + + EmitSafeGuardEnd(m, "lcms2gammatable", 1); +} + + +// Compare gamma table + +static +cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nG1, cmsUInt32Number nG2) +{ + if (nG1 != nG2) return FALSE; + return memcmp(g1, g2, nG1 * sizeof(cmsUInt16Number)) == 0; +} + + +// Does write a set of gamma curves + +static +void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[], const char* nameprefix) +{ + cmsUInt32Number i; + static char buffer[2048]; + + for( i=0; i < n; i++ ) + { + if (g[i] == NULL) return; // Error + + if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i-1]->nEntries, g[i]->nEntries)) { + + _cmsIOPrintf(m, "/%s%d /%s%d load def\n", nameprefix, i, nameprefix, i-1); + } + else { + snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, (int) i); + buffer[sizeof(buffer)-1] = '\0'; + Emit1Gamma(m, g[i], buffer); + } + } + +} + + +// Following code dumps a LUT onto memory stream + + +// This is the sampler. Intended to work in SAMPLER_INSPECT mode, +// that is, the callback will be called for each knot with +// +// In[] The grid location coordinates, normalized to 0..ffff +// Out[] The Pipeline values, normalized to 0..ffff +// +// Returning a value other than 0 does terminate the sampling process +// +// Each row contains Pipeline values for all but first component. So, I +// detect row changing by keeping a copy of last value of first +// component. -1 is used to mark beginning of whole block. + +static +int OutputValueSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo) +{ + cmsPsSamplerCargo* sc = (cmsPsSamplerCargo*) Cargo; + cmsUInt32Number i; + + + if (sc -> FixWhite) { + + if (In[0] == 0xFFFF) { // Only in L* = 100, ab = [-8..8] + + if ((In[1] >= 0x7800 && In[1] <= 0x8800) && + (In[2] >= 0x7800 && In[2] <= 0x8800)) { + + cmsUInt16Number* Black; + cmsUInt16Number* White; + cmsUInt32Number nOutputs; + + if (!_cmsEndPointsBySpace(sc ->ColorSpace, &White, &Black, &nOutputs)) + return 0; + + for (i=0; i < nOutputs; i++) + Out[i] = White[i]; + } + + + } + } + + + // Hadle the parenthesis on rows + + if (In[0] != sc ->FirstComponent) { + + if (sc ->FirstComponent != -1) { + + _cmsIOPrintf(sc ->m, sc ->PostMin); + sc ->SecondComponent = -1; + _cmsIOPrintf(sc ->m, sc ->PostMaj); + } + + // Begin block + _cmsPSActualColumn = 0; + + _cmsIOPrintf(sc ->m, sc ->PreMaj); + sc ->FirstComponent = In[0]; + } + + + if (In[1] != sc ->SecondComponent) { + + if (sc ->SecondComponent != -1) { + + _cmsIOPrintf(sc ->m, sc ->PostMin); + } + + _cmsIOPrintf(sc ->m, sc ->PreMin); + sc ->SecondComponent = In[1]; + } + + // Dump table. + + for (i=0; i < sc -> Pipeline ->Params->nOutputs; i++) { + + cmsUInt16Number wWordOut = Out[i]; + cmsUInt8Number wByteOut; // Value as byte + + + // We always deal with Lab4 + + wByteOut = Word2Byte(wWordOut); + WriteByte(sc -> m, wByteOut); + } + + return 1; +} + +// Writes a Pipeline on memstream. Could be 8 or 16 bits based + +static +void WriteCLUT(cmsIOHANDLER* m, cmsStage* mpe, const char* PreMaj, + const char* PostMaj, + const char* PreMin, + const char* PostMin, + int FixWhite, + cmsColorSpaceSignature ColorSpace) +{ + cmsUInt32Number i; + cmsPsSamplerCargo sc; + + sc.FirstComponent = -1; + sc.SecondComponent = -1; + sc.Pipeline = (_cmsStageCLutData *) mpe ->Data; + sc.m = m; + sc.PreMaj = PreMaj; + sc.PostMaj= PostMaj; + + sc.PreMin = PreMin; + sc.PostMin = PostMin; + sc.FixWhite = FixWhite; + sc.ColorSpace = ColorSpace; + + _cmsIOPrintf(m, "["); + + for (i=0; i < sc.Pipeline->Params->nInputs; i++) + _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]); + + _cmsIOPrintf(m, " [\n"); + + cmsStageSampleCLut16bit(mpe, OutputValueSampler, (void*) &sc, SAMPLER_INSPECT); + + _cmsIOPrintf(m, PostMin); + _cmsIOPrintf(m, PostMaj); + _cmsIOPrintf(m, "] "); + +} + + +// Dumps CIEBasedA Color Space Array + +static +int EmitCIEBasedA(cmsIOHANDLER* m, cmsToneCurve* Curve, cmsCIEXYZ* BlackPoint) +{ + + _cmsIOPrintf(m, "[ /CIEBasedA\n"); + _cmsIOPrintf(m, " <<\n"); + + EmitSafeGuardBegin(m, "lcms2gammaproc"); + Emit1Gamma(m, Curve, "lcms2gammaproc"); + + _cmsIOPrintf(m, "/DecodeA /lcms2gammaproc load\n"); + EmitSafeGuardEnd(m, "lcms2gammaproc", 3); + + _cmsIOPrintf(m, "/MatrixA [ 0.9642 1.0000 0.8249 ]\n"); + _cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n"); + + EmitWhiteBlackD50(m, BlackPoint); + EmitIntent(m, INTENT_PERCEPTUAL); + + _cmsIOPrintf(m, ">>\n"); + _cmsIOPrintf(m, "]\n"); + + return 1; +} + + +// Dumps CIEBasedABC Color Space Array + +static +int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** CurveSet, cmsCIEXYZ* BlackPoint) +{ + int i; + + _cmsIOPrintf(m, "[ /CIEBasedABC\n"); + _cmsIOPrintf(m, "<<\n"); + + EmitSafeGuardBegin(m, "lcms2gammaproc0"); + EmitSafeGuardBegin(m, "lcms2gammaproc1"); + EmitSafeGuardBegin(m, "lcms2gammaproc2"); + EmitNGamma(m, 3, CurveSet, "lcms2gammaproc"); + _cmsIOPrintf(m, "/DecodeABC [\n"); + _cmsIOPrintf(m, " /lcms2gammaproc0 load\n"); + _cmsIOPrintf(m, " /lcms2gammaproc1 load\n"); + _cmsIOPrintf(m, " /lcms2gammaproc2 load\n"); + _cmsIOPrintf(m, "]\n"); + EmitSafeGuardEnd(m, "lcms2gammaproc2", 3); + EmitSafeGuardEnd(m, "lcms2gammaproc1", 3); + EmitSafeGuardEnd(m, "lcms2gammaproc0", 3); + + _cmsIOPrintf(m, "/MatrixABC [ " ); + + for( i=0; i < 3; i++ ) { + + _cmsIOPrintf(m, "%.6f %.6f %.6f ", Matrix[i + 3*0], + Matrix[i + 3*1], + Matrix[i + 3*2]); + } + + + _cmsIOPrintf(m, "]\n"); + + _cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n"); + + EmitWhiteBlackD50(m, BlackPoint); + EmitIntent(m, INTENT_PERCEPTUAL); + + _cmsIOPrintf(m, ">>\n"); + _cmsIOPrintf(m, "]\n"); + + + return 1; +} + + +static +int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Intent, cmsCIEXYZ* BlackPoint) +{ + const char* PreMaj; + const char* PostMaj; + const char* PreMin, * PostMin; + cmsStage* mpe; + int i, numchans; + static char buffer[2048]; + + mpe = Pipeline->Elements; + + switch (cmsStageInputChannels(mpe)) { + case 3: + _cmsIOPrintf(m, "[ /CIEBasedDEF\n"); + PreMaj = "<"; + PostMaj = ">\n"; + PreMin = PostMin = ""; + break; + + case 4: + _cmsIOPrintf(m, "[ /CIEBasedDEFG\n"); + PreMaj = "["; + PostMaj = "]\n"; + PreMin = "<"; + PostMin = ">\n"; + break; + + default: + return 0; + + } + + _cmsIOPrintf(m, "<<\n"); + + if (cmsStageType(mpe) == cmsSigCurveSetElemType) { + + numchans = (int) cmsStageOutputChannels(mpe); + for (i = 0; i < numchans; ++i) { + snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i); + buffer[sizeof(buffer) - 1] = '\0'; + EmitSafeGuardBegin(m, buffer); + } + EmitNGamma(m, cmsStageOutputChannels(mpe), _cmsStageGetPtrToCurveSet(mpe), "lcms2gammaproc"); + _cmsIOPrintf(m, "/DecodeDEF [\n"); + for (i = 0; i < numchans; ++i) { + snprintf(buffer, sizeof(buffer), " /lcms2gammaproc%d load\n", i); + buffer[sizeof(buffer) - 1] = '\0'; + _cmsIOPrintf(m, buffer); + } + _cmsIOPrintf(m, "]\n"); + for (i = numchans - 1; i >= 0; --i) { + snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i); + buffer[sizeof(buffer) - 1] = '\0'; + EmitSafeGuardEnd(m, buffer, 3); + } + + mpe = mpe->Next; + } + + if (cmsStageType(mpe) == cmsSigCLutElemType) { + + _cmsIOPrintf(m, "/Table "); + WriteCLUT(m, mpe, PreMaj, PostMaj, PreMin, PostMin, FALSE, (cmsColorSpaceSignature)0); + _cmsIOPrintf(m, "]\n"); + } + + EmitLab2XYZ(m); + EmitWhiteBlackD50(m, BlackPoint); + EmitIntent(m, Intent); + + _cmsIOPrintf(m, " >>\n"); + _cmsIOPrintf(m, "]\n"); + + return 1; +} + +// Generates a curve from a gray profile + +static +cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent) +{ + cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL); + cmsHPROFILE hXYZ = cmsCreateXYZProfile(); + cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE); + int i; + + if (Out != NULL && xform != NULL) { + for (i=0; i < 256; i++) { + + cmsUInt8Number Gray = (cmsUInt8Number) i; + cmsCIEXYZ XYZ; + + cmsDoTransform(xform, &Gray, &XYZ, 1); + + Out ->Table16[i] =_cmsQuickSaturateWord(XYZ.Y * 65535.0); + } + } + + if (xform) cmsDeleteTransform(xform); + if (hXYZ) cmsCloseProfile(hXYZ); + return Out; +} + + + +// Because PostScript has only 8 bits in /Table, we should use +// a more perceptually uniform space... I do choose Lab. + +static +int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags) +{ + cmsHPROFILE hLab; + cmsHTRANSFORM xform; + cmsUInt32Number nChannels; + cmsUInt32Number InputFormat; + int rc; + cmsHPROFILE Profiles[2]; + cmsCIEXYZ BlackPointAdaptedToD50; + + // Does create a device-link based transform. + // The DeviceLink is next dumped as working CSA. + + InputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE); + nChannels = T_CHANNELS(InputFormat); + + + cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0); + + // Adjust output to Lab4 + hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL); + + Profiles[0] = hProfile; + Profiles[1] = hLab; + + xform = cmsCreateMultiprofileTransform(Profiles, 2, InputFormat, TYPE_Lab_DBL, Intent, 0); + cmsCloseProfile(hLab); + + if (xform == NULL) { + + cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Profile -> Lab"); + return 0; + } + + // Only 1, 3 and 4 channels are allowed + + switch (nChannels) { + + case 1: { + cmsToneCurve* Gray2Y = ExtractGray2Y(m ->ContextID, hProfile, Intent); + EmitCIEBasedA(m, Gray2Y, &BlackPointAdaptedToD50); + cmsFreeToneCurve(Gray2Y); + } + break; + + case 3: + case 4: { + cmsUInt32Number OutFrm = TYPE_Lab_16; + cmsPipeline* DeviceLink; + _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform; + + DeviceLink = cmsPipelineDup(v ->Lut); + if (DeviceLink == NULL) return 0; + + dwFlags |= cmsFLAGS_FORCE_CLUT; + _cmsOptimizePipeline(m->ContextID, &DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags); + + rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50); + cmsPipelineFree(DeviceLink); + if (rc == 0) return 0; + } + break; + + default: + + cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Only 3, 4 channels are supported for CSA. This profile has %d channels.", nChannels); + return 0; + } + + + cmsDeleteTransform(xform); + + return 1; +} + +static +cmsFloat64Number* GetPtrToMatrix(const cmsStage* mpe) +{ + _cmsStageMatrixData* Data = (_cmsStageMatrixData*) mpe ->Data; + + return Data -> Double; +} + + +// Does create CSA based on matrix-shaper. Allowed types are gray and RGB based +static +int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matrix, cmsStage* Shaper) +{ + cmsColorSpaceSignature ColorSpace; + int rc; + cmsCIEXYZ BlackPointAdaptedToD50; + + ColorSpace = cmsGetColorSpace(hProfile); + + cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, INTENT_RELATIVE_COLORIMETRIC, 0); + + if (ColorSpace == cmsSigGrayData) { + + cmsToneCurve** ShaperCurve = _cmsStageGetPtrToCurveSet(Shaper); + rc = EmitCIEBasedA(m, ShaperCurve[0], &BlackPointAdaptedToD50); + + } + else + if (ColorSpace == cmsSigRgbData) { + + cmsMAT3 Mat; + int i, j; + + memmove(&Mat, GetPtrToMatrix(Matrix), sizeof(Mat)); + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ; + + rc = EmitCIEBasedABC(m, (cmsFloat64Number *)&Mat, + _cmsStageGetPtrToCurveSet(Shaper), + &BlackPointAdaptedToD50); + } + else { + + cmsSignalError(m->ContextID, cmsERROR_COLORSPACE_CHECK, "Profile is not suitable for CSA. Unsupported colorspace."); + return 0; + } + + return rc; +} + + + +// Creates a PostScript color list from a named profile data. +// This is a HP extension, and it works in Lab instead of XYZ + +static +int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent) +{ + cmsHTRANSFORM xform; + cmsHPROFILE hLab; + cmsUInt32Number i, nColors; + char ColorName[cmsMAX_PATH]; + cmsNAMEDCOLORLIST* NamedColorList; + + hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL); + xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, hLab, TYPE_Lab_DBL, Intent, 0); + if (xform == NULL) return 0; + + NamedColorList = cmsGetNamedColorList(xform); + if (NamedColorList == NULL) return 0; + + _cmsIOPrintf(m, "<<\n"); + _cmsIOPrintf(m, "(colorlistcomment) (%s)\n", "Named color CSA"); + _cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n"); + _cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n"); + + nColors = cmsNamedColorCount(NamedColorList); + + + for (i=0; i < nColors; i++) { + + cmsUInt16Number In[1]; + cmsCIELab Lab; + + In[0] = (cmsUInt16Number) i; + + if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL)) + continue; + + cmsDoTransform(xform, In, &Lab, 1); + _cmsIOPrintf(m, " (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b); + } + + + + _cmsIOPrintf(m, ">>\n"); + + cmsDeleteTransform(xform); + cmsCloseProfile(hLab); + return 1; +} + + +// Does create a Color Space Array on XYZ colorspace for PostScript usage +static +cmsUInt32Number GenerateCSA(cmsContext ContextID, + cmsHPROFILE hProfile, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags, + cmsIOHANDLER* mem) +{ + cmsUInt32Number dwBytesUsed; + cmsPipeline* lut = NULL; + cmsStage* Matrix, *Shaper; + + + // Is a named color profile? + if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) { + + if (!WriteNamedColorCSA(mem, hProfile, Intent)) goto Error; + } + else { + + + // Any profile class are allowed (including devicelink), but + // output (PCS) colorspace must be XYZ or Lab + cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile); + + if (ColorSpace != cmsSigXYZData && + ColorSpace != cmsSigLabData) { + + cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Invalid output color space"); + goto Error; + } + + + // Read the lut with all necessary conversion stages + lut = _cmsReadInputLUT(hProfile, Intent); + if (lut == NULL) goto Error; + + + // Tone curves + matrix can be implemented without any LUT + if (cmsPipelineCheckAndRetreiveStages(lut, 2, cmsSigCurveSetElemType, cmsSigMatrixElemType, &Shaper, &Matrix)) { + + if (!WriteInputMatrixShaper(mem, hProfile, Matrix, Shaper)) goto Error; + + } + else { + // We need a LUT for the rest + if (!WriteInputLUT(mem, hProfile, Intent, dwFlags)) goto Error; + } + } + + + // Done, keep memory usage + dwBytesUsed = mem ->UsedSpace; + + // Get rid of LUT + if (lut != NULL) cmsPipelineFree(lut); + + // Finally, return used byte count + return dwBytesUsed; + +Error: + if (lut != NULL) cmsPipelineFree(lut); + return 0; +} + +// ------------------------------------------------------ Color Rendering Dictionary (CRD) + + + +/* + + Black point compensation plus chromatic adaptation: + + Step 1 - Chromatic adaptation + ============================= + + WPout + X = ------- PQR + Wpin + + Step 2 - Black point compensation + ================================= + + (WPout - BPout)*X - WPout*(BPin - BPout) + out = --------------------------------------- + WPout - BPin + + + Algorithm discussion + ==================== + + TransformPQR(WPin, BPin, WPout, BPout, PQR) + + Wpin,etc= { Xws Yws Zws Pws Qws Rws } + + + Algorithm Stack 0...n + =========================================================== + PQR BPout WPout BPin WPin + 4 index 3 get WPin PQR BPout WPout BPin WPin + div (PQR/WPin) BPout WPout BPin WPin + 2 index 3 get WPout (PQR/WPin) BPout WPout BPin WPin + mult WPout*(PQR/WPin) BPout WPout BPin WPin + + 2 index 3 get WPout WPout*(PQR/WPin) BPout WPout BPin WPin + 2 index 3 get BPout WPout WPout*(PQR/WPin) BPout WPout BPin WPin + sub (WPout-BPout) WPout*(PQR/WPin) BPout WPout BPin WPin + mult (WPout-BPout)* WPout*(PQR/WPin) BPout WPout BPin WPin + + 2 index 3 get WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin + 4 index 3 get BPin WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin + 3 index 3 get BPout BPin WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin + + sub (BPin-BPout) WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin + mult (BPin-BPout)*WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin + sub (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin + + 3 index 3 get BPin (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin + 3 index 3 get WPout BPin (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin + exch + sub (WPout-BPin) (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin + div + + exch pop + exch pop + exch pop + exch pop + +*/ + + +static +void EmitPQRStage(cmsIOHANDLER* m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute) +{ + + + if (lIsAbsolute) { + + // For absolute colorimetric intent, encode back to relative + // and generate a relative Pipeline + + // Relative encoding is obtained across XYZpcs*(D50/WhitePoint) + + cmsCIEXYZ White; + + _cmsReadMediaWhitePoint(&White, hProfile); + + _cmsIOPrintf(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n"); + _cmsIOPrintf(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n"); + + _cmsIOPrintf(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n" + "/TransformPQR [\n" + "{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n" + "{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n" + "{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n", + White.X, White.Y, White.Z); + return; + } + + + _cmsIOPrintf(m,"%% Bradford Cone Space\n" + "/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n"); + + _cmsIOPrintf(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n"); + + + // No BPC + + if (!DoBPC) { + + _cmsIOPrintf(m, "%% VonKries-like transform in Bradford Cone Space\n" + "/TransformPQR [\n" + "{exch pop exch 3 get mul exch pop exch 3 get div} bind\n" + "{exch pop exch 4 get mul exch pop exch 4 get div} bind\n" + "{exch pop exch 5 get mul exch pop exch 5 get div} bind\n]\n"); + } else { + + // BPC + + _cmsIOPrintf(m, "%% VonKries-like transform in Bradford Cone Space plus BPC\n" + "/TransformPQR [\n"); + + _cmsIOPrintf(m, "{4 index 3 get div 2 index 3 get mul " + "2 index 3 get 2 index 3 get sub mul " + "2 index 3 get 4 index 3 get 3 index 3 get sub mul sub " + "3 index 3 get 3 index 3 get exch sub div " + "exch pop exch pop exch pop exch pop } bind\n"); + + _cmsIOPrintf(m, "{4 index 4 get div 2 index 4 get mul " + "2 index 4 get 2 index 4 get sub mul " + "2 index 4 get 4 index 4 get 3 index 4 get sub mul sub " + "3 index 4 get 3 index 4 get exch sub div " + "exch pop exch pop exch pop exch pop } bind\n"); + + _cmsIOPrintf(m, "{4 index 5 get div 2 index 5 get mul " + "2 index 5 get 2 index 5 get sub mul " + "2 index 5 get 4 index 5 get 3 index 5 get sub mul sub " + "3 index 5 get 3 index 5 get exch sub div " + "exch pop exch pop exch pop exch pop } bind\n]\n"); + + } +} + + +static +void EmitXYZ2Lab(cmsIOHANDLER* m) +{ + _cmsIOPrintf(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n"); + _cmsIOPrintf(m, "/EncodeLMN [\n"); + _cmsIOPrintf(m, "{ 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n"); + _cmsIOPrintf(m, "{ 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n"); + _cmsIOPrintf(m, "{ 0.824900 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n"); + _cmsIOPrintf(m, "]\n"); + _cmsIOPrintf(m, "/MatrixABC [ 0 1 0 1 -1 1 0 0 -1 ]\n"); + _cmsIOPrintf(m, "/EncodeABC [\n"); + + + _cmsIOPrintf(m, "{ 116 mul 16 sub 100 div } bind\n"); + _cmsIOPrintf(m, "{ 500 mul 128 add 256 div } bind\n"); + _cmsIOPrintf(m, "{ 200 mul 128 add 256 div } bind\n"); + + + _cmsIOPrintf(m, "]\n"); + + +} + +// Due to impedance mismatch between XYZ and almost all RGB and CMYK spaces +// I choose to dump LUTS in Lab instead of XYZ. There is still a lot of wasted +// space on 3D CLUT, but since space seems not to be a problem here, 33 points +// would give a reasonable accuracy. Note also that CRD tables must operate in +// 8 bits. + +static +int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags) +{ + cmsHPROFILE hLab; + cmsHTRANSFORM xform; + cmsUInt32Number i, nChannels; + cmsUInt32Number OutputFormat; + _cmsTRANSFORM* v; + cmsPipeline* DeviceLink; + cmsHPROFILE Profiles[3]; + cmsCIEXYZ BlackPointAdaptedToD50; + cmsBool lDoBPC = (cmsBool) (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); + cmsBool lFixWhite = (cmsBool) !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP); + cmsUInt32Number InFrm = TYPE_Lab_16; + cmsUInt32Number RelativeEncodingIntent; + cmsColorSpaceSignature ColorSpace; + + + hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL); + if (hLab == NULL) return 0; + + OutputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE); + nChannels = T_CHANNELS(OutputFormat); + + ColorSpace = cmsGetColorSpace(hProfile); + + // For absolute colorimetric, the LUT is encoded as relative in order to preserve precision. + + RelativeEncodingIntent = Intent; + if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC) + RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC; + + + // Use V4 Lab always + Profiles[0] = hLab; + Profiles[1] = hProfile; + + xform = cmsCreateMultiprofileTransformTHR(m ->ContextID, + Profiles, 2, TYPE_Lab_DBL, + OutputFormat, RelativeEncodingIntent, 0); + cmsCloseProfile(hLab); + + if (xform == NULL) { + + cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation"); + return 0; + } + + // Get a copy of the internal devicelink + v = (_cmsTRANSFORM*) xform; + DeviceLink = cmsPipelineDup(v ->Lut); + if (DeviceLink == NULL) return 0; + + + // We need a CLUT + dwFlags |= cmsFLAGS_FORCE_CLUT; + _cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags); + + _cmsIOPrintf(m, "<<\n"); + _cmsIOPrintf(m, "/ColorRenderingType 1\n"); + + + cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0); + + // Emit headers, etc. + EmitWhiteBlackD50(m, &BlackPointAdaptedToD50); + EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC); + EmitXYZ2Lab(m); + + + // FIXUP: map Lab (100, 0, 0) to perfect white, because the particular encoding for Lab + // does map a=b=0 not falling into any specific node. Since range a,b goes -128..127, + // zero is slightly moved towards right, so assure next node (in L=100 slice) is mapped to + // zero. This would sacrifice a bit of highlights, but failure to do so would cause + // scum dot. Ouch. + + if (Intent == INTENT_ABSOLUTE_COLORIMETRIC) + lFixWhite = FALSE; + + _cmsIOPrintf(m, "/RenderTable "); + + + WriteCLUT(m, cmsPipelineGetPtrToFirstStage(DeviceLink), "<", ">\n", "", "", lFixWhite, ColorSpace); + + _cmsIOPrintf(m, " %d {} bind ", nChannels); + + for (i=1; i < nChannels; i++) + _cmsIOPrintf(m, "dup "); + + _cmsIOPrintf(m, "]\n"); + + + EmitIntent(m, Intent); + + _cmsIOPrintf(m, ">>\n"); + + if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) { + + _cmsIOPrintf(m, "/Current exch /ColorRendering defineresource pop\n"); + } + + cmsPipelineFree(DeviceLink); + cmsDeleteTransform(xform); + + return 1; +} + + +// Builds a ASCII string containing colorant list in 0..1.0 range +static +void BuildColorantList(char *Colorant, cmsUInt32Number nColorant, cmsUInt16Number Out[]) +{ + char Buff[32]; + cmsUInt32Number j; + + Colorant[0] = 0; + if (nColorant > cmsMAXCHANNELS) + nColorant = cmsMAXCHANNELS; + + for (j = 0; j < nColorant; j++) { + + snprintf(Buff, 31, "%.3f", Out[j] / 65535.0); + Buff[31] = 0; + strcat(Colorant, Buff); + if (j < nColorant - 1) + strcat(Colorant, " "); + + } +} + + +// Creates a PostScript color list from a named profile data. +// This is a HP extension. + +static +int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent, cmsUInt32Number dwFlags) +{ + cmsHTRANSFORM xform; + cmsUInt32Number i, nColors, nColorant; + cmsUInt32Number OutputFormat; + char ColorName[cmsMAX_PATH]; + char Colorant[512]; + cmsNAMEDCOLORLIST* NamedColorList; + + + OutputFormat = cmsFormatterForColorspaceOfProfile(hNamedColor, 2, FALSE); + nColorant = T_CHANNELS(OutputFormat); + + + xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, NULL, OutputFormat, Intent, dwFlags); + if (xform == NULL) return 0; + + + NamedColorList = cmsGetNamedColorList(xform); + if (NamedColorList == NULL) return 0; + + _cmsIOPrintf(m, "<<\n"); + _cmsIOPrintf(m, "(colorlistcomment) (%s) \n", "Named profile"); + _cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n"); + _cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n"); + + nColors = cmsNamedColorCount(NamedColorList); + + for (i=0; i < nColors; i++) { + + cmsUInt16Number In[1]; + cmsUInt16Number Out[cmsMAXCHANNELS]; + + In[0] = (cmsUInt16Number) i; + + if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL)) + continue; + + cmsDoTransform(xform, In, Out, 1); + BuildColorantList(Colorant, nColorant, Out); + _cmsIOPrintf(m, " (%s) [ %s ]\n", ColorName, Colorant); + } + + _cmsIOPrintf(m, " >>"); + + if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) { + + _cmsIOPrintf(m, " /Current exch /HPSpotTable defineresource pop\n"); + } + + cmsDeleteTransform(xform); + return 1; +} + + + +// This one does create a Color Rendering Dictionary. +// CRD are always LUT-Based, no matter if profile is +// implemented as matrix-shaper. + +static +cmsUInt32Number GenerateCRD(cmsContext ContextID, + cmsHPROFILE hProfile, + cmsUInt32Number Intent, cmsUInt32Number dwFlags, + cmsIOHANDLER* mem) +{ + cmsUInt32Number dwBytesUsed; + + if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) { + + EmitHeader(mem, "Color Rendering Dictionary (CRD)", hProfile); + } + + + // Is a named color profile? + if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) { + + if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) { + return 0; + } + } + else { + + // CRD are always implemented as LUT + + if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) { + return 0; + } + } + + if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) { + + _cmsIOPrintf(mem, "%%%%EndResource\n"); + _cmsIOPrintf(mem, "\n%% CRD End\n"); + } + + // Done, keep memory usage + dwBytesUsed = mem ->UsedSpace; + + // Finally, return used byte count + return dwBytesUsed; + + cmsUNUSED_PARAMETER(ContextID); +} + + + + +cmsUInt32Number CMSEXPORT cmsGetPostScriptColorResource(cmsContext ContextID, + cmsPSResourceType Type, + cmsHPROFILE hProfile, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags, + cmsIOHANDLER* io) +{ + cmsUInt32Number rc; + + + switch (Type) { + + case cmsPS_RESOURCE_CSA: + rc = GenerateCSA(ContextID, hProfile, Intent, dwFlags, io); + break; + + default: + case cmsPS_RESOURCE_CRD: + rc = GenerateCRD(ContextID, hProfile, Intent, dwFlags, io); + break; + } + + return rc; +} + + + +cmsUInt32Number CMSEXPORT cmsGetPostScriptCRD(cmsContext ContextID, + cmsHPROFILE hProfile, + cmsUInt32Number Intent, cmsUInt32Number dwFlags, + void* Buffer, cmsUInt32Number dwBufferLen) +{ + cmsIOHANDLER* mem; + cmsUInt32Number dwBytesUsed; + + // Set up the serialization engine + if (Buffer == NULL) + mem = cmsOpenIOhandlerFromNULL(ContextID); + else + mem = cmsOpenIOhandlerFromMem(ContextID, Buffer, dwBufferLen, "w"); + + if (!mem) return 0; + + dwBytesUsed = cmsGetPostScriptColorResource(ContextID, cmsPS_RESOURCE_CRD, hProfile, Intent, dwFlags, mem); + + // Get rid of memory stream + cmsCloseIOhandler(mem); + + return dwBytesUsed; +} + + + +// Does create a Color Space Array on XYZ colorspace for PostScript usage +cmsUInt32Number CMSEXPORT cmsGetPostScriptCSA(cmsContext ContextID, + cmsHPROFILE hProfile, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags, + void* Buffer, + cmsUInt32Number dwBufferLen) +{ + cmsIOHANDLER* mem; + cmsUInt32Number dwBytesUsed; + + if (Buffer == NULL) + mem = cmsOpenIOhandlerFromNULL(ContextID); + else + mem = cmsOpenIOhandlerFromMem(ContextID, Buffer, dwBufferLen, "w"); + + if (!mem) return 0; + + dwBytesUsed = cmsGetPostScriptColorResource(ContextID, cmsPS_RESOURCE_CSA, hProfile, Intent, dwFlags, mem); + + // Get rid of memory stream + cmsCloseIOhandler(mem); + + return dwBytesUsed; + +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmssamp.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmssamp.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmssamp.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmssamp.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,581 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +#define cmsmin(a, b) (((a) < (b)) ? (a) : (b)) +#define cmsmax(a, b) (((a) > (b)) ? (a) : (b)) + +// This file contains routines for resampling and LUT optimization, black point detection +// and black preservation. + +// Black point detection ------------------------------------------------------------------------- + + +// PCS -> PCS round trip transform, always uses relative intent on the device -> pcs +static +cmsHTRANSFORM CreateRoundtripXForm(cmsHPROFILE hProfile, cmsUInt32Number nIntent) +{ + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsHPROFILE hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + cmsHTRANSFORM xform; + cmsBool BPC[4] = { FALSE, FALSE, FALSE, FALSE }; + cmsFloat64Number States[4] = { 1.0, 1.0, 1.0, 1.0 }; + cmsHPROFILE hProfiles[4]; + cmsUInt32Number Intents[4]; + + hProfiles[0] = hLab; hProfiles[1] = hProfile; hProfiles[2] = hProfile; hProfiles[3] = hLab; + Intents[0] = INTENT_RELATIVE_COLORIMETRIC; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = INTENT_RELATIVE_COLORIMETRIC; + + xform = cmsCreateExtendedTransform(ContextID, 4, hProfiles, BPC, Intents, + States, NULL, 0, TYPE_Lab_DBL, TYPE_Lab_DBL, cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE); + + cmsCloseProfile(hLab); + return xform; +} + +// Use darker colorants to obtain black point. This works in the relative colorimetric intent and +// assumes more ink results in darker colors. No ink limit is assumed. +static +cmsBool BlackPointAsDarkerColorant(cmsHPROFILE hInput, + cmsUInt32Number Intent, + cmsCIEXYZ* BlackPoint, + cmsUInt32Number dwFlags) +{ + cmsUInt16Number *Black; + cmsHTRANSFORM xform; + cmsColorSpaceSignature Space; + cmsUInt32Number nChannels; + cmsUInt32Number dwFormat; + cmsHPROFILE hLab; + cmsCIELab Lab; + cmsCIEXYZ BlackXYZ; + cmsContext ContextID = cmsGetProfileContextID(hInput); + + // If the profile does not support input direction, assume Black point 0 + if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) { + + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + // Create a formatter which has n channels and no floating point + dwFormat = cmsFormatterForColorspaceOfProfile(hInput, 2, FALSE); + + // Try to get black by using black colorant + Space = cmsGetColorSpace(hInput); + + // This function returns darker colorant in 16 bits for several spaces + if (!_cmsEndPointsBySpace(Space, NULL, &Black, &nChannels)) { + + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + if (nChannels != T_CHANNELS(dwFormat)) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + // Lab will be used as the output space, but lab2 will avoid recursion + hLab = cmsCreateLab2ProfileTHR(ContextID, NULL); + if (hLab == NULL) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + // Create the transform + xform = cmsCreateTransformTHR(ContextID, hInput, dwFormat, + hLab, TYPE_Lab_DBL, Intent, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE); + cmsCloseProfile(hLab); + + if (xform == NULL) { + + // Something went wrong. Get rid of open resources and return zero as black + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + // Convert black to Lab + cmsDoTransform(xform, Black, &Lab, 1); + + // Force it to be neutral, check for inconsistences + Lab.a = Lab.b = 0; + if (Lab.L > 50 || Lab.L < 0) Lab.L = 0; + + // Free the resources + cmsDeleteTransform(xform); + + // Convert from Lab (which is now clipped) to XYZ. + cmsLab2XYZ(NULL, &BlackXYZ, &Lab); + + if (BlackPoint != NULL) + *BlackPoint = BlackXYZ; + + return TRUE; + + cmsUNUSED_PARAMETER(dwFlags); +} + +// Get a black point of output CMYK profile, discounting any ink-limiting embedded +// in the profile. For doing that, we use perceptual intent in input direction: +// Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab +static +cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile) +{ + cmsHTRANSFORM hRoundTrip; + cmsCIELab LabIn, LabOut; + cmsCIEXYZ BlackXYZ; + + // Is the intent supported by the profile? + if (!cmsIsIntentSupported(hProfile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) { + + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return TRUE; + } + + hRoundTrip = CreateRoundtripXForm(hProfile, INTENT_PERCEPTUAL); + if (hRoundTrip == NULL) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + LabIn.L = LabIn.a = LabIn.b = 0; + cmsDoTransform(hRoundTrip, &LabIn, &LabOut, 1); + + // Clip Lab to reasonable limits + if (LabOut.L > 50) LabOut.L = 50; + LabOut.a = LabOut.b = 0; + + cmsDeleteTransform(hRoundTrip); + + // Convert it to XYZ + cmsLab2XYZ(NULL, &BlackXYZ, &LabOut); + + if (BlackPoint != NULL) + *BlackPoint = BlackXYZ; + + return TRUE; +} + +// This function shouldn't exist at all -- there is such quantity of broken +// profiles on black point tag, that we must somehow fix chromaticity to +// avoid huge tint when doing Black point compensation. This function does +// just that. There is a special flag for using black point tag, but turned +// off by default because it is bogus on most profiles. The detection algorithm +// involves to turn BP to neutral and to use only L component. +cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags) +{ + cmsProfileClassSignature devClass; + + // Make sure the device class is adequate + devClass = cmsGetDeviceClass(hProfile); + if (devClass == cmsSigLinkClass || + devClass == cmsSigAbstractClass || + devClass == cmsSigNamedColorClass) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + // Make sure intent is adequate + if (Intent != INTENT_PERCEPTUAL && + Intent != INTENT_RELATIVE_COLORIMETRIC && + Intent != INTENT_SATURATION) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + // v4 + perceptual & saturation intents does have its own black point, and it is + // well specified enough to use it. Black point tag is deprecated in V4. + if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) && + (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) { + + // Matrix shaper share MRC & perceptual intents + if (cmsIsMatrixShaper(hProfile)) + return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, 0); + + // Get Perceptual black out of v4 profiles. That is fixed for perceptual & saturation intents + BlackPoint -> X = cmsPERCEPTUAL_BLACK_X; + BlackPoint -> Y = cmsPERCEPTUAL_BLACK_Y; + BlackPoint -> Z = cmsPERCEPTUAL_BLACK_Z; + + return TRUE; + } + + +#ifdef CMS_USE_PROFILE_BLACK_POINT_TAG + + // v2, v4 rel/abs colorimetric + if (cmsIsTag(hProfile, cmsSigMediaBlackPointTag) && + Intent == INTENT_RELATIVE_COLORIMETRIC) { + + cmsCIEXYZ *BlackPtr, BlackXYZ, UntrustedBlackPoint, TrustedBlackPoint, MediaWhite; + cmsCIELab Lab; + + // If black point is specified, then use it, + + BlackPtr = cmsReadTag(hProfile, cmsSigMediaBlackPointTag); + if (BlackPtr != NULL) { + + BlackXYZ = *BlackPtr; + _cmsReadMediaWhitePoint(&MediaWhite, hProfile); + + // Black point is absolute XYZ, so adapt to D50 to get PCS value + cmsAdaptToIlluminant(&UntrustedBlackPoint, &MediaWhite, cmsD50_XYZ(), &BlackXYZ); + + // Force a=b=0 to get rid of any chroma + cmsXYZ2Lab(NULL, &Lab, &UntrustedBlackPoint); + Lab.a = Lab.b = 0; + if (Lab.L > 50) Lab.L = 50; // Clip to L* <= 50 + cmsLab2XYZ(NULL, &TrustedBlackPoint, &Lab); + + if (BlackPoint != NULL) + *BlackPoint = TrustedBlackPoint; + + return TRUE; + } + } +#endif + + // That is about v2 profiles. + + // If output profile, discount ink-limiting and that's all + if (Intent == INTENT_RELATIVE_COLORIMETRIC && + (cmsGetDeviceClass(hProfile) == cmsSigOutputClass) && + (cmsGetColorSpace(hProfile) == cmsSigCmykData)) + return BlackPointUsingPerceptualBlack(BlackPoint, hProfile); + + // Nope, compute BP using current intent. + return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags); +} + + + +// --------------------------------------------------------------------------------------------------------- + +// Least Squares Fit of a Quadratic Curve to Data +// http://www.personal.psu.edu/jhm/f90/lectures/lsq2.html + +static +cmsFloat64Number RootOfLeastSquaresFitQuadraticCurve(int n, cmsFloat64Number x[], cmsFloat64Number y[]) +{ + double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0; + double sum_y = 0, sum_yx = 0, sum_yx2 = 0; + double d, a, b, c; + int i; + cmsMAT3 m; + cmsVEC3 v, res; + + if (n < 4) return 0; + + for (i=0; i < n; i++) { + + double xn = x[i]; + double yn = y[i]; + + sum_x += xn; + sum_x2 += xn*xn; + sum_x3 += xn*xn*xn; + sum_x4 += xn*xn*xn*xn; + + sum_y += yn; + sum_yx += yn*xn; + sum_yx2 += yn*xn*xn; + } + + _cmsVEC3init(&m.v[0], n, sum_x, sum_x2); + _cmsVEC3init(&m.v[1], sum_x, sum_x2, sum_x3); + _cmsVEC3init(&m.v[2], sum_x2, sum_x3, sum_x4); + + _cmsVEC3init(&v, sum_y, sum_yx, sum_yx2); + + if (!_cmsMAT3solve(&res, &m, &v)) return 0; + + + a = res.n[2]; + b = res.n[1]; + c = res.n[0]; + + if (fabs(a) < 1.0E-10) { + + if (fabs(b) < 1.0E-10) return 0; + return cmsmin(0, cmsmax(50, -c/b )); + } + else { + + d = b*b - 4.0 * a * c; + if (d <= 0) { + return 0; + } + else { + + double rt; + + if (fabs(a) < 1.0E-10) return 0; + + rt = (-b + sqrt(d)) / (2.0 * a); + + return cmsmax(0, cmsmin(50, rt)); + } + } + +} + + + +// Calculates the black point of a destination profile. +// This algorithm comes from the Adobe paper disclosing its black point compensation method. +cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags) +{ + cmsColorSpaceSignature ColorSpace; + cmsHTRANSFORM hRoundTrip = NULL; + cmsCIELab InitialLab, destLab, Lab; + cmsFloat64Number inRamp[256], outRamp[256]; + cmsFloat64Number MinL, MaxL; + cmsBool NearlyStraightMidrange = TRUE; + cmsFloat64Number yRamp[256]; + cmsFloat64Number x[256], y[256]; + cmsFloat64Number lo, hi; + int n, l; + cmsProfileClassSignature devClass; + + // Make sure the device class is adequate + devClass = cmsGetDeviceClass(hProfile); + if (devClass == cmsSigLinkClass || + devClass == cmsSigAbstractClass || + devClass == cmsSigNamedColorClass) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + // Make sure intent is adequate + if (Intent != INTENT_PERCEPTUAL && + Intent != INTENT_RELATIVE_COLORIMETRIC && + Intent != INTENT_SATURATION) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + + // v4 + perceptual & saturation intents does have its own black point, and it is + // well specified enough to use it. Black point tag is deprecated in V4. + if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) && + (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) { + + // Matrix shaper share MRC & perceptual intents + if (cmsIsMatrixShaper(hProfile)) + return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, 0); + + // Get Perceptual black out of v4 profiles. That is fixed for perceptual & saturation intents + BlackPoint -> X = cmsPERCEPTUAL_BLACK_X; + BlackPoint -> Y = cmsPERCEPTUAL_BLACK_Y; + BlackPoint -> Z = cmsPERCEPTUAL_BLACK_Z; + return TRUE; + } + + + // Check if the profile is lut based and gray, rgb or cmyk (7.2 in Adobe's document) + ColorSpace = cmsGetColorSpace(hProfile); + if (!cmsIsCLUT(hProfile, Intent, LCMS_USED_AS_OUTPUT ) || + (ColorSpace != cmsSigGrayData && + ColorSpace != cmsSigRgbData && + ColorSpace != cmsSigCmykData)) { + + // In this case, handle as input case + return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags); + } + + // It is one of the valid cases!, use Adobe algorithm + + + // Set a first guess, that should work on good profiles. + if (Intent == INTENT_RELATIVE_COLORIMETRIC) { + + cmsCIEXYZ IniXYZ; + + // calculate initial Lab as source black point + if (!cmsDetectBlackPoint(&IniXYZ, hProfile, Intent, dwFlags)) { + return FALSE; + } + + // convert the XYZ to lab + cmsXYZ2Lab(NULL, &InitialLab, &IniXYZ); + + } else { + + // set the initial Lab to zero, that should be the black point for perceptual and saturation + InitialLab.L = 0; + InitialLab.a = 0; + InitialLab.b = 0; + } + + + // Step 2 + // ====== + + // Create a roundtrip. Define a Transform BT for all x in L*a*b* + hRoundTrip = CreateRoundtripXForm(hProfile, Intent); + if (hRoundTrip == NULL) return FALSE; + + // Compute ramps + + for (l=0; l < 256; l++) { + + Lab.L = (cmsFloat64Number) (l * 100.0) / 255.0; + Lab.a = cmsmin(50, cmsmax(-50, InitialLab.a)); + Lab.b = cmsmin(50, cmsmax(-50, InitialLab.b)); + + cmsDoTransform(hRoundTrip, &Lab, &destLab, 1); + + inRamp[l] = Lab.L; + outRamp[l] = destLab.L; + } + + // Make monotonic + for (l = 254; l > 0; --l) { + outRamp[l] = cmsmin(outRamp[l], outRamp[l+1]); + } + + // Check + if (! (outRamp[0] < outRamp[255])) { + + cmsDeleteTransform(hRoundTrip); + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + + // Test for mid range straight (only on relative colorimetric) + NearlyStraightMidrange = TRUE; + MinL = outRamp[0]; MaxL = outRamp[255]; + if (Intent == INTENT_RELATIVE_COLORIMETRIC) { + + for (l=0; l < 256; l++) { + + if (! ((inRamp[l] <= MinL + 0.2 * (MaxL - MinL) ) || + (fabs(inRamp[l] - outRamp[l]) < 4.0 ))) + NearlyStraightMidrange = FALSE; + } + + // If the mid range is straight (as determined above) then the + // DestinationBlackPoint shall be the same as initialLab. + // Otherwise, the DestinationBlackPoint shall be determined + // using curve fitting. + if (NearlyStraightMidrange) { + + cmsLab2XYZ(NULL, BlackPoint, &InitialLab); + cmsDeleteTransform(hRoundTrip); + return TRUE; + } + } + + + // curve fitting: The round-trip curve normally looks like a nearly constant section at the black point, + // with a corner and a nearly straight line to the white point. + for (l=0; l < 256; l++) { + + yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL); + } + + // find the black point using the least squares error quadratic curve fitting + if (Intent == INTENT_RELATIVE_COLORIMETRIC) { + lo = 0.1; + hi = 0.5; + } + else { + + // Perceptual and saturation + lo = 0.03; + hi = 0.25; + } + + // Capture shadow points for the fitting. + n = 0; + for (l=0; l < 256; l++) { + + cmsFloat64Number ff = yRamp[l]; + + if (ff >= lo && ff < hi) { + x[n] = inRamp[l]; + y[n] = yRamp[l]; + n++; + } + } + + + // No suitable points + if (n < 3 ) { + cmsDeleteTransform(hRoundTrip); + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } + + + // fit and get the vertex of quadratic curve + Lab.L = RootOfLeastSquaresFitQuadraticCurve(n, x, y); + + if (Lab.L < 0.0) { // clip to zero L* if the vertex is negative + Lab.L = 0; + } + + Lab.a = InitialLab.a; + Lab.b = InitialLab.b; + + cmsLab2XYZ(NULL, BlackPoint, &Lab); + + cmsDeleteTransform(hRoundTrip); + return TRUE; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmssm.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmssm.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmssm.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmssm.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,765 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// ------------------------------------------------------------------------ + +// Gamut boundary description by using Jan Morovic's Segment maxima method +// Many thanks to Jan for allowing me to use his algorithm. + +// r = C* +// alpha = Hab +// theta = L* + +#define SECTORS 16 // number of divisions in alpha and theta + +// Spherical coordinates +typedef struct { + + cmsFloat64Number r; + cmsFloat64Number alpha; + cmsFloat64Number theta; + +} cmsSpherical; + +typedef enum { + GP_EMPTY, + GP_SPECIFIED, + GP_MODELED + + } GDBPointType; + + +typedef struct { + + GDBPointType Type; + cmsSpherical p; // Keep also alpha & theta of maximum + +} cmsGDBPoint; + + +typedef struct { + + cmsContext ContextID; + cmsGDBPoint Gamut[SECTORS][SECTORS]; + +} cmsGDB; + + +// A line using the parametric form +// P = a + t*u +typedef struct { + + cmsVEC3 a; + cmsVEC3 u; + +} cmsLine; + + +// A plane using the parametric form +// Q = b + r*v + s*w +typedef struct { + + cmsVEC3 b; + cmsVEC3 v; + cmsVEC3 w; + +} cmsPlane; + + + +// -------------------------------------------------------------------------------------------- + +// ATAN2() which always returns degree positive numbers + +static +cmsFloat64Number _cmsAtan2(cmsFloat64Number y, cmsFloat64Number x) +{ + cmsFloat64Number a; + + // Deal with undefined case + if (x == 0.0 && y == 0.0) return 0; + + a = (atan2(y, x) * 180.0) / M_PI; + + while (a < 0) { + a += 360; + } + + return a; +} + +// Convert to spherical coordinates +static +void ToSpherical(cmsSpherical* sp, const cmsVEC3* v) +{ + + cmsFloat64Number L, a, b; + + L = v ->n[VX]; + a = v ->n[VY]; + b = v ->n[VZ]; + + sp ->r = sqrt( L*L + a*a + b*b ); + + if (sp ->r == 0) { + sp ->alpha = sp ->theta = 0; + return; + } + + sp ->alpha = _cmsAtan2(a, b); + sp ->theta = _cmsAtan2(sqrt(a*a + b*b), L); +} + + +// Convert to cartesian from spherical +static +void ToCartesian(cmsVEC3* v, const cmsSpherical* sp) +{ + cmsFloat64Number sin_alpha; + cmsFloat64Number cos_alpha; + cmsFloat64Number sin_theta; + cmsFloat64Number cos_theta; + cmsFloat64Number L, a, b; + + sin_alpha = sin((M_PI * sp ->alpha) / 180.0); + cos_alpha = cos((M_PI * sp ->alpha) / 180.0); + sin_theta = sin((M_PI * sp ->theta) / 180.0); + cos_theta = cos((M_PI * sp ->theta) / 180.0); + + a = sp ->r * sin_theta * sin_alpha; + b = sp ->r * sin_theta * cos_alpha; + L = sp ->r * cos_theta; + + v ->n[VX] = L; + v ->n[VY] = a; + v ->n[VZ] = b; +} + + +// Quantize sector of a spherical coordinate. Saturate 360, 180 to last sector +// The limits are the centers of each sector, so +static +void QuantizeToSector(const cmsSpherical* sp, int* alpha, int* theta) +{ + *alpha = (int) floor(((sp->alpha * (SECTORS)) / 360.0) ); + *theta = (int) floor(((sp->theta * (SECTORS)) / 180.0) ); + + if (*alpha >= SECTORS) + *alpha = SECTORS-1; + if (*theta >= SECTORS) + *theta = SECTORS-1; +} + + +// Line determined by 2 points +static +void LineOf2Points(cmsLine* line, cmsVEC3* a, cmsVEC3* b) +{ + + _cmsVEC3init(&line ->a, a ->n[VX], a ->n[VY], a ->n[VZ]); + _cmsVEC3init(&line ->u, b ->n[VX] - a ->n[VX], + b ->n[VY] - a ->n[VY], + b ->n[VZ] - a ->n[VZ]); +} + + +// Evaluate parametric line +static +void GetPointOfLine(cmsVEC3* p, const cmsLine* line, cmsFloat64Number t) +{ + p ->n[VX] = line ->a.n[VX] + t * line->u.n[VX]; + p ->n[VY] = line ->a.n[VY] + t * line->u.n[VY]; + p ->n[VZ] = line ->a.n[VZ] + t * line->u.n[VZ]; +} + + + +/* + Closest point in sector line1 to sector line2 (both are defined as 0 <=t <= 1) + http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm + + Copyright 2001, softSurfer (www.softsurfer.com) + This code may be freely used and modified for any purpose + providing that this copyright notice is included with it. + SoftSurfer makes no warranty for this code, and cannot be held + liable for any real or imagined damage resulting from its use. + Users of this code must verify correctness for their application. + +*/ + +static +cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2) +{ + cmsFloat64Number a, b, c, d, e, D; + cmsFloat64Number sc, sN, sD; + //cmsFloat64Number tc; // left for future use + cmsFloat64Number tN, tD; + cmsVEC3 w0; + + _cmsVEC3minus(&w0, &line1 ->a, &line2 ->a); + + a = _cmsVEC3dot(&line1 ->u, &line1 ->u); + b = _cmsVEC3dot(&line1 ->u, &line2 ->u); + c = _cmsVEC3dot(&line2 ->u, &line2 ->u); + d = _cmsVEC3dot(&line1 ->u, &w0); + e = _cmsVEC3dot(&line2 ->u, &w0); + + D = a*c - b * b; // Denominator + sD = tD = D; // default sD = D >= 0 + + if (D < MATRIX_DET_TOLERANCE) { // the lines are almost parallel + + sN = 0.0; // force using point P0 on segment S1 + sD = 1.0; // to prevent possible division by 0.0 later + tN = e; + tD = c; + } + else { // get the closest points on the infinite lines + + sN = (b*e - c*d); + tN = (a*e - b*d); + + if (sN < 0.0) { // sc < 0 => the s=0 edge is visible + + sN = 0.0; + tN = e; + tD = c; + } + else if (sN > sD) { // sc > 1 => the s=1 edge is visible + sN = sD; + tN = e + b; + tD = c; + } + } + + if (tN < 0.0) { // tc < 0 => the t=0 edge is visible + + tN = 0.0; + // recompute sc for this edge + if (-d < 0.0) + sN = 0.0; + else if (-d > a) + sN = sD; + else { + sN = -d; + sD = a; + } + } + else if (tN > tD) { // tc > 1 => the t=1 edge is visible + + tN = tD; + + // recompute sc for this edge + if ((-d + b) < 0.0) + sN = 0; + else if ((-d + b) > a) + sN = sD; + else { + sN = (-d + b); + sD = a; + } + } + // finally do the division to get sc and tc + sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD); + //tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD); // left for future use. + + GetPointOfLine(r, line1, sc); + return TRUE; +} + + + +// ------------------------------------------------------------------ Wrapper + + +// Allocate & free structure +cmsHANDLE CMSEXPORT cmsGBDAlloc(cmsContext ContextID) +{ + cmsGDB* gbd = (cmsGDB*) _cmsMallocZero(ContextID, sizeof(cmsGDB)); + if (gbd == NULL) return NULL; + + gbd -> ContextID = ContextID; + + return (cmsHANDLE) gbd; +} + + +void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD) +{ + cmsGDB* gbd = (cmsGDB*) hGBD; + if (hGBD != NULL) + _cmsFree(gbd->ContextID, (void*) gbd); +} + + +// Auxiliary to retrieve a pointer to the segmentr containing the Lab value +static +cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp) +{ + cmsVEC3 v; + int alpha, theta; + + // Housekeeping + _cmsAssert(gbd != NULL); + _cmsAssert(Lab != NULL); + _cmsAssert(sp != NULL); + + // Center L* by subtracting half of its domain, that's 50 + _cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b); + + // Convert to spherical coordinates + ToSpherical(sp, &v); + + if (sp ->r < 0 || sp ->alpha < 0 || sp->theta < 0) { + cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, "spherical value out of range"); + return NULL; + } + + // On which sector it falls? + QuantizeToSector(sp, &alpha, &theta); + + if (alpha < 0 || theta < 0 || alpha >= SECTORS || theta >= SECTORS) { + cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, " quadrant out of range"); + return NULL; + } + + // Get pointer to the sector + return &gbd ->Gamut[theta][alpha]; +} + +// Add a point to gamut descriptor. Point to add is in Lab color space. +// GBD is centered on a=b=0 and L*=50 +cmsBool CMSEXPORT cmsGDBAddPoint(cmsHANDLE hGBD, const cmsCIELab* Lab) +{ + cmsGDB* gbd = (cmsGDB*) hGBD; + cmsGDBPoint* ptr; + cmsSpherical sp; + + + // Get pointer to the sector + ptr = GetPoint(gbd, Lab, &sp); + if (ptr == NULL) return FALSE; + + // If no samples at this sector, add it + if (ptr ->Type == GP_EMPTY) { + + ptr -> Type = GP_SPECIFIED; + ptr -> p = sp; + } + else { + + + // Substitute only if radius is greater + if (sp.r > ptr -> p.r) { + + ptr -> Type = GP_SPECIFIED; + ptr -> p = sp; + } + } + + return TRUE; +} + +// Check if a given point falls inside gamut +cmsBool CMSEXPORT cmsGDBCheckPoint(cmsHANDLE hGBD, const cmsCIELab* Lab) +{ + cmsGDB* gbd = (cmsGDB*) hGBD; + cmsGDBPoint* ptr; + cmsSpherical sp; + + // Get pointer to the sector + ptr = GetPoint(gbd, Lab, &sp); + if (ptr == NULL) return FALSE; + + // If no samples at this sector, return no data + if (ptr ->Type == GP_EMPTY) return FALSE; + + // In gamut only if radius is greater + + return (sp.r <= ptr -> p.r); +} + +// ----------------------------------------------------------------------------------------------------------------------- + +// Find near sectors. The list of sectors found is returned on Close[]. +// The function returns the number of sectors as well. + +// 24 9 10 11 12 +// 23 8 1 2 13 +// 22 7 * 3 14 +// 21 6 5 4 15 +// 20 19 18 17 16 +// +// Those are the relative movements +// {-2,-2}, {-1, -2}, {0, -2}, {+1, -2}, {+2, -2}, +// {-2,-1}, {-1, -1}, {0, -1}, {+1, -1}, {+2, -1}, +// {-2, 0}, {-1, 0}, {0, 0}, {+1, 0}, {+2, 0}, +// {-2,+1}, {-1, +1}, {0, +1}, {+1, +1}, {+2, +1}, +// {-2,+2}, {-1, +2}, {0, +2}, {+1, +2}, {+2, +2}}; + + +static +const struct _spiral { + + int AdvX, AdvY; + + } Spiral[] = { {0, -1}, {+1, -1}, {+1, 0}, {+1, +1}, {0, +1}, {-1, +1}, + {-1, 0}, {-1, -1}, {-1, -2}, {0, -2}, {+1, -2}, {+2, -2}, + {+2, -1}, {+2, 0}, {+2, +1}, {+2, +2}, {+1, +2}, {0, +2}, + {-1, +2}, {-2, +2}, {-2, +1}, {-2, 0}, {-2, -1}, {-2, -2} }; + +#define NSTEPS (sizeof(Spiral) / sizeof(struct _spiral)) + +static +int FindNearSectors(cmsGDB* gbd, int alpha, int theta, cmsGDBPoint* Close[]) +{ + int nSectors = 0; + int a, t; + cmsUInt32Number i; + cmsGDBPoint* pt; + + for (i=0; i < NSTEPS; i++) { + + a = alpha + Spiral[i].AdvX; + t = theta + Spiral[i].AdvY; + + // Cycle at the end + a %= SECTORS; + t %= SECTORS; + + // Cycle at the begin + if (a < 0) a = SECTORS + a; + if (t < 0) t = SECTORS + t; + + pt = &gbd ->Gamut[t][a]; + + if (pt -> Type != GP_EMPTY) { + + Close[nSectors++] = pt; + } + } + + return nSectors; +} + + +// Interpolate a missing sector. Method identifies whatever this is top, bottom or mid +static +cmsBool InterpolateMissingSector(cmsGDB* gbd, int alpha, int theta) +{ + cmsSpherical sp; + cmsVEC3 Lab; + cmsVEC3 Centre; + cmsLine ray; + int nCloseSectors; + cmsGDBPoint* Close[NSTEPS + 1]; + cmsSpherical closel, templ; + cmsLine edge; + int k, m; + + // Is that point already specified? + if (gbd ->Gamut[theta][alpha].Type != GP_EMPTY) return TRUE; + + // Fill close points + nCloseSectors = FindNearSectors(gbd, alpha, theta, Close); + + + // Find a central point on the sector + sp.alpha = (cmsFloat64Number) ((alpha + 0.5) * 360.0) / (SECTORS); + sp.theta = (cmsFloat64Number) ((theta + 0.5) * 180.0) / (SECTORS); + sp.r = 50.0; + + // Convert to Cartesian + ToCartesian(&Lab, &sp); + + // Create a ray line from centre to this point + _cmsVEC3init(&Centre, 50.0, 0, 0); + LineOf2Points(&ray, &Lab, &Centre); + + // For all close sectors + closel.r = 0.0; + closel.alpha = 0; + closel.theta = 0; + + for (k=0; k < nCloseSectors; k++) { + + for(m = k+1; m < nCloseSectors; m++) { + + cmsVEC3 temp, a1, a2; + + // A line from sector to sector + ToCartesian(&a1, &Close[k]->p); + ToCartesian(&a2, &Close[m]->p); + + LineOf2Points(&edge, &a1, &a2); + + // Find a line + ClosestLineToLine(&temp, &ray, &edge); + + // Convert to spherical + ToSpherical(&templ, &temp); + + + if ( templ.r > closel.r && + templ.theta >= (theta*180.0/SECTORS) && + templ.theta <= ((theta+1)*180.0/SECTORS) && + templ.alpha >= (alpha*360.0/SECTORS) && + templ.alpha <= ((alpha+1)*360.0/SECTORS)) { + + closel = templ; + } + } + } + + gbd ->Gamut[theta][alpha].p = closel; + gbd ->Gamut[theta][alpha].Type = GP_MODELED; + + return TRUE; + +} + + +// Interpolate missing parts. The algorithm fist computes slices at +// theta=0 and theta=Max. +cmsBool CMSEXPORT cmsGDBCompute(cmsHANDLE hGBD, cmsUInt32Number dwFlags) +{ + int alpha, theta; + cmsGDB* gbd = (cmsGDB*) hGBD; + + _cmsAssert(hGBD != NULL); + + // Interpolate black + for (alpha = 0; alpha < SECTORS; alpha++) { + + if (!InterpolateMissingSector(gbd, alpha, 0)) return FALSE; + } + + // Interpolate white + for (alpha = 0; alpha < SECTORS; alpha++) { + + if (!InterpolateMissingSector(gbd, alpha, SECTORS-1)) return FALSE; + } + + + // Interpolate Mid + for (theta = 1; theta < SECTORS; theta++) { + for (alpha = 0; alpha < SECTORS; alpha++) { + + if (!InterpolateMissingSector(gbd, alpha, theta)) return FALSE; + } + } + + // Done + return TRUE; + + cmsUNUSED_PARAMETER(dwFlags); +} + + + + +// -------------------------------------------------------------------------------------------------------- + +// Great for debug, but not suitable for real use + +#if 0 +cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname) +{ + FILE* fp; + int i, j; + cmsGDB* gbd = (cmsGDB*) hGBD; + cmsGDBPoint* pt; + + fp = fopen (fname, "wt"); + if (fp == NULL) + return FALSE; + + fprintf (fp, "#VRML V2.0 utf8\n"); + + // set the viewing orientation and distance + fprintf (fp, "DEF CamTest Group {\n"); + fprintf (fp, "\tchildren [\n"); + fprintf (fp, "\t\tDEF Cameras Group {\n"); + fprintf (fp, "\t\t\tchildren [\n"); + fprintf (fp, "\t\t\t\tDEF DefaultView Viewpoint {\n"); + fprintf (fp, "\t\t\t\t\tposition 0 0 340\n"); + fprintf (fp, "\t\t\t\t\torientation 0 0 1 0\n"); + fprintf (fp, "\t\t\t\t\tdescription \"default view\"\n"); + fprintf (fp, "\t\t\t\t}\n"); + fprintf (fp, "\t\t\t]\n"); + fprintf (fp, "\t\t},\n"); + fprintf (fp, "\t]\n"); + fprintf (fp, "}\n"); + + // Output the background stuff + fprintf (fp, "Background {\n"); + fprintf (fp, "\tskyColor [\n"); + fprintf (fp, "\t\t.5 .5 .5\n"); + fprintf (fp, "\t]\n"); + fprintf (fp, "}\n"); + + // Output the shape stuff + fprintf (fp, "Transform {\n"); + fprintf (fp, "\tscale .3 .3 .3\n"); + fprintf (fp, "\tchildren [\n"); + + // Draw the axes as a shape: + fprintf (fp, "\t\tShape {\n"); + fprintf (fp, "\t\t\tappearance Appearance {\n"); + fprintf (fp, "\t\t\t\tmaterial Material {\n"); + fprintf (fp, "\t\t\t\t\tdiffuseColor 0 0.8 0\n"); + fprintf (fp, "\t\t\t\t\temissiveColor 1.0 1.0 1.0\n"); + fprintf (fp, "\t\t\t\t\tshininess 0.8\n"); + fprintf (fp, "\t\t\t\t}\n"); + fprintf (fp, "\t\t\t}\n"); + fprintf (fp, "\t\t\tgeometry IndexedLineSet {\n"); + fprintf (fp, "\t\t\t\tcoord Coordinate {\n"); + fprintf (fp, "\t\t\t\t\tpoint [\n"); + fprintf (fp, "\t\t\t\t\t0.0 0.0 0.0,\n"); + fprintf (fp, "\t\t\t\t\t%f 0.0 0.0,\n", 255.0); + fprintf (fp, "\t\t\t\t\t0.0 %f 0.0,\n", 255.0); + fprintf (fp, "\t\t\t\t\t0.0 0.0 %f]\n", 255.0); + fprintf (fp, "\t\t\t\t}\n"); + fprintf (fp, "\t\t\t\tcoordIndex [\n"); + fprintf (fp, "\t\t\t\t\t0, 1, -1\n"); + fprintf (fp, "\t\t\t\t\t0, 2, -1\n"); + fprintf (fp, "\t\t\t\t\t0, 3, -1]\n"); + fprintf (fp, "\t\t\t}\n"); + fprintf (fp, "\t\t}\n"); + + + fprintf (fp, "\t\tShape {\n"); + fprintf (fp, "\t\t\tappearance Appearance {\n"); + fprintf (fp, "\t\t\t\tmaterial Material {\n"); + fprintf (fp, "\t\t\t\t\tdiffuseColor 0 0.8 0\n"); + fprintf (fp, "\t\t\t\t\temissiveColor 1 1 1\n"); + fprintf (fp, "\t\t\t\t\tshininess 0.8\n"); + fprintf (fp, "\t\t\t\t}\n"); + fprintf (fp, "\t\t\t}\n"); + fprintf (fp, "\t\t\tgeometry PointSet {\n"); + + // fill in the points here + fprintf (fp, "\t\t\t\tcoord Coordinate {\n"); + fprintf (fp, "\t\t\t\t\tpoint [\n"); + + // We need to transverse all gamut hull. + for (i=0; i < SECTORS; i++) + for (j=0; j < SECTORS; j++) { + + cmsVEC3 v; + + pt = &gbd ->Gamut[i][j]; + ToCartesian(&v, &pt ->p); + + fprintf (fp, "\t\t\t\t\t%g %g %g", v.n[0]+50, v.n[1], v.n[2]); + + if ((j == SECTORS - 1) && (i == SECTORS - 1)) + fprintf (fp, "]\n"); + else + fprintf (fp, ",\n"); + + } + + fprintf (fp, "\t\t\t\t}\n"); + + + + // fill in the face colors + fprintf (fp, "\t\t\t\tcolor Color {\n"); + fprintf (fp, "\t\t\t\t\tcolor [\n"); + + for (i=0; i < SECTORS; i++) + for (j=0; j < SECTORS; j++) { + + cmsVEC3 v; + + pt = &gbd ->Gamut[i][j]; + + + ToCartesian(&v, &pt ->p); + + + if (pt ->Type == GP_EMPTY) + fprintf (fp, "\t\t\t\t\t%g %g %g", 0.0, 0.0, 0.0); + else + if (pt ->Type == GP_MODELED) + fprintf (fp, "\t\t\t\t\t%g %g %g", 1.0, .5, .5); + else { + fprintf (fp, "\t\t\t\t\t%g %g %g", 1.0, 1.0, 1.0); + + } + + if ((j == SECTORS - 1) && (i == SECTORS - 1)) + fprintf (fp, "]\n"); + else + fprintf (fp, ",\n"); + } + fprintf (fp, "\t\t\t}\n"); + + + fprintf (fp, "\t\t\t}\n"); + fprintf (fp, "\t\t}\n"); + fprintf (fp, "\t]\n"); + fprintf (fp, "}\n"); + + fclose (fp); + + return TRUE; +} +#endif + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmstypes.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmstypes.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmstypes.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmstypes.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,5848 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// Tag Serialization ----------------------------------------------------------------------------- +// This file implements every single tag and tag type as described in the ICC spec. Some types +// have been deprecated, like ncl and Data. There is no implementation for those types as there +// are no profiles holding them. The programmer can also extend this list by defining his own types +// by using the appropriate plug-in. There are three types of plug ins regarding that. First type +// allows to define new tags using any existing type. Next plug-in type allows to define new types +// and the third one is very specific: allows to extend the number of elements in the multiprocessing +// elements special type. +//-------------------------------------------------------------------------------------------------- + +// Some broken types +#define cmsCorbisBrokenXYZtype ((cmsTagTypeSignature) 0x17A505B8) +#define cmsMonacoBrokenCurveType ((cmsTagTypeSignature) 0x9478ee00) + +// This is the linked list that keeps track of the defined types +typedef struct _cmsTagTypeLinkedList_st { + + cmsTagTypeHandler Handler; + struct _cmsTagTypeLinkedList_st* Next; + +} _cmsTagTypeLinkedList; + +// Some macros to define callbacks. +#define READ_FN(x) Type_##x##_Read +#define WRITE_FN(x) Type_##x##_Write +#define FREE_FN(x) Type_##x##_Free +#define DUP_FN(x) Type_##x##_Dup + +// Helper macro to define a handler. Callbacks do have a fixed naming convention. +#define TYPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), DUP_FN(x), FREE_FN(x), NULL, 0 } + +// Helper macro to define a MPE handler. Callbacks do have a fixed naming convention +#define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 } + +// Infinites +#define MINUS_INF (-1E22F) +#define PLUS_INF (+1E22F) + + +// Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head +static +cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos) +{ + cmsPluginTagType* Plugin = (cmsPluginTagType*) Data; + _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(id, pos); + _cmsTagTypeLinkedList *pt; + + // Calling the function with NULL as plug-in would unregister the plug in. + if (Data == NULL) { + + // There is no need to set free the memory, as pool is destroyed as a whole. + ctx ->TagTypes = NULL; + return TRUE; + } + + // Registering happens in plug-in memory pool. + pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagTypeLinkedList)); + if (pt == NULL) return FALSE; + + pt ->Handler = Plugin ->Handler; + pt ->Next = ctx ->TagTypes; + + ctx ->TagTypes = pt; + + return TRUE; +} + +// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additons +// made by plug-ins and then the built-in defaults. +static +cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList) +{ + _cmsTagTypeLinkedList* pt; + + for (pt = PluginLinkedList; + pt != NULL; + pt = pt ->Next) { + + if (sig == pt -> Handler.Signature) return &pt ->Handler; + } + + for (pt = DefaultLinkedList; + pt != NULL; + pt = pt ->Next) { + + if (sig == pt -> Handler.Signature) return &pt ->Handler; + } + + return NULL; +} + + +// Auxiliary to convert UTF-32 to UTF-16 in some cases +static +cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array) +{ + cmsUInt32Number i; + + _cmsAssert(io != NULL); + _cmsAssert(!(Array == NULL && n > 0)); + + for (i=0; i < n; i++) { + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) Array[i])) return FALSE; + } + + return TRUE; +} + +// Try to promote correctly to wchar_t when 32 bits +cmsINLINE cmsBool is_surrogate(cmsUInt32Number uc) { return (uc - 0xd800u) < 2048u; } +cmsINLINE cmsBool is_high_surrogate(cmsUInt32Number uc) { return (uc & 0xfffffc00) == 0xd800; } +cmsINLINE cmsBool is_low_surrogate(cmsUInt32Number uc) { return (uc & 0xfffffc00) == 0xdc00; } + +cmsINLINE cmsUInt32Number surrogate_to_utf32(cmsUInt32Number high, cmsUInt32Number low) +{ + return (high << 10) + low - 0x35fdc00; +} + +cmsINLINE cmsBool convert_utf16_to_utf32(cmsIOHANDLER* io, cmsInt32Number n, wchar_t* output) +{ + cmsUInt16Number uc; + + while (n > 0) + { + if (!_cmsReadUInt16Number(io, &uc)) return FALSE; + n--; + + if (!is_surrogate(uc)) + { + *output++ = (wchar_t)uc; + } + else { + + cmsUInt16Number low; + + if (!_cmsReadUInt16Number(io, &low)) return FALSE; + n--; + + if (is_high_surrogate(uc) && is_low_surrogate(low)) + *output++ = (wchar_t)surrogate_to_utf32(uc, low); + else + return FALSE; // Corrupted string, just ignore + } + } + + return TRUE; +} + + +// Auxiliary to read an array of wchar_t +static +cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array) +{ + cmsUInt32Number i; + cmsUInt16Number tmp; + cmsBool is32 = sizeof(wchar_t) > sizeof(cmsUInt16Number); + + _cmsAssert(io != NULL); + + if (is32 && Array != NULL) + { + return convert_utf16_to_utf32(io, n, Array); + } + + for (i=0; i < n; i++) { + + if (Array != NULL) { + + if (!_cmsReadUInt16Number(io, &tmp)) return FALSE; + Array[i] = (wchar_t) tmp; + } + else { + if (!_cmsReadUInt16Number(io, NULL)) return FALSE; + } + + } + return TRUE; +} + +// To deal with position tables +typedef cmsBool (* PositionTableEntryFn)(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Cargo, + cmsUInt32Number n, + cmsUInt32Number SizeOfTag); + +// Helper function to deal with position tables as described in ICC spec 4.3 +// A table of n elements is read, where first comes n records containing offsets and sizes and +// then a block containing the data itself. This allows to reuse same data in more than one entry +static +cmsBool ReadPositionTable(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + cmsUInt32Number Count, + cmsUInt32Number BaseOffset, + void *Cargo, + PositionTableEntryFn ElementFn) +{ + cmsUInt32Number i; + cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; + cmsUInt32Number currentPosition; + + currentPosition = io->Tell(io); + + // Verify there is enough space left to read at least two cmsUInt32Number items for Count items. + if (((io->ReportedSize - currentPosition) / (2 * sizeof(cmsUInt32Number))) < Count) + return FALSE; + + // Let's take the offsets to each element + ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); + if (ElementOffsets == NULL) goto Error; + + ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); + if (ElementSizes == NULL) goto Error; + + for (i=0; i < Count; i++) { + + if (!_cmsReadUInt32Number(io, &ElementOffsets[i])) goto Error; + if (!_cmsReadUInt32Number(io, &ElementSizes[i])) goto Error; + + ElementOffsets[i] += BaseOffset; + } + + // Seek to each element and read it + for (i=0; i < Count; i++) { + + if (!io -> Seek(io, ElementOffsets[i])) goto Error; + + // This is the reader callback + if (!ElementFn(self, io, Cargo, i, ElementSizes[i])) goto Error; + } + + // Success + if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); + if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); + return TRUE; + +Error: + if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); + if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); + return FALSE; +} + +// Same as anterior, but for write position tables +static +cmsBool WritePositionTable(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + cmsUInt32Number SizeOfTag, + cmsUInt32Number Count, + cmsUInt32Number BaseOffset, + void *Cargo, + PositionTableEntryFn ElementFn) +{ + cmsUInt32Number i; + cmsUInt32Number DirectoryPos, CurrentPos, Before; + cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; + + // Create table + ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); + if (ElementOffsets == NULL) goto Error; + + ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); + if (ElementSizes == NULL) goto Error; + + // Keep starting position of curve offsets + DirectoryPos = io ->Tell(io); + + // Write a fake directory to be filled latter on + for (i=0; i < Count; i++) { + + if (!_cmsWriteUInt32Number(io, 0)) goto Error; // Offset + if (!_cmsWriteUInt32Number(io, 0)) goto Error; // size + } + + // Write each element. Keep track of the size as well. + for (i=0; i < Count; i++) { + + Before = io ->Tell(io); + ElementOffsets[i] = Before - BaseOffset; + + // Callback to write... + if (!ElementFn(self, io, Cargo, i, SizeOfTag)) goto Error; + + // Now the size + ElementSizes[i] = io ->Tell(io) - Before; + } + + // Write the directory + CurrentPos = io ->Tell(io); + if (!io ->Seek(io, DirectoryPos)) goto Error; + + for (i=0; i < Count; i++) { + if (!_cmsWriteUInt32Number(io, ElementOffsets[i])) goto Error; + if (!_cmsWriteUInt32Number(io, ElementSizes[i])) goto Error; + } + + if (!io ->Seek(io, CurrentPos)) goto Error; + + if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); + if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); + return TRUE; + +Error: + if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); + if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); + return FALSE; +} + + +// ******************************************************************************** +// Type XYZ. Only one value is allowed +// ******************************************************************************** + +//The XYZType contains an array of three encoded values for the XYZ tristimulus +//values. Tristimulus values must be non-negative. The signed encoding allows for +//implementation optimizations by minimizing the number of fixed formats. + + +static +void *Type_XYZ_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsCIEXYZ* xyz; + + *nItems = 0; + xyz = (cmsCIEXYZ*) _cmsMallocZero(self ->ContextID, sizeof(cmsCIEXYZ)); + if (xyz == NULL) return NULL; + + if (!_cmsReadXYZNumber(io, xyz)) { + _cmsFree(self ->ContextID, xyz); + return NULL; + } + + *nItems = 1; + return (void*) xyz; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +static +cmsBool Type_XYZ_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + return _cmsWriteXYZNumber(io, (cmsCIEXYZ*) Ptr); + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_XYZ_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsCIEXYZ)); + + cmsUNUSED_PARAMETER(n); +} + +static +void Type_XYZ_Free(struct _cms_typehandler_struct* self, void *Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + + +static +cmsTagTypeSignature DecideXYZtype(cmsFloat64Number ICCVersion, const void *Data) +{ + return cmsSigXYZType; + + cmsUNUSED_PARAMETER(ICCVersion); + cmsUNUSED_PARAMETER(Data); +} + + +// ******************************************************************************** +// Type chromaticity. Only one value is allowed +// ******************************************************************************** +// The chromaticity tag type provides basic chromaticity data and type of +// phosphors or colorants of a monitor to applications and utilities. + +static +void *Type_Chromaticity_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsCIExyYTRIPLE* chrm; + cmsUInt16Number nChans, Table; + + *nItems = 0; + chrm = (cmsCIExyYTRIPLE*) _cmsMallocZero(self ->ContextID, sizeof(cmsCIExyYTRIPLE)); + if (chrm == NULL) return NULL; + + if (!_cmsReadUInt16Number(io, &nChans)) goto Error; + + // Let's recover from a bug introduced in early versions of lcms1 + if (nChans == 0 && SizeOfTag == 32) { + + if (!_cmsReadUInt16Number(io, NULL)) goto Error; + if (!_cmsReadUInt16Number(io, &nChans)) goto Error; + } + + if (nChans != 3) goto Error; + + if (!_cmsReadUInt16Number(io, &Table)) goto Error; + + if (!_cmsRead15Fixed16Number(io, &chrm ->Red.x)) goto Error; + if (!_cmsRead15Fixed16Number(io, &chrm ->Red.y)) goto Error; + + chrm ->Red.Y = 1.0; + + if (!_cmsRead15Fixed16Number(io, &chrm ->Green.x)) goto Error; + if (!_cmsRead15Fixed16Number(io, &chrm ->Green.y)) goto Error; + + chrm ->Green.Y = 1.0; + + if (!_cmsRead15Fixed16Number(io, &chrm ->Blue.x)) goto Error; + if (!_cmsRead15Fixed16Number(io, &chrm ->Blue.y)) goto Error; + + chrm ->Blue.Y = 1.0; + + *nItems = 1; + return (void*) chrm; + +Error: + _cmsFree(self ->ContextID, (void*) chrm); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +static +cmsBool SaveOneChromaticity(cmsFloat64Number x, cmsFloat64Number y, cmsIOHANDLER* io) +{ + if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(x))) return FALSE; + if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(y))) return FALSE; + + return TRUE; +} + +static +cmsBool Type_Chromaticity_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsCIExyYTRIPLE* chrm = (cmsCIExyYTRIPLE*) Ptr; + + if (!_cmsWriteUInt16Number(io, 3)) return FALSE; // nChannels + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; // Table + + if (!SaveOneChromaticity(chrm -> Red.x, chrm -> Red.y, io)) return FALSE; + if (!SaveOneChromaticity(chrm -> Green.x, chrm -> Green.y, io)) return FALSE; + if (!SaveOneChromaticity(chrm -> Blue.x, chrm -> Blue.y, io)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_Chromaticity_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsCIExyYTRIPLE)); + + cmsUNUSED_PARAMETER(n); +} + +static +void Type_Chromaticity_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + + +// ******************************************************************************** +// Type cmsSigColorantOrderType +// ******************************************************************************** + +// This is an optional tag which specifies the laydown order in which colorants will +// be printed on an n-colorant device. The laydown order may be the same as the +// channel generation order listed in the colorantTableTag or the channel order of a +// colour space such as CMYK, in which case this tag is not needed. When this is not +// the case (for example, ink-towers sometimes use the order KCMY), this tag may be +// used to specify the laydown order of the colorants. + + +static +void *Type_ColorantOrderType_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt8Number* ColorantOrder; + cmsUInt32Number Count; + + *nItems = 0; + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + if (Count > cmsMAXCHANNELS) return NULL; + + ColorantOrder = (cmsUInt8Number*) _cmsCalloc(self ->ContextID, cmsMAXCHANNELS, sizeof(cmsUInt8Number)); + if (ColorantOrder == NULL) return NULL; + + // We use FF as end marker + memset(ColorantOrder, 0xFF, cmsMAXCHANNELS * sizeof(cmsUInt8Number)); + + if (io ->Read(io, ColorantOrder, sizeof(cmsUInt8Number), Count) != Count) { + + _cmsFree(self ->ContextID, (void*) ColorantOrder); + return NULL; + } + + *nItems = 1; + return (void*) ColorantOrder; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +static +cmsBool Type_ColorantOrderType_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUInt8Number* ColorantOrder = (cmsUInt8Number*) Ptr; + cmsUInt32Number i, sz, Count; + + // Get the length + for (Count=i=0; i < cmsMAXCHANNELS; i++) { + if (ColorantOrder[i] != 0xFF) Count++; + } + + if (!_cmsWriteUInt32Number(io, Count)) return FALSE; + + sz = Count * sizeof(cmsUInt8Number); + if (!io -> Write(io, sz, ColorantOrder)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_ColorantOrderType_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, cmsMAXCHANNELS * sizeof(cmsUInt8Number)); + + cmsUNUSED_PARAMETER(n); +} + + +static +void Type_ColorantOrderType_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + +// ******************************************************************************** +// Type cmsSigS15Fixed16ArrayType +// ******************************************************************************** +// This type represents an array of generic 4-byte/32-bit fixed point quantity. +// The number of values is determined from the size of the tag. + +static +void *Type_S15Fixed16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsFloat64Number* array_double; + cmsUInt32Number i, n; + + *nItems = 0; + n = SizeOfTag / sizeof(cmsUInt32Number); + array_double = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, n, sizeof(cmsFloat64Number)); + if (array_double == NULL) return NULL; + + for (i=0; i < n; i++) { + + if (!_cmsRead15Fixed16Number(io, &array_double[i])) { + + _cmsFree(self ->ContextID, array_double); + return NULL; + } + } + + *nItems = n; + return (void*) array_double; +} + +static +cmsBool Type_S15Fixed16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsFloat64Number* Value = (cmsFloat64Number*) Ptr; + cmsUInt32Number i; + + for (i=0; i < nItems; i++) { + + if (!_cmsWrite15Fixed16Number(io, Value[i])) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_S15Fixed16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsFloat64Number)); +} + + +static +void Type_S15Fixed16_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + +// ******************************************************************************** +// Type cmsSigU16Fixed16ArrayType +// ******************************************************************************** +// This type represents an array of generic 4-byte/32-bit quantity. +// The number of values is determined from the size of the tag. + + +static +void *Type_U16Fixed16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsFloat64Number* array_double; + cmsUInt32Number v; + cmsUInt32Number i, n; + + *nItems = 0; + n = SizeOfTag / sizeof(cmsUInt32Number); + array_double = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, n, sizeof(cmsFloat64Number)); + if (array_double == NULL) return NULL; + + for (i=0; i < n; i++) { + + if (!_cmsReadUInt32Number(io, &v)) { + _cmsFree(self ->ContextID, (void*) array_double); + return NULL; + } + + // Convert to cmsFloat64Number + array_double[i] = (cmsFloat64Number) (v / 65536.0); + } + + *nItems = n; + return (void*) array_double; +} + +static +cmsBool Type_U16Fixed16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsFloat64Number* Value = (cmsFloat64Number*) Ptr; + cmsUInt32Number i; + + for (i=0; i < nItems; i++) { + + cmsUInt32Number v = (cmsUInt32Number) floor(Value[i]*65536.0 + 0.5); + + if (!_cmsWriteUInt32Number(io, v)) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(self); +} + + +static +void* Type_U16Fixed16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsFloat64Number)); +} + +static +void Type_U16Fixed16_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + +// ******************************************************************************** +// Type cmsSigSignatureType +// ******************************************************************************** +// +// The signatureType contains a four-byte sequence, Sequences of less than four +// characters are padded at the end with spaces, 20h. +// Typically this type is used for registered tags that can be displayed on many +// development systems as a sequence of four characters. + +static +void *Type_Signature_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsSignature* SigPtr = (cmsSignature*) _cmsMalloc(self ->ContextID, sizeof(cmsSignature)); + if (SigPtr == NULL) return NULL; + + if (!_cmsReadUInt32Number(io, SigPtr)) return NULL; + *nItems = 1; + + return SigPtr; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +static +cmsBool Type_Signature_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsSignature* SigPtr = (cmsSignature*) Ptr; + + return _cmsWriteUInt32Number(io, *SigPtr); + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_Signature_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsSignature)); +} + +static +void Type_Signature_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + + +// ******************************************************************************** +// Type cmsSigTextType +// ******************************************************************************** +// +// The textType is a simple text structure that contains a 7-bit ASCII text string. +// The length of the string is obtained by subtracting 8 from the element size portion +// of the tag itself. This string must be terminated with a 00h byte. + +static +void *Type_Text_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + char* Text = NULL; + cmsMLU* mlu = NULL; + + // Create a container + mlu = cmsMLUalloc(self ->ContextID, 1); + if (mlu == NULL) return NULL; + + *nItems = 0; + + // We need to store the "\0" at the end, so +1 + if (SizeOfTag == UINT_MAX) goto Error; + + Text = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1); + if (Text == NULL) goto Error; + + if (io -> Read(io, Text, sizeof(char), SizeOfTag) != SizeOfTag) goto Error; + + // Make sure text is properly ended + Text[SizeOfTag] = 0; + *nItems = 1; + + // Keep the result + if (!cmsMLUsetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text)) goto Error; + + _cmsFree(self ->ContextID, Text); + return (void*) mlu; + +Error: + if (mlu != NULL) + cmsMLUfree(mlu); + if (Text != NULL) + _cmsFree(self ->ContextID, Text); + + return NULL; +} + +// The conversion implies to choose a language. So, we choose the actual language. +static +cmsBool Type_Text_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsMLU* mlu = (cmsMLU*) Ptr; + cmsUInt32Number size; + cmsBool rc; + char* Text; + + // Get the size of the string. Note there is an extra "\0" at the end + size = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0); + if (size == 0) return FALSE; // Cannot be zero! + + // Create memory + Text = (char*) _cmsMalloc(self ->ContextID, size); + if (Text == NULL) return FALSE; + + cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, size); + + // Write it, including separator + rc = io ->Write(io, size, Text); + + _cmsFree(self ->ContextID, Text); + return rc; + + cmsUNUSED_PARAMETER(nItems); +} + +static +void* Type_Text_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsMLUdup((cmsMLU*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + + +static +void Type_Text_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsMLU* mlu = (cmsMLU*) Ptr; + cmsMLUfree(mlu); + return; + + cmsUNUSED_PARAMETER(self); +} + +static +cmsTagTypeSignature DecideTextType(cmsFloat64Number ICCVersion, const void *Data) +{ + if (ICCVersion >= 4.0) + return cmsSigMultiLocalizedUnicodeType; + + return cmsSigTextType; + + cmsUNUSED_PARAMETER(Data); +} + + +// ******************************************************************************** +// Type cmsSigDataType +// ******************************************************************************** + +// General purpose data type +static +void *Type_Data_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsICCData* BinData; + cmsUInt32Number LenOfData; + + *nItems = 0; + + if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; + + LenOfData = SizeOfTag - sizeof(cmsUInt32Number); + if (LenOfData > INT_MAX) return NULL; + + BinData = (cmsICCData*) _cmsMalloc(self ->ContextID, sizeof(cmsICCData) + LenOfData - 1); + if (BinData == NULL) return NULL; + + BinData ->len = LenOfData; + if (!_cmsReadUInt32Number(io, &BinData->flag)) { + _cmsFree(self ->ContextID, BinData); + return NULL; + } + + if (io -> Read(io, BinData ->data, sizeof(cmsUInt8Number), LenOfData) != LenOfData) { + + _cmsFree(self ->ContextID, BinData); + return NULL; + } + + *nItems = 1; + + return (void*) BinData; +} + + +static +cmsBool Type_Data_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsICCData* BinData = (cmsICCData*) Ptr; + + if (!_cmsWriteUInt32Number(io, BinData ->flag)) return FALSE; + + return io ->Write(io, BinData ->len, BinData ->data); + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + +static +void* Type_Data_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + cmsICCData* BinData = (cmsICCData*) Ptr; + + return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsICCData) + BinData ->len - 1); + + cmsUNUSED_PARAMETER(n); +} + +static +void Type_Data_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + +// ******************************************************************************** +// Type cmsSigTextDescriptionType +// ******************************************************************************** + +static +void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + char* Text = NULL; + cmsMLU* mlu = NULL; + cmsUInt32Number AsciiCount; + cmsUInt32Number i, UnicodeCode, UnicodeCount; + cmsUInt16Number ScriptCodeCode, Dummy; + cmsUInt8Number ScriptCodeCount; + + *nItems = 0; + + // One dword should be there + if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; + + // Read len of ASCII + if (!_cmsReadUInt32Number(io, &AsciiCount)) return NULL; + SizeOfTag -= sizeof(cmsUInt32Number); + + // Check for size + if (SizeOfTag < AsciiCount) return NULL; + + // All seems Ok, allocate the container + mlu = cmsMLUalloc(self ->ContextID, 1); + if (mlu == NULL) return NULL; + + // As many memory as size of tag + Text = (char*) _cmsMalloc(self ->ContextID, AsciiCount + 1); + if (Text == NULL) goto Error; + + // Read it + if (io ->Read(io, Text, sizeof(char), AsciiCount) != AsciiCount) goto Error; + SizeOfTag -= AsciiCount; + + // Make sure there is a terminator + Text[AsciiCount] = 0; + + // Set the MLU entry. From here we can be tolerant to wrong types + if (!cmsMLUsetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text)) goto Error; + _cmsFree(self ->ContextID, (void*) Text); + Text = NULL; + + // Skip Unicode code + if (SizeOfTag < 2* sizeof(cmsUInt32Number)) goto Done; + if (!_cmsReadUInt32Number(io, &UnicodeCode)) goto Done; + if (!_cmsReadUInt32Number(io, &UnicodeCount)) goto Done; + SizeOfTag -= 2* sizeof(cmsUInt32Number); + + if (SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done; + + for (i=0; i < UnicodeCount; i++) { + if (!io ->Read(io, &Dummy, sizeof(cmsUInt16Number), 1)) goto Done; + } + SizeOfTag -= UnicodeCount*sizeof(cmsUInt16Number); + + // Skip ScriptCode code if present. Some buggy profiles does have less + // data that stricttly required. We need to skip it as this type may come + // embedded in other types. + + if (SizeOfTag >= sizeof(cmsUInt16Number) + sizeof(cmsUInt8Number) + 67) { + + if (!_cmsReadUInt16Number(io, &ScriptCodeCode)) goto Done; + if (!_cmsReadUInt8Number(io, &ScriptCodeCount)) goto Done; + + // Skip rest of tag + for (i=0; i < 67; i++) { + if (!io ->Read(io, &Dummy, sizeof(cmsUInt8Number), 1)) goto Error; + } + } + +Done: + + *nItems = 1; + return mlu; + +Error: + if (Text) _cmsFree(self ->ContextID, (void*) Text); + if (mlu) cmsMLUfree(mlu); + return NULL; +} + + +// This tag can come IN UNALIGNED SIZE. In order to prevent issues, we force zeros on description to align it +static +cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsMLU* mlu = (cmsMLU*) Ptr; + char *Text = NULL; + wchar_t *Wide = NULL; + cmsUInt32Number len, len_text, len_tag_requirement, len_aligned; + cmsBool rc = FALSE; + char Filler[68]; + + // Used below for writing zeroes + memset(Filler, 0, sizeof(Filler)); + + // Get the len of string + len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0); + + // Specification ICC.1:2001-04 (v2.4.0): It has been found that textDescriptionType can contain misaligned data + //(see clause 4.1 for the definition of 'aligned'). Because the Unicode language + // code and Unicode count immediately follow the ASCII description, their + // alignment is not correct if the ASCII count is not a multiple of four. The + // ScriptCode code is misaligned when the ASCII count is odd. Profile reading and + // writing software must be written carefully in order to handle these alignment + // problems. + // + // The above last sentence suggest to handle alignment issues in the + // parser. The provided example (Table 69 on Page 60) makes this clear. + // The padding only in the ASCII count is not sufficient for a aligned tag + // size, with the same text size in ASCII and Unicode. + + // Null strings + if (len <= 0) { + + Text = (char*) _cmsDupMem(self ->ContextID, "", sizeof(char)); + Wide = (wchar_t*) _cmsDupMem(self ->ContextID, L"", sizeof(wchar_t)); + } + else { + // Create independent buffers + Text = (char*) _cmsCalloc(self ->ContextID, len, sizeof(char)); + if (Text == NULL) goto Error; + + Wide = (wchar_t*) _cmsCalloc(self ->ContextID, len, sizeof(wchar_t)); + if (Wide == NULL) goto Error; + + // Get both representations. + cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, len * sizeof(char)); + cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t)); + } + + // Tell the real text len including the null terminator and padding + len_text = (cmsUInt32Number) strlen(Text) + 1; + // Compute an total tag size requirement + len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67); + len_aligned = _cmsALIGNLONG(len_tag_requirement); + + // * cmsUInt32Number count; * Description length + // * cmsInt8Number desc[count] * NULL terminated ascii string + // * cmsUInt32Number ucLangCode; * UniCode language code + // * cmsUInt32Number ucCount; * UniCode description length + // * cmsInt16Number ucDesc[ucCount];* The UniCode description + // * cmsUInt16Number scCode; * ScriptCode code + // * cmsUInt8Number scCount; * ScriptCode count + // * cmsInt8Number scDesc[67]; * ScriptCode Description + + if (!_cmsWriteUInt32Number(io, len_text)) goto Error; + if (!io ->Write(io, len_text, Text)) goto Error; + + if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode + + if (!_cmsWriteUInt32Number(io, len_text)) goto Error; + // Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t) + if (!_cmsWriteWCharArray(io, len_text, Wide)) goto Error; + + // ScriptCode Code & count (unused) + if (!_cmsWriteUInt16Number(io, 0)) goto Error; + if (!_cmsWriteUInt8Number(io, 0)) goto Error; + + if (!io ->Write(io, 67, Filler)) goto Error; + + // possibly add pad at the end of tag + if(len_aligned - len_tag_requirement > 0) + if (!io ->Write(io, len_aligned - len_tag_requirement, Filler)) goto Error; + + rc = TRUE; + +Error: + if (Text) _cmsFree(self ->ContextID, Text); + if (Wide) _cmsFree(self ->ContextID, Wide); + + return rc; + + cmsUNUSED_PARAMETER(nItems); +} + + +static +void* Type_Text_Description_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsMLUdup((cmsMLU*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_Text_Description_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsMLU* mlu = (cmsMLU*) Ptr; + + cmsMLUfree(mlu); + return; + + cmsUNUSED_PARAMETER(self); +} + + +static +cmsTagTypeSignature DecideTextDescType(cmsFloat64Number ICCVersion, const void *Data) +{ + if (ICCVersion >= 4.0) + return cmsSigMultiLocalizedUnicodeType; + + return cmsSigTextDescriptionType; + + cmsUNUSED_PARAMETER(Data); +} + + +// ******************************************************************************** +// Type cmsSigCurveType +// ******************************************************************************** + +static +void *Type_Curve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt32Number Count; + cmsToneCurve* NewGamma; + + *nItems = 0; + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + + switch (Count) { + + case 0: // Linear. + { + cmsFloat64Number SingleGamma = 1.0; + + NewGamma = cmsBuildParametricToneCurve(self ->ContextID, 1, &SingleGamma); + if (!NewGamma) return NULL; + *nItems = 1; + return NewGamma; + } + + case 1: // Specified as the exponent of gamma function + { + cmsUInt16Number SingleGammaFixed; + cmsFloat64Number SingleGamma; + + if (!_cmsReadUInt16Number(io, &SingleGammaFixed)) return NULL; + SingleGamma = _cms8Fixed8toDouble(SingleGammaFixed); + + *nItems = 1; + return cmsBuildParametricToneCurve(self ->ContextID, 1, &SingleGamma); + } + + default: // Curve + + if (Count > 0x7FFF) + return NULL; // This is to prevent bad guys for doing bad things + + NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL); + if (!NewGamma) return NULL; + + if (!_cmsReadUInt16Array(io, Count, NewGamma -> Table16)) { + cmsFreeToneCurve(NewGamma); + return NULL; + } + + *nItems = 1; + return NewGamma; + } + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +static +cmsBool Type_Curve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsToneCurve* Curve = (cmsToneCurve*) Ptr; + + if (Curve ->nSegments == 1 && Curve ->Segments[0].Type == 1) { + + // Single gamma, preserve number + cmsUInt16Number SingleGammaFixed = _cmsDoubleTo8Fixed8(Curve ->Segments[0].Params[0]); + + if (!_cmsWriteUInt32Number(io, 1)) return FALSE; + if (!_cmsWriteUInt16Number(io, SingleGammaFixed)) return FALSE; + return TRUE; + + } + + if (!_cmsWriteUInt32Number(io, Curve ->nEntries)) return FALSE; + return _cmsWriteUInt16Array(io, Curve ->nEntries, Curve ->Table16); + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + +static +void* Type_Curve_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsDupToneCurve((cmsToneCurve*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_Curve_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsToneCurve* gamma = (cmsToneCurve*) Ptr; + + cmsFreeToneCurve(gamma); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigParametricCurveType +// ******************************************************************************** + + +// Decide which curve type to use on writing +static +cmsTagTypeSignature DecideCurveType(cmsFloat64Number ICCVersion, const void *Data) +{ + cmsToneCurve* Curve = (cmsToneCurve*) Data; + + if (ICCVersion < 4.0) return cmsSigCurveType; + if (Curve ->nSegments != 1) return cmsSigCurveType; // Only 1-segment curves can be saved as parametric + if (Curve ->Segments[0].Type < 0) return cmsSigCurveType; // Only non-inverted curves + if (Curve ->Segments[0].Type > 5) return cmsSigCurveType; // Only ICC parametric curves + + return cmsSigParametricCurveType; +} + +static +void *Type_ParametricCurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + static const int ParamsByType[] = { 1, 3, 4, 5, 7 }; + cmsFloat64Number Params[10]; + cmsUInt16Number Type; + int i, n; + cmsToneCurve* NewGamma; + + if (!_cmsReadUInt16Number(io, &Type)) return NULL; + if (!_cmsReadUInt16Number(io, NULL)) return NULL; // Reserved + + if (Type > 4) { + + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown parametric curve type '%d'", Type); + return NULL; + } + + memset(Params, 0, sizeof(Params)); + n = ParamsByType[Type]; + + for (i=0; i < n; i++) { + + if (!_cmsRead15Fixed16Number(io, &Params[i])) return NULL; + } + + NewGamma = cmsBuildParametricToneCurve(self ->ContextID, Type+1, Params); + + *nItems = 1; + return NewGamma; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +static +cmsBool Type_ParametricCurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsToneCurve* Curve = (cmsToneCurve*) Ptr; + int i, nParams, typen; + static const int ParamsByType[] = { 0, 1, 3, 4, 5, 7 }; + + typen = Curve -> Segments[0].Type; + + if (Curve ->nSegments > 1 || typen < 1) { + + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Multisegment or Inverted parametric curves cannot be written"); + return FALSE; + } + + if (typen > 5) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported parametric curve"); + return FALSE; + } + + nParams = ParamsByType[typen]; + + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) (Curve ->Segments[0].Type - 1))) return FALSE; + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; // Reserved + + for (i=0; i < nParams; i++) { + + if (!_cmsWrite15Fixed16Number(io, Curve -> Segments[0].Params[i])) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + +static +void* Type_ParametricCurve_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsDupToneCurve((cmsToneCurve*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_ParametricCurve_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsToneCurve* gamma = (cmsToneCurve*) Ptr; + + cmsFreeToneCurve(gamma); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigDateTimeType +// ******************************************************************************** + +// A 12-byte value representation of the time and date, where the byte usage is assigned +// as specified in table 1. The actual values are encoded as 16-bit unsigned integers +// (uInt16Number - see 5.1.6). +// +// All the dateTimeNumber values in a profile shall be in Coordinated Universal Time +// (UTC, also known as GMT or ZULU Time). Profile writers are required to convert local +// time to UTC when setting these values. Programs that display these values may show +// the dateTimeNumber as UTC, show the equivalent local time (at current locale), or +// display both UTC and local versions of the dateTimeNumber. + +static +void *Type_DateTime_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsDateTimeNumber timestamp; + struct tm * NewDateTime; + + *nItems = 0; + NewDateTime = (struct tm*) _cmsMalloc(self ->ContextID, sizeof(struct tm)); + if (NewDateTime == NULL) return NULL; + + if (io->Read(io, ×tamp, sizeof(cmsDateTimeNumber), 1) != 1) return NULL; + + _cmsDecodeDateTimeNumber(×tamp, NewDateTime); + + *nItems = 1; + return NewDateTime; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +static +cmsBool Type_DateTime_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + struct tm * DateTime = (struct tm*) Ptr; + cmsDateTimeNumber timestamp; + + _cmsEncodeDateTimeNumber(×tamp, DateTime); + if (!io ->Write(io, sizeof(cmsDateTimeNumber), ×tamp)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_DateTime_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, sizeof(struct tm)); + + cmsUNUSED_PARAMETER(n); +} + +static +void Type_DateTime_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + + + +// ******************************************************************************** +// Type icMeasurementType +// ******************************************************************************** + +/* +The measurementType information refers only to the internal profile data and is +meant to provide profile makers an alternative to the default measurement +specifications. +*/ + +static +void *Type_Measurement_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsICCMeasurementConditions mc; + + + memset(&mc, 0, sizeof(mc)); + + if (!_cmsReadUInt32Number(io, &mc.Observer)) return NULL; + if (!_cmsReadXYZNumber(io, &mc.Backing)) return NULL; + if (!_cmsReadUInt32Number(io, &mc.Geometry)) return NULL; + if (!_cmsRead15Fixed16Number(io, &mc.Flare)) return NULL; + if (!_cmsReadUInt32Number(io, &mc.IlluminantType)) return NULL; + + *nItems = 1; + return _cmsDupMem(self ->ContextID, &mc, sizeof(cmsICCMeasurementConditions)); + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +static +cmsBool Type_Measurement_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsICCMeasurementConditions* mc =(cmsICCMeasurementConditions*) Ptr; + + if (!_cmsWriteUInt32Number(io, mc->Observer)) return FALSE; + if (!_cmsWriteXYZNumber(io, &mc->Backing)) return FALSE; + if (!_cmsWriteUInt32Number(io, mc->Geometry)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, mc->Flare)) return FALSE; + if (!_cmsWriteUInt32Number(io, mc->IlluminantType)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_Measurement_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsICCMeasurementConditions)); + + cmsUNUSED_PARAMETER(n); +} + +static +void Type_Measurement_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + + +// ******************************************************************************** +// Type cmsSigMultiLocalizedUnicodeType +// ******************************************************************************** +// +// Do NOT trust SizeOfTag as there is an issue on the definition of profileSequenceDescTag. See the TechNote from +// Max Derhak and Rohit Patil about this: basically the size of the string table should be guessed and cannot be +// taken from the size of tag if this tag is embedded as part of bigger structures (profileSequenceDescTag, for instance) +// + +static +void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsMLU* mlu; + cmsUInt32Number Count, RecLen, NumOfWchar; + cmsUInt32Number SizeOfHeader; + cmsUInt32Number Len, Offset; + cmsUInt32Number i; + wchar_t* Block; + cmsUInt32Number BeginOfThisString, EndOfThisString, LargestPosition; + + *nItems = 0; + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + if (!_cmsReadUInt32Number(io, &RecLen)) return NULL; + + if (RecLen != 12) { + + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "multiLocalizedUnicodeType of len != 12 is not supported."); + return NULL; + } + + mlu = cmsMLUalloc(self ->ContextID, Count); + if (mlu == NULL) return NULL; + + mlu ->UsedEntries = Count; + + SizeOfHeader = 12 * Count + sizeof(_cmsTagBase); + LargestPosition = 0; + + for (i=0; i < Count; i++) { + + if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Language)) goto Error; + if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Country)) goto Error; + + // Now deal with Len and offset. + if (!_cmsReadUInt32Number(io, &Len)) goto Error; + if (!_cmsReadUInt32Number(io, &Offset)) goto Error; + + // Offset MUST be even because it indexes a block of utf16 chars. + // Tricky profiles that uses odd positions will not work anyway + // because the whole utf16 block is previously converted to wchar_t + // and sizeof this type may be of 4 bytes. On Linux systems, for example. + if (Offset & 1) goto Error; + + // Check for overflow + if (Offset < (SizeOfHeader + 8)) goto Error; + if (((Offset + Len) < Len) || ((Offset + Len) > SizeOfTag + 8)) goto Error; + + // True begin of the string + BeginOfThisString = Offset - SizeOfHeader - 8; + + // Adjust to wchar_t elements + mlu ->Entries[i].Len = (Len * sizeof(wchar_t)) / sizeof(cmsUInt16Number); + mlu ->Entries[i].StrW = (BeginOfThisString * sizeof(wchar_t)) / sizeof(cmsUInt16Number); + + // To guess maximum size, add offset + len + EndOfThisString = BeginOfThisString + Len; + if (EndOfThisString > LargestPosition) + LargestPosition = EndOfThisString; + } + + // Now read the remaining of tag and fill all strings. Subtract the directory + SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number); + if (SizeOfTag == 0) + { + Block = NULL; + NumOfWchar = 0; + + } + else + { + // Make sure this is an even utf16 size. + if (SizeOfTag & 1) goto Error; + + Block = (wchar_t*) _cmsCalloc(self ->ContextID, 1, SizeOfTag); + if (Block == NULL) goto Error; + + NumOfWchar = SizeOfTag / sizeof(wchar_t); + if (!_cmsReadWCharArray(io, NumOfWchar, Block)) { + _cmsFree(self->ContextID, Block); + goto Error; + } + } + + mlu ->MemPool = Block; + mlu ->PoolSize = SizeOfTag; + mlu ->PoolUsed = SizeOfTag; + + *nItems = 1; + return (void*) mlu; + +Error: + if (mlu) cmsMLUfree(mlu); + return NULL; +} + +static +cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsMLU* mlu =(cmsMLU*) Ptr; + cmsUInt32Number HeaderSize; + cmsUInt32Number Len, Offset; + cmsUInt32Number i; + + if (Ptr == NULL) { + + // Empty placeholder + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 12)) return FALSE; + return TRUE; + } + + if (!_cmsWriteUInt32Number(io, mlu ->UsedEntries)) return FALSE; + if (!_cmsWriteUInt32Number(io, 12)) return FALSE; + + HeaderSize = 12 * mlu ->UsedEntries + sizeof(_cmsTagBase); + + for (i=0; i < mlu ->UsedEntries; i++) { + + Len = mlu ->Entries[i].Len; + Offset = mlu ->Entries[i].StrW; + + Len = (Len * sizeof(cmsUInt16Number)) / sizeof(wchar_t); + Offset = (Offset * sizeof(cmsUInt16Number)) / sizeof(wchar_t) + HeaderSize + 8; + + if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Language)) return FALSE; + if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Country)) return FALSE; + if (!_cmsWriteUInt32Number(io, Len)) return FALSE; + if (!_cmsWriteUInt32Number(io, Offset)) return FALSE; + } + + if (!_cmsWriteWCharArray(io, mlu ->PoolUsed / sizeof(wchar_t), (wchar_t*) mlu ->MemPool)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + +static +void* Type_MLU_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsMLUdup((cmsMLU*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_MLU_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsMLUfree((cmsMLU*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigLut8Type +// ******************************************************************************** + +// Decide which LUT type to use on writing +static +cmsTagTypeSignature DecideLUTtypeA2B(cmsFloat64Number ICCVersion, const void *Data) +{ + cmsPipeline* Lut = (cmsPipeline*) Data; + + if (ICCVersion < 4.0) { + if (Lut ->SaveAs8Bits) return cmsSigLut8Type; + return cmsSigLut16Type; + } + else { + return cmsSigLutAtoBType; + } +} + +static +cmsTagTypeSignature DecideLUTtypeB2A(cmsFloat64Number ICCVersion, const void *Data) +{ + cmsPipeline* Lut = (cmsPipeline*) Data; + + if (ICCVersion < 4.0) { + if (Lut ->SaveAs8Bits) return cmsSigLut8Type; + return cmsSigLut16Type; + } + else { + return cmsSigLutBtoAType; + } +} + +/* +This structure represents a colour transform using tables of 8-bit precision. +This type contains four processing elements: a 3 by 3 matrix (which shall be +the identity matrix unless the input colour space is XYZ), a set of one dimensional +input tables, a multidimensional lookup table, and a set of one dimensional output +tables. Data is processed using these elements via the following sequence: +(matrix) -> (1d input tables) -> (multidimensional lookup table - CLUT) -> (1d output tables) + +Byte Position Field Length (bytes) Content Encoded as... +8 1 Number of Input Channels (i) uInt8Number +9 1 Number of Output Channels (o) uInt8Number +10 1 Number of CLUT grid points (identical for each side) (g) uInt8Number +11 1 Reserved for padding (fill with 00h) + +12..15 4 Encoded e00 parameter s15Fixed16Number +*/ + + +// Read 8 bit tables as gamma functions +static +cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, cmsUInt32Number nChannels) +{ + cmsUInt8Number* Temp = NULL; + cmsUInt32Number i, j; + cmsToneCurve* Tables[cmsMAXCHANNELS]; + + if (nChannels > cmsMAXCHANNELS) return FALSE; + if (nChannels <= 0) return FALSE; + + memset(Tables, 0, sizeof(Tables)); + + Temp = (cmsUInt8Number*) _cmsMalloc(ContextID, 256); + if (Temp == NULL) return FALSE; + + for (i=0; i < nChannels; i++) { + Tables[i] = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL); + if (Tables[i] == NULL) goto Error; + } + + for (i=0; i < nChannels; i++) { + + if (io ->Read(io, Temp, 256, 1) != 1) goto Error; + + for (j=0; j < 256; j++) + Tables[i]->Table16[j] = (cmsUInt16Number) FROM_8_TO_16(Temp[j]); + } + + _cmsFree(ContextID, Temp); + Temp = NULL; + + if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables))) + goto Error; + + for (i=0; i < nChannels; i++) + cmsFreeToneCurve(Tables[i]); + + return TRUE; + +Error: + for (i=0; i < nChannels; i++) { + if (Tables[i]) cmsFreeToneCurve(Tables[i]); + } + + if (Temp) _cmsFree(ContextID, Temp); + return FALSE; +} + + +static +cmsBool Write8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsUInt32Number n, _cmsStageToneCurvesData* Tables) +{ + int j; + cmsUInt32Number i; + cmsUInt8Number val; + + for (i=0; i < n; i++) { + + if (Tables) { + + // Usual case of identity curves + if ((Tables ->TheCurves[i]->nEntries == 2) && + (Tables->TheCurves[i]->Table16[0] == 0) && + (Tables->TheCurves[i]->Table16[1] == 65535)) { + + for (j=0; j < 256; j++) { + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) j)) return FALSE; + } + } + else + if (Tables ->TheCurves[i]->nEntries != 256) { + cmsSignalError(ContextID, cmsERROR_RANGE, "LUT8 needs 256 entries on prelinearization"); + return FALSE; + } + else + for (j=0; j < 256; j++) { + + val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]); + + if (!_cmsWriteUInt8Number(io, val)) return FALSE; + } + } + } + return TRUE; +} + + +// Check overflow +static +cmsUInt32Number uipow(cmsUInt32Number n, cmsUInt32Number a, cmsUInt32Number b) +{ + cmsUInt32Number rv = 1, rc; + + if (a == 0) return 0; + if (n == 0) return 0; + + for (; b > 0; b--) { + + rv *= a; + + // Check for overflow + if (rv > UINT_MAX / a) return (cmsUInt32Number) -1; + + } + + rc = rv * n; + + if (rv != rc / n) return (cmsUInt32Number) -1; + return rc; +} + + +// That will create a MPE LUT with Matrix, pre tables, CLUT and post tables. +// 8 bit lut may be scaled easily to v4 PCS, but we need also to properly adjust +// PCS on BToAxx tags and AtoB if abstract. We need to fix input direction. + +static +void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt8Number InputChannels, OutputChannels, CLUTpoints; + cmsUInt8Number* Temp = NULL; + cmsPipeline* NewLUT = NULL; + cmsUInt32Number nTabSize, i; + cmsFloat64Number Matrix[3*3]; + + *nItems = 0; + + if (!_cmsReadUInt8Number(io, &InputChannels)) goto Error; + if (!_cmsReadUInt8Number(io, &OutputChannels)) goto Error; + if (!_cmsReadUInt8Number(io, &CLUTpoints)) goto Error; + + if (CLUTpoints == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least + + // Padding + if (!_cmsReadUInt8Number(io, NULL)) goto Error; + + // Do some checking + if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; + if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; + + // Allocates an empty Pipeline + NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); + if (NewLUT == NULL) goto Error; + + // Read the Matrix + if (!_cmsRead15Fixed16Number(io, &Matrix[0])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[1])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[2])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[3])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[4])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[5])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[6])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[7])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[8])) goto Error; + + + // Only operates if not identity... + if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) { + + if (!cmsPipelineInsertStage(NewLUT, cmsAT_BEGIN, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL))) + goto Error; + } + + // Get input tables + if (!Read8bitTables(self ->ContextID, io, NewLUT, InputChannels)) goto Error; + + // Get 3D CLUT. Check the overflow.... + nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels); + if (nTabSize == (cmsUInt32Number) -1) goto Error; + if (nTabSize > 0) { + + cmsUInt16Number *PtrW, *T; + + PtrW = T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number)); + if (T == NULL) goto Error; + + Temp = (cmsUInt8Number*) _cmsMalloc(self ->ContextID, nTabSize); + if (Temp == NULL) { + _cmsFree(self ->ContextID, T); + goto Error; + } + + if (io ->Read(io, Temp, nTabSize, 1) != 1) { + _cmsFree(self ->ContextID, T); + _cmsFree(self ->ContextID, Temp); + goto Error; + } + + for (i = 0; i < nTabSize; i++) { + + *PtrW++ = FROM_8_TO_16(Temp[i]); + } + _cmsFree(self ->ContextID, Temp); + Temp = NULL; + + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) { + _cmsFree(self ->ContextID, T); + goto Error; + } + _cmsFree(self ->ContextID, T); + } + + + // Get output tables + if (!Read8bitTables(self ->ContextID, io, NewLUT, OutputChannels)) goto Error; + + *nItems = 1; + return NewLUT; + +Error: + if (NewLUT != NULL) cmsPipelineFree(NewLUT); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +// We only allow a specific MPE structure: Matrix plus prelin, plus clut, plus post-lin. +static +cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUInt32Number j, nTabSize, i; + cmsUInt8Number val; + cmsPipeline* NewLUT = (cmsPipeline*) Ptr; + cmsStage* mpe; + _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; + _cmsStageMatrixData* MatMPE = NULL; + _cmsStageCLutData* clut = NULL; + cmsUInt32Number clutPoints; + + // Disassemble the LUT into components. + mpe = NewLUT -> Elements; + if (mpe ->Type == cmsSigMatrixElemType) { + + if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE; + MatMPE = (_cmsStageMatrixData*) mpe ->Data; + mpe = mpe -> Next; + } + + if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { + PreMPE = (_cmsStageToneCurvesData*) mpe ->Data; + mpe = mpe -> Next; + } + + if (mpe != NULL && mpe ->Type == cmsSigCLutElemType) { + clut = (_cmsStageCLutData*) mpe -> Data; + mpe = mpe ->Next; + } + + if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { + PostMPE = (_cmsStageToneCurvesData*) mpe ->Data; + mpe = mpe -> Next; + } + + // That should be all + if (mpe != NULL) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT8"); + return FALSE; + } + + if (clut == NULL) + clutPoints = 0; + else { + // Lut8 only allows same CLUT points in all dimensions + clutPoints = clut->Params->nSamples[0]; + for (i = 1; i < cmsPipelineInputChannels(NewLUT); i++) { + if (clut->Params->nSamples[i] != clutPoints) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT with different samples per dimension not suitable to be saved as LUT16"); + return FALSE; + } + } + } + + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number)cmsPipelineInputChannels(NewLUT))) return FALSE; + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number)cmsPipelineOutputChannels(NewLUT))) return FALSE; + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE; + if (!_cmsWriteUInt8Number(io, 0)) return FALSE; // Padding + + if (MatMPE != NULL) { + + for (i = 0; i < 9; i++) + { + if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE; + } + } + else { + + if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; + } + + // The prelinearization table + if (!Write8bitTables(self ->ContextID, io, NewLUT ->InputChannels, PreMPE)) return FALSE; + + nTabSize = uipow(NewLUT->OutputChannels, clutPoints, NewLUT ->InputChannels); + if (nTabSize == (cmsUInt32Number) -1) return FALSE; + if (nTabSize > 0) { + + // The 3D CLUT. + if (clut != NULL) { + + for (j=0; j < nTabSize; j++) { + + val = (cmsUInt8Number) FROM_16_TO_8(clut ->Tab.T[j]); + if (!_cmsWriteUInt8Number(io, val)) return FALSE; + } + } + } + + // The postlinearization table + if (!Write8bitTables(self ->ContextID, io, NewLUT ->OutputChannels, PostMPE)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + + +static +void* Type_LUT8_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsPipelineDup((cmsPipeline*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_LUT8_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsPipelineFree((cmsPipeline*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + +// ******************************************************************************** +// Type cmsSigLut16Type +// ******************************************************************************** + +// Read 16 bit tables as gamma functions +static +cmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, + cmsUInt32Number nChannels, cmsUInt32Number nEntries) +{ + cmsUInt32Number i; + cmsToneCurve* Tables[cmsMAXCHANNELS]; + + // Maybe an empty table? (this is a lcms extension) + if (nEntries <= 0) return TRUE; + + // Check for malicious profiles + if (nEntries < 2) return FALSE; + if (nChannels > cmsMAXCHANNELS) return FALSE; + + // Init table to zero + memset(Tables, 0, sizeof(Tables)); + + for (i=0; i < nChannels; i++) { + + Tables[i] = cmsBuildTabulatedToneCurve16(ContextID, nEntries, NULL); + if (Tables[i] == NULL) goto Error; + + if (!_cmsReadUInt16Array(io, nEntries, Tables[i]->Table16)) goto Error; + } + + + // Add the table (which may certainly be an identity, but this is up to the optimizer, not the reading code) + if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables))) + goto Error; + + for (i=0; i < nChannels; i++) + cmsFreeToneCurve(Tables[i]); + + return TRUE; + +Error: + for (i=0; i < nChannels; i++) { + if (Tables[i]) cmsFreeToneCurve(Tables[i]); + } + + return FALSE; +} + +static +cmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCurvesData* Tables) +{ + cmsUInt32Number j; + cmsUInt32Number i; + cmsUInt16Number val; + cmsUInt32Number nEntries; + + _cmsAssert(Tables != NULL); + + for (i=0; i < Tables ->nCurves; i++) { + + nEntries = Tables->TheCurves[i]->nEntries; + + for (j=0; j < nEntries; j++) { + + val = Tables->TheCurves[i]->Table16[j]; + if (!_cmsWriteUInt16Number(io, val)) return FALSE; + } + } + return TRUE; + + cmsUNUSED_PARAMETER(ContextID); +} + +static +void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt8Number InputChannels, OutputChannels, CLUTpoints; + cmsPipeline* NewLUT = NULL; + cmsUInt32Number nTabSize; + cmsFloat64Number Matrix[3*3]; + cmsUInt16Number InputEntries, OutputEntries; + + *nItems = 0; + + if (!_cmsReadUInt8Number(io, &InputChannels)) return NULL; + if (!_cmsReadUInt8Number(io, &OutputChannels)) return NULL; + if (!_cmsReadUInt8Number(io, &CLUTpoints)) return NULL; // 255 maximum + + // Padding + if (!_cmsReadUInt8Number(io, NULL)) return NULL; + + // Do some checking + if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; + if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; + + // Allocates an empty LUT + NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); + if (NewLUT == NULL) goto Error; + + // Read the Matrix + if (!_cmsRead15Fixed16Number(io, &Matrix[0])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[1])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[2])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[3])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[4])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[5])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[6])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[7])) goto Error; + if (!_cmsRead15Fixed16Number(io, &Matrix[8])) goto Error; + + + // Only operates on 3 channels + if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) { + + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL))) + goto Error; + } + + if (!_cmsReadUInt16Number(io, &InputEntries)) goto Error; + if (!_cmsReadUInt16Number(io, &OutputEntries)) goto Error; + + if (InputEntries > 0x7FFF || OutputEntries > 0x7FFF) goto Error; + if (CLUTpoints == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least + + // Get input tables + if (!Read16bitTables(self ->ContextID, io, NewLUT, InputChannels, InputEntries)) goto Error; + + // Get 3D CLUT + nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels); + if (nTabSize == (cmsUInt32Number) -1) goto Error; + if (nTabSize > 0) { + + cmsUInt16Number *T; + + T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number)); + if (T == NULL) goto Error; + + if (!_cmsReadUInt16Array(io, nTabSize, T)) { + _cmsFree(self ->ContextID, T); + goto Error; + } + + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) { + _cmsFree(self ->ContextID, T); + goto Error; + } + _cmsFree(self ->ContextID, T); + } + + + // Get output tables + if (!Read16bitTables(self ->ContextID, io, NewLUT, OutputChannels, OutputEntries)) goto Error; + + *nItems = 1; + return NewLUT; + +Error: + if (NewLUT != NULL) cmsPipelineFree(NewLUT); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +// We only allow some specific MPE structures: Matrix plus prelin, plus clut, plus post-lin. +// Some empty defaults are created for missing parts + +static +cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUInt32Number nTabSize; + cmsPipeline* NewLUT = (cmsPipeline*) Ptr; + cmsStage* mpe; + _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; + _cmsStageMatrixData* MatMPE = NULL; + _cmsStageCLutData* clut = NULL; + cmsUInt32Number i, InputChannels, OutputChannels, clutPoints; + + // Disassemble the LUT into components. + mpe = NewLUT -> Elements; + if (mpe != NULL && mpe ->Type == cmsSigMatrixElemType) { + + MatMPE = (_cmsStageMatrixData*) mpe ->Data; + if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE; + mpe = mpe -> Next; + } + + + if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { + PreMPE = (_cmsStageToneCurvesData*) mpe ->Data; + mpe = mpe -> Next; + } + + if (mpe != NULL && mpe ->Type == cmsSigCLutElemType) { + clut = (_cmsStageCLutData*) mpe -> Data; + mpe = mpe ->Next; + } + + if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { + PostMPE = (_cmsStageToneCurvesData*) mpe ->Data; + mpe = mpe -> Next; + } + + // That should be all + if (mpe != NULL) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT16"); + return FALSE; + } + + InputChannels = cmsPipelineInputChannels(NewLUT); + OutputChannels = cmsPipelineOutputChannels(NewLUT); + + if (clut == NULL) + clutPoints = 0; + else { + // Lut16 only allows same CLUT points in all dimensions + clutPoints = clut->Params->nSamples[0]; + for (i = 1; i < InputChannels; i++) { + if (clut->Params->nSamples[i] != clutPoints) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT with different samples per dimension not suitable to be saved as LUT16"); + return FALSE; + } + } + } + + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) InputChannels)) return FALSE; + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) OutputChannels)) return FALSE; + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE; + if (!_cmsWriteUInt8Number(io, 0)) return FALSE; // Padding + + if (MatMPE != NULL) { + + for (i = 0; i < 9; i++) + { + if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE; + } + + } + else { + + if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; + } + + + if (PreMPE != NULL) { + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PreMPE ->TheCurves[0]->nEntries)) return FALSE; + } else { + if (!_cmsWriteUInt16Number(io, 2)) return FALSE; + } + + if (PostMPE != NULL) { + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PostMPE ->TheCurves[0]->nEntries)) return FALSE; + } else { + if (!_cmsWriteUInt16Number(io, 2)) return FALSE; + + } + + // The prelinearization table + + if (PreMPE != NULL) { + if (!Write16bitTables(self ->ContextID, io, PreMPE)) return FALSE; + } + else { + for (i=0; i < InputChannels; i++) { + + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE; + } + } + + nTabSize = uipow(OutputChannels, clutPoints, InputChannels); + if (nTabSize == (cmsUInt32Number) -1) return FALSE; + if (nTabSize > 0) { + // The 3D CLUT. + if (clut != NULL) { + if (!_cmsWriteUInt16Array(io, nTabSize, clut->Tab.T)) return FALSE; + } + } + + // The postlinearization table + if (PostMPE != NULL) { + if (!Write16bitTables(self ->ContextID, io, PostMPE)) return FALSE; + } + else { + for (i=0; i < OutputChannels; i++) { + + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE; + } + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + +static +void* Type_LUT16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsPipelineDup((cmsPipeline*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_LUT16_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsPipelineFree((cmsPipeline*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigLutAToBType +// ******************************************************************************** + + +// V4 stuff. Read matrix for LutAtoB and LutBtoA + +static +cmsStage* ReadMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset) +{ + cmsFloat64Number dMat[3*3]; + cmsFloat64Number dOff[3]; + cmsStage* Mat; + + // Go to address + if (!io -> Seek(io, Offset)) return NULL; + + // Read the Matrix + if (!_cmsRead15Fixed16Number(io, &dMat[0])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[1])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[2])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[3])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[4])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[5])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[6])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[7])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dMat[8])) return NULL; + + if (!_cmsRead15Fixed16Number(io, &dOff[0])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dOff[1])) return NULL; + if (!_cmsRead15Fixed16Number(io, &dOff[2])) return NULL; + + Mat = cmsStageAllocMatrix(self ->ContextID, 3, 3, dMat, dOff); + + return Mat; +} + + + + +// V4 stuff. Read CLUT part for LutAtoB and LutBtoA + +static +cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, + cmsUInt32Number Offset, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels) +{ + cmsUInt8Number gridPoints8[cmsMAXCHANNELS]; // Number of grid points in each dimension. + cmsUInt32Number GridPoints[cmsMAXCHANNELS], i; + cmsUInt8Number Precision; + cmsStage* CLUT; + _cmsStageCLutData* Data; + + if (!io -> Seek(io, Offset)) return NULL; + if (io -> Read(io, gridPoints8, cmsMAXCHANNELS, 1) != 1) return NULL; + + + for (i=0; i < cmsMAXCHANNELS; i++) { + + if (gridPoints8[i] == 1) return NULL; // Impossible value, 0 for no CLUT and then 2 at least + GridPoints[i] = gridPoints8[i]; + } + + if (!_cmsReadUInt8Number(io, &Precision)) return NULL; + + if (!_cmsReadUInt8Number(io, NULL)) return NULL; + if (!_cmsReadUInt8Number(io, NULL)) return NULL; + if (!_cmsReadUInt8Number(io, NULL)) return NULL; + + CLUT = cmsStageAllocCLut16bitGranular(self ->ContextID, GridPoints, InputChannels, OutputChannels, NULL); + if (CLUT == NULL) return NULL; + + Data = (_cmsStageCLutData*) CLUT ->Data; + + // Precision can be 1 or 2 bytes + if (Precision == 1) { + + cmsUInt8Number v; + + for (i=0; i < Data ->nEntries; i++) { + + if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) { + cmsStageFree(CLUT); + return NULL; + } + Data ->Tab.T[i] = FROM_8_TO_16(v); + } + + } + else + if (Precision == 2) { + + if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) { + cmsStageFree(CLUT); + return NULL; + } + } + else { + cmsStageFree(CLUT); + cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision); + return NULL; + } + + return CLUT; +} + +static +cmsToneCurve* ReadEmbeddedCurve(struct _cms_typehandler_struct* self, cmsIOHANDLER* io) +{ + cmsTagTypeSignature BaseType; + cmsUInt32Number nItems; + + BaseType = _cmsReadTypeBase(io); + switch (BaseType) { + + case cmsSigCurveType: + return (cmsToneCurve*) Type_Curve_Read(self, io, &nItems, 0); + + case cmsSigParametricCurveType: + return (cmsToneCurve*) Type_ParametricCurve_Read(self, io, &nItems, 0); + + default: + { + char String[5]; + + _cmsTagSignature2String(String, (cmsTagSignature) BaseType); + cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String); + } + return NULL; + } +} + + +// Read a set of curves from specific offset +static +cmsStage* ReadSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, cmsUInt32Number nCurves) +{ + cmsToneCurve* Curves[cmsMAXCHANNELS]; + cmsUInt32Number i; + cmsStage* Lin = NULL; + + if (nCurves > cmsMAXCHANNELS) return FALSE; + + if (!io -> Seek(io, Offset)) return FALSE; + + for (i=0; i < nCurves; i++) + Curves[i] = NULL; + + for (i=0; i < nCurves; i++) { + + Curves[i] = ReadEmbeddedCurve(self, io); + if (Curves[i] == NULL) goto Error; + if (!_cmsReadAlignment(io)) goto Error; + + } + + Lin = cmsStageAllocToneCurves(self ->ContextID, nCurves, Curves); + +Error: + for (i=0; i < nCurves; i++) + cmsFreeToneCurve(Curves[i]); + + return Lin; +} + + +// LutAtoB type + +// This structure represents a colour transform. The type contains up to five processing +// elements which are stored in the AtoBTag tag in the following order: a set of one +// dimensional curves, a 3 by 3 matrix with offset terms, a set of one dimensional curves, +// a multidimensional lookup table, and a set of one dimensional output curves. +// Data are processed using these elements via the following sequence: +// +//("A" curves) -> (multidimensional lookup table - CLUT) -> ("M" curves) -> (matrix) -> ("B" curves). +// +/* +It is possible to use any or all of these processing elements. At least one processing element +must be included.Only the following combinations are allowed: + +B +M - Matrix - B +A - CLUT - B +A - CLUT - M - Matrix - B + +*/ + +static +void* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt32Number BaseOffset; + cmsUInt8Number inputChan; // Number of input channels + cmsUInt8Number outputChan; // Number of output channels + cmsUInt32Number offsetB; // Offset to first "B" curve + cmsUInt32Number offsetMat; // Offset to matrix + cmsUInt32Number offsetM; // Offset to first "M" curve + cmsUInt32Number offsetC; // Offset to CLUT + cmsUInt32Number offsetA; // Offset to first "A" curve + cmsPipeline* NewLUT = NULL; + + + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + if (!_cmsReadUInt8Number(io, &inputChan)) return NULL; + if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; + + if (!_cmsReadUInt16Number(io, NULL)) return NULL; + + if (!_cmsReadUInt32Number(io, &offsetB)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetMat)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetM)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetC)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetA)) return NULL; + + if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; + if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; + + // Allocates an empty LUT + NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan); + if (NewLUT == NULL) return NULL; + + if (offsetA!= 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, inputChan))) + goto Error; + } + + if (offsetC != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan))) + goto Error; + } + + if (offsetM != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, outputChan))) + goto Error; + } + + if (offsetMat != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat))) + goto Error; + } + + if (offsetB != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, outputChan))) + goto Error; + } + + *nItems = 1; + return NewLUT; +Error: + cmsPipelineFree(NewLUT); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +// Write a set of curves +static +cmsBool WriteMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsStage* mpe) +{ + cmsUInt32Number i, n; + + _cmsStageMatrixData* m = (_cmsStageMatrixData*) mpe -> Data; + + n = mpe->InputChannels * mpe->OutputChannels; + + // Write the Matrix + for (i = 0; i < n; i++) + { + if (!_cmsWrite15Fixed16Number(io, m->Double[i])) return FALSE; + } + + if (m->Offset != NULL) { + + for (i = 0; i < mpe->OutputChannels; i++) + { + if (!_cmsWrite15Fixed16Number(io, m->Offset[i])) return FALSE; + } + } + else { + for (i = 0; i < mpe->OutputChannels; i++) + { + if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; + } + } + + + return TRUE; + + cmsUNUSED_PARAMETER(self); +} + + +// Write a set of curves +static +cmsBool WriteSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsTagTypeSignature Type, cmsStage* mpe) +{ + cmsUInt32Number i, n; + cmsTagTypeSignature CurrentType; + cmsToneCurve** Curves; + + + n = cmsStageOutputChannels(mpe); + Curves = _cmsStageGetPtrToCurveSet(mpe); + + for (i=0; i < n; i++) { + + // If this is a table-based curve, use curve type even on V4 + CurrentType = Type; + + if ((Curves[i] ->nSegments == 0)|| + ((Curves[i]->nSegments == 2) && (Curves[i] ->Segments[1].Type == 0)) ) + CurrentType = cmsSigCurveType; + else + if (Curves[i] ->Segments[0].Type < 0) + CurrentType = cmsSigCurveType; + + if (!_cmsWriteTypeBase(io, CurrentType)) return FALSE; + + switch (CurrentType) { + + case cmsSigCurveType: + if (!Type_Curve_Write(self, io, Curves[i], 1)) return FALSE; + break; + + case cmsSigParametricCurveType: + if (!Type_ParametricCurve_Write(self, io, Curves[i], 1)) return FALSE; + break; + + default: + { + char String[5]; + + _cmsTagSignature2String(String, (cmsTagSignature) Type); + cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String); + } + return FALSE; + } + + if (!_cmsWriteAlignment(io)) return FALSE; + } + + + return TRUE; +} + + +static +cmsBool WriteCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt8Number Precision, cmsStage* mpe) +{ + cmsUInt8Number gridPoints[cmsMAXCHANNELS]; // Number of grid points in each dimension. + cmsUInt32Number i; + _cmsStageCLutData* CLUT = ( _cmsStageCLutData*) mpe -> Data; + + if (CLUT ->HasFloatValues) { + cmsSignalError(self ->ContextID, cmsERROR_NOT_SUITABLE, "Cannot save floating point data, CLUT are 8 or 16 bit only"); + return FALSE; + } + + memset(gridPoints, 0, sizeof(gridPoints)); + for (i=0; i < (cmsUInt32Number) CLUT ->Params ->nInputs; i++) + gridPoints[i] = (cmsUInt8Number) CLUT ->Params ->nSamples[i]; + + if (!io -> Write(io, cmsMAXCHANNELS*sizeof(cmsUInt8Number), gridPoints)) return FALSE; + + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) Precision)) return FALSE; + if (!_cmsWriteUInt8Number(io, 0)) return FALSE; + if (!_cmsWriteUInt8Number(io, 0)) return FALSE; + if (!_cmsWriteUInt8Number(io, 0)) return FALSE; + + // Precision can be 1 or 2 bytes + if (Precision == 1) { + + for (i=0; i < CLUT->nEntries; i++) { + + if (!_cmsWriteUInt8Number(io, FROM_16_TO_8(CLUT->Tab.T[i]))) return FALSE; + } + } + else + if (Precision == 2) { + + if (!_cmsWriteUInt16Array(io, CLUT->nEntries, CLUT ->Tab.T)) return FALSE; + } + else { + cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision); + return FALSE; + } + + if (!_cmsWriteAlignment(io)) return FALSE; + + return TRUE; +} + + + + +static +cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsPipeline* Lut = (cmsPipeline*) Ptr; + cmsUInt32Number inputChan, outputChan; + cmsStage *A = NULL, *B = NULL, *M = NULL; + cmsStage * Matrix = NULL; + cmsStage * CLUT = NULL; + cmsUInt32Number offsetB = 0, offsetMat = 0, offsetM = 0, offsetC = 0, offsetA = 0; + cmsUInt32Number BaseOffset, DirectoryPos, CurrentPos; + + // Get the base for all offsets + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + if (Lut ->Elements != NULL) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 1, cmsSigCurveSetElemType, &B)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, &M, &Matrix, &B)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, &A, &CLUT, &B)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 5, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, + cmsSigMatrixElemType, cmsSigCurveSetElemType, &A, &CLUT, &M, &Matrix, &B)) { + + cmsSignalError(self->ContextID, cmsERROR_NOT_SUITABLE, "LUT is not suitable to be saved as LutAToB"); + return FALSE; + } + + // Get input, output channels + inputChan = cmsPipelineInputChannels(Lut); + outputChan = cmsPipelineOutputChannels(Lut); + + // Write channel count + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) inputChan)) return FALSE; + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) outputChan)) return FALSE; + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + + // Keep directory to be filled latter + DirectoryPos = io ->Tell(io); + + // Write the directory + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + + if (A != NULL) { + + offsetA = io ->Tell(io) - BaseOffset; + if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, A)) return FALSE; + } + + if (CLUT != NULL) { + offsetC = io ->Tell(io) - BaseOffset; + if (!WriteCLUT(self, io, (Lut ->SaveAs8Bits ? 1U : 2U), CLUT)) return FALSE; + + } + if (M != NULL) { + + offsetM = io ->Tell(io) - BaseOffset; + if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, M)) return FALSE; + } + + if (Matrix != NULL) { + offsetMat = io ->Tell(io) - BaseOffset; + if (!WriteMatrix(self, io, Matrix)) return FALSE; + } + + if (B != NULL) { + + offsetB = io ->Tell(io) - BaseOffset; + if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, B)) return FALSE; + } + + CurrentPos = io ->Tell(io); + + if (!io ->Seek(io, DirectoryPos)) return FALSE; + + if (!_cmsWriteUInt32Number(io, offsetB)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetMat)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetM)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetC)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetA)) return FALSE; + + if (!io ->Seek(io, CurrentPos)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + + +static +void* Type_LUTA2B_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsPipelineDup((cmsPipeline*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_LUTA2B_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsPipelineFree((cmsPipeline*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// LutBToA type + +static +void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt8Number inputChan; // Number of input channels + cmsUInt8Number outputChan; // Number of output channels + cmsUInt32Number BaseOffset; // Actual position in file + cmsUInt32Number offsetB; // Offset to first "B" curve + cmsUInt32Number offsetMat; // Offset to matrix + cmsUInt32Number offsetM; // Offset to first "M" curve + cmsUInt32Number offsetC; // Offset to CLUT + cmsUInt32Number offsetA; // Offset to first "A" curve + cmsPipeline* NewLUT = NULL; + + + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + if (!_cmsReadUInt8Number(io, &inputChan)) return NULL; + if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; + + if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; + if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; + + // Padding + if (!_cmsReadUInt16Number(io, NULL)) return NULL; + + if (!_cmsReadUInt32Number(io, &offsetB)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetMat)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetM)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetC)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetA)) return NULL; + + // Allocates an empty LUT + NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan); + if (NewLUT == NULL) return NULL; + + if (offsetB != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, inputChan))) + goto Error; + } + + if (offsetMat != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat))) + goto Error; + } + + if (offsetM != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, inputChan))) + goto Error; + } + + if (offsetC != 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan))) + goto Error; + } + + if (offsetA!= 0) { + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, outputChan))) + goto Error; + } + + *nItems = 1; + return NewLUT; +Error: + cmsPipelineFree(NewLUT); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +/* +B +B - Matrix - M +B - CLUT - A +B - Matrix - M - CLUT - A +*/ + +static +cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsPipeline* Lut = (cmsPipeline*) Ptr; + cmsUInt32Number inputChan, outputChan; + cmsStage *A = NULL, *B = NULL, *M = NULL; + cmsStage *Matrix = NULL; + cmsStage *CLUT = NULL; + cmsUInt32Number offsetB = 0, offsetMat = 0, offsetM = 0, offsetC = 0, offsetA = 0; + cmsUInt32Number BaseOffset, DirectoryPos, CurrentPos; + + + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + if (!cmsPipelineCheckAndRetreiveStages(Lut, 1, cmsSigCurveSetElemType, &B)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, &B, &Matrix, &M)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, &B, &CLUT, &A)) + if (!cmsPipelineCheckAndRetreiveStages(Lut, 5, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, + cmsSigCLutElemType, cmsSigCurveSetElemType, &B, &Matrix, &M, &CLUT, &A)) { + cmsSignalError(self->ContextID, cmsERROR_NOT_SUITABLE, "LUT is not suitable to be saved as LutBToA"); + return FALSE; + } + + inputChan = cmsPipelineInputChannels(Lut); + outputChan = cmsPipelineOutputChannels(Lut); + + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) inputChan)) return FALSE; + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) outputChan)) return FALSE; + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + + DirectoryPos = io ->Tell(io); + + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + + if (A != NULL) { + + offsetA = io ->Tell(io) - BaseOffset; + if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, A)) return FALSE; + } + + if (CLUT != NULL) { + offsetC = io ->Tell(io) - BaseOffset; + if (!WriteCLUT(self, io, (Lut ->SaveAs8Bits ? 1U : 2U), CLUT)) return FALSE; + + } + if (M != NULL) { + + offsetM = io ->Tell(io) - BaseOffset; + if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, M)) return FALSE; + } + + if (Matrix != NULL) { + offsetMat = io ->Tell(io) - BaseOffset; + if (!WriteMatrix(self, io, Matrix)) return FALSE; + } + + if (B != NULL) { + + offsetB = io ->Tell(io) - BaseOffset; + if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, B)) return FALSE; + } + + CurrentPos = io ->Tell(io); + + if (!io ->Seek(io, DirectoryPos)) return FALSE; + + if (!_cmsWriteUInt32Number(io, offsetB)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetMat)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetM)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetC)) return FALSE; + if (!_cmsWriteUInt32Number(io, offsetA)) return FALSE; + + if (!io ->Seek(io, CurrentPos)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + + + +static +void* Type_LUTB2A_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsPipelineDup((cmsPipeline*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_LUTB2A_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsPipelineFree((cmsPipeline*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + + +// ******************************************************************************** +// Type cmsSigColorantTableType +// ******************************************************************************** +/* +The purpose of this tag is to identify the colorants used in the profile by a +unique name and set of XYZ or L*a*b* values to give the colorant an unambiguous +value. The first colorant listed is the colorant of the first device channel of +a lut tag. The second colorant listed is the colorant of the second device channel +of a lut tag, and so on. +*/ + +static +void *Type_ColorantTable_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt32Number i, Count; + cmsNAMEDCOLORLIST* List; + char Name[34]; + cmsUInt16Number PCS[3]; + + + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + + if (Count > cmsMAXCHANNELS) { + cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many colorants '%d'", Count); + return NULL; + } + + List = cmsAllocNamedColorList(self ->ContextID, Count, 0, "", ""); + if (List == NULL) + return NULL; + + for (i=0; i < Count; i++) { + + if (io ->Read(io, Name, 32, 1) != 1) goto Error; + Name[32] = 0; + + if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; + + if (!cmsAppendNamedColor(List, Name, PCS, NULL)) goto Error; + + } + + *nItems = 1; + return List; + +Error: + *nItems = 0; + cmsFreeNamedColorList(List); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + + +// Saves a colorant table. It is using the named color structure for simplicity sake +static +cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; + cmsUInt32Number i, nColors; + + nColors = cmsNamedColorCount(NamedColorList); + + if (!_cmsWriteUInt32Number(io, nColors)) return FALSE; + + for (i=0; i < nColors; i++) { + + char root[cmsMAX_PATH]; + cmsUInt16Number PCS[3]; + + memset(root, 0, sizeof(root)); + + if (!cmsNamedColorInfo(NamedColorList, i, root, NULL, NULL, PCS, NULL)) return 0; + root[32] = 0; + + if (!io ->Write(io, 32, root)) return FALSE; + if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + +static +void* Type_ColorantTable_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) +{ + cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) Ptr; + return (void*) cmsDupNamedColorList(nc); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + + +static +void Type_ColorantTable_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsFreeNamedColorList((cmsNAMEDCOLORLIST*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigNamedColor2Type +// ******************************************************************************** +// +//The namedColor2Type is a count value and array of structures that provide color +//coordinates for 7-bit ASCII color names. For each named color, a PCS and optional +//device representation of the color are given. Both representations are 16-bit values. +//The device representation corresponds to the header's 'color space of data' field. +//This representation should be consistent with the 'number of device components' +//field in the namedColor2Type. If this field is 0, device coordinates are not provided. +//The PCS representation corresponds to the header's PCS field. The PCS representation +//is always provided. Color names are fixed-length, 32-byte fields including null +//termination. In order to maintain maximum portability, it is strongly recommended +//that special characters of the 7-bit ASCII set not be used. + +static +void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt32Number vendorFlag; // Bottom 16 bits for ICC use + cmsUInt32Number count; // Count of named colors + cmsUInt32Number nDeviceCoords; // Num of device coordinates + char prefix[32]; // Prefix for each color name + char suffix[32]; // Suffix for each color name + cmsNAMEDCOLORLIST* v; + cmsUInt32Number i; + + + *nItems = 0; + if (!_cmsReadUInt32Number(io, &vendorFlag)) return NULL; + if (!_cmsReadUInt32Number(io, &count)) return NULL; + if (!_cmsReadUInt32Number(io, &nDeviceCoords)) return NULL; + + if (io -> Read(io, prefix, 32, 1) != 1) return NULL; + if (io -> Read(io, suffix, 32, 1) != 1) return NULL; + + prefix[31] = suffix[31] = 0; + + v = cmsAllocNamedColorList(self ->ContextID, count, nDeviceCoords, prefix, suffix); + if (v == NULL) { + cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many named colors '%d'", count); + return NULL; + } + + if (nDeviceCoords > cmsMAXCHANNELS) { + cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords); + goto Error; + } + for (i=0; i < count; i++) { + + cmsUInt16Number PCS[3]; + cmsUInt16Number Colorant[cmsMAXCHANNELS]; + char Root[33]; + + memset(Colorant, 0, sizeof(Colorant)); + if (io -> Read(io, Root, 32, 1) != 1) goto Error; + Root[32] = 0; // To prevent exploits + + if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; + if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error; + + if (!cmsAppendNamedColor(v, Root, PCS, Colorant)) goto Error; + } + + *nItems = 1; + return (void*) v ; + +Error: + cmsFreeNamedColorList(v); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +// Saves a named color list into a named color profile +static +cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; + char prefix[33]; // Prefix for each color name + char suffix[33]; // Suffix for each color name + cmsUInt32Number i, nColors; + + nColors = cmsNamedColorCount(NamedColorList); + + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt32Number(io, nColors)) return FALSE; + if (!_cmsWriteUInt32Number(io, NamedColorList ->ColorantCount)) return FALSE; + + memcpy(prefix, (const char*) NamedColorList->Prefix, sizeof(prefix)); + memcpy(suffix, (const char*) NamedColorList->Suffix, sizeof(suffix)); + + suffix[32] = prefix[32] = 0; + + if (!io ->Write(io, 32, prefix)) return FALSE; + if (!io ->Write(io, 32, suffix)) return FALSE; + + for (i=0; i < nColors; i++) { + + cmsUInt16Number PCS[3]; + cmsUInt16Number Colorant[cmsMAXCHANNELS]; + char Root[cmsMAX_PATH]; + + memset(Root, 0, sizeof(Root)); + memset(PCS, 0, sizeof(PCS)); + memset(Colorant, 0, sizeof(Colorant)); + + if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0; + Root[32] = 0; + if (!io ->Write(io, 32 , Root)) return FALSE; + if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE; + if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + +static +void* Type_NamedColor_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) +{ + cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) Ptr; + + return (void*) cmsDupNamedColorList(nc); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + + +static +void Type_NamedColor_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsFreeNamedColorList((cmsNAMEDCOLORLIST*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigProfileSequenceDescType +// ******************************************************************************** + +// This type is an array of structures, each of which contains information from the +// header fields and tags from the original profiles which were combined to create +// the final profile. The order of the structures is the order in which the profiles +// were combined and includes a structure for the final profile. This provides a +// description of the profile sequence from source to destination, +// typically used with the DeviceLink profile. + +static +cmsBool ReadEmbeddedText(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU** mlu, cmsUInt32Number SizeOfTag) +{ + cmsTagTypeSignature BaseType; + cmsUInt32Number nItems; + + BaseType = _cmsReadTypeBase(io); + + switch (BaseType) { + + case cmsSigTextType: + if (*mlu) cmsMLUfree(*mlu); + *mlu = (cmsMLU*)Type_Text_Read(self, io, &nItems, SizeOfTag); + return (*mlu != NULL); + + case cmsSigTextDescriptionType: + if (*mlu) cmsMLUfree(*mlu); + *mlu = (cmsMLU*) Type_Text_Description_Read(self, io, &nItems, SizeOfTag); + return (*mlu != NULL); + + /* + TBD: Size is needed for MLU, and we have no idea on which is the available size + */ + + case cmsSigMultiLocalizedUnicodeType: + if (*mlu) cmsMLUfree(*mlu); + *mlu = (cmsMLU*) Type_MLU_Read(self, io, &nItems, SizeOfTag); + return (*mlu != NULL); + + default: return FALSE; + } +} + + +static +void *Type_ProfileSequenceDesc_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsSEQ* OutSeq; + cmsUInt32Number i, Count; + + *nItems = 0; + + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + + if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; + SizeOfTag -= sizeof(cmsUInt32Number); + + + OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count); + if (OutSeq == NULL) return NULL; + + OutSeq ->n = Count; + + // Get structures as well + + for (i=0; i < Count; i++) { + + cmsPSEQDESC* sec = &OutSeq -> seq[i]; + + if (!_cmsReadUInt32Number(io, &sec ->deviceMfg)) goto Error; + if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error; + SizeOfTag -= sizeof(cmsUInt32Number); + + if (!_cmsReadUInt32Number(io, &sec ->deviceModel)) goto Error; + if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error; + SizeOfTag -= sizeof(cmsUInt32Number); + + if (!_cmsReadUInt64Number(io, &sec ->attributes)) goto Error; + if (SizeOfTag < sizeof(cmsUInt64Number)) goto Error; + SizeOfTag -= sizeof(cmsUInt64Number); + + if (!_cmsReadUInt32Number(io, (cmsUInt32Number *)&sec ->technology)) goto Error; + if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error; + SizeOfTag -= sizeof(cmsUInt32Number); + + if (!ReadEmbeddedText(self, io, &sec ->Manufacturer, SizeOfTag)) goto Error; + if (!ReadEmbeddedText(self, io, &sec ->Model, SizeOfTag)) goto Error; + } + + *nItems = 1; + return OutSeq; + +Error: + cmsFreeProfileSequenceDescription(OutSeq); + return NULL; +} + + +// Aux--Embed a text description type. It can be of type text description or multilocalized unicode +// and it depends of the version number passed on cmsTagDescriptor structure instead of stack +static +cmsBool SaveDescription(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* Text) +{ + if (self ->ICCVersion < 0x4000000) { + + if (!_cmsWriteTypeBase(io, cmsSigTextDescriptionType)) return FALSE; + return Type_Text_Description_Write(self, io, Text, 1); + } + else { + if (!_cmsWriteTypeBase(io, cmsSigMultiLocalizedUnicodeType)) return FALSE; + return Type_MLU_Write(self, io, Text, 1); + } +} + + +static +cmsBool Type_ProfileSequenceDesc_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsSEQ* Seq = (cmsSEQ*) Ptr; + cmsUInt32Number i; + + if (!_cmsWriteUInt32Number(io, Seq->n)) return FALSE; + + for (i=0; i < Seq ->n; i++) { + + cmsPSEQDESC* sec = &Seq -> seq[i]; + + if (!_cmsWriteUInt32Number(io, sec ->deviceMfg)) return FALSE; + if (!_cmsWriteUInt32Number(io, sec ->deviceModel)) return FALSE; + if (!_cmsWriteUInt64Number(io, &sec ->attributes)) return FALSE; + if (!_cmsWriteUInt32Number(io, sec ->technology)) return FALSE; + + if (!SaveDescription(self, io, sec ->Manufacturer)) return FALSE; + if (!SaveDescription(self, io, sec ->Model)) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + + +static +void* Type_ProfileSequenceDesc_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) +{ + return (void*) cmsDupProfileSequenceDescription((cmsSEQ*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_ProfileSequenceDesc_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsFreeProfileSequenceDescription((cmsSEQ*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigProfileSequenceIdType +// ******************************************************************************** +/* +In certain workflows using ICC Device Link Profiles, it is necessary to identify the +original profiles that were combined to create the Device Link Profile. +This type is an array of structures, each of which contains information for +identification of a profile used in a sequence +*/ + + +static +cmsBool ReadSeqID(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Cargo, + cmsUInt32Number n, + cmsUInt32Number SizeOfTag) +{ + cmsSEQ* OutSeq = (cmsSEQ*) Cargo; + cmsPSEQDESC* seq = &OutSeq ->seq[n]; + + if (io -> Read(io, seq ->ProfileID.ID8, 16, 1) != 1) return FALSE; + if (!ReadEmbeddedText(self, io, &seq ->Description, SizeOfTag)) return FALSE; + + return TRUE; +} + + + +static +void *Type_ProfileSequenceId_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsSEQ* OutSeq; + cmsUInt32Number Count; + cmsUInt32Number BaseOffset; + + *nItems = 0; + + // Get actual position as a basis for element offsets + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + // Get table count + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + + // Allocate an empty structure + OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count); + if (OutSeq == NULL) return NULL; + + + // Read the position table + if (!ReadPositionTable(self, io, Count, BaseOffset, OutSeq, ReadSeqID)) { + + cmsFreeProfileSequenceDescription(OutSeq); + return NULL; + } + + // Success + *nItems = 1; + return OutSeq; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +static +cmsBool WriteSeqID(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Cargo, + cmsUInt32Number n, + cmsUInt32Number SizeOfTag) +{ + cmsSEQ* Seq = (cmsSEQ*) Cargo; + + if (!io ->Write(io, 16, Seq ->seq[n].ProfileID.ID8)) return FALSE; + + // Store here the MLU + if (!SaveDescription(self, io, Seq ->seq[n].Description)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +static +cmsBool Type_ProfileSequenceId_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsSEQ* Seq = (cmsSEQ*) Ptr; + cmsUInt32Number BaseOffset; + + // Keep the base offset + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + // This is the table count + if (!_cmsWriteUInt32Number(io, Seq ->n)) return FALSE; + + // This is the position table and content + if (!WritePositionTable(self, io, 0, Seq ->n, BaseOffset, Seq, WriteSeqID)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + +static +void* Type_ProfileSequenceId_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) +{ + return (void*) cmsDupProfileSequenceDescription((cmsSEQ*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_ProfileSequenceId_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsFreeProfileSequenceDescription((cmsSEQ*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigUcrBgType +// ******************************************************************************** +/* +This type contains curves representing the under color removal and black +generation and a text string which is a general description of the method used +for the ucr/bg. +*/ + +static +void *Type_UcrBg_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUcrBg* n = (cmsUcrBg*) _cmsMallocZero(self ->ContextID, sizeof(cmsUcrBg)); + cmsUInt32Number CountUcr, CountBg; + cmsInt32Number SignedSizeOfTag = (cmsInt32Number)SizeOfTag; + char* ASCIIString; + + *nItems = 0; + if (n == NULL) return NULL; + + // First curve is Under color removal + + if (SignedSizeOfTag < (cmsInt32Number) sizeof(cmsUInt32Number)) return NULL; + if (!_cmsReadUInt32Number(io, &CountUcr)) return NULL; + SignedSizeOfTag -= sizeof(cmsUInt32Number); + + n ->Ucr = cmsBuildTabulatedToneCurve16(self ->ContextID, CountUcr, NULL); + if (n ->Ucr == NULL) goto error; + + if (SignedSizeOfTag < (cmsInt32Number)(CountUcr * sizeof(cmsUInt16Number))) goto error; + if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) goto error; + + SignedSizeOfTag -= CountUcr * sizeof(cmsUInt16Number); + + // Second curve is Black generation + + if (SignedSizeOfTag < (cmsInt32Number)sizeof(cmsUInt32Number)) goto error; + if (!_cmsReadUInt32Number(io, &CountBg)) goto error; + SignedSizeOfTag -= sizeof(cmsUInt32Number); + + n ->Bg = cmsBuildTabulatedToneCurve16(self ->ContextID, CountBg, NULL); + if (n ->Bg == NULL) goto error; + + if (SignedSizeOfTag < (cmsInt32Number) (CountBg * sizeof(cmsUInt16Number))) goto error; + if (!_cmsReadUInt16Array(io, CountBg, n ->Bg->Table16)) goto error; + SignedSizeOfTag -= CountBg * sizeof(cmsUInt16Number); + + if (SignedSizeOfTag < 0 || SignedSizeOfTag > 32000) goto error; + + // Now comes the text. The length is specified by the tag size + n ->Desc = cmsMLUalloc(self ->ContextID, 1); + if (n ->Desc == NULL) goto error; + + ASCIIString = (char*) _cmsMalloc(self ->ContextID, SignedSizeOfTag + 1); + if (io->Read(io, ASCIIString, sizeof(char), SignedSizeOfTag) != (cmsUInt32Number)SignedSizeOfTag) + { + _cmsFree(self->ContextID, ASCIIString); + goto error; + } + + ASCIIString[SignedSizeOfTag] = 0; + cmsMLUsetASCII(n ->Desc, cmsNoLanguage, cmsNoCountry, ASCIIString); + _cmsFree(self ->ContextID, ASCIIString); + + *nItems = 1; + return (void*) n; + +error: + + if (n->Ucr) cmsFreeToneCurve(n->Ucr); + if (n->Bg) cmsFreeToneCurve(n->Bg); + if (n->Desc) cmsMLUfree(n->Desc); + _cmsFree(self->ContextID, n); + *nItems = 0; + return NULL; + +} + +static +cmsBool Type_UcrBg_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUcrBg* Value = (cmsUcrBg*) Ptr; + cmsUInt32Number TextSize; + char* Text; + + // First curve is Under color removal + if (!_cmsWriteUInt32Number(io, Value ->Ucr ->nEntries)) return FALSE; + if (!_cmsWriteUInt16Array(io, Value ->Ucr ->nEntries, Value ->Ucr ->Table16)) return FALSE; + + // Then black generation + if (!_cmsWriteUInt32Number(io, Value ->Bg ->nEntries)) return FALSE; + if (!_cmsWriteUInt16Array(io, Value ->Bg ->nEntries, Value ->Bg ->Table16)) return FALSE; + + // Now comes the text. The length is specified by the tag size + TextSize = cmsMLUgetASCII(Value ->Desc, cmsNoLanguage, cmsNoCountry, NULL, 0); + Text = (char*) _cmsMalloc(self ->ContextID, TextSize); + if (cmsMLUgetASCII(Value ->Desc, cmsNoLanguage, cmsNoCountry, Text, TextSize) != TextSize) return FALSE; + + if (!io ->Write(io, TextSize, Text)) return FALSE; + _cmsFree(self ->ContextID, Text); + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + +static +void* Type_UcrBg_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + cmsUcrBg* Src = (cmsUcrBg*) Ptr; + cmsUcrBg* NewUcrBg = (cmsUcrBg*) _cmsMallocZero(self ->ContextID, sizeof(cmsUcrBg)); + + if (NewUcrBg == NULL) return NULL; + + NewUcrBg ->Bg = cmsDupToneCurve(Src ->Bg); + NewUcrBg ->Ucr = cmsDupToneCurve(Src ->Ucr); + NewUcrBg ->Desc = cmsMLUdup(Src ->Desc); + + return (void*) NewUcrBg; + + cmsUNUSED_PARAMETER(n); +} + +static +void Type_UcrBg_Free(struct _cms_typehandler_struct* self, void *Ptr) +{ + cmsUcrBg* Src = (cmsUcrBg*) Ptr; + + if (Src ->Ucr) cmsFreeToneCurve(Src ->Ucr); + if (Src ->Bg) cmsFreeToneCurve(Src ->Bg); + if (Src ->Desc) cmsMLUfree(Src ->Desc); + + _cmsFree(self ->ContextID, Ptr); +} + +// ******************************************************************************** +// Type cmsSigCrdInfoType +// ******************************************************************************** + +/* +This type contains the PostScript product name to which this profile corresponds +and the names of the companion CRDs. Recall that a single profile can generate +multiple CRDs. It is implemented as a MLU being the language code "PS" and then +country varies for each element: + + nm: PostScript product name + #0: Rendering intent 0 CRD name + #1: Rendering intent 1 CRD name + #2: Rendering intent 2 CRD name + #3: Rendering intent 3 CRD name +*/ + + + +// Auxiliary, read an string specified as count + string +static +cmsBool ReadCountAndString(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section) +{ + cmsUInt32Number Count; + char* Text; + + if (*SizeOfTag < sizeof(cmsUInt32Number)) return FALSE; + + if (!_cmsReadUInt32Number(io, &Count)) return FALSE; + + if (Count > UINT_MAX - sizeof(cmsUInt32Number)) return FALSE; + if (*SizeOfTag < Count + sizeof(cmsUInt32Number)) return FALSE; + + Text = (char*) _cmsMalloc(self ->ContextID, Count+1); + if (Text == NULL) return FALSE; + + if (io ->Read(io, Text, sizeof(cmsUInt8Number), Count) != Count) { + _cmsFree(self ->ContextID, Text); + return FALSE; + } + + Text[Count] = 0; + + cmsMLUsetASCII(mlu, "PS", Section, Text); + _cmsFree(self ->ContextID, Text); + + *SizeOfTag -= (Count + sizeof(cmsUInt32Number)); + return TRUE; +} + +static +cmsBool WriteCountAndString(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, const char* Section) +{ + cmsUInt32Number TextSize; + char* Text; + + TextSize = cmsMLUgetASCII(mlu, "PS", Section, NULL, 0); + Text = (char*) _cmsMalloc(self ->ContextID, TextSize); + + if (!_cmsWriteUInt32Number(io, TextSize)) return FALSE; + + if (cmsMLUgetASCII(mlu, "PS", Section, Text, TextSize) == 0) return FALSE; + + if (!io ->Write(io, TextSize, Text)) return FALSE; + _cmsFree(self ->ContextID, Text); + + return TRUE; +} + +static +void *Type_CrdInfo_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsMLU* mlu = cmsMLUalloc(self ->ContextID, 5); + + *nItems = 0; + if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "nm")) goto Error; + if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#0")) goto Error; + if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#1")) goto Error; + if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#2")) goto Error; + if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#3")) goto Error; + + *nItems = 1; + return (void*) mlu; + +Error: + cmsMLUfree(mlu); + return NULL; + +} + +static +cmsBool Type_CrdInfo_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + + cmsMLU* mlu = (cmsMLU*) Ptr; + + if (!WriteCountAndString(self, io, mlu, "nm")) goto Error; + if (!WriteCountAndString(self, io, mlu, "#0")) goto Error; + if (!WriteCountAndString(self, io, mlu, "#1")) goto Error; + if (!WriteCountAndString(self, io, mlu, "#2")) goto Error; + if (!WriteCountAndString(self, io, mlu, "#3")) goto Error; + + return TRUE; + +Error: + return FALSE; + + cmsUNUSED_PARAMETER(nItems); +} + + +static +void* Type_CrdInfo_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsMLUdup((cmsMLU*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_CrdInfo_Free(struct _cms_typehandler_struct* self, void *Ptr) +{ + cmsMLUfree((cmsMLU*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + +// ******************************************************************************** +// Type cmsSigScreeningType +// ******************************************************************************** +// +//The screeningType describes various screening parameters including screen +//frequency, screening angle, and spot shape. + +static +void *Type_Screening_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsScreening* sc = NULL; + cmsUInt32Number i; + + sc = (cmsScreening*) _cmsMallocZero(self ->ContextID, sizeof(cmsScreening)); + if (sc == NULL) return NULL; + + *nItems = 0; + + if (!_cmsReadUInt32Number(io, &sc ->Flag)) goto Error; + if (!_cmsReadUInt32Number(io, &sc ->nChannels)) goto Error; + + if (sc ->nChannels > cmsMAXCHANNELS - 1) + sc ->nChannels = cmsMAXCHANNELS - 1; + + for (i=0; i < sc ->nChannels; i++) { + + if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].Frequency)) goto Error; + if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].ScreenAngle)) goto Error; + if (!_cmsReadUInt32Number(io, &sc ->Channels[i].SpotShape)) goto Error; + } + + + *nItems = 1; + + return (void*) sc; + +Error: + if (sc != NULL) + _cmsFree(self ->ContextID, sc); + + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +static +cmsBool Type_Screening_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsScreening* sc = (cmsScreening* ) Ptr; + cmsUInt32Number i; + + if (!_cmsWriteUInt32Number(io, sc ->Flag)) return FALSE; + if (!_cmsWriteUInt32Number(io, sc ->nChannels)) return FALSE; + + for (i=0; i < sc ->nChannels; i++) { + + if (!_cmsWrite15Fixed16Number(io, sc ->Channels[i].Frequency)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, sc ->Channels[i].ScreenAngle)) return FALSE; + if (!_cmsWriteUInt32Number(io, sc ->Channels[i].SpotShape)) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + +static +void* Type_Screening_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening)); + + cmsUNUSED_PARAMETER(n); +} + + +static +void Type_Screening_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + +// ******************************************************************************** +// Type cmsSigViewingConditionsType +// ******************************************************************************** +// +//This type represents a set of viewing condition parameters including: +//CIE 'absolute' illuminant white point tristimulus values and CIE 'absolute' +//surround tristimulus values. + +static +void *Type_ViewingConditions_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsICCViewingConditions* vc = NULL; + + vc = (cmsICCViewingConditions*) _cmsMallocZero(self ->ContextID, sizeof(cmsICCViewingConditions)); + if (vc == NULL) return NULL; + + *nItems = 0; + + if (!_cmsReadXYZNumber(io, &vc ->IlluminantXYZ)) goto Error; + if (!_cmsReadXYZNumber(io, &vc ->SurroundXYZ)) goto Error; + if (!_cmsReadUInt32Number(io, &vc ->IlluminantType)) goto Error; + + *nItems = 1; + + return (void*) vc; + +Error: + if (vc != NULL) + _cmsFree(self ->ContextID, vc); + + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +static +cmsBool Type_ViewingConditions_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsICCViewingConditions* sc = (cmsICCViewingConditions* ) Ptr; + + if (!_cmsWriteXYZNumber(io, &sc ->IlluminantXYZ)) return FALSE; + if (!_cmsWriteXYZNumber(io, &sc ->SurroundXYZ)) return FALSE; + if (!_cmsWriteUInt32Number(io, sc ->IlluminantType)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + +static +void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsICCViewingConditions)); + + cmsUNUSED_PARAMETER(n); +} + + +static +void Type_ViewingConditions_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + + +// ******************************************************************************** +// Type cmsSigMultiProcessElementType +// ******************************************************************************** + + +static +void* GenericMPEdup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsStageDup((cmsStage*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void GenericMPEfree(struct _cms_typehandler_struct* self, void *Ptr) +{ + cmsStageFree((cmsStage*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + +// Each curve is stored in one or more curve segments, with break-points specified between curve segments. +// The first curve segment always starts at -Infinity, and the last curve segment always ends at +Infinity. The +// first and last curve segments shall be specified in terms of a formula, whereas the other segments shall be +// specified either in terms of a formula, or by a sampled curve. + + +// Read an embedded segmented curve +static +cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHANDLER* io) +{ + cmsCurveSegSignature ElementSig; + cmsUInt32Number i, j; + cmsUInt16Number nSegments; + cmsCurveSegment* Segments; + cmsToneCurve* Curve; + cmsFloat32Number PrevBreak = MINUS_INF; // - infinite + + // Take signature and channels for each element. + if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL; + + // That should be a segmented curve + if (ElementSig != cmsSigSegmentedCurve) return NULL; + + if (!_cmsReadUInt32Number(io, NULL)) return NULL; + if (!_cmsReadUInt16Number(io, &nSegments)) return NULL; + if (!_cmsReadUInt16Number(io, NULL)) return NULL; + + if (nSegments < 1) return NULL; + Segments = (cmsCurveSegment*) _cmsCalloc(self ->ContextID, nSegments, sizeof(cmsCurveSegment)); + if (Segments == NULL) return NULL; + + // Read breakpoints + for (i=0; i < (cmsUInt32Number) nSegments - 1; i++) { + + Segments[i].x0 = PrevBreak; + if (!_cmsReadFloat32Number(io, &Segments[i].x1)) goto Error; + PrevBreak = Segments[i].x1; + } + + Segments[nSegments-1].x0 = PrevBreak; + Segments[nSegments-1].x1 = PLUS_INF; // A big cmsFloat32Number number + + // Read segments + for (i=0; i < nSegments; i++) { + + if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) goto Error; + if (!_cmsReadUInt32Number(io, NULL)) goto Error; + + switch (ElementSig) { + + case cmsSigFormulaCurveSeg: { + + cmsUInt16Number Type; + cmsUInt32Number ParamsByType[] = { 4, 5, 5 }; + + if (!_cmsReadUInt16Number(io, &Type)) goto Error; + if (!_cmsReadUInt16Number(io, NULL)) goto Error; + + Segments[i].Type = Type + 6; + if (Type > 2) goto Error; + + for (j = 0; j < ParamsByType[Type]; j++) { + + cmsFloat32Number f; + if (!_cmsReadFloat32Number(io, &f)) goto Error; + Segments[i].Params[j] = f; + } + } + break; + + + case cmsSigSampledCurveSeg: { + cmsUInt32Number Count; + + if (!_cmsReadUInt32Number(io, &Count)) goto Error; + + // The first point is implicit in the last stage, we allocate an extra note to be populated latter on + Count++; + Segments[i].nGridPoints = Count; + Segments[i].SampledPoints = (cmsFloat32Number*)_cmsCalloc(self->ContextID, Count, sizeof(cmsFloat32Number)); + if (Segments[i].SampledPoints == NULL) goto Error; + + Segments[i].SampledPoints[0] = 0; + for (j = 1; j < Count; j++) { + if (!_cmsReadFloat32Number(io, &Segments[i].SampledPoints[j])) goto Error; + } + } + break; + + default: + { + char String[5]; + + _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve element type '%s' found.", String); + } + goto Error; + + } + } + + Curve = cmsBuildSegmentedToneCurve(self ->ContextID, nSegments, Segments); + + for (i=0; i < nSegments; i++) { + if (Segments[i].SampledPoints) _cmsFree(self ->ContextID, Segments[i].SampledPoints); + } + _cmsFree(self ->ContextID, Segments); + + // Explore for missing implicit points + for (i = 0; i < nSegments; i++) { + + // If sampled curve, fix it + if (Curve->Segments[i].Type == 0) { + + Curve->Segments[i].SampledPoints[0] = cmsEvalToneCurveFloat(Curve, Curve->Segments[i].x0); + } + } + + return Curve; + +Error: + if (Segments) { + for (i=0; i < nSegments; i++) { + if (Segments[i].SampledPoints) _cmsFree(self ->ContextID, Segments[i].SampledPoints); + } + _cmsFree(self ->ContextID, Segments); + } + return NULL; +} + + +static +cmsBool ReadMPECurve(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Cargo, + cmsUInt32Number n, + cmsUInt32Number SizeOfTag) +{ + cmsToneCurve** GammaTables = ( cmsToneCurve**) Cargo; + + GammaTables[n] = ReadSegmentedCurve(self, io); + return (GammaTables[n] != NULL); + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +static +void *Type_MPEcurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsStage* mpe = NULL; + cmsUInt16Number InputChans, OutputChans; + cmsUInt32Number i, BaseOffset; + cmsToneCurve** GammaTables; + + *nItems = 0; + + // Get actual position as a basis for element offsets + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; + if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + + if (InputChans != OutputChans) return NULL; + + GammaTables = (cmsToneCurve**) _cmsCalloc(self ->ContextID, InputChans, sizeof(cmsToneCurve*)); + if (GammaTables == NULL) return NULL; + + if (ReadPositionTable(self, io, InputChans, BaseOffset, GammaTables, ReadMPECurve)) { + + mpe = cmsStageAllocToneCurves(self ->ContextID, InputChans, GammaTables); + } + else { + mpe = NULL; + } + + for (i=0; i < InputChans; i++) { + if (GammaTables[i]) cmsFreeToneCurve(GammaTables[i]); + } + + _cmsFree(self ->ContextID, GammaTables); + *nItems = (mpe != NULL) ? 1U : 0; + return mpe; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +// Write a single segmented curve. NO CHECK IS PERFORMED ON VALIDITY +static +cmsBool WriteSegmentedCurve(cmsIOHANDLER* io, cmsToneCurve* g) +{ + cmsUInt32Number i, j; + cmsCurveSegment* Segments = g ->Segments; + cmsUInt32Number nSegments = g ->nSegments; + + if (!_cmsWriteUInt32Number(io, cmsSigSegmentedCurve)) goto Error; + if (!_cmsWriteUInt32Number(io, 0)) goto Error; + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) nSegments)) goto Error; + if (!_cmsWriteUInt16Number(io, 0)) goto Error; + + // Write the break-points + for (i=0; i < nSegments - 1; i++) { + if (!_cmsWriteFloat32Number(io, Segments[i].x1)) goto Error; + } + + // Write the segments + for (i=0; i < g ->nSegments; i++) { + + cmsCurveSegment* ActualSeg = Segments + i; + + if (ActualSeg -> Type == 0) { + + // This is a sampled curve. First point is implicit in the ICC format, but not in our representation + if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) cmsSigSampledCurveSeg)) goto Error; + if (!_cmsWriteUInt32Number(io, 0)) goto Error; + if (!_cmsWriteUInt32Number(io, ActualSeg -> nGridPoints - 1)) goto Error; + + for (j=1; j < g ->Segments[i].nGridPoints; j++) { + if (!_cmsWriteFloat32Number(io, ActualSeg -> SampledPoints[j])) goto Error; + } + + } + else { + int Type; + cmsUInt32Number ParamsByType[] = { 4, 5, 5 }; + + // This is a formula-based + if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) cmsSigFormulaCurveSeg)) goto Error; + if (!_cmsWriteUInt32Number(io, 0)) goto Error; + + // We only allow 1, 2 and 3 as types + Type = ActualSeg ->Type - 6; + if (Type > 2 || Type < 0) goto Error; + + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) Type)) goto Error; + if (!_cmsWriteUInt16Number(io, 0)) goto Error; + + for (j=0; j < ParamsByType[Type]; j++) { + if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) ActualSeg ->Params[j])) goto Error; + } + } + + // It seems there is no need to align. Code is here, and for safety commented out + // if (!_cmsWriteAlignment(io)) goto Error; + } + + return TRUE; + +Error: + return FALSE; +} + + +static +cmsBool WriteMPECurve(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Cargo, + cmsUInt32Number n, + cmsUInt32Number SizeOfTag) +{ + _cmsStageToneCurvesData* Curves = (_cmsStageToneCurvesData*) Cargo; + + return WriteSegmentedCurve(io, Curves ->TheCurves[n]); + + cmsUNUSED_PARAMETER(SizeOfTag); + cmsUNUSED_PARAMETER(self); +} + +// Write a curve, checking first for validity +static +cmsBool Type_MPEcurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUInt32Number BaseOffset; + cmsStage* mpe = (cmsStage*) Ptr; + _cmsStageToneCurvesData* Curves = (_cmsStageToneCurvesData*) mpe ->Data; + + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + // Write the header. Since those are curves, input and output channels are same + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; + + if (!WritePositionTable(self, io, 0, + mpe ->InputChannels, BaseOffset, Curves, WriteMPECurve)) return FALSE; + + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); +} + + + +// The matrix is organized as an array of PxQ+Q elements, where P is the number of input channels to the +// matrix, and Q is the number of output channels. The matrix elements are each float32Numbers. The array +// is organized as follows: +// array = [e11, e12, ..., e1P, e21, e22, ..., e2P, ..., eQ1, eQ2, ..., eQP, e1, e2, ..., eQ] + +static +void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsStage* mpe; + cmsUInt16Number InputChans, OutputChans; + cmsUInt32Number nElems, i; + cmsFloat64Number* Matrix; + cmsFloat64Number* Offsets; + + if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; + if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + + + // Input and output chans may be ANY (up to 0xffff), + // but we choose to limit to 16 channels for now + if (InputChans >= cmsMAXCHANNELS) return NULL; + if (OutputChans >= cmsMAXCHANNELS) return NULL; + + nElems = (cmsUInt32Number) InputChans * OutputChans; + + Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number)); + if (Matrix == NULL) return NULL; + + Offsets = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, OutputChans, sizeof(cmsFloat64Number)); + if (Offsets == NULL) { + + _cmsFree(self ->ContextID, Matrix); + return NULL; + } + + for (i=0; i < nElems; i++) { + + cmsFloat32Number v; + + if (!_cmsReadFloat32Number(io, &v)) { + _cmsFree(self ->ContextID, Matrix); + _cmsFree(self ->ContextID, Offsets); + return NULL; + } + Matrix[i] = v; + } + + + for (i=0; i < OutputChans; i++) { + + cmsFloat32Number v; + + if (!_cmsReadFloat32Number(io, &v)) { + _cmsFree(self ->ContextID, Matrix); + _cmsFree(self ->ContextID, Offsets); + return NULL; + } + Offsets[i] = v; + } + + + mpe = cmsStageAllocMatrix(self ->ContextID, OutputChans, InputChans, Matrix, Offsets); + _cmsFree(self ->ContextID, Matrix); + _cmsFree(self ->ContextID, Offsets); + + *nItems = 1; + + return mpe; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +static +cmsBool Type_MPEmatrix_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUInt32Number i, nElems; + cmsStage* mpe = (cmsStage*) Ptr; + _cmsStageMatrixData* Matrix = (_cmsStageMatrixData*) mpe ->Data; + + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->OutputChannels)) return FALSE; + + nElems = mpe ->InputChannels * mpe ->OutputChannels; + + for (i=0; i < nElems; i++) { + if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) Matrix->Double[i])) return FALSE; + } + + + for (i=0; i < mpe ->OutputChannels; i++) { + + if (Matrix ->Offset == NULL) { + + if (!_cmsWriteFloat32Number(io, 0)) return FALSE; + } + else { + if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) Matrix->Offset[i])) return FALSE; + } + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + + +static +void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsStage* mpe = NULL; + cmsUInt16Number InputChans, OutputChans; + cmsUInt8Number Dimensions8[16]; + cmsUInt32Number i, nMaxGrids, GridPoints[MAX_INPUT_DIMENSIONS]; + _cmsStageCLutData* clut; + + if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; + if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + + if (InputChans == 0) goto Error; + if (OutputChans == 0) goto Error; + + if (io ->Read(io, Dimensions8, sizeof(cmsUInt8Number), 16) != 16) + goto Error; + + // Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number + nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? (cmsUInt32Number) MAX_INPUT_DIMENSIONS : InputChans; + + for (i = 0; i < nMaxGrids; i++) { + if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least + GridPoints[i] = (cmsUInt32Number)Dimensions8[i]; + } + + // Allocate the true CLUT + mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL); + if (mpe == NULL) goto Error; + + // Read and sanitize the data + clut = (_cmsStageCLutData*) mpe ->Data; + for (i=0; i < clut ->nEntries; i++) { + + if (!_cmsReadFloat32Number(io, &clut->Tab.TFloat[i])) goto Error; + } + + *nItems = 1; + return mpe; + +Error: + *nItems = 0; + if (mpe != NULL) cmsStageFree(mpe); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + +// Write a CLUT in floating point +static +cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUInt8Number Dimensions8[16]; // 16 because the spec says 16 and not max number of channels + cmsUInt32Number i; + cmsStage* mpe = (cmsStage*) Ptr; + _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data; + + // Check for maximum number of channels supported by lcms + if (mpe -> InputChannels > MAX_INPUT_DIMENSIONS) return FALSE; + + // Only floats are supported in MPE + if (clut ->HasFloatValues == FALSE) return FALSE; + + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->OutputChannels)) return FALSE; + + memset(Dimensions8, 0, sizeof(Dimensions8)); + + for (i=0; i < mpe ->InputChannels; i++) + Dimensions8[i] = (cmsUInt8Number) clut ->Params ->nSamples[i]; + + if (!io ->Write(io, 16, Dimensions8)) return FALSE; + + for (i=0; i < clut ->nEntries; i++) { + + if (!_cmsWriteFloat32Number(io, clut ->Tab.TFloat[i])) return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(nItems); + cmsUNUSED_PARAMETER(self); +} + + + +// This is the list of built-in MPE types +static _cmsTagTypeLinkedList SupportedMPEtypes[] = { + +{{ (cmsTagTypeSignature) cmsSigBAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[1] }, // Ignore those elements for now +{{ (cmsTagTypeSignature) cmsSigEAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[2] }, // (That's what the spec says) + +{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCurveSetElemType, MPEcurve), &SupportedMPEtypes[3] }, +{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigMatrixElemType, MPEmatrix), &SupportedMPEtypes[4] }, +{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCLutElemType, MPEclut), NULL }, +}; + +_cmsTagTypePluginChunkType _cmsMPETypePluginChunk = { NULL }; + +static +cmsBool ReadMPEElem(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Cargo, + cmsUInt32Number n, + cmsUInt32Number SizeOfTag) +{ + cmsStageSignature ElementSig; + cmsTagTypeHandler* TypeHandler; + cmsUInt32Number nItems; + cmsPipeline *NewLUT = (cmsPipeline *) Cargo; + _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin); + + + // Take signature and channels for each element. + if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return FALSE; + + // The reserved placeholder + if (!_cmsReadUInt32Number(io, NULL)) return FALSE; + + // Read diverse MPE types + TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk ->TagTypes, SupportedMPEtypes); + if (TypeHandler == NULL) { + + char String[5]; + + _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); + + // An unknown element was found. + cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown MPE type '%s' found.", String); + return FALSE; + } + + // If no read method, just ignore the element (valid for cmsSigBAcsElemType and cmsSigEAcsElemType) + // Read the MPE. No size is given + if (TypeHandler ->ReadPtr != NULL) { + + // This is a real element which should be read and processed + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, (cmsStage*) TypeHandler ->ReadPtr(self, io, &nItems, SizeOfTag))) + return FALSE; + } + + return TRUE; + + cmsUNUSED_PARAMETER(SizeOfTag); + cmsUNUSED_PARAMETER(n); +} + + +// This is the main dispatcher for MPE +static +void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsUInt16Number InputChans, OutputChans; + cmsUInt32Number ElementCount; + cmsPipeline *NewLUT = NULL; + cmsUInt32Number BaseOffset; + + // Get actual position as a basis for element offsets + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + // Read channels and element count + if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; + if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + + if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) return NULL; + if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) return NULL; + + // Allocates an empty LUT + NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans); + if (NewLUT == NULL) return NULL; + + if (!_cmsReadUInt32Number(io, &ElementCount)) goto Error; + if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) goto Error; + + // Check channel count + if (InputChans != NewLUT->InputChannels || + OutputChans != NewLUT->OutputChannels) goto Error; + + // Success + *nItems = 1; + return NewLUT; + + // Error +Error: + if (NewLUT != NULL) cmsPipelineFree(NewLUT); + *nItems = 0; + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + + +// This one is a little bit more complex, so we don't use position tables this time. +static +cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsUInt32Number i, BaseOffset, DirectoryPos, CurrentPos; + cmsUInt32Number inputChan, outputChan; + cmsUInt32Number ElemCount; + cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL, Before; + cmsStageSignature ElementSig; + cmsPipeline* Lut = (cmsPipeline*) Ptr; + cmsStage* Elem = Lut ->Elements; + cmsTagTypeHandler* TypeHandler; + _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin); + + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + inputChan = cmsPipelineInputChannels(Lut); + outputChan = cmsPipelineOutputChannels(Lut); + ElemCount = cmsPipelineStageCount(Lut); + + ElementOffsets = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number)); + if (ElementOffsets == NULL) goto Error; + + ElementSizes = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number)); + if (ElementSizes == NULL) goto Error; + + // Write the head + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) inputChan)) goto Error; + if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) outputChan)) goto Error; + if (!_cmsWriteUInt32Number(io, (cmsUInt16Number) ElemCount)) goto Error; + + DirectoryPos = io ->Tell(io); + + // Write a fake directory to be filled latter on + for (i=0; i < ElemCount; i++) { + if (!_cmsWriteUInt32Number(io, 0)) goto Error; // Offset + if (!_cmsWriteUInt32Number(io, 0)) goto Error; // size + } + + // Write each single tag. Keep track of the size as well. + for (i=0; i < ElemCount; i++) { + + ElementOffsets[i] = io ->Tell(io) - BaseOffset; + + ElementSig = Elem ->Type; + + TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk->TagTypes, SupportedMPEtypes); + if (TypeHandler == NULL) { + + char String[5]; + + _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); + + // An unknown element was found. + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Found unknown MPE type '%s'", String); + goto Error; + } + + if (!_cmsWriteUInt32Number(io, ElementSig)) goto Error; + if (!_cmsWriteUInt32Number(io, 0)) goto Error; + Before = io ->Tell(io); + if (!TypeHandler ->WritePtr(self, io, Elem, 1)) goto Error; + if (!_cmsWriteAlignment(io)) goto Error; + + ElementSizes[i] = io ->Tell(io) - Before; + + Elem = Elem ->Next; + } + + // Write the directory + CurrentPos = io ->Tell(io); + + if (!io ->Seek(io, DirectoryPos)) goto Error; + + for (i=0; i < ElemCount; i++) { + if (!_cmsWriteUInt32Number(io, ElementOffsets[i])) goto Error; + if (!_cmsWriteUInt32Number(io, ElementSizes[i])) goto Error; + } + + if (!io ->Seek(io, CurrentPos)) goto Error; + + if (ElementOffsets != NULL) _cmsFree(self ->ContextID, ElementOffsets); + if (ElementSizes != NULL) _cmsFree(self ->ContextID, ElementSizes); + return TRUE; + +Error: + if (ElementOffsets != NULL) _cmsFree(self ->ContextID, ElementOffsets); + if (ElementSizes != NULL) _cmsFree(self ->ContextID, ElementSizes); + return FALSE; + + cmsUNUSED_PARAMETER(nItems); +} + + +static +void* Type_MPE_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsPipelineDup((cmsPipeline*) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + +static +void Type_MPE_Free(struct _cms_typehandler_struct* self, void *Ptr) +{ + cmsPipelineFree((cmsPipeline*) Ptr); + return; + + cmsUNUSED_PARAMETER(self); +} + + +// ******************************************************************************** +// Type cmsSigVcgtType +// ******************************************************************************** + + +#define cmsVideoCardGammaTableType 0 +#define cmsVideoCardGammaFormulaType 1 + +// Used internally +typedef struct { + double Gamma; + double Min; + double Max; +} _cmsVCGTGAMMA; + + +static +void *Type_vcgt_Read(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + cmsUInt32Number* nItems, + cmsUInt32Number SizeOfTag) +{ + cmsUInt32Number TagType, n, i; + cmsToneCurve** Curves; + + *nItems = 0; + + // Read tag type + if (!_cmsReadUInt32Number(io, &TagType)) return NULL; + + // Allocate space for the array + Curves = ( cmsToneCurve**) _cmsCalloc(self ->ContextID, 3, sizeof(cmsToneCurve*)); + if (Curves == NULL) return NULL; + + // There are two possible flavors + switch (TagType) { + + // Gamma is stored as a table + case cmsVideoCardGammaTableType: + { + cmsUInt16Number nChannels, nElems, nBytes; + + // Check channel count, which should be 3 (we don't support monochrome this time) + if (!_cmsReadUInt16Number(io, &nChannels)) goto Error; + + if (nChannels != 3) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported number of channels for VCGT '%d'", nChannels); + goto Error; + } + + // Get Table element count and bytes per element + if (!_cmsReadUInt16Number(io, &nElems)) goto Error; + if (!_cmsReadUInt16Number(io, &nBytes)) goto Error; + + // Adobe's quirk fixup. Fixing broken profiles... + if (nElems == 256 && nBytes == 1 && SizeOfTag == 1576) + nBytes = 2; + + + // Populate tone curves + for (n=0; n < 3; n++) { + + Curves[n] = cmsBuildTabulatedToneCurve16(self ->ContextID, nElems, NULL); + if (Curves[n] == NULL) goto Error; + + // On depending on byte depth + switch (nBytes) { + + // One byte, 0..255 + case 1: + for (i=0; i < nElems; i++) { + + cmsUInt8Number v; + + if (!_cmsReadUInt8Number(io, &v)) goto Error; + Curves[n] ->Table16[i] = FROM_8_TO_16(v); + } + break; + + // One word 0..65535 + case 2: + if (!_cmsReadUInt16Array(io, nElems, Curves[n]->Table16)) goto Error; + break; + + // Unsupported + default: + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported bit depth for VCGT '%d'", nBytes * 8); + goto Error; + } + } // For all 3 channels + } + break; + + // In this case, gamma is stored as a formula + case cmsVideoCardGammaFormulaType: + { + _cmsVCGTGAMMA Colorant[3]; + + // Populate tone curves + for (n=0; n < 3; n++) { + + double Params[10]; + + if (!_cmsRead15Fixed16Number(io, &Colorant[n].Gamma)) goto Error; + if (!_cmsRead15Fixed16Number(io, &Colorant[n].Min)) goto Error; + if (!_cmsRead15Fixed16Number(io, &Colorant[n].Max)) goto Error; + + // Parametric curve type 5 is: + // Y = (aX + b)^Gamma + e | X >= d + // Y = cX + f | X < d + + // vcgt formula is: + // Y = (Max - Min) * (X ^ Gamma) + Min + + // So, the translation is + // a = (Max - Min) ^ ( 1 / Gamma) + // e = Min + // b=c=d=f=0 + + Params[0] = Colorant[n].Gamma; + Params[1] = pow((Colorant[n].Max - Colorant[n].Min), (1.0 / Colorant[n].Gamma)); + Params[2] = 0; + Params[3] = 0; + Params[4] = 0; + Params[5] = Colorant[n].Min; + Params[6] = 0; + + Curves[n] = cmsBuildParametricToneCurve(self ->ContextID, 5, Params); + if (Curves[n] == NULL) goto Error; + } + } + break; + + // Unsupported + default: + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported tag type for VCGT '%d'", TagType); + goto Error; + } + + *nItems = 1; + return (void*) Curves; + +// Regret, free all resources +Error: + + cmsFreeToneCurveTriple(Curves); + _cmsFree(self ->ContextID, Curves); + return NULL; + + cmsUNUSED_PARAMETER(SizeOfTag); +} + + +// We don't support all flavors, only 16bits tables and formula +static +cmsBool Type_vcgt_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsToneCurve** Curves = (cmsToneCurve**) Ptr; + cmsUInt32Number i, j; + + if (cmsGetToneCurveParametricType(Curves[0]) == 5 && + cmsGetToneCurveParametricType(Curves[1]) == 5 && + cmsGetToneCurveParametricType(Curves[2]) == 5) { + + if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaFormulaType)) return FALSE; + + // Save parameters + for (i=0; i < 3; i++) { + + _cmsVCGTGAMMA v; + + v.Gamma = Curves[i] ->Segments[0].Params[0]; + v.Min = Curves[i] ->Segments[0].Params[5]; + v.Max = pow(Curves[i] ->Segments[0].Params[1], v.Gamma) + v.Min; + + if (!_cmsWrite15Fixed16Number(io, v.Gamma)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, v.Min)) return FALSE; + if (!_cmsWrite15Fixed16Number(io, v.Max)) return FALSE; + } + } + + else { + + // Always store as a table of 256 words + if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaTableType)) return FALSE; + if (!_cmsWriteUInt16Number(io, 3)) return FALSE; + if (!_cmsWriteUInt16Number(io, 256)) return FALSE; + if (!_cmsWriteUInt16Number(io, 2)) return FALSE; + + for (i=0; i < 3; i++) { + for (j=0; j < 256; j++) { + + cmsFloat32Number v = cmsEvalToneCurveFloat(Curves[i], (cmsFloat32Number) (j / 255.0)); + cmsUInt16Number n = _cmsQuickSaturateWord(v * 65535.0); + + if (!_cmsWriteUInt16Number(io, n)) return FALSE; + } + } + } + + return TRUE; + + cmsUNUSED_PARAMETER(self); + cmsUNUSED_PARAMETER(nItems); +} + +static +void* Type_vcgt_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + cmsToneCurve** OldCurves = (cmsToneCurve**) Ptr; + cmsToneCurve** NewCurves; + + NewCurves = ( cmsToneCurve**) _cmsCalloc(self ->ContextID, 3, sizeof(cmsToneCurve*)); + if (NewCurves == NULL) return NULL; + + NewCurves[0] = cmsDupToneCurve(OldCurves[0]); + NewCurves[1] = cmsDupToneCurve(OldCurves[1]); + NewCurves[2] = cmsDupToneCurve(OldCurves[2]); + + return (void*) NewCurves; + + cmsUNUSED_PARAMETER(n); +} + + +static +void Type_vcgt_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsFreeToneCurveTriple((cmsToneCurve**) Ptr); + _cmsFree(self ->ContextID, Ptr); +} + + +// ******************************************************************************** +// Type cmsSigDictType +// ******************************************************************************** + +// Single column of the table can point to wchar or MLUC elements. Holds arrays of data +typedef struct { + cmsContext ContextID; + cmsUInt32Number *Offsets; + cmsUInt32Number *Sizes; +} _cmsDICelem; + +typedef struct { + _cmsDICelem Name, Value, DisplayName, DisplayValue; + +} _cmsDICarray; + +// Allocate an empty array element +static +cmsBool AllocElem(cmsContext ContextID, _cmsDICelem* e, cmsUInt32Number Count) +{ + e->Offsets = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number)); + if (e->Offsets == NULL) return FALSE; + + e->Sizes = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number)); + if (e->Sizes == NULL) { + + _cmsFree(ContextID, e -> Offsets); + return FALSE; + } + + e ->ContextID = ContextID; + return TRUE; +} + +// Free an array element +static +void FreeElem(_cmsDICelem* e) +{ + if (e ->Offsets != NULL) _cmsFree(e -> ContextID, e -> Offsets); + if (e ->Sizes != NULL) _cmsFree(e -> ContextID, e -> Sizes); + e->Offsets = e ->Sizes = NULL; +} + +// Get rid of whole array +static +void FreeArray( _cmsDICarray* a) +{ + if (a ->Name.Offsets != NULL) FreeElem(&a->Name); + if (a ->Value.Offsets != NULL) FreeElem(&a ->Value); + if (a ->DisplayName.Offsets != NULL) FreeElem(&a->DisplayName); + if (a ->DisplayValue.Offsets != NULL) FreeElem(&a ->DisplayValue); +} + + +// Allocate whole array +static +cmsBool AllocArray(cmsContext ContextID, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length) +{ + // Empty values + memset(a, 0, sizeof(_cmsDICarray)); + + // On depending on record size, create column arrays + if (!AllocElem(ContextID, &a ->Name, Count)) goto Error; + if (!AllocElem(ContextID, &a ->Value, Count)) goto Error; + + if (Length > 16) { + if (!AllocElem(ContextID, &a -> DisplayName, Count)) goto Error; + + } + if (Length > 24) { + if (!AllocElem(ContextID, &a ->DisplayValue, Count)) goto Error; + } + return TRUE; + +Error: + FreeArray(a); + return FALSE; +} + +// Read one element +static +cmsBool ReadOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsUInt32Number BaseOffset) +{ + if (!_cmsReadUInt32Number(io, &e->Offsets[i])) return FALSE; + if (!_cmsReadUInt32Number(io, &e ->Sizes[i])) return FALSE; + + // An offset of zero has special meaning and shall be preserved + if (e ->Offsets[i] > 0) + e ->Offsets[i] += BaseOffset; + return TRUE; +} + + +static +cmsBool ReadOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, + cmsUInt32Number Count, cmsUInt32Number Length, cmsUInt32Number BaseOffset, + cmsInt32Number* SignedSizeOfTagPtr) +{ + cmsUInt32Number i; + cmsInt32Number SignedSizeOfTag = *SignedSizeOfTagPtr; + + // Read column arrays + for (i=0; i < Count; i++) { + + if (SignedSizeOfTag < 4 * (cmsInt32Number) sizeof(cmsUInt32Number)) return FALSE; + SignedSizeOfTag -= 4 * sizeof(cmsUInt32Number); + + if (!ReadOneElem(io, &a -> Name, i, BaseOffset)) return FALSE; + if (!ReadOneElem(io, &a -> Value, i, BaseOffset)) return FALSE; + + if (Length > 16) { + + if (SignedSizeOfTag < 2 * (cmsInt32Number) sizeof(cmsUInt32Number)) return FALSE; + SignedSizeOfTag -= 2 * sizeof(cmsUInt32Number); + + if (!ReadOneElem(io, &a ->DisplayName, i, BaseOffset)) return FALSE; + + } + + if (Length > 24) { + + if (SignedSizeOfTag < 2 * (cmsInt32Number) sizeof(cmsUInt32Number)) return FALSE; + SignedSizeOfTag -= 2 * (cmsInt32Number) sizeof(cmsUInt32Number); + + if (!ReadOneElem(io, & a -> DisplayValue, i, BaseOffset)) return FALSE; + } + } + + *SignedSizeOfTagPtr = SignedSizeOfTag; + return TRUE; +} + + +// Write one element +static +cmsBool WriteOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i) +{ + if (!_cmsWriteUInt32Number(io, e->Offsets[i])) return FALSE; + if (!_cmsWriteUInt32Number(io, e ->Sizes[i])) return FALSE; + + return TRUE; +} + +static +cmsBool WriteOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length) +{ + cmsUInt32Number i; + + for (i=0; i < Count; i++) { + + if (!WriteOneElem(io, &a -> Name, i)) return FALSE; + if (!WriteOneElem(io, &a -> Value, i)) return FALSE; + + if (Length > 16) { + + if (!WriteOneElem(io, &a -> DisplayName, i)) return FALSE; + } + + if (Length > 24) { + + if (!WriteOneElem(io, &a -> DisplayValue, i)) return FALSE; + } + } + + return TRUE; +} + +static +cmsBool ReadOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, wchar_t ** wcstr) +{ + + cmsUInt32Number nChars; + + // Special case for undefined strings (see ICC Votable + // Proposal Submission, Dictionary Type and Metadata TAG Definition) + if (e -> Offsets[i] == 0) { + + *wcstr = NULL; + return TRUE; + } + + if (!io -> Seek(io, e -> Offsets[i])) return FALSE; + + nChars = e ->Sizes[i] / sizeof(cmsUInt16Number); + + + *wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, (nChars + 1) * sizeof(wchar_t)); + if (*wcstr == NULL) return FALSE; + + if (!_cmsReadWCharArray(io, nChars, *wcstr)) { + _cmsFree(e ->ContextID, *wcstr); + return FALSE; + } + + // End of string marker + (*wcstr)[nChars] = 0; + return TRUE; +} + +static +cmsUInt32Number mywcslen(const wchar_t *s) +{ + const wchar_t *p; + + p = s; + while (*p) + p++; + + return (cmsUInt32Number)(p - s); +} + +static +cmsBool WriteOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const wchar_t * wcstr, cmsUInt32Number BaseOffset) +{ + cmsUInt32Number Before = io ->Tell(io); + cmsUInt32Number n; + + e ->Offsets[i] = Before - BaseOffset; + + if (wcstr == NULL) { + e ->Sizes[i] = 0; + e ->Offsets[i] = 0; + return TRUE; + } + + n = mywcslen(wcstr); + if (!_cmsWriteWCharArray(io, n, wcstr)) return FALSE; + + e ->Sizes[i] = io ->Tell(io) - Before; + return TRUE; +} + +static +cmsBool ReadOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsMLU** mlu) +{ + cmsUInt32Number nItems = 0; + + // A way to get null MLUCs + if (e -> Offsets[i] == 0 || e ->Sizes[i] == 0) { + + *mlu = NULL; + return TRUE; + } + + if (!io -> Seek(io, e -> Offsets[i])) return FALSE; + + *mlu = (cmsMLU*) Type_MLU_Read(self, io, &nItems, e ->Sizes[i]); + return *mlu != NULL; +} + +static +cmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const cmsMLU* mlu, cmsUInt32Number BaseOffset) +{ + cmsUInt32Number Before; + + // Special case for undefined strings (see ICC Votable + // Proposal Submission, Dictionary Type and Metadata TAG Definition) + if (mlu == NULL) { + e ->Sizes[i] = 0; + e ->Offsets[i] = 0; + return TRUE; + } + + Before = io ->Tell(io); + e ->Offsets[i] = Before - BaseOffset; + + if (!Type_MLU_Write(self, io, (void*) mlu, 1)) return FALSE; + + e ->Sizes[i] = io ->Tell(io) - Before; + return TRUE; +} + + +static +void *Type_Dictionary_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsHANDLE hDict = NULL; + cmsUInt32Number i, Count, Length; + cmsUInt32Number BaseOffset; + _cmsDICarray a; + wchar_t *NameWCS = NULL, *ValueWCS = NULL; + cmsMLU *DisplayNameMLU = NULL, *DisplayValueMLU=NULL; + cmsBool rc; + cmsInt32Number SignedSizeOfTag = (cmsInt32Number)SizeOfTag; + + *nItems = 0; + memset(&a, 0, sizeof(a)); + + // Get actual position as a basis for element offsets + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + // Get name-value record count + SignedSizeOfTag -= sizeof(cmsUInt32Number); + if (SignedSizeOfTag < 0) goto Error; + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + + // Get rec length + SignedSizeOfTag -= sizeof(cmsUInt32Number); + if (SignedSizeOfTag < 0) goto Error; + if (!_cmsReadUInt32Number(io, &Length)) return NULL; + + + // Check for valid lengths + if (Length != 16 && Length != 24 && Length != 32) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown record length in dictionary '%d'", Length); + return NULL; + } + + // Creates an empty dictionary + hDict = cmsDictAlloc(self -> ContextID); + if (hDict == NULL) return NULL; + + // On depending on record size, create column arrays + if (!AllocArray(self -> ContextID, &a, Count, Length)) goto Error; + + // Read column arrays + if (!ReadOffsetArray(io, &a, Count, Length, BaseOffset, &SignedSizeOfTag)) goto Error; + + // Seek to each element and read it + for (i=0; i < Count; i++) { + + if (!ReadOneWChar(io, &a.Name, i, &NameWCS)) goto Error; + if (!ReadOneWChar(io, &a.Value, i, &ValueWCS)) goto Error; + + if (Length > 16) { + if (!ReadOneMLUC(self, io, &a.DisplayName, i, &DisplayNameMLU)) goto Error; + } + + if (Length > 24) { + if (!ReadOneMLUC(self, io, &a.DisplayValue, i, &DisplayValueMLU)) goto Error; + } + + if (NameWCS == NULL || ValueWCS == NULL) { + + cmsSignalError(self->ContextID, cmsERROR_CORRUPTION_DETECTED, "Bad dictionary Name/Value"); + rc = FALSE; + } + else { + + rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU); + } + + if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS); + if (ValueWCS != NULL) _cmsFree(self ->ContextID, ValueWCS); + if (DisplayNameMLU != NULL) cmsMLUfree(DisplayNameMLU); + if (DisplayValueMLU != NULL) cmsMLUfree(DisplayValueMLU); + + if (!rc) goto Error; + } + + FreeArray(&a); + *nItems = 1; + return (void*) hDict; + +Error: + FreeArray(&a); + if (hDict != NULL) cmsDictFree(hDict); + return NULL; +} + + +static +cmsBool Type_Dictionary_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsHANDLE hDict = (cmsHANDLE) Ptr; + const cmsDICTentry* p; + cmsBool AnyName, AnyValue; + cmsUInt32Number i, Count, Length; + cmsUInt32Number DirectoryPos, CurrentPos, BaseOffset; + _cmsDICarray a; + + if (hDict == NULL) return FALSE; + + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + // Let's inspect the dictionary + Count = 0; AnyName = FALSE; AnyValue = FALSE; + for (p = cmsDictGetEntryList(hDict); p != NULL; p = cmsDictNextEntry(p)) { + + if (p ->DisplayName != NULL) AnyName = TRUE; + if (p ->DisplayValue != NULL) AnyValue = TRUE; + Count++; + } + + Length = 16; + if (AnyName) Length += 8; + if (AnyValue) Length += 8; + + if (!_cmsWriteUInt32Number(io, Count)) return FALSE; + if (!_cmsWriteUInt32Number(io, Length)) return FALSE; + + // Keep starting position of offsets table + DirectoryPos = io ->Tell(io); + + // Allocate offsets array + if (!AllocArray(self ->ContextID, &a, Count, Length)) goto Error; + + // Write a fake directory to be filled latter on + if (!WriteOffsetArray(io, &a, Count, Length)) goto Error; + + // Write each element. Keep track of the size as well. + p = cmsDictGetEntryList(hDict); + for (i=0; i < Count; i++) { + + if (!WriteOneWChar(io, &a.Name, i, p ->Name, BaseOffset)) goto Error; + if (!WriteOneWChar(io, &a.Value, i, p ->Value, BaseOffset)) goto Error; + + if (p ->DisplayName != NULL) { + if (!WriteOneMLUC(self, io, &a.DisplayName, i, p ->DisplayName, BaseOffset)) goto Error; + } + + if (p ->DisplayValue != NULL) { + if (!WriteOneMLUC(self, io, &a.DisplayValue, i, p ->DisplayValue, BaseOffset)) goto Error; + } + + p = cmsDictNextEntry(p); + } + + // Write the directory + CurrentPos = io ->Tell(io); + if (!io ->Seek(io, DirectoryPos)) goto Error; + + if (!WriteOffsetArray(io, &a, Count, Length)) goto Error; + + if (!io ->Seek(io, CurrentPos)) goto Error; + + FreeArray(&a); + return TRUE; + +Error: + FreeArray(&a); + return FALSE; + + cmsUNUSED_PARAMETER(nItems); +} + + +static +void* Type_Dictionary_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) +{ + return (void*) cmsDictDup((cmsHANDLE) Ptr); + + cmsUNUSED_PARAMETER(n); + cmsUNUSED_PARAMETER(self); +} + + +static +void Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + cmsDictFree((cmsHANDLE) Ptr); + cmsUNUSED_PARAMETER(self); +} + +// cicp VideoSignalType + +static +void* Type_VideoSignal_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) +{ + cmsVideoSignalType* cicp = NULL; + + if (SizeOfTag != 8) return NULL; + + if (!_cmsReadUInt32Number(io, NULL)) return NULL; + + cicp = (cmsVideoSignalType*)_cmsCalloc(self->ContextID, 1, sizeof(cmsVideoSignalType)); + if (cicp == NULL) return NULL; + + if (!_cmsReadUInt8Number(io, &cicp->ColourPrimaries)) goto Error; + if (!_cmsReadUInt8Number(io, &cicp->TransferCharacteristics)) goto Error; + if (!_cmsReadUInt8Number(io, &cicp->MatrixCoefficients)) goto Error; + if (!_cmsReadUInt8Number(io, &cicp->VideoFullRangeFlag)) goto Error; + + // Success + *nItems = 1; + return cicp; + +Error: + if (cicp != NULL) _cmsFree(self->ContextID, cicp); + return NULL; +} + +static +cmsBool Type_VideoSignal_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +{ + cmsVideoSignalType* cicp = (cmsVideoSignalType*)Ptr; + + if (!_cmsWriteUInt32Number(io, 0)) return FALSE; + if (!_cmsWriteUInt8Number(io, cicp->ColourPrimaries)) return FALSE; + if (!_cmsWriteUInt8Number(io, cicp->TransferCharacteristics)) return FALSE; + if (!_cmsWriteUInt8Number(io, cicp->MatrixCoefficients)) return FALSE; + if (!_cmsWriteUInt8Number(io, cicp->VideoFullRangeFlag)) return FALSE; + + return TRUE; + + cmsUNUSED_PARAMETER(self); + cmsUNUSED_PARAMETER(nItems); +} + +void* Type_VideoSignal_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsVideoSignalType)); + + cmsUNUSED_PARAMETER(n); +} + + +static +void Type_VideoSignal_Free(struct _cms_typehandler_struct* self, void* Ptr) +{ + _cmsFree(self->ContextID, Ptr); +} + +// ******************************************************************************** +// Type support main routines +// ******************************************************************************** + + +// This is the list of built-in types +static const _cmsTagTypeLinkedList SupportedTagTypes[] = { + +{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), (_cmsTagTypeLinkedList*) &SupportedTagTypes[1] }, +{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), (_cmsTagTypeLinkedList*) &SupportedTagTypes[2] }, +{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[3] }, +{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[4] }, +{TYPE_HANDLER(cmsSigTextType, Text), (_cmsTagTypeLinkedList*) &SupportedTagTypes[5] }, +{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), (_cmsTagTypeLinkedList*) &SupportedTagTypes[6] }, +{TYPE_HANDLER(cmsSigCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[7] }, +{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[8] }, +{TYPE_HANDLER(cmsSigDateTimeType, DateTime), (_cmsTagTypeLinkedList*) &SupportedTagTypes[9] }, +{TYPE_HANDLER(cmsSigLut8Type, LUT8), (_cmsTagTypeLinkedList*) &SupportedTagTypes[10] }, +{TYPE_HANDLER(cmsSigLut16Type, LUT16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[11] }, +{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), (_cmsTagTypeLinkedList*) &SupportedTagTypes[12] }, +{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), (_cmsTagTypeLinkedList*) &SupportedTagTypes[13] }, +{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), (_cmsTagTypeLinkedList*) &SupportedTagTypes[14] }, +{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc),(_cmsTagTypeLinkedList*) &SupportedTagTypes[15] }, +{TYPE_HANDLER(cmsSigSignatureType, Signature), (_cmsTagTypeLinkedList*) &SupportedTagTypes[16] }, +{TYPE_HANDLER(cmsSigMeasurementType, Measurement), (_cmsTagTypeLinkedList*) &SupportedTagTypes[17] }, +{TYPE_HANDLER(cmsSigDataType, Data), (_cmsTagTypeLinkedList*) &SupportedTagTypes[18] }, +{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), (_cmsTagTypeLinkedList*) &SupportedTagTypes[19] }, +{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), (_cmsTagTypeLinkedList*) &SupportedTagTypes[20] }, +{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), (_cmsTagTypeLinkedList*) &SupportedTagTypes[21] }, +{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), (_cmsTagTypeLinkedList*) &SupportedTagTypes[22] }, +{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), (_cmsTagTypeLinkedList*) &SupportedTagTypes[23] }, +{TYPE_HANDLER(cmsSigScreeningType, Screening), (_cmsTagTypeLinkedList*) &SupportedTagTypes[24] }, +{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), (_cmsTagTypeLinkedList*) &SupportedTagTypes[25] }, +{TYPE_HANDLER(cmsSigXYZType, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[26] }, +{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[27] }, +{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[28] }, +{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] }, +{TYPE_HANDLER(cmsSigDictType, Dictionary), (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] }, +{TYPE_HANDLER(cmsSigcicpType, VideoSignal), (_cmsTagTypeLinkedList*) &SupportedTagTypes[31] }, +{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL } +}; + + +_cmsTagTypePluginChunkType _cmsTagTypePluginChunk = { NULL }; + + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupTagTypeList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src, + int loc) +{ + _cmsTagTypePluginChunkType newHead = { NULL }; + _cmsTagTypeLinkedList* entry; + _cmsTagTypeLinkedList* Anterior = NULL; + _cmsTagTypePluginChunkType* head = (_cmsTagTypePluginChunkType*) src->chunks[loc]; + + // Walk the list copying all nodes + for (entry = head->TagTypes; + entry != NULL; + entry = entry ->Next) { + + _cmsTagTypeLinkedList *newEntry = ( _cmsTagTypeLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagTypeLinkedList)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.TagTypes == NULL) + newHead.TagTypes = newEntry; + } + + ctx ->chunks[loc] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagTypePluginChunkType)); +} + + +void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Duplicate the LIST + DupTagTypeList(ctx, src, TagTypePlugin); + } + else { + static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL }; + ctx ->chunks[TagTypePlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType)); + } +} + +void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Duplicate the LIST + DupTagTypeList(ctx, src, MPEPlugin); + } + else { + static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL }; + ctx ->chunks[MPEPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType)); + } + +} + + +// Both kind of plug-ins share same structure +cmsBool _cmsRegisterTagTypePlugin(cmsContext id, cmsPluginBase* Data) +{ + return RegisterTypesPlugin(id, Data, TagTypePlugin); +} + +cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext id, cmsPluginBase* Data) +{ + return RegisterTypesPlugin(id, Data,MPEPlugin); +} + + +// Wrapper for tag types +cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig) +{ + _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin); + + return GetHandler(sig, ctx->TagTypes, (_cmsTagTypeLinkedList*) SupportedTagTypes); +} + +// ******************************************************************************** +// Tag support main routines +// ******************************************************************************** + +typedef struct _cmsTagLinkedList_st { + + cmsTagSignature Signature; + cmsTagDescriptor Descriptor; + struct _cmsTagLinkedList_st* Next; + +} _cmsTagLinkedList; + +// This is the list of built-in tags. The data of this list can be modified by plug-ins +static _cmsTagLinkedList SupportedTags[] = { + + { cmsSigAToB0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[1]}, + { cmsSigAToB1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[2]}, + { cmsSigAToB2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[3]}, + { cmsSigBToA0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[4]}, + { cmsSigBToA1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[5]}, + { cmsSigBToA2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[6]}, + + // Allow corbis and its broken XYZ type + { cmsSigRedColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[7]}, + { cmsSigGreenColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[8]}, + { cmsSigBlueColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[9]}, + + { cmsSigRedTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[10]}, + { cmsSigGreenTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[11]}, + { cmsSigBlueTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[12]}, + + { cmsSigCalibrationDateTimeTag, { 1, 1, { cmsSigDateTimeType }, NULL}, &SupportedTags[13]}, + { cmsSigCharTargetTag, { 1, 1, { cmsSigTextType }, NULL}, &SupportedTags[14]}, + + { cmsSigChromaticAdaptationTag, { 9, 1, { cmsSigS15Fixed16ArrayType }, NULL}, &SupportedTags[15]}, + { cmsSigChromaticityTag, { 1, 1, { cmsSigChromaticityType }, NULL}, &SupportedTags[16]}, + { cmsSigColorantOrderTag, { 1, 1, { cmsSigColorantOrderType }, NULL}, &SupportedTags[17]}, + { cmsSigColorantTableTag, { 1, 1, { cmsSigColorantTableType }, NULL}, &SupportedTags[18]}, + { cmsSigColorantTableOutTag, { 1, 1, { cmsSigColorantTableType }, NULL}, &SupportedTags[19]}, + + { cmsSigCopyrightTag, { 1, 3, { cmsSigTextType, cmsSigMultiLocalizedUnicodeType, cmsSigTextDescriptionType}, DecideTextType}, &SupportedTags[20]}, + { cmsSigDateTimeTag, { 1, 1, { cmsSigDateTimeType }, NULL}, &SupportedTags[21]}, + + { cmsSigDeviceMfgDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[22]}, + { cmsSigDeviceModelDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[23]}, + + { cmsSigGamutTag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[24]}, + + { cmsSigGrayTRCTag, { 1, 2, { cmsSigCurveType, cmsSigParametricCurveType }, DecideCurveType}, &SupportedTags[25]}, + { cmsSigLuminanceTag, { 1, 1, { cmsSigXYZType }, NULL}, &SupportedTags[26]}, + + { cmsSigMediaBlackPointTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, NULL}, &SupportedTags[27]}, + { cmsSigMediaWhitePointTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, NULL}, &SupportedTags[28]}, + + { cmsSigNamedColor2Tag, { 1, 1, { cmsSigNamedColor2Type }, NULL}, &SupportedTags[29]}, + + { cmsSigPreview0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[30]}, + { cmsSigPreview1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[31]}, + { cmsSigPreview2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[32]}, + + { cmsSigProfileDescriptionTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[33]}, + { cmsSigProfileSequenceDescTag, { 1, 1, { cmsSigProfileSequenceDescType }, NULL}, &SupportedTags[34]}, + { cmsSigTechnologyTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[35]}, + + { cmsSigColorimetricIntentImageStateTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[36]}, + { cmsSigPerceptualRenderingIntentGamutTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[37]}, + { cmsSigSaturationRenderingIntentGamutTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[38]}, + + { cmsSigMeasurementTag, { 1, 1, { cmsSigMeasurementType }, NULL}, &SupportedTags[39]}, + + { cmsSigPs2CRD0Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[40]}, + { cmsSigPs2CRD1Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[41]}, + { cmsSigPs2CRD2Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[42]}, + { cmsSigPs2CRD3Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[43]}, + { cmsSigPs2CSATag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[44]}, + { cmsSigPs2RenderingIntentTag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[45]}, + + { cmsSigViewingCondDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[46]}, + + { cmsSigUcrBgTag, { 1, 1, { cmsSigUcrBgType}, NULL}, &SupportedTags[47]}, + { cmsSigCrdInfoTag, { 1, 1, { cmsSigCrdInfoType}, NULL}, &SupportedTags[48]}, + + { cmsSigDToB0Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[49]}, + { cmsSigDToB1Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[50]}, + { cmsSigDToB2Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[51]}, + { cmsSigDToB3Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[52]}, + { cmsSigBToD0Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[53]}, + { cmsSigBToD1Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[54]}, + { cmsSigBToD2Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[55]}, + { cmsSigBToD3Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[56]}, + + { cmsSigScreeningDescTag, { 1, 1, { cmsSigTextDescriptionType }, NULL}, &SupportedTags[57]}, + { cmsSigViewingConditionsTag, { 1, 1, { cmsSigViewingConditionsType }, NULL}, &SupportedTags[58]}, + + { cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]}, + { cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]}, + { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]}, + { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, + + { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]}, + { cmsSigcicpTag, { 1, 1, { cmsSigcicpType}, NULL }, &SupportedTags[64]}, + + { cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL} + +}; + +/* + Not supported Why + ======================= ========================================= + cmsSigOutputResponseTag ==> WARNING, POSSIBLE PATENT ON THIS SUBJECT! + cmsSigNamedColorTag ==> Deprecated + cmsSigDataTag ==> Ancient, unused + cmsSigDeviceSettingsTag ==> Deprecated, useless +*/ + + +_cmsTagPluginChunkType _cmsTagPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupTagList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsTagPluginChunkType newHead = { NULL }; + _cmsTagLinkedList* entry; + _cmsTagLinkedList* Anterior = NULL; + _cmsTagPluginChunkType* head = (_cmsTagPluginChunkType*) src->chunks[TagPlugin]; + + // Walk the list copying all nodes + for (entry = head->Tag; + entry != NULL; + entry = entry ->Next) { + + _cmsTagLinkedList *newEntry = ( _cmsTagLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagLinkedList)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.Tag == NULL) + newHead.Tag = newEntry; + } + + ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagPluginChunkType)); +} + +void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + DupTagList(ctx, src); + } + else { + static _cmsTagPluginChunkType TagPluginChunk = { NULL }; + ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagPluginChunk, sizeof(_cmsTagPluginChunkType)); + } + +} + +cmsBool _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data) +{ + cmsPluginTag* Plugin = (cmsPluginTag*) Data; + _cmsTagLinkedList *pt; + _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(id, TagPlugin); + + if (Data == NULL) { + + TagPluginChunk->Tag = NULL; + return TRUE; + } + + pt = (_cmsTagLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagLinkedList)); + if (pt == NULL) return FALSE; + + pt ->Signature = Plugin ->Signature; + pt ->Descriptor = Plugin ->Descriptor; + pt ->Next = TagPluginChunk ->Tag; + + TagPluginChunk ->Tag = pt; + + return TRUE; +} + +// Return a descriptor for a given tag or NULL +cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig) +{ + _cmsTagLinkedList* pt; + _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(ContextID, TagPlugin); + + for (pt = TagPluginChunk->Tag; + pt != NULL; + pt = pt ->Next) { + + if (sig == pt -> Signature) return &pt ->Descriptor; + } + + for (pt = SupportedTags; + pt != NULL; + pt = pt ->Next) { + + if (sig == pt -> Signature) return &pt ->Descriptor; + } + + return NULL; +} + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsvirt.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsvirt.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsvirt.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsvirt.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1247 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// Virtual (built-in) profiles +// ----------------------------------------------------------------------------------- + +static +cmsBool SetTextTags(cmsHPROFILE hProfile, const wchar_t* Description) +{ + cmsMLU *DescriptionMLU, *CopyrightMLU; + cmsBool rc = FALSE; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + DescriptionMLU = cmsMLUalloc(ContextID, 1); + CopyrightMLU = cmsMLUalloc(ContextID, 1); + + if (DescriptionMLU == NULL || CopyrightMLU == NULL) goto Error; + + if (!cmsMLUsetWide(DescriptionMLU, "en", "US", Description)) goto Error; + if (!cmsMLUsetWide(CopyrightMLU, "en", "US", L"No copyright, use freely")) goto Error; + + if (!cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Error; + if (!cmsWriteTag(hProfile, cmsSigCopyrightTag, CopyrightMLU)) goto Error; + + rc = TRUE; + +Error: + + if (DescriptionMLU) + cmsMLUfree(DescriptionMLU); + if (CopyrightMLU) + cmsMLUfree(CopyrightMLU); + return rc; +} + + +static +cmsBool SetSeqDescTag(cmsHPROFILE hProfile, const char* Model) +{ + cmsBool rc = FALSE; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsSEQ* Seq = cmsAllocProfileSequenceDescription(ContextID, 1); + + if (Seq == NULL) return FALSE; + + Seq->seq[0].deviceMfg = (cmsSignature) 0; + Seq->seq[0].deviceModel = (cmsSignature) 0; + +#ifdef CMS_DONT_USE_INT64 + Seq->seq[0].attributes[0] = 0; + Seq->seq[0].attributes[1] = 0; +#else + Seq->seq[0].attributes = 0; +#endif + + Seq->seq[0].technology = (cmsTechnologySignature) 0; + + cmsMLUsetASCII( Seq->seq[0].Manufacturer, cmsNoLanguage, cmsNoCountry, "Little CMS"); + cmsMLUsetASCII( Seq->seq[0].Model, cmsNoLanguage, cmsNoCountry, Model); + + if (!_cmsWriteProfileSequence(hProfile, Seq)) goto Error; + + rc = TRUE; + +Error: + if (Seq) + cmsFreeProfileSequenceDescription(Seq); + + return rc; +} + + + +// This function creates a profile based on White point, primaries and +// transfer functions. +cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID, + const cmsCIExyY* WhitePoint, + const cmsCIExyYTRIPLE* Primaries, + cmsToneCurve* const TransferFunction[3]) +{ + cmsHPROFILE hICC; + cmsMAT3 MColorants; + cmsCIEXYZTRIPLE Colorants; + cmsCIExyY MaxWhite; + cmsMAT3 CHAD; + cmsCIEXYZ WhitePointXYZ; + + hICC = cmsCreateProfilePlaceholder(ContextID); + if (!hICC) // can't allocate + return NULL; + + cmsSetProfileVersion(hICC, 4.4); + + cmsSetDeviceClass(hICC, cmsSigDisplayClass); + cmsSetColorSpace(hICC, cmsSigRgbData); + cmsSetPCS(hICC, cmsSigXYZData); + + cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL); + + + // Implement profile using following tags: + // + // 1 cmsSigProfileDescriptionTag + // 2 cmsSigMediaWhitePointTag + // 3 cmsSigRedColorantTag + // 4 cmsSigGreenColorantTag + // 5 cmsSigBlueColorantTag + // 6 cmsSigRedTRCTag + // 7 cmsSigGreenTRCTag + // 8 cmsSigBlueTRCTag + // 9 Chromatic adaptation Tag + // This conforms a standard RGB DisplayProfile as says ICC, and then I add (As per addendum II) + // 10 cmsSigChromaticityTag + + + if (!SetTextTags(hICC, L"RGB built-in")) goto Error; + + if (WhitePoint) { + + if (!cmsWriteTag(hICC, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error; + + cmsxyY2XYZ(&WhitePointXYZ, WhitePoint); + _cmsAdaptationMatrix(&CHAD, NULL, &WhitePointXYZ, cmsD50_XYZ()); + + // This is a V4 tag, but many CMM does read and understand it no matter which version + if (!cmsWriteTag(hICC, cmsSigChromaticAdaptationTag, (void*) &CHAD)) goto Error; + } + + if (WhitePoint && Primaries) { + + MaxWhite.x = WhitePoint -> x; + MaxWhite.y = WhitePoint -> y; + MaxWhite.Y = 1.0; + + if (!_cmsBuildRGB2XYZtransferMatrix(&MColorants, &MaxWhite, Primaries)) goto Error; + + Colorants.Red.X = MColorants.v[0].n[0]; + Colorants.Red.Y = MColorants.v[1].n[0]; + Colorants.Red.Z = MColorants.v[2].n[0]; + + Colorants.Green.X = MColorants.v[0].n[1]; + Colorants.Green.Y = MColorants.v[1].n[1]; + Colorants.Green.Z = MColorants.v[2].n[1]; + + Colorants.Blue.X = MColorants.v[0].n[2]; + Colorants.Blue.Y = MColorants.v[1].n[2]; + Colorants.Blue.Z = MColorants.v[2].n[2]; + + if (!cmsWriteTag(hICC, cmsSigRedColorantTag, (void*) &Colorants.Red)) goto Error; + if (!cmsWriteTag(hICC, cmsSigBlueColorantTag, (void*) &Colorants.Blue)) goto Error; + if (!cmsWriteTag(hICC, cmsSigGreenColorantTag, (void*) &Colorants.Green)) goto Error; + } + + + if (TransferFunction) { + + // Tries to minimize space. Thanks to Richard Hughes for this nice idea + if (!cmsWriteTag(hICC, cmsSigRedTRCTag, (void*) TransferFunction[0])) goto Error; + + if (TransferFunction[1] == TransferFunction[0]) { + + if (!cmsLinkTag (hICC, cmsSigGreenTRCTag, cmsSigRedTRCTag)) goto Error; + + } else { + + if (!cmsWriteTag(hICC, cmsSigGreenTRCTag, (void*) TransferFunction[1])) goto Error; + } + + if (TransferFunction[2] == TransferFunction[0]) { + + if (!cmsLinkTag (hICC, cmsSigBlueTRCTag, cmsSigRedTRCTag)) goto Error; + + } else { + + if (!cmsWriteTag(hICC, cmsSigBlueTRCTag, (void*) TransferFunction[2])) goto Error; + } + } + + if (Primaries) { + if (!cmsWriteTag(hICC, cmsSigChromaticityTag, (void*) Primaries)) goto Error; + } + + + return hICC; + +Error: + if (hICC) + cmsCloseProfile(hICC); + return NULL; +} + +cmsHPROFILE CMSEXPORT cmsCreateRGBProfile(const cmsCIExyY* WhitePoint, + const cmsCIExyYTRIPLE* Primaries, + cmsToneCurve* const TransferFunction[3]) +{ + return cmsCreateRGBProfileTHR(NULL, WhitePoint, Primaries, TransferFunction); +} + + + +// This function creates a profile based on White point and transfer function. +cmsHPROFILE CMSEXPORT cmsCreateGrayProfileTHR(cmsContext ContextID, + const cmsCIExyY* WhitePoint, + const cmsToneCurve* TransferFunction) +{ + cmsHPROFILE hICC; + cmsCIEXYZ tmp; + + hICC = cmsCreateProfilePlaceholder(ContextID); + if (!hICC) // can't allocate + return NULL; + + cmsSetProfileVersion(hICC, 4.4); + + cmsSetDeviceClass(hICC, cmsSigDisplayClass); + cmsSetColorSpace(hICC, cmsSigGrayData); + cmsSetPCS(hICC, cmsSigXYZData); + cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL); + + + // Implement profile using following tags: + // + // 1 cmsSigProfileDescriptionTag + // 2 cmsSigMediaWhitePointTag + // 3 cmsSigGrayTRCTag + + // This conforms a standard Gray DisplayProfile + + // Fill-in the tags + + if (!SetTextTags(hICC, L"gray built-in")) goto Error; + + + if (WhitePoint) { + + cmsxyY2XYZ(&tmp, WhitePoint); + if (!cmsWriteTag(hICC, cmsSigMediaWhitePointTag, (void*) &tmp)) goto Error; + } + + if (TransferFunction) { + + if (!cmsWriteTag(hICC, cmsSigGrayTRCTag, (void*) TransferFunction)) goto Error; + } + + return hICC; + +Error: + if (hICC) + cmsCloseProfile(hICC); + return NULL; +} + + + +cmsHPROFILE CMSEXPORT cmsCreateGrayProfile(const cmsCIExyY* WhitePoint, + const cmsToneCurve* TransferFunction) +{ + return cmsCreateGrayProfileTHR(NULL, WhitePoint, TransferFunction); +} + +// This is a devicelink operating in the target colorspace with as many transfer functions as components + +cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID, + cmsColorSpaceSignature ColorSpace, + cmsToneCurve* const TransferFunctions[]) +{ + cmsHPROFILE hICC; + cmsPipeline* Pipeline; + cmsInt32Number nChannels; + + hICC = cmsCreateProfilePlaceholder(ContextID); + if (!hICC) + return NULL; + + cmsSetProfileVersion(hICC, 4.4); + + cmsSetDeviceClass(hICC, cmsSigLinkClass); + cmsSetColorSpace(hICC, ColorSpace); + cmsSetPCS(hICC, ColorSpace); + + cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL); + + // Set up channels + nChannels = cmsChannelsOfColorSpace(ColorSpace); + + // Creates a Pipeline with prelinearization step only + Pipeline = cmsPipelineAlloc(ContextID, nChannels, nChannels); + if (Pipeline == NULL) goto Error; + + + // Copy tables to Pipeline + if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, cmsStageAllocToneCurves(ContextID, nChannels, TransferFunctions))) + goto Error; + + // Create tags + if (!SetTextTags(hICC, L"Linearization built-in")) goto Error; + if (!cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline)) goto Error; + if (!SetSeqDescTag(hICC, "Linearization built-in")) goto Error; + + // Pipeline is already on virtual profile + cmsPipelineFree(Pipeline); + + // Ok, done + return hICC; + +Error: + cmsPipelineFree(Pipeline); + if (hICC) + cmsCloseProfile(hICC); + + + return NULL; +} + +cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLink(cmsColorSpaceSignature ColorSpace, + cmsToneCurve* const TransferFunctions[]) +{ + return cmsCreateLinearizationDeviceLinkTHR(NULL, ColorSpace, TransferFunctions); +} + +// Ink-limiting algorithm +// +// Sum = C + M + Y + K +// If Sum > InkLimit +// Ratio= 1 - (Sum - InkLimit) / (C + M + Y) +// if Ratio <0 +// Ratio=0 +// endif +// Else +// Ratio=1 +// endif +// +// C = Ratio * C +// M = Ratio * M +// Y = Ratio * Y +// K: Does not change + +static +int InkLimitingSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo) +{ + cmsFloat64Number InkLimit = *(cmsFloat64Number *) Cargo; + cmsFloat64Number SumCMY, SumCMYK, Ratio; + + InkLimit = (InkLimit * 655.35); + + SumCMY = (cmsFloat64Number) In[0] + In[1] + In[2]; + SumCMYK = SumCMY + In[3]; + + if (SumCMYK > InkLimit) { + + Ratio = 1 - ((SumCMYK - InkLimit) / SumCMY); + if (Ratio < 0) + Ratio = 0; + } + else Ratio = 1; + + Out[0] = _cmsQuickSaturateWord(In[0] * Ratio); // C + Out[1] = _cmsQuickSaturateWord(In[1] * Ratio); // M + Out[2] = _cmsQuickSaturateWord(In[2] * Ratio); // Y + + Out[3] = In[3]; // K (untouched) + + return TRUE; +} + +// This is a devicelink operating in CMYK for ink-limiting + +cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID, + cmsColorSpaceSignature ColorSpace, + cmsFloat64Number Limit) +{ + cmsHPROFILE hICC; + cmsPipeline* LUT; + cmsStage* CLUT; + cmsInt32Number nChannels; + + if (ColorSpace != cmsSigCmykData) { + cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported"); + return NULL; + } + + if (Limit < 0.0 || Limit > 400) { + + cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 0..400"); + if (Limit < 0) Limit = 0; + if (Limit > 400) Limit = 400; + + } + + hICC = cmsCreateProfilePlaceholder(ContextID); + if (!hICC) // can't allocate + return NULL; + + cmsSetProfileVersion(hICC, 4.4); + + cmsSetDeviceClass(hICC, cmsSigLinkClass); + cmsSetColorSpace(hICC, ColorSpace); + cmsSetPCS(hICC, ColorSpace); + + cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL); + + + // Creates a Pipeline with 3D grid only + LUT = cmsPipelineAlloc(ContextID, 4, 4); + if (LUT == NULL) goto Error; + + + nChannels = cmsChannelsOf(ColorSpace); + + CLUT = cmsStageAllocCLut16bit(ContextID, 17, nChannels, nChannels, NULL); + if (CLUT == NULL) goto Error; + + if (!cmsStageSampleCLut16bit(CLUT, InkLimitingSampler, (void*) &Limit, 0)) goto Error; + + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, nChannels)) || + !cmsPipelineInsertStage(LUT, cmsAT_END, CLUT) || + !cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, nChannels))) + goto Error; + + // Create tags + if (!SetTextTags(hICC, L"ink-limiting built-in")) goto Error; + + if (!cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) LUT)) goto Error; + if (!SetSeqDescTag(hICC, "ink-limiting built-in")) goto Error; + + // cmsPipeline is already on virtual profile + cmsPipelineFree(LUT); + + // Ok, done + return hICC; + +Error: + if (LUT != NULL) + cmsPipelineFree(LUT); + + if (hICC != NULL) + cmsCloseProfile(hICC); + + return NULL; +} + +cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLink(cmsColorSpaceSignature ColorSpace, cmsFloat64Number Limit) +{ + return cmsCreateInkLimitingDeviceLinkTHR(NULL, ColorSpace, Limit); +} + + +// Creates a fake Lab identity. +cmsHPROFILE CMSEXPORT cmsCreateLab2ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint) +{ + cmsHPROFILE hProfile; + cmsPipeline* LUT = NULL; + + hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL); + if (hProfile == NULL) return NULL; + + cmsSetProfileVersion(hProfile, 2.1); + + cmsSetDeviceClass(hProfile, cmsSigAbstractClass); + cmsSetColorSpace(hProfile, cmsSigLabData); + cmsSetPCS(hProfile, cmsSigLabData); + + if (!SetTextTags(hProfile, L"Lab identity built-in")) return NULL; + + // An identity LUT is all we need + LUT = cmsPipelineAlloc(ContextID, 3, 3); + if (LUT == NULL) goto Error; + + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCLut(ContextID, 3))) + goto Error; + + if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error; + cmsPipelineFree(LUT); + + return hProfile; + +Error: + + if (LUT != NULL) + cmsPipelineFree(LUT); + + if (hProfile != NULL) + cmsCloseProfile(hProfile); + + return NULL; +} + + +cmsHPROFILE CMSEXPORT cmsCreateLab2Profile(const cmsCIExyY* WhitePoint) +{ + return cmsCreateLab2ProfileTHR(NULL, WhitePoint); +} + + +// Creates a fake Lab V4 identity. +cmsHPROFILE CMSEXPORT cmsCreateLab4ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint) +{ + cmsHPROFILE hProfile; + cmsPipeline* LUT = NULL; + + hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL); + if (hProfile == NULL) return NULL; + + cmsSetProfileVersion(hProfile, 4.4); + + cmsSetDeviceClass(hProfile, cmsSigAbstractClass); + cmsSetColorSpace(hProfile, cmsSigLabData); + cmsSetPCS(hProfile, cmsSigLabData); + + if (!SetTextTags(hProfile, L"Lab identity built-in")) goto Error; + + // An empty LUTs is all we need + LUT = cmsPipelineAlloc(ContextID, 3, 3); + if (LUT == NULL) goto Error; + + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3))) + goto Error; + + if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error; + cmsPipelineFree(LUT); + + return hProfile; + +Error: + + if (LUT != NULL) + cmsPipelineFree(LUT); + + if (hProfile != NULL) + cmsCloseProfile(hProfile); + + return NULL; +} + +cmsHPROFILE CMSEXPORT cmsCreateLab4Profile(const cmsCIExyY* WhitePoint) +{ + return cmsCreateLab4ProfileTHR(NULL, WhitePoint); +} + + +// Creates a fake XYZ identity +cmsHPROFILE CMSEXPORT cmsCreateXYZProfileTHR(cmsContext ContextID) +{ + cmsHPROFILE hProfile; + cmsPipeline* LUT = NULL; + + hProfile = cmsCreateRGBProfileTHR(ContextID, cmsD50_xyY(), NULL, NULL); + if (hProfile == NULL) return NULL; + + cmsSetProfileVersion(hProfile, 4.4); + + cmsSetDeviceClass(hProfile, cmsSigAbstractClass); + cmsSetColorSpace(hProfile, cmsSigXYZData); + cmsSetPCS(hProfile, cmsSigXYZData); + + if (!SetTextTags(hProfile, L"XYZ identity built-in")) goto Error; + + // An identity LUT is all we need + LUT = cmsPipelineAlloc(ContextID, 3, 3); + if (LUT == NULL) goto Error; + + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3))) + goto Error; + + if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error; + cmsPipelineFree(LUT); + + return hProfile; + +Error: + + if (LUT != NULL) + cmsPipelineFree(LUT); + + if (hProfile != NULL) + cmsCloseProfile(hProfile); + + return NULL; +} + + +cmsHPROFILE CMSEXPORT cmsCreateXYZProfile(void) +{ + return cmsCreateXYZProfileTHR(NULL); +} + + +//sRGB Curves are defined by: +// +//If R'sRGB,G'sRGB, B'sRGB < 0.04045 +// +// R = R'sRGB / 12.92 +// G = G'sRGB / 12.92 +// B = B'sRGB / 12.92 +// +// +//else if R'sRGB,G'sRGB, B'sRGB >= 0.04045 +// +// R = ((R'sRGB + 0.055) / 1.055)^2.4 +// G = ((G'sRGB + 0.055) / 1.055)^2.4 +// B = ((B'sRGB + 0.055) / 1.055)^2.4 + +static +cmsToneCurve* Build_sRGBGamma(cmsContext ContextID) +{ + cmsFloat64Number Parameters[5]; + + Parameters[0] = 2.4; + Parameters[1] = 1. / 1.055; + Parameters[2] = 0.055 / 1.055; + Parameters[3] = 1. / 12.92; + Parameters[4] = 0.04045; + + return cmsBuildParametricToneCurve(ContextID, 4, Parameters); +} + +// Create the ICC virtual profile for sRGB space +cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID) +{ + cmsCIExyY D65 = { 0.3127, 0.3290, 1.0 }; + cmsCIExyYTRIPLE Rec709Primaries = { + {0.6400, 0.3300, 1.0}, + {0.3000, 0.6000, 1.0}, + {0.1500, 0.0600, 1.0} + }; + cmsToneCurve* Gamma22[3]; + cmsHPROFILE hsRGB; + + // cmsWhitePointFromTemp(&D65, 6504); + Gamma22[0] = Gamma22[1] = Gamma22[2] = Build_sRGBGamma(ContextID); + if (Gamma22[0] == NULL) return NULL; + + hsRGB = cmsCreateRGBProfileTHR(ContextID, &D65, &Rec709Primaries, Gamma22); + cmsFreeToneCurve(Gamma22[0]); + if (hsRGB == NULL) return NULL; + + if (!SetTextTags(hsRGB, L"sRGB built-in")) { + cmsCloseProfile(hsRGB); + return NULL; + } + + return hsRGB; +} + +cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void) +{ + return cmsCreate_sRGBProfileTHR(NULL); +} + + + +typedef struct { + cmsFloat64Number Brightness; + cmsFloat64Number Contrast; + cmsFloat64Number Hue; + cmsFloat64Number Saturation; + cmsBool lAdjustWP; + cmsCIEXYZ WPsrc, WPdest; + +} BCHSWADJUSTS, *LPBCHSWADJUSTS; + + +static +int bchswSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo) +{ + cmsCIELab LabIn, LabOut; + cmsCIELCh LChIn, LChOut; + cmsCIEXYZ XYZ; + LPBCHSWADJUSTS bchsw = (LPBCHSWADJUSTS) Cargo; + + + cmsLabEncoded2Float(&LabIn, In); + + + cmsLab2LCh(&LChIn, &LabIn); + + // Do some adjusts on LCh + + LChOut.L = LChIn.L * bchsw ->Contrast + bchsw ->Brightness; + LChOut.C = LChIn.C + bchsw -> Saturation; + LChOut.h = LChIn.h + bchsw -> Hue; + + + cmsLCh2Lab(&LabOut, &LChOut); + + // Move white point in Lab + if (bchsw->lAdjustWP) { + cmsLab2XYZ(&bchsw->WPsrc, &XYZ, &LabOut); + cmsXYZ2Lab(&bchsw->WPdest, &LabOut, &XYZ); + } + + // Back to encoded + + cmsFloat2LabEncoded(Out, &LabOut); + + return TRUE; +} + + +// Creates an abstract profile operating in Lab space for Brightness, +// contrast, Saturation and white point displacement + +cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, + cmsUInt32Number nLUTPoints, + cmsFloat64Number Bright, + cmsFloat64Number Contrast, + cmsFloat64Number Hue, + cmsFloat64Number Saturation, + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest) +{ + cmsHPROFILE hICC; + cmsPipeline* Pipeline; + BCHSWADJUSTS bchsw; + cmsCIExyY WhitePnt; + cmsStage* CLUT; + cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; + cmsUInt32Number i; + + bchsw.Brightness = Bright; + bchsw.Contrast = Contrast; + bchsw.Hue = Hue; + bchsw.Saturation = Saturation; + if (TempSrc == TempDest) { + + bchsw.lAdjustWP = FALSE; + } + else { + bchsw.lAdjustWP = TRUE; + cmsWhitePointFromTemp(&WhitePnt, TempSrc); + cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt); + cmsWhitePointFromTemp(&WhitePnt, TempDest); + cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt); + + } + + hICC = cmsCreateProfilePlaceholder(ContextID); + if (!hICC) // can't allocate + return NULL; + + cmsSetDeviceClass(hICC, cmsSigAbstractClass); + cmsSetColorSpace(hICC, cmsSigLabData); + cmsSetPCS(hICC, cmsSigLabData); + + cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL); + + // Creates a Pipeline with 3D grid only + Pipeline = cmsPipelineAlloc(ContextID, 3, 3); + if (Pipeline == NULL) { + cmsCloseProfile(hICC); + return NULL; + } + + for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints; + CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL); + if (CLUT == NULL) goto Error; + + + if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) { + + // Shouldn't reach here + goto Error; + } + + if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT)) { + goto Error; + } + + // Create tags + if (!SetTextTags(hICC, L"BCHS built-in")) return NULL; + + cmsWriteTag(hICC, cmsSigMediaWhitePointTag, (void*) cmsD50_XYZ()); + + cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline); + + // Pipeline is already on virtual profile + cmsPipelineFree(Pipeline); + + // Ok, done + return hICC; + +Error: + cmsPipelineFree(Pipeline); + cmsCloseProfile(hICC); + return NULL; +} + + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints, + cmsFloat64Number Bright, + cmsFloat64Number Contrast, + cmsFloat64Number Hue, + cmsFloat64Number Saturation, + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest) +{ + return cmsCreateBCHSWabstractProfileTHR(NULL, nLUTPoints, Bright, Contrast, Hue, Saturation, TempSrc, TempDest); +} + + +// Creates a fake NULL profile. This profile return 1 channel as always 0. +// Is useful only for gamut checking tricks +cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID) +{ + cmsHPROFILE hProfile; + cmsPipeline* LUT = NULL; + cmsStage* PostLin; + cmsStage* OutLin; + cmsToneCurve* EmptyTab[3]; + cmsUInt16Number Zero[2] = { 0, 0 }; + const cmsFloat64Number PickLstarMatrix[] = { 1, 0, 0 }; + + hProfile = cmsCreateProfilePlaceholder(ContextID); + if (!hProfile) // can't allocate + return NULL; + + cmsSetProfileVersion(hProfile, 4.4); + + if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error; + + + cmsSetDeviceClass(hProfile, cmsSigOutputClass); + cmsSetColorSpace(hProfile, cmsSigGrayData); + cmsSetPCS(hProfile, cmsSigLabData); + + // Create a valid ICC 4 structure + LUT = cmsPipelineAlloc(ContextID, 3, 1); + if (LUT == NULL) goto Error; + + EmptyTab[0] = EmptyTab[1] = EmptyTab[2] = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero); + PostLin = cmsStageAllocToneCurves(ContextID, 3, EmptyTab); + OutLin = cmsStageAllocToneCurves(ContextID, 1, EmptyTab); + cmsFreeToneCurve(EmptyTab[0]); + + if (!cmsPipelineInsertStage(LUT, cmsAT_END, PostLin)) + goto Error; + + if (!cmsPipelineInsertStage(LUT, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL))) + goto Error; + + if (!cmsPipelineInsertStage(LUT, cmsAT_END, OutLin)) + goto Error; + + if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, (void*) LUT)) goto Error; + if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error; + + cmsPipelineFree(LUT); + return hProfile; + +Error: + + if (LUT != NULL) + cmsPipelineFree(LUT); + + if (hProfile != NULL) + cmsCloseProfile(hProfile); + + return NULL; +} + +cmsHPROFILE CMSEXPORT cmsCreateNULLProfile(void) +{ + return cmsCreateNULLProfileTHR(NULL); +} + + +static +int IsPCS(cmsColorSpaceSignature ColorSpace) +{ + return (ColorSpace == cmsSigXYZData || + ColorSpace == cmsSigLabData); +} + + +static +void FixColorSpaces(cmsHPROFILE hProfile, + cmsColorSpaceSignature ColorSpace, + cmsColorSpaceSignature PCS, + cmsUInt32Number dwFlags) +{ + if (dwFlags & cmsFLAGS_GUESSDEVICECLASS) { + + if (IsPCS(ColorSpace) && IsPCS(PCS)) { + + cmsSetDeviceClass(hProfile, cmsSigAbstractClass); + cmsSetColorSpace(hProfile, ColorSpace); + cmsSetPCS(hProfile, PCS); + return; + } + + if (IsPCS(ColorSpace) && !IsPCS(PCS)) { + + cmsSetDeviceClass(hProfile, cmsSigOutputClass); + cmsSetPCS(hProfile, ColorSpace); + cmsSetColorSpace(hProfile, PCS); + return; + } + + if (IsPCS(PCS) && !IsPCS(ColorSpace)) { + + cmsSetDeviceClass(hProfile, cmsSigInputClass); + cmsSetColorSpace(hProfile, ColorSpace); + cmsSetPCS(hProfile, PCS); + return; + } + } + + cmsSetDeviceClass(hProfile, cmsSigLinkClass); + cmsSetColorSpace(hProfile, ColorSpace); + cmsSetPCS(hProfile, PCS); +} + + + +// This function creates a named color profile dumping all the contents of transform to a single profile +// In this way, LittleCMS may be used to "group" several named color databases into a single profile. +// It has, however, several minor limitations. PCS is always Lab, which is not very critic since this +// is the normal PCS for named color profiles. +static +cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform) +{ + _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform; + cmsHPROFILE hICC = NULL; + cmsUInt32Number i, nColors; + cmsNAMEDCOLORLIST *nc2 = NULL, *Original = NULL; + + // Create an empty placeholder + hICC = cmsCreateProfilePlaceholder(v->ContextID); + if (hICC == NULL) return NULL; + + // Critical information + cmsSetDeviceClass(hICC, cmsSigNamedColorClass); + cmsSetColorSpace(hICC, v ->ExitColorSpace); + cmsSetPCS(hICC, cmsSigLabData); + + // Tag profile with information + if (!SetTextTags(hICC, L"Named color devicelink")) goto Error; + + Original = cmsGetNamedColorList(xform); + if (Original == NULL) goto Error; + + nColors = cmsNamedColorCount(Original); + nc2 = cmsDupNamedColorList(Original); + if (nc2 == NULL) goto Error; + + // Colorant count now depends on the output space + nc2 ->ColorantCount = cmsPipelineOutputChannels(v ->Lut); + + // Make sure we have proper formatters + cmsChangeBuffersFormat(xform, TYPE_NAMED_COLOR_INDEX, + FLOAT_SH(0) | COLORSPACE_SH(_cmsLCMScolorSpace(v ->ExitColorSpace)) + | BYTES_SH(2) | CHANNELS_SH(cmsChannelsOfColorSpace(v ->ExitColorSpace))); + + // Apply the transfor to colorants. + for (i=0; i < nColors; i++) { + cmsDoTransform(xform, &i, nc2 ->List[i].DeviceColorant, 1); + } + + if (!cmsWriteTag(hICC, cmsSigNamedColor2Tag, (void*) nc2)) goto Error; + cmsFreeNamedColorList(nc2); + + return hICC; + +Error: + if (hICC != NULL) cmsCloseProfile(hICC); + return NULL; +} + + +// This structure holds information about which MPU can be stored on a profile based on the version + +typedef struct { + cmsBool IsV4; // Is a V4 tag? + cmsTagSignature RequiredTag; // Set to 0 for both types + cmsTagTypeSignature LutType; // The LUT type + int nTypes; // Number of types (up to 5) + cmsStageSignature MpeTypes[5]; // 5 is the maximum number + +} cmsAllowedLUT; + +#define cmsSig0 ((cmsTagSignature) 0) + +static const cmsAllowedLUT AllowedLUTTypes[] = { + + { FALSE, cmsSig0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } }, + { FALSE, cmsSig0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } }, + { FALSE, cmsSig0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType } }, + { TRUE, cmsSig0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType } }, + { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType } }, + { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } }, + { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 5, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }}, + { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 1, { cmsSigCurveSetElemType }}, + { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }}, + { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType }}, + { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 5, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType }} +}; + +#define SIZE_OF_ALLOWED_LUT (sizeof(AllowedLUTTypes)/sizeof(cmsAllowedLUT)) + +// Check a single entry +static +cmsBool CheckOne(const cmsAllowedLUT* Tab, const cmsPipeline* Lut) +{ + cmsStage* mpe; + int n; + + for (n=0, mpe = Lut ->Elements; mpe != NULL; mpe = mpe ->Next, n++) { + + if (n > Tab ->nTypes) return FALSE; + if (cmsStageType(mpe) != Tab ->MpeTypes[n]) return FALSE; + } + + return (n == Tab ->nTypes); +} + + +static +const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4, cmsTagSignature DestinationTag) +{ + cmsUInt32Number n; + + for (n=0; n < SIZE_OF_ALLOWED_LUT; n++) { + + const cmsAllowedLUT* Tab = AllowedLUTTypes + n; + + if (IsV4 ^ Tab -> IsV4) continue; + if ((Tab ->RequiredTag != 0) && (Tab ->RequiredTag != DestinationTag)) continue; + + if (CheckOne(Tab, Lut)) return Tab; + } + + return NULL; +} + + +// Does convert a transform into a device link profile +cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags) +{ + cmsHPROFILE hProfile = NULL; + cmsUInt32Number FrmIn, FrmOut; + cmsInt32Number ChansIn, ChansOut; + int ColorSpaceBitsIn, ColorSpaceBitsOut; + _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; + cmsPipeline* LUT = NULL; + cmsStage* mpe; + cmsContext ContextID = cmsGetTransformContextID(hTransform); + const cmsAllowedLUT* AllowedLUT; + cmsTagSignature DestinationTag; + cmsProfileClassSignature deviceClass; + + _cmsAssert(hTransform != NULL); + + // Get the first mpe to check for named color + mpe = cmsPipelineGetPtrToFirstStage(xform ->Lut); + + // Check if is a named color transform + if (mpe != NULL) { + + if (cmsStageType(mpe) == cmsSigNamedColorElemType) { + return CreateNamedColorDevicelink(hTransform); + } + } + + // First thing to do is to get a copy of the transformation + LUT = cmsPipelineDup(xform ->Lut); + if (LUT == NULL) return NULL; + + // Time to fix the Lab2/Lab4 issue. + if ((xform ->EntryColorSpace == cmsSigLabData) && (Version < 4.0)) { + + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID))) + goto Error; + } + + // On the output side too. Note that due to V2/V4 PCS encoding on lab we cannot fix white misalignments + if ((xform ->ExitColorSpace) == cmsSigLabData && (Version < 4.0)) { + + dwFlags |= cmsFLAGS_NOWHITEONWHITEFIXUP; + if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error; + } + + + hProfile = cmsCreateProfilePlaceholder(ContextID); + if (!hProfile) goto Error; // can't allocate + + cmsSetProfileVersion(hProfile, Version); + + FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags); + + // Optimize the LUT and precalculate a devicelink + + ChansIn = cmsChannelsOfColorSpace(xform -> EntryColorSpace); + ChansOut = cmsChannelsOfColorSpace(xform -> ExitColorSpace); + + ColorSpaceBitsIn = _cmsLCMScolorSpace(xform -> EntryColorSpace); + ColorSpaceBitsOut = _cmsLCMScolorSpace(xform -> ExitColorSpace); + + FrmIn = COLORSPACE_SH(ColorSpaceBitsIn) | CHANNELS_SH(ChansIn)|BYTES_SH(2); + FrmOut = COLORSPACE_SH(ColorSpaceBitsOut) | CHANNELS_SH(ChansOut)|BYTES_SH(2); + + deviceClass = cmsGetDeviceClass(hProfile); + + if (deviceClass == cmsSigOutputClass) + DestinationTag = cmsSigBToA0Tag; + else + DestinationTag = cmsSigAToB0Tag; + + // Check if the profile/version can store the result + if (dwFlags & cmsFLAGS_FORCE_CLUT) + AllowedLUT = NULL; + else + AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag); + + if (AllowedLUT == NULL) { + + // Try to optimize + _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags); + AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag); + + } + + // If no way, then force CLUT that for sure can be written + if (AllowedLUT == NULL) { + + cmsStage* FirstStage; + cmsStage* LastStage; + + dwFlags |= cmsFLAGS_FORCE_CLUT; + _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags); + + // Put identity curves if needed + FirstStage = cmsPipelineGetPtrToFirstStage(LUT); + if (FirstStage != NULL && FirstStage ->Type != cmsSigCurveSetElemType) + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn))) + goto Error; + + LastStage = cmsPipelineGetPtrToLastStage(LUT); + if (LastStage != NULL && LastStage ->Type != cmsSigCurveSetElemType) + if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut))) + goto Error; + + AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag); + } + + // Somethings is wrong... + if (AllowedLUT == NULL) { + goto Error; + } + + + if (dwFlags & cmsFLAGS_8BITS_DEVICELINK) + cmsPipelineSetSaveAs8bitsFlag(LUT, TRUE); + + // Tag profile with information + if (!SetTextTags(hProfile, L"devicelink")) goto Error; + + // Store result + if (!cmsWriteTag(hProfile, DestinationTag, LUT)) goto Error; + + + if (xform -> InputColorant != NULL) { + if (!cmsWriteTag(hProfile, cmsSigColorantTableTag, xform->InputColorant)) goto Error; + } + + if (xform -> OutputColorant != NULL) { + if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error; + } + + if ((deviceClass == cmsSigLinkClass) && (xform ->Sequence != NULL)) { + if (!_cmsWriteProfileSequence(hProfile, xform ->Sequence)) goto Error; + } + + // Set the white point + if (deviceClass == cmsSigInputClass) { + if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->EntryWhitePoint)) goto Error; + } + else { + if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->ExitWhitePoint)) goto Error; + } + + + // Per 7.2.15 in spec 4.3 + cmsSetHeaderRenderingIntent(hProfile, xform ->RenderingIntent); + + cmsPipelineFree(LUT); + return hProfile; + +Error: + if (LUT != NULL) cmsPipelineFree(LUT); + cmsCloseProfile(hProfile); + return NULL; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmswtpnt.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmswtpnt.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmswtpnt.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmswtpnt.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,382 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// D50 - Widely used +const cmsCIEXYZ* CMSEXPORT cmsD50_XYZ(void) +{ + static cmsCIEXYZ D50XYZ = {cmsD50X, cmsD50Y, cmsD50Z}; + + return &D50XYZ; +} + +const cmsCIExyY* CMSEXPORT cmsD50_xyY(void) +{ + static cmsCIExyY D50xyY; + + cmsXYZ2xyY(&D50xyY, cmsD50_XYZ()); + + return &D50xyY; +} + +// Obtains WhitePoint from Temperature +cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number TempK) +{ + cmsFloat64Number x, y; + cmsFloat64Number T, T2, T3; + // cmsFloat64Number M1, M2; + + _cmsAssert(WhitePoint != NULL); + + T = TempK; + T2 = T*T; // Square + T3 = T2*T; // Cube + + // For correlated color temperature (T) between 4000K and 7000K: + + if (T >= 4000. && T <= 7000.) + { + x = -4.6070*(1E9/T3) + 2.9678*(1E6/T2) + 0.09911*(1E3/T) + 0.244063; + } + else + // or for correlated color temperature (T) between 7000K and 25000K: + + if (T > 7000.0 && T <= 25000.0) + { + x = -2.0064*(1E9/T3) + 1.9018*(1E6/T2) + 0.24748*(1E3/T) + 0.237040; + } + else { + cmsSignalError(0, cmsERROR_RANGE, "cmsWhitePointFromTemp: invalid temp"); + return FALSE; + } + + // Obtain y(x) + y = -3.000*(x*x) + 2.870*x - 0.275; + + // wave factors (not used, but here for futures extensions) + + // M1 = (-1.3515 - 1.7703*x + 5.9114 *y)/(0.0241 + 0.2562*x - 0.7341*y); + // M2 = (0.0300 - 31.4424*x + 30.0717*y)/(0.0241 + 0.2562*x - 0.7341*y); + + WhitePoint -> x = x; + WhitePoint -> y = y; + WhitePoint -> Y = 1.0; + + return TRUE; +} + + + +typedef struct { + + cmsFloat64Number mirek; // temp (in microreciprocal kelvin) + cmsFloat64Number ut; // u coord of intersection w/ blackbody locus + cmsFloat64Number vt; // v coord of intersection w/ blackbody locus + cmsFloat64Number tt; // slope of ISOTEMPERATURE. line + + } ISOTEMPERATURE; + +static const ISOTEMPERATURE isotempdata[] = { +// {Mirek, Ut, Vt, Tt } + {0, 0.18006, 0.26352, -0.24341}, + {10, 0.18066, 0.26589, -0.25479}, + {20, 0.18133, 0.26846, -0.26876}, + {30, 0.18208, 0.27119, -0.28539}, + {40, 0.18293, 0.27407, -0.30470}, + {50, 0.18388, 0.27709, -0.32675}, + {60, 0.18494, 0.28021, -0.35156}, + {70, 0.18611, 0.28342, -0.37915}, + {80, 0.18740, 0.28668, -0.40955}, + {90, 0.18880, 0.28997, -0.44278}, + {100, 0.19032, 0.29326, -0.47888}, + {125, 0.19462, 0.30141, -0.58204}, + {150, 0.19962, 0.30921, -0.70471}, + {175, 0.20525, 0.31647, -0.84901}, + {200, 0.21142, 0.32312, -1.0182 }, + {225, 0.21807, 0.32909, -1.2168 }, + {250, 0.22511, 0.33439, -1.4512 }, + {275, 0.23247, 0.33904, -1.7298 }, + {300, 0.24010, 0.34308, -2.0637 }, + {325, 0.24702, 0.34655, -2.4681 }, + {350, 0.25591, 0.34951, -2.9641 }, + {375, 0.26400, 0.35200, -3.5814 }, + {400, 0.27218, 0.35407, -4.3633 }, + {425, 0.28039, 0.35577, -5.3762 }, + {450, 0.28863, 0.35714, -6.7262 }, + {475, 0.29685, 0.35823, -8.5955 }, + {500, 0.30505, 0.35907, -11.324 }, + {525, 0.31320, 0.35968, -15.628 }, + {550, 0.32129, 0.36011, -23.325 }, + {575, 0.32931, 0.36038, -40.770 }, + {600, 0.33724, 0.36051, -116.45 } +}; + +#define NISO sizeof(isotempdata)/sizeof(ISOTEMPERATURE) + + +// Robertson's method +cmsBool CMSEXPORT cmsTempFromWhitePoint(cmsFloat64Number* TempK, const cmsCIExyY* WhitePoint) +{ + cmsUInt32Number j; + cmsFloat64Number us,vs; + cmsFloat64Number uj,vj,tj,di,dj,mi,mj; + cmsFloat64Number xs, ys; + + _cmsAssert(WhitePoint != NULL); + _cmsAssert(TempK != NULL); + + di = mi = 0; + xs = WhitePoint -> x; + ys = WhitePoint -> y; + + // convert (x,y) to CIE 1960 (u,WhitePoint) + + us = (2*xs) / (-xs + 6*ys + 1.5); + vs = (3*ys) / (-xs + 6*ys + 1.5); + + + for (j=0; j < NISO; j++) { + + uj = isotempdata[j].ut; + vj = isotempdata[j].vt; + tj = isotempdata[j].tt; + mj = isotempdata[j].mirek; + + dj = ((vs - vj) - tj * (us - uj)) / sqrt(1.0 + tj * tj); + + if ((j != 0) && (di/dj < 0.0)) { + + // Found a match + *TempK = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi)); + return TRUE; + } + + di = dj; + mi = mj; + } + + // Not found + return FALSE; +} + + +// Compute chromatic adaptation matrix using Chad as cone matrix + +static +cmsBool ComputeChromaticAdaptation(cmsMAT3* Conversion, + const cmsCIEXYZ* SourceWhitePoint, + const cmsCIEXYZ* DestWhitePoint, + const cmsMAT3* Chad) + +{ + + cmsMAT3 Chad_Inv; + cmsVEC3 ConeSourceXYZ, ConeSourceRGB; + cmsVEC3 ConeDestXYZ, ConeDestRGB; + cmsMAT3 Cone, Tmp; + + + Tmp = *Chad; + if (!_cmsMAT3inverse(&Tmp, &Chad_Inv)) return FALSE; + + _cmsVEC3init(&ConeSourceXYZ, SourceWhitePoint -> X, + SourceWhitePoint -> Y, + SourceWhitePoint -> Z); + + _cmsVEC3init(&ConeDestXYZ, DestWhitePoint -> X, + DestWhitePoint -> Y, + DestWhitePoint -> Z); + + _cmsMAT3eval(&ConeSourceRGB, Chad, &ConeSourceXYZ); + _cmsMAT3eval(&ConeDestRGB, Chad, &ConeDestXYZ); + + if ((fabs(ConeSourceRGB.n[0]) < MATRIX_DET_TOLERANCE) || + (fabs(ConeSourceRGB.n[1]) < MATRIX_DET_TOLERANCE) || + (fabs(ConeSourceRGB.n[2]) < MATRIX_DET_TOLERANCE)) return FALSE; + + // Build matrix + _cmsVEC3init(&Cone.v[0], ConeDestRGB.n[0]/ConeSourceRGB.n[0], 0.0, 0.0); + _cmsVEC3init(&Cone.v[1], 0.0, ConeDestRGB.n[1]/ConeSourceRGB.n[1], 0.0); + _cmsVEC3init(&Cone.v[2], 0.0, 0.0, ConeDestRGB.n[2]/ConeSourceRGB.n[2]); + + // Normalize + _cmsMAT3per(&Tmp, &Cone, Chad); + _cmsMAT3per(Conversion, &Chad_Inv, &Tmp); + + return TRUE; +} + +// Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll +// The cone matrix can be specified in ConeMatrix. If NULL, Bradford is assumed +cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll) +{ + cmsMAT3 LamRigg = {{ // Bradford matrix + {{ 0.8951, 0.2664, -0.1614 }}, + {{ -0.7502, 1.7135, 0.0367 }}, + {{ 0.0389, -0.0685, 1.0296 }} + }}; + + if (ConeMatrix == NULL) + ConeMatrix = &LamRigg; + + return ComputeChromaticAdaptation(r, FromIll, ToIll, ConeMatrix); +} + +// Same as anterior, but assuming D50 destination. White point is given in xyY +static +cmsBool _cmsAdaptMatrixToD50(cmsMAT3* r, const cmsCIExyY* SourceWhitePt) +{ + cmsCIEXYZ Dn; + cmsMAT3 Bradford; + cmsMAT3 Tmp; + + cmsxyY2XYZ(&Dn, SourceWhitePt); + + if (!_cmsAdaptationMatrix(&Bradford, NULL, &Dn, cmsD50_XYZ())) return FALSE; + + Tmp = *r; + _cmsMAT3per(r, &Bradford, &Tmp); + + return TRUE; +} + +// Build a White point, primary chromas transfer matrix from RGB to CIE XYZ +// This is just an approximation, I am not handling all the non-linear +// aspects of the RGB to XYZ process, and assuming that the gamma correction +// has transitive property in the transformation chain. +// +// the algorithm: +// +// - First I build the absolute conversion matrix using +// primaries in XYZ. This matrix is next inverted +// - Then I eval the source white point across this matrix +// obtaining the coefficients of the transformation +// - Then, I apply these coefficients to the original matrix +// +cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePt, const cmsCIExyYTRIPLE* Primrs) +{ + cmsVEC3 WhitePoint, Coef; + cmsMAT3 Result, Primaries; + cmsFloat64Number xn, yn; + cmsFloat64Number xr, yr; + cmsFloat64Number xg, yg; + cmsFloat64Number xb, yb; + + xn = WhitePt -> x; + yn = WhitePt -> y; + xr = Primrs -> Red.x; + yr = Primrs -> Red.y; + xg = Primrs -> Green.x; + yg = Primrs -> Green.y; + xb = Primrs -> Blue.x; + yb = Primrs -> Blue.y; + + // Build Primaries matrix + _cmsVEC3init(&Primaries.v[0], xr, xg, xb); + _cmsVEC3init(&Primaries.v[1], yr, yg, yb); + _cmsVEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg), (1-xb-yb)); + + + // Result = Primaries ^ (-1) inverse matrix + if (!_cmsMAT3inverse(&Primaries, &Result)) + return FALSE; + + + _cmsVEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn); + + // Across inverse primaries ... + _cmsMAT3eval(&Coef, &Result, &WhitePoint); + + // Give us the Coefs, then I build transformation matrix + _cmsVEC3init(&r -> v[0], Coef.n[VX]*xr, Coef.n[VY]*xg, Coef.n[VZ]*xb); + _cmsVEC3init(&r -> v[1], Coef.n[VX]*yr, Coef.n[VY]*yg, Coef.n[VZ]*yb); + _cmsVEC3init(&r -> v[2], Coef.n[VX]*(1.0-xr-yr), Coef.n[VY]*(1.0-xg-yg), Coef.n[VZ]*(1.0-xb-yb)); + + + return _cmsAdaptMatrixToD50(r, WhitePt); + +} + + +// Adapts a color to a given illuminant. Original color is expected to have +// a SourceWhitePt white point. +cmsBool CMSEXPORT cmsAdaptToIlluminant(cmsCIEXYZ* Result, + const cmsCIEXYZ* SourceWhitePt, + const cmsCIEXYZ* Illuminant, + const cmsCIEXYZ* Value) +{ + cmsMAT3 Bradford; + cmsVEC3 In, Out; + + _cmsAssert(Result != NULL); + _cmsAssert(SourceWhitePt != NULL); + _cmsAssert(Illuminant != NULL); + _cmsAssert(Value != NULL); + + if (!_cmsAdaptationMatrix(&Bradford, NULL, SourceWhitePt, Illuminant)) return FALSE; + + _cmsVEC3init(&In, Value -> X, Value -> Y, Value -> Z); + _cmsMAT3eval(&Out, &Bradford, &In); + + Result -> X = Out.n[0]; + Result -> Y = Out.n[1]; + Result -> Z = Out.n[2]; + + return TRUE; +} + + diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsxform.c openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsxform.c --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/cmsxform.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/cmsxform.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1474 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + +// Transformations stuff +// ----------------------------------------------------------------------- + +#define DEFAULT_OBSERVER_ADAPTATION_STATE 1.0 + +// The Context0 observer adaptation state. +_cmsAdaptationStateChunkType _cmsAdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE }; + +// Init and duplicate observer adaptation state +void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsAdaptationStateChunkType AdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE }; + void* from; + + if (src != NULL) { + from = src ->chunks[AdaptationStateContext]; + } + else { + from = &AdaptationStateChunk; + } + + ctx ->chunks[AdaptationStateContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAdaptationStateChunkType)); +} + + +// Sets adaptation state for absolute colorimetric intent in the given context. Adaptation state applies on all +// but cmsCreateExtendedTransformTHR(). Little CMS can handle incomplete adaptation states. +cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d) +{ + cmsFloat64Number prev; + _cmsAdaptationStateChunkType* ptr = (_cmsAdaptationStateChunkType*) _cmsContextGetClientChunk(ContextID, AdaptationStateContext); + + // Get previous value for return + prev = ptr ->AdaptationState; + + // Set the value if d is positive or zero + if (d >= 0.0) { + + ptr ->AdaptationState = d; + } + + // Always return previous value + return prev; +} + + +// The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine +cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d) +{ + return cmsSetAdaptationStateTHR(NULL, d); +} + +// ----------------------------------------------------------------------- + +// Alarm codes for 16-bit transformations, because the fixed range of containers there are +// no values left to mark out of gamut. + +#define DEFAULT_ALARM_CODES_VALUE {0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +_cmsAlarmCodesChunkType _cmsAlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE }; + +// Sets the codes used to mark out-out-gamut on Proofing transforms for a given context. Values are meant to be +// encoded in 16 bits. +void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID, const cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS]) +{ + _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext); + + _cmsAssert(ContextAlarmCodes != NULL); // Can't happen + + memcpy(ContextAlarmCodes->AlarmCodes, AlarmCodesP, sizeof(ContextAlarmCodes->AlarmCodes)); +} + +// Gets the current codes used to mark out-out-gamut on Proofing transforms for the given context. +// Values are meant to be encoded in 16 bits. +void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID, cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS]) +{ + _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext); + + _cmsAssert(ContextAlarmCodes != NULL); // Can't happen + + memcpy(AlarmCodesP, ContextAlarmCodes->AlarmCodes, sizeof(ContextAlarmCodes->AlarmCodes)); +} + +void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]) +{ + _cmsAssert(NewAlarm != NULL); + + cmsSetAlarmCodesTHR(NULL, NewAlarm); +} + +void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number OldAlarm[cmsMAXCHANNELS]) +{ + _cmsAssert(OldAlarm != NULL); + cmsGetAlarmCodesTHR(NULL, OldAlarm); +} + + +// Init and duplicate alarm codes +void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsAlarmCodesChunkType AlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE }; + void* from; + + if (src != NULL) { + from = src ->chunks[AlarmCodesContext]; + } + else { + from = &AlarmCodesChunk; + } + + ctx ->chunks[AlarmCodesContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAlarmCodesChunkType)); +} + +// ----------------------------------------------------------------------- + +// Get rid of transform resources +void CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform) +{ + _cmsTRANSFORM* p = (_cmsTRANSFORM*) hTransform; + + _cmsAssert(p != NULL); + + if (p -> GamutCheck) + cmsPipelineFree(p -> GamutCheck); + + if (p -> Lut) + cmsPipelineFree(p -> Lut); + + if (p ->InputColorant) + cmsFreeNamedColorList(p ->InputColorant); + + if (p -> OutputColorant) + cmsFreeNamedColorList(p ->OutputColorant); + + if (p ->Sequence) + cmsFreeProfileSequenceDescription(p ->Sequence); + + if (p ->UserData) + p ->FreeUserData(p ->ContextID, p ->UserData); + + _cmsFree(p ->ContextID, (void *) p); +} + + +static +cmsUInt32Number PixelSize(cmsUInt32Number Format) +{ + cmsUInt32Number fmt_bytes = T_BYTES(Format); + + // For double, the T_BYTES field is zero + if (fmt_bytes == 0) + return sizeof(cmsUInt64Number); + + // Otherwise, it is already correct for all formats + return fmt_bytes; +} + + + + +// Apply transform. +void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number Size) + +{ + _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform; + cmsStride stride; + + stride.BytesPerLineIn = 0; // Not used + stride.BytesPerLineOut = 0; + stride.BytesPerPlaneIn = Size * PixelSize(p->InputFormat); + stride.BytesPerPlaneOut = Size * PixelSize(p->OutputFormat); + + p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride); +} + + +// This is a legacy stride for planar +void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number Size, cmsUInt32Number Stride) + +{ + _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform; + cmsStride stride; + + stride.BytesPerLineIn = 0; + stride.BytesPerLineOut = 0; + stride.BytesPerPlaneIn = Stride; + stride.BytesPerPlaneOut = Stride; + + p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride); +} + +// This is the "fast" function for plugins +void CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM Transform, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + cmsUInt32Number BytesPerLineIn, + cmsUInt32Number BytesPerLineOut, + cmsUInt32Number BytesPerPlaneIn, + cmsUInt32Number BytesPerPlaneOut) + +{ + _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform; + cmsStride stride; + + stride.BytesPerLineIn = BytesPerLineIn; + stride.BytesPerLineOut = BytesPerLineOut; + stride.BytesPerPlaneIn = BytesPerPlaneIn; + stride.BytesPerPlaneOut = BytesPerPlaneOut; + + p->xform(p, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, &stride); +} + + + +// Transform routines ---------------------------------------------------------------------------------------------------------- + +// Float xform converts floats. Since there are no performance issues, one routine does all job, including gamut check. +// Note that because extended range, we can use a -1.0 value for out of gamut in this case. +static +void FloatXFORM(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsUInt8Number* accum; + cmsUInt8Number* output; + cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS]; + cmsFloat32Number OutOfGamut; + cmsUInt32Number i, j, c, strideIn, strideOut; + + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); + + strideIn = 0; + strideOut = 0; + memset(fIn, 0, sizeof(fIn)); + memset(fOut, 0, sizeof(fOut)); + + for (i = 0; i < LineCount; i++) { + + accum = (cmsUInt8Number*)in + strideIn; + output = (cmsUInt8Number*)out + strideOut; + + for (j = 0; j < PixelsPerLine; j++) { + + accum = p->FromInputFloat(p, fIn, accum, Stride->BytesPerPlaneIn); + + // Any gamut check to do? + if (p->GamutCheck != NULL) { + + // Evaluate gamut marker. + cmsPipelineEvalFloat(fIn, &OutOfGamut, p->GamutCheck); + + // Is current color out of gamut? + if (OutOfGamut > 0.0) { + + // Certainly, out of gamut + for (c = 0; c < cmsMAXCHANNELS; c++) + fOut[c] = -1.0; + + } + else { + // No, proceed normally + cmsPipelineEvalFloat(fIn, fOut, p->Lut); + } + } + else { + + // No gamut check at all + cmsPipelineEvalFloat(fIn, fOut, p->Lut); + } + + + output = p->ToOutputFloat(p, fOut, output, Stride->BytesPerPlaneOut); + } + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } + +} + + +static +void NullFloatXFORM(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) + +{ + cmsUInt8Number* accum; + cmsUInt8Number* output; + cmsFloat32Number fIn[cmsMAXCHANNELS]; + cmsUInt32Number i, j, strideIn, strideOut; + + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); + + strideIn = 0; + strideOut = 0; + memset(fIn, 0, sizeof(fIn)); + + for (i = 0; i < LineCount; i++) { + + accum = (cmsUInt8Number*) in + strideIn; + output = (cmsUInt8Number*) out + strideOut; + + for (j = 0; j < PixelsPerLine; j++) { + + accum = p->FromInputFloat(p, fIn, accum, Stride ->BytesPerPlaneIn); + output = p->ToOutputFloat(p, fIn, output, Stride->BytesPerPlaneOut); + } + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } +} + +// 16 bit precision ----------------------------------------------------------------------------------------------------------- + +// Null transformation, only applies formatters. No cache +static +void NullXFORM(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsUInt8Number* accum; + cmsUInt8Number* output; + cmsUInt16Number wIn[cmsMAXCHANNELS]; + cmsUInt32Number i, j, strideIn, strideOut; + + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); + + strideIn = 0; + strideOut = 0; + memset(wIn, 0, sizeof(wIn)); + + for (i = 0; i < LineCount; i++) { + + accum = (cmsUInt8Number*)in + strideIn; + output = (cmsUInt8Number*)out + strideOut; + + for (j = 0; j < PixelsPerLine; j++) { + + accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); + output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut); + } + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } + +} + + +// No gamut check, no cache, 16 bits +static +void PrecalculatedXFORM(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + CMSREGISTER cmsUInt8Number* accum; + CMSREGISTER cmsUInt8Number* output; + cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; + cmsUInt32Number i, j, strideIn, strideOut; + + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); + + strideIn = 0; + strideOut = 0; + memset(wIn, 0, sizeof(wIn)); + memset(wOut, 0, sizeof(wOut)); + + for (i = 0; i < LineCount; i++) { + + accum = (cmsUInt8Number*)in + strideIn; + output = (cmsUInt8Number*)out + strideOut; + + for (j = 0; j < PixelsPerLine; j++) { + + accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); + p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data); + output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); + } + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } + +} + + +// Auxiliary: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical. +static +void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p, + const cmsUInt16Number wIn[], + cmsUInt16Number wOut[]) +{ + cmsUInt16Number wOutOfGamut; + + p ->GamutCheck ->Eval16Fn(wIn, &wOutOfGamut, p ->GamutCheck ->Data); + if (wOutOfGamut >= 1) { + + cmsUInt32Number i; + _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(p->ContextID, AlarmCodesContext); + + for (i=0; i < p ->Lut->OutputChannels; i++) { + + wOut[i] = ContextAlarmCodes ->AlarmCodes[i]; + } + } + else + p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data); +} + +// Gamut check, No cache, 16 bits. +static +void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsUInt8Number* accum; + cmsUInt8Number* output; + cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; + cmsUInt32Number i, j, strideIn, strideOut; + + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); + + strideIn = 0; + strideOut = 0; + memset(wIn, 0, sizeof(wIn)); + memset(wOut, 0, sizeof(wOut)); + + for (i = 0; i < LineCount; i++) { + + accum = (cmsUInt8Number*)in + strideIn; + output = (cmsUInt8Number*)out + strideOut; + + for (j = 0; j < PixelsPerLine; j++) { + + accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); + TransformOnePixelWithGamutCheck(p, wIn, wOut); + output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); + } + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } +} + + +// No gamut check, Cache, 16 bits, +static +void CachedXFORM(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsUInt8Number* accum; + cmsUInt8Number* output; + cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; + _cmsCACHE Cache; + cmsUInt32Number i, j, strideIn, strideOut; + + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); + + // Empty buffers for quick memcmp + memset(wIn, 0, sizeof(wIn)); + memset(wOut, 0, sizeof(wOut)); + + // Get copy of zero cache + memcpy(&Cache, &p->Cache, sizeof(Cache)); + + strideIn = 0; + strideOut = 0; + + for (i = 0; i < LineCount; i++) { + + accum = (cmsUInt8Number*)in + strideIn; + output = (cmsUInt8Number*)out + strideOut; + + for (j = 0; j < PixelsPerLine; j++) { + + accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); + + if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) { + + memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut)); + } + else { + p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data); + + memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn)); + memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut)); + } + + output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); + } + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } +} + +// All those nice features together +static +void CachedXFORMGamutCheck(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsUInt8Number* accum; + cmsUInt8Number* output; + cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; + _cmsCACHE Cache; + cmsUInt32Number i, j, strideIn, strideOut; + + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); + + // Empty buffers for quick memcmp + memset(wIn, 0, sizeof(wIn)); + memset(wOut, 0, sizeof(wOut)); + + // Get copy of zero cache + memcpy(&Cache, &p->Cache, sizeof(Cache)); + + strideIn = 0; + strideOut = 0; + + for (i = 0; i < LineCount; i++) { + + accum = (cmsUInt8Number*)in + strideIn; + output = (cmsUInt8Number*)out + strideOut; + + for (j = 0; j < PixelsPerLine; j++) { + + accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); + + if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) { + + memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut)); + } + else { + TransformOnePixelWithGamutCheck(p, wIn, wOut); + + memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn)); + memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut)); + } + + output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); + } + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } +} + +// Transform plug-ins ---------------------------------------------------------------------------------------------------- + +// List of used-defined transform factories +typedef struct _cmsTransformCollection_st { + + _cmsTransform2Factory Factory; + cmsBool OldXform; // Factory returns xform function in the old style + + struct _cmsTransformCollection_st *Next; + +} _cmsTransformCollection; + +// The linked list head +_cmsTransformPluginChunkType _cmsTransformPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginTransformList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsTransformPluginChunkType newHead = { NULL }; + _cmsTransformCollection* entry; + _cmsTransformCollection* Anterior = NULL; + _cmsTransformPluginChunkType* head = (_cmsTransformPluginChunkType*) src->chunks[TransformPlugin]; + + // Walk the list copying all nodes + for (entry = head->TransformCollection; + entry != NULL; + entry = entry ->Next) { + + _cmsTransformCollection *newEntry = ( _cmsTransformCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTransformCollection)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.TransformCollection == NULL) + newHead.TransformCollection = newEntry; + } + + ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType)); +} + +// Allocates memory for transform plugin factory +void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Copy all linked list + DupPluginTransformList(ctx, src); + } + else { + static _cmsTransformPluginChunkType TransformPluginChunkType = { NULL }; + ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TransformPluginChunkType, sizeof(_cmsTransformPluginChunkType)); + } +} + +// Adaptor for old versions of plug-in +static +void _cmsTransform2toTransformAdaptor(struct _cmstransform_struct *CMMcargo, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + + cmsUInt32Number i, strideIn, strideOut; + + _cmsHandleExtraChannels(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride); + + strideIn = 0; + strideOut = 0; + + for (i = 0; i < LineCount; i++) { + + void *accum = (cmsUInt8Number*)InputBuffer + strideIn; + void *output = (cmsUInt8Number*)OutputBuffer + strideOut; + + CMMcargo->OldXform(CMMcargo, accum, output, PixelsPerLine, Stride->BytesPerPlaneIn); + + strideIn += Stride->BytesPerLineIn; + strideOut += Stride->BytesPerLineOut; + } +} + + + +// Register new ways to transform +cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + cmsPluginTransform* Plugin = (cmsPluginTransform*) Data; + _cmsTransformCollection* fl; + _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID,TransformPlugin); + + if (Data == NULL) { + + // Free the chain. Memory is safely freed at exit + ctx->TransformCollection = NULL; + return TRUE; + } + + // Factory callback is required + if (Plugin->factories.xform == NULL) return FALSE; + + + fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection)); + if (fl == NULL) return FALSE; + + // Check for full xform plug-ins previous to 2.8, we would need an adapter in that case + if (Plugin->base.ExpectedVersion < 2080) { + + fl->OldXform = TRUE; + } + else + fl->OldXform = FALSE; + + // Copy the parameters + fl->Factory = Plugin->factories.xform; + + // Keep linked list + fl ->Next = ctx->TransformCollection; + ctx->TransformCollection = fl; + + // All is ok + return TRUE; +} + + +void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn) +{ + _cmsAssert(CMMcargo != NULL); + CMMcargo ->UserData = ptr; + CMMcargo ->FreeUserData = FreePrivateDataFn; +} + +// returns the pointer defined by the plug-in to store private data +void * CMSEXPORT _cmsGetTransformUserData(struct _cmstransform_struct *CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo ->UserData; +} + +// returns the current formatters +void CMSEXPORT _cmsGetTransformFormatters16(struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput) +{ + _cmsAssert(CMMcargo != NULL); + if (FromInput) *FromInput = CMMcargo ->FromInput; + if (ToOutput) *ToOutput = CMMcargo ->ToOutput; +} + +void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput) +{ + _cmsAssert(CMMcargo != NULL); + if (FromInput) *FromInput = CMMcargo ->FromInputFloat; + if (ToOutput) *ToOutput = CMMcargo ->ToOutputFloat; +} + +// returns original flags +cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->dwOriginalFlags; +} + +// Returns the worker callback for parallelization plug-ins +_cmsTransform2Fn CMSEXPORT _cmsGetTransformWorker(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->Worker; +} + +// This field holds maximum number of workers or -1 to auto +cmsInt32Number CMSEXPORT _cmsGetTransformMaxWorkers(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->MaxWorkers; +} + +// This field is actually unused and reserved +cmsUInt32Number CMSEXPORT _cmsGetTransformWorkerFlags(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->WorkerFlags; +} + +// In the case there is a parallelization plug-in, let it to do its job +static +void ParalellizeIfSuitable(_cmsTRANSFORM* p) +{ + _cmsParallelizationPluginChunkType* ctx = (_cmsParallelizationPluginChunkType*)_cmsContextGetClientChunk(p->ContextID, ParallelizationPlugin); + + _cmsAssert(p != NULL); + if (ctx != NULL && ctx->SchedulerFn != NULL) { + + p->Worker = p->xform; + p->xform = ctx->SchedulerFn; + p->MaxWorkers = ctx->MaxWorkers; + p->WorkerFlags = ctx->WorkerFlags; + } +} + + +/** +* An empty unroll to avoid a check with NULL on cmsDoTransform() +*/ +static +cmsUInt8Number* UnrollNothing(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wIn[], + CMSREGISTER cmsUInt8Number* accum, + CMSREGISTER cmsUInt32Number Stride) +{ + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(wIn); + cmsUNUSED_PARAMETER(Stride); +} + +static +cmsUInt8Number* PackNothing(CMSREGISTER _cmsTRANSFORM* info, + CMSREGISTER cmsUInt16Number wOut[], + CMSREGISTER cmsUInt8Number* output, + CMSREGISTER cmsUInt32Number Stride) +{ + return output; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(wOut); + cmsUNUSED_PARAMETER(Stride); +} + +// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper +// for separated transforms. If this is the case, +static +_cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, + cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) +{ + _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin); + _cmsTransformCollection* Plugin; + + // Allocate needed memory + _cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM)); + if (!p) { + cmsPipelineFree(lut); + return NULL; + } + + // Store the proposed pipeline + p->Lut = lut; + + // Let's see if any plug-in want to do the transform by itself + if (p->Lut != NULL) { + + if (!(*dwFlags & cmsFLAGS_NOOPTIMIZE)) + { + for (Plugin = ctx->TransformCollection; + Plugin != NULL; + Plugin = Plugin->Next) { + + if (Plugin->Factory(&p->xform, &p->UserData, &p->FreeUserData, &p->Lut, InputFormat, OutputFormat, dwFlags)) { + + // Last plugin in the declaration order takes control. We just keep + // the original parameters as a logging. + // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default + // an optimized transform is not reusable. The plug-in can, however, change + // the flags and make it suitable. + + p->ContextID = ContextID; + p->InputFormat = *InputFormat; + p->OutputFormat = *OutputFormat; + p->dwOriginalFlags = *dwFlags; + + // Fill the formatters just in case the optimized routine is interested. + // No error is thrown if the formatter doesn't exist. It is up to the optimization + // factory to decide what to do in those cases. + p->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; + p->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; + p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + + // Save the day? (Ignore the warning) + if (Plugin->OldXform) { + p->OldXform = (_cmsTransformFn)(void*)p->xform; + p->xform = _cmsTransform2toTransformAdaptor; + } + + ParalellizeIfSuitable(p); + return p; + } + } + } + + // Not suitable for the transform plug-in, let's check the pipeline plug-in + _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags); + } + + // Check whatever this is a true floating point transform + if (_cmsFormatterIsFloat(*OutputFormat)) { + + // Get formatter function always return a valid union, but the contents of this union may be NULL. + p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; + + if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) { + + cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); + cmsDeleteTransform(p); + return NULL; + } + + if (*dwFlags & cmsFLAGS_NULLTRANSFORM) { + + p ->xform = NullFloatXFORM; + } + else { + // Float transforms don't use cache, always are non-NULL + p ->xform = FloatXFORM; + } + + } + else { + + // Formats are intended to be changed before use + if (*InputFormat == 0 && *OutputFormat == 0) { + p->FromInput = UnrollNothing; + p->ToOutput = PackNothing; + *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; + } + else { + + cmsUInt32Number BytesPerPixelInput; + + p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; + p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; + + if (p ->FromInput == NULL || p ->ToOutput == NULL) { + + cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); + cmsDeleteTransform(p); + return NULL; + } + + BytesPerPixelInput = T_BYTES(*InputFormat); + if (BytesPerPixelInput == 0 || BytesPerPixelInput >= 2) + *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; + + } + + if (*dwFlags & cmsFLAGS_NULLTRANSFORM) { + + p ->xform = NullXFORM; + } + else { + if (*dwFlags & cmsFLAGS_NOCACHE) { + + if (*dwFlags & cmsFLAGS_GAMUTCHECK) + p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no cache + else + p ->xform = PrecalculatedXFORM; // No cache, no gamut check + } + else { + + if (*dwFlags & cmsFLAGS_GAMUTCHECK) + p ->xform = CachedXFORMGamutCheck; // Gamut check, cache + else + p ->xform = CachedXFORM; // No gamut check, cache + + } + } + } + + p ->InputFormat = *InputFormat; + p ->OutputFormat = *OutputFormat; + p ->dwOriginalFlags = *dwFlags; + p ->ContextID = ContextID; + p ->UserData = NULL; + ParalellizeIfSuitable(p); + return p; +} + +static +cmsBool GetXFormColorSpaces(cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output) +{ + cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut; + cmsColorSpaceSignature PostColorSpace; + cmsUInt32Number i; + + if (nProfiles == 0) return FALSE; + if (hProfiles[0] == NULL) return FALSE; + + *Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]); + + for (i=0; i < nProfiles; i++) { + + cmsProfileClassSignature cls; + cmsHPROFILE hProfile = hProfiles[i]; + + int lIsInput = (PostColorSpace != cmsSigXYZData) && + (PostColorSpace != cmsSigLabData); + + if (hProfile == NULL) return FALSE; + + cls = cmsGetDeviceClass(hProfile); + + if (cls == cmsSigNamedColorClass) { + + ColorSpaceIn = cmsSig1colorData; + ColorSpaceOut = (nProfiles > 1) ? cmsGetPCS(hProfile) : cmsGetColorSpace(hProfile); + } + else + if (lIsInput || (cls == cmsSigLinkClass)) { + + ColorSpaceIn = cmsGetColorSpace(hProfile); + ColorSpaceOut = cmsGetPCS(hProfile); + } + else + { + ColorSpaceIn = cmsGetPCS(hProfile); + ColorSpaceOut = cmsGetColorSpace(hProfile); + } + + if (i==0) + *Input = ColorSpaceIn; + + PostColorSpace = ColorSpaceOut; + } + + *Output = PostColorSpace; + + return TRUE; +} + +// Check colorspace +static +cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat) +{ + int Space1 = (int) T_COLORSPACE(dwFormat); + int Space2 = _cmsLCMScolorSpace(Check); + + if (Space1 == PT_ANY) return TRUE; + if (Space1 == Space2) return TRUE; + + if (Space1 == PT_LabV2 && Space2 == PT_Lab) return TRUE; + if (Space1 == PT_Lab && Space2 == PT_LabV2) return TRUE; + + return FALSE; +} + +// ---------------------------------------------------------------------------------------------------------------- + +// Jun-21-2000: Some profiles (those that comes with W2K) comes +// with the media white (media black?) x 100. Add a sanity check + +static +void NormalizeXYZ(cmsCIEXYZ* Dest) +{ + while (Dest -> X > 2. && + Dest -> Y > 2. && + Dest -> Z > 2.) { + + Dest -> X /= 10.; + Dest -> Y /= 10.; + Dest -> Z /= 10.; + } +} + +static +void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src) +{ + if (src == NULL) { + wtPt ->X = cmsD50X; + wtPt ->Y = cmsD50Y; + wtPt ->Z = cmsD50Z; + } + else { + wtPt ->X = src->X; + wtPt ->Y = src->Y; + wtPt ->Z = src->Z; + + NormalizeXYZ(wtPt); + } + +} + +// New to lcms 2.0 -- have all parameters available. +cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID, + cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsUInt32Number Intents[], + cmsFloat64Number AdaptationStates[], + cmsHPROFILE hGamutProfile, + cmsUInt32Number nGamutPCSposition, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + cmsUInt32Number dwFlags) +{ + _cmsTRANSFORM* xform; + cmsColorSpaceSignature EntryColorSpace; + cmsColorSpaceSignature ExitColorSpace; + cmsPipeline* Lut; + cmsUInt32Number LastIntent = Intents[nProfiles-1]; + + // If it is a fake transform + if (dwFlags & cmsFLAGS_NULLTRANSFORM) + { + return AllocEmptyTransform(ContextID, NULL, INTENT_PERCEPTUAL, &InputFormat, &OutputFormat, &dwFlags); + } + + // If gamut check is requested, make sure we have a gamut profile + if (dwFlags & cmsFLAGS_GAMUTCHECK) { + if (hGamutProfile == NULL) dwFlags &= ~cmsFLAGS_GAMUTCHECK; + } + + // On floating point transforms, inhibit cache + if (_cmsFormatterIsFloat(InputFormat) || _cmsFormatterIsFloat(OutputFormat)) + dwFlags |= cmsFLAGS_NOCACHE; + + // Mark entry/exit spaces + if (!GetXFormColorSpaces(nProfiles, hProfiles, &EntryColorSpace, &ExitColorSpace)) { + cmsSignalError(ContextID, cmsERROR_NULL, "NULL input profiles on transform"); + return NULL; + } + + // Check if proper colorspaces + if (!IsProperColorSpace(EntryColorSpace, InputFormat)) { + cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Wrong input color space on transform"); + return NULL; + } + + if (!IsProperColorSpace(ExitColorSpace, OutputFormat)) { + cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Wrong output color space on transform"); + return NULL; + } + + // Check whatever the transform is 16 bits and involves linear RGB in first profile. If so, disable optimizations + if (EntryColorSpace == cmsSigRgbData && T_BYTES(InputFormat) == 2 && !(dwFlags & cmsFLAGS_NOOPTIMIZE)) + { + cmsFloat64Number gamma = cmsDetectRGBProfileGamma(hProfiles[0], 0.1); + + if (gamma > 0 && gamma < 1.6) + dwFlags |= cmsFLAGS_NOOPTIMIZE; + } + + // Create a pipeline with all transformations + Lut = _cmsLinkProfiles(ContextID, nProfiles, Intents, hProfiles, BPC, AdaptationStates, dwFlags); + if (Lut == NULL) { + cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Couldn't link the profiles"); + return NULL; + } + + // Check channel count + if ((cmsChannelsOfColorSpace(EntryColorSpace) != (cmsInt32Number) cmsPipelineInputChannels(Lut)) || + (cmsChannelsOfColorSpace(ExitColorSpace) != (cmsInt32Number) cmsPipelineOutputChannels(Lut))) { + cmsPipelineFree(Lut); + cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted"); + return NULL; + } + + + // All seems ok + xform = AllocEmptyTransform(ContextID, Lut, LastIntent, &InputFormat, &OutputFormat, &dwFlags); + if (xform == NULL) { + return NULL; + } + + // Keep values + xform ->EntryColorSpace = EntryColorSpace; + xform ->ExitColorSpace = ExitColorSpace; + xform ->RenderingIntent = Intents[nProfiles-1]; + + // Take white points + SetWhitePoint(&xform->EntryWhitePoint, (cmsCIEXYZ*) cmsReadTag(hProfiles[0], cmsSigMediaWhitePointTag)); + SetWhitePoint(&xform->ExitWhitePoint, (cmsCIEXYZ*) cmsReadTag(hProfiles[nProfiles-1], cmsSigMediaWhitePointTag)); + + + // Create a gamut check LUT if requested + if (hGamutProfile != NULL && (dwFlags & cmsFLAGS_GAMUTCHECK)) + xform ->GamutCheck = _cmsCreateGamutCheckPipeline(ContextID, hProfiles, + BPC, Intents, + AdaptationStates, + nGamutPCSposition, + hGamutProfile); + + + // Try to read input and output colorant table + if (cmsIsTag(hProfiles[0], cmsSigColorantTableTag)) { + + // Input table can only come in this way. + xform ->InputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[0], cmsSigColorantTableTag)); + } + + // Output is a little bit more complex. + if (cmsGetDeviceClass(hProfiles[nProfiles-1]) == cmsSigLinkClass) { + + // This tag may exist only on devicelink profiles. + if (cmsIsTag(hProfiles[nProfiles-1], cmsSigColorantTableOutTag)) { + + // It may be NULL if error + xform ->OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableOutTag)); + } + + } else { + + if (cmsIsTag(hProfiles[nProfiles-1], cmsSigColorantTableTag)) { + + xform -> OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableTag)); + } + } + + // Store the sequence of profiles + if (dwFlags & cmsFLAGS_KEEP_SEQUENCE) { + xform ->Sequence = _cmsCompileProfileSequence(ContextID, nProfiles, hProfiles); + } + else + xform ->Sequence = NULL; + + // If this is a cached transform, init first value, which is zero (16 bits only) + if (!(dwFlags & cmsFLAGS_NOCACHE)) { + + memset(&xform ->Cache.CacheIn, 0, sizeof(xform ->Cache.CacheIn)); + + if (xform ->GamutCheck != NULL) { + TransformOnePixelWithGamutCheck(xform, xform ->Cache.CacheIn, xform->Cache.CacheOut); + } + else { + + xform ->Lut ->Eval16Fn(xform ->Cache.CacheIn, xform->Cache.CacheOut, xform -> Lut->Data); + } + + } + + return (cmsHTRANSFORM) xform; +} + +// Multiprofile transforms: Gamut check is not available here, as it is unclear from which profile the gamut comes. +cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransformTHR(cmsContext ContextID, + cmsHPROFILE hProfiles[], + cmsUInt32Number nProfiles, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags) +{ + cmsUInt32Number i; + cmsBool BPC[256]; + cmsUInt32Number Intents[256]; + cmsFloat64Number AdaptationStates[256]; + + if (nProfiles <= 0 || nProfiles > 255) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles); + return NULL; + } + + for (i=0; i < nProfiles; i++) { + BPC[i] = dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION ? TRUE : FALSE; + Intents[i] = Intent; + AdaptationStates[i] = cmsSetAdaptationStateTHR(ContextID, -1); + } + + + return cmsCreateExtendedTransform(ContextID, nProfiles, hProfiles, BPC, Intents, AdaptationStates, NULL, 0, InputFormat, OutputFormat, dwFlags); +} + + + +cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], + cmsUInt32Number nProfiles, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags) +{ + + if (nProfiles <= 0 || nProfiles > 255) { + cmsSignalError(NULL, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles); + return NULL; + } + + return cmsCreateMultiprofileTransformTHR(cmsGetProfileContextID(hProfiles[0]), + hProfiles, + nProfiles, + InputFormat, + OutputFormat, + Intent, + dwFlags); +} + +cmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID, + cmsHPROFILE Input, + cmsUInt32Number InputFormat, + cmsHPROFILE Output, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags) +{ + + cmsHPROFILE hArray[2]; + + hArray[0] = Input; + hArray[1] = Output; + + return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1U : 2U, InputFormat, OutputFormat, Intent, dwFlags); +} + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransform(cmsHPROFILE Input, + cmsUInt32Number InputFormat, + cmsHPROFILE Output, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags) +{ + return cmsCreateTransformTHR(cmsGetProfileContextID(Input), Input, InputFormat, Output, OutputFormat, Intent, dwFlags); +} + + +cmsHTRANSFORM CMSEXPORT cmsCreateProofingTransformTHR(cmsContext ContextID, + cmsHPROFILE InputProfile, + cmsUInt32Number InputFormat, + cmsHPROFILE OutputProfile, + cmsUInt32Number OutputFormat, + cmsHPROFILE ProofingProfile, + cmsUInt32Number nIntent, + cmsUInt32Number ProofingIntent, + cmsUInt32Number dwFlags) +{ + cmsHPROFILE hArray[4]; + cmsUInt32Number Intents[4]; + cmsBool BPC[4]; + cmsFloat64Number Adaptation[4]; + cmsBool DoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION) ? TRUE : FALSE; + + + hArray[0] = InputProfile; hArray[1] = ProofingProfile; hArray[2] = ProofingProfile; hArray[3] = OutputProfile; + Intents[0] = nIntent; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = ProofingIntent; + BPC[0] = DoBPC; BPC[1] = DoBPC; BPC[2] = 0; BPC[3] = 0; + + Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = cmsSetAdaptationStateTHR(ContextID, -1); + + if (!(dwFlags & (cmsFLAGS_SOFTPROOFING|cmsFLAGS_GAMUTCHECK))) + return cmsCreateTransformTHR(ContextID, InputProfile, InputFormat, OutputProfile, OutputFormat, nIntent, dwFlags); + + return cmsCreateExtendedTransform(ContextID, 4, hArray, BPC, Intents, Adaptation, + ProofingProfile, 1, InputFormat, OutputFormat, dwFlags); + +} + + +cmsHTRANSFORM CMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, + cmsUInt32Number InputFormat, + cmsHPROFILE OutputProfile, + cmsUInt32Number OutputFormat, + cmsHPROFILE ProofingProfile, + cmsUInt32Number nIntent, + cmsUInt32Number ProofingIntent, + cmsUInt32Number dwFlags) +{ + return cmsCreateProofingTransformTHR(cmsGetProfileContextID(InputProfile), + InputProfile, + InputFormat, + OutputProfile, + OutputFormat, + ProofingProfile, + nIntent, + ProofingIntent, + dwFlags); +} + + +// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed +cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform) +{ + _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; + + if (xform == NULL) return NULL; + return xform -> ContextID; +} + +// Grab the input/output formats +cmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform) +{ + _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; + + if (xform == NULL) return 0; + return xform->InputFormat; +} + +cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform) +{ + _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; + + if (xform == NULL) return 0; + return xform->OutputFormat; +} + +// For backwards compatibility +cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat) +{ + _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; + cmsFormatter16 FromInput, ToOutput; + + + // We only can afford to change formatters if previous transform is at least 16 bits + if (!(xform ->dwOriginalFlags & cmsFLAGS_CAN_CHANGE_FORMATTER)) { + + cmsSignalError(xform ->ContextID, cmsERROR_NOT_SUITABLE, "cmsChangeBuffersFormat works only on transforms created originally with at least 16 bits of precision"); + return FALSE; + } + + FromInput = _cmsGetFormatter(xform->ContextID, InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; + ToOutput = _cmsGetFormatter(xform->ContextID, OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; + + if (FromInput == NULL || ToOutput == NULL) { + + cmsSignalError(xform -> ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); + return FALSE; + } + + xform ->InputFormat = InputFormat; + xform ->OutputFormat = OutputFormat; + xform ->FromInput = FromInput; + xform ->ToOutput = ToOutput; + return TRUE; +} diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/lcms2.h openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/lcms2.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/lcms2.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/lcms2.h 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1987 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// +// Version 2.15 +// + +#ifndef _lcms2_H + +// ********** Configuration toggles **************************************** + +// Uncomment this one if you are using big endian machines +// #define CMS_USE_BIG_ENDIAN 1 + +// Uncomment this one if your compiler/machine does NOT support the +// "long long" type. +// #define CMS_DONT_USE_INT64 1 + +// Uncomment this if your compiler doesn't work with fast floor function +// #define CMS_DONT_USE_FAST_FLOOR 1 + +// Uncomment this line if you want lcms to use the black point tag in profile, +// if commented, lcms will compute the black point by its own. +// It is safer to leave it commented out +// #define CMS_USE_PROFILE_BLACK_POINT_TAG 1 + +// Uncomment this line if you are compiling as C++ and want a C++ API +// #define CMS_USE_CPP_API + +// Uncomment this line if you need strict CGATS syntax. Makes CGATS files to +// require "KEYWORD" on undefined identifiers, keep it commented out unless needed +// #define CMS_STRICT_CGATS 1 + +// Uncomment to get rid of the tables for "half" float support +// #define CMS_NO_HALF_SUPPORT 1 + +// Uncomment to get rid of pthreads/windows dependency +// #define CMS_NO_PTHREADS 1 + +// Uncomment this for special windows mutex initialization (see lcms2_internal.h) +// #define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT + +// Uncomment this to remove the "register" storage class +// #define CMS_NO_REGISTER_KEYWORD 1 + +// ********** End of configuration toggles ****************************** + +// Needed for streams +#include + +// Needed for portability (C99 per 7.1.2) +#include +#include +#include + +#ifndef CMS_USE_CPP_API +# ifdef __cplusplus +extern "C" { +# endif +#endif + +// Version/release +#define LCMS_VERSION 2150 + +// I will give the chance of redefining basic types for compilers that are not fully C99 compliant +#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED + +// Base types +typedef unsigned char cmsUInt8Number; // That is guaranteed by the C99 spec +typedef signed char cmsInt8Number; // That is guaranteed by the C99 spec + +#if CHAR_BIT != 8 +# error "Unable to find 8 bit type, unsupported compiler" +#endif + +// IEEE float storage numbers +typedef float cmsFloat32Number; +typedef double cmsFloat64Number; + +// 16-bit base types +#if (USHRT_MAX == 65535U) + typedef unsigned short cmsUInt16Number; +#elif (UINT_MAX == 65535U) + typedef unsigned int cmsUInt16Number; +#else +# error "Unable to find 16 bits unsigned type, unsupported compiler" +#endif + +#if (SHRT_MAX == 32767) + typedef short cmsInt16Number; +#elif (INT_MAX == 32767) + typedef int cmsInt16Number; +#else +# error "Unable to find 16 bits signed type, unsupported compiler" +#endif + +// 32-bit base type +#if (UINT_MAX == 4294967295U) + typedef unsigned int cmsUInt32Number; +#elif (ULONG_MAX == 4294967295U) + typedef unsigned long cmsUInt32Number; +#else +# error "Unable to find 32 bit unsigned type, unsupported compiler" +#endif + +#if (INT_MAX == +2147483647) + typedef int cmsInt32Number; +#elif (LONG_MAX == +2147483647) + typedef long cmsInt32Number; +#else +# error "Unable to find 32 bit signed type, unsupported compiler" +#endif + +// 64-bit base types +#ifndef CMS_DONT_USE_INT64 +# if (ULONG_MAX == 18446744073709551615U) + typedef unsigned long cmsUInt64Number; +# elif (ULLONG_MAX == 18446744073709551615U) + typedef unsigned long long cmsUInt64Number; +# else +# define CMS_DONT_USE_INT64 1 +# endif +# if (LONG_MAX == +9223372036854775807) + typedef long cmsInt64Number; +# elif (LLONG_MAX == +9223372036854775807) + typedef long long cmsInt64Number; +# else +# define CMS_DONT_USE_INT64 1 +# endif +#endif +#endif + +// Handle "register" keyword +#if defined(CMS_NO_REGISTER_KEYWORD) +# define CMSREGISTER +#else +# define CMSREGISTER register +#endif + +// In the case 64 bit numbers are not supported by the compiler +#ifdef CMS_DONT_USE_INT64 + typedef cmsUInt32Number cmsUInt64Number[2]; + typedef cmsInt32Number cmsInt64Number[2]; +#endif + +// Derivative types +typedef cmsUInt32Number cmsSignature; +typedef cmsUInt16Number cmsU8Fixed8Number; +typedef cmsInt32Number cmsS15Fixed16Number; +typedef cmsUInt32Number cmsU16Fixed16Number; + +// Boolean type, which will be using the native integer +typedef int cmsBool; + +// Try to detect windows +#if defined (_WIN32) || defined(_WIN64) || defined(WIN32) || defined(_WIN32_) +# define CMS_IS_WINDOWS_ 1 +#endif + +#ifdef _MSC_VER +# define CMS_IS_WINDOWS_ 1 +#endif + +#ifdef __BORLANDC__ +# define CMS_IS_WINDOWS_ 1 +#endif + +// Try to detect big endian platforms. This list can be endless, so primarily rely on the configure script +// on Unix-like systems, and allow it to be set on the compiler command line using +// -DCMS_USE_BIG_ENDIAN or something similar +#ifdef CMS_USE_BIG_ENDIAN // set at compiler command line takes overall precedence + +# if CMS_USE_BIG_ENDIAN == 0 +# undef CMS_USE_BIG_ENDIAN +# endif + +#else // CMS_USE_BIG_ENDIAN + +# ifdef WORDS_BIGENDIAN // set by configure (or explicitly on compiler command line) +# define CMS_USE_BIG_ENDIAN 1 +# else // WORDS_BIGENDIAN +// Fall back to platform/compiler specific tests +# if defined(__sgi__) || defined(__sgi) || defined(sparc) +# define CMS_USE_BIG_ENDIAN 1 +# endif + +# if defined(__s390__) || defined(__s390x__) +# define CMS_USE_BIG_ENDIAN 1 +# endif + +# ifdef macintosh +# ifdef __BIG_ENDIAN__ +# define CMS_USE_BIG_ENDIAN 1 +# endif +# ifdef __LITTLE_ENDIAN__ +# undef CMS_USE_BIG_ENDIAN +# endif +# endif +# endif // WORDS_BIGENDIAN + +# if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) +# define CMS_USE_BIG_ENDIAN 1 +# endif + +#endif // CMS_USE_BIG_ENDIAN + + +// Calling convention -- this is hardly platform and compiler dependent +#if defined(CMS_IS_WINDOWS_) && !defined(__GNUC__) +# if defined(CMS_DLL) || defined(CMS_DLL_BUILD) +# ifdef __BORLANDC__ +# define CMSEXPORT __stdcall _export +# define CMSAPI +# else +# define CMSEXPORT __stdcall +# ifdef CMS_DLL_BUILD +# define CMSAPI __declspec(dllexport) +# else +# define CMSAPI __declspec(dllimport) +# endif +# endif +# else +# define CMSEXPORT +# define CMSAPI +# endif +#else // not Windows +# ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY +# define CMSEXPORT +# define CMSAPI __attribute__((visibility("default"))) +# else +# define CMSEXPORT +# define CMSAPI +# endif +#endif // CMS_IS_WINDOWS_ + +#ifdef HasTHREADS +# if HasTHREADS == 1 +# undef CMS_NO_PTHREADS +# else +# define CMS_NO_PTHREADS 1 +# endif +#endif + +// Some common definitions +#define cmsMAX_PATH 256 + +#ifndef FALSE +# define FALSE 0 +#endif +#ifndef TRUE +# define TRUE 1 +#endif + +// D50 XYZ normalized to Y=1.0 +#define cmsD50X 0.9642 +#define cmsD50Y 1.0 +#define cmsD50Z 0.8249 + +// V4 perceptual black +#define cmsPERCEPTUAL_BLACK_X 0.00336 +#define cmsPERCEPTUAL_BLACK_Y 0.0034731 +#define cmsPERCEPTUAL_BLACK_Z 0.00287 + +// Definitions in ICC spec +#define cmsMagicNumber 0x61637370 // 'acsp' +#define lcmsSignature 0x6c636d73 // 'lcms' + + +// Base ICC type definitions +typedef enum { + cmsSigChromaticityType = 0x6368726D, // 'chrm' + cmsSigcicpType = 0x63696370, // 'cicp' + cmsSigColorantOrderType = 0x636C726F, // 'clro' + cmsSigColorantTableType = 0x636C7274, // 'clrt' + cmsSigCrdInfoType = 0x63726469, // 'crdi' + cmsSigCurveType = 0x63757276, // 'curv' + cmsSigDataType = 0x64617461, // 'data' + cmsSigDictType = 0x64696374, // 'dict' + cmsSigDateTimeType = 0x6474696D, // 'dtim' + cmsSigDeviceSettingsType = 0x64657673, // 'devs' + cmsSigLut16Type = 0x6d667432, // 'mft2' + cmsSigLut8Type = 0x6d667431, // 'mft1' + cmsSigLutAtoBType = 0x6d414220, // 'mAB ' + cmsSigLutBtoAType = 0x6d424120, // 'mBA ' + cmsSigMeasurementType = 0x6D656173, // 'meas' + cmsSigMultiLocalizedUnicodeType = 0x6D6C7563, // 'mluc' + cmsSigMultiProcessElementType = 0x6D706574, // 'mpet' + cmsSigNamedColorType = 0x6E636f6C, // 'ncol' -- DEPRECATED! + cmsSigNamedColor2Type = 0x6E636C32, // 'ncl2' + cmsSigParametricCurveType = 0x70617261, // 'para' + cmsSigProfileSequenceDescType = 0x70736571, // 'pseq' + cmsSigProfileSequenceIdType = 0x70736964, // 'psid' + cmsSigResponseCurveSet16Type = 0x72637332, // 'rcs2' + cmsSigS15Fixed16ArrayType = 0x73663332, // 'sf32' + cmsSigScreeningType = 0x7363726E, // 'scrn' + cmsSigSignatureType = 0x73696720, // 'sig ' + cmsSigTextType = 0x74657874, // 'text' + cmsSigTextDescriptionType = 0x64657363, // 'desc' + cmsSigU16Fixed16ArrayType = 0x75663332, // 'uf32' + cmsSigUcrBgType = 0x62666420, // 'bfd ' + cmsSigUInt16ArrayType = 0x75693136, // 'ui16' + cmsSigUInt32ArrayType = 0x75693332, // 'ui32' + cmsSigUInt64ArrayType = 0x75693634, // 'ui64' + cmsSigUInt8ArrayType = 0x75693038, // 'ui08' + cmsSigVcgtType = 0x76636774, // 'vcgt' + cmsSigViewingConditionsType = 0x76696577, // 'view' + cmsSigXYZType = 0x58595A20 // 'XYZ ' + + +} cmsTagTypeSignature; + +// Base ICC tag definitions +typedef enum { + cmsSigAToB0Tag = 0x41324230, // 'A2B0' + cmsSigAToB1Tag = 0x41324231, // 'A2B1' + cmsSigAToB2Tag = 0x41324232, // 'A2B2' + cmsSigBlueColorantTag = 0x6258595A, // 'bXYZ' + cmsSigBlueMatrixColumnTag = 0x6258595A, // 'bXYZ' + cmsSigBlueTRCTag = 0x62545243, // 'bTRC' + cmsSigBToA0Tag = 0x42324130, // 'B2A0' + cmsSigBToA1Tag = 0x42324131, // 'B2A1' + cmsSigBToA2Tag = 0x42324132, // 'B2A2' + cmsSigCalibrationDateTimeTag = 0x63616C74, // 'calt' + cmsSigCharTargetTag = 0x74617267, // 'targ' + cmsSigChromaticAdaptationTag = 0x63686164, // 'chad' + cmsSigChromaticityTag = 0x6368726D, // 'chrm' + cmsSigColorantOrderTag = 0x636C726F, // 'clro' + cmsSigColorantTableTag = 0x636C7274, // 'clrt' + cmsSigColorantTableOutTag = 0x636C6F74, // 'clot' + cmsSigColorimetricIntentImageStateTag = 0x63696973, // 'ciis' + cmsSigCopyrightTag = 0x63707274, // 'cprt' + cmsSigCrdInfoTag = 0x63726469, // 'crdi' + cmsSigDataTag = 0x64617461, // 'data' + cmsSigDateTimeTag = 0x6474696D, // 'dtim' + cmsSigDeviceMfgDescTag = 0x646D6E64, // 'dmnd' + cmsSigDeviceModelDescTag = 0x646D6464, // 'dmdd' + cmsSigDeviceSettingsTag = 0x64657673, // 'devs' + cmsSigDToB0Tag = 0x44324230, // 'D2B0' + cmsSigDToB1Tag = 0x44324231, // 'D2B1' + cmsSigDToB2Tag = 0x44324232, // 'D2B2' + cmsSigDToB3Tag = 0x44324233, // 'D2B3' + cmsSigBToD0Tag = 0x42324430, // 'B2D0' + cmsSigBToD1Tag = 0x42324431, // 'B2D1' + cmsSigBToD2Tag = 0x42324432, // 'B2D2' + cmsSigBToD3Tag = 0x42324433, // 'B2D3' + cmsSigGamutTag = 0x67616D74, // 'gamt' + cmsSigGrayTRCTag = 0x6b545243, // 'kTRC' + cmsSigGreenColorantTag = 0x6758595A, // 'gXYZ' + cmsSigGreenMatrixColumnTag = 0x6758595A, // 'gXYZ' + cmsSigGreenTRCTag = 0x67545243, // 'gTRC' + cmsSigLuminanceTag = 0x6C756d69, // 'lumi' + cmsSigMeasurementTag = 0x6D656173, // 'meas' + cmsSigMediaBlackPointTag = 0x626B7074, // 'bkpt' + cmsSigMediaWhitePointTag = 0x77747074, // 'wtpt' + cmsSigNamedColorTag = 0x6E636f6C, // 'ncol' // Deprecated by the ICC + cmsSigNamedColor2Tag = 0x6E636C32, // 'ncl2' + cmsSigOutputResponseTag = 0x72657370, // 'resp' + cmsSigPerceptualRenderingIntentGamutTag = 0x72696730, // 'rig0' + cmsSigPreview0Tag = 0x70726530, // 'pre0' + cmsSigPreview1Tag = 0x70726531, // 'pre1' + cmsSigPreview2Tag = 0x70726532, // 'pre2' + cmsSigProfileDescriptionTag = 0x64657363, // 'desc' + cmsSigProfileDescriptionMLTag = 0x6473636d, // 'dscm' + cmsSigProfileSequenceDescTag = 0x70736571, // 'pseq' + cmsSigProfileSequenceIdTag = 0x70736964, // 'psid' + cmsSigPs2CRD0Tag = 0x70736430, // 'psd0' + cmsSigPs2CRD1Tag = 0x70736431, // 'psd1' + cmsSigPs2CRD2Tag = 0x70736432, // 'psd2' + cmsSigPs2CRD3Tag = 0x70736433, // 'psd3' + cmsSigPs2CSATag = 0x70733273, // 'ps2s' + cmsSigPs2RenderingIntentTag = 0x70733269, // 'ps2i' + cmsSigRedColorantTag = 0x7258595A, // 'rXYZ' + cmsSigRedMatrixColumnTag = 0x7258595A, // 'rXYZ' + cmsSigRedTRCTag = 0x72545243, // 'rTRC' + cmsSigSaturationRenderingIntentGamutTag = 0x72696732, // 'rig2' + cmsSigScreeningDescTag = 0x73637264, // 'scrd' + cmsSigScreeningTag = 0x7363726E, // 'scrn' + cmsSigTechnologyTag = 0x74656368, // 'tech' + cmsSigUcrBgTag = 0x62666420, // 'bfd ' + cmsSigViewingCondDescTag = 0x76756564, // 'vued' + cmsSigViewingConditionsTag = 0x76696577, // 'view' + cmsSigVcgtTag = 0x76636774, // 'vcgt' + cmsSigMetaTag = 0x6D657461, // 'meta' + cmsSigcicpTag = 0x63696370, // 'cicp' + cmsSigArgyllArtsTag = 0x61727473 // 'arts' + +} cmsTagSignature; + + +// ICC Technology tag +typedef enum { + cmsSigDigitalCamera = 0x6463616D, // 'dcam' + cmsSigFilmScanner = 0x6673636E, // 'fscn' + cmsSigReflectiveScanner = 0x7273636E, // 'rscn' + cmsSigInkJetPrinter = 0x696A6574, // 'ijet' + cmsSigThermalWaxPrinter = 0x74776178, // 'twax' + cmsSigElectrophotographicPrinter = 0x6570686F, // 'epho' + cmsSigElectrostaticPrinter = 0x65737461, // 'esta' + cmsSigDyeSublimationPrinter = 0x64737562, // 'dsub' + cmsSigPhotographicPaperPrinter = 0x7270686F, // 'rpho' + cmsSigFilmWriter = 0x6670726E, // 'fprn' + cmsSigVideoMonitor = 0x7669646D, // 'vidm' + cmsSigVideoCamera = 0x76696463, // 'vidc' + cmsSigProjectionTelevision = 0x706A7476, // 'pjtv' + cmsSigCRTDisplay = 0x43525420, // 'CRT ' + cmsSigPMDisplay = 0x504D4420, // 'PMD ' + cmsSigAMDisplay = 0x414D4420, // 'AMD ' + cmsSigPhotoCD = 0x4B504344, // 'KPCD' + cmsSigPhotoImageSetter = 0x696D6773, // 'imgs' + cmsSigGravure = 0x67726176, // 'grav' + cmsSigOffsetLithography = 0x6F666673, // 'offs' + cmsSigSilkscreen = 0x73696C6B, // 'silk' + cmsSigFlexography = 0x666C6578, // 'flex' + cmsSigMotionPictureFilmScanner = 0x6D706673, // 'mpfs' + cmsSigMotionPictureFilmRecorder = 0x6D706672, // 'mpfr' + cmsSigDigitalMotionPictureCamera = 0x646D7063, // 'dmpc' + cmsSigDigitalCinemaProjector = 0x64636A70 // 'dcpj' + +} cmsTechnologySignature; + + +// ICC Color spaces +typedef enum { + cmsSigXYZData = 0x58595A20, // 'XYZ ' + cmsSigLabData = 0x4C616220, // 'Lab ' + cmsSigLuvData = 0x4C757620, // 'Luv ' + cmsSigYCbCrData = 0x59436272, // 'YCbr' + cmsSigYxyData = 0x59787920, // 'Yxy ' + cmsSigRgbData = 0x52474220, // 'RGB ' + cmsSigGrayData = 0x47524159, // 'GRAY' + cmsSigHsvData = 0x48535620, // 'HSV ' + cmsSigHlsData = 0x484C5320, // 'HLS ' + cmsSigCmykData = 0x434D594B, // 'CMYK' + cmsSigCmyData = 0x434D5920, // 'CMY ' + cmsSigMCH1Data = 0x4D434831, // 'MCH1' + cmsSigMCH2Data = 0x4D434832, // 'MCH2' + cmsSigMCH3Data = 0x4D434833, // 'MCH3' + cmsSigMCH4Data = 0x4D434834, // 'MCH4' + cmsSigMCH5Data = 0x4D434835, // 'MCH5' + cmsSigMCH6Data = 0x4D434836, // 'MCH6' + cmsSigMCH7Data = 0x4D434837, // 'MCH7' + cmsSigMCH8Data = 0x4D434838, // 'MCH8' + cmsSigMCH9Data = 0x4D434839, // 'MCH9' + cmsSigMCHAData = 0x4D434841, // 'MCHA' + cmsSigMCHBData = 0x4D434842, // 'MCHB' + cmsSigMCHCData = 0x4D434843, // 'MCHC' + cmsSigMCHDData = 0x4D434844, // 'MCHD' + cmsSigMCHEData = 0x4D434845, // 'MCHE' + cmsSigMCHFData = 0x4D434846, // 'MCHF' + cmsSigNamedData = 0x6e6d636c, // 'nmcl' + cmsSig1colorData = 0x31434C52, // '1CLR' + cmsSig2colorData = 0x32434C52, // '2CLR' + cmsSig3colorData = 0x33434C52, // '3CLR' + cmsSig4colorData = 0x34434C52, // '4CLR' + cmsSig5colorData = 0x35434C52, // '5CLR' + cmsSig6colorData = 0x36434C52, // '6CLR' + cmsSig7colorData = 0x37434C52, // '7CLR' + cmsSig8colorData = 0x38434C52, // '8CLR' + cmsSig9colorData = 0x39434C52, // '9CLR' + cmsSig10colorData = 0x41434C52, // 'ACLR' + cmsSig11colorData = 0x42434C52, // 'BCLR' + cmsSig12colorData = 0x43434C52, // 'CCLR' + cmsSig13colorData = 0x44434C52, // 'DCLR' + cmsSig14colorData = 0x45434C52, // 'ECLR' + cmsSig15colorData = 0x46434C52, // 'FCLR' + cmsSigLuvKData = 0x4C75764B // 'LuvK' + +} cmsColorSpaceSignature; + +// ICC Profile Class +typedef enum { + cmsSigInputClass = 0x73636E72, // 'scnr' + cmsSigDisplayClass = 0x6D6E7472, // 'mntr' + cmsSigOutputClass = 0x70727472, // 'prtr' + cmsSigLinkClass = 0x6C696E6B, // 'link' + cmsSigAbstractClass = 0x61627374, // 'abst' + cmsSigColorSpaceClass = 0x73706163, // 'spac' + cmsSigNamedColorClass = 0x6e6d636c // 'nmcl' + +} cmsProfileClassSignature; + +// ICC Platforms +typedef enum { + cmsSigMacintosh = 0x4150504C, // 'APPL' + cmsSigMicrosoft = 0x4D534654, // 'MSFT' + cmsSigSolaris = 0x53554E57, // 'SUNW' + cmsSigSGI = 0x53474920, // 'SGI ' + cmsSigTaligent = 0x54474E54, // 'TGNT' + cmsSigUnices = 0x2A6E6978 // '*nix' // From argyll -- Not official + +} cmsPlatformSignature; + +// Reference gamut +#define cmsSigPerceptualReferenceMediumGamut 0x70726d67 //'prmg' + +// For cmsSigColorimetricIntentImageStateTag +#define cmsSigSceneColorimetryEstimates 0x73636F65 //'scoe' +#define cmsSigSceneAppearanceEstimates 0x73617065 //'sape' +#define cmsSigFocalPlaneColorimetryEstimates 0x66706365 //'fpce' +#define cmsSigReflectionHardcopyOriginalColorimetry 0x72686F63 //'rhoc' +#define cmsSigReflectionPrintOutputColorimetry 0x72706F63 //'rpoc' + +// Multi process elements types +typedef enum { + cmsSigCurveSetElemType = 0x63767374, //'cvst' + cmsSigMatrixElemType = 0x6D617466, //'matf' + cmsSigCLutElemType = 0x636C7574, //'clut' + + cmsSigBAcsElemType = 0x62414353, // 'bACS' + cmsSigEAcsElemType = 0x65414353, // 'eACS' + + // Custom from here, not in the ICC Spec + cmsSigXYZ2LabElemType = 0x6C327820, // 'l2x ' + cmsSigLab2XYZElemType = 0x78326C20, // 'x2l ' + cmsSigNamedColorElemType = 0x6E636C20, // 'ncl ' + cmsSigLabV2toV4 = 0x32203420, // '2 4 ' + cmsSigLabV4toV2 = 0x34203220, // '4 2 ' + + // Identities + cmsSigIdentityElemType = 0x69646E20, // 'idn ' + + // Float to floatPCS + cmsSigLab2FloatPCS = 0x64326C20, // 'd2l ' + cmsSigFloatPCS2Lab = 0x6C326420, // 'l2d ' + cmsSigXYZ2FloatPCS = 0x64327820, // 'd2x ' + cmsSigFloatPCS2XYZ = 0x78326420, // 'x2d ' + cmsSigClipNegativesElemType = 0x636c7020 // 'clp ' + +} cmsStageSignature; + +// Types of CurveElements +typedef enum { + + cmsSigFormulaCurveSeg = 0x70617266, // 'parf' + cmsSigSampledCurveSeg = 0x73616D66, // 'samf' + cmsSigSegmentedCurve = 0x63757266 // 'curf' + +} cmsCurveSegSignature; + +// Used in ResponseCurveType +#define cmsSigStatusA 0x53746141 //'StaA' +#define cmsSigStatusE 0x53746145 //'StaE' +#define cmsSigStatusI 0x53746149 //'StaI' +#define cmsSigStatusT 0x53746154 //'StaT' +#define cmsSigStatusM 0x5374614D //'StaM' +#define cmsSigDN 0x444E2020 //'DN ' +#define cmsSigDNP 0x444E2050 //'DN P' +#define cmsSigDNN 0x444E4E20 //'DNN ' +#define cmsSigDNNP 0x444E4E50 //'DNNP' + +// Device attributes, currently defined values correspond to the low 4 bytes +// of the 8 byte attribute quantity +#define cmsReflective 0 +#define cmsTransparency 1 +#define cmsGlossy 0 +#define cmsMatte 2 + +// Common structures in ICC tags +typedef struct { + cmsUInt32Number len; + cmsUInt32Number flag; + cmsUInt8Number data[1]; + +} cmsICCData; + +// ICC date time +typedef struct { + cmsUInt16Number year; + cmsUInt16Number month; + cmsUInt16Number day; + cmsUInt16Number hours; + cmsUInt16Number minutes; + cmsUInt16Number seconds; + +} cmsDateTimeNumber; + +// ICC XYZ +typedef struct { + cmsS15Fixed16Number X; + cmsS15Fixed16Number Y; + cmsS15Fixed16Number Z; + +} cmsEncodedXYZNumber; + + +// Profile ID as computed by MD5 algorithm +typedef union { + cmsUInt8Number ID8[16]; + cmsUInt16Number ID16[8]; + cmsUInt32Number ID32[4]; + +} cmsProfileID; + + +// ---------------------------------------------------------------------------------------------- +// ICC profile internal base types. Strictly, shouldn't be declared in this header, but maybe +// somebody want to use this info for accessing profile header directly, so here it is. + +// Profile header -- it is 32-bit aligned, so no issues are expected on alignment +typedef struct { + cmsUInt32Number size; // Profile size in bytes + cmsSignature cmmId; // CMM for this profile + cmsUInt32Number version; // Format version number + cmsProfileClassSignature deviceClass; // Type of profile + cmsColorSpaceSignature colorSpace; // Color space of data + cmsColorSpaceSignature pcs; // PCS, XYZ or Lab only + cmsDateTimeNumber date; // Date profile was created + cmsSignature magic; // Magic Number to identify an ICC profile + cmsPlatformSignature platform; // Primary Platform + cmsUInt32Number flags; // Various bit settings + cmsSignature manufacturer; // Device manufacturer + cmsUInt32Number model; // Device model number + cmsUInt64Number attributes; // Device attributes + cmsUInt32Number renderingIntent;// Rendering intent + cmsEncodedXYZNumber illuminant; // Profile illuminant + cmsSignature creator; // Profile creator + cmsProfileID profileID; // Profile ID using MD5 + cmsInt8Number reserved[28]; // Reserved for future use + +} cmsICCHeader; + +// ICC base tag +typedef struct { + cmsTagTypeSignature sig; + cmsInt8Number reserved[4]; + +} cmsTagBase; + +// A tag entry in directory +typedef struct { + cmsTagSignature sig; // The tag signature + cmsUInt32Number offset; // Start of tag + cmsUInt32Number size; // Size in bytes + +} cmsTagEntry; + +// ---------------------------------------------------------------------------------------------- + +// Little CMS specific typedefs + +typedef void* cmsHANDLE ; // Generic handle +typedef void* cmsHPROFILE; // Opaque typedefs to hide internals +typedef void* cmsHTRANSFORM; + +#define cmsMAXCHANNELS 16 // Maximum number of channels in ICC profiles + +// Format of pixel is defined by one cmsUInt32Number, using bit fields as follows +// +// 2 1 0 +// 4 3 2 10987 6 5 4 3 2 1 098 7654 321 +// M A O TTTTT U Y F P X S EEE CCCC BBB +// +// M: Premultiplied alpha (only works when extra samples is 1) +// A: Floating point -- With this flag we can differentiate 16 bits as float and as int +// O: Optimized -- previous optimization already returns the final 8-bit value +// T: Pixeltype +// F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla) +// P: Planar? 0=Chunky, 1=Planar +// X: swap 16 bps endianness? +// S: Do swap? ie, BGR, KYMC +// E: Extra samples +// C: Channels (Samples per pixel) +// B: bytes per sample +// Y: Swap first - changes ABGR to BGRA and KCMY to CMYK + +#define PREMUL_SH(m) ((m) << 23) +#define FLOAT_SH(a) ((a) << 22) +#define OPTIMIZED_SH(s) ((s) << 21) +#define COLORSPACE_SH(s) ((s) << 16) +#define SWAPFIRST_SH(s) ((s) << 14) +#define FLAVOR_SH(s) ((s) << 13) +#define PLANAR_SH(p) ((p) << 12) +#define ENDIAN16_SH(e) ((e) << 11) +#define DOSWAP_SH(e) ((e) << 10) +#define EXTRA_SH(e) ((e) << 7) +#define CHANNELS_SH(c) ((c) << 3) +#define BYTES_SH(b) (b) + +// These macros unpack format specifiers into integers +#define T_PREMUL(m) (((m)>>23)&1) +#define T_FLOAT(a) (((a)>>22)&1) +#define T_OPTIMIZED(o) (((o)>>21)&1) +#define T_COLORSPACE(s) (((s)>>16)&31) +#define T_SWAPFIRST(s) (((s)>>14)&1) +#define T_FLAVOR(s) (((s)>>13)&1) +#define T_PLANAR(p) (((p)>>12)&1) +#define T_ENDIAN16(e) (((e)>>11)&1) +#define T_DOSWAP(e) (((e)>>10)&1) +#define T_EXTRA(e) (((e)>>7)&7) +#define T_CHANNELS(c) (((c)>>3)&15) +#define T_BYTES(b) ((b)&7) + + +// Pixel types +#define PT_ANY 0 // Don't check colorspace + // 1 & 2 are reserved +#define PT_GRAY 3 +#define PT_RGB 4 +#define PT_CMY 5 +#define PT_CMYK 6 +#define PT_YCbCr 7 +#define PT_YUV 8 // Lu'v' +#define PT_XYZ 9 +#define PT_Lab 10 +#define PT_YUVK 11 // Lu'v'K +#define PT_HSV 12 +#define PT_HLS 13 +#define PT_Yxy 14 +#define PT_MCH1 15 +#define PT_MCH2 16 +#define PT_MCH3 17 +#define PT_MCH4 18 +#define PT_MCH5 19 +#define PT_MCH6 20 +#define PT_MCH7 21 +#define PT_MCH8 22 +#define PT_MCH9 23 +#define PT_MCH10 24 +#define PT_MCH11 25 +#define PT_MCH12 26 +#define PT_MCH13 27 +#define PT_MCH14 28 +#define PT_MCH15 29 +#define PT_LabV2 30 // Identical to PT_Lab, but using the V2 old encoding + +// Some (not all!) representations + +#ifndef TYPE_RGB_8 // TYPE_RGB_8 is a very common identifier, so don't include ours + // if user has it already defined. + +#define TYPE_GRAY_8 (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(1)) +#define TYPE_GRAY_8_REV (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1)) +#define TYPE_GRAY_16 (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2)) +#define TYPE_GRAY_16_REV (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1)) +#define TYPE_GRAY_16_SE (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_GRAYA_8 (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(1)) +#define TYPE_GRAYA_8_PREMUL (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(1)|PREMUL_SH(1)) +#define TYPE_GRAYA_16 (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2)) +#define TYPE_GRAYA_16_PREMUL (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2)|PREMUL_SH(1)) +#define TYPE_GRAYA_16_SE (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_GRAYA_8_PLANAR (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_GRAYA_16_PLANAR (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2)|PLANAR_SH(1)) + +#define TYPE_RGB_8 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_RGB_8_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_BGR_8 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_BGR_8_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|PLANAR_SH(1)) +#define TYPE_RGB_16 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_RGB_16_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_RGB_16_SE (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_BGR_16 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_BGR_16_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|PLANAR_SH(1)) +#define TYPE_BGR_16_SE (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +#define TYPE_RGBA_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_RGBA_8_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|PREMUL_SH(1)) +#define TYPE_RGBA_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_RGBA_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_RGBA_16_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|PREMUL_SH(1)) +#define TYPE_RGBA_16_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_RGBA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +#define TYPE_ARGB_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_ARGB_8_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1)|PREMUL_SH(1)) +#define TYPE_ARGB_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1)|PLANAR_SH(1)) +#define TYPE_ARGB_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1)) +#define TYPE_ARGB_16_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1)|PREMUL_SH(1)) + +#define TYPE_ABGR_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_ABGR_8_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|PREMUL_SH(1)) +#define TYPE_ABGR_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|PLANAR_SH(1)) +#define TYPE_ABGR_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_ABGR_16_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|PREMUL_SH(1)) +#define TYPE_ABGR_16_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|PLANAR_SH(1)) +#define TYPE_ABGR_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +#define TYPE_BGRA_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_BGRA_8_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|PREMUL_SH(1)) +#define TYPE_BGRA_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|PLANAR_SH(1)) +#define TYPE_BGRA_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_BGRA_16_PREMUL (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|PREMUL_SH(1)) +#define TYPE_BGRA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)) + +#define TYPE_CMY_8 (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_CMY_8_PLANAR (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_CMY_16 (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_CMY_16_PLANAR (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_CMY_16_SE (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +#define TYPE_CMYK_8 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)) +#define TYPE_CMYKA_8 (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(1)) +#define TYPE_CMYK_8_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1)) +#define TYPE_YUVK_8 TYPE_CMYK_8_REV +#define TYPE_CMYK_8_PLANAR (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_CMYK_16 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)) +#define TYPE_CMYK_16_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1)) +#define TYPE_YUVK_16 TYPE_CMYK_16_REV +#define TYPE_CMYK_16_PLANAR (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_CMYK_16_SE (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1)) + +#define TYPE_KYMC_8 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC_16 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC_16_SE (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +#define TYPE_KCMY_8 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_8_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_16 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_16_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_16_SE (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1)|SWAPFIRST_SH(1)) + +#define TYPE_CMYK5_8 (COLORSPACE_SH(PT_MCH5)|CHANNELS_SH(5)|BYTES_SH(1)) +#define TYPE_CMYK5_16 (COLORSPACE_SH(PT_MCH5)|CHANNELS_SH(5)|BYTES_SH(2)) +#define TYPE_CMYK5_16_SE (COLORSPACE_SH(PT_MCH5)|CHANNELS_SH(5)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC5_8 (COLORSPACE_SH(PT_MCH5)|CHANNELS_SH(5)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC5_16 (COLORSPACE_SH(PT_MCH5)|CHANNELS_SH(5)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC5_16_SE (COLORSPACE_SH(PT_MCH5)|CHANNELS_SH(5)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK6_8 (COLORSPACE_SH(PT_MCH6)|CHANNELS_SH(6)|BYTES_SH(1)) +#define TYPE_CMYK6_8_PLANAR (COLORSPACE_SH(PT_MCH6)|CHANNELS_SH(6)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_CMYK6_16 (COLORSPACE_SH(PT_MCH6)|CHANNELS_SH(6)|BYTES_SH(2)) +#define TYPE_CMYK6_16_PLANAR (COLORSPACE_SH(PT_MCH6)|CHANNELS_SH(6)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_CMYK6_16_SE (COLORSPACE_SH(PT_MCH6)|CHANNELS_SH(6)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_CMYK7_8 (COLORSPACE_SH(PT_MCH7)|CHANNELS_SH(7)|BYTES_SH(1)) +#define TYPE_CMYK7_16 (COLORSPACE_SH(PT_MCH7)|CHANNELS_SH(7)|BYTES_SH(2)) +#define TYPE_CMYK7_16_SE (COLORSPACE_SH(PT_MCH7)|CHANNELS_SH(7)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC7_8 (COLORSPACE_SH(PT_MCH7)|CHANNELS_SH(7)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC7_16 (COLORSPACE_SH(PT_MCH7)|CHANNELS_SH(7)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC7_16_SE (COLORSPACE_SH(PT_MCH7)|CHANNELS_SH(7)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK8_8 (COLORSPACE_SH(PT_MCH8)|CHANNELS_SH(8)|BYTES_SH(1)) +#define TYPE_CMYK8_16 (COLORSPACE_SH(PT_MCH8)|CHANNELS_SH(8)|BYTES_SH(2)) +#define TYPE_CMYK8_16_SE (COLORSPACE_SH(PT_MCH8)|CHANNELS_SH(8)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC8_8 (COLORSPACE_SH(PT_MCH8)|CHANNELS_SH(8)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC8_16 (COLORSPACE_SH(PT_MCH8)|CHANNELS_SH(8)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC8_16_SE (COLORSPACE_SH(PT_MCH8)|CHANNELS_SH(8)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK9_8 (COLORSPACE_SH(PT_MCH9)|CHANNELS_SH(9)|BYTES_SH(1)) +#define TYPE_CMYK9_16 (COLORSPACE_SH(PT_MCH9)|CHANNELS_SH(9)|BYTES_SH(2)) +#define TYPE_CMYK9_16_SE (COLORSPACE_SH(PT_MCH9)|CHANNELS_SH(9)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC9_8 (COLORSPACE_SH(PT_MCH9)|CHANNELS_SH(9)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC9_16 (COLORSPACE_SH(PT_MCH9)|CHANNELS_SH(9)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC9_16_SE (COLORSPACE_SH(PT_MCH9)|CHANNELS_SH(9)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK10_8 (COLORSPACE_SH(PT_MCH10)|CHANNELS_SH(10)|BYTES_SH(1)) +#define TYPE_CMYK10_16 (COLORSPACE_SH(PT_MCH10)|CHANNELS_SH(10)|BYTES_SH(2)) +#define TYPE_CMYK10_16_SE (COLORSPACE_SH(PT_MCH10)|CHANNELS_SH(10)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC10_8 (COLORSPACE_SH(PT_MCH10)|CHANNELS_SH(10)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC10_16 (COLORSPACE_SH(PT_MCH10)|CHANNELS_SH(10)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC10_16_SE (COLORSPACE_SH(PT_MCH10)|CHANNELS_SH(10)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK11_8 (COLORSPACE_SH(PT_MCH11)|CHANNELS_SH(11)|BYTES_SH(1)) +#define TYPE_CMYK11_16 (COLORSPACE_SH(PT_MCH11)|CHANNELS_SH(11)|BYTES_SH(2)) +#define TYPE_CMYK11_16_SE (COLORSPACE_SH(PT_MCH11)|CHANNELS_SH(11)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC11_8 (COLORSPACE_SH(PT_MCH11)|CHANNELS_SH(11)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC11_16 (COLORSPACE_SH(PT_MCH11)|CHANNELS_SH(11)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC11_16_SE (COLORSPACE_SH(PT_MCH11)|CHANNELS_SH(11)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK12_8 (COLORSPACE_SH(PT_MCH12)|CHANNELS_SH(12)|BYTES_SH(1)) +#define TYPE_CMYK12_16 (COLORSPACE_SH(PT_MCH12)|CHANNELS_SH(12)|BYTES_SH(2)) +#define TYPE_CMYK12_16_SE (COLORSPACE_SH(PT_MCH12)|CHANNELS_SH(12)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC12_8 (COLORSPACE_SH(PT_MCH12)|CHANNELS_SH(12)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC12_16 (COLORSPACE_SH(PT_MCH12)|CHANNELS_SH(12)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC12_16_SE (COLORSPACE_SH(PT_MCH12)|CHANNELS_SH(12)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +// Colorimetric +#define TYPE_XYZ_16 (COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_Lab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_LabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1)) + +#define TYPE_ALab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_ALabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_Lab_16 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_LabV2_16 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_Yxy_16 (COLORSPACE_SH(PT_Yxy)|CHANNELS_SH(3)|BYTES_SH(2)) + +// YCbCr +#define TYPE_YCbCr_8 (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_YCbCr_8_PLANAR (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_YCbCr_16 (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_YCbCr_16_PLANAR (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_YCbCr_16_SE (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// YUV +#define TYPE_YUV_8 (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_YUV_8_PLANAR (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_YUV_16 (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_YUV_16_PLANAR (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_YUV_16_SE (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// HLS +#define TYPE_HLS_8 (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_HLS_8_PLANAR (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_HLS_16 (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_HLS_16_PLANAR (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_HLS_16_SE (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// HSV +#define TYPE_HSV_8 (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_HSV_8_PLANAR (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_HSV_16 (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_HSV_16_PLANAR (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_HSV_16_SE (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// Named color index. Only 16 bits is allowed (don't check colorspace) +#define TYPE_NAMED_COLOR_INDEX (CHANNELS_SH(1)|BYTES_SH(2)) + +// Float formatters. +#define TYPE_XYZ_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(4)) +#define TYPE_Lab_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(4)) +#define TYPE_LabA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)) +#define TYPE_GRAY_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(4)) +#define TYPE_GRAYA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(4)|EXTRA_SH(1)) +#define TYPE_GRAYA_FLT_PREMUL (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(4)|EXTRA_SH(1)|PREMUL_SH(1)) +#define TYPE_RGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)) + +#define TYPE_RGBA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)) +#define TYPE_RGBA_FLT_PREMUL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|PREMUL_SH(1)) +#define TYPE_ARGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|SWAPFIRST_SH(1)) +#define TYPE_ARGB_FLT_PREMUL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|SWAPFIRST_SH(1)|PREMUL_SH(1)) +#define TYPE_BGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)) +#define TYPE_BGRA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_BGRA_FLT_PREMUL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|PREMUL_SH(1)) +#define TYPE_ABGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)) +#define TYPE_ABGR_FLT_PREMUL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|PREMUL_SH(1)) + +#define TYPE_CMYK_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(4)) + +// Floating point formatters. +// NOTE THAT 'BYTES' FIELD IS SET TO ZERO ON DLB because 8 bytes overflows the bitfield +#define TYPE_XYZ_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(0)) +#define TYPE_Lab_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(0)) +#define TYPE_GRAY_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(0)) +#define TYPE_RGB_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0)) +#define TYPE_BGR_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0)|DOSWAP_SH(1)) +#define TYPE_CMYK_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(0)) + +// IEEE 754-2008 "half" +#define TYPE_GRAY_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2)) +#define TYPE_RGB_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_RGBA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_CMYK_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)) + +#define TYPE_RGBA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_ARGB_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1)) +#define TYPE_BGR_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_BGRA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_ABGR_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)) + +#endif + +// Colorspaces +typedef struct { + cmsFloat64Number X; + cmsFloat64Number Y; + cmsFloat64Number Z; + + } cmsCIEXYZ; + +typedef struct { + cmsFloat64Number x; + cmsFloat64Number y; + cmsFloat64Number Y; + + } cmsCIExyY; + +typedef struct { + cmsFloat64Number L; + cmsFloat64Number a; + cmsFloat64Number b; + + } cmsCIELab; + +typedef struct { + cmsFloat64Number L; + cmsFloat64Number C; + cmsFloat64Number h; + + } cmsCIELCh; + +typedef struct { + cmsFloat64Number J; + cmsFloat64Number C; + cmsFloat64Number h; + + } cmsJCh; + +typedef struct { + cmsCIEXYZ Red; + cmsCIEXYZ Green; + cmsCIEXYZ Blue; + + } cmsCIEXYZTRIPLE; + +typedef struct { + cmsCIExyY Red; + cmsCIExyY Green; + cmsCIExyY Blue; + + } cmsCIExyYTRIPLE; + +// Illuminant types for structs below +#define cmsILLUMINANT_TYPE_UNKNOWN 0x0000000 +#define cmsILLUMINANT_TYPE_D50 0x0000001 +#define cmsILLUMINANT_TYPE_D65 0x0000002 +#define cmsILLUMINANT_TYPE_D93 0x0000003 +#define cmsILLUMINANT_TYPE_F2 0x0000004 +#define cmsILLUMINANT_TYPE_D55 0x0000005 +#define cmsILLUMINANT_TYPE_A 0x0000006 +#define cmsILLUMINANT_TYPE_E 0x0000007 +#define cmsILLUMINANT_TYPE_F8 0x0000008 + +typedef struct { + cmsUInt32Number Observer; // 0 = unknown, 1=CIE 1931, 2=CIE 1964 + cmsCIEXYZ Backing; // Value of backing + cmsUInt32Number Geometry; // 0=unknown, 1=45/0, 0/45 2=0d, d/0 + cmsFloat64Number Flare; // 0..1.0 + cmsUInt32Number IlluminantType; + + } cmsICCMeasurementConditions; + +typedef struct { + cmsCIEXYZ IlluminantXYZ; // Not the same struct as CAM02, + cmsCIEXYZ SurroundXYZ; // This is for storing the tag + cmsUInt32Number IlluminantType; // viewing condition + + } cmsICCViewingConditions; + +typedef struct { + cmsUInt8Number ColourPrimaries; // Recommendation ITU-T H.273 + cmsUInt8Number TransferCharacteristics; // (ISO/IEC 23091-2) + cmsUInt8Number MatrixCoefficients; + cmsUInt8Number VideoFullRangeFlag; + +} cmsVideoSignalType; + + + +// Get LittleCMS version (for shared objects) ----------------------------------------------------------------------------- + +CMSAPI int CMSEXPORT cmsGetEncodedCMMversion(void); + +// Support of non-standard functions -------------------------------------------------------------------------------------- + +CMSAPI int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2); +CMSAPI long int CMSEXPORT cmsfilelength(FILE* f); + + +// Context handling -------------------------------------------------------------------------------------------------------- + +// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility +// though using the global context is not recommended. Proper context handling makes lcms more thread-safe. + +typedef struct _cmsContext_struct* cmsContext; + +CMSAPI cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData); +CMSAPI void CMSEXPORT cmsDeleteContext(cmsContext ContextID); +CMSAPI cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData); +CMSAPI void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID); + +// Plug-In registering -------------------------------------------------------------------------------------------------- + +CMSAPI cmsBool CMSEXPORT cmsPlugin(void* Plugin); +CMSAPI cmsBool CMSEXPORT cmsPluginTHR(cmsContext ContextID, void* Plugin); +CMSAPI void CMSEXPORT cmsUnregisterPlugins(void); +CMSAPI void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID); + +// Error logging ---------------------------------------------------------------------------------------------------------- + +// There is no error handling at all. When a function fails, it returns proper value. +// For example, all create functions does return NULL on failure. Other may return FALSE. +// It may be interesting, for the developer, to know why the function is failing. +// for that reason, lcms2 does offer a logging function. This function will get +// an ENGLISH string with some clues on what is going wrong. You can show this +// info to the end user if you wish, or just create some sort of log on disk. +// The logging function should NOT terminate the program, as this obviously can leave +// unfreed resources. It is the programmer's responsibility to check each function +// return code to make sure it didn't fail. + +#define cmsERROR_UNDEFINED 0 +#define cmsERROR_FILE 1 +#define cmsERROR_RANGE 2 +#define cmsERROR_INTERNAL 3 +#define cmsERROR_NULL 4 +#define cmsERROR_READ 5 +#define cmsERROR_SEEK 6 +#define cmsERROR_WRITE 7 +#define cmsERROR_UNKNOWN_EXTENSION 8 +#define cmsERROR_COLORSPACE_CHECK 9 +#define cmsERROR_ALREADY_DEFINED 10 +#define cmsERROR_BAD_SIGNATURE 11 +#define cmsERROR_CORRUPTION_DETECTED 12 +#define cmsERROR_NOT_SUITABLE 13 + +// Error logger is called with the ContextID when a message is raised. This gives the +// chance to know which thread is responsible of the warning and any environment associated +// with it. Non-multithreading applications may safely ignore this parameter. +// Note that under certain special circumstances, ContextID may be NULL. +typedef void (* cmsLogErrorHandlerFunction)(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text); + +// Allows user to set any specific logger +CMSAPI void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn); +CMSAPI void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn); + +// Conversions -------------------------------------------------------------------------------------------------------------- + +// Returns pointers to constant structs +CMSAPI const cmsCIEXYZ* CMSEXPORT cmsD50_XYZ(void); +CMSAPI const cmsCIExyY* CMSEXPORT cmsD50_xyY(void); + +// Colorimetric space conversions +CMSAPI void CMSEXPORT cmsXYZ2xyY(cmsCIExyY* Dest, const cmsCIEXYZ* Source); +CMSAPI void CMSEXPORT cmsxyY2XYZ(cmsCIEXYZ* Dest, const cmsCIExyY* Source); +CMSAPI void CMSEXPORT cmsXYZ2Lab(const cmsCIEXYZ* WhitePoint, cmsCIELab* Lab, const cmsCIEXYZ* xyz); +CMSAPI void CMSEXPORT cmsLab2XYZ(const cmsCIEXYZ* WhitePoint, cmsCIEXYZ* xyz, const cmsCIELab* Lab); +CMSAPI void CMSEXPORT cmsLab2LCh(cmsCIELCh*LCh, const cmsCIELab* Lab); +CMSAPI void CMSEXPORT cmsLCh2Lab(cmsCIELab* Lab, const cmsCIELCh* LCh); + +// Encoding /Decoding on PCS +CMSAPI void CMSEXPORT cmsLabEncoded2Float(cmsCIELab* Lab, const cmsUInt16Number wLab[3]); +CMSAPI void CMSEXPORT cmsLabEncoded2FloatV2(cmsCIELab* Lab, const cmsUInt16Number wLab[3]); +CMSAPI void CMSEXPORT cmsFloat2LabEncoded(cmsUInt16Number wLab[3], const cmsCIELab* Lab); +CMSAPI void CMSEXPORT cmsFloat2LabEncodedV2(cmsUInt16Number wLab[3], const cmsCIELab* Lab); +CMSAPI void CMSEXPORT cmsXYZEncoded2Float(cmsCIEXYZ* fxyz, const cmsUInt16Number XYZ[3]); +CMSAPI void CMSEXPORT cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3], const cmsCIEXYZ* fXYZ); + +// DeltaE metrics +CMSAPI cmsFloat64Number CMSEXPORT cmsDeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2); +CMSAPI cmsFloat64Number CMSEXPORT cmsCIE94DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2); +CMSAPI cmsFloat64Number CMSEXPORT cmsBFDdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2); +CMSAPI cmsFloat64Number CMSEXPORT cmsCMCdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2, cmsFloat64Number l, cmsFloat64Number c); +CMSAPI cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2, cmsFloat64Number Kl, cmsFloat64Number Kc, cmsFloat64Number Kh); + +// Temperature <-> Chromaticity (Black body) +CMSAPI cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number TempK); +CMSAPI cmsBool CMSEXPORT cmsTempFromWhitePoint(cmsFloat64Number* TempK, const cmsCIExyY* WhitePoint); + +// Chromatic adaptation +CMSAPI cmsBool CMSEXPORT cmsAdaptToIlluminant(cmsCIEXYZ* Result, const cmsCIEXYZ* SourceWhitePt, + const cmsCIEXYZ* Illuminant, + const cmsCIEXYZ* Value); + +// CIECAM02 --------------------------------------------------------------------------------------------------- + +// Viewing conditions. Please note those are CAM model viewing conditions, and not the ICC tag viewing +// conditions, which I'm naming cmsICCViewingConditions to make differences evident. Unfortunately, the tag +// cannot deal with surround La, Yb and D value so is basically useless to store CAM02 viewing conditions. + + +#define AVG_SURROUND 1 +#define DIM_SURROUND 2 +#define DARK_SURROUND 3 +#define CUTSHEET_SURROUND 4 + +#define D_CALCULATE (-1) + +typedef struct { + cmsCIEXYZ whitePoint; + cmsFloat64Number Yb; + cmsFloat64Number La; + cmsUInt32Number surround; + cmsFloat64Number D_value; + + } cmsViewingConditions; + +CMSAPI cmsHANDLE CMSEXPORT cmsCIECAM02Init(cmsContext ContextID, const cmsViewingConditions* pVC); +CMSAPI void CMSEXPORT cmsCIECAM02Done(cmsHANDLE hModel); +CMSAPI void CMSEXPORT cmsCIECAM02Forward(cmsHANDLE hModel, const cmsCIEXYZ* pIn, cmsJCh* pOut); +CMSAPI void CMSEXPORT cmsCIECAM02Reverse(cmsHANDLE hModel, const cmsJCh* pIn, cmsCIEXYZ* pOut); + + +// Tone curves ----------------------------------------------------------------------------------------- + +// This describes a curve segment. For a table of supported types, see the manual. User can increase the number of +// available types by using a proper plug-in. Parametric segments allow 10 parameters at most + +typedef struct { + cmsFloat32Number x0, x1; // Domain; for x0 < x <= x1 + cmsInt32Number Type; // Parametric type, Type == 0 means sampled segment. Negative values are reserved + cmsFloat64Number Params[10]; // Parameters if Type != 0 + cmsUInt32Number nGridPoints; // Number of grid points if Type == 0 + cmsFloat32Number* SampledPoints; // Points to an array of floats if Type == 0 + +} cmsCurveSegment; + +// The internal representation is none of your business. +typedef struct _cms_curve_struct cmsToneCurve; + +CMSAPI cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, cmsUInt32Number nSegments, const cmsCurveSegment Segments[]); +CMSAPI cmsToneCurve* CMSEXPORT cmsBuildParametricToneCurve(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[]); +CMSAPI cmsToneCurve* CMSEXPORT cmsBuildGamma(cmsContext ContextID, cmsFloat64Number Gamma); +CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsUInt32Number nEntries, const cmsUInt16Number values[]); +CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[]); +CMSAPI void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve); +CMSAPI void CMSEXPORT cmsFreeToneCurveTriple(cmsToneCurve* Curve[3]); +CMSAPI cmsToneCurve* CMSEXPORT cmsDupToneCurve(const cmsToneCurve* Src); +CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma); +CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsUInt32Number nResultSamples, const cmsToneCurve* InGamma); +CMSAPI cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, const cmsToneCurve* X, const cmsToneCurve* Y, cmsUInt32Number nPoints); +CMSAPI cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda); +CMSAPI cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v); +CMSAPI cmsUInt16Number CMSEXPORT cmsEvalToneCurve16(const cmsToneCurve* Curve, cmsUInt16Number v); +CMSAPI cmsBool CMSEXPORT cmsIsToneCurveMultisegment(const cmsToneCurve* InGamma); +CMSAPI cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve); +CMSAPI cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t); +CMSAPI cmsBool CMSEXPORT cmsIsToneCurveDescending(const cmsToneCurve* t); +CMSAPI cmsInt32Number CMSEXPORT cmsGetToneCurveParametricType(const cmsToneCurve* t); +CMSAPI cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Number Precision); +CMSAPI cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(const cmsToneCurve* t); + +// Tone curve tabular estimation +CMSAPI cmsUInt32Number CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t); +CMSAPI const cmsUInt16Number* CMSEXPORT cmsGetToneCurveEstimatedTable(const cmsToneCurve* t); + + +// Implements pipelines of multi-processing elements ------------------------------------------------------------- + +// Nothing to see here, move along +typedef struct _cmsPipeline_struct cmsPipeline; +typedef struct _cmsStage_struct cmsStage; + +// Those are hi-level pipelines +CMSAPI cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels); +CMSAPI void CMSEXPORT cmsPipelineFree(cmsPipeline* lut); +CMSAPI cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* Orig); + +CMSAPI cmsContext CMSEXPORT cmsGetPipelineContextID(const cmsPipeline* lut); +CMSAPI cmsUInt32Number CMSEXPORT cmsPipelineInputChannels(const cmsPipeline* lut); +CMSAPI cmsUInt32Number CMSEXPORT cmsPipelineOutputChannels(const cmsPipeline* lut); + +CMSAPI cmsUInt32Number CMSEXPORT cmsPipelineStageCount(const cmsPipeline* lut); +CMSAPI cmsStage* CMSEXPORT cmsPipelineGetPtrToFirstStage(const cmsPipeline* lut); +CMSAPI cmsStage* CMSEXPORT cmsPipelineGetPtrToLastStage(const cmsPipeline* lut); + +CMSAPI void CMSEXPORT cmsPipelineEval16(const cmsUInt16Number In[], cmsUInt16Number Out[], const cmsPipeline* lut); +CMSAPI void CMSEXPORT cmsPipelineEvalFloat(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsPipeline* lut); +CMSAPI cmsBool CMSEXPORT cmsPipelineEvalReverseFloat(cmsFloat32Number Target[], cmsFloat32Number Result[], cmsFloat32Number Hint[], const cmsPipeline* lut); +CMSAPI cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2); +CMSAPI cmsBool CMSEXPORT cmsPipelineSetSaveAs8bitsFlag(cmsPipeline* lut, cmsBool On); + +// Where to place/locate the stages in the pipeline chain +typedef enum { cmsAT_BEGIN, cmsAT_END } cmsStageLoc; + +CMSAPI cmsBool CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe); +CMSAPI void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage** mpe); + +// This function is quite useful to analyze the structure of a Pipeline and retrieve the Stage elements +// that conform the Pipeline. It should be called with the Pipeline, the number of expected elements and +// then a list of expected types followed with a list of double pointers to Stage elements. If +// the function founds a match with current pipeline, it fills the pointers and returns TRUE +// if not, returns FALSE without touching anything. +CMSAPI cmsBool CMSEXPORT cmsPipelineCheckAndRetreiveStages(const cmsPipeline* Lut, cmsUInt32Number n, ...); + +// Matrix has double precision and CLUT has only float precision. That is because an ICC profile can encode +// matrices with far more precision that CLUTS +CMSAPI cmsStage* CMSEXPORT cmsStageAllocIdentity(cmsContext ContextID, cmsUInt32Number nChannels); +CMSAPI cmsStage* CMSEXPORT cmsStageAllocToneCurves(cmsContext ContextID, cmsUInt32Number nChannels, cmsToneCurve* const Curves[]); +CMSAPI cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number Rows, cmsUInt32Number Cols, const cmsFloat64Number* Matrix, const cmsFloat64Number* Offset); + +CMSAPI cmsStage* CMSEXPORT cmsStageAllocCLut16bit(cmsContext ContextID, cmsUInt32Number nGridPoints, cmsUInt32Number inputChan, cmsUInt32Number outputChan, const cmsUInt16Number* Table); +CMSAPI cmsStage* CMSEXPORT cmsStageAllocCLutFloat(cmsContext ContextID, cmsUInt32Number nGridPoints, cmsUInt32Number inputChan, cmsUInt32Number outputChan, const cmsFloat32Number* Table); + +CMSAPI cmsStage* CMSEXPORT cmsStageAllocCLut16bitGranular(cmsContext ContextID, const cmsUInt32Number clutPoints[], cmsUInt32Number inputChan, cmsUInt32Number outputChan, const cmsUInt16Number* Table); +CMSAPI cmsStage* CMSEXPORT cmsStageAllocCLutFloatGranular(cmsContext ContextID, const cmsUInt32Number clutPoints[], cmsUInt32Number inputChan, cmsUInt32Number outputChan, const cmsFloat32Number* Table); + +CMSAPI cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe); +CMSAPI void CMSEXPORT cmsStageFree(cmsStage* mpe); +CMSAPI cmsStage* CMSEXPORT cmsStageNext(const cmsStage* mpe); + +CMSAPI cmsUInt32Number CMSEXPORT cmsStageInputChannels(const cmsStage* mpe); +CMSAPI cmsUInt32Number CMSEXPORT cmsStageOutputChannels(const cmsStage* mpe); +CMSAPI cmsStageSignature CMSEXPORT cmsStageType(const cmsStage* mpe); +CMSAPI void* CMSEXPORT cmsStageData(const cmsStage* mpe); +CMSAPI cmsContext CMSEXPORT cmsGetStageContextID(const cmsStage* mpe); + +// Sampling +typedef cmsInt32Number (* cmsSAMPLER16) (CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + CMSREGISTER void * Cargo); + +typedef cmsInt32Number (* cmsSAMPLERFLOAT)(CMSREGISTER const cmsFloat32Number In[], + CMSREGISTER cmsFloat32Number Out[], + CMSREGISTER void * Cargo); + +// Use this flag to prevent changes being written to destination +#define SAMPLER_INSPECT 0x01000000 + +// For CLUT only +CMSAPI cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags); +CMSAPI cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void* Cargo, cmsUInt32Number dwFlags); + +// Slicers +CMSAPI cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], + cmsSAMPLER16 Sampler, void * Cargo); + +CMSAPI cmsBool CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], + cmsSAMPLERFLOAT Sampler, void * Cargo); + +// Multilocalized Unicode management --------------------------------------------------------------------------------------- + +typedef struct _cms_MLU_struct cmsMLU; + +#define cmsNoLanguage "\0\0" +#define cmsNoCountry "\0\0" + +CMSAPI cmsMLU* CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems); +CMSAPI void CMSEXPORT cmsMLUfree(cmsMLU* mlu); +CMSAPI cmsMLU* CMSEXPORT cmsMLUdup(const cmsMLU* mlu); + +CMSAPI cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + const char* ASCIIString); +CMSAPI cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + const wchar_t* WideString); + +CMSAPI cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + char* Buffer, cmsUInt32Number BufferSize); + +CMSAPI cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + wchar_t* Buffer, cmsUInt32Number BufferSize); + +CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + char ObtainedLanguage[3], char ObtainedCountry[3]); + +CMSAPI cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu); + +CMSAPI cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu, + cmsUInt32Number idx, + char LanguageCode[3], + char CountryCode[3]); + +// Undercolorremoval & black generation ------------------------------------------------------------------------------------- + +typedef struct { + cmsToneCurve* Ucr; + cmsToneCurve* Bg; + cmsMLU* Desc; + +} cmsUcrBg; + +// Screening ---------------------------------------------------------------------------------------------------------------- + +#define cmsPRINTER_DEFAULT_SCREENS 0x0001 +#define cmsFREQUENCE_UNITS_LINES_CM 0x0000 +#define cmsFREQUENCE_UNITS_LINES_INCH 0x0002 + +#define cmsSPOT_UNKNOWN 0 +#define cmsSPOT_PRINTER_DEFAULT 1 +#define cmsSPOT_ROUND 2 +#define cmsSPOT_DIAMOND 3 +#define cmsSPOT_ELLIPSE 4 +#define cmsSPOT_LINE 5 +#define cmsSPOT_SQUARE 6 +#define cmsSPOT_CROSS 7 + +typedef struct { + cmsFloat64Number Frequency; + cmsFloat64Number ScreenAngle; + cmsUInt32Number SpotShape; + +} cmsScreeningChannel; + +typedef struct { + cmsUInt32Number Flag; + cmsUInt32Number nChannels; + cmsScreeningChannel Channels[cmsMAXCHANNELS]; + +} cmsScreening; + + +// Named color ----------------------------------------------------------------------------------------------------------------- + +typedef struct _cms_NAMEDCOLORLIST_struct cmsNAMEDCOLORLIST; + +CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, + cmsUInt32Number n, + cmsUInt32Number ColorantCount, + const char* Prefix, const char* Suffix); + +CMSAPI void CMSEXPORT cmsFreeNamedColorList(cmsNAMEDCOLORLIST* v); +CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v); +CMSAPI cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* v, const char* Name, + cmsUInt16Number PCS[3], + cmsUInt16Number Colorant[cmsMAXCHANNELS]); + +CMSAPI cmsUInt32Number CMSEXPORT cmsNamedColorCount(const cmsNAMEDCOLORLIST* v); +CMSAPI cmsInt32Number CMSEXPORT cmsNamedColorIndex(const cmsNAMEDCOLORLIST* v, const char* Name); + +CMSAPI cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cmsUInt32Number nColor, + char* Name, + char* Prefix, + char* Suffix, + cmsUInt16Number* PCS, + cmsUInt16Number* Colorant); + +// Retrieve named color list from transform +CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsGetNamedColorList(cmsHTRANSFORM xform); + +// Profile sequence ----------------------------------------------------------------------------------------------------- + +// Profile sequence descriptor. Some fields come from profile sequence descriptor tag, others +// come from Profile Sequence Identifier Tag +typedef struct { + + cmsSignature deviceMfg; + cmsSignature deviceModel; + cmsUInt64Number attributes; + cmsTechnologySignature technology; + cmsProfileID ProfileID; + cmsMLU* Manufacturer; + cmsMLU* Model; + cmsMLU* Description; + +} cmsPSEQDESC; + +typedef struct { + + cmsUInt32Number n; + cmsContext ContextID; + cmsPSEQDESC* seq; + +} cmsSEQ; + +CMSAPI cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext ContextID, cmsUInt32Number n); +CMSAPI cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq); +CMSAPI void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq); + +// Dictionaries -------------------------------------------------------------------------------------------------------- + +typedef struct _cmsDICTentry_struct { + + struct _cmsDICTentry_struct* Next; + + cmsMLU *DisplayName; + cmsMLU *DisplayValue; + wchar_t* Name; + wchar_t* Value; + +} cmsDICTentry; + +CMSAPI cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID); +CMSAPI void CMSEXPORT cmsDictFree(cmsHANDLE hDict); +CMSAPI cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict); + +CMSAPI cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue); +CMSAPI const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict); +CMSAPI const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e); + +// Access to Profile data ---------------------------------------------------------------------------------------------- +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID); + +CMSAPI cmsContext CMSEXPORT cmsGetProfileContextID(cmsHPROFILE hProfile); +CMSAPI cmsInt32Number CMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile); +CMSAPI cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Number n); +CMSAPI cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig); + +// Read and write pre-formatted data +CMSAPI void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig); +CMSAPI cmsBool CMSEXPORT cmsWriteTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data); +CMSAPI cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignature sig, cmsTagSignature dest); +CMSAPI cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig); + +// Read and write raw data +CMSAPI cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* Buffer, cmsUInt32Number BufferSize); +CMSAPI cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size); + +// Access header data +#define cmsEmbeddedProfileFalse 0x00000000 +#define cmsEmbeddedProfileTrue 0x00000001 +#define cmsUseAnywhere 0x00000000 +#define cmsUseWithEmbeddedDataOnly 0x00000002 + +CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderFlags(cmsHPROFILE hProfile); +CMSAPI void CMSEXPORT cmsGetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number* Flags); +CMSAPI void CMSEXPORT cmsGetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID); +CMSAPI cmsBool CMSEXPORT cmsGetHeaderCreationDateTime(cmsHPROFILE hProfile, struct tm *Dest); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderRenderingIntent(cmsHPROFILE hProfile); + +CMSAPI void CMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, cmsUInt32Number Flags); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderManufacturer(cmsHPROFILE hProfile); +CMSAPI void CMSEXPORT cmsSetHeaderManufacturer(cmsHPROFILE hProfile, cmsUInt32Number manufacturer); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderCreator(cmsHPROFILE hProfile); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderModel(cmsHPROFILE hProfile); +CMSAPI void CMSEXPORT cmsSetHeaderModel(cmsHPROFILE hProfile, cmsUInt32Number model); +CMSAPI void CMSEXPORT cmsSetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number Flags); +CMSAPI void CMSEXPORT cmsSetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID); +CMSAPI void CMSEXPORT cmsSetHeaderRenderingIntent(cmsHPROFILE hProfile, cmsUInt32Number RenderingIntent); + +CMSAPI cmsColorSpaceSignature + CMSEXPORT cmsGetPCS(cmsHPROFILE hProfile); +CMSAPI void CMSEXPORT cmsSetPCS(cmsHPROFILE hProfile, cmsColorSpaceSignature pcs); +CMSAPI cmsColorSpaceSignature + CMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile); +CMSAPI void CMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, cmsColorSpaceSignature sig); +CMSAPI cmsProfileClassSignature + CMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile); +CMSAPI void CMSEXPORT cmsSetDeviceClass(cmsHPROFILE hProfile, cmsProfileClassSignature sig); +CMSAPI void CMSEXPORT cmsSetProfileVersion(cmsHPROFILE hProfile, cmsFloat64Number Version); +CMSAPI cmsFloat64Number CMSEXPORT cmsGetProfileVersion(cmsHPROFILE hProfile); + +CMSAPI cmsUInt32Number CMSEXPORT cmsGetEncodedICCversion(cmsHPROFILE hProfile); +CMSAPI void CMSEXPORT cmsSetEncodedICCversion(cmsHPROFILE hProfile, cmsUInt32Number Version); + +// How profiles may be used +#define LCMS_USED_AS_INPUT 0 +#define LCMS_USED_AS_OUTPUT 1 +#define LCMS_USED_AS_PROOF 2 + +CMSAPI cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection); +CMSAPI cmsBool CMSEXPORT cmsIsMatrixShaper(cmsHPROFILE hProfile); +CMSAPI cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection); + +// Translate form/to our notation to ICC +CMSAPI cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation); +CMSAPI int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace); + +// Deprecated, use cmsChannelsOfColorSpace instead +CMSAPI cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace); + +// Get number of channels of color space or -1 if color space is not listed/supported +CMSAPI cmsInt32Number CMSEXPORT cmsChannelsOfColorSpace(cmsColorSpaceSignature ColorSpace); + +// Build a suitable formatter for the colorspace of this profile. nBytes=1 means 8 bits, nBytes=2 means 16 bits. +CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat); +CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat); + + +// Localized info +typedef enum { + cmsInfoDescription = 0, + cmsInfoManufacturer = 1, + cmsInfoModel = 2, + cmsInfoCopyright = 3 +} cmsInfoType; + +CMSAPI cmsUInt32Number CMSEXPORT cmsGetProfileInfo(cmsHPROFILE hProfile, cmsInfoType Info, + const char LanguageCode[3], const char CountryCode[3], + wchar_t* Buffer, cmsUInt32Number BufferSize); + +CMSAPI cmsUInt32Number CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile, cmsInfoType Info, + const char LanguageCode[3], const char CountryCode[3], + char* Buffer, cmsUInt32Number BufferSize); + +// IO handlers ---------------------------------------------------------------------------------------------------------- + +typedef struct _cms_io_handler cmsIOHANDLER; + +CMSAPI cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const char* FileName, const char* AccessMode); +CMSAPI cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream); +CMSAPI cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buffer, cmsUInt32Number size, const char* AccessMode); +CMSAPI cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromNULL(cmsContext ContextID); +CMSAPI cmsIOHANDLER* CMSEXPORT cmsGetProfileIOhandler(cmsHPROFILE hProfile); +CMSAPI cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io); + +// MD5 message digest -------------------------------------------------------------------------------------------------- + +CMSAPI cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile); + +// Profile high level functions ------------------------------------------------------------------------------------------ + +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *ICCProfile, const char *sAccess); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromStream(FILE* ICCProfile, const char* sAccess); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromStreamTHR(cmsContext ContextID, FILE* ICCProfile, const char* sAccess); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMem(const void * MemPtr, cmsUInt32Number dwSize); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void * MemPtr, cmsUInt32Number dwSize); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandlerTHR(cmsContext ContextID, cmsIOHANDLER* io); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write); +CMSAPI cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile); + +CMSAPI cmsBool CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName); +CMSAPI cmsBool CMSEXPORT cmsSaveProfileToStream(cmsHPROFILE hProfile, FILE* Stream); +CMSAPI cmsBool CMSEXPORT cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, cmsUInt32Number* BytesNeeded); +CMSAPI cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOHANDLER* io); + +// Predefined virtual profiles ------------------------------------------------------------------------------------------ + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID, + const cmsCIExyY* WhitePoint, + const cmsCIExyYTRIPLE* Primaries, + cmsToneCurve* const TransferFunction[3]); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateRGBProfile(const cmsCIExyY* WhitePoint, + const cmsCIExyYTRIPLE* Primaries, + cmsToneCurve* const TransferFunction[3]); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateGrayProfileTHR(cmsContext ContextID, + const cmsCIExyY* WhitePoint, + const cmsToneCurve* TransferFunction); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateGrayProfile(const cmsCIExyY* WhitePoint, + const cmsToneCurve* TransferFunction); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID, + cmsColorSpaceSignature ColorSpace, + cmsToneCurve* const TransferFunctions[]); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLink(cmsColorSpaceSignature ColorSpace, + cmsToneCurve* const TransferFunctions[]); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID, + cmsColorSpaceSignature ColorSpace, cmsFloat64Number Limit); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLink(cmsColorSpaceSignature ColorSpace, cmsFloat64Number Limit); + + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateLab2ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint); +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateLab2Profile(const cmsCIExyY* WhitePoint); +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateLab4ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint); +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateLab4Profile(const cmsCIExyY* WhitePoint); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateXYZProfileTHR(cmsContext ContextID); +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateXYZProfile(void); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID); +CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, + cmsUInt32Number nLUTPoints, + cmsFloat64Number Bright, + cmsFloat64Number Contrast, + cmsFloat64Number Hue, + cmsFloat64Number Saturation, + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints, + cmsFloat64Number Bright, + cmsFloat64Number Contrast, + cmsFloat64Number Hue, + cmsFloat64Number Saturation, + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest); + +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID); +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfile(void); + +// Converts a transform to a devicelink profile +CMSAPI cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags); + +// Intents ---------------------------------------------------------------------------------------------- + +// ICC Intents +#define INTENT_PERCEPTUAL 0 +#define INTENT_RELATIVE_COLORIMETRIC 1 +#define INTENT_SATURATION 2 +#define INTENT_ABSOLUTE_COLORIMETRIC 3 + +// Non-ICC intents +#define INTENT_PRESERVE_K_ONLY_PERCEPTUAL 10 +#define INTENT_PRESERVE_K_ONLY_RELATIVE_COLORIMETRIC 11 +#define INTENT_PRESERVE_K_ONLY_SATURATION 12 +#define INTENT_PRESERVE_K_PLANE_PERCEPTUAL 13 +#define INTENT_PRESERVE_K_PLANE_RELATIVE_COLORIMETRIC 14 +#define INTENT_PRESERVE_K_PLANE_SATURATION 15 + +// Call with NULL as parameters to get the intent count +CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions); + +// Flags + +#define cmsFLAGS_NOCACHE 0x0040 // Inhibit 1-pixel cache +#define cmsFLAGS_NOOPTIMIZE 0x0100 // Inhibit optimizations +#define cmsFLAGS_NULLTRANSFORM 0x0200 // Don't transform anyway + +// Proofing flags +#define cmsFLAGS_GAMUTCHECK 0x1000 // Out of Gamut alarm +#define cmsFLAGS_SOFTPROOFING 0x4000 // Do softproofing + +// Misc +#define cmsFLAGS_BLACKPOINTCOMPENSATION 0x2000 +#define cmsFLAGS_NOWHITEONWHITEFIXUP 0x0004 // Don't fix scum dot +#define cmsFLAGS_HIGHRESPRECALC 0x0400 // Use more memory to give better accuracy +#define cmsFLAGS_LOWRESPRECALC 0x0800 // Use less memory to minimize resources + +// For devicelink creation +#define cmsFLAGS_8BITS_DEVICELINK 0x0008 // Create 8 bits devicelinks +#define cmsFLAGS_GUESSDEVICECLASS 0x0020 // Guess device class (for transform2devicelink) +#define cmsFLAGS_KEEP_SEQUENCE 0x0080 // Keep profile sequence for devicelink creation + +// Specific to a particular optimizations +#define cmsFLAGS_FORCE_CLUT 0x0002 // Force CLUT optimization +#define cmsFLAGS_CLUT_POST_LINEARIZATION 0x0001 // create postlinearization tables if possible +#define cmsFLAGS_CLUT_PRE_LINEARIZATION 0x0010 // create prelinearization tables if possible + +// Specific to unbounded mode +#define cmsFLAGS_NONEGATIVES 0x8000 // Prevent negative numbers in floating point transforms + +// Copy alpha channels when transforming +#define cmsFLAGS_COPY_ALPHA 0x04000000 // Alpha channels are copied on cmsDoTransform() + +// Fine-tune control over number of gridpoints +#define cmsFLAGS_GRIDPOINTS(n) (((n) & 0xFF) << 16) + +// CRD special +#define cmsFLAGS_NODEFAULTRESOURCEDEF 0x01000000 + +// Transforms --------------------------------------------------------------------------------------------------- + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID, + cmsHPROFILE Input, + cmsUInt32Number InputFormat, + cmsHPROFILE Output, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags); + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransform(cmsHPROFILE Input, + cmsUInt32Number InputFormat, + cmsHPROFILE Output, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags); + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateProofingTransformTHR(cmsContext ContextID, + cmsHPROFILE Input, + cmsUInt32Number InputFormat, + cmsHPROFILE Output, + cmsUInt32Number OutputFormat, + cmsHPROFILE Proofing, + cmsUInt32Number Intent, + cmsUInt32Number ProofingIntent, + cmsUInt32Number dwFlags); + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateProofingTransform(cmsHPROFILE Input, + cmsUInt32Number InputFormat, + cmsHPROFILE Output, + cmsUInt32Number OutputFormat, + cmsHPROFILE Proofing, + cmsUInt32Number Intent, + cmsUInt32Number ProofingIntent, + cmsUInt32Number dwFlags); + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransformTHR(cmsContext ContextID, + cmsHPROFILE hProfiles[], + cmsUInt32Number nProfiles, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags); + + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], + cmsUInt32Number nProfiles, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags); + + +CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID, + cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsUInt32Number Intents[], + cmsFloat64Number AdaptationStates[], + cmsHPROFILE hGamutProfile, + cmsUInt32Number nGamutPCSposition, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + cmsUInt32Number dwFlags); + +CMSAPI void CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform); + +CMSAPI void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform, + const void * InputBuffer, + void * OutputBuffer, + cmsUInt32Number Size); + +CMSAPI void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform, // Deprecated + const void * InputBuffer, + void * OutputBuffer, + cmsUInt32Number Size, + cmsUInt32Number Stride); + +CMSAPI void CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM Transform, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + cmsUInt32Number BytesPerLineIn, + cmsUInt32Number BytesPerLineOut, + cmsUInt32Number BytesPerPlaneIn, + cmsUInt32Number BytesPerPlaneOut); + + +CMSAPI void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]); +CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]); + + +CMSAPI void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID, + const cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]); +CMSAPI void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID, + cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]); + + + +// Adaptation state for absolute colorimetric intent +CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d); +CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d); + + + +// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed +CMSAPI cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform); + +// Grab the input/output formats +CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform); + +// For backwards compatibility +CMSAPI cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat); + + + +// PostScript ColorRenderingDictionary and ColorSpaceArray ---------------------------------------------------- + +typedef enum { cmsPS_RESOURCE_CSA, cmsPS_RESOURCE_CRD } cmsPSResourceType; + +// lcms2 unified method to access postscript color resources +CMSAPI cmsUInt32Number CMSEXPORT cmsGetPostScriptColorResource(cmsContext ContextID, + cmsPSResourceType Type, + cmsHPROFILE hProfile, + cmsUInt32Number Intent, + cmsUInt32Number dwFlags, + cmsIOHANDLER* io); + +CMSAPI cmsUInt32Number CMSEXPORT cmsGetPostScriptCSA(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags, void* Buffer, cmsUInt32Number dwBufferLen); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetPostScriptCRD(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags, void* Buffer, cmsUInt32Number dwBufferLen); + + +// IT8.7 / CGATS.17-200x handling ----------------------------------------------------------------------------- + +CMSAPI cmsHANDLE CMSEXPORT cmsIT8Alloc(cmsContext ContextID); +CMSAPI void CMSEXPORT cmsIT8Free(cmsHANDLE hIT8); + +// Tables +CMSAPI cmsUInt32Number CMSEXPORT cmsIT8TableCount(cmsHANDLE hIT8); +CMSAPI cmsInt32Number CMSEXPORT cmsIT8SetTable(cmsHANDLE hIT8, cmsUInt32Number nTable); + +// Persistence +CMSAPI cmsHANDLE CMSEXPORT cmsIT8LoadFromFile(cmsContext ContextID, const char* cFileName); +CMSAPI cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len); +// CMSAPI cmsHANDLE CMSEXPORT cmsIT8LoadFromIOhandler(cmsContext ContextID, cmsIOHANDLER* io); + +CMSAPI cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName); +CMSAPI cmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number* BytesNeeded); + +// Properties +CMSAPI const char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8); +CMSAPI cmsBool CMSEXPORT cmsIT8SetSheetType(cmsHANDLE hIT8, const char* Type); + +CMSAPI cmsBool CMSEXPORT cmsIT8SetComment(cmsHANDLE hIT8, const char* cComment); + +CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* cProp, const char *Str); +CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val); +CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val); +CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer); +CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyUncooked(cmsHANDLE hIT8, const char* Key, const char* Buffer); + + +CMSAPI const char* CMSEXPORT cmsIT8GetProperty(cmsHANDLE hIT8, const char* cProp); +CMSAPI cmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp); +CMSAPI const char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey); +CMSAPI cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyNames); +CMSAPI cmsUInt32Number CMSEXPORT cmsIT8EnumPropertyMulti(cmsHANDLE hIT8, const char* cProp, const char ***SubpropertyNames); + +// Datasets +CMSAPI const char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col); +CMSAPI cmsFloat64Number CMSEXPORT cmsIT8GetDataRowColDbl(cmsHANDLE hIT8, int row, int col); + +CMSAPI cmsBool CMSEXPORT cmsIT8SetDataRowCol(cmsHANDLE hIT8, int row, int col, + const char* Val); + +CMSAPI cmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, + cmsFloat64Number Val); + +CMSAPI const char* CMSEXPORT cmsIT8GetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample); + + +CMSAPI cmsFloat64Number CMSEXPORT cmsIT8GetDataDbl(cmsHANDLE hIT8, const char* cPatch, const char* cSample); + +CMSAPI cmsBool CMSEXPORT cmsIT8SetData(cmsHANDLE hIT8, const char* cPatch, + const char* cSample, + const char *Val); + +CMSAPI cmsBool CMSEXPORT cmsIT8SetDataDbl(cmsHANDLE hIT8, const char* cPatch, + const char* cSample, + cmsFloat64Number Val); + +CMSAPI int CMSEXPORT cmsIT8FindDataFormat(cmsHANDLE hIT8, const char* cSample); +CMSAPI cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE hIT8, int n, const char *Sample); +CMSAPI int CMSEXPORT cmsIT8EnumDataFormat(cmsHANDLE hIT8, char ***SampleNames); + +CMSAPI const char* CMSEXPORT cmsIT8GetPatchName(cmsHANDLE hIT8, int nPatch, char* buffer); +CMSAPI int CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch); + +// The LABEL extension +CMSAPI int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType); + +CMSAPI cmsBool CMSEXPORT cmsIT8SetIndexColumn(cmsHANDLE hIT8, const char* cSample); + +// Formatter for double +CMSAPI void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter); + +// Gamut boundary description routines ------------------------------------------------------------------------------ + +CMSAPI cmsHANDLE CMSEXPORT cmsGBDAlloc(cmsContext ContextID); +CMSAPI void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD); +CMSAPI cmsBool CMSEXPORT cmsGDBAddPoint(cmsHANDLE hGBD, const cmsCIELab* Lab); +CMSAPI cmsBool CMSEXPORT cmsGDBCompute(cmsHANDLE hGDB, cmsUInt32Number dwFlags); +CMSAPI cmsBool CMSEXPORT cmsGDBCheckPoint(cmsHANDLE hGBD, const cmsCIELab* Lab); + +// Feature detection ---------------------------------------------------------------------------------------------- + +// Estimate the black point +CMSAPI cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags); +CMSAPI cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags); + +// Estimate total area coverage +CMSAPI cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile); + +// Estimate gamma space, always positive. Returns -1 on error. +CMSAPI cmsFloat64Number CMSEXPORT cmsDetectRGBProfileGamma(cmsHPROFILE hProfile, cmsFloat64Number threshold); + +// Poor man's gamut mapping +CMSAPI cmsBool CMSEXPORT cmsDesaturateLab(cmsCIELab* Lab, + double amax, double amin, + double bmax, double bmin); + +#ifndef CMS_USE_CPP_API +# ifdef __cplusplus + } +# endif +#endif + +#define _lcms2_H +#endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/lcms2_internal.h openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/lcms2_internal.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/lcms2_internal.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/lcms2_internal.h 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1180 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// + +#ifndef _lcms_internal_H + +// Include plug-in foundation +#ifndef _lcms_plugin_H +# include "lcms2_plugin.h" +#endif + +// ctype is part of C99 as per 7.1.2 +#include + +// assert macro is part of C99 as per 7.2 +#include + +// Some needed constants +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +#ifndef M_LOG10E +# define M_LOG10E 0.434294481903251827651 +#endif + +// BorlandC 5.5, VC2003 are broken on that +#if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER < 1400)) // 1400 == VC++ 8.0 +#define sinf(x) (float)sin((float)x) +#define sqrtf(x) (float)sqrt((float)x) +#endif + + +// Alignment of ICC file format uses 4 bytes (cmsUInt32Number) +#define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1)) + +// Alignment to memory pointer + +// (Ultra)SPARC with gcc requires ptr alignment of 8 bytes +// even though sizeof(void *) is only four: for greatest flexibility +// allow the build to specify ptr alignment. +#ifndef CMS_PTR_ALIGNMENT +# define CMS_PTR_ALIGNMENT sizeof(void *) +#endif + +#define _cmsALIGNMEM(x) (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1)) + +// Maximum encodeable values in floating point +#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0) +#define MIN_ENCODEABLE_ab2 (-128.0) +#define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0) +#define MIN_ENCODEABLE_ab4 (-128.0) +#define MAX_ENCODEABLE_ab4 (127.0) + +// Maximum of channels for internal pipeline evaluation +#define MAX_STAGE_CHANNELS 128 + +// Unused parameter warning suppression +#define cmsUNUSED_PARAMETER(x) ((void)x) + +// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). +// unfortunately VisualC++ does not conform that +#if defined(_MSC_VER) || defined(__BORLANDC__) +# define cmsINLINE __inline +#else +# define cmsINLINE static inline +#endif + +// Allow signed overflow, we know this is harmless in this particular context +#if defined(__clang__) +# define CMS_NO_SANITIZE __attribute__((no_sanitize("signed-integer-overflow"))) +#else +# define CMS_NO_SANITIZE +#endif + +// Other replacement functions +#ifdef _MSC_VER +# ifndef snprintf +# define snprintf _snprintf +# endif +# ifndef vsnprintf +# define vsnprintf _vsnprintf +# endif + +/// Properly define some macros to accommodate +/// older MSVC versions. +# if defined(_MSC_VER) && _MSC_VER <= 1700 + #include + #define isnan _isnan + #define isinf(x) (!_finite((x))) +# endif + +#if !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L) + #if !defined(isinf) + #define isinf(x) (!finite((x))) + #endif +#endif + + +#endif + +// A fast way to convert from/to 16 <-> 8 bits +#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb)) +#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU) + +// Code analysis is broken on asserts +#ifdef _MSC_VER +# if (_MSC_VER >= 1500) +# define _cmsAssert(a) { assert((a)); __analysis_assume((a)); } +# else +# define _cmsAssert(a) assert((a)) +# endif +#else +# define _cmsAssert(a) assert((a)) +#endif + +//--------------------------------------------------------------------------------- + +// Determinant lower than that are assumed zero (used on matrix invert) +#define MATRIX_DET_TOLERANCE 0.0001 + +//--------------------------------------------------------------------------------- + +// Fixed point +#define FIXED_TO_INT(x) ((x)>>16) +#define FIXED_REST_TO_INT(x) ((x)&0xFFFFU) +#define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16) + +cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); } +cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); } + +// ----------------------------------------------------------------------------------------------------------- + +// Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon +// note than this only works in the range ..-32767...+32767 because +// mantissa is interpreted as 15.16 fixed point. +// The union is to avoid pointer aliasing overoptimization. +cmsINLINE int _cmsQuickFloor(cmsFloat64Number val) +{ +#ifdef CMS_DONT_USE_FAST_FLOOR + return (int) floor(val); +#else + const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor + union { + cmsFloat64Number val; + int halves[2]; + } temp; + + temp.val = val + _lcms_double2fixmagic; + +#ifdef CMS_USE_BIG_ENDIAN + return temp.halves[1] >> 16; +#else + return temp.halves[0] >> 16; +#endif +#endif +} + +// Fast floor restricted to 0..65535.0 +cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d) +{ + return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U; +} + +// Floor to word, taking care of saturation +cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d) +{ + d += 0.5; + if (d <= 0) return 0; + if (d >= 65535.0) return 0xffff; + + return _cmsQuickFloorWord(d); +} + +// Test bed entry points--------------------------------------------------------------- +#define CMSCHECKPOINT CMSAPI + +// Pthread support -------------------------------------------------------------------- +#ifndef CMS_NO_PTHREADS + +// This is the threading support. Unfortunately, it has to be platform-dependent because +// windows does not support pthreads. +#ifdef CMS_IS_WINDOWS_ + +#define WIN32_LEAN_AND_MEAN 1 +#include + + +// The locking scheme in LCMS requires a single 'top level' mutex +// to work. This is actually implemented on Windows as a +// CriticalSection, because they are lighter weight. With +// pthreads, this is statically inited. Unfortunately, windows +// can't officially statically init critical sections. +// +// We can work around this in 2 ways. +// +// 1) We can use a proper mutex purely to protect the init +// of the CriticalSection. This in turns requires us to protect +// the Mutex creation, which we can do using the snappily +// named InterlockedCompareExchangePointer API (present on +// windows XP and above). +// +// 2) In cases where we want to work on pre-Windows XP, we +// can use an even more horrible hack described below. +// +// So why wouldn't we always use 2)? Because not calling +// the init function for a critical section means it fails +// testing with ApplicationVerifier (and presumably similar +// tools). +// +// We therefore default to 1, and people who want to be able +// to run on pre-Windows XP boxes can build with: +// CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +// defined. This is automatically set for builds using +// versions of MSVC that don't have this API available. +// +// From: http://locklessinc.com/articles/pthreads_on_windows/ +// The pthreads API has an initialization macro that has no correspondence to anything in +// the windows API. By investigating the internal definition of the critical section type, +// one may work out how to initialize one without calling InitializeCriticalSection(). +// The trick here is that InitializeCriticalSection() is not allowed to fail. It tries +// to allocate a critical section debug object, but if no memory is available, it sets +// the pointer to a specific value. (One would expect that value to be NULL, but it is +// actually (void *)-1 for some reason.) Thus we can use this special value for that +// pointer, and the critical section code will work. + +// The other important part of the critical section type to initialize is the number +// of waiters. This controls whether or not the mutex is locked. Fortunately, this +// part of the critical section is unlikely to change. Apparently, many programs +// already test critical sections to see if they are locked using this value, so +// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical +// section, even when they changed the underlying algorithm to be more scalable. +// The final parts of the critical section object are unimportant, and can be set +// to zero for their defaults. This yields to an initialization macro: + +typedef CRITICAL_SECTION _cmsMutex; + +#ifdef _MSC_VER +# if (_MSC_VER >= 1800) +# pragma warning(disable : 26135) +# endif +#endif + +#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +// If we are building with a version of MSVC smaller +// than 1400 (i.e. before VS2005) then we don't have +// the InterlockedCompareExchangePointer API, so use +// the old version. +# ifdef _MSC_VER +# if _MSC_VER < 1400 +# define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +# endif +# endif +#endif + +#ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0} +#else +# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0} +#endif + +cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) +{ + EnterCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) +{ + LeaveCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) +{ + InitializeCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) +{ + DeleteCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) +{ + EnterCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) +{ + LeaveCriticalSection(m); + return 0; +} + +#else + +// Rest of the wide world +#include + +#define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +typedef pthread_mutex_t _cmsMutex; + + +cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) +{ + return pthread_mutex_lock(m); +} + +cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) +{ + return pthread_mutex_unlock(m); +} + +cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) +{ + return pthread_mutex_init(m, NULL); +} + +cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) +{ + return pthread_mutex_destroy(m); +} + +cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) +{ + return pthread_mutex_lock(m); +} + +cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) +{ + return pthread_mutex_unlock(m); +} + +#endif +#else + +#define CMS_MUTEX_INITIALIZER 0 +typedef int _cmsMutex; + + +cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) +{ + cmsUNUSED_PARAMETER(m); + return 0; +} + +cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) +{ + cmsUNUSED_PARAMETER(m); + return 0; +} + +cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) +{ + cmsUNUSED_PARAMETER(m); + return 0; +} + +cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) +{ + cmsUNUSED_PARAMETER(m); + return 0; +} + +cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) +{ + cmsUNUSED_PARAMETER(m); + return 0; +} + +cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) +{ + cmsUNUSED_PARAMETER(m); + return 0; +} +#endif + +// Plug-In registration --------------------------------------------------------------- + +// Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once. +void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size); + +// Memory management +cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Interpolation +cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Parametric curves +cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Formatters management +cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Tag type management +cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Tag management +cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Intent management +cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Multi Process elements +cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Optimization +cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Transform +cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Mutex +cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// Paralellization +cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + +// --------------------------------------------------------------------------------------------------------- + +// Suballocators. +typedef struct _cmsSubAllocator_chunk_st { + + cmsUInt8Number* Block; + cmsUInt32Number BlockSize; + cmsUInt32Number Used; + + struct _cmsSubAllocator_chunk_st* next; + +} _cmsSubAllocator_chunk; + + +typedef struct { + + cmsContext ContextID; + _cmsSubAllocator_chunk* h; + +} _cmsSubAllocator; + + +_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial); +void _cmsSubAllocDestroy(_cmsSubAllocator* s); +void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size); +void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size); + +// ---------------------------------------------------------------------------------- + +// The context clients. +typedef enum { + + UserPtr, // User-defined pointer + Logger, + AlarmCodesContext, + AdaptationStateContext, + MemPlugin, + InterpPlugin, + CurvesPlugin, + FormattersPlugin, + TagTypePlugin, + TagPlugin, + IntentPlugin, + MPEPlugin, + OptimizationPlugin, + TransformPlugin, + MutexPlugin, + ParallelizationPlugin, + + // Last in list + MemoryClientMax + +} _cmsMemoryClient; + + +// Container for memory management plug-in. +typedef struct { + + _cmsMallocFnPtrType MallocPtr; + _cmsMalloZerocFnPtrType MallocZeroPtr; + _cmsFreeFnPtrType FreePtr; + _cmsReallocFnPtrType ReallocPtr; + _cmsCallocFnPtrType CallocPtr; + _cmsDupFnPtrType DupPtr; + +} _cmsMemPluginChunkType; + +// Copy memory management function pointers from plug-in to chunk, taking care of missing routines +void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr); + +// Internal structure for context +struct _cmsContext_struct { + + struct _cmsContext_struct* Next; // Points to next context in the new style + _cmsSubAllocator* MemPool; // The memory pool that stores context data + + void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator. + // If NULL, then it reverts to global Context0 + + _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overridden +}; + +// Returns a pointer to a valid context structure, including the global one if id is zero. +// Verifies the magic number. +struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID); + +// Returns the block assigned to the specific zone. +void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc); + + +// Chunks of context memory by plug-in client ------------------------------------------------------- + +// Those structures encapsulates all variables needed by the several context clients (mostly plug-ins) + +// Container for error logger -- not a plug-in +typedef struct { + + cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback + +} _cmsLogErrorChunkType; + +// The global Context0 storage for error logger +extern _cmsLogErrorChunkType _cmsLogErrorChunk; + +// Allocate and init error logger container. +void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for alarm codes -- not a plug-in +typedef struct { + + cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]; + +} _cmsAlarmCodesChunkType; + +// The global Context0 storage for alarm codes +extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk; + +// Allocate and init alarm codes container. +void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for adaptation state -- not a plug-in +typedef struct { + + cmsFloat64Number AdaptationState; + +} _cmsAdaptationStateChunkType; + +// The global Context0 storage for adaptation state +extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk; + +// Allocate and init adaptation state container. +void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + + +// The global Context0 storage for memory management +extern _cmsMemPluginChunkType _cmsMemPluginChunk; + +// Allocate and init memory management container. +void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for interpolation plug-in +typedef struct { + + cmsInterpFnFactory Interpolators; + +} _cmsInterpPluginChunkType; + +// The global Context0 storage for interpolation plug-in +extern _cmsInterpPluginChunkType _cmsInterpPluginChunk; + +// Allocate and init interpolation container. +void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for parametric curves plug-in +typedef struct { + + struct _cmsParametricCurvesCollection_st* ParametricCurves; + +} _cmsCurvesPluginChunkType; + +// The global Context0 storage for tone curves plug-in +extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk; + +// Allocate and init parametric curves container. +void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for formatters plug-in +typedef struct { + + struct _cms_formatters_factory_list* FactoryList; + +} _cmsFormattersPluginChunkType; + +// The global Context0 storage for formatters plug-in +extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk; + +// Allocate and init formatters container. +void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// This chunk type is shared by TagType plug-in and MPE Plug-in +typedef struct { + + struct _cmsTagTypeLinkedList_st* TagTypes; + +} _cmsTagTypePluginChunkType; + + +// The global Context0 storage for tag types plug-in +extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk; + + +// The global Context0 storage for mult process elements plug-in +extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk; + +// Allocate and init Tag types container. +void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); +// Allocate and init MPE container. +void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); +// Container for tag plug-in +typedef struct { + + struct _cmsTagLinkedList_st* Tag; + +} _cmsTagPluginChunkType; + + +// The global Context0 storage for tag plug-in +extern _cmsTagPluginChunkType _cmsTagPluginChunk; + +// Allocate and init Tag container. +void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for intents plug-in +typedef struct { + + struct _cms_intents_list* Intents; + +} _cmsIntentsPluginChunkType; + + +// The global Context0 storage for intents plug-in +extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk; + +// Allocate and init intents container. +void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for optimization plug-in +typedef struct { + + struct _cmsOptimizationCollection_st* OptimizationCollection; + +} _cmsOptimizationPluginChunkType; + + +// The global Context0 storage for optimizers plug-in +extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk; + +// Allocate and init optimizers container. +void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for transform plug-in +typedef struct { + + struct _cmsTransformCollection_st* TransformCollection; + +} _cmsTransformPluginChunkType; + +// The global Context0 storage for full-transform replacement plug-in +extern _cmsTransformPluginChunkType _cmsTransformPluginChunk; + +// Allocate and init transform container. +void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for mutex plug-in +typedef struct { + + _cmsCreateMutexFnPtrType CreateMutexPtr; + _cmsDestroyMutexFnPtrType DestroyMutexPtr; + _cmsLockMutexFnPtrType LockMutexPtr; + _cmsUnlockMutexFnPtrType UnlockMutexPtr; + +} _cmsMutexPluginChunkType; + +// The global Context0 storage for mutex plug-in +extern _cmsMutexPluginChunkType _cmsMutexPluginChunk; + +// Allocate and init mutex container. +void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for parallelization plug-in +typedef struct { + + cmsInt32Number MaxWorkers; // Number of workers to do as maximum + cmsInt32Number WorkerFlags; // reserved + _cmsTransform2Fn SchedulerFn; // callback to setup functions + +} _cmsParallelizationPluginChunkType; + +// The global Context0 storage for parallelization plug-in +extern _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk; + +// Allocate parallelization container. +void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + + + +// ---------------------------------------------------------------------------------- +// MLU internal representation +typedef struct { + + cmsUInt16Number Language; + cmsUInt16Number Country; + + cmsUInt32Number StrW; // Offset to current unicode string + cmsUInt32Number Len; // Length in bytes + +} _cmsMLUentry; + +struct _cms_MLU_struct { + + cmsContext ContextID; + + // The directory + cmsUInt32Number AllocatedEntries; + cmsUInt32Number UsedEntries; + _cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool + + // The Pool + cmsUInt32Number PoolSize; // The maximum allocated size + cmsUInt32Number PoolUsed; // The used size + void* MemPool; // Pointer to begin of memory pool +}; + +// Named color list internal representation +typedef struct { + + char Name[cmsMAX_PATH]; + cmsUInt16Number PCS[3]; + cmsUInt16Number DeviceColorant[cmsMAXCHANNELS]; + +} _cmsNAMEDCOLOR; + +struct _cms_NAMEDCOLORLIST_struct { + + cmsUInt32Number nColors; + cmsUInt32Number Allocated; + cmsUInt32Number ColorantCount; + + char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most + char Suffix[33]; + + _cmsNAMEDCOLOR* List; + + cmsContext ContextID; +}; + + +// ---------------------------------------------------------------------------------- + +// This is the internal struct holding profile details. + +// Maximum supported tags in a profile +#define MAX_TABLE_TAG 100 + +typedef struct _cms_iccprofile_struct { + + // I/O handler + cmsIOHANDLER* IOhandler; + + // The thread ID + cmsContext ContextID; + + // Creation time + struct tm Created; + + // Only most important items found in ICC profiles + cmsUInt32Number Version; + cmsProfileClassSignature DeviceClass; + cmsColorSpaceSignature ColorSpace; + cmsColorSpaceSignature PCS; + cmsUInt32Number RenderingIntent; + + cmsUInt32Number flags; + cmsUInt32Number manufacturer, model; + cmsUInt64Number attributes; + cmsUInt32Number creator; + + cmsProfileID ProfileID; + + // Dictionary + cmsUInt32Number TagCount; + cmsTagSignature TagNames[MAX_TABLE_TAG]; + cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to which is linked (0=none) + cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk + cmsUInt32Number TagOffsets[MAX_TABLE_TAG]; + cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked + void * TagPtrs[MAX_TABLE_TAG]; + cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types + // depending on profile version, so we keep track of the + // type handler for each tag in the list. + // Special + cmsBool IsWrite; + + // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin + void * UsrMutex; + +} _cmsICCPROFILE; + +// IO helpers for profiles +cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc); +cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace); +int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks); + +// Tag types +cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig); +cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig); +cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig); + +// Error logging --------------------------------------------------------------------------------------------------------- + +void _cmsTagSignature2String(char String[5], cmsTagSignature sig); + +// Interpolation --------------------------------------------------------------------------------------------------------- + +CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags); +cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags); +CMSCHECKPOINT void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p); +cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p); + +// Curves ---------------------------------------------------------------------------------------------------------------- + +// This struct holds information about a segment, plus a pointer to the function that implements the evaluation. +// In the case of table-based, Eval pointer is set to NULL + +// The gamma function main structure +struct _cms_curve_struct { + + cmsInterpParams* InterpParams; // Private optimizations for interpolation + + cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables + cmsCurveSegment* Segments; // The segments + cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments + + cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment) + + // 16 bit Table-based representation follows + cmsUInt32Number nEntries; // Number of table elements + cmsUInt16Number* Table16; // The table itself. +}; + + +// Pipelines & Stages --------------------------------------------------------------------------------------------- + +// A single stage +struct _cmsStage_struct { + + cmsContext ContextID; + + cmsStageSignature Type; // Identifies the stage + cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations) + + cmsUInt32Number InputChannels; // Input channels -- for optimization purposes + cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes + + _cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point) + _cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage + _cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free + + // A generic pointer to whatever memory needed by the stage + void* Data; + + // Maintains linked list (used internally) + struct _cmsStage_struct* Next; +}; + + +// Special Stages (cannot be saved) +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID); +cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID); +cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan); +cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID); +cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID); +cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID); +cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID); +cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels); + + +// For curve set only +cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe); + +struct _cmsPipeline_struct { + + cmsStage* Elements; // Points to elements chain + cmsUInt32Number InputChannels, OutputChannels; + + // Data & evaluators + void *Data; + + _cmsPipelineEval16Fn Eval16Fn; + _cmsPipelineEvalFloatFn EvalFloatFn; + _cmsFreeUserDataFn FreeDataFn; + _cmsDupUserDataFn DupDataFn; + + cmsContext ContextID; // Environment + + cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible +}; + +// LUT reading & creation ------------------------------------------------------------------------------------------- + +// Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy +// of the LUTS, since ownership of original is up to the profile. The user should free allocated resources. + +CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); +CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); +CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); + +// Special values +cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile); +cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile); + +// Profile linker -------------------------------------------------------------------------------------------------- + +// Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point +// compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS +// after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1) +cmsPipeline* _cmsLinkProfiles(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number TheIntents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + +// Sequence -------------------------------------------------------------------------------------------------------- + +cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile); +cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq); +cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]); + + +// LUT optimization ------------------------------------------------------------------------------------------------ + +CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples); + +CMSAPI cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); + +cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, + cmsUInt16Number **White, + cmsUInt16Number **Black, + cmsUInt32Number *nOutputs); + +CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID, + cmsPipeline** Lut, + cmsUInt32Number Intent, + cmsUInt32Number* InputFormat, + cmsUInt32Number* OutputFormat, + cmsUInt32Number* dwFlags ); + + +// Hi level LUT building ---------------------------------------------------------------------------------------------- + +cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID, + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsUInt32Number Intents[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number nGamutPCSposition, + cmsHPROFILE hGamut); + + +// Formatters ------------------------------------------------------------------------------------------------------------ + +#define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format + +cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type); +cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type); + +CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID, + cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags); + + +#ifndef CMS_NO_HALF_SUPPORT + +// Half float +CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h); +CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt); + +#endif + +// Transform logic ------------------------------------------------------------------------------------------------------ + +struct _cmstransform_struct; + +typedef struct { + + // 1-pixel cache (16 bits only) + cmsUInt16Number CacheIn[cmsMAXCHANNELS]; + cmsUInt16Number CacheOut[cmsMAXCHANNELS]; + +} _cmsCACHE; + + + +// Transformation +typedef struct _cmstransform_struct { + + cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference + + // Points to transform code + _cmsTransform2Fn xform; + + // Formatters, cannot be embedded into LUT because cache + cmsFormatter16 FromInput; + cmsFormatter16 ToOutput; + + cmsFormatterFloat FromInputFloat; + cmsFormatterFloat ToOutputFloat; + + // 1-pixel cache seed for zero as input (16 bits, read only) + _cmsCACHE Cache; + + // A Pipeline holding the full (optimized) transform + cmsPipeline* Lut; + + // A Pipeline holding the gamut check. It goes from the input space to bilevel + cmsPipeline* GamutCheck; + + // Colorant tables + cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table + cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK) + + // Informational only + cmsColorSpaceSignature EntryColorSpace; + cmsColorSpaceSignature ExitColorSpace; + + // White points (informative only) + cmsCIEXYZ EntryWhitePoint; + cmsCIEXYZ ExitWhitePoint; + + // Profiles used to create the transform + cmsSEQ* Sequence; + + cmsUInt32Number dwOriginalFlags; + cmsFloat64Number AdaptationState; + + // The intent of this transform. That is usually the last intent in the profilechain, but may differ + cmsUInt32Number RenderingIntent; + + // An id that uniquely identifies the running context. May be null. + cmsContext ContextID; + + // A user-defined pointer that can be used to store data for transform plug-ins + void* UserData; + _cmsFreeUserDataFn FreeUserData; + + // A way to provide backwards compatibility with full xform plugins + _cmsTransformFn OldXform; + + // A one-worker transform entry for parallelization + _cmsTransform2Fn Worker; + cmsInt32Number MaxWorkers; + cmsUInt32Number WorkerFlags; + +} _cmsTRANSFORM; + +// Copies extra channels from input to output if the original flags in the transform structure +// instructs to do so. This function is called on all standard transform functions. +void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride); + +// ----------------------------------------------------------------------------------------------------------------------- + +cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + + +cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID, + cmsUInt32Number nPoints, + cmsUInt32Number nProfiles, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + +cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll); + +cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries); + + +// thread-safe gettime +cmsBool _cmsGetTime(struct tm* ptr_time); + +#define _lcms_internal_H +#endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/lcms2_plugin.h openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/lcms2_plugin.h --- openjdk-17-17.0.7+7~us1/src/java.desktop/share/native/liblcms/lcms2_plugin.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/share/native/liblcms/lcms2_plugin.h 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,729 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This file is available under and governed by the GNU General Public +// License version 2 only, as published by the Free Software Foundation. +// However, the following notice accompanied the original version of this +// file: +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2023 Marti Maria Saguer +// +// 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. +// +//--------------------------------------------------------------------------------- +// +// This is the plug-in header file. Normal LittleCMS clients should not use it. +// It is provided for plug-in writers that may want to access the support +// functions to do low level operations. All plug-in related structures +// are defined here. Including this file forces to include the standard API too. + +#ifndef _lcms_plugin_H + +// Deal with Microsoft's attempt at deprecating C standard runtime functions +#ifdef _MSC_VER +# if (_MSC_VER >= 1400) +# ifndef _CRT_SECURE_NO_DEPRECATE +# define _CRT_SECURE_NO_DEPRECATE +# endif +# ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +# endif +# endif +#endif + +#ifndef _lcms2_H +#include "lcms2.h" +#endif + +// We need some standard C functions. +#include +#include +#include +#include +#include + + +#ifndef CMS_USE_CPP_API +# ifdef __cplusplus +extern "C" { +# endif +#endif + +// Vector & Matrix operations ----------------------------------------------------------------------- + +// Axis of the matrix/array. No specific meaning at all. +#define VX 0 +#define VY 1 +#define VZ 2 + +// Vectors +typedef struct { + cmsFloat64Number n[3]; + + } cmsVEC3; + +// 3x3 Matrix +typedef struct { + cmsVEC3 v[3]; + + } cmsMAT3; + +CMSAPI void CMSEXPORT _cmsVEC3init(cmsVEC3* r, cmsFloat64Number x, cmsFloat64Number y, cmsFloat64Number z); +CMSAPI void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b); +CMSAPI void CMSEXPORT _cmsVEC3cross(cmsVEC3* r, const cmsVEC3* u, const cmsVEC3* v); +CMSAPI cmsFloat64Number CMSEXPORT _cmsVEC3dot(const cmsVEC3* u, const cmsVEC3* v); +CMSAPI cmsFloat64Number CMSEXPORT _cmsVEC3length(const cmsVEC3* a); +CMSAPI cmsFloat64Number CMSEXPORT _cmsVEC3distance(const cmsVEC3* a, const cmsVEC3* b); + +CMSAPI void CMSEXPORT _cmsMAT3identity(cmsMAT3* a); +CMSAPI cmsBool CMSEXPORT _cmsMAT3isIdentity(const cmsMAT3* a); +CMSAPI void CMSEXPORT _cmsMAT3per(cmsMAT3* r, const cmsMAT3* a, const cmsMAT3* b); +CMSAPI cmsBool CMSEXPORT _cmsMAT3inverse(const cmsMAT3* a, cmsMAT3* b); +CMSAPI cmsBool CMSEXPORT _cmsMAT3solve(cmsVEC3* x, cmsMAT3* a, cmsVEC3* b); +CMSAPI void CMSEXPORT _cmsMAT3eval(cmsVEC3* r, const cmsMAT3* a, const cmsVEC3* v); + + +// MD5 low level ------------------------------------------------------------------------------------- + +CMSAPI cmsHANDLE CMSEXPORT cmsMD5alloc(cmsContext ContextID); +CMSAPI void CMSEXPORT cmsMD5add(cmsHANDLE Handle, const cmsUInt8Number* buf, cmsUInt32Number len); +CMSAPI void CMSEXPORT cmsMD5finish(cmsProfileID* ProfileID, cmsHANDLE Handle); + +// Error logging ------------------------------------------------------------------------------------- + +CMSAPI void CMSEXPORT cmsSignalError(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *ErrorText, ...); + +// Memory management ---------------------------------------------------------------------------------- + +CMSAPI void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size); +CMSAPI void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size); +CMSAPI void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size); +CMSAPI void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize); +CMSAPI void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr); +CMSAPI void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size); + +// I/O handler ---------------------------------------------------------------------------------- + +struct _cms_io_handler { + + void* stream; // Associated stream, which is implemented differently depending on media. + + cmsContext ContextID; + cmsUInt32Number UsedSpace; + cmsUInt32Number ReportedSize; + char PhysicalFile[cmsMAX_PATH]; + + cmsUInt32Number (* Read)(struct _cms_io_handler* iohandler, void *Buffer, + cmsUInt32Number size, + cmsUInt32Number count); + cmsBool (* Seek)(struct _cms_io_handler* iohandler, cmsUInt32Number offset); + cmsBool (* Close)(struct _cms_io_handler* iohandler); + cmsUInt32Number (* Tell)(struct _cms_io_handler* iohandler); + cmsBool (* Write)(struct _cms_io_handler* iohandler, cmsUInt32Number size, + const void* Buffer); +}; + +// Endianness adjust functions +CMSAPI cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word); +CMSAPI cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number Value); +CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord); + +// Helper IO functions +CMSAPI cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n); +CMSAPI cmsBool CMSEXPORT _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n); +CMSAPI cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n); +CMSAPI cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n); +CMSAPI cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n); +CMSAPI cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n); +CMSAPI cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ); +CMSAPI cmsBool CMSEXPORT _cmsReadUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, cmsUInt16Number* Array); + +CMSAPI cmsBool CMSEXPORT _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n); +CMSAPI cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n); +CMSAPI cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n); +CMSAPI cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n); +CMSAPI cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n); +CMSAPI cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n); +CMSAPI cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ); +CMSAPI cmsBool CMSEXPORT _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array); + +// ICC base tag +typedef struct { + cmsTagTypeSignature sig; + cmsInt8Number reserved[4]; + +} _cmsTagBase; + +// Type base helper functions +CMSAPI cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io); +CMSAPI cmsBool CMSEXPORT _cmsWriteTypeBase(cmsIOHANDLER* io, cmsTagTypeSignature sig); + +// Alignment functions +CMSAPI cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io); +CMSAPI cmsBool CMSEXPORT _cmsWriteAlignment(cmsIOHANDLER* io); + +// To deal with text streams. 2K at most +CMSAPI cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...); + +// Fixed point helper functions +CMSAPI cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8); +CMSAPI cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val); + +CMSAPI cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32); +CMSAPI cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v); + +// Date/time helper functions +CMSAPI void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source); +CMSAPI void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest); + +//---------------------------------------------------------------------------------------------------------- + +// Shared callbacks for user data +typedef void (* _cmsFreeUserDataFn)(cmsContext ContextID, void* Data); +typedef void* (* _cmsDupUserDataFn)(cmsContext ContextID, const void* Data); + +//---------------------------------------------------------------------------------------------------------- + +// Plug-in foundation +#define cmsPluginMagicNumber 0x61637070 // 'acpp' + +#define cmsPluginMemHandlerSig 0x6D656D48 // 'memH' +#define cmsPluginInterpolationSig 0x696E7048 // 'inpH' +#define cmsPluginParametricCurveSig 0x70617248 // 'parH' +#define cmsPluginFormattersSig 0x66726D48 // 'frmH +#define cmsPluginTagTypeSig 0x74797048 // 'typH' +#define cmsPluginTagSig 0x74616748 // 'tagH' +#define cmsPluginRenderingIntentSig 0x696E7448 // 'intH' +#define cmsPluginMultiProcessElementSig 0x6D706548 // 'mpeH' +#define cmsPluginOptimizationSig 0x6F707448 // 'optH' +#define cmsPluginTransformSig 0x7A666D48 // 'xfmH' +#define cmsPluginMutexSig 0x6D747A48 // 'mtxH' +#define cmsPluginParalellizationSig 0x70726C48 // 'prlH + +typedef struct _cmsPluginBaseStruct { + + cmsUInt32Number Magic; // 'acpp' signature + cmsUInt32Number ExpectedVersion; // Expected version of LittleCMS + cmsUInt32Number Type; // Type of plug-in + struct _cmsPluginBaseStruct* Next; // For multiple plugin definition. NULL for end of list. + +} cmsPluginBase; + +// Maximum number of types in a plugin array +#define MAX_TYPES_IN_LCMS_PLUGIN 20 + +//---------------------------------------------------------------------------------------------------------- + +// Memory handler. Each new plug-in type replaces current behaviour + +typedef void* (* _cmsMallocFnPtrType)(cmsContext ContextID, cmsUInt32Number size); +typedef void (* _cmsFreeFnPtrType)(cmsContext ContextID, void *Ptr); +typedef void* (* _cmsReallocFnPtrType)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize); + +typedef void* (* _cmsMalloZerocFnPtrType)(cmsContext ContextID, cmsUInt32Number size); +typedef void* (* _cmsCallocFnPtrType)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size); +typedef void* (* _cmsDupFnPtrType)(cmsContext ContextID, const void* Org, cmsUInt32Number size); + +typedef struct { + + cmsPluginBase base; + + // Required + _cmsMallocFnPtrType MallocPtr; + _cmsFreeFnPtrType FreePtr; + _cmsReallocFnPtrType ReallocPtr; + + // Optional + _cmsMalloZerocFnPtrType MallocZeroPtr; + _cmsCallocFnPtrType CallocPtr; + _cmsDupFnPtrType DupPtr; + +} cmsPluginMemHandler; + + +// ------------------------------------------------------------------------------------------------------------------ + +// Interpolation. 16 bits and floating point versions. +struct _cms_interp_struc; + +// Interpolation callbacks + +// 16 bits forward interpolation. This function performs precision-limited linear interpolation +// and is supposed to be quite fast. Implementation may be tetrahedral or trilinear, and plug-ins may +// choose to implement any other interpolation algorithm. +typedef void (* _cmsInterpFn16)(CMSREGISTER const cmsUInt16Number Input[], + CMSREGISTER cmsUInt16Number Output[], + CMSREGISTER const struct _cms_interp_struc* p); + +// Floating point forward interpolation. Full precision interpolation using floats. This is not a +// time critical function. Implementation may be tetrahedral or trilinear, and plug-ins may +// choose to implement any other interpolation algorithm. +typedef void (* _cmsInterpFnFloat)(cmsFloat32Number const Input[], + cmsFloat32Number Output[], + const struct _cms_interp_struc* p); + + + +// This type holds a pointer to an interpolator that can be either 16 bits or float +typedef union { + _cmsInterpFn16 Lerp16; // Forward interpolation in 16 bits + _cmsInterpFnFloat LerpFloat; // Forward interpolation in floating point +} cmsInterpFunction; + +// Flags for interpolator selection +#define CMS_LERP_FLAGS_16BITS 0x0000 // The default +#define CMS_LERP_FLAGS_FLOAT 0x0001 // Requires different implementation +#define CMS_LERP_FLAGS_TRILINEAR 0x0100 // Hint only + + +#define MAX_INPUT_DIMENSIONS 15 + +typedef struct _cms_interp_struc { // Used on all interpolations. Supplied by lcms2 when calling the interpolation function + + cmsContext ContextID; // The calling thread + + cmsUInt32Number dwFlags; // Keep original flags + cmsUInt32Number nInputs; // != 1 only in 3D interpolation + cmsUInt32Number nOutputs; // != 1 only in 3D interpolation + + cmsUInt32Number nSamples[MAX_INPUT_DIMENSIONS]; // Valid on all kinds of tables + cmsUInt32Number Domain[MAX_INPUT_DIMENSIONS]; // Domain = nSamples - 1 + + cmsUInt32Number opta[MAX_INPUT_DIMENSIONS]; // Optimization for 3D CLUT. This is the number of nodes premultiplied for each + // dimension. For example, in 7 nodes, 7, 7^2 , 7^3, 7^4, etc. On non-regular + // Samplings may vary according of the number of nodes for each dimension. + + const void *Table; // Points to the actual interpolation table + cmsInterpFunction Interpolation; // Points to the function to do the interpolation + + } cmsInterpParams; + +// Interpolators factory +typedef cmsInterpFunction (* cmsInterpFnFactory)(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags); + +// The plug-in +typedef struct { + cmsPluginBase base; + + // Points to a user-supplied function which implements the factory + cmsInterpFnFactory InterpolatorsFactory; + +} cmsPluginInterpolation; + +//---------------------------------------------------------------------------------------------------------- + +// Parametric curves. A negative type means same function but analytically inverted. Max. number of params is 10 + +// Evaluator callback for user-supplied parametric curves. May implement more than one type +typedef cmsFloat64Number (* cmsParametricCurveEvaluator)(cmsInt32Number Type, const cmsFloat64Number Params[10], cmsFloat64Number R); + +// Plug-in may implement an arbitrary number of parametric curves +typedef struct { + cmsPluginBase base; + + cmsUInt32Number nFunctions; // Number of supported functions + cmsUInt32Number FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types + cmsUInt32Number ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function + + cmsParametricCurveEvaluator Evaluator; // The evaluator + +} cmsPluginParametricCurves; +//---------------------------------------------------------------------------------------------------------- + +// Formatters. This plug-in adds new handlers, replacing them if they already exist. Formatters dealing with +// cmsFloat32Number (bps = 4) or double (bps = 0) types are requested via FormatterFloat callback. Others come across +// Formatter16 callback + +struct _cmstransform_struct; + +typedef cmsUInt8Number* (* cmsFormatter16)(CMSREGISTER struct _cmstransform_struct* CMMcargo, + CMSREGISTER cmsUInt16Number Values[], + CMSREGISTER cmsUInt8Number* Buffer, + CMSREGISTER cmsUInt32Number Stride); + +typedef cmsUInt8Number* (* cmsFormatterFloat)(struct _cmstransform_struct* CMMcargo, + cmsFloat32Number Values[], + cmsUInt8Number* Buffer, + cmsUInt32Number Stride); + +// This type holds a pointer to a formatter that can be either 16 bits or cmsFloat32Number +typedef union { + cmsFormatter16 Fmt16; + cmsFormatterFloat FmtFloat; + +} cmsFormatter; + +#define CMS_PACK_FLAGS_16BITS 0x0000 +#define CMS_PACK_FLAGS_FLOAT 0x0001 + +typedef enum { cmsFormatterInput=0, cmsFormatterOutput=1 } cmsFormatterDirection; + +typedef cmsFormatter (* cmsFormatterFactory)(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags); // precision + +// Plug-in may implement an arbitrary number of formatters +typedef struct { + cmsPluginBase base; + cmsFormatterFactory FormattersFactory; + +} cmsPluginFormatters; + +//---------------------------------------------------------------------------------------------------------- + +// Tag type handler. Each type is free to return anything it wants, and it is up to the caller to +// know in advance what is the type contained in the tag. +typedef struct _cms_typehandler_struct { + + cmsTagTypeSignature Signature; // The signature of the type + + // Allocates and reads items + void * (* ReadPtr)(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + cmsUInt32Number* nItems, + cmsUInt32Number SizeOfTag); + + // Writes n Items + cmsBool (* WritePtr)(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Ptr, + cmsUInt32Number nItems); + + // Duplicate an item or array of items + void* (* DupPtr)(struct _cms_typehandler_struct* self, + const void *Ptr, + cmsUInt32Number n); + + // Free all resources + void (* FreePtr)(struct _cms_typehandler_struct* self, + void *Ptr); + + // Additional parameters used by the calling thread + cmsContext ContextID; + cmsUInt32Number ICCVersion; + +} cmsTagTypeHandler; + +// Each plug-in implements a single type +typedef struct { + cmsPluginBase base; + cmsTagTypeHandler Handler; + +} cmsPluginTagType; + +//---------------------------------------------------------------------------------------------------------- + +// This is the tag plugin, which identifies tags. For writing, a pointer to function is provided. +// This function should return the desired type for this tag, given the version of profile +// and the data being serialized. +typedef struct { + + cmsUInt32Number ElemCount; // If this tag needs an array, how many elements should keep + + // For reading. + cmsUInt32Number nSupportedTypes; // In how many types this tag can come (MAX_TYPES_IN_LCMS_PLUGIN maximum) + cmsTagTypeSignature SupportedTypes[MAX_TYPES_IN_LCMS_PLUGIN]; + + // For writing + cmsTagTypeSignature (* DecideType)(cmsFloat64Number ICCVersion, const void *Data); + +} cmsTagDescriptor; + +// Plug-in implements a single tag +typedef struct { + cmsPluginBase base; + + cmsTagSignature Signature; + cmsTagDescriptor Descriptor; + +} cmsPluginTag; + +//---------------------------------------------------------------------------------------------------------- + +// Custom intents. This function should join all profiles specified in the array in +// a single LUT. Any custom intent in the chain redirects to custom function. If more than +// one custom intent is found, the one located first is invoked. Usually users should use only one +// custom intent, so mixing custom intents in same multiprofile transform is not supported. + +typedef cmsPipeline* (* cmsIntentFn)( cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number Intents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + + +// Each plug-in defines a single intent number. +typedef struct { + cmsPluginBase base; + cmsUInt32Number Intent; + cmsIntentFn Link; + char Description[256]; + +} cmsPluginRenderingIntent; + + +// The default ICC intents (perceptual, saturation, rel.col and abs.col) +CMSAPI cmsPipeline* CMSEXPORT _cmsDefaultICCintents(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number Intents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags); + + +//---------------------------------------------------------------------------------------------------------- + +// Pipelines, Multi Process Elements. + +typedef void (* _cmsStageEvalFn) (const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage* mpe); +typedef void*(* _cmsStageDupElemFn) (cmsStage* mpe); +typedef void (* _cmsStageFreeElemFn) (cmsStage* mpe); + + +// This function allocates a generic MPE +CMSAPI cmsStage* CMSEXPORT _cmsStageAllocPlaceholder(cmsContext ContextID, + cmsStageSignature Type, + cmsUInt32Number InputChannels, + cmsUInt32Number OutputChannels, + _cmsStageEvalFn EvalPtr, // Points to fn that evaluates the element (always in floating point) + _cmsStageDupElemFn DupElemPtr, // Points to a fn that duplicates the stage + _cmsStageFreeElemFn FreePtr, // Points to a fn that sets the element free + void* Data); // A generic pointer to whatever memory needed by the element +typedef struct { + cmsPluginBase base; + cmsTagTypeHandler Handler; + +} cmsPluginMultiProcessElement; + + +// Data kept in "Element" member of cmsStage + +// Curves +typedef struct { + cmsUInt32Number nCurves; + cmsToneCurve** TheCurves; + +} _cmsStageToneCurvesData; + +// Matrix +typedef struct { + cmsFloat64Number* Double; // floating point for the matrix + cmsFloat64Number* Offset; // The offset + +} _cmsStageMatrixData; + +// CLUT +typedef struct { + + union { // Can have only one of both representations at same time + cmsUInt16Number* T; // Points to the table 16 bits table + cmsFloat32Number* TFloat; // Points to the cmsFloat32Number table + + } Tab; + + cmsInterpParams* Params; + cmsUInt32Number nEntries; + cmsBool HasFloatValues; + +} _cmsStageCLutData; + + +//---------------------------------------------------------------------------------------------------------- +// Optimization. Using this plug-in, additional optimization strategies may be implemented. +// The function should return TRUE if any optimization is done on the LUT, this terminates +// the optimization search. Or FALSE if it is unable to optimize and want to give a chance +// to the rest of optimizers. + +typedef cmsBool (* _cmsOPToptimizeFn)(cmsPipeline** Lut, + cmsUInt32Number Intent, + cmsUInt32Number* InputFormat, + cmsUInt32Number* OutputFormat, + cmsUInt32Number* dwFlags); + +// Pipeline Evaluator (in 16 bits) +typedef void (* _cmsPipelineEval16Fn)(CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + const void* Data); + +// Pipeline Evaluator (in floating point) +typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[], + cmsFloat32Number Out[], + const void* Data); + + +// This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional +// duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality. + +CMSAPI void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut, + _cmsPipelineEval16Fn Eval16, + void* PrivateData, + _cmsFreeUserDataFn FreePrivateDataFn, + _cmsDupUserDataFn DupPrivateDataFn); + +typedef struct { + cmsPluginBase base; + + // Optimize entry point + _cmsOPToptimizeFn OptimizePtr; + +} cmsPluginOptimization; + +//---------------------------------------------------------------------------------------------------------- +// Full xform + +typedef struct { + cmsUInt32Number BytesPerLineIn; + cmsUInt32Number BytesPerLineOut; + cmsUInt32Number BytesPerPlaneIn; + cmsUInt32Number BytesPerPlaneOut; + +} cmsStride; + +typedef void (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo, // Legacy function, handles just ONE scanline. + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number Size, + cmsUInt32Number Stride); // Stride in bytes to the next plane in planar formats + + +typedef void (*_cmsTransform2Fn)(struct _cmstransform_struct *CMMcargo, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride); + +typedef cmsBool (* _cmsTransformFactory)(_cmsTransformFn* xform, + void** UserData, + _cmsFreeUserDataFn* FreePrivateDataFn, + cmsPipeline** Lut, + cmsUInt32Number* InputFormat, + cmsUInt32Number* OutputFormat, + cmsUInt32Number* dwFlags); + +typedef cmsBool (* _cmsTransform2Factory)(_cmsTransform2Fn* xform, + void** UserData, + _cmsFreeUserDataFn* FreePrivateDataFn, + cmsPipeline** Lut, + cmsUInt32Number* InputFormat, + cmsUInt32Number* OutputFormat, + cmsUInt32Number* dwFlags); + + +// Retrieve user data as specified by the factory +CMSAPI void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn); +CMSAPI void * CMSEXPORT _cmsGetTransformUserData(struct _cmstransform_struct *CMMcargo); + + +// Retrieve formatters +CMSAPI void CMSEXPORT _cmsGetTransformFormatters16 (struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput); +CMSAPI void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput); + +// Retrieve original flags +CMSAPI cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMMcargo); + +typedef struct { + cmsPluginBase base; + + // Transform entry point + union { + _cmsTransformFactory legacy_xform; + _cmsTransform2Factory xform; + } factories; + +} cmsPluginTransform; + +//---------------------------------------------------------------------------------------------------------- +// Mutex + +typedef void* (* _cmsCreateMutexFnPtrType)(cmsContext ContextID); +typedef void (* _cmsDestroyMutexFnPtrType)(cmsContext ContextID, void* mtx); +typedef cmsBool (* _cmsLockMutexFnPtrType)(cmsContext ContextID, void* mtx); +typedef void (* _cmsUnlockMutexFnPtrType)(cmsContext ContextID, void* mtx); + +typedef struct { + cmsPluginBase base; + + _cmsCreateMutexFnPtrType CreateMutexPtr; + _cmsDestroyMutexFnPtrType DestroyMutexPtr; + _cmsLockMutexFnPtrType LockMutexPtr; + _cmsUnlockMutexFnPtrType UnlockMutexPtr; + +} cmsPluginMutex; + +CMSAPI void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID); +CMSAPI void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx); +CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx); +CMSAPI void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx); + +//---------------------------------------------------------------------------------------------------------- +// Parallelization + +CMSAPI _cmsTransform2Fn CMSEXPORT _cmsGetTransformWorker(struct _cmstransform_struct* CMMcargo); +CMSAPI cmsInt32Number CMSEXPORT _cmsGetTransformMaxWorkers(struct _cmstransform_struct* CMMcargo); +CMSAPI cmsUInt32Number CMSEXPORT _cmsGetTransformWorkerFlags(struct _cmstransform_struct* CMMcargo); + +// Let's plug-in to guess the best number of workers +#define CMS_GUESS_MAX_WORKERS -1 + +typedef struct { + cmsPluginBase base; + + cmsInt32Number MaxWorkers; // Number of starts to do as maximum + cmsUInt32Number WorkerFlags; // Reserved + _cmsTransform2Fn SchedulerFn; // callback to setup functions + +} cmsPluginParalellization; + + +#ifndef CMS_USE_CPP_API +# ifdef __cplusplus + } +# endif +#endif + +#define _lcms_plugin_H +#endif diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java 2023-07-05 07:11:54.000000000 +0000 @@ -53,10 +53,14 @@ * @see GraphicsDevice * @see java.awt.GraphicsConfiguration */ -@SuppressWarnings("removal") public final class X11GraphicsEnvironment extends SunGraphicsEnvironment { static { + initStatic(); + } + + @SuppressWarnings("removal") + private static void initStatic() { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { @@ -295,6 +299,7 @@ return true; } + @SuppressWarnings("removal") String isRemote = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.java2d.remote")); if (isRemote != null) { @@ -317,6 +322,7 @@ return true; } + @SuppressWarnings("removal") Boolean result = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Boolean run() { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java 2023-07-05 07:11:54.000000000 +0000 @@ -46,7 +46,6 @@ import javax.print.attribute.standard.PrinterName; -@SuppressWarnings("removal") public class CUPSPrinter { private static final String debugPrefix = "CUPSPrinter>> "; private static final double PRINTER_DPI = 72.0; @@ -83,6 +82,11 @@ private static int cupsPort = 0; static { + initStatic(); + } + + @SuppressWarnings("removal") + private static void initStatic() { // load awt library to access native code java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { @@ -292,6 +296,7 @@ IPPPrintService.getIPPConnection(url); if (urlConnection != null) { + @SuppressWarnings("removal") OutputStream os = java.security.AccessController. doPrivileged(new java.security.PrivilegedAction() { public OutputStream run() { @@ -406,6 +411,7 @@ IPPPrintService.getIPPConnection(url); if (urlConnection != null) { + @SuppressWarnings("removal") OutputStream os = java.security.AccessController. doPrivileged(new java.security.PrivilegedAction() { public OutputStream run() { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -58,7 +58,6 @@ * Remind: This class uses solaris commands. We also need a linux * version */ -@SuppressWarnings("removal") public class PrintServiceLookupProvider extends PrintServiceLookup implements BackgroundServiceLookup, Runnable { @@ -76,8 +75,9 @@ private static final int DEFAULT_MINREFRESH = 120; // 2 minutes private static int minRefreshTime = DEFAULT_MINREFRESH; - - static String osname; + @SuppressWarnings("removal") + static String osname = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("os.name")); // List of commands used to deal with the printer queues on AIX String[] lpNameComAix = { @@ -97,6 +97,7 @@ * can be used to force the printing code to poll or not poll * for PrintServices. */ + @SuppressWarnings("removal") String pollStr = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.java2d.print.polling")); @@ -112,6 +113,7 @@ * can be used to specify minimum refresh time (in seconds) * for polling PrintServices. The default is 120. */ + @SuppressWarnings("removal") String refreshTimeStr = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction( "sun.java2d.print.minRefreshTime")); @@ -126,15 +128,13 @@ } } - osname = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("os.name")); - /* The system property "sun.java2d.print.aix.lpstat" * can be used to force the usage of 'lpstat -p' to enumerate all * printer queues. By default we use 'lsallq', because 'lpstat -p' can * take lots of time if thousands of printers are attached to a server. */ if (isAIX()) { + @SuppressWarnings("removal") String aixPrinterEnumerator = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat")); @@ -222,6 +222,7 @@ * lead people to assume its guaranteed. */ public synchronized PrintService[] getPrintServices() { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); @@ -560,6 +561,7 @@ */ public PrintService[] getPrintServices(DocFlavor flavor, AttributeSet attributes) { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); @@ -623,6 +625,7 @@ public MultiDocPrintService[] getMultiDocPrintServices(DocFlavor[] flavors, AttributeSet attributes) { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); @@ -632,6 +635,7 @@ public synchronized PrintService getDefaultPrintService() { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); @@ -865,6 +869,7 @@ return printerNames.toArray(new String[printerNames.size()]); } + @SuppressWarnings("removal") static String[] execCmd(final String command) { ArrayList results = null; try { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java 2023-07-05 07:11:54.000000000 +0000 @@ -309,7 +309,6 @@ } } - @SuppressWarnings("removal") public void print(Doc doc, PrintRequestAttributeSet attributes) throws PrintException { @@ -536,7 +535,8 @@ // now spool the print data. PrinterOpener po = new PrinterOpener(); - java.security.AccessController.doPrivileged(po); + @SuppressWarnings("removal") + var dummy = java.security.AccessController.doPrivileged(po); if (po.pex != null) { throw po.pex; } @@ -609,7 +609,8 @@ if (mDestType == UnixPrintJob.DESTPRINTER) { PrinterSpooler spooler = new PrinterSpooler(); - java.security.AccessController.doPrivileged(spooler); + @SuppressWarnings("removal") + var dummy2 = java.security.AccessController.doPrivileged(spooler); if (spooler.pex != null) { throw spooler.pex; } diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/UnixPrintService.java openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/UnixPrintService.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/unix/classes/sun/print/UnixPrintService.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/unix/classes/sun/print/UnixPrintService.java 2023-07-05 07:11:54.000000000 +0000 @@ -74,14 +74,12 @@ import javax.print.event.PrintServiceAttributeListener; -@SuppressWarnings("removal") public class UnixPrintService implements PrintService, AttributeUpdater, SunPrinterJobService { /* define doc flavors for text types in the default encoding of * this platform since we can always read those. */ - private static String encoding = "ISO8859_1"; private static DocFlavor textByteFlavor; private static DocFlavor[] supportedDocFlavors = null; @@ -147,10 +145,9 @@ "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk '{print $4}'" }; - static { - encoding = java.security.AccessController.doPrivileged( + @SuppressWarnings("removal") + private static String encoding = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("file.encoding")); - } /* let's try to support a few of these */ private static final Class[] serviceAttrCats = { @@ -421,6 +418,7 @@ } public DocPrintJob createPrintJob() { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java 2023-07-05 07:11:54.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 @@ -902,7 +902,7 @@ location = Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(), linkLocationPIDL); - } catch (InterruptedException e) { + } catch (InterruptedException | FileNotFoundException e) { // Return null } catch (InternalError e) { // Could be a link to a non-bindable object, such as a network connection diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java 2023-07-05 07:11:54.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 @@ -108,11 +108,15 @@ } static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL) - throws InterruptedException { + throws InterruptedException, FileNotFoundException + { // Walk down this relative pIDL, creating new nodes for each of the entries while (pIDL != 0) { long curPIDL = Win32ShellFolder2.copyFirstPIDLEntry(pIDL); if (curPIDL != 0) { + if (!parent.isDirectory()) { + throw new FileNotFoundException("not a directory"); + } parent = Win32ShellFolder2.createShellFolder(parent, curPIDL); pIDL = Win32ShellFolder2.getNextPIDLEntry(pIDL); } else { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java 2023-07-05 07:11:54.000000000 +0000 @@ -45,32 +45,26 @@ /** * The X11 implementation of {@link FontManager}. */ -@SuppressWarnings("removal") public final class Win32FontManager extends SunFontManager { - private static TrueTypeFont eudcFont; - - static { - - AccessController.doPrivileged(new PrivilegedAction() { - - public Object run() { + @SuppressWarnings("removal") + private static final TrueTypeFont eudcFont = + AccessController.doPrivileged(new PrivilegedAction() { + public TrueTypeFont run() { String eudcFile = getEUDCFontFile(); if (eudcFile != null) { try { /* Must use Java rasteriser since GDI doesn't * enumerate (allow direct use) of EUDC fonts. */ - eudcFont = new TrueTypeFont(eudcFile, null, 0, + return new TrueTypeFont(eudcFile, null, 0, true, false); } catch (FontFormatException e) { } } return null; } - }); - } /* Used on Windows to obtain from the windows registry the name * of a file containing the system EUFC font. If running in one of @@ -84,6 +78,7 @@ return eudcFont; } + @SuppressWarnings("removal") public Win32FontManager() { super(); AccessController.doPrivileged(new PrivilegedAction() { @@ -218,6 +213,7 @@ info[1] = "c:\\windows\\fonts"; final String[] dirs = getPlatformFontDirs(true); if (dirs.length > 1) { + @SuppressWarnings("removal") String dir = (String) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { @@ -252,6 +248,7 @@ fontsForPrinting = pathName; } + @SuppressWarnings("removal") public static void registerJREFontsForPrinting() { final String pathName; synchronized (Win32GraphicsEnvironment.class) { diff -Nru openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java --- openjdk-17-17.0.7+7~us1/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -41,13 +41,17 @@ import javax.print.attribute.PrintServiceAttributeSet; import javax.print.attribute.standard.PrinterName; -@SuppressWarnings("removal") public class PrintServiceLookupProvider extends PrintServiceLookup { private PrintService defaultPrintService; private PrintService[] printServices; /* includes the default printer */ static { + loadAWTLibrary(); + } + + @SuppressWarnings("removal") + private static void loadAWTLibrary() { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { @@ -102,6 +106,7 @@ * lead people to assume its guaranteed. */ public synchronized PrintService[] getPrintServices() { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); @@ -202,6 +207,7 @@ public PrintService[] getPrintServices(DocFlavor flavor, AttributeSet attributes) { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); @@ -267,6 +273,7 @@ public MultiDocPrintService[] getMultiDocPrintServices(DocFlavor[] flavors, AttributeSet attributes) { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); @@ -276,6 +283,7 @@ public synchronized PrintService getDefaultPrintService() { + @SuppressWarnings("removal") SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPrintJobAccess(); diff -Nru openjdk-17-17.0.7+7~us1/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java openjdk-17-17.0.8+7/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java --- openjdk-17-17.0.7+7~us1/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java 2023-07-05 07:11:54.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 @@ -44,6 +44,7 @@ import javax.naming.CommunicationException; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; +import javax.naming.ldap.LdapName; import javax.security.auth.x500.X500Principal; import com.sun.jndi.ldap.LdapReferralException; @@ -218,16 +219,23 @@ */ private class LDAPRequest { - private final String name; + private final LdapName name; private Map valueMap; private final List requestedAttributes; LDAPRequest(String name) throws CertStoreException { - this.name = checkName(name); + try { + // Convert DN to an LdapName so that it is not treated as a + // composite name by JNDI. In JNDI, using a string name is + // equivalent to calling new CompositeName(stringName). + this.name = new LdapName(name); + } catch (InvalidNameException ine) { + throw new CertStoreException("Invalid name: " + name, ine); + } requestedAttributes = new ArrayList<>(5); } - private String checkName(String name) throws CertStoreException { + private static String checkName(String name) throws CertStoreException { if (name == null) { throw new CertStoreException("Name absent"); } @@ -321,6 +329,9 @@ if (newDn != null && newDn.charAt(0) == '/') { newDn = newDn.substring(1); } + // In JNDI, it is not possible to use an LdapName for + // the referral DN, so we must validate the syntax of + // the string DN. checkName(newDn); } catch (Exception e) { throw new NamingException("Cannot follow referral to " @@ -371,7 +382,7 @@ * or does not contain any values, a zero length byte array is * returned. NOTE that it is assumed that all values are byte arrays. */ - private byte[][] getAttributeValues(Attribute attr) + private static byte[][] getAttributeValues(Attribute attr) throws NamingException { byte[][] values; if (attr == null) { diff -Nru openjdk-17-17.0.7+7~us1/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java openjdk-17-17.0.8+7/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java --- openjdk-17-17.0.7+7~us1/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java 2023-07-05 07:11:54.000000000 +0000 @@ -45,6 +45,7 @@ import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.ResponseInfo; import java.net.http.HttpResponse.BodySubscriber; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import jdk.internal.net.http.ResponseSubscribers.PathSubscriber; @@ -229,16 +230,120 @@ static final String DISPOSITION_TYPE = "attachment;"; /** The "filename" parameter. */ - static final Pattern FILENAME = Pattern.compile("filename\\s*=", CASE_INSENSITIVE); + static final Pattern FILENAME = Pattern.compile("filename\\s*=\\s*", CASE_INSENSITIVE); static final List PROHIBITED = List.of(".", "..", "", "~" , "|"); + // Characters disallowed in token values + + static final Set NOT_ALLOWED_IN_TOKEN = Set.of( + '(', ')', '<', '>', '@', + ',', ';', ':', '\\', '"', + '/', '[', ']', '?', '=', + '{', '}', ' ', '\t'); + + static boolean allowedInToken(char c) { + if (NOT_ALLOWED_IN_TOKEN.contains(c)) + return false; + // exclude CTL chars <= 31, == 127, or anything >= 128 + return isTokenText(c); + } + static final UncheckedIOException unchecked(ResponseInfo rinfo, String msg) { String s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); return new UncheckedIOException(new IOException(s)); } + static final UncheckedIOException unchecked(String msg) { + return new UncheckedIOException(new IOException(msg)); + } + + // Process a "filename=" parameter, which is either a "token" + // or a "quoted string". If a token, it is terminated by a + // semicolon or the end of the string. + // If a quoted string (surrounded by "" chars then the closing " + // terminates the name. + // quoted strings may contain quoted-pairs (eg embedded " chars) + + static String processFilename(String src) throws UncheckedIOException { + if ("".equals(src)) + return src; + if (src.charAt(0) == '\"') { + return processQuotedString(src.substring(1)); + } else { + return processToken(src); + } + } + + static boolean isTokenText(char c) throws UncheckedIOException { + return c > 31 && c < 127; + } + + static boolean isQuotedStringText(char c) throws UncheckedIOException { + return c > 31; + } + + static String processQuotedString(String src) throws UncheckedIOException { + boolean inqpair = false; + int len = src.length(); + StringBuilder sb = new StringBuilder(); + + for (int i=0; i apply(ResponseInfo responseInfo) { String dispoHeader = responseInfo.headers().firstValue("Content-Disposition") @@ -256,13 +361,7 @@ } int n = matcher.end(); - int semi = dispoHeader.substring(n).indexOf(";"); - String filenameParam; - if (semi < 0) { - filenameParam = dispoHeader.substring(n); - } else { - filenameParam = dispoHeader.substring(n, n + semi); - } + String filenameParam = processFilename(dispoHeader.substring(n)); // strip all but the last path segment int x = filenameParam.lastIndexOf("/"); @@ -276,19 +375,6 @@ filenameParam = filenameParam.trim(); - if (filenameParam.startsWith("\"")) { // quoted-string - if (!filenameParam.endsWith("\"") || filenameParam.length() == 1) { - throw unchecked(responseInfo, - "Badly quoted Content-Disposition filename parameter"); - } - filenameParam = filenameParam.substring(1, filenameParam.length() -1 ); - } else { // token, - if (filenameParam.contains(" ")) { // space disallowed - throw unchecked(responseInfo, - "unquoted space in Content-Disposition filename parameter"); - } - } - if (PROHIBITED.contains(filenameParam)) { throw unchecked(responseInfo, "Prohibited Content-Disposition filename parameter:" diff -Nru openjdk-17-17.0.7+7~us1/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java openjdk-17-17.0.8+7/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java --- openjdk-17-17.0.7+7~us1/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -127,6 +127,11 @@ "fallback to other scheme if allowed. Reason:"); e.printStackTrace(); } + try { + disposeContext(); + } catch (Exception ex) { + //dispose context silently + } IOException ioe = new IOException("Negotiate support not initiated"); ioe.initCause(e); throw ioe; @@ -151,6 +156,9 @@ @Override public byte[] nextToken(byte[] token) throws IOException { try { + if (context == null) { + throw new IOException("Negotiate support cannot continue. Context is invalidated"); + } return context.initSecContext(token, 0, token.length); } catch (GSSException e) { if (DEBUG) { @@ -162,4 +170,26 @@ throw ioe; } } + + /** + * Releases any system resources and cryptographic information stored in + * the context object and invalidates the context. + * + * @throws IOException containing a reason of failure in the cause + */ + @Override + public void disposeContext() throws IOException { + try { + if (context != null) { + context.dispose(); + } + } catch (GSSException e) { + if (DEBUG) { + System.out.println("Cannot release resources. Reason:"); + e.printStackTrace(); + } + throw new IOException("Cannot release resources", e); + }; + context = null; + } } diff -Nru openjdk-17-17.0.7+7~us1/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java openjdk-17-17.0.8+7/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java --- openjdk-17-17.0.7+7~us1/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java 2023-07-05 07:11:54.000000000 +0000 @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. */ package org.jcp.xml.dsig.internal.dom; @@ -300,35 +300,23 @@ ("unable to create DSA KeyFactory: " + e.getMessage()); } } - Element curElem = DOMUtils.getFirstChildElement(kvtElem); - if (curElem == null) { - throw new MarshalException("KeyValue must contain at least one type"); - } - // check for P and Q - BigInteger p = null; - BigInteger q = null; - if ("P".equals(curElem.getLocalName()) && XMLSignature.XMLNS.equals(curElem.getNamespaceURI())) { - p = decode(curElem); - curElem = DOMUtils.getNextSiblingElement(curElem, "Q", XMLSignature.XMLNS); - q = decode(curElem); - curElem = DOMUtils.getNextSiblingElement(curElem); - } - BigInteger g = null; - if (curElem != null - && "G".equals(curElem.getLocalName()) && XMLSignature.XMLNS.equals(curElem.getNamespaceURI())) { - g = decode(curElem); - curElem = DOMUtils.getNextSiblingElement(curElem, "Y", XMLSignature.XMLNS); - } - BigInteger y = null; - if (curElem != null) { - y = decode(curElem); - curElem = DOMUtils.getNextSiblingElement(curElem); - } - //if (curElem != null && "J".equals(curElem.getLocalName())) { - //j = new DOMCryptoBinary(curElem.getFirstChild()); - // curElem = DOMUtils.getNextSiblingElement(curElem); - //} - //@@@ do we care about j, pgenCounter or seed? + // P, Q, and G are optional according to the XML Signature + // Recommendation as they might be known from application context, + // but this implementation does not provide a mechanism or API for + // an application to supply the missing parameters, so they are + // required to be specified. + Element curElem = + DOMUtils.getFirstChildElement(kvtElem, "P", XMLSignature.XMLNS); + BigInteger p = decode(curElem); + curElem = + DOMUtils.getNextSiblingElement(curElem, "Q", XMLSignature.XMLNS); + BigInteger q = decode(curElem); + curElem = + DOMUtils.getNextSiblingElement(curElem, "G", XMLSignature.XMLNS); + BigInteger g = decode(curElem); + curElem = + DOMUtils.getNextSiblingElement(curElem, "Y", XMLSignature.XMLNS); + BigInteger y = decode(curElem); DSAPublicKeySpec spec = new DSAPublicKeySpec(y, p, q, g); return (DSAPublicKey) generatePublicKey(dsakf, spec); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template openjdk-17-17.0.8+7/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template --- openjdk-17-17.0.7+7~us1/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, 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. * @@ -29,9 +29,6 @@ package sun.nio.cs.ext; -import java.nio.charset.Charset; -import java.nio.charset.spi.CharsetProvider; - /** * Provider for extended charsets. */ diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template openjdk-17-17.0.8+7/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template --- openjdk-17-17.0.7+7~us1/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template 1970-01-01 00:00:00.000000000 +0000 @@ -1,12772 +0,0 @@ -/* - * Copyright (c) 2002, 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. 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 $PACKAGE$; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CoderResult; -import sun.nio.cs.Surrogate; - -public class GB18030 - extends Charset -{ - private static final int GB18030_SINGLE_BYTE = 1; - private static final int GB18030_DOUBLE_BYTE = 2; - private static final int GB18030_FOUR_BYTE = 3; - - public GB18030() { - super("GB18030", $ALIASES$); - } - - public boolean contains(Charset cs) { - return ((cs.name().equals("US-ASCII")) - || (cs.name().equals("GBK")) - || (cs.name().equals("ISO-8859-1")) - || (cs.name().equals("ISO-8859-2")) - || (cs.name().equals("ISO-8859-3")) - || (cs.name().equals("ISO-8859-4")) - || (cs.name().equals("ISO-8859-5")) - || (cs.name().equals("ISO-8859-6")) - || (cs.name().equals("ISO-8859-7")) - || (cs.name().equals("ISO-8859-8")) - || (cs.name().equals("ISO-8859-9")) - || (cs.name().equals("ISO-8859-13")) - || (cs.name().equals("ISO-8859-15")) - || (cs.name().equals("ISO-8859-16")) - || (cs.name().equals("UTF-8")) - || (cs.name().equals("UTF-16")) - || (cs.name().equals("UTF-16LE")) - || (cs.name().equals("UTF-16BE")) - || (cs.name().equals("windows-1251")) - || (cs.name().equals("windows-1252")) - || (cs.name().equals("windows-1253")) - || (cs.name().equals("windows-1254")) - || (cs.name().equals("windows-1255")) - || (cs.name().equals("windows-1256")) - || (cs.name().equals("windows-1257")) - || (cs.name().equals("windows-1258")) - || (cs.name().equals("windows-932")) - || (cs.name().equals("x-mswin-936")) - || (cs.name().equals("x-windows-949")) - || (cs.name().equals("x-windows-950")) - || (cs.name().equals("windows-31j")) - || (cs.name().equals("JIS_X0201")) - || (cs.name().equals("JIS_X0208-1990")) - || (cs.name().equals("JIS_X0212")) - || (cs.name().equals("Shift_JIS")) - || (cs.name().equals("GB2312")) - || (cs.name().equals("EUC-KR")) - || (cs.name().equals("x-EUC-TW")) - || (cs.name().equals("EUC-JP")) - || (cs.name().equals("euc-jp-linux")) - || (cs.name().equals("KOI8-R")) - || (cs.name().equals("TIS-620")) - || (cs.name().equals("x-ISCII91")) - || (cs.name().equals("Big5")) - || (cs.name().equals("Big5-HKSCS")) - || (cs.name().equals("x-MS950-HKSCS")) - || (cs.name().equals("ISO-2022-JP")) - || (cs.name().equals("ISO-2022-KR")) - || (cs.name().equals("x-ISO-2022-CN-CNS")) - || (cs.name().equals("x-ISO-2022-CN-GB")) - || (cs.name().equals("x-Johab")) - || (cs instanceof GB18030)); - } - - public CharsetDecoder newDecoder() { - return new Decoder(this); - } - - public CharsetEncoder newEncoder() { - return new Encoder(this); - } - - private static final String innerDecoderIndex0= - "\u0080"+ - "\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088"+ - "\u0089\u008A\u008B\u008C\u008D\u008E\u008F\u0090"+ - "\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098"+ - "\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0"+ - "\u00A1\u00A2\u00A3\u00A5\u00A6\u00A9\u00AA\u00AB"+ - "\u00AC\u00AD\u00AE\u00AF\u00B2\u00B3\u00B4\u00B5"+ - "\u00B6\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE"+ - "\u00BF\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6"+ - "\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE"+ - "\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6"+ - "\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF"+ - "\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00EB\u00EE"+ - "\u00EF\u00F0\u00F1\u00F4\u00F5\u00F6\u00F8\u00FB"+ - "\u00FD\u00FE\u00FF\u0100\u0102\u0103\u0104\u0105"+ - "\u0106\u0107\u0108\u0109\u010A\u010B\u010C\u010D"+ - "\u010E\u010F\u0110\u0111\u0112\u0114\u0115\u0116"+ - "\u0117\u0118\u0119\u011A\u011C\u011D\u011E\u011F"+ - "\u0120\u0121\u0122\u0123\u0124\u0125\u0126\u0127"+ - "\u0128\u0129\u012A\u012C\u012D\u012E\u012F\u0130"+ - "\u0131\u0132\u0133\u0134\u0135\u0136\u0137\u0138"+ - "\u0139\u013A\u013B\u013C\u013D\u013E\u013F\u0140"+ - "\u0141\u0142\u0143\u0145\u0146\u0147\u0149\u014A"+ - "\u014B\u014C\u014E\u014F\u0150\u0151\u0152\u0153"+ - "\u0154\u0155\u0156\u0157\u0158\u0159\u015A\u015B"+ - "\u015C\u015D\u015E\u015F\u0160\u0161\u0162\u0163"+ - "\u0164\u0165\u0166\u0167\u0168\u0169\u016A\u016C"+ - "\u016D\u016E\u016F\u0170\u0171\u0172\u0173\u0174"+ - "\u0175\u0176\u0177\u0178\u0179\u017A\u017B\u017C"+ - "\u017D\u017E\u017F\u0180\u0181\u0182\u0183\u0184"+ - "\u0185\u0186\u0187\u0188\u0189\u018A\u018B\u018C"+ - "\u018D\u018E\u018F\u0190\u0191\u0192\u0193\u0194"+ - "\u0195\u0196\u0197\u0198\u0199\u019A\u019B"+ - "\u019C\u019D\u019E\u019F\u01A0\u01A1\u01A2\u01A3"+ - "\u01A4\u01A5\u01A6\u01A7\u01A8\u01A9\u01AA\u01AB"+ - "\u01AC\u01AD\u01AE\u01AF\u01B0\u01B1\u01B2\u01B3"+ - "\u01B4\u01B5\u01B6\u01B7\u01B8\u01B9\u01BA\u01BB"+ - "\u01BC\u01BD\u01BE\u01BF\u01C0\u01C1\u01C2\u01C3"+ - "\u01C4\u01C5\u01C6\u01C7\u01C8\u01C9\u01CA\u01CB"+ - "\u01CC\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9"+ - "\u01DB\u01DD\u01DE\u01DF\u01E0\u01E1\u01E2\u01E3"+ - "\u01E4\u01E5\u01E6\u01E7\u01E8\u01E9\u01EA\u01EB"+ - "\u01EC\u01ED\u01EE\u01EF\u01F0\u01F1\u01F2\u01F3"+ - "\u01F4\u01F5\u01F6\u01F7\u01F8\u01FA\u01FB\u01FC"+ - "\u01FD\u01FE\u01FF\u0200\u0201\u0202\u0203\u0204"+ - "\u0205\u0206\u0207\u0208\u0209\u020A\u020B\u020C"+ - "\u020D\u020E\u020F\u0210\u0211\u0212\u0213\u0214"+ - "\u0215\u0216\u0217\u0218\u0219\u021A\u021B\u021C"+ - "\u021D\u021E\u021F\u0220\u0221\u0222\u0223\u0224"+ - "\u0225\u0226\u0227\u0228\u0229\u022A\u022B\u022C"+ - "\u022D\u022E\u022F\u0230\u0231\u0232\u0233\u0234"+ - "\u0235\u0236\u0237\u0238\u0239\u023A\u023B\u023C"+ - "\u023D\u023E\u023F\u0240\u0241\u0242\u0243\u0244"+ - "\u0245\u0246\u0247\u0248\u0249\u024A\u024B\u024C"+ - "\u024D\u024E\u024F\u0250\u0252\u0253\u0254\u0255"+ - "\u0256\u0257\u0258\u0259\u025A\u025B\u025C\u025D"+ - "\u025E\u025F\u0260\u0262\u0263\u0264\u0265\u0266"+ - "\u0267\u0268\u0269\u026A\u026B\u026C\u026D\u026E"+ - "\u026F\u0270\u0271\u0272\u0273\u0274\u0275\u0276"+ - "\u0277\u0278\u0279\u027A\u027B\u027C\u027D\u027E"+ - "\u027F\u0280\u0281\u0282\u0283\u0284\u0285\u0286"+ - "\u0287\u0288\u0289\u028A\u028B\u028C\u028D\u028E"+ - "\u028F\u0290\u0291\u0292\u0293\u0294\u0295\u0296"+ - "\u0297\u0298\u0299\u029A\u029B\u029C\u029D\u029E"+ - "\u029F\u02A0\u02A1\u02A2\u02A3\u02A4\u02A5\u02A6"+ - "\u02A7\u02A8\u02A9\u02AA\u02AB\u02AC\u02AD\u02AE"+ - "\u02AF\u02B0\u02B1\u02B2\u02B3\u02B4\u02B5\u02B6"+ - "\u02B7\u02B8\u02B9\u02BA\u02BB\u02BC\u02BD\u02BE"+ - "\u02BF\u02C0\u02C1\u02C2\u02C3\u02C4\u02C5\u02C6"+ - "\u02C8\u02CC\u02CD\u02CE\u02CF\u02D0\u02D1\u02D2"+ - "\u02D3\u02D4\u02D5\u02D6\u02D7\u02D8\u02DA\u02DB"+ - "\u02DC\u02DD\u02DE\u02DF\u02E0\u02E1\u02E2\u02E3"+ - "\u02E4\u02E5\u02E6\u02E7\u02E8\u02E9\u02EA\u02EB"+ - "\u02EC\u02ED\u02EE\u02EF\u02F0\u02F1\u02F2\u02F3"+ - "\u02F4\u02F5\u02F6\u02F7\u02F8\u02F9\u02FA\u02FB"+ - "\u02FC\u02FD\u02FE\u02FF\u0300\u0301\u0302\u0303"+ - "\u0304\u0305\u0306\u0307\u0308\u0309\u030A\u030B"+ - "\u030C\u030D\u030E\u030F\u0310\u0311\u0312\u0313"+ - "\u0314\u0315\u0316\u0317\u0318\u0319\u031A\u031B"+ - "\u031C\u031D\u031E\u031F\u0320\u0321\u0322\u0323"+ - "\u0324\u0325\u0326\u0327\u0328\u0329\u032A\u032B"+ - "\u032C\u032D\u032E\u032F\u0330\u0331\u0332\u0333"+ - "\u0334\u0335\u0336\u0337\u0338\u0339\u033A\u033B"+ - "\u033C\u033D\u033E\u033F\u0340\u0341\u0342\u0343"+ - "\u0344\u0345\u0346\u0347\u0348\u0349\u034A\u034B"+ - "\u034C\u034D\u034E\u034F\u0350\u0351\u0352\u0353"+ - "\u0354\u0355\u0356\u0357\u0358\u0359\u035A\u035B"+ - "\u035C\u035D\u035E\u035F\u0360\u0361\u0362\u0363"+ - "\u0364\u0365\u0366\u0367\u0368\u0369\u036A\u036B"+ - "\u036C\u036D\u036E\u036F\u0370\u0371\u0372\u0373"+ - "\u0374\u0375\u0376\u0377\u0378\u0379\u037A\u037B"+ - "\u037C\u037D\u037E\u037F\u0380\u0381\u0382\u0383"+ - "\u0384\u0385\u0386\u0387\u0388\u0389\u038A\u038B"+ - "\u038C\u038D\u038E\u038F\u0390\u03A2\u03AA\u03AB"+ - "\u03AC\u03AD\u03AE\u03AF\u03B0\u03C2\u03CA\u03CB"+ - "\u03CC\u03CD\u03CE\u03CF\u03D0\u03D1\u03D2\u03D3"+ - "\u03D4\u03D5\u03D6\u03D7\u03D8\u03D9\u03DA\u03DB"+ - "\u03DC\u03DD\u03DE\u03DF\u03E0\u03E1\u03E2\u03E3"+ - "\u03E4\u03E5\u03E6\u03E7\u03E8\u03E9\u03EA\u03EB"+ - "\u03EC\u03ED\u03EE\u03EF\u03F0\u03F1\u03F2\u03F3"+ - "\u03F4\u03F5\u03F6\u03F7\u03F8\u03F9\u03FA\u03FB"+ - "\u03FC\u03FD\u03FE\u03FF\u0400\u0402\u0403\u0404"+ - "\u0405\u0406\u0407\u0408\u0409\u040A\u040B\u040C"+ - "\u040D\u040E\u040F\u0450\u0452\u0453\u0454\u0455"+ - "\u0456\u0457\u0458\u0459\u045A\u045B\u045C\u045D"+ - "\u045E\u045F\u0460\u0461\u0462\u0463\u0464\u0465"+ - "\u0466\u0467\u0468\u0469\u046A\u046B\u046C\u046D"+ - "\u046E\u046F\u0470\u0471\u0472\u0473\u0474\u0475"+ - "\u0476\u0477\u0478\u0479\u047A\u047B\u047C\u047D"+ - "\u047E\u047F\u0480\u0481\u0482\u0483\u0484\u0485"+ - "\u0486\u0487\u0488\u0489\u048A\u048B\u048C\u048D"+ - "\u048E\u048F\u0490\u0491\u0492\u0493\u0494\u0495"+ - "\u0496\u0497\u0498\u0499\u049A\u049B\u049C\u049D"+ - "\u049E\u049F\u04A0\u04A1\u04A2\u04A3\u04A4\u04A5"+ - "\u04A6\u04A7\u04A8\u04A9\u04AA\u04AB\u04AC\u04AD"+ - "\u04AE\u04AF\u04B0\u04B1\u04B2\u04B3\u04B4\u04B5"+ - "\u04B6\u04B7\u04B8\u04B9\u04BA\u04BB\u04BC\u04BD"+ - "\u04BE\u04BF\u04C0\u04C1\u04C2\u04C3\u04C4\u04C5"+ - "\u04C6\u04C7\u04C8\u04C9\u04CA\u04CB\u04CC\u04CD"+ - "\u04CE\u04CF\u04D0\u04D1\u04D2\u04D3\u04D4\u04D5"+ - "\u04D6\u04D7\u04D8\u04D9\u04DA\u04DB\u04DC\u04DD"+ - "\u04DE\u04DF\u04E0\u04E1\u04E2\u04E3\u04E4\u04E5"+ - "\u04E6\u04E7\u04E8\u04E9\u04EA\u04EB\u04EC\u04ED"+ - "\u04EE\u04EF\u04F0\u04F1\u04F2\u04F3\u04F4\u04F5"+ - "\u04F6\u04F7\u04F8\u04F9\u04FA\u04FB\u04FC\u04FD"+ - "\u04FE\u04FF\u0500\u0501\u0502\u0503\u0504\u0505"+ - "\u0506\u0507\u0508\u0509\u050A\u050B\u050C\u050D"+ - "\u050E\u050F\u0510\u0511\u0512\u0513\u0514\u0515"+ - "\u0516\u0517\u0518\u0519\u051A\u051B\u051C\u051D"+ - "\u051E\u051F\u0520\u0521\u0522\u0523\u0524\u0525"+ - "\u0526\u0527\u0528\u0529\u052A\u052B\u052C\u052D"+ - "\u052E\u052F\u0530\u0531\u0532\u0533\u0534\u0535"+ - "\u0536\u0537\u0538\u0539\u053A\u053B\u053C\u053D"+ - "\u053E\u053F\u0540\u0541\u0542\u0543\u0544\u0545"+ - "\u0546\u0547\u0548\u0549\u054A\u054B\u054C\u054D"+ - "\u054E\u054F\u0550\u0551\u0552\u0553\u0554\u0555"+ - "\u0556\u0557\u0558\u0559\u055A\u055B\u055C\u055D"+ - "\u055E\u055F\u0560\u0561\u0562\u0563\u0564\u0565"+ - "\u0566\u0567\u0568\u0569\u056A\u056B\u056C\u056D"+ - "\u056E\u056F\u0570\u0571\u0572\u0573\u0574\u0575"+ - "\u0576\u0577\u0578\u0579\u057A\u057B\u057C\u057D"+ - "\u057E\u057F\u0580\u0581\u0582\u0583\u0584\u0585"+ - "\u0586\u0587\u0588\u0589\u058A\u058B\u058C\u058D"+ - "\u058E\u058F\u0590\u0591\u0592\u0593\u0594\u0595"+ - "\u0596\u0597\u0598\u0599\u059A\u059B\u059C\u059D"+ - "\u059E\u059F\u05A0\u05A1\u05A2\u05A3\u05A4\u05A5"+ - "\u05A6\u05A7\u05A8\u05A9\u05AA\u05AB\u05AC\u05AD"+ - "\u05AE\u05AF\u05B0\u05B1\u05B2\u05B3\u05B4\u05B5"+ - "\u05B6\u05B7\u05B8\u05B9\u05BA\u05BB\u05BC\u05BD"+ - "\u05BE\u05BF\u05C0\u05C1\u05C2\u05C3\u05C4\u05C5"+ - "\u05C6\u05C7\u05C8\u05C9\u05CA\u05CB\u05CC\u05CD"+ - "\u05CE\u05CF\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5"+ - "\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD"+ - "\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5"+ - "\u05E6\u05E7\u05E8\u05E9\u05EA\u05EB\u05EC\u05ED"+ - "\u05EE\u05EF\u05F0\u05F1\u05F2\u05F3\u05F4\u05F5"+ - "\u05F6\u05F7\u05F8\u05F9\u05FA\u05FB\u05FC\u05FD"+ - "\u05FE\u05FF\u0600\u0601\u0602\u0603\u0604\u0605"+ - "\u0606\u0607\u0608\u0609\u060A\u060B\u060C\u060D"+ - "\u060E\u060F\u0610\u0611\u0612\u0613\u0614\u0615"+ - "\u0616\u0617\u0618\u0619\u061A\u061B\u061C\u061D"+ - "\u061E\u061F\u0620\u0621\u0622\u0623\u0624\u0625"+ - "\u0626\u0627\u0628\u0629\u062A\u062B\u062C\u062D"+ - "\u062E\u062F\u0630\u0631\u0632\u0633\u0634\u0635"+ - "\u0636\u0637\u0638\u0639\u063A\u063B\u063C\u063D"+ - "\u063E\u063F\u0640\u0641\u0642\u0643\u0644\u0645"+ - "\u0646\u0647\u0648\u0649\u064A\u064B\u064C\u064D"+ - "\u064E\u064F\u0650\u0651\u0652\u0653\u0654\u0655"+ - "\u0656\u0657\u0658\u0659\u065A\u065B\u065C\u065D"+ - "\u065E\u065F\u0660\u0661\u0662\u0663\u0664\u0665"+ - "\u0666\u0667\u0668\u0669\u066A\u066B\u066C\u066D"+ - "\u066E\u066F\u0670\u0671\u0672\u0673\u0674\u0675"+ - "\u0676\u0677\u0678\u0679\u067A\u067B\u067C\u067D"+ - "\u067E\u067F\u0680\u0681\u0682\u0683\u0684\u0685"+ - "\u0686\u0687\u0688\u0689\u068A\u068B\u068C\u068D"+ - "\u068E\u068F\u0690\u0691\u0692\u0693\u0694\u0695"+ - "\u0696\u0697\u0698\u0699\u069A\u069B\u069C\u069D"+ - "\u069E\u069F\u06A0\u06A1\u06A2\u06A3\u06A4\u06A5"+ - "\u06A6\u06A7\u06A8\u06A9\u06AA\u06AB\u06AC\u06AD"+ - "\u06AE\u06AF\u06B0\u06B1\u06B2\u06B3\u06B4\u06B5"+ - "\u06B6\u06B7\u06B8\u06B9\u06BA\u06BB\u06BC\u06BD"+ - "\u06BE\u06BF\u06C0\u06C1\u06C2\u06C3\u06C4\u06C5"+ - "\u06C6\u06C7\u06C8\u06C9\u06CA\u06CB\u06CC\u06CD"+ - "\u06CE\u06CF\u06D0\u06D1\u06D2\u06D3\u06D4\u06D5"+ - "\u06D6\u06D7\u06D8\u06D9\u06DA\u06DB\u06DC\u06DD"+ - "\u06DE\u06DF\u06E0\u06E1\u06E2\u06E3\u06E4\u06E5"+ - "\u06E6\u06E7\u06E8\u06E9\u06EA\u06EB\u06EC\u06ED"+ - "\u06EE\u06EF\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5"+ - "\u06F6\u06F7\u06F8\u06F9\u06FA\u06FB\u06FC\u06FD"+ - "\u06FE\u06FF\u0700\u0701\u0702\u0703\u0704\u0705"+ - "\u0706\u0707\u0708\u0709\u070A\u070B\u070C\u070D"+ - "\u070E\u070F\u0710\u0711\u0712\u0713\u0714\u0715"+ - "\u0716\u0717\u0718\u0719\u071A\u071B\u071C\u071D"+ - "\u071E\u071F\u0720\u0721\u0722\u0723\u0724\u0725"+ - "\u0726\u0727\u0728\u0729\u072A\u072B\u072C\u072D"+ - "\u072E\u072F\u0730\u0731\u0732\u0733\u0734\u0735"+ - "\u0736\u0737\u0738\u0739\u073A\u073B\u073C\u073D"+ - "\u073E\u073F\u0740\u0741\u0742\u0743\u0744\u0745"+ - "\u0746\u0747\u0748\u0749\u074A\u074B\u074C\u074D"+ - "\u074E\u074F\u0750\u0751\u0752\u0753\u0754\u0755"+ - "\u0756\u0757\u0758\u0759\u075A\u075B\u075C\u075D"+ - "\u075E\u075F\u0760\u0761\u0762\u0763\u0764\u0765"+ - "\u0766\u0767\u0768\u0769\u076A\u076B\u076C\u076D"+ - "\u076E\u076F\u0770\u0771\u0772\u0773\u0774\u0775"+ - "\u0776\u0777\u0778\u0779\u077A\u077B\u077C\u077D"+ - "\u077E\u077F\u0780\u0781\u0782\u0783\u0784\u0785"+ - "\u0786\u0787\u0788\u0789\u078A\u078B\u078C\u078D"+ - "\u078E\u078F\u0790\u0791\u0792\u0793\u0794\u0795"+ - "\u0796\u0797\u0798\u0799\u079A\u079B\u079C\u079D"+ - "\u079E\u079F\u07A0\u07A1\u07A2\u07A3\u07A4\u07A5"+ - "\u07A6\u07A7\u07A8\u07A9\u07AA\u07AB\u07AC\u07AD"+ - "\u07AE\u07AF\u07B0\u07B1\u07B2\u07B3\u07B4\u07B5"+ - "\u07B6\u07B7\u07B8\u07B9\u07BA\u07BB\u07BC\u07BD"+ - "\u07BE\u07BF\u07C0\u07C1\u07C2\u07C3\u07C4\u07C5"+ - "\u07C6\u07C7\u07C8\u07C9\u07CA\u07CB\u07CC\u07CD"+ - "\u07CE\u07CF\u07D0\u07D1\u07D2\u07D3\u07D4\u07D5"+ - "\u07D6\u07D7\u07D8\u07D9\u07DA\u07DB\u07DC\u07DD"+ - "\u07DE\u07DF\u07E0\u07E1\u07E2\u07E3\u07E4\u07E5"+ - "\u07E6\u07E7\u07E8\u07E9\u07EA\u07EB\u07EC\u07ED"+ - "\u07EE\u07EF\u07F0\u07F1\u07F2\u07F3\u07F4\u07F5"+ - "\u07F6\u07F7\u07F8\u07F9\u07FA\u07FB\u07FC\u07FD"+ - "\u07FE\u07FF\u0800\u0801\u0802\u0803\u0804\u0805"+ - "\u0806\u0807\u0808\u0809\u080A\u080B\u080C\u080D"+ - "\u080E\u080F\u0810\u0811\u0812\u0813\u0814\u0815"+ - "\u0816\u0817\u0818\u0819\u081A\u081B\u081C\u081D"+ - "\u081E\u081F\u0820\u0821\u0822\u0823\u0824\u0825"+ - "\u0826\u0827\u0828\u0829\u082A\u082B\u082C\u082D"+ - "\u082E\u082F\u0830\u0831\u0832\u0833\u0834\u0835"+ - "\u0836\u0837\u0838\u0839\u083A\u083B\u083C\u083D"+ - "\u083E\u083F\u0840\u0841\u0842\u0843\u0844\u0845"+ - "\u0846\u0847\u0848\u0849\u084A\u084B\u084C\u084D"+ - "\u084E\u084F\u0850\u0851\u0852\u0853\u0854\u0855"+ - "\u0856\u0857\u0858\u0859\u085A\u085B\u085C\u085D"+ - "\u085E\u085F\u0860\u0861\u0862\u0863\u0864\u0865"+ - "\u0866\u0867\u0868\u0869\u086A\u086B\u086C\u086D"+ - "\u086E\u086F\u0870\u0871\u0872\u0873\u0874\u0875"+ - "\u0876\u0877\u0878\u0879\u087A\u087B\u087C\u087D"+ - "\u087E\u087F\u0880\u0881\u0882\u0883\u0884\u0885"+ - "\u0886\u0887\u0888\u0889\u088A\u088B\u088C\u088D"+ - "\u088E\u088F\u0890\u0891\u0892\u0893\u0894\u0895"+ - "\u0896\u0897\u0898\u0899\u089A\u089B\u089C\u089D"+ - "\u089E\u089F\u08A0\u08A1\u08A2\u08A3\u08A4\u08A5"+ - "\u08A6\u08A7\u08A8\u08A9\u08AA\u08AB\u08AC\u08AD"+ - "\u08AE\u08AF\u08B0\u08B1\u08B2\u08B3\u08B4\u08B5"+ - "\u08B6\u08B7\u08B8\u08B9\u08BA\u08BB\u08BC\u08BD"+ - "\u08BE\u08BF\u08C0\u08C1\u08C2\u08C3\u08C4\u08C5"+ - "\u08C6\u08C7\u08C8\u08C9\u08CA\u08CB\u08CC\u08CD"+ - "\u08CE\u08CF\u08D0\u08D1\u08D2\u08D3\u08D4\u08D5"+ - "\u08D6\u08D7\u08D8\u08D9\u08DA\u08DB\u08DC\u08DD"+ - "\u08DE\u08DF\u08E0\u08E1\u08E2\u08E3\u08E4\u08E5"+ - "\u08E6\u08E7\u08E8\u08E9\u08EA\u08EB\u08EC\u08ED"+ - "\u08EE\u08EF\u08F0\u08F1\u08F2\u08F3\u08F4\u08F5"+ - "\u08F6\u08F7\u08F8\u08F9\u08FA\u08FB\u08FC\u08FD"+ - "\u08FE\u08FF\u0900\u0901\u0902\u0903\u0904\u0905"+ - "\u0906\u0907\u0908\u0909\u090A\u090B\u090C\u090D"+ - "\u090E\u090F\u0910\u0911\u0912\u0913\u0914\u0915"+ - "\u0916\u0917\u0918\u0919\u091A\u091B\u091C\u091D"+ - "\u091E\u091F\u0920\u0921\u0922\u0923\u0924\u0925"+ - "\u0926\u0927\u0928\u0929\u092A\u092B\u092C\u092D"+ - "\u092E\u092F\u0930\u0931\u0932\u0933\u0934\u0935"+ - "\u0936\u0937\u0938\u0939\u093A\u093B\u093C\u093D"+ - "\u093E\u093F\u0940\u0941\u0942\u0943\u0944\u0945"+ - "\u0946\u0947\u0948\u0949\u094A\u094B\u094C\u094D"+ - "\u094E\u094F\u0950\u0951\u0952\u0953\u0954\u0955"+ - "\u0956\u0957\u0958\u0959\u095A\u095B\u095C\u095D"+ - "\u095E\u095F\u0960\u0961\u0962\u0963\u0964\u0965"+ - "\u0966\u0967\u0968\u0969\u096A\u096B\u096C\u096D"+ - "\u096E\u096F\u0970\u0971\u0972\u0973\u0974\u0975"+ - "\u0976\u0977\u0978\u0979\u097A\u097B\u097C\u097D"+ - "\u097E\u097F\u0980\u0981\u0982\u0983\u0984\u0985"+ - "\u0986\u0987\u0988\u0989\u098A\u098B\u098C\u098D"+ - "\u098E\u098F\u0990\u0991\u0992\u0993\u0994\u0995"+ - "\u0996\u0997\u0998\u0999\u099A\u099B\u099C\u099D"+ - "\u099E\u099F\u09A0\u09A1\u09A2\u09A3\u09A4\u09A5"+ - "\u09A6\u09A7\u09A8\u09A9\u09AA\u09AB\u09AC\u09AD"+ - "\u09AE\u09AF\u09B0\u09B1\u09B2\u09B3\u09B4\u09B5"+ - "\u09B6\u09B7\u09B8\u09B9\u09BA\u09BB\u09BC\u09BD"+ - "\u09BE\u09BF\u09C0\u09C1\u09C2\u09C3\u09C4\u09C5"+ - "\u09C6\u09C7\u09C8\u09C9\u09CA\u09CB\u09CC\u09CD"+ - "\u09CE\u09CF\u09D0\u09D1\u09D2\u09D3\u09D4\u09D5"+ - "\u09D6\u09D7\u09D8\u09D9\u09DA\u09DB\u09DC\u09DD"+ - "\u09DE\u09DF\u09E0\u09E1\u09E2\u09E3\u09E4\u09E5"+ - "\u09E6\u09E7\u09E8\u09E9\u09EA\u09EB\u09EC\u09ED"+ - "\u09EE\u09EF\u09F0\u09F1\u09F2\u09F3\u09F4\u09F5"+ - "\u09F6\u09F7\u09F8\u09F9\u09FA\u09FB\u09FC\u09FD"+ - "\u09FE\u09FF\u0A00\u0A01\u0A02\u0A03\u0A04\u0A05"+ - "\u0A06\u0A07\u0A08\u0A09\u0A0A\u0A0B\u0A0C\u0A0D"+ - "\u0A0E\u0A0F\u0A10\u0A11\u0A12\u0A13\u0A14\u0A15"+ - "\u0A16\u0A17\u0A18\u0A19\u0A1A\u0A1B\u0A1C\u0A1D"+ - "\u0A1E\u0A1F\u0A20\u0A21\u0A22\u0A23\u0A24\u0A25"+ - "\u0A26\u0A27\u0A28\u0A29\u0A2A\u0A2B\u0A2C\u0A2D"+ - "\u0A2E\u0A2F\u0A30\u0A31\u0A32\u0A33\u0A34\u0A35"+ - "\u0A36\u0A37\u0A38\u0A39\u0A3A\u0A3B\u0A3C\u0A3D"+ - "\u0A3E\u0A3F\u0A40\u0A41\u0A42\u0A43\u0A44\u0A45"+ - "\u0A46\u0A47\u0A48\u0A49\u0A4A\u0A4B\u0A4C\u0A4D"+ - "\u0A4E\u0A4F\u0A50\u0A51\u0A52\u0A53\u0A54\u0A55"+ - "\u0A56\u0A57\u0A58\u0A59\u0A5A\u0A5B\u0A5C\u0A5D"+ - "\u0A5E\u0A5F\u0A60\u0A61\u0A62\u0A63\u0A64\u0A65"+ - "\u0A66\u0A67\u0A68\u0A69\u0A6A\u0A6B\u0A6C\u0A6D"+ - "\u0A6E\u0A6F\u0A70\u0A71\u0A72\u0A73\u0A74\u0A75"+ - "\u0A76\u0A77\u0A78\u0A79\u0A7A\u0A7B\u0A7C\u0A7D"+ - "\u0A7E\u0A7F\u0A80\u0A81\u0A82\u0A83\u0A84\u0A85"+ - "\u0A86\u0A87\u0A88\u0A89\u0A8A\u0A8B\u0A8C\u0A8D"+ - "\u0A8E\u0A8F\u0A90\u0A91\u0A92\u0A93\u0A94\u0A95"+ - "\u0A96\u0A97\u0A98\u0A99\u0A9A\u0A9B\u0A9C\u0A9D"+ - "\u0A9E\u0A9F\u0AA0\u0AA1\u0AA2\u0AA3\u0AA4\u0AA5"+ - "\u0AA6\u0AA7\u0AA8\u0AA9\u0AAA\u0AAB\u0AAC\u0AAD"+ - "\u0AAE\u0AAF\u0AB0\u0AB1\u0AB2\u0AB3\u0AB4\u0AB5"+ - "\u0AB6\u0AB7\u0AB8\u0AB9\u0ABA\u0ABB\u0ABC\u0ABD"+ - "\u0ABE\u0ABF\u0AC0\u0AC1\u0AC2\u0AC3\u0AC4\u0AC5"+ - "\u0AC6\u0AC7\u0AC8\u0AC9\u0ACA\u0ACB\u0ACC\u0ACD"+ - "\u0ACE\u0ACF\u0AD0\u0AD1\u0AD2\u0AD3\u0AD4\u0AD5"+ - "\u0AD6\u0AD7\u0AD8\u0AD9\u0ADA\u0ADB\u0ADC\u0ADD"+ - "\u0ADE\u0ADF\u0AE0\u0AE1\u0AE2\u0AE3\u0AE4\u0AE5"+ - "\u0AE6\u0AE7\u0AE8\u0AE9\u0AEA\u0AEB\u0AEC\u0AED"+ - "\u0AEE\u0AEF\u0AF0\u0AF1\u0AF2\u0AF3\u0AF4\u0AF5"+ - "\u0AF6\u0AF7\u0AF8\u0AF9\u0AFA\u0AFB\u0AFC\u0AFD"+ - "\u0AFE\u0AFF\u0B00\u0B01\u0B02\u0B03\u0B04\u0B05"+ - "\u0B06\u0B07\u0B08\u0B09\u0B0A\u0B0B\u0B0C\u0B0D"+ - "\u0B0E\u0B0F\u0B10\u0B11\u0B12\u0B13\u0B14\u0B15"+ - "\u0B16\u0B17\u0B18\u0B19\u0B1A\u0B1B\u0B1C\u0B1D"+ - "\u0B1E\u0B1F\u0B20\u0B21\u0B22\u0B23\u0B24\u0B25"+ - "\u0B26\u0B27\u0B28\u0B29\u0B2A\u0B2B\u0B2C\u0B2D"+ - "\u0B2E\u0B2F\u0B30\u0B31\u0B32\u0B33\u0B34\u0B35"+ - "\u0B36\u0B37\u0B38\u0B39\u0B3A\u0B3B\u0B3C\u0B3D"+ - "\u0B3E\u0B3F\u0B40\u0B41\u0B42\u0B43\u0B44\u0B45"+ - "\u0B46\u0B47\u0B48\u0B49\u0B4A\u0B4B\u0B4C\u0B4D"+ - "\u0B4E\u0B4F\u0B50\u0B51\u0B52\u0B53\u0B54\u0B55"+ - "\u0B56\u0B57\u0B58\u0B59\u0B5A\u0B5B\u0B5C\u0B5D"+ - "\u0B5E\u0B5F\u0B60\u0B61\u0B62\u0B63\u0B64\u0B65"+ - "\u0B66\u0B67\u0B68\u0B69\u0B6A\u0B6B\u0B6C\u0B6D"+ - "\u0B6E\u0B6F\u0B70\u0B71\u0B72\u0B73\u0B74\u0B75"+ - "\u0B76\u0B77\u0B78\u0B79\u0B7A\u0B7B\u0B7C\u0B7D"+ - "\u0B7E\u0B7F\u0B80\u0B81\u0B82\u0B83\u0B84\u0B85"+ - "\u0B86\u0B87\u0B88\u0B89\u0B8A\u0B8B\u0B8C\u0B8D"+ - "\u0B8E\u0B8F\u0B90\u0B91\u0B92\u0B93\u0B94\u0B95"+ - "\u0B96\u0B97\u0B98\u0B99\u0B9A\u0B9B\u0B9C\u0B9D"+ - "\u0B9E\u0B9F\u0BA0\u0BA1\u0BA2\u0BA3\u0BA4\u0BA5"+ - "\u0BA6\u0BA7\u0BA8\u0BA9\u0BAA\u0BAB\u0BAC\u0BAD"+ - "\u0BAE\u0BAF\u0BB0\u0BB1\u0BB2\u0BB3\u0BB4\u0BB5"+ - "\u0BB6\u0BB7\u0BB8\u0BB9\u0BBA\u0BBB\u0BBC\u0BBD"+ - "\u0BBE\u0BBF\u0BC0\u0BC1\u0BC2\u0BC3\u0BC4\u0BC5"+ - "\u0BC6\u0BC7\u0BC8\u0BC9\u0BCA\u0BCB\u0BCC\u0BCD"+ - "\u0BCE\u0BCF\u0BD0\u0BD1\u0BD2\u0BD3\u0BD4\u0BD5"+ - "\u0BD6\u0BD7\u0BD8\u0BD9\u0BDA\u0BDB\u0BDC\u0BDD"+ - "\u0BDE\u0BDF\u0BE0\u0BE1\u0BE2\u0BE3\u0BE4\u0BE5"+ - "\u0BE6\u0BE7\u0BE8\u0BE9\u0BEA\u0BEB\u0BEC\u0BED"+ - "\u0BEE\u0BEF\u0BF0\u0BF1\u0BF2\u0BF3\u0BF4\u0BF5"+ - "\u0BF6\u0BF7\u0BF8\u0BF9\u0BFA\u0BFB\u0BFC\u0BFD"+ - "\u0BFE\u0BFF\u0C00\u0C01\u0C02\u0C03\u0C04\u0C05"+ - "\u0C06\u0C07\u0C08\u0C09\u0C0A\u0C0B\u0C0C\u0C0D"+ - "\u0C0E\u0C0F\u0C10\u0C11\u0C12\u0C13\u0C14\u0C15"+ - "\u0C16\u0C17\u0C18\u0C19\u0C1A\u0C1B\u0C1C\u0C1D"+ - "\u0C1E\u0C1F\u0C20\u0C21\u0C22\u0C23\u0C24\u0C25"+ - "\u0C26\u0C27\u0C28\u0C29\u0C2A\u0C2B\u0C2C\u0C2D"+ - "\u0C2E\u0C2F\u0C30\u0C31\u0C32\u0C33\u0C34\u0C35"+ - "\u0C36\u0C37\u0C38\u0C39\u0C3A\u0C3B\u0C3C\u0C3D"+ - "\u0C3E\u0C3F\u0C40\u0C41\u0C42\u0C43\u0C44\u0C45"+ - "\u0C46\u0C47\u0C48\u0C49\u0C4A\u0C4B\u0C4C\u0C4D"+ - "\u0C4E\u0C4F\u0C50\u0C51\u0C52\u0C53\u0C54\u0C55"+ - "\u0C56\u0C57\u0C58\u0C59\u0C5A\u0C5B\u0C5C\u0C5D"+ - "\u0C5E\u0C5F\u0C60\u0C61\u0C62\u0C63\u0C64\u0C65"+ - "\u0C66\u0C67\u0C68\u0C69\u0C6A\u0C6B\u0C6C\u0C6D"+ - "\u0C6E\u0C6F\u0C70\u0C71\u0C72\u0C73\u0C74\u0C75"+ - "\u0C76\u0C77\u0C78\u0C79\u0C7A\u0C7B\u0C7C\u0C7D"+ - "\u0C7E\u0C7F\u0C80\u0C81\u0C82\u0C83\u0C84\u0C85"+ - "\u0C86\u0C87\u0C88\u0C89\u0C8A\u0C8B\u0C8C\u0C8D"+ - "\u0C8E\u0C8F\u0C90\u0C91\u0C92\u0C93\u0C94\u0C95"+ - "\u0C96\u0C97\u0C98\u0C99\u0C9A\u0C9B\u0C9C\u0C9D"+ - "\u0C9E\u0C9F\u0CA0\u0CA1\u0CA2\u0CA3\u0CA4\u0CA5"+ - "\u0CA6\u0CA7\u0CA8\u0CA9\u0CAA\u0CAB\u0CAC\u0CAD"+ - "\u0CAE\u0CAF\u0CB0\u0CB1\u0CB2\u0CB3\u0CB4\u0CB5"+ - "\u0CB6\u0CB7\u0CB8\u0CB9\u0CBA\u0CBB\u0CBC\u0CBD"+ - "\u0CBE\u0CBF\u0CC0\u0CC1\u0CC2\u0CC3\u0CC4\u0CC5"+ - "\u0CC6\u0CC7\u0CC8\u0CC9\u0CCA\u0CCB\u0CCC\u0CCD"+ - "\u0CCE\u0CCF\u0CD0\u0CD1\u0CD2\u0CD3\u0CD4\u0CD5"+ - "\u0CD6\u0CD7\u0CD8\u0CD9\u0CDA\u0CDB\u0CDC\u0CDD"+ - "\u0CDE\u0CDF\u0CE0\u0CE1\u0CE2\u0CE3\u0CE4\u0CE5"+ - "\u0CE6\u0CE7\u0CE8\u0CE9\u0CEA\u0CEB\u0CEC\u0CED"+ - "\u0CEE\u0CEF\u0CF0\u0CF1\u0CF2\u0CF3\u0CF4\u0CF5"+ - "\u0CF6\u0CF7\u0CF8\u0CF9\u0CFA\u0CFB\u0CFC\u0CFD"+ - "\u0CFE\u0CFF\u0D00\u0D01\u0D02\u0D03\u0D04\u0D05"+ - "\u0D06\u0D07\u0D08\u0D09\u0D0A\u0D0B\u0D0C\u0D0D"+ - "\u0D0E\u0D0F\u0D10\u0D11\u0D12\u0D13\u0D14\u0D15"+ - "\u0D16\u0D17\u0D18\u0D19\u0D1A\u0D1B\u0D1C\u0D1D"+ - "\u0D1E\u0D1F\u0D20\u0D21\u0D22\u0D23\u0D24\u0D25"+ - "\u0D26\u0D27\u0D28\u0D29\u0D2A\u0D2B\u0D2C\u0D2D"+ - "\u0D2E\u0D2F\u0D30\u0D31\u0D32\u0D33\u0D34\u0D35"+ - "\u0D36\u0D37\u0D38\u0D39\u0D3A\u0D3B\u0D3C\u0D3D"+ - "\u0D3E\u0D3F\u0D40\u0D41\u0D42\u0D43\u0D44\u0D45"+ - "\u0D46\u0D47\u0D48\u0D49\u0D4A\u0D4B\u0D4C\u0D4D"+ - "\u0D4E\u0D4F\u0D50\u0D51\u0D52\u0D53\u0D54\u0D55"+ - "\u0D56\u0D57\u0D58\u0D59\u0D5A\u0D5B\u0D5C\u0D5D"+ - "\u0D5E\u0D5F\u0D60\u0D61\u0D62\u0D63\u0D64\u0D65"+ - "\u0D66\u0D67\u0D68\u0D69\u0D6A\u0D6B\u0D6C\u0D6D"+ - "\u0D6E\u0D6F\u0D70\u0D71\u0D72\u0D73\u0D74\u0D75"+ - "\u0D76\u0D77\u0D78\u0D79\u0D7A\u0D7B\u0D7C\u0D7D"+ - "\u0D7E\u0D7F\u0D80\u0D81\u0D82\u0D83\u0D84\u0D85"+ - "\u0D86\u0D87\u0D88\u0D89\u0D8A\u0D8B\u0D8C\u0D8D"+ - "\u0D8E\u0D8F\u0D90\u0D91\u0D92\u0D93\u0D94\u0D95"+ - "\u0D96\u0D97\u0D98\u0D99\u0D9A\u0D9B\u0D9C\u0D9D"+ - "\u0D9E\u0D9F\u0DA0\u0DA1\u0DA2\u0DA3\u0DA4\u0DA5"+ - "\u0DA6\u0DA7\u0DA8\u0DA9\u0DAA\u0DAB\u0DAC\u0DAD"+ - "\u0DAE\u0DAF\u0DB0\u0DB1\u0DB2\u0DB3\u0DB4\u0DB5"+ - "\u0DB6\u0DB7\u0DB8\u0DB9\u0DBA\u0DBB\u0DBC\u0DBD"+ - "\u0DBE\u0DBF\u0DC0\u0DC1\u0DC2\u0DC3\u0DC4\u0DC5"+ - "\u0DC6\u0DC7\u0DC8\u0DC9\u0DCA\u0DCB\u0DCC\u0DCD"+ - "\u0DCE\u0DCF\u0DD0\u0DD1\u0DD2\u0DD3\u0DD4\u0DD5"+ - "\u0DD6\u0DD7\u0DD8\u0DD9\u0DDA\u0DDB\u0DDC\u0DDD"+ - "\u0DDE\u0DDF\u0DE0\u0DE1\u0DE2\u0DE3\u0DE4\u0DE5"+ - "\u0DE6\u0DE7\u0DE8\u0DE9\u0DEA\u0DEB\u0DEC\u0DED"+ - "\u0DEE\u0DEF\u0DF0\u0DF1\u0DF2\u0DF3\u0DF4\u0DF5"+ - "\u0DF6\u0DF7\u0DF8\u0DF9\u0DFA\u0DFB\u0DFC\u0DFD"+ - "\u0DFE\u0DFF\u0E00\u0E01\u0E02\u0E03\u0E04\u0E05"+ - "\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D"+ - "\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15"+ - "\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D"+ - "\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25"+ - "\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D"+ - "\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35"+ - "\u0E36\u0E37\u0E38\u0E39\u0E3A\u0E3B\u0E3C\u0E3D"+ - "\u0E3E\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45"+ - "\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D"+ - "\u0E4E\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55"+ - "\u0E56\u0E57\u0E58\u0E59\u0E5A\u0E5B\u0E5C\u0E5D"+ - "\u0E5E\u0E5F\u0E60\u0E61\u0E62\u0E63\u0E64\u0E65"+ - "\u0E66\u0E67\u0E68\u0E69\u0E6A\u0E6B\u0E6C\u0E6D"+ - "\u0E6E\u0E6F\u0E70\u0E71\u0E72\u0E73\u0E74\u0E75"+ - "\u0E76\u0E77\u0E78\u0E79\u0E7A\u0E7B\u0E7C\u0E7D"+ - "\u0E7E\u0E7F\u0E80\u0E81\u0E82\u0E83\u0E84\u0E85"+ - "\u0E86\u0E87\u0E88\u0E89\u0E8A\u0E8B\u0E8C\u0E8D"+ - "\u0E8E\u0E8F\u0E90\u0E91\u0E92\u0E93\u0E94\u0E95"+ - "\u0E96\u0E97\u0E98\u0E99\u0E9A\u0E9B\u0E9C\u0E9D"+ - "\u0E9E\u0E9F\u0EA0\u0EA1\u0EA2\u0EA3\u0EA4\u0EA5"+ - "\u0EA6\u0EA7\u0EA8\u0EA9\u0EAA\u0EAB\u0EAC\u0EAD"+ - "\u0EAE\u0EAF\u0EB0\u0EB1\u0EB2\u0EB3\u0EB4\u0EB5"+ - "\u0EB6\u0EB7\u0EB8\u0EB9\u0EBA\u0EBB\u0EBC\u0EBD"+ - "\u0EBE\u0EBF\u0EC0\u0EC1\u0EC2\u0EC3\u0EC4\u0EC5"+ - "\u0EC6\u0EC7\u0EC8\u0EC9\u0ECA\u0ECB\u0ECC\u0ECD"+ - "\u0ECE\u0ECF\u0ED0\u0ED1\u0ED2\u0ED3\u0ED4\u0ED5"+ - "\u0ED6\u0ED7\u0ED8\u0ED9\u0EDA\u0EDB\u0EDC\u0EDD"+ - "\u0EDE\u0EDF\u0EE0\u0EE1\u0EE2\u0EE3\u0EE4\u0EE5"+ - "\u0EE6\u0EE7\u0EE8\u0EE9\u0EEA\u0EEB\u0EEC\u0EED"+ - "\u0EEE\u0EEF\u0EF0\u0EF1\u0EF2\u0EF3\u0EF4\u0EF5"+ - "\u0EF6\u0EF7\u0EF8\u0EF9\u0EFA\u0EFB\u0EFC\u0EFD"+ - "\u0EFE\u0EFF\u0F00\u0F01\u0F02\u0F03\u0F04\u0F05"+ - "\u0F06\u0F07\u0F08\u0F09\u0F0A\u0F0B\u0F0C\u0F0D"+ - "\u0F0E\u0F0F\u0F10\u0F11\u0F12\u0F13\u0F14\u0F15"+ - "\u0F16\u0F17\u0F18\u0F19\u0F1A\u0F1B\u0F1C\u0F1D"+ - "\u0F1E\u0F1F\u0F20\u0F21\u0F22\u0F23\u0F24\u0F25"+ - "\u0F26\u0F27\u0F28\u0F29\u0F2A\u0F2B\u0F2C\u0F2D"+ - "\u0F2E\u0F2F\u0F30\u0F31\u0F32\u0F33\u0F34\u0F35"+ - "\u0F36\u0F37\u0F38\u0F39\u0F3A\u0F3B\u0F3C\u0F3D"+ - "\u0F3E\u0F3F\u0F40\u0F41\u0F42\u0F43\u0F44\u0F45"+ - "\u0F46\u0F47\u0F48\u0F49\u0F4A\u0F4B\u0F4C\u0F4D"+ - "\u0F4E\u0F4F\u0F50\u0F51\u0F52\u0F53\u0F54\u0F55"+ - "\u0F56\u0F57\u0F58\u0F59\u0F5A\u0F5B\u0F5C\u0F5D"+ - "\u0F5E\u0F5F\u0F60\u0F61\u0F62\u0F63\u0F64\u0F65"+ - "\u0F66\u0F67\u0F68\u0F69\u0F6A\u0F6B\u0F6C\u0F6D"+ - "\u0F6E\u0F6F\u0F70\u0F71\u0F72\u0F73\u0F74\u0F75"+ - "\u0F76\u0F77\u0F78\u0F79\u0F7A\u0F7B\u0F7C\u0F7D"+ - "\u0F7E\u0F7F\u0F80\u0F81\u0F82\u0F83\u0F84\u0F85"+ - "\u0F86\u0F87\u0F88\u0F89\u0F8A\u0F8B\u0F8C\u0F8D"+ - "\u0F8E\u0F8F\u0F90\u0F91\u0F92\u0F93\u0F94\u0F95"+ - "\u0F96\u0F97\u0F98\u0F99\u0F9A\u0F9B\u0F9C\u0F9D"+ - "\u0F9E\u0F9F\u0FA0\u0FA1\u0FA2\u0FA3\u0FA4\u0FA5"+ - "\u0FA6\u0FA7\u0FA8\u0FA9\u0FAA\u0FAB\u0FAC\u0FAD"+ - "\u0FAE\u0FAF\u0FB0\u0FB1\u0FB2\u0FB3\u0FB4\u0FB5"+ - "\u0FB6\u0FB7\u0FB8\u0FB9\u0FBA\u0FBB\u0FBC\u0FBD"+ - "\u0FBE\u0FBF\u0FC0\u0FC1\u0FC2\u0FC3\u0FC4\u0FC5"+ - "\u0FC6\u0FC7\u0FC8\u0FC9\u0FCA\u0FCB\u0FCC\u0FCD"+ - "\u0FCE\u0FCF\u0FD0\u0FD1\u0FD2\u0FD3\u0FD4\u0FD5"+ - "\u0FD6\u0FD7\u0FD8\u0FD9\u0FDA\u0FDB\u0FDC\u0FDD"+ - "\u0FDE\u0FDF\u0FE0\u0FE1\u0FE2\u0FE3\u0FE4\u0FE5"+ - "\u0FE6\u0FE7\u0FE8\u0FE9\u0FEA\u0FEB\u0FEC\u0FED"+ - "\u0FEE\u0FEF\u0FF0\u0FF1\u0FF2\u0FF3\u0FF4\u0FF5"+ - "\u0FF6\u0FF7\u0FF8\u0FF9\u0FFA\u0FFB\u0FFC\u0FFD"+ - "\u0FFE\u0FFF\u1000\u1001\u1002\u1003\u1004\u1005"+ - "\u1006\u1007\u1008\u1009\u100A\u100B\u100C\u100D"+ - "\u100E\u100F\u1010\u1011\u1012\u1013\u1014\u1015"+ - "\u1016\u1017\u1018\u1019\u101A\u101B\u101C\u101D"+ - "\u101E\u101F\u1020\u1021\u1022\u1023\u1024\u1025"+ - "\u1026\u1027\u1028\u1029\u102A\u102B\u102C\u102D"+ - "\u102E\u102F\u1030\u1031\u1032\u1033\u1034\u1035"+ - "\u1036\u1037\u1038\u1039\u103A\u103B\u103C\u103D"+ - "\u103E\u103F\u1040\u1041\u1042\u1043\u1044\u1045"+ - "\u1046\u1047\u1048\u1049\u104A\u104B\u104C\u104D"+ - "\u104E\u104F\u1050\u1051\u1052\u1053\u1054\u1055"+ - "\u1056\u1057\u1058\u1059\u105A\u105B\u105C\u105D"+ - "\u105E\u105F\u1060\u1061\u1062\u1063\u1064\u1065"+ - "\u1066\u1067\u1068\u1069\u106A\u106B\u106C\u106D"+ - "\u106E\u106F\u1070\u1071\u1072\u1073\u1074\u1075"+ - "\u1076\u1077\u1078\u1079\u107A\u107B\u107C\u107D"+ - "\u107E\u107F\u1080\u1081\u1082\u1083\u1084\u1085"+ - "\u1086\u1087\u1088\u1089\u108A\u108B\u108C\u108D"+ - "\u108E\u108F\u1090\u1091\u1092\u1093\u1094\u1095"+ - "\u1096\u1097\u1098\u1099\u109A\u109B\u109C\u109D"+ - "\u109E\u109F\u10A0\u10A1\u10A2\u10A3\u10A4\u10A5"+ - "\u10A6\u10A7\u10A8\u10A9\u10AA\u10AB\u10AC\u10AD"+ - "\u10AE\u10AF\u10B0\u10B1\u10B2\u10B3\u10B4\u10B5"+ - "\u10B6\u10B7\u10B8\u10B9\u10BA\u10BB\u10BC\u10BD"+ - "\u10BE\u10BF\u10C0\u10C1\u10C2\u10C3\u10C4\u10C5"+ - "\u10C6\u10C7\u10C8\u10C9\u10CA\u10CB\u10CC\u10CD"+ - "\u10CE\u10CF\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5"+ - "\u10D6\u10D7\u10D8\u10D9\u10DA\u10DB\u10DC\u10DD"+ - "\u10DE\u10DF\u10E0\u10E1\u10E2\u10E3\u10E4\u10E5"+ - "\u10E6\u10E7\u10E8\u10E9\u10EA\u10EB\u10EC\u10ED"+ - "\u10EE\u10EF\u10F0\u10F1\u10F2\u10F3\u10F4\u10F5"+ - "\u10F6\u10F7\u10F8\u10F9\u10FA\u10FB\u10FC\u10FD"+ - "\u10FE\u10FF\u1100\u1101\u1102\u1103\u1104\u1105"+ - "\u1106\u1107\u1108\u1109\u110A\u110B\u110C\u110D"+ - "\u110E\u110F\u1110\u1111\u1112\u1113\u1114\u1115"+ - "\u1116\u1117\u1118\u1119\u111A\u111B\u111C\u111D"; - - private static final String innerDecoderIndex1= - "\u111E\u111F\u1120\u1121\u1122\u1123\u1124\u1125"+ - "\u1126\u1127\u1128\u1129\u112A\u112B\u112C\u112D"+ - "\u112E\u112F\u1130\u1131\u1132\u1133\u1134\u1135"+ - "\u1136\u1137\u1138\u1139\u113A\u113B\u113C\u113D"+ - "\u113E\u113F\u1140\u1141\u1142\u1143\u1144\u1145"+ - "\u1146\u1147\u1148\u1149\u114A\u114B\u114C\u114D"+ - "\u114E\u114F\u1150\u1151\u1152\u1153\u1154\u1155"+ - "\u1156\u1157\u1158\u1159\u115A\u115B\u115C\u115D"+ - "\u115E\u115F\u1160\u1161\u1162\u1163\u1164\u1165"+ - "\u1166\u1167\u1168\u1169\u116A\u116B\u116C\u116D"+ - "\u116E\u116F\u1170\u1171\u1172\u1173\u1174\u1175"+ - "\u1176\u1177\u1178\u1179\u117A\u117B\u117C\u117D"+ - "\u117E\u117F\u1180\u1181\u1182\u1183\u1184\u1185"+ - "\u1186\u1187\u1188\u1189\u118A\u118B\u118C\u118D"+ - "\u118E\u118F\u1190\u1191\u1192\u1193\u1194\u1195"+ - "\u1196\u1197\u1198\u1199\u119A\u119B\u119C\u119D"+ - "\u119E\u119F\u11A0\u11A1\u11A2\u11A3\u11A4\u11A5"+ - "\u11A6\u11A7\u11A8\u11A9\u11AA\u11AB\u11AC\u11AD"+ - "\u11AE\u11AF\u11B0\u11B1\u11B2\u11B3\u11B4\u11B5"+ - "\u11B6\u11B7\u11B8\u11B9\u11BA\u11BB\u11BC\u11BD"+ - "\u11BE\u11BF\u11C0\u11C1\u11C2\u11C3\u11C4\u11C5"+ - "\u11C6\u11C7\u11C8\u11C9\u11CA\u11CB\u11CC\u11CD"+ - "\u11CE\u11CF\u11D0\u11D1\u11D2\u11D3\u11D4\u11D5"+ - "\u11D6\u11D7\u11D8\u11D9\u11DA\u11DB\u11DC\u11DD"+ - "\u11DE\u11DF\u11E0\u11E1\u11E2\u11E3\u11E4\u11E5"+ - "\u11E6\u11E7\u11E8\u11E9\u11EA\u11EB\u11EC\u11ED"+ - "\u11EE\u11EF\u11F0\u11F1\u11F2\u11F3\u11F4\u11F5"+ - "\u11F6\u11F7\u11F8\u11F9\u11FA\u11FB\u11FC\u11FD"+ - "\u11FE\u11FF\u1200\u1201\u1202\u1203\u1204\u1205"+ - "\u1206\u1207\u1208\u1209\u120A\u120B\u120C\u120D"+ - "\u120E\u120F\u1210\u1211\u1212\u1213\u1214\u1215"+ - "\u1216\u1217\u1218\u1219\u121A\u121B\u121C\u121D"+ - "\u121E\u121F\u1220\u1221\u1222\u1223\u1224\u1225"+ - "\u1226\u1227\u1228\u1229\u122A\u122B\u122C\u122D"+ - "\u122E\u122F\u1230\u1231\u1232\u1233\u1234\u1235"+ - "\u1236\u1237\u1238\u1239\u123A\u123B\u123C\u123D"+ - "\u123E\u123F\u1240\u1241\u1242\u1243\u1244\u1245"+ - "\u1246\u1247\u1248\u1249\u124A\u124B\u124C\u124D"+ - "\u124E\u124F\u1250\u1251\u1252\u1253\u1254\u1255"+ - "\u1256\u1257\u1258\u1259\u125A\u125B\u125C\u125D"+ - "\u125E\u125F\u1260\u1261\u1262\u1263\u1264\u1265"+ - "\u1266\u1267\u1268\u1269\u126A\u126B\u126C\u126D"+ - "\u126E\u126F\u1270\u1271\u1272\u1273\u1274\u1275"+ - "\u1276\u1277\u1278\u1279\u127A\u127B\u127C\u127D"+ - "\u127E\u127F\u1280\u1281\u1282\u1283\u1284\u1285"+ - "\u1286\u1287\u1288\u1289\u128A\u128B\u128C\u128D"+ - "\u128E\u128F\u1290\u1291\u1292\u1293\u1294\u1295"+ - "\u1296\u1297\u1298\u1299\u129A\u129B\u129C\u129D"+ - "\u129E\u129F\u12A0\u12A1\u12A2\u12A3\u12A4\u12A5"+ - "\u12A6\u12A7\u12A8\u12A9\u12AA\u12AB\u12AC\u12AD"+ - "\u12AE\u12AF\u12B0\u12B1\u12B2\u12B3\u12B4\u12B5"+ - "\u12B6\u12B7\u12B8\u12B9\u12BA\u12BB\u12BC\u12BD"+ - "\u12BE\u12BF\u12C0\u12C1\u12C2\u12C3\u12C4\u12C5"+ - "\u12C6\u12C7\u12C8\u12C9\u12CA\u12CB\u12CC\u12CD"+ - "\u12CE\u12CF\u12D0\u12D1\u12D2\u12D3\u12D4\u12D5"+ - "\u12D6\u12D7\u12D8\u12D9\u12DA\u12DB\u12DC\u12DD"+ - "\u12DE\u12DF\u12E0\u12E1\u12E2\u12E3\u12E4\u12E5"+ - "\u12E6\u12E7\u12E8\u12E9\u12EA\u12EB\u12EC\u12ED"+ - "\u12EE\u12EF\u12F0\u12F1\u12F2\u12F3\u12F4\u12F5"+ - "\u12F6\u12F7\u12F8\u12F9\u12FA\u12FB\u12FC\u12FD"+ - "\u12FE\u12FF\u1300\u1301\u1302\u1303\u1304\u1305"+ - "\u1306\u1307\u1308\u1309\u130A\u130B\u130C\u130D"+ - "\u130E\u130F\u1310\u1311\u1312\u1313\u1314\u1315"+ - "\u1316\u1317\u1318\u1319\u131A\u131B\u131C\u131D"+ - "\u131E\u131F\u1320\u1321\u1322\u1323\u1324\u1325"+ - "\u1326\u1327\u1328\u1329\u132A\u132B\u132C\u132D"+ - "\u132E\u132F\u1330\u1331\u1332\u1333\u1334\u1335"+ - "\u1336\u1337\u1338\u1339\u133A\u133B\u133C\u133D"+ - "\u133E\u133F\u1340\u1341\u1342\u1343\u1344\u1345"+ - "\u1346\u1347\u1348\u1349\u134A\u134B\u134C\u134D"+ - "\u134E\u134F\u1350\u1351\u1352\u1353\u1354\u1355"+ - "\u1356\u1357\u1358\u1359\u135A\u135B\u135C\u135D"+ - "\u135E\u135F\u1360\u1361\u1362\u1363\u1364\u1365"+ - "\u1366\u1367\u1368\u1369\u136A\u136B\u136C\u136D"+ - "\u136E\u136F\u1370\u1371\u1372\u1373\u1374\u1375"+ - "\u1376\u1377\u1378\u1379\u137A\u137B\u137C\u137D"+ - "\u137E\u137F\u1380\u1381\u1382\u1383\u1384\u1385"+ - "\u1386\u1387\u1388\u1389\u138A\u138B\u138C\u138D"+ - "\u138E\u138F\u1390\u1391\u1392\u1393\u1394\u1395"+ - "\u1396\u1397\u1398\u1399\u139A\u139B\u139C\u139D"+ - "\u139E\u139F\u13A0\u13A1\u13A2\u13A3\u13A4\u13A5"+ - "\u13A6\u13A7\u13A8\u13A9\u13AA\u13AB\u13AC\u13AD"+ - "\u13AE\u13AF\u13B0\u13B1\u13B2\u13B3\u13B4\u13B5"+ - "\u13B6\u13B7\u13B8\u13B9\u13BA\u13BB\u13BC\u13BD"+ - "\u13BE\u13BF\u13C0\u13C1\u13C2\u13C3\u13C4\u13C5"+ - "\u13C6\u13C7\u13C8\u13C9\u13CA\u13CB\u13CC\u13CD"+ - "\u13CE\u13CF\u13D0\u13D1\u13D2\u13D3\u13D4\u13D5"+ - "\u13D6\u13D7\u13D8\u13D9\u13DA\u13DB\u13DC\u13DD"+ - "\u13DE\u13DF\u13E0\u13E1\u13E2\u13E3\u13E4\u13E5"+ - "\u13E6\u13E7\u13E8\u13E9\u13EA\u13EB\u13EC\u13ED"+ - "\u13EE\u13EF\u13F0\u13F1\u13F2\u13F3\u13F4\u13F5"+ - "\u13F6\u13F7\u13F8\u13F9\u13FA\u13FB\u13FC\u13FD"+ - "\u13FE\u13FF\u1400\u1401\u1402\u1403\u1404\u1405"+ - "\u1406\u1407\u1408\u1409\u140A\u140B\u140C\u140D"+ - "\u140E\u140F\u1410\u1411\u1412\u1413\u1414\u1415"+ - "\u1416\u1417\u1418\u1419\u141A\u141B\u141C\u141D"+ - "\u141E\u141F\u1420\u1421\u1422\u1423\u1424\u1425"+ - "\u1426\u1427\u1428\u1429\u142A\u142B\u142C\u142D"+ - "\u142E\u142F\u1430\u1431\u1432\u1433\u1434\u1435"+ - "\u1436\u1437\u1438\u1439\u143A\u143B\u143C\u143D"+ - "\u143E\u143F\u1440\u1441\u1442\u1443\u1444\u1445"+ - "\u1446\u1447\u1448\u1449\u144A\u144B\u144C\u144D"+ - "\u144E\u144F\u1450\u1451\u1452\u1453\u1454\u1455"+ - "\u1456\u1457\u1458\u1459\u145A\u145B\u145C\u145D"+ - "\u145E\u145F\u1460\u1461\u1462\u1463\u1464\u1465"+ - "\u1466\u1467\u1468\u1469\u146A\u146B\u146C\u146D"+ - "\u146E\u146F\u1470\u1471\u1472\u1473\u1474\u1475"+ - "\u1476\u1477\u1478\u1479\u147A\u147B\u147C\u147D"+ - "\u147E\u147F\u1480\u1481\u1482\u1483\u1484\u1485"+ - "\u1486\u1487\u1488\u1489\u148A\u148B\u148C\u148D"+ - "\u148E\u148F\u1490\u1491\u1492\u1493\u1494\u1495"+ - "\u1496\u1497\u1498\u1499\u149A\u149B\u149C\u149D"+ - "\u149E\u149F\u14A0\u14A1\u14A2\u14A3\u14A4\u14A5"+ - "\u14A6\u14A7\u14A8\u14A9\u14AA\u14AB\u14AC\u14AD"+ - "\u14AE\u14AF\u14B0\u14B1\u14B2\u14B3\u14B4\u14B5"+ - "\u14B6\u14B7\u14B8\u14B9\u14BA\u14BB\u14BC\u14BD"+ - "\u14BE\u14BF\u14C0\u14C1\u14C2\u14C3\u14C4\u14C5"+ - "\u14C6\u14C7\u14C8\u14C9\u14CA\u14CB\u14CC\u14CD"+ - "\u14CE\u14CF\u14D0\u14D1\u14D2\u14D3\u14D4\u14D5"+ - "\u14D6\u14D7\u14D8\u14D9\u14DA\u14DB\u14DC\u14DD"+ - "\u14DE\u14DF\u14E0\u14E1\u14E2\u14E3\u14E4\u14E5"+ - "\u14E6\u14E7\u14E8\u14E9\u14EA\u14EB\u14EC\u14ED"+ - "\u14EE\u14EF\u14F0\u14F1\u14F2\u14F3\u14F4\u14F5"+ - "\u14F6\u14F7\u14F8\u14F9\u14FA\u14FB\u14FC\u14FD"+ - "\u14FE\u14FF\u1500\u1501\u1502\u1503\u1504\u1505"+ - "\u1506\u1507\u1508\u1509\u150A\u150B\u150C\u150D"+ - "\u150E\u150F\u1510\u1511\u1512\u1513\u1514\u1515"+ - "\u1516\u1517\u1518\u1519\u151A\u151B\u151C\u151D"+ - "\u151E\u151F\u1520\u1521\u1522\u1523\u1524\u1525"+ - "\u1526\u1527\u1528\u1529\u152A\u152B\u152C\u152D"+ - "\u152E\u152F\u1530\u1531\u1532\u1533\u1534\u1535"+ - "\u1536\u1537\u1538\u1539\u153A\u153B\u153C\u153D"+ - "\u153E\u153F\u1540\u1541\u1542\u1543\u1544\u1545"+ - "\u1546\u1547\u1548\u1549\u154A\u154B\u154C\u154D"+ - "\u154E\u154F\u1550\u1551\u1552\u1553\u1554\u1555"+ - "\u1556\u1557\u1558\u1559\u155A\u155B\u155C\u155D"+ - "\u155E\u155F\u1560\u1561\u1562\u1563\u1564\u1565"+ - "\u1566\u1567\u1568\u1569\u156A\u156B\u156C\u156D"+ - "\u156E\u156F\u1570\u1571\u1572\u1573\u1574\u1575"+ - "\u1576\u1577\u1578\u1579\u157A\u157B\u157C\u157D"+ - "\u157E\u157F\u1580\u1581\u1582\u1583\u1584\u1585"+ - "\u1586\u1587\u1588\u1589\u158A\u158B\u158C\u158D"+ - "\u158E\u158F\u1590\u1591\u1592\u1593\u1594\u1595"+ - "\u1596\u1597\u1598\u1599\u159A\u159B\u159C\u159D"+ - "\u159E\u159F\u15A0\u15A1\u15A2\u15A3\u15A4\u15A5"+ - "\u15A6\u15A7\u15A8\u15A9\u15AA\u15AB\u15AC\u15AD"+ - "\u15AE\u15AF\u15B0\u15B1\u15B2\u15B3\u15B4\u15B5"+ - "\u15B6\u15B7\u15B8\u15B9\u15BA\u15BB\u15BC\u15BD"+ - "\u15BE\u15BF\u15C0\u15C1\u15C2\u15C3\u15C4\u15C5"+ - "\u15C6\u15C7\u15C8\u15C9\u15CA\u15CB\u15CC\u15CD"+ - "\u15CE\u15CF\u15D0\u15D1\u15D2\u15D3\u15D4\u15D5"+ - "\u15D6\u15D7\u15D8\u15D9\u15DA\u15DB\u15DC\u15DD"+ - "\u15DE\u15DF\u15E0\u15E1\u15E2\u15E3\u15E4\u15E5"+ - "\u15E6\u15E7\u15E8\u15E9\u15EA\u15EB\u15EC\u15ED"+ - "\u15EE\u15EF\u15F0\u15F1\u15F2\u15F3\u15F4\u15F5"+ - "\u15F6\u15F7\u15F8\u15F9\u15FA\u15FB\u15FC\u15FD"+ - "\u15FE\u15FF\u1600\u1601\u1602\u1603\u1604\u1605"+ - "\u1606\u1607\u1608\u1609\u160A\u160B\u160C\u160D"+ - "\u160E\u160F\u1610\u1611\u1612\u1613\u1614\u1615"+ - "\u1616\u1617\u1618\u1619\u161A\u161B\u161C\u161D"+ - "\u161E\u161F\u1620\u1621\u1622\u1623\u1624\u1625"+ - "\u1626\u1627\u1628\u1629\u162A\u162B\u162C\u162D"+ - "\u162E\u162F\u1630\u1631\u1632\u1633\u1634\u1635"+ - "\u1636\u1637\u1638\u1639\u163A\u163B\u163C\u163D"+ - "\u163E\u163F\u1640\u1641\u1642\u1643\u1644\u1645"+ - "\u1646\u1647\u1648\u1649\u164A\u164B\u164C\u164D"+ - "\u164E\u164F\u1650\u1651\u1652\u1653\u1654\u1655"+ - "\u1656\u1657\u1658\u1659\u165A\u165B\u165C\u165D"+ - "\u165E\u165F\u1660\u1661\u1662\u1663\u1664\u1665"+ - "\u1666\u1667\u1668\u1669\u166A\u166B\u166C\u166D"+ - "\u166E\u166F\u1670\u1671\u1672\u1673\u1674\u1675"+ - "\u1676\u1677\u1678\u1679\u167A\u167B\u167C\u167D"+ - "\u167E\u167F\u1680\u1681\u1682\u1683\u1684\u1685"+ - "\u1686\u1687\u1688\u1689\u168A\u168B\u168C\u168D"+ - "\u168E\u168F\u1690\u1691\u1692\u1693\u1694\u1695"+ - "\u1696\u1697\u1698\u1699\u169A\u169B\u169C\u169D"+ - "\u169E\u169F\u16A0\u16A1\u16A2\u16A3\u16A4\u16A5"+ - "\u16A6\u16A7\u16A8\u16A9\u16AA\u16AB\u16AC\u16AD"+ - "\u16AE\u16AF\u16B0\u16B1\u16B2\u16B3\u16B4\u16B5"+ - "\u16B6\u16B7\u16B8\u16B9\u16BA\u16BB\u16BC\u16BD"+ - "\u16BE\u16BF\u16C0\u16C1\u16C2\u16C3\u16C4\u16C5"+ - "\u16C6\u16C7\u16C8\u16C9\u16CA\u16CB\u16CC\u16CD"+ - "\u16CE\u16CF\u16D0\u16D1\u16D2\u16D3\u16D4\u16D5"+ - "\u16D6\u16D7\u16D8\u16D9\u16DA\u16DB\u16DC\u16DD"+ - "\u16DE\u16DF\u16E0\u16E1\u16E2\u16E3\u16E4\u16E5"+ - "\u16E6\u16E7\u16E8\u16E9\u16EA\u16EB\u16EC\u16ED"+ - "\u16EE\u16EF\u16F0\u16F1\u16F2\u16F3\u16F4\u16F5"+ - "\u16F6\u16F7\u16F8\u16F9\u16FA\u16FB\u16FC\u16FD"+ - "\u16FE\u16FF\u1700\u1701\u1702\u1703\u1704\u1705"+ - "\u1706\u1707\u1708\u1709\u170A\u170B\u170C\u170D"+ - "\u170E\u170F\u1710\u1711\u1712\u1713\u1714\u1715"+ - "\u1716\u1717\u1718\u1719\u171A\u171B\u171C\u171D"+ - "\u171E\u171F\u1720\u1721\u1722\u1723\u1724\u1725"+ - "\u1726\u1727\u1728\u1729\u172A\u172B\u172C\u172D"+ - "\u172E\u172F\u1730\u1731\u1732\u1733\u1734\u1735"+ - "\u1736\u1737\u1738\u1739\u173A\u173B\u173C\u173D"+ - "\u173E\u173F\u1740\u1741\u1742\u1743\u1744\u1745"+ - "\u1746\u1747\u1748\u1749\u174A\u174B\u174C\u174D"+ - "\u174E\u174F\u1750\u1751\u1752\u1753\u1754\u1755"+ - "\u1756\u1757\u1758\u1759\u175A\u175B\u175C\u175D"+ - "\u175E\u175F\u1760\u1761\u1762\u1763\u1764\u1765"+ - "\u1766\u1767\u1768\u1769\u176A\u176B\u176C\u176D"+ - "\u176E\u176F\u1770\u1771\u1772\u1773\u1774\u1775"+ - "\u1776\u1777\u1778\u1779\u177A\u177B\u177C\u177D"+ - "\u177E\u177F\u1780\u1781\u1782\u1783\u1784\u1785"+ - "\u1786\u1787\u1788\u1789\u178A\u178B\u178C\u178D"+ - "\u178E\u178F\u1790\u1791\u1792\u1793\u1794\u1795"+ - "\u1796\u1797\u1798\u1799\u179A\u179B\u179C\u179D"+ - "\u179E\u179F\u17A0\u17A1\u17A2\u17A3\u17A4\u17A5"+ - "\u17A6\u17A7\u17A8\u17A9\u17AA\u17AB\u17AC\u17AD"+ - "\u17AE\u17AF\u17B0\u17B1\u17B2\u17B3\u17B4\u17B5"+ - "\u17B6\u17B7\u17B8\u17B9\u17BA\u17BB\u17BC\u17BD"+ - "\u17BE\u17BF\u17C0\u17C1\u17C2\u17C3\u17C4\u17C5"+ - "\u17C6\u17C7\u17C8\u17C9\u17CA\u17CB\u17CC\u17CD"+ - "\u17CE\u17CF\u17D0\u17D1\u17D2\u17D3\u17D4\u17D5"+ - "\u17D6\u17D7\u17D8\u17D9\u17DA\u17DB\u17DC\u17DD"+ - "\u17DE\u17DF\u17E0\u17E1\u17E2\u17E3\u17E4\u17E5"+ - "\u17E6\u17E7\u17E8\u17E9\u17EA\u17EB\u17EC\u17ED"+ - "\u17EE\u17EF\u17F0\u17F1\u17F2\u17F3\u17F4\u17F5"+ - "\u17F6\u17F7\u17F8\u17F9\u17FA\u17FB\u17FC\u17FD"+ - "\u17FE\u17FF\u1800\u1801\u1802\u1803\u1804\u1805"+ - "\u1806\u1807\u1808\u1809\u180A\u180B\u180C\u180D"+ - "\u180E\u180F\u1810\u1811\u1812\u1813\u1814\u1815"+ - "\u1816\u1817\u1818\u1819\u181A\u181B\u181C\u181D"+ - "\u181E\u181F\u1820\u1821\u1822\u1823\u1824\u1825"+ - "\u1826\u1827\u1828\u1829\u182A\u182B\u182C\u182D"+ - "\u182E\u182F\u1830\u1831\u1832\u1833\u1834\u1835"+ - "\u1836\u1837\u1838\u1839\u183A\u183B\u183C\u183D"+ - "\u183E\u183F\u1840\u1841\u1842\u1843\u1844\u1845"+ - "\u1846\u1847\u1848\u1849\u184A\u184B\u184C\u184D"+ - "\u184E\u184F\u1850\u1851\u1852\u1853\u1854\u1855"+ - "\u1856\u1857\u1858\u1859\u185A\u185B\u185C\u185D"+ - "\u185E\u185F\u1860\u1861\u1862\u1863\u1864\u1865"+ - "\u1866\u1867\u1868\u1869\u186A\u186B\u186C\u186D"+ - "\u186E\u186F\u1870\u1871\u1872\u1873\u1874\u1875"+ - "\u1876\u1877\u1878\u1879\u187A\u187B\u187C\u187D"+ - "\u187E\u187F\u1880\u1881\u1882\u1883\u1884\u1885"+ - "\u1886\u1887\u1888\u1889\u188A\u188B\u188C\u188D"+ - "\u188E\u188F\u1890\u1891\u1892\u1893\u1894\u1895"+ - "\u1896\u1897\u1898\u1899\u189A\u189B\u189C\u189D"+ - "\u189E\u189F\u18A0\u18A1\u18A2\u18A3\u18A4\u18A5"+ - "\u18A6\u18A7\u18A8\u18A9\u18AA\u18AB\u18AC\u18AD"+ - "\u18AE\u18AF\u18B0\u18B1\u18B2\u18B3\u18B4\u18B5"+ - "\u18B6\u18B7\u18B8\u18B9\u18BA\u18BB\u18BC\u18BD"+ - "\u18BE\u18BF\u18C0\u18C1\u18C2\u18C3\u18C4\u18C5"+ - "\u18C6\u18C7\u18C8\u18C9\u18CA\u18CB\u18CC\u18CD"+ - "\u18CE\u18CF\u18D0\u18D1\u18D2\u18D3\u18D4\u18D5"+ - "\u18D6\u18D7\u18D8\u18D9\u18DA\u18DB\u18DC\u18DD"+ - "\u18DE\u18DF\u18E0\u18E1\u18E2\u18E3\u18E4\u18E5"+ - "\u18E6\u18E7\u18E8\u18E9\u18EA\u18EB\u18EC\u18ED"+ - "\u18EE\u18EF\u18F0\u18F1\u18F2\u18F3\u18F4\u18F5"+ - "\u18F6\u18F7\u18F8\u18F9\u18FA\u18FB\u18FC\u18FD"+ - "\u18FE\u18FF\u1900\u1901\u1902\u1903\u1904\u1905"+ - "\u1906\u1907\u1908\u1909\u190A\u190B\u190C\u190D"+ - "\u190E\u190F\u1910\u1911\u1912\u1913\u1914\u1915"+ - "\u1916\u1917\u1918\u1919\u191A\u191B\u191C\u191D"+ - "\u191E\u191F\u1920\u1921\u1922\u1923\u1924\u1925"+ - "\u1926\u1927\u1928\u1929\u192A\u192B\u192C\u192D"+ - "\u192E\u192F\u1930\u1931\u1932\u1933\u1934\u1935"+ - "\u1936\u1937\u1938\u1939\u193A\u193B\u193C\u193D"+ - "\u193E\u193F\u1940\u1941\u1942\u1943\u1944\u1945"+ - "\u1946\u1947\u1948\u1949\u194A\u194B\u194C\u194D"+ - "\u194E\u194F\u1950\u1951\u1952\u1953\u1954\u1955"+ - "\u1956\u1957\u1958\u1959\u195A\u195B\u195C\u195D"+ - "\u195E\u195F\u1960\u1961\u1962\u1963\u1964\u1965"+ - "\u1966\u1967\u1968\u1969\u196A\u196B\u196C\u196D"+ - "\u196E\u196F\u1970\u1971\u1972\u1973\u1974\u1975"+ - "\u1976\u1977\u1978\u1979\u197A\u197B\u197C\u197D"+ - "\u197E\u197F\u1980\u1981\u1982\u1983\u1984\u1985"+ - "\u1986\u1987\u1988\u1989\u198A\u198B\u198C\u198D"+ - "\u198E\u198F\u1990\u1991\u1992\u1993\u1994\u1995"+ - "\u1996\u1997\u1998\u1999\u199A\u199B\u199C\u199D"+ - "\u199E\u199F\u19A0\u19A1\u19A2\u19A3\u19A4\u19A5"+ - "\u19A6\u19A7\u19A8\u19A9\u19AA\u19AB\u19AC\u19AD"+ - "\u19AE\u19AF\u19B0\u19B1\u19B2\u19B3\u19B4\u19B5"+ - "\u19B6\u19B7\u19B8\u19B9\u19BA\u19BB\u19BC\u19BD"+ - "\u19BE\u19BF\u19C0\u19C1\u19C2\u19C3\u19C4\u19C5"+ - "\u19C6\u19C7\u19C8\u19C9\u19CA\u19CB\u19CC\u19CD"+ - "\u19CE\u19CF\u19D0\u19D1\u19D2\u19D3\u19D4\u19D5"+ - "\u19D6\u19D7\u19D8\u19D9\u19DA\u19DB\u19DC\u19DD"+ - "\u19DE\u19DF\u19E0\u19E1\u19E2\u19E3\u19E4\u19E5"+ - "\u19E6\u19E7\u19E8\u19E9\u19EA\u19EB\u19EC\u19ED"+ - "\u19EE\u19EF\u19F0\u19F1\u19F2\u19F3\u19F4\u19F5"+ - "\u19F6\u19F7\u19F8\u19F9\u19FA\u19FB\u19FC\u19FD"+ - "\u19FE\u19FF\u1A00\u1A01\u1A02\u1A03\u1A04\u1A05"+ - "\u1A06\u1A07\u1A08\u1A09\u1A0A\u1A0B\u1A0C\u1A0D"+ - "\u1A0E\u1A0F\u1A10\u1A11\u1A12\u1A13\u1A14\u1A15"+ - "\u1A16\u1A17\u1A18\u1A19\u1A1A\u1A1B\u1A1C\u1A1D"+ - "\u1A1E\u1A1F\u1A20\u1A21\u1A22\u1A23\u1A24\u1A25"+ - "\u1A26\u1A27\u1A28\u1A29\u1A2A\u1A2B\u1A2C\u1A2D"+ - "\u1A2E\u1A2F\u1A30\u1A31\u1A32\u1A33\u1A34\u1A35"+ - "\u1A36\u1A37\u1A38\u1A39\u1A3A\u1A3B\u1A3C\u1A3D"+ - "\u1A3E\u1A3F\u1A40\u1A41\u1A42\u1A43\u1A44\u1A45"+ - "\u1A46\u1A47\u1A48\u1A49\u1A4A\u1A4B\u1A4C\u1A4D"+ - "\u1A4E\u1A4F\u1A50\u1A51\u1A52\u1A53\u1A54\u1A55"+ - "\u1A56\u1A57\u1A58\u1A59\u1A5A\u1A5B\u1A5C\u1A5D"+ - "\u1A5E\u1A5F\u1A60\u1A61\u1A62\u1A63\u1A64\u1A65"+ - "\u1A66\u1A67\u1A68\u1A69\u1A6A\u1A6B\u1A6C\u1A6D"+ - "\u1A6E\u1A6F\u1A70\u1A71\u1A72\u1A73\u1A74\u1A75"+ - "\u1A76\u1A77\u1A78\u1A79\u1A7A\u1A7B\u1A7C\u1A7D"+ - "\u1A7E\u1A7F\u1A80\u1A81\u1A82\u1A83\u1A84\u1A85"+ - "\u1A86\u1A87\u1A88\u1A89\u1A8A\u1A8B\u1A8C\u1A8D"+ - "\u1A8E\u1A8F\u1A90\u1A91\u1A92\u1A93\u1A94\u1A95"+ - "\u1A96\u1A97\u1A98\u1A99\u1A9A\u1A9B\u1A9C\u1A9D"+ - "\u1A9E\u1A9F\u1AA0\u1AA1\u1AA2\u1AA3\u1AA4\u1AA5"+ - "\u1AA6\u1AA7\u1AA8\u1AA9\u1AAA\u1AAB\u1AAC\u1AAD"+ - "\u1AAE\u1AAF\u1AB0\u1AB1\u1AB2\u1AB3\u1AB4\u1AB5"+ - "\u1AB6\u1AB7\u1AB8\u1AB9\u1ABA\u1ABB\u1ABC\u1ABD"+ - "\u1ABE\u1ABF\u1AC0\u1AC1\u1AC2\u1AC3\u1AC4\u1AC5"+ - "\u1AC6\u1AC7\u1AC8\u1AC9\u1ACA\u1ACB\u1ACC\u1ACD"+ - "\u1ACE\u1ACF\u1AD0\u1AD1\u1AD2\u1AD3\u1AD4\u1AD5"+ - "\u1AD6\u1AD7\u1AD8\u1AD9\u1ADA\u1ADB\u1ADC\u1ADD"+ - "\u1ADE\u1ADF\u1AE0\u1AE1\u1AE2\u1AE3\u1AE4\u1AE5"+ - "\u1AE6\u1AE7\u1AE8\u1AE9\u1AEA\u1AEB\u1AEC\u1AED"+ - "\u1AEE\u1AEF\u1AF0\u1AF1\u1AF2\u1AF3\u1AF4\u1AF5"+ - "\u1AF6\u1AF7\u1AF8\u1AF9\u1AFA\u1AFB\u1AFC\u1AFD"+ - "\u1AFE\u1AFF\u1B00\u1B01\u1B02\u1B03\u1B04\u1B05"+ - "\u1B06\u1B07\u1B08\u1B09\u1B0A\u1B0B\u1B0C\u1B0D"+ - "\u1B0E\u1B0F\u1B10\u1B11\u1B12\u1B13\u1B14\u1B15"+ - "\u1B16\u1B17\u1B18\u1B19\u1B1A\u1B1B\u1B1C\u1B1D"+ - "\u1B1E\u1B1F\u1B20\u1B21\u1B22\u1B23\u1B24\u1B25"+ - "\u1B26\u1B27\u1B28\u1B29\u1B2A\u1B2B\u1B2C\u1B2D"+ - "\u1B2E\u1B2F\u1B30\u1B31\u1B32\u1B33\u1B34\u1B35"+ - "\u1B36\u1B37\u1B38\u1B39\u1B3A\u1B3B\u1B3C\u1B3D"+ - "\u1B3E\u1B3F\u1B40\u1B41\u1B42\u1B43\u1B44\u1B45"+ - "\u1B46\u1B47\u1B48\u1B49\u1B4A\u1B4B\u1B4C\u1B4D"+ - "\u1B4E\u1B4F\u1B50\u1B51\u1B52\u1B53\u1B54\u1B55"+ - "\u1B56\u1B57\u1B58\u1B59\u1B5A\u1B5B\u1B5C\u1B5D"+ - "\u1B5E\u1B5F\u1B60\u1B61\u1B62\u1B63\u1B64\u1B65"+ - "\u1B66\u1B67\u1B68\u1B69\u1B6A\u1B6B\u1B6C\u1B6D"+ - "\u1B6E\u1B6F\u1B70\u1B71\u1B72\u1B73\u1B74\u1B75"+ - "\u1B76\u1B77\u1B78\u1B79\u1B7A\u1B7B\u1B7C\u1B7D"+ - "\u1B7E\u1B7F\u1B80\u1B81\u1B82\u1B83\u1B84\u1B85"+ - "\u1B86\u1B87\u1B88\u1B89\u1B8A\u1B8B\u1B8C\u1B8D"+ - "\u1B8E\u1B8F\u1B90\u1B91\u1B92\u1B93\u1B94\u1B95"+ - "\u1B96\u1B97\u1B98\u1B99\u1B9A\u1B9B\u1B9C\u1B9D"+ - "\u1B9E\u1B9F\u1BA0\u1BA1\u1BA2\u1BA3\u1BA4\u1BA5"+ - "\u1BA6\u1BA7\u1BA8\u1BA9\u1BAA\u1BAB\u1BAC\u1BAD"+ - "\u1BAE\u1BAF\u1BB0\u1BB1\u1BB2\u1BB3\u1BB4\u1BB5"+ - "\u1BB6\u1BB7\u1BB8\u1BB9\u1BBA\u1BBB\u1BBC\u1BBD"+ - "\u1BBE\u1BBF\u1BC0\u1BC1\u1BC2\u1BC3\u1BC4\u1BC5"+ - "\u1BC6\u1BC7\u1BC8\u1BC9\u1BCA\u1BCB\u1BCC\u1BCD"+ - "\u1BCE\u1BCF\u1BD0\u1BD1\u1BD2\u1BD3\u1BD4\u1BD5"+ - "\u1BD6\u1BD7\u1BD8\u1BD9\u1BDA\u1BDB\u1BDC\u1BDD"+ - "\u1BDE\u1BDF\u1BE0\u1BE1\u1BE2\u1BE3\u1BE4\u1BE5"+ - "\u1BE6\u1BE7\u1BE8\u1BE9\u1BEA\u1BEB\u1BEC\u1BED"+ - "\u1BEE\u1BEF\u1BF0\u1BF1\u1BF2\u1BF3\u1BF4\u1BF5"+ - "\u1BF6\u1BF7\u1BF8\u1BF9\u1BFA\u1BFB\u1BFC\u1BFD"+ - "\u1BFE\u1BFF\u1C00\u1C01\u1C02\u1C03\u1C04\u1C05"+ - "\u1C06\u1C07\u1C08\u1C09\u1C0A\u1C0B\u1C0C\u1C0D"+ - "\u1C0E\u1C0F\u1C10\u1C11\u1C12\u1C13\u1C14\u1C15"+ - "\u1C16\u1C17\u1C18\u1C19\u1C1A\u1C1B\u1C1C\u1C1D"+ - "\u1C1E\u1C1F\u1C20\u1C21\u1C22\u1C23\u1C24\u1C25"+ - "\u1C26\u1C27\u1C28\u1C29\u1C2A\u1C2B\u1C2C\u1C2D"+ - "\u1C2E\u1C2F\u1C30\u1C31\u1C32\u1C33\u1C34\u1C35"+ - "\u1C36\u1C37\u1C38\u1C39\u1C3A\u1C3B\u1C3C\u1C3D"+ - "\u1C3E\u1C3F\u1C40\u1C41\u1C42\u1C43\u1C44\u1C45"+ - "\u1C46\u1C47\u1C48\u1C49\u1C4A\u1C4B\u1C4C\u1C4D"+ - "\u1C4E\u1C4F\u1C50\u1C51\u1C52\u1C53\u1C54\u1C55"+ - "\u1C56\u1C57\u1C58\u1C59\u1C5A\u1C5B\u1C5C\u1C5D"+ - "\u1C5E\u1C5F\u1C60\u1C61\u1C62\u1C63\u1C64\u1C65"+ - "\u1C66\u1C67\u1C68\u1C69\u1C6A\u1C6B\u1C6C\u1C6D"+ - "\u1C6E\u1C6F\u1C70\u1C71\u1C72\u1C73\u1C74\u1C75"+ - "\u1C76\u1C77\u1C78\u1C79\u1C7A\u1C7B\u1C7C\u1C7D"+ - "\u1C7E\u1C7F\u1C80\u1C81\u1C82\u1C83\u1C84\u1C85"+ - "\u1C86\u1C87\u1C88\u1C89\u1C8A\u1C8B\u1C8C\u1C8D"+ - "\u1C8E\u1C8F\u1C90\u1C91\u1C92\u1C93\u1C94\u1C95"+ - "\u1C96\u1C97\u1C98\u1C99\u1C9A\u1C9B\u1C9C\u1C9D"+ - "\u1C9E\u1C9F\u1CA0\u1CA1\u1CA2\u1CA3\u1CA4\u1CA5"+ - "\u1CA6\u1CA7\u1CA8\u1CA9\u1CAA\u1CAB\u1CAC\u1CAD"+ - "\u1CAE\u1CAF\u1CB0\u1CB1\u1CB2\u1CB3\u1CB4\u1CB5"+ - "\u1CB6\u1CB7\u1CB8\u1CB9\u1CBA\u1CBB\u1CBC\u1CBD"+ - "\u1CBE\u1CBF\u1CC0\u1CC1\u1CC2\u1CC3\u1CC4\u1CC5"+ - "\u1CC6\u1CC7\u1CC8\u1CC9\u1CCA\u1CCB\u1CCC\u1CCD"+ - "\u1CCE\u1CCF\u1CD0\u1CD1\u1CD2\u1CD3\u1CD4\u1CD5"+ - "\u1CD6\u1CD7\u1CD8\u1CD9\u1CDA\u1CDB\u1CDC\u1CDD"+ - "\u1CDE\u1CDF\u1CE0\u1CE1\u1CE2\u1CE3\u1CE4\u1CE5"+ - "\u1CE6\u1CE7\u1CE8\u1CE9\u1CEA\u1CEB\u1CEC\u1CED"+ - "\u1CEE\u1CEF\u1CF0\u1CF1\u1CF2\u1CF3\u1CF4\u1CF5"+ - "\u1CF6\u1CF7\u1CF8\u1CF9\u1CFA\u1CFB\u1CFC\u1CFD"+ - "\u1CFE\u1CFF\u1D00\u1D01\u1D02\u1D03\u1D04\u1D05"+ - "\u1D06\u1D07\u1D08\u1D09\u1D0A\u1D0B\u1D0C\u1D0D"+ - "\u1D0E\u1D0F\u1D10\u1D11\u1D12\u1D13\u1D14\u1D15"+ - "\u1D16\u1D17\u1D18\u1D19\u1D1A\u1D1B\u1D1C\u1D1D"+ - "\u1D1E\u1D1F\u1D20\u1D21\u1D22\u1D23\u1D24\u1D25"+ - "\u1D26\u1D27\u1D28\u1D29\u1D2A\u1D2B\u1D2C\u1D2D"+ - "\u1D2E\u1D2F\u1D30\u1D31\u1D32\u1D33\u1D34\u1D35"+ - "\u1D36\u1D37\u1D38\u1D39\u1D3A\u1D3B\u1D3C\u1D3D"+ - "\u1D3E\u1D3F\u1D40\u1D41\u1D42\u1D43\u1D44\u1D45"+ - "\u1D46\u1D47\u1D48\u1D49\u1D4A\u1D4B\u1D4C\u1D4D"+ - "\u1D4E\u1D4F\u1D50\u1D51\u1D52\u1D53\u1D54\u1D55"+ - "\u1D56\u1D57\u1D58\u1D59\u1D5A\u1D5B\u1D5C\u1D5D"+ - "\u1D5E\u1D5F\u1D60\u1D61\u1D62\u1D63\u1D64\u1D65"+ - "\u1D66\u1D67\u1D68\u1D69\u1D6A\u1D6B\u1D6C\u1D6D"+ - "\u1D6E\u1D6F\u1D70\u1D71\u1D72\u1D73\u1D74\u1D75"+ - "\u1D76\u1D77\u1D78\u1D79\u1D7A\u1D7B\u1D7C\u1D7D"+ - "\u1D7E\u1D7F\u1D80\u1D81\u1D82\u1D83\u1D84\u1D85"+ - "\u1D86\u1D87\u1D88\u1D89\u1D8A\u1D8B\u1D8C\u1D8D"+ - "\u1D8E\u1D8F\u1D90\u1D91\u1D92\u1D93\u1D94\u1D95"+ - "\u1D96\u1D97\u1D98\u1D99\u1D9A\u1D9B\u1D9C\u1D9D"+ - "\u1D9E\u1D9F\u1DA0\u1DA1\u1DA2\u1DA3\u1DA4\u1DA5"+ - "\u1DA6\u1DA7\u1DA8\u1DA9\u1DAA\u1DAB\u1DAC\u1DAD"+ - "\u1DAE\u1DAF\u1DB0\u1DB1\u1DB2\u1DB3\u1DB4\u1DB5"+ - "\u1DB6\u1DB7\u1DB8\u1DB9\u1DBA\u1DBB\u1DBC\u1DBD"+ - "\u1DBE\u1DBF\u1DC0\u1DC1\u1DC2\u1DC3\u1DC4\u1DC5"+ - "\u1DC6\u1DC7\u1DC8\u1DC9\u1DCA\u1DCB\u1DCC\u1DCD"+ - "\u1DCE\u1DCF\u1DD0\u1DD1\u1DD2\u1DD3\u1DD4\u1DD5"+ - "\u1DD6\u1DD7\u1DD8\u1DD9\u1DDA\u1DDB\u1DDC\u1DDD"+ - "\u1DDE\u1DDF\u1DE0\u1DE1\u1DE2\u1DE3\u1DE4\u1DE5"+ - "\u1DE6\u1DE7\u1DE8\u1DE9\u1DEA\u1DEB\u1DEC\u1DED"+ - "\u1DEE\u1DEF\u1DF0\u1DF1\u1DF2\u1DF3\u1DF4\u1DF5"+ - "\u1DF6\u1DF7\u1DF8\u1DF9\u1DFA\u1DFB\u1DFC\u1DFD"+ - "\u1DFE\u1DFF\u1E00\u1E01\u1E02\u1E03\u1E04\u1E05"+ - "\u1E06\u1E07\u1E08\u1E09\u1E0A\u1E0B\u1E0C\u1E0D"+ - "\u1E0E\u1E0F\u1E10\u1E11\u1E12\u1E13\u1E14\u1E15"+ - "\u1E16\u1E17\u1E18\u1E19\u1E1A\u1E1B\u1E1C\u1E1D"+ - "\u1E1E\u1E1F\u1E20\u1E21\u1E22\u1E23\u1E24\u1E25"+ - "\u1E26\u1E27\u1E28\u1E29\u1E2A\u1E2B\u1E2C\u1E2D"+ - "\u1E2E\u1E2F\u1E30\u1E31\u1E32\u1E33\u1E34\u1E35"+ - "\u1E36\u1E37\u1E38\u1E39\u1E3A\u1E3B\u1E3C\u1E3D"+ - "\u1E3E\u1E3F\u1E40\u1E41\u1E42\u1E43\u1E44\u1E45"+ - "\u1E46\u1E47\u1E48\u1E49\u1E4A\u1E4B\u1E4C\u1E4D"+ - "\u1E4E\u1E4F\u1E50\u1E51\u1E52\u1E53\u1E54\u1E55"+ - "\u1E56\u1E57\u1E58\u1E59\u1E5A\u1E5B\u1E5C\u1E5D"+ - "\u1E5E\u1E5F\u1E60\u1E61\u1E62\u1E63\u1E64\u1E65"+ - "\u1E66\u1E67\u1E68\u1E69\u1E6A\u1E6B\u1E6C\u1E6D"+ - "\u1E6E\u1E6F\u1E70\u1E71\u1E72\u1E73\u1E74\u1E75"+ - "\u1E76\u1E77\u1E78\u1E79\u1E7A\u1E7B\u1E7C\u1E7D"+ - "\u1E7E\u1E7F\u1E80\u1E81\u1E82\u1E83\u1E84\u1E85"+ - "\u1E86\u1E87\u1E88\u1E89\u1E8A\u1E8B\u1E8C\u1E8D"+ - "\u1E8E\u1E8F\u1E90\u1E91\u1E92\u1E93\u1E94\u1E95"+ - "\u1E96\u1E97\u1E98\u1E99\u1E9A\u1E9B\u1E9C\u1E9D"+ - "\u1E9E\u1E9F\u1EA0\u1EA1\u1EA2\u1EA3\u1EA4\u1EA5"+ - "\u1EA6\u1EA7\u1EA8\u1EA9\u1EAA\u1EAB\u1EAC\u1EAD"+ - "\u1EAE\u1EAF\u1EB0\u1EB1\u1EB2\u1EB3\u1EB4\u1EB5"+ - "\u1EB6\u1EB7\u1EB8\u1EB9\u1EBA\u1EBB\u1EBC\u1EBD"+ - "\u1EBE\u1EBF\u1EC0\u1EC1\u1EC2\u1EC3\u1EC4\u1EC5"+ - "\u1EC6\u1EC7\u1EC8\u1EC9\u1ECA\u1ECB\u1ECC\u1ECD"+ - "\u1ECE\u1ECF\u1ED0\u1ED1\u1ED2\u1ED3\u1ED4\u1ED5"+ - "\u1ED6\u1ED7\u1ED8\u1ED9\u1EDA\u1EDB\u1EDC\u1EDD"+ - "\u1EDE\u1EDF\u1EE0\u1EE1\u1EE2\u1EE3\u1EE4\u1EE5"+ - "\u1EE6\u1EE7\u1EE8\u1EE9\u1EEA\u1EEB\u1EEC\u1EED"+ - "\u1EEE\u1EEF\u1EF0\u1EF1\u1EF2\u1EF3\u1EF4\u1EF5"+ - "\u1EF6\u1EF7\u1EF8\u1EF9\u1EFA\u1EFB\u1EFC\u1EFD"+ - "\u1EFE\u1EFF\u1F00\u1F01\u1F02\u1F03\u1F04\u1F05"+ - "\u1F06\u1F07\u1F08\u1F09\u1F0A\u1F0B\u1F0C\u1F0D"+ - "\u1F0E\u1F0F\u1F10\u1F11\u1F12\u1F13\u1F14\u1F15"+ - "\u1F16\u1F17\u1F18\u1F19\u1F1A\u1F1B\u1F1C\u1F1D"+ - "\u1F1E\u1F1F\u1F20\u1F21\u1F22\u1F23\u1F24\u1F25"+ - "\u1F26\u1F27\u1F28\u1F29\u1F2A\u1F2B\u1F2C\u1F2D"+ - "\u1F2E\u1F2F\u1F30\u1F31\u1F32\u1F33\u1F34\u1F35"+ - "\u1F36\u1F37\u1F38\u1F39\u1F3A\u1F3B\u1F3C\u1F3D"+ - "\u1F3E\u1F3F\u1F40\u1F41\u1F42\u1F43\u1F44\u1F45"+ - "\u1F46\u1F47\u1F48\u1F49\u1F4A\u1F4B\u1F4C\u1F4D"+ - "\u1F4E\u1F4F\u1F50\u1F51\u1F52\u1F53\u1F54\u1F55"+ - "\u1F56\u1F57\u1F58\u1F59\u1F5A\u1F5B\u1F5C\u1F5D"+ - "\u1F5E\u1F5F\u1F60\u1F61\u1F62\u1F63\u1F64\u1F65"+ - "\u1F66\u1F67\u1F68\u1F69\u1F6A\u1F6B\u1F6C\u1F6D"+ - "\u1F6E\u1F6F\u1F70\u1F71\u1F72\u1F73\u1F74\u1F75"+ - "\u1F76\u1F77\u1F78\u1F79\u1F7A\u1F7B\u1F7C\u1F7D"+ - "\u1F7E\u1F7F\u1F80\u1F81\u1F82\u1F83\u1F84\u1F85"+ - "\u1F86\u1F87\u1F88\u1F89\u1F8A\u1F8B\u1F8C\u1F8D"+ - "\u1F8E\u1F8F\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95"+ - "\u1F96\u1F97\u1F98\u1F99\u1F9A\u1F9B\u1F9C\u1F9D"+ - "\u1F9E\u1F9F\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5"+ - "\u1FA6\u1FA7\u1FA8\u1FA9\u1FAA\u1FAB\u1FAC\u1FAD"+ - "\u1FAE\u1FAF\u1FB0\u1FB1\u1FB2\u1FB3\u1FB4\u1FB5"+ - "\u1FB6\u1FB7\u1FB8\u1FB9\u1FBA\u1FBB\u1FBC\u1FBD"+ - "\u1FBE\u1FBF\u1FC0\u1FC1\u1FC2\u1FC3\u1FC4\u1FC5"+ - "\u1FC6\u1FC7\u1FC8\u1FC9\u1FCA\u1FCB\u1FCC\u1FCD"+ - "\u1FCE\u1FCF\u1FD0\u1FD1\u1FD2\u1FD3\u1FD4\u1FD5"+ - "\u1FD6\u1FD7\u1FD8\u1FD9\u1FDA\u1FDB\u1FDC\u1FDD"+ - "\u1FDE\u1FDF\u1FE0\u1FE1\u1FE2\u1FE3\u1FE4\u1FE5"+ - "\u1FE6\u1FE7\u1FE8\u1FE9\u1FEA\u1FEB\u1FEC\u1FED"+ - "\u1FEE\u1FEF\u1FF0\u1FF1\u1FF2\u1FF3\u1FF4\u1FF5"+ - "\u1FF6\u1FF7\u1FF8\u1FF9\u1FFA\u1FFB\u1FFC\u1FFD"+ - "\u1FFE\u1FFF\u2000\u2001\u2002\u2003\u2004\u2005"+ - "\u2006\u2007\u2008\u2009\u200A\u200B\u200C\u200D"+ - "\u200E\u200F\u2011\u2012\u2017\u201A\u201B\u201E"+ - "\u201F\u2020\u2021\u2022\u2023\u2024\u2027\u2028"+ - "\u2029\u202A\u202B\u202C\u202D\u202E\u202F\u2031"+ - "\u2034\u2036\u2037\u2038\u2039\u203A\u203C\u203D"+ - "\u203E\u203F\u2040\u2041\u2042\u2043\u2044\u2045"+ - "\u2046\u2047\u2048\u2049\u204A\u204B\u204C\u204D"+ - "\u204E\u204F\u2050\u2051\u2052\u2053\u2054\u2055"+ - "\u2056\u2057\u2058\u2059\u205A\u205B\u205C\u205D"+ - "\u205E\u205F\u2060\u2061\u2062\u2063\u2064\u2065"+ - "\u2066\u2067\u2068\u2069\u206A\u206B\u206C\u206D"+ - "\u206E\u206F\u2070\u2071\u2072\u2073\u2074\u2075"+ - "\u2076\u2077\u2078\u2079\u207A\u207B\u207C\u207D"+ - "\u207E\u207F\u2080\u2081\u2082\u2083\u2084\u2085"+ - "\u2086\u2087\u2088\u2089\u208A\u208B\u208C\u208D"+ - "\u208E\u208F\u2090\u2091\u2092\u2093\u2094\u2095"+ - "\u2096\u2097\u2098\u2099\u209A\u209B\u209C\u209D"+ - "\u209E\u209F\u20A0\u20A1\u20A2\u20A3\u20A4\u20A5"+ - "\u20A6\u20A7\u20A8\u20A9\u20AA\u20AB\u20AD\u20AE"+ - "\u20AF\u20B0\u20B1\u20B2\u20B3\u20B4\u20B5\u20B6"+ - "\u20B7\u20B8\u20B9\u20BA\u20BB\u20BC\u20BD\u20BE"+ - "\u20BF\u20C0\u20C1\u20C2\u20C3\u20C4\u20C5\u20C6"+ - "\u20C7\u20C8\u20C9\u20CA\u20CB\u20CC\u20CD\u20CE"+ - "\u20CF\u20D0\u20D1\u20D2\u20D3\u20D4\u20D5\u20D6"+ - "\u20D7\u20D8\u20D9\u20DA\u20DB\u20DC\u20DD\u20DE"+ - "\u20DF\u20E0\u20E1\u20E2\u20E3\u20E4\u20E5\u20E6"+ - "\u20E7\u20E8\u20E9\u20EA\u20EB\u20EC\u20ED\u20EE"+ - "\u20EF\u20F0\u20F1\u20F2\u20F3\u20F4\u20F5\u20F6"+ - "\u20F7\u20F8\u20F9\u20FA\u20FB\u20FC\u20FD\u20FE"+ - "\u20FF\u2100\u2101\u2102\u2104\u2106\u2107\u2108"+ - "\u210A\u210B\u210C\u210D\u210E\u210F\u2110\u2111"+ - "\u2112\u2113\u2114\u2115\u2117\u2118\u2119\u211A"+ - "\u211B\u211C\u211D\u211E\u211F\u2120\u2122\u2123"+ - "\u2124\u2125\u2126\u2127\u2128\u2129\u212A\u212B"+ - "\u212C\u212D\u212E\u212F\u2130\u2131\u2132\u2133"; - - private static final String innerDecoderIndex2= - "\u2134\u2135\u2136\u2137\u2138\u2139\u213A\u213B"+ - "\u213C\u213D\u213E\u213F\u2140\u2141\u2142\u2143"+ - "\u2144\u2145\u2146\u2147\u2148\u2149\u214A\u214B"+ - "\u214C\u214D\u214E\u214F\u2150\u2151\u2152\u2153"+ - "\u2154\u2155\u2156\u2157\u2158\u2159\u215A\u215B"+ - "\u215C\u215D\u215E\u215F\u216C\u216D\u216E\u216F"+ - "\u217A\u217B\u217C\u217D\u217E\u217F\u2180\u2181"+ - "\u2182\u2183\u2184\u2185\u2186\u2187\u2188\u2189"+ - "\u218A\u218B\u218C\u218D\u218E\u218F\u2194\u2195"+ - "\u219A\u219B\u219C\u219D\u219E\u219F\u21A0\u21A1"+ - "\u21A2\u21A3\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9"+ - "\u21AA\u21AB\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1"+ - "\u21B2\u21B3\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9"+ - "\u21BA\u21BB\u21BC\u21BD\u21BE\u21BF\u21C0\u21C1"+ - "\u21C2\u21C3\u21C4\u21C5\u21C6\u21C7\u21C8\u21C9"+ - "\u21CA\u21CB\u21CC\u21CD\u21CE\u21CF\u21D0\u21D1"+ - "\u21D2\u21D3\u21D4\u21D5\u21D6\u21D7\u21D8\u21D9"+ - "\u21DA\u21DB\u21DC\u21DD\u21DE\u21DF\u21E0\u21E1"+ - "\u21E2\u21E3\u21E4\u21E5\u21E6\u21E7\u21E8\u21E9"+ - "\u21EA\u21EB\u21EC\u21ED\u21EE\u21EF\u21F0\u21F1"+ - "\u21F2\u21F3\u21F4\u21F5\u21F6\u21F7\u21F8\u21F9"+ - "\u21FA\u21FB\u21FC\u21FD\u21FE\u21FF\u2200\u2201"+ - "\u2202\u2203\u2204\u2205\u2206\u2207\u2209\u220A"+ - "\u220B\u220C\u220D\u220E\u2210\u2212\u2213\u2214"+ - "\u2216\u2217\u2218\u2219\u221B\u221C\u2221\u2222"+ - "\u2224\u2226\u222C\u222D\u222F\u2230\u2231\u2232"+ - "\u2233\u2238\u2239\u223A\u223B\u223C\u223E\u223F"+ - "\u2240\u2241\u2242\u2243\u2244\u2245\u2246\u2247"+ - "\u2249\u224A\u224B\u224D\u224E\u224F\u2250\u2251"+ - "\u2253\u2254\u2255\u2256\u2257\u2258\u2259\u225A"+ - "\u225B\u225C\u225D\u225E\u225F\u2262\u2263\u2268"+ - "\u2269\u226A\u226B\u226C\u226D\u2270\u2271\u2272"+ - "\u2273\u2274\u2275\u2276\u2277\u2278\u2279\u227A"+ - "\u227B\u227C\u227D\u227E\u227F\u2280\u2281\u2282"+ - "\u2283\u2284\u2285\u2286\u2287\u2288\u2289\u228A"+ - "\u228B\u228C\u228D\u228E\u228F\u2290\u2291\u2292"+ - "\u2293\u2294\u2296\u2297\u2298\u229A\u229B\u229C"+ - "\u229D\u229E\u229F\u22A0\u22A1\u22A2\u22A3\u22A4"+ - "\u22A6\u22A7\u22A8\u22A9\u22AA\u22AB\u22AC\u22AD"+ - "\u22AE\u22AF\u22B0\u22B1\u22B2\u22B3\u22B4\u22B5"+ - "\u22B6\u22B7\u22B8\u22B9\u22BA\u22BB\u22BC\u22BD"+ - "\u22BE\u22C0\u22C1\u22C2\u22C3\u22C4\u22C5\u22C6"+ - "\u22C7\u22C8\u22C9\u22CA\u22CB\u22CC\u22CD\u22CE"+ - "\u22CF\u22D0\u22D1\u22D2\u22D3\u22D4\u22D5\u22D6"+ - "\u22D7\u22D8\u22D9\u22DA\u22DB\u22DC\u22DD\u22DE"+ - "\u22DF\u22E0\u22E1\u22E2\u22E3\u22E4\u22E5\u22E6"+ - "\u22E7\u22E8\u22E9\u22EA\u22EB\u22EC\u22ED\u22EE"+ - "\u22EF\u22F0\u22F1\u22F2\u22F3\u22F4\u22F5\u22F6"+ - "\u22F7\u22F8\u22F9\u22FA\u22FB\u22FC\u22FD\u22FE"+ - "\u22FF\u2300\u2301\u2302\u2303\u2304\u2305\u2306"+ - "\u2307\u2308\u2309\u230A\u230B\u230C\u230D\u230E"+ - "\u230F\u2310\u2311\u2313\u2314\u2315\u2316\u2317"+ - "\u2318\u2319\u231A\u231B\u231C\u231D\u231E\u231F"+ - "\u2320\u2321\u2322\u2323\u2324\u2325\u2326\u2327"+ - "\u2328\u2329\u232A\u232B\u232C\u232D\u232E\u232F"+ - "\u2330\u2331\u2332\u2333\u2334\u2335\u2336\u2337"+ - "\u2338\u2339\u233A\u233B\u233C\u233D\u233E\u233F"+ - "\u2340\u2341\u2342\u2343\u2344\u2345\u2346\u2347"+ - "\u2348\u2349\u234A\u234B\u234C\u234D\u234E\u234F"+ - "\u2350\u2351\u2352\u2353\u2354\u2355\u2356\u2357"+ - "\u2358\u2359\u235A\u235B\u235C\u235D\u235E\u235F"+ - "\u2360\u2361\u2362\u2363\u2364\u2365\u2366\u2367"+ - "\u2368\u2369\u236A\u236B\u236C\u236D\u236E\u236F"+ - "\u2370\u2371\u2372\u2373\u2374\u2375\u2376\u2377"+ - "\u2378\u2379\u237A\u237B\u237C\u237D\u237E\u237F"+ - "\u2380\u2381\u2382\u2383\u2384\u2385\u2386\u2387"+ - "\u2388\u2389\u238A\u238B\u238C\u238D\u238E\u238F"+ - "\u2390\u2391\u2392\u2393\u2394\u2395\u2396\u2397"+ - "\u2398\u2399\u239A\u239B\u239C\u239D\u239E\u239F"+ - "\u23A0\u23A1\u23A2\u23A3\u23A4\u23A5\u23A6\u23A7"+ - "\u23A8\u23A9\u23AA\u23AB\u23AC\u23AD\u23AE\u23AF"+ - "\u23B0\u23B1\u23B2\u23B3\u23B4\u23B5\u23B6\u23B7"+ - "\u23B8\u23B9\u23BA\u23BB\u23BC\u23BD\u23BE\u23BF"+ - "\u23C0\u23C1\u23C2\u23C3\u23C4\u23C5\u23C6\u23C7"+ - "\u23C8\u23C9\u23CA\u23CB\u23CC\u23CD\u23CE\u23CF"+ - "\u23D0\u23D1\u23D2\u23D3\u23D4\u23D5\u23D6\u23D7"+ - "\u23D8\u23D9\u23DA\u23DB\u23DC\u23DD\u23DE\u23DF"+ - "\u23E0\u23E1\u23E2\u23E3\u23E4\u23E5\u23E6\u23E7"+ - "\u23E8\u23E9\u23EA\u23EB\u23EC\u23ED\u23EE\u23EF"+ - "\u23F0\u23F1\u23F2\u23F3\u23F4\u23F5\u23F6\u23F7"+ - "\u23F8\u23F9\u23FA\u23FB\u23FC\u23FD\u23FE\u23FF"+ - "\u2400\u2401\u2402\u2403\u2404\u2405\u2406\u2407"+ - "\u2408\u2409\u240A\u240B\u240C\u240D\u240E\u240F"+ - "\u2410\u2411\u2412\u2413\u2414\u2415\u2416\u2417"+ - "\u2418\u2419\u241A\u241B\u241C\u241D\u241E\u241F"+ - "\u2420\u2421\u2422\u2423\u2424\u2425\u2426\u2427"+ - "\u2428\u2429\u242A\u242B\u242C\u242D\u242E\u242F"+ - "\u2430\u2431\u2432\u2433\u2434\u2435\u2436\u2437"+ - "\u2438\u2439\u243A\u243B\u243C\u243D\u243E\u243F"+ - "\u2440\u2441\u2442\u2443\u2444\u2445\u2446\u2447"+ - "\u2448\u2449\u244A\u244B\u244C\u244D\u244E\u244F"+ - "\u2450\u2451\u2452\u2453\u2454\u2455\u2456\u2457"+ - "\u2458\u2459\u245A\u245B\u245C\u245D\u245E\u245F"+ - "\u246A\u246B\u246C\u246D\u246E\u246F\u2470\u2471"+ - "\u2472\u2473\u249C\u249D\u249E\u249F\u24A0\u24A1"+ - "\u24A2\u24A3\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9"+ - "\u24AA\u24AB\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1"+ - "\u24B2\u24B3\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9"+ - "\u24BA\u24BB\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1"+ - "\u24C2\u24C3\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9"+ - "\u24CA\u24CB\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1"+ - "\u24D2\u24D3\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9"+ - "\u24DA\u24DB\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1"+ - "\u24E2\u24E3\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9"+ - "\u24EA\u24EB\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1"+ - "\u24F2\u24F3\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9"+ - "\u24FA\u24FB\u24FC\u24FD\u24FE\u24FF\u254C\u254D"+ - "\u254E\u254F\u2574\u2575\u2576\u2577\u2578\u2579"+ - "\u257A\u257B\u257C\u257D\u257E\u257F\u2580\u2590"+ - "\u2591\u2592\u2596\u2597\u2598\u2599\u259A\u259B"+ - "\u259C\u259D\u259E\u259F\u25A2\u25A3\u25A4\u25A5"+ - "\u25A6\u25A7\u25A8\u25A9\u25AA\u25AB\u25AC\u25AD"+ - "\u25AE\u25AF\u25B0\u25B1\u25B4\u25B5\u25B6\u25B7"+ - "\u25B8\u25B9\u25BA\u25BB\u25BE\u25BF\u25C0\u25C1"+ - "\u25C2\u25C3\u25C4\u25C5\u25C8\u25C9\u25CA\u25CC"+ - "\u25CD\u25D0\u25D1\u25D2\u25D3\u25D4\u25D5\u25D6"+ - "\u25D7\u25D8\u25D9\u25DA\u25DB\u25DC\u25DD\u25DE"+ - "\u25DF\u25E0\u25E1\u25E6\u25E7\u25E8\u25E9\u25EA"+ - "\u25EB\u25EC\u25ED\u25EE\u25EF\u25F0\u25F1\u25F2"+ - "\u25F3\u25F4\u25F5\u25F6\u25F7\u25F8\u25F9\u25FA"+ - "\u25FB\u25FC\u25FD\u25FE\u25FF\u2600\u2601\u2602"+ - "\u2603\u2604\u2607\u2608\u260A\u260B\u260C\u260D"+ - "\u260E\u260F\u2610\u2611\u2612\u2613\u2614\u2615"+ - "\u2616\u2617\u2618\u2619\u261A\u261B\u261C\u261D"+ - "\u261E\u261F\u2620\u2621\u2622\u2623\u2624\u2625"+ - "\u2626\u2627\u2628\u2629\u262A\u262B\u262C\u262D"+ - "\u262E\u262F\u2630\u2631\u2632\u2633\u2634\u2635"+ - "\u2636\u2637\u2638\u2639\u263A\u263B\u263C\u263D"+ - "\u263E\u263F\u2641\u2643\u2644\u2645\u2646\u2647"+ - "\u2648\u2649\u264A\u264B\u264C\u264D\u264E\u264F"+ - "\u2650\u2651\u2652\u2653\u2654\u2655\u2656\u2657"+ - "\u2658\u2659\u265A\u265B\u265C\u265D\u265E\u265F"+ - "\u2660\u2661\u2662\u2663\u2664\u2665\u2666\u2667"+ - "\u2668\u2669\u266A\u266B\u266C\u266D\u266E\u266F"+ - "\u2670\u2671\u2672\u2673\u2674\u2675\u2676\u2677"+ - "\u2678\u2679\u267A\u267B\u267C\u267D\u267E\u267F"+ - "\u2680\u2681\u2682\u2683\u2684\u2685\u2686\u2687"+ - "\u2688\u2689\u268A\u268B\u268C\u268D\u268E\u268F"+ - "\u2690\u2691\u2692\u2693\u2694\u2695\u2696\u2697"+ - "\u2698\u2699\u269A\u269B\u269C\u269D\u269E\u269F"+ - "\u26A0\u26A1\u26A2\u26A3\u26A4\u26A5\u26A6\u26A7"+ - "\u26A8\u26A9\u26AA\u26AB\u26AC\u26AD\u26AE\u26AF"+ - "\u26B0\u26B1\u26B2\u26B3\u26B4\u26B5\u26B6\u26B7"+ - "\u26B8\u26B9\u26BA\u26BB\u26BC\u26BD\u26BE\u26BF"+ - "\u26C0\u26C1\u26C2\u26C3\u26C4\u26C5\u26C6\u26C7"+ - "\u26C8\u26C9\u26CA\u26CB\u26CC\u26CD\u26CE\u26CF"+ - "\u26D0\u26D1\u26D2\u26D3\u26D4\u26D5\u26D6\u26D7"+ - "\u26D8\u26D9\u26DA\u26DB\u26DC\u26DD\u26DE\u26DF"+ - "\u26E0\u26E1\u26E2\u26E3\u26E4\u26E5\u26E6\u26E7"+ - "\u26E8\u26E9\u26EA\u26EB\u26EC\u26ED\u26EE\u26EF"+ - "\u26F0\u26F1\u26F2\u26F3\u26F4\u26F5\u26F6\u26F7"+ - "\u26F8\u26F9\u26FA\u26FB\u26FC\u26FD\u26FE\u26FF"+ - "\u2700\u2701\u2702\u2703\u2704\u2705\u2706\u2707"+ - "\u2708\u2709\u270A\u270B\u270C\u270D\u270E\u270F"+ - "\u2710\u2711\u2712\u2713\u2714\u2715\u2716\u2717"+ - "\u2718\u2719\u271A\u271B\u271C\u271D\u271E\u271F"+ - "\u2720\u2721\u2722\u2723\u2724\u2725\u2726\u2727"+ - "\u2728\u2729\u272A\u272B\u272C\u272D\u272E\u272F"+ - "\u2730\u2731\u2732\u2733\u2734\u2735\u2736\u2737"+ - "\u2738\u2739\u273A\u273B\u273C\u273D\u273E\u273F"+ - "\u2740\u2741\u2742\u2743\u2744\u2745\u2746\u2747"+ - "\u2748\u2749\u274A\u274B\u274C\u274D\u274E\u274F"+ - "\u2750\u2751\u2752\u2753\u2754\u2755\u2756\u2757"+ - "\u2758\u2759\u275A\u275B\u275C\u275D\u275E\u275F"+ - "\u2760\u2761\u2762\u2763\u2764\u2765\u2766\u2767"+ - "\u2768\u2769\u276A\u276B\u276C\u276D\u276E\u276F"+ - "\u2770\u2771\u2772\u2773\u2774\u2775\u2776\u2777"+ - "\u2778\u2779\u277A\u277B\u277C\u277D\u277E\u277F"+ - "\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787"+ - "\u2788\u2789\u278A\u278B\u278C\u278D\u278E\u278F"+ - "\u2790\u2791\u2792\u2793\u2794\u2795\u2796\u2797"+ - "\u2798\u2799\u279A\u279B\u279C\u279D\u279E\u279F"+ - "\u27A0\u27A1\u27A2\u27A3\u27A4\u27A5\u27A6\u27A7"+ - "\u27A8\u27A9\u27AA\u27AB\u27AC\u27AD\u27AE\u27AF"+ - "\u27B0\u27B1\u27B2\u27B3\u27B4\u27B5\u27B6\u27B7"+ - "\u27B8\u27B9\u27BA\u27BB\u27BC\u27BD\u27BE\u27BF"+ - "\u27C0\u27C1\u27C2\u27C3\u27C4\u27C5\u27C6\u27C7"+ - "\u27C8\u27C9\u27CA\u27CB\u27CC\u27CD\u27CE\u27CF"+ - "\u27D0\u27D1\u27D2\u27D3\u27D4\u27D5\u27D6\u27D7"+ - "\u27D8\u27D9\u27DA\u27DB\u27DC\u27DD\u27DE\u27DF"+ - "\u27E0\u27E1\u27E2\u27E3\u27E4\u27E5\u27E6\u27E7"+ - "\u27E8\u27E9\u27EA\u27EB\u27EC\u27ED\u27EE\u27EF"+ - "\u27F0\u27F1\u27F2\u27F3\u27F4\u27F5\u27F6\u27F7"+ - "\u27F8\u27F9\u27FA\u27FB\u27FC\u27FD\u27FE\u27FF"+ - "\u2800\u2801\u2802\u2803\u2804\u2805\u2806\u2807"+ - "\u2808\u2809\u280A\u280B\u280C\u280D\u280E\u280F"+ - "\u2810\u2811\u2812\u2813\u2814\u2815\u2816\u2817"+ - "\u2818\u2819\u281A\u281B\u281C\u281D\u281E\u281F"+ - "\u2820\u2821\u2822\u2823\u2824\u2825\u2826\u2827"+ - "\u2828\u2829\u282A\u282B\u282C\u282D\u282E\u282F"+ - "\u2830\u2831\u2832\u2833\u2834\u2835\u2836\u2837"+ - "\u2838\u2839\u283A\u283B\u283C\u283D\u283E\u283F"+ - "\u2840\u2841\u2842\u2843\u2844\u2845\u2846\u2847"+ - "\u2848\u2849\u284A\u284B\u284C\u284D\u284E\u284F"+ - "\u2850\u2851\u2852\u2853\u2854\u2855\u2856\u2857"+ - "\u2858\u2859\u285A\u285B\u285C\u285D\u285E\u285F"+ - "\u2860\u2861\u2862\u2863\u2864\u2865\u2866\u2867"+ - "\u2868\u2869\u286A\u286B\u286C\u286D\u286E\u286F"+ - "\u2870\u2871\u2872\u2873\u2874\u2875\u2876\u2877"+ - "\u2878\u2879\u287A\u287B\u287C\u287D\u287E\u287F"+ - "\u2880\u2881\u2882\u2883\u2884\u2885\u2886\u2887"+ - "\u2888\u2889\u288A\u288B\u288C\u288D\u288E\u288F"+ - "\u2890\u2891\u2892\u2893\u2894\u2895\u2896\u2897"+ - "\u2898\u2899\u289A\u289B\u289C\u289D\u289E\u289F"+ - "\u28A0\u28A1\u28A2\u28A3\u28A4\u28A5\u28A6\u28A7"+ - "\u28A8\u28A9\u28AA\u28AB\u28AC\u28AD\u28AE\u28AF"+ - "\u28B0\u28B1\u28B2\u28B3\u28B4\u28B5\u28B6\u28B7"+ - "\u28B8\u28B9\u28BA\u28BB\u28BC\u28BD\u28BE\u28BF"+ - "\u28C0\u28C1\u28C2\u28C3\u28C4\u28C5\u28C6\u28C7"+ - "\u28C8\u28C9\u28CA\u28CB\u28CC\u28CD\u28CE\u28CF"+ - "\u28D0\u28D1\u28D2\u28D3\u28D4\u28D5\u28D6\u28D7"+ - "\u28D8\u28D9\u28DA\u28DB\u28DC\u28DD\u28DE\u28DF"+ - "\u28E0\u28E1\u28E2\u28E3\u28E4\u28E5\u28E6\u28E7"+ - "\u28E8\u28E9\u28EA\u28EB\u28EC\u28ED\u28EE\u28EF"+ - "\u28F0\u28F1\u28F2\u28F3\u28F4\u28F5\u28F6\u28F7"+ - "\u28F8\u28F9\u28FA\u28FB\u28FC\u28FD\u28FE\u28FF"+ - "\u2900\u2901\u2902\u2903\u2904\u2905\u2906\u2907"+ - "\u2908\u2909\u290A\u290B\u290C\u290D\u290E\u290F"+ - "\u2910\u2911\u2912\u2913\u2914\u2915\u2916\u2917"+ - "\u2918\u2919\u291A\u291B\u291C\u291D\u291E\u291F"+ - "\u2920\u2921\u2922\u2923\u2924\u2925\u2926\u2927"+ - "\u2928\u2929\u292A\u292B\u292C\u292D\u292E\u292F"+ - "\u2930\u2931\u2932\u2933\u2934\u2935\u2936\u2937"+ - "\u2938\u2939\u293A\u293B\u293C\u293D\u293E\u293F"+ - "\u2940\u2941\u2942\u2943\u2944\u2945\u2946\u2947"+ - "\u2948\u2949\u294A\u294B\u294C\u294D\u294E\u294F"+ - "\u2950\u2951\u2952\u2953\u2954\u2955\u2956\u2957"+ - "\u2958\u2959\u295A\u295B\u295C\u295D\u295E\u295F"+ - "\u2960\u2961\u2962\u2963\u2964\u2965\u2966\u2967"+ - "\u2968\u2969\u296A\u296B\u296C\u296D\u296E\u296F"+ - "\u2970\u2971\u2972\u2973\u2974\u2975\u2976\u2977"+ - "\u2978\u2979\u297A\u297B\u297C\u297D\u297E\u297F"+ - "\u2980\u2981\u2982\u2983\u2984\u2985\u2986\u2987"+ - "\u2988\u2989\u298A\u298B\u298C\u298D\u298E\u298F"+ - "\u2990\u2991\u2992\u2993\u2994\u2995\u2996\u2997"+ - "\u2998\u2999\u299A\u299B\u299C\u299D\u299E\u299F"+ - "\u29A0\u29A1\u29A2\u29A3\u29A4\u29A5\u29A6\u29A7"+ - "\u29A8\u29A9\u29AA\u29AB\u29AC\u29AD\u29AE\u29AF"+ - "\u29B0\u29B1\u29B2\u29B3\u29B4\u29B5\u29B6\u29B7"+ - "\u29B8\u29B9\u29BA\u29BB\u29BC\u29BD\u29BE\u29BF"+ - "\u29C0\u29C1\u29C2\u29C3\u29C4\u29C5\u29C6\u29C7"+ - "\u29C8\u29C9\u29CA\u29CB\u29CC\u29CD\u29CE\u29CF"+ - "\u29D0\u29D1\u29D2\u29D3\u29D4\u29D5\u29D6\u29D7"+ - "\u29D8\u29D9\u29DA\u29DB\u29DC\u29DD\u29DE\u29DF"+ - "\u29E0\u29E1\u29E2\u29E3\u29E4\u29E5\u29E6\u29E7"+ - "\u29E8\u29E9\u29EA\u29EB\u29EC\u29ED\u29EE\u29EF"+ - "\u29F0\u29F1\u29F2\u29F3\u29F4\u29F5\u29F6\u29F7"+ - "\u29F8\u29F9\u29FA\u29FB\u29FC\u29FD\u29FE\u29FF"+ - "\u2A00\u2A01\u2A02\u2A03\u2A04\u2A05\u2A06\u2A07"+ - "\u2A08\u2A09\u2A0A\u2A0B\u2A0C\u2A0D\u2A0E\u2A0F"+ - "\u2A10\u2A11\u2A12\u2A13\u2A14\u2A15\u2A16\u2A17"+ - "\u2A18\u2A19\u2A1A\u2A1B\u2A1C\u2A1D\u2A1E\u2A1F"+ - "\u2A20\u2A21\u2A22\u2A23\u2A24\u2A25\u2A26\u2A27"+ - "\u2A28\u2A29\u2A2A\u2A2B\u2A2C\u2A2D\u2A2E\u2A2F"+ - "\u2A30\u2A31\u2A32\u2A33\u2A34\u2A35\u2A36\u2A37"+ - "\u2A38\u2A39\u2A3A\u2A3B\u2A3C\u2A3D\u2A3E\u2A3F"+ - "\u2A40\u2A41\u2A42\u2A43\u2A44\u2A45\u2A46\u2A47"+ - "\u2A48\u2A49\u2A4A\u2A4B\u2A4C\u2A4D\u2A4E\u2A4F"+ - "\u2A50\u2A51\u2A52\u2A53\u2A54\u2A55\u2A56\u2A57"+ - "\u2A58\u2A59\u2A5A\u2A5B\u2A5C\u2A5D\u2A5E\u2A5F"+ - "\u2A60\u2A61\u2A62\u2A63\u2A64\u2A65\u2A66\u2A67"+ - "\u2A68\u2A69\u2A6A\u2A6B\u2A6C\u2A6D\u2A6E\u2A6F"+ - "\u2A70\u2A71\u2A72\u2A73\u2A74\u2A75\u2A76\u2A77"+ - "\u2A78\u2A79\u2A7A\u2A7B\u2A7C\u2A7D\u2A7E\u2A7F"+ - "\u2A80\u2A81\u2A82\u2A83\u2A84\u2A85\u2A86\u2A87"+ - "\u2A88\u2A89\u2A8A\u2A8B\u2A8C\u2A8D\u2A8E\u2A8F"+ - "\u2A90\u2A91\u2A92\u2A93\u2A94\u2A95\u2A96\u2A97"+ - "\u2A98\u2A99\u2A9A\u2A9B\u2A9C\u2A9D\u2A9E\u2A9F"+ - "\u2AA0\u2AA1\u2AA2\u2AA3\u2AA4\u2AA5\u2AA6\u2AA7"+ - "\u2AA8\u2AA9\u2AAA\u2AAB\u2AAC\u2AAD\u2AAE\u2AAF"+ - "\u2AB0\u2AB1\u2AB2\u2AB3\u2AB4\u2AB5\u2AB6\u2AB7"+ - "\u2AB8\u2AB9\u2ABA\u2ABB\u2ABC\u2ABD\u2ABE\u2ABF"+ - "\u2AC0\u2AC1\u2AC2\u2AC3\u2AC4\u2AC5\u2AC6\u2AC7"+ - "\u2AC8\u2AC9\u2ACA\u2ACB\u2ACC\u2ACD\u2ACE\u2ACF"+ - "\u2AD0\u2AD1\u2AD2\u2AD3\u2AD4\u2AD5\u2AD6\u2AD7"+ - "\u2AD8\u2AD9\u2ADA\u2ADB\u2ADC\u2ADD\u2ADE\u2ADF"+ - "\u2AE0\u2AE1\u2AE2\u2AE3\u2AE4\u2AE5\u2AE6\u2AE7"+ - "\u2AE8\u2AE9\u2AEA\u2AEB\u2AEC\u2AED\u2AEE\u2AEF"+ - "\u2AF0\u2AF1\u2AF2\u2AF3\u2AF4\u2AF5\u2AF6\u2AF7"+ - "\u2AF8\u2AF9\u2AFA\u2AFB\u2AFC\u2AFD\u2AFE\u2AFF"+ - "\u2B00\u2B01\u2B02\u2B03\u2B04\u2B05\u2B06\u2B07"+ - "\u2B08\u2B09\u2B0A\u2B0B\u2B0C\u2B0D\u2B0E\u2B0F"+ - "\u2B10\u2B11\u2B12\u2B13\u2B14\u2B15\u2B16\u2B17"+ - "\u2B18\u2B19\u2B1A\u2B1B\u2B1C\u2B1D\u2B1E\u2B1F"+ - "\u2B20\u2B21\u2B22\u2B23\u2B24\u2B25\u2B26\u2B27"+ - "\u2B28\u2B29\u2B2A\u2B2B\u2B2C\u2B2D\u2B2E\u2B2F"+ - "\u2B30\u2B31\u2B32\u2B33\u2B34\u2B35\u2B36\u2B37"+ - "\u2B38\u2B39\u2B3A\u2B3B\u2B3C\u2B3D\u2B3E\u2B3F"+ - "\u2B40\u2B41\u2B42\u2B43\u2B44\u2B45\u2B46\u2B47"+ - "\u2B48\u2B49\u2B4A\u2B4B\u2B4C\u2B4D\u2B4E\u2B4F"+ - "\u2B50\u2B51\u2B52\u2B53\u2B54\u2B55\u2B56\u2B57"+ - "\u2B58\u2B59\u2B5A\u2B5B\u2B5C\u2B5D\u2B5E\u2B5F"+ - "\u2B60\u2B61\u2B62\u2B63\u2B64\u2B65\u2B66\u2B67"+ - "\u2B68\u2B69\u2B6A\u2B6B\u2B6C\u2B6D\u2B6E\u2B6F"+ - "\u2B70\u2B71\u2B72\u2B73\u2B74\u2B75\u2B76\u2B77"+ - "\u2B78\u2B79\u2B7A\u2B7B\u2B7C\u2B7D\u2B7E\u2B7F"+ - "\u2B80\u2B81\u2B82\u2B83\u2B84\u2B85\u2B86\u2B87"+ - "\u2B88\u2B89\u2B8A\u2B8B\u2B8C\u2B8D\u2B8E\u2B8F"+ - "\u2B90\u2B91\u2B92\u2B93\u2B94\u2B95\u2B96\u2B97"+ - "\u2B98\u2B99\u2B9A\u2B9B\u2B9C\u2B9D\u2B9E\u2B9F"+ - "\u2BA0\u2BA1\u2BA2\u2BA3\u2BA4\u2BA5\u2BA6\u2BA7"+ - "\u2BA8\u2BA9\u2BAA\u2BAB\u2BAC\u2BAD\u2BAE\u2BAF"+ - "\u2BB0\u2BB1\u2BB2\u2BB3\u2BB4\u2BB5\u2BB6\u2BB7"+ - "\u2BB8\u2BB9\u2BBA\u2BBB\u2BBC\u2BBD\u2BBE\u2BBF"+ - "\u2BC0\u2BC1\u2BC2\u2BC3\u2BC4\u2BC5\u2BC6\u2BC7"+ - "\u2BC8\u2BC9\u2BCA\u2BCB\u2BCC\u2BCD\u2BCE\u2BCF"+ - "\u2BD0\u2BD1\u2BD2\u2BD3\u2BD4\u2BD5\u2BD6\u2BD7"+ - "\u2BD8\u2BD9\u2BDA\u2BDB\u2BDC\u2BDD\u2BDE\u2BDF"+ - "\u2BE0\u2BE1\u2BE2\u2BE3\u2BE4\u2BE5\u2BE6\u2BE7"+ - "\u2BE8\u2BE9\u2BEA\u2BEB\u2BEC\u2BED\u2BEE\u2BEF"+ - "\u2BF0\u2BF1\u2BF2\u2BF3\u2BF4\u2BF5\u2BF6\u2BF7"+ - "\u2BF8\u2BF9\u2BFA\u2BFB\u2BFC\u2BFD\u2BFE\u2BFF"+ - "\u2C00\u2C01\u2C02\u2C03\u2C04\u2C05\u2C06\u2C07"+ - "\u2C08\u2C09\u2C0A\u2C0B\u2C0C\u2C0D\u2C0E\u2C0F"+ - "\u2C10\u2C11\u2C12\u2C13\u2C14\u2C15\u2C16\u2C17"+ - "\u2C18\u2C19\u2C1A\u2C1B\u2C1C\u2C1D\u2C1E\u2C1F"+ - "\u2C20\u2C21\u2C22\u2C23\u2C24\u2C25\u2C26\u2C27"+ - "\u2C28\u2C29\u2C2A\u2C2B\u2C2C\u2C2D\u2C2E\u2C2F"+ - "\u2C30\u2C31\u2C32\u2C33\u2C34\u2C35\u2C36\u2C37"+ - "\u2C38\u2C39\u2C3A\u2C3B\u2C3C\u2C3D\u2C3E\u2C3F"+ - "\u2C40\u2C41\u2C42\u2C43\u2C44\u2C45\u2C46\u2C47"+ - "\u2C48\u2C49\u2C4A\u2C4B\u2C4C\u2C4D\u2C4E\u2C4F"+ - "\u2C50\u2C51\u2C52\u2C53\u2C54\u2C55\u2C56\u2C57"+ - "\u2C58\u2C59\u2C5A\u2C5B\u2C5C\u2C5D\u2C5E\u2C5F"+ - "\u2C60\u2C61\u2C62\u2C63\u2C64\u2C65\u2C66\u2C67"+ - "\u2C68\u2C69\u2C6A\u2C6B\u2C6C\u2C6D\u2C6E\u2C6F"+ - "\u2C70\u2C71\u2C72\u2C73\u2C74\u2C75\u2C76\u2C77"+ - "\u2C78\u2C79\u2C7A\u2C7B\u2C7C\u2C7D\u2C7E\u2C7F"+ - "\u2C80\u2C81\u2C82\u2C83\u2C84\u2C85\u2C86\u2C87"+ - "\u2C88\u2C89\u2C8A\u2C8B\u2C8C\u2C8D\u2C8E\u2C8F"+ - "\u2C90\u2C91\u2C92\u2C93\u2C94\u2C95\u2C96\u2C97"+ - "\u2C98\u2C99\u2C9A\u2C9B\u2C9C\u2C9D\u2C9E\u2C9F"+ - "\u2CA0\u2CA1\u2CA2\u2CA3\u2CA4\u2CA5\u2CA6\u2CA7"+ - "\u2CA8\u2CA9\u2CAA\u2CAB\u2CAC\u2CAD\u2CAE\u2CAF"+ - "\u2CB0\u2CB1\u2CB2\u2CB3\u2CB4\u2CB5\u2CB6\u2CB7"+ - "\u2CB8\u2CB9\u2CBA\u2CBB\u2CBC\u2CBD\u2CBE\u2CBF"+ - "\u2CC0\u2CC1\u2CC2\u2CC3\u2CC4\u2CC5\u2CC6\u2CC7"+ - "\u2CC8\u2CC9\u2CCA\u2CCB\u2CCC\u2CCD\u2CCE\u2CCF"+ - "\u2CD0\u2CD1\u2CD2\u2CD3\u2CD4\u2CD5\u2CD6\u2CD7"+ - "\u2CD8\u2CD9\u2CDA\u2CDB\u2CDC\u2CDD\u2CDE\u2CDF"+ - "\u2CE0\u2CE1\u2CE2\u2CE3\u2CE4\u2CE5\u2CE6\u2CE7"+ - "\u2CE8\u2CE9\u2CEA\u2CEB\u2CEC\u2CED\u2CEE\u2CEF"+ - "\u2CF0\u2CF1\u2CF2\u2CF3\u2CF4\u2CF5\u2CF6\u2CF7"+ - "\u2CF8\u2CF9\u2CFA\u2CFB\u2CFC\u2CFD\u2CFE\u2CFF"+ - "\u2D00\u2D01\u2D02\u2D03\u2D04\u2D05\u2D06\u2D07"+ - "\u2D08\u2D09\u2D0A\u2D0B\u2D0C\u2D0D\u2D0E\u2D0F"+ - "\u2D10\u2D11\u2D12\u2D13\u2D14\u2D15\u2D16\u2D17"+ - "\u2D18\u2D19\u2D1A\u2D1B\u2D1C\u2D1D\u2D1E\u2D1F"+ - "\u2D20\u2D21\u2D22\u2D23\u2D24\u2D25\u2D26\u2D27"+ - "\u2D28\u2D29\u2D2A\u2D2B\u2D2C\u2D2D\u2D2E\u2D2F"+ - "\u2D30\u2D31\u2D32\u2D33\u2D34\u2D35\u2D36\u2D37"+ - "\u2D38\u2D39\u2D3A\u2D3B\u2D3C\u2D3D\u2D3E\u2D3F"+ - "\u2D40\u2D41\u2D42\u2D43\u2D44\u2D45\u2D46\u2D47"+ - "\u2D48\u2D49\u2D4A\u2D4B\u2D4C\u2D4D\u2D4E\u2D4F"+ - "\u2D50\u2D51\u2D52\u2D53\u2D54\u2D55\u2D56\u2D57"+ - "\u2D58\u2D59\u2D5A\u2D5B\u2D5C\u2D5D\u2D5E\u2D5F"+ - "\u2D60\u2D61\u2D62\u2D63\u2D64\u2D65\u2D66\u2D67"+ - "\u2D68\u2D69\u2D6A\u2D6B\u2D6C\u2D6D\u2D6E\u2D6F"+ - "\u2D70\u2D71\u2D72\u2D73\u2D74\u2D75\u2D76\u2D77"+ - "\u2D78\u2D79\u2D7A\u2D7B\u2D7C\u2D7D\u2D7E\u2D7F"+ - "\u2D80\u2D81\u2D82\u2D83\u2D84\u2D85\u2D86\u2D87"+ - "\u2D88\u2D89\u2D8A\u2D8B\u2D8C\u2D8D\u2D8E\u2D8F"+ - "\u2D90\u2D91\u2D92\u2D93\u2D94\u2D95\u2D96\u2D97"+ - "\u2D98\u2D99\u2D9A\u2D9B\u2D9C\u2D9D\u2D9E\u2D9F"+ - "\u2DA0\u2DA1\u2DA2\u2DA3\u2DA4\u2DA5\u2DA6\u2DA7"+ - "\u2DA8\u2DA9\u2DAA\u2DAB\u2DAC\u2DAD\u2DAE\u2DAF"+ - "\u2DB0\u2DB1\u2DB2\u2DB3\u2DB4\u2DB5\u2DB6\u2DB7"+ - "\u2DB8\u2DB9\u2DBA\u2DBB\u2DBC\u2DBD\u2DBE\u2DBF"+ - "\u2DC0\u2DC1\u2DC2\u2DC3\u2DC4\u2DC5\u2DC6\u2DC7"+ - "\u2DC8\u2DC9\u2DCA\u2DCB\u2DCC\u2DCD\u2DCE\u2DCF"+ - "\u2DD0\u2DD1\u2DD2\u2DD3\u2DD4\u2DD5\u2DD6\u2DD7"+ - "\u2DD8\u2DD9\u2DDA\u2DDB\u2DDC\u2DDD\u2DDE\u2DDF"+ - "\u2DE0\u2DE1\u2DE2\u2DE3\u2DE4\u2DE5\u2DE6\u2DE7"+ - "\u2DE8\u2DE9\u2DEA\u2DEB\u2DEC\u2DED\u2DEE\u2DEF"+ - "\u2DF0\u2DF1\u2DF2\u2DF3\u2DF4\u2DF5\u2DF6\u2DF7"+ - "\u2DF8\u2DF9\u2DFA\u2DFB\u2DFC\u2DFD\u2DFE\u2DFF"+ - "\u2E00\u2E01\u2E02\u2E03\u2E04\u2E05\u2E06\u2E07"+ - "\u2E08\u2E09\u2E0A\u2E0B\u2E0C\u2E0D\u2E0E\u2E0F"+ - "\u2E10\u2E11\u2E12\u2E13\u2E14\u2E15\u2E16\u2E17"+ - "\u2E18\u2E19\u2E1A\u2E1B\u2E1C\u2E1D\u2E1E\u2E1F"+ - "\u2E20\u2E21\u2E22\u2E23\u2E24\u2E25\u2E26\u2E27"+ - "\u2E28\u2E29\u2E2A\u2E2B\u2E2C\u2E2D\u2E2E\u2E2F"+ - "\u2E30\u2E31\u2E32\u2E33\u2E34\u2E35\u2E36\u2E37"+ - "\u2E38\u2E39\u2E3A\u2E3B\u2E3C\u2E3D\u2E3E\u2E3F"+ - "\u2E40\u2E41\u2E42\u2E43\u2E44\u2E45\u2E46\u2E47"+ - "\u2E48\u2E49\u2E4A\u2E4B\u2E4C\u2E4D\u2E4E\u2E4F"+ - "\u2E50\u2E51\u2E52\u2E53\u2E54\u2E55\u2E56\u2E57"+ - "\u2E58\u2E59\u2E5A\u2E5B\u2E5C\u2E5D\u2E5E\u2E5F"+ - "\u2E60\u2E61\u2E62\u2E63\u2E64\u2E65\u2E66\u2E67"+ - "\u2E68\u2E69\u2E6A\u2E6B\u2E6C\u2E6D\u2E6E\u2E6F"+ - "\u2E70\u2E71\u2E72\u2E73\u2E74\u2E75\u2E76\u2E77"+ - "\u2E78\u2E79\u2E7A\u2E7B\u2E7C\u2E7D\u2E7E\u2E7F"+ - "\u2E80\u2E82\u2E83\u2E85\u2E86\u2E87\u2E89\u2E8A"+ - "\u2E8D\u2E8E\u2E8F\u2E90\u2E91\u2E92\u2E93\u2E94"+ - "\u2E95\u2E96\u2E98\u2E99\u2E9A\u2E9B\u2E9C\u2E9D"+ - "\u2E9E\u2E9F\u2EA0\u2EA1\u2EA2\u2EA3\u2EA4\u2EA5"+ - "\u2EA6\u2EA8\u2EA9\u2EAB\u2EAC\u2EAD\u2EAF\u2EB0"+ - "\u2EB1\u2EB2\u2EB4\u2EB5\u2EB8\u2EB9\u2EBA\u2EBC"+ - "\u2EBD\u2EBE\u2EBF\u2EC0\u2EC1\u2EC2\u2EC3\u2EC4"+ - "\u2EC5\u2EC6\u2EC7\u2EC8\u2EC9\u2ECB\u2ECC\u2ECD"+ - "\u2ECE\u2ECF\u2ED0\u2ED1\u2ED2\u2ED3\u2ED4\u2ED5"+ - "\u2ED6\u2ED7\u2ED8\u2ED9\u2EDA\u2EDB\u2EDC\u2EDD"+ - "\u2EDE\u2EDF\u2EE0\u2EE1\u2EE2\u2EE3\u2EE4\u2EE5"+ - "\u2EE6\u2EE7\u2EE8\u2EE9\u2EEA\u2EEB\u2EEC\u2EED"+ - "\u2EEE\u2EEF\u2EF0\u2EF1\u2EF2\u2EF3\u2EF4\u2EF5"+ - "\u2EF6\u2EF7\u2EF8\u2EF9\u2EFA\u2EFB\u2EFC\u2EFD"+ - "\u2EFE\u2EFF\u2F00\u2F01\u2F02\u2F03\u2F04\u2F05"+ - "\u2F06\u2F07\u2F08\u2F09\u2F0A\u2F0B\u2F0C\u2F0D"+ - "\u2F0E\u2F0F\u2F10\u2F11\u2F12\u2F13\u2F14\u2F15"+ - "\u2F16\u2F17\u2F18\u2F19\u2F1A\u2F1B\u2F1C\u2F1D"+ - "\u2F1E\u2F1F\u2F20\u2F21\u2F22\u2F23\u2F24\u2F25"+ - "\u2F26\u2F27\u2F28\u2F29\u2F2A\u2F2B\u2F2C\u2F2D"+ - "\u2F2E\u2F2F\u2F30\u2F31\u2F32\u2F33\u2F34\u2F35"+ - "\u2F36\u2F37\u2F38\u2F39\u2F3A\u2F3B\u2F3C\u2F3D"+ - "\u2F3E\u2F3F\u2F40\u2F41\u2F42\u2F43\u2F44\u2F45"+ - "\u2F46\u2F47\u2F48\u2F49\u2F4A\u2F4B\u2F4C\u2F4D"+ - "\u2F4E\u2F4F\u2F50\u2F51\u2F52\u2F53\u2F54\u2F55"+ - "\u2F56\u2F57\u2F58\u2F59\u2F5A\u2F5B\u2F5C\u2F5D"+ - "\u2F5E\u2F5F\u2F60\u2F61\u2F62\u2F63\u2F64\u2F65"+ - "\u2F66\u2F67\u2F68\u2F69\u2F6A\u2F6B\u2F6C\u2F6D"+ - "\u2F6E\u2F6F\u2F70\u2F71\u2F72\u2F73\u2F74\u2F75"+ - "\u2F76\u2F77\u2F78\u2F79\u2F7A\u2F7B\u2F7C\u2F7D"+ - "\u2F7E\u2F7F\u2F80\u2F81\u2F82\u2F83\u2F84\u2F85"+ - "\u2F86\u2F87\u2F88\u2F89\u2F8A\u2F8B\u2F8C\u2F8D"+ - "\u2F8E\u2F8F\u2F90\u2F91\u2F92\u2F93\u2F94\u2F95"+ - "\u2F96\u2F97\u2F98\u2F99\u2F9A\u2F9B\u2F9C\u2F9D"+ - "\u2F9E\u2F9F\u2FA0\u2FA1\u2FA2\u2FA3\u2FA4\u2FA5"+ - "\u2FA6\u2FA7\u2FA8\u2FA9\u2FAA\u2FAB\u2FAC\u2FAD"+ - "\u2FAE\u2FAF\u2FB0\u2FB1\u2FB2\u2FB3\u2FB4\u2FB5"+ - "\u2FB6\u2FB7\u2FB8\u2FB9\u2FBA\u2FBB\u2FBC\u2FBD"+ - "\u2FBE\u2FBF\u2FC0\u2FC1\u2FC2\u2FC3\u2FC4\u2FC5"+ - "\u2FC6\u2FC7\u2FC8\u2FC9\u2FCA\u2FCB\u2FCC\u2FCD"+ - "\u2FCE\u2FCF\u2FD0\u2FD1\u2FD2\u2FD3\u2FD4\u2FD5"+ - "\u2FD6\u2FD7\u2FD8\u2FD9\u2FDA\u2FDB\u2FDC\u2FDD"+ - "\u2FDE\u2FDF\u2FE0\u2FE1\u2FE2\u2FE3\u2FE4\u2FE5"+ - "\u2FE6\u2FE7\u2FE8\u2FE9\u2FEA\u2FEB\u2FEC\u2FED"+ - "\u2FEE\u2FEF\u2FFC\u2FFD\u2FFE\u2FFF\u3004\u3018"+ - "\u3019\u301A\u301B\u301C\u301F\u3020\u302A\u302B"+ - "\u302C\u302D\u302E\u302F\u3030\u3031\u3032\u3033"+ - "\u3034\u3035\u3036\u3037\u3038\u3039\u303A\u303B"+ - "\u303C\u303D\u303F\u3040\u3094\u3095\u3096\u3097"+ - "\u3098\u3099\u309A\u309F\u30A0\u30F7\u30F8\u30F9"+ - "\u30FA\u30FB\u30FF\u3100\u3101\u3102\u3103\u3104"+ - "\u312A\u312B\u312C\u312D\u312E\u312F\u3130\u3131"+ - "\u3132\u3133\u3134\u3135\u3136\u3137\u3138\u3139"+ - "\u313A\u313B\u313C\u313D\u313E\u313F\u3140\u3141"+ - "\u3142\u3143\u3144\u3145\u3146\u3147\u3148\u3149"+ - "\u314A\u314B\u314C\u314D\u314E\u314F\u3150\u3151"+ - "\u3152\u3153\u3154\u3155\u3156\u3157\u3158\u3159"+ - "\u315A\u315B\u315C\u315D\u315E\u315F\u3160\u3161"+ - "\u3162\u3163\u3164\u3165\u3166\u3167\u3168\u3169"+ - "\u316A\u316B\u316C\u316D\u316E\u316F\u3170\u3171"+ - "\u3172\u3173\u3174\u3175\u3176\u3177\u3178\u3179"+ - "\u317A\u317B\u317C\u317D\u317E\u317F\u3180\u3181"+ - "\u3182\u3183\u3184\u3185\u3186\u3187\u3188\u3189"+ - "\u318A\u318B\u318C\u318D\u318E\u318F\u3190\u3191"+ - "\u3192\u3193\u3194\u3195\u3196\u3197\u3198\u3199"+ - "\u319A\u319B\u319C\u319D\u319E\u319F\u31A0\u31A1"+ - "\u31A2\u31A3\u31A4\u31A5\u31A6\u31A7\u31A8\u31A9"+ - "\u31AA\u31AB\u31AC\u31AD\u31AE\u31AF\u31B0\u31B1"+ - "\u31B2\u31B3\u31B4\u31B5\u31B6\u31B7\u31B8\u31B9"+ - "\u31BA\u31BB\u31BC\u31BD\u31BE\u31BF\u31C0\u31C1"+ - "\u31C2\u31C3\u31C4\u31C5\u31C6\u31C7\u31C8\u31C9"+ - "\u31CA\u31CB\u31CC\u31CD\u31CE\u31CF\u31D0\u31D1"+ - "\u31D2\u31D3\u31D4\u31D5\u31D6\u31D7\u31D8\u31D9"+ - "\u31DA\u31DB\u31DC\u31DD\u31DE\u31DF\u31E0\u31E1"+ - "\u31E2\u31E3\u31E4\u31E5\u31E6\u31E7\u31E8\u31E9"+ - "\u31EA\u31EB\u31EC\u31ED\u31EE\u31EF\u31F0\u31F1"+ - "\u31F2\u31F3\u31F4\u31F5\u31F6\u31F7\u31F8\u31F9"+ - "\u31FA\u31FB\u31FC\u31FD\u31FE\u31FF\u3200\u3201"+ - "\u3202\u3203\u3204\u3205\u3206\u3207\u3208\u3209"+ - "\u320A\u320B\u320C\u320D\u320E\u320F\u3210\u3211"+ - "\u3212\u3213\u3214\u3215\u3216\u3217\u3218\u3219"+ - "\u321A\u321B\u321C\u321D\u321E\u321F\u322A\u322B"+ - "\u322C\u322D\u322E\u322F\u3230\u3232\u3233\u3234"+ - "\u3235\u3236\u3237\u3238\u3239\u323A\u323B\u323C"+ - "\u323D\u323E\u323F\u3240\u3241\u3242\u3243\u3244"+ - "\u3245\u3246\u3247\u3248\u3249\u324A\u324B\u324C"+ - "\u324D\u324E\u324F\u3250\u3251\u3252\u3253\u3254"+ - "\u3255\u3256\u3257\u3258\u3259\u325A\u325B\u325C"+ - "\u325D\u325E\u325F\u3260\u3261\u3262\u3263\u3264"+ - "\u3265\u3266\u3267\u3268\u3269\u326A\u326B\u326C"+ - "\u326D\u326E\u326F\u3270\u3271\u3272\u3273\u3274"+ - "\u3275\u3276\u3277\u3278\u3279\u327A\u327B\u327C"+ - "\u327D\u327E\u327F\u3280\u3281\u3282\u3283\u3284"+ - "\u3285\u3286\u3287\u3288\u3289\u328A\u328B\u328C"+ - "\u328D\u328E\u328F\u3290\u3291\u3292\u3293\u3294"+ - "\u3295\u3296\u3297\u3298\u3299\u329A\u329B\u329C"+ - "\u329D\u329E\u329F\u32A0\u32A1\u32A2\u32A4\u32A5"+ - "\u32A6\u32A7\u32A8\u32A9\u32AA\u32AB\u32AC\u32AD"+ - "\u32AE\u32AF\u32B0\u32B1\u32B2\u32B3\u32B4\u32B5"+ - "\u32B6\u32B7\u32B8\u32B9\u32BA\u32BB\u32BC\u32BD"+ - "\u32BE\u32BF\u32C0\u32C1\u32C2\u32C3\u32C4\u32C5"+ - "\u32C6\u32C7\u32C8\u32C9\u32CA\u32CB\u32CC\u32CD"+ - "\u32CE\u32CF\u32D0\u32D1\u32D2\u32D3\u32D4\u32D5"+ - "\u32D6\u32D7\u32D8\u32D9\u32DA\u32DB\u32DC\u32DD"+ - "\u32DE\u32DF\u32E0\u32E1\u32E2\u32E3\u32E4\u32E5"+ - "\u32E6\u32E7\u32E8\u32E9\u32EA\u32EB\u32EC\u32ED"+ - "\u32EE\u32EF\u32F0\u32F1\u32F2\u32F3\u32F4\u32F5"+ - "\u32F6\u32F7\u32F8\u32F9\u32FA\u32FB\u32FC\u32FD"+ - "\u32FE\u32FF\u3300\u3301\u3302\u3303\u3304\u3305"+ - "\u3306\u3307\u3308\u3309\u330A\u330B\u330C\u330D"+ - "\u330E\u330F\u3310\u3311\u3312\u3313\u3314\u3315"+ - "\u3316\u3317\u3318\u3319\u331A\u331B\u331C\u331D"+ - "\u331E\u331F\u3320\u3321\u3322\u3323\u3324\u3325"+ - "\u3326\u3327\u3328\u3329\u332A\u332B\u332C\u332D"+ - "\u332E\u332F\u3330\u3331\u3332\u3333\u3334\u3335"+ - "\u3336\u3337\u3338\u3339\u333A\u333B\u333C\u333D"+ - "\u333E\u333F\u3340\u3341\u3342\u3343\u3344\u3345"+ - "\u3346\u3347\u3348\u3349\u334A\u334B\u334C\u334D"+ - "\u334E\u334F\u3350\u3351\u3352\u3353\u3354\u3355"+ - "\u3356\u3357\u3358\u3359\u335A\u335B\u335C\u335D"; - - private static final String innerDecoderIndex3= - "\u335E\u335F\u3360\u3361\u3362\u3363\u3364\u3365"+ - "\u3366\u3367\u3368\u3369\u336A\u336B\u336C\u336D"+ - "\u336E\u336F\u3370\u3371\u3372\u3373\u3374\u3375"+ - "\u3376\u3377\u3378\u3379\u337A\u337B\u337C\u337D"+ - "\u337E\u337F\u3380\u3381\u3382\u3383\u3384\u3385"+ - "\u3386\u3387\u3388\u3389\u338A\u338B\u338C\u338D"+ - "\u3390\u3391\u3392\u3393\u3394\u3395\u3396\u3397"+ - "\u3398\u3399\u339A\u339B\u339F\u33A0\u33A2\u33A3"+ - "\u33A4\u33A5\u33A6\u33A7\u33A8\u33A9\u33AA\u33AB"+ - "\u33AC\u33AD\u33AE\u33AF\u33B0\u33B1\u33B2\u33B3"+ - "\u33B4\u33B5\u33B6\u33B7\u33B8\u33B9\u33BA\u33BB"+ - "\u33BC\u33BD\u33BE\u33BF\u33C0\u33C1\u33C2\u33C3"+ - "\u33C5\u33C6\u33C7\u33C8\u33C9\u33CA\u33CB\u33CC"+ - "\u33CD\u33CF\u33D0\u33D3\u33D4\u33D6\u33D7\u33D8"+ - "\u33D9\u33DA\u33DB\u33DC\u33DD\u33DE\u33DF\u33E0"+ - "\u33E1\u33E2\u33E3\u33E4\u33E5\u33E6\u33E7\u33E8"+ - "\u33E9\u33EA\u33EB\u33EC\u33ED\u33EE\u33EF\u33F0"+ - "\u33F1\u33F2\u33F3\u33F4\u33F5\u33F6\u33F7\u33F8"+ - "\u33F9\u33FA\u33FB\u33FC\u33FD\u33FE\u33FF\u3400"+ - "\u3401\u3402\u3403\u3404\u3405\u3406\u3407\u3408"+ - "\u3409\u340A\u340B\u340C\u340D\u340E\u340F\u3410"+ - "\u3411\u3412\u3413\u3414\u3415\u3416\u3417\u3418"+ - "\u3419\u341A\u341B\u341C\u341D\u341E\u341F\u3420"+ - "\u3421\u3422\u3423\u3424\u3425\u3426\u3427\u3428"+ - "\u3429\u342A\u342B\u342C\u342D\u342E\u342F\u3430"+ - "\u3431\u3432\u3433\u3434\u3435\u3436\u3437\u3438"+ - "\u3439\u343A\u343B\u343C\u343D\u343E\u343F\u3440"+ - "\u3441\u3442\u3443\u3444\u3445\u3446\u3448\u3449"+ - "\u344A\u344B\u344C\u344D\u344E\u344F\u3450\u3451"+ - "\u3452\u3453\u3454\u3455\u3456\u3457\u3458\u3459"+ - "\u345A\u345B\u345C\u345D\u345E\u345F\u3460\u3461"+ - "\u3462\u3463\u3464\u3465\u3466\u3467\u3468\u3469"+ - "\u346A\u346B\u346C\u346D\u346E\u346F\u3470\u3471"+ - "\u3472\u3474\u3475\u3476\u3477\u3478\u3479\u347A"+ - "\u347B\u347C\u347D\u347E\u347F\u3480\u3481\u3482"+ - "\u3483\u3484\u3485\u3486\u3487\u3488\u3489\u348A"+ - "\u348B\u348C\u348D\u348E\u348F\u3490\u3491\u3492"+ - "\u3493\u3494\u3495\u3496\u3497\u3498\u3499\u349A"+ - "\u349B\u349C\u349D\u349E\u349F\u34A0\u34A1\u34A2"+ - "\u34A3\u34A4\u34A5\u34A6\u34A7\u34A8\u34A9\u34AA"+ - "\u34AB\u34AC\u34AD\u34AE\u34AF\u34B0\u34B1\u34B2"+ - "\u34B3\u34B4\u34B5\u34B6\u34B7\u34B8\u34B9\u34BA"+ - "\u34BB\u34BC\u34BD\u34BE\u34BF\u34C0\u34C1\u34C2"+ - "\u34C3\u34C4\u34C5\u34C6\u34C7\u34C8\u34C9\u34CA"+ - "\u34CB\u34CC\u34CD\u34CE\u34CF\u34D0\u34D1\u34D2"+ - "\u34D3\u34D4\u34D5\u34D6\u34D7\u34D8\u34D9\u34DA"+ - "\u34DB\u34DC\u34DD\u34DE\u34DF\u34E0\u34E1\u34E2"+ - "\u34E3\u34E4\u34E5\u34E6\u34E7\u34E8\u34E9\u34EA"+ - "\u34EB\u34EC\u34ED\u34EE\u34EF\u34F0\u34F1\u34F2"+ - "\u34F3\u34F4\u34F5\u34F6\u34F7\u34F8\u34F9\u34FA"+ - "\u34FB\u34FC\u34FD\u34FE\u34FF\u3500\u3501\u3502"+ - "\u3503\u3504\u3505\u3506\u3507\u3508\u3509\u350A"+ - "\u350B\u350C\u350D\u350E\u350F\u3510\u3511\u3512"+ - "\u3513\u3514\u3515\u3516\u3517\u3518\u3519\u351A"+ - "\u351B\u351C\u351D\u351E\u351F\u3520\u3521\u3522"+ - "\u3523\u3524\u3525\u3526\u3527\u3528\u3529\u352A"+ - "\u352B\u352C\u352D\u352E\u352F\u3530\u3531\u3532"+ - "\u3533\u3534\u3535\u3536\u3537\u3538\u3539\u353A"+ - "\u353B\u353C\u353D\u353E\u353F\u3540\u3541\u3542"+ - "\u3543\u3544\u3545\u3546\u3547\u3548\u3549\u354A"+ - "\u354B\u354C\u354D\u354E\u354F\u3550\u3551\u3552"+ - "\u3553\u3554\u3555\u3556\u3557\u3558\u3559\u355A"+ - "\u355B\u355C\u355D\u355E\u355F\u3560\u3561\u3562"+ - "\u3563\u3564\u3565\u3566\u3567\u3568\u3569\u356A"+ - "\u356B\u356C\u356D\u356E\u356F\u3570\u3571\u3572"+ - "\u3573\u3574\u3575\u3576\u3577\u3578\u3579\u357A"+ - "\u357B\u357C\u357D\u357E\u357F\u3580\u3581\u3582"+ - "\u3583\u3584\u3585\u3586\u3587\u3588\u3589\u358A"+ - "\u358B\u358C\u358D\u358E\u358F\u3590\u3591\u3592"+ - "\u3593\u3594\u3595\u3596\u3597\u3598\u3599\u359A"+ - "\u359B\u359C\u359D\u359F\u35A0\u35A1\u35A2\u35A3"+ - "\u35A4\u35A5\u35A6\u35A7\u35A8\u35A9\u35AA\u35AB"+ - "\u35AC\u35AD\u35AE\u35AF\u35B0\u35B1\u35B2\u35B3"+ - "\u35B4\u35B5\u35B6\u35B7\u35B8\u35B9\u35BA\u35BB"+ - "\u35BC\u35BD\u35BE\u35BF\u35C0\u35C1\u35C2\u35C3"+ - "\u35C4\u35C5\u35C6\u35C7\u35C8\u35C9\u35CA\u35CB"+ - "\u35CC\u35CD\u35CE\u35CF\u35D0\u35D1\u35D2\u35D3"+ - "\u35D4\u35D5\u35D6\u35D7\u35D8\u35D9\u35DA\u35DB"+ - "\u35DC\u35DD\u35DE\u35DF\u35E0\u35E1\u35E2\u35E3"+ - "\u35E4\u35E5\u35E6\u35E7\u35E8\u35E9\u35EA\u35EB"+ - "\u35EC\u35ED\u35EE\u35EF\u35F0\u35F1\u35F2\u35F3"+ - "\u35F4\u35F5\u35F6\u35F7\u35F8\u35F9\u35FA\u35FB"+ - "\u35FC\u35FD\u35FE\u35FF\u3600\u3601\u3602\u3603"+ - "\u3604\u3605\u3606\u3607\u3608\u3609\u360A\u360B"+ - "\u360C\u360D\u360F\u3610\u3611\u3612\u3613\u3614"+ - "\u3615\u3616\u3617\u3618\u3619\u361B\u361C\u361D"+ - "\u361E\u361F\u3620\u3621\u3622\u3623\u3624\u3625"+ - "\u3626\u3627\u3628\u3629\u362A\u362B\u362C\u362D"+ - "\u362E\u362F\u3630\u3631\u3632\u3633\u3634\u3635"+ - "\u3636\u3637\u3638\u3639\u363A\u363B\u363C\u363D"+ - "\u363E\u363F\u3640\u3641\u3642\u3643\u3644\u3645"+ - "\u3646\u3647\u3648\u3649\u364A\u364B\u364C\u364D"+ - "\u364E\u364F\u3650\u3651\u3652\u3653\u3654\u3655"+ - "\u3656\u3657\u3658\u3659\u365A\u365B\u365C\u365D"+ - "\u365E\u365F\u3660\u3661\u3662\u3663\u3664\u3665"+ - "\u3666\u3667\u3668\u3669\u366A\u366B\u366C\u366D"+ - "\u366E\u366F\u3670\u3671\u3672\u3673\u3674\u3675"+ - "\u3676\u3677\u3678\u3679\u367A\u367B\u367C\u367D"+ - "\u367E\u367F\u3680\u3681\u3682\u3683\u3684\u3685"+ - "\u3686\u3687\u3688\u3689\u368A\u368B\u368C\u368D"+ - "\u368E\u368F\u3690\u3691\u3692\u3693\u3694\u3695"+ - "\u3696\u3697\u3698\u3699\u369A\u369B\u369C\u369D"+ - "\u369E\u369F\u36A0\u36A1\u36A2\u36A3\u36A4\u36A5"+ - "\u36A6\u36A7\u36A8\u36A9\u36AA\u36AB\u36AC\u36AD"+ - "\u36AE\u36AF\u36B0\u36B1\u36B2\u36B3\u36B4\u36B5"+ - "\u36B6\u36B7\u36B8\u36B9\u36BA\u36BB\u36BC\u36BD"+ - "\u36BE\u36BF\u36C0\u36C1\u36C2\u36C3\u36C4\u36C5"+ - "\u36C6\u36C7\u36C8\u36C9\u36CA\u36CB\u36CC\u36CD"+ - "\u36CE\u36CF\u36D0\u36D1\u36D2\u36D3\u36D4\u36D5"+ - "\u36D6\u36D7\u36D8\u36D9\u36DA\u36DB\u36DC\u36DD"+ - "\u36DE\u36DF\u36E0\u36E1\u36E2\u36E3\u36E4\u36E5"+ - "\u36E6\u36E7\u36E8\u36E9\u36EA\u36EB\u36EC\u36ED"+ - "\u36EE\u36EF\u36F0\u36F1\u36F2\u36F3\u36F4\u36F5"+ - "\u36F6\u36F7\u36F8\u36F9\u36FA\u36FB\u36FC\u36FD"+ - "\u36FE\u36FF\u3700\u3701\u3702\u3703\u3704\u3705"+ - "\u3706\u3707\u3708\u3709\u370A\u370B\u370C\u370D"+ - "\u370E\u370F\u3710\u3711\u3712\u3713\u3714\u3715"+ - "\u3716\u3717\u3718\u3719\u371A\u371B\u371C\u371D"+ - "\u371E\u371F\u3720\u3721\u3722\u3723\u3724\u3725"+ - "\u3726\u3727\u3728\u3729\u372A\u372B\u372C\u372D"+ - "\u372E\u372F\u3730\u3731\u3732\u3733\u3734\u3735"+ - "\u3736\u3737\u3738\u3739\u373A\u373B\u373C\u373D"+ - "\u373E\u373F\u3740\u3741\u3742\u3743\u3744\u3745"+ - "\u3746\u3747\u3748\u3749\u374A\u374B\u374C\u374D"+ - "\u374E\u374F\u3750\u3751\u3752\u3753\u3754\u3755"+ - "\u3756\u3757\u3758\u3759\u375A\u375B\u375C\u375D"+ - "\u375E\u375F\u3760\u3761\u3762\u3763\u3764\u3765"+ - "\u3766\u3767\u3768\u3769\u376A\u376B\u376C\u376D"+ - "\u376E\u376F\u3770\u3771\u3772\u3773\u3774\u3775"+ - "\u3776\u3777\u3778\u3779\u377A\u377B\u377C\u377D"+ - "\u377E\u377F\u3780\u3781\u3782\u3783\u3784\u3785"+ - "\u3786\u3787\u3788\u3789\u378A\u378B\u378C\u378D"+ - "\u378E\u378F\u3790\u3791\u3792\u3793\u3794\u3795"+ - "\u3796\u3797\u3798\u3799\u379A\u379B\u379C\u379D"+ - "\u379E\u379F\u37A0\u37A1\u37A2\u37A3\u37A4\u37A5"+ - "\u37A6\u37A7\u37A8\u37A9\u37AA\u37AB\u37AC\u37AD"+ - "\u37AE\u37AF\u37B0\u37B1\u37B2\u37B3\u37B4\u37B5"+ - "\u37B6\u37B7\u37B8\u37B9\u37BA\u37BB\u37BC\u37BD"+ - "\u37BE\u37BF\u37C0\u37C1\u37C2\u37C3\u37C4\u37C5"+ - "\u37C6\u37C7\u37C8\u37C9\u37CA\u37CB\u37CC\u37CD"+ - "\u37CE\u37CF\u37D0\u37D1\u37D2\u37D3\u37D4\u37D5"+ - "\u37D6\u37D7\u37D8\u37D9\u37DA\u37DB\u37DC\u37DD"+ - "\u37DE\u37DF\u37E0\u37E1\u37E2\u37E3\u37E4\u37E5"+ - "\u37E6\u37E7\u37E8\u37E9\u37EA\u37EB\u37EC\u37ED"+ - "\u37EE\u37EF\u37F0\u37F1\u37F2\u37F3\u37F4\u37F5"+ - "\u37F6\u37F7\u37F8\u37F9\u37FA\u37FB\u37FC\u37FD"+ - "\u37FE\u37FF\u3800\u3801\u3802\u3803\u3804\u3805"+ - "\u3806\u3807\u3808\u3809\u380A\u380B\u380C\u380D"+ - "\u380E\u380F\u3810\u3811\u3812\u3813\u3814\u3815"+ - "\u3816\u3817\u3818\u3819\u381A\u381B\u381C\u381D"+ - "\u381E\u381F\u3820\u3821\u3822\u3823\u3824\u3825"+ - "\u3826\u3827\u3828\u3829\u382A\u382B\u382C\u382D"+ - "\u382E\u382F\u3830\u3831\u3832\u3833\u3834\u3835"+ - "\u3836\u3837\u3838\u3839\u383A\u383B\u383C\u383D"+ - "\u383E\u383F\u3840\u3841\u3842\u3843\u3844\u3845"+ - "\u3846\u3847\u3848\u3849\u384A\u384B\u384C\u384D"+ - "\u384E\u384F\u3850\u3851\u3852\u3853\u3854\u3855"+ - "\u3856\u3857\u3858\u3859\u385A\u385B\u385C\u385D"+ - "\u385E\u385F\u3860\u3861\u3862\u3863\u3864\u3865"+ - "\u3866\u3867\u3868\u3869\u386A\u386B\u386C\u386D"+ - "\u386E\u386F\u3870\u3871\u3872\u3873\u3874\u3875"+ - "\u3876\u3877\u3878\u3879\u387A\u387B\u387C\u387D"+ - "\u387E\u387F\u3880\u3881\u3882\u3883\u3884\u3885"+ - "\u3886\u3887\u3888\u3889\u388A\u388B\u388C\u388D"+ - "\u388E\u388F\u3890\u3891\u3892\u3893\u3894\u3895"+ - "\u3896\u3897\u3898\u3899\u389A\u389B\u389C\u389D"+ - "\u389E\u389F\u38A0\u38A1\u38A2\u38A3\u38A4\u38A5"+ - "\u38A6\u38A7\u38A8\u38A9\u38AA\u38AB\u38AC\u38AD"+ - "\u38AE\u38AF\u38B0\u38B1\u38B2\u38B3\u38B4\u38B5"+ - "\u38B6\u38B7\u38B8\u38B9\u38BA\u38BB\u38BC\u38BD"+ - "\u38BE\u38BF\u38C0\u38C1\u38C2\u38C3\u38C4\u38C5"+ - "\u38C6\u38C7\u38C8\u38C9\u38CA\u38CB\u38CC\u38CD"+ - "\u38CE\u38CF\u38D0\u38D1\u38D2\u38D3\u38D4\u38D5"+ - "\u38D6\u38D7\u38D8\u38D9\u38DA\u38DB\u38DC\u38DD"+ - "\u38DE\u38DF\u38E0\u38E1\u38E2\u38E3\u38E4\u38E5"+ - "\u38E6\u38E7\u38E8\u38E9\u38EA\u38EB\u38EC\u38ED"+ - "\u38EE\u38EF\u38F0\u38F1\u38F2\u38F3\u38F4\u38F5"+ - "\u38F6\u38F7\u38F8\u38F9\u38FA\u38FB\u38FC\u38FD"+ - "\u38FE\u38FF\u3900\u3901\u3902\u3903\u3904\u3905"+ - "\u3906\u3907\u3908\u3909\u390A\u390B\u390C\u390D"+ - "\u390E\u390F\u3910\u3911\u3912\u3913\u3914\u3915"+ - "\u3916\u3917\u3919\u391A\u391B\u391C\u391D\u391E"+ - "\u391F\u3920\u3921\u3922\u3923\u3924\u3925\u3926"+ - "\u3927\u3928\u3929\u392A\u392B\u392C\u392D\u392E"+ - "\u392F\u3930\u3931\u3932\u3933\u3934\u3935\u3936"+ - "\u3937\u3938\u3939\u393A\u393B\u393C\u393D\u393E"+ - "\u393F\u3940\u3941\u3942\u3943\u3944\u3945\u3946"+ - "\u3947\u3948\u3949\u394A\u394B\u394C\u394D\u394E"+ - "\u394F\u3950\u3951\u3952\u3953\u3954\u3955\u3956"+ - "\u3957\u3958\u3959\u395A\u395B\u395C\u395D\u395E"+ - "\u395F\u3960\u3961\u3962\u3963\u3964\u3965\u3966"+ - "\u3967\u3968\u3969\u396A\u396B\u396C\u396D\u396F"+ - "\u3970\u3971\u3972\u3973\u3974\u3975\u3976\u3977"+ - "\u3978\u3979\u397A\u397B\u397C\u397D\u397E\u397F"+ - "\u3980\u3981\u3982\u3983\u3984\u3985\u3986\u3987"+ - "\u3988\u3989\u398A\u398B\u398C\u398D\u398E\u398F"+ - "\u3990\u3991\u3992\u3993\u3994\u3995\u3996\u3997"+ - "\u3998\u3999\u399A\u399B\u399C\u399D\u399E\u399F"+ - "\u39A0\u39A1\u39A2\u39A3\u39A4\u39A5\u39A6\u39A7"+ - "\u39A8\u39A9\u39AA\u39AB\u39AC\u39AD\u39AE\u39AF"+ - "\u39B0\u39B1\u39B2\u39B3\u39B4\u39B5\u39B6\u39B7"+ - "\u39B8\u39B9\u39BA\u39BB\u39BC\u39BD\u39BE\u39BF"+ - "\u39C0\u39C1\u39C2\u39C3\u39C4\u39C5\u39C6\u39C7"+ - "\u39C8\u39C9\u39CA\u39CB\u39CC\u39CD\u39CE\u39D1"+ - "\u39D2\u39D3\u39D4\u39D5\u39D6\u39D7\u39D8\u39D9"+ - "\u39DA\u39DB\u39DC\u39DD\u39DE\u39E0\u39E1\u39E2"+ - "\u39E3\u39E4\u39E5\u39E6\u39E7\u39E8\u39E9\u39EA"+ - "\u39EB\u39EC\u39ED\u39EE\u39EF\u39F0\u39F1\u39F2"+ - "\u39F3\u39F4\u39F5\u39F6\u39F7\u39F8\u39F9\u39FA"+ - "\u39FB\u39FC\u39FD\u39FE\u39FF\u3A00\u3A01\u3A02"+ - "\u3A03\u3A04\u3A05\u3A06\u3A07\u3A08\u3A09\u3A0A"+ - "\u3A0B\u3A0C\u3A0D\u3A0E\u3A0F\u3A10\u3A11\u3A12"+ - "\u3A13\u3A14\u3A15\u3A16\u3A17\u3A18\u3A19\u3A1A"+ - "\u3A1B\u3A1C\u3A1D\u3A1E\u3A1F\u3A20\u3A21\u3A22"+ - "\u3A23\u3A24\u3A25\u3A26\u3A27\u3A28\u3A29\u3A2A"+ - "\u3A2B\u3A2C\u3A2D\u3A2E\u3A2F\u3A30\u3A31\u3A32"+ - "\u3A33\u3A34\u3A35\u3A36\u3A37\u3A38\u3A39\u3A3A"+ - "\u3A3B\u3A3C\u3A3D\u3A3E\u3A3F\u3A40\u3A41\u3A42"+ - "\u3A43\u3A44\u3A45\u3A46\u3A47\u3A48\u3A49\u3A4A"+ - "\u3A4B\u3A4C\u3A4D\u3A4E\u3A4F\u3A50\u3A51\u3A52"+ - "\u3A53\u3A54\u3A55\u3A56\u3A57\u3A58\u3A59\u3A5A"+ - "\u3A5B\u3A5C\u3A5D\u3A5E\u3A5F\u3A60\u3A61\u3A62"+ - "\u3A63\u3A64\u3A65\u3A66\u3A67\u3A68\u3A69\u3A6A"+ - "\u3A6B\u3A6C\u3A6D\u3A6E\u3A6F\u3A70\u3A71\u3A72"+ - "\u3A74\u3A75\u3A76\u3A77\u3A78\u3A79\u3A7A\u3A7B"+ - "\u3A7C\u3A7D\u3A7E\u3A7F\u3A80\u3A81\u3A82\u3A83"+ - "\u3A84\u3A85\u3A86\u3A87\u3A88\u3A89\u3A8A\u3A8B"+ - "\u3A8C\u3A8D\u3A8E\u3A8F\u3A90\u3A91\u3A92\u3A93"+ - "\u3A94\u3A95\u3A96\u3A97\u3A98\u3A99\u3A9A\u3A9B"+ - "\u3A9C\u3A9D\u3A9E\u3A9F\u3AA0\u3AA1\u3AA2\u3AA3"+ - "\u3AA4\u3AA5\u3AA6\u3AA7\u3AA8\u3AA9\u3AAA\u3AAB"+ - "\u3AAC\u3AAD\u3AAE\u3AAF\u3AB0\u3AB1\u3AB2\u3AB3"+ - "\u3AB4\u3AB5\u3AB6\u3AB7\u3AB8\u3AB9\u3ABA\u3ABB"+ - "\u3ABC\u3ABD\u3ABE\u3ABF\u3AC0\u3AC1\u3AC2\u3AC3"+ - "\u3AC4\u3AC5\u3AC6\u3AC7\u3AC8\u3AC9\u3ACA\u3ACB"+ - "\u3ACC\u3ACD\u3ACE\u3ACF\u3AD0\u3AD1\u3AD2\u3AD3"+ - "\u3AD4\u3AD5\u3AD6\u3AD7\u3AD8\u3AD9\u3ADA\u3ADB"+ - "\u3ADC\u3ADD\u3ADE\u3ADF\u3AE0\u3AE1\u3AE2\u3AE3"+ - "\u3AE4\u3AE5\u3AE6\u3AE7\u3AE8\u3AE9\u3AEA\u3AEB"+ - "\u3AEC\u3AED\u3AEE\u3AEF\u3AF0\u3AF1\u3AF2\u3AF3"+ - "\u3AF4\u3AF5\u3AF6\u3AF7\u3AF8\u3AF9\u3AFA\u3AFB"+ - "\u3AFC\u3AFD\u3AFE\u3AFF\u3B00\u3B01\u3B02\u3B03"+ - "\u3B04\u3B05\u3B06\u3B07\u3B08\u3B09\u3B0A\u3B0B"+ - "\u3B0C\u3B0D\u3B0E\u3B0F\u3B10\u3B11\u3B12\u3B13"+ - "\u3B14\u3B15\u3B16\u3B17\u3B18\u3B19\u3B1A\u3B1B"+ - "\u3B1C\u3B1D\u3B1E\u3B1F\u3B20\u3B21\u3B22\u3B23"+ - "\u3B24\u3B25\u3B26\u3B27\u3B28\u3B29\u3B2A\u3B2B"+ - "\u3B2C\u3B2D\u3B2E\u3B2F\u3B30\u3B31\u3B32\u3B33"+ - "\u3B34\u3B35\u3B36\u3B37\u3B38\u3B39\u3B3A\u3B3B"+ - "\u3B3C\u3B3D\u3B3E\u3B3F\u3B40\u3B41\u3B42\u3B43"+ - "\u3B44\u3B45\u3B46\u3B47\u3B48\u3B49\u3B4A\u3B4B"+ - "\u3B4C\u3B4D\u3B4F\u3B50\u3B51\u3B52\u3B53\u3B54"+ - "\u3B55\u3B56\u3B57\u3B58\u3B59\u3B5A\u3B5B\u3B5C"+ - "\u3B5D\u3B5E\u3B5F\u3B60\u3B61\u3B62\u3B63\u3B64"+ - "\u3B65\u3B66\u3B67\u3B68\u3B69\u3B6A\u3B6B\u3B6C"+ - "\u3B6D\u3B6E\u3B6F\u3B70\u3B71\u3B72\u3B73\u3B74"+ - "\u3B75\u3B76\u3B77\u3B78\u3B79\u3B7A\u3B7B\u3B7C"+ - "\u3B7D\u3B7E\u3B7F\u3B80\u3B81\u3B82\u3B83\u3B84"+ - "\u3B85\u3B86\u3B87\u3B88\u3B89\u3B8A\u3B8B\u3B8C"+ - "\u3B8D\u3B8E\u3B8F\u3B90\u3B91\u3B92\u3B93\u3B94"+ - "\u3B95\u3B96\u3B97\u3B98\u3B99\u3B9A\u3B9B\u3B9C"+ - "\u3B9D\u3B9E\u3B9F\u3BA0\u3BA1\u3BA2\u3BA3\u3BA4"+ - "\u3BA5\u3BA6\u3BA7\u3BA8\u3BA9\u3BAA\u3BAB\u3BAC"+ - "\u3BAD\u3BAE\u3BAF\u3BB0\u3BB1\u3BB2\u3BB3\u3BB4"+ - "\u3BB5\u3BB6\u3BB7\u3BB8\u3BB9\u3BBA\u3BBB\u3BBC"+ - "\u3BBD\u3BBE\u3BBF\u3BC0\u3BC1\u3BC2\u3BC3\u3BC4"+ - "\u3BC5\u3BC6\u3BC7\u3BC8\u3BC9\u3BCA\u3BCB\u3BCC"+ - "\u3BCD\u3BCE\u3BCF\u3BD0\u3BD1\u3BD2\u3BD3\u3BD4"+ - "\u3BD5\u3BD6\u3BD7\u3BD8\u3BD9\u3BDA\u3BDB\u3BDC"+ - "\u3BDD\u3BDE\u3BDF\u3BE0\u3BE1\u3BE2\u3BE3\u3BE4"+ - "\u3BE5\u3BE6\u3BE7\u3BE8\u3BE9\u3BEA\u3BEB\u3BEC"+ - "\u3BED\u3BEE\u3BEF\u3BF0\u3BF1\u3BF2\u3BF3\u3BF4"+ - "\u3BF5\u3BF6\u3BF7\u3BF8\u3BF9\u3BFA\u3BFB\u3BFC"+ - "\u3BFD\u3BFE\u3BFF\u3C00\u3C01\u3C02\u3C03\u3C04"+ - "\u3C05\u3C06\u3C07\u3C08\u3C09\u3C0A\u3C0B\u3C0C"+ - "\u3C0D\u3C0E\u3C0F\u3C10\u3C11\u3C12\u3C13\u3C14"+ - "\u3C15\u3C16\u3C17\u3C18\u3C19\u3C1A\u3C1B\u3C1C"+ - "\u3C1D\u3C1E\u3C1F\u3C20\u3C21\u3C22\u3C23\u3C24"+ - "\u3C25\u3C26\u3C27\u3C28\u3C29\u3C2A\u3C2B\u3C2C"+ - "\u3C2D\u3C2E\u3C2F\u3C30\u3C31\u3C32\u3C33\u3C34"+ - "\u3C35\u3C36\u3C37\u3C38\u3C39\u3C3A\u3C3B\u3C3C"+ - "\u3C3D\u3C3E\u3C3F\u3C40\u3C41\u3C42\u3C43\u3C44"+ - "\u3C45\u3C46\u3C47\u3C48\u3C49\u3C4A\u3C4B\u3C4C"+ - "\u3C4D\u3C4E\u3C4F\u3C50\u3C51\u3C52\u3C53\u3C54"+ - "\u3C55\u3C56\u3C57\u3C58\u3C59\u3C5A\u3C5B\u3C5C"+ - "\u3C5D\u3C5E\u3C5F\u3C60\u3C61\u3C62\u3C63\u3C64"+ - "\u3C65\u3C66\u3C67\u3C68\u3C69\u3C6A\u3C6B\u3C6C"+ - "\u3C6D\u3C6F\u3C70\u3C71\u3C72\u3C73\u3C74\u3C75"+ - "\u3C76\u3C77\u3C78\u3C79\u3C7A\u3C7B\u3C7C\u3C7D"+ - "\u3C7E\u3C7F\u3C80\u3C81\u3C82\u3C83\u3C84\u3C85"+ - "\u3C86\u3C87\u3C88\u3C89\u3C8A\u3C8B\u3C8C\u3C8D"+ - "\u3C8E\u3C8F\u3C90\u3C91\u3C92\u3C93\u3C94\u3C95"+ - "\u3C96\u3C97\u3C98\u3C99\u3C9A\u3C9B\u3C9C\u3C9D"+ - "\u3C9E\u3C9F\u3CA0\u3CA1\u3CA2\u3CA3\u3CA4\u3CA5"+ - "\u3CA6\u3CA7\u3CA8\u3CA9\u3CAA\u3CAB\u3CAC\u3CAD"+ - "\u3CAE\u3CAF\u3CB0\u3CB1\u3CB2\u3CB3\u3CB4\u3CB5"+ - "\u3CB6\u3CB7\u3CB8\u3CB9\u3CBA\u3CBB\u3CBC\u3CBD"+ - "\u3CBE\u3CBF\u3CC0\u3CC1\u3CC2\u3CC3\u3CC4\u3CC5"+ - "\u3CC6\u3CC7\u3CC8\u3CC9\u3CCA\u3CCB\u3CCC\u3CCD"+ - "\u3CCE\u3CCF\u3CD0\u3CD1\u3CD2\u3CD3\u3CD4\u3CD5"+ - "\u3CD6\u3CD7\u3CD8\u3CD9\u3CDA\u3CDB\u3CDC\u3CDD"+ - "\u3CDE\u3CDF\u3CE1\u3CE2\u3CE3\u3CE4\u3CE5\u3CE6"+ - "\u3CE7\u3CE8\u3CE9\u3CEA\u3CEB\u3CEC\u3CED\u3CEE"+ - "\u3CEF\u3CF0\u3CF1\u3CF2\u3CF3\u3CF4\u3CF5\u3CF6"+ - "\u3CF7\u3CF8\u3CF9\u3CFA\u3CFB\u3CFC\u3CFD\u3CFE"+ - "\u3CFF\u3D00\u3D01\u3D02\u3D03\u3D04\u3D05\u3D06"+ - "\u3D07\u3D08\u3D09\u3D0A\u3D0B\u3D0C\u3D0D\u3D0E"+ - "\u3D0F\u3D10\u3D11\u3D12\u3D13\u3D14\u3D15\u3D16"+ - "\u3D17\u3D18\u3D19\u3D1A\u3D1B\u3D1C\u3D1D\u3D1E"+ - "\u3D1F\u3D20\u3D21\u3D22\u3D23\u3D24\u3D25\u3D26"+ - "\u3D27\u3D28\u3D29\u3D2A\u3D2B\u3D2C\u3D2D\u3D2E"+ - "\u3D2F\u3D30\u3D31\u3D32\u3D33\u3D34\u3D35\u3D36"+ - "\u3D37\u3D38\u3D39\u3D3A\u3D3B\u3D3C\u3D3D\u3D3E"+ - "\u3D3F\u3D40\u3D41\u3D42\u3D43\u3D44\u3D45\u3D46"+ - "\u3D47\u3D48\u3D49\u3D4A\u3D4B\u3D4C\u3D4D\u3D4E"+ - "\u3D4F\u3D50\u3D51\u3D52\u3D53\u3D54\u3D55\u3D56"+ - "\u3D57\u3D58\u3D59\u3D5A\u3D5B\u3D5C\u3D5D\u3D5E"+ - "\u3D5F\u3D60\u3D61\u3D62\u3D63\u3D64\u3D65\u3D66"+ - "\u3D67\u3D68\u3D69\u3D6A\u3D6B\u3D6C\u3D6D\u3D6E"+ - "\u3D6F\u3D70\u3D71\u3D72\u3D73\u3D74\u3D75\u3D76"+ - "\u3D77\u3D78\u3D79\u3D7A\u3D7B\u3D7C\u3D7D\u3D7E"+ - "\u3D7F\u3D80\u3D81\u3D82\u3D83\u3D84\u3D85\u3D86"+ - "\u3D87\u3D88\u3D89\u3D8A\u3D8B\u3D8C\u3D8D\u3D8E"+ - "\u3D8F\u3D90\u3D91\u3D92\u3D93\u3D94\u3D95\u3D96"+ - "\u3D97\u3D98\u3D99\u3D9A\u3D9B\u3D9C\u3D9D\u3D9E"+ - "\u3D9F\u3DA0\u3DA1\u3DA2\u3DA3\u3DA4\u3DA5\u3DA6"+ - "\u3DA7\u3DA8\u3DA9\u3DAA\u3DAB\u3DAC\u3DAD\u3DAE"+ - "\u3DAF\u3DB0\u3DB1\u3DB2\u3DB3\u3DB4\u3DB5\u3DB6"+ - "\u3DB7\u3DB8\u3DB9\u3DBA\u3DBB\u3DBC\u3DBD\u3DBE"+ - "\u3DBF\u3DC0\u3DC1\u3DC2\u3DC3\u3DC4\u3DC5\u3DC6"+ - "\u3DC7\u3DC8\u3DC9\u3DCA\u3DCB\u3DCC\u3DCD\u3DCE"+ - "\u3DCF\u3DD0\u3DD1\u3DD2\u3DD3\u3DD4\u3DD5\u3DD6"+ - "\u3DD7\u3DD8\u3DD9\u3DDA\u3DDB\u3DDC\u3DDD\u3DDE"+ - "\u3DDF\u3DE0\u3DE1\u3DE2\u3DE3\u3DE4\u3DE5\u3DE6"+ - "\u3DE7\u3DE8\u3DE9\u3DEA\u3DEB\u3DEC\u3DED\u3DEE"+ - "\u3DEF\u3DF0\u3DF1\u3DF2\u3DF3\u3DF4\u3DF5\u3DF6"+ - "\u3DF7\u3DF8\u3DF9\u3DFA\u3DFB\u3DFC\u3DFD\u3DFE"+ - "\u3DFF\u3E00\u3E01\u3E02\u3E03\u3E04\u3E05\u3E06"+ - "\u3E07\u3E08\u3E09\u3E0A\u3E0B\u3E0C\u3E0D\u3E0E"+ - "\u3E0F\u3E10\u3E11\u3E12\u3E13\u3E14\u3E15\u3E16"+ - "\u3E17\u3E18\u3E19\u3E1A\u3E1B\u3E1C\u3E1D\u3E1E"+ - "\u3E1F\u3E20\u3E21\u3E22\u3E23\u3E24\u3E25\u3E26"+ - "\u3E27\u3E28\u3E29\u3E2A\u3E2B\u3E2C\u3E2D\u3E2E"+ - "\u3E2F\u3E30\u3E31\u3E32\u3E33\u3E34\u3E35\u3E36"+ - "\u3E37\u3E38\u3E39\u3E3A\u3E3B\u3E3C\u3E3D\u3E3E"+ - "\u3E3F\u3E40\u3E41\u3E42\u3E43\u3E44\u3E45\u3E46"+ - "\u3E47\u3E48\u3E49\u3E4A\u3E4B\u3E4C\u3E4D\u3E4E"+ - "\u3E4F\u3E50\u3E51\u3E52\u3E53\u3E54\u3E55\u3E56"+ - "\u3E57\u3E58\u3E59\u3E5A\u3E5B\u3E5C\u3E5D\u3E5E"+ - "\u3E5F\u3E60\u3E61\u3E62\u3E63\u3E64\u3E65\u3E66"+ - "\u3E67\u3E68\u3E69\u3E6A\u3E6B\u3E6C\u3E6D\u3E6E"+ - "\u3E6F\u3E70\u3E71\u3E72\u3E73\u3E74\u3E75\u3E76"+ - "\u3E77\u3E78\u3E79\u3E7A\u3E7B\u3E7C\u3E7D\u3E7E"+ - "\u3E7F\u3E80\u3E81\u3E82\u3E83\u3E84\u3E85\u3E86"+ - "\u3E87\u3E88\u3E89\u3E8A\u3E8B\u3E8C\u3E8D\u3E8E"+ - "\u3E8F\u3E90\u3E91\u3E92\u3E93\u3E94\u3E95\u3E96"+ - "\u3E97\u3E98\u3E99\u3E9A\u3E9B\u3E9C\u3E9D\u3E9E"+ - "\u3E9F\u3EA0\u3EA1\u3EA2\u3EA3\u3EA4\u3EA5\u3EA6"+ - "\u3EA7\u3EA8\u3EA9\u3EAA\u3EAB\u3EAC\u3EAD\u3EAE"+ - "\u3EAF\u3EB0\u3EB1\u3EB2\u3EB3\u3EB4\u3EB5\u3EB6"+ - "\u3EB7\u3EB8\u3EB9\u3EBA\u3EBB\u3EBC\u3EBD\u3EBE"+ - "\u3EBF\u3EC0\u3EC1\u3EC2\u3EC3\u3EC4\u3EC5\u3EC6"+ - "\u3EC7\u3EC8\u3EC9\u3ECA\u3ECB\u3ECC\u3ECD\u3ECE"+ - "\u3ECF\u3ED0\u3ED1\u3ED2\u3ED3\u3ED4\u3ED5\u3ED6"+ - "\u3ED7\u3ED8\u3ED9\u3EDA\u3EDB\u3EDC\u3EDD\u3EDE"+ - "\u3EDF\u3EE0\u3EE1\u3EE2\u3EE3\u3EE4\u3EE5\u3EE6"+ - "\u3EE7\u3EE8\u3EE9\u3EEA\u3EEB\u3EEC\u3EED\u3EEE"+ - "\u3EEF\u3EF0\u3EF1\u3EF2\u3EF3\u3EF4\u3EF5\u3EF6"+ - "\u3EF7\u3EF8\u3EF9\u3EFA\u3EFB\u3EFC\u3EFD\u3EFE"+ - "\u3EFF\u3F00\u3F01\u3F02\u3F03\u3F04\u3F05\u3F06"+ - "\u3F07\u3F08\u3F09\u3F0A\u3F0B\u3F0C\u3F0D\u3F0E"+ - "\u3F0F\u3F10\u3F11\u3F12\u3F13\u3F14\u3F15\u3F16"+ - "\u3F17\u3F18\u3F19\u3F1A\u3F1B\u3F1C\u3F1D\u3F1E"+ - "\u3F1F\u3F20\u3F21\u3F22\u3F23\u3F24\u3F25\u3F26"+ - "\u3F27\u3F28\u3F29\u3F2A\u3F2B\u3F2C\u3F2D\u3F2E"+ - "\u3F2F\u3F30\u3F31\u3F32\u3F33\u3F34\u3F35\u3F36"+ - "\u3F37\u3F38\u3F39\u3F3A\u3F3B\u3F3C\u3F3D\u3F3E"+ - "\u3F3F\u3F40\u3F41\u3F42\u3F43\u3F44\u3F45\u3F46"+ - "\u3F47\u3F48\u3F49\u3F4A\u3F4B\u3F4C\u3F4D\u3F4E"+ - "\u3F4F\u3F50\u3F51\u3F52\u3F53\u3F54\u3F55\u3F56"+ - "\u3F57\u3F58\u3F59\u3F5A\u3F5B\u3F5C\u3F5D\u3F5E"+ - "\u3F5F\u3F60\u3F61\u3F62\u3F63\u3F64\u3F65\u3F66"+ - "\u3F67\u3F68\u3F69\u3F6A\u3F6B\u3F6C\u3F6D\u3F6E"+ - "\u3F6F\u3F70\u3F71\u3F72\u3F73\u3F74\u3F75\u3F76"+ - "\u3F77\u3F78\u3F79\u3F7A\u3F7B\u3F7C\u3F7D\u3F7E"+ - "\u3F7F\u3F80\u3F81\u3F82\u3F83\u3F84\u3F85\u3F86"+ - "\u3F87\u3F88\u3F89\u3F8A\u3F8B\u3F8C\u3F8D\u3F8E"+ - "\u3F8F\u3F90\u3F91\u3F92\u3F93\u3F94\u3F95\u3F96"+ - "\u3F97\u3F98\u3F99\u3F9A\u3F9B\u3F9C\u3F9D\u3F9E"+ - "\u3F9F\u3FA0\u3FA1\u3FA2\u3FA3\u3FA4\u3FA5\u3FA6"+ - "\u3FA7\u3FA8\u3FA9\u3FAA\u3FAB\u3FAC\u3FAD\u3FAE"+ - "\u3FAF\u3FB0\u3FB1\u3FB2\u3FB3\u3FB4\u3FB5\u3FB6"+ - "\u3FB7\u3FB8\u3FB9\u3FBA\u3FBB\u3FBC\u3FBD\u3FBE"+ - "\u3FBF\u3FC0\u3FC1\u3FC2\u3FC3\u3FC4\u3FC5\u3FC6"+ - "\u3FC7\u3FC8\u3FC9\u3FCA\u3FCB\u3FCC\u3FCD\u3FCE"+ - "\u3FCF\u3FD0\u3FD1\u3FD2\u3FD3\u3FD4\u3FD5\u3FD6"+ - "\u3FD7\u3FD8\u3FD9\u3FDA\u3FDB\u3FDC\u3FDD\u3FDE"+ - "\u3FDF\u3FE0\u3FE1\u3FE2\u3FE3\u3FE4\u3FE5\u3FE6"+ - "\u3FE7\u3FE8\u3FE9\u3FEA\u3FEB\u3FEC\u3FED\u3FEE"+ - "\u3FEF\u3FF0\u3FF1\u3FF2\u3FF3\u3FF4\u3FF5\u3FF6"+ - "\u3FF7\u3FF8\u3FF9\u3FFA\u3FFB\u3FFC\u3FFD\u3FFE"+ - "\u3FFF\u4000\u4001\u4002\u4003\u4004\u4005\u4006"+ - "\u4007\u4008\u4009\u400A\u400B\u400C\u400D\u400E"+ - "\u400F\u4010\u4011\u4012\u4013\u4014\u4015\u4016"+ - "\u4017\u4018\u4019\u401A\u401B\u401C\u401D\u401E"+ - "\u401F\u4020\u4021\u4022\u4023\u4024\u4025\u4026"+ - "\u4027\u4028\u4029\u402A\u402B\u402C\u402D\u402E"+ - "\u402F\u4030\u4031\u4032\u4033\u4034\u4035\u4036"+ - "\u4037\u4038\u4039\u403A\u403B\u403C\u403D\u403E"+ - "\u403F\u4040\u4041\u4042\u4043\u4044\u4045\u4046"+ - "\u4047\u4048\u4049\u404A\u404B\u404C\u404D\u404E"+ - "\u404F\u4050\u4051\u4052\u4053\u4054\u4055\u4057"+ - "\u4058\u4059\u405A\u405B\u405C\u405D\u405E\u405F"+ - "\u4060\u4061\u4062\u4063\u4064\u4065\u4066\u4067"+ - "\u4068\u4069\u406A\u406B\u406C\u406D\u406E\u406F"+ - "\u4070\u4071\u4072\u4073\u4074\u4075\u4076\u4077"+ - "\u4078\u4079\u407A\u407B\u407C\u407D\u407E\u407F"+ - "\u4080\u4081\u4082\u4083\u4084\u4085\u4086\u4087"+ - "\u4088\u4089\u408A\u408B\u408C\u408D\u408E\u408F"+ - "\u4090\u4091\u4092\u4093\u4094\u4095\u4096\u4097"+ - "\u4098\u4099\u409A\u409B\u409C\u409D\u409E\u409F"+ - "\u40A0\u40A1\u40A2\u40A3\u40A4\u40A5\u40A6\u40A7"+ - "\u40A8\u40A9\u40AA\u40AB\u40AC\u40AD\u40AE\u40AF"+ - "\u40B0\u40B1\u40B2\u40B3\u40B4\u40B5\u40B6\u40B7"+ - "\u40B8\u40B9\u40BA\u40BB\u40BC\u40BD\u40BE\u40BF"+ - "\u40C0\u40C1\u40C2\u40C3\u40C4\u40C5\u40C6\u40C7"+ - "\u40C8\u40C9\u40CA\u40CB\u40CC\u40CD\u40CE\u40CF"+ - "\u40D0\u40D1\u40D2\u40D3\u40D4\u40D5\u40D6\u40D7"+ - "\u40D8\u40D9\u40DA\u40DB\u40DC\u40DD\u40DE\u40DF"+ - "\u40E0\u40E1\u40E2\u40E3\u40E4\u40E5\u40E6\u40E7"+ - "\u40E8\u40E9\u40EA\u40EB\u40EC\u40ED\u40EE\u40EF"+ - "\u40F0\u40F1\u40F2\u40F3\u40F4\u40F5\u40F6\u40F7"+ - "\u40F8\u40F9\u40FA\u40FB\u40FC\u40FD\u40FE\u40FF"+ - "\u4100\u4101\u4102\u4103\u4104\u4105\u4106\u4107"+ - "\u4108\u4109\u410A\u410B\u410C\u410D\u410E\u410F"+ - "\u4110\u4111\u4112\u4113\u4114\u4115\u4116\u4117"+ - "\u4118\u4119\u411A\u411B\u411C\u411D\u411E\u411F"+ - "\u4120\u4121\u4122\u4123\u4124\u4125\u4126\u4127"+ - "\u4128\u4129\u412A\u412B\u412C\u412D\u412E\u412F"+ - "\u4130\u4131\u4132\u4133\u4134\u4135\u4136\u4137"+ - "\u4138\u4139\u413A\u413B\u413C\u413D\u413E\u413F"+ - "\u4140\u4141\u4142\u4143\u4144\u4145\u4146\u4147"+ - "\u4148\u4149\u414A\u414B\u414C\u414D\u414E\u414F"+ - "\u4150\u4151\u4152\u4153\u4154\u4155\u4156\u4157"+ - "\u4158\u4159\u415A\u415B\u415C\u415D\u415E\u4160"+ - "\u4161\u4162\u4163\u4164\u4165\u4166\u4167\u4168"+ - "\u4169\u416A\u416B\u416C\u416D\u416E\u416F\u4170"+ - "\u4171\u4172\u4173\u4174\u4175\u4176\u4177\u4178"+ - "\u4179\u417A\u417B\u417C\u417D\u417E\u417F\u4180"+ - "\u4181\u4182\u4183\u4184\u4185\u4186\u4187\u4188"+ - "\u4189\u418A\u418B\u418C\u418D\u418E\u418F\u4190"+ - "\u4191\u4192\u4193\u4194\u4195\u4196\u4197\u4198"+ - "\u4199\u419A\u419B\u419C\u419D\u419E\u419F\u41A0"+ - "\u41A1\u41A2\u41A3\u41A4\u41A5\u41A6\u41A7\u41A8"+ - "\u41A9\u41AA\u41AB\u41AC\u41AD\u41AE\u41AF\u41B0"+ - "\u41B1\u41B2\u41B3\u41B4\u41B5\u41B6\u41B7\u41B8"+ - "\u41B9\u41BA\u41BB\u41BC\u41BD\u41BE\u41BF\u41C0"+ - "\u41C1\u41C2\u41C3\u41C4\u41C5\u41C6\u41C7\u41C8"+ - "\u41C9\u41CA\u41CB\u41CC\u41CD\u41CE\u41CF\u41D0"+ - "\u41D1\u41D2\u41D3\u41D4\u41D5\u41D6\u41D7\u41D8"+ - "\u41D9\u41DA\u41DB\u41DC\u41DD\u41DE\u41DF\u41E0"+ - "\u41E1\u41E2\u41E3\u41E4\u41E5\u41E6\u41E7\u41E8"+ - "\u41E9\u41EA\u41EB\u41EC\u41ED\u41EE\u41EF\u41F0"+ - "\u41F1\u41F2\u41F3\u41F4\u41F5\u41F6\u41F7\u41F8"+ - "\u41F9\u41FA\u41FB\u41FC\u41FD\u41FE\u41FF\u4200"+ - "\u4201\u4202\u4203\u4204\u4205\u4206\u4207\u4208"+ - "\u4209\u420A\u420B\u420C\u420D\u420E\u420F\u4210"+ - "\u4211\u4212\u4213\u4214\u4215\u4216\u4217\u4218"+ - "\u4219\u421A\u421B\u421C\u421D\u421E\u421F\u4220"+ - "\u4221\u4222\u4223\u4224\u4225\u4226\u4227\u4228"+ - "\u4229\u422A\u422B\u422C\u422D\u422E\u422F\u4230"+ - "\u4231\u4232\u4233\u4234\u4235\u4236\u4237\u4238"+ - "\u4239\u423A\u423B\u423C\u423D\u423E\u423F\u4240"+ - "\u4241\u4242\u4243\u4244\u4245\u4246\u4247\u4248"+ - "\u4249\u424A\u424B\u424C\u424D\u424E\u424F\u4250"+ - "\u4251\u4252\u4253\u4254\u4255\u4256\u4257\u4258"+ - "\u4259\u425A\u425B\u425C\u425D\u425E\u425F\u4260"+ - "\u4261\u4262\u4263\u4264\u4265\u4266\u4267\u4268"+ - "\u4269\u426A\u426B\u426C\u426D\u426E\u426F\u4270"+ - "\u4271\u4272\u4273\u4274\u4275\u4276\u4277\u4278"+ - "\u4279\u427A\u427B\u427C\u427D\u427E\u427F\u4280"+ - "\u4281\u4282\u4283\u4284\u4285\u4286\u4287\u4288"+ - "\u4289\u428A\u428B\u428C\u428D\u428E\u428F\u4290"+ - "\u4291\u4292\u4293\u4294\u4295\u4296\u4297\u4298"+ - "\u4299\u429A\u429B\u429C\u429D\u429E\u429F\u42A0"+ - "\u42A1\u42A2\u42A3\u42A4\u42A5\u42A6\u42A7\u42A8"+ - "\u42A9\u42AA\u42AB\u42AC\u42AD\u42AE\u42AF\u42B0"+ - "\u42B1\u42B2\u42B3\u42B4\u42B5\u42B6\u42B7\u42B8"+ - "\u42B9\u42BA\u42BB\u42BC\u42BD\u42BE\u42BF\u42C0"+ - "\u42C1\u42C2\u42C3\u42C4\u42C5\u42C6\u42C7\u42C8"+ - "\u42C9\u42CA\u42CB\u42CC\u42CD\u42CE\u42CF\u42D0"+ - "\u42D1\u42D2\u42D3\u42D4\u42D5\u42D6\u42D7\u42D8"+ - "\u42D9\u42DA\u42DB\u42DC\u42DD\u42DE\u42DF\u42E0"+ - "\u42E1\u42E2\u42E3\u42E4\u42E5\u42E6\u42E7\u42E8"+ - "\u42E9\u42EA\u42EB\u42EC\u42ED\u42EE\u42EF\u42F0"+ - "\u42F1\u42F2\u42F3\u42F4\u42F5\u42F6\u42F7\u42F8"+ - "\u42F9\u42FA\u42FB\u42FC\u42FD\u42FE\u42FF\u4300"+ - "\u4301\u4302\u4303\u4304\u4305\u4306\u4307\u4308"+ - "\u4309\u430A\u430B\u430C\u430D\u430E\u430F\u4310"+ - "\u4311\u4312\u4313\u4314\u4315\u4316\u4317\u4318"+ - "\u4319\u431A\u431B\u431C\u431D\u431E\u431F\u4320"+ - "\u4321\u4322\u4323\u4324\u4325\u4326\u4327\u4328"+ - "\u4329\u432A\u432B\u432C\u432D\u432E\u432F\u4330"+ - "\u4331\u4332\u4333\u4334\u4335\u4336\u4338\u4339"+ - "\u433A\u433B\u433C\u433D\u433E\u433F\u4340\u4341"+ - "\u4342\u4343\u4344\u4345\u4346\u4347\u4348\u4349"+ - "\u434A\u434B\u434C\u434D\u434E\u434F\u4350\u4351"+ - "\u4352\u4353\u4354\u4355\u4356\u4357\u4358\u4359"+ - "\u435A\u435B\u435C\u435D\u435E\u435F\u4360\u4361"+ - "\u4362\u4363\u4364\u4365\u4366\u4367\u4368\u4369"+ - "\u436A\u436B\u436C\u436D\u436E\u436F\u4370\u4371"+ - "\u4372\u4373\u4374\u4375\u4376\u4377\u4378\u4379"; - - private static final String innerDecoderIndex4= - "\u437A\u437B\u437C\u437D\u437E\u437F\u4380\u4381"+ - "\u4382\u4383\u4384\u4385\u4386\u4387\u4388\u4389"+ - "\u438A\u438B\u438C\u438D\u438E\u438F\u4390\u4391"+ - "\u4392\u4393\u4394\u4395\u4396\u4397\u4398\u4399"+ - "\u439A\u439B\u439C\u439D\u439E\u439F\u43A0\u43A1"+ - "\u43A2\u43A3\u43A4\u43A5\u43A6\u43A7\u43A8\u43A9"+ - "\u43AA\u43AB\u43AD\u43AE\u43AF\u43B0\u43B2\u43B3"+ - "\u43B4\u43B5\u43B6\u43B7\u43B8\u43B9\u43BA\u43BB"+ - "\u43BC\u43BD\u43BE\u43BF\u43C0\u43C1\u43C2\u43C3"+ - "\u43C4\u43C5\u43C6\u43C7\u43C8\u43C9\u43CA\u43CB"+ - "\u43CC\u43CD\u43CE\u43CF\u43D0\u43D1\u43D2\u43D3"+ - "\u43D4\u43D5\u43D6\u43D7\u43D8\u43D9\u43DA\u43DB"+ - "\u43DC\u43DE\u43DF\u43E0\u43E1\u43E2\u43E3\u43E4"+ - "\u43E5\u43E6\u43E7\u43E8\u43E9\u43EA\u43EB\u43EC"+ - "\u43ED\u43EE\u43EF\u43F0\u43F1\u43F2\u43F3\u43F4"+ - "\u43F5\u43F6\u43F7\u43F8\u43F9\u43FA\u43FB\u43FC"+ - "\u43FD\u43FE\u43FF\u4400\u4401\u4402\u4403\u4404"+ - "\u4405\u4406\u4407\u4408\u4409\u440A\u440B\u440C"+ - "\u440D\u440E\u440F\u4410\u4411\u4412\u4413\u4414"+ - "\u4415\u4416\u4417\u4418\u4419\u441A\u441B\u441C"+ - "\u441D\u441E\u441F\u4420\u4421\u4422\u4423\u4424"+ - "\u4425\u4426\u4427\u4428\u4429\u442A\u442B\u442C"+ - "\u442D\u442E\u442F\u4430\u4431\u4432\u4433\u4434"+ - "\u4435\u4436\u4437\u4438\u4439\u443A\u443B\u443C"+ - "\u443D\u443E\u443F\u4440\u4441\u4442\u4443\u4444"+ - "\u4445\u4446\u4447\u4448\u4449\u444A\u444B\u444C"+ - "\u444D\u444E\u444F\u4450\u4451\u4452\u4453\u4454"+ - "\u4455\u4456\u4457\u4458\u4459\u445A\u445B\u445C"+ - "\u445D\u445E\u445F\u4460\u4461\u4462\u4463\u4464"+ - "\u4465\u4466\u4467\u4468\u4469\u446A\u446B\u446C"+ - "\u446D\u446E\u446F\u4470\u4471\u4472\u4473\u4474"+ - "\u4475\u4476\u4477\u4478\u4479\u447A\u447B\u447C"+ - "\u447D\u447E\u447F\u4480\u4481\u4482\u4483\u4484"+ - "\u4485\u4486\u4487\u4488\u4489\u448A\u448B\u448C"+ - "\u448D\u448E\u448F\u4490\u4491\u4492\u4493\u4494"+ - "\u4495\u4496\u4497\u4498\u4499\u449A\u449B\u449C"+ - "\u449D\u449E\u449F\u44A0\u44A1\u44A2\u44A3\u44A4"+ - "\u44A5\u44A6\u44A7\u44A8\u44A9\u44AA\u44AB\u44AC"+ - "\u44AD\u44AE\u44AF\u44B0\u44B1\u44B2\u44B3\u44B4"+ - "\u44B5\u44B6\u44B7\u44B8\u44B9\u44BA\u44BB\u44BC"+ - "\u44BD\u44BE\u44BF\u44C0\u44C1\u44C2\u44C3\u44C4"+ - "\u44C5\u44C6\u44C7\u44C8\u44C9\u44CA\u44CB\u44CC"+ - "\u44CD\u44CE\u44CF\u44D0\u44D1\u44D2\u44D3\u44D4"+ - "\u44D5\u44D7\u44D8\u44D9\u44DA\u44DB\u44DC\u44DD"+ - "\u44DE\u44DF\u44E0\u44E1\u44E2\u44E3\u44E4\u44E5"+ - "\u44E6\u44E7\u44E8\u44E9\u44EA\u44EB\u44EC\u44ED"+ - "\u44EE\u44EF\u44F0\u44F1\u44F2\u44F3\u44F4\u44F5"+ - "\u44F6\u44F7\u44F8\u44F9\u44FA\u44FB\u44FC\u44FD"+ - "\u44FE\u44FF\u4500\u4501\u4502\u4503\u4504\u4505"+ - "\u4506\u4507\u4508\u4509\u450A\u450B\u450C\u450D"+ - "\u450E\u450F\u4510\u4511\u4512\u4513\u4514\u4515"+ - "\u4516\u4517\u4518\u4519\u451A\u451B\u451C\u451D"+ - "\u451E\u451F\u4520\u4521\u4522\u4523\u4524\u4525"+ - "\u4526\u4527\u4528\u4529\u452A\u452B\u452C\u452D"+ - "\u452E\u452F\u4530\u4531\u4532\u4533\u4534\u4535"+ - "\u4536\u4537\u4538\u4539\u453A\u453B\u453C\u453D"+ - "\u453E\u453F\u4540\u4541\u4542\u4543\u4544\u4545"+ - "\u4546\u4547\u4548\u4549\u454A\u454B\u454C\u454D"+ - "\u454E\u454F\u4550\u4551\u4552\u4553\u4554\u4555"+ - "\u4556\u4557\u4558\u4559\u455A\u455B\u455C\u455D"+ - "\u455E\u455F\u4560\u4561\u4562\u4563\u4564\u4565"+ - "\u4566\u4567\u4568\u4569\u456A\u456B\u456C\u456D"+ - "\u456E\u456F\u4570\u4571\u4572\u4573\u4574\u4575"+ - "\u4576\u4577\u4578\u4579\u457A\u457B\u457C\u457D"+ - "\u457E\u457F\u4580\u4581\u4582\u4583\u4584\u4585"+ - "\u4586\u4587\u4588\u4589\u458A\u458B\u458C\u458D"+ - "\u458E\u458F\u4590\u4591\u4592\u4593\u4594\u4595"+ - "\u4596\u4597\u4598\u4599\u459A\u459B\u459C\u459D"+ - "\u459E\u459F\u45A0\u45A1\u45A2\u45A3\u45A4\u45A5"+ - "\u45A6\u45A7\u45A8\u45A9\u45AA\u45AB\u45AC\u45AD"+ - "\u45AE\u45AF\u45B0\u45B1\u45B2\u45B3\u45B4\u45B5"+ - "\u45B6\u45B7\u45B8\u45B9\u45BA\u45BB\u45BC\u45BD"+ - "\u45BE\u45BF\u45C0\u45C1\u45C2\u45C3\u45C4\u45C5"+ - "\u45C6\u45C7\u45C8\u45C9\u45CA\u45CB\u45CC\u45CD"+ - "\u45CE\u45CF\u45D0\u45D1\u45D2\u45D3\u45D4\u45D5"+ - "\u45D6\u45D7\u45D8\u45D9\u45DA\u45DB\u45DC\u45DD"+ - "\u45DE\u45DF\u45E0\u45E1\u45E2\u45E3\u45E4\u45E5"+ - "\u45E6\u45E7\u45E8\u45E9\u45EA\u45EB\u45EC\u45ED"+ - "\u45EE\u45EF\u45F0\u45F1\u45F2\u45F3\u45F4\u45F5"+ - "\u45F6\u45F7\u45F8\u45F9\u45FA\u45FB\u45FC\u45FD"+ - "\u45FE\u45FF\u4600\u4601\u4602\u4603\u4604\u4605"+ - "\u4606\u4607\u4608\u4609\u460A\u460B\u460C\u460D"+ - "\u460E\u460F\u4610\u4611\u4612\u4613\u4614\u4615"+ - "\u4616\u4617\u4618\u4619\u461A\u461B\u461C\u461D"+ - "\u461E\u461F\u4620\u4621\u4622\u4623\u4624\u4625"+ - "\u4626\u4627\u4628\u4629\u462A\u462B\u462C\u462D"+ - "\u462E\u462F\u4630\u4631\u4632\u4633\u4634\u4635"+ - "\u4636\u4637\u4638\u4639\u463A\u463B\u463C\u463D"+ - "\u463E\u463F\u4640\u4641\u4642\u4643\u4644\u4645"+ - "\u4646\u4647\u4648\u4649\u464A\u464B\u464D\u464E"+ - "\u464F\u4650\u4651\u4652\u4653\u4654\u4655\u4656"+ - "\u4657\u4658\u4659\u465A\u465B\u465C\u465D\u465E"+ - "\u465F\u4660\u4662\u4663\u4664\u4665\u4666\u4667"+ - "\u4668\u4669\u466A\u466B\u466C\u466D\u466E\u466F"+ - "\u4670\u4671\u4672\u4673\u4674\u4675\u4676\u4677"+ - "\u4678\u4679\u467A\u467B\u467C\u467D\u467E\u467F"+ - "\u4680\u4681\u4682\u4683\u4684\u4685\u4686\u4687"+ - "\u4688\u4689\u468A\u468B\u468C\u468D\u468E\u468F"+ - "\u4690\u4691\u4692\u4693\u4694\u4695\u4696\u4697"+ - "\u4698\u4699\u469A\u469B\u469C\u469D\u469E\u469F"+ - "\u46A0\u46A1\u46A2\u46A3\u46A4\u46A5\u46A6\u46A7"+ - "\u46A8\u46A9\u46AA\u46AB\u46AC\u46AD\u46AE\u46AF"+ - "\u46B0\u46B1\u46B2\u46B3\u46B4\u46B5\u46B6\u46B7"+ - "\u46B8\u46B9\u46BA\u46BB\u46BC\u46BD\u46BE\u46BF"+ - "\u46C0\u46C1\u46C2\u46C3\u46C4\u46C5\u46C6\u46C7"+ - "\u46C8\u46C9\u46CA\u46CB\u46CC\u46CD\u46CE\u46CF"+ - "\u46D0\u46D1\u46D2\u46D3\u46D4\u46D5\u46D6\u46D7"+ - "\u46D8\u46D9\u46DA\u46DB\u46DC\u46DD\u46DE\u46DF"+ - "\u46E0\u46E1\u46E2\u46E3\u46E4\u46E5\u46E6\u46E7"+ - "\u46E8\u46E9\u46EA\u46EB\u46EC\u46ED\u46EE\u46EF"+ - "\u46F0\u46F1\u46F2\u46F3\u46F4\u46F5\u46F6\u46F7"+ - "\u46F8\u46F9\u46FA\u46FB\u46FC\u46FD\u46FE\u46FF"+ - "\u4700\u4701\u4702\u4703\u4704\u4705\u4706\u4707"+ - "\u4708\u4709\u470A\u470B\u470C\u470D\u470E\u470F"+ - "\u4710\u4711\u4712\u4713\u4714\u4715\u4716\u4717"+ - "\u4718\u4719\u471A\u471B\u471C\u471D\u471E\u471F"+ - "\u4720\u4721\u4722\u4724\u4725\u4726\u4727\u4728"+ - "\u472A\u472B\u472C\u472D\u472E\u472F\u4730\u4731"+ - "\u4732\u4733\u4734\u4735\u4736\u4737\u4738\u4739"+ - "\u473A\u473B\u473C\u473D\u473E\u473F\u4740\u4741"+ - "\u4742\u4743\u4744\u4745\u4746\u4747\u4748\u4749"+ - "\u474A\u474B\u474C\u474D\u474E\u474F\u4750\u4751"+ - "\u4752\u4753\u4754\u4755\u4756\u4757\u4758\u4759"+ - "\u475A\u475B\u475C\u475D\u475E\u475F\u4760\u4761"+ - "\u4762\u4763\u4764\u4765\u4766\u4767\u4768\u4769"+ - "\u476A\u476B\u476C\u476D\u476E\u476F\u4770\u4771"+ - "\u4772\u4773\u4774\u4775\u4776\u4777\u4778\u4779"+ - "\u477A\u477B\u477D\u477E\u477F\u4780\u4781\u4782"+ - "\u4783\u4784\u4785\u4786\u4787\u4788\u4789\u478A"+ - "\u478B\u478C\u478E\u478F\u4790\u4791\u4792\u4793"+ - "\u4794\u4795\u4796\u4797\u4798\u4799\u479A\u479B"+ - "\u479C\u479D\u479E\u479F\u47A0\u47A1\u47A2\u47A3"+ - "\u47A4\u47A5\u47A6\u47A7\u47A8\u47A9\u47AA\u47AB"+ - "\u47AC\u47AD\u47AE\u47AF\u47B0\u47B1\u47B2\u47B3"+ - "\u47B4\u47B5\u47B6\u47B7\u47B8\u47B9\u47BA\u47BB"+ - "\u47BC\u47BD\u47BE\u47BF\u47C0\u47C1\u47C2\u47C3"+ - "\u47C4\u47C5\u47C6\u47C7\u47C8\u47C9\u47CA\u47CB"+ - "\u47CC\u47CD\u47CE\u47CF\u47D0\u47D1\u47D2\u47D3"+ - "\u47D4\u47D5\u47D6\u47D7\u47D8\u47D9\u47DA\u47DB"+ - "\u47DC\u47DD\u47DE\u47DF\u47E0\u47E1\u47E2\u47E3"+ - "\u47E4\u47E5\u47E6\u47E7\u47E8\u47E9\u47EA\u47EB"+ - "\u47EC\u47ED\u47EE\u47EF\u47F0\u47F1\u47F2\u47F3"+ - "\u47F4\u47F5\u47F6\u47F7\u47F8\u47F9\u47FA\u47FB"+ - "\u47FC\u47FD\u47FE\u47FF\u4800\u4801\u4802\u4803"+ - "\u4804\u4805\u4806\u4807\u4808\u4809\u480A\u480B"+ - "\u480C\u480D\u480E\u480F\u4810\u4811\u4812\u4813"+ - "\u4814\u4815\u4816\u4817\u4818\u4819\u481A\u481B"+ - "\u481C\u481D\u481E\u481F\u4820\u4821\u4822\u4823"+ - "\u4824\u4825\u4826\u4827\u4828\u4829\u482A\u482B"+ - "\u482C\u482D\u482E\u482F\u4830\u4831\u4832\u4833"+ - "\u4834\u4835\u4836\u4837\u4838\u4839\u483A\u483B"+ - "\u483C\u483D\u483E\u483F\u4840\u4841\u4842\u4843"+ - "\u4844\u4845\u4846\u4847\u4848\u4849\u484A\u484B"+ - "\u484C\u484D\u484E\u484F\u4850\u4851\u4852\u4853"+ - "\u4854\u4855\u4856\u4857\u4858\u4859\u485A\u485B"+ - "\u485C\u485D\u485E\u485F\u4860\u4861\u4862\u4863"+ - "\u4864\u4865\u4866\u4867\u4868\u4869\u486A\u486B"+ - "\u486C\u486D\u486E\u486F\u4870\u4871\u4872\u4873"+ - "\u4874\u4875\u4876\u4877\u4878\u4879\u487A\u487B"+ - "\u487C\u487D\u487E\u487F\u4880\u4881\u4882\u4883"+ - "\u4884\u4885\u4886\u4887\u4888\u4889\u488A\u488B"+ - "\u488C\u488D\u488E\u488F\u4890\u4891\u4892\u4893"+ - "\u4894\u4895\u4896\u4897\u4898\u4899\u489A\u489B"+ - "\u489C\u489D\u489E\u489F\u48A0\u48A1\u48A2\u48A3"+ - "\u48A4\u48A5\u48A6\u48A7\u48A8\u48A9\u48AA\u48AB"+ - "\u48AC\u48AD\u48AE\u48AF\u48B0\u48B1\u48B2\u48B3"+ - "\u48B4\u48B5\u48B6\u48B7\u48B8\u48B9\u48BA\u48BB"+ - "\u48BC\u48BD\u48BE\u48BF\u48C0\u48C1\u48C2\u48C3"+ - "\u48C4\u48C5\u48C6\u48C7\u48C8\u48C9\u48CA\u48CB"+ - "\u48CC\u48CD\u48CE\u48CF\u48D0\u48D1\u48D2\u48D3"+ - "\u48D4\u48D5\u48D6\u48D7\u48D8\u48D9\u48DA\u48DB"+ - "\u48DC\u48DD\u48DE\u48DF\u48E0\u48E1\u48E2\u48E3"+ - "\u48E4\u48E5\u48E6\u48E7\u48E8\u48E9\u48EA\u48EB"+ - "\u48EC\u48ED\u48EE\u48EF\u48F0\u48F1\u48F2\u48F3"+ - "\u48F4\u48F5\u48F6\u48F7\u48F8\u48F9\u48FA\u48FB"+ - "\u48FC\u48FD\u48FE\u48FF\u4900\u4901\u4902\u4903"+ - "\u4904\u4905\u4906\u4907\u4908\u4909\u490A\u490B"+ - "\u490C\u490D\u490E\u490F\u4910\u4911\u4912\u4913"+ - "\u4914\u4915\u4916\u4917\u4918\u4919\u491A\u491B"+ - "\u491C\u491D\u491E\u491F\u4920\u4921\u4922\u4923"+ - "\u4924\u4925\u4926\u4927\u4928\u4929\u492A\u492B"+ - "\u492C\u492D\u492E\u492F\u4930\u4931\u4932\u4933"+ - "\u4934\u4935\u4936\u4937\u4938\u4939\u493A\u493B"+ - "\u493C\u493D\u493E\u493F\u4940\u4941\u4942\u4943"+ - "\u4944\u4945\u4946\u4948\u4949\u494A\u494B\u494C"+ - "\u494D\u494E\u494F\u4950\u4951\u4952\u4953\u4954"+ - "\u4955\u4956\u4957\u4958\u4959\u495A\u495B\u495C"+ - "\u495D\u495E\u495F\u4960\u4961\u4962\u4963\u4964"+ - "\u4965\u4966\u4967\u4968\u4969\u496A\u496B\u496C"+ - "\u496D\u496E\u496F\u4970\u4971\u4972\u4973\u4974"+ - "\u4975\u4976\u4977\u4978\u4979\u497B\u497C\u497E"+ - "\u497F\u4980\u4981\u4984\u4987\u4988\u4989\u498A"+ - "\u498B\u498C\u498D\u498E\u498F\u4990\u4991\u4992"+ - "\u4993\u4994\u4995\u4996\u4997\u4998\u4999\u499A"+ - "\u499C\u499D\u499E\u49A0\u49A1\u49A2\u49A3\u49A4"+ - "\u49A5\u49A6\u49A7\u49A8\u49A9\u49AA\u49AB\u49AC"+ - "\u49AD\u49AE\u49AF\u49B0\u49B1\u49B2\u49B3\u49B4"+ - "\u49B5\u49B8\u49B9\u49BA\u49BB\u49BC\u49BD\u49BE"+ - "\u49BF\u49C0\u49C1\u49C2\u49C3\u49C4\u49C5\u49C6"+ - "\u49C7\u49C8\u49C9\u49CA\u49CB\u49CC\u49CD\u49CE"+ - "\u49CF\u49D0\u49D1\u49D2\u49D3\u49D4\u49D5\u49D6"+ - "\u49D7\u49D8\u49D9\u49DA\u49DB\u49DC\u49DD\u49DE"+ - "\u49DF\u49E0\u49E1\u49E2\u49E3\u49E4\u49E5\u49E6"+ - "\u49E7\u49E8\u49E9\u49EA\u49EB\u49EC\u49ED\u49EE"+ - "\u49EF\u49F0\u49F1\u49F2\u49F3\u49F4\u49F5\u49F6"+ - "\u49F7\u49F8\u49F9\u49FA\u49FB\u49FC\u49FD\u49FE"+ - "\u49FF\u4A00\u4A01\u4A02\u4A03\u4A04\u4A05\u4A06"+ - "\u4A07\u4A08\u4A09\u4A0A\u4A0B\u4A0C\u4A0D\u4A0E"+ - "\u4A0F\u4A10\u4A11\u4A12\u4A13\u4A14\u4A15\u4A16"+ - "\u4A17\u4A18\u4A19\u4A1A\u4A1B\u4A1C\u4A1D\u4A1E"+ - "\u4A1F\u4A20\u4A21\u4A22\u4A23\u4A24\u4A25\u4A26"+ - "\u4A27\u4A28\u4A29\u4A2A\u4A2B\u4A2C\u4A2D\u4A2E"+ - "\u4A2F\u4A30\u4A31\u4A32\u4A33\u4A34\u4A35\u4A36"+ - "\u4A37\u4A38\u4A39\u4A3A\u4A3B\u4A3C\u4A3D\u4A3E"+ - "\u4A3F\u4A40\u4A41\u4A42\u4A43\u4A44\u4A45\u4A46"+ - "\u4A47\u4A48\u4A49\u4A4A\u4A4B\u4A4C\u4A4D\u4A4E"+ - "\u4A4F\u4A50\u4A51\u4A52\u4A53\u4A54\u4A55\u4A56"+ - "\u4A57\u4A58\u4A59\u4A5A\u4A5B\u4A5C\u4A5D\u4A5E"+ - "\u4A5F\u4A60\u4A61\u4A62\u4A63\u4A64\u4A65\u4A66"+ - "\u4A67\u4A68\u4A69\u4A6A\u4A6B\u4A6C\u4A6D\u4A6E"+ - "\u4A6F\u4A70\u4A71\u4A72\u4A73\u4A74\u4A75\u4A76"+ - "\u4A77\u4A78\u4A79\u4A7A\u4A7B\u4A7C\u4A7D\u4A7E"+ - "\u4A7F\u4A80\u4A81\u4A82\u4A83\u4A84\u4A85\u4A86"+ - "\u4A87\u4A88\u4A89\u4A8A\u4A8B\u4A8C\u4A8D\u4A8E"+ - "\u4A8F\u4A90\u4A91\u4A92\u4A93\u4A94\u4A95\u4A96"+ - "\u4A97\u4A98\u4A99\u4A9A\u4A9B\u4A9C\u4A9D\u4A9E"+ - "\u4A9F\u4AA0\u4AA1\u4AA2\u4AA3\u4AA4\u4AA5\u4AA6"+ - "\u4AA7\u4AA8\u4AA9\u4AAA\u4AAB\u4AAC\u4AAD\u4AAE"+ - "\u4AAF\u4AB0\u4AB1\u4AB2\u4AB3\u4AB4\u4AB5\u4AB6"+ - "\u4AB7\u4AB8\u4AB9\u4ABA\u4ABB\u4ABC\u4ABD\u4ABE"+ - "\u4ABF\u4AC0\u4AC1\u4AC2\u4AC3\u4AC4\u4AC5\u4AC6"+ - "\u4AC7\u4AC8\u4AC9\u4ACA\u4ACB\u4ACC\u4ACD\u4ACE"+ - "\u4ACF\u4AD0\u4AD1\u4AD2\u4AD3\u4AD4\u4AD5\u4AD6"+ - "\u4AD7\u4AD8\u4AD9\u4ADA\u4ADB\u4ADC\u4ADD\u4ADE"+ - "\u4ADF\u4AE0\u4AE1\u4AE2\u4AE3\u4AE4\u4AE5\u4AE6"+ - "\u4AE7\u4AE8\u4AE9\u4AEA\u4AEB\u4AEC\u4AED\u4AEE"+ - "\u4AEF\u4AF0\u4AF1\u4AF2\u4AF3\u4AF4\u4AF5\u4AF6"+ - "\u4AF7\u4AF8\u4AF9\u4AFA\u4AFB\u4AFC\u4AFD\u4AFE"+ - "\u4AFF\u4B00\u4B01\u4B02\u4B03\u4B04\u4B05\u4B06"+ - "\u4B07\u4B08\u4B09\u4B0A\u4B0B\u4B0C\u4B0D\u4B0E"+ - "\u4B0F\u4B10\u4B11\u4B12\u4B13\u4B14\u4B15\u4B16"+ - "\u4B17\u4B18\u4B19\u4B1A\u4B1B\u4B1C\u4B1D\u4B1E"+ - "\u4B1F\u4B20\u4B21\u4B22\u4B23\u4B24\u4B25\u4B26"+ - "\u4B27\u4B28\u4B29\u4B2A\u4B2B\u4B2C\u4B2D\u4B2E"+ - "\u4B2F\u4B30\u4B31\u4B32\u4B33\u4B34\u4B35\u4B36"+ - "\u4B37\u4B38\u4B39\u4B3A\u4B3B\u4B3C\u4B3D\u4B3E"+ - "\u4B3F\u4B40\u4B41\u4B42\u4B43\u4B44\u4B45\u4B46"+ - "\u4B47\u4B48\u4B49\u4B4A\u4B4B\u4B4C\u4B4D\u4B4E"+ - "\u4B4F\u4B50\u4B51\u4B52\u4B53\u4B54\u4B55\u4B56"+ - "\u4B57\u4B58\u4B59\u4B5A\u4B5B\u4B5C\u4B5D\u4B5E"+ - "\u4B5F\u4B60\u4B61\u4B62\u4B63\u4B64\u4B65\u4B66"+ - "\u4B67\u4B68\u4B69\u4B6A\u4B6B\u4B6C\u4B6D\u4B6E"+ - "\u4B6F\u4B70\u4B71\u4B72\u4B73\u4B74\u4B75\u4B76"+ - "\u4B77\u4B78\u4B79\u4B7A\u4B7B\u4B7C\u4B7D\u4B7E"+ - "\u4B7F\u4B80\u4B81\u4B82\u4B83\u4B84\u4B85\u4B86"+ - "\u4B87\u4B88\u4B89\u4B8A\u4B8B\u4B8C\u4B8D\u4B8E"+ - "\u4B8F\u4B90\u4B91\u4B92\u4B93\u4B94\u4B95\u4B96"+ - "\u4B97\u4B98\u4B99\u4B9A\u4B9B\u4B9C\u4B9D\u4B9E"+ - "\u4B9F\u4BA0\u4BA1\u4BA2\u4BA3\u4BA4\u4BA5\u4BA6"+ - "\u4BA7\u4BA8\u4BA9\u4BAA\u4BAB\u4BAC\u4BAD\u4BAE"+ - "\u4BAF\u4BB0\u4BB1\u4BB2\u4BB3\u4BB4\u4BB5\u4BB6"+ - "\u4BB7\u4BB8\u4BB9\u4BBA\u4BBB\u4BBC\u4BBD\u4BBE"+ - "\u4BBF\u4BC0\u4BC1\u4BC2\u4BC3\u4BC4\u4BC5\u4BC6"+ - "\u4BC7\u4BC8\u4BC9\u4BCA\u4BCB\u4BCC\u4BCD\u4BCE"+ - "\u4BCF\u4BD0\u4BD1\u4BD2\u4BD3\u4BD4\u4BD5\u4BD6"+ - "\u4BD7\u4BD8\u4BD9\u4BDA\u4BDB\u4BDC\u4BDD\u4BDE"+ - "\u4BDF\u4BE0\u4BE1\u4BE2\u4BE3\u4BE4\u4BE5\u4BE6"+ - "\u4BE7\u4BE8\u4BE9\u4BEA\u4BEB\u4BEC\u4BED\u4BEE"+ - "\u4BEF\u4BF0\u4BF1\u4BF2\u4BF3\u4BF4\u4BF5\u4BF6"+ - "\u4BF7\u4BF8\u4BF9\u4BFA\u4BFB\u4BFC\u4BFD\u4BFE"+ - "\u4BFF\u4C00\u4C01\u4C02\u4C03\u4C04\u4C05\u4C06"+ - "\u4C07\u4C08\u4C09\u4C0A\u4C0B\u4C0C\u4C0D\u4C0E"+ - "\u4C0F\u4C10\u4C11\u4C12\u4C13\u4C14\u4C15\u4C16"+ - "\u4C17\u4C18\u4C19\u4C1A\u4C1B\u4C1C\u4C1D\u4C1E"+ - "\u4C1F\u4C20\u4C21\u4C22\u4C23\u4C24\u4C25\u4C26"+ - "\u4C27\u4C28\u4C29\u4C2A\u4C2B\u4C2C\u4C2D\u4C2E"+ - "\u4C2F\u4C30\u4C31\u4C32\u4C33\u4C34\u4C35\u4C36"+ - "\u4C37\u4C38\u4C39\u4C3A\u4C3B\u4C3C\u4C3D\u4C3E"+ - "\u4C3F\u4C40\u4C41\u4C42\u4C43\u4C44\u4C45\u4C46"+ - "\u4C47\u4C48\u4C49\u4C4A\u4C4B\u4C4C\u4C4D\u4C4E"+ - "\u4C4F\u4C50\u4C51\u4C52\u4C53\u4C54\u4C55\u4C56"+ - "\u4C57\u4C58\u4C59\u4C5A\u4C5B\u4C5C\u4C5D\u4C5E"+ - "\u4C5F\u4C60\u4C61\u4C62\u4C63\u4C64\u4C65\u4C66"+ - "\u4C67\u4C68\u4C69\u4C6A\u4C6B\u4C6C\u4C6D\u4C6E"+ - "\u4C6F\u4C70\u4C71\u4C72\u4C73\u4C74\u4C75\u4C76"+ - "\u4C78\u4C79\u4C7A\u4C7B\u4C7C\u4C7D\u4C7E\u4C7F"+ - "\u4C80\u4C81\u4C82\u4C83\u4C84\u4C85\u4C86\u4C87"+ - "\u4C88\u4C89\u4C8A\u4C8B\u4C8C\u4C8D\u4C8E\u4C8F"+ - "\u4C90\u4C91\u4C92\u4C93\u4C94\u4C95\u4C96\u4C97"+ - "\u4C98\u4C99\u4C9A\u4C9B\u4C9C\u4C9D\u4C9E\u4CA4"+ - "\u4CA5\u4CA6\u4CA7\u4CA8\u4CA9\u4CAA\u4CAB\u4CAC"+ - "\u4CAD\u4CAE\u4CAF\u4CB0\u4CB1\u4CB2\u4CB3\u4CB4"+ - "\u4CB5\u4CB6\u4CB7\u4CB8\u4CB9\u4CBA\u4CBB\u4CBC"+ - "\u4CBD\u4CBE\u4CBF\u4CC0\u4CC1\u4CC2\u4CC3\u4CC4"+ - "\u4CC5\u4CC6\u4CC7\u4CC8\u4CC9\u4CCA\u4CCB\u4CCC"+ - "\u4CCD\u4CCE\u4CCF\u4CD0\u4CD1\u4CD2\u4CD3\u4CD4"+ - "\u4CD5\u4CD6\u4CD7\u4CD8\u4CD9\u4CDA\u4CDB\u4CDC"+ - "\u4CDD\u4CDE\u4CDF\u4CE0\u4CE1\u4CE2\u4CE3\u4CE4"+ - "\u4CE5\u4CE6\u4CE7\u4CE8\u4CE9\u4CEA\u4CEB\u4CEC"+ - "\u4CED\u4CEE\u4CEF\u4CF0\u4CF1\u4CF2\u4CF3\u4CF4"+ - "\u4CF5\u4CF6\u4CF7\u4CF8\u4CF9\u4CFA\u4CFB\u4CFC"+ - "\u4CFD\u4CFE\u4CFF\u4D00\u4D01\u4D02\u4D03\u4D04"+ - "\u4D05\u4D06\u4D07\u4D08\u4D09\u4D0A\u4D0B\u4D0C"+ - "\u4D0D\u4D0E\u4D0F\u4D10\u4D11\u4D12\u4D1A\u4D1B"+ - "\u4D1C\u4D1D\u4D1E\u4D1F\u4D20\u4D21\u4D22\u4D23"+ - "\u4D24\u4D25\u4D26\u4D27\u4D28\u4D29\u4D2A\u4D2B"+ - "\u4D2C\u4D2D\u4D2E\u4D2F\u4D30\u4D31\u4D32\u4D33"+ - "\u4D34\u4D35\u4D36\u4D37\u4D38\u4D39\u4D3A\u4D3B"+ - "\u4D3C\u4D3D\u4D3E\u4D3F\u4D40\u4D41\u4D42\u4D43"+ - "\u4D44\u4D45\u4D46\u4D47\u4D48\u4D49\u4D4A\u4D4B"+ - "\u4D4C\u4D4D\u4D4E\u4D4F\u4D50\u4D51\u4D52\u4D53"+ - "\u4D54\u4D55\u4D56\u4D57\u4D58\u4D59\u4D5A\u4D5B"+ - "\u4D5C\u4D5D\u4D5E\u4D5F\u4D60\u4D61\u4D62\u4D63"+ - "\u4D64\u4D65\u4D66\u4D67\u4D68\u4D69\u4D6A\u4D6B"+ - "\u4D6C\u4D6D\u4D6E\u4D6F\u4D70\u4D71\u4D72\u4D73"+ - "\u4D74\u4D75\u4D76\u4D77\u4D78\u4D79\u4D7A\u4D7B"+ - "\u4D7C\u4D7D\u4D7E\u4D7F\u4D80\u4D81\u4D82\u4D83"+ - "\u4D84\u4D85\u4D86\u4D87\u4D88\u4D89\u4D8A\u4D8B"+ - "\u4D8C\u4D8D\u4D8E\u4D8F\u4D90\u4D91\u4D92\u4D93"+ - "\u4D94\u4D95\u4D96\u4D97\u4D98\u4D99\u4D9A\u4D9B"+ - "\u4D9C\u4D9D\u4D9E\u4D9F\u4DA0\u4DA1\u4DA2\u4DA3"+ - "\u4DA4\u4DA5\u4DA6\u4DA7\u4DA8\u4DA9\u4DAA\u4DAB"+ - "\u4DAC\u4DAD\u4DAF\u4DB0\u4DB1\u4DB2\u4DB3\u4DB4"+ - "\u4DB5\u4DB6\u4DB7\u4DB8\u4DB9\u4DBA\u4DBB\u4DBC"+ - "\u4DBD\u4DBE\u4DBF\u4DC0\u4DC1\u4DC2\u4DC3\u4DC4"+ - "\u4DC5\u4DC6\u4DC7\u4DC8\u4DC9\u4DCA\u4DCB\u4DCC"+ - "\u4DCD\u4DCE\u4DCF\u4DD0\u4DD1\u4DD2\u4DD3\u4DD4"+ - "\u4DD5\u4DD6\u4DD7\u4DD8\u4DD9\u4DDA\u4DDB\u4DDC"+ - "\u4DDD\u4DDE\u4DDF\u4DE0\u4DE1\u4DE2\u4DE3\u4DE4"+ - "\u4DE5\u4DE6\u4DE7\u4DE8\u4DE9\u4DEA\u4DEB\u4DEC"+ - "\u4DED\u4DEE\u4DEF\u4DF0\u4DF1\u4DF2\u4DF3\u4DF4"+ - "\u4DF5\u4DF6\u4DF7\u4DF8\u4DF9\u4DFA\u4DFB\u4DFC"+ - "\u4DFD\u4DFE\u4DFF\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uE76C\uE7C8\uE7E7"+ - "\uE7E8\uE7E9\uE7EA\uE7EB\uE7EC\uE7ED\uE7EE\uE7EF"+ - "\uE7F0\uE7F1\uE7F2\uE7F3\uE815\uE819\uE81A\uE81B"+ - "\uE81C\uE81D\uE81F\uE820\uE821\uE822\uE823\uE824"+ - "\uE825\uE827\uE828\uE829\uE82A\uE82D\uE82E\uE82F"+ - "\uE830\uE833\uE834\uE835\uE836\uE837\uE838\uE839"+ - "\uE83A\uE83C\uE83D\uE83E\uE83F\uE840\uE841\uE842"+ - "\uE844\uE845\uE846\uE847\uE848\uE849\uE84A\uE84B"+ - "\uE84C\uE84D\uE84E\uE84F\uE850\uE851\uE852\uE853"+ - "\uE856\uE857\uE858\uE859\uE85A\uE85B\uE85C\uE85D"+ - "\uE85E\uE85F\uE860\uE861\uE862\uE863\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uF900\uF901\uF902\uF903\uF904\uF905\uF906"+ - "\uF907\uF908\uF909\uF90A\uF90B\uF90C\uF90D\uF90E"+ - "\uF90F\uF910\uF911\uF912\uF913\uF914\uF915\uF916"+ - "\uF917\uF918\uF919\uF91A\uF91B\uF91C\uF91D\uF91E"+ - "\uF91F\uF920\uF921\uF922\uF923\uF924\uF925\uF926"+ - "\uF927\uF928\uF929\uF92A\uF92B\uF92D\uF92E\uF92F"+ - "\uF930\uF931\uF932\uF933\uF934\uF935\uF936\uF937"+ - "\uF938\uF939\uF93A\uF93B\uF93C\uF93D\uF93E\uF93F"+ - "\uF940\uF941\uF942\uF943\uF944\uF945\uF946\uF947"+ - "\uF948\uF949\uF94A\uF94B\uF94C\uF94D\uF94E\uF94F"+ - "\uF950\uF951\uF952\uF953\uF954\uF955\uF956\uF957"+ - "\uF958\uF959\uF95A\uF95B\uF95C\uF95D\uF95E\uF95F"+ - "\uF960\uF961\uF962\uF963\uF964\uF965\uF966\uF967"+ - "\uF968\uF969\uF96A\uF96B\uF96C\uF96D\uF96E\uF96F"+ - "\uF970\uF971\uF972\uF973\uF974\uF975\uF976\uF977"+ - "\uF978\uF97A\uF97B\uF97C\uF97D\uF97E\uF97F\uF980"+ - "\uF981\uF982\uF983\uF984\uF985\uF986\uF987\uF988"+ - "\uF989\uF98A\uF98B\uF98C\uF98D\uF98E\uF98F\uF990"+ - "\uF991\uF992\uF993\uF994\uF996\uF997\uF998\uF999"+ - "\uF99A\uF99B\uF99C\uF99D\uF99E\uF99F\uF9A0\uF9A1"+ - "\uF9A2\uF9A3\uF9A4\uF9A5\uF9A6\uF9A7\uF9A8\uF9A9"+ - "\uF9AA\uF9AB\uF9AC\uF9AD\uF9AE\uF9AF\uF9B0\uF9B1"+ - "\uF9B2\uF9B3\uF9B4\uF9B5\uF9B6\uF9B7\uF9B8\uF9B9"+ - "\uF9BA\uF9BB\uF9BC\uF9BD\uF9BE\uF9BF\uF9C0\uF9C1"+ - "\uF9C2\uF9C3\uF9C4\uF9C5\uF9C6\uF9C7\uF9C8\uF9C9"+ - "\uF9CA\uF9CB\uF9CC\uF9CD\uF9CE\uF9CF\uF9D0\uF9D1"+ - "\uF9D2\uF9D3\uF9D4\uF9D5\uF9D6\uF9D7\uF9D8\uF9D9"+ - "\uF9DA\uF9DB\uF9DC\uF9DD\uF9DE\uF9DF\uF9E0\uF9E1"+ - "\uF9E2\uF9E3\uF9E4\uF9E5\uF9E6\uF9E8\uF9E9\uF9EA"+ - "\uF9EB\uF9EC\uF9ED\uF9EE\uF9EF\uF9F0\uF9F2\uF9F3"+ - "\uF9F4\uF9F5\uF9F6\uF9F7\uF9F8\uF9F9\uF9FA\uF9FB"+ - "\uF9FC\uF9FD\uF9FE\uF9FF\uFA00\uFA01\uFA02\uFA03"+ - "\uFA04\uFA05\uFA06\uFA07\uFA08\uFA09\uFA0A\uFA0B"+ - "\uFA10\uFA12\uFA15\uFA16\uFA17\uFA19\uFA1A\uFA1B"+ - "\uFA1C\uFA1D\uFA1E\uFA22\uFA25\uFA26\uFA2A\uFA2B"+ - "\uFA2C\uFA2D\uFA2E\uFA2F\uFA30\uFA31\uFA32\uFA33"+ - "\uFA34\uFA35\uFA36\uFA37\uFA38\uFA39\uFA3A\uFA3B"+ - "\uFA3C\uFA3D\uFA3E\uFA3F\uFA40\uFA41\uFA42\uFA43"+ - "\uFA44\uFA45\uFA46\uFA47\uFA48\uFA49\uFA4A\uFA4B"+ - "\uFA4C\uFA4D\uFA4E\uFA4F\uFA50\uFA51\uFA52\uFA53"+ - "\uFA54\uFA55\uFA56\uFA57\uFA58\uFA59\uFA5A\uFA5B"+ - "\uFA5C\uFA5D\uFA5E\uFA5F\uFA60\uFA61\uFA62\uFA63"+ - "\uFA64\uFA65\uFA66\uFA67\uFA68\uFA69\uFA6A\uFA6B"+ - "\uFA6C\uFA6D\uFA6E\uFA6F\uFA70\uFA71\uFA72\uFA73"+ - "\uFA74\uFA75\uFA76\uFA77\uFA78\uFA79\uFA7A\uFA7B"+ - "\uFA7C\uFA7D\uFA7E\uFA7F\uFA80\uFA81\uFA82\uFA83"+ - "\uFA84\uFA85\uFA86\uFA87\uFA88\uFA89\uFA8A\uFA8B"+ - "\uFA8C\uFA8D\uFA8E\uFA8F\uFA90\uFA91\uFA92\uFA93"+ - "\uFA94\uFA95\uFA96\uFA97\uFA98\uFA99\uFA9A\uFA9B"+ - "\uFA9C\uFA9D\uFA9E\uFA9F\uFAA0\uFAA1\uFAA2\uFAA3"+ - "\uFAA4\uFAA5\uFAA6\uFAA7\uFAA8\uFAA9\uFAAA\uFAAB"+ - "\uFAAC\uFAAD\uFAAE\uFAAF\uFAB0\uFAB1\uFAB2\uFAB3"+ - "\uFAB4\uFAB5\uFAB6\uFAB7\uFAB8\uFAB9\uFABA\uFABB"+ - "\uFABC\uFABD\uFABE\uFABF\uFAC0\uFAC1\uFAC2\uFAC3"+ - "\uFAC4\uFAC5\uFAC6\uFAC7\uFAC8\uFAC9\uFACA\uFACB"+ - "\uFACC\uFACD\uFACE\uFACF\uFAD0\uFAD1\uFAD2\uFAD3"+ - "\uFAD4\uFAD5\uFAD6\uFAD7\uFAD8\uFAD9\uFADA\uFADB"+ - "\uFADC\uFADD\uFADE\uFADF\uFAE0\uFAE1\uFAE2\uFAE3"+ - "\uFAE4\uFAE5\uFAE6\uFAE7\uFAE8\uFAE9\uFAEA\uFAEB"+ - "\uFAEC\uFAED\uFAEE\uFAEF\uFAF0\uFAF1\uFAF2\uFAF3"+ - "\uFAF4\uFAF5\uFAF6\uFAF7\uFAF8\uFAF9\uFAFA\uFAFB"+ - "\uFAFC\uFAFD\uFAFE\uFAFF\uFB00\uFB01\uFB02\uFB03"+ - "\uFB04\uFB05\uFB06\uFB07\uFB08\uFB09\uFB0A\uFB0B"+ - "\uFB0C\uFB0D\uFB0E\uFB0F\uFB10\uFB11\uFB12\uFB13"+ - "\uFB14\uFB15\uFB16\uFB17\uFB18\uFB19\uFB1A\uFB1B"+ - "\uFB1C\uFB1D\uFB1E\uFB1F\uFB20\uFB21\uFB22\uFB23"+ - "\uFB24\uFB25\uFB26\uFB27\uFB28\uFB29\uFB2A\uFB2B"+ - "\uFB2C\uFB2D\uFB2E\uFB2F\uFB30\uFB31\uFB32\uFB33"+ - "\uFB34\uFB35\uFB36\uFB37\uFB38\uFB39\uFB3A\uFB3B"+ - "\uFB3C\uFB3D\uFB3E\uFB3F\uFB40\uFB41\uFB42\uFB43"+ - "\uFB44\uFB45\uFB46\uFB47\uFB48\uFB49\uFB4A\uFB4B"+ - "\uFB4C\uFB4D\uFB4E\uFB4F\uFB50\uFB51\uFB52\uFB53"+ - "\uFB54\uFB55\uFB56\uFB57\uFB58\uFB59\uFB5A\uFB5B"+ - "\uFB5C\uFB5D\uFB5E\uFB5F\uFB60\uFB61\uFB62\uFB63"+ - "\uFB64\uFB65\uFB66\uFB67\uFB68\uFB69\uFB6A\uFB6B"; - - private static final String innerDecoderIndex5= - "\uFB6C\uFB6D\uFB6E\uFB6F\uFB70\uFB71\uFB72\uFB73"+ - "\uFB74\uFB75\uFB76\uFB77\uFB78\uFB79\uFB7A\uFB7B"+ - "\uFB7C\uFB7D\uFB7E\uFB7F\uFB80\uFB81\uFB82\uFB83"+ - "\uFB84\uFB85\uFB86\uFB87\uFB88\uFB89\uFB8A\uFB8B"+ - "\uFB8C\uFB8D\uFB8E\uFB8F\uFB90\uFB91\uFB92\uFB93"+ - "\uFB94\uFB95\uFB96\uFB97\uFB98\uFB99\uFB9A\uFB9B"+ - "\uFB9C\uFB9D\uFB9E\uFB9F\uFBA0\uFBA1\uFBA2\uFBA3"+ - "\uFBA4\uFBA5\uFBA6\uFBA7\uFBA8\uFBA9\uFBAA\uFBAB"+ - "\uFBAC\uFBAD\uFBAE\uFBAF\uFBB0\uFBB1\uFBB2\uFBB3"+ - "\uFBB4\uFBB5\uFBB6\uFBB7\uFBB8\uFBB9\uFBBA\uFBBB"+ - "\uFBBC\uFBBD\uFBBE\uFBBF\uFBC0\uFBC1\uFBC2\uFBC3"+ - "\uFBC4\uFBC5\uFBC6\uFBC7\uFBC8\uFBC9\uFBCA\uFBCB"+ - "\uFBCC\uFBCD\uFBCE\uFBCF\uFBD0\uFBD1\uFBD2\uFBD3"+ - "\uFBD4\uFBD5\uFBD6\uFBD7\uFBD8\uFBD9\uFBDA\uFBDB"+ - "\uFBDC\uFBDD\uFBDE\uFBDF\uFBE0\uFBE1\uFBE2\uFBE3"+ - "\uFBE4\uFBE5\uFBE6\uFBE7\uFBE8\uFBE9\uFBEA\uFBEB"+ - "\uFBEC\uFBED\uFBEE\uFBEF\uFBF0\uFBF1\uFBF2\uFBF3"+ - "\uFBF4\uFBF5\uFBF6\uFBF7\uFBF8\uFBF9\uFBFA\uFBFB"+ - "\uFBFC\uFBFD\uFBFE\uFBFF\uFC00\uFC01\uFC02\uFC03"+ - "\uFC04\uFC05\uFC06\uFC07\uFC08\uFC09\uFC0A\uFC0B"+ - "\uFC0C\uFC0D\uFC0E\uFC0F\uFC10\uFC11\uFC12\uFC13"+ - "\uFC14\uFC15\uFC16\uFC17\uFC18\uFC19\uFC1A\uFC1B"+ - "\uFC1C\uFC1D\uFC1E\uFC1F\uFC20\uFC21\uFC22\uFC23"+ - "\uFC24\uFC25\uFC26\uFC27\uFC28\uFC29\uFC2A\uFC2B"+ - "\uFC2C\uFC2D\uFC2E\uFC2F\uFC30\uFC31\uFC32\uFC33"+ - "\uFC34\uFC35\uFC36\uFC37\uFC38\uFC39\uFC3A\uFC3B"+ - "\uFC3C\uFC3D\uFC3E\uFC3F\uFC40\uFC41\uFC42\uFC43"+ - "\uFC44\uFC45\uFC46\uFC47\uFC48\uFC49\uFC4A\uFC4B"+ - "\uFC4C\uFC4D\uFC4E\uFC4F\uFC50\uFC51\uFC52\uFC53"+ - "\uFC54\uFC55\uFC56\uFC57\uFC58\uFC59\uFC5A\uFC5B"+ - "\uFC5C\uFC5D\uFC5E\uFC5F\uFC60\uFC61\uFC62\uFC63"+ - "\uFC64\uFC65\uFC66\uFC67\uFC68\uFC69\uFC6A\uFC6B"+ - "\uFC6C\uFC6D\uFC6E\uFC6F\uFC70\uFC71\uFC72\uFC73"+ - "\uFC74\uFC75\uFC76\uFC77\uFC78\uFC79\uFC7A\uFC7B"+ - "\uFC7C\uFC7D\uFC7E\uFC7F\uFC80\uFC81\uFC82\uFC83"+ - "\uFC84\uFC85\uFC86\uFC87\uFC88\uFC89\uFC8A\uFC8B"+ - "\uFC8C\uFC8D\uFC8E\uFC8F\uFC90\uFC91\uFC92\uFC93"+ - "\uFC94\uFC95\uFC96\uFC97\uFC98\uFC99\uFC9A\uFC9B"+ - "\uFC9C\uFC9D\uFC9E\uFC9F\uFCA0\uFCA1\uFCA2\uFCA3"+ - "\uFCA4\uFCA5\uFCA6\uFCA7\uFCA8\uFCA9\uFCAA\uFCAB"+ - "\uFCAC\uFCAD\uFCAE\uFCAF\uFCB0\uFCB1\uFCB2\uFCB3"+ - "\uFCB4\uFCB5\uFCB6\uFCB7\uFCB8\uFCB9\uFCBA\uFCBB"+ - "\uFCBC\uFCBD\uFCBE\uFCBF\uFCC0\uFCC1\uFCC2\uFCC3"+ - "\uFCC4\uFCC5\uFCC6\uFCC7\uFCC8\uFCC9\uFCCA\uFCCB"+ - "\uFCCC\uFCCD\uFCCE\uFCCF\uFCD0\uFCD1\uFCD2\uFCD3"+ - "\uFCD4\uFCD5\uFCD6\uFCD7\uFCD8\uFCD9\uFCDA\uFCDB"+ - "\uFCDC\uFCDD\uFCDE\uFCDF\uFCE0\uFCE1\uFCE2\uFCE3"+ - "\uFCE4\uFCE5\uFCE6\uFCE7\uFCE8\uFCE9\uFCEA\uFCEB"+ - "\uFCEC\uFCED\uFCEE\uFCEF\uFCF0\uFCF1\uFCF2\uFCF3"+ - "\uFCF4\uFCF5\uFCF6\uFCF7\uFCF8\uFCF9\uFCFA\uFCFB"+ - "\uFCFC\uFCFD\uFCFE\uFCFF\uFD00\uFD01\uFD02\uFD03"+ - "\uFD04\uFD05\uFD06\uFD07\uFD08\uFD09\uFD0A\uFD0B"+ - "\uFD0C\uFD0D\uFD0E\uFD0F\uFD10\uFD11\uFD12\uFD13"+ - "\uFD14\uFD15\uFD16\uFD17\uFD18\uFD19\uFD1A\uFD1B"+ - "\uFD1C\uFD1D\uFD1E\uFD1F\uFD20\uFD21\uFD22\uFD23"+ - "\uFD24\uFD25\uFD26\uFD27\uFD28\uFD29\uFD2A\uFD2B"+ - "\uFD2C\uFD2D\uFD2E\uFD2F\uFD30\uFD31\uFD32\uFD33"+ - "\uFD34\uFD35\uFD36\uFD37\uFD38\uFD39\uFD3A\uFD3B"+ - "\uFD3C\uFD3D\uFD3E\uFD3F\uFD40\uFD41\uFD42\uFD43"+ - "\uFD44\uFD45\uFD46\uFD47\uFD48\uFD49\uFD4A\uFD4B"+ - "\uFD4C\uFD4D\uFD4E\uFD4F\uFD50\uFD51\uFD52\uFD53"+ - "\uFD54\uFD55\uFD56\uFD57\uFD58\uFD59\uFD5A\uFD5B"+ - "\uFD5C\uFD5D\uFD5E\uFD5F\uFD60\uFD61\uFD62\uFD63"+ - "\uFD64\uFD65\uFD66\uFD67\uFD68\uFD69\uFD6A\uFD6B"+ - "\uFD6C\uFD6D\uFD6E\uFD6F\uFD70\uFD71\uFD72\uFD73"+ - "\uFD74\uFD75\uFD76\uFD77\uFD78\uFD79\uFD7A\uFD7B"+ - "\uFD7C\uFD7D\uFD7E\uFD7F\uFD80\uFD81\uFD82\uFD83"+ - "\uFD84\uFD85\uFD86\uFD87\uFD88\uFD89\uFD8A\uFD8B"+ - "\uFD8C\uFD8D\uFD8E\uFD8F\uFD90\uFD91\uFD92\uFD93"+ - "\uFD94\uFD95\uFD96\uFD97\uFD98\uFD99\uFD9A\uFD9B"+ - "\uFD9C\uFD9D\uFD9E\uFD9F\uFDA0\uFDA1\uFDA2\uFDA3"+ - "\uFDA4\uFDA5\uFDA6\uFDA7\uFDA8\uFDA9\uFDAA\uFDAB"+ - "\uFDAC\uFDAD\uFDAE\uFDAF\uFDB0\uFDB1\uFDB2\uFDB3"+ - "\uFDB4\uFDB5\uFDB6\uFDB7\uFDB8\uFDB9\uFDBA\uFDBB"+ - "\uFDBC\uFDBD\uFDBE\uFDBF\uFDC0\uFDC1\uFDC2\uFDC3"+ - "\uFDC4\uFDC5\uFDC6\uFDC7\uFDC8\uFDC9\uFDCA\uFDCB"+ - "\uFDCC\uFDCD\uFDCE\uFDCF\uFDD0\uFDD1\uFDD2\uFDD3"+ - "\uFDD4\uFDD5\uFDD6\uFDD7\uFDD8\uFDD9\uFDDA\uFDDB"+ - "\uFDDC\uFDDD\uFDDE\uFDDF\uFDE0\uFDE1\uFDE2\uFDE3"+ - "\uFDE4\uFDE5\uFDE6\uFDE7\uFDE8\uFDE9\uFDEA\uFDEB"+ - "\uFDEC\uFDED\uFDEE\uFDEF\uFDF0\uFDF1\uFDF2\uFDF3"+ - "\uFDF4\uFDF5\uFDF6\uFDF7\uFDF8\uFDF9\uFDFA\uFDFB"+ - "\uFDFC\uFDFD\uFDFE\uFDFF\uFE00\uFE01\uFE02\uFE03"+ - "\uFE04\uFE05\uFE06\uFE07\uFE08\uFE09\uFE0A\uFE0B"+ - "\uFE0C\uFE0D\uFE0E\uFE0F\uFE10\uFE11\uFE12\uFE13"+ - "\uFE14\uFE15\uFE16\uFE17\uFE18\uFE19\uFE1A\uFE1B"+ - "\uFE1C\uFE1D\uFE1E\uFE1F\uFE20\uFE21\uFE22\uFE23"+ - "\uFE24\uFE25\uFE26\uFE27\uFE28\uFE29\uFE2A\uFE2B"+ - "\uFE2C\uFE2D\uFE2E\uFE2F\uFE32\uFE45\uFE46\uFE47"+ - "\uFE48\uFE53\uFE58\uFE67\uFE6C\uFE6D\uFE6E\uFE6F"+ - "\uFE70\uFE71\uFE72\uFE73\uFE74\uFE75\uFE76\uFE77"+ - "\uFE78\uFE79\uFE7A\uFE7B\uFE7C\uFE7D\uFE7E\uFE7F"+ - "\uFE80\uFE81\uFE82\uFE83\uFE84\uFE85\uFE86\uFE87"+ - "\uFE88\uFE89\uFE8A\uFE8B\uFE8C\uFE8D\uFE8E\uFE8F"+ - "\uFE90\uFE91\uFE92\uFE93\uFE94\uFE95\uFE96\uFE97"+ - "\uFE98\uFE99\uFE9A\uFE9B\uFE9C\uFE9D\uFE9E\uFE9F"+ - "\uFEA0\uFEA1\uFEA2\uFEA3\uFEA4\uFEA5\uFEA6\uFEA7"+ - "\uFEA8\uFEA9\uFEAA\uFEAB\uFEAC\uFEAD\uFEAE\uFEAF"+ - "\uFEB0\uFEB1\uFEB2\uFEB3\uFEB4\uFEB5\uFEB6\uFEB7"+ - "\uFEB8\uFEB9\uFEBA\uFEBB\uFEBC\uFEBD\uFEBE\uFEBF"+ - "\uFEC0\uFEC1\uFEC2\uFEC3\uFEC4\uFEC5\uFEC6\uFEC7"+ - "\uFEC8\uFEC9\uFECA\uFECB\uFECC\uFECD\uFECE\uFECF"+ - "\uFED0\uFED1\uFED2\uFED3\uFED4\uFED5\uFED6\uFED7"+ - "\uFED8\uFED9\uFEDA\uFEDB\uFEDC\uFEDD\uFEDE\uFEDF"+ - "\uFEE0\uFEE1\uFEE2\uFEE3\uFEE4\uFEE5\uFEE6\uFEE7"+ - "\uFEE8\uFEE9\uFEEA\uFEEB\uFEEC\uFEED\uFEEE\uFEEF"+ - "\uFEF0\uFEF1\uFEF2\uFEF3\uFEF4\uFEF5\uFEF6\uFEF7"+ - "\uFEF8\uFEF9\uFEFA\uFEFB\uFEFC\uFEFD\uFEFE\uFEFF"+ - "\uFF00\uFF5F\uFF60\uFF61\uFF62\uFF63\uFF64\uFF65"+ - "\uFF66\uFF67\uFF68\uFF69\uFF6A\uFF6B\uFF6C\uFF6D"+ - "\uFF6E\uFF6F\uFF70\uFF71\uFF72\uFF73\uFF74\uFF75"+ - "\uFF76\uFF77\uFF78\uFF79\uFF7A\uFF7B\uFF7C\uFF7D"+ - "\uFF7E\uFF7F\uFF80\uFF81\uFF82\uFF83\uFF84\uFF85"+ - "\uFF86\uFF87\uFF88\uFF89\uFF8A\uFF8B\uFF8C\uFF8D"+ - "\uFF8E\uFF8F\uFF90\uFF91\uFF92\uFF93\uFF94\uFF95"+ - "\uFF96\uFF97\uFF98\uFF99\uFF9A\uFF9B\uFF9C\uFF9D"+ - "\uFF9E\uFF9F\uFFA0\uFFA1\uFFA2\uFFA3\uFFA4\uFFA5"+ - "\uFFA6\uFFA7\uFFA8\uFFA9\uFFAA\uFFAB\uFFAC\uFFAD"+ - "\uFFAE\uFFAF\uFFB0\uFFB1\uFFB2\uFFB3\uFFB4\uFFB5"+ - "\uFFB6\uFFB7\uFFB8\uFFB9\uFFBA\uFFBB\uFFBC\uFFBD"+ - "\uFFBE\uFFBF\uFFC0\uFFC1\uFFC2\uFFC3\uFFC4\uFFC5"+ - "\uFFC6\uFFC7\uFFC8\uFFC9\uFFCA\uFFCB\uFFCC\uFFCD"+ - "\uFFCE\uFFCF\uFFD0\uFFD1\uFFD2\uFFD3\uFFD4\uFFD5"+ - "\uFFD6\uFFD7\uFFD8\uFFD9\uFFDA\uFFDB\uFFDC\uFFDD"+ - "\uFFDE\uFFDF\uFFE6\uFFE7\uFFE8\uFFE9\uFFEA\uFFEB"+ - "\uFFEC\uFFED\uFFEE\uFFEF\uFFF0\uFFF1\uFFF2\uFFF3"+ - "\uFFF4\uFFF5\uFFF6\uFFF7\uFFF8\uFFF9\uFFFA\uFFFB"+ - "\uFFFC\uFFFD\uFFFE\uFFFF\uFFFD\uFFFD\uFFFD\uFFFD"; - - private static final short decoderIndex1[] = { - 0, 1, 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, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 77, 78, 79, 80, 81, 82, 83, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 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 String decoderIndex2[] = { - innerDecoderIndex0, - innerDecoderIndex1, - innerDecoderIndex2, - innerDecoderIndex3, - innerDecoderIndex4, - innerDecoderIndex5 - }; - -/* - * - */ - private static final String innerIndex0= - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u4E02"+ - "\u4E04\u4E05\u4E06\u4E0F\u4E12\u4E17\u4E1F\u4E20"+ - "\u4E21\u4E23\u4E26\u4E29\u4E2E\u4E2F\u4E31\u4E33"+ - "\u4E35\u4E37\u4E3C\u4E40\u4E41\u4E42\u4E44\u4E46"+ - "\u4E4A\u4E51\u4E55\u4E57\u4E5A\u4E5B\u4E62\u4E63"+ - "\u4E64\u4E65\u4E67\u4E68\u4E6A\u4E6B\u4E6C\u4E6D"+ - "\u4E6E\u4E6F\u4E72\u4E74\u4E75\u4E76\u4E77\u4E78"+ - "\u4E79\u4E7A\u4E7B\u4E7C\u4E7D\u4E7F\u4E80\u4E81"+ - "\u4E82\u4E83\u4E84\u4E85\u4E87\u4E8A\uFFFD\u4E90"+ - "\u4E96\u4E97\u4E99\u4E9C\u4E9D\u4E9E\u4EA3\u4EAA"+ - "\u4EAF\u4EB0\u4EB1\u4EB4\u4EB6\u4EB7\u4EB8\u4EB9"+ - "\u4EBC\u4EBD\u4EBE\u4EC8\u4ECC\u4ECF\u4ED0\u4ED2"+ - "\u4EDA\u4EDB\u4EDC\u4EE0\u4EE2\u4EE6\u4EE7\u4EE9"+ - "\u4EED\u4EEE\u4EEF\u4EF1\u4EF4\u4EF8\u4EF9\u4EFA"+ - "\u4EFC\u4EFE\u4F00\u4F02\u4F03\u4F04\u4F05\u4F06"+ - "\u4F07\u4F08\u4F0B\u4F0C\u4F12\u4F13\u4F14\u4F15"+ - "\u4F16\u4F1C\u4F1D\u4F21\u4F23\u4F28\u4F29\u4F2C"+ - "\u4F2D\u4F2E\u4F31\u4F33\u4F35\u4F37\u4F39\u4F3B"+ - "\u4F3E\u4F3F\u4F40\u4F41\u4F42\u4F44\u4F45\u4F47"+ - "\u4F48\u4F49\u4F4A\u4F4B\u4F4C\u4F52\u4F54\u4F56"+ - "\u4F61\u4F62\u4F66\u4F68\u4F6A\u4F6B\u4F6D\u4F6E"+ - "\u4F71\u4F72\u4F75\u4F77\u4F78\u4F79\u4F7A\u4F7D"+ - "\u4F80\u4F81\u4F82\u4F85\u4F86\u4F87\u4F8A\u4F8C"+ - "\u4F8E\u4F90\u4F92\u4F93\u4F95\u4F96\u4F98\u4F99"+ - "\u4F9A\u4F9C\u4F9E\u4F9F\u4FA1\u4FA2\u4FA4\u4FAB"+ - "\u4FAD\u4FB0\u4FB1\u4FB2\u4FB3\u4FB4\u4FB6\u4FB7"+ - "\u4FB8\u4FB9\u4FBA\u4FBB\u4FBC\u4FBD\u4FBE\u4FC0"+ - "\u4FC1\u4FC2\u4FC6\u4FC7\u4FC8\u4FC9\u4FCB\u4FCC"+ - "\u4FCD\u4FD2\u4FD3\u4FD4\u4FD5\u4FD6\u4FD9\u4FDB"+ - "\u4FE0\u4FE2\u4FE4\u4FE5\u4FE7\u4FEB\u4FEC\u4FF0"+ - "\u4FF2\u4FF4\u4FF5\u4FF6\u4FF7\u4FF9\u4FFB\u4FFC"+ - "\u4FFD\u4FFF\u5000\u5001\u5002\u5003\u5004\u5005"+ - "\u5006\u5007\u5008\u5009\u500A\uFFFD\u500B\u500E"+ - "\u5010\u5011\u5013\u5015\u5016\u5017\u501B\u501D"+ - "\u501E\u5020\u5022\u5023\u5024\u5027\u502B\u502F"+ - "\u5030\u5031\u5032\u5033\u5034\u5035\u5036\u5037"+ - "\u5038\u5039\u503B\u503D\u503F\u5040\u5041\u5042"+ - "\u5044\u5045\u5046\u5049\u504A\u504B\u504D\u5050"+ - "\u5051\u5052\u5053\u5054\u5056\u5057\u5058\u5059"+ - "\u505B\u505D\u505E\u505F\u5060\u5061\u5062\u5063"+ - "\u5064\u5066\u5067\u5068\u5069\u506A\u506B\u506D"+ - "\u506E\u506F\u5070\u5071\u5072\u5073\u5074\u5075"+ - "\u5078\u5079\u507A\u507C\u507D\u5081\u5082\u5083"+ - "\u5084\u5086\u5087\u5089\u508A\u508B\u508C\u508E"+ - "\u508F\u5090\u5091\u5092\u5093\u5094\u5095\u5096"+ - "\u5097\u5098\u5099\u509A\u509B\u509C\u509D\u509E"+ - "\u509F\u50A0\u50A1\u50A2\u50A4\u50A6\u50AA\u50AB"+ - "\u50AD\u50AE\u50AF\u50B0\u50B1\u50B3\u50B4\u50B5"+ - "\u50B6\u50B7\u50B8\u50B9\u50BC\u50BD\u50BE\u50BF"+ - "\u50C0\u50C1\u50C2\u50C3\u50C4\u50C5\u50C6\u50C7"+ - "\u50C8\u50C9\u50CA\u50CB\u50CC\u50CD\u50CE\u50D0"+ - "\u50D1\u50D2\u50D3\u50D4\u50D5\u50D7\u50D8\u50D9"+ - "\u50DB\u50DC\u50DD\u50DE\u50DF\u50E0\u50E1\u50E2"+ - "\u50E3\u50E4\u50E5\u50E8\u50E9\u50EA\u50EB\u50EF"+ - "\u50F0\u50F1\u50F2\u50F4\u50F6\u50F7\u50F8\u50F9"+ - "\u50FA\u50FC\u50FD\u50FE\u50FF\u5100\u5101\u5102"+ - "\u5103\u5104\u5105\u5108\uFFFD\u5109\u510A\u510C"+ - "\u510D\u510E\u510F\u5110\u5111\u5113\u5114\u5115"+ - "\u5116\u5117\u5118\u5119\u511A\u511B\u511C\u511D"+ - "\u511E\u511F\u5120\u5122\u5123\u5124\u5125\u5126"+ - "\u5127\u5128\u5129\u512A\u512B\u512C\u512D\u512E"+ - "\u512F\u5130\u5131\u5132\u5133\u5134\u5135\u5136"+ - "\u5137\u5138\u5139\u513A\u513B\u513C\u513D\u513E"+ - "\u5142\u5147\u514A\u514C\u514E\u514F\u5150\u5152"+ - "\u5153\u5157\u5158\u5159\u515B\u515D\u515E\u515F"+ - "\u5160\u5161\u5163\u5164\u5166\u5167\u5169\u516A"+ - "\u516F\u5172\u517A\u517E\u517F\u5183\u5184\u5186"+ - "\u5187\u518A\u518B\u518E\u518F\u5190\u5191\u5193"+ - "\u5194\u5198\u519A\u519D\u519E\u519F\u51A1\u51A3"+ - "\u51A6\u51A7\u51A8\u51A9\u51AA\u51AD\u51AE\u51B4"+ - "\u51B8\u51B9\u51BA\u51BE\u51BF\u51C1\u51C2\u51C3"+ - "\u51C5\u51C8\u51CA\u51CD\u51CE\u51D0\u51D2\u51D3"+ - "\u51D4\u51D5\u51D6\u51D7\u51D8\u51D9\u51DA\u51DC"+ - "\u51DE\u51DF\u51E2\u51E3\u51E5\u51E6\u51E7\u51E8"+ - "\u51E9\u51EA\u51EC\u51EE\u51F1\u51F2\u51F4\u51F7"+ - "\u51FE\u5204\u5205\u5209\u520B\u520C\u520F\u5210"+ - "\u5213\u5214\u5215\u521C\u521E\u521F\u5221\u5222"+ - "\u5223\u5225\u5226\u5227\u522A\u522C\u522F\u5231"+ - "\u5232\u5234\u5235\u523C\u523E\u5244\u5245\u5246"+ - "\u5247\u5248\u5249\u524B\u524E\u524F\u5252\u5253"+ - "\u5255\u5257\u5258\uFFFD\u5259\u525A\u525B\u525D"+ - "\u525F\u5260\u5262\u5263\u5264\u5266\u5268\u526B"+ - "\u526C\u526D\u526E\u5270\u5271\u5273\u5274\u5275"+ - "\u5276\u5277\u5278\u5279\u527A\u527B\u527C\u527E"+ - "\u5280\u5283\u5284\u5285\u5286\u5287\u5289\u528A"+ - "\u528B\u528C\u528D\u528E\u528F\u5291\u5292\u5294"+ - "\u5295\u5296\u5297\u5298\u5299\u529A\u529C\u52A4"+ - "\u52A5\u52A6\u52A7\u52AE\u52AF\u52B0\u52B4\u52B5"+ - "\u52B6\u52B7\u52B8\u52B9\u52BA\u52BB\u52BC\u52BD"+ - "\u52C0\u52C1\u52C2\u52C4\u52C5\u52C6\u52C8\u52CA"+ - "\u52CC\u52CD\u52CE\u52CF\u52D1\u52D3\u52D4\u52D5"+ - "\u52D7\u52D9\u52DA\u52DB\u52DC\u52DD\u52DE\u52E0"+ - "\u52E1\u52E2\u52E3\u52E5\u52E6\u52E7\u52E8\u52E9"+ - "\u52EA\u52EB\u52EC\u52ED\u52EE\u52EF\u52F1\u52F2"+ - "\u52F3\u52F4\u52F5\u52F6\u52F7\u52F8\u52FB\u52FC"+ - "\u52FD\u5301\u5302\u5303\u5304\u5307\u5309\u530A"+ - "\u530B\u530C\u530E\u5311\u5312\u5313\u5314\u5318"+ - "\u531B\u531C\u531E\u531F\u5322\u5324\u5325\u5327"+ - "\u5328\u5329\u532B\u532C\u532D\u532F\u5330\u5331"+ - "\u5332\u5333\u5334\u5335\u5336\u5337\u5338\u533C"+ - "\u533D\u5340\u5342\u5344\u5346\u534B\u534C\u534D"+ - "\u5350\u5354\u5358\u5359\u535B\u535D\u5365\u5368"+ - "\u536A\u536C\u536D\u5372\u5376\u5379\u537B\u537C"+ - "\u537D\u537E\u5380\u5381\u5383\u5387\u5388\u538A"+ - "\u538E\u538F\uFFFD\u5390\u5391\u5392\u5393\u5394"+ - "\u5396\u5397\u5399\u539B\u539C\u539E\u53A0\u53A1"+ - "\u53A4\u53A7\u53AA\u53AB\u53AC\u53AD\u53AF\u53B0"+ - "\u53B1\u53B2\u53B3\u53B4\u53B5\u53B7\u53B8\u53B9"+ - "\u53BA\u53BC\u53BD\u53BE\u53C0\u53C3\u53C4\u53C5"+ - "\u53C6\u53C7\u53CE\u53CF\u53D0\u53D2\u53D3\u53D5"+ - "\u53DA\u53DC\u53DD\u53DE\u53E1\u53E2\u53E7\u53F4"+ - "\u53FA\u53FE\u53FF\u5400\u5402\u5405\u5407\u540B"+ - "\u5414\u5418\u5419\u541A\u541C\u5422\u5424\u5425"+ - "\u542A\u5430\u5433\u5436\u5437\u543A\u543D\u543F"+ - "\u5441\u5442\u5444\u5445\u5447\u5449\u544C\u544D"+ - "\u544E\u544F\u5451\u545A\u545D\u545E\u545F\u5460"+ - "\u5461\u5463\u5465\u5467\u5469\u546A\u546B\u546C"+ - "\u546D\u546E\u546F\u5470\u5474\u5479\u547A\u547E"+ - "\u547F\u5481\u5483\u5485\u5487\u5488\u5489\u548A"+ - "\u548D\u5491\u5493\u5497\u5498\u549C\u549E\u549F"+ - "\u54A0\u54A1\u54A2\u54A5\u54AE\u54B0\u54B2\u54B5"+ - "\u54B6\u54B7\u54B9\u54BA\u54BC\u54BE\u54C3\u54C5"+ - "\u54CA\u54CB\u54D6\u54D8\u54DB\u54E0\u54E1\u54E2"+ - "\u54E3\u54E4\u54EB\u54EC\u54EF\u54F0\u54F1\u54F4"+ - "\u54F5\u54F6\u54F7\u54F8\u54F9\u54FB\u54FE\u5500"+ - "\u5502\u5503\u5504\u5505\u5508\u550A\u550B\u550C"+ - "\u550D\u550E\u5512\u5513\u5515\u5516\u5517\u5518"+ - "\u5519\u551A\u551C\u551D\u551E\u551F\u5521\u5525"+ - "\u5526\uFFFD\u5528\u5529\u552B\u552D\u5532\u5534"+ - "\u5535\u5536\u5538\u5539\u553A\u553B\u553D\u5540"+ - "\u5542\u5545\u5547\u5548\u554B\u554C\u554D\u554E"+ - "\u554F\u5551\u5552\u5553\u5554\u5557\u5558\u5559"+ - "\u555A\u555B\u555D\u555E\u555F\u5560\u5562\u5563"+ - "\u5568\u5569\u556B\u556F\u5570\u5571\u5572\u5573"+ - "\u5574\u5579\u557A\u557D\u557F\u5585\u5586\u558C"+ - "\u558D\u558E\u5590\u5592\u5593\u5595\u5596\u5597"+ - "\u559A\u559B\u559E\u55A0\u55A1\u55A2\u55A3\u55A4"+ - "\u55A5\u55A6\u55A8\u55A9\u55AA\u55AB\u55AC\u55AD"+ - "\u55AE\u55AF\u55B0\u55B2\u55B4\u55B6\u55B8\u55BA"+ - "\u55BC\u55BF\u55C0\u55C1\u55C2\u55C3\u55C6\u55C7"+ - "\u55C8\u55CA\u55CB\u55CE\u55CF\u55D0\u55D5\u55D7"+ - "\u55D8\u55D9\u55DA\u55DB\u55DE\u55E0\u55E2\u55E7"+ - "\u55E9\u55ED\u55EE\u55F0\u55F1\u55F4\u55F6\u55F8"+ - "\u55F9\u55FA\u55FB\u55FC\u55FF\u5602\u5603\u5604"+ - "\u5605\u5606\u5607\u560A\u560B\u560D\u5610\u5611"+ - "\u5612\u5613\u5614\u5615\u5616\u5617\u5619\u561A"+ - "\u561C\u561D\u5620\u5621\u5622\u5625\u5626\u5628"+ - "\u5629\u562A\u562B\u562E\u562F\u5630\u5633\u5635"+ - "\u5637\u5638\u563A\u563C\u563D\u563E\u5640\u5641"+ - "\u5642\u5643\u5644\u5645\u5646\u5647\u5648\u5649"+ - "\u564A\u564B\u564F\u5650\u5651\u5652\u5653\u5655"+ - "\u5656\u565A\u565B\u565D\u565E\u565F\u5660\u5661"+ - "\uFFFD\u5663\u5665\u5666\u5667\u566D\u566E\u566F"+ - "\u5670\u5672\u5673\u5674\u5675\u5677\u5678\u5679"+ - "\u567A\u567D\u567E\u567F\u5680\u5681\u5682\u5683"+ - "\u5684\u5687\u5688\u5689\u568A\u568B\u568C\u568D"+ - "\u5690\u5691\u5692\u5694\u5695\u5696\u5697\u5698"+ - "\u5699\u569A\u569B\u569C\u569D\u569E\u569F\u56A0"+ - "\u56A1\u56A2\u56A4\u56A5\u56A6\u56A7\u56A8\u56A9"+ - "\u56AA\u56AB\u56AC\u56AD\u56AE\u56B0\u56B1\u56B2"+ - "\u56B3\u56B4\u56B5\u56B6\u56B8\u56B9\u56BA\u56BB"+ - "\u56BD\u56BE\u56BF\u56C0\u56C1\u56C2\u56C3\u56C4"+ - "\u56C5\u56C6\u56C7\u56C8\u56C9\u56CB\u56CC\u56CD"+ - "\u56CE\u56CF\u56D0\u56D1\u56D2\u56D3\u56D5\u56D6"+ - "\u56D8\u56D9\u56DC\u56E3\u56E5\u56E6\u56E7\u56E8"+ - "\u56E9\u56EA\u56EC\u56EE\u56EF\u56F2\u56F3\u56F6"+ - "\u56F7\u56F8\u56FB\u56FC\u5700\u5701\u5702\u5705"+ - "\u5707\u570B\u570C\u570D\u570E\u570F\u5710\u5711"+ - "\u5712\u5713\u5714\u5715\u5716\u5717\u5718\u5719"+ - "\u571A\u571B\u571D\u571E\u5720\u5721\u5722\u5724"+ - "\u5725\u5726\u5727\u572B\u5731\u5732\u5734\u5735"+ - "\u5736\u5737\u5738\u573C\u573D\u573F\u5741\u5743"+ - "\u5744\u5745\u5746\u5748\u5749\u574B\u5752\u5753"+ - "\u5754\u5755\u5756\u5758\u5759\u5762\u5763\u5765"+ - "\u5767\u576C\u576E\u5770\u5771\u5772\u5774\u5775"+ - "\u5778\u5779\u577A\u577D\u577E\u577F\u5780\uFFFD"+ - "\u5781\u5787\u5788\u5789\u578A\u578D\u578E\u578F"+ - "\u5790\u5791\u5794\u5795\u5796\u5797\u5798\u5799"+ - "\u579A\u579C\u579D\u579E\u579F\u57A5\u57A8\u57AA"+ - "\u57AC\u57AF\u57B0\u57B1\u57B3\u57B5\u57B6\u57B7"+ - "\u57B9\u57BA\u57BB\u57BC\u57BD\u57BE\u57BF\u57C0"+ - "\u57C1\u57C4\u57C5\u57C6\u57C7\u57C8\u57C9\u57CA"+ - "\u57CC\u57CD\u57D0\u57D1\u57D3\u57D6\u57D7\u57DB"+ - "\u57DC\u57DE\u57E1\u57E2\u57E3\u57E5\u57E6\u57E7"+ - "\u57E8\u57E9\u57EA\u57EB\u57EC\u57EE\u57F0\u57F1"+ - "\u57F2\u57F3\u57F5\u57F6\u57F7\u57FB\u57FC\u57FE"+ - "\u57FF\u5801\u5803\u5804\u5805\u5808\u5809\u580A"+ - "\u580C\u580E\u580F\u5810\u5812\u5813\u5814\u5816"+ - "\u5817\u5818\u581A\u581B\u581C\u581D\u581F\u5822"+ - "\u5823\u5825\u5826\u5827\u5828\u5829\u582B\u582C"+ - "\u582D\u582E\u582F\u5831\u5832\u5833\u5834\u5836"+ - "\u5837\u5838\u5839\u583A\u583B\u583C\u583D\u583E"+ - "\u583F\u5840\u5841\u5842\u5843\u5845\u5846\u5847"+ - "\u5848\u5849\u584A\u584B\u584E\u584F\u5850\u5852"+ - "\u5853\u5855\u5856\u5857\u5859\u585A\u585B\u585C"+ - "\u585D\u585F\u5860\u5861\u5862\u5863\u5864\u5866"+ - "\u5867\u5868\u5869\u586A\u586D\u586E\u586F\u5870"+ - "\u5871\u5872\u5873\u5874\u5875\u5876\u5877\u5878"+ - "\u5879\u587A\u587B\u587C\u587D\u587F\u5882\u5884"+ - "\u5886\u5887\u5888\u588A\u588B\u588C\uFFFD\u588D"+ - "\u588E\u588F\u5890\u5891\u5894\u5895\u5896\u5897"+ - "\u5898\u589B\u589C\u589D\u58A0\u58A1\u58A2\u58A3"+ - "\u58A4\u58A5\u58A6\u58A7\u58AA\u58AB\u58AC\u58AD"+ - "\u58AE\u58AF\u58B0\u58B1\u58B2\u58B3\u58B4\u58B5"+ - "\u58B6\u58B7\u58B8\u58B9\u58BA\u58BB\u58BD\u58BE"+ - "\u58BF\u58C0\u58C2\u58C3\u58C4\u58C6\u58C7\u58C8"+ - "\u58C9\u58CA\u58CB\u58CC\u58CD\u58CE\u58CF\u58D0"+ - "\u58D2\u58D3\u58D4\u58D6\u58D7\u58D8\u58D9\u58DA"+ - "\u58DB\u58DC\u58DD\u58DE\u58DF\u58E0\u58E1\u58E2"+ - "\u58E3\u58E5\u58E6\u58E7\u58E8\u58E9\u58EA\u58ED"+ - "\u58EF\u58F1\u58F2\u58F4\u58F5\u58F7\u58F8\u58FA"+ - "\u58FB\u58FC\u58FD\u58FE\u58FF\u5900\u5901\u5903"+ - "\u5905\u5906\u5908\u5909\u590A\u590B\u590C\u590E"+ - "\u5910\u5911\u5912\u5913\u5917\u5918\u591B\u591D"+ - "\u591E\u5920\u5921\u5922\u5923\u5926\u5928\u592C"+ - "\u5930\u5932\u5933\u5935\u5936\u593B\u593D\u593E"+ - "\u593F\u5940\u5943\u5945\u5946\u594A\u594C\u594D"+ - "\u5950\u5952\u5953\u5959\u595B\u595C\u595D\u595E"+ - "\u595F\u5961\u5963\u5964\u5966\u5967\u5968\u5969"+ - "\u596A\u596B\u596C\u596D\u596E\u596F\u5970\u5971"+ - "\u5972\u5975\u5977\u597A\u597B\u597C\u597E\u597F"+ - "\u5980\u5985\u5989\u598B\u598C\u598E\u598F\u5990"+ - "\u5991\u5994\u5995\u5998\u599A\u599B\u599C\u599D"+ - "\u599F\u59A0\u59A1\u59A2\u59A6\uFFFD\u59A7\u59AC"+ - "\u59AD\u59B0\u59B1\u59B3\u59B4\u59B5\u59B6\u59B7"+ - "\u59B8\u59BA\u59BC\u59BD\u59BF\u59C0\u59C1\u59C2"+ - "\u59C3\u59C4\u59C5\u59C7\u59C8\u59C9\u59CC\u59CD"+ - "\u59CE\u59CF\u59D5\u59D6\u59D9\u59DB\u59DE\u59DF"+ - "\u59E0\u59E1\u59E2\u59E4\u59E6\u59E7\u59E9\u59EA"+ - "\u59EB\u59ED\u59EE\u59EF\u59F0\u59F1\u59F2\u59F3"+ - "\u59F4\u59F5\u59F6\u59F7\u59F8\u59FA\u59FC\u59FD"+ - "\u59FE\u5A00\u5A02\u5A0A\u5A0B\u5A0D\u5A0E\u5A0F"+ - "\u5A10\u5A12\u5A14\u5A15\u5A16\u5A17\u5A19\u5A1A"+ - "\u5A1B\u5A1D\u5A1E\u5A21\u5A22\u5A24\u5A26\u5A27"+ - "\u5A28\u5A2A\u5A2B\u5A2C\u5A2D\u5A2E\u5A2F\u5A30"+ - "\u5A33\u5A35\u5A37\u5A38\u5A39\u5A3A\u5A3B\u5A3D"+ - "\u5A3E\u5A3F\u5A41\u5A42\u5A43\u5A44\u5A45\u5A47"+ - "\u5A48\u5A4B\u5A4C\u5A4D\u5A4E\u5A4F\u5A50\u5A51"+ - "\u5A52\u5A53\u5A54\u5A56\u5A57\u5A58\u5A59\u5A5B"+ - "\u5A5C\u5A5D\u5A5E\u5A5F\u5A60\u5A61\u5A63\u5A64"+ - "\u5A65\u5A66\u5A68\u5A69\u5A6B\u5A6C\u5A6D\u5A6E"+ - "\u5A6F\u5A70\u5A71\u5A72\u5A73\u5A78\u5A79\u5A7B"+ - "\u5A7C\u5A7D\u5A7E\u5A80\u5A81\u5A82\u5A83\u5A84"+ - "\u5A85\u5A86\u5A87\u5A88\u5A89\u5A8A\u5A8B\u5A8C"+ - "\u5A8D\u5A8E\u5A8F\u5A90\u5A91\u5A93\u5A94\u5A95"+ - "\u5A96\u5A97\u5A98\u5A99\u5A9C\u5A9D\u5A9E\u5A9F"+ - "\u5AA0\u5AA1\u5AA2\u5AA3\u5AA4\u5AA5\u5AA6\u5AA7"+ - "\u5AA8\u5AA9\u5AAB\u5AAC\uFFFD\u5AAD\u5AAE\u5AAF"+ - "\u5AB0\u5AB1\u5AB4\u5AB6\u5AB7\u5AB9\u5ABA\u5ABB"+ - "\u5ABC\u5ABD\u5ABF\u5AC0\u5AC3\u5AC4\u5AC5\u5AC6"+ - "\u5AC7\u5AC8\u5ACA\u5ACB\u5ACD\u5ACE\u5ACF\u5AD0"+ - "\u5AD1\u5AD3\u5AD5\u5AD7\u5AD9\u5ADA\u5ADB\u5ADD"+ - "\u5ADE\u5ADF\u5AE2\u5AE4\u5AE5\u5AE7\u5AE8\u5AEA"+ - "\u5AEC\u5AED\u5AEE\u5AEF\u5AF0\u5AF2\u5AF3\u5AF4"+ - "\u5AF5\u5AF6\u5AF7\u5AF8\u5AF9\u5AFA\u5AFB\u5AFC"+ - "\u5AFD\u5AFE\u5AFF\u5B00\u5B01\u5B02\u5B03\u5B04"+ - "\u5B05\u5B06\u5B07\u5B08\u5B0A\u5B0B\u5B0C\u5B0D"+ - "\u5B0E\u5B0F\u5B10\u5B11\u5B12\u5B13\u5B14\u5B15"+ - "\u5B18\u5B19\u5B1A\u5B1B\u5B1C\u5B1D\u5B1E\u5B1F"+ - "\u5B20\u5B21\u5B22\u5B23\u5B24\u5B25\u5B26\u5B27"+ - "\u5B28\u5B29\u5B2A\u5B2B\u5B2C\u5B2D\u5B2E\u5B2F"+ - "\u5B30\u5B31\u5B33\u5B35\u5B36\u5B38\u5B39\u5B3A"+ - "\u5B3B\u5B3C\u5B3D\u5B3E\u5B3F\u5B41\u5B42\u5B43"+ - "\u5B44\u5B45\u5B46\u5B47\u5B48\u5B49\u5B4A\u5B4B"+ - "\u5B4C\u5B4D\u5B4E\u5B4F\u5B52\u5B56\u5B5E\u5B60"+ - "\u5B61\u5B67\u5B68\u5B6B\u5B6D\u5B6E\u5B6F\u5B72"+ - "\u5B74\u5B76\u5B77\u5B78\u5B79\u5B7B\u5B7C\u5B7E"+ - "\u5B7F\u5B82\u5B86\u5B8A\u5B8D\u5B8E\u5B90\u5B91"+ - "\u5B92\u5B94\u5B96\u5B9F\u5BA7\u5BA8\u5BA9\u5BAC"+ - "\u5BAD\u5BAE\u5BAF\u5BB1\u5BB2\u5BB7\u5BBA\u5BBB"+ - "\u5BBC\u5BC0\u5BC1\u5BC3\u5BC8\u5BC9\u5BCA\u5BCB"+ - "\u5BCD\u5BCE\u5BCF\uFFFD\u5BD1\u5BD4\u5BD5\u5BD6"+ - "\u5BD7\u5BD8\u5BD9\u5BDA\u5BDB\u5BDC\u5BE0\u5BE2"+ - "\u5BE3\u5BE6\u5BE7\u5BE9\u5BEA\u5BEB\u5BEC\u5BED"+ - "\u5BEF\u5BF1\u5BF2\u5BF3\u5BF4\u5BF5\u5BF6\u5BF7"+ - "\u5BFD\u5BFE\u5C00\u5C02\u5C03\u5C05\u5C07\u5C08"+ - "\u5C0B\u5C0C\u5C0D\u5C0E\u5C10\u5C12\u5C13\u5C17"+ - "\u5C19\u5C1B\u5C1E\u5C1F\u5C20\u5C21\u5C23\u5C26"+ - "\u5C28\u5C29\u5C2A\u5C2B\u5C2D\u5C2E\u5C2F\u5C30"+ - "\u5C32\u5C33\u5C35\u5C36\u5C37\u5C43\u5C44\u5C46"+ - "\u5C47\u5C4C\u5C4D\u5C52\u5C53\u5C54\u5C56\u5C57"+ - "\u5C58\u5C5A\u5C5B\u5C5C\u5C5D\u5C5F\u5C62\u5C64"+ - "\u5C67\u5C68\u5C69\u5C6A\u5C6B\u5C6C\u5C6D\u5C70"+ - "\u5C72\u5C73\u5C74\u5C75\u5C76\u5C77\u5C78\u5C7B"+ - "\u5C7C\u5C7D\u5C7E\u5C80\u5C83\u5C84\u5C85\u5C86"+ - "\u5C87\u5C89\u5C8A\u5C8B\u5C8E\u5C8F\u5C92\u5C93"+ - "\u5C95\u5C9D\u5C9E\u5C9F\u5CA0\u5CA1\u5CA4\u5CA5"+ - "\u5CA6\u5CA7\u5CA8\u5CAA\u5CAE\u5CAF\u5CB0\u5CB2"+ - "\u5CB4\u5CB6\u5CB9\u5CBA\u5CBB\u5CBC\u5CBE\u5CC0"+ - "\u5CC2\u5CC3\u5CC5\u5CC6\u5CC7\u5CC8\u5CC9\u5CCA"+ - "\u5CCC\u5CCD\u5CCE\u5CCF\u5CD0\u5CD1\u5CD3\u5CD4"+ - "\u5CD5\u5CD6\u5CD7\u5CD8\u5CDA\u5CDB\u5CDC\u5CDD"+ - "\u5CDE\u5CDF\u5CE0\u5CE2\u5CE3\u5CE7\u5CE9\u5CEB"+ - "\u5CEC\u5CEE\u5CEF\u5CF1\u5CF2\u5CF3\u5CF4\u5CF5"+ - "\u5CF6\u5CF7\u5CF8\u5CF9\u5CFA\u5CFC\u5CFD\u5CFE"+ - "\u5CFF\u5D00\uFFFD\u5D01\u5D04\u5D05\u5D08\u5D09"+ - "\u5D0A\u5D0B\u5D0C\u5D0D\u5D0F\u5D10\u5D11\u5D12"+ - "\u5D13\u5D15\u5D17\u5D18\u5D19\u5D1A\u5D1C\u5D1D"+ - "\u5D1F\u5D20\u5D21\u5D22\u5D23\u5D25\u5D28\u5D2A"+ - "\u5D2B\u5D2C\u5D2F\u5D30\u5D31\u5D32\u5D33\u5D35"+ - "\u5D36\u5D37\u5D38\u5D39\u5D3A\u5D3B\u5D3C\u5D3F"+ - "\u5D40\u5D41\u5D42\u5D43\u5D44\u5D45\u5D46\u5D48"+ - "\u5D49\u5D4D\u5D4E\u5D4F\u5D50\u5D51\u5D52\u5D53"+ - "\u5D54\u5D55\u5D56\u5D57\u5D59\u5D5A\u5D5C\u5D5E"+ - "\u5D5F\u5D60\u5D61\u5D62\u5D63\u5D64\u5D65\u5D66"+ - "\u5D67\u5D68\u5D6A\u5D6D\u5D6E\u5D70\u5D71\u5D72"+ - "\u5D73\u5D75\u5D76\u5D77\u5D78\u5D79\u5D7A\u5D7B"+ - "\u5D7C\u5D7D\u5D7E\u5D7F\u5D80\u5D81\u5D83\u5D84"+ - "\u5D85\u5D86\u5D87\u5D88\u5D89\u5D8A\u5D8B\u5D8C"+ - "\u5D8D\u5D8E\u5D8F\u5D90\u5D91\u5D92\u5D93\u5D94"+ - "\u5D95\u5D96\u5D97\u5D98\u5D9A\u5D9B\u5D9C\u5D9E"+ - "\u5D9F\u5DA0\u5DA1\u5DA2\u5DA3\u5DA4\u5DA5\u5DA6"+ - "\u5DA7\u5DA8\u5DA9\u5DAA\u5DAB\u5DAC\u5DAD\u5DAE"+ - "\u5DAF\u5DB0\u5DB1\u5DB2\u5DB3\u5DB4\u5DB5\u5DB6"+ - "\u5DB8\u5DB9\u5DBA\u5DBB\u5DBC\u5DBD\u5DBE\u5DBF"+ - "\u5DC0\u5DC1\u5DC2\u5DC3\u5DC4\u5DC6\u5DC7\u5DC8"+ - "\u5DC9\u5DCA\u5DCB\u5DCC\u5DCE\u5DCF\u5DD0\u5DD1"+ - "\u5DD2\u5DD3\u5DD4\u5DD5\u5DD6\u5DD7\u5DD8\u5DD9"+ - "\u5DDA\u5DDC\u5DDF\u5DE0\u5DE3\u5DE4\u5DEA\u5DEC"+ - "\u5DED\uFFFD\u5DF0\u5DF5\u5DF6\u5DF8\u5DF9\u5DFA"+ - "\u5DFB\u5DFC\u5DFF\u5E00\u5E04\u5E07\u5E09\u5E0A"+ - "\u5E0B\u5E0D\u5E0E\u5E12\u5E13\u5E17\u5E1E\u5E1F"+ - "\u5E20\u5E21\u5E22\u5E23\u5E24\u5E25\u5E28\u5E29"+ - "\u5E2A\u5E2B\u5E2C\u5E2F\u5E30\u5E32\u5E33\u5E34"+ - "\u5E35\u5E36\u5E39\u5E3A\u5E3E\u5E3F\u5E40\u5E41"+ - "\u5E43\u5E46\u5E47\u5E48\u5E49\u5E4A\u5E4B\u5E4D"+ - "\u5E4E\u5E4F\u5E50\u5E51\u5E52\u5E53\u5E56\u5E57"+ - "\u5E58\u5E59\u5E5A\u5E5C\u5E5D\u5E5F\u5E60\u5E63"+ - "\u5E64\u5E65\u5E66\u5E67\u5E68\u5E69\u5E6A\u5E6B"+ - "\u5E6C\u5E6D\u5E6E\u5E6F\u5E70\u5E71\u5E75\u5E77"+ - "\u5E79\u5E7E\u5E81\u5E82\u5E83\u5E85\u5E88\u5E89"+ - "\u5E8C\u5E8D\u5E8E\u5E92\u5E98\u5E9B\u5E9D\u5EA1"+ - "\u5EA2\u5EA3\u5EA4\u5EA8\u5EA9\u5EAA\u5EAB\u5EAC"+ - "\u5EAE\u5EAF\u5EB0\u5EB1\u5EB2\u5EB4\u5EBA\u5EBB"+ - "\u5EBC\u5EBD\u5EBF\u5EC0\u5EC1\u5EC2\u5EC3\u5EC4"+ - "\u5EC5\u5EC6\u5EC7\u5EC8\u5ECB\u5ECC\u5ECD\u5ECE"+ - "\u5ECF\u5ED0\u5ED4\u5ED5\u5ED7\u5ED8\u5ED9\u5EDA"+ - "\u5EDC\u5EDD\u5EDE\u5EDF\u5EE0\u5EE1\u5EE2\u5EE3"+ - "\u5EE4\u5EE5\u5EE6\u5EE7\u5EE9\u5EEB\u5EEC\u5EED"+ - "\u5EEE\u5EEF\u5EF0\u5EF1\u5EF2\u5EF3\u5EF5\u5EF8"+ - "\u5EF9\u5EFB\u5EFC\u5EFD\u5F05\u5F06\u5F07\u5F09"+ - "\u5F0C\u5F0D\u5F0E\u5F10\u5F12\u5F14\u5F16\u5F19"+ - "\u5F1A\u5F1C\u5F1D\u5F1E\u5F21\u5F22\u5F23\u5F24"+ - "\uFFFD\u5F28\u5F2B\u5F2C\u5F2E\u5F30\u5F32\u5F33"+ - "\u5F34\u5F35\u5F36\u5F37\u5F38\u5F3B\u5F3D\u5F3E"+ - "\u5F3F\u5F41\u5F42\u5F43\u5F44\u5F45\u5F46\u5F47"+ - "\u5F48\u5F49\u5F4A\u5F4B\u5F4C\u5F4D\u5F4E\u5F4F"+ - "\u5F51\u5F54\u5F59\u5F5A\u5F5B\u5F5C\u5F5E\u5F5F"+ - "\u5F60\u5F63\u5F65\u5F67\u5F68\u5F6B\u5F6E\u5F6F"+ - "\u5F72\u5F74\u5F75\u5F76\u5F78\u5F7A\u5F7D\u5F7E"+ - "\u5F7F\u5F83\u5F86\u5F8D\u5F8E\u5F8F\u5F91\u5F93"+ - "\u5F94\u5F96\u5F9A\u5F9B\u5F9D\u5F9E\u5F9F\u5FA0"+ - "\u5FA2\u5FA3\u5FA4\u5FA5\u5FA6\u5FA7\u5FA9\u5FAB"+ - "\u5FAC\u5FAF\u5FB0\u5FB1\u5FB2\u5FB3\u5FB4\u5FB6"+ - "\u5FB8\u5FB9\u5FBA\u5FBB\u5FBE\u5FBF\u5FC0\u5FC1"+ - "\u5FC2\u5FC7\u5FC8\u5FCA\u5FCB\u5FCE\u5FD3\u5FD4"+ - "\u5FD5\u5FDA\u5FDB\u5FDC\u5FDE\u5FDF\u5FE2\u5FE3"+ - "\u5FE5\u5FE6\u5FE8\u5FE9\u5FEC\u5FEF\u5FF0\u5FF2"+ - "\u5FF3\u5FF4\u5FF6\u5FF7\u5FF9\u5FFA\u5FFC\u6007"; - - private static final String innerIndex1= - "\u6008\u6009\u600B\u600C\u6010\u6011\u6013\u6017"+ - "\u6018\u601A\u601E\u601F\u6022\u6023\u6024\u602C"+ - "\u602D\u602E\u6030\u6031\u6032\u6033\u6034\u6036"+ - "\u6037\u6038\u6039\u603A\u603D\u603E\u6040\u6044"+ - "\u6045\u6046\u6047\u6048\u6049\u604A\u604C\u604E"+ - "\u604F\u6051\u6053\u6054\u6056\u6057\u6058\u605B"+ - "\u605C\u605E\u605F\u6060\u6061\u6065\u6066\u606E"+ - "\u6071\u6072\u6074\u6075\u6077\u607E\u6080\uFFFD"+ - "\u6081\u6082\u6085\u6086\u6087\u6088\u608A\u608B"+ - "\u608E\u608F\u6090\u6091\u6093\u6095\u6097\u6098"+ - "\u6099\u609C\u609E\u60A1\u60A2\u60A4\u60A5\u60A7"+ - "\u60A9\u60AA\u60AE\u60B0\u60B3\u60B5\u60B6\u60B7"+ - "\u60B9\u60BA\u60BD\u60BE\u60BF\u60C0\u60C1\u60C2"+ - "\u60C3\u60C4\u60C7\u60C8\u60C9\u60CC\u60CD\u60CE"+ - "\u60CF\u60D0\u60D2\u60D3\u60D4\u60D6\u60D7\u60D9"+ - "\u60DB\u60DE\u60E1\u60E2\u60E3\u60E4\u60E5\u60EA"+ - "\u60F1\u60F2\u60F5\u60F7\u60F8\u60FB\u60FC\u60FD"+ - "\u60FE\u60FF\u6102\u6103\u6104\u6105\u6107\u610A"+ - "\u610B\u610C\u6110\u6111\u6112\u6113\u6114\u6116"+ - "\u6117\u6118\u6119\u611B\u611C\u611D\u611E\u6121"+ - "\u6122\u6125\u6128\u6129\u612A\u612C\u612D\u612E"+ - "\u612F\u6130\u6131\u6132\u6133\u6134\u6135\u6136"+ - "\u6137\u6138\u6139\u613A\u613B\u613C\u613D\u613E"+ - "\u6140\u6141\u6142\u6143\u6144\u6145\u6146\u6147"+ - "\u6149\u614B\u614D\u614F\u6150\u6152\u6153\u6154"+ - "\u6156\u6157\u6158\u6159\u615A\u615B\u615C\u615E"+ - "\u615F\u6160\u6161\u6163\u6164\u6165\u6166\u6169"+ - "\u616A\u616B\u616C\u616D\u616E\u616F\u6171\u6172"+ - "\u6173\u6174\u6176\u6178\u6179\u617A\u617B\u617C"+ - "\u617D\u617E\u617F\u6180\u6181\u6182\u6183\u6184"+ - "\u6185\u6186\u6187\u6188\u6189\u618A\u618C\u618D"+ - "\u618F\u6190\u6191\u6192\u6193\u6195\uFFFD\u6196"+ - "\u6197\u6198\u6199\u619A\u619B\u619C\u619E\u619F"+ - "\u61A0\u61A1\u61A2\u61A3\u61A4\u61A5\u61A6\u61AA"+ - "\u61AB\u61AD\u61AE\u61AF\u61B0\u61B1\u61B2\u61B3"+ - "\u61B4\u61B5\u61B6\u61B8\u61B9\u61BA\u61BB\u61BC"+ - "\u61BD\u61BF\u61C0\u61C1\u61C3\u61C4\u61C5\u61C6"+ - "\u61C7\u61C9\u61CC\u61CD\u61CE\u61CF\u61D0\u61D3"+ - "\u61D5\u61D6\u61D7\u61D8\u61D9\u61DA\u61DB\u61DC"+ - "\u61DD\u61DE\u61DF\u61E0\u61E1\u61E2\u61E3\u61E4"+ - "\u61E5\u61E7\u61E8\u61E9\u61EA\u61EB\u61EC\u61ED"+ - "\u61EE\u61EF\u61F0\u61F1\u61F2\u61F3\u61F4\u61F6"+ - "\u61F7\u61F8\u61F9\u61FA\u61FB\u61FC\u61FD\u61FE"+ - "\u6200\u6201\u6202\u6203\u6204\u6205\u6207\u6209"+ - "\u6213\u6214\u6219\u621C\u621D\u621E\u6220\u6223"+ - "\u6226\u6227\u6228\u6229\u622B\u622D\u622F\u6230"+ - "\u6231\u6232\u6235\u6236\u6238\u6239\u623A\u623B"+ - "\u623C\u6242\u6244\u6245\u6246\u624A\u624F\u6250"+ - "\u6255\u6256\u6257\u6259\u625A\u625C\u625D\u625E"+ - "\u625F\u6260\u6261\u6262\u6264\u6265\u6268\u6271"+ - "\u6272\u6274\u6275\u6277\u6278\u627A\u627B\u627D"+ - "\u6281\u6282\u6283\u6285\u6286\u6287\u6288\u628B"+ - "\u628C\u628D\u628E\u628F\u6290\u6294\u6299\u629C"+ - "\u629D\u629E\u62A3\u62A6\u62A7\u62A9\u62AA\u62AD"+ - "\u62AE\u62AF\u62B0\u62B2\u62B3\u62B4\u62B6\u62B7"+ - "\u62B8\u62BA\u62BE\u62C0\u62C1\uFFFD\u62C3\u62CB"+ - "\u62CF\u62D1\u62D5\u62DD\u62DE\u62E0\u62E1\u62E4"+ - "\u62EA\u62EB\u62F0\u62F2\u62F5\u62F8\u62F9\u62FA"+ - "\u62FB\u6300\u6303\u6304\u6305\u6306\u630A\u630B"+ - "\u630C\u630D\u630F\u6310\u6312\u6313\u6314\u6315"+ - "\u6317\u6318\u6319\u631C\u6326\u6327\u6329\u632C"+ - "\u632D\u632E\u6330\u6331\u6333\u6334\u6335\u6336"+ - "\u6337\u6338\u633B\u633C\u633E\u633F\u6340\u6341"+ - "\u6344\u6347\u6348\u634A\u6351\u6352\u6353\u6354"+ - "\u6356\u6357\u6358\u6359\u635A\u635B\u635C\u635D"+ - "\u6360\u6364\u6365\u6366\u6368\u636A\u636B\u636C"+ - "\u636F\u6370\u6372\u6373\u6374\u6375\u6378\u6379"+ - "\u637C\u637D\u637E\u637F\u6381\u6383\u6384\u6385"+ - "\u6386\u638B\u638D\u6391\u6393\u6394\u6395\u6397"+ - "\u6399\u639A\u639B\u639C\u639D\u639E\u639F\u63A1"+ - "\u63A4\u63A6\u63AB\u63AF\u63B1\u63B2\u63B5\u63B6"+ - "\u63B9\u63BB\u63BD\u63BF\u63C0\u63C1\u63C2\u63C3"+ - "\u63C5\u63C7\u63C8\u63CA\u63CB\u63CC\u63D1\u63D3"+ - "\u63D4\u63D5\u63D7\u63D8\u63D9\u63DA\u63DB\u63DC"+ - "\u63DD\u63DF\u63E2\u63E4\u63E5\u63E6\u63E7\u63E8"+ - "\u63EB\u63EC\u63EE\u63EF\u63F0\u63F1\u63F3\u63F5"+ - "\u63F7\u63F9\u63FA\u63FB\u63FC\u63FE\u6403\u6404"+ - "\u6406\u6407\u6408\u6409\u640A\u640D\u640E\u6411"+ - "\u6412\u6415\u6416\u6417\u6418\u6419\u641A\u641D"+ - "\u641F\u6422\u6423\u6424\uFFFD\u6425\u6427\u6428"+ - "\u6429\u642B\u642E\u642F\u6430\u6431\u6432\u6433"+ - "\u6435\u6436\u6437\u6438\u6439\u643B\u643C\u643E"+ - "\u6440\u6442\u6443\u6449\u644B\u644C\u644D\u644E"+ - "\u644F\u6450\u6451\u6453\u6455\u6456\u6457\u6459"+ - "\u645A\u645B\u645C\u645D\u645F\u6460\u6461\u6462"+ - "\u6463\u6464\u6465\u6466\u6468\u646A\u646B\u646C"+ - "\u646E\u646F\u6470\u6471\u6472\u6473\u6474\u6475"+ - "\u6476\u6477\u647B\u647C\u647D\u647E\u647F\u6480"+ - "\u6481\u6483\u6486\u6488\u6489\u648A\u648B\u648C"+ - "\u648D\u648E\u648F\u6490\u6493\u6494\u6497\u6498"+ - "\u649A\u649B\u649C\u649D\u649F\u64A0\u64A1\u64A2"+ - "\u64A3\u64A5\u64A6\u64A7\u64A8\u64AA\u64AB\u64AF"+ - "\u64B1\u64B2\u64B3\u64B4\u64B6\u64B9\u64BB\u64BD"+ - "\u64BE\u64BF\u64C1\u64C3\u64C4\u64C6\u64C7\u64C8"+ - "\u64C9\u64CA\u64CB\u64CC\u64CF\u64D1\u64D3\u64D4"+ - "\u64D5\u64D6\u64D9\u64DA\u64DB\u64DC\u64DD\u64DF"+ - "\u64E0\u64E1\u64E3\u64E5\u64E7\u64E8\u64E9\u64EA"+ - "\u64EB\u64EC\u64ED\u64EE\u64EF\u64F0\u64F1\u64F2"+ - "\u64F3\u64F4\u64F5\u64F6\u64F7\u64F8\u64F9\u64FA"+ - "\u64FB\u64FC\u64FD\u64FE\u64FF\u6501\u6502\u6503"+ - "\u6504\u6505\u6506\u6507\u6508\u650A\u650B\u650C"+ - "\u650D\u650E\u650F\u6510\u6511\u6513\u6514\u6515"+ - "\u6516\u6517\u6519\u651A\u651B\u651C\u651D\u651E"+ - "\u651F\u6520\u6521\uFFFD\u6522\u6523\u6524\u6526"+ - "\u6527\u6528\u6529\u652A\u652C\u652D\u6530\u6531"+ - "\u6532\u6533\u6537\u653A\u653C\u653D\u6540\u6541"+ - "\u6542\u6543\u6544\u6546\u6547\u654A\u654B\u654D"+ - "\u654E\u6550\u6552\u6553\u6554\u6557\u6558\u655A"+ - "\u655C\u655F\u6560\u6561\u6564\u6565\u6567\u6568"+ - "\u6569\u656A\u656D\u656E\u656F\u6571\u6573\u6575"+ - "\u6576\u6578\u6579\u657A\u657B\u657C\u657D\u657E"+ - "\u657F\u6580\u6581\u6582\u6583\u6584\u6585\u6586"+ - "\u6588\u6589\u658A\u658D\u658E\u658F\u6592\u6594"+ - "\u6595\u6596\u6598\u659A\u659D\u659E\u65A0\u65A2"+ - "\u65A3\u65A6\u65A8\u65AA\u65AC\u65AE\u65B1\u65B2"+ - "\u65B3\u65B4\u65B5\u65B6\u65B7\u65B8\u65BA\u65BB"+ - "\u65BE\u65BF\u65C0\u65C2\u65C7\u65C8\u65C9\u65CA"+ - "\u65CD\u65D0\u65D1\u65D3\u65D4\u65D5\u65D8\u65D9"+ - "\u65DA\u65DB\u65DC\u65DD\u65DE\u65DF\u65E1\u65E3"+ - "\u65E4\u65EA\u65EB\u65F2\u65F3\u65F4\u65F5\u65F8"+ - "\u65F9\u65FB\u65FC\u65FD\u65FE\u65FF\u6601\u6604"+ - "\u6605\u6607\u6608\u6609\u660B\u660D\u6610\u6611"+ - "\u6612\u6616\u6617\u6618\u661A\u661B\u661C\u661E"+ - "\u6621\u6622\u6623\u6624\u6626\u6629\u662A\u662B"+ - "\u662C\u662E\u6630\u6632\u6633\u6637\u6638\u6639"+ - "\u663A\u663B\u663D\u663F\u6640\u6642\u6644\u6645"+ - "\u6646\u6647\u6648\u6649\u664A\u664D\u664E\u6650"+ - "\u6651\u6658\uFFFD\u6659\u665B\u665C\u665D\u665E"+ - "\u6660\u6662\u6663\u6665\u6667\u6669\u666A\u666B"+ - "\u666C\u666D\u6671\u6672\u6673\u6675\u6678\u6679"+ - "\u667B\u667C\u667D\u667F\u6680\u6681\u6683\u6685"+ - "\u6686\u6688\u6689\u668A\u668B\u668D\u668E\u668F"+ - "\u6690\u6692\u6693\u6694\u6695\u6698\u6699\u669A"+ - "\u669B\u669C\u669E\u669F\u66A0\u66A1\u66A2\u66A3"+ - "\u66A4\u66A5\u66A6\u66A9\u66AA\u66AB\u66AC\u66AD"+ - "\u66AF\u66B0\u66B1\u66B2\u66B3\u66B5\u66B6\u66B7"+ - "\u66B8\u66BA\u66BB\u66BC\u66BD\u66BF\u66C0\u66C1"+ - "\u66C2\u66C3\u66C4\u66C5\u66C6\u66C7\u66C8\u66C9"+ - "\u66CA\u66CB\u66CC\u66CD\u66CE\u66CF\u66D0\u66D1"+ - "\u66D2\u66D3\u66D4\u66D5\u66D6\u66D7\u66D8\u66DA"+ - "\u66DE\u66DF\u66E0\u66E1\u66E2\u66E3\u66E4\u66E5"+ - "\u66E7\u66E8\u66EA\u66EB\u66EC\u66ED\u66EE\u66EF"+ - "\u66F1\u66F5\u66F6\u66F8\u66FA\u66FB\u66FD\u6701"+ - "\u6702\u6703\u6704\u6705\u6706\u6707\u670C\u670E"+ - "\u670F\u6711\u6712\u6713\u6716\u6718\u6719\u671A"+ - "\u671C\u671E\u6720\u6721\u6722\u6723\u6724\u6725"+ - "\u6727\u6729\u672E\u6730\u6732\u6733\u6736\u6737"+ - "\u6738\u6739\u673B\u673C\u673E\u673F\u6741\u6744"+ - "\u6745\u6747\u674A\u674B\u674D\u6752\u6754\u6755"+ - "\u6757\u6758\u6759\u675A\u675B\u675D\u6762\u6763"+ - "\u6764\u6766\u6767\u676B\u676C\u676E\u6771\u6774"+ - "\u6776\uFFFD\u6778\u6779\u677A\u677B\u677D\u6780"+ - "\u6782\u6783\u6785\u6786\u6788\u678A\u678C\u678D"+ - "\u678E\u678F\u6791\u6792\u6793\u6794\u6796\u6799"+ - "\u679B\u679F\u67A0\u67A1\u67A4\u67A6\u67A9\u67AC"+ - "\u67AE\u67B1\u67B2\u67B4\u67B9\u67BA\u67BB\u67BC"+ - "\u67BD\u67BE\u67BF\u67C0\u67C2\u67C5\u67C6\u67C7"+ - "\u67C8\u67C9\u67CA\u67CB\u67CC\u67CD\u67CE\u67D5"+ - "\u67D6\u67D7\u67DB\u67DF\u67E1\u67E3\u67E4\u67E6"+ - "\u67E7\u67E8\u67EA\u67EB\u67ED\u67EE\u67F2\u67F5"+ - "\u67F6\u67F7\u67F8\u67F9\u67FA\u67FB\u67FC\u67FE"+ - "\u6801\u6802\u6803\u6804\u6806\u680D\u6810\u6812"+ - "\u6814\u6815\u6818\u6819\u681A\u681B\u681C\u681E"+ - "\u681F\u6820\u6822\u6823\u6824\u6825\u6826\u6827"+ - "\u6828\u682B\u682C\u682D\u682E\u682F\u6830\u6831"+ - "\u6834\u6835\u6836\u683A\u683B\u683F\u6847\u684B"+ - "\u684D\u684F\u6852\u6856\u6857\u6858\u6859\u685A"+ - "\u685B\u685C\u685D\u685E\u685F\u686A\u686C\u686D"+ - "\u686E\u686F\u6870\u6871\u6872\u6873\u6875\u6878"+ - "\u6879\u687A\u687B\u687C\u687D\u687E\u687F\u6880"+ - "\u6882\u6884\u6887\u6888\u6889\u688A\u688B\u688C"+ - "\u688D\u688E\u6890\u6891\u6892\u6894\u6895\u6896"+ - "\u6898\u6899\u689A\u689B\u689C\u689D\u689E\u689F"+ - "\u68A0\u68A1\u68A3\u68A4\u68A5\u68A9\u68AA\u68AB"+ - "\u68AC\u68AE\u68B1\u68B2\u68B4\u68B6\u68B7\u68B8"+ - "\uFFFD\u68B9\u68BA\u68BB\u68BC\u68BD\u68BE\u68BF"+ - "\u68C1\u68C3\u68C4\u68C5\u68C6\u68C7\u68C8\u68CA"+ - "\u68CC\u68CE\u68CF\u68D0\u68D1\u68D3\u68D4\u68D6"+ - "\u68D7\u68D9\u68DB\u68DC\u68DD\u68DE\u68DF\u68E1"+ - "\u68E2\u68E4\u68E5\u68E6\u68E7\u68E8\u68E9\u68EA"+ - "\u68EB\u68EC\u68ED\u68EF\u68F2\u68F3\u68F4\u68F6"+ - "\u68F7\u68F8\u68FB\u68FD\u68FE\u68FF\u6900\u6902"+ - "\u6903\u6904\u6906\u6907\u6908\u6909\u690A\u690C"+ - "\u690F\u6911\u6913\u6914\u6915\u6916\u6917\u6918"+ - "\u6919\u691A\u691B\u691C\u691D\u691E\u6921\u6922"+ - "\u6923\u6925\u6926\u6927\u6928\u6929\u692A\u692B"+ - "\u692C\u692E\u692F\u6931\u6932\u6933\u6935\u6936"+ - "\u6937\u6938\u693A\u693B\u693C\u693E\u6940\u6941"+ - "\u6943\u6944\u6945\u6946\u6947\u6948\u6949\u694A"+ - "\u694B\u694C\u694D\u694E\u694F\u6950\u6951\u6952"+ - "\u6953\u6955\u6956\u6958\u6959\u695B\u695C\u695F"+ - "\u6961\u6962\u6964\u6965\u6967\u6968\u6969\u696A"+ - "\u696C\u696D\u696F\u6970\u6972\u6973\u6974\u6975"+ - "\u6976\u697A\u697B\u697D\u697E\u697F\u6981\u6983"+ - "\u6985\u698A\u698B\u698C\u698E\u698F\u6990\u6991"+ - "\u6992\u6993\u6996\u6997\u6999\u699A\u699D\u699E"+ - "\u699F\u69A0\u69A1\u69A2\u69A3\u69A4\u69A5\u69A6"+ - "\u69A9\u69AA\u69AC\u69AE\u69AF\u69B0\u69B2\u69B3"+ - "\u69B5\u69B6\u69B8\u69B9\u69BA\u69BC\u69BD\uFFFD"+ - "\u69BE\u69BF\u69C0\u69C2\u69C3\u69C4\u69C5\u69C6"+ - "\u69C7\u69C8\u69C9\u69CB\u69CD\u69CF\u69D1\u69D2"+ - "\u69D3\u69D5\u69D6\u69D7\u69D8\u69D9\u69DA\u69DC"+ - "\u69DD\u69DE\u69E1\u69E2\u69E3\u69E4\u69E5\u69E6"+ - "\u69E7\u69E8\u69E9\u69EA\u69EB\u69EC\u69EE\u69EF"+ - "\u69F0\u69F1\u69F3\u69F4\u69F5\u69F6\u69F7\u69F8"+ - "\u69F9\u69FA\u69FB\u69FC\u69FE\u6A00\u6A01\u6A02"+ - "\u6A03\u6A04\u6A05\u6A06\u6A07\u6A08\u6A09\u6A0B"+ - "\u6A0C\u6A0D\u6A0E\u6A0F\u6A10\u6A11\u6A12\u6A13"+ - "\u6A14\u6A15\u6A16\u6A19\u6A1A\u6A1B\u6A1C\u6A1D"+ - "\u6A1E\u6A20\u6A22\u6A23\u6A24\u6A25\u6A26\u6A27"+ - "\u6A29\u6A2B\u6A2C\u6A2D\u6A2E\u6A30\u6A32\u6A33"+ - "\u6A34\u6A36\u6A37\u6A38\u6A39\u6A3A\u6A3B\u6A3C"+ - "\u6A3F\u6A40\u6A41\u6A42\u6A43\u6A45\u6A46\u6A48"+ - "\u6A49\u6A4A\u6A4B\u6A4C\u6A4D\u6A4E\u6A4F\u6A51"+ - "\u6A52\u6A53\u6A54\u6A55\u6A56\u6A57\u6A5A\u6A5C"+ - "\u6A5D\u6A5E\u6A5F\u6A60\u6A62\u6A63\u6A64\u6A66"+ - "\u6A67\u6A68\u6A69\u6A6A\u6A6B\u6A6C\u6A6D\u6A6E"+ - "\u6A6F\u6A70\u6A72\u6A73\u6A74\u6A75\u6A76\u6A77"+ - "\u6A78\u6A7A\u6A7B\u6A7D\u6A7E\u6A7F\u6A81\u6A82"+ - "\u6A83\u6A85\u6A86\u6A87\u6A88\u6A89\u6A8A\u6A8B"+ - "\u6A8C\u6A8D\u6A8F\u6A92\u6A93\u6A94\u6A95\u6A96"+ - "\u6A98\u6A99\u6A9A\u6A9B\u6A9C\u6A9D\u6A9E\u6A9F"+ - "\u6AA1\u6AA2\u6AA3\u6AA4\u6AA5\u6AA6\uFFFD\u6AA7"+ - "\u6AA8\u6AAA\u6AAD\u6AAE\u6AAF\u6AB0\u6AB1\u6AB2"+ - "\u6AB3\u6AB4\u6AB5\u6AB6\u6AB7\u6AB8\u6AB9\u6ABA"+ - "\u6ABB\u6ABC\u6ABD\u6ABE\u6ABF\u6AC0\u6AC1\u6AC2"+ - "\u6AC3\u6AC4\u6AC5\u6AC6\u6AC7\u6AC8\u6AC9\u6ACA"+ - "\u6ACB\u6ACC\u6ACD\u6ACE\u6ACF\u6AD0\u6AD1\u6AD2"+ - "\u6AD3\u6AD4\u6AD5\u6AD6\u6AD7\u6AD8\u6AD9\u6ADA"+ - "\u6ADB\u6ADC\u6ADD\u6ADE\u6ADF\u6AE0\u6AE1\u6AE2"+ - "\u6AE3\u6AE4\u6AE5\u6AE6\u6AE7\u6AE8\u6AE9\u6AEA"+ - "\u6AEB\u6AEC\u6AED\u6AEE\u6AEF\u6AF0\u6AF1\u6AF2"+ - "\u6AF3\u6AF4\u6AF5\u6AF6\u6AF7\u6AF8\u6AF9\u6AFA"+ - "\u6AFB\u6AFC\u6AFD\u6AFE\u6AFF\u6B00\u6B01\u6B02"+ - "\u6B03\u6B04\u6B05\u6B06\u6B07\u6B08\u6B09\u6B0A"+ - "\u6B0B\u6B0C\u6B0D\u6B0E\u6B0F\u6B10\u6B11\u6B12"+ - "\u6B13\u6B14\u6B15\u6B16\u6B17\u6B18\u6B19\u6B1A"+ - "\u6B1B\u6B1C\u6B1D\u6B1E\u6B1F\u6B25\u6B26\u6B28"+ - "\u6B29\u6B2A\u6B2B\u6B2C\u6B2D\u6B2E\u6B2F\u6B30"+ - "\u6B31\u6B33\u6B34\u6B35\u6B36\u6B38\u6B3B\u6B3C"+ - "\u6B3D\u6B3F\u6B40\u6B41\u6B42\u6B44\u6B45\u6B48"+ - "\u6B4A\u6B4B\u6B4D\u6B4E\u6B4F\u6B50\u6B51\u6B52"+ - "\u6B53\u6B54\u6B55\u6B56\u6B57\u6B58\u6B5A\u6B5B"+ - "\u6B5C\u6B5D\u6B5E\u6B5F\u6B60\u6B61\u6B68\u6B69"+ - "\u6B6B\u6B6C\u6B6D\u6B6E\u6B6F\u6B70\u6B71\u6B72"+ - "\u6B73\u6B74\u6B75\u6B76\u6B77\u6B78\u6B7A\u6B7D"+ - "\u6B7E\u6B7F\u6B80\u6B85\u6B88\uFFFD\u6B8C\u6B8E"+ - "\u6B8F\u6B90\u6B91\u6B94\u6B95\u6B97\u6B98\u6B99"+ - "\u6B9C\u6B9D\u6B9E\u6B9F\u6BA0\u6BA2\u6BA3\u6BA4"+ - "\u6BA5\u6BA6\u6BA7\u6BA8\u6BA9\u6BAB\u6BAC\u6BAD"+ - "\u6BAE\u6BAF\u6BB0\u6BB1\u6BB2\u6BB6\u6BB8\u6BB9"+ - "\u6BBA\u6BBB\u6BBC\u6BBD\u6BBE\u6BC0\u6BC3\u6BC4"+ - "\u6BC6\u6BC7\u6BC8\u6BC9\u6BCA\u6BCC\u6BCE\u6BD0"+ - "\u6BD1\u6BD8\u6BDA\u6BDC\u6BDD\u6BDE\u6BDF\u6BE0"+ - "\u6BE2\u6BE3\u6BE4\u6BE5\u6BE6\u6BE7\u6BE8\u6BE9"+ - "\u6BEC\u6BED\u6BEE\u6BF0\u6BF1\u6BF2\u6BF4\u6BF6"+ - "\u6BF7\u6BF8\u6BFA\u6BFB\u6BFC\u6BFE\u6BFF\u6C00"+ - "\u6C01\u6C02\u6C03\u6C04\u6C08\u6C09\u6C0A\u6C0B"+ - "\u6C0C\u6C0E\u6C12\u6C17\u6C1C\u6C1D\u6C1E\u6C20"+ - "\u6C23\u6C25\u6C2B\u6C2C\u6C2D\u6C31\u6C33\u6C36"+ - "\u6C37\u6C39\u6C3A\u6C3B\u6C3C\u6C3E\u6C3F\u6C43"+ - "\u6C44\u6C45\u6C48\u6C4B\u6C4C\u6C4D\u6C4E\u6C4F"+ - "\u6C51\u6C52\u6C53\u6C56\u6C58\u6C59\u6C5A\u6C62"+ - "\u6C63\u6C65\u6C66\u6C67\u6C6B\u6C6C\u6C6D\u6C6E"+ - "\u6C6F\u6C71\u6C73\u6C75\u6C77\u6C78\u6C7A\u6C7B"+ - "\u6C7C\u6C7F\u6C80\u6C84\u6C87\u6C8A\u6C8B\u6C8D"+ - "\u6C8E\u6C91\u6C92\u6C95\u6C96\u6C97\u6C98\u6C9A"+ - "\u6C9C\u6C9D\u6C9E\u6CA0\u6CA2\u6CA8\u6CAC\u6CAF"+ - "\u6CB0\u6CB4\u6CB5\u6CB6\u6CB7\u6CBA\u6CC0\u6CC1"+ - "\u6CC2\u6CC3\u6CC6\u6CC7\u6CC8\u6CCB\u6CCD\u6CCE"+ - "\u6CCF\u6CD1\u6CD2\u6CD8\uFFFD\u6CD9\u6CDA\u6CDC"+ - "\u6CDD\u6CDF\u6CE4\u6CE6\u6CE7\u6CE9\u6CEC\u6CED"+ - "\u6CF2\u6CF4\u6CF9\u6CFF\u6D00\u6D02\u6D03\u6D05"+ - "\u6D06\u6D08\u6D09\u6D0A\u6D0D\u6D0F\u6D10\u6D11"+ - "\u6D13\u6D14\u6D15\u6D16\u6D18\u6D1C\u6D1D\u6D1F"+ - "\u6D20\u6D21\u6D22\u6D23\u6D24\u6D26\u6D28\u6D29"+ - "\u6D2C\u6D2D\u6D2F\u6D30\u6D34\u6D36\u6D37\u6D38"+ - "\u6D3A\u6D3F\u6D40\u6D42\u6D44\u6D49\u6D4C\u6D50"+ - "\u6D55\u6D56\u6D57\u6D58\u6D5B\u6D5D\u6D5F\u6D61"+ - "\u6D62\u6D64\u6D65\u6D67\u6D68\u6D6B\u6D6C\u6D6D"+ - "\u6D70\u6D71\u6D72\u6D73\u6D75\u6D76\u6D79\u6D7A"+ - "\u6D7B\u6D7D\u6D7E\u6D7F\u6D80\u6D81\u6D83\u6D84"+ - "\u6D86\u6D87\u6D8A\u6D8B\u6D8D\u6D8F\u6D90\u6D92"+ - "\u6D96\u6D97\u6D98\u6D99\u6D9A\u6D9C\u6DA2\u6DA5"+ - "\u6DAC\u6DAD\u6DB0\u6DB1\u6DB3\u6DB4\u6DB6\u6DB7"+ - "\u6DB9\u6DBA\u6DBB\u6DBC\u6DBD\u6DBE\u6DC1\u6DC2"+ - "\u6DC3\u6DC8\u6DC9\u6DCA\u6DCD\u6DCE\u6DCF\u6DD0"+ - "\u6DD2\u6DD3\u6DD4\u6DD5\u6DD7\u6DDA\u6DDB\u6DDC"+ - "\u6DDF\u6DE2\u6DE3\u6DE5\u6DE7\u6DE8\u6DE9\u6DEA"+ - "\u6DED\u6DEF\u6DF0\u6DF2\u6DF4\u6DF5\u6DF6\u6DF8"+ - "\u6DFA\u6DFD\u6DFE\u6DFF\u6E00\u6E01\u6E02\u6E03"+ - "\u6E04\u6E06\u6E07\u6E08\u6E09\u6E0B\u6E0F\u6E12"+ - "\u6E13\u6E15\u6E18\u6E19\u6E1B\u6E1C\u6E1E\u6E1F"+ - "\u6E22\u6E26\u6E27\u6E28\u6E2A\u6E2C\u6E2E\u6E30"+ - "\u6E31\u6E33\u6E35\uFFFD\u6E36\u6E37\u6E39\u6E3B"+ - "\u6E3C\u6E3D\u6E3E\u6E3F\u6E40\u6E41\u6E42\u6E45"+ - "\u6E46\u6E47\u6E48\u6E49\u6E4A\u6E4B\u6E4C\u6E4F"+ - "\u6E50\u6E51\u6E52\u6E55\u6E57\u6E59\u6E5A\u6E5C"+ - "\u6E5D\u6E5E\u6E60\u6E61\u6E62\u6E63\u6E64\u6E65"+ - "\u6E66\u6E67\u6E68\u6E69\u6E6A\u6E6C\u6E6D\u6E6F"+ - "\u6E70\u6E71\u6E72\u6E73\u6E74\u6E75\u6E76\u6E77"+ - "\u6E78\u6E79\u6E7A\u6E7B\u6E7C\u6E7D\u6E80\u6E81"+ - "\u6E82\u6E84\u6E87\u6E88\u6E8A\u6E8B\u6E8C\u6E8D"+ - "\u6E8E\u6E91\u6E92\u6E93\u6E94\u6E95\u6E96\u6E97"+ - "\u6E99\u6E9A\u6E9B\u6E9D\u6E9E\u6EA0\u6EA1\u6EA3"+ - "\u6EA4\u6EA6\u6EA8\u6EA9\u6EAB\u6EAC\u6EAD\u6EAE"+ - "\u6EB0\u6EB3\u6EB5\u6EB8\u6EB9\u6EBC\u6EBE\u6EBF"+ - "\u6EC0\u6EC3\u6EC4\u6EC5\u6EC6\u6EC8\u6EC9\u6ECA"+ - "\u6ECC\u6ECD\u6ECE\u6ED0\u6ED2\u6ED6\u6ED8\u6ED9"+ - "\u6EDB\u6EDC\u6EDD\u6EE3\u6EE7\u6EEA\u6EEB\u6EEC"+ - "\u6EED\u6EEE\u6EEF\u6EF0\u6EF1\u6EF2\u6EF3\u6EF5"+ - "\u6EF6\u6EF7\u6EF8\u6EFA\u6EFB\u6EFC\u6EFD\u6EFE"+ - "\u6EFF\u6F00\u6F01\u6F03\u6F04\u6F05\u6F07\u6F08"+ - "\u6F0A\u6F0B\u6F0C\u6F0D\u6F0E\u6F10\u6F11\u6F12"+ - "\u6F16\u6F17\u6F18\u6F19\u6F1A\u6F1B\u6F1C\u6F1D"+ - "\u6F1E\u6F1F\u6F21\u6F22\u6F23\u6F25\u6F26\u6F27"+ - "\u6F28\u6F2C\u6F2E\u6F30\u6F32\u6F34\u6F35\u6F37"+ - "\u6F38\u6F39\u6F3A\u6F3B\u6F3C\u6F3D\u6F3F\u6F40"+ - "\u6F41\u6F42\uFFFD\u6F43\u6F44\u6F45\u6F48\u6F49"+ - "\u6F4A\u6F4C\u6F4E\u6F4F\u6F50\u6F51\u6F52\u6F53"+ - "\u6F54\u6F55\u6F56\u6F57\u6F59\u6F5A\u6F5B\u6F5D"+ - "\u6F5F\u6F60\u6F61\u6F63\u6F64\u6F65\u6F67\u6F68"+ - "\u6F69\u6F6A\u6F6B\u6F6C\u6F6F\u6F70\u6F71\u6F73"+ - "\u6F75\u6F76\u6F77\u6F79\u6F7B\u6F7D\u6F7E\u6F7F"+ - "\u6F80\u6F81\u6F82\u6F83\u6F85\u6F86\u6F87\u6F8A"+ - "\u6F8B\u6F8F\u6F90\u6F91\u6F92\u6F93\u6F94\u6F95"+ - "\u6F96\u6F97\u6F98\u6F99\u6F9A\u6F9B\u6F9D\u6F9E"+ - "\u6F9F\u6FA0\u6FA2\u6FA3\u6FA4\u6FA5\u6FA6\u6FA8"+ - "\u6FA9\u6FAA\u6FAB\u6FAC\u6FAD\u6FAE\u6FAF\u6FB0"+ - "\u6FB1\u6FB2\u6FB4\u6FB5\u6FB7\u6FB8\u6FBA\u6FBB"+ - "\u6FBC\u6FBD\u6FBE\u6FBF\u6FC1\u6FC3\u6FC4\u6FC5"+ - "\u6FC6\u6FC7\u6FC8\u6FCA\u6FCB\u6FCC\u6FCD\u6FCE"+ - "\u6FCF\u6FD0\u6FD3\u6FD4\u6FD5\u6FD6\u6FD7\u6FD8"+ - "\u6FD9\u6FDA\u6FDB\u6FDC\u6FDD\u6FDF\u6FE2\u6FE3"+ - "\u6FE4\u6FE5\u6FE6\u6FE7\u6FE8\u6FE9\u6FEA\u6FEB"+ - "\u6FEC\u6FED\u6FF0\u6FF1\u6FF2\u6FF3\u6FF4\u6FF5"+ - "\u6FF6\u6FF7\u6FF8\u6FF9\u6FFA\u6FFB\u6FFC\u6FFD"+ - "\u6FFE\u6FFF\u7000\u7001\u7002\u7003\u7004\u7005"+ - "\u7006\u7007\u7008\u7009\u700A\u700B\u700C\u700D"+ - "\u700E\u700F\u7010\u7012\u7013\u7014\u7015\u7016"+ - "\u7017\u7018\u7019\u701C\u701D\u701E\u701F\u7020"+ - "\u7021\u7022\u7024\u7025\u7026\u7027\u7028\u7029"+ - "\u702A\uFFFD\u702B\u702C\u702D\u702E\u702F\u7030"+ - "\u7031\u7032\u7033\u7034\u7036\u7037\u7038\u703A"+ - "\u703B\u703C\u703D\u703E\u703F\u7040\u7041\u7042"+ - "\u7043\u7044\u7045\u7046\u7047\u7048\u7049\u704A"+ - "\u704B\u704D\u704E\u7050\u7051\u7052\u7053\u7054"+ - "\u7055\u7056\u7057\u7058\u7059\u705A\u705B\u705C"+ - "\u705D\u705F\u7060\u7061\u7062\u7063\u7064\u7065"+ - "\u7066\u7067\u7068\u7069\u706A\u706E\u7071\u7072"+ - "\u7073\u7074\u7077\u7079\u707A\u707B\u707D\u7081"+ - "\u7082\u7083\u7084\u7086\u7087\u7088\u708B\u708C"+ - "\u708D\u708F\u7090\u7091\u7093\u7097\u7098\u709A"+ - "\u709B\u709E\u709F\u70A0\u70A1\u70A2\u70A3\u70A4"+ - "\u70A5\u70A6\u70A7\u70A8\u70A9\u70AA\u70B0\u70B2"+ - "\u70B4\u70B5\u70B6\u70BA\u70BE\u70BF\u70C4\u70C5"+ - "\u70C6\u70C7\u70C9\u70CB\u70CC\u70CD\u70CE\u70CF"+ - "\u70D0\u70D1\u70D2\u70D3\u70D4\u70D5\u70D6\u70D7"+ - "\u70DA\u70DC\u70DD\u70DE\u70E0\u70E1\u70E2\u70E3"+ - "\u70E5\u70EA\u70EE\u70F0\u70F1\u70F2\u70F3\u70F4"+ - "\u70F5\u70F6\u70F8\u70FA\u70FB\u70FC\u70FE\u70FF"+ - "\u7100\u7101\u7102\u7103\u7104\u7105\u7106\u7107"+ - "\u7108\u710B\u710C\u710D\u710E\u710F\u7111\u7112"+ - "\u7114\u7117\u711B\u711C\u711D\u711E\u711F\u7120"+ - "\u7121\u7122\u7123\u7124\u7125\u7127\u7128\u7129"+ - "\u712A\u712B\u712C\u712D\u712E\u7132\u7133\u7134"+ - "\uFFFD\u7135\u7137\u7138\u7139\u713A\u713B\u713C"+ - "\u713D\u713E\u713F\u7140\u7141\u7142\u7143\u7144"+ - "\u7146\u7147\u7148\u7149\u714B\u714D\u714F\u7150"+ - "\u7151\u7152\u7153\u7154\u7155\u7156\u7157\u7158"+ - "\u7159\u715A\u715B\u715D\u715F\u7160\u7161\u7162"+ - "\u7163\u7165\u7169\u716A\u716B\u716C\u716D\u716F"+ - "\u7170\u7171\u7174\u7175\u7176\u7177\u7179\u717B"+ - "\u717C\u717E\u717F\u7180\u7181\u7182\u7183\u7185"+ - "\u7186\u7187\u7188\u7189\u718B\u718C\u718D\u718E"+ - "\u7190\u7191\u7192\u7193\u7195\u7196\u7197\u719A"+ - "\u719B\u719C\u719D\u719E\u71A1\u71A2\u71A3\u71A4"+ - "\u71A5\u71A6\u71A7\u71A9\u71AA\u71AB\u71AD\u71AE"+ - "\u71AF\u71B0\u71B1\u71B2\u71B4\u71B6\u71B7\u71B8"+ - "\u71BA\u71BB\u71BC\u71BD\u71BE\u71BF\u71C0\u71C1"+ - "\u71C2\u71C4\u71C5\u71C6\u71C7\u71C8\u71C9\u71CA"+ - "\u71CB\u71CC\u71CD\u71CF\u71D0\u71D1\u71D2\u71D3"; - - private static final String innerIndex2= - "\u71D6\u71D7\u71D8\u71D9\u71DA\u71DB\u71DC\u71DD"+ - "\u71DE\u71DF\u71E1\u71E2\u71E3\u71E4\u71E6\u71E8"+ - "\u71E9\u71EA\u71EB\u71EC\u71ED\u71EF\u71F0\u71F1"+ - "\u71F2\u71F3\u71F4\u71F5\u71F6\u71F7\u71F8\u71FA"+ - "\u71FB\u71FC\u71FD\u71FE\u71FF\u7200\u7201\u7202"+ - "\u7203\u7204\u7205\u7207\u7208\u7209\u720A\u720B"+ - "\u720C\u720D\u720E\u720F\u7210\u7211\u7212\u7213"+ - "\u7214\u7215\u7216\u7217\u7218\u7219\u721A\uFFFD"+ - "\u721B\u721C\u721E\u721F\u7220\u7221\u7222\u7223"+ - "\u7224\u7225\u7226\u7227\u7229\u722B\u722D\u722E"+ - "\u722F\u7232\u7233\u7234\u723A\u723C\u723E\u7240"+ - "\u7241\u7242\u7243\u7244\u7245\u7246\u7249\u724A"+ - "\u724B\u724E\u724F\u7250\u7251\u7253\u7254\u7255"+ - "\u7257\u7258\u725A\u725C\u725E\u7260\u7263\u7264"+ - "\u7265\u7268\u726A\u726B\u726C\u726D\u7270\u7271"+ - "\u7273\u7274\u7276\u7277\u7278\u727B\u727C\u727D"+ - "\u7282\u7283\u7285\u7286\u7287\u7288\u7289\u728C"+ - "\u728E\u7290\u7291\u7293\u7294\u7295\u7296\u7297"+ - "\u7298\u7299\u729A\u729B\u729C\u729D\u729E\u72A0"+ - "\u72A1\u72A2\u72A3\u72A4\u72A5\u72A6\u72A7\u72A8"+ - "\u72A9\u72AA\u72AB\u72AE\u72B1\u72B2\u72B3\u72B5"+ - "\u72BA\u72BB\u72BC\u72BD\u72BE\u72BF\u72C0\u72C5"+ - "\u72C6\u72C7\u72C9\u72CA\u72CB\u72CC\u72CF\u72D1"+ - "\u72D3\u72D4\u72D5\u72D6\u72D8\u72DA\u72DB\uE4C6"+ - "\uE4C7\uE4C8\uE4C9\uE4CA\uE4CB\uE4CC\uE4CD\uE4CE"+ - "\uE4CF\uE4D0\uE4D1\uE4D2\uE4D3\uE4D4\uE4D5\uE4D6"+ - "\uE4D7\uE4D8\uE4D9\uE4DA\uE4DB\uE4DC\uE4DD\uE4DE"+ - "\uE4DF\uE4E0\uE4E1\uE4E2\uE4E3\uE4E4\uE4E5\uE4E6"+ - "\uE4E7\uE4E8\uE4E9\uE4EA\uE4EB\uE4EC\uE4ED\uE4EE"+ - "\uE4EF\uE4F0\uE4F1\uE4F2\uE4F3\uE4F4\uE4F5\uE4F6"+ - "\uE4F7\uE4F8\uE4F9\uE4FA\uE4FB\uE4FC\uE4FD\uE4FE"+ - "\uE4FF\uE500\uE501\uE502\uE503\uE504\uFFFD\uE505"+ - "\uE506\uE507\uE508\uE509\uE50A\uE50B\uE50C\uE50D"+ - "\uE50E\uE50F\uE510\uE511\uE512\uE513\uE514\uE515"+ - "\uE516\uE517\uE518\uE519\uE51A\uE51B\uE51C\uE51D"+ - "\uE51E\uE51F\uE520\uE521\uE522\uE523\uE524\uE525"+ - "\u3000\u3001\u3002\u00B7\u02C9\u02C7\u00A8\u3003"+ - "\u3005\u2014\uFF5E\u2016\u2026\u2018\u2019\u201C"+ - "\u201D\u3014\u3015\u3008\u3009\u300A\u300B\u300C"+ - "\u300D\u300E\u300F\u3016\u3017\u3010\u3011\u00B1"+ - "\u00D7\u00F7\u2236\u2227\u2228\u2211\u220F\u222A"+ - "\u2229\u2208\u2237\u221A\u22A5\u2225\u2220\u2312"+ - "\u2299\u222B\u222E\u2261\u224C\u2248\u223D\u221D"+ - "\u2260\u226E\u226F\u2264\u2265\u221E\u2235\u2234"+ - "\u2642\u2640\u00B0\u2032\u2033\u2103\uFF04\u00A4"+ - "\uFFE0\uFFE1\u2030\u00A7\u2116\u2606\u2605\u25CB"+ - "\u25CF\u25CE\u25C7\u25C6\u25A1\u25A0\u25B3\u25B2"+ - "\u203B\u2192\u2190\u2191\u2193\u3013\uE526\uE527"+ - "\uE528\uE529\uE52A\uE52B\uE52C\uE52D\uE52E\uE52F"+ - "\uE530\uE531\uE532\uE533\uE534\uE535\uE536\uE537"+ - "\uE538\uE539\uE53A\uE53B\uE53C\uE53D\uE53E\uE53F"+ - "\uE540\uE541\uE542\uE543\uE544\uE545\uE546\uE547"+ - "\uE548\uE549\uE54A\uE54B\uE54C\uE54D\uE54E\uE54F"+ - "\uE550\uE551\uE552\uE553\uE554\uE555\uE556\uE557"+ - "\uE558\uE559\uE55A\uE55B\uE55C\uE55D\uE55E\uE55F"+ - "\uE560\uE561\uE562\uE563\uE564\uFFFD\uE565\uE566"+ - "\uE567\uE568\uE569\uE56A\uE56B\uE56C\uE56D\uE56E"+ - "\uE56F\uE570\uE571\uE572\uE573\uE574\uE575\uE576"+ - "\uE577\uE578\uE579\uE57A\uE57B\uE57C\uE57D\uE57E"+ - "\uE57F\uE580\uE581\uE582\uE583\uE584\uE585\u2170"+ - "\u2171\u2172\u2173\u2174\u2175\u2176\u2177\u2178"+ - "\u2179\uE766\uE767\uE768\uE769\uE76A\uE76B\u2488"+ - "\u2489\u248A\u248B\u248C\u248D\u248E\u248F\u2490"+ - "\u2491\u2492\u2493\u2494\u2495\u2496\u2497\u2498"+ - "\u2499\u249A\u249B\u2474\u2475\u2476\u2477\u2478"+ - "\u2479\u247A\u247B\u247C\u247D\u247E\u247F\u2480"+ - "\u2481\u2482\u2483\u2484\u2485\u2486\u2487\u2460"+ - "\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468"+ - "\u2469\u20AC\uE76D\u3220\u3221\u3222\u3223\u3224"+ - "\u3225\u3226\u3227\u3228\u3229\uE76E\uE76F\u2160"+ - "\u2161\u2162\u2163\u2164\u2165\u2166\u2167\u2168"+ - "\u2169\u216A\u216B\uE770\uE771\uE586\uE587\uE588"+ - "\uE589\uE58A\uE58B\uE58C\uE58D\uE58E\uE58F\uE590"+ - "\uE591\uE592\uE593\uE594\uE595\uE596\uE597\uE598"+ - "\uE599\uE59A\uE59B\uE59C\uE59D\uE59E\uE59F\uE5A0"+ - "\uE5A1\uE5A2\uE5A3\uE5A4\uE5A5\uE5A6\uE5A7\uE5A8"+ - "\uE5A9\uE5AA\uE5AB\uE5AC\uE5AD\uE5AE\uE5AF\uE5B0"+ - "\uE5B1\uE5B2\uE5B3\uE5B4\uE5B5\uE5B6\uE5B7\uE5B8"+ - "\uE5B9\uE5BA\uE5BB\uE5BC\uE5BD\uE5BE\uE5BF\uE5C0"+ - "\uE5C1\uE5C2\uE5C3\uE5C4\uFFFD\uE5C5\uE5C6\uE5C7"+ - "\uE5C8\uE5C9\uE5CA\uE5CB\uE5CC\uE5CD\uE5CE\uE5CF"+ - "\uE5D0\uE5D1\uE5D2\uE5D3\uE5D4\uE5D5\uE5D6\uE5D7"+ - "\uE5D8\uE5D9\uE5DA\uE5DB\uE5DC\uE5DD\uE5DE\uE5DF"+ - "\uE5E0\uE5E1\uE5E2\uE5E3\uE5E4\uE5E5\uFF01\uFF02"+ - "\uFF03\uFFE5\uFF05\uFF06\uFF07\uFF08\uFF09\uFF0A"+ - "\uFF0B\uFF0C\uFF0D\uFF0E\uFF0F\uFF10\uFF11\uFF12"+ - "\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF1A"+ - "\uFF1B\uFF1C\uFF1D\uFF1E\uFF1F\uFF20\uFF21\uFF22"+ - "\uFF23\uFF24\uFF25\uFF26\uFF27\uFF28\uFF29\uFF2A"+ - "\uFF2B\uFF2C\uFF2D\uFF2E\uFF2F\uFF30\uFF31\uFF32"+ - "\uFF33\uFF34\uFF35\uFF36\uFF37\uFF38\uFF39\uFF3A"+ - "\uFF3B\uFF3C\uFF3D\uFF3E\uFF3F\uFF40\uFF41\uFF42"+ - "\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48\uFF49\uFF4A"+ - "\uFF4B\uFF4C\uFF4D\uFF4E\uFF4F\uFF50\uFF51\uFF52"+ - "\uFF53\uFF54\uFF55\uFF56\uFF57\uFF58\uFF59\uFF5A"+ - "\uFF5B\uFF5C\uFF5D\uFFE3\uE5E6\uE5E7\uE5E8\uE5E9"+ - "\uE5EA\uE5EB\uE5EC\uE5ED\uE5EE\uE5EF\uE5F0\uE5F1"+ - "\uE5F2\uE5F3\uE5F4\uE5F5\uE5F6\uE5F7\uE5F8\uE5F9"+ - "\uE5FA\uE5FB\uE5FC\uE5FD\uE5FE\uE5FF\uE600\uE601"+ - "\uE602\uE603\uE604\uE605\uE606\uE607\uE608\uE609"+ - "\uE60A\uE60B\uE60C\uE60D\uE60E\uE60F\uE610\uE611"+ - "\uE612\uE613\uE614\uE615\uE616\uE617\uE618\uE619"+ - "\uE61A\uE61B\uE61C\uE61D\uE61E\uE61F\uE620\uE621"+ - "\uE622\uE623\uE624\uFFFD\uE625\uE626\uE627\uE628"+ - "\uE629\uE62A\uE62B\uE62C\uE62D\uE62E\uE62F\uE630"+ - "\uE631\uE632\uE633\uE634\uE635\uE636\uE637\uE638"+ - "\uE639\uE63A\uE63B\uE63C\uE63D\uE63E\uE63F\uE640"+ - "\uE641\uE642\uE643\uE644\uE645\u3041\u3042\u3043"+ - "\u3044\u3045\u3046\u3047\u3048\u3049\u304A\u304B"+ - "\u304C\u304D\u304E\u304F\u3050\u3051\u3052\u3053"+ - "\u3054\u3055\u3056\u3057\u3058\u3059\u305A\u305B"+ - "\u305C\u305D\u305E\u305F\u3060\u3061\u3062\u3063"+ - "\u3064\u3065\u3066\u3067\u3068\u3069\u306A\u306B"+ - "\u306C\u306D\u306E\u306F\u3070\u3071\u3072\u3073"+ - "\u3074\u3075\u3076\u3077\u3078\u3079\u307A\u307B"+ - "\u307C\u307D\u307E\u307F\u3080\u3081\u3082\u3083"+ - "\u3084\u3085\u3086\u3087\u3088\u3089\u308A\u308B"+ - "\u308C\u308D\u308E\u308F\u3090\u3091\u3092\u3093"+ - "\uE772\uE773\uE774\uE775\uE776\uE777\uE778\uE779"+ - "\uE77A\uE77B\uE77C\uE646\uE647\uE648\uE649\uE64A"+ - "\uE64B\uE64C\uE64D\uE64E\uE64F\uE650\uE651\uE652"+ - "\uE653\uE654\uE655\uE656\uE657\uE658\uE659\uE65A"+ - "\uE65B\uE65C\uE65D\uE65E\uE65F\uE660\uE661\uE662"+ - "\uE663\uE664\uE665\uE666\uE667\uE668\uE669\uE66A"+ - "\uE66B\uE66C\uE66D\uE66E\uE66F\uE670\uE671\uE672"+ - "\uE673\uE674\uE675\uE676\uE677\uE678\uE679\uE67A"+ - "\uE67B\uE67C\uE67D\uE67E\uE67F\uE680\uE681\uE682"+ - "\uE683\uE684\uFFFD\uE685\uE686\uE687\uE688\uE689"+ - "\uE68A\uE68B\uE68C\uE68D\uE68E\uE68F\uE690\uE691"+ - "\uE692\uE693\uE694\uE695\uE696\uE697\uE698\uE699"+ - "\uE69A\uE69B\uE69C\uE69D\uE69E\uE69F\uE6A0\uE6A1"+ - "\uE6A2\uE6A3\uE6A4\uE6A5\u30A1\u30A2\u30A3\u30A4"+ - "\u30A5\u30A6\u30A7\u30A8\u30A9\u30AA\u30AB\u30AC"+ - "\u30AD\u30AE\u30AF\u30B0\u30B1\u30B2\u30B3\u30B4"+ - "\u30B5\u30B6\u30B7\u30B8\u30B9\u30BA\u30BB\u30BC"+ - "\u30BD\u30BE\u30BF\u30C0\u30C1\u30C2\u30C3\u30C4"+ - "\u30C5\u30C6\u30C7\u30C8\u30C9\u30CA\u30CB\u30CC"+ - "\u30CD\u30CE\u30CF\u30D0\u30D1\u30D2\u30D3\u30D4"+ - "\u30D5\u30D6\u30D7\u30D8\u30D9\u30DA\u30DB\u30DC"+ - "\u30DD\u30DE\u30DF\u30E0\u30E1\u30E2\u30E3\u30E4"+ - "\u30E5\u30E6\u30E7\u30E8\u30E9\u30EA\u30EB\u30EC"+ - "\u30ED\u30EE\u30EF\u30F0\u30F1\u30F2\u30F3\u30F4"+ - "\u30F5\u30F6\uE77D\uE77E\uE77F\uE780\uE781\uE782"+ - "\uE783\uE784\uE6A6\uE6A7\uE6A8\uE6A9\uE6AA\uE6AB"+ - "\uE6AC\uE6AD\uE6AE\uE6AF\uE6B0\uE6B1\uE6B2\uE6B3"+ - "\uE6B4\uE6B5\uE6B6\uE6B7\uE6B8\uE6B9\uE6BA\uE6BB"+ - "\uE6BC\uE6BD\uE6BE\uE6BF\uE6C0\uE6C1\uE6C2\uE6C3"+ - "\uE6C4\uE6C5\uE6C6\uE6C7\uE6C8\uE6C9\uE6CA\uE6CB"+ - "\uE6CC\uE6CD\uE6CE\uE6CF\uE6D0\uE6D1\uE6D2\uE6D3"+ - "\uE6D4\uE6D5\uE6D6\uE6D7\uE6D8\uE6D9\uE6DA\uE6DB"+ - "\uE6DC\uE6DD\uE6DE\uE6DF\uE6E0\uE6E1\uE6E2\uE6E3"+ - "\uE6E4\uFFFD\uE6E5\uE6E6\uE6E7\uE6E8\uE6E9\uE6EA"+ - "\uE6EB\uE6EC\uE6ED\uE6EE\uE6EF\uE6F0\uE6F1\uE6F2"+ - "\uE6F3\uE6F4\uE6F5\uE6F6\uE6F7\uE6F8\uE6F9\uE6FA"+ - "\uE6FB\uE6FC\uE6FD\uE6FE\uE6FF\uE700\uE701\uE702"+ - "\uE703\uE704\uE705\u0391\u0392\u0393\u0394\u0395"+ - "\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D"+ - "\u039E\u039F\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6"+ - "\u03A7\u03A8\u03A9\uE785\uE786\uE787\uE788\uE789"+ - "\uE78A\uE78B\uE78C\u03B1\u03B2\u03B3\u03B4\u03B5"+ - "\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD"+ - "\u03BE\u03BF\u03C0\u03C1\u03C3\u03C4\u03C5\u03C6"+ - "\u03C7\u03C8\u03C9\uE78D\uE78E\uE78F\uE790\uE791"+ - "\uE792\uE793\uFE35\uFE36\uFE39\uFE3A\uFE3F\uFE40"+ - "\uFE3D\uFE3E\uFE41\uFE42\uFE43\uFE44\uE794\uE795"+ - "\uFE3B\uFE3C\uFE37\uFE38\uFE31\uE796\uFE33\uFE34"+ - "\uE797\uE798\uE799\uE79A\uE79B\uE79C\uE79D\uE79E"+ - "\uE79F\uE706\uE707\uE708\uE709\uE70A\uE70B\uE70C"+ - "\uE70D\uE70E\uE70F\uE710\uE711\uE712\uE713\uE714"+ - "\uE715\uE716\uE717\uE718\uE719\uE71A\uE71B\uE71C"+ - "\uE71D\uE71E\uE71F\uE720\uE721\uE722\uE723\uE724"+ - "\uE725\uE726\uE727\uE728\uE729\uE72A\uE72B\uE72C"+ - "\uE72D\uE72E\uE72F\uE730\uE731\uE732\uE733\uE734"+ - "\uE735\uE736\uE737\uE738\uE739\uE73A\uE73B\uE73C"+ - "\uE73D\uE73E\uE73F\uE740\uE741\uE742\uE743\uE744"+ - "\uFFFD\uE745\uE746\uE747\uE748\uE749\uE74A\uE74B"+ - "\uE74C\uE74D\uE74E\uE74F\uE750\uE751\uE752\uE753"+ - "\uE754\uE755\uE756\uE757\uE758\uE759\uE75A\uE75B"+ - "\uE75C\uE75D\uE75E\uE75F\uE760\uE761\uE762\uE763"+ - "\uE764\uE765\u0410\u0411\u0412\u0413\u0414\u0415"+ - "\u0401\u0416\u0417\u0418\u0419\u041A\u041B\u041C"+ - "\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424"+ - "\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C"+ - "\u042D\u042E\u042F\uE7A0\uE7A1\uE7A2\uE7A3\uE7A4"+ - "\uE7A5\uE7A6\uE7A7\uE7A8\uE7A9\uE7AA\uE7AB\uE7AC"+ - "\uE7AD\uE7AE\u0430\u0431\u0432\u0433\u0434\u0435"+ - "\u0451\u0436\u0437\u0438\u0439\u043A\u043B\u043C"+ - "\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444"+ - "\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C"+ - "\u044D\u044E\u044F\uE7AF\uE7B0\uE7B1\uE7B2\uE7B3"+ - "\uE7B4\uE7B5\uE7B6\uE7B7\uE7B8\uE7B9\uE7BA\uE7BB"+ - "\u02CA\u02CB\u02D9\u2013\u2015\u2025\u2035\u2105"+ - "\u2109\u2196\u2197\u2198\u2199\u2215\u221F\u2223"+ - "\u2252\u2266\u2267\u22BF\u2550\u2551\u2552\u2553"+ - "\u2554\u2555\u2556\u2557\u2558\u2559\u255A\u255B"+ - "\u255C\u255D\u255E\u255F\u2560\u2561\u2562\u2563"+ - "\u2564\u2565\u2566\u2567\u2568\u2569\u256A\u256B"+ - "\u256C\u256D\u256E\u256F\u2570\u2571\u2572\u2573"+ - "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\uFFFD"+ - "\u2588\u2589\u258A\u258B\u258C\u258D\u258E\u258F"+ - "\u2593\u2594\u2595\u25BC\u25BD\u25E2\u25E3\u25E4"+ - "\u25E5\u2609\u2295\u3012\u301D\u301E\uE7BC\uE7BD"+ - "\uE7BE\uE7BF\uE7C0\uE7C1\uE7C2\uE7C3\uE7C4\uE7C5"+ - "\uE7C6\u0101\u00E1\u01CE\u00E0\u0113\u00E9\u011B"+ - "\u00E8\u012B\u00ED\u01D0\u00EC\u014D\u00F3\u01D2"+ - "\u00F2\u016B\u00FA\u01D4\u00F9\u01D6\u01D8\u01DA"+ - "\u01DC\u00FC\u00EA\u0251\uE7C7\u0144\u0148\u01F9"+ - "\u0261\uE7C9\uE7CA\uE7CB\uE7CC\u3105\u3106\u3107"+ - "\u3108\u3109\u310A\u310B\u310C\u310D\u310E\u310F"+ - "\u3110\u3111\u3112\u3113\u3114\u3115\u3116\u3117"+ - "\u3118\u3119\u311A\u311B\u311C\u311D\u311E\u311F"+ - "\u3120\u3121\u3122\u3123\u3124\u3125\u3126\u3127"+ - "\u3128\u3129\uE7CD\uE7CE\uE7CF\uE7D0\uE7D1\uE7D2"+ - "\uE7D3\uE7D4\uE7D5\uE7D6\uE7D7\uE7D8\uE7D9\uE7DA"+ - "\uE7DB\uE7DC\uE7DD\uE7DE\uE7DF\uE7E0\uE7E1\u3021"+ - "\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029"+ - "\u32A3\u338E\u338F\u339C\u339D\u339E\u33A1\u33C4"+ - "\u33CE\u33D1\u33D2\u33D5\uFE30\uFFE2\uFFE4\uE7E2"+ - "\u2121\u3231\uE7E3\u2010\uE7E4\uE7E5\uE7E6\u30FC"+ - "\u309B\u309C\u30FD\u30FE\u3006\u309D\u309E\uFE49"+ - "\uFE4A\uFE4B\uFE4C\uFE4D\uFE4E\uFE4F\uFE50\uFE51"+ - "\uFE52\uFE54\uFE55\uFE56\uFE57\uFE59\uFE5A\uFE5B"+ - "\uFE5C\uFE5D\uFE5E\uFE5F\uFE60\uFE61\uFFFD\uFE62"+ - "\uFE63\uFE64\uFE65\uFE66\uFE68\uFE69\uFE6A\uFE6B"+ - "\u303E\u2FF0\u2FF1\u2FF2\u2FF3\u2FF4\u2FF5\u2FF6"+ - "\u2FF7\u2FF8\u2FF9\u2FFA\u2FFB\u3007\uE7F4\uE7F5"+ - "\uE7F6\uE7F7\uE7F8\uE7F9\uE7FA\uE7FB\uE7FC\uE7FD"+ - "\uE7FE\uE7FF\uE800\u2500\u2501\u2502\u2503\u2504"+ - "\u2505\u2506\u2507\u2508\u2509\u250A\u250B\u250C"+ - "\u250D\u250E\u250F\u2510\u2511\u2512\u2513\u2514"+ - "\u2515\u2516\u2517\u2518\u2519\u251A\u251B\u251C"+ - "\u251D\u251E\u251F\u2520\u2521\u2522\u2523\u2524"+ - "\u2525\u2526\u2527\u2528\u2529\u252A\u252B\u252C"+ - "\u252D\u252E\u252F\u2530\u2531\u2532\u2533\u2534"+ - "\u2535\u2536\u2537\u2538\u2539\u253A\u253B\u253C"+ - "\u253D\u253E\u253F\u2540\u2541\u2542\u2543\u2544"+ - "\u2545\u2546\u2547\u2548\u2549\u254A\u254B\uE801"+ - "\uE802\uE803\uE804\uE805\uE806\uE807\uE808\uE809"+ - "\uE80A\uE80B\uE80C\uE80D\uE80E\uE80F\u72DC\u72DD"+ - "\u72DF\u72E2\u72E3\u72E4\u72E5\u72E6\u72E7\u72EA"+ - "\u72EB\u72F5\u72F6\u72F9\u72FD\u72FE\u72FF\u7300"+ - "\u7302\u7304\u7305\u7306\u7307\u7308\u7309\u730B"+ - "\u730C\u730D\u730F\u7310\u7311\u7312\u7314\u7318"+ - "\u7319\u731A\u731F\u7320\u7323\u7324\u7326\u7327"+ - "\u7328\u732D\u732F\u7330\u7332\u7333\u7335\u7336"+ - "\u733A\u733B\u733C\u733D\u7340\u7341\u7342\u7343"+ - "\u7344\u7345\u7346\u7347\u7348\uFFFD\u7349\u734A"+ - "\u734B\u734C\u734E\u734F\u7351\u7353\u7354\u7355"+ - "\u7356\u7358\u7359\u735A\u735B\u735C\u735D\u735E"+ - "\u735F\u7361\u7362\u7363\u7364\u7365\u7366\u7367"+ - "\u7368\u7369\u736A\u736B\u736E\u7370\u7371\uE000"+ - "\uE001\uE002\uE003\uE004\uE005\uE006\uE007\uE008"+ - "\uE009\uE00A\uE00B\uE00C\uE00D\uE00E\uE00F\uE010"+ - "\uE011\uE012\uE013\uE014\uE015\uE016\uE017\uE018"+ - "\uE019\uE01A\uE01B\uE01C\uE01D\uE01E\uE01F\uE020"+ - "\uE021\uE022\uE023\uE024\uE025\uE026\uE027\uE028"+ - "\uE029\uE02A\uE02B\uE02C\uE02D\uE02E\uE02F\uE030"+ - "\uE031\uE032\uE033\uE034\uE035\uE036\uE037\uE038"+ - "\uE039\uE03A\uE03B\uE03C\uE03D\uE03E\uE03F\uE040"+ - "\uE041\uE042\uE043\uE044\uE045\uE046\uE047\uE048"+ - "\uE049\uE04A\uE04B\uE04C\uE04D\uE04E\uE04F\uE050"+ - "\uE051\uE052\uE053\uE054\uE055\uE056\uE057\uE058"+ - "\uE059\uE05A\uE05B\uE05C\uE05D\u7372\u7373\u7374"+ - "\u7375\u7376\u7377\u7378\u7379\u737A\u737B\u737C"+ - "\u737D\u737F\u7380\u7381\u7382\u7383\u7385\u7386"+ - "\u7388\u738A\u738C\u738D\u738F\u7390\u7392\u7393"+ - "\u7394\u7395\u7397\u7398\u7399\u739A\u739C\u739D"+ - "\u739E\u73A0\u73A1\u73A3\u73A4\u73A5\u73A6\u73A7"+ - "\u73A8\u73AA\u73AC\u73AD\u73B1\u73B4\u73B5\u73B6"+ - "\u73B8\u73B9\u73BC\u73BD\u73BE\u73BF\u73C1\u73C3"+ - "\u73C4\u73C5\u73C6\u73C7\uFFFD\u73CB\u73CC\u73CE"+ - "\u73D2\u73D3\u73D4\u73D5\u73D6\u73D7\u73D8\u73DA"+ - "\u73DB\u73DC\u73DD\u73DF\u73E1\u73E2\u73E3\u73E4"+ - "\u73E6\u73E8\u73EA\u73EB\u73EC\u73EE\u73EF\u73F0"+ - "\u73F1\u73F3\u73F4\u73F5\u73F6\u73F7\uE05E\uE05F"+ - "\uE060\uE061\uE062\uE063\uE064\uE065\uE066\uE067"+ - "\uE068\uE069\uE06A\uE06B\uE06C\uE06D\uE06E\uE06F"+ - "\uE070\uE071\uE072\uE073\uE074\uE075\uE076\uE077"+ - "\uE078\uE079\uE07A\uE07B\uE07C\uE07D\uE07E\uE07F"+ - "\uE080\uE081\uE082\uE083\uE084\uE085\uE086\uE087"+ - "\uE088\uE089\uE08A\uE08B\uE08C\uE08D\uE08E\uE08F"+ - "\uE090\uE091\uE092\uE093\uE094\uE095\uE096\uE097"+ - "\uE098\uE099\uE09A\uE09B\uE09C\uE09D\uE09E\uE09F"+ - "\uE0A0\uE0A1\uE0A2\uE0A3\uE0A4\uE0A5\uE0A6\uE0A7"+ - "\uE0A8\uE0A9\uE0AA\uE0AB\uE0AC\uE0AD\uE0AE\uE0AF"+ - "\uE0B0\uE0B1\uE0B2\uE0B3\uE0B4\uE0B5\uE0B6\uE0B7"+ - "\uE0B8\uE0B9\uE0BA\uE0BB\u73F8\u73F9\u73FA\u73FB"+ - "\u73FC\u73FD\u73FE\u73FF\u7400\u7401\u7402\u7404"+ - "\u7407\u7408\u740B\u740C\u740D\u740E\u7411\u7412"+ - "\u7413\u7414\u7415\u7416\u7417\u7418\u7419\u741C"+ - "\u741D\u741E\u741F\u7420\u7421\u7423\u7424\u7427"+ - "\u7429\u742B\u742D\u742F\u7431\u7432\u7437\u7438"+ - "\u7439\u743A\u743B\u743D\u743E\u743F\u7440\u7442"+ - "\u7443\u7444\u7445\u7446\u7447\u7448\u7449\u744A"+ - "\u744B\u744C\u744D\uFFFD\u744E\u744F\u7450\u7451"+ - "\u7452\u7453\u7454\u7456\u7458\u745D\u7460\u7461"+ - "\u7462\u7463\u7464\u7465\u7466\u7467\u7468\u7469"+ - "\u746A\u746B\u746C\u746E\u746F\u7471\u7472\u7473"+ - "\u7474\u7475\u7478\u7479\u747A\uE0BC\uE0BD\uE0BE"+ - "\uE0BF\uE0C0\uE0C1\uE0C2\uE0C3\uE0C4\uE0C5\uE0C6"+ - "\uE0C7\uE0C8\uE0C9\uE0CA\uE0CB\uE0CC\uE0CD\uE0CE"+ - "\uE0CF\uE0D0\uE0D1\uE0D2\uE0D3\uE0D4\uE0D5\uE0D6"+ - "\uE0D7\uE0D8\uE0D9\uE0DA\uE0DB\uE0DC\uE0DD\uE0DE"+ - "\uE0DF\uE0E0\uE0E1\uE0E2\uE0E3\uE0E4\uE0E5\uE0E6"+ - "\uE0E7\uE0E8\uE0E9\uE0EA\uE0EB\uE0EC\uE0ED\uE0EE"+ - "\uE0EF\uE0F0\uE0F1\uE0F2\uE0F3\uE0F4\uE0F5\uE0F6"+ - "\uE0F7\uE0F8\uE0F9\uE0FA\uE0FB\uE0FC\uE0FD\uE0FE"+ - "\uE0FF\uE100\uE101\uE102\uE103\uE104\uE105\uE106"+ - "\uE107\uE108\uE109\uE10A\uE10B\uE10C\uE10D\uE10E"+ - "\uE10F\uE110\uE111\uE112\uE113\uE114\uE115\uE116"+ - "\uE117\uE118\uE119\u747B\u747C\u747D\u747F\u7482"+ - "\u7484\u7485\u7486\u7488\u7489\u748A\u748C\u748D"+ - "\u748F\u7491\u7492\u7493\u7494\u7495\u7496\u7497"+ - "\u7498\u7499\u749A\u749B\u749D\u749F\u74A0\u74A1"+ - "\u74A2\u74A3\u74A4\u74A5\u74A6\u74AA\u74AB\u74AC"+ - "\u74AD\u74AE\u74AF\u74B0\u74B1\u74B2\u74B3\u74B4"+ - "\u74B5\u74B6\u74B7\u74B8\u74B9\u74BB\u74BC\u74BD"+ - "\u74BE\u74BF\u74C0\u74C1\u74C2\u74C3\u74C4\u74C5"+ - "\u74C6\u74C7\uFFFD\u74C8\u74C9\u74CA\u74CB\u74CC"+ - "\u74CD\u74CE\u74CF\u74D0\u74D1\u74D3\u74D4\u74D5"+ - "\u74D6\u74D7\u74D8\u74D9\u74DA\u74DB\u74DD\u74DF"+ - "\u74E1\u74E5\u74E7\u74E8\u74E9\u74EA\u74EB\u74EC"+ - "\u74ED\u74F0\u74F1\u74F2\uE11A\uE11B\uE11C\uE11D"+ - "\uE11E\uE11F\uE120\uE121\uE122\uE123\uE124\uE125"+ - "\uE126\uE127\uE128\uE129\uE12A\uE12B\uE12C\uE12D"+ - "\uE12E\uE12F\uE130\uE131\uE132\uE133\uE134\uE135"+ - "\uE136\uE137\uE138\uE139\uE13A\uE13B\uE13C\uE13D"+ - "\uE13E\uE13F\uE140\uE141\uE142\uE143\uE144\uE145"+ - "\uE146\uE147\uE148\uE149\uE14A\uE14B\uE14C\uE14D"+ - "\uE14E\uE14F\uE150\uE151\uE152\uE153\uE154\uE155"+ - "\uE156\uE157\uE158\uE159\uE15A\uE15B\uE15C\uE15D"+ - "\uE15E\uE15F\uE160\uE161\uE162\uE163\uE164\uE165"+ - "\uE166\uE167\uE168\uE169\uE16A\uE16B\uE16C\uE16D"+ - "\uE16E\uE16F\uE170\uE171\uE172\uE173\uE174\uE175"+ - "\uE176\uE177\u74F3\u74F5\u74F8\u74F9\u74FA\u74FB"+ - "\u74FC\u74FD\u74FE\u7500\u7501\u7502\u7503\u7505"+ - "\u7506\u7507\u7508\u7509\u750A\u750B\u750C\u750E"+ - "\u7510\u7512\u7514\u7515\u7516\u7517\u751B\u751D"+ - "\u751E\u7520\u7521\u7522\u7523\u7524\u7526\u7527"+ - "\u752A\u752E\u7534\u7536\u7539\u753C\u753D\u753F"+ - "\u7541\u7542\u7543\u7544\u7546\u7547\u7549\u754A"+ - "\u754D\u7550\u7551\u7552\u7553\u7555\u7556\u7557"+ - "\u7558\uFFFD\u755D\u755E\u755F\u7560\u7561\u7562"+ - "\u7563\u7564\u7567\u7568\u7569\u756B\u756C\u756D"+ - "\u756E\u756F\u7570\u7571\u7573\u7575\u7576\u7577"+ - "\u757A\u757B\u757C\u757D\u757E\u7580\u7581\u7582"+ - "\u7584\u7585\u7587\uE178\uE179\uE17A\uE17B\uE17C"+ - "\uE17D\uE17E\uE17F\uE180\uE181\uE182\uE183\uE184"+ - "\uE185\uE186\uE187\uE188\uE189\uE18A\uE18B\uE18C"+ - "\uE18D\uE18E\uE18F\uE190\uE191\uE192\uE193\uE194"+ - "\uE195\uE196\uE197\uE198\uE199\uE19A\uE19B\uE19C"+ - "\uE19D\uE19E\uE19F\uE1A0\uE1A1\uE1A2\uE1A3\uE1A4"+ - "\uE1A5\uE1A6\uE1A7\uE1A8\uE1A9\uE1AA\uE1AB\uE1AC"+ - "\uE1AD\uE1AE\uE1AF\uE1B0\uE1B1\uE1B2\uE1B3\uE1B4"+ - "\uE1B5\uE1B6\uE1B7\uE1B8\uE1B9\uE1BA\uE1BB\uE1BC"+ - "\uE1BD\uE1BE\uE1BF\uE1C0\uE1C1\uE1C2\uE1C3\uE1C4"+ - "\uE1C5\uE1C6\uE1C7\uE1C8\uE1C9\uE1CA\uE1CB\uE1CC"+ - "\uE1CD\uE1CE\uE1CF\uE1D0\uE1D1\uE1D2\uE1D3\uE1D4"+ - "\uE1D5\u7588\u7589\u758A\u758C\u758D\u758E\u7590"+ - "\u7593\u7595\u7598\u759B\u759C\u759E\u75A2\u75A6"+ - "\u75A7\u75A8\u75A9\u75AA\u75AD\u75B6\u75B7\u75BA"+ - "\u75BB\u75BF\u75C0\u75C1\u75C6\u75CB\u75CC\u75CE"+ - "\u75CF\u75D0\u75D1\u75D3\u75D7\u75D9\u75DA\u75DC"+ - "\u75DD\u75DF\u75E0\u75E1\u75E5\u75E9\u75EC\u75ED"+ - "\u75EE\u75EF\u75F2\u75F3\u75F5\u75F6\u75F7\u75F8"+ - "\u75FA\u75FB\u75FD\u75FE\u7602\u7604\u7606\u7607"+ - "\uFFFD\u7608\u7609\u760B\u760D\u760E\u760F\u7611"+ - "\u7612\u7613\u7614\u7616\u761A\u761C\u761D\u761E"+ - "\u7621\u7623\u7627\u7628\u762C\u762E\u762F\u7631"+ - "\u7632\u7636\u7637\u7639\u763A\u763B\u763D\u7641"+ - "\u7642\u7644\uE1D6\uE1D7\uE1D8\uE1D9\uE1DA\uE1DB"+ - "\uE1DC\uE1DD\uE1DE\uE1DF\uE1E0\uE1E1\uE1E2\uE1E3"+ - "\uE1E4\uE1E5\uE1E6\uE1E7\uE1E8\uE1E9\uE1EA\uE1EB"+ - "\uE1EC\uE1ED\uE1EE\uE1EF\uE1F0\uE1F1\uE1F2\uE1F3"+ - "\uE1F4\uE1F5\uE1F6\uE1F7\uE1F8\uE1F9\uE1FA\uE1FB"+ - "\uE1FC\uE1FD\uE1FE\uE1FF\uE200\uE201\uE202\uE203"+ - "\uE204\uE205\uE206\uE207\uE208\uE209\uE20A\uE20B"+ - "\uE20C\uE20D\uE20E\uE20F\uE210\uE211\uE212\uE213"+ - "\uE214\uE215\uE216\uE217\uE218\uE219\uE21A\uE21B"+ - "\uE21C\uE21D\uE21E\uE21F\uE220\uE221\uE222\uE223"+ - "\uE224\uE225\uE226\uE227\uE228\uE229\uE22A\uE22B"+ - "\uE22C\uE22D\uE22E\uE22F\uE230\uE231\uE232\uE233"; - - private static final String innerIndex3= - "\u7645\u7646\u7647\u7648\u7649\u764A\u764B\u764E"+ - "\u764F\u7650\u7651\u7652\u7653\u7655\u7657\u7658"+ - "\u7659\u765A\u765B\u765D\u765F\u7660\u7661\u7662"+ - "\u7664\u7665\u7666\u7667\u7668\u7669\u766A\u766C"+ - "\u766D\u766E\u7670\u7671\u7672\u7673\u7674\u7675"+ - "\u7676\u7677\u7679\u767A\u767C\u767F\u7680\u7681"+ - "\u7683\u7685\u7689\u768A\u768C\u768D\u768F\u7690"+ - "\u7692\u7694\u7695\u7697\u7698\u769A\u769B\uFFFD"+ - "\u769C\u769D\u769E\u769F\u76A0\u76A1\u76A2\u76A3"+ - "\u76A5\u76A6\u76A7\u76A8\u76A9\u76AA\u76AB\u76AC"+ - "\u76AD\u76AF\u76B0\u76B3\u76B5\u76B6\u76B7\u76B8"+ - "\u76B9\u76BA\u76BB\u76BC\u76BD\u76BE\u76C0\u76C1"+ - "\u76C3\u554A\u963F\u57C3\u6328\u54CE\u5509\u54C0"+ - "\u7691\u764C\u853C\u77EE\u827E\u788D\u7231\u9698"+ - "\u978D\u6C28\u5B89\u4FFA\u6309\u6697\u5CB8\u80FA"+ - "\u6848\u80AE\u6602\u76CE\u51F9\u6556\u71AC\u7FF1"+ - "\u8884\u50B2\u5965\u61CA\u6FB3\u82AD\u634C\u6252"+ - "\u53ED\u5427\u7B06\u516B\u75A4\u5DF4\u62D4\u8DCB"+ - "\u9776\u628A\u8019\u575D\u9738\u7F62\u7238\u767D"+ - "\u67CF\u767E\u6446\u4F70\u8D25\u62DC\u7A17\u6591"+ - "\u73ED\u642C\u6273\u822C\u9881\u677F\u7248\u626E"+ - "\u62CC\u4F34\u74E3\u534A\u529E\u7ECA\u90A6\u5E2E"+ - "\u6886\u699C\u8180\u7ED1\u68D2\u78C5\u868C\u9551"+ - "\u508D\u8C24\u82DE\u80DE\u5305\u8912\u5265\u76C4"+ - "\u76C7\u76C9\u76CB\u76CC\u76D3\u76D5\u76D9\u76DA"+ - "\u76DC\u76DD\u76DE\u76E0\u76E1\u76E2\u76E3\u76E4"+ - "\u76E6\u76E7\u76E8\u76E9\u76EA\u76EB\u76EC\u76ED"+ - "\u76F0\u76F3\u76F5\u76F6\u76F7\u76FA\u76FB\u76FD"+ - "\u76FF\u7700\u7702\u7703\u7705\u7706\u770A\u770C"+ - "\u770E\u770F\u7710\u7711\u7712\u7713\u7714\u7715"+ - "\u7716\u7717\u7718\u771B\u771C\u771D\u771E\u7721"+ - "\u7723\u7724\u7725\u7727\u772A\u772B\uFFFD\u772C"+ - "\u772E\u7730\u7731\u7732\u7733\u7734\u7739\u773B"+ - "\u773D\u773E\u773F\u7742\u7744\u7745\u7746\u7748"+ - "\u7749\u774A\u774B\u774C\u774D\u774E\u774F\u7752"+ - "\u7753\u7754\u7755\u7756\u7757\u7758\u7759\u775C"+ - "\u8584\u96F9\u4FDD\u5821\u9971\u5B9D\u62B1\u62A5"+ - "\u66B4\u8C79\u9C8D\u7206\u676F\u7891\u60B2\u5351"+ - "\u5317\u8F88\u80CC\u8D1D\u94A1\u500D\u72C8\u5907"+ - "\u60EB\u7119\u88AB\u5954\u82EF\u672C\u7B28\u5D29"+ - "\u7EF7\u752D\u6CF5\u8E66\u8FF8\u903C\u9F3B\u6BD4"+ - "\u9119\u7B14\u5F7C\u78A7\u84D6\u853D\u6BD5\u6BD9"+ - "\u6BD6\u5E01\u5E87\u75F9\u95ED\u655D\u5F0A\u5FC5"+ - "\u8F9F\u58C1\u81C2\u907F\u965B\u97AD\u8FB9\u7F16"+ - "\u8D2C\u6241\u4FBF\u53D8\u535E\u8FA8\u8FA9\u8FAB"+ - "\u904D\u6807\u5F6A\u8198\u8868\u9CD6\u618B\u522B"+ - "\u762A\u5F6C\u658C\u6FD2\u6EE8\u5BBE\u6448\u5175"+ - "\u51B0\u67C4\u4E19\u79C9\u997C\u70B3\u775D\u775E"+ - "\u775F\u7760\u7764\u7767\u7769\u776A\u776D\u776E"+ - "\u776F\u7770\u7771\u7772\u7773\u7774\u7775\u7776"+ - "\u7777\u7778\u777A\u777B\u777C\u7781\u7782\u7783"+ - "\u7786\u7787\u7788\u7789\u778A\u778B\u778F\u7790"+ - "\u7793\u7794\u7795\u7796\u7797\u7798\u7799\u779A"+ - "\u779B\u779C\u779D\u779E\u77A1\u77A3\u77A4\u77A6"+ - "\u77A8\u77AB\u77AD\u77AE\u77AF\u77B1\u77B2\u77B4"+ - "\u77B6\u77B7\u77B8\u77B9\u77BA\uFFFD\u77BC\u77BE"+ - "\u77C0\u77C1\u77C2\u77C3\u77C4\u77C5\u77C6\u77C7"+ - "\u77C8\u77C9\u77CA\u77CB\u77CC\u77CE\u77CF\u77D0"+ - "\u77D1\u77D2\u77D3\u77D4\u77D5\u77D6\u77D8\u77D9"+ - "\u77DA\u77DD\u77DE\u77DF\u77E0\u77E1\u77E4\u75C5"+ - "\u5E76\u73BB\u83E0\u64AD\u62E8\u94B5\u6CE2\u535A"+ - "\u52C3\u640F\u94C2\u7B94\u4F2F\u5E1B\u8236\u8116"+ - "\u818A\u6E24\u6CCA\u9A73\u6355\u535C\u54FA\u8865"+ - "\u57E0\u4E0D\u5E03\u6B65\u7C3F\u90E8\u6016\u64E6"+ - "\u731C\u88C1\u6750\u624D\u8D22\u776C\u8E29\u91C7"+ - "\u5F69\u83DC\u8521\u9910\u53C2\u8695\u6B8B\u60ED"+ - "\u60E8\u707F\u82CD\u8231\u4ED3\u6CA7\u85CF\u64CD"+ - "\u7CD9\u69FD\u66F9\u8349\u5395\u7B56\u4FA7\u518C"+ - "\u6D4B\u5C42\u8E6D\u63D2\u53C9\u832C\u8336\u67E5"+ - "\u78B4\u643D\u5BDF\u5C94\u5DEE\u8BE7\u62C6\u67F4"+ - "\u8C7A\u6400\u63BA\u8749\u998B\u8C17\u7F20\u94F2"+ - "\u4EA7\u9610\u98A4\u660C\u7316\u77E6\u77E8\u77EA"+ - "\u77EF\u77F0\u77F1\u77F2\u77F4\u77F5\u77F7\u77F9"+ - "\u77FA\u77FB\u77FC\u7803\u7804\u7805\u7806\u7807"+ - "\u7808\u780A\u780B\u780E\u780F\u7810\u7813\u7815"+ - "\u7819\u781B\u781E\u7820\u7821\u7822\u7824\u7828"+ - "\u782A\u782B\u782E\u782F\u7831\u7832\u7833\u7835"+ - "\u7836\u783D\u783F\u7841\u7842\u7843\u7844\u7846"+ - "\u7848\u7849\u784A\u784B\u784D\u784F\u7851\u7853"+ - "\u7854\u7858\u7859\u785A\uFFFD\u785B\u785C\u785E"+ - "\u785F\u7860\u7861\u7862\u7863\u7864\u7865\u7866"+ - "\u7867\u7868\u7869\u786F\u7870\u7871\u7872\u7873"+ - "\u7874\u7875\u7876\u7878\u7879\u787A\u787B\u787D"+ - "\u787E\u787F\u7880\u7881\u7882\u7883\u573A\u5C1D"+ - "\u5E38\u957F\u507F\u80A0\u5382\u655E\u7545\u5531"+ - "\u5021\u8D85\u6284\u949E\u671D\u5632\u6F6E\u5DE2"+ - "\u5435\u7092\u8F66\u626F\u64A4\u63A3\u5F7B\u6F88"+ - "\u90F4\u81E3\u8FB0\u5C18\u6668\u5FF1\u6C89\u9648"+ - "\u8D81\u886C\u6491\u79F0\u57CE\u6A59\u6210\u5448"+ - "\u4E58\u7A0B\u60E9\u6F84\u8BDA\u627F\u901E\u9A8B"+ - "\u79E4\u5403\u75F4\u6301\u5319\u6C60\u8FDF\u5F1B"+ - "\u9A70\u803B\u9F7F\u4F88\u5C3A\u8D64\u7FC5\u65A5"+ - "\u70BD\u5145\u51B2\u866B\u5D07\u5BA0\u62BD\u916C"+ - "\u7574\u8E0C\u7A20\u6101\u7B79\u4EC7\u7EF8\u7785"+ - "\u4E11\u81ED\u521D\u51FA\u6A71\u53A8\u8E87\u9504"+ - "\u96CF\u6EC1\u9664\u695A\u7884\u7885\u7886\u7888"+ - "\u788A\u788B\u788F\u7890\u7892\u7894\u7895\u7896"+ - "\u7899\u789D\u789E\u78A0\u78A2\u78A4\u78A6\u78A8"+ - "\u78A9\u78AA\u78AB\u78AC\u78AD\u78AE\u78AF\u78B5"+ - "\u78B6\u78B7\u78B8\u78BA\u78BB\u78BC\u78BD\u78BF"+ - "\u78C0\u78C2\u78C3\u78C4\u78C6\u78C7\u78C8\u78CC"+ - "\u78CD\u78CE\u78CF\u78D1\u78D2\u78D3\u78D6\u78D7"+ - "\u78D8\u78DA\u78DB\u78DC\u78DD\u78DE\u78DF\u78E0"+ - "\u78E1\u78E2\u78E3\uFFFD\u78E4\u78E5\u78E6\u78E7"+ - "\u78E9\u78EA\u78EB\u78ED\u78EE\u78EF\u78F0\u78F1"+ - "\u78F3\u78F5\u78F6\u78F8\u78F9\u78FB\u78FC\u78FD"+ - "\u78FE\u78FF\u7900\u7902\u7903\u7904\u7906\u7907"+ - "\u7908\u7909\u790A\u790B\u790C\u7840\u50A8\u77D7"+ - "\u6410\u89E6\u5904\u63E3\u5DDD\u7A7F\u693D\u4F20"+ - "\u8239\u5598\u4E32\u75AE\u7A97\u5E62\u5E8A\u95EF"+ - "\u521B\u5439\u708A\u6376\u9524\u5782\u6625\u693F"+ - "\u9187\u5507\u6DF3\u7EAF\u8822\u6233\u7EF0\u75B5"+ - "\u8328\u78C1\u96CC\u8F9E\u6148\u74F7\u8BCD\u6B64"+ - "\u523A\u8D50\u6B21\u806A\u8471\u56F1\u5306\u4ECE"+ - "\u4E1B\u51D1\u7C97\u918B\u7C07\u4FC3\u8E7F\u7BE1"+ - "\u7A9C\u6467\u5D14\u50AC\u8106\u7601\u7CB9\u6DEC"+ - "\u7FE0\u6751\u5B58\u5BF8\u78CB\u64AE\u6413\u63AA"+ - "\u632B\u9519\u642D\u8FBE\u7B54\u7629\u6253\u5927"+ - "\u5446\u6B79\u50A3\u6234\u5E26\u6B86\u4EE3\u8D37"+ - "\u888B\u5F85\u902E\u790D\u790E\u790F\u7910\u7911"+ - "\u7912\u7914\u7915\u7916\u7917\u7918\u7919\u791A"+ - "\u791B\u791C\u791D\u791F\u7920\u7921\u7922\u7923"+ - "\u7925\u7926\u7927\u7928\u7929\u792A\u792B\u792C"+ - "\u792D\u792E\u792F\u7930\u7931\u7932\u7933\u7935"+ - "\u7936\u7937\u7938\u7939\u793D\u793F\u7942\u7943"+ - "\u7944\u7945\u7947\u794A\u794B\u794C\u794D\u794E"+ - "\u794F\u7950\u7951\u7952\u7954\u7955\u7958\u7959"+ - "\u7961\u7963\uFFFD\u7964\u7966\u7969\u796A\u796B"+ - "\u796C\u796E\u7970\u7971\u7972\u7973\u7974\u7975"+ - "\u7976\u7979\u797B\u797C\u797D\u797E\u797F\u7982"+ - "\u7983\u7986\u7987\u7988\u7989\u798B\u798C\u798D"+ - "\u798E\u7990\u7991\u7992\u6020\u803D\u62C5\u4E39"+ - "\u5355\u90F8\u63B8\u80C6\u65E6\u6C2E\u4F46\u60EE"+ - "\u6DE1\u8BDE\u5F39\u86CB\u5F53\u6321\u515A\u8361"+ - "\u6863\u5200\u6363\u8E48\u5012\u5C9B\u7977\u5BFC"+ - "\u5230\u7A3B\u60BC\u9053\u76D7\u5FB7\u5F97\u7684"+ - "\u8E6C\u706F\u767B\u7B49\u77AA\u51F3\u9093\u5824"+ - "\u4F4E\u6EF4\u8FEA\u654C\u7B1B\u72C4\u6DA4\u7FDF"+ - "\u5AE1\u62B5\u5E95\u5730\u8482\u7B2C\u5E1D\u5F1F"+ - "\u9012\u7F14\u98A0\u6382\u6EC7\u7898\u70B9\u5178"+ - "\u975B\u57AB\u7535\u4F43\u7538\u5E97\u60E6\u5960"+ - "\u6DC0\u6BBF\u7889\u53FC\u96D5\u51CB\u5201\u6389"+ - "\u540A\u9493\u8C03\u8DCC\u7239\u789F\u8776\u8FED"+ - "\u8C0D\u53E0\u7993\u7994\u7995\u7996\u7997\u7998"+ - "\u7999\u799B\u799C\u799D\u799E\u799F\u79A0\u79A1"+ - "\u79A2\u79A3\u79A4\u79A5\u79A6\u79A8\u79A9\u79AA"+ - "\u79AB\u79AC\u79AD\u79AE\u79AF\u79B0\u79B1\u79B2"+ - "\u79B4\u79B5\u79B6\u79B7\u79B8\u79BC\u79BF\u79C2"+ - "\u79C4\u79C5\u79C7\u79C8\u79CA\u79CC\u79CE\u79CF"+ - "\u79D0\u79D3\u79D4\u79D6\u79D7\u79D9\u79DA\u79DB"+ - "\u79DC\u79DD\u79DE\u79E0\u79E1\u79E2\u79E5\u79E8"+ - "\u79EA\uFFFD\u79EC\u79EE\u79F1\u79F2\u79F3\u79F4"+ - "\u79F5\u79F6\u79F7\u79F9\u79FA\u79FC\u79FE\u79FF"+ - "\u7A01\u7A04\u7A05\u7A07\u7A08\u7A09\u7A0A\u7A0C"+ - "\u7A0F\u7A10\u7A11\u7A12\u7A13\u7A15\u7A16\u7A18"+ - "\u7A19\u7A1B\u7A1C\u4E01\u76EF\u53EE\u9489\u9876"+ - "\u9F0E\u952D\u5B9A\u8BA2\u4E22\u4E1C\u51AC\u8463"+ - "\u61C2\u52A8\u680B\u4F97\u606B\u51BB\u6D1E\u515C"+ - "\u6296\u6597\u9661\u8C46\u9017\u75D8\u90FD\u7763"+ - "\u6BD2\u728A\u72EC\u8BFB\u5835\u7779\u8D4C\u675C"+ - "\u9540\u809A\u5EA6\u6E21\u5992\u7AEF\u77ED\u953B"+ - "\u6BB5\u65AD\u7F0E\u5806\u5151\u961F\u5BF9\u58A9"+ - "\u5428\u8E72\u6566\u987F\u56E4\u949D\u76FE\u9041"+ - "\u6387\u54C6\u591A\u593A\u579B\u8EB2\u6735\u8DFA"+ - "\u8235\u5241\u60F0\u5815\u86FE\u5CE8\u9E45\u4FC4"+ - "\u989D\u8BB9\u5A25\u6076\u5384\u627C\u904F\u9102"+ - "\u997F\u6069\u800C\u513F\u8033\u5C14\u9975\u6D31"+ - "\u4E8C\u7A1D\u7A1F\u7A21\u7A22\u7A24\u7A25\u7A26"+ - "\u7A27\u7A28\u7A29\u7A2A\u7A2B\u7A2C\u7A2D\u7A2E"+ - "\u7A2F\u7A30\u7A31\u7A32\u7A34\u7A35\u7A36\u7A38"+ - "\u7A3A\u7A3E\u7A40\u7A41\u7A42\u7A43\u7A44\u7A45"+ - "\u7A47\u7A48\u7A49\u7A4A\u7A4B\u7A4C\u7A4D\u7A4E"+ - "\u7A4F\u7A50\u7A52\u7A53\u7A54\u7A55\u7A56\u7A58"+ - "\u7A59\u7A5A\u7A5B\u7A5C\u7A5D\u7A5E\u7A5F\u7A60"+ - "\u7A61\u7A62\u7A63\u7A64\u7A65\u7A66\u7A67\u7A68"+ - "\uFFFD\u7A69\u7A6A\u7A6B\u7A6C\u7A6D\u7A6E\u7A6F"+ - "\u7A71\u7A72\u7A73\u7A75\u7A7B\u7A7C\u7A7D\u7A7E"+ - "\u7A82\u7A85\u7A87\u7A89\u7A8A\u7A8B\u7A8C\u7A8E"+ - "\u7A8F\u7A90\u7A93\u7A94\u7A99\u7A9A\u7A9B\u7A9E"+ - "\u7AA1\u7AA2\u8D30\u53D1\u7F5A\u7B4F\u4F10\u4E4F"+ - "\u9600\u6CD5\u73D0\u85E9\u5E06\u756A\u7FFB\u6A0A"+ - "\u77FE\u9492\u7E41\u51E1\u70E6\u53CD\u8FD4\u8303"+ - "\u8D29\u72AF\u996D\u6CDB\u574A\u82B3\u65B9\u80AA"+ - "\u623F\u9632\u59A8\u4EFF\u8BBF\u7EBA\u653E\u83F2"+ - "\u975E\u5561\u98DE\u80A5\u532A\u8BFD\u5420\u80BA"+ - "\u5E9F\u6CB8\u8D39\u82AC\u915A\u5429\u6C1B\u5206"+ - "\u7EB7\u575F\u711A\u6C7E\u7C89\u594B\u4EFD\u5FFF"+ - "\u6124\u7CAA\u4E30\u5C01\u67AB\u8702\u5CF0\u950B"+ - "\u98CE\u75AF\u70FD\u9022\u51AF\u7F1D\u8BBD\u5949"+ - "\u51E4\u4F5B\u5426\u592B\u6577\u80A4\u5B75\u6276"+ - "\u62C2\u8F90\u5E45\u6C1F\u7B26\u4F0F\u4FD8\u670D"+ - "\u7AA3\u7AA4\u7AA7\u7AA9\u7AAA\u7AAB\u7AAE\u7AAF"+ - "\u7AB0\u7AB1\u7AB2\u7AB4\u7AB5\u7AB6\u7AB7\u7AB8"+ - "\u7AB9\u7ABA\u7ABB\u7ABC\u7ABD\u7ABE\u7AC0\u7AC1"+ - "\u7AC2\u7AC3\u7AC4\u7AC5\u7AC6\u7AC7\u7AC8\u7AC9"+ - "\u7ACA\u7ACC\u7ACD\u7ACE\u7ACF\u7AD0\u7AD1\u7AD2"+ - "\u7AD3\u7AD4\u7AD5\u7AD7\u7AD8\u7ADA\u7ADB\u7ADC"+ - "\u7ADD\u7AE1\u7AE2\u7AE4\u7AE7\u7AE8\u7AE9\u7AEA"+ - "\u7AEB\u7AEC\u7AEE\u7AF0\u7AF1\u7AF2\u7AF3\uFFFD"+ - "\u7AF4\u7AF5\u7AF6\u7AF7\u7AF8\u7AFB\u7AFC\u7AFE"+ - "\u7B00\u7B01\u7B02\u7B05\u7B07\u7B09\u7B0C\u7B0D"+ - "\u7B0E\u7B10\u7B12\u7B13\u7B16\u7B17\u7B18\u7B1A"+ - "\u7B1C\u7B1D\u7B1F\u7B21\u7B22\u7B23\u7B27\u7B29"+ - "\u7B2D\u6D6E\u6DAA\u798F\u88B1\u5F17\u752B\u629A"+ - "\u8F85\u4FEF\u91DC\u65A7\u812F\u8151\u5E9C\u8150"+ - "\u8D74\u526F\u8986\u8D4B\u590D\u5085\u4ED8\u961C"+ - "\u7236\u8179\u8D1F\u5BCC\u8BA3\u9644\u5987\u7F1A"+ - "\u5490\u5676\u560E\u8BE5\u6539\u6982\u9499\u76D6"+ - "\u6E89\u5E72\u7518\u6746\u67D1\u7AFF\u809D\u8D76"+ - "\u611F\u79C6\u6562\u8D63\u5188\u521A\u94A2\u7F38"+ - "\u809B\u7EB2\u5C97\u6E2F\u6760\u7BD9\u768B\u9AD8"+ - "\u818F\u7F94\u7CD5\u641E\u9550\u7A3F\u544A\u54E5"+ - "\u6B4C\u6401\u6208\u9E3D\u80F3\u7599\u5272\u9769"+ - "\u845B\u683C\u86E4\u9601\u9694\u94EC\u4E2A\u5404"+ - "\u7ED9\u6839\u8DDF\u8015\u66F4\u5E9A\u7FB9\u7B2F"+ - "\u7B30\u7B32\u7B34\u7B35\u7B36\u7B37\u7B39\u7B3B"+ - "\u7B3D\u7B3F\u7B40\u7B41\u7B42\u7B43\u7B44\u7B46"+ - "\u7B48\u7B4A\u7B4D\u7B4E\u7B53\u7B55\u7B57\u7B59"+ - "\u7B5C\u7B5E\u7B5F\u7B61\u7B63\u7B64\u7B65\u7B66"+ - "\u7B67\u7B68\u7B69\u7B6A\u7B6B\u7B6C\u7B6D\u7B6F"+ - "\u7B70\u7B73\u7B74\u7B76\u7B78\u7B7A\u7B7C\u7B7D"+ - "\u7B7F\u7B81\u7B82\u7B83\u7B84\u7B86\u7B87\u7B88"+ - "\u7B89\u7B8A\u7B8B\u7B8C\u7B8E\u7B8F\uFFFD\u7B91"+ - "\u7B92\u7B93\u7B96\u7B98\u7B99\u7B9A\u7B9B\u7B9E"+ - "\u7B9F\u7BA0\u7BA3\u7BA4\u7BA5\u7BAE\u7BAF\u7BB0"+ - "\u7BB2\u7BB3\u7BB5\u7BB6\u7BB7\u7BB9\u7BBA\u7BBB"+ - "\u7BBC\u7BBD\u7BBE\u7BBF\u7BC0\u7BC2\u7BC3\u7BC4"+ - "\u57C2\u803F\u6897\u5DE5\u653B\u529F\u606D\u9F9A"+ - "\u4F9B\u8EAC\u516C\u5BAB\u5F13\u5DE9\u6C5E\u62F1"+ - "\u8D21\u5171\u94A9\u52FE\u6C9F\u82DF\u72D7\u57A2"+ - "\u6784\u8D2D\u591F\u8F9C\u83C7\u5495\u7B8D\u4F30"+ - "\u6CBD\u5B64\u59D1\u9F13\u53E4\u86CA\u9AA8\u8C37"+ - "\u80A1\u6545\u987E\u56FA\u96C7\u522E\u74DC\u5250"+ - "\u5BE1\u6302\u8902\u4E56\u62D0\u602A\u68FA\u5173"+ - "\u5B98\u51A0\u89C2\u7BA1\u9986\u7F50\u60EF\u704C"+ - "\u8D2F\u5149\u5E7F\u901B\u7470\u89C4\u572D\u7845"+ - "\u5F52\u9F9F\u95FA\u8F68\u9B3C\u8BE1\u7678\u6842"+ - "\u67DC\u8DEA\u8D35\u523D\u8F8A\u6EDA\u68CD\u9505"+ - "\u90ED\u56FD\u679C\u88F9\u8FC7\u54C8\u7BC5\u7BC8"+ - "\u7BC9\u7BCA\u7BCB\u7BCD\u7BCE\u7BCF\u7BD0\u7BD2"+ - "\u7BD4\u7BD5\u7BD6\u7BD7\u7BD8\u7BDB\u7BDC\u7BDE"+ - "\u7BDF\u7BE0\u7BE2\u7BE3\u7BE4\u7BE7\u7BE8\u7BE9"+ - "\u7BEB\u7BEC\u7BED\u7BEF\u7BF0\u7BF2\u7BF3\u7BF4"+ - "\u7BF5\u7BF6\u7BF8\u7BF9\u7BFA\u7BFB\u7BFD\u7BFF"+ - "\u7C00\u7C01\u7C02\u7C03\u7C04\u7C05\u7C06\u7C08"+ - "\u7C09\u7C0A\u7C0D\u7C0E\u7C10\u7C11\u7C12\u7C13"+ - "\u7C14\u7C15\u7C17\u7C18\u7C19\uFFFD\u7C1A\u7C1B"+ - "\u7C1C\u7C1D\u7C1E\u7C20\u7C21\u7C22\u7C23\u7C24"+ - "\u7C25\u7C28\u7C29\u7C2B\u7C2C\u7C2D\u7C2E\u7C2F"+ - "\u7C30\u7C31\u7C32\u7C33\u7C34\u7C35\u7C36\u7C37"+ - "\u7C39\u7C3A\u7C3B\u7C3C\u7C3D\u7C3E\u7C42\u9AB8"+ - "\u5B69\u6D77\u6C26\u4EA5\u5BB3\u9A87\u9163\u61A8"+ - "\u90AF\u97E9\u542B\u6DB5\u5BD2\u51FD\u558A\u7F55"+ - "\u7FF0\u64BC\u634D\u65F1\u61BE\u608D\u710A\u6C57"+ - "\u6C49\u592F\u676D\u822A\u58D5\u568E\u8C6A\u6BEB"+ - "\u90DD\u597D\u8017\u53F7\u6D69\u5475\u559D\u8377"+ - "\u83CF\u6838\u79BE\u548C\u4F55\u5408\u76D2\u8C89"+ - "\u9602\u6CB3\u6DB8\u8D6B\u8910\u9E64\u8D3A\u563F"+ - "\u9ED1\u75D5\u5F88\u72E0\u6068\u54FC\u4EA8\u6A2A"+ - "\u8861\u6052\u8F70\u54C4\u70D8\u8679\u9E3F\u6D2A"+ - "\u5B8F\u5F18\u7EA2\u5589\u4FAF\u7334\u543C\u539A"+ - "\u5019\u540E\u547C\u4E4E\u5FFD\u745A\u58F6\u846B"+ - "\u80E1\u8774\u72D0\u7CCA\u6E56\u7C43\u7C44\u7C45"+ - "\u7C46\u7C47\u7C48\u7C49\u7C4A\u7C4B\u7C4C\u7C4E"+ - "\u7C4F\u7C50\u7C51\u7C52\u7C53\u7C54\u7C55\u7C56"+ - "\u7C57\u7C58\u7C59\u7C5A\u7C5B\u7C5C\u7C5D\u7C5E"+ - "\u7C5F\u7C60\u7C61\u7C62\u7C63\u7C64\u7C65\u7C66"+ - "\u7C67\u7C68\u7C69\u7C6A\u7C6B\u7C6C\u7C6D\u7C6E"+ - "\u7C6F\u7C70\u7C71\u7C72\u7C75\u7C76\u7C77\u7C78"+ - "\u7C79\u7C7A\u7C7E\u7C7F\u7C80\u7C81\u7C82\u7C83"+ - "\u7C84\u7C85\u7C86\u7C87\uFFFD\u7C88\u7C8A\u7C8B"+ - "\u7C8C\u7C8D\u7C8E\u7C8F\u7C90\u7C93\u7C94\u7C96"+ - "\u7C99\u7C9A\u7C9B\u7CA0\u7CA1\u7CA3\u7CA6\u7CA7"+ - "\u7CA8\u7CA9\u7CAB\u7CAC\u7CAD\u7CAF\u7CB0\u7CB4"+ - "\u7CB5\u7CB6\u7CB7\u7CB8\u7CBA\u7CBB\u5F27\u864E"+ - "\u552C\u62A4\u4E92\u6CAA\u6237\u82B1\u54D7\u534E"+ - "\u733E\u6ED1\u753B\u5212\u5316\u8BDD\u69D0\u5F8A"+ - "\u6000\u6DEE\u574F\u6B22\u73AF\u6853\u8FD8\u7F13"+ - "\u6362\u60A3\u5524\u75EA\u8C62\u7115\u6DA3\u5BA6"+ - "\u5E7B\u8352\u614C\u9EC4\u78FA\u8757\u7C27\u7687"+ - "\u51F0\u60F6\u714C\u6643\u5E4C\u604D\u8C0E\u7070"+ - "\u6325\u8F89\u5FBD\u6062\u86D4\u56DE\u6BC1\u6094"+ - "\u6167\u5349\u60E0\u6666\u8D3F\u79FD\u4F1A\u70E9"+ - "\u6C47\u8BB3\u8BF2\u7ED8\u8364\u660F\u5A5A\u9B42"+ - "\u6D51\u6DF7\u8C41\u6D3B\u4F19\u706B\u83B7\u6216"+ - "\u60D1\u970D\u8D27\u7978\u51FB\u573E\u57FA\u673A"+ - "\u7578\u7A3D\u79EF\u7B95\u7CBF\u7CC0\u7CC2\u7CC3"+ - "\u7CC4\u7CC6\u7CC9\u7CCB\u7CCE\u7CCF\u7CD0\u7CD1"+ - "\u7CD2\u7CD3\u7CD4\u7CD8\u7CDA\u7CDB\u7CDD\u7CDE"+ - "\u7CE1\u7CE2\u7CE3\u7CE4\u7CE5\u7CE6\u7CE7\u7CE9"+ - "\u7CEA\u7CEB\u7CEC\u7CED\u7CEE\u7CF0\u7CF1\u7CF2"+ - "\u7CF3\u7CF4\u7CF5\u7CF6\u7CF7\u7CF9\u7CFA\u7CFC"+ - "\u7CFD\u7CFE\u7CFF\u7D00\u7D01\u7D02\u7D03\u7D04"+ - "\u7D05\u7D06\u7D07\u7D08\u7D09\u7D0B\u7D0C\u7D0D"+ - "\u7D0E\u7D0F\u7D10\uFFFD\u7D11\u7D12\u7D13\u7D14"+ - "\u7D15\u7D16\u7D17\u7D18\u7D19\u7D1A\u7D1B\u7D1C"+ - "\u7D1D\u7D1E\u7D1F\u7D21\u7D23\u7D24\u7D25\u7D26"+ - "\u7D28\u7D29\u7D2A\u7D2C\u7D2D\u7D2E\u7D30\u7D31"+ - "\u7D32\u7D33\u7D34\u7D35\u7D36\u808C\u9965\u8FF9"+ - "\u6FC0\u8BA5\u9E21\u59EC\u7EE9\u7F09\u5409\u6781"+ - "\u68D8\u8F91\u7C4D\u96C6\u53CA\u6025\u75BE\u6C72"+ - "\u5373\u5AC9\u7EA7\u6324\u51E0\u810A\u5DF1\u84DF"+ - "\u6280\u5180\u5B63\u4F0E\u796D\u5242\u60B8\u6D4E"+ - "\u5BC4\u5BC2\u8BA1\u8BB0\u65E2\u5FCC\u9645\u5993"+ - "\u7EE7\u7EAA\u5609\u67B7\u5939\u4F73\u5BB6\u52A0"+ - "\u835A\u988A\u8D3E\u7532\u94BE\u5047\u7A3C\u4EF7"+ - "\u67B6\u9A7E\u5AC1\u6B7C\u76D1\u575A\u5C16\u7B3A"+ - "\u95F4\u714E\u517C\u80A9\u8270\u5978\u7F04\u8327"+ - "\u68C0\u67EC\u78B1\u7877\u62E3\u6361\u7B80\u4FED"+ - "\u526A\u51CF\u8350\u69DB\u9274\u8DF5\u8D31\u89C1"+ - "\u952E\u7BAD\u4EF6\u7D37\u7D38\u7D39\u7D3A\u7D3B"+ - "\u7D3C\u7D3D\u7D3E\u7D3F\u7D40\u7D41\u7D42\u7D43"+ - "\u7D44\u7D45\u7D46\u7D47\u7D48\u7D49\u7D4A\u7D4B"+ - "\u7D4C\u7D4D\u7D4E\u7D4F\u7D50\u7D51\u7D52\u7D53"+ - "\u7D54\u7D55\u7D56\u7D57\u7D58\u7D59\u7D5A\u7D5B"+ - "\u7D5C\u7D5D\u7D5E\u7D5F\u7D60\u7D61\u7D62\u7D63"+ - "\u7D64\u7D65\u7D66\u7D67\u7D68\u7D69\u7D6A\u7D6B"+ - "\u7D6C\u7D6D\u7D6F\u7D70\u7D71\u7D72\u7D73\u7D74"+ - "\u7D75\u7D76\uFFFD\u7D78\u7D79\u7D7A\u7D7B\u7D7C"+ - "\u7D7D\u7D7E\u7D7F\u7D80\u7D81\u7D82\u7D83\u7D84"+ - "\u7D85\u7D86\u7D87\u7D88\u7D89\u7D8A\u7D8B\u7D8C"+ - "\u7D8D\u7D8E\u7D8F\u7D90\u7D91\u7D92\u7D93\u7D94"+ - "\u7D95\u7D96\u7D97\u7D98\u5065\u8230\u5251\u996F"+ - "\u6E10\u6E85\u6DA7\u5EFA\u50F5\u59DC\u5C06\u6D46"+ - "\u6C5F\u7586\u848B\u6868\u5956\u8BB2\u5320\u9171"+ - "\u964D\u8549\u6912\u7901\u7126\u80F6\u4EA4\u90CA"+ - "\u6D47\u9A84\u5A07\u56BC\u6405\u94F0\u77EB\u4FA5"+ - "\u811A\u72E1\u89D2\u997A\u7F34\u7EDE\u527F\u6559"+ - "\u9175\u8F7F\u8F83\u53EB\u7A96\u63ED\u63A5\u7686"+ - "\u79F8\u8857\u9636\u622A\u52AB\u8282\u6854\u6770"+ - "\u6377\u776B\u7AED\u6D01\u7ED3\u89E3\u59D0\u6212"+ - "\u85C9\u82A5\u754C\u501F\u4ECB\u75A5\u8BEB\u5C4A"+ - "\u5DFE\u7B4B\u65A4\u91D1\u4ECA\u6D25\u895F\u7D27"+ - "\u9526\u4EC5\u8C28\u8FDB\u9773\u664B\u7981\u8FD1"+ - "\u70EC\u6D78\u7D99\u7D9A\u7D9B\u7D9C\u7D9D\u7D9E"+ - "\u7D9F\u7DA0\u7DA1\u7DA2\u7DA3\u7DA4\u7DA5\u7DA7"+ - "\u7DA8\u7DA9\u7DAA\u7DAB\u7DAC\u7DAD\u7DAF\u7DB0"+ - "\u7DB1\u7DB2\u7DB3\u7DB4\u7DB5\u7DB6\u7DB7\u7DB8"+ - "\u7DB9\u7DBA\u7DBB\u7DBC\u7DBD\u7DBE\u7DBF\u7DC0"+ - "\u7DC1\u7DC2\u7DC3\u7DC4\u7DC5\u7DC6\u7DC7\u7DC8"+ - "\u7DC9\u7DCA\u7DCB\u7DCC\u7DCD\u7DCE\u7DCF\u7DD0"+ - "\u7DD1\u7DD2\u7DD3\u7DD4\u7DD5\u7DD6\u7DD7\u7DD8"+ - "\u7DD9\uFFFD\u7DDA\u7DDB\u7DDC\u7DDD\u7DDE\u7DDF"+ - "\u7DE0\u7DE1\u7DE2\u7DE3\u7DE4\u7DE5\u7DE6\u7DE7"+ - "\u7DE8\u7DE9\u7DEA\u7DEB\u7DEC\u7DED\u7DEE\u7DEF"+ - "\u7DF0\u7DF1\u7DF2\u7DF3\u7DF4\u7DF5\u7DF6\u7DF7"+ - "\u7DF8\u7DF9\u7DFA\u5C3D\u52B2\u8346\u5162\u830E"+ - "\u775B\u6676\u9CB8\u4EAC\u60CA\u7CBE\u7CB3\u7ECF"+ - "\u4E95\u8B66\u666F\u9888\u9759\u5883\u656C\u955C"+ - "\u5F84\u75C9\u9756\u7ADF\u7ADE\u51C0\u70AF\u7A98"+ - "\u63EA\u7A76\u7EA0\u7396\u97ED\u4E45\u7078\u4E5D"+ - "\u9152\u53A9\u6551\u65E7\u81FC\u8205\u548E\u5C31"+ - "\u759A\u97A0\u62D8\u72D9\u75BD\u5C45\u9A79\u83CA"+ - "\u5C40\u5480\u77E9\u4E3E\u6CAE\u805A\u62D2\u636E"+ - "\u5DE8\u5177\u8DDD\u8E1E\u952F\u4FF1\u53E5\u60E7"+ - "\u70AC\u5267\u6350\u9E43\u5A1F\u5026\u7737\u5377"+ - "\u7EE2\u6485\u652B\u6289\u6398\u5014\u7235\u89C9"+ - "\u51B3\u8BC0\u7EDD\u5747\u83CC\u94A7\u519B\u541B"+ - "\u5CFB\u7DFB\u7DFC\u7DFD\u7DFE\u7DFF\u7E00\u7E01"+ - "\u7E02\u7E03\u7E04\u7E05\u7E06\u7E07\u7E08\u7E09"+ - "\u7E0A\u7E0B\u7E0C\u7E0D\u7E0E\u7E0F\u7E10\u7E11"+ - "\u7E12\u7E13\u7E14\u7E15\u7E16\u7E17\u7E18\u7E19"+ - "\u7E1A\u7E1B\u7E1C\u7E1D\u7E1E\u7E1F\u7E20\u7E21"+ - "\u7E22\u7E23\u7E24\u7E25\u7E26\u7E27\u7E28\u7E29"+ - "\u7E2A\u7E2B\u7E2C\u7E2D\u7E2E\u7E2F\u7E30\u7E31"+ - "\u7E32\u7E33\u7E34\u7E35\u7E36\u7E37\u7E38\u7E39"+ - "\uFFFD\u7E3A\u7E3C\u7E3D\u7E3E\u7E3F\u7E40\u7E42"+ - "\u7E43\u7E44\u7E45\u7E46\u7E48\u7E49\u7E4A\u7E4B"+ - "\u7E4C\u7E4D\u7E4E\u7E4F\u7E50\u7E51\u7E52\u7E53"+ - "\u7E54\u7E55\u7E56\u7E57\u7E58\u7E59\u7E5A\u7E5B"+ - "\u7E5C\u7E5D\u4FCA\u7AE3\u6D5A\u90E1\u9A8F\u5580"+ - "\u5496\u5361\u54AF\u5F00\u63E9\u6977\u51EF\u6168"+ - "\u520A\u582A\u52D8\u574E\u780D\u770B\u5EB7\u6177"+ - "\u7CE0\u625B\u6297\u4EA2\u7095\u8003\u62F7\u70E4"+ - "\u9760\u5777\u82DB\u67EF\u68F5\u78D5\u9897\u79D1"+ - "\u58F3\u54B3\u53EF\u6E34\u514B\u523B\u5BA2\u8BFE"+ - "\u80AF\u5543\u57A6\u6073\u5751\u542D\u7A7A\u6050"+ - "\u5B54\u63A7\u62A0\u53E3\u6263\u5BC7\u67AF\u54ED"+ - "\u7A9F\u82E6\u9177\u5E93\u88E4\u5938\u57AE\u630E"+ - "\u8DE8\u80EF\u5757\u7B77\u4FA9\u5FEB\u5BBD\u6B3E"+ - "\u5321\u7B50\u72C2\u6846\u77FF\u7736\u65F7\u51B5"+ - "\u4E8F\u76D4\u5CBF\u7AA5\u8475\u594E\u9B41\u5080"; - - private static final String innerIndex4= - "\u7E5E\u7E5F\u7E60\u7E61\u7E62\u7E63\u7E64\u7E65"+ - "\u7E66\u7E67\u7E68\u7E69\u7E6A\u7E6B\u7E6C\u7E6D"+ - "\u7E6E\u7E6F\u7E70\u7E71\u7E72\u7E73\u7E74\u7E75"+ - "\u7E76\u7E77\u7E78\u7E79\u7E7A\u7E7B\u7E7C\u7E7D"+ - "\u7E7E\u7E7F\u7E80\u7E81\u7E83\u7E84\u7E85\u7E86"+ - "\u7E87\u7E88\u7E89\u7E8A\u7E8B\u7E8C\u7E8D\u7E8E"+ - "\u7E8F\u7E90\u7E91\u7E92\u7E93\u7E94\u7E95\u7E96"+ - "\u7E97\u7E98\u7E99\u7E9A\u7E9C\u7E9D\u7E9E\uFFFD"+ - "\u7EAE\u7EB4\u7EBB\u7EBC\u7ED6\u7EE4\u7EEC\u7EF9"+ - "\u7F0A\u7F10\u7F1E\u7F37\u7F39\u7F3B\u7F3C\u7F3D"+ - "\u7F3E\u7F3F\u7F40\u7F41\u7F43\u7F46\u7F47\u7F48"+ - "\u7F49\u7F4A\u7F4B\u7F4C\u7F4D\u7F4E\u7F4F\u7F52"+ - "\u7F53\u9988\u6127\u6E83\u5764\u6606\u6346\u56F0"+ - "\u62EC\u6269\u5ED3\u9614\u5783\u62C9\u5587\u8721"+ - "\u814A\u8FA3\u5566\u83B1\u6765\u8D56\u84DD\u5A6A"+ - "\u680F\u62E6\u7BEE\u9611\u5170\u6F9C\u8C30\u63FD"+ - "\u89C8\u61D2\u7F06\u70C2\u6EE5\u7405\u6994\u72FC"+ - "\u5ECA\u90CE\u6717\u6D6A\u635E\u52B3\u7262\u8001"+ - "\u4F6C\u59E5\u916A\u70D9\u6D9D\u52D2\u4E50\u96F7"+ - "\u956D\u857E\u78CA\u7D2F\u5121\u5792\u64C2\u808B"+ - "\u7C7B\u6CEA\u68F1\u695E\u51B7\u5398\u68A8\u7281"+ - "\u9ECE\u7BF1\u72F8\u79BB\u6F13\u7406\u674E\u91CC"+ - "\u9CA4\u793C\u8389\u8354\u540F\u6817\u4E3D\u5389"+ - "\u52B1\u783E\u5386\u5229\u5088\u4F8B\u4FD0\u7F56"+ - "\u7F59\u7F5B\u7F5C\u7F5D\u7F5E\u7F60\u7F63\u7F64"+ - "\u7F65\u7F66\u7F67\u7F6B\u7F6C\u7F6D\u7F6F\u7F70"+ - "\u7F73\u7F75\u7F76\u7F77\u7F78\u7F7A\u7F7B\u7F7C"+ - "\u7F7D\u7F7F\u7F80\u7F82\u7F83\u7F84\u7F85\u7F86"+ - "\u7F87\u7F88\u7F89\u7F8B\u7F8D\u7F8F\u7F90\u7F91"+ - "\u7F92\u7F93\u7F95\u7F96\u7F97\u7F98\u7F99\u7F9B"+ - "\u7F9C\u7FA0\u7FA2\u7FA3\u7FA5\u7FA6\u7FA8\u7FA9"+ - "\u7FAA\u7FAB\u7FAC\u7FAD\u7FAE\u7FB1\uFFFD\u7FB3"+ - "\u7FB4\u7FB5\u7FB6\u7FB7\u7FBA\u7FBB\u7FBE\u7FC0"+ - "\u7FC2\u7FC3\u7FC4\u7FC6\u7FC7\u7FC8\u7FC9\u7FCB"+ - "\u7FCD\u7FCF\u7FD0\u7FD1\u7FD2\u7FD3\u7FD6\u7FD7"+ - "\u7FD9\u7FDA\u7FDB\u7FDC\u7FDD\u7FDE\u7FE2\u7FE3"+ - "\u75E2\u7ACB\u7C92\u6CA5\u96B6\u529B\u7483\u54E9"+ - "\u4FE9\u8054\u83B2\u8FDE\u9570\u5EC9\u601C\u6D9F"+ - "\u5E18\u655B\u8138\u94FE\u604B\u70BC\u7EC3\u7CAE"+ - "\u51C9\u6881\u7CB1\u826F\u4E24\u8F86\u91CF\u667E"+ - "\u4EAE\u8C05\u64A9\u804A\u50DA\u7597\u71CE\u5BE5"+ - "\u8FBD\u6F66\u4E86\u6482\u9563\u5ED6\u6599\u5217"+ - "\u88C2\u70C8\u52A3\u730E\u7433\u6797\u78F7\u9716"+ - "\u4E34\u90BB\u9CDE\u6DCB\u51DB\u8D41\u541D\u62CE"+ - "\u73B2\u83F1\u96F6\u9F84\u94C3\u4F36\u7F9A\u51CC"+ - "\u7075\u9675\u5CAD\u9886\u53E6\u4EE4\u6E9C\u7409"+ - "\u69B4\u786B\u998F\u7559\u5218\u7624\u6D41\u67F3"+ - "\u516D\u9F99\u804B\u5499\u7B3C\u7ABF\u7FE4\u7FE7"+ - "\u7FE8\u7FEA\u7FEB\u7FEC\u7FED\u7FEF\u7FF2\u7FF4"+ - "\u7FF5\u7FF6\u7FF7\u7FF8\u7FF9\u7FFA\u7FFD\u7FFE"+ - "\u7FFF\u8002\u8007\u8008\u8009\u800A\u800E\u800F"+ - "\u8011\u8013\u801A\u801B\u801D\u801E\u801F\u8021"+ - "\u8023\u8024\u802B\u802C\u802D\u802E\u802F\u8030"+ - "\u8032\u8034\u8039\u803A\u803C\u803E\u8040\u8041"+ - "\u8044\u8045\u8047\u8048\u8049\u804E\u804F\u8050"+ - "\u8051\u8053\u8055\u8056\u8057\uFFFD\u8059\u805B"+ - "\u805C\u805D\u805E\u805F\u8060\u8061\u8062\u8063"+ - "\u8064\u8065\u8066\u8067\u8068\u806B\u806C\u806D"+ - "\u806E\u806F\u8070\u8072\u8073\u8074\u8075\u8076"+ - "\u8077\u8078\u8079\u807A\u807B\u807C\u807D\u9686"+ - "\u5784\u62E2\u9647\u697C\u5A04\u6402\u7BD3\u6F0F"+ - "\u964B\u82A6\u5362\u9885\u5E90\u7089\u63B3\u5364"+ - "\u864F\u9C81\u9E93\u788C\u9732\u8DEF\u8D42\u9E7F"+ - "\u6F5E\u7984\u5F55\u9646\u622E\u9A74\u5415\u94DD"+ - "\u4FA3\u65C5\u5C65\u5C61\u7F15\u8651\u6C2F\u5F8B"+ - "\u7387\u6EE4\u7EFF\u5CE6\u631B\u5B6A\u6EE6\u5375"+ - "\u4E71\u63A0\u7565\u62A1\u8F6E\u4F26\u4ED1\u6CA6"+ - "\u7EB6\u8BBA\u841D\u87BA\u7F57\u903B\u9523\u7BA9"+ - "\u9AA1\u88F8\u843D\u6D1B\u9A86\u7EDC\u5988\u9EBB"+ - "\u739B\u7801\u8682\u9A6C\u9A82\u561B\u5417\u57CB"+ - "\u4E70\u9EA6\u5356\u8FC8\u8109\u7792\u9992\u86EE"+ - "\u6EE1\u8513\u66FC\u6162\u6F2B\u807E\u8081\u8082"+ - "\u8085\u8088\u808A\u808D\u808E\u808F\u8090\u8091"+ - "\u8092\u8094\u8095\u8097\u8099\u809E\u80A3\u80A6"+ - "\u80A7\u80A8\u80AC\u80B0\u80B3\u80B5\u80B6\u80B8"+ - "\u80B9\u80BB\u80C5\u80C7\u80C8\u80C9\u80CA\u80CB"+ - "\u80CF\u80D0\u80D1\u80D2\u80D3\u80D4\u80D5\u80D8"+ - "\u80DF\u80E0\u80E2\u80E3\u80E6\u80EE\u80F5\u80F7"+ - "\u80F9\u80FB\u80FE\u80FF\u8100\u8101\u8103\u8104"+ - "\u8105\u8107\u8108\u810B\uFFFD\u810C\u8115\u8117"+ - "\u8119\u811B\u811C\u811D\u811F\u8120\u8121\u8122"+ - "\u8123\u8124\u8125\u8126\u8127\u8128\u8129\u812A"+ - "\u812B\u812D\u812E\u8130\u8133\u8134\u8135\u8137"+ - "\u8139\u813A\u813B\u813C\u813D\u813F\u8C29\u8292"+ - "\u832B\u76F2\u6C13\u5FD9\u83BD\u732B\u8305\u951A"+ - "\u6BDB\u77DB\u94C6\u536F\u8302\u5192\u5E3D\u8C8C"+ - "\u8D38\u4E48\u73AB\u679A\u6885\u9176\u9709\u7164"+ - "\u6CA1\u7709\u5A92\u9541\u6BCF\u7F8E\u6627\u5BD0"+ - "\u59B9\u5A9A\u95E8\u95F7\u4EEC\u840C\u8499\u6AAC"+ - "\u76DF\u9530\u731B\u68A6\u5B5F\u772F\u919A\u9761"+ - "\u7CDC\u8FF7\u8C1C\u5F25\u7C73\u79D8\u89C5\u6CCC"+ - "\u871C\u5BC6\u5E42\u68C9\u7720\u7EF5\u5195\u514D"+ - "\u52C9\u5A29\u7F05\u9762\u82D7\u63CF\u7784\u85D0"+ - "\u79D2\u6E3A\u5E99\u5999\u8511\u706D\u6C11\u62BF"+ - "\u76BF\u654F\u60AF\u95FD\u660E\u879F\u9E23\u94ED"+ - "\u540D\u547D\u8C2C\u6478\u8140\u8141\u8142\u8143"+ - "\u8144\u8145\u8147\u8149\u814D\u814E\u814F\u8152"+ - "\u8156\u8157\u8158\u815B\u815C\u815D\u815E\u815F"+ - "\u8161\u8162\u8163\u8164\u8166\u8168\u816A\u816B"+ - "\u816C\u816F\u8172\u8173\u8175\u8176\u8177\u8178"+ - "\u8181\u8183\u8184\u8185\u8186\u8187\u8189\u818B"+ - "\u818C\u818D\u818E\u8190\u8192\u8193\u8194\u8195"+ - "\u8196\u8197\u8199\u819A\u819E\u819F\u81A0\u81A1"+ - "\u81A2\u81A4\u81A5\uFFFD\u81A7\u81A9\u81AB\u81AC"+ - "\u81AD\u81AE\u81AF\u81B0\u81B1\u81B2\u81B4\u81B5"+ - "\u81B6\u81B7\u81B8\u81B9\u81BC\u81BD\u81BE\u81BF"+ - "\u81C4\u81C5\u81C7\u81C8\u81C9\u81CB\u81CD\u81CE"+ - "\u81CF\u81D0\u81D1\u81D2\u81D3\u6479\u8611\u6A21"+ - "\u819C\u78E8\u6469\u9B54\u62B9\u672B\u83AB\u58A8"+ - "\u9ED8\u6CAB\u6F20\u5BDE\u964C\u8C0B\u725F\u67D0"+ - "\u62C7\u7261\u4EA9\u59C6\u6BCD\u5893\u66AE\u5E55"+ - "\u52DF\u6155\u6728\u76EE\u7766\u7267\u7A46\u62FF"+ - "\u54EA\u5450\u94A0\u90A3\u5A1C\u7EB3\u6C16\u4E43"+ - "\u5976\u8010\u5948\u5357\u7537\u96BE\u56CA\u6320"+ - "\u8111\u607C\u95F9\u6DD6\u5462\u9981\u5185\u5AE9"+ - "\u80FD\u59AE\u9713\u502A\u6CE5\u5C3C\u62DF\u4F60"+ - "\u533F\u817B\u9006\u6EBA\u852B\u62C8\u5E74\u78BE"+ - "\u64B5\u637B\u5FF5\u5A18\u917F\u9E1F\u5C3F\u634F"+ - "\u8042\u5B7D\u556E\u954A\u954D\u6D85\u60A8\u67E0"+ - "\u72DE\u51DD\u5B81\u81D4\u81D5\u81D6\u81D7\u81D8"+ - "\u81D9\u81DA\u81DB\u81DC\u81DD\u81DE\u81DF\u81E0"+ - "\u81E1\u81E2\u81E4\u81E5\u81E6\u81E8\u81E9\u81EB"+ - "\u81EE\u81EF\u81F0\u81F1\u81F2\u81F5\u81F6\u81F7"+ - "\u81F8\u81F9\u81FA\u81FD\u81FF\u8203\u8207\u8208"+ - "\u8209\u820A\u820B\u820E\u820F\u8211\u8213\u8215"+ - "\u8216\u8217\u8218\u8219\u821A\u821D\u8220\u8224"+ - "\u8225\u8226\u8227\u8229\u822E\u8232\u823A\u823C"+ - "\u823D\u823F\uFFFD\u8240\u8241\u8242\u8243\u8245"+ - "\u8246\u8248\u824A\u824C\u824D\u824E\u8250\u8251"+ - "\u8252\u8253\u8254\u8255\u8256\u8257\u8259\u825B"+ - "\u825C\u825D\u825E\u8260\u8261\u8262\u8263\u8264"+ - "\u8265\u8266\u8267\u8269\u62E7\u6CDE\u725B\u626D"+ - "\u94AE\u7EBD\u8113\u6D53\u519C\u5F04\u5974\u52AA"+ - "\u6012\u5973\u6696\u8650\u759F\u632A\u61E6\u7CEF"+ - "\u8BFA\u54E6\u6B27\u9E25\u6BB4\u85D5\u5455\u5076"+ - "\u6CA4\u556A\u8DB4\u722C\u5E15\u6015\u7436\u62CD"+ - "\u6392\u724C\u5F98\u6E43\u6D3E\u6500\u6F58\u76D8"+ - "\u78D0\u76FC\u7554\u5224\u53DB\u4E53\u5E9E\u65C1"+ - "\u802A\u80D6\u629B\u5486\u5228\u70AE\u888D\u8DD1"+ - "\u6CE1\u5478\u80DA\u57F9\u88F4\u8D54\u966A\u914D"+ - "\u4F69\u6C9B\u55B7\u76C6\u7830\u62A8\u70F9\u6F8E"+ - "\u5F6D\u84EC\u68DA\u787C\u7BF7\u81A8\u670B\u9E4F"+ - "\u6367\u78B0\u576F\u7812\u9739\u6279\u62AB\u5288"+ - "\u7435\u6BD7\u826A\u826B\u826C\u826D\u8271\u8275"+ - "\u8276\u8277\u8278\u827B\u827C\u8280\u8281\u8283"+ - "\u8285\u8286\u8287\u8289\u828C\u8290\u8293\u8294"+ - "\u8295\u8296\u829A\u829B\u829E\u82A0\u82A2\u82A3"+ - "\u82A7\u82B2\u82B5\u82B6\u82BA\u82BB\u82BC\u82BF"+ - "\u82C0\u82C2\u82C3\u82C5\u82C6\u82C9\u82D0\u82D6"+ - "\u82D9\u82DA\u82DD\u82E2\u82E7\u82E8\u82E9\u82EA"+ - "\u82EC\u82ED\u82EE\u82F0\u82F2\u82F3\u82F5\u82F6"+ - "\u82F8\uFFFD\u82FA\u82FC\u82FD\u82FE\u82FF\u8300"+ - "\u830A\u830B\u830D\u8310\u8312\u8313\u8316\u8318"+ - "\u8319\u831D\u831E\u831F\u8320\u8321\u8322\u8323"+ - "\u8324\u8325\u8326\u8329\u832A\u832E\u8330\u8332"+ - "\u8337\u833B\u833D\u5564\u813E\u75B2\u76AE\u5339"+ - "\u75DE\u50FB\u5C41\u8B6C\u7BC7\u504F\u7247\u9A97"+ - "\u98D8\u6F02\u74E2\u7968\u6487\u77A5\u62FC\u9891"+ - "\u8D2B\u54C1\u8058\u4E52\u576A\u82F9\u840D\u5E73"+ - "\u51ED\u74F6\u8BC4\u5C4F\u5761\u6CFC\u9887\u5A46"+ - "\u7834\u9B44\u8FEB\u7C95\u5256\u6251\u94FA\u4EC6"+ - "\u8386\u8461\u83E9\u84B2\u57D4\u6734\u5703\u666E"+ - "\u6D66\u8C31\u66DD\u7011\u671F\u6B3A\u6816\u621A"+ - "\u59BB\u4E03\u51C4\u6F06\u67D2\u6C8F\u5176\u68CB"+ - "\u5947\u6B67\u7566\u5D0E\u8110\u9F50\u65D7\u7948"+ - "\u7941\u9A91\u8D77\u5C82\u4E5E\u4F01\u542F\u5951"+ - "\u780C\u5668\u6C14\u8FC4\u5F03\u6C7D\u6CE3\u8BAB"+ - "\u6390\u833E\u833F\u8341\u8342\u8344\u8345\u8348"+ - "\u834A\u834B\u834C\u834D\u834E\u8353\u8355\u8356"+ - "\u8357\u8358\u8359\u835D\u8362\u8370\u8371\u8372"+ - "\u8373\u8374\u8375\u8376\u8379\u837A\u837E\u837F"+ - "\u8380\u8381\u8382\u8383\u8384\u8387\u8388\u838A"+ - "\u838B\u838C\u838D\u838F\u8390\u8391\u8394\u8395"+ - "\u8396\u8397\u8399\u839A\u839D\u839F\u83A1\u83A2"+ - "\u83A3\u83A4\u83A5\u83A6\u83A7\u83AC\u83AD\u83AE"+ - "\uFFFD\u83AF\u83B5\u83BB\u83BE\u83BF\u83C2\u83C3"+ - "\u83C4\u83C6\u83C8\u83C9\u83CB\u83CD\u83CE\u83D0"+ - "\u83D1\u83D2\u83D3\u83D5\u83D7\u83D9\u83DA\u83DB"+ - "\u83DE\u83E2\u83E3\u83E4\u83E6\u83E7\u83E8\u83EB"+ - "\u83EC\u83ED\u6070\u6D3D\u7275\u6266\u948E\u94C5"+ - "\u5343\u8FC1\u7B7E\u4EDF\u8C26\u4E7E\u9ED4\u94B1"+ - "\u94B3\u524D\u6F5C\u9063\u6D45\u8C34\u5811\u5D4C"+ - "\u6B20\u6B49\u67AA\u545B\u8154\u7F8C\u5899\u8537"+ - "\u5F3A\u62A2\u6A47\u9539\u6572\u6084\u6865\u77A7"+ - "\u4E54\u4FA8\u5DE7\u9798\u64AC\u7FD8\u5CED\u4FCF"+ - "\u7A8D\u5207\u8304\u4E14\u602F\u7A83\u94A6\u4FB5"+ - "\u4EB2\u79E6\u7434\u52E4\u82B9\u64D2\u79BD\u5BDD"+ - "\u6C81\u9752\u8F7B\u6C22\u503E\u537F\u6E05\u64CE"+ - "\u6674\u6C30\u60C5\u9877\u8BF7\u5E86\u743C\u7A77"+ - "\u79CB\u4E18\u90B1\u7403\u6C42\u56DA\u914B\u6CC5"+ - "\u8D8B\u533A\u86C6\u66F2\u8EAF\u5C48\u9A71\u6E20"+ - "\u83EE\u83EF\u83F3\u83F4\u83F5\u83F6\u83F7\u83FA"+ - "\u83FB\u83FC\u83FE\u83FF\u8400\u8402\u8405\u8407"+ - "\u8408\u8409\u840A\u8410\u8412\u8413\u8414\u8415"+ - "\u8416\u8417\u8419\u841A\u841B\u841E\u841F\u8420"+ - "\u8421\u8422\u8423\u8429\u842A\u842B\u842C\u842D"+ - "\u842E\u842F\u8430\u8432\u8433\u8434\u8435\u8436"+ - "\u8437\u8439\u843A\u843B\u843E\u843F\u8440\u8441"+ - "\u8442\u8443\u8444\u8445\u8447\u8448\u8449\uFFFD"+ - "\u844A\u844B\u844C\u844D\u844E\u844F\u8450\u8452"+ - "\u8453\u8454\u8455\u8456\u8458\u845D\u845E\u845F"+ - "\u8460\u8462\u8464\u8465\u8466\u8467\u8468\u846A"+ - "\u846E\u846F\u8470\u8472\u8474\u8477\u8479\u847B"+ - "\u847C\u53D6\u5A36\u9F8B\u8DA3\u53BB\u5708\u98A7"+ - "\u6743\u919B\u6CC9\u5168\u75CA\u62F3\u72AC\u5238"+ - "\u529D\u7F3A\u7094\u7638\u5374\u9E4A\u69B7\u786E"+ - "\u96C0\u88D9\u7FA4\u7136\u71C3\u5189\u67D3\u74E4"+ - "\u58E4\u6518\u56B7\u8BA9\u9976\u6270\u7ED5\u60F9"+ - "\u70ED\u58EC\u4EC1\u4EBA\u5FCD\u97E7\u4EFB\u8BA4"+ - "\u5203\u598A\u7EAB\u6254\u4ECD\u65E5\u620E\u8338"+ - "\u84C9\u8363\u878D\u7194\u6EB6\u5BB9\u7ED2\u5197"+ - "\u63C9\u67D4\u8089\u8339\u8815\u5112\u5B7A\u5982"+ - "\u8FB1\u4E73\u6C5D\u5165\u8925\u8F6F\u962E\u854A"+ - "\u745E\u9510\u95F0\u6DA6\u82E5\u5F31\u6492\u6D12"+ - "\u8428\u816E\u9CC3\u585E\u8D5B\u4E09\u53C1\u847D"+ - "\u847E\u847F\u8480\u8481\u8483\u8484\u8485\u8486"+ - "\u848A\u848D\u848F\u8490\u8491\u8492\u8493\u8494"+ - "\u8495\u8496\u8498\u849A\u849B\u849D\u849E\u849F"+ - "\u84A0\u84A2\u84A3\u84A4\u84A5\u84A6\u84A7\u84A8"+ - "\u84A9\u84AA\u84AB\u84AC\u84AD\u84AE\u84B0\u84B1"+ - "\u84B3\u84B5\u84B6\u84B7\u84BB\u84BC\u84BE\u84C0"+ - "\u84C2\u84C3\u84C5\u84C6\u84C7\u84C8\u84CB\u84CC"+ - "\u84CE\u84CF\u84D2\u84D4\u84D5\u84D7\uFFFD\u84D8"+ - "\u84D9\u84DA\u84DB\u84DC\u84DE\u84E1\u84E2\u84E4"+ - "\u84E7\u84E8\u84E9\u84EA\u84EB\u84ED\u84EE\u84EF"+ - "\u84F1\u84F2\u84F3\u84F4\u84F5\u84F6\u84F7\u84F8"+ - "\u84F9\u84FA\u84FB\u84FD\u84FE\u8500\u8501\u8502"+ - "\u4F1E\u6563\u6851\u55D3\u4E27\u6414\u9A9A\u626B"+ - "\u5AC2\u745F\u8272\u6DA9\u68EE\u50E7\u838E\u7802"+ - "\u6740\u5239\u6C99\u7EB1\u50BB\u5565\u715E\u7B5B"+ - "\u6652\u73CA\u82EB\u6749\u5C71\u5220\u717D\u886B"+ - "\u95EA\u9655\u64C5\u8D61\u81B3\u5584\u6C55\u6247"+ - "\u7F2E\u5892\u4F24\u5546\u8D4F\u664C\u4E0A\u5C1A"+ - "\u88F3\u68A2\u634E\u7A0D\u70E7\u828D\u52FA\u97F6"+ - "\u5C11\u54E8\u90B5\u7ECD\u5962\u8D4A\u86C7\u820C"+ - "\u820D\u8D66\u6444\u5C04\u6151\u6D89\u793E\u8BBE"+ - "\u7837\u7533\u547B\u4F38\u8EAB\u6DF1\u5A20\u7EC5"+ - "\u795E\u6C88\u5BA1\u5A76\u751A\u80BE\u614E\u6E17"+ - "\u58F0\u751F\u7525\u7272\u5347\u7EF3\u8503\u8504"+ - "\u8505\u8506\u8507\u8508\u8509\u850A\u850B\u850D"+ - "\u850E\u850F\u8510\u8512\u8514\u8515\u8516\u8518"+ - "\u8519\u851B\u851C\u851D\u851E\u8520\u8522\u8523"+ - "\u8524\u8525\u8526\u8527\u8528\u8529\u852A\u852D"+ - "\u852E\u852F\u8530\u8531\u8532\u8533\u8534\u8535"+ - "\u8536\u853E\u853F\u8540\u8541\u8542\u8544\u8545"+ - "\u8546\u8547\u854B\u854C\u854D\u854E\u854F\u8550"+ - "\u8551\u8552\u8553\u8554\u8555\uFFFD\u8557\u8558"+ - "\u855A\u855B\u855C\u855D\u855F\u8560\u8561\u8562"+ - "\u8563\u8565\u8566\u8567\u8569\u856A\u856B\u856C"+ - "\u856D\u856E\u856F\u8570\u8571\u8573\u8575\u8576"+ - "\u8577\u8578\u857C\u857D\u857F\u8580\u8581\u7701"+ - "\u76DB\u5269\u80DC\u5723\u5E08\u5931\u72EE\u65BD"+ - "\u6E7F\u8BD7\u5C38\u8671\u5341\u77F3\u62FE\u65F6"+ - "\u4EC0\u98DF\u8680\u5B9E\u8BC6\u53F2\u77E2\u4F7F"+ - "\u5C4E\u9A76\u59CB\u5F0F\u793A\u58EB\u4E16\u67FF"+ - "\u4E8B\u62ED\u8A93\u901D\u52BF\u662F\u55DC\u566C"+ - "\u9002\u4ED5\u4F8D\u91CA\u9970\u6C0F\u5E02\u6043"+ - "\u5BA4\u89C6\u8BD5\u6536\u624B\u9996\u5B88\u5BFF"+ - "\u6388\u552E\u53D7\u7626\u517D\u852C\u67A2\u68B3"+ - "\u6B8A\u6292\u8F93\u53D4\u8212\u6DD1\u758F\u4E66"+ - "\u8D4E\u5B70\u719F\u85AF\u6691\u66D9\u7F72\u8700"+ - "\u9ECD\u9F20\u5C5E\u672F\u8FF0\u6811\u675F\u620D"+ - "\u7AD6\u5885\u5EB6\u6570\u6F31\u8582\u8583\u8586"+ - "\u8588\u8589\u858A\u858B\u858C\u858D\u858E\u8590"+ - "\u8591\u8592\u8593\u8594\u8595\u8596\u8597\u8598"+ - "\u8599\u859A\u859D\u859E\u859F\u85A0\u85A1\u85A2"+ - "\u85A3\u85A5\u85A6\u85A7\u85A9\u85AB\u85AC\u85AD"+ - "\u85B1\u85B2\u85B3\u85B4\u85B5\u85B6\u85B8\u85BA"+ - "\u85BB\u85BC\u85BD\u85BE\u85BF\u85C0\u85C2\u85C3"+ - "\u85C4\u85C5\u85C6\u85C7\u85C8\u85CA\u85CB\u85CC"+ - "\u85CD\u85CE\u85D1\u85D2\uFFFD\u85D4\u85D6\u85D7"+ - "\u85D8\u85D9\u85DA\u85DB\u85DD\u85DE\u85DF\u85E0"+ - "\u85E1\u85E2\u85E3\u85E5\u85E6\u85E7\u85E8\u85EA"+ - "\u85EB\u85EC\u85ED\u85EE\u85EF\u85F0\u85F1\u85F2"+ - "\u85F3\u85F4\u85F5\u85F6\u85F7\u85F8\u6055\u5237"+ - "\u800D\u6454\u8870\u7529\u5E05\u6813\u62F4\u971C"+ - "\u53CC\u723D\u8C01\u6C34\u7761\u7A0E\u542E\u77AC"+ - "\u987A\u821C\u8BF4\u7855\u6714\u70C1\u65AF\u6495"+ - "\u5636\u601D\u79C1\u53F8\u4E1D\u6B7B\u8086\u5BFA"+ - "\u55E3\u56DB\u4F3A\u4F3C\u9972\u5DF3\u677E\u8038"+ - "\u6002\u9882\u9001\u5B8B\u8BBC\u8BF5\u641C\u8258"+ - "\u64DE\u55FD\u82CF\u9165\u4FD7\u7D20\u901F\u7C9F"+ - "\u50F3\u5851\u6EAF\u5BBF\u8BC9\u8083\u9178\u849C"+ - "\u7B97\u867D\u968B\u968F\u7EE5\u9AD3\u788E\u5C81"+ - "\u7A57\u9042\u96A7\u795F\u5B59\u635F\u7B0B\u84D1"+ - "\u68AD\u5506\u7F29\u7410\u7D22\u9501\u6240\u584C"+ - "\u4ED6\u5B83\u5979\u5854\u85F9\u85FA\u85FC\u85FD"+ - "\u85FE\u8600\u8601\u8602\u8603\u8604\u8606\u8607"+ - "\u8608\u8609\u860A\u860B\u860C\u860D\u860E\u860F"+ - "\u8610\u8612\u8613\u8614\u8615\u8617\u8618\u8619"+ - "\u861A\u861B\u861C\u861D\u861E\u861F\u8620\u8621"+ - "\u8622\u8623\u8624\u8625\u8626\u8628\u862A\u862B"+ - "\u862C\u862D\u862E\u862F\u8630\u8631\u8632\u8633"+ - "\u8634\u8635\u8636\u8637\u8639\u863A\u863B\u863D"+ - "\u863E\u863F\u8640\uFFFD\u8641\u8642\u8643\u8644"+ - "\u8645\u8646\u8647\u8648\u8649\u864A\u864B\u864C"+ - "\u8652\u8653\u8655\u8656\u8657\u8658\u8659\u865B"+ - "\u865C\u865D\u865F\u8660\u8661\u8663\u8664\u8665"+ - "\u8666\u8667\u8668\u8669\u866A\u736D\u631E\u8E4B"+ - "\u8E0F\u80CE\u82D4\u62AC\u53F0\u6CF0\u915E\u592A"+ - "\u6001\u6C70\u574D\u644A\u8D2A\u762B\u6EE9\u575B"+ - "\u6A80\u75F0\u6F6D\u8C2D\u8C08\u5766\u6BEF\u8892"+ - "\u78B3\u63A2\u53F9\u70AD\u6C64\u5858\u642A\u5802"+ - "\u68E0\u819B\u5510\u7CD6\u5018\u8EBA\u6DCC\u8D9F"+ - "\u70EB\u638F\u6D9B\u6ED4\u7EE6\u8404\u6843\u9003"+ - "\u6DD8\u9676\u8BA8\u5957\u7279\u85E4\u817E\u75BC"+ - "\u8A8A\u68AF\u5254\u8E22\u9511\u63D0\u9898\u8E44"+ - "\u557C\u4F53\u66FF\u568F\u60D5\u6D95\u5243\u5C49"+ - "\u5929\u6DFB\u586B\u7530\u751C\u606C\u8214\u8146"+ - "\u6311\u6761\u8FE2\u773A\u8DF3\u8D34\u94C1\u5E16"+ - "\u5385\u542C\u70C3\u866D\u866F\u8670\u8672\u8673"+ - "\u8674\u8675\u8676\u8677\u8678\u8683\u8684\u8685"+ - "\u8686\u8687\u8688\u8689\u868E\u868F\u8690\u8691"+ - "\u8692\u8694\u8696\u8697\u8698\u8699\u869A\u869B"+ - "\u869E\u869F\u86A0\u86A1\u86A2\u86A5\u86A6\u86AB"+ - "\u86AD\u86AE\u86B2\u86B3\u86B7\u86B8\u86B9\u86BB"+ - "\u86BC\u86BD\u86BE\u86BF\u86C1\u86C2\u86C3\u86C5"+ - "\u86C8\u86CC\u86CD\u86D2\u86D3\u86D5\u86D6\u86D7"+ - "\u86DA\u86DC\uFFFD\u86DD\u86E0\u86E1\u86E2\u86E3"+ - "\u86E5\u86E6\u86E7\u86E8\u86EA\u86EB\u86EC\u86EF"+ - "\u86F5\u86F6\u86F7\u86FA\u86FB\u86FC\u86FD\u86FF"+ - "\u8701\u8704\u8705\u8706\u870B\u870C\u870E\u870F"+ - "\u8710\u8711\u8714\u8716\u6C40\u5EF7\u505C\u4EAD"+ - "\u5EAD\u633A\u8247\u901A\u6850\u916E\u77B3\u540C"+ - "\u94DC\u5F64\u7AE5\u6876\u6345\u7B52\u7EDF\u75DB"+ - "\u5077\u6295\u5934\u900F\u51F8\u79C3\u7A81\u56FE"+ - "\u5F92\u9014\u6D82\u5C60\u571F\u5410\u5154\u6E4D"+ - "\u56E2\u63A8\u9893\u817F\u8715\u892A\u9000\u541E"+ - "\u5C6F\u81C0\u62D6\u6258\u8131\u9E35\u9640\u9A6E"+ - "\u9A7C\u692D\u59A5\u62D3\u553E\u6316\u54C7\u86D9"+ - "\u6D3C\u5A03\u74E6\u889C\u6B6A\u5916\u8C4C\u5F2F"+ - "\u6E7E\u73A9\u987D\u4E38\u70F7\u5B8C\u7897\u633D"+ - "\u665A\u7696\u60CB\u5B9B\u5A49\u4E07\u8155\u6C6A"+ - "\u738B\u4EA1\u6789\u7F51\u5F80\u65FA\u671B\u5FD8"+ - "\u5984\u5A01\u8719\u871B\u871D\u871F\u8720\u8724"+ - "\u8726\u8727\u8728\u872A\u872B\u872C\u872D\u872F"+ - "\u8730\u8732\u8733\u8735\u8736\u8738\u8739\u873A"+ - "\u873C\u873D\u8740\u8741\u8742\u8743\u8744\u8745"+ - "\u8746\u874A\u874B\u874D\u874F\u8750\u8751\u8752"+ - "\u8754\u8755\u8756\u8758\u875A\u875B\u875C\u875D"+ - "\u875E\u875F\u8761\u8762\u8766\u8767\u8768\u8769"+ - "\u876A\u876B\u876C\u876D\u876F\u8771\u8772\u8773"+ - "\u8775\uFFFD\u8777\u8778\u8779\u877A\u877F\u8780"+ - "\u8781\u8784\u8786\u8787\u8789\u878A\u878C\u878E"+ - "\u878F\u8790\u8791\u8792\u8794\u8795\u8796\u8798"+ - "\u8799\u879A\u879B\u879C\u879D\u879E\u87A0\u87A1"+ - "\u87A2\u87A3\u87A4\u5DCD\u5FAE\u5371\u97E6\u8FDD"+ - "\u6845\u56F4\u552F\u60DF\u4E3A\u6F4D\u7EF4\u82C7"+ - "\u840E\u59D4\u4F1F\u4F2A\u5C3E\u7EAC\u672A\u851A"+ - "\u5473\u754F\u80C3\u5582\u9B4F\u4F4D\u6E2D\u8C13"+ - "\u5C09\u6170\u536B\u761F\u6E29\u868A\u6587\u95FB"+ - "\u7EB9\u543B\u7A33\u7D0A\u95EE\u55E1\u7FC1\u74EE"+ - "\u631D\u8717\u6DA1\u7A9D\u6211\u65A1\u5367\u63E1"+ - "\u6C83\u5DEB\u545C\u94A8\u4E4C\u6C61\u8BEC\u5C4B"+ - "\u65E0\u829C\u68A7\u543E\u5434\u6BCB\u6B66\u4E94"+ - "\u6342\u5348\u821E\u4F0D\u4FAE\u575E\u620A\u96FE"+ - "\u6664\u7269\u52FF\u52A1\u609F\u8BEF\u6614\u7199"+ - "\u6790\u897F\u7852\u77FD\u6670\u563B\u5438\u9521"+ - "\u727A\u87A5\u87A6\u87A7\u87A9\u87AA\u87AE\u87B0"+ - "\u87B1\u87B2\u87B4\u87B6\u87B7\u87B8\u87B9\u87BB"+ - "\u87BC\u87BE\u87BF\u87C1\u87C2\u87C3\u87C4\u87C5"+ - "\u87C7\u87C8\u87C9\u87CC\u87CD\u87CE\u87CF\u87D0"+ - "\u87D4\u87D5\u87D6\u87D7\u87D8\u87D9\u87DA\u87DC"+ - "\u87DD\u87DE\u87DF\u87E1\u87E2\u87E3\u87E4\u87E6"+ - "\u87E7\u87E8\u87E9\u87EB\u87EC\u87ED\u87EF\u87F0"+ - "\u87F1\u87F2\u87F3\u87F4\u87F5\u87F6\u87F7\u87F8"+ - "\uFFFD\u87FA\u87FB\u87FC\u87FD\u87FF\u8800\u8801"+ - "\u8802\u8804\u8805\u8806\u8807\u8808\u8809\u880B"+ - "\u880C\u880D\u880E\u880F\u8810\u8811\u8812\u8814"+ - "\u8817\u8818\u8819\u881A\u881C\u881D\u881E\u881F"+ - "\u8820\u8823\u7A00\u606F\u5E0C\u6089\u819D\u5915"+ - "\u60DC\u7184\u70EF\u6EAA\u6C50\u7280\u6A84\u88AD"+ - "\u5E2D\u4E60\u5AB3\u559C\u94E3\u6D17\u7CFB\u9699"+ - "\u620F\u7EC6\u778E\u867E\u5323\u971E\u8F96\u6687"+ - "\u5CE1\u4FA0\u72ED\u4E0B\u53A6\u590F\u5413\u6380"+ - "\u9528\u5148\u4ED9\u9C9C\u7EA4\u54B8\u8D24\u8854"+ - "\u8237\u95F2\u6D8E\u5F26\u5ACC\u663E\u9669\u73B0"+ - "\u732E\u53BF\u817A\u9985\u7FA1\u5BAA\u9677\u9650"+ - "\u7EBF\u76F8\u53A2\u9576\u9999\u7BB1\u8944\u6E58"+ - "\u4E61\u7FD4\u7965\u8BE6\u60F3\u54CD\u4EAB\u9879"+ - "\u5DF7\u6A61\u50CF\u5411\u8C61\u8427\u785D\u9704"+ - "\u524A\u54EE\u56A3\u9500\u6D88\u5BB5\u6DC6\u6653"; - - private static final String innerIndex5= - "\u8824\u8825\u8826\u8827\u8828\u8829\u882A\u882B"+ - "\u882C\u882D\u882E\u882F\u8830\u8831\u8833\u8834"+ - "\u8835\u8836\u8837\u8838\u883A\u883B\u883D\u883E"+ - "\u883F\u8841\u8842\u8843\u8846\u8847\u8848\u8849"+ - "\u884A\u884B\u884E\u884F\u8850\u8851\u8852\u8853"+ - "\u8855\u8856\u8858\u885A\u885B\u885C\u885D\u885E"+ - "\u885F\u8860\u8866\u8867\u886A\u886D\u886F\u8871"+ - "\u8873\u8874\u8875\u8876\u8878\u8879\u887A\uFFFD"+ - "\u887B\u887C\u8880\u8883\u8886\u8887\u8889\u888A"+ - "\u888C\u888E\u888F\u8890\u8891\u8893\u8894\u8895"+ - "\u8897\u8898\u8899\u889A\u889B\u889D\u889E\u889F"+ - "\u88A0\u88A1\u88A3\u88A5\u88A6\u88A7\u88A8\u88A9"+ - "\u88AA\u5C0F\u5B5D\u6821\u8096\u5578\u7B11\u6548"+ - "\u6954\u4E9B\u6B47\u874E\u978B\u534F\u631F\u643A"+ - "\u90AA\u659C\u80C1\u8C10\u5199\u68B0\u5378\u87F9"+ - "\u61C8\u6CC4\u6CFB\u8C22\u5C51\u85AA\u82AF\u950C"+ - "\u6B23\u8F9B\u65B0\u5FFB\u5FC3\u4FE1\u8845\u661F"+ - "\u8165\u7329\u60FA\u5174\u5211\u578B\u5F62\u90A2"+ - "\u884C\u9192\u5E78\u674F\u6027\u59D3\u5144\u51F6"+ - "\u80F8\u5308\u6C79\u96C4\u718A\u4F11\u4FEE\u7F9E"+ - "\u673D\u55C5\u9508\u79C0\u8896\u7EE3\u589F\u620C"+ - "\u9700\u865A\u5618\u987B\u5F90\u8BB8\u84C4\u9157"+ - "\u53D9\u65ED\u5E8F\u755C\u6064\u7D6E\u5A7F\u7EEA"+ - "\u7EED\u8F69\u55A7\u5BA3\u60AC\u65CB\u7384\u88AC"+ - "\u88AE\u88AF\u88B0\u88B2\u88B3\u88B4\u88B5\u88B6"+ - "\u88B8\u88B9\u88BA\u88BB\u88BD\u88BE\u88BF\u88C0"+ - "\u88C3\u88C4\u88C7\u88C8\u88CA\u88CB\u88CC\u88CD"+ - "\u88CF\u88D0\u88D1\u88D3\u88D6\u88D7\u88DA\u88DB"+ - "\u88DC\u88DD\u88DE\u88E0\u88E1\u88E6\u88E7\u88E9"+ - "\u88EA\u88EB\u88EC\u88ED\u88EE\u88EF\u88F2\u88F5"+ - "\u88F6\u88F7\u88FA\u88FB\u88FD\u88FF\u8900\u8901"+ - "\u8903\u8904\u8905\u8906\u8907\u8908\uFFFD\u8909"+ - "\u890B\u890C\u890D\u890E\u890F\u8911\u8914\u8915"+ - "\u8916\u8917\u8918\u891C\u891D\u891E\u891F\u8920"+ - "\u8922\u8923\u8924\u8926\u8927\u8928\u8929\u892C"+ - "\u892D\u892E\u892F\u8931\u8932\u8933\u8935\u8937"+ - "\u9009\u7663\u7729\u7EDA\u9774\u859B\u5B66\u7A74"+ - "\u96EA\u8840\u52CB\u718F\u5FAA\u65EC\u8BE2\u5BFB"+ - "\u9A6F\u5DE1\u6B89\u6C5B\u8BAD\u8BAF\u900A\u8FC5"+ - "\u538B\u62BC\u9E26\u9E2D\u5440\u4E2B\u82BD\u7259"+ - "\u869C\u5D16\u8859\u6DAF\u96C5\u54D1\u4E9A\u8BB6"+ - "\u7109\u54BD\u9609\u70DF\u6DF9\u76D0\u4E25\u7814"+ - "\u8712\u5CA9\u5EF6\u8A00\u989C\u960E\u708E\u6CBF"+ - "\u5944\u63A9\u773C\u884D\u6F14\u8273\u5830\u71D5"+ - "\u538C\u781A\u96C1\u5501\u5F66\u7130\u5BB4\u8C1A"+ - "\u9A8C\u6B83\u592E\u9E2F\u79E7\u6768\u626C\u4F6F"+ - "\u75A1\u7F8A\u6D0B\u9633\u6C27\u4EF0\u75D2\u517B"+ - "\u6837\u6F3E\u9080\u8170\u5996\u7476\u8938\u8939"+ - "\u893A\u893B\u893C\u893D\u893E\u893F\u8940\u8942"+ - "\u8943\u8945\u8946\u8947\u8948\u8949\u894A\u894B"+ - "\u894C\u894D\u894E\u894F\u8950\u8951\u8952\u8953"+ - "\u8954\u8955\u8956\u8957\u8958\u8959\u895A\u895B"+ - "\u895C\u895D\u8960\u8961\u8962\u8963\u8964\u8965"+ - "\u8967\u8968\u8969\u896A\u896B\u896C\u896D\u896E"+ - "\u896F\u8970\u8971\u8972\u8973\u8974\u8975\u8976"+ - "\u8977\u8978\u8979\u897A\u897C\uFFFD\u897D\u897E"+ - "\u8980\u8982\u8984\u8985\u8987\u8988\u8989\u898A"+ - "\u898B\u898C\u898D\u898E\u898F\u8990\u8991\u8992"+ - "\u8993\u8994\u8995\u8996\u8997\u8998\u8999\u899A"+ - "\u899B\u899C\u899D\u899E\u899F\u89A0\u89A1\u6447"+ - "\u5C27\u9065\u7A91\u8C23\u59DA\u54AC\u8200\u836F"+ - "\u8981\u8000\u6930\u564E\u8036\u7237\u91CE\u51B6"+ - "\u4E5F\u9875\u6396\u4E1A\u53F6\u66F3\u814B\u591C"+ - "\u6DB2\u4E00\u58F9\u533B\u63D6\u94F1\u4F9D\u4F0A"+ - "\u8863\u9890\u5937\u9057\u79FB\u4EEA\u80F0\u7591"+ - "\u6C82\u5B9C\u59E8\u5F5D\u6905\u8681\u501A\u5DF2"+ - "\u4E59\u77E3\u4EE5\u827A\u6291\u6613\u9091\u5C79"+ - "\u4EBF\u5F79\u81C6\u9038\u8084\u75AB\u4EA6\u88D4"+ - "\u610F\u6BC5\u5FC6\u4E49\u76CA\u6EA2\u8BE3\u8BAE"+ - "\u8C0A\u8BD1\u5F02\u7FFC\u7FCC\u7ECE\u8335\u836B"+ - "\u56E0\u6BB7\u97F3\u9634\u59FB\u541F\u94F6\u6DEB"+ - "\u5BC5\u996E\u5C39\u5F15\u9690\u89A2\u89A3\u89A4"+ - "\u89A5\u89A6\u89A7\u89A8\u89A9\u89AA\u89AB\u89AC"+ - "\u89AD\u89AE\u89AF\u89B0\u89B1\u89B2\u89B3\u89B4"+ - "\u89B5\u89B6\u89B7\u89B8\u89B9\u89BA\u89BB\u89BC"+ - "\u89BD\u89BE\u89BF\u89C0\u89C3\u89CD\u89D3\u89D4"+ - "\u89D5\u89D7\u89D8\u89D9\u89DB\u89DD\u89DF\u89E0"+ - "\u89E1\u89E2\u89E4\u89E7\u89E8\u89E9\u89EA\u89EC"+ - "\u89ED\u89EE\u89F0\u89F1\u89F2\u89F4\u89F5\u89F6"+ - "\u89F7\u89F8\u89F9\u89FA\uFFFD\u89FB\u89FC\u89FD"+ - "\u89FE\u89FF\u8A01\u8A02\u8A03\u8A04\u8A05\u8A06"+ - "\u8A08\u8A09\u8A0A\u8A0B\u8A0C\u8A0D\u8A0E\u8A0F"+ - "\u8A10\u8A11\u8A12\u8A13\u8A14\u8A15\u8A16\u8A17"+ - "\u8A18\u8A19\u8A1A\u8A1B\u8A1C\u8A1D\u5370\u82F1"+ - "\u6A31\u5A74\u9E70\u5E94\u7F28\u83B9\u8424\u8425"+ - "\u8367\u8747\u8FCE\u8D62\u76C8\u5F71\u9896\u786C"+ - "\u6620\u54DF\u62E5\u4F63\u81C3\u75C8\u5EB8\u96CD"+ - "\u8E0A\u86F9\u548F\u6CF3\u6D8C\u6C38\u607F\u52C7"+ - "\u7528\u5E7D\u4F18\u60A0\u5FE7\u5C24\u7531\u90AE"+ - "\u94C0\u72B9\u6CB9\u6E38\u9149\u6709\u53CB\u53F3"+ - "\u4F51\u91C9\u8BF1\u53C8\u5E7C\u8FC2\u6DE4\u4E8E"+ - "\u76C2\u6986\u865E\u611A\u8206\u4F59\u4FDE\u903E"+ - "\u9C7C\u6109\u6E1D\u6E14\u9685\u4E88\u5A31\u96E8"+ - "\u4E0E\u5C7F\u79B9\u5B87\u8BED\u7FBD\u7389\u57DF"+ - "\u828B\u90C1\u5401\u9047\u55BB\u5CEA\u5FA1\u6108"+ - "\u6B32\u72F1\u80B2\u8A89\u8A1E\u8A1F\u8A20\u8A21"+ - "\u8A22\u8A23\u8A24\u8A25\u8A26\u8A27\u8A28\u8A29"+ - "\u8A2A\u8A2B\u8A2C\u8A2D\u8A2E\u8A2F\u8A30\u8A31"+ - "\u8A32\u8A33\u8A34\u8A35\u8A36\u8A37\u8A38\u8A39"+ - "\u8A3A\u8A3B\u8A3C\u8A3D\u8A3F\u8A40\u8A41\u8A42"+ - "\u8A43\u8A44\u8A45\u8A46\u8A47\u8A49\u8A4A\u8A4B"+ - "\u8A4C\u8A4D\u8A4E\u8A4F\u8A50\u8A51\u8A52\u8A53"+ - "\u8A54\u8A55\u8A56\u8A57\u8A58\u8A59\u8A5A\u8A5B"+ - "\u8A5C\u8A5D\u8A5E\uFFFD\u8A5F\u8A60\u8A61\u8A62"+ - "\u8A63\u8A64\u8A65\u8A66\u8A67\u8A68\u8A69\u8A6A"+ - "\u8A6B\u8A6C\u8A6D\u8A6E\u8A6F\u8A70\u8A71\u8A72"+ - "\u8A73\u8A74\u8A75\u8A76\u8A77\u8A78\u8A7A\u8A7B"+ - "\u8A7C\u8A7D\u8A7E\u8A7F\u8A80\u6D74\u5BD3\u88D5"+ - "\u9884\u8C6B\u9A6D\u9E33\u6E0A\u51A4\u5143\u57A3"+ - "\u8881\u539F\u63F4\u8F95\u56ED\u5458\u5706\u733F"+ - "\u6E90\u7F18\u8FDC\u82D1\u613F\u6028\u9662\u66F0"+ - "\u7EA6\u8D8A\u8DC3\u94A5\u5CB3\u7CA4\u6708\u60A6"+ - "\u9605\u8018\u4E91\u90E7\u5300\u9668\u5141\u8FD0"+ - "\u8574\u915D\u6655\u97F5\u5B55\u531D\u7838\u6742"+ - "\u683D\u54C9\u707E\u5BB0\u8F7D\u518D\u5728\u54B1"+ - "\u6512\u6682\u8D5E\u8D43\u810F\u846C\u906D\u7CDF"+ - "\u51FF\u85FB\u67A3\u65E9\u6FA1\u86A4\u8E81\u566A"+ - "\u9020\u7682\u7076\u71E5\u8D23\u62E9\u5219\u6CFD"+ - "\u8D3C\u600E\u589E\u618E\u66FE\u8D60\u624E\u55B3"+ - "\u6E23\u672D\u8F67\u8A81\u8A82\u8A83\u8A84\u8A85"+ - "\u8A86\u8A87\u8A88\u8A8B\u8A8C\u8A8D\u8A8E\u8A8F"+ - "\u8A90\u8A91\u8A92\u8A94\u8A95\u8A96\u8A97\u8A98"+ - "\u8A99\u8A9A\u8A9B\u8A9C\u8A9D\u8A9E\u8A9F\u8AA0"+ - "\u8AA1\u8AA2\u8AA3\u8AA4\u8AA5\u8AA6\u8AA7\u8AA8"+ - "\u8AA9\u8AAA\u8AAB\u8AAC\u8AAD\u8AAE\u8AAF\u8AB0"+ - "\u8AB1\u8AB2\u8AB3\u8AB4\u8AB5\u8AB6\u8AB7\u8AB8"+ - "\u8AB9\u8ABA\u8ABB\u8ABC\u8ABD\u8ABE\u8ABF\u8AC0"+ - "\u8AC1\u8AC2\uFFFD\u8AC3\u8AC4\u8AC5\u8AC6\u8AC7"+ - "\u8AC8\u8AC9\u8ACA\u8ACB\u8ACC\u8ACD\u8ACE\u8ACF"+ - "\u8AD0\u8AD1\u8AD2\u8AD3\u8AD4\u8AD5\u8AD6\u8AD7"+ - "\u8AD8\u8AD9\u8ADA\u8ADB\u8ADC\u8ADD\u8ADE\u8ADF"+ - "\u8AE0\u8AE1\u8AE2\u8AE3\u94E1\u95F8\u7728\u6805"+ - "\u69A8\u548B\u4E4D\u70B8\u8BC8\u6458\u658B\u5B85"+ - "\u7A84\u503A\u5BE8\u77BB\u6BE1\u8A79\u7C98\u6CBE"+ - "\u76CF\u65A9\u8F97\u5D2D\u5C55\u8638\u6808\u5360"+ - "\u6218\u7AD9\u6E5B\u7EFD\u6A1F\u7AE0\u5F70\u6F33"+ - "\u5F20\u638C\u6DA8\u6756\u4E08\u5E10\u8D26\u4ED7"+ - "\u80C0\u7634\u969C\u62DB\u662D\u627E\u6CBC\u8D75"+ - "\u7167\u7F69\u5146\u8087\u53EC\u906E\u6298\u54F2"+ - "\u86F0\u8F99\u8005\u9517\u8517\u8FD9\u6D59\u73CD"+ - "\u659F\u771F\u7504\u7827\u81FB\u8D1E\u9488\u4FA6"+ - "\u6795\u75B9\u8BCA\u9707\u632F\u9547\u9635\u84B8"+ - "\u6323\u7741\u5F81\u72F0\u4E89\u6014\u6574\u62EF"+ - "\u6B63\u653F\u8AE4\u8AE5\u8AE6\u8AE7\u8AE8\u8AE9"+ - "\u8AEA\u8AEB\u8AEC\u8AED\u8AEE\u8AEF\u8AF0\u8AF1"+ - "\u8AF2\u8AF3\u8AF4\u8AF5\u8AF6\u8AF7\u8AF8\u8AF9"+ - "\u8AFA\u8AFB\u8AFC\u8AFD\u8AFE\u8AFF\u8B00\u8B01"+ - "\u8B02\u8B03\u8B04\u8B05\u8B06\u8B08\u8B09\u8B0A"+ - "\u8B0B\u8B0C\u8B0D\u8B0E\u8B0F\u8B10\u8B11\u8B12"+ - "\u8B13\u8B14\u8B15\u8B16\u8B17\u8B18\u8B19\u8B1A"+ - "\u8B1B\u8B1C\u8B1D\u8B1E\u8B1F\u8B20\u8B21\u8B22"+ - "\u8B23\uFFFD\u8B24\u8B25\u8B27\u8B28\u8B29\u8B2A"+ - "\u8B2B\u8B2C\u8B2D\u8B2E\u8B2F\u8B30\u8B31\u8B32"+ - "\u8B33\u8B34\u8B35\u8B36\u8B37\u8B38\u8B39\u8B3A"+ - "\u8B3B\u8B3C\u8B3D\u8B3E\u8B3F\u8B40\u8B41\u8B42"+ - "\u8B43\u8B44\u8B45\u5E27\u75C7\u90D1\u8BC1\u829D"+ - "\u679D\u652F\u5431\u8718\u77E5\u80A2\u8102\u6C41"+ - "\u4E4B\u7EC7\u804C\u76F4\u690D\u6B96\u6267\u503C"+ - "\u4F84\u5740\u6307\u6B62\u8DBE\u53EA\u65E8\u7EB8"+ - "\u5FD7\u631A\u63B7\u81F3\u81F4\u7F6E\u5E1C\u5CD9"+ - "\u5236\u667A\u79E9\u7A1A\u8D28\u7099\u75D4\u6EDE"+ - "\u6CBB\u7A92\u4E2D\u76C5\u5FE0\u949F\u8877\u7EC8"+ - "\u79CD\u80BF\u91CD\u4EF2\u4F17\u821F\u5468\u5DDE"+ - "\u6D32\u8BCC\u7CA5\u8F74\u8098\u5E1A\u5492\u76B1"+ - "\u5B99\u663C\u9AA4\u73E0\u682A\u86DB\u6731\u732A"+ - "\u8BF8\u8BDB\u9010\u7AF9\u70DB\u716E\u62C4\u77A9"+ - "\u5631\u4E3B\u8457\u67F1\u52A9\u86C0\u8D2E\u94F8"+ - "\u7B51\u8B46\u8B47\u8B48\u8B49\u8B4A\u8B4B\u8B4C"+ - "\u8B4D\u8B4E\u8B4F\u8B50\u8B51\u8B52\u8B53\u8B54"+ - "\u8B55\u8B56\u8B57\u8B58\u8B59\u8B5A\u8B5B\u8B5C"+ - "\u8B5D\u8B5E\u8B5F\u8B60\u8B61\u8B62\u8B63\u8B64"+ - "\u8B65\u8B67\u8B68\u8B69\u8B6A\u8B6B\u8B6D\u8B6E"+ - "\u8B6F\u8B70\u8B71\u8B72\u8B73\u8B74\u8B75\u8B76"+ - "\u8B77\u8B78\u8B79\u8B7A\u8B7B\u8B7C\u8B7D\u8B7E"+ - "\u8B7F\u8B80\u8B81\u8B82\u8B83\u8B84\u8B85\u8B86"+ - "\uFFFD\u8B87\u8B88\u8B89\u8B8A\u8B8B\u8B8C\u8B8D"+ - "\u8B8E\u8B8F\u8B90\u8B91\u8B92\u8B93\u8B94\u8B95"+ - "\u8B96\u8B97\u8B98\u8B99\u8B9A\u8B9B\u8B9C\u8B9D"+ - "\u8B9E\u8B9F\u8BAC\u8BB1\u8BBB\u8BC7\u8BD0\u8BEA"+ - "\u8C09\u8C1E\u4F4F\u6CE8\u795D\u9A7B\u6293\u722A"+ - "\u62FD\u4E13\u7816\u8F6C\u64B0\u8D5A\u7BC6\u6869"+ - "\u5E84\u88C5\u5986\u649E\u58EE\u72B6\u690E\u9525"+ - "\u8FFD\u8D58\u5760\u7F00\u8C06\u51C6\u6349\u62D9"+ - "\u5353\u684C\u7422\u8301\u914C\u5544\u7740\u707C"+ - "\u6D4A\u5179\u54A8\u8D44\u59FF\u6ECB\u6DC4\u5B5C"+ - "\u7D2B\u4ED4\u7C7D\u6ED3\u5B50\u81EA\u6E0D\u5B57"+ - "\u9B03\u68D5\u8E2A\u5B97\u7EFC\u603B\u7EB5\u90B9"+ - "\u8D70\u594F\u63CD\u79DF\u8DB3\u5352\u65CF\u7956"+ - "\u8BC5\u963B\u7EC4\u94BB\u7E82\u5634\u9189\u6700"+ - "\u7F6A\u5C0A\u9075\u6628\u5DE6\u4F50\u67DE\u505A"+ - "\u4F5C\u5750\u5EA7\uE810\uE811\uE812\uE813\uE814"+ - "\u8C38\u8C39\u8C3A\u8C3B\u8C3C\u8C3D\u8C3E\u8C3F"+ - "\u8C40\u8C42\u8C43\u8C44\u8C45\u8C48\u8C4A\u8C4B"+ - "\u8C4D\u8C4E\u8C4F\u8C50\u8C51\u8C52\u8C53\u8C54"+ - "\u8C56\u8C57\u8C58\u8C59\u8C5B\u8C5C\u8C5D\u8C5E"+ - "\u8C5F\u8C60\u8C63\u8C64\u8C65\u8C66\u8C67\u8C68"+ - "\u8C69\u8C6C\u8C6D\u8C6E\u8C6F\u8C70\u8C71\u8C72"+ - "\u8C74\u8C75\u8C76\u8C77\u8C7B\u8C7C\u8C7D\u8C7E"+ - "\u8C7F\u8C80\u8C81\u8C83\u8C84\u8C86\u8C87\uFFFD"+ - "\u8C88\u8C8B\u8C8D\u8C8E\u8C8F\u8C90\u8C91\u8C92"+ - "\u8C93\u8C95\u8C96\u8C97\u8C99\u8C9A\u8C9B\u8C9C"+ - "\u8C9D\u8C9E\u8C9F\u8CA0\u8CA1\u8CA2\u8CA3\u8CA4"+ - "\u8CA5\u8CA6\u8CA7\u8CA8\u8CA9\u8CAA\u8CAB\u8CAC"+ - "\u8CAD\u4E8D\u4E0C\u5140\u4E10\u5EFF\u5345\u4E15"+ - "\u4E98\u4E1E\u9B32\u5B6C\u5669\u4E28\u79BA\u4E3F"+ - "\u5315\u4E47\u592D\u723B\u536E\u6C10\u56DF\u80E4"+ - "\u9997\u6BD3\u777E\u9F17\u4E36\u4E9F\u9F10\u4E5C"+ - "\u4E69\u4E93\u8288\u5B5B\u556C\u560F\u4EC4\u538D"+ - "\u539D\u53A3\u53A5\u53AE\u9765\u8D5D\u531A\u53F5"+ - "\u5326\u532E\u533E\u8D5C\u5366\u5363\u5202\u5208"+ - "\u520E\u522D\u5233\u523F\u5240\u524C\u525E\u5261"+ - "\u525C\u84AF\u527D\u5282\u5281\u5290\u5293\u5182"+ - "\u7F54\u4EBB\u4EC3\u4EC9\u4EC2\u4EE8\u4EE1\u4EEB"+ - "\u4EDE\u4F1B\u4EF3\u4F22\u4F64\u4EF5\u4F25\u4F27"+ - "\u4F09\u4F2B\u4F5E\u4F67\u6538\u4F5A\u4F5D\u8CAE"+ - "\u8CAF\u8CB0\u8CB1\u8CB2\u8CB3\u8CB4\u8CB5\u8CB6"+ - "\u8CB7\u8CB8\u8CB9\u8CBA\u8CBB\u8CBC\u8CBD\u8CBE"+ - "\u8CBF\u8CC0\u8CC1\u8CC2\u8CC3\u8CC4\u8CC5\u8CC6"+ - "\u8CC7\u8CC8\u8CC9\u8CCA\u8CCB\u8CCC\u8CCD\u8CCE"+ - "\u8CCF\u8CD0\u8CD1\u8CD2\u8CD3\u8CD4\u8CD5\u8CD6"+ - "\u8CD7\u8CD8\u8CD9\u8CDA\u8CDB\u8CDC\u8CDD\u8CDE"+ - "\u8CDF\u8CE0\u8CE1\u8CE2\u8CE3\u8CE4\u8CE5\u8CE6"+ - "\u8CE7\u8CE8\u8CE9\u8CEA\u8CEB\u8CEC\uFFFD\u8CED"+ - "\u8CEE\u8CEF\u8CF0\u8CF1\u8CF2\u8CF3\u8CF4\u8CF5"+ - "\u8CF6\u8CF7\u8CF8\u8CF9\u8CFA\u8CFB\u8CFC\u8CFD"+ - "\u8CFE\u8CFF\u8D00\u8D01\u8D02\u8D03\u8D04\u8D05"+ - "\u8D06\u8D07\u8D08\u8D09\u8D0A\u8D0B\u8D0C\u8D0D"+ - "\u4F5F\u4F57\u4F32\u4F3D\u4F76\u4F74\u4F91\u4F89"+ - "\u4F83\u4F8F\u4F7E\u4F7B\u4FAA\u4F7C\u4FAC\u4F94"+ - "\u4FE6\u4FE8\u4FEA\u4FC5\u4FDA\u4FE3\u4FDC\u4FD1"+ - "\u4FDF\u4FF8\u5029\u504C\u4FF3\u502C\u500F\u502E"+ - "\u502D\u4FFE\u501C\u500C\u5025\u5028\u507E\u5043"+ - "\u5055\u5048\u504E\u506C\u507B\u50A5\u50A7\u50A9"+ - "\u50BA\u50D6\u5106\u50ED\u50EC\u50E6\u50EE\u5107"+ - "\u510B\u4EDD\u6C3D\u4F58\u4F65\u4FCE\u9FA0\u6C46"+ - "\u7C74\u516E\u5DFD\u9EC9\u9998\u5181\u5914\u52F9"+ - "\u530D\u8A07\u5310\u51EB\u5919\u5155\u4EA0\u5156"+ - "\u4EB3\u886E\u88A4\u4EB5\u8114\u88D2\u7980\u5B34"+ - "\u8803\u7FB8\u51AB\u51B1\u51BD\u51BC\u8D0E\u8D0F"+ - "\u8D10\u8D11\u8D12\u8D13\u8D14\u8D15\u8D16\u8D17"+ - "\u8D18\u8D19\u8D1A\u8D1B\u8D1C\u8D20\u8D51\u8D52"+ - "\u8D57\u8D5F\u8D65\u8D68\u8D69\u8D6A\u8D6C\u8D6E"+ - "\u8D6F\u8D71\u8D72\u8D78\u8D79\u8D7A\u8D7B\u8D7C"+ - "\u8D7D\u8D7E\u8D7F\u8D80\u8D82\u8D83\u8D86\u8D87"+ - "\u8D88\u8D89\u8D8C\u8D8D\u8D8E\u8D8F\u8D90\u8D92"+ - "\u8D93\u8D95\u8D96\u8D97\u8D98\u8D99\u8D9A\u8D9B"+ - "\u8D9C\u8D9D\u8D9E\u8DA0\u8DA1\uFFFD\u8DA2\u8DA4"+ - "\u8DA5\u8DA6\u8DA7\u8DA8\u8DA9\u8DAA\u8DAB\u8DAC"+ - "\u8DAD\u8DAE\u8DAF\u8DB0\u8DB2\u8DB6\u8DB7\u8DB9"+ - "\u8DBB\u8DBD\u8DC0\u8DC1\u8DC2\u8DC5\u8DC7\u8DC8"+ - "\u8DC9\u8DCA\u8DCD\u8DD0\u8DD2\u8DD3\u8DD4\u51C7"+ - "\u5196\u51A2\u51A5\u8BA0\u8BA6\u8BA7\u8BAA\u8BB4"+ - "\u8BB5\u8BB7\u8BC2\u8BC3\u8BCB\u8BCF\u8BCE\u8BD2"+ - "\u8BD3\u8BD4\u8BD6\u8BD8\u8BD9\u8BDC\u8BDF\u8BE0"+ - "\u8BE4\u8BE8\u8BE9\u8BEE\u8BF0\u8BF3\u8BF6\u8BF9"+ - "\u8BFC\u8BFF\u8C00\u8C02\u8C04\u8C07\u8C0C\u8C0F"+ - "\u8C11\u8C12\u8C14\u8C15\u8C16\u8C19\u8C1B\u8C18"+ - "\u8C1D\u8C1F\u8C20\u8C21\u8C25\u8C27\u8C2A\u8C2B"+ - "\u8C2E\u8C2F\u8C32\u8C33\u8C35\u8C36\u5369\u537A"+ - "\u961D\u9622\u9621\u9631\u962A\u963D\u963C\u9642"+ - "\u9649\u9654\u965F\u9667\u966C\u9672\u9674\u9688"+ - "\u968D\u9697\u96B0\u9097\u909B\u909D\u9099\u90AC"+ - "\u90A1\u90B4\u90B3\u90B6\u90BA\u8DD5\u8DD8\u8DD9"+ - "\u8DDC\u8DE0\u8DE1\u8DE2\u8DE5\u8DE6\u8DE7\u8DE9"+ - "\u8DED\u8DEE\u8DF0\u8DF1\u8DF2\u8DF4\u8DF6\u8DFC"+ - "\u8DFE\u8DFF\u8E00\u8E01\u8E02\u8E03\u8E04\u8E06"+ - "\u8E07\u8E08\u8E0B\u8E0D\u8E0E\u8E10\u8E11\u8E12"+ - "\u8E13\u8E15\u8E16\u8E17\u8E18\u8E19\u8E1A\u8E1B"+ - "\u8E1C\u8E20\u8E21\u8E24\u8E25\u8E26\u8E27\u8E28"+ - "\u8E2B\u8E2D\u8E30\u8E32\u8E33\u8E34\u8E36\u8E37"+ - "\u8E38\u8E3B\u8E3C\u8E3E\uFFFD\u8E3F\u8E43\u8E45"+ - "\u8E46\u8E4C\u8E4D\u8E4E\u8E4F\u8E50\u8E53\u8E54"+ - "\u8E55\u8E56\u8E57\u8E58\u8E5A\u8E5B\u8E5C\u8E5D"+ - "\u8E5E\u8E5F\u8E60\u8E61\u8E62\u8E63\u8E64\u8E65"+ - "\u8E67\u8E68\u8E6A\u8E6B\u8E6E\u8E71\u90B8\u90B0"+ - "\u90CF\u90C5\u90BE\u90D0\u90C4\u90C7\u90D3\u90E6"+ - "\u90E2\u90DC\u90D7\u90DB\u90EB\u90EF\u90FE\u9104"+ - "\u9122\u911E\u9123\u9131\u912F\u9139\u9143\u9146"+ - "\u520D\u5942\u52A2\u52AC\u52AD\u52BE\u54FF\u52D0"+ - "\u52D6\u52F0\u53DF\u71EE\u77CD\u5EF4\u51F5\u51FC"+ - "\u9B2F\u53B6\u5F01\u755A\u5DEF\u574C\u57A9\u57A1"+ - "\u587E\u58BC\u58C5\u58D1\u5729\u572C\u572A\u5733"+ - "\u5739\u572E\u572F\u575C\u573B\u5742\u5769\u5785"+ - "\u576B\u5786\u577C\u577B\u5768\u576D\u5776\u5773"+ - "\u57AD\u57A4\u578C\u57B2\u57CF\u57A7\u57B4\u5793"+ - "\u57A0\u57D5\u57D8\u57DA\u57D9\u57D2\u57B8\u57F4"+ - "\u57EF\u57F8\u57E4\u57DD\u8E73\u8E75\u8E77\u8E78"+ - "\u8E79\u8E7A\u8E7B\u8E7D\u8E7E\u8E80\u8E82\u8E83"+ - "\u8E84\u8E86\u8E88\u8E89\u8E8A\u8E8B\u8E8C\u8E8D"+ - "\u8E8E\u8E91\u8E92\u8E93\u8E95\u8E96\u8E97\u8E98"+ - "\u8E99\u8E9A\u8E9B\u8E9D\u8E9F\u8EA0\u8EA1\u8EA2"+ - "\u8EA3\u8EA4\u8EA5\u8EA6\u8EA7\u8EA8\u8EA9\u8EAA"+ - "\u8EAD\u8EAE\u8EB0\u8EB1\u8EB3\u8EB4\u8EB5\u8EB6"+ - "\u8EB7\u8EB8\u8EB9\u8EBB\u8EBC\u8EBD\u8EBE\u8EBF"+ - "\u8EC0\u8EC1\u8EC2\uFFFD\u8EC3\u8EC4\u8EC5\u8EC6"+ - "\u8EC7\u8EC8\u8EC9\u8ECA\u8ECB\u8ECC\u8ECD\u8ECF"+ - "\u8ED0\u8ED1\u8ED2\u8ED3\u8ED4\u8ED5\u8ED6\u8ED7"+ - "\u8ED8\u8ED9\u8EDA\u8EDB\u8EDC\u8EDD\u8EDE\u8EDF"+ - "\u8EE0\u8EE1\u8EE2\u8EE3\u8EE4\u580B\u580D\u57FD"+ - "\u57ED\u5800\u581E\u5819\u5844\u5820\u5865\u586C"+ - "\u5881\u5889\u589A\u5880\u99A8\u9F19\u61FF\u8279"+ - "\u827D\u827F\u828F\u828A\u82A8\u8284\u828E\u8291"+ - "\u8297\u8299\u82AB\u82B8\u82BE\u82B0\u82C8\u82CA"+ - "\u82E3\u8298\u82B7\u82AE\u82CB\u82CC\u82C1\u82A9"+ - "\u82B4\u82A1\u82AA\u829F\u82C4\u82CE\u82A4\u82E1"+ - "\u8309\u82F7\u82E4\u830F\u8307\u82DC\u82F4\u82D2"+ - "\u82D8\u830C\u82FB\u82D3\u8311\u831A\u8306\u8314"+ - "\u8315\u82E0\u82D5\u831C\u8351\u835B\u835C\u8308"+ - "\u8392\u833C\u8334\u8331\u839B\u835E\u832F\u834F"+ - "\u8347\u8343\u835F\u8340\u8317\u8360\u832D\u833A"+ - "\u8333\u8366\u8365\u8EE5\u8EE6\u8EE7\u8EE8\u8EE9"+ - "\u8EEA\u8EEB\u8EEC\u8EED\u8EEE\u8EEF\u8EF0\u8EF1"+ - "\u8EF2\u8EF3\u8EF4\u8EF5\u8EF6\u8EF7\u8EF8\u8EF9"+ - "\u8EFA\u8EFB\u8EFC\u8EFD\u8EFE\u8EFF\u8F00\u8F01"+ - "\u8F02\u8F03\u8F04\u8F05\u8F06\u8F07\u8F08\u8F09"+ - "\u8F0A\u8F0B\u8F0C\u8F0D\u8F0E\u8F0F\u8F10\u8F11"+ - "\u8F12\u8F13\u8F14\u8F15\u8F16\u8F17\u8F18\u8F19"+ - "\u8F1A\u8F1B\u8F1C\u8F1D\u8F1E\u8F1F\u8F20\u8F21"+ - "\u8F22\u8F23\uFFFD\u8F24\u8F25\u8F26\u8F27\u8F28"+ - "\u8F29\u8F2A\u8F2B\u8F2C\u8F2D\u8F2E\u8F2F\u8F30"+ - "\u8F31\u8F32\u8F33\u8F34\u8F35\u8F36\u8F37\u8F38"+ - "\u8F39\u8F3A\u8F3B\u8F3C\u8F3D\u8F3E\u8F3F\u8F40"+ - "\u8F41\u8F42\u8F43\u8F44\u8368\u831B\u8369\u836C"+ - "\u836A\u836D\u836E\u83B0\u8378\u83B3\u83B4\u83A0"+ - "\u83AA\u8393\u839C\u8385\u837C\u83B6\u83A9\u837D"+ - "\u83B8\u837B\u8398\u839E\u83A8\u83BA\u83BC\u83C1"+ - "\u8401\u83E5\u83D8\u5807\u8418\u840B\u83DD\u83FD"+ - "\u83D6\u841C\u8438\u8411\u8406\u83D4\u83DF\u840F"+ - "\u8403\u83F8\u83F9\u83EA\u83C5\u83C0\u8426\u83F0"+ - "\u83E1\u845C\u8451\u845A\u8459\u8473\u8487\u8488"+ - "\u847A\u8489\u8478\u843C\u8446\u8469\u8476\u848C"+ - "\u848E\u8431\u846D\u84C1\u84CD\u84D0\u84E6\u84BD"+ - "\u84D3\u84CA\u84BF\u84BA\u84E0\u84A1\u84B9\u84B4"+ - "\u8497\u84E5\u84E3\u850C\u750D\u8538\u84F0\u8539"+ - "\u851F\u853A\u8F45\u8F46\u8F47\u8F48\u8F49\u8F4A"+ - "\u8F4B\u8F4C\u8F4D\u8F4E\u8F4F\u8F50\u8F51\u8F52"+ - "\u8F53\u8F54\u8F55\u8F56\u8F57\u8F58\u8F59\u8F5A"+ - "\u8F5B\u8F5C\u8F5D\u8F5E\u8F5F\u8F60\u8F61\u8F62"+ - "\u8F63\u8F64\u8F65\u8F6A\u8F80\u8F8C\u8F92\u8F9D"+ - "\u8FA0\u8FA1\u8FA2\u8FA4\u8FA5\u8FA6\u8FA7\u8FAA"+ - "\u8FAC\u8FAD\u8FAE\u8FAF\u8FB2\u8FB3\u8FB4\u8FB5"+ - "\u8FB7\u8FB8\u8FBA\u8FBB\u8FBC\u8FBF\u8FC0\u8FC3"+ - "\u8FC6\uFFFD\u8FC9\u8FCA\u8FCB\u8FCC\u8FCD\u8FCF"+ - "\u8FD2\u8FD6\u8FD7\u8FDA\u8FE0\u8FE1\u8FE3\u8FE7"+ - "\u8FEC\u8FEF\u8FF1\u8FF2\u8FF4\u8FF5\u8FF6\u8FFA"+ - "\u8FFB\u8FFC\u8FFE\u8FFF\u9007\u9008\u900C\u900E"+ - "\u9013\u9015\u9018\u8556\u853B\u84FF\u84FC\u8559"+ - "\u8548\u8568\u8564\u855E\u857A\u77A2\u8543\u8572"+ - "\u857B\u85A4\u85A8\u8587\u858F\u8579\u85AE\u859C"+ - "\u8585\u85B9\u85B7\u85B0\u85D3\u85C1\u85DC\u85FF"+ - "\u8627\u8605\u8629\u8616\u863C\u5EFE\u5F08\u593C"+ - "\u5941\u8037\u5955\u595A\u5958\u530F\u5C22\u5C25"+ - "\u5C2C\u5C34\u624C\u626A\u629F\u62BB\u62CA\u62DA"+ - "\u62D7\u62EE\u6322\u62F6\u6339\u634B\u6343\u63AD"+ - "\u63F6\u6371\u637A\u638E\u63B4\u636D\u63AC\u638A"+ - "\u6369\u63AE\u63BC\u63F2\u63F8\u63E0\u63FF\u63C4"+ - "\u63DE\u63CE\u6452\u63C6\u63BE\u6445\u6441\u640B"+ - "\u641B\u6420\u640C\u6426\u6421\u645E\u6484\u646D"+ - "\u6496\u9019\u901C\u9023\u9024\u9025\u9027\u9028"+ - "\u9029\u902A\u902B\u902C\u9030\u9031\u9032\u9033"+ - "\u9034\u9037\u9039\u903A\u903D\u903F\u9040\u9043"+ - "\u9045\u9046\u9048\u9049\u904A\u904B\u904C\u904E"+ - "\u9054\u9055\u9056\u9059\u905A\u905C\u905D\u905E"+ - "\u905F\u9060\u9061\u9064\u9066\u9067\u9069\u906A"+ - "\u906B\u906C\u906F\u9070\u9071\u9072\u9073\u9076"+ - "\u9077\u9078\u9079\u907A\u907B\u907C\u907E\u9081"+ - "\uFFFD\u9084\u9085\u9086\u9087\u9089\u908A\u908C"+ - "\u908D\u908E\u908F\u9090\u9092\u9094\u9096\u9098"+ - "\u909A\u909C\u909E\u909F\u90A0\u90A4\u90A5\u90A7"+ - "\u90A8\u90A9\u90AB\u90AD\u90B2\u90B7\u90BC\u90BD"+ - "\u90BF\u90C0\u647A\u64B7\u64B8\u6499\u64BA\u64C0"+ - "\u64D0\u64D7\u64E4\u64E2\u6509\u6525\u652E\u5F0B"+ - "\u5FD2\u7519\u5F11\u535F\u53F1\u53FD\u53E9\u53E8"+ - "\u53FB\u5412\u5416\u5406\u544B\u5452\u5453\u5454"+ - "\u5456\u5443\u5421\u5457\u5459\u5423\u5432\u5482"+ - "\u5494\u5477\u5471\u5464\u549A\u549B\u5484\u5476"+ - "\u5466\u549D\u54D0\u54AD\u54C2\u54B4\u54D2\u54A7"+ - "\u54A6\u54D3\u54D4\u5472\u54A3\u54D5\u54BB\u54BF"+ - "\u54CC\u54D9\u54DA\u54DC\u54A9\u54AA\u54A4\u54DD"+ - "\u54CF\u54DE\u551B\u54E7\u5520\u54FD\u5514\u54F3"+ - "\u5522\u5523\u550F\u5511\u5527\u552A\u5567\u558F"+ - "\u55B5\u5549\u556D\u5541\u5555\u553F\u5550\u553C"; - - private static final String innerIndex6= - "\u90C2\u90C3\u90C6\u90C8\u90C9\u90CB\u90CC\u90CD"+ - "\u90D2\u90D4\u90D5\u90D6\u90D8\u90D9\u90DA\u90DE"+ - "\u90DF\u90E0\u90E3\u90E4\u90E5\u90E9\u90EA\u90EC"+ - "\u90EE\u90F0\u90F1\u90F2\u90F3\u90F5\u90F6\u90F7"+ - "\u90F9\u90FA\u90FB\u90FC\u90FF\u9100\u9101\u9103"+ - "\u9105\u9106\u9107\u9108\u9109\u910A\u910B\u910C"+ - "\u910D\u910E\u910F\u9110\u9111\u9112\u9113\u9114"+ - "\u9115\u9116\u9117\u9118\u911A\u911B\u911C\uFFFD"+ - "\u911D\u911F\u9120\u9121\u9124\u9125\u9126\u9127"+ - "\u9128\u9129\u912A\u912B\u912C\u912D\u912E\u9130"+ - "\u9132\u9133\u9134\u9135\u9136\u9137\u9138\u913A"+ - "\u913B\u913C\u913D\u913E\u913F\u9140\u9141\u9142"+ - "\u9144\u5537\u5556\u5575\u5576\u5577\u5533\u5530"+ - "\u555C\u558B\u55D2\u5583\u55B1\u55B9\u5588\u5581"+ - "\u559F\u557E\u55D6\u5591\u557B\u55DF\u55BD\u55BE"+ - "\u5594\u5599\u55EA\u55F7\u55C9\u561F\u55D1\u55EB"+ - "\u55EC\u55D4\u55E6\u55DD\u55C4\u55EF\u55E5\u55F2"+ - "\u55F3\u55CC\u55CD\u55E8\u55F5\u55E4\u8F94\u561E"+ - "\u5608\u560C\u5601\u5624\u5623\u55FE\u5600\u5627"+ - "\u562D\u5658\u5639\u5657\u562C\u564D\u5662\u5659"+ - "\u565C\u564C\u5654\u5686\u5664\u5671\u566B\u567B"+ - "\u567C\u5685\u5693\u56AF\u56D4\u56D7\u56DD\u56E1"+ - "\u56F5\u56EB\u56F9\u56FF\u5704\u570A\u5709\u571C"+ - "\u5E0F\u5E19\u5E14\u5E11\u5E31\u5E3B\u5E3C\u9145"+ - "\u9147\u9148\u9151\u9153\u9154\u9155\u9156\u9158"+ - "\u9159\u915B\u915C\u915F\u9160\u9166\u9167\u9168"+ - "\u916B\u916D\u9173\u917A\u917B\u917C\u9180\u9181"+ - "\u9182\u9183\u9184\u9186\u9188\u918A\u918E\u918F"+ - "\u9193\u9194\u9195\u9196\u9197\u9198\u9199\u919C"+ - "\u919D\u919E\u919F\u91A0\u91A1\u91A4\u91A5\u91A6"+ - "\u91A7\u91A8\u91A9\u91AB\u91AC\u91B0\u91B1\u91B2"+ - "\u91B3\u91B6\u91B7\u91B8\u91B9\u91BB\uFFFD\u91BC"+ - "\u91BD\u91BE\u91BF\u91C0\u91C1\u91C2\u91C3\u91C4"+ - "\u91C5\u91C6\u91C8\u91CB\u91D0\u91D2\u91D3\u91D4"+ - "\u91D5\u91D6\u91D7\u91D8\u91D9\u91DA\u91DB\u91DD"+ - "\u91DE\u91DF\u91E0\u91E1\u91E2\u91E3\u91E4\u91E5"+ - "\u5E37\u5E44\u5E54\u5E5B\u5E5E\u5E61\u5C8C\u5C7A"+ - "\u5C8D\u5C90\u5C96\u5C88\u5C98\u5C99\u5C91\u5C9A"+ - "\u5C9C\u5CB5\u5CA2\u5CBD\u5CAC\u5CAB\u5CB1\u5CA3"+ - "\u5CC1\u5CB7\u5CC4\u5CD2\u5CE4\u5CCB\u5CE5\u5D02"+ - "\u5D03\u5D27\u5D26\u5D2E\u5D24\u5D1E\u5D06\u5D1B"+ - "\u5D58\u5D3E\u5D34\u5D3D\u5D6C\u5D5B\u5D6F\u5D5D"+ - "\u5D6B\u5D4B\u5D4A\u5D69\u5D74\u5D82\u5D99\u5D9D"+ - "\u8C73\u5DB7\u5DC5\u5F73\u5F77\u5F82\u5F87\u5F89"+ - "\u5F8C\u5F95\u5F99\u5F9C\u5FA8\u5FAD\u5FB5\u5FBC"+ - "\u8862\u5F61\u72AD\u72B0\u72B4\u72B7\u72B8\u72C3"+ - "\u72C1\u72CE\u72CD\u72D2\u72E8\u72EF\u72E9\u72F2"+ - "\u72F4\u72F7\u7301\u72F3\u7303\u72FA\u91E6\u91E7"+ - "\u91E8\u91E9\u91EA\u91EB\u91EC\u91ED\u91EE\u91EF"+ - "\u91F0\u91F1\u91F2\u91F3\u91F4\u91F5\u91F6\u91F7"+ - "\u91F8\u91F9\u91FA\u91FB\u91FC\u91FD\u91FE\u91FF"+ - "\u9200\u9201\u9202\u9203\u9204\u9205\u9206\u9207"+ - "\u9208\u9209\u920A\u920B\u920C\u920D\u920E\u920F"+ - "\u9210\u9211\u9212\u9213\u9214\u9215\u9216\u9217"+ - "\u9218\u9219\u921A\u921B\u921C\u921D\u921E\u921F"+ - "\u9220\u9221\u9222\u9223\u9224\uFFFD\u9225\u9226"+ - "\u9227\u9228\u9229\u922A\u922B\u922C\u922D\u922E"+ - "\u922F\u9230\u9231\u9232\u9233\u9234\u9235\u9236"+ - "\u9237\u9238\u9239\u923A\u923B\u923C\u923D\u923E"+ - "\u923F\u9240\u9241\u9242\u9243\u9244\u9245\u72FB"+ - "\u7317\u7313\u7321\u730A\u731E\u731D\u7315\u7322"+ - "\u7339\u7325\u732C\u7338\u7331\u7350\u734D\u7357"+ - "\u7360\u736C\u736F\u737E\u821B\u5925\u98E7\u5924"+ - "\u5902\u9963\u9967\u9968\u9969\u996A\u996B\u996C"+ - "\u9974\u9977\u997D\u9980\u9984\u9987\u998A\u998D"+ - "\u9990\u9991\u9993\u9994\u9995\u5E80\u5E91\u5E8B"+ - "\u5E96\u5EA5\u5EA0\u5EB9\u5EB5\u5EBE\u5EB3\u8D53"+ - "\u5ED2\u5ED1\u5EDB\u5EE8\u5EEA\u81BA\u5FC4\u5FC9"+ - "\u5FD6\u5FCF\u6003\u5FEE\u6004\u5FE1\u5FE4\u5FFE"+ - "\u6005\u6006\u5FEA\u5FED\u5FF8\u6019\u6035\u6026"+ - "\u601B\u600F\u600D\u6029\u602B\u600A\u603F\u6021"+ - "\u6078\u6079\u607B\u607A\u6042\u9246\u9247\u9248"+ - "\u9249\u924A\u924B\u924C\u924D\u924E\u924F\u9250"+ - "\u9251\u9252\u9253\u9254\u9255\u9256\u9257\u9258"+ - "\u9259\u925A\u925B\u925C\u925D\u925E\u925F\u9260"+ - "\u9261\u9262\u9263\u9264\u9265\u9266\u9267\u9268"+ - "\u9269\u926A\u926B\u926C\u926D\u926E\u926F\u9270"+ - "\u9271\u9272\u9273\u9275\u9276\u9277\u9278\u9279"+ - "\u927A\u927B\u927C\u927D\u927E\u927F\u9280\u9281"+ - "\u9282\u9283\u9284\u9285\uFFFD\u9286\u9287\u9288"+ - "\u9289\u928A\u928B\u928C\u928D\u928F\u9290\u9291"+ - "\u9292\u9293\u9294\u9295\u9296\u9297\u9298\u9299"+ - "\u929A\u929B\u929C\u929D\u929E\u929F\u92A0\u92A1"+ - "\u92A2\u92A3\u92A4\u92A5\u92A6\u92A7\u606A\u607D"+ - "\u6096\u609A\u60AD\u609D\u6083\u6092\u608C\u609B"+ - "\u60EC\u60BB\u60B1\u60DD\u60D8\u60C6\u60DA\u60B4"+ - "\u6120\u6126\u6115\u6123\u60F4\u6100\u610E\u612B"+ - "\u614A\u6175\u61AC\u6194\u61A7\u61B7\u61D4\u61F5"+ - "\u5FDD\u96B3\u95E9\u95EB\u95F1\u95F3\u95F5\u95F6"+ - "\u95FC\u95FE\u9603\u9604\u9606\u9608\u960A\u960B"+ - "\u960C\u960D\u960F\u9612\u9615\u9616\u9617\u9619"+ - "\u961A\u4E2C\u723F\u6215\u6C35\u6C54\u6C5C\u6C4A"+ - "\u6CA3\u6C85\u6C90\u6C94\u6C8C\u6C68\u6C69\u6C74"+ - "\u6C76\u6C86\u6CA9\u6CD0\u6CD4\u6CAD\u6CF7\u6CF8"+ - "\u6CF1\u6CD7\u6CB2\u6CE0\u6CD6\u6CFA\u6CEB\u6CEE"+ - "\u6CB1\u6CD3\u6CEF\u6CFE\u92A8\u92A9\u92AA\u92AB"+ - "\u92AC\u92AD\u92AF\u92B0\u92B1\u92B2\u92B3\u92B4"+ - "\u92B5\u92B6\u92B7\u92B8\u92B9\u92BA\u92BB\u92BC"+ - "\u92BD\u92BE\u92BF\u92C0\u92C1\u92C2\u92C3\u92C4"+ - "\u92C5\u92C6\u92C7\u92C9\u92CA\u92CB\u92CC\u92CD"+ - "\u92CE\u92CF\u92D0\u92D1\u92D2\u92D3\u92D4\u92D5"+ - "\u92D6\u92D7\u92D8\u92D9\u92DA\u92DB\u92DC\u92DD"+ - "\u92DE\u92DF\u92E0\u92E1\u92E2\u92E3\u92E4\u92E5"+ - "\u92E6\u92E7\u92E8\uFFFD\u92E9\u92EA\u92EB\u92EC"+ - "\u92ED\u92EE\u92EF\u92F0\u92F1\u92F2\u92F3\u92F4"+ - "\u92F5\u92F6\u92F7\u92F8\u92F9\u92FA\u92FB\u92FC"+ - "\u92FD\u92FE\u92FF\u9300\u9301\u9302\u9303\u9304"+ - "\u9305\u9306\u9307\u9308\u9309\u6D39\u6D27\u6D0C"+ - "\u6D43\u6D48\u6D07\u6D04\u6D19\u6D0E\u6D2B\u6D4D"+ - "\u6D2E\u6D35\u6D1A\u6D4F\u6D52\u6D54\u6D33\u6D91"+ - "\u6D6F\u6D9E\u6DA0\u6D5E\u6D93\u6D94\u6D5C\u6D60"+ - "\u6D7C\u6D63\u6E1A\u6DC7\u6DC5\u6DDE\u6E0E\u6DBF"+ - "\u6DE0\u6E11\u6DE6\u6DDD\u6DD9\u6E16\u6DAB\u6E0C"+ - "\u6DAE\u6E2B\u6E6E\u6E4E\u6E6B\u6EB2\u6E5F\u6E86"+ - "\u6E53\u6E54\u6E32\u6E25\u6E44\u6EDF\u6EB1\u6E98"+ - "\u6EE0\u6F2D\u6EE2\u6EA5\u6EA7\u6EBD\u6EBB\u6EB7"+ - "\u6ED7\u6EB4\u6ECF\u6E8F\u6EC2\u6E9F\u6F62\u6F46"+ - "\u6F47\u6F24\u6F15\u6EF9\u6F2F\u6F36\u6F4B\u6F74"+ - "\u6F2A\u6F09\u6F29\u6F89\u6F8D\u6F8C\u6F78\u6F72"+ - "\u6F7C\u6F7A\u6FD1\u930A\u930B\u930C\u930D\u930E"+ - "\u930F\u9310\u9311\u9312\u9313\u9314\u9315\u9316"+ - "\u9317\u9318\u9319\u931A\u931B\u931C\u931D\u931E"+ - "\u931F\u9320\u9321\u9322\u9323\u9324\u9325\u9326"+ - "\u9327\u9328\u9329\u932A\u932B\u932C\u932D\u932E"+ - "\u932F\u9330\u9331\u9332\u9333\u9334\u9335\u9336"+ - "\u9337\u9338\u9339\u933A\u933B\u933C\u933D\u933F"+ - "\u9340\u9341\u9342\u9343\u9344\u9345\u9346\u9347"+ - "\u9348\u9349\uFFFD\u934A\u934B\u934C\u934D\u934E"+ - "\u934F\u9350\u9351\u9352\u9353\u9354\u9355\u9356"+ - "\u9357\u9358\u9359\u935A\u935B\u935C\u935D\u935E"+ - "\u935F\u9360\u9361\u9362\u9363\u9364\u9365\u9366"+ - "\u9367\u9368\u9369\u936B\u6FC9\u6FA7\u6FB9\u6FB6"+ - "\u6FC2\u6FE1\u6FEE\u6FDE\u6FE0\u6FEF\u701A\u7023"+ - "\u701B\u7039\u7035\u704F\u705E\u5B80\u5B84\u5B95"+ - "\u5B93\u5BA5\u5BB8\u752F\u9A9E\u6434\u5BE4\u5BEE"+ - "\u8930\u5BF0\u8E47\u8B07\u8FB6\u8FD3\u8FD5\u8FE5"+ - "\u8FEE\u8FE4\u8FE9\u8FE6\u8FF3\u8FE8\u9005\u9004"+ - "\u900B\u9026\u9011\u900D\u9016\u9021\u9035\u9036"+ - "\u902D\u902F\u9044\u9051\u9052\u9050\u9068\u9058"+ - "\u9062\u905B\u66B9\u9074\u907D\u9082\u9088\u9083"+ - "\u908B\u5F50\u5F57\u5F56\u5F58\u5C3B\u54AB\u5C50"+ - "\u5C59\u5B71\u5C63\u5C66\u7FBC\u5F2A\u5F29\u5F2D"+ - "\u8274\u5F3C\u9B3B\u5C6E\u5981\u5983\u598D\u59A9"+ - "\u59AA\u59A3\u936C\u936D\u936E\u936F\u9370\u9371"+ - "\u9372\u9373\u9374\u9375\u9376\u9377\u9378\u9379"+ - "\u937A\u937B\u937C\u937D\u937E\u937F\u9380\u9381"+ - "\u9382\u9383\u9384\u9385\u9386\u9387\u9388\u9389"+ - "\u938A\u938B\u938C\u938D\u938E\u9390\u9391\u9392"+ - "\u9393\u9394\u9395\u9396\u9397\u9398\u9399\u939A"+ - "\u939B\u939C\u939D\u939E\u939F\u93A0\u93A1\u93A2"+ - "\u93A3\u93A4\u93A5\u93A6\u93A7\u93A8\u93A9\u93AA"+ - "\u93AB\uFFFD\u93AC\u93AD\u93AE\u93AF\u93B0\u93B1"+ - "\u93B2\u93B3\u93B4\u93B5\u93B6\u93B7\u93B8\u93B9"+ - "\u93BA\u93BB\u93BC\u93BD\u93BE\u93BF\u93C0\u93C1"+ - "\u93C2\u93C3\u93C4\u93C5\u93C6\u93C7\u93C8\u93C9"+ - "\u93CB\u93CC\u93CD\u5997\u59CA\u59AB\u599E\u59A4"+ - "\u59D2\u59B2\u59AF\u59D7\u59BE\u5A05\u5A06\u59DD"+ - "\u5A08\u59E3\u59D8\u59F9\u5A0C\u5A09\u5A32\u5A34"+ - "\u5A11\u5A23\u5A13\u5A40\u5A67\u5A4A\u5A55\u5A3C"+ - "\u5A62\u5A75\u80EC\u5AAA\u5A9B\u5A77\u5A7A\u5ABE"+ - "\u5AEB\u5AB2\u5AD2\u5AD4\u5AB8\u5AE0\u5AE3\u5AF1"+ - "\u5AD6\u5AE6\u5AD8\u5ADC\u5B09\u5B17\u5B16\u5B32"+ - "\u5B37\u5B40\u5C15\u5C1C\u5B5A\u5B65\u5B73\u5B51"+ - "\u5B53\u5B62\u9A75\u9A77\u9A78\u9A7A\u9A7F\u9A7D"+ - "\u9A80\u9A81\u9A85\u9A88\u9A8A\u9A90\u9A92\u9A93"+ - "\u9A96\u9A98\u9A9B\u9A9C\u9A9D\u9A9F\u9AA0\u9AA2"+ - "\u9AA3\u9AA5\u9AA7\u7E9F\u7EA1\u7EA3\u7EA5\u7EA8"+ - "\u7EA9\u93CE\u93CF\u93D0\u93D1\u93D2\u93D3\u93D4"+ - "\u93D5\u93D7\u93D8\u93D9\u93DA\u93DB\u93DC\u93DD"+ - "\u93DE\u93DF\u93E0\u93E1\u93E2\u93E3\u93E4\u93E5"+ - "\u93E6\u93E7\u93E8\u93E9\u93EA\u93EB\u93EC\u93ED"+ - "\u93EE\u93EF\u93F0\u93F1\u93F2\u93F3\u93F4\u93F5"+ - "\u93F6\u93F7\u93F8\u93F9\u93FA\u93FB\u93FC\u93FD"+ - "\u93FE\u93FF\u9400\u9401\u9402\u9403\u9404\u9405"+ - "\u9406\u9407\u9408\u9409\u940A\u940B\u940C\u940D"+ - "\uFFFD\u940E\u940F\u9410\u9411\u9412\u9413\u9414"+ - "\u9415\u9416\u9417\u9418\u9419\u941A\u941B\u941C"+ - "\u941D\u941E\u941F\u9420\u9421\u9422\u9423\u9424"+ - "\u9425\u9426\u9427\u9428\u9429\u942A\u942B\u942C"+ - "\u942D\u942E\u7EAD\u7EB0\u7EBE\u7EC0\u7EC1\u7EC2"+ - "\u7EC9\u7ECB\u7ECC\u7ED0\u7ED4\u7ED7\u7EDB\u7EE0"+ - "\u7EE1\u7EE8\u7EEB\u7EEE\u7EEF\u7EF1\u7EF2\u7F0D"+ - "\u7EF6\u7EFA\u7EFB\u7EFE\u7F01\u7F02\u7F03\u7F07"+ - "\u7F08\u7F0B\u7F0C\u7F0F\u7F11\u7F12\u7F17\u7F19"+ - "\u7F1C\u7F1B\u7F1F\u7F21\u7F22\u7F23\u7F24\u7F25"+ - "\u7F26\u7F27\u7F2A\u7F2B\u7F2C\u7F2D\u7F2F\u7F30"+ - "\u7F31\u7F32\u7F33\u7F35\u5E7A\u757F\u5DDB\u753E"+ - "\u9095\u738E\u7391\u73AE\u73A2\u739F\u73CF\u73C2"+ - "\u73D1\u73B7\u73B3\u73C0\u73C9\u73C8\u73E5\u73D9"+ - "\u987C\u740A\u73E9\u73E7\u73DE\u73BA\u73F2\u740F"+ - "\u742A\u745B\u7426\u7425\u7428\u7430\u742E\u742C"+ - "\u942F\u9430\u9431\u9432\u9433\u9434\u9435\u9436"+ - "\u9437\u9438\u9439\u943A\u943B\u943C\u943D\u943F"+ - "\u9440\u9441\u9442\u9443\u9444\u9445\u9446\u9447"+ - "\u9448\u9449\u944A\u944B\u944C\u944D\u944E\u944F"+ - "\u9450\u9451\u9452\u9453\u9454\u9455\u9456\u9457"+ - "\u9458\u9459\u945A\u945B\u945C\u945D\u945E\u945F"+ - "\u9460\u9461\u9462\u9463\u9464\u9465\u9466\u9467"+ - "\u9468\u9469\u946A\u946C\u946D\u946E\u946F\uFFFD"+ - "\u9470\u9471\u9472\u9473\u9474\u9475\u9476\u9477"+ - "\u9478\u9479\u947A\u947B\u947C\u947D\u947E\u947F"+ - "\u9480\u9481\u9482\u9483\u9484\u9491\u9496\u9498"+ - "\u94C7\u94CF\u94D3\u94D4\u94DA\u94E6\u94FB\u951C"+ - "\u9520\u741B\u741A\u7441\u745C\u7457\u7455\u7459"+ - "\u7477\u746D\u747E\u749C\u748E\u7480\u7481\u7487"+ - "\u748B\u749E\u74A8\u74A9\u7490\u74A7\u74D2\u74BA"+ - "\u97EA\u97EB\u97EC\u674C\u6753\u675E\u6748\u6769"+ - "\u67A5\u6787\u676A\u6773\u6798\u67A7\u6775\u67A8"+ - "\u679E\u67AD\u678B\u6777\u677C\u67F0\u6809\u67D8"+ - "\u680A\u67E9\u67B0\u680C\u67D9\u67B5\u67DA\u67B3"+ - "\u67DD\u6800\u67C3\u67B8\u67E2\u680E\u67C1\u67FD"+ - "\u6832\u6833\u6860\u6861\u684E\u6862\u6844\u6864"+ - "\u6883\u681D\u6855\u6866\u6841\u6867\u6840\u683E"+ - "\u684A\u6849\u6829\u68B5\u688F\u6874\u6877\u6893"+ - "\u686B\u68C2\u696E\u68FC\u691F\u6920\u68F9\u9527"+ - "\u9533\u953D\u9543\u9548\u954B\u9555\u955A\u9560"+ - "\u956E\u9574\u9575\u9577\u9578\u9579\u957A\u957B"+ - "\u957C\u957D\u957E\u9580\u9581\u9582\u9583\u9584"+ - "\u9585\u9586\u9587\u9588\u9589\u958A\u958B\u958C"+ - "\u958D\u958E\u958F\u9590\u9591\u9592\u9593\u9594"+ - "\u9595\u9596\u9597\u9598\u9599\u959A\u959B\u959C"+ - "\u959D\u959E\u959F\u95A0\u95A1\u95A2\u95A3\u95A4"+ - "\u95A5\u95A6\u95A7\u95A8\u95A9\u95AA\uFFFD\u95AB"+ - "\u95AC\u95AD\u95AE\u95AF\u95B0\u95B1\u95B2\u95B3"+ - "\u95B4\u95B5\u95B6\u95B7\u95B8\u95B9\u95BA\u95BB"+ - "\u95BC\u95BD\u95BE\u95BF\u95C0\u95C1\u95C2\u95C3"+ - "\u95C4\u95C5\u95C6\u95C7\u95C8\u95C9\u95CA\u95CB"+ - "\u6924\u68F0\u690B\u6901\u6957\u68E3\u6910\u6971"+ - "\u6939\u6960\u6942\u695D\u6984\u696B\u6980\u6998"+ - "\u6978\u6934\u69CC\u6987\u6988\u69CE\u6989\u6966"+ - "\u6963\u6979\u699B\u69A7\u69BB\u69AB\u69AD\u69D4"+ - "\u69B1\u69C1\u69CA\u69DF\u6995\u69E0\u698D\u69FF"+ - "\u6A2F\u69ED\u6A17\u6A18\u6A65\u69F2\u6A44\u6A3E"+ - "\u6AA0\u6A50\u6A5B\u6A35\u6A8E\u6A79\u6A3D\u6A28"+ - "\u6A58\u6A7C\u6A91\u6A90\u6AA9\u6A97\u6AAB\u7337"+ - "\u7352\u6B81\u6B82\u6B87\u6B84\u6B92\u6B93\u6B8D"+ - "\u6B9A\u6B9B\u6BA1\u6BAA\u8F6B\u8F6D\u8F71\u8F72"+ - "\u8F73\u8F75\u8F76\u8F78\u8F77\u8F79\u8F7A\u8F7C"+ - "\u8F7E\u8F81\u8F82\u8F84\u8F87\u8F8B\u95CC\u95CD"+ - "\u95CE\u95CF\u95D0\u95D1\u95D2\u95D3\u95D4\u95D5"+ - "\u95D6\u95D7\u95D8\u95D9\u95DA\u95DB\u95DC\u95DD"+ - "\u95DE\u95DF\u95E0\u95E1\u95E2\u95E3\u95E4\u95E5"+ - "\u95E6\u95E7\u95EC\u95FF\u9607\u9613\u9618\u961B"+ - "\u961E\u9620\u9623\u9624\u9625\u9626\u9627\u9628"+ - "\u9629\u962B\u962C\u962D\u962F\u9630\u9637\u9638"+ - "\u9639\u963A\u963E\u9641\u9643\u964A\u964E\u964F"+ - "\u9651\u9652\u9653\u9656\u9657\uFFFD\u9658\u9659"+ - "\u965A\u965C\u965D\u965E\u9660\u9663\u9665\u9666"+ - "\u966B\u966D\u966E\u966F\u9670\u9671\u9673\u9678"+ - "\u9679\u967A\u967B\u967C\u967D\u967E\u967F\u9680"+ - "\u9681\u9682\u9683\u9684\u9687\u9689\u968A\u8F8D"+ - "\u8F8E\u8F8F\u8F98\u8F9A\u8ECE\u620B\u6217\u621B"+ - "\u621F\u6222\u6221\u6225\u6224\u622C\u81E7\u74EF"+ - "\u74F4\u74FF\u750F\u7511\u7513\u6534\u65EE\u65EF"+ - "\u65F0\u660A\u6619\u6772\u6603\u6615\u6600\u7085"+ - "\u66F7\u661D\u6634\u6631\u6636\u6635\u8006\u665F"+ - "\u6654\u6641\u664F\u6656\u6661\u6657\u6677\u6684"+ - "\u668C\u66A7\u669D\u66BE\u66DB\u66DC\u66E6\u66E9"+ - "\u8D32\u8D33\u8D36\u8D3B\u8D3D\u8D40\u8D45\u8D46"+ - "\u8D48\u8D49\u8D47\u8D4D\u8D55\u8D59\u89C7\u89CA"+ - "\u89CB\u89CC\u89CE\u89CF\u89D0\u89D1\u726E\u729F"+ - "\u725D\u7266\u726F\u727E\u727F\u7284\u728B\u728D"+ - "\u728F\u7292\u6308\u6332\u63B0\u968C\u968E\u9691"+ - "\u9692\u9693\u9695\u9696\u969A\u969B\u969D\u969E"+ - "\u969F\u96A0\u96A1\u96A2\u96A3\u96A4\u96A5\u96A6"+ - "\u96A8\u96A9\u96AA\u96AB\u96AC\u96AD\u96AE\u96AF"+ - "\u96B1\u96B2\u96B4\u96B5\u96B7\u96B8\u96BA\u96BB"+ - "\u96BF\u96C2\u96C3\u96C8\u96CA\u96CB\u96D0\u96D1"+ - "\u96D3\u96D4\u96D6\u96D7\u96D8\u96D9\u96DA\u96DB"+ - "\u96DC\u96DD\u96DE\u96DF\u96E1\u96E2\u96E3\u96E4"+ - "\u96E5\u96E6\u96E7\u96EB\uFFFD\u96EC\u96ED\u96EE"+ - "\u96F0\u96F1\u96F2\u96F4\u96F5\u96F8\u96FA\u96FB"+ - "\u96FC\u96FD\u96FF\u9702\u9703\u9705\u970A\u970B"+ - "\u970C\u9710\u9711\u9712\u9714\u9715\u9717\u9718"+ - "\u9719\u971A\u971B\u971D\u971F\u9720\u643F\u64D8"+ - "\u8004\u6BEA\u6BF3\u6BFD\u6BF5\u6BF9\u6C05\u6C07"+ - "\u6C06\u6C0D\u6C15\u6C18\u6C19\u6C1A\u6C21\u6C29"+ - "\u6C24\u6C2A\u6C32\u6535\u6555\u656B\u724D\u7252"+ - "\u7256\u7230\u8662\u5216\u809F\u809C\u8093\u80BC"+ - "\u670A\u80BD\u80B1\u80AB\u80AD\u80B4\u80B7\u80E7"+ - "\u80E8\u80E9\u80EA\u80DB\u80C2\u80C4\u80D9\u80CD"+ - "\u80D7\u6710\u80DD\u80EB\u80F1\u80F4\u80ED\u810D"+ - "\u810E\u80F2\u80FC\u6715\u8112\u8C5A\u8136\u811E"+ - "\u812C\u8118\u8132\u8148\u814C\u8153\u8174\u8159"+ - "\u815A\u8171\u8160\u8169\u817C\u817D\u816D\u8167"+ - "\u584D\u5AB5\u8188\u8182\u8191\u6ED5\u81A3\u81AA"+ - "\u81CC\u6726\u81CA\u81BB\u9721\u9722\u9723\u9724"+ - "\u9725\u9726\u9727\u9728\u9729\u972B\u972C\u972E"+ - "\u972F\u9731\u9733\u9734\u9735\u9736\u9737\u973A"+ - "\u973B\u973C\u973D\u973F\u9740\u9741\u9742\u9743"+ - "\u9744\u9745\u9746\u9747\u9748\u9749\u974A\u974B"+ - "\u974C\u974D\u974E\u974F\u9750\u9751\u9754\u9755"+ - "\u9757\u9758\u975A\u975C\u975D\u975F\u9763\u9764"+ - "\u9766\u9767\u9768\u976A\u976B\u976C\u976D\u976E"+ - "\u976F\u9770\u9771\uFFFD\u9772\u9775\u9777\u9778"+ - "\u9779\u977A\u977B\u977D\u977E\u977F\u9780\u9781"+ - "\u9782\u9783\u9784\u9786\u9787\u9788\u9789\u978A"+ - "\u978C\u978E\u978F\u9790\u9793\u9795\u9796\u9797"+ - "\u9799\u979A\u979B\u979C\u979D\u81C1\u81A6\u6B24"+ - "\u6B37\u6B39\u6B43\u6B46\u6B59\u98D1\u98D2\u98D3"+ - "\u98D5\u98D9\u98DA\u6BB3\u5F40\u6BC2\u89F3\u6590"+ - "\u9F51\u6593\u65BC\u65C6\u65C4\u65C3\u65CC\u65CE"+ - "\u65D2\u65D6\u7080\u709C\u7096\u709D\u70BB\u70C0"+ - "\u70B7\u70AB\u70B1\u70E8\u70CA\u7110\u7113\u7116"+ - "\u712F\u7131\u7173\u715C\u7168\u7145\u7172\u714A"+ - "\u7178\u717A\u7198\u71B3\u71B5\u71A8\u71A0\u71E0"+ - "\u71D4\u71E7\u71F9\u721D\u7228\u706C\u7118\u7166"+ - "\u71B9\u623E\u623D\u6243\u6248\u6249\u793B\u7940"+ - "\u7946\u7949\u795B\u795C\u7953\u795A\u7962\u7957"+ - "\u7960\u796F\u7967\u797A\u7985\u798A\u799A\u79A7"+ - "\u79B3\u5FD1\u5FD0\u979E\u979F\u97A1\u97A2\u97A4"+ - "\u97A5\u97A6\u97A7\u97A8\u97A9\u97AA\u97AC\u97AE"+ - "\u97B0\u97B1\u97B3\u97B5\u97B6\u97B7\u97B8\u97B9"+ - "\u97BA\u97BB\u97BC\u97BD\u97BE\u97BF\u97C0\u97C1"+ - "\u97C2\u97C3\u97C4\u97C5\u97C6\u97C7\u97C8\u97C9"+ - "\u97CA\u97CB\u97CC\u97CD\u97CE\u97CF\u97D0\u97D1"+ - "\u97D2\u97D3\u97D4\u97D5\u97D6\u97D7\u97D8\u97D9"+ - "\u97DA\u97DB\u97DC\u97DD\u97DE\u97DF\u97E0\u97E1"+ - "\u97E2\u97E3\uFFFD\u97E4\u97E5\u97E8\u97EE\u97EF"+ - "\u97F0\u97F1\u97F2\u97F4\u97F7\u97F8\u97F9\u97FA"+ - "\u97FB\u97FC\u97FD\u97FE\u97FF\u9800\u9801\u9802"+ - "\u9803\u9804\u9805\u9806\u9807\u9808\u9809\u980A"+ - "\u980B\u980C\u980D\u980E\u603C\u605D\u605A\u6067"+ - "\u6041\u6059\u6063\u60AB\u6106\u610D\u615D\u61A9"+ - "\u619D\u61CB\u61D1\u6206\u8080\u807F\u6C93\u6CF6"+ - "\u6DFC\u77F6\u77F8\u7800\u7809\u7817\u7818\u7811"+ - "\u65AB\u782D\u781C\u781D\u7839\u783A\u783B\u781F"+ - "\u783C\u7825\u782C\u7823\u7829\u784E\u786D\u7856"+ - "\u7857\u7826\u7850\u7847\u784C\u786A\u789B\u7893"+ - "\u789A\u7887\u789C\u78A1\u78A3\u78B2\u78B9\u78A5"+ - "\u78D4\u78D9\u78C9\u78EC\u78F2\u7905\u78F4\u7913"+ - "\u7924\u791E\u7934\u9F9B\u9EF9\u9EFB\u9EFC\u76F1"+ - "\u7704\u770D\u76F9\u7707\u7708\u771A\u7722\u7719"+ - "\u772D\u7726\u7735\u7738\u7750\u7751\u7747\u7743"+ - "\u775A\u7768\u980F\u9810\u9811\u9812\u9813\u9814"+ - "\u9815\u9816\u9817\u9818\u9819\u981A\u981B\u981C"+ - "\u981D\u981E\u981F\u9820\u9821\u9822\u9823\u9824"+ - "\u9825\u9826\u9827\u9828\u9829\u982A\u982B\u982C"+ - "\u982D\u982E\u982F\u9830\u9831\u9832\u9833\u9834"+ - "\u9835\u9836\u9837\u9838\u9839\u983A\u983B\u983C"+ - "\u983D\u983E\u983F\u9840\u9841\u9842\u9843\u9844"+ - "\u9845\u9846\u9847\u9848\u9849\u984A\u984B\u984C"+ - "\u984D\uFFFD\u984E\u984F\u9850\u9851\u9852\u9853"+ - "\u9854\u9855\u9856\u9857\u9858\u9859\u985A\u985B"+ - "\u985C\u985D\u985E\u985F\u9860\u9861\u9862\u9863"+ - "\u9864\u9865\u9866\u9867\u9868\u9869\u986A\u986B"+ - "\u986C\u986D\u986E\u7762\u7765\u777F\u778D\u777D"+ - "\u7780\u778C\u7791\u779F\u77A0\u77B0\u77B5\u77BD"+ - "\u753A\u7540\u754E\u754B\u7548\u755B\u7572\u7579"+ - "\u7583\u7F58\u7F61\u7F5F\u8A48\u7F68\u7F74\u7F71"+ - "\u7F79\u7F81\u7F7E\u76CD\u76E5\u8832\u9485\u9486"+ - "\u9487\u948B\u948A\u948C\u948D\u948F\u9490\u9494"+ - "\u9497\u9495\u949A\u949B\u949C\u94A3\u94A4\u94AB"+ - "\u94AA\u94AD\u94AC\u94AF\u94B0\u94B2\u94B4\u94B6"+ - "\u94B7\u94B8\u94B9\u94BA\u94BC\u94BD\u94BF\u94C4"+ - "\u94C8\u94C9\u94CA\u94CB\u94CC\u94CD\u94CE\u94D0"+ - "\u94D1\u94D2\u94D5\u94D6\u94D7\u94D9\u94D8\u94DB"+ - "\u94DE\u94DF\u94E0\u94E2\u94E4\u94E5\u94E7\u94E8"+ - "\u94EA\u986F\u9870\u9871\u9872\u9873\u9874\u988B"+ - "\u988E\u9892\u9895\u9899\u98A3\u98A8\u98A9\u98AA"+ - "\u98AB\u98AC\u98AD\u98AE\u98AF\u98B0\u98B1\u98B2"+ - "\u98B3\u98B4\u98B5\u98B6\u98B7\u98B8\u98B9\u98BA"+ - "\u98BB\u98BC\u98BD\u98BE\u98BF\u98C0\u98C1\u98C2"+ - "\u98C3\u98C4\u98C5\u98C6\u98C7\u98C8\u98C9\u98CA"+ - "\u98CB\u98CC\u98CD\u98CF\u98D0\u98D4\u98D6\u98D7"+ - "\u98DB\u98DC\u98DD\u98E0\u98E1\u98E2\u98E3\u98E4"+ - "\uFFFD\u98E5\u98E6\u98E9\u98EA\u98EB\u98EC\u98ED"+ - "\u98EE\u98EF\u98F0\u98F1\u98F2\u98F3\u98F4\u98F5"+ - "\u98F6\u98F7\u98F8\u98F9\u98FA\u98FB\u98FC\u98FD"+ - "\u98FE\u98FF\u9900\u9901\u9902\u9903\u9904\u9905"+ - "\u9906\u9907\u94E9\u94EB\u94EE\u94EF\u94F3\u94F4"+ - "\u94F5\u94F7\u94F9\u94FC\u94FD\u94FF\u9503\u9502"+ - "\u9506\u9507\u9509\u950A\u950D\u950E\u950F\u9512"+ - "\u9513\u9514\u9515\u9516\u9518\u951B\u951D\u951E"+ - "\u951F\u9522\u952A\u952B\u9529\u952C\u9531\u9532"+ - "\u9534\u9536\u9537\u9538\u953C\u953E\u953F\u9542"+ - "\u9535\u9544\u9545\u9546\u9549\u954C\u954E\u954F"+ - "\u9552\u9553\u9554\u9556\u9557\u9558\u9559\u955B"+ - "\u955E\u955F\u955D\u9561\u9562\u9564\u9565\u9566"+ - "\u9567\u9568\u9569\u956A\u956B\u956C\u956F\u9571"+ - "\u9572\u9573\u953A\u77E7\u77EC\u96C9\u79D5\u79ED"+ - "\u79E3\u79EB\u7A06\u5D47\u7A03\u7A02\u7A1E\u7A14"; - - private static final String innerIndex7= - "\u9908\u9909\u990A\u990B\u990C\u990E\u990F\u9911"+ - "\u9912\u9913\u9914\u9915\u9916\u9917\u9918\u9919"+ - "\u991A\u991B\u991C\u991D\u991E\u991F\u9920\u9921"+ - "\u9922\u9923\u9924\u9925\u9926\u9927\u9928\u9929"+ - "\u992A\u992B\u992C\u992D\u992F\u9930\u9931\u9932"+ - "\u9933\u9934\u9935\u9936\u9937\u9938\u9939\u993A"+ - "\u993B\u993C\u993D\u993E\u993F\u9940\u9941\u9942"+ - "\u9943\u9944\u9945\u9946\u9947\u9948\u9949\uFFFD"+ - "\u994A\u994B\u994C\u994D\u994E\u994F\u9950\u9951"+ - "\u9952\u9953\u9956\u9957\u9958\u9959\u995A\u995B"+ - "\u995C\u995D\u995E\u995F\u9960\u9961\u9962\u9964"+ - "\u9966\u9973\u9978\u9979\u997B\u997E\u9982\u9983"+ - "\u9989\u7A39\u7A37\u7A51\u9ECF\u99A5\u7A70\u7688"+ - "\u768E\u7693\u7699\u76A4\u74DE\u74E0\u752C\u9E20"+ - "\u9E22\u9E28\u9E29\u9E2A\u9E2B\u9E2C\u9E32\u9E31"+ - "\u9E36\u9E38\u9E37\u9E39\u9E3A\u9E3E\u9E41\u9E42"+ - "\u9E44\u9E46\u9E47\u9E48\u9E49\u9E4B\u9E4C\u9E4E"+ - "\u9E51\u9E55\u9E57\u9E5A\u9E5B\u9E5C\u9E5E\u9E63"+ - "\u9E66\u9E67\u9E68\u9E69\u9E6A\u9E6B\u9E6C\u9E71"+ - "\u9E6D\u9E73\u7592\u7594\u7596\u75A0\u759D\u75AC"+ - "\u75A3\u75B3\u75B4\u75B8\u75C4\u75B1\u75B0\u75C3"+ - "\u75C2\u75D6\u75CD\u75E3\u75E8\u75E6\u75E4\u75EB"+ - "\u75E7\u7603\u75F1\u75FC\u75FF\u7610\u7600\u7605"+ - "\u760C\u7617\u760A\u7625\u7618\u7615\u7619\u998C"+ - "\u998E\u999A\u999B\u999C\u999D\u999E\u999F\u99A0"+ - "\u99A1\u99A2\u99A3\u99A4\u99A6\u99A7\u99A9\u99AA"+ - "\u99AB\u99AC\u99AD\u99AE\u99AF\u99B0\u99B1\u99B2"+ - "\u99B3\u99B4\u99B5\u99B6\u99B7\u99B8\u99B9\u99BA"+ - "\u99BB\u99BC\u99BD\u99BE\u99BF\u99C0\u99C1\u99C2"+ - "\u99C3\u99C4\u99C5\u99C6\u99C7\u99C8\u99C9\u99CA"+ - "\u99CB\u99CC\u99CD\u99CE\u99CF\u99D0\u99D1\u99D2"+ - "\u99D3\u99D4\u99D5\u99D6\u99D7\u99D8\uFFFD\u99D9"+ - "\u99DA\u99DB\u99DC\u99DD\u99DE\u99DF\u99E0\u99E1"+ - "\u99E2\u99E3\u99E4\u99E5\u99E6\u99E7\u99E8\u99E9"+ - "\u99EA\u99EB\u99EC\u99ED\u99EE\u99EF\u99F0\u99F1"+ - "\u99F2\u99F3\u99F4\u99F5\u99F6\u99F7\u99F8\u99F9"+ - "\u761B\u763C\u7622\u7620\u7640\u762D\u7630\u763F"+ - "\u7635\u7643\u763E\u7633\u764D\u765E\u7654\u765C"+ - "\u7656\u766B\u766F\u7FCA\u7AE6\u7A78\u7A79\u7A80"+ - "\u7A86\u7A88\u7A95\u7AA6\u7AA0\u7AAC\u7AA8\u7AAD"+ - "\u7AB3\u8864\u8869\u8872\u887D\u887F\u8882\u88A2"+ - "\u88C6\u88B7\u88BC\u88C9\u88E2\u88CE\u88E3\u88E5"+ - "\u88F1\u891A\u88FC\u88E8\u88FE\u88F0\u8921\u8919"+ - "\u8913\u891B\u890A\u8934\u892B\u8936\u8941\u8966"+ - "\u897B\u758B\u80E5\u76B2\u76B4\u77DC\u8012\u8014"+ - "\u8016\u801C\u8020\u8022\u8025\u8026\u8027\u8029"+ - "\u8028\u8031\u800B\u8035\u8043\u8046\u804D\u8052"+ - "\u8069\u8071\u8983\u9878\u9880\u9883\u99FA\u99FB"+ - "\u99FC\u99FD\u99FE\u99FF\u9A00\u9A01\u9A02\u9A03"+ - "\u9A04\u9A05\u9A06\u9A07\u9A08\u9A09\u9A0A\u9A0B"+ - "\u9A0C\u9A0D\u9A0E\u9A0F\u9A10\u9A11\u9A12\u9A13"+ - "\u9A14\u9A15\u9A16\u9A17\u9A18\u9A19\u9A1A\u9A1B"+ - "\u9A1C\u9A1D\u9A1E\u9A1F\u9A20\u9A21\u9A22\u9A23"+ - "\u9A24\u9A25\u9A26\u9A27\u9A28\u9A29\u9A2A\u9A2B"+ - "\u9A2C\u9A2D\u9A2E\u9A2F\u9A30\u9A31\u9A32\u9A33"+ - "\u9A34\u9A35\u9A36\u9A37\u9A38\uFFFD\u9A39\u9A3A"+ - "\u9A3B\u9A3C\u9A3D\u9A3E\u9A3F\u9A40\u9A41\u9A42"+ - "\u9A43\u9A44\u9A45\u9A46\u9A47\u9A48\u9A49\u9A4A"+ - "\u9A4B\u9A4C\u9A4D\u9A4E\u9A4F\u9A50\u9A51\u9A52"+ - "\u9A53\u9A54\u9A55\u9A56\u9A57\u9A58\u9A59\u9889"+ - "\u988C\u988D\u988F\u9894\u989A\u989B\u989E\u989F"+ - "\u98A1\u98A2\u98A5\u98A6\u864D\u8654\u866C\u866E"+ - "\u867F\u867A\u867C\u867B\u86A8\u868D\u868B\u86AC"+ - "\u869D\u86A7\u86A3\u86AA\u8693\u86A9\u86B6\u86C4"+ - "\u86B5\u86CE\u86B0\u86BA\u86B1\u86AF\u86C9\u86CF"+ - "\u86B4\u86E9\u86F1\u86F2\u86ED\u86F3\u86D0\u8713"+ - "\u86DE\u86F4\u86DF\u86D8\u86D1\u8703\u8707\u86F8"+ - "\u8708\u870A\u870D\u8709\u8723\u873B\u871E\u8725"+ - "\u872E\u871A\u873E\u8748\u8734\u8731\u8729\u8737"+ - "\u873F\u8782\u8722\u877D\u877E\u877B\u8760\u8770"+ - "\u874C\u876E\u878B\u8753\u8763\u877C\u8764\u8759"+ - "\u8765\u8793\u87AF\u87A8\u87D2\u9A5A\u9A5B\u9A5C"+ - "\u9A5D\u9A5E\u9A5F\u9A60\u9A61\u9A62\u9A63\u9A64"+ - "\u9A65\u9A66\u9A67\u9A68\u9A69\u9A6A\u9A6B\u9A72"+ - "\u9A83\u9A89\u9A8D\u9A8E\u9A94\u9A95\u9A99\u9AA6"+ - "\u9AA9\u9AAA\u9AAB\u9AAC\u9AAD\u9AAE\u9AAF\u9AB2"+ - "\u9AB3\u9AB4\u9AB5\u9AB9\u9ABB\u9ABD\u9ABE\u9ABF"+ - "\u9AC3\u9AC4\u9AC6\u9AC7\u9AC8\u9AC9\u9ACA\u9ACD"+ - "\u9ACE\u9ACF\u9AD0\u9AD2\u9AD4\u9AD5\u9AD6\u9AD7"+ - "\u9AD9\u9ADA\u9ADB\u9ADC\uFFFD\u9ADD\u9ADE\u9AE0"+ - "\u9AE2\u9AE3\u9AE4\u9AE5\u9AE7\u9AE8\u9AE9\u9AEA"+ - "\u9AEC\u9AEE\u9AF0\u9AF1\u9AF2\u9AF3\u9AF4\u9AF5"+ - "\u9AF6\u9AF7\u9AF8\u9AFA\u9AFC\u9AFD\u9AFE\u9AFF"+ - "\u9B00\u9B01\u9B02\u9B04\u9B05\u9B06\u87C6\u8788"+ - "\u8785\u87AD\u8797\u8783\u87AB\u87E5\u87AC\u87B5"+ - "\u87B3\u87CB\u87D3\u87BD\u87D1\u87C0\u87CA\u87DB"+ - "\u87EA\u87E0\u87EE\u8816\u8813\u87FE\u880A\u881B"+ - "\u8821\u8839\u883C\u7F36\u7F42\u7F44\u7F45\u8210"+ - "\u7AFA\u7AFD\u7B08\u7B03\u7B04\u7B15\u7B0A\u7B2B"+ - "\u7B0F\u7B47\u7B38\u7B2A\u7B19\u7B2E\u7B31\u7B20"+ - "\u7B25\u7B24\u7B33\u7B3E\u7B1E\u7B58\u7B5A\u7B45"+ - "\u7B75\u7B4C\u7B5D\u7B60\u7B6E\u7B7B\u7B62\u7B72"+ - "\u7B71\u7B90\u7BA6\u7BA7\u7BB8\u7BAC\u7B9D\u7BA8"+ - "\u7B85\u7BAA\u7B9C\u7BA2\u7BAB\u7BB4\u7BD1\u7BC1"+ - "\u7BCC\u7BDD\u7BDA\u7BE5\u7BE6\u7BEA\u7C0C\u7BFE"+ - "\u7BFC\u7C0F\u7C16\u7C0B\u9B07\u9B09\u9B0A\u9B0B"+ - "\u9B0C\u9B0D\u9B0E\u9B10\u9B11\u9B12\u9B14\u9B15"+ - "\u9B16\u9B17\u9B18\u9B19\u9B1A\u9B1B\u9B1C\u9B1D"+ - "\u9B1E\u9B20\u9B21\u9B22\u9B24\u9B25\u9B26\u9B27"+ - "\u9B28\u9B29\u9B2A\u9B2B\u9B2C\u9B2D\u9B2E\u9B30"+ - "\u9B31\u9B33\u9B34\u9B35\u9B36\u9B37\u9B38\u9B39"+ - "\u9B3A\u9B3D\u9B3E\u9B3F\u9B40\u9B46\u9B4A\u9B4B"+ - "\u9B4C\u9B4E\u9B50\u9B52\u9B53\u9B55\u9B56\u9B57"+ - "\u9B58\u9B59\u9B5A\uFFFD\u9B5B\u9B5C\u9B5D\u9B5E"+ - "\u9B5F\u9B60\u9B61\u9B62\u9B63\u9B64\u9B65\u9B66"+ - "\u9B67\u9B68\u9B69\u9B6A\u9B6B\u9B6C\u9B6D\u9B6E"+ - "\u9B6F\u9B70\u9B71\u9B72\u9B73\u9B74\u9B75\u9B76"+ - "\u9B77\u9B78\u9B79\u9B7A\u9B7B\u7C1F\u7C2A\u7C26"+ - "\u7C38\u7C41\u7C40\u81FE\u8201\u8202\u8204\u81EC"+ - "\u8844\u8221\u8222\u8223\u822D\u822F\u8228\u822B"+ - "\u8238\u823B\u8233\u8234\u823E\u8244\u8249\u824B"+ - "\u824F\u825A\u825F\u8268\u887E\u8885\u8888\u88D8"+ - "\u88DF\u895E\u7F9D\u7F9F\u7FA7\u7FAF\u7FB0\u7FB2"+ - "\u7C7C\u6549\u7C91\u7C9D\u7C9C\u7C9E\u7CA2\u7CB2"+ - "\u7CBC\u7CBD\u7CC1\u7CC7\u7CCC\u7CCD\u7CC8\u7CC5"+ - "\u7CD7\u7CE8\u826E\u66A8\u7FBF\u7FCE\u7FD5\u7FE5"+ - "\u7FE1\u7FE6\u7FE9\u7FEE\u7FF3\u7CF8\u7D77\u7DA6"+ - "\u7DAE\u7E47\u7E9B\u9EB8\u9EB4\u8D73\u8D84\u8D94"+ - "\u8D91\u8DB1\u8D67\u8D6D\u8C47\u8C49\u914A\u9150"+ - "\u914E\u914F\u9164\u9B7C\u9B7D\u9B7E\u9B7F\u9B80"+ - "\u9B81\u9B82\u9B83\u9B84\u9B85\u9B86\u9B87\u9B88"+ - "\u9B89\u9B8A\u9B8B\u9B8C\u9B8D\u9B8E\u9B8F\u9B90"+ - "\u9B91\u9B92\u9B93\u9B94\u9B95\u9B96\u9B97\u9B98"+ - "\u9B99\u9B9A\u9B9B\u9B9C\u9B9D\u9B9E\u9B9F\u9BA0"+ - "\u9BA1\u9BA2\u9BA3\u9BA4\u9BA5\u9BA6\u9BA7\u9BA8"+ - "\u9BA9\u9BAA\u9BAB\u9BAC\u9BAD\u9BAE\u9BAF\u9BB0"+ - "\u9BB1\u9BB2\u9BB3\u9BB4\u9BB5\u9BB6\u9BB7\u9BB8"+ - "\u9BB9\u9BBA\uFFFD\u9BBB\u9BBC\u9BBD\u9BBE\u9BBF"+ - "\u9BC0\u9BC1\u9BC2\u9BC3\u9BC4\u9BC5\u9BC6\u9BC7"+ - "\u9BC8\u9BC9\u9BCA\u9BCB\u9BCC\u9BCD\u9BCE\u9BCF"+ - "\u9BD0\u9BD1\u9BD2\u9BD3\u9BD4\u9BD5\u9BD6\u9BD7"+ - "\u9BD8\u9BD9\u9BDA\u9BDB\u9162\u9161\u9170\u9169"+ - "\u916F\u917D\u917E\u9172\u9174\u9179\u918C\u9185"+ - "\u9190\u918D\u9191\u91A2\u91A3\u91AA\u91AD\u91AE"+ - "\u91AF\u91B5\u91B4\u91BA\u8C55\u9E7E\u8DB8\u8DEB"+ - "\u8E05\u8E59\u8E69\u8DB5\u8DBF\u8DBC\u8DBA\u8DC4"+ - "\u8DD6\u8DD7\u8DDA\u8DDE\u8DCE\u8DCF\u8DDB\u8DC6"+ - "\u8DEC\u8DF7\u8DF8\u8DE3\u8DF9\u8DFB\u8DE4\u8E09"+ - "\u8DFD\u8E14\u8E1D\u8E1F\u8E2C\u8E2E\u8E23\u8E2F"+ - "\u8E3A\u8E40\u8E39\u8E35\u8E3D\u8E31\u8E49\u8E41"+ - "\u8E42\u8E51\u8E52\u8E4A\u8E70\u8E76\u8E7C\u8E6F"+ - "\u8E74\u8E85\u8E8F\u8E94\u8E90\u8E9C\u8E9E\u8C78"+ - "\u8C82\u8C8A\u8C85\u8C98\u8C94\u659B\u89D6\u89DE"+ - "\u89DA\u89DC\u9BDC\u9BDD\u9BDE\u9BDF\u9BE0\u9BE1"+ - "\u9BE2\u9BE3\u9BE4\u9BE5\u9BE6\u9BE7\u9BE8\u9BE9"+ - "\u9BEA\u9BEB\u9BEC\u9BED\u9BEE\u9BEF\u9BF0\u9BF1"+ - "\u9BF2\u9BF3\u9BF4\u9BF5\u9BF6\u9BF7\u9BF8\u9BF9"+ - "\u9BFA\u9BFB\u9BFC\u9BFD\u9BFE\u9BFF\u9C00\u9C01"+ - "\u9C02\u9C03\u9C04\u9C05\u9C06\u9C07\u9C08\u9C09"+ - "\u9C0A\u9C0B\u9C0C\u9C0D\u9C0E\u9C0F\u9C10\u9C11"+ - "\u9C12\u9C13\u9C14\u9C15\u9C16\u9C17\u9C18\u9C19"+ - "\u9C1A\uFFFD\u9C1B\u9C1C\u9C1D\u9C1E\u9C1F\u9C20"+ - "\u9C21\u9C22\u9C23\u9C24\u9C25\u9C26\u9C27\u9C28"+ - "\u9C29\u9C2A\u9C2B\u9C2C\u9C2D\u9C2E\u9C2F\u9C30"+ - "\u9C31\u9C32\u9C33\u9C34\u9C35\u9C36\u9C37\u9C38"+ - "\u9C39\u9C3A\u9C3B\u89E5\u89EB\u89EF\u8A3E\u8B26"+ - "\u9753\u96E9\u96F3\u96EF\u9706\u9701\u9708\u970F"+ - "\u970E\u972A\u972D\u9730\u973E\u9F80\u9F83\u9F85"+ - "\u9F86\u9F87\u9F88\u9F89\u9F8A\u9F8C\u9EFE\u9F0B"+ - "\u9F0D\u96B9\u96BC\u96BD\u96CE\u96D2\u77BF\u96E0"+ - "\u928E\u92AE\u92C8\u933E\u936A\u93CA\u938F\u943E"+ - "\u946B\u9C7F\u9C82\u9C85\u9C86\u9C87\u9C88\u7A23"+ - "\u9C8B\u9C8E\u9C90\u9C91\u9C92\u9C94\u9C95\u9C9A"+ - "\u9C9B\u9C9E\u9C9F\u9CA0\u9CA1\u9CA2\u9CA3\u9CA5"+ - "\u9CA6\u9CA7\u9CA8\u9CA9\u9CAB\u9CAD\u9CAE\u9CB0"+ - "\u9CB1\u9CB2\u9CB3\u9CB4\u9CB5\u9CB6\u9CB7\u9CBA"+ - "\u9CBB\u9CBC\u9CBD\u9CC4\u9CC5\u9CC6\u9CC7\u9CCA"+ - "\u9CCB\u9C3C\u9C3D\u9C3E\u9C3F\u9C40\u9C41\u9C42"+ - "\u9C43\u9C44\u9C45\u9C46\u9C47\u9C48\u9C49\u9C4A"+ - "\u9C4B\u9C4C\u9C4D\u9C4E\u9C4F\u9C50\u9C51\u9C52"+ - "\u9C53\u9C54\u9C55\u9C56\u9C57\u9C58\u9C59\u9C5A"+ - "\u9C5B\u9C5C\u9C5D\u9C5E\u9C5F\u9C60\u9C61\u9C62"+ - "\u9C63\u9C64\u9C65\u9C66\u9C67\u9C68\u9C69\u9C6A"+ - "\u9C6B\u9C6C\u9C6D\u9C6E\u9C6F\u9C70\u9C71\u9C72"+ - "\u9C73\u9C74\u9C75\u9C76\u9C77\u9C78\u9C79\u9C7A"+ - "\uFFFD\u9C7B\u9C7D\u9C7E\u9C80\u9C83\u9C84\u9C89"+ - "\u9C8A\u9C8C\u9C8F\u9C93\u9C96\u9C97\u9C98\u9C99"+ - "\u9C9D\u9CAA\u9CAC\u9CAF\u9CB9\u9CBE\u9CBF\u9CC0"+ - "\u9CC1\u9CC2\u9CC8\u9CC9\u9CD1\u9CD2\u9CDA\u9CDB"+ - "\u9CE0\u9CE1\u9CCC\u9CCD\u9CCE\u9CCF\u9CD0\u9CD3"+ - "\u9CD4\u9CD5\u9CD7\u9CD8\u9CD9\u9CDC\u9CDD\u9CDF"+ - "\u9CE2\u977C\u9785\u9791\u9792\u9794\u97AF\u97AB"+ - "\u97A3\u97B2\u97B4\u9AB1\u9AB0\u9AB7\u9E58\u9AB6"+ - "\u9ABA\u9ABC\u9AC1\u9AC0\u9AC5\u9AC2\u9ACB\u9ACC"+ - "\u9AD1\u9B45\u9B43\u9B47\u9B49\u9B48\u9B4D\u9B51"+ - "\u98E8\u990D\u992E\u9955\u9954\u9ADF\u9AE1\u9AE6"+ - "\u9AEF\u9AEB\u9AFB\u9AED\u9AF9\u9B08\u9B0F\u9B13"+ - "\u9B1F\u9B23\u9EBD\u9EBE\u7E3B\u9E82\u9E87\u9E88"+ - "\u9E8B\u9E92\u93D6\u9E9D\u9E9F\u9EDB\u9EDC\u9EDD"+ - "\u9EE0\u9EDF\u9EE2\u9EE9\u9EE7\u9EE5\u9EEA\u9EEF"+ - "\u9F22\u9F2C\u9F2F\u9F39\u9F37\u9F3D\u9F3E\u9F44"+ - "\u9CE3\u9CE4\u9CE5\u9CE6\u9CE7\u9CE8\u9CE9\u9CEA"+ - "\u9CEB\u9CEC\u9CED\u9CEE\u9CEF\u9CF0\u9CF1\u9CF2"+ - "\u9CF3\u9CF4\u9CF5\u9CF6\u9CF7\u9CF8\u9CF9\u9CFA"+ - "\u9CFB\u9CFC\u9CFD\u9CFE\u9CFF\u9D00\u9D01\u9D02"+ - "\u9D03\u9D04\u9D05\u9D06\u9D07\u9D08\u9D09\u9D0A"+ - "\u9D0B\u9D0C\u9D0D\u9D0E\u9D0F\u9D10\u9D11\u9D12"+ - "\u9D13\u9D14\u9D15\u9D16\u9D17\u9D18\u9D19\u9D1A"+ - "\u9D1B\u9D1C\u9D1D\u9D1E\u9D1F\u9D20\u9D21\uFFFD"+ - "\u9D22\u9D23\u9D24\u9D25\u9D26\u9D27\u9D28\u9D29"+ - "\u9D2A\u9D2B\u9D2C\u9D2D\u9D2E\u9D2F\u9D30\u9D31"+ - "\u9D32\u9D33\u9D34\u9D35\u9D36\u9D37\u9D38\u9D39"+ - "\u9D3A\u9D3B\u9D3C\u9D3D\u9D3E\u9D3F\u9D40\u9D41"+ - "\u9D42\uE234\uE235\uE236\uE237\uE238\uE239\uE23A"+ - "\uE23B\uE23C\uE23D\uE23E\uE23F\uE240\uE241\uE242"+ - "\uE243\uE244\uE245\uE246\uE247\uE248\uE249\uE24A"+ - "\uE24B\uE24C\uE24D\uE24E\uE24F\uE250\uE251\uE252"+ - "\uE253\uE254\uE255\uE256\uE257\uE258\uE259\uE25A"+ - "\uE25B\uE25C\uE25D\uE25E\uE25F\uE260\uE261\uE262"+ - "\uE263\uE264\uE265\uE266\uE267\uE268\uE269\uE26A"+ - "\uE26B\uE26C\uE26D\uE26E\uE26F\uE270\uE271\uE272"+ - "\uE273\uE274\uE275\uE276\uE277\uE278\uE279\uE27A"+ - "\uE27B\uE27C\uE27D\uE27E\uE27F\uE280\uE281\uE282"+ - "\uE283\uE284\uE285\uE286\uE287\uE288\uE289\uE28A"+ - "\uE28B\uE28C\uE28D\uE28E\uE28F\uE290\uE291\u9D43"+ - "\u9D44\u9D45\u9D46\u9D47\u9D48\u9D49\u9D4A\u9D4B"+ - "\u9D4C\u9D4D\u9D4E\u9D4F\u9D50\u9D51\u9D52\u9D53"+ - "\u9D54\u9D55\u9D56\u9D57\u9D58\u9D59\u9D5A\u9D5B"+ - "\u9D5C\u9D5D\u9D5E\u9D5F\u9D60\u9D61\u9D62\u9D63"+ - "\u9D64\u9D65\u9D66\u9D67\u9D68\u9D69\u9D6A\u9D6B"+ - "\u9D6C\u9D6D\u9D6E\u9D6F\u9D70\u9D71\u9D72\u9D73"+ - "\u9D74\u9D75\u9D76\u9D77\u9D78\u9D79\u9D7A\u9D7B"+ - "\u9D7C\u9D7D\u9D7E\u9D7F\u9D80\u9D81\uFFFD\u9D82"+ - "\u9D83\u9D84\u9D85\u9D86\u9D87\u9D88\u9D89\u9D8A"+ - "\u9D8B\u9D8C\u9D8D\u9D8E\u9D8F\u9D90\u9D91\u9D92"+ - "\u9D93\u9D94\u9D95\u9D96\u9D97\u9D98\u9D99\u9D9A"+ - "\u9D9B\u9D9C\u9D9D\u9D9E\u9D9F\u9DA0\u9DA1\u9DA2"+ - "\uE292\uE293\uE294\uE295\uE296\uE297\uE298\uE299"+ - "\uE29A\uE29B\uE29C\uE29D\uE29E\uE29F\uE2A0\uE2A1"+ - "\uE2A2\uE2A3\uE2A4\uE2A5\uE2A6\uE2A7\uE2A8\uE2A9"+ - "\uE2AA\uE2AB\uE2AC\uE2AD\uE2AE\uE2AF\uE2B0\uE2B1"+ - "\uE2B2\uE2B3\uE2B4\uE2B5\uE2B6\uE2B7\uE2B8\uE2B9"+ - "\uE2BA\uE2BB\uE2BC\uE2BD\uE2BE\uE2BF\uE2C0\uE2C1"+ - "\uE2C2\uE2C3\uE2C4\uE2C5\uE2C6\uE2C7\uE2C8\uE2C9"+ - "\uE2CA\uE2CB\uE2CC\uE2CD\uE2CE\uE2CF\uE2D0\uE2D1"+ - "\uE2D2\uE2D3\uE2D4\uE2D5\uE2D6\uE2D7\uE2D8\uE2D9"+ - "\uE2DA\uE2DB\uE2DC\uE2DD\uE2DE\uE2DF\uE2E0\uE2E1"+ - "\uE2E2\uE2E3\uE2E4\uE2E5\uE2E6\uE2E7\uE2E8\uE2E9"+ - "\uE2EA\uE2EB\uE2EC\uE2ED\uE2EE\uE2EF\u9DA3\u9DA4"+ - "\u9DA5\u9DA6\u9DA7\u9DA8\u9DA9\u9DAA\u9DAB\u9DAC"+ - "\u9DAD\u9DAE\u9DAF\u9DB0\u9DB1\u9DB2\u9DB3\u9DB4"+ - "\u9DB5\u9DB6\u9DB7\u9DB8\u9DB9\u9DBA\u9DBB\u9DBC"+ - "\u9DBD\u9DBE\u9DBF\u9DC0\u9DC1\u9DC2\u9DC3\u9DC4"+ - "\u9DC5\u9DC6\u9DC7\u9DC8\u9DC9\u9DCA\u9DCB\u9DCC"+ - "\u9DCD\u9DCE\u9DCF\u9DD0\u9DD1\u9DD2\u9DD3\u9DD4"+ - "\u9DD5\u9DD6\u9DD7\u9DD8\u9DD9\u9DDA\u9DDB\u9DDC"+ - "\u9DDD\u9DDE\u9DDF\u9DE0\u9DE1\uFFFD\u9DE2\u9DE3"+ - "\u9DE4\u9DE5\u9DE6\u9DE7\u9DE8\u9DE9\u9DEA\u9DEB"+ - "\u9DEC\u9DED\u9DEE\u9DEF\u9DF0\u9DF1\u9DF2\u9DF3"+ - "\u9DF4\u9DF5\u9DF6\u9DF7\u9DF8\u9DF9\u9DFA\u9DFB"+ - "\u9DFC\u9DFD\u9DFE\u9DFF\u9E00\u9E01\u9E02\uE2F0"+ - "\uE2F1\uE2F2\uE2F3\uE2F4\uE2F5\uE2F6\uE2F7\uE2F8"+ - "\uE2F9\uE2FA\uE2FB\uE2FC\uE2FD\uE2FE\uE2FF\uE300"+ - "\uE301\uE302\uE303\uE304\uE305\uE306\uE307\uE308"+ - "\uE309\uE30A\uE30B\uE30C\uE30D\uE30E\uE30F\uE310"+ - "\uE311\uE312\uE313\uE314\uE315\uE316\uE317\uE318"+ - "\uE319\uE31A\uE31B\uE31C\uE31D\uE31E\uE31F\uE320"+ - "\uE321\uE322\uE323\uE324\uE325\uE326\uE327\uE328"+ - "\uE329\uE32A\uE32B\uE32C\uE32D\uE32E\uE32F\uE330"+ - "\uE331\uE332\uE333\uE334\uE335\uE336\uE337\uE338"+ - "\uE339\uE33A\uE33B\uE33C\uE33D\uE33E\uE33F\uE340"+ - "\uE341\uE342\uE343\uE344\uE345\uE346\uE347\uE348"+ - "\uE349\uE34A\uE34B\uE34C\uE34D\u9E03\u9E04\u9E05"+ - "\u9E06\u9E07\u9E08\u9E09\u9E0A\u9E0B\u9E0C\u9E0D"+ - "\u9E0E\u9E0F\u9E10\u9E11\u9E12\u9E13\u9E14\u9E15"+ - "\u9E16\u9E17\u9E18\u9E19\u9E1A\u9E1B\u9E1C\u9E1D"+ - "\u9E1E\u9E24\u9E27\u9E2E\u9E30\u9E34\u9E3B\u9E3C"+ - "\u9E40\u9E4D\u9E50\u9E52\u9E53\u9E54\u9E56\u9E59"+ - "\u9E5D\u9E5F\u9E60\u9E61\u9E62\u9E65\u9E6E\u9E6F"+ - "\u9E72\u9E74\u9E75\u9E76\u9E77\u9E78\u9E79\u9E7A"+ - "\u9E7B\u9E7C\u9E7D\u9E80\uFFFD\u9E81\u9E83\u9E84"+ - "\u9E85\u9E86\u9E89\u9E8A\u9E8C\u9E8D\u9E8E\u9E8F"+ - "\u9E90\u9E91\u9E94\u9E95\u9E96\u9E97\u9E98\u9E99"+ - "\u9E9A\u9E9B\u9E9C\u9E9E\u9EA0\u9EA1\u9EA2\u9EA3"+ - "\u9EA4\u9EA5\u9EA7\u9EA8\u9EA9\u9EAA\uE34E\uE34F"+ - "\uE350\uE351\uE352\uE353\uE354\uE355\uE356\uE357"+ - "\uE358\uE359\uE35A\uE35B\uE35C\uE35D\uE35E\uE35F"+ - "\uE360\uE361\uE362\uE363\uE364\uE365\uE366\uE367"+ - "\uE368\uE369\uE36A\uE36B\uE36C\uE36D\uE36E\uE36F"+ - "\uE370\uE371\uE372\uE373\uE374\uE375\uE376\uE377"+ - "\uE378\uE379\uE37A\uE37B\uE37C\uE37D\uE37E\uE37F"+ - "\uE380\uE381\uE382\uE383\uE384\uE385\uE386\uE387"+ - "\uE388\uE389\uE38A\uE38B\uE38C\uE38D\uE38E\uE38F"+ - "\uE390\uE391\uE392\uE393\uE394\uE395\uE396\uE397"+ - "\uE398\uE399\uE39A\uE39B\uE39C\uE39D\uE39E\uE39F"+ - "\uE3A0\uE3A1\uE3A2\uE3A3\uE3A4\uE3A5\uE3A6\uE3A7"+ - "\uE3A8\uE3A9\uE3AA\uE3AB\u9EAB\u9EAC\u9EAD\u9EAE"+ - "\u9EAF\u9EB0\u9EB1\u9EB2\u9EB3\u9EB5\u9EB6\u9EB7"+ - "\u9EB9\u9EBA\u9EBC\u9EBF\u9EC0\u9EC1\u9EC2\u9EC3"+ - "\u9EC5\u9EC6\u9EC7\u9EC8\u9ECA\u9ECB\u9ECC\u9ED0"+ - "\u9ED2\u9ED3\u9ED5\u9ED6\u9ED7\u9ED9\u9EDA\u9EDE"+ - "\u9EE1\u9EE3\u9EE4\u9EE6\u9EE8\u9EEB\u9EEC\u9EED"+ - "\u9EEE\u9EF0\u9EF1\u9EF2\u9EF3\u9EF4\u9EF5\u9EF6"+ - "\u9EF7\u9EF8\u9EFA\u9EFD\u9EFF\u9F00\u9F01\u9F02"+ - "\u9F03\u9F04\u9F05\uFFFD\u9F06\u9F07\u9F08\u9F09"+ - "\u9F0A\u9F0C\u9F0F\u9F11\u9F12\u9F14\u9F15\u9F16"+ - "\u9F18\u9F1A\u9F1B\u9F1C\u9F1D\u9F1E\u9F1F\u9F21"+ - "\u9F23\u9F24\u9F25\u9F26\u9F27\u9F28\u9F29\u9F2A"+ - "\u9F2B\u9F2D\u9F2E\u9F30\u9F31\uE3AC\uE3AD\uE3AE"+ - "\uE3AF\uE3B0\uE3B1\uE3B2\uE3B3\uE3B4\uE3B5\uE3B6"+ - "\uE3B7\uE3B8\uE3B9\uE3BA\uE3BB\uE3BC\uE3BD\uE3BE"+ - "\uE3BF\uE3C0\uE3C1\uE3C2\uE3C3\uE3C4\uE3C5\uE3C6"+ - "\uE3C7\uE3C8\uE3C9\uE3CA\uE3CB\uE3CC\uE3CD\uE3CE"+ - "\uE3CF\uE3D0\uE3D1\uE3D2\uE3D3\uE3D4\uE3D5\uE3D6"+ - "\uE3D7\uE3D8\uE3D9\uE3DA\uE3DB\uE3DC\uE3DD\uE3DE"+ - "\uE3DF\uE3E0\uE3E1\uE3E2\uE3E3\uE3E4\uE3E5\uE3E6"+ - "\uE3E7\uE3E8\uE3E9\uE3EA\uE3EB\uE3EC\uE3ED\uE3EE"+ - "\uE3EF\uE3F0\uE3F1\uE3F2\uE3F3\uE3F4\uE3F5\uE3F6"+ - "\uE3F7\uE3F8\uE3F9\uE3FA\uE3FB\uE3FC\uE3FD\uE3FE"+ - "\uE3FF\uE400\uE401\uE402\uE403\uE404\uE405\uE406"+ - "\uE407\uE408\uE409\u9F32\u9F33\u9F34\u9F35\u9F36"+ - "\u9F38\u9F3A\u9F3C\u9F3F\u9F40\u9F41\u9F42\u9F43"+ - "\u9F45\u9F46\u9F47\u9F48\u9F49\u9F4A\u9F4B\u9F4C"+ - "\u9F4D\u9F4E\u9F4F\u9F52\u9F53\u9F54\u9F55\u9F56"+ - "\u9F57\u9F58\u9F59\u9F5A\u9F5B\u9F5C\u9F5D\u9F5E"+ - "\u9F5F\u9F60\u9F61\u9F62\u9F63\u9F64\u9F65\u9F66"+ - "\u9F67\u9F68\u9F69\u9F6A\u9F6B\u9F6C\u9F6D\u9F6E"+ - "\u9F6F\u9F70\u9F71\u9F72\u9F73\u9F74\u9F75\u9F76"+ - "\u9F77\u9F78\uFFFD\u9F79\u9F7A\u9F7B\u9F7C\u9F7D"+ - "\u9F7E\u9F81\u9F82\u9F8D\u9F8E\u9F8F\u9F90\u9F91"+ - "\u9F92\u9F93\u9F94\u9F95\u9F96\u9F97\u9F98\u9F9C"+ - "\u9F9D\u9F9E\u9FA1\u9FA2\u9FA3\u9FA4\u9FA5\uF92C"+ - "\uF979\uF995\uF9E7\uF9F1\uE40A\uE40B\uE40C\uE40D"+ - "\uE40E\uE40F\uE410\uE411\uE412\uE413\uE414\uE415"+ - "\uE416\uE417\uE418\uE419\uE41A\uE41B\uE41C\uE41D"+ - "\uE41E\uE41F\uE420\uE421\uE422\uE423\uE424\uE425"+ - "\uE426\uE427\uE428\uE429\uE42A\uE42B\uE42C\uE42D"+ - "\uE42E\uE42F\uE430\uE431\uE432\uE433\uE434\uE435"+ - "\uE436\uE437\uE438\uE439\uE43A\uE43B\uE43C\uE43D"+ - "\uE43E\uE43F\uE440\uE441\uE442\uE443\uE444\uE445"+ - "\uE446\uE447\uE448\uE449\uE44A\uE44B\uE44C\uE44D"+ - "\uE44E\uE44F\uE450\uE451\uE452\uE453\uE454\uE455"+ - "\uE456\uE457\uE458\uE459\uE45A\uE45B\uE45C\uE45D"+ - "\uE45E\uE45F\uE460\uE461\uE462\uE463\uE464\uE465"+ - "\uE466\uE467\uFA0C\uFA0D\uFA0E\uFA0F\uFA11\uFA13"+ - "\uFA14\uFA18\uFA1F\uFA20\uFA21\uFA23\uFA24\uFA27"+ - "\uFA28\uFA29\u2E81\uE816\uE817\uE818\u2E84\u3473"+ - "\u3447\u2E88\u2E8B\uE81E\u359E\u361A\u360E\u2E8C"+ - "\u2E97\u396E\u3918\uE826\u39CF\u39DF\u3A73\u39D0"+ - "\uE82B\uE82C\u3B4E\u3C6E\u3CE0\u2EA7\uE831\uE832"+ - "\u2EAA\u4056\u415F\u2EAE\u4337\u2EB3\u2EB6\u2EB7"+ - "\uE83B\u43B1\u43AC\u2EBB\u43DD\u44D6\u4661\u464C"+ - "\uE843\uFFFD\u4723\u4729\u477C\u478D\u2ECA\u4947"+ - "\u497A\u497D\u4982\u4983\u4985\u4986\u499F\u499B"+ - "\u49B7\u49B6\uE854\uE855\u4CA3\u4C9F\u4CA0\u4CA1"+ - "\u4C77\u4CA2\u4D13\u4D14\u4D15\u4D16\u4D17\u4D18"+ - "\u4D19\u4DAE\uE864\uE468\uE469\uE46A\uE46B\uE46C"+ - "\uE46D\uE46E\uE46F\uE470\uE471\uE472\uE473\uE474"+ - "\uE475\uE476\uE477\uE478\uE479\uE47A\uE47B\uE47C"+ - "\uE47D\uE47E\uE47F\uE480\uE481\uE482\uE483\uE484"+ - "\uE485\uE486\uE487\uE488\uE489\uE48A\uE48B\uE48C"+ - "\uE48D\uE48E\uE48F\uE490\uE491\uE492\uE493\uE494"+ - "\uE495\uE496\uE497\uE498\uE499\uE49A\uE49B\uE49C"+ - "\uE49D\uE49E\uE49F\uE4A0\uE4A1\uE4A2\uE4A3\uE4A4"+ - "\uE4A5\uE4A6\uE4A7\uE4A8\uE4A9\uE4AA\uE4AB\uE4AC"+ - "\uE4AD\uE4AE\uE4AF\uE4B0\uE4B1\uE4B2\uE4B3\uE4B4"+ - "\uE4B5\uE4B6\uE4B7\uE4B8\uE4B9\uE4BA\uE4BB\uE4BC"+ - "\uE4BD\uE4BE\uE4BF\uE4C0\uE4C1\uE4C2\uE4C3\uE4C4"+ - "\uE4C5"; - - static final short index1[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 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, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 0 - }; - - static String index2[] = { - innerIndex0, - innerIndex1, - innerIndex2, - innerIndex3, - innerIndex4, - innerIndex5, - innerIndex6, - innerIndex7 - }; - - - - - - private static final String innerEncoderIndex0= - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007"+ - "\u2008\u2009\u200A\u200B\u200C\u200D\u200E\u200F"+ - "\u2010\u2011\u2012\u2013\u2014\u2015\u2016\u2017"+ - "\u2018\u2019\u201A\u201B\u201C\u201D\u201E\u201F"+ - "\u2020\u2021\u2022\u2023\uA1E8\u2024\u2025\uA1EC"+ - "\uA1A7\u2026\u2027\u2028\u2029\u202A\u202B\u202C"+ - "\uA1E3\uA1C0\u202D\u202E\u202F\u2030\u2031\uA1A4"+ - "\u2032\u2033\u2034\u2035\u2036\u2037\u2038\u2039"+ - "\u203A\u203B\u203C\u203D\u203E\u203F\u2040\u2041"+ - "\u2042\u2043\u2044\u2045\u2046\u2047\u2048\u2049"+ - "\u204A\u204B\u204C\u204D\u204E\u204F\u2050\uA1C1"+ - "\u2051\u2052\u2053\u2054\u2055\u2056\u2057\u2058"+ - "\uA8A4\uA8A2\u2059\u205A\u205B\u205C\u205D\u205E"+ - "\uA8A8\uA8A6\uA8BA\u205F\uA8AC\uA8AA\u2060\u2061"+ - "\u2062\u2063\uA8B0\uA8AE\u2064\u2065\u2066\uA1C2"+ - "\u2067\uA8B4\uA8B2\u2068\uA8B9\u2069\u206A\u206B"+ - "\u206C\uA8A1\u206D\u206E\u206F\u2070\u2071\u2072"+ - "\u2073\u2074\u2075\u2076\u2077\u2078\u2079\u207A"+ - "\u207B\u207C\u207D\uA8A5\u207E\u207F\u2080\u2081"+ - "\u2082\u2083\u2084\uA8A7\u2085\u2086\u2087\u2088"+ - "\u2089\u208A\u208B\u208C\u208D\u208E\u208F\u2090"+ - "\u2091\u2092\u2093\uA8A9\u2094\u2095\u2096\u2097"+ - "\u2098\u2099\u209A\u209B\u209C\u209D\u209E\u209F"+ - "\u20A0\u20A1\u20A2\u20A3\u20A4\u20A5\u20A6\u20A7"+ - "\u20A8\u20A9\u20AA\u20AB\uA8BD\u20AC\u20AD\u20AE"+ - "\uA8BE\u20AF\u20B0\u20B1\u20B2\uA8AD\u20B3\u20B4"+ - "\u20B5\u20B6\u20B7\u20B8\u20B9\u20BA\u20BB\u20BC"+ - "\u20BD\u20BE\u20BF\u20C0\u20C1\u20C2\u20C3\u20C4"+ - "\u20C5\u20C6\u20C7\u20C8\u20C9\u20CA\u20CB\u20CC"+ - "\u20CD\u20CE\u20CF\uA8B1\u20D0\u20D1\u20D2\u20D3"+ - "\u20D4\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB"+ - "\u20DC\u20DD\u20DE\u20DF\u20E0\u20E1\u20E2\u20E3"+ - "\u20E4\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB"+ - "\u20EC\u20ED\u20EE\u20EF\u20F0\u20F1\u20F2\u20F3"+ - "\u20F4\u20F5\u20F6\u20F7\u20F8\u20F9\u20FA\u20FB"+ - "\u20FC\u20FD\u20FE\u20FF\u2100\u2101\u2102\u2103"+ - "\u2104\u2105\u2106\u2107\u2108\u2109\u210A\u210B"+ - "\u210C\u210D\u210E\u210F\u2110\u2111\u2112\u2113"+ - "\u2114\u2115\u2116\u2117\u2118\u2119\u211A\u211B"+ - "\u211C\u211D\u211E\u211F\u2120\u2121\u2122\u2123"+ - "\u2124\u2125\u2126\u2127\u2128\u2129\u212A\u212B"+ - "\u212C\u212D\u212E\u212F\u2130\u2131\uA8A3\u2132"+ - "\uA8AB\u2133\uA8AF\u2134\uA8B3\u2135\uA8B5\u2136"+ - "\uA8B6\u2137\uA8B7\u2138\uA8B8\u2139\u213A\u213B"+ - "\u213C\u213D\u213E\u213F\u2140\u2141\u2142\u2143"+ - "\u2144\u2145\u2146\u2147\u2148\u2149\u214A\u214B"+ - "\u214C\u214D\u214E\u214F\u2150\u2151\u2152\u2153"+ - "\u2154\uA8BF\u2155\u2156\u2157\u2158\u2159\u215A"+ - "\u215B\u215C\u215D\u215E\u215F\u2160\u2161\u2162"+ - "\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216A"+ - "\u216B\u216C\u216D\u216E\u216F\u2170\u2171\u2172"+ - "\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217A"+ - "\u217B\u217C\u217D\u217E\u217F\u2180\u2181\u2182"+ - "\u2183\u2184\u2185\u2186\u2187\u2188\u2189\u218A"+ - "\u218B\u218C\u218D\u218E\u218F\u2190\u2191\u2192"+ - "\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u219A"+ - "\u219B\u219C\u219D\u219E\u219F\u21A0\u21A1\u21A2"+ - "\u21A3\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9\u21AA"+ - "\u21AB\uA8BB\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1"+ - "\u21B2\u21B3\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9"+ - "\u21BA\uA8C0\u21BB\u21BC\u21BD\u21BE\u21BF\u21C0"+ - "\u21C1\u21C2\u21C3\u21C4\u21C5\u21C6\u21C7\u21C8"+ - "\u21C9\u21CA\u21CB\u21CC\u21CD\u21CE\u21CF\u21D0"+ - "\u21D1\u21D2\u21D3\u21D4\u21D5\u21D6\u21D7\u21D8"+ - "\u21D9\u21DA\u21DB\u21DC\u21DD\u21DE\u21DF\u21E0"+ - "\u21E1\u21E2\u21E3\u21E4\u21E5\u21E6\u21E7\u21E8"+ - "\u21E9\u21EA\u21EB\u21EC\u21ED\u21EE\u21EF\u21F0"+ - "\u21F1\u21F2\u21F3\u21F4\u21F5\u21F6\u21F7\u21F8"+ - "\u21F9\u21FA\u21FB\u21FC\u21FD\u21FE\u21FF\u2200"+ - "\u2201\u2202\u2203\u2204\u2205\u2206\u2207\u2208"+ - "\u2209\u220A\u220B\u220C\u220D\u220E\u220F\u2210"+ - "\u2211\u2212\u2213\u2214\u2215\u2216\u2217\u2218"+ - "\u2219\u221A\u221B\u221C\u221D\u221E\u221F\uA1A6"+ - "\u2220\uA1A5\uA840\uA841\u2221\u2222\u2223\u2224"+ - "\u2225\u2226\u2227\u2228\u2229\u222A\u222B\u222C"+ - "\u222D\uA842\u222E\u222F\u2230\u2231\u2232\u2233"+ - "\u2234\u2235\u2236\u2237\u2238\u2239\u223A\u223B"+ - "\u223C\u223D\u223E\u223F\u2240\u2241\u2242\u2243"+ - "\u2244\u2245\u2246\u2247\u2248\u2249\u224A\u224B"+ - "\u224C\u224D\u224E\u224F\u2250\u2251\u2252\u2253"+ - "\u2254\u2255\u2256\u2257\u2258\u2259\u225A\u225B"+ - "\u225C\u225D\u225E\u225F\u2260\u2261\u2262\u2263"+ - "\u2264\u2265\u2266\u2267\u2268\u2269\u226A\u226B"+ - "\u226C\u226D\u226E\u226F\u2270\u2271\u2272\u2273"+ - "\u2274\u2275\u2276\u2277\u2278\u2279\u227A\u227B"+ - "\u227C\u227D\u227E\u227F\u2280\u2281\u2282\u2283"+ - "\u2284\u2285\u2286\u2287\u2288\u2289\u228A\u228B"+ - "\u228C\u228D\u228E\u228F\u2290\u2291\u2292\u2293"+ - "\u2294\u2295\u2296\u2297\u2298\u2299\u229A\u229B"+ - "\u229C\u229D\u229E\u229F\u22A0\u22A1\u22A2\u22A3"+ - "\u22A4\u22A5\u22A6\u22A7\u22A8\u22A9\u22AA\u22AB"+ - "\u22AC\u22AD\u22AE\u22AF\u22B0\u22B1\u22B2\u22B3"+ - "\u22B4\u22B5\u22B6\u22B7\u22B8\u22B9\u22BA\u22BB"+ - "\u22BC\u22BD\u22BE\u22BF\u22C0\u22C1\u22C2\u22C3"+ - "\u22C4\u22C5\u22C6\u22C7\u22C8\u22C9\u22CA\u22CB"+ - "\u22CC\u22CD\u22CE\u22CF\u22D0\u22D1\u22D2\u22D3"+ - "\u22D4\u22D5\u22D6\u22D7\u22D8\u22D9\u22DA\u22DB"+ - "\u22DC\u22DD\u22DE\u22DF\u22E0\u22E1\u22E2\u22E3"+ - "\u22E4\uA6A1\uA6A2\uA6A3\uA6A4\uA6A5\uA6A6\uA6A7"+ - "\uA6A8\uA6A9\uA6AA\uA6AB\uA6AC\uA6AD\uA6AE\uA6AF"+ - "\uA6B0\uA6B1\u22E5\uA6B2\uA6B3\uA6B4\uA6B5\uA6B6"+ - "\uA6B7\uA6B8\u22E6\u22E7\u22E8\u22E9\u22EA\u22EB"+ - "\u22EC\uA6C1\uA6C2\uA6C3\uA6C4\uA6C5\uA6C6\uA6C7"+ - "\uA6C8\uA6C9\uA6CA\uA6CB\uA6CC\uA6CD\uA6CE\uA6CF"+ - "\uA6D0\uA6D1\u22ED\uA6D2\uA6D3\uA6D4\uA6D5\uA6D6"+ - "\uA6D7\uA6D8\u22EE\u22EF\u22F0\u22F1\u22F2\u22F3"+ - "\u22F4\u22F5\u22F6\u22F7\u22F8\u22F9\u22FA\u22FB"+ - "\u22FC\u22FD\u22FE\u22FF\u2300\u2301\u2302\u2303"+ - "\u2304\u2305\u2306\u2307\u2308\u2309\u230A\u230B"+ - "\u230C\u230D\u230E\u230F\u2310\u2311\u2312\u2313"+ - "\u2314\u2315\u2316\u2317\u2318\u2319\u231A\u231B"+ - "\u231C\u231D\u231E\u231F\u2320\u2321\u2322\u2323"+ - "\u2324\uA7A7\u2325\u2326\u2327\u2328\u2329\u232A"+ - "\u232B\u232C\u232D\u232E\u232F\u2330\u2331\u2332"+ - "\uA7A1\uA7A2\uA7A3\uA7A4\uA7A5\uA7A6\uA7A8\uA7A9"+ - "\uA7AA\uA7AB\uA7AC\uA7AD\uA7AE\uA7AF\uA7B0\uA7B1"+ - "\uA7B2\uA7B3\uA7B4\uA7B5\uA7B6\uA7B7\uA7B8\uA7B9"+ - "\uA7BA\uA7BB\uA7BC\uA7BD\uA7BE\uA7BF\uA7C0\uA7C1"+ - "\uA7D1\uA7D2\uA7D3\uA7D4\uA7D5\uA7D6\uA7D8\uA7D9"+ - "\uA7DA\uA7DB\uA7DC\uA7DD\uA7DE\uA7DF\uA7E0\uA7E1"+ - "\uA7E2\uA7E3\uA7E4\uA7E5\uA7E6\uA7E7\uA7E8\uA7E9"+ - "\uA7EA\uA7EB\uA7EC\uA7ED\uA7EE\uA7EF\uA7F0\uA7F1"+ - "\u2333\uA7D7\u2334\u2335\u2336\u2337\u2338\u2339"+ - "\u233A\u233B\u233C\u233D\u233E\u233F\u2340\u2341"+ - "\u2342\u2343\u2344\u2345\u2346\u2347\u2348\u2349"+ - "\u234A\u234B\u234C\u234D\u234E\u234F\u2350\u2351"+ - "\u2352\u2353\u2354\u2355\u2356\u2357\u2358\u2359"+ - "\u235A\u235B\u235C\u235D\u235E\u235F\u2360\u2361"+ - "\u2362\u2363\u2364\u2365\u2366\u2367\u2368\u2369"+ - "\u236A\u236B\u236C\u236D\u236E\u236F\u2370\u2371"+ - "\u2372\u2373\u2374\u2375\u2376\u2377\u2378\u2379"+ - "\u237A\u237B\u237C\u237D\u237E\u237F\u2380\u2381"+ - "\u2382\u2383\u2384\u2385\u2386\u2387\u2388\u2389"+ - "\u238A\u238B\u238C\u238D\u238E\u238F\u2390\u2391"+ - "\u2392\u2393\u2394\u2395\u2396\u2397\u2398\u2399"+ - "\u239A\u239B\u239C\u239D\u239E\u239F\u23A0\u23A1"+ - "\u23A2\u23A3\u23A4\u23A5\u23A6\u23A7\u23A8\u23A9"+ - "\u23AA\u23AB\u23AC\u23AD\u23AE\u23AF\u23B0\u23B1"+ - "\u23B2\u23B3\u23B4\u23B5\u23B6\u23B7\u23B8\u23B9"+ - "\u23BA\u23BB\u23BC\u23BD\u23BE\u23BF\u23C0\u23C1"+ - "\u23C2\u23C3\u23C4\u23C5\u23C6\u23C7\u23C8\u23C9"+ - "\u23CA\u23CB\u23CC\u23CD\u23CE\u23CF\u23D0\u23D1"+ - "\u23D2\u23D3\u23D4\u23D5\u23D6\u23D7\u23D8\u23D9"+ - "\u23DA\u23DB\u23DC\u23DD\u23DE\u23DF\u23E0\u23E1"+ - "\u23E2\u23E3\u23E4\u23E5\u23E6\u23E7\u23E8\u23E9"+ - "\u23EA\u23EB\u23EC\u23ED\u23EE\u23EF\u23F0\u23F1"+ - "\u23F2\u23F3\u23F4\u23F5\u23F6\u23F7\u23F8\u23F9"+ - "\u23FA\u23FB\u23FC\u23FD\u23FE\u23FF\u2400\u2401"+ - "\u2402\u2403\u2404\u2405\u2406\u2407\u2408\u2409"+ - "\u240A\u240B\u240C\u240D\u240E\u240F\u2410\u2411"+ - "\u2412\u2413\u2414\u2415\u2416\u2417\u2418\u2419"+ - "\u241A\u241B\u241C\u241D\u241E\u241F\u2420\u2421"+ - "\u2422\u2423\u2424\u2425\u2426\u2427\u2428\u2429"+ - "\u242A\u242B\u242C\u242D\u242E\u242F\u2430\u2431"+ - "\u2432\u2433\u2434\u2435\u2436\u2437\u2438\u2439"+ - "\u243A\u243B\u243C\u243D\u243E\u243F\u2440\u2441"+ - "\u2442\u2443\u2444\u2445\u2446\u2447\u2448\u2449"+ - "\u244A\u244B\u244C\u244D\u244E\u244F\u2450\u2451"+ - "\u2452\u2453\u2454\u2455\u2456\u2457\u2458\u2459"+ - "\u245A\u245B\u245C\u245D\u245E\u245F\u2460\u2461"+ - "\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2469"+ - "\u246A\u246B\u246C\u246D\u246E\u246F\u2470\u2471"+ - "\u2472\u2473\u2474\u2475\u2476\u2477\u2478\u2479"+ - "\u247A\u247B\u247C\u247D\u247E\u247F\u2480\u2481"+ - "\u2482\u2483\u2484\u2485\u2486\u2487\u2488\u2489"+ - "\u248A\u248B\u248C\u248D\u248E\u248F\u2490\u2491"+ - "\u2492\u2493\u2494\u2495\u2496\u2497\u2498\u2499"+ - "\u249A\u249B\u249C\u249D\u249E\u249F\u24A0\u24A1"+ - "\u24A2\u24A3\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9"+ - "\u24AA\u24AB\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1"+ - "\u24B2\u24B3\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9"+ - "\u24BA\u24BB\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1"+ - "\u24C2\u24C3\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9"+ - "\u24CA\u24CB\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1"+ - "\u24D2\u24D3\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9"+ - "\u24DA\u24DB\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1"+ - "\u24E2\u24E3\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9"+ - "\u24EA\u24EB\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1"+ - "\u24F2\u24F3\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9"+ - "\u24FA\u24FB\u24FC\u24FD\u24FE\u24FF\u2500\u2501"+ - "\u2502\u2503\u2504\u2505\u2506\u2507\u2508\u2509"+ - "\u250A\u250B\u250C\u250D\u250E\u250F\u2510\u2511"+ - "\u2512\u2513\u2514\u2515\u2516\u2517\u2518\u2519"+ - "\u251A\u251B\u251C\u251D\u251E\u251F\u2520\u2521"+ - "\u2522\u2523\u2524\u2525\u2526\u2527\u2528\u2529"+ - "\u252A\u252B\u252C\u252D\u252E\u252F\u2530\u2531"+ - "\u2532\u2533\u2534\u2535\u2536\u2537\u2538\u2539"+ - "\u253A\u253B\u253C\u253D\u253E\u253F\u2540\u2541"+ - "\u2542\u2543\u2544\u2545\u2546\u2547\u2548\u2549"+ - "\u254A\u254B\u254C\u254D\u254E\u254F\u2550\u2551"+ - "\u2552\u2553\u2554\u2555\u2556\u2557\u2558\u2559"+ - "\u255A\u255B\u255C\u255D\u255E\u255F\u2560\u2561"+ - "\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569"+ - "\u256A\u256B\u256C\u256D\u256E\u256F\u2570\u2571"+ - "\u2572\u2573\u2574\u2575\u2576\u2577\u2578\u2579"+ - "\u257A\u257B\u257C\u257D\u257E\u257F\u2580\u2581"+ - "\u2582\u2583\u2584\u2585\u2586\u2587\u2588\u2589"+ - "\u258A\u258B\u258C\u258D\u258E\u258F\u2590\u2591"+ - "\u2592\u2593\u2594\u2595\u2596\u2597\u2598\u2599"+ - "\u259A\u259B\u259C\u259D\u259E\u259F\u25A0\u25A1"+ - "\u25A2\u25A3\u25A4\u25A5\u25A6\u25A7\u25A8\u25A9"+ - "\u25AA\u25AB\u25AC\u25AD\u25AE\u25AF\u25B0\u25B1"+ - "\u25B2\u25B3\u25B4\u25B5\u25B6\u25B7\u25B8\u25B9"+ - "\u25BA\u25BB\u25BC\u25BD\u25BE\u25BF\u25C0\u25C1"+ - "\u25C2\u25C3\u25C4\u25C5\u25C6\u25C7\u25C8\u25C9"+ - "\u25CA\u25CB\u25CC\u25CD\u25CE\u25CF\u25D0\u25D1"+ - "\u25D2\u25D3\u25D4\u25D5\u25D6\u25D7\u25D8\u25D9"+ - "\u25DA\u25DB\u25DC\u25DD\u25DE\u25DF\u25E0\u25E1"+ - "\u25E2\u25E3\u25E4\u25E5\u25E6\u25E7\u25E8\u25E9"+ - "\u25EA\u25EB\u25EC\u25ED\u25EE\u25EF\u25F0\u25F1"+ - "\u25F2\u25F3\u25F4\u25F5\u25F6\u25F7\u25F8\u25F9"+ - "\u25FA\u25FB\u25FC\u25FD\u25FE\u25FF\u2600\u2601"+ - "\u2602\u2603\u2604\u2605\u2606\u2607\u2608\u2609"+ - "\u260A\u260B\u260C\u260D\u260E\u260F\u2610\u2611"+ - "\u2612\u2613\u2614\u2615\u2616\u2617\u2618\u2619"+ - "\u261A\u261B\u261C\u261D\u261E\u261F\u2620\u2621"+ - "\u2622\u2623\u2624\u2625\u2626\u2627\u2628\u2629"+ - "\u262A\u262B\u262C\u262D\u262E\u262F\u2630\u2631"+ - "\u2632\u2633\u2634\u2635\u2636\u2637\u2638\u2639"+ - "\u263A\u263B\u263C\u263D\u263E\u263F\u2640\u2641"+ - "\u2642\u2643\u2644\u2645\u2646\u2647\u2648\u2649"+ - "\u264A\u264B\u264C\u264D\u264E\u264F\u2650\u2651"+ - "\u2652\u2653\u2654\u2655\u2656\u2657\u2658\u2659"+ - "\u265A\u265B\u265C\u265D\u265E\u265F\u2660\u2661"+ - "\u2662\u2663\u2664\u2665\u2666\u2667\u2668\u2669"+ - "\u266A\u266B\u266C\u266D\u266E\u266F\u2670\u2671"+ - "\u2672\u2673\u2674\u2675\u2676\u2677\u2678\u2679"+ - "\u267A\u267B\u267C\u267D\u267E\u267F\u2680\u2681"+ - "\u2682\u2683\u2684\u2685\u2686\u2687\u2688\u2689"+ - "\u268A\u268B\u268C\u268D\u268E\u268F\u2690\u2691"+ - "\u2692\u2693\u2694\u2695\u2696\u2697\u2698\u2699"+ - "\u269A\u269B\u269C\u269D\u269E\u269F\u26A0\u26A1"+ - "\u26A2\u26A3\u26A4\u26A5\u26A6\u26A7\u26A8\u26A9"+ - "\u26AA\u26AB\u26AC\u26AD\u26AE\u26AF\u26B0\u26B1"+ - "\u26B2\u26B3\u26B4\u26B5\u26B6\u26B7\u26B8\u26B9"+ - "\u26BA\u26BB\u26BC\u26BD\u26BE\u26BF\u26C0\u26C1"+ - "\u26C2\u26C3\u26C4\u26C5\u26C6\u26C7\u26C8\u26C9"+ - "\u26CA\u26CB\u26CC\u26CD\u26CE\u26CF\u26D0\u26D1"+ - "\u26D2\u26D3\u26D4\u26D5\u26D6\u26D7\u26D8\u26D9"+ - "\u26DA\u26DB\u26DC\u26DD\u26DE\u26DF\u26E0\u26E1"+ - "\u26E2\u26E3\u26E4\u26E5\u26E6\u26E7\u26E8\u26E9"+ - "\u26EA\u26EB\u26EC\u26ED\u26EE\u26EF\u26F0\u26F1"+ - "\u26F2\u26F3\u26F4\u26F5\u26F6\u26F7\u26F8\u26F9"+ - "\u26FA\u26FB\u26FC\u26FD\u26FE\u26FF\u2700\u2701"+ - "\u2702\u2703\u2704\u2705\u2706\u2707\u2708\u2709"+ - "\u270A\u270B\u270C\u270D\u270E\u270F\u2710\u2711"+ - "\u2712\u2713\u2714\u2715\u2716\u2717\u2718\u2719"+ - "\u271A\u271B\u271C\u271D\u271E\u271F\u2720\u2721"+ - "\u2722\u2723\u2724\u2725\u2726\u2727\u2728\u2729"+ - "\u272A\u272B\u272C\u272D\u272E\u272F\u2730\u2731"+ - "\u2732\u2733\u2734\u2735\u2736\u2737\u2738\u2739"+ - "\u273A\u273B\u273C\u273D\u273E\u273F\u2740\u2741"+ - "\u2742\u2743\u2744\u2745\u2746\u2747\u2748\u2749"+ - "\u274A\u274B\u274C\u274D\u274E\u274F\u2750\u2751"+ - "\u2752\u2753\u2754\u2755\u2756\u2757\u2758\u2759"+ - "\u275A\u275B\u275C\u275D\u275E\u275F\u2760\u2761"+ - "\u2762\u2763\u2764\u2765\u2766\u2767\u2768\u2769"+ - "\u276A\u276B\u276C\u276D\u276E\u276F\u2770\u2771"+ - "\u2772\u2773\u2774\u2775\u2776\u2777\u2778\u2779"+ - "\u277A\u277B\u277C\u277D\u277E\u277F\u2780\u2781"+ - "\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u2789"+ - "\u278A\u278B\u278C\u278D\u278E\u278F\u2790\u2791"+ - "\u2792\u2793\u2794\u2795\u2796\u2797\u2798\u2799"+ - "\u279A\u279B\u279C\u279D\u279E\u279F\u27A0\u27A1"+ - "\u27A2\u27A3\u27A4\u27A5\u27A6\u27A7\u27A8\u27A9"+ - "\u27AA\u27AB\u27AC\u27AD\u27AE\u27AF\u27B0\u27B1"+ - "\u27B2\u27B3\u27B4\u27B5\u27B6\u27B7\u27B8\u27B9"+ - "\u27BA\u27BB\u27BC\u27BD\u27BE\u27BF\u27C0\u27C1"+ - "\u27C2\u27C3\u27C4\u27C5\u27C6\u27C7\u27C8\u27C9"+ - "\u27CA\u27CB\u27CC\u27CD\u27CE\u27CF\u27D0\u27D1"+ - "\u27D2\u27D3\u27D4\u27D5\u27D6\u27D7\u27D8\u27D9"+ - "\u27DA\u27DB\u27DC\u27DD\u27DE\u27DF\u27E0\u27E1"+ - "\u27E2\u27E3\u27E4\u27E5\u27E6\u27E7\u27E8\u27E9"+ - "\u27EA\u27EB\u27EC\u27ED\u27EE\u27EF\u27F0\u27F1"+ - "\u27F2\u27F3\u27F4\u27F5\u27F6\u27F7\u27F8\u27F9"+ - "\u27FA\u27FB\u27FC\u27FD\u27FE\u27FF\u2800\u2801"+ - "\u2802\u2803\u2804\u2805\u2806\u2807\u2808\u2809"+ - "\u280A\u280B\u280C\u280D\u280E\u280F\u2810\u2811"+ - "\u2812\u2813\u2814\u2815\u2816\u2817\u2818\u2819"+ - "\u281A\u281B\u281C\u281D\u281E\u281F\u2820\u2821"+ - "\u2822\u2823\u2824\u2825\u2826\u2827\u2828\u2829"+ - "\u282A\u282B\u282C\u282D\u282E\u282F\u2830\u2831"+ - "\u2832\u2833\u2834\u2835\u2836\u2837\u2838\u2839"+ - "\u283A\u283B\u283C\u283D\u283E\u283F\u2840\u2841"+ - "\u2842\u2843\u2844\u2845\u2846\u2847\u2848\u2849"+ - "\u284A\u284B\u284C\u284D\u284E\u284F\u2850\u2851"+ - "\u2852\u2853\u2854\u2855\u2856\u2857\u2858\u2859"+ - "\u285A\u285B\u285C\u285D\u285E\u285F\u2860\u2861"+ - "\u2862\u2863\u2864\u2865\u2866\u2867\u2868\u2869"+ - "\u286A\u286B\u286C\u286D\u286E\u286F\u2870\u2871"+ - "\u2872\u2873\u2874\u2875\u2876\u2877\u2878\u2879"+ - "\u287A\u287B\u287C\u287D\u287E\u287F\u2880\u2881"+ - "\u2882\u2883\u2884\u2885\u2886\u2887\u2888\u2889"+ - "\u288A\u288B\u288C\u288D\u288E\u288F\u2890\u2891"+ - "\u2892\u2893\u2894\u2895\u2896\u2897\u2898\u2899"+ - "\u289A\u289B\u289C\u289D\u289E\u289F\u28A0\u28A1"+ - "\u28A2\u28A3\u28A4\u28A5\u28A6\u28A7\u28A8\u28A9"+ - "\u28AA\u28AB\u28AC\u28AD\u28AE\u28AF\u28B0\u28B1"+ - "\u28B2\u28B3\u28B4\u28B5\u28B6\u28B7\u28B8\u28B9"+ - "\u28BA\u28BB\u28BC\u28BD\u28BE\u28BF\u28C0\u28C1"+ - "\u28C2\u28C3\u28C4\u28C5\u28C6\u28C7\u28C8\u28C9"+ - "\u28CA\u28CB\u28CC\u28CD\u28CE\u28CF\u28D0\u28D1"+ - "\u28D2\u28D3\u28D4\u28D5\u28D6\u28D7\u28D8\u28D9"+ - "\u28DA\u28DB\u28DC\u28DD\u28DE\u28DF\u28E0\u28E1"+ - "\u28E2\u28E3\u28E4\u28E5\u28E6\u28E7\u28E8\u28E9"+ - "\u28EA\u28EB\u28EC\u28ED\u28EE\u28EF\u28F0\u28F1"+ - "\u28F2\u28F3\u28F4\u28F5\u28F6\u28F7\u28F8\u28F9"+ - "\u28FA\u28FB\u28FC\u28FD\u28FE\u28FF\u2900\u2901"+ - "\u2902\u2903\u2904\u2905\u2906\u2907\u2908\u2909"+ - "\u290A\u290B\u290C\u290D\u290E\u290F\u2910\u2911"+ - "\u2912\u2913\u2914\u2915\u2916\u2917\u2918\u2919"+ - "\u291A\u291B\u291C\u291D\u291E\u291F\u2920\u2921"+ - "\u2922\u2923\u2924\u2925\u2926\u2927\u2928\u2929"+ - "\u292A\u292B\u292C\u292D\u292E\u292F\u2930\u2931"+ - "\u2932\u2933\u2934\u2935\u2936\u2937\u2938\u2939"+ - "\u293A\u293B\u293C\u293D\u293E\u293F\u2940\u2941"+ - "\u2942\u2943\u2944\u2945\u2946\u2947\u2948\u2949"+ - "\u294A\u294B\u294C\u294D\u294E\u294F\u2950\u2951"+ - "\u2952\u2953\u2954\u2955\u2956\u2957\u2958\u2959"+ - "\u295A\u295B\u295C\u295D\u295E\u295F\u2960\u2961"+ - "\u2962\u2963\u2964\u2965\u2966\u2967\u2968\u2969"+ - "\u296A\u296B\u296C\u296D\u296E\u296F\u2970\u2971"+ - "\u2972\u2973\u2974\u2975\u2976\u2977\u2978\u2979"+ - "\u297A\u297B\u297C\u297D\u297E\u297F\u2980\u2981"+ - "\u2982\u2983\u2984\u2985\u2986\u2987\u2988\u2989"+ - "\u298A\u298B\u298C\u298D\u298E\u298F\u2990\u2991"+ - "\u2992\u2993\u2994\u2995\u2996\u2997\u2998\u2999"+ - "\u299A\u299B\u299C\u299D\u299E\u299F\u29A0\u29A1"+ - "\u29A2\u29A3\u29A4\u29A5\u29A6\u29A7\u29A8\u29A9"+ - "\u29AA\u29AB\u29AC\u29AD\u29AE\u29AF\u29B0\u29B1"+ - "\u29B2\u29B3\u29B4\u29B5\u29B6\u29B7\u29B8\u29B9"+ - "\u29BA\u29BB\u29BC\u29BD\u29BE\u29BF\u29C0\u29C1"+ - "\u29C2\u29C3\u29C4\u29C5\u29C6\u29C7\u29C8\u29C9"+ - "\u29CA\u29CB\u29CC\u29CD\u29CE\u29CF\u29D0\u29D1"+ - "\u29D2\u29D3\u29D4\u29D5\u29D6\u29D7\u29D8\u29D9"+ - "\u29DA\u29DB\u29DC\u29DD\u29DE\u29DF\u29E0\u29E1"+ - "\u29E2\u29E3\u29E4\u29E5\u29E6\u29E7\u29E8\u29E9"+ - "\u29EA\u29EB\u29EC\u29ED\u29EE\u29EF\u29F0\u29F1"+ - "\u29F2\u29F3\u29F4\u29F5\u29F6\u29F7\u29F8\u29F9"+ - "\u29FA\u29FB\u29FC\u29FD\u29FE\u29FF\u2A00\u2A01"+ - "\u2A02\u2A03\u2A04\u2A05\u2A06\u2A07\u2A08\u2A09"+ - "\u2A0A\u2A0B\u2A0C\u2A0D\u2A0E\u2A0F\u2A10\u2A11"+ - "\u2A12\u2A13\u2A14\u2A15\u2A16\u2A17\u2A18\u2A19"+ - "\u2A1A\u2A1B\u2A1C\u2A1D\u2A1E\u2A1F\u2A20\u2A21"+ - "\u2A22\u2A23\u2A24\u2A25\u2A26\u2A27\u2A28\u2A29"+ - "\u2A2A\u2A2B\u2A2C\u2A2D\u2A2E\u2A2F\u2A30\u2A31"+ - "\u2A32\u2A33\u2A34\u2A35\u2A36\u2A37\u2A38\u2A39"+ - "\u2A3A\u2A3B\u2A3C\u2A3D\u2A3E\u2A3F\u2A40\u2A41"+ - "\u2A42\u2A43\u2A44\u2A45\u2A46\u2A47\u2A48\u2A49"+ - "\u2A4A\u2A4B\u2A4C\u2A4D\u2A4E\u2A4F\u2A50\u2A51"+ - "\u2A52\u2A53\u2A54\u2A55\u2A56\u2A57\u2A58\u2A59"+ - "\u2A5A\u2A5B\u2A5C\u2A5D\u2A5E\u2A5F\u2A60\u2A61"+ - "\u2A62\u2A63\u2A64\u2A65\u2A66\u2A67\u2A68\u2A69"+ - "\u2A6A\u2A6B\u2A6C\u2A6D\u2A6E\u2A6F\u2A70\u2A71"+ - "\u2A72\u2A73\u2A74\u2A75\u2A76\u2A77\u2A78\u2A79"+ - "\u2A7A\u2A7B\u2A7C\u2A7D\u2A7E\u2A7F\u2A80\u2A81"+ - "\u2A82\u2A83\u2A84\u2A85\u2A86\u2A87\u2A88\u2A89"+ - "\u2A8A\u2A8B\u2A8C\u2A8D\u2A8E\u2A8F\u2A90\u2A91"+ - "\u2A92\u2A93\u2A94\u2A95\u2A96\u2A97\u2A98\u2A99"+ - "\u2A9A\u2A9B\u2A9C\u2A9D\u2A9E\u2A9F\u2AA0\u2AA1"+ - "\u2AA2\u2AA3\u2AA4\u2AA5\u2AA6\u2AA7\u2AA8\u2AA9"+ - "\u2AAA\u2AAB\u2AAC\u2AAD\u2AAE\u2AAF\u2AB0\u2AB1"+ - "\u2AB2\u2AB3\u2AB4\u2AB5\u2AB6\u2AB7\u2AB8\u2AB9"+ - "\u2ABA\u2ABB\u2ABC\u2ABD\u2ABE\u2ABF\u2AC0\u2AC1"+ - "\u2AC2\u2AC3\u2AC4\u2AC5\u2AC6\u2AC7\u2AC8\u2AC9"+ - "\u2ACA\u2ACB\u2ACC\u2ACD\u2ACE\u2ACF\u2AD0\u2AD1"+ - "\u2AD2\u2AD3\u2AD4\u2AD5\u2AD6\u2AD7\u2AD8\u2AD9"+ - "\u2ADA\u2ADB\u2ADC\u2ADD\u2ADE\u2ADF\u2AE0\u2AE1"+ - "\u2AE2\u2AE3\u2AE4\u2AE5\u2AE6\u2AE7\u2AE8\u2AE9"+ - "\u2AEA\u2AEB\u2AEC\u2AED\u2AEE\u2AEF\u2AF0\u2AF1"+ - "\u2AF2\u2AF3\u2AF4\u2AF5\u2AF6\u2AF7\u2AF8\u2AF9"+ - "\u2AFA\u2AFB\u2AFC\u2AFD\u2AFE\u2AFF\u2B00\u2B01"+ - "\u2B02\u2B03\u2B04\u2B05\u2B06\u2B07\u2B08\u2B09"+ - "\u2B0A\u2B0B\u2B0C\u2B0D\u2B0E\u2B0F\u2B10\u2B11"+ - "\u2B12\u2B13\u2B14\u2B15\u2B16\u2B17\u2B18\u2B19"+ - "\u2B1A\u2B1B\u2B1C\u2B1D\u2B1E\u2B1F\u2B20\u2B21"+ - "\u2B22\u2B23\u2B24\u2B25\u2B26\u2B27\u2B28\u2B29"+ - "\u2B2A\u2B2B\u2B2C\u2B2D\u2B2E\u2B2F\u2B30\u2B31"+ - "\u2B32\u2B33\u2B34\u2B35\u2B36\u2B37\u2B38\u2B39"+ - "\u2B3A\u2B3B\u2B3C\u2B3D\u2B3E\u2B3F\u2B40\u2B41"+ - "\u2B42\u2B43\u2B44\u2B45\u2B46\u2B47\u2B48\u2B49"+ - "\u2B4A\u2B4B\u2B4C\u2B4D\u2B4E\u2B4F\u2B50\u2B51"+ - "\u2B52\u2B53\u2B54\u2B55\u2B56\u2B57\u2B58\u2B59"+ - "\u2B5A\u2B5B\u2B5C\u2B5D\u2B5E\u2B5F\u2B60\u2B61"+ - "\u2B62\u2B63\u2B64\u2B65\u2B66\u2B67\u2B68\u2B69"+ - "\u2B6A\u2B6B\u2B6C\u2B6D\u2B6E\u2B6F\u2B70\u2B71"+ - "\u2B72\u2B73\u2B74\u2B75\u2B76\u2B77\u2B78\u2B79"+ - "\u2B7A\u2B7B\u2B7C\u2B7D\u2B7E\u2B7F\u2B80\u2B81"+ - "\u2B82\u2B83\u2B84\u2B85\u2B86\u2B87\u2B88\u2B89"+ - "\u2B8A\u2B8B\u2B8C\u2B8D\u2B8E\u2B8F\u2B90\u2B91"+ - "\u2B92\u2B93\u2B94\u2B95\u2B96\u2B97\u2B98\u2B99"+ - "\u2B9A\u2B9B\u2B9C\u2B9D\u2B9E\u2B9F\u2BA0\u2BA1"+ - "\u2BA2\u2BA3\u2BA4\u2BA5\u2BA6\u2BA7\u2BA8\u2BA9"+ - "\u2BAA\u2BAB\u2BAC\u2BAD\u2BAE\u2BAF\u2BB0\u2BB1"+ - "\u2BB2\u2BB3\u2BB4\u2BB5\u2BB6\u2BB7\u2BB8\u2BB9"+ - "\u2BBA\u2BBB\u2BBC\u2BBD\u2BBE\u2BBF\u2BC0\u2BC1"+ - "\u2BC2\u2BC3\u2BC4\u2BC5\u2BC6\u2BC7\u2BC8\u2BC9"+ - "\u2BCA\u2BCB\u2BCC\u2BCD\u2BCE\u2BCF\u2BD0\u2BD1"+ - "\u2BD2\u2BD3\u2BD4\u2BD5\u2BD6\u2BD7\u2BD8\u2BD9"+ - "\u2BDA\u2BDB\u2BDC\u2BDD\u2BDE\u2BDF\u2BE0\u2BE1"+ - "\u2BE2\u2BE3\u2BE4\u2BE5\u2BE6\u2BE7\u2BE8\u2BE9"+ - "\u2BEA\u2BEB\u2BEC\u2BED\u2BEE\u2BEF\u2BF0\u2BF1"+ - "\u2BF2\u2BF3\u2BF4\u2BF5\u2BF6\u2BF7\u2BF8\u2BF9"+ - "\u2BFA\u2BFB\u2BFC\u2BFD\u2BFE\u2BFF\u2C00\u2C01"+ - "\u2C02\u2C03\u2C04\u2C05\u2C06\u2C07\u2C08\u2C09"+ - "\u2C0A\u2C0B\u2C0C\u2C0D\u2C0E\u2C0F\u2C10\u2C11"+ - "\u2C12\u2C13\u2C14\u2C15\u2C16\u2C17\u2C18\u2C19"+ - "\u2C1A\u2C1B\u2C1C\u2C1D\u2C1E\u2C1F\u2C20\u2C21"+ - "\u2C22\u2C23\u2C24\u2C25\u2C26\u2C27\u2C28\u2C29"+ - "\u2C2A\u2C2B\u2C2C\u2C2D\u2C2E\u2C2F\u2C30\u2C31"+ - "\u2C32\u2C33\u2C34\u2C35\u2C36\u2C37\u2C38\u2C39"+ - "\u2C3A\u2C3B\u2C3C\u2C3D\u2C3E\u2C3F\u2C40\u2C41"+ - "\u2C42\u2C43\u2C44\u2C45\u2C46\u2C47\u2C48\u2C49"+ - "\u2C4A\u2C4B\u2C4C\u2C4D\u2C4E\u2C4F\u2C50\u2C51"+ - "\u2C52\u2C53\u2C54\u2C55\u2C56\u2C57\u2C58\u2C59"+ - "\u2C5A\u2C5B\u2C5C\u2C5D\u2C5E\u2C5F\u2C60\u2C61"+ - "\u2C62\u2C63\u2C64\u2C65\u2C66\u2C67\u2C68\u2C69"+ - "\u2C6A\u2C6B\u2C6C\u2C6D\u2C6E\u2C6F\u2C70\u2C71"+ - "\u2C72\u2C73\u2C74\u2C75\u2C76\u2C77\u2C78\u2C79"+ - "\u2C7A\u2C7B\u2C7C\u2C7D\u2C7E\u2C7F\u2C80\u2C81"+ - "\u2C82\u2C83\u2C84\u2C85\u2C86\u2C87\u2C88\u2C89"+ - "\u2C8A\u2C8B\u2C8C\u2C8D\u2C8E\u2C8F\u2C90\u2C91"+ - "\u2C92\u2C93\u2C94\u2C95\u2C96\u2C97\u2C98\u2C99"+ - "\u2C9A\u2C9B\u2C9C\u2C9D\u2C9E\u2C9F\u2CA0\u2CA1"+ - "\u2CA2\u2CA3\u2CA4\u2CA5\u2CA6\u2CA7\u2CA8\u2CA9"+ - "\u2CAA\u2CAB\u2CAC\u2CAD\u2CAE\u2CAF\u2CB0\u2CB1"+ - "\u2CB2\u2CB3\u2CB4\u2CB5\u2CB6\u2CB7\u2CB8\u2CB9"+ - "\u2CBA\u2CBB\u2CBC\u2CBD\u2CBE\u2CBF\u2CC0\u2CC1"+ - "\u2CC2\u2CC3\u2CC4\u2CC5\u2CC6\u2CC7\u2CC8\u2CC9"+ - "\u2CCA\u2CCB\u2CCC\u2CCD\u2CCE\u2CCF\u2CD0\u2CD1"+ - "\u2CD2\u2CD3\u2CD4\u2CD5\u2CD6\u2CD7\u2CD8\u2CD9"+ - "\u2CDA\u2CDB\u2CDC\u2CDD\u2CDE\u2CDF\u2CE0\u2CE1"+ - "\u2CE2\u2CE3\u2CE4\u2CE5\u2CE6\u2CE7\u2CE8\u2CE9"+ - "\u2CEA\u2CEB\u2CEC\u2CED\u2CEE\u2CEF\u2CF0\u2CF1"+ - "\u2CF2\u2CF3\u2CF4\u2CF5\u2CF6\u2CF7\u2CF8\u2CF9"+ - "\u2CFA\u2CFB\u2CFC\u2CFD\u2CFE\u2CFF\u2D00\u2D01"+ - "\u2D02\u2D03\u2D04\u2D05\u2D06\u2D07\u2D08\u2D09"+ - "\u2D0A\u2D0B\u2D0C\u2D0D\u2D0E\u2D0F\u2D10\u2D11"+ - "\u2D12\u2D13\u2D14\u2D15\u2D16\u2D17\u2D18\u2D19"+ - "\u2D1A\u2D1B\u2D1C\u2D1D\u2D1E\u2D1F\u2D20\u2D21"+ - "\u2D22\u2D23\u2D24\u2D25\u2D26\u2D27\u2D28\u2D29"+ - "\u2D2A\u2D2B\u2D2C\u2D2D\u2D2E\u2D2F\u2D30\u2D31"+ - "\u2D32\u2D33\u2D34\u2D35\u2D36\u2D37\u2D38\u2D39"+ - "\u2D3A\u2D3B\u2D3C\u2D3D\u2D3E\u2D3F\u2D40\u2D41"+ - "\u2D42\u2D43\u2D44\u2D45\u2D46\u2D47\u2D48\u2D49"+ - "\u2D4A\u2D4B\u2D4C\u2D4D\u2D4E\u2D4F\u2D50\u2D51"+ - "\u2D52\u2D53\u2D54\u2D55\u2D56\u2D57\u2D58\u2D59"+ - "\u2D5A\u2D5B\u2D5C\u2D5D\u2D5E\u2D5F\u2D60\u2D61"+ - "\u2D62\u2D63\u2D64\u2D65\u2D66\u2D67\u2D68\u2D69"+ - "\u2D6A\u2D6B\u2D6C\u2D6D\u2D6E\u2D6F\u2D70\u2D71"+ - "\u2D72\u2D73\u2D74\u2D75\u2D76\u2D77\u2D78\u2D79"+ - "\u2D7A\u2D7B\u2D7C\u2D7D\u2D7E\u2D7F\u2D80\u2D81"+ - "\u2D82\u2D83\u2D84\u2D85\u2D86\u2D87\u2D88\u2D89"+ - "\u2D8A\u2D8B\u2D8C\u2D8D\u2D8E\u2D8F\u2D90\u2D91"+ - "\u2D92\u2D93\u2D94\u2D95\u2D96\u2D97\u2D98\u2D99"+ - "\u2D9A\u2D9B\u2D9C\u2D9D\u2D9E\u2D9F\u2DA0\u2DA1"+ - "\u2DA2\u2DA3\u2DA4\u2DA5\u2DA6\u2DA7\u2DA8\u2DA9"+ - "\u2DAA\u2DAB\u2DAC\u2DAD\u2DAE\u2DAF\u2DB0\u2DB1"+ - "\u2DB2\u2DB3\u2DB4\u2DB5\u2DB6\u2DB7\u2DB8\u2DB9"+ - "\u2DBA\u2DBB\u2DBC\u2DBD\u2DBE\u2DBF\u2DC0\u2DC1"+ - "\u2DC2\u2DC3\u2DC4\u2DC5\u2DC6\u2DC7\u2DC8\u2DC9"+ - "\u2DCA\u2DCB\u2DCC\u2DCD\u2DCE\u2DCF\u2DD0\u2DD1"+ - "\u2DD2\u2DD3\u2DD4\u2DD5\u2DD6\u2DD7\u2DD8\u2DD9"+ - "\u2DDA\u2DDB\u2DDC\u2DDD\u2DDE\u2DDF\u2DE0\u2DE1"+ - "\u2DE2\u2DE3\u2DE4\u2DE5\u2DE6\u2DE7\u2DE8\u2DE9"+ - "\u2DEA\u2DEB\u2DEC\u2DED\u2DEE\u2DEF\u2DF0\u2DF1"+ - "\u2DF2\u2DF3\u2DF4\u2DF5\u2DF6\u2DF7\u2DF8\u2DF9"+ - "\u2DFA\u2DFB\u2DFC\u2DFD\u2DFE\u2DFF\u2E00\u2E01"+ - "\u2E02\u2E03\u2E04\u2E05\u2E06\u2E07\u2E08\u2E09"+ - "\u2E0A\u2E0B\u2E0C\u2E0D\u2E0E\u2E0F\u2E10\u2E11"+ - "\u2E12\u2E13\u2E14\u2E15\u2E16\u2E17\u2E18\u2E19"+ - "\u2E1A\u2E1B\u2E1C\u2E1D\u2E1E\u2E1F\u2E20\u2E21"+ - "\u2E22\u2E23\u2E24\u2E25\u2E26\u2E27\u2E28\u2E29"+ - "\u2E2A\u2E2B\u2E2C\u2E2D\u2E2E\u2E2F\u2E30\u2E31"+ - "\u2E32\u2E33\u2E34\u2E35\u2E36\u2E37\u2E38\u2E39"+ - "\u2E3A\u2E3B\u2E3C\u2E3D\u2E3E\u2E3F\u2E40\u2E41"+ - "\u2E42\u2E43\u2E44\u2E45\u2E46\u2E47\u2E48\u2E49"+ - "\u2E4A\u2E4B\u2E4C\u2E4D\u2E4E\u2E4F\u2E50\u2E51"+ - "\u2E52\u2E53\u2E54\u2E55\u2E56\u2E57\u2E58\u2E59"+ - "\u2E5A\u2E5B\u2E5C\u2E5D\u2E5E\u2E5F\u2E60\u2E61"+ - "\u2E62\u2E63\u2E64\u2E65\u2E66\u2E67\u2E68\u2E69"+ - "\u2E6A\u2E6B\u2E6C\u2E6D\u2E6E\u2E6F\u2E70\u2E71"+ - "\u2E72\u2E73\u2E74\u2E75\u2E76\u2E77\u2E78\u2E79"+ - "\u2E7A\u2E7B\u2E7C\u2E7D\u2E7E\u2E7F\u2E80\u2E81"+ - "\u2E82\u2E83\u2E84\u2E85\u2E86\u2E87\u2E88\u2E89"+ - "\u2E8A\u2E8B\u2E8C\u2E8D\u2E8E\u2E8F\u2E90\u2E91"+ - "\u2E92\u2E93\u2E94\u2E95\u2E96\u2E97\u2E98\u2E99"+ - "\u2E9A\u2E9B\u2E9C\u2E9D\u2E9E\u2E9F\u2EA0\u2EA1"+ - "\u2EA2\u2EA3\u2EA4\u2EA5\u2EA6\u2EA7\u2EA8\u2EA9"+ - "\u2EAA\u2EAB\u2EAC\u2EAD\u2EAE\u2EAF\u2EB0\u2EB1"+ - "\u2EB2\u2EB3\u2EB4\u2EB5\u2EB6\u2EB7\u2EB8\u2EB9"+ - "\u2EBA\u2EBB\u2EBC\u2EBD\u2EBE\u2EBF\u2EC0\u2EC1"+ - "\u2EC2\u2EC3\u2EC4\u2EC5\u2EC6\u2EC7\u2EC8\u2EC9"+ - "\u2ECA\u2ECB\u2ECC\u2ECD\u2ECE\u2ECF\u2ED0\u2ED1"+ - "\u2ED2\u2ED3\u2ED4\u2ED5\u2ED6\u2ED7\u2ED8\u2ED9"+ - "\u2EDA\u2EDB\u2EDC\u2EDD\u2EDE\u2EDF\u2EE0\u2EE1"; - - private static final String innerEncoderIndex1= - "\u2EE2\u2EE3\u2EE4\u2EE5\u2EE6\u2EE7\u2EE8\u2EE9"+ - "\u2EEA\u2EEB\u2EEC\u2EED\u2EEE\u2EEF\u2EF0\u2EF1"+ - "\u2EF2\u2EF3\u2EF4\u2EF5\u2EF6\u2EF7\u2EF8\u2EF9"+ - "\u2EFA\u2EFB\u2EFC\u2EFD\u2EFE\u2EFF\u2F00\u2F01"+ - "\u2F02\u2F03\u2F04\u2F05\u2F06\u2F07\u2F08\u2F09"+ - "\u2F0A\u2F0B\u2F0C\u2F0D\u2F0E\u2F0F\u2F10\u2F11"+ - "\u2F12\u2F13\u2F14\u2F15\u2F16\u2F17\u2F18\u2F19"+ - "\u2F1A\u2F1B\u2F1C\u2F1D\u2F1E\u2F1F\u2F20\u2F21"+ - "\u2F22\u2F23\u2F24\u2F25\u2F26\u2F27\u2F28\u2F29"+ - "\u2F2A\u2F2B\u2F2C\u2F2D\u2F2E\u2F2F\u2F30\u2F31"+ - "\u2F32\u2F33\u2F34\u2F35\u2F36\u2F37\u2F38\u2F39"+ - "\u2F3A\u2F3B\u2F3C\u2F3D\u2F3E\u2F3F\u2F40\u2F41"+ - "\u2F42\u2F43\u2F44\u2F45\u2F46\u2F47\u2F48\u2F49"+ - "\u2F4A\u2F4B\u2F4C\u2F4D\u2F4E\u2F4F\u2F50\u2F51"+ - "\u2F52\u2F53\u2F54\u2F55\u2F56\u2F57\u2F58\u2F59"+ - "\u2F5A\u2F5B\u2F5C\u2F5D\u2F5E\u2F5F\u2F60\u2F61"+ - "\u2F62\u2F63\u2F64\u2F65\u2F66\u2F67\u2F68\u2F69"+ - "\u2F6A\u2F6B\u2F6C\u2F6D\u2F6E\u2F6F\u2F70\u2F71"+ - "\u2F72\u2F73\u2F74\u2F75\u2F76\u2F77\u2F78\u2F79"+ - "\u2F7A\u2F7B\u2F7C\u2F7D\u2F7E\u2F7F\u2F80\u2F81"+ - "\u2F82\u2F83\u2F84\u2F85\u2F86\u2F87\u2F88\u2F89"+ - "\u2F8A\u2F8B\u2F8C\u2F8D\u2F8E\u2F8F\u2F90\u2F91"+ - "\u2F92\u2F93\u2F94\u2F95\u2F96\u2F97\u2F98\u2F99"+ - "\u2F9A\u2F9B\u2F9C\u2F9D\u2F9E\u2F9F\u2FA0\u2FA1"+ - "\u2FA2\u2FA3\u2FA4\u2FA5\u2FA6\u2FA7\u2FA8\u2FA9"+ - "\u2FAA\u2FAB\u2FAC\u2FAD\u2FAE\u2FAF\u2FB0\u2FB1"+ - "\u2FB2\u2FB3\u2FB4\u2FB5\u2FB6\u2FB7\u2FB8\u2FB9"+ - "\u2FBA\u2FBB\u2FBC\u2FBD\u2FBE\u2FBF\u2FC0\u2FC1"+ - "\u2FC2\u2FC3\u2FC4\u2FC5\u2FC6\u2FC7\u2FC8\u2FC9"+ - "\u2FCA\u2FCB\u2FCC\u2FCD\u2FCE\u2FCF\u2FD0\u2FD1"+ - "\u2FD2\u2FD3\u2FD4\u2FD5\u2FD6\u2FD7\u2FD8\u2FD9"+ - "\u2FDA\u2FDB\u2FDC\u2FDD\u2FDE\u2FDF\u2FE0\u2FE1"+ - "\u2FE2\u2FE3\u2FE4\u2FE5\u2FE6\u2FE7\u2FE8\u2FE9"+ - "\u2FEA\u2FEB\u2FEC\u2FED\u2FEE\u2FEF\u2FF0\u2FF1"+ - "\u2FF2\u2FF3\u2FF4\u2FF5\u2FF6\u2FF7\u2FF8\u2FF9"+ - "\u2FFA\u2FFB\u2FFC\u2FFD\u2FFE\u2FFF\u3000\u3001"+ - "\u3002\u3003\u3004\u3005\u3006\u3007\u3008\u3009"+ - "\u300A\u300B\u300C\u300D\u300E\u300F\u3010\u3011"+ - "\u3012\u3013\u3014\u3015\u3016\u3017\u3018\u3019"+ - "\u301A\u301B\u301C\u301D\u301E\u301F\u3020\u3021"+ - "\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029"+ - "\u302A\u302B\u302C\u302D\u302E\u302F\u3030\u3031"+ - "\u3032\u3033\u3034\u3035\u3036\u3037\u3038\u3039"+ - "\u303A\u303B\u303C\u303D\u303E\u303F\u3040\u3041"+ - "\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049"+ - "\u304A\u304B\u304C\u304D\u304E\u304F\u3050\u3051"+ - "\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059"+ - "\u305A\u305B\u305C\u305D\u305E\u305F\u3060\u3061"+ - "\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069"+ - "\u306A\u306B\u306C\u306D\u306E\u306F\u3070\u3071"+ - "\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079"+ - "\u307A\u307B\u307C\u307D\u307E\u307F\u3080\u3081"+ - "\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089"+ - "\u308A\u308B\u308C\u308D\u308E\u308F\u3090\u3091"+ - "\u3092\u3093\u3094\u3095\u3096\u3097\u3098\u3099"+ - "\u309A\u309B\u309C\u309D\u309E\u309F\u30A0\u30A1"+ - "\u30A2\u30A3\u30A4\u30A5\u30A6\u30A7\u30A8\u30A9"+ - "\u30AA\u30AB\u30AC\u30AD\u30AE\u30AF\u30B0\u30B1"+ - "\u30B2\u30B3\u30B4\u30B5\u30B6\u30B7\u30B8\u30B9"+ - "\u30BA\u30BB\u30BC\u30BD\u30BE\u30BF\u30C0\u30C1"+ - "\u30C2\u30C3\u30C4\u30C5\u30C6\u30C7\u30C8\u30C9"+ - "\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D0\u30D1"+ - "\u30D2\u30D3\u30D4\u30D5\u30D6\u30D7\u30D8\u30D9"+ - "\u30DA\u30DB\u30DC\u30DD\u30DE\u30DF\u30E0\u30E1"+ - "\u30E2\u30E3\u30E4\u30E5\u30E6\u30E7\u30E8\u30E9"+ - "\u30EA\u30EB\u30EC\u30ED\u30EE\u30EF\u30F0\u30F1"+ - "\u30F2\u30F3\u30F4\u30F5\u30F6\u30F7\u30F8\u30F9"+ - "\u30FA\u30FB\u30FC\u30FD\u30FE\u30FF\u3100\u3101"+ - "\u3102\u3103\u3104\u3105\u3106\u3107\u3108\u3109"+ - "\u310A\u310B\u310C\u310D\u310E\u310F\u3110\u3111"+ - "\u3112\u3113\u3114\u3115\u3116\u3117\u3118\u3119"+ - "\u311A\u311B\u311C\u311D\u311E\u311F\u3120\u3121"+ - "\u3122\u3123\u3124\u3125\u3126\u3127\u3128\u3129"+ - "\u312A\u312B\u312C\u312D\u312E\u312F\u3130\u3131"+ - "\u3132\u3133\u3134\u3135\u3136\u3137\u3138\u3139"+ - "\u313A\u313B\u313C\u313D\u313E\u313F\u3140\u3141"+ - "\u3142\u3143\u3144\u3145\u3146\u3147\u3148\u3149"+ - "\u314A\u314B\u314C\u314D\u314E\u314F\u3150\u3151"+ - "\u3152\u3153\u3154\u3155\u3156\u3157\u3158\u3159"+ - "\u315A\u315B\u315C\u315D\u315E\u315F\u3160\u3161"+ - "\u3162\u3163\u3164\u3165\u3166\u3167\u3168\u3169"+ - "\u316A\u316B\u316C\u316D\u316E\u316F\u3170\u3171"+ - "\u3172\u3173\u3174\u3175\u3176\u3177\u3178\u3179"+ - "\u317A\u317B\u317C\u317D\u317E\u317F\u3180\u3181"+ - "\u3182\u3183\u3184\u3185\u3186\u3187\u3188\u3189"+ - "\u318A\u318B\u318C\u318D\u318E\u318F\u3190\u3191"+ - "\u3192\u3193\u3194\u3195\u3196\u3197\u3198\u3199"+ - "\u319A\u319B\u319C\u319D\u319E\u319F\u31A0\u31A1"+ - "\u31A2\u31A3\u31A4\u31A5\u31A6\u31A7\u31A8\u31A9"+ - "\u31AA\u31AB\u31AC\u31AD\u31AE\u31AF\u31B0\u31B1"+ - "\u31B2\u31B3\u31B4\u31B5\u31B6\u31B7\u31B8\u31B9"+ - "\u31BA\u31BB\u31BC\u31BD\u31BE\u31BF\u31C0\u31C1"+ - "\u31C2\u31C3\u31C4\u31C5\u31C6\u31C7\u31C8\u31C9"+ - "\u31CA\u31CB\u31CC\u31CD\u31CE\u31CF\u31D0\u31D1"+ - "\u31D2\u31D3\u31D4\u31D5\u31D6\u31D7\u31D8\u31D9"+ - "\u31DA\u31DB\u31DC\u31DD\u31DE\u31DF\u31E0\u31E1"+ - "\u31E2\u31E3\u31E4\u31E5\u31E6\u31E7\u31E8\u31E9"+ - "\u31EA\u31EB\u31EC\u31ED\u31EE\u31EF\u31F0\u31F1"+ - "\u31F2\u31F3\u31F4\u31F5\u31F6\u31F7\u31F8\u31F9"+ - "\u31FA\u31FB\u31FC\u31FD\u31FE\u31FF\u3200\u3201"+ - "\u3202\u3203\u3204\u3205\u3206\u3207\u3208\u3209"+ - "\u320A\u320B\u320C\u320D\u320E\u320F\u3210\u3211"+ - "\u3212\u3213\u3214\u3215\u3216\u3217\u3218\u3219"+ - "\u321A\u321B\u321C\u321D\u321E\u321F\u3220\u3221"+ - "\u3222\u3223\u3224\u3225\u3226\u3227\u3228\u3229"+ - "\u322A\u322B\u322C\u322D\u322E\u322F\u3230\u3231"+ - "\u3232\u3233\u3234\u3235\u3236\u3237\u3238\u3239"+ - "\u323A\u323B\u323C\u323D\u323E\u323F\u3240\u3241"+ - "\u3242\u3243\u3244\u3245\u3246\u3247\u3248\u3249"+ - "\u324A\u324B\u324C\u324D\u324E\u324F\u3250\u3251"+ - "\u3252\u3253\u3254\u3255\u3256\u3257\u3258\u3259"+ - "\u325A\u325B\u325C\u325D\u325E\u325F\u3260\u3261"+ - "\u3262\u3263\u3264\u3265\u3266\u3267\u3268\u3269"+ - "\u326A\u326B\u326C\u326D\u326E\u326F\u3270\u3271"+ - "\u3272\u3273\u3274\u3275\u3276\u3277\u3278\u3279"+ - "\u327A\u327B\u327C\u327D\u327E\u327F\u3280\u3281"+ - "\u3282\u3283\u3284\u3285\u3286\u3287\u3288\u3289"+ - "\u328A\u328B\u328C\u328D\u328E\u328F\u3290\u3291"+ - "\u3292\u3293\u3294\u3295\u3296\u3297\u3298\u3299"+ - "\u329A\u329B\u329C\u329D\u329E\u329F\u32A0\u32A1"+ - "\u32A2\u32A3\u32A4\u32A5\u32A6\u32A7\u32A8\u32A9"+ - "\u32AA\u32AB\u32AC\u32AD\u32AE\u32AF\u32B0\u32B1"+ - "\u32B2\u32B3\u32B4\u32B5\u32B6\u32B7\u32B8\u32B9"+ - "\u32BA\u32BB\u32BC\u32BD\u32BE\u32BF\u32C0\u32C1"+ - "\u32C2\u32C3\u32C4\u32C5\u32C6\u32C7\u32C8\u32C9"+ - "\u32CA\u32CB\u32CC\u32CD\u32CE\u32CF\u32D0\u32D1"+ - "\u32D2\u32D3\u32D4\u32D5\u32D6\u32D7\u32D8\u32D9"+ - "\u32DA\u32DB\u32DC\u32DD\u32DE\u32DF\u32E0\u32E1"+ - "\u32E2\u32E3\u32E4\u32E5\u32E6\u32E7\u32E8\u32E9"+ - "\u32EA\u32EB\u32EC\u32ED\u32EE\u32EF\u32F0\u32F1"+ - "\u32F2\u32F3\u32F4\u32F5\u32F6\u32F7\u32F8\u32F9"+ - "\u32FA\u32FB\u32FC\u32FD\u32FE\u32FF\u3300\u3301"+ - "\u3302\u3303\u3304\u3305\u3306\u3307\u3308\u3309"+ - "\u330A\u330B\u330C\u330D\u330E\u330F\u3310\u3311"+ - "\u3312\u3313\u3314\u3315\u3316\u3317\u3318\u3319"+ - "\u331A\u331B\u331C\u331D\u331E\u331F\u3320\u3321"+ - "\u3322\u3323\u3324\u3325\u3326\u3327\u3328\u3329"+ - "\u332A\u332B\u332C\u332D\u332E\u332F\u3330\u3331"+ - "\u3332\u3333\u3334\u3335\u3336\u3337\u3338\u3339"+ - "\u333A\u333B\u333C\u333D\u333E\u333F\u3340\u3341"+ - "\u3342\u3343\u3344\u3345\u3346\u3347\u3348\u3349"+ - "\u334A\u334B\u334C\u334D\u334E\u334F\u3350\u3351"+ - "\u3352\u3353\u3354\u3355\u3356\u3357\u3358\u3359"+ - "\u335A\u335B\u335C\u335D\u335E\u335F\u3360\u3361"+ - "\u3362\u3363\u3364\u3365\u3366\u3367\u3368\u3369"+ - "\u336A\u336B\u336C\u336D\u336E\u336F\u3370\u3371"+ - "\u3372\u3373\u3374\u3375\u3376\u3377\u3378\u3379"+ - "\u337A\u337B\u337C\u337D\u337E\u337F\u3380\u3381"+ - "\u3382\u3383\u3384\u3385\u3386\u3387\u3388\u3389"+ - "\u338A\u338B\u338C\u338D\u338E\u338F\u3390\u3391"+ - "\u3392\u3393\u3394\u3395\u3396\u3397\u3398\u3399"+ - "\u339A\u339B\u339C\u339D\u339E\u339F\u33A0\u33A1"+ - "\u33A2\u33A3\u33A4\u33A5\u33A6\u33A7\u33A8\u33A9"+ - "\u33AA\u33AB\u33AC\u33AD\u33AE\u33AF\u33B0\u33B1"+ - "\u33B2\u33B3\u33B4\u33B5\u33B6\u33B7\u33B8\u33B9"+ - "\u33BA\u33BB\u33BC\u33BD\u33BE\u33BF\u33C0\u33C1"+ - "\u33C2\u33C3\u33C4\u33C5\u33C6\u33C7\u33C8\u33C9"+ - "\u33CA\u33CB\u33CC\u33CD\u33CE\u33CF\u33D0\u33D1"+ - "\u33D2\u33D3\u33D4\u33D5\u33D6\u33D7\u33D8\u33D9"+ - "\u33DA\u33DB\u33DC\u33DD\u33DE\u33DF\u33E0\u33E1"+ - "\u33E2\u33E3\u33E4\u33E5\u33E6\u33E7\u33E8\u33E9"+ - "\u33EA\u33EB\u33EC\u33ED\u33EE\u33EF\u33F0\u33F1"+ - "\u33F2\u33F3\u33F4\u33F5\u33F6\u33F7\u33F8\u33F9"+ - "\u33FA\u33FB\u33FC\u33FD\u33FE\u33FF\u3400\u3401"+ - "\u3402\u3403\u3404\u3405\u3406\u3407\u3408\u3409"+ - "\u340A\u340B\u340C\u340D\u340E\u340F\u3410\u3411"+ - "\u3412\u3413\u3414\u3415\u3416\u3417\u3418\u3419"+ - "\u341A\u341B\u341C\u341D\u341E\u341F\u3420\u3421"+ - "\u3422\u3423\u3424\u3425\u3426\u3427\u3428\u3429"+ - "\u342A\u342B\u342C\u342D\u342E\u342F\u3430\u3431"+ - "\u3432\u3433\u3434\u3435\u3436\u3437\u3438\u3439"+ - "\u343A\u343B\u343C\u343D\u343E\u343F\u3440\u3441"+ - "\u3442\u3443\u3444\u3445\u3446\u3447\u3448\u3449"+ - "\u344A\u344B\u344C\u344D\u344E\u344F\u3450\u3451"+ - "\u3452\u3453\u3454\u3455\u3456\u3457\u3458\u3459"+ - "\u345A\u345B\u345C\u345D\u345E\u345F\u3460\u3461"+ - "\u3462\u3463\u3464\u3465\u3466\u3467\u3468\u3469"+ - "\u346A\u346B\u346C\u346D\u346E\u346F\u3470\u3471"+ - "\u3472\u3473\u3474\u3475\u3476\u3477\u3478\u3479"+ - "\u347A\u347B\u347C\u347D\u347E\u347F\u3480\u3481"+ - "\u3482\u3483\u3484\u3485\u3486\u3487\u3488\u3489"+ - "\u348A\u348B\u348C\u348D\u348E\u348F\u3490\u3491"+ - "\u3492\u3493\u3494\u3495\u3496\u3497\u3498\u3499"+ - "\u349A\u349B\u349C\u349D\u349E\u349F\u34A0\u34A1"+ - "\u34A2\u34A3\u34A4\u34A5\u34A6\u34A7\u34A8\u34A9"+ - "\u34AA\u34AB\u34AC\u34AD\u34AE\u34AF\u34B0\u34B1"+ - "\u34B2\u34B3\u34B4\u34B5\u34B6\u34B7\u34B8\u34B9"+ - "\u34BA\u34BB\u34BC\u34BD\u34BE\u34BF\u34C0\u34C1"+ - "\u34C2\u34C3\u34C4\u34C5\u34C6\u34C7\u34C8\u34C9"+ - "\u34CA\u34CB\u34CC\u34CD\u34CE\u34CF\u34D0\u34D1"+ - "\u34D2\u34D3\u34D4\u34D5\u34D6\u34D7\u34D8\u34D9"+ - "\u34DA\u34DB\u34DC\u34DD\u34DE\u34DF\u34E0\u34E1"+ - "\u34E2\u34E3\u34E4\u34E5\u34E6\u34E7\u34E8\u34E9"+ - "\u34EA\u34EB\u34EC\u34ED\u34EE\u34EF\u34F0\u34F1"+ - "\u34F2\u34F3\u34F4\u34F5\u34F6\u34F7\u34F8\u34F9"+ - "\u34FA\u34FB\u34FC\u34FD\u34FE\u34FF\u3500\u3501"+ - "\u3502\u3503\u3504\u3505\u3506\u3507\u3508\u3509"+ - "\u350A\u350B\u350C\u350D\u350E\u350F\u3510\u3511"+ - "\u3512\u3513\u3514\u3515\u3516\u3517\u3518\u3519"+ - "\u351A\u351B\u351C\u351D\u351E\u351F\u3520\u3521"+ - "\u3522\u3523\u3524\u3525\u3526\u3527\u3528\u3529"+ - "\u352A\u352B\u352C\u352D\u352E\u352F\u3530\u3531"+ - "\u3532\u3533\u3534\u3535\u3536\u3537\u3538\u3539"+ - "\u353A\u353B\u353C\u353D\u353E\u353F\u3540\u3541"+ - "\u3542\u3543\u3544\u3545\u3546\u3547\u3548\u3549"+ - "\u354A\u354B\u354C\u354D\u354E\u354F\u3550\u3551"+ - "\u3552\u3553\u3554\u3555\u3556\u3557\u3558\u3559"+ - "\u355A\u355B\u355C\u355D\u355E\u355F\u3560\u3561"+ - "\u3562\u3563\u3564\u3565\u3566\u3567\u3568\u3569"+ - "\u356A\u356B\u356C\u356D\u356E\u356F\u3570\u3571"+ - "\u3572\u3573\u3574\u3575\u3576\u3577\u3578\u3579"+ - "\u357A\u357B\u357C\u357D\u357E\u357F\u3580\u3581"+ - "\u3582\u3583\u3584\u3585\u3586\u3587\u3588\u3589"+ - "\u358A\u358B\u358C\u358D\u358E\u358F\u3590\u3591"+ - "\u3592\u3593\u3594\u3595\u3596\u3597\u3598\u3599"+ - "\u359A\u359B\u359C\u359D\u359E\u359F\u35A0\u35A1"+ - "\u35A2\u35A3\u35A4\u35A5\u35A6\u35A7\u35A8\u35A9"+ - "\u35AA\u35AB\u35AC\u35AD\u35AE\u35AF\u35B0\u35B1"+ - "\u35B2\u35B3\u35B4\u35B5\u35B6\u35B7\u35B8\u35B9"+ - "\u35BA\u35BB\u35BC\u35BD\u35BE\u35BF\u35C0\u35C1"+ - "\u35C2\u35C3\u35C4\u35C5\u35C6\u35C7\u35C8\u35C9"+ - "\u35CA\u35CB\u35CC\u35CD\u35CE\u35CF\u35D0\u35D1"+ - "\u35D2\u35D3\u35D4\u35D5\u35D6\u35D7\u35D8\u35D9"+ - "\u35DA\u35DB\u35DC\u35DD\u35DE\u35DF\u35E0\u35E1"+ - "\u35E2\u35E3\u35E4\u35E5\u35E6\u35E7\u35E8\u35E9"+ - "\u35EA\u35EB\u35EC\u35ED\u35EE\u35EF\u35F0\u35F1"+ - "\u35F2\u35F3\u35F4\u35F5\u35F6\u35F7\u35F8\u35F9"+ - "\u35FA\u35FB\u35FC\u35FD\u35FE\u35FF\u3600\u3601"+ - "\u3602\u3603\u3604\u3605\u3606\u3607\u3608\u3609"+ - "\u360A\u360B\u360C\u360D\u360E\u360F\u3610\u3611"+ - "\u3612\u3613\u3614\u3615\u3616\u3617\u3618\u3619"+ - "\u361A\u361B\u361C\u361D\u361E\u361F\u3620\u3621"+ - "\u3622\u3623\u3624\u3625\u3626\u3627\u3628\u3629"+ - "\u362A\u362B\u362C\u362D\u362E\u362F\u3630\u3631"+ - "\u3632\u3633\u3634\u3635\u3636\u3637\u3638\u3639"+ - "\u363A\u363B\u363C\u363D\u363E\u363F\u3640\u3641"+ - "\u3642\u3643\u3644\u3645\u3646\u3647\u3648\u3649"+ - "\u364A\u364B\u364C\u364D\u364E\u364F\u3650\u3651"+ - "\u3652\u3653\u3654\u3655\u3656\u3657\u3658\u3659"+ - "\u365A\u365B\u365C\u365D\u365E\u365F\u3660\u3661"+ - "\u3662\u3663\u3664\u3665\u3666\u3667\u3668\u3669"+ - "\u366A\u366B\u366C\u366D\u366E\u366F\u3670\u3671"+ - "\u3672\u3673\u3674\u3675\u3676\u3677\u3678\u3679"+ - "\u367A\u367B\u367C\u367D\u367E\u367F\u3680\u3681"+ - "\u3682\u3683\u3684\u3685\u3686\u3687\u3688\u3689"+ - "\u368A\u368B\u368C\u368D\u368E\u368F\u3690\u3691"+ - "\u3692\u3693\u3694\u3695\u3696\u3697\u3698\u3699"+ - "\u369A\u369B\u369C\u369D\u369E\u369F\u36A0\u36A1"+ - "\u36A2\u36A3\u36A4\u36A5\u36A6\u36A7\u36A8\u36A9"+ - "\u36AA\u36AB\u36AC\u36AD\u36AE\u36AF\u36B0\u36B1"+ - "\u36B2\u36B3\u36B4\u36B5\u36B6\u36B7\u36B8\u36B9"+ - "\u36BA\u36BB\u36BC\u36BD\u36BE\u36BF\u36C0\u36C1"+ - "\u36C2\u36C3\u36C4\u36C5\u36C6\u36C7\u36C8\u36C9"+ - "\u36CA\u36CB\u36CC\u36CD\u36CE\u36CF\u36D0\u36D1"+ - "\u36D2\u36D3\u36D4\u36D5\u36D6\u36D7\u36D8\u36D9"+ - "\u36DA\u36DB\u36DC\u36DD\u36DE\u36DF\u36E0\u36E1"+ - "\u36E2\u36E3\u36E4\u36E5\u36E6\u36E7\u36E8\u36E9"+ - "\u36EA\u36EB\u36EC\u36ED\u36EE\u36EF\u36F0\u36F1"+ - "\u36F2\u36F3\u36F4\u36F5\u36F6\u36F7\u36F8\u36F9"+ - "\u36FA\u36FB\u36FC\u36FD\u36FE\u36FF\u3700\u3701"+ - "\u3702\u3703\u3704\u3705\u3706\u3707\u3708\u3709"+ - "\u370A\u370B\u370C\u370D\u370E\u370F\u3710\u3711"+ - "\u3712\u3713\u3714\u3715\u3716\u3717\u3718\u3719"+ - "\u371A\u371B\u371C\u371D\u371E\u371F\u3720\u3721"+ - "\u3722\u3723\u3724\u3725\u3726\u3727\u3728\u3729"+ - "\u372A\u372B\u372C\u372D\u372E\u372F\u3730\u3731"+ - "\u3732\u3733\u3734\u3735\u3736\u3737\u3738\u3739"+ - "\u373A\u373B\u373C\u373D\u373E\u373F\u3740\u3741"+ - "\u3742\u3743\u3744\u3745\u3746\u3747\u3748\u3749"+ - "\u374A\u374B\u374C\u374D\u374E\u374F\u3750\u3751"+ - "\u3752\u3753\u3754\u3755\u3756\u3757\u3758\u3759"+ - "\u375A\u375B\u375C\u375D\u375E\u375F\u3760\u3761"+ - "\u3762\u3763\u3764\u3765\u3766\u3767\u3768\u3769"+ - "\u376A\u376B\u376C\u376D\u376E\u376F\u3770\u3771"+ - "\u3772\u3773\u3774\u3775\u3776\u3777\u3778\u3779"+ - "\u377A\u377B\u377C\u377D\u377E\u377F\u3780\u3781"+ - "\u3782\u3783\u3784\u3785\u3786\u3787\u3788\u3789"+ - "\u378A\u378B\u378C\u378D\u378E\u378F\u3790\u3791"+ - "\u3792\u3793\u3794\u3795\u3796\u3797\u3798\u3799"+ - "\u379A\u379B\u379C\u379D\u379E\u379F\u37A0\u37A1"+ - "\u37A2\u37A3\u37A4\u37A5\u37A6\u37A7\u37A8\u37A9"+ - "\u37AA\u37AB\u37AC\u37AD\u37AE\u37AF\u37B0\u37B1"+ - "\u37B2\u37B3\u37B4\u37B5\u37B6\u37B7\u37B8\u37B9"+ - "\u37BA\u37BB\u37BC\u37BD\u37BE\u37BF\u37C0\u37C1"+ - "\u37C2\u37C3\u37C4\u37C5\u37C6\u37C7\u37C8\u37C9"+ - "\u37CA\u37CB\u37CC\u37CD\u37CE\u37CF\u37D0\u37D1"+ - "\u37D2\u37D3\u37D4\u37D5\u37D6\u37D7\u37D8\u37D9"+ - "\u37DA\u37DB\u37DC\u37DD\u37DE\u37DF\u37E0\u37E1"+ - "\u37E2\u37E3\u37E4\u37E5\u37E6\u37E7\u37E8\u37E9"+ - "\u37EA\u37EB\u37EC\u37ED\u37EE\u37EF\u37F0\u37F1"+ - "\u37F2\u37F3\u37F4\u37F5\u37F6\u37F7\u37F8\u37F9"+ - "\u37FA\u37FB\u37FC\u37FD\u37FE\u37FF\u3800\u3801"+ - "\u3802\u3803\u3804\u3805\u3806\u3807\u3808\u3809"+ - "\u380A\u380B\u380C\u380D\u380E\u380F\u3810\u3811"+ - "\u3812\u3813\u3814\u3815\u3816\u3817\u3818\u3819"+ - "\u381A\u381B\u381C\u381D\u381E\u381F\u3820\u3821"+ - "\u3822\u3823\u3824\u3825\u3826\u3827\u3828\u3829"+ - "\u382A\u382B\u382C\u382D\u382E\u382F\u3830\u3831"+ - "\u3832\u3833\u3834\u3835\u3836\u3837\u3838\u3839"+ - "\u383A\u383B\u383C\u383D\u383E\u383F\u3840\u3841"+ - "\u3842\u3843\u3844\u3845\u3846\u3847\u3848\u3849"+ - "\u384A\u384B\u384C\u384D\u384E\u384F\u3850\u3851"+ - "\u3852\u3853\u3854\u3855\u3856\u3857\u3858\u3859"+ - "\u385A\u385B\u385C\u385D\u385E\u385F\u3860\u3861"+ - "\u3862\u3863\u3864\u3865\u3866\u3867\u3868\u3869"+ - "\u386A\u386B\u386C\u386D\u386E\u386F\u3870\u3871"+ - "\u3872\u3873\u3874\u3875\u3876\u3877\u3878\u3879"+ - "\u387A\u387B\u387C\u387D\u387E\u387F\u3880\u3881"+ - "\u3882\u3883\u3884\u3885\u3886\u3887\u3888\u3889"+ - "\u388A\u388B\u388C\u388D\u388E\u388F\u3890\u3891"+ - "\u3892\u3893\u3894\u3895\u3896\u3897\u3898\u3899"+ - "\u389A\u389B\u389C\u389D\u389E\u389F\u38A0\u38A1"+ - "\u38A2\u38A3\u38A4\u38A5\u38A6\u38A7\u38A8\u38A9"+ - "\u38AA\u38AB\u38AC\u38AD\u38AE\u38AF\u38B0\u38B1"+ - "\u38B2\u38B3\u38B4\u38B5\u38B6\u38B7\u38B8\u38B9"+ - "\u38BA\u38BB\u38BC\u38BD\u38BE\u38BF\u38C0\u38C1"+ - "\u38C2\u38C3\u38C4\u38C5\u38C6\u38C7\u38C8\u38C9"+ - "\u38CA\u38CB\u38CC\u38CD\u38CE\u38CF\u38D0\u38D1"+ - "\u38D2\u38D3\u38D4\u38D5\u38D6\u38D7\u38D8\u38D9"+ - "\u38DA\u38DB\u38DC\u38DD\u38DE\u38DF\u38E0\u38E1"+ - "\u38E2\u38E3\u38E4\u38E5\u38E6\u38E7\u38E8\u38E9"+ - "\u38EA\u38EB\u38EC\u38ED\u38EE\u38EF\u38F0\u38F1"+ - "\u38F2\u38F3\u38F4\u38F5\u38F6\u38F7\u38F8\u38F9"+ - "\u38FA\u38FB\u38FC\u38FD\u38FE\u38FF\u3900\u3901"+ - "\u3902\u3903\u3904\u3905\u3906\u3907\u3908\u3909"+ - "\u390A\u390B\u390C\u390D\u390E\u390F\u3910\u3911"+ - "\u3912\u3913\u3914\u3915\u3916\u3917\u3918\u3919"+ - "\u391A\u391B\u391C\u391D\u391E\u391F\u3920\u3921"+ - "\u3922\u3923\u3924\u3925\u3926\u3927\u3928\u3929"+ - "\u392A\u392B\u392C\u392D\u392E\u392F\u3930\u3931"+ - "\u3932\u3933\u3934\u3935\u3936\u3937\u3938\u3939"+ - "\u393A\u393B\u393C\u393D\u393E\u393F\u3940\u3941"+ - "\u3942\u3943\u3944\u3945\u3946\u3947\u3948\u3949"+ - "\u394A\u394B\u394C\u394D\u394E\u394F\u3950\u3951"+ - "\u3952\u3953\u3954\u3955\u3956\u3957\u3958\u3959"+ - "\u395A\u395B\u395C\u395D\u395E\u395F\u3960\u3961"+ - "\u3962\u3963\u3964\u3965\u3966\u3967\u3968\u3969"+ - "\u396A\u396B\u396C\u396D\u396E\u396F\u3970\u3971"+ - "\u3972\u3973\u3974\u3975\u3976\u3977\u3978\u3979"+ - "\u397A\u397B\u397C\u397D\u397E\u397F\u3980\u3981"+ - "\u3982\u3983\u3984\u3985\u3986\u3987\u3988\u3989"+ - "\u398A\u398B\u398C\u398D\u398E\u398F\u3990\u3991"+ - "\u3992\u3993\u3994\u3995\u3996\u3997\u3998\u3999"+ - "\u399A\u399B\u399C\u399D\u399E\u399F\u39A0\u39A1"+ - "\u39A2\u39A3\u39A4\u39A5\u39A6\u39A7\u39A8\u39A9"+ - "\u39AA\u39AB\u39AC\u39AD\u39AE\u39AF\u39B0\u39B1"+ - "\u39B2\u39B3\u39B4\u39B5\u39B6\u39B7\u39B8\u39B9"+ - "\u39BA\u39BB\u39BC\u39BD\u39BE\u39BF\u39C0\u39C1"+ - "\u39C2\u39C3\u39C4\u39C5\u39C6\u39C7\u39C8\u39C9"+ - "\u39CA\u39CB\u39CC\u39CD\u39CE\u39CF\u39D0\u39D1"+ - "\u39D2\u39D3\u39D4\u39D5\u39D6\u39D7\u39D8\u39D9"+ - "\u39DA\u39DB\u39DC\u39DD\u39DE\u39DF\u39E0\u39E1"+ - "\u39E2\u39E3\u39E4\u39E5\u39E6\u39E7\u39E8\u39E9"+ - "\u39EA\u39EB\u39EC\u39ED\u39EE\u39EF\u39F0\u39F1"+ - "\u39F2\u39F3\u39F4\u39F5\u39F6\u39F7\u39F8\u39F9"+ - "\u39FA\u39FB\u39FC\u39FD\u39FE\u39FF\u3A00\u3A01"+ - "\u3A02\u3A03\u3A04\u3A05\u3A06\u3A07\u3A08\u3A09"+ - "\u3A0A\u3A0B\u3A0C\u3A0D\u3A0E\u3A0F\u3A10\u3A11"+ - "\u3A12\u3A13\u3A14\u3A15\u3A16\u3A17\u3A18\u3A19"+ - "\u3A1A\u3A1B\u3A1C\u3A1D\u3A1E\u3A1F\u3A20\u3A21"+ - "\u3A22\u3A23\u3A24\u3A25\u3A26\u3A27\u3A28\u3A29"+ - "\u3A2A\u3A2B\u3A2C\u3A2D\u3A2E\u3A2F\u3A30\u3A31"+ - "\u3A32\u3A33\u3A34\u3A35\u3A36\u3A37\u3A38\u3A39"+ - "\u3A3A\u3A3B\u3A3C\u3A3D\u3A3E\u3A3F\u3A40\u3A41"+ - "\u3A42\u3A43\u3A44\u3A45\u3A46\u3A47\u3A48\u3A49"+ - "\u3A4A\u3A4B\u3A4C\u3A4D\u3A4E\u3A4F\u3A50\u3A51"+ - "\u3A52\u3A53\u3A54\u3A55\u3A56\u3A57\u3A58\u3A59"+ - "\u3A5A\u3A5B\u3A5C\u3A5D\u3A5E\u3A5F\u3A60\u3A61"+ - "\u3A62\u3A63\u3A64\u3A65\u3A66\u3A67\u3A68\u3A69"+ - "\u3A6A\u3A6B\u3A6C\u3A6D\u3A6E\u3A6F\u3A70\u3A71"+ - "\u3A72\u3A73\u3A74\u3A75\u3A76\u3A77\u3A78\u3A79"+ - "\u3A7A\u3A7B\u3A7C\u3A7D\u3A7E\u3A7F\u3A80\u3A81"+ - "\u3A82\u3A83\u3A84\u3A85\u3A86\u3A87\u3A88\u3A89"+ - "\u3A8A\u3A8B\u3A8C\u3A8D\u3A8E\u3A8F\u3A90\u3A91"+ - "\u3A92\u3A93\u3A94\u3A95\u3A96\u3A97\u3A98\u3A99"+ - "\u3A9A\u3A9B\u3A9C\u3A9D\u3A9E\u3A9F\u3AA0\u3AA1"+ - "\u3AA2\u3AA3\u3AA4\u3AA5\u3AA6\u3AA7\u3AA8\u3AA9"+ - "\u3AAA\u3AAB\u3AAC\u3AAD\u3AAE\u3AAF\u3AB0\u3AB1"+ - "\u3AB2\u3AB3\u3AB4\u3AB5\u3AB6\u3AB7\u3AB8\u3AB9"+ - "\u3ABA\u3ABB\u3ABC\u3ABD\u3ABE\u3ABF\u3AC0\u3AC1"+ - "\u3AC2\u3AC3\u3AC4\u3AC5\u3AC6\u3AC7\u3AC8\u3AC9"+ - "\u3ACA\u3ACB\u3ACC\u3ACD\u3ACE\u3ACF\u3AD0\u3AD1"+ - "\u3AD2\u3AD3\u3AD4\u3AD5\u3AD6\u3AD7\u3AD8\u3AD9"+ - "\u3ADA\u3ADB\u3ADC\u3ADD\u3ADE\u3ADF\u3AE0\u3AE1"+ - "\u3AE2\u3AE3\u3AE4\u3AE5\u3AE6\u3AE7\u3AE8\u3AE9"+ - "\u3AEA\u3AEB\u3AEC\u3AED\u3AEE\u3AEF\u3AF0\u3AF1"+ - "\u3AF2\u3AF3\u3AF4\u3AF5\u3AF6\u3AF7\u3AF8\u3AF9"+ - "\u3AFA\u3AFB\u3AFC\u3AFD\u3AFE\u3AFF\u3B00\u3B01"+ - "\u3B02\u3B03\u3B04\u3B05\u3B06\u3B07\u3B08\u3B09"+ - "\u3B0A\u3B0B\u3B0C\u3B0D\u3B0E\u3B0F\u3B10\u3B11"+ - "\u3B12\u3B13\u3B14\u3B15\u3B16\u3B17\u3B18\u3B19"+ - "\u3B1A\u3B1B\u3B1C\u3B1D\u3B1E\u3B1F\u3B20\u3B21"+ - "\u3B22\u3B23\u3B24\u3B25\u3B26\u3B27\u3B28\u3B29"+ - "\u3B2A\u3B2B\u3B2C\u3B2D\u3B2E\u3B2F\u3B30\u3B31"+ - "\u3B32\u3B33\u3B34\u3B35\u3B36\u3B37\u3B38\u3B39"+ - "\u3B3A\u3B3B\u3B3C\u3B3D\u3B3E\u3B3F\u3B40\u3B41"+ - "\u3B42\u3B43\u3B44\u3B45\u3B46\u3B47\u3B48\u3B49"+ - "\u3B4A\u3B4B\u3B4C\u3B4D\u3B4E\u3B4F\u3B50\u3B51"+ - "\u3B52\u3B53\u3B54\u3B55\u3B56\u3B57\u3B58\u3B59"+ - "\u3B5A\u3B5B\u3B5C\u3B5D\u3B5E\u3B5F\u3B60\u3B61"+ - "\u3B62\u3B63\u3B64\u3B65\u3B66\u3B67\u3B68\u3B69"+ - "\u3B6A\u3B6B\u3B6C\u3B6D\u3B6E\u3B6F\u3B70\u3B71"+ - "\u3B72\u3B73\u3B74\u3B75\u3B76\u3B77\u3B78\u3B79"+ - "\u3B7A\u3B7B\u3B7C\u3B7D\u3B7E\u3B7F\u3B80\u3B81"+ - "\u3B82\u3B83\u3B84\u3B85\u3B86\u3B87\u3B88\u3B89"+ - "\u3B8A\u3B8B\u3B8C\u3B8D\u3B8E\u3B8F\u3B90\u3B91"+ - "\u3B92\u3B93\u3B94\u3B95\u3B96\u3B97\u3B98\u3B99"+ - "\u3B9A\u3B9B\u3B9C\u3B9D\u3B9E\u3B9F\u3BA0\u3BA1"+ - "\u3BA2\u3BA3\u3BA4\u3BA5\u3BA6\u3BA7\u3BA8\u3BA9"+ - "\u3BAA\u3BAB\u3BAC\u3BAD\u3BAE\u3BAF\u3BB0\u3BB1"+ - "\u3BB2\u3BB3\u3BB4\u3BB5\u3BB6\u3BB7\u3BB8\u3BB9"+ - "\u3BBA\u3BBB\u3BBC\u3BBD\u3BBE\u3BBF\u3BC0\u3BC1"+ - "\u3BC2\u3BC3\u3BC4\u3BC5\u3BC6\u3BC7\u3BC8\u3BC9"+ - "\u3BCA\u3BCB\u3BCC\u3BCD\u3BCE\u3BCF\u3BD0\u3BD1"+ - "\u3BD2\u3BD3\u3BD4\u3BD5\u3BD6\u3BD7\u3BD8\u3BD9"+ - "\u3BDA\u3BDB\u3BDC\u3BDD\u3BDE\u3BDF\u3BE0\u3BE1"+ - "\u3BE2\u3BE3\u3BE4\u3BE5\u3BE6\u3BE7\u3BE8\u3BE9"+ - "\u3BEA\u3BEB\u3BEC\u3BED\u3BEE\u3BEF\u3BF0\u3BF1"+ - "\u3BF2\u3BF3\u3BF4\u3BF5\u3BF6\u3BF7\u3BF8\u3BF9"+ - "\u3BFA\u3BFB\u3BFC\u3BFD\u3BFE\u3BFF\u3C00\u3C01"+ - "\u3C02\u3C03\u3C04\u3C05\u3C06\u3C07\u3C08\u3C09"+ - "\u3C0A\u3C0B\u3C0C\u3C0D\u3C0E\u3C0F\u3C10\u3C11"+ - "\u3C12\u3C13\u3C14\u3C15\u3C16\u3C17\u3C18\u3C19"+ - "\u3C1A\u3C1B\u3C1C\u3C1D\u3C1E\u3C1F\u3C20\u3C21"+ - "\u3C22\u3C23\u3C24\u3C25\u3C26\u3C27\u3C28\u3C29"+ - "\u3C2A\u3C2B\u3C2C\u3C2D\u3C2E\u3C2F\u3C30\u3C31"+ - "\u3C32\u3C33\u3C34\u3C35\u3C36\u3C37\u3C38\u3C39"+ - "\u3C3A\u3C3B\u3C3C\u3C3D\u3C3E\u3C3F\u3C40\u3C41"+ - "\u3C42\u3C43\u3C44\u3C45\u3C46\u3C47\u3C48\u3C49"+ - "\u3C4A\u3C4B\u3C4C\u3C4D\u3C4E\u3C4F\u3C50\u3C51"+ - "\u3C52\u3C53\u3C54\u3C55\u3C56\u3C57\u3C58\u3C59"+ - "\u3C5A\u3C5B\u3C5C\u3C5D\u3C5E\u3C5F\u3C60\u3C61"+ - "\u3C62\u3C63\u3C64\u3C65\u3C66\u3C67\u3C68\u3C69"+ - "\u3C6A\u3C6B\u3C6C\u3C6D\u3C6E\u3C6F\u3C70\u3C71"+ - "\u3C72\u3C73\u3C74\u3C75\u3C76\u3C77\u3C78\u3C79"+ - "\u3C7A\u3C7B\u3C7C\u3C7D\u3C7E\u3C7F\u3C80\u3C81"+ - "\u3C82\u3C83\u3C84\u3C85\u3C86\u3C87\u3C88\u3C89"+ - "\u3C8A\u3C8B\u3C8C\u3C8D\u3C8E\u3C8F\u3C90\u3C91"+ - "\u3C92\u3C93\u3C94\u3C95\u3C96\u3C97\u3C98\u3C99"+ - "\u3C9A\u3C9B\u3C9C\u3C9D\u3C9E\u3C9F\u3CA0\u3CA1"+ - "\u3CA2\u3CA3\u3CA4\u3CA5\u3CA6\u3CA7\u3CA8\u3CA9"+ - "\u3CAA\u3CAB\u3CAC\u3CAD\u3CAE\u3CAF\u3CB0\u3CB1"+ - "\u3CB2\u3CB3\u3CB4\u3CB5\u3CB6\u3CB7\u3CB8\u3CB9"+ - "\u3CBA\u3CBB\u3CBC\u3CBD\u3CBE\u3CBF\u3CC0\u3CC1"+ - "\u3CC2\u3CC3\u3CC4\u3CC5\u3CC6\u3CC7\u3CC8\u3CC9"+ - "\u3CCA\u3CCB\u3CCC\u3CCD\u3CCE\u3CCF\u3CD0\u3CD1"+ - "\u3CD2\u3CD3\u3CD4\u3CD5\u3CD6\u3CD7\u3CD8\u3CD9"+ - "\u3CDA\u3CDB\u3CDC\u3CDD\u3CDE\u3CDF\u3CE0\u3CE1"+ - "\u3CE2\u3CE3\u3CE4\u3CE5\u3CE6\u3CE7\u3CE8\u3CE9"+ - "\u3CEA\u3CEB\u3CEC\u3CED\u3CEE\u3CEF\u3CF0\u3CF1"+ - "\u3CF2\u3CF3\u3CF4\u3CF5\u3CF6\u3CF7\u3CF8\u3CF9"+ - "\u3CFA\u3CFB\u3CFC\u3CFD\u3CFE\u3CFF\u3D00\u3D01"+ - "\u3D02\u3D03\u3D04\u3D05\u3D06\u3D07\u3D08\u3D09"+ - "\u3D0A\u3D0B\u3D0C\u3D0D\u3D0E\u3D0F\u3D10\u3D11"+ - "\u3D12\u3D13\u3D14\u3D15\u3D16\u3D17\u3D18\u3D19"+ - "\u3D1A\u3D1B\u3D1C\u3D1D\u3D1E\u3D1F\u3D20\u3D21"+ - "\u3D22\u3D23\u3D24\u3D25\u3D26\u3D27\u3D28\u3D29"+ - "\u3D2A\u3D2B\u3D2C\u3D2D\u3D2E\u3D2F\u3D30\u3D31"+ - "\u3D32\u3D33\u3D34\u3D35\u3D36\u3D37\u3D38\u3D39"+ - "\u3D3A\u3D3B\u3D3C\u3D3D\u3D3E\u3D3F\u3D40\u3D41"+ - "\u3D42\u3D43\u3D44\u3D45\u3D46\u3D47\u3D48\u3D49"+ - "\u3D4A\u3D4B\u3D4C\u3D4D\u3D4E\u3D4F\u3D50\u3D51"+ - "\u3D52\u3D53\u3D54\u3D55\u3D56\u3D57\u3D58\u3D59"+ - "\u3D5A\u3D5B\u3D5C\u3D5D\u3D5E\u3D5F\u3D60\u3D61"+ - "\u3D62\u3D63\u3D64\u3D65\u3D66\u3D67\u3D68\u3D69"+ - "\u3D6A\u3D6B\u3D6C\u3D6D\u3D6E\u3D6F\u3D70\u3D71"+ - "\u3D72\u3D73\u3D74\u3D75\u3D76\u3D77\u3D78\u3D79"+ - "\u3D7A\u3D7B\u3D7C\u3D7D\u3D7E\u3D7F\u3D80\u3D81"+ - "\u3D82\u3D83\u3D84\u3D85\u3D86\u3D87\u3D88\u3D89"+ - "\u3D8A\u3D8B\u3D8C\u3D8D\u3D8E\u3D8F\u3D90\u3D91"+ - "\u3D92\u3D93\u3D94\u3D95\u3D96\u3D97\u3D98\u3D99"+ - "\u3D9A\u3D9B\u3D9C\u3D9D\u3D9E\u3D9F\u3DA0\u3DA1"+ - "\u3DA2\u3DA3\u3DA4\u3DA5\u3DA6\u3DA7\u3DA8\u3DA9"+ - "\u3DAA\u3DAB\u3DAC\u3DAD\u3DAE\u3DAF\u3DB0\u3DB1"+ - "\u3DB2\u3DB3\u3DB4\u3DB5\u3DB6\u3DB7\u3DB8\u3DB9"+ - "\u3DBA\u3DBB\u3DBC\u3DBD\u3DBE\u3DBF\u3DC0\u3DC1"+ - "\u3DC2\u3DC3\u3DC4\u3DC5\u3DC6\u3DC7\u3DC8\u3DC9"+ - "\u3DCA\u3DCB\u3DCC\u3DCD\u3DCE\u3DCF\u3DD0\u3DD1"+ - "\u3DD2\u3DD3\u3DD4\u3DD5\u3DD6\u3DD7\u3DD8\u3DD9"+ - "\u3DDA\u3DDB\u3DDC\u3DDD\u3DDE\u3DDF\u3DE0\u3DE1"+ - "\u3DE2\u3DE3\u3DE4\u3DE5\u3DE6\u3DE7\u3DE8\u3DE9"+ - "\u3DEA\u3DEB\u3DEC\u3DED\u3DEE\u3DEF\u3DF0\u3DF1"+ - "\u3DF2\u3DF3\u3DF4\u3DF5\u3DF6\u3DF7\u3DF8\u3DF9"+ - "\u3DFA\u3DFB\u3DFC\u3DFD\u3DFE\u3DFF\u3E00\u3E01"+ - "\u3E02\u3E03\u3E04\u3E05\u3E06\u3E07\u3E08\u3E09"+ - "\u3E0A\u3E0B\u3E0C\u3E0D\u3E0E\u3E0F\u3E10\u3E11"+ - "\u3E12\u3E13\u3E14\u3E15\u3E16\u3E17\u3E18\u3E19"+ - "\u3E1A\u3E1B\u3E1C\u3E1D\u3E1E\u3E1F\u3E20\u3E21"+ - "\u3E22\u3E23\u3E24\u3E25\u3E26\u3E27\u3E28\u3E29"+ - "\u3E2A\u3E2B\u3E2C\u3E2D\u3E2E\u3E2F\u3E30\u3E31"+ - "\u3E32\u3E33\u3E34\u3E35\u3E36\u3E37\u3E38\u3E39"+ - "\u3E3A\u3E3B\u3E3C\u3E3D\u3E3E\u3E3F\u3E40\u3E41"+ - "\u3E42\u3E43\u3E44\u3E45\u3E46\u3E47\u3E48\u3E49"+ - "\u3E4A\u3E4B\u3E4C\u3E4D\u3E4E\u3E4F\u3E50\u3E51"+ - "\u3E52\u3E53\u3E54\u3E55\u3E56\u3E57\u3E58\u3E59"+ - "\u3E5A\u3E5B\u3E5C\u3E5D\u3E5E\u3E5F\u3E60\u3E61"+ - "\u3E62\u3E63\u3E64\u3E65\u3E66\u3E67\u3E68\u3E69"+ - "\u3E6A\u3E6B\u3E6C\u3E6D\u3E6E\u3E6F\u3E70\u3E71"+ - "\u3E72\u3E73\u3E74\u3E75\u3E76\u3E77\u3E78\u3E79"+ - "\u3E7A\u3E7B\u3E7C\u3E7D\u3E7E\u3E7F\u3E80\u3E81"+ - "\u3E82\u3E83\u3E84\u3E85\u3E86\u3E87\u3E88\u3E89"+ - "\u3E8A\u3E8B\u3E8C\u3E8D\u3E8E\u3E8F\u3E90\u3E91"+ - "\u3E92\u3E93\u3E94\u3E95\u3E96\u3E97\u3E98\u3E99"+ - "\u3E9A\u3E9B\u3E9C\u3E9D\u3E9E\u3E9F\u3EA0\u3EA1"+ - "\u3EA2\u3EA3\u3EA4\u3EA5\u3EA6\u3EA7\u3EA8\u3EA9"+ - "\u3EAA\u3EAB\u3EAC\u3EAD\u3EAE\u3EAF\u3EB0\u3EB1"+ - "\u3EB2\u3EB3\u3EB4\u3EB5\u3EB6\u3EB7\u3EB8\u3EB9"+ - "\u3EBA\u3EBB\u3EBC\u3EBD\u3EBE\u3EBF\u3EC0\u3EC1"+ - "\u3EC2\u3EC3\u3EC4\u3EC5\u3EC6\u3EC7\u3EC8\u3EC9"+ - "\u3ECA\u3ECB\u3ECC\u3ECD\u3ECE\u3ECF\u3ED0\u3ED1"+ - "\u3ED2\u3ED3\u3ED4\u3ED5\u3ED6\u3ED7\u3ED8\u3ED9"+ - "\u3EDA\u3EDB\u3EDC\u3EDD\u3EDE\u3EDF\u3EE0\u3EE1"; - - private static final String innerEncoderIndex2= - "\u3EE2\u3EE3\u3EE4\u3EE5\u3EE6\u3EE7\u3EE8\u3EE9"+ - "\u3EEA\u3EEB\u3EEC\u3EED\u3EEE\u3EEF\u3EF0\u3EF1"+ - "\uA95C\u3EF2\u3EF3\uA843\uA1AA\uA844\uA1AC\u3EF4"+ - "\uA1AE\uA1AF\u3EF5\u3EF6\uA1B0\uA1B1\u3EF7\u3EF8"+ - "\u3EF9\u3EFA\u3EFB\u3EFC\u3EFD\uA845\uA1AD\u3EFE"+ - "\u3EFF\u3F00\u3F01\u3F02\u3F03\u3F04\u3F05\u3F06"+ - "\uA1EB\u3F07\uA1E4\uA1E5\u3F08\uA846\u3F09\u3F0A"+ - "\u3F0B\u3F0C\u3F0D\uA1F9\u3F0E\u3F0F\u3F10\u3F11"+ - "\u3F12\u3F13\u3F14\u3F15\u3F16\u3F17\u3F18\u3F19"+ - "\u3F1A\u3F1B\u3F1C\u3F1D\u3F1E\u3F1F\u3F20\u3F21"+ - "\u3F22\u3F23\u3F24\u3F25\u3F26\u3F27\u3F28\u3F29"+ - "\u3F2A\u3F2B\u3F2C\u3F2D\u3F2E\u3F2F\u3F30\u3F31"+ - "\u3F32\u3F33\u3F34\u3F35\u3F36\u3F37\u3F38\u3F39"+ - "\u3F3A\u3F3B\u3F3C\u3F3D\u3F3E\u3F3F\u3F40\u3F41"+ - "\u3F42\u3F43\u3F44\u3F45\u3F46\u3F47\u3F48\u3F49"+ - "\u3F4A\u3F4B\u3F4C\u3F4D\u3F4E\u3F4F\u3F50\u3F51"+ - "\u3F52\u3F53\u3F54\u3F55\u3F56\u3F57\u3F58\u3F59"+ - "\u3F5A\u3F5B\u3F5C\u3F5D\u3F5E\u3F5F\u3F60\u3F61"+ - "\u3F62\u3F63\u3F64\u3F65\u3F66\u3F67\u3F68\u3F69"+ - "\u3F6A\u3F6B\u3F6C\u3F6D\u3F6E\u3F6F\u3F70\u3F71"+ - "\u3F72\u3F73\u3F74\u3F75\u3F76\u3F77\u3F78\u3F79"+ - "\u3F7A\u3F7B\u3F7C\u3F7D\uA2E3\u3F7E\u3F7F\u3F80"+ - "\u3F81\u3F82\u3F83\u3F84\u3F85\u3F86\u3F87\u3F88"+ - "\u3F89\u3F8A\u3F8B\u3F8C\u3F8D\u3F8E\u3F8F\u3F90"+ - "\u3F91\u3F92\u3F93\u3F94\u3F95\u3F96\u3F97\u3F98"+ - "\u3F99\u3F9A\u3F9B\u3F9C\u3F9D\u3F9E\u3F9F\u3FA0"+ - "\u3FA1\u3FA2\u3FA3\u3FA4\u3FA5\u3FA6\u3FA7\u3FA8"+ - "\u3FA9\u3FAA\u3FAB\u3FAC\u3FAD\u3FAE\u3FAF\u3FB0"+ - "\u3FB1\u3FB2\u3FB3\u3FB4\u3FB5\u3FB6\u3FB7\u3FB8"+ - "\u3FB9\u3FBA\u3FBB\u3FBC\u3FBD\u3FBE\u3FBF\u3FC0"+ - "\u3FC1\u3FC2\u3FC3\u3FC4\u3FC5\u3FC6\u3FC7\u3FC8"+ - "\u3FC9\u3FCA\u3FCB\u3FCC\u3FCD\u3FCE\u3FCF\u3FD0"+ - "\u3FD1\u3FD2\u3FD3\uA1E6\u3FD4\uA847\u3FD5\u3FD6"+ - "\u3FD7\uA848\u3FD8\u3FD9\u3FDA\u3FDB\u3FDC\u3FDD"+ - "\u3FDE\u3FDF\u3FE0\u3FE1\u3FE2\u3FE3\uA1ED\u3FE4"+ - "\u3FE5\u3FE6\u3FE7\u3FE8\u3FE9\u3FEA\u3FEB\u3FEC"+ - "\u3FED\uA959\u3FEE\u3FEF\u3FF0\u3FF1\u3FF2\u3FF3"+ - "\u3FF4\u3FF5\u3FF6\u3FF7\u3FF8\u3FF9\u3FFA\u3FFB"+ - "\u3FFC\u3FFD\u3FFE\u3FFF\u4000\u4001\u4002\u4003"+ - "\u4004\u4005\u4006\u4007\u4008\u4009\u400A\u400B"+ - "\u400C\u400D\u400E\u400F\u4010\u4011\u4012\u4013"+ - "\u4014\u4015\u4016\u4017\u4018\u4019\u401A\u401B"+ - "\u401C\u401D\u401E\u401F\u4020\u4021\u4022\u4023"+ - "\u4024\u4025\u4026\u4027\u4028\u4029\u402A\u402B"+ - "\uA2F1\uA2F2\uA2F3\uA2F4\uA2F5\uA2F6\uA2F7\uA2F8"+ - "\uA2F9\uA2FA\uA2FB\uA2FC\u402C\u402D\u402E\u402F"+ - "\uA2A1\uA2A2\uA2A3\uA2A4\uA2A5\uA2A6\uA2A7\uA2A8"+ - "\uA2A9\uA2AA\u4030\u4031\u4032\u4033\u4034\u4035"+ - "\u4036\u4037\u4038\u4039\u403A\u403B\u403C\u403D"+ - "\u403E\u403F\u4040\u4041\u4042\u4043\u4044\u4045"+ - "\uA1FB\uA1FC\uA1FA\uA1FD\u4046\u4047\uA849\uA84A"+ - "\uA84B\uA84C\u4048\u4049\u404A\u404B\u404C\u404D"+ - "\u404E\u404F\u4050\u4051\u4052\u4053\u4054\u4055"+ - "\u4056\u4057\u4058\u4059\u405A\u405B\u405C\u405D"+ - "\u405E\u405F\u4060\u4061\u4062\u4063\u4064\u4065"+ - "\u4066\u4067\u4068\u4069\u406A\u406B\u406C\u406D"+ - "\u406E\u406F\u4070\u4071\u4072\u4073\u4074\u4075"+ - "\u4076\u4077\u4078\u4079\u407A\u407B\u407C\u407D"+ - "\u407E\u407F\u4080\u4081\u4082\u4083\u4084\u4085"+ - "\u4086\u4087\u4088\u4089\u408A\u408B\u408C\u408D"+ - "\u408E\u408F\u4090\u4091\u4092\u4093\u4094\u4095"+ - "\u4096\u4097\u4098\u4099\u409A\u409B\u409C\u409D"+ - "\u409E\u409F\u40A0\u40A1\u40A2\u40A3\u40A4\u40A5"+ - "\u40A6\u40A7\u40A8\u40A9\u40AA\u40AB\u40AC\u40AD"+ - "\u40AE\u40AF\u40B0\u40B1\u40B2\u40B3\u40B4\u40B5"+ - "\uA1CA\u40B6\u40B7\u40B8\u40B9\u40BA\u40BB\uA1C7"+ - "\u40BC\uA1C6\u40BD\u40BE\u40BF\uA84D\u40C0\u40C1"+ - "\u40C2\u40C3\uA1CC\u40C4\u40C5\uA1D8\uA1DE\uA84E"+ - "\uA1CF\u40C6\u40C7\uA84F\u40C8\uA1CE\u40C9\uA1C4"+ - "\uA1C5\uA1C9\uA1C8\uA1D2\u40CA\u40CB\uA1D3\u40CC"+ - "\u40CD\u40CE\u40CF\u40D0\uA1E0\uA1DF\uA1C3\uA1CB"+ - "\u40D1\u40D2\u40D3\u40D4\u40D5\uA1D7\u40D6\u40D7"+ - "\u40D8\u40D9\u40DA\u40DB\u40DC\u40DD\u40DE\u40DF"+ - "\uA1D6\u40E0\u40E1\u40E2\uA1D5\u40E3\u40E4\u40E5"+ - "\u40E6\u40E7\uA850\u40E8\u40E9\u40EA\u40EB\u40EC"+ - "\u40ED\u40EE\u40EF\u40F0\u40F1\u40F2\u40F3\u40F4"+ - "\uA1D9\uA1D4\u40F5\u40F6\uA1DC\uA1DD\uA851\uA852"+ - "\u40F7\u40F8\u40F9\u40FA\u40FB\u40FC\uA1DA\uA1DB"+ - "\u40FD\u40FE\u40FF\u4100\u4101\u4102\u4103\u4104"+ - "\u4105\u4106\u4107\u4108\u4109\u410A\u410B\u410C"+ - "\u410D\u410E\u410F\u4110\u4111\u4112\u4113\u4114"+ - "\u4115\u4116\u4117\u4118\u4119\u411A\u411B\u411C"+ - "\u411D\u411E\u411F\u4120\u4121\uA892\u4122\u4123"+ - "\u4124\uA1D1\u4125\u4126\u4127\u4128\u4129\u412A"+ - "\u412B\u412C\u412D\u412E\u412F\uA1CD\u4130\u4131"+ - "\u4132\u4133\u4134\u4135\u4136\u4137\u4138\u4139"+ - "\u413A\u413B\u413C\u413D\u413E\u413F\u4140\u4141"+ - "\u4142\u4143\u4144\u4145\u4146\u4147\u4148\uA853"+ - "\u4149\u414A\u414B\u414C\u414D\u414E\u414F\u4150"+ - "\u4151\u4152\u4153\u4154\u4155\u4156\u4157\u4158"+ - "\u4159\u415A\u415B\u415C\u415D\u415E\u415F\u4160"+ - "\u4161\u4162\u4163\u4164\u4165\u4166\u4167\u4168"+ - "\u4169\u416A\u416B\u416C\u416D\u416E\u416F\u4170"+ - "\u4171\u4172\u4173\u4174\u4175\u4176\u4177\u4178"+ - "\u4179\u417A\u417B\u417C\u417D\u417E\u417F\u4180"+ - "\u4181\u4182\u4183\u4184\u4185\u4186\u4187\u4188"+ - "\u4189\u418A\u418B\u418C\u418D\u418E\u418F\u4190"+ - "\u4191\u4192\u4193\u4194\u4195\u4196\u4197\u4198"+ - "\u4199\u419A\uA1D0\u419B\u419C\u419D\u419E\u419F"+ - "\u41A0\u41A1\u41A2\u41A3\u41A4\u41A5\u41A6\u41A7"+ - "\u41A8\u41A9\u41AA\u41AB\u41AC\u41AD\u41AE\u41AF"+ - "\u41B0\u41B1\u41B2\u41B3\u41B4\u41B5\u41B6\u41B7"+ - "\u41B8\u41B9\u41BA\u41BB\u41BC\u41BD\u41BE\u41BF"+ - "\u41C0\u41C1\u41C2\u41C3\u41C4\u41C5\u41C6\u41C7"+ - "\u41C8\u41C9\u41CA\u41CB\u41CC\u41CD\u41CE\u41CF"+ - "\u41D0\u41D1\u41D2\u41D3\u41D4\u41D5\u41D6\u41D7"+ - "\u41D8\u41D9\u41DA\u41DB\u41DC\u41DD\u41DE\u41DF"+ - "\u41E0\u41E1\u41E2\u41E3\u41E4\u41E5\u41E6\u41E7"+ - "\u41E8\u41E9\u41EA\u41EB\u41EC\u41ED\u41EE\u41EF"+ - "\u41F0\u41F1\u41F2\u41F3\u41F4\u41F5\u41F6\u41F7"+ - "\u41F8\u41F9\u41FA\u41FB\u41FC\u41FD\u41FE\u41FF"+ - "\u4200\u4201\u4202\u4203\u4204\u4205\u4206\u4207"+ - "\u4208\u4209\u420A\u420B\u420C\u420D\u420E\u420F"+ - "\u4210\u4211\u4212\u4213\u4214\u4215\u4216\u4217"+ - "\u4218\u4219\u421A\u421B\u421C\u421D\u421E\u421F"+ - "\u4220\u4221\u4222\u4223\u4224\u4225\u4226\u4227"+ - "\u4228\u4229\u422A\u422B\u422C\u422D\u422E\u422F"+ - "\u4230\u4231\u4232\u4233\u4234\u4235\u4236\u4237"+ - "\u4238\u4239\u423A\u423B\u423C\u423D\u423E\u423F"+ - "\u4240\u4241\u4242\u4243\u4244\u4245\u4246\u4247"+ - "\u4248\u4249\u424A\u424B\u424C\u424D\u424E\u424F"+ - "\u4250\u4251\u4252\u4253\u4254\u4255\u4256\u4257"+ - "\u4258\u4259\u425A\u425B\u425C\u425D\u425E\u425F"+ - "\u4260\u4261\u4262\u4263\u4264\u4265\u4266\u4267"+ - "\u4268\u4269\u426A\u426B\u426C\u426D\u426E\u426F"+ - "\u4270\u4271\u4272\u4273\u4274\u4275\u4276\u4277"+ - "\u4278\u4279\u427A\u427B\u427C\u427D\u427E\u427F"+ - "\u4280\u4281\u4282\u4283\u4284\u4285\u4286\u4287"+ - "\u4288\u4289\u428A\u428B\u428C\u428D\u428E\u428F"+ - "\u4290\u4291\u4292\u4293\u4294\u4295\u4296\u4297"+ - "\u4298\u4299\u429A\u429B\u429C\u429D\u429E\u429F"+ - "\u42A0\u42A1\u42A2\u42A3\u42A4\u42A5\u42A6\u42A7"+ - "\u42A8\u42A9\u42AA\u42AB\u42AC\u42AD\u42AE\u42AF"+ - "\u42B0\u42B1\u42B2\u42B3\u42B4\u42B5\u42B6\u42B7"+ - "\u42B8\u42B9\u42BA\u42BB\u42BC\u42BD\u42BE\u42BF"+ - "\u42C0\u42C1\u42C2\u42C3\u42C4\u42C5\u42C6\u42C7"+ - "\u42C8\u42C9\u42CA\u42CB\u42CC\u42CD\u42CE\u42CF"+ - "\u42D0\u42D1\u42D2\u42D3\u42D4\u42D5\u42D6\u42D7"+ - "\u42D8\u42D9\u42DA\u42DB\u42DC\u42DD\u42DE\u42DF"+ - "\u42E0\u42E1\u42E2\u42E3\u42E4\u42E5\u42E6\u42E7"+ - "\uA2D9\uA2DA\uA2DB\uA2DC\uA2DD\uA2DE\uA2DF\uA2E0"+ - "\uA2E1\uA2E2\u42E8\u42E9\u42EA\u42EB\u42EC\u42ED"+ - "\u42EE\u42EF\u42F0\u42F1\uA2C5\uA2C6\uA2C7\uA2C8"+ - "\uA2C9\uA2CA\uA2CB\uA2CC\uA2CD\uA2CE\uA2CF\uA2D0"+ - "\uA2D1\uA2D2\uA2D3\uA2D4\uA2D5\uA2D6\uA2D7\uA2D8"+ - "\uA2B1\uA2B2\uA2B3\uA2B4\uA2B5\uA2B6\uA2B7\uA2B8"+ - "\uA2B9\uA2BA\uA2BB\uA2BC\uA2BD\uA2BE\uA2BF\uA2C0"+ - "\uA2C1\uA2C2\uA2C3\uA2C4\u42F2\u42F3\u42F4\u42F5"+ - "\u42F6\u42F7\u42F8\u42F9\u42FA\u42FB\u42FC\u42FD"+ - "\u42FE\u42FF\u4300\u4301\u4302\u4303\u4304\u4305"+ - "\u4306\u4307\u4308\u4309\u430A\u430B\u430C\u430D"+ - "\u430E\u430F\u4310\u4311\u4312\u4313\u4314\u4315"+ - "\u4316\u4317\u4318\u4319\u431A\u431B\u431C\u431D"+ - "\u431E\u431F\u4320\u4321\u4322\u4323\u4324\u4325"+ - "\u4326\u4327\u4328\u4329\u432A\u432B\u432C\u432D"+ - "\u432E\u432F\u4330\u4331\u4332\u4333\u4334\u4335"+ - "\u4336\u4337\u4338\u4339\u433A\u433B\u433C\u433D"+ - "\u433E\u433F\u4340\u4341\u4342\u4343\u4344\u4345"+ - "\u4346\u4347\u4348\u4349\u434A\u434B\u434C\u434D"+ - "\u434E\u434F\u4350\u4351\u4352\u4353\u4354\u4355"+ - "\uA9A4\uA9A5\uA9A6\uA9A7\uA9A8\uA9A9\uA9AA\uA9AB"+ - "\uA9AC\uA9AD\uA9AE\uA9AF\uA9B0\uA9B1\uA9B2\uA9B3"+ - "\uA9B4\uA9B5\uA9B6\uA9B7\uA9B8\uA9B9\uA9BA\uA9BB"+ - "\uA9BC\uA9BD\uA9BE\uA9BF\uA9C0\uA9C1\uA9C2\uA9C3"+ - "\uA9C4\uA9C5\uA9C6\uA9C7\uA9C8\uA9C9\uA9CA\uA9CB"+ - "\uA9CC\uA9CD\uA9CE\uA9CF\uA9D0\uA9D1\uA9D2\uA9D3"+ - "\uA9D4\uA9D5\uA9D6\uA9D7\uA9D8\uA9D9\uA9DA\uA9DB"+ - "\uA9DC\uA9DD\uA9DE\uA9DF\uA9E0\uA9E1\uA9E2\uA9E3"+ - "\uA9E4\uA9E5\uA9E6\uA9E7\uA9E8\uA9E9\uA9EA\uA9EB"+ - "\uA9EC\uA9ED\uA9EE\uA9EF\u4356\u4357\u4358\u4359"+ - "\uA854\uA855\uA856\uA857\uA858\uA859\uA85A\uA85B"+ - "\uA85C\uA85D\uA85E\uA85F\uA860\uA861\uA862\uA863"+ - "\uA864\uA865\uA866\uA867\uA868\uA869\uA86A\uA86B"+ - "\uA86C\uA86D\uA86E\uA86F\uA870\uA871\uA872\uA873"+ - "\uA874\uA875\uA876\uA877\u435A\u435B\u435C\u435D"+ - "\u435E\u435F\u4360\u4361\u4362\u4363\u4364\u4365"+ - "\u4366\uA878\uA879\uA87A\uA87B\uA87C\uA87D\uA87E"+ - "\uA880\uA881\uA882\uA883\uA884\uA885\uA886\uA887"+ - "\u4367\u4368\u4369\uA888\uA889\uA88A\u436A\u436B"+ - "\u436C\u436D\u436E\u436F\u4370\u4371\u4372\u4373"+ - "\uA1F6\uA1F5\u4374\u4375\u4376\u4377\u4378\u4379"+ - "\u437A\u437B\u437C\u437D\u437E\u437F\u4380\u4381"+ - "\u4382\u4383\uA1F8\uA1F7\u4384\u4385\u4386\u4387"+ - "\u4388\u4389\u438A\u438B\uA88B\uA88C\u438C\u438D"+ - "\u438E\u438F\u4390\u4391\u4392\u4393\uA1F4\uA1F3"+ - "\u4394\u4395\u4396\uA1F0\u4397\u4398\uA1F2\uA1F1"+ - "\u4399\u439A\u439B\u439C\u439D\u439E\u439F\u43A0"+ - "\u43A1\u43A2\u43A3\u43A4\u43A5\u43A6\u43A7\u43A8"+ - "\u43A9\u43AA\uA88D\uA88E\uA88F\uA890\u43AB\u43AC"+ - "\u43AD\u43AE\u43AF\u43B0\u43B1\u43B2\u43B3\u43B4"+ - "\u43B5\u43B6\u43B7\u43B8\u43B9\u43BA\u43BB\u43BC"+ - "\u43BD\u43BE\u43BF\u43C0\u43C1\u43C2\u43C3\u43C4"+ - "\u43C5\u43C6\u43C7\u43C8\u43C9\uA1EF\uA1EE\u43CA"+ - "\u43CB\uA891\u43CC\u43CD\u43CE\u43CF\u43D0\u43D1"+ - "\u43D2\u43D3\u43D4\u43D5\u43D6\u43D7\u43D8\u43D9"+ - "\u43DA\u43DB\u43DC\u43DD\u43DE\u43DF\u43E0\u43E1"+ - "\u43E2\u43E3\u43E4\u43E5\u43E6\u43E7\u43E8\u43E9"+ - "\u43EA\u43EB\u43EC\u43ED\u43EE\u43EF\u43F0\u43F1"+ - "\u43F2\u43F3\u43F4\u43F5\u43F6\u43F7\u43F8\u43F9"+ - "\u43FA\u43FB\u43FC\u43FD\u43FE\u43FF\u4400\u4401"+ - "\uA1E2\u4402\uA1E1\u4403\u4404\u4405\u4406\u4407"+ - "\u4408\u4409\u440A\u440B\u440C\u440D\u440E\u440F"+ - "\u4410\u4411\u4412\u4413\u4414\u4415\u4416\u4417"+ - "\u4418\u4419\u441A\u441B\u441C\u441D\u441E\u441F"+ - "\u4420\u4421\u4422\u4423\u4424\u4425\u4426\u4427"+ - "\u4428\u4429\u442A\u442B\u442C\u442D\u442E\u442F"+ - "\u4430\u4431\u4432\u4433\u4434\u4435\u4436\u4437"+ - "\u4438\u4439\u443A\u443B\u443C\u443D\u443E\u443F"+ - "\u4440\u4441\u4442\u4443\u4444\u4445\u4446\u4447"+ - "\u4448\u4449\u444A\u444B\u444C\u444D\u444E\u444F"+ - "\u4450\u4451\u4452\u4453\u4454\u4455\u4456\u4457"+ - "\u4458\u4459\u445A\u445B\u445C\u445D\u445E\u445F"+ - "\u4460\u4461\u4462\u4463\u4464\u4465\u4466\u4467"+ - "\u4468\u4469\u446A\u446B\u446C\u446D\u446E\u446F"+ - "\u4470\u4471\u4472\u4473\u4474\u4475\u4476\u4477"+ - "\u4478\u4479\u447A\u447B\u447C\u447D\u447E\u447F"+ - "\u4480\u4481\u4482\u4483\u4484\u4485\u4486\u4487"+ - "\u4488\u4489\u448A\u448B\u448C\u448D\u448E\u448F"+ - "\u4490\u4491\u4492\u4493\u4494\u4495\u4496\u4497"+ - "\u4498\u4499\u449A\u449B\u449C\u449D\u449E\u449F"+ - "\u44A0\u44A1\u44A2\u44A3\u44A4\u44A5\u44A6\u44A7"+ - "\u44A8\u44A9\u44AA\u44AB\u44AC\u44AD\u44AE\u44AF"+ - "\u44B0\u44B1\u44B2\u44B3\u44B4\u44B5\u44B6\u44B7"+ - "\u44B8\u44B9\u44BA\u44BB\u44BC\u44BD\u44BE\u44BF"+ - "\u44C0\u44C1\u44C2\u44C3\u44C4\u44C5\u44C6\u44C7"+ - "\u44C8\u44C9\u44CA\u44CB\u44CC\u44CD\u44CE\u44CF"+ - "\u44D0\u44D1\u44D2\u44D3\u44D4\u44D5\u44D6\u44D7"+ - "\u44D8\u44D9\u44DA\u44DB\u44DC\u44DD\u44DE\u44DF"+ - "\u44E0\u44E1\u44E2\u44E3\u44E4\u44E5\u44E6\u44E7"+ - "\u44E8\u44E9\u44EA\u44EB\u44EC\u44ED\u44EE\u44EF"+ - "\u44F0\u44F1\u44F2\u44F3\u44F4\u44F5\u44F6\u44F7"+ - "\u44F8\u44F9\u44FA\u44FB\u44FC\u44FD\u44FE\u44FF"+ - "\u4500\u4501\u4502\u4503\u4504\u4505\u4506\u4507"+ - "\u4508\u4509\u450A\u450B\u450C\u450D\u450E\u450F"+ - "\u4510\u4511\u4512\u4513\u4514\u4515\u4516\u4517"+ - "\u4518\u4519\u451A\u451B\u451C\u451D\u451E\u451F"+ - "\u4520\u4521\u4522\u4523\u4524\u4525\u4526\u4527"+ - "\u4528\u4529\u452A\u452B\u452C\u452D\u452E\u452F"+ - "\u4530\u4531\u4532\u4533\u4534\u4535\u4536\u4537"+ - "\u4538\u4539\u453A\u453B\u453C\u453D\u453E\u453F"+ - "\u4540\u4541\u4542\u4543\u4544\u4545\u4546\u4547"+ - "\u4548\u4549\u454A\u454B\u454C\u454D\u454E\u454F"+ - "\u4550\u4551\u4552\u4553\u4554\u4555\u4556\u4557"+ - "\u4558\u4559\u455A\u455B\u455C\u455D\u455E\u455F"+ - "\u4560\u4561\u4562\u4563\u4564\u4565\u4566\u4567"+ - "\u4568\u4569\u456A\u456B\u456C\u456D\u456E\u456F"+ - "\u4570\u4571\u4572\u4573\u4574\u4575\u4576\u4577"+ - "\u4578\u4579\u457A\u457B\u457C\u457D\u457E\u457F"+ - "\u4580\u4581\u4582\u4583\u4584\u4585\u4586\u4587"+ - "\u4588\u4589\u458A\u458B\u458C\u458D\u458E\u458F"+ - "\u4590\u4591\u4592\u4593\u4594\u4595\u4596\u4597"+ - "\u4598\u4599\u459A\u459B\u459C\u459D\u459E\u459F"+ - "\u45A0\u45A1\u45A2\u45A3\u45A4\u45A5\u45A6\u45A7"+ - "\u45A8\u45A9\u45AA\u45AB\u45AC\u45AD\u45AE\u45AF"+ - "\u45B0\u45B1\u45B2\u45B3\u45B4\u45B5\u45B6\u45B7"+ - "\u45B8\u45B9\u45BA\u45BB\u45BC\u45BD\u45BE\u45BF"+ - "\u45C0\u45C1\u45C2\u45C3\u45C4\u45C5\u45C6\u45C7"+ - "\u45C8\u45C9\u45CA\u45CB\u45CC\u45CD\u45CE\u45CF"+ - "\u45D0\u45D1\u45D2\u45D3\u45D4\u45D5\u45D6\u45D7"+ - "\u45D8\u45D9\u45DA\u45DB\u45DC\u45DD\u45DE\u45DF"+ - "\u45E0\u45E1\u45E2\u45E3\u45E4\u45E5\u45E6\u45E7"+ - "\u45E8\u45E9\u45EA\u45EB\u45EC\u45ED\u45EE\u45EF"+ - "\u45F0\u45F1\u45F2\u45F3\u45F4\u45F5\u45F6\u45F7"+ - "\u45F8\u45F9\u45FA\u45FB\u45FC\u45FD\u45FE\u45FF"+ - "\u4600\u4601\u4602\u4603\u4604\u4605\u4606\u4607"+ - "\u4608\u4609\u460A\u460B\u460C\u460D\u460E\u460F"+ - "\u4610\u4611\u4612\u4613\u4614\u4615\u4616\u4617"+ - "\u4618\u4619\u461A\u461B\u461C\u461D\u461E\u461F"+ - "\u4620\u4621\u4622\u4623\u4624\u4625\u4626\u4627"+ - "\u4628\u4629\u462A\u462B\u462C\u462D\u462E\u462F"+ - "\u4630\u4631\u4632\u4633\u4634\u4635\u4636\u4637"+ - "\u4638\u4639\u463A\u463B\u463C\u463D\u463E\u463F"+ - "\u4640\u4641\u4642\u4643\u4644\u4645\u4646\u4647"+ - "\u4648\u4649\u464A\u464B\u464C\u464D\u464E\u464F"+ - "\u4650\u4651\u4652\u4653\u4654\u4655\u4656\u4657"+ - "\u4658\u4659\u465A\u465B\u465C\u465D\u465E\u465F"+ - "\u4660\u4661\u4662\u4663\u4664\u4665\u4666\u4667"+ - "\u4668\u4669\u466A\u466B\u466C\u466D\u466E\u466F"+ - "\u4670\u4671\u4672\u4673\u4674\u4675\u4676\u4677"+ - "\u4678\u4679\u467A\u467B\u467C\u467D\u467E\u467F"+ - "\u4680\u4681\u4682\u4683\u4684\u4685\u4686\u4687"+ - "\u4688\u4689\u468A\u468B\u468C\u468D\u468E\u468F"+ - "\u4690\u4691\u4692\u4693\u4694\u4695\u4696\u4697"+ - "\u4698\u4699\u469A\u469B\u469C\u469D\u469E\u469F"+ - "\u46A0\u46A1\u46A2\u46A3\u46A4\u46A5\u46A6\u46A7"+ - "\u46A8\u46A9\u46AA\u46AB\u46AC\u46AD\u46AE\u46AF"+ - "\u46B0\u46B1\u46B2\u46B3\u46B4\u46B5\u46B6\u46B7"+ - "\u46B8\u46B9\u46BA\u46BB\u46BC\u46BD\u46BE\u46BF"+ - "\u46C0\u46C1\u46C2\u46C3\u46C4\u46C5\u46C6\u46C7"+ - "\u46C8\u46C9\u46CA\u46CB\u46CC\u46CD\u46CE\u46CF"+ - "\u46D0\u46D1\u46D2\u46D3\u46D4\u46D5\u46D6\u46D7"+ - "\u46D8\u46D9\u46DA\u46DB\u46DC\u46DD\u46DE\u46DF"+ - "\u46E0\u46E1\u46E2\u46E3\u46E4\u46E5\u46E6\u46E7"+ - "\u46E8\u46E9\u46EA\u46EB\u46EC\u46ED\u46EE\u46EF"+ - "\u46F0\u46F1\u46F2\u46F3\u46F4\u46F5\u46F6\u46F7"+ - "\u46F8\u46F9\u46FA\u46FB\u46FC\u46FD\u46FE\u46FF"+ - "\u4700\u4701\u4702\u4703\u4704\u4705\u4706\u4707"+ - "\u4708\u4709\u470A\u470B\u470C\u470D\u470E\u470F"+ - "\u4710\u4711\u4712\u4713\u4714\u4715\u4716\u4717"+ - "\u4718\u4719\u471A\u471B\u471C\u471D\u471E\u471F"+ - "\u4720\u4721\u4722\u4723\u4724\u4725\u4726\u4727"+ - "\u4728\u4729\u472A\u472B\u472C\u472D\u472E\u472F"+ - "\u4730\u4731\u4732\u4733\u4734\u4735\u4736\u4737"+ - "\u4738\u4739\u473A\u473B\u473C\u473D\u473E\u473F"+ - "\u4740\u4741\u4742\u4743\u4744\u4745\u4746\u4747"+ - "\u4748\u4749\u474A\u474B\u474C\u474D\u474E\u474F"+ - "\u4750\u4751\u4752\u4753\u4754\u4755\u4756\u4757"+ - "\u4758\u4759\u475A\u475B\u475C\u475D\u475E\u475F"+ - "\u4760\u4761\u4762\u4763\u4764\u4765\u4766\u4767"+ - "\u4768\u4769\u476A\u476B\u476C\u476D\u476E\u476F"+ - "\u4770\u4771\u4772\u4773\u4774\u4775\u4776\u4777"+ - "\u4778\u4779\u477A\u477B\u477C\u477D\u477E\u477F"+ - "\u4780\u4781\u4782\u4783\u4784\u4785\u4786\u4787"+ - "\u4788\u4789\u478A\u478B\u478C\u478D\u478E\u478F"+ - "\u4790\u4791\u4792\u4793\u4794\u4795\u4796\u4797"+ - "\u4798\u4799\u479A\u479B\u479C\u479D\u479E\u479F"+ - "\u47A0\u47A1\u47A2\u47A3\u47A4\u47A5\u47A6\u47A7"+ - "\u47A8\u47A9\u47AA\u47AB\u47AC\u47AD\u47AE\u47AF"+ - "\u47B0\u47B1\u47B2\u47B3\u47B4\u47B5\u47B6\u47B7"+ - "\u47B8\u47B9\u47BA\u47BB\u47BC\u47BD\u47BE\u47BF"+ - "\u47C0\u47C1\u47C2\u47C3\u47C4\u47C5\u47C6\u47C7"+ - "\u47C8\u47C9\u47CA\u47CB\u47CC\u47CD\u47CE\u47CF"+ - "\u47D0\u47D1\u47D2\u47D3\u47D4\u47D5\u47D6\u47D7"+ - "\u47D8\u47D9\u47DA\u47DB\u47DC\u47DD\u47DE\u47DF"+ - "\u47E0\u47E1\u47E2\u47E3\u47E4\u47E5\u47E6\u47E7"+ - "\u47E8\u47E9\u47EA\u47EB\u47EC\u47ED\u47EE\u47EF"+ - "\u47F0\u47F1\u47F2\u47F3\u47F4\u47F5\u47F6\u47F7"+ - "\u47F8\u47F9\u47FA\u47FB\u47FC\u47FD\u47FE\u47FF"+ - "\u4800\u4801\u4802\u4803\u4804\u4805\u4806\u4807"+ - "\u4808\u4809\u480A\u480B\u480C\u480D\u480E\u480F"+ - "\u4810\u4811\u4812\u4813\u4814\u4815\u4816\u4817"+ - "\u4818\u4819\u481A\u481B\u481C\u481D\u481E\u481F"+ - "\u4820\u4821\u4822\u4823\u4824\u4825\u4826\u4827"+ - "\u4828\u4829\u482A\u482B\u482C\u482D\u482E\u482F"+ - "\u4830\u4831\u4832\u4833\u4834\u4835\u4836\u4837"+ - "\u4838\u4839\u483A\u483B\u483C\u483D\u483E\u483F"+ - "\u4840\u4841\u4842\u4843\u4844\u4845\u4846\u4847"+ - "\u4848\u4849\u484A\u484B\u484C\u484D\u484E\u484F"+ - "\u4850\u4851\u4852\u4853\u4854\u4855\u4856\u4857"+ - "\u4858\u4859\u485A\u485B\u485C\u485D\u485E\u485F"+ - "\u4860\u4861\u4862\u4863\u4864\u4865\u4866\u4867"+ - "\u4868\u4869\u486A\u486B\u486C\u486D\u486E\u486F"+ - "\u4870\u4871\u4872\u4873\u4874\u4875\u4876\u4877"+ - "\u4878\u4879\u487A\u487B\u487C\u487D\u487E\u487F"+ - "\u4880\u4881\u4882\u4883\u4884\u4885\u4886\u4887"+ - "\u4888\u4889\u488A\u488B\u488C\u488D\u488E\u488F"+ - "\u4890\u4891\u4892\u4893\u4894\u4895\u4896\u4897"+ - "\u4898\u4899\u489A\u489B\u489C\u489D\u489E\u489F"+ - "\u48A0\u48A1\u48A2\u48A3\u48A4\u48A5\u48A6\u48A7"+ - "\u48A8\u48A9\u48AA\u48AB\u48AC\u48AD\u48AE\u48AF"+ - "\u48B0\u48B1\u48B2\u48B3\u48B4\u48B5\u48B6\u48B7"+ - "\u48B8\u48B9\u48BA\u48BB\u48BC\u48BD\u48BE\u48BF"+ - "\u48C0\u48C1\u48C2\u48C3\u48C4\u48C5\u48C6\u48C7"+ - "\u48C8\u48C9\u48CA\u48CB\u48CC\u48CD\u48CE\u48CF"+ - "\u48D0\u48D1\u48D2\u48D3\u48D4\u48D5\u48D6\u48D7"+ - "\u48D8\u48D9\u48DA\u48DB\u48DC\u48DD\u48DE\u48DF"+ - "\u48E0\u48E1\u48E2\u48E3\u48E4\u48E5\u48E6\u48E7"+ - "\u48E8\u48E9\u48EA\u48EB\u48EC\u48ED\u48EE\u48EF"+ - "\u48F0\u48F1\u48F2\u48F3\u48F4\u48F5\u48F6\u48F7"+ - "\u48F8\u48F9\u48FA\u48FB\u48FC\u48FD\u48FE\u48FF"+ - "\u4900\u4901\u4902\u4903\u4904\u4905\u4906\u4907"+ - "\u4908\u4909\u490A\u490B\u490C\u490D\u490E\u490F"+ - "\u4910\u4911\u4912\u4913\u4914\u4915\u4916\u4917"+ - "\u4918\u4919\u491A\u491B\u491C\u491D\u491E\u491F"+ - "\u4920\u4921\u4922\u4923\u4924\u4925\u4926\u4927"+ - "\u4928\u4929\u492A\u492B\u492C\u492D\u492E\u492F"+ - "\u4930\u4931\u4932\u4933\u4934\u4935\u4936\u4937"+ - "\u4938\u4939\u493A\u493B\u493C\u493D\u493E\u493F"+ - "\u4940\u4941\u4942\u4943\u4944\u4945\u4946\u4947"+ - "\u4948\u4949\u494A\u494B\u494C\u494D\u494E\u494F"+ - "\u4950\u4951\u4952\u4953\u4954\u4955\u4956\u4957"+ - "\u4958\u4959\u495A\u495B\u495C\u495D\u495E\u495F"+ - "\u4960\u4961\u4962\u4963\u4964\u4965\u4966\u4967"+ - "\u4968\u4969\u496A\u496B\u496C\u496D\u496E\u496F"+ - "\u4970\u4971\u4972\u4973\u4974\u4975\u4976\u4977"+ - "\u4978\u4979\u497A\u497B\u497C\u497D\u497E\u497F"+ - "\u4980\u4981\u4982\u4983\u4984\u4985\u4986\u4987"+ - "\u4988\u4989\u498A\u498B\u498C\u498D\u498E\u498F"+ - "\u4990\u4991\u4992\u4993\u4994\u4995\u4996\u4997"+ - "\u4998\u4999\u499A\u499B\u499C\u499D\u499E\u499F"+ - "\u49A0\u49A1\u49A2\u49A3\u49A4\u49A5\u49A6\u49A7"+ - "\u49A8\u49A9\u49AA\u49AB\u49AC\u49AD\u49AE\u49AF"+ - "\u49B0\u49B1\u49B2\u49B3\u49B4\u49B5\u49B6\u49B7"+ - "\u49B8\u49B9\u49BA\u49BB\u49BC\u49BD\u49BE\u49BF"+ - "\u49C0\u49C1\u49C2\u49C3\u49C4\u49C5\u49C6\u49C7"+ - "\u49C8\u49C9\u49CA\u49CB\u49CC\u49CD\u49CE\u49CF"+ - "\u49D0\u49D1\u49D2\u49D3\u49D4\u49D5\u49D6\u49D7"+ - "\u49D8\u49D9\u49DA\u49DB\u49DC\u49DD\u49DE\u49DF"+ - "\u49E0\u49E1\u49E2\u49E3\u49E4\u49E5\u49E6\u49E7"+ - "\u49E8\u49E9\u49EA\u49EB\u49EC\u49ED\u49EE\u49EF"+ - "\u49F0\u49F1\u49F2\u49F3\u49F4\u49F5\u49F6\u49F7"+ - "\u49F8\u49F9\u49FA\u49FB\u49FC\u49FD\u49FE\u49FF"+ - "\u4A00\u4A01\u4A02\u4A03\u4A04\u4A05\u4A06\u4A07"+ - "\u4A08\u4A09\u4A0A\u4A0B\u4A0C\u4A0D\u4A0E\u4A0F"+ - "\u4A10\u4A11\u4A12\u4A13\u4A14\u4A15\u4A16\u4A17"+ - "\u4A18\u4A19\u4A1A\u4A1B\u4A1C\u4A1D\u4A1E\u4A1F"+ - "\u4A20\u4A21\u4A22\u4A23\u4A24\u4A25\u4A26\u4A27"+ - "\u4A28\u4A29\u4A2A\u4A2B\u4A2C\u4A2D\u4A2E\u4A2F"+ - "\u4A30\u4A31\u4A32\u4A33\u4A34\u4A35\u4A36\u4A37"+ - "\u4A38\u4A39\u4A3A\u4A3B\u4A3C\u4A3D\u4A3E\u4A3F"+ - "\u4A40\u4A41\u4A42\u4A43\u4A44\u4A45\u4A46\u4A47"+ - "\u4A48\u4A49\u4A4A\u4A4B\u4A4C\u4A4D\u4A4E\u4A4F"+ - "\u4A50\u4A51\u4A52\u4A53\u4A54\u4A55\u4A56\u4A57"+ - "\u4A58\u4A59\u4A5A\u4A5B\u4A5C\u4A5D\u4A5E\u4A5F"+ - "\u4A60\u4A61\u4A62\u4A63\u4A64\u4A65\u4A66\u4A67"+ - "\u4A68\u4A69\u4A6A\u4A6B\u4A6C\u4A6D\u4A6E\u4A6F"+ - "\u4A70\u4A71\u4A72\u4A73\u4A74\u4A75\u4A76\u4A77"+ - "\u4A78\u4A79\u4A7A\u4A7B\u4A7C\u4A7D\u4A7E\u4A7F"+ - "\u4A80\u4A81\u4A82\u4A83\u4A84\u4A85\u4A86\u4A87"+ - "\u4A88\u4A89\u4A8A\u4A8B\u4A8C\u4A8D\u4A8E\u4A8F"+ - "\u4A90\u4A91\u4A92\u4A93\u4A94\u4A95\u4A96\u4A97"+ - "\u4A98\u4A99\u4A9A\u4A9B\u4A9C\u4A9D\u4A9E\u4A9F"+ - "\u4AA0\u4AA1\u4AA2\u4AA3\u4AA4\u4AA5\u4AA6\u4AA7"+ - "\u4AA8\u4AA9\u4AAA\u4AAB\u4AAC\u4AAD\u4AAE\u4AAF"+ - "\u4AB0\u4AB1\u4AB2\u4AB3\u4AB4\u4AB5\u4AB6\u4AB7"+ - "\u4AB8\u4AB9\u4ABA\u4ABB\u4ABC\u4ABD\u4ABE\u4ABF"+ - "\u4AC0\u4AC1\u4AC2\u4AC3\u4AC4\u4AC5\u4AC6\u4AC7"+ - "\u4AC8\u4AC9\u4ACA\u4ACB\u4ACC\u4ACD\u4ACE\u4ACF"+ - "\u4AD0\u4AD1\u4AD2\u4AD3\u4AD4\u4AD5\u4AD6\u4AD7"+ - "\u4AD8\u4AD9\u4ADA\u4ADB\u4ADC\u4ADD\u4ADE\u4ADF"+ - "\u4AE0\u4AE1\u4AE2\u4AE3\u4AE4\u4AE5\u4AE6\u4AE7"+ - "\u4AE8\u4AE9\u4AEA\u4AEB\u4AEC\u4AED\u4AEE\u4AEF"+ - "\u4AF0\u4AF1\u4AF2\u4AF3\u4AF4\u4AF5\u4AF6\u4AF7"+ - "\u4AF8\u4AF9\u4AFA\u4AFB\u4AFC\u4AFD\u4AFE\u4AFF"+ - "\u4B00\u4B01\u4B02\u4B03\u4B04\u4B05\u4B06\u4B07"+ - "\u4B08\u4B09\u4B0A\u4B0B\u4B0C\u4B0D\u4B0E\u4B0F"+ - "\u4B10\u4B11\u4B12\u4B13\u4B14\u4B15\u4B16\u4B17"+ - "\u4B18\u4B19\u4B1A\u4B1B\u4B1C\u4B1D\u4B1E\u4B1F"+ - "\u4B20\u4B21\u4B22\u4B23\u4B24\u4B25\u4B26\u4B27"+ - "\u4B28\u4B29\u4B2A\u4B2B\u4B2C\u4B2D\u4B2E\u4B2F"+ - "\u4B30\u4B31\u4B32\u4B33\u4B34\u4B35\u4B36\u4B37"+ - "\u4B38\u4B39\u4B3A\u4B3B\u4B3C\u4B3D\u4B3E\u4B3F"+ - "\u4B40\u4B41\u4B42\u4B43\u4B44\u4B45\u4B46\u4B47"+ - "\u4B48\u4B49\u4B4A\u4B4B\u4B4C\u4B4D\u4B4E\u4B4F"+ - "\u4B50\u4B51\u4B52\u4B53\u4B54\u4B55\u4B56\u4B57"+ - "\u4B58\u4B59\u4B5A\u4B5B\u4B5C\u4B5D\u4B5E\u4B5F"+ - "\u4B60\u4B61\u4B62\u4B63\u4B64\u4B65\u4B66\u4B67"+ - "\u4B68\u4B69\u4B6A\u4B6B\u4B6C\u4B6D\u4B6E\u4B6F"+ - "\u4B70\u4B71\u4B72\u4B73\u4B74\u4B75\u4B76\u4B77"+ - "\u4B78\u4B79\u4B7A\u4B7B\u4B7C\u4B7D\u4B7E\u4B7F"+ - "\u4B80\u4B81\u4B82\u4B83\u4B84\u4B85\u4B86\u4B87"+ - "\u4B88\u4B89\u4B8A\u4B8B\u4B8C\u4B8D\u4B8E\u4B8F"+ - "\u4B90\u4B91\u4B92\u4B93\u4B94\u4B95\u4B96\u4B97"+ - "\u4B98\u4B99\u4B9A\u4B9B\u4B9C\u4B9D\u4B9E\u4B9F"+ - "\u4BA0\u4BA1\u4BA2\u4BA3\u4BA4\u4BA5\u4BA6\u4BA7"+ - "\u4BA8\u4BA9\u4BAA\u4BAB\u4BAC\u4BAD\u4BAE\u4BAF"+ - "\u4BB0\u4BB1\u4BB2\u4BB3\u4BB4\u4BB5\u4BB6\u4BB7"+ - "\u4BB8\u4BB9\u4BBA\u4BBB\u4BBC\u4BBD\u4BBE\u4BBF"+ - "\u4BC0\u4BC1\u4BC2\u4BC3\u4BC4\u4BC5\u4BC6\u4BC7"+ - "\u4BC8\u4BC9\u4BCA\u4BCB\u4BCC\u4BCD\u4BCE\u4BCF"+ - "\u4BD0\u4BD1\u4BD2\u4BD3\u4BD4\u4BD5\u4BD6\u4BD7"+ - "\u4BD8\u4BD9\u4BDA\u4BDB\u4BDC\u4BDD\u4BDE\u4BDF"+ - "\u4BE0\u4BE1\u4BE2\u4BE3\u4BE4\u4BE5\u4BE6\u4BE7"+ - "\u4BE8\u4BE9\u4BEA\u4BEB\u4BEC\u4BED\u4BEE\u4BEF"+ - "\u4BF0\u4BF1\u4BF2\u4BF3\u4BF4\u4BF5\u4BF6\u4BF7"+ - "\u4BF8\u4BF9\u4BFA\u4BFB\u4BFC\u4BFD\u4BFE\u4BFF"+ - "\u4C00\u4C01\u4C02\u4C03\u4C04\u4C05\u4C06\u4C07"+ - "\u4C08\u4C09\u4C0A\u4C0B\u4C0C\u4C0D\u4C0E\u4C0F"+ - "\u4C10\u4C11\u4C12\u4C13\u4C14\u4C15\u4C16\u4C17"+ - "\u4C18\u4C19\u4C1A\u4C1B\u4C1C\u4C1D\u4C1E\u4C1F"+ - "\u4C20\u4C21\u4C22\u4C23\u4C24\u4C25\u4C26\u4C27"+ - "\u4C28\u4C29\u4C2A\u4C2B\u4C2C\u4C2D\u4C2E\u4C2F"+ - "\u4C30\u4C31\u4C32\u4C33\u4C34\u4C35\u4C36\u4C37"+ - "\u4C38\u4C39\u4C3A\u4C3B\u4C3C\u4C3D\u4C3E\u4C3F"+ - "\u4C40\uFE50\u4C41\u4C42\uFE54\u4C43\u4C44\u4C45"+ - "\uFE57\u4C46\u4C47\uFE58\uFE5D\u4C48\u4C49\u4C4A"+ - "\u4C4B\u4C4C\u4C4D\u4C4E\u4C4F\u4C50\u4C51\uFE5E"+ - "\u4C52\u4C53\u4C54\u4C55\u4C56\u4C57\u4C58\u4C59"+ - "\u4C5A\u4C5B\u4C5C\u4C5D\u4C5E\u4C5F\u4C60\uFE6B"+ - "\u4C61\u4C62\uFE6E\u4C63\u4C64\u4C65\uFE71\u4C66"+ - "\u4C67\u4C68\u4C69\uFE73\u4C6A\u4C6B\uFE74\uFE75"+ - "\u4C6C\u4C6D\u4C6E\uFE79\u4C6F\u4C70\u4C71\u4C72"+ - "\u4C73\u4C74\u4C75\u4C76\u4C77\u4C78\u4C79\u4C7A"+ - "\u4C7B\u4C7C\uFE84\u4C7D\u4C7E\u4C7F\u4C80\u4C81"+ - "\u4C82\u4C83\u4C84\u4C85\u4C86\u4C87\u4C88\u4C89"+ - "\u4C8A\u4C8B\u4C8C\u4C8D\u4C8E\u4C8F\u4C90\u4C91"+ - "\u4C92\u4C93\u4C94\u4C95\u4C96\u4C97\u4C98\u4C99"+ - "\u4C9A\u4C9B\u4C9C\u4C9D\u4C9E\u4C9F\u4CA0\u4CA1"+ - "\u4CA2\u4CA3\u4CA4\u4CA5\u4CA6\u4CA7\u4CA8\u4CA9"+ - "\u4CAA\u4CAB\u4CAC\u4CAD\u4CAE\u4CAF\u4CB0\u4CB1"+ - "\u4CB2\u4CB3\u4CB4\u4CB5\u4CB6\u4CB7\u4CB8\u4CB9"+ - "\u4CBA\u4CBB\u4CBC\u4CBD\u4CBE\u4CBF\u4CC0\u4CC1"+ - "\u4CC2\u4CC3\u4CC4\u4CC5\u4CC6\u4CC7\u4CC8\u4CC9"+ - "\u4CCA\u4CCB\u4CCC\u4CCD\u4CCE\u4CCF\u4CD0\u4CD1"+ - "\u4CD2\u4CD3\u4CD4\u4CD5\u4CD6\u4CD7\u4CD8\u4CD9"+ - "\u4CDA\u4CDB\u4CDC\u4CDD\u4CDE\u4CDF\u4CE0\u4CE1"+ - "\u4CE2\u4CE3\u4CE4\u4CE5\u4CE6\u4CE7\u4CE8\u4CE9"+ - "\u4CEA\u4CEB\u4CEC\u4CED\u4CEE\u4CEF\u4CF0\u4CF1"+ - "\u4CF2\u4CF3\u4CF4\u4CF5\u4CF6\u4CF7\u4CF8\u4CF9"+ - "\u4CFA\u4CFB\u4CFC\u4CFD\u4CFE\u4CFF\u4D00\u4D01"+ - "\u4D02\u4D03\u4D04\u4D05\u4D06\u4D07\u4D08\u4D09"+ - "\u4D0A\u4D0B\u4D0C\u4D0D\u4D0E\u4D0F\u4D10\u4D11"+ - "\u4D12\u4D13\u4D14\u4D15\u4D16\u4D17\u4D18\u4D19"+ - "\u4D1A\u4D1B\u4D1C\u4D1D\u4D1E\u4D1F\u4D20\u4D21"+ - "\u4D22\u4D23\u4D24\u4D25\u4D26\u4D27\u4D28\u4D29"+ - "\u4D2A\u4D2B\u4D2C\u4D2D\u4D2E\u4D2F\u4D30\u4D31"+ - "\u4D32\u4D33\u4D34\u4D35\u4D36\u4D37\u4D38\u4D39"+ - "\u4D3A\u4D3B\u4D3C\u4D3D\u4D3E\u4D3F\u4D40\u4D41"+ - "\u4D42\u4D43\u4D44\u4D45\u4D46\u4D47\u4D48\u4D49"+ - "\u4D4A\u4D4B\u4D4C\u4D4D\u4D4E\u4D4F\u4D50\u4D51"+ - "\u4D52\u4D53\u4D54\u4D55\u4D56\u4D57\u4D58\u4D59"+ - "\u4D5A\u4D5B\u4D5C\u4D5D\u4D5E\u4D5F\u4D60\u4D61"+ - "\u4D62\u4D63\u4D64\u4D65\u4D66\u4D67\u4D68\u4D69"+ - "\u4D6A\u4D6B\u4D6C\u4D6D\u4D6E\u4D6F\u4D70\u4D71"+ - "\u4D72\u4D73\u4D74\u4D75\u4D76\u4D77\u4D78\u4D79"+ - "\u4D7A\u4D7B\u4D7C\u4D7D\u4D7E\u4D7F\u4D80\u4D81"+ - "\u4D82\u4D83\u4D84\u4D85\u4D86\u4D87\u4D88\u4D89"+ - "\u4D8A\u4D8B\u4D8C\u4D8D\u4D8E\u4D8F\u4D90\u4D91"+ - "\u4D92\u4D93\u4D94\u4D95\u4D96\u4D97\u4D98\u4D99"+ - "\u4D9A\u4D9B\u4D9C\u4D9D\u4D9E\u4D9F\u4DA0\u4DA1"+ - "\uA98A\uA98B\uA98C\uA98D\uA98E\uA98F\uA990\uA991"+ - "\uA992\uA993\uA994\uA995\u4DA2\u4DA3\u4DA4\u4DA5"; - - private static final String innerEncoderIndex3= - "\uA1A1\uA1A2\uA1A3\uA1A8\u4DA6\uA1A9\uA965\uA996"+ - "\uA1B4\uA1B5\uA1B6\uA1B7\uA1B8\uA1B9\uA1BA\uA1BB"+ - "\uA1BE\uA1BF\uA893\uA1FE\uA1B2\uA1B3\uA1BC\uA1BD"+ - "\u4DA7\u4DA8\u4DA9\u4DAA\u4DAB\uA894\uA895\u4DAC"+ - "\u4DAD\uA940\uA941\uA942\uA943\uA944\uA945\uA946"+ - "\uA947\uA948\u4DAE\u4DAF\u4DB0\u4DB1\u4DB2\u4DB3"+ - "\u4DB4\u4DB5\u4DB6\u4DB7\u4DB8\u4DB9\u4DBA\u4DBB"+ - "\u4DBC\u4DBD\u4DBE\u4DBF\u4DC0\u4DC1\uA989\u4DC2"+ - "\u4DC3\uA4A1\uA4A2\uA4A3\uA4A4\uA4A5\uA4A6\uA4A7"+ - "\uA4A8\uA4A9\uA4AA\uA4AB\uA4AC\uA4AD\uA4AE\uA4AF"+ - "\uA4B0\uA4B1\uA4B2\uA4B3\uA4B4\uA4B5\uA4B6\uA4B7"+ - "\uA4B8\uA4B9\uA4BA\uA4BB\uA4BC\uA4BD\uA4BE\uA4BF"+ - "\uA4C0\uA4C1\uA4C2\uA4C3\uA4C4\uA4C5\uA4C6\uA4C7"+ - "\uA4C8\uA4C9\uA4CA\uA4CB\uA4CC\uA4CD\uA4CE\uA4CF"+ - "\uA4D0\uA4D1\uA4D2\uA4D3\uA4D4\uA4D5\uA4D6\uA4D7"+ - "\uA4D8\uA4D9\uA4DA\uA4DB\uA4DC\uA4DD\uA4DE\uA4DF"+ - "\uA4E0\uA4E1\uA4E2\uA4E3\uA4E4\uA4E5\uA4E6\uA4E7"+ - "\uA4E8\uA4E9\uA4EA\uA4EB\uA4EC\uA4ED\uA4EE\uA4EF"+ - "\uA4F0\uA4F1\uA4F2\uA4F3\u4DC4\u4DC5\u4DC6\u4DC7"+ - "\u4DC8\u4DC9\u4DCA\uA961\uA962\uA966\uA967\u4DCB"+ - "\u4DCC\uA5A1\uA5A2\uA5A3\uA5A4\uA5A5\uA5A6\uA5A7"+ - "\uA5A8\uA5A9\uA5AA\uA5AB\uA5AC\uA5AD\uA5AE\uA5AF"+ - "\uA5B0\uA5B1\uA5B2\uA5B3\uA5B4\uA5B5\uA5B6\uA5B7"+ - "\uA5B8\uA5B9\uA5BA\uA5BB\uA5BC\uA5BD\uA5BE\uA5BF"+ - "\uA5C0\uA5C1\uA5C2\uA5C3\uA5C4\uA5C5\uA5C6\uA5C7"+ - "\uA5C8\uA5C9\uA5CA\uA5CB\uA5CC\uA5CD\uA5CE\uA5CF"+ - "\uA5D0\uA5D1\uA5D2\uA5D3\uA5D4\uA5D5\uA5D6\uA5D7"+ - "\uA5D8\uA5D9\uA5DA\uA5DB\uA5DC\uA5DD\uA5DE\uA5DF"+ - "\uA5E0\uA5E1\uA5E2\uA5E3\uA5E4\uA5E5\uA5E6\uA5E7"+ - "\uA5E8\uA5E9\uA5EA\uA5EB\uA5EC\uA5ED\uA5EE\uA5EF"+ - "\uA5F0\uA5F1\uA5F2\uA5F3\uA5F4\uA5F5\uA5F6\u4DCD"+ - "\u4DCE\u4DCF\u4DD0\u4DD1\uA960\uA963\uA964\u4DD2"+ - "\u4DD3\u4DD4\u4DD5\u4DD6\u4DD7\uA8C5\uA8C6\uA8C7"+ - "\uA8C8\uA8C9\uA8CA\uA8CB\uA8CC\uA8CD\uA8CE\uA8CF"+ - "\uA8D0\uA8D1\uA8D2\uA8D3\uA8D4\uA8D5\uA8D6\uA8D7"+ - "\uA8D8\uA8D9\uA8DA\uA8DB\uA8DC\uA8DD\uA8DE\uA8DF"+ - "\uA8E0\uA8E1\uA8E2\uA8E3\uA8E4\uA8E5\uA8E6\uA8E7"+ - "\uA8E8\uA8E9\u4DD8\u4DD9\u4DDA\u4DDB\u4DDC\u4DDD"+ - "\u4DDE\u4DDF\u4DE0\u4DE1\u4DE2\u4DE3\u4DE4\u4DE5"+ - "\u4DE6\u4DE7\u4DE8\u4DE9\u4DEA\u4DEB\u4DEC\u4DED"+ - "\u4DEE\u4DEF\u4DF0\u4DF1\u4DF2\u4DF3\u4DF4\u4DF5"+ - "\u4DF6\u4DF7\u4DF8\u4DF9\u4DFA\u4DFB\u4DFC\u4DFD"+ - "\u4DFE\u4DFF\u4E00\u4E01\u4E02\u4E03\u4E04\u4E05"+ - "\u4E06\u4E07\u4E08\u4E09\u4E0A\u4E0B\u4E0C\u4E0D"+ - "\u4E0E\u4E0F\u4E10\u4E11\u4E12\u4E13\u4E14\u4E15"+ - "\u4E16\u4E17\u4E18\u4E19\u4E1A\u4E1B\u4E1C\u4E1D"+ - "\u4E1E\u4E1F\u4E20\u4E21\u4E22\u4E23\u4E24\u4E25"+ - "\u4E26\u4E27\u4E28\u4E29\u4E2A\u4E2B\u4E2C\u4E2D"+ - "\u4E2E\u4E2F\u4E30\u4E31\u4E32\u4E33\u4E34\u4E35"+ - "\u4E36\u4E37\u4E38\u4E39\u4E3A\u4E3B\u4E3C\u4E3D"+ - "\u4E3E\u4E3F\u4E40\u4E41\u4E42\u4E43\u4E44\u4E45"+ - "\u4E46\u4E47\u4E48\u4E49\u4E4A\u4E4B\u4E4C\u4E4D"+ - "\u4E4E\u4E4F\u4E50\u4E51\u4E52\u4E53\u4E54\u4E55"+ - "\u4E56\u4E57\u4E58\u4E59\u4E5A\u4E5B\u4E5C\u4E5D"+ - "\u4E5E\u4E5F\u4E60\u4E61\u4E62\u4E63\u4E64\u4E65"+ - "\u4E66\u4E67\u4E68\u4E69\u4E6A\u4E6B\u4E6C\u4E6D"+ - "\u4E6E\u4E6F\u4E70\u4E71\u4E72\u4E73\u4E74\u4E75"+ - "\u4E76\u4E77\u4E78\u4E79\u4E7A\u4E7B\u4E7C\u4E7D"+ - "\u4E7E\u4E7F\u4E80\u4E81\u4E82\u4E83\u4E84\u4E85"+ - "\u4E86\u4E87\u4E88\u4E89\u4E8A\u4E8B\u4E8C\u4E8D"+ - "\u4E8E\u4E8F\u4E90\u4E91\u4E92\u4E93\u4E94\u4E95"+ - "\u4E96\u4E97\u4E98\u4E99\u4E9A\u4E9B\u4E9C\u4E9D"+ - "\u4E9E\u4E9F\u4EA0\u4EA1\u4EA2\u4EA3\u4EA4\u4EA5"+ - "\u4EA6\u4EA7\u4EA8\u4EA9\u4EAA\u4EAB\u4EAC\u4EAD"+ - "\u4EAE\u4EAF\u4EB0\u4EB1\u4EB2\u4EB3\u4EB4\u4EB5"+ - "\u4EB6\u4EB7\u4EB8\u4EB9\u4EBA\u4EBB\u4EBC\u4EBD"+ - "\u4EBE\u4EBF\u4EC0\u4EC1\u4EC2\u4EC3\u4EC4\u4EC5"+ - "\u4EC6\u4EC7\u4EC8\u4EC9\u4ECA\u4ECB\u4ECC\u4ECD"+ - "\uA2E5\uA2E6\uA2E7\uA2E8\uA2E9\uA2EA\uA2EB\uA2EC"+ - "\uA2ED\uA2EE\u4ECE\u4ECF\u4ED0\u4ED1\u4ED2\u4ED3"+ - "\u4ED4\uA95A\u4ED5\u4ED6\u4ED7\u4ED8\u4ED9\u4EDA"+ - "\u4EDB\u4EDC\u4EDD\u4EDE\u4EDF\u4EE0\u4EE1\u4EE2"+ - "\u4EE3\u4EE4\u4EE5\u4EE6\u4EE7\u4EE8\u4EE9\u4EEA"+ - "\u4EEB\u4EEC\u4EED\u4EEE\u4EEF\u4EF0\u4EF1\u4EF2"+ - "\u4EF3\u4EF4\u4EF5\u4EF6\u4EF7\u4EF8\u4EF9\u4EFA"+ - "\u4EFB\u4EFC\u4EFD\u4EFE\u4EFF\u4F00\u4F01\u4F02"+ - "\u4F03\u4F04\u4F05\u4F06\u4F07\u4F08\u4F09\u4F0A"+ - "\u4F0B\u4F0C\u4F0D\u4F0E\u4F0F\u4F10\u4F11\u4F12"+ - "\u4F13\u4F14\u4F15\u4F16\u4F17\u4F18\u4F19\u4F1A"+ - "\u4F1B\u4F1C\u4F1D\u4F1E\u4F1F\u4F20\u4F21\u4F22"+ - "\u4F23\u4F24\u4F25\u4F26\u4F27\u4F28\u4F29\u4F2A"+ - "\u4F2B\u4F2C\u4F2D\u4F2E\u4F2F\u4F30\u4F31\u4F32"+ - "\u4F33\u4F34\u4F35\u4F36\u4F37\u4F38\u4F39\u4F3A"+ - "\u4F3B\u4F3C\u4F3D\u4F3E\u4F3F\u4F40\u4F41\u4F42"+ - "\u4F43\u4F44\u4F45\uA949\u4F46\u4F47\u4F48\u4F49"+ - "\u4F4A\u4F4B\u4F4C\u4F4D\u4F4E\u4F4F\u4F50\u4F51"+ - "\u4F52\u4F53\u4F54\u4F55\u4F56\u4F57\u4F58\u4F59"+ - "\u4F5A\u4F5B\u4F5C\u4F5D\u4F5E\u4F5F\u4F60\u4F61"+ - "\u4F62\u4F63\u4F64\u4F65\u4F66\u4F67\u4F68\u4F69"+ - "\u4F6A\u4F6B\u4F6C\u4F6D\u4F6E\u4F6F\u4F70\u4F71"+ - "\u4F72\u4F73\u4F74\u4F75\u4F76\u4F77\u4F78\u4F79"+ - "\u4F7A\u4F7B\u4F7C\u4F7D\u4F7E\u4F7F\u4F80\u4F81"+ - "\u4F82\u4F83\u4F84\u4F85\u4F86\u4F87\u4F88\u4F89"+ - "\u4F8A\u4F8B\u4F8C\u4F8D\u4F8E\u4F8F\u4F90\u4F91"+ - "\u4F92\u4F93\u4F94\u4F95\u4F96\u4F97\u4F98\u4F99"+ - "\u4F9A\u4F9B\u4F9C\u4F9D\u4F9E\u4F9F\u4FA0\u4FA1"+ - "\u4FA2\u4FA3\u4FA4\u4FA5\u4FA6\u4FA7\u4FA8\u4FA9"+ - "\u4FAA\u4FAB\u4FAC\u4FAD\u4FAE\u4FAF\u4FB0\u4FB1"+ - "\u4FB2\u4FB3\u4FB4\u4FB5\u4FB6\u4FB7\u4FB8\u4FB9"+ - "\u4FBA\u4FBB\u4FBC\u4FBD\u4FBE\u4FBF\u4FC0\u4FC1"+ - "\u4FC2\u4FC3\u4FC4\u4FC5\u4FC6\u4FC7\u4FC8\u4FC9"+ - "\u4FCA\u4FCB\u4FCC\u4FCD\u4FCE\u4FCF\u4FD0\u4FD1"+ - "\u4FD2\u4FD3\u4FD4\u4FD5\u4FD6\u4FD7\u4FD8\u4FD9"+ - "\u4FDA\u4FDB\u4FDC\u4FDD\u4FDE\u4FDF\u4FE0\u4FE1"+ - "\u4FE2\u4FE3\u4FE4\u4FE5\u4FE6\u4FE7\u4FE8\u4FE9"+ - "\u4FEA\u4FEB\u4FEC\u4FED\u4FEE\u4FEF\u4FF0\u4FF1"+ - "\u4FF2\u4FF3\u4FF4\u4FF5\u4FF6\u4FF7\u4FF8\u4FF9"+ - "\u4FFA\u4FFB\u4FFC\u4FFD\u4FFE\u4FFF\u5000\u5001"+ - "\u5002\u5003\u5004\u5005\u5006\u5007\u5008\u5009"+ - "\u500A\u500B\u500C\u500D\u500E\u500F\u5010\u5011"+ - "\u5012\u5013\u5014\u5015\u5016\u5017\u5018\u5019"+ - "\u501A\u501B\u501C\u501D\u501E\u501F\u5020\u5021"+ - "\u5022\u5023\u5024\u5025\u5026\u5027\u5028\u5029"+ - "\u502A\u502B\u502C\u502D\u502E\u502F\uA94A\uA94B"+ - "\u5030\u5031\u5032\u5033\u5034\u5035\u5036\u5037"+ - "\u5038\u5039\u503A\u503B\uA94C\uA94D\uA94E\u503C"+ - "\u503D\uA94F\u503E\u503F\u5040\u5041\u5042\u5043"+ - "\u5044\u5045\u5046\u5047\u5048\u5049\u504A\u504B"+ - "\u504C\u504D\u504E\u504F\u5050\u5051\u5052\u5053"+ - "\u5054\u5055\u5056\u5057\u5058\u5059\u505A\u505B"+ - "\u505C\u505D\u505E\u505F\uA950\u5060\u5061\u5062"+ - "\u5063\u5064\u5065\u5066\u5067\u5068\uA951\u5069"+ - "\u506A\uA952\uA953\u506B\u506C\uA954\u506D\u506E"+ - "\u506F\u5070\u5071\u5072\u5073\u5074\u5075\u5076"+ - "\u5077\u5078\u5079\u507A\u507B\u507C\u507D\u507E"+ - "\u507F\u5080\u5081\u5082\u5083\u5084\u5085\u5086"+ - "\u5087\u5088\u5089\u508A\u508B\u508C\u508D\u508E"+ - "\u508F\u5090\u5091\u5092\u5093\u5094\u5095\u5096"+ - "\u5097\u5098\u5099\u509A\u509B\u509C\u509D\u509E"+ - "\u509F\u50A0\u50A1\u50A2\u50A3\u50A4\u50A5\u50A6"+ - "\u50A7\u50A8\u50A9\u50AA\u50AB\u50AC\u50AD\u50AE"+ - "\u50AF\u50B0\u50B1\u50B2\u50B3\u50B4\u50B5\u50B6"+ - "\u50B7\u50B8\u50B9\u50BA\u50BB\u50BC\u50BD\u50BE"+ - "\u50BF\u50C0\u50C1\u50C2\u50C3\u50C4\u50C5\u50C6"+ - "\u50C7\u50C8\u50C9\u50CA\u50CB\u50CC\u50CD\u50CE"+ - "\u50CF\u50D0\u50D1\u50D2\u50D3\u50D4\u50D5\u50D6"+ - "\u50D7\u50D8\u50D9\u50DA\u50DB\u50DC\u50DD\uFE56"+ - "\u50DE\u50DF\u50E0\u50E1\u50E2\u50E3\u50E4\u50E5"+ - "\u50E6\u50E7\u50E8\u50E9\u50EA\u50EB\u50EC\u50ED"+ - "\u50EE\u50EF\u50F0\u50F1\u50F2\u50F3\u50F4\u50F5"+ - "\u50F6\u50F7\u50F8\u50F9\u50FA\u50FB\u50FC\u50FD"+ - "\u50FE\u50FF\u5100\u5101\u5102\u5103\u5104\u5105"+ - "\u5106\u5107\u5108\uFE55\u5109\u510A\u510B\u510C"+ - "\u510D\u510E\u510F\u5110\u5111\u5112\u5113\u5114"+ - "\u5115\u5116\u5117\u5118\u5119\u511A\u511B\u511C"+ - "\u511D\u511E\u511F\u5120\u5121\u5122\u5123\u5124"+ - "\u5125\u5126\u5127\u5128\u5129\u512A\u512B\u512C"+ - "\u512D\u512E\u512F\u5130\u5131\u5132\u5133\u5134"+ - "\u5135\u5136\u5137\u5138\u5139\u513A\u513B\u513C"+ - "\u513D\u513E\u513F\u5140\u5141\u5142\u5143\u5144"+ - "\u5145\u5146\u5147\u5148\u5149\u514A\u514B\u514C"+ - "\u514D\u514E\u514F\u5150\u5151\u5152\u5153\u5154"+ - "\u5155\u5156\u5157\u5158\u5159\u515A\u515B\u515C"+ - "\u515D\u515E\u515F\u5160\u5161\u5162\u5163\u5164"+ - "\u5165\u5166\u5167\u5168\u5169\u516A\u516B\u516C"+ - "\u516D\u516E\u516F\u5170\u5171\u5172\u5173\u5174"+ - "\u5175\u5176\u5177\u5178\u5179\u517A\u517B\u517C"+ - "\u517D\u517E\u517F\u5180\u5181\u5182\u5183\u5184"+ - "\u5185\u5186\u5187\u5188\u5189\u518A\u518B\u518C"+ - "\u518D\u518E\u518F\u5190\u5191\u5192\u5193\u5194"+ - "\u5195\u5196\u5197\u5198\u5199\u519A\u519B\u519C"+ - "\u519D\u519E\u519F\u51A0\u51A1\u51A2\u51A3\u51A4"+ - "\u51A5\u51A6\u51A7\u51A8\u51A9\u51AA\u51AB\u51AC"+ - "\u51AD\u51AE\u51AF\u51B0\u51B1\u51B2\u51B3\u51B4"+ - "\u51B5\u51B6\u51B7\u51B8\u51B9\u51BA\u51BB\u51BC"+ - "\u51BD\u51BE\u51BF\u51C0\u51C1\u51C2\u51C3\u51C4"+ - "\u51C5\u51C6\u51C7\u51C8\u51C9\u51CA\u51CB\u51CC"+ - "\u51CD\u51CE\u51CF\u51D0\u51D1\u51D2\u51D3\u51D4"+ - "\u51D5\u51D6\u51D7\u51D8\u51D9\u51DA\u51DB\u51DC"+ - "\u51DD\u51DE\u51DF\u51E0\u51E1\u51E2\u51E3\u51E4"+ - "\u51E5\u51E6\u51E7\u51E8\u51E9\u51EA\u51EB\u51EC"+ - "\u51ED\u51EE\u51EF\u51F0\u51F1\u51F2\u51F3\u51F4"+ - "\u51F5\u51F6\u51F7\u51F8\u51F9\u51FA\u51FB\u51FC"+ - "\u51FD\u51FE\u51FF\u5200\u5201\u5202\u5203\u5204"+ - "\u5205\u5206\u5207\u5208\u5209\u520A\u520B\u520C"+ - "\u520D\u520E\u520F\u5210\u5211\u5212\u5213\u5214"+ - "\u5215\u5216\u5217\u5218\u5219\u521A\u521B\u521C"+ - "\u521D\u521E\u521F\u5220\u5221\u5222\u5223\u5224"+ - "\u5225\u5226\u5227\u5228\u5229\u522A\u522B\u522C"+ - "\u522D\u522E\u522F\u5230\u5231\u5232\uFE5A\u5233"+ - "\u5234\u5235\u5236\u5237\u5238\u5239\u523A\u523B"+ - "\u523C\u523D\u523E\u523F\u5240\u5241\u5242\u5243"+ - "\u5244\u5245\u5246\u5247\u5248\u5249\u524A\u524B"+ - "\u524C\u524D\u524E\u524F\u5250\u5251\u5252\u5253"+ - "\u5254\u5255\u5256\u5257\u5258\u5259\u525A\u525B"+ - "\u525C\u525D\u525E\u525F\u5260\u5261\u5262\u5263"+ - "\u5264\u5265\u5266\u5267\u5268\u5269\u526A\u526B"+ - "\u526C\u526D\u526E\u526F\u5270\u5271\u5272\u5273"+ - "\u5274\u5275\u5276\u5277\u5278\u5279\u527A\u527B"+ - "\u527C\u527D\u527E\u527F\u5280\u5281\u5282\u5283"+ - "\u5284\u5285\u5286\u5287\u5288\u5289\u528A\u528B"+ - "\u528C\u528D\u528E\u528F\u5290\u5291\u5292\u5293"+ - "\u5294\u5295\u5296\u5297\u5298\u5299\u529A\u529B"+ - "\u529C\u529D\u529E\u529F\u52A0\u52A1\uFE5C\u52A2"+ - "\u52A3\u52A4\u52A5\u52A6\u52A7\u52A8\u52A9\u52AA"+ - "\u52AB\u52AC\uFE5B\u52AD\u52AE\u52AF\u52B0\u52B1"+ - "\u52B2\u52B3\u52B4\u52B5\u52B6\u52B7\u52B8\u52B9"+ - "\u52BA\u52BB\u52BC\u52BD\u52BE\u52BF\u52C0\u52C1"+ - "\u52C2\u52C3\u52C4\u52C5\u52C6\u52C7\u52C8\u52C9"+ - "\u52CA\u52CB\u52CC\u52CD\u52CE\u52CF\u52D0\u52D1"+ - "\u52D2\u52D3\u52D4\u52D5\u52D6\u52D7\u52D8\u52D9"+ - "\u52DA\u52DB\u52DC\u52DD\u52DE\u52DF\u52E0\u52E1"+ - "\u52E2\u52E3\u52E4\u52E5\u52E6\u52E7\u52E8\u52E9"+ - "\u52EA\u52EB\u52EC\u52ED\u52EE\u52EF\u52F0\u52F1"+ - "\u52F2\u52F3\u52F4\u52F5\u52F6\u52F7\u52F8\u52F9"+ - "\u52FA\u52FB\u52FC\u52FD\u52FE\u52FF\u5300\u5301"+ - "\u5302\u5303\u5304\u5305\u5306\u5307\u5308\u5309"+ - "\u530A\u530B\u530C\u530D\u530E\u530F\u5310\u5311"+ - "\u5312\u5313\u5314\u5315\u5316\u5317\u5318\u5319"+ - "\u531A\u531B\u531C\u531D\u531E\u531F\u5320\u5321"+ - "\u5322\u5323\u5324\u5325\u5326\u5327\u5328\u5329"+ - "\u532A\u532B\u532C\u532D\u532E\u532F\u5330\u5331"+ - "\u5332\u5333\u5334\u5335\u5336\u5337\u5338\u5339"+ - "\u533A\u533B\u533C\u533D\u533E\u533F\u5340\u5341"+ - "\u5342\u5343\u5344\u5345\u5346\u5347\u5348\u5349"+ - "\u534A\u534B\u534C\u534D\u534E\u534F\u5350\u5351"+ - "\u5352\u5353\u5354\u5355\u5356\u5357\u5358\u5359"+ - "\u535A\u535B\u535C\u535D\u535E\u535F\u5360\u5361"+ - "\u5362\u5363\u5364\u5365\u5366\u5367\u5368\u5369"+ - "\u536A\u536B\u536C\u536D\u536E\u536F\u5370\u5371"+ - "\u5372\u5373\u5374\u5375\u5376\u5377\u5378\u5379"+ - "\u537A\u537B\u537C\u537D\u537E\u537F\u5380\u5381"+ - "\u5382\u5383\u5384\u5385\u5386\u5387\u5388\u5389"+ - "\u538A\u538B\u538C\u538D\u538E\u538F\u5390\u5391"+ - "\u5392\u5393\u5394\u5395\u5396\u5397\u5398\u5399"+ - "\u539A\u539B\u539C\u539D\u539E\u539F\u53A0\u53A1"+ - "\u53A2\u53A3\u53A4\u53A5\u53A6\u53A7\u53A8\u53A9"+ - "\u53AA\u53AB\u53AC\u53AD\u53AE\u53AF\u53B0\u53B1"+ - "\u53B2\u53B3\u53B4\u53B5\u53B6\u53B7\u53B8\u53B9"+ - "\u53BA\u53BB\u53BC\u53BD\u53BE\u53BF\u53C0\u53C1"+ - "\u53C2\u53C3\u53C4\u53C5\u53C6\u53C7\u53C8\u53C9"+ - "\u53CA\u53CB\u53CC\u53CD\u53CE\u53CF\u53D0\u53D1"+ - "\u53D2\u53D3\u53D4\u53D5\u53D6\u53D7\u53D8\u53D9"+ - "\u53DA\u53DB\u53DC\u53DD\u53DE\u53DF\u53E0\u53E1"+ - "\u53E2\u53E3\u53E4\u53E5\u53E6\u53E7\u53E8\u53E9"+ - "\u53EA\u53EB\u53EC\u53ED\u53EE\u53EF\u53F0\u53F1"+ - "\u53F2\u53F3\u53F4\u53F5\u53F6\u53F7\u53F8\u53F9"+ - "\u53FA\u53FB\u53FC\u53FD\u53FE\u53FF\u5400\u5401"+ - "\u5402\u5403\u5404\u5405\u5406\u5407\u5408\u5409"+ - "\u540A\u540B\u540C\u540D\u540E\u540F\u5410\u5411"+ - "\u5412\u5413\u5414\u5415\u5416\u5417\u5418\u5419"+ - "\u541A\u541B\u541C\u541D\u541E\u541F\u5420\u5421"+ - "\u5422\u5423\u5424\u5425\u5426\u5427\u5428\u5429"+ - "\u542A\u542B\u542C\u542D\u542E\u542F\u5430\u5431"+ - "\u5432\u5433\u5434\u5435\u5436\u5437\u5438\u5439"+ - "\u543A\u543B\u543C\u543D\u543E\u543F\u5440\u5441"+ - "\u5442\u5443\u5444\u5445\u5446\u5447\u5448\u5449"+ - "\u544A\u544B\u544C\u544D\u544E\u544F\u5450\u5451"+ - "\u5452\u5453\u5454\u5455\u5456\u5457\u5458\u5459"+ - "\u545A\u545B\u545C\u545D\u545E\u545F\u5460\u5461"+ - "\u5462\u5463\u5464\u5465\u5466\u5467\u5468\u5469"+ - "\u546A\u546B\u546C\u546D\u546E\u546F\u5470\u5471"+ - "\u5472\u5473\u5474\u5475\u5476\u5477\u5478\u5479"+ - "\u547A\u547B\u547C\u547D\u547E\u547F\u5480\u5481"+ - "\u5482\u5483\u5484\u5485\u5486\u5487\u5488\u5489"+ - "\u548A\u548B\u548C\u548D\u548E\u548F\u5490\u5491"+ - "\u5492\u5493\u5494\u5495\u5496\u5497\u5498\u5499"+ - "\u549A\u549B\u549C\u549D\u549E\u549F\u54A0\u54A1"+ - "\u54A2\u54A3\u54A4\u54A5\u54A6\u54A7\u54A8\u54A9"+ - "\u54AA\u54AB\u54AC\u54AD\u54AE\u54AF\u54B0\u54B1"+ - "\u54B2\u54B3\u54B4\u54B5\u54B6\u54B7\u54B8\u54B9"+ - "\u54BA\u54BB\u54BC\u54BD\u54BE\u54BF\u54C0\u54C1"+ - "\u54C2\u54C3\u54C4\u54C5\u54C6\u54C7\u54C8\u54C9"+ - "\u54CA\u54CB\u54CC\u54CD\u54CE\u54CF\u54D0\u54D1"+ - "\u54D2\u54D3\u54D4\u54D5\u54D6\u54D7\u54D8\u54D9"+ - "\u54DA\u54DB\u54DC\u54DD\u54DE\u54DF\u54E0\u54E1"+ - "\u54E2\u54E3\u54E4\u54E5\u54E6\u54E7\u54E8\u54E9"+ - "\u54EA\u54EB\u54EC\u54ED\u54EE\u54EF\u54F0\u54F1"+ - "\u54F2\u54F3\u54F4\u54F5\u54F6\u54F7\u54F8\u54F9"+ - "\u54FA\u54FB\u54FC\u54FD\u54FE\u54FF\u5500\u5501"+ - "\u5502\u5503\u5504\u5505\u5506\u5507\u5508\u5509"+ - "\u550A\u550B\u550C\u550D\u550E\u550F\u5510\u5511"+ - "\u5512\u5513\u5514\u5515\u5516\u5517\u5518\u5519"+ - "\u551A\u551B\u551C\u551D\u551E\u551F\u5520\u5521"+ - "\u5522\u5523\u5524\u5525\u5526\u5527\u5528\u5529"+ - "\u552A\u552B\u552C\u552D\u552E\u552F\u5530\u5531"+ - "\u5532\u5533\u5534\u5535\u5536\u5537\u5538\u5539"+ - "\u553A\u553B\u553C\u553D\u553E\u553F\u5540\u5541"+ - "\u5542\u5543\u5544\u5545\u5546\u5547\u5548\u5549"+ - "\u554A\u554B\u554C\u554D\u554E\u554F\u5550\u5551"+ - "\u5552\u5553\u5554\u5555\u5556\u5557\u5558\u5559"+ - "\u555A\u555B\u555C\u555D\u555E\u555F\u5560\u5561"+ - "\u5562\u5563\u5564\u5565\u5566\u5567\u5568\u5569"+ - "\u556A\u556B\u556C\u556D\u556E\u556F\u5570\u5571"+ - "\u5572\u5573\u5574\u5575\u5576\u5577\u5578\u5579"+ - "\u557A\u557B\u557C\u557D\u557E\u557F\u5580\u5581"+ - "\u5582\u5583\u5584\u5585\u5586\u5587\u5588\u5589"+ - "\u558A\u558B\u558C\u558D\u558E\u558F\u5590\u5591"+ - "\u5592\u5593\u5594\u5595\u5596\u5597\u5598\u5599"+ - "\u559A\u559B\u559C\u559D\u559E\u559F\u55A0\u55A1"+ - "\u55A2\u55A3\u55A4\u55A5\u55A6\u55A7\u55A8\u55A9"+ - "\uFE60\u55AA\u55AB\u55AC\u55AD\u55AE\u55AF\u55B0"+ - "\u55B1\u55B2\u55B3\u55B4\u55B5\u55B6\u55B7\u55B8"+ - "\u55B9\u55BA\u55BB\u55BC\u55BD\u55BE\u55BF\u55C0"+ - "\u55C1\u55C2\u55C3\u55C4\u55C5\u55C6\u55C7\u55C8"+ - "\u55C9\u55CA\u55CB\u55CC\u55CD\u55CE\u55CF\u55D0"+ - "\u55D1\u55D2\u55D3\u55D4\u55D5\u55D6\u55D7\u55D8"+ - "\u55D9\u55DA\u55DB\u55DC\u55DD\u55DE\u55DF\u55E0"+ - "\u55E1\u55E2\u55E3\u55E4\u55E5\u55E6\u55E7\u55E8"+ - "\u55E9\u55EA\u55EB\u55EC\u55ED\u55EE\u55EF\u55F0"+ - "\u55F1\u55F2\u55F3\u55F4\u55F5\u55F6\u55F7\u55F8"+ - "\u55F9\u55FA\u55FB\u55FC\u55FD\u55FE\uFE5F\u55FF"+ - "\u5600\u5601\u5602\u5603\u5604\u5605\u5606\u5607"+ - "\u5608\u5609\u560A\u560B\u560C\u560D\u560E\u560F"+ - "\u5610\u5611\u5612\u5613\u5614\u5615\u5616\u5617"+ - "\u5618\u5619\u561A\u561B\u561C\u561D\u561E\u561F"+ - "\u5620\u5621\u5622\u5623\u5624\u5625\u5626\u5627"+ - "\u5628\u5629\u562A\u562B\u562C\u562D\u562E\u562F"+ - "\u5630\u5631\u5632\u5633\u5634\u5635\u5636\u5637"+ - "\u5638\u5639\u563A\u563B\u563C\u563D\u563E\u563F"+ - "\u5640\u5641\u5642\u5643\u5644\u5645\u5646\u5647"+ - "\u5648\u5649\u564A\u564B\u564C\u564D\u564E\u564F"+ - "\u5650\u5651\u5652\u5653\u5654\u5655\u5656\u5657"+ - "\u5658\u5659\u565A\u565B\u565C\u565D\u565E\uFE62"+ - "\uFE65\u565F\u5660\u5661\u5662\u5663\u5664\u5665"+ - "\u5666\u5667\u5668\u5669\u566A\u566B\u566C\uFE63"+ - "\u566D\u566E\u566F\u5670\u5671\u5672\u5673\u5674"+ - "\u5675\u5676\u5677\u5678\u5679\u567A\u567B\u567C"+ - "\u567D\u567E\u567F\u5680\u5681\u5682\u5683\u5684"+ - "\u5685\u5686\u5687\u5688\u5689\u568A\u568B\u568C"+ - "\u568D\u568E\u568F\u5690\u5691\u5692\u5693\u5694"+ - "\u5695\u5696\u5697\u5698\u5699\u569A\u569B\u569C"+ - "\u569D\u569E\u569F\u56A0\u56A1\u56A2\u56A3\u56A4"+ - "\u56A5\u56A6\u56A7\u56A8\u56A9\u56AA\u56AB\u56AC"+ - "\u56AD\u56AE\u56AF\u56B0\u56B1\u56B2\u56B3\u56B4"+ - "\u56B5\u56B6\u56B7\u56B8\u56B9\u56BA\u56BB\u56BC"+ - "\u56BD\u56BE\u56BF\u56C0\u56C1\u56C2\u56C3\u56C4"+ - "\u56C5\u56C6\u56C7\u56C8\u56C9\u56CA\u56CB\u56CC"+ - "\u56CD\u56CE\u56CF\u56D0\u56D1\u56D2\u56D3\u56D4"+ - "\u56D5\u56D6\u56D7\u56D8\u56D9\u56DA\u56DB\u56DC"+ - "\u56DD\u56DE\u56DF\u56E0\u56E1\u56E2\u56E3\u56E4"+ - "\u56E5\u56E6\u56E7\u56E8\u56E9\u56EA\u56EB\u56EC"+ - "\u56ED\u56EE\u56EF\u56F0\u56F1\u56F2\u56F3\u56F4"+ - "\u56F5\u56F6\u56F7\u56F8\u56F9\u56FA\u56FB\u56FC"+ - "\u56FD\u56FE\u56FF\uFE64\u5700\u5701\u5702\u5703"+ - "\u5704\u5705\u5706\u5707\u5708\u5709\u570A\u570B"+ - "\u570C\u570D\u570E\u570F\u5710\u5711\u5712\u5713"+ - "\u5714\u5715\u5716\u5717\u5718\u5719\u571A\u571B"+ - "\u571C\u571D\u571E\u571F\u5720\u5721\u5722\u5723"+ - "\u5724\u5725\u5726\u5727\u5728\u5729\u572A\u572B"+ - "\u572C\u572D\u572E\u572F\u5730\u5731\u5732\u5733"+ - "\u5734\u5735\u5736\u5737\u5738\u5739\u573A\u573B"+ - "\u573C\u573D\u573E\u573F\u5740\u5741\u5742\u5743"+ - "\u5744\u5745\u5746\u5747\u5748\u5749\u574A\u574B"+ - "\u574C\u574D\u574E\u574F\u5750\u5751\u5752\u5753"+ - "\u5754\u5755\u5756\u5757\u5758\u5759\u575A\u575B"+ - "\u575C\u575D\u575E\u575F\u5760\u5761\u5762\u5763"+ - "\u5764\u5765\u5766\u5767\u5768\u5769\u576A\u576B"+ - "\u576C\u576D\u576E\u576F\u5770\u5771\u5772\u5773"+ - "\u5774\u5775\u5776\u5777\u5778\u5779\u577A\u577B"+ - "\u577C\u577D\u577E\u577F\u5780\u5781\u5782\u5783"+ - "\u5784\u5785\u5786\u5787\u5788\u5789\u578A\u578B"+ - "\u578C\u578D\u578E\u578F\u5790\u5791\u5792\u5793"+ - "\u5794\u5795\u5796\u5797\u5798\u5799\u579A\u579B"+ - "\u579C\u579D\u579E\u579F\u57A0\u57A1\u57A2\u57A3"+ - "\u57A4\u57A5\u57A6\u57A7\u57A8\u57A9\u57AA\u57AB"+ - "\u57AC\u57AD\u57AE\u57AF\u57B0\u57B1\u57B2\u57B3"+ - "\u57B4\u57B5\u57B6\u57B7\u57B8\u57B9\u57BA\u57BB"+ - "\u57BC\u57BD\u57BE\u57BF\u57C0\u57C1\u57C2\u57C3"+ - "\u57C4\u57C5\u57C6\u57C7\u57C8\u57C9\u57CA\u57CB"+ - "\u57CC\u57CD\u57CE\u57CF\u57D0\u57D1\u57D2\u57D3"+ - "\u57D4\u57D5\u57D6\u57D7\u57D8\u57D9\uFE68\u57DA"+ - "\u57DB\u57DC\u57DD\u57DE\u57DF\u57E0\u57E1\u57E2"+ - "\u57E3\u57E4\u57E5\u57E6\u57E7\u57E8\u57E9\u57EA"+ - "\u57EB\u57EC\u57ED\u57EE\u57EF\u57F0\u57F1\u57F2"+ - "\u57F3\u57F4\u57F5\u57F6\u57F7\u57F8\u57F9\u57FA"+ - "\u57FB\u57FC\u57FD\u57FE\u57FF\u5800\u5801\u5802"+ - "\u5803\u5804\u5805\u5806\u5807\u5808\u5809\u580A"+ - "\u580B\u580C\u580D\u580E\u580F\u5810\u5811\u5812"+ - "\u5813\u5814\u5815\u5816\u5817\u5818\u5819\u581A"+ - "\u581B\u581C\u581D\u581E\u581F\u5820\u5821\u5822"+ - "\u5823\u5824\u5825\u5826\u5827\u5828\u5829\u582A"+ - "\u582B\u582C\u582D\u582E\u582F\u5830\u5831\u5832"+ - "\u5833\u5834\u5835\u5836\u5837\u5838\u5839\u583A"+ - "\u583B\u583C\u583D\u583E\u583F\u5840\u5841\u5842"+ - "\u5843\u5844\u5845\u5846\u5847\u5848\u5849\u584A"+ - "\u584B\u584C\u584D\u584E\u584F\u5850\u5851\u5852"+ - "\u5853\u5854\u5855\u5856\u5857\u5858\u5859\u585A"+ - "\u585B\u585C\u585D\u585E\u585F\u5860\u5861\u5862"+ - "\u5863\u5864\u5865\u5866\u5867\u5868\u5869\u586A"+ - "\u586B\u586C\u586D\u586E\u586F\u5870\u5871\u5872"+ - "\u5873\u5874\u5875\u5876\u5877\u5878\u5879\u587A"+ - "\u587B\u587C\u587D\u587E\u587F\u5880\u5881\u5882"+ - "\u5883\u5884\u5885\u5886\u5887\u5888\u5889\u588A"+ - "\u588B\u588C\u588D\u588E\u588F\u5890\u5891\u5892"+ - "\u5893\u5894\u5895\u5896\u5897\u5898\u5899\u589A"+ - "\u589B\u589C\u589D\u589E\u589F\u58A0\u58A1\u58A2"+ - "\u58A3\u58A4\u58A5\u58A6\u58A7\u58A8\u58A9\u58AA"+ - "\u58AB\u58AC\u58AD\u58AE\u58AF\u58B0\u58B1\u58B2"+ - "\u58B3\u58B4\u58B5\u58B6\u58B7\u58B8\u58B9\u58BA"+ - "\u58BB\u58BC\u58BD\u58BE\u58BF\u58C0\u58C1\u58C2"+ - "\u58C3\u58C4\u58C5\u58C6\u58C7\u58C8\u58C9\u58CA"+ - "\u58CB\u58CC\u58CD\u58CE\u58CF\u58D0\u58D1\u58D2"+ - "\u58D3\u58D4\u58D5\u58D6\u58D7\u58D8\u58D9\u58DA"+ - "\u58DB\u58DC\u58DD\u58DE\u58DF\u58E0\u58E1\u58E2"+ - "\u58E3\u58E4\u58E5\u58E6\u58E7\u58E8\u58E9\u58EA"+ - "\u58EB\u58EC\u58ED\u58EE\u58EF\u58F0\u58F1\u58F2"+ - "\u58F3\u58F4\u58F5\u58F6\u58F7\u58F8\uFE69\u58F9"+ - "\u58FA\u58FB\u58FC\u58FD\u58FE\u58FF\u5900\u5901"+ - "\u5902\u5903\u5904\u5905\u5906\u5907\u5908\u5909"+ - "\u590A\u590B\u590C\u590D\u590E\u590F\u5910\u5911"+ - "\u5912\u5913\u5914\u5915\u5916\u5917\u5918\u5919"+ - "\u591A\u591B\u591C\u591D\u591E\u591F\u5920\u5921"+ - "\u5922\u5923\u5924\u5925\u5926\u5927\u5928\u5929"+ - "\u592A\u592B\u592C\u592D\u592E\u592F\u5930\u5931"+ - "\u5932\u5933\u5934\u5935\u5936\u5937\u5938\u5939"+ - "\u593A\u593B\u593C\u593D\u593E\u593F\u5940\u5941"+ - "\u5942\u5943\u5944\u5945\u5946\u5947\u5948\u5949"+ - "\u594A\u594B\u594C\u594D\u594E\u594F\u5950\u5951"+ - "\u5952\u5953\u5954\u5955\u5956\u5957\u5958\u5959"+ - "\u595A\u595B\u595C\u595D\u595E\u595F\u5960\u5961"+ - "\u5962\u5963\u5964\u5965\u5966\u5967\u5968\u5969"+ - "\uFE6A\u596A\u596B\u596C\u596D\u596E\u596F\u5970"+ - "\u5971\u5972\u5973\u5974\u5975\u5976\u5977\u5978"+ - "\u5979\u597A\u597B\u597C\u597D\u597E\u597F\u5980"+ - "\u5981\u5982\u5983\u5984\u5985\u5986\u5987\u5988"+ - "\u5989\u598A\u598B\u598C\u598D\u598E\u598F\u5990"+ - "\u5991\u5992\u5993\u5994\u5995\u5996\u5997\u5998"+ - "\u5999\u599A\u599B\u599C\u599D\u599E\u599F\u59A0"+ - "\u59A1\u59A2\u59A3\u59A4\u59A5\u59A6\u59A7\u59A8"+ - "\u59A9\u59AA\u59AB\u59AC\u59AD\u59AE\u59AF\u59B0"+ - "\u59B1\u59B2\u59B3\u59B4\u59B5\u59B6\u59B7\u59B8"+ - "\u59B9\u59BA\u59BB\u59BC\u59BD\u59BE\u59BF\u59C0"+ - "\u59C1\u59C2\u59C3\u59C4\u59C5\u59C6\u59C7\u59C8"+ - "\u59C9\u59CA\u59CB\u59CC\u59CD\u59CE\u59CF\u59D0"+ - "\u59D1\u59D2\u59D3\u59D4\u59D5\u59D6\u59D7\u59D8"+ - "\u59D9\u59DA\u59DB\u59DC\u59DD\u59DE\u59DF\u59E0"+ - "\u59E1\u59E2\u59E3\u59E4\u59E5\u59E6\u59E7\u59E8"+ - "\u59E9\u59EA\u59EB\u59EC\u59ED\u59EE\u59EF\u59F0"+ - "\u59F1\u59F2\u59F3\u59F4\u59F5\u59F6\u59F7\u59F8"+ - "\u59F9\u59FA\u59FB\u59FC\u59FD\u59FE\u59FF\u5A00"+ - "\u5A01\u5A02\u5A03\u5A04\u5A05\u5A06\u5A07\u5A08"+ - "\u5A09\u5A0A\u5A0B\u5A0C\u5A0D\u5A0E\u5A0F\u5A10"+ - "\u5A11\u5A12\u5A13\u5A14\u5A15\u5A16\u5A17\u5A18"+ - "\u5A19\u5A1A\u5A1B\u5A1C\u5A1D\u5A1E\u5A1F\u5A20"+ - "\u5A21\u5A22\u5A23\u5A24\u5A25\u5A26\u5A27\u5A28"+ - "\u5A29\u5A2A\u5A2B\u5A2C\u5A2D\u5A2E\u5A2F\u5A30"+ - "\u5A31\u5A32\u5A33\u5A34\u5A35\u5A36\u5A37\u5A38"+ - "\u5A39\u5A3A\u5A3B\u5A3C\u5A3D\u5A3E\u5A3F\u5A40"+ - "\u5A41\u5A42\u5A43\u5A44\u5A45\u5A46\u5A47\u5A48"+ - "\u5A49\u5A4A\u5A4B\u5A4C\u5A4D\u5A4E\u5A4F\u5A50"+ - "\u5A51\u5A52\u5A53\u5A54\u5A55\u5A56\u5A57\u5A58"+ - "\u5A59\u5A5A\u5A5B\u5A5C\u5A5D\u5A5E\u5A5F\u5A60"+ - "\u5A61\u5A62\u5A63\u5A64\u5A65\u5A66\u5A67\u5A68"+ - "\u5A69\u5A6A\u5A6B\u5A6C\u5A6D\u5A6E\u5A6F\u5A70"+ - "\u5A71\u5A72\u5A73\u5A74\u5A75\u5A76\u5A77\u5A78"+ - "\u5A79\u5A7A\u5A7B\u5A7C\u5A7D\u5A7E\u5A7F\u5A80"+ - "\u5A81\u5A82\u5A83\u5A84\u5A85\u5A86\u5A87\u5A88"+ - "\u5A89\u5A8A\u5A8B\u5A8C\u5A8D\u5A8E\u5A8F\u5A90"+ - "\u5A91\u5A92\u5A93\u5A94\u5A95\u5A96\u5A97\u5A98"+ - "\u5A99\u5A9A\u5A9B\u5A9C\u5A9D\u5A9E\u5A9F\u5AA0"+ - "\u5AA1\u5AA2\u5AA3\u5AA4\u5AA5\u5AA6\u5AA7\u5AA8"+ - "\u5AA9\u5AAA\u5AAB\u5AAC\u5AAD\u5AAE\u5AAF\u5AB0"+ - "\u5AB1\u5AB2\u5AB3\u5AB4\u5AB5\u5AB6\u5AB7\u5AB8"+ - "\u5AB9\u5ABA\u5ABB\u5ABC\u5ABD\u5ABE\u5ABF\u5AC0"+ - "\u5AC1\u5AC2\u5AC3\u5AC4\u5AC5\u5AC6\u5AC7\u5AC8"+ - "\u5AC9\u5ACA\u5ACB\u5ACC\u5ACD\u5ACE\u5ACF\u5AD0"+ - "\u5AD1\u5AD2\u5AD3\u5AD4\u5AD5\u5AD6\u5AD7\u5AD8"+ - "\u5AD9\u5ADA\u5ADB\u5ADC\u5ADD\u5ADE\u5ADF\u5AE0"+ - "\u5AE1\u5AE2\u5AE3\u5AE4\u5AE5\u5AE6\u5AE7\u5AE8"+ - "\u5AE9\u5AEA\u5AEB\u5AEC\u5AED\u5AEE\u5AEF\u5AF0"+ - "\u5AF1\u5AF2\u5AF3\u5AF4\u5AF5\u5AF6\u5AF7\u5AF8"+ - "\u5AF9\u5AFA\u5AFB\u5AFC\u5AFD\u5AFE\u5AFF\u5B00"+ - "\u5B01\u5B02\u5B03\u5B04\u5B05\u5B06\u5B07\u5B08"+ - "\u5B09\u5B0A\u5B0B\u5B0C\u5B0D\u5B0E\u5B0F\u5B10"+ - "\u5B11\u5B12\u5B13\u5B14\u5B15\u5B16\u5B17\u5B18"+ - "\u5B19\u5B1A\u5B1B\u5B1C\u5B1D\u5B1E\u5B1F\u5B20"+ - "\u5B21\u5B22\u5B23\u5B24\u5B25\u5B26\u5B27\u5B28"+ - "\u5B29\u5B2A\u5B2B\u5B2C\u5B2D\u5B2E\u5B2F\u5B30"+ - "\u5B31\u5B32\u5B33\u5B34\u5B35\u5B36\u5B37\u5B38"+ - "\u5B39\u5B3A\u5B3B\u5B3C\u5B3D\u5B3E\u5B3F\u5B40"+ - "\u5B41\u5B42\u5B43\u5B44\u5B45\u5B46\u5B47\u5B48"+ - "\u5B49\u5B4A\u5B4B\u5B4C\u5B4D\u5B4E\u5B4F\u5B50"+ - "\u5B51\u5B52\u5B53\u5B54\u5B55\u5B56\u5B57\u5B58"+ - "\u5B59\u5B5A\u5B5B\u5B5C\u5B5D\u5B5E\u5B5F\u5B60"+ - "\u5B61\u5B62\u5B63\u5B64\u5B65\u5B66\u5B67\u5B68"+ - "\u5B69\u5B6A\u5B6B\u5B6C\u5B6D\u5B6E\u5B6F\u5B70"+ - "\u5B71\u5B72\u5B73\u5B74\u5B75\u5B76\u5B77\u5B78"+ - "\u5B79\u5B7A\u5B7B\u5B7C\u5B7D\u5B7E\u5B7F\u5B80"+ - "\u5B81\u5B82\u5B83\u5B84\u5B85\u5B86\u5B87\u5B88"+ - "\u5B89\u5B8A\u5B8B\u5B8C\u5B8D\u5B8E\u5B8F\u5B90"+ - "\u5B91\u5B92\u5B93\u5B94\u5B95\u5B96\u5B97\u5B98"+ - "\u5B99\u5B9A\u5B9B\u5B9C\u5B9D\u5B9E\u5B9F\u5BA0"+ - "\u5BA1\u5BA2\u5BA3\u5BA4\u5BA5\u5BA6\u5BA7\u5BA8"+ - "\u5BA9\u5BAA\u5BAB\u5BAC\u5BAD\u5BAE\u5BAF\u5BB0"+ - "\u5BB1\u5BB2\u5BB3\u5BB4\u5BB5\u5BB6\u5BB7\u5BB8"+ - "\u5BB9\u5BBA\u5BBB\u5BBC\u5BBD\u5BBE\u5BBF\u5BC0"+ - "\u5BC1\u5BC2\u5BC3\u5BC4\u5BC5\u5BC6\u5BC7\u5BC8"+ - "\u5BC9\u5BCA\u5BCB\u5BCC\u5BCD\u5BCE\u5BCF\u5BD0"+ - "\u5BD1\u5BD2\u5BD3\u5BD4\u5BD5\u5BD6\u5BD7\u5BD8"+ - "\u5BD9\u5BDA\u5BDB\u5BDC\u5BDD\u5BDE\u5BDF\u5BE0"+ - "\u5BE1\u5BE2\u5BE3\u5BE4\u5BE5\u5BE6\u5BE7\u5BE8"+ - "\u5BE9\u5BEA\u5BEB\u5BEC\u5BED\u5BEE\u5BEF\u5BF0"+ - "\u5BF1\u5BF2\u5BF3\u5BF4\u5BF5\u5BF6\u5BF7\u5BF8"+ - "\u5BF9\u5BFA\u5BFB\u5BFC\u5BFD\u5BFE\u5BFF\u5C00"+ - "\u5C01\u5C02\u5C03\u5C04\u5C05\u5C06\u5C07\u5C08"+ - "\u5C09\u5C0A\u5C0B\u5C0C\u5C0D\u5C0E\u5C0F\u5C10"+ - "\u5C11\u5C12\u5C13\u5C14\u5C15\u5C16\u5C17\u5C18"+ - "\u5C19\u5C1A\u5C1B\u5C1C\u5C1D\u5C1E\u5C1F\u5C20"+ - "\u5C21\u5C22\u5C23\u5C24\u5C25\u5C26\u5C27\u5C28"+ - "\u5C29\u5C2A\u5C2B\u5C2C\u5C2D\u5C2E\u5C2F\u5C30"+ - "\u5C31\u5C32\u5C33\u5C34\u5C35\u5C36\u5C37\u5C38"+ - "\u5C39\u5C3A\u5C3B\u5C3C\u5C3D\u5C3E\u5C3F\u5C40"+ - "\u5C41\u5C42\u5C43\u5C44\u5C45\u5C46\u5C47\u5C48"+ - "\u5C49\u5C4A\u5C4B\u5C4C\u5C4D\u5C4E\u5C4F\u5C50"+ - "\u5C51\u5C52\u5C53\u5C54\u5C55\u5C56\u5C57\u5C58"+ - "\u5C59\u5C5A\u5C5B\u5C5C\u5C5D\u5C5E\u5C5F\u5C60"+ - "\u5C61\u5C62\u5C63\u5C64\u5C65\u5C66\u5C67\u5C68"+ - "\u5C69\u5C6A\u5C6B\u5C6C\u5C6D\u5C6E\u5C6F\u5C70"+ - "\u5C71\u5C72\u5C73\u5C74\u5C75\u5C76\u5C77\u5C78"+ - "\u5C79\u5C7A\u5C7B\u5C7C\u5C7D\u5C7E\u5C7F\u5C80"+ - "\u5C81\u5C82\u5C83\u5C84\u5C85\u5C86\u5C87\u5C88"; - - private static final String innerEncoderIndex4= - "\u5C89\u5C8A\u5C8B\u5C8C\u5C8D\u5C8E\u5C8F\u5C90"+ - "\u5C91\u5C92\u5C93\u5C94\u5C95\u5C96\u5C97\u5C98"+ - "\u5C99\u5C9A\u5C9B\u5C9C\u5C9D\u5C9E\u5C9F\u5CA0"+ - "\u5CA1\u5CA2\u5CA3\u5CA4\u5CA5\u5CA6\u5CA7\u5CA8"+ - "\u5CA9\u5CAA\u5CAB\u5CAC\u5CAD\u5CAE\u5CAF\u5CB0"+ - "\u5CB1\u5CB2\u5CB3\u5CB4\u5CB5\u5CB6\u5CB7\u5CB8"+ - "\u5CB9\u5CBA\u5CBB\u5CBC\u5CBD\u5CBE\u5CBF\u5CC0"+ - "\u5CC1\u5CC2\u5CC3\u5CC4\u5CC5\u5CC6\u5CC7\u5CC8"+ - "\u5CC9\u5CCA\u5CCB\u5CCC\u5CCD\u5CCE\u5CCF\u5CD0"+ - "\u5CD1\u5CD2\u5CD3\u5CD4\u5CD5\u5CD6\u5CD7\u5CD8"+ - "\u5CD9\u5CDA\u5CDB\u5CDC\u5CDD\u5CDE\uFE6F\u5CDF"+ - "\u5CE0\u5CE1\u5CE2\u5CE3\u5CE4\u5CE5\u5CE6\u5CE7"+ - "\u5CE8\u5CE9\u5CEA\u5CEB\u5CEC\u5CED\u5CEE\u5CEF"+ - "\u5CF0\u5CF1\u5CF2\u5CF3\u5CF4\u5CF5\u5CF6\u5CF7"+ - "\u5CF8\u5CF9\u5CFA\u5CFB\u5CFC\u5CFD\u5CFE\u5CFF"+ - "\u5D00\u5D01\u5D02\u5D03\u5D04\u5D05\u5D06\u5D07"+ - "\u5D08\u5D09\u5D0A\u5D0B\u5D0C\u5D0D\u5D0E\u5D0F"+ - "\u5D10\u5D11\u5D12\u5D13\u5D14\u5D15\u5D16\u5D17"+ - "\u5D18\u5D19\u5D1A\u5D1B\u5D1C\u5D1D\u5D1E\u5D1F"+ - "\u5D20\u5D21\u5D22\u5D23\u5D24\u5D25\u5D26\u5D27"+ - "\u5D28\u5D29\u5D2A\u5D2B\u5D2C\u5D2D\u5D2E\u5D2F"+ - "\u5D30\u5D31\u5D32\u5D33\u5D34\u5D35\u5D36\u5D37"+ - "\u5D38\u5D39\u5D3A\u5D3B\u5D3C\u5D3D\u5D3E\u5D3F"+ - "\u5D40\u5D41\u5D42\u5D43\u5D44\u5D45\u5D46\u5D47"+ - "\u5D48\u5D49\u5D4A\u5D4B\u5D4C\u5D4D\u5D4E\u5D4F"+ - "\u5D50\u5D51\u5D52\u5D53\u5D54\u5D55\u5D56\u5D57"+ - "\u5D58\u5D59\u5D5A\u5D5B\u5D5C\u5D5D\u5D5E\u5D5F"+ - "\u5D60\u5D61\u5D62\u5D63\u5D64\u5D65\u5D66\u5D67"+ - "\u5D68\u5D69\u5D6A\u5D6B\u5D6C\u5D6D\u5D6E\u5D6F"+ - "\u5D70\u5D71\u5D72\u5D73\u5D74\u5D75\u5D76\u5D77"+ - "\u5D78\u5D79\u5D7A\u5D7B\u5D7C\u5D7D\u5D7E\u5D7F"+ - "\u5D80\u5D81\u5D82\u5D83\u5D84\u5D85\u5D86\u5D87"+ - "\u5D88\u5D89\u5D8A\u5D8B\u5D8C\u5D8D\u5D8E\u5D8F"+ - "\u5D90\u5D91\u5D92\u5D93\u5D94\u5D95\u5D96\u5D97"+ - "\u5D98\u5D99\u5D9A\u5D9B\u5D9C\u5D9D\u5D9E\u5D9F"+ - "\u5DA0\u5DA1\u5DA2\u5DA3\u5DA4\u5DA5\u5DA6\u5DA7"+ - "\u5DA8\u5DA9\u5DAA\u5DAB\u5DAC\u5DAD\u5DAE\u5DAF"+ - "\u5DB0\u5DB1\u5DB2\u5DB3\u5DB4\u5DB5\u5DB6\u5DB7"+ - "\u5DB8\u5DB9\u5DBA\u5DBB\u5DBC\u5DBD\u5DBE\u5DBF"+ - "\u5DC0\u5DC1\u5DC2\u5DC3\u5DC4\u5DC5\u5DC6\u5DC7"+ - "\u5DC8\u5DC9\u5DCA\u5DCB\u5DCC\u5DCD\u5DCE\u5DCF"+ - "\u5DD0\u5DD1\u5DD2\u5DD3\u5DD4\u5DD5\u5DD6\u5DD7"+ - "\u5DD8\u5DD9\u5DDA\u5DDB\u5DDC\u5DDD\u5DDE\u5DDF"+ - "\u5DE0\u5DE1\u5DE2\u5DE3\u5DE4\u5DE5\u5DE6\uFE70"+ - "\u5DE7\u5DE8\u5DE9\u5DEA\u5DEB\u5DEC\u5DED\u5DEE"+ - "\u5DEF\u5DF0\u5DF1\u5DF2\u5DF3\u5DF4\u5DF5\u5DF6"+ - "\u5DF7\u5DF8\u5DF9\u5DFA\u5DFB\u5DFC\u5DFD\u5DFE"+ - "\u5DFF\u5E00\u5E01\u5E02\u5E03\u5E04\u5E05\u5E06"+ - "\u5E07\u5E08\u5E09\u5E0A\u5E0B\u5E0C\u5E0D\u5E0E"+ - "\u5E0F\u5E10\u5E11\u5E12\u5E13\u5E14\u5E15\u5E16"+ - "\u5E17\u5E18\u5E19\u5E1A\u5E1B\u5E1C\u5E1D\u5E1E"+ - "\u5E1F\u5E20\u5E21\u5E22\u5E23\u5E24\u5E25\u5E26"+ - "\u5E27\u5E28\u5E29\u5E2A\u5E2B\u5E2C\u5E2D\u5E2E"+ - "\u5E2F\u5E30\u5E31\u5E32\u5E33\u5E34\u5E35\u5E36"+ - "\u5E37\u5E38\u5E39\u5E3A\u5E3B\u5E3C\u5E3D\u5E3E"+ - "\u5E3F\u5E40\u5E41\u5E42\u5E43\u5E44\u5E45\u5E46"+ - "\u5E47\u5E48\u5E49\u5E4A\u5E4B\u5E4C\u5E4D\u5E4E"+ - "\u5E4F\u5E50\u5E51\u5E52\u5E53\u5E54\u5E55\u5E56"+ - "\u5E57\u5E58\u5E59\u5E5A\u5E5B\u5E5C\u5E5D\u5E5E"+ - "\u5E5F\u5E60\u5E61\u5E62\u5E63\u5E64\u5E65\u5E66"+ - "\u5E67\u5E68\u5E69\u5E6A\u5E6B\u5E6C\u5E6D\u5E6E"+ - "\u5E6F\u5E70\u5E71\u5E72\u5E73\u5E74\u5E75\u5E76"+ - "\u5E77\u5E78\u5E79\u5E7A\u5E7B\u5E7C\u5E7D\u5E7E"+ - "\u5E7F\u5E80\u5E81\u5E82\u5E83\u5E84\u5E85\u5E86"+ - "\u5E87\u5E88\u5E89\u5E8A\u5E8B\u5E8C\u5E8D\u5E8E"+ - "\u5E8F\u5E90\u5E91\u5E92\u5E93\u5E94\u5E95\u5E96"+ - "\u5E97\u5E98\u5E99\u5E9A\u5E9B\u5E9C\u5E9D\u5E9E"+ - "\u5E9F\u5EA0\u5EA1\u5EA2\u5EA3\u5EA4\u5EA5\u5EA6"+ - "\u5EA7\u5EA8\u5EA9\u5EAA\u5EAB\u5EAC\u5EAD\u5EAE"+ - "\u5EAF\u5EB0\u5EB1\u5EB2\u5EB3\u5EB4\u5EB5\u5EB6"+ - "\u5EB7\u5EB8\u5EB9\u5EBA\u5EBB\u5EBC\u5EBD\u5EBE"+ - "\u5EBF\u5EC0\u5EC1\u5EC2\u5EC3\u5EC4\u5EC5\u5EC6"+ - "\u5EC7\u5EC8\u5EC9\u5ECA\u5ECB\u5ECC\u5ECD\u5ECE"+ - "\u5ECF\u5ED0\u5ED1\u5ED2\u5ED3\u5ED4\u5ED5\u5ED6"+ - "\u5ED7\u5ED8\u5ED9\u5EDA\u5EDB\u5EDC\u5EDD\u5EDE"+ - "\u5EDF\u5EE0\u5EE1\u5EE2\u5EE3\u5EE4\u5EE5\u5EE6"+ - "\u5EE7\u5EE8\u5EE9\u5EEA\u5EEB\u5EEC\u5EED\u5EEE"+ - "\u5EEF\u5EF0\u5EF1\u5EF2\u5EF3\u5EF4\u5EF5\u5EF6"+ - "\u5EF7\u5EF8\u5EF9\u5EFA\u5EFB\u5EFC\u5EFD\u5EFE"+ - "\u5EFF\u5F00\u5F01\u5F02\u5F03\u5F04\u5F05\u5F06"+ - "\u5F07\u5F08\u5F09\u5F0A\u5F0B\u5F0C\u5F0D\u5F0E"+ - "\u5F0F\u5F10\u5F11\u5F12\u5F13\u5F14\u5F15\u5F16"+ - "\u5F17\u5F18\u5F19\u5F1A\u5F1B\u5F1C\u5F1D\u5F1E"+ - "\u5F1F\u5F20\u5F21\u5F22\u5F23\u5F24\u5F25\u5F26"+ - "\u5F27\u5F28\u5F29\u5F2A\u5F2B\u5F2C\u5F2D\u5F2E"+ - "\u5F2F\u5F30\u5F31\u5F32\u5F33\u5F34\u5F35\u5F36"+ - "\u5F37\u5F38\u5F39\u5F3A\u5F3B\u5F3C\u5F3D\u5F3E"+ - "\u5F3F\u5F40\u5F41\u5F42\u5F43\u5F44\u5F45\u5F46"+ - "\u5F47\u5F48\u5F49\u5F4A\u5F4B\u5F4C\u5F4D\u5F4E"+ - "\u5F4F\u5F50\u5F51\u5F52\u5F53\u5F54\u5F55\u5F56"+ - "\u5F57\u5F58\u5F59\u5F5A\u5F5B\u5F5C\u5F5D\u5F5E"+ - "\u5F5F\u5F60\u5F61\u5F62\u5F63\u5F64\u5F65\u5F66"+ - "\u5F67\u5F68\u5F69\u5F6A\u5F6B\u5F6C\u5F6D\u5F6E"+ - "\u5F6F\u5F70\u5F71\u5F72\u5F73\u5F74\u5F75\u5F76"+ - "\u5F77\u5F78\u5F79\u5F7A\u5F7B\u5F7C\u5F7D\u5F7E"+ - "\u5F7F\u5F80\u5F81\u5F82\u5F83\u5F84\u5F85\u5F86"+ - "\u5F87\u5F88\u5F89\u5F8A\u5F8B\u5F8C\u5F8D\u5F8E"+ - "\u5F8F\u5F90\u5F91\u5F92\u5F93\u5F94\u5F95\u5F96"+ - "\u5F97\u5F98\u5F99\u5F9A\u5F9B\u5F9C\u5F9D\u5F9E"+ - "\u5F9F\u5FA0\u5FA1\u5FA2\u5FA3\u5FA4\u5FA5\u5FA6"+ - "\u5FA7\u5FA8\u5FA9\u5FAA\u5FAB\u5FAC\u5FAD\u5FAE"+ - "\u5FAF\u5FB0\u5FB1\u5FB2\u5FB3\u5FB4\u5FB5\u5FB6"+ - "\u5FB7\u5FB8\u5FB9\u5FBA\u5FBB\u5FBC\u5FBD\uFE72"+ - "\u5FBE\u5FBF\u5FC0\u5FC1\u5FC2\u5FC3\u5FC4\u5FC5"+ - "\u5FC6\u5FC7\u5FC8\u5FC9\u5FCA\u5FCB\u5FCC\u5FCD"+ - "\u5FCE\u5FCF\u5FD0\u5FD1\u5FD2\u5FD3\u5FD4\u5FD5"+ - "\u5FD6\u5FD7\u5FD8\u5FD9\u5FDA\u5FDB\u5FDC\u5FDD"+ - "\u5FDE\u5FDF\u5FE0\u5FE1\u5FE2\u5FE3\u5FE4\u5FE5"+ - "\u5FE6\u5FE7\u5FE8\u5FE9\u5FEA\u5FEB\u5FEC\u5FED"+ - "\u5FEE\u5FEF\u5FF0\u5FF1\u5FF2\u5FF3\u5FF4\u5FF5"+ - "\u5FF6\u5FF7\u5FF8\u5FF9\u5FFA\u5FFB\u5FFC\u5FFD"+ - "\u5FFE\u5FFF\u6000\u6001\u6002\u6003\u6004\u6005"+ - "\u6006\u6007\u6008\u6009\u600A\u600B\u600C\u600D"+ - "\u600E\u600F\u6010\u6011\u6012\u6013\u6014\u6015"+ - "\u6016\u6017\u6018\u6019\u601A\u601B\u601C\u601D"+ - "\u601E\u601F\u6020\u6021\u6022\u6023\u6024\u6025"+ - "\u6026\u6027\u6028\u6029\u602A\u602B\u602C\u602D"+ - "\u602E\u602F\u6030\u6031\uFE78\u6032\u6033\u6034"+ - "\u6035\uFE77\u6036\u6037\u6038\u6039\u603A\u603B"+ - "\u603C\u603D\u603E\u603F\u6040\u6041\u6042\u6043"+ - "\u6044\u6045\u6046\u6047\u6048\u6049\u604A\u604B"+ - "\u604C\u604D\u604E\u604F\u6050\u6051\u6052\u6053"+ - "\u6054\u6055\u6056\u6057\u6058\u6059\u605A\u605B"+ - "\u605C\u605D\u605E\u605F\u6060\uFE7A\u6061\u6062"+ - "\u6063\u6064\u6065\u6066\u6067\u6068\u6069\u606A"+ - "\u606B\u606C\u606D\u606E\u606F\u6070\u6071\u6072"+ - "\u6073\u6074\u6075\u6076\u6077\u6078\u6079\u607A"+ - "\u607B\u607C\u607D\u607E\u607F\u6080\u6081\u6082"+ - "\u6083\u6084\u6085\u6086\u6087\u6088\u6089\u608A"+ - "\u608B\u608C\u608D\u608E\u608F\u6090\u6091\u6092"+ - "\u6093\u6094\u6095\u6096\u6097\u6098\u6099\u609A"+ - "\u609B\u609C\u609D\u609E\u609F\u60A0\u60A1\u60A2"+ - "\u60A3\u60A4\u60A5\u60A6\u60A7\u60A8\u60A9\u60AA"+ - "\u60AB\u60AC\u60AD\u60AE\u60AF\u60B0\u60B1\u60B2"+ - "\u60B3\u60B4\u60B5\u60B6\u60B7\u60B8\u60B9\u60BA"+ - "\u60BB\u60BC\u60BD\u60BE\u60BF\u60C0\u60C1\u60C2"+ - "\u60C3\u60C4\u60C5\u60C6\u60C7\u60C8\u60C9\u60CA"+ - "\u60CB\u60CC\u60CD\u60CE\u60CF\u60D0\u60D1\u60D2"+ - "\u60D3\u60D4\u60D5\u60D6\u60D7\u60D8\u60D9\u60DA"+ - "\u60DB\u60DC\u60DD\u60DE\u60DF\u60E0\u60E1\u60E2"+ - "\u60E3\u60E4\u60E5\u60E6\u60E7\u60E8\u60E9\u60EA"+ - "\u60EB\u60EC\u60ED\u60EE\u60EF\u60F0\u60F1\u60F2"+ - "\u60F3\u60F4\u60F5\u60F6\u60F7\u60F8\u60F9\u60FA"+ - "\u60FB\u60FC\u60FD\u60FE\u60FF\u6100\u6101\u6102"+ - "\u6103\u6104\u6105\u6106\u6107\u6108\u6109\u610A"+ - "\u610B\u610C\u610D\u610E\u610F\u6110\u6111\u6112"+ - "\u6113\u6114\u6115\u6116\u6117\u6118\u6119\u611A"+ - "\u611B\u611C\u611D\u611E\u611F\u6120\u6121\u6122"+ - "\u6123\u6124\u6125\u6126\u6127\u6128\u6129\u612A"+ - "\u612B\u612C\u612D\u612E\u612F\u6130\u6131\u6132"+ - "\u6133\u6134\u6135\u6136\u6137\u6138\u6139\u613A"+ - "\u613B\u613C\u613D\u613E\u613F\u6140\u6141\u6142"+ - "\u6143\u6144\u6145\u6146\u6147\u6148\u6149\u614A"+ - "\u614B\u614C\u614D\u614E\u614F\u6150\u6151\u6152"+ - "\u6153\u6154\u6155\u6156\u6157\u6158\uFE7B\u6159"+ - "\u615A\u615B\u615C\u615D\u615E\u615F\u6160\u6161"+ - "\u6162\u6163\u6164\u6165\u6166\u6167\u6168\u6169"+ - "\u616A\u616B\u616C\u616D\u616E\u616F\u6170\u6171"+ - "\u6172\u6173\u6174\u6175\u6176\u6177\u6178\u6179"+ - "\u617A\u617B\u617C\u617D\u617E\u617F\u6180\u6181"+ - "\u6182\u6183\u6184\u6185\u6186\u6187\u6188\u6189"+ - "\u618A\u618B\u618C\u618D\u618E\u618F\u6190\u6191"+ - "\u6192\u6193\u6194\u6195\u6196\u6197\u6198\u6199"+ - "\u619A\u619B\u619C\u619D\u619E\u619F\u61A0\u61A1"+ - "\u61A2\u61A3\u61A4\u61A5\u61A6\u61A7\u61A8\u61A9"+ - "\u61AA\u61AB\u61AC\u61AD\u61AE\u61AF\u61B0\u61B1"+ - "\u61B2\u61B3\u61B4\u61B5\u61B6\u61B7\u61B8\u61B9"+ - "\u61BA\u61BB\u61BC\u61BD\u61BE\u61BF\u61C0\u61C1"+ - "\u61C2\u61C3\u61C4\u61C5\u61C6\u61C7\u61C8\u61C9"+ - "\u61CA\u61CB\u61CC\u61CD\u61CE\u61CF\u61D0\u61D1"+ - "\u61D2\u61D3\u61D4\u61D5\u61D6\u61D7\u61D8\u61D9"+ - "\u61DA\u61DB\u61DC\u61DD\u61DE\u61DF\u61E0\u61E1"+ - "\u61E2\u61E3\u61E4\u61E5\u61E6\u61E7\u61E8\u61E9"+ - "\u61EA\u61EB\u61EC\u61ED\u61EE\u61EF\u61F0\u61F1"+ - "\u61F2\u61F3\u61F4\u61F5\u61F6\u61F7\u61F8\u61F9"+ - "\u61FA\u61FB\u61FC\u61FD\u61FE\u61FF\u6200\u6201"+ - "\u6202\u6203\u6204\u6205\u6206\u6207\u6208\u6209"+ - "\u620A\u620B\u620C\u620D\u620E\u620F\u6210\u6211"+ - "\u6212\u6213\u6214\u6215\u6216\u6217\u6218\u6219"+ - "\u621A\u621B\u621C\u621D\u621E\u621F\u6220\u6221"+ - "\u6222\u6223\u6224\u6225\u6226\u6227\u6228\u6229"+ - "\u622A\u622B\u622C\u622D\u622E\u622F\u6230\u6231"+ - "\u6232\u6233\u6234\u6235\u6236\u6237\u6238\u6239"+ - "\u623A\u623B\u623C\u623D\u623E\u623F\u6240\u6241"+ - "\u6242\u6243\u6244\u6245\u6246\u6247\u6248\u6249"+ - "\u624A\u624B\u624C\u624D\u624E\u624F\u6250\u6251"+ - "\u6252\u6253\u6254\u6255\u6256\u6257\u6258\u6259"+ - "\u625A\u625B\u625C\u625D\u625E\u625F\u6260\u6261"+ - "\u6262\u6263\u6264\u6265\u6266\u6267\u6268\u6269"+ - "\u626A\u626B\u626C\u626D\u626E\u626F\u6270\u6271"+ - "\u6272\u6273\u6274\u6275\u6276\u6277\u6278\u6279"+ - "\u627A\u627B\u627C\u627D\u627E\u627F\u6280\u6281"+ - "\u6282\u6283\u6284\u6285\u6286\u6287\u6288\u6289"+ - "\u628A\u628B\u628C\u628D\u628E\u628F\u6290\u6291"+ - "\u6292\u6293\u6294\u6295\u6296\u6297\u6298\u6299"+ - "\u629A\u629B\u629C\u629D\u629E\u629F\u62A0\u62A1"+ - "\u62A2\u62A3\u62A4\u62A5\u62A6\u62A7\u62A8\u62A9"+ - "\u62AA\u62AB\u62AC\u62AD\u62AE\u62AF\u62B0\u62B1"+ - "\u62B2\u62B3\u62B4\u62B5\u62B6\u62B7\u62B8\u62B9"+ - "\u62BA\u62BB\u62BC\u62BD\u62BE\u62BF\u62C0\u62C1"+ - "\u62C2\u62C3\u62C4\u62C5\u62C6\u62C7\u62C8\u62C9"+ - "\u62CA\u62CB\u62CC\u62CD\uFE7D\u62CE\u62CF\u62D0"+ - "\u62D1\u62D2\u62D3\u62D4\u62D5\u62D6\u62D7\u62D8"+ - "\u62D9\u62DA\u62DB\u62DC\u62DD\u62DE\u62DF\u62E0"+ - "\u62E1\uFE7C\u62E2\u62E3\u62E4\u62E5\u62E6\u62E7"+ - "\u62E8\u62E9\u62EA\u62EB\u62EC\u62ED\u62EE\u62EF"+ - "\u62F0\u62F1\u62F2\u62F3\u62F4\u62F5\u62F6\u62F7"+ - "\u62F8\u62F9\u62FA\u62FB\u62FC\u62FD\u62FE\u62FF"+ - "\u6300\u6301\u6302\u6303\u6304\u6305\u6306\u6307"+ - "\u6308\u6309\u630A\u630B\u630C\u630D\u630E\u630F"+ - "\u6310\u6311\u6312\u6313\u6314\u6315\u6316\u6317"+ - "\u6318\u6319\u631A\u631B\u631C\u631D\u631E\u631F"+ - "\u6320\u6321\u6322\u6323\u6324\u6325\u6326\u6327"+ - "\u6328\u6329\u632A\u632B\u632C\u632D\u632E\u632F"+ - "\u6330\u6331\u6332\u6333\u6334\u6335\u6336\u6337"+ - "\u6338\u6339\u633A\u633B\u633C\u633D\u633E\u633F"+ - "\u6340\u6341\u6342\u6343\u6344\u6345\u6346\u6347"+ - "\u6348\u6349\u634A\u634B\u634C\u634D\u634E\u634F"+ - "\u6350\u6351\u6352\u6353\u6354\u6355\u6356\u6357"+ - "\u6358\u6359\u635A\u635B\u635C\u635D\u635E\u635F"+ - "\u6360\u6361\u6362\u6363\u6364\u6365\u6366\u6367"+ - "\u6368\u6369\u636A\u636B\u636C\u636D\u636E\u636F"+ - "\u6370\u6371\u6372\u6373\u6374\u6375\u6376\u6377"+ - "\u6378\u6379\u637A\u637B\u637C\u637D\u637E\u637F"+ - "\u6380\u6381\u6382\u6383\u6384\u6385\u6386\u6387"+ - "\u6388\u6389\u638A\u638B\u638C\u638D\u638E\u638F"+ - "\u6390\u6391\u6392\u6393\u6394\u6395\u6396\u6397"+ - "\u6398\u6399\u639A\u639B\u639C\u639D\u639E\u639F"+ - "\u63A0\u63A1\u63A2\uFE80\u63A3\u63A4\u63A5\u63A6"+ - "\u63A7\uFE81\u63A8\u63A9\u63AA\u63AB\u63AC\u63AD"+ - "\u63AE\u63AF\u63B0\u63B1\u63B2\u63B3\u63B4\u63B5"+ - "\u63B6\u63B7\u63B8\u63B9\u63BA\u63BB\u63BC\u63BD"+ - "\u63BE\u63BF\u63C0\u63C1\u63C2\u63C3\u63C4\u63C5"+ - "\u63C6\u63C7\u63C8\u63C9\u63CA\u63CB\u63CC\u63CD"+ - "\u63CE\u63CF\u63D0\u63D1\u63D2\u63D3\u63D4\u63D5"+ - "\u63D6\u63D7\u63D8\u63D9\u63DA\u63DB\u63DC\u63DD"+ - "\u63DE\u63DF\u63E0\u63E1\u63E2\u63E3\u63E4\u63E5"+ - "\u63E6\u63E7\u63E8\u63E9\u63EA\u63EB\u63EC\u63ED"+ - "\u63EE\u63EF\u63F0\u63F1\u63F2\u63F3\u63F4\u63F5"+ - "\u63F6\u63F7\u63F8\u63F9\uFE82\u63FA\u63FB\u63FC"+ - "\u63FD\u63FE\u63FF\u6400\u6401\u6402\u6403\u6404"+ - "\u6405\u6406\u6407\u6408\u6409\uFE83\u640A\u640B"+ - "\u640C\u640D\u640E\u640F\u6410\u6411\u6412\u6413"+ - "\u6414\u6415\u6416\u6417\u6418\u6419\u641A\u641B"+ - "\u641C\u641D\u641E\u641F\u6420\u6421\u6422\u6423"+ - "\u6424\u6425\u6426\u6427\u6428\u6429\u642A\u642B"+ - "\u642C\u642D\u642E\u642F\u6430\u6431\u6432\u6433"+ - "\u6434\u6435\u6436\u6437\u6438\u6439\u643A\u643B"+ - "\u643C\u643D\u643E\u643F\u6440\u6441\u6442\u6443"+ - "\u6444\u6445\u6446\u6447\u6448\u6449\u644A\u644B"+ - "\u644C\u644D\u644E\u644F\u6450\u6451\u6452\u6453"+ - "\u6454\u6455\u6456\u6457\u6458\u6459\u645A\u645B"+ - "\u645C\u645D\u645E\u645F\u6460\u6461\u6462\u6463"+ - "\u6464\u6465\u6466\u6467\u6468\u6469\u646A\u646B"+ - "\u646C\u646D\u646E\u646F\u6470\u6471\u6472\u6473"+ - "\u6474\u6475\u6476\u6477\u6478\u6479\u647A\u647B"+ - "\u647C\u647D\u647E\u647F\u6480\u6481\u6482\u6483"+ - "\u6484\u6485\u6486\u6487\u6488\u6489\u648A\u648B"+ - "\u648C\u648D\u648E\u648F\u6490\u6491\u6492\u6493"+ - "\u6494\u6495\u6496\u6497\u6498\u6499\u649A\u649B"+ - "\u649C\u649D\u649E\u649F\u64A0\u64A1\u64A2\u64A3"+ - "\u64A4\u64A5\u64A6\u64A7\u64A8\u64A9\u64AA\u64AB"+ - "\u64AC\u64AD\u64AE\u64AF\u64B0\u64B1\u64B2\u64B3"+ - "\u64B4\u64B5\u64B6\u64B7\u64B8\u64B9\u64BA\u64BB"+ - "\u64BC\u64BD\u64BE\u64BF\u64C0\u64C1\u64C2\u64C3"+ - "\u64C4\u64C5\u64C6\u64C7\u64C8\u64C9\u64CA\u64CB"+ - "\u64CC\u64CD\u64CE\u64CF\u64D0\u64D1\u64D2\u64D3"+ - "\u64D4\u64D5\u64D6\u64D7\u64D8\u64D9\u64DA\u64DB"+ - "\u64DC\u64DD\u64DE\u64DF\u64E0\u64E1\u64E2\u64E3"+ - "\u64E4\u64E5\u64E6\u64E7\u64E8\u64E9\u64EA\u64EB"+ - "\u64EC\u64ED\u64EE\u64EF\u64F0\u64F1\u64F2\u64F3"+ - "\u64F4\u64F5\u64F6\u64F7\u64F8\u64F9\u64FA\u64FB"+ - "\u64FC\u64FD\u64FE\u64FF\u6500\u6501\u6502\u6503"+ - "\u6504\u6505\u6506\u6507\u6508\u6509\u650A\u650B"+ - "\u650C\u650D\u650E\u650F\u6510\u6511\u6512\u6513"+ - "\u6514\u6515\u6516\u6517\u6518\u6519\u651A\u651B"+ - "\u651C\u651D\u651E\u651F\u6520\u6521\u6522\u6523"+ - "\u6524\u6525\u6526\u6527\u6528\u6529\u652A\u652B"+ - "\u652C\u652D\u652E\u652F\u6530\u6531\u6532\u6533"+ - "\u6534\u6535\u6536\u6537\u6538\u6539\u653A\u653B"+ - "\u653C\u653D\u653E\u653F\u6540\u6541\u6542\u6543"+ - "\u6544\u6545\u6546\u6547\u6548\u6549\u654A\u654B"+ - "\u654C\u654D\u654E\u654F\u6550\u6551\u6552\u6553"+ - "\u6554\u6555\u6556\u6557\u6558\u6559\u655A\u655B"+ - "\u655C\u655D\u655E\u655F\u6560\u6561\u6562\u6563"+ - "\u6564\u6565\u6566\u6567\u6568\u6569\u656A\u656B"+ - "\u656C\u656D\u656E\u656F\u6570\u6571\u6572\u6573"+ - "\u6574\u6575\u6576\u6577\u6578\u6579\u657A\u657B"+ - "\u657C\u657D\u657E\u657F\u6580\u6581\u6582\u6583"+ - "\u6584\u6585\u6586\u6587\u6588\u6589\u658A\u658B"+ - "\u658C\u658D\u658E\u658F\u6590\u6591\u6592\u6593"+ - "\u6594\u6595\u6596\u6597\u6598\u6599\u659A\u659B"+ - "\u659C\u659D\u659E\u659F\u65A0\u65A1\u65A2\u65A3"+ - "\u65A4\u65A5\u65A6\u65A7\u65A8\u65A9\u65AA\u65AB"+ - "\u65AC\u65AD\u65AE\u65AF\u65B0\u65B1\u65B2\u65B3"+ - "\u65B4\u65B5\u65B6\u65B7\u65B8\u65B9\u65BA\u65BB"+ - "\u65BC\u65BD\u65BE\u65BF\u65C0\u65C1\u65C2\uFE85"+ - "\u65C3\u65C4\u65C5\u65C6\u65C7\u65C8\u65C9\u65CA"+ - "\u65CB\u65CC\u65CD\u65CE\u65CF\u65D0\u65D1\u65D2"+ - "\u65D3\u65D4\u65D5\u65D6\u65D7\u65D8\u65D9\u65DA"+ - "\u65DB\u65DC\u65DD\u65DE\u65DF\u65E0\u65E1\u65E2"+ - "\u65E3\u65E4\u65E5\u65E6\u65E7\u65E8\u65E9\u65EA"+ - "\u65EB\u65EC\u65ED\u65EE\u65EF\u65F0\u65F1\u65F2"+ - "\u65F3\u65F4\uFE86\u65F5\u65F6\uFE87\u65F7\u65F8"+ - "\u65F9\u65FA\uFE88\uFE89\u65FB\uFE8A\uFE8B\u65FC"+ - "\u65FD\u65FE\u65FF\u6600\u6601\u6602\u6603\u6604"+ - "\u6605\u6606\u6607\u6608\u6609\u660A\u660B\u660C"+ - "\u660D\u660E\u660F\uFE8D\u6610\u6611\u6612\uFE8C"+ - "\u6613\u6614\u6615\u6616\u6617\u6618\u6619\u661A"+ - "\u661B\u661C\u661D\u661E\u661F\u6620\u6621\u6622"+ - "\u6623\u6624\u6625\u6626\u6627\u6628\uFE8F\uFE8E"+ - "\u6629\u662A\u662B\u662C\u662D\u662E\u662F\u6630"+ - "\u6631\u6632\u6633\u6634\u6635\u6636\u6637\u6638"+ - "\u6639\u663A\u663B\u663C\u663D\u663E\u663F\u6640"+ - "\u6641\u6642\u6643\u6644\u6645\u6646\u6647\u6648"+ - "\u6649\u664A\u664B\u664C\u664D\u664E\u664F\u6650"+ - "\u6651\u6652\u6653\u6654\u6655\u6656\u6657\u6658"+ - "\u6659\u665A\u665B\u665C\u665D\u665E\u665F\u6660"+ - "\u6661\u6662\u6663\u6664\u6665\u6666\u6667\u6668"+ - "\u6669\u666A\u666B\u666C\u666D\u666E\u666F\u6670"+ - "\u6671\u6672\u6673\u6674\u6675\u6676\u6677\u6678"+ - "\u6679\u667A\u667B\u667C\u667D\u667E\u667F\u6680"+ - "\u6681\u6682\u6683\u6684\u6685\u6686\u6687\u6688"+ - "\u6689\u668A\u668B\u668C\u668D\u668E\u668F\u6690"+ - "\u6691\u6692\u6693\u6694\u6695\u6696\u6697\u6698"+ - "\u6699\u669A\u669B\u669C\u669D\u669E\u669F\u66A0"+ - "\u66A1\u66A2\u66A3\u66A4\u66A5\u66A6\u66A7\u66A8"+ - "\u66A9\u66AA\u66AB\u66AC\u66AD\u66AE\u66AF\u66B0"+ - "\u66B1\u66B2\u66B3\u66B4\u66B5\u66B6\u66B7\u66B8"+ - "\u66B9\u66BA\u66BB\u66BC\u66BD\u66BE\u66BF\u66C0"+ - "\u66C1\u66C2\u66C3\u66C4\u66C5\u66C6\u66C7\u66C8"+ - "\u66C9\u66CA\u66CB\u66CC\u66CD\u66CE\u66CF\u66D0"+ - "\u66D1\u66D2\u66D3\u66D4\u66D5\u66D6\u66D7\u66D8"+ - "\u66D9\u66DA\u66DB\u66DC\u66DD\u66DE\u66DF\u66E0"+ - "\u66E1\u66E2\u66E3\u66E4\u66E5\u66E6\u66E7\u66E8"+ - "\u66E9\u66EA\u66EB\u66EC\u66ED\u66EE\u66EF\u66F0"+ - "\u66F1\u66F2\u66F3\u66F4\u66F5\u66F6\u66F7\u66F8"+ - "\u66F9\u66FA\u66FB\u66FC\u66FD\u66FE\u66FF\u6700"+ - "\u6701\u6702\u6703\u6704\u6705\u6706\u6707\u6708"+ - "\u6709\u670A\u670B\u670C\u670D\u670E\u670F\u6710"+ - "\u6711\u6712\u6713\u6714\u6715\u6716\u6717\u6718"+ - "\u6719\u671A\u671B\u671C\u671D\u671E\u671F\u6720"+ - "\u6721\u6722\u6723\u6724\u6725\u6726\u6727\u6728"+ - "\u6729\u672A\u672B\u672C\u672D\u672E\u672F\u6730"+ - "\u6731\u6732\u6733\u6734\u6735\u6736\u6737\u6738"+ - "\u6739\u673A\u673B\u673C\u673D\u673E\u673F\u6740"+ - "\u6741\u6742\u6743\u6744\u6745\u6746\u6747\u6748"+ - "\u6749\u674A\u674B\u674C\u674D\u674E\u674F\u6750"+ - "\u6751\u6752\u6753\u6754\u6755\u6756\u6757\u6758"+ - "\u6759\u675A\u675B\u675C\u675D\u675E\u675F\u6760"+ - "\u6761\u6762\u6763\u6764\u6765\u6766\u6767\u6768"+ - "\u6769\u676A\u676B\u676C\u676D\u676E\u676F\u6770"+ - "\u6771\u6772\u6773\u6774\u6775\u6776\u6777\u6778"+ - "\u6779\u677A\u677B\u677C\u677D\u677E\u677F\u6780"+ - "\u6781\u6782\u6783\u6784\u6785\u6786\u6787\u6788"+ - "\u6789\u678A\u678B\u678C\u678D\u678E\u678F\u6790"+ - "\u6791\u6792\u6793\u6794\u6795\u6796\u6797\u6798"+ - "\u6799\u679A\u679B\u679C\u679D\u679E\u679F\u67A0"+ - "\u67A1\u67A2\u67A3\u67A4\u67A5\u67A6\u67A7\u67A8"+ - "\u67A9\u67AA\u67AB\u67AC\u67AD\u67AE\u67AF\u67B0"+ - "\u67B1\u67B2\u67B3\u67B4\u67B5\u67B6\u67B7\u67B8"+ - "\u67B9\u67BA\u67BB\u67BC\u67BD\u67BE\u67BF\u67C0"+ - "\u67C1\u67C2\u67C3\u67C4\u67C5\u67C6\u67C7\u67C8"+ - "\u67C9\u67CA\u67CB\u67CC\u67CD\u67CE\u67CF\u67D0"+ - "\u67D1\u67D2\u67D3\u67D4\u67D5\u67D6\u67D7\u67D8"+ - "\u67D9\u67DA\u67DB\u67DC\u67DD\u67DE\u67DF\u67E0"+ - "\u67E1\u67E2\u67E3\u67E4\u67E5\u67E6\u67E7\u67E8"+ - "\u67E9\u67EA\u67EB\u67EC\u67ED\u67EE\u67EF\u67F0"+ - "\u67F1\u67F2\u67F3\u67F4\u67F5\u67F6\u67F7\u67F8"+ - "\u67F9\u67FA\u67FB\u67FC\u67FD\u67FE\u67FF\u6800"+ - "\u6801\u6802\u6803\u6804\u6805\u6806\u6807\u6808"+ - "\u6809\u680A\u680B\u680C\u680D\u680E\u680F\u6810"+ - "\u6811\u6812\u6813\u6814\u6815\u6816\u6817\u6818"+ - "\u6819\u681A\u681B\u681C\u681D\u681E\u681F\u6820"+ - "\u6821\u6822\u6823\u6824\u6825\u6826\u6827\u6828"+ - "\u6829\u682A\u682B\u682C\u682D\u682E\u682F\u6830"+ - "\u6831\u6832\u6833\u6834\u6835\u6836\u6837\u6838"+ - "\u6839\u683A\u683B\u683C\u683D\u683E\u683F\u6840"+ - "\u6841\u6842\u6843\u6844\u6845\u6846\u6847\u6848"+ - "\u6849\u684A\u684B\u684C\u684D\u684E\u684F\u6850"+ - "\u6851\u6852\u6853\u6854\u6855\u6856\u6857\u6858"+ - "\u6859\u685A\u685B\u685C\u685D\u685E\u685F\u6860"+ - "\u6861\u6862\u6863\u6864\u6865\u6866\u6867\u6868"+ - "\u6869\u686A\u686B\u686C\u686D\u686E\u686F\u6870"+ - "\u6871\u6872\u6873\u6874\u6875\u6876\u6877\u6878"+ - "\u6879\u687A\u687B\u687C\u687D\u687E\u687F\u6880"+ - "\u6881\u6882\u6883\u6884\u6885\u6886\u6887\u6888"+ - "\u6889\u688A\u688B\u688C\u688D\u688E\u688F\u6890"+ - "\u6891\u6892\u6893\u6894\u6895\u6896\u6897\u6898"+ - "\u6899\u689A\u689B\u689C\u689D\u689E\u689F\u68A0"+ - "\u68A1\u68A2\u68A3\u68A4\u68A5\u68A6\u68A7\u68A8"+ - "\u68A9\u68AA\u68AB\u68AC\u68AD\u68AE\u68AF\u68B0"+ - "\u68B1\u68B2\u68B3\u68B4\u68B5\u68B6\u68B7\u68B8"+ - "\u68B9\u68BA\u68BB\u68BC\u68BD\u68BE\u68BF\u68C0"+ - "\u68C1\u68C2\u68C3\u68C4\u68C5\u68C6\u68C7\u68C8"+ - "\u68C9\u68CA\u68CB\u68CC\u68CD\u68CE\u68CF\u68D0"+ - "\u68D1\u68D2\u68D3\u68D4\u68D5\u68D6\u68D7\u68D8"+ - "\u68D9\u68DA\u68DB\u68DC\u68DD\u68DE\u68DF\u68E0"+ - "\u68E1\u68E2\u68E3\u68E4\u68E5\u68E6\u68E7\uFE96"+ - "\u68E8\u68E9\u68EA\u68EB\u68EC\u68ED\u68EE\u68EF"+ - "\u68F0\u68F1\u68F2\u68F3\u68F4\u68F5\u68F6\u68F7"+ - "\u68F8\u68F9\u68FA\u68FB\u68FC\u68FD\u68FE\u68FF"+ - "\u6900\u6901\u6902\u6903\u6904\u6905\u6906\u6907"+ - "\u6908\u6909\u690A\u690B\u690C\u690D\u690E\uFE93"+ - "\uFE94\uFE95\uFE97\uFE92\u690F\u6910\u6911\u6912"+ - "\u6913\u6914\u6915\u6916\u6917\u6918\u6919\u691A"+ - "\u691B\u691C\u691D\u691E\u691F\u6920\u6921\u6922"+ - "\u6923\u6924\u6925\u6926\u6927\u6928\u6929\u692A"+ - "\u692B\u692C\u692D\u692E\u692F\u6930\u6931\u6932"+ - "\u6933\u6934\u6935\u6936\u6937\u6938\u6939\u693A"+ - "\u693B\u693C\u693D\u693E\u693F\u6940\u6941\u6942"+ - "\u6943\u6944\u6945\u6946\u6947\u6948\u6949\u694A"+ - "\u694B\u694C\u694D\u694E\u694F\u6950\u6951\u6952"+ - "\u6953\u6954\u6955\u6956\u6957\u6958\u6959\u695A"+ - "\u695B\u695C\u695D\u695E\u695F\u6960\u6961\u6962"+ - "\u6963\u6964\u6965\u6966\u6967\u6968\u6969\u696A"+ - "\u696B\u696C\u696D\u696E\u696F\u6970\u6971\u6972"+ - "\u6973\u6974\u6975\u6976\u6977\u6978\u6979\u697A"+ - "\u697B\u697C\u697D\uFE98\uFE99\uFE9A\uFE9B\uFE9C"+ - "\uFE9D\uFE9E\u697E\u697F\u6980\u6981\u6982\u6983"+ - "\u6984\u6985\u6986\u6987\u6988\u6989\u698A\u698B"+ - "\u698C\u698D\u698E\u698F\u6990\u6991\u6992\u6993"+ - "\u6994\u6995\u6996\u6997\u6998\u6999\u699A\u699B"+ - "\u699C\u699D\u699E\u699F\u69A0\u69A1\u69A2\u69A3"+ - "\u69A4\u69A5\u69A6\u69A7\u69A8\u69A9\u69AA\u69AB"+ - "\u69AC\u69AD\u69AE\u69AF\u69B0\u69B1\u69B2\u69B3"+ - "\u69B4\u69B5\u69B6\u69B7\u69B8\u69B9\u69BA\u69BB"+ - "\u69BC\u69BD\u69BE\u69BF\u69C0\u69C1\u69C2\u69C3"+ - "\u69C4\u69C5\u69C6\u69C7\u69C8\u69C9\u69CA\u69CB"+ - "\u69CC\u69CD\u69CE\u69CF\u69D0\u69D1\u69D2\u69D3"+ - "\u69D4\u69D5\u69D6\u69D7\u69D8\u69D9\u69DA\u69DB"+ - "\u69DC\u69DD\u69DE\u69DF\u69E0\u69E1\u69E2\u69E3"+ - "\u69E4\u69E5\u69E6\u69E7\u69E8\u69E9\u69EA\u69EB"+ - "\u69EC\u69ED\u69EE\u69EF\u69F0\u69F1\u69F2\u69F3"+ - "\u69F4\u69F5\u69F6\u69F7\u69F8\u69F9\u69FA\u69FB"+ - "\u69FC\u69FD\u69FE\u69FF\u6A00\u6A01\u6A02\u6A03"+ - "\u6A04\u6A05\u6A06\u6A07\u6A08\u6A09\u6A0A\u6A0B"+ - "\u6A0C\u6A0D\u6A0E\u6A0F\u6A10\u6A11\uFE9F\u6A12"+ - "\u6A13\u6A14\u6A15\u6A16\u6A17\u6A18\u6A19\u6A1A"+ - "\u6A1B\u6A1C\u6A1D\u6A1E\u6A1F\u6A20\u6A21\u6A22"+ - "\u6A23\u6A24\u6A25\u6A26\u6A27\u6A28\u6A29\u6A2A"+ - "\u6A2B\u6A2C\u6A2D\u6A2E\u6A2F\u6A30\u6A31\u6A32"+ - "\u6A33\u6A34\u6A35\u6A36\u6A37\u6A38\u6A39\u6A3A"+ - "\u6A3B\u6A3C\u6A3D\u6A3E\u6A3F\u6A40\u6A41\u6A42"+ - "\u6A43\u6A44\u6A45\u6A46\u6A47\u6A48\u6A49\u6A4A"+ - "\u6A4B\u6A4C\u6A4D\u6A4E\u6A4F\u6A50\u6A51\u6A52"+ - "\u6A53\u6A54\u6A55\u6A56\u6A57\u6A58\u6A59\u6A5A"+ - "\u6A5B\u6A5C\u6A5D\u6A5E\u6A5F\u6A60\u6A61\u6A62"+ - "\uD2BB\uB6A1\u8140\uC6DF\u8141\u8142\u8143\uCDF2"+ - "\uD5C9\uC8FD\uC9CF\uCFC2\uD8A2\uB2BB\uD3EB\u8144"+ - "\uD8A4\uB3F3\u8145\uD7A8\uC7D2\uD8A7\uCAC0\u8146"+ - "\uC7F0\uB1FB\uD2B5\uB4D4\uB6AB\uCBBF\uD8A9\u8147"+ - "\u8148\u8149\uB6AA\u814A\uC1BD\uD1CF\u814B\uC9A5"+ - "\uD8AD\u814C\uB8F6\uD1BE\uE3DC\uD6D0\u814D\u814E"+ - "\uB7E1\u814F\uB4AE\u8150\uC1D9\u8151\uD8BC\u8152"+ - "\uCDE8\uB5A4\uCEAA\uD6F7\u8153\uC0F6\uBED9\uD8AF"+ - "\u8154\u8155\u8156\uC4CB\u8157\uBEC3\u8158\uD8B1"+ - "\uC3B4\uD2E5\u8159\uD6AE\uCEDA\uD5A7\uBAF5\uB7A6"+ - "\uC0D6\u815A\uC6B9\uC5D2\uC7C7\u815B\uB9D4\u815C"+ - "\uB3CB\uD2D2\u815D\u815E\uD8BF\uBEC5\uC6F2\uD2B2"+ - "\uCFB0\uCFE7\u815F\u8160\u8161\u8162\uCAE9\u8163"+ - "\u8164\uD8C0\u8165\u8166\u8167\u8168\u8169\u816A"+ - "\uC2F2\uC2D2\u816B\uC8E9\u816C\u816D\u816E\u816F"+ - "\u8170\u8171\u8172\u8173\u8174\u8175\uC7AC\u8176"+ - "\u8177\u8178\u8179\u817A\u817B\u817C\uC1CB\u817D"+ - "\uD3E8\uD5F9\u817E\uCAC2\uB6FE\uD8A1\uD3DA\uBFF7"+ - "\u8180\uD4C6\uBBA5\uD8C1\uCEE5\uBEAE\u8181\u8182"+ - "\uD8A8\u8183\uD1C7\uD0A9\u8184\u8185\u8186\uD8BD"+ - "\uD9EF\uCDF6\uBFBA\u8187\uBDBB\uBAA5\uD2E0\uB2FA"+ - "\uBAE0\uC4B6\u8188\uCFED\uBEA9\uCDA4\uC1C1\u8189"+ - "\u818A\u818B\uC7D7\uD9F1\u818C\uD9F4\u818D\u818E"+ - "\u818F\u8190\uC8CB\uD8E9\u8191\u8192\u8193\uD2DA"+ - "\uCAB2\uC8CA\uD8EC\uD8EA\uD8C6\uBDF6\uC6CD\uB3F0"+ - "\u8194\uD8EB\uBDF1\uBDE9\u8195\uC8D4\uB4D3\u8196"+ - "\u8197\uC2D8\u8198\uB2D6\uD7D0\uCACB\uCBFB\uD5CC"+ - "\uB8B6\uCFC9\u8199\u819A\u819B\uD9DA\uD8F0\uC7AA"+ - "\u819C\uD8EE\u819D\uB4FA\uC1EE\uD2D4\u819E\u819F"+ - "\uD8ED\u81A0\uD2C7\uD8EF\uC3C7\u81A1\u81A2\u81A3"+ - "\uD1F6\u81A4\uD6D9\uD8F2\u81A5\uD8F5\uBCFE\uBCDB"+ - "\u81A6\u81A7\u81A8\uC8CE\u81A9\uB7DD\u81AA\uB7C2"+ - "\u81AB\uC6F3\u81AC\u81AD\u81AE\u81AF\u81B0\u81B1"+ - "\u81B2\uD8F8\uD2C1\u81B3\u81B4\uCEE9\uBCBF\uB7FC"+ - "\uB7A5\uD0DD\u81B5\u81B6\u81B7\u81B8\u81B9\uD6DA"+ - "\uD3C5\uBBEF\uBBE1\uD8F1\u81BA\u81BB\uC9A1\uCEB0"+ - "\uB4AB\u81BC\uD8F3\u81BD\uC9CB\uD8F6\uC2D7\uD8F7"+ - "\u81BE\u81BF\uCEB1\uD8F9\u81C0\u81C1\u81C2\uB2AE"+ - "\uB9C0\u81C3\uD9A3\u81C4\uB0E9\u81C5\uC1E6\u81C6"+ - "\uC9EC\u81C7\uCBC5\u81C8\uCBC6\uD9A4\u81C9\u81CA"+ - "\u81CB\u81CC\u81CD\uB5E8\u81CE\u81CF\uB5AB\u81D0"+ - "\u81D1\u81D2\u81D3\u81D4\u81D5\uCEBB\uB5CD\uD7A1"+ - "\uD7F4\uD3D3\u81D6\uCCE5\u81D7\uBACE\u81D8\uD9A2"+ - "\uD9DC\uD3E0\uD8FD\uB7F0\uD7F7\uD8FE\uD8FA\uD9A1"+ - "\uC4E3\u81D9\u81DA\uD3B6\uD8F4\uD9DD\u81DB\uD8FB"+ - "\u81DC\uC5E5\u81DD\u81DE\uC0D0\u81DF\u81E0\uD1F0"+ - "\uB0DB\u81E1\u81E2\uBCD1\uD9A6\u81E3\uD9A5\u81E4"+ - "\u81E5\u81E6\u81E7\uD9AC\uD9AE\u81E8\uD9AB\uCAB9"+ - "\u81E9\u81EA\u81EB\uD9A9\uD6B6\u81EC\u81ED\u81EE"+ - "\uB3DE\uD9A8\u81EF\uC0FD\u81F0\uCACC\u81F1\uD9AA"+ - "\u81F2\uD9A7\u81F3\u81F4\uD9B0\u81F5\u81F6\uB6B1"+ - "\u81F7\u81F8\u81F9\uB9A9\u81FA\uD2C0\u81FB\u81FC"+ - "\uCFC0\u81FD\u81FE\uC2C2\u8240\uBDC4\uD5EC\uB2E0"+ - "\uC7C8\uBFEB\uD9AD\u8241\uD9AF\u8242\uCEEA\uBAEE"+ - "\u8243\u8244\u8245\u8246\u8247\uC7D6\u8248\u8249"+ - "\u824A\u824B\u824C\u824D\u824E\u824F\u8250\uB1E3"+ - "\u8251\u8252\u8253\uB4D9\uB6ED\uD9B4\u8254\u8255"+ - "\u8256\u8257\uBFA1\u8258\u8259\u825A\uD9DE\uC7CE"+ - "\uC0FE\uD9B8\u825B\u825C\u825D\u825E\u825F\uCBD7"+ - "\uB7FD\u8260\uD9B5\u8261\uD9B7\uB1A3\uD3E1\uD9B9"+ - "\u8262\uD0C5\u8263\uD9B6\u8264\u8265\uD9B1\u8266"+ - "\uD9B2\uC1A9\uD9B3\u8267\u8268\uBCF3\uD0DE\uB8A9"+ - "\u8269\uBEE3\u826A\uD9BD\u826B\u826C\u826D\u826E"+ - "\uD9BA\u826F\uB0B3\u8270\u8271\u8272\uD9C2\u8273"; - - private static final String innerEncoderIndex5= - "\u8274\u8275\u8276\u8277\u8278\u8279\u827A\u827B"+ - "\u827C\u827D\u827E\u8280\uD9C4\uB1B6\u8281\uD9BF"+ - "\u8282\u8283\uB5B9\u8284\uBEF3\u8285\u8286\u8287"+ - "\uCCC8\uBAF2\uD2D0\u8288\uD9C3\u8289\u828A\uBDE8"+ - "\u828B\uB3AB\u828C\u828D\u828E\uD9C5\uBEEB\u828F"+ - "\uD9C6\uD9BB\uC4DF\u8290\uD9BE\uD9C1\uD9C0\u8291"+ - "\u8292\u8293\u8294\u8295\u8296\u8297\u8298\u8299"+ - "\u829A\u829B\uD5AE\u829C\uD6B5\u829D\uC7E3\u829E"+ - "\u829F\u82A0\u82A1\uD9C8\u82A2\u82A3\u82A4\uBCD9"+ - "\uD9CA\u82A5\u82A6\u82A7\uD9BC\u82A8\uD9CB\uC6AB"+ - "\u82A9\u82AA\u82AB\u82AC\u82AD\uD9C9\u82AE\u82AF"+ - "\u82B0\u82B1\uD7F6\u82B2\uCDA3\u82B3\u82B4\u82B5"+ - "\u82B6\u82B7\u82B8\u82B9\u82BA\uBDA1\u82BB\u82BC"+ - "\u82BD\u82BE\u82BF\u82C0\uD9CC\u82C1\u82C2\u82C3"+ - "\u82C4\u82C5\u82C6\u82C7\u82C8\u82C9\uC5BC\uCDB5"+ - "\u82CA\u82CB\u82CC\uD9CD\u82CD\u82CE\uD9C7\uB3A5"+ - "\uBFFE\u82CF\u82D0\u82D1\u82D2\uB8B5\u82D3\u82D4"+ - "\uC0FC\u82D5\u82D6\u82D7\u82D8\uB0F8\u82D9\u82DA"+ - "\u82DB\u82DC\u82DD\u82DE\u82DF\u82E0\u82E1\u82E2"+ - "\u82E3\u82E4\u82E5\u82E6\u82E7\u82E8\u82E9\u82EA"+ - "\u82EB\u82EC\u82ED\uB4F6\u82EE\uD9CE\u82EF\uD9CF"+ - "\uB4A2\uD9D0\u82F0\u82F1\uB4DF\u82F2\u82F3\u82F4"+ - "\u82F5\u82F6\uB0C1\u82F7\u82F8\u82F9\u82FA\u82FB"+ - "\u82FC\u82FD\uD9D1\uC9B5\u82FE\u8340\u8341\u8342"+ - "\u8343\u8344\u8345\u8346\u8347\u8348\u8349\u834A"+ - "\u834B\u834C\u834D\u834E\u834F\u8350\u8351\uCFF1"+ - "\u8352\u8353\u8354\u8355\u8356\u8357\uD9D2\u8358"+ - "\u8359\u835A\uC1C5\u835B\u835C\u835D\u835E\u835F"+ - "\u8360\u8361\u8362\u8363\u8364\u8365\uD9D6\uC9AE"+ - "\u8366\u8367\u8368\u8369\uD9D5\uD9D4\uD9D7\u836A"+ - "\u836B\u836C\u836D\uCBDB\u836E\uBDA9\u836F\u8370"+ - "\u8371\u8372\u8373\uC6A7\u8374\u8375\u8376\u8377"+ - "\u8378\u8379\u837A\u837B\u837C\u837D\uD9D3\uD9D8"+ - "\u837E\u8380\u8381\uD9D9\u8382\u8383\u8384\u8385"+ - "\u8386\u8387\uC8E5\u8388\u8389\u838A\u838B\u838C"+ - "\u838D\u838E\u838F\u8390\u8391\u8392\u8393\u8394"+ - "\u8395\uC0DC\u8396\u8397\u8398\u8399\u839A\u839B"+ - "\u839C\u839D\u839E\u839F\u83A0\u83A1\u83A2\u83A3"+ - "\u83A4\u83A5\u83A6\u83A7\u83A8\u83A9\u83AA\u83AB"+ - "\u83AC\u83AD\u83AE\u83AF\u83B0\u83B1\u83B2\uB6F9"+ - "\uD8A3\uD4CA\u83B3\uD4AA\uD0D6\uB3E4\uD5D7\u83B4"+ - "\uCFC8\uB9E2\u83B5\uBFCB\u83B6\uC3E2\u83B7\u83B8"+ - "\u83B9\uB6D2\u83BA\u83BB\uCDC3\uD9EE\uD9F0\u83BC"+ - "\u83BD\u83BE\uB5B3\u83BF\uB6B5\u83C0\u83C1\u83C2"+ - "\u83C3\u83C4\uBEA4\u83C5\u83C6\uC8EB\u83C7\u83C8"+ - "\uC8AB\u83C9\u83CA\uB0CB\uB9AB\uC1F9\uD9E2\u83CB"+ - "\uC0BC\uB9B2\u83CC\uB9D8\uD0CB\uB1F8\uC6E4\uBEDF"+ - "\uB5E4\uD7C8\u83CD\uD1F8\uBCE6\uCADE\u83CE\u83CF"+ - "\uBCBD\uD9E6\uD8E7\u83D0\u83D1\uC4DA\u83D2\u83D3"+ - "\uB8D4\uC8BD\u83D4\u83D5\uB2E1\uD4D9\u83D6\u83D7"+ - "\u83D8\u83D9\uC3B0\u83DA\u83DB\uC3E1\uDAA2\uC8DF"+ - "\u83DC\uD0B4\u83DD\uBEFC\uC5A9\u83DE\u83DF\u83E0"+ - "\uB9DA\u83E1\uDAA3\u83E2\uD4A9\uDAA4\u83E3\u83E4"+ - "\u83E5\u83E6\u83E7\uD9FB\uB6AC\u83E8\u83E9\uB7EB"+ - "\uB1F9\uD9FC\uB3E5\uBEF6\u83EA\uBFF6\uD2B1\uC0E4"+ - "\u83EB\u83EC\u83ED\uB6B3\uD9FE\uD9FD\u83EE\u83EF"+ - "\uBEBB\u83F0\u83F1\u83F2\uC6E0\u83F3\uD7BC\uDAA1"+ - "\u83F4\uC1B9\u83F5\uB5F2\uC1E8\u83F6\u83F7\uBCF5"+ - "\u83F8\uB4D5\u83F9\u83FA\u83FB\u83FC\u83FD\u83FE"+ - "\u8440\u8441\u8442\uC1DD\u8443\uC4FD\u8444\u8445"+ - "\uBCB8\uB7B2\u8446\u8447\uB7EF\u8448\u8449\u844A"+ - "\u844B\u844C\u844D\uD9EC\u844E\uC6BE\u844F\uBFAD"+ - "\uBBCB\u8450\u8451\uB5CA\u8452\uDBC9\uD0D7\u8453"+ - "\uCDB9\uB0BC\uB3F6\uBBF7\uDBCA\uBAAF\u8454\uD4E4"+ - "\uB5B6\uB5F3\uD8D6\uC8D0\u8455\u8456\uB7D6\uC7D0"+ - "\uD8D7\u8457\uBFAF\u8458\u8459\uDBBB\uD8D8\u845A"+ - "\u845B\uD0CC\uBBAE\u845C\u845D\u845E\uEBBE\uC1D0"+ - "\uC1F5\uD4F2\uB8D5\uB4B4\u845F\uB3F5\u8460\u8461"+ - "\uC9BE\u8462\u8463\u8464\uC5D0\u8465\u8466\u8467"+ - "\uC5D9\uC0FB\u8468\uB1F0\u8469\uD8D9\uB9CE\u846A"+ - "\uB5BD\u846B\u846C\uD8DA\u846D\u846E\uD6C6\uCBA2"+ - "\uC8AF\uC9B2\uB4CC\uBFCC\u846F\uB9F4\u8470\uD8DB"+ - "\uD8DC\uB6E7\uBCC1\uCCEA\u8471\u8472\u8473\u8474"+ - "\u8475\u8476\uCFF7\u8477\uD8DD\uC7B0\u8478\u8479"+ - "\uB9D0\uBDA3\u847A\u847B\uCCDE\u847C\uC6CA\u847D"+ - "\u847E\u8480\u8481\u8482\uD8E0\u8483\uD8DE\u8484"+ - "\u8485\uD8DF\u8486\u8487\u8488\uB0FE\u8489\uBEE7"+ - "\u848A\uCAA3\uBCF4\u848B\u848C\u848D\u848E\uB8B1"+ - "\u848F\u8490\uB8EE\u8491\u8492\u8493\u8494\u8495"+ - "\u8496\u8497\u8498\u8499\u849A\uD8E2\u849B\uBDCB"+ - "\u849C\uD8E4\uD8E3\u849D\u849E\u849F\u84A0\u84A1"+ - "\uC5FC\u84A2\u84A3\u84A4\u84A5\u84A6\u84A7\u84A8"+ - "\uD8E5\u84A9\u84AA\uD8E6\u84AB\u84AC\u84AD\u84AE"+ - "\u84AF\u84B0\u84B1\uC1A6\u84B2\uC8B0\uB0EC\uB9A6"+ - "\uBCD3\uCEF1\uDBBD\uC1D3\u84B3\u84B4\u84B5\u84B6"+ - "\uB6AF\uD6FA\uC5AC\uBDD9\uDBBE\uDBBF\u84B7\u84B8"+ - "\u84B9\uC0F8\uBEA2\uC0CD\u84BA\u84BB\u84BC\u84BD"+ - "\u84BE\u84BF\u84C0\u84C1\u84C2\u84C3\uDBC0\uCAC6"+ - "\u84C4\u84C5\u84C6\uB2AA\u84C7\u84C8\u84C9\uD3C2"+ - "\u84CA\uC3E3\u84CB\uD1AB\u84CC\u84CD\u84CE\u84CF"+ - "\uDBC2\u84D0\uC0D5\u84D1\u84D2\u84D3\uDBC3\u84D4"+ - "\uBFB1\u84D5\u84D6\u84D7\u84D8\u84D9\u84DA\uC4BC"+ - "\u84DB\u84DC\u84DD\u84DE\uC7DA\u84DF\u84E0\u84E1"+ - "\u84E2\u84E3\u84E4\u84E5\u84E6\u84E7\u84E8\u84E9"+ - "\uDBC4\u84EA\u84EB\u84EC\u84ED\u84EE\u84EF\u84F0"+ - "\u84F1\uD9E8\uC9D7\u84F2\u84F3\u84F4\uB9B4\uCEF0"+ - "\uD4C8\u84F5\u84F6\u84F7\u84F8\uB0FC\uB4D2\u84F9"+ - "\uD0D9\u84FA\u84FB\u84FC\u84FD\uD9E9\u84FE\uDECB"+ - "\uD9EB\u8540\u8541\u8542\u8543\uD8B0\uBBAF\uB1B1"+ - "\u8544\uB3D7\uD8CE\u8545\u8546\uD4D1\u8547\u8548"+ - "\uBDB3\uBFEF\u8549\uCFBB\u854A\u854B\uD8D0\u854C"+ - "\u854D\u854E\uB7CB\u854F\u8550\u8551\uD8D1\u8552"+ - "\u8553\u8554\u8555\u8556\u8557\u8558\u8559\u855A"+ - "\u855B\uC6A5\uC7F8\uD2BD\u855C\u855D\uD8D2\uC4E4"+ - "\u855E\uCAAE\u855F\uC7A7\u8560\uD8A6\u8561\uC9FD"+ - "\uCEE7\uBBDC\uB0EB\u8562\u8563\u8564\uBBAA\uD0AD"+ - "\u8565\uB1B0\uD7E4\uD7BF\u8566\uB5A5\uC2F4\uC4CF"+ - "\u8567\u8568\uB2A9\u8569\uB2B7\u856A\uB1E5\uDFB2"+ - "\uD5BC\uBFA8\uC2AC\uD8D5\uC2B1\u856B\uD8D4\uCED4"+ - "\u856C\uDAE0\u856D\uCEC0\u856E\u856F\uD8B4\uC3AE"+ - "\uD3A1\uCEA3\u8570\uBCB4\uC8B4\uC2D1\u8571\uBEED"+ - "\uD0B6\u8572\uDAE1\u8573\u8574\u8575\u8576\uC7E4"+ - "\u8577\u8578\uB3A7\u8579\uB6F2\uCCFC\uC0FA\u857A"+ - "\u857B\uC0F7\u857C\uD1B9\uD1E1\uD8C7\u857D\u857E"+ - "\u8580\u8581\u8582\u8583\u8584\uB2DE\u8585\u8586"+ - "\uC0E5\u8587\uBAF1\u8588\u8589\uD8C8\u858A\uD4AD"+ - "\u858B\u858C\uCFE1\uD8C9\u858D\uD8CA\uCFC3\u858E"+ - "\uB3F8\uBEC7\u858F\u8590\u8591\u8592\uD8CB\u8593"+ - "\u8594\u8595\u8596\u8597\u8598\u8599\uDBCC\u859A"+ - "\u859B\u859C\u859D\uC8A5\u859E\u859F\u85A0\uCFD8"+ - "\u85A1\uC8FE\uB2CE\u85A2\u85A3\u85A4\u85A5\u85A6"+ - "\uD3D6\uB2E6\uBCB0\uD3D1\uCBAB\uB7B4\u85A7\u85A8"+ - "\u85A9\uB7A2\u85AA\u85AB\uCAE5\u85AC\uC8A1\uCADC"+ - "\uB1E4\uD0F0\u85AD\uC5D1\u85AE\u85AF\u85B0\uDBC5"+ - "\uB5FE\u85B1\u85B2\uBFDA\uB9C5\uBEE4\uC1ED\u85B3"+ - "\uDFB6\uDFB5\uD6BB\uBDD0\uD5D9\uB0C8\uB6A3\uBFC9"+ - "\uCCA8\uDFB3\uCAB7\uD3D2\u85B4\uD8CF\uD2B6\uBAC5"+ - "\uCBBE\uCCBE\u85B5\uDFB7\uB5F0\uDFB4\u85B6\u85B7"+ - "\u85B8\uD3F5\u85B9\uB3D4\uB8F7\u85BA\uDFBA\u85BB"+ - "\uBACF\uBCAA\uB5F5\u85BC\uCDAC\uC3FB\uBAF3\uC0F4"+ - "\uCDC2\uCFF2\uDFB8\uCFC5\u85BD\uC2C0\uDFB9\uC2F0"+ - "\u85BE\u85BF\u85C0\uBEFD\u85C1\uC1DF\uCDCC\uD2F7"+ - "\uB7CD\uDFC1\u85C2\uDFC4\u85C3\u85C4\uB7F1\uB0C9"+ - "\uB6D6\uB7D4\u85C5\uBAAC\uCCFD\uBFD4\uCBB1\uC6F4"+ - "\u85C6\uD6A8\uDFC5\u85C7\uCEE2\uB3B3\u85C8\u85C9"+ - "\uCEFC\uB4B5\u85CA\uCEC7\uBAF0\u85CB\uCEE1\u85CC"+ - "\uD1BD\u85CD\u85CE\uDFC0\u85CF\u85D0\uB4F4\u85D1"+ - "\uB3CA\u85D2\uB8E6\uDFBB\u85D3\u85D4\u85D5\u85D6"+ - "\uC4C5\u85D7\uDFBC\uDFBD\uDFBE\uC5BB\uDFBF\uDFC2"+ - "\uD4B1\uDFC3\u85D8\uC7BA\uCED8\u85D9\u85DA\u85DB"+ - "\u85DC\u85DD\uC4D8\u85DE\uDFCA\u85DF\uDFCF\u85E0"+ - "\uD6DC\u85E1\u85E2\u85E3\u85E4\u85E5\u85E6\u85E7"+ - "\u85E8\uDFC9\uDFDA\uCEB6\u85E9\uBAC7\uDFCE\uDFC8"+ - "\uC5DE\u85EA\u85EB\uC9EB\uBAF4\uC3FC\u85EC\u85ED"+ - "\uBED7\u85EE\uDFC6\u85EF\uDFCD\u85F0\uC5D8\u85F1"+ - "\u85F2\u85F3\u85F4\uD5A6\uBACD\u85F5\uBECC\uD3BD"+ - "\uB8C0\u85F6\uD6E4\u85F7\uDFC7\uB9BE\uBFA7\u85F8"+ - "\u85F9\uC1FC\uDFCB\uDFCC\u85FA\uDFD0\u85FB\u85FC"+ - "\u85FD\u85FE\u8640\uDFDB\uDFE5\u8641\uDFD7\uDFD6"+ - "\uD7C9\uDFE3\uDFE4\uE5EB\uD2A7\uDFD2\u8642\uBFA9"+ - "\u8643\uD4DB\u8644\uBFC8\uDFD4\u8645\u8646\u8647"+ - "\uCFCC\u8648\u8649\uDFDD\u864A\uD1CA\u864B\uDFDE"+ - "\uB0A7\uC6B7\uDFD3\u864C\uBAE5\u864D\uB6DF\uCDDB"+ - "\uB9FE\uD4D5\u864E\u864F\uDFDF\uCFEC\uB0A5\uDFE7"+ - "\uDFD1\uD1C6\uDFD5\uDFD8\uDFD9\uDFDC\u8650\uBBA9"+ - "\u8651\uDFE0\uDFE1\u8652\uDFE2\uDFE6\uDFE8\uD3B4"+ - "\u8653\u8654\u8655\u8656\u8657\uB8E7\uC5B6\uDFEA"+ - "\uC9DA\uC1A8\uC4C4\u8658\u8659\uBFDE\uCFF8\u865A"+ - "\u865B\u865C\uD5DC\uDFEE\u865D\u865E\u865F\u8660"+ - "\u8661\u8662\uB2B8\u8663\uBADF\uDFEC\u8664\uDBC1"+ - "\u8665\uD1E4\u8666\u8667\u8668\u8669\uCBF4\uB4BD"+ - "\u866A\uB0A6\u866B\u866C\u866D\u866E\u866F\uDFF1"+ - "\uCCC6\uDFF2\u8670\u8671\uDFED\u8672\u8673\u8674"+ - "\u8675\u8676\u8677\uDFE9\u8678\u8679\u867A\u867B"+ - "\uDFEB\u867C\uDFEF\uDFF0\uBBBD\u867D\u867E\uDFF3"+ - "\u8680\u8681\uDFF4\u8682\uBBA3\u8683\uCADB\uCEA8"+ - "\uE0A7\uB3AA\u8684\uE0A6\u8685\u8686\u8687\uE0A1"+ - "\u8688\u8689\u868A\u868B\uDFFE\u868C\uCDD9\uDFFC"+ - "\u868D\uDFFA\u868E\uBFD0\uD7C4\u868F\uC9CC\u8690"+ - "\u8691\uDFF8\uB0A1\u8692\u8693\u8694\u8695\u8696"+ - "\uDFFD\u8697\u8698\u8699\u869A\uDFFB\uE0A2\u869B"+ - "\u869C\u869D\u869E\u869F\uE0A8\u86A0\u86A1\u86A2"+ - "\u86A3\uB7C8\u86A4\u86A5\uC6A1\uC9B6\uC0B2\uDFF5"+ - "\u86A6\u86A7\uC5BE\u86A8\uD8C4\uDFF9\uC4F6\u86A9"+ - "\u86AA\u86AB\u86AC\u86AD\u86AE\uE0A3\uE0A4\uE0A5"+ - "\uD0A5\u86AF\u86B0\uE0B4\uCCE4\u86B1\uE0B1\u86B2"+ - "\uBFA6\uE0AF\uCEB9\uE0AB\uC9C6\u86B3\u86B4\uC0AE"+ - "\uE0AE\uBAED\uBAB0\uE0A9\u86B5\u86B6\u86B7\uDFF6"+ - "\u86B8\uE0B3\u86B9\u86BA\uE0B8\u86BB\u86BC\u86BD"+ - "\uB4AD\uE0B9\u86BE\u86BF\uCFB2\uBAC8\u86C0\uE0B0"+ - "\u86C1\u86C2\u86C3\u86C4\u86C5\u86C6\u86C7\uD0FA"+ - "\u86C8\u86C9\u86CA\u86CB\u86CC\u86CD\u86CE\u86CF"+ - "\u86D0\uE0AC\u86D1\uD4FB\u86D2\uDFF7\u86D3\uC5E7"+ - "\u86D4\uE0AD\u86D5\uD3F7\u86D6\uE0B6\uE0B7\u86D7"+ - "\u86D8\u86D9\u86DA\u86DB\uE0C4\uD0E1\u86DC\u86DD"+ - "\u86DE\uE0BC\u86DF\u86E0\uE0C9\uE0CA\u86E1\u86E2"+ - "\u86E3\uE0BE\uE0AA\uC9A4\uE0C1\u86E4\uE0B2\u86E5"+ - "\u86E6\u86E7\u86E8\u86E9\uCAC8\uE0C3\u86EA\uE0B5"+ - "\u86EB\uCECB\u86EC\uCBC3\uE0CD\uE0C6\uE0C2\u86ED"+ - "\uE0CB\u86EE\uE0BA\uE0BF\uE0C0\u86EF\u86F0\uE0C5"+ - "\u86F1\u86F2\uE0C7\uE0C8\u86F3\uE0CC\u86F4\uE0BB"+ - "\u86F5\u86F6\u86F7\u86F8\u86F9\uCBD4\uE0D5\u86FA"+ - "\uE0D6\uE0D2\u86FB\u86FC\u86FD\u86FE\u8740\u8741"+ - "\uE0D0\uBCCE\u8742\u8743\uE0D1\u8744\uB8C2\uD8C5"+ - "\u8745\u8746\u8747\u8748\u8749\u874A\u874B\u874C"+ - "\uD0EA\u874D\u874E\uC2EF\u874F\u8750\uE0CF\uE0BD"+ - "\u8751\u8752\u8753\uE0D4\uE0D3\u8754\u8755\uE0D7"+ - "\u8756\u8757\u8758\u8759\uE0DC\uE0D8\u875A\u875B"+ - "\u875C\uD6F6\uB3B0\u875D\uD7EC\u875E\uCBBB\u875F"+ - "\u8760\uE0DA\u8761\uCEFB\u8762\u8763\u8764\uBAD9"+ - "\u8765\u8766\u8767\u8768\u8769\u876A\u876B\u876C"+ - "\u876D\u876E\u876F\u8770\uE0E1\uE0DD\uD2AD\u8771"+ - "\u8772\u8773\u8774\u8775\uE0E2\u8776\u8777\uE0DB"+ - "\uE0D9\uE0DF\u8778\u8779\uE0E0\u877A\u877B\u877C"+ - "\u877D\u877E\uE0DE\u8780\uE0E4\u8781\u8782\u8783"+ - "\uC6F7\uD8AC\uD4EB\uE0E6\uCAC9\u8784\u8785\u8786"+ - "\u8787\uE0E5\u8788\u8789\u878A\u878B\uB8C1\u878C"+ - "\u878D\u878E\u878F\uE0E7\uE0E8\u8790\u8791\u8792"+ - "\u8793\u8794\u8795\u8796\u8797\uE0E9\uE0E3\u8798"+ - "\u8799\u879A\u879B\u879C\u879D\u879E\uBABF\uCCE7"+ - "\u879F\u87A0\u87A1\uE0EA\u87A2\u87A3\u87A4\u87A5"+ - "\u87A6\u87A7\u87A8\u87A9\u87AA\u87AB\u87AC\u87AD"+ - "\u87AE\u87AF\u87B0\uCFF9\u87B1\u87B2\u87B3\u87B4"+ - "\u87B5\u87B6\u87B7\u87B8\u87B9\u87BA\u87BB\uE0EB"+ - "\u87BC\u87BD\u87BE\u87BF\u87C0\u87C1\u87C2\uC8C2"+ - "\u87C3\u87C4\u87C5\u87C6\uBDC0\u87C7\u87C8\u87C9"+ - "\u87CA\u87CB\u87CC\u87CD\u87CE\u87CF\u87D0\u87D1"+ - "\u87D2\u87D3\uC4D2\u87D4\u87D5\u87D6\u87D7\u87D8"+ - "\u87D9\u87DA\u87DB\u87DC\uE0EC\u87DD\u87DE\uE0ED"+ - "\u87DF\u87E0\uC7F4\uCBC4\u87E1\uE0EE\uBBD8\uD8B6"+ - "\uD2F2\uE0EF\uCDC5\u87E2\uB6DA\u87E3\u87E4\u87E5"+ - "\u87E6\u87E7\u87E8\uE0F1\u87E9\uD4B0\u87EA\u87EB"+ - "\uC0A7\uB4D1\u87EC\u87ED\uCEA7\uE0F0\u87EE\u87EF"+ - "\u87F0\uE0F2\uB9CC\u87F1\u87F2\uB9FA\uCDBC\uE0F3"+ - "\u87F3\u87F4\u87F5\uC6D4\uE0F4\u87F6\uD4B2\u87F7"+ - "\uC8A6\uE0F6\uE0F5\u87F8\u87F9\u87FA\u87FB\u87FC"+ - "\u87FD\u87FE\u8840\u8841\u8842\u8843\u8844\u8845"+ - "\u8846\u8847\u8848\u8849\uE0F7\u884A\u884B\uCDC1"+ - "\u884C\u884D\u884E\uCAA5\u884F\u8850\u8851\u8852"+ - "\uD4DA\uDBD7\uDBD9\u8853\uDBD8\uB9E7\uDBDC\uDBDD"+ - "\uB5D8\u8854\u8855\uDBDA\u8856\u8857\u8858\u8859"+ - "\u885A\uDBDB\uB3A1\uDBDF\u885B\u885C\uBBF8\u885D"+ - "\uD6B7\u885E\uDBE0\u885F\u8860\u8861\u8862\uBEF9"+ - "\u8863\u8864\uB7BB\u8865\uDBD0\uCCAE\uBFB2\uBBB5"+ - "\uD7F8\uBFD3\u8866\u8867\u8868\u8869\u886A\uBFE9"+ - "\u886B\u886C\uBCE1\uCCB3\uDBDE\uB0D3\uCEEB\uB7D8"+ - "\uD7B9\uC6C2\u886D\u886E\uC0A4\u886F\uCCB9\u8870"+ - "\uDBE7\uDBE1\uC6BA\uDBE3\u8871\uDBE8\u8872\uC5F7"+ - "\u8873\u8874\u8875\uDBEA\u8876\u8877\uDBE9\uBFC0"+ - "\u8878\u8879\u887A\uDBE6\uDBE5\u887B\u887C\u887D"+ - "\u887E\u8880\uB4B9\uC0AC\uC2A2\uDBE2\uDBE4\u8881"+ - "\u8882\u8883\u8884\uD0CD\uDBED\u8885\u8886\u8887"+ - "\u8888\u8889\uC0DD\uDBF2\u888A\u888B\u888C\u888D"+ - "\u888E\u888F\u8890\uB6E2\u8891\u8892\u8893\u8894"+ - "\uDBF3\uDBD2\uB9B8\uD4AB\uDBEC\u8895\uBFD1\uDBF0"+ - "\u8896\uDBD1\u8897\uB5E6\u8898\uDBEB\uBFE5\u8899"+ - "\u889A\u889B\uDBEE\u889C\uDBF1\u889D\u889E\u889F"+ - "\uDBF9\u88A0\u88A1\u88A2\u88A3\u88A4\u88A5\u88A6"+ - "\u88A7\u88A8\uB9A1\uB0A3\u88A9\u88AA\u88AB\u88AC"+ - "\u88AD\u88AE\u88AF\uC2F1\u88B0\u88B1\uB3C7\uDBEF"+ - "\u88B2\u88B3\uDBF8\u88B4\uC6D2\uDBF4\u88B5\u88B6"+ - "\uDBF5\uDBF7\uDBF6\u88B7\u88B8\uDBFE\u88B9\uD3F2"+ - "\uB2BA\u88BA\u88BB\u88BC\uDBFD\u88BD\u88BE\u88BF"+ - "\u88C0\u88C1\u88C2\u88C3\u88C4\uDCA4\u88C5\uDBFB"+ - "\u88C6\u88C7\u88C8\u88C9\uDBFA\u88CA\u88CB\u88CC"+ - "\uDBFC\uC5E0\uBBF9\u88CD\u88CE\uDCA3\u88CF\u88D0"+ - "\uDCA5\u88D1\uCCC3\u88D2\u88D3\u88D4\uB6D1\uDDC0"+ - "\u88D5\u88D6\u88D7\uDCA1\u88D8\uDCA2\u88D9\u88DA"+ - "\u88DB\uC7B5\u88DC\u88DD\u88DE\uB6E9\u88DF\u88E0"+ - "\u88E1\uDCA7\u88E2\u88E3\u88E4\u88E5\uDCA6\u88E6"+ - "\uDCA9\uB1A4\u88E7\u88E8\uB5CC\u88E9\u88EA\u88EB"+ - "\u88EC\u88ED\uBFB0\u88EE\u88EF\u88F0\u88F1\u88F2"+ - "\uD1DF\u88F3\u88F4\u88F5\u88F6\uB6C2\u88F7\u88F8"+ - "\u88F9\u88FA\u88FB\u88FC\u88FD\u88FE\u8940\u8941"+ - "\u8942\u8943\u8944\u8945\uDCA8\u8946\u8947\u8948"+ - "\u8949\u894A\u894B\u894C\uCBFA\uEBF3\u894D\u894E"+ - "\u894F\uCBDC\u8950\u8951\uCBFE\u8952\u8953\u8954"+ - "\uCCC1\u8955\u8956\u8957\u8958\u8959\uC8FB\u895A"+ - "\u895B\u895C\u895D\u895E\u895F\uDCAA\u8960\u8961"+ - "\u8962\u8963\u8964\uCCEE\uDCAB\u8965\u8966\u8967"+ - "\u8968\u8969\u896A\u896B\u896C\u896D\u896E\u896F"+ - "\u8970\u8971\u8972\u8973\u8974\u8975\uDBD3\u8976"+ - "\uDCAF\uDCAC\u8977\uBEB3\u8978\uCAFB\u8979\u897A"+ - "\u897B\uDCAD\u897C\u897D\u897E\u8980\u8981\u8982"+ - "\u8983\u8984\uC9CA\uC4B9\u8985\u8986\u8987\u8988"+ - "\u8989\uC7BD\uDCAE\u898A\u898B\u898C\uD4F6\uD0E6"+ - "\u898D\u898E\u898F\u8990\u8991\u8992\u8993\u8994"+ - "\uC4AB\uB6D5\u8995\u8996\u8997\u8998\u8999\u899A"+ - "\u899B\u899C\u899D\u899E\u899F\u89A0\u89A1\u89A2"+ - "\u89A3\u89A4\u89A5\u89A6\uDBD4\u89A7\u89A8\u89A9"+ - "\u89AA\uB1DA\u89AB\u89AC\u89AD\uDBD5\u89AE\u89AF"+ - "\u89B0\u89B1\u89B2\u89B3\u89B4\u89B5\u89B6\u89B7"+ - "\u89B8\uDBD6\u89B9\u89BA\u89BB\uBABE\u89BC\u89BD"+ - "\u89BE\u89BF\u89C0\u89C1\u89C2\u89C3\u89C4\u89C5"+ - "\u89C6\u89C7\u89C8\u89C9\uC8C0\u89CA\u89CB\u89CC"+ - "\u89CD\u89CE\u89CF\uCABF\uC8C9\u89D0\uD7B3\u89D1"+ - "\uC9F9\u89D2\u89D3\uBFC7\u89D4\u89D5\uBAF8\u89D6"+ - "\u89D7\uD2BC\u89D8\u89D9\u89DA\u89DB\u89DC\u89DD"+ - "\u89DE\u89DF\uE2BA\u89E0\uB4A6\u89E1\u89E2\uB1B8"+ - "\u89E3\u89E4\u89E5\u89E6\u89E7\uB8B4\u89E8\uCFC4"+ - "\u89E9\u89EA\u89EB\u89EC\uD9E7\uCFA6\uCDE2\u89ED"+ - "\u89EE\uD9ED\uB6E0\u89EF\uD2B9\u89F0\u89F1\uB9BB"+ - "\u89F2\u89F3\u89F4\u89F5\uE2B9\uE2B7\u89F6\uB4F3"+ - "\u89F7\uCCEC\uCCAB\uB7F2\u89F8\uD8B2\uD1EB\uBABB"+ - "\u89F9\uCAA7\u89FA\u89FB\uCDB7\u89FC\u89FD\uD2C4"+ - "\uBFE4\uBCD0\uB6E1\u89FE\uDEC5\u8A40\u8A41\u8A42"+ - "\u8A43\uDEC6\uDBBC\u8A44\uD1D9\u8A45\u8A46\uC6E6"+ - "\uC4CE\uB7EE\u8A47\uB7DC\u8A48\u8A49\uBFFC\uD7E0"+ - "\u8A4A\uC6F5\u8A4B\u8A4C\uB1BC\uDEC8\uBDB1\uCCD7"+ - "\uDECA\u8A4D\uDEC9\u8A4E\u8A4F\u8A50\u8A51\u8A52"+ - "\uB5EC\u8A53\uC9DD\u8A54\u8A55\uB0C2\u8A56\u8A57"+ - "\u8A58\u8A59\u8A5A\u8A5B\u8A5C\u8A5D\u8A5E\u8A5F"+ - "\u8A60\u8A61\u8A62\uC5AE\uC5AB\u8A63\uC4CC\u8A64"+ - "\uBCE9\uCBFD\u8A65\u8A66\u8A67\uBAC3\u8A68\u8A69"+ - "\u8A6A\uE5F9\uC8E7\uE5FA\uCDFD\u8A6B\uD7B1\uB8BE"+ - "\uC2E8\u8A6C\uC8D1\u8A6D\u8A6E\uE5FB\u8A6F\u8A70"+ - "\u8A71\u8A72\uB6CA\uBCCB\u8A73\u8A74\uD1FD\uE6A1"+ - "\u8A75\uC3EE\u8A76\u8A77\u8A78\u8A79\uE6A4\u8A7A"+ - "\u8A7B\u8A7C\u8A7D\uE5FE\uE6A5\uCDD7\u8A7E\u8A80"+ - "\uB7C1\uE5FC\uE5FD\uE6A3\u8A81\u8A82\uC4DD\uE6A8"+ - "\u8A83\u8A84\uE6A7\u8A85\u8A86\u8A87\u8A88\u8A89"+ - "\u8A8A\uC3C3\u8A8B\uC6DE\u8A8C\u8A8D\uE6AA\u8A8E"+ - "\u8A8F\u8A90\u8A91\u8A92\u8A93\u8A94\uC4B7\u8A95"+ - "\u8A96\u8A97\uE6A2\uCABC\u8A98\u8A99\u8A9A\u8A9B"+ - "\uBDE3\uB9C3\uE6A6\uD0D5\uCEAF\u8A9C\u8A9D\uE6A9"+ - "\uE6B0\u8A9E\uD2A6\u8A9F\uBDAA\uE6AD\u8AA0\u8AA1"+ - "\u8AA2\u8AA3\u8AA4\uE6AF\u8AA5\uC0D1\u8AA6\u8AA7"+ - "\uD2CC\u8AA8\u8AA9\u8AAA\uBCA7\u8AAB\u8AAC\u8AAD"+ - "\u8AAE\u8AAF\u8AB0\u8AB1\u8AB2\u8AB3\u8AB4\u8AB5"+ - "\u8AB6\uE6B1\u8AB7\uD2F6\u8AB8\u8AB9\u8ABA\uD7CB"+ - "\u8ABB\uCDFE\u8ABC\uCDDE\uC2A6\uE6AB\uE6AC\uBDBF"+ - "\uE6AE\uE6B3\u8ABD\u8ABE\uE6B2\u8ABF\u8AC0\u8AC1"+ - "\u8AC2\uE6B6\u8AC3\uE6B8\u8AC4\u8AC5\u8AC6\u8AC7"+ - "\uC4EF\u8AC8\u8AC9\u8ACA\uC4C8\u8ACB\u8ACC\uBEEA"+ - "\uC9EF\u8ACD\u8ACE\uE6B7\u8ACF\uB6F0\u8AD0\u8AD1"+ - "\u8AD2\uC3E4\u8AD3\u8AD4\u8AD5\u8AD6\u8AD7\u8AD8"+ - "\u8AD9\uD3E9\uE6B4\u8ADA\uE6B5\u8ADB\uC8A2\u8ADC"+ - "\u8ADD\u8ADE\u8ADF\u8AE0\uE6BD\u8AE1\u8AE2\u8AE3"+ - "\uE6B9\u8AE4\u8AE5\u8AE6\u8AE7\u8AE8\uC6C5\u8AE9"+ - "\u8AEA\uCDF1\uE6BB\u8AEB\u8AEC\u8AED\u8AEE\u8AEF"+ - "\u8AF0\u8AF1\u8AF2\u8AF3\u8AF4\uE6BC\u8AF5\u8AF6"+ - "\u8AF7\u8AF8\uBBE9\u8AF9\u8AFA\u8AFB\u8AFC\u8AFD"+ - "\u8AFE\u8B40\uE6BE\u8B41\u8B42\u8B43\u8B44\uE6BA"+ - "\u8B45\u8B46\uC0B7\u8B47\u8B48\u8B49\u8B4A\u8B4B"+ - "\u8B4C\u8B4D\u8B4E\u8B4F\uD3A4\uE6BF\uC9F4\uE6C3"+ - "\u8B50\u8B51\uE6C4\u8B52\u8B53\u8B54\u8B55\uD0F6"+ - "\u8B56\u8B57\u8B58\u8B59\u8B5A\u8B5B\u8B5C\u8B5D"+ - "\u8B5E\u8B5F\u8B60\u8B61\u8B62\u8B63\u8B64\u8B65"+ - "\u8B66\u8B67\uC3BD\u8B68\u8B69\u8B6A\u8B6B\u8B6C"+ - "\u8B6D\u8B6E\uC3C4\uE6C2\u8B6F\u8B70\u8B71\u8B72"+ - "\u8B73\u8B74\u8B75\u8B76\u8B77\u8B78\u8B79\u8B7A"+ - "\u8B7B\u8B7C\uE6C1\u8B7D\u8B7E\u8B80\u8B81\u8B82"+ - "\u8B83\u8B84\uE6C7\uCFB1\u8B85\uEBF4\u8B86\u8B87"+ - "\uE6CA\u8B88\u8B89\u8B8A\u8B8B\u8B8C\uE6C5\u8B8D"+ - "\u8B8E\uBCDE\uC9A9\u8B8F\u8B90\u8B91\u8B92\u8B93"+ - "\u8B94\uBCB5\u8B95\u8B96\uCFD3\u8B97\u8B98\u8B99"+ - "\u8B9A\u8B9B\uE6C8\u8B9C\uE6C9\u8B9D\uE6CE\u8B9E"+ - "\uE6D0\u8B9F\u8BA0\u8BA1\uE6D1\u8BA2\u8BA3\u8BA4"+ - "\uE6CB\uB5D5\u8BA5\uE6CC\u8BA6\u8BA7\uE6CF\u8BA8"+ - "\u8BA9\uC4DB\u8BAA\uE6C6\u8BAB\u8BAC\u8BAD\u8BAE"+ - "\u8BAF\uE6CD\u8BB0\u8BB1\u8BB2\u8BB3\u8BB4\u8BB5"+ - "\u8BB6\u8BB7\u8BB8\u8BB9\u8BBA\u8BBB\u8BBC\u8BBD"+ - "\u8BBE\u8BBF\u8BC0\u8BC1\u8BC2\u8BC3\u8BC4\u8BC5"+ - "\u8BC6\uE6D2\u8BC7\u8BC8\u8BC9\u8BCA\u8BCB\u8BCC"+ - "\u8BCD\u8BCE\u8BCF\u8BD0\u8BD1\u8BD2\uE6D4\uE6D3"+ - "\u8BD3\u8BD4\u8BD5\u8BD6\u8BD7\u8BD8\u8BD9\u8BDA"+ - "\u8BDB\u8BDC\u8BDD\u8BDE\u8BDF\u8BE0\u8BE1\u8BE2"+ - "\u8BE3\u8BE4\u8BE5\u8BE6\u8BE7\u8BE8\u8BE9\u8BEA"+ - "\u8BEB\u8BEC\uE6D5\u8BED\uD9F8\u8BEE\u8BEF\uE6D6"+ - "\u8BF0\u8BF1\u8BF2\u8BF3\u8BF4\u8BF5\u8BF6\u8BF7"+ - "\uE6D7\u8BF8\u8BF9\u8BFA\u8BFB\u8BFC\u8BFD\u8BFE"+ - "\u8C40\u8C41\u8C42\u8C43\u8C44\u8C45\u8C46\u8C47"+ - "\uD7D3\uE6DD\u8C48\uE6DE\uBFD7\uD4D0\u8C49\uD7D6"+ - "\uB4E6\uCBEF\uE6DA\uD8C3\uD7CE\uD0A2\u8C4A\uC3CF"+ - "\u8C4B\u8C4C\uE6DF\uBCBE\uB9C2\uE6DB\uD1A7\u8C4D"+ - "\u8C4E\uBAA2\uC2CF\u8C4F\uD8AB\u8C50\u8C51\u8C52"+ - "\uCAEB\uE5EE\u8C53\uE6DC\u8C54\uB7F5\u8C55\u8C56"+ - "\u8C57\u8C58\uC8E6\u8C59\u8C5A\uC4F5\u8C5B\u8C5C"+ - "\uE5B2\uC4FE\u8C5D\uCBFC\uE5B3\uD5AC\u8C5E\uD3EE"+ - "\uCAD8\uB0B2\u8C5F\uCBCE\uCDEA\u8C60\u8C61\uBAEA"+ - "\u8C62\u8C63\u8C64\uE5B5\u8C65\uE5B4\u8C66\uD7DA"+ - "\uB9D9\uD6E6\uB6A8\uCDF0\uD2CB\uB1A6\uCAB5\u8C67"+ - "\uB3E8\uC9F3\uBFCD\uD0FB\uCAD2\uE5B6\uBBC2\u8C68"+ - "\u8C69\u8C6A\uCFDC\uB9AC\u8C6B\u8C6C\u8C6D\u8C6E"+ - "\uD4D7\u8C6F\u8C70\uBAA6\uD1E7\uCFFC\uBCD2\u8C71"+ - "\uE5B7\uC8DD\u8C72\u8C73\u8C74\uBFED\uB1F6\uCBDE"+ - "\u8C75\u8C76\uBCC5\u8C77\uBCC4\uD2FA\uC3DC\uBFDC"+ - "\u8C78\u8C79\u8C7A\u8C7B\uB8BB\u8C7C\u8C7D\u8C7E"+ - "\uC3C2\u8C80\uBAAE\uD4A2\u8C81\u8C82\u8C83\u8C84"+ - "\u8C85\u8C86\u8C87\u8C88\u8C89\uC7DE\uC4AF\uB2EC"+ - "\u8C8A\uB9D1\u8C8B\u8C8C\uE5BB\uC1C8\u8C8D\u8C8E"+ - "\uD5AF\u8C8F\u8C90\u8C91\u8C92\u8C93\uE5BC\u8C94"+ - "\uE5BE\u8C95\u8C96\u8C97\u8C98\u8C99\u8C9A\u8C9B"+ - "\uB4E7\uB6D4\uCBC2\uD1B0\uB5BC\u8C9C\u8C9D\uCAD9"+ - "\u8C9E\uB7E2\u8C9F\u8CA0\uC9E4\u8CA1\uBDAB\u8CA2"+ - "\u8CA3\uCEBE\uD7F0\u8CA4\u8CA5\u8CA6\u8CA7\uD0A1"+ - "\u8CA8\uC9D9\u8CA9\u8CAA\uB6FB\uE6D8\uBCE2\u8CAB"+ - "\uB3BE\u8CAC\uC9D0\u8CAD\uE6D9\uB3A2\u8CAE\u8CAF"+ - "\u8CB0\u8CB1\uDECC\u8CB2\uD3C8\uDECD\u8CB3\uD2A2"+ - "\u8CB4\u8CB5\u8CB6\u8CB7\uDECE\u8CB8\u8CB9\u8CBA"+ - "\u8CBB\uBECD\u8CBC\u8CBD\uDECF\u8CBE\u8CBF\u8CC0"+ - "\uCAAC\uD2FC\uB3DF\uE5EA\uC4E1\uBEA1\uCEB2\uC4F2"+ - "\uBED6\uC6A8\uB2E3\u8CC1\u8CC2\uBED3\u8CC3\u8CC4"+ - "\uC7FC\uCCEB\uBDEC\uCEDD\u8CC5\u8CC6\uCABA\uC6C1"+ - "\uE5EC\uD0BC\u8CC7\u8CC8\u8CC9\uD5B9\u8CCA\u8CCB"+ - "\u8CCC\uE5ED\u8CCD\u8CCE\u8CCF\u8CD0\uCAF4\u8CD1"+ - "\uCDC0\uC2C5\u8CD2\uE5EF\u8CD3\uC2C4\uE5F0\u8CD4"+ - "\u8CD5\u8CD6\u8CD7\u8CD8\u8CD9\u8CDA\uE5F8\uCDCD"+ - "\u8CDB\uC9BD\u8CDC\u8CDD\u8CDE\u8CDF\u8CE0\u8CE1"+ - "\u8CE2\uD2D9\uE1A8\u8CE3\u8CE4\u8CE5\u8CE6\uD3EC"+ - "\u8CE7\uCBEA\uC6F1\u8CE8\u8CE9\u8CEA\u8CEB\u8CEC"+ - "\uE1AC\u8CED\u8CEE\u8CEF\uE1A7\uE1A9\u8CF0\u8CF1"+ - "\uE1AA\uE1AF\u8CF2\u8CF3\uB2ED\u8CF4\uE1AB\uB8DA"+ - "\uE1AD\uE1AE\uE1B0\uB5BA\uE1B1\u8CF5\u8CF6\u8CF7"+ - "\u8CF8\u8CF9\uE1B3\uE1B8\u8CFA\u8CFB\u8CFC\u8CFD"+ - "\u8CFE\uD1D2\u8D40\uE1B6\uE1B5\uC1EB\u8D41\u8D42"+ - "\u8D43\uE1B7\u8D44\uD4C0\u8D45\uE1B2\u8D46\uE1BA"+ - "\uB0B6\u8D47\u8D48\u8D49\u8D4A\uE1B4\u8D4B\uBFF9"+ - "\u8D4C\uE1B9\u8D4D\u8D4E\uE1BB\u8D4F\u8D50\u8D51"+ - "\u8D52\u8D53\u8D54\uE1BE\u8D55\u8D56\u8D57\u8D58"+ - "\u8D59\u8D5A\uE1BC\u8D5B\u8D5C\u8D5D\u8D5E\u8D5F"+ - "\u8D60\uD6C5\u8D61\u8D62\u8D63\u8D64\u8D65\u8D66"+ - "\u8D67\uCFBF\u8D68\u8D69\uE1BD\uE1BF\uC2CD\u8D6A"+ - "\uB6EB\u8D6B\uD3F8\u8D6C\u8D6D\uC7CD\u8D6E\u8D6F"+ - "\uB7E5\u8D70\u8D71\u8D72\u8D73\u8D74\u8D75\u8D76"+ - "\u8D77\u8D78\u8D79\uBEFE\u8D7A\u8D7B\u8D7C\u8D7D"+ - "\u8D7E\u8D80\uE1C0\uE1C1\u8D81\u8D82\uE1C7\uB3E7"+ - "\u8D83\u8D84\u8D85\u8D86\u8D87\u8D88\uC6E9\u8D89"+ - "\u8D8A\u8D8B\u8D8C\u8D8D\uB4DE\u8D8E\uD1C2\u8D8F"+ - "\u8D90\u8D91\u8D92\uE1C8\u8D93\u8D94\uE1C6\u8D95"+ - "\u8D96\u8D97\u8D98\u8D99\uE1C5\u8D9A\uE1C3\uE1C2"+ - "\u8D9B\uB1C0\u8D9C\u8D9D\u8D9E\uD5B8\uE1C4\u8D9F"+ - "\u8DA0\u8DA1\u8DA2\u8DA3\uE1CB\u8DA4\u8DA5\u8DA6"+ - "\u8DA7\u8DA8\u8DA9\u8DAA\u8DAB\uE1CC\uE1CA\u8DAC"+ - "\u8DAD\u8DAE\u8DAF\u8DB0\u8DB1\u8DB2\u8DB3\uEFFA"+ - "\u8DB4\u8DB5\uE1D3\uE1D2\uC7B6\u8DB6\u8DB7\u8DB8"+ - "\u8DB9\u8DBA\u8DBB\u8DBC\u8DBD\u8DBE\u8DBF\u8DC0"+ - "\uE1C9\u8DC1\u8DC2\uE1CE\u8DC3\uE1D0\u8DC4\u8DC5"+ - "\u8DC6\u8DC7\u8DC8\u8DC9\u8DCA\u8DCB\u8DCC\u8DCD"+ - "\u8DCE\uE1D4\u8DCF\uE1D1\uE1CD\u8DD0\u8DD1\uE1CF"+ - "\u8DD2\u8DD3\u8DD4\u8DD5\uE1D5\u8DD6\u8DD7\u8DD8"+ - "\u8DD9\u8DDA\u8DDB\u8DDC\u8DDD\u8DDE\u8DDF\u8DE0"+ - "\u8DE1\u8DE2\uE1D6\u8DE3\u8DE4\u8DE5\u8DE6\u8DE7"+ - "\u8DE8\u8DE9\u8DEA\u8DEB\u8DEC\u8DED\u8DEE\u8DEF"+ - "\u8DF0\u8DF1\u8DF2\u8DF3\u8DF4\u8DF5\u8DF6\u8DF7"+ - "\u8DF8\uE1D7\u8DF9\u8DFA\u8DFB\uE1D8\u8DFC\u8DFD"+ - "\u8DFE\u8E40\u8E41\u8E42\u8E43\u8E44\u8E45\u8E46"+ - "\u8E47\u8E48\u8E49\u8E4A\u8E4B\u8E4C\u8E4D\u8E4E"+ - "\u8E4F\u8E50\u8E51\u8E52\u8E53\u8E54\u8E55\uE1DA"+ - "\u8E56\u8E57\u8E58\u8E59\u8E5A\u8E5B\u8E5C\u8E5D"+ - "\u8E5E\u8E5F\u8E60\u8E61\u8E62\uE1DB\u8E63\u8E64"+ - "\u8E65\u8E66\u8E67\u8E68\u8E69\uCEA1\u8E6A\u8E6B"+ - "\u8E6C\u8E6D\u8E6E\u8E6F\u8E70\u8E71\u8E72\u8E73"+ - "\u8E74\u8E75\u8E76\uE7DD\u8E77\uB4A8\uD6DD\u8E78"+ - "\u8E79\uD1B2\uB3B2\u8E7A\u8E7B\uB9A4\uD7F3\uC7C9"+ - "\uBEDE\uB9AE\u8E7C\uCED7\u8E7D\u8E7E\uB2EE\uDBCF"+ - "\u8E80\uBCBA\uD2D1\uCBC8\uB0CD\u8E81\u8E82\uCFEF"+ - "\u8E83\u8E84\u8E85\u8E86\u8E87\uD9E3\uBDED\u8E88"+ - "\u8E89\uB1D2\uCAD0\uB2BC\u8E8A\uCBA7\uB7AB\u8E8B"+ - "\uCAA6\u8E8C\u8E8D\u8E8E\uCFA3\u8E8F\u8E90\uE0F8"+ - "\uD5CA\uE0FB\u8E91\u8E92\uE0FA\uC5C1\uCCFB\u8E93"+ - "\uC1B1\uE0F9\uD6E3\uB2AF\uD6C4\uB5DB\u8E94\u8E95"+ - "\u8E96\u8E97\u8E98\u8E99\u8E9A\u8E9B\uB4F8\uD6A1"+ - "\u8E9C\u8E9D\u8E9E\u8E9F\u8EA0\uCFAF\uB0EF\u8EA1"+ - "\u8EA2\uE0FC\u8EA3\u8EA4\u8EA5\u8EA6\u8EA7\uE1A1"+ - "\uB3A3\u8EA8\u8EA9\uE0FD\uE0FE\uC3B1\u8EAA\u8EAB"+ - "\u8EAC\u8EAD\uC3DD\u8EAE\uE1A2\uB7F9\u8EAF\u8EB0"+ - "\u8EB1\u8EB2\u8EB3\u8EB4\uBBCF\u8EB5\u8EB6\u8EB7"+ - "\u8EB8\u8EB9\u8EBA\u8EBB\uE1A3\uC4BB\u8EBC\u8EBD"+ - "\u8EBE\u8EBF\u8EC0\uE1A4\u8EC1\u8EC2\uE1A5\u8EC3"+ - "\u8EC4\uE1A6\uB4B1\u8EC5\u8EC6\u8EC7\u8EC8\u8EC9"+ - "\u8ECA\u8ECB\u8ECC\u8ECD\u8ECE\u8ECF\u8ED0\u8ED1"+ - "\u8ED2\u8ED3\uB8C9\uC6BD\uC4EA\u8ED4\uB2A2\u8ED5"+ - "\uD0D2\u8ED6\uE7DB\uBBC3\uD3D7\uD3C4\u8ED7\uB9E3"+ - "\uE2CF\u8ED8\u8ED9\u8EDA\uD7AF\u8EDB\uC7EC\uB1D3"+ - "\u8EDC\u8EDD\uB4B2\uE2D1\u8EDE\u8EDF\u8EE0\uD0F2"+ - "\uC2AE\uE2D0\u8EE1\uBFE2\uD3A6\uB5D7\uE2D2\uB5EA"+ - "\u8EE2\uC3ED\uB8FD\u8EE3\uB8AE\u8EE4\uC5D3\uB7CF"+ - "\uE2D4\u8EE5\u8EE6\u8EE7\u8EE8\uE2D3\uB6C8\uD7F9"+ - "\u8EE9\u8EEA\u8EEB\u8EEC\u8EED\uCDA5\u8EEE\u8EEF"+ - "\u8EF0\u8EF1\u8EF2\uE2D8\u8EF3\uE2D6\uCAFC\uBFB5"+ - "\uD3B9\uE2D5\u8EF4\u8EF5\u8EF6\u8EF7\uE2D7\u8EF8"+ - "\u8EF9\u8EFA\u8EFB\u8EFC\u8EFD\u8EFE\u8F40\u8F41"+ - "\u8F42\uC1AE\uC0C8\u8F43\u8F44\u8F45\u8F46\u8F47"+ - "\u8F48\uE2DB\uE2DA\uC0AA\u8F49\u8F4A\uC1CE\u8F4B"+ - "\u8F4C\u8F4D\u8F4E\uE2DC\u8F4F\u8F50\u8F51\u8F52"+ - "\u8F53\u8F54\u8F55\u8F56\u8F57\u8F58\u8F59\u8F5A"+ - "\uE2DD\u8F5B\uE2DE\u8F5C\u8F5D\u8F5E\u8F5F\u8F60"+ - "\u8F61\u8F62\u8F63\u8F64\uDBC8\u8F65\uD1D3\uCDA2"+ - "\u8F66\u8F67\uBDA8\u8F68\u8F69\u8F6A\uDEC3\uD8A5"+ - "\uBFAA\uDBCD\uD2EC\uC6FA\uC5AA\u8F6B\u8F6C\u8F6D"+ - "\uDEC4\u8F6E\uB1D7\uDFAE\u8F6F\u8F70\u8F71\uCABD"+ - "\u8F72\uDFB1\u8F73\uB9AD\u8F74\uD2FD\u8F75\uB8A5"+ - "\uBAEB\u8F76\u8F77\uB3DA\u8F78\u8F79\u8F7A\uB5DC"+ - "\uD5C5\u8F7B\u8F7C\u8F7D\u8F7E\uC3D6\uCFD2\uBBA1"+ - "\u8F80\uE5F3\uE5F2\u8F81\u8F82\uE5F4\u8F83\uCDE4"+ - "\u8F84\uC8F5\u8F85\u8F86\u8F87\u8F88\u8F89\u8F8A"+ - "\u8F8B\uB5AF\uC7BF\u8F8C\uE5F6\u8F8D\u8F8E\u8F8F"+ - "\uECB0\u8F90\u8F91\u8F92\u8F93\u8F94\u8F95\u8F96"+ - "\u8F97\u8F98\u8F99\u8F9A\u8F9B\u8F9C\u8F9D\u8F9E"+ - "\uE5E6\u8F9F\uB9E9\uB5B1\u8FA0\uC2BC\uE5E8\uE5E7"+ - "\uE5E9\u8FA1\u8FA2\u8FA3\u8FA4\uD2CD\u8FA5\u8FA6"+ - "\u8FA7\uE1EA\uD0CE\u8FA8\uCDAE\u8FA9\uD1E5\u8FAA"+ - "\u8FAB\uB2CA\uB1EB\u8FAC\uB1F2\uC5ED\u8FAD\u8FAE"+ - "\uD5C3\uD3B0\u8FAF\uE1DC\u8FB0\u8FB1\u8FB2\uE1DD"+ - "\u8FB3\uD2DB\u8FB4\uB3B9\uB1CB\u8FB5\u8FB6\u8FB7"+ - "\uCDF9\uD5F7\uE1DE\u8FB8\uBEB6\uB4FD\u8FB9\uE1DF"+ - "\uBADC\uE1E0\uBBB2\uC2C9\uE1E1\u8FBA\u8FBB\u8FBC"+ - "\uD0EC\u8FBD\uCDBD\u8FBE\u8FBF\uE1E2\u8FC0\uB5C3"+ - "\uC5C7\uE1E3\u8FC1\u8FC2\uE1E4\u8FC3\u8FC4\u8FC5"+ - "\u8FC6\uD3F9\u8FC7\u8FC8\u8FC9\u8FCA\u8FCB\u8FCC"+ - "\uE1E5\u8FCD\uD1AD\u8FCE\u8FCF\uE1E6\uCEA2\u8FD0"+ - "\u8FD1\u8FD2\u8FD3\u8FD4\u8FD5\uE1E7\u8FD6\uB5C2"+ - "\u8FD7\u8FD8\u8FD9\u8FDA\uE1E8\uBBD5\u8FDB\u8FDC"+ - "\u8FDD\u8FDE\u8FDF\uD0C4\uE2E0\uB1D8\uD2E4\u8FE0"+ - "\u8FE1\uE2E1\u8FE2\u8FE3\uBCC9\uC8CC\u8FE4\uE2E3"+ - "\uECFE\uECFD\uDFAF\u8FE5\u8FE6\u8FE7\uE2E2\uD6BE"+ - "\uCDFC\uC3A6\u8FE8\u8FE9\u8FEA\uE3C3\u8FEB\u8FEC"+ - "\uD6D2\uE2E7\u8FED\u8FEE\uE2E8\u8FEF\u8FF0\uD3C7"+ - "\u8FF1\u8FF2\uE2EC\uBFEC\u8FF3\uE2ED\uE2E5\u8FF4"+ - "\u8FF5\uB3C0\u8FF6\u8FF7\u8FF8\uC4EE\u8FF9\u8FFA"+ - "\uE2EE\u8FFB\u8FFC\uD0C3\u8FFD\uBAF6\uE2E9\uB7DE"; - - private static final String innerEncoderIndex6= - "\uBBB3\uCCAC\uCBCB\uE2E4\uE2E6\uE2EA\uE2EB\u8FFE"+ - "\u9040\u9041\uE2F7\u9042\u9043\uE2F4\uD4F5\uE2F3"+ - "\u9044\u9045\uC5AD\u9046\uD5FA\uC5C2\uB2C0\u9047"+ - "\u9048\uE2EF\u9049\uE2F2\uC1AF\uCBBC\u904A\u904B"+ - "\uB5A1\uE2F9\u904C\u904D\u904E\uBCB1\uE2F1\uD0D4"+ - "\uD4B9\uE2F5\uB9D6\uE2F6\u904F\u9050\u9051\uC7D3"+ - "\u9052\u9053\u9054\u9055\u9056\uE2F0\u9057\u9058"+ - "\u9059\u905A\u905B\uD7DC\uEDA1\u905C\u905D\uE2F8"+ - "\u905E\uEDA5\uE2FE\uCAD1\u905F\u9060\u9061\u9062"+ - "\u9063\u9064\u9065\uC1B5\u9066\uBBD0\u9067\u9068"+ - "\uBFD6\u9069\uBAE3\u906A\u906B\uCBA1\u906C\u906D"+ - "\u906E\uEDA6\uEDA3\u906F\u9070\uEDA2\u9071\u9072"+ - "\u9073\u9074\uBBD6\uEDA7\uD0F4\u9075\u9076\uEDA4"+ - "\uBADE\uB6F7\uE3A1\uB6B2\uCCF1\uB9A7\u9077\uCFA2"+ - "\uC7A1\u9078\u9079\uBFD2\u907A\u907B\uB6F1\u907C"+ - "\uE2FA\uE2FB\uE2FD\uE2FC\uC4D5\uE3A2\u907D\uD3C1"+ - "\u907E\u9080\u9081\uE3A7\uC7C4\u9082\u9083\u9084"+ - "\u9085\uCFA4\u9086\u9087\uE3A9\uBAB7\u9088\u9089"+ - "\u908A\u908B\uE3A8\u908C\uBBDA\u908D\uE3A3\u908E"+ - "\u908F\u9090\uE3A4\uE3AA\u9091\uE3A6\u9092\uCEF2"+ - "\uD3C6\u9093\u9094\uBBBC\u9095\u9096\uD4C3\u9097"+ - "\uC4FA\u9098\u9099\uEDA8\uD0FC\uE3A5\u909A\uC3F5"+ - "\u909B\uE3AD\uB1AF\u909C\uE3B2\u909D\u909E\u909F"+ - "\uBCC2\u90A0\u90A1\uE3AC\uB5BF\u90A2\u90A3\u90A4"+ - "\u90A5\u90A6\u90A7\u90A8\u90A9\uC7E9\uE3B0\u90AA"+ - "\u90AB\u90AC\uBEAA\uCDEF\u90AD\u90AE\u90AF\u90B0"+ - "\u90B1\uBBF3\u90B2\u90B3\u90B4\uCCE8\u90B5\u90B6"+ - "\uE3AF\u90B7\uE3B1\u90B8\uCFA7\uE3AE\u90B9\uCEA9"+ - "\uBBDD\u90BA\u90BB\u90BC\u90BD\u90BE\uB5EB\uBEE5"+ - "\uB2D2\uB3CD\u90BF\uB1B9\uE3AB\uB2D1\uB5AC\uB9DF"+ - "\uB6E8\u90C0\u90C1\uCFEB\uE3B7\u90C2\uBBCC\u90C3"+ - "\u90C4\uC8C7\uD0CA\u90C5\u90C6\u90C7\u90C8\u90C9"+ - "\uE3B8\uB3EE\u90CA\u90CB\u90CC\u90CD\uEDA9\u90CE"+ - "\uD3FA\uD3E4\u90CF\u90D0\u90D1\uEDAA\uE3B9\uD2E2"+ - "\u90D2\u90D3\u90D4\u90D5\u90D6\uE3B5\u90D7\u90D8"+ - "\u90D9\u90DA\uD3DE\u90DB\u90DC\u90DD\u90DE\uB8D0"+ - "\uE3B3\u90DF\u90E0\uE3B6\uB7DF\u90E1\uE3B4\uC0A2"+ - "\u90E2\u90E3\u90E4\uE3BA\u90E5\u90E6\u90E7\u90E8"+ - "\u90E9\u90EA\u90EB\u90EC\u90ED\u90EE\u90EF\u90F0"+ - "\u90F1\u90F2\u90F3\u90F4\u90F5\u90F6\u90F7\uD4B8"+ - "\u90F8\u90F9\u90FA\u90FB\u90FC\u90FD\u90FE\u9140"+ - "\uB4C8\u9141\uE3BB\u9142\uBBC5\u9143\uC9F7\u9144"+ - "\u9145\uC9E5\u9146\u9147\u9148\uC4BD\u9149\u914A"+ - "\u914B\u914C\u914D\u914E\u914F\uEDAB\u9150\u9151"+ - "\u9152\u9153\uC2FD\u9154\u9155\u9156\u9157\uBBDB"+ - "\uBFAE\u9158\u9159\u915A\u915B\u915C\u915D\u915E"+ - "\uCEBF\u915F\u9160\u9161\u9162\uE3BC\u9163\uBFB6"+ - "\u9164\u9165\u9166\u9167\u9168\u9169\u916A\u916B"+ - "\u916C\u916D\u916E\u916F\u9170\u9171\u9172\u9173"+ - "\u9174\u9175\u9176\uB1EF\u9177\u9178\uD4F7\u9179"+ - "\u917A\u917B\u917C\u917D\uE3BE\u917E\u9180\u9181"+ - "\u9182\u9183\u9184\u9185\u9186\uEDAD\u9187\u9188"+ - "\u9189\u918A\u918B\u918C\u918D\u918E\u918F\uE3BF"+ - "\uBAA9\uEDAC\u9190\u9191\uE3BD\u9192\u9193\u9194"+ - "\u9195\u9196\u9197\u9198\u9199\u919A\u919B\uE3C0"+ - "\u919C\u919D\u919E\u919F\u91A0\u91A1\uBAB6\u91A2"+ - "\u91A3\u91A4\uB6AE\u91A5\u91A6\u91A7\u91A8\u91A9"+ - "\uD0B8\u91AA\uB0C3\uEDAE\u91AB\u91AC\u91AD\u91AE"+ - "\u91AF\uEDAF\uC0C1\u91B0\uE3C1\u91B1\u91B2\u91B3"+ - "\u91B4\u91B5\u91B6\u91B7\u91B8\u91B9\u91BA\u91BB"+ - "\u91BC\u91BD\u91BE\u91BF\u91C0\u91C1\uC5B3\u91C2"+ - "\u91C3\u91C4\u91C5\u91C6\u91C7\u91C8\u91C9\u91CA"+ - "\u91CB\u91CC\u91CD\u91CE\u91CF\uE3C2\u91D0\u91D1"+ - "\u91D2\u91D3\u91D4\u91D5\u91D6\u91D7\u91D8\uDCB2"+ - "\u91D9\u91DA\u91DB\u91DC\u91DD\u91DE\uEDB0\u91DF"+ - "\uB8EA\u91E0\uCEEC\uEAA7\uD0E7\uCAF9\uC8D6\uCFB7"+ - "\uB3C9\uCED2\uBDE4\u91E1\u91E2\uE3DE\uBBF2\uEAA8"+ - "\uD5BD\u91E3\uC6DD\uEAA9\u91E4\u91E5\u91E6\uEAAA"+ - "\u91E7\uEAAC\uEAAB\u91E8\uEAAE\uEAAD\u91E9\u91EA"+ - "\u91EB\u91EC\uBDD8\u91ED\uEAAF\u91EE\uC2BE\u91EF"+ - "\u91F0\u91F1\u91F2\uB4C1\uB4F7\u91F3\u91F4\uBBA7"+ - "\u91F5\u91F6\u91F7\u91F8\u91F9\uECE6\uECE5\uB7BF"+ - "\uCBF9\uB1E2\u91FA\uECE7\u91FB\u91FC\u91FD\uC9C8"+ - "\uECE8\uECE9\u91FE\uCAD6\uDED0\uB2C5\uD4FA\u9240"+ - "\u9241\uC6CB\uB0C7\uB4F2\uC8D3\u9242\u9243\u9244"+ - "\uCDD0\u9245\u9246\uBFB8\u9247\u9248\u9249\u924A"+ - "\u924B\u924C\u924D\uBFDB\u924E\u924F\uC7A4\uD6B4"+ - "\u9250\uC0A9\uDED1\uC9A8\uD1EF\uC5A4\uB0E7\uB3B6"+ - "\uC8C5\u9251\u9252\uB0E2\u9253\u9254\uB7F6\u9255"+ - "\u9256\uC5FA\u9257\u9258\uB6F3\u9259\uD5D2\uB3D0"+ - "\uBCBC\u925A\u925B\u925C\uB3AD\u925D\u925E\u925F"+ - "\u9260\uBEF1\uB0D1\u9261\u9262\u9263\u9264\u9265"+ - "\u9266\uD2D6\uCAE3\uD7A5\u9267\uCDB6\uB6B6\uBFB9"+ - "\uD5DB\u9268\uB8A7\uC5D7\u9269\u926A\u926B\uDED2"+ - "\uBFD9\uC2D5\uC7C0\u926C\uBBA4\uB1A8\u926D\u926E"+ - "\uC5EA\u926F\u9270\uC5FB\uCCA7\u9271\u9272\u9273"+ - "\u9274\uB1A7\u9275\u9276\u9277\uB5D6\u9278\u9279"+ - "\u927A\uC4A8\u927B\uDED3\uD1BA\uB3E9\u927C\uC3F2"+ - "\u927D\u927E\uB7F7\u9280\uD6F4\uB5A3\uB2F0\uC4B4"+ - "\uC4E9\uC0AD\uDED4\u9281\uB0E8\uC5C4\uC1E0\u9282"+ - "\uB9D5\u9283\uBEDC\uCDD8\uB0CE\u9284\uCDCF\uDED6"+ - "\uBED0\uD7BE\uDED5\uD5D0\uB0DD\u9285\u9286\uC4E2"+ - "\u9287\u9288\uC2A3\uBCF0\u9289\uD3B5\uC0B9\uC5A1"+ - "\uB2A6\uD4F1\u928A\u928B\uC0A8\uCAC3\uDED7\uD5FC"+ - "\u928C\uB9B0\u928D\uC8AD\uCBA9\u928E\uDED9\uBFBD"+ - "\u928F\u9290\u9291\u9292\uC6B4\uD7A7\uCAB0\uC4C3"+ - "\u9293\uB3D6\uB9D2\u9294\u9295\u9296\u9297\uD6B8"+ - "\uEAFC\uB0B4\u9298\u9299\u929A\u929B\uBFE6\u929C"+ - "\u929D\uCCF4\u929E\u929F\u92A0\u92A1\uCDDA\u92A2"+ - "\u92A3\u92A4\uD6BF\uC2CE\u92A5\uCECE\uCCA2\uD0AE"+ - "\uC4D3\uB5B2\uDED8\uD5F5\uBCB7\uBBD3\u92A6\u92A7"+ - "\uB0A4\u92A8\uC5B2\uB4EC\u92A9\u92AA\u92AB\uD5F1"+ - "\u92AC\u92AD\uEAFD\u92AE\u92AF\u92B0\u92B1\u92B2"+ - "\u92B3\uDEDA\uCDA6\u92B4\u92B5\uCDEC\u92B6\u92B7"+ - "\u92B8\u92B9\uCEE6\uDEDC\u92BA\uCDB1\uC0A6\u92BB"+ - "\u92BC\uD7BD\u92BD\uDEDB\uB0C6\uBAB4\uC9D3\uC4F3"+ - "\uBEE8\u92BE\u92BF\u92C0\u92C1\uB2B6\u92C2\u92C3"+ - "\u92C4\u92C5\u92C6\u92C7\u92C8\u92C9\uC0CC\uCBF0"+ - "\u92CA\uBCF1\uBBBB\uB5B7\u92CB\u92CC\u92CD\uC5F5"+ - "\u92CE\uDEE6\u92CF\u92D0\u92D1\uDEE3\uBEDD\u92D2"+ - "\u92D3\uDEDF\u92D4\u92D5\u92D6\u92D7\uB4B7\uBDDD"+ - "\u92D8\u92D9\uDEE0\uC4ED\u92DA\u92DB\u92DC\u92DD"+ - "\uCFC6\u92DE\uB5E0\u92DF\u92E0\u92E1\u92E2\uB6DE"+ - "\uCADA\uB5F4\uDEE5\u92E3\uD5C6\u92E4\uDEE1\uCCCD"+ - "\uC6FE\u92E5\uC5C5\u92E6\u92E7\u92E8\uD2B4\u92E9"+ - "\uBEF2\u92EA\u92EB\u92EC\u92ED\u92EE\u92EF\u92F0"+ - "\uC2D3\u92F1\uCCBD\uB3B8\u92F2\uBDD3\u92F3\uBFD8"+ - "\uCDC6\uD1DA\uB4EB\u92F4\uDEE4\uDEDD\uDEE7\u92F5"+ - "\uEAFE\u92F6\u92F7\uC2B0\uDEE2\u92F8\u92F9\uD6C0"+ - "\uB5A7\u92FA\uB2F4\u92FB\uDEE8\u92FC\uDEF2\u92FD"+ - "\u92FE\u9340\u9341\u9342\uDEED\u9343\uDEF1\u9344"+ - "\u9345\uC8E0\u9346\u9347\u9348\uD7E1\uDEEF\uC3E8"+ - "\uCCE1\u9349\uB2E5\u934A\u934B\u934C\uD2BE\u934D"+ - "\u934E\u934F\u9350\u9351\u9352\u9353\uDEEE\u9354"+ - "\uDEEB\uCED5\u9355\uB4A7\u9356\u9357\u9358\u9359"+ - "\u935A\uBFAB\uBEBE\u935B\u935C\uBDD2\u935D\u935E"+ - "\u935F\u9360\uDEE9\u9361\uD4AE\u9362\uDEDE\u9363"+ - "\uDEEA\u9364\u9365\u9366\u9367\uC0BF\u9368\uDEEC"+ - "\uB2F3\uB8E9\uC2A7\u9369\u936A\uBDC1\u936B\u936C"+ - "\u936D\u936E\u936F\uDEF5\uDEF8\u9370\u9371\uB2AB"+ - "\uB4A4\u9372\u9373\uB4EA\uC9A6\u9374\u9375\u9376"+ - "\u9377\u9378\u9379\uDEF6\uCBD1\u937A\uB8E3\u937B"+ - "\uDEF7\uDEFA\u937C\u937D\u937E\u9380\uDEF9\u9381"+ - "\u9382\u9383\uCCC2\u9384\uB0E1\uB4EE\u9385\u9386"+ - "\u9387\u9388\u9389\u938A\uE5BA\u938B\u938C\u938D"+ - "\u938E\u938F\uD0AF\u9390\u9391\uB2EB\u9392\uEBA1"+ - "\u9393\uDEF4\u9394\u9395\uC9E3\uDEF3\uB0DA\uD2A1"+ - "\uB1F7\u9396\uCCAF\u9397\u9398\u9399\u939A\u939B"+ - "\u939C\u939D\uDEF0\u939E\uCBA4\u939F\u93A0\u93A1"+ - "\uD5AA\u93A2\u93A3\u93A4\u93A5\u93A6\uDEFB\u93A7"+ - "\u93A8\u93A9\u93AA\u93AB\u93AC\u93AD\u93AE\uB4DD"+ - "\u93AF\uC4A6\u93B0\u93B1\u93B2\uDEFD\u93B3\u93B4"+ - "\u93B5\u93B6\u93B7\u93B8\u93B9\u93BA\u93BB\u93BC"+ - "\uC3FE\uC4A1\uDFA1\u93BD\u93BE\u93BF\u93C0\u93C1"+ - "\u93C2\u93C3\uC1CC\u93C4\uDEFC\uBEEF\u93C5\uC6B2"+ - "\u93C6\u93C7\u93C8\u93C9\u93CA\u93CB\u93CC\u93CD"+ - "\u93CE\uB3C5\uC8F6\u93CF\u93D0\uCBBA\uDEFE\u93D1"+ - "\u93D2\uDFA4\u93D3\u93D4\u93D5\u93D6\uD7B2\u93D7"+ - "\u93D8\u93D9\u93DA\u93DB\uB3B7\u93DC\u93DD\u93DE"+ - "\u93DF\uC1C3\u93E0\u93E1\uC7CB\uB2A5\uB4E9\u93E2"+ - "\uD7AB\u93E3\u93E4\u93E5\u93E6\uC4EC\u93E7\uDFA2"+ - "\uDFA3\u93E8\uDFA5\u93E9\uBAB3\u93EA\u93EB\u93EC"+ - "\uDFA6\u93ED\uC0DE\u93EE\u93EF\uC9C3\u93F0\u93F1"+ - "\u93F2\u93F3\u93F4\u93F5\u93F6\uB2D9\uC7E6\u93F7"+ - "\uDFA7\u93F8\uC7DC\u93F9\u93FA\u93FB\u93FC\uDFA8"+ - "\uEBA2\u93FD\u93FE\u9440\u9441\u9442\uCBD3\u9443"+ - "\u9444\u9445\uDFAA\u9446\uDFA9\u9447\uB2C1\u9448"+ - "\u9449\u944A\u944B\u944C\u944D\u944E\u944F\u9450"+ - "\u9451\u9452\u9453\u9454\u9455\u9456\u9457\u9458"+ - "\u9459\u945A\u945B\u945C\u945D\u945E\u945F\u9460"+ - "\uC5CA\u9461\u9462\u9463\u9464\u9465\u9466\u9467"+ - "\u9468\uDFAB\u9469\u946A\u946B\u946C\u946D\u946E"+ - "\u946F\u9470\uD4DC\u9471\u9472\u9473\u9474\u9475"+ - "\uC8C1\u9476\u9477\u9478\u9479\u947A\u947B\u947C"+ - "\u947D\u947E\u9480\u9481\u9482\uDFAC\u9483\u9484"+ - "\u9485\u9486\u9487\uBEF0\u9488\u9489\uDFAD\uD6A7"+ - "\u948A\u948B\u948C\u948D\uEAB7\uEBB6\uCAD5\u948E"+ - "\uD8FC\uB8C4\u948F\uB9A5\u9490\u9491\uB7C5\uD5FE"+ - "\u9492\u9493\u9494\u9495\u9496\uB9CA\u9497\u9498"+ - "\uD0A7\uF4CD\u9499\u949A\uB5D0\u949B\u949C\uC3F4"+ - "\u949D\uBEC8\u949E\u949F\u94A0\uEBB7\uB0BD\u94A1"+ - "\u94A2\uBDCC\u94A3\uC1B2\u94A4\uB1D6\uB3A8\u94A5"+ - "\u94A6\u94A7\uB8D2\uC9A2\u94A8\u94A9\uB6D8\u94AA"+ - "\u94AB\u94AC\u94AD\uEBB8\uBEB4\u94AE\u94AF\u94B0"+ - "\uCAFD\u94B1\uC7C3\u94B2\uD5FB\u94B3\u94B4\uB7F3"+ - "\u94B5\u94B6\u94B7\u94B8\u94B9\u94BA\u94BB\u94BC"+ - "\u94BD\u94BE\u94BF\u94C0\u94C1\u94C2\u94C3\uCEC4"+ - "\u94C4\u94C5\u94C6\uD5AB\uB1F3\u94C7\u94C8\u94C9"+ - "\uECB3\uB0DF\u94CA\uECB5\u94CB\u94CC\u94CD\uB6B7"+ - "\u94CE\uC1CF\u94CF\uF5FA\uD0B1\u94D0\u94D1\uD5E5"+ - "\u94D2\uCED3\u94D3\u94D4\uBDEF\uB3E2\u94D5\uB8AB"+ - "\u94D6\uD5B6\u94D7\uEDBD\u94D8\uB6CF\u94D9\uCBB9"+ - "\uD0C2\u94DA\u94DB\u94DC\u94DD\u94DE\u94DF\u94E0"+ - "\u94E1\uB7BD\u94E2\u94E3\uECB6\uCAA9\u94E4\u94E5"+ - "\u94E6\uC5D4\u94E7\uECB9\uECB8\uC2C3\uECB7\u94E8"+ - "\u94E9\u94EA\u94EB\uD0FD\uECBA\u94EC\uECBB\uD7E5"+ - "\u94ED\u94EE\uECBC\u94EF\u94F0\u94F1\uECBD\uC6EC"+ - "\u94F2\u94F3\u94F4\u94F5\u94F6\u94F7\u94F8\u94F9"+ - "\uCEDE\u94FA\uBCC8\u94FB\u94FC\uC8D5\uB5A9\uBEC9"+ - "\uD6BC\uD4E7\u94FD\u94FE\uD1AE\uD0F1\uEAB8\uEAB9"+ - "\uEABA\uBAB5\u9540\u9541\u9542\u9543\uCAB1\uBFF5"+ - "\u9544\u9545\uCDFA\u9546\u9547\u9548\u9549\u954A"+ - "\uEAC0\u954B\uB0BA\uEABE\u954C\u954D\uC0A5\u954E"+ - "\u954F\u9550\uEABB\u9551\uB2FD\u9552\uC3F7\uBBE8"+ - "\u9553\u9554\u9555\uD2D7\uCEF4\uEABF\u9556\u9557"+ - "\u9558\uEABC\u9559\u955A\u955B\uEAC3\u955C\uD0C7"+ - "\uD3B3\u955D\u955E\u955F\u9560\uB4BA\u9561\uC3C1"+ - "\uD7F2\u9562\u9563\u9564\u9565\uD5D1\u9566\uCAC7"+ - "\u9567\uEAC5\u9568\u9569\uEAC4\uEAC7\uEAC6\u956A"+ - "\u956B\u956C\u956D\u956E\uD6E7\u956F\uCFD4\u9570"+ - "\u9571\uEACB\u9572\uBBCE\u9573\u9574\u9575\u9576"+ - "\u9577\u9578\u9579\uBDFA\uC9CE\u957A\u957B\uEACC"+ - "\u957C\u957D\uC9B9\uCFFE\uEACA\uD4CE\uEACD\uEACF"+ - "\u957E\u9580\uCDED\u9581\u9582\u9583\u9584\uEAC9"+ - "\u9585\uEACE\u9586\u9587\uCEEE\u9588\uBBDE\u9589"+ - "\uB3BF\u958A\u958B\u958C\u958D\u958E\uC6D5\uBEB0"+ - "\uCEFA\u958F\u9590\u9591\uC7E7\u9592\uBEA7\uEAD0"+ - "\u9593\u9594\uD6C7\u9595\u9596\u9597\uC1C0\u9598"+ - "\u9599\u959A\uD4DD\u959B\uEAD1\u959C\u959D\uCFBE"+ - "\u959E\u959F\u95A0\u95A1\uEAD2\u95A2\u95A3\u95A4"+ - "\u95A5\uCAEE\u95A6\u95A7\u95A8\u95A9\uC5AF\uB0B5"+ - "\u95AA\u95AB\u95AC\u95AD\u95AE\uEAD4\u95AF\u95B0"+ - "\u95B1\u95B2\u95B3\u95B4\u95B5\u95B6\u95B7\uEAD3"+ - "\uF4DF\u95B8\u95B9\u95BA\u95BB\u95BC\uC4BA\u95BD"+ - "\u95BE\u95BF\u95C0\u95C1\uB1A9\u95C2\u95C3\u95C4"+ - "\u95C5\uE5DF\u95C6\u95C7\u95C8\u95C9\uEAD5\u95CA"+ - "\u95CB\u95CC\u95CD\u95CE\u95CF\u95D0\u95D1\u95D2"+ - "\u95D3\u95D4\u95D5\u95D6\u95D7\u95D8\u95D9\u95DA"+ - "\u95DB\u95DC\u95DD\u95DE\u95DF\u95E0\u95E1\u95E2"+ - "\u95E3\uCAEF\u95E4\uEAD6\uEAD7\uC6D8\u95E5\u95E6"+ - "\u95E7\u95E8\u95E9\u95EA\u95EB\u95EC\uEAD8\u95ED"+ - "\u95EE\uEAD9\u95EF\u95F0\u95F1\u95F2\u95F3\u95F4"+ - "\uD4BB\u95F5\uC7FA\uD2B7\uB8FC\u95F6\u95F7\uEAC2"+ - "\u95F8\uB2DC\u95F9\u95FA\uC2FC\u95FB\uD4F8\uCCE6"+ - "\uD7EE\u95FC\u95FD\u95FE\u9640\u9641\u9642\u9643"+ - "\uD4C2\uD3D0\uEBC3\uC5F3\u9644\uB7FE\u9645\u9646"+ - "\uEBD4\u9647\u9648\u9649\uCBB7\uEBDE\u964A\uC0CA"+ - "\u964B\u964C\u964D\uCDFB\u964E\uB3AF\u964F\uC6DA"+ - "\u9650\u9651\u9652\u9653\u9654\u9655\uEBFC\u9656"+ - "\uC4BE\u9657\uCEB4\uC4A9\uB1BE\uD4FD\u9658\uCAF5"+ - "\u9659\uD6EC\u965A\u965B\uC6D3\uB6E4\u965C\u965D"+ - "\u965E\u965F\uBBFA\u9660\u9661\uD0E0\u9662\u9663"+ - "\uC9B1\u9664\uD4D3\uC8A8\u9665\u9666\uB8CB\u9667"+ - "\uE8BE\uC9BC\u9668\u9669\uE8BB\u966A\uC0EE\uD0D3"+ - "\uB2C4\uB4E5\u966B\uE8BC\u966C\u966D\uD5C8\u966E"+ - "\u966F\u9670\u9671\u9672\uB6C5\u9673\uE8BD\uCAF8"+ - "\uB8DC\uCCF5\u9674\u9675\u9676\uC0B4\u9677\u9678"+ - "\uD1EE\uE8BF\uE8C2\u9679\u967A\uBABC\u967B\uB1AD"+ - "\uBDDC\u967C\uEABD\uE8C3\u967D\uE8C6\u967E\uE8CB"+ - "\u9680\u9681\u9682\u9683\uE8CC\u9684\uCBC9\uB0E5"+ - "\u9685\uBCAB\u9686\u9687\uB9B9\u9688\u9689\uE8C1"+ - "\u968A\uCDF7\u968B\uE8CA\u968C\u968D\u968E\u968F"+ - "\uCEF6\u9690\u9691\u9692\u9693\uD5ED\u9694\uC1D6"+ - "\uE8C4\u9695\uC3B6\u9696\uB9FB\uD6A6\uE8C8\u9697"+ - "\u9698\u9699\uCAE0\uD4E6\u969A\uE8C0\u969B\uE8C5"+ - "\uE8C7\u969C\uC7B9\uB7E3\u969D\uE8C9\u969E\uBFDD"+ - "\uE8D2\u969F\u96A0\uE8D7\u96A1\uE8D5\uBCDC\uBCCF"+ - "\uE8DB\u96A2\u96A3\u96A4\u96A5\u96A6\u96A7\u96A8"+ - "\u96A9\uE8DE\u96AA\uE8DA\uB1FA\u96AB\u96AC\u96AD"+ - "\u96AE\u96AF\u96B0\u96B1\u96B2\u96B3\u96B4\uB0D8"+ - "\uC4B3\uB8CC\uC6E2\uC8BE\uC8E1\u96B5\u96B6\u96B7"+ - "\uE8CF\uE8D4\uE8D6\u96B8\uB9F1\uE8D8\uD7F5\u96B9"+ - "\uC4FB\u96BA\uE8DC\u96BB\u96BC\uB2E9\u96BD\u96BE"+ - "\u96BF\uE8D1\u96C0\u96C1\uBCED\u96C2\u96C3\uBFC2"+ - "\uE8CD\uD6F9\u96C4\uC1F8\uB2F1\u96C5\u96C6\u96C7"+ - "\u96C8\u96C9\u96CA\u96CB\u96CC\uE8DF\u96CD\uCAC1"+ - "\uE8D9\u96CE\u96CF\u96D0\u96D1\uD5A4\u96D2\uB1EA"+ - "\uD5BB\uE8CE\uE8D0\uB6B0\uE8D3\u96D3\uE8DD\uC0B8"+ - "\u96D4\uCAF7\u96D5\uCBA8\u96D6\u96D7\uC6DC\uC0F5"+ - "\u96D8\u96D9\u96DA\u96DB\u96DC\uE8E9\u96DD\u96DE"+ - "\u96DF\uD0A3\u96E0\u96E1\u96E2\u96E3\u96E4\u96E5"+ - "\u96E6\uE8F2\uD6EA\u96E7\u96E8\u96E9\u96EA\u96EB"+ - "\u96EC\u96ED\uE8E0\uE8E1\u96EE\u96EF\u96F0\uD1F9"+ - "\uBACB\uB8F9\u96F1\u96F2\uB8F1\uD4D4\uE8EF\u96F3"+ - "\uE8EE\uE8EC\uB9F0\uCCD2\uE8E6\uCEA6\uBFF2\u96F4"+ - "\uB0B8\uE8F1\uE8F0\u96F5\uD7C0\u96F6\uE8E4\u96F7"+ - "\uCDA9\uC9A3\u96F8\uBBB8\uBDDB\uE8EA\u96F9\u96FA"+ - "\u96FB\u96FC\u96FD\u96FE\u9740\u9741\u9742\u9743"+ - "\uE8E2\uE8E3\uE8E5\uB5B5\uE8E7\uC7C5\uE8EB\uE8ED"+ - "\uBDB0\uD7AE\u9744\uE8F8\u9745\u9746\u9747\u9748"+ - "\u9749\u974A\u974B\u974C\uE8F5\u974D\uCDB0\uE8F6"+ - "\u974E\u974F\u9750\u9751\u9752\u9753\u9754\u9755"+ - "\u9756\uC1BA\u9757\uE8E8\u9758\uC3B7\uB0F0\u9759"+ - "\u975A\u975B\u975C\u975D\u975E\u975F\u9760\uE8F4"+ - "\u9761\u9762\u9763\uE8F7\u9764\u9765\u9766\uB9A3"+ - "\u9767\u9768\u9769\u976A\u976B\u976C\u976D\u976E"+ - "\u976F\u9770\uC9D2\u9771\u9772\u9773\uC3CE\uCEE0"+ - "\uC0E6\u9774\u9775\u9776\u9777\uCBF3\u9778\uCCDD"+ - "\uD0B5\u9779\u977A\uCAE1\u977B\uE8F3\u977C\u977D"+ - "\u977E\u9780\u9781\u9782\u9783\u9784\u9785\u9786"+ - "\uBCEC\u9787\uE8F9\u9788\u9789\u978A\u978B\u978C"+ - "\u978D\uC3DE\u978E\uC6E5\u978F\uB9F7\u9790\u9791"+ - "\u9792\u9793\uB0F4\u9794\u9795\uD7D8\u9796\u9797"+ - "\uBCAC\u9798\uC5EF\u9799\u979A\u979B\u979C\u979D"+ - "\uCCC4\u979E\u979F\uE9A6\u97A0\u97A1\u97A2\u97A3"+ - "\u97A4\u97A5\u97A6\u97A7\u97A8\u97A9\uC9AD\u97AA"+ - "\uE9A2\uC0E2\u97AB\u97AC\u97AD\uBFC3\u97AE\u97AF"+ - "\u97B0\uE8FE\uB9D7\u97B1\uE8FB\u97B2\u97B3\u97B4"+ - "\u97B5\uE9A4\u97B6\u97B7\u97B8\uD2CE\u97B9\u97BA"+ - "\u97BB\u97BC\u97BD\uE9A3\u97BE\uD6B2\uD7B5\u97BF"+ - "\uE9A7\u97C0\uBDB7\u97C1\u97C2\u97C3\u97C4\u97C5"+ - "\u97C6\u97C7\u97C8\u97C9\u97CA\u97CB\u97CC\uE8FC"+ - "\uE8FD\u97CD\u97CE\u97CF\uE9A1\u97D0\u97D1\u97D2"+ - "\u97D3\u97D4\u97D5\u97D6\u97D7\uCDD6\u97D8\u97D9"+ - "\uD2AC\u97DA\u97DB\u97DC\uE9B2\u97DD\u97DE\u97DF"+ - "\u97E0\uE9A9\u97E1\u97E2\u97E3\uB4AA\u97E4\uB4BB"+ - "\u97E5\u97E6\uE9AB\u97E7\u97E8\u97E9\u97EA\u97EB"+ - "\u97EC\u97ED\u97EE\u97EF\u97F0\u97F1\u97F2\u97F3"+ - "\u97F4\u97F5\u97F6\u97F7\uD0A8\u97F8\u97F9\uE9A5"+ - "\u97FA\u97FB\uB3FE\u97FC\u97FD\uE9AC\uC0E3\u97FE"+ - "\uE9AA\u9840\u9841\uE9B9\u9842\u9843\uE9B8\u9844"+ - "\u9845\u9846\u9847\uE9AE\u9848\u9849\uE8FA\u984A"+ - "\u984B\uE9A8\u984C\u984D\u984E\u984F\u9850\uBFAC"+ - "\uE9B1\uE9BA\u9851\u9852\uC2A5\u9853\u9854\u9855"+ - "\uE9AF\u9856\uB8C5\u9857\uE9AD\u9858\uD3DC\uE9B4"+ - "\uE9B5\uE9B7\u9859\u985A\u985B\uE9C7\u985C\u985D"+ - "\u985E\u985F\u9860\u9861\uC0C6\uE9C5\u9862\u9863"+ - "\uE9B0\u9864\u9865\uE9BB\uB0F1\u9866\u9867\u9868"+ - "\u9869\u986A\u986B\u986C\u986D\u986E\u986F\uE9BC"+ - "\uD5A5\u9870\u9871\uE9BE\u9872\uE9BF\u9873\u9874"+ - "\u9875\uE9C1\u9876\u9877\uC1F1\u9878\u9879\uC8B6"+ - "\u987A\u987B\u987C\uE9BD\u987D\u987E\u9880\u9881"+ - "\u9882\uE9C2\u9883\u9884\u9885\u9886\u9887\u9888"+ - "\u9889\u988A\uE9C3\u988B\uE9B3\u988C\uE9B6\u988D"+ - "\uBBB1\u988E\u988F\u9890\uE9C0\u9891\u9892\u9893"+ - "\u9894\u9895\u9896\uBCF7\u9897\u9898\u9899\uE9C4"+ - "\uE9C6\u989A\u989B\u989C\u989D\u989E\u989F\u98A0"+ - "\u98A1\u98A2\u98A3\u98A4\u98A5\uE9CA\u98A6\u98A7"+ - "\u98A8\u98A9\uE9CE\u98AA\u98AB\u98AC\u98AD\u98AE"+ - "\u98AF\u98B0\u98B1\u98B2\u98B3\uB2DB\u98B4\uE9C8"+ - "\u98B5\u98B6\u98B7\u98B8\u98B9\u98BA\u98BB\u98BC"+ - "\u98BD\u98BE\uB7AE\u98BF\u98C0\u98C1\u98C2\u98C3"+ - "\u98C4\u98C5\u98C6\u98C7\u98C8\u98C9\u98CA\uE9CB"+ - "\uE9CC\u98CB\u98CC\u98CD\u98CE\u98CF\u98D0\uD5C1"+ - "\u98D1\uC4A3\u98D2\u98D3\u98D4\u98D5\u98D6\u98D7"+ - "\uE9D8\u98D8\uBAE1\u98D9\u98DA\u98DB\u98DC\uE9C9"+ - "\u98DD\uD3A3\u98DE\u98DF\u98E0\uE9D4\u98E1\u98E2"+ - "\u98E3\u98E4\u98E5\u98E6\u98E7\uE9D7\uE9D0\u98E8"+ - "\u98E9\u98EA\u98EB\u98EC\uE9CF\u98ED\u98EE\uC7C1"+ - "\u98EF\u98F0\u98F1\u98F2\u98F3\u98F4\u98F5\u98F6"+ - "\uE9D2\u98F7\u98F8\u98F9\u98FA\u98FB\u98FC\u98FD"+ - "\uE9D9\uB3C8\u98FE\uE9D3\u9940\u9941\u9942\u9943"+ - "\u9944\uCFF0\u9945\u9946\u9947\uE9CD\u9948\u9949"+ - "\u994A\u994B\u994C\u994D\u994E\u994F\u9950\u9951"+ - "\u9952\uB3F7\u9953\u9954\u9955\u9956\u9957\u9958"+ - "\u9959\uE9D6\u995A\u995B\uE9DA\u995C\u995D\u995E"+ - "\uCCB4\u995F\u9960\u9961\uCFAD\u9962\u9963\u9964"+ - "\u9965\u9966\u9967\u9968\u9969\u996A\uE9D5\u996B"+ - "\uE9DC\uE9DB\u996C\u996D\u996E\u996F\u9970\uE9DE"+ - "\u9971\u9972\u9973\u9974\u9975\u9976\u9977\u9978"+ - "\uE9D1\u9979\u997A\u997B\u997C\u997D\u997E\u9980"+ - "\u9981\uE9DD\u9982\uE9DF\uC3CA\u9983\u9984\u9985"+ - "\u9986\u9987\u9988\u9989\u998A\u998B\u998C\u998D"+ - "\u998E\u998F\u9990\u9991\u9992\u9993\u9994\u9995"+ - "\u9996\u9997\u9998\u9999\u999A\u999B\u999C\u999D"+ - "\u999E\u999F\u99A0\u99A1\u99A2\u99A3\u99A4\u99A5"+ - "\u99A6\u99A7\u99A8\u99A9\u99AA\u99AB\u99AC\u99AD"+ - "\u99AE\u99AF\u99B0\u99B1\u99B2\u99B3\u99B4\u99B5"+ - "\u99B6\u99B7\u99B8\u99B9\u99BA\u99BB\u99BC\u99BD"+ - "\u99BE\u99BF\u99C0\u99C1\u99C2\u99C3\u99C4\u99C5"+ - "\u99C6\u99C7\u99C8\u99C9\u99CA\u99CB\u99CC\u99CD"+ - "\u99CE\u99CF\u99D0\u99D1\u99D2\u99D3\u99D4\u99D5"+ - "\u99D6\u99D7\u99D8\u99D9\u99DA\u99DB\u99DC\u99DD"+ - "\u99DE\u99DF\u99E0\u99E1\u99E2\u99E3\u99E4\u99E5"+ - "\u99E6\u99E7\u99E8\u99E9\u99EA\u99EB\u99EC\u99ED"+ - "\u99EE\u99EF\u99F0\u99F1\u99F2\u99F3\u99F4\u99F5"+ - "\uC7B7\uB4CE\uBBB6\uD0C0\uECA3\u99F6\u99F7\uC5B7"+ - "\u99F8\u99F9\u99FA\u99FB\u99FC\u99FD\u99FE\u9A40"+ - "\u9A41\u9A42\uD3FB\u9A43\u9A44\u9A45\u9A46\uECA4"+ - "\u9A47\uECA5\uC6DB\u9A48\u9A49\u9A4A\uBFEE\u9A4B"+ - "\u9A4C\u9A4D\u9A4E\uECA6\u9A4F\u9A50\uECA7\uD0AA"+ - "\u9A51\uC7B8\u9A52\u9A53\uB8E8\u9A54\u9A55\u9A56"+ - "\u9A57\u9A58\u9A59\u9A5A\u9A5B\u9A5C\u9A5D\u9A5E"+ - "\u9A5F\uECA8\u9A60\u9A61\u9A62\u9A63\u9A64\u9A65"+ - "\u9A66\u9A67\uD6B9\uD5FD\uB4CB\uB2BD\uCEE4\uC6E7"+ - "\u9A68\u9A69\uCDE1\u9A6A\u9A6B\u9A6C\u9A6D\u9A6E"+ - "\u9A6F\u9A70\u9A71\u9A72\u9A73\u9A74\u9A75\u9A76"+ - "\u9A77\uB4F5\u9A78\uCBC0\uBCDF\u9A79\u9A7A\u9A7B"+ - "\u9A7C\uE9E2\uE9E3\uD1EA\uE9E5\u9A7D\uB4F9\uE9E4"+ - "\u9A7E\uD1B3\uCAE2\uB2D0\u9A80\uE9E8\u9A81\u9A82"+ - "\u9A83\u9A84\uE9E6\uE9E7\u9A85\u9A86\uD6B3\u9A87"+ - "\u9A88\u9A89\uE9E9\uE9EA\u9A8A\u9A8B\u9A8C\u9A8D"+ - "\u9A8E\uE9EB\u9A8F\u9A90\u9A91\u9A92\u9A93\u9A94"+ - "\u9A95\u9A96\uE9EC\u9A97\u9A98\u9A99\u9A9A\u9A9B"+ - "\u9A9C\u9A9D\u9A9E\uECAF\uC5B9\uB6CE\u9A9F\uD2F3"+ - "\u9AA0\u9AA1\u9AA2\u9AA3\u9AA4\u9AA5\u9AA6\uB5EE"+ - "\u9AA7\uBBD9\uECB1\u9AA8\u9AA9\uD2E3\u9AAA\u9AAB"+ - "\u9AAC\u9AAD\u9AAE\uCEE3\u9AAF\uC4B8\u9AB0\uC3BF"+ - "\u9AB1\u9AB2\uB6BE\uD8B9\uB1C8\uB1CF\uB1D1\uC5FE"+ - "\u9AB3\uB1D0\u9AB4\uC3AB\u9AB5\u9AB6\u9AB7\u9AB8"+ - "\u9AB9\uD5B1\u9ABA\u9ABB\u9ABC\u9ABD\u9ABE\u9ABF"+ - "\u9AC0\u9AC1\uEBA4\uBAC1\u9AC2\u9AC3\u9AC4\uCCBA"+ - "\u9AC5\u9AC6\u9AC7\uEBA5\u9AC8\uEBA7\u9AC9\u9ACA"+ - "\u9ACB\uEBA8\u9ACC\u9ACD\u9ACE\uEBA6\u9ACF\u9AD0"+ - "\u9AD1\u9AD2\u9AD3\u9AD4\u9AD5\uEBA9\uEBAB\uEBAA"+ - "\u9AD6\u9AD7\u9AD8\u9AD9\u9ADA\uEBAC\u9ADB\uCACF"+ - "\uD8B5\uC3F1\u9ADC\uC3A5\uC6F8\uEBAD\uC4CA\u9ADD"+ - "\uEBAE\uEBAF\uEBB0\uB7D5\u9ADE\u9ADF\u9AE0\uB7FA"+ - "\u9AE1\uEBB1\uC7E2\u9AE2\uEBB3\u9AE3\uBAA4\uD1F5"+ - "\uB0B1\uEBB2\uEBB4\u9AE4\u9AE5\u9AE6\uB5AA\uC2C8"+ - "\uC7E8\u9AE7\uEBB5\u9AE8\uCBAE\uE3DF\u9AE9\u9AEA"+ - "\uD3C0\u9AEB\u9AEC\u9AED\u9AEE\uD9DB\u9AEF\u9AF0"+ - "\uCDA1\uD6AD\uC7F3\u9AF1\u9AF2\u9AF3\uD9E0\uBBE3"+ - "\u9AF4\uBABA\uE3E2\u9AF5\u9AF6\u9AF7\u9AF8\u9AF9"+ - "\uCFAB\u9AFA\u9AFB\u9AFC\uE3E0\uC9C7\u9AFD\uBAB9"+ - "\u9AFE\u9B40\u9B41\uD1B4\uE3E1\uC8EA\uB9AF\uBDAD"+ - "\uB3D8\uCEDB\u9B42\u9B43\uCCC0\u9B44\u9B45\u9B46"+ - "\uE3E8\uE3E9\uCDF4\u9B47\u9B48\u9B49\u9B4A\u9B4B"+ - "\uCCAD\u9B4C\uBCB3\u9B4D\uE3EA\u9B4E\uE3EB\u9B4F"+ - "\u9B50\uD0DA\u9B51\u9B52\u9B53\uC6FB\uB7DA\u9B54"+ - "\u9B55\uC7DF\uD2CA\uCED6\u9B56\uE3E4\uE3EC\u9B57"+ - "\uC9F2\uB3C1\u9B58\u9B59\uE3E7\u9B5A\u9B5B\uC6E3"+ - "\uE3E5\u9B5C\u9B5D\uEDB3\uE3E6\u9B5E\u9B5F\u9B60"+ - "\u9B61\uC9B3\u9B62\uC5E6\u9B63\u9B64\u9B65\uB9B5"+ - "\u9B66\uC3BB\u9B67\uE3E3\uC5BD\uC1A4\uC2D9\uB2D7"+ - "\u9B68\uE3ED\uBBA6\uC4AD\u9B69\uE3F0\uBEDA\u9B6A"+ - "\u9B6B\uE3FB\uE3F5\uBAD3\u9B6C\u9B6D\u9B6E\u9B6F"+ - "\uB7D0\uD3CD\u9B70\uD6CE\uD5D3\uB9C1\uD5B4\uD1D8"+ - "\u9B71\u9B72\u9B73\u9B74\uD0B9\uC7F6\u9B75\u9B76"+ - "\u9B77\uC8AA\uB2B4\u9B78\uC3DA\u9B79\u9B7A\u9B7B"+ - "\uE3EE\u9B7C\u9B7D\uE3FC\uE3EF\uB7A8\uE3F7\uE3F4"+ - "\u9B7E\u9B80\u9B81\uB7BA\u9B82\u9B83\uC5A2\u9B84"+ - "\uE3F6\uC5DD\uB2A8\uC6FC\u9B85\uC4E0\u9B86\u9B87"+ - "\uD7A2\u9B88\uC0E1\uE3F9\u9B89\u9B8A\uE3FA\uE3FD"+ - "\uCCA9\uE3F3\u9B8B\uD3BE\u9B8C\uB1C3\uEDB4\uE3F1"+ - "\uE3F2\u9B8D\uE3F8\uD0BA\uC6C3\uD4F3\uE3FE\u9B8E"+ - "\u9B8F\uBDE0\u9B90\u9B91\uE4A7\u9B92\u9B93\uE4A6"+ - "\u9B94\u9B95\u9B96\uD1F3\uE4A3\u9B97\uE4A9\u9B98"+ - "\u9B99\u9B9A\uC8F7\u9B9B\u9B9C\u9B9D\u9B9E\uCFB4"+ - "\u9B9F\uE4A8\uE4AE\uC2E5\u9BA0\u9BA1\uB6B4\u9BA2"+ - "\u9BA3\u9BA4\u9BA5\u9BA6\u9BA7\uBDF2\u9BA8\uE4A2"+ - "\u9BA9\u9BAA\uBAE9\uE4AA\u9BAB\u9BAC\uE4AC\u9BAD"+ - "\u9BAE\uB6FD\uD6DE\uE4B2\u9BAF\uE4AD\u9BB0\u9BB1"+ - "\u9BB2\uE4A1\u9BB3\uBBEE\uCDDD\uC7A2\uC5C9\u9BB4"+ - "\u9BB5\uC1F7\u9BB6\uE4A4\u9BB7\uC7B3\uBDAC\uBDBD"+ - "\uE4A5\u9BB8\uD7C7\uB2E2\u9BB9\uE4AB\uBCC3\uE4AF"+ - "\u9BBA\uBBEB\uE4B0\uC5A8\uE4B1\u9BBB\u9BBC\u9BBD"+ - "\u9BBE\uD5E3\uBFA3\u9BBF\uE4BA\u9BC0\uE4B7\u9BC1"+ - "\uE4BB\u9BC2\u9BC3\uE4BD\u9BC4\u9BC5\uC6D6\u9BC6"+ - "\u9BC7\uBAC6\uC0CB\u9BC8\u9BC9\u9BCA\uB8A1\uE4B4"+ - "\u9BCB\u9BCC\u9BCD\u9BCE\uD4A1\u9BCF\u9BD0\uBAA3"+ - "\uBDFE\u9BD1\u9BD2\u9BD3\uE4BC\u9BD4\u9BD5\u9BD6"+ - "\u9BD7\u9BD8\uCDBF\u9BD9\u9BDA\uC4F9\u9BDB\u9BDC"+ - "\uCFFB\uC9E6\u9BDD\u9BDE\uD3BF\u9BDF\uCFD1\u9BE0"+ - "\u9BE1\uE4B3\u9BE2\uE4B8\uE4B9\uCCE9\u9BE3\u9BE4"+ - "\u9BE5\u9BE6\u9BE7\uCCCE\u9BE8\uC0D4\uE4B5\uC1B0"+ - "\uE4B6\uCED0\u9BE9\uBBC1\uB5D3\u9BEA\uC8F3\uBDA7"+ - "\uD5C7\uC9AC\uB8A2\uE4CA\u9BEB\u9BEC\uE4CC\uD1C4"+ - "\u9BED\u9BEE\uD2BA\u9BEF\u9BF0\uBAAD\u9BF1\u9BF2"+ - "\uBAD4\u9BF3\u9BF4\u9BF5\u9BF6\u9BF7\u9BF8\uE4C3"+ - "\uB5ED\u9BF9\u9BFA\u9BFB\uD7CD\uE4C0\uCFFD\uE4BF"+ - "\u9BFC\u9BFD\u9BFE\uC1DC\uCCCA\u9C40\u9C41\u9C42"+ - "\u9C43\uCAE7\u9C44\u9C45\u9C46\u9C47\uC4D7\u9C48"+ - "\uCCD4\uE4C8\u9C49\u9C4A\u9C4B\uE4C7\uE4C1\u9C4C"+ - "\uE4C4\uB5AD\u9C4D\u9C4E\uD3D9\u9C4F\uE4C6\u9C50"+ - "\u9C51\u9C52\u9C53\uD2F9\uB4E3\u9C54\uBBB4\u9C55"+ - "\u9C56\uC9EE\u9C57\uB4BE\u9C58\u9C59\u9C5A\uBBEC"+ - "\u9C5B\uD1CD\u9C5C\uCCED\uEDB5\u9C5D\u9C5E\u9C5F"+ - "\u9C60\u9C61\u9C62\u9C63\u9C64\uC7E5\u9C65\u9C66"+ - "\u9C67\u9C68\uD4A8\u9C69\uE4CB\uD7D5\uE4C2\u9C6A"+ - "\uBDA5\uE4C5\u9C6B\u9C6C\uD3E6\u9C6D\uE4C9\uC9F8"+ - "\u9C6E\u9C6F\uE4BE\u9C70\u9C71\uD3E5\u9C72\u9C73"+ - "\uC7FE\uB6C9\u9C74\uD4FC\uB2B3\uE4D7\u9C75\u9C76"+ - "\u9C77\uCEC2\u9C78\uE4CD\u9C79\uCEBC\u9C7A\uB8DB"+ - "\u9C7B\u9C7C\uE4D6\u9C7D\uBFCA\u9C7E\u9C80\u9C81"+ - "\uD3CE\u9C82\uC3EC\u9C83\u9C84\u9C85\u9C86\u9C87"+ - "\u9C88\u9C89\u9C8A\uC5C8\uE4D8\u9C8B\u9C8C\u9C8D"+ - "\u9C8E\u9C8F\u9C90\u9C91\u9C92\uCDC4\uE4CF\u9C93"+ - "\u9C94\u9C95\u9C96\uE4D4\uE4D5\u9C97\uBAFE\u9C98"+ - "\uCFE6\u9C99\u9C9A\uD5BF\u9C9B\u9C9C\u9C9D\uE4D2"+ - "\u9C9E\u9C9F\u9CA0\u9CA1\u9CA2\u9CA3\u9CA4\u9CA5"+ - "\u9CA6\u9CA7\u9CA8\uE4D0\u9CA9\u9CAA\uE4CE\u9CAB"+ - "\u9CAC\u9CAD\u9CAE\u9CAF\u9CB0\u9CB1\u9CB2\u9CB3"+ - "\u9CB4\u9CB5\u9CB6\u9CB7\u9CB8\u9CB9\uCDE5\uCAAA"+ - "\u9CBA\u9CBB\u9CBC\uC0A3\u9CBD\uBDA6\uE4D3\u9CBE"+ - "\u9CBF\uB8C8\u9CC0\u9CC1\u9CC2\u9CC3\u9CC4\uE4E7"+ - "\uD4B4\u9CC5\u9CC6\u9CC7\u9CC8\u9CC9\u9CCA\u9CCB"+ - "\uE4DB\u9CCC\u9CCD\u9CCE\uC1EF\u9CCF\u9CD0\uE4E9"+ - "\u9CD1\u9CD2\uD2E7\u9CD3\u9CD4\uE4DF\u9CD5\uE4E0"+ - "\u9CD6\u9CD7\uCFAA\u9CD8\u9CD9\u9CDA\u9CDB\uCBDD"+ - "\u9CDC\uE4DA\uE4D1\u9CDD\uE4E5\u9CDE\uC8DC\uE4E3"+ - "\u9CDF\u9CE0\uC4E7\uE4E2\u9CE1\uE4E1\u9CE2\u9CE3"+ - "\u9CE4\uB3FC\uE4E8\u9CE5\u9CE6\u9CE7\u9CE8\uB5E1"+ - "\u9CE9\u9CEA\u9CEB\uD7CC\u9CEC\u9CED\u9CEE\uE4E6"+ - "\u9CEF\uBBAC\u9CF0\uD7D2\uCCCF\uEBF8\u9CF1\uE4E4"+ - "\u9CF2\u9CF3\uB9F6\u9CF4\u9CF5\u9CF6\uD6CD\uE4D9"+ - "\uE4DC\uC2FA\uE4DE\u9CF7\uC2CB\uC0C4\uC2D0\u9CF8"+ - "\uB1F5\uCCB2\u9CF9\u9CFA\u9CFB\u9CFC\u9CFD\u9CFE"+ - "\u9D40\u9D41\u9D42\u9D43\uB5CE\u9D44\u9D45\u9D46"+ - "\u9D47\uE4EF\u9D48\u9D49\u9D4A\u9D4B\u9D4C\u9D4D"+ - "\u9D4E\u9D4F\uC6AF\u9D50\u9D51\u9D52\uC6E1\u9D53"+ - "\u9D54\uE4F5\u9D55\u9D56\u9D57\u9D58\u9D59\uC2A9"+ - "\u9D5A\u9D5B\u9D5C\uC0EC\uD1DD\uE4EE\u9D5D\u9D5E"+ - "\u9D5F\u9D60\u9D61\u9D62\u9D63\u9D64\u9D65\u9D66"+ - "\uC4AE\u9D67\u9D68\u9D69\uE4ED\u9D6A\u9D6B\u9D6C"+ - "\u9D6D\uE4F6\uE4F4\uC2FE\u9D6E\uE4DD\u9D6F\uE4F0"+ - "\u9D70\uCAFE\u9D71\uD5C4\u9D72\u9D73\uE4F1\u9D74"+ - "\u9D75\u9D76\u9D77\u9D78\u9D79\u9D7A\uD1FA\u9D7B"+ - "\u9D7C\u9D7D\u9D7E\u9D80\u9D81\u9D82\uE4EB\uE4EC"+ - "\u9D83\u9D84\u9D85\uE4F2\u9D86\uCEAB\u9D87\u9D88"+ - "\u9D89\u9D8A\u9D8B\u9D8C\u9D8D\u9D8E\u9D8F\u9D90"+ - "\uC5CB\u9D91\u9D92\u9D93\uC7B1\u9D94\uC2BA\u9D95"+ - "\u9D96\u9D97\uE4EA\u9D98\u9D99\u9D9A\uC1CA\u9D9B"+ - "\u9D9C\u9D9D\u9D9E\u9D9F\u9DA0\uCCB6\uB3B1\u9DA1"+ - "\u9DA2\u9DA3\uE4FB\u9DA4\uE4F3\u9DA5\u9DA6\u9DA7"+ - "\uE4FA\u9DA8\uE4FD\u9DA9\uE4FC\u9DAA\u9DAB\u9DAC"+ - "\u9DAD\u9DAE\u9DAF\u9DB0\uB3CE\u9DB1\u9DB2\u9DB3"+ - "\uB3BA\uE4F7\u9DB4\u9DB5\uE4F9\uE4F8\uC5EC\u9DB6"+ - "\u9DB7\u9DB8\u9DB9\u9DBA\u9DBB\u9DBC\u9DBD\u9DBE"+ - "\u9DBF\u9DC0\u9DC1\u9DC2\uC0BD\u9DC3\u9DC4\u9DC5"+ - "\u9DC6\uD4E8\u9DC7\u9DC8\u9DC9\u9DCA\u9DCB\uE5A2"+ - "\u9DCC\u9DCD\u9DCE\u9DCF\u9DD0\u9DD1\u9DD2\u9DD3"+ - "\u9DD4\u9DD5\u9DD6\uB0C4\u9DD7\u9DD8\uE5A4\u9DD9"+ - "\u9DDA\uE5A3\u9DDB\u9DDC\u9DDD\u9DDE\u9DDF\u9DE0"+ - "\uBCA4\u9DE1\uE5A5\u9DE2\u9DE3\u9DE4\u9DE5\u9DE6"+ - "\u9DE7\uE5A1\u9DE8\u9DE9\u9DEA\u9DEB\u9DEC\u9DED"+ - "\u9DEE\uE4FE\uB1F4\u9DEF\u9DF0\u9DF1\u9DF2\u9DF3"+ - "\u9DF4\u9DF5\u9DF6\u9DF7\u9DF8\u9DF9\uE5A8\u9DFA"+ - "\uE5A9\uE5A6\u9DFB\u9DFC\u9DFD\u9DFE\u9E40\u9E41"+ - "\u9E42\u9E43\u9E44\u9E45\u9E46\u9E47\uE5A7\uE5AA"+ - "\u9E48\u9E49\u9E4A\u9E4B\u9E4C\u9E4D\u9E4E\u9E4F"+ - "\u9E50\u9E51\u9E52\u9E53\u9E54\u9E55\u9E56\u9E57"; - - private static final String innerEncoderIndex7= - "\u9E58\u9E59\u9E5A\u9E5B\u9E5C\u9E5D\u9E5E\u9E5F"+ - "\u9E60\u9E61\u9E62\u9E63\u9E64\u9E65\u9E66\u9E67"+ - "\u9E68\uC6D9\u9E69\u9E6A\u9E6B\u9E6C\u9E6D\u9E6E"+ - "\u9E6F\u9E70\uE5AB\uE5AD\u9E71\u9E72\u9E73\u9E74"+ - "\u9E75\u9E76\u9E77\uE5AC\u9E78\u9E79\u9E7A\u9E7B"+ - "\u9E7C\u9E7D\u9E7E\u9E80\u9E81\u9E82\u9E83\u9E84"+ - "\u9E85\u9E86\u9E87\u9E88\u9E89\uE5AF\u9E8A\u9E8B"+ - "\u9E8C\uE5AE\u9E8D\u9E8E\u9E8F\u9E90\u9E91\u9E92"+ - "\u9E93\u9E94\u9E95\u9E96\u9E97\u9E98\u9E99\u9E9A"+ - "\u9E9B\u9E9C\u9E9D\u9E9E\uB9E0\u9E9F\u9EA0\uE5B0"+ - "\u9EA1\u9EA2\u9EA3\u9EA4\u9EA5\u9EA6\u9EA7\u9EA8"+ - "\u9EA9\u9EAA\u9EAB\u9EAC\u9EAD\u9EAE\uE5B1\u9EAF"+ - "\u9EB0\u9EB1\u9EB2\u9EB3\u9EB4\u9EB5\u9EB6\u9EB7"+ - "\u9EB8\u9EB9\u9EBA\uBBF0\uECE1\uC3F0\u9EBB\uB5C6"+ - "\uBBD2\u9EBC\u9EBD\u9EBE\u9EBF\uC1E9\uD4EE\u9EC0"+ - "\uBEC4\u9EC1\u9EC2\u9EC3\uD7C6\u9EC4\uD4D6\uB2D3"+ - "\uECBE\u9EC5\u9EC6\u9EC7\u9EC8\uEAC1\u9EC9\u9ECA"+ - "\u9ECB\uC2AF\uB4B6\u9ECC\u9ECD\u9ECE\uD1D7\u9ECF"+ - "\u9ED0\u9ED1\uB3B4\u9ED2\uC8B2\uBFBB\uECC0\u9ED3"+ - "\u9ED4\uD6CB\u9ED5\u9ED6\uECBF\uECC1\u9ED7\u9ED8"+ - "\u9ED9\u9EDA\u9EDB\u9EDC\u9EDD\u9EDE\u9EDF\u9EE0"+ - "\u9EE1\u9EE2\u9EE3\uECC5\uBEE6\uCCBF\uC5DA\uBEBC"+ - "\u9EE4\uECC6\u9EE5\uB1FE\u9EE6\u9EE7\u9EE8\uECC4"+ - "\uD5A8\uB5E3\u9EE9\uECC2\uC1B6\uB3E3\u9EEA\u9EEB"+ - "\uECC3\uCBB8\uC0C3\uCCFE\u9EEC\u9EED\u9EEE\u9EEF"+ - "\uC1D2\u9EF0\uECC8\u9EF1\u9EF2\u9EF3\u9EF4\u9EF5"+ - "\u9EF6\u9EF7\u9EF8\u9EF9\u9EFA\u9EFB\u9EFC\u9EFD"+ - "\uBAE6\uC0D3\u9EFE\uD6F2\u9F40\u9F41\u9F42\uD1CC"+ - "\u9F43\u9F44\u9F45\u9F46\uBFBE\u9F47\uB7B3\uC9D5"+ - "\uECC7\uBBE2\u9F48\uCCCC\uBDFD\uC8C8\u9F49\uCFA9"+ - "\u9F4A\u9F4B\u9F4C\u9F4D\u9F4E\u9F4F\u9F50\uCDE9"+ - "\u9F51\uC5EB\u9F52\u9F53\u9F54\uB7E9\u9F55\u9F56"+ - "\u9F57\u9F58\u9F59\u9F5A\u9F5B\u9F5C\u9F5D\u9F5E"+ - "\u9F5F\uD1C9\uBAB8\u9F60\u9F61\u9F62\u9F63\u9F64"+ - "\uECC9\u9F65\u9F66\uECCA\u9F67\uBBC0\uECCB\u9F68"+ - "\uECE2\uB1BA\uB7D9\u9F69\u9F6A\u9F6B\u9F6C\u9F6D"+ - "\u9F6E\u9F6F\u9F70\u9F71\u9F72\u9F73\uBDB9\u9F74"+ - "\u9F75\u9F76\u9F77\u9F78\u9F79\u9F7A\u9F7B\uECCC"+ - "\uD1E6\uECCD\u9F7C\u9F7D\u9F7E\u9F80\uC8BB\u9F81"+ - "\u9F82\u9F83\u9F84\u9F85\u9F86\u9F87\u9F88\u9F89"+ - "\u9F8A\u9F8B\u9F8C\u9F8D\u9F8E\uECD1\u9F8F\u9F90"+ - "\u9F91\u9F92\uECD3\u9F93\uBBCD\u9F94\uBCE5\u9F95"+ - "\u9F96\u9F97\u9F98\u9F99\u9F9A\u9F9B\u9F9C\u9F9D"+ - "\u9F9E\u9F9F\u9FA0\u9FA1\uECCF\u9FA2\uC9B7\u9FA3"+ - "\u9FA4\u9FA5\u9FA6\u9FA7\uC3BA\u9FA8\uECE3\uD5D5"+ - "\uECD0\u9FA9\u9FAA\u9FAB\u9FAC\u9FAD\uD6F3\u9FAE"+ - "\u9FAF\u9FB0\uECD2\uECCE\u9FB1\u9FB2\u9FB3\u9FB4"+ - "\uECD4\u9FB5\uECD5\u9FB6\u9FB7\uC9BF\u9FB8\u9FB9"+ - "\u9FBA\u9FBB\u9FBC\u9FBD\uCFA8\u9FBE\u9FBF\u9FC0"+ - "\u9FC1\u9FC2\uD0DC\u9FC3\u9FC4\u9FC5\u9FC6\uD1AC"+ - "\u9FC7\u9FC8\u9FC9\u9FCA\uC8DB\u9FCB\u9FCC\u9FCD"+ - "\uECD6\uCEF5\u9FCE\u9FCF\u9FD0\u9FD1\u9FD2\uCAEC"+ - "\uECDA\u9FD3\u9FD4\u9FD5\u9FD6\u9FD7\u9FD8\u9FD9"+ - "\uECD9\u9FDA\u9FDB\u9FDC\uB0BE\u9FDD\u9FDE\u9FDF"+ - "\u9FE0\u9FE1\u9FE2\uECD7\u9FE3\uECD8\u9FE4\u9FE5"+ - "\u9FE6\uECE4\u9FE7\u9FE8\u9FE9\u9FEA\u9FEB\u9FEC"+ - "\u9FED\u9FEE\u9FEF\uC8BC\u9FF0\u9FF1\u9FF2\u9FF3"+ - "\u9FF4\u9FF5\u9FF6\u9FF7\u9FF8\u9FF9\uC1C7\u9FFA"+ - "\u9FFB\u9FFC\u9FFD\u9FFE\uECDC\uD1E0\uA040\uA041"+ - "\uA042\uA043\uA044\uA045\uA046\uA047\uA048\uA049"+ - "\uECDB\uA04A\uA04B\uA04C\uA04D\uD4EF\uA04E\uECDD"+ - "\uA04F\uA050\uA051\uA052\uA053\uA054\uDBC6\uA055"+ - "\uA056\uA057\uA058\uA059\uA05A\uA05B\uA05C\uA05D"+ - "\uA05E\uECDE\uA05F\uA060\uA061\uA062\uA063\uA064"+ - "\uA065\uA066\uA067\uA068\uA069\uA06A\uB1AC\uA06B"+ - "\uA06C\uA06D\uA06E\uA06F\uA070\uA071\uA072\uA073"+ - "\uA074\uA075\uA076\uA077\uA078\uA079\uA07A\uA07B"+ - "\uA07C\uA07D\uA07E\uA080\uA081\uECDF\uA082\uA083"+ - "\uA084\uA085\uA086\uA087\uA088\uA089\uA08A\uA08B"+ - "\uECE0\uA08C\uD7A6\uA08D\uC5C0\uA08E\uA08F\uA090"+ - "\uEBBC\uB0AE\uA091\uA092\uA093\uBEF4\uB8B8\uD2AF"+ - "\uB0D6\uB5F9\uA094\uD8B3\uA095\uCBAC\uA096\uE3DD"+ - "\uA097\uA098\uA099\uA09A\uA09B\uA09C\uA09D\uC6AC"+ - "\uB0E6\uA09E\uA09F\uA0A0\uC5C6\uEBB9\uA0A1\uA0A2"+ - "\uA0A3\uA0A4\uEBBA\uA0A5\uA0A6\uA0A7\uEBBB\uA0A8"+ - "\uA0A9\uD1C0\uA0AA\uC5A3\uA0AB\uEAF2\uA0AC\uC4B2"+ - "\uA0AD\uC4B5\uC0CE\uA0AE\uA0AF\uA0B0\uEAF3\uC4C1"+ - "\uA0B1\uCEEF\uA0B2\uA0B3\uA0B4\uA0B5\uEAF0\uEAF4"+ - "\uA0B6\uA0B7\uC9FC\uA0B8\uA0B9\uC7A3\uA0BA\uA0BB"+ - "\uA0BC\uCCD8\uCEFE\uA0BD\uA0BE\uA0BF\uEAF5\uEAF6"+ - "\uCFAC\uC0E7\uA0C0\uA0C1\uEAF7\uA0C2\uA0C3\uA0C4"+ - "\uA0C5\uA0C6\uB6BF\uEAF8\uA0C7\uEAF9\uA0C8\uEAFA"+ - "\uA0C9\uA0CA\uEAFB\uA0CB\uA0CC\uA0CD\uA0CE\uA0CF"+ - "\uA0D0\uA0D1\uA0D2\uA0D3\uA0D4\uA0D5\uA0D6\uEAF1"+ - "\uA0D7\uA0D8\uA0D9\uA0DA\uA0DB\uA0DC\uA0DD\uA0DE"+ - "\uA0DF\uA0E0\uA0E1\uA0E2\uC8AE\uE1EB\uA0E3\uB7B8"+ - "\uE1EC\uA0E4\uA0E5\uA0E6\uE1ED\uA0E7\uD7B4\uE1EE"+ - "\uE1EF\uD3CC\uA0E8\uA0E9\uA0EA\uA0EB\uA0EC\uA0ED"+ - "\uA0EE\uE1F1\uBFF1\uE1F0\uB5D2\uA0EF\uA0F0\uA0F1"+ - "\uB1B7\uA0F2\uA0F3\uA0F4\uA0F5\uE1F3\uE1F2\uA0F6"+ - "\uBAFC\uA0F7\uE1F4\uA0F8\uA0F9\uA0FA\uA0FB\uB9B7"+ - "\uA0FC\uBED1\uA0FD\uA0FE\uAA40\uAA41\uC4FC\uAA42"+ - "\uBADD\uBDC6\uAA43\uAA44\uAA45\uAA46\uAA47\uAA48"+ - "\uE1F5\uE1F7\uAA49\uAA4A\uB6C0\uCFC1\uCAA8\uE1F6"+ - "\uD5F8\uD3FC\uE1F8\uE1FC\uE1F9\uAA4B\uAA4C\uE1FA"+ - "\uC0EA\uAA4D\uE1FE\uE2A1\uC0C7\uAA4E\uAA4F\uAA50"+ - "\uAA51\uE1FB\uAA52\uE1FD\uAA53\uAA54\uAA55\uAA56"+ - "\uAA57\uAA58\uE2A5\uAA59\uAA5A\uAA5B\uC1D4\uAA5C"+ - "\uAA5D\uAA5E\uAA5F\uE2A3\uAA60\uE2A8\uB2FE\uE2A2"+ - "\uAA61\uAA62\uAA63\uC3CD\uB2C2\uE2A7\uE2A6\uAA64"+ - "\uAA65\uE2A4\uE2A9\uAA66\uAA67\uE2AB\uAA68\uAA69"+ - "\uAA6A\uD0C9\uD6ED\uC3A8\uE2AC\uAA6B\uCFD7\uAA6C"+ - "\uAA6D\uE2AE\uAA6E\uAA6F\uBAEF\uAA70\uAA71\uE9E0"+ - "\uE2AD\uE2AA\uAA72\uAA73\uAA74\uAA75\uBBAB\uD4B3"+ - "\uAA76\uAA77\uAA78\uAA79\uAA7A\uAA7B\uAA7C\uAA7D"+ - "\uAA7E\uAA80\uAA81\uAA82\uAA83\uE2B0\uAA84\uAA85"+ - "\uE2AF\uAA86\uE9E1\uAA87\uAA88\uAA89\uAA8A\uE2B1"+ - "\uAA8B\uAA8C\uAA8D\uAA8E\uAA8F\uAA90\uAA91\uAA92"+ - "\uE2B2\uAA93\uAA94\uAA95\uAA96\uAA97\uAA98\uAA99"+ - "\uAA9A\uAA9B\uAA9C\uAA9D\uE2B3\uCCA1\uAA9E\uE2B4"+ - "\uAA9F\uAAA0\uAB40\uAB41\uAB42\uAB43\uAB44\uAB45"+ - "\uAB46\uAB47\uAB48\uAB49\uAB4A\uAB4B\uE2B5\uAB4C"+ - "\uAB4D\uAB4E\uAB4F\uAB50\uD0FE\uAB51\uAB52\uC2CA"+ - "\uAB53\uD3F1\uAB54\uCDF5\uAB55\uAB56\uE7E0\uAB57"+ - "\uAB58\uE7E1\uAB59\uAB5A\uAB5B\uAB5C\uBEC1\uAB5D"+ - "\uAB5E\uAB5F\uAB60\uC2EA\uAB61\uAB62\uAB63\uE7E4"+ - "\uAB64\uAB65\uE7E3\uAB66\uAB67\uAB68\uAB69\uAB6A"+ - "\uAB6B\uCDE6\uAB6C\uC3B5\uAB6D\uAB6E\uE7E2\uBBB7"+ - "\uCFD6\uAB6F\uC1E1\uE7E9\uAB70\uAB71\uAB72\uE7E8"+ - "\uAB73\uAB74\uE7F4\uB2A3\uAB75\uAB76\uAB77\uAB78"+ - "\uE7EA\uAB79\uE7E6\uAB7A\uAB7B\uAB7C\uAB7D\uAB7E"+ - "\uE7EC\uE7EB\uC9BA\uAB80\uAB81\uD5E4\uAB82\uE7E5"+ - "\uB7A9\uE7E7\uAB83\uAB84\uAB85\uAB86\uAB87\uAB88"+ - "\uAB89\uE7EE\uAB8A\uAB8B\uAB8C\uAB8D\uE7F3\uAB8E"+ - "\uD6E9\uAB8F\uAB90\uAB91\uAB92\uE7ED\uAB93\uE7F2"+ - "\uAB94\uE7F1\uAB95\uAB96\uAB97\uB0E0\uAB98\uAB99"+ - "\uAB9A\uAB9B\uE7F5\uAB9C\uAB9D\uAB9E\uAB9F\uABA0"+ - "\uAC40\uAC41\uAC42\uAC43\uAC44\uAC45\uAC46\uAC47"+ - "\uAC48\uAC49\uAC4A\uC7F2\uAC4B\uC0C5\uC0ED\uAC4C"+ - "\uAC4D\uC1F0\uE7F0\uAC4E\uAC4F\uAC50\uAC51\uE7F6"+ - "\uCBF6\uAC52\uAC53\uAC54\uAC55\uAC56\uAC57\uAC58"+ - "\uAC59\uAC5A\uE8A2\uE8A1\uAC5B\uAC5C\uAC5D\uAC5E"+ - "\uAC5F\uAC60\uD7C1\uAC61\uAC62\uE7FA\uE7F9\uAC63"+ - "\uE7FB\uAC64\uE7F7\uAC65\uE7FE\uAC66\uE7FD\uAC67"+ - "\uE7FC\uAC68\uAC69\uC1D5\uC7D9\uC5FD\uC5C3\uAC6A"+ - "\uAC6B\uAC6C\uAC6D\uAC6E\uC7ED\uAC6F\uAC70\uAC71"+ - "\uAC72\uE8A3\uAC73\uAC74\uAC75\uAC76\uAC77\uAC78"+ - "\uAC79\uAC7A\uAC7B\uAC7C\uAC7D\uAC7E\uAC80\uAC81"+ - "\uAC82\uAC83\uAC84\uAC85\uAC86\uE8A6\uAC87\uE8A5"+ - "\uAC88\uE8A7\uBAF7\uE7F8\uE8A4\uAC89\uC8F0\uC9AA"+ - "\uAC8A\uAC8B\uAC8C\uAC8D\uAC8E\uAC8F\uAC90\uAC91"+ - "\uAC92\uAC93\uAC94\uAC95\uAC96\uE8A9\uAC97\uAC98"+ - "\uB9E5\uAC99\uAC9A\uAC9B\uAC9C\uAC9D\uD1FE\uE8A8"+ - "\uAC9E\uAC9F\uACA0\uAD40\uAD41\uAD42\uE8AA\uAD43"+ - "\uE8AD\uE8AE\uAD44\uC1A7\uAD45\uAD46\uAD47\uE8AF"+ - "\uAD48\uAD49\uAD4A\uE8B0\uAD4B\uAD4C\uE8AC\uAD4D"+ - "\uE8B4\uAD4E\uAD4F\uAD50\uAD51\uAD52\uAD53\uAD54"+ - "\uAD55\uAD56\uAD57\uAD58\uE8AB\uAD59\uE8B1\uAD5A"+ - "\uAD5B\uAD5C\uAD5D\uAD5E\uAD5F\uAD60\uAD61\uE8B5"+ - "\uE8B2\uE8B3\uAD62\uAD63\uAD64\uAD65\uAD66\uAD67"+ - "\uAD68\uAD69\uAD6A\uAD6B\uAD6C\uAD6D\uAD6E\uAD6F"+ - "\uAD70\uAD71\uE8B7\uAD72\uAD73\uAD74\uAD75\uAD76"+ - "\uAD77\uAD78\uAD79\uAD7A\uAD7B\uAD7C\uAD7D\uAD7E"+ - "\uAD80\uAD81\uAD82\uAD83\uAD84\uAD85\uAD86\uAD87"+ - "\uAD88\uAD89\uE8B6\uAD8A\uAD8B\uAD8C\uAD8D\uAD8E"+ - "\uAD8F\uAD90\uAD91\uAD92\uB9CF\uAD93\uF0AC\uAD94"+ - "\uF0AD\uAD95\uC6B0\uB0EA\uC8BF\uAD96\uCDDF\uAD97"+ - "\uAD98\uAD99\uAD9A\uAD9B\uAD9C\uAD9D\uCECD\uEAB1"+ - "\uAD9E\uAD9F\uADA0\uAE40\uEAB2\uAE41\uC6BF\uB4C9"+ - "\uAE42\uAE43\uAE44\uAE45\uAE46\uAE47\uAE48\uEAB3"+ - "\uAE49\uAE4A\uAE4B\uAE4C\uD5E7\uAE4D\uAE4E\uAE4F"+ - "\uAE50\uAE51\uAE52\uAE53\uAE54\uDDF9\uAE55\uEAB4"+ - "\uAE56\uEAB5\uAE57\uEAB6\uAE58\uAE59\uAE5A\uAE5B"+ - "\uB8CA\uDFB0\uC9F5\uAE5C\uCCF0\uAE5D\uAE5E\uC9FA"+ - "\uAE5F\uAE60\uAE61\uAE62\uAE63\uC9FB\uAE64\uAE65"+ - "\uD3C3\uCBA6\uAE66\uB8A6\uF0AE\uB1C2\uAE67\uE5B8"+ - "\uCCEF\uD3C9\uBCD7\uC9EA\uAE68\uB5E7\uAE69\uC4D0"+ - "\uB5E9\uAE6A\uEEAE\uBBAD\uAE6B\uAE6C\uE7DE\uAE6D"+ - "\uEEAF\uAE6E\uAE6F\uAE70\uAE71\uB3A9\uAE72\uAE73"+ - "\uEEB2\uAE74\uAE75\uEEB1\uBDE7\uAE76\uEEB0\uCEB7"+ - "\uAE77\uAE78\uAE79\uAE7A\uC5CF\uAE7B\uAE7C\uAE7D"+ - "\uAE7E\uC1F4\uDBCE\uEEB3\uD0F3\uAE80\uAE81\uAE82"+ - "\uAE83\uAE84\uAE85\uAE86\uAE87\uC2D4\uC6E8\uAE88"+ - "\uAE89\uAE8A\uB7AC\uAE8B\uAE8C\uAE8D\uAE8E\uAE8F"+ - "\uAE90\uAE91\uEEB4\uAE92\uB3EB\uAE93\uAE94\uAE95"+ - "\uBBFB\uEEB5\uAE96\uAE97\uAE98\uAE99\uAE9A\uE7DC"+ - "\uAE9B\uAE9C\uAE9D\uEEB6\uAE9E\uAE9F\uBDAE\uAEA0"+ - "\uAF40\uAF41\uAF42\uF1E2\uAF43\uAF44\uAF45\uCAE8"+ - "\uAF46\uD2C9\uF0DA\uAF47\uF0DB\uAF48\uF0DC\uC1C6"+ - "\uAF49\uB8ED\uBECE\uAF4A\uAF4B\uF0DE\uAF4C\uC5B1"+ - "\uF0DD\uD1F1\uAF4D\uF0E0\uB0CC\uBDEA\uAF4E\uAF4F"+ - "\uAF50\uAF51\uAF52\uD2DF\uF0DF\uAF53\uB4AF\uB7E8"+ - "\uF0E6\uF0E5\uC6A3\uF0E1\uF0E2\uB4C3\uAF54\uAF55"+ - "\uF0E3\uD5EE\uAF56\uAF57\uCCDB\uBED2\uBCB2\uAF58"+ - "\uAF59\uAF5A\uF0E8\uF0E7\uF0E4\uB2A1\uAF5B\uD6A2"+ - "\uD3B8\uBEB7\uC8AC\uAF5C\uAF5D\uF0EA\uAF5E\uAF5F"+ - "\uAF60\uAF61\uD1F7\uAF62\uD6CC\uBADB\uF0E9\uAF63"+ - "\uB6BB\uAF64\uAF65\uCDB4\uAF66\uAF67\uC6A6\uAF68"+ - "\uAF69\uAF6A\uC1A1\uF0EB\uF0EE\uAF6B\uF0ED\uF0F0"+ - "\uF0EC\uAF6C\uBBBE\uF0EF\uAF6D\uAF6E\uAF6F\uAF70"+ - "\uCCB5\uF0F2\uAF71\uAF72\uB3D5\uAF73\uAF74\uAF75"+ - "\uAF76\uB1D4\uAF77\uAF78\uF0F3\uAF79\uAF7A\uF0F4"+ - "\uF0F6\uB4E1\uAF7B\uF0F1\uAF7C\uF0F7\uAF7D\uAF7E"+ - "\uAF80\uAF81\uF0FA\uAF82\uF0F8\uAF83\uAF84\uAF85"+ - "\uF0F5\uAF86\uAF87\uAF88\uAF89\uF0FD\uAF8A\uF0F9"+ - "\uF0FC\uF0FE\uAF8B\uF1A1\uAF8C\uAF8D\uAF8E\uCEC1"+ - "\uF1A4\uAF8F\uF1A3\uAF90\uC1F6\uF0FB\uCADD\uAF91"+ - "\uAF92\uB4F1\uB1F1\uCCB1\uAF93\uF1A6\uAF94\uAF95"+ - "\uF1A7\uAF96\uAF97\uF1AC\uD5CE\uF1A9\uAF98\uAF99"+ - "\uC8B3\uAF9A\uAF9B\uAF9C\uF1A2\uAF9D\uF1AB\uF1A8"+ - "\uF1A5\uAF9E\uAF9F\uF1AA\uAFA0\uB040\uB041\uB042"+ - "\uB043\uB044\uB045\uB046\uB0A9\uF1AD\uB047\uB048"+ - "\uB049\uB04A\uB04B\uB04C\uF1AF\uB04D\uF1B1\uB04E"+ - "\uB04F\uB050\uB051\uB052\uF1B0\uB053\uF1AE\uB054"+ - "\uB055\uB056\uB057\uD1A2\uB058\uB059\uB05A\uB05B"+ - "\uB05C\uB05D\uB05E\uF1B2\uB05F\uB060\uB061\uF1B3"+ - "\uB062\uB063\uB064\uB065\uB066\uB067\uB068\uB069"+ - "\uB9EF\uB06A\uB06B\uB5C7\uB06C\uB0D7\uB0D9\uB06D"+ - "\uB06E\uB06F\uD4ED\uB070\uB5C4\uB071\uBDD4\uBBCA"+ - "\uF0A7\uB072\uB073\uB8DE\uB074\uB075\uF0A8\uB076"+ - "\uB077\uB0A8\uB078\uF0A9\uB079\uB07A\uCDEE\uB07B"+ - "\uB07C\uF0AA\uB07D\uB07E\uB080\uB081\uB082\uB083"+ - "\uB084\uB085\uB086\uB087\uF0AB\uB088\uB089\uB08A"+ - "\uB08B\uB08C\uB08D\uB08E\uB08F\uB090\uC6A4\uB091"+ - "\uB092\uD6E5\uF1E4\uB093\uF1E5\uB094\uB095\uB096"+ - "\uB097\uB098\uB099\uB09A\uB09B\uB09C\uB09D\uC3F3"+ - "\uB09E\uB09F\uD3DB\uB0A0\uB140\uD6D1\uC5E8\uB141"+ - "\uD3AF\uB142\uD2E6\uB143\uB144\uEEC1\uB0BB\uD5B5"+ - "\uD1CE\uBCE0\uBAD0\uB145\uBFF8\uB146\uB8C7\uB5C1"+ - "\uC5CC\uB147\uB148\uCAA2\uB149\uB14A\uB14B\uC3CB"+ - "\uB14C\uB14D\uB14E\uB14F\uB150\uEEC2\uB151\uB152"+ - "\uB153\uB154\uB155\uB156\uB157\uB158\uC4BF\uB6A2"+ - "\uB159\uEDEC\uC3A4\uB15A\uD6B1\uB15B\uB15C\uB15D"+ - "\uCFE0\uEDEF\uB15E\uB15F\uC5CE\uB160\uB6DC\uB161"+ - "\uB162\uCAA1\uB163\uB164\uEDED\uB165\uB166\uEDF0"+ - "\uEDF1\uC3BC\uB167\uBFB4\uB168\uEDEE\uB169\uB16A"+ - "\uB16B\uB16C\uB16D\uB16E\uB16F\uB170\uB171\uB172"+ - "\uB173\uEDF4\uEDF2\uB174\uB175\uB176\uB177\uD5E6"+ - "\uC3DF\uB178\uEDF3\uB179\uB17A\uB17B\uEDF6\uB17C"+ - "\uD5A3\uD1A3\uB17D\uB17E\uB180\uEDF5\uB181\uC3D0"+ - "\uB182\uB183\uB184\uB185\uB186\uEDF7\uBFF4\uBEEC"+ - "\uEDF8\uB187\uCCF7\uB188\uD1DB\uB189\uB18A\uB18B"+ - "\uD7C5\uD5F6\uB18C\uEDFC\uB18D\uB18E\uB18F\uEDFB"+ - "\uB190\uB191\uB192\uB193\uB194\uB195\uB196\uB197"+ - "\uEDF9\uEDFA\uB198\uB199\uB19A\uB19B\uB19C\uB19D"+ - "\uB19E\uB19F\uEDFD\uBEA6\uB1A0\uB240\uB241\uB242"+ - "\uB243\uCBAF\uEEA1\uB6BD\uB244\uEEA2\uC4C0\uB245"+ - "\uEDFE\uB246\uB247\uBDDE\uB2C7\uB248\uB249\uB24A"+ - "\uB24B\uB24C\uB24D\uB24E\uB24F\uB250\uB251\uB252"+ - "\uB253\uB6C3\uB254\uB255\uB256\uEEA5\uD8BA\uEEA3"+ - "\uEEA6\uB257\uB258\uB259\uC3E9\uB3F2\uB25A\uB25B"+ - "\uB25C\uB25D\uB25E\uB25F\uEEA7\uEEA4\uCFB9\uB260"+ - "\uB261\uEEA8\uC2F7\uB262\uB263\uB264\uB265\uB266"+ - "\uB267\uB268\uB269\uB26A\uB26B\uB26C\uB26D\uEEA9"+ - "\uEEAA\uB26E\uDEAB\uB26F\uB270\uC6B3\uB271\uC7C6"+ - "\uB272\uD6F5\uB5C9\uB273\uCBB2\uB274\uB275\uB276"+ - "\uEEAB\uB277\uB278\uCDAB\uB279\uEEAC\uB27A\uB27B"+ - "\uB27C\uB27D\uB27E\uD5B0\uB280\uEEAD\uB281\uF6C4"+ - "\uB282\uB283\uB284\uB285\uB286\uB287\uB288\uB289"+ - "\uB28A\uB28B\uB28C\uB28D\uB28E\uDBC7\uB28F\uB290"+ - "\uB291\uB292\uB293\uB294\uB295\uB296\uB297\uB4A3"+ - "\uB298\uB299\uB29A\uC3AC\uF1E6\uB29B\uB29C\uB29D"+ - "\uB29E\uB29F\uCAB8\uD2D3\uB2A0\uD6AA\uB340\uEFF2"+ - "\uB341\uBED8\uB342\uBDC3\uEFF3\uB6CC\uB0AB\uB343"+ - "\uB344\uB345\uB346\uCAAF\uB347\uB348\uEDB6\uB349"+ - "\uEDB7\uB34A\uB34B\uB34C\uB34D\uCEF9\uB7AF\uBFF3"+ - "\uEDB8\uC2EB\uC9B0\uB34E\uB34F\uB350\uB351\uB352"+ - "\uB353\uEDB9\uB354\uB355\uC6F6\uBFB3\uB356\uB357"+ - "\uB358\uEDBC\uC5F8\uB359\uD1D0\uB35A\uD7A9\uEDBA"+ - "\uEDBB\uB35B\uD1E2\uB35C\uEDBF\uEDC0\uB35D\uEDC4"+ - "\uB35E\uB35F\uB360\uEDC8\uB361\uEDC6\uEDCE\uD5E8"+ - "\uB362\uEDC9\uB363\uB364\uEDC7\uEDBE\uB365\uB366"+ - "\uC5E9\uB367\uB368\uB369\uC6C6\uB36A\uB36B\uC9E9"+ - "\uD4D2\uEDC1\uEDC2\uEDC3\uEDC5\uB36C\uC0F9\uB36D"+ - "\uB4A1\uB36E\uB36F\uB370\uB371\uB9E8\uB372\uEDD0"+ - "\uB373\uB374\uB375\uB376\uEDD1\uB377\uEDCA\uB378"+ - "\uEDCF\uB379\uCEF8\uB37A\uB37B\uCBB6\uEDCC\uEDCD"+ - "\uB37C\uB37D\uB37E\uB380\uB381\uCFF5\uB382\uB383"+ - "\uB384\uB385\uB386\uB387\uB388\uB389\uB38A\uB38B"+ - "\uB38C\uB38D\uEDD2\uC1F2\uD3B2\uEDCB\uC8B7\uB38E"+ - "\uB38F\uB390\uB391\uB392\uB393\uB394\uB395\uBCEF"+ - "\uB396\uB397\uB398\uB399\uC5F0\uB39A\uB39B\uB39C"+ - "\uB39D\uB39E\uB39F\uB3A0\uB440\uB441\uB442\uEDD6"+ - "\uB443\uB5EF\uB444\uB445\uC2B5\uB0AD\uCBE9\uB446"+ - "\uB447\uB1AE\uB448\uEDD4\uB449\uB44A\uB44B\uCDEB"+ - "\uB5E2\uB44C\uEDD5\uEDD3\uEDD7\uB44D\uB44E\uB5FA"+ - "\uB44F\uEDD8\uB450\uEDD9\uB451\uEDDC\uB452\uB1CC"+ - "\uB453\uB454\uB455\uB456\uB457\uB458\uB459\uB45A"+ - "\uC5F6\uBCEE\uEDDA\uCCBC\uB2EA\uB45B\uB45C\uB45D"+ - "\uB45E\uEDDB\uB45F\uB460\uB461\uB462\uC4EB\uB463"+ - "\uB464\uB4C5\uB465\uB466\uB467\uB0F5\uB468\uB469"+ - "\uB46A\uEDDF\uC0DA\uB4E8\uB46B\uB46C\uB46D\uB46E"+ - "\uC5CD\uB46F\uB470\uB471\uEDDD\uBFC4\uB472\uB473"+ - "\uB474\uEDDE\uB475\uB476\uB477\uB478\uB479\uB47A"+ - "\uB47B\uB47C\uB47D\uB47E\uB480\uB481\uB482\uB483"+ - "\uC4A5\uB484\uB485\uB486\uEDE0\uB487\uB488\uB489"+ - "\uB48A\uB48B\uEDE1\uB48C\uEDE3\uB48D\uB48E\uC1D7"+ - "\uB48F\uB490\uBBC7\uB491\uB492\uB493\uB494\uB495"+ - "\uB496\uBDB8\uB497\uB498\uB499\uEDE2\uB49A\uB49B"+ - "\uB49C\uB49D\uB49E\uB49F\uB4A0\uB540\uB541\uB542"+ - "\uB543\uB544\uB545\uEDE4\uB546\uB547\uB548\uB549"+ - "\uB54A\uB54B\uB54C\uB54D\uB54E\uB54F\uEDE6\uB550"+ - "\uB551\uB552\uB553\uB554\uEDE5\uB555\uB556\uB557"+ - "\uB558\uB559\uB55A\uB55B\uB55C\uB55D\uB55E\uB55F"+ - "\uB560\uB561\uB562\uB563\uEDE7\uB564\uB565\uB566"+ - "\uB567\uB568\uCABE\uECEA\uC0F1\uB569\uC9E7\uB56A"+ - "\uECEB\uC6EE\uB56B\uB56C\uB56D\uB56E\uECEC\uB56F"+ - "\uC6ED\uECED\uB570\uB571\uB572\uB573\uB574\uB575"+ - "\uB576\uB577\uB578\uECF0\uB579\uB57A\uD7E6\uECF3"+ - "\uB57B\uB57C\uECF1\uECEE\uECEF\uD7A3\uC9F1\uCBEE"+ - "\uECF4\uB57D\uECF2\uB57E\uB580\uCFE9\uB581\uECF6"+ - "\uC6B1\uB582\uB583\uB584\uB585\uBCC0\uB586\uECF5"+ - "\uB587\uB588\uB589\uB58A\uB58B\uB58C\uB58D\uB5BB"+ - "\uBBF6\uB58E\uECF7\uB58F\uB590\uB591\uB592\uB593"+ - "\uD9F7\uBDFB\uB594\uB595\uC2BB\uECF8\uB596\uB597"+ - "\uB598\uB599\uECF9\uB59A\uB59B\uB59C\uB59D\uB8A3"+ - "\uB59E\uB59F\uB5A0\uB640\uB641\uB642\uB643\uB644"+ - "\uB645\uB646\uECFA\uB647\uB648\uB649\uB64A\uB64B"+ - "\uB64C\uB64D\uB64E\uB64F\uB650\uB651\uB652\uECFB"+ - "\uB653\uB654\uB655\uB656\uB657\uB658\uB659\uB65A"+ - "\uB65B\uB65C\uB65D\uECFC\uB65E\uB65F\uB660\uB661"+ - "\uB662\uD3ED\uD8AE\uC0EB\uB663\uC7DD\uBACC\uB664"+ - "\uD0E3\uCBBD\uB665\uCDBA\uB666\uB667\uB8D1\uB668"+ - "\uB669\uB1FC\uB66A\uC7EF\uB66B\uD6D6\uB66C\uB66D"+ - "\uB66E\uBFC6\uC3EB\uB66F\uB670\uEFF5\uB671\uB672"+ - "\uC3D8\uB673\uB674\uB675\uB676\uB677\uB678\uD7E2"+ - "\uB679\uB67A\uB67B\uEFF7\uB3D3\uB67C\uC7D8\uD1ED"+ - "\uB67D\uD6C8\uB67E\uEFF8\uB680\uEFF6\uB681\uBBFD"+ - "\uB3C6\uB682\uB683\uB684\uB685\uB686\uB687\uB688"+ - "\uBDD5\uB689\uB68A\uD2C6\uB68B\uBBE0\uB68C\uB68D"+ - "\uCFA1\uB68E\uEFFC\uEFFB\uB68F\uB690\uEFF9\uB691"+ - "\uB692\uB693\uB694\uB3CC\uB695\uC9D4\uCBB0\uB696"+ - "\uB697\uB698\uB699\uB69A\uEFFE\uB69B\uB69C\uB0DE"+ - "\uB69D\uB69E\uD6C9\uB69F\uB6A0\uB740\uEFFD\uB741"+ - "\uB3ED\uB742\uB743\uF6D5\uB744\uB745\uB746\uB747"+ - "\uB748\uB749\uB74A\uB74B\uB74C\uB74D\uB74E\uB74F"+ - "\uB750\uB751\uB752\uCEC8\uB753\uB754\uB755\uF0A2"+ - "\uB756\uF0A1\uB757\uB5BE\uBCDA\uBBFC\uB758\uB8E5"+ - "\uB759\uB75A\uB75B\uB75C\uB75D\uB75E\uC4C2\uB75F"+ - "\uB760\uB761\uB762\uB763\uB764\uB765\uB766\uB767"+ - "\uB768\uF0A3\uB769\uB76A\uB76B\uB76C\uB76D\uCBEB"+ - "\uB76E\uB76F\uB770\uB771\uB772\uB773\uB774\uB775"+ - "\uB776\uB777\uB778\uB779\uB77A\uB77B\uB77C\uB77D"+ - "\uB77E\uB780\uB781\uB782\uB783\uB784\uB785\uB786"+ - "\uF0A6\uB787\uB788\uB789\uD1A8\uB78A\uBEBF\uC7EE"+ - "\uF1B6\uF1B7\uBFD5\uB78B\uB78C\uB78D\uB78E\uB4A9"+ - "\uF1B8\uCDBB\uB78F\uC7D4\uD5AD\uB790\uF1B9\uB791"+ - "\uF1BA\uB792\uB793\uB794\uB795\uC7CF\uB796\uB797"+ - "\uB798\uD2A4\uD6CF\uB799\uB79A\uF1BB\uBDD1\uB4B0"+ - "\uBEBD\uB79B\uB79C\uB79D\uB4DC\uCED1\uB79E\uBFDF"+ - "\uF1BD\uB79F\uB7A0\uB840\uB841\uBFFA\uF1BC\uB842"+ - "\uF1BF\uB843\uB844\uB845\uF1BE\uF1C0\uB846\uB847"+ - "\uB848\uB849\uB84A\uF1C1\uB84B\uB84C\uB84D\uB84E"+ - "\uB84F\uB850\uB851\uB852\uB853\uB854\uB855\uC1FE"+ - "\uB856\uB857\uB858\uB859\uB85A\uB85B\uB85C\uB85D"+ - "\uB85E\uB85F\uB860\uC1A2\uB861\uB862\uB863\uB864"+ - "\uB865\uB866\uB867\uB868\uB869\uB86A\uCAFA\uB86B"+ - "\uB86C\uD5BE\uB86D\uB86E\uB86F\uB870\uBEBA\uBEB9"+ - "\uD5C2\uB871\uB872\uBFA2\uB873\uCDAF\uF1B5\uB874"+ - "\uB875\uB876\uB877\uB878\uB879\uBDDF\uB87A\uB6CB"+ - "\uB87B\uB87C\uB87D\uB87E\uB880\uB881\uB882\uB883"+ - "\uB884\uD6F1\uF3C3\uB885\uB886\uF3C4\uB887\uB8CD"+ - "\uB888\uB889\uB88A\uF3C6\uF3C7\uB88B\uB0CA\uB88C"+ - "\uF3C5\uB88D\uF3C9\uCBF1\uB88E\uB88F\uB890\uF3CB"+ - "\uB891\uD0A6\uB892\uB893\uB1CA\uF3C8\uB894\uB895"+ - "\uB896\uF3CF\uB897\uB5D1\uB898\uB899\uF3D7\uB89A"+ - "\uF3D2\uB89B\uB89C\uB89D\uF3D4\uF3D3\uB7FB\uB89E"+ - "\uB1BF\uB89F\uF3CE\uF3CA\uB5DA\uB8A0\uF3D0\uB940"+ - "\uB941\uF3D1\uB942\uF3D5\uB943\uB944\uB945\uB946"+ - "\uF3CD\uB947\uBCE3\uB948\uC1FD\uB949\uF3D6\uB94A"+ - "\uB94B\uB94C\uB94D\uB94E\uB94F\uF3DA\uB950\uF3CC"+ - "\uB951\uB5C8\uB952\uBDEE\uF3DC\uB953\uB954\uB7A4"+ - "\uBFF0\uD6FE\uCDB2\uB955\uB4F0\uB956\uB2DF\uB957"+ - "\uF3D8\uB958\uF3D9\uC9B8\uB959\uF3DD\uB95A\uB95B"+ - "\uF3DE\uB95C\uF3E1\uB95D\uB95E\uB95F\uB960\uB961"+ - "\uB962\uB963\uB964\uB965\uB966\uB967\uF3DF\uB968"+ - "\uB969\uF3E3\uF3E2\uB96A\uB96B\uF3DB\uB96C\uBFEA"+ - "\uB96D\uB3EF\uB96E\uF3E0\uB96F\uB970\uC7A9\uB971"+ - "\uBCF2\uB972\uB973\uB974\uB975\uF3EB\uB976\uB977"+ - "\uB978\uB979\uB97A\uB97B\uB97C\uB9BF\uB97D\uB97E"+ - "\uF3E4\uB980\uB981\uB982\uB2AD\uBBFE\uB983\uCBE3"+ - "\uB984\uB985\uB986\uB987\uF3ED\uF3E9\uB988\uB989"+ - "\uB98A\uB9DC\uF3EE\uB98B\uB98C\uB98D\uF3E5\uF3E6"+ - "\uF3EA\uC2E1\uF3EC\uF3EF\uF3E8\uBCFD\uB98E\uB98F"+ - "\uB990\uCFE4\uB991\uB992\uF3F0\uB993\uB994\uB995"+ - "\uF3E7\uB996\uB997\uB998\uB999\uB99A\uB99B\uB99C"+ - "\uB99D\uF3F2\uB99E\uB99F\uB9A0\uBA40\uD7AD\uC6AA"+ - "\uBA41\uBA42\uBA43\uBA44\uF3F3\uBA45\uBA46\uBA47"+ - "\uBA48\uF3F1\uBA49\uC2A8\uBA4A\uBA4B\uBA4C\uBA4D"+ - "\uBA4E\uB8DD\uF3F5\uBA4F\uBA50\uF3F4\uBA51\uBA52"+ - "\uBA53\uB4DB\uBA54\uBA55\uBA56\uF3F6\uF3F7\uBA57"+ - "\uBA58\uBA59\uF3F8\uBA5A\uBA5B\uBA5C\uC0BA\uBA5D"+ - "\uBA5E\uC0E9\uBA5F\uBA60\uBA61\uBA62\uBA63\uC5F1"+ - "\uBA64\uBA65\uBA66\uBA67\uF3FB\uBA68\uF3FA\uBA69"+ - "\uBA6A\uBA6B\uBA6C\uBA6D\uBA6E\uBA6F\uBA70\uB4D8"+ - "\uBA71\uBA72\uBA73\uF3FE\uF3F9\uBA74\uBA75\uF3FC"+ - "\uBA76\uBA77\uBA78\uBA79\uBA7A\uBA7B\uF3FD\uBA7C"+ - "\uBA7D\uBA7E\uBA80\uBA81\uBA82\uBA83\uBA84\uF4A1"+ - "\uBA85\uBA86\uBA87\uBA88\uBA89\uBA8A\uF4A3\uBBC9"+ - "\uBA8B\uBA8C\uF4A2\uBA8D\uBA8E\uBA8F\uBA90\uBA91"+ - "\uBA92\uBA93\uBA94\uBA95\uBA96\uBA97\uBA98\uBA99"+ - "\uF4A4\uBA9A\uBA9B\uBA9C\uBA9D\uBA9E\uBA9F\uB2BE"+ - "\uF4A6\uF4A5\uBAA0\uBB40\uBB41\uBB42\uBB43\uBB44"+ - "\uBB45\uBB46\uBB47\uBB48\uBB49\uBCAE\uBB4A\uBB4B"+ - "\uBB4C\uBB4D\uBB4E\uBB4F\uBB50\uBB51\uBB52\uBB53"+ - "\uBB54\uBB55\uBB56\uBB57\uBB58\uBB59\uBB5A\uBB5B"+ - "\uBB5C\uBB5D\uBB5E\uBB5F\uBB60\uBB61\uBB62\uBB63"+ - "\uBB64\uBB65\uBB66\uBB67\uBB68\uBB69\uBB6A\uBB6B"+ - "\uBB6C\uBB6D\uBB6E\uC3D7\uD9E1\uBB6F\uBB70\uBB71"+ - "\uBB72\uBB73\uBB74\uC0E0\uF4CC\uD7D1\uBB75\uBB76"+ - "\uBB77\uBB78\uBB79\uBB7A\uBB7B\uBB7C\uBB7D\uBB7E"+ - "\uBB80\uB7DB\uBB81\uBB82\uBB83\uBB84\uBB85\uBB86"+ - "\uBB87\uF4CE\uC1A3\uBB88\uBB89\uC6C9\uBB8A\uB4D6"+ - "\uD5B3\uBB8B\uBB8C\uBB8D\uF4D0\uF4CF\uF4D1\uCBDA"+ - "\uBB8E\uBB8F\uF4D2\uBB90\uD4C1\uD6E0\uBB91\uBB92"+ - "\uBB93\uBB94\uB7E0\uBB95\uBB96\uBB97\uC1B8\uBB98"+ - "\uBB99\uC1BB\uF4D3\uBEAC\uBB9A\uBB9B\uBB9C\uBB9D"+ - "\uBB9E\uB4E2\uBB9F\uBBA0\uF4D4\uF4D5\uBEAB\uBC40"+ - "\uBC41\uF4D6\uBC42\uBC43\uBC44\uF4DB\uBC45\uF4D7"+ - "\uF4DA\uBC46\uBAFD\uBC47\uF4D8\uF4D9\uBC48\uBC49"+ - "\uBC4A\uBC4B\uBC4C\uBC4D\uBC4E\uB8E2\uCCC7\uF4DC"+ - "\uBC4F\uB2DA\uBC50\uBC51\uC3D3\uBC52\uBC53\uD4E3"+ - "\uBFB7\uBC54\uBC55\uBC56\uBC57\uBC58\uBC59\uBC5A"+ - "\uF4DD\uBC5B\uBC5C\uBC5D\uBC5E\uBC5F\uBC60\uC5B4"+ - "\uBC61\uBC62\uBC63\uBC64\uBC65\uBC66\uBC67\uBC68"+ - "\uF4E9\uBC69\uBC6A\uCFB5\uBC6B\uBC6C\uBC6D\uBC6E"+ - "\uBC6F\uBC70\uBC71\uBC72\uBC73\uBC74\uBC75\uBC76"+ - "\uBC77\uBC78\uCEC9\uBC79\uBC7A\uBC7B\uBC7C\uBC7D"+ - "\uBC7E\uBC80\uBC81\uBC82\uBC83\uBC84\uBC85\uBC86"+ - "\uBC87\uBC88\uBC89\uBC8A\uBC8B\uBC8C\uBC8D\uBC8E"+ - "\uCBD8\uBC8F\uCBF7\uBC90\uBC91\uBC92\uBC93\uBDF4"+ - "\uBC94\uBC95\uBC96\uD7CF\uBC97\uBC98\uBC99\uC0DB"+ - "\uBC9A\uBC9B\uBC9C\uBC9D\uBC9E\uBC9F\uBCA0\uBD40"+ - "\uBD41\uBD42\uBD43\uBD44\uBD45\uBD46\uBD47\uBD48"+ - "\uBD49\uBD4A\uBD4B\uBD4C\uBD4D\uBD4E\uBD4F\uBD50"+ - "\uBD51\uBD52\uBD53\uBD54\uBD55\uBD56\uBD57\uBD58"+ - "\uBD59\uBD5A\uBD5B\uBD5C\uBD5D\uBD5E\uBD5F\uBD60"+ - "\uBD61\uBD62\uBD63\uBD64\uBD65\uBD66\uBD67\uBD68"+ - "\uBD69\uBD6A\uBD6B\uBD6C\uBD6D\uBD6E\uBD6F\uBD70"+ - "\uBD71\uBD72\uBD73\uBD74\uBD75\uBD76\uD0F5\uBD77"+ - "\uBD78\uBD79\uBD7A\uBD7B\uBD7C\uBD7D\uBD7E\uF4EA"+ - "\uBD80\uBD81\uBD82\uBD83\uBD84\uBD85\uBD86\uBD87"+ - "\uBD88\uBD89\uBD8A\uBD8B\uBD8C\uBD8D\uBD8E\uBD8F"+ - "\uBD90\uBD91\uBD92\uBD93\uBD94\uBD95\uBD96\uBD97"+ - "\uBD98\uBD99\uBD9A\uBD9B\uBD9C\uBD9D\uBD9E\uBD9F"+ - "\uBDA0\uBE40\uBE41\uBE42\uBE43\uBE44\uBE45\uBE46"+ - "\uBE47\uBE48\uBE49\uBE4A\uBE4B\uBE4C\uF4EB\uBE4D"+ - "\uBE4E\uBE4F\uBE50\uBE51\uBE52\uBE53\uF4EC\uBE54"+ - "\uBE55\uBE56\uBE57\uBE58\uBE59\uBE5A\uBE5B\uBE5C"+ - "\uBE5D\uBE5E\uBE5F\uBE60\uBE61\uBE62\uBE63\uBE64"+ - "\uBE65\uBE66\uBE67\uBE68\uBE69\uBE6A\uBE6B\uBE6C"+ - "\uBE6D\uBE6E\uBE6F\uBE70\uBE71\uBE72\uBE73\uBE74"+ - "\uBE75\uBE76\uBE77\uBE78\uBE79\uBE7A\uBE7B\uBE7C"+ - "\uBE7D\uBE7E\uBE80\uBE81\uBE82\uBE83\uBE84\uBE85"+ - "\uBE86\uBE87\uBE88\uBE89\uBE8A\uBE8B\uBE8C\uBE8D"+ - "\uBE8E\uBE8F\uBE90\uBE91\uBE92\uBE93\uBE94\uBE95"+ - "\uBE96\uBE97\uBE98\uBE99\uBE9A\uBE9B\uBE9C\uBE9D"+ - "\uBE9E\uBE9F\uBEA0\uBF40\uBF41\uBF42\uBF43\uBF44"+ - "\uBF45\uBF46\uBF47\uBF48\uBF49\uBF4A\uBF4B\uBF4C"+ - "\uBF4D\uBF4E\uBF4F\uBF50\uBF51\uBF52\uBF53\uBF54"+ - "\uBF55\uBF56\uBF57\uBF58\uBF59\uBF5A\uBF5B\uBF5C"+ - "\uBF5D\uBF5E\uBF5F\uBF60\uBF61\uBF62\uBF63\uBF64"+ - "\uBF65\uBF66\uBF67\uBF68\uBF69\uBF6A\uBF6B\uBF6C"+ - "\uBF6D\uBF6E\uBF6F\uBF70\uBF71\uBF72\uBF73\uBF74"+ - "\uBF75\uBF76\uBF77\uBF78\uBF79\uBF7A\uBF7B\uBF7C"+ - "\uBF7D\uBF7E\uBF80\uF7E3\uBF81\uBF82\uBF83\uBF84"+ - "\uBF85\uB7B1\uBF86\uBF87\uBF88\uBF89\uBF8A\uF4ED"+ - "\uBF8B\uBF8C\uBF8D\uBF8E\uBF8F\uBF90\uBF91\uBF92"+ - "\uBF93\uBF94\uBF95\uBF96\uBF97\uBF98\uBF99\uBF9A"+ - "\uBF9B\uBF9C\uBF9D\uBF9E\uBF9F\uBFA0\uC040\uC041"+ - "\uC042\uC043\uC044\uC045\uC046\uC047\uC048\uC049"+ - "\uC04A\uC04B\uC04C\uC04D\uC04E\uC04F\uC050\uC051"+ - "\uC052\uC053\uC054\uC055\uC056\uC057\uC058\uC059"+ - "\uC05A\uC05B\uC05C\uC05D\uC05E\uC05F\uC060\uC061"+ - "\uC062\uC063\uD7EB\uC064\uC065\uC066\uC067\uC068"+ - "\uC069\uC06A\uC06B\uC06C\uC06D\uC06E\uC06F\uC070"+ - "\uC071\uC072\uC073\uC074\uC075\uC076\uC077\uC078"+ - "\uC079\uC07A\uC07B\uF4EE\uC07C\uC07D\uC07E\uE6F9"+ - "\uBEC0\uE6FA\uBAEC\uE6FB\uCFCB\uE6FC\uD4BC\uBCB6"+ - "\uE6FD\uE6FE\uBCCD\uC8D2\uCEB3\uE7A1\uC080\uB4BF"+ - "\uE7A2\uC9B4\uB8D9\uC4C9\uC081\uD7DD\uC2DA\uB7D7"+ - "\uD6BD\uCEC6\uB7C4\uC082\uC083\uC5A6\uE7A3\uCFDF"+ - "\uE7A4\uE7A5\uE7A6\uC1B7\uD7E9\uC9F0\uCFB8\uD6AF"+ - "\uD6D5\uE7A7\uB0ED\uE7A8\uE7A9\uC9DC\uD2EF\uBEAD"+ - "\uE7AA\uB0F3\uC8DE\uBDE1\uE7AB\uC8C6\uC084\uE7AC"+ - "\uBBE6\uB8F8\uD1A4\uE7AD\uC2E7\uBEF8\uBDCA\uCDB3"+ - "\uE7AE\uE7AF\uBEEE\uD0E5\uC085\uCBE7\uCCD0\uBCCC"+ - "\uE7B0\uBCA8\uD0F7\uE7B1\uC086\uD0F8\uE7B2\uE7B3"+ - "\uB4C2\uE7B4\uE7B5\uC9FE\uCEAC\uC3E0\uE7B7\uB1C1"+ - "\uB3F1\uC087\uE7B8\uE7B9\uD7DB\uD5C0\uE7BA\uC2CC"+ - "\uD7BA\uE7BB\uE7BC\uE7BD\uBCEA\uC3E5\uC0C2\uE7BE"+ - "\uE7BF\uBCA9\uC088\uE7C0\uE7C1\uE7B6\uB6D0\uE7C2"+ - "\uC089\uE7C3\uE7C4\uBBBA\uB5DE\uC2C6\uB1E0\uE7C5"+ - "\uD4B5\uE7C6\uB8BF\uE7C8\uE7C7\uB7EC\uC08A\uE7C9"+ - "\uB2F8\uE7CA\uE7CB\uE7CC\uE7CD\uE7CE\uE7CF\uE7D0"+ - "\uD3A7\uCBF5\uE7D1\uE7D2\uE7D3\uE7D4\uC9C9\uE7D5"+ - "\uE7D6\uE7D7\uE7D8\uE7D9\uBDC9\uE7DA\uF3BE\uC08B"+ - "\uB8D7\uC08C\uC8B1\uC08D\uC08E\uC08F\uC090\uC091"+ - "\uC092\uC093\uF3BF\uC094\uF3C0\uF3C1\uC095\uC096"+ - "\uC097\uC098\uC099\uC09A\uC09B\uC09C\uC09D\uC09E"+ - "\uB9DE\uCDF8\uC09F\uC0A0\uD8E8\uBAB1\uC140\uC2DE"+ - "\uEEB7\uC141\uB7A3\uC142\uC143\uC144\uC145\uEEB9"+ - "\uC146\uEEB8\uB0D5\uC147\uC148\uC149\uC14A\uC14B"+ - "\uEEBB\uD5D6\uD7EF\uC14C\uC14D\uC14E\uD6C3\uC14F"+ - "\uC150\uEEBD\uCAF0\uC151\uEEBC\uC152\uC153\uC154"+ - "\uC155\uEEBE\uC156\uC157\uC158\uC159\uEEC0\uC15A"+ - "\uC15B\uEEBF\uC15C\uC15D\uC15E\uC15F\uC160\uC161"+ - "\uC162\uC163\uD1F2\uC164\uC7BC\uC165\uC3C0\uC166"+ - "\uC167\uC168\uC169\uC16A\uB8E1\uC16B\uC16C\uC16D"+ - "\uC16E\uC16F\uC1E7\uC170\uC171\uF4C6\uD0DF\uF4C7"+ - "\uC172\uCFDB\uC173\uC174\uC8BA\uC175\uC176\uF4C8"+ - "\uC177\uC178\uC179\uC17A\uC17B\uC17C\uC17D\uF4C9"+ - "\uF4CA\uC17E\uF4CB\uC180\uC181\uC182\uC183\uC184"+ - "\uD9FA\uB8FE\uC185\uC186\uE5F1\uD3F0\uC187\uF4E0"+ - "\uC188\uCECC\uC189\uC18A\uC18B\uB3E1\uC18C\uC18D"+ - "\uC18E\uC18F\uF1B4\uC190\uD2EE\uC191\uF4E1\uC192"+ - "\uC193\uC194\uC195\uC196\uCFE8\uF4E2\uC197\uC198"+ - "\uC7CC\uC199\uC19A\uC19B\uC19C\uC19D\uC19E\uB5D4"+ - "\uB4E4\uF4E4\uC19F\uC1A0\uC240\uF4E3\uF4E5\uC241"+ - "\uC242\uF4E6\uC243\uC244\uC245\uC246\uF4E7\uC247"+ - "\uBAB2\uB0BF\uC248\uF4E8\uC249\uC24A\uC24B\uC24C"+ - "\uC24D\uC24E\uC24F\uB7AD\uD2ED\uC250\uC251\uC252"; - - private static final String innerEncoderIndex8= - "\uD2AB\uC0CF\uC253\uBFBC\uEBA3\uD5DF\uEAC8\uC254"+ - "\uC255\uC256\uC257\uF1F3\uB6F8\uCBA3\uC258\uC259"+ - "\uC4CD\uC25A\uF1E7\uC25B\uF1E8\uB8FB\uF1E9\uBAC4"+ - "\uD4C5\uB0D2\uC25C\uC25D\uF1EA\uC25E\uC25F\uC260"+ - "\uF1EB\uC261\uF1EC\uC262\uC263\uF1ED\uF1EE\uF1EF"+ - "\uF1F1\uF1F0\uC5D5\uC264\uC265\uC266\uC267\uC268"+ - "\uC269\uF1F2\uC26A\uB6FA\uC26B\uF1F4\uD2AE\uDEC7"+ - "\uCBCA\uC26C\uC26D\uB3DC\uC26E\uB5A2\uC26F\uB9A2"+ - "\uC270\uC271\uC4F4\uF1F5\uC272\uC273\uF1F6\uC274"+ - "\uC275\uC276\uC1C4\uC1FB\uD6B0\uF1F7\uC277\uC278"+ - "\uC279\uC27A\uF1F8\uC27B\uC1AA\uC27C\uC27D\uC27E"+ - "\uC6B8\uC280\uBEDB\uC281\uC282\uC283\uC284\uC285"+ - "\uC286\uC287\uC288\uC289\uC28A\uC28B\uC28C\uC28D"+ - "\uC28E\uF1F9\uB4CF\uC28F\uC290\uC291\uC292\uC293"+ - "\uC294\uF1FA\uC295\uC296\uC297\uC298\uC299\uC29A"+ - "\uC29B\uC29C\uC29D\uC29E\uC29F\uC2A0\uC340\uEDB2"+ - "\uEDB1\uC341\uC342\uCBE0\uD2DE\uC343\uCBC1\uD5D8"+ - "\uC344\uC8E2\uC345\uC0DF\uBCA1\uC346\uC347\uC348"+ - "\uC349\uC34A\uC34B\uEBC1\uC34C\uC34D\uD0A4\uC34E"+ - "\uD6E2\uC34F\uB6C7\uB8D8\uEBC0\uB8CE\uC350\uEBBF"+ - "\uB3A6\uB9C9\uD6AB\uC351\uB7F4\uB7CA\uC352\uC353"+ - "\uC354\uBCE7\uB7BE\uEBC6\uC355\uEBC7\uB0B9\uBFCF"+ - "\uC356\uEBC5\uD3FD\uC357\uEBC8\uC358\uC359\uEBC9"+ - "\uC35A\uC35B\uB7CE\uC35C\uEBC2\uEBC4\uC9F6\uD6D7"+ - "\uD5CD\uD0B2\uEBCF\uCEB8\uEBD0\uC35D\uB5A8\uC35E"+ - "\uC35F\uC360\uC361\uC362\uB1B3\uEBD2\uCCA5\uC363"+ - "\uC364\uC365\uC366\uC367\uC368\uC369\uC5D6\uEBD3"+ - "\uC36A\uEBD1\uC5DF\uEBCE\uCAA4\uEBD5\uB0FB\uC36B"+ - "\uC36C\uBAFA\uC36D\uC36E\uD8B7\uF1E3\uC36F\uEBCA"+ - "\uEBCB\uEBCC\uEBCD\uEBD6\uE6C0\uEBD9\uC370\uBFE8"+ - "\uD2C8\uEBD7\uEBDC\uB8EC\uEBD8\uC371\uBDBA\uC372"+ - "\uD0D8\uC373\uB0B7\uC374\uEBDD\uC4DC\uC375\uC376"+ - "\uC377\uC378\uD6AC\uC379\uC37A\uC37B\uB4E0\uC37C"+ - "\uC37D\uC2F6\uBCB9\uC37E\uC380\uEBDA\uEBDB\uD4E0"+ - "\uC6EA\uC4D4\uEBDF\uC5A7\uD9F5\uC381\uB2B1\uC382"+ - "\uEBE4\uC383\uBDC5\uC384\uC385\uC386\uEBE2\uC387"+ - "\uC388\uC389\uC38A\uC38B\uC38C\uC38D\uC38E\uC38F"+ - "\uC390\uC391\uC392\uC393\uEBE3\uC394\uC395\uB8AC"+ - "\uC396\uCDD1\uEBE5\uC397\uC398\uC399\uEBE1\uC39A"+ - "\uC1B3\uC39B\uC39C\uC39D\uC39E\uC39F\uC6A2\uC3A0"+ - "\uC440\uC441\uC442\uC443\uC444\uC445\uCCF3\uC446"+ - "\uEBE6\uC447\uC0B0\uD2B8\uEBE7\uC448\uC449\uC44A"+ - "\uB8AF\uB8AD\uC44B\uEBE8\uC7BB\uCDF3\uC44C\uC44D"+ - "\uC44E\uEBEA\uEBEB\uC44F\uC450\uC451\uC452\uC453"+ - "\uEBED\uC454\uC455\uC456\uC457\uD0C8\uC458\uEBF2"+ - "\uC459\uEBEE\uC45A\uC45B\uC45C\uEBF1\uC8F9\uC45D"+ - "\uD1FC\uEBEC\uC45E\uC45F\uEBE9\uC460\uC461\uC462"+ - "\uC463\uB8B9\uCFD9\uC4E5\uEBEF\uEBF0\uCCDA\uCDC8"+ - "\uB0F2\uC464\uEBF6\uC465\uC466\uC467\uC468\uC469"+ - "\uEBF5\uC46A\uB2B2\uC46B\uC46C\uC46D\uC46E\uB8E0"+ - "\uC46F\uEBF7\uC470\uC471\uC472\uC473\uC474\uC475"+ - "\uB1EC\uC476\uC477\uCCC5\uC4A4\uCFA5\uC478\uC479"+ - "\uC47A\uC47B\uC47C\uEBF9\uC47D\uC47E\uECA2\uC480"+ - "\uC5F2\uC481\uEBFA\uC482\uC483\uC484\uC485\uC486"+ - "\uC487\uC488\uC489\uC9C5\uC48A\uC48B\uC48C\uC48D"+ - "\uC48E\uC48F\uE2DF\uEBFE\uC490\uC491\uC492\uC493"+ - "\uCDCE\uECA1\uB1DB\uD3B7\uC494\uC495\uD2DC\uC496"+ - "\uC497\uC498\uEBFD\uC499\uEBFB\uC49A\uC49B\uC49C"+ - "\uC49D\uC49E\uC49F\uC4A0\uC540\uC541\uC542\uC543"+ - "\uC544\uC545\uC546\uC547\uC548\uC549\uC54A\uC54B"+ - "\uC54C\uC54D\uC54E\uB3BC\uC54F\uC550\uC551\uEAB0"+ - "\uC552\uC553\uD7D4\uC554\uF4AB\uB3F4\uC555\uC556"+ - "\uC557\uC558\uC559\uD6C1\uD6C2\uC55A\uC55B\uC55C"+ - "\uC55D\uC55E\uC55F\uD5E9\uBECA\uC560\uF4A7\uC561"+ - "\uD2A8\uF4A8\uF4A9\uC562\uF4AA\uBECB\uD3DF\uC563"+ - "\uC564\uC565\uC566\uC567\uC9E0\uC9E1\uC568\uC569"+ - "\uF3C2\uC56A\uCAE6\uC56B\uCCF2\uC56C\uC56D\uC56E"+ - "\uC56F\uC570\uC571\uE2B6\uCBB4\uC572\uCEE8\uD6DB"+ - "\uC573\uF4AD\uF4AE\uF4AF\uC574\uC575\uC576\uC577"+ - "\uF4B2\uC578\uBABD\uF4B3\uB0E3\uF4B0\uC579\uF4B1"+ - "\uBDA2\uB2D5\uC57A\uF4B6\uF4B7\uB6E6\uB2B0\uCFCF"+ - "\uF4B4\uB4AC\uC57B\uF4B5\uC57C\uC57D\uF4B8\uC57E"+ - "\uC580\uC581\uC582\uC583\uF4B9\uC584\uC585\uCDA7"+ - "\uC586\uF4BA\uC587\uF4BB\uC588\uC589\uC58A\uF4BC"+ - "\uC58B\uC58C\uC58D\uC58E\uC58F\uC590\uC591\uC592"+ - "\uCBD2\uC593\uF4BD\uC594\uC595\uC596\uC597\uF4BE"+ - "\uC598\uC599\uC59A\uC59B\uC59C\uC59D\uC59E\uC59F"+ - "\uF4BF\uC5A0\uC640\uC641\uC642\uC643\uF4DE\uC1BC"+ - "\uBCE8\uC644\uC9AB\uD1DE\uE5F5\uC645\uC646\uC647"+ - "\uC648\uDCB3\uD2D5\uC649\uC64A\uDCB4\uB0AC\uDCB5"+ - "\uC64B\uC64C\uBDDA\uC64D\uDCB9\uC64E\uC64F\uC650"+ - "\uD8C2\uC651\uDCB7\uD3F3\uC652\uC9D6\uDCBA\uDCB6"+ - "\uC653\uDCBB\uC3A2\uC654\uC655\uC656\uC657\uDCBC"+ - "\uDCC5\uDCBD\uC658\uC659\uCEDF\uD6A5\uC65A\uDCCF"+ - "\uC65B\uDCCD\uC65C\uC65D\uDCD2\uBDE6\uC2AB\uC65E"+ - "\uDCB8\uDCCB\uDCCE\uDCBE\uB7D2\uB0C5\uDCC7\uD0BE"+ - "\uDCC1\uBBA8\uC65F\uB7BC\uDCCC\uC660\uC661\uDCC6"+ - "\uDCBF\uC7DB\uC662\uC663\uC664\uD1BF\uDCC0\uC665"+ - "\uC666\uDCCA\uC667\uC668\uDCD0\uC669\uC66A\uCEAD"+ - "\uDCC2\uC66B\uDCC3\uDCC8\uDCC9\uB2D4\uDCD1\uCBD5"+ - "\uC66C\uD4B7\uDCDB\uDCDF\uCCA6\uDCE6\uC66D\uC3E7"+ - "\uDCDC\uC66E\uC66F\uBFC1\uDCD9\uC670\uB0FA\uB9B6"+ - "\uDCE5\uDCD3\uC671\uDCC4\uDCD6\uC8F4\uBFE0\uC672"+ - "\uC673\uC674\uC675\uC9BB\uC676\uC677\uC678\uB1BD"+ - "\uC679\uD3A2\uC67A\uC67B\uDCDA\uC67C\uC67D\uDCD5"+ - "\uC67E\uC6BB\uC680\uDCDE\uC681\uC682\uC683\uC684"+ - "\uC685\uD7C2\uC3AF\uB7B6\uC7D1\uC3A9\uDCE2\uDCD8"+ - "\uDCEB\uDCD4\uC686\uC687\uDCDD\uC688\uBEA5\uDCD7"+ - "\uC689\uDCE0\uC68A\uC68B\uDCE3\uDCE4\uC68C\uDCF8"+ - "\uC68D\uC68E\uDCE1\uDDA2\uDCE7\uC68F\uC690\uC691"+ - "\uC692\uC693\uC694\uC695\uC696\uC697\uC698\uBCEB"+ - "\uB4C4\uC699\uC69A\uC3A3\uB2E7\uDCFA\uC69B\uDCF2"+ - "\uC69C\uDCEF\uC69D\uDCFC\uDCEE\uD2F0\uB2E8\uC69E"+ - "\uC8D7\uC8E3\uDCFB\uC69F\uDCED\uC6A0\uC740\uC741"+ - "\uDCF7\uC742\uC743\uDCF5\uC744\uC745\uBEA3\uDCF4"+ - "\uC746\uB2DD\uC747\uC748\uC749\uC74A\uC74B\uDCF3"+ - "\uBCF6\uDCE8\uBBC4\uC74C\uC0F3\uC74D\uC74E\uC74F"+ - "\uC750\uC751\uBCD4\uDCE9\uDCEA\uC752\uDCF1\uDCF6"+ - "\uDCF9\uB5B4\uC753\uC8D9\uBBE7\uDCFE\uDCFD\uD3AB"+ - "\uDDA1\uDDA3\uDDA5\uD2F1\uDDA4\uDDA6\uDDA7\uD2A9"+ - "\uC754\uC755\uC756\uC757\uC758\uC759\uC75A\uBAC9"+ - "\uDDA9\uC75B\uC75C\uDDB6\uDDB1\uDDB4\uC75D\uC75E"+ - "\uC75F\uC760\uC761\uC762\uC763\uDDB0\uC6CE\uC764"+ - "\uC765\uC0F2\uC766\uC767\uC768\uC769\uC9AF\uC76A"+ - "\uC76B\uC76C\uDCEC\uDDAE\uC76D\uC76E\uC76F\uC770"+ - "\uDDB7\uC771\uC772\uDCF0\uDDAF\uC773\uDDB8\uC774"+ - "\uDDAC\uC775\uC776\uC777\uC778\uC779\uC77A\uC77B"+ - "\uDDB9\uDDB3\uDDAD\uC4AA\uC77C\uC77D\uC77E\uC780"+ - "\uDDA8\uC0B3\uC1AB\uDDAA\uDDAB\uC781\uDDB2\uBBF1"+ - "\uDDB5\uD3A8\uDDBA\uC782\uDDBB\uC3A7\uC783\uC784"+ - "\uDDD2\uDDBC\uC785\uC786\uC787\uDDD1\uC788\uB9BD"+ - "\uC789\uC78A\uBED5\uC78B\uBEFA\uC78C\uC78D\uBACA"+ - "\uC78E\uC78F\uC790\uC791\uDDCA\uC792\uDDC5\uC793"+ - "\uDDBF\uC794\uC795\uC796\uB2CB\uDDC3\uC797\uDDCB"+ - "\uB2A4\uDDD5\uC798\uC799\uC79A\uDDBE\uC79B\uC79C"+ - "\uC79D\uC6D0\uDDD0\uC79E\uC79F\uC7A0\uC840\uC841"+ - "\uDDD4\uC1E2\uB7C6\uC842\uC843\uC844\uC845\uC846"+ - "\uDDCE\uDDCF\uC847\uC848\uC849\uDDC4\uC84A\uC84B"+ - "\uC84C\uDDBD\uC84D\uDDCD\uCCD1\uC84E\uDDC9\uC84F"+ - "\uC850\uC851\uC852\uDDC2\uC3C8\uC6BC\uCEAE\uDDCC"+ - "\uC853\uDDC8\uC854\uC855\uC856\uC857\uC858\uC859"+ - "\uDDC1\uC85A\uC85B\uC85C\uDDC6\uC2DC\uC85D\uC85E"+ - "\uC85F\uC860\uC861\uC862\uD3A9\uD3AA\uDDD3\uCFF4"+ - "\uC8F8\uC863\uC864\uC865\uC866\uC867\uC868\uC869"+ - "\uC86A\uDDE6\uC86B\uC86C\uC86D\uC86E\uC86F\uC870"+ - "\uDDC7\uC871\uC872\uC873\uDDE0\uC2E4\uC874\uC875"+ - "\uC876\uC877\uC878\uC879\uC87A\uC87B\uDDE1\uC87C"+ - "\uC87D\uC87E\uC880\uC881\uC882\uC883\uC884\uC885"+ - "\uC886\uDDD7\uC887\uC888\uC889\uC88A\uC88B\uD6F8"+ - "\uC88C\uDDD9\uDDD8\uB8F0\uDDD6\uC88D\uC88E\uC88F"+ - "\uC890\uC6CF\uC891\uB6AD\uC892\uC893\uC894\uC895"+ - "\uC896\uDDE2\uC897\uBAF9\uD4E1\uDDE7\uC898\uC899"+ - "\uC89A\uB4D0\uC89B\uDDDA\uC89C\uBFFB\uDDE3\uC89D"+ - "\uDDDF\uC89E\uDDDD\uC89F\uC8A0\uC940\uC941\uC942"+ - "\uC943\uC944\uB5D9\uC945\uC946\uC947\uC948\uDDDB"+ - "\uDDDC\uDDDE\uC949\uBDAF\uDDE4\uC94A\uDDE5\uC94B"+ - "\uC94C\uC94D\uC94E\uC94F\uC950\uC951\uC952\uDDF5"+ - "\uC953\uC3C9\uC954\uC955\uCBE2\uC956\uC957\uC958"+ - "\uC959\uDDF2\uC95A\uC95B\uC95C\uC95D\uC95E\uC95F"+ - "\uC960\uC961\uC962\uC963\uC964\uC965\uC966\uD8E1"+ - "\uC967\uC968\uC6D1\uC969\uDDF4\uC96A\uC96B\uC96C"+ - "\uD5F4\uDDF3\uDDF0\uC96D\uC96E\uDDEC\uC96F\uDDEF"+ - "\uC970\uDDE8\uC971\uC972\uD0EE\uC973\uC974\uC975"+ - "\uC976\uC8D8\uDDEE\uC977\uC978\uDDE9\uC979\uC97A"+ - "\uDDEA\uCBF2\uC97B\uDDED\uC97C\uC97D\uB1CD\uC97E"+ - "\uC980\uC981\uC982\uC983\uC984\uC0B6\uC985\uBCBB"+ - "\uDDF1\uC986\uC987\uDDF7\uC988\uDDF6\uDDEB\uC989"+ - "\uC98A\uC98B\uC98C\uC98D\uC5EE\uC98E\uC98F\uC990"+ - "\uDDFB\uC991\uC992\uC993\uC994\uC995\uC996\uC997"+ - "\uC998\uC999\uC99A\uC99B\uDEA4\uC99C\uC99D\uDEA3"+ - "\uC99E\uC99F\uC9A0\uCA40\uCA41\uCA42\uCA43\uCA44"+ - "\uCA45\uCA46\uCA47\uCA48\uDDF8\uCA49\uCA4A\uCA4B"+ - "\uCA4C\uC3EF\uCA4D\uC2FB\uCA4E\uCA4F\uCA50\uD5E1"+ - "\uCA51\uCA52\uCEB5\uCA53\uCA54\uCA55\uCA56\uDDFD"+ - "\uCA57\uB2CC\uCA58\uCA59\uCA5A\uCA5B\uCA5C\uCA5D"+ - "\uCA5E\uCA5F\uCA60\uC4E8\uCADF\uCA61\uCA62\uCA63"+ - "\uCA64\uCA65\uCA66\uCA67\uCA68\uCA69\uCA6A\uC7BE"+ - "\uDDFA\uDDFC\uDDFE\uDEA2\uB0AA\uB1CE\uCA6B\uCA6C"+ - "\uCA6D\uCA6E\uCA6F\uDEAC\uCA70\uCA71\uCA72\uCA73"+ - "\uDEA6\uBDB6\uC8EF\uCA74\uCA75\uCA76\uCA77\uCA78"+ - "\uCA79\uCA7A\uCA7B\uCA7C\uCA7D\uCA7E\uDEA1\uCA80"+ - "\uCA81\uDEA5\uCA82\uCA83\uCA84\uCA85\uDEA9\uCA86"+ - "\uCA87\uCA88\uCA89\uCA8A\uDEA8\uCA8B\uCA8C\uCA8D"+ - "\uDEA7\uCA8E\uCA8F\uCA90\uCA91\uCA92\uCA93\uCA94"+ - "\uCA95\uCA96\uDEAD\uCA97\uD4CC\uCA98\uCA99\uCA9A"+ - "\uCA9B\uDEB3\uDEAA\uDEAE\uCA9C\uCA9D\uC0D9\uCA9E"+ - "\uCA9F\uCAA0\uCB40\uCB41\uB1A1\uDEB6\uCB42\uDEB1"+ - "\uCB43\uCB44\uCB45\uCB46\uCB47\uCB48\uCB49\uDEB2"+ - "\uCB4A\uCB4B\uCB4C\uCB4D\uCB4E\uCB4F\uCB50\uCB51"+ - "\uCB52\uCB53\uCB54\uD1A6\uDEB5\uCB55\uCB56\uCB57"+ - "\uCB58\uCB59\uCB5A\uCB5B\uDEAF\uCB5C\uCB5D\uCB5E"+ - "\uDEB0\uCB5F\uD0BD\uCB60\uCB61\uCB62\uDEB4\uCAED"+ - "\uDEB9\uCB63\uCB64\uCB65\uCB66\uCB67\uCB68\uDEB8"+ - "\uCB69\uDEB7\uCB6A\uCB6B\uCB6C\uCB6D\uCB6E\uCB6F"+ - "\uCB70\uDEBB\uCB71\uCB72\uCB73\uCB74\uCB75\uCB76"+ - "\uCB77\uBDE5\uCB78\uCB79\uCB7A\uCB7B\uCB7C\uB2D8"+ - "\uC3EA\uCB7D\uCB7E\uDEBA\uCB80\uC5BA\uCB81\uCB82"+ - "\uCB83\uCB84\uCB85\uCB86\uDEBC\uCB87\uCB88\uCB89"+ - "\uCB8A\uCB8B\uCB8C\uCB8D\uCCD9\uCB8E\uCB8F\uCB90"+ - "\uCB91\uB7AA\uCB92\uCB93\uCB94\uCB95\uCB96\uCB97"+ - "\uCB98\uCB99\uCB9A\uCB9B\uCB9C\uCB9D\uCB9E\uCB9F"+ - "\uCBA0\uCC40\uCC41\uD4E5\uCC42\uCC43\uCC44\uDEBD"+ - "\uCC45\uCC46\uCC47\uCC48\uCC49\uDEBF\uCC4A\uCC4B"+ - "\uCC4C\uCC4D\uCC4E\uCC4F\uCC50\uCC51\uCC52\uCC53"+ - "\uCC54\uC4A2\uCC55\uCC56\uCC57\uCC58\uDEC1\uCC59"+ - "\uCC5A\uCC5B\uCC5C\uCC5D\uCC5E\uCC5F\uCC60\uCC61"+ - "\uCC62\uCC63\uCC64\uCC65\uCC66\uCC67\uCC68\uDEBE"+ - "\uCC69\uDEC0\uCC6A\uCC6B\uCC6C\uCC6D\uCC6E\uCC6F"+ - "\uCC70\uCC71\uCC72\uCC73\uCC74\uCC75\uCC76\uCC77"+ - "\uD5BA\uCC78\uCC79\uCC7A\uDEC2\uCC7B\uCC7C\uCC7D"+ - "\uCC7E\uCC80\uCC81\uCC82\uCC83\uCC84\uCC85\uCC86"+ - "\uCC87\uCC88\uCC89\uCC8A\uCC8B\uF2AE\uBBA2\uC2B2"+ - "\uC5B0\uC2C7\uCC8C\uCC8D\uF2AF\uCC8E\uCC8F\uCC90"+ - "\uCC91\uCC92\uD0E9\uCC93\uCC94\uCC95\uD3DD\uCC96"+ - "\uCC97\uCC98\uEBBD\uCC99\uCC9A\uCC9B\uCC9C\uCC9D"+ - "\uCC9E\uCC9F\uCCA0\uB3E6\uF2B0\uCD40\uF2B1\uCD41"+ - "\uCD42\uCAAD\uCD43\uCD44\uCD45\uCD46\uCD47\uCD48"+ - "\uCD49\uBAE7\uF2B3\uF2B5\uF2B4\uCBE4\uCFBA\uF2B2"+ - "\uCAB4\uD2CF\uC2EC\uCD4A\uCD4B\uCD4C\uCD4D\uCD4E"+ - "\uCD4F\uCD50\uCEC3\uF2B8\uB0F6\uF2B7\uCD51\uCD52"+ - "\uCD53\uCD54\uCD55\uF2BE\uCD56\uB2CF\uCD57\uCD58"+ - "\uCD59\uCD5A\uCD5B\uCD5C\uD1C1\uF2BA\uCD5D\uCD5E"+ - "\uCD5F\uCD60\uCD61\uF2BC\uD4E9\uCD62\uCD63\uF2BB"+ - "\uF2B6\uF2BF\uF2BD\uCD64\uF2B9\uCD65\uCD66\uF2C7"+ - "\uF2C4\uF2C6\uCD67\uCD68\uF2CA\uF2C2\uF2C0\uCD69"+ - "\uCD6A\uCD6B\uF2C5\uCD6C\uCD6D\uCD6E\uCD6F\uCD70"+ - "\uD6FB\uCD71\uCD72\uCD73\uF2C1\uCD74\uC7F9\uC9DF"+ - "\uCD75\uF2C8\uB9C6\uB5B0\uCD76\uCD77\uF2C3\uF2C9"+ - "\uF2D0\uF2D6\uCD78\uCD79\uBBD7\uCD7A\uCD7B\uCD7C"+ - "\uF2D5\uCDDC\uCD7D\uD6EB\uCD7E\uCD80\uF2D2\uF2D4"+ - "\uCD81\uCD82\uCD83\uCD84\uB8F2\uCD85\uCD86\uCD87"+ - "\uCD88\uF2CB\uCD89\uCD8A\uCD8B\uF2CE\uC2F9\uCD8C"+ - "\uD5DD\uF2CC\uF2CD\uF2CF\uF2D3\uCD8D\uCD8E\uCD8F"+ - "\uF2D9\uD3BC\uCD90\uCD91\uCD92\uCD93\uB6EA\uCD94"+ - "\uCAF1\uCD95\uB7E4\uF2D7\uCD96\uCD97\uCD98\uF2D8"+ - "\uF2DA\uF2DD\uF2DB\uCD99\uCD9A\uF2DC\uCD9B\uCD9C"+ - "\uCD9D\uCD9E\uD1D1\uF2D1\uCD9F\uCDC9\uCDA0\uCECF"+ - "\uD6A9\uCE40\uF2E3\uCE41\uC3DB\uCE42\uF2E0\uCE43"+ - "\uCE44\uC0AF\uF2EC\uF2DE\uCE45\uF2E1\uCE46\uCE47"+ - "\uCE48\uF2E8\uCE49\uCE4A\uCE4B\uCE4C\uF2E2\uCE4D"+ - "\uCE4E\uF2E7\uCE4F\uCE50\uF2E6\uCE51\uCE52\uF2E9"+ - "\uCE53\uCE54\uCE55\uF2DF\uCE56\uCE57\uF2E4\uF2EA"+ - "\uCE58\uCE59\uCE5A\uCE5B\uCE5C\uCE5D\uCE5E\uD3AC"+ - "\uF2E5\uB2F5\uCE5F\uCE60\uF2F2\uCE61\uD0AB\uCE62"+ - "\uCE63\uCE64\uCE65\uF2F5\uCE66\uCE67\uCE68\uBBC8"+ - "\uCE69\uF2F9\uCE6A\uCE6B\uCE6C\uCE6D\uCE6E\uCE6F"+ - "\uF2F0\uCE70\uCE71\uF2F6\uF2F8\uF2FA\uCE72\uCE73"+ - "\uCE74\uCE75\uCE76\uCE77\uCE78\uCE79\uF2F3\uCE7A"+ - "\uF2F1\uCE7B\uCE7C\uCE7D\uBAFB\uCE7E\uB5FB\uCE80"+ - "\uCE81\uCE82\uCE83\uF2EF\uF2F7\uF2ED\uF2EE\uCE84"+ - "\uCE85\uCE86\uF2EB\uF3A6\uCE87\uF3A3\uCE88\uCE89"+ - "\uF3A2\uCE8A\uCE8B\uF2F4\uCE8C\uC8DA\uCE8D\uCE8E"+ - "\uCE8F\uCE90\uCE91\uF2FB\uCE92\uCE93\uCE94\uF3A5"+ - "\uCE95\uCE96\uCE97\uCE98\uCE99\uCE9A\uCE9B\uC3F8"+ - "\uCE9C\uCE9D\uCE9E\uCE9F\uCEA0\uCF40\uCF41\uCF42"+ - "\uF2FD\uCF43\uCF44\uF3A7\uF3A9\uF3A4\uCF45\uF2FC"+ - "\uCF46\uCF47\uCF48\uF3AB\uCF49\uF3AA\uCF4A\uCF4B"+ - "\uCF4C\uCF4D\uC2DD\uCF4E\uCF4F\uF3AE\uCF50\uCF51"+ - "\uF3B0\uCF52\uCF53\uCF54\uCF55\uCF56\uF3A1\uCF57"+ - "\uCF58\uCF59\uF3B1\uF3AC\uCF5A\uCF5B\uCF5C\uCF5D"+ - "\uCF5E\uF3AF\uF2FE\uF3AD\uCF5F\uCF60\uCF61\uCF62"+ - "\uCF63\uCF64\uCF65\uF3B2\uCF66\uCF67\uCF68\uCF69"+ - "\uF3B4\uCF6A\uCF6B\uCF6C\uCF6D\uF3A8\uCF6E\uCF6F"+ - "\uCF70\uCF71\uF3B3\uCF72\uCF73\uCF74\uF3B5\uCF75"+ - "\uCF76\uCF77\uCF78\uCF79\uCF7A\uCF7B\uCF7C\uCF7D"+ - "\uCF7E\uD0B7\uCF80\uCF81\uCF82\uCF83\uF3B8\uCF84"+ - "\uCF85\uCF86\uCF87\uD9F9\uCF88\uCF89\uCF8A\uCF8B"+ - "\uCF8C\uCF8D\uF3B9\uCF8E\uCF8F\uCF90\uCF91\uCF92"+ - "\uCF93\uCF94\uCF95\uF3B7\uCF96\uC8E4\uF3B6\uCF97"+ - "\uCF98\uCF99\uCF9A\uF3BA\uCF9B\uCF9C\uCF9D\uCF9E"+ - "\uCF9F\uF3BB\uB4C0\uCFA0\uD040\uD041\uD042\uD043"+ - "\uD044\uD045\uD046\uD047\uD048\uD049\uD04A\uD04B"+ - "\uD04C\uD04D\uEEC3\uD04E\uD04F\uD050\uD051\uD052"+ - "\uD053\uF3BC\uD054\uD055\uF3BD\uD056\uD057\uD058"+ - "\uD1AA\uD059\uD05A\uD05B\uF4AC\uD0C6\uD05C\uD05D"+ - "\uD05E\uD05F\uD060\uD061\uD0D0\uD1DC\uD062\uD063"+ - "\uD064\uD065\uD066\uD067\uCFCE\uD068\uD069\uBDD6"+ - "\uD06A\uD1C3\uD06B\uD06C\uD06D\uD06E\uD06F\uD070"+ - "\uD071\uBAE2\uE1E9\uD2C2\uF1C2\uB2B9\uD072\uD073"+ - "\uB1ED\uF1C3\uD074\uC9C0\uB3C4\uD075\uD9F2\uD076"+ - "\uCBA5\uD077\uF1C4\uD078\uD079\uD07A\uD07B\uD6D4"+ - "\uD07C\uD07D\uD07E\uD080\uD081\uF1C5\uF4C0\uF1C6"+ - "\uD082\uD4AC\uF1C7\uD083\uB0C0\uF4C1\uD084\uD085"+ - "\uF4C2\uD086\uD087\uB4FC\uD088\uC5DB\uD089\uD08A"+ - "\uD08B\uD08C\uCCBB\uD08D\uD08E\uD08F\uD0E4\uD090"+ - "\uD091\uD092\uD093\uD094\uCDE0\uD095\uD096\uD097"+ - "\uD098\uD099\uF1C8\uD09A\uD9F3\uD09B\uD09C\uD09D"+ - "\uD09E\uD09F\uD0A0\uB1BB\uD140\uCFAE\uD141\uD142"+ - "\uD143\uB8A4\uD144\uD145\uD146\uD147\uD148\uF1CA"+ - "\uD149\uD14A\uD14B\uD14C\uF1CB\uD14D\uD14E\uD14F"+ - "\uD150\uB2C3\uC1D1\uD151\uD152\uD7B0\uF1C9\uD153"+ - "\uD154\uF1CC\uD155\uD156\uD157\uD158\uF1CE\uD159"+ - "\uD15A\uD15B\uD9F6\uD15C\uD2E1\uD4A3\uD15D\uD15E"+ - "\uF4C3\uC8B9\uD15F\uD160\uD161\uD162\uD163\uF4C4"+ - "\uD164\uD165\uF1CD\uF1CF\uBFE3\uF1D0\uD166\uD167"+ - "\uF1D4\uD168\uD169\uD16A\uD16B\uD16C\uD16D\uD16E"+ - "\uF1D6\uF1D1\uD16F\uC9D1\uC5E1\uD170\uD171\uD172"+ - "\uC2E3\uB9FC\uD173\uD174\uF1D3\uD175\uF1D5\uD176"+ - "\uD177\uD178\uB9D3\uD179\uD17A\uD17B\uD17C\uD17D"+ - "\uD17E\uD180\uF1DB\uD181\uD182\uD183\uD184\uD185"+ - "\uBAD6\uD186\uB0FD\uF1D9\uD187\uD188\uD189\uD18A"+ - "\uD18B\uF1D8\uF1D2\uF1DA\uD18C\uD18D\uD18E\uD18F"+ - "\uD190\uF1D7\uD191\uD192\uD193\uC8EC\uD194\uD195"+ - "\uD196\uD197\uCDCA\uF1DD\uD198\uD199\uD19A\uD19B"+ - "\uE5BD\uD19C\uD19D\uD19E\uF1DC\uD19F\uF1DE\uD1A0"+ - "\uD240\uD241\uD242\uD243\uD244\uD245\uD246\uD247"+ - "\uD248\uF1DF\uD249\uD24A\uCFE5\uD24B\uD24C\uD24D"+ - "\uD24E\uD24F\uD250\uD251\uD252\uD253\uD254\uD255"+ - "\uD256\uD257\uD258\uD259\uD25A\uD25B\uD25C\uD25D"+ - "\uD25E\uD25F\uD260\uD261\uD262\uD263\uF4C5\uBDF3"+ - "\uD264\uD265\uD266\uD267\uD268\uD269\uF1E0\uD26A"+ - "\uD26B\uD26C\uD26D\uD26E\uD26F\uD270\uD271\uD272"+ - "\uD273\uD274\uD275\uD276\uD277\uD278\uD279\uD27A"+ - "\uD27B\uD27C\uD27D\uF1E1\uD27E\uD280\uD281\uCEF7"+ - "\uD282\uD2AA\uD283\uF1FB\uD284\uD285\uB8B2\uD286"+ - "\uD287\uD288\uD289\uD28A\uD28B\uD28C\uD28D\uD28E"+ - "\uD28F\uD290\uD291\uD292\uD293\uD294\uD295\uD296"+ - "\uD297\uD298\uD299\uD29A\uD29B\uD29C\uD29D\uD29E"+ - "\uD29F\uD2A0\uD340\uD341\uD342\uD343\uD344\uD345"+ - "\uD346\uD347\uD348\uD349\uD34A\uD34B\uD34C\uD34D"+ - "\uD34E\uD34F\uD350\uD351\uD352\uD353\uD354\uD355"+ - "\uD356\uD357\uD358\uD359\uD35A\uD35B\uD35C\uD35D"+ - "\uD35E\uBCFB\uB9DB\uD35F\uB9E6\uC3D9\uCAD3\uEAE8"+ - "\uC0C0\uBEF5\uEAE9\uEAEA\uEAEB\uD360\uEAEC\uEAED"+ - "\uEAEE\uEAEF\uBDC7\uD361\uD362\uD363\uF5FB\uD364"+ - "\uD365\uD366\uF5FD\uD367\uF5FE\uD368\uF5FC\uD369"+ - "\uD36A\uD36B\uD36C\uBDE2\uD36D\uF6A1\uB4A5\uD36E"+ - "\uD36F\uD370\uD371\uF6A2\uD372\uD373\uD374\uF6A3"+ - "\uD375\uD376\uD377\uECB2\uD378\uD379\uD37A\uD37B"+ - "\uD37C\uD37D\uD37E\uD380\uD381\uD382\uD383\uD384"+ - "\uD1D4\uD385\uD386\uD387\uD388\uD389\uD38A\uD9EA"+ - "\uD38B\uD38C\uD38D\uD38E\uD38F\uD390\uD391\uD392"+ - "\uD393\uD394\uD395\uD396\uD397\uD398\uD399\uD39A"+ - "\uD39B\uD39C\uD39D\uD39E\uD39F\uD3A0\uD440\uD441"+ - "\uD442\uD443\uD444\uD445\uD446\uD447\uD448\uD449"+ - "\uD44A\uD44B\uD44C\uD44D\uD44E\uD44F\uD450\uD451"+ - "\uD452\uD453\uD454\uD455\uD456\uD457\uD458\uD459"+ - "\uD45A\uD45B\uD45C\uD45D\uD45E\uD45F\uF6A4\uD460"+ - "\uD461\uD462\uD463\uD464\uD465\uD466\uD467\uD468"+ - "\uEEBA\uD469\uD46A\uD46B\uD46C\uD46D\uD46E\uD46F"+ - "\uD470\uD471\uD472\uD473\uD474\uD475\uD476\uD477"+ - "\uD478\uD479\uD47A\uD47B\uD47C\uD47D\uD47E\uD480"+ - "\uD481\uD482\uD483\uD484\uD485\uD486\uD487\uD488"+ - "\uD489\uD48A\uD48B\uD48C\uD48D\uD48E\uD48F\uD490"+ - "\uD491\uD492\uD493\uD494\uD495\uD496\uD497\uD498"+ - "\uD499\uD5B2\uD49A\uD49B\uD49C\uD49D\uD49E\uD49F"+ - "\uD4A0\uD540\uD541\uD542\uD543\uD544\uD545\uD546"+ - "\uD547\uD3FE\uCCDC\uD548\uD549\uD54A\uD54B\uD54C"+ - "\uD54D\uD54E\uD54F\uCAC4\uD550\uD551\uD552\uD553"+ - "\uD554\uD555\uD556\uD557\uD558\uD559\uD55A\uD55B"+ - "\uD55C\uD55D\uD55E\uD55F\uD560\uD561\uD562\uD563"+ - "\uD564\uD565\uD566\uD567\uD568\uD569\uD56A\uD56B"+ - "\uD56C\uD56D\uD56E\uD56F\uD570\uD571\uD572\uD573"+ - "\uD574\uD575\uD576\uD577\uD578\uD579\uD57A\uD57B"+ - "\uD57C\uD57D\uD57E\uD580\uD581\uD582\uD583\uD584"+ - "\uD585\uD586\uD587\uD588\uD589\uD58A\uD58B\uD58C"+ - "\uD58D\uD58E\uD58F\uD590\uD591\uD592\uD593\uD594"+ - "\uD595\uD596\uD597\uD598\uD599\uD59A\uD59B\uD59C"+ - "\uD59D\uD59E\uD59F\uD5A0\uD640\uD641\uD642\uD643"+ - "\uD644\uD645\uD646\uD647\uD648\uD649\uD64A\uD64B"+ - "\uD64C\uD64D\uD64E\uD64F\uD650\uD651\uD652\uD653"+ - "\uD654\uD655\uD656\uD657\uD658\uD659\uD65A\uD65B"+ - "\uD65C\uD65D\uD65E\uD65F\uD660\uD661\uD662\uE5C0"+ - "\uD663\uD664\uD665\uD666\uD667\uD668\uD669\uD66A"+ - "\uD66B\uD66C\uD66D\uD66E\uD66F\uD670\uD671\uD672"+ - "\uD673\uD674\uD675\uD676\uD677\uD678\uD679\uD67A"+ - "\uD67B\uD67C\uD67D\uD67E\uD680\uD681\uF6A5\uD682"+ - "\uD683\uD684\uD685\uD686\uD687\uD688\uD689\uD68A"+ - "\uD68B\uD68C\uD68D\uD68E\uD68F\uD690\uD691\uD692"+ - "\uD693\uD694\uD695\uD696\uD697\uD698\uD699\uD69A"+ - "\uD69B\uD69C\uD69D\uD69E\uD69F\uD6A0\uD740\uD741"+ - "\uD742\uD743\uD744\uD745\uD746\uD747\uD748\uD749"+ - "\uD74A\uD74B\uD74C\uD74D\uD74E\uD74F\uD750\uD751"+ - "\uD752\uD753\uD754\uD755\uD756\uD757\uD758\uD759"+ - "\uD75A\uD75B\uD75C\uD75D\uD75E\uD75F\uBEAF\uD760"+ - "\uD761\uD762\uD763\uD764\uC6A9\uD765\uD766\uD767"+ - "\uD768\uD769\uD76A\uD76B\uD76C\uD76D\uD76E\uD76F"+ - "\uD770\uD771\uD772\uD773\uD774\uD775\uD776\uD777"+ - "\uD778\uD779\uD77A\uD77B\uD77C\uD77D\uD77E\uD780"+ - "\uD781\uD782\uD783\uD784\uD785\uD786\uD787\uD788"+ - "\uD789\uD78A\uD78B\uD78C\uD78D\uD78E\uD78F\uD790"+ - "\uD791\uD792\uD793\uD794\uD795\uD796\uD797\uD798"+ - "\uDAA5\uBCC6\uB6A9\uB8BC\uC8CF\uBCA5\uDAA6\uDAA7"+ - "\uCCD6\uC8C3\uDAA8\uC6FD\uD799\uD1B5\uD2E9\uD1B6"+ - "\uBCC7\uD79A\uBDB2\uBBE4\uDAA9\uDAAA\uD1C8\uDAAB"+ - "\uD0ED\uB6EF\uC2DB\uD79B\uCBCF\uB7ED\uC9E8\uB7C3"+ - "\uBEF7\uD6A4\uDAAC\uDAAD\uC6C0\uD7E7\uCAB6\uD79C"+ - "\uD5A9\uCBDF\uD5EF\uDAAE\uD6DF\uB4CA\uDAB0\uDAAF"+ - "\uD79D\uD2EB\uDAB1\uDAB2\uDAB3\uCAD4\uDAB4\uCAAB"+ - "\uDAB5\uDAB6\uB3CF\uD6EF\uDAB7\uBBB0\uB5AE\uDAB8"+ - "\uDAB9\uB9EE\uD1AF\uD2E8\uDABA\uB8C3\uCFEA\uB2EF"+ - "\uDABB\uDABC\uD79E\uBDEB\uCEDC\uD3EF\uDABD\uCEF3"+ - "\uDABE\uD3D5\uBBE5\uDABF\uCBB5\uCBD0\uDAC0\uC7EB"+ - "\uD6EE\uDAC1\uC5B5\uB6C1\uDAC2\uB7CC\uBFCE\uDAC3"+ - "\uDAC4\uCBAD\uDAC5\uB5F7\uDAC6\uC1C2\uD7BB\uDAC7"+ - "\uCCB8\uD79F\uD2EA\uC4B1\uDAC8\uB5FD\uBBD1\uDAC9"+ - "\uD0B3\uDACA\uDACB\uCEBD\uDACC\uDACD\uDACE\uB2F7"+ - "\uDAD1\uDACF\uD1E8\uDAD0\uC3D5\uDAD2\uD7A0\uDAD3"+ - "\uDAD4\uDAD5\uD0BB\uD2A5\uB0F9\uDAD6\uC7AB\uDAD7"+ - "\uBDF7\uC3A1\uDAD8\uDAD9\uC3FD\uCCB7\uDADA\uDADB"+ - "\uC0BE\uC6D7\uDADC\uDADD\uC7B4\uDADE\uDADF\uB9C8"+ - "\uD840\uD841\uD842\uD843\uD844\uD845\uD846\uD847"+ - "\uD848\uBBED\uD849\uD84A\uD84B\uD84C\uB6B9\uF4F8"+ - "\uD84D\uF4F9\uD84E\uD84F\uCDE3\uD850\uD851\uD852"+ - "\uD853\uD854\uD855\uD856\uD857\uF5B9\uD858\uD859"+ - "\uD85A\uD85B\uEBE0\uD85C\uD85D\uD85E\uD85F\uD860"+ - "\uD861\uCFF3\uBBBF\uD862\uD863\uD864\uD865\uD866"+ - "\uD867\uD868\uBAC0\uD4A5\uD869\uD86A\uD86B\uD86C"+ - "\uD86D\uD86E\uD86F\uE1D9\uD870\uD871\uD872\uD873"+ - "\uF5F4\uB1AA\uB2F2\uD874\uD875\uD876\uD877\uD878"+ - "\uD879\uD87A\uF5F5\uD87B\uD87C\uF5F7\uD87D\uD87E"+ - "\uD880\uBAD1\uF5F6\uD881\uC3B2\uD882\uD883\uD884"+ - "\uD885\uD886\uD887\uD888\uF5F9\uD889\uD88A\uD88B"+ - "\uF5F8\uD88C\uD88D\uD88E\uD88F\uD890\uD891\uD892"+ - "\uD893\uD894\uD895\uD896\uD897\uD898\uD899\uD89A"+ - "\uD89B\uD89C\uD89D\uD89E\uD89F\uD8A0\uD940\uD941"+ - "\uD942\uD943\uD944\uD945\uD946\uD947\uD948\uD949"+ - "\uD94A\uD94B\uD94C\uD94D\uD94E\uD94F\uD950\uD951"+ - "\uD952\uD953\uD954\uD955\uD956\uD957\uD958\uD959"+ - "\uD95A\uD95B\uD95C\uD95D\uD95E\uD95F\uD960\uD961"+ - "\uD962\uD963\uD964\uD965\uD966\uD967\uD968\uD969"+ - "\uD96A\uD96B\uD96C\uD96D\uD96E\uD96F\uD970\uD971"+ - "\uD972\uD973\uD974\uD975\uD976\uD977\uD978\uD979"+ - "\uD97A\uD97B\uD97C\uD97D\uD97E\uD980\uD981\uD982"+ - "\uD983\uD984\uD985\uD986\uD987\uD988\uD989\uD98A"+ - "\uD98B\uD98C\uD98D\uD98E\uD98F\uD990\uD991\uD992"+ - "\uD993\uD994\uD995\uD996\uD997\uD998\uD999\uD99A"+ - "\uD99B\uD99C\uD99D\uD99E\uD99F\uD9A0\uDA40\uDA41"+ - "\uDA42\uDA43\uDA44\uDA45\uDA46\uDA47\uDA48\uDA49"+ - "\uDA4A\uDA4B\uDA4C\uDA4D\uDA4E\uB1B4\uD5EA\uB8BA"+ - "\uDA4F\uB9B1\uB2C6\uD4F0\uCFCD\uB0DC\uD5CB\uBBF5"+ - "\uD6CA\uB7B7\uCCB0\uC6B6\uB1E1\uB9BA\uD6FC\uB9E1"+ - "\uB7A1\uBCFA\uEADA\uEADB\uCCF9\uB9F3\uEADC\uB4FB"+ - "\uC3B3\uB7D1\uBAD8\uEADD\uD4F4\uEADE\uBCD6\uBBDF"+ - "\uEADF\uC1DE\uC2B8\uD4DF\uD7CA\uEAE0\uEAE1\uEAE4"+ - "\uEAE2\uEAE3\uC9DE\uB8B3\uB6C4\uEAE5\uCAEA\uC9CD"+ - "\uB4CD\uDA50\uDA51\uE2D9\uC5E2\uEAE6\uC0B5\uDA52"+ - "\uD7B8\uEAE7\uD7AC\uC8FC\uD8D3\uD8CD\uD4DE\uDA53"+ - "\uD4F9\uC9C4\uD3AE\uB8D3\uB3E0\uDA54\uC9E2\uF4F6"+ - "\uDA55\uDA56\uDA57\uBAD5\uDA58\uF4F7\uDA59\uDA5A"+ - "\uD7DF\uDA5B\uDA5C\uF4F1\uB8B0\uD5D4\uB8CF\uC6F0"+ - "\uDA5D\uDA5E\uDA5F\uDA60\uDA61\uDA62\uDA63\uDA64"+ - "\uDA65\uB3C3\uDA66\uDA67\uF4F2\uB3AC\uDA68\uDA69"+ - "\uDA6A\uDA6B\uD4BD\uC7F7\uDA6C\uDA6D\uDA6E\uDA6F"+ - "\uDA70\uF4F4\uDA71\uDA72\uF4F3\uDA73\uDA74\uDA75"+ - "\uDA76\uDA77\uDA78\uDA79\uDA7A\uDA7B\uDA7C\uCCCB"+ - "\uDA7D\uDA7E\uDA80\uC8A4\uDA81\uDA82\uDA83\uDA84"+ - "\uDA85\uDA86\uDA87\uDA88\uDA89\uDA8A\uDA8B\uDA8C"+ - "\uDA8D\uF4F5\uDA8E\uD7E3\uC5BF\uF5C0\uDA8F\uDA90"+ - "\uF5BB\uDA91\uF5C3\uDA92\uF5C2\uDA93\uD6BA\uF5C1"+ - "\uDA94\uDA95\uDA96\uD4BE\uF5C4\uDA97\uF5CC\uDA98"+ - "\uDA99\uDA9A\uDA9B\uB0CF\uB5F8\uDA9C\uF5C9\uF5CA"+ - "\uDA9D\uC5DC\uDA9E\uDA9F\uDAA0\uDB40\uF5C5\uF5C6"+ - "\uDB41\uDB42\uF5C7\uF5CB\uDB43\uBEE0\uF5C8\uB8FA"+ - "\uDB44\uDB45\uDB46\uF5D0\uF5D3\uDB47\uDB48\uDB49"+ - "\uBFE7\uDB4A\uB9F2\uF5BC\uF5CD\uDB4B\uDB4C\uC2B7"+ - "\uDB4D\uDB4E\uDB4F\uCCF8\uDB50\uBCF9\uDB51\uF5CE"+ - "\uF5CF\uF5D1\uB6E5\uF5D2\uDB52\uF5D5\uDB53\uDB54"+ - "\uDB55\uDB56\uDB57\uDB58\uDB59\uF5BD\uDB5A\uDB5B"+ - "\uDB5C\uF5D4\uD3BB\uDB5D\uB3EC\uDB5E\uDB5F\uCCA4"+ - "\uDB60\uDB61\uDB62\uDB63\uF5D6\uDB64\uDB65\uDB66"+ - "\uDB67\uDB68\uDB69\uDB6A\uDB6B\uF5D7\uBEE1\uF5D8"+ - "\uDB6C\uDB6D\uCCDF\uF5DB\uDB6E\uDB6F\uDB70\uDB71"+ - "\uDB72\uB2C8\uD7D9\uDB73\uF5D9\uDB74\uF5DA\uF5DC"+ - "\uDB75\uF5E2\uDB76\uDB77\uDB78\uF5E0\uDB79\uDB7A"+ - "\uDB7B\uF5DF\uF5DD\uDB7C\uDB7D\uF5E1\uDB7E\uDB80"+ - "\uF5DE\uF5E4\uF5E5\uDB81\uCCE3\uDB82\uDB83\uE5BF"+ - "\uB5B8\uF5E3\uF5E8\uCCA3\uDB84\uDB85\uDB86\uDB87"+ - "\uDB88\uF5E6\uF5E7\uDB89\uDB8A\uDB8B\uDB8C\uDB8D"+ - "\uDB8E\uF5BE\uDB8F\uDB90\uDB91\uDB92\uDB93\uDB94"+ - "\uDB95\uDB96\uDB97\uDB98\uDB99\uDB9A\uB1C4\uDB9B"+ - "\uDB9C\uF5BF\uDB9D\uDB9E\uB5C5\uB2E4\uDB9F\uF5EC"+ - "\uF5E9\uDBA0\uB6D7\uDC40\uF5ED\uDC41\uF5EA\uDC42"+ - "\uDC43\uDC44\uDC45\uDC46\uF5EB\uDC47\uDC48\uB4DA"+ - "\uDC49\uD4EA\uDC4A\uDC4B\uDC4C\uF5EE\uDC4D\uB3F9"+ - "\uDC4E\uDC4F\uDC50\uDC51\uDC52\uDC53\uDC54\uF5EF"+ - "\uF5F1\uDC55\uDC56\uDC57\uF5F0\uDC58\uDC59\uDC5A"+ - "\uDC5B\uDC5C\uDC5D\uDC5E\uF5F2\uDC5F\uF5F3\uDC60"+ - "\uDC61\uDC62\uDC63\uDC64\uDC65\uDC66\uDC67\uDC68"+ - "\uDC69\uDC6A\uDC6B\uC9ED\uB9AA\uDC6C\uDC6D\uC7FB"+ - "\uDC6E\uDC6F\uB6E3\uDC70\uDC71\uDC72\uDC73\uDC74"+ - "\uDC75\uDC76\uCCC9\uDC77\uDC78\uDC79\uDC7A\uDC7B"+ - "\uDC7C\uDC7D\uDC7E\uDC80\uDC81\uDC82\uDC83\uDC84"+ - "\uDC85\uDC86\uDC87\uDC88\uDC89\uDC8A\uEAA6\uDC8B"+ - "\uDC8C\uDC8D\uDC8E\uDC8F\uDC90\uDC91\uDC92\uDC93"+ - "\uDC94\uDC95\uDC96\uDC97\uDC98\uDC99\uDC9A\uDC9B"+ - "\uDC9C\uDC9D\uDC9E\uDC9F\uDCA0\uDD40\uDD41\uDD42"+ - "\uDD43\uDD44\uDD45\uDD46\uDD47\uDD48\uDD49\uDD4A"+ - "\uDD4B\uDD4C\uDD4D\uDD4E\uDD4F\uDD50\uDD51\uDD52"+ - "\uDD53\uDD54\uDD55\uDD56\uDD57\uDD58\uDD59\uDD5A"+ - "\uDD5B\uDD5C\uDD5D\uDD5E\uDD5F\uDD60\uDD61\uDD62"+ - "\uDD63\uDD64\uDD65\uDD66\uDD67\uDD68\uDD69\uDD6A"+ - "\uDD6B\uDD6C\uDD6D\uDD6E\uDD6F\uDD70\uDD71\uDD72"+ - "\uDD73\uDD74\uDD75\uDD76\uDD77\uDD78\uDD79\uDD7A"+ - "\uDD7B\uDD7C\uDD7D\uDD7E\uDD80\uDD81\uDD82\uDD83"+ - "\uDD84\uDD85\uDD86\uDD87\uDD88\uDD89\uDD8A\uDD8B"+ - "\uDD8C\uDD8D\uDD8E\uDD8F\uDD90\uDD91\uDD92\uDD93"+ - "\uDD94\uDD95\uDD96\uDD97\uDD98\uDD99\uDD9A\uDD9B"+ - "\uDD9C\uDD9D\uDD9E\uDD9F\uDDA0\uDE40\uDE41\uDE42"+ - "\uDE43\uDE44\uDE45\uDE46\uDE47\uDE48\uDE49\uDE4A"+ - "\uDE4B\uDE4C\uDE4D\uDE4E\uDE4F\uDE50\uDE51\uDE52"+ - "\uDE53\uDE54\uDE55\uDE56\uDE57\uDE58\uDE59\uDE5A"+ - "\uDE5B\uDE5C\uDE5D\uDE5E\uDE5F\uDE60\uB3B5\uD4FE"+ - "\uB9EC\uD0F9\uDE61\uE9ED\uD7AA\uE9EE\uC2D6\uC8ED"+ - "\uBAE4\uE9EF\uE9F0\uE9F1\uD6E1\uE9F2\uE9F3\uE9F5"+ - "\uE9F4\uE9F6\uE9F7\uC7E1\uE9F8\uD4D8\uE9F9\uBDCE"+ - "\uDE62\uE9FA\uE9FB\uBDCF\uE9FC\uB8A8\uC1BE\uE9FD"+ - "\uB1B2\uBBD4\uB9F5\uE9FE\uDE63\uEAA1\uEAA2\uEAA3"+ - "\uB7F8\uBCAD\uDE64\uCAE4\uE0CE\uD4AF\uCFBD\uD5B7"+ - "\uEAA4\uD5DE\uEAA5\uD0C1\uB9BC\uDE65\uB4C7\uB1D9"+ - "\uDE66\uDE67\uDE68\uC0B1\uDE69\uDE6A\uDE6B\uDE6C"+ - "\uB1E6\uB1E7\uDE6D\uB1E8\uDE6E\uDE6F\uDE70\uDE71"+ - "\uB3BD\uC8E8\uDE72\uDE73\uDE74\uDE75\uE5C1\uDE76"+ - "\uDE77\uB1DF\uDE78\uDE79\uDE7A\uC1C9\uB4EF\uDE7B"+ - "\uDE7C\uC7A8\uD3D8\uDE7D\uC6F9\uD1B8\uDE7E\uB9FD"+ - "\uC2F5\uDE80\uDE81\uDE82\uDE83\uDE84\uD3AD\uDE85"+ - "\uD4CB\uBDFC\uDE86\uE5C2\uB7B5\uE5C3\uDE87\uDE88"+ - "\uBBB9\uD5E2\uDE89\uBDF8\uD4B6\uCEA5\uC1AC\uB3D9"+ - "\uDE8A\uDE8B\uCCF6\uDE8C\uE5C6\uE5C4\uE5C8\uDE8D"+ - "\uE5CA\uE5C7\uB5CF\uC6C8\uDE8E\uB5FC\uE5C5\uDE8F"+ - "\uCAF6\uDE90\uDE91\uE5C9\uDE92\uDE93\uDE94\uC3D4"+ - "\uB1C5\uBCA3\uDE95\uDE96\uDE97\uD7B7\uDE98\uDE99"; - - private static final String innerEncoderIndex9= - "\uCDCB\uCBCD\uCACA\uCCD3\uE5CC\uE5CB\uC4E6\uDE9A"+ - "\uDE9B\uD1A1\uD1B7\uE5CD\uDE9C\uE5D0\uDE9D\uCDB8"+ - "\uD6F0\uE5CF\uB5DD\uDE9E\uCDBE\uDE9F\uE5D1\uB6BA"+ - "\uDEA0\uDF40\uCDA8\uB9E4\uDF41\uCAC5\uB3D1\uCBD9"+ - "\uD4EC\uE5D2\uB7EA\uDF42\uDF43\uDF44\uE5CE\uDF45"+ - "\uDF46\uDF47\uDF48\uDF49\uDF4A\uE5D5\uB4FE\uE5D6"+ - "\uDF4B\uDF4C\uDF4D\uDF4E\uDF4F\uE5D3\uE5D4\uDF50"+ - "\uD2DD\uDF51\uDF52\uC2DF\uB1C6\uDF53\uD3E2\uDF54"+ - "\uDF55\uB6DD\uCBEC\uDF56\uE5D7\uDF57\uDF58\uD3F6"+ - "\uDF59\uDF5A\uDF5B\uDF5C\uDF5D\uB1E9\uDF5E\uB6F4"+ - "\uE5DA\uE5D8\uE5D9\uB5C0\uDF5F\uDF60\uDF61\uD2C5"+ - "\uE5DC\uDF62\uDF63\uE5DE\uDF64\uDF65\uDF66\uDF67"+ - "\uDF68\uDF69\uE5DD\uC7B2\uDF6A\uD2A3\uDF6B\uDF6C"+ - "\uE5DB\uDF6D\uDF6E\uDF6F\uDF70\uD4E2\uD5DA\uDF71"+ - "\uDF72\uDF73\uDF74\uDF75\uE5E0\uD7F1\uDF76\uDF77"+ - "\uDF78\uDF79\uDF7A\uDF7B\uDF7C\uE5E1\uDF7D\uB1DC"+ - "\uD1FB\uDF7E\uE5E2\uE5E4\uDF80\uDF81\uDF82\uDF83"+ - "\uE5E3\uDF84\uDF85\uE5E5\uDF86\uDF87\uDF88\uDF89"+ - "\uDF8A\uD2D8\uDF8B\uB5CB\uDF8C\uE7DF\uDF8D\uDAF5"+ - "\uDF8E\uDAF8\uDF8F\uDAF6\uDF90\uDAF7\uDF91\uDF92"+ - "\uDF93\uDAFA\uD0CF\uC4C7\uDF94\uDF95\uB0EE\uDF96"+ - "\uDF97\uDF98\uD0B0\uDF99\uDAF9\uDF9A\uD3CA\uBAAA"+ - "\uDBA2\uC7F1\uDF9B\uDAFC\uDAFB\uC9DB\uDAFD\uDF9C"+ - "\uDBA1\uD7DE\uDAFE\uC1DA\uDF9D\uDF9E\uDBA5\uDF9F"+ - "\uDFA0\uD3F4\uE040\uE041\uDBA7\uDBA4\uE042\uDBA8"+ - "\uE043\uE044\uBDBC\uE045\uE046\uE047\uC0C9\uDBA3"+ - "\uDBA6\uD6A3\uE048\uDBA9\uE049\uE04A\uE04B\uDBAD"+ - "\uE04C\uE04D\uE04E\uDBAE\uDBAC\uBAC2\uE04F\uE050"+ - "\uE051\uBFA4\uDBAB\uE052\uE053\uE054\uDBAA\uD4C7"+ - "\uB2BF\uE055\uE056\uDBAF\uE057\uB9F9\uE058\uDBB0"+ - "\uE059\uE05A\uE05B\uE05C\uB3BB\uE05D\uE05E\uE05F"+ - "\uB5A6\uE060\uE061\uE062\uE063\uB6BC\uDBB1\uE064"+ - "\uE065\uE066\uB6F5\uE067\uDBB2\uE068\uE069\uE06A"+ - "\uE06B\uE06C\uE06D\uE06E\uE06F\uE070\uE071\uE072"+ - "\uE073\uE074\uE075\uE076\uE077\uE078\uE079\uE07A"+ - "\uE07B\uB1C9\uE07C\uE07D\uE07E\uE080\uDBB4\uE081"+ - "\uE082\uE083\uDBB3\uDBB5\uE084\uE085\uE086\uE087"+ - "\uE088\uE089\uE08A\uE08B\uE08C\uE08D\uE08E\uDBB7"+ - "\uE08F\uDBB6\uE090\uE091\uE092\uE093\uE094\uE095"+ - "\uE096\uDBB8\uE097\uE098\uE099\uE09A\uE09B\uE09C"+ - "\uE09D\uE09E\uE09F\uDBB9\uE0A0\uE140\uDBBA\uE141"+ - "\uE142\uD3CF\uF4FA\uC7F5\uD7C3\uC5E4\uF4FC\uF4FD"+ - "\uF4FB\uE143\uBEC6\uE144\uE145\uE146\uE147\uD0EF"+ - "\uE148\uE149\uB7D3\uE14A\uE14B\uD4CD\uCCAA\uE14C"+ - "\uE14D\uF5A2\uF5A1\uBAA8\uF4FE\uCBD6\uE14E\uE14F"+ - "\uE150\uF5A4\uC0D2\uE151\uB3EA\uE152\uCDAA\uF5A5"+ - "\uF5A3\uBDB4\uF5A8\uE153\uF5A9\uBDCD\uC3B8\uBFE1"+ - "\uCBE1\uF5AA\uE154\uE155\uE156\uF5A6\uF5A7\uC4F0"+ - "\uE157\uE158\uE159\uE15A\uE15B\uF5AC\uE15C\uB4BC"+ - "\uE15D\uD7ED\uE15E\uB4D7\uF5AB\uF5AE\uE15F\uE160"+ - "\uF5AD\uF5AF\uD0D1\uE161\uE162\uE163\uE164\uE165"+ - "\uE166\uE167\uC3D1\uC8A9\uE168\uE169\uE16A\uE16B"+ - "\uE16C\uE16D\uF5B0\uF5B1\uE16E\uE16F\uE170\uE171"+ - "\uE172\uE173\uF5B2\uE174\uE175\uF5B3\uF5B4\uF5B5"+ - "\uE176\uE177\uE178\uE179\uF5B7\uF5B6\uE17A\uE17B"+ - "\uE17C\uE17D\uF5B8\uE17E\uE180\uE181\uE182\uE183"+ - "\uE184\uE185\uE186\uE187\uE188\uE189\uE18A\uB2C9"+ - "\uE18B\uD3D4\uCACD\uE18C\uC0EF\uD6D8\uD2B0\uC1BF"+ - "\uE18D\uBDF0\uE18E\uE18F\uE190\uE191\uE192\uE193"+ - "\uE194\uE195\uE196\uE197\uB8AA\uE198\uE199\uE19A"+ - "\uE19B\uE19C\uE19D\uE19E\uE19F\uE1A0\uE240\uE241"+ - "\uE242\uE243\uE244\uE245\uE246\uE247\uE248\uE249"+ - "\uE24A\uE24B\uE24C\uE24D\uE24E\uE24F\uE250\uE251"+ - "\uE252\uE253\uE254\uE255\uE256\uE257\uE258\uE259"+ - "\uE25A\uE25B\uE25C\uE25D\uE25E\uE25F\uE260\uE261"+ - "\uE262\uE263\uE264\uE265\uE266\uE267\uE268\uE269"+ - "\uE26A\uE26B\uE26C\uE26D\uE26E\uE26F\uE270\uE271"+ - "\uE272\uE273\uE274\uE275\uE276\uE277\uE278\uE279"+ - "\uE27A\uE27B\uE27C\uE27D\uE27E\uE280\uE281\uE282"+ - "\uE283\uE284\uE285\uE286\uE287\uE288\uE289\uE28A"+ - "\uE28B\uE28C\uE28D\uE28E\uE28F\uE290\uE291\uE292"+ - "\uE293\uE294\uE295\uE296\uE297\uE298\uE299\uE29A"+ - "\uE29B\uE29C\uE29D\uE29E\uE29F\uE2A0\uE340\uE341"+ - "\uE342\uE343\uE344\uE345\uE346\uE347\uE348\uE349"+ - "\uE34A\uE34B\uE34C\uE34D\uE34E\uE34F\uE350\uE351"+ - "\uE352\uE353\uE354\uE355\uE356\uE357\uE358\uE359"+ - "\uE35A\uE35B\uE35C\uE35D\uE35E\uE35F\uE360\uE361"+ - "\uE362\uE363\uE364\uE365\uE366\uE367\uE368\uE369"+ - "\uE36A\uE36B\uE36C\uE36D\uBCF8\uE36E\uE36F\uE370"+ - "\uE371\uE372\uE373\uE374\uE375\uE376\uE377\uE378"+ - "\uE379\uE37A\uE37B\uE37C\uE37D\uE37E\uE380\uE381"+ - "\uE382\uE383\uE384\uE385\uE386\uE387\uF6C6\uE388"+ - "\uE389\uE38A\uE38B\uE38C\uE38D\uE38E\uE38F\uE390"+ - "\uE391\uE392\uE393\uE394\uE395\uE396\uE397\uE398"+ - "\uE399\uE39A\uE39B\uE39C\uE39D\uE39E\uE39F\uE3A0"+ - "\uE440\uE441\uE442\uE443\uE444\uE445\uF6C7\uE446"+ - "\uE447\uE448\uE449\uE44A\uE44B\uE44C\uE44D\uE44E"+ - "\uE44F\uE450\uE451\uE452\uE453\uE454\uE455\uE456"+ - "\uE457\uE458\uE459\uE45A\uE45B\uE45C\uE45D\uE45E"+ - "\uF6C8\uE45F\uE460\uE461\uE462\uE463\uE464\uE465"+ - "\uE466\uE467\uE468\uE469\uE46A\uE46B\uE46C\uE46D"+ - "\uE46E\uE46F\uE470\uE471\uE472\uE473\uE474\uE475"+ - "\uE476\uE477\uE478\uE479\uE47A\uE47B\uE47C\uE47D"+ - "\uE47E\uE480\uE481\uE482\uE483\uE484\uE485\uE486"+ - "\uE487\uE488\uE489\uE48A\uE48B\uE48C\uE48D\uE48E"+ - "\uE48F\uE490\uE491\uE492\uE493\uE494\uE495\uE496"+ - "\uE497\uE498\uE499\uE49A\uE49B\uE49C\uE49D\uE49E"+ - "\uE49F\uE4A0\uE540\uE541\uE542\uE543\uE544\uE545"+ - "\uE546\uE547\uE548\uE549\uE54A\uE54B\uE54C\uE54D"+ - "\uE54E\uE54F\uE550\uE551\uE552\uE553\uE554\uE555"+ - "\uE556\uE557\uE558\uE559\uE55A\uE55B\uE55C\uE55D"+ - "\uE55E\uE55F\uE560\uE561\uE562\uE563\uE564\uE565"+ - "\uE566\uE567\uE568\uE569\uE56A\uE56B\uE56C\uE56D"+ - "\uE56E\uE56F\uE570\uE571\uE572\uE573\uF6C9\uE574"+ - "\uE575\uE576\uE577\uE578\uE579\uE57A\uE57B\uE57C"+ - "\uE57D\uE57E\uE580\uE581\uE582\uE583\uE584\uE585"+ - "\uE586\uE587\uE588\uE589\uE58A\uE58B\uE58C\uE58D"+ - "\uE58E\uE58F\uE590\uE591\uE592\uE593\uE594\uE595"+ - "\uE596\uE597\uE598\uE599\uE59A\uE59B\uE59C\uE59D"+ - "\uE59E\uE59F\uF6CA\uE5A0\uE640\uE641\uE642\uE643"+ - "\uE644\uE645\uE646\uE647\uE648\uE649\uE64A\uE64B"+ - "\uE64C\uE64D\uE64E\uE64F\uE650\uE651\uE652\uE653"+ - "\uE654\uE655\uE656\uE657\uE658\uE659\uE65A\uE65B"+ - "\uE65C\uE65D\uE65E\uE65F\uE660\uE661\uE662\uF6CC"+ - "\uE663\uE664\uE665\uE666\uE667\uE668\uE669\uE66A"+ - "\uE66B\uE66C\uE66D\uE66E\uE66F\uE670\uE671\uE672"+ - "\uE673\uE674\uE675\uE676\uE677\uE678\uE679\uE67A"+ - "\uE67B\uE67C\uE67D\uE67E\uE680\uE681\uE682\uE683"+ - "\uE684\uE685\uE686\uE687\uE688\uE689\uE68A\uE68B"+ - "\uE68C\uE68D\uE68E\uE68F\uE690\uE691\uE692\uE693"+ - "\uE694\uE695\uE696\uE697\uE698\uE699\uE69A\uE69B"+ - "\uE69C\uE69D\uF6CB\uE69E\uE69F\uE6A0\uE740\uE741"+ - "\uE742\uE743\uE744\uE745\uE746\uE747\uF7E9\uE748"+ - "\uE749\uE74A\uE74B\uE74C\uE74D\uE74E\uE74F\uE750"+ - "\uE751\uE752\uE753\uE754\uE755\uE756\uE757\uE758"+ - "\uE759\uE75A\uE75B\uE75C\uE75D\uE75E\uE75F\uE760"+ - "\uE761\uE762\uE763\uE764\uE765\uE766\uE767\uE768"+ - "\uE769\uE76A\uE76B\uE76C\uE76D\uE76E\uE76F\uE770"+ - "\uE771\uE772\uE773\uE774\uE775\uE776\uE777\uE778"+ - "\uE779\uE77A\uE77B\uE77C\uE77D\uE77E\uE780\uE781"+ - "\uE782\uE783\uE784\uE785\uE786\uE787\uE788\uE789"+ - "\uE78A\uE78B\uE78C\uE78D\uE78E\uE78F\uE790\uE791"+ - "\uE792\uE793\uE794\uE795\uE796\uE797\uE798\uE799"+ - "\uE79A\uE79B\uE79C\uE79D\uE79E\uE79F\uE7A0\uE840"+ - "\uE841\uE842\uE843\uE844\uE845\uE846\uE847\uE848"+ - "\uE849\uE84A\uE84B\uE84C\uE84D\uE84E\uF6CD\uE84F"+ - "\uE850\uE851\uE852\uE853\uE854\uE855\uE856\uE857"+ - "\uE858\uE859\uE85A\uE85B\uE85C\uE85D\uE85E\uE85F"+ - "\uE860\uE861\uE862\uE863\uE864\uE865\uE866\uE867"+ - "\uE868\uE869\uE86A\uE86B\uE86C\uE86D\uE86E\uE86F"+ - "\uE870\uE871\uE872\uE873\uE874\uE875\uE876\uE877"+ - "\uE878\uE879\uE87A\uF6CE\uE87B\uE87C\uE87D\uE87E"+ - "\uE880\uE881\uE882\uE883\uE884\uE885\uE886\uE887"+ - "\uE888\uE889\uE88A\uE88B\uE88C\uE88D\uE88E\uE88F"+ - "\uE890\uE891\uE892\uE893\uE894\uEEC4\uEEC5\uEEC6"+ - "\uD5EB\uB6A4\uEEC8\uEEC7\uEEC9\uEECA\uC7A5\uEECB"+ - "\uEECC\uE895\uB7B0\uB5F6\uEECD\uEECF\uE896\uEECE"+ - "\uE897\uB8C6\uEED0\uEED1\uEED2\uB6DB\uB3AE\uD6D3"+ - "\uC4C6\uB1B5\uB8D6\uEED3\uEED4\uD4BF\uC7D5\uBEFB"+ - "\uCED9\uB9B3\uEED6\uEED5\uEED8\uEED7\uC5A5\uEED9"+ - "\uEEDA\uC7AE\uEEDB\uC7AF\uEEDC\uB2A7\uEEDD\uEEDE"+ - "\uEEDF\uEEE0\uEEE1\uD7EA\uEEE2\uEEE3\uBCD8\uEEE4"+ - "\uD3CB\uCCFA\uB2AC\uC1E5\uEEE5\uC7A6\uC3AD\uE898"+ - "\uEEE6\uEEE7\uEEE8\uEEE9\uEEEA\uEEEB\uEEEC\uE899"+ - "\uEEED\uEEEE\uEEEF\uE89A\uE89B\uEEF0\uEEF1\uEEF2"+ - "\uEEF4\uEEF3\uE89C\uEEF5\uCDAD\uC2C1\uEEF6\uEEF7"+ - "\uEEF8\uD5A1\uEEF9\uCFB3\uEEFA\uEEFB\uE89D\uEEFC"+ - "\uEEFD\uEFA1\uEEFE\uEFA2\uB8F5\uC3FA\uEFA3\uEFA4"+ - "\uBDC2\uD2BF\uB2F9\uEFA5\uEFA6\uEFA7\uD2F8\uEFA8"+ - "\uD6FD\uEFA9\uC6CC\uE89E\uEFAA\uEFAB\uC1B4\uEFAC"+ - "\uCFFA\uCBF8\uEFAE\uEFAD\uB3FA\uB9F8\uEFAF\uEFB0"+ - "\uD0E2\uEFB1\uEFB2\uB7E6\uD0BF\uEFB3\uEFB4\uEFB5"+ - "\uC8F1\uCCE0\uEFB6\uEFB7\uEFB8\uEFB9\uEFBA\uD5E0"+ - "\uEFBB\uB4ED\uC3AA\uEFBC\uE89F\uEFBD\uEFBE\uEFBF"+ - "\uE8A0\uCEFD\uEFC0\uC2E0\uB4B8\uD7B6\uBDF5\uE940"+ - "\uCFC7\uEFC3\uEFC1\uEFC2\uEFC4\uB6A7\uBCFC\uBEE2"+ - "\uC3CC\uEFC5\uEFC6\uE941\uEFC7\uEFCF\uEFC8\uEFC9"+ - "\uEFCA\uC7C2\uEFF1\uB6CD\uEFCB\uE942\uEFCC\uEFCD"+ - "\uB6C6\uC3BE\uEFCE\uE943\uEFD0\uEFD1\uEFD2\uD5F2"+ - "\uE944\uEFD3\uC4F7\uE945\uEFD4\uC4F8\uEFD5\uEFD6"+ - "\uB8E4\uB0F7\uEFD7\uEFD8\uEFD9\uE946\uEFDA\uEFDB"+ - "\uEFDC\uEFDD\uE947\uEFDE\uBEB5\uEFE1\uEFDF\uEFE0"+ - "\uE948\uEFE2\uEFE3\uC1CD\uEFE4\uEFE5\uEFE6\uEFE7"+ - "\uEFE8\uEFE9\uEFEA\uEFEB\uEFEC\uC0D8\uE949\uEFED"+ - "\uC1AD\uEFEE\uEFEF\uEFF0\uE94A\uE94B\uCFE2\uE94C"+ - "\uE94D\uE94E\uE94F\uE950\uE951\uE952\uE953\uB3A4"+ - "\uE954\uE955\uE956\uE957\uE958\uE959\uE95A\uE95B"+ - "\uE95C\uE95D\uE95E\uE95F\uE960\uE961\uE962\uE963"+ - "\uE964\uE965\uE966\uE967\uE968\uE969\uE96A\uE96B"+ - "\uE96C\uE96D\uE96E\uE96F\uE970\uE971\uE972\uE973"+ - "\uE974\uE975\uE976\uE977\uE978\uE979\uE97A\uE97B"+ - "\uE97C\uE97D\uE97E\uE980\uE981\uE982\uE983\uE984"+ - "\uE985\uE986\uE987\uE988\uE989\uE98A\uE98B\uE98C"+ - "\uE98D\uE98E\uE98F\uE990\uE991\uE992\uE993\uE994"+ - "\uE995\uE996\uE997\uE998\uE999\uE99A\uE99B\uE99C"+ - "\uE99D\uE99E\uE99F\uE9A0\uEA40\uEA41\uEA42\uEA43"+ - "\uEA44\uEA45\uEA46\uEA47\uEA48\uEA49\uEA4A\uEA4B"+ - "\uEA4C\uEA4D\uEA4E\uEA4F\uEA50\uEA51\uEA52\uEA53"+ - "\uEA54\uEA55\uEA56\uEA57\uEA58\uEA59\uEA5A\uEA5B"+ - "\uC3C5\uE3C5\uC9C1\uE3C6\uEA5C\uB1D5\uCECA\uB4B3"+ - "\uC8F2\uE3C7\uCFD0\uE3C8\uBCE4\uE3C9\uE3CA\uC3C6"+ - "\uD5A2\uC4D6\uB9EB\uCEC5\uE3CB\uC3F6\uE3CC\uEA5D"+ - "\uB7A7\uB8F3\uBAD2\uE3CD\uE3CE\uD4C4\uE3CF\uEA5E"+ - "\uE3D0\uD1CB\uE3D1\uE3D2\uE3D3\uE3D4\uD1D6\uE3D5"+ - "\uB2FB\uC0BB\uE3D6\uEA5F\uC0AB\uE3D7\uE3D8\uE3D9"+ - "\uEA60\uE3DA\uE3DB\uEA61\uB8B7\uDAE2\uEA62\uB6D3"+ - "\uEA63\uDAE4\uDAE3\uEA64\uEA65\uEA66\uEA67\uEA68"+ - "\uEA69\uEA6A\uDAE6\uEA6B\uEA6C\uEA6D\uC8EE\uEA6E"+ - "\uEA6F\uDAE5\uB7C0\uD1F4\uD2F5\uD5F3\uBDD7\uEA70"+ - "\uEA71\uEA72\uEA73\uD7E8\uDAE8\uDAE7\uEA74\uB0A2"+ - "\uCDD3\uEA75\uDAE9\uEA76\uB8BD\uBCCA\uC2BD\uC2A4"+ - "\uB3C2\uDAEA\uEA77\uC2AA\uC4B0\uBDB5\uEA78\uEA79"+ - "\uCFDE\uEA7A\uEA7B\uEA7C\uDAEB\uC9C2\uEA7D\uEA7E"+ - "\uEA80\uEA81\uEA82\uB1DD\uEA83\uEA84\uEA85\uDAEC"+ - "\uEA86\uB6B8\uD4BA\uEA87\uB3FD\uEA88\uEA89\uDAED"+ - "\uD4C9\uCFD5\uC5E3\uEA8A\uDAEE\uEA8B\uEA8C\uEA8D"+ - "\uEA8E\uEA8F\uDAEF\uEA90\uDAF0\uC1EA\uCCD5\uCFDD"+ - "\uEA91\uEA92\uEA93\uEA94\uEA95\uEA96\uEA97\uEA98"+ - "\uEA99\uEA9A\uEA9B\uEA9C\uEA9D\uD3E7\uC2A1\uEA9E"+ - "\uDAF1\uEA9F\uEAA0\uCBE5\uEB40\uDAF2\uEB41\uCBE6"+ - "\uD2FE\uEB42\uEB43\uEB44\uB8F4\uEB45\uEB46\uDAF3"+ - "\uB0AF\uCFB6\uEB47\uEB48\uD5CF\uEB49\uEB4A\uEB4B"+ - "\uEB4C\uEB4D\uEB4E\uEB4F\uEB50\uEB51\uEB52\uCBED"+ - "\uEB53\uEB54\uEB55\uEB56\uEB57\uEB58\uEB59\uEB5A"+ - "\uDAF4\uEB5B\uEB5C\uE3C4\uEB5D\uEB5E\uC1A5\uEB5F"+ - "\uEB60\uF6BF\uEB61\uEB62\uF6C0\uF6C1\uC4D1\uEB63"+ - "\uC8B8\uD1E3\uEB64\uEB65\uD0DB\uD1C5\uBCAF\uB9CD"+ - "\uEB66\uEFF4\uEB67\uEB68\uB4C6\uD3BA\uF6C2\uB3FB"+ - "\uEB69\uEB6A\uF6C3\uEB6B\uEB6C\uB5F1\uEB6D\uEB6E"+ - "\uEB6F\uEB70\uEB71\uEB72\uEB73\uEB74\uEB75\uEB76"+ - "\uF6C5\uEB77\uEB78\uEB79\uEB7A\uEB7B\uEB7C\uEB7D"+ - "\uD3EA\uF6A7\uD1A9\uEB7E\uEB80\uEB81\uEB82\uF6A9"+ - "\uEB83\uEB84\uEB85\uF6A8\uEB86\uEB87\uC1E3\uC0D7"+ - "\uEB88\uB1A2\uEB89\uEB8A\uEB8B\uEB8C\uCEED\uEB8D"+ - "\uD0E8\uF6AB\uEB8E\uEB8F\uCFF6\uEB90\uF6AA\uD5F0"+ - "\uF6AC\uC3B9\uEB91\uEB92\uEB93\uBBF4\uF6AE\uF6AD"+ - "\uEB94\uEB95\uEB96\uC4DE\uEB97\uEB98\uC1D8\uEB99"+ - "\uEB9A\uEB9B\uEB9C\uEB9D\uCBAA\uEB9E\uCFBC\uEB9F"+ - "\uEBA0\uEC40\uEC41\uEC42\uEC43\uEC44\uEC45\uEC46"+ - "\uEC47\uEC48\uF6AF\uEC49\uEC4A\uF6B0\uEC4B\uEC4C"+ - "\uF6B1\uEC4D\uC2B6\uEC4E\uEC4F\uEC50\uEC51\uEC52"+ - "\uB0D4\uC5F9\uEC53\uEC54\uEC55\uEC56\uF6B2\uEC57"+ - "\uEC58\uEC59\uEC5A\uEC5B\uEC5C\uEC5D\uEC5E\uEC5F"+ - "\uEC60\uEC61\uEC62\uEC63\uEC64\uEC65\uEC66\uEC67"+ - "\uEC68\uEC69\uC7E0\uF6A6\uEC6A\uEC6B\uBEB8\uEC6C"+ - "\uEC6D\uBEB2\uEC6E\uB5E5\uEC6F\uEC70\uB7C7\uEC71"+ - "\uBFBF\uC3D2\uC3E6\uEC72\uEC73\uD8CC\uEC74\uEC75"+ - "\uEC76\uB8EF\uEC77\uEC78\uEC79\uEC7A\uEC7B\uEC7C"+ - "\uEC7D\uEC7E\uEC80\uBDF9\uD1A5\uEC81\uB0D0\uEC82"+ - "\uEC83\uEC84\uEC85\uEC86\uF7B0\uEC87\uEC88\uEC89"+ - "\uEC8A\uEC8B\uEC8C\uEC8D\uEC8E\uF7B1\uEC8F\uEC90"+ - "\uEC91\uEC92\uEC93\uD0AC\uEC94\uB0B0\uEC95\uEC96"+ - "\uEC97\uF7B2\uF7B3\uEC98\uF7B4\uEC99\uEC9A\uEC9B"+ - "\uC7CA\uEC9C\uEC9D\uEC9E\uEC9F\uECA0\uED40\uED41"+ - "\uBECF\uED42\uED43\uF7B7\uED44\uED45\uED46\uED47"+ - "\uED48\uED49\uED4A\uF7B6\uED4B\uB1DE\uED4C\uF7B5"+ - "\uED4D\uED4E\uF7B8\uED4F\uF7B9\uED50\uED51\uED52"+ - "\uED53\uED54\uED55\uED56\uED57\uED58\uED59\uED5A"+ - "\uED5B\uED5C\uED5D\uED5E\uED5F\uED60\uED61\uED62"+ - "\uED63\uED64\uED65\uED66\uED67\uED68\uED69\uED6A"+ - "\uED6B\uED6C\uED6D\uED6E\uED6F\uED70\uED71\uED72"+ - "\uED73\uED74\uED75\uED76\uED77\uED78\uED79\uED7A"+ - "\uED7B\uED7C\uED7D\uED7E\uED80\uED81\uCEA4\uC8CD"+ - "\uED82\uBAAB\uE8B8\uE8B9\uE8BA\uBEC2\uED83\uED84"+ - "\uED85\uED86\uED87\uD2F4\uED88\uD4CF\uC9D8\uED89"+ - "\uED8A\uED8B\uED8C\uED8D\uED8E\uED8F\uED90\uED91"+ - "\uED92\uED93\uED94\uED95\uED96\uED97\uED98\uED99"+ - "\uED9A\uED9B\uED9C\uED9D\uED9E\uED9F\uEDA0\uEE40"+ - "\uEE41\uEE42\uEE43\uEE44\uEE45\uEE46\uEE47\uEE48"+ - "\uEE49\uEE4A\uEE4B\uEE4C\uEE4D\uEE4E\uEE4F\uEE50"+ - "\uEE51\uEE52\uEE53\uEE54\uEE55\uEE56\uEE57\uEE58"+ - "\uEE59\uEE5A\uEE5B\uEE5C\uEE5D\uEE5E\uEE5F\uEE60"+ - "\uEE61\uEE62\uEE63\uEE64\uEE65\uEE66\uEE67\uEE68"+ - "\uEE69\uEE6A\uEE6B\uEE6C\uEE6D\uEE6E\uEE6F\uEE70"+ - "\uEE71\uEE72\uEE73\uEE74\uEE75\uEE76\uEE77\uEE78"+ - "\uEE79\uEE7A\uEE7B\uEE7C\uEE7D\uEE7E\uEE80\uEE81"+ - "\uEE82\uEE83\uEE84\uEE85\uEE86\uEE87\uEE88\uEE89"+ - "\uEE8A\uEE8B\uEE8C\uEE8D\uEE8E\uEE8F\uEE90\uEE91"+ - "\uEE92\uEE93\uEE94\uEE95\uEE96\uEE97\uEE98\uEE99"+ - "\uEE9A\uEE9B\uEE9C\uEE9D\uEE9E\uEE9F\uEEA0\uEF40"+ - "\uEF41\uEF42\uEF43\uEF44\uEF45\uD2B3\uB6A5\uC7EA"+ - "\uF1FC\uCFEE\uCBB3\uD0EB\uE7EF\uCDE7\uB9CB\uB6D9"+ - "\uF1FD\uB0E4\uCBCC\uF1FE\uD4A4\uC2AD\uC1EC\uC6C4"+ - "\uBEB1\uF2A1\uBCD5\uEF46\uF2A2\uF2A3\uEF47\uF2A4"+ - "\uD2C3\uC6B5\uEF48\uCDC7\uF2A5\uEF49\uD3B1\uBFC5"+ - "\uCCE2\uEF4A\uF2A6\uF2A7\uD1D5\uB6EE\uF2A8\uF2A9"+ - "\uB5DF\uF2AA\uF2AB\uEF4B\uB2FC\uF2AC\uF2AD\uC8A7"+ - "\uEF4C\uEF4D\uEF4E\uEF4F\uEF50\uEF51\uEF52\uEF53"+ - "\uEF54\uEF55\uEF56\uEF57\uEF58\uEF59\uEF5A\uEF5B"+ - "\uEF5C\uEF5D\uEF5E\uEF5F\uEF60\uEF61\uEF62\uEF63"+ - "\uEF64\uEF65\uEF66\uEF67\uEF68\uEF69\uEF6A\uEF6B"+ - "\uEF6C\uEF6D\uEF6E\uEF6F\uEF70\uEF71\uB7E7\uEF72"+ - "\uEF73\uECA9\uECAA\uECAB\uEF74\uECAC\uEF75\uEF76"+ - "\uC6AE\uECAD\uECAE\uEF77\uEF78\uEF79\uB7C9\uCAB3"+ - "\uEF7A\uEF7B\uEF7C\uEF7D\uEF7E\uEF80\uEF81\uE2B8"+ - "\uF7CF\uEF82\uEF83\uEF84\uEF85\uEF86\uEF87\uEF88"+ - "\uEF89\uEF8A\uEF8B\uEF8C\uEF8D\uEF8E\uEF8F\uEF90"+ - "\uEF91\uEF92\uEF93\uEF94\uEF95\uEF96\uEF97\uEF98"+ - "\uEF99\uEF9A\uEF9B\uEF9C\uEF9D\uEF9E\uEF9F\uEFA0"+ - "\uF040\uF041\uF042\uF043\uF044\uF7D0\uF045\uF046"+ - "\uB2CD\uF047\uF048\uF049\uF04A\uF04B\uF04C\uF04D"+ - "\uF04E\uF04F\uF050\uF051\uF052\uF053\uF054\uF055"+ - "\uF056\uF057\uF058\uF059\uF05A\uF05B\uF05C\uF05D"+ - "\uF05E\uF05F\uF060\uF061\uF062\uF063\uF7D1\uF064"+ - "\uF065\uF066\uF067\uF068\uF069\uF06A\uF06B\uF06C"+ - "\uF06D\uF06E\uF06F\uF070\uF071\uF072\uF073\uF074"+ - "\uF075\uF076\uF077\uF078\uF079\uF07A\uF07B\uF07C"+ - "\uF07D\uF07E\uF080\uF081\uF082\uF083\uF084\uF085"+ - "\uF086\uF087\uF088\uF089\uF7D3\uF7D2\uF08A\uF08B"+ - "\uF08C\uF08D\uF08E\uF08F\uF090\uF091\uF092\uF093"+ - "\uF094\uF095\uF096\uE2BB\uF097\uBCA2\uF098\uE2BC"+ - "\uE2BD\uE2BE\uE2BF\uE2C0\uE2C1\uB7B9\uD2FB\uBDA4"+ - "\uCACE\uB1A5\uCBC7\uF099\uE2C2\uB6FC\uC8C4\uE2C3"+ - "\uF09A\uF09B\uBDC8\uF09C\uB1FD\uE2C4\uF09D\uB6F6"+ - "\uE2C5\uC4D9\uF09E\uF09F\uE2C6\uCFDA\uB9DD\uE2C7"+ - "\uC0A1\uF0A0\uE2C8\uB2F6\uF140\uE2C9\uF141\uC1F3"+ - "\uE2CA\uE2CB\uC2F8\uE2CC\uE2CD\uE2CE\uCAD7\uD8B8"+ - "\uD9E5\uCFE3\uF142\uF143\uF144\uF145\uF146\uF147"+ - "\uF148\uF149\uF14A\uF14B\uF14C\uF0A5\uF14D\uF14E"+ - "\uDCB0\uF14F\uF150\uF151\uF152\uF153\uF154\uF155"+ - "\uF156\uF157\uF158\uF159\uF15A\uF15B\uF15C\uF15D"+ - "\uF15E\uF15F\uF160\uF161\uF162\uF163\uF164\uF165"+ - "\uF166\uF167\uF168\uF169\uF16A\uF16B\uF16C\uF16D"+ - "\uF16E\uF16F\uF170\uF171\uF172\uF173\uF174\uF175"+ - "\uF176\uF177\uF178\uF179\uF17A\uF17B\uF17C\uF17D"+ - "\uF17E\uF180\uF181\uF182\uF183\uF184\uF185\uF186"+ - "\uF187\uF188\uF189\uF18A\uF18B\uF18C\uF18D\uF18E"+ - "\uF18F\uF190\uF191\uF192\uF193\uF194\uF195\uF196"+ - "\uF197\uF198\uF199\uF19A\uF19B\uF19C\uF19D\uF19E"+ - "\uF19F\uF1A0\uF240\uF241\uF242\uF243\uF244\uF245"+ - "\uF246\uF247\uF248\uF249\uF24A\uF24B\uF24C\uF24D"+ - "\uF24E\uF24F\uF250\uF251\uF252\uF253\uF254\uF255"+ - "\uF256\uF257\uF258\uF259\uF25A\uF25B\uF25C\uF25D"+ - "\uF25E\uF25F\uF260\uF261\uF262\uF263\uF264\uF265"+ - "\uF266\uF267\uF268\uF269\uF26A\uF26B\uF26C\uF26D"+ - "\uF26E\uF26F\uF270\uF271\uF272\uF273\uF274\uF275"+ - "\uF276\uF277\uF278\uF279\uF27A\uF27B\uF27C\uF27D"+ - "\uF27E\uF280\uF281\uF282\uF283\uF284\uF285\uF286"+ - "\uF287\uF288\uF289\uF28A\uF28B\uF28C\uF28D\uF28E"+ - "\uF28F\uF290\uF291\uF292\uF293\uF294\uF295\uF296"+ - "\uF297\uF298\uF299\uF29A\uF29B\uF29C\uF29D\uF29E"+ - "\uF29F\uF2A0\uF340\uF341\uF342\uF343\uF344\uF345"+ - "\uF346\uF347\uF348\uF349\uF34A\uF34B\uF34C\uF34D"+ - "\uF34E\uF34F\uF350\uF351\uC2ED\uD4A6\uCDD4\uD1B1"+ - "\uB3DB\uC7FD\uF352\uB2B5\uC2BF\uE6E0\uCABB\uE6E1"+ - "\uE6E2\uBED4\uE6E3\uD7A4\uCDD5\uE6E5\uBCDD\uE6E4"+ - "\uE6E6\uE6E7\uC2EE\uF353\uBDBE\uE6E8\uC2E6\uBAA7"+ - "\uE6E9\uF354\uE6EA\uB3D2\uD1E9\uF355\uF356\uBFA5"+ - "\uE6EB\uC6EF\uE6EC\uE6ED\uF357\uF358\uE6EE\uC6AD"+ - "\uE6EF\uF359\uC9A7\uE6F0\uE6F1\uE6F2\uE5B9\uE6F3"+ - "\uE6F4\uC2E2\uE6F5\uE6F6\uD6E8\uE6F7\uF35A\uE6F8"+ - "\uB9C7\uF35B\uF35C\uF35D\uF35E\uF35F\uF360\uF361"+ - "\uF7BB\uF7BA\uF362\uF363\uF364\uF365\uF7BE\uF7BC"+ - "\uBAA1\uF366\uF7BF\uF367\uF7C0\uF368\uF369\uF36A"+ - "\uF7C2\uF7C1\uF7C4\uF36B\uF36C\uF7C3\uF36D\uF36E"+ - "\uF36F\uF370\uF371\uF7C5\uF7C6\uF372\uF373\uF374"+ - "\uF375\uF7C7\uF376\uCBE8\uF377\uF378\uF379\uF37A"+ - "\uB8DF\uF37B\uF37C\uF37D\uF37E\uF380\uF381\uF7D4"+ - "\uF382\uF7D5\uF383\uF384\uF385\uF386\uF7D6\uF387"+ - "\uF388\uF389\uF38A\uF7D8\uF38B\uF7DA\uF38C\uF7D7"+ - "\uF38D\uF38E\uF38F\uF390\uF391\uF392\uF393\uF394"+ - "\uF395\uF7DB\uF396\uF7D9\uF397\uF398\uF399\uF39A"+ - "\uF39B\uF39C\uF39D\uD7D7\uF39E\uF39F\uF3A0\uF440"+ - "\uF7DC\uF441\uF442\uF443\uF444\uF445\uF446\uF7DD"+ - "\uF447\uF448\uF449\uF7DE\uF44A\uF44B\uF44C\uF44D"+ - "\uF44E\uF44F\uF450\uF451\uF452\uF453\uF454\uF7DF"+ - "\uF455\uF456\uF457\uF7E0\uF458\uF459\uF45A\uF45B"+ - "\uF45C\uF45D\uF45E\uF45F\uF460\uF461\uF462\uDBCB"+ - "\uF463\uF464\uD8AA\uF465\uF466\uF467\uF468\uF469"+ - "\uF46A\uF46B\uF46C\uE5F7\uB9ED\uF46D\uF46E\uF46F"+ - "\uF470\uBFFD\uBBEA\uF7C9\uC6C7\uF7C8\uF471\uF7CA"+ - "\uF7CC\uF7CB\uF472\uF473\uF474\uF7CD\uF475\uCEBA"+ - "\uF476\uF7CE\uF477\uF478\uC4A7\uF479\uF47A\uF47B"+ - "\uF47C\uF47D\uF47E\uF480\uF481\uF482\uF483\uF484"+ - "\uF485\uF486\uF487\uF488\uF489\uF48A\uF48B\uF48C"+ - "\uF48D\uF48E\uF48F\uF490\uF491\uF492\uF493\uF494"+ - "\uF495\uF496\uF497\uF498\uF499\uF49A\uF49B\uF49C"+ - "\uF49D\uF49E\uF49F\uF4A0\uF540\uF541\uF542\uF543"+ - "\uF544\uF545\uF546\uF547\uF548\uF549\uF54A\uF54B"+ - "\uF54C\uF54D\uF54E\uF54F\uF550\uF551\uF552\uF553"+ - "\uF554\uF555\uF556\uF557\uF558\uF559\uF55A\uF55B"+ - "\uF55C\uF55D\uF55E\uF55F\uF560\uF561\uF562\uF563"+ - "\uF564\uF565\uF566\uF567\uF568\uF569\uF56A\uF56B"+ - "\uF56C\uF56D\uF56E\uF56F\uF570\uF571\uF572\uF573"+ - "\uF574\uF575\uF576\uF577\uF578\uF579\uF57A\uF57B"+ - "\uF57C\uF57D\uF57E\uF580\uF581\uF582\uF583\uF584"+ - "\uF585\uF586\uF587\uF588\uF589\uF58A\uF58B\uF58C"+ - "\uF58D\uF58E\uF58F\uF590\uF591\uF592\uF593\uF594"+ - "\uF595\uF596\uF597\uF598\uF599\uF59A\uF59B\uF59C"+ - "\uF59D\uF59E\uF59F\uF5A0\uF640\uF641\uF642\uF643"+ - "\uF644\uF645\uF646\uF647\uF648\uF649\uF64A\uF64B"+ - "\uF64C\uF64D\uF64E\uF64F\uF650\uF651\uF652\uF653"+ - "\uF654\uF655\uF656\uF657\uF658\uF659\uF65A\uF65B"+ - "\uF65C\uF65D\uF65E\uF65F\uF660\uF661\uF662\uF663"+ - "\uF664\uF665\uF666\uF667\uF668\uF669\uF66A\uF66B"+ - "\uF66C\uF66D\uF66E\uF66F\uF670\uF671\uF672\uF673"+ - "\uF674\uF675\uF676\uF677\uF678\uF679\uF67A\uF67B"+ - "\uF67C\uF67D\uF67E\uF680\uF681\uF682\uF683\uF684"+ - "\uF685\uF686\uF687\uF688\uF689\uF68A\uF68B\uF68C"+ - "\uF68D\uF68E\uF68F\uF690\uF691\uF692\uF693\uF694"+ - "\uF695\uF696\uF697\uF698\uF699\uF69A\uF69B\uF69C"+ - "\uF69D\uF69E\uF69F\uF6A0\uF740\uF741\uF742\uF743"+ - "\uF744\uF745\uF746\uF747\uF748\uF749\uF74A\uF74B"+ - "\uF74C\uF74D\uF74E\uF74F\uF750\uF751\uF752\uF753"+ - "\uF754\uF755\uF756\uF757\uF758\uF759\uF75A\uF75B"+ - "\uF75C\uF75D\uF75E\uF75F\uF760\uF761\uF762\uF763"+ - "\uF764\uF765\uF766\uF767\uF768\uF769\uF76A\uF76B"+ - "\uF76C\uF76D\uF76E\uF76F\uF770\uF771\uF772\uF773"+ - "\uF774\uF775\uF776\uF777\uF778\uF779\uF77A\uF77B"+ - "\uF77C\uF77D\uF77E\uF780\uD3E3\uF781\uF782\uF6CF"+ - "\uF783\uC2B3\uF6D0\uF784\uF785\uF6D1\uF6D2\uF6D3"+ - "\uF6D4\uF786\uF787\uF6D6\uF788\uB1AB\uF6D7\uF789"+ - "\uF6D8\uF6D9\uF6DA\uF78A\uF6DB\uF6DC\uF78B\uF78C"+ - "\uF78D\uF78E\uF6DD\uF6DE\uCFCA\uF78F\uF6DF\uF6E0"+ - "\uF6E1\uF6E2\uF6E3\uF6E4\uC0F0\uF6E5\uF6E6\uF6E7"+ - "\uF6E8\uF6E9\uF790\uF6EA\uF791\uF6EB\uF6EC\uF792"+ - "\uF6ED\uF6EE\uF6EF\uF6F0\uF6F1\uF6F2\uF6F3\uF6F4"+ - "\uBEA8\uF793\uF6F5\uF6F6\uF6F7\uF6F8\uF794\uF795"+ - "\uF796\uF797\uF798\uC8FA\uF6F9\uF6FA\uF6FB\uF6FC"+ - "\uF799\uF79A\uF6FD\uF6FE\uF7A1\uF7A2\uF7A3\uF7A4"+ - "\uF7A5\uF79B\uF79C\uF7A6\uF7A7\uF7A8\uB1EE\uF7A9"+ - "\uF7AA\uF7AB\uF79D\uF79E\uF7AC\uF7AD\uC1DB\uF7AE"+ - "\uF79F\uF7A0\uF7AF\uF840\uF841\uF842\uF843\uF844"+ - "\uF845\uF846\uF847\uF848\uF849\uF84A\uF84B\uF84C"+ - "\uF84D\uF84E\uF84F\uF850\uF851\uF852\uF853\uF854"+ - "\uF855\uF856\uF857\uF858\uF859\uF85A\uF85B\uF85C"+ - "\uF85D\uF85E\uF85F\uF860\uF861\uF862\uF863\uF864"+ - "\uF865\uF866\uF867\uF868\uF869\uF86A\uF86B\uF86C"+ - "\uF86D\uF86E\uF86F\uF870\uF871\uF872\uF873\uF874"+ - "\uF875\uF876\uF877\uF878\uF879\uF87A\uF87B\uF87C"+ - "\uF87D\uF87E\uF880\uF881\uF882\uF883\uF884\uF885"+ - "\uF886\uF887\uF888\uF889\uF88A\uF88B\uF88C\uF88D"+ - "\uF88E\uF88F\uF890\uF891\uF892\uF893\uF894\uF895"+ - "\uF896\uF897\uF898\uF899\uF89A\uF89B\uF89C\uF89D"+ - "\uF89E\uF89F\uF8A0\uF940\uF941\uF942\uF943\uF944"+ - "\uF945\uF946\uF947\uF948\uF949\uF94A\uF94B\uF94C"+ - "\uF94D\uF94E\uF94F\uF950\uF951\uF952\uF953\uF954"+ - "\uF955\uF956\uF957\uF958\uF959\uF95A\uF95B\uF95C"+ - "\uF95D\uF95E\uF95F\uF960\uF961\uF962\uF963\uF964"+ - "\uF965\uF966\uF967\uF968\uF969\uF96A\uF96B\uF96C"+ - "\uF96D\uF96E\uF96F\uF970\uF971\uF972\uF973\uF974"+ - "\uF975\uF976\uF977\uF978\uF979\uF97A\uF97B\uF97C"+ - "\uF97D\uF97E\uF980\uF981\uF982\uF983\uF984\uF985"+ - "\uF986\uF987\uF988\uF989\uF98A\uF98B\uF98C\uF98D"+ - "\uF98E\uF98F\uF990\uF991\uF992\uF993\uF994\uF995"+ - "\uF996\uF997\uF998\uF999\uF99A\uF99B\uF99C\uF99D"+ - "\uF99E\uF99F\uF9A0\uFA40\uFA41\uFA42\uFA43\uFA44"+ - "\uFA45\uFA46\uFA47\uFA48\uFA49\uFA4A\uFA4B\uFA4C"+ - "\uFA4D\uFA4E\uFA4F\uFA50\uFA51\uFA52\uFA53\uFA54"+ - "\uFA55\uFA56\uFA57\uFA58\uFA59\uFA5A\uFA5B\uFA5C"+ - "\uFA5D\uFA5E\uFA5F\uFA60\uFA61\uFA62\uFA63\uFA64"+ - "\uFA65\uFA66\uFA67\uFA68\uFA69\uFA6A\uFA6B\uFA6C"+ - "\uFA6D\uFA6E\uFA6F\uFA70\uFA71\uFA72\uFA73\uFA74"+ - "\uFA75\uFA76\uFA77\uFA78\uFA79\uFA7A\uFA7B\uFA7C"+ - "\uFA7D\uFA7E\uFA80\uFA81\uFA82\uFA83\uFA84\uFA85"+ - "\uFA86\uFA87\uFA88\uFA89\uFA8A\uFA8B\uFA8C\uFA8D"+ - "\uFA8E\uFA8F\uFA90\uFA91\uFA92\uFA93\uFA94\uFA95"+ - "\uFA96\uFA97\uFA98\uFA99\uFA9A\uFA9B\uFA9C\uFA9D"+ - "\uFA9E\uFA9F\uFAA0\uFB40\uFB41\uFB42\uFB43\uFB44"+ - "\uFB45\uFB46\uFB47\uFB48\uFB49\uFB4A\uFB4B\uFB4C"+ - "\uFB4D\uFB4E\uFB4F\uFB50\uFB51\uFB52\uFB53\uFB54"+ - "\uFB55\uFB56\uFB57\uFB58\uFB59\uFB5A\uFB5B\uC4F1"+ - "\uF0AF\uBCA6\uF0B0\uC3F9\uFB5C\uC5B8\uD1BB\uFB5D"+ - "\uF0B1\uF0B2\uF0B3\uF0B4\uF0B5\uD1BC\uFB5E\uD1EC"+ - "\uFB5F\uF0B7\uF0B6\uD4A7\uFB60\uCDD2\uF0B8\uF0BA"+ - "\uF0B9\uF0BB\uF0BC\uFB61\uFB62\uB8EB\uF0BD\uBAE8"+ - "\uFB63\uF0BE\uF0BF\uBEE9\uF0C0\uB6EC\uF0C1\uF0C2"+ - "\uF0C3\uF0C4\uC8B5\uF0C5\uF0C6\uFB64\uF0C7\uC5F4"+ - "\uFB65\uF0C8\uFB66\uFB67\uFB68\uF0C9\uFB69\uF0CA"+ - "\uF7BD\uFB6A\uF0CB\uF0CC\uF0CD\uFB6B\uF0CE\uFB6C"+ - "\uFB6D\uFB6E\uFB6F\uF0CF\uBAD7\uFB70\uF0D0\uF0D1"+ - "\uF0D2\uF0D3\uF0D4\uF0D5\uF0D6\uF0D8\uFB71\uFB72"+ - "\uD3A5\uF0D7\uFB73\uF0D9\uFB74\uFB75\uFB76\uFB77"+ - "\uFB78\uFB79\uFB7A\uFB7B\uFB7C\uFB7D\uF5BA\uC2B9"+ - "\uFB7E\uFB80\uF7E4\uFB81\uFB82\uFB83\uFB84\uF7E5"+ - "\uF7E6\uFB85\uFB86\uF7E7\uFB87\uFB88\uFB89\uFB8A"+ - "\uFB8B\uFB8C\uF7E8\uC2B4\uFB8D\uFB8E\uFB8F\uFB90"+ - "\uFB91\uFB92\uFB93\uFB94\uFB95\uF7EA\uFB96\uF7EB"+ - "\uFB97\uFB98\uFB99\uFB9A\uFB9B\uFB9C\uC2F3\uFB9D"+ - "\uFB9E\uFB9F\uFBA0\uFC40\uFC41\uFC42\uFC43\uFC44"+ - "\uFC45\uFC46\uFC47\uFC48\uF4F0\uFC49\uFC4A\uFC4B"+ - "\uF4EF\uFC4C\uFC4D\uC2E9\uFC4E\uF7E1\uF7E2\uFC4F"+ - "\uFC50\uFC51\uFC52\uFC53\uBBC6\uFC54\uFC55\uFC56"+ - "\uFC57\uD9E4\uFC58\uFC59\uFC5A\uCAF2\uC0E8\uF0A4"+ - "\uFC5B\uBADA\uFC5C\uFC5D\uC7AD\uFC5E\uFC5F\uFC60"+ - "\uC4AC\uFC61\uFC62\uF7EC\uF7ED\uF7EE\uFC63\uF7F0"+ - "\uF7EF\uFC64\uF7F1\uFC65\uFC66\uF7F4\uFC67\uF7F3"+ - "\uFC68\uF7F2\uF7F5\uFC69\uFC6A\uFC6B\uFC6C\uF7F6"+ - "\uFC6D\uFC6E\uFC6F\uFC70\uFC71\uFC72\uFC73\uFC74"+ - "\uFC75\uEDE9\uFC76\uEDEA\uEDEB\uFC77\uF6BC\uFC78"+ - "\uFC79\uFC7A\uFC7B\uFC7C\uFC7D\uFC7E\uFC80\uFC81"+ - "\uFC82\uFC83\uFC84\uF6BD\uFC85\uF6BE\uB6A6\uFC86"+ - "\uD8BE\uFC87\uFC88\uB9C4\uFC89\uFC8A\uFC8B\uD8BB"+ - "\uFC8C\uDCB1\uFC8D\uFC8E\uFC8F\uFC90\uFC91\uFC92"+ - "\uCAF3\uFC93\uF7F7\uFC94\uFC95\uFC96\uFC97\uFC98"+ - "\uFC99\uFC9A\uFC9B\uFC9C\uF7F8\uFC9D\uFC9E\uF7F9"+ - "\uFC9F\uFCA0\uFD40\uFD41\uFD42\uFD43\uFD44\uF7FB"+ - "\uFD45\uF7FA\uFD46\uB1C7\uFD47\uF7FC\uF7FD\uFD48"+ - "\uFD49\uFD4A\uFD4B\uFD4C\uF7FE\uFD4D\uFD4E\uFD4F"+ - "\uFD50\uFD51\uFD52\uFD53\uFD54\uFD55\uFD56\uFD57"+ - "\uC6EB\uECB4\uFD58\uFD59\uFD5A\uFD5B\uFD5C\uFD5D"+ - "\uFD5E\uFD5F\uFD60\uFD61\uFD62\uFD63\uFD64\uFD65"+ - "\uFD66\uFD67\uFD68\uFD69\uFD6A\uFD6B\uFD6C\uFD6D"+ - "\uFD6E\uFD6F\uFD70\uFD71\uFD72\uFD73\uFD74\uFD75"+ - "\uFD76\uFD77\uFD78\uFD79\uFD7A\uFD7B\uFD7C\uFD7D"+ - "\uFD7E\uFD80\uFD81\uFD82\uFD83\uFD84\uFD85\uB3DD"+ - "\uF6B3\uFD86\uFD87\uF6B4\uC1E4\uF6B5\uF6B6\uF6B7"+ - "\uF6B8\uF6B9\uF6BA\uC8A3\uF6BB\uFD88\uFD89\uFD8A"+ - "\uFD8B\uFD8C\uFD8D\uFD8E\uFD8F\uFD90\uFD91\uFD92"+ - "\uFD93\uC1FA\uB9A8\uEDE8\uFD94\uFD95\uFD96\uB9EA"+ - "\uD9DF\uFD97\uFD98\uFD99\uFD9A\uFD9B\u6A63\u6A64"+ - "\u6A65\u6A66\u6A67\u6A68\u6A69\u6A6A\u6A6B\u6A6C"+ - "\u6A6D\u6A6E\u6A6F\u6A70\u6A71\u6A72\u6A73\u6A74"+ - "\u6A75\u6A76\u6A77\u6A78\u6A79\u6A7A\u6A7B\u6A7C"+ - "\u6A7D\u6A7E\u6A7F\u6A80\u6A81\u6A82\u6A83\u6A84"+ - "\u6A85\u6A86\u6A87\u6A88\u6A89\u6A8A\u6A8B\u6A8C"+ - "\u6A8D\u6A8E\u6A8F\u6A90\u6A91\u6A92\u6A93\u6A94"+ - "\u6A95\u6A96\u6A97\u6A98\u6A99\u6A9A\u6A9B\u6A9C"+ - "\u6A9D\u6A9E\u6A9F\u6AA0\u6AA1\u6AA2\u6AA3\u6AA4"+ - "\u6AA5\u6AA6\u6AA7\u6AA8\u6AA9\u6AAA\u6AAB\u6AAC"+ - "\u6AAD\u6AAE\u6AAF\u6AB0\u6AB1\u6AB2\u6AB3\u6AB4"+ - "\u6AB5\u6AB6\u6AB7\u6AB8\u6AB9\u6ABA\u6ABB\u6ABC"; - - private static final String innerEncoderIndex10= - "\u6ABD\u6ABE\u6ABF\u6AC0\u6AC1\u6AC2\u6AC3\u6AC4"+ - "\u6AC5\u6AC6\u6AC7\u6AC8\u6AC9\u6ACA\u6ACB\u6ACC"+ - "\u6ACD\u6ACE\u6ACF\u6AD0\u6AD1\u6AD2\u6AD3\u6AD4"+ - "\u6AD5\u6AD6\u6AD7\u6AD8\u6AD9\u6ADA\u6ADB\u6ADC"+ - "\u6ADD\u6ADE\u6ADF\u6AE0\u6AE1\u6AE2\u6AE3\u6AE4"+ - "\u6AE5\u6AE6\u6AE7\u6AE8\u6AE9\u6AEA\u6AEB\u6AEC"+ - "\u6AED\u6AEE\u6AEF\u6AF0\u6AF1\u6AF2\u6AF3\u6AF4"+ - "\u6AF5\u6AF6\u6AF7\u6AF8\u6AF9\u6AFA\u6AFB\u6AFC"+ - "\u6AFD\u6AFE\u6AFF\u6B00\u6B01\u6B02\u6B03\u6B04"+ - "\u6B05\u6B06\u6B07\u6B08\u6B09\u6B0A\u6B0B\u6B0C"+ - "\u6B0D\u6B0E\u6B0F\u6B10\u6B11\u6B12\u6B13\u6B14"+ - "\u6B15\u6B16\u6B17\u6B18\u6B19\u6B1A\u6B1B\u6B1C"+ - "\u6B1D\u6B1E\u6B1F\u6B20\u6B21\u6B22\u6B23\u6B24"+ - "\u6B25\u6B26\u6B27\u6B28\u6B29\u6B2A\u6B2B\u6B2C"+ - "\u6B2D\u6B2E\u6B2F\u6B30\u6B31\u6B32\u6B33\u6B34"+ - "\u6B35\u6B36\u6B37\u6B38\u6B39\u6B3A\u6B3B\u6B3C"+ - "\u6B3D\u6B3E\u6B3F\u6B40\u6B41\u6B42\u6B43\u6B44"+ - "\u6B45\u6B46\u6B47\u6B48\u6B49\u6B4A\u6B4B\u6B4C"+ - "\u6B4D\u6B4E\u6B4F\u6B50\u6B51\u6B52\u6B53\u6B54"+ - "\u6B55\u6B56\u6B57\u6B58\u6B59\u6B5A\u6B5B\u6B5C"+ - "\u6B5D\u6B5E\u6B5F\u6B60\u6B61\u6B62\u6B63\u6B64"+ - "\u6B65\u6B66\u6B67\u6B68\u6B69\u6B6A\u6B6B\u6B6C"+ - "\u6B6D\u6B6E\u6B6F\u6B70\u6B71\u6B72\u6B73\u6B74"+ - "\u6B75\u6B76\u6B77\u6B78\u6B79\u6B7A\u6B7B\u6B7C"+ - "\u6B7D\u6B7E\u6B7F\u6B80\u6B81\u6B82\u6B83\u6B84"+ - "\u6B85\u6B86\u6B87\u6B88\u6B89\u6B8A\u6B8B\u6B8C"+ - "\u6B8D\u6B8E\u6B8F\u6B90\u6B91\u6B92\u6B93\u6B94"+ - "\u6B95\u6B96\u6B97\u6B98\u6B99\u6B9A\u6B9B\u6B9C"+ - "\u6B9D\u6B9E\u6B9F\u6BA0\u6BA1\u6BA2\u6BA3\u6BA4"+ - "\u6BA5\u6BA6\u6BA7\u6BA8\u6BA9\u6BAA\u6BAB\u6BAC"+ - "\u6BAD\u6BAE\u6BAF\u6BB0\u6BB1\u6BB2\u6BB3\u6BB4"+ - "\u6BB5\u6BB6\u6BB7\u6BB8\u6BB9\u6BBA\u6BBB\u6BBC"+ - "\u6BBD\u6BBE\u6BBF\u6BC0\u6BC1\u6BC2\u6BC3\u6BC4"+ - "\u6BC5\u6BC6\u6BC7\u6BC8\u6BC9\u6BCA\u6BCB\u6BCC"+ - "\u6BCD\u6BCE\u6BCF\u6BD0\u6BD1\u6BD2\u6BD3\u6BD4"+ - "\u6BD5\u6BD6\u6BD7\u6BD8\u6BD9\u6BDA\u6BDB\u6BDC"+ - "\u6BDD\u6BDE\u6BDF\u6BE0\u6BE1\u6BE2\u6BE3\u6BE4"+ - "\u6BE5\u6BE6\u6BE7\u6BE8\u6BE9\u6BEA\u6BEB\u6BEC"+ - "\u6BED\u6BEE\u6BEF\u6BF0\u6BF1\u6BF2\u6BF3\u6BF4"+ - "\u6BF5\u6BF6\u6BF7\u6BF8\u6BF9\u6BFA\u6BFB\u6BFC"+ - "\u6BFD\u6BFE\u6BFF\u6C00\u6C01\u6C02\u6C03\u6C04"+ - "\u6C05\u6C06\u6C07\u6C08\u6C09\u6C0A\u6C0B\u6C0C"+ - "\u6C0D\u6C0E\u6C0F\u6C10\u6C11\u6C12\u6C13\u6C14"+ - "\u6C15\u6C16\u6C17\u6C18\u6C19\u6C1A\u6C1B\u6C1C"+ - "\u6C1D\u6C1E\u6C1F\u6C20\u6C21\u6C22\u6C23\u6C24"+ - "\u6C25\u6C26\u6C27\u6C28\u6C29\u6C2A\u6C2B\u6C2C"+ - "\u6C2D\u6C2E\u6C2F\u6C30\u6C31\u6C32\u6C33\u6C34"+ - "\u6C35\u6C36\u6C37\u6C38\u6C39\u6C3A\u6C3B\u6C3C"+ - "\u6C3D\u6C3E\u6C3F\u6C40\u6C41\u6C42\u6C43\u6C44"+ - "\u6C45\u6C46\u6C47\u6C48\u6C49\u6C4A\u6C4B\u6C4C"+ - "\u6C4D\u6C4E\u6C4F\u6C50\u6C51\u6C52\u6C53\u6C54"+ - "\u6C55\u6C56\u6C57\u6C58\u6C59\u6C5A\u6C5B\u6C5C"+ - "\u6C5D\u6C5E\u6C5F\u6C60\u6C61\u6C62\u6C63\u6C64"+ - "\u6C65\u6C66\u6C67\u6C68\u6C69\u6C6A\u6C6B\u6C6C"+ - "\u6C6D\u6C6E\u6C6F\u6C70\u6C71\u6C72\u6C73\u6C74"+ - "\u6C75\u6C76\u6C77\u6C78\u6C79\u6C7A\u6C7B\u6C7C"+ - "\u6C7D\u6C7E\u6C7F\u6C80\u6C81\u6C82\u6C83\u6C84"+ - "\u6C85\u6C86\u6C87\u6C88\u6C89\u6C8A\u6C8B\u6C8C"+ - "\u6C8D\u6C8E\u6C8F\u6C90\u6C91\u6C92\u6C93\u6C94"+ - "\u6C95\u6C96\u6C97\u6C98\u6C99\u6C9A\u6C9B\u6C9C"+ - "\u6C9D\u6C9E\u6C9F\u6CA0\u6CA1\u6CA2\u6CA3\u6CA4"+ - "\u6CA5\u6CA6\u6CA7\u6CA8\u6CA9\u6CAA\u6CAB\u6CAC"+ - "\u6CAD\u6CAE\u6CAF\u6CB0\u6CB1\u6CB2\u6CB3\u6CB4"+ - "\u6CB5\u6CB6\u6CB7\u6CB8\u6CB9\u6CBA\u6CBB\u6CBC"+ - "\u6CBD\u6CBE\u6CBF\u6CC0\u6CC1\u6CC2\u6CC3\u6CC4"+ - "\u6CC5\u6CC6\u6CC7\u6CC8\u6CC9\u6CCA\u6CCB\u6CCC"+ - "\u6CCD\u6CCE\u6CCF\u6CD0\u6CD1\u6CD2\u6CD3\u6CD4"+ - "\u6CD5\u6CD6\u6CD7\u6CD8\u6CD9\u6CDA\u6CDB\u6CDC"+ - "\u6CDD\u6CDE\u6CDF\u6CE0\u6CE1\u6CE2\u6CE3\u6CE4"+ - "\u6CE5\u6CE6\u6CE7\u6CE8\u6CE9\u6CEA\u6CEB\u6CEC"+ - "\u6CED\u6CEE\u6CEF\u6CF0\u6CF1\u6CF2\u6CF3\u6CF4"+ - "\u6CF5\u6CF6\u6CF7\u6CF8\u6CF9\u6CFA\u6CFB\u6CFC"+ - "\u6CFD\u6CFE\u6CFF\u6D00\u6D01\u6D02\u6D03\u6D04"+ - "\u6D05\u6D06\u6D07\u6D08\u6D09\u6D0A\u6D0B\u6D0C"+ - "\u6D0D\u6D0E\u6D0F\u6D10\u6D11\u6D12\u6D13\u6D14"+ - "\u6D15\u6D16\u6D17\u6D18\u6D19\u6D1A\u6D1B\u6D1C"+ - "\u6D1D\u6D1E\u6D1F\u6D20\u6D21\u6D22\u6D23\u6D24"+ - "\u6D25\u6D26\u6D27\u6D28\u6D29\u6D2A\u6D2B\u6D2C"+ - "\u6D2D\u6D2E\u6D2F\u6D30\u6D31\u6D32\u6D33\u6D34"+ - "\u6D35\u6D36\u6D37\u6D38\u6D39\u6D3A\u6D3B\u6D3C"+ - "\u6D3D\u6D3E\u6D3F\u6D40\u6D41\u6D42\u6D43\u6D44"+ - "\u6D45\u6D46\u6D47\u6D48\u6D49\u6D4A\u6D4B\u6D4C"+ - "\u6D4D\u6D4E\u6D4F\u6D50\u6D51\u6D52\u6D53\u6D54"+ - "\u6D55\u6D56\u6D57\u6D58\u6D59\u6D5A\u6D5B\u6D5C"+ - "\u6D5D\u6D5E\u6D5F\u6D60\u6D61\u6D62\u6D63\u6D64"+ - "\u6D65\u6D66\u6D67\u6D68\u6D69\u6D6A\u6D6B\u6D6C"+ - "\u6D6D\u6D6E\u6D6F\u6D70\u6D71\u6D72\u6D73\u6D74"+ - "\u6D75\u6D76\u6D77\u6D78\u6D79\u6D7A\u6D7B\u6D7C"+ - "\u6D7D\u6D7E\u6D7F\u6D80\u6D81\u6D82\u6D83\u6D84"+ - "\u6D85\u6D86\u6D87\u6D88\u6D89\u6D8A\u6D8B\u6D8C"+ - "\u6D8D\u6D8E\u6D8F\u6D90\u6D91\u6D92\u6D93\u6D94"+ - "\u6D95\u6D96\u6D97\u6D98\u6D99\u6D9A\u6D9B\u6D9C"+ - "\u6D9D\u6D9E\u6D9F\u6DA0\u6DA1\u6DA2\u6DA3\u6DA4"+ - "\u6DA5\u6DA6\u6DA7\u6DA8\u6DA9\u6DAA\u6DAB\u6DAC"+ - "\u6DAD\u6DAE\u6DAF\u6DB0\u6DB1\u6DB2\u6DB3\u6DB4"+ - "\u6DB5\u6DB6\u6DB7\u6DB8\u6DB9\u6DBA\u6DBB\u6DBC"+ - "\u6DBD\u6DBE\u6DBF\u6DC0\u6DC1\u6DC2\u6DC3\u6DC4"+ - "\u6DC5\u6DC6\u6DC7\u6DC8\u6DC9\u6DCA\u6DCB\u6DCC"+ - "\u6DCD\u6DCE\u6DCF\u6DD0\u6DD1\u6DD2\u6DD3\u6DD4"+ - "\u6DD5\u6DD6\u6DD7\u6DD8\u6DD9\u6DDA\u6DDB\u6DDC"+ - "\u6DDD\u6DDE\u6DDF\u6DE0\u6DE1\u6DE2\u6DE3\u6DE4"+ - "\u6DE5\u6DE6\u6DE7\u6DE8\u6DE9\u6DEA\u6DEB\u6DEC"+ - "\u6DED\u6DEE\u6DEF\u6DF0\u6DF1\u6DF2\u6DF3\u6DF4"+ - "\u6DF5\u6DF6\u6DF7\u6DF8\u6DF9\u6DFA\u6DFB\u6DFC"+ - "\u6DFD\u6DFE\u6DFF\u6E00\u6E01\u6E02\u6E03\u6E04"+ - "\u6E05\u6E06\u6E07\u6E08\u6E09\u6E0A\u6E0B\u6E0C"+ - "\u6E0D\u6E0E\u6E0F\u6E10\u6E11\u6E12\u6E13\u6E14"+ - "\u6E15\u6E16\u6E17\u6E18\u6E19\u6E1A\u6E1B\u6E1C"+ - "\u6E1D\u6E1E\u6E1F\u6E20\u6E21\u6E22\u6E23\u6E24"+ - "\u6E25\u6E26\u6E27\u6E28\u6E29\u6E2A\u6E2B\u6E2C"+ - "\u6E2D\u6E2E\u6E2F\u6E30\u6E31\u6E32\u6E33\u6E34"+ - "\u6E35\u6E36\u6E37\u6E38\u6E39\u6E3A\u6E3B\u6E3C"+ - "\u6E3D\u6E3E\u6E3F\u6E40\u6E41\u6E42\u6E43\u6E44"+ - "\u6E45\u6E46\u6E47\u6E48\u6E49\u6E4A\u6E4B\u6E4C"+ - "\u6E4D\u6E4E\u6E4F\u6E50\u6E51\u6E52\u6E53\u6E54"+ - "\u6E55\u6E56\u6E57\u6E58\u6E59\u6E5A\u6E5B\u6E5C"+ - "\u6E5D\u6E5E\u6E5F\u6E60\u6E61\u6E62\u6E63\u6E64"+ - "\u6E65\u6E66\u6E67\u6E68\u6E69\u6E6A\u6E6B\u6E6C"+ - "\u6E6D\u6E6E\u6E6F\u6E70\u6E71\u6E72\u6E73\u6E74"+ - "\u6E75\u6E76\u6E77\u6E78\u6E79\u6E7A\u6E7B\u6E7C"+ - "\u6E7D\u6E7E\u6E7F\u6E80\u6E81\u6E82\u6E83\u6E84"+ - "\u6E85\u6E86\u6E87\u6E88\u6E89\u6E8A\u6E8B\u6E8C"+ - "\u6E8D\u6E8E\u6E8F\u6E90\u6E91\u6E92\u6E93\u6E94"+ - "\u6E95\u6E96\u6E97\u6E98\u6E99\u6E9A\u6E9B\u6E9C"+ - "\u6E9D\u6E9E\u6E9F\u6EA0\u6EA1\u6EA2\u6EA3\u6EA4"+ - "\u6EA5\u6EA6\u6EA7\u6EA8\u6EA9\u6EAA\u6EAB\u6EAC"+ - "\u6EAD\u6EAE\u6EAF\u6EB0\u6EB1\u6EB2\u6EB3\u6EB4"+ - "\u6EB5\u6EB6\u6EB7\u6EB8\u6EB9\u6EBA\u6EBB\u6EBC"+ - "\u6EBD\u6EBE\u6EBF\u6EC0\u6EC1\u6EC2\u6EC3\u6EC4"+ - "\u6EC5\u6EC6\u6EC7\u6EC8\u6EC9\u6ECA\u6ECB\u6ECC"+ - "\u6ECD\u6ECE\u6ECF\u6ED0\u6ED1\u6ED2\u6ED3\u6ED4"+ - "\u6ED5\u6ED6\u6ED7\u6ED8\u6ED9\u6EDA\u6EDB\u6EDC"+ - "\u6EDD\u6EDE\u6EDF\u6EE0\u6EE1\u6EE2\u6EE3\u6EE4"+ - "\u6EE5\u6EE6\u6EE7\u6EE8\u6EE9\u6EEA\u6EEB\u6EEC"+ - "\u6EED\u6EEE\u6EEF\u6EF0\u6EF1\u6EF2\u6EF3\u6EF4"+ - "\u6EF5\u6EF6\u6EF7\u6EF8\u6EF9\u6EFA\u6EFB\u6EFC"+ - "\u6EFD\u6EFE\u6EFF\u6F00\u6F01\u6F02\u6F03\u6F04"+ - "\u6F05\u6F06\u6F07\u6F08\u6F09\u6F0A\u6F0B\u6F0C"+ - "\u6F0D\u6F0E\u6F0F\u6F10\u6F11\u6F12\u6F13\u6F14"+ - "\u6F15\u6F16\u6F17\u6F18\u6F19\u6F1A\u6F1B\u6F1C"+ - "\u6F1D\u6F1E\u6F1F\u6F20\u6F21\u6F22\u6F23\u6F24"+ - "\u6F25\u6F26\u6F27\u6F28\u6F29\u6F2A\u6F2B\u6F2C"+ - "\u6F2D\u6F2E\u6F2F\u6F30\u6F31\u6F32\u6F33\u6F34"+ - "\u6F35\u6F36\u6F37\u6F38\u6F39\u6F3A\u6F3B\u6F3C"+ - "\u6F3D\u6F3E\u6F3F\u6F40\u6F41\u6F42\u6F43\u6F44"+ - "\u6F45\u6F46\u6F47\u6F48\u6F49\u6F4A\u6F4B\u6F4C"+ - "\u6F4D\u6F4E\u6F4F\u6F50\u6F51\u6F52\u6F53\u6F54"+ - "\u6F55\u6F56\u6F57\u6F58\u6F59\u6F5A\u6F5B\u6F5C"+ - "\u6F5D\u6F5E\u6F5F\u6F60\u6F61\u6F62\u6F63\u6F64"+ - "\u6F65\u6F66\u6F67\u6F68\u6F69\u6F6A\u6F6B\u6F6C"+ - "\u6F6D\u6F6E\u6F6F\u6F70\u6F71\u6F72\u6F73\u6F74"+ - "\u6F75\u6F76\u6F77\u6F78\u6F79\u6F7A\u6F7B\u6F7C"+ - "\u6F7D\u6F7E\u6F7F\u6F80\u6F81\u6F82\u6F83\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"+ - "\uAAA1\uAAA2\uAAA3\uAAA4\uAAA5\uAAA6\uAAA7\uAAA8"+ - "\uAAA9\uAAAA\uAAAB\uAAAC\uAAAD\uAAAE\uAAAF\uAAB0"+ - "\uAAB1\uAAB2\uAAB3\uAAB4\uAAB5\uAAB6\uAAB7\uAAB8"+ - "\uAAB9\uAABA\uAABB\uAABC\uAABD\uAABE\uAABF\uAAC0"+ - "\uAAC1\uAAC2\uAAC3\uAAC4\uAAC5\uAAC6\uAAC7\uAAC8"+ - "\uAAC9\uAACA\uAACB\uAACC\uAACD\uAACE\uAACF\uAAD0"+ - "\uAAD1\uAAD2\uAAD3\uAAD4\uAAD5\uAAD6\uAAD7\uAAD8"+ - "\uAAD9\uAADA\uAADB\uAADC\uAADD\uAADE\uAADF\uAAE0"+ - "\uAAE1\uAAE2\uAAE3\uAAE4\uAAE5\uAAE6\uAAE7\uAAE8"+ - "\uAAE9\uAAEA\uAAEB\uAAEC\uAAED\uAAEE\uAAEF\uAAF0"+ - "\uAAF1\uAAF2\uAAF3\uAAF4\uAAF5\uAAF6\uAAF7\uAAF8"+ - "\uAAF9\uAAFA\uAAFB\uAAFC\uAAFD\uAAFE\uABA1\uABA2"+ - "\uABA3\uABA4\uABA5\uABA6\uABA7\uABA8\uABA9\uABAA"+ - "\uABAB\uABAC\uABAD\uABAE\uABAF\uABB0\uABB1\uABB2"+ - "\uABB3\uABB4\uABB5\uABB6\uABB7\uABB8\uABB9\uABBA"+ - "\uABBB\uABBC\uABBD\uABBE\uABBF\uABC0\uABC1\uABC2"+ - "\uABC3\uABC4\uABC5\uABC6\uABC7\uABC8\uABC9\uABCA"+ - "\uABCB\uABCC\uABCD\uABCE\uABCF\uABD0\uABD1\uABD2"+ - "\uABD3\uABD4\uABD5\uABD6\uABD7\uABD8\uABD9\uABDA"+ - "\uABDB\uABDC\uABDD\uABDE\uABDF\uABE0\uABE1\uABE2"+ - "\uABE3\uABE4\uABE5\uABE6\uABE7\uABE8\uABE9\uABEA"+ - "\uABEB\uABEC\uABED\uABEE\uABEF\uABF0\uABF1\uABF2"+ - "\uABF3\uABF4\uABF5\uABF6\uABF7\uABF8\uABF9\uABFA"+ - "\uABFB\uABFC\uABFD\uABFE\uACA1\uACA2\uACA3\uACA4"+ - "\uACA5\uACA6\uACA7\uACA8\uACA9\uACAA\uACAB\uACAC"+ - "\uACAD\uACAE\uACAF\uACB0\uACB1\uACB2\uACB3\uACB4"+ - "\uACB5\uACB6\uACB7\uACB8\uACB9\uACBA\uACBB\uACBC"+ - "\uACBD\uACBE\uACBF\uACC0\uACC1\uACC2\uACC3\uACC4"+ - "\uACC5\uACC6\uACC7\uACC8\uACC9\uACCA\uACCB\uACCC"+ - "\uACCD\uACCE\uACCF\uACD0\uACD1\uACD2\uACD3\uACD4"+ - "\uACD5\uACD6\uACD7\uACD8\uACD9\uACDA\uACDB\uACDC"+ - "\uACDD\uACDE\uACDF\uACE0\uACE1\uACE2\uACE3\uACE4"+ - "\uACE5\uACE6\uACE7\uACE8\uACE9\uACEA\uACEB\uACEC"+ - "\uACED\uACEE\uACEF\uACF0\uACF1\uACF2\uACF3\uACF4"+ - "\uACF5\uACF6\uACF7\uACF8\uACF9\uACFA\uACFB\uACFC"+ - "\uACFD\uACFE\uADA1\uADA2\uADA3\uADA4\uADA5\uADA6"+ - "\uADA7\uADA8\uADA9\uADAA\uADAB\uADAC\uADAD\uADAE"+ - "\uADAF\uADB0\uADB1\uADB2\uADB3\uADB4\uADB5\uADB6"+ - "\uADB7\uADB8\uADB9\uADBA\uADBB\uADBC\uADBD\uADBE"+ - "\uADBF\uADC0\uADC1\uADC2\uADC3\uADC4\uADC5\uADC6"+ - "\uADC7\uADC8\uADC9\uADCA\uADCB\uADCC\uADCD\uADCE"+ - "\uADCF\uADD0\uADD1\uADD2\uADD3\uADD4\uADD5\uADD6"+ - "\uADD7\uADD8\uADD9\uADDA\uADDB\uADDC\uADDD\uADDE"+ - "\uADDF\uADE0\uADE1\uADE2\uADE3\uADE4\uADE5\uADE6"+ - "\uADE7\uADE8\uADE9\uADEA\uADEB\uADEC\uADED\uADEE"+ - "\uADEF\uADF0\uADF1\uADF2\uADF3\uADF4\uADF5\uADF6"+ - "\uADF7\uADF8\uADF9\uADFA\uADFB\uADFC\uADFD\uADFE"+ - "\uAEA1\uAEA2\uAEA3\uAEA4\uAEA5\uAEA6\uAEA7\uAEA8"+ - "\uAEA9\uAEAA\uAEAB\uAEAC\uAEAD\uAEAE\uAEAF\uAEB0"+ - "\uAEB1\uAEB2\uAEB3\uAEB4\uAEB5\uAEB6\uAEB7\uAEB8"+ - "\uAEB9\uAEBA\uAEBB\uAEBC\uAEBD\uAEBE\uAEBF\uAEC0"+ - "\uAEC1\uAEC2\uAEC3\uAEC4\uAEC5\uAEC6\uAEC7\uAEC8"+ - "\uAEC9\uAECA\uAECB\uAECC\uAECD\uAECE\uAECF\uAED0"+ - "\uAED1\uAED2\uAED3\uAED4\uAED5\uAED6\uAED7\uAED8"+ - "\uAED9\uAEDA\uAEDB\uAEDC\uAEDD\uAEDE\uAEDF\uAEE0"+ - "\uAEE1\uAEE2\uAEE3\uAEE4\uAEE5\uAEE6\uAEE7\uAEE8"+ - "\uAEE9\uAEEA\uAEEB\uAEEC\uAEED\uAEEE\uAEEF\uAEF0"+ - "\uAEF1\uAEF2\uAEF3\uAEF4\uAEF5\uAEF6\uAEF7\uAEF8"+ - "\uAEF9\uAEFA\uAEFB\uAEFC\uAEFD\uAEFE\uAFA1\uAFA2"+ - "\uAFA3\uAFA4\uAFA5\uAFA6\uAFA7\uAFA8\uAFA9\uAFAA"+ - "\uAFAB\uAFAC\uAFAD\uAFAE\uAFAF\uAFB0\uAFB1\uAFB2"+ - "\uAFB3\uAFB4\uAFB5\uAFB6\uAFB7\uAFB8\uAFB9\uAFBA"+ - "\uAFBB\uAFBC\uAFBD\uAFBE\uAFBF\uAFC0\uAFC1\uAFC2"+ - "\uAFC3\uAFC4\uAFC5\uAFC6\uAFC7\uAFC8\uAFC9\uAFCA"+ - "\uAFCB\uAFCC\uAFCD\uAFCE\uAFCF\uAFD0\uAFD1\uAFD2"+ - "\uAFD3\uAFD4\uAFD5\uAFD6\uAFD7\uAFD8\uAFD9\uAFDA"+ - "\uAFDB\uAFDC\uAFDD\uAFDE\uAFDF\uAFE0\uAFE1\uAFE2"+ - "\uAFE3\uAFE4\uAFE5\uAFE6\uAFE7\uAFE8\uAFE9\uAFEA"+ - "\uAFEB\uAFEC\uAFED\uAFEE\uAFEF\uAFF0\uAFF1\uAFF2"+ - "\uAFF3\uAFF4\uAFF5\uAFF6\uAFF7\uAFF8\uAFF9\uAFFA"+ - "\uAFFB\uAFFC\uAFFD\uAFFE\uF8A1\uF8A2\uF8A3\uF8A4"+ - "\uF8A5\uF8A6\uF8A7\uF8A8\uF8A9\uF8AA\uF8AB\uF8AC"+ - "\uF8AD\uF8AE\uF8AF\uF8B0\uF8B1\uF8B2\uF8B3\uF8B4"+ - "\uF8B5\uF8B6\uF8B7\uF8B8\uF8B9\uF8BA\uF8BB\uF8BC"+ - "\uF8BD\uF8BE\uF8BF\uF8C0\uF8C1\uF8C2\uF8C3\uF8C4"+ - "\uF8C5\uF8C6\uF8C7\uF8C8\uF8C9\uF8CA\uF8CB\uF8CC"+ - "\uF8CD\uF8CE\uF8CF\uF8D0\uF8D1\uF8D2\uF8D3\uF8D4"+ - "\uF8D5\uF8D6\uF8D7\uF8D8\uF8D9\uF8DA\uF8DB\uF8DC"+ - "\uF8DD\uF8DE\uF8DF\uF8E0\uF8E1\uF8E2\uF8E3\uF8E4"+ - "\uF8E5\uF8E6\uF8E7\uF8E8\uF8E9\uF8EA\uF8EB\uF8EC"+ - "\uF8ED\uF8EE\uF8EF\uF8F0\uF8F1\uF8F2\uF8F3\uF8F4"+ - "\uF8F5\uF8F6\uF8F7\uF8F8\uF8F9\uF8FA\uF8FB\uF8FC"+ - "\uF8FD\uF8FE\uF9A1\uF9A2\uF9A3\uF9A4\uF9A5\uF9A6"+ - "\uF9A7\uF9A8\uF9A9\uF9AA\uF9AB\uF9AC\uF9AD\uF9AE"+ - "\uF9AF\uF9B0\uF9B1\uF9B2\uF9B3\uF9B4\uF9B5\uF9B6"+ - "\uF9B7\uF9B8\uF9B9\uF9BA\uF9BB\uF9BC\uF9BD\uF9BE"+ - "\uF9BF\uF9C0\uF9C1\uF9C2\uF9C3\uF9C4\uF9C5\uF9C6"+ - "\uF9C7\uF9C8\uF9C9\uF9CA\uF9CB\uF9CC\uF9CD\uF9CE"+ - "\uF9CF\uF9D0\uF9D1\uF9D2\uF9D3\uF9D4\uF9D5\uF9D6"+ - "\uF9D7\uF9D8\uF9D9\uF9DA\uF9DB\uF9DC\uF9DD\uF9DE"+ - "\uF9DF\uF9E0\uF9E1\uF9E2\uF9E3\uF9E4\uF9E5\uF9E6"+ - "\uF9E7\uF9E8\uF9E9\uF9EA\uF9EB\uF9EC\uF9ED\uF9EE"+ - "\uF9EF\uF9F0\uF9F1\uF9F2\uF9F3\uF9F4\uF9F5\uF9F6"+ - "\uF9F7\uF9F8\uF9F9\uF9FA\uF9FB\uF9FC\uF9FD\uF9FE"+ - "\uFAA1\uFAA2\uFAA3\uFAA4\uFAA5\uFAA6\uFAA7\uFAA8"+ - "\uFAA9\uFAAA\uFAAB\uFAAC\uFAAD\uFAAE\uFAAF\uFAB0"+ - "\uFAB1\uFAB2\uFAB3\uFAB4\uFAB5\uFAB6\uFAB7\uFAB8"+ - "\uFAB9\uFABA\uFABB\uFABC\uFABD\uFABE\uFABF\uFAC0"+ - "\uFAC1\uFAC2\uFAC3\uFAC4\uFAC5\uFAC6\uFAC7\uFAC8"+ - "\uFAC9\uFACA\uFACB\uFACC\uFACD\uFACE\uFACF\uFAD0"+ - "\uFAD1\uFAD2\uFAD3\uFAD4\uFAD5\uFAD6\uFAD7\uFAD8"+ - "\uFAD9\uFADA\uFADB\uFADC\uFADD\uFADE\uFADF\uFAE0"+ - "\uFAE1\uFAE2\uFAE3\uFAE4\uFAE5\uFAE6\uFAE7\uFAE8"+ - "\uFAE9\uFAEA\uFAEB\uFAEC\uFAED\uFAEE\uFAEF\uFAF0"+ - "\uFAF1\uFAF2\uFAF3\uFAF4\uFAF5\uFAF6\uFAF7\uFAF8"+ - "\uFAF9\uFAFA\uFAFB\uFAFC\uFAFD\uFAFE\uFBA1\uFBA2"+ - "\uFBA3\uFBA4\uFBA5\uFBA6\uFBA7\uFBA8\uFBA9\uFBAA"+ - "\uFBAB\uFBAC\uFBAD\uFBAE\uFBAF\uFBB0\uFBB1\uFBB2"+ - "\uFBB3\uFBB4\uFBB5\uFBB6\uFBB7\uFBB8\uFBB9\uFBBA"+ - "\uFBBB\uFBBC\uFBBD\uFBBE\uFBBF\uFBC0\uFBC1\uFBC2"+ - "\uFBC3\uFBC4\uFBC5\uFBC6\uFBC7\uFBC8\uFBC9\uFBCA"+ - "\uFBCB\uFBCC\uFBCD\uFBCE\uFBCF\uFBD0\uFBD1\uFBD2"+ - "\uFBD3\uFBD4\uFBD5\uFBD6\uFBD7\uFBD8\uFBD9\uFBDA"+ - "\uFBDB\uFBDC\uFBDD\uFBDE\uFBDF\uFBE0\uFBE1\uFBE2"+ - "\uFBE3\uFBE4\uFBE5\uFBE6\uFBE7\uFBE8\uFBE9\uFBEA"+ - "\uFBEB\uFBEC\uFBED\uFBEE\uFBEF\uFBF0\uFBF1\uFBF2"+ - "\uFBF3\uFBF4\uFBF5\uFBF6\uFBF7\uFBF8\uFBF9\uFBFA"+ - "\uFBFB\uFBFC\uFBFD\uFBFE\uFCA1\uFCA2\uFCA3\uFCA4"+ - "\uFCA5\uFCA6\uFCA7\uFCA8\uFCA9\uFCAA\uFCAB\uFCAC"+ - "\uFCAD\uFCAE\uFCAF\uFCB0\uFCB1\uFCB2\uFCB3\uFCB4"+ - "\uFCB5\uFCB6\uFCB7\uFCB8\uFCB9\uFCBA\uFCBB\uFCBC"+ - "\uFCBD\uFCBE\uFCBF\uFCC0\uFCC1\uFCC2\uFCC3\uFCC4"+ - "\uFCC5\uFCC6\uFCC7\uFCC8\uFCC9\uFCCA\uFCCB\uFCCC"+ - "\uFCCD\uFCCE\uFCCF\uFCD0\uFCD1\uFCD2\uFCD3\uFCD4"+ - "\uFCD5\uFCD6\uFCD7\uFCD8\uFCD9\uFCDA\uFCDB\uFCDC"+ - "\uFCDD\uFCDE\uFCDF\uFCE0\uFCE1\uFCE2\uFCE3\uFCE4"+ - "\uFCE5\uFCE6\uFCE7\uFCE8\uFCE9\uFCEA\uFCEB\uFCEC"+ - "\uFCED\uFCEE\uFCEF\uFCF0\uFCF1\uFCF2\uFCF3\uFCF4"+ - "\uFCF5\uFCF6\uFCF7\uFCF8\uFCF9\uFCFA\uFCFB\uFCFC"+ - "\uFCFD\uFCFE\uFDA1\uFDA2\uFDA3\uFDA4\uFDA5\uFDA6"+ - "\uFDA7\uFDA8\uFDA9\uFDAA\uFDAB\uFDAC\uFDAD\uFDAE"+ - "\uFDAF\uFDB0\uFDB1\uFDB2\uFDB3\uFDB4\uFDB5\uFDB6"+ - "\uFDB7\uFDB8\uFDB9\uFDBA\uFDBB\uFDBC\uFDBD\uFDBE"+ - "\uFDBF\uFDC0\uFDC1\uFDC2\uFDC3\uFDC4\uFDC5\uFDC6"+ - "\uFDC7\uFDC8\uFDC9\uFDCA\uFDCB\uFDCC\uFDCD\uFDCE"+ - "\uFDCF\uFDD0\uFDD1\uFDD2\uFDD3\uFDD4\uFDD5\uFDD6"+ - "\uFDD7\uFDD8\uFDD9\uFDDA\uFDDB\uFDDC\uFDDD\uFDDE"+ - "\uFDDF\uFDE0\uFDE1\uFDE2\uFDE3\uFDE4\uFDE5\uFDE6"+ - "\uFDE7\uFDE8\uFDE9\uFDEA\uFDEB\uFDEC\uFDED\uFDEE"+ - "\uFDEF\uFDF0\uFDF1\uFDF2\uFDF3\uFDF4\uFDF5\uFDF6"+ - "\uFDF7\uFDF8\uFDF9\uFDFA\uFDFB\uFDFC\uFDFD\uFDFE"+ - "\uFEA1\uFEA2\uFEA3\uFEA4\uFEA5\uFEA6\uFEA7\uFEA8"+ - "\uFEA9\uFEAA\uFEAB\uFEAC\uFEAD\uFEAE\uFEAF\uFEB0"+ - "\uFEB1\uFEB2\uFEB3\uFEB4\uFEB5\uFEB6\uFEB7\uFEB8"+ - "\uFEB9\uFEBA\uFEBB\uFEBC\uFEBD\uFEBE\uFEBF\uFEC0"+ - "\uFEC1\uFEC2\uFEC3\uFEC4\uFEC5\uFEC6\uFEC7\uFEC8"+ - "\uFEC9\uFECA\uFECB\uFECC\uFECD\uFECE\uFECF\uFED0"+ - "\uFED1\uFED2\uFED3\uFED4\uFED5\uFED6\uFED7\uFED8"+ - "\uFED9\uFEDA\uFEDB\uFEDC\uFEDD\uFEDE\uFEDF\uFEE0"+ - "\uFEE1\uFEE2\uFEE3\uFEE4\uFEE5\uFEE6\uFEE7\uFEE8"+ - "\uFEE9\uFEEA\uFEEB\uFEEC\uFEED\uFEEE\uFEEF\uFEF0"+ - "\uFEF1\uFEF2\uFEF3\uFEF4\uFEF5\uFEF6\uFEF7\uFEF8"+ - "\uFEF9\uFEFA\uFEFB\uFEFC\uFEFD\uFEFE\uA140\uA141"+ - "\uA142\uA143\uA144\uA145\uA146\uA147\uA148\uA149"+ - "\uA14A\uA14B\uA14C\uA14D\uA14E\uA14F\uA150\uA151"+ - "\uA152\uA153\uA154\uA155\uA156\uA157\uA158\uA159"+ - "\uA15A\uA15B\uA15C\uA15D\uA15E\uA15F\uA160\uA161"+ - "\uA162\uA163\uA164\uA165\uA166\uA167\uA168\uA169"+ - "\uA16A\uA16B\uA16C\uA16D\uA16E\uA16F\uA170\uA171"+ - "\uA172\uA173\uA174\uA175\uA176\uA177\uA178\uA179"+ - "\uA17A\uA17B\uA17C\uA17D\uA17E\uA180\uA181\uA182"+ - "\uA183\uA184\uA185\uA186\uA187\uA188\uA189\uA18A"+ - "\uA18B\uA18C\uA18D\uA18E\uA18F\uA190\uA191\uA192"+ - "\uA193\uA194\uA195\uA196\uA197\uA198\uA199\uA19A"+ - "\uA19B\uA19C\uA19D\uA19E\uA19F\uA1A0\uA240\uA241"+ - "\uA242\uA243\uA244\uA245\uA246\uA247\uA248\uA249"+ - "\uA24A\uA24B\uA24C\uA24D\uA24E\uA24F\uA250\uA251"+ - "\uA252\uA253\uA254\uA255\uA256\uA257\uA258\uA259"+ - "\uA25A\uA25B\uA25C\uA25D\uA25E\uA25F\uA260\uA261"+ - "\uA262\uA263\uA264\uA265\uA266\uA267\uA268\uA269"+ - "\uA26A\uA26B\uA26C\uA26D\uA26E\uA26F\uA270\uA271"+ - "\uA272\uA273\uA274\uA275\uA276\uA277\uA278\uA279"+ - "\uA27A\uA27B\uA27C\uA27D\uA27E\uA280\uA281\uA282"+ - "\uA283\uA284\uA285\uA286\uA287\uA288\uA289\uA28A"+ - "\uA28B\uA28C\uA28D\uA28E\uA28F\uA290\uA291\uA292"+ - "\uA293\uA294\uA295\uA296\uA297\uA298\uA299\uA29A"+ - "\uA29B\uA29C\uA29D\uA29E\uA29F\uA2A0\uA340\uA341"+ - "\uA342\uA343\uA344\uA345\uA346\uA347\uA348\uA349"+ - "\uA34A\uA34B\uA34C\uA34D\uA34E\uA34F\uA350\uA351"+ - "\uA352\uA353\uA354\uA355\uA356\uA357\uA358\uA359"+ - "\uA35A\uA35B\uA35C\uA35D\uA35E\uA35F\uA360\uA361"+ - "\uA362\uA363\uA364\uA365\uA366\uA367\uA368\uA369"+ - "\uA36A\uA36B\uA36C\uA36D\uA36E\uA36F\uA370\uA371"+ - "\uA372\uA373\uA374\uA375\uA376\uA377\uA378\uA379"+ - "\uA37A\uA37B\uA37C\uA37D\uA37E\uA380\uA381\uA382"+ - "\uA383\uA384\uA385\uA386\uA387\uA388\uA389\uA38A"+ - "\uA38B\uA38C\uA38D\uA38E\uA38F\uA390\uA391\uA392"+ - "\uA393\uA394\uA395\uA396\uA397\uA398\uA399\uA39A"+ - "\uA39B\uA39C\uA39D\uA39E\uA39F\uA3A0\uA440\uA441"+ - "\uA442\uA443\uA444\uA445\uA446\uA447\uA448\uA449"+ - "\uA44A\uA44B\uA44C\uA44D\uA44E\uA44F\uA450\uA451"+ - "\uA452\uA453\uA454\uA455\uA456\uA457\uA458\uA459"+ - "\uA45A\uA45B\uA45C\uA45D\uA45E\uA45F\uA460\uA461"+ - "\uA462\uA463\uA464\uA465\uA466\uA467\uA468\uA469"+ - "\uA46A\uA46B\uA46C\uA46D\uA46E\uA46F\uA470\uA471"+ - "\uA472\uA473\uA474\uA475\uA476\uA477\uA478\uA479"+ - "\uA47A\uA47B\uA47C\uA47D\uA47E\uA480\uA481\uA482"+ - "\uA483\uA484\uA485\uA486\uA487\uA488\uA489\uA48A"+ - "\uA48B\uA48C\uA48D\uA48E\uA48F\uA490\uA491\uA492"+ - "\uA493\uA494\uA495\uA496\uA497\uA498\uA499\uA49A"+ - "\uA49B\uA49C\uA49D\uA49E\uA49F\uA4A0\uA540\uA541"+ - "\uA542\uA543\uA544\uA545\uA546\uA547\uA548\uA549"+ - "\uA54A\uA54B\uA54C\uA54D\uA54E\uA54F\uA550\uA551"+ - "\uA552\uA553\uA554\uA555\uA556\uA557\uA558\uA559"+ - "\uA55A\uA55B\uA55C\uA55D\uA55E\uA55F\uA560\uA561"+ - "\uA562\uA563\uA564\uA565\uA566\uA567\uA568\uA569"+ - "\uA56A\uA56B\uA56C\uA56D\uA56E\uA56F\uA570\uA571"+ - "\uA572\uA573\uA574\uA575\uA576\uA577\uA578\uA579"+ - "\uA57A\uA57B\uA57C\uA57D\uA57E\uA580\uA581\uA582"+ - "\uA583\uA584\uA585\uA586\uA587\uA588\uA589\uA58A"+ - "\uA58B\uA58C\uA58D\uA58E\uA58F\uA590\uA591\uA592"+ - "\uA593\uA594\uA595\uA596\uA597\uA598\uA599\uA59A"+ - "\uA59B\uA59C\uA59D\uA59E\uA59F\uA5A0\uA640\uA641"+ - "\uA642\uA643\uA644\uA645\uA646\uA647\uA648\uA649"+ - "\uA64A\uA64B\uA64C\uA64D\uA64E\uA64F\uA650\uA651"+ - "\uA652\uA653\uA654\uA655\uA656\uA657\uA658\uA659"+ - "\uA65A\uA65B\uA65C\uA65D\uA65E\uA65F\uA660\uA661"+ - "\uA662\uA663\uA664\uA665\uA666\uA667\uA668\uA669"+ - "\uA66A\uA66B\uA66C\uA66D\uA66E\uA66F\uA670\uA671"+ - "\uA672\uA673\uA674\uA675\uA676\uA677\uA678\uA679"+ - "\uA67A\uA67B\uA67C\uA67D\uA67E\uA680\uA681\uA682"+ - "\uA683\uA684\uA685\uA686\uA687\uA688\uA689\uA68A"+ - "\uA68B\uA68C\uA68D\uA68E\uA68F\uA690\uA691\uA692"+ - "\uA693\uA694\uA695\uA696\uA697\uA698\uA699\uA69A"+ - "\uA69B\uA69C\uA69D\uA69E\uA69F\uA6A0\uA740\uA741"+ - "\uA742\uA743\uA744\uA745\uA746\uA747\uA748\uA749"+ - "\uA74A\uA74B\uA74C\uA74D\uA74E\uA74F\uA750\uA751"+ - "\uA752\uA753\uA754\uA755\uA756\uA757\uA758\uA759"+ - "\uA75A\uA75B\uA75C\uA75D\uA75E\uA75F\uA760\uA761"+ - "\uA762\uA763\uA764\uA765\uA766\uA767\uA768\uA769"+ - "\uA76A\uA76B\uA76C\uA76D\uA76E\uA76F\uA770\uA771"+ - "\uA772\uA773\uA774\uA775\uA776\uA777\uA778\uA779"+ - "\uA77A\uA77B\uA77C\uA77D\uA77E\uA780\uA781\uA782"+ - "\uA783\uA784\uA785\uA786\uA787\uA788\uA789\uA78A"+ - "\uA78B\uA78C\uA78D\uA78E\uA78F\uA790\uA791\uA792"+ - "\uA793\uA794\uA795\uA796\uA797\uA798\uA799\uA79A"+ - "\uA79B\uA79C\uA79D\uA79E\uA79F\uA7A0\uA2AB\uA2AC"+ - "\uA2AD\uA2AE\uA2AF\uA2B0\u2000\uA2E4\uA2EF\uA2F0"+ - "\uA2FD\uA2FE\uA4F4\uA4F5\uA4F6\uA4F7\uA4F8\uA4F9"+ - "\uA4FA\uA4FB\uA4FC\uA4FD\uA4FE\uA5F7\uA5F8\uA5F9"+ - "\uA5FA\uA5FB\uA5FC\uA5FD\uA5FE\uA6B9\uA6BA\uA6BB"+ - "\uA6BC\uA6BD\uA6BE\uA6BF\uA6C0\uA6D9\uA6DA\uA6DB"+ - "\uA6DC\uA6DD\uA6DE\uA6DF\uA6EC\uA6ED\uA6F3\uA6F6"+ - "\uA6F7\uA6F8\uA6F9\uA6FA\uA6FB\uA6FC\uA6FD\uA6FE"+ - "\uA7C2\uA7C3\uA7C4\uA7C5\uA7C6\uA7C7\uA7C8\uA7C9"+ - "\uA7CA\uA7CB\uA7CC\uA7CD\uA7CE\uA7CF\uA7D0\uA7F2"+ - "\uA7F3\uA7F4\uA7F5\uA7F6\uA7F7\uA7F8\uA7F9\uA7FA"+ - "\uA7FB\uA7FC\uA7FD\uA7FE\uA896\uA897\uA898\uA899"+ - "\uA89A\uA89B\uA89C\uA89D\uA89E\uA89F\uA8A0\uA8BC"+ - "\u2001\uA8C1\uA8C2\uA8C3\uA8C4\uA8EA\uA8EB\uA8EC"+ - "\uA8ED\uA8EE\uA8EF\uA8F0\uA8F1\uA8F2\uA8F3\uA8F4"+ - "\uA8F5\uA8F6\uA8F7\uA8F8\uA8F9\uA8FA\uA8FB\uA8FC"+ - "\uA8FD\uA8FE\uA958\uA95B\uA95D\uA95E\uA95F\u2002"+ - "\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A"+ - "\u200B\u200C\u200D\u200E\uA997\uA998\uA999\uA99A"+ - "\uA99B\uA99C\uA99D\uA99E\uA99F\uA9A0\uA9A1\uA9A2"+ - "\uA9A3\uA9F0\uA9F1\uA9F2\uA9F3\uA9F4\uA9F5\uA9F6"+ - "\uA9F7\uA9F8\uA9F9\uA9FA\uA9FB\uA9FC\uA9FD\uA9FE"+ - "\uD7FA\uD7FB\uD7FC\uD7FD\uD7FE\u200F\uFE51\uFE52"+ - "\uFE53\u2010\u2011\u2012\u2013\u2014\uFE59\u2015"+ - "\u2016\u2017\u2018\u2019\u201A\u201B\uFE61\u201C"+ - "\u201D\u201E\u201F\uFE66\uFE67\u2020\u2021\u2022"+ - "\u2023\uFE6C\uFE6D\u2024\u2025\u2026\u2027\u2028"+ - "\u2029\u202A\u202B\uFE76\u202C\u202D\u202E\u202F"+ - "\u2030\u2031\u2032\uFE7E\u2033\u2034\u2035\u2036"+ - "\u2037\u2038\u2039\u203A\u203B\u203C\u203D\u203E"+ - "\u203F\u2040\u2041\u2042\uFE90\uFE91\u2043\u2044"+ - "\u2045\u2046\u2047\u2048\u2049\u204A\u204B\u204C"+ - "\u204D\u204E\u204F\u2050\uFEA0\u2051\u2052\u2053"+ - "\u2054\u2055\u2056\u2057\u2058\u2059\u205A\u205B"+ - "\u205C\u205D\u205E\u205F\u2060\u2061\u2062\u2063"+ - "\u2064\u2065\u2066\u2067\u2068\u2069\u206A\u206B"+ - "\u206C\u206D\u206E\u206F\u2070\u2071\u2072\u2073"+ - "\u2074\u2075\u2076\u2077\u2078\u2079\u207A\u207B"+ - "\u207C\u207D\u207E\u207F\u2080\u2081\u2082\u2083"+ - "\u2084\u2085\u2086\u2087\u2088\u2089\u208A\u208B"+ - "\u208C\u208D\u208E\u208F\u2090\u2091\u2092\u2093"+ - "\u2094\u2095\u2096\u2097\u2098\u2099\u209A\u209B"+ - "\u209C\u209D\u209E\u209F\u20A0\u20A1\u20A2\u20A3"+ - "\u20A4\u20A5\u20A6\u20A7\u20A8\u20A9\u20AA\u20AB"+ - "\u20AC\u20AD\u20AE\u20AF\u20B0\u20B1\u20B2\u20B3"+ - "\u20B4\u20B5\u20B6\u20B7\u20B8\u20B9\u20BA\u20BB"+ - "\u20BC\u20BD\u20BE\u20BF\u20C0\u20C1\u20C2\u20C3"+ - "\u20C4\u20C5\u20C6\u20C7\u20C8\u20C9\u20CA\u20CB"+ - "\u20CC\u20CD\u20CE\u20CF\u20D0\u20D1\u20D2\u20D3"+ - "\u20D4\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB"+ - "\u20DC\u20DD\u20DE\u20DF\u20E0\u20E1\u20E2\u20E3"+ - "\u20E4\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB"+ - "\u20EC\u20ED\u20EE\u20EF\u20F0\u20F1\u20F2\u20F3"+ - "\u20F4\u20F5\u20F6\u20F7\u20F8\u20F9\u20FA\u20FB"+ - "\u20FC\u20FD\u20FE\u20FF\u2100\u2101\u2102\u2103"+ - "\u2104\u2105\u2106\u2107\u2108\u2109\u210A\u210B"+ - "\u210C\u210D\u210E\u210F\u2110\u2111\u2112\u2113"+ - "\u2114\u2115\u2116\u2117\u2118\u2119\u211A\u211B"+ - "\u211C\u211D\u211E\u211F\u2120\u2121\u2122\u2123"+ - "\u2124\u2125\u2126\u2127\u2128\u2129\u212A\u212B"+ - "\u212C\u212D\u212E\u212F\u2130\u2131\u2132\u2133"+ - "\u2134\u2135\u2136\u2137\u2138\u2139\u213A\u213B"+ - "\u213C\u213D\u213E\u213F\u2140\u2141\u2142\u2143"+ - "\u2144\u2145\u2146\u2147\u2148\u2149\u214A\u214B"+ - "\u214C\u214D\u214E\u214F\u2150\u2151\u2152\u2153"+ - "\u2154\u2155\u2156\u2157\u2158\u2159\u215A\u215B"+ - "\u215C\u215D\u215E\u215F\u2160\u2161\u2162\u2163"+ - "\u2164\u2165\u2166\u2167\u2168\u2169\u216A\u216B"+ - "\u216C\u216D\u216E\u216F\u2170\u2171\u2172\u2173"+ - "\u2174\u2175\u2176\u2177\u2178\u2179\u217A\u217B"+ - "\u217C\u217D\u217E\u217F\u2180\u2181\u2182\u2183"+ - "\u2184\u2185\u2186\u2187\u2188\u2189\u218A\u218B"+ - "\u218C\u218D\u218E\u218F\u2190\u2191\u2192\u2193"+ - "\u2194\u2195\u2196\u2197\u2198\u2199\u219A\u219B"+ - "\u219C\u219D\u219E\u219F\u21A0\u21A1\u21A2\u21A3"+ - "\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9\u21AA\u21AB"+ - "\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1\u21B2\u21B3"+ - "\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9\u21BA\u21BB"+ - "\u21BC\u21BD\u21BE\u21BF\u21C0\u21C1\u21C2\u21C3"+ - "\u21C4\u21C5\u21C6\u21C7\u21C8\u21C9\u21CA\u21CB"+ - "\u21CC\u21CD\u21CE\u21CF\u21D0\u21D1\u21D2\u21D3"+ - "\u21D4\u21D5\u21D6\u21D7\u21D8\u21D9\u21DA\u21DB"+ - "\u21DC\u21DD\u21DE\u21DF\u21E0\u21E1\u21E2\u21E3"+ - "\u21E4\u21E5\u21E6\u21E7\u21E8\u21E9\u21EA\u21EB"+ - "\u21EC\u21ED\u21EE\u21EF\u21F0\u21F1\u21F2\u21F3"+ - "\u21F4\u21F5\u21F6\u21F7\u21F8\u21F9\u21FA\u21FB"+ - "\u21FC\u21FD\u21FE\u21FF\u2200\u2201\u2202\u2203"+ - "\u2204\u2205\u2206\u2207\u2208\u2209\u220A\u220B"+ - "\u220C\u220D\u220E\u220F\u2210\u2211\u2212\u2213"+ - "\u2214\u2215\u2216\u2217\u2218\u2219\u221A\u221B"+ - "\u221C\u221D\u221E\u221F\u2220\u2221\u2222\u2223"+ - "\u2224\u2225\u2226\u2227\u2228\u2229\u222A\u222B"+ - "\u222C\u222D\u222E\u222F\u2230\u2231\u2232\u2233"+ - "\u2234\u2235\u2236\u2237\u2238\u2239\u223A\u223B"+ - "\u223C\u223D\u223E\u223F\u2240\u2241\u2242\u2243"+ - "\u2244\u2245\u2246\u2247\u2248\u2249\u224A\u224B"+ - "\u224C\u224D\u224E\u224F\u2250\u2251\u2252\u2253"+ - "\u2254\u2255\u2256\u2257\u2258\u2259\u225A\u225B"+ - "\u225C\u225D\u225E\u225F\u2260\u2261\u2262\u2263"+ - "\u2264\u2265\u2266\u2267\u2268\u2269\u226A\u226B"+ - "\u226C\u226D\u226E\u226F\u2270\u2271\u2272\u2273"+ - "\u2274\u2275\u2276\u2277\u2278\u2279\u227A\u227B"+ - "\u227C\u227D\u227E\u227F\u2280\u2281\u2282\u2283"+ - "\u2284\u2285\u2286\u2287\u2288\u2289\u228A\u228B"+ - "\u228C\u228D\u228E\u228F\u2290\u2291\u2292\u2293"+ - "\u2294\u2295\u2296\u2297\u2298\u2299\u229A\u229B"+ - "\u229C\u229D\u229E\u229F\u22A0\u22A1\u22A2\u22A3"+ - "\u22A4\u22A5\u22A6\u22A7\u22A8\u22A9\u22AA\u22AB"+ - "\u22AC\u22AD\u22AE\u22AF\u22B0\u22B1\u22B2\u22B3"+ - "\u22B4\u22B5\u22B6\u22B7\u22B8\u22B9\u22BA\u22BB"+ - "\u22BC\u22BD\u22BE\u22BF\u22C0\u22C1\u22C2\u22C3"+ - "\u22C4\u22C5\u22C6\u22C7\u22C8\u22C9\u22CA\u22CB"+ - "\u22CC\u22CD\u22CE\u22CF\u22D0\u22D1\u22D2\u22D3"+ - "\u22D4\u22D5\u22D6\u22D7\u22D8\u22D9\u22DA\u22DB"+ - "\u22DC\u22DD\u22DE\u22DF\u22E0\u22E1\u22E2\u22E3"+ - "\u22E4\u22E5\u22E6\u22E7\u22E8\u22E9\u22EA\u22EB"; - - private static final String innerEncoderIndex11= - "\u22EC\u22ED\u22EE\u22EF\u22F0\u22F1\u22F2\u22F3"+ - "\u22F4\u22F5\u22F6\u22F7\u22F8\u22F9\u22FA\u22FB"+ - "\u22FC\u22FD\u22FE\u22FF\u2300\u2301\u2302\u2303"+ - "\u2304\u2305\u2306\u2307\u2308\u2309\u230A\u230B"+ - "\u230C\u230D\u230E\u230F\u2310\u2311\u2312\u2313"+ - "\u2314\u2315\u2316\u2317\u2318\u2319\u231A\u231B"+ - "\u231C\u231D\u231E\u231F\u2320\u2321\u2322\u2323"+ - "\u2324\u2325\u2326\u2327\u2328\u2329\u232A\u232B"+ - "\u232C\u232D\u232E\u232F\u2330\u2331\u2332\u2333"+ - "\u2334\u2335\u2336\u2337\u2338\u2339\u233A\u233B"+ - "\u233C\u233D\u233E\u233F\u2340\u2341\u2342\u2343"+ - "\u2344\u2345\u2346\u2347\u2348\u2349\u234A\u234B"+ - "\u234C\u234D\u234E\u234F\u2350\u2351\u2352\u2353"+ - "\u2354\u2355\u2356\u2357\u2358\u2359\u235A\u235B"+ - "\u235C\u235D\u235E\u235F\u2360\u2361\u2362\u2363"+ - "\u2364\u2365\u2366\u2367\u2368\u2369\u236A\u236B"+ - "\u236C\u236D\u236E\u236F\u2370\u2371\u2372\u2373"+ - "\u2374\u2375\u2376\u2377\u2378\u2379\u237A\u237B"+ - "\u237C\u237D\u237E\u237F\u2380\u2381\u2382\u2383"+ - "\u2384\u2385\u2386\u2387\u2388\u2389\u238A\u238B"+ - "\u238C\u238D\u238E\u238F\u2390\u2391\u2392\u2393"+ - "\u2394\u2395\u2396\u2397\u2398\u2399\u239A\u239B"+ - "\u239C\u239D\u239E\u239F\u23A0\u23A1\u23A2\u23A3"+ - "\u23A4\u23A5\u23A6\u23A7\u23A8\u23A9\u23AA\u23AB"+ - "\u23AC\u23AD\u23AE\u23AF\u23B0\u23B1\u23B2\u23B3"+ - "\u23B4\u23B5\u23B6\u23B7\u23B8\u23B9\u23BA\u23BB"+ - "\u23BC\u23BD\u23BE\u23BF\u23C0\u23C1\u23C2\u23C3"+ - "\u23C4\u23C5\u23C6\u23C7\u23C8\u23C9\u23CA\u23CB"+ - "\u23CC\u23CD\u23CE\u23CF\u23D0\u23D1\u23D2\u23D3"+ - "\u23D4\u23D5\u23D6\u23D7\u23D8\u23D9\u23DA\u23DB"+ - "\u23DC\u23DD\u23DE\u23DF\u23E0\u23E1\u23E2\u23E3"+ - "\u23E4\u23E5\u23E6\u23E7\u23E8\u23E9\u23EA\u23EB"+ - "\u23EC\u23ED\u23EE\u23EF\u23F0\u23F1\u23F2\u23F3"+ - "\u23F4\u23F5\u23F6\u23F7\u23F8\u23F9\u23FA\u23FB"+ - "\u23FC\u23FD\u23FE\u23FF\u2400\u2401\u2402\u2403"+ - "\u2404\u2405\u2406\u2407\u2408\u2409\u240A\u240B"+ - "\u240C\u240D\u240E\u240F\u2410\u2411\u2412\u2413"+ - "\u2414\u2415\u2416\u2417\u2418\u2419\u241A\u241B"+ - "\u241C\u241D\u241E\u241F\u2420\u2421\u2422\u2423"+ - "\u2424\u2425\u2426\u2427\u2428\u2429\u242A\u242B"+ - "\u242C\u242D\u242E\u242F\u2430\u2431\u2432\u2433"+ - "\u2434\u2435\u2436\u2437\u2438\u2439\u243A\u243B"+ - "\u243C\u243D\u243E\u243F\u2440\u2441\u2442\u2443"+ - "\u2444\u2445\u2446\u2447\u2448\u2449\u244A\u244B"+ - "\u244C\u244D\u244E\u244F\u2450\u2451\u2452\u2453"+ - "\u2454\u2455\u2456\u2457\u2458\u2459\u245A\u245B"+ - "\u245C\u245D\u245E\u245F\u2460\u2461\u2462\u2463"+ - "\u2464\u2465\u2466\u2467\u2468\u2469\u246A\u246B"+ - "\u246C\u246D\u246E\u246F\u2470\u2471\u2472\u2473"+ - "\u2474\u2475\u2476\u2477\u2478\u2479\u247A\u247B"+ - "\u247C\u247D\u247E\u247F\u2480\u2481\u2482\u2483"+ - "\u2484\u2485\u2486\u2487\u2488\u2489\u248A\u248B"+ - "\u248C\u248D\u248E\u248F\u2490\u2491\u2492\u2493"+ - "\u2494\u2495\u2496\u2497\u2498\u2499\u249A\u249B"+ - "\u249C\u249D\u249E\u249F\u24A0\u24A1\u24A2\u24A3"+ - "\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9\u24AA\u24AB"+ - "\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1\u24B2\u24B3"+ - "\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9\u24BA\u24BB"+ - "\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1\u24C2\u24C3"+ - "\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9\u24CA\u24CB"+ - "\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1\u24D2\u24D3"+ - "\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9\u24DA\u24DB"+ - "\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1\u24E2\u24E3"+ - "\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9\u24EA\u24EB"+ - "\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1\u24F2\u24F3"+ - "\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9\u24FA\u24FB"+ - "\u24FC\u24FD\u24FE\u24FF\u2500\u2501\u2502\u2503"+ - "\u2504\u2505\u2506\u2507\u2508\u2509\u250A\u250B"+ - "\u250C\u250D\u250E\u250F\u2510\u2511\u2512\u2513"+ - "\u2514\u2515\u2516\u2517\u2518\u2519\u251A\u251B"+ - "\u251C\u251D\u251E\u251F\u2520\u2521\u2522\u2523"+ - "\u2524\u2525\u2526\u2527\u2528\u2529\u252A\u252B"+ - "\u252C\u252D\u252E\u252F\u2530\u2531\u2532\u2533"+ - "\u2534\u2535\u2536\u2537\u2538\u2539\u253A\u253B"+ - "\u253C\u253D\u253E\u253F\u2540\u2541\u2542\u2543"+ - "\u2544\u2545\u2546\u2547\u2548\u2549\u254A\u254B"+ - "\u254C\u254D\u254E\u254F\u2550\u2551\u2552\u2553"+ - "\u2554\u2555\u2556\u2557\u2558\u2559\u255A\u255B"+ - "\u255C\u255D\u255E\u255F\u2560\u2561\u2562\u2563"+ - "\u2564\u2565\u2566\u2567\u2568\u2569\u256A\u256B"+ - "\u256C\u256D\u256E\u256F\u2570\u2571\u2572\u2573"+ - "\u2574\u2575\u2576\u2577\u2578\u2579\u257A\u257B"+ - "\u257C\u257D\u257E\u257F\u2580\u2581\u2582\u2583"+ - "\u2584\u2585\u2586\u2587\u2588\u2589\u258A\u258B"+ - "\u258C\u258D\u258E\u258F\u2590\u2591\u2592\u2593"+ - "\u2594\u2595\u2596\u2597\u2598\u2599\u259A\u259B"+ - "\u259C\u259D\u259E\u259F\u25A0\u25A1\u25A2\u25A3"+ - "\u25A4\u25A5\u25A6\u25A7\u25A8\u25A9\u25AA\u25AB"+ - "\u25AC\u25AD\u25AE\u25AF\u25B0\u25B1\u25B2\u25B3"+ - "\u25B4\u25B5\u25B6\u25B7\u25B8\u25B9\u25BA\u25BB"+ - "\u25BC\u25BD\u25BE\u25BF\u25C0\u25C1\u25C2\u25C3"+ - "\u25C4\u25C5\u25C6\u25C7\u25C8\u25C9\u25CA\u25CB"+ - "\u25CC\u25CD\u25CE\u25CF\u25D0\u25D1\u25D2\u25D3"+ - "\u25D4\u25D5\u25D6\u25D7\u25D8\u25D9\u25DA\u25DB"+ - "\u25DC\u25DD\u25DE\u25DF\u25E0\u25E1\u25E2\u25E3"+ - "\u25E4\u25E5\u25E6\u25E7\u25E8\u25E9\u25EA\u25EB"+ - "\u25EC\u25ED\u25EE\u25EF\u25F0\u25F1\u25F2\u25F3"+ - "\u25F4\u25F5\u25F6\u25F7\u25F8\u25F9\u25FA\u25FB"+ - "\u25FC\u25FD\u25FE\u25FF\u2600\u2601\u2602\u2603"+ - "\u2604\u2605\u2606\u2607\u2608\u2609\u260A\u260B"+ - "\u260C\u260D\u260E\u260F\u2610\u2611\u2612\u2613"+ - "\u2614\u2615\u2616\u2617\u2618\u2619\u261A\u261B"+ - "\u261C\u261D\u261E\u261F\u2620\u2621\u2622\u2623"+ - "\u2624\u2625\u2626\u2627\u2628\u2629\u262A\u262B"+ - "\u262C\u262D\u262E\u262F\u2630\u2631\u2632\u2633"+ - "\u2634\u2635\u2636\u2637\u2638\u2639\u263A\u263B"+ - "\u263C\u263D\u263E\u263F\u2640\u2641\u2642\u2643"+ - "\u2644\u2645\u2646\u2647\u2648\u2649\u264A\u264B"+ - "\u264C\u264D\u264E\u264F\u2650\u2651\u2652\u2653"+ - "\u2654\u2655\u2656\u2657\u2658\u2659\u265A\u265B"+ - "\u265C\u265D\u265E\u265F\u2660\u2661\u2662\u2663"+ - "\u2664\u2665\u2666\u2667\u2668\u2669\u266A\u266B"+ - "\u266C\u266D\u266E\u266F\u2670\u2671\u2672\u2673"+ - "\u2674\u2675\u2676\u2677\u2678\u2679\u267A\u267B"+ - "\u267C\u267D\u267E\u267F\u2680\u2681\u2682\u2683"+ - "\u2684\u2685\u2686\u2687\u2688\u2689\u268A\u268B"+ - "\u268C\u268D\u268E\u268F\u2690\u2691\u2692\u2693"+ - "\u2694\u2695\u2696\u2697\u2698\u2699\u269A\u269B"+ - "\u269C\u269D\u269E\u269F\u26A0\u26A1\u26A2\u26A3"+ - "\u26A4\u26A5\u26A6\u26A7\u26A8\u26A9\u26AA\u26AB"+ - "\u26AC\u26AD\u26AE\u26AF\u26B0\u26B1\u26B2\u26B3"+ - "\u26B4\u26B5\u26B6\u26B7\u26B8\u26B9\u26BA\u26BB"+ - "\u26BC\u26BD\u26BE\u26BF\u26C0\u26C1\u26C2\u26C3"+ - "\u26C4\u26C5\u26C6\u26C7\u26C8\u26C9\u26CA\u26CB"+ - "\u26CC\u26CD\u26CE\u26CF\u26D0\u26D1\u26D2\u26D3"+ - "\u26D4\u26D5\u26D6\u26D7\u26D8\u26D9\u26DA\u26DB"+ - "\u26DC\u26DD\u26DE\u26DF\u26E0\u26E1\u26E2\u26E3"+ - "\u26E4\u26E5\u26E6\u26E7\u26E8\u26E9\u26EA\u26EB"+ - "\u26EC\u26ED\u26EE\u26EF\u26F0\u26F1\u26F2\u26F3"+ - "\u26F4\u26F5\u26F6\u26F7\u26F8\u26F9\u26FA\u26FB"+ - "\u26FC\u26FD\u26FE\u26FF\u2700\u2701\u2702\u2703"+ - "\u2704\u2705\u2706\u2707\u2708\u2709\u270A\u270B"+ - "\u270C\u270D\u270E\u270F\u2710\u2711\u2712\u2713"+ - "\u2714\u2715\u2716\u2717\u2718\u2719\u271A\u271B"+ - "\u271C\u271D\u271E\u271F\u2720\u2721\u2722\u2723"+ - "\u2724\u2725\u2726\u2727\u2728\u2729\u272A\u272B"+ - "\u272C\u272D\u272E\u272F\u2730\u2731\u2732\u2733"+ - "\u2734\u2735\u2736\u2737\u2738\u2739\u273A\u273B"+ - "\u273C\u273D\u273E\u273F\u2740\u2741\u2742\u2743"+ - "\u2744\u2745\u2746\u2747\u2748\u2749\u274A\u274B"+ - "\u274C\u274D\u274E\u274F\u2750\u2751\u2752\u2753"+ - "\u2754\u2755\u2756\u2757\u2758\u2759\u275A\u275B"+ - "\u275C\u275D\u275E\u275F\u2760\u2761\u2762\u2763"+ - "\u2764\u2765\u2766\u2767\u2768\u2769\u276A\u276B"+ - "\u276C\u276D\u276E\u276F\u2770\u2771\u2772\u2773"+ - "\u2774\u2775\u2776\u2777\u2778\u2779\u277A\u277B"+ - "\u277C\u277D\u277E\u277F\u2780\u2781\u2782\u2783"+ - "\u2784\u2785\u2786\u2787\u2788\u2789\u278A\u278B"+ - "\u278C\u278D\u278E\u278F\u2790\u2791\u2792\u2793"+ - "\u2794\u2795\u2796\u2797\u2798\u2799\u279A\u279B"+ - "\u279C\u279D\u279E\u279F\u27A0\u27A1\u27A2\u27A3"+ - "\u27A4\u27A5\u27A6\u27A7\u27A8\u27A9\u27AA\u27AB"+ - "\u27AC\u27AD\u27AE\u27AF\u27B0\u27B1\u27B2\u27B3"+ - "\u27B4\u27B5\u27B6\u27B7\u27B8\u27B9\u27BA\u27BB"+ - "\u27BC\u27BD\u27BE\u27BF\u27C0\u27C1\u27C2\u27C3"+ - "\u27C4\u27C5\u27C6\u27C7\u27C8\u27C9\u27CA\u27CB"+ - "\u27CC\u27CD\u27CE\u27CF\u27D0\u27D1\u27D2\u27D3"+ - "\u27D4\u27D5\u27D6\u27D7\u27D8\u27D9\u27DA\u27DB"+ - "\u27DC\u27DD\u27DE\u27DF\u27E0\u27E1\u27E2\u27E3"+ - "\u27E4\u27E5\u27E6\u27E7\u27E8\u27E9\u27EA\u27EB"+ - "\u27EC\u27ED\u27EE\u27EF\u27F0\u27F1\u27F2\u27F3"+ - "\u27F4\u27F5\u27F6\u27F7\u27F8\u27F9\u27FA\u27FB"+ - "\u27FC\u27FD\u27FE\u27FF\u2800\u2801\u2802\u2803"+ - "\u2804\u2805\u2806\u2807\u2808\u2809\u280A\u280B"+ - "\u280C\u280D\u280E\u280F\u2810\u2811\u2812\u2813"+ - "\u2814\u2815\u2816\u2817\u2818\u2819\u281A\u281B"+ - "\u281C\u281D\u281E\u281F\u2820\u2821\u2822\u2823"+ - "\u2824\u2825\u2826\u2827\u2828\u2829\u282A\u282B"+ - "\u282C\u282D\u282E\u282F\u2830\u2831\u2832\u2833"+ - "\u2834\u2835\u2836\u2837\u2838\u2839\u283A\u283B"+ - "\u283C\u283D\u283E\u283F\u2840\u2841\u2842\u2843"+ - "\u2844\u2845\u2846\u2847\u2848\u2849\u284A\u284B"+ - "\u284C\u284D\u284E\u284F\u2850\u2851\u2852\u2853"+ - "\u2854\u2855\u2856\u2857\u2858\u2859\u285A\u285B"+ - "\u285C\u285D\u285E\u285F\u2860\u2861\u2862\u2863"+ - "\u2864\u2865\u2866\u2867\u2868\u2869\u286A\u286B"+ - "\u286C\u286D\u286E\u286F\u2870\u2871\u2872\u2873"+ - "\u2874\u2875\u2876\u2877\u2878\u2879\u287A\u287B"+ - "\u287C\u287D\u287E\u287F\u2880\u2881\u2882\u2883"+ - "\u2884\u2885\u2886\u2887\u2888\u2889\u288A\u288B"+ - "\u288C\u288D\u288E\u288F\u2890\u2891\u2892\u2893"+ - "\u2894\u2895\u2896\u2897\u2898\u2899\u289A\u289B"+ - "\u289C\u289D\u289E\u289F\u28A0\u28A1\u28A2\u28A3"+ - "\u28A4\u28A5\u28A6\u28A7\u28A8\u28A9\u28AA\u28AB"+ - "\u28AC\u28AD\u28AE\u28AF\u28B0\u28B1\u28B2\u28B3"+ - "\u28B4\u28B5\u28B6\u28B7\u28B8\u28B9\u28BA\u28BB"+ - "\u28BC\u28BD\u28BE\u28BF\u28C0\u28C1\u28C2\u28C3"+ - "\u28C4\u28C5\u28C6\u28C7\u28C8\u28C9\u28CA\u28CB"+ - "\u28CC\u28CD\u28CE\u28CF\u28D0\u28D1\u28D2\u28D3"+ - "\u28D4\u28D5\u28D6\u28D7\u28D8\u28D9\u28DA\u28DB"+ - "\u28DC\u28DD\u28DE\u28DF\u28E0\u28E1\u28E2\u28E3"+ - "\u28E4\u28E5\u28E6\u28E7\u28E8\u28E9\u28EA\u28EB"+ - "\u28EC\u28ED\u28EE\u28EF\u28F0\u28F1\u28F2\u28F3"+ - "\u28F4\u28F5\u28F6\u28F7\u28F8\u28F9\u28FA\u28FB"+ - "\u28FC\u28FD\u28FE\u28FF\u2900\u2901\u2902\u2903"+ - "\u2904\u2905\u2906\u2907\u2908\u2909\u290A\u290B"+ - "\u290C\u290D\u290E\u290F\u2910\u2911\u2912\u2913"+ - "\u2914\u2915\u2916\u2917\u2918\u2919\u291A\u291B"+ - "\u291C\u291D\u291E\u291F\u2920\u2921\u2922\u2923"+ - "\u2924\u2925\u2926\u2927\u2928\u2929\u292A\u292B"+ - "\u292C\u292D\u292E\u292F\u2930\u2931\u2932\u2933"+ - "\u2934\u2935\u2936\u2937\u2938\u2939\u293A\u293B"+ - "\u293C\u293D\u293E\u293F\u2940\u2941\u2942\u2943"+ - "\u2944\u2945\u2946\u2947\u2948\u2949\u294A\u294B"+ - "\u294C\u294D\u294E\u294F\u2950\u2951\u2952\u2953"+ - "\u2954\u2955\u2956\u2957\u2958\u2959\u295A\u295B"+ - "\u295C\u295D\u295E\u295F\u2960\u2961\u2962\u2963"+ - "\u2964\u2965\u2966\u2967\u2968\u2969\u296A\u296B"+ - "\u296C\u296D\u296E\u296F\u2970\u2971\u2972\u2973"+ - "\u2974\u2975\u2976\u2977\u2978\u2979\u297A\u297B"+ - "\u297C\u297D\u297E\u297F\u2980\u2981\u2982\u2983"+ - "\u2984\u2985\u2986\u2987\u2988\u2989\u298A\u298B"+ - "\u298C\u298D\u298E\u298F\u2990\u2991\u2992\u2993"+ - "\u2994\u2995\u2996\u2997\u2998\u2999\u299A\u299B"+ - "\u299C\u299D\u299E\u299F\u29A0\u29A1\u29A2\u29A3"+ - "\u29A4\u29A5\u29A6\u29A7\u29A8\u29A9\u29AA\u29AB"+ - "\u29AC\u29AD\u29AE\u29AF\u29B0\u29B1\u29B2\u29B3"+ - "\u29B4\u29B5\u29B6\u29B7\u29B8\u29B9\u29BA\u29BB"+ - "\u29BC\u29BD\u29BE\u29BF\u29C0\u29C1\u29C2\u29C3"+ - "\u29C4\u29C5\u29C6\u29C7\u29C8\u29C9\u29CA\u29CB"+ - "\u29CC\u29CD\u29CE\u29CF\u29D0\u29D1\u29D2\u29D3"+ - "\u29D4\u29D5\u29D6\u29D7\u29D8\u29D9\u29DA\u29DB"+ - "\u29DC\u29DD\u29DE\u29DF\u29E0\u29E1\u29E2\u29E3"+ - "\u29E4\u29E5\u29E6\u29E7\u29E8\u29E9\u29EA\u29EB"+ - "\u29EC\u29ED\u29EE\u29EF\u29F0\u29F1\u29F2\u29F3"+ - "\u29F4\u29F5\u29F6\u29F7\u29F8\u29F9\u29FA\u29FB"+ - "\u29FC\u29FD\u29FE\u29FF\u2A00\u2A01\u2A02\u2A03"+ - "\u2A04\u2A05\u2A06\u2A07\u2A08\u2A09\u2A0A\u2A0B"+ - "\u2A0C\u2A0D\u2A0E\u2A0F\u2A10\u2A11\u2A12\u2A13"+ - "\u2A14\u2A15\u2A16\u2A17\u2A18\u2A19\u2A1A\u2A1B"+ - "\u2A1C\u2A1D\u2A1E\u2A1F\u2A20\u2A21\u2A22\u2A23"+ - "\u2A24\u2A25\u2A26\u2A27\u2A28\u2A29\u2A2A\u2A2B"+ - "\u2A2C\u2A2D\u2A2E\u2A2F\u2A30\u2A31\u2A32\u2A33"+ - "\u2A34\u2A35\u2A36\u2A37\u2A38\u2A39\u2A3A\u2A3B"+ - "\u2A3C\u2A3D\u2A3E\u2A3F\u2A40\u2A41\u2A42\u2A43"+ - "\u2A44\u2A45\u2A46\u2A47\u2A48\u2A49\u2A4A\u2A4B"+ - "\u2A4C\u2A4D\u2A4E\u2A4F\u2A50\u2A51\u2A52\u2A53"+ - "\u2A54\u2A55\u2A56\u2A57\u2A58\u2A59\u2A5A\u2A5B"+ - "\u2A5C\u2A5D\u2A5E\u2A5F\u2A60\u2A61\u2A62\u2A63"+ - "\u2A64\u2A65\u2A66\u2A67\u2A68\u2A69\u2A6A\u2A6B"+ - "\u2A6C\u2A6D\u2A6E\u2A6F\u2A70\u2A71\u2A72\u2A73"+ - "\u2A74\u2A75\u2A76\u2A77\u2A78\u2A79\u2A7A\u2A7B"+ - "\u2A7C\u2A7D\u2A7E\u2A7F\u2A80\u2A81\u2A82\u2A83"+ - "\u2A84\u2A85\u2A86\u2A87\u2A88\u2A89\u2A8A\u2A8B"+ - "\u2A8C\u2A8D\u2A8E\u2A8F\u2A90\u2A91\u2A92\u2A93"+ - "\u2A94\u2A95\u2A96\u2A97\u2A98\u2A99\u2A9A\u2A9B"+ - "\u2A9C\u2A9D\u2A9E\u2A9F\u2AA0\u2AA1\u2AA2\u2AA3"+ - "\u2AA4\u2AA5\u2AA6\u2AA7\u2AA8\u2AA9\u2AAA\u2AAB"+ - "\u2AAC\u2AAD\u2AAE\u2AAF\u2AB0\u2AB1\u2AB2\u2AB3"+ - "\u2AB4\u2AB5\u2AB6\u2AB7\u2AB8\u2AB9\u2ABA\u2ABB"+ - "\u2ABC\u2ABD\u2ABE\u2ABF\u2AC0\u2AC1\u2AC2\u2AC3"+ - "\u2AC4\u2AC5\u2AC6\u2AC7\u2AC8\u2AC9\u2ACA\u2ACB"+ - "\u2ACC\u2ACD\u2ACE\u2ACF\u2AD0\u2AD1\u2AD2\u2AD3"+ - "\u2AD4\u2AD5\u2AD6\u2AD7\u2AD8\u2AD9\u2ADA\u2ADB"+ - "\u2ADC\u2ADD\u2ADE\u2ADF\u2AE0\u2AE1\u2AE2\u2AE3"+ - "\u2AE4\u2AE5\u2AE6\u2AE7\u2AE8\u2AE9\u2AEA\u2AEB"+ - "\u2AEC\u2AED\u2AEE\u2AEF\u2AF0\u2AF1\u2AF2\u2AF3"+ - "\u2AF4\u2AF5\u2AF6\u2AF7\u2AF8\u2AF9\u2AFA\u2AFB"+ - "\u2AFC\u2AFD\u2AFE\u2AFF\u2B00\u2B01\u2B02\u2B03"+ - "\u2B04\u2B05\u2B06\u2B07\u2B08\u2B09\u2B0A\u2B0B"+ - "\u2B0C\u2B0D\u2B0E\u2B0F\u2B10\u2B11\u2B12\u2B13"+ - "\u2B14\u2B15\u2B16\u2B17\u2B18\u2B19\u2B1A\u2B1B"+ - "\u2B1C\u2B1D\u2B1E\u2B1F\u2B20\u2B21\u2B22\u2B23"+ - "\u2B24\u2B25\u2B26\u2B27\u2B28\u2B29\u2B2A\u2B2B"+ - "\u2B2C\u2B2D\u2B2E\u2B2F\u2B30\u2B31\u2B32\u2B33"+ - "\u2B34\u2B35\u2B36\u2B37\u2B38\u2B39\u2B3A\u2B3B"+ - "\u2B3C\u2B3D\u2B3E\u2B3F\u2B40\u2B41\u2B42\u2B43"+ - "\u2B44\u2B45\u2B46\u2B47\u2B48\u2B49\u2B4A\u2B4B"+ - "\u2B4C\u2B4D\u2B4E\u2B4F\u2B50\u2B51\u2B52\u2B53"+ - "\u2B54\u2B55\u2B56\u2B57\u2B58\u2B59\u2B5A\u2B5B"+ - "\u2B5C\u2B5D\u2B5E\u2B5F\u2B60\u2B61\u2B62\u2B63"+ - "\u2B64\u2B65\u2B66\u2B67\u2B68\u2B69\u2B6A\u2B6B"+ - "\u2B6C\u2B6D\u2B6E\u2B6F\u2B70\u2B71\u2B72\u2B73"+ - "\u2B74\u2B75\u2B76\u2B77\u2B78\u2B79\u2B7A\u2B7B"+ - "\u2B7C\u2B7D\u2B7E\u2B7F\u2B80\u2B81\u2B82\u2B83"+ - "\u2B84\u2B85\u2B86\u2B87\u2B88\u2B89\u2B8A\u2B8B"+ - "\u2B8C\u2B8D\u2B8E\u2B8F\u2B90\u2B91\u2B92\u2B93"+ - "\u2B94\u2B95\u2B96\u2B97\u2B98\u2B99\u2B9A\u2B9B"+ - "\u2B9C\u2B9D\u2B9E\u2B9F\u2BA0\u2BA1\u2BA2\u2BA3"+ - "\u2BA4\u2BA5\u2BA6\u2BA7\u2BA8\u2BA9\u2BAA\u2BAB"+ - "\u2BAC\u2BAD\u2BAE\u2BAF\u2BB0\u2BB1\u2BB2\u2BB3"+ - "\u2BB4\u2BB5\u2BB6\u2BB7\u2BB8\u2BB9\u2BBA\u2BBB"+ - "\u2BBC\u2BBD\u2BBE\u2BBF\u2BC0\u2BC1\u2BC2\u2BC3"+ - "\u2BC4\u2BC5\u2BC6\u2BC7\u2BC8\u2BC9\u2BCA\u2BCB"+ - "\u2BCC\u2BCD\u2BCE\u2BCF\u2BD0\u2BD1\u2BD2\u2BD3"+ - "\u2BD4\u2BD5\u2BD6\u2BD7\u2BD8\u2BD9\u2BDA\u2BDB"+ - "\u2BDC\u2BDD\u2BDE\u2BDF\u2BE0\u2BE1\u2BE2\u2BE3"+ - "\u2BE4\u2BE5\u2BE6\u2BE7\u2BE8\u2BE9\u2BEA\u2BEB"+ - "\u2BEC\u2BED\u2BEE\u2BEF\u2BF0\u2BF1\u2BF2\u2BF3"+ - "\u2BF4\u2BF5\u2BF6\u2BF7\u2BF8\u2BF9\u2BFA\u2BFB"+ - "\u2BFC\u2BFD\u2BFE\u2BFF\u2C00\u2C01\u2C02\u2C03"+ - "\u2C04\u2C05\u2C06\u2C07\u2C08\u2C09\u2C0A\u2C0B"+ - "\u2C0C\u2C0D\u2C0E\u2C0F\u2C10\u2C11\u2C12\u2C13"+ - "\u2C14\u2C15\u2C16\u2C17\u2C18\u2C19\u2C1A\u2C1B"+ - "\u2C1C\u2C1D\u2C1E\u2C1F\u2C20\u2C21\u2C22\u2C23"+ - "\u2C24\u2C25\u2C26\u2C27\u2C28\u2C29\u2C2A\u2C2B"+ - "\u2C2C\u2C2D\u2C2E\u2C2F\u2C30\u2C31\u2C32\u2C33"+ - "\u2C34\u2C35\u2C36\u2C37\u2C38\u2C39\u2C3A\u2C3B"+ - "\u2C3C\u2C3D\u2C3E\u2C3F\u2C40\u2C41\u2C42\u2C43"+ - "\u2C44\u2C45\u2C46\u2C47\u2C48\u2C49\u2C4A\u2C4B"+ - "\u2C4C\u2C4D\u2C4E\u2C4F\u2C50\u2C51\u2C52\u2C53"+ - "\u2C54\u2C55\u2C56\u2C57\u2C58\u2C59\u2C5A\u2C5B"+ - "\u2C5C\u2C5D\u2C5E\u2C5F\u2C60\u2C61\u2C62\u2C63"+ - "\u2C64\u2C65\u2C66\u2C67\u2C68\u2C69\u2C6A\u2C6B"+ - "\u2C6C\u2C6D\u2C6E\u2C6F\u2C70\u2C71\u2C72\u2C73"+ - "\u2C74\u2C75\u2C76\u2C77\u2C78\u2C79\u2C7A\u2C7B"+ - "\u2C7C\u2C7D\u2C7E\u2C7F\u2C80\u2C81\u2C82\u2C83"+ - "\u2C84\u2C85\u2C86\u2C87\u2C88\u2C89\u2C8A\u2C8B"+ - "\u2C8C\u2C8D\u2C8E\u2C8F\u2C90\u2C91\u2C92\u2C93"+ - "\u2C94\u2C95\u2C96\u2C97\u2C98\u2C99\u2C9A\u2C9B"+ - "\u2C9C\u2C9D\u2C9E\u2C9F\u2CA0\u2CA1\u2CA2\u2CA3"+ - "\u2CA4\u2CA5\u2CA6\u2CA7\u2CA8\u2CA9\u2CAA\u2CAB"+ - "\u2CAC\u2CAD\u2CAE\u2CAF\u2CB0\u2CB1\u2CB2\u2CB3"+ - "\u2CB4\u2CB5\u2CB6\u2CB7\u2CB8\u2CB9\u2CBA\u2CBB"+ - "\u2CBC\u2CBD\u2CBE\u2CBF\u2CC0\u2CC1\u2CC2\u2CC3"+ - "\u2CC4\u2CC5\u2CC6\u2CC7\u2CC8\u2CC9\u2CCA\u2CCB"+ - "\u2CCC\u2CCD\u2CCE\u2CCF\u2CD0\u2CD1\u2CD2\u2CD3"+ - "\u2CD4\u2CD5\u2CD6\u2CD7\u2CD8\u2CD9\u2CDA\u2CDB"+ - "\u2CDC\u2CDD\u2CDE\u2CDF\u2CE0\u2CE1\u2CE2\u2CE3"+ - "\u2CE4\u2CE5\u2CE6\u2CE7\u2CE8\u2CE9\u2CEA\u2CEB"+ - "\u2CEC\u2CED\u2CEE\u2CEF\u2CF0\u2CF1\u2CF2\u2CF3"+ - "\u2CF4\u2CF5\u2CF6\u2CF7\u2CF8\u2CF9\u2CFA\u2CFB"+ - "\u2CFC\u2CFD\u2CFE\u2CFF\u2D00\u2D01\u2D02\u2D03"+ - "\u2D04\u2D05\u2D06\u2D07\u2D08\u2D09\u2D0A\u2D0B"+ - "\u2D0C\u2D0D\u2D0E\u2D0F\u2D10\u2D11\u2D12\u2D13"+ - "\u2D14\u2D15\u2D16\u2D17\u2D18\u2D19\u2D1A\u2D1B"+ - "\u2D1C\u2D1D\u2D1E\u2D1F\u2D20\u2D21\u2D22\u2D23"+ - "\u2D24\u2D25\u2D26\u2D27\u2D28\u2D29\u2D2A\u2D2B"+ - "\u2D2C\u2D2D\u2D2E\u2D2F\u2D30\u2D31\u2D32\u2D33"+ - "\u2D34\u2D35\u2D36\u2D37\u2D38\u2D39\u2D3A\u2D3B"+ - "\u2D3C\u2D3D\u2D3E\u2D3F\u2D40\u2D41\u2D42\u2D43"+ - "\u2D44\u2D45\u2D46\u2D47\u2D48\u2D49\u2D4A\u2D4B"+ - "\u2D4C\u2D4D\u2D4E\u2D4F\u2D50\u2D51\u2D52\u2D53"+ - "\u2D54\u2D55\u2D56\u2D57\u2D58\u2D59\u2D5A\u2D5B"+ - "\u2D5C\u2D5D\u2D5E\u2D5F\u2D60\u2D61\u2D62\u2D63"+ - "\u2D64\u2D65\u2D66\u2D67\u2D68\u2D69\u2D6A\u2D6B"+ - "\u2D6C\u2D6D\u2D6E\u2D6F\u2D70\u2D71\u2D72\u2D73"+ - "\u2D74\u2D75\u2D76\u2D77\u2D78\u2D79\u2D7A\u2D7B"+ - "\u2D7C\u2D7D\u2D7E\u2D7F\u2D80\u2D81\u2D82\u2D83"+ - "\u2D84\u2D85\u2D86\u2D87\u2D88\u2D89\u2D8A\u2D8B"+ - "\u2D8C\u2D8D\u2D8E\u2D8F\u2D90\u2D91\u2D92\u2D93"+ - "\u2D94\u2D95\u2D96\u2D97\u2D98\u2D99\u2D9A\u2D9B"+ - "\u2D9C\u2D9D\u2D9E\u2D9F\u2DA0\u2DA1\u2DA2\u2DA3"+ - "\u2DA4\u2DA5\u2DA6\u2DA7\u2DA8\u2DA9\u2DAA\u2DAB"+ - "\u2DAC\u2DAD\u2DAE\u2DAF\u2DB0\u2DB1\u2DB2\u2DB3"+ - "\u2DB4\u2DB5\u2DB6\u2DB7\u2DB8\u2DB9\u2DBA\u2DBB"+ - "\u2DBC\u2DBD\u2DBE\u2DBF\u2DC0\u2DC1\u2DC2\u2DC3"+ - "\u2DC4\u2DC5\u2DC6\u2DC7\u2DC8\u2DC9\u2DCA\u2DCB"+ - "\u2DCC\u2DCD\u2DCE\u2DCF\u2DD0\u2DD1\u2DD2\u2DD3"+ - "\u2DD4\u2DD5\u2DD6\u2DD7\u2DD8\u2DD9\u2DDA\u2DDB"+ - "\u2DDC\u2DDD\u2DDE\u2DDF\u2DE0\u2DE1\u2DE2\u2DE3"+ - "\u2DE4\u2DE5\u2DE6\u2DE7\u2DE8\u2DE9\u2DEA\u2DEB"+ - "\u2DEC\u2DED\u2DEE\u2DEF\u2DF0\u2DF1\u2DF2\u2DF3"+ - "\u2DF4\u2DF5\u2DF6\u2DF7\u2DF8\u2DF9\u2DFA\u2DFB"+ - "\u2DFC\u2DFD\u2DFE\u2DFF\u2E00\u2E01\u2E02\u2E03"+ - "\u2E04\u2E05\u2E06\u2E07\u2E08\u2E09\u2E0A\u2E0B"+ - "\u2E0C\u2E0D\u2E0E\u2E0F\u2E10\u2E11\u2E12\u2E13"+ - "\u2E14\u2E15\u2E16\u2E17\u2E18\u2E19\u2E1A\u2E1B"+ - "\u2E1C\u2E1D\u2E1E\u2E1F\u2E20\u2E21\u2E22\u2E23"+ - "\u2E24\u2E25\u2E26\u2E27\u2E28\u2E29\u2E2A\u2E2B"+ - "\u2E2C\u2E2D\u2E2E\u2E2F\u2E30\u2E31\u2E32\u2E33"+ - "\u2E34\u2E35\u2E36\u2E37\u2E38\u2E39\u2E3A\u2E3B"+ - "\u2E3C\u2E3D\u2E3E\u2E3F\u2E40\u2E41\u2E42\u2E43"+ - "\u2E44\u2E45\u2E46\u2E47\u2E48\u2E49\u2E4A\u2E4B"+ - "\u2E4C\u2E4D\u2E4E\u2E4F\u2E50\u2E51\u2E52\u2E53"+ - "\u2E54\u2E55\u2E56\u2E57\u2E58\u2E59\u2E5A\u2E5B"+ - "\u2E5C\u2E5D\u2E5E\u2E5F\u2E60\u2E61\u2E62\u2E63"+ - "\u2E64\u2E65\u2E66\u2E67\u2E68\u2E69\u2E6A\u2E6B"+ - "\u2E6C\u2E6D\u2E6E\u2E6F\u2E70\u2E71\u2E72\u2E73"+ - "\u2E74\u2E75\u2E76\u2E77\u2E78\u2E79\u2E7A\u2E7B"+ - "\u2E7C\u2E7D\u2E7E\u2E7F\u2E80\u2E81\u2E82\u2E83"+ - "\u2E84\u2E85\u2E86\u2E87\u2E88\u2E89\u2E8A\u2E8B"+ - "\u2E8C\u2E8D\u2E8E\u2E8F\u2E90\u2E91\u2E92\u2E93"+ - "\u2E94\u2E95\u2E96\u2E97\u2E98\u2E99\u2E9A\u2E9B"+ - "\u2E9C\u2E9D\u2E9E\u2E9F\u2EA0\u2EA1\u2EA2\u2EA3"+ - "\u2EA4\u2EA5\u2EA6\u2EA7\u2EA8\u2EA9\u2EAA\u2EAB"+ - "\u2EAC\u2EAD\u2EAE\u2EAF\u2EB0\u2EB1\u2EB2\u2EB3"+ - "\u2EB4\u2EB5\u2EB6\u2EB7\u2EB8\u2EB9\u2EBA\u2EBB"+ - "\u2EBC\u2EBD\u2EBE\u2EBF\u2EC0\u2EC1\u2EC2\u2EC3"+ - "\u2EC4\u2EC5\u2EC6\u2EC7\u2EC8\u2EC9\u2ECA\u2ECB"+ - "\u2ECC\u2ECD\u2ECE\u2ECF\u2ED0\u2ED1\u2ED2\u2ED3"+ - "\u2ED4\u2ED5\u2ED6\u2ED7\u2ED8\u2ED9\u2EDA\u2EDB"+ - "\u2EDC\u2EDD\u2EDE\u2EDF\u2EE0\u2EE1\u2EE2\u2EE3"+ - "\u2EE4\u2EE5\u2EE6\u2EE7\u2EE8\u2EE9\u2EEA\u2EEB"+ - "\u2EEC\u2EED\u2EEE\u2EEF\u2EF0\u2EF1\u2EF2\u2EF3"+ - "\u2EF4\u2EF5\u2EF6\u2EF7\u2EF8\u2EF9\u2EFA\u2EFB"+ - "\u2EFC\u2EFD\u2EFE\u2EFF\u2F00\u2F01\u2F02\u2F03"+ - "\u2F04\u2F05\u2F06\u2F07\u2F08\u2F09\u2F0A\u2F0B"+ - "\u2F0C\u2F0D\u2F0E\u2F0F\u2F10\u2F11\u2F12\u2F13"+ - "\u2F14\u2F15\u2F16\u2F17\u2F18\u2F19\u2F1A\u2F1B"+ - "\u2F1C\u2F1D\u2F1E\u2F1F\u2F20\u2F21\u2F22\u2F23"+ - "\u2F24\u2F25\u2F26\u2F27\u2F28\u2F29\u2F2A\u2F2B"+ - "\u2F2C\u2F2D\u2F2E\u2F2F\u2F30\u2F31\u2F32\u2F33"+ - "\u2F34\u2F35\u2F36\u2F37\u2F38\u2F39\u2F3A\u2F3B"+ - "\u2F3C\u2F3D\u2F3E\u2F3F\u2F40\u2F41\u2F42\u2F43"+ - "\u2F44\u2F45\u2F46\u2F47\u2F48\u2F49\u2F4A\u2F4B"+ - "\u2F4C\u2F4D\u2F4E\u2F4F\u2F50\u2F51\u2F52\u2F53"+ - "\u2F54\u2F55\u2F56\u2F57\u2F58\u2F59\u2F5A\u2F5B"+ - "\u2F5C\u2F5D\u2F5E\u2F5F\u2F60\u2F61\u2F62\u2F63"+ - "\u2F64\u2F65\u2F66\u2F67\u2F68\u2F69\u2F6A\u2F6B"+ - "\u2F6C\u2F6D\u2F6E\u2F6F\u2F70\u2F71\u2F72\u2F73"+ - "\u2F74\u2F75\u2F76\u2F77\u2F78\u2F79\u2F7A\u2F7B"+ - "\u2F7C\u2F7D\u2F7E\u2F7F\u2F80\u2F81\u2F82\u2F83"+ - "\u2F84\u2F85\u2F86\u2F87\u2F88\u2F89\u2F8A\u2F8B"+ - "\u2F8C\u2F8D\u2F8E\u2F8F\u2F90\u2F91\u2F92\u2F93"+ - "\u2F94\u2F95\u2F96\u2F97\u2F98\u2F99\u2F9A\u2F9B"+ - "\u2F9C\u2F9D\u2F9E\u2F9F\u2FA0\u2FA1\u2FA2\u2FA3"+ - "\u2FA4\u2FA5\u2FA6\u2FA7\u2FA8\u2FA9\u2FAA\u2FAB"+ - "\u2FAC\u2FAD\u2FAE\u2FAF\u2FB0\u2FB1\u2FB2\u2FB3"+ - "\u2FB4\u2FB5\u2FB6\u2FB7\u2FB8\u2FB9\u2FBA\u2FBB"+ - "\u2FBC\u2FBD\u2FBE\u2FBF\u2FC0\u2FC1\u2FC2\u2FC3"+ - "\u2FC4\u2FC5\u2FC6\u2FC7\u2FC8\u2FC9\u2FCA\u2FCB"+ - "\u2FCC\u2FCD\u2FCE\u2FCF\u2FD0\u2FD1\u2FD2\u2FD3"+ - "\u2FD4\u2FD5\u2FD6\u2FD7\u2FD8\u2FD9\u2FDA\u2FDB"+ - "\u2FDC\u2FDD\u2FDE\u2FDF\u2FE0\u2FE1\u2FE2\u2FE3"+ - "\u2FE4\u2FE5\u2FE6\u2FE7\u2FE8\u2FE9\u2FEA\u2FEB"+ - "\u2FEC\u2FED\u2FEE\u2FEF\u2FF0\u2FF1\u2FF2\u2FF3"+ - "\u2FF4\u2FF5\u2FF6\u2FF7\u2FF8\u2FF9\u2FFA\u2FFB"+ - "\u2FFC\u2FFD\u2FFE\u2FFF\u3000\u3001\u3002\u3003"+ - "\u3004\u3005\u3006\u3007\u3008\u3009\u300A\u300B"+ - "\u300C\u300D\u300E\u300F\u3010\u3011\u3012\u3013"+ - "\u3014\u3015\u3016\u3017\u3018\u3019\u301A\u301B"+ - "\u301C\u301D\u301E\u301F\u3020\u3021\u3022\u3023"+ - "\u3024\u3025\u3026\u3027\u3028\u3029\u302A\u302B"+ - "\u302C\u302D\u302E\u302F\u3030\u3031\u3032\u3033"+ - "\u3034\u3035\u3036\u3037\u3038\u3039\u303A\u303B"+ - "\u303C\u303D\u303E\u303F\u3040\u3041\u3042\u3043"+ - "\u3044\u3045\u3046\u3047\u3048\u3049\u304A\u304B"+ - "\u304C\u304D\u304E\u304F\u3050\u3051\u3052\u3053"+ - "\u3054\u3055\u3056\u3057\u3058\u3059\u305A\u305B"+ - "\u305C\u305D\u305E\u305F\u3060\u3061\u3062\u3063"+ - "\u3064\u3065\u3066\u3067\u3068\u3069\u306A\u306B"+ - "\u306C\u306D\u306E\u306F\u3070\u3071\u3072\u3073"+ - "\u3074\u3075\u3076\u3077\u3078\u3079\u307A\u307B"+ - "\u307C\u307D\u307E\u307F\u3080\u3081\u3082\u3083"+ - "\u3084\u3085\u3086\u3087\u3088\u3089\u308A\u308B"+ - "\u308C\u308D\u308E\u308F\u3090\u3091\u3092\u3093"+ - "\u3094\u3095\u3096\u3097\u3098\u3099\u309A\u309B"+ - "\u309C\u309D\u309E\u309F\u30A0\u30A1\u30A2\u30A3"+ - "\u30A4\u30A5\u30A6\u30A7\u30A8\u30A9\u30AA\u30AB"+ - "\u30AC\u30AD\u30AE\u30AF\u30B0\u30B1\u30B2\u30B3"+ - "\u30B4\u30B5\u30B6\u30B7\u30B8\u30B9\u30BA\u30BB"+ - "\u30BC\u30BD\u30BE\u30BF\u30C0\u30C1\u30C2\u30C3"+ - "\u30C4\u30C5\u30C6\u30C7\u30C8\u30C9\u30CA\u30CB"+ - "\u30CC\u30CD\u30CE\u30CF\u30D0\u30D1\u30D2\u30D3"+ - "\u30D4\u30D5\u30D6\u30D7\u30D8\u30D9\u30DA\u30DB"+ - "\u30DC\u30DD\u30DE\u30DF\u30E0\u30E1\u30E2\u30E3"+ - "\u30E4\u30E5\u30E6\u30E7\u30E8\u30E9\u30EA\u30EB"+ - "\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007"+ - "\u2008\u2009\u200A\u200B\u200C\u200D\u200E\u200F"+ - "\u2010\u2011\u2012\u2013\u2014\u2015\u2016\u2017"+ - "\u2018\u2019\u201A\u201B\u201C\u201D\u201E\u201F"+ - "\u2020\u2021\u2022\u2023\u2024\u2025\u2026\u2027"+ - "\u2028\u2029\u202A\u202B\uFD9C\u202C\u202D\u202E"+ - "\u202F\u2030\u2031\u2032\u2033\u2034\u2035\u2036"+ - "\u2037\u2038\u2039\u203A\u203B\u203C\u203D\u203E"+ - "\u203F\u2040\u2041\u2042\u2043\u2044\u2045\u2046"+ - "\u2047\u2048\u2049\u204A\u204B\u204C\u204D\u204E"+ - "\u204F\u2050\u2051\u2052\u2053\u2054\u2055\u2056"+ - "\u2057\u2058\u2059\u205A\u205B\u205C\u205D\u205E"+ - "\u205F\u2060\u2061\u2062\u2063\u2064\u2065\u2066"+ - "\u2067\u2068\u2069\u206A\u206B\u206C\u206D\u206E"+ - "\u206F\u2070\u2071\u2072\u2073\u2074\u2075\u2076"+ - "\u2077\uFD9D\u2078\u2079\u207A\u207B\u207C\u207D"+ - "\u207E\u207F\u2080\u2081\u2082\u2083\u2084\u2085"+ - "\u2086\u2087\u2088\u2089\u208A\u208B\u208C\u208D"+ - "\u208E\u208F\u2090\u2091\u2092\uFD9E\u2093\u2094"+ - "\u2095\u2096\u2097\u2098\u2099\u209A\u209B\u209C"+ - "\u209D\u209E\u209F\u20A0\u20A1\u20A2\u20A3\u20A4"+ - "\u20A5\u20A6\u20A7\u20A8\u20A9\u20AA\u20AB\u20AC"+ - "\u20AD\u20AE\u20AF\u20B0\u20B1\u20B2\u20B3\u20B4"+ - "\u20B5\u20B6\u20B7\u20B8\u20B9\u20BA\u20BB\u20BC"+ - "\u20BD\u20BE\u20BF\u20C0\u20C1\u20C2\u20C3\u20C4"+ - "\u20C5\u20C6\u20C7\u20C8\u20C9\u20CA\u20CB\u20CC"+ - "\u20CD\u20CE\u20CF\u20D0\u20D1\u20D2\u20D3\u20D4"+ - "\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB\u20DC"+ - "\u20DD\u20DE\u20DF\u20E0\u20E1\u20E2\u20E3\uFD9F"+ - "\u20E4\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB"+ - "\u20EC\uFDA0\u20ED\u20EE\u20EF\u20F0\u20F1\u20F2"+ - "\u20F3\u20F4\u20F5\u20F6\u20F7\u20F8\u20F9\u20FA"+ - "\u20FB\u20FC\u20FD\u20FE\u20FF\u2100\u2101\u2102"+ - "\u2103\u2104\u2105\u2106\uFE40\uFE41\uFE42\uFE43"+ - "\u2107\uFE44\u2108\uFE45\uFE46\u2109\u210A\u210B"+ - "\uFE47\u210C\u210D\u210E\u210F\u2110\u2111\uFE48"+ - "\uFE49\uFE4A\u2112\uFE4B\uFE4C\u2113\u2114\uFE4D"+ - "\uFE4E\uFE4F\u2115\u2116\u2117\u2118\u2119\u211A"+ - "\u211B\u211C\u211D\u211E\u211F\u2120\u2121\u2122"+ - "\u2123\u2124\u2125\u2126\u2127\u2128\u2129\u212A"+ - "\u212B\u212C\u212D\u212E\u212F\u2130\u2131\u2132"+ - "\u2133\u2134\u2135\u2136\u2137\u2138\u2139\u213A"+ - "\u213B\u213C\u213D\u213E\u213F\u2140\u2141\u2142"+ - "\u2143\u2144\u2145\u2146\u2147\u2148\u2149\u214A"+ - "\u214B\u214C\u214D\u214E\u214F\u2150\u2151\u2152"+ - "\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215A"+ - "\u215B\u215C\u215D\u215E\u215F\u2160\u2161\u2162"+ - "\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216A"+ - "\u216B\u216C\u216D\u216E\u216F\u2170\u2171\u2172"+ - "\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217A"+ - "\u217B\u217C\u217D\u217E\u217F\u2180\u2181\u2182"+ - "\u2183\u2184\u2185\u2186\u2187\u2188\u2189\u218A"+ - "\u218B\u218C\u218D\u218E\u218F\u2190\u2191\u2192"+ - "\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u219A"+ - "\u219B\u219C\u219D\u219E\u219F\u21A0\u21A1\u21A2"+ - "\u21A3\u21A4\u21A5\u21A6\u21A7\u21A8\u21A9\u21AA"+ - "\u21AB\u21AC\u21AD\u21AE\u21AF\u21B0\u21B1\u21B2"+ - "\u21B3\u21B4\u21B5\u21B6\u21B7\u21B8\u21B9\u21BA"+ - "\u21BB\u21BC\u21BD\u21BE\u21BF\u21C0\u21C1\u21C2"+ - "\u21C3\u21C4\u21C5\u21C6\u21C7\u21C8\u21C9\u21CA"+ - "\u21CB\u21CC\u21CD\u21CE\u21CF\u21D0\u21D1\u21D2"+ - "\u21D3\u21D4\u21D5\u21D6\u21D7\u21D8\u21D9\u21DA"+ - "\u21DB\u21DC\u21DD\u21DE\u21DF\u21E0\u21E1\u21E2"+ - "\u21E3\u21E4\u21E5\u21E6\u21E7\u21E8\u21E9\u21EA"; - - private static final String innerEncoderIndex12= - "\u21EB\u21EC\u21ED\u21EE\u21EF\u21F0\u21F1\u21F2"+ - "\u21F3\u21F4\u21F5\u21F6\u21F7\u21F8\u21F9\u21FA"+ - "\u21FB\u21FC\u21FD\u21FE\u21FF\u2200\u2201\u2202"+ - "\u2203\u2204\u2205\u2206\u2207\u2208\u2209\u220A"+ - "\u220B\u220C\u220D\u220E\u220F\u2210\u2211\u2212"+ - "\u2213\u2214\u2215\u2216\u2217\u2218\u2219\u221A"+ - "\u221B\u221C\u221D\u221E\u221F\u2220\u2221\u2222"+ - "\u2223\u2224\u2225\u2226\u2227\u2228\u2229\u222A"+ - "\u222B\u222C\u222D\u222E\u222F\u2230\u2231\u2232"+ - "\u2233\u2234\u2235\u2236\u2237\u2238\u2239\u223A"+ - "\u223B\u223C\u223D\u223E\u223F\u2240\u2241\u2242"+ - "\u2243\u2244\u2245\u2246\u2247\u2248\u2249\u224A"+ - "\u224B\u224C\u224D\u224E\u224F\u2250\u2251\u2252"+ - "\u2253\u2254\u2255\u2256\u2257\u2258\u2259\u225A"+ - "\u225B\u225C\u225D\u225E\u225F\u2260\u2261\u2262"+ - "\u2263\u2264\u2265\u2266\u2267\u2268\u2269\u226A"+ - "\u226B\u226C\u226D\u226E\u226F\u2270\u2271\u2272"+ - "\u2273\u2274\u2275\u2276\u2277\u2278\u2279\u227A"+ - "\u227B\u227C\u227D\u227E\u227F\u2280\u2281\u2282"+ - "\u2283\u2284\u2285\u2286\u2287\u2288\u2289\u228A"+ - "\u228B\u228C\u228D\u228E\u228F\u2290\u2291\u2292"+ - "\u2293\u2294\u2295\u2296\u2297\u2298\u2299\u229A"+ - "\u229B\u229C\u229D\u229E\u229F\u22A0\u22A1\u22A2"+ - "\u22A3\u22A4\u22A5\u22A6\u22A7\u22A8\u22A9\u22AA"+ - "\u22AB\u22AC\u22AD\u22AE\u22AF\u22B0\u22B1\u22B2"+ - "\u22B3\u22B4\u22B5\u22B6\u22B7\u22B8\u22B9\u22BA"+ - "\u22BB\u22BC\u22BD\u22BE\u22BF\u22C0\u22C1\u22C2"+ - "\u22C3\u22C4\u22C5\u22C6\u22C7\u22C8\u22C9\u22CA"+ - "\u22CB\u22CC\u22CD\u22CE\u22CF\u22D0\u22D1\u22D2"+ - "\u22D3\u22D4\u22D5\u22D6\u22D7\u22D8\u22D9\u22DA"+ - "\u22DB\u22DC\u22DD\u22DE\u22DF\u22E0\u22E1\u22E2"+ - "\u22E3\u22E4\u22E5\u22E6\u22E7\u22E8\u22E9\u22EA"+ - "\u22EB\u22EC\u22ED\u22EE\u22EF\u22F0\u22F1\u22F2"+ - "\u22F3\u22F4\u22F5\u22F6\u22F7\u22F8\u22F9\u22FA"+ - "\u22FB\u22FC\u22FD\u22FE\u22FF\u2300\u2301\u2302"+ - "\u2303\u2304\u2305\u2306\u2307\u2308\u2309\u230A"+ - "\u230B\u230C\u230D\u230E\u230F\u2310\u2311\u2312"+ - "\u2313\u2314\u2315\u2316\u2317\u2318\u2319\u231A"+ - "\u231B\u231C\u231D\u231E\u231F\u2320\u2321\u2322"+ - "\u2323\u2324\u2325\u2326\u2327\u2328\u2329\u232A"+ - "\u232B\u232C\u232D\u232E\u232F\u2330\u2331\u2332"+ - "\u2333\u2334\u2335\u2336\u2337\u2338\u2339\u233A"+ - "\u233B\u233C\u233D\u233E\u233F\u2340\u2341\u2342"+ - "\u2343\u2344\u2345\u2346\u2347\u2348\u2349\u234A"+ - "\u234B\u234C\u234D\u234E\u234F\u2350\u2351\u2352"+ - "\u2353\u2354\u2355\u2356\u2357\u2358\u2359\u235A"+ - "\u235B\u235C\u235D\u235E\u235F\u2360\u2361\u2362"+ - "\u2363\u2364\u2365\u2366\u2367\u2368\u2369\u236A"+ - "\u236B\u236C\u236D\u236E\u236F\u2370\u2371\u2372"+ - "\u2373\u2374\u2375\u2376\u2377\u2378\u2379\u237A"+ - "\u237B\u237C\u237D\u237E\u237F\u2380\u2381\u2382"+ - "\u2383\u2384\u2385\u2386\u2387\u2388\u2389\u238A"+ - "\u238B\u238C\u238D\u238E\u238F\u2390\u2391\u2392"+ - "\u2393\u2394\u2395\u2396\u2397\u2398\u2399\u239A"+ - "\u239B\u239C\u239D\u239E\u239F\u23A0\u23A1\u23A2"+ - "\u23A3\u23A4\u23A5\u23A6\u23A7\u23A8\u23A9\u23AA"+ - "\u23AB\u23AC\u23AD\u23AE\u23AF\u23B0\u23B1\u23B2"+ - "\u23B3\u23B4\u23B5\u23B6\u23B7\u23B8\u23B9\u23BA"+ - "\u23BB\u23BC\u23BD\u23BE\u23BF\u23C0\u23C1\u23C2"+ - "\u23C3\u23C4\u23C5\u23C6\u23C7\u23C8\u23C9\u23CA"+ - "\u23CB\u23CC\u23CD\u23CE\u23CF\u23D0\u23D1\u23D2"+ - "\u23D3\u23D4\u23D5\u23D6\u23D7\u23D8\u23D9\u23DA"+ - "\u23DB\u23DC\u23DD\u23DE\u23DF\u23E0\u23E1\u23E2"+ - "\u23E3\u23E4\u23E5\u23E6\u23E7\u23E8\u23E9\u23EA"+ - "\u23EB\u23EC\u23ED\u23EE\u23EF\u23F0\u23F1\u23F2"+ - "\u23F3\u23F4\u23F5\u23F6\u23F7\u23F8\u23F9\u23FA"+ - "\u23FB\u23FC\u23FD\u23FE\u23FF\u2400\u2401\u2402"+ - "\u2403\u2404\u2405\u2406\u2407\u2408\u2409\u240A"+ - "\u240B\u240C\u240D\u240E\u240F\u2410\u2411\u2412"+ - "\u2413\u2414\u2415\u2416\u2417\u2418\u2419\u241A"+ - "\u241B\u241C\u241D\u241E\u241F\u2420\u2421\u2422"+ - "\u2423\u2424\u2425\u2426\u2427\u2428\u2429\u242A"+ - "\u242B\u242C\u242D\u242E\u242F\u2430\u2431\u2432"+ - "\u2433\u2434\u2435\u2436\u2437\u2438\u2439\u243A"+ - "\u243B\u243C\u243D\u243E\u243F\u2440\u2441\u2442"+ - "\u2443\u2444\u2445\u2446\u2447\u2448\u2449\u244A"+ - "\u244B\u244C\u244D\u244E\u244F\u2450\u2451\u2452"+ - "\u2453\u2454\u2455\u2456\u2457\u2458\u2459\u245A"+ - "\u245B\u245C\u245D\u245E\u245F\u2460\u2461\u2462"+ - "\u2463\u2464\u2465\u2466\u2467\u2468\u2469\u246A"+ - "\u246B\u246C\u246D\u246E\u246F\u2470\u2471\u2472"+ - "\u2473\u2474\u2475\u2476\u2477\u2478\u2479\u247A"+ - "\u247B\u247C\u247D\u247E\u247F\u2480\u2481\u2482"+ - "\u2483\u2484\u2485\u2486\u2487\u2488\u2489\u248A"+ - "\u248B\u248C\u248D\u248E\u248F\u2490\u2491\u2492"+ - "\u2493\u2494\u2495\u2496\u2497\u2498\u2499\u249A"+ - "\u249B\u249C\u249D\u249E\u249F\u24A0\u24A1\u24A2"+ - "\u24A3\u24A4\u24A5\u24A6\u24A7\u24A8\u24A9\u24AA"+ - "\u24AB\u24AC\u24AD\u24AE\u24AF\u24B0\u24B1\u24B2"+ - "\u24B3\u24B4\u24B5\u24B6\u24B7\u24B8\u24B9\u24BA"+ - "\u24BB\u24BC\u24BD\u24BE\u24BF\u24C0\u24C1\u24C2"+ - "\u24C3\u24C4\u24C5\u24C6\u24C7\u24C8\u24C9\u24CA"+ - "\u24CB\u24CC\u24CD\u24CE\u24CF\u24D0\u24D1\u24D2"+ - "\u24D3\u24D4\u24D5\u24D6\u24D7\u24D8\u24D9\u24DA"+ - "\u24DB\u24DC\u24DD\u24DE\u24DF\u24E0\u24E1\u24E2"+ - "\u24E3\u24E4\u24E5\u24E6\u24E7\u24E8\u24E9\u24EA"+ - "\u24EB\u24EC\u24ED\u24EE\u24EF\u24F0\u24F1\u24F2"+ - "\u24F3\u24F4\u24F5\u24F6\u24F7\u24F8\u24F9\u24FA"+ - "\u24FB\u24FC\u24FD\u24FE\u24FF\u2500\u2501\u2502"+ - "\u2503\u2504\u2505\u2506\u2507\u2508\u2509\u250A"+ - "\u250B\u250C\u250D\u250E\u250F\u2510\u2511\u2512"+ - "\u2513\u2514\u2515\u2516\u2517\u2518\u2519\u251A"+ - "\uA955\uA6F2\u251B\uA6F4\uA6F5\uA6E0\uA6E1\uA6F0"+ - "\uA6F1\uA6E2\uA6E3\uA6EE\uA6EF\uA6E6\uA6E7\uA6E4"+ - "\uA6E5\uA6E8\uA6E9\uA6EA\uA6EB\u251C\u251D\u251E"+ - "\u251F\uA968\uA969\uA96A\uA96B\uA96C\uA96D\uA96E"+ - "\uA96F\uA970\uA971\u2520\uA972\uA973\uA974\uA975"+ - "\u2521\uA976\uA977\uA978\uA979\uA97A\uA97B\uA97C"+ - "\uA97D\uA97E\uA980\uA981\uA982\uA983\uA984\u2522"+ - "\uA985\uA986\uA987\uA988\u2523\u2524\u2525\u2526"+ - "\u2527\u2528\u2529\u252A\u252B\u252C\u252D\u252E"+ - "\u252F\u2530\u2531\u2532\u2533\u2534\u2535\u2536"+ - "\u2537\u2538\u2539\u253A\u253B\u253C\u253D\u253E"+ - "\u253F\u2540\u2541\u2542\u2543\u2544\u2545\u2546"+ - "\u2547\u2548\u2549\u254A\u254B\u254C\u254D\u254E"+ - "\u254F\u2550\u2551\u2552\u2553\u2554\u2555\u2556"+ - "\u2557\u2558\u2559\u255A\u255B\u255C\u255D\u255E"+ - "\u255F\u2560\u2561\u2562\u2563\u2564\u2565\u2566"+ - "\u2567\u2568\u2569\u256A\u256B\u256C\u256D\u256E"+ - "\u256F\u2570\u2571\u2572\u2573\u2574\u2575\u2576"+ - "\u2577\u2578\u2579\u257A\u257B\u257C\u257D\u257E"+ - "\u257F\u2580\u2581\u2582\u2583\u2584\u2585\u2586"+ - "\u2587\u2588\u2589\u258A\u258B\u258C\u258D\u258E"+ - "\u258F\u2590\u2591\u2592\u2593\u2594\u2595\u2596"+ - "\u2597\u2598\u2599\u259A\u259B\u259C\u259D\u259E"+ - "\u259F\u25A0\u25A1\u25A2\u25A3\u25A4\u25A5\u25A6"+ - "\u25A7\u25A8\u25A9\u25AA\u25AB\u25AC\u25AD\u25AE"+ - "\u25AF\u25B0\u25B1\u25B2\u25B3\u25B4\u25B5\u25B6"+ - "\u25B7\uA3A1\uA3A2\uA3A3\uA1E7\uA3A5\uA3A6\uA3A7"+ - "\uA3A8\uA3A9\uA3AA\uA3AB\uA3AC\uA3AD\uA3AE\uA3AF"+ - "\uA3B0\uA3B1\uA3B2\uA3B3\uA3B4\uA3B5\uA3B6\uA3B7"+ - "\uA3B8\uA3B9\uA3BA\uA3BB\uA3BC\uA3BD\uA3BE\uA3BF"+ - "\uA3C0\uA3C1\uA3C2\uA3C3\uA3C4\uA3C5\uA3C6\uA3C7"+ - "\uA3C8\uA3C9\uA3CA\uA3CB\uA3CC\uA3CD\uA3CE\uA3CF"+ - "\uA3D0\uA3D1\uA3D2\uA3D3\uA3D4\uA3D5\uA3D6\uA3D7"+ - "\uA3D8\uA3D9\uA3DA\uA3DB\uA3DC\uA3DD\uA3DE\uA3DF"+ - "\uA3E0\uA3E1\uA3E2\uA3E3\uA3E4\uA3E5\uA3E6\uA3E7"+ - "\uA3E8\uA3E9\uA3EA\uA3EB\uA3EC\uA3ED\uA3EE\uA3EF"+ - "\uA3F0\uA3F1\uA3F2\uA3F3\uA3F4\uA3F5\uA3F6\uA3F7"+ - "\uA3F8\uA3F9\uA3FA\uA3FB\uA3FC\uA3FD\uA1AB\u25B8"+ - "\u25B9\u25BA\u25BB\u25BC\u25BD\u25BE\u25BF\u25C0"+ - "\u25C1\u25C2\u25C3\u25C4\u25C5\u25C6\u25C7\u25C8"+ - "\u25C9\u25CA\u25CB\u25CC\u25CD\u25CE\u25CF\u25D0"+ - "\u25D1\u25D2\u25D3\u25D4\u25D5\u25D6\u25D7\u25D8"+ - "\u25D9\u25DA\u25DB\u25DC\u25DD\u25DE\u25DF\u25E0"+ - "\u25E1\u25E2\u25E3\u25E4\u25E5\u25E6\u25E7\u25E8"+ - "\u25E9\u25EA\u25EB\u25EC\u25ED\u25EE\u25EF\u25F0"+ - "\u25F1\u25F2\u25F3\u25F4\u25F5\u25F6\u25F7\u25F8"+ - "\u25F9\u25FA\u25FB\u25FC\u25FD\u25FE\u25FF\u2600"+ - "\u2601\u2602\u2603\u2604\u2605\u2606\u2607\u2608"+ - "\u2609\u260A\u260B\u260C\u260D\u260E\u260F\u2610"+ - "\u2611\u2612\u2613\u2614\u2615\u2616\u2617\u2618"+ - "\u2619\u261A\u261B\u261C\u261D\u261E\u261F\u2620"+ - "\u2621\u2622\u2623\u2624\u2625\u2626\u2627\u2628"+ - "\u2629\u262A\u262B\u262C\u262D\u262E\u262F\u2630"+ - "\u2631\u2632\u2633\u2634\u2635\u2636\u2637\u2638"+ - "\uA1E9\uA1EA\uA956\uA3FE\uA957\uA3A4\u2639\u263A"+ - "\u263B\u263C\u263D\u263E\u263F\u2640\u2641\u2642"+ - "\u2643\u2644\u2645\u2646\u2647\u2648\u2649\u264A"+ - "\u264B\u264C\u264D\u264E\u264F\u2650\u2651\u2652"; - - private static final short encoderIndex1[] = { - 0, 1, 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, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 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, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 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, 158, 159, - 160, 161, 162, 163, 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, 0, 0, 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, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196 - }; - - static String encoderIndex2[] = { - innerEncoderIndex0, - innerEncoderIndex1, - innerEncoderIndex2, - innerEncoderIndex3, - innerEncoderIndex4, - innerEncoderIndex5, - innerEncoderIndex6, - innerEncoderIndex7, - innerEncoderIndex8, - innerEncoderIndex9, - innerEncoderIndex10, - innerEncoderIndex11, - innerEncoderIndex12 - }; - private static class Decoder extends CharsetDecoder { - - private static final char REPLACE_CHAR = '\uFFFD'; - private int currentState = GB18030_DOUBLE_BYTE; - - private Decoder(Charset cs) { - super(cs, 1.0f, 2.0f); - } - - private char getChar(int offset) { - int byte1 = (offset >>8) & 0xFF; - int byte2 = (offset & 0xFF); - int start = 0, end = 0xFF; - - if (((byte1 < 0) || (byte1 > decoderIndex1.length)) - || ((byte2 < start) || (byte2 > end))) { - return REPLACE_CHAR; - } - - int n = (decoderIndex1[byte1] & 0xf) * (end - start + 1) + (byte2 - start); - return decoderIndex2[decoderIndex1[byte1] >> 4].charAt(n); - } - - protected char decodeDouble(int byte1, int byte2) { - int start = 0x40, end = 0xFE; - if (((byte1 < 0) || (byte1 > index1.length)) - || ((byte2 < start) || (byte2 > end))) - return '\uFFFD'; - - int n = (index1[byte1] & 0xf) * (end - start + 1) + (byte2 - start); - return index2[index1[byte1] >> 4].charAt(n); - } - - protected void implReset() { - currentState = GB18030_DOUBLE_BYTE; - } - - private CoderResult decodeArrayLoop(ByteBuffer src, - CharBuffer dst) - { - byte[] sa = src.array(); - int sp = src.arrayOffset() + src.position(); - int sl = src.arrayOffset() + src.limit(); - - char[] da = dst.array(); - int dp = dst.arrayOffset() + dst.position(); - int dl = dst.arrayOffset() + dst.limit(); - - int inputSize = 1; - - try { - while (sp < sl) { - int byte1 = 0 , byte2 = 0, byte3 = 0, byte4 = 0; - // Get the input byte - byte1 = sa[sp] & 0xFF; - inputSize = 1; - - if ((byte1 & (byte)0x80) == 0){ // US-ASCII range - currentState = GB18030_SINGLE_BYTE; - } - else if (byte1 < 0x81 || byte1 > 0xfe) { - return CoderResult.malformedForLength(1); - } - else { // Either 2 or 4 byte sequence follows - if ( sl - sp < 2 ) - return CoderResult.UNDERFLOW; - byte2 = sa[sp + 1] & 0xFF; - inputSize = 2; - - if (byte2 < 0x30) - return CoderResult.malformedForLength(1); - else if (byte2 >= 0x30 && byte2 <= 0x39) { - currentState = GB18030_FOUR_BYTE; - - if (sl - sp < 4) - return CoderResult.UNDERFLOW; - - byte3 = sa[sp + 2] & 0xFF; - if (byte3 < 0x81 || byte3 > 0xfe) - return CoderResult.malformedForLength(3); - - byte4 = sa[sp + 3] & 0xFF; - inputSize = 4; - - if (byte4 < 0x30 || byte4 > 0x39) - return CoderResult.malformedForLength(4); - } - else if (byte2 == 0x7f || byte2 == 0xff || - (byte2 < 0x40 )) { - return CoderResult.malformedForLength(2); - } - else - currentState = GB18030_DOUBLE_BYTE; - } - - if (dl - dp < 1) - return CoderResult.OVERFLOW; - switch (currentState){ - case GB18030_SINGLE_BYTE: - da[dp++] = (char)byte1; - break; - case GB18030_DOUBLE_BYTE: - da[dp++] = decodeDouble(byte1, byte2); - break; - case GB18030_FOUR_BYTE: - int offset = (((byte1 - 0x81) * 10 + - (byte2 - 0x30)) * 126 + - byte3 - 0x81) * 10 + byte4 - 0x30; - int hiByte = (offset >>8) & 0xFF; - int lowByte = (offset & 0xFF); - - // Mixture of table lookups and algorithmic calculation - // of character values. - - // BMP Ranges - if (offset <= 0x4A62) - da[dp++] = getChar(offset); - else if (offset > 0x4A62 && offset <= 0x82BC) - da[dp++] = (char)(offset + 0x5543); - else if (offset >= 0x82BD && offset <= 0x830D) - da[dp++] = getChar(offset); - else if (offset >= 0x830D && offset <= 0x93A8) - da[dp++] = (char)(offset + 0x6557); - else if (offset >= 0x93A9 && offset <= 0x99FB) - da[dp++] = getChar(offset); - // Supplemental UCS planes handled via surrogates - else if (offset >= 0x2E248 && offset < 0x12E248) { - if (offset >= 0x12E248) - return CoderResult.malformedForLength(4); - offset -= 0x1e248; - if ( dl - dp < 2) - return CoderResult.OVERFLOW; - // emit high + low surrogate - da[dp++] = (char)((offset - 0x10000) / 0x400 + 0xD800); - da[dp++] = (char)((offset - 0x10000) % 0x400 + 0xDC00); - } - else - return CoderResult.malformedForLength(inputSize); - break; - } - sp += inputSize; - } - return CoderResult.UNDERFLOW; - } finally { - src.position(sp - src.arrayOffset()); - dst.position(dp - dst.arrayOffset()); - } - } - - private CoderResult decodeBufferLoop(ByteBuffer src, - CharBuffer dst) - { - int mark = src.position(); - - try { - while (src.hasRemaining()) { - int byte1 = 0, byte2 = 0, byte3 = 0, byte4 = 0; - byte1 = src.get() & 0xFF; - int inputSize = 1; - - if ((byte1 & (byte)0x80) == 0){ // US-ASCII range - currentState = GB18030_SINGLE_BYTE; - } - else if (byte1 < 0x81 || byte1 > 0xfe) { - return CoderResult.malformedForLength(1); - } - else { // Either 2 or 4 byte sequence follows - if ( src.remaining() < 1 ) - return CoderResult.UNDERFLOW; - byte2 = src.get() & 0xFF; - inputSize = 2; - - if (byte2 < 0x30) - return CoderResult.malformedForLength(1); - else if (byte2 >= 0x30 && byte2 <= 0x39) { - currentState = GB18030_FOUR_BYTE; - - if (src.remaining() < 2) - return CoderResult.UNDERFLOW; - - byte3 = src.get() & 0xFF; - if (byte3 < 0x81 || byte3 > 0xfe) - return CoderResult.malformedForLength(3); - - byte4 = src.get() & 0xFF; - inputSize = 4; - - if (byte4 < 0x30 || byte4 > 0x39) - return CoderResult.malformedForLength(4); - } - else if (byte2 == 0x7f || byte2 == 0xff || - (byte2 < 0x40 )) { - return CoderResult.malformedForLength(2); - } - else - currentState = GB18030_DOUBLE_BYTE; - } - - if (dst.remaining() < 1) - return CoderResult.OVERFLOW; - switch (currentState){ - case GB18030_SINGLE_BYTE: - dst.put((char)byte1); - break; - case GB18030_DOUBLE_BYTE: - dst.put(decodeDouble(byte1, byte2)); - break; - case GB18030_FOUR_BYTE: - int offset = (((byte1 - 0x81) * 10 + - (byte2 - 0x30)) * 126 + - byte3 - 0x81) * 10 + byte4 - 0x30; - int hiByte = (offset >>8) & 0xFF; - int lowByte = (offset & 0xFF); - - // Mixture of table lookups and algorithmic calculation - // of character values. - - // BMP Ranges - if (offset <= 0x4A62) - dst.put(getChar(offset)); - else if (offset > 0x4A62 && offset <= 0x82BC) - dst.put((char)(offset + 0x5543)); - else if (offset >= 0x82BD && offset <= 0x830D) - dst.put(getChar(offset)); - else if (offset >= 0x830D && offset <= 0x93A8) - dst.put((char)(offset + 0x6557)); - else if (offset >= 0x93A9 && offset <= 0x99FB) - dst.put(getChar(offset)); - // Supplemental UCS planes handled via surrogates - else if (offset >= 0x2E248 && offset < 0x12E248) { - if (offset >= 0x12E248) - return CoderResult.malformedForLength(4); - offset -= 0x1e248; - if ( dst.remaining() < 2) - return CoderResult.OVERFLOW; - // emit high + low surrogate - dst.put((char)((offset - 0x10000) / 0x400 + 0xD800)); - dst.put((char)((offset - 0x10000) % 0x400 + 0xDC00)); - } else { - return CoderResult.malformedForLength(inputSize); - } - } - mark += inputSize; - } - return CoderResult.UNDERFLOW; - } finally { - src.position(mark); - } - } - - - protected CoderResult decodeLoop(ByteBuffer src, - CharBuffer dst) - { - if (src.hasArray() && dst.hasArray()) - return decodeArrayLoop(src, dst); - else - return decodeBufferLoop(src, dst); - } - } - - private static class Encoder extends CharsetEncoder { - - private int currentState = GB18030_DOUBLE_BYTE; - - private Encoder(Charset cs) { - super(cs, 4.0f, 4.0f); // max of 4 bytes per char - } - - public boolean canEncode(char c) { - return ! Character.isSurrogate(c); - } - - private final Surrogate.Parser sgp = new Surrogate.Parser(); - - private int getGB18030(short[] outerIndex, String[] innerEncoderIndex, - char ch) { - int offset = outerIndex[((ch & 0xff00) >> 8 )] << 8; - return innerEncoderIndex[offset >> 12].charAt((offset & 0xfff) + - (ch & 0xff)); - } - - protected void implReset() { - currentState = GB18030_DOUBLE_BYTE; - } - - private CoderResult encodeArrayLoop(CharBuffer src, - ByteBuffer dst) - { - char[] sa = src.array(); - int sp = src.arrayOffset() + src.position(); - int sl = src.arrayOffset() + src.limit(); - - byte[] da = dst.array(); - int dp = dst.arrayOffset() + dst.position(); - int dl = dst.arrayOffset() + dst.limit(); - - int condensedKey = 0; // expands to a four byte sequence - int hiByte = 0, loByte = 0; - currentState = GB18030_DOUBLE_BYTE; - - try { - while (sp < sl) { - int inputSize = 1; - char c = sa[sp]; - - if (Character.isSurrogate(c)) { - if ((condensedKey=sgp.parse(c, sa, sp, sl)) < 0) - return sgp.error(); - // Character.toCodePoint looks like - // (((high & 0x3ff) << 10) | (low & 0x3ff)) + 0x10000; - // so we add (0x2e248 - 0x10000) to get the "key". - condensedKey += 0x1E248; - currentState = GB18030_FOUR_BYTE; - inputSize = sgp.increment(); - } - else if (c >= 0x0000 && c <= 0x007F) { - currentState = GB18030_SINGLE_BYTE; - } - else if (c <= 0xA4C6 || c >= 0xE000) { - int outByteVal = getGB18030(encoderIndex1, - encoderIndex2, - c); - if (outByteVal == 0xFFFD ) - return CoderResult.unmappableForLength(1); - - hiByte = (outByteVal & 0xFF00) >> 8; - loByte = (outByteVal & 0xFF); - - condensedKey = (hiByte - 0x20) * 256 + loByte; - - if (c >= 0xE000 && c < 0xF900) - condensedKey += 0x82BD; - else if (c >= 0xF900) - condensedKey += 0x93A9; - - if (hiByte > 0x80) - currentState = GB18030_DOUBLE_BYTE; - else - currentState = GB18030_FOUR_BYTE; - } - else if (c >= 0xA4C7 && c <= 0xD7FF) { - condensedKey = c - 0x5543; - currentState = GB18030_FOUR_BYTE; - } - - switch(currentState) { - case GB18030_SINGLE_BYTE: - if (dl - dp < 1) - return CoderResult.OVERFLOW; - da[dp++] = (byte)c; - break; - - case GB18030_DOUBLE_BYTE: - if (dl - dp < 2) - return CoderResult.OVERFLOW; - da[dp++] = (byte)hiByte; - da[dp++] = (byte)loByte; - break; - - case GB18030_FOUR_BYTE: // Four Byte encoding - byte b1, b2, b3, b4; - - if (dl - dp < 4) - return CoderResult.OVERFLOW; - // Decompose the condensed key into its 4 byte equivalent - b4 = (byte)((condensedKey % 10) + 0x30); - condensedKey /= 10; - b3 = (byte)((condensedKey % 126) + 0x81); - condensedKey /= 126; - b2 = (byte)((condensedKey % 10) + 0x30); - b1 = (byte)((condensedKey / 10) + 0x81); - da[dp++] = b1; - da[dp++] = b2; - da[dp++] = b3; - da[dp++] = b4; - break; - default: - assert(false); - } - sp += inputSize; - } - return CoderResult.UNDERFLOW; - } finally { - src.position(sp - src.arrayOffset()); - dst.position(dp - dst.arrayOffset()); - } - } - - private CoderResult encodeBufferLoop(CharBuffer src, - ByteBuffer dst) - { - int condensedKey = 0; - int hiByte = 0, loByte = 0; - currentState = GB18030_DOUBLE_BYTE; - int mark = src.position(); - try { - while (src.hasRemaining()) { - char c = src.get(); - int inputSize = 1; - if (Character.isSurrogate(c)) { - if ((condensedKey = sgp.parse(c, src))<0) - return sgp.error(); - condensedKey += 0x1e248; - currentState = GB18030_FOUR_BYTE; - inputSize = 2; - } - else if (c >= 0x0000 && c <= 0x007F) { - currentState = GB18030_SINGLE_BYTE; - } - else if (c <= 0xA4C6 || c >= 0xE000) { - int outByteVal = getGB18030(encoderIndex1, - encoderIndex2, - c); - if (outByteVal == 0xFFFD ) - return CoderResult.unmappableForLength(1); - - hiByte = (outByteVal & 0xFF00) >> 8; - loByte = (outByteVal & 0xFF); - - condensedKey = (hiByte - 0x20) * 256 + loByte; - - if (c >= 0xE000 && c < 0xF900) - condensedKey += 0x82BD; - else if (c >= 0xF900) - condensedKey += 0x93A9; - - if (hiByte > 0x80) - currentState = GB18030_DOUBLE_BYTE; - else - currentState = GB18030_FOUR_BYTE; - } - else if (c >= 0xA4C7 && c <= 0xD7FF) { - condensedKey = c - 0x5543; - currentState = GB18030_FOUR_BYTE; - } - - if (currentState == GB18030_SINGLE_BYTE) { - if (dst.remaining() < 1) - return CoderResult.OVERFLOW; - dst.put((byte)c); - } else if (currentState == GB18030_DOUBLE_BYTE) { - if (dst.remaining() < 2) - return CoderResult.OVERFLOW; - dst.put((byte)hiByte); - dst.put((byte)loByte); - } - else { // Four Byte encoding - byte b1, b2, b3, b4; - - if (dst.remaining() < 4) - return CoderResult.OVERFLOW; - // Decompose the condensed key into its 4 byte equivalent - b4 = (byte)((condensedKey % 10) + 0x30); - condensedKey /= 10; - b3 = (byte)((condensedKey % 126) + 0x81); - condensedKey /= 126; - b2 = (byte)((condensedKey % 10) + 0x30); - b1 = (byte)((condensedKey / 10) + 0x81); - dst.put(b1); - dst.put(b2); - dst.put(b3); - dst.put(b4); - } - mark += inputSize; - } - return CoderResult.UNDERFLOW; - } finally { - src.position(mark); - } - } - protected CoderResult encodeLoop(CharBuffer src, - ByteBuffer dst) - { - if (src.hasArray() && dst.hasArray()) - return encodeArrayLoop(src, dst); - else - return encodeBufferLoop(src, dst); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java 2023-07-05 07:11:54.000000000 +0000 @@ -1183,15 +1183,16 @@ } if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0) log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract); - } else if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) { - if ((owner.flags() & INTERFACE) != 0) { - log.error(tree.body.pos(), Errors.IntfMethCantHaveBody); - } else { - log.error(tree.pos(), Errors.AbstractMethCantHaveBody); - } - } else if ((tree.mods.flags & NATIVE) != 0) { - log.error(tree.pos(), Errors.NativeMethCantHaveBody); } else { + if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) { + if ((owner.flags() & INTERFACE) != 0) { + log.error(tree.body.pos(), Errors.IntfMethCantHaveBody); + } else { + log.error(tree.pos(), Errors.AbstractMethCantHaveBody); + } + } else if ((tree.mods.flags & NATIVE) != 0) { + log.error(tree.pos(), Errors.NativeMethCantHaveBody); + } // Add an implicit super() call unless an explicit call to // super(...) or this(...) is given // or we are compiling class java.lang.Object. diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -165,9 +165,14 @@ dumpLambdaToMethodStats = options.isSet("debug.dumpLambdaToMethodStats"); attr = Attr.instance(context); forceSerializable = options.isSet("forceSerializable"); - debugLinesOrVars = options.isSet(Option.G) - || options.isSet(Option.G_CUSTOM, "lines") - || options.isSet(Option.G_CUSTOM, "vars"); + boolean lineDebugInfo = + options.isUnset(Option.G_CUSTOM) || + options.isSet(Option.G_CUSTOM, "lines"); + boolean varDebugInfo = + options.isUnset(Option.G_CUSTOM) + ? options.isSet(Option.G) + : options.isSet(Option.G_CUSTOM, "vars"); + debugLinesOrVars = lineDebugInfo || varDebugInfo; verboseDeduplication = options.isSet("debug.dumpLambdaToMethodDeduplication"); deduplicateLambdas = options.getBoolean("deduplicateLambdas", true); nestmateLambdas = Target.instance(context).runtimeUseNestAccess(); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java --- openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java 2023-07-05 07:11:54.000000000 +0000 @@ -664,11 +664,14 @@ @Override public void visitClassDef(JCClassDecl tree) { ClassSymbol prevCurrentClass = currentClass; + MethodSymbol prevMethodSym = currentMethodSym; try { currentClass = tree.sym; + currentMethodSym = null; super.visitClassDef(tree); } finally { currentClass = prevCurrentClass; + currentMethodSym = prevMethodSym; } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java --- openjdk-17-17.0.7+7~us1/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4120,10 +4120,13 @@ return defs.toList(); } + @SuppressWarnings("fallthrough") private EnumeratorEstimate estimateEnumeratorOrMember(Name enumName) { // if we are seeing a record declaration inside of an enum we want the same error message as expected for a // let's say an interface declaration inside an enum - if (token.kind == TokenKind.IDENTIFIER && token.name() != enumName && + boolean ident = token.kind == TokenKind.IDENTIFIER || + token.kind == TokenKind.UNDERSCORE; + if (ident && token.name() != enumName && (!allowRecords || !isRecordStart())) { Token next = S.token(1); switch (next.kind) { @@ -4132,12 +4135,11 @@ } } switch (token.kind) { - case IDENTIFIER: case MONKEYS_AT: case LT: - if (token.kind == IDENTIFIER) { - if (allowRecords && isRecordStart()) { - return EnumeratorEstimate.MEMBER; - } + case IDENTIFIER: + if (allowRecords && isRecordStart()) { + return EnumeratorEstimate.MEMBER; } + case MONKEYS_AT: case LT: case UNDERSCORE: return EnumeratorEstimate.UNKNOWN; default: return EnumeratorEstimate.MEMBER; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java openjdk-17-17.0.8+7/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java --- openjdk-17-17.0.7+7~us1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -209,15 +209,19 @@ SecretKey clientMacKey, serverMacKey; // The MAC size may be zero for GCM mode. - // - // PKCS11 does not support GCM mode as the author made the comment, - // so the macBits is unlikely to be zero. It's only a place holder. if (macBits != 0) { clientMacKey = P11Key.secretKey (session, out.hClientMacSecret, "MAC", macBits, attributes); serverMacKey = P11Key.secretKey (session, out.hServerMacSecret, "MAC", macBits, attributes); } else { + // NSS allocates MAC keys even if macBits is zero + if (out.hClientMacSecret != CK_INVALID_HANDLE) { + token.p11.C_DestroyObject(session.id(), out.hClientMacSecret); + } + if (out.hServerMacSecret != CK_INVALID_HANDLE) { + token.p11.C_DestroyObject(session.id(), out.hServerMacSecret); + } clientMacKey = null; serverMacKey = null; } @@ -229,6 +233,8 @@ serverCipherKey = P11Key.secretKey(session, out.hServerKey, cipherAlgorithm, expandedKeyBits, attributes); } else { + assert out.hClientKey == 0; + assert out.hServerKey == 0; clientCipherKey = null; serverCipherKey = null; } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c openjdk-17-17.0.8+7/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c --- openjdk-17-17.0.7+7~us1/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -144,11 +144,22 @@ TRACE1("DEBUG C_Sign: ret rv=0x%lX\n", rv); + if (rv == CKR_BUFFER_TOO_SMALL) { + bufP = (CK_BYTE_PTR) malloc(ckSignatureLength); + if (bufP == NULL) { + throwOutOfMemoryError(env, 0); + goto cleanup; + } + rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, + bufP, &ckSignatureLength); + } + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength); TRACE1("DEBUG C_Sign: signature length = %lu\n", ckSignatureLength); } +cleanup: free(ckpData); if (bufP != BUF) { free(bufP); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java openjdk-17-17.0.8+7/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java --- openjdk-17-17.0.7+7~us1/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, 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 @@ -65,7 +65,7 @@ // int:128 or int:4 or float:16, report the size in the // printName. If we do unsigned or vector or bit lane types, // report that condition also. - this.typeChar = printName.toUpperCase().charAt(0); + this.typeChar = genericElementType.getSimpleName().charAt(0); assert("FDBSIL".indexOf(typeChar) == ordinal()) : this; // Same as in JVMS, org.objectweb.asm.Opcodes, etc.: this.basicType = basicType; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java 2023-07-05 07:11:54.000000000 +0000 @@ -14,7 +14,7 @@ * @see Macro * @see Reference * @see Widget - * @see org.jline.keymap.KeyMap + * @see jdk.internal.org.jline.keymap.KeyMap * * @author Guillaume Nodet */ diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java 2023-07-05 07:11:54.000000000 +0000 @@ -24,6 +24,7 @@ private final String suffix; private final String key; private final boolean complete; + private final int sort; /** * Simple constructor with only a single String as an argument. @@ -31,7 +32,7 @@ * @param value the candidate */ public Candidate(String value) { - this(value, value, null, null, null, null, true); + this(value, value, null, null, null, null, true, 0); } /** @@ -44,8 +45,9 @@ * @param suffix the suffix * @param key the key * @param complete the complete flag + * @param sort the sort flag */ - public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete) { + public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete, int sort) { this.value = Objects.requireNonNull(value); this.displ = Objects.requireNonNull(displ); this.group = group; @@ -53,6 +55,22 @@ this.suffix = suffix; this.key = key; this.complete = complete; + this.sort = sort; + } + + /** + * Constructs a new Candidate. + * + * @param value the value + * @param displ the display string + * @param group the group + * @param descr the description + * @param suffix the suffix + * @param key the key + * @param complete the complete flag + */ + public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete) { + this(value, displ, group, descr, suffix, key, complete, 0); } /** @@ -133,9 +151,36 @@ return complete; } + /** + * Integer used to override default sort logic. + * @return the sort int + */ + public int sort() { + return sort; + } + + @Override public int compareTo(Candidate o) { - return value.compareTo(o.value); + // If both candidates have same sort, use default behavior + if( sort == o.sort() ) { + return value.compareTo(o.value); + } else { + return Integer.compare(sort, o.sort()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Candidate candidate = (Candidate) o; + return Objects.equals(value, candidate.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); } @Override diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java 2023-07-05 07:11:54.000000000 +0000 @@ -10,7 +10,7 @@ /** * An extension of {@link ParsedLine} that, being aware of the quoting and escaping rules - * of the {@link org.jline.reader.Parser} that produced it, knows if and how a completion candidate + * of the {@link jdk.internal.org.jline.reader.Parser} that produced it, knows if and how a completion candidate * should be escaped/quoted. * * @author Eric Bottard diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java 2023-07-05 07:11:54.000000000 +0000 @@ -29,7 +29,7 @@ /** * * @param candidates list of candidates - * @return a map of candidates that completion matcher matches + * @return a list of candidates that completion matcher matches */ List matches(List candidates); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -14,7 +14,28 @@ public interface Highlighter { + /** + * Highlight buffer + * @param reader LineReader + * @param buffer the buffer to be highlighted + * @return highlighted buffer + */ AttributedString highlight(LineReader reader, String buffer); - public void setErrorPattern(Pattern errorPattern); - public void setErrorIndex(int errorIndex); + + /** + * Refresh highlight configuration + */ + default void refresh(LineReader reader) {} + + /** + * Set error pattern to be highlighted + * @param errorPattern error pattern to be highlighted + */ + void setErrorPattern(Pattern errorPattern); + + /** + * Set error index to be highlighted + * @param errorIndex error index to be highlighted + */ + void setErrorIndex(int errorIndex); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java 2023-07-05 07:11:54.000000000 +0000 @@ -61,12 +61,13 @@ void append(Path file, boolean incremental) throws IOException; /** - * Read history from the file. If incremental only the events that are not contained within the internal list are added. + * Read history from the file. If checkDuplicates is true only the events that + * are not contained within the internal list are added. * @param file History file - * @param incremental If true incremental read operation is performed. + * @param checkDuplicates If true, duplicate history entries will be discarded * @throws IOException if a problem occurs */ - void read(Path file, boolean incremental) throws IOException; + void read(Path file, boolean checkDuplicates) throws IOException; /** * Purge history. diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java 2023-07-05 07:11:54.000000000 +0000 @@ -41,7 +41,7 @@ * @author Marc Prud'hommeaux * @author Jason Dillon * @since 2.3 - * @deprecated use org.jline.builtins.Completers$FileNameCompleter instead + * @deprecated use jdk.internal.org.jline.builtins.Completers$FileNameCompleter instead */ @Deprecated public class FileNameCompleter implements Completer diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java 2023-07-05 07:11:54.000000000 +0000 @@ -67,7 +67,7 @@ if (cmd != null) { if (completers.containsKey(cmd)) { out = cmd; - } else if (aliasCommand.containsKey(cmd)) { + } else { out = aliasCommand.get(cmd); } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -54,7 +54,7 @@ break; } } - return !matching.isEmpty() ? matching.entrySet().stream().flatMap(e -> e.getValue().stream()).collect(Collectors.toList()) + return !matching.isEmpty() ? matching.entrySet().stream().flatMap(e -> e.getValue().stream()).distinct().collect(Collectors.toList()) : new ArrayList<>(); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java 2023-07-05 07:11:54.000000000 +0000 @@ -27,6 +27,27 @@ ANGLE // <> } + public static class BlockCommentDelims { + private final String start; + private final String end; + public BlockCommentDelims(String start, String end) { + if (start == null || end == null + || start.isEmpty() || end.isEmpty() || start.equals(end)) { + throw new IllegalArgumentException("Bad block comment delimiter!"); + } + this.start = start; + this.end = end; + } + + public String getStart() { + return start; + } + + public String getEnd() { + return end; + } + } + private char[] quoteChars = {'\'', '"'}; private char[] escapeChars = {'\\'}; @@ -39,6 +60,10 @@ private char[] closingBrackets = null; + private String[] lineCommentDelims = null; + + private BlockCommentDelims blockCommentDelims = null; + private String regexVariable = "[a-zA-Z_]+[a-zA-Z0-9_-]*((\\.|\\['|\\[\"|\\[)[a-zA-Z0-9_-]*(|']|\"]|]))?"; private String regexCommand = "[:]?[a-zA-Z]+[a-zA-Z0-9_-]*"; private int commandGroup = 4; @@ -47,6 +72,16 @@ // Chainable setters // + public DefaultParser lineCommentDelims(final String[] lineCommentDelims) { + this.lineCommentDelims = lineCommentDelims; + return this; + } + + public DefaultParser blockCommentDelims(final BlockCommentDelims blockCommentDelims) { + this.blockCommentDelims = blockCommentDelims; + return this; + } + public DefaultParser quoteChars(final char[] chars) { this.quoteChars = chars; return this; @@ -107,6 +142,22 @@ return this.escapeChars; } + public void setLineCommentDelims(String[] lineCommentDelims) { + this.lineCommentDelims = lineCommentDelims; + } + + public String[] getLineCommentDelims() { + return this.lineCommentDelims; + } + + public void setBlockCommentDelims(BlockCommentDelims blockCommentDelims) { + this.blockCommentDelims = blockCommentDelims; + } + + public BlockCommentDelims getBlockCommentDelims() { + return blockCommentDelims; + } + public void setEofOnUnclosedQuote(boolean eofOnUnclosedQuote) { this.eofOnUnclosedQuote = eofOnUnclosedQuote; } @@ -225,6 +276,11 @@ int rawWordStart = 0; BracketChecker bracketChecker = new BracketChecker(cursor); boolean quotedWord = false; + boolean lineCommented = false; + boolean blockCommented = false; + boolean blockCommentInRightOrder = true; + final String blockCommentEnd = blockCommentDelims == null ? null : blockCommentDelims.end; + final String blockCommentStart = blockCommentDelims == null ? null : blockCommentDelims.start; for (int i = 0; (line != null) && (i < line.length()); i++) { // once we reach the cursor, set the @@ -237,7 +293,7 @@ rawWordCursor = i - rawWordStart; } - if (quoteStart < 0 && isQuoteChar(line, i)) { + if (quoteStart < 0 && isQuoteChar(line, i) && !lineCommented && !blockCommented) { // Start a quote block quoteStart = i; if (current.length()==0) { @@ -258,17 +314,40 @@ quoteStart = -1; quotedWord = false; } else if (quoteStart < 0 && isDelimiter(line, i)) { - // Delimiter - if (current.length() > 0) { - words.add(current.toString()); - current.setLength(0); // reset the arg - if (rawWordCursor >= 0 && rawWordLength < 0) { - rawWordLength = i - rawWordStart; + if (lineCommented) { + if (isCommentDelim(line, i, System.lineSeparator())) { + lineCommented = false; + } + } else if (blockCommented) { + if (isCommentDelim(line, i, blockCommentEnd)) { + blockCommented = false; } + } else { + // Delimiter + rawWordLength = handleDelimiterAndGetRawWordLength(current, words, rawWordStart, rawWordCursor, rawWordLength, i); + rawWordStart = i + 1; } - rawWordStart = i + 1; } else { - if (!isEscapeChar(line, i)) { + if (quoteStart < 0 && !blockCommented && (lineCommented || isLineCommentStarted(line, i))) { + lineCommented = true; + } else if (quoteStart < 0 && !lineCommented + && (blockCommented || isCommentDelim(line, i, blockCommentStart))) { + if (blockCommented) { + if (blockCommentEnd != null && isCommentDelim(line, i, blockCommentEnd)) { + blockCommented = false; + i += blockCommentEnd.length() - 1; + } + } else { + blockCommented = true; + rawWordLength = handleDelimiterAndGetRawWordLength(current, words, rawWordStart, rawWordCursor, rawWordLength, i); + i += blockCommentStart == null ? 0 : blockCommentStart.length() - 1; + rawWordStart = i + 1; + } + } else if (quoteStart < 0 && !lineCommented + && isCommentDelim(line, i, blockCommentEnd)) { + current.append(line.charAt(i)); + blockCommentInRightOrder = false; + } else if (!isEscapeChar(line, i)) { current.append(line.charAt(i)); if (quoteStart < 0) { bracketChecker.check(line, i); @@ -301,6 +380,14 @@ throw new EOFError(-1, -1, "Missing closing quote", line.charAt(quoteStart) == '\'' ? "quote" : "dquote"); } + if (blockCommented) { + throw new EOFError(-1, -1, "Missing closing block comment delimiter", + "add: " + blockCommentEnd); + } + if (!blockCommentInRightOrder) { + throw new EOFError(-1, -1, "Missing opening block comment delimiter", + "missing: " + blockCommentStart); + } if (bracketChecker.isClosingBracketMissing() || bracketChecker.isOpeningBracketMissing()) { String message = null; String missing = null; @@ -333,6 +420,17 @@ return !isQuoted(buffer, pos) && !isEscaped(buffer, pos) && isDelimiterChar(buffer, pos); } + private int handleDelimiterAndGetRawWordLength(StringBuilder current, List words, int rawWordStart, int rawWordCursor, int rawWordLength, int pos) { + if (current.length() > 0) { + words.add(current.toString()); + current.setLength(0); // reset the arg + if (rawWordCursor >= 0 && rawWordLength < 0) { + return pos - rawWordStart; + } + } + return rawWordLength; + } + public boolean isQuoted(final CharSequence buffer, final int pos) { return false; } @@ -348,6 +446,36 @@ } } } + return false; + } + + private boolean isCommentDelim(final CharSequence buffer, final int pos, final String pattern) { + if (pos < 0) { + return false; + } + + if (pattern != null) { + final int length = pattern.length(); + if (length <= buffer.length() - pos) { + for (int i = 0; i < length; i++) { + if (pattern.charAt(i) != buffer.charAt(pos + i)) { + return false; + } + } + return true; + } + } + return false; + } + + public boolean isLineCommentStarted(final CharSequence buffer, final int pos) { + if (lineCommentDelims != null) { + for (String comment: lineCommentDelims) { + if (isCommentDelim(buffer, pos, comment)) { + return true; + } + } + } return false; } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java 2023-07-05 07:11:54.000000000 +0000 @@ -97,14 +97,14 @@ } @Override - public void read(Path file, boolean incremental) throws IOException { + public void read(Path file, boolean checkDuplicates) throws IOException { Path path = file != null ? file : getPath(); if (path != null) { try { if (Files.exists(path)) { Log.trace("Reading history from: ", path); try (BufferedReader reader = Files.newBufferedReader(path)) { - reader.lines().forEach(line -> addHistoryLine(path, line, incremental)); + reader.lines().forEach(line -> addHistoryLine(path, line, checkDuplicates)); setHistoryFileData(path, new HistoryFileData(items.size(), offset + items.size())); maybeResize(); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2022, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -281,7 +281,7 @@ int candidateStartPosition = 0; public LineReaderImpl(Terminal terminal) throws IOException { - this(terminal, null, null); + this(terminal, terminal.getName(), null); } public LineReaderImpl(Terminal terminal, String appName) throws IOException { @@ -633,7 +633,8 @@ callWidget(CALLBACK_INIT); - undo.newState(buf.copy()); + if (!isSet(Option.DISABLE_UNDO)) + undo.newState(buf.copy()); // Draw initial prompt redrawLine(); @@ -679,7 +680,7 @@ if (!w.apply()) { beep(); } - if (!isUndo && copy != null && buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) + if (!isSet(Option.DISABLE_UNDO) && !isUndo && copy != null && buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) && !copy.toString().equals(buf.toString())) { undo.newState(buf.copy()); } @@ -739,8 +740,8 @@ } } finally { lock.unlock(); + startedReading.set(false); } - startedReading.set(false); } } @@ -1082,18 +1083,18 @@ if (isSet(Option.BRACKETED_PASTE)) { terminal.writer().write(BRACKETED_PASTE_OFF); } - Constructor ctor = Class.forName("org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); + Constructor ctor = Class.forName("jdk.internal.org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); Editor editor = (Editor) ctor.newInstance(terminal, new File(file.getParent())); editor.setRestricted(true); editor.open(Collections.singletonList(file.getName())); editor.run(); - BufferedReader br = new BufferedReader(new FileReader(file)); - String line; - commandsBuffer.clear(); - while ((line = br.readLine()) != null) { - commandsBuffer.add(line); + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String line; + commandsBuffer.clear(); + while ((line = br.readLine()) != null) { + commandsBuffer.add(line); + } } - br.close(); } // @@ -3595,9 +3596,9 @@ File file = null; try { file = File.createTempFile("jline-execute-", null); - FileWriter writer = new FileWriter(file); - writer.write(buf.toString()); - writer.close(); + try (FileWriter writer = new FileWriter(file)) { + writer.write(buf.toString()); + } editAndAddInBuffer(file); } catch (Exception e) { e.printStackTrace(terminal.writer()); @@ -3796,6 +3797,9 @@ Status status = Status.getStatus(terminal, false); if (status != null) { + if (terminal.getType().startsWith(AbstractWindowsTerminal.TYPE_WINDOWS)) { + status.resize(); + } status.redraw(); } @@ -3947,7 +3951,8 @@ StringBuilder sb = new StringBuilder(); for (char c: buffer.replace("\\", "\\\\").toCharArray()) { if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '*' - || c == '$' || c == '.' || c == '?' || c == '+') { + || c == '$' || c == '.' || c == '?' || c == '+' || c == '|' || c == '<' || c == '>' || c == '!' + || c == '-') { sb.append('\\'); } sb.append(c); @@ -4520,7 +4525,7 @@ } } - private CompletingParsedLine wrap(ParsedLine line) { + protected static CompletingParsedLine wrap(ParsedLine line) { if (line instanceof CompletingParsedLine) { return (CompletingParsedLine) line; } else { @@ -4625,6 +4630,11 @@ return size.getRows() - (status != null ? status.size() : 0); } + private int visibleDisplayRows() { + Status status = Status.getStatus(terminal, false); + return terminal.getSize().getRows() - (status != null ? status.size() : 0); + } + private int promptLines() { AttributedString text = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); return text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); @@ -5070,18 +5080,19 @@ protected PostResult computePost(List possible, Candidate selection, List ordered, String completed, Function wcwidth, int width, boolean autoGroup, boolean groupName, boolean rowsFirst) { List strings = new ArrayList<>(); + boolean customOrder = possible.stream().anyMatch(c -> c.sort() != 0); if (groupName) { Comparator groupComparator = getGroupComparator(); - Map> sorted; + Map> sorted; sorted = groupComparator != null ? new TreeMap<>(groupComparator) : new LinkedHashMap<>(); for (Candidate cand : possible) { String group = cand.group(); sorted.computeIfAbsent(group != null ? group : "", s -> new LinkedHashMap<>()) - .put(cand.value(), cand); + .put((customOrder ? cand.sort() : cand.value()), cand); } - for (Map.Entry> entry : sorted.entrySet()) { + for (Map.Entry> entry : sorted.entrySet()) { String group = entry.getKey(); if (group.isEmpty() && sorted.size() > 1) { group = getOthersGroupName(); @@ -5096,13 +5107,13 @@ } } else { Set groups = new LinkedHashSet<>(); - TreeMap sorted = new TreeMap<>(); + TreeMap sorted = new TreeMap<>(); for (Candidate cand : possible) { String group = cand.group(); if (group != null) { groups.add(group); } - sorted.put(cand.value(), cand); + sorted.put((customOrder ? cand.sort() : cand.value()), cand); } if (autoGroup) { strings.addAll(groups); @@ -5129,7 +5140,7 @@ this.startPos = startPos; endLine = line.substring(line.lastIndexOf('\n') + 1); boolean first = true; - while (endLine.length() + (first ? startPos : 0) > width) { + while (endLine.length() + (first ? startPos : 0) > width && width > 0) { if (first) { endLine = endLine.substring(width - startPos); } else { @@ -5207,7 +5218,7 @@ AttributedStringBuilder sb = new AttributedStringBuilder(); if (listSize > 0) { if (isSet(Option.AUTO_MENU_LIST) - && listSize < Math.min(getInt(MENU_LIST_MAX, DEFAULT_MENU_LIST_MAX), displayRows() - promptLines())) { + && listSize < Math.min(getInt(MENU_LIST_MAX, DEFAULT_MENU_LIST_MAX), visibleDisplayRows() - promptLines())) { maxWidth = Math.max(maxWidth, MENU_LIST_WIDTH); sb.tabs(Math.max(Math.min(candidateStartPosition, width - maxWidth - 1), 1)); width = maxWidth + 2; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java 2023-07-05 07:11:54.000000000 +0000 @@ -118,6 +118,12 @@ throw new IOError(e); } } + + String appName = this.appName; + if (null == appName) { + appName = terminal.getName(); + } + LineReaderImpl reader = new LineReaderImpl(terminal, appName, variables); if (history != null) { reader.setHistory(history); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java 2023-07-05 07:11:54.000000000 +0000 @@ -352,7 +352,7 @@ String AMBIGUOUS_BINDING = "ambiguous-binding"; /** - * Columns separated list of patterns that will not be saved in history. + * Colon separated list of patterns that will not be saved in history. */ String HISTORY_IGNORE = "history-ignore"; @@ -467,6 +467,9 @@ /** Show command options tab completion candidates for zero length word */ EMPTY_WORD_OPTIONS(true), + + /** Disable the undo feature */ + DISABLE_UNDO ; private final boolean def; @@ -699,7 +702,7 @@ void runMacro(String macro); /** - * Read a mouse event when the {@link org.jline.utils.InfoCmp.Capability#key_mouse} sequence + * Read a mouse event when the {@link jdk.internal.org.jline.utils.InfoCmp.Capability#key_mouse} sequence * has just been read on the input stream. * Compared to {@link Terminal#readMouseEvent()}, this method takes into account keys * that have been pushed back using {@link #runMacro(String)}. diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -12,8 +12,8 @@ import java.util.regex.Pattern; public interface Parser { - static final String REGEX_VARIABLE = "[a-zA-Z_]{1,}[a-zA-Z0-9_-]*"; - static final String REGEX_COMMAND = "[:]{0,1}[a-zA-Z]{1,}[a-zA-Z0-9_-]*"; + String REGEX_VARIABLE = "[a-zA-Z_]+[a-zA-Z0-9_-]*"; + String REGEX_COMMAND = "[:]?[a-zA-Z]+[a-zA-Z0-9_-]*"; ParsedLine parse(String line, int cursor, ParseContext context) throws SyntaxError; @@ -34,7 +34,7 @@ } default String getCommand(final String line) { - String out = ""; + String out; Pattern patternCommand = Pattern.compile("^\\s*" + REGEX_VARIABLE + "=(" + REGEX_COMMAND + ")(\\s+|$)"); Matcher matcher = patternCommand.matcher(line); if (matcher.find()) { @@ -68,7 +68,7 @@ /** Parsed words will have all characters present in input line * including quotes and escape chars. - * May throw EOFError in which case we have incomplete input. + * We should tolerate and ignore errors. */ SPLIT_LINE, diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java 2023-07-05 07:11:54.000000000 +0000 @@ -86,11 +86,6 @@ } } - @Override - public int readBuffered(byte[] b) throws IOException { - return in.read(b); - } - private void setNonBlocking() { if (current == null || current.getControlChar(Attributes.ControlChar.VMIN) != 0 diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java 2023-07-05 07:11:54.000000000 +0000 @@ -81,8 +81,8 @@ protected boolean focusTracking = false; private volatile boolean closing; - public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, Function inputStreamWrapper) throws IOException { - super(name, type, selectCharset(encoding, codepage), signalHandler); + public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, Function inputStreamWrapper) throws IOException { + super(name, type, encoding, signalHandler); NonBlockingPumpReader reader = NonBlocking.nonBlockingPumpReader(); this.slaveInputPipe = reader.getWriter(); this.input = inputStreamWrapper.apply(NonBlocking.nonBlockingStream(reader, encoding())); @@ -116,35 +116,6 @@ } } - private static Charset selectCharset(Charset encoding, int codepage) { - if (encoding != null) { - return encoding; - } - - if (codepage >= 0) { - return getCodepageCharset(codepage); - } - - // Use UTF-8 as default - return StandardCharsets.UTF_8; - } - - private static Charset getCodepageCharset(int codepage) { - //http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html - if (codepage == UTF8_CODE_PAGE) { - return StandardCharsets.UTF_8; - } - String charsetMS = "ms" + codepage; - if (Charset.isSupported(charsetMS)) { - return Charset.forName(charsetMS); - } - String charsetCP = "cp" + codepage; - if (Charset.isSupported(charsetCP)) { - return Charset.forName(charsetCP); - } - return Charset.defaultCharset(); - } - @Override public SignalHandler handle(Signal signal, SignalHandler handler) { SignalHandler prev = super.handle(signal, handler); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2022, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl; + +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.ServiceLoader; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.TimeUnit; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.OSUtils; + +public class Diag { + + public static void main(String[] args) { + diag(System.out); + } + + static void diag(PrintStream out) { + out.println("System properties"); + out.println("================="); + out.println("os.name = " + System.getProperty("os.name")); + out.println("OSTYPE = " + System.getenv("OSTYPE")); + out.println("MSYSTEM = " + System.getenv("MSYSTEM")); + out.println("PWD = " + System.getenv("PWD")); + out.println("ConEmuPID = " + System.getenv("ConEmuPID")); + out.println("WSL_DISTRO_NAME = " + System.getenv("WSL_DISTRO_NAME")); + out.println("WSL_INTEROP = " + System.getenv("WSL_INTEROP")); + out.println(); + + out.println("OSUtils"); + out.println("================="); + out.println("IS_WINDOWS = " + OSUtils.IS_WINDOWS); + out.println("IS_CYGWIN = " + OSUtils.IS_CYGWIN); + out.println("IS_MSYSTEM = " + OSUtils.IS_MSYSTEM); + out.println("IS_WSL = " + OSUtils.IS_WSL); + out.println("IS_WSL1 = " + OSUtils.IS_WSL1); + out.println("IS_WSL2 = " + OSUtils.IS_WSL2); + out.println("IS_CONEMU = " + OSUtils.IS_CONEMU); + out.println("IS_OSX = " + OSUtils.IS_OSX); + out.println(); + + out.println("JnaSupport"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("jna"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("JNA support not available: " + t); + } + out.println(); + + out.println("JansiSupport"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("jansi"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("Jansi support not available: " + t); + } + out.println(); + + // Exec + out.println("Exec Support"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("exec"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("Exec support not available: " + t); + } + } + + private static void testProvider(PrintStream out, TerminalProvider provider) { + try { + out.println("StdIn stream = " + provider.isSystemStream(TerminalProvider.Stream.Input)); + out.println("StdOut stream = " + provider.isSystemStream(TerminalProvider.Stream.Output)); + out.println("StdErr stream = " + provider.isSystemStream(TerminalProvider.Stream.Error)); + } catch (Throwable t2) { + out.println("Unable to check stream: " + t2); + } + try { + out.println("StdIn stream name = " + provider.systemStreamName(TerminalProvider.Stream.Input)); + out.println("StdOut stream name = " + provider.systemStreamName(TerminalProvider.Stream.Output)); + out.println("StdErr stream name = " + provider.systemStreamName(TerminalProvider.Stream.Error)); + } catch (Throwable t2) { + out.println("Unable to check stream names: " + t2); + } + try (Terminal terminal = provider.sysTerminal("diag", "xterm", false, StandardCharsets.UTF_8, + false, Terminal.SignalHandler.SIG_DFL, false, TerminalProvider.Stream.Output, input -> input) ) { + if (terminal != null) { + Attributes attr = terminal.enterRawMode(); + try { + out.println("Terminal size: " + terminal.getSize()); + ForkJoinTask t = new ForkJoinPool(1).submit(() -> terminal.reader().read(1) ); + int r = t.get(1000, TimeUnit.MILLISECONDS); + StringBuilder sb = new StringBuilder(); + sb.append("The terminal seems to work: "); + sb.append("terminal ").append(terminal.getClass().getName()); + if (terminal instanceof AbstractPosixTerminal) { + sb.append(" with pty ").append(((AbstractPosixTerminal) terminal).getPty().getClass().getName()); + } + out.println(sb); + } catch (Throwable t3) { + out.println("Unable to read from terminal: " + t3); + t3.printStackTrace(); + } finally { + terminal.setAttributes(attr); + } + } else { + out.println("Not supported by provider"); + } + } catch (Throwable t2) { + out.println("Unable to open terminal: " + t2); + t2.printStackTrace(); + } + } + + static S load(Class clazz) { + return ServiceLoader.load(clazz, clazz.getClassLoader()).iterator().next(); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2022, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.exec; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.util.function.Function; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.impl.ExecPty; +import jdk.internal.org.jline.terminal.impl.ExternalTerminal; +import jdk.internal.org.jline.terminal.impl.PosixSysTerminal; +import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.ExecHelper; +import jdk.internal.org.jline.utils.OSUtils; + +public class ExecTerminalProvider implements TerminalProvider +{ + + public String name() { + return "exec"; + } + + public Pty current(Stream consoleStream) throws IOException { + return ExecPty.current(consoleStream); + } + + @Override + public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper) throws IOException { + if (OSUtils.IS_WINDOWS) { + return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper ); + } else { + return posixSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper ); + } + } + + public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper ) throws IOException { + if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { + Pty pty = current(consoleStream); + return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper); + } else { + return null; + } + } + + public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper) throws IOException { + Pty pty = current(consoleStream); + return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper); + } + + @Override + public Terminal newTerminal(String name, String type, InputStream in, OutputStream out, + Charset encoding, Terminal.SignalHandler signalHandler, boolean paused, + Attributes attributes, Size size) throws IOException + { + return new ExternalTerminal(name, type, in, out, encoding, signalHandler, paused, attributes, size); + } + + @Override + public boolean isSystemStream(Stream stream) { + try { + return isWindowsSystemStream(stream) || isPosixSystemStream(stream); + } catch (Throwable t) { + return false; + } + } + + public boolean isWindowsSystemStream(Stream stream) { + return systemStreamName( stream ) != null; + } + + public boolean isPosixSystemStream(Stream stream) { + try { + Process p = new ProcessBuilder(OSUtils.TEST_COMMAND, "-t", Integer.toString(stream.ordinal())) + .inheritIO().start(); + return p.waitFor() == 0; + } catch (Throwable t) { + // ignore + } + return false; + } + + @Override + public String systemStreamName(Stream stream) { + try { + ProcessBuilder.Redirect input = stream == Stream.Input + ? ProcessBuilder.Redirect.INHERIT + : getRedirect(stream == Stream.Output ? FileDescriptor.out : FileDescriptor.err); + Process p = new ProcessBuilder(OSUtils.TTY_COMMAND).redirectInput(input).start(); + String result = ExecHelper.waitAndCapture(p); + if (p.exitValue() == 0) { + return result.trim(); + } + } catch (Throwable t) { + // ignore + } + return null; + } + + private ProcessBuilder.Redirect getRedirect(FileDescriptor fd) throws ReflectiveOperationException { + // This is not really allowed, but this is the only way to redirect the output or error stream + // to the input. This is definitely not something you'd usually want to do, but in the case of + // the `tty` utility, it provides a way to get + Class rpi = Class.forName("java.lang.ProcessBuilder$RedirectPipeImpl"); + Constructor cns = rpi.getDeclaredConstructor(); + cns.setAccessible(true); + ProcessBuilder.Redirect input = (ProcessBuilder.Redirect) cns.newInstance(); + Field f = rpi.getDeclaredField("fd"); + f.setAccessible(true); + f.set(input, fd); + return input; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java 2023-07-05 07:11:54.000000000 +0000 @@ -26,6 +26,7 @@ import jdk.internal.org.jline.terminal.Attributes.LocalFlag; import jdk.internal.org.jline.terminal.Attributes.OutputFlag; import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.terminal.spi.Pty; import jdk.internal.org.jline.utils.OSUtils; @@ -34,20 +35,23 @@ public class ExecPty extends AbstractPty implements Pty { private final String name; - private final boolean system; + private final TerminalProvider.Stream console; - public static Pty current() throws IOException { + public static Pty current(TerminalProvider.Stream console) throws IOException { try { String result = exec(true, OSUtils.TTY_COMMAND); - return new ExecPty(result.trim(), true); + if (console != TerminalProvider.Stream.Output && console != TerminalProvider.Stream.Error) { + throw new IllegalArgumentException("console should be Output or Error: " + console); + } + return new ExecPty(result.trim(), console); } catch (IOException e) { throw new IOException("Not a tty", e); } } - protected ExecPty(String name, boolean system) { + protected ExecPty(String name, TerminalProvider.Stream console) { this.name = name; - this.system = system; + this.console = console; } @Override @@ -70,16 +74,18 @@ @Override protected InputStream doGetSlaveInput() throws IOException { - return system + return console != null ? new FileInputStream(FileDescriptor.in) : new FileInputStream(getName()); } @Override public OutputStream getSlaveOutput() throws IOException { - return system + return console == TerminalProvider.Stream.Output ? new FileOutputStream(FileDescriptor.out) - : new FileOutputStream(getName()); + : console == TerminalProvider.Stream.Error + ? new FileOutputStream(FileDescriptor.err) + : new FileOutputStream(getName()); } @Override @@ -93,23 +99,11 @@ List commands = getFlagsToSet(attr, getAttr()); if (!commands.isEmpty()) { commands.add(0, OSUtils.STTY_COMMAND); - if (!system) { + if (console == null) { commands.add(1, OSUtils.STTY_F_OPTION); commands.add(2, getName()); } - try { - exec(system, commands.toArray(new String[commands.size()])); - } catch (IOException e) { - // Handle partial failures with GNU stty, see #97 - if (e.toString().contains("unable to perform all requested operations")) { - commands = getFlagsToSet(attr, getAttr()); - if (!commands.isEmpty()) { - throw new IOException("Could not set the following flags: " + String.join(", ", commands), e); - } - } else { - throw e; - } - } + exec(console != null, commands.toArray(new String[0])); } } @@ -171,7 +165,7 @@ } protected String doGetConfig() throws IOException { - return system + return console != null ? exec(true, OSUtils.STTY_COMMAND, "-a") : exec(false, OSUtils.STTY_COMMAND, OSUtils.STTY_F_OPTION, getName(), "-a"); } @@ -280,7 +274,7 @@ @Override public void setSize(Size size) throws IOException { - if (system) { + if (console != null) { exec(true, OSUtils.STTY_COMMAND, "columns", Integer.toString(size.getColumns()), @@ -296,7 +290,7 @@ @Override public String toString() { - return "ExecPty[" + getName() + (system ? ", system]" : "]"); + return "ExecPty[" + getName() + (console != null ? ", system]" : "]"); } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java 2023-07-05 07:11:54.000000000 +0000 @@ -15,7 +15,6 @@ import java.io.PrintWriter; import java.nio.charset.Charset; import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; import jdk.internal.org.jline.terminal.spi.Pty; import jdk.internal.org.jline.utils.ClosedException; @@ -143,10 +142,10 @@ } } - private class InputStreamWrapper extends NonBlockingInputStream { + private static class InputStreamWrapper extends NonBlockingInputStream { private final NonBlockingInputStream in; - private final AtomicBoolean closed = new AtomicBoolean(); + private volatile boolean closed; protected InputStreamWrapper(NonBlockingInputStream in) { this.in = in; @@ -154,7 +153,7 @@ @Override public int read(long timeout, boolean isPeek) throws IOException { - if (closed.get()) { + if (closed) { throw new ClosedException(); } return in.read(timeout, isPeek); @@ -162,7 +161,7 @@ @Override public void close() throws IOException { - closed.set(true); + closed = true; } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java 2023-07-05 07:11:54.000000000 +0000 @@ -16,6 +16,7 @@ import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import jdk.internal.org.jline.utils.NonBlocking; import jdk.internal.org.jline.terminal.spi.Pty; @@ -34,11 +35,12 @@ protected final Map nativeHandlers = new HashMap<>(); protected final Task closer; - public PosixSysTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding, - boolean nativeSignals, SignalHandler signalHandler) throws IOException { + public PosixSysTerminal(String name, String type, Pty pty, Charset encoding, + boolean nativeSignals, SignalHandler signalHandler, + Function inputStreamWrapper) throws IOException { super(name, type, pty, encoding, signalHandler); - this.input = NonBlocking.nonBlocking(getName(), in); - this.output = out; + this.input = NonBlocking.nonBlocking(getName(), inputStreamWrapper.apply(pty.getSlaveInput())); + this.output = pty.getSlaveOutput(); this.reader = NonBlocking.nonBlocking(getName(), input, encoding()); this.writer = new PrintWriter(new OutputStreamWriter(output, encoding())); parseInfoCmp(); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.spi; - -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.Terminal; - -import java.io.IOException; -import java.nio.charset.Charset; - -public interface JansiSupport { - - Pty current() throws IOException; - - Pty open(Attributes attributes, Size size) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException; - - boolean isWindowsConsole(); - - boolean isConsoleOutput(); - - boolean isConsoleInput(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.spi; - -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.Terminal; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.function.Function; - -public interface JnaSupport { - - Pty current() throws IOException; - - Pty open(Attributes attributes, Size size) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, Function inputStreamWrapper) throws IOException; - - boolean isWindowsConsole(); - - boolean isConsoleOutput(); - - boolean isConsoleInput(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.spi; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.Properties; +import java.util.ServiceLoader; +import java.util.function.Function; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.impl.exec.ExecTerminalProvider; + +public interface TerminalProvider +{ + + enum Stream { + Input, + Output, + Error + } + + String name(); + + Terminal sysTerminal(String name, String type, boolean ansiPassThrough, + Charset encoding, boolean nativeSignals, + Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper) throws IOException; + + Terminal newTerminal(String name, String type, + InputStream masterInput, OutputStream masterOutput, + Charset encoding, Terminal.SignalHandler signalHandler, + boolean paused, Attributes attributes, Size size) throws IOException; + + boolean isSystemStream(Stream stream); + + String systemStreamName(Stream stream); + + static TerminalProvider load(String name) throws IOException { + switch (name) { + case "exec": return new ExecTerminalProvider(); + case "jna": { + try { + return (TerminalProvider) Class.forName("jdk.internal.org.jline.terminal.impl.jna.JnaTerminalProvider").getConstructor().newInstance(); + } catch (ReflectiveOperationException t) { + throw new IOException(t); + } + } + } + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } + InputStream is = cl.getResourceAsStream( "META-INF/services/org/jline/terminal/provider/" + name); + if (is != null) { + Properties props = new Properties(); + try { + props.load(is); + String className = props.getProperty("class"); + if (className == null) { + throw new IOException("No class defined in terminal provider file " + name); + } + Class clazz = cl.loadClass( className ); + return (TerminalProvider) clazz.getConstructor().newInstance(); + } catch ( Exception e ) { + throw new IOException("Unable to load terminal provider " + name, e); + } + } else { + throw new IOException("Unable to find terminal provider " + name); + } + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -16,22 +16,24 @@ import java.io.OutputStream; import java.lang.reflect.Method; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.Optional; import java.util.ServiceLoader; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.internal.org.jline.terminal.impl.AbstractPosixTerminal; import jdk.internal.org.jline.terminal.impl.AbstractTerminal; +import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal; import jdk.internal.org.jline.terminal.impl.DumbTerminal; -import jdk.internal.org.jline.terminal.impl.ExecPty; -import jdk.internal.org.jline.terminal.impl.ExternalTerminal; -import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal; -import jdk.internal.org.jline.terminal.impl.PosixSysTerminal; -import jdk.internal.org.jline.terminal.spi.JansiSupport; -import jdk.internal.org.jline.terminal.spi.JnaSupport; -import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.Log; import jdk.internal.org.jline.utils.OSUtils; @@ -52,6 +54,11 @@ public static final String PROP_EXEC = "org.jline.terminal.exec"; public static final String PROP_DUMB = "org.jline.terminal.dumb"; public static final String PROP_DUMB_COLOR = "org.jline.terminal.dumb.color"; + public static final String PROP_OUTPUT = "org.jline.terminal.output"; + public static final String PROP_OUTPUT_OUT = "out"; + public static final String PROP_OUTPUT_ERR = "err"; + public static final String PROP_OUTPUT_OUT_ERR = "out-err"; + public static final String PROP_OUTPUT_ERR_OUT = "err-out"; // // Other system properties controlling various jline parts @@ -61,6 +68,16 @@ public static final String PROP_COLOR_DISTANCE = "org.jline.utils.colorDistance"; public static final String PROP_DISABLE_ALTERNATE_CHARSET = "org.jline.utils.disableAlternateCharset"; + // + // Terminal output control + // + public enum SystemOutput { + SysOut, + SysErr, + SysOutOrSysErr, + SysErrOrSysOut + } + /** * Returns the default system terminal. * Terminals should be closed properly using the {@link Terminal#close()} @@ -97,6 +114,7 @@ private Charset encoding; private int codepage; private Boolean system; + private SystemOutput systemOutput; private Boolean jna; private Boolean jansi; private Boolean exec; @@ -128,6 +146,20 @@ return this; } + /** + * Indicates which standard stream should be used when displaying to the terminal. + * The default is to use the system output stream. + * Building a system terminal will fail if one of the stream specified is not linked + * to the controlling terminal. + * + * @param systemOutput The mode to choose the output stream. + * @return The builder. + */ + public TerminalBuilder systemOutput(SystemOutput systemOutput) { + this.systemOutput = systemOutput; + return this; + } + public TerminalBuilder jna(boolean jna) { this.jna = jna; return this; @@ -298,11 +330,18 @@ encoding = Charset.forName(charsetName); } } - int codepage = this.codepage; - if (codepage <= 0) { - String str = System.getProperty(PROP_CODEPAGE); - if (str != null) { - codepage = Integer.parseInt(str); + if (encoding == null) { + int codepage = this.codepage; + if (codepage <= 0) { + String str = System.getProperty(PROP_CODEPAGE); + if (str != null) { + codepage = Integer.parseInt(str); + } + } + if (codepage >= 0) { + encoding = getCodepageCharset(codepage); + } else { + encoding = StandardCharsets.UTF_8; } } String type = this.type; @@ -328,102 +367,112 @@ if (dumb == null) { dumb = getBoolean(PROP_DUMB, null); } + IllegalStateException exception = new IllegalStateException("Unable to create a terminal"); + List providers = new ArrayList<>(); + if (jna) { + try { + TerminalProvider provider = TerminalProvider.load("jna"); + providers.add(provider); + } catch (Throwable t) { + Log.debug("Unable to load JNA support: ", t); + exception.addSuppressed(t); + } + } + if (jansi) { + try { + TerminalProvider provider = TerminalProvider.load("jansi"); + providers.add(provider); + } catch (Throwable t) { + Log.debug("Unable to load JANSI support: ", t); + exception.addSuppressed(t); + } + } + if (exec) + { + try { + TerminalProvider provider = TerminalProvider.load("exec"); + providers.add(provider); + } catch (Throwable t) { + Log.debug("Unable to load EXEC support: ", t); + exception.addSuppressed(t); + } + } + + Terminal terminal = null; if ((system != null && system) || (system == null && in == null && out == null)) { - if (system != null && ((in != null && !in.equals(System.in)) || (out != null && !out.equals(System.out)))) { + if (system != null && ((in != null && !in.equals(System.in)) || + (out != null && !out.equals(System.out) && !out.equals(System.err)))) { throw new IllegalArgumentException("Cannot create a system terminal using non System streams"); } - Terminal terminal = null; - IllegalStateException exception = new IllegalStateException("Unable to create a system terminal"); - TerminalBuilderSupport tbs = new TerminalBuilderSupport(jna, jansi); - if (tbs.isConsoleInput() && tbs.isConsoleOutput()) { + if (attributes != null || size != null) { + Log.warn("Attributes and size fields are ignored when creating a system terminal"); + } + if (out != null) { + if (out.equals(System.out)) { + systemOutput = SystemOutput.SysOut; + } else if (out.equals(System.err)) { + systemOutput = SystemOutput.SysErr; + } + } + if (systemOutput == null) { + String str = System.getProperty(PROP_OUTPUT); + if (str != null) { + switch (str.trim().toLowerCase(Locale.ROOT)) { + case PROP_OUTPUT_OUT: systemOutput = SystemOutput.SysOut; break; + case PROP_OUTPUT_ERR: systemOutput = SystemOutput.SysErr; break; + case PROP_OUTPUT_OUT_ERR: systemOutput = SystemOutput.SysOutOrSysErr; break; + case PROP_OUTPUT_ERR_OUT: systemOutput = SystemOutput.SysErrOrSysOut; break; + default: + Log.debug("Unsupported value for " + PROP_OUTPUT + ": " + str + ". Supported values are: " + + String.join(", ", PROP_OUTPUT_OUT, PROP_OUTPUT_ERR, PROP_OUTPUT_OUT_ERR,PROP_OUTPUT_ERR_OUT) + + "."); + } + } + } + if (systemOutput == null) { + systemOutput = SystemOutput.SysOutOrSysErr; + } + Map system = Stream.of(TerminalProvider.Stream.values()) + .collect(Collectors.toMap(stream -> stream, stream -> providers.stream().anyMatch(p -> p.isSystemStream(stream)))); + TerminalProvider.Stream console = select(system, systemOutput); + + if (system.get(TerminalProvider.Stream.Input) && console != null) { if (attributes != null || size != null) { Log.warn("Attributes and size fields are ignored when creating a system terminal"); } - if (OSUtils.IS_WINDOWS) { - if (!OSUtils.IS_CYGWIN && !OSUtils.IS_MSYSTEM) { - boolean ansiPassThrough = OSUtils.IS_CONEMU; - if (tbs.hasJnaSupport()) { - try { - terminal = tbs.getJnaSupport().winSysTerminal(name, type, ansiPassThrough, encoding, codepage - , nativeSignals, signalHandler, paused, inputStreamWrapper); - } catch (Throwable t) { - Log.debug("Error creating JNA based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - if (terminal == null && tbs.hasJansiSupport()) { - try { - terminal = tbs.getJansiSupport().winSysTerminal(name, type, ansiPassThrough, encoding, codepage - , nativeSignals, signalHandler, paused); - } catch (Throwable t) { - Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - } else if (exec) { - // - // Cygwin support - // - try { - // Cygwin defaults to XTERM, but actually supports 256 colors, - // so if the value comes from the environment, change it to xterm-256color - if ("xterm".equals(type) && this.type == null && System.getProperty(PROP_TYPE) == null) { - type = "xterm-256color"; - } - Pty pty = tbs.getExecPty(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); - } catch (IOException e) { - // Ignore if not a tty - Log.debug("Error creating EXEC based terminal: ", e.getMessage(), e); - exception.addSuppressed(e); - } - } - if (terminal == null && !jna && !jansi && (dumb == null || !dumb)) { - throw new IllegalStateException("Unable to create a system terminal. On windows, either " - + "JNA or JANSI library is required. Make sure to add one of those in the classpath."); - } - } else { - if (tbs.hasJnaSupport()) { - try { - Pty pty = tbs.getJnaSupport().current(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); - } catch (Throwable t) { - // ignore - Log.debug("Error creating JNA based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - if (terminal == null && tbs.hasJansiSupport()) { - try { - Pty pty = tbs.getJansiSupport().current(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); - } catch (Throwable t) { - Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - if (terminal == null && exec) { + boolean ansiPassThrough = OSUtils.IS_CONEMU; + // Cygwin defaults to XTERM, but actually supports 256 colors, + // so if the value comes from the environment, change it to xterm-256color + if ((OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) && "xterm".equals(type) + && this.type == null && System.getProperty(PROP_TYPE) == null) { + type = "xterm-256color"; + } + for ( TerminalProvider provider : providers) { + if (terminal == null) { try { - Pty pty = tbs.getExecPty(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); + terminal = provider.sysTerminal(name, type, ansiPassThrough, encoding, + nativeSignals, signalHandler, paused, console, inputStreamWrapper); } catch (Throwable t) { - // Ignore if not a tty - Log.debug("Error creating EXEC based terminal: ", t.getMessage(), t); + Log.debug("Error creating " + provider.name() + " based terminal: ", t.getMessage(), t); exception.addSuppressed(t); } } } - if (terminal instanceof AbstractTerminal) { - AbstractTerminal t = (AbstractTerminal) terminal; - if (SYSTEM_TERMINAL.compareAndSet(null, t)) { - t.setOnClose(() -> SYSTEM_TERMINAL.compareAndSet(t, null)); - } else { - exception.addSuppressed(new IllegalStateException("A system terminal is already running. " + - "Make sure to use the created system Terminal on the LineReaderBuilder if you're using one " + - "or that previously created system Terminals have been correctly closed.")); - terminal.close(); - terminal = null; - } + if (terminal == null && OSUtils.IS_WINDOWS && !jna && !jansi && (dumb == null || !dumb)) { + throw new IllegalStateException("Unable to create a system terminal. On windows, either " + + "JNA or JANSI library is required. Make sure to add one of those in the classpath."); + } + } + if (terminal instanceof AbstractTerminal) { + AbstractTerminal t = (AbstractTerminal) terminal; + if (SYSTEM_TERMINAL.compareAndSet(null, t)) { + t.setOnClose(() -> SYSTEM_TERMINAL.compareAndSet(t, null)); + } else { + exception.addSuppressed(new IllegalStateException("A system terminal is already running. " + + "Make sure to use the created system Terminal on the LineReaderBuilder if you're using one " + + "or that previously created system Terminals have been correctly closed.")); + terminal.close(); + terminal = null; } } if (terminal == null && (dumb == null || dumb)) { @@ -433,7 +482,8 @@ color = getBoolean(PROP_DUMB_COLOR, false); // detect emacs using the env variable if (!color) { - color = System.getenv("INSIDE_EMACS") != null; + String emacs = System.getenv("INSIDE_EMACS"); + color = emacs != null && emacs.contains("comint"); } // detect Intellij Idea if (!color) { @@ -441,12 +491,13 @@ color = command != null && command.contains("idea"); } if (!color) { - color = tbs.isConsoleOutput() && System.getenv("TERM") != null; + color = system.get(TerminalProvider.Stream.Output) && System.getenv("TERM") != null; } if (!color && dumb == null) { if (Log.isDebugEnabled()) { - Log.warn("input is tty: {}", tbs.isConsoleInput()); - Log.warn("output is tty: {}", tbs.isConsoleOutput()); + Log.warn("input is tty: {}", system.get(TerminalProvider.Stream.Input)); + Log.warn("output is tty: {}", system.get(TerminalProvider.Stream.Output)); + Log.warn("error is tty: {}", system.get(TerminalProvider.Stream.Error)); Log.warn("Creating a dumb terminal", exception); } else { Log.warn("Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)"); @@ -454,33 +505,49 @@ } } terminal = new DumbTerminal(name, color ? Terminal.TYPE_DUMB_COLOR : Terminal.TYPE_DUMB, - inputStreamWrapper.apply(new FileInputStream(FileDescriptor.in)), - new FileOutputStream(FileDescriptor.out), + new FileInputStream(FileDescriptor.in), + new FileOutputStream(console == TerminalProvider.Stream.Output ? FileDescriptor.out : FileDescriptor.err), encoding, signalHandler); } - if (terminal == null) { - throw exception; - } - return terminal; } else { - if (jna) { - try { - Pty pty = load(JnaSupport.class).open(attributes, size); - return new PosixPtyTerminal(name, type, pty, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused); - } catch (Throwable t) { - Log.debug("Error creating JNA based terminal: ", t.getMessage(), t); + for ( TerminalProvider provider : providers) { + if (terminal == null) { + try { + terminal = provider.newTerminal(name, type, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused, attributes, size); + } catch (Throwable t) { + Log.debug("Error creating " + provider.name() + " based terminal: ", t.getMessage(), t); + exception.addSuppressed(t); + } } } - if (jansi) { - try { - Pty pty = load(JansiSupport.class).open(attributes, size); - return new PosixPtyTerminal(name, type, pty, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused); - } catch (Throwable t) { - Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t); - } + } + if (terminal == null) { + throw exception; + } + return terminal; + } + + private TerminalProvider.Stream select(Map system, SystemOutput systemOutput) { + switch (systemOutput) { + case SysOut: + return select(system, TerminalProvider.Stream.Output); + case SysErr: + return select(system, TerminalProvider.Stream.Error); + case SysOutOrSysErr: + return select(system, TerminalProvider.Stream.Output, TerminalProvider.Stream.Error); + case SysErrOrSysOut: + return select(system, TerminalProvider.Stream.Error, TerminalProvider.Stream.Output); + } + return null; + } + + private static TerminalProvider.Stream select(Map system, TerminalProvider.Stream... streams) { + for (TerminalProvider.Stream s : streams) { + if (system.get(s)) { + return s; } - return new ExternalTerminal(name, type, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused, attributes, size); } + return null; } private static String getParentProcessCommand() { @@ -512,6 +579,24 @@ return ServiceLoader.load(clazz, clazz.getClassLoader()).iterator().next(); } + private static final int UTF8_CODE_PAGE = 65001; + + private static Charset getCodepageCharset(int codepage) { + //http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html + if (codepage == UTF8_CODE_PAGE) { + return StandardCharsets.UTF_8; + } + String charsetMS = "ms" + codepage; + if (Charset.isSupported(charsetMS)) { + return Charset.forName(charsetMS); + } + String charsetCP = "cp" + codepage; + if (Charset.isSupported(charsetCP)) { + return Charset.forName(charsetCP); + } + return Charset.defaultCharset(); + } + /** * Allows an application to override the result of {@link #build()}. The * intended use case is to allow a container or server application to control @@ -545,79 +630,4 @@ TERMINAL_OVERRIDE.set(terminal); } - private static class TerminalBuilderSupport { - private JansiSupport jansiSupport = null; - private JnaSupport jnaSupport = null; - private Pty pty = null; - private boolean consoleOutput; - - TerminalBuilderSupport(boolean jna, boolean jansi) { - if (jna) { - try { - jnaSupport = load(JnaSupport.class); - consoleOutput = jnaSupport.isConsoleOutput(); - } catch (Throwable e) { - jnaSupport = null; - Log.debug("jnaSupport.isConsoleOutput(): ", e); - } - } - if (jansi) { - try { - jansiSupport = load(JansiSupport.class); - consoleOutput = jansiSupport.isConsoleOutput(); - } catch (Throwable e) { - jansiSupport = null; - Log.debug("jansiSupport.isConsoleOutput(): ", e); - } - } - if (jnaSupport == null && jansiSupport == null) { - try { - pty = ExecPty.current(); - consoleOutput = true; - } catch (Exception e) { - Log.debug("ExecPty.current(): ", e); - } - } - } - - public boolean isConsoleOutput() { - return consoleOutput; - } - - public boolean isConsoleInput() { - if (pty != null) { - return true; - } else if (hasJnaSupport()) { - return jnaSupport.isConsoleInput(); - } else if (hasJansiSupport()) { - return jansiSupport.isConsoleInput(); - } else { - return false; - } - } - - public boolean hasJnaSupport() { - return jnaSupport != null; - } - - public boolean hasJansiSupport() { - return jansiSupport != null; - } - - public JnaSupport getJnaSupport() { - return jnaSupport; - } - - public JansiSupport getJansiSupport() { - return jansiSupport; - } - - public Pty getExecPty() throws IOException { - if (pty == null) { - pty = ExecPty.current(); - } - return pty; - } - - } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java 2023-07-05 07:11:54.000000000 +0000 @@ -534,7 +534,7 @@ H = 0; return H; } else { - throw new IllegalArgumentException("h outside assumed range 0..360: " + Double.toString(h)); + throw new IllegalArgumentException("h outside assumed range 0..360: " + h); } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java 2023-07-05 07:11:54.000000000 +0000 @@ -12,7 +12,7 @@ import java.io.IOError; import java.io.IOException; import java.io.StringWriter; -import java.util.Stack; +import java.util.ArrayDeque; /** * Curses helper methods. @@ -21,8 +21,8 @@ */ public final class Curses { - private static Object[] sv = new Object[26]; - private static Object[] dv = new Object[26]; + private static final Object[] sv = new Object[26]; + private static final Object[] dv = new Object[26]; private static final int IFTE_NONE = 0; private static final int IFTE_IF = 1; @@ -68,7 +68,7 @@ int length = str.length(); int ifte = IFTE_NONE; boolean exec = true; - Stack stack = new Stack<>(); + ArrayDeque stack = new ArrayDeque<>(); while (index < length) { char ch = str.charAt(index++); switch (ch) { @@ -197,7 +197,7 @@ int start = index; while (str.charAt(index++) != '}') ; if (exec) { - int v = Integer.valueOf(str.substring(start, index - 1)); + int v = Integer.parseInt(str.substring(start, index - 1)); stack.push(v); } break; @@ -470,7 +470,7 @@ } else if (pop instanceof Boolean) { return (Boolean) pop ? 1 : 0; } else { - return Integer.valueOf(pop.toString()); + return Integer.parseInt(pop.toString()); } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java 2023-07-05 07:11:54.000000000 +0000 @@ -187,7 +187,7 @@ int lineIndex = 0; int currentPos = 0; - int numLines = Math.max(oldLines.size(), newLines.size()); + int numLines = Math.min(rows, Math.max(oldLines.size(), newLines.size())); boolean wrapNeeded = false; while (lineIndex < numLines) { AttributedString oldLine = diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java 2023-07-05 07:11:54.000000000 +0000 @@ -503,7 +503,7 @@ public String[] getNames() { return getCapabilitiesByName().entrySet().stream() .filter(e -> e.getValue() == this) - .map(Map.Entry::getValue) + .map(Map.Entry::getKey) .toArray(String[]::new); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -123,20 +123,17 @@ notifyAll(); } - boolean isInfinite = (timeout <= 0L); - /* * So the thread is currently doing the reading for us. So * now we play the waiting game. */ - while (isInfinite || timeout > 0L) { - long start = System.currentTimeMillis (); - + Timeout t = new Timeout(timeout); + while (!t.elapsed()) { try { if (Thread.interrupted()) { throw new InterruptedException(); } - wait(timeout); + wait(t.timeout()); } catch (InterruptedException e) { exception = (IOException) new InterruptedIOException().initCause(e); @@ -155,10 +152,6 @@ assert exception == null; break; } - - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java 2023-07-05 07:11:54.000000000 +0000 @@ -79,12 +79,34 @@ } public int readBuffered(byte[] b) throws IOException { + return readBuffered(b, 0L); + } + + public int readBuffered(byte[] b, long timeout) throws IOException { + return readBuffered(b, 0, b.length, timeout); + } + + public int readBuffered(byte[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; } else { - return super.read(b, 0, b.length); + Timeout t = new Timeout(timeout); + int nb = 0; + while (!t.elapsed()) { + int r = read(nb > 0 ? 1 : t.timeout()); + if (r < 0) { + return nb > 0 ? nb : r; + } + b[off + nb++] = (byte) r; + if (nb >= len || t.isInfinite()) { + break; + } + } + return nb; } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java 2023-07-05 07:11:54.000000000 +0000 @@ -95,13 +95,9 @@ @Override public int read(long timeout, boolean isPeek) throws IOException { - boolean isInfinite = (timeout <= 0L); - while (!bytes.hasRemaining() && (isInfinite || timeout > 0L)) { - long start = 0; - if (!isInfinite) { - start = System.currentTimeMillis(); - } - int c = reader.read(timeout); + Timeout t = new Timeout(timeout); + while (!bytes.hasRemaining() && !t.elapsed()) { + int c = reader.read(t.timeout()); if (c == EOF) { return EOF; } @@ -117,9 +113,6 @@ encoder.encode(chars, bytes, false); bytes.flip(); } - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } if (bytes.hasRemaining()) { if (isPeek) { @@ -151,21 +144,17 @@ public NonBlockingInputStreamReader(NonBlockingInputStream input, CharsetDecoder decoder) { this.input = input; this.decoder = decoder; - this.bytes = ByteBuffer.allocate(4); - this.chars = CharBuffer.allocate(2); + this.bytes = ByteBuffer.allocate(2048); + this.chars = CharBuffer.allocate(1024); this.bytes.limit(0); this.chars.limit(0); } @Override protected int read(long timeout, boolean isPeek) throws IOException { - boolean isInfinite = (timeout <= 0L); - while (!chars.hasRemaining() && (isInfinite || timeout > 0L)) { - long start = 0; - if (!isInfinite) { - start = System.currentTimeMillis(); - } - int b = input.read(timeout); + Timeout t = new Timeout(timeout); + while (!chars.hasRemaining() && !t.elapsed()) { + int b = input.read(t.timeout()); if (b == EOF) { return EOF; } @@ -181,10 +170,6 @@ decoder.decode(bytes, chars, false); chars.flip(); } - - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } if (chars.hasRemaining()) { if (isPeek) { @@ -198,46 +183,37 @@ } @Override - public int readBuffered(char[] b) throws IOException { + public int readBuffered(char[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; + } else if (chars.hasRemaining()) { + int r = Math.min(len, chars.remaining()); + chars.get(b, off, r); + return r; } else { - if (chars.hasRemaining()) { - int r = Math.min(b.length, chars.remaining()); - chars.get(b); - return r; - } else { - byte[] buf = new byte[b.length]; - int l = input.readBuffered(buf); - if (l < 0) { - return l; - } else { - ByteBuffer currentBytes; - if (bytes.hasRemaining()) { - int transfer = bytes.remaining(); - byte[] newBuf = new byte[l + transfer]; - bytes.get(newBuf, 0, transfer); - System.arraycopy(buf, 0, newBuf, transfer, l); - currentBytes = ByteBuffer.wrap(newBuf); - bytes.position(0); - bytes.limit(0); - } else { - currentBytes = ByteBuffer.wrap(buf, 0, l); - } - CharBuffer chars = CharBuffer.wrap(b); - decoder.decode(currentBytes, chars, false); - chars.flip(); - if (currentBytes.hasRemaining()) { - int pos = bytes.position(); - bytes.limit(bytes.limit() + currentBytes.remaining()); - bytes.put(currentBytes); - bytes.position(pos); - } - return chars.remaining(); + Timeout t = new Timeout(timeout); + while (!chars.hasRemaining() && !t.elapsed()) { + if (!bytes.hasRemaining()) { + bytes.position(0); + bytes.limit(0); + } + int nb = input.readBuffered(bytes.array(), bytes.limit(), + bytes.capacity() - bytes.limit(), t.timeout()); + if (nb < 0) { + return nb; } + bytes.limit(bytes.limit() + nb); + chars.clear(); + decoder.decode(bytes, chars, false); + chars.flip(); } + int nb = Math.min(len, chars.remaining()); + chars.get(b, off, nb); + return nb; } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java 2023-07-05 07:11:54.000000000 +0000 @@ -45,24 +45,17 @@ } private int wait(ByteBuffer buffer, long timeout) throws IOException { - boolean isInfinite = (timeout <= 0L); - long end = 0; - if (!isInfinite) { - end = System.currentTimeMillis() + timeout; - } - while (!closed && !buffer.hasRemaining() && (isInfinite || timeout > 0L)) { + Timeout t = new Timeout(timeout); + while (!closed && !buffer.hasRemaining() && !t.elapsed()) { // Wake up waiting readers/writers notifyAll(); try { - wait(timeout); + wait(t.timeout()); checkIoException(); } catch (InterruptedException e) { checkIoException(); throw new InterruptedIOException(); } - if (!isInfinite) { - timeout = end - System.currentTimeMillis(); - } } return buffer.hasRemaining() ? 0 @@ -107,17 +100,25 @@ } @Override - public synchronized int readBuffered(byte[] b) throws IOException { - checkIoException(); - int res = wait(readBuffer, 0L); - if (res >= 0) { - res = 0; - while (res < b.length && readBuffer.hasRemaining()) { - b[res++] = (byte) (readBuffer.get() & 0x00FF); + public synchronized int readBuffered(byte[] b, int off, int len, long timeout) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { + return 0; + } else { + checkIoException(); + int res = wait(readBuffer, timeout); + if (res >= 0) { + res = 0; + while (res < len && readBuffer.hasRemaining()) { + b[off + res++] = (byte) (readBuffer.get() & 0x00FF); + } } + rewind(readBuffer, writeBuffer); + return res; } - rewind(readBuffer, writeBuffer); - return res; } public synchronized void setIoException(IOException exception) { diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java 2023-07-05 07:11:54.000000000 +0000 @@ -106,10 +106,12 @@ } @Override - public int readBuffered(char[] b) throws IOException { + public int readBuffered(char[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; } else { final ReentrantLock lock = this.lock; @@ -117,7 +119,13 @@ try { if (!closed && count == 0) { try { - notEmpty.await(); + if (timeout > 0) { + if (!notEmpty.await(timeout, TimeUnit.MILLISECONDS)) { + throw new IOException( "Timeout reading" ); + } + } else { + notEmpty.await(); + } } catch (InterruptedException e) { throw (IOException) new InterruptedIOException().initCause(e); } @@ -127,9 +135,9 @@ } else if (count == 0) { return READ_EXPIRED; } else { - int r = Math.min(b.length, count); + int r = Math.min(len, count); for (int i = 0; i < r; i++) { - b[i] = buffer[read++]; + b[off + i] = buffer[read++]; if (read == buffer.length) { read = 0; } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -91,10 +91,12 @@ } @Override - public int readBuffered(char[] b) throws IOException { + public int readBuffered(char[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; } else if (exception != null) { assert ch == READ_EXPIRED; @@ -105,15 +107,16 @@ b[0] = (char) ch; ch = READ_EXPIRED; return 1; - } else if (!threadIsReading) { - return in.read(b); + } else if (!threadIsReading && timeout <= 0) { + return in.read(b, off, len); } else { - int c = read(-1, false); + // TODO: rework implementation to read as much as possible + int c = read(timeout, false); if (c >= 0) { - b[0] = (char) c; + b[off] = (char) c; return 1; } else { - return -1; + return c; } } } @@ -158,20 +161,17 @@ notifyAll(); } - boolean isInfinite = (timeout <= 0L); - /* * So the thread is currently doing the reading for us. So * now we play the waiting game. */ - while (isInfinite || timeout > 0L) { - long start = System.currentTimeMillis (); - + Timeout t = new Timeout(timeout); + while (!t.elapsed()) { try { if (Thread.interrupted()) { throw new InterruptedException(); } - wait(timeout); + wait(t.timeout()); } catch (InterruptedException e) { exception = (IOException) new InterruptedIOException().initCause(e); @@ -190,10 +190,6 @@ assert exception == null; break; } - - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java 2023-07-05 07:11:54.000000000 +0000 @@ -85,7 +85,15 @@ return 1; } - public abstract int readBuffered(char[] b) throws IOException; + public int readBuffered(char[] b) throws IOException { + return readBuffered(b, 0L); + } + + public int readBuffered(char[] b, long timeout) throws IOException { + return readBuffered(b, 0, b.length, timeout); + } + + public abstract int readBuffered(char[] b, int off, int len, long timeout) throws IOException; public int available() { return 0; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java 2023-07-05 07:11:54.000000000 +0000 @@ -9,6 +9,8 @@ package jdk.internal.org.jline.utils; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; public class OSUtils { @@ -28,6 +30,12 @@ && (System.getenv("MSYSTEM").startsWith("MINGW") || System.getenv("MSYSTEM").equals("MSYS")); + public static final boolean IS_WSL = System.getenv("WSL_DISTRO_NAME") != null; + + public static final boolean IS_WSL1 = IS_WSL && System.getenv("WSL_INTEROP") == null; + + public static final boolean IS_WSL2 = IS_WSL && !IS_WSL1; + public static final boolean IS_CONEMU = IS_WINDOWS && System.getenv("ConEmuPID") != null; @@ -38,17 +46,20 @@ public static String STTY_COMMAND; public static String STTY_F_OPTION; public static String INFOCMP_COMMAND; + public static String TEST_COMMAND; static { String tty; String stty; String sttyfopt; String infocmp; + String test; if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { - tty = "tty.exe"; - stty = "stty.exe"; + tty = null; + stty = null; sttyfopt = null; - infocmp = "infocmp.exe"; + infocmp = null; + test = null; String path = System.getenv("PATH"); if (path != null) { String[] paths = path.split(";"); @@ -62,23 +73,39 @@ if (infocmp == null && new File(p, "infocmp.exe").exists()) { infocmp = new File(p, "infocmp.exe").getAbsolutePath(); } + if (test == null && new File(p, "test.exe").exists()) { + test = new File(p, "test.exe").getAbsolutePath(); + } } } + if (tty == null) { + tty = "tty.exe"; + } + if (stty == null) { + stty = "stty.exe"; + } + if (infocmp == null) { + infocmp = "infocmp.exe"; + } + if (test == null) { + test = "test.exe"; + } } else { tty = "tty"; - stty = "stty"; + stty = IS_OSX ? "/bin/stty" : "stty"; + sttyfopt = IS_OSX ? "-f" : "-F"; infocmp = "infocmp"; - if (IS_OSX) { - sttyfopt = "-f"; - } - else { - sttyfopt = "-F"; - } + test = isTestCommandValid("/usr/bin/test") ? "/usr/bin/test" + : "/bin/test"; } TTY_COMMAND = tty; STTY_COMMAND = stty; STTY_F_OPTION = sttyfopt; INFOCMP_COMMAND = infocmp; + TEST_COMMAND = test; } + private static boolean isTestCommandValid(String command) { + return Files.isExecutable(Paths.get(command)); + } } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java 2023-07-05 07:11:54.000000000 +0000 @@ -36,7 +36,7 @@ } public PumpReader(int bufferSize) { - char[] buf = new char[bufferSize]; + char[] buf = new char[Math.max(bufferSize, 2)]; this.readBuffer = CharBuffer.wrap(buf); this.writeBuffer = CharBuffer.wrap(buf); this.writer = new Writer(this); @@ -53,13 +53,27 @@ return new InputStream(this, charset); } - private boolean wait(CharBuffer buffer) throws InterruptedIOException { - if (closed) { - return false; + /** + * Blocks until more input is available, even if {@link #readBuffer} already + * contains some chars; or until the reader is closed. + * + * @return true if more input is available, false if no additional input is + * available and the reader is closed + * @throws InterruptedIOException If {@link #wait()} is interrupted + */ + private boolean waitForMoreInput() throws InterruptedIOException { + if (!writeBuffer.hasRemaining()) { + throw new AssertionError("No space in write buffer"); } - while (!buffer.hasRemaining()) { - // Wake up waiting readers/writers + int oldRemaining = readBuffer.remaining(); + + do { + if (closed) { + return false; + } + + // Wake up waiting writers notifyAll(); try { @@ -67,19 +81,41 @@ } catch (InterruptedException e) { throw new InterruptedIOException(); } + } while (readBuffer.remaining() <= oldRemaining); + + return true; + } + /** + * Waits until {@code buffer.hasRemaining() == true}, or it is false and + * the reader is {@link #closed}. + * + * @return true if {@code buffer.hasRemaining() == true}; false otherwise + * when reader is closed + */ + private boolean wait(CharBuffer buffer) throws InterruptedIOException { + while (!buffer.hasRemaining()) { if (closed) { return false; } + + // Wake up waiting readers/writers + notifyAll(); + + try { + wait(); + } catch (InterruptedException e) { + throw new InterruptedIOException(); + } } return true; } /** - * Blocks until more input is available or the reader is closed. + * Blocks until input is available or the reader is closed. * - * @return true if more input is available, false if the reader is closed + * @return true if input is available, false if no input is available and the reader is closed * @throws InterruptedIOException If {@link #wait()} is interrupted */ private boolean waitForInput() throws InterruptedIOException { @@ -94,7 +130,8 @@ * @throws ClosedException If the reader was closed */ private void waitForBufferSpace() throws InterruptedIOException, ClosedException { - if (!wait(writeBuffer)) { + // Check `closed` to throw even if writer buffer has space available + if (!wait(writeBuffer) || closed) { throw new ClosedException(); } } @@ -122,7 +159,9 @@ * @return If more input is available */ private boolean rewindReadBuffer() { - return rewind(readBuffer, writeBuffer) && readBuffer.hasRemaining(); + boolean rw = rewind(readBuffer, writeBuffer) && readBuffer.hasRemaining(); + notifyAll(); + return rw; } /** @@ -131,6 +170,7 @@ */ private void rewindWriteBuffer() { rewind(writeBuffer, readBuffer); + notifyAll(); } @Override @@ -202,10 +242,33 @@ } private void encodeBytes(CharsetEncoder encoder, ByteBuffer output) throws IOException { + int oldPos = output.position(); CoderResult result = encoder.encode(readBuffer, output, false); - if (rewindReadBuffer() && result.isUnderflow()) { - encoder.encode(readBuffer, output, false); + int encodedCount = output.position() - oldPos; + + if (result.isUnderflow()) { + boolean hasMoreInput = rewindReadBuffer(); + boolean reachedEndOfInput = false; + + // If encoding did not make any progress must block for more input + if (encodedCount == 0 && !hasMoreInput) { + reachedEndOfInput = !waitForMoreInput(); + } + + result = encoder.encode(readBuffer, output, reachedEndOfInput); + if (result.isError()) { + result.throwException(); + } + if (!reachedEndOfInput && output.position() - oldPos == 0) { + throw new AssertionError("Failed to encode any chars"); + } rewindReadBuffer(); + } else if (result.isOverflow()) { + if (encodedCount == 0) { + throw new AssertionError("Output buffer has not enough space"); + } + } else { + result.throwException(); } } @@ -334,7 +397,7 @@ this.encoder = charset.newEncoder() .onUnmappableCharacter(CodingErrorAction.REPLACE) .onMalformedInput(CodingErrorAction.REPLACE); - this.buffer = ByteBuffer.allocate((int) Math.ceil(encoder.maxBytesPerChar())); + this.buffer = ByteBuffer.allocate((int) Math.ceil(encoder.maxBytesPerChar() * 2)); // No input available after initialization buffer.limit(0); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java 2023-07-05 07:11:54.000000000 +0000 @@ -241,7 +241,7 @@ if (spec.length() == 1) { // log.warning("Invalid style-reference; missing discriminator: " + spec); } else { - String name = spec.substring(1, spec.length()); + String name = spec.substring(1); String resolvedSpec = source.apply(name); if (resolvedSpec != null) { return apply(style, resolvedSpec); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2002-2018, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.utils; + +/** + * Helper class ti use during I/O operations with an eventual timeout. + */ +public class Timeout { + + private final long timeout; + private long cur = 0; + private long end = Long.MAX_VALUE; + + public Timeout(long timeout) { + this.timeout = timeout; + } + + public boolean isInfinite() { + return timeout <= 0; + } + + public boolean isFinite() { + return timeout > 0; + } + + public boolean elapsed() { + if (timeout > 0) { + cur = System.currentTimeMillis(); + if (end == Long.MAX_VALUE) { + end = cur + timeout; + } + return cur >= end; + } else { + return false; + } + } + + public long timeout() { + return timeout > 0 ? Math.max(1, end - cur) : timeout; + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java 2023-07-05 07:11:54.000000000 +0000 @@ -70,6 +70,7 @@ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x1f000 && ucs <= 0x1feee) || (ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd))) ? 1 : 0); } @@ -123,8 +124,8 @@ new Interval( 0x10A01, 0x10A03 ), new Interval( 0x10A05, 0x10A06 ), new Interval( 0x10A0C, 0x10A0F ), new Interval( 0x10A38, 0x10A3A ), new Interval( 0x10A3F, 0x10A3F ), new Interval( 0x1D167, 0x1D169 ), new Interval( 0x1D173, 0x1D182 ), new Interval( 0x1D185, 0x1D18B ), new Interval( 0x1D1AA, 0x1D1AD ), - new Interval( 0x1D242, 0x1D244 ), new Interval( 0xE0001, 0xE0001 ), new Interval( 0xE0020, 0xE007F ), - new Interval( 0xE0100, 0xE01EF ) + new Interval( 0x1D242, 0x1D244 ), new Interval( 0x1F3FB, 0x1F3FF ), new Interval( 0xE0001, 0xE0001 ), + new Interval( 0xE0020, 0xE007F ), new Interval( 0xE0100, 0xE01EF ) }; private static class Interval { diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps 2023-07-05 07:11:54.000000000 +0000 @@ -2,7 +2,7 @@ am, mc5i, mir, msgr, colors#256, cols#80, it#8, lines#24, ncv#3, pairs#64, bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, clear=\E[H\E[J, - cr=^M, cub=\E[%p1%dD, cub1=\E[D, cud=\E[%p1%dB, cud1=\E[B, + cr=^M, cub=\E[%p1%dD, cub1=\E[D, cud=\E[%p1%dB, cud1=\n, cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, il=\E[%p1%dL, il1=\E[L, diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/module-info.java openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/module-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/classes/module-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/classes/module-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -47,8 +47,5 @@ jdk.jshell; exports jdk.internal.org.jline.terminal.spi to jdk.jshell; - - uses jdk.internal.org.jline.terminal.spi.JnaSupport; - } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/legal/jline.md openjdk-17-17.0.8+7/src/jdk.internal.le/share/legal/jline.md --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/share/legal/jline.md 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/share/legal/jline.md 2023-07-05 07:11:54.000000000 +0000 @@ -1,4 +1,4 @@ -## JLine v3.20.0 +## JLine v3.22.0 ### JLine License
    @@ -38,4 +38,257 @@
     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-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2002-2019, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.impl.jna; - -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.Terminal; -import jdk.internal.org.jline.terminal.impl.jna.win.JnaWinSysTerminal; -import jdk.internal.org.jline.terminal.spi.JnaSupport; -import jdk.internal.org.jline.terminal.spi.Pty; -import jdk.internal.org.jline.utils.OSUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.function.Function; - -public class JnaSupportImpl implements JnaSupport { - @Override - public Pty current() throws IOException { -// return JnaNativePty.current(); - throw new UnsupportedOperationException(); - } - - @Override - public Pty open(Attributes attributes, Size size) throws IOException { -// return JnaNativePty.open(attributes, size); - throw new UnsupportedOperationException(); - } - - @Override - public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException { - return winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, false); - } - - @Override - public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException { - return winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused, input -> input); - } - - @Override - public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, Function inputStreamWrapper) throws IOException { - return JnaWinSysTerminal.createTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused, inputStreamWrapper); - } - - @Override - public boolean isWindowsConsole() { - return JnaWinSysTerminal.isWindowsConsole(); - } - - @Override - public boolean isConsoleOutput() { - if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { - throw new UnsupportedOperationException(); - } else if (OSUtils.IS_WINDOWS) { - return JnaWinSysTerminal.isConsoleOutput(); - } - throw new UnsupportedOperationException(); - } - - @Override - public boolean isConsoleInput() { - if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { - throw new UnsupportedOperationException(); - } else if (OSUtils.IS_WINDOWS) { - return JnaWinSysTerminal.isConsoleInput(); - } - throw new UnsupportedOperationException(); - } - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2002-2020, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.jna; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal; +import jdk.internal.org.jline.terminal.impl.PosixSysTerminal; +import jdk.internal.org.jline.terminal.impl.jna.win.JnaWinSysTerminal; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.utils.OSUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.function.Function; + +public class JnaTerminalProvider implements TerminalProvider +{ + @Override + public String name() { + return "jna"; + } + +// public Pty current(TerminalProvider.Stream console) throws IOException { +// return JnaNativePty.current(console); +// } +// +// public Pty open(Attributes attributes, Size size) throws IOException { +// return JnaNativePty.open(attributes, size); +// } + + @Override + public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper) throws IOException { + if (OSUtils.IS_WINDOWS) { + return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper ); + } else { + return null; + } + } + + public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream console, Function inputStreamWrapper) throws IOException { + return JnaWinSysTerminal.createTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, console, inputStreamWrapper); + } + +// public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, +// boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, +// Stream consoleStream) throws IOException { +// Pty pty = current(consoleStream); +// return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler); +// } + + @Override + public Terminal newTerminal(String name, String type, InputStream in, OutputStream out, + Charset encoding, Terminal.SignalHandler signalHandler, boolean paused, + Attributes attributes, Size size) throws IOException + { +// Pty pty = open(attributes, size); +// return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused); + return null; + } + + @Override + public boolean isSystemStream(Stream stream) { + try { + if (OSUtils.IS_WINDOWS) { + return isWindowsSystemStream(stream); + } else { +// return isPosixSystemStream(stream); + return false; + } + } catch (Throwable t) { + return false; + } + } + + public boolean isWindowsSystemStream(Stream stream) { + return JnaWinSysTerminal.isWindowsSystemStream(stream); + } + +// public boolean isPosixSystemStream(Stream stream) { +// return JnaNativePty.isPosixSystemStream(stream); +// } + + @Override + public String systemStreamName(Stream stream) { +// if (OSUtils.IS_WINDOWS) { + return null; +// } else { +// return JnaNativePty.posixSystemStreamName(stream); +// } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java 2023-07-05 07:11:54.000000000 +0000 @@ -17,17 +17,17 @@ class JnaWinConsoleWriter extends AbstractWindowsConsoleWriter { - private final Pointer consoleHandle; + private final Pointer console; private final IntByReference writtenChars = new IntByReference(); - JnaWinConsoleWriter(Pointer consoleHandle) { - this.consoleHandle = consoleHandle; + JnaWinConsoleWriter(Pointer console) { + this.console = console; } @Override protected void writeConsole(char[] text, int len) throws IOException { try { - Kernel32.INSTANCE.WriteConsoleW(this.consoleHandle, text, len, this.writtenChars, null); + Kernel32.INSTANCE.WriteConsoleW(this.console, text, len, this.writtenChars, null); } catch (LastErrorException e) { throw new IOException("Failed to write to console", e); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2020, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -19,11 +19,10 @@ //import com.sun.jna.LastErrorException; //import com.sun.jna.Pointer; //import com.sun.jna.ptr.IntByReference; - import jdk.internal.org.jline.terminal.Cursor; import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.Terminal; import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.InfoCmp; import jdk.internal.org.jline.utils.OSUtils; @@ -31,38 +30,50 @@ private static final Pointer consoleIn = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_INPUT_HANDLE); private static final Pointer consoleOut = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_OUTPUT_HANDLE); + private static final Pointer consoleErr = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_ERROR_HANDLE); - public static JnaWinSysTerminal createTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, boolean paused, Function inputStreamWrapper) throws IOException { + public static JnaWinSysTerminal createTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, boolean paused, TerminalProvider.Stream consoleStream, Function inputStreamWrapper) throws IOException { + Pointer console; + switch (consoleStream) { + case Output: + console = JnaWinSysTerminal.consoleOut; + break; + case Error: + console = JnaWinSysTerminal.consoleErr; + break; + default: + throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream); + } Writer writer; if (ansiPassThrough) { if (type == null) { type = OSUtils.IS_CONEMU ? TYPE_WINDOWS_CONEMU : TYPE_WINDOWS; } - writer = new JnaWinConsoleWriter(consoleOut); + writer = new JnaWinConsoleWriter(console); } else { IntByReference mode = new IntByReference(); - Kernel32.INSTANCE.GetConsoleMode(consoleOut, mode); + Kernel32.INSTANCE.GetConsoleMode(console, mode); try { - Kernel32.INSTANCE.SetConsoleMode(consoleOut, mode.getValue() | AbstractWindowsTerminal.ENABLE_VIRTUAL_TERMINAL_PROCESSING); + Kernel32.INSTANCE.SetConsoleMode(console, mode.getValue() | AbstractWindowsTerminal.ENABLE_VIRTUAL_TERMINAL_PROCESSING); if (type == null) { type = TYPE_WINDOWS_VTP; } - writer = new JnaWinConsoleWriter(consoleOut); + writer = new JnaWinConsoleWriter(console); } catch (LastErrorException e) { if (OSUtils.IS_CONEMU) { if (type == null) { type = TYPE_WINDOWS_CONEMU; } - writer = new JnaWinConsoleWriter(consoleOut); + writer = new JnaWinConsoleWriter(console); } else { if (type == null) { type = TYPE_WINDOWS; } - writer = new WindowsAnsiWriter(new BufferedWriter(new JnaWinConsoleWriter(consoleOut)), consoleOut); + writer = new WindowsAnsiWriter(new BufferedWriter(new JnaWinConsoleWriter(console)), console); } } } - JnaWinSysTerminal terminal = new JnaWinSysTerminal(writer, name, type, encoding, codepage, nativeSignals, signalHandler, inputStreamWrapper); + JnaWinSysTerminal terminal = new JnaWinSysTerminal(writer, name, type, encoding, nativeSignals, signalHandler, inputStreamWrapper); // Start input pump thread if (!paused) { terminal.resume(); @@ -70,39 +81,26 @@ return terminal; } - public static boolean isWindowsConsole() { - try { - IntByReference mode = new IntByReference(); - Kernel32.INSTANCE.GetConsoleMode(consoleOut, mode); - Kernel32.INSTANCE.GetConsoleMode(consoleIn, mode); - return true; - } catch (LastErrorException e) { - return false; - } - } - - public static boolean isConsoleOutput() { + public static boolean isWindowsSystemStream(TerminalProvider.Stream stream) { try { IntByReference mode = new IntByReference(); - Kernel32.INSTANCE.GetConsoleMode(consoleOut, mode); - return true; - } catch (LastErrorException e) { - return false; - } - } - - public static boolean isConsoleInput() { - try { - IntByReference mode = new IntByReference(); - Kernel32.INSTANCE.GetConsoleMode(consoleIn, mode); + Pointer console; + switch (stream) { + case Input: console = consoleIn; break; + case Output: console = consoleOut; break; + case Error: console = consoleErr; break; + default: return false; + } + Kernel32.INSTANCE.GetConsoleMode(console, mode); return true; } catch (LastErrorException e) { return false; } } - JnaWinSysTerminal(Writer writer, String name, String type, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, Function inputStreamWrapper) throws IOException { - super(writer, name, type, encoding, codepage, nativeSignals, signalHandler, inputStreamWrapper); + JnaWinSysTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, + Function inputStreamWrapper) throws IOException { + super(writer, name, type, encoding, nativeSignals, signalHandler, inputStreamWrapper); strings.put(InfoCmp.Capability.key_mouse, "\\E[M"); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java 2023-07-05 07:11:54.000000000 +0000 @@ -183,26 +183,26 @@ protected void processCursorUpLine(int count) throws IOException { getConsoleInfo(); info.dwCursorPosition.X = 0; - info.dwCursorPosition.Y -= count; + info.dwCursorPosition.Y -= (short)count; applyCursorPosition(); } protected void processCursorDownLine(int count) throws IOException { getConsoleInfo(); info.dwCursorPosition.X = 0; - info.dwCursorPosition.Y += count; + info.dwCursorPosition.Y += (short)count; applyCursorPosition(); } protected void processCursorLeft(int count) throws IOException { getConsoleInfo(); - info.dwCursorPosition.X -= count; + info.dwCursorPosition.X -= (short)count; applyCursorPosition(); } protected void processCursorRight(int count) throws IOException { getConsoleInfo(); - info.dwCursorPosition.X += count; + info.dwCursorPosition.X += (short)count; applyCursorPosition(); } @@ -210,7 +210,7 @@ getConsoleInfo(); int nb = Math.max(0, info.dwCursorPosition.Y + count - info.dwSize.Y + 1); if (nb != count) { - info.dwCursorPosition.Y += count; + info.dwCursorPosition.Y += (short)count; applyCursorPosition(); } if (nb > 0) { @@ -226,7 +226,7 @@ protected void processCursorUp(int count) throws IOException { getConsoleInfo(); - info.dwCursorPosition.Y -= count; + info.dwCursorPosition.Y -= (short)count; applyCursorPosition(); } diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/module-info.java.extra openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/module-info.java.extra --- openjdk-17-17.0.7+7~us1/src/jdk.internal.le/windows/classes/module-info.java.extra 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.le/windows/classes/module-info.java.extra 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. 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. - */ - - -provides jdk.internal.org.jline.terminal.spi.JnaSupport with jdk.internal.org.jline.terminal.impl.jna.JnaSupportImpl; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2015, 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. + */ +package jdk.vm.ci.aarch64; + +import java.nio.ByteOrder; +import java.util.EnumSet; + +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.CPUFeatureName; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.Register.RegisterCategory; +import jdk.vm.ci.code.RegisterArray; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.PlatformKind; + +/** + * Represents the AArch64 architecture. + */ +public class AArch64 extends Architecture { + + public static final RegisterCategory CPU = new RegisterCategory("CPU"); + + // General purpose CPU registers + public static final Register r0 = new Register(0, 0, "r0", CPU); + public static final Register r1 = new Register(1, 1, "r1", CPU); + public static final Register r2 = new Register(2, 2, "r2", CPU); + public static final Register r3 = new Register(3, 3, "r3", CPU); + public static final Register r4 = new Register(4, 4, "r4", CPU); + public static final Register r5 = new Register(5, 5, "r5", CPU); + public static final Register r6 = new Register(6, 6, "r6", CPU); + public static final Register r7 = new Register(7, 7, "r7", CPU); + public static final Register r8 = new Register(8, 8, "r8", CPU); + public static final Register r9 = new Register(9, 9, "r9", CPU); + public static final Register r10 = new Register(10, 10, "r10", CPU); + public static final Register r11 = new Register(11, 11, "r11", CPU); + public static final Register r12 = new Register(12, 12, "r12", CPU); + public static final Register r13 = new Register(13, 13, "r13", CPU); + public static final Register r14 = new Register(14, 14, "r14", CPU); + public static final Register r15 = new Register(15, 15, "r15", CPU); + public static final Register r16 = new Register(16, 16, "r16", CPU); + public static final Register r17 = new Register(17, 17, "r17", CPU); + public static final Register r18 = new Register(18, 18, "r18", CPU); + public static final Register r19 = new Register(19, 19, "r19", CPU); + public static final Register r20 = new Register(20, 20, "r20", CPU); + public static final Register r21 = new Register(21, 21, "r21", CPU); + public static final Register r22 = new Register(22, 22, "r22", CPU); + public static final Register r23 = new Register(23, 23, "r23", CPU); + public static final Register r24 = new Register(24, 24, "r24", CPU); + public static final Register r25 = new Register(25, 25, "r25", CPU); + public static final Register r26 = new Register(26, 26, "r26", CPU); + public static final Register r27 = new Register(27, 27, "r27", CPU); + public static final Register r28 = new Register(28, 28, "r28", CPU); + public static final Register r29 = new Register(29, 29, "r29", CPU); + public static final Register r30 = new Register(30, 30, "r30", CPU); + + /* + * r31 is not a general purpose register, but represents either the stackpointer or the + * zero/discard register depending on the instruction. So we represent those two uses as two + * different registers. The register numbers are kept in sync with register_aarch64.hpp and have + * to be sequential, hence we also need a general r31 register here, which is never used. + */ + public static final Register r31 = new Register(31, 31, "r31", CPU); + public static final Register zr = new Register(32, 31, "zr", CPU); + public static final Register sp = new Register(33, 31, "sp", CPU); + + public static final Register lr = r30; + + // Used by runtime code: cannot be compiler-allocated. + public static final Register rscratch1 = r8; + public static final Register rscratch2 = r9; + + // @formatter:off + public static final RegisterArray cpuRegisters = new RegisterArray( + r0, r1, r2, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, + r16, r17, r18, r19, r20, r21, r22, r23, + r24, r25, r26, r27, r28, r29, r30, r31, + zr, sp + ); + // @formatter:on + + public static final RegisterCategory SIMD = new RegisterCategory("SIMD"); + + // Simd registers + public static final Register v0 = new Register(34, 0, "v0", SIMD); + public static final Register v1 = new Register(35, 1, "v1", SIMD); + public static final Register v2 = new Register(36, 2, "v2", SIMD); + public static final Register v3 = new Register(37, 3, "v3", SIMD); + public static final Register v4 = new Register(38, 4, "v4", SIMD); + public static final Register v5 = new Register(39, 5, "v5", SIMD); + public static final Register v6 = new Register(40, 6, "v6", SIMD); + public static final Register v7 = new Register(41, 7, "v7", SIMD); + public static final Register v8 = new Register(42, 8, "v8", SIMD); + public static final Register v9 = new Register(43, 9, "v9", SIMD); + public static final Register v10 = new Register(44, 10, "v10", SIMD); + public static final Register v11 = new Register(45, 11, "v11", SIMD); + public static final Register v12 = new Register(46, 12, "v12", SIMD); + public static final Register v13 = new Register(47, 13, "v13", SIMD); + public static final Register v14 = new Register(48, 14, "v14", SIMD); + public static final Register v15 = new Register(49, 15, "v15", SIMD); + public static final Register v16 = new Register(50, 16, "v16", SIMD); + public static final Register v17 = new Register(51, 17, "v17", SIMD); + public static final Register v18 = new Register(52, 18, "v18", SIMD); + public static final Register v19 = new Register(53, 19, "v19", SIMD); + public static final Register v20 = new Register(54, 20, "v20", SIMD); + public static final Register v21 = new Register(55, 21, "v21", SIMD); + public static final Register v22 = new Register(56, 22, "v22", SIMD); + public static final Register v23 = new Register(57, 23, "v23", SIMD); + public static final Register v24 = new Register(58, 24, "v24", SIMD); + public static final Register v25 = new Register(59, 25, "v25", SIMD); + public static final Register v26 = new Register(60, 26, "v26", SIMD); + public static final Register v27 = new Register(61, 27, "v27", SIMD); + public static final Register v28 = new Register(62, 28, "v28", SIMD); + public static final Register v29 = new Register(63, 29, "v29", SIMD); + public static final Register v30 = new Register(64, 30, "v30", SIMD); + public static final Register v31 = new Register(65, 31, "v31", SIMD); + + // @formatter:off + public static final RegisterArray simdRegisters = new RegisterArray( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31 + ); + // @formatter:on + + // @formatter:off + public static final RegisterArray allRegisters = new RegisterArray( + r0, r1, r2, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, + r16, r17, r18, r19, r20, r21, r22, r23, + r24, r25, r26, r27, r28, r29, r30, r31, + zr, sp, + + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31 + ); + // @formatter:on + + /** + * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: + * {@code VM_Version::cpuFeatureFlags}. + */ + public enum CPUFeature implements CPUFeatureName { + FP, + ASIMD, + EVTSTRM, + AES, + PMULL, + SHA1, + SHA2, + CRC32, + LSE, + DCPOP, + SHA3, + SHA512, + SVE, + SVE2, + STXR_PREFETCH, + A53MAC, + } + + private final EnumSet features; + + /** + * Set of flags to control code emission. + */ + public enum Flag { + UseCRC32, + UseNeon, + UseSIMDForMemoryOps, + AvoidUnalignedAccesses, + UseLSE, + UseBlockZeroing + } + + private final EnumSet flags; + + public AArch64(EnumSet features, EnumSet flags) { + super("aarch64", AArch64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, 0, 0, 0); + this.features = features; + this.flags = flags; + } + + @Override + public EnumSet getFeatures() { + return features; + } + + public EnumSet getFlags() { + return flags; + } + + @Override + public PlatformKind getPlatformKind(JavaKind javaKind) { + switch (javaKind) { + case Boolean: + case Byte: + return AArch64Kind.BYTE; + case Short: + case Char: + return AArch64Kind.WORD; + case Int: + return AArch64Kind.DWORD; + case Long: + case Object: + return AArch64Kind.QWORD; + case Float: + return AArch64Kind.SINGLE; + case Double: + return AArch64Kind.DOUBLE; + default: + return null; + } + } + + @Override + public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { + AArch64Kind kind = (AArch64Kind) platformKind; + if (kind.isInteger()) { + return category.equals(CPU); + } else if (kind.isSIMD()) { + return category.equals(SIMD); + } + return false; + } + + @Override + public AArch64Kind getLargestStorableKind(RegisterCategory category) { + if (category.equals(CPU)) { + return AArch64Kind.QWORD; + } else if (category.equals(SIMD)) { + return AArch64Kind.V128_QWORD; + } else { + return null; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64Kind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64Kind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64Kind.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/AArch64Kind.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,153 @@ +/* + * 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. + */ +package jdk.vm.ci.aarch64; + +import jdk.vm.ci.meta.PlatformKind; + +public enum AArch64Kind implements PlatformKind { + + // scalar + BYTE(1), + WORD(2), + DWORD(4), + QWORD(8), + SINGLE(4), + DOUBLE(8), + + // SIMD + V32_BYTE(4, BYTE), + V32_WORD(4, WORD), + V64_BYTE(8, BYTE), + V64_WORD(8, WORD), + V64_DWORD(8, DWORD), + V128_BYTE(16, BYTE), + V128_WORD(16, WORD), + V128_DWORD(16, DWORD), + V128_QWORD(16, QWORD), + V128_SINGLE(16, SINGLE), + V128_DOUBLE(16, DOUBLE); + + private final int size; + private final int vectorLength; + + private final AArch64Kind scalar; + private final EnumKey key = new EnumKey<>(this); + + AArch64Kind(int size) { + this.size = size; + this.scalar = this; + this.vectorLength = 1; + } + + AArch64Kind(int size, AArch64Kind scalar) { + this.size = size; + this.scalar = scalar; + + assert size % scalar.size == 0; + this.vectorLength = size / scalar.size; + } + + public AArch64Kind getScalar() { + return scalar; + } + + @Override + public int getSizeInBytes() { + return size; + } + + @Override + public int getVectorLength() { + return vectorLength; + } + + @Override + public Key getKey() { + return key; + } + + public boolean isInteger() { + switch (this) { + case BYTE: + case WORD: + case DWORD: + case QWORD: + return true; + default: + return false; + } + } + + public boolean isSIMD() { + switch (this) { + case SINGLE: + case DOUBLE: + case V32_BYTE: + case V32_WORD: + case V64_BYTE: + case V64_WORD: + case V64_DWORD: + case V128_BYTE: + case V128_WORD: + case V128_DWORD: + case V128_QWORD: + case V128_SINGLE: + case V128_DOUBLE: + return true; + default: + return false; + } + } + + @Override + public char getTypeChar() { + switch (this) { + case BYTE: + return 'b'; + case WORD: + return 'w'; + case DWORD: + return 'd'; + case QWORD: + return 'q'; + case SINGLE: + return 'S'; + case DOUBLE: + return 'D'; + case V32_BYTE: + case V32_WORD: + case V64_BYTE: + case V64_WORD: + case V64_DWORD: + case V128_BYTE: + case V128_WORD: + case V128_DWORD: + case V128_QWORD: + case V128_SINGLE: + case V128_DOUBLE: + return 'v'; + default: + return '-'; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/aarch64/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * The AArch64 platform independent portions of the JVMCI API. + */ +package jdk.vm.ci.aarch64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.amd64; + +import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD; +import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE; +import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; +import static jdk.vm.ci.code.Register.SPECIAL; + +import java.nio.ByteOrder; +import java.util.EnumSet; + +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.CPUFeatureName; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.Register.RegisterCategory; +import jdk.vm.ci.code.RegisterArray; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.PlatformKind; + +/** + * Represents the AMD64 architecture. + */ +public class AMD64 extends Architecture { + + public static final RegisterCategory CPU = new RegisterCategory("CPU"); + + // @formatter:off + + // General purpose CPU registers + public static final Register rax = new Register(0, 0, "rax", CPU); + public static final Register rcx = new Register(1, 1, "rcx", CPU); + public static final Register rdx = new Register(2, 2, "rdx", CPU); + public static final Register rbx = new Register(3, 3, "rbx", CPU); + public static final Register rsp = new Register(4, 4, "rsp", CPU); + public static final Register rbp = new Register(5, 5, "rbp", CPU); + public static final Register rsi = new Register(6, 6, "rsi", CPU); + public static final Register rdi = new Register(7, 7, "rdi", CPU); + + public static final Register r8 = new Register(8, 8, "r8", CPU); + public static final Register r9 = new Register(9, 9, "r9", CPU); + public static final Register r10 = new Register(10, 10, "r10", CPU); + public static final Register r11 = new Register(11, 11, "r11", CPU); + public static final Register r12 = new Register(12, 12, "r12", CPU); + public static final Register r13 = new Register(13, 13, "r13", CPU); + public static final Register r14 = new Register(14, 14, "r14", CPU); + public static final Register r15 = new Register(15, 15, "r15", CPU); + + public static final Register[] cpuRegisters = { + rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, + r8, r9, r10, r11, r12, r13, r14, r15 + }; + + public static final RegisterCategory XMM = new RegisterCategory("XMM"); + + // XMM registers + public static final Register xmm0 = new Register(16, 0, "xmm0", XMM); + public static final Register xmm1 = new Register(17, 1, "xmm1", XMM); + public static final Register xmm2 = new Register(18, 2, "xmm2", XMM); + public static final Register xmm3 = new Register(19, 3, "xmm3", XMM); + public static final Register xmm4 = new Register(20, 4, "xmm4", XMM); + public static final Register xmm5 = new Register(21, 5, "xmm5", XMM); + public static final Register xmm6 = new Register(22, 6, "xmm6", XMM); + public static final Register xmm7 = new Register(23, 7, "xmm7", XMM); + + public static final Register xmm8 = new Register(24, 8, "xmm8", XMM); + public static final Register xmm9 = new Register(25, 9, "xmm9", XMM); + public static final Register xmm10 = new Register(26, 10, "xmm10", XMM); + public static final Register xmm11 = new Register(27, 11, "xmm11", XMM); + public static final Register xmm12 = new Register(28, 12, "xmm12", XMM); + public static final Register xmm13 = new Register(29, 13, "xmm13", XMM); + public static final Register xmm14 = new Register(30, 14, "xmm14", XMM); + public static final Register xmm15 = new Register(31, 15, "xmm15", XMM); + + public static final Register xmm16 = new Register(32, 16, "xmm16", XMM); + public static final Register xmm17 = new Register(33, 17, "xmm17", XMM); + public static final Register xmm18 = new Register(34, 18, "xmm18", XMM); + public static final Register xmm19 = new Register(35, 19, "xmm19", XMM); + public static final Register xmm20 = new Register(36, 20, "xmm20", XMM); + public static final Register xmm21 = new Register(37, 21, "xmm21", XMM); + public static final Register xmm22 = new Register(38, 22, "xmm22", XMM); + public static final Register xmm23 = new Register(39, 23, "xmm23", XMM); + + public static final Register xmm24 = new Register(40, 24, "xmm24", XMM); + public static final Register xmm25 = new Register(41, 25, "xmm25", XMM); + public static final Register xmm26 = new Register(42, 26, "xmm26", XMM); + public static final Register xmm27 = new Register(43, 27, "xmm27", XMM); + public static final Register xmm28 = new Register(44, 28, "xmm28", XMM); + public static final Register xmm29 = new Register(45, 29, "xmm29", XMM); + public static final Register xmm30 = new Register(46, 30, "xmm30", XMM); + public static final Register xmm31 = new Register(47, 31, "xmm31", XMM); + + public static final Register[] xmmRegistersSSE = { + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + + public static final Register[] xmmRegistersAVX512 = { + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, + xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, + xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31 + }; + + public static final RegisterCategory MASK = new RegisterCategory("MASK", false); + + public static final Register k0 = new Register(48, 0, "k0", MASK); + public static final Register k1 = new Register(49, 1, "k1", MASK); + public static final Register k2 = new Register(50, 2, "k2", MASK); + public static final Register k3 = new Register(51, 3, "k3", MASK); + public static final Register k4 = new Register(52, 4, "k4", MASK); + public static final Register k5 = new Register(53, 5, "k5", MASK); + public static final Register k6 = new Register(54, 6, "k6", MASK); + public static final Register k7 = new Register(55, 7, "k7", MASK); + + public static final RegisterArray valueRegistersSSE = new RegisterArray( + rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, + r8, r9, r10, r11, r12, r13, r14, r15, + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + ); + + public static final RegisterArray valueRegistersAVX512 = new RegisterArray( + rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, + r8, r9, r10, r11, r12, r13, r14, r15, + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, + xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, + xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31, + k0, k1, k2, k3, k4, k5, k6, k7 + ); + + /** + * Register used to construct an instruction-relative address. + */ + public static final Register rip = new Register(56, -1, "rip", SPECIAL); + + public static final RegisterArray allRegisters = new RegisterArray( + rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, + r8, r9, r10, r11, r12, r13, r14, r15, + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, + xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, + xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31, + k0, k1, k2, k3, k4, k5, k6, k7, + rip + ); + + // @formatter:on + + /** + * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: + * {@code VM_Version::cpuFeatureFlags}. + */ + public enum CPUFeature implements CPUFeatureName { + CX8, + CMOV, + FXSR, + HT, + MMX, + AMD_3DNOW_PREFETCH, + SSE, + SSE2, + SSE3, + SSSE3, + SSE4A, + SSE4_1, + SSE4_2, + POPCNT, + LZCNT, + TSC, + TSCINV, + TSCINV_BIT, + AVX, + AVX2, + AES, + ERMS, + CLMUL, + BMI1, + BMI2, + RTM, + ADX, + AVX512F, + AVX512DQ, + AVX512PF, + AVX512ER, + AVX512CD, + AVX512BW, + AVX512VL, + SHA, + FMA, + VZEROUPPER, + AVX512_VPOPCNTDQ, + AVX512_VPCLMULQDQ, + AVX512_VAES, + AVX512_VNNI, + FLUSH, + FLUSHOPT, + CLWB, + AVX512_VBMI2, + AVX512_VBMI, + HV, + } + + private final EnumSet features; + + /** + * Set of flags to control code emission. + */ + public enum Flag { + UseCountLeadingZerosInstruction, + UseCountTrailingZerosInstruction + } + + private final EnumSet flags; + + private final AMD64Kind largestKind; + + public AMD64(EnumSet features, EnumSet flags) { + super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8); + this.features = features; + this.flags = flags; + assert features.contains(CPUFeature.SSE2) : "minimum config for x64"; + + if (features.contains(CPUFeature.AVX512F)) { + largestKind = AMD64Kind.V512_QWORD; + } else if (features.contains(CPUFeature.AVX)) { + largestKind = AMD64Kind.V256_QWORD; + } else { + largestKind = AMD64Kind.V128_QWORD; + } + } + + @Override + public EnumSet getFeatures() { + return features; + } + + public EnumSet getFlags() { + return flags; + } + + @Override + public RegisterArray getAvailableValueRegisters() { + if (features.contains(CPUFeature.AVX512F)) { + return valueRegistersAVX512; + } else { + return valueRegistersSSE; + } + } + + @Override + public PlatformKind getPlatformKind(JavaKind javaKind) { + switch (javaKind) { + case Boolean: + case Byte: + return AMD64Kind.BYTE; + case Short: + case Char: + return AMD64Kind.WORD; + case Int: + return AMD64Kind.DWORD; + case Long: + case Object: + return AMD64Kind.QWORD; + case Float: + return AMD64Kind.SINGLE; + case Double: + return AMD64Kind.DOUBLE; + default: + return null; + } + } + + @Override + public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { + AMD64Kind kind = (AMD64Kind) platformKind; + if (kind.isInteger()) { + return category.equals(CPU); + } else if (kind.isXMM()) { + return category.equals(XMM); + } else { + assert kind.isMask(); + return category.equals(MASK); + } + } + + @Override + public AMD64Kind getLargestStorableKind(RegisterCategory category) { + if (category.equals(CPU)) { + return AMD64Kind.QWORD; + } else if (category.equals(XMM)) { + return largestKind; + } else if (category.equals(MASK)) { + return AMD64Kind.MASK64; + } else { + return null; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64Kind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64Kind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64Kind.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64Kind.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,218 @@ +/* + * 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. + */ +package jdk.vm.ci.amd64; + +import jdk.vm.ci.meta.PlatformKind; + +public enum AMD64Kind implements PlatformKind { + + // scalar + BYTE(1), + WORD(2), + DWORD(4), + QWORD(8), + SINGLE(4), + DOUBLE(8), + + // SSE2 + V32_BYTE(4, BYTE), + V32_WORD(4, WORD), + V64_BYTE(8, BYTE), + V64_WORD(8, WORD), + V64_DWORD(8, DWORD), + V128_BYTE(16, BYTE), + V128_WORD(16, WORD), + V128_DWORD(16, DWORD), + V128_QWORD(16, QWORD), + V128_SINGLE(16, SINGLE), + V128_DOUBLE(16, DOUBLE), + + // AVX + V256_BYTE(32, BYTE), + V256_WORD(32, WORD), + V256_DWORD(32, DWORD), + V256_QWORD(32, QWORD), + V256_SINGLE(32, SINGLE), + V256_DOUBLE(32, DOUBLE), + + // AVX512 + V512_BYTE(64, BYTE), + V512_WORD(64, WORD), + V512_DWORD(64, DWORD), + V512_QWORD(64, QWORD), + V512_SINGLE(64, SINGLE), + V512_DOUBLE(64, DOUBLE), + + MASK8(1), + MASK16(2), + MASK32(4), + MASK64(8); + + private final int size; + private final int vectorLength; + + private final AMD64Kind scalar; + private final EnumKey key = new EnumKey<>(this); + + AMD64Kind(int size) { + this.size = size; + this.scalar = this; + this.vectorLength = 1; + } + + AMD64Kind(int size, AMD64Kind scalar) { + this.size = size; + this.scalar = scalar; + + assert size % scalar.size == 0; + this.vectorLength = size / scalar.size; + } + + public AMD64Kind getScalar() { + return scalar; + } + + @Override + public int getSizeInBytes() { + return size; + } + + @Override + public int getVectorLength() { + return vectorLength; + } + + @Override + public Key getKey() { + return key; + } + + public boolean isInteger() { + switch (this) { + case BYTE: + case WORD: + case DWORD: + case QWORD: + return true; + default: + return false; + } + } + + public boolean isXMM() { + switch (this) { + case SINGLE: + case DOUBLE: + case V32_BYTE: + case V32_WORD: + case V64_BYTE: + case V64_WORD: + case V64_DWORD: + case V128_BYTE: + case V128_WORD: + case V128_DWORD: + case V128_QWORD: + case V128_SINGLE: + case V128_DOUBLE: + case V256_BYTE: + case V256_WORD: + case V256_DWORD: + case V256_QWORD: + case V256_SINGLE: + case V256_DOUBLE: + case V512_BYTE: + case V512_WORD: + case V512_DWORD: + case V512_QWORD: + case V512_SINGLE: + case V512_DOUBLE: + return true; + default: + return false; + } + } + + public boolean isMask() { + switch (this) { + case MASK8: + case MASK16: + case MASK32: + case MASK64: + return true; + default: + return false; + } + } + + @Override + public char getTypeChar() { + switch (this) { + case BYTE: + return 'b'; + case WORD: + return 'w'; + case DWORD: + return 'd'; + case QWORD: + return 'q'; + case SINGLE: + return 'S'; + case DOUBLE: + return 'D'; + case V32_BYTE: + case V32_WORD: + case V64_BYTE: + case V64_WORD: + case V64_DWORD: + return 'v'; + case V128_BYTE: + case V128_WORD: + case V128_DWORD: + case V128_QWORD: + case V128_SINGLE: + case V128_DOUBLE: + return 'x'; + case V256_BYTE: + case V256_WORD: + case V256_DWORD: + case V256_QWORD: + case V256_SINGLE: + case V256_DOUBLE: + return 'y'; + case V512_BYTE: + case V512_WORD: + case V512_DWORD: + case V512_QWORD: + case V512_SINGLE: + case V512_DOUBLE: + return 'z'; + case MASK8: + case MASK16: + case MASK32: + case MASK64: + return 'k'; + default: + return '-'; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * The AMD64 platform independent portions of the JVMCI API. + */ +package jdk.vm.ci.amd64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Architecture.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Architecture.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Architecture.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Architecture.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.code; + +import java.nio.ByteOrder; +import java.util.Set; + +import jdk.vm.ci.code.Register.RegisterCategory; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.PlatformKind; + +/** + * Represents a CPU architecture, including information such as its endianness, CPU registers, word + * width, etc. + */ +public abstract class Architecture { + + /** + * The architecture specific type of a native word. + */ + private final PlatformKind wordKind; + + /** + * The name of this architecture (e.g. "AMD64"). + */ + private final String name; + + /** + * List of all available registers on this architecture. The index of each register in this list + * is equal to its {@linkplain Register#number number}. + */ + private final RegisterArray registers; + + /** + * The byte ordering can be either little or big endian. + */ + private final ByteOrder byteOrder; + + /** + * Whether the architecture supports unaligned memory accesses. + */ + private final boolean unalignedMemoryAccess; + + /** + * Mask of the barrier constants denoting the barriers that are not required to be explicitly + * inserted under this architecture. + */ + private final int implicitMemoryBarriers; + + /** + * Offset in bytes from the beginning of a call instruction to the displacement. + */ + private final int machineCodeCallDisplacementOffset; + + /** + * The size of the return address pushed to the stack by a call instruction. A value of 0 + * denotes that call linkage uses registers instead (e.g. SPARC). + */ + private final int returnAddressSize; + + protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, RegisterArray registers, int implicitMemoryBarriers, + int nativeCallDisplacementOffset, + int returnAddressSize) { + this.name = name; + this.registers = registers; + this.wordKind = wordKind; + this.byteOrder = byteOrder; + this.unalignedMemoryAccess = unalignedMemoryAccess; + this.implicitMemoryBarriers = implicitMemoryBarriers; + this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset; + this.returnAddressSize = returnAddressSize; + } + + /** + * Gets the set of CPU features supported by the current platform. + */ + public abstract Set getFeatures(); + + /** + * Converts this architecture to a string. + * + * @return the string representation of this architecture + */ + @Override + public final String toString() { + return getName().toLowerCase(); + } + + /** + * Gets the natural size of words (typically registers and pointers) of this architecture, in + * bytes. + */ + public int getWordSize() { + return wordKind.getSizeInBytes(); + } + + public PlatformKind getWordKind() { + return wordKind; + } + + /** + * Gets the name of this architecture. + */ + public String getName() { + return name; + } + + /** + * Gets the list of all registers that exist on this architecture. This contains all registers + * that exist in the specification of this architecture. Not all of them may be available on + * this particular architecture instance. The index of each register in this list is equal to + * its {@linkplain Register#number number}. + */ + public RegisterArray getRegisters() { + return registers; + } + + /** + * Gets a list of all registers available for storing values on this architecture. This may be a + * subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU. + */ + public RegisterArray getAvailableValueRegisters() { + return getRegisters(); + } + + public ByteOrder getByteOrder() { + return byteOrder; + } + + /** + * @return true if the architecture supports unaligned memory accesses. + */ + public boolean supportsUnalignedMemoryAccess() { + return unalignedMemoryAccess; + } + + /** + * Gets the size of the return address pushed to the stack by a call instruction. A value of 0 + * denotes that call linkage uses registers instead. + */ + public int getReturnAddressSize() { + return returnAddressSize; + } + + /** + * Gets the offset in bytes from the beginning of a call instruction to the displacement. + */ + public int getMachineCodeCallDisplacementOffset() { + return machineCodeCallDisplacementOffset; + } + + /** + * Determines the barriers in a given barrier mask that are explicitly required on this + * architecture. + * + * @param barriers a mask of the barrier constants + * @return the value of {@code barriers} minus the barriers unnecessary on this architecture + */ + public final int requiredBarriers(int barriers) { + return barriers & ~implicitMemoryBarriers; + } + + /** + * Determine whether a kind can be stored in a register of a given category. + * + * @param category the category of the register + * @param kind the kind that should be stored in the register + */ + public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind); + + /** + * Return the largest kind that can be stored in a register of a given category. + * + * @param category the category of the register + * @return the largest kind that can be stored in a register {@code category} + */ + public abstract PlatformKind getLargestStorableKind(RegisterCategory category); + + /** + * Gets the {@link PlatformKind} that is used to store values of a given {@link JavaKind}. + * + * @return {@code null} if there no deterministic {@link PlatformKind} for {@code javaKind} + */ + public abstract PlatformKind getPlatformKind(JavaKind javaKind); + + @Override + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Architecture) { + Architecture that = (Architecture) obj; + if (this.name.equals(that.name)) { + assert this.byteOrder.equals(that.byteOrder); + assert this.implicitMemoryBarriers == that.implicitMemoryBarriers; + assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset; + assert this.registers.equals(that.registers); + assert this.returnAddressSize == that.returnAddressSize; + assert this.unalignedMemoryAccess == that.unalignedMemoryAccess; + assert this.wordKind == that.wordKind; + return true; + } + } + return false; + } + + @Override + public final int hashCode() { + return name.hashCode(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BailoutException.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BailoutException.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BailoutException.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BailoutException.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.Locale; + +/** + * Exception thrown when the compiler refuses to compile a method because of problems with the + * method. e.g. bytecode wouldn't verify, too big, JSR/ret too complicated, etc. This exception is + * not meant to indicate problems with the compiler itself. + */ +public class BailoutException extends RuntimeException { + + public static final long serialVersionUID = 8974598793458772L; + private final boolean permanent; + + /** + * Creates a new {@link BailoutException}. + * + * + * @param args parameters to the formatter + */ + public BailoutException(String format, Object... args) { + super(String.format(Locale.ENGLISH, format, args)); + this.permanent = true; + } + + /** + * Creates a new {@link BailoutException}. + * + * + * @param args parameters to the formatter + */ + public BailoutException(Throwable cause, String format, Object... args) { + super(String.format(Locale.ENGLISH, format, args), cause); + this.permanent = true; + } + + /** + * Creates a new {@link BailoutException}. + * + * @param permanent specifies whether this exception will occur again if compilation is retried + * @param args parameters to the formatter + */ + public BailoutException(boolean permanent, String format, Object... args) { + super(String.format(Locale.ENGLISH, format, args)); + this.permanent = permanent; + } + + /** + * @return whether this exception will occur again if compilation is retried + */ + public boolean isPermanent() { + return permanent; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.Arrays; +import java.util.Objects; + +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.Value; + +/** + * Represents the Java bytecode frame state(s) at a given position including {@link Value locations} + * where to find the local variables, operand stack values and locked objects of the bytecode + * frame(s). + */ +public final class BytecodeFrame extends BytecodePosition { + + /** + * An array of values representing how to reconstruct the state of the Java frame. This is array + * is partitioned as follows: + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Start index (inclusive)End index (exclusive)Description
    0numLocalsLocal variables
    numLocalsnumLocals + numStackOperand stack
    numLocals + numStackvalues.lengthLocked objects
    + *

    + * Note that the number of locals and the number of stack slots may be smaller than the maximum + * number of locals and stack slots as specified in the compiled method. + * + * This field is intentionally exposed as a mutable array that a compiler may modify (e.g. + * during register allocation). + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "field is intentionally mutable")// + public final JavaValue[] values; + + /** + * An array describing the Java kinds in {@link #values}. It records a kind for the locals and + * the operand stack. + */ + private final JavaKind[] slotKinds; + + /** + * The number of locals in the values array. + */ + public final int numLocals; + + /** + * The number of stack slots in the values array. + */ + public final int numStack; + + /** + * The number of locks in the values array. + */ + public final int numLocks; + + /** + * True if this is a position inside an exception handler before the exception object has been + * consumed. In this case, {@link #numStack} {@code == 1} and {@link #getStackValue(int) + * getStackValue(0)} is the location of the exception object. If deoptimization happens at this + * position, the interpreter will rethrow the exception instead of executing the bytecode + * instruction at this position. + */ + public final boolean rethrowException; + + /** + * Specifies if this object represents a frame state in the middle of executing a call. If true, + * the arguments to the call have been popped from the stack and the return value (for a + * non-void call) has not yet been pushed. + */ + public final boolean duringCall; + + /** + * This BCI should be used for frame states that are built for code with no meaningful BCI. + */ + public static final int UNKNOWN_BCI = -5; + + /** + * The BCI for exception unwind. This is synthetic code and has no representation in bytecode. + * In contrast with {@link #AFTER_EXCEPTION_BCI}, at this point, if the method is synchronized, + * the monitor is still held. + */ + public static final int UNWIND_BCI = -1; + + /** + * The BCI for the state before starting to execute a method. Note that if the method is + * synchronized, the monitor is not yet held. + */ + public static final int BEFORE_BCI = -2; + + /** + * The BCI for the state after finishing the execution of a method and returning normally. Note + * that if the method was synchronized the monitor is already released. + */ + public static final int AFTER_BCI = -3; + + /** + * The BCI for exception unwind. This is synthetic code and has no representation in bytecode. + * In contrast with {@link #UNWIND_BCI}, at this point, if the method is synchronized, the + * monitor is already released. + */ + public static final int AFTER_EXCEPTION_BCI = -4; + + /** + * This BCI should be used for states that cannot be the target of a deoptimization, like + * snippet frame states. + */ + public static final int INVALID_FRAMESTATE_BCI = -6; + + /** + * Determines if a given BCI matches one of the placeholder BCI constants defined in this class. + */ + public static boolean isPlaceholderBci(int bci) { + return bci < 0; + } + + /** + * Gets the name of a given placeholder BCI. + */ + public static String getPlaceholderBciName(int bci) { + assert isPlaceholderBci(bci); + if (bci == BytecodeFrame.AFTER_BCI) { + return "AFTER_BCI"; + } else if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) { + return "AFTER_EXCEPTION_BCI"; + } else if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) { + return "INVALID_FRAMESTATE_BCI"; + } else if (bci == BytecodeFrame.BEFORE_BCI) { + return "BEFORE_BCI"; + } else if (bci == BytecodeFrame.UNKNOWN_BCI) { + return "UNKNOWN_BCI"; + } else { + assert bci == BytecodeFrame.UNWIND_BCI; + return "UNWIND_BCI"; + } + } + + /** + * Creates a new frame object. + * + * @param caller the caller frame (which may be {@code null}) + * @param method the method + * @param bci a BCI within the method + * @param rethrowException specifies if the VM should re-throw the pending exception when + * deopt'ing using this frame + * @param values the frame state {@link #values}. + * @param slotKinds the kinds in {@code values}. This array is now owned by this object and must + * not be mutated by the caller. + * @param numLocals the number of local variables + * @param numStack the depth of the stack + * @param numLocks the number of locked objects + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `slotKinds`") + public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, JavaValue[] values, JavaKind[] slotKinds, int numLocals, int numStack, + int numLocks) { + super(caller, method, bci); + assert values != null; + this.rethrowException = rethrowException; + this.duringCall = duringCall; + this.values = values; + this.slotKinds = slotKinds; + this.numLocals = numLocals; + this.numStack = numStack; + this.numLocks = numLocks; + assert !rethrowException || numStack == 1 : "must have exception on top of the stack"; + } + + /** + * Ensure that the frame state is formatted as expected by the JVM, with null or Illegal in the + * slot following a double word item. This should really be checked in FrameState itself but + * because of Word type rewriting and alternative backends that can't be done. + */ + public boolean validateFormat() { + if (caller() != null) { + caller().validateFormat(); + } + for (int i = 0; i < numLocals + numStack; i++) { + if (values[i] != null) { + JavaKind kind = slotKinds[i]; + if (kind.needsTwoSlots()) { + assert slotKinds.length > i + 1 : String.format("missing second word %s", this); + assert slotKinds[i + 1] == JavaKind.Illegal : this; + } + } + } + return true; + } + + /** + * Gets the kind of a local variable. + * + * @param i the local variable to query + * @return the kind of local variable {@code i} + * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocals} + */ + public JavaKind getLocalValueKind(int i) { + if (i < 0 || i >= numLocals) { + throw new IndexOutOfBoundsException(); + } + return slotKinds[i]; + } + + /** + * Gets the kind of a stack slot. + * + * @param i the local variable to query + * @return the kind of stack slot {@code i} + * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numStack} + */ + public JavaKind getStackValueKind(int i) { + if (i < 0 || i >= numStack) { + throw new IndexOutOfBoundsException(); + } + return slotKinds[i + numLocals]; + } + + /** + * Gets the value representing the specified local variable. + * + * @param i the local variable index + * @return the value that can be used to reconstruct the local's current value + * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocals} + */ + public JavaValue getLocalValue(int i) { + if (i < 0 || i >= numLocals) { + throw new IndexOutOfBoundsException(); + } + return values[i]; + } + + /** + * Gets the value representing the specified stack slot. + * + * @param i the stack index + * @return the value that can be used to reconstruct the stack slot's current value + * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numStack} + */ + public JavaValue getStackValue(int i) { + if (i < 0 || i >= numStack) { + throw new IndexOutOfBoundsException(); + } + return values[i + numLocals]; + } + + /** + * Gets the value representing the specified lock. + * + * @param i the lock index + * @return the value that can be used to reconstruct the lock's current value + * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocks} + */ + public JavaValue getLockValue(int i) { + if (i < 0 || i >= numLocks) { + throw new IndexOutOfBoundsException(); + } + return values[i + numLocals + numStack]; + } + + /** + * Gets the caller of this frame. + * + * @return {@code null} if this frame has no caller + */ + public BytecodeFrame caller() { + return (BytecodeFrame) getCaller(); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), + duringCall, + numLocals, + numLocks, + numStack, + rethrowException, + Arrays.hashCode(slotKinds), + Arrays.hashCode(values)); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BytecodeFrame that = (BytecodeFrame) obj; + return duringCall == that.duringCall && + numLocals == that.numLocals && + numLocks == that.numLocks && + numStack == that.numStack && + rethrowException == that.rethrowException && + Arrays.equals(slotKinds, that.slotKinds) && + Arrays.equals(values, that.values); + } + + @Override + public String toString() { + return CodeUtil.append(new StringBuilder(100), this).toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodePosition.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodePosition.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodePosition.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodePosition.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.Objects; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Represents a code position, that is, a chain of inlined methods with bytecode locations, that is + * communicated from the compiler to the runtime system. A code position can be used by the runtime + * system to reconstruct a source-level stack trace for exceptions and to create + * {@linkplain BytecodeFrame frames} for deoptimization. + */ +public class BytecodePosition { + + private final BytecodePosition caller; + private final ResolvedJavaMethod method; + private final int bci; + + /** + * Constructs a new object representing a given parent/caller, a given method, and a given BCI. + * + * @param caller the parent position + * @param method the method + * @param bci a BCI such that {@code method.codeSize() == 0 || bci < method.getCodeSize()}. That + * is, if code size is 0 then allow any value, otherwise the bci must be less than + * the code size. + */ + public BytecodePosition(BytecodePosition caller, ResolvedJavaMethod method, int bci) { + assert method != null; + this.caller = caller; + this.method = method; + this.bci = bci; + int codeSize = method.getCodeSize(); + if (codeSize != 0 && bci >= codeSize) { + throw new IllegalArgumentException(String.format("bci %d is out of range for %s %d bytes", bci, method.format("%H.%n(%p)"), codeSize)); + } + } + + /** + * Converts this code position to a string representation. + * + * @return a string representation of this code position + */ + @Override + public String toString() { + return CodeUtil.append(new StringBuilder(100), this).toString(); + } + + /** + * Deep equality test. + */ + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj != null && getClass() == obj.getClass()) { + BytecodePosition that = (BytecodePosition) obj; + if (this.bci == that.bci && Objects.equals(this.getMethod(), that.getMethod()) && Objects.equals(this.caller, that.caller)) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + int hc = method.hashCode() * 31 + bci; + if (caller != null) { + hc = (hc * 31) + caller.hashCode(); + } + return hc; + } + + /** + * @return The location within the method, as a bytecode index. The constant {@code -1} may be + * used to indicate the location is unknown, for example within code synthesized by the + * compiler. + */ + public int getBCI() { + return bci; + } + + /** + * @return The runtime interface method for this position. + */ + public ResolvedJavaMethod getMethod() { + return method; + } + + /** + * The position where this position has been called, {@code null} if none. + */ + public BytecodePosition getCaller() { + return caller; + } + + /** + * Adds a caller to the current position returning the new position. + */ + public BytecodePosition addCaller(BytecodePosition link) { + if (getCaller() == null) { + return new BytecodePosition(link, getMethod(), getBCI()); + } else { + return new BytecodePosition(getCaller().addCaller(link), getMethod(), getBCI()); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CallingConvention.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CallingConvention.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CallingConvention.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CallingConvention.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import static jdk.vm.ci.code.ValueUtil.isAllocatableValue; +import static jdk.vm.ci.code.ValueUtil.isStackSlot; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.Value; + +/** + * A calling convention describes the locations in which the arguments for a call are placed and the + * location in which the return value is placed if the call is not void. + */ +public class CallingConvention { + + /** + * Marker interface denoting the type of a call for which a calling convention is requested. + */ + public interface Type { + } + + /** + * The amount of stack space (in bytes) required for the stack-based arguments of the call. + */ + private final int stackSize; + + private final AllocatableValue returnLocation; + + /** + * The ordered locations in which the arguments are placed. + */ + private final AllocatableValue[] argumentLocations; + + /** + * Creates a description of the registers and stack locations used by a call. + * + * @param stackSize amount of stack space (in bytes) required for the stack-based arguments of + * the call + * @param returnLocation the location for the return value or {@link Value#ILLEGAL} if a void + * call + * @param argumentLocations the ordered locations in which the arguments are placed + */ + public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) { + assert argumentLocations != null; + assert returnLocation != null; + this.argumentLocations = argumentLocations; + this.stackSize = stackSize; + this.returnLocation = returnLocation; + assert verify(); + } + + /** + * Gets the location for the return value or {@link Value#ILLEGAL} if a void call. + */ + public AllocatableValue getReturn() { + return returnLocation; + } + + /** + * Gets the location for the {@code index}'th argument. + */ + public AllocatableValue getArgument(int index) { + return argumentLocations[index]; + } + + /** + * Gets the amount of stack space (in bytes) required for the stack-based arguments of the call. + */ + public int getStackSize() { + return stackSize; + } + + /** + * Gets the number of locations required for the arguments. + */ + public int getArgumentCount() { + return argumentLocations.length; + } + + /** + * Gets the locations required for the arguments. + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "FB false positive") + public AllocatableValue[] getArguments() { + if (argumentLocations.length == 0) { + return argumentLocations; + } + return argumentLocations.clone(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("CallingConvention["); + String sep = ""; + for (Value op : argumentLocations) { + sb.append(sep).append(op); + sep = ", "; + } + if (!returnLocation.equals(Value.ILLEGAL)) { + sb.append(" -> ").append(returnLocation); + } + sb.append("]"); + return sb.toString(); + } + + private boolean verify() { + for (int i = 0; i < argumentLocations.length; i++) { + Value location = argumentLocations[i]; + assert isStackSlot(location) || isAllocatableValue(location); + } + return true; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeCacheProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeCacheProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeCacheProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeCacheProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2009, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.code.site.Call; +import jdk.vm.ci.code.site.Mark; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.SpeculationLog; + +/** + * Access to code cache related details and requirements. + */ +public interface CodeCacheProvider { + + /** + * Installs code for a given method based on a given compilation result without making it the + * default implementation of the method. + * + * @param method a method implemented by the installed code + * @param compiledCode the compiled code to be added + * @param log the speculation log to be used + * @param installedCode a predefined {@link InstalledCode} object to use as a reference to the + * installed code. If {@code null}, a new {@link InstalledCode} object will be + * created. + * @return a reference to the ready-to-run code + * @throws BailoutException if the code installation failed + * @throws IllegalArgumentException if {@code installedCode != null} and this object does not + * support a predefined {@link InstalledCode} object + */ + default InstalledCode addCode(ResolvedJavaMethod method, CompiledCode compiledCode, SpeculationLog log, InstalledCode installedCode) { + return installCode(method, compiledCode, installedCode, log, false); + } + + /** + * Installs code for a given method based on a given compilation result and makes it the default + * implementation of the method. + * + * @param method a method implemented by the installed code and for which the installed code + * becomes the default implementation + * @param compiledCode the compiled code to be added + * @return a reference to the ready-to-run code + * @throws BailoutException if the code installation failed + * @throws IllegalArgumentException if {@code installedCode != null} and this object does not + * support a predefined {@link InstalledCode} object + */ + default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompiledCode compiledCode) { + return installCode(method, compiledCode, null, null, true); + } + + /** + * Installs code based on a given compilation result. + * + * @param method the method compiled to produce {@code compiledCode} or {@code null} if the + * input to {@code compResult} was not a {@link ResolvedJavaMethod} + * @param compiledCode the compiled code to be added + * @param installedCode a pre-allocated {@link InstalledCode} object to use as a reference to + * the installed code. If {@code null}, a new {@link InstalledCode} object will be + * created. + * @param log the speculation log to be used + * @param isDefault specifies if the installed code should be made the default implementation of + * {@code compRequest.getMethod()}. The default implementation for a method is the + * code executed for standard calls to the method. This argument is ignored if + * {@code compRequest == null}. + * @return a reference to the compiled and ready-to-run installed code + * @throws BailoutException if the code installation failed + */ + InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault); + + /** + * Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be + * raised the next time {@code installedCode} is + * {@linkplain InstalledCode#executeVarargs(Object...) executed}. + */ + void invalidateInstalledCode(InstalledCode installedCode); + + /** + * Gets a name for a {@link Mark} mark. + */ + default String getMarkName(Mark mark) { + return String.valueOf(mark.id); + } + + /** + * Gets a name for the {@linkplain Call#target target} of a {@link Call}. + */ + default String getTargetName(Call call) { + return String.valueOf(call.target); + } + + /** + * Gets the register configuration to use when compiling a given method. + */ + RegisterConfig getRegisterConfig(); + + /** + * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all + * cases, even when the compiled method has no regular call instructions. + * + * @return the minimum size of the outgoing parameter area in bytes + */ + int getMinimumOutgoingSize(); + + /** + * Gets a description of the target architecture. + */ + TargetDescription getTarget(); + + /** + * Create a new speculation log for the target runtime. + */ + SpeculationLog createSpeculationLog(); + + /** + * Returns the maximum absolute offset of a PC relative call to a given address from any + * position in the code cache or -1 when not applicable. Intended for determining the required + * size of address/offset fields. + */ + long getMaxCallTargetOffset(long address); + + /** + * Determines if debug info should also be emitted at non-safepoint locations. + */ + boolean shouldDebugNonSafepoints(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeUtil.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeUtil.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CodeUtil.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.MetaUtil; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.Signature; + +/** + * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.code} and its clients. + */ +public class CodeUtil { + + public static final String NEW_LINE = String.format("%n"); + + public static final int K = 1024; + public static final int M = 1024 * 1024; + + public static boolean isOdd(int n) { + return (n & 1) == 1; + } + + public static boolean isEven(int n) { + return (n & 1) == 0; + } + + /** + * Checks whether the specified integer is a power of two. + * + * @param val the value to check + * @return {@code true} if the value is a power of two; {@code false} otherwise + */ + public static boolean isPowerOf2(int val) { + return val > 0 && (val & val - 1) == 0; + } + + /** + * Checks whether the specified long is a power of two. + * + * @param val the value to check + * @return {@code true} if the value is a power of two; {@code false} otherwise + */ + public static boolean isPowerOf2(long val) { + return val > 0 && (val & val - 1) == 0; + } + + /** + * Computes the log (base 2) of the specified integer, rounding down. (E.g {@code log2(8) = 3}, + * {@code log2(21) = 4} ) + * + * @param val the value + * @return the log base 2 of the value + */ + public static int log2(int val) { + assert val > 0; + return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(val); + } + + /** + * Computes the log (base 2) of the specified long, rounding down. (E.g {@code log2(8) = 3}, + * {@code log2(21) = 4}) + * + * @param val the value + * @return the log base 2 of the value + */ + public static int log2(long val) { + assert val > 0; + return (Long.SIZE - 1) - Long.numberOfLeadingZeros(val); + } + + /** + * Narrow an integer value to a given bit width, and return the result as a signed long. + * + * @param value the value + * @param resultBits the result bit width + * @return {@code value} interpreted as {@code resultBits} bit number, encoded as signed long + */ + public static long narrow(long value, int resultBits) { + long ret = value & mask(resultBits); + return signExtend(ret, resultBits); + } + + /** + * Sign extend an integer. + * + * @param value the input value + * @param inputBits the bit width of the input value + * @return a signed long with the same value as the signed {@code inputBits}-bit number + * {@code value} + */ + public static long signExtend(long value, int inputBits) { + if (inputBits < 64) { + if ((value >>> (inputBits - 1) & 1) == 1) { + return value | (-1L << inputBits); + } else { + return value & ~(-1L << inputBits); + } + } else { + return value; + } + } + + /** + * Zero extend an integer. + * + * @param value the input value + * @param inputBits the bit width of the input value + * @return an unsigned long with the same value as the unsigned {@code inputBits}-bit number + * {@code value} + */ + public static long zeroExtend(long value, int inputBits) { + if (inputBits < 64) { + return value & ~(-1L << inputBits); + } else { + return value; + } + } + + /** + * Convert an integer to long. + * + * @param value the input value + * @param inputBits the bit width of the input value + * @param unsigned whether the values should be interpreted as signed or unsigned + * @return a long with the same value as the {@code inputBits}-bit number {@code value} + */ + public static long convert(long value, int inputBits, boolean unsigned) { + if (unsigned) { + return zeroExtend(value, inputBits); + } else { + return signExtend(value, inputBits); + } + } + + /** + * Get a bitmask with the low {@code bits} bit set and the high {@code 64 - bits} bit clear. + */ + public static long mask(int bits) { + assert 0 <= bits && bits <= 64; + if (bits == 64) { + return 0xffffffffffffffffL; + } else { + return (1L << bits) - 1; + } + } + + /** + * Get the minimum value representable in a {@code bits} bit signed integer. + */ + public static long minValue(int bits) { + assert 0 < bits && bits <= 64; + return -1L << (bits - 1); + } + + /** + * Get the maximum value representable in a {@code bits} bit signed integer. + */ + public static long maxValue(int bits) { + assert 0 < bits && bits <= 64; + return mask(bits - 1); + } + + /** + * Formats the values in a frame as a tabulated string. + * + * @param frame + * @return the values in {@code frame} as a tabulated string + */ + public static String tabulateValues(BytecodeFrame frame) { + int cols = Math.max(frame.numLocals, Math.max(frame.numStack, frame.numLocks)); + assert cols > 0; + ArrayList cells = new ArrayList<>(); + cells.add(""); + for (int i = 0; i < cols; i++) { + cells.add(i); + } + cols++; + if (frame.numLocals != 0) { + cells.add("locals:"); + cells.addAll(Arrays.asList(frame.values).subList(0, frame.numLocals)); + cells.addAll(Collections.nCopies(cols - frame.numLocals - 1, "")); + } + if (frame.numStack != 0) { + cells.add("stack:"); + cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals, frame.numLocals + frame.numStack)); + cells.addAll(Collections.nCopies(cols - frame.numStack - 1, "")); + } + if (frame.numLocks != 0) { + cells.add("locks:"); + cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals + frame.numStack, frame.values.length)); + cells.addAll(Collections.nCopies(cols - frame.numLocks - 1, "")); + } + Object[] cellArray = cells.toArray(); + for (int i = 0; i < cellArray.length; i++) { + if ((i % cols) != 0) { + cellArray[i] = "|" + cellArray[i]; + } + } + return CodeUtil.tabulate(cellArray, cols, 1, 1); + } + + /** + * Formats a given table as a string. The value of each cell is produced by + * {@link String#valueOf(Object)}. + * + * @param cells the cells of the table in row-major order + * @param cols the number of columns per row + * @param lpad the number of space padding inserted before each formatted cell value + * @param rpad the number of space padding inserted after each formatted cell value + * @return a string with one line per row and each column left-aligned + */ + public static String tabulate(Object[] cells, int cols, int lpad, int rpad) { + int rows = (cells.length + (cols - 1)) / cols; + int[] colWidths = new int[cols]; + for (int col = 0; col < cols; col++) { + for (int row = 0; row < rows; row++) { + int index = col + (row * cols); + if (index < cells.length) { + Object cell = cells[index]; + colWidths[col] = Math.max(colWidths[col], String.valueOf(cell).length()); + } + } + } + StringBuilder sb = new StringBuilder(); + String nl = NEW_LINE; + for (int row = 0; row < rows; row++) { + for (int col = 0; col < cols; col++) { + int index = col + (row * cols); + if (index < cells.length) { + for (int i = 0; i < lpad; i++) { + sb.append(' '); + } + Object cell = cells[index]; + String s = String.valueOf(cell); + int w = s.length(); + sb.append(s); + while (w < colWidths[col]) { + sb.append(' '); + w++; + } + for (int i = 0; i < rpad; i++) { + sb.append(' '); + } + } + } + sb.append(nl); + } + return sb.toString(); + } + + /** + * Appends a formatted code position to a {@link StringBuilder}. + * + * @param sb the {@link StringBuilder} to append to + * @param pos the code position to format and append to {@code sb} + * @return the value of {@code sb} + */ + public static StringBuilder append(StringBuilder sb, BytecodePosition pos) { + MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI()); + if (pos.getCaller() != null) { + sb.append(NEW_LINE); + append(sb, pos.getCaller()); + } + return sb; + } + + /** + * Appends a formatted frame to a {@link StringBuilder}. + * + * @param sb the {@link StringBuilder} to append to + * @param frame the frame to format and append to {@code sb} + * @return the value of {@code sb} + */ + public static StringBuilder append(StringBuilder sb, BytecodeFrame frame) { + MetaUtil.appendLocation(sb.append("at "), frame.getMethod(), frame.getBCI()); + assert sb.charAt(sb.length() - 1) == ']'; + sb.deleteCharAt(sb.length() - 1); + sb.append(", duringCall: ").append(frame.duringCall).append(", rethrow: ").append(frame.rethrowException).append(']'); + if (frame.values != null && frame.values.length > 0) { + sb.append(NEW_LINE); + String table = tabulateValues(frame); + String[] rows = table.split(NEW_LINE); + for (int i = 0; i < rows.length; i++) { + String row = rows[i]; + if (!row.trim().isEmpty()) { + sb.append(" ").append(row); + if (i != rows.length - 1) { + sb.append(NEW_LINE); + } + } + } + } + if (frame.caller() != null) { + sb.append(NEW_LINE); + append(sb, frame.caller()); + } else if (frame.getCaller() != null) { + sb.append(NEW_LINE); + append(sb, frame.getCaller()); + } + return sb; + } + + public interface RefMapFormatter { + + String formatStackSlot(int frameRefMapIndex); + } + + /** + * Formats a location present in a reference map. + */ + public static class DefaultRefMapFormatter implements RefMapFormatter { + + /** + * The size of a stack slot. + */ + public final int slotSize; + + /** + * The register used as the frame pointer. + */ + public final Register fp; + + /** + * The offset (in bytes) from the slot pointed to by {@link #fp} to the slot corresponding + * to bit 0 in the frame reference map. + */ + public final int refMapToFPOffset; + + public DefaultRefMapFormatter(int slotSize, Register fp, int refMapToFPOffset) { + this.slotSize = slotSize; + this.fp = fp; + this.refMapToFPOffset = refMapToFPOffset; + } + + @Override + public String formatStackSlot(int frameRefMapIndex) { + int refMapOffset = frameRefMapIndex * slotSize; + int fpOffset = refMapOffset + refMapToFPOffset; + if (fpOffset >= 0) { + return fp + "+" + fpOffset; + } + return fp.name + fpOffset; + } + } + + public static class NumberedRefMapFormatter implements RefMapFormatter { + + @Override + public String formatStackSlot(int frameRefMapIndex) { + return "s" + frameRefMapIndex; + } + + public String formatRegister(int regRefMapIndex) { + return "r" + regRefMapIndex; + } + } + + /** + * Appends a formatted debug info to a {@link StringBuilder}. + * + * @param sb the {@link StringBuilder} to append to + * @param info the debug info to format and append to {@code sb} + * @return the value of {@code sb} + */ + public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatterArg) { + RefMapFormatter formatter = formatterArg; + if (formatter == null) { + formatter = new NumberedRefMapFormatter(); + } + String nl = NEW_LINE; + ReferenceMap refMap = info.getReferenceMap(); + if (refMap != null) { + sb.append(refMap.toString()); + } + RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); + if (calleeSaveInfo != null) { + sb.append("callee-save-info:").append(nl); + Map map = calleeSaveInfo.slotsToRegisters(true); + for (Map.Entry e : map.entrySet()) { + sb.append(" ").append(e.getValue()).append(" -> ").append(formatter.formatStackSlot(e.getKey())).append(nl); + } + } + BytecodeFrame frame = info.frame(); + if (frame != null) { + append(sb, frame); + } else if (info.getBytecodePosition() != null) { + append(sb, info.getBytecodePosition()); + } + return sb; + } + + /** + * Create a calling convention from a {@link ResolvedJavaMethod}. + */ + public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, ValueKindFactory valueKindFactory) { + Signature sig = method.getSignature(); + JavaType retType = sig.getReturnType(null); + int sigCount = sig.getParameterCount(false); + JavaType[] argTypes; + int argIndex = 0; + if (!method.isStatic()) { + argTypes = new JavaType[sigCount + 1]; + argTypes[argIndex++] = method.getDeclaringClass(); + } else { + argTypes = new JavaType[sigCount]; + } + for (int i = 0; i < sigCount; i++) { + argTypes[argIndex++] = sig.getParameterType(i, null); + } + + RegisterConfig registerConfig = codeCache.getRegisterConfig(); + return registerConfig.getCallingConvention(type, retType, argTypes, valueKindFactory); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequest.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequest.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,78 @@ +/* + * 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. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Represents a request to compile a method. + */ +public class CompilationRequest { + + private final ResolvedJavaMethod method; + + private final int entryBCI; + + /** + * Creates a request to compile a method starting at its entry point. + * + * @param method the method to be compiled + */ + public CompilationRequest(ResolvedJavaMethod method) { + this(method, -1); + } + + /** + * Creates a request to compile a method starting at a given BCI. + * + * @param method the method to be compiled + * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the + * method's entry point + */ + public CompilationRequest(ResolvedJavaMethod method, int entryBCI) { + assert method != null; + this.method = method; + this.entryBCI = entryBCI; + } + + /** + * Gets the method to be compiled. + */ + public ResolvedJavaMethod getMethod() { + return method; + } + + /** + * Gets the bytecode index (BCI) at which to start compiling where -1 denotes a non-OSR + * compilation request and all other values denote an on stack replacement (OSR) compilation + * request. + */ + public int getEntryBCI() { + return entryBCI; + } + + @Override + public String toString() { + return method.format("%H.%n(%p)@" + entryBCI); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequestResult.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequestResult.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequestResult.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompilationRequestResult.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * 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. + */ +package jdk.vm.ci.code; + +/** + * Provides information about the result of a {@link CompilationRequest}. + */ +public interface CompilationRequestResult { + + /** + * Determines if the compilation was successful. + * + * @return a non-null object whose {@link Object#toString()} describes the failure or null if + * compilation was successful + */ + Object getFailure(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompiledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompiledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompiledCode.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CompiledCode.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +/** + * Marker type for an object containing the output of a compiler in a form suitable for installing + * into a managed code heap. Since the details of a code heap are specific to each runtime, this + * interface does not specify any methods. + */ +public interface CompiledCode { +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CPUFeatureName.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CPUFeatureName.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CPUFeatureName.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/CPUFeatureName.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 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. + */ +package jdk.vm.ci.code; + +/** + * A CPU feature identified by a name. + */ +public interface CPUFeatureName { + /** + * Gets the name of this feature. + */ + String name(); + + /** + * Determines if {@code other} equals {@link #name()}. + */ + default boolean nameEquals(String other) { + return name().equals(other); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/DebugInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/DebugInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/DebugInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/DebugInfo.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.code; + +import java.util.Objects; + +/** + * Represents the debugging information for a particular point of execution. This information + * includes: + *
      + *
    • a {@linkplain #getBytecodePosition() bytecode position}
    • + *
    • a reference map for registers and stack slots in the current frame
    • + *
    • a map from bytecode locals and operand stack slots to their values or locations from which + * their values can be read
    • + *
    • a map from the registers (in the caller's frame) to the slots where they are saved in the + * current frame
    • + *
    + */ +public final class DebugInfo { + + private final BytecodePosition bytecodePosition; + private ReferenceMap referenceMap; + private final VirtualObject[] virtualObjectMapping; + private RegisterSaveLayout calleeSaveInfo; + + /** + * Creates a new {@link DebugInfo} from the given values. + * + * @param codePos the {@linkplain BytecodePosition code position} or {@linkplain BytecodeFrame + * frame} info + * @param virtualObjectMapping the mapping of {@link VirtualObject}s to their real values. This + * array is now owned by this object and must not be mutated by the caller. + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `virtualObjectMapping`") + public DebugInfo(BytecodePosition codePos, VirtualObject[] virtualObjectMapping) { + this.bytecodePosition = codePos; + this.virtualObjectMapping = virtualObjectMapping; + } + + public DebugInfo(BytecodePosition codePos) { + this(codePos, null); + } + + public void setReferenceMap(ReferenceMap referenceMap) { + this.referenceMap = referenceMap; + } + + /** + * @return {@code true} if this debug information has a frame + */ + public boolean hasFrame() { + return getBytecodePosition() instanceof BytecodeFrame; + } + + /** + * Gets the deoptimization information for each inlined frame (if available). + * + * @return {@code null} if no frame de-opt info is {@linkplain #hasFrame() available} + */ + public BytecodeFrame frame() { + if (hasFrame()) { + return (BytecodeFrame) getBytecodePosition(); + } + return null; + } + + @Override + public String toString() { + return CodeUtil.append(new StringBuilder(100), this, null).toString(); + } + + /** + * @return The code position (including all inlined methods) of this debug info. If this is a + * {@link BytecodeFrame} instance, then it is also the deoptimization information for + * each inlined frame. + */ + public BytecodePosition getBytecodePosition() { + return bytecodePosition; + } + + public ReferenceMap getReferenceMap() { + return referenceMap; + } + + public VirtualObject[] getVirtualObjectMapping() { + return virtualObjectMapping; + } + + /** + * Sets the map from the registers (in the caller's frame) to the slots where they are saved in + * the current frame. + */ + public void setCalleeSaveInfo(RegisterSaveLayout calleeSaveInfo) { + this.calleeSaveInfo = calleeSaveInfo; + } + + /** + * Gets the map from the registers (in the caller's frame) to the slots where they are saved in + * the current frame. If no such information is available, {@code null} is returned. + */ + public RegisterSaveLayout getCalleeSaveInfo() { + return calleeSaveInfo; + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DebugInfo) { + DebugInfo that = (DebugInfo) obj; + if (Objects.equals(this.bytecodePosition, that.bytecodePosition) && Objects.equals(this.calleeSaveInfo, that.calleeSaveInfo) && Objects.equals(this.referenceMap, that.referenceMap)) { + return true; + } + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InstalledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InstalledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InstalledCode.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InstalledCode.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +/** + * Represents a compiled instance of a method. It may have been invalidated or removed in the + * meantime. + */ +public class InstalledCode { + + /** + * Raw address address of entity representing this installed code. + */ + protected long address; + + /** + * Raw address of entryPoint of this installed code. + */ + protected long entryPoint; + + /** + * Counts how often the address field was reassigned. + */ + protected long version; + + protected final String name; + + public InstalledCode(String name) { + this.name = name; + } + + /** + * @return the address of entity representing this installed code. + */ + public long getAddress() { + return address; + } + + /** + * @return the address of the normal entry point of the installed code. + */ + public long getEntryPoint() { + return entryPoint; + } + + /** + * @return the version number of this installed code + */ + public final long getVersion() { + return version; + } + + /** + * Returns the name of this installed code. + */ + public String getName() { + return name; + } + + /** + * Returns the start address of this installed code if it is {@linkplain #isValid() valid}, 0 + * otherwise. + */ + public long getStart() { + return 0; + } + + /** + * @return true if the code represented by this object is still valid for invocation, false + * otherwise (may happen due to deopt, etc.) + */ + public boolean isValid() { + return entryPoint != 0; + } + + /** + * @return true if the code represented by this object still exists and might have live + * activations, false otherwise (may happen due to deopt, etc.) + */ + public boolean isAlive() { + return address != 0; + } + + /** + * Returns a copy of this installed code if it is {@linkplain #isValid() valid}, null otherwise. + */ + public byte[] getCode() { + return null; + } + + /** + * Invalidates this installed code such that any subsequent + * {@linkplain #executeVarargs(Object...) invocation} will throw an + * {@link InvalidInstalledCodeException} and all existing invocations will be deoptimized. + */ + public void invalidate() { + throw new UnsupportedOperationException(); + } + + /** + * Executes the installed code with a variable number of arguments. + * + * @param args the array of object arguments + * @return the value returned by the executed code + */ + @SuppressWarnings("unused") + public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { + throw new UnsupportedOperationException(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InvalidInstalledCodeException.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InvalidInstalledCodeException.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InvalidInstalledCodeException.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/InvalidInstalledCodeException.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +/** + * Exception thrown by the runtime in case an invalidated machine code is called. + */ +public final class InvalidInstalledCodeException extends Exception { + + public InvalidInstalledCodeException() { + } + + public InvalidInstalledCodeException(String message) { + super(message); + } + + private static final long serialVersionUID = -3540232440794244844L; +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Location.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Location.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Location.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Location.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * 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. + */ +package jdk.vm.ci.code; + +/** + * Represents a location where a value can be stored. This can be either a {@link Register} or a + * stack slot. + */ +public final class Location { + + public final Register reg; + public final int offset; + + private Location(Register reg, int offset) { + this.reg = reg; + this.offset = offset; + } + + /** + * Create a {@link Location} for a register. + */ + public static Location register(Register reg) { + return new Location(reg, 0); + } + + /** + * Create a {@link Location} for a vector subregister. + * + * @param reg the {@link Register vector register} + * @param offset the offset in bytes into the vector register + */ + public static Location subregister(Register reg, int offset) { + return new Location(reg, offset); + } + + /** + * Create a {@link Location} for a stack slot. + */ + public static Location stack(int offset) { + return new Location(null, offset); + } + + public boolean isRegister() { + return reg != null; + } + + public boolean isStack() { + return reg == null; + } + + @Override + public String toString() { + String regName; + if (isRegister()) { + regName = reg.name + ":"; + } else { + regName = "stack:"; + } + return regName + offset; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/MemoryBarriers.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/MemoryBarriers.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/MemoryBarriers.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/MemoryBarriers.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +/** + * Constants and intrinsic definition for memory barriers. + * + * The documentation for each constant is taken from Doug Lea's + * The JSR-133 Cookbook for Compiler + * Writers. + *

    + * The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory + * Model with respect to volatile field accesses. Their values are explained by this comment from + * templateTable_i486.cpp in the HotSpot source code: + * + *

    + * Volatile variables demand their effects be made known to all CPU's in
    + * order.  Store buffers on most chips allow reads & writes to reorder; the
    + * JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
    + * memory barrier (i.e., it's not sufficient that the interpreter does not
    + * reorder volatile references, the hardware also must not reorder them).
    + *
    + * According to the new Java Memory Model (JMM):
    + * (1) All volatiles are serialized wrt to each other.
    + * ALSO reads & writes act as acquire & release, so:
    + * (2) A read cannot let unrelated NON-volatile memory refs that happen after
    + * the read float up to before the read.  It's OK for non-volatile memory refs
    + * that happen before the volatile read to float down below it.
    + * (3) Similarly, a volatile write cannot let unrelated NON-volatile memory refs
    + * that happen BEFORE the write float down to after the write.  It's OK for
    + * non-volatile memory refs that happen after the volatile write to float up
    + * before it.
    + *
    + * We only put in barriers around volatile refs (they are expensive), not
    + * _between_ memory refs (which would require us to track the flavor of the
    + * previous memory refs).  Requirements (2) and (3) require some barriers
    + * before volatile stores and after volatile loads.  These nearly cover
    + * requirement (1) but miss the volatile-store-volatile-load case.  This final
    + * case is placed after volatile-stores although it could just as well go
    + * before volatile-loads.
    + * 
    + */ +public class MemoryBarriers { + + /** + * The sequence {@code Load1; LoadLoad; Load2} ensures that {@code Load1}'s data are loaded + * before data accessed by {@code Load2} and all subsequent load instructions are loaded. In + * general, explicit {@code LoadLoad} barriers are needed on processors that perform speculative + * loads and/or out-of-order processing in which waiting load instructions can bypass waiting + * stores. On processors that guarantee to always preserve load ordering, these barriers amount + * to no-ops. + */ + public static final int LOAD_LOAD = 0x0001; + + /** + * The sequence {@code Load1; LoadStore; Store2} ensures that {@code Load1}'s data are loaded + * before all data associated with {@code Store2} and subsequent store instructions are flushed. + * {@code LoadStore} barriers are needed only on those out-of-order processors in which waiting + * store instructions can bypass loads. + */ + public static final int LOAD_STORE = 0x0002; + + /** + * The sequence {@code Store1; StoreLoad; Load2} ensures that {@code Store1}'s data are made + * visible to other processors (i.e., flushed to main memory) before data accessed by + * {@code Load2} and all subsequent load instructions are loaded. {@code StoreLoad} barriers + * protect against a subsequent load incorrectly using {@code Store1}'s data value rather than + * that from a more recent store to the same location performed by a different processor. + * Because of this, on the processors discussed below, a {@code StoreLoad} is strictly necessary + * only for separating stores from subsequent loads of the same location(s) as were stored + * before the barrier. {@code StoreLoad} barriers are needed on nearly all recent + * multiprocessors, and are usually the most expensive kind. Part of the reason they are + * expensive is that they must disable mechanisms that ordinarily bypass cache to satisfy loads + * from write-buffers. This might be implemented by letting the buffer fully flush, among other + * possible stalls. + */ + public static final int STORE_LOAD = 0x0004; + + /** + * The sequence {@code Store1; StoreStore; Store2} ensures that {@code Store1}'s data are + * visible to other processors (i.e., flushed to memory) before the data associated with + * {@code Store2} and all subsequent store instructions. In general, {@code StoreStore} barriers + * are needed on processors that do not otherwise guarantee strict ordering of flushes from + * write buffers and/or caches to other processors or main memory. + */ + public static final int STORE_STORE = 0x0008; + + public static final int JMM_PRE_VOLATILE_WRITE = LOAD_STORE | STORE_STORE; + public static final int JMM_POST_VOLATILE_WRITE = STORE_LOAD | STORE_STORE; + public static final int JMM_PRE_VOLATILE_READ = 0; + public static final int JMM_POST_VOLATILE_READ = LOAD_LOAD | LOAD_STORE; + + public static String barriersString(int barriers) { + StringBuilder sb = new StringBuilder(); + sb.append((barriers & LOAD_LOAD) != 0 ? "LOAD_LOAD " : ""); + sb.append((barriers & LOAD_STORE) != 0 ? "LOAD_STORE " : ""); + sb.append((barriers & STORE_LOAD) != 0 ? "STORE_LOAD " : ""); + sb.append((barriers & STORE_STORE) != 0 ? "STORE_STORE " : ""); + return sb.toString().trim(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 that defines the interface between a Java application that wants to install code and the + * runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider} + * interface. The method + * {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)} + * can be used to install code. + */ +package jdk.vm.ci.code; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ReferenceMap.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ReferenceMap.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ReferenceMap.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ReferenceMap.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.code; + +/** + * Marker type for an object containing information about where the object references are in machine + * state (e.g., registers or stack locations). This is typically associated with an execution point + * in compiled code. + */ +public abstract class ReferenceMap { +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterArray.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterArray.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterArray.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterArray.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * An immutable ordered list of registers. Only required because Java lacks immutable arrays. + */ +public final class RegisterArray implements Iterable { + + private final Register[] registers; + private int hash; + + public RegisterArray(Register... registers) { + this.registers = registers; + } + + public RegisterArray(Collection registers) { + this.registers = registers.toArray(new Register[registers.size()]); + } + + /** + * Gets the number of registers. + */ + public int size() { + return registers.length; + } + + /** + * Gets the register at a given index. + * + * @param index the index of the register to retrieve + */ + public Register get(int index) { + return registers[index]; + } + + public void addTo(Collection collection) { + collection.addAll(Arrays.asList(registers)); + } + + /** + * Gets an immutable view of the registers as a list. + */ + public List asList() { + return Collections.unmodifiableList(Arrays.asList(registers)); + } + + /** + * Gets a copy of the registers as an array. + */ + public Register[] toArray() { + return registers.clone(); + } + + @Override + public Iterator iterator() { + return Arrays.asList(registers).iterator(); + } + + @Override + public int hashCode() { + if (hash == 0 && registers.length > 0) { + hash = Arrays.hashCode(registers); + } + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof RegisterArray) { + return Arrays.equals(registers, ((RegisterArray) obj).registers); + } + return false; + } + + @Override + public String toString() { + return Arrays.toString(registers); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterAttributes.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterAttributes.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterAttributes.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterAttributes.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * A collection of register attributes. The specific attribute values for a register may be local to + * a compilation context. For example, a {@link RegisterConfig} in use during a compilation will + * determine which registers are callee saved. + */ +public class RegisterAttributes { + + private final boolean callerSave; + private final boolean calleeSave; + private final boolean allocatable; + + public RegisterAttributes(boolean isCallerSave, boolean isCalleeSave, boolean isAllocatable) { + this.callerSave = isCallerSave; + this.calleeSave = isCalleeSave; + this.allocatable = isAllocatable; + } + + public static final RegisterAttributes NONE = new RegisterAttributes(false, false, false); + + /** + * Creates a map from register {@linkplain Register#number numbers} to register + * {@linkplain RegisterAttributes attributes} for a given register configuration and set of + * registers. + * + * @param registerConfig a register configuration + * @param registers a set of registers + * @return an array whose length is the max register number in {@code registers} plus 1. An + * element at index i holds the attributes of the register whose number is i. + */ + public static RegisterAttributes[] createMap(RegisterConfig registerConfig, RegisterArray registers) { + RegisterAttributes[] map = new RegisterAttributes[registers.size()]; + List callerSaveRegisters = registerConfig.getCallerSaveRegisters().asList(); + List calleeSaveRegisters = registerConfig.getCalleeSaveRegisters() == null ? Collections.emptyList() : registerConfig.getCalleeSaveRegisters().asList(); + List allocatableRegisters = registerConfig.getAllocatableRegisters().asList(); + for (Register reg : registers) { + if (reg != null) { + RegisterAttributes attr = new RegisterAttributes(callerSaveRegisters.contains(reg), calleeSaveRegisters.contains(reg), allocatableRegisters.contains(reg)); + if (map.length <= reg.number) { + map = Arrays.copyOf(map, reg.number + 1); + } + map[reg.number] = attr; + } + } + for (int i = 0; i < map.length; i++) { + if (map[i] == null) { + map[i] = NONE; + } + } + return map; + } + + /** + * @return {@code true} if a register is available for use by a register allocator otherwise + * {@code false} + */ + public boolean isAllocatable() { + return allocatable; + } + + /** + * @return {@code true} if a register whose value preservation (if required) across a call is + * the responsibility of the callee otherwise {@code false} + */ + public boolean isCalleeSave() { + return calleeSave; + } + + /** + * @return {@code true} if a register whose value preservation (if required) across a call is + * the responsibility of the caller otherwise {@code false} + */ + public boolean isCallerSave() { + return callerSave; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterConfig.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.code.CallingConvention.Type; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.PlatformKind; +import jdk.vm.ci.meta.ValueKind; + +/** + * A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical + * registers. + */ +public interface RegisterConfig { + + /** + * Gets the register to be used for returning a value of a given kind. + */ + Register getReturnRegister(JavaKind kind); + + /** + * Gets the maximum allowed size of the frame. + */ + default int getMaximumFrameSize() { + return Integer.MAX_VALUE; + } + + /** + * Gets the register used as the frame pointer. Spill slots and outgoing stack-based arguments + * are addressed relative to this register. + */ + Register getFrameRegister(); + + /** + * Gets the calling convention describing how arguments are passed. + * + * @param type the type of calling convention being requested + * @param returnType the return type (can be null for methods returning {@code void}) + * @param parameterTypes the types of the arguments of the call + * @param valueKindFactory the factory to create custom {@link ValueKind ValueKinds} + */ + CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory valueKindFactory); + + /** + * Gets the ordered set of registers that are can be used to pass parameters according to a + * given calling convention. + * + * @param type the type of calling convention + * @param kind specifies what kind of registers is being requested + * @return the ordered set of registers that may be used to pass parameters in a call conforming + * to {@code type} + */ + RegisterArray getCallingConventionRegisters(Type type, JavaKind kind); + + /** + * Gets the set of all registers that might be used by the register allocator. + */ + RegisterArray getAllocatableRegisters(); + + /** + * Filters a set of registers and returns only those that can be used by the register allocator + * for a value of a particular kind. + */ + RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers); + + /** + * Gets the registers whose values must be preserved by a method across any call it makes. + */ + RegisterArray getCallerSaveRegisters(); + + /** + * Gets the registers whose values must be preserved by the callee. + */ + RegisterArray getCalleeSaveRegisters(); + + /** + * Gets a map from register {@linkplain Register#number numbers} to register + * {@linkplain RegisterAttributes attributes} for this register configuration. + * + * @return an array where an element at index i holds the attributes of the register whose + * number is i + */ + RegisterAttributes[] getAttributesMap(); + + /** + * Determines if all {@link #getAllocatableRegisters() allocatable} registers are + * {@link #getCallerSaveRegisters() caller saved}. + */ + boolean areAllAllocatableRegistersCallerSaved(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Register.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Register.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Register.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/Register.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.meta.ValueKind; + +/** + * Represents a target machine register. + */ +public final class Register implements Comparable { + + public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL"); + + /** + * Invalid register. + */ + public static final Register None = new Register(-1, -1, "noreg", SPECIAL); + + /** + * The identifier for this register that is unique across all the registers in a + * {@link Architecture}. A valid register has {@code number >= 0}. + */ + public final int number; + + /** + * The mnemonic of this register. + */ + public final String name; + + /** + * The actual encoding in a target machine instruction for this register, which may or may not + * be the same as {@link #number}. + */ + public final int encoding; + + /** + * The assembler calls this method to get the register's encoding. + */ + public int encoding() { + return encoding; + } + + /** + * A platform specific register category that describes which values can be stored in a + * register. + */ + private final RegisterCategory registerCategory; + + /** + * A platform specific register type that describes which values can be stored in a register. + */ + public static class RegisterCategory { + + private final String name; + private final boolean mayContainReference; + + public RegisterCategory(String name) { + this(name, true); + } + + public RegisterCategory(String name, boolean mayContainReference) { + this.name = name; + this.mayContainReference = mayContainReference; + } + + @Override + public String toString() { + return name; + } + + @Override + public int hashCode() { + return 23 + name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof RegisterCategory) { + RegisterCategory that = (RegisterCategory) obj; + return this.name.equals(that.name); + } + return false; + } + } + + /** + * Creates a {@link Register} instance. + * + * @param number unique identifier for the register + * @param encoding the target machine encoding for the register + * @param name the mnemonic name for the register + * @param registerCategory the register category + */ + public Register(int number, int encoding, String name, RegisterCategory registerCategory) { + this.number = number; + this.name = name; + this.registerCategory = registerCategory; + this.encoding = encoding; + } + + public RegisterCategory getRegisterCategory() { + return registerCategory; + } + + /** + * Determine whether this register needs to be part of the reference map. + */ + public boolean mayContainReference() { + return registerCategory.mayContainReference; + } + + /** + * Gets this register as a {@linkplain RegisterValue value} with a specified kind. + * + * @param kind the specified kind + * @return the {@link RegisterValue} + */ + public RegisterValue asValue(ValueKind kind) { + return new RegisterValue(kind, this); + } + + /** + * Gets this register as a {@linkplain RegisterValue value} with no particular kind. + * + * @return a {@link RegisterValue} with {@link ValueKind#Illegal} kind. + */ + public RegisterValue asValue() { + return asValue(ValueKind.Illegal); + } + + /** + * Determines if this is a valid register. + * + * @return {@code true} iff this register is valid + */ + public boolean isValid() { + return number >= 0; + } + + @Override + public String toString() { + return name; + } + + @Override + public int compareTo(Register o) { + if (number < o.number) { + return -1; + } + if (number > o.number) { + return 1; + } + return 0; + } + + @Override + public int hashCode() { + return 17 + name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Register) { + Register other = (Register) obj; + if (number == other.number) { + assert name.equals(other.name); + assert encoding == other.encoding; + assert registerCategory.equals(other.registerCategory); + return true; + } + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterSaveLayout.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterSaveLayout.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterSaveLayout.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterSaveLayout.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.TreeMap; + +/** + * A map from registers to frame slots. This can be used to describe where callee saved registers + * are saved in a callee's frame. + */ +public final class RegisterSaveLayout { + + /** + * Keys. + */ + private final Register[] registers; + + /** + * Slot indexes relative to stack pointer. + */ + private final int[] slots; + + /** + * Creates a map from registers to frame slots. + * + * @param registers the keys in the map + * @param slots frame slot index for each register in {@code registers} + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `registers` and `slots`") + public RegisterSaveLayout(Register[] registers, int[] slots) { + assert registers.length == slots.length; + this.registers = registers; + this.slots = slots; + assert registersToSlots(false).size() == registers.length : "non-unique registers"; + assert new HashSet<>(registersToSlots(false).values()).size() == slots.length : "non-unqiue slots"; + } + + /** + * Gets the frame slot index for a given register. + * + * @param register register to get the frame slot index for + * @return frame slot index + */ + public int registerToSlot(Register register) { + for (int i = 0; i < registers.length; i++) { + if (register.equals(registers[i])) { + return slots[i]; + } + } + throw new IllegalArgumentException(register + " not saved by this layout: " + this); + } + + /** + * Gets this layout information as a {@link Map} from registers to slots. + */ + public Map registersToSlots(boolean sorted) { + Map result; + if (sorted) { + result = new TreeMap<>(); + } else { + result = new HashMap<>(); + } + for (int i = 0; i < registers.length; i++) { + result.put(registers[i], slots[i]); + } + return result; + } + + /** + * Gets this layout information as a {@link Map} from slots to registers. + */ + public Map slotsToRegisters(boolean sorted) { + Map result; + if (sorted) { + result = new TreeMap<>(); + } else { + result = new HashMap<>(); + } + for (int i = 0; i < registers.length; i++) { + result.put(slots[i], registers[i]); + } + return result; + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof RegisterSaveLayout) { + RegisterSaveLayout that = (RegisterSaveLayout) obj; + if (Arrays.equals(registers, that.registers) && Arrays.equals(slots, that.slots)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return registersToSlots(true).toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterValue.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/RegisterValue.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.ValueKind; + +/** + * Denotes a register that stores a value of a fixed kind. + */ +public final class RegisterValue extends AllocatableValue { + + private final Register reg; + + protected RegisterValue(ValueKind kind, Register register) { + super(kind); + this.reg = register; + } + + @Override + public String toString() { + return getRegister().name + getKindSuffix(); + } + + /** + * @return the register that contains the value + */ + public Register getRegister() { + return reg; + } + + @Override + public int hashCode() { + return 29 * super.hashCode() + reg.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof RegisterValue) { + RegisterValue other = (RegisterValue) obj; + return super.equals(obj) && reg.equals(other.reg); + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Call.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Call.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Call.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Call.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +import java.util.Objects; + +import jdk.vm.ci.code.DebugInfo; +import jdk.vm.ci.meta.InvokeTarget; + +/** + * Represents a call in the code. + */ +public final class Call extends Infopoint { + + /** + * The target of the call. + */ + public final InvokeTarget target; + + /** + * The size of the call instruction. + */ + public final int size; + + /** + * Specifies if this call is direct or indirect. A direct call has an immediate operand encoding + * the absolute or relative (to the call itself) address of the target. An indirect call has a + * register or memory operand specifying the target address of the call. + */ + public final boolean direct; + + public Call(InvokeTarget target, int pcOffset, int size, boolean direct, DebugInfo debugInfo) { + super(pcOffset, debugInfo, InfopointReason.CALL); + this.size = size; + this.target = target; + this.direct = direct; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Call && super.equals(obj)) { + Call that = (Call) obj; + if (this.size == that.size && this.direct == that.direct && Objects.equals(this.target, that.target)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(pcOffset); + sb.append('['); + sb.append(target); + sb.append(']'); + + if (debugInfo != null) { + appendDebugInfo(sb, debugInfo); + } + + return sb.toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ConstantReference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ConstantReference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ConstantReference.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ConstantReference.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +import java.util.Objects; + +import jdk.vm.ci.meta.VMConstant; + +/** + * Represents an embedded {@link VMConstant} in the code or data section that needs to be + * {@link DataPatch patched} by the VM (e.g. an embedded pointer to a Java object). + */ +public final class ConstantReference extends Reference { + + private final VMConstant constant; + + public ConstantReference(VMConstant constant) { + this.constant = constant; + } + + public VMConstant getConstant() { + return constant; + } + + @Override + public String toString() { + return constant.toString(); + } + + @Override + public int hashCode() { + return constant.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ConstantReference) { + ConstantReference that = (ConstantReference) obj; + return Objects.equals(this.constant, that.constant); + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataPatch.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataPatch.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataPatch.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataPatch.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +import java.util.Objects; + +import jdk.vm.ci.meta.VMConstant; + +/** + * Represents a code site that references some data. The associated data can be either a + * {@link DataSectionReference reference} to the data section, or it may be an inlined + * {@link VMConstant} that needs to be patched. + */ +public final class DataPatch extends Site { + + public Reference reference; + public Object note; + + public DataPatch(int pcOffset, Reference reference) { + super(pcOffset); + this.reference = reference; + this.note = null; + } + + public DataPatch(int pcOffset, Reference reference, Object note) { + super(pcOffset); + this.reference = reference; + this.note = note; + } + + @Override + public String toString() { + if (note != null) { + return String.format("%d[, note: %s]", pcOffset, reference.toString(), note.toString()); + } else { + return String.format("%d[]", pcOffset, reference.toString()); + } + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DataPatch) { + DataPatch that = (DataPatch) obj; + if (this.pcOffset == that.pcOffset && Objects.equals(this.reference, that.reference) && Objects.equals(this.note, that.note)) { + return true; + } + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataSectionReference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataSectionReference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataSectionReference.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/DataSectionReference.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +/** + * Represents a pointer to some location in the data section that should be {@link DataPatch + * patched} into the code. + */ +public final class DataSectionReference extends Reference { + + private boolean initialized; + private int offset; + + public DataSectionReference() { + // will be set after the data section layout is fixed + offset = 0xDEADDEAD; + } + + public int getOffset() { + assert initialized; + + return offset; + } + + public void setOffset(int offset) { + assert !initialized; + initialized = true; + + this.offset = offset; + } + + @Override + public int hashCode() { + return offset; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DataSectionReference) { + DataSectionReference that = (DataSectionReference) obj; + return this.offset == that.offset; + } + return false; + } + + @Override + public String toString() { + if (initialized) { + return String.format("DataSection[0x%x]", offset); + } else { + return "DataSection[?]"; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ExceptionHandler.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ExceptionHandler.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ExceptionHandler.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ExceptionHandler.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +/** + * Represents exception handler information for a specific code position. It includes the catch code + * position as well as the caught exception type. + */ +public final class ExceptionHandler extends Site { + + public final int handlerPos; + + public ExceptionHandler(int pcOffset, int handlerPos) { + super(pcOffset); + this.handlerPos = handlerPos; + } + + @Override + public String toString() { + return String.format("%d[]", pcOffset, handlerPos); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ExceptionHandler) { + ExceptionHandler that = (ExceptionHandler) obj; + if (this.pcOffset == that.pcOffset && this.handlerPos == that.handlerPos) { + return true; + } + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 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. 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.vm.ci.code.site; + +import jdk.vm.ci.code.DebugInfo; + +/** + * Represents an implicit exception dispatch in the code. Implicit exception dispatch is a + * platform-specific optimization that makes use of an operating system's trap mechanism, to turn + * specific branches into sequential code with implicit traps. Information contained in this class + * will be used by the runtime to register implicit exception dispatch, i.e., a mapping from an + * exceptional PC offset to a continuation PC offset. + */ +public final class ImplicitExceptionDispatch extends Infopoint { + + public final int dispatchOffset; + + /** + * Construct an implicit exception dispatch. + * + * @param pcOffset the exceptional PC offset + * @param dispatchOffset the continuation PC offset + * @param debugInfo debugging information at the exceptional PC + */ + public ImplicitExceptionDispatch(int pcOffset, int dispatchOffset, DebugInfo debugInfo) { + super(pcOffset, debugInfo, InfopointReason.IMPLICIT_EXCEPTION); + this.dispatchOffset = dispatchOffset; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ImplicitExceptionDispatch && super.equals(obj)) { + ImplicitExceptionDispatch that = (ImplicitExceptionDispatch) obj; + if (this.dispatchOffset == that.dispatchOffset) { + return true; + } + } + return false; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(pcOffset); + sb.append("->"); + sb.append(dispatchOffset); + + if (debugInfo != null) { + appendDebugInfo(sb, debugInfo); + } + + return sb.toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Infopoint.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Infopoint.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Infopoint.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Infopoint.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +import java.util.Map; +import java.util.Objects; + +import jdk.vm.ci.code.BytecodePosition; +import jdk.vm.ci.code.DebugInfo; +import jdk.vm.ci.code.ReferenceMap; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.RegisterSaveLayout; +import jdk.vm.ci.meta.MetaUtil; + +/** + * Represents an infopoint with associated debug info. Note that safepoints are also infopoints. + */ +public class Infopoint extends Site implements Comparable { + + public final DebugInfo debugInfo; + + public final InfopointReason reason; + + public Infopoint(int pcOffset, DebugInfo debugInfo, InfopointReason reason) { + super(pcOffset); + this.debugInfo = debugInfo; + this.reason = reason; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(pcOffset); + sb.append("[]"); + appendDebugInfo(sb, debugInfo); + return sb.toString(); + } + + @Override + public int compareTo(Infopoint o) { + if (pcOffset < o.pcOffset) { + return -1; + } else if (pcOffset > o.pcOffset) { + return 1; + } + return this.reason.compareTo(o.reason); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj != null && obj.getClass() == getClass()) { + Infopoint that = (Infopoint) obj; + if (this.pcOffset == that.pcOffset && Objects.equals(this.debugInfo, that.debugInfo) && Objects.equals(this.reason, that.reason)) { + return true; + } + } + return false; + } + + protected static void appendDebugInfo(StringBuilder sb, DebugInfo info) { + if (info != null) { + ReferenceMap refMap = info.getReferenceMap(); + if (refMap != null) { + sb.append(refMap.toString()); + sb.append(']'); + } + RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); + if (calleeSaveInfo != null) { + sb.append(" callee-save-info["); + String sep = ""; + for (Map.Entry e : calleeSaveInfo.registersToSlots(true).entrySet()) { + sb.append(sep).append(e.getKey()).append("->").append(e.getValue()); + sep = ", "; + } + sb.append(']'); + } + BytecodePosition codePos = info.getBytecodePosition(); + if (codePos != null) { + MetaUtil.appendLocation(sb.append(" "), codePos.getMethod(), codePos.getBCI()); + if (info.hasFrame()) { + sb.append(" #locals=").append(info.frame().numLocals).append(" #expr=").append(info.frame().numStack); + if (info.frame().numLocks > 0) { + sb.append(" #locks=").append(info.frame().numLocks); + } + } + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/InfopointReason.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/InfopointReason.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/InfopointReason.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/InfopointReason.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +/** + * A reason for infopoint insertion. + */ +public enum InfopointReason { + + SAFEPOINT, + CALL, + IMPLICIT_EXCEPTION, + METHOD_START, + METHOD_END, + BYTECODE_POSITION; +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Mark.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Mark.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Mark.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Mark.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +import java.util.Objects; + +/** + * Associates arbitrary information with a position in machine code. For example, HotSpot specific + * code in a compiler backend may use this to denote the position of a safepoint, exception handler + * entry point, verified entry point etc. + */ +public final class Mark extends Site { + + /** + * An object denoting extra semantic information about the machine code position of this mark. + */ + public final Object id; + + /** + * Creates a mark that associates {@code id} with the machine code position {@code pcOffset}. + * + * @param pcOffset + * @param id + */ + public Mark(int pcOffset, Object id) { + super(pcOffset); + this.id = id; + } + + @Override + public String toString() { + if (id == null) { + return String.format("%d[]", pcOffset); + } else if (id instanceof Integer) { + return String.format("%d[]", pcOffset, Integer.toHexString((Integer) id)); + } else { + return String.format("%d[]", pcOffset, id.toString()); + } + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Mark) { + Mark that = (Mark) obj; + if (this.pcOffset == that.pcOffset && Objects.equals(this.id, that.id)) { + return true; + } + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ +/** + * Package that defines the information associated with various {@link jdk.vm.ci.code.site.Site + * sites} in generated code. + */ +package jdk.vm.ci.code.site; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Reference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Reference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Reference.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Reference.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +/** + * Represents some external data that is referenced by the code. + */ +public abstract class Reference { + + @Override + public abstract int hashCode(); + + @Override + public abstract boolean equals(Object obj); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.site; + +import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString; + +/** + * Represents a code position with associated additional information. + */ +public abstract class Site { + + /** + * The position (or offset) of this site with respect to the start of the target method. + */ + public final int pcOffset; + + public Site(int pos) { + this.pcOffset = pos; + } + + @Override + public final int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + @Override + public String toString() { + return identityHashCodeString(this); + } + + @Override + public abstract boolean equals(Object obj); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrame.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrame.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrame.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrame.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.stack; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Access to the object variables in a stack frame. + */ +public interface InspectedFrame { + + /** + * Returns the value of the object local at {@code index}. This value is a copy iff + * {@link #isVirtual(int)} is true. + */ + Object getLocal(int index); + + /** + * Returns whether the local at {@code index} is a virtual object, and therefore the object + * returned by {@link #getLocal(int)} is a copy. + */ + boolean isVirtual(int index); + + /** + * Returns true if the stack frame is a compiled stack frame and there are virtual objects + * anywhere in the current state of the compiled method. This can return true even if + * {@link #isVirtual(int)} return false for all locals. + */ + boolean hasVirtualObjects(); + + /** + * This method will materialize all virtual objects, deoptimize the stack frame and make sure + * that subsequent execution of the deoptimized frame uses the materialized values. + */ + void materializeVirtualObjects(boolean invalidateCode); + + /** + * @return the current bytecode index + */ + int getBytecodeIndex(); + + /** + * @return the current method + */ + ResolvedJavaMethod getMethod(); + + /** + * Checks if the current method is equal to the given method. This is semantically equivalent to + * {@code method.equals(getMethod())}, but can be implemented more efficiently. + */ + boolean isMethod(ResolvedJavaMethod method); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrameVisitor.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrameVisitor.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrameVisitor.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/InspectedFrameVisitor.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.stack; + +/** + * Callback interface for {@link StackIntrospection#iterateFrames}. Implementations of + * {@link #visitFrame} return null to indicate that frame iteration should continue and the next + * caller frame should be visited; and return any non-null value to indicate that frame iteration + * should stop. + */ +public interface InspectedFrameVisitor { + + T visitFrame(InspectedFrame frame); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * 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. + */ +/** + * Package that defines the interface for runtime stack introspection. + */ +package jdk.vm.ci.code.stack; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/StackIntrospection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/StackIntrospection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/StackIntrospection.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/stack/StackIntrospection.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.stack; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public interface StackIntrospection { + + /** + * Walks the current stack, providing {@link InspectedFrame}s to the visitor that can be used to + * inspect the stack frame's contents. Iteration continues as long as + * {@link InspectedFrameVisitor#visitFrame}, which is invoked for every {@link InspectedFrame}, + * returns {@code null}. A non-null return value from {@link InspectedFrameVisitor#visitFrame} + * indicates that frame iteration should stop. + * + * @param initialMethods if this is non-{@code null}, then the stack walk will start at the + * first frame whose method is one of these methods. + * @param matchingMethods if this is non-{@code null}, then only frames whose methods are in + * this array are visited + * @param initialSkip the number of matching methods to skip (including the initial method) + * @param visitor the visitor that is called for every matching method + * @return the last result returned by the visitor (which is non-null to indicate that iteration + * should stop), or null if the whole stack was iterated. + */ + T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor visitor); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackLockValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackLockValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackLockValue.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackLockValue.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.Value; + +/** + * Represents lock information in the debug information. + */ +public final class StackLockValue implements JavaValue { + + private JavaValue owner; + private AllocatableValue slot; + private final boolean eliminated; + + public StackLockValue(JavaValue object, AllocatableValue slot, boolean eliminated) { + this.owner = object; + this.slot = slot; + this.eliminated = eliminated; + } + + public JavaValue getOwner() { + return owner; + } + + public void setOwner(JavaValue newOwner) { + this.owner = newOwner; + } + + public Value getSlot() { + return slot; + } + + public boolean isEliminated() { + return eliminated; + } + + @Override + public String toString() { + return "monitor[" + owner + (slot != null ? ", " + slot : "") + (eliminated ? ", eliminated" : "") + "]"; + } + + @Override + public int hashCode() { + final int prime = 43; + int result = super.hashCode(); + result = prime * result + (eliminated ? 1231 : 1237); + result = prime * result + owner.hashCode(); + result = prime * result + slot.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof StackLockValue) { + StackLockValue other = (StackLockValue) obj; + return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot); + } + return false; + } + + public void setSlot(AllocatableValue stackSlot) { + slot = stackSlot; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackSlot.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackSlot.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackSlot.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/StackSlot.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.ValueKind; + +/** + * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an + * incoming stack-based argument in a method's {@linkplain #isInCallerFrame() caller's frame}. + */ +public final class StackSlot extends AllocatableValue { + + private final int offset; + private final boolean addFrameSize; + + /** + * Gets a {@link StackSlot} instance representing a stack slot at a given index holding a value + * of a given kind. + * + * @param kind The kind of the value stored in the stack slot. + * @param offset The offset of the stack slot (in bytes) + * @param addFrameSize Specifies if the offset is relative to the stack pointer, or the + * beginning of the frame (stack pointer + total frame size). + */ + public static StackSlot get(ValueKind kind, int offset, boolean addFrameSize) { + assert addFrameSize || offset >= 0; + return new StackSlot(kind, offset, addFrameSize); + } + + /** + * Private constructor to enforce use of {@link #get(ValueKind, int, boolean)} so that a cache + * can be used. + */ + private StackSlot(ValueKind kind, int offset, boolean addFrameSize) { + super(kind); + this.offset = offset; + this.addFrameSize = addFrameSize; + } + + /** + * Gets the offset of this stack slot, relative to the stack pointer. + * + * @return The offset of this slot (in bytes). + */ + public int getOffset(int totalFrameSize) { + assert totalFrameSize > 0 || !addFrameSize; + int result = offset + (addFrameSize ? totalFrameSize : 0); + assert result >= 0; + return result; + } + + public boolean isInCallerFrame() { + return addFrameSize && offset >= 0; + } + + public int getRawOffset() { + return offset; + } + + public boolean getRawAddFrameSize() { + return addFrameSize; + } + + @Override + public String toString() { + if (!addFrameSize) { + return "out:" + offset + getKindSuffix(); + } else if (offset >= 0) { + return "in:" + offset + getKindSuffix(); + } else { + return "stack:" + (-offset) + getKindSuffix(); + } + } + + /** + * Gets this stack slot used to pass an argument from the perspective of a caller. + */ + public StackSlot asOutArg() { + assert offset >= 0; + if (addFrameSize) { + return get(getValueKind(), offset, false); + } + return this; + } + + /** + * Gets this stack slot used to pass an argument from the perspective of a callee. + */ + public StackSlot asInArg() { + assert offset >= 0; + if (!addFrameSize) { + return get(getValueKind(), offset, true); + } + return this; + } + + @Override + public int hashCode() { + final int prime = 37; + int result = super.hashCode(); + result = prime * result + (addFrameSize ? 1231 : 1237); + result = prime * result + offset; + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof StackSlot) { + StackSlot other = (StackSlot) obj; + return super.equals(obj) && addFrameSize == other.addFrameSize && offset == other.offset; + } + return false; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/SuppressFBWarnings.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +/** + * Used to suppress FindBugs warnings. + */ +@interface SuppressFBWarnings { + /** + * The set of FindBugs + * warnings that are to be + * suppressed in annotated element. The value can be a bug category, kind or pattern. + */ + String[] value(); + + /** + * Reason why the warning is suppressed. + */ + String justification(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/TargetDescription.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/TargetDescription.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/TargetDescription.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/TargetDescription.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString; + +import jdk.vm.ci.meta.JavaKind; + +/** + * Represents the target machine for a compiler, including the CPU architecture, the size of + * pointers and references, alignment of stacks, caches, etc. + */ +public class TargetDescription { + + public final Architecture arch; + + /** + * Specifies if this is a multi-processor system. + */ + public final boolean isMP; + + /** + * Specifies if this target supports encoding objects inline in the machine code. + */ + public final boolean inlineObjects; + + /** + * The machine word size on this target. + */ + public final int wordSize; + + /** + * The {@link JavaKind} to be used for representing raw pointers and CPU registers in Java code. + */ + public final JavaKind wordJavaKind; + + /** + * The stack alignment requirement of the platform. For example, from Appendix D of + * Intel 64 and IA-32 Architectures + * Optimization Reference Manual: + * + *
    +     *     "It is important to ensure that the stack frame is aligned to a
    +     *      16-byte boundary upon function entry to keep local __m128 data,
    +     *      parameters, and XMM register spill locations aligned throughout
    +     *      a function invocation."
    +     * 
    + */ + public final int stackAlignment; + + /** + * Maximum constant displacement at which a memory access can no longer be an implicit null + * check. + */ + public final int implicitNullCheckLimit; + + public TargetDescription(Architecture arch, boolean isMP, int stackAlignment, int implicitNullCheckLimit, boolean inlineObjects) { + this.arch = arch; + this.isMP = isMP; + this.wordSize = arch.getWordSize(); + this.wordJavaKind = JavaKind.fromWordSize(wordSize); + this.stackAlignment = stackAlignment; + this.implicitNullCheckLimit = implicitNullCheckLimit; + this.inlineObjects = inlineObjects; + + assert arch.getPlatformKind(wordJavaKind).equals(arch.getWordKind()); + } + + @Override + public final int hashCode() { + throw new UnsupportedOperationException(); + } + + @Override + public final boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TargetDescription) { + TargetDescription that = (TargetDescription) obj; + // @formatter:off + if (this.implicitNullCheckLimit == that.implicitNullCheckLimit && + this.inlineObjects == that.inlineObjects && + this.isMP == that.isMP && + this.stackAlignment == that.stackAlignment && + this.wordJavaKind.equals(that.wordJavaKind) && + this.wordSize == that.wordSize && + this.arch.equals(that.arch)) { + return true; + } + // @formatter:on + } + return false; + } + + @Override + public String toString() { + return identityHashCodeString(this); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueKindFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueKindFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueKindFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueKindFactory.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ValueKind; + +/** + * Can be implemented by compilers to create custom {@link ValueKind} subclasses. + */ +public interface ValueKindFactory> { + + K getValueKind(JavaKind javaKind); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueUtil.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueUtil.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/ValueUtil.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, 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. + */ +package jdk.vm.ci.code; + +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.PlatformKind; +import jdk.vm.ci.meta.Value; + +/** + * Utility class for working with the {@link Value} class and its subclasses. + */ +public final class ValueUtil { + + public static boolean isIllegal(Value value) { + assert value != null; + return Value.ILLEGAL.equals(value); + } + + public static boolean isIllegalJavaValue(JavaValue value) { + assert value != null; + return Value.ILLEGAL.equals(value); + } + + public static boolean isLegal(Value value) { + return !isIllegal(value); + } + + public static boolean isVirtualObject(JavaValue value) { + assert value != null; + return value instanceof VirtualObject; + } + + public static VirtualObject asVirtualObject(JavaValue value) { + assert value != null; + return (VirtualObject) value; + } + + public static boolean isConstantJavaValue(JavaValue value) { + assert value != null; + return value instanceof JavaConstant; + } + + public static JavaConstant asConstantJavaValue(JavaValue value) { + assert value != null; + return (JavaConstant) value; + } + + public static boolean isAllocatableValue(Value value) { + assert value != null; + return value instanceof AllocatableValue; + } + + public static AllocatableValue asAllocatableValue(Value value) { + assert value != null; + return (AllocatableValue) value; + } + + public static boolean isStackSlot(Value value) { + assert value != null; + return value instanceof StackSlot; + } + + public static StackSlot asStackSlot(Value value) { + assert value != null; + return (StackSlot) value; + } + + public static boolean isRegister(Value value) { + assert value != null; + return value instanceof RegisterValue; + } + + public static Register asRegister(Value value) { + return asRegisterValue(value).getRegister(); + } + + public static RegisterValue asRegisterValue(Value value) { + assert value != null; + return (RegisterValue) value; + } + + public static Register asRegister(Value value, PlatformKind kind) { + if (value.getPlatformKind() != kind) { + throw new InternalError("needed: " + kind + " got: " + value.getPlatformKind()); + } else { + return asRegister(value); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2010, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code; + +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Set; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * An instance of this class represents an object whose allocation was removed by escape analysis. + * The information stored in the {@link VirtualObject} is used during deoptimization to recreate the + * object. + */ +public final class VirtualObject implements JavaValue { + + private final ResolvedJavaType type; + private JavaValue[] values; + private JavaKind[] slotKinds; + private final int id; + private boolean isAutoBox; + + /** + * Creates a new {@link VirtualObject} for the given type, with the given fields. If + * {@code type} is an instance class then {@code values} provides the values for the fields + * returned by {@link ResolvedJavaType#getInstanceFields(boolean) getInstanceFields(true)}. If + * {@code type} is an array then the length of the values array determines the reallocated array + * length. + * + * @param type the type of the object whose allocation was removed during compilation. This can + * be either an instance of an array type. + * @param id a unique id that identifies the object within the debug information for one + * position in the compiled code. + * @return a new {@link VirtualObject} instance. + */ + public static VirtualObject get(ResolvedJavaType type, int id) { + return new VirtualObject(type, id, false); + } + + /** + * Creates a new {@link VirtualObject} for the given type, with the given fields. If + * {@code type} is an instance class then {@code values} provides the values for the fields + * returned by {@link ResolvedJavaType#getInstanceFields(boolean) getInstanceFields(true)}. If + * {@code type} is an array then the length of the values array determines the reallocated array + * length. + * + * @param type the type of the object whose allocation was removed during compilation. This can + * be either an instance of an array type. + * @param id a unique id that identifies the object within the debug information for one + * position in the compiled code. + * @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and + * that it possibly needs to be obtained for the box cache instead of creating a new + * instance. + * @return a new {@link VirtualObject} instance. + */ + public static VirtualObject get(ResolvedJavaType type, int id, boolean isAutoBox) { + return new VirtualObject(type, id, isAutoBox); + } + + private VirtualObject(ResolvedJavaType type, int id, boolean isAutoBox) { + this.type = type; + this.id = id; + this.isAutoBox = isAutoBox; + } + + private static StringBuilder appendValue(StringBuilder buf, JavaValue value, Set visited) { + if (value instanceof VirtualObject) { + VirtualObject vo = (VirtualObject) value; + buf.append("vobject:").append(vo.type.toJavaName(false)).append(':').append(vo.id); + if (!visited.contains(vo)) { + visited.add(vo); + buf.append('{'); + if (vo.values == null) { + buf.append(""); + } else { + if (vo.type.isArray()) { + for (int i = 0; i < vo.values.length; i++) { + if (i != 0) { + buf.append(','); + } + buf.append(i).append('='); + appendValue(buf, vo.values[i], visited); + } + } else { + ResolvedJavaField[] fields = vo.type.getInstanceFields(true); + int fieldIndex = 0; + for (int i = 0; i < vo.values.length; i++, fieldIndex++) { + if (i != 0) { + buf.append(','); + } + if (fieldIndex >= fields.length) { + buf.append(""); + } else { + ResolvedJavaField field = fields[fieldIndex]; + buf.append(field.getName()); + if (vo.slotKinds[i].getSlotCount() == 2 && field.getType().getJavaKind().getSlotCount() == 1) { + if (fieldIndex + 1 >= fields.length) { + buf.append("/"); + } else { + ResolvedJavaField field2 = fields[++fieldIndex]; + buf.append('/').append(field2.getName()); + } + } + } + buf.append('='); + appendValue(buf, vo.values[i], visited); + } + // Extra fields + for (; fieldIndex < fields.length; fieldIndex++) { + buf.append(fields[fieldIndex].getName()).append("="); + } + } + } + buf.append('}'); + } + } else { + buf.append(value); + } + return buf; + } + + public interface LayoutVerifier { + int getOffset(ResolvedJavaField field); + + default JavaKind getStorageKind(ResolvedJavaField field) { + return field.getType().getJavaKind(); + } + } + + public void verifyLayout(LayoutVerifier verifier) { + if (!type.isArray()) { + ResolvedJavaField[] fields = type.getInstanceFields(true); + int fieldIndex = 0; + for (int i = 0; i < values.length; i++, fieldIndex++) { + JavaKind slotKind = slotKinds[i]; + if (fieldIndex >= fields.length) { + throw new JVMCIError("Not enough fields for the values provided for %s", toString()); + } else { + ResolvedJavaField field = fields[fieldIndex]; + JavaKind fieldKind = verifier.getStorageKind(field); + if (slotKind.getSlotCount() == 2 && fieldKind == JavaKind.Int) { + int offset = verifier.getOffset(field); + if (offset % 8 != 0) { + throw new JVMCIError("Double word value stored across two ints must be aligned %s", toString()); + } + + if (fieldIndex + 1 >= fields.length) { + throw new JVMCIError("Missing second field for double word value stored in two ints %s", toString()); + } + ResolvedJavaField field2 = fields[fieldIndex + 1]; + if (field2.getType().getJavaKind() != JavaKind.Int) { + throw new JVMCIError("Second field for double word value stored in two ints must be int but got %s in %s", field2.getType().getJavaKind(), toString()); + } + int offset2 = verifier.getOffset(field2); + if (offset + 4 != offset2) { + throw new JVMCIError("Double word value stored across two ints must be sequential %s", toString()); + } + fieldIndex++; + } else if (fieldKind.getStackKind() != slotKind.getStackKind()) { + throw new JVMCIError("Expected value of kind %s but got %s for field %s in %s", fieldKind, slotKind, field, toString()); + } + } + } + // Extra fields + if (fieldIndex < fields.length) { + throw new JVMCIError("Not enough values provided for fields in %s", this); + } + } else if (type.getComponentType().getJavaKind() == JavaKind.Byte) { + for (int i = 0; i < values.length;) { + JavaKind slotkind = slotKinds[i]; + if (slotkind != JavaKind.Byte) { + if (!slotkind.isPrimitive()) { + throw new JVMCIError("Storing a non-primitive in a byte array: %s %s", slotkind, toString()); + } + int byteCount = 1; + while (++i < values.length && slotKinds[i] == JavaKind.Illegal) { + byteCount++; + } + /* + * Checks: a) The byte count is a valid count (ie: power of two), b) if the kind + * was not erased to int (happens for regular byte array accesses), check that + * the count is correct, c) No writes spanning more than a long. + */ + if (!CodeUtil.isPowerOf2(byteCount) || (slotkind.getStackKind() != JavaKind.Int && byteCount != slotkind.getByteCount()) || byteCount > JavaKind.Long.getByteCount()) { + throw new JVMCIError("Invalid number of illegals to reconstruct a byte array: %s in %s", byteCount, toString()); + } + continue; + } + i++; + } + } + } + + @Override + public String toString() { + Set visited = Collections.newSetFromMap(new IdentityHashMap()); + return appendValue(new StringBuilder(), this, visited).toString(); + } + + /** + * Returns the type of the object whose allocation was removed during compilation. This can be + * either an instance of an array type. + */ + public ResolvedJavaType getType() { + return type; + } + + /** + * Returns the array containing all the values to be stored into the object when it is + * recreated. This field is intentional exposed as a mutable array that a compiler may modify + * (e.g. during register allocation). + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "`values` is intentional mutable")// + public JavaValue[] getValues() { + return values; + } + + /** + * Returns the kind of the value at {@code index}. + */ + public JavaKind getSlotKind(int index) { + return slotKinds[index]; + } + + /** + * Returns the unique id that identifies the object within the debug information for one + * position in the compiled code. + */ + public int getId() { + return id; + } + + /** + * Returns true if the object is a box. For boxes the deoptimization would check if the value of + * the box is in the cache range and try to return a cached object. + */ + public boolean isAutoBox() { + return isAutoBox; + } + + /** + * Overwrites the current set of values with a new one. + * + * @param values an array containing all the values to be stored into the object when it is + * recreated. + * @param slotKinds an array containing the Java kinds of the values. This must have the same + * length as {@code values}. This array is now owned by this object and must not be + * mutated by the caller. + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `slotKinds`") + public void setValues(JavaValue[] values, JavaKind[] slotKinds) { + assert values.length == slotKinds.length; + this.values = values; + this.slotKinds = slotKinds; + } + + @Override + public int hashCode() { + return 42 + type.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o instanceof VirtualObject) { + VirtualObject l = (VirtualObject) o; + if (!l.type.equals(type) || l.values.length != values.length) { + return false; + } + for (int i = 0; i < values.length; i++) { + /* + * Virtual objects can form cycles. Calling equals() could therefore lead to + * infinite recursion. + */ + if (!same(values[i], l.values[i])) { + return false; + } + } + return true; + } + return false; + } + + private static boolean same(Object o1, Object o2) { + return o1 == o2; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/InitTimer.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/InitTimer.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/InitTimer.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/InitTimer.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.common; + +import java.util.concurrent.atomic.AtomicInteger; + +import jdk.vm.ci.services.Services; + +/** + * A facility for timing a step in the runtime initialization sequence. This is independent from all + * other JVMCI code so as to not perturb the initialization sequence. It is enabled by setting the + * {@code "jvmci.inittimer"} system property to {@code "true"}. + */ +public final class InitTimer implements AutoCloseable { + private final String name; + private final long start; + + private InitTimer(String name) { + int n = nesting.getAndIncrement(); + if (n == 0) { + initializingThread = Thread.currentThread(); + System.out.println("INITIALIZING THREAD: " + initializingThread); + } else { + assert Thread.currentThread() == initializingThread : Thread.currentThread() + " != " + initializingThread; + } + this.name = name; + this.start = System.currentTimeMillis(); + System.out.println("START: " + SPACES.substring(0, n * 2) + name); + } + + @Override + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "only the initializing thread accesses this field") + public void close() { + final long end = System.currentTimeMillis(); + int n = nesting.decrementAndGet(); + System.out.println(" DONE: " + SPACES.substring(0, n * 2) + name + " [" + (end - start) + " ms]"); + if (n == 0) { + initializingThread = null; + } + } + + public static InitTimer timer(String name) { + return isEnabled() ? new InitTimer(name) : null; + } + + public static InitTimer timer(String name, Object suffix) { + return isEnabled() ? new InitTimer(name + suffix) : null; + } + + /** + * Determines if initialization timing is enabled. Note: This property cannot use + * {@code HotSpotJVMCIRuntime.Option} since that class is not visible from this package. + */ + private static boolean isEnabled() { + if (enabledPropertyValue == null) { + enabledPropertyValue = Boolean.parseBoolean(Services.getSavedProperty("jvmci.InitTimer")); + nesting = new AtomicInteger(); + } + return enabledPropertyValue; + } + + /** + * Cache for value of {@code jvmci.InitTimer} system property. + */ + @NativeImageReinitialize private static Boolean enabledPropertyValue; + + private static AtomicInteger nesting; + private static final String SPACES = " "; + + /** + * Used to assert the invariant that all related initialization happens on the same thread. + */ + static Thread initializingThread; +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/JVMCIError.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/JVMCIError.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/JVMCIError.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/JVMCIError.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.common; + +import java.util.ArrayList; +import java.util.Locale; + +/** + * Indicates a condition in JVMCI related code that should never occur during normal operation. + */ +public class JVMCIError extends Error { + + private static final long serialVersionUID = 531632331813456233L; + + public static RuntimeException unimplemented() { + throw new JVMCIError("unimplemented"); + } + + public static RuntimeException unimplemented(String msg) { + throw new JVMCIError("unimplemented: %s", msg); + } + + public static RuntimeException shouldNotReachHere() { + throw new JVMCIError("should not reach here"); + } + + public static RuntimeException shouldNotReachHere(String msg) { + throw new JVMCIError("should not reach here: %s", msg); + } + + public static RuntimeException shouldNotReachHere(Throwable cause) { + throw new JVMCIError(cause); + } + + /** + * Checks a given condition and throws a {@link JVMCIError} if it is false. Guarantees are + * stronger than assertions in that they are always checked. Error messages for guarantee + * violations should clearly indicate the nature of the problem as well as a suggested solution + * if possible. + * + * @param condition the condition to check + * @param msg the message that will be associated with the error, in + * {@link String#format(String, Object...)} syntax + * @param args arguments to the format string + */ + public static void guarantee(boolean condition, String msg, Object... args) { + if (!condition) { + throw new JVMCIError("failed guarantee: " + msg, args); + } + } + + /** + * This constructor creates a {@link JVMCIError} with a given message. + * + * @param msg the message that will be associated with the error + */ + public JVMCIError(String msg) { + super(msg); + } + + /** + * This constructor creates a {@link JVMCIError} with a message assembled via + * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to + * always generate the same output. + * + * @param msg the message that will be associated with the error, in String.format syntax + * @param args parameters to String.format - parameters that implement {@link Iterable} will be + * expanded into a [x, x, ...] representation. + */ + public JVMCIError(String msg, Object... args) { + super(format(msg, args)); + } + + /** + * This constructor creates a {@link JVMCIError} for a given causing Throwable instance. + * + * @param cause the original exception that contains additional information on this error + */ + public JVMCIError(Throwable cause) { + super(cause); + } + + private static String format(String msg, Object... args) { + if (args != null) { + // expand Iterable parameters into a list representation + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Iterable) { + ArrayList list = new ArrayList<>(); + for (Object o : (Iterable) args[i]) { + list.add(o); + } + args[i] = list.toString(); + } + } + } + return String.format(Locale.ENGLISH, msg, args); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/NativeImageReinitialize.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/NativeImageReinitialize.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/NativeImageReinitialize.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/NativeImageReinitialize.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.common; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Denotes a field that should have the default value for its type in an ahead of time image. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface NativeImageReinitialize { +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * Common utility classes used by the JVMCI API. + */ +package jdk.vm.ci.common; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/common/SuppressFBWarnings.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.common; + +/** + * Used to suppress FindBugs warnings. + */ +@interface SuppressFBWarnings { + /** + * The set of FindBugs + * warnings that are to be + * suppressed in annotated element. The value can be a bug category, kind or pattern. + */ + String[] value(); + + /** + * Reason why the warning is suppressed. + */ + String justification(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015, 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. + */ +package jdk.vm.ci.hotspot.aarch64; + +import static java.util.Collections.emptyMap; +import static jdk.vm.ci.common.InitTimer.timer; + +import java.util.EnumSet; +import java.util.Map; + +import jdk.vm.ci.aarch64.AArch64; +import jdk.vm.ci.aarch64.AArch64.CPUFeature; +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.RegisterConfig; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.stack.StackIntrospection; +import jdk.vm.ci.common.InitTimer; +import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; +import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; +import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; +import jdk.vm.ci.hotspot.HotSpotStackIntrospection; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.runtime.JVMCIBackend; + +public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory { + + private static EnumSet computeFeatures(AArch64HotSpotVMConfig config) { + // Configure the feature set using the HotSpot flag settings. + Map constants = config.getStore().getConstants(); + return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, emptyMap()); + } + + private static EnumSet computeFlags(AArch64HotSpotVMConfig config) { + EnumSet flags = EnumSet.noneOf(AArch64.Flag.class); + + if (config.useCRC32) { + flags.add(AArch64.Flag.UseCRC32); + } + if (config.useNeon) { + flags.add(AArch64.Flag.UseNeon); + } + if (config.useSIMDForMemoryOps) { + flags.add(AArch64.Flag.UseSIMDForMemoryOps); + } + if (config.avoidUnalignedAccesses) { + flags.add(AArch64.Flag.AvoidUnalignedAccesses); + } + if (config.useLSE) { + flags.add(AArch64.Flag.UseLSE); + } + if (config.useBlockZeroing) { + flags.add(AArch64.Flag.UseBlockZeroing); + } + + return flags; + } + + private static TargetDescription createTarget(AArch64HotSpotVMConfig config) { + final int stackFrameAlignment = 16; + final int implicitNullCheckLimit = 4096; + final boolean inlineObjects = true; + Architecture arch = new AArch64(computeFeatures(config), computeFlags(config)); + return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + } + + protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntime runtime) { + return new HotSpotConstantReflectionProvider(runtime); + } + + private static RegisterConfig createRegisterConfig(AArch64HotSpotVMConfig config, TargetDescription target) { + // ARMv8 defines r18 as being available to the platform ABI. Windows + // and Darwin use it for such. Linux doesn't assign it and thus r18 can + // be used as an additional register. + boolean canUsePlatformRegister = config.linuxOs; + return new AArch64HotSpotRegisterConfig(target, config.useCompressedOops, canUsePlatformRegister); + } + + protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { + return new HotSpotCodeCacheProvider(runtime, target, regConfig); + } + + protected HotSpotMetaAccessProvider createMetaAccess(HotSpotJVMCIRuntime runtime) { + return new HotSpotMetaAccessProvider(runtime); + } + + @Override + public String getArchitecture() { + return "aarch64"; + } + + @Override + public String toString() { + return "JVMCIBackend:" + getArchitecture(); + } + + @Override + @SuppressWarnings("try") + public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host) { + + assert host == null; + AArch64HotSpotVMConfig config = new AArch64HotSpotVMConfig(runtime.getConfigStore()); + TargetDescription target = createTarget(config); + + RegisterConfig regConfig; + HotSpotCodeCacheProvider codeCache; + ConstantReflectionProvider constantReflection; + HotSpotMetaAccessProvider metaAccess; + StackIntrospection stackIntrospection; + try (InitTimer t = timer("create providers")) { + try (InitTimer rt = timer("create MetaAccess provider")) { + metaAccess = createMetaAccess(runtime); + } + try (InitTimer rt = timer("create RegisterConfig")) { + regConfig = createRegisterConfig(config, target); + } + try (InitTimer rt = timer("create CodeCache provider")) { + codeCache = createCodeCache(runtime, target, regConfig); + } + try (InitTimer rt = timer("create ConstantReflection provider")) { + constantReflection = createConstantReflection(runtime); + } + try (InitTimer rt = timer("create StackIntrospection provider")) { + stackIntrospection = new HotSpotStackIntrospection(runtime); + } + } + try (InitTimer rt = timer("instantiate backend")) { + return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection); + } + } + + protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, + StackIntrospection stackIntrospection) { + return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2015, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot.aarch64; + +import static jdk.vm.ci.aarch64.AArch64.lr; +import static jdk.vm.ci.aarch64.AArch64.r0; +import static jdk.vm.ci.aarch64.AArch64.r1; +import static jdk.vm.ci.aarch64.AArch64.r2; +import static jdk.vm.ci.aarch64.AArch64.r3; +import static jdk.vm.ci.aarch64.AArch64.r4; +import static jdk.vm.ci.aarch64.AArch64.r5; +import static jdk.vm.ci.aarch64.AArch64.r6; +import static jdk.vm.ci.aarch64.AArch64.r7; +import static jdk.vm.ci.aarch64.AArch64.rscratch1; +import static jdk.vm.ci.aarch64.AArch64.rscratch2; +import static jdk.vm.ci.aarch64.AArch64.r12; +import static jdk.vm.ci.aarch64.AArch64.r18; +import static jdk.vm.ci.aarch64.AArch64.r27; +import static jdk.vm.ci.aarch64.AArch64.r28; +import static jdk.vm.ci.aarch64.AArch64.r29; +import static jdk.vm.ci.aarch64.AArch64.r31; +import static jdk.vm.ci.aarch64.AArch64.sp; +import static jdk.vm.ci.aarch64.AArch64.v0; +import static jdk.vm.ci.aarch64.AArch64.v1; +import static jdk.vm.ci.aarch64.AArch64.v2; +import static jdk.vm.ci.aarch64.AArch64.v3; +import static jdk.vm.ci.aarch64.AArch64.v4; +import static jdk.vm.ci.aarch64.AArch64.v5; +import static jdk.vm.ci.aarch64.AArch64.v6; +import static jdk.vm.ci.aarch64.AArch64.v7; +import static jdk.vm.ci.aarch64.AArch64.zr; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import jdk.vm.ci.aarch64.AArch64; +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.CallingConvention; +import jdk.vm.ci.code.CallingConvention.Type; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.RegisterArray; +import jdk.vm.ci.code.RegisterAttributes; +import jdk.vm.ci.code.RegisterConfig; +import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.ValueKindFactory; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.hotspot.HotSpotCallingConventionType; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.PlatformKind; +import jdk.vm.ci.meta.Value; +import jdk.vm.ci.meta.ValueKind; + +public class AArch64HotSpotRegisterConfig implements RegisterConfig { + + private final TargetDescription target; + + private final RegisterArray allocatable; + + /** + * The caller saved registers always include all parameter registers. + */ + private final RegisterArray callerSaved; + + private final boolean allAllocatableAreCallerSaved; + + private final RegisterAttributes[] attributesMap; + + @Override + public RegisterArray getAllocatableRegisters() { + return allocatable; + } + + @Override + public RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers) { + ArrayList list = new ArrayList<>(); + for (Register reg : registers) { + if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) { + list.add(reg); + } + } + + return new RegisterArray(list); + } + + @Override + public RegisterAttributes[] getAttributesMap() { + return attributesMap.clone(); + } + + private final RegisterArray javaGeneralParameterRegisters = new RegisterArray(r1, r2, r3, r4, r5, r6, r7, r0); + private final RegisterArray nativeGeneralParameterRegisters = new RegisterArray(r0, r1, r2, r3, r4, r5, r6, r7); + private final RegisterArray simdParameterRegisters = new RegisterArray(v0, v1, v2, v3, v4, v5, v6, v7); + + public static final Register inlineCacheRegister = rscratch2; + + /** + * Vtable stubs expect the metaspace Method in r12. + */ + public static final Register metaspaceMethodRegister = r12; + + /** + * The platform ABI can use r18 to carry inter-procedural state (e.g. thread + * context). If not defined as such by the platform ABI, it can be used as + * additional temporary register. + */ + public static final Register platformRegister = r18; + public static final Register heapBaseRegister = r27; + public static final Register threadRegister = r28; + public static final Register fp = r29; + + private static final RegisterArray reservedRegisters = new RegisterArray(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp); + + private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase, boolean canUsePlatformRegister) { + RegisterArray allRegisters = arch.getAvailableValueRegisters(); + Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0) - (!canUsePlatformRegister ? 1 : 0)]; + List reservedRegistersList = reservedRegisters.asList(); + + int idx = 0; + for (Register reg : allRegisters) { + if (reservedRegistersList.contains(reg)) { + // skip reserved registers + continue; + } + if (!canUsePlatformRegister && reg.equals(platformRegister)) { + continue; + } + assert !(reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp)); + if (reserveForHeapBase && reg.equals(heapBaseRegister)) { + // skip heap base register + continue; + } + + registers[idx++] = reg; + } + + assert idx == registers.length; + return new RegisterArray(registers); + } + + public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean canUsePlatformRegister) { + this(target, initAllocatable(target.arch, useCompressedOops, canUsePlatformRegister)); + assert callerSaved.size() >= allocatable.size(); + } + + public AArch64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable) { + this.target = target; + + this.allocatable = allocatable; + Set callerSaveSet = new HashSet<>(); + allocatable.addTo(callerSaveSet); + simdParameterRegisters.addTo(callerSaveSet); + javaGeneralParameterRegisters.addTo(callerSaveSet); + nativeGeneralParameterRegisters.addTo(callerSaveSet); + callerSaved = new RegisterArray(callerSaveSet); + + allAllocatableAreCallerSaved = true; + attributesMap = RegisterAttributes.createMap(this, AArch64.allRegisters); + } + + @Override + public RegisterArray getCallerSaveRegisters() { + return callerSaved; + } + + @Override + public RegisterArray getCalleeSaveRegisters() { + return null; + } + + @Override + public boolean areAllAllocatableRegistersCallerSaved() { + return allAllocatableAreCallerSaved; + } + + @Override + public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory valueKindFactory) { + HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; + if (type == HotSpotCallingConventionType.NativeCall) { + return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory); + } + // On x64, parameter locations are the same whether viewed + // from the caller or callee perspective + return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory); + } + + @Override + public RegisterArray getCallingConventionRegisters(Type type, JavaKind kind) { + HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; + switch (kind) { + case Boolean: + case Byte: + case Short: + case Char: + case Int: + case Long: + case Object: + return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; + case Float: + case Double: + return simdParameterRegisters; + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + private CallingConvention callingConvention(RegisterArray generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, + ValueKindFactory valueKindFactory) { + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; + + int currentGeneral = 0; + int currentSIMD = 0; + int currentStackOffset = 0; + + for (int i = 0; i < parameterTypes.length; i++) { + final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind(); + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Long: + case Object: + if (currentGeneral < generalParameterRegisters.size()) { + Register register = generalParameterRegisters.get(currentGeneral++); + locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); + } + break; + case Float: + case Double: + if (currentSIMD < simdParameterRegisters.size()) { + Register register = simdParameterRegisters.get(currentSIMD++); + locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); + } + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + + if (locations[i] == null) { + ValueKind valueKind = valueKindFactory.getValueKind(kind); + locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out); + currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize); + } + } + + JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind(); + AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind())); + return new CallingConvention(currentStackOffset, returnLocation, locations); + } + + @Override + public Register getReturnRegister(JavaKind kind) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + return r0; + case Float: + case Double: + return v0; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public Register getFrameRegister() { + return sp; + } + + @Override + public String toString() { + return String.format("Allocatable: " + getAllocatableRegisters() + "%n" + "CallerSave: " + getCallerSaveRegisters() + "%n"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, 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. + */ +package jdk.vm.ci.hotspot.aarch64; + +import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; +import jdk.vm.ci.hotspot.HotSpotVMConfigStore; +import jdk.vm.ci.services.Services; + +/** + * Used to access native configuration details. + * + * All non-static, public fields in this class are so that they can be compiled as constants. + */ +class AArch64HotSpotVMConfig extends HotSpotVMConfigAccess { + + AArch64HotSpotVMConfig(HotSpotVMConfigStore config) { + super(config); + } + + final boolean linuxOs = Services.getSavedProperty("os.name", "").startsWith("Linux"); + + final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class); + + // CPU Capabilities + + /* + * These flags are set based on the corresponding command line flags. + */ + final boolean useCRC32 = getFlag("UseCRC32", Boolean.class); + final boolean useNeon = getFlag("UseNeon", Boolean.class); + final boolean useSIMDForMemoryOps = getFlag("UseSIMDForMemoryOps", Boolean.class); + final boolean avoidUnalignedAccesses = getFlag("AvoidUnalignedAccesses", Boolean.class); + final boolean useLSE = getFlag("UseLSE", Boolean.class); + final boolean useBlockZeroing = getFlag("UseBlockZeroing", Boolean.class); + + final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t"); + + /* + * These flags are set if the corresponding support is in the hardware. + */ + final long aarch64FP = getConstant("VM_Version::CPU_FP", Long.class); + final long aarch64ASIMD = getConstant("VM_Version::CPU_ASIMD", Long.class); + final long aarch64EVTSTRM = getConstant("VM_Version::CPU_EVTSTRM", Long.class); + final long aarch64AES = getConstant("VM_Version::CPU_AES", Long.class); + final long aarch64PMULL = getConstant("VM_Version::CPU_PMULL", Long.class); + final long aarch64SHA1 = getConstant("VM_Version::CPU_SHA1", Long.class); + final long aarch64SHA2 = getConstant("VM_Version::CPU_SHA2", Long.class); + final long aarch64CRC32 = getConstant("VM_Version::CPU_CRC32", Long.class); + final long aarch64LSE = getConstant("VM_Version::CPU_LSE", Long.class); + final long aarch64STXR_PREFETCH = getConstant("VM_Version::CPU_STXR_PREFETCH", Long.class); + final long aarch64A53MAC = getConstant("VM_Version::CPU_A53MAC", Long.class); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * The AArch64 HotSpot specific portions of the JVMCI API. + */ +package jdk.vm.ci.hotspot.aarch64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2012, 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. + */ +package jdk.vm.ci.hotspot.amd64; + +import static jdk.vm.ci.common.InitTimer.timer; + +import java.util.EnumSet; +import java.util.Map; + +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.amd64.AMD64.CPUFeature; +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.RegisterConfig; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.stack.StackIntrospection; +import jdk.vm.ci.common.InitTimer; +import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; +import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; +import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; +import jdk.vm.ci.hotspot.HotSpotStackIntrospection; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.runtime.JVMCIBackend; + +public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory { + + private static EnumSet computeFeatures(AMD64HotSpotVMConfig config) { + // Configure the feature set using the HotSpot flag settings. + Map constants = config.getStore().getConstants(); + Map renaming = Map.of("3DNOW_PREFETCH", "AMD_3DNOW_PREFETCH"); + assert config.useSSE >= 2 : "minimum config for x64"; + EnumSet features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, renaming); + features.add(AMD64.CPUFeature.SSE); + features.add(AMD64.CPUFeature.SSE2); + return features; + } + + private static EnumSet computeFlags(AMD64HotSpotVMConfig config) { + EnumSet flags = EnumSet.noneOf(AMD64.Flag.class); + if (config.useCountLeadingZerosInstruction) { + flags.add(AMD64.Flag.UseCountLeadingZerosInstruction); + } + if (config.useCountTrailingZerosInstruction) { + flags.add(AMD64.Flag.UseCountTrailingZerosInstruction); + } + return flags; + } + + private static TargetDescription createTarget(AMD64HotSpotVMConfig config) { + final int stackFrameAlignment = 16; + final int implicitNullCheckLimit = 4096; + final boolean inlineObjects = true; + Architecture arch = new AMD64(computeFeatures(config), computeFlags(config)); + return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + } + + protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntime runtime) { + return new HotSpotConstantReflectionProvider(runtime); + } + + private static RegisterConfig createRegisterConfig(AMD64HotSpotVMConfig config, TargetDescription target) { + return new AMD64HotSpotRegisterConfig(target, config.useCompressedOops, config.windowsOs); + } + + protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { + return new HotSpotCodeCacheProvider(runtime, target, regConfig); + } + + protected HotSpotMetaAccessProvider createMetaAccess(HotSpotJVMCIRuntime runtime) { + return new HotSpotMetaAccessProvider(runtime); + } + + @Override + public String getArchitecture() { + return "AMD64"; + } + + @Override + public String toString() { + return "JVMCIBackend:" + getArchitecture(); + } + + @Override + @SuppressWarnings("try") + public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host) { + assert host == null; + AMD64HotSpotVMConfig config = new AMD64HotSpotVMConfig(runtime.getConfigStore()); + TargetDescription target = createTarget(config); + + RegisterConfig regConfig; + HotSpotCodeCacheProvider codeCache; + ConstantReflectionProvider constantReflection; + HotSpotMetaAccessProvider metaAccess; + StackIntrospection stackIntrospection; + try (InitTimer t = timer("create providers")) { + try (InitTimer rt = timer("create MetaAccess provider")) { + metaAccess = createMetaAccess(runtime); + } + try (InitTimer rt = timer("create RegisterConfig")) { + regConfig = createRegisterConfig(config, target); + } + try (InitTimer rt = timer("create CodeCache provider")) { + codeCache = createCodeCache(runtime, target, regConfig); + } + try (InitTimer rt = timer("create ConstantReflection provider")) { + constantReflection = createConstantReflection(runtime); + } + try (InitTimer rt = timer("create StackIntrospection provider")) { + stackIntrospection = new HotSpotStackIntrospection(runtime); + } + } + try (InitTimer rt = timer("instantiate backend")) { + return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection); + } + } + + protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, + StackIntrospection stackIntrospection) { + return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot.amd64; + +import static jdk.vm.ci.amd64.AMD64.r12; +import static jdk.vm.ci.amd64.AMD64.r15; +import static jdk.vm.ci.amd64.AMD64.r8; +import static jdk.vm.ci.amd64.AMD64.r9; +import static jdk.vm.ci.amd64.AMD64.rax; +import static jdk.vm.ci.amd64.AMD64.rcx; +import static jdk.vm.ci.amd64.AMD64.rdi; +import static jdk.vm.ci.amd64.AMD64.rdx; +import static jdk.vm.ci.amd64.AMD64.rsi; +import static jdk.vm.ci.amd64.AMD64.rsp; +import static jdk.vm.ci.amd64.AMD64.xmm0; +import static jdk.vm.ci.amd64.AMD64.xmm1; +import static jdk.vm.ci.amd64.AMD64.xmm2; +import static jdk.vm.ci.amd64.AMD64.xmm3; +import static jdk.vm.ci.amd64.AMD64.xmm4; +import static jdk.vm.ci.amd64.AMD64.xmm5; +import static jdk.vm.ci.amd64.AMD64.xmm6; +import static jdk.vm.ci.amd64.AMD64.xmm7; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.CallingConvention; +import jdk.vm.ci.code.CallingConvention.Type; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.RegisterArray; +import jdk.vm.ci.code.RegisterAttributes; +import jdk.vm.ci.code.RegisterConfig; +import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.ValueKindFactory; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.hotspot.HotSpotCallingConventionType; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.PlatformKind; +import jdk.vm.ci.meta.Value; +import jdk.vm.ci.meta.ValueKind; + +public class AMD64HotSpotRegisterConfig implements RegisterConfig { + + private final TargetDescription target; + + private final RegisterArray allocatable; + + /** + * The caller saved registers always include all parameter registers. + */ + private final RegisterArray callerSaved; + + private final boolean allAllocatableAreCallerSaved; + + private final RegisterAttributes[] attributesMap; + + @Override + public RegisterArray getAllocatableRegisters() { + return allocatable; + } + + @Override + public RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers) { + ArrayList list = new ArrayList<>(); + for (Register reg : registers) { + if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) { + list.add(reg); + } + } + + RegisterArray ret = new RegisterArray(list); + return ret; + } + + @Override + public RegisterAttributes[] getAttributesMap() { + return attributesMap.clone(); + } + + private final RegisterArray javaGeneralParameterRegisters; + private final RegisterArray nativeGeneralParameterRegisters; + private final RegisterArray javaXMMParameterRegisters; + private final RegisterArray nativeXMMParameterRegisters; + private final boolean windowsOS; + + /* + * Some ABIs (e.g. Windows) require a so-called "home space", that is a save area on the stack + * to store the argument registers + */ + private final boolean needsNativeStackHomeSpace; + + private static final RegisterArray reservedRegisters = new RegisterArray(rsp, r15); + + private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) { + RegisterArray allRegisters = arch.getAvailableValueRegisters(); + Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0)]; + List reservedRegistersList = reservedRegisters.asList(); + + int idx = 0; + for (Register reg : allRegisters) { + if (reservedRegistersList.contains(reg)) { + // skip reserved registers + continue; + } + if (reserveForHeapBase && reg.equals(r12)) { + // skip heap base register + continue; + } + + registers[idx++] = reg; + } + + assert idx == registers.length; + return new RegisterArray(registers); + } + + public AMD64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean windowsOs) { + this(target, initAllocatable(target.arch, useCompressedOops), windowsOs); + assert callerSaved.size() >= allocatable.size(); + } + + public AMD64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable, boolean windowsOS) { + this.target = target; + this.windowsOS = windowsOS; + + if (windowsOS) { + javaGeneralParameterRegisters = new RegisterArray(rdx, r8, r9, rdi, rsi, rcx); + nativeGeneralParameterRegisters = new RegisterArray(rcx, rdx, r8, r9); + nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3); + this.needsNativeStackHomeSpace = true; + } else { + javaGeneralParameterRegisters = new RegisterArray(rsi, rdx, rcx, r8, r9, rdi); + nativeGeneralParameterRegisters = new RegisterArray(rdi, rsi, rdx, rcx, r8, r9); + nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7); + this.needsNativeStackHomeSpace = false; + } + javaXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7); + + this.allocatable = allocatable; + Set callerSaveSet = new HashSet<>(); + allocatable.addTo(callerSaveSet); + javaXMMParameterRegisters.addTo(callerSaveSet); + callerSaveSet.addAll(javaGeneralParameterRegisters.asList()); + nativeGeneralParameterRegisters.addTo(callerSaveSet); + callerSaved = new RegisterArray(callerSaveSet); + + allAllocatableAreCallerSaved = true; + attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters()); + } + + @Override + public RegisterArray getCallerSaveRegisters() { + return callerSaved; + } + + @Override + public RegisterArray getCalleeSaveRegisters() { + return null; + } + + @Override + public boolean areAllAllocatableRegistersCallerSaved() { + return allAllocatableAreCallerSaved; + } + + @Override + public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory valueKindFactory) { + HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; + if (type == HotSpotCallingConventionType.NativeCall) { + return callingConvention(nativeGeneralParameterRegisters, nativeXMMParameterRegisters, windowsOS, returnType, parameterTypes, hotspotType, valueKindFactory); + } + // On x64, parameter locations are the same whether viewed + // from the caller or callee perspective + return callingConvention(javaGeneralParameterRegisters, javaXMMParameterRegisters, false, returnType, parameterTypes, hotspotType, valueKindFactory); + } + + @Override + public RegisterArray getCallingConventionRegisters(Type type, JavaKind kind) { + HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; + switch (kind) { + case Boolean: + case Byte: + case Short: + case Char: + case Int: + case Long: + case Object: + return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; + case Float: + case Double: + return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeXMMParameterRegisters : javaXMMParameterRegisters; + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + /** + * Hand out registers matching the calling convention from the {@code generalParameterRegisters} + * and {@code xmmParameterRegisters} sets. Normally registers are handed out from each set + * individually based on the type of the argument. If the {@code unified} flag is true then hand + * out registers in a single sequence, selecting between the sets based on the type. This is to + * support the Windows calling convention which only ever passes 4 arguments in registers, no + * matter their types. + * + * @param generalParameterRegisters + * @param xmmParameterRegisters + * @param unified + * @param returnType + * @param parameterTypes + * @param type + * @param valueKindFactory + * @return the resulting calling convention + */ + private CallingConvention callingConvention(RegisterArray generalParameterRegisters, RegisterArray xmmParameterRegisters, boolean unified, JavaType returnType, JavaType[] parameterTypes, + HotSpotCallingConventionType type, + ValueKindFactory valueKindFactory) { + assert !unified || generalParameterRegisters.size() == xmmParameterRegisters.size() : "must be same size in unified mode"; + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; + + int currentGeneral = 0; + int currentXMM = 0; + int currentStackOffset = type == HotSpotCallingConventionType.NativeCall && needsNativeStackHomeSpace ? generalParameterRegisters.size() * target.wordSize : 0; + + for (int i = 0; i < parameterTypes.length; i++) { + final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind(); + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Long: + case Object: + if (currentGeneral < generalParameterRegisters.size()) { + Register register = generalParameterRegisters.get(currentGeneral++); + locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); + } + break; + case Float: + case Double: + if ((unified ? currentGeneral : currentXMM) < xmmParameterRegisters.size()) { + Register register = xmmParameterRegisters.get(unified ? currentGeneral++ : currentXMM++); + locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); + } + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + + if (locations[i] == null) { + ValueKind valueKind = valueKindFactory.getValueKind(kind); + locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out); + currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize); + } + } + assert !unified || currentXMM == 0 : "shouldn't be used in unified mode"; + + JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind(); + AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind())); + return new CallingConvention(currentStackOffset, returnLocation, locations); + } + + @Override + public Register getReturnRegister(JavaKind kind) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + return rax; + case Float: + case Double: + return xmm0; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public Register getFrameRegister() { + return rsp; + } + + @Override + public String toString() { + return String.format("Allocatable: " + getAllocatableRegisters() + "%n" + "CallerSave: " + getCallerSaveRegisters() + "%n"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot.amd64; + +import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; +import jdk.vm.ci.hotspot.HotSpotVMConfigStore; +import jdk.vm.ci.services.Services; + +/** + * Used to access AMD64 specific native configuration details. + */ +class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess { + + AMD64HotSpotVMConfig(HotSpotVMConfigStore config) { + super(config); + } + + final boolean windowsOs = Services.getSavedProperty("os.name", "").startsWith("Windows"); + + final boolean useCountLeadingZerosInstruction = getFlag("UseCountLeadingZerosInstruction", Boolean.class); + final boolean useCountTrailingZerosInstruction = getFlag("UseCountTrailingZerosInstruction", Boolean.class); + final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class); + + // CPU capabilities + final int useSSE = getFlag("UseSSE", Integer.class); + final int useAVX = getFlag("UseAVX", Integer.class); + + final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t"); + + // CPU feature flags + final long amd64CX8 = getConstant("VM_Version::CPU_CX8", Long.class); + final long amd64CMOV = getConstant("VM_Version::CPU_CMOV", Long.class); + final long amd64FXSR = getConstant("VM_Version::CPU_FXSR", Long.class); + final long amd64HT = getConstant("VM_Version::CPU_HT", Long.class); + final long amd64MMX = getConstant("VM_Version::CPU_MMX", Long.class); + final long amd643DNOWPREFETCH = getConstant("VM_Version::CPU_3DNOW_PREFETCH", Long.class); + final long amd64SSE = getConstant("VM_Version::CPU_SSE", Long.class); + final long amd64SSE2 = getConstant("VM_Version::CPU_SSE2", Long.class); + final long amd64SSE3 = getConstant("VM_Version::CPU_SSE3", Long.class); + final long amd64SSSE3 = getConstant("VM_Version::CPU_SSSE3", Long.class); + final long amd64SSE4A = getConstant("VM_Version::CPU_SSE4A", Long.class); + final long amd64SSE41 = getConstant("VM_Version::CPU_SSE4_1", Long.class); + final long amd64SSE42 = getConstant("VM_Version::CPU_SSE4_2", Long.class); + final long amd64POPCNT = getConstant("VM_Version::CPU_POPCNT", Long.class); + final long amd64LZCNT = getConstant("VM_Version::CPU_LZCNT", Long.class); + final long amd64TSC = getConstant("VM_Version::CPU_TSC", Long.class); + final long amd64TSCINV = getConstant("VM_Version::CPU_TSCINV", Long.class); + final long amd64AVX = getConstant("VM_Version::CPU_AVX", Long.class); + final long amd64AVX2 = getConstant("VM_Version::CPU_AVX2", Long.class); + final long amd64AES = getConstant("VM_Version::CPU_AES", Long.class); + final long amd64ERMS = getConstant("VM_Version::CPU_ERMS", Long.class); + final long amd64CLMUL = getConstant("VM_Version::CPU_CLMUL", Long.class); + final long amd64BMI1 = getConstant("VM_Version::CPU_BMI1", Long.class); + final long amd64BMI2 = getConstant("VM_Version::CPU_BMI2", Long.class); + final long amd64RTM = getConstant("VM_Version::CPU_RTM", Long.class); + final long amd64ADX = getConstant("VM_Version::CPU_ADX", Long.class); + final long amd64AVX512F = getConstant("VM_Version::CPU_AVX512F", Long.class); + final long amd64AVX512DQ = getConstant("VM_Version::CPU_AVX512DQ", Long.class); + final long amd64AVX512PF = getConstant("VM_Version::CPU_AVX512PF", Long.class); + final long amd64AVX512ER = getConstant("VM_Version::CPU_AVX512ER", Long.class); + final long amd64AVX512CD = getConstant("VM_Version::CPU_AVX512CD", Long.class); + final long amd64AVX512BW = getConstant("VM_Version::CPU_AVX512BW", Long.class); + final long amd64AVX512VL = getConstant("VM_Version::CPU_AVX512VL", Long.class); + final long amd64SHA = getConstant("VM_Version::CPU_SHA", Long.class); + final long amd64FMA = getConstant("VM_Version::CPU_FMA", Long.class); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * The AMD64 HotSpot specific portions of the JVMCI API. + */ +package jdk.vm.ci.hotspot.amd64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * A cleaner tracks a referent object and includes some {@linkplain #doCleanup() cleanup code} that + * is run some time after the referent object has become weakly-reachable. + * + * This is like {@link java.lang.ref.Cleaner} but with weak semantics instead of phantom. Objects + * referenced by this might be referenced by {@link ResolvedJavaType} which is kept alive by a + * {@link WeakReference} so we need equivalent reference strength. + */ +abstract class Cleaner extends WeakReference { + + /** + * Head of linked list of cleaners. + */ + @NativeImageReinitialize private static Cleaner first; + + /** + * Linked list pointers. + */ + private Cleaner next = null; + private Cleaner prev = null; + + Cleaner(Object referent) { + super(referent, queue); + add(this); + } + + private static synchronized Cleaner add(Cleaner cl) { + if (first != null) { + clean(); + } + if (first != null) { + cl.next = first; + first.prev = cl; + } + first = cl; + return cl; + } + + /** + * Removes {@code cl} from the linked list of cleaners. + */ + private static synchronized void remove(Cleaner cl) { + // If already removed, do nothing + if (cl.next == cl) { + return; + } + + // Update list + if (first == cl) { + if (cl.next != null) { + first = cl.next; + } else { + first = cl.prev; + } + } + if (cl.next != null) { + cl.next.prev = cl.prev; + } + if (cl.prev != null) { + cl.prev.next = cl.next; + } + + // Indicate removal by pointing the cleaner to itself + cl.next = cl; + cl.prev = cl; + } + + /** + * Performs the cleanup action now that this object's referent has become weakly reachable. + */ + abstract void doCleanup(); + + /** + * Remove the cleaners whose referents have become weakly reachable. + */ + static void clean() { + Cleaner c = (Cleaner) queue.poll(); + while (c != null) { + remove(c); + c.doCleanup(); + c = (Cleaner) queue.poll(); + } + } + + /** + * The {@link ReferenceQueue} to which {@link Cleaner}s are enqueued once their referents' + * become unreachable. + */ + private static final ReferenceQueue queue = new ReferenceQueue<>(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,998 @@ +/* + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.common.InitTimer.timer; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import java.lang.reflect.Executable; +import java.lang.reflect.Field; + +import jdk.vm.ci.code.BytecodeFrame; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.InvalidInstalledCodeException; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.stack.InspectedFrameVisitor; +import jdk.vm.ci.common.InitTimer; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * Calls from Java into HotSpot. The behavior of all the methods in this class that take a native + * pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not + * denote a valid native object. + */ +final class CompilerToVM { + /** + * Initializes the native part of the JVMCI runtime. + */ + private static native void registerNatives(); + + /** + * These values mirror the equivalent values from {@code Unsafe} but are appropriate for the JVM + * being compiled against. + */ + final int ARRAY_BOOLEAN_BASE_OFFSET; + final int ARRAY_BYTE_BASE_OFFSET; + final int ARRAY_SHORT_BASE_OFFSET; + final int ARRAY_CHAR_BASE_OFFSET; + final int ARRAY_INT_BASE_OFFSET; + final int ARRAY_LONG_BASE_OFFSET; + final int ARRAY_FLOAT_BASE_OFFSET; + final int ARRAY_DOUBLE_BASE_OFFSET; + final int ARRAY_OBJECT_BASE_OFFSET; + final int ARRAY_BOOLEAN_INDEX_SCALE; + final int ARRAY_BYTE_INDEX_SCALE; + final int ARRAY_SHORT_INDEX_SCALE; + final int ARRAY_CHAR_INDEX_SCALE; + final int ARRAY_INT_INDEX_SCALE; + final int ARRAY_LONG_INDEX_SCALE; + final int ARRAY_FLOAT_INDEX_SCALE; + final int ARRAY_DOUBLE_INDEX_SCALE; + final int ARRAY_OBJECT_INDEX_SCALE; + + @SuppressWarnings("try") + CompilerToVM() { + try (InitTimer t = timer("CompilerToVM.registerNatives")) { + registerNatives(); + ARRAY_BOOLEAN_BASE_OFFSET = arrayBaseOffset(JavaKind.Boolean); + ARRAY_BYTE_BASE_OFFSET = arrayBaseOffset(JavaKind.Byte); + ARRAY_SHORT_BASE_OFFSET = arrayBaseOffset(JavaKind.Short); + ARRAY_CHAR_BASE_OFFSET = arrayBaseOffset(JavaKind.Char); + ARRAY_INT_BASE_OFFSET = arrayBaseOffset(JavaKind.Int); + ARRAY_LONG_BASE_OFFSET = arrayBaseOffset(JavaKind.Long); + ARRAY_FLOAT_BASE_OFFSET = arrayBaseOffset(JavaKind.Float); + ARRAY_DOUBLE_BASE_OFFSET = arrayBaseOffset(JavaKind.Double); + ARRAY_OBJECT_BASE_OFFSET = arrayBaseOffset(JavaKind.Object); + ARRAY_BOOLEAN_INDEX_SCALE = arrayIndexScale(JavaKind.Boolean); + ARRAY_BYTE_INDEX_SCALE = arrayIndexScale(JavaKind.Byte); + ARRAY_SHORT_INDEX_SCALE = arrayIndexScale(JavaKind.Short); + ARRAY_CHAR_INDEX_SCALE = arrayIndexScale(JavaKind.Char); + ARRAY_INT_INDEX_SCALE = arrayIndexScale(JavaKind.Int); + ARRAY_LONG_INDEX_SCALE = arrayIndexScale(JavaKind.Long); + ARRAY_FLOAT_INDEX_SCALE = arrayIndexScale(JavaKind.Float); + ARRAY_DOUBLE_INDEX_SCALE = arrayIndexScale(JavaKind.Double); + ARRAY_OBJECT_INDEX_SCALE = arrayIndexScale(JavaKind.Object); + } + } + + native int arrayBaseOffset(JavaKind kind); + + native int arrayIndexScale(JavaKind kind); + + /** + * Gets the {@link CompilerToVM} instance associated with the singleton + * {@link HotSpotJVMCIRuntime} instance. + */ + public static CompilerToVM compilerToVM() { + return runtime().getCompilerToVM(); + } + + /** + * Copies the original bytecode of {@code method} into a new byte array and returns it. + * + * @return a new byte array containing the original bytecode of {@code method} + */ + native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method); + + /** + * Gets the number of entries in {@code method}'s exception handler table or 0 if it has no + * exception handler table. + */ + native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method); + + /** + * Gets the address of the first entry in {@code method}'s exception handler table. + * + * Each entry is a native object described by these fields: + * + *
      + *
    • {@link HotSpotVMConfig#exceptionTableElementSize}
    • + *
    • {@link HotSpotVMConfig#exceptionTableElementStartPcOffset}
    • + *
    • {@link HotSpotVMConfig#exceptionTableElementEndPcOffset}
    • + *
    • {@link HotSpotVMConfig#exceptionTableElementHandlerPcOffset}
    • + *
    • {@link HotSpotVMConfig#exceptionTableElementCatchTypeIndexOffset} + *
    + * + * @return 0 if {@code method} has no exception handlers (i.e. + * {@code getExceptionTableLength(method) == 0}) + */ + native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method); + + /** + * Determines whether {@code method} is currently compilable by the JVMCI compiler being used by + * the VM. This can return false if JVMCI compilation failed earlier for {@code method}, a + * breakpoint is currently set in {@code method} or {@code method} contains other bytecode + * features that require special handling by the VM. + */ + native boolean isCompilable(HotSpotResolvedJavaMethodImpl method); + + /** + * Determines if {@code method} is targeted by a VM directive (e.g., + * {@code -XX:CompileCommand=dontinline,}) or annotation (e.g., + * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined. + */ + native boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method); + + /** + * Determines if {@code method} should be inlined at any cost. This could be because: + *
      + *
    • a CompileOracle directive may forces inlining of this methods
    • + *
    • an annotation forces inlining of this method
    • + *
    + */ + native boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method); + + /** + * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}. + * + * @param method the method on which to base the search + * @param actualHolderType the best known type of receiver + * @return the method result or 0 is there is no unique concrete method for {@code method} + */ + native HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl actualHolderType, HotSpotResolvedJavaMethodImpl method); + + /** + * Gets the implementor for the interface class {@code type}. + * + * @return the implementor if there is a single implementor, {@code null} if there is no + * implementor, or {@code type} itself if there is more than one implementor + * @throws IllegalArgumentException if type is not an interface type + */ + native HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type); + + /** + * Determines if {@code method} is ignored by security stack walks. + */ + native boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method); + + /** + * Converts a name to a type. + * + * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format + * @param accessingClass the context of resolution. A value of {@code null} implies that the + * class should be resolved with the class loader. + * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will + * either return a {@link ResolvedJavaType} or throw an exception + * @return the type for {@code name} or 0 if resolution failed and {@code resolve == false} + * @throws ClassNotFoundException if {@code resolve == true} and the resolution failed + */ + native HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl accessingClass, boolean resolve) throws ClassNotFoundException; + + native HotSpotResolvedJavaType lookupClass(Class javaClass); + + /** + * Resolves the entry at index {@code cpi} in {@code constantPool} to an interned String object. + * + * The behavior of this method is undefined if {@code cpi} does not denote an + * {@code JVM_CONSTANT_String}. + */ + native JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the + * constant pool cache first. + * + * The behavior of this method is undefined if {@code cpi} does not denote one of the following + * entry types: {@code JVM_CONSTANT_Dynamic}, {@code JVM_CONSTANT_String}, + * {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError}, + * {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}. + */ + native JavaConstant resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * Gets the {@code JVM_CONSTANT_NameAndType} index from the entry at index {@code cpi} in + * {@code constantPool}. + * + * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a + * {@code JVM_CONSTANT_NameAndType} index. + */ + native int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * Gets the name of the {@code JVM_CONSTANT_NameAndType} entry referenced by another entry + * denoted by {@code which} in {@code constantPool}. + * + * The behavior of this method is undefined if {@code which} does not denote a entry that + * references a {@code JVM_CONSTANT_NameAndType} entry. + */ + native String lookupNameInPool(HotSpotConstantPool constantPool, int which); + + /** + * Gets the signature of the {@code JVM_CONSTANT_NameAndType} entry referenced by another entry + * denoted by {@code which} in {@code constantPool}. + * + * The behavior of this method is undefined if {@code which} does not denote a entry that + * references a {@code JVM_CONSTANT_NameAndType} entry. + */ + native String lookupSignatureInPool(HotSpotConstantPool constantPool, int which); + + /** + * Gets the {@code JVM_CONSTANT_Class} index from the entry at index {@code cpi} in + * {@code constantPool}. + * + * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a + * {@code JVM_CONSTANT_Class} index. + */ + native int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * Looks up a class denoted by the {@code JVM_CONSTANT_Class} entry at index {@code cpi} in + * {@code constantPool}. This method does not perform any resolution. + * + * The behavior of this method is undefined if {@code cpi} does not denote a + * {@code JVM_CONSTANT_Class} entry. + * + * @return the resolved class entry or a String otherwise + */ + native Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * Looks up a method denoted by the entry at index {@code cpi} in {@code constantPool}. This + * method does not perform any resolution. + * + * The behavior of this method is undefined if {@code cpi} does not denote an entry representing + * a method. + * + * @param opcode the opcode of the instruction for which the lookup is being performed or + * {@code -1}. If non-negative, then resolution checks specific to the bytecode it + * denotes are performed if the method is already resolved. Should any of these + * checks fail, 0 is returned. + * @return the resolved method entry, 0 otherwise + */ + native HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool, int cpi, byte opcode); + + // TODO resolving JVM_CONSTANT_Dynamic + + /** + * Ensures that the type referenced by the specified {@code JVM_CONSTANT_InvokeDynamic} entry at + * index {@code cpi} in {@code constantPool} is loaded and initialized. + * + * The behavior of this method is undefined if {@code cpi} does not denote a + * {@code JVM_CONSTANT_InvokeDynamic} entry. + */ + native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * If {@code cpi} denotes an entry representing a + * signature + * polymorphic method, this method ensures that the type referenced by the entry is loaded + * and initialized. It {@code cpi} does not denote a signature polymorphic method, this method + * does nothing. + */ + native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * If {@code cpi} denotes an entry representing a resolved dynamic adapter (see + * {@link #resolveInvokeDynamicInPool} and {@link #resolveInvokeHandleInPool}), return the + * opcode of the instruction for which the resolution was performed ({@code invokedynamic} or + * {@code invokevirtual}), or {@code -1} otherwise. + */ + native int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the + * classes that define signature polymorphic methods. + */ + native String[] getSignaturePolymorphicHolders(); + + /** + * Gets the resolved type denoted by the entry at index {@code cpi} in {@code constantPool}. + * + * The behavior of this method is undefined if {@code cpi} does not denote an entry representing + * a class. + * + * @throws LinkageError if resolution failed + */ + native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError; + + /** + * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index + * {@code cpi} in {@code constantPool}. For some opcodes, checks are performed that require the + * {@code method} that contains {@code opcode} to be specified. The values returned in + * {@code info} are: + * + *
    +     *     [ flags,  // fieldDescriptor::access_flags()
    +     *       offset, // fieldDescriptor::offset()
    +     *       index   // fieldDescriptor::index()
    +     *     ]
    +     * 
    + * + * The behavior of this method is undefined if {@code cpi} does not denote a + * {@code JVM_CONSTANT_Field} entry. + * + * @param info an array in which the details of the field are returned + * @return the type defining the field if resolution is successful, 0 otherwise + */ + native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int cpi, HotSpotResolvedJavaMethodImpl method, byte opcode, int[] info); + + /** + * Converts {@code cpci} from an index into the cache for {@code constantPool} to an index + * directly into {@code constantPool}. + * + * The behavior of this method is undefined if {@code ccpi} is an invalid constant pool cache + * index. + */ + native int constantPoolRemapInstructionOperandFromCache(HotSpotConstantPool constantPool, int cpci); + + /** + * Gets the appendix object (if any) associated with the entry at index {@code cpi} in + * {@code constantPool}. + */ + native HotSpotObjectConstantImpl lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi); + + /** + * Installs the result of a compilation into the code cache. + * + * @param target the target where this code should be installed + * @param compiledCode the result of a compilation + * @param code the details of the installed CodeBlob are written to this object + * @return the outcome of the installation which will be one of + * {@link HotSpotVMConfig#codeInstallResultOk}, + * {@link HotSpotVMConfig#codeInstallResultCacheFull}, + * {@link HotSpotVMConfig#codeInstallResultCodeTooLarge} or + * {@link HotSpotVMConfig#codeInstallResultDependenciesFailed}. + * @throws JVMCIError if there is something wrong with the compiled code or the associated + * metadata. + */ + native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, long failedSpeculationsAddress, byte[] speculations); + + /** + * Generates the VM metadata for some compiled code and copies them into {@code metaData}. This + * method does not install anything into the code cache. + * + * @param target the target where this code would be installed + * @param compiledCode the result of a compilation + * @param metaData the metadata is written to this object + * @return the outcome of the installation which will be one of + * {@link HotSpotVMConfig#codeInstallResultOk}, + * {@link HotSpotVMConfig#codeInstallResultCacheFull}, + * {@link HotSpotVMConfig#codeInstallResultCodeTooLarge} or + * {@link HotSpotVMConfig#codeInstallResultDependenciesFailed}. + * @throws JVMCIError if there is something wrong with the compiled code or the metadata + */ + native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData); + + /** + * Resets all compilation statistics. + */ + native void resetCompilationStatistics(); + + /** + * Reads the database of VM info. The return value encodes the info in a nested object array + * that is described by the pseudo Java object {@code info} below: + * + *
    +     *     info = [
    +     *         VMField[] vmFields,
    +     *         [String name, Long size, ...] vmTypeSizes,
    +     *         [String name, Long value, ...] vmConstants,
    +     *         [String name, Long value, ...] vmAddresses,
    +     *         VMFlag[] vmFlags
    +     *         VMIntrinsicMethod[] vmIntrinsics
    +     *     ]
    +     * 
    + * + * @return VM info as encoded above + */ + native Object[] readConfiguration(); + + /** + * Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic + * type {@code exactReceiver}. This resolution process only searches "up" the class hierarchy of + * {@code exactReceiver}. + * + * @param caller the caller or context type used to perform access checks + * @return the link-time resolved method (might be abstract) or {@code null} if it is either a + * signature polymorphic method or can not be linked. + */ + native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller); + + /** + * Gets the static initializer of {@code type}. + * + * @return {@code null} if {@code type} has no static initializer + */ + native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type); + + /** + * Determines if {@code type} or any of its currently loaded subclasses overrides + * {@code Object.finalize()}. + */ + native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type); + + /** + * Gets the method corresponding to {@code executable}. + */ + native HotSpotResolvedJavaMethodImpl asResolvedJavaMethod(Executable executable); + + /** + * Gets the maximum absolute offset of a PC relative call to {@code address} from any position + * in the code cache. + * + * @param address an address that may be called from any code in the code cache + * @return -1 if {@code address == 0} + */ + native long getMaxCallTargetOffset(long address); + + /** + * Gets a textual disassembly of {@code codeBlob}. + * + * @return a non-zero length string containing a disassembly of {@code codeBlob} or null if + * {@code codeBlob} could not be disassembled for some reason + */ + // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage + synchronized native String disassembleCodeBlob(InstalledCode installedCode); + + /** + * Gets a stack trace element for {@code method} at bytecode index {@code bci}. + */ + native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci); + + /** + * Executes some {@code installedCode} with arguments {@code args}. + * + * @return the result of executing {@code nmethodMirror} + * @throws InvalidInstalledCodeException if {@code nmethodMirror} has been invalidated + */ + native Object executeHotSpotNmethod(Object[] args, HotSpotNmethod nmethodMirror) throws InvalidInstalledCodeException; + + /** + * Gets the line number table for {@code method}. The line number table is encoded as (bci, + * source line number) pairs. + * + * @return the line number table for {@code method} or null if it doesn't have one + */ + native long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method); + + /** + * Gets the number of entries in the local variable table for {@code method}. + * + * @return the number of entries in the local variable table for {@code method} + */ + native int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method); + + /** + * Gets the address of the first entry in the local variable table for {@code method}. + * + * Each entry is a native object described by these fields: + * + *
      + *
    • {@link HotSpotVMConfig#localVariableTableElementSize}
    • + *
    • {@link HotSpotVMConfig#localVariableTableElementLengthOffset}
    • + *
    • {@link HotSpotVMConfig#localVariableTableElementNameCpIndexOffset}
    • + *
    • {@link HotSpotVMConfig#localVariableTableElementDescriptorCpIndexOffset}
    • + *
    • {@link HotSpotVMConfig#localVariableTableElementSlotOffset} + *
    • {@link HotSpotVMConfig#localVariableTableElementStartBciOffset} + *
    + * + * @return 0 if {@code method} does not have a local variable table + */ + native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method); + + /** + * Sets flags on {@code method} indicating that it should never be inlined or compiled by the + * VM. + */ + native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method); + + /** + * Invalidates the profiling information for {@code method} and (re)initializes it such that + * profiling restarts upon its next invocation. + */ + native void reprofile(HotSpotResolvedJavaMethodImpl method); + + /** + * Invalidates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be + * raised the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}. + * The {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and any + * current activations of the {@code nmethod} are deoptimized. + */ + native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror); + + /** + * Collects the current values of all JVMCI benchmark counters, summed up over all threads. + */ + native long[] collectCounters(); + + /** + * Get the current number of counters allocated for use by JVMCI. Should be the same value as + * the flag {@code JVMCICounterSize}. + */ + native int getCountersSize(); + + /** + * Attempt to change the size of the counters allocated for JVMCI. This requires a safepoint to + * safely reallocate the storage but it's advisable to increase the size in reasonable chunks. + */ + native boolean setCountersSize(int newSize); + + /** + * Determines if {@code metaspaceMethodData} is mature. + */ + native boolean isMature(long metaspaceMethodData); + + /** + * Generate a unique id to identify the result of the compile. + */ + native int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI); + + /** + * Determines if {@code method} has OSR compiled code identified by {@code entryBCI} for + * compilation level {@code level}. + */ + native boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level); + + /** + * Gets the value of {@code metaspaceSymbol} as a String. + */ + native String getSymbol(long metaspaceSymbol); + + /** + * @see jdk.vm.ci.code.stack.StackIntrospection#iterateFrames + */ + native T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor visitor); + + /** + * Materializes all virtual objects within {@code stackFrame} and updates its locals. + * + * @param invalidate if {@code true}, the compiled method for the stack frame will be + * invalidated + */ + native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); + + /** + * Gets the v-table index for interface method {@code method} in the receiver {@code type} or + * {@link HotSpotVMConfig#invalidVtableIndex} if {@code method} is not in {@code type}'s + * v-table. + * + * @throws InternalError if {@code type} is an interface, {@code method} is not defined by an + * interface, {@code type} does not implement the interface defining {@code method} + * or class represented by {@code type} is not initialized + */ + native int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, HotSpotResolvedJavaMethodImpl method); + + /** + * Determines if debug info should also be emitted at non-safepoint locations. + */ + native boolean shouldDebugNonSafepoints(); + + /** + * Writes {@code length} bytes from {@code buffer} to HotSpot's log stream. + * + * @param buffer if {@code length <= 8}, then the bytes are encoded in this value in native + * endianness order otherwise this is the address of a native memory buffer holding + * the bytes + * @param flush specifies if the log stream should be flushed after writing + */ + native void writeDebugOutput(long buffer, int length, boolean flush); + + /** + * Flush HotSpot's log stream. + */ + native void flushDebugOutput(); + + /** + * Read a HotSpot Method* value from the memory location described by {@code base} plus + * {@code displacement} and return the {@link HotSpotResolvedJavaMethodImpl} wrapping it. This + * method does no checking that the memory location actually contains a valid pointer and may + * crash the VM if an invalid location is provided. If the {@code base} is null then + * {@code displacement} is used by itself. If {@code base} is a + * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or + * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object + * and added to {@code displacement}. Any other non-null object type causes an + * {@link IllegalArgumentException} to be thrown. + * + * @param base an object to read from or null + * @param displacement + * @return null or the resolved method for this location + */ + native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(HotSpotObjectConstantImpl base, long displacement); + + /** + * Gets the {@code ConstantPool*} associated with {@code object} and returns a + * {@link HotSpotConstantPool} wrapping it. + * + * @param object a {@link HotSpotResolvedJavaMethodImpl} or + * {@link HotSpotResolvedObjectTypeImpl} object + * @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with + * {@code object} + * @throws NullPointerException if {@code object == null} + * @throws IllegalArgumentException if {@code object} is neither a + * {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl} + */ + native HotSpotConstantPool getConstantPool(MetaspaceObject object); + + /** + * Read a HotSpot Klass* value from the memory location described by {@code base} plus + * {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This + * method does no checking that the memory location actually contains a valid pointer and may + * crash the VM if an invalid location is provided. If the {@code base} is null then + * {@code displacement} is used by itself. If {@code base} is a + * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or + * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object + * and added to {@code displacement}. Any other non-null object type causes an + * {@link IllegalArgumentException} to be thrown. + * + * @param base an object to read from or null + * @param displacement + * @param compressed true if the location contains a compressed Klass* + * @return null or the resolved method for this location + */ + private native HotSpotResolvedObjectTypeImpl getResolvedJavaType0(Object base, long displacement, boolean compressed); + + HotSpotResolvedObjectTypeImpl getResolvedJavaType(MetaspaceObject base, long displacement, boolean compressed) { + return getResolvedJavaType0(base, displacement, compressed); + } + + HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotObjectConstantImpl base, long displacement, boolean compressed) { + return getResolvedJavaType0(base, displacement, compressed); + } + + HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean compressed) { + return getResolvedJavaType0(null, displacement, compressed); + } + + /** + * Return the size of the HotSpot ProfileData* pointed at by {@code position}. If + * {@code position} is outside the space of the MethodData then an + * {@link IllegalArgumentException} is thrown. A {@code position} inside the MethodData but that + * isn't pointing at a valid ProfileData will crash the VM. + * + * @param metaspaceMethodData + * @param position + * @return the size of the ProfileData item pointed at by {@code position} + * @throws IllegalArgumentException if an out of range position is given + */ + native int methodDataProfileDataSize(long metaspaceMethodData, int position); + + /** + * Gets the fingerprint for a given Klass*. + * + * @param metaspaceKlass + * @return the value of the fingerprint (zero for arrays and synthetic classes). + */ + native long getFingerprint(long metaspaceKlass); + + /** + * Return the amount of native stack required for the interpreter frames represented by + * {@code frame}. This is used when emitting the stack banging code to ensure that there is + * enough space for the frames during deoptimization. + * + * @param frame + * @return the number of bytes required for deoptimization of this frame state + */ + native int interpreterFrameSize(BytecodeFrame frame); + + /** + * Invokes non-public method {@code java.lang.invoke.LambdaForm.compileToBytecode()} on + * {@code lambdaForm} (which must be a {@code java.lang.invoke.LambdaForm} instance). + */ + native void compileToBytecode(HotSpotObjectConstantImpl lambdaForm); + + /** + * Gets the value of the VM flag named {@code name}. + * + * @param name name of a VM option + * @return {@code this} if the named VM option doesn't exist, a {@link String} or {@code null} + * if its type is {@code ccstr} or {@code ccstrlist}, a {@link Double} if its type is + * {@code double}, a {@link Boolean} if its type is {@code bool} otherwise a + * {@link Long} + */ + native Object getFlagValue(String name); + + /** + * @see ResolvedJavaType#getInterfaces() + */ + native HotSpotResolvedObjectTypeImpl[] getInterfaces(HotSpotResolvedObjectTypeImpl type); + + /** + * @see ResolvedJavaType#getComponentType() + */ + native HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl type); + + /** + * Get the array class for {@code type}. This can't be done symbolically since hidden classes + * can't be looked up by name. + */ + native HotSpotResolvedObjectTypeImpl getArrayType(HotSpotResolvedJavaType type); + + /** + * Forces initialization of {@code type}. + */ + native void ensureInitialized(HotSpotResolvedObjectTypeImpl type); + + /** + * Forces linking of {@code type}. + */ + native void ensureLinked(HotSpotResolvedObjectTypeImpl type); + + /** + * Checks if {@code object} is a String and is an interned string value. + */ + native boolean isInternedString(HotSpotObjectConstantImpl object); + + /** + * Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object + * represented by this constant. + */ + native int getIdentityHashCode(HotSpotObjectConstantImpl object); + + /** + * Converts a constant object representing a boxed primitive into a boxed primitive. + */ + native Object unboxPrimitive(HotSpotObjectConstantImpl object); + + /** + * Converts a boxed primitive into a JavaConstant representing the same value. + */ + native HotSpotObjectConstantImpl boxPrimitive(Object source); + + /** + * Gets the {@link ResolvedJavaMethod}s for all the constructors of the type {@code holder}. + */ + native ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl holder); + + /** + * Gets the {@link ResolvedJavaMethod}s for all the non-constructor methods of the type + * {@code holder}. + */ + native ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl holder); + + /** + * Reads the current value of a static field. If {@code expectedType} is non-null, then the + * object is expected to be a subtype of {@code expectedType} and extra sanity checking is + * performed on the offset and kind of the read being performed. + * + * @throws IllegalArgumentException if any of the sanity checks fail + */ + native JavaConstant readFieldValue(HotSpotResolvedObjectTypeImpl object, HotSpotResolvedObjectTypeImpl expectedType, long offset, JavaKind kind); + + /** + * Reads the current value of an instance field. If {@code expectedType} is non-null, then the + * object is expected to be a subtype of {@code expectedType} and extra sanity checking is + * performed on the offset and kind of the read being performed. + * + * @throws IllegalArgumentException if any of the sanity checks fail + */ + native JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedObjectTypeImpl expectedType, long offset, JavaKind kind); + + /** + * @see ResolvedJavaType#isInstance(JavaConstant) + */ + native boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl object); + + /** + * @see ResolvedJavaType#isAssignableFrom(ResolvedJavaType) + */ + native boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType); + + /** + * @see ConstantReflectionProvider#asJavaType(Constant) + */ + native HotSpotResolvedJavaType asJavaType(HotSpotObjectConstantImpl object); + + /** + * Converts a String constant into a String. + */ + native String asString(HotSpotObjectConstantImpl object); + + /** + * Compares the contents of {@code xHandle} and {@code yHandle} for pointer equality. + */ + native boolean equals(HotSpotObjectConstantImpl x, long xHandle, HotSpotObjectConstantImpl y, long yHandle); + + /** + * Gets a {@link JavaConstant} wrapping the {@link java.lang.Class} mirror for {@code type}. + */ + native HotSpotObjectConstantImpl getJavaMirror(HotSpotResolvedJavaType type); + + /** + * Returns the length of the array if {@code object} represents an array or -1 otherwise. + */ + native int getArrayLength(HotSpotObjectConstantImpl object); + + /** + * Reads the element at {@code index} if {@code object} is an array. Elements of an object array + * are returned as {@link JavaConstant}s and primitives are returned as boxed values. The value + * {@code null} is returned if the {@code index} is out of range or object is not an array. + */ + native Object readArrayElement(HotSpotObjectConstantImpl object, int index); + + /** + * @see HotSpotJVMCIRuntime#registerNativeMethods + */ + native long[] registerNativeMethods(Class clazz); + + /** + * @see HotSpotJVMCIRuntime#translate(Object) + */ + native long translate(Object obj, boolean callPostTranslation); + + /** + * @see HotSpotJVMCIRuntime#unhand(Class, long) + */ + native Object unhand(long handle); + + /** + * Updates {@code address} and {@code entryPoint} fields of {@code nmethodMirror} based on the + * current state of the {@code nmethod} identified by {@code address} and + * {@code nmethodMirror.compileId} in the code cache. + */ + native void updateHotSpotNmethod(HotSpotNmethod nmethodMirror); + + /** + * @see InstalledCode#getCode() + */ + native byte[] getCode(HotSpotInstalledCode code); + + /** + * Gets a {@link Executable} corresponding to {@code method}. + */ + native Executable asReflectionExecutable(HotSpotResolvedJavaMethodImpl method); + + /** + * Gets a {@link Field} denoted by {@code holder} and {@code index}. + * + * @param holder the class in which the requested field is declared + * @param fieldIndex the {@code fieldDescriptor::index()} denoting the field + */ + native Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, int fieldIndex); + + /** + * @see HotSpotJVMCIRuntime#getIntrinsificationTrustPredicate(Class...) + */ + native boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl type); + + /** + * Releases the resources backing the global JNI {@code handle}. This is equivalent to the + * {@code DeleteGlobalRef} JNI function. + */ + native void deleteGlobalHandle(long handle); + + /** + * Gets the failed speculations pointed to by {@code *failedSpeculationsAddress}. + * + * @param currentFailures the known failures at {@code failedSpeculationsAddress} + * @return the list of failed speculations with each entry being a single speculation in the + * format emitted by {@link HotSpotSpeculationEncoding#toByteArray()} + */ + native byte[][] getFailedSpeculations(long failedSpeculationsAddress, byte[][] currentFailures); + + /** + * Gets the address of the {@code MethodData::_failed_speculations} field in the + * {@code MethodData} associated with {@code method}. This will create and install the + * {@code MethodData} if it didn't already exist. + */ + native long getFailedSpeculationsAddress(HotSpotResolvedJavaMethodImpl method); + + /** + * Frees the failed speculations pointed to by {@code *failedSpeculationsAddress}. + */ + native void releaseFailedSpeculations(long failedSpeculationsAddress); + + /** + * Adds a speculation to the failed speculations pointed to by + * {@code *failedSpeculationsAddress}. + * + * @return {@code false} if the speculation could not be appended to the list + */ + native boolean addFailedSpeculation(long failedSpeculationsAddress, byte[] speculation); + + /** + * @see HotSpotJVMCIRuntime#isCurrentThreadAttached() + */ + native boolean isCurrentThreadAttached(); + + /** + * @see HotSpotJVMCIRuntime#getCurrentJavaThread() + */ + native long getCurrentJavaThread(); + + /** + * @param name name of current thread if in a native image otherwise {@code null} + * @see HotSpotJVMCIRuntime#attachCurrentThread + */ + native boolean attachCurrentThread(byte[] name, boolean asDaemon); + + /** + * @see HotSpotJVMCIRuntime#detachCurrentThread() + */ + native void detachCurrentThread(); + + /** + * @see HotSpotJVMCIRuntime#exitHotSpot(int) + */ + native void callSystemExit(int status); + + /** + * @see JFR.Ticks#now + */ + native long ticksNow(); + + /** + * @see HotSpotJVMCIRuntime#setThreadLocalObject(int, Object) + */ + native void setThreadLocalObject(int id, Object value); + + /** + * @see HotSpotJVMCIRuntime#getThreadLocalObject(int) + */ + native Object getThreadLocalObject(int id); + + /** + * @see HotSpotJVMCIRuntime#setThreadLocalLong(int, long) + */ + native void setThreadLocalLong(int id, long value); + + /** + * @see HotSpotJVMCIRuntime#getThreadLocalLong(int) + */ + native long getThreadLocalLong(int id); + + /** + * Adds phases in HotSpot JFR. + * + * @see JFR.CompilerPhaseEvent#write + */ + native int registerCompilerPhase(String phaseName); + + /** + * @see JFR.CompilerPhaseEvent#write + */ + native void notifyCompilerPhaseEvent(long startTime, int phase, int compileId, int level); + + /** + * @see JFR.CompilerInliningEvent#write + */ + native void notifyCompilerInliningEvent(int compileId, HotSpotResolvedJavaMethodImpl caller, HotSpotResolvedJavaMethodImpl callee, boolean succeeded, String message, int bci); + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaConstant; + +final class DirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl { + + static JavaConstant forObject(Object object, boolean compressed) { + if (object == null) { + return compressed ? HotSpotCompressedNullConstant.COMPRESSED_NULL : JavaConstant.NULL_POINTER; + } else { + return new DirectHotSpotObjectConstantImpl(object, compressed); + } + } + + static HotSpotObjectConstantImpl forNonNullObject(Object object, boolean compressed) { + if (object == null) { + throw new NullPointerException(); + } + return new DirectHotSpotObjectConstantImpl(object, compressed); + } + + private DirectHotSpotObjectConstantImpl(Object object, boolean compressed) { + super(compressed); + assert object != null; + this.object = object; + } + + final Object object; + + @Override + public JavaConstant compress() { + assert !compressed; + return new DirectHotSpotObjectConstantImpl(object, true); + } + + @Override + public JavaConstant uncompress() { + assert compressed; + return new DirectHotSpotObjectConstantImpl(object, false); + } + + @Override + public int getIdentityHashCode() { + return System.identityHashCode(object); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EmptyEventProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EmptyEventProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EmptyEventProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EmptyEventProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * An empty implementation for {@link EventProvider}. This implementation is used when no logging is + * requested. + */ +final class EmptyEventProvider implements EventProvider { + + static InternalError shouldNotReachHere() { + throw new InternalError("should not reach here"); + } + + @Override + public CompilationEvent newCompilationEvent() { + return new EmptyCompilationEvent(); + } + + static class EmptyCompilationEvent implements CompilationEvent { + @Override + public void commit() { + throw shouldNotReachHere(); + } + + @Override + public boolean shouldWrite() { + // Events of this class should never been written. + return false; + } + + @Override + public void begin() { + } + + @Override + public void end() { + } + + @Override + public void setMethod(String method) { + throw shouldNotReachHere(); + } + + @Override + public void setCompileId(int compileId) { + throw shouldNotReachHere(); + } + + @Override + public void setCompileLevel(int compileLevel) { + throw shouldNotReachHere(); + } + + @Override + public void setSucceeded(boolean succeeded) { + throw shouldNotReachHere(); + } + + @Override + public void setIsOsr(boolean isOsr) { + throw shouldNotReachHere(); + } + + @Override + public void setCodeSize(int codeSize) { + throw shouldNotReachHere(); + } + + @Override + public void setInlinedBytes(int inlinedBytes) { + throw shouldNotReachHere(); + } + } + + @Override + public CompilerFailureEvent newCompilerFailureEvent() { + return new EmptyCompilerFailureEvent(); + } + + static class EmptyCompilerFailureEvent implements CompilerFailureEvent { + @Override + public void commit() { + throw shouldNotReachHere(); + } + + @Override + public boolean shouldWrite() { + // Events of this class should never been written. + return false; + } + + @Override + public void setCompileId(int compileId) { + throw shouldNotReachHere(); + } + + @Override + public void setMessage(String message) { + throw shouldNotReachHere(); + } + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EventProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EventProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EventProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/EventProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilationEvent; +import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilerFailureEvent; + +/** + * Service-provider class for logging compiler related events. + */ +public interface EventProvider { + + /** + * Creates and returns an empty implementation for {@link EventProvider}. This implementation + * can be used when no logging is requested. + */ + static EventProvider createEmptyEventProvider() { + return new EmptyEventProvider(); + } + + /** + * Creates and returns an empty implementation for {@link CompilationEvent}. + */ + static CompilationEvent createEmptyCompilationEvent() { + return new EmptyCompilationEvent(); + } + + /** + * Creates and returns an empty implementation for {@link CompilationEvent}. + */ + static CompilerFailureEvent createEmptyCompilerFailureEvent() { + return new EmptyCompilerFailureEvent(); + } + + /** + * An instant event is an event that is not considered to have taken any time. + */ + public interface InstantEvent { + /** + * Commits the event. + */ + void commit(); + + /** + * Determines if this particular event instance would be committed to the data stream right + * now if application called {@link #commit()}. This in turn depends on whether the event is + * enabled and possible other factors. + * + * @return if this event would be committed on a call to {@link #commit()}. + */ + boolean shouldWrite(); + } + + /** + * Timed events describe an operation that somehow consumes time. + */ + public interface TimedEvent extends InstantEvent { + /** + * Starts the timing for this event. + */ + void begin(); + + /** + * Ends the timing period for this event. + */ + void end(); + } + + /** + * Creates a new {@link CompilationEvent}. + * + * @return a compilation event + */ + CompilationEvent newCompilationEvent(); + + /** + * A compilation event. + */ + public interface CompilationEvent extends TimedEvent { + void setMethod(String method); + + void setCompileId(int compileId); + + void setCompileLevel(int compileLevel); + + void setSucceeded(boolean succeeded); + + void setIsOsr(boolean isOsr); + + void setCodeSize(int codeSize); + + void setInlinedBytes(int inlinedBytes); + } + + /** + * Creates a new {@link CompilerFailureEvent}. + * + * @return a compiler failure event + */ + CompilerFailureEvent newCompilerFailureEvent(); + + /** + * A compiler failure event. + */ + public interface CompilerFailureEvent extends InstantEvent { + void setCompileId(int compileId); + + void setMessage(String message); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HandleCleaner.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HandleCleaner.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HandleCleaner.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HandleCleaner.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +/** + * This class manages a set of {@code jobject} and {@code jmetadata} handles whose lifetimes are + * dependent on associated {@link IndirectHotSpotObjectConstantImpl} and + * {@link MetaspaceHandleObject} wrapper objects respectively. + * + * The general theory of operation is that all wrappers are created by calling into the VM which + * calls back out to actually create the wrapper instance. During the call the VM keeps the object + * or metadata reference alive through the use of handles. Once the call completes the wrapper + * object is registered here and will be scanned during metadata scanning. The weakness of the + * reference to the wrapper object allows the handles to be reclaimed when they are no longer used. + */ +final class HandleCleaner extends Cleaner { + + /** + * A {@code jmetadata} or {@code jobject} handle. + */ + private final long handle; + + /** + * Specifies if {@link #handle} is a {@code jobject} or {@code jmetadata}. + */ + private final boolean isJObject; + + private HandleCleaner(Object wrapper, long handle, boolean isJObject) { + super(wrapper); + this.handle = handle; + this.isJObject = isJObject; + } + + /** + * Releases the resource associated with {@code this.handle}. + */ + @Override + void doCleanup() { + if (isJObject) { + // The sentinel value used to denote a free handle is + // an object on the HotSpot heap so we call into the + // VM to set the target of an object handle to this value. + CompilerToVM.compilerToVM().deleteGlobalHandle(handle); + } else { + // Setting the target of a jmetadata handle to 0 enables + // the handle to be reused. See MetadataHandles in + // metadataHandles.hpp for more info. + long value = UNSAFE.getLong(null, handle); + UNSAFE.compareAndSetLong(null, handle, value, 0); + } + } + + /** + * Registers a cleaner for {@code handle}. The cleaner will release the handle some time after + * {@code wrapper} is detected as unreachable by the garbage collector. + */ + @SuppressWarnings("unused") + static void create(Object wrapper, long handle) { + assert wrapper instanceof IndirectHotSpotObjectConstantImpl || wrapper instanceof MetaspaceHandleObject; + new HandleCleaner(wrapper, handle, wrapper instanceof IndirectHotSpotObjectConstantImpl); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.CallingConvention; +import jdk.vm.ci.code.CallingConvention.Type; + +public enum HotSpotCallingConventionType implements CallingConvention.Type { + /** + * A request for the outgoing argument locations at a call site to Java code. + */ + JavaCall(true), + + /** + * A request for the incoming argument locations. + */ + JavaCallee(false), + + /** + * A request for the outgoing argument locations at a call site to external native code that + * complies with the platform ABI. + */ + NativeCall(true); + + /** + * Determines if this is a request for the outgoing argument locations at a call site. + */ + public final boolean out; + + public static final Type[] VALUES = values(); + + HotSpotCallingConventionType(boolean out) { + this.out = out; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2013, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.Map; +import java.util.Objects; + +import jdk.vm.ci.code.BailoutException; +import jdk.vm.ci.code.BytecodeFrame; +import jdk.vm.ci.code.CodeCacheProvider; +import jdk.vm.ci.code.CompiledCode; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.RegisterConfig; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.site.Call; +import jdk.vm.ci.code.site.Mark; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.SpeculationLog; + +/** + * HotSpot implementation of {@link CodeCacheProvider}. + */ +public class HotSpotCodeCacheProvider implements CodeCacheProvider { + + protected final HotSpotJVMCIRuntime runtime; + private final HotSpotVMConfig config; + protected final TargetDescription target; + protected final RegisterConfig regConfig; + + public HotSpotCodeCacheProvider(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { + this.runtime = runtime; + this.config = runtime.getConfig(); + this.target = target; + this.regConfig = regConfig; + } + + @Override + public String getMarkName(Mark mark) { + int markId = (int) mark.id; + HotSpotVMConfigStore store = runtime.getConfigStore(); + for (Map.Entry e : store.getConstants().entrySet()) { + String name = e.getKey(); + if (name.startsWith("MARKID_") && e.getValue() == markId) { + return name; + } + } + return CodeCacheProvider.super.getMarkName(mark); + } + + /** + * Decodes a call target to a mnemonic if possible. + */ + @Override + public String getTargetName(Call call) { + if (call.target instanceof HotSpotForeignCallTarget) { + long address = ((HotSpotForeignCallTarget) call.target).address; + HotSpotVMConfigStore store = runtime.getConfigStore(); + for (Map.Entry e : store.getFields().entrySet()) { + VMField field = e.getValue(); + if (field.isStatic() && field.value != null && field.value instanceof Long && ((Long) field.value) == address) { + return e.getValue() + ":0x" + Long.toHexString(address); + } + } + } + return CodeCacheProvider.super.getTargetName(call); + } + + @Override + public RegisterConfig getRegisterConfig() { + return regConfig; + } + + @Override + public int getMinimumOutgoingSize() { + return config.runtimeCallStackSize; + } + + private InstalledCode logOrDump(InstalledCode installedCode, CompiledCode compiledCode) { + runtime.notifyInstall(this, installedCode, compiledCode); + return installedCode; + } + + @Override + public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault) { + InstalledCode resultInstalledCode; + if (installedCode != null) { + throw new IllegalArgumentException("InstalledCode argument must be null"); + } + HotSpotCompiledCode hsCompiledCode = (HotSpotCompiledCode) compiledCode; + String name = hsCompiledCode.getName(); + HotSpotCompiledNmethod hsCompiledNmethod = null; + HotSpotSpeculationLog speculationLog = null; + if (log != null) { + if (log.hasSpeculations()) { + speculationLog = (HotSpotSpeculationLog) log; + } + } + byte[] speculations; + long failedSpeculationsAddress; + if (speculationLog != null) { + speculations = speculationLog.getFlattenedSpeculations(true); + failedSpeculationsAddress = speculationLog.getFailedSpeculationsAddress(); + } else { + speculations = new byte[0]; + failedSpeculationsAddress = 0L; + } + + if (method == null) { + // Must be a stub + resultInstalledCode = new HotSpotRuntimeStub(name); + } else { + hsCompiledNmethod = (HotSpotCompiledNmethod) hsCompiledCode; + HotSpotResolvedJavaMethodImpl hsMethod = (HotSpotResolvedJavaMethodImpl) method; + HotSpotNmethod nmethod = new HotSpotNmethod(hsMethod, name, isDefault, hsCompiledNmethod.id); + nmethod.setSpeculationLog(speculationLog); + resultInstalledCode = nmethod; + } + + int result = runtime.getCompilerToVM().installCode(target, (HotSpotCompiledCode) compiledCode, resultInstalledCode, failedSpeculationsAddress, speculations); + if (result != config.codeInstallResultOk) { + String resultDesc = config.getCodeInstallResultDescription(result); + if (hsCompiledNmethod != null) { + String msg = hsCompiledNmethod.getInstallationFailureMessage(); + if (msg != null) { + msg = String.format("Code installation failed: %s%n%s", resultDesc, msg); + } else { + msg = String.format("Code installation failed: %s", resultDesc); + } + throw new BailoutException(result >= config.codeInstallResultFirstPermanentBailout, msg); + } else { + throw new BailoutException("Error installing %s: %s", ((HotSpotCompiledCode) compiledCode).getName(), resultDesc); + } + } + return logOrDump(resultInstalledCode, compiledCode); + } + + @Override + public void invalidateInstalledCode(InstalledCode installedCode) { + if (installedCode instanceof HotSpotNmethod) { + runtime.getCompilerToVM().invalidateHotSpotNmethod((HotSpotNmethod) installedCode); + } else { + throw new IllegalArgumentException("Cannot invalidate a " + Objects.requireNonNull(installedCode).getClass().getName()); + } + } + + @Override + public TargetDescription getTarget() { + return target; + } + + public String disassemble(InstalledCode code) { + if (code.isValid()) { + return runtime.getCompilerToVM().disassembleCodeBlob(code); + } + return null; + } + + @Override + public SpeculationLog createSpeculationLog() { + return new HotSpotSpeculationLog(); + } + + @Override + public long getMaxCallTargetOffset(long address) { + return runtime.getCompilerToVM().getMaxCallTargetOffset(address); + } + + @Override + public boolean shouldDebugNonSafepoints() { + return runtime.getCompilerToVM().shouldDebugNonSafepoints(); + } + + public int interpreterFrameSize(BytecodeFrame pos) { + return runtime.getCompilerToVM().interpreterFrameSize(pos); + } + + /** + * Resets all compilation statistics. + */ + public void resetCompilationStatistics() { + runtime.getCompilerToVM().resetCompilationStatistics(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.CompilationRequest; + +/** + * A compilation request with extra HotSpot specific context such as a compilation identifier and + * the address of a {@code JVMCIEnv} object that provides native context for a compilation. + */ +public class HotSpotCompilationRequest extends CompilationRequest { + /** + * Address of the native {@code JVMCICompileState} associated with the request. + */ + private final long compileState; + + /** + * An identifier for the request. + */ + private final int id; + + /** + * Creates a request to compile a method starting at a given BCI and allocates an identifier to + * the request. + * + * @param method the method to be compiled + * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the + * method's entry point + * @param compileState address of a native {@code JVMCICompileState} object or 0L + */ + public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long compileState) { + this(method, entryBCI, compileState, method.allocateCompileId(entryBCI)); + } + + /** + * Creates a request to compile a method starting at a given BCI. + * + * @param method the method to be compiled + * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the + * method's entry point + * @param compileState address of a native {@code JVMCICompileState} object or 0L + * @param id an identifier for the request + */ + public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long compileState, int id) { + super(method, entryBCI); + this.compileState = compileState; + this.id = id; + } + + @Override + public HotSpotResolvedJavaMethod getMethod() { + return (HotSpotResolvedJavaMethod) super.getMethod(); + } + + /** + * Gets the address of the native {@code JVMCICompileState} or 0L if no such object exists. This + * method should really be named {@code getCompileState} but must remain as is for API + * stability. + */ + public long getJvmciEnv() { + return compileState; + } + + /** + * Gets the VM allocated identifier for this compilation. + */ + public int getId() { + return id; + } + + @Override + public String toString() { + return id + ":" + super.toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * 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. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.CompilationRequest; +import jdk.vm.ci.code.CompilationRequestResult; + +/** + * HotSpot specific information about the result of a {@link CompilationRequest}. + */ +public final class HotSpotCompilationRequestResult implements CompilationRequestResult { + + /** + * A user readable description of the failure. + * + * This field is read by the VM. + */ + private final String failureMessage; + + /** + * Whether this is a transient failure where retrying would help. + * + * This field is read by the VM. + */ + private final boolean retry; + + /** + * Number of bytecodes inlined into the compilation, exclusive of the bytecodes in the root + * method. + * + * This field is read by the VM. + */ + private final int inlinedBytecodes; + + private HotSpotCompilationRequestResult(String failureMessage, boolean retry, int inlinedBytecodes) { + this.failureMessage = failureMessage; + this.retry = retry; + this.inlinedBytecodes = inlinedBytecodes; + } + + @Override + public Object getFailure() { + return failureMessage; + } + + /** + * Creates a result representing a successful compilation. + * + * @param inlinedBytecodes number of bytecodes inlined into the compilation, exclusive of the + * bytecodes in the root method + */ + public static HotSpotCompilationRequestResult success(int inlinedBytecodes) { + return new HotSpotCompilationRequestResult(null, true, inlinedBytecodes); + } + + /** + * Creates a result representing a failed compilation. + * + * @param failureMessage a description of the failure + * @param retry whether this is a transient failure where retrying may succeed + */ + public static HotSpotCompilationRequestResult failure(String failureMessage, boolean retry) { + return new HotSpotCompilationRequestResult(failureMessage, retry, 0); + } + + public String getFailureMessage() { + return failureMessage; + } + + public boolean getRetry() { + return retry; + } + + public int getInlinedBytecodes() { + return inlinedBytecodes; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.BytecodeFrame; +import jdk.vm.ci.code.CompiledCode; +import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.code.VirtualObject; +import jdk.vm.ci.code.site.DataPatch; +import jdk.vm.ci.code.site.Infopoint; +import jdk.vm.ci.code.site.Site; +import jdk.vm.ci.meta.Assumptions.Assumption; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * A {@link CompiledCode} with additional HotSpot-specific information required for installing the + * code in HotSpot's code cache. + */ +public class HotSpotCompiledCode implements CompiledCode { + + /** + * The name of this compilation unit. + */ + protected final String name; + + /** + * The buffer containing the emitted machine code. + */ + protected final byte[] targetCode; + + /** + * The leading number of bytes in {@link #targetCode} containing the emitted machine code. + */ + protected final int targetCodeSize; + + /** + * A list of code annotations describing special sites in {@link #targetCode}. + */ + protected final Site[] sites; + + /** + * A list of {@link Assumption} this code relies on. + */ + protected final Assumption[] assumptions; + + /** + * The list of the methods whose bytecodes were used as input to the compilation. If + * {@code null}, then the compilation did not record method dependencies. Otherwise, the first + * element of this array is the root method of the compilation. + */ + protected final ResolvedJavaMethod[] methods; + + /** + * A list of comments that will be included in code dumps. + */ + protected final Comment[] comments; + + /** + * The data section containing serialized constants for the emitted machine code. + */ + protected final byte[] dataSection; + + /** + * The minimum alignment of the data section. + */ + protected final int dataSectionAlignment; + + /** + * A list of relocations in the {@link #dataSection}. + */ + protected final DataPatch[] dataSectionPatches; + + /** + * A flag determining whether this code is immutable and position independent. + */ + protected final boolean isImmutablePIC; + + /** + * The total size of the stack frame of this compiled method. + */ + protected final int totalFrameSize; + + /** + * The deopt rescue slot. Must be non-null if there is a safepoint in the method. + */ + protected final StackSlot deoptRescueSlot; + + public static class Comment { + + public final String text; + public final int pcOffset; + + public Comment(int pcOffset, String text) { + this.text = text; + this.pcOffset = pcOffset; + } + } + + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `sites`, `targetCode`, `comments`, `methods`, `dataSection`, `dataSectionPatches` and `assumptions`") + public HotSpotCompiledCode(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection, + int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot) { + this.name = name; + this.targetCode = targetCode; + this.targetCodeSize = targetCodeSize; + this.sites = sites; + this.assumptions = assumptions; + this.methods = methods; + + this.comments = comments; + this.dataSection = dataSection; + this.dataSectionAlignment = dataSectionAlignment; + this.dataSectionPatches = dataSectionPatches; + this.isImmutablePIC = isImmutablePIC; + this.totalFrameSize = totalFrameSize; + this.deoptRescueSlot = deoptRescueSlot; + + assert validateFrames(); + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + + /** + * Ensure that all the frames passed into the VM are properly formatted with an empty or illegal + * slot following double word slots. + */ + private boolean validateFrames() { + for (Site site : sites) { + if (site instanceof Infopoint) { + Infopoint info = (Infopoint) site; + if (info.debugInfo != null) { + BytecodeFrame frame = info.debugInfo.frame(); + assert frame == null || frame.validateFormat(); + if (info.debugInfo.getVirtualObjectMapping() != null) { + for (VirtualObject v : info.debugInfo.getVirtualObjectMapping()) { + verifyVirtualObject(v); + } + } + } + } + } + return true; + } + + public static void verifyVirtualObject(VirtualObject v) { + v.verifyLayout(new VirtualObject.LayoutVerifier() { + @Override + public int getOffset(ResolvedJavaField field) { + return field.getOffset(); + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.code.site.DataPatch; +import jdk.vm.ci.code.site.Site; +import jdk.vm.ci.meta.Assumptions.Assumption; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * {@link HotSpotCompiledCode} destined for installation as an nmethod. + */ +public final class HotSpotCompiledNmethod extends HotSpotCompiledCode { + + protected final HotSpotResolvedJavaMethod method; + protected final int entryBCI; + + /** + * Compilation identifier. + */ + protected final int id; + + /** + * Address of a native {@code JVMCICompileState} object or 0L if no such object exists. + */ + protected final long compileState; + + protected final boolean hasUnsafeAccess; + + /** + * May be set by VM if code installation fails. It will describe in more detail why installation + * failed (e.g., exactly which dependency failed). + */ + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage; + + public HotSpotCompiledNmethod(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection, + int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot, HotSpotResolvedJavaMethod method, int entryBCI, + int id, long compileState, boolean hasUnsafeAccess) { + super(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC, totalFrameSize, deoptRescueSlot); + this.method = method; + this.entryBCI = entryBCI; + this.id = id; + this.compileState = compileState; + this.hasUnsafeAccess = hasUnsafeAccess; + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + id + ":" + method.format("%H.%n(%p)%r@") + entryBCI + "]"; + } + + public String getInstallationFailureMessage() { + return installationFailureMessage; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2014, 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. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; + +/** + * The compressed representation of the {@link JavaConstant#NULL_POINTER null constant}. + */ +public final class HotSpotCompressedNullConstant implements JavaConstant, HotSpotConstant { + + public static final JavaConstant COMPRESSED_NULL = new HotSpotCompressedNullConstant(); + + private HotSpotCompressedNullConstant() { + } + + @Override + public JavaKind getJavaKind() { + return JavaKind.Object; + } + + @Override + public boolean isNull() { + return true; + } + + @Override + public boolean isCompressed() { + return true; + } + + @Override + public Constant compress() { + throw new IllegalArgumentException(); + } + + @Override + public Constant uncompress() { + return NULL_POINTER; + } + + @Override + public boolean isDefaultForKind() { + return true; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public String toString() { + return JavaConstant.toString(this); + } + + @Override + public String toValueString() { + return "null"; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + + @Override + public boolean equals(Object o) { + return o instanceof HotSpotCompressedNullConstant; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, 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. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.Constant; + +/** + * Marker interface for hotspot specific constants. + */ +public interface HotSpotConstant extends Constant { + + boolean isCompressed(); + + Constant compress(); + + Constant uncompress(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,897 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.meta.ConstantPool; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaField; +import jdk.vm.ci.meta.JavaMethod; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.Signature; +import jdk.vm.ci.meta.UnresolvedJavaField; +import jdk.vm.ci.meta.UnresolvedJavaMethod; +import jdk.vm.ci.meta.UnresolvedJavaType; + +/** + * Implementation of {@link ConstantPool} for HotSpot. + */ +public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleObject { + + /** + * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}. + */ + public static class Bytecodes { + public static final int LDC = 18; // 0x12 + public static final int LDC_W = 19; // 0x13 + public static final int LDC2_W = 20; // 0x14 + public static final int GETSTATIC = 178; // 0xB2 + public static final int PUTSTATIC = 179; // 0xB3 + public static final int GETFIELD = 180; // 0xB4 + public static final int PUTFIELD = 181; // 0xB5 + public static final int INVOKEVIRTUAL = 182; // 0xB6 + public static final int INVOKESPECIAL = 183; // 0xB7 + public static final int INVOKESTATIC = 184; // 0xB8 + public static final int INVOKEINTERFACE = 185; // 0xB9 + public static final int INVOKEDYNAMIC = 186; // 0xBA + public static final int NEW = 187; // 0xBB + public static final int NEWARRAY = 188; // 0xBC + public static final int ANEWARRAY = 189; // 0xBD + public static final int CHECKCAST = 192; // 0xC0 + public static final int INSTANCEOF = 193; // 0xC1 + public static final int MULTIANEWARRAY = 197; // 0xC5 + + static boolean isInvoke(int opcode) { + switch (opcode) { + case INVOKEVIRTUAL: + case INVOKESPECIAL: + case INVOKESTATIC: + case INVOKEINTERFACE: + case INVOKEDYNAMIC: + return true; + default: + return false; + } + } + + /** + * See: {@code Rewriter::maybe_rewrite_invokehandle}. + */ + static boolean isInvokeHandleAlias(int opcode) { + switch (opcode) { + case INVOKEVIRTUAL: + case INVOKESPECIAL: + return true; + default: + return false; + } + } + } + + static final class JvmConstant { + private final int tag; + private final String name; + + JvmConstant(int tag, String name) { + this.tag = tag; + this.name = name; + } + + @Override + public String toString() { + return name; + } + } + + /** + * {@code JVM_CONSTANT} constants used in the VM including both public and internal ones. + */ + static final class JvmConstants { + + private final HotSpotVMConfig c = config(); + private final int externalMax = c.jvmConstantExternalMax; + private final int internalMax = c.jvmConstantInternalMax; + private final int internalMin = c.jvmConstantInternalMin; + private final JvmConstant[] table = new JvmConstant[externalMax + 1 + (internalMax - internalMin) + 1]; + + final JvmConstant jvmUtf8 = add(new JvmConstant(c.jvmConstantUtf8, "Utf8")); + final JvmConstant jvmInteger = add(new JvmConstant(c.jvmConstantInteger, "Integer")); + final JvmConstant jvmLong = add(new JvmConstant(c.jvmConstantLong, "Long")); + final JvmConstant jvmFloat = add(new JvmConstant(c.jvmConstantFloat, "Float")); + final JvmConstant jvmDouble = add(new JvmConstant(c.jvmConstantDouble, "Double")); + final JvmConstant jvmClass = add(new JvmConstant(c.jvmConstantClass, "Class")); + final JvmConstant jvmUnresolvedClass = add(new JvmConstant(c.jvmConstantUnresolvedClass, "UnresolvedClass")); + final JvmConstant jvmUnresolvedClassInError = add(new JvmConstant(c.jvmConstantUnresolvedClassInError, "UnresolvedClassInError")); + final JvmConstant jvmString = add(new JvmConstant(c.jvmConstantString, "String")); + final JvmConstant jvmFieldref = add(new JvmConstant(c.jvmConstantFieldref, "Fieldref")); + final JvmConstant jvmMethodref = add(new JvmConstant(c.jvmConstantMethodref, "Methodref")); + final JvmConstant jvmInterfaceMethodref = add(new JvmConstant(c.jvmConstantInterfaceMethodref, "InterfaceMethodref")); + final JvmConstant jvmNameAndType = add(new JvmConstant(c.jvmConstantNameAndType, "NameAndType")); + final JvmConstant jvmMethodHandle = add(new JvmConstant(c.jvmConstantMethodHandle, "MethodHandle")); + final JvmConstant jvmMethodHandleInError = add(new JvmConstant(c.jvmConstantMethodHandleInError, "MethodHandleInError")); + final JvmConstant jvmMethodType = add(new JvmConstant(c.jvmConstantMethodType, "MethodType")); + final JvmConstant jvmMethodTypeInError = add(new JvmConstant(c.jvmConstantMethodTypeInError, "MethodTypeInError")); + final JvmConstant jvmInvokeDynamic = add(new JvmConstant(c.jvmConstantInvokeDynamic, "InvokeDynamic")); + final JvmConstant jvmDynamic = add(new JvmConstant(c.jvmConstantDynamic, "Dynamic")); + final JvmConstant jvmDynamicInError = add(new JvmConstant(c.jvmConstantDynamicInError, "DynamicInError")); + + private JvmConstant add(JvmConstant constant) { + table[indexOf(constant.tag)] = constant; + return constant; + } + + private int indexOf(int tag) { + if (tag >= internalMin) { + return tag - internalMin + externalMax + 1; + } else { + assert tag <= externalMax; + } + return tag; + } + + JvmConstant get(int tag) { + JvmConstant res = table[indexOf(tag)]; + if (res != null) { + return res; + } + throw new JVMCIError("Unknown JvmConstant tag %s", tag); + } + + @NativeImageReinitialize private static volatile JvmConstants instance; + + static JvmConstants instance() { + JvmConstants result = instance; + if (result == null) { + synchronized (JvmConstants.class) { + result = instance; + if (result == null) { + instance = result = new JvmConstants(); + } + } + } + return result; + } + } + + private static class LookupTypeCacheElement { + int lastCpi = Integer.MIN_VALUE; + JavaType javaType; + + LookupTypeCacheElement(int lastCpi, JavaType javaType) { + super(); + this.lastCpi = lastCpi; + this.javaType = javaType; + } + } + + /** + * Handle to the {@code ConstantPool} VM object. The handle is in + * {@code JVMCI::_metadata_handles}. + */ + private final long metadataHandle; + + private volatile LookupTypeCacheElement lastLookupType; + private final JvmConstants constants; + + /** + * Gets the JVMCI mirror from a HotSpot constant pool.The VM is responsible for ensuring that + * the ConstantPool is kept alive for the duration of this call and the + * {@link HotSpotJVMCIRuntime} keeps it alive after that. + * + * Called from the VM. + * + * @param metaspaceConstantPool a metaspace ConstantPool object + * @return the {@link HotSpotConstantPool} corresponding to {@code metaspaceConstantPool} + */ + @SuppressWarnings("unused") + @VMEntryPoint + private static HotSpotConstantPool fromMetaspace(long metaspaceConstantPool) { + return new HotSpotConstantPool(metaspaceConstantPool); + } + + private HotSpotConstantPool(long metadataHandle) { + this.metadataHandle = metadataHandle; + this.constants = JvmConstants.instance(); + HandleCleaner.create(this, metadataHandle); + } + + /** + * Gets the holder for this constant pool as {@link HotSpotResolvedObjectTypeImpl}. + * + * @return holder for this constant pool + */ + private HotSpotResolvedObjectType getHolder() { + return compilerToVM().getResolvedJavaType(this, config().constantPoolHolderOffset, false); + } + + /** + * Converts a raw index from the bytecodes to a constant pool cache index by adding a + * {@link HotSpotVMConfig#constantPoolCpCacheIndexTag constant}. + * + * @param rawIndex index from the bytecode + * @param opcode bytecode to convert the index for + * @return constant pool cache index + */ + private static int rawIndexToConstantPoolCacheIndex(int rawIndex, int opcode) { + int index; + if (opcode == Bytecodes.INVOKEDYNAMIC) { + index = rawIndex; + // See: ConstantPool::is_invokedynamic_index + if (index >= 0) { + throw new IllegalArgumentException("not an invokedynamic constant pool index " + index); + } + } else { + if (opcode == Bytecodes.GETFIELD || + opcode == Bytecodes.PUTFIELD || + opcode == Bytecodes.GETSTATIC || + opcode == Bytecodes.PUTSTATIC || + opcode == Bytecodes.INVOKEINTERFACE || + opcode == Bytecodes.INVOKEVIRTUAL || + opcode == Bytecodes.INVOKESPECIAL || + opcode == Bytecodes.INVOKESTATIC) { + index = rawIndex + config().constantPoolCpCacheIndexTag; + } else { + throw new IllegalArgumentException("unexpected opcode " + opcode); + + } + } + return index; + } + + /** + * Decode a constant pool cache index to a constant pool index. + * + * See {@code ConstantPool::decode_cpcache_index}. + * + * @param index constant pool cache index + * @return decoded index + */ + private static int decodeConstantPoolCacheIndex(int index) { + if (isInvokedynamicIndex(index)) { + return decodeInvokedynamicIndex(index); + } else { + return index - config().constantPoolCpCacheIndexTag; + } + } + + /** + * See {@code ConstantPool::is_invokedynamic_index}. + */ + private static boolean isInvokedynamicIndex(int index) { + return index < 0; + } + + /** + * See {@code ConstantPool::decode_invokedynamic_index}. + */ + private static int decodeInvokedynamicIndex(int i) { + if (!isInvokedynamicIndex(i)) { + throw new IllegalArgumentException("not an invokedynamic index: " + i); + } + return ~i; + } + + long getMetaspaceConstantPool() { + return getMetaspacePointer(); + } + + @Override + public long getMetadataHandle() { + return metadataHandle; + } + + /** + * Gets the constant pool tag at index {@code index}. + * + * @param index constant pool index + * @return constant pool tag + */ + private JvmConstant getTagAt(int index) { + checkBounds(index); + HotSpotVMConfig config = config(); + final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset); + final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index); + if (tag == 0) { + return null; + } + return constants.get(tag); + } + + /** + * Gets the constant pool entry at index {@code index}. + * + * @param index constant pool index + * @return constant pool entry + */ + long getEntryAt(int index) { + checkBounds(index); + int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; + return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + offset); + } + + /** + * Gets the integer constant pool entry at index {@code index}. + * + * @param index constant pool index + * @return integer constant pool entry at index + */ + private int getIntAt(int index) { + checkTag(index, constants.jvmInteger); + int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; + return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); + } + + /** + * Gets the long constant pool entry at index {@code index}. + * + * @param index constant pool index + * @return long constant pool entry + */ + private long getLongAt(int index) { + checkTag(index, constants.jvmLong); + int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; + return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + offset); + } + + /** + * Gets the float constant pool entry at index {@code index}. + * + * @param index constant pool index + * @return float constant pool entry + */ + private float getFloatAt(int index) { + checkTag(index, constants.jvmFloat); + int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; + return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + offset); + } + + /** + * Gets the double constant pool entry at index {@code index}. + * + * @param index constant pool index + * @return float constant pool entry + */ + private double getDoubleAt(int index) { + checkTag(index, constants.jvmDouble); + int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; + return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + offset); + } + + /** + * Gets the {@code JVM_CONSTANT_NameAndType} constant pool entry at index {@code index}. + * + * @param index constant pool index + * @return {@code JVM_CONSTANT_NameAndType} constant pool entry + */ + private int getNameAndTypeAt(int index) { + checkTag(index, constants.jvmNameAndType); + int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; + return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); + } + + /** + * Gets the {@code JVM_CONSTANT_NameAndType} reference index constant pool entry at index + * {@code index}. + * + * @param index constant pool index + * @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry + */ + private int getNameAndTypeRefIndexAt(int index) { + return compilerToVM().lookupNameAndTypeRefIndexInPool(this, index); + } + + /** + * Gets the name of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by another + * entry denoted by {@code which}. + * + * @param which constant pool index or constant pool cache index + * @return name as {@link String} + */ + private String getNameOf(int which) { + return compilerToVM().lookupNameInPool(this, which); + } + + /** + * Gets the name reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry at + * index {@code index}. + * + * @param index constant pool index + * @return name reference index + */ + private int getNameRefIndexAt(int index) { + final int refIndex = getNameAndTypeAt(index); + // name ref index is in the low 16-bits. + return refIndex & 0xFFFF; + } + + /** + * Gets the signature of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by + * another entry denoted by {@code which}. + * + * @param which constant pool index or constant pool cache index + * @return signature as {@link String} + */ + private String getSignatureOf(int which) { + return compilerToVM().lookupSignatureInPool(this, which); + } + + /** + * Gets the signature reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry + * at index {@code index}. + * + * @param index constant pool index + * @return signature reference index + */ + private int getSignatureRefIndexAt(int index) { + final int refIndex = getNameAndTypeAt(index); + // signature ref index is in the high 16-bits. + return refIndex >>> 16; + } + + /** + * Gets the klass reference index constant pool entry at index {@code index}. + * + * @param index constant pool index + * @return klass reference index + */ + private int getKlassRefIndexAt(int index) { + return compilerToVM().lookupKlassRefIndexInPool(this, index); + } + + /** + * Gets the uncached klass reference index constant pool entry at index {@code index}. See: + * {@code ConstantPool::uncached_klass_ref_index_at}. + * + * @param index constant pool index + * @return klass reference index + */ + private int getUncachedKlassRefIndexAt(int index) { + checkTagIsFieldOrMethod(index); + int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; + final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); + // klass ref index is in the low 16-bits. + return refIndex & 0xFFFF; + } + + /** + * Checks that the constant pool index {@code index} is in the bounds of the constant pool. + * + * @param index constant pool index + * @throws IndexOutOfBoundsException if the check fails + */ + private void checkBounds(int index) { + if (index < 1 || index >= length()) { + throw new IndexOutOfBoundsException("index " + index + " not between 1 and " + length()); + } + } + + /** + * Checks that the constant pool tag at index {@code index} is equal to {@code tag}. + * + * @param index constant pool index + * @param tag expected tag + * @throws IllegalArgumentException if the check fails + */ + private void checkTag(int index, JvmConstant tag) { + final JvmConstant tagAt = getTagAt(index); + if (tagAt != tag) { + throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt + " but expected " + tag); + } + } + + /** + * Asserts that the constant pool tag at index {@code index} is a + * {@link JvmConstants#jvmFieldref}, or a {@link JvmConstants#jvmMethodref}, or a + * {@link JvmConstants#jvmInterfaceMethodref}. + * + * @param index constant pool index + * @throws IllegalArgumentException if the check fails + */ + private void checkTagIsFieldOrMethod(int index) { + final JvmConstant tagAt = getTagAt(index); + if (tagAt != constants.jvmFieldref && tagAt != constants.jvmMethodref && tagAt != constants.jvmInterfaceMethodref) { + throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt); + } + } + + @Override + public int length() { + return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolLengthOffset); + } + + public boolean hasDynamicConstant() { + return (flags() & config().constantPoolHasDynamicConstant) != 0; + } + + private int flags() { + return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolFlagsOffset); + } + + /** + * Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of a field. + */ + JavaConstant getStaticFieldConstantValue(int cpi) { + final JvmConstant tag = getTagAt(cpi); + switch (tag.name) { + case "Integer": + return JavaConstant.forInt(getIntAt(cpi)); + case "Long": + return JavaConstant.forLong(getLongAt(cpi)); + case "Float": + return JavaConstant.forFloat(getFloatAt(cpi)); + case "Double": + return JavaConstant.forDouble(getDoubleAt(cpi)); + case "String": + return compilerToVM().getUncachedStringInPool(this, cpi); + default: + throw new IllegalArgumentException("Illegal entry for a ConstantValue attribute:" + tag); + } + } + + @Override + public Object lookupConstant(int cpi) { + final JvmConstant tag = getTagAt(cpi); + switch (tag.name) { + case "Integer": + return JavaConstant.forInt(getIntAt(cpi)); + case "Long": + return JavaConstant.forLong(getLongAt(cpi)); + case "Float": + return JavaConstant.forFloat(getFloatAt(cpi)); + case "Double": + return JavaConstant.forDouble(getDoubleAt(cpi)); + case "Class": + case "UnresolvedClass": + case "UnresolvedClassInError": + final int opcode = -1; // opcode is not used + return lookupType(cpi, opcode); + case "String": + /* + * Normally, we would expect a String here, but unsafe anonymous classes can have + * "pseudo strings" (arbitrary live objects) patched into a String entry. Such + * entries do not have a symbol in the constant pool slot. + */ + return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi); + case "MethodHandle": + case "MethodHandleInError": + case "MethodType": + case "MethodTypeInError": + case "Dynamic": + case "DynamicInError": + return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi); + default: + throw new JVMCIError("Unknown constant pool tag %s", tag); + } + } + + @Override + public String lookupUtf8(int cpi) { + checkTag(cpi, constants.jvmUtf8); + return compilerToVM().getSymbol(getEntryAt(cpi)); + } + + @Override + public Signature lookupSignature(int cpi) { + return new HotSpotSignature(runtime(), lookupUtf8(cpi)); + } + + @Override + public JavaConstant lookupAppendix(int cpi, int opcode) { + if (!Bytecodes.isInvoke(opcode)) { + throw new IllegalArgumentException("expected an invoke bytecode at " + cpi + ", got " + opcode); + } + + final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); + return compilerToVM().lookupAppendixInPool(this, index); + } + + /** + * Gets a {@link JavaType} corresponding a given resolved or unresolved type. + * + * @param type either a ResolvedJavaType or a String naming a unresolved type. + */ + private static JavaType getJavaType(final Object type) { + if (type instanceof String) { + String name = (String) type; + return UnresolvedJavaType.create("L" + name + ";"); + } else { + return (JavaType) type; + } + } + + @Override + public JavaMethod lookupMethod(int cpi, int opcode) { + final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); + final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, index, (byte) opcode); + if (method != null) { + return method; + } else { + // Get the method's name and signature. + String name = getNameOf(index); + HotSpotSignature signature = new HotSpotSignature(runtime(), getSignatureOf(index)); + if (opcode == Bytecodes.INVOKEDYNAMIC) { + HotSpotResolvedObjectType holder = runtime().getMethodHandleClass(); + return new UnresolvedJavaMethod(name, signature, holder); + } else { + final int klassIndex = getKlassRefIndexAt(index); + final Object type = compilerToVM().lookupKlassInPool(this, klassIndex); + JavaType holder = getJavaType(type); + return new UnresolvedJavaMethod(name, signature, holder); + } + } + } + + @Override + public JavaType lookupType(int cpi, int opcode) { + final LookupTypeCacheElement elem = this.lastLookupType; + if (elem != null && elem.lastCpi == cpi) { + return elem.javaType; + } else { + final Object type = compilerToVM().lookupKlassInPool(this, cpi); + JavaType result = getJavaType(type); + if (result instanceof ResolvedJavaType) { + this.lastLookupType = new LookupTypeCacheElement(cpi, result); + } + return result; + } + } + + @Override + public JavaType lookupReferencedType(int cpi, int opcode) { + int index; + switch (opcode) { + case Bytecodes.CHECKCAST: + case Bytecodes.INSTANCEOF: + case Bytecodes.NEW: + case Bytecodes.ANEWARRAY: + case Bytecodes.MULTIANEWARRAY: + case Bytecodes.LDC: + case Bytecodes.LDC_W: + case Bytecodes.LDC2_W: + index = cpi; + break; + case Bytecodes.GETSTATIC: + case Bytecodes.PUTSTATIC: + case Bytecodes.GETFIELD: + case Bytecodes.PUTFIELD: + case Bytecodes.INVOKEVIRTUAL: + case Bytecodes.INVOKESPECIAL: + case Bytecodes.INVOKESTATIC: + case Bytecodes.INVOKEINTERFACE: { + index = rawIndexToConstantPoolCacheIndex(cpi, opcode); + index = getKlassRefIndexAt(index); + break; + } + default: + throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode); + } + final Object type = compilerToVM().lookupKlassInPool(this, index); + return getJavaType(type); + } + + @Override + public JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode) { + final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); + final int nameAndTypeIndex = getNameAndTypeRefIndexAt(index); + final int typeIndex = getSignatureRefIndexAt(nameAndTypeIndex); + String typeName = lookupUtf8(typeIndex); + JavaType type = runtime().lookupType(typeName, getHolder(), false); + + final int holderIndex = getKlassRefIndexAt(index); + JavaType holder = lookupType(holderIndex, opcode); + + if (holder instanceof HotSpotResolvedObjectTypeImpl) { + int[] info = new int[3]; + HotSpotResolvedObjectTypeImpl resolvedHolder; + try { + resolvedHolder = compilerToVM().resolveFieldInPool(this, index, (HotSpotResolvedJavaMethodImpl) method, (byte) opcode, info); + } catch (Throwable t) { + /* + * If there was an exception resolving the field we give up and return an unresolved + * field. + */ + return new UnresolvedJavaField(holder, lookupUtf8(getNameRefIndexAt(nameAndTypeIndex)), type); + } + final int flags = info[0]; + final int offset = info[1]; + final int fieldIndex = info[2]; + HotSpotResolvedJavaField result = resolvedHolder.createField(type, offset, flags, fieldIndex); + return result; + } else { + return new UnresolvedJavaField(holder, lookupUtf8(getNameRefIndexAt(nameAndTypeIndex)), type); + } + } + + /** + * Converts a raw index from the bytecodes to a constant pool index (not a cache index). + * + * @param rawIndex index from the bytecode + * + * @param opcode bytecode to convert the index for + * + * @return constant pool index + */ + public int rawIndexToConstantPoolIndex(int rawIndex, int opcode) { + int index; + if (isInvokedynamicIndex(rawIndex)) { + if (opcode != Bytecodes.INVOKEDYNAMIC) { + throw new IllegalArgumentException("expected INVOKEDYNAMIC at " + rawIndex + ", got " + opcode); + } + index = decodeInvokedynamicIndex(rawIndex) + config().constantPoolCpCacheIndexTag; + } else { + if (opcode == Bytecodes.INVOKEDYNAMIC) { + throw new IllegalArgumentException("unexpected INVOKEDYNAMIC at " + rawIndex); + } + index = rawIndexToConstantPoolCacheIndex(rawIndex, opcode); + } + return compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); + } + + @Override + public void loadReferencedType(int cpi, int opcode) { + loadReferencedType(cpi, opcode, true /* initialize */); + } + + @Override + @SuppressWarnings("fallthrough") + public void loadReferencedType(int cpi, int opcode, boolean initialize) { + int index; + switch (opcode) { + case Bytecodes.CHECKCAST: + case Bytecodes.INSTANCEOF: + case Bytecodes.NEW: + case Bytecodes.ANEWARRAY: + case Bytecodes.MULTIANEWARRAY: + case Bytecodes.LDC: + case Bytecodes.LDC_W: + case Bytecodes.LDC2_W: + index = cpi; + break; + case Bytecodes.INVOKEDYNAMIC: { + // invokedynamic instructions point to a constant pool cache entry. + index = decodeConstantPoolCacheIndex(cpi) + config().constantPoolCpCacheIndexTag; + index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); + break; + } + case Bytecodes.GETSTATIC: + case Bytecodes.PUTSTATIC: + case Bytecodes.GETFIELD: + case Bytecodes.PUTFIELD: + case Bytecodes.INVOKEVIRTUAL: + case Bytecodes.INVOKESPECIAL: + case Bytecodes.INVOKESTATIC: + case Bytecodes.INVOKEINTERFACE: { + // invoke and field instructions point to a constant pool cache entry. + index = rawIndexToConstantPoolCacheIndex(cpi, opcode); + index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); + break; + } + default: + throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode); + } + + final JvmConstant tag = getTagAt(index); + if (tag == null) { + assert getTagAt(index - 1) == constants.jvmDouble || getTagAt(index - 1) == constants.jvmLong; + return; + } + switch (tag.name) { + case "Methodref": + case "Fieldref": + case "InterfaceMethodref": + index = getUncachedKlassRefIndexAt(index); + // Read the tag only once because it could change between multiple reads. + final JvmConstant klassTag = getTagAt(index); + assert klassTag == constants.jvmClass || klassTag == constants.jvmUnresolvedClass || klassTag == constants.jvmUnresolvedClassInError : klassTag; + // fall through + case "Class": + case "UnresolvedClass": + case "UnresolvedClassInError": + final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index); + if (initialize && !type.isPrimitive() && !type.isArray()) { + type.ensureInitialized(); + } + if (tag == constants.jvmMethodref) { + if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) { + final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); + checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); + compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex); + } + } + + break; + case "InvokeDynamic": + if (isInvokedynamicIndex(cpi)) { + compilerToVM().resolveInvokeDynamicInPool(this, cpi); + } + break; + default: + // nothing + break; + } + + } + + // Lazily initialized. + private static String[] signaturePolymorphicHolders; + + /** + * Determines if {@code type} contains signature polymorphic methods. + */ + @SuppressFBWarnings(value = "LI_LAZY_INIT_STATIC", justification = "signaturePolymorphicHolders is a cache, not a singleton that must be constructed exactly once" + + "and compiler re-ordering is not an issue due to the VM call") + static boolean isSignaturePolymorphicHolder(final ResolvedJavaType type) { + String name = type.getName(); + if (signaturePolymorphicHolders == null) { + signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders(); + } + for (String holder : signaturePolymorphicHolders) { + if (name.equals(holder)) { + return true; + } + } + return false; + } + + /** + * Check for a resolved dynamic adapter method at the specified index, resulting from either a + * resolved invokedynamic or invokevirtual on a signature polymorphic MethodHandle method + * (HotSpot invokehandle). + * + * @param cpi the constant pool index + * @param opcode the opcode of the instruction for which the lookup is being performed + * @return {@code true} if a signature polymorphic method reference was found, otherwise + * {@code false} + */ + public boolean isResolvedDynamicInvoke(int cpi, int opcode) { + if (Bytecodes.isInvokeHandleAlias(opcode)) { + final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); + checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); + int op = compilerToVM().isResolvedInvokeHandleInPool(this, methodRefCacheIndex); + return op == opcode; + } + return false; + } + + public String getSourceFileName() { + final int sourceFileNameIndex = UNSAFE.getChar(getMetaspaceConstantPool() + config().constantPoolSourceFileNameIndexOffset); + if (sourceFileNameIndex == 0) { + return null; + } + return lookupUtf8(sourceFileNameIndex); + } + + @Override + public String toString() { + HotSpotResolvedObjectType holder = getHolder(); + return "HotSpotConstantPool<" + holder.toJavaName() + ">"; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2017, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; + +/** + * Represents a constant that was retrieved from a constant pool. Used to keep track of the constant + * pool slot for the constant. + */ +public final class HotSpotConstantPoolObject implements JavaConstant { + + public static JavaConstant forObject(HotSpotResolvedObjectType type, int cpi, JavaConstant object) { + return new HotSpotConstantPoolObject(type, cpi, object); + } + + private final JavaConstant constant; + private final HotSpotResolvedObjectType type; + private final int cpi; + + public HotSpotResolvedObjectType getCpType() { + return type; + } + + public int getCpi() { + return cpi; + } + + HotSpotConstantPoolObject(HotSpotResolvedObjectType type, int cpi, JavaConstant constant) { + this.type = type; + this.cpi = cpi; + this.constant = constant; + } + + @Override + public boolean equals(Object o) { + if (o instanceof HotSpotConstantPoolObject) { + HotSpotConstantPoolObject other = (HotSpotConstantPoolObject) o; + return type.equals(other.type) && cpi == other.cpi && constant.equals(other.constant); + } + return false; + } + + @Override + public int hashCode() { + return constant.hashCode() + cpi + type.hashCode(); + } + + @Override + public JavaKind getJavaKind() { + return constant.getJavaKind(); + } + + @Override + public boolean isNull() { + return constant.isNull(); + } + + @Override + public boolean isDefaultForKind() { + return constant.isDefaultForKind(); + } + + @Override + public Object asBoxedPrimitive() { + return constant.asBoxedPrimitive(); + } + + @Override + public int asInt() { + return constant.asInt(); + } + + @Override + public boolean asBoolean() { + return constant.asBoolean(); + } + + @Override + public long asLong() { + return constant.asLong(); + } + + @Override + public float asFloat() { + return constant.asFloat(); + } + + @Override + public double asDouble() { + return 0; + } + + @Override + public String toValueString() { + return getCpType().getName() + getCpi(); + } + + @Override + public String toString() { + return super.toString() + "@" + toValueString(); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import java.util.Objects; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MemoryAccessProvider; +import jdk.vm.ci.meta.MethodHandleAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * HotSpot implementation of {@link ConstantReflectionProvider}. + */ +public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider { + + protected final HotSpotJVMCIRuntime runtime; + protected final HotSpotMethodHandleAccessProvider methodHandleAccess; + private final HotSpotMemoryAccessProviderImpl memoryAccess; + + public HotSpotConstantReflectionProvider(HotSpotJVMCIRuntime runtime) { + this.runtime = runtime; + this.methodHandleAccess = new HotSpotMethodHandleAccessProvider(this); + this.memoryAccess = new HotSpotMemoryAccessProviderImpl(runtime); + } + + @Override + public MethodHandleAccessProvider getMethodHandleAccess() { + return methodHandleAccess; + } + + @Override + public MemoryAccessProvider getMemoryAccessProvider() { + return memoryAccess; + } + + @Override + public Boolean constantEquals(Constant x, Constant y) { + if (x == y) { + return true; + } else if (x instanceof HotSpotObjectConstantImpl) { + return y instanceof HotSpotObjectConstantImpl && x.equals(y); + } else { + return Objects.equals(x, y); + } + } + + @Override + public Integer readArrayLength(JavaConstant array) { + if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) { + return null; + } + + HotSpotObjectConstantImpl arrayObject = ((HotSpotObjectConstantImpl) array); + return runtime.getReflection().getLength(arrayObject); + } + + @Override + public JavaConstant readArrayElement(JavaConstant array, int index) { + if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) { + return null; + } + HotSpotObjectConstantImpl arrayObject = ((HotSpotObjectConstantImpl) array); + return runtime.getReflection().readArrayElement(arrayObject, index); + } + + /** + * Check if the constant is a boxed value that is guaranteed to be cached by the platform. + * Otherwise the generated code might be the only reference to the boxed value and since object + * references from nmethods are weak this can cause GC problems. + * + * @return true if the box is cached + */ + private static boolean isBoxCached(JavaConstant source) { + switch (source.getJavaKind()) { + case Boolean: + return true; + case Char: + return source.asInt() <= 127; + case Byte: + case Short: + case Int: + return source.asInt() >= -128 && source.asInt() <= 127; + case Long: + return source.asLong() >= -128 && source.asLong() <= 127; + case Float: + case Double: + return false; + default: + throw new IllegalArgumentException("unexpected kind " + source.getJavaKind()); + } + } + + @Override + public JavaConstant boxPrimitive(JavaConstant source) { + if (source == null || !source.getJavaKind().isPrimitive() || !isBoxCached(source)) { + return null; + } + return runtime.getReflection().boxPrimitive(source); + } + + @Override + public JavaConstant unboxPrimitive(JavaConstant source) { + if (source == null || !source.getJavaKind().isObject()) { + return null; + } + if (source.isNull()) { + return null; + } + return runtime.getReflection().unboxPrimitive((HotSpotObjectConstantImpl) source); + } + + @Override + public JavaConstant forString(String value) { + return runtime.getReflection().forObject(value); + } + + public JavaConstant forObject(Object value) { + return runtime.getReflection().forObject(value); + } + + @Override + public ResolvedJavaType asJavaType(Constant constant) { + if (constant instanceof HotSpotObjectConstantImpl) { + return ((HotSpotObjectConstantImpl) constant).asJavaType(); + } + if (constant instanceof HotSpotMetaspaceConstant) { + MetaspaceObject obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant); + if (obj instanceof HotSpotResolvedObjectTypeImpl) { + return (ResolvedJavaType) obj; + } + } + return null; + } + + @Override + public JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver) { + HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field; + if (hotspotField.isStatic()) { + HotSpotResolvedObjectTypeImpl holder = (HotSpotResolvedObjectTypeImpl) hotspotField.getDeclaringClass(); + if (holder.isInitialized()) { + return runtime().compilerToVm.readFieldValue(holder, (HotSpotResolvedObjectTypeImpl) hotspotField.getDeclaringClass(), hotspotField.getOffset(), + hotspotField.getType().getJavaKind()); + } + } else if (receiver instanceof HotSpotObjectConstantImpl) { + return ((HotSpotObjectConstantImpl) receiver).readFieldValue(hotspotField); + } else if (receiver == null) { + throw new NullPointerException("receiver is null"); + } + return null; + } + + @Override + public JavaConstant asJavaClass(ResolvedJavaType type) { + return ((HotSpotResolvedJavaType) type).getJavaMirror(); + } + + @Override + public Constant asObjectHub(ResolvedJavaType type) { + if (type instanceof HotSpotResolvedObjectType) { + return ((HotSpotResolvedObjectType) type).klass(); + } else { + throw JVMCIError.unimplemented(); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.InvokeTarget; + +public class HotSpotForeignCallTarget implements InvokeTarget { + + /** + * The entry point address of this call's target. + */ + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "accessed by subclasses")// + protected long address; + + public HotSpotForeignCallTarget(long address) { + this.address = address; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotInstalledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotInstalledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotInstalledCode.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotInstalledCode.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; + +import jdk.vm.ci.code.InstalledCode; + +/** + * Implementation of {@link InstalledCode} for HotSpot representing a {@code CodeBlob}. The address + * of the {@code CodeBlob} is stored in {@link InstalledCode#address}. + */ +public abstract class HotSpotInstalledCode extends InstalledCode { + + /** + * Total size of the code blob (i.e. {@code CodeBlob::size()}). + */ + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int size; + + /** + * Start address of the code (i.e. {@code CodeBlob::code_begin()}). + */ + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private long codeStart; + + /** + * Size of the code (i.e. {@code CodeBlob::code_size()}). + */ + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int codeSize; + + public HotSpotInstalledCode(String name) { + super(name); + } + + /** + * Gets the value of {@code CodeBlob::size()}. + */ + public int getSize() { + return size; + } + + @Override + public abstract String toString(); + + /** + * Gets the value of {@code CodeBlob::code_begin()} if {@linkplain #isValid() valid}, 0 + * otherwise. + */ + @Override + public long getStart() { + return codeStart; + } + + /** + * Gets the value of {@code CodeBlob::code_size()} if {@linkplain #isValid() valid}, 0 + * otherwise. + */ + public long getCodeSize() { + return codeSize; + } + + @Override + public byte[] getCode() { + return compilerToVM().getCode(this); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaType; + +/** + * Common base class for all HotSpot {@link JavaType} implementations. + */ +public abstract class HotSpotJavaType implements JavaType { + + private final String name; + + public HotSpotJavaType(String name) { + this.name = name; + } + + @Override + public final String getName() { + return name; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJDKReflection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJDKReflection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJDKReflection.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJDKReflection.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Array; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.HashMap; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * Implementation of {@link HotSpotJVMCIReflection} in terms of standard JDK reflection API. This is + * only available when running in the HotSpot heap. + */ +final class HotSpotJDKReflection extends HotSpotJVMCIReflection { + + @Override + Object resolveObject(HotSpotObjectConstantImpl object) { + if (object == null) { + return null; + } + return ((DirectHotSpotObjectConstantImpl) object).object; + } + + @Override + boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl obj) { + Class javaMirror = getMirror(holder); + Object value = resolveObject(obj); + return javaMirror.isInstance(value); + } + + @Override + boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType) { + Class javaMirror = getMirror(holder); + return javaMirror.isAssignableFrom(getMirror(otherType)); + + } + + @Override + Annotation[] getAnnotations(HotSpotResolvedObjectTypeImpl holder) { + Class javaMirror = getMirror(holder); + return javaMirror.getAnnotations(); + } + + @Override + Annotation[] getDeclaredAnnotations(HotSpotResolvedObjectTypeImpl holder) { + Class javaMirror = getMirror(holder); + return javaMirror.getDeclaredAnnotations(); + } + + @Override + T getAnnotation(HotSpotResolvedObjectTypeImpl holder, Class annotationClass) { + Class javaMirror = getMirror(holder); + return javaMirror.getAnnotation(annotationClass); + } + + @Override + boolean isLocalClass(HotSpotResolvedObjectTypeImpl holder) { + Class javaMirror = getMirror(holder); + return javaMirror.isLocalClass(); + } + + @Override + boolean isMemberClass(HotSpotResolvedObjectTypeImpl holder) { + Class javaMirror = getMirror(holder); + return javaMirror.isMemberClass(); + } + + @Override + HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder) { + Class javaMirror = getMirror(holder); + return (HotSpotResolvedObjectType) runtime().fromClass(javaMirror.getEnclosingClass()); + } + + @Override + boolean equals(HotSpotObjectConstantImpl a, HotSpotObjectConstantImpl b) { + return resolveObject(a) == resolveObject(b) && a.isCompressed() == b.isCompressed(); + } + + // This field is being kept around for compatibility with libgraal + @SuppressWarnings("unused") private long oopSizeOffset; + + @Override + ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod) { + java.lang.reflect.Parameter[] javaParameters = getMethod(javaMethod).getParameters(); + ResolvedJavaMethod.Parameter[] res = new ResolvedJavaMethod.Parameter[javaParameters.length]; + for (int i = 0; i < res.length; i++) { + java.lang.reflect.Parameter src = javaParameters[i]; + String paramName = src.isNamePresent() ? src.getName() : null; + res[i] = new ResolvedJavaMethod.Parameter(paramName, src.getModifiers(), javaMethod, i); + } + return res; + } + + @Override + Annotation[][] getParameterAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { + return getMethod(javaMethod).getParameterAnnotations(); + } + + @Override + Type[] getGenericParameterTypes(HotSpotResolvedJavaMethodImpl javaMethod) { + return getMethod(javaMethod).getGenericParameterTypes(); + } + + @Override + Annotation[] getFieldAnnotations(HotSpotResolvedJavaFieldImpl javaField) { + return getField(javaField).getAnnotations(); + } + + @Override + Annotation[] getMethodAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { + return getMethod(javaMethod).getAnnotations(); + } + + @Override + Annotation[] getMethodDeclaredAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { + return getMethod(javaMethod).getDeclaredAnnotations(); + } + + @Override + Annotation[] getFieldDeclaredAnnotations(HotSpotResolvedJavaFieldImpl javaField) { + return getField(javaField).getDeclaredAnnotations(); + } + + @Override + T getMethodAnnotation(HotSpotResolvedJavaMethodImpl javaMethod, Class annotationClass) { + return getMethod(javaMethod).getAnnotation(annotationClass); + } + + @Override + T getFieldAnnotation(HotSpotResolvedJavaFieldImpl javaField, Class annotationClass) { + return getField(javaField).getAnnotation(annotationClass); + } + + @Override + HotSpotResolvedObjectTypeImpl getType(HotSpotObjectConstantImpl object) { + Object value = resolveObject(object); + Class theClass = value.getClass(); + return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(theClass); + } + + @Override + String asString(HotSpotObjectConstantImpl object) { + Object value = resolveObject(object); + if (value instanceof String) { + return (String) value; + } + return null; + } + + @Override + ResolvedJavaType asJavaType(HotSpotObjectConstantImpl object) { + Object value = resolveObject(object); + if (value instanceof Class) { + Class javaClass = (Class) value; + return runtime().fromClass(javaClass); + } + if (value instanceof ResolvedJavaType) { + return (ResolvedJavaType) value; + } + return null; + } + + @SuppressWarnings("unchecked") + @Override + T asObject(HotSpotObjectConstantImpl object, Class type) { + Object value = resolveObject(object); + if (type.isInstance(value)) { + return (T) value; + } + return null; + } + + @Override + Object asObject(HotSpotObjectConstantImpl object, HotSpotResolvedJavaType type) { + Object value = resolveObject(object); + if (getMirror(type).isInstance(value)) { + return value; + } + return null; + } + + @Override + String formatString(HotSpotObjectConstantImpl object) { + return JavaKind.Object.format(resolveObject(object)); + } + + @Override + Integer getLength(HotSpotObjectConstantImpl arrayObject) { + Object object = resolveObject(arrayObject); + if (object.getClass().isArray()) { + return Array.getLength(object); + } + return null; + } + + @Override + JavaConstant readArrayElement(HotSpotObjectConstantImpl arrayObject, int index) { + Object a = resolveObject(arrayObject); + if (!a.getClass().isArray() || index < 0 || index >= Array.getLength(a)) { + return null; + } + if (a instanceof Object[]) { + Object element = ((Object[]) a)[index]; + return forObject(element); + } else { + if (a instanceof int[]) { + return JavaConstant.forInt(((int[]) a)[index]); + } else if (a instanceof char[]) { + return JavaConstant.forChar(((char[]) a)[index]); + } else if (a instanceof byte[]) { + return JavaConstant.forByte(((byte[]) a)[index]); + } else if (a instanceof long[]) { + return JavaConstant.forLong(((long[]) a)[index]); + } else if (a instanceof short[]) { + return JavaConstant.forShort(((short[]) a)[index]); + } else if (a instanceof float[]) { + return JavaConstant.forFloat(((float[]) a)[index]); + } else if (a instanceof double[]) { + return JavaConstant.forDouble(((double[]) a)[index]); + } else if (a instanceof boolean[]) { + return JavaConstant.forBoolean(((boolean[]) a)[index]); + } else { + throw new JVMCIError("Should not reach here"); + } + } + } + + @Override + JavaConstant unboxPrimitive(HotSpotObjectConstantImpl source) { + return JavaConstant.forBoxedPrimitive(resolveObject(source)); + } + + @Override + JavaConstant forObject(Object value) { + if (value == null) { + return JavaConstant.NULL_POINTER; + } + return forNonNullObject(value); + } + + private static HotSpotObjectConstantImpl forNonNullObject(Object value) { + return DirectHotSpotObjectConstantImpl.forNonNullObject(value, false); + } + + @Override + JavaConstant boxPrimitive(JavaConstant source) { + return forNonNullObject(source.asBoxedPrimitive()); + } + + /** + * Gets a {@link Method} object corresponding to {@code method}. This method guarantees the same + * {@link Method} object is returned if called twice on the same {@code method} value. + */ + static Executable getMethod(HotSpotResolvedJavaMethodImpl method) { + assert !method.isClassInitializer() : method; + if (method.toJavaCache == null) { + synchronized (method) { + if (method.toJavaCache == null) { + method.toJavaCache = compilerToVM().asReflectionExecutable(method); + } + } + } + return method.toJavaCache; + } + + /** + * Gets a {@link Field} object corresponding to {@code field}. This method guarantees the same + * {@link Field} object is returned if called twice on the same {@code field} value. This is + * required to ensure the results of {@link HotSpotResolvedJavaFieldImpl#getAnnotations()} and + * {@link HotSpotResolvedJavaFieldImpl#getAnnotation(Class)} are stable (i.e., for a given field + * {@code f} and annotation class {@code a}, the same object is returned for each call to + * {@code f.getAnnotation(a)}). + */ + static Field getField(HotSpotResolvedJavaFieldImpl field) { + HotSpotResolvedObjectTypeImpl declaringClass = field.getDeclaringClass(); + synchronized (declaringClass) { + HashMap cache = declaringClass.reflectionFieldCache; + if (cache == null) { + cache = new HashMap<>(); + declaringClass.reflectionFieldCache = cache; + } + Field reflect = cache.get(field); + if (reflect == null) { + reflect = compilerToVM().asReflectionField(field.getDeclaringClass(), field.getIndex()); + cache.put(field, reflect); + } + return reflect; + } + } + + Class getMirror(HotSpotResolvedObjectTypeImpl holder) { + return (Class) resolveObject((HotSpotObjectConstantImpl) holder.getJavaMirror()); + } + + Class getMirror(HotSpotResolvedJavaType type) { + assert type != null; + if (type instanceof HotSpotResolvedPrimitiveType) { + return (Class) resolveObject(((HotSpotResolvedPrimitiveType) type).mirror); + } else { + return getMirror((HotSpotResolvedObjectTypeImpl) type); + } + } +} + diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015, 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. + */ +package jdk.vm.ci.hotspot; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.runtime.JVMCIBackend; + +public interface HotSpotJVMCIBackendFactory { + + JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host); + + /** + * Gets the CPU architecture of this backend. + */ + String getArchitecture(); + + /** + * Converts a bit mask of CPU features to enum constants. + * + * @param CPU feature enum type + * @param enumType the class of {@code CPUFeatureType} + * @param constants VM constants. Each entry whose key starts with {@code "VM_Version::CPU_"} + * specifies a CPU feature and its value is a mask for a bit in {@code features} + * @param features bits specifying CPU features + * @param renaming maps from VM feature names to enum constant names where the two differ + * @throws IllegalArgumentException if any VM CPU feature constant cannot be converted to an + * enum value + * @return the set of converted values + */ + static > EnumSet convertFeatures( + Class enumType, + Map constants, + long features, + Map renaming) { + EnumSet outFeatures = EnumSet.noneOf(enumType); + List missing = new ArrayList<>(); + for (Entry e : constants.entrySet()) { + long bitMask = e.getValue(); + String key = e.getKey(); + if (key.startsWith("VM_Version::CPU_")) { + String name = key.substring("VM_Version::CPU_".length()); + try { + CPUFeatureType feature = Enum.valueOf(enumType, renaming.getOrDefault(name, name)); + if ((features & bitMask) != 0) { + outFeatures.add(feature); + } + } catch (IllegalArgumentException iae) { + missing.add(name); + } + } + } + if (!missing.isEmpty()) { + throw new JVMCIError("Missing CPU feature constants: %s", missing); + } + return outFeatures; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2015, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.List; +import java.util.Set; + +import jdk.vm.ci.code.CompilationRequest; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; +import jdk.vm.ci.runtime.JVMCICompiler; +import jdk.vm.ci.runtime.JVMCICompilerFactory; +import jdk.vm.ci.runtime.JVMCIRuntime; +import jdk.vm.ci.services.JVMCIPermission; +import jdk.vm.ci.services.JVMCIServiceLocator; +import jdk.vm.ci.services.Services; + +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; + +final class HotSpotJVMCICompilerConfig { + + /** + * This factory allows JVMCI initialization to succeed but raises an error if the VM asks JVMCI + * to perform a compilation. This allows the reflective parts of the JVMCI API to be used + * without requiring a compiler implementation to be available. + */ + private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler { + + private final String reason; + private final HotSpotJVMCIRuntime runtime; + + DummyCompilerFactory(String reason, HotSpotJVMCIRuntime runtime) { + this.reason = reason; + this.runtime = runtime; + } + + @Override + public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) { + throw runtime.exitHotSpotWithMessage(1, "Cannot use JVMCI compiler: %s%n", reason); + } + + @Override + public String getCompilerName() { + return "null"; + } + + @Override + public JVMCICompiler createCompiler(JVMCIRuntime rt) { + return this; + } + + @Override + public boolean isGCSupported(int gcIdentifier) { + return false; + } + } + + /** + * Factory of the selected system compiler. + */ + @NativeImageReinitialize private static JVMCICompilerFactory compilerFactory; + + /** + * Gets the selected system compiler factory. + * + * @return the selected system compiler factory + * @throws SecurityException if a security manager is present and it denies + * {@link JVMCIPermission} for any {@link JVMCIServiceLocator} loaded by this method + */ + static JVMCICompilerFactory getCompilerFactory(HotSpotJVMCIRuntime runtime) { + if (compilerFactory == null) { + JVMCICompilerFactory factory = null; + String compilerName = Option.Compiler.getString(); + if (compilerName != null) { + String compPropertyName = Option.Compiler.getPropertyName(); + if (compilerName.isEmpty()) { + factory = new DummyCompilerFactory("Value of " + compPropertyName + " is empty", runtime); + } else if (compilerName.equals("null")) { + factory = new DummyCompilerFactory("Value of " + compPropertyName + " is \"null\"", runtime); + } else { + for (JVMCICompilerFactory f : getJVMCICompilerFactories()) { + if (f.getCompilerName().equals(compilerName)) { + factory = f; + } + } + if (factory == null) { + if (Services.IS_IN_NATIVE_IMAGE) { + throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' not found in JVMCI native library.%n" + + "Use -XX:-UseJVMCINativeLibrary when specifying a JVMCI compiler available on a class path with %s.%n", + compilerName, compPropertyName); + } + throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' specified by %s not found%n", compilerName, compPropertyName); + } + } + } else { + // Auto select a single available compiler + String reason = "No JVMCI compiler found"; + for (JVMCICompilerFactory f : getJVMCICompilerFactories()) { + if (factory == null) { + openJVMCITo(f.getClass().getModule()); + factory = f; + } else { + // Multiple factories seen - cancel auto selection + reason = "Multiple JVMCI compilers found: \"" + factory.getCompilerName() + "\" and \"" + f.getCompilerName() + "\""; + factory = null; + break; + } + } + if (factory == null) { + factory = new DummyCompilerFactory(reason, runtime); + } + } + factory.onSelection(); + compilerFactory = factory; + } + return compilerFactory; + } + + /** + * Opens all JVMCI packages to {@code otherModule}. + */ + private static void openJVMCITo(Module otherModule) { + if (!IS_IN_NATIVE_IMAGE) { + Module jvmci = HotSpotJVMCICompilerConfig.class.getModule(); + if (jvmci != otherModule) { + Set packages = jvmci.getPackages(); + for (String pkg : packages) { + boolean opened = jvmci.isOpen(pkg, otherModule); + if (!opened) { + jvmci.addOpens(pkg, otherModule); + } + } + } + } + } + + private static List getJVMCICompilerFactories() { + return JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.runtime.JVMCICompilerFactory; + +/** + * HotSpot extensions to {@link JVMCICompilerFactory}. + */ +public abstract class HotSpotJVMCICompilerFactory implements JVMCICompilerFactory { + + public enum CompilationLevelAdjustment { + /** + * No adjustment. + */ + None, + + /** + * Adjust based on declaring class of method. + */ + ByHolder, + + /** + * Adjust based on declaring class, name and signature of method. + */ + ByFullSignature + } + + /** + * Determines if this object may want to adjust the compilation level for a method that is being + * scheduled by the VM for compilation. + */ + public CompilationLevelAdjustment getCompilationLevelAdjustment() { + return CompilationLevelAdjustment.None; + } + + public enum CompilationLevel { + None, + Simple, + LimitedProfile, + FullProfile, + FullOptimization + } + + /** + * Potentially modifies the compilation level currently selected by the VM compilation policy + * for a method. + * + * @param declaringClass the class in which the method is declared. This value is either a + * {@code Class} instance or a {@code String} representing the + * {@link JavaType#toJavaName() name} of the class. + * @param name the name of the method or {@code null} depending on the value that was returned + * by {@link #getCompilationLevelAdjustment()} + * @param signature the signature of the method or {@code null} depending on the value that was + * returned by {@link #getCompilationLevelAdjustment()} + * @param isOsr specifies if the compilation being scheduled in an OSR compilation + * @param level the compilation level currently selected by the VM compilation policy + * @return the compilation level to use for the compilation being scheduled (must be a valid + * {@code CompLevel} enum value) + */ + public CompilationLevel adjustCompilationLevel(Object declaringClass, String name, String signature, boolean isOsr, CompilationLevel level) { + throw new InternalError(getClass().getName() + " must override adjustCompilationLevel(...) since it returned a value other than " + CompilationLevel.class.getName() + "." + + CompilationLevel.None + " from getCompilationLevelAdjustment()"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * API for reflecting on the internals of HotSpot JVMCI types and objects. + */ +abstract class HotSpotJVMCIReflection { + + abstract boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl obj); + + abstract boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType); + + abstract Annotation[] getAnnotations(HotSpotResolvedObjectTypeImpl holder); + + abstract Annotation[] getDeclaredAnnotations(HotSpotResolvedObjectTypeImpl holder); + + abstract T getAnnotation(HotSpotResolvedObjectTypeImpl holder, Class annotationClass); + + abstract boolean isLocalClass(HotSpotResolvedObjectTypeImpl holder); + + abstract boolean isMemberClass(HotSpotResolvedObjectTypeImpl holder); + + abstract HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder); + + abstract boolean equals(HotSpotObjectConstantImpl hotSpotResolvedJavaType, HotSpotObjectConstantImpl that); + + abstract ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod); + + abstract Annotation[][] getParameterAnnotations(HotSpotResolvedJavaMethodImpl javaMethod); + + abstract Type[] getGenericParameterTypes(HotSpotResolvedJavaMethodImpl javaMethod); + + abstract Annotation[] getFieldAnnotations(HotSpotResolvedJavaFieldImpl javaMethod); + + abstract Annotation[] getMethodAnnotations(HotSpotResolvedJavaMethodImpl javaField); + + abstract Annotation[] getMethodDeclaredAnnotations(HotSpotResolvedJavaMethodImpl javaMethod); + + abstract Annotation[] getFieldDeclaredAnnotations(HotSpotResolvedJavaFieldImpl javaMethod); + + abstract T getMethodAnnotation(HotSpotResolvedJavaMethodImpl javaMethod, Class annotationClass); + + abstract HotSpotResolvedObjectTypeImpl getType(HotSpotObjectConstantImpl object); + + abstract String asString(HotSpotObjectConstantImpl object); + + /** + * Given a {@link java.lang.Class} instance, return the corresponding ResolvedJavaType. + */ + abstract ResolvedJavaType asJavaType(HotSpotObjectConstantImpl object); + + abstract T asObject(HotSpotObjectConstantImpl object, Class type); + + abstract Object asObject(HotSpotObjectConstantImpl object, HotSpotResolvedJavaType type); + + abstract String formatString(HotSpotObjectConstantImpl object); + + abstract Integer getLength(HotSpotObjectConstantImpl arrayObject); + + abstract JavaConstant readArrayElement(HotSpotObjectConstantImpl arrayObject, int index); + + abstract JavaConstant unboxPrimitive(HotSpotObjectConstantImpl source); + + abstract JavaConstant forObject(Object value); + + abstract JavaConstant boxPrimitive(JavaConstant source); + + abstract T getFieldAnnotation(HotSpotResolvedJavaFieldImpl javaField, Class annotationClass); + + /** + * Resolves {@code objectHandle} to a raw object if possible. + * + * @throws HotSpotJVMCIUnsupportedOperationError if {@code objectHandle} refers to an object in + * another heap + */ + abstract Object resolveObject(HotSpotObjectConstantImpl objectHandle); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1453 @@ +/* + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.common.InitTimer.timer; +import static jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.None; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.Serializable; +import java.lang.invoke.CallSite; +import java.lang.invoke.ConstantCallSite; +import java.lang.invoke.MethodHandle; +import java.lang.ref.WeakReference; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Formatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import jdk.internal.misc.Unsafe; +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.CompilationRequest; +import jdk.vm.ci.code.CompilationRequestResult; +import jdk.vm.ci.code.CompiledCode; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.common.InitTimer; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.UnresolvedJavaType; +import jdk.vm.ci.runtime.JVMCI; +import jdk.vm.ci.runtime.JVMCIBackend; +import jdk.vm.ci.runtime.JVMCICompiler; +import jdk.vm.ci.runtime.JVMCICompilerFactory; +import jdk.vm.ci.runtime.JVMCIRuntime; +import jdk.vm.ci.services.JVMCIServiceLocator; +import jdk.vm.ci.services.Services; + +/** + * HotSpot implementation of a JVMCI runtime. + */ +public final class HotSpotJVMCIRuntime implements JVMCIRuntime { + + /** + * Singleton instance lazily initialized via double-checked locking. + */ + @NativeImageReinitialize private static volatile HotSpotJVMCIRuntime instance; + + private HotSpotResolvedObjectTypeImpl javaLangObject; + private HotSpotResolvedObjectTypeImpl javaLangInvokeMethodHandle; + private HotSpotResolvedObjectTypeImpl constantCallSiteType; + private HotSpotResolvedObjectTypeImpl callSiteType; + private HotSpotResolvedObjectTypeImpl javaLangString; + private HotSpotResolvedObjectTypeImpl javaLangClass; + private HotSpotResolvedObjectTypeImpl throwableType; + private HotSpotResolvedObjectTypeImpl serializableType; + private HotSpotResolvedObjectTypeImpl cloneableType; + private HotSpotResolvedObjectTypeImpl enumType; + + HotSpotResolvedObjectTypeImpl getJavaLangObject() { + if (javaLangObject == null) { + javaLangObject = (HotSpotResolvedObjectTypeImpl) fromClass(Object.class); + } + return javaLangObject; + } + + HotSpotResolvedObjectTypeImpl getJavaLangString() { + if (javaLangString == null) { + javaLangString = (HotSpotResolvedObjectTypeImpl) fromClass(String.class); + } + return javaLangString; + } + + HotSpotResolvedObjectTypeImpl getJavaLangClass() { + if (javaLangClass == null) { + javaLangClass = (HotSpotResolvedObjectTypeImpl) fromClass(Class.class); + } + return javaLangClass; + } + + HotSpotResolvedObjectTypeImpl getJavaLangCloneable() { + if (cloneableType == null) { + cloneableType = (HotSpotResolvedObjectTypeImpl) fromClass(Cloneable.class); + } + return cloneableType; + } + + HotSpotResolvedObjectTypeImpl getJavaLangSerializable() { + if (serializableType == null) { + serializableType = (HotSpotResolvedObjectTypeImpl) fromClass(Serializable.class); + } + return serializableType; + } + + HotSpotResolvedObjectTypeImpl getJavaLangThrowable() { + if (throwableType == null) { + throwableType = (HotSpotResolvedObjectTypeImpl) fromClass(Throwable.class); + } + return throwableType; + } + + HotSpotResolvedObjectTypeImpl getJavaLangEnum() { + if (enumType == null) { + enumType = (HotSpotResolvedObjectTypeImpl) fromClass(Enum.class); + } + return enumType; + } + + HotSpotResolvedObjectTypeImpl getConstantCallSite() { + if (constantCallSiteType == null) { + constantCallSiteType = (HotSpotResolvedObjectTypeImpl) fromClass(ConstantCallSite.class); + } + return constantCallSiteType; + } + + HotSpotResolvedObjectTypeImpl getCallSite() { + if (callSiteType == null) { + callSiteType = (HotSpotResolvedObjectTypeImpl) fromClass(CallSite.class); + } + return callSiteType; + } + + HotSpotResolvedObjectType getMethodHandleClass() { + if (javaLangInvokeMethodHandle == null) { + javaLangInvokeMethodHandle = (HotSpotResolvedObjectTypeImpl) fromClass(MethodHandle.class); + } + return javaLangInvokeMethodHandle; + } + + /** + * Gets the singleton {@link HotSpotJVMCIRuntime} object. + */ + @VMEntryPoint + @SuppressWarnings("try") + public static HotSpotJVMCIRuntime runtime() { + HotSpotJVMCIRuntime result = instance; + if (result == null) { + // Synchronize on JVMCI.class to avoid deadlock + // between the two JVMCI initialization paths: + // HotSpotJVMCIRuntime.runtime() and JVMCI.getRuntime(). + synchronized (JVMCI.class) { + result = instance; + if (result == null) { + try (InitTimer t = timer("HotSpotJVMCIRuntime.")) { + instance = result = new HotSpotJVMCIRuntime(); + + // Can only do eager initialization of the JVMCI compiler + // once the singleton instance is available. + if (result.config.getFlag("EagerJVMCI", Boolean.class)) { + result.getCompiler(); + } + } + // Ensures JVMCIRuntime::_HotSpotJVMCIRuntime_instance is + // initialized. + JVMCI.getRuntime(); + } + // Make sure all the primitive box caches are populated (required to properly + // materialize boxed primitives + // during deoptimization). + Boolean.valueOf(false); + Byte.valueOf((byte) 0); + Short.valueOf((short) 0); + Character.valueOf((char) 0); + Integer.valueOf(0); + Long.valueOf(0); + } + } + return result; + } + + /** + * Decodes the exception encoded in {@code buffer} and throws it. + * + * @param errorOrBuffer an error code or a native byte buffer containing an exception encoded by + * {@link #encodeThrowable}. Error code values and their meanings are: + * + *
    +     *             0: native memory for the buffer could not be allocated
    +     *            -1: an OutOfMemoryError was thrown while encoding the exception
    +     *            -2: some other throwable was thrown while encoding the exception
    +     *            
    + */ + @VMEntryPoint + static void decodeAndThrowThrowable(long errorOrBuffer) throws Throwable { + if (errorOrBuffer >= -2L && errorOrBuffer <= 0) { + String context = String.format("while encoding an exception to translate it from %s to %s", + IS_IN_NATIVE_IMAGE ? "HotSpot" : "libjvmci", + IS_IN_NATIVE_IMAGE ? "libjvmci" : "HotSpot"); + if (errorOrBuffer == 0) { + throw new InternalError("native buffer could not be allocated " + context); + } + if (errorOrBuffer == -1L) { + throw new OutOfMemoryError("OutOfMemoryError occurred " + context); + } + throw new InternalError("unexpected problem occurred " + context); + } + Unsafe unsafe = UnsafeAccess.UNSAFE; + int encodingLength = unsafe.getInt(errorOrBuffer); + byte[] encoding = new byte[encodingLength]; + unsafe.copyMemory(null, errorOrBuffer + 4, encoding, Unsafe.ARRAY_BYTE_BASE_OFFSET, encodingLength); + throw TranslatedException.decodeThrowable(encoding); + } + + /** + * If {@code bufferSize} is large enough, encodes {@code throwable} into a byte array and writes + * it to {@code buffer}. The encoding in {@code buffer} can be decoded by + * {@link #decodeAndThrowThrowable}. + * + * @param throwable the exception to encode + * @param buffer a native byte buffer + * @param bufferSize the size of {@code buffer} in bytes + * @return the number of bytes written into {@code buffer} if {@code bufferSize} is large + * enough, otherwise {@code -N} where {@code N} is the value {@code bufferSize} needs to + * be to fit the encoding + */ + @VMEntryPoint + static int encodeThrowable(Throwable throwable, long buffer, int bufferSize) throws Throwable { + byte[] encoding = TranslatedException.encodeThrowable(throwable); + int requiredSize = 4 + encoding.length; + if (bufferSize < requiredSize) { + return -requiredSize; + } + Unsafe unsafe = UnsafeAccess.UNSAFE; + unsafe.putInt(buffer, encoding.length); + unsafe.copyMemory(encoding, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, buffer + 4, encoding.length); + return requiredSize; + } + + @VMEntryPoint + static String callToString(Object o) { + return o.toString(); + } + + /** + * Set of recognized {@code "jvmci.*"} system properties. Entries not associated with an + * {@link Option} have this object as their value. + */ + static final Map options = new HashMap<>(); + static { + options.put("jvmci.class.path.append", options); + } + + /** + * A list of all supported JVMCI options. + */ + public enum Option { + // @formatter:off + Compiler(String.class, null, "Selects the system compiler. This must match the getCompilerName() value returned " + + "by a jdk.vm.ci.runtime.JVMCICompilerFactory provider. " + + "An empty string or the value \"null\" selects a compiler " + + "that will raise an exception upon receiving a compilation request."), + // Note: The following one is not used (see InitTimer.ENABLED). It is added here + // so that -XX:+JVMCIPrintProperties shows the option. + InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."), + ForceTranslateFailure(String.class, null, "Forces HotSpotJVMCIRuntime.translate to throw an exception in the context " + + "of the peer runtime. The value is a filter that can restrict the forced failure to matching translated " + + "objects. See HotSpotJVMCIRuntime.postTranslation for more details. This option exists soley to test " + + "correct handling of translation failure."), + PrintConfig(Boolean.class, false, "Prints VM configuration available via JVMCI."), + AuditHandles(Boolean.class, false, "Record stack trace along with scoped foreign object reference wrappers " + + "to debug issue with a wrapper being used after its scope has closed."), + TraceMethodDataFilter(String.class, null, + "Enables tracing of profiling info when read by JVMCI.", + "Empty value: trace all methods", + "Non-empty value: trace methods whose fully qualified name contains the value."), + UseProfilingInformation(Boolean.class, true, ""); + // @formatter:on + + /** + * The prefix for system properties that are JVMCI options. + */ + private static final String JVMCI_OPTION_PROPERTY_PREFIX = "jvmci."; + + /** + * Sentinel for value initialized to {@code null} since {@code null} means uninitialized. + */ + private static final String NULL_VALUE = "NULL"; + + private final Class type; + @NativeImageReinitialize private Object value; + private final Object defaultValue; + private boolean isDefault = true; + private final String[] helpLines; + + Option(Class type, Object defaultValue, String... helpLines) { + assert Character.isUpperCase(name().charAt(0)) : "Option name must start with upper-case letter: " + name(); + this.type = type; + this.defaultValue = defaultValue; + this.helpLines = helpLines; + Object existing = options.put(getPropertyName(), this); + assert existing == null : getPropertyName(); + } + + @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum") + private void init(String propertyValue) { + assert value == null : "cannot re-initialize " + name(); + if (propertyValue == null) { + this.value = defaultValue == null ? NULL_VALUE : defaultValue; + this.isDefault = true; + } else { + if (type == Boolean.class) { + this.value = Boolean.parseBoolean(propertyValue); + } else if (type == String.class) { + this.value = propertyValue; + } else { + throw new JVMCIError("Unexpected option type " + type); + } + this.isDefault = false; + } + } + + @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum") + private Object getValue() { + if (value == NULL_VALUE) { + return null; + } + if (value == null) { + return defaultValue; + } + return value; + } + + /** + * Gets the name of system property from which this option gets its value. + */ + public String getPropertyName() { + return JVMCI_OPTION_PROPERTY_PREFIX + name(); + } + + /** + * Returns the option's value as boolean. + * + * @return option's value + */ + public boolean getBoolean() { + return (boolean) getValue(); + } + + /** + * Returns the option's value as String. + * + * @return option's value + */ + public String getString() { + return (String) getValue(); + } + + private static final int PROPERTY_LINE_WIDTH = 80; + private static final int PROPERTY_HELP_INDENT = 10; + + /** + * Prints a description of the properties used to configure shared JVMCI code. + * + * @param out stream to print to + */ + public static void printProperties(PrintStream out) { + out.println("[JVMCI properties]"); + Option[] values = values(); + for (Option option : values) { + Object value = option.getValue(); + if (value instanceof String) { + value = '"' + String.valueOf(value) + '"'; + } + + String name = option.getPropertyName(); + String assign = option.isDefault ? "=" : ":="; + String typeName = option.type.getSimpleName(); + String linePrefix = String.format("%s %s %s ", name, assign, value); + int typeStartPos = PROPERTY_LINE_WIDTH - typeName.length(); + int linePad = typeStartPos - linePrefix.length(); + if (linePad > 0) { + out.printf("%s%-" + linePad + "s[%s]%n", linePrefix, "", typeName); + } else { + out.printf("%s[%s]%n", linePrefix, typeName); + } + for (String line : option.helpLines) { + out.printf("%" + PROPERTY_HELP_INDENT + "s%s%n", "", line); + } + } + } + + /** + * Compute string similarity based on Dice's coefficient. + * + * Ported from str_similar() in globals.cpp. + */ + static float stringSimiliarity(String str1, String str2) { + int hit = 0; + for (int i = 0; i < str1.length() - 1; ++i) { + for (int j = 0; j < str2.length() - 1; ++j) { + if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) { + ++hit; + break; + } + } + } + return 2.0f * hit / (str1.length() + str2.length()); + } + + private static final float FUZZY_MATCH_THRESHOLD = 0.7F; + + /** + * Parses all system properties starting with {@value #JVMCI_OPTION_PROPERTY_PREFIX} and + * initializes the options based on their values. + * + * @param runtime + */ + static void parse(HotSpotJVMCIRuntime runtime) { + Map savedProps = jdk.vm.ci.services.Services.getSavedProperties(); + for (Map.Entry e : savedProps.entrySet()) { + String name = e.getKey(); + if (name.startsWith(Option.JVMCI_OPTION_PROPERTY_PREFIX)) { + Object value = options.get(name); + if (value == null) { + List matches = new ArrayList<>(); + for (String pn : options.keySet()) { + float score = stringSimiliarity(pn, name); + if (score >= FUZZY_MATCH_THRESHOLD) { + matches.add(pn); + } + } + Formatter msg = new Formatter(); + msg.format("Error parsing JVMCI options: Could not find option %s", name); + if (!matches.isEmpty()) { + msg.format("%nDid you mean one of the following?"); + for (String match : matches) { + msg.format("%n %s=", match); + } + } + msg.format("%nError: A fatal exception has occurred. Program will exit.%n"); + runtime.exitHotSpotWithMessage(1, msg.toString()); + } else if (value instanceof Option) { + Option option = (Option) value; + option.init(e.getValue()); + } + } + } + } + } + + private static HotSpotJVMCIBackendFactory findFactory(String architecture) { + Iterable factories = getHotSpotJVMCIBackendFactories(); + assert factories != null : "sanity"; + for (HotSpotJVMCIBackendFactory factory : factories) { + if (factory.getArchitecture().equalsIgnoreCase(architecture)) { + return factory; + } + } + + throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture); + } + + private static volatile List cachedHotSpotJVMCIBackendFactories; + + @SuppressFBWarnings(value = "LI_LAZY_INIT_UPDATE_STATIC", justification = "not sure about this") + private static Iterable getHotSpotJVMCIBackendFactories() { + if (IS_IN_NATIVE_IMAGE || cachedHotSpotJVMCIBackendFactories != null) { + return cachedHotSpotJVMCIBackendFactories; + } + Iterable result = ServiceLoader.load(HotSpotJVMCIBackendFactory.class, ClassLoader.getSystemClassLoader()); + if (IS_BUILDING_NATIVE_IMAGE) { + cachedHotSpotJVMCIBackendFactories = new ArrayList<>(); + for (HotSpotJVMCIBackendFactory factory : result) { + cachedHotSpotJVMCIBackendFactories.add(factory); + } + } + return result; + } + + /** + * Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend. + */ + public static JavaKind getHostWordKind() { + return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind; + } + + protected final CompilerToVM compilerToVm; + + protected final HotSpotVMConfigStore configStore; + protected final HotSpotVMConfig config; + private final JVMCIBackend hostBackend; + + private final JVMCICompilerFactory compilerFactory; + private final HotSpotJVMCICompilerFactory hsCompilerFactory; + private volatile JVMCICompiler compiler; + protected final HotSpotJVMCIReflection reflection; + + @NativeImageReinitialize private volatile boolean creatingCompiler; + + /** + * Cache for speeding up {@link #fromClass(Class)}. + */ + @NativeImageReinitialize private volatile ClassValue> resolvedJavaType; + + /** + * To avoid calling ClassValue.remove to refresh the weak reference, which under certain + * circumstances can lead to an infinite loop, we use a permanent holder with a mutable field + * that we refresh. + */ + private static class WeakReferenceHolder { + private volatile WeakReference ref; + + WeakReferenceHolder(T value) { + set(value); + } + + void set(T value) { + ref = new WeakReference<>(value); + } + + T get() { + return ref.get(); + } + } + + @NativeImageReinitialize private HashMap> resolvedJavaTypes; + + /** + * Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can be + * read from the VM. + */ + @SuppressWarnings("unused")// + @NativeImageReinitialize private Module[] excludeFromJVMCICompilation; + + private final Map, JVMCIBackend> backends = new HashMap<>(); + + private volatile List vmEventListeners; + + private Iterable getVmEventListeners() { + if (vmEventListeners == null) { + synchronized (this) { + if (vmEventListeners == null) { + vmEventListeners = JVMCIServiceLocator.getProviders(HotSpotVMEventListener.class); + } + } + } + return vmEventListeners; + } + + @SuppressWarnings("try") + private HotSpotJVMCIRuntime() { + compilerToVm = new CompilerToVM(); + + try (InitTimer t = timer("HotSpotVMConfig")) { + configStore = new HotSpotVMConfigStore(compilerToVm); + config = new HotSpotVMConfig(configStore); + } + + reflection = IS_IN_NATIVE_IMAGE ? new SharedLibraryJVMCIReflection() : new HotSpotJDKReflection(); + + PrintStream vmLogStream = null; + if (IS_IN_NATIVE_IMAGE) { + // Redirect System.out and System.err to HotSpot's TTY stream + vmLogStream = new PrintStream(getLogStream()); + System.setOut(vmLogStream); + System.setErr(vmLogStream); + } + + // Initialize the Option values. + Option.parse(this); + + String hostArchitecture = config.getHostArchitectureName(); + + HotSpotJVMCIBackendFactory factory; + try (InitTimer t = timer("find factory:", hostArchitecture)) { + factory = findFactory(hostArchitecture); + } + + try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) { + hostBackend = registerBackend(factory.createJVMCIBackend(this, null)); + } + + compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory(this); + if (compilerFactory instanceof HotSpotJVMCICompilerFactory) { + hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory; + if (hsCompilerFactory.getCompilationLevelAdjustment() != None) { + String name = HotSpotJVMCICompilerFactory.class.getName(); + String msg = String.format("%s.getCompilationLevelAdjustment() is no longer supported. " + + "Use %s.excludeFromJVMCICompilation() instead.", name, name); + throw new UnsupportedOperationException(msg); + } + } else { + hsCompilerFactory = null; + } + + if (config.getFlag("JVMCIPrintProperties", Boolean.class)) { + if (vmLogStream == null) { + vmLogStream = new PrintStream(getLogStream()); + } + Option.printProperties(vmLogStream); + compilerFactory.printProperties(vmLogStream); + System.exit(0); + } + + if (Option.PrintConfig.getBoolean()) { + configStore.printConfig(this); + } + } + + /** + * Sets the current thread's {@code JavaThread::_jvmci_reserved_oop} field to {@code value}. + * + * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved_oop} field + * does not exist + */ + public void setThreadLocalObject(int id, Object value) { + compilerToVm.setThreadLocalObject(id, value); + } + + /** + * Get the value of the current thread's {@code JavaThread::_jvmci_reserved_oop} field. + * + * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved_oop} field + * does not exist + */ + public Object getThreadLocalObject(int id) { + return compilerToVm.getThreadLocalObject(id); + } + + /** + * Sets the current thread's {@code JavaThread::_jvmci_reserved} field to {@code value}. + * + * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved} field does + * not exist + */ + public void setThreadLocalLong(int id, long value) { + compilerToVm.setThreadLocalLong(id, value); + } + + /** + * Get the value of the current thread's {@code JavaThread::_jvmci_reserved} field. + * + * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved} field does + * not exist + */ + public long getThreadLocalLong(int id) { + return compilerToVm.getThreadLocalLong(id); + } + + HotSpotResolvedJavaType createClass(Class javaClass) { + if (javaClass.isPrimitive()) { + return HotSpotResolvedPrimitiveType.forKind(JavaKind.fromJavaClass(javaClass)); + } + if (IS_IN_NATIVE_IMAGE) { + try { + return compilerToVm.lookupType(javaClass.getName().replace('.', '/'), null, true); + } catch (ClassNotFoundException e) { + throw new JVMCIError(e); + } + } + return compilerToVm.lookupClass(javaClass); + } + + private HotSpotResolvedJavaType fromClass0(Class javaClass) { + if (resolvedJavaType == null) { + synchronized (this) { + if (resolvedJavaType == null) { + resolvedJavaType = new ClassValue<>() { + @Override + protected WeakReferenceHolder computeValue(Class type) { + return new WeakReferenceHolder<>(createClass(type)); + } + }; + } + } + } + + WeakReferenceHolder ref = resolvedJavaType.get(javaClass); + HotSpotResolvedJavaType javaType = ref.get(); + if (javaType == null) { + /* + * If the referent has become null, create a new value and update cached weak reference. + */ + javaType = createClass(javaClass); + ref.set(javaType); + } + return javaType; + } + + /** + * Gets the JVMCI mirror for a {@link Class} object. + * + * @return the {@link ResolvedJavaType} corresponding to {@code javaClass} + */ + HotSpotResolvedJavaType fromClass(Class javaClass) { + if (javaClass == null) { + return null; + } + return fromClass0(javaClass); + } + + synchronized HotSpotResolvedObjectTypeImpl fromMetaspace(long klassPointer, String signature) { + if (resolvedJavaTypes == null) { + resolvedJavaTypes = new HashMap<>(); + } + assert klassPointer != 0; + WeakReference klassReference = resolvedJavaTypes.get(klassPointer); + HotSpotResolvedObjectTypeImpl javaType = null; + if (klassReference != null) { + javaType = (HotSpotResolvedObjectTypeImpl) klassReference.get(); + } + if (javaType == null) { + javaType = new HotSpotResolvedObjectTypeImpl(klassPointer, signature); + resolvedJavaTypes.put(klassPointer, new WeakReference<>(javaType)); + } + return javaType; + } + + private JVMCIBackend registerBackend(JVMCIBackend backend) { + Class arch = backend.getCodeCache().getTarget().arch.getClass(); + JVMCIBackend oldValue = backends.put(arch, backend); + assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName(); + return backend; + } + + public HotSpotVMConfigStore getConfigStore() { + return configStore; + } + + public HotSpotVMConfig getConfig() { + return config; + } + + public CompilerToVM getCompilerToVM() { + return compilerToVm; + } + + HotSpotJVMCIReflection getReflection() { + return reflection; + } + + /** + * Gets a predicate that determines if a given type can be considered trusted for the purpose of + * intrinsifying methods it declares. + * + * @param compilerLeafClasses classes in the leaves of the module graph comprising the JVMCI + * compiler. + */ + public Predicate getIntrinsificationTrustPredicate(Class... compilerLeafClasses) { + return new Predicate<>() { + @Override + public boolean test(ResolvedJavaType type) { + if (type instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl hsType = (HotSpotResolvedObjectTypeImpl) type; + return compilerToVm.isTrustedForIntrinsics(hsType); + } else { + return false; + } + } + }; + } + + /** + * Gets the {@link Class} corresponding to {@code type}. + * + * @param type the type for which a {@link Class} is requested + * @return the original Java class corresponding to {@code type} or {@code null} if this runtime + * does not support mapping {@link ResolvedJavaType} instances to {@link Class} + * instances + */ + public Class getMirror(ResolvedJavaType type) { + if (type instanceof HotSpotResolvedJavaType && reflection instanceof HotSpotJDKReflection) { + return ((HotSpotJDKReflection) reflection).getMirror((HotSpotResolvedJavaType) type); + } + return null; + } + + /** + * Gets the {@link Executable} corresponding to {@code method}. + * + * @param method the method for which an {@link Executable} is requested + * @return the original Java method or constructor corresponding to {@code method} or + * {@code null} if this runtime does not support mapping {@link ResolvedJavaMethod} + * instances to {@link Executable} instances + */ + public Executable getMirror(ResolvedJavaMethod method) { + if (method instanceof HotSpotResolvedJavaMethodImpl && reflection instanceof HotSpotJDKReflection) { + return HotSpotJDKReflection.getMethod((HotSpotResolvedJavaMethodImpl) method); + } + return null; + } + + /** + * Gets the {@link Field} corresponding to {@code field}. + * + * @param field the field for which a {@link Field} is requested + * @return the original Java field corresponding to {@code field} or {@code null} if this + * runtime does not support mapping {@link ResolvedJavaField} instances to {@link Field} + * instances + */ + public Field getMirror(ResolvedJavaField field) { + if (field instanceof HotSpotResolvedJavaFieldImpl && reflection instanceof HotSpotJDKReflection) { + return HotSpotJDKReflection.getField((HotSpotResolvedJavaFieldImpl) field); + } + return null; + } + + static class ErrorCreatingCompiler implements JVMCICompiler { + private final RuntimeException t; + + ErrorCreatingCompiler(RuntimeException t) { + this.t = t; + } + + @Override + public CompilationRequestResult compileMethod(CompilationRequest request) { + throw t; + } + + @Override + public boolean isGCSupported(int gcIdentifier) { + return false; + } + } + + @Override + public JVMCICompiler getCompiler() { + if (compiler == null) { + synchronized (this) { + if (compiler == null) { + assert !creatingCompiler : "recursive compiler creation"; + creatingCompiler = true; + try { + compiler = compilerFactory.createCompiler(this); + } catch (RuntimeException t) { + compiler = new ErrorCreatingCompiler(t); + } finally { + creatingCompiler = false; + } + } + } + } + if (compiler instanceof ErrorCreatingCompiler) { + throw ((ErrorCreatingCompiler) compiler).t; + } + return compiler; + } + + /** + * Converts a name to a Java type. This method attempts to resolve {@code name} to a + * {@link ResolvedJavaType}. + * + * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format + * @param accessingType the context of resolution which must be non-null + * @param resolve specifies whether resolution failure results in an unresolved type being + * return or a {@link LinkageError} being thrown + * @return a Java type for {@code name} which is guaranteed to be of type + * {@link ResolvedJavaType} if {@code resolve == true} + * @throws LinkageError if {@code resolve == true} and the resolution failed + * @throws NullPointerException if {@code accessingClass} is {@code null} + */ + public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) { + Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class"); + return lookupTypeInternal(name, accessingType, resolve); + } + + JavaType lookupTypeInternal(String name, HotSpotResolvedObjectType accessingType, boolean resolve) { + // If the name represents a primitive type we can short-circuit the lookup. + if (name.length() == 1) { + JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); + return HotSpotResolvedPrimitiveType.forKind(kind); + } + + // Resolve non-primitive types in the VM. + HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType; + try { + final HotSpotResolvedJavaType klass = compilerToVm.lookupType(name, hsAccessingType, resolve); + + if (klass == null) { + assert resolve == false : name; + return UnresolvedJavaType.create(name); + } + return klass; + } catch (ClassNotFoundException e) { + throw (NoClassDefFoundError) new NoClassDefFoundError().initCause(e); + } + } + + @Override + public JVMCIBackend getHostJVMCIBackend() { + return hostBackend; + } + + @Override + public JVMCIBackend getJVMCIBackend(Class arch) { + assert arch != Architecture.class; + return backends.get(arch); + } + + public Map, JVMCIBackend> getJVMCIBackends() { + return Collections.unmodifiableMap(backends); + } + + @SuppressWarnings("try") + @VMEntryPoint + private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long compileState, int id) { + HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, compileState, id); + CompilationRequestResult result = getCompiler().compileMethod(request); + assert result != null : "compileMethod must always return something"; + HotSpotCompilationRequestResult hsResult; + if (result instanceof HotSpotCompilationRequestResult) { + hsResult = (HotSpotCompilationRequestResult) result; + } else { + Object failure = result.getFailure(); + if (failure != null) { + boolean retry = false; // Be conservative with unknown compiler + hsResult = HotSpotCompilationRequestResult.failure(failure.toString(), retry); + } else { + int inlinedBytecodes = -1; + hsResult = HotSpotCompilationRequestResult.success(inlinedBytecodes); + } + } + return hsResult; + } + + @SuppressWarnings("try") + @VMEntryPoint + private boolean isGCSupported(int gcIdentifier) { + return getCompiler().isGCSupported(gcIdentifier); + } + + /** + * Guard to ensure shut down actions are performed at most once. + */ + private boolean isShutdown; + + /** + * Shuts down the runtime. + */ + @VMEntryPoint + private synchronized void shutdown() throws Exception { + if (!isShutdown) { + isShutdown = true; + // Cleaners are normally only processed when a new Cleaner is + // instantiated so process all remaining cleaners now. + Cleaner.clean(); + + for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { + vmEventListener.notifyShutdown(); + } + } + } + + /** + * Notify on completion of a bootstrap. + */ + @VMEntryPoint + private void bootstrapFinished() throws Exception { + for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { + vmEventListener.notifyBootstrapFinished(); + } + } + + /** + * Notify on successful install into the CodeCache. + * + * @param hotSpotCodeCacheProvider + * @param installedCode + * @param compiledCode + */ + void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) { + for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { + vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compiledCode); + } + } + + /** + * Writes {@code length} bytes from {@code bytes} starting at offset {@code offset} to HotSpot's + * log stream. + * + * @param flush specifies if the log stream should be flushed after writing + * @param canThrow specifies if an error in the {@code bytes}, {@code offset} or {@code length} + * arguments should result in an exception or a negative return value. If + * {@code false}, this call will not perform any heap allocation + * @return 0 on success, -1 if {@code bytes == null && !canThrow}, -2 if {@code !canThrow} and + * copying would cause access of data outside array bounds + * @throws NullPointerException if {@code bytes == null} + * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds + */ + public int writeDebugOutput(byte[] bytes, int offset, int length, boolean flush, boolean canThrow) { + return writeDebugOutput0(compilerToVm, bytes, offset, length, flush, canThrow); + } + + /** + * @see #writeDebugOutput + */ + static int writeDebugOutput0(CompilerToVM vm, byte[] bytes, int offset, int length, boolean flush, boolean canThrow) { + if (bytes == null) { + if (!canThrow) { + return -1; + } + throw new NullPointerException(); + } + if (offset < 0 || length < 0 || offset + length > bytes.length) { + if (!canThrow) { + return -2; + } + throw new ArrayIndexOutOfBoundsException(); + } + if (length <= 8) { + ByteBuffer buffer = ByteBuffer.wrap(bytes, offset, length); + if (length != 8) { + ByteBuffer buffer8 = ByteBuffer.allocate(8); + buffer8.put(buffer); + buffer8.position(8); + buffer = buffer8; + } + buffer.order(ByteOrder.nativeOrder()); + vm.writeDebugOutput(buffer.getLong(0), length, flush); + } else { + Unsafe unsafe = UnsafeAccess.UNSAFE; + long buffer = unsafe.allocateMemory(length); + try { + unsafe.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, buffer, length); + vm.writeDebugOutput(buffer, length, flush); + } finally { + unsafe.freeMemory(buffer); + } + } + return 0; + } + + /** + * Gets an output stream that writes to HotSpot's {@code tty} stream. + */ + public OutputStream getLogStream() { + return new OutputStream() { + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || off > b.length || len < 0 || (off + len) > b.length || (off + len) < 0) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + writeDebugOutput(b, off, len, false, true); + } + + @Override + public void write(int b) throws IOException { + write(new byte[]{(byte) b}, 0, 1); + } + + @Override + public void flush() throws IOException { + compilerToVm.flushDebugOutput(); + } + }; + } + + /** + * Collects the current values of all JVMCI benchmark counters, summed up over all threads. + */ + public long[] collectCounters() { + return compilerToVm.collectCounters(); + } + + /** + * @return the current number of per thread counters. May be set through + * {@code -XX:JVMCICompilerSize=} command line option or the + * {@link #setCountersSize(int)} call. + */ + public int getCountersSize() { + return compilerToVm.getCountersSize(); + } + + /** + * Attempt to enlarge the number of per thread counters available. Requires a safepoint so + * resizing should be rare to avoid performance effects. + * + * @param newSize + * @return false if the resizing failed + */ + public boolean setCountersSize(int newSize) { + return compilerToVm.setCountersSize(newSize); + } + + /** + * The offset from the origin of an array to the first element. + * + * @return the offset in bytes + */ + public int getArrayBaseOffset(JavaKind kind) { + switch (kind) { + case Boolean: + return compilerToVm.ARRAY_BOOLEAN_BASE_OFFSET; + case Byte: + return compilerToVm.ARRAY_BYTE_BASE_OFFSET; + case Char: + return compilerToVm.ARRAY_CHAR_BASE_OFFSET; + case Short: + return compilerToVm.ARRAY_SHORT_BASE_OFFSET; + case Int: + return compilerToVm.ARRAY_INT_BASE_OFFSET; + case Long: + return compilerToVm.ARRAY_LONG_BASE_OFFSET; + case Float: + return compilerToVm.ARRAY_FLOAT_BASE_OFFSET; + case Double: + return compilerToVm.ARRAY_DOUBLE_BASE_OFFSET; + case Object: + return compilerToVm.ARRAY_OBJECT_BASE_OFFSET; + default: + throw new JVMCIError("%s", kind); + } + + } + + /** + * The scale used for the index when accessing elements of an array of this kind. + * + * @return the scale in order to convert the index into a byte offset + */ + public int getArrayIndexScale(JavaKind kind) { + switch (kind) { + case Boolean: + return compilerToVm.ARRAY_BOOLEAN_INDEX_SCALE; + case Byte: + return compilerToVm.ARRAY_BYTE_INDEX_SCALE; + case Char: + return compilerToVm.ARRAY_CHAR_INDEX_SCALE; + case Short: + return compilerToVm.ARRAY_SHORT_INDEX_SCALE; + case Int: + return compilerToVm.ARRAY_INT_INDEX_SCALE; + case Long: + return compilerToVm.ARRAY_LONG_INDEX_SCALE; + case Float: + return compilerToVm.ARRAY_FLOAT_INDEX_SCALE; + case Double: + return compilerToVm.ARRAY_DOUBLE_INDEX_SCALE; + case Object: + return compilerToVm.ARRAY_OBJECT_INDEX_SCALE; + default: + throw new JVMCIError("%s", kind); + + } + } + + /** + * Links each native method in {@code clazz} to an implementation in the JVMCI shared library. + *

    + * A use case for this is a JVMCI compiler implementation that offers an API to Java code + * executing in HotSpot to exercise functionality (mostly) in the JVMCI shared library. For + * example: + * + *

    +     * package com.jcompile;
    +     *
    +     * import java.lang.reflect.Method;
    +     *
    +     * public static class JCompile {
    +     *     static {
    +     *         HotSpotJVMCIRuntime.runtime().registerNativeMethods(JCompile.class);
    +     *     }
    +     *     public static boolean compile(Method method, String[] options) {
    +     *         // Convert to simpler data types for passing/serializing across native interface
    +     *         long metaspaceMethodHandle = getHandle(method);
    +     *         char[] opts = convertToCharArray(options);
    +     *         return compile(metaspaceMethodHandle, opts);
    +     *     }
    +     *     private static native boolean compile0(long metaspaceMethodHandle, char[] options);
    +     *
    +     *     private static long getHandle(Method method) { ... }
    +     *     private static char[] convertToCharArray(String[] a) { ... }
    +     * }
    +     * 
    + * + * The implementation of the native {@code JCompile.compile0} method would be in the JVMCI + * shared library that contains the JVMCI compiler. The {@code JCompile.compile0} implementation + * must be exported as the following JNI-compatible symbol: + * + *
    +     * Java_com_jcompile_JCompile_compile0
    +     * 
    + * + * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#resolving_native_method_names" + * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#creating_the_vm" + * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#invocation_api_functions" + * + * + * @return info about the Java VM in the JVMCI shared library {@code JavaVM*}. The info is + * encoded in a long array as follows: + * + *
    +     *     long[] info = {
    +     *         javaVM, // the {@code JavaVM*} value
    +     *         javaVM->functions->reserved0,
    +     *         javaVM->functions->reserved1,
    +     *         javaVM->functions->reserved2
    +     *     }
    +     *         
    + * + * @throws NullPointerException if {@code clazz == null} + * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. + * {@code -XX:-UseJVMCINativeLibrary}) + * @throws IllegalStateException if the current execution context is the JVMCI shared library + * @throws IllegalArgumentException if {@code clazz} is {@link Class#isPrimitive()} + * @throws UnsatisfiedLinkError if there's a problem linking a native method in {@code clazz} + * (no matching JNI symbol or the native method is already linked to a different + * address) + */ + public long[] registerNativeMethods(Class clazz) { + return compilerToVm.registerNativeMethods(clazz); + } + + /** + * Creates or retrieves an object in the peer runtime that mirrors {@code obj}. The types whose + * objects can be translated are: + *
      + *
    • {@link HotSpotResolvedJavaMethodImpl},
    • + *
    • {@link HotSpotResolvedObjectTypeImpl},
    • + *
    • {@link HotSpotResolvedPrimitiveType},
    • + *
    • {@link IndirectHotSpotObjectConstantImpl},
    • + *
    • {@link DirectHotSpotObjectConstantImpl} and
    • + *
    • {@link HotSpotNmethod}
    • + *
    + * + * This mechanism can be used to pass and return values between the HotSpot and JVMCI shared + * library runtimes. In the receiving runtime, the value can be converted back to an object with + * {@link #unhand(Class, long)}. + * + * @param obj an object for which an equivalent instance in the peer runtime is requested + * @return a JNI global reference to the mirror of {@code obj} in the peer runtime + * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. + * {@code -XX:-UseJVMCINativeLibrary}) + * @throws IllegalArgumentException if {@code obj} is not of a translatable type + * + * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references" + */ + public long translate(Object obj) { + return compilerToVm.translate(obj, Option.ForceTranslateFailure.getString() != null); + } + + private static final Pattern FORCE_TRANSLATE_FAILURE_FILTER_RE = Pattern.compile("(?:(method|type|nmethod)/)?([^:]+)(?::(hotspot|native))?"); + + /** + * Forces translation failure based on {@code translatedObject} and the value of + * {@link Option#ForceTranslateFailure}. The value is zero or more filters separated by a comma. + * The syntax for a filter is: + * + *
    +     *   Filter = [ TypeSelector "/" ] Substring [ ":" JVMCIEnvSelector ] .
    +     *   TypeSelector = "type" | "method" | "nmethod"
    +     *   JVMCIEnvSelector = "native" | "hotspot"
    +     * 
    + * + * For example: + * + *
    +     *   -Djvmci.ForceTranslateFailure=nmethod/StackOverflowError:native,method/computeHash,execute
    +     * 
    + * + * will cause failure of: + *
      + *
    • translating a {@link HotSpotNmethod} to the libjvmci heap whose fully qualified name + * contains "StackOverflowError"
    • + *
    • translating a {@link HotSpotResolvedJavaMethodImpl} to the libjvmci or HotSpot heap whose + * fully qualified name contains "computeHash"
    • + *
    • translating a {@link HotSpotNmethod}, {@link HotSpotResolvedJavaMethodImpl} or + * {@link HotSpotResolvedObjectTypeImpl} to the libjvmci or HotSpot heap whose fully qualified + * name contains "execute"
    • + *
    + */ + @VMEntryPoint + static void postTranslation(Object translatedObject) { + String value = Option.ForceTranslateFailure.getString(); + String toMatch; + String type; + if (translatedObject instanceof HotSpotResolvedJavaMethodImpl) { + toMatch = ((HotSpotResolvedJavaMethodImpl) translatedObject).format("%H.%n"); + type = "method"; + } else if (translatedObject instanceof HotSpotResolvedObjectTypeImpl) { + toMatch = ((HotSpotResolvedObjectTypeImpl) translatedObject).toJavaName(); + type = "type"; + } else if (translatedObject instanceof HotSpotNmethod) { + HotSpotNmethod nmethod = (HotSpotNmethod) translatedObject; + if (nmethod.getMethod() != null) { + toMatch = nmethod.getMethod().format("%H.%n"); + } else { + toMatch = String.valueOf(nmethod.getName()); + } + type = "nmethod"; + } else { + return; + } + String[] filters = value.split(","); + for (String filter : filters) { + Matcher m = FORCE_TRANSLATE_FAILURE_FILTER_RE.matcher(filter); + if (!m.matches()) { + throw new JVMCIError(Option.ForceTranslateFailure + " filter does not match " + FORCE_TRANSLATE_FAILURE_FILTER_RE + ": " + filter); + } + String typeSelector = m.group(1); + String substring = m.group(2); + String jvmciEnvSelector = m.group(3); + if (jvmciEnvSelector != null) { + if (jvmciEnvSelector.equals("native")) { + if (!Services.IS_IN_NATIVE_IMAGE) { + continue; + } + } else { + if (Services.IS_IN_NATIVE_IMAGE) { + continue; + } + } + } + if (typeSelector != null && !typeSelector.equals(type)) { + continue; + } + if (toMatch.contains(substring)) { + throw new JVMCIError("translation of " + translatedObject + " failed due to matching " + Option.ForceTranslateFailure + " filter \"" + filter + "\""); + } + } + } + + /** + * Dereferences and returns the object referred to by the JNI global reference {@code handle}. + * The global reference is deleted prior to returning. Any further use of {@code handle} is + * invalid. + * + * @param handle a JNI global reference to an object in the current runtime + * @return the object referred to by {@code handle} + * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. + * {@code -XX:-UseJVMCINativeLibrary}) + * @throws ClassCastException if the returned object cannot be cast to {@code type} + * + * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references" + * + */ + public T unhand(Class type, long handle) { + return type.cast(compilerToVm.unhand(handle)); + } + + /** + * Determines if the current thread is attached to the peer runtime. + * + * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. + * {@code -XX:-UseJVMCINativeLibrary}) + * @throws IllegalStateException if the peer runtime has not been initialized + */ + public boolean isCurrentThreadAttached() { + return compilerToVm.isCurrentThreadAttached(); + } + + /** + * Gets the address of the HotSpot {@code JavaThread} C++ object for the current thread. This + * will return {@code 0} if called from an unattached JVMCI shared library thread. + */ + public long getCurrentJavaThread() { + return compilerToVm.getCurrentJavaThread(); + } + + /** + * Ensures the current thread is attached to the peer runtime. + * + * @param asDaemon if the thread is not yet attached, should it be attached as a daemon + * @return {@code true} if this call attached the current thread, {@code false} if the current + * thread was already attached + * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. + * {@code -XX:-UseJVMCINativeLibrary}) + * @throws IllegalStateException if the peer runtime has not been initialized or there is an + * error while trying to attach the thread + * @throws ArrayIndexOutOfBoundsException if {@code javaVMInfo} is non-null and is shorter than + * the length of the array returned by {@link #registerNativeMethods} + */ + public boolean attachCurrentThread(boolean asDaemon) { + byte[] name = IS_IN_NATIVE_IMAGE ? Thread.currentThread().getName().getBytes() : null; + return compilerToVm.attachCurrentThread(name, asDaemon); + } + + /** + * Detaches the current thread from the peer runtime. + * + * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. + * {@code -XX:-UseJVMCINativeLibrary}) + * @throws IllegalStateException if the peer runtime has not been initialized or if the current + * thread is not attached or if there is an error while trying to detach the thread + */ + public void detachCurrentThread() { + compilerToVm.detachCurrentThread(); + } + + /** + * Informs HotSpot that no method whose module is in {@code modules} is to be compiled with + * {@link #compileMethod}. + * + * @param modules the set of modules containing JVMCI compiler classes + */ + public void excludeFromJVMCICompilation(Module... modules) { + this.excludeFromJVMCICompilation = modules.clone(); + } + + /** + * Calls {@link System#exit(int)} in HotSpot's runtime. + */ + public void exitHotSpot(int status) { + if (!IS_IN_NATIVE_IMAGE) { + System.exit(status); + } + compilerToVm.callSystemExit(status); + } + + /** + * Writes a message to HotSpot's log stream and then calls {@link System#exit(int)} in HotSpot's + * runtime. + */ + JVMCIError exitHotSpotWithMessage(int status, String format, Object... args) { + byte[] messageBytes = String.format(format, args).getBytes(); + writeDebugOutput(messageBytes, 0, messageBytes.length, true, true); + exitHotSpot(status); + throw JVMCIError.shouldNotReachHere(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.services.Services; + +/** + * Indicates a path in HotSpot JVMCI related code that is unsupported in the current execution + * environment. For example, certain operations are not supported by JVMCI code running in an ahead + * of time compiled {@linkplain Services#IS_IN_NATIVE_IMAGE native image}. This usually reflects + * functionality only needed in non-native image execution that would require a more complex + * implementation to support in a native image. + * + * An example of such functionality is {@link ResolvedJavaType#isLocal()}. This can be conveniently + * implemented when JVMCI is running on the HotSpot heap as we can obtain the {@link Class} mirror + * for the {@link ResolvedJavaType} and call {@link Class#isLocalClass()}. In a native image, there + * is no {@link Class} mirror available in the native image heap so implementing this would involve + * a call into VM native code that in turn would make an upcall into Java code executing on the + * HotSpot heap. We have opted to defer implementing functionality such as this until there's a + * demonstrated need for it. + */ +public class HotSpotJVMCIUnsupportedOperationError extends Error { + + public HotSpotJVMCIUnsupportedOperationError(String reason) { + super(reason); + } + + public HotSpotJVMCIUnsupportedOperationError(String reason, Throwable cause) { + super(reason, cause); + } + + private static final long serialVersionUID = 7782431672678016392L; + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MemoryAccessProvider; +import jdk.vm.ci.meta.PrimitiveConstant; + +/** + * HotSpot implementation of {@link MemoryAccessProvider}. + */ +class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider { + + protected final HotSpotJVMCIRuntime runtime; + + HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntime runtime) { + this.runtime = runtime; + } + + private static long asRawPointer(Constant base) { + if (base instanceof HotSpotMetaspaceConstantImpl) { + MetaspaceObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base); + return meta.getMetaspacePointer(); + } else if (base instanceof PrimitiveConstant) { + PrimitiveConstant prim = (PrimitiveConstant) base; + if (prim.getJavaKind().isNumericInteger()) { + return prim.asLong(); + } + } + throw new IllegalArgumentException(String.valueOf(base)); + } + + @Override + public JavaConstant readPrimitiveConstant(JavaKind kind, Constant baseConstant, long initialDisplacement, int bits) { + if (baseConstant instanceof HotSpotObjectConstantImpl) { + JavaKind readKind = kind; + if (kind.getBitCount() != bits) { + switch (bits) { + case Byte.SIZE: + readKind = JavaKind.Byte; + break; + case Short.SIZE: + readKind = JavaKind.Short; + break; + case Integer.SIZE: + readKind = JavaKind.Int; + break; + case Long.SIZE: + readKind = JavaKind.Long; + break; + default: + throw new IllegalArgumentException(String.valueOf(bits)); + } + } + HotSpotObjectConstantImpl baseObject = (HotSpotObjectConstantImpl) baseConstant; + JavaConstant result = runtime().compilerToVm.readFieldValue(baseObject, null, initialDisplacement, readKind); + if (result != null && kind != readKind) { + return JavaConstant.forPrimitive(kind, result.asLong()); + } + return result; + } else { + long pointer = asRawPointer(baseConstant); + long value; + switch (bits) { + case Byte.SIZE: + value = UNSAFE.getByte(pointer + initialDisplacement); + break; + case Short.SIZE: + value = UNSAFE.getShort(pointer + initialDisplacement); + break; + case Integer.SIZE: + value = UNSAFE.getInt(pointer + initialDisplacement); + break; + case Long.SIZE: + value = UNSAFE.getLong(pointer + initialDisplacement); + break; + default: + throw new IllegalArgumentException(String.valueOf(bits)); + } + return JavaConstant.forPrimitive(kind, value); + } + } + + @Override + public JavaConstant readObjectConstant(Constant base, long displacement) { + if (base instanceof HotSpotObjectConstantImpl) { + return runtime.getCompilerToVM().readFieldValue((HotSpotObjectConstantImpl) base, null, displacement, JavaKind.Object); + } + if (base instanceof HotSpotMetaspaceConstant) { + MetaspaceObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base); + if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl type = (HotSpotResolvedObjectTypeImpl) metaspaceObject; + if (displacement == runtime.getConfig().javaMirrorOffset) { + // Klass::_java_mirror is valid for all Klass* values + return type.getJavaMirror(); + } + return null; + } else { + throw new IllegalArgumentException(String.valueOf(metaspaceObject)); + } + } + return null; + } + + @Override + public JavaConstant readNarrowOopConstant(Constant base, long displacement) { + if (base instanceof HotSpotObjectConstantImpl) { + assert runtime.getConfig().useCompressedOops; + JavaConstant res = runtime.getCompilerToVM().readFieldValue((HotSpotObjectConstantImpl) base, null, displacement, JavaKind.Object); + if (res != null) { + return JavaConstant.NULL_POINTER.equals(res) ? HotSpotCompressedNullConstant.COMPRESSED_NULL : ((HotSpotObjectConstant) res).compress(); + } + } + return null; + } + + private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) { + assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass(); + if (base instanceof HotSpotMetaspaceConstantImpl) { + return runtime.getCompilerToVM().getResolvedJavaType((HotSpotResolvedObjectTypeImpl) ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType(), displacement, compressed); + } else { + return runtime.getCompilerToVM().getResolvedJavaType(((HotSpotObjectConstantImpl) base), displacement, compressed); + } + } + + @Override + public Constant readKlassPointerConstant(Constant base, long displacement) { + HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false); + if (klass == null) { + return JavaConstant.NULL_POINTER; + } + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, false); + } + + @Override + public Constant readNarrowKlassPointerConstant(Constant base, long displacement) { + HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, true); + if (klass == null) { + return HotSpotCompressedNullConstant.COMPRESSED_NULL; + } + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, true); + } + + @Override + public Constant readMethodPointerConstant(Constant base, long displacement) { + assert (base instanceof HotSpotObjectConstantImpl); + HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod((HotSpotObjectConstantImpl) base, displacement); + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.MemoryAccessProvider; + +/** + * HotSpot specific extension of {@link MemoryAccessProvider}. + */ +public interface HotSpotMemoryAccessProvider extends MemoryAccessProvider { + + /** + * @throws IllegalArgumentException if the address computed from {@code base} and + * {@code displacement} does not denote a location holding a narrow oop + */ + JavaConstant readNarrowOopConstant(Constant base, long displacement); + + Constant readKlassPointerConstant(Constant base, long displacement); + + Constant readNarrowKlassPointerConstant(Constant base, long displacement); + + Constant readMethodPointerConstant(Constant base, long displacement); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Objects; + +import jdk.vm.ci.code.CodeUtil; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.DeoptimizationAction; +import jdk.vm.ci.meta.DeoptimizationReason; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.Signature; +import jdk.vm.ci.meta.SpeculationLog; +import jdk.vm.ci.meta.SpeculationLog.NoSpeculationReason; +import jdk.vm.ci.meta.SpeculationLog.Speculation; + +// JaCoCo Exclude + +/** + * HotSpot implementation of {@link MetaAccessProvider}. + */ +public class HotSpotMetaAccessProvider implements MetaAccessProvider { + + protected final HotSpotJVMCIRuntime runtime; + + public HotSpotMetaAccessProvider(HotSpotJVMCIRuntime runtime) { + this.runtime = runtime; + } + + @Override + public ResolvedJavaType lookupJavaType(Class clazz) { + if (clazz == null) { + throw new IllegalArgumentException("Class parameter was null"); + } + return runtime.fromClass(clazz); + } + + @Override + public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) { + if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) { + return null; + } + return ((HotSpotObjectConstant) constant).getType(); + } + + @Override + public Signature parseMethodDescriptor(String signature) { + return new HotSpotSignature(runtime, signature); + } + + @Override + public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) { + return runtime.getCompilerToVM().asResolvedJavaMethod(Objects.requireNonNull(reflectionMethod)); + } + + @Override + public ResolvedJavaField lookupJavaField(Field reflectionField) { + Class fieldHolder = reflectionField.getDeclaringClass(); + + HotSpotResolvedJavaType holder = runtime.fromClass(fieldHolder); + assert holder != null : fieldHolder; + ResolvedJavaField[] fields; + if (Modifier.isStatic(reflectionField.getModifiers())) { + fields = holder.getStaticFields(); + } else { + fields = holder.getInstanceFields(false); + } + ResolvedJavaType fieldType = lookupJavaType(reflectionField.getType()); + for (ResolvedJavaField field : fields) { + if (reflectionField.getName().equals(field.getName()) && field.getType().equals(fieldType)) { + assert Modifier.isStatic(reflectionField.getModifiers()) == field.isStatic(); + return field; + } + } + + throw new JVMCIError("unresolved field %s", reflectionField); + } + + private static int intMaskRight(int n) { + assert n <= 32; + return n == 32 ? -1 : (1 << n) - 1; + } + + @Override + public JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId) { + HotSpotVMConfig config = runtime.getConfig(); + int actionValue = convertDeoptAction(action); + int reasonValue = convertDeoptReason(reason); + int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits); + JavaConstant c = JavaConstant.forInt( + ~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift))); + assert c.asInt() < 0; + return c; + } + + @Override + public DeoptimizationReason decodeDeoptReason(JavaConstant constant) { + HotSpotVMConfig config = runtime.getConfig(); + int reasonValue = ((~constant.asInt()) >> config.deoptimizationReasonShift) & intMaskRight(config.deoptimizationReasonBits); + DeoptimizationReason reason = convertDeoptReason(reasonValue); + return reason; + } + + @Override + public DeoptimizationAction decodeDeoptAction(JavaConstant constant) { + HotSpotVMConfig config = runtime.getConfig(); + int actionValue = ((~constant.asInt()) >> config.deoptimizationActionShift) & intMaskRight(config.deoptimizationActionBits); + DeoptimizationAction action = convertDeoptAction(actionValue); + return action; + } + + @Override + public int decodeDebugId(JavaConstant constant) { + HotSpotVMConfig config = runtime.getConfig(); + return ((~constant.asInt()) >> config.deoptimizationDebugIdShift) & intMaskRight(config.deoptimizationDebugIdBits); + } + + @Override + public JavaConstant encodeSpeculation(Speculation speculation) { + if (speculation.getReason() instanceof NoSpeculationReason) { + return JavaConstant.LONG_0; + } + return ((HotSpotSpeculationLog.HotSpotSpeculation) speculation).getEncoding(); + } + + @Override + public Speculation decodeSpeculation(JavaConstant constant, SpeculationLog speculationLog) { + if (constant.equals(JavaConstant.LONG_0)) { + return SpeculationLog.NO_SPECULATION; + } + if (speculationLog == null) { + throw new IllegalArgumentException("A speculation log is required to decode the speculation denoted by " + constant); + } + return speculationLog.lookupSpeculation(constant); + } + + public int convertDeoptAction(DeoptimizationAction action) { + HotSpotVMConfig config = runtime.getConfig(); + switch (action) { + case None: + return config.deoptActionNone; + case RecompileIfTooManyDeopts: + return config.deoptActionMaybeRecompile; + case InvalidateReprofile: + return config.deoptActionReinterpret; + case InvalidateRecompile: + return config.deoptActionMakeNotEntrant; + case InvalidateStopCompiling: + return config.deoptActionMakeNotCompilable; + default: + throw new JVMCIError("%s", action); + } + } + + public DeoptimizationAction convertDeoptAction(int action) { + HotSpotVMConfig config = runtime.getConfig(); + if (action == config.deoptActionNone) { + return DeoptimizationAction.None; + } + if (action == config.deoptActionMaybeRecompile) { + return DeoptimizationAction.RecompileIfTooManyDeopts; + } + if (action == config.deoptActionReinterpret) { + return DeoptimizationAction.InvalidateReprofile; + } + if (action == config.deoptActionMakeNotEntrant) { + return DeoptimizationAction.InvalidateRecompile; + } + if (action == config.deoptActionMakeNotCompilable) { + return DeoptimizationAction.InvalidateStopCompiling; + } + throw new JVMCIError("%d", action); + } + + public int convertDeoptReason(DeoptimizationReason reason) { + HotSpotVMConfig config = runtime.getConfig(); + switch (reason) { + case None: + return config.deoptReasonNone; + case NullCheckException: + return config.deoptReasonNullCheck; + case BoundsCheckException: + return config.deoptReasonRangeCheck; + case ClassCastException: + return config.deoptReasonClassCheck; + case ArrayStoreException: + return config.deoptReasonArrayCheck; + case UnreachedCode: + return config.deoptReasonUnreached0; + case TypeCheckedInliningViolated: + return config.deoptReasonTypeCheckInlining; + case OptimizedTypeCheckViolated: + return config.deoptReasonOptimizedTypeCheck; + case NotCompiledExceptionHandler: + return config.deoptReasonNotCompiledExceptionHandler; + case Unresolved: + return config.deoptReasonUnresolved; + case JavaSubroutineMismatch: + return config.deoptReasonJsrMismatch; + case ArithmeticException: + return config.deoptReasonDiv0Check; + case RuntimeConstraint: + return config.deoptReasonConstraint; + case LoopLimitCheck: + return config.deoptReasonLoopLimitCheck; + case Aliasing: + return config.deoptReasonAliasing; + case TransferToInterpreter: + return config.deoptReasonTransferToInterpreter; + default: + throw new JVMCIError("%s", reason); + } + } + + public DeoptimizationReason convertDeoptReason(int reason) { + HotSpotVMConfig config = runtime.getConfig(); + if (reason == config.deoptReasonNone) { + return DeoptimizationReason.None; + } + if (reason == config.deoptReasonNullCheck) { + return DeoptimizationReason.NullCheckException; + } + if (reason == config.deoptReasonRangeCheck) { + return DeoptimizationReason.BoundsCheckException; + } + if (reason == config.deoptReasonClassCheck) { + return DeoptimizationReason.ClassCastException; + } + if (reason == config.deoptReasonArrayCheck) { + return DeoptimizationReason.ArrayStoreException; + } + if (reason == config.deoptReasonUnreached0) { + return DeoptimizationReason.UnreachedCode; + } + if (reason == config.deoptReasonTypeCheckInlining) { + return DeoptimizationReason.TypeCheckedInliningViolated; + } + if (reason == config.deoptReasonOptimizedTypeCheck) { + return DeoptimizationReason.OptimizedTypeCheckViolated; + } + if (reason == config.deoptReasonNotCompiledExceptionHandler) { + return DeoptimizationReason.NotCompiledExceptionHandler; + } + if (reason == config.deoptReasonUnresolved) { + return DeoptimizationReason.Unresolved; + } + if (reason == config.deoptReasonJsrMismatch) { + return DeoptimizationReason.JavaSubroutineMismatch; + } + if (reason == config.deoptReasonDiv0Check) { + return DeoptimizationReason.ArithmeticException; + } + if (reason == config.deoptReasonConstraint) { + return DeoptimizationReason.RuntimeConstraint; + } + if (reason == config.deoptReasonLoopLimitCheck) { + return DeoptimizationReason.LoopLimitCheck; + } + if (reason == config.deoptReasonAliasing) { + return DeoptimizationReason.Aliasing; + } + if (reason == config.deoptReasonTransferToInterpreter) { + return DeoptimizationReason.TransferToInterpreter; + } + throw new JVMCIError("%x", reason); + } + + @Override + public long getMemorySize(JavaConstant constant) { + if (constant.getJavaKind() == JavaKind.Object) { + HotSpotResolvedObjectType lookupJavaType = lookupJavaType(constant); + + if (lookupJavaType == null) { + return 0; + } else { + if (lookupJavaType.isArray()) { + int length = runtime.getHostJVMCIBackend().getConstantReflection().readArrayLength(constant); + ResolvedJavaType elementType = lookupJavaType.getComponentType(); + JavaKind elementKind = elementType.getJavaKind(); + final int headerSize = runtime.getArrayBaseOffset(elementKind); + int sizeOfElement = runtime.getArrayIndexScale(elementKind); + int log2ElementSize = CodeUtil.log2(sizeOfElement); + return computeArrayAllocationSize(length, headerSize, log2ElementSize); + } + return lookupJavaType.instanceSize(); + } + } else { + return constant.getJavaKind().getByteCount(); + } + } + + /** + * Computes the size of the memory chunk allocated for an array. This size accounts for the + * array header size, body size and any padding after the last element to satisfy object + * alignment requirements. + * + * @param length the number of elements in the array + * @param headerSize the size of the array header + * @param log2ElementSize log2 of the size of an element in the array + * @return the size of the memory chunk + */ + public int computeArrayAllocationSize(int length, int headerSize, int log2ElementSize) { + HotSpotVMConfig config = runtime.getConfig(); + int alignment = config.objectAlignment; + int size = (length << log2ElementSize) + headerSize + (alignment - 1); + int mask = ~(alignment - 1); + return size & mask; + } + + @Override + public int getArrayBaseOffset(JavaKind kind) { + return runtime.getArrayBaseOffset(kind); + } + + @Override + public int getArrayIndexScale(JavaKind kind) { + return runtime.getArrayIndexScale(kind); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaData.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaData.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaData.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaData.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import jdk.vm.ci.code.TargetDescription; + +public class HotSpotMetaData { + private byte[] pcDescBytes; + private byte[] scopesDescBytes; + private byte[] relocBytes; + private byte[] exceptionBytes; + private byte[] implicitExceptionBytes; + private byte[] oopMaps; + private Object[] metadata; + + public HotSpotMetaData(TargetDescription target, HotSpotCompiledCode compiledMethod) { + // Assign the fields default values... + pcDescBytes = new byte[0]; + scopesDescBytes = new byte[0]; + relocBytes = new byte[0]; + exceptionBytes = new byte[0]; + oopMaps = new byte[0]; + metadata = new String[0]; + // ...some of them will be overwritten by the VM: + runtime().getCompilerToVM().getMetadata(target, compiledMethod, this); + } + + public byte[] pcDescBytes() { + return pcDescBytes; + } + + public byte[] scopesDescBytes() { + return scopesDescBytes; + } + + public byte[] relocBytes() { + return relocBytes; + } + + public byte[] exceptionBytes() { + return exceptionBytes; + } + + public byte[] implicitExceptionBytes() { + return implicitExceptionBytes; + } + + public byte[] oopMaps() { + return oopMaps; + } + + public Object[] metadataEntries() { + return metadata; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2014, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.Objects; + +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.VMConstant; + +final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant { + + static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceObject metaspaceObject, boolean compressed) { + return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed); + } + + static MetaspaceObject getMetaspaceObject(Constant constant) { + return ((HotSpotMetaspaceConstantImpl) constant).metaspaceObject; + } + + private final MetaspaceObject metaspaceObject; + private final boolean compressed; + + private HotSpotMetaspaceConstantImpl(MetaspaceObject metaspaceObject, boolean compressed) { + this.metaspaceObject = metaspaceObject; + this.compressed = compressed; + } + + @Override + public int hashCode() { + return System.identityHashCode(metaspaceObject) ^ (compressed ? 1 : 2); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof HotSpotMetaspaceConstantImpl)) { + return false; + } + + HotSpotMetaspaceConstantImpl other = (HotSpotMetaspaceConstantImpl) o; + return Objects.equals(this.metaspaceObject, other.metaspaceObject) && this.compressed == other.compressed; + } + + @Override + public String toValueString() { + return String.format("meta{%s%s}", metaspaceObject, compressed ? ";compressed" : ""); + } + + @Override + public String toString() { + return toValueString(); + } + + @Override + public boolean isDefaultForKind() { + return false; + } + + @Override + public boolean isCompressed() { + return compressed; + } + + @Override + public Constant compress() { + assert !isCompressed(); + HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, true); + assert res.isCompressed(); + return res; + } + + @Override + public Constant uncompress() { + assert isCompressed(); + HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, false); + assert !res.isCompressed(); + return res; + } + + @Override + public HotSpotResolvedObjectType asResolvedJavaType() { + if (metaspaceObject instanceof HotSpotResolvedObjectType) { + return (HotSpotResolvedObjectType) metaspaceObject; + } + return null; + } + + @Override + public HotSpotResolvedJavaMethod asResolvedJavaMethod() { + if (metaspaceObject instanceof HotSpotResolvedJavaMethod) { + return (HotSpotResolvedJavaMethod) metaspaceObject; + } + return null; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.VMConstant; + +public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant { + + HotSpotResolvedObjectType asResolvedJavaType(); + + HotSpotResolvedJavaMethod asResolvedJavaMethod(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaMethodProfile; +import jdk.vm.ci.meta.JavaTypeProfile; +import jdk.vm.ci.meta.ProfilingInfo; +import jdk.vm.ci.meta.TriState; + +/** + * Base class for accessing the different kinds of data in a HotSpot {@code MethodData}. This is + * similar to {@link ProfilingInfo}, but most methods require a {@link HotSpotMethodData} and the + * exact position within the method data. + */ +abstract class HotSpotMethodDataAccessor { + + final int tag; + final int staticSize; + final HotSpotMethodData.VMState state; + final HotSpotVMConfig config; + + protected HotSpotMethodDataAccessor(HotSpotMethodData.VMState state, int tag, int staticSize) { + this.state = state; + this.config = state.config; + this.tag = tag; + this.staticSize = staticSize; + } + + /** + * Returns the tag stored in the LayoutData header. + * + * @return tag stored in the LayoutData header + */ + int getTag() { + return tag; + } + + static int readTag(HotSpotVMConfig config, HotSpotMethodData data, int position) { + final int tag = data.readUnsignedByte(position, config.dataLayoutTagOffset); + assert tag >= config.dataLayoutNoTag && tag <= config.dataLayoutSpeculativeTrapDataTag : "profile data tag out of bounds: " + tag; + return tag; + } + + /** + * Returns the BCI stored in the LayoutData header. + * + * @return an integer between 0 and {@link Short#MAX_VALUE} inclusive, or -1 if not supported + */ + int getBCI(HotSpotMethodData data, int position) { + return data.readUnsignedShort(position, config.dataLayoutBCIOffset); + } + + /** + * Computes the size for the specific data at the given position. + * + * @return a value greater than 0 + */ + final int getSize(HotSpotMethodData data, int position) { + int size = staticSize + getDynamicSize(data, position); + // Sanity check against VM + int vmSize = HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position); + assert size == vmSize : size + " != " + vmSize; + return size; + } + + TriState getExceptionSeen(HotSpotMethodData data, int position) { + final int exceptionsMask = 1 << config.bitDataExceptionSeenFlag; + return TriState.get((getFlags(data, position) & exceptionsMask) != 0); + } + + /** + * @param data + * @param position + */ + JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) { + return null; + } + + /** + * @param data + * @param position + */ + JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) { + return null; + } + + /** + * @param data + * @param position + */ + double getBranchTakenProbability(HotSpotMethodData data, int position) { + return -1; + } + + /** + * @param data + * @param position + */ + double[] getSwitchProbabilities(HotSpotMethodData data, int position) { + return null; + } + + /** + * @param data + * @param position + */ + int getExecutionCount(HotSpotMethodData data, int position) { + return -1; + } + + /** + * @param data + * @param position + */ + TriState getNullSeen(HotSpotMethodData data, int position) { + return TriState.UNKNOWN; + } + + protected int getFlags(HotSpotMethodData data, int position) { + return data.readUnsignedByte(position, config.dataLayoutFlagsOffset); + } + + /** + * @param data + * @param position + */ + protected int getDynamicSize(HotSpotMethodData data, int position) { + return 0; + } + + abstract StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos); + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,890 @@ +/* + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static java.lang.String.format; +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import java.util.Arrays; + +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.internal.misc.Unsafe; +import jdk.vm.ci.meta.DeoptimizationReason; +import jdk.vm.ci.meta.JavaMethodProfile; +import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod; +import jdk.vm.ci.meta.JavaTypeProfile; +import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.TriState; + +/** + * Access to a HotSpot {@code MethodData} structure (defined in methodData.hpp). + */ +final class HotSpotMethodData { + + /** + * VM state that can be reset when building an AOT image. + */ + static final class VMState { + final HotSpotVMConfig config = config(); + final HotSpotMethodDataAccessor noDataNoExceptionAccessor = new NoMethodData(this, config.dataLayoutNoTag, TriState.FALSE); + final HotSpotMethodDataAccessor noDataExceptionPossiblyNotRecordedAccessor = new NoMethodData(this, config.dataLayoutNoTag, TriState.UNKNOWN); + final int noDataSize = cellIndexToOffset(0); + final int bitDataSize = cellIndexToOffset(0); + final int bitDataNullSeenFlag = 1 << config.bitDataNullSeenFlag; + final int counterDataSize = cellIndexToOffset(1); + final int counterDataCountOffset = cellIndexToOffset(config.methodDataCountOffset); + final int jumpDataSize = cellIndexToOffset(2); + final int takenCountOffset = cellIndexToOffset(config.jumpDataTakenOffset); + final int takenDisplacementOffset = cellIndexToOffset(config.jumpDataDisplacementOffset); + final int typeDataRowSize = cellsToBytes(config.receiverTypeDataReceiverTypeRowCellCount); + + final int nonprofiledCountOffset = cellIndexToOffset(config.receiverTypeDataNonprofiledCountOffset); + final int typeDataFirstTypeOffset = cellIndexToOffset(config.receiverTypeDataReceiver0Offset); + final int typeDataFirstTypeCountOffset = cellIndexToOffset(config.receiverTypeDataCount0Offset); + + final int typeCheckDataSize = cellIndexToOffset(2) + typeDataRowSize * config.typeProfileWidth; + final int virtualCallDataSize = cellIndexToOffset(2) + typeDataRowSize * (config.typeProfileWidth + config.methodProfileWidth); + final int virtualCallDataFirstMethodOffset = typeDataFirstTypeOffset + typeDataRowSize * config.typeProfileWidth; + final int virtualCallDataFirstMethodCountOffset = typeDataFirstTypeCountOffset + typeDataRowSize * config.typeProfileWidth; + + final int retDataRowSize = cellsToBytes(3); + final int retDataSize = cellIndexToOffset(1) + retDataRowSize * config.bciProfileWidth; + + final int branchDataSize = cellIndexToOffset(3); + final int notTakenCountOffset = cellIndexToOffset(config.branchDataNotTakenOffset); + + final int arrayDataLengthOffset = cellIndexToOffset(config.arrayDataArrayLenOffset); + final int arrayDataStartOffset = cellIndexToOffset(config.arrayDataArrayStartOffset); + + final int multiBranchDataSize = cellIndexToOffset(1); + final int multiBranchDataRowSizeInCells = config.multiBranchDataPerCaseCellCount; + final int multiBranchDataRowSize = cellsToBytes(multiBranchDataRowSizeInCells); + final int multiBranchDataFirstCountOffset = arrayDataStartOffset + cellsToBytes(0); + final int multiBranchDataFirstDisplacementOffset = arrayDataStartOffset + cellsToBytes(1); + + final int argInfoDataSize = cellIndexToOffset(1); + + // sorted by tag + // @formatter:off + final HotSpotMethodDataAccessor[] profileDataAccessors = { + null, + new BitData(this, config.dataLayoutBitDataTag), + new CounterData(this, config.dataLayoutCounterDataTag), + new JumpData(this, config.dataLayoutJumpDataTag), + new ReceiverTypeData(this, config.dataLayoutReceiverTypeDataTag), + new VirtualCallData(this, config.dataLayoutVirtualCallDataTag), + new RetData(this, config.dataLayoutRetDataTag), + new BranchData(this, config.dataLayoutBranchDataTag), + new MultiBranchData(this, config.dataLayoutMultiBranchDataTag), + new ArgInfoData(this, config.dataLayoutArgInfoDataTag), + new UnknownProfileData(this, config.dataLayoutCallTypeDataTag), + new VirtualCallTypeData(this, config.dataLayoutVirtualCallTypeDataTag), + new UnknownProfileData(this, config.dataLayoutParametersTypeDataTag), + new UnknownProfileData(this, config.dataLayoutSpeculativeTrapDataTag), + }; + // @formatter:on + + private boolean checkAccessorTags() { + int expectedTag = 0; + for (HotSpotMethodDataAccessor accessor : profileDataAccessors) { + if (expectedTag == 0) { + assert accessor == null; + } else { + assert accessor.tag == expectedTag : expectedTag + " != " + accessor.tag + " " + accessor; + } + expectedTag++; + } + return true; + } + + private VMState() { + assert checkAccessorTags(); + } + + private static int truncateLongToInt(long value) { + return value > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) value; + } + + private int computeFullOffset(int position, int offsetInBytes) { + return config.methodDataOopDataOffset + position + offsetInBytes; + } + + private int cellIndexToOffset(int cells) { + return config.dataLayoutHeaderSize + cellsToBytes(cells); + } + + private int cellsToBytes(int cells) { + return cells * config.dataLayoutCellSize; + } + + /** + * Singleton instance lazily initialized via double-checked locking. + */ + @NativeImageReinitialize private static volatile VMState instance; + + static VMState instance() { + VMState result = instance; + if (result == null) { + synchronized (VMState.class) { + result = instance; + if (result == null) { + instance = result = new VMState(); + } + } + } + return result; + } + } + + /** + * Reference to the C++ MethodData object. + */ + final long metaspaceMethodData; + private final HotSpotResolvedJavaMethodImpl method; + private final VMState state; + + HotSpotMethodData(long metaspaceMethodData, HotSpotResolvedJavaMethodImpl method) { + this.metaspaceMethodData = metaspaceMethodData; + this.method = method; + this.state = VMState.instance(); + } + + /** + * @return value of the MethodData::_data_size field + */ + private int normalDataSize() { + return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataDataSize); + } + + /** + * Returns the size of the extra data records. This method does the same calculation as + * MethodData::extra_data_size(). + * + * @return size of extra data records + */ + private int extraDataSize() { + final int extraDataBase = state.config.methodDataOopDataOffset + normalDataSize(); + final int extraDataLimit = UNSAFE.getInt(metaspaceMethodData + state.config.methodDataSize); + return extraDataLimit - extraDataBase; + } + + public boolean hasNormalData() { + return normalDataSize() > 0; + } + + public boolean hasExtraData() { + return extraDataSize() > 0; + } + + public int getExtraDataBeginOffset() { + return normalDataSize(); + } + + public boolean isWithin(int position) { + return position >= 0 && position < normalDataSize() + extraDataSize(); + } + + public int getDeoptimizationCount(DeoptimizationReason reason) { + HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess(); + int reasonIndex = metaAccess.convertDeoptReason(reason); + return UNSAFE.getByte(metaspaceMethodData + state.config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF; + } + + public int getOSRDeoptimizationCount(DeoptimizationReason reason) { + HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess(); + int reasonIndex = metaAccess.convertDeoptReason(reason); + return UNSAFE.getByte(metaspaceMethodData + state.config.methodDataOopTrapHistoryOffset + state.config.deoptReasonOSROffset + reasonIndex) & 0xFF; + } + + public int getDecompileCount() { + return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataDecompiles); + } + + public int getOverflowRecompileCount() { + return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataOverflowRecompiles); + } + + public int getOverflowTrapCount() { + return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataOverflowTraps); + } + + public HotSpotMethodDataAccessor getNormalData(int position) { + if (position >= normalDataSize()) { + return null; + } + + return getData(position); + } + + public HotSpotMethodDataAccessor getExtraData(int position) { + if (position >= normalDataSize() + extraDataSize()) { + return null; + } + HotSpotMethodDataAccessor data = getData(position); + if (data != null) { + return data; + } + return data; + } + + public static HotSpotMethodDataAccessor getNoDataAccessor(boolean exceptionPossiblyNotRecorded) { + if (exceptionPossiblyNotRecorded) { + return VMState.instance().noDataExceptionPossiblyNotRecordedAccessor; + } else { + return VMState.instance().noDataNoExceptionAccessor; + } + } + + private HotSpotMethodDataAccessor getData(int position) { + assert position >= 0 : "out of bounds"; + final int tag = HotSpotMethodDataAccessor.readTag(state.config, this, position); + HotSpotMethodDataAccessor accessor = state.profileDataAccessors[tag]; + assert accessor == null || accessor.getTag() == tag : "wrong data accessor " + accessor + " for tag " + tag; + return accessor; + } + + int readUnsignedByte(int position, int offsetInBytes) { + long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); + return UNSAFE.getByte(metaspaceMethodData + fullOffsetInBytes) & 0xFF; + } + + int readUnsignedShort(int position, int offsetInBytes) { + long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); + return UNSAFE.getShort(metaspaceMethodData + fullOffsetInBytes) & 0xFFFF; + } + + /** + * Since the values are stored in cells (platform words) this method uses + * {@link Unsafe#getAddress} to read the right value on both little and big endian machines. + */ + private long readUnsignedInt(int position, int offsetInBytes) { + long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); + return UNSAFE.getAddress(metaspaceMethodData + fullOffsetInBytes) & 0xFFFFFFFFL; + } + + private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) { + long value = readUnsignedInt(position, offsetInBytes); + return VMState.truncateLongToInt(value); + } + + /** + * Since the values are stored in cells (platform words) this method uses + * {@link Unsafe#getAddress} to read the right value on both little and big endian machines. + */ + private int readInt(int position, int offsetInBytes) { + long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); + return (int) UNSAFE.getAddress(metaspaceMethodData + fullOffsetInBytes); + } + + private HotSpotResolvedJavaMethod readMethod(int position, int offsetInBytes) { + long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); + return compilerToVM().getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes); + } + + private HotSpotResolvedObjectTypeImpl readKlass(int position, int offsetInBytes) { + long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); + return compilerToVM().getResolvedJavaType(metaspaceMethodData + fullOffsetInBytes, false); + } + + /** + * Returns whether profiling ran long enough that the profile information is mature. Other + * informational data will still be valid even if the profile isn't mature. + */ + public boolean isProfileMature() { + return runtime().getCompilerToVM().isMature(metaspaceMethodData); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + String nl = String.format("%n"); + String nlIndent = String.format("%n%38s", ""); + sb.append("Raw method data for "); + sb.append(method.format("%H.%n(%p)")); + sb.append(":"); + sb.append(nl); + sb.append(String.format("nof_decompiles(%d) nof_overflow_recompiles(%d) nof_overflow_traps(%d)%n", + getDecompileCount(), getOverflowRecompileCount(), getOverflowTrapCount())); + if (hasNormalData()) { + int pos = 0; + HotSpotMethodDataAccessor data; + while ((data = getNormalData(pos)) != null) { + if (pos != 0) { + sb.append(nl); + } + int bci = data.getBCI(this, pos); + sb.append(String.format("%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName())); + sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent)); + pos = pos + data.getSize(this, pos); + } + } + + if (hasExtraData()) { + int pos = getExtraDataBeginOffset(); + HotSpotMethodDataAccessor data; + while ((data = getExtraData(pos)) != null) { + if (pos == getExtraDataBeginOffset()) { + sb.append(nl).append("--- Extra data:"); + } + int bci = data.getBCI(this, pos); + sb.append(String.format("%n%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName())); + sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent)); + pos = pos + data.getSize(this, pos); + } + + } + return sb.toString(); + } + + static class NoMethodData extends HotSpotMethodDataAccessor { + + private final TriState exceptionSeen; + + protected NoMethodData(VMState state, int tag, TriState exceptionSeen) { + super(state, tag, state.noDataSize); + this.exceptionSeen = exceptionSeen; + } + + @Override + public int getBCI(HotSpotMethodData data, int position) { + return -1; + } + + @Override + public TriState getExceptionSeen(HotSpotMethodData data, int position) { + return exceptionSeen; + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb; + } + } + + static class BitData extends HotSpotMethodDataAccessor { + + private BitData(VMState state, int tag) { + super(state, tag, state.bitDataSize); + } + + protected BitData(VMState state, int tag, int staticSize) { + super(state, tag, staticSize); + } + + @Override + public TriState getNullSeen(HotSpotMethodData data, int position) { + return TriState.get((getFlags(data, position) & state.bitDataNullSeenFlag) != 0); + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("exception_seen(%s)", getExceptionSeen(data, pos))); + } + } + + static class CounterData extends BitData { + + CounterData(VMState state, int tag) { + super(state, tag, state.counterDataSize); + } + + protected CounterData(VMState state, int tag, int staticSize) { + super(state, tag, staticSize); + } + + @Override + public int getExecutionCount(HotSpotMethodData data, int position) { + return getCounterValue(data, position); + } + + protected int getCounterValue(HotSpotMethodData data, int position) { + return data.readUnsignedIntAsSignedInt(position, state.counterDataCountOffset); + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("count(%d) null_seen(%s) exception_seen(%s)", getCounterValue(data, pos), getNullSeen(data, pos), getExceptionSeen(data, pos))); + } + } + + static class JumpData extends HotSpotMethodDataAccessor { + + JumpData(VMState state, int tag) { + super(state, tag, state.jumpDataSize); + } + + protected JumpData(VMState state, int tag, int staticSize) { + super(state, tag, staticSize); + } + + @Override + public double getBranchTakenProbability(HotSpotMethodData data, int position) { + return getExecutionCount(data, position) != 0 ? 1 : 0; + } + + @Override + public int getExecutionCount(HotSpotMethodData data, int position) { + return data.readUnsignedIntAsSignedInt(position, state.takenCountOffset); + } + + public int getTakenDisplacement(HotSpotMethodData data, int position) { + return data.readInt(position, state.takenDisplacementOffset); + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("taken(%d) displacement(%d)", getExecutionCount(data, pos), getTakenDisplacement(data, pos))); + } + } + + static class RawItemProfile { + final int entries; + final T[] items; + final long[] counts; + final long totalCount; + + RawItemProfile(int entries, T[] items, long[] counts, long totalCount) { + this.entries = entries; + this.items = items; + this.counts = counts; + this.totalCount = totalCount; + } + } + + abstract static class AbstractTypeData extends CounterData { + + protected AbstractTypeData(VMState state, int tag, int staticSize) { + super(state, tag, staticSize); + } + + @Override + public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) { + return createTypeProfile(getNullSeen(data, position), getRawTypeProfile(data, position)); + } + + private RawItemProfile getRawTypeProfile(HotSpotMethodData data, int position) { + int typeProfileWidth = config.typeProfileWidth; + + ResolvedJavaType[] types = new ResolvedJavaType[typeProfileWidth]; + long[] counts = new long[typeProfileWidth]; + long totalCount = 0; + int entries = 0; + + outer: for (int i = 0; i < typeProfileWidth; i++) { + HotSpotResolvedObjectTypeImpl receiverKlass = data.readKlass(position, getTypeOffset(i)); + if (receiverKlass != null) { + HotSpotResolvedObjectTypeImpl klass = receiverKlass; + long count = data.readUnsignedInt(position, getTypeCountOffset(i)); + /* + * Because of races in the profile collection machinery it's possible for a + * class to appear multiple times so merge them to make the profile look + * rational. + */ + for (int j = 0; j < entries; j++) { + if (types[j].equals(klass)) { + totalCount += count; + counts[j] += count; + continue outer; + } + } + types[entries] = klass; + totalCount += count; + counts[entries] = count; + entries++; + } + } + + totalCount += getTypesNotRecordedExecutionCount(data, position); + return new RawItemProfile<>(entries, types, counts, totalCount); + } + + protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position); + + public int getNonprofiledCount(HotSpotMethodData data, int position) { + return data.readUnsignedIntAsSignedInt(position, state.nonprofiledCountOffset); + } + + private JavaTypeProfile createTypeProfile(TriState nullSeen, RawItemProfile profile) { + if (profile.entries <= 0 || profile.totalCount <= 0) { + return null; + } + + ProfiledType[] ptypes = new ProfiledType[profile.entries]; + double totalProbability = 0.0; + for (int i = 0; i < profile.entries; i++) { + double p = profile.counts[i]; + p = p / profile.totalCount; + totalProbability += p; + ptypes[i] = new ProfiledType(profile.items[i], p); + } + + Arrays.sort(ptypes); + + double notRecordedTypeProbability = profile.entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); + assert notRecordedTypeProbability == 0 || profile.entries == config.typeProfileWidth; + return new JavaTypeProfile(nullSeen, notRecordedTypeProbability, ptypes); + } + + private int getTypeOffset(int row) { + return state.typeDataFirstTypeOffset + row * state.typeDataRowSize; + } + + protected int getTypeCountOffset(int row) { + return state.typeDataFirstTypeCountOffset + row * state.typeDataRowSize; + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + RawItemProfile profile = getRawTypeProfile(data, pos); + TriState nullSeen = getNullSeen(data, pos); + TriState exceptionSeen = getExceptionSeen(data, pos); + sb.append(format("count(%d) null_seen(%s) exception_seen(%s) nonprofiled_count(%d) entries(%d)", getCounterValue(data, pos), nullSeen, exceptionSeen, + getNonprofiledCount(data, pos), profile.entries)); + for (int i = 0; i < profile.entries; i++) { + long count = profile.counts[i]; + sb.append(format("%n %s (%d, %4.2f)", profile.items[i].toJavaName(), count, (double) count / profile.totalCount)); + } + return sb; + } + } + + static class ReceiverTypeData extends AbstractTypeData { + + ReceiverTypeData(VMState state, int tag) { + super(state, tag, state.typeCheckDataSize); + } + + protected ReceiverTypeData(VMState state, int tag, int staticSize) { + super(state, tag, staticSize); + } + + @Override + public int getExecutionCount(HotSpotMethodData data, int position) { + return -1; + } + + @Override + protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) { + return getNonprofiledCount(data, position); + } + } + + static class VirtualCallData extends ReceiverTypeData { + + VirtualCallData(VMState state, int tag) { + super(state, tag, state.virtualCallDataSize); + } + + protected VirtualCallData(VMState state, int tag, int staticSize) { + super(state, tag, staticSize); + } + + @Override + public int getExecutionCount(HotSpotMethodData data, int position) { + final int typeProfileWidth = config.typeProfileWidth; + + long total = 0; + for (int i = 0; i < typeProfileWidth; i++) { + total += data.readUnsignedInt(position, getTypeCountOffset(i)); + } + + total += getCounterValue(data, position); + return VMState.truncateLongToInt(total); + } + + @Override + protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) { + return getCounterValue(data, position); + } + + private long getMethodsNotRecordedExecutionCount(HotSpotMethodData data, int position) { + return data.readUnsignedIntAsSignedInt(position, state.nonprofiledCountOffset); + } + + @Override + public JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) { + return createMethodProfile(getRawMethodProfile(data, position)); + } + + private RawItemProfile getRawMethodProfile(HotSpotMethodData data, int position) { + int profileWidth = config.methodProfileWidth; + + ResolvedJavaMethod[] methods = new ResolvedJavaMethod[profileWidth]; + long[] counts = new long[profileWidth]; + long totalCount = 0; + int entries = 0; + + for (int i = 0; i < profileWidth; i++) { + HotSpotResolvedJavaMethod method = data.readMethod(position, getMethodOffset(i)); + if (method != null) { + methods[entries] = method; + long count = data.readUnsignedInt(position, getMethodCountOffset(i)); + totalCount += count; + counts[entries] = count; + + entries++; + } + } + + totalCount += getMethodsNotRecordedExecutionCount(data, position); + + // Fixup the case of C1's inability to optimize profiling of a statically bindable call + // site. If it's a monomorphic call site, attribute all the counts to the first type (if + // any is recorded). + if (entries == 1) { + counts[0] = totalCount; + } + + return new RawItemProfile<>(entries, methods, counts, totalCount); + } + + private JavaMethodProfile createMethodProfile(RawItemProfile profile) { + if (profile.entries <= 0 || profile.totalCount <= 0) { + return null; + } + + ProfiledMethod[] pmethods = new ProfiledMethod[profile.entries]; + double totalProbability = 0.0; + for (int i = 0; i < profile.entries; i++) { + double p = profile.counts[i]; + p = p / profile.totalCount; + totalProbability += p; + pmethods[i] = new ProfiledMethod(profile.items[i], p); + } + + Arrays.sort(pmethods); + + double notRecordedMethodProbability = profile.entries < config.methodProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); + assert notRecordedMethodProbability == 0 || profile.entries == config.methodProfileWidth; + return new JavaMethodProfile(notRecordedMethodProbability, pmethods); + } + + private int getMethodOffset(int row) { + return state.virtualCallDataFirstMethodOffset + row * state.typeDataRowSize; + } + + private int getMethodCountOffset(int row) { + return state.virtualCallDataFirstMethodCountOffset + row * state.typeDataRowSize; + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + RawItemProfile profile = getRawMethodProfile(data, pos); + super.appendTo(sb.append(format("exception_seen(%s) ", getExceptionSeen(data, pos))), data, pos).append(format("%nmethod_entries(%d)", profile.entries)); + for (int i = 0; i < profile.entries; i++) { + long count = profile.counts[i]; + sb.append(format("%n %s (%d, %4.2f)", profile.items[i].format("%H.%n(%p)"), count, (double) count / profile.totalCount)); + } + return sb; + } + } + + static class VirtualCallTypeData extends VirtualCallData { + + VirtualCallTypeData(VMState state, int tag) { + super(state, tag, 0); + } + + @Override + protected int getDynamicSize(HotSpotMethodData data, int position) { + assert staticSize == 0; + return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position); + } + } + + static class RetData extends CounterData { + + RetData(VMState state, int tag) { + super(state, tag, state.retDataSize); + } + } + + static class BranchData extends JumpData { + + BranchData(VMState state, int tag) { + super(state, tag, state.branchDataSize); + } + + @Override + public double getBranchTakenProbability(HotSpotMethodData data, int position) { + long takenCount = data.readUnsignedInt(position, state.takenCountOffset); + long notTakenCount = data.readUnsignedInt(position, state.notTakenCountOffset); + long total = takenCount + notTakenCount; + + return total <= 0 ? -1 : takenCount / (double) total; + } + + @Override + public int getExecutionCount(HotSpotMethodData data, int position) { + long count = data.readUnsignedInt(position, state.takenCountOffset) + data.readUnsignedInt(position, state.notTakenCountOffset); + return VMState.truncateLongToInt(count); + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + long taken = data.readUnsignedInt(pos, state.takenCountOffset); + long notTaken = data.readUnsignedInt(pos, state.notTakenCountOffset); + double takenProbability = getBranchTakenProbability(data, pos); + return sb.append(format("taken(%d, %4.2f) not_taken(%d, %4.2f) displacement(%d)", taken, takenProbability, notTaken, 1.0D - takenProbability, getTakenDisplacement(data, pos))); + } + } + + static class ArrayData extends HotSpotMethodDataAccessor { + + ArrayData(VMState state, int tag, int staticSize) { + super(state, tag, staticSize); + } + + @Override + protected int getDynamicSize(HotSpotMethodData data, int position) { + return state.cellsToBytes(getLength(data, position)); + } + + protected int getLength(HotSpotMethodData data, int position) { + return data.readInt(position, state.arrayDataLengthOffset); + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("length(%d)", getLength(data, pos))); + } + } + + static class MultiBranchData extends ArrayData { + + MultiBranchData(VMState state, int tag) { + super(state, tag, state.multiBranchDataSize); + } + + @Override + public double[] getSwitchProbabilities(HotSpotMethodData data, int position) { + int arrayLength = getLength(data, position); + assert arrayLength > 0 : "switch must have at least the default case"; + assert arrayLength % state.multiBranchDataRowSizeInCells == 0 : "array must have full rows"; + + int length = arrayLength / state.multiBranchDataRowSizeInCells; + long totalCount = 0; + double[] result = new double[length]; + + // default case is first in HotSpot but last for the compiler + long count = readCount(data, position, 0); + totalCount += count; + result[length - 1] = count; + + for (int i = 1; i < length; i++) { + count = readCount(data, position, i); + totalCount += count; + result[i - 1] = count; + } + + if (totalCount <= 0) { + return null; + } else { + for (int i = 0; i < length; i++) { + result[i] = result[i] / totalCount; + } + return result; + } + } + + private long readCount(HotSpotMethodData data, int position, int i) { + int offset; + long count; + offset = getCountOffset(i); + count = data.readUnsignedInt(position, offset); + return count; + } + + @Override + public int getExecutionCount(HotSpotMethodData data, int position) { + int arrayLength = getLength(data, position); + assert arrayLength > 0 : "switch must have at least the default case"; + assert arrayLength % state.multiBranchDataRowSizeInCells == 0 : "array must have full rows"; + + int length = arrayLength / state.multiBranchDataRowSizeInCells; + long totalCount = 0; + for (int i = 0; i < length; i++) { + int offset = getCountOffset(i); + totalCount += data.readUnsignedInt(position, offset); + } + + return VMState.truncateLongToInt(totalCount); + } + + private int getCountOffset(int index) { + return state.multiBranchDataFirstCountOffset + index * state.multiBranchDataRowSize; + } + + private int getDisplacementOffset(int index) { + return state.multiBranchDataFirstDisplacementOffset + index * state.multiBranchDataRowSize; + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + int entries = getLength(data, pos) / state.multiBranchDataRowSizeInCells; + sb.append(format("entries(%d)", entries)); + for (int i = 0; i < entries; i++) { + sb.append(format("%n %d: count(%d) displacement(%d)", i, data.readUnsignedInt(pos, getCountOffset(i)), data.readUnsignedInt(pos, getDisplacementOffset(i)))); + } + return sb; + } + } + + static class ArgInfoData extends ArrayData { + + ArgInfoData(VMState state, int tag) { + super(state, tag, state.argInfoDataSize); + } + } + + static class UnknownProfileData extends HotSpotMethodDataAccessor { + UnknownProfileData(VMState state, int tag) { + super(state, tag, 0); + } + + @Override + protected int getDynamicSize(HotSpotMethodData data, int position) { + assert staticSize == 0; + return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position); + } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + sb.append("unknown profile data with tag: " + tag); + return sb; + } + } + + public void setCompiledIRSize(int size) { + UNSAFE.putInt(metaspaceMethodData + state.config.methodDataIRSizeOffset, size); + } + + public int getCompiledIRSize() { + return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataIRSizeOffset); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2014, 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. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import java.lang.invoke.MethodHandle; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.hotspot.HotSpotMethodData.VMState; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.MethodHandleAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider { + + private final ConstantReflectionProvider constantReflection; + + public HotSpotMethodHandleAccessProvider(ConstantReflectionProvider constantReflection) { + this.constantReflection = constantReflection; + } + + /** + * Lazy initialized reflection on {@link MethodHandle} internals. Field and method lookup is + * only possible after the {@link HotSpotJVMCIRuntime} is fully initialized. + */ + static final class Internals { + final ResolvedJavaType lambdaFormType; + final ResolvedJavaField methodHandleFormField; + final ResolvedJavaField lambdaFormVmentryField; + final HotSpotResolvedJavaField callSiteTargetField; + final HotSpotResolvedJavaField constantCallSiteFrozenField; + final ResolvedJavaField methodField; + final HotSpotResolvedJavaField vmtargetField; + + /** + * Search for an instance field with the given name in a class. + * + * @param declaringType the type declaring the field + * @param fieldName name of the field to be searched + * @param fieldType resolved Java type of the field + * @return resolved Java field + * @throws NoSuchFieldError + */ + private static ResolvedJavaField findFieldInClass(ResolvedJavaType declaringType, String fieldName, ResolvedJavaType fieldType) { + ResolvedJavaField[] fields = declaringType.getInstanceFields(false); + for (ResolvedJavaField field : fields) { + if (field.getName().equals(fieldName) && field.getType().equals(fieldType)) { + return field; + } + } + throw new NoSuchFieldError(declaringType + "." + fieldName); + } + + private static ResolvedJavaType resolveType(String className) { + return (ResolvedJavaType) runtime().lookupTypeInternal(className, null, true); + } + + private Internals() { + try { + ResolvedJavaType methodHandleType = resolveType("Ljava/lang/invoke/MethodHandle;"); + ResolvedJavaType memberNameType = resolveType("Ljava/lang/invoke/MemberName;"); + lambdaFormType = resolveType("Ljava/lang/invoke/LambdaForm;"); + methodHandleFormField = findFieldInClass(methodHandleType, "form", lambdaFormType); + lambdaFormVmentryField = findFieldInClass(lambdaFormType, "vmentry", memberNameType); + + ResolvedJavaType methodType = resolveType("Ljava/lang/invoke/ResolvedMethodName;"); + methodField = findFieldInClass(memberNameType, "method", methodType); + vmtargetField = (HotSpotResolvedJavaField) findFieldInClass(methodType, "vmtarget", resolveType(Character.toString(HotSpotJVMCIRuntime.getHostWordKind().getTypeChar()))); + + ResolvedJavaType callSiteType = resolveType("Ljava/lang/invoke/CallSite;"); + callSiteTargetField = (HotSpotResolvedJavaField) findFieldInClass(callSiteType, "target", methodHandleType); + ResolvedJavaType constantCallSiteType = resolveType("Ljava/lang/invoke/ConstantCallSite;"); + ResolvedJavaType booleanType = resolveType("Z"); + constantCallSiteFrozenField = (HotSpotResolvedJavaField) findFieldInClass(constantCallSiteType, "isFrozen", booleanType); + } catch (Throwable ex) { + throw new JVMCIError(ex); + } + } + + /** + * Singleton instance lazily initialized via double-checked locking. + */ + @NativeImageReinitialize private static volatile Internals instance; + + static Internals instance() { + Internals result = instance; + if (result == null) { + synchronized (VMState.class) { + result = instance; + if (result == null) { + instance = result = new Internals(); + } + } + } + return result; + } + + } + + + @Override + public IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method) { + int intrinsicId = ((HotSpotResolvedJavaMethodImpl) method).intrinsicId(); + if (intrinsicId != 0) { + return getMethodHandleIntrinsic(intrinsicId); + } + return null; + } + + public static IntrinsicMethod getMethodHandleIntrinsic(int intrinsicId) { + HotSpotVMConfig config = runtime().getConfig(); + if (intrinsicId == config.vmIntrinsicInvokeBasic) { + return IntrinsicMethod.INVOKE_BASIC; + } else if (intrinsicId == config.vmIntrinsicLinkToInterface) { + return IntrinsicMethod.LINK_TO_INTERFACE; + } else if (intrinsicId == config.vmIntrinsicLinkToSpecial) { + return IntrinsicMethod.LINK_TO_SPECIAL; + } else if (intrinsicId == config.vmIntrinsicLinkToStatic) { + return IntrinsicMethod.LINK_TO_STATIC; + } else if (intrinsicId == config.vmIntrinsicLinkToVirtual) { + return IntrinsicMethod.LINK_TO_VIRTUAL; + } + return null; + } + + @Override + public ResolvedJavaMethod resolveInvokeBasicTarget(JavaConstant methodHandle, boolean forceBytecodeGeneration) { + if (methodHandle.isNull()) { + return null; + } + + /* Load non-public field: LambdaForm MethodHandle.form */ + Internals internals = Internals.instance(); + JavaConstant lambdaForm = constantReflection.readFieldValue(internals.methodHandleFormField, methodHandle); + if (lambdaForm == null || lambdaForm.isNull()) { + return null; + } + + JavaConstant memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm); + if (memberName.isNull() && forceBytecodeGeneration) { + compilerToVM().compileToBytecode((HotSpotObjectConstantImpl) lambdaForm); + memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm); + assert memberName.isNonNull(); + } + JavaConstant method = constantReflection.readFieldValue(internals.methodField, memberName); + return getTargetMethod(method); + } + + @Override + public ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName) { + if (memberName.isNull()) { + return null; + } + JavaConstant method = constantReflection.readFieldValue(Internals.instance().methodField, memberName); + return getTargetMethod(method); + } + + /** + * Returns the {@link ResolvedJavaMethod} for the method of a java.lang.invoke.MemberName. + */ + private static ResolvedJavaMethod getTargetMethod(JavaConstant method) { + if (method == null) { + // If readFieldValue returns NULL the type was wrong + throw new IllegalArgumentException("unexpected type for memberName"); + } + + /* Read the ResolvedJavaMethod from the injected field MemberName.method.vmtarget */ + return compilerToVM().getResolvedJavaMethod((HotSpotObjectConstantImpl) method, Internals.instance().vmtargetField.getOffset()); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static java.util.FormattableFlags.ALTERNATE; +import static java.util.FormattableFlags.LEFT_JUSTIFY; +import static java.util.FormattableFlags.UPPERCASE; + +import java.util.Formattable; +import java.util.Formatter; + +import jdk.vm.ci.meta.JavaMethod; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +abstract class HotSpotMethod implements JavaMethod, Formattable { + + public static String applyFormattingFlagsAndWidth(String s, int flags, int width) { + if (flags == 0 && width < 0) { + return s; + } + StringBuilder sb = new StringBuilder(s); + + // apply width and justification + int len = sb.length(); + if (len < width) { + for (int i = 0; i < width - len; i++) { + if ((flags & LEFT_JUSTIFY) == LEFT_JUSTIFY) { + sb.append(' '); + } else { + sb.insert(0, ' '); + } + } + } + + String res = sb.toString(); + if ((flags & UPPERCASE) == UPPERCASE) { + res = res.toUpperCase(); + } + return res; + } + + /** + * Controls whether {@link #toString()} includes the qualified or simple name of the class in + * which the method is declared. + */ + public static final boolean FULLY_QUALIFIED_METHOD_NAME = false; + + @Override + public final String toString() { + char h = FULLY_QUALIFIED_METHOD_NAME ? 'H' : 'h'; + String suffix = this instanceof ResolvedJavaMethod ? "" : ", unresolved"; + String fmt = String.format("HotSpotMethod<%%%c.%%n(%%p)%s>", h, suffix); + return format(fmt); + } + + @Override + public void formatTo(Formatter formatter, int flags, int width, int precision) { + String base = (flags & ALTERNATE) == ALTERNATE ? getName() : toString(); + formatter.format(applyFormattingFlagsAndWidth(base, flags & ~ALTERNATE, width)); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotModifiers.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotModifiers.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotModifiers.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotModifiers.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static java.lang.reflect.Modifier.ABSTRACT; +import static java.lang.reflect.Modifier.FINAL; +import static java.lang.reflect.Modifier.INTERFACE; +import static java.lang.reflect.Modifier.NATIVE; +import static java.lang.reflect.Modifier.PRIVATE; +import static java.lang.reflect.Modifier.PROTECTED; +import static java.lang.reflect.Modifier.PUBLIC; +import static java.lang.reflect.Modifier.STATIC; +import static java.lang.reflect.Modifier.STRICT; +import static java.lang.reflect.Modifier.SYNCHRONIZED; +import static java.lang.reflect.Modifier.TRANSIENT; +import static java.lang.reflect.Modifier.VOLATILE; +import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; + +import java.lang.reflect.Modifier; + +/** + * The non-public modifiers in {@link Modifier} that need to be retrieved from + * {@link HotSpotVMConfig}. + */ +public class HotSpotModifiers { + + // @formatter:off + public static final int ANNOTATION = config().jvmAccAnnotation; + public static final int ENUM = config().jvmAccEnum; + public static final int VARARGS = config().jvmAccVarargs; + public static final int BRIDGE = config().jvmAccBridge; + public static final int SYNTHETIC = config().jvmAccSynthetic; + // @formatter:on + + public static int jvmClassModifiers() { + return PUBLIC | FINAL | INTERFACE | ABSTRACT | ANNOTATION | ENUM | SYNTHETIC; + } + + public static int jvmMethodModifiers() { + return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | BRIDGE | VARARGS | NATIVE | ABSTRACT | STRICT | SYNTHETIC; + } + + public static int jvmFieldModifiers() { + return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | ENUM | SYNTHETIC; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; + +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.InvalidInstalledCodeException; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Implementation of {@link InstalledCode} for code installed as an {@code nmethod}. The address of + * the {@code nmethod} is stored in {@link InstalledCode#address} and the value of + * {@code nmethod::verified_entry_point()} is in {@link InstalledCode#entryPoint}. + */ +public class HotSpotNmethod extends HotSpotInstalledCode { + + /** + * This (indirect) {@code Method*} reference is safe since class redefinition preserves all + * methods associated with nmethods in the code cache. + */ + private final HotSpotResolvedJavaMethodImpl method; + + /** + * Specifies whether the {@code nmethod} associated with this object is the code executed by + * default HotSpot linkage when a normal Java call to {@link #method} is made. That is, does + * {@code this.method.metadataHandle->_code} == {@code this.address}. If not, then the + * {@code nmethod} can only be invoked via a reference to this object. An example of this is the + * trampoline mechanism used by Truffle: https://goo.gl/LX88rZ. + */ + private final boolean isDefault; + + /** + * Determines whether this object is in the oops table of the nmethod. + *

    + * If this object is in the oops table, the VM uses the oops table entry to update this object's + * {@link #address} and {@link #entryPoint} fields when the state of the nmethod changes. The + * nmethod will be unloadable when this object dies. + *

    + * Otherwise, the nmethod's unloadability is not changed when this object dies. + */ + boolean inOopsTable() { + return compileIdSnapshot != 0; + } + + /** + * If this field is 0, this object is in the oops table of the nmethod. Otherwise, the value of + * the field records the nmethod's compile identifier. This value is used to confirm if an entry + * in the code cache retrieved by {@link #address} is indeed the nmethod represented by this + * object. + * + * @see #inOopsTable + */ + private final long compileIdSnapshot; + + HotSpotNmethod(HotSpotResolvedJavaMethodImpl method, String name, boolean isDefault, long compileId) { + super(name); + this.method = method; + this.isDefault = isDefault; + boolean inOopsTable = !IS_IN_NATIVE_IMAGE && !isDefault; + this.compileIdSnapshot = inOopsTable ? 0L : compileId; + assert inOopsTable || compileId != 0L : this; + } + + /** + * Attaches {@code log} to this object. If {@code log.managesFailedSpeculations() == true}, this + * ensures the failed speculation list lives at least as long as this object. + */ + public void setSpeculationLog(HotSpotSpeculationLog log) { + this.speculationLog = log; + } + + /** + * The speculation log containing speculations embedded in the nmethod. + * + * If {@code speculationLog.managesFailedSpeculations() == true}, this field ensures the failed + * speculation list lives at least as long as this object. This prevents deoptimization from + * appending to an already freed list. + */ + @SuppressWarnings("unused") private HotSpotSpeculationLog speculationLog; + + /** + * Determines if the nmethod associated with this object is the compiled entry point for + * {@link #getMethod()}. + */ + public boolean isDefault() { + return isDefault; + } + + @Override + public boolean isValid() { + if (compileIdSnapshot != 0L) { + compilerToVM().updateHotSpotNmethod(this); + } + return super.isValid(); + } + + public ResolvedJavaMethod getMethod() { + return method; + } + + @Override + public void invalidate() { + compilerToVM().invalidateHotSpotNmethod(this); + } + + @Override + public long getAddress() { + if (compileIdSnapshot != 0L) { + compilerToVM().updateHotSpotNmethod(this); + } + return super.getAddress(); + } + + @Override + public long getEntryPoint() { + if (compileIdSnapshot != 0L) { + return 0; + } + return super.getEntryPoint(); + } + + @Override + public String toString() { + return String.format("HotSpotNmethod[method=%s, codeBlob=0x%x, isDefault=%b, name=%s, inOopsTable=%s]", + method, getAddress(), isDefault, name, inOopsTable()); + } + + private boolean checkArgs(Object... args) { + JavaType[] sig = method.toParameterTypes(); + assert args.length == sig.length : method.format("%H.%n(%p): expected ") + sig.length + " args, got " + args.length; + for (int i = 0; i < sig.length; i++) { + Object arg = args[i]; + if (arg == null) { + assert sig[i].getJavaKind() == JavaKind.Object : method.format("%H.%n(%p): expected arg ") + i + " to be Object, not " + sig[i]; + } else if (sig[i].getJavaKind() != JavaKind.Object) { + assert sig[i].getJavaKind().toBoxedJavaClass() == arg.getClass() : method.format("%H.%n(%p): expected arg ") + i + " to be " + sig[i] + ", not " + arg.getClass(); + } + } + return true; + } + + /** + * {@inheritDoc} + * + * It's possible for the HotSpot runtime to sweep nmethods at any point in time. As a result, + * there is no guarantee that calling this method will execute the wrapped nmethod. Instead, it + * may end up executing the bytecode of the associated {@link #getMethod() Java method}. Only if + * {@link #isValid()} is {@code true} after returning can the caller be sure that the nmethod + * was executed. If {@link #isValid()} is {@code false}, then the only way to determine if the + * nmethod was executed is to test for some side-effect specific to the nmethod (e.g., update to + * a field) that is not performed by the bytecode of the associated {@link #getMethod() Java + * method}. + */ + @Override + public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { + if (IS_IN_NATIVE_IMAGE) { + throw new HotSpotJVMCIUnsupportedOperationError("Cannot execute nmethod via mirror in native image"); + } + assert checkArgs(args); + return compilerToVM().executeHotSpotNmethod(args, this); + } + + @Override + public long getStart() { + return isValid() ? super.getStart() : 0; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; + +import jdk.vm.ci.meta.Assumptions; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * Represents a constant non-{@code null} object reference, within the compiler and across the + * compiler/runtime interface. + */ +abstract class HotSpotObjectConstantImpl implements HotSpotObjectConstant { + + protected final boolean compressed; + + HotSpotObjectConstantImpl(boolean compressed) { + this.compressed = compressed; + } + + @Override + public JavaKind getJavaKind() { + return JavaKind.Object; + } + + @Override + public boolean isCompressed() { + return compressed; + } + + @Override + public abstract JavaConstant compress(); + + @Override + public abstract JavaConstant uncompress(); + + @Override + public HotSpotResolvedObjectType getType() { + return runtime().reflection.getType(this); + } + + @Override + public abstract int getIdentityHashCode(); + + private boolean isFullyInitializedConstantCallSite() { + if (!runtime().getConstantCallSite().isInstance(this)) { + return false; + } + // read ConstantCallSite.isFrozen as a volatile field + HotSpotResolvedJavaField field = HotSpotMethodHandleAccessProvider.Internals.instance().constantCallSiteFrozenField; + boolean isFrozen = readFieldValue(field).asBoolean(); + // isFrozen true implies fully-initialized + return isFrozen; + } + + private HotSpotObjectConstantImpl readTarget() { + // read CallSite.target as a volatile field + HotSpotResolvedJavaField field = HotSpotMethodHandleAccessProvider.Internals.instance().callSiteTargetField; + return (HotSpotObjectConstantImpl) readFieldValue(field); + } + + @Override + public JavaConstant getCallSiteTarget(Assumptions assumptions) { + if (runtime().getCallSite().isInstance(this)) { + // For ConstantCallSites, we need to read "isFrozen" before reading "target" + // isFullyInitializedConstantCallSite() reads "isFrozen" + if (!isFullyInitializedConstantCallSite()) { + if (assumptions == null) { + return null; + } + assumptions.record(new Assumptions.CallSiteTargetValue(this, readTarget())); + } + return readTarget(); + } + return null; + } + + @Override + public boolean isInternedString() { + return runtime().compilerToVm.isInternedString(this); + } + + @Override + public T asObject(Class type) { + return runtime().reflection.asObject(this, type); + } + + @Override + public Object asObject(ResolvedJavaType type) { + return runtime().reflection.asObject(this, (HotSpotResolvedJavaType) type); + } + + @Override + public boolean isNull() { + return false; + } + + @Override + public boolean isDefaultForKind() { + return false; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof HotSpotObjectConstantImpl) { + HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o; + return runtime().reflection.equals(this, other); + } + return false; + } + + @Override + public int hashCode() { + return getIdentityHashCode(); + } + + @Override + public String toValueString() { + if (runtime().getJavaLangString().isInstance(this)) { + return "\"" + runtime().reflection.asString(this) + "\""; + } else { + return runtime().reflection.formatString(this); + } + } + + @Override + public String toString() { + return (compressed ? "NarrowOop" : getJavaKind().getJavaName()) + "[" + runtime().reflection.formatString(this) + "]"; + } + + public JavaConstant readFieldValue(HotSpotResolvedJavaField field) { + if (IS_IN_NATIVE_IMAGE && this instanceof DirectHotSpotObjectConstantImpl) { + // cannot read fields from objects due to lack of + // general reflection support in native image + return null; + } + if (field.isStatic()) { + return null; + } + return runtime().compilerToVm.readFieldValue(this, (HotSpotResolvedObjectTypeImpl) field.getDeclaringClass(), field.getOffset(), field.getType().getJavaKind()); + } + + public ResolvedJavaType asJavaType() { + return runtime().reflection.asJavaType(this); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.hotspot; + +import java.lang.invoke.CallSite; +import java.util.Objects; + +import jdk.vm.ci.meta.Assumptions; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.VMConstant; + +/** + * Represents a constant non-{@code null} object reference, within the compiler and across the + * compiler/runtime interface. + */ +public interface HotSpotObjectConstant extends JavaConstant, HotSpotConstant, VMConstant { + + @Override + JavaConstant compress(); + + @Override + JavaConstant uncompress(); + + /** + * Gets the resolved Java type of the object represented by this constant. + */ + HotSpotResolvedObjectType getType(); + + /** + * Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object + * represented by this constant. + */ + int getIdentityHashCode(); + + /** + * Gets the result of {@link CallSite#getTarget()} for the {@link CallSite} object represented + * by this constant. + * + * @param assumptions used to register an assumption that the {@link CallSite}'s target does not + * change + * @return {@code null} if this constant does not represent a {@link CallSite} object + */ + JavaConstant getCallSiteTarget(Assumptions assumptions); + + /** + * Determines if this constant represents an {@linkplain String#intern() interned} string. + */ + boolean isInternedString(); + + /** + * Gets the object represented by this constant represents if it is of a given type. + * + * @param type the expected type of the object represented by this constant. If the object is + * required to be of this type, then wrap the call to this method in + * {@link Objects#requireNonNull(Object)}. + * @return the object value represented by this constant if it is an + * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise + * {@code null} + */ + T asObject(Class type); + + /** + * Gets the object represented by this constant represents if it is of a given type. + * + * @param type the expected type of the object represented by this constant. If the object is + * required to be of this type, then wrap the call to this method in + * {@link Objects#requireNonNull(Object)}. + * @return the object value represented by this constant if it is an + * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise + * {@code null} + */ + Object asObject(ResolvedJavaType type); + + @Override + String toValueString(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,121 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import jdk.vm.ci.services.Services; + +/** + * A mechanism for limiting the lifetime of a foreign object reference encapsulated in a + * {@link HotSpotObjectConstant}. + * + * A {@link HotSpotObjectConstant} allocated in a {@linkplain #openLocalScope local} scope will have + * its reference to any foreign object cleared when the scope {@linkplain #close() closes}. This + * allows the foreign memory manager to reclaim the foreign object (once there are no other strong + * references to it). + * + * {@link HotSpotObjectConstantScope}s have no impact on {@link HotSpotObjectConstant}s that do not + * encapsulate a foreign object reference. + * + * The object returned by {@link #enterGlobalScope()} or {@link #openLocalScope(Object)} should + * always be used in a try-with-resources statement. Failure to close a scope will almost certainly + * result in foreign objects being leaked. + */ +public final class HotSpotObjectConstantScope implements AutoCloseable { + static final ThreadLocal CURRENT = new ThreadLocal<>(); + + private final HotSpotObjectConstantScope parent; + private List foreignObjects; + + /** + * An object whose {@link Object#toString()} value describes a non-global scope. This is + * {@code null} iff this is a global scope. + */ + final Object localScopeDescription; + + /** + * Opens a local scope that upon closing, will release foreign object references encapsulated by + * {@link HotSpotObjectConstant}s created in the scope. + * + * @param description an non-null object whose {@link Object#toString()} value describes the + * scope being opened + * @return {@code null} if the current runtime does not support remote object references + */ + public static HotSpotObjectConstantScope openLocalScope(Object description) { + return Services.IS_IN_NATIVE_IMAGE ? new HotSpotObjectConstantScope(Objects.requireNonNull(description)) : null; + } + + /** + * Enters the global scope. This is useful to escape a local scope for execution that will + * create foreign object references that need to outlive the local scope. + * + * Foreign object references encapsulated by {@link HotSpotObjectConstant}s created in the + * global scope are only subject to reclamation once the {@link HotSpotObjectConstant} wrapper + * dies. + * + * @return {@code null} if the current runtime does not support remote object references or if + * this thread is currently in the global scope + */ + public static HotSpotObjectConstantScope enterGlobalScope() { + return Services.IS_IN_NATIVE_IMAGE && CURRENT.get() != null ? new HotSpotObjectConstantScope(null) : null; + } + + private HotSpotObjectConstantScope(Object localScopeDescription) { + this.parent = CURRENT.get(); + CURRENT.set(this); + this.localScopeDescription = localScopeDescription; + } + + /** + * Determines if this scope is global. + */ + boolean isGlobal() { + return localScopeDescription == null; + } + + void add(IndirectHotSpotObjectConstantImpl obj) { + assert !isGlobal(); + if (foreignObjects == null) { + foreignObjects = new ArrayList<>(); + } + foreignObjects.add(obj); + } + + @VMEntryPoint + @Override + public void close() { + if (CURRENT.get() != this) { + throw new IllegalStateException("Cannot close non-active scope"); + } + if (foreignObjects != null) { + for (IndirectHotSpotObjectConstantImpl obj : foreignObjects) { + obj.clear(localScopeDescription); + } + foreignObjects = null; + } + CURRENT.set(parent); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.DeoptimizationReason; +import jdk.vm.ci.meta.JavaMethodProfile; +import jdk.vm.ci.meta.JavaTypeProfile; +import jdk.vm.ci.meta.ProfilingInfo; +import jdk.vm.ci.meta.TriState; + +final class HotSpotProfilingInfo implements ProfilingInfo { + + private final HotSpotMethodData methodData; + private final HotSpotResolvedJavaMethod method; + + private boolean isMature; + private int position; + private int hintPosition; + private int hintBCI; + private HotSpotMethodDataAccessor dataAccessor; + + private boolean includeNormal; + private boolean includeOSR; + + HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) { + this.methodData = methodData; + this.method = method; + if (!method.getDeclaringClass().isLinked()) { + throw new IllegalArgumentException(method.format("%H.%n(%p) must be linked")); + } + this.includeNormal = includeNormal; + this.includeOSR = includeOSR; + this.isMature = methodData.isProfileMature(); + hintPosition = 0; + hintBCI = -1; + } + + @Override + public int getCodeSize() { + return method.getCodeSize(); + } + + public int getDecompileCount() { + return methodData.getDecompileCount(); + } + + public int getOverflowRecompileCount() { + return methodData.getOverflowRecompileCount(); + } + + public int getOverflowTrapCount() { + return methodData.getOverflowTrapCount(); + } + + @Override + public JavaTypeProfile getTypeProfile(int bci) { + if (!isMature) { + return null; + } + findBCI(bci, false); + return dataAccessor.getTypeProfile(methodData, position); + } + + @Override + public JavaMethodProfile getMethodProfile(int bci) { + if (!isMature) { + return null; + } + findBCI(bci, false); + return dataAccessor.getMethodProfile(methodData, position); + } + + @Override + public double getBranchTakenProbability(int bci) { + if (!isMature) { + return -1; + } + findBCI(bci, false); + return dataAccessor.getBranchTakenProbability(methodData, position); + } + + @Override + public double[] getSwitchProbabilities(int bci) { + if (!isMature) { + return null; + } + findBCI(bci, false); + return dataAccessor.getSwitchProbabilities(methodData, position); + } + + @Override + public TriState getExceptionSeen(int bci) { + findBCI(bci, true); + return dataAccessor.getExceptionSeen(methodData, position); + } + + @Override + public TriState getNullSeen(int bci) { + findBCI(bci, false); + return dataAccessor.getNullSeen(methodData, position); + } + + @Override + public int getExecutionCount(int bci) { + if (!isMature) { + return -1; + } + findBCI(bci, false); + return dataAccessor.getExecutionCount(methodData, position); + } + + @Override + public int getDeoptimizationCount(DeoptimizationReason reason) { + int count = 0; + if (includeNormal) { + count += methodData.getDeoptimizationCount(reason); + } + if (includeOSR) { + count += methodData.getOSRDeoptimizationCount(reason); + } + return count; + } + + private void findBCI(int targetBCI, boolean searchExtraData) { + assert targetBCI >= 0 : "invalid BCI"; + + if (methodData.hasNormalData()) { + int currentPosition = targetBCI < hintBCI ? 0 : hintPosition; + HotSpotMethodDataAccessor currentAccessor; + while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) { + int currentBCI = currentAccessor.getBCI(methodData, currentPosition); + if (currentBCI == targetBCI) { + normalDataFound(currentAccessor, currentPosition, currentBCI); + return; + } else if (currentBCI > targetBCI) { + break; + } + currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); + } + } + + boolean exceptionPossiblyNotRecorded = false; + if (searchExtraData && methodData.hasExtraData()) { + int currentPosition = methodData.getExtraDataBeginOffset(); + HotSpotMethodDataAccessor currentAccessor; + while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) { + int currentBCI = currentAccessor.getBCI(methodData, currentPosition); + if (currentBCI == targetBCI) { + extraDataFound(currentAccessor, currentPosition); + return; + } + currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); + } + + if (!methodData.isWithin(currentPosition)) { + exceptionPossiblyNotRecorded = true; + } + } + + noDataFound(exceptionPossiblyNotRecorded); + } + + private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) { + setCurrentData(data, pos); + this.hintPosition = position; + this.hintBCI = bci; + } + + private void extraDataFound(HotSpotMethodDataAccessor data, int pos) { + setCurrentData(data, pos); + } + + private void noDataFound(boolean exceptionPossiblyNotRecorded) { + HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded); + setCurrentData(accessor, -1); + } + + private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) { + this.dataAccessor = dataAccessor; + this.position = position; + } + + @Override + public boolean isMature() { + return isMature; + } + + public void ignoreMature() { + isMature = true; + } + + @Override + public String toString() { + return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">"; + } + + @Override + public void setMature() { + isMature = true; + } + + /** + * {@code MethodData::_jvmci_ir_size} (currently) supports at most one JVMCI compiler IR type + * which will be determined by the first JVMCI compiler that calls + * {@link #setCompilerIRSize(Class, int)}. + */ + private static volatile Class supportedCompilerIRType; + + @Override + public boolean setCompilerIRSize(Class irType, int size) { + if (supportedCompilerIRType == null) { + synchronized (HotSpotProfilingInfo.class) { + if (supportedCompilerIRType == null) { + supportedCompilerIRType = irType; + } + } + } + if (supportedCompilerIRType != irType) { + return false; + } + methodData.setCompiledIRSize(size); + return true; + } + + @Override + public int getCompilerIRSize(Class irType) { + if (irType == supportedCompilerIRType) { + return methodData.getCompiledIRSize(); + } + return -1; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotReferenceMap.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotReferenceMap.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotReferenceMap.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotReferenceMap.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.hotspot; + +import java.util.Arrays; + +import jdk.vm.ci.code.Location; +import jdk.vm.ci.code.ReferenceMap; + +/** + * Describes where the object references are in machine state, compliant with what HotSpot expects. + */ +public final class HotSpotReferenceMap extends ReferenceMap { + + private final Location[] objects; + private final Location[] derivedBase; + private final int[] sizeInBytes; + private final int maxRegisterSize; + + /** + * + * @param objects This array is now owned by this object and must not be mutated by the caller. + * @param derivedBase This array is now owned by this object and must not be mutated by the + * caller. + * @param sizeInBytes This array is now owned by this object and must not be mutated by the + * caller. + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `objects`, `derivedBase` and `sizeInBytes`") + public HotSpotReferenceMap(Location[] objects, Location[] derivedBase, int[] sizeInBytes, int maxRegisterSize) { + this.objects = objects; + this.derivedBase = derivedBase; + this.sizeInBytes = sizeInBytes; + this.maxRegisterSize = maxRegisterSize; + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof HotSpotReferenceMap) { + HotSpotReferenceMap that = (HotSpotReferenceMap) obj; + if (sizeInBytes == that.sizeInBytes && maxRegisterSize == that.maxRegisterSize && Arrays.equals(objects, that.objects) && Arrays.equals(derivedBase, that.derivedBase)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return Arrays.toString(objects); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.internal.misc.Unsafe.ADDRESS_SIZE; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import java.lang.annotation.Annotation; + +import jdk.internal.vm.annotation.Stable; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.UnresolvedJavaType; + +/** + * Represents a field in a HotSpot type. + */ +class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField { + + private final HotSpotResolvedObjectTypeImpl holder; + private JavaType type; + + /** + * Offset (in bytes) of field from start of its storage container (i.e. {@code instanceOop} or + * {@code Klass*}). + */ + private final int offset; + + /** + * Value of {@code fieldDescriptor::index()}. + */ + private final int index; + + /** + * This value contains all flags as stored in the VM including internal ones. + */ + private final int modifiers; + + HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, JavaType type, int offset, int modifiers, int index) { + this.holder = holder; + this.type = type; + this.index = index; + this.offset = offset; + this.modifiers = modifiers; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof HotSpotResolvedJavaFieldImpl) { + HotSpotResolvedJavaFieldImpl that = (HotSpotResolvedJavaFieldImpl) obj; + if (that.offset != this.offset || that.isStatic() != this.isStatic()) { + return false; + } else if (this.holder.equals(that.holder)) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + return holder.hashCode() ^ offset; + } + + @Override + public int getModifiers() { + return modifiers & HotSpotModifiers.jvmFieldModifiers(); + } + + @Override + public boolean isInternal() { + return (modifiers & config().jvmAccFieldInternal) != 0; + } + + /** + * Determines if a given object contains this field. + * + * @return true iff this is a non-static field and its declaring class is assignable from + * {@code object}'s class + */ + @Override + public boolean isInObject(JavaConstant object) { + if (isStatic()) { + return false; + } + HotSpotObjectConstant constant = (HotSpotObjectConstant) object; + return getDeclaringClass().isAssignableFrom(constant.getType()); + } + + @Override + public HotSpotResolvedObjectTypeImpl getDeclaringClass() { + return holder; + } + + @Override + public String getName() { + return holder.createFieldInfo(index).getName(); + } + + @Override + public JavaType getType() { + // Pull field into local variable to prevent a race causing + // a ClassCastException below + JavaType currentType = type; + if (currentType instanceof UnresolvedJavaType) { + // Don't allow unresolved types to hang around forever + UnresolvedJavaType unresolvedType = (UnresolvedJavaType) currentType; + JavaType resolved = HotSpotJVMCIRuntime.runtime().lookupType(unresolvedType.getName(), holder, false); + if (resolved instanceof ResolvedJavaType) { + type = resolved; + } + } + return type; + + } + + /** + * Gets the offset (in bytes) of field from start of its storage container (i.e. + * {@code instanceOop} or {@code Klass*}). + */ + @Override + public int getOffset() { + return offset; + } + + /** + * Gets the value of this field's index (i.e. {@code fieldDescriptor::index()} in the encoded + * fields of the declaring class. + */ + int getIndex() { + return index; + } + + @Override + public String toString() { + return format("HotSpotResolvedJavaFieldImpl<%H.%n %t:") + offset + ">"; + } + + @Override + public boolean isSynthetic() { + return (config().jvmAccSynthetic & modifiers) != 0; + } + + /** + * Checks if this field has the {@code Stable} annotation. + * + * @return true if field has {@code Stable} annotation, false otherwise + */ + @Override + public boolean isStable() { + return (config().jvmAccFieldStable & modifiers) != 0; + } + + private boolean hasAnnotations() { + if (!isInternal()) { + HotSpotVMConfig config = config(); + final long metaspaceAnnotations = UNSAFE.getAddress(holder.getMetaspaceKlass() + config.instanceKlassAnnotationsOffset); + if (metaspaceAnnotations != 0) { + long fieldsAnnotations = UNSAFE.getAddress(metaspaceAnnotations + config.annotationsFieldAnnotationsOffset); + if (fieldsAnnotations != 0) { + long fieldAnnotations = UNSAFE.getAddress(fieldsAnnotations + config.fieldsAnnotationsBaseOffset + (ADDRESS_SIZE * index)); + return fieldAnnotations != 0; + } + } + } + return false; + } + + @Override + public Annotation[] getAnnotations() { + if (!hasAnnotations()) { + return new Annotation[0]; + } + return runtime().reflection.getFieldAnnotations(this); + } + + @Override + public Annotation[] getDeclaredAnnotations() { + if (!hasAnnotations()) { + return new Annotation[0]; + } + return runtime().reflection.getFieldDeclaredAnnotations(this); + } + + @Override + public T getAnnotation(Class annotationClass) { + if (!hasAnnotations()) { + return null; + } + return runtime().reflection.getFieldAnnotation(this, annotationClass); + } + + @Override + public JavaConstant getConstantValue() { + return holder.createFieldInfo(index).getConstantValue(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.ResolvedJavaField; + +/** + * Represents a field in a HotSpot type. + */ +public interface HotSpotResolvedJavaField extends ResolvedJavaField { + + /** + * Determines if a given object contains this field. + * + * @return true iff this is a non-static field and its declaring class is assignable from + * {@code object}'s class + */ + boolean isInObject(JavaConstant object); + + /** + * Determines if this field should be treated as a constant. + */ + boolean isStable(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,756 @@ +/* + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.HotSpotModifiers.BRIDGE; +import static jdk.vm.ci.hotspot.HotSpotModifiers.SYNTHETIC; +import static jdk.vm.ci.hotspot.HotSpotModifiers.VARARGS; +import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmMethodModifiers; +import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Executable; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.ConstantPool; +import jdk.vm.ci.meta.DefaultProfilingInfo; +import jdk.vm.ci.meta.ExceptionHandler; +import jdk.vm.ci.meta.JavaMethod; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.LineNumberTable; +import jdk.vm.ci.meta.Local; +import jdk.vm.ci.meta.LocalVariableTable; +import jdk.vm.ci.meta.ProfilingInfo; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.SpeculationLog; +import jdk.vm.ci.meta.TriState; + +/** + * Implementation of {@link JavaMethod} for resolved HotSpot methods. + */ +final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, MetaspaceHandleObject { + + /** + * Handle to the metaspace {@code Method} object. The handle is in + * {@code JVMCI::_metadata_handles}. + */ + private final long metadataHandle; + + private final HotSpotResolvedObjectTypeImpl holder; + private final HotSpotConstantPool constantPool; + final HotSpotSignature signature; + private HotSpotMethodData methodData; + private byte[] code; + + /** + * Cache for {@link HotSpotJDKReflection#getMethod}. + */ + volatile Executable toJavaCache; + + /** + * Only 30% of {@link HotSpotResolvedJavaMethodImpl}s have their name accessed so compute it + * lazily and cache it. + */ + private String nameCache; + + /** + * Gets the holder of a HotSpot metaspace method native object. + * + * @param metaspaceHandle a handle to a metaspace Method object + * @return the {@link ResolvedJavaType} corresponding to the holder of the + * {@code metaspaceMethod} + */ + private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceHandle) { + HotSpotVMConfig config = config(); + long metaspaceMethod = UNSAFE.getLong(metaspaceHandle); + assert metaspaceMethod != 0 : metaspaceHandle; + final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset); + final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset); + HotSpotResolvedObjectTypeImpl result = compilerToVM().getResolvedJavaType(metaspaceConstantPool + config.constantPoolHolderOffset, false); + assert result != null; + return result; + } + + /** + * Gets the JVMCI mirror from a HotSpot method. The VM is responsible for ensuring that the + * Method* is kept alive for the duration of this call and the {@link HotSpotJVMCIRuntime} keeps + * it alive after that. + *

    + * Called from the VM. + * + * @param metaspaceHandle a handle to metaspace Method object + * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod} + */ + @SuppressWarnings("unused") + @VMEntryPoint + private static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceHandle) { + HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceHandle); + return holder.createMethod(metaspaceHandle); + } + + HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceHandle) { + this.metadataHandle = metaspaceHandle; + this.holder = holder; + + HotSpotVMConfig config = config(); + final long constMethod = getConstMethod(); + + /* + * Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for + * signature-polymorphic method handle methods) have their own constant pool instead of the + * one from their holder. + */ + final long metaspaceConstantPool = UNSAFE.getAddress(constMethod + config.constMethodConstantsOffset); + if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) { + this.constantPool = holder.getConstantPool(); + } else { + this.constantPool = compilerToVM().getConstantPool(this); + } + + final int signatureIndex = UNSAFE.getChar(constMethod + config.constMethodSignatureIndexOffset); + this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex); + HandleCleaner.create(this, metaspaceHandle); + } + + /** + * Returns a pointer to this method's constant method data structure ( + * {@code Method::_constMethod}). This pointer isn't wrapped since it should be safe to use it + * within the context of this HotSpotResolvedJavaMethodImpl since the Method* and ConstMethod* + * are kept alive as a pair. + * + * @return pointer to this method's ConstMethod + */ + private long getConstMethod() { + return UNSAFE.getAddress(getMetaspaceMethod() + config().methodConstMethodOffset); + } + + @Override + public String getName() { + if (nameCache == null) { + final int nameIndex = UNSAFE.getChar(getConstMethod() + config().constMethodNameIndexOffset); + nameCache = constantPool.lookupUtf8(nameIndex); + } + return nameCache; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof HotSpotResolvedJavaMethodImpl) { + HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj; + return that.getMetaspaceMethod() == getMetaspaceMethod(); + } + return false; + } + + @Override + public int hashCode() { + return (int) getMetaspaceMethod(); + } + + /** + * Returns this method's flags ({@code Method::_flags}). + * + * @return flags of this method + */ + private int getFlags() { + return UNSAFE.getShort(getMetaspaceMethod() + config().methodFlagsOffset); + } + + /** + * Returns this method's constant method flags ({@code ConstMethod::_flags}). + * + * @return flags of this method's ConstMethod + */ + private int getConstMethodFlags() { + return UNSAFE.getChar(getConstMethod() + config().constMethodFlagsOffset); + } + + @Override + public HotSpotResolvedObjectTypeImpl getDeclaringClass() { + return holder; + } + + /** + * Gets the address of the C++ Method object for this method. + */ + public Constant getMetaspaceMethodConstant() { + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false); + } + + long getMetaspaceMethod() { + long metaspacePointer = getMetaspacePointer(); + if (metaspacePointer == 0) { + throw new NullPointerException("Method* is null"); + } + return metaspacePointer; + } + + @Override + public long getMetadataHandle() { + return metadataHandle; + } + + @Override + public Constant getEncoding() { + return getMetaspaceMethodConstant(); + } + + /** + * Gets the complete set of modifiers for this method which includes the JVM specification + * modifiers as well as the HotSpot internal modifiers. + */ + public int getAllModifiers() { + return UNSAFE.getInt(getMetaspaceMethod() + config().methodAccessFlagsOffset); + } + + @Override + public int getModifiers() { + return getAllModifiers() & jvmMethodModifiers(); + } + + @Override + public boolean canBeStaticallyBound() { + return (isFinal() || isPrivate() || isStatic() || holder.isLeaf() || isConstructor()) && isConcrete(); + } + + @Override + public byte[] getCode() { + if (getCodeSize() == 0) { + return null; + } + if (code == null && holder.isLinked()) { + code = compilerToVM().getBytecode(this); + assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length; + } + return code; + } + + @Override + public int getCodeSize() { + int codeSize = UNSAFE.getChar(getConstMethod() + config().constMethodCodeSizeOffset); + if (codeSize > 0 && !getDeclaringClass().isLinked()) { + return -1; + } + return codeSize; + } + + @Override + public ExceptionHandler[] getExceptionHandlers() { + final boolean hasExceptionTable = (getConstMethodFlags() & config().constMethodHasExceptionTable) != 0; + if (!hasExceptionTable) { + return new ExceptionHandler[0]; + } + + HotSpotVMConfig config = config(); + final int exceptionTableLength = compilerToVM().getExceptionTableLength(this); + ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength]; + long exceptionTableElement = compilerToVM().getExceptionTableStart(this); + + for (int i = 0; i < exceptionTableLength; i++) { + final int startPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset); + final int endPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementEndPcOffset); + final int handlerPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementHandlerPcOffset); + int catchTypeIndex = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementCatchTypeIndexOffset); + + JavaType catchType; + if (catchTypeIndex == 0) { + catchType = null; + } else { + final int opcode = -1; // opcode is not used + catchType = constantPool.lookupType(catchTypeIndex, opcode); + + // Check for Throwable which catches everything. + if (catchType instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl resolvedType = (HotSpotResolvedObjectTypeImpl) catchType; + if (resolvedType.equals(runtime().getJavaLangThrowable())) { + catchTypeIndex = 0; + catchType = null; + } + } + } + handlers[i] = new ExceptionHandler(startPc, endPc, handlerPc, catchTypeIndex, catchType); + + // Go to the next ExceptionTableElement + exceptionTableElement += config.exceptionTableElementSize; + } + + return handlers; + } + + /** + * Returns true if this method has a {@code CallerSensitive} annotation. + * + * @return true if CallerSensitive annotation present, false otherwise + */ + @Override + public boolean isCallerSensitive() { + return (getFlags() & config().methodFlagsCallerSensitive) != 0; + } + + /** + * Returns true if this method has a {@code ForceInline} annotation. + * + * @return true if ForceInline annotation present, false otherwise + */ + @Override + public boolean isForceInline() { + return (getFlags() & config().methodFlagsForceInline) != 0; + } + + /** + * Returns true if this method has a {@code ReservedStackAccess} annotation. + * + * @return true if ReservedStackAccess annotation present, false otherwise + */ + @Override + public boolean hasReservedStackAccess() { + return (getFlags() & config().methodFlagsReservedStackAccess) != 0; + } + + /** + * Sets flags on {@code method} indicating that it should never be inlined or compiled by the + * VM. + */ + @Override + public void setNotInlinableOrCompilable() { + compilerToVM().setNotInlinableOrCompilable(this); + } + + /** + * Returns true if this method is one of the special methods that is ignored by security stack + * walks. + * + * @return true if special method ignored by security stack walks, false otherwise + */ + @Override + public boolean ignoredBySecurityStackWalk() { + return compilerToVM().methodIsIgnoredBySecurityStackWalk(this); + } + + @Override + public boolean isClassInitializer() { + if (isStatic()) { + final int nameIndex = UNSAFE.getChar(getConstMethod() + config().constMethodNameIndexOffset); + long nameSymbol = constantPool.getEntryAt(nameIndex); + long clinitSymbol = config().symbolClinit; + return nameSymbol == clinitSymbol; + } + return false; + } + + @Override + public boolean isConstructor() { + if (!isStatic()) { + final int nameIndex = UNSAFE.getChar(getConstMethod() + config().constMethodNameIndexOffset); + long nameSymbol = constantPool.getEntryAt(nameIndex); + long initSymbol = config().symbolInit; + return nameSymbol == initSymbol; + } + return false; + } + + @Override + public int getMaxLocals() { + if (isAbstract() || isNative()) { + return 0; + } + HotSpotVMConfig config = config(); + return UNSAFE.getChar(getConstMethod() + config.methodMaxLocalsOffset); + } + + @Override + public int getMaxStackSize() { + if (isAbstract() || isNative()) { + return 0; + } + HotSpotVMConfig config = config(); + return config.extraStackEntries + UNSAFE.getChar(getConstMethod() + config.constMethodMaxStackOffset); + } + + @Override + public StackTraceElement asStackTraceElement(int bci) { + if (bci < 0 || bci >= getCodeSize()) { + // HotSpot code can only construct stack trace elements for valid bcis + StackTraceElement ste = compilerToVM().getStackTraceElement(this, 0); + return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1); + } + return compilerToVM().getStackTraceElement(this, bci); + } + + @Override + public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) { + assert !canBeStaticallyBound() : this; + + if (receiver.isInterface()) { + // Cannot trust interfaces. Because of: + // interface I { void foo(); } + // class A { public void foo() {} } + // class B extends A implements I { } + // class C extends B { public void foo() { } } + // class D extends B { } + // Would lead to identify C.foo() as the unique concrete method for I.foo() without + // seeing A.foo(). + return null; + } + assert !receiver.isLinked() || isInVirtualMethodTable(receiver); + if (this.isDefault()) { + // CHA for default methods doesn't work and may crash the VM + return null; + } + return compilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this); + } + + @Override + public HotSpotSignature getSignature() { + return signature; + } + + /** + * Gets the value of {@code Method::_code}. + * + * @return the value of {@code Method::_code} + */ + private long getCompiledCode() { + HotSpotVMConfig config = config(); + return UNSAFE.getAddress(getMetaspaceMethod() + config.methodCodeOffset); + } + + /** + * Returns whether this method has compiled code. + * + * @return true if this method has compiled code, false otherwise + */ + @Override + public boolean hasCompiledCode() { + return getCompiledCode() != 0L; + } + + /** + * @param level + * @return true if the currently installed code was generated at {@code level}. + */ + @Override + public boolean hasCompiledCodeAtLevel(int level) { + long compiledCode = getCompiledCode(); + if (compiledCode != 0) { + return UNSAFE.getInt(compiledCode + config().nmethodCompLevelOffset) == level; + } + return false; + } + + @Override + public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) { + ProfilingInfo info; + + if (Option.UseProfilingInformation.getBoolean() && methodData == null) { + long metaspaceMethodData = UNSAFE.getAddress(getMetaspaceMethod() + config().methodDataOffset); + if (metaspaceMethodData != 0) { + methodData = new HotSpotMethodData(metaspaceMethodData, this); + String methodDataFilter = Option.TraceMethodDataFilter.getString(); + if (methodDataFilter != null && this.format("%H.%n").contains(methodDataFilter)) { + String line = methodData.toString() + System.lineSeparator(); + byte[] lineBytes = line.getBytes(); + HotSpotJVMCIRuntime.runtime().writeDebugOutput(lineBytes, 0, lineBytes.length, true, true); + } + } + } + + if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) { + // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in + // case of a deoptimization. + info = DefaultProfilingInfo.get(TriState.FALSE); + } else { + info = new HotSpotProfilingInfo(methodData, this, includeNormal, includeOSR); + } + return info; + } + + @Override + public void reprofile() { + compilerToVM().reprofile(this); + } + + @Override + public ConstantPool getConstantPool() { + return constantPool; + } + + @Override + public Parameter[] getParameters() { + if (signature.getParameterCount(false) == 0) { + return new ResolvedJavaMethod.Parameter[0]; + } + return runtime().reflection.getParameters(this); + } + + @Override + public Annotation[][] getParameterAnnotations() { + if ((getConstMethodFlags() & config().constMethodHasParameterAnnotations) == 0 || isClassInitializer()) { + return new Annotation[signature.getParameterCount(false)][0]; + } + return runtime().reflection.getParameterAnnotations(this); + } + + @Override + public Annotation[] getAnnotations() { + if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { + return new Annotation[0]; + } + return runtime().reflection.getMethodAnnotations(this); + } + + @Override + public Annotation[] getDeclaredAnnotations() { + if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { + return new Annotation[0]; + } + return runtime().reflection.getMethodDeclaredAnnotations(this); + } + + @Override + public T getAnnotation(Class annotationClass) { + if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { + return null; + } + return runtime().reflection.getMethodAnnotation(this, annotationClass); + } + + @Override + public boolean isBridge() { + return (BRIDGE & getModifiers()) != 0; + } + + @Override + public boolean isSynthetic() { + return (SYNTHETIC & getModifiers()) != 0; + } + + @Override + public boolean isVarArgs() { + return (VARARGS & getModifiers()) != 0; + } + + @Override + public boolean isDefault() { + // Copied from java.lang.Method.isDefault() + int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC; + return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); + } + + @Override + public Type[] getGenericParameterTypes() { + if (isClassInitializer()) { + return new Type[0]; + } + return runtime().reflection.getGenericParameterTypes(this); + } + + @Override + public boolean canBeInlined() { + if (isForceInline()) { + return true; + } + if (hasNeverInlineDirective()) { + return false; + } + return compilerToVM().isCompilable(this); + } + + @Override + public boolean hasNeverInlineDirective() { + return compilerToVM().hasNeverInlineDirective(this); + } + + @Override + public boolean shouldBeInlined() { + if (isForceInline()) { + return true; + } + return compilerToVM().shouldInlineMethod(this); + } + + @Override + public LineNumberTable getLineNumberTable() { + final boolean hasLineNumberTable = (getConstMethodFlags() & config().constMethodHasLineNumberTable) != 0; + if (!hasLineNumberTable) { + return null; + } + + long[] values = compilerToVM().getLineNumberTable(this); + if (values == null || values.length == 0) { + // Empty table so treat is as non-existent + return null; + } + assert values.length % 2 == 0; + int[] bci = new int[values.length / 2]; + int[] line = new int[values.length / 2]; + + for (int i = 0; i < values.length / 2; i++) { + bci[i] = (int) values[i * 2]; + line[i] = (int) values[i * 2 + 1]; + } + + return new LineNumberTable(line, bci); + } + + @Override + public LocalVariableTable getLocalVariableTable() { + final boolean hasLocalVariableTable = (getConstMethodFlags() & config().constMethodHasLocalVariableTable) != 0; + if (!hasLocalVariableTable) { + return null; + } + + HotSpotVMConfig config = config(); + long localVariableTableElement = compilerToVM().getLocalVariableTableStart(this); + final int localVariableTableLength = compilerToVM().getLocalVariableTableLength(this); + Local[] locals = new Local[localVariableTableLength]; + + for (int i = 0; i < localVariableTableLength; i++) { + final int startBci = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementStartBciOffset); + final int endBci = startBci + UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementLengthOffset); + final int nameCpIndex = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementNameCpIndexOffset); + final int typeCpIndex = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementDescriptorCpIndexOffset); + final int slot = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementSlotOffset); + + String localName = getConstantPool().lookupUtf8(nameCpIndex); + String localType = getConstantPool().lookupUtf8(typeCpIndex); + + locals[i] = new Local(localName, runtime().lookupType(localType, holder, false), startBci, endBci, slot); + + // Go to the next LocalVariableTableElement + localVariableTableElement += config.localVariableTableElementSize; + } + + return new LocalVariableTable(locals); + } + + /** + * Returns the offset of this method into the v-table. The method must have a v-table entry as + * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is + * thrown. + * + * @return the offset of this method into the v-table + */ + @Override + public int vtableEntryOffset(ResolvedJavaType resolved) { + if (!isInVirtualMethodTable(resolved)) { + throw new JVMCIError("%s does not have a vtable entry in type %s", this, resolved); + } + HotSpotVMConfig config = config(); + final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved); + return config.klassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset; + } + + @Override + public boolean isInVirtualMethodTable(ResolvedJavaType resolved) { + if (resolved instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl hotspotResolved = (HotSpotResolvedObjectTypeImpl) resolved; + int vtableIndex = getVtableIndex(hotspotResolved); + return vtableIndex >= 0 && vtableIndex < hotspotResolved.getVtableLength(); + } + return false; + } + + private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) { + if (!holder.isLinked()) { + return config().invalidVtableIndex; + } + if (holder.isInterface()) { + if (resolved.isInterface() || !resolved.isLinked() || !getDeclaringClass().isAssignableFrom(resolved)) { + return config().invalidVtableIndex; + } + return getVtableIndexForInterfaceMethod(resolved); + } + return getVtableIndex(); + } + + /** + * Returns this method's virtual table index. + * + * @return virtual table index + */ + private int getVtableIndex() { + assert !holder.isInterface(); + HotSpotVMConfig config = config(); + int result = UNSAFE.getInt(getMetaspaceMethod() + config.methodVtableIndexOffset); + assert result >= config.nonvirtualVtableIndex : "must be linked"; + return result; + } + + private int getVtableIndexForInterfaceMethod(ResolvedJavaType resolved) { + HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved; + return compilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this); + } + + @Override + public SpeculationLog getSpeculationLog() { + long address = compilerToVM().getFailedSpeculationsAddress(this); + return new HotSpotSpeculationLog(address); + } + + @Override + public int intrinsicId() { + HotSpotVMConfig config = config(); + return UNSAFE.getChar(getMetaspaceMethod() + config.methodIntrinsicIdOffset); + } + + @Override + public boolean isIntrinsicCandidate() { + return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0; + } + + /** + * Allocates a compile id for this method by asking the VM for one. + * + * @param entryBCI entry bci + * @return compile id + */ + @Override + public int allocateCompileId(int entryBCI) { + return compilerToVM().allocateCompileId(this, entryBCI); + } + + @Override + public boolean hasCodeAtLevel(int entryBCI, int level) { + if (entryBCI == config().invocationEntryBci) { + return hasCompiledCodeAtLevel(level); + } + return compilerToVM().hasCompiledCodeForOSR(this, entryBCI, level); + } + + @Override + public int methodIdnum() { + return UNSAFE.getChar(getConstMethod() + config().constMethodMethodIdnumOffset); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.hotspot; + +import java.lang.reflect.Modifier; + +import jdk.vm.ci.meta.JavaMethod; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * Implementation of {@link JavaMethod} for resolved HotSpot methods. + */ +public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod { + + /** + * Returns true if this method has a {@code CallerSensitive} annotation. + * + * @return true if CallerSensitive annotation present, false otherwise + */ + boolean isCallerSensitive(); + + @Override + HotSpotResolvedObjectType getDeclaringClass(); + + /** + * Returns true if this method has a {@code ForceInline} annotation. + * + * @return true if ForceInline annotation present, false otherwise + */ + boolean isForceInline(); + + /** + * Returns true if this method has a {@code ReservedStackAccess} annotation. + * + * @return true if ReservedStackAccess annotation present, false otherwise + */ + boolean hasReservedStackAccess(); + + /** + * Sets flags on {@code method} indicating that it should never be inlined or compiled by the + * VM. + */ + void setNotInlinableOrCompilable(); + + /** + * Returns true if this method is one of the special methods that is ignored by security stack + * walks. + * + * @return true if special method ignored by security stack walks, false otherwise + */ + boolean ignoredBySecurityStackWalk(); + + ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver); + + /** + * Returns whether this method has compiled code. + * + * @return true if this method has compiled code, false otherwise + */ + boolean hasCompiledCode(); + + /** + * @param level + * @return true if the currently installed code was generated at {@code level}. + */ + boolean hasCompiledCodeAtLevel(int level); + + @Override + default boolean isDefault() { + if (isConstructor()) { + return false; + } + // Copied from java.lang.Method.isDefault() + int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC; + return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); + } + + /** + * Returns the offset of this method into the v-table. The method must have a v-table entry as + * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is + * thrown. + * + * @return the offset of this method into the v-table + */ + int vtableEntryOffset(ResolvedJavaType resolved); + + int intrinsicId(); + + /** + * Determines if this method denotes itself as a candidate for intrinsification. As of JDK 9, + * this is denoted by the {@code IntrinsicCandidate} annotation. In earlier JDK versions, this + * method returns true. + * + * @see JDK-8076112 + */ + boolean isIntrinsicCandidate(); + + /** + * Allocates a compile id for this method by asking the VM for one. + * + * @param entryBCI entry bci + * @return compile id + */ + int allocateCompileId(int entryBCI); + + boolean hasCodeAtLevel(int entryBCI, int level); + + int methodIdnum(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.ResolvedJavaType; + +public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType { + + HotSpotResolvedObjectTypeImpl arrayOfType; + + HotSpotResolvedJavaType(String name) { + super(name); + } + + @Override + public abstract boolean equals(Object obj); + + @Override + public final int hashCode() { + return getName().hashCode(); + } + + abstract JavaConstant getJavaMirror(); + + @Override + public HotSpotResolvedObjectType getArrayClass() { + if (arrayOfType == null) { + arrayOfType = runtime().compilerToVm.getArrayType(this); + } + return arrayOfType; + } + + /** + * Checks whether this type is currently being initialized. If a type is being initialized it + * implies that it was {@link #isLinked() linked} and that the static initializer is currently + * being run. + * + * @return {@code true} if this type is being initialized + */ + abstract boolean isBeingInitialized(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1069 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.hotspot; + +import static java.util.Objects.requireNonNull; +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers; +import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.nio.ByteOrder; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.Assumptions.AssumptionResult; +import jdk.vm.ci.meta.Assumptions.ConcreteMethod; +import jdk.vm.ci.meta.Assumptions.ConcreteSubtype; +import jdk.vm.ci.meta.Assumptions.LeafType; +import jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.UnresolvedJavaField; +import jdk.vm.ci.meta.UnresolvedJavaType; + +/** + * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. This class is not + * an {@link MetaspaceHandleObject} because it doesn't have to be scanned for GC. It's liveness is + * maintained by a reference to the {@link Class} instance. + */ +final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, MetaspaceObject { + + private static final HotSpotResolvedJavaField[] NO_FIELDS = new HotSpotResolvedJavaField[0]; + private static final int METHOD_CACHE_ARRAY_CAPACITY = 8; + private static final SortByOffset fieldSortingMethod = new SortByOffset(); + + /** + * The Java class this type represents. + */ + private final long metadataPointer; + + private HotSpotResolvedJavaMethodImpl[] methodCacheArray; + private HashMap methodCacheHashMap; + private volatile HotSpotResolvedJavaField[] instanceFields; + private volatile HotSpotResolvedObjectTypeImpl[] interfaces; + private HotSpotConstantPool constantPool; + private final JavaConstant mirror; + private HotSpotResolvedObjectTypeImpl superClass; + private HotSpotResolvedJavaType componentType; + + /** + * Managed exclusively by {@link HotSpotJDKReflection#getField}. + */ + HashMap reflectionFieldCache; + + static HotSpotResolvedObjectTypeImpl getJavaLangObject() { + return runtime().getJavaLangObject(); + } + + /** + * Gets the JVMCI mirror from a HotSpot type. + * + * Called from the VM. + * + * @param klassPointer a native pointer to the Klass* + * @return the {@link ResolvedJavaType} corresponding to {@code javaClass} + */ + @SuppressWarnings("unused") + @VMEntryPoint + private static HotSpotResolvedObjectTypeImpl fromMetaspace(long klassPointer, String signature) { + return runtime().fromMetaspace(klassPointer, signature); + } + + /** + * Creates the JVMCI mirror for a {@link Class} object. + * + * NOTE: Creating an instance of this class does not install the mirror for the + * {@link Class} type. + *

    + * + * @param metadataPointer the Klass* to create the mirror for + */ + @SuppressWarnings("try") + HotSpotResolvedObjectTypeImpl(long metadataPointer, String name) { + super(name); + assert metadataPointer != 0; + this.metadataPointer = metadataPointer; + + // The mirror object must be in the global scope since + // this object will be cached in HotSpotJVMCIRuntime.resolvedJavaTypes + // and live across more than one compilation. + try (HotSpotObjectConstantScope global = HotSpotObjectConstantScope.enterGlobalScope()) { + this.mirror = runtime().compilerToVm.getJavaMirror(this); + assert getName().charAt(0) != '[' || isArray() : getName(); + } + } + + /** + * Gets the metaspace Klass for this type. + */ + long getMetaspaceKlass() { + long metaspacePointer = getMetaspacePointer(); + if (metaspacePointer == 0) { + throw new NullPointerException("Klass* is null"); + } + return metaspacePointer; + } + + @Override + public long getMetaspacePointer() { + return metadataPointer; + } + + @Override + public int getModifiers() { + if (isArray()) { + return (getElementalType().getModifiers() & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) | Modifier.FINAL | Modifier.ABSTRACT; + } else { + return getAccessFlags() & jvmClassModifiers(); + } + } + + public int getAccessFlags() { + HotSpotVMConfig config = config(); + return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset); + } + + @Override + public ResolvedJavaType getComponentType() { + if (componentType == null) { + if (isArray()) { + componentType = runtime().compilerToVm.getComponentType(this); + } else { + componentType = this; + } + } + return this.equals(componentType) ? null : componentType; + } + + @Override + public AssumptionResult findLeafConcreteSubtype() { + if (isLeaf()) { + // No assumptions are required. + return new AssumptionResult<>(this); + } + HotSpotVMConfig config = config(); + if (isArray()) { + ResolvedJavaType elementalType = getElementalType(); + AssumptionResult elementType = elementalType.findLeafConcreteSubtype(); + if (elementType != null && elementType.getResult().equals(elementalType)) { + /* + * If the elementType is leaf then the array is leaf under the same assumptions but + * only if the element type is exactly the leaf type. The element type can be + * abstract even if there is only one implementor of the abstract type. + */ + AssumptionResult result = new AssumptionResult<>(this); + result.add(elementType); + return result; + } + return null; + } else if (isInterface()) { + HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor(); + /* + * If the implementor field contains itself that indicates that the interface has more + * than one implementors (see: InstanceKlass::add_implementor). + */ + if (implementor == null || implementor.equals(this)) { + return null; + } + + assert !implementor.isInterface(); + if (implementor.isAbstract() || !implementor.isLeafClass()) { + AssumptionResult leafConcreteSubtype = implementor.findLeafConcreteSubtype(); + if (leafConcreteSubtype != null) { + assert !leafConcreteSubtype.getResult().equals(implementor); + AssumptionResult newResult = new AssumptionResult<>(leafConcreteSubtype.getResult(), new ConcreteSubtype(this, implementor)); + // Accumulate leaf assumptions and return the combined result. + newResult.add(leafConcreteSubtype); + return newResult; + } + return null; + } + return concreteSubtype(implementor); + } else { + HotSpotResolvedObjectTypeImpl type = this; + while (type.isAbstract()) { + HotSpotResolvedObjectTypeImpl subklass = type.getSubklass(); + if (subklass == null || UNSAFE.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) { + return null; + } + type = subklass; + } + if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { + return null; + } + if (this.isAbstract()) { + return concreteSubtype(type); + } else { + assert this.equals(type); + return new AssumptionResult<>(type, new LeafType(type)); + } + } + } + + private AssumptionResult concreteSubtype(HotSpotResolvedObjectTypeImpl type) { + if (type.isLeaf()) { + return new AssumptionResult<>(type, new ConcreteSubtype(this, type)); + } else { + return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type)); + } + } + + /** + * Returns if type {@code type} is a leaf class. This is the case if the + * {@code Klass::_subklass} field of the underlying class is zero. + * + * @return true if the type is a leaf class + */ + private boolean isLeafClass() { + return UNSAFE.getLong(this.getMetaspaceKlass() + config().subklassOffset) == 0; + } + + /** + * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given + * type {@code type}. + * + * @return value of the subklass field as metaspace klass pointer + */ + private HotSpotResolvedObjectTypeImpl getSubklass() { + return compilerToVM().getResolvedJavaType(this, config().subklassOffset, false); + } + + @Override + public HotSpotResolvedObjectTypeImpl getSuperclass() { + if (isInterface()) { + return null; + } + HotSpotResolvedObjectTypeImpl javaLangObject = runtime().getJavaLangObject(); + if (this.equals(javaLangObject)) { + return null; + } + if (isArray()) { + return javaLangObject; + } + + // Cache result of native call + if (superClass == null) { + superClass = compilerToVM().getResolvedJavaType(this, config().superOffset, false); + } + return superClass; + } + + @Override + public HotSpotResolvedObjectTypeImpl[] getInterfaces() { + if (interfaces == null) { + if (isArray()) { + HotSpotResolvedObjectTypeImpl[] types = new HotSpotResolvedObjectTypeImpl[2]; + types[0] = runtime().getJavaLangCloneable(); + types[1] = runtime().getJavaLangSerializable(); + this.interfaces = types; + } else { + interfaces = runtime().compilerToVm.getInterfaces(this); + } + } + return interfaces; + } + + @Override + public HotSpotResolvedObjectTypeImpl getSingleImplementor() { + if (!isInterface()) { + throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this); + } + return compilerToVM().getImplementor(this); + } + + @Override + public HotSpotResolvedObjectTypeImpl getSupertype() { + ResolvedJavaType component = getComponentType(); + if (component != null) { + if (component.equals(getJavaLangObject()) || component.isPrimitive()) { + return getJavaLangObject(); + } + HotSpotResolvedObjectTypeImpl supertype = ((HotSpotResolvedObjectTypeImpl) component).getSupertype(); + return (HotSpotResolvedObjectTypeImpl) supertype.getArrayClass(); + } + if (isInterface()) { + return getJavaLangObject(); + } + return getSuperclass(); + } + + @Override + public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) { + if (otherType.isPrimitive()) { + return null; + } else { + HotSpotResolvedObjectTypeImpl t1 = this; + HotSpotResolvedObjectTypeImpl t2 = (HotSpotResolvedObjectTypeImpl) otherType; + while (true) { + if (t1.isAssignableFrom(t2)) { + return t1; + } + if (t2.isAssignableFrom(t1)) { + return t2; + } + t1 = t1.getSupertype(); + t2 = t2.getSupertype(); + } + } + } + + @Override + public AssumptionResult hasFinalizableSubclass() { + assert !isArray(); + if (!compilerToVM().hasFinalizableSubclass(this)) { + return new AssumptionResult<>(false, new NoFinalizableSubclass(this)); + } + return new AssumptionResult<>(true); + } + + @Override + public boolean hasFinalizer() { + return (getAccessFlags() & config().jvmAccHasFinalizer) != 0; + } + + @Override + public boolean isArray() { + return layoutHelper() < config().klassLayoutHelperNeutralValue; + } + + @Override + public boolean isEnum() { + HotSpotResolvedObjectTypeImpl superclass = getSuperclass(); + return superclass != null && superclass.equals(runtime().getJavaLangEnum()); + } + + @Override + public boolean isInitialized() { + return isArray() ? true : getInitState() == config().instanceKlassStateFullyInitialized; + } + + @Override + public boolean isBeingInitialized() { + return isArray() ? false : getInitState() == config().instanceKlassStateBeingInitialized; + } + + @Override + public boolean isLinked() { + return isArray() ? true : getInitState() >= config().instanceKlassStateLinked; + } + + @Override + public void link() { + if (!isLinked()) { + runtime().compilerToVm.ensureLinked(this); + } + } + + @Override + public boolean hasDefaultMethods() { + HotSpotVMConfig config = config(); + int miscFlags = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassMiscFlagsOffset); + return (miscFlags & config.jvmMiscFlagsHasDefaultMethods) != 0; + } + + @Override + public boolean declaresDefaultMethods() { + HotSpotVMConfig config = config(); + int miscFlags = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassMiscFlagsOffset); + return (miscFlags & config.jvmMiscFlagsDeclaresDefaultMethods) != 0; + } + + /** + * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace + * klass. + * + * @return state field value of this type + */ + private int getInitState() { + assert !isArray() : "_init_state only exists in InstanceKlass"; + return UNSAFE.getByte(getMetaspaceKlass() + config().instanceKlassInitStateOffset) & 0xFF; + } + + @Override + public void initialize() { + if (!isInitialized()) { + runtime().compilerToVm.ensureInitialized(this); + assert isInitialized() || isBeingInitialized(); + } + } + + @Override + public boolean isInstance(JavaConstant obj) { + if (obj.getJavaKind() == JavaKind.Object && !obj.isNull()) { + return runtime().reflection.isInstance(this, (HotSpotObjectConstantImpl) obj); + } + return false; + } + + @Override + public boolean isInstanceClass() { + return !isArray() && !isInterface(); + } + + @Override + public boolean isInterface() { + return (getAccessFlags() & config().jvmAccInterface) != 0; + } + + @Override + public boolean isAssignableFrom(ResolvedJavaType other) { + assert other != null; + if (other instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl otherType = (HotSpotResolvedObjectTypeImpl) other; + return runtime().reflection.isAssignableFrom(this, otherType); + } + return false; + } + + @Override + public boolean isJavaLangObject() { + return getName().equals("Ljava/lang/Object;"); + } + + @Override + public JavaKind getJavaKind() { + return JavaKind.Object; + } + + @Override + public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { + assert !callerType.isArray(); + if (isInterface()) { + // Methods can only be resolved against concrete types + return null; + } + if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic() && !isSignaturePolymorphicHolder(method.getDeclaringClass())) { + return method; + } + if (!method.getDeclaringClass().isAssignableFrom(this)) { + return null; + } + if (method.isConstructor()) { + // Constructor calls should have been checked in the verifier and method's + // declaring class is assignable from this (see above) so treat it as resolved. + return method; + } + HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method; + HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType; + return compilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType); + } + + @Override + public HotSpotConstantPool getConstantPool() { + if (constantPool == null || !isArray() && UNSAFE.getAddress(getMetaspaceKlass() + config().instanceKlassConstantsOffset) != constantPool.getMetaspaceConstantPool()) { + /* + * If the pointer to the ConstantPool has changed since this was last read refresh the + * HotSpotConstantPool wrapper object. This ensures that uses of the constant pool are + * operating on the latest one and that HotSpotResolvedJavaMethodImpls will be able to + * use the shared copy instead of creating their own instance. + */ + constantPool = compilerToVM().getConstantPool(this); + } + return constantPool; + } + + /** + * Gets the instance size of this type. If an instance of this type cannot be fast path + * allocated, then the returned value is negative (its absolute value gives the size). Must not + * be called if this is an array or interface type. + */ + @Override + public int instanceSize() { + assert !isArray(); + assert !isInterface(); + + HotSpotVMConfig config = config(); + final int layoutHelper = layoutHelper(); + assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance"; + + // See: Klass::layout_helper_size_in_bytes + int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit; + + // See: Klass::layout_helper_needs_slow_path + boolean needsSlowPath = (layoutHelper & config.klassLayoutHelperInstanceSlowPathBit) != 0; + + return needsSlowPath ? -size : size; + } + + @Override + public int layoutHelper() { + HotSpotVMConfig config = config(); + assert getMetaspaceKlass() != 0 : getName(); + return UNSAFE.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset); + } + + @Override + public long getFingerprint() { + return compilerToVM().getFingerprint(getMetaspaceKlass()); + } + + synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceHandle) { + long metaspaceMethod = UNSAFE.getLong(metaspaceHandle); + // Maintain cache as array. + if (methodCacheArray == null) { + methodCacheArray = new HotSpotResolvedJavaMethodImpl[METHOD_CACHE_ARRAY_CAPACITY]; + } + + int i = 0; + for (; i < methodCacheArray.length; ++i) { + HotSpotResolvedJavaMethodImpl curMethod = methodCacheArray[i]; + if (curMethod == null) { + HotSpotResolvedJavaMethodImpl newMethod = new HotSpotResolvedJavaMethodImpl(this, metaspaceHandle); + methodCacheArray[i] = newMethod; + return newMethod; + } else if (curMethod.getMetaspaceMethod() == metaspaceMethod) { + return curMethod; + } + } + + // Fall-back to hash table. + if (methodCacheHashMap == null) { + methodCacheHashMap = new HashMap<>(); + } + + HotSpotResolvedJavaMethodImpl lookupResult = methodCacheHashMap.get(metaspaceMethod); + if (lookupResult == null) { + HotSpotResolvedJavaMethodImpl newMethod = new HotSpotResolvedJavaMethodImpl(this, metaspaceHandle); + methodCacheHashMap.put(metaspaceMethod, newMethod); + return newMethod; + } else { + return lookupResult; + } + } + + @Override + public int getVtableLength() { + HotSpotVMConfig config = config(); + if (isInterface() || isArray()) { + /* Everything has the core vtable of java.lang.Object */ + return config.baseVtableLength(); + } + int result = UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize); + assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) + " " + config.vtableEntrySize; + return result; + } + + HotSpotResolvedJavaField createField(JavaType type, int offset, int rawFlags, int index) { + return new HotSpotResolvedJavaFieldImpl(this, type, offset, rawFlags, index); + } + + @Override + public AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method) { + HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method; + HotSpotResolvedObjectType declaredHolder = hmethod.getDeclaringClass(); + /* + * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared + * holder, usually because of phis, so make sure that the type is related to the declared + * type before using it for lookup. Unlinked types should also be ignored because we can't + * resolve the proper method to invoke. Generally unlinked types in invokes should result in + * a deopt instead since they can't really be used if they aren't linked yet. + */ + if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) { + if (hmethod.canBeStaticallyBound()) { + // No assumptions are required. + return new AssumptionResult<>(hmethod); + } + ResolvedJavaMethod result = hmethod.uniqueConcreteMethod(declaredHolder); + if (result != null) { + return new AssumptionResult<>(result, new ConcreteMethod(method, declaredHolder, result)); + } + return null; + } + /* + * The holder may be a subtype of the declaredHolder so make sure to resolve the method to + * the correct method for the subtype. + */ + HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this); + if (resolvedMethod == null) { + // The type isn't known to implement the method. + return null; + } + if (resolvedMethod.canBeStaticallyBound()) { + // No assumptions are required. + return new AssumptionResult<>(resolvedMethod); + } + + ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this); + if (result != null) { + return new AssumptionResult<>(result, new ConcreteMethod(method, this, result)); + } + return null; + } + + FieldInfo createFieldInfo(int index) { + return new FieldInfo(index); + } + + public void ensureInitialized() { + runtime().compilerToVm.ensureInitialized(this); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof HotSpotResolvedObjectTypeImpl)) { + return false; + } + HotSpotResolvedObjectTypeImpl that = (HotSpotResolvedObjectTypeImpl) obj; + return getMetaspaceKlass() == that.getMetaspaceKlass(); + } + + @Override + JavaConstant getJavaMirror() { + return mirror; + } + + /** + * This class represents the field information for one field contained in the fields array of an + * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class. + */ + class FieldInfo { + /** + * Native pointer into the array of Java shorts. + */ + private final long metaspaceData; + + /** + * Creates a field info for the field in the fields array at index {@code index}. + * + * @param index index to the fields array + */ + FieldInfo(int index) { + HotSpotVMConfig config = config(); + // Get Klass::_fields + final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); + assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code"; + int offset = config.fieldInfoFieldSlots * Short.BYTES * index; + metaspaceData = metaspaceFields + config.arrayU2DataOffset + offset; + } + + private int getAccessFlags() { + return readFieldSlot(config().fieldInfoAccessFlagsOffset); + } + + private int getNameIndex() { + return readFieldSlot(config().fieldInfoNameIndexOffset); + } + + private int getSignatureIndex() { + return readFieldSlot(config().fieldInfoSignatureIndexOffset); + } + + private int getConstantValueIndex() { + return readFieldSlot(config().fieldInfoConstantValueIndexOffset); + } + + public int getOffset() { + HotSpotVMConfig config = config(); + final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset); + final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset); + final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize; + return offset; + } + + /** + * Helper method to read an entry (slot) from the field array. Currently field info is laid + * on top an array of Java shorts. + */ + private int readFieldSlot(int index) { + int offset = Short.BYTES * index; + return UNSAFE.getChar(metaspaceData + offset); + } + + /** + * Returns the name of this field as a {@link String}. If the field is an internal field the + * name index is pointing into the vmSymbols table. + */ + public String getName() { + final int nameIndex = getNameIndex(); + return isInternal() ? config().symbolAt(nameIndex) : getConstantPool().lookupUtf8(nameIndex); + } + + /** + * Returns the signature of this field as {@link String}. If the field is an internal field + * the signature index is pointing into the vmSymbols table. + */ + public String getSignature() { + final int signatureIndex = getSignatureIndex(); + return isInternal() ? config().symbolAt(signatureIndex) : getConstantPool().lookupUtf8(signatureIndex); + } + + /** + * Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of this field. + * + * @return {@code null} if this field has no {@code ConstantValue} attribute + */ + public JavaConstant getConstantValue() { + int cvIndex = getConstantValueIndex(); + if (cvIndex == 0) { + return null; + } + return constantPool.getStaticFieldConstantValue(cvIndex); + } + + public JavaType getType() { + String signature = getSignature(); + return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false); + } + + private boolean isInternal() { + return (getAccessFlags() & config().jvmAccFieldInternal) != 0; + } + + public boolean isStatic() { + return Modifier.isStatic(getAccessFlags()); + } + + public boolean hasGenericSignature() { + return (getAccessFlags() & config().jvmAccFieldHasGenericSignature) != 0; + } + } + + static class SortByOffset implements Comparator { + public int compare(ResolvedJavaField a, ResolvedJavaField b) { + return a.getOffset() - b.getOffset(); + } + } + + @Override + public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { + if (instanceFields == null) { + if (isArray() || isInterface()) { + instanceFields = NO_FIELDS; + } else { + HotSpotResolvedJavaField[] prepend = NO_FIELDS; + if (getSuperclass() != null) { + prepend = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true); + } + instanceFields = getFields(false, prepend); + } + } + if (!includeSuperclasses && getSuperclass() != null) { + int superClassFieldCount = getSuperclass().getInstanceFields(true).length; + if (superClassFieldCount == instanceFields.length) { + // This class does not have any instance fields of its own. + return NO_FIELDS; + } else if (superClassFieldCount != 0) { + // Fields of the current class can be interleaved with fields of its super-classes + // but the array of fields to be returned must be sorted by increasing offset + // This code populates the array, then applies the sorting function + HotSpotResolvedJavaField[] result = new HotSpotResolvedJavaField[instanceFields.length - superClassFieldCount]; + int i = 0; + for (HotSpotResolvedJavaField f : instanceFields) { + if (f.getDeclaringClass() == this) { + result[i++] = f; + } + } + Arrays.sort(result, fieldSortingMethod); + return result; + } else { + // The super classes of this class do not have any instance fields. + } + } + return instanceFields; + } + + @Override + public ResolvedJavaField[] getStaticFields() { + if (isArray()) { + return new HotSpotResolvedJavaField[0]; + } else { + return getFields(true, NO_FIELDS); + } + } + + /** + * Gets the instance or static fields of this class. + * + * @param retrieveStaticFields specifies whether to return instance or static fields + * @param prepend an array to be prepended to the returned result + */ + private HotSpotResolvedJavaField[] getFields(boolean retrieveStaticFields, HotSpotResolvedJavaField[] prepend) { + HotSpotVMConfig config = config(); + final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); + int metaspaceFieldsLength = UNSAFE.getInt(metaspaceFields + config.arrayU1LengthOffset); + int resultCount = 0; + int index = 0; + for (int i = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) { + FieldInfo field = new FieldInfo(index); + if (field.hasGenericSignature()) { + metaspaceFieldsLength--; + } + + if (field.isStatic() == retrieveStaticFields) { + resultCount++; + } + } + + if (resultCount == 0) { + return prepend; + } + + int prependLength = prepend.length; + resultCount += prependLength; + + HotSpotResolvedJavaField[] result = new HotSpotResolvedJavaField[resultCount]; + if (prependLength != 0) { + System.arraycopy(prepend, 0, result, 0, prependLength); + } + + // Fields of the current class can be interleaved with fields of its super-classes + // but the array of fields to be returned must be sorted by increasing offset + // This code populates the array, then applies the sorting function + int resultIndex = prependLength; + for (int i = 0; i < index; ++i) { + FieldInfo field = new FieldInfo(i); + if (field.isStatic() == retrieveStaticFields) { + int offset = field.getOffset(); + HotSpotResolvedJavaField resolvedJavaField = createField(field.getType(), offset, field.getAccessFlags(), i); + result[resultIndex++] = resolvedJavaField; + } + } + Arrays.sort(result, fieldSortingMethod); + return result; + } + + @Override + public String getSourceFileName() { + if (isArray()) { + return null; + } + return getConstantPool().getSourceFileName(); + } + + @Override + public Annotation[] getAnnotations() { + return runtime().reflection.getAnnotations(this); + } + + @Override + public Annotation[] getDeclaredAnnotations() { + return runtime().reflection.getDeclaredAnnotations(this); + } + + @Override + public T getAnnotation(Class annotationClass) { + return runtime().reflection.getAnnotation(this, annotationClass); + } + + /** + * Performs a fast-path check that this type is resolved in the context of a given accessing + * class. A negative result does not mean this type is not resolved with respect to + * {@code accessingClass}. That can only be determined by + * {@linkplain HotSpotJVMCIRuntime#lookupType(String, HotSpotResolvedObjectType, boolean) + * re-resolving} the type. + */ + @Override + public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) { + assert accessingClass != null; + ResolvedJavaType elementType = getElementalType(); + if (elementType.isPrimitive()) { + // Primitive type resolution is context free. + return true; + } + if (elementType.getName().startsWith("Ljava/") && hasSameClassLoader(runtime().getJavaLangObject())) { + // Classes in a java.* package defined by the boot class loader are always resolved. + return true; + } + HotSpotResolvedObjectTypeImpl otherMirror = ((HotSpotResolvedObjectTypeImpl) accessingClass); + return hasSameClassLoader(otherMirror); + } + + private boolean hasSameClassLoader(HotSpotResolvedObjectTypeImpl otherMirror) { + return UnsafeAccess.UNSAFE.getAddress(getMetaspaceKlass() + config().classLoaderDataOffset) == UnsafeAccess.UNSAFE.getAddress( + otherMirror.getMetaspaceKlass() + config().classLoaderDataOffset); + } + + @Override + public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { + if (isDefinitelyResolvedWithRespectTo(requireNonNull(accessingClass))) { + return this; + } + HotSpotResolvedObjectTypeImpl accessingType = (HotSpotResolvedObjectTypeImpl) accessingClass; + return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true); + } + + /** + * Gets the metaspace Klass boxed in a {@link JavaConstant}. + */ + @Override + public Constant klass() { + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false); + } + + @Override + public boolean isPrimaryType() { + return config().secondarySuperCacheOffset != superCheckOffset(); + } + + @Override + public int superCheckOffset() { + HotSpotVMConfig config = config(); + return UNSAFE.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset); + } + + @Override + public long prototypeMarkWord() { + HotSpotVMConfig config = config(); + if (isArray()) { + return config.arrayPrototypeMarkWord(); + } else { + return UNSAFE.getAddress(getMetaspaceKlass() + config.prototypeMarkWordOffset); + } + } + + @Override + public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedEntryKind) { + ResolvedJavaField[] declaredFields = getInstanceFields(true); + return findFieldWithOffset(offset, expectedEntryKind, declaredFields); + } + + public ResolvedJavaField findStaticFieldWithOffset(long offset, JavaKind expectedEntryKind) { + ResolvedJavaField[] declaredFields = getStaticFields(); + return findFieldWithOffset(offset, expectedEntryKind, declaredFields); + } + + private static ResolvedJavaField findFieldWithOffset(long offset, JavaKind expectedEntryKind, ResolvedJavaField[] declaredFields) { + for (ResolvedJavaField field : declaredFields) { + long resolvedFieldOffset = field.getOffset(); + // @formatter:off + if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN && + expectedEntryKind.isPrimitive() && + !expectedEntryKind.equals(JavaKind.Void) && + field.getJavaKind().isPrimitive()) { + resolvedFieldOffset += + field.getJavaKind().getByteCount() - + Math.min(field.getJavaKind().getByteCount(), 4 + expectedEntryKind.getByteCount()); + } + if (resolvedFieldOffset == offset) { + return field; + } + // @formatter:on + } + return null; + } + + @Override + public boolean isLocal() { + return runtime().reflection.isLocalClass(this); + } + + @Override + public boolean isMember() { + return runtime().reflection.isMemberClass(this); + } + + @Override + public HotSpotResolvedObjectType getEnclosingType() { + return runtime().reflection.getEnclosingClass(this); + } + + @Override + public ResolvedJavaMethod[] getDeclaredConstructors() { + link(); + return runtime().compilerToVm.getDeclaredConstructors(this); + } + + @Override + public ResolvedJavaMethod[] getDeclaredConstructors(boolean forceLink) { + if (forceLink) { + link(); + } + return runtime().compilerToVm.getDeclaredConstructors(this); + } + + @Override + public ResolvedJavaMethod[] getDeclaredMethods() { + return getDeclaredMethods(true); + } + + @Override + public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { + if (forceLink) { + link(); + } + return runtime().compilerToVm.getDeclaredMethods(this); + } + + @Override + public ResolvedJavaMethod getClassInitializer() { + if (!isArray()) { + return compilerToVM().getClassInitializer(this); + } + return null; + } + + @Override + public String toString() { + return "HotSpotType<" + getName() + ", resolved>"; + } + + @Override + public ResolvedJavaType lookupType(UnresolvedJavaType unresolvedJavaType, boolean resolve) { + JavaType javaType = HotSpotJVMCIRuntime.runtime().lookupType(unresolvedJavaType.getName(), this, resolve); + if (javaType instanceof ResolvedJavaType) { + return (ResolvedJavaType) javaType; + } + return null; + } + + @Override + public ResolvedJavaField resolveField(UnresolvedJavaField unresolvedJavaField, ResolvedJavaType accessingClass) { + for (ResolvedJavaField field : getInstanceFields(false)) { + if (field.getName().equals(unresolvedJavaField.getName())) { + return field; + } + } + for (ResolvedJavaField field : getStaticFields()) { + if (field.getName().equals(unresolvedJavaField.getName())) { + return field; + } + } + throw new InternalError(unresolvedJavaField.toString()); + } + + @Override + public boolean isCloneableWithAllocation() { + return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0; + } + + private int getMiscFlags() { + return UNSAFE.getInt(getMetaspaceKlass() + config().instanceKlassMiscFlagsOffset); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.Assumptions.AssumptionResult; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.ConstantPool; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. + */ +public interface HotSpotResolvedObjectType extends ResolvedJavaType { + + @Override + HotSpotResolvedObjectType getArrayClass(); + + @Override + ResolvedJavaType getComponentType(); + + @Override + AssumptionResult findLeafConcreteSubtype(); + + @Override + HotSpotResolvedObjectType getSuperclass(); + + @Override + HotSpotResolvedObjectType[] getInterfaces(); + + HotSpotResolvedObjectType getSupertype(); + + @Override + HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType); + + @Override + default boolean isPrimitive() { + return false; + } + + @Override + default JavaKind getJavaKind() { + return JavaKind.Object; + } + + ConstantPool getConstantPool(); + + /** + * Gets the instance size of this type. If an instance of this type cannot be fast path + * allocated, then the returned value is negative (its absolute value gives the size). Must not + * be called if this is an array or interface type. + */ + int instanceSize(); + + int getVtableLength(); + + @Override + AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method); + + /** + * Performs a fast-path check that this type is resolved in the context of a given accessing + * class. A negative result does not mean this type is not resolved with respect to + * {@code accessingClass}. That can only be determined by + * {@linkplain HotSpotJVMCIRuntime#lookupType(String, HotSpotResolvedObjectType, boolean) + * re-resolving} the type. + */ + boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass); + + /** + * Gets the metaspace Klass boxed in a {@link JavaConstant}. + */ + Constant klass(); + + boolean isPrimaryType(); + + int superCheckOffset(); + + long prototypeMarkWord(); + + int layoutHelper(); + + @Override + HotSpotResolvedObjectType getEnclosingType(); + + @Override + ResolvedJavaMethod getClassInitializer(); + + /** + * Gets the fingerprint for this type. + * + * @return the value of the fingerprint ({@code 0} for arrays and synthetic classes or if the VM + * does not support fingerprints) + */ + long getFingerprint(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.hotspot; + +import static java.util.Objects.requireNonNull; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Modifier; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.meta.Assumptions.AssumptionResult; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * Implementation of {@link JavaType} for primitive HotSpot types. + */ +public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType { + + @NativeImageReinitialize static HotSpotResolvedPrimitiveType[] primitives; + + private JavaKind kind; + HotSpotObjectConstantImpl mirror; + + /** + * Creates the JVMCI mirror for a primitive {@link JavaKind}. + * + * @param kind the Kind to create the mirror for + */ + private HotSpotResolvedPrimitiveType(JavaKind kind, HotSpotObjectConstantImpl mirror) { + super(String.valueOf(kind.getTypeChar())); + this.mirror = mirror; + this.kind = kind; + } + + static HotSpotResolvedPrimitiveType forKind(JavaKind kind) { + HotSpotResolvedPrimitiveType primitive = primitives[kind.getBasicType()]; + assert primitive != null : kind; + return primitive; + } + + @VMEntryPoint + static HotSpotResolvedPrimitiveType fromMetaspace(HotSpotObjectConstantImpl mirror, char typeChar) { + JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(typeChar); + if (primitives == null) { + primitives = new HotSpotResolvedPrimitiveType[JavaKind.Void.getBasicType() + 1]; + } + HotSpotResolvedPrimitiveType result = new HotSpotResolvedPrimitiveType(kind, mirror); + primitives[kind.getBasicType()] = result; + return result; + } + + @Override + public int getModifiers() { + return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; + } + + @Override + public HotSpotResolvedObjectType getArrayClass() { + if (kind == JavaKind.Void) { + return null; + } + return super.getArrayClass(); + } + + @Override + public ResolvedJavaType getElementalType() { + return this; + } + + @Override + public ResolvedJavaType getComponentType() { + return null; + } + + @Override + public ResolvedJavaType getSuperclass() { + return null; + } + + @Override + public ResolvedJavaType[] getInterfaces() { + return new ResolvedJavaType[0]; + } + + @Override + public ResolvedJavaType getSingleImplementor() { + throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this); + } + + @Override + public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) { + return null; + } + + @Override + public AssumptionResult hasFinalizableSubclass() { + return new AssumptionResult<>(false); + } + + @Override + public boolean hasFinalizer() { + return false; + } + + @Override + public boolean isArray() { + return false; + } + + @Override + public boolean isEnum() { + return false; + } + + @Override + public boolean isPrimitive() { + return true; + } + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public boolean isBeingInitialized() { + return false; + } + + @Override + public boolean isLinked() { + return true; + } + + @Override + public boolean isInstance(JavaConstant obj) { + return false; + } + + @Override + public boolean isInstanceClass() { + return false; + } + + @Override + public boolean isInterface() { + return false; + } + + @Override + public boolean isAssignableFrom(ResolvedJavaType other) { + assert other != null; + return other.equals(this); + } + + @Override + public JavaKind getJavaKind() { + return kind; + } + + @Override + public boolean isJavaLangObject() { + return false; + } + + @Override + public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { + return null; + } + + @Override + public String toString() { + return "HotSpotResolvedPrimitiveType<" + kind + ">"; + } + + @Override + public AssumptionResult findLeafConcreteSubtype() { + return new AssumptionResult<>(this); + } + + @Override + public AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method) { + return null; + } + + @Override + public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { + return new ResolvedJavaField[0]; + } + + @Override + public ResolvedJavaField[] getStaticFields() { + return new ResolvedJavaField[0]; + } + + @Override + public Annotation[] getAnnotations() { + return new Annotation[0]; + } + + @Override + public Annotation[] getDeclaredAnnotations() { + return new Annotation[0]; + } + + @Override + public T getAnnotation(Class annotationClass) { + return null; + } + + @Override + public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { + requireNonNull(accessingClass); + return this; + } + + @Override + public void initialize() { + } + + @Override + public void link() { + } + + @Override + public boolean hasDefaultMethods() { + return false; + } + + @Override + public boolean declaresDefaultMethods() { + return false; + } + + @Override + public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedType) { + return null; + } + + @Override + public String getSourceFileName() { + throw JVMCIError.unimplemented(); + } + + @Override + public boolean isLocal() { + return false; + } + + @Override + public boolean isMember() { + return false; + } + + @Override + public ResolvedJavaType getEnclosingType() { + return null; + } + + @Override + public ResolvedJavaMethod[] getDeclaredConstructors() { + return new ResolvedJavaMethod[0]; + } + + @Override + public ResolvedJavaMethod[] getDeclaredMethods() { + return new ResolvedJavaMethod[0]; + } + + @Override + public ResolvedJavaMethod getClassInitializer() { + return null; + } + + @Override + public boolean isCloneableWithAllocation() { + return false; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof HotSpotResolvedPrimitiveType)) { + return false; + } + HotSpotResolvedPrimitiveType that = (HotSpotResolvedPrimitiveType) obj; + return that.kind == kind; + } + + @Override + JavaConstant getJavaMirror() { + return mirror; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.InvalidInstalledCodeException; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Implementation of {@link InstalledCode} for code installed as a {@code RuntimeStub}. The address + * of the {@code RuntimeStub} is stored in {@link InstalledCode#address} and the value of + * {@code RuntimeStub::entry_point()} is in {@link InstalledCode#entryPoint}. + */ +public class HotSpotRuntimeStub extends HotSpotInstalledCode { + + public HotSpotRuntimeStub(String name) { + super(name); + } + + public ResolvedJavaMethod getMethod() { + return null; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public void invalidate() { + } + + @Override + public String toString() { + return String.format("InstalledRuntimeStub[stub=%s, codeBlob=0x%x]", name, getAddress()); + } + + @Override + public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { + throw new InternalError("Cannot call stub " + name); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.VMConstant; +import jdk.vm.ci.meta.Value; +import jdk.vm.ci.meta.ValueKind; + +public final class HotSpotSentinelConstant extends Value implements JavaConstant, VMConstant { + + private final JavaKind javaKind; + + public HotSpotSentinelConstant(ValueKind valueKind, JavaKind javaKind) { + super(valueKind); + this.javaKind = javaKind; + } + + @Override + public JavaKind getJavaKind() { + return javaKind; + } + + @Override + public boolean isNull() { + return true; + } + + @Override + public boolean isDefaultForKind() { + return true; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public String toString() { + return JavaConstant.toString(this); + } + + @Override + public String toValueString() { + return "sentinel"; + } + + @Override + public int hashCode() { + return 13; + } + + @Override + public boolean equals(Object o) { + return o instanceof HotSpotSentinelConstant; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSignature.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSignature.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSignature.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSignature.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.ArrayList; +import java.util.List; + +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.Signature; +import jdk.vm.ci.meta.UnresolvedJavaType; + +/** + * Represents a method signature. + */ +public class HotSpotSignature implements Signature { + + private final List parameters = new ArrayList<>(); + private final String returnType; + private final String originalString; + private ResolvedJavaType[] parameterTypes; + private ResolvedJavaType returnTypeCache; + private final HotSpotJVMCIRuntime runtime; + + public HotSpotSignature(HotSpotJVMCIRuntime runtime, String signature) { + this.runtime = runtime; + if (signature.length() == 0) { + throw new IllegalArgumentException("Signature cannot be empty"); + } + this.originalString = signature; + + if (signature.charAt(0) == '(') { + int cur = 1; + while (cur < signature.length() && signature.charAt(cur) != ')') { + int nextCur = parseSignature(signature, cur); + parameters.add(signature.substring(cur, nextCur)); + cur = nextCur; + } + + cur++; + int nextCur = parseSignature(signature, cur); + returnType = signature.substring(cur, nextCur); + if (nextCur != signature.length()) { + throw new IllegalArgumentException("Extra characters at end of signature: " + signature); + } + } else { + throw new IllegalArgumentException("Signature must start with a '(': " + signature); + } + } + + public HotSpotSignature(HotSpotJVMCIRuntime runtime, ResolvedJavaType returnType, ResolvedJavaType... parameterTypes) { + this.runtime = runtime; + this.parameterTypes = parameterTypes.clone(); + this.returnTypeCache = returnType; + this.returnType = returnType.getName(); + StringBuilder sb = new StringBuilder("("); + for (JavaType type : parameterTypes) { + parameters.add(type.getName()); + sb.append(type.getName()); + } + sb.append(")").append(returnType.getName()); + this.originalString = sb.toString(); + assert new HotSpotSignature(runtime, originalString).equals(this); + } + + private static int parseSignature(String signature, int start) { + try { + int cur = start; + char first; + do { + first = signature.charAt(cur); + cur++; + } while (first == '['); + + switch (first) { + case 'L': + while (signature.charAt(cur) != ';') { + if (signature.charAt(cur) == '.') { + throw new IllegalArgumentException("Class name in signature contains '.' at index " + cur + ": " + signature); + } + cur++; + } + cur++; + break; + case 'V': + case 'I': + case 'B': + case 'C': + case 'D': + case 'F': + case 'J': + case 'S': + case 'Z': + break; + default: + throw new IllegalArgumentException("Invalid character '" + signature.charAt(cur - 1) + "' at index " + (cur - 1) + " in signature: " + signature); + } + return cur; + } catch (StringIndexOutOfBoundsException e) { + throw new IllegalArgumentException("Truncated signature: " + signature); + } + } + + @Override + public int getParameterCount(boolean withReceiver) { + return parameters.size() + (withReceiver ? 1 : 0); + } + + @Override + public JavaKind getParameterKind(int index) { + return JavaKind.fromTypeString(parameters.get(index)); + } + + private static boolean checkValidCache(ResolvedJavaType type, ResolvedJavaType accessingClass) { + assert accessingClass != null; + if (type == null) { + return false; + } else if (type instanceof HotSpotResolvedObjectTypeImpl) { + return ((HotSpotResolvedObjectTypeImpl) type).isDefinitelyResolvedWithRespectTo(accessingClass); + } + return true; + } + + private static JavaType getUnresolvedOrPrimitiveType(HotSpotJVMCIRuntime runtime, String name) { + if (name.length() == 1) { + JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); + return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(kind.toJavaClass()); + } + return UnresolvedJavaType.create(name); + } + + @Override + public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { + if (accessingClass == null) { + // Caller doesn't care about resolution context so return an unresolved + // or primitive type (primitive type resolution is context free) + return getUnresolvedOrPrimitiveType(runtime, parameters.get(index)); + } + if (parameterTypes == null) { + parameterTypes = new ResolvedJavaType[parameters.size()]; + } + + ResolvedJavaType type = parameterTypes[index]; + if (!checkValidCache(type, accessingClass)) { + JavaType result = runtime.lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false); + if (result instanceof ResolvedJavaType) { + type = (ResolvedJavaType) result; + parameterTypes[index] = type; + } else { + assert result != null; + return result; + } + } + assert type != null; + return type; + } + + @Override + public String toMethodDescriptor() { + assert originalString.equals(Signature.super.toMethodDescriptor()) : originalString + " != " + Signature.super.toMethodDescriptor(); + return originalString; + } + + @Override + public JavaKind getReturnKind() { + return JavaKind.fromTypeString(returnType); + } + + @Override + public JavaType getReturnType(ResolvedJavaType accessingClass) { + if (accessingClass == null) { + // Caller doesn't care about resolution context so return an unresolved + // or primitive type (primitive type resolution is context free) + return getUnresolvedOrPrimitiveType(runtime, returnType); + } + if (!checkValidCache(returnTypeCache, accessingClass)) { + JavaType result = runtime.lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false); + if (result instanceof ResolvedJavaType) { + returnTypeCache = (ResolvedJavaType) result; + } else { + return result; + } + } + return returnTypeCache; + } + + @Override + public String toString() { + return "HotSpotSignature<" + originalString + ">"; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof HotSpotSignature) { + HotSpotSignature other = (HotSpotSignature) obj; + if (other.originalString.equals(originalString)) { + assert other.parameters.equals(parameters); + assert other.returnType.equals(returnType); + return true; + } + } + return false; + } + + @Override + public int hashCode() { + return originalString.hashCode(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,224 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReasonEncoding; + +/** + * Implements a {@link SpeculationReasonEncoding} that {@linkplain #getByteArray() produces} a byte + * array. Data is added via a {@link DataOutputStream}. When producing the final byte array, if the + * total length of data exceeds {@value HotSpotSpeculationEncoding#MAX_LENGTH}, then a SHA-1 digest + * of the data is produced instead. + */ +final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements SpeculationReasonEncoding { + + /** + * Number of bits used for the length of an encoded speculation. The bit size of 5 is chosen to + * accommodate specifying // the length of a SHA-1 digest (i.e., 20 bytes). + */ + // Also defined in C++ JVMCINMethodData class - keep in sync. + static final int LENGTH_BITS = 5; + + /** + * The maximum length of an encoded speculation. + */ + static final int MAX_LENGTH = (1 << LENGTH_BITS) - 1; + + static final int LENGTH_MASK = MAX_LENGTH; + + private DataOutputStream dos = new DataOutputStream(this); + private byte[] result; + + HotSpotSpeculationEncoding() { + super(SHA1_LENGTH); + } + + private void checkOpen() { + if (result != null) { + throw new IllegalArgumentException("Cannot update closed speculation encoding"); + } + } + + private static final int NULL_METHOD = -1; + private static final int NULL_TYPE = -2; + private static final int NULL_STRING = -3; + + @Override + public void addByte(int value) { + checkOpen(); + try { + dos.writeByte(value); + } catch (IOException e) { + throw new InternalError(e); + } + } + + @Override + public void addShort(int value) { + checkOpen(); + try { + dos.writeShort(value); + } catch (IOException e) { + throw new InternalError(e); + } + } + + @Override + public void addMethod(ResolvedJavaMethod method) { + if (!addNull(method, NULL_METHOD)) { + checkOpen(); + if (method instanceof HotSpotResolvedJavaMethodImpl) { + try { + dos.writeLong(((HotSpotResolvedJavaMethodImpl) method).getMetaspaceMethod()); + } catch (IOException e) { + throw new InternalError(e); + } + } else { + throw new IllegalArgumentException("Cannot encode unsupported type " + method.getClass().getName() + ": " + method.format("%H.%n(%p)")); + } + } + } + + @Override + public void addType(ResolvedJavaType type) { + if (!addNull(type, NULL_TYPE)) { + checkOpen(); + if (type instanceof HotSpotResolvedObjectTypeImpl) { + try { + dos.writeLong(((HotSpotResolvedObjectTypeImpl) type).getMetaspaceKlass()); + } catch (IOException e) { + throw new InternalError(e); + } + } else { + throw new IllegalArgumentException("Cannot encode unsupported type " + type.getClass().getName() + ": " + type.toClassName()); + } + } + } + + @Override + public void addString(String value) { + if (!addNull(value, NULL_STRING)) { + checkOpen(); + try { + dos.writeChars(value); + } catch (IOException e) { + throw new InternalError(e); + } + } + } + + @Override + public void addInt(int value) { + checkOpen(); + try { + dos.writeInt(value); + } catch (IOException e) { + throw new InternalError(e); + } + } + + @Override + public void addLong(long value) { + checkOpen(); + try { + dos.writeLong(value); + } catch (IOException e) { + throw new InternalError(e); + } + } + + private boolean addNull(Object o, int nullValue) { + if (o == null) { + addInt(nullValue); + return true; + } + return false; + } + + /** + * Prototype SHA1 digest. + */ + private static final MessageDigest SHA1; + + /** + * Cloning the prototype is quicker than calling {@link MessageDigest#getInstance(String)} every + * time. + */ + private static final boolean SHA1_IS_CLONEABLE; + private static final int SHA1_LENGTH = 20; + + static { + MessageDigest sha1 = null; + boolean sha1IsCloneable = false; + try { + sha1 = MessageDigest.getInstance("SHA-1"); + sha1.clone(); + sha1IsCloneable = true; + } catch (NoSuchAlgorithmException e) { + // Should never happen given that SHA-1 is mandated in a + // compliant Java platform implementation. + throw new JVMCIError(e); + } catch (CloneNotSupportedException e) { + } + SHA1 = sha1; + SHA1_IS_CLONEABLE = sha1IsCloneable; + assert SHA1.getDigestLength() == SHA1_LENGTH; + assert SHA1_LENGTH < MAX_LENGTH; + } + + /** + * Gets the final encoded byte array and closes this encoding such that any further attempts to + * update it result in an {@link IllegalArgumentException}. + */ + byte[] getByteArray() { + if (result == null) { + if (count > MAX_LENGTH) { + try { + MessageDigest md = SHA1_IS_CLONEABLE ? (MessageDigest) SHA1.clone() : MessageDigest.getInstance("SHA-1"); + md.update(buf, 0, count); + result = md.digest(); + } catch (CloneNotSupportedException | NoSuchAlgorithmException e) { + throw new InternalError(e); + } + } else { + if (buf.length == count) { + // No need to copy the byte array + return buf; + } + result = Arrays.copyOf(buf, count); + } + dos = null; + } + return result; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2014, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Formatter; +import java.util.List; + +import jdk.vm.ci.code.BailoutException; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.SpeculationLog; + +/** + * Implements a {@link SpeculationLog} that can be used to: + *
      + *
    • Query failed speculations recorded in a native linked list of {@code FailedSpeculation}s (see + * methodData.hpp).
    • + *
    • Make speculations during compilation and record them in compiled code. This must only be done + * on compilation-local {@link HotSpotSpeculationLog} objects.
    • + *
    + * + * The choice of constructor determines whether the native failed speculations list is + * {@linkplain #managesFailedSpeculations() managed} by a {@link HotSpotSpeculationLog} object. + */ +public class HotSpotSpeculationLog implements SpeculationLog { + + private static final byte[] NO_FLATTENED_SPECULATIONS = {}; + + /** + * Creates a speculation log that manages a failed speculation list. That is, when this object + * dies, the native resources of the list are freed. + * + * @see #managesFailedSpeculations() + * @see #getFailedSpeculationsAddress() + */ + public HotSpotSpeculationLog() { + managesFailedSpeculations = true; + } + + /** + * Creates a speculation log that reads from an externally managed failed speculation list. That + * is, the lifetime of the list is independent of this object. + * + * @param failedSpeculationsAddress an address in native memory at which the pointer to the + * externally managed sailed speculation list resides + */ + public HotSpotSpeculationLog(long failedSpeculationsAddress) { + if (failedSpeculationsAddress == 0) { + throw new IllegalArgumentException("failedSpeculationsAddress cannot be 0"); + } + this.failedSpeculationsAddress = failedSpeculationsAddress; + managesFailedSpeculations = false; + } + + /** + * Gets the address of the pointer to the native failed speculations list. + * + * @see #managesFailedSpeculations() + */ + public long getFailedSpeculationsAddress() { + if (managesFailedSpeculations) { + synchronized (this) { + if (failedSpeculationsAddress == 0L) { + failedSpeculationsAddress = UnsafeAccess.UNSAFE.allocateMemory(HotSpotJVMCIRuntime.getHostWordKind().getByteCount()); + UnsafeAccess.UNSAFE.putAddress(failedSpeculationsAddress, 0L); + LogCleaner c = new LogCleaner(this, failedSpeculationsAddress); + assert c.address == failedSpeculationsAddress; + } + } + } + return failedSpeculationsAddress; + } + + /** + * Adds {@code speculation} to the native list of failed speculations. To update this object's + * view of the failed speculations, {@link #collectFailedSpeculations()} must be called after + * this method returns. + * + * This method exists primarily for testing purposes. Speculations are normally only added to + * the list by HotSpot during deoptimization. + * + * @return {@code false} if the speculation could not be appended to the list + */ + public boolean addFailedSpeculation(Speculation speculation) { + return compilerToVM().addFailedSpeculation(getFailedSpeculationsAddress(), ((HotSpotSpeculation) speculation).encoding); + } + + /** + * Returns {@code true} if the value returned by {@link #getFailedSpeculationsAddress()} is only + * valid only as long as this object is alive, {@code false} otherwise. + */ + public boolean managesFailedSpeculations() { + return managesFailedSpeculations; + } + + public static final class HotSpotSpeculation extends Speculation { + + /** + * A speculation id is a long encoding a length (low 5 bits) and an index into a + * {@code byte[]}. Combined, the index and length denote where the {@linkplain #encoding + * encoded speculation} is in a {@linkplain HotSpotSpeculationLog#getFlattenedSpeculations + * flattened} speculations array. + */ + private final JavaConstant id; + + private final byte[] encoding; + + HotSpotSpeculation(SpeculationReason reason, JavaConstant id, byte[] encoding) { + super(reason); + this.id = id; + this.encoding = encoding; + } + + public JavaConstant getEncoding() { + return id; + } + + @Override + public String toString() { + long indexAndLength = id.asLong(); + int index = decodeIndex(indexAndLength); + int length = decodeLength(indexAndLength); + return String.format("{0x%016x[index: %d, len: %d, hash: 0x%x]: %s}", indexAndLength, index, length, Arrays.hashCode(encoding), getReason()); + } + } + + /** + * Address of a pointer to a set of failed speculations. The address is recorded in the nmethod + * compiled with this speculation log such that when it fails a speculation, the speculation is + * added to the list. + */ + private long failedSpeculationsAddress; + + private final boolean managesFailedSpeculations; + + /** + * The list of failed speculations read from native memory via + * {@link CompilerToVM#getFailedSpeculations}. + */ + private byte[][] failedSpeculations; + + /** + * Speculations made during the compilation associated with this log. + */ + private List speculations; + private List speculationReasons; + + @Override + public void collectFailedSpeculations() { + if (failedSpeculationsAddress != 0 && UnsafeAccess.UNSAFE.getLong(failedSpeculationsAddress) != 0) { + failedSpeculations = compilerToVM().getFailedSpeculations(failedSpeculationsAddress, failedSpeculations); + assert failedSpeculations.getClass() == byte[][].class; + } + } + + byte[] getFlattenedSpeculations(boolean validate) { + if (speculations == null) { + return NO_FLATTENED_SPECULATIONS; + } + if (validate) { + int newFailuresStart = failedSpeculations == null ? 0 : failedSpeculations.length; + collectFailedSpeculations(); + if (failedSpeculations != null && failedSpeculations.length != newFailuresStart) { + for (SpeculationReason reason : speculationReasons) { + byte[] encoding = encode(reason); + // Only check against new failures + if (contains(failedSpeculations, newFailuresStart, encoding)) { + throw new BailoutException(false, "Speculation failed: " + reason); + } + } + } + } + int size = 0; + for (byte[] s : speculations) { + size += s.length; + } + byte[] result = new byte[size]; + size = 0; + for (byte[] s : speculations) { + System.arraycopy(s, 0, result, size, s.length); + size += s.length; + } + return result; + } + + @Override + public boolean maySpeculate(SpeculationReason reason) { + if (failedSpeculations == null) { + collectFailedSpeculations(); + } + if (failedSpeculations != null && failedSpeculations.length != 0) { + byte[] encoding = encode(reason); + return !contains(failedSpeculations, 0, encoding); + } + return true; + } + + /** + * @return {@code true} if {@code needle} is in {@code haystack[fromIndex..haystack.length-1]} + */ + private static boolean contains(byte[][] haystack, int fromIndex, byte[] needle) { + for (int i = fromIndex; i < haystack.length; i++) { + byte[] fs = haystack[i]; + + if (Arrays.equals(fs, needle)) { + return true; + } + } + return false; + } + + private static long encodeIndexAndLength(int index, int length) { + if (length > HotSpotSpeculationEncoding.MAX_LENGTH || length < 0) { + throw new InternalError(String.format("Invalid encoded speculation length: %d (0x%x)", length, length)); + } + if (index < 0) { + throw new JVMCIError("Encoded speculation index is negative: %d (0x%x)", index, index); + } + return (index << HotSpotSpeculationEncoding.LENGTH_BITS) | length; + } + + private static int decodeIndex(long indexAndLength) { + return (int) (indexAndLength >>> HotSpotSpeculationEncoding.LENGTH_BITS); + } + + private static int decodeLength(long indexAndLength) { + return (int) (indexAndLength & HotSpotSpeculationEncoding.LENGTH_MASK); + } + + @Override + public Speculation speculate(SpeculationReason reason) { + byte[] encoding = encode(reason); + JavaConstant id; + if (speculations == null) { + speculations = new ArrayList<>(); + speculationReasons = new ArrayList<>(); + id = JavaConstant.forLong(encodeIndexAndLength(0, encoding.length)); + speculations.add(encoding); + speculationReasons.add(reason); + } else { + id = null; + int flattenedIndex = 0; + for (byte[] fs : speculations) { + if (Arrays.equals(fs, encoding)) { + id = JavaConstant.forLong(encodeIndexAndLength(flattenedIndex, fs.length)); + break; + } + flattenedIndex += fs.length; + } + if (id == null) { + id = JavaConstant.forLong(encodeIndexAndLength(flattenedIndex, encoding.length)); + speculations.add(encoding); + speculationReasons.add(reason); + } + } + + return new HotSpotSpeculation(reason, id, encoding); + } + + private static byte[] encode(SpeculationReason reason) { + HotSpotSpeculationEncoding encoding = (HotSpotSpeculationEncoding) reason.encode(HotSpotSpeculationEncoding::new); + byte[] result = encoding == null ? null : encoding.getByteArray(); + if (result == null) { + throw new IllegalArgumentException(HotSpotSpeculationLog.class.getName() + " expects " + reason.getClass().getName() + ".encode() to return a non-empty encoding"); + } + return result; + } + + @Override + public boolean hasSpeculations() { + return speculations != null; + } + + @Override + public Speculation lookupSpeculation(JavaConstant constant) { + if (constant.isDefaultForKind()) { + return NO_SPECULATION; + } + int flattenedIndex = decodeIndex(constant.asLong()); + int index = 0; + for (byte[] s : speculations) { + if (flattenedIndex == 0) { + SpeculationReason reason = speculationReasons.get(index); + return new HotSpotSpeculation(reason, constant, s); + } + index++; + flattenedIndex -= s.length; + } + throw new IllegalArgumentException("Unknown encoded speculation: " + constant); + } + + @Override + public String toString() { + Formatter buf = new Formatter(); + buf.format("{managed:%s, failedSpeculationsAddress:0x%x, failedSpeculations:[", managesFailedSpeculations, failedSpeculationsAddress); + + String sep = ""; + if (failedSpeculations != null) { + for (int i = 0; i < failedSpeculations.length; i++) { + buf.format("%s{len:%d, hash:0x%x}", sep, failedSpeculations[i].length, Arrays.hashCode(failedSpeculations[i])); + sep = ", "; + } + } + + buf.format("], speculations:["); + + int size = 0; + if (speculations != null) { + sep = ""; + for (int i = 0; i < speculations.size(); i++) { + byte[] s = speculations.get(i); + size += s.length; + buf.format("%s{len:%d, hash:0x%x, reason:{%s}}", sep, s.length, Arrays.hashCode(s), speculationReasons.get(i)); + sep = ", "; + } + } + buf.format("], len:%d, hash:0x%x}", size, Arrays.hashCode(getFlattenedSpeculations(false))); + return buf.toString(); + } + + /** + * Frees the native memory resources associated with {@link HotSpotSpeculationLog}s once they + * become reclaimable. + */ + private static final class LogCleaner extends Cleaner { + + LogCleaner(HotSpotSpeculationLog referent, long address) { + super(referent); + this.address = address; + } + + @Override + void doCleanup() { + long pointer = UnsafeAccess.UNSAFE.getAddress(address); + if (pointer != 0) { + compilerToVM().releaseFailedSpeculations(address); + } + UnsafeAccess.UNSAFE.freeMemory(address); + } + + final long address; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.Arrays; + +import jdk.vm.ci.code.stack.InspectedFrame; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class HotSpotStackFrameReference implements InspectedFrame { + + private CompilerToVM compilerToVM; + // set in the VM when materializeVirtualObjects is called + @SuppressWarnings("unused") private boolean objectsMaterialized; + + // information used to find the stack frame + private long stackPointer; + private int frameNumber; + + // information about the stack frame's contents + private int bci; + private HotSpotResolvedJavaMethod method; + private Object[] locals; + private boolean[] localIsVirtual; + + public long getStackPointer() { + return stackPointer; + } + + public int getFrameNumber() { + return frameNumber; + } + + @Override + public Object getLocal(int index) { + return locals[index]; + } + + @Override + public boolean isVirtual(int index) { + return localIsVirtual == null ? false : localIsVirtual[index]; + } + + @Override + public void materializeVirtualObjects(boolean invalidateCode) { + compilerToVM.materializeVirtualObjects(this, invalidateCode); + } + + @Override + public int getBytecodeIndex() { + return bci; + } + + @Override + public ResolvedJavaMethod getMethod() { + return method; + } + + @Override + public boolean isMethod(ResolvedJavaMethod otherMethod) { + return method.equals(otherMethod); + } + + @Override + public boolean hasVirtualObjects() { + return localIsVirtual != null; + } + + @Override + public String toString() { + return "HotSpotStackFrameReference [stackPointer=" + stackPointer + ", frameNumber=" + frameNumber + ", bci=" + bci + ", method=" + getMethod() + ", locals=" + Arrays.toString(locals) + + ", localIsVirtual=" + Arrays.toString(localIsVirtual) + "]"; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015, 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. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.stack.InspectedFrameVisitor; +import jdk.vm.ci.code.stack.StackIntrospection; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class HotSpotStackIntrospection implements StackIntrospection { + + protected final HotSpotJVMCIRuntime runtime; + + public HotSpotStackIntrospection(HotSpotJVMCIRuntime runtime) { + this.runtime = runtime; + } + + @Override + public T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor visitor) { + CompilerToVM compilerToVM = runtime.getCompilerToVM(); + return compilerToVM.iterateFrames(initialMethods, matchingMethods, initialSkip, visitor); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2016, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.Set; +import java.util.stream.Collectors; + +import jdk.vm.ci.common.JVMCIError; + +/** + * Access to VM configuration data. + */ +public class HotSpotVMConfigAccess { + + /** + * Gets the available configuration data. + */ + public HotSpotVMConfigStore getStore() { + return store; + } + + /** + * Gets the address of a C++ symbol. + * + * @param name name of C++ symbol + * @param notPresent if non-null and the symbol is not present then this value is returned + * @return the address of the symbol + * @throws JVMCIError if the symbol is not present and {@code notPresent == null} + */ + public long getAddress(String name, Long notPresent) { + Long entry = store.vmAddresses.get(name); + if (entry == null) { + if (notPresent != null) { + return notPresent; + } + throw missingEntry("address", name, store.vmFlags.keySet()); + + } + return entry; + } + + /** + * Gets the address of a C++ symbol. + * + * @param name name of C++ symbol + * @return the address of the symbol + * @throws JVMCIError if the symbol is not present + */ + public long getAddress(String name) { + return getAddress(name, null); + } + + /** + * Gets the value of a C++ constant. + * + * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) + * @param type the boxed type to which the constant value will be converted + * @param notPresent if non-null and the constant is not present then this value is returned + * @return the constant value converted to {@code type} + * @throws JVMCIError if the constant is not present and {@code notPresent == null} + */ + public T getConstant(String name, Class type, T notPresent) { + Long c = store.vmConstants.get(name); + if (c == null) { + if (notPresent != null) { + return notPresent; + } + throw missingEntry("constant", name, store.vmConstants.keySet()); + } + return type.cast(convertValue(name, type, c, null)); + } + + /** + * Gets the value of a C++ constant. + * + * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) + * @param type the boxed type to which the constant value will be converted + * @return the constant value converted to {@code type} + * @throws JVMCIError if the constant is not present + */ + public T getConstant(String name, Class type) { + return getConstant(name, type, null); + } + + /** + * Gets the offset of a non-static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the offset value will be converted (must be + * {@link Integer} or {@link Long}) + * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) + * @param notPresent if non-null and the field is not present then this value is returned + * @return the offset in bytes of the requested field + * @throws JVMCIError if the field is static or not present and {@code notPresent} is null + */ + public T getFieldOffset(String name, Class type, String cppType, T notPresent) { + return getFieldOffset0(name, type, notPresent, cppType, null); + } + + /** + * Gets the offset of a non-static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the offset value will be converted (must be + * {@link Integer} or {@link Long}) + * @param notPresent if non-null and the field is not present then this value is returned + * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is + * returned in element 0 of this array + * @return the offset in bytes of the requested field + * @throws JVMCIError if the field is static or not present and {@code notPresent} is null + */ + public T getFieldOffset(String name, Class type, T notPresent, String[] outCppType) { + return getFieldOffset0(name, type, notPresent, null, outCppType); + } + + /** + * Gets the offset of a non-static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the offset value will be converted (must be + * {@link Integer} or {@link Long}) + * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) + * @return the offset in bytes of the requested field + * @throws JVMCIError if the field is static or not present + */ + public T getFieldOffset(String name, Class type, String cppType) { + return getFieldOffset0(name, type, null, cppType, null); + } + + /** + * Gets the offset of a non-static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the offset value will be converted (must be + * {@link Integer} or {@link Long}) + * @return the offset in bytes of the requested field + * @throws JVMCIError if the field is static or not present + */ + public T getFieldOffset(String name, Class type) { + return getFieldOffset0(name, type, null, null, null); + } + + private T getFieldOffset0(String name, Class type, T notPresent, String inCppType, String[] outCppType) { + assert type == Integer.class || type == Long.class; + VMField entry = getField(name, inCppType, notPresent == null); + if (entry == null) { + return notPresent; + } + if (entry.address != 0) { + throw new JVMCIError("cannot get offset of static field " + name); + } + if (outCppType != null) { + outCppType[0] = entry.type; + } + return type.cast(convertValue(name, type, entry.offset, inCppType)); + } + + /** + * Gets the address of a static C++ field. + * + * @param name fully qualified name of the field + * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) + * @param notPresent if non-null and the field is not present then this value is returned + * @return the address of the requested field + * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null + */ + public long getFieldAddress(String name, String cppType, Long notPresent) { + return getFieldAddress0(name, notPresent, cppType, null); + } + + /** + * Gets the address of a static C++ field. + * + * @param name fully qualified name of the field + * @param notPresent if non-null and the field is not present then this value is returned + * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is + * returned in element 0 of this array + * @return the address of the requested field + * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null + */ + public long getFieldAddress(String name, Long notPresent, String[] outCppType) { + return getFieldAddress0(name, notPresent, null, outCppType); + } + + /** + * Gets the address of a static C++ field. + * + * @param name fully qualified name of the field + * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) + * @return the address of the requested field + * @throws JVMCIError if the field is not static or not present + */ + public long getFieldAddress(String name, String cppType) { + return getFieldAddress0(name, null, cppType, null); + } + + private long getFieldAddress0(String name, Long notPresent, String inCppType, String[] outCppType) { + VMField entry = getField(name, inCppType, notPresent == null); + if (entry == null) { + return notPresent; + } + if (entry.address == 0) { + throw new JVMCIError(name + " is not a static field"); + } + if (outCppType != null) { + outCppType[0] = entry.type; + } + return entry.address; + } + + /** + * Gets the value of a static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the constant value will be converted + * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) + * @param notPresent if non-null and the field is not present then this value is returned + * @return the value of the requested field + * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null + */ + public T getFieldValue(String name, Class type, String cppType, T notPresent) { + return getFieldValue0(name, type, notPresent, cppType, null); + } + + /** + * Gets the value of a static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the constant value will be converted + * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) + * @return the value of the requested field + * @throws JVMCIError if the field is not static or not present + */ + public T getFieldValue(String name, Class type, String cppType) { + return getFieldValue0(name, type, null, cppType, null); + } + + /** + * Gets the value of a static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the constant value will be converted + * @param notPresent if non-null and the field is not present then this value is returned + * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is + * returned in element 0 of this array + * @return the value of the requested field + * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null + */ + public T getFieldValue(String name, Class type, T notPresent, String[] outCppType) { + return getFieldValue0(name, type, notPresent, null, outCppType); + } + + /** + * Gets the value of a static C++ field. + * + * @param name fully qualified name of the field + * @param type the boxed type to which the constant value will be converted + * @return the value of the requested field + * @throws JVMCIError if the field is not static or not present + */ + public T getFieldValue(String name, Class type) { + return getFieldValue0(name, type, null, null, null); + } + + private T getFieldValue0(String name, Class type, T notPresent, String inCppType, String[] outCppType) { + VMField entry = getField(name, inCppType, notPresent == null); + if (entry == null) { + return notPresent; + } + if (entry.value == null) { + throw new JVMCIError(name + " is not a static field "); + } + if (outCppType != null) { + outCppType[0] = entry.type; + } + return type.cast(convertValue(name, type, entry.value, inCppType)); + } + + /** + * Gets a C++ field. + * + * @param name fully qualified name of the field + * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) + * @param required specifies if the field must be present + * @return the field + * @throws JVMCIError if the field is not present and {@code required == true} + */ + private VMField getField(String name, String cppType, boolean required) { + VMField entry = store.vmFields.get(name); + if (entry == null) { + if (!required) { + return null; + } + throw missingEntry("field", name, store.vmFields.keySet()); + } + + // Make sure the native type is still the type we expect. + if (cppType != null && !cppType.equals(entry.type)) { + throw new JVMCIError("expected type " + cppType + " but VM field " + name + " is of type " + entry.type); + } + return entry; + } + + /** + * Gets a VM flag value. + * + * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) + * @param type the boxed type to which the flag's value will be converted + * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not + * present + * @throws JVMCIError if the flag is not present + */ + public T getFlag(String name, Class type) { + return getFlag(name, type, null); + } + + /** + * Gets a VM flag value. + * + * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) + * @param type the boxed type to which the flag's value will be converted + * @param notPresent if non-null and the flag is not present then this value is returned + * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not + * present + * @throws JVMCIError if the flag is not present and {@code notPresent == null} + */ + public T getFlag(String name, Class type, T notPresent) { + VMFlag entry = store.vmFlags.get(name); + Object value; + String cppType; + if (entry == null) { + // Fall back to VM call + value = store.compilerToVm.getFlagValue(name); + if (value == store.compilerToVm) { + if (notPresent != null) { + return notPresent; + } + throw missingEntry("flag", name, store.vmFlags.keySet()); + } else { + cppType = null; + } + } else { + value = entry.value; + cppType = entry.type; + } + return type.cast(convertValue(name, type, value, cppType)); + } + + private JVMCIError missingEntry(String category, String name, Set keys) { + throw new JVMCIError("expected VM %s not found in %s: %s%nAvailable values:%n %s", category, store, name, + keys.stream().sorted().collect(Collectors.joining(System.lineSeparator() + " "))); + } + + private static Object convertValue(String name, Class toType, Object value, String cppType) throws JVMCIError { + if (toType == Boolean.class) { + if (value instanceof String) { + return Boolean.valueOf((String) value); + } else if (value instanceof Boolean) { + return value; + } else if (value instanceof Long) { + return ((long) value) != 0; + } + } else if (toType == Byte.class) { + if (value instanceof Long) { + return (byte) (long) value; + } + } else if (toType == Integer.class) { + if (value instanceof Integer) { + return value; + } else if (value instanceof Long) { + return (int) (long) value; + } + } else if (toType == String.class) { + if (value == null || value instanceof String) { + return value; + } + } else if (toType == Long.class) { + return value; + } + + throw new JVMCIError("cannot convert " + name + " of type " + value.getClass().getSimpleName() + (cppType == null ? "" : " [" + cppType + "]") + " to " + toType.getSimpleName()); + } + + private final HotSpotVMConfigStore store; + + public HotSpotVMConfigAccess(HotSpotVMConfigStore store) { + this.store = store; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.services.Services; +import jdk.internal.misc.Unsafe; + +/** + * Used to access native configuration details. + * + * All non-static, public fields in this class are so that they can be compiled as constants. + */ +class HotSpotVMConfig extends HotSpotVMConfigAccess { + + /** + * Gets the configuration associated with the singleton {@link HotSpotJVMCIRuntime}. + */ + static HotSpotVMConfig config() { + return runtime().getConfig(); + } + + private final String osArch = getHostArchitectureName(); + + HotSpotVMConfig(HotSpotVMConfigStore store) { + super(store); + + int speculationLengthBits = getConstant("JVMCINMethodData::SPECULATION_LENGTH_BITS", Integer.class); + JVMCIError.guarantee(HotSpotSpeculationEncoding.LENGTH_BITS == speculationLengthBits, "%d != %d", HotSpotSpeculationEncoding.LENGTH_BITS, speculationLengthBits); + } + + /** + * Gets the host architecture name for the purpose of finding the corresponding + * {@linkplain HotSpotJVMCIBackendFactory backend}. + */ + String getHostArchitectureName() { + String arch = Services.getSavedProperty("os.arch"); + switch (arch) { + case "x86_64": + return "amd64"; + + default: + return arch; + } + } + + final boolean useDeferredInitBarriers = getFlag("ReduceInitialCardMarks", Boolean.class); + + final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class); + + final int objectAlignment = getFlag("ObjectAlignmentInBytes", Integer.class); + + final int hubOffset = getFieldOffset("oopDesc::_metadata._klass", Integer.class, "Klass*"); + + final int prototypeMarkWordOffset = getFieldOffset("Klass::_prototype_header", Integer.class, "markWord"); + final int subklassOffset = getFieldOffset("Klass::_subklass", Integer.class, "Klass*"); + final int superOffset = getFieldOffset("Klass::_super", Integer.class, "Klass*"); + final int nextSiblingOffset = getFieldOffset("Klass::_next_sibling", Integer.class, "Klass*"); + final int superCheckOffsetOffset = getFieldOffset("Klass::_super_check_offset", Integer.class, "juint"); + final int secondarySuperCacheOffset = getFieldOffset("Klass::_secondary_super_cache", Integer.class, "Klass*"); + + final int classLoaderDataOffset = getFieldOffset("Klass::_class_loader_data", Integer.class, "ClassLoaderData*"); + + /** + * The offset of the _java_mirror field (of type {@link Class}) in a Klass. + */ + final int javaMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle"); + + final int klassAccessFlagsOffset = getFieldOffset("Klass::_access_flags", Integer.class, "AccessFlags"); + final int klassLayoutHelperOffset = getFieldOffset("Klass::_layout_helper", Integer.class, "jint"); + + final int klassLayoutHelperNeutralValue = getConstant("Klass::_lh_neutral_value", Integer.class); + final int klassLayoutHelperInstanceSlowPathBit = getConstant("Klass::_lh_instance_slow_path_bit", Integer.class); + + final int vtableEntrySize = getFieldValue("CompilerToVM::Data::sizeof_vtableEntry", Integer.class, "int"); + final int vtableEntryMethodOffset = getFieldOffset("vtableEntry::_method", Integer.class, "Method*"); + + final int instanceKlassInitStateOffset = getFieldOffset("InstanceKlass::_init_state", Integer.class, "u1"); + final int instanceKlassConstantsOffset = getFieldOffset("InstanceKlass::_constants", Integer.class, "ConstantPool*"); + final int instanceKlassFieldsOffset = getFieldOffset("InstanceKlass::_fields", Integer.class, "Array*"); + final int instanceKlassAnnotationsOffset = getFieldOffset("InstanceKlass::_annotations", Integer.class, "Annotations*"); + final int instanceKlassMiscFlagsOffset = getFieldOffset("InstanceKlass::_misc_flags", Integer.class, "u2"); + final int klassVtableStartOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_start_offset", Integer.class, "int"); + final int klassVtableLengthOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_length_offset", Integer.class, "int"); + + final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class); + final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", Integer.class); + final int instanceKlassStateBeingInitialized = getConstant("InstanceKlass::being_initialized", Integer.class); + + final int annotationsFieldAnnotationsOffset = getFieldOffset("Annotations::_fields_annotations", Integer.class, "Array*"); + final int fieldsAnnotationsBaseOffset = getFieldValue("CompilerToVM::Data::_fields_annotations_base_offset", Integer.class, "int"); + + final int arrayU1LengthOffset = getFieldOffset("Array::_length", Integer.class, "int"); + final int arrayU1DataOffset = getFieldOffset("Array::_data", Integer.class); + final int arrayU2DataOffset = getFieldOffset("Array::_data", Integer.class); + + final int fieldInfoAccessFlagsOffset = getConstant("FieldInfo::access_flags_offset", Integer.class); + final int fieldInfoNameIndexOffset = getConstant("FieldInfo::name_index_offset", Integer.class); + final int fieldInfoSignatureIndexOffset = getConstant("FieldInfo::signature_index_offset", Integer.class); + final int fieldInfoConstantValueIndexOffset = getConstant("FieldInfo::initval_index_offset", Integer.class); + final int fieldInfoLowPackedOffset = getConstant("FieldInfo::low_packed_offset", Integer.class); + final int fieldInfoHighPackedOffset = getConstant("FieldInfo::high_packed_offset", Integer.class); + final int fieldInfoFieldSlots = getConstant("FieldInfo::field_slots", Integer.class); + + final int fieldInfoTagSize = getConstant("FIELDINFO_TAG_SIZE", Integer.class); + + final int jvmAccHasFinalizer = getConstant("JVM_ACC_HAS_FINALIZER", Integer.class); + final int jvmAccFieldInternal = getConstant("JVM_ACC_FIELD_INTERNAL", Integer.class); + final int jvmAccFieldStable = getConstant("JVM_ACC_FIELD_STABLE", Integer.class); + final int jvmAccFieldHasGenericSignature = getConstant("JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE", Integer.class); + final int jvmAccIsCloneableFast = getConstant("JVM_ACC_IS_CLONEABLE_FAST", Integer.class); + + // These modifiers are not public in Modifier so we get them via vmStructs. + final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class); + final int jvmAccAnnotation = getConstant("JVM_ACC_ANNOTATION", Integer.class); + final int jvmAccBridge = getConstant("JVM_ACC_BRIDGE", Integer.class); + final int jvmAccVarargs = getConstant("JVM_ACC_VARARGS", Integer.class); + final int jvmAccEnum = getConstant("JVM_ACC_ENUM", Integer.class); + final int jvmAccInterface = getConstant("JVM_ACC_INTERFACE", Integer.class); + + final int jvmMiscFlagsHasDefaultMethods = getConstant("InstanceKlass::_misc_has_nonstatic_concrete_methods", Integer.class); + final int jvmMiscFlagsDeclaresDefaultMethods = getConstant("InstanceKlass::_misc_declares_nonstatic_concrete_methods", Integer.class); + + // This is only valid on AMD64. + final int runtimeCallStackSize = getConstant("frame::arg_reg_save_area_bytes", Integer.class, osArch.equals("amd64") ? null : 0); + + private final int markWordNoHashInPlace = getConstant("markWord::no_hash_in_place", Integer.class); + private final int markWordNoLockInPlace = getConstant("markWord::no_lock_in_place", Integer.class); + + /** + * See {@code markWord::prototype()}. + */ + long arrayPrototypeMarkWord() { + return markWordNoHashInPlace | markWordNoLockInPlace; + } + + final int methodAccessFlagsOffset = getFieldOffset("Method::_access_flags", Integer.class, "AccessFlags"); + final int methodConstMethodOffset = getFieldOffset("Method::_constMethod", Integer.class, "ConstMethod*"); + final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2"); + final int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, "u2"); + final int methodVtableIndexOffset = getFieldOffset("Method::_vtable_index", Integer.class, "int"); + + final int methodDataOffset = getFieldOffset("Method::_method_data", Integer.class, "MethodData*"); + final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*"); + + final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class); + final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class); + final int methodFlagsIntrinsicCandidate = getConstant("Method::_intrinsic_candidate", Integer.class); + final int methodFlagsDontInline = getConstant("Method::_dont_inline", Integer.class); + final int methodFlagsReservedStackAccess = getConstant("Method::_reserved_stack_access", Integer.class); + final int nonvirtualVtableIndex = getConstant("Method::nonvirtual_vtable_index", Integer.class); + final int invalidVtableIndex = getConstant("Method::invalid_vtable_index", Integer.class); + + final int methodDataSize = getFieldOffset("MethodData::_size", Integer.class, "int"); + final int methodDataDataSize = getFieldOffset("MethodData::_data_size", Integer.class, "int"); + final int methodDataOopDataOffset = getFieldOffset("MethodData::_data[0]", Integer.class, "intptr_t"); + final int methodDataOopTrapHistoryOffset = getFieldOffset("MethodData::_compiler_counters._trap_hist._array[0]", Integer.class, "u1"); + final int methodDataIRSizeOffset = getFieldOffset("MethodData::_jvmci_ir_size", Integer.class, "int"); + + final int methodDataDecompiles = getFieldOffset("MethodData::_compiler_counters._nof_decompiles", Integer.class, "uint"); + final int methodDataOverflowRecompiles = getFieldOffset("MethodData::_compiler_counters._nof_overflow_recompiles", Integer.class, "uint"); + final int methodDataOverflowTraps = getFieldOffset("MethodData::_compiler_counters._nof_overflow_traps", Integer.class, "uint"); + + final int nmethodCompLevelOffset = getFieldOffset("nmethod::_comp_level", Integer.class, "int"); + + final int compilationLevelNone = getConstant("CompLevel_none", Integer.class); + final int compilationLevelSimple = getConstant("CompLevel_simple", Integer.class); + final int compilationLevelLimitedProfile = getConstant("CompLevel_limited_profile", Integer.class); + final int compilationLevelFullProfile = getConstant("CompLevel_full_profile", Integer.class); + final int compilationLevelFullOptimization = getConstant("CompLevel_full_optimization", Integer.class); + + final int compLevelAdjustmentNone = getConstant("JVMCIRuntime::none", Integer.class); + final int compLevelAdjustmentByHolder = getConstant("JVMCIRuntime::by_holder", Integer.class); + final int compLevelAdjustmentByFullSignature = getConstant("JVMCIRuntime::by_full_signature", Integer.class); + + final int invocationEntryBci = getConstant("InvocationEntryBci", Integer.class); + + final int extraStackEntries = getFieldValue("CompilerToVM::Data::Method_extra_stack_entries", Integer.class, "int"); + + final int constMethodConstantsOffset = getFieldOffset("ConstMethod::_constants", Integer.class, "ConstantPool*"); + final int constMethodFlagsOffset = getFieldOffset("ConstMethod::_flags", Integer.class, "u2"); + final int constMethodCodeSizeOffset = getFieldOffset("ConstMethod::_code_size", Integer.class, "u2"); + final int constMethodNameIndexOffset = getFieldOffset("ConstMethod::_name_index", Integer.class, "u2"); + final int constMethodSignatureIndexOffset = getFieldOffset("ConstMethod::_signature_index", Integer.class, "u2"); + final int constMethodMethodIdnumOffset = getFieldOffset("ConstMethod::_method_idnum", Integer.class, "u2"); + final int constMethodMaxStackOffset = getFieldOffset("ConstMethod::_max_stack", Integer.class, "u2"); + final int methodMaxLocalsOffset = getFieldOffset("ConstMethod::_max_locals", Integer.class, "u2"); + + final int constMethodHasLineNumberTable = getConstant("ConstMethod::_has_linenumber_table", Integer.class); + final int constMethodHasLocalVariableTable = getConstant("ConstMethod::_has_localvariable_table", Integer.class); + final int constMethodHasMethodAnnotations = getConstant("ConstMethod::_has_method_annotations", Integer.class); + final int constMethodHasParameterAnnotations = getConstant("ConstMethod::_has_parameter_annotations", Integer.class); + final int constMethodHasExceptionTable = getConstant("ConstMethod::_has_exception_table", Integer.class); + + final int exceptionTableElementSize = getFieldValue("CompilerToVM::Data::sizeof_ExceptionTableElement", Integer.class, "int"); + final int exceptionTableElementStartPcOffset = getFieldOffset("ExceptionTableElement::start_pc", Integer.class, "u2"); + final int exceptionTableElementEndPcOffset = getFieldOffset("ExceptionTableElement::end_pc", Integer.class, "u2"); + final int exceptionTableElementHandlerPcOffset = getFieldOffset("ExceptionTableElement::handler_pc", Integer.class, "u2"); + final int exceptionTableElementCatchTypeIndexOffset = getFieldOffset("ExceptionTableElement::catch_type_index", Integer.class, "u2"); + + final int localVariableTableElementSize = getFieldValue("CompilerToVM::Data::sizeof_LocalVariableTableElement", Integer.class, "int"); + final int localVariableTableElementStartBciOffset = getFieldOffset("LocalVariableTableElement::start_bci", Integer.class, "u2"); + final int localVariableTableElementLengthOffset = getFieldOffset("LocalVariableTableElement::length", Integer.class, "u2"); + final int localVariableTableElementNameCpIndexOffset = getFieldOffset("LocalVariableTableElement::name_cp_index", Integer.class, "u2"); + final int localVariableTableElementDescriptorCpIndexOffset = getFieldOffset("LocalVariableTableElement::descriptor_cp_index", Integer.class, "u2"); + final int localVariableTableElementSlotOffset = getFieldOffset("LocalVariableTableElement::slot", Integer.class, "u2"); + + final int constantPoolSize = getFieldValue("CompilerToVM::Data::sizeof_ConstantPool", Integer.class, "int"); + final int constantPoolTagsOffset = getFieldOffset("ConstantPool::_tags", Integer.class, "Array*"); + final int constantPoolHolderOffset = getFieldOffset("ConstantPool::_pool_holder", Integer.class, "InstanceKlass*"); + final int constantPoolLengthOffset = getFieldOffset("ConstantPool::_length", Integer.class, "int"); + final int constantPoolFlagsOffset = getFieldOffset("ConstantPool::_flags", Integer.class, "u2"); + + final int constantPoolCpCacheIndexTag = getConstant("ConstantPool::CPCACHE_INDEX_TAG", Integer.class); + final int constantPoolHasDynamicConstant = getConstant("ConstantPool::_has_dynamic_constant", Integer.class); + final int constantPoolSourceFileNameIndexOffset = getFieldOffset("ConstantPool::_source_file_name_index", Integer.class, "u2"); + + final int jvmConstantUtf8 = getConstant("JVM_CONSTANT_Utf8", Integer.class); + final int jvmConstantInteger = getConstant("JVM_CONSTANT_Integer", Integer.class); + final int jvmConstantLong = getConstant("JVM_CONSTANT_Long", Integer.class); + final int jvmConstantFloat = getConstant("JVM_CONSTANT_Float", Integer.class); + final int jvmConstantDouble = getConstant("JVM_CONSTANT_Double", Integer.class); + final int jvmConstantClass = getConstant("JVM_CONSTANT_Class", Integer.class); + final int jvmConstantUnresolvedClass = getConstant("JVM_CONSTANT_UnresolvedClass", Integer.class); + final int jvmConstantUnresolvedClassInError = getConstant("JVM_CONSTANT_UnresolvedClassInError", Integer.class); + final int jvmConstantString = getConstant("JVM_CONSTANT_String", Integer.class); + final int jvmConstantFieldref = getConstant("JVM_CONSTANT_Fieldref", Integer.class); + final int jvmConstantMethodref = getConstant("JVM_CONSTANT_Methodref", Integer.class); + final int jvmConstantInterfaceMethodref = getConstant("JVM_CONSTANT_InterfaceMethodref", Integer.class); + final int jvmConstantNameAndType = getConstant("JVM_CONSTANT_NameAndType", Integer.class); + final int jvmConstantMethodHandle = getConstant("JVM_CONSTANT_MethodHandle", Integer.class); + final int jvmConstantMethodHandleInError = getConstant("JVM_CONSTANT_MethodHandleInError", Integer.class); + final int jvmConstantMethodType = getConstant("JVM_CONSTANT_MethodType", Integer.class); + final int jvmConstantMethodTypeInError = getConstant("JVM_CONSTANT_MethodTypeInError", Integer.class); + final int jvmConstantDynamic = getConstant("JVM_CONSTANT_Dynamic", Integer.class); + final int jvmConstantDynamicInError = getConstant("JVM_CONSTANT_DynamicInError", Integer.class); + final int jvmConstantInvokeDynamic = getConstant("JVM_CONSTANT_InvokeDynamic", Integer.class); + + final int jvmConstantExternalMax = getConstant("JVM_CONSTANT_ExternalMax", Integer.class); + final int jvmConstantInternalMin = getConstant("JVM_CONSTANT_InternalMin", Integer.class); + final int jvmConstantInternalMax = getConstant("JVM_CONSTANT_InternalMax", Integer.class); + + final int heapWordSize = getConstant("HeapWordSize", Integer.class); + + final long symbolVmSymbols = getFieldAddress("Symbol::_vm_symbols[0]", "Symbol*"); + final int vmSymbolsFirstSID = getConstant("vmSymbols::FIRST_SID", Integer.class); + final int vmSymbolsSIDLimit = getConstant("vmSymbols::SID_LIMIT", Integer.class); + + final long symbolInit = getFieldValue("CompilerToVM::Data::symbol_init", Long.class); + final long symbolClinit = getFieldValue("CompilerToVM::Data::symbol_clinit", Long.class); + + /** + * Returns the symbol in the {@code vmSymbols} table at position {@code index} as a + * {@link String}. + * + * @param index position in the symbol table + * @return the symbol at position id + */ + String symbolAt(int index) { + HotSpotJVMCIRuntime runtime = runtime(); + assert vmSymbolsFirstSID <= index && index < vmSymbolsSIDLimit : "index " + index + " is out of bounds"; + int offset = index * Unsafe.ADDRESS_SIZE; + return runtime.getCompilerToVM().getSymbol(UNSAFE.getAddress(symbolVmSymbols + offset)); + } + + final int universeBaseVtableSize = getFieldValue("CompilerToVM::Data::Universe_base_vtable_size", Integer.class, "int"); + + final int baseVtableLength() { + return universeBaseVtableSize / (vtableEntrySize / heapWordSize); + } + + final int klassOffset = getFieldValue("java_lang_Class::_klass_offset", Integer.class, "int"); + + /** + * The DataLayout header size is the same as the cell size. + */ + final int dataLayoutHeaderSize = getConstant("DataLayout::cell_size", Integer.class); + final int dataLayoutTagOffset = getFieldOffset("DataLayout::_header._struct._tag", Integer.class, "u1"); + final int dataLayoutFlagsOffset = getFieldOffset("DataLayout::_header._struct._flags", Integer.class, "u1"); + final int dataLayoutBCIOffset = getFieldOffset("DataLayout::_header._struct._bci", Integer.class, "u2"); + final int dataLayoutCellSize = getConstant("DataLayout::cell_size", Integer.class); + + final int dataLayoutNoTag = getConstant("DataLayout::no_tag", Integer.class); + final int dataLayoutBitDataTag = getConstant("DataLayout::bit_data_tag", Integer.class); + final int dataLayoutCounterDataTag = getConstant("DataLayout::counter_data_tag", Integer.class); + final int dataLayoutJumpDataTag = getConstant("DataLayout::jump_data_tag", Integer.class); + final int dataLayoutReceiverTypeDataTag = getConstant("DataLayout::receiver_type_data_tag", Integer.class); + final int dataLayoutVirtualCallDataTag = getConstant("DataLayout::virtual_call_data_tag", Integer.class); + final int dataLayoutRetDataTag = getConstant("DataLayout::ret_data_tag", Integer.class); + final int dataLayoutBranchDataTag = getConstant("DataLayout::branch_data_tag", Integer.class); + final int dataLayoutMultiBranchDataTag = getConstant("DataLayout::multi_branch_data_tag", Integer.class); + final int dataLayoutArgInfoDataTag = getConstant("DataLayout::arg_info_data_tag", Integer.class); + final int dataLayoutCallTypeDataTag = getConstant("DataLayout::call_type_data_tag", Integer.class); + final int dataLayoutVirtualCallTypeDataTag = getConstant("DataLayout::virtual_call_type_data_tag", Integer.class); + final int dataLayoutParametersTypeDataTag = getConstant("DataLayout::parameters_type_data_tag", Integer.class); + final int dataLayoutSpeculativeTrapDataTag = getConstant("DataLayout::speculative_trap_data_tag", Integer.class); + + final int bciProfileWidth = getFlag("BciProfileWidth", Integer.class); + final int typeProfileWidth = getFlag("TypeProfileWidth", Integer.class); + final int methodProfileWidth = getFlag("MethodProfileWidth", Integer.class, 0); + + final int deoptReasonNone = getConstant("Deoptimization::Reason_none", Integer.class); + final int deoptReasonNullCheck = getConstant("Deoptimization::Reason_null_check", Integer.class); + final int deoptReasonRangeCheck = getConstant("Deoptimization::Reason_range_check", Integer.class); + final int deoptReasonClassCheck = getConstant("Deoptimization::Reason_class_check", Integer.class); + final int deoptReasonArrayCheck = getConstant("Deoptimization::Reason_array_check", Integer.class); + final int deoptReasonUnreached0 = getConstant("Deoptimization::Reason_unreached0", Integer.class); + final int deoptReasonTypeCheckInlining = getConstant("Deoptimization::Reason_type_checked_inlining", Integer.class); + final int deoptReasonOptimizedTypeCheck = getConstant("Deoptimization::Reason_optimized_type_check", Integer.class); + final int deoptReasonNotCompiledExceptionHandler = getConstant("Deoptimization::Reason_not_compiled_exception_handler", Integer.class); + final int deoptReasonUnresolved = getConstant("Deoptimization::Reason_unresolved", Integer.class); + final int deoptReasonJsrMismatch = getConstant("Deoptimization::Reason_jsr_mismatch", Integer.class); + final int deoptReasonDiv0Check = getConstant("Deoptimization::Reason_div0_check", Integer.class); + final int deoptReasonConstraint = getConstant("Deoptimization::Reason_constraint", Integer.class); + final int deoptReasonLoopLimitCheck = getConstant("Deoptimization::Reason_loop_limit_check", Integer.class); + final int deoptReasonAliasing = getConstant("Deoptimization::Reason_aliasing", Integer.class); + final int deoptReasonTransferToInterpreter = getConstant("Deoptimization::Reason_transfer_to_interpreter", Integer.class); + final int deoptReasonOSROffset = getConstant("Deoptimization::Reason_TRAP_HISTORY_LENGTH", Integer.class); + + final int deoptActionNone = getConstant("Deoptimization::Action_none", Integer.class); + final int deoptActionMaybeRecompile = getConstant("Deoptimization::Action_maybe_recompile", Integer.class); + final int deoptActionReinterpret = getConstant("Deoptimization::Action_reinterpret", Integer.class); + final int deoptActionMakeNotEntrant = getConstant("Deoptimization::Action_make_not_entrant", Integer.class); + final int deoptActionMakeNotCompilable = getConstant("Deoptimization::Action_make_not_compilable", Integer.class); + + final int deoptimizationActionBits = getConstant("Deoptimization::_action_bits", Integer.class); + final int deoptimizationReasonBits = getConstant("Deoptimization::_reason_bits", Integer.class); + final int deoptimizationDebugIdBits = getConstant("Deoptimization::_debug_id_bits", Integer.class); + final int deoptimizationActionShift = getConstant("Deoptimization::_action_shift", Integer.class); + final int deoptimizationReasonShift = getConstant("Deoptimization::_reason_shift", Integer.class); + final int deoptimizationDebugIdShift = getConstant("Deoptimization::_debug_id_shift", Integer.class); + + final int vmIntrinsicInvokeBasic = getConstant("vmIntrinsics::_invokeBasic", Integer.class); + final int vmIntrinsicLinkToVirtual = getConstant("vmIntrinsics::_linkToVirtual", Integer.class); + final int vmIntrinsicLinkToStatic = getConstant("vmIntrinsics::_linkToStatic", Integer.class); + final int vmIntrinsicLinkToSpecial = getConstant("vmIntrinsics::_linkToSpecial", Integer.class); + final int vmIntrinsicLinkToInterface = getConstant("vmIntrinsics::_linkToInterface", Integer.class); + + final int codeInstallResultOk = getConstant("JVMCI::ok", Integer.class); + final int codeInstallResultDependenciesFailed = getConstant("JVMCI::dependencies_failed", Integer.class); + final int codeInstallResultCacheFull = getConstant("JVMCI::cache_full", Integer.class); + final int codeInstallResultCodeTooLarge = getConstant("JVMCI::code_too_large", Integer.class); + final int codeInstallResultNMethodReclaimed = getConstant("JVMCI::nmethod_reclaimed", Integer.class); + final int codeInstallResultFirstPermanentBailout = getConstant("JVMCI::first_permanent_bailout", Integer.class); + + String getCodeInstallResultDescription(int codeInstallResult) { + if (codeInstallResult == codeInstallResultOk) { + return "ok"; + } + if (codeInstallResult == codeInstallResultDependenciesFailed) { + return "dependencies failed"; + } + if (codeInstallResult == codeInstallResultCacheFull) { + return "code cache is full"; + } + if (codeInstallResult == codeInstallResultCodeTooLarge) { + return "code is too large"; + } + if (codeInstallResult == codeInstallResultNMethodReclaimed) { + return "nmethod reclaimed"; + } + assert false : codeInstallResult; + return "unknown"; + } + + final int bitDataExceptionSeenFlag = getConstant("BitData::exception_seen_flag", Integer.class); + final int bitDataNullSeenFlag = getConstant("BitData::null_seen_flag", Integer.class); + final int methodDataCountOffset = getConstant("CounterData::count_off", Integer.class); + final int jumpDataTakenOffset = getConstant("JumpData::taken_off_set", Integer.class); + final int jumpDataDisplacementOffset = getConstant("JumpData::displacement_off_set", Integer.class); + final int receiverTypeDataNonprofiledCountOffset = getConstant("ReceiverTypeData::nonprofiled_count_off_set", Integer.class); + final int receiverTypeDataReceiverTypeRowCellCount = getConstant("ReceiverTypeData::receiver_type_row_cell_count", Integer.class); + final int receiverTypeDataReceiver0Offset = getConstant("ReceiverTypeData::receiver0_offset", Integer.class); + final int receiverTypeDataCount0Offset = getConstant("ReceiverTypeData::count0_offset", Integer.class); + final int branchDataNotTakenOffset = getConstant("BranchData::not_taken_off_set", Integer.class); + final int arrayDataArrayLenOffset = getConstant("ArrayData::array_len_off_set", Integer.class); + final int arrayDataArrayStartOffset = getConstant("ArrayData::array_start_off_set", Integer.class); + final int multiBranchDataPerCaseCellCount = getConstant("MultiBranchData::per_case_cell_count", Integer.class); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016, 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. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.common.InitTimer.timer; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import jdk.vm.ci.common.InitTimer; +import jdk.vm.ci.common.JVMCIError; + +/** + * Access to VM configuration data. + */ +public final class HotSpotVMConfigStore { + + /** + * Gets the C++ symbols whose addresses are exposed by this object. + * + * @return an unmodifiable map from the symbol names to their addresses + */ + public Map getAddresses() { + return Collections.unmodifiableMap(vmAddresses); + } + + /** + * Gets the C++ constants exposed by this object. + * + * @return an unmodifiable map from the names of C++ constants to their values + */ + public Map getConstants() { + return Collections.unmodifiableMap(vmConstants); + } + + /** + * Gets the VM flags exposed by this object. + * + * @return an unmodifiable map from VM flag names to {@link VMFlag} objects + */ + public Map getFlags() { + return Collections.unmodifiableMap(vmFlags); + } + + /** + * Gets the C++ fields exposed by this object. + * + * @return an unmodifiable map from VM field names to {@link VMField} objects + */ + public Map getFields() { + return Collections.unmodifiableMap(vmFields); + } + + /** + * Gets the VM intrinsic descriptions exposed by this object. + */ + public List getIntrinsics() { + return Collections.unmodifiableList(vmIntrinsics); + } + + final HashMap vmFields; + final HashMap vmConstants; + final HashMap vmAddresses; + final HashMap vmFlags; + final List vmIntrinsics; + final CompilerToVM compilerToVm; + + /** + * Reads the database of VM info. The return value encodes the info in a nested object array + * that is described by the pseudo Java object {@code info} below: + * + *
    +     *     info = [
    +     *         VMField[] vmFields,
    +     *         [String name, Long value, ...] vmConstants,
    +     *         [String name, Long value, ...] vmAddresses,
    +     *         VMFlag[] vmFlags
    +     *         VMIntrinsicMethod[] vmIntrinsics
    +     *     ]
    +     * 
    + */ + @SuppressWarnings("try") + HotSpotVMConfigStore(CompilerToVM compilerToVm) { + this.compilerToVm = compilerToVm; + Object[] data; + try (InitTimer t = timer("CompilerToVm readConfiguration")) { + data = compilerToVm.readConfiguration(); + } + if (data.length != 5) { + throw new JVMCIError("Expected data.length to be 5, not %d", data.length); + } + + // @formatter:off + VMField[] vmFieldsInfo = (VMField[]) data[0]; + Object[] vmConstantsInfo = (Object[]) data[1]; + Object[] vmAddressesInfo = (Object[]) data[2]; + VMFlag[] vmFlagsInfo = (VMFlag[]) data[3]; + + vmFields = new HashMap<>(vmFieldsInfo.length); + vmConstants = new HashMap<>(vmConstantsInfo.length); + vmAddresses = new HashMap<>(vmAddressesInfo.length); + vmFlags = new HashMap<>(vmFlagsInfo.length); + vmIntrinsics = Arrays.asList((VMIntrinsicMethod[]) data[4]); + // @formatter:on + + try (InitTimer t = timer("HotSpotVMConfigStore fill maps")) { + for (VMField vmField : vmFieldsInfo) { + vmFields.put(vmField.name, vmField); + } + + for (int i = 0; i < vmConstantsInfo.length / 2; i++) { + String name = (String) vmConstantsInfo[i * 2]; + Long value = (Long) vmConstantsInfo[i * 2 + 1]; + vmConstants.put(name, value); + } + + for (int i = 0; i < vmAddressesInfo.length / 2; i++) { + String name = (String) vmAddressesInfo[i * 2]; + Long value = (Long) vmAddressesInfo[i * 2 + 1]; + vmAddresses.put(name, value); + } + + for (VMFlag vmFlag : vmFlagsInfo) { + vmFlags.put(vmFlag.name, vmFlag); + } + } + } + + @Override + public String toString() { + return String.format("%s[%d fields, %d constants, %d addresses, %d flags, %d intrinsics]", + getClass().getSimpleName(), + vmFields.size(), + vmConstants.size(), + vmAddresses.size(), + vmFlags.size(), + vmIntrinsics.size()); + } + + void printConfig(HotSpotJVMCIRuntime runtime) { + TreeMap fields = new TreeMap<>(getFields()); + for (VMField field : fields.values()) { + if (!field.isStatic()) { + printConfigLine(runtime, "[vmconfig:instance field] %s %s {offset=%d[0x%x]}%n", field.type, field.name, field.offset, field.offset); + } else { + String value = field.value == null ? "null" : field.value instanceof Boolean ? field.value.toString() : String.format("%d[0x%x]", field.value, field.value); + printConfigLine(runtime, "[vmconfig:static field] %s %s = %s {address=0x%x}%n", field.type, field.name, value, field.address); + } + } + TreeMap flags = new TreeMap<>(getFlags()); + for (VMFlag flag : flags.values()) { + printConfigLine(runtime, "[vmconfig:flag] %s %s = %s%n", flag.type, flag.name, flag.value); + } + TreeMap addresses = new TreeMap<>(getAddresses()); + for (Map.Entry e : addresses.entrySet()) { + printConfigLine(runtime, "[vmconfig:address] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue()); + } + TreeMap constants = new TreeMap<>(getConstants()); + for (Map.Entry e : constants.entrySet()) { + printConfigLine(runtime, "[vmconfig:constant] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue()); + } + for (VMIntrinsicMethod e : getIntrinsics()) { + printConfigLine(runtime, "[vmconfig:intrinsic] %d = %s.%s %s%n", e.id, e.declaringClass, e.name, e.descriptor); + } + } + + @SuppressFBWarnings(value = "DM_DEFAULT_ENCODING", justification = "no localization here please!") + private static void printConfigLine(HotSpotJVMCIRuntime runtime, String format, Object... args) { + String line = String.format(format, args); + byte[] lineBytes = line.getBytes(); + runtime.writeDebugOutput(lineBytes, 0, lineBytes.length, true, true); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMEventListener.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMEventListener.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMEventListener.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMEventListener.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.code.CompiledCode; +import jdk.vm.ci.code.InstalledCode; + +/** + * Listener for responding to VM events. + */ +public interface HotSpotVMEventListener { + + /** + * Notifies this client that the VM is shutting down. + */ + default void notifyShutdown() { + } + + /** + * Notify on successful install into the code cache. + * + * @param hotSpotCodeCacheProvider the code cache into which the code was installed + * @param installedCode the code that was installed + * @param compiledCode the compiled code from which {@code installedCode} was produced + */ + default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) { + } + + /** + * Notify on completion of a bootstrap. + */ + default void notifyBootstrapFinished() { + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; +import jdk.vm.ci.meta.JavaConstant; + +/** + * Encapsulates a JNI reference to an object in the HotSpot heap. + * + * {@link IndirectHotSpotObjectConstantImpl} objects are only allocated in the shared library heap. + * + * @see HotSpotObjectConstantScope + */ +final class IndirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl { + /** + * An object handle in {@code JVMCI::_object_handles}. + */ + private long objectHandle; + + /** + * Lazily computed hash code. + */ + private int hashCode; + + final IndirectHotSpotObjectConstantImpl base; + + private static class Audit { + final Object scope; + final long handle; + final Throwable origin; + + Audit(Object scope, long handle, Throwable origin) { + this.scope = scope; + this.handle = handle; + this.origin = origin; + } + } + + /** + * Details useful to audit a scoped handle used after its creating scope closes. Set to an + * {@link Audit} object if {@link HotSpotJVMCIRuntime.Option#AuditHandles} is true otherwise to + * {@link HotSpotObjectConstantScope#localScopeDescription}. + */ + private Object rawAudit; + + @SuppressWarnings("serial") + @VMEntryPoint + private IndirectHotSpotObjectConstantImpl(long objectHandle, boolean compressed, boolean skipRegister) { + super(compressed); + assert objectHandle != 0 && UnsafeAccess.UNSAFE.getLong(objectHandle) != 0; + this.objectHandle = objectHandle; + this.base = null; + if (!skipRegister) { + HotSpotObjectConstantScope scope = HotSpotObjectConstantScope.CURRENT.get(); + if (scope != null && !scope.isGlobal()) { + scope.add(this); + if (HotSpotJVMCIRuntime.Option.AuditHandles.getBoolean()) { + rawAudit = new Audit(scope.localScopeDescription, objectHandle, new Throwable() { + @Override + public String toString() { + return "Created " + objectHandle; + } + }); + } + } else { + HandleCleaner.create(this, objectHandle); + } + } + } + + private IndirectHotSpotObjectConstantImpl(IndirectHotSpotObjectConstantImpl base, boolean compressed) { + super(compressed); + // This is a variant of an original object that only varies in compress vs uncompressed. + // Instead of creating a new handle, reference that object and objectHandle. + this.objectHandle = base.getHandle(); + // There should only be one level of indirection to the base object. + assert base.base == null || base.base.base == null; + this.base = base.base != null ? base.base : base; + } + + long getHandle() { + checkHandle(); + return objectHandle; + } + + private void checkHandle() { + if (objectHandle == 0L) { + String message; + if (rawAudit instanceof Audit) { + Audit audit = (Audit) rawAudit; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + ps.println("Foreign object reference " + audit.handle + " created in scope '" + audit.scope + "' is no longer valid. Origin: {"); + audit.origin.printStackTrace(ps); + ps.print('}'); + ps.flush(); + message = baos.toString(); + } else { + message = "Foreign object reference created in scope '" + rawAudit + "' is no longer valid. " + + "Set property " + Option.AuditHandles.getPropertyName() + "=true to show origin of invalid foreign references."; + } + throw new NullPointerException(message); + } + } + + boolean isValid() { + return objectHandle != 0L; + } + + @Override + public HotSpotResolvedObjectType getType() { + checkHandle(); + return super.getType(); + } + + /** + * Clears the foreign object reference. + */ + void clear(Object scopeDescription) { + checkHandle(); + CompilerToVM.compilerToVM().deleteGlobalHandle(objectHandle); + if (rawAudit == null) { + rawAudit = scopeDescription; + } + objectHandle = 0L; + } + + @Override + public JavaConstant compress() { + assert !compressed; + return new IndirectHotSpotObjectConstantImpl(this, true); + } + + @Override + public JavaConstant uncompress() { + assert compressed; + return new IndirectHotSpotObjectConstantImpl(this, false); + } + + @Override + public int getIdentityHashCode() { + checkHandle(); + int hash = hashCode; + if (hash == 0) { + hash = runtime().compilerToVm.getIdentityHashCode(this); + if (hash == 0) { + hash = 31; + } + hashCode = hash; + } + return hash; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/JFR.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/JFR.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/JFR.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/JFR.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify + * it when events occur. The JFR events are defined in {see @code + * src/share/jfr/metadata/metadata.xml}. + */ +public final class JFR { + + /** + * Provides access to current JFR time stamp. + */ + public static final class Ticks { + + /** + * @return current JFR time stamp + */ + public static long now() { + return compilerToVM().ticksNow(); + } + } + + /** + * Helper methods for managing JFR CompilerPhase events. + * The events are defined in {see @code src/share/jfr/metadata/metadata.xml}. + */ + public static final class CompilerPhaseEvent { + + private static final ConcurrentHashMap phaseToId = new ConcurrentHashMap<>(); + + private static int getPhaseToId(String phaseName) { + return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhase(phaseName)); + } + + /** + * Commits a CompilerPhase event. + * + * @param startTime time captured at the start of compiler phase + * @param phaseName compiler phase name + * @param compileId current compilation unit id + * @param phaseLevel compiler phase nesting level + */ + public static void write(long startTime, String phaseName, int compileId, int phaseLevel) { + compilerToVM().notifyCompilerPhaseEvent(startTime, getPhaseToId(phaseName), compileId, phaseLevel); + } + } + + /** + * Helper methods for managing JFR CompilerInlining events. The events are defined in {see @code + * src/share/jfr/metadata/metadata.xml}. + */ + public static final class CompilerInliningEvent { + + /** + * Commits a CompilerInlining event. + * + * @param compileId current compilation unit id + * @param caller caller method + * @param callee callee method + * @param succeeded inlining succeeded or not + * @param message extra information on inlining + * @param bci invocation byte code index + */ + public static void write(int compileId, ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, String message, int bci) { + compilerToVM().notifyCompilerInliningEvent(compileId, (HotSpotResolvedJavaMethodImpl) caller, (HotSpotResolvedJavaMethodImpl) callee, succeeded, message, bci); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceHandleObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceHandleObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceHandleObject.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceHandleObject.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * A tag interface indicating that this type is a handledized wrapper around a HotSpot metaspace + * object that requires GC interaction to keep alive. + * + * It would preferable if this were the base class containing the pointer but that would require + * mixins since most of the wrapper types have complex supertype hierarchies. + */ +interface MetaspaceHandleObject extends MetaspaceObject { + + long getMetadataHandle(); + + @Override + default long getMetaspacePointer() { + return UnsafeAccess.UNSAFE.getLong(getMetadataHandle()); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceObject.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/MetaspaceObject.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * The marker interface for an object which wraps HotSpot Metadata. + */ +interface MetaspaceObject { + long getMetaspacePointer(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * HotSpot specific portions of the JVMCI API. + */ +package jdk.vm.ci.hotspot; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * A wrapper that holds a strong reference to a "master" speculation log that + * {@linkplain HotSpotSpeculationLog#managesFailedSpeculations() manages} the failed speculations + * list. + */ +public class SharedHotSpotSpeculationLog extends HotSpotSpeculationLog { + private final HotSpotSpeculationLog masterLog; + + public SharedHotSpotSpeculationLog(HotSpotSpeculationLog masterLog) { + super(masterLog.getFailedSpeculationsAddress()); + this.masterLog = masterLog; + } + + @Override + public String toString() { + return masterLog.toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Array; +import java.lang.reflect.Type; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * Implementation of {@link HotSpotJVMCIReflection} when running in a JVMCI shared library. + */ +class SharedLibraryJVMCIReflection extends HotSpotJVMCIReflection { + + @Override + Object resolveObject(HotSpotObjectConstantImpl objectHandle) { + throw new HotSpotJVMCIUnsupportedOperationError("cannot resolve handle in a JVMCI shared library to a raw object: " + objectHandle); + } + + @Override + boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl obj) { + if (obj instanceof DirectHotSpotObjectConstantImpl) { + ResolvedJavaType type = getType(obj); + return holder.isAssignableFrom(type); + } + return runtime().compilerToVm.isInstance(holder, obj); + } + + @Override + boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType) { + return runtime().compilerToVm.isAssignableFrom(holder, otherType); + } + + @Override + boolean isLocalClass(HotSpotResolvedObjectTypeImpl holder) { + throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.isLocalClass()"); + } + + @Override + boolean isMemberClass(HotSpotResolvedObjectTypeImpl holder) { + throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.isMemberClass()"); + } + + @Override + HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder) { + throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.getEnclosingClass()"); + } + + @Override + boolean equals(HotSpotObjectConstantImpl x, HotSpotObjectConstantImpl y) { + if (x == y) { + return true; + } + if (x.compressed != y.compressed) { + return false; + } + if (x instanceof DirectHotSpotObjectConstantImpl && y instanceof DirectHotSpotObjectConstantImpl) { + DirectHotSpotObjectConstantImpl xd = (DirectHotSpotObjectConstantImpl) x; + DirectHotSpotObjectConstantImpl yd = (DirectHotSpotObjectConstantImpl) y; + return (xd.object == yd.object); + } + if (x instanceof DirectHotSpotObjectConstantImpl || y instanceof DirectHotSpotObjectConstantImpl) { + // Mixing of constant types is always inequal + return false; + } + IndirectHotSpotObjectConstantImpl indirectX = (IndirectHotSpotObjectConstantImpl) x; + IndirectHotSpotObjectConstantImpl indirectY = (IndirectHotSpotObjectConstantImpl) y; + return runtime().compilerToVm.equals(x, indirectX.getHandle(), y, indirectY.getHandle()); + } + + @Override + ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod) { + // ResolvedJavaMethod.getParameters allows a return value of null + return null; + } + + // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection + static Annotation[] getClassAnnotations(String className) { + throw new InternalError("missing substitution: " + className); + } + + // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection + static Annotation[][] getParameterAnnotations(String className, String methodName) { + throw new InternalError("missing substitution: " + className + " " + methodName); + } + + @Override + Annotation[] getAnnotations(HotSpotResolvedObjectTypeImpl holder) { + Annotation[] annotations = getClassAnnotations(holder.getName()); + return annotations == null ? new Annotation[0] : annotations; + } + + @Override + Annotation[] getDeclaredAnnotations(HotSpotResolvedObjectTypeImpl holder) { + throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); + } + + @Override + T getAnnotation(HotSpotResolvedObjectTypeImpl holder, Class annotationClass) { + throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); + } + + @Override + Annotation[][] getParameterAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { + Annotation[][] annotations = getParameterAnnotations(javaMethod.getDeclaringClass().getName(), javaMethod.getName()); + if (annotations == null) { + return new Annotation[javaMethod.signature.getParameterCount(false)][0]; + } + return annotations; + } + + @Override + Type[] getGenericParameterTypes(HotSpotResolvedJavaMethodImpl javaMethod) { + throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); + } + + @Override + Annotation[] getFieldAnnotations(HotSpotResolvedJavaFieldImpl javaField) { + throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); + } + + @Override + Annotation[] getMethodAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { + Annotation[] annotations = getMethodAnnotationsInternal(javaMethod); + return annotations == null ? new Annotation[0] : annotations; + } + + @Override + T getMethodAnnotation(HotSpotResolvedJavaMethodImpl javaMethod, Class annotationClass) { + Annotation[] methodAnnotations = getMethodAnnotations(javaMethod); + if (methodAnnotations != null) { + for (Annotation ann : methodAnnotations) { + if (annotationClass.isInstance(ann)) { + return annotationClass.cast(ann); + } + } + } + return null; + } + + // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection + @SuppressWarnings("unused") + private static Annotation[] getMethodAnnotationsInternal(ResolvedJavaMethod javaMethod) { + throw new InternalError("missing substitution"); + } + + @Override + Annotation[] getMethodDeclaredAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { + throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); + } + + @Override + Annotation[] getFieldDeclaredAnnotations(HotSpotResolvedJavaFieldImpl javaMethod) { + throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); + } + + @Override + T getFieldAnnotation(HotSpotResolvedJavaFieldImpl javaField, Class annotationClass) { + throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); + } + + @Override + HotSpotResolvedObjectTypeImpl getType(HotSpotObjectConstantImpl object) { + if (object instanceof DirectHotSpotObjectConstantImpl) { + Class theClass = ((DirectHotSpotObjectConstantImpl) object).object.getClass(); + try { + String name = theClass.getName().replace('.', '/'); + HotSpotResolvedObjectTypeImpl type = (HotSpotResolvedObjectTypeImpl) runtime().compilerToVm.lookupType(name, null, true); + if (type == null) { + throw new InternalError(name); + } + return type; + } catch (ClassNotFoundException e) { + throw new InternalError(e); + } + } + return runtime().compilerToVm.getResolvedJavaType(object, runtime().getConfig().hubOffset, false); + } + + @Override + String asString(HotSpotObjectConstantImpl object) { + if (object instanceof IndirectHotSpotObjectConstantImpl) { + return runtime().compilerToVm.asString(object); + } + Object value = ((DirectHotSpotObjectConstantImpl) object).object; + if (value instanceof String) { + return (String) value; + } + return null; + } + + @Override + ResolvedJavaType asJavaType(HotSpotObjectConstantImpl object) { + if (object instanceof DirectHotSpotObjectConstantImpl) { + DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; + if (direct.object instanceof Class) { + Class javaClass = (Class) direct.object; + return runtime().fromClass(javaClass); + } + if (direct.object instanceof ResolvedJavaType) { + return (ResolvedJavaType) convertUnknownValue(direct.object); + } + return null; + } + return runtime().compilerToVm.asJavaType(object); + } + + // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection + static Object convertUnknownValue(Object object) { + return object; + } + + @SuppressWarnings("unchecked") + @Override + T asObject(HotSpotObjectConstantImpl object, Class type) { + if (object instanceof DirectHotSpotObjectConstantImpl) { + Object theObject = ((DirectHotSpotObjectConstantImpl) object).object; + if (type.isInstance(theObject)) { + return (T) convertUnknownValue(type.cast(theObject)); + } + } + return null; + } + + @Override + Object asObject(HotSpotObjectConstantImpl object, HotSpotResolvedJavaType type) { + throw new HotSpotJVMCIUnsupportedOperationError("cannot resolve a shared library JVMCI object handle to a " + + "raw object as it may be in another runtime"); + } + + @Override + String formatString(HotSpotObjectConstantImpl object) { + if (object instanceof DirectHotSpotObjectConstantImpl) { + DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; + return "CompilerObject<" + direct.object.getClass().getName() + ">"; + } + IndirectHotSpotObjectConstantImpl indirect = (IndirectHotSpotObjectConstantImpl) object; + if (!indirect.isValid()) { + return "Instance"; + } + return "Instance<" + object.getType().toJavaName() + ">"; + } + + @Override + Integer getLength(HotSpotObjectConstantImpl object) { + if (object instanceof DirectHotSpotObjectConstantImpl) { + DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; + if (direct.object.getClass().isArray()) { + return Array.getLength(direct.object); + } + return null; + } + int length = runtime().compilerToVm.getArrayLength(object); + if (length >= 0) { + return length; + } + return null; + } + + @Override + JavaConstant readArrayElement(HotSpotObjectConstantImpl arrayObject, int index) { + Object result = runtime().compilerToVm.readArrayElement(arrayObject, index); + if (result == null) { + return null; + } + if (result instanceof JavaConstant) { + return (JavaConstant) result; + } + JavaConstant constant = JavaConstant.forBoxedPrimitive(result); + if (constant == null) { + throw new InternalError("Unexpected value " + result); + } + return constant; + } + + @Override + JavaConstant forObject(Object value) { + return DirectHotSpotObjectConstantImpl.forObject(value, false); + } + + @Override + JavaConstant unboxPrimitive(HotSpotObjectConstantImpl source) { + Object box = runtime().compilerToVm.unboxPrimitive(source); + return JavaConstant.forBoxedPrimitive(box); + } + + @Override + JavaConstant boxPrimitive(JavaConstant source) { + return runtime().compilerToVm.boxPrimitive(source.asBoxedPrimitive()); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SuppressFBWarnings.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * Used to suppress FindBugs warnings. + */ +@interface SuppressFBWarnings { + /** + * The set of FindBugs + * warnings that are to be + * suppressed in annotated element. The value can be a bug category, kind or pattern. + */ + String[] value(); + + /** + * Reason why the warning is suppressed. + */ + String justification(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/TranslatedException.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/TranslatedException.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/TranslatedException.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/TranslatedException.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import jdk.vm.ci.common.JVMCIError; + +/** + * Support for translating exceptions between different runtime heaps. + */ +@SuppressWarnings("serial") +final class TranslatedException extends Exception { + + /** + * The value returned by {@link #encodeThrowable(Throwable)} when encoding fails due to an + * {@link OutOfMemoryError}. + */ + private static final byte[] FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES; + + /** + * The value returned by {@link #encodeThrowable(Throwable)} when encoding fails for any reason + * other than {@link OutOfMemoryError}. + */ + private static final byte[] FALLBACK_ENCODED_THROWABLE_BYTES; + static { + try { + FALLBACK_ENCODED_THROWABLE_BYTES = encodeThrowable(new TranslatedException("error during encoding", ""), false); + FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES = encodeThrowable(new OutOfMemoryError(), false); + } catch (IOException e) { + throw new JVMCIError(e); + } + } + + /** + * Class name of exception that could not be instantiated. + */ + private String originalExceptionClassName; + + private TranslatedException(String message, String originalExceptionClassName) { + super(message); + this.originalExceptionClassName = originalExceptionClassName; + } + + /** + * No need to record an initial stack trace since it will be manually overwritten. + */ + @SuppressWarnings("sync-override") + @Override + public Throwable fillInStackTrace() { + return this; + } + + @Override + public String toString() { + String s; + if (originalExceptionClassName.equals(TranslatedException.class.getName())) { + s = getClass().getName(); + } else { + s = getClass().getName() + "[" + originalExceptionClassName + "]"; + } + String message = getMessage(); + return (message != null) ? (s + ": " + message) : s; + } + + /** + * Prints a stack trace for {@code throwable} and returns {@code true}. Used to print stack + * traces only when assertions are enabled. + */ + private static boolean printStackTrace(Throwable throwable) { + throwable.printStackTrace(); + return true; + } + + private static Throwable initCause(Throwable throwable, Throwable cause) { + if (cause != null) { + try { + throwable.initCause(cause); + } catch (IllegalStateException e) { + // Cause could not be set or overwritten. + assert printStackTrace(e); + } + } + return throwable; + } + + private static Throwable create(String className, String message, Throwable cause) { + // Try create with reflection first. + try { + Class cls = Class.forName(className); + if (cause != null) { + // Handle known exception types whose cause must be set in the constructor + if (cls == InvocationTargetException.class) { + return new InvocationTargetException(cause, message); + } + if (cls == ExceptionInInitializerError.class) { + return new ExceptionInInitializerError(cause); + } + } + if (message == null) { + return initCause((Throwable) cls.getConstructor().newInstance(), cause); + } + return initCause((Throwable) cls.getDeclaredConstructor(String.class).newInstance(message), cause); + } catch (Throwable translationFailure) { + return initCause(new TranslatedException(message, className), cause); + } + } + + private static String emptyIfNull(String value) { + return value == null ? "" : value; + } + + private static String emptyAsNull(String value) { + return value.isEmpty() ? null : value; + } + + /** + * Encodes {@code throwable} including its stack and causes as a {@linkplain GZIPOutputStream + * compressed} byte array that can be decoded by {@link #decodeThrowable}. + */ + static byte[] encodeThrowable(Throwable throwable) throws Throwable { + try { + return encodeThrowable(throwable, true); + } catch (OutOfMemoryError e) { + return FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES; + } catch (Throwable e) { + return FALLBACK_ENCODED_THROWABLE_BYTES; + } + } + + private static byte[] encodeThrowable(Throwable throwable, boolean withCauseAndStack) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(new GZIPOutputStream(baos))) { + List throwables = new ArrayList<>(); + for (Throwable current = throwable; current != null; current = current.getCause()) { + throwables.add(current); + if (!withCauseAndStack) { + break; + } + } + + // Encode from inner most cause outwards + Collections.reverse(throwables); + + for (Throwable current : throwables) { + dos.writeUTF(current.getClass().getName()); + dos.writeUTF(emptyIfNull(current.getMessage())); + StackTraceElement[] stackTrace = withCauseAndStack ? current.getStackTrace() : null; + if (stackTrace == null) { + stackTrace = new StackTraceElement[0]; + } + dos.writeInt(stackTrace.length); + for (int i = 0; i < stackTrace.length; i++) { + StackTraceElement frame = stackTrace[i]; + if (frame != null) { + dos.writeUTF(emptyIfNull(frame.getClassLoaderName())); + dos.writeUTF(emptyIfNull(frame.getModuleName())); + dos.writeUTF(emptyIfNull(frame.getModuleVersion())); + dos.writeUTF(emptyIfNull(frame.getClassName())); + dos.writeUTF(emptyIfNull(frame.getMethodName())); + dos.writeUTF(emptyIfNull(frame.getFileName())); + dos.writeInt(frame.getLineNumber()); + } + } + } + } + return baos.toByteArray(); + } + + /** + * Gets the stack of the current thread without the frames between this call and the one just + * below the frame of the first method in {@link CompilerToVM}. The chopped frames are for the + * VM call to {@link HotSpotJVMCIRuntime#decodeAndThrowThrowable}. + */ + private static StackTraceElement[] getMyStackTrace() { + StackTraceElement[] stack = new Exception().getStackTrace(); + for (int i = 0; i < stack.length; i++) { + StackTraceElement e = stack[i]; + if (e.getClassName().equals(CompilerToVM.class.getName())) { + return Arrays.copyOfRange(stack, i, stack.length); + } + } + // This should never happen but since we're in exception handling + // code, just return a safe value instead raising a nested exception. + return new StackTraceElement[0]; + } + + /** + * Decodes {@code encodedThrowable} into a {@link TranslatedException}. + * + * @param encodedThrowable an encoded exception in the format specified by + * {@link #encodeThrowable} + */ + static Throwable decodeThrowable(byte[] encodedThrowable) { + try (DataInputStream dis = new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(encodedThrowable)))) { + Throwable cause = null; + Throwable throwable = null; + StackTraceElement[] myStack = getMyStackTrace(); + while (dis.available() != 0) { + String exceptionClassName = dis.readUTF(); + String exceptionMessage = emptyAsNull(dis.readUTF()); + throwable = create(exceptionClassName, exceptionMessage, cause); + int stackTraceDepth = dis.readInt(); + StackTraceElement[] stackTrace = new StackTraceElement[stackTraceDepth + myStack.length]; + int stackTraceIndex = 0; + int myStackIndex = 0; + for (int j = 0; j < stackTraceDepth; j++) { + String classLoaderName = emptyAsNull(dis.readUTF()); + String moduleName = emptyAsNull(dis.readUTF()); + String moduleVersion = emptyAsNull(dis.readUTF()); + String className = emptyAsNull(dis.readUTF()); + String methodName = emptyAsNull(dis.readUTF()); + String fileName = emptyAsNull(dis.readUTF()); + int lineNumber = dis.readInt(); + StackTraceElement ste = new StackTraceElement(classLoaderName, moduleName, moduleVersion, className, methodName, fileName, lineNumber); + + if (ste.isNativeMethod()) { + // Best effort attempt to weave stack traces from two heaps into + // a single stack trace using native method frames as stitching points. + // This is not 100% reliable as there's no guarantee that native method + // frames only exist for calls between HotSpot and libjvmci. + while (myStackIndex < myStack.length) { + StackTraceElement suffixSTE = myStack[myStackIndex++]; + if (suffixSTE.isNativeMethod()) { + break; + } + stackTrace[stackTraceIndex++] = suffixSTE; + } + } + stackTrace[stackTraceIndex++] = ste; + } + while (myStackIndex < myStack.length) { + stackTrace[stackTraceIndex++] = myStack[myStackIndex++]; + } + throwable.setStackTrace(stackTrace); + cause = throwable; + } + return throwable; + } catch (Throwable translationFailure) { + assert printStackTrace(translationFailure); + return new TranslatedException("Error decoding exception: " + encodedThrowable, translationFailure.getClass().getName()); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/UnsafeAccess.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/UnsafeAccess.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/UnsafeAccess.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/UnsafeAccess.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.internal.misc.Unsafe; + +/** + * Package private access to the {@link Unsafe} capability. + */ +class UnsafeAccess { + + static final Unsafe UNSAFE = Unsafe.getUnsafe(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMEntryPoint.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMEntryPoint.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMEntryPoint.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMEntryPoint.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * Marker interface for methods which are called from the JVM. + */ +@interface VMEntryPoint { + /** + * An optional comment describing the caller. + */ + String value() default ""; +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * Describes a C++ field exposed via {@link HotSpotVMConfigAccess}. + */ +public final class VMField { + + /** + * Fully qualified name of the represented field (e.g., "Klass::_name"). + */ + public final String name; + + /** + * The represented field's type (e.g., "Symbol*"). This may be {@code null}. + */ + public final String type; + + /** + * If the represented field is non-static, this is its offset within the containing structure. + */ + public final long offset; + + /** + * If the represented field is static, this is its address. Otherwise, this is 0. + */ + public final long address; + + /** + * Value of the field represented as a boxed boolean if its C++ type is bool otherwise as a + * boxed long; only valid for non-oop static fields. This value is only captured once, during + * JVMCI initialization. If {@link #type} cannot be meaningfully (e.g., a struct) or safely + * (e.g., an oop) expressed as a boxed object, this is {@code null}. + */ + public final Object value; + + /** + * Determines if the represented field is static. + */ + public boolean isStatic() { + return address != 0; + } + + /** + * Creates a description of a non-static field. + */ + @VMEntryPoint + VMField(String name, String type, long offset, long address, Object value) { + this.name = name; + this.type = type; + this.offset = offset; + this.address = address; + this.value = value; + } + + @Override + public String toString() { + String val = value == null ? "null" : (type.contains("*") ? String.format("0x%x", value) : String.format("%s", value)); + return String.format("Field[name=%s, type=%s, offset=%d, address=0x%x, value=%s]", name, type, offset, address, val); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMFlag.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMFlag.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMFlag.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMFlag.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * Describes a VM flag exposed via {@link HotSpotVMConfigAccess}. + */ +public final class VMFlag { + + /** + * The name of the flag. + */ + public final String name; + + /** + * The C++ type of the flag. + */ + public final String type; + + /** + * The flag's value. + */ + public final Object value; + + @VMEntryPoint + VMFlag(String name, String type, Object value) { + this.name = name; + this.type = type; + this.value = value; + } + + @Override + public String toString() { + return String.format("Flag[type=%s, name=%s, value=%s]", type, name, value); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.Signature; + +/** + * Describes a method for which the VM has an intrinsic implementation. + */ +public final class VMIntrinsicMethod { + + /** + * The name of the class declaring the intrinsified method. The name is in + * class + * file format (e.g., {@code "java/lang/Thread"} instead of {@code "java.lang.Thread"}). + */ + public final String declaringClass; + + /** + * The name of the intrinsified method. This is not guaranteed to be a legal method name (e.g., + * there is a HotSpot intrinsic with the name {@code ""}). + */ + public final String name; + + /** + * The {@link Signature#toMethodDescriptor() descriptor} of the intrinsified method. This is not + * guaranteed to be a legal method descriptor (e.g., intrinsics for signature polymorphic + * methods have a descriptor of {@code "*"}). + */ + public final String descriptor; + + /** + * The unique VM identifier for the intrinsic. + */ + public final int id; + + @VMEntryPoint + VMIntrinsicMethod(String declaringClass, String name, String descriptor, int id) { + this.declaringClass = declaringClass; + this.name = name; + this.descriptor = descriptor; + this.id = id; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof VMIntrinsicMethod) { + VMIntrinsicMethod that = (VMIntrinsicMethod) obj; + if (that.id == this.id) { + assert that.name.equals(this.name) && + that.declaringClass.equals(this.declaringClass) && + that.descriptor.equals(this.descriptor); + return true; + } + } + return false; + } + + @Override + public int hashCode() { + return id; + } + + @Override + public String toString() { + return String.format("IntrinsicMethod[declaringClass=%s, name=%s, descriptor=%s, id=%d]", declaringClass, name, descriptor, id); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractJavaProfile.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractJavaProfile.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractJavaProfile.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractJavaProfile.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * This object holds probability information for a set of items that were profiled at a specific + * BCI. The precision of the supplied values may vary, but a runtime that provides this information + * should be aware that it will be used to guide performance-critical decisions like speculative + * inlining, etc. + * + * @param a subclass of AbstractProfiledItem + * @param the class of the items that are profiled at the specific BCI and for which + * probabilities are stored. E.g., a ResolvedJavaType or a ResolvedJavaMethod. + */ +public abstract class AbstractJavaProfile, U> { + + private final double notRecordedProbability; + private final T[] pitems; + + /** + * + * @param notRecordedProbability + * @param pitems + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of the `pitems` array parameter") + public AbstractJavaProfile(double notRecordedProbability, T[] pitems) { + this.pitems = pitems; + assert !Double.isNaN(notRecordedProbability); + this.notRecordedProbability = notRecordedProbability; + assert isSorted(); + assert totalProbablility() >= 0 && totalProbablility() <= 1.0001 : totalProbablility() + " " + this; + } + + private double totalProbablility() { + double total = notRecordedProbability; + for (T item : pitems) { + total += item.probability; + } + return total; + } + + /** + * Determines if an array of profiled items are sorted in descending order of their + * probabilities. + */ + private boolean isSorted() { + for (int i = 1; i < pitems.length; i++) { + if (pitems[i - 1].getProbability() < pitems[i].getProbability()) { + return false; + } + } + return true; + } + + /** + * Returns the estimated probability of all types that could not be recorded due to profiling + * limitations. + * + * @return double value ≥ 0.0 and ≤ 1.0 + */ + public double getNotRecordedProbability() { + return notRecordedProbability; + } + + protected T[] getItems() { + return pitems; + } + + /** + * Searches for an entry of a given resolved Java type. + * + * @param type the type for which an entry should be searched + * @return the entry or null if no entry for this type can be found + */ + public T findEntry(ResolvedJavaType type) { + if (pitems != null) { + for (T pt : pitems) { + if (pt.getItem().equals(type)) { + return pt; + } + } + } + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(this.getClass().getName()); + builder.append("["); + if (pitems != null) { + for (T pt : pitems) { + builder.append(pt.toString()); + builder.append(", "); + } + } + builder.append(this.notRecordedProbability); + builder.append("]"); + return builder.toString(); + } + + public boolean isIncluded(U item) { + if (this.getNotRecordedProbability() > 0.0) { + return true; + } else { + for (int i = 0; i < getItems().length; i++) { + T pitem = getItems()[i]; + U curType = pitem.getItem(); + if (curType == item) { + return true; + } + } + } + return false; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof AbstractJavaProfile)) { + return false; + } + AbstractJavaProfile that = (AbstractJavaProfile) obj; + if (that.notRecordedProbability != notRecordedProbability) { + return false; + } + if (that.pitems.length != pitems.length) { + return false; + } + for (int i = 0; i < pitems.length; ++i) { + if (!pitems[i].equals(that.pitems[i])) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + return (int) Double.doubleToLongBits(notRecordedProbability) + pitems.length * 13; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractProfiledItem.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractProfiledItem.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractProfiledItem.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AbstractProfiledItem.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * A profiled type that has a probability. Profiled types are naturally sorted in descending order + * of their probabilities. + */ +public abstract class AbstractProfiledItem implements Comparable> { + + protected final T item; + protected final double probability; + + public AbstractProfiledItem(T item, double probability) { + assert item != null; + assert probability >= 0.0D && probability <= 1.0D; + this.item = item; + this.probability = probability; + } + + protected T getItem() { + return item; + } + + /** + * Returns the estimated probability of {@link #getItem()}. + * + * @return double value ≥ 0.0 and ≤ 1.0 + */ + public double getProbability() { + return probability; + } + + /** + * Returns -1 if the {@linkplain #getProbability() probability} of this item is greater than + * {@code o}'s probability, 0 if there are equal otherwise 1. + */ + @Override + public int compareTo(AbstractProfiledItem o) { + // Need to swap the order of operands so that higher probabilities are sorted first + return Double.compare(o.getProbability(), getProbability()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(probability); + result = prime * result + (int) (temp ^ (temp >>> 32)); + result = prime * result + item.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + AbstractProfiledItem other = (AbstractProfiledItem) obj; + if (Double.doubleToLongBits(probability) != Double.doubleToLongBits(other.probability)) { + return false; + } + return item.equals(other.item); + } + + @Override + public abstract String toString(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AllocatableValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AllocatableValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AllocatableValue.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AllocatableValue.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Common base class for values that are stored in some location that's managed by the register + * allocator (e.g. register, stack slot). + */ +public abstract class AllocatableValue extends Value implements JavaValue { + + public static final AllocatableValue[] NONE = {}; + + public AllocatableValue(ValueKind kind) { + super(kind); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Assumptions.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Assumptions.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Assumptions.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Assumptions.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * Class for recording assumptions made during compilation. + */ +public final class Assumptions implements Iterable { + + /** + * Abstract base class for assumptions. An assumption assumes a property of the runtime that may + * be invalidated by subsequent execution (e.g., that a class has no subclasses implementing + * {@link NoFinalizableSubclass Object.finalize()}). + */ + public abstract static class Assumption { + } + + /** + * A class for providing information that is only valid in association with a set of + * {@link Assumption}s. It is permissible for AssumptionResults to have no assumptions at all. + * For instance, if {@link ResolvedJavaType#isLeaf()} returns true for a type + * {@link ResolvedJavaType#findLeafConcreteSubtype()} can return an AssumptionResult with no + * assumptions since the leaf information is statically true. + * + * @param + */ + public static class AssumptionResult { + Assumption[] assumptions; + final T result; + + private static final Assumption[] EMPTY = new Assumption[0]; + + public AssumptionResult(T result, Assumption... assumptions) { + this.result = result; + this.assumptions = assumptions; + } + + public AssumptionResult(T result) { + this(result, EMPTY); + } + + public T getResult() { + return result; + } + + public boolean isAssumptionFree() { + return assumptions.length == 0; + } + + public void add(AssumptionResult other) { + Assumption[] newAssumptions = Arrays.copyOf(this.assumptions, this.assumptions.length + other.assumptions.length); + System.arraycopy(other.assumptions, 0, newAssumptions, this.assumptions.length, other.assumptions.length); + this.assumptions = newAssumptions; + } + + public boolean canRecordTo(Assumptions target) { + /* + * We can use the result if it is either assumption free, or if we have a valid + * Assumptions object where we can record assumptions. + */ + return assumptions.length == 0 || target != null; + } + + public void recordTo(Assumptions target) { + assert canRecordTo(target); + + if (assumptions.length > 0) { + for (Assumption assumption : assumptions) { + target.record(assumption); + } + } + } + } + + /** + * An assumption that a given class has no subclasses implementing {@code Object#finalize()}). + */ + public static final class NoFinalizableSubclass extends Assumption { + + private ResolvedJavaType receiverType; + + public NoFinalizableSubclass(ResolvedJavaType receiverType) { + this.receiverType = receiverType; + } + + @Override + public int hashCode() { + return 31 + receiverType.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof NoFinalizableSubclass) { + NoFinalizableSubclass other = (NoFinalizableSubclass) obj; + return other.receiverType.equals(receiverType); + } + return false; + } + + @Override + public String toString() { + return "NoFinalizableSubclass[receiverType=" + receiverType.toJavaName() + "]"; + } + + } + + /** + * An assumption that a given abstract or interface type has one direct concrete subtype. There + * is no requirement that the subtype is a leaf type. + */ + public static final class ConcreteSubtype extends Assumption { + + /** + * Type the assumption is made about. + */ + public final ResolvedJavaType context; + + /** + * Assumed concrete sub-type of the context type. + */ + public final ResolvedJavaType subtype; + + public ConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) { + this.context = context; + this.subtype = subtype; + assert context.isAbstract(); + assert subtype.isConcrete() || context.isInterface() : subtype.toString() + " : " + context.toString(); + assert !subtype.isArray() || subtype.getElementalType().isFinalFlagSet() : subtype.toString() + " : " + context.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + context.hashCode(); + result = prime * result + subtype.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ConcreteSubtype) { + ConcreteSubtype other = (ConcreteSubtype) obj; + return other.context.equals(context) && other.subtype.equals(subtype); + } + return false; + } + + @Override + public String toString() { + return "ConcreteSubtype[context=" + context.toJavaName() + ", subtype=" + subtype.toJavaName() + "]"; + } + } + + /** + * An assumption that a given type has no subtypes. + */ + public static final class LeafType extends Assumption { + + /** + * Type the assumption is made about. + */ + public final ResolvedJavaType context; + + public LeafType(ResolvedJavaType context) { + assert !context.isLeaf() : "assumption isn't required for leaf types"; + this.context = context; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + context.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LeafType) { + LeafType other = (LeafType) obj; + return other.context.equals(context); + } + return false; + } + + @Override + public String toString() { + return "LeafSubtype[context=" + context.toJavaName() + "]"; + } + } + + /** + * An assumption that a given virtual method has a given unique implementation. + */ + public static final class ConcreteMethod extends Assumption { + + /** + * A virtual (or interface) method whose unique implementation for the receiver type in + * {@link #context} is {@link #impl}. + */ + public final ResolvedJavaMethod method; + + /** + * A receiver type. + */ + public final ResolvedJavaType context; + + /** + * The unique implementation of {@link #method} for {@link #context}. + */ + public final ResolvedJavaMethod impl; + + public ConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) { + this.method = method; + this.context = context; + this.impl = impl; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + method.hashCode(); + result = prime * result + context.hashCode(); + result = prime * result + impl.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ConcreteMethod) { + ConcreteMethod other = (ConcreteMethod) obj; + return other.method.equals(method) && other.context.equals(context) && other.impl.equals(impl); + } + return false; + } + + @Override + public String toString() { + return "ConcreteMethod[method=" + method.format("%H.%n(%p)%r") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)%r") + "]"; + } + } + + /** + * An assumption that a given call site's method handle did not change. + */ + public static final class CallSiteTargetValue extends Assumption { + + public final JavaConstant callSite; + public final JavaConstant methodHandle; + + public CallSiteTargetValue(JavaConstant callSite, JavaConstant methodHandle) { + this.callSite = callSite; + this.methodHandle = methodHandle; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + callSite.hashCode(); + result = prime * result + methodHandle.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof CallSiteTargetValue) { + CallSiteTargetValue other = (CallSiteTargetValue) obj; + return callSite.equals(other.callSite) && methodHandle.equals(other.methodHandle); + } + return false; + } + + @Override + public String toString() { + return "CallSiteTargetValue[callSite=" + callSite + ", methodHandle=" + methodHandle + "]"; + } + } + + private final Set assumptions = new HashSet<>(); + + /** + * Returns whether any assumptions have been registered. + * + * @return {@code true} if at least one assumption has been registered, {@code false} otherwise. + */ + public boolean isEmpty() { + return assumptions.isEmpty(); + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Assumptions) { + Assumptions that = (Assumptions) obj; + if (!this.assumptions.equals(that.assumptions)) { + return false; + } + return true; + } + return false; + } + + @Override + public Iterator iterator() { + return assumptions.iterator(); + } + + /** + * Records an assumption that the specified type has no finalizable subclasses. + * + * @param receiverType the type that is assumed to have no finalizable subclasses + */ + public void recordNoFinalizableSubclassAssumption(ResolvedJavaType receiverType) { + record(new NoFinalizableSubclass(receiverType)); + } + + /** + * Records that {@code subtype} is the only concrete subtype in the class hierarchy below + * {@code context}. + * + * @param context the root of the subtree of the class hierarchy that this assumptions is about + * @param subtype the one concrete subtype + */ + public void recordConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) { + record(new ConcreteSubtype(context, subtype)); + } + + /** + * Records that {@code impl} is the only possible concrete target for a virtual call to + * {@code method} with a receiver of type {@code context}. + * + * @param method a method that is the target of a virtual call + * @param context the receiver type of a call to {@code method} + * @param impl the concrete method that is the only possible target for the virtual call + */ + public void recordConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) { + record(new ConcreteMethod(method, context, impl)); + } + + public void record(Assumption assumption) { + assumptions.add(assumption); + } + + /** + * Gets a copy of the assumptions recorded in this object as an array. + */ + public Assumption[] toArray() { + return assumptions.toArray(new Assumption[assumptions.size()]); + } + + /** + * Copies assumptions recorded by another {@link Assumptions} object into this object. + */ + public void record(Assumptions other) { + assert other != this; + assumptions.addAll(other.assumptions); + } + + @Override + public String toString() { + return "Assumptions[" + assumptions + "]"; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Constant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Constant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Constant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Constant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Represents a compile-time constant (boxed) value within the compiler. + */ +public interface Constant { + + boolean isDefaultForKind(); + + String toValueString(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Represents the runtime representation of the constant pool that is used by the compiler when + * parsing bytecode. Provides methods to look up a constant pool entry without performing + * resolution. They are used during compilation. + */ +public interface ConstantPool { + + /** + * Returns the number of entries the constant pool. + * + * @return number of entries in the constant pool + */ + int length(); + + /** + * Ensures that the type referenced by the specified constant pool entry is loaded and + * initialized. This can be used to compile time resolve a type. It works for field, method, or + * type constant pool entries. + * + * @param cpi the index of the constant pool entry that references the type + * @param opcode the opcode of the instruction that references the type + */ + void loadReferencedType(int cpi, int opcode); + + /** + * Ensures that the type referenced by the specified constant pool entry is loaded. This can be + * used to compile time resolve a type. It works for field, method, or type constant pool + * entries. + * + * @param cpi the index of the constant pool entry that references the type + * @param opcode the opcode of the instruction that references the type + * @param initialize if {@code true}, the referenced type is either guaranteed to be initialized + * upon return or an initialization exception is thrown + */ + default void loadReferencedType(int cpi, int opcode, boolean initialize) { + if (initialize) { + loadReferencedType(cpi, opcode); + } else { + throw new UnsupportedOperationException(); + } + } + + /** + * Looks up the type referenced by the constant pool entry at {@code cpi} as referenced by the + * {@code opcode} bytecode instruction. + * + * @param cpi the index of a constant pool entry that references a type + * @param opcode the opcode of the instruction with {@code cpi} as an operand + * @return a reference to the compiler interface type + */ + JavaType lookupReferencedType(int cpi, int opcode); + + /** + * Looks up a reference to a field. If {@code opcode} is non-negative, then resolution checks + * specific to the bytecode it denotes are performed if the field is already resolved. Checks + * for some bytecodes require the method that contains the bytecode to be specified. Should any + * of these checks fail, an unresolved field reference is returned. + * + * @param cpi the constant pool index + * @param opcode the opcode of the instruction for which the lookup is being performed or + * {@code -1} + * @param method the method for which the lookup is being performed + * @return a reference to the field at {@code cpi} in this pool + * @throws ClassFormatError if the entry at {@code cpi} is not a field + */ + JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode); + + /** + * Looks up a reference to a method. If {@code opcode} is non-negative, then resolution checks + * specific to the bytecode it denotes are performed if the method is already resolved. Should + * any of these checks fail, an unresolved method reference is returned. + * + * @param cpi the constant pool index + * @param opcode the opcode of the instruction for which the lookup is being performed or + * {@code -1} + * @return a reference to the method at {@code cpi} in this pool + * @throws ClassFormatError if the entry at {@code cpi} is not a method + */ + JavaMethod lookupMethod(int cpi, int opcode); + + /** + * Looks up a reference to a type. If {@code opcode} is non-negative, then resolution checks + * specific to the bytecode it denotes are performed if the type is already resolved. Should any + * of these checks fail, an unresolved type reference is returned. + * + * @param cpi the constant pool index + * @param opcode the opcode of the instruction for which the lookup is being performed or + * {@code -1} + * @return a reference to the compiler interface type + */ + JavaType lookupType(int cpi, int opcode); + + /** + * Looks up an Utf8 string. + * + * @param cpi the constant pool index + * @return the Utf8 string at index {@code cpi} in this constant pool + */ + String lookupUtf8(int cpi); + + /** + * Looks up a method signature. + * + * @param cpi the constant pool index + * @return the method signature at index {@code cpi} in this constant pool + */ + Signature lookupSignature(int cpi); + + /** + * Looks up a constant at the specified index. + * + * @param cpi the constant pool index + * @return the {@code Constant} or {@code JavaType} instance representing the constant pool + * entry + */ + Object lookupConstant(int cpi); + + /** + * Looks up the appendix at the specified index. + * + * @param cpi the constant pool index + * @param opcode the opcode of the instruction for which the lookup is being performed or + * {@code -1} + * @return the appendix if it exists and is resolved or {@code null} + */ + JavaConstant lookupAppendix(int cpi, int opcode); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantReflectionProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantReflectionProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantReflectionProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantReflectionProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2012, 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. + */ +package jdk.vm.ci.meta; + +import java.lang.invoke.MethodHandle; + +/** + * Reflection operations on values represented as {@linkplain JavaConstant constants}. All methods + * in this interface require the VM to access the actual object encapsulated in + * {@link JavaKind#Object object} constants. This access is not always possible, depending on kind + * of VM and the state that the VM is in. Therefore, all methods can return {@code null} at any + * time, to indicate that the result is not available at this point. The caller is responsible to + * check for {@code null} results and handle them properly, e.g., not perform an optimization. + */ +public interface ConstantReflectionProvider { + + /** + * Compares two constants for equality. The equality relationship is symmetric. Returns + * {@link Boolean#TRUE true} if the two constants represent the same run time value, + * {@link Boolean#FALSE false} if they are different. Returns {@code null} if the constants + * cannot be compared at this point. + */ + Boolean constantEquals(Constant x, Constant y); + + /** + * Returns the length of the array constant. Returns {@code null} if the constant is not an + * array, or if the array length is not available at this point. + */ + Integer readArrayLength(JavaConstant array); + + /** + * Reads a value from the given array at the given index. Returns {@code null} if the constant + * is not an array, if the index is out of bounds, or if the value is not available at this + * point. + */ + JavaConstant readArrayElement(JavaConstant array, int index); + + /** + * Gets the current value of this field for a given object, if available. + * + * There is no guarantee that the same value will be returned by this method for a field unless + * the field is considered to be constant by the runtime. + * + * @param receiver object from which this field's value is to be read. This value is ignored if + * this field is static. + * @return the value of this field or {@code null} if the value is not available (e.g., because + * the field holder is not yet initialized). + */ + JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver); + + /** + * Converts the given {@link JavaKind#isPrimitive() primitive} constant to a boxed + * {@link JavaKind#Object object} constant, according to the Java boxing rules. Returns + * {@code null} if the source is is not a primitive constant, or the boxed value is not + * available at this point. + */ + JavaConstant boxPrimitive(JavaConstant source); + + /** + * Converts the given {@link JavaKind#Object object} constant to a {@link JavaKind#isPrimitive() + * primitive} constant, according to the Java unboxing rules. Returns {@code null} if the source + * is is not an object constant that can be unboxed, or the unboxed value is not available at + * this point. + */ + JavaConstant unboxPrimitive(JavaConstant source); + + /** + * Gets a string as a {@link JavaConstant}. + */ + JavaConstant forString(String value); + + /** + * Returns the {@link ResolvedJavaType} for a {@link Class} object (or any other object regarded + * as a class by the VM) encapsulated in the given constant. Returns {@code null} if the + * constant does not encapsulate a class, or if the type is not available at this point. + */ + ResolvedJavaType asJavaType(Constant constant); + + /** + * Gets access to the internals of {@link MethodHandle}. + */ + MethodHandleAccessProvider getMethodHandleAccess(); + + /** + * Gets raw memory access. + */ + MemoryAccessProvider getMemoryAccessProvider(); + + /** + * Gets the runtime representation of the {@link Class} object of this type. + */ + JavaConstant asJavaClass(ResolvedJavaType type); + + /** + * Gets the runtime representation of the "hub" of this type--that is, the closest part of the + * type representation which is typically stored in the object header. + */ + Constant asObjectHub(ResolvedJavaType type); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DefaultProfilingInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DefaultProfilingInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DefaultProfilingInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DefaultProfilingInfo.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * An implementation of {@link ProfilingInfo} that can used in the absence of real profile + * information. + */ +public final class DefaultProfilingInfo implements ProfilingInfo { + + private static final ProfilingInfo[] NO_PROFILING_INFO = new ProfilingInfo[]{new DefaultProfilingInfo(TriState.TRUE), new DefaultProfilingInfo(TriState.FALSE), + new DefaultProfilingInfo(TriState.UNKNOWN)}; + + private final TriState exceptionSeen; + + DefaultProfilingInfo(TriState exceptionSeen) { + this.exceptionSeen = exceptionSeen; + } + + @Override + public int getCodeSize() { + return 0; + } + + @Override + public JavaTypeProfile getTypeProfile(int bci) { + return null; + } + + @Override + public JavaMethodProfile getMethodProfile(int bci) { + return null; + } + + @Override + public double getBranchTakenProbability(int bci) { + return -1; + } + + @Override + public double[] getSwitchProbabilities(int bci) { + return null; + } + + @Override + public TriState getExceptionSeen(int bci) { + return exceptionSeen; + } + + @Override + public TriState getNullSeen(int bci) { + return TriState.UNKNOWN; + } + + @Override + public int getExecutionCount(int bci) { + return -1; + } + + public static ProfilingInfo get(TriState exceptionSeen) { + return NO_PROFILING_INFO[exceptionSeen.ordinal()]; + } + + @Override + public int getDeoptimizationCount(DeoptimizationReason reason) { + return 0; + } + + @Override + public boolean isMature() { + return false; + } + + @Override + public String toString() { + return "DefaultProfilingInfo<" + this.toString(null, "; ") + ">"; + } + + @Override + public void setMature() { + // Do nothing + } + + @Override + public boolean setCompilerIRSize(Class irType, int nodeCount) { + return false; + } + + @Override + public int getCompilerIRSize(Class irType) { + return -1; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationAction.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationAction.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationAction.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationAction.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Specifies the action that should be taken by the runtime in case a certain deoptimization is + * triggered. + */ +public enum DeoptimizationAction { + /** + * Do not invalidate the machine code. This is typically used when deoptimizing at a point where + * it's highly likely nothing will change the likelihood of the deoptimization happening again. + * For example, a compiled array allocation where the size is negative. + */ + None(false), + + /** + * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is + * triggered too often. + */ + RecompileIfTooManyDeopts(true), + + /** + * Invalidate the machine code and reset the profiling information. + */ + InvalidateReprofile(true), + + /** + * Invalidate the machine code and immediately schedule a recompilation. This is typically used + * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not + * required to determine that the deoptimization will not re-occur. + */ + InvalidateRecompile(true), + + /** + * Invalidate the machine code and stop compiling the outermost method of this compilation. + */ + InvalidateStopCompiling(true); + + private final boolean invalidatesCompilation; + + DeoptimizationAction(boolean invalidatesCompilation) { + this.invalidatesCompilation = invalidatesCompilation; + } + + public boolean doesInvalidateCompilation() { + return invalidatesCompilation; + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationReason.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationReason.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationReason.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/DeoptimizationReason.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Enumeration of reasons for why a deoptimization is happening. + */ +public enum DeoptimizationReason { + None, + NullCheckException, + BoundsCheckException, + ClassCastException, + ArrayStoreException, + UnreachedCode, + TypeCheckedInliningViolated, + OptimizedTypeCheckViolated, + NotCompiledExceptionHandler, + Unresolved, + JavaSubroutineMismatch, + ArithmeticException, + RuntimeConstraint, + LoopLimitCheck, + Aliasing, + TransferToInterpreter, +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,115 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package jdk.vm.ci.meta; + +import java.util.Arrays; +import java.util.function.Supplier; + +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; + +/** + * An implementation of {@link SpeculationReason} based on encoded values. + */ +public class EncodedSpeculationReason implements SpeculationReason { + final int groupId; + final String groupName; + final Object[] context; + private SpeculationLog.SpeculationReasonEncoding encoding; + + public EncodedSpeculationReason(int groupId, String groupName, Object[] context) { + this.groupId = groupId; + this.groupName = groupName; + this.context = context; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof EncodedSpeculationReason) { + if (obj instanceof EncodedSpeculationReason) { + EncodedSpeculationReason that = (EncodedSpeculationReason) obj; + return this.groupId == that.groupId && Arrays.equals(this.context, that.context); + } + return false; + } + return false; + } + + @Override + public SpeculationLog.SpeculationReasonEncoding encode(Supplier encodingSupplier) { + if (encoding == null) { + encoding = encodingSupplier.get(); + encoding.addInt(groupId); + for (Object o : context) { + if (o == null) { + encoding.addInt(0); + } else { + addNonNullObject(encoding, o); + } + } + } + return encoding; + } + + static void addNonNullObject(SpeculationLog.SpeculationReasonEncoding encoding, Object o) { + Class c = o.getClass(); + if (c == String.class) { + encoding.addString((String) o); + } else if (c == Byte.class) { + encoding.addByte((Byte) o); + } else if (c == Short.class) { + encoding.addShort((Short) o); + } else if (c == Character.class) { + encoding.addShort((Character) o); + } else if (c == Integer.class) { + encoding.addInt((Integer) o); + } else if (c == Long.class) { + encoding.addLong((Long) o); + } else if (c == Float.class) { + encoding.addInt(Float.floatToRawIntBits((Float) o)); + } else if (c == Double.class) { + encoding.addLong(Double.doubleToRawLongBits((Double) o)); + } else if (o instanceof Enum) { + encoding.addInt(((Enum) o).ordinal()); + } else if (o instanceof ResolvedJavaMethod) { + encoding.addMethod((ResolvedJavaMethod) o); + } else if (o instanceof ResolvedJavaType) { + encoding.addType((ResolvedJavaType) o); + } else if (o instanceof ResolvedJavaField) { + encoding.addField((ResolvedJavaField) o); + } else { + throw new IllegalArgumentException("Unsupported type for encoding: " + c.getName()); + } + } + + @Override + public int hashCode() { + return groupId + Arrays.hashCode(this.context); + } + + @Override + public String toString() { + return String.format("%s@%d%s", groupName, groupId, Arrays.toString(context)); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ExceptionHandler.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ExceptionHandler.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ExceptionHandler.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ExceptionHandler.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.util.Objects; + +/** + * Represents an exception handler within the bytecodes. + */ +public final class ExceptionHandler { + + private final int startBCI; + private final int endBCI; + private final int handlerBCI; + private final int catchTypeCPI; + private final JavaType catchType; + + /** + * Creates a new exception handler with the specified ranges. + * + * @param startBCI the start index of the protected range + * @param endBCI the end index of the protected range + * @param catchBCI the index of the handler + * @param catchTypeCPI the index of the throwable class in the constant pool + * @param catchType the type caught by this exception handler + */ + public ExceptionHandler(int startBCI, int endBCI, int catchBCI, int catchTypeCPI, JavaType catchType) { + this.startBCI = startBCI; + this.endBCI = endBCI; + this.handlerBCI = catchBCI; + this.catchTypeCPI = catchTypeCPI; + this.catchType = catchType; + } + + /** + * Returns the start bytecode index of the protected range of this handler. + */ + public int getStartBCI() { + return startBCI; + } + + /** + * Returns the end bytecode index of the protected range of this handler. + */ + public int getEndBCI() { + return endBCI; + } + + /** + * Returns the bytecode index of the handler block of this handler. + */ + public int getHandlerBCI() { + return handlerBCI; + } + + /** + * Returns the index into the constant pool representing the type of exception caught by this + * handler. + */ + public int catchTypeCPI() { + return catchTypeCPI; + } + + /** + * Checks whether this handler catches all exceptions. + * + * @return {@code true} if this handler catches all exceptions + */ + public boolean isCatchAll() { + return catchTypeCPI == 0; + } + + /** + * Returns the type of exception caught by this exception handler. + */ + public JavaType getCatchType() { + return catchType; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ExceptionHandler)) { + return false; + } + ExceptionHandler that = (ExceptionHandler) obj; + if (this.startBCI != that.startBCI || this.endBCI != that.endBCI || this.handlerBCI != that.handlerBCI || this.catchTypeCPI != that.catchTypeCPI) { + return false; + } + return Objects.equals(this.catchType, that.catchType); + } + + @Override + public String toString() { + return "ExceptionHandler"; + } + + @Override + public int hashCode() { + return catchTypeCPI ^ endBCI ^ handlerBCI; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/InvokeTarget.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/InvokeTarget.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/InvokeTarget.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/InvokeTarget.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Represents the resolved target of an invocation. + */ +public interface InvokeTarget { +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.meta; + +/** + * Represents a constant (boxed) value, such as an integer, floating point number, or object + * reference, within the compiler and across the compiler/runtime interface. Exports a set of + * {@code JavaConstant} instances that represent frequently used constant values, such as + * {@link #NULL_POINTER}. + */ +public interface JavaConstant extends Constant, JavaValue { + /* + * Using a larger cache for integers leads to only a slight increase in cache hit ratio which is + * not enough to justify the impact on startup time. + */ + JavaConstant NULL_POINTER = new NullConstant(); + PrimitiveConstant INT_MINUS_1 = new PrimitiveConstant(JavaKind.Int, -1); + PrimitiveConstant INT_0 = new PrimitiveConstant(JavaKind.Int, 0); + PrimitiveConstant INT_1 = new PrimitiveConstant(JavaKind.Int, 1); + PrimitiveConstant INT_2 = new PrimitiveConstant(JavaKind.Int, 2); + PrimitiveConstant LONG_0 = new PrimitiveConstant(JavaKind.Long, 0L); + PrimitiveConstant LONG_1 = new PrimitiveConstant(JavaKind.Long, 1L); + PrimitiveConstant FLOAT_0 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(0.0F)); + PrimitiveConstant FLOAT_1 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(1.0F)); + PrimitiveConstant DOUBLE_0 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(0.0D)); + PrimitiveConstant DOUBLE_1 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(1.0D)); + PrimitiveConstant TRUE = new PrimitiveConstant(JavaKind.Boolean, 1L); + PrimitiveConstant FALSE = new PrimitiveConstant(JavaKind.Boolean, 0L); + PrimitiveConstant ILLEGAL = new PrimitiveConstant(JavaKind.Illegal, 0); + + /** + * Returns the Java kind of this constant. + */ + JavaKind getJavaKind(); + + /** + * Checks whether this constant is null. + * + * @return {@code true} if this constant is the null constant + */ + boolean isNull(); + + static boolean isNull(Constant c) { + if (c instanceof JavaConstant) { + return ((JavaConstant) c).isNull(); + } else { + return false; + } + } + + /** + * Checks whether this constant is non-null. + * + * @return {@code true} if this constant is a primitive, or an object constant that is not null + */ + default boolean isNonNull() { + return !isNull(); + } + + /** + * Checks whether this constant is the default value for its kind (null, 0, 0.0, false). + * + * @return {@code true} if this constant is the default value for its kind + */ + @Override + boolean isDefaultForKind(); + + /** + * Returns the value of this constant as a boxed Java value. + * + * @return the value of this constant + */ + Object asBoxedPrimitive(); + + /** + * Returns the primitive int value this constant represents. The constant must have a + * {@link JavaKind#getStackKind()} of {@link JavaKind#Int}. + * + * @return the constant value + */ + int asInt(); + + /** + * Returns the primitive boolean value this constant represents. The constant must have kind + * {@link JavaKind#Boolean}. + * + * @return the constant value + */ + boolean asBoolean(); + + /** + * Returns the primitive long value this constant represents. The constant must have kind + * {@link JavaKind#Long}, a {@link JavaKind#getStackKind()} of {@link JavaKind#Int}. + * + * @return the constant value + */ + long asLong(); + + /** + * Returns the primitive float value this constant represents. The constant must have kind + * {@link JavaKind#Float}. + * + * @return the constant value + */ + float asFloat(); + + /** + * Returns the primitive double value this constant represents. The constant must have kind + * {@link JavaKind#Double}. + * + * @return the constant value + */ + double asDouble(); + + @Override + default String toValueString() { + if (getJavaKind() == JavaKind.Illegal) { + return "illegal"; + } else { + return getJavaKind().format(asBoxedPrimitive()); + } + } + + static String toString(JavaConstant constant) { + if (constant.getJavaKind() == JavaKind.Illegal) { + return "illegal"; + } else { + return constant.getJavaKind().getJavaName() + "[" + constant.toValueString() + "]"; + } + } + + /** + * Creates a boxed double constant. + * + * @param d the double value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forDouble(double d) { + if (Double.compare(0.0D, d) == 0) { + return DOUBLE_0; + } + if (Double.compare(d, 1.0D) == 0) { + return DOUBLE_1; + } + return new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(d)); + } + + /** + * Creates a boxed float constant. + * + * @param f the float value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forFloat(float f) { + if (Float.compare(f, 0.0F) == 0) { + return FLOAT_0; + } + if (Float.compare(f, 1.0F) == 0) { + return FLOAT_1; + } + return new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(f)); + } + + /** + * Creates a boxed long constant. + * + * @param i the long value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forLong(long i) { + if (i == 0) { + return LONG_0; + } else if (i == 1) { + return LONG_1; + } else { + return new PrimitiveConstant(JavaKind.Long, i); + } + } + + /** + * Creates a boxed integer constant. + * + * @param i the integer value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forInt(int i) { + switch (i) { + case -1: + return INT_MINUS_1; + case 0: + return INT_0; + case 1: + return INT_1; + case 2: + return INT_2; + default: + return new PrimitiveConstant(JavaKind.Int, i); + } + } + + /** + * Creates a boxed byte constant. + * + * @param i the byte value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forByte(byte i) { + return new PrimitiveConstant(JavaKind.Byte, i); + } + + /** + * Creates a boxed boolean constant. + * + * @param i the boolean value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forBoolean(boolean i) { + return i ? TRUE : FALSE; + } + + /** + * Creates a boxed char constant. + * + * @param i the char value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forChar(char i) { + return new PrimitiveConstant(JavaKind.Char, i); + } + + /** + * Creates a boxed short constant. + * + * @param i the short value to box + * @return a boxed copy of {@code value} + */ + static PrimitiveConstant forShort(short i) { + return new PrimitiveConstant(JavaKind.Short, i); + } + + /** + * Creates a {@link JavaConstant} from a primitive integer of a certain kind. + */ + static PrimitiveConstant forIntegerKind(JavaKind kind, long i) { + switch (kind) { + case Boolean: + return forBoolean(i != 0); + case Byte: + return forByte((byte) i); + case Short: + return forShort((short) i); + case Char: + return forChar((char) i); + case Int: + return forInt((int) i); + case Long: + return forLong(i); + default: + throw new IllegalArgumentException("not an integer kind: " + kind); + } + } + + /** + * Creates a {@link JavaConstant} from a primitive integer of a certain width. + */ + static PrimitiveConstant forPrimitiveInt(int bits, long i) { + assert bits <= 64; + switch (bits) { + case 1: + return forBoolean(i != 0); + case 8: + return forByte((byte) i); + case 16: + return forShort((short) i); + case 32: + return forInt((int) i); + case 64: + return forLong(i); + default: + throw new IllegalArgumentException("unsupported integer width: " + bits); + } + } + + static PrimitiveConstant forPrimitive(JavaKind kind, long rawValue) { + switch (kind) { + case Boolean: + return JavaConstant.forBoolean(rawValue != 0); + case Byte: + return JavaConstant.forByte((byte) rawValue); + case Char: + return JavaConstant.forChar((char) rawValue); + case Short: + return JavaConstant.forShort((short) rawValue); + case Int: + return JavaConstant.forInt((int) rawValue); + case Long: + return JavaConstant.forLong(rawValue); + case Float: + return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue)); + case Double: + return JavaConstant.forDouble(Double.longBitsToDouble(rawValue)); + default: + throw new IllegalArgumentException("Unsupported kind: " + kind); + } + } + + /** + * Creates a boxed constant for the given boxed primitive value. + * + * @param value the Java boxed value + * @return the primitive constant holding the {@code value} + */ + static PrimitiveConstant forBoxedPrimitive(Object value) { + if (value instanceof Boolean) { + return forBoolean((Boolean) value); + } else if (value instanceof Byte) { + return forByte((Byte) value); + } else if (value instanceof Character) { + return forChar((Character) value); + } else if (value instanceof Short) { + return forShort((Short) value); + } else if (value instanceof Integer) { + return forInt((Integer) value); + } else if (value instanceof Long) { + return forLong((Long) value); + } else if (value instanceof Float) { + return forFloat((Float) value); + } else if (value instanceof Double) { + return forDouble((Double) value); + } else { + return null; + } + } + + static PrimitiveConstant forIllegal() { + return JavaConstant.ILLEGAL; + } + + /** + * Returns a constant with the default value for the given kind. + */ + static JavaConstant defaultForKind(JavaKind kind) { + switch (kind) { + case Boolean: + return FALSE; + case Byte: + return forByte((byte) 0); + case Char: + return forChar((char) 0); + case Short: + return forShort((short) 0); + case Int: + return INT_0; + case Double: + return DOUBLE_0; + case Float: + return FLOAT_0; + case Long: + return LONG_0; + case Object: + return NULL_POINTER; + default: + throw new IllegalArgumentException(kind.toString()); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaField.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaField.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.util.IllegalFormatException; +import java.util.UnknownFormatConversionException; + +/** + * Represents a reference to a Java field, either resolved or unresolved fields. Fields, like + * methods and types, are resolved through {@link ConstantPool constant pools}. + */ +public interface JavaField { + + /** + * Returns the name of this field. + */ + String getName(); + + /** + * Returns a {@link JavaType} object that identifies the declared type for this field. + */ + JavaType getType(); + + /** + * Returns the kind of this field. This is the same as calling {@link #getType}. + * {@link JavaType#getJavaKind getJavaKind}. + */ + default JavaKind getJavaKind() { + return getType().getJavaKind(); + } + + /** + * Returns the {@link JavaType} object representing the class or interface that declares this + * field. + */ + JavaType getDeclaringClass(); + + /** + * Gets a string for this field formatted according to a given format specification. A format + * specification is composed of characters that are to be copied verbatim to the result and + * specifiers that denote an attribute of this field that is to be copied to the result. A + * specifier is a single character preceded by a '%' character. The accepted specifiers and the + * field attributes they denote are described below: + * + *
    +     *     Specifier | Description                                          | Example(s)
    +     *     ----------+------------------------------------------------------------------------------------------
    +     *     'T'       | Qualified type                                       | "int" "java.lang.String"
    +     *     't'       | Unqualified type                                     | "int" "String"
    +     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
    +     *     'h'       | Unqualified holder                                   | "Entry"
    +     *     'n'       | Field name                                           | "age"
    +     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
    +     *     '%'       | A '%' character                                      | "%"
    +     * 
    + * + * @param format a format specification + * @return the result of formatting this field according to {@code format} + * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} + */ + default String format(String format) throws IllegalFormatException { + StringBuilder sb = new StringBuilder(); + int index = 0; + JavaType type = getType(); + while (index < format.length()) { + char ch = format.charAt(index++); + if (ch == '%') { + if (index >= format.length()) { + throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification"); + } + char specifier = format.charAt(index++); + switch (specifier) { + case 'T': + case 't': { + sb.append(type.toJavaName(specifier == 'T')); + break; + } + case 'H': + case 'h': { + sb.append(getDeclaringClass().toJavaName(specifier == 'H')); + break; + } + case 'n': { + sb.append(getName()); + break; + } + case 'f': { + sb.append(!(this instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) this).isStatic() ? "static" : "instance"); + break; + } + case '%': { + sb.append('%'); + break; + } + default: { + throw new UnknownFormatConversionException(String.valueOf(specifier)); + } + } + } else { + sb.append(ch); + } + } + return sb.toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaKind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaKind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaKind.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaKind.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.meta; + +import java.lang.reflect.Array; + +//JaCoCo Exclude + +/** + * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example, + * {@link JavaKind#Int} for {@code int} and {@link JavaKind#Object} for all object types. A kind has + * a single character short name, a Java name, and a set of flags further describing its behavior. + */ +public enum JavaKind { + /** The primitive boolean kind, represented as an int on the stack. */ + Boolean('Z', 4, "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class), + + /** The primitive byte kind, represented as an int on the stack. */ + Byte('B', 8, "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class), + + /** The primitive short kind, represented as an int on the stack. */ + Short('S', 9, "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class), + + /** The primitive char kind, represented as an int on the stack. */ + Char('C', 5, "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class), + + /** The primitive int kind, represented as an int on the stack. */ + Int('I', 10, "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class), + + /** The primitive float kind. */ + Float('F', 6, "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class), + + /** The primitive long kind. */ + Long('J', 11, "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class), + + /** The primitive double kind. */ + Double('D', 7, "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class), + + /** The Object kind, also used for arrays. */ + Object('A', 12, "Object", 1, false, null, null), + + /** The void kind. */ + Void('V', 14, "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class), + + /** The non-type. */ + Illegal('-', 99, "illegal", 0, false, null, null); + + private final char typeChar; + private final String javaName; + private final boolean isStackInt; + private final Class primitiveJavaClass; + private final Class boxedJavaClass; + private final int slotCount; + private final int basicType; + + JavaKind(char typeChar, int basicType, String javaName, int slotCount, boolean isStackInt, Class primitiveJavaClass, Class boxedJavaClass) { + this.typeChar = typeChar; + this.javaName = javaName; + this.slotCount = slotCount; + this.isStackInt = isStackInt; + this.primitiveJavaClass = primitiveJavaClass; + this.boxedJavaClass = boxedJavaClass; + this.basicType = basicType; + assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName()); + } + + /** + * Returns the number of stack slots occupied by this kind according to the Java bytecodes + * specification. + */ + public int getSlotCount() { + return this.slotCount; + } + + /** + * Returns whether this kind occupied two stack slots. + */ + public boolean needsTwoSlots() { + return this.slotCount == 2; + } + + /** + * Returns the name of the kind as a single upper case character. For the void and primitive + * kinds, this is the FieldType term in + * + * table 4.3-A of the JVM Specification. For {@link #Object}, the character {@code 'A'} is + * returned and for {@link #Illegal}, {@code '-'} is returned. + */ + public char getTypeChar() { + return typeChar; + } + + /** + * Returns the JVM BasicType value for this type. + */ + public int getBasicType() { + return basicType; + } + + /** + * Returns the name of this kind which will also be it Java programming language name if it is + * {@linkplain #isPrimitive() primitive} or {@code void}. + */ + public String getJavaName() { + return javaName; + } + + /** + * Checks whether this type is a Java primitive type. + * + * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, + * {@link #Short}, {@link #Int}, {@link #Long}, {@link #Float}, {@link #Double}, or + * {@link #Void}. + */ + public boolean isPrimitive() { + return primitiveJavaClass != null; + } + + /** + * Returns the kind that represents this kind when on the Java operand stack. + * + * @return the kind used on the operand stack + */ + public JavaKind getStackKind() { + if (isStackInt) { + return Int; + } + return this; + } + + /** + * Checks whether this type is a Java primitive type representing an integer number. + * + * @return {@code true} if the stack kind is {@link #Int} or {@link #Long}. + */ + public boolean isNumericInteger() { + return isStackInt || this == JavaKind.Long; + } + + /** + * Checks whether this type is a Java primitive type representing an unsigned number. + * + * @return {@code true} if the kind is {@link #Boolean} or {@link #Char}. + */ + public boolean isUnsigned() { + return this == JavaKind.Boolean || this == JavaKind.Char; + } + + /** + * Checks whether this type is a Java primitive type representing a floating point number. + * + * @return {@code true} if this is {@link #Float} or {@link #Double}. + */ + public boolean isNumericFloat() { + return this == JavaKind.Float || this == JavaKind.Double; + } + + /** + * Checks whether this represent an Object of some sort. + * + * @return {@code true} if this is {@link #Object}. + */ + public boolean isObject() { + return this == JavaKind.Object; + } + + /** + * Returns the kind corresponding to the Java type string. + * + * @param typeString the Java type string + * @return the kind + */ + public static JavaKind fromTypeString(String typeString) { + assert typeString.length() > 0; + final char first = typeString.charAt(0); + if (first == '[' || first == 'L') { + return JavaKind.Object; + } + return JavaKind.fromPrimitiveOrVoidTypeChar(first); + } + + /** + * Returns the kind of a word given the size of a word in bytes. + * + * @param wordSizeInBytes the size of a word in bytes + * @return the kind representing a word value + */ + public static JavaKind fromWordSize(int wordSizeInBytes) { + if (wordSizeInBytes == 8) { + return JavaKind.Long; + } else { + assert wordSizeInBytes == 4 : "Unsupported word size!"; + return JavaKind.Int; + } + } + + /** + * Returns the kind from the character describing a primitive or void. + * + * @param ch the character for a void or primitive kind as returned by {@link #getTypeChar()} + * @return the kind + */ + public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) { + switch (ch) { + case 'Z': + return Boolean; + case 'C': + return Char; + case 'F': + return Float; + case 'D': + return Double; + case 'B': + return Byte; + case 'S': + return Short; + case 'I': + return Int; + case 'J': + return Long; + case 'V': + return Void; + } + throw new IllegalArgumentException("unknown primitive or void type character: " + ch); + } + + /** + * Returns the Kind representing the given Java class. + * + * @param klass the class + * @return the kind + */ + public static JavaKind fromJavaClass(Class klass) { + if (klass == Boolean.primitiveJavaClass) { + return Boolean; + } else if (klass == Byte.primitiveJavaClass) { + return Byte; + } else if (klass == Short.primitiveJavaClass) { + return Short; + } else if (klass == Char.primitiveJavaClass) { + return Char; + } else if (klass == Int.primitiveJavaClass) { + return Int; + } else if (klass == Long.primitiveJavaClass) { + return Long; + } else if (klass == Float.primitiveJavaClass) { + return Float; + } else if (klass == Double.primitiveJavaClass) { + return Double; + } else if (klass == Void.primitiveJavaClass) { + return Void; + } else { + return Object; + } + } + + /** + * Returns the Java class representing this kind. + * + * @return the Java class + */ + public Class toJavaClass() { + return primitiveJavaClass; + } + + /** + * Returns the Java class for instances of boxed values of this kind. + * + * @return the Java class + */ + public Class toBoxedJavaClass() { + return boxedJavaClass; + } + + /** + * Converts this value type to a string. + */ + @Override + public String toString() { + return javaName; + } + + /** + * Marker interface for types that should be {@linkplain JavaKind#format(Object) formatted} with + * their {@link Object#toString()} value. Calling {@link Object#toString()} on other objects + * poses a security risk because it can potentially call user code. + */ + public interface FormatWithToString { + } + + /** + * Classes for which invoking {@link Object#toString()} does not run user code. + */ + private static boolean isToStringSafe(Class c) { + return c == Boolean.class || c == Byte.class || c == Character.class || c == Short.class || c == Integer.class || c == Float.class || c == Long.class || c == Double.class; + } + + /** + * Gets a formatted string for a given value of this kind. + * + * @param value a value of this kind + * @return a formatted string for {@code value} based on this kind + */ + public String format(Object value) { + if (isPrimitive()) { + assert isToStringSafe(value.getClass()); + return value.toString(); + } else { + if (value == null) { + return "null"; + } else { + if (value instanceof String) { + String s = (String) value; + if (s.length() > 50) { + return "String:\"" + s.substring(0, 30) + "...\""; + } else { + return "String:\"" + s + '"'; + } + } else if (value instanceof JavaType) { + return "JavaType:" + ((JavaType) value).toJavaName(); + } else if (value instanceof Enum) { + return MetaUtil.getSimpleName(value.getClass(), true) + ":" + ((Enum) value).name(); + } else if (value instanceof FormatWithToString) { + return MetaUtil.getSimpleName(value.getClass(), true) + ":" + String.valueOf(value); + } else if (value instanceof Class) { + return "Class:" + ((Class) value).getName(); + } else if (isToStringSafe(value.getClass())) { + return value.toString(); + } else if (value.getClass().isArray()) { + return formatArray(value); + } else { + return MetaUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value); + } + } + } + } + + private static final int MAX_FORMAT_ARRAY_LENGTH = 5; + + private static String formatArray(Object array) { + Class componentType = array.getClass().getComponentType(); + assert componentType != null; + int arrayLength = Array.getLength(array); + StringBuilder buf = new StringBuilder(MetaUtil.getSimpleName(componentType, true)).append('[').append(arrayLength).append("]{"); + int length = Math.min(MAX_FORMAT_ARRAY_LENGTH, arrayLength); + boolean primitive = componentType.isPrimitive(); + for (int i = 0; i < length; i++) { + if (primitive) { + buf.append(Array.get(array, i)); + } else { + Object o = ((Object[]) array)[i]; + buf.append(JavaKind.Object.format(o)); + } + if (i != length - 1) { + buf.append(", "); + } + } + if (arrayLength != length) { + buf.append(", ..."); + } + return buf.append('}').toString(); + } + + /** + * Gets the minimum value that can be represented as a value of this kind. + * + * @return the minimum value represented as a {@code long} + */ + public long getMinValue() { + switch (this) { + case Boolean: + return 0; + case Byte: + return java.lang.Byte.MIN_VALUE; + case Char: + return java.lang.Character.MIN_VALUE; + case Short: + return java.lang.Short.MIN_VALUE; + case Int: + return java.lang.Integer.MIN_VALUE; + case Long: + return java.lang.Long.MIN_VALUE; + case Float: + return java.lang.Float.floatToRawIntBits(java.lang.Float.MIN_VALUE); + case Double: + return java.lang.Double.doubleToRawLongBits(java.lang.Double.MIN_VALUE); + default: + throw new IllegalArgumentException("illegal call to minValue on " + this); + } + } + + /** + * Gets the maximum value that can be represented as a value of this kind. + * + * @return the maximum value represented as a {@code long} + */ + public long getMaxValue() { + switch (this) { + case Boolean: + return 1; + case Byte: + return java.lang.Byte.MAX_VALUE; + case Char: + return java.lang.Character.MAX_VALUE; + case Short: + return java.lang.Short.MAX_VALUE; + case Int: + return java.lang.Integer.MAX_VALUE; + case Long: + return java.lang.Long.MAX_VALUE; + case Float: + return java.lang.Float.floatToRawIntBits(java.lang.Float.MAX_VALUE); + case Double: + return java.lang.Double.doubleToRawLongBits(java.lang.Double.MAX_VALUE); + default: + throw new IllegalArgumentException("illegal call to maxValue on " + this); + } + } + + /** + * Number of bytes that are necessary to represent a value of this kind. + * + * @return the number of bytes + */ + public int getByteCount() { + if (this == Boolean) { + return 1; + } else { + return getBitCount() >> 3; + } + } + + /** + * Number of bits that are necessary to represent a value of this kind. + * + * @return the number of bits + */ + public int getBitCount() { + switch (this) { + case Boolean: + return 1; + case Byte: + return 8; + case Char: + case Short: + return 16; + case Float: + return 32; + case Int: + return 32; + case Double: + return 64; + case Long: + return 64; + default: + throw new IllegalArgumentException("illegal call to getBitCount() on " + this); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.util.IllegalFormatException; +import java.util.UnknownFormatConversionException; + +/** + * Represents a reference to a Java method, either resolved or unresolved. Methods, like fields and + * types, are resolved through {@link ConstantPool constant pools}. + */ +public interface JavaMethod { + + /** + * Returns the name of this method. + */ + String getName(); + + /** + * Returns the {@link JavaType} object representing the class or interface that declares this + * method. + */ + JavaType getDeclaringClass(); + + /** + * Returns the signature of this method. + */ + Signature getSignature(); + + /** + * Gets a string for this method formatted according to a given format specification. A format + * specification is composed of characters that are to be copied verbatim to the result and + * specifiers that denote an attribute of this method that is to be copied to the result. A + * specifier is a single character preceded by a '%' character. The accepted specifiers and the + * method attributes they denote are described below: + * + *
    +     *     Specifier | Description                                          | Example(s)
    +     *     ----------+------------------------------------------------------------------------------------------
    +     *     'R'       | Qualified return type                                | "int" "java.lang.String"
    +     *     'r'       | Unqualified return type                              | "int" "String"
    +     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
    +     *     'h'       | Unqualified holder                                   | "Entry"
    +     *     'n'       | Method name                                          | "add"
    +     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
    +     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
    +     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
    +     *     '%'       | A '%' character                                      | "%"
    +     * 
    + * + * @param format a format specification + * @return the result of formatting this method according to {@code format} + * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} + */ + default String format(String format) throws IllegalFormatException { + StringBuilder sb = new StringBuilder(); + int index = 0; + Signature sig = null; + while (index < format.length()) { + char ch = format.charAt(index++); + if (ch == '%') { + if (index >= format.length()) { + throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification"); + } + char specifier = format.charAt(index++); + switch (specifier) { + case 'R': + case 'r': { + if (sig == null) { + sig = getSignature(); + } + sb.append(sig.getReturnType(null).toJavaName(specifier == 'R')); + break; + } + case 'H': + case 'h': { + sb.append(getDeclaringClass().toJavaName(specifier == 'H')); + break; + } + case 'n': { + sb.append(getName()); + break; + } + case 'P': + case 'p': { + if (sig == null) { + sig = getSignature(); + } + for (int i = 0; i < sig.getParameterCount(false); i++) { + if (i != 0) { + sb.append(", "); + } + sb.append(sig.getParameterType(i, null).toJavaName(specifier == 'P')); + } + break; + } + case 'f': { + sb.append(!(this instanceof ResolvedJavaMethod) ? "unresolved" : ((ResolvedJavaMethod) this).isStatic() ? "static" : "virtual"); + break; + } + case '%': { + sb.append('%'); + break; + } + default: { + throw new UnknownFormatConversionException(String.valueOf(specifier)); + } + } + } else { + sb.append(ch); + } + } + return sb.toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethodProfile.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethodProfile.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethodProfile.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaMethodProfile.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod; + +/** + * This profile object represents the method profile at a specific BCI. The precision of the + * supplied values may vary, but a runtime that provides this information should be aware that it + * will be used to guide performance-critical decisions like speculative inlining, etc. + */ +public final class JavaMethodProfile extends AbstractJavaProfile { + + public JavaMethodProfile(double notRecordedProbability, ProfiledMethod[] pitems) { + super(notRecordedProbability, pitems); + } + + public ProfiledMethod[] getMethods() { + return super.getItems(); + } + + public static class ProfiledMethod extends AbstractProfiledItem { + + public ProfiledMethod(ResolvedJavaMethod method, double probability) { + super(method, probability); + } + + /** + * Returns the type for this profile entry. + */ + public ResolvedJavaMethod getMethod() { + return getItem(); + } + + @Override + public String toString() { + return "{" + item.getName() + ", " + probability + "}"; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import static jdk.vm.ci.meta.MetaUtil.internalNameToJava; + +/** + * Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and + * arrays thereof. + */ +public interface JavaType { + + /** + * Returns the name of this type in internal form. The following are examples of strings + * returned by this method: + * + *
    +     *     "Ljava/lang/Object;"
    +     *     "I"
    +     *     "[[B"
    +     * 
    + */ + String getName(); + + /** + * Returns an unqualified name of this type. + * + *
    +     *     "Object"
    +     *     "Integer"
    +     * 
    + */ + default String getUnqualifiedName() { + String name = getName(); + if (name.indexOf('/') != -1) { + name = name.substring(name.lastIndexOf('/') + 1); + } + if (name.endsWith(";")) { + name = name.substring(0, name.length() - 1); + } + return name; + } + + /** + * Checks whether this type is an array class. + * + * @return {@code true} if this type is an array class + */ + default boolean isArray() { + return getComponentType() != null; + } + + /** + * For array types, gets the type of the components, or {@code null} if this is not an array + * type. This method is analogous to {@link Class#getComponentType()}. + */ + JavaType getComponentType(); + + /** + * Gets the elemental type for this given type. The elemental type is the corresponding zero + * dimensional type of an array type. For example, the elemental type of {@code int[][][]} is + * {@code int}. A non-array type is its own elemental type. + */ + default JavaType getElementalType() { + JavaType t = this; + while (t.getComponentType() != null) { + t = t.getComponentType(); + } + return t; + } + + /** + * Gets the array class type representing an array with elements of this type. + */ + JavaType getArrayClass(); + + /** + * Gets the {@link JavaKind} of this type. + */ + JavaKind getJavaKind(); + + /** + * Resolves this type to a {@link ResolvedJavaType}. + * + * @param accessingClass the context of resolution (must not be null) + * @return the resolved Java type + * @throws LinkageError if the resolution failed + * @throws NullPointerException if {@code accessingClass} is {@code null} + */ + ResolvedJavaType resolve(ResolvedJavaType accessingClass); + + /** + * Gets the Java programming language name for this type. The following are examples of strings + * returned by this method: + * + *
    +     *      java.lang.Object
    +     *      int
    +     *      boolean[][]
    +     * 
    + * + * @return the Java name corresponding to this type + */ + default String toJavaName() { + return internalNameToJava(getName(), true, false); + } + + /** + * Gets the Java programming language name for this type. The following are examples of strings + * returned by this method: + * + *
    +     *     qualified == true:
    +     *         java.lang.Object
    +     *         int
    +     *         boolean[][]
    +     *     qualified == false:
    +     *         Object
    +     *         int
    +     *         boolean[][]
    +     * 
    + * + * @param qualified specifies if the package prefix of this type should be included in the + * returned name + * @return the Java name corresponding to this type + */ + default String toJavaName(boolean qualified) { + JavaKind kind = getJavaKind(); + if (kind == JavaKind.Object) { + return internalNameToJava(getName(), qualified, false); + } + return getJavaKind().getJavaName(); + } + + /** + * Returns this type's name in the same format as {@link Class#getName()}. + */ + default String toClassName() { + return internalNameToJava(getName(), true, true); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaTypeProfile.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaTypeProfile.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaTypeProfile.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaTypeProfile.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2011, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.reflect.Modifier; +import java.util.ArrayList; + +import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType; + +/** + * This profile object represents the type profile at a specific BCI. The precision of the supplied + * values may vary, but a runtime that provides this information should be aware that it will be + * used to guide performance-critical decisions like speculative inlining, etc. + */ +public final class JavaTypeProfile extends AbstractJavaProfile { + + private static final ProfiledType[] EMPTY_ARRAY = new ProfiledType[0]; + + private final TriState nullSeen; + + public JavaTypeProfile(TriState nullSeen, double notRecordedProbability, ProfiledType[] pitems) { + super(notRecordedProbability, pitems); + this.nullSeen = nullSeen; + } + + /** + * Returns whether a null value was at the type check. + */ + public TriState getNullSeen() { + return nullSeen; + } + + /** + * A list of types for which the runtime has recorded probability information. Note that this + * includes both positive and negative types where a positive type is a subtype of the checked + * type and a negative type is not. + */ + public ProfiledType[] getTypes() { + return getItems(); + } + + public JavaTypeProfile restrict(JavaTypeProfile otherProfile) { + if (otherProfile.getNotRecordedProbability() > 0.0) { + // Not useful for restricting since there is an unknown set of types occurring. + return this; + } + + if (this.getNotRecordedProbability() > 0.0) { + // We are unrestricted, so the other profile is always a better estimate. + return otherProfile; + } + + ArrayList result = new ArrayList<>(); + for (int i = 0; i < getItems().length; i++) { + ProfiledType ptype = getItems()[i]; + ResolvedJavaType type = ptype.getItem(); + if (otherProfile.isIncluded(type)) { + result.add(ptype); + } + } + + TriState newNullSeen = (otherProfile.getNullSeen() == TriState.FALSE) ? TriState.FALSE : getNullSeen(); + double newNotRecorded = getNotRecordedProbability(); + return createAdjustedProfile(result, newNullSeen, newNotRecorded); + } + + public JavaTypeProfile restrict(ResolvedJavaType declaredType, boolean nonNull) { + ArrayList result = new ArrayList<>(); + for (int i = 0; i < getItems().length; i++) { + ProfiledType ptype = getItems()[i]; + ResolvedJavaType type = ptype.getItem(); + if (declaredType.isAssignableFrom(type)) { + result.add(ptype); + } + } + + TriState newNullSeen = (nonNull) ? TriState.FALSE : getNullSeen(); + double newNotRecorded = this.getNotRecordedProbability(); + // Assume for the types not recorded, the incompatibility rate is the same. + if (getItems().length != 0) { + newNotRecorded *= ((double) result.size() / (double) getItems().length); + } + return createAdjustedProfile(result, newNullSeen, newNotRecorded); + } + + private JavaTypeProfile createAdjustedProfile(ArrayList result, TriState newNullSeen, double newNotRecorded) { + if (result.size() != this.getItems().length || newNotRecorded != getNotRecordedProbability() || newNullSeen != getNullSeen()) { + if (result.size() == 0) { + return new JavaTypeProfile(newNullSeen, 1.0, EMPTY_ARRAY); + } + double factor; + if (result.size() == this.getItems().length) { + /* List of types did not change, no need to recompute probabilities. */ + factor = 1.0; + } else { + double probabilitySum = 0.0; + for (int i = 0; i < result.size(); i++) { + probabilitySum += result.get(i).getProbability(); + } + probabilitySum += newNotRecorded; + + factor = 1.0 / probabilitySum; // Normalize to 1.0 + assert factor >= 1.0; + } + ProfiledType[] newResult = new ProfiledType[result.size()]; + for (int i = 0; i < newResult.length; ++i) { + ProfiledType curType = result.get(i); + newResult[i] = new ProfiledType(curType.getItem(), Math.min(1.0, curType.getProbability() * factor)); + } + double newNotRecordedTypeProbability = Math.min(1.0, newNotRecorded * factor); + return new JavaTypeProfile(newNullSeen, newNotRecordedTypeProbability, newResult); + } + return this; + } + + @Override + public boolean equals(Object other) { + return super.equals(other) && nullSeen.equals(((JavaTypeProfile) other).nullSeen); + } + + @Override + public int hashCode() { + return nullSeen.hashCode() + super.hashCode(); + } + + public static class ProfiledType extends AbstractProfiledItem { + + public ProfiledType(ResolvedJavaType type, double probability) { + super(type, probability); + assert type.isArray() || type.isConcrete() : type + " " + Modifier.toString(type.getModifiers()); + } + + /** + * Returns the type for this profile entry. + */ + public ResolvedJavaType getType() { + return getItem(); + } + + @Override + public String toString() { + return String.format("%.6f#%s", probability, item); + } + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("JavaTypeProfile", getNotRecordedProbability())).toString(); + } + + /** + * Returns {@code true} if all types seen at this location have been recorded in the profile. + */ + public boolean allTypesRecorded() { + return this.getNotRecordedProbability() == 0.0; + } + + /** + * Returns the single monormorphic type representing this profile or {@code null} if no such + * type exists. + */ + public ResolvedJavaType asSingleType() { + if (allTypesRecorded() && this.getTypes().length == 1) { + return getTypes()[0].getType(); + } + return null; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaValue.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/JavaValue.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014, 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. + */ +package jdk.vm.ci.meta; + +/** + * Marker interface for things that represent a Java value. + */ +public interface JavaValue { +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LineNumberTable.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LineNumberTable.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LineNumberTable.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LineNumberTable.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Maps bytecode indexes to source line numbers. + * + * @see "https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.12" + */ +public class LineNumberTable { + + private final int[] lineNumbers; + private final int[] bcis; + + /** + * + * @param lineNumbers an array of source line numbers. This array is now owned by this object + * and should not be mutated by the caller. + * @param bcis an array of bytecode indexes the same length at {@code lineNumbers} whose entries + * are sorted in ascending order. This array is now owned by this object and must not + * be mutated by the caller. + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `lineNumbers` and `bcis`") + public LineNumberTable(int[] lineNumbers, int[] bcis) { + assert bcis.length == lineNumbers.length; + this.lineNumbers = lineNumbers; + this.bcis = bcis; + } + + /** + * Gets a source line number for bytecode index {@code atBci}. + */ + public int getLineNumber(int atBci) { + for (int i = 0; i < this.bcis.length - 1; i++) { + if (this.bcis[i] <= atBci && atBci < this.bcis[i + 1]) { + return lineNumbers[i]; + } + } + return lineNumbers[lineNumbers.length - 1]; + } + + /** + * Gets a copy of the array of line numbers that was passed to this object's constructor. + */ + public int[] getLineNumbers() { + return lineNumbers.clone(); + } + + /** + * Gets a copy of the array of bytecode indexes that was passed to this object's constructor. + */ + public int[] getBcis() { + return bcis.clone(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Local.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Local.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Local.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Local.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Describes the type and bytecode index range in which a local variable is live. + */ +public class Local { + + private final String name; + private final int startBci; + private final int endBci; + private final int slot; + private final JavaType type; + + public Local(String name, JavaType type, int startBci, int endBci, int slot) { + this.name = name; + this.startBci = startBci; + this.endBci = endBci; + this.slot = slot; + this.type = type; + } + + public int getStartBCI() { + return startBci; + } + + public int getEndBCI() { + return endBci; + } + + public String getName() { + return name; + } + + public JavaType getType() { + return type; + } + + public int getSlot() { + return slot; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Local)) { + return false; + } + Local that = (Local) obj; + return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public String toString() { + return "LocalImpl"; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LocalVariableTable.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LocalVariableTable.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LocalVariableTable.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/LocalVariableTable.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.util.ArrayList; +import java.util.List; + +/** + * Describes the {@link Local}s for a Java method. + * + * @see "https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.13" + */ +public class LocalVariableTable { + + private final Local[] locals; + + /** + * Creates an object describing the {@link Local}s for a Java method. + * + * @param locals array of objects describing local variables. This array is now owned by this + * object and must not be mutated by the caller. + */ + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `locals`") + public LocalVariableTable(Local[] locals) { + this.locals = locals; + } + + /** + * Gets a description of a local variable that occupies the bytecode frame slot indexed by + * {@code slot} and is live at the bytecode index {@code bci}. + * + * @return a description of the requested local variable or null if no such variable matches + * {@code slot} and {@code bci} + */ + public Local getLocal(int slot, int bci) { + Local result = null; + for (Local local : locals) { + if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) { + if (result == null) { + result = local; + } else { + throw new IllegalStateException("Locals overlap!"); + } + } + } + return result; + } + + /** + * Gets a copy of the array of {@link Local}s that was passed to this object's constructor. + */ + public Local[] getLocals() { + return locals.clone(); + } + + /** + * Gets a description of all the local variables live at the bytecode index {@code bci}. + */ + public Local[] getLocalsAt(int bci) { + List result = new ArrayList<>(); + for (Local l : locals) { + if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) { + result.add(l); + } + } + return result.toArray(new Local[result.size()]); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MemoryAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MemoryAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MemoryAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MemoryAccessProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012, 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. + */ +package jdk.vm.ci.meta; + +/** + * Provides memory access operations for the target VM. + */ +public interface MemoryAccessProvider { + + /** + * Reads a primitive value using a base address and a displacement. + * + * @param kind the {@link JavaKind} of the returned {@link JavaConstant} object + * @param base the base address from which the value is read + * @param displacement the displacement within the object in bytes + * @param bits the number of bits to read from memory + * @return the read value encapsulated in a {@link JavaConstant} object of {@link JavaKind} kind + * @throws IllegalArgumentException if the read is out of bounds of the object or {@code kind} + * is {@link JavaKind#Void} or not {@linkplain JavaKind#isPrimitive() primitive} + * kind or {@code bits} is not 8, 16, 32 or 64, or the read is unaligned + */ + JavaConstant readPrimitiveConstant(JavaKind kind, Constant base, long displacement, int bits) throws IllegalArgumentException; + + /** + * Reads a Java {@link Object} value using a base address and a displacement. + * + * @param base the base address from which the value is read + * @param displacement the displacement within the object in bytes + * @return the read value encapsulated in a {@link Constant} object + * @throws IllegalArgumentException if the address computed from {@code base} and + * {@code displacement} does not denote a location holding an {@code Object} value + */ + JavaConstant readObjectConstant(Constant base, long displacement); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaAccessProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import jdk.vm.ci.meta.SpeculationLog.Speculation; + +/** + * Provides access to the metadata of a class typically provided in a class file. + */ +public interface MetaAccessProvider { + + /** + * Returns the resolved Java type representing a given Java class. + * + * @param clazz the Java class object + * @return the resolved Java type object + */ + ResolvedJavaType lookupJavaType(Class clazz); + + /** + * Returns the resolved Java types representing some given Java classes. + * + * @param classes the Java class objects + * @return the resolved Java type objects + */ + default ResolvedJavaType[] lookupJavaTypes(Class[] classes) { + ResolvedJavaType[] result = new ResolvedJavaType[classes.length]; + for (int i = 0; i < result.length; i++) { + result[i] = lookupJavaType(classes[i]); + } + return result; + } + + /** + * Provides the {@link ResolvedJavaMethod} for a {@link Method} or {@link Constructor} obtained + * via reflection. + */ + ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod); + + /** + * Provides the {@link ResolvedJavaField} for a {@link Field} obtained via reflection. + */ + ResolvedJavaField lookupJavaField(Field reflectionField); + + /** + * Returns the resolved Java type of the given {@link JavaConstant} object. + * + * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()} + */ + ResolvedJavaType lookupJavaType(JavaConstant constant); + + /** + * Returns the number of bytes occupied by this constant value or constant object. + * + * @param constant the constant whose bytes should be measured + * @return the number of bytes occupied by this constant + */ + long getMemorySize(JavaConstant constant); + + /** + * Parses a + * method + * descriptor into a {@link Signature}. + * + * @throws IllegalArgumentException if the method descriptor is not well formed + */ + Signature parseMethodDescriptor(String methodDescriptor); + + /** + * Encodes a deoptimization action and a deoptimization reason in an integer value. + * + * @param debugId an integer that can be used to track the origin of a deoptimization at + * runtime. There is no guarantee that the runtime will use this value. The runtime + * may even keep fewer than 32 bits. + * + * @return the encoded value as an integer + */ + JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId); + + /** + * Gets a constant that denotes {@code speculation}. The constant can passed to the + * deoptimization handler (e.g., through a thread local) to indicate a failed speculation. + */ + JavaConstant encodeSpeculation(Speculation speculation); + + /** + * Decodes {@code constant} back to a {@link Speculation} object. + * + * @throws IllegalArgumentException if {@code constant} can only be decoded through a + * {@link SpeculationLog} and {@code speculationLog} does not contain the + * speculation denoted by {@code constant} + */ + Speculation decodeSpeculation(JavaConstant constant, SpeculationLog speculationLog); + + DeoptimizationReason decodeDeoptReason(JavaConstant constant); + + DeoptimizationAction decodeDeoptAction(JavaConstant constant); + + int decodeDebugId(JavaConstant constant); + + int getArrayBaseOffset(JavaKind elementKind); + + int getArrayIndexScale(JavaKind elementKind); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaUtil.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaUtil.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MetaUtil.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients. + */ +public class MetaUtil { + + public static final char PACKAGE_SEPARATOR_INTERNAL = '/'; + public static final char HIDDEN_SEPARATOR_INTERNAL = '.'; + public static final char PACKAGE_SEPARATOR_JAVA = HIDDEN_SEPARATOR_INTERNAL; + public static final char HIDDEN_SEPARATOR_JAVA = PACKAGE_SEPARATOR_INTERNAL; + + /** + * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for + * anonymous and local classes. + * + * @param clazz the class for which the simple name is being requested + * @param withEnclosingClass specifies if the returned name should be qualified with the name(s) + * of the enclosing class/classes of {@code clazz} (if any). This option is ignored + * if {@code clazz} denotes an anonymous or local class. + * @return the simple name + */ + public static String getSimpleName(Class clazz, boolean withEnclosingClass) { + final String simpleName = safeSimpleName(clazz); + if (simpleName.length() != 0) { + if (withEnclosingClass) { + String prefix = ""; + Class enclosingClass = clazz; + while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) { + prefix = safeSimpleName(enclosingClass) + "." + prefix; + } + return prefix + simpleName; + } + return simpleName; + } + // Must be an anonymous or local class + final String name = clazz.getName(); + int index = name.indexOf('$'); + if (index == -1) { + return name; + } + index = name.lastIndexOf('.', index); + if (index == -1) { + return name; + } + return name.substring(index + 1); + } + + private static String safeSimpleName(Class clazz) { + try { + return clazz.getSimpleName(); + } catch (InternalError e) { + // Scala inner class names do not always start with '$', + // causing Class.getSimpleName to throw an InternalError + Class enclosingClass = clazz.getEnclosingClass(); + String fqn = clazz.getName(); + if (enclosingClass == null) { + // Should never happen given logic in + // Class.getSimpleName but best be safe + return fqn; + } + String enclosingFQN = enclosingClass.getName(); + int length = fqn.length(); + if (enclosingFQN.length() >= length) { + // Should also never happen + return fqn; + } + return fqn.substring(enclosingFQN.length()); + } + } + + /** + * Hidden classes have {@code /} characters in their internal names and {@code .} characters in their names returned + * by {@link Class#getName()} that are not package separators. + * These are distinguished by being followed by a character that is not a + * {@link Character#isJavaIdentifierStart(char)} (e.g., + * "jdk.vm.ci.runtime.test.TypeUniverse$$Lambda$1/869601985"). + * + * @param name the name to perform the replacements on + * @param packageSeparator the {@link Character} used as the package separator, e.g. {@code /} in internal form + * @param hiddenSeparator the {@link Character} used as the hidden class separator, e.g. {@code .} in internal form + */ + private static String replacePackageAndHiddenSeparators(String name, Character packageSeparator, Character hiddenSeparator) { + int index = name.indexOf(hiddenSeparator); // check if it's a hidden class + int length = name.length(); + StringBuilder buf = new StringBuilder(length); + if (index < 0) { + buf.append(name.replace(packageSeparator, hiddenSeparator)); + } else { + buf.append(name.substring(0, index).replace(packageSeparator, hiddenSeparator)); + buf.append(packageSeparator); + buf.append(name.substring(index + 1)); + } + return buf.toString(); + } + + /** + * Converts a type name in internal form to an external form. + * + * @param name the internal name to convert + * @param qualified whether the returned name should be qualified with the package name + * @param classForNameCompatible specifies if the returned name for array types should be in + * {@link Class#forName(String)} format (e.g., {@code "[Ljava.lang.Object;"}, + * {@code "[[I"}) or in Java source code format (e.g., {@code "java.lang.Object[]"}, + * {@code "int[][]"} ). + */ + public static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) { + switch (name.charAt(0)) { + case 'L': { + String type = name.substring(1, name.length() - 1); + String result = replacePackageAndHiddenSeparators(type, PACKAGE_SEPARATOR_INTERNAL, HIDDEN_SEPARATOR_INTERNAL); + if (!qualified) { + final int lastDot = result.lastIndexOf(HIDDEN_SEPARATOR_INTERNAL); + if (lastDot != -1) { + result = result.substring(lastDot + 1); + } + } + return result; + } + case '[': + if (classForNameCompatible) { + return replacePackageAndHiddenSeparators(name, PACKAGE_SEPARATOR_INTERNAL, HIDDEN_SEPARATOR_INTERNAL); + } else { + return internalNameToJava(name.substring(1), qualified, false) + "[]"; + } + default: + if (name.length() != 1) { + throw new IllegalArgumentException("Illegal internal name: " + name); + } + return JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)).getJavaName(); + } + } + + /** + * Convenient shortcut for calling + * {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a + * {@link StringBuilder} instance and convert the result to a string. + */ + public static String toLocation(ResolvedJavaMethod method, int bci) { + return appendLocation(new StringBuilder(), method, bci).toString(); + } + + /** + * Appends a string representation of a location specified by a given method and bci to a given + * {@link StringBuilder}. If a stack trace element with a non-null file name and non-negative + * line number is {@linkplain ResolvedJavaMethod#asStackTraceElement(int) available} for the + * given method, then the string returned is the {@link StackTraceElement#toString()} value of + * the stack trace element, suffixed by the bci location. For example: + * + *
    +     *     java.lang.String.valueOf(String.java:2930) [bci: 12]
    +     * 
    + * + * Otherwise, the string returned is the value of applying {@link JavaMethod#format(String)} + * with the format string {@code "%H.%n(%p)"}, suffixed by the bci location. For example: + * + *
    +     *     java.lang.String.valueOf(int) [bci: 12]
    +     * 
    + * + * @param sb + * @param method + * @param bci + */ + public static StringBuilder appendLocation(StringBuilder sb, ResolvedJavaMethod method, int bci) { + if (method != null) { + StackTraceElement ste = method.asStackTraceElement(bci); + if (ste.getFileName() != null && ste.getLineNumber() > 0) { + sb.append(ste); + } else { + sb.append(method.format("%H.%n(%p)")); + } + } else { + sb.append("Null method"); + } + return sb.append(" [bci: ").append(bci).append(']'); + } + + static void appendProfile(StringBuilder buf, AbstractJavaProfile profile, int bci, String type, String sep) { + if (profile != null) { + AbstractProfiledItem[] pitems = profile.getItems(); + if (pitems != null) { + buf.append(String.format("%s@%d:", type, bci)); + for (int j = 0; j < pitems.length; j++) { + AbstractProfiledItem pitem = pitems[j]; + buf.append(String.format(" %.6f (%s)%s", pitem.getProbability(), pitem.getItem(), sep)); + } + if (profile.getNotRecordedProbability() != 0) { + buf.append(String.format(" %.6f %s", profile.getNotRecordedProbability(), type, sep)); + } else { + buf.append(String.format(" %s", type, sep)); + } + } + } + } + + /** + * Converts a Java source-language class name into the internal form. + * + * @param className the class name + * @return the internal name form of the class name + */ + public static String toInternalName(String className) { + if (className.startsWith("[")) { + /* Already in the correct array style. */ + return replacePackageAndHiddenSeparators(className, PACKAGE_SEPARATOR_JAVA, HIDDEN_SEPARATOR_JAVA); + } + + StringBuilder result = new StringBuilder(); + String base = className; + while (base.endsWith("[]")) { + result.append("["); + base = base.substring(0, base.length() - 2); + } + + switch (base) { + case "boolean": + result.append("Z"); + break; + case "byte": + result.append("B"); + break; + case "short": + result.append("S"); + break; + case "char": + result.append("C"); + break; + case "int": + result.append("I"); + break; + case "float": + result.append("F"); + break; + case "long": + result.append("J"); + break; + case "double": + result.append("D"); + break; + case "void": + result.append("V"); + break; + default: + result.append("L") + .append(replacePackageAndHiddenSeparators(base, PACKAGE_SEPARATOR_JAVA, HIDDEN_SEPARATOR_JAVA)) + .append(";"); + break; + } + return result.toString(); + } + + /** + * Gets a string representation of an object based soley on its class and its + * {@linkplain System#identityHashCode(Object) identity hash code}. This avoids and calls to + * virtual methods on the object such as {@link Object#hashCode()}. + */ + public static String identityHashCodeString(Object obj) { + if (obj == null) { + return "null"; + } + return obj.getClass().getName() + "@" + System.identityHashCode(obj); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.invoke.MethodHandle; + +/** + * Interface to access the internals of the {@link MethodHandle} implementation of the VM. An + * implementation of this interface is usually required to access non-public classes, methods, and + * fields of {@link MethodHandle}, i.e., data that is not standardized by the Java specification. + */ +public interface MethodHandleAccessProvider { + + /** + * Identification for methods defined on the class {@link MethodHandle} that are processed by + * the {@link MethodHandleAccessProvider}. + */ + enum IntrinsicMethod { + /** The method {@code MethodHandle.invokeBasic}. */ + INVOKE_BASIC, + /** The method {@code MethodHandle.linkToStatic}. */ + LINK_TO_STATIC, + /** The method {@code MethodHandle.linkToSpecial}. */ + LINK_TO_SPECIAL, + /** The method {@code MethodHandle.linkToVirtual}. */ + LINK_TO_VIRTUAL, + /** The method {@code MethodHandle.linkToInterface}. */ + LINK_TO_INTERFACE + } + + /** + * Returns the method handle method intrinsic identifier for the provided method, or + * {@code null} if the method is not an intrinsic processed by this interface. + * + * @throws NullPointerException if {@code method} is null + */ + IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method); + + /** + * Resolves the invocation target for an invocation of {@link IntrinsicMethod#INVOKE_BASIC + * MethodHandle.invokeBasic} with the given constant receiver {@link MethodHandle}. Returns + * {@code null} if the invocation target is not available at this time. + * + * The first invocations of a method handle can use an interpreter to lookup the actual invoked + * method; frequently executed method handles can use Java bytecode generation to avoid the + * interpreter overhead. If the parameter forceBytecodeGeneration is set to true, the VM should + * try to generate bytecodes before this method returns. + * + * @returns {@code null} if {@code methodHandle} is not a {@link MethodHandle} or the invocation + * target is not available at this time + * @throws NullPointerException if {@code methodHandle} is null + */ + ResolvedJavaMethod resolveInvokeBasicTarget(JavaConstant methodHandle, boolean forceBytecodeGeneration); + + /** + * Resolves the invocation target for an invocation of a {@code MethodHandle.linkTo*} method + * with the given constant member name. The member name is the last parameter of the + * {@code linkTo*} method. + * + * @returns {@code null} if the invocation target is not available at this time + * @throws NullPointerException if {@code memberName} is null + * @throws IllegalArgumentException if {@code memberName} is not a + * {@code java.lang.invoke.MemberName} + */ + ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.reflect.Modifier; + +import static java.lang.reflect.Modifier.PRIVATE; +import static java.lang.reflect.Modifier.PROTECTED; +import static java.lang.reflect.Modifier.PUBLIC; + +/** + * A Java element (i.e., a class, interface, field or method) that is described by a set of Java + * language {@linkplain #getModifiers() modifiers}. + */ +public interface ModifiersProvider { + + /** + * Returns the modifiers for this element. + */ + int getModifiers(); + + /** + * @see Modifier#isInterface(int) + */ + default boolean isInterface() { + return Modifier.isInterface(getModifiers()); + } + + /** + * @see Modifier#isSynchronized(int) + */ + default boolean isSynchronized() { + return Modifier.isSynchronized(getModifiers()); + } + + /** + * @see Modifier#isStatic(int) + */ + default boolean isStatic() { + return Modifier.isStatic(getModifiers()); + } + + /** + * The setting of the final modifier bit for types is somewhat confusing, so don't export + * isFinal by default. Subclasses like {@link ResolvedJavaField} and {@link ResolvedJavaMethod} + * can export it as isFinal, but {@link ResolvedJavaType} can provide a more sensible equivalent + * like {@link ResolvedJavaType#isLeaf}. + * + * @see Modifier#isFinal(int) + */ + default boolean isFinalFlagSet() { + return Modifier.isFinal(getModifiers()); + } + + /** + * @see Modifier#isPublic(int) + */ + default boolean isPublic() { + return Modifier.isPublic(getModifiers()); + } + + /** + * Determines if this element is neither {@linkplain #isPublic() public}, + * {@linkplain #isProtected() protected} nor {@linkplain #isPrivate() private}. + */ + default boolean isPackagePrivate() { + return ((PUBLIC | PROTECTED | PRIVATE) & getModifiers()) == 0; + } + + /** + * @see Modifier#isPrivate(int) + */ + default boolean isPrivate() { + return Modifier.isPrivate(getModifiers()); + } + + /** + * @see Modifier#isProtected(int) + */ + default boolean isProtected() { + return Modifier.isProtected(getModifiers()); + } + + /** + * @see Modifier#isTransient(int) + */ + default boolean isTransient() { + return Modifier.isTransient(getModifiers()); + } + + /** + * @see Modifier#isStrict(int) + */ + default boolean isStrict() { + return Modifier.isStrict(getModifiers()); + } + + /** + * @see Modifier#isVolatile(int) + */ + default boolean isVolatile() { + return Modifier.isVolatile(getModifiers()); + } + + /** + * @see Modifier#isNative(int) + */ + default boolean isNative() { + return Modifier.isNative(getModifiers()); + } + + /** + * @see Modifier#isAbstract(int) + */ + default boolean isAbstract() { + return Modifier.isAbstract(getModifiers()); + } + + /** + * Checks that the method is concrete and not abstract. + * + * @return whether the method is a concrete method + */ + default boolean isConcrete() { + return !isAbstract(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/NullConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/NullConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/NullConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/NullConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, 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. + */ +package jdk.vm.ci.meta; + +/** + * The implementation type of the {@link JavaConstant#NULL_POINTER null constant}. + */ +final class NullConstant implements JavaConstant { + + protected NullConstant() { + } + + @Override + public JavaKind getJavaKind() { + return JavaKind.Object; + } + + @Override + public boolean isNull() { + return true; + } + + @Override + public boolean isDefaultForKind() { + return true; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public String toString() { + return JavaConstant.toString(this); + } + + @Override + public String toValueString() { + return "null"; + } + + @Override + public int hashCode() { + return 13; + } + + @Override + public boolean equals(Object o) { + return o instanceof NullConstant; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 that defines the interface between a runtime and a Java application that wants to access + * meta information. The runtime provides an implementation of the + * {@link jdk.vm.ci.meta.MetaAccessProvider} interface. + */ +package jdk.vm.ci.meta; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PlatformKind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PlatformKind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PlatformKind.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PlatformKind.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013, 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. + */ +package jdk.vm.ci.meta; + +/** + * Represents a platform-specific low-level type for values. + */ +public interface PlatformKind { + + String name(); + + public interface Key { + + } + + class EnumKey> implements Key { + private final Enum e; + + public EnumKey(Enum e) { + this.e = e; + } + + @Override + public int hashCode() { + return e.ordinal(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof EnumKey) { + EnumKey that = (EnumKey) obj; + return this.e == that.e; + } + return false; + } + } + + /** + * Gets a value associated with this object that can be used as a stable key in a map. The + * {@link Object#hashCode()} implementation of the returned value should be stable between VM + * executions. + */ + Key getKey(); + + /** + * Get the size in bytes of this {@link PlatformKind}. + */ + int getSizeInBytes(); + + /** + * Returns how many primitive values fit in this {@link PlatformKind}. For scalar types this is + * one, for SIMD types it may be higher. + */ + int getVectorLength(); + + /** + * Gets a single type char that identifies this type for use in debug output. + */ + char getTypeChar(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PrimitiveConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PrimitiveConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PrimitiveConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/PrimitiveConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.nio.ByteBuffer; + +/** + * Represents a primitive constant value, such as an integer or floating point number, within the + * compiler and across the compiler/runtime interface. + */ +public class PrimitiveConstant implements JavaConstant, SerializableConstant { + + private final JavaKind kind; + + /** + * The boxed primitive value as a {@code long}. For {@code float} and {@code double} values, + * this value is the result of {@link Float#floatToRawIntBits(float)} and + * {@link Double#doubleToRawLongBits(double)} respectively. + */ + private final long primitive; + + protected PrimitiveConstant(JavaKind kind, long primitive) { + this.primitive = primitive; + this.kind = kind; + + assert kind.isPrimitive() || kind == JavaKind.Illegal; + } + + static PrimitiveConstant forTypeChar(char kind, long i) { + return JavaConstant.forIntegerKind(JavaKind.fromPrimitiveOrVoidTypeChar(kind), i); + } + + @Override + public JavaKind getJavaKind() { + return kind; + } + + @Override + public boolean isNull() { + return false; + } + + @Override + public boolean isDefaultForKind() { + return primitive == 0; + } + + @Override + public boolean asBoolean() { + assert getJavaKind() == JavaKind.Boolean; + return primitive != 0L; + } + + @Override + public int asInt() { + assert getJavaKind().getStackKind() == JavaKind.Int : getJavaKind().getStackKind(); + return (int) primitive; + } + + @Override + public long asLong() { + assert getJavaKind().isNumericInteger(); + return primitive; + } + + @Override + public float asFloat() { + assert getJavaKind() == JavaKind.Float; + return Float.intBitsToFloat((int) primitive); + } + + @Override + public double asDouble() { + assert getJavaKind() == JavaKind.Double; + return Double.longBitsToDouble(primitive); + } + + @Override + public Object asBoxedPrimitive() { + switch (getJavaKind()) { + case Byte: + return Byte.valueOf((byte) primitive); + case Boolean: + return Boolean.valueOf(asBoolean()); + case Short: + return Short.valueOf((short) primitive); + case Char: + return Character.valueOf((char) primitive); + case Int: + return Integer.valueOf(asInt()); + case Long: + return Long.valueOf(asLong()); + case Float: + return Float.valueOf(asFloat()); + case Double: + return Double.valueOf(asDouble()); + default: + throw new IllegalArgumentException("unexpected kind " + getJavaKind()); + } + } + + @Override + public int getSerializedSize() { + return getJavaKind().getByteCount(); + } + + @Override + public void serialize(ByteBuffer buffer) { + switch (getJavaKind()) { + case Byte: + case Boolean: + buffer.put((byte) primitive); + break; + case Short: + buffer.putShort((short) primitive); + break; + case Char: + buffer.putChar((char) primitive); + break; + case Int: + buffer.putInt(asInt()); + break; + case Long: + buffer.putLong(asLong()); + break; + case Float: + buffer.putFloat(asFloat()); + break; + case Double: + buffer.putDouble(asDouble()); + break; + default: + throw new IllegalArgumentException("unexpected kind " + getJavaKind()); + } + } + + @Override + public int hashCode() { + return (int) (primitive ^ (primitive >>> 32)) * (getJavaKind().ordinal() + 31); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PrimitiveConstant)) { + return false; + } + PrimitiveConstant other = (PrimitiveConstant) o; + return this.kind.equals(other.kind) && this.primitive == other.primitive; + } + + @Override + public String toString() { + if (getJavaKind() == JavaKind.Illegal) { + return "illegal"; + } else { + return getJavaKind().getJavaName() + "[" + asBoxedPrimitive() + "|0x" + Long.toHexString(primitive) + "]"; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ProfilingInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ProfilingInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ProfilingInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ProfilingInfo.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Provides access to the profiling information of one specific method. Every accessor method + * returns the information that is available at the time of invocation. If a method is invoked + * multiple times, it may return significantly different results for every invocation as the + * profiling information may be changed by other Java threads at any time. + */ +public interface ProfilingInfo { + + /** + * Returns the length of the bytecodes associated with this profile. + */ + int getCodeSize(); + + /** + * Returns an estimate of how often the branch at the given byte code was taken. + * + * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if + * this information is not available. + */ + double getBranchTakenProbability(int bci); + + /** + * Returns an estimate of how often the switch cases are taken at the given BCI. The default + * case is stored as the last entry. + * + * @return A double value that contains the estimated probabilities, with 0.0 meaning never and + * 1.0 meaning always, or -1 if this information is not available. + */ + double[] getSwitchProbabilities(int bci); + + /** + * Returns the TypeProfile for the given BCI. + * + * @return Returns a JavaTypeProfile object, or null if not available. + */ + JavaTypeProfile getTypeProfile(int bci); + + /** + * Returns the MethodProfile for the given BCI. + * + * @return Returns a JavaMethodProfile object, or null if not available. + */ + JavaMethodProfile getMethodProfile(int bci); + + /** + * Returns information if the given BCI did ever throw an exception. + * + * @return {@link TriState#TRUE} if the instruction has thrown an exception at least once, + * {@link TriState#FALSE} if it never threw an exception, and {@link TriState#UNKNOWN} + * if this information was not recorded. + */ + TriState getExceptionSeen(int bci); + + /** + * Returns information if null was ever seen for the given BCI. This information is collected + * for the aastore, checkcast and instanceof bytecodes. + * + * @return {@link TriState#TRUE} if null was seen for the instruction, {@link TriState#FALSE} if + * null was NOT seen, and {@link TriState#UNKNOWN} if this information was not recorded. + */ + TriState getNullSeen(int bci); + + /** + * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts + * to each other, as the returned value highly depends on the time of invocation. + * + * @return the estimated execution count or -1 if not available. + */ + int getExecutionCount(int bci); + + /** + * Returns how frequently a method was deoptimized for the given deoptimization reason. This + * only indicates how often the method did fall back to the interpreter for the execution and + * does not indicate how often it was recompiled. + * + * @param reason the reason for which the number of deoptimizations should be queried + * @return the number of times the compiled method deoptimized for the given reason. + */ + int getDeoptimizationCount(DeoptimizationReason reason); + + /** + * Records the size of the compiler intermediate representation (IR) associated with this + * method. + * + * @param irType the IR type for which the size is being recorded + * @param irSize the IR size to be recorded. The unit depends on the IR. + * @return whether recording this information for {@code irType} is supported + */ + boolean setCompilerIRSize(Class irType, int irSize); + + /** + * Gets the size of the compiler intermediate representation (IR) associated with this method + * last recorded by {@link #setCompilerIRSize(Class, int)}. + * + * @param irType the IR type for which the size is being requested + * @return the requested IR size or -1 if it is unavailable for {@code irType} + */ + int getCompilerIRSize(Class irType); + + /** + * Returns true if the profiling information can be assumed as sufficiently accurate. + * + * @return true if the profiling information was recorded often enough mature enough, false + * otherwise. + */ + boolean isMature(); + + /** + * Force data to be treated as mature if possible. + */ + void setMature(); + + /** + * Formats this profiling information to a string. + * + * @param method an optional method that augments the profile string returned + * @param sep the separator to use for each separate profile record + */ + default String toString(ResolvedJavaMethod method, String sep) { + StringBuilder buf = new StringBuilder(100); + if (method != null) { + buf.append(String.format("canBeStaticallyBound: %b%s", method.canBeStaticallyBound(), sep)); + } + for (int i = 0; i < getCodeSize(); i++) { + if (getExecutionCount(i) != -1) { + buf.append(String.format("executionCount@%d: %d%s", i, getExecutionCount(i), sep)); + } + + if (getBranchTakenProbability(i) != -1) { + buf.append(String.format("branchProbability@%d: %.6f%s", i, getBranchTakenProbability(i), sep)); + } + + double[] switchProbabilities = getSwitchProbabilities(i); + if (switchProbabilities != null) { + buf.append(String.format("switchProbabilities@%d:", i)); + for (int j = 0; j < switchProbabilities.length; j++) { + buf.append(String.format(" %.6f", switchProbabilities[j])); + } + buf.append(sep); + } + + if (getExceptionSeen(i) != TriState.UNKNOWN) { + buf.append(String.format("exceptionSeen@%d: %s%s", i, getExceptionSeen(i).name(), sep)); + } + + if (getNullSeen(i) != TriState.UNKNOWN) { + buf.append(String.format("nullSeen@%d: %s%s", i, getNullSeen(i).name(), sep)); + } + + JavaTypeProfile typeProfile = getTypeProfile(i); + MetaUtil.appendProfile(buf, typeProfile, i, "types", sep); + + JavaMethodProfile methodProfile = getMethodProfile(i); + MetaUtil.appendProfile(buf, methodProfile, i, "methods", sep); + } + + boolean firstDeoptReason = true; + for (DeoptimizationReason reason : DeoptimizationReason.values()) { + int count = getDeoptimizationCount(reason); + if (count > 0) { + if (firstDeoptReason) { + buf.append("deoptimization history").append(sep); + firstDeoptReason = false; + } + buf.append(String.format(" %s: %d%s", reason.name(), count, sep)); + } + } + if (buf.length() == 0) { + return ""; + } + String s = buf.toString(); + return s.substring(0, s.length() - sep.length()); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/RawConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/RawConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/RawConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/RawConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.meta; + +public class RawConstant extends PrimitiveConstant { + + public RawConstant(long rawValue) { + super(JavaKind.Int, rawValue); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Modifier; + +/** + * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved + * through {@link ConstantPool constant pools}. + */ +public interface ResolvedJavaField extends JavaField, ModifiersProvider, AnnotatedElement { + + /** + * {@inheritDoc} + *

    + * Only the {@linkplain Modifier#fieldModifiers() field flags} specified in the JVM + * specification will be included in the returned mask. + */ + @Override + int getModifiers(); + + /** + * Returns the offset of the field relative to the base of its storage container (e.g., + * {@code instanceOop} for an instance field or {@code Klass*} for a static field on HotSpot). + */ + int getOffset(); + + default boolean isFinal() { + return ModifiersProvider.super.isFinalFlagSet(); + } + + /** + * Determines if this field was injected by the VM. Such a field, for example, is not derived + * from a class file. + */ + boolean isInternal(); + + /** + * Determines if this field is a synthetic field as defined by the Java Language Specification. + */ + boolean isSynthetic(); + + /** + * Returns the {@link ResolvedJavaType} object representing the class or interface that declares + * this field. + */ + @Override + ResolvedJavaType getDeclaringClass(); + + /** + * Gets the value of the {@code ConstantValue} attribute ({@jvms 4.7.2}) associated with this + * field. + * + * @return {@code null} if this field has no {@code ConstantValue} attribute + * @throws UnsupportedOperationException if this operation is not supported + */ + default JavaConstant getConstantValue() { + throw new UnsupportedOperationException(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; + +/** + * Represents a resolved Java method. Methods, like fields and types, are resolved through + * {@link ConstantPool constant pools}. + */ +public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider, AnnotatedElement { + + /** + * Returns the method's bytecode. The returned bytecode does not contain breakpoints or non-Java + * bytecodes. This will return {@code null} if {@link #getCodeSize()} returns {@code <= 0} or if + * {@link #hasBytecodes()} returns {@code false}. + * + * The contained constant pool indexes may not be the ones found in the original class file but + * they can be used with the JVMCI API (e.g. methods in {@link ConstantPool}). + * + * @return {@code null} if {@code getLinkedCodeSize() <= 0} otherwise the bytecode of the method + * whose length is guaranteed to be {@code > 0} + */ + byte[] getCode(); + + /** + * Returns the size of the method's bytecode. If this method returns a value {@code > 0} then + * {@link #getCode()} will not return {@code null}. + * + * @return 0 if the method has no bytecode, {@code -1} if the method does have bytecode but its + * {@linkplain #getDeclaringClass() declaring class} is not + * {@linkplain ResolvedJavaType#isLinked() linked} otherwise the size of the bytecode in + * bytes (guaranteed to be {@code > 0}) + */ + int getCodeSize(); + + /** + * Returns the {@link ResolvedJavaType} object representing the class or interface that declares + * this method. + */ + @Override + ResolvedJavaType getDeclaringClass(); + + /** + * Returns the maximum number of locals used in this method's bytecodes. + */ + int getMaxLocals(); + + /** + * Returns the maximum number of stack slots used in this method's bytecodes. + */ + int getMaxStackSize(); + + default boolean isFinal() { + return ModifiersProvider.super.isFinalFlagSet(); + } + + /** + * Determines if this method is a synthetic method as defined by the Java Language + * Specification. + */ + boolean isSynthetic(); + + /** + * Checks that the method is a + * varargs + * method. + * + * @return whether the method is a varargs method + */ + boolean isVarArgs(); + + /** + * Checks that the method is a + * bridge + * method. + * + * @return whether the method is a bridge method + */ + boolean isBridge(); + + /** + * Returns {@code true} if this method is a default method; returns {@code false} otherwise. + * + * A default method is a public non-abstract instance method, that is, a non-static method with + * a body, declared in an interface type. + * + * @return true if and only if this method is a default method as defined by the Java Language + * Specification. + */ + boolean isDefault(); + + /** + * Checks whether this method is a class initializer. + * + * @return {@code true} if the method is a class initializer + */ + boolean isClassInitializer(); + + /** + * Checks whether this method is a constructor. + * + * @return {@code true} if the method is a constructor + */ + boolean isConstructor(); + + /** + * Checks whether this method can be statically bound (usually, that means it is final or + * private or static, but not abstract, or the declaring class is final). + * + * @return {@code true} if this method can be statically bound + */ + boolean canBeStaticallyBound(); + + /** + * Returns the list of exception handlers for this method. + */ + ExceptionHandler[] getExceptionHandlers(); + + /** + * Returns a stack trace element for this method and a given bytecode index. + */ + StackTraceElement asStackTraceElement(int bci); + + /** + * Returns an object that provides access to the profiling information recorded for this method. + */ + default ProfilingInfo getProfilingInfo() { + return getProfilingInfo(true, true); + } + + /** + * Returns an object that provides access to the profiling information recorded for this method. + * + * @param includeNormal if true, + * {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason) + * deoptimization counts} will include deoptimization that happened during execution + * of standard non-osr methods. + * @param includeOSR if true, + * {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason) + * deoptimization counts} will include deoptimization that happened during execution + * of on-stack-replacement methods. + */ + ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR); + + /** + * Invalidates the profiling information and restarts profiling upon the next invocation. + */ + void reprofile(); + + /** + * Returns the constant pool of this method. + */ + ConstantPool getConstantPool(); + + /** + * A {@code Parameter} provides information about method parameters. + */ + class Parameter implements AnnotatedElement { + private final String name; + private final ResolvedJavaMethod method; + private final int modifiers; + private final int index; + + /** + * Constructor for {@code Parameter}. + * + * @param name the name of the parameter or {@code null} if there is no + * {@literal MethodParameters} class file attribute providing a non-empty name + * for the parameter + * @param modifiers the modifier flags for the parameter + * @param method the method which defines this parameter + * @param index the index of the parameter + */ + public Parameter(String name, + int modifiers, + ResolvedJavaMethod method, + int index) { + assert name == null || !name.isEmpty(); + this.name = name; + this.modifiers = modifiers; + this.method = method; + this.index = index; + } + + /** + * Gets the name of the parameter. If the parameter's name is {@linkplain #isNamePresent() + * present}, then this method returns the name provided by the class file. Otherwise, this + * method synthesizes a name of the form argN, where N is the index of the parameter in the + * descriptor of the method which declares the parameter. + * + * @return the name of the parameter, either provided by the class file or synthesized if + * the class file does not provide a name + */ + public String getName() { + if (name == null) { + return "arg" + index; + } else { + return name; + } + } + + /** + * Gets the method declaring the parameter. + */ + public ResolvedJavaMethod getDeclaringMethod() { + return method; + } + + /** + * Get the modifier flags for the parameter. + */ + public int getModifiers() { + return modifiers; + } + + /** + * Gets the kind of the parameter. + */ + public JavaKind getKind() { + return method.getSignature().getParameterKind(index); + } + + /** + * Gets the formal type of the parameter. + */ + public Type getParameterizedType() { + return method.getGenericParameterTypes()[index]; + } + + /** + * Gets the type of the parameter. + */ + public JavaType getType() { + return method.getSignature().getParameterType(index, method.getDeclaringClass()); + } + + /** + * Determines if the parameter has a name according to a {@literal MethodParameters} class + * file attribute. + * + * @return true if and only if the parameter has a name according to the class file. + */ + public boolean isNamePresent() { + return name != null; + } + + /** + * Determines if the parameter represents a variable argument list. + */ + public boolean isVarArgs() { + return method.isVarArgs() && index == method.getSignature().getParameterCount(false) - 1; + } + + @Override + public T getAnnotation(Class annotationClass) { + return method.getParameterAnnotations(annotationClass)[index]; + } + + @Override + public Annotation[] getAnnotations() { + return method.getParameterAnnotations()[index]; + } + + @Override + public Annotation[] getDeclaredAnnotations() { + return getAnnotations(); + } + + @Override + public String toString() { + Type type = getParameterizedType(); + String typename = type.getTypeName(); + if (isVarArgs()) { + typename = typename.replaceFirst("\\[\\]$", "..."); + } + + final StringBuilder sb = new StringBuilder(Modifier.toString(getModifiers())); + if (sb.length() != 0) { + sb.append(' '); + } + return sb.append(typename).append(' ').append(getName()).toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Parameter) { + Parameter other = (Parameter) obj; + return (other.method.equals(method) && other.index == index); + } + return false; + } + + @Override + public int hashCode() { + return method.hashCode() ^ index; + } + } + + /** + * Returns an array of {@code Parameter} objects that represent all the parameters to this + * method. Returns an array of length 0 if this method has no parameters. Returns {@code null} + * if the parameter information is unavailable. + */ + default Parameter[] getParameters() { + return null; + } + + /** + * Returns an array of arrays that represent the annotations on the formal parameters, in + * declaration order, of this method. + * + * @see Method#getParameterAnnotations() + */ + Annotation[][] getParameterAnnotations(); + + /** + * Returns an array of {@link Type} objects that represent the formal parameter types, in + * declaration order, of this method. + * + * @see Method#getGenericParameterTypes() + */ + Type[] getGenericParameterTypes(); + + /** + * Returns {@code true} if this method is not excluded from inlining and has associated Java + * bytecodes (@see {@link ResolvedJavaMethod#hasBytecodes()}). + */ + boolean canBeInlined(); + + /** + * Determines if this method is targeted by a VM directive (e.g., + * {@code -XX:CompileCommand=dontinline,}) or VM recognized annotation (e.g., + * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined. + */ + boolean hasNeverInlineDirective(); + + /** + * Returns {@code true} if the inlining of this method should be forced. + */ + boolean shouldBeInlined(); + + /** + * Returns the LineNumberTable of this method or null if this method does not have a line + * numbers table. + */ + LineNumberTable getLineNumberTable(); + + /** + * Returns the local variable table of this method or null if this method does not have a local + * variable table. + */ + LocalVariableTable getLocalVariableTable(); + + /** + * Gets the encoding of (that is, a constant representing the value of) this method. + * + * @return a constant representing a reference to this method + */ + Constant getEncoding(); + + /** + * Checks if this method is present in the virtual table for subtypes of the specified + * {@linkplain ResolvedJavaType type}. + * + * @return true is this method is present in the virtual table for subtypes of this type. + */ + boolean isInVirtualMethodTable(ResolvedJavaType resolved); + + /** + * Gets the annotation of a particular type for a formal parameter of this method. + * + * @param annotationClass the Class object corresponding to the annotation type + * @param parameterIndex the index of a formal parameter of {@code method} + * @return the annotation of type {@code annotationClass} for the formal parameter present, else + * null + * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal + * parameter + */ + default T getParameterAnnotation(Class annotationClass, int parameterIndex) { + if (parameterIndex >= 0) { + Annotation[][] parameterAnnotations = getParameterAnnotations(); + for (Annotation a : parameterAnnotations[parameterIndex]) { + if (a.annotationType() == annotationClass) { + return annotationClass.cast(a); + } + } + } + return null; + } + + default JavaType[] toParameterTypes() { + JavaType receiver = isStatic() || isConstructor() ? null : getDeclaringClass(); + return getSignature().toParameterTypes(receiver); + } + + /** + * Gets the annotations of a particular type for the formal parameters of this method. + * + * @param annotationClass the Class object corresponding to the annotation type + * @return the annotation of type {@code annotationClass} (if any) for each formal parameter + * present + */ + @SuppressWarnings("unchecked") + default T[] getParameterAnnotations(Class annotationClass) { + Annotation[][] parameterAnnotations = getParameterAnnotations(); + T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length); + for (int i = 0; i < parameterAnnotations.length; i++) { + for (Annotation a : parameterAnnotations[i]) { + if (a.annotationType() == annotationClass) { + result[i] = annotationClass.cast(a); + } + } + } + return result; + } + + /** + * @see #getCodeSize() + * @return {@code getCodeSize() > 0} + */ + default boolean hasBytecodes() { + return getCodeSize() > 0; + } + + /** + * Checks whether the method has a receiver parameter - i.e., whether it is not static. + * + * @return whether the method has a receiver parameter + */ + default boolean hasReceiver() { + return !isStatic(); + } + + /** + * Determines if this method is {@link java.lang.Object#Object()}. + */ + default boolean isJavaLangObjectInit() { + return getDeclaringClass().isJavaLangObject() && getName().equals(""); + } + + /** + * Gets a speculation log that can be used when compiling this method to make new speculations + * and query previously failed speculations. The implementation may return a new + * {@link SpeculationLog} object each time this method is called so its the caller's + * responsibility to ensure the same speculation log is used throughout a compilation. + */ + SpeculationLog getSpeculationLog(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.reflect.AnnotatedElement; + +import jdk.vm.ci.meta.Assumptions.AssumptionResult; + +/** + * Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays + * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools} + * . + */ +public interface ResolvedJavaType extends JavaType, ModifiersProvider, AnnotatedElement { + /** + * Checks whether this type has a finalizer method. + * + * @return {@code true} if this class has a finalizer + */ + boolean hasFinalizer(); + + /** + * Checks whether this type has any finalizable subclasses so far. Any decisions based on this + * information require the registration of a dependency, since this information may change. + * + * @return {@code true} if this class has any subclasses with finalizers + */ + AssumptionResult hasFinalizableSubclass(); + + /** + * Checks whether this type is an interface. + * + * @return {@code true} if this type is an interface + */ + @Override + boolean isInterface(); + + /** + * Checks whether this type is an instance class. + * + * @return {@code true} if this type is an instance class + */ + boolean isInstanceClass(); + + /** + * Checks whether this type is primitive. + * + * @return {@code true} if this type is primitive + */ + boolean isPrimitive(); + + /* + * The setting of the final bit for types is a bit confusing since arrays are marked as final. + * This method provides a semantically equivalent test that appropriate for types. + */ + default boolean isLeaf() { + return getElementalType().isFinalFlagSet(); + } + + /** + * Checks whether this type is an enum. + * + * @return {@code true} if this type is an enum + */ + boolean isEnum(); + + /** + * Checks whether this type is initialized. If a type is initialized it implies that it was + * {@link #isLinked() linked} and that the static initializer has run. + * + * @return {@code true} if this type is initialized + */ + boolean isInitialized(); + + /** + * Initializes this type. + */ + void initialize(); + + /** + * Checks whether this type is linked and verified. When a type is linked the static initializer + * has not necessarily run. An {@link #isInitialized() initialized} type is always linked. + * + * @return {@code true} if this type is linked + */ + boolean isLinked(); + + /** + * Links this type. If this method returns normally, then future calls of {@link #isLinked} will + * return true and future calls of {@link #link} are no-ops. If the method throws an exception, + * then future calls of {@link #isLinked} will return false and future calls of {@link #link} + * will reattempt the linking step which might succeed or throw an exception. + */ + default void link() { + throw new UnsupportedOperationException("link is unsupported"); + } + + /** + * Checks whether this type or any of its supertypes or superinterfaces has default methods. + */ + default boolean hasDefaultMethods() { + throw new UnsupportedOperationException("hasDefaultMethods is unsupported"); + } + + /** + * Checks whether this type declares defaults methods. + */ + default boolean declaresDefaultMethods() { + throw new UnsupportedOperationException("declaresDefaultMethods is unsupported"); + } + + /** + * Determines if this type is either the same as, or is a superclass or superinterface of, the + * type represented by the specified parameter. This method is identical to + * {@link Class#isAssignableFrom(Class)} in terms of the value return for this type. + */ + boolean isAssignableFrom(ResolvedJavaType other); + + /** + * Returns {@code null} since support for VM anonymous class was removed by JDK-8243287. + * This method is preserved for JVMCI backwards compatibility. + */ + @Deprecated + default ResolvedJavaType getHostClass() { + return null; + } + + /** + * Returns true if this type is exactly the type {@link java.lang.Object}. + */ + default boolean isJavaLangObject() { + // Removed assertion due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=434442 + return getSuperclass() == null && !isInterface() && getJavaKind() == JavaKind.Object; + } + + /** + * Checks whether the specified object is an instance of this type. + * + * @param obj the object to test + * @return {@code true} if the object is an instance of this type + */ + boolean isInstance(JavaConstant obj); + + /** + * Gets the super class of this type. If this type represents either the {@code Object} class, + * an interface, a primitive type, or void, then null is returned. If this object represents an + * array class then the type object representing the {@code Object} class is returned. + */ + ResolvedJavaType getSuperclass(); + + /** + * Gets the interfaces implemented or extended by this type. This method is analogous to + * {@link Class#getInterfaces()} and as such, only returns the interfaces directly implemented + * or extended by this type. + */ + ResolvedJavaType[] getInterfaces(); + + /** + * Gets the single implementor of this type. Calling this method on a non-interface type causes + * an exception. + *

    + * If the compiler uses the result of this method for its compilation, the usage must be guarded + * because the verifier can not guarantee that the assigned type really implements this + * interface. Additionally, class loading can invalidate the result of this method. + * + * @return {@code null} if there is no implementor, the implementor if there is only one, or + * {@code this} if there are more than one. + */ + ResolvedJavaType getSingleImplementor(); + + /** + * Walks the class hierarchy upwards and returns the least common class that is a superclass of + * both the current and the given type. + * + * @return the least common type that is a super type of both the current and the given type, or + * {@code null} if primitive types are involved. + */ + ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType); + + /** + * Attempts to get a leaf concrete subclass of this type. + *

    + * For an {@linkplain #isArray() array} type A, the leaf concrete subclass is A if the + * {@linkplain #getElementalType() elemental} type of A is final (which includes primitive + * types). Otherwise {@code null} is returned for A. + *

    + * For a non-array type T, the result is the leaf concrete type in the current hierarchy of T. + *

    + * A runtime may decide not to manage or walk a large hierarchy and so the result is + * conservative. That is, a non-null result is guaranteed to be the leaf concrete class in T's + * hierarchy at the current point in time but a null result does not necessarily imply + * that there is no leaf concrete class in T's hierarchy. + *

    + * If the compiler uses the result of this method for its compilation, it must register the + * {@link AssumptionResult} in its {@link Assumptions} because dynamic class loading can + * invalidate the result of this method. + * + * @return an {@link AssumptionResult} containing the leaf concrete subclass for this type as + * described above + */ + AssumptionResult findLeafConcreteSubtype(); + + @Override + ResolvedJavaType getComponentType(); + + @Override + default ResolvedJavaType getElementalType() { + ResolvedJavaType t = this; + while (t.isArray()) { + t = t.getComponentType(); + } + return t; + } + + @Override + ResolvedJavaType getArrayClass(); + + /** + * Resolves the method implementation for virtual dispatches on objects of this dynamic type. + * This resolution process only searches "up" the class hierarchy of this type. A broader search + * that also walks "down" the hierarchy is implemented by + * {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}. For interface types it returns null + * since no concrete object can be an interface. + * + * @param method the method to select the implementation of + * @param callerType the caller or context type used to perform access checks + * @return the link-time resolved method (might be abstract) or {@code null} if it is either a + * signature polymorphic method or can not be linked. + */ + ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType); + + /** + * A convenience wrapper for {@link #resolveMethod(ResolvedJavaMethod, ResolvedJavaType)} that + * only returns non-abstract methods. + * + * @param method the method to select the implementation of + * @param callerType the caller or context type used to perform access checks + * @return the concrete method that would be selected at runtime, or {@code null} if there is no + * concrete implementation of {@code method} in this type or any of its superclasses + */ + default ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { + ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType); + if (resolvedMethod == null || resolvedMethod.isAbstract()) { + return null; + } + return resolvedMethod; + } + + /** + * Given a {@link ResolvedJavaMethod} A, returns a concrete {@link ResolvedJavaMethod} B that is + * the only possible unique target for a virtual call on A(). Returns {@code null} if either no + * such concrete method or more than one such method exists. Returns the method A if A is a + * concrete method that is not overridden. + *

    + * If the compiler uses the result of this method for its compilation, it must register an + * assumption because dynamic class loading can invalidate the result of this method. + * + * @param method the method A for which a unique concrete target is searched + * @return the unique concrete target or {@code null} if no such target exists or assumptions + * are not supported by this runtime + */ + AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method); + + /** + * Returns the instance fields of this class, including + * {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned + * for array and primitive types. The order of fields returned by this method is stable. That + * is, for a single JVM execution the same order is returned each time this method is called. It + * is also the "natural" order, which means that the JVM would expect the fields in this order + * if no specific order is given. + * + * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this + * type are included in the result + * @return an array of instance fields + */ + ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses); + + /** + * Returns the static fields of this class, including {@linkplain ResolvedJavaField#isInternal() + * internal} fields. A zero-length array is returned for array and primitive types. The order of + * fields returned by this method is stable. That is, for a single JVM execution the same order + * is returned each time this method is called. + */ + ResolvedJavaField[] getStaticFields(); + + /** + * Returns the instance field of this class (or one of its super classes) at the given offset, + * or {@code null} if there is no such field. + * + * @param offset the offset of the field to look for + * @return the field with the given offset, or {@code null} if there is no such field. + */ + ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind); + + /** + * Returns name of source file of this type. + */ + String getSourceFileName(); + + /** + * Returns {@code true} if the type is a local type. + */ + boolean isLocal(); + + /** + * Returns {@code true} if the type is a member type. + */ + boolean isMember(); + + /** + * Returns the enclosing type of this type, if it exists, or {@code null}. + */ + ResolvedJavaType getEnclosingType(); + + /** + * Returns an array reflecting all the constructors declared by this type. This method is + * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors. Calling + * this method forces this type to be {@link #link linked}. + */ + ResolvedJavaMethod[] getDeclaredConstructors(); + + /** + * Returns an array reflecting all the constructors declared by this type. This method is + * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors. + * + * @param forceLink if {@code true}, forces this type to be {@link #link linked} + */ + default ResolvedJavaMethod[] getDeclaredConstructors(boolean forceLink) { + throw new UnsupportedOperationException(); + } + + /** + * Returns an array reflecting all the methods declared by this type. This method is similar to + * {@link Class#getDeclaredMethods()} in terms of returned methods. Calling this method forces + * this type to be {@link #link linked}. + */ + ResolvedJavaMethod[] getDeclaredMethods(); + + /** + * Returns an array reflecting all the methods declared by this type. This method is similar to + * {@link Class#getDeclaredMethods()} in terms of returned methods. + * + * @param forceLink if {@code true}, forces this type to be {@link #link linked} + */ + default ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { + throw new UnsupportedOperationException(); + } + + /** + * Returns the {@code } method for this class if there is one. + */ + ResolvedJavaMethod getClassInitializer(); + + default ResolvedJavaMethod findMethod(String name, Signature signature) { + for (ResolvedJavaMethod method : getDeclaredMethods()) { + if (method.getName().equals(name) && method.getSignature().equals(signature)) { + return method; + } + } + return null; + } + + /** + * Returns true if this type is {@link Cloneable} and can be safely cloned by creating a normal + * Java allocation and populating it from the fields returned by + * {@link #getInstanceFields(boolean)}. Some types may require special handling by the platform + * so they would to go through the normal {@link Object#clone} path. + */ + boolean isCloneableWithAllocation(); + + /** + * Lookup an unresolved type relative to an existing resolved type. + */ + @SuppressWarnings("unused") + default ResolvedJavaType lookupType(UnresolvedJavaType unresolvedJavaType, boolean resolve) { + return null; + } + + @SuppressWarnings("unused") + default ResolvedJavaField resolveField(UnresolvedJavaField unresolvedJavaField, ResolvedJavaType accessingClass) { + return null; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SerializableConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SerializableConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SerializableConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SerializableConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 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. + */ +package jdk.vm.ci.meta; + +import java.nio.ByteBuffer; + +/** + * Represents a compile-time constant that can be converted to a byte array. + */ +public interface SerializableConstant extends Constant { + + /** + * Return the size in bytes of the serialized representation of this constant. + */ + int getSerializedSize(); + + /** + * Serialize the constant into the ByteBuffer. There must be at least + * {@link #getSerializedSize()} bytes available capacity in the buffer. + */ + void serialize(ByteBuffer buffer); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Signature.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Signature.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Signature.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Signature.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.meta; + +/** + * Represents a method signature provided by the runtime. + * + * @see Method + * Descriptors + */ +public interface Signature { + + /** + * Returns the number of parameters in this signature, adding 1 for a receiver if requested. + * + * @param receiver true if 1 is to be added to the result for a receiver + * @return the number of parameters; + 1 iff {@code receiver == true} + */ + int getParameterCount(boolean receiver); + + /** + * Gets the parameter type at the specified position. + * + * @param index the index into the parameters, with {@code 0} indicating the first parameter + * @param accessingClass the context of the type lookup. If non-null, its class loader is used + * for resolving the type. If {@code null}, then the type returned is either + * unresolved or a resolved type whose resolution is context free (e.g., a primitive + * type or a type in a java.* package). + * @return the {@code index}'th parameter type + * @throws LinkageError if {@code accessingClass != null} and resolution fails + * + */ + JavaType getParameterType(int index, ResolvedJavaType accessingClass); + + /** + * Gets the parameter kind at the specified position. This is the same as calling + * {@link #getParameterType}. {@link JavaType#getJavaKind getJavaKind}. + * + * @param index the index into the parameters, with {@code 0} indicating the first parameter + * @return the kind of the parameter at the specified position + */ + default JavaKind getParameterKind(int index) { + return getParameterType(index, null).getJavaKind(); + } + + /** + * Gets the return type of this signature. + * + * @param accessingClass the context of the type lookup. If non-null, its class loader is used + * for resolving the type. If {@code null}, then the type returned is either + * unresolved or a resolved type whose resolution is context free (e.g., a primitive + * type or a type in a java.* package). + * @return the return type + * @throws LinkageError if {@code accessingClass != null} and resolution fails + */ + JavaType getReturnType(ResolvedJavaType accessingClass); + + /** + * Gets the return kind of this signature. This is the same as calling {@link #getReturnType}. + * {@link JavaType#getJavaKind getJavaKind}. + */ + default JavaKind getReturnKind() { + return getReturnType(null).getJavaKind(); + } + + /** + * Gets the + * method + * descriptor corresponding to this signature. For example: + * + *

    +     * (ILjava/lang/String;D)V
    +     * 
    + * + * @return the signature as a string + */ + default String toMethodDescriptor() { + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < getParameterCount(false); ++i) { + sb.append(getParameterType(i, null).getName()); + } + sb.append(')').append(getReturnType(null).getName()); + return sb.toString(); + } + + default JavaType[] toParameterTypes(JavaType receiverType) { + int args = getParameterCount(false); + JavaType[] result; + int i = 0; + if (receiverType != null) { + result = new JavaType[args + 1]; + result[0] = receiverType; + i = 1; + } else { + result = new JavaType[args]; + } + for (int j = 0; j < args; j++) { + result[i + j] = getParameterType(j, null); + } + return result; + } + + default JavaKind[] toParameterKinds(boolean receiver) { + int args = getParameterCount(false); + JavaKind[] result; + int i = 0; + if (receiver) { + result = new JavaKind[args + 1]; + result[0] = JavaKind.Object; + i = 1; + } else { + result = new JavaKind[args]; + } + for (int j = 0; j < args; j++) { + result[i + j] = getParameterKind(j); + } + return result; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SpeculationLog.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SpeculationLog.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SpeculationLog.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SpeculationLog.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.util.Map; +import java.util.function.Supplier; + +/** + * Manages unique {@link SpeculationReason} objects that denote why a deoptimization occurred. + * Reasons are embedded in compiled code for a method. If the compiled code deoptimizes at a + * position associated with a {@link SpeculationReason}, the reason is added to a set of failed + * speculations associated with the method. A subsequent compilation of the method can query the + * failed speculations via a {@link SpeculationLog} to avoid making a speculation based on + * invalidated reasons. This avoids repeated deoptimizations. + */ +public interface SpeculationLog { + /** + * The specific attributes of a speculation that a compiler uses to denote a speculation in a + * compiled method. Typical attributes of a speculation are a bytecode position, type + * information about a variable being speculated on and an enum denoting the type of operation + * to which the speculation applies. A {@link SpeculationReason} is used as a key in a + * {@link Map} and so it must implement {@link Object#equals(Object)} and + * {@link Object#hashCode()} in terms of its attributes. + * + * A JVMCI implementation may serialize speculations for storage off heap (e.g. in native memory + * associated with an nmethod). For this reason, the attributes of a {@link SpeculationReason} + * are restricted to those supported by the {@code add...} methods of + * {@link SpeculationReasonEncoding}. + */ + public interface SpeculationReason { + + /** + * Encodes the attributes of this reason using a {@link SpeculationReasonEncoding}. For + * efficiency, a {@link SpeculationReason} implementation should cache the returned value + * and return it for all subsequent calls to this method. This also underlines the + * requirement that the encoding for a specific reason instance should be stable. + * + * @param encodingSupplier source of a {@link SpeculationReasonEncoding} + * @return a {@link SpeculationReasonEncoding} that encodes all the attributes that uniquely + * identify this reason + */ + default SpeculationReasonEncoding encode(Supplier encodingSupplier) { + return null; + } + } + + /** + * Provides a facility for encoding the attributes of a {@link SpeculationReason}. The encoding + * format is determined by the implementation of this interface. + */ + public interface SpeculationReasonEncoding { + void addByte(int value); + + void addShort(int value); + + void addInt(int value); + + void addLong(long value); + + void addMethod(ResolvedJavaMethod method); + + void addType(ResolvedJavaType type); + + void addString(String value); + + default void addField(ResolvedJavaField field) { + addType(field.getDeclaringClass()); + addInt(field.getModifiers()); + addInt(field.getOffset()); + } + } + + /** + * Marker class that indicates that a speculation has no reason. + */ + final class NoSpeculationReason implements SpeculationReason { + } + + class Speculation { + private final SpeculationReason reason; + + public Speculation(SpeculationReason reason) { + this.reason = reason; + } + + public SpeculationReason getReason() { + return reason; + } + + @Override + public String toString() { + return reason.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Speculation) { + Speculation other = (Speculation) obj; + return reason.equals(other.reason); + } + return false; + } + + @Override + public int hashCode() { + return getReason().hashCode(); + } + } + + Speculation NO_SPECULATION = new Speculation(new NoSpeculationReason()); + + /** + * Updates the set of failed speculations recorded in this log. This must be called before + * compilation. + */ + void collectFailedSpeculations(); + + /** + * If this method returns true, the compiler is allowed to {@link #speculate} with the given + * reason. + */ + boolean maySpeculate(SpeculationReason reason); + + /** + * Registers a speculation performed by the compiler. The compiler must guard every call to this + * method for a specific reason with a call to {@link #maySpeculate(SpeculationReason)}. + * + * This API is subject to a benign race where a during the course of a compilation another + * thread might fail a speculation such that {@link #maySpeculate(SpeculationReason)} will + * return false but an earlier call returned true. This method will still return a working + * {@link Speculation} in that case but the compile will eventually be invalidated and the + * compile attempted again without the now invalid speculation. + * + * @param reason an object representing the reason for the speculation + * @return a compiler constant encapsulating the provided reason. It is usually passed as an + * argument to the deoptimization function. + */ + Speculation speculate(SpeculationReason reason); + + /** + * Returns if this log has speculations. + * + * @return true if there are speculations, false otherwise + */ + boolean hasSpeculations(); + + /** + * Given a {@link JavaConstant} previously returned from + * {@link MetaAccessProvider#encodeSpeculation(Speculation)} return the original + * {@link Speculation} object. + */ + Speculation lookupSpeculation(JavaConstant constant); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/SuppressFBWarnings.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Used to suppress FindBugs warnings. + */ +@interface SuppressFBWarnings { + /** + * The set of FindBugs + * warnings that are to be + * suppressed in annotated element. The value can be a bug category, kind or pattern. + */ + String[] value(); + + /** + * Reason why the warning is suppressed. + */ + String justification(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/TriState.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/TriState.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/TriState.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/TriState.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012, 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. + */ +package jdk.vm.ci.meta; + +/** + * Represents a logic value that can be either {@link #TRUE}, {@link #FALSE}, or {@link #UNKNOWN}. + */ +public enum TriState { + TRUE, + FALSE, + UNKNOWN; + + public static TriState get(boolean value) { + return value ? TRUE : FALSE; + } + + /** + * This is optimistic about {@link #UNKNOWN} (it prefers known values over {@link #UNKNOWN}) and + * pesimistic about known (it perfers {@link #TRUE} over {@link #FALSE}). + */ + public static TriState merge(TriState a, TriState b) { + if (a == TRUE || b == TRUE) { + return TRUE; + } + if (a == FALSE || b == FALSE) { + return FALSE; + } + assert a == UNKNOWN && b == UNKNOWN; + return UNKNOWN; + } + + public boolean isTrue() { + return this == TRUE; + } + + public boolean isFalse() { + return this == FALSE; + } + + public boolean isUnknown() { + return this == UNKNOWN; + } + + public boolean isKnown() { + return this != UNKNOWN; + } + + public boolean toBoolean() { + if (isTrue()) { + return true; + } else if (isFalse()) { + return false; + } else { + throw new IllegalStateException("Cannot convert to boolean, TriState is in an unknown state"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaField.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaField.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.meta; + +/** + * A implementation of {@link JavaField} for an unresolved field. + */ +public final class UnresolvedJavaField implements JavaField { + + private final String name; + private final JavaType holder; + private final JavaType type; + + public UnresolvedJavaField(JavaType holder, String name, JavaType type) { + this.name = name; + this.type = type; + this.holder = holder; + } + + @Override + public String getName() { + return name; + } + + @Override + public JavaType getType() { + return type; + } + + @Override + public JavaType getDeclaringClass() { + return holder; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !(obj instanceof UnresolvedJavaField)) { + return false; + } + UnresolvedJavaField that = (UnresolvedJavaField) obj; + return this.holder.equals(that.holder) && this.name.equals(that.name) && this.type.equals(that.type); + } + + /** + * Converts this compiler interface field to a string. + */ + @Override + public String toString() { + return format("UnresolvedJavaField<%H.%n %t>"); + } + + public ResolvedJavaField resolve(ResolvedJavaType accessingClass) { + ResolvedJavaType resolvedHolder = holder.resolve(accessingClass); + return resolvedHolder.resolveField(this, accessingClass); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaMethod.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaMethod.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.meta; + +/** + * Implementation of {@link JavaMethod} for unresolved HotSpot methods. + */ +public final class UnresolvedJavaMethod implements JavaMethod { + + private final String name; + private final Signature signature; + protected JavaType holder; + + public UnresolvedJavaMethod(String name, Signature signature, JavaType holder) { + this.name = name; + this.holder = holder; + this.signature = signature; + } + + @Override + public String getName() { + return name; + } + + @Override + public Signature getSignature() { + return signature; + } + + @Override + public JavaType getDeclaringClass() { + return holder; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !(obj instanceof UnresolvedJavaMethod)) { + return false; + } + UnresolvedJavaMethod that = (UnresolvedJavaMethod) obj; + return this.name.equals(that.name) && this.signature.equals(that.signature) && this.holder.equals(that.holder); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaType.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/UnresolvedJavaType.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011, 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. + */ +package jdk.vm.ci.meta; + +/** + * Implementation of {@link JavaType} for unresolved HotSpot classes. + */ +public final class UnresolvedJavaType implements JavaType { + private final String name; + + @Override + public String getName() { + return name; + } + + private UnresolvedJavaType(String name) { + this.name = name; + assert name.length() == 1 && JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)) != null || name.charAt(0) == '[' || name.charAt(name.length() - 1) == ';' : name; + } + + /** + * Creates an unresolved type for a valid {@link JavaType#getName() type name}. + */ + public static UnresolvedJavaType create(String name) { + return new UnresolvedJavaType(name); + } + + @Override + public JavaType getComponentType() { + if (getName().charAt(0) == '[') { + return new UnresolvedJavaType(getName().substring(1)); + } + return null; + } + + @Override + public JavaType getArrayClass() { + return new UnresolvedJavaType('[' + getName()); + } + + @Override + public JavaKind getJavaKind() { + return JavaKind.Object; + } + + @Override + public int hashCode() { + return getName().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !(obj instanceof UnresolvedJavaType)) { + return false; + } + UnresolvedJavaType that = (UnresolvedJavaType) obj; + return this.getName().equals(that.getName()); + } + + @Override + public String toString() { + return "UnresolvedJavaType<" + getName() + ">"; + } + + @Override + public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { + return accessingClass.lookupType(this, true); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Value.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Value.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Value.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Value.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2009, 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. + */ +package jdk.vm.ci.meta; + +/** + * Abstract base class for values. + */ +public abstract class Value { + + public static final Value[] NO_VALUES = new Value[0]; + + public static final AllocatableValue ILLEGAL = new IllegalValue(); + + private static final class IllegalValue extends AllocatableValue { + private IllegalValue() { + super(ValueKind.Illegal); + } + + @Override + public String toString() { + return "-"; + } + + @Override + public boolean equals(Object other) { + // Due to de-serialization this object may exist multiple times. So we compare classes + // instead of the individual objects. + return other instanceof IllegalValue; + } + } + + private final ValueKind valueKind; + + /** + * Initializes a new value of the specified kind. + * + * @param valueKind the kind + */ + protected Value(ValueKind valueKind) { + this.valueKind = valueKind; + } + + /** + * Returns a String representation of the kind, which should be the end of all + * {@link #toString()} implementation of subclasses. + */ + protected final String getKindSuffix() { + return "|" + valueKind.getKindSuffix(); + } + + public final ValueKind getValueKind() { + return valueKind; + } + + public final > K getValueKind(Class cls) { + return cls.cast(valueKind); + } + + /** + * Returns the platform specific kind used to store this value. + */ + public final PlatformKind getPlatformKind() { + return valueKind.getPlatformKind(); + } + + @Override + public int hashCode() { + return 41 + valueKind.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Value) { + Value that = (Value) obj; + return valueKind.equals(that.valueKind); + } + return false; + } + + /** + * Checks if this value is identical to {@code other}. + * + * Warning: Use with caution! Usually equivalence {@link #equals(Object)} is sufficient and + * should be used. + */ + public final boolean identityEquals(Value other) { + return this == other; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ValueKind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ValueKind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ValueKind.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ValueKind.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Represents the type of {@link Value values}. This class can be extended by compilers to track + * additional information about values. + */ +public abstract class ValueKind> { + + private enum IllegalKind implements PlatformKind { + ILLEGAL; + + private final EnumKey key = new EnumKey<>(this); + + @Override + public Key getKey() { + return key; + } + + @Override + public int getSizeInBytes() { + return 0; + } + + @Override + public int getVectorLength() { + return 0; + } + + @Override + public char getTypeChar() { + return '-'; + } + } + + private static class IllegalValueKind extends ValueKind { + + IllegalValueKind() { + super(IllegalKind.ILLEGAL); + } + + @Override + public IllegalValueKind changeType(PlatformKind newPlatformKind) { + return this; + } + + @Override + public String toString() { + return "ILLEGAL"; + } + } + + /** + * The non-type. + */ + public static final ValueKind Illegal = new IllegalValueKind(); + + private final PlatformKind platformKind; + + public ValueKind(PlatformKind platformKind) { + this.platformKind = platformKind; + } + + public final PlatformKind getPlatformKind() { + return platformKind; + } + + /** + * Create a new {@link ValueKind} with a different {@link PlatformKind}. Subclasses must + * override this to preserve the additional information added by the compiler. + */ + public abstract K changeType(PlatformKind newPlatformKind); + + /** + * Returns a String representation of the kind, which will be included at the end of + * {@link Value#toString()} implementation. Defaults to {@link #toString()} but can be + * overridden to provide something more specific. + */ + public String getKindSuffix() { + return toString(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/VMConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/VMConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/VMConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/VMConstant.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Represents a constant that needs to be patched at runtime by the VM. + */ +public interface VMConstant extends Constant { +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIBackend.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIBackend.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIBackend.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIBackend.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * 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. + */ +package jdk.vm.ci.runtime; + +import jdk.vm.ci.code.CodeCacheProvider; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.stack.StackIntrospection; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; + +/** + * A JVMCI backend encapsulates the capabilities needed by a Java based compiler for compiling and + * installing code for a single compute unit within a JVM. In a JVM with support for heterogeneous + * computing, more than one backend may be exposed. + */ +public class JVMCIBackend { + + private final MetaAccessProvider metaAccess; + private final CodeCacheProvider codeCache; + private final ConstantReflectionProvider constantReflection; + private final StackIntrospection stackIntrospection; + + public JVMCIBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) { + this.metaAccess = metaAccess; + this.codeCache = codeCache; + this.constantReflection = constantReflection; + this.stackIntrospection = stackIntrospection; + } + + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + public CodeCacheProvider getCodeCache() { + return codeCache; + } + + public ConstantReflectionProvider getConstantReflection() { + return constantReflection; + } + + public TargetDescription getTarget() { + return codeCache.getTarget(); + } + + public StackIntrospection getStackIntrospection() { + return stackIntrospection; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompilerFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompilerFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompilerFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompilerFactory.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * 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. + */ +package jdk.vm.ci.runtime; + +import java.io.PrintStream; + +/** + * Factory for creating JVMCI compilers. + */ +public interface JVMCICompilerFactory { + + /** + * Get the name of this compiler. The name is used by JVMCI to determine which factory to use. + */ + String getCompilerName(); + + /** + * Notifies this object that it has been selected to {@linkplain #createCompiler(JVMCIRuntime) + * create} a compiler and it should now perform any heavy weight initialization that it deferred + * during construction. + */ + default void onSelection() { + } + + /** + * Create a new instance of a {@link JVMCICompiler}. + */ + JVMCICompiler createCompiler(JVMCIRuntime runtime); + + /** + * Prints a description of the properties used to configure this compiler. + * + * @param out where to print the message + */ + default void printProperties(PrintStream out) { + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompiler.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompiler.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompiler.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCICompiler.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * 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. + */ +package jdk.vm.ci.runtime; + +import jdk.vm.ci.code.CompilationRequest; +import jdk.vm.ci.code.CompilationRequestResult; + +public interface JVMCICompiler { + int INVOCATION_ENTRY_BCI = -1; + + /** + * Services a compilation request. This object should compile the method to machine code and + * install it in the code cache if the compilation is successful. + */ + CompilationRequestResult compileMethod(CompilationRequest request); + + /** + * Determines if this compiler supports the {@code gcIdentifier} garbage collector. The default + * implementation of this method returns true as that is the effective answer given by a + * {@link JVMCICompiler} before this method was added. + * + * @param gcIdentifier a VM dependent GC identifier + */ + default boolean isGCSupported(int gcIdentifier) { + return true; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCI.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCI.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCI.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCI.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.runtime; + +import java.util.Formatter; + +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.services.Services; + +public class JVMCI { + + /** + * Singleton instance lazily initialized via double-checked locking. + */ + @NativeImageReinitialize private static volatile JVMCIRuntime runtime; + + @NativeImageReinitialize private static boolean initializing; + + public static void initialize() { + // force static initializer + } + + private static native JVMCIRuntime initializeRuntime(); + + /** + * Gets the singleton {@link JVMCIRuntime} instance available to the application. + * + * @throws UnsupportedOperationException if JVMCI is not supported + */ + public static JVMCIRuntime getRuntime() { + JVMCIRuntime result = runtime; + if (result == null) { + synchronized (JVMCI.class) { + result = runtime; + if (result == null) { + if (initializing) { + // In recursive call from HotSpotJVMCIRuntime.runtime + // so no need to re-enter initializeRuntime below. This + // path is only entered if JVMCI initialization starts + // with JVMCI.getRuntime(). + return null; + } + initializing = true; + try { + runtime = result = initializeRuntime(); + } catch (UnsatisfiedLinkError e) { + String javaHome = Services.getSavedProperty("java.home"); + String vmName = Services.getSavedProperty("java.vm.name"); + Formatter errorMessage = new Formatter(); + errorMessage.format("The VM does not support the JVMCI API.%n"); + errorMessage.format("Currently used Java home directory is %s.%n", javaHome); + errorMessage.format("Currently used VM configuration is: %s", vmName); + throw new UnsupportedOperationException(errorMessage.toString()); + } finally { + initializing = false; + } + } + } + } + return result; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIRuntime.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIRuntime.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIRuntime.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/JVMCIRuntime.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * 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. + */ +package jdk.vm.ci.runtime; + +import jdk.vm.ci.code.Architecture; + +/** + * Interface for accessing the {@link JVMCI} APIs supported by the runtime. + */ +public interface JVMCIRuntime { + + /** + * Gets the default system compiler. + */ + JVMCICompiler getCompiler(); + + /** + * Gets the host JVMCI backend. + */ + JVMCIBackend getHostJVMCIBackend(); + + /** + * Gets the backend for a given architecture. + * + * @param arch a specific architecture class + */ + JVMCIBackend getJVMCIBackend(Class arch); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/runtime/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * The core runtime interface of the JVMCI API. + */ +package jdk.vm.ci.runtime; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIPermission.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIPermission.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIPermission.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIPermission.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.services; + +import java.security.BasicPermission; + +/** + * This class represents the permission to access JVMCI services. + */ +public class JVMCIPermission extends BasicPermission { + + private static final long serialVersionUID = 6346818963934448226L; + + public JVMCIPermission() { + super("jvmci"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016, 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. + */ +package jdk.vm.ci.services; + +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; + +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; + +/** + * Service-provider class for the runtime to locate providers of JVMCI services where the latter are + * not in packages exported by the JVMCI module. As part of instantiating a + * {@link JVMCIServiceLocator}, all JVMCI packages will be opened to the module defining the class + * of the instantiated object. + * + * While the {@link #getProvider(Class)} method can be used directly, it's usually easier to use + * {@link #getProviders(Class)}. + */ +public abstract class JVMCIServiceLocator { + + private static Void checkPermission() { + @SuppressWarnings("removal") + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new JVMCIPermission()); + } + return null; + } + + @SuppressWarnings("unused") + private JVMCIServiceLocator(Void ignore) { + } + + /** + * Creates a capability for accessing JVMCI. Once successfully instantiated, JVMCI opens all its + * packages to the module defining the type of this object. + * + * @throws SecurityException if a security manager has been installed and it denies + * {@link JVMCIPermission} + */ + protected JVMCIServiceLocator() { + this(checkPermission()); + Services.checkJVMCIEnabled(); + Services.openJVMCITo(getClass().getModule()); + } + + /** + * Gets the provider of the service defined by {@code service} or {@code null} if this object + * does not have a provider for {@code service}. + */ + protected abstract S getProvider(Class service); + + private static volatile List cachedLocators; + + private static Iterable getJVMCIServiceLocators() { + Iterable result = cachedLocators; + if (result != null) { + return result; + } + result = ServiceLoader.load(JVMCIServiceLocator.class, ClassLoader.getSystemClassLoader()); + if (IS_BUILDING_NATIVE_IMAGE) { + ArrayList l = new ArrayList<>(); + for (JVMCIServiceLocator locator : result) { + l.add(locator); + } + l.trimToSize(); + cachedLocators = l; + return l; + } + return result; + } + + /** + * Gets the providers of the service defined by {@code service} by querying the available + * {@link JVMCIServiceLocator} providers. + * + * @throws SecurityException if a security manager is present and it denies + * {@link JVMCIPermission} + */ + public static List getProviders(Class service) { + Services.checkJVMCIEnabled(); + @SuppressWarnings("removal") + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new JVMCIPermission()); + } + List providers = new ArrayList<>(); + for (JVMCIServiceLocator access : getJVMCIServiceLocators()) { + S provider = access.getProvider(service); + if (provider != null) { + providers.add(provider); + } + } + return providers; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/package-info.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * The service related portions of the JVMCI API. + */ +package jdk.vm.ci.services; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2014, 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. + */ +package jdk.vm.ci.services; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Formatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; + +import jdk.internal.misc.VM; + +/** + * Provides utilities needed by JVMCI clients. + */ +public final class Services { + + /** + * Guards code that should be run when building an JVMCI shared library but should be excluded + * from (being compiled into) the library. Such code must be directly guarded by an {@code if} + * statement on this field - the guard cannot be behind a method call. + */ + public static final boolean IS_BUILDING_NATIVE_IMAGE = Boolean.parseBoolean(VM.getSavedProperty("jdk.vm.ci.services.aot")); + + /** + * Guards code that should only be run in a JVMCI shared library. Such code must be directly + * guarded by an {@code if} statement on this field - the guard cannot be behind a method call. + * + * The value of this field in a JVMCI shared library runtime must be {@code true}. + */ + public static final boolean IS_IN_NATIVE_IMAGE; + static { + /* + * Prevents javac from constant folding use of this field. It is set to true by the process + * that builds the shared library. + */ + IS_IN_NATIVE_IMAGE = false; + } + + private Services() { + } + + /** + * In a native image, this field is initialized by {@link #initializeSavedProperties(byte[])}. + */ + private static volatile Map savedProperties; + + static final boolean JVMCI_ENABLED = Boolean.parseBoolean(VM.getSavedProperties().get("jdk.internal.vm.ci.enabled")); + + /** + * Checks that JVMCI is enabled in the VM and throws an error if it isn't. + */ + static void checkJVMCIEnabled() { + if (!JVMCI_ENABLED) { + throw new Error("The EnableJVMCI VM option must be true (i.e., -XX:+EnableJVMCI) to use JVMCI"); + } + } + + /** + * Gets an unmodifiable copy of the system properties saved when {@link System} is initialized. + */ + public static Map getSavedProperties() { + checkJVMCIEnabled(); + if (IS_IN_NATIVE_IMAGE) { + if (savedProperties == null) { + throw new InternalError("Saved properties not initialized"); + } + } else { + if (savedProperties == null) { + synchronized (Services.class) { + if (savedProperties == null) { + @SuppressWarnings("removal") + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new JVMCIPermission()); + } + savedProperties = VM.getSavedProperties(); + } + } + } + } + return savedProperties; + } + + /** + * Helper method equivalent to {@link #getSavedProperties()}{@code .getOrDefault(name, def)}. + */ + public static String getSavedProperty(String name, String def) { + return Services.getSavedProperties().getOrDefault(name, def); + } + + /** + * Helper method equivalent to {@link #getSavedProperties()}{@code .get(name)}. + */ + public static String getSavedProperty(String name) { + return Services.getSavedProperties().get(name); + } + + /** + * Causes the JVMCI subsystem to be initialized if it isn't already initialized. + */ + public static void initializeJVMCI() { + checkJVMCIEnabled(); + try { + Class.forName("jdk.vm.ci.runtime.JVMCI"); + } catch (ClassNotFoundException e) { + throw new InternalError(e); + } + } + + private static final Map, List> servicesCache = IS_BUILDING_NATIVE_IMAGE ? new HashMap<>() : null; + + @SuppressWarnings("unchecked") + private static Iterable load0(Class service) { + if (IS_IN_NATIVE_IMAGE || IS_BUILDING_NATIVE_IMAGE) { + List list = servicesCache.get(service); + if (list != null) { + return (Iterable) list; + } + if (IS_IN_NATIVE_IMAGE) { + throw new InternalError(String.format("No %s providers found when building native image", service.getName())); + } + } + + Iterable providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader()); + if (IS_BUILDING_NATIVE_IMAGE) { + synchronized (servicesCache) { + ArrayList providersList = new ArrayList<>(); + for (S provider : providers) { + providersList.add(provider); + } + servicesCache.put(service, providersList); + providers = providersList; + } + } + return providers; + } + + /** + * Opens all JVMCI packages to {@code otherModule}. + */ + static void openJVMCITo(Module otherModule) { + Module jvmci = Services.class.getModule(); + if (jvmci != otherModule) { + Set packages = jvmci.getPackages(); + for (String pkg : packages) { + boolean opened = jvmci.isOpen(pkg, otherModule); + if (!opened) { + jvmci.addOpens(pkg, otherModule); + } + } + } + } + + /** + * Gets an {@link Iterable} of the JVMCI providers available for a given service. + * + * @throws SecurityException if a security manager is present and it denies + * {@link RuntimePermission}("jvmci") + */ + public static Iterable load(Class service) { + @SuppressWarnings("removal") + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new JVMCIPermission()); + } + return load0(service); + } + + /** + * Gets the JVMCI provider for a given service for which at most one provider must be available. + * + * @param service the service whose provider is being requested + * @param required specifies if an {@link InternalError} should be thrown if no provider of + * {@code service} is available + * @throws SecurityException if a security manager is present and it denies + * {@link RuntimePermission}("jvmci") + */ + public static S loadSingle(Class service, boolean required) { + @SuppressWarnings("removal") + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new JVMCIPermission()); + } + Iterable providers = load0(service); + + S singleProvider = null; + for (S provider : providers) { + if (singleProvider != null) { + throw new InternalError(String.format("Multiple %s providers found: %s, %s", service.getName(), singleProvider.getClass().getName(), provider.getClass().getName())); + } + singleProvider = provider; + } + if (singleProvider == null && required) { + String javaHome = Services.getSavedProperty("java.home"); + String vmName = Services.getSavedProperty("java.vm.name"); + Formatter errorMessage = new Formatter(); + errorMessage.format("The VM does not expose required service %s.%n", service.getName()); + errorMessage.format("Currently used Java home directory is %s.%n", javaHome); + errorMessage.format("Currently used VM configuration is: %s", vmName); + throw new UnsupportedOperationException(errorMessage.toString()); + } + return singleProvider; + } + + /** + * A Java {@code char} has a maximal UTF8 length of 3. + */ + private static final int MAX_UNICODE_IN_UTF8_LENGTH = 3; + + /** + * {@link DataOutputStream#writeUTF(String)} only supports values whose UTF8 encoding length is + * less than 65535. + */ + private static final int MAX_UTF8_PROPERTY_STRING_LENGTH = 65535 / MAX_UNICODE_IN_UTF8_LENGTH; + + /** + * Serializes the {@linkplain #getSavedProperties() saved system properties} to a byte array for + * the purpose of {@linkplain #initializeSavedProperties(byte[]) initializing} the initial + * properties in the JVMCI shared library. + */ + @VMEntryPoint + private static byte[] serializeSavedProperties() throws IOException { + if (IS_IN_NATIVE_IMAGE) { + throw new InternalError("Can only serialize saved properties in HotSpot runtime"); + } + return serializeProperties(Services.getSavedProperties()); + } + + private static byte[] serializeProperties(Map props) throws IOException { + // Compute size of output on the assumption that + // all system properties have ASCII names and values + int estimate = 4 + 4; + int nonUtf8Props = 0; + for (Map.Entry e : props.entrySet()) { + String name = e.getKey(); + String value = e.getValue(); + estimate += (2 + (name.length())) + (2 + (value.length())); + if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) { + nonUtf8Props++; + } + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(estimate); + DataOutputStream out = new DataOutputStream(baos); + out.writeInt(props.size() - nonUtf8Props); + out.writeInt(nonUtf8Props); + for (Map.Entry e : props.entrySet()) { + String name = e.getKey(); + String value = e.getValue(); + if (name.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH && value.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH) { + out.writeUTF(name); + out.writeUTF(value); + } + } + if (nonUtf8Props != 0) { + for (Map.Entry e : props.entrySet()) { + String name = e.getKey(); + String value = e.getValue(); + if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) { + byte[] utf8Name = name.getBytes("UTF-8"); + byte[] utf8Value = value.getBytes("UTF-8"); + out.writeInt(utf8Name.length); + out.write(utf8Name); + out.writeInt(utf8Value.length); + out.write(utf8Value); + } + } + } + return baos.toByteArray(); + } + + /** + * Initialized the {@linkplain #getSavedProperties() saved system properties} in the JVMCI + * shared library from the {@linkplain #serializeSavedProperties() serialized saved properties} + * in the HotSpot runtime. + */ + @VMEntryPoint + private static void initializeSavedProperties(byte[] serializedProperties) throws IOException { + if (!IS_IN_NATIVE_IMAGE) { + throw new InternalError("Can only initialize saved properties in JVMCI shared library runtime"); + } + savedProperties = Collections.unmodifiableMap(deserializeProperties(serializedProperties)); + } + + private static Map deserializeProperties(byte[] serializedProperties) throws IOException { + DataInputStream in = new DataInputStream(new ByteArrayInputStream(serializedProperties)); + int utf8Props = in.readInt(); + int nonUtf8Props = in.readInt(); + Map props = new HashMap<>(utf8Props + nonUtf8Props); + int index = 0; + while (in.available() != 0) { + if (index < utf8Props) { + String name = in.readUTF(); + String value = in.readUTF(); + props.put(name, value); + } else { + int nameLen = in.readInt(); + byte[] nameBytes = new byte[nameLen]; + in.read(nameBytes); + int valueLen = in.readInt(); + byte[] valueBytes = new byte[valueLen]; + in.read(valueBytes); + String name = new String(nameBytes, "UTF-8"); + String value = new String(valueBytes, "UTF-8"); + props.put(name, value); + } + index++; + } + return props; + } +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/SuppressFBWarnings.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.services; + +/** + * Used to suppress FindBugs warnings. + */ +@interface SuppressFBWarnings { + /** + * The set of FindBugs + * warnings that are to be + * suppressed in annotated element. The value can be a bug category, kind or pattern. + */ + String[] value(); + + /** + * Reason why the warning is suppressed. + */ + String justification(); +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/VMEntryPoint.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/VMEntryPoint.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/VMEntryPoint.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/VMEntryPoint.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.services; + +/** + * Marker interface for methods which are called from the JVM. + */ +@interface VMEntryPoint { + /** + * An optional comment describing the caller. + */ + String value() default ""; +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ -package jdk.vm.ci.aarch64; - -import java.nio.ByteOrder; -import java.util.EnumSet; - -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.CPUFeatureName; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.Register.RegisterCategory; -import jdk.vm.ci.code.RegisterArray; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.PlatformKind; - -/** - * Represents the AArch64 architecture. - */ -public class AArch64 extends Architecture { - - public static final RegisterCategory CPU = new RegisterCategory("CPU"); - - // General purpose CPU registers - public static final Register r0 = new Register(0, 0, "r0", CPU); - public static final Register r1 = new Register(1, 1, "r1", CPU); - public static final Register r2 = new Register(2, 2, "r2", CPU); - public static final Register r3 = new Register(3, 3, "r3", CPU); - public static final Register r4 = new Register(4, 4, "r4", CPU); - public static final Register r5 = new Register(5, 5, "r5", CPU); - public static final Register r6 = new Register(6, 6, "r6", CPU); - public static final Register r7 = new Register(7, 7, "r7", CPU); - public static final Register r8 = new Register(8, 8, "r8", CPU); - public static final Register r9 = new Register(9, 9, "r9", CPU); - public static final Register r10 = new Register(10, 10, "r10", CPU); - public static final Register r11 = new Register(11, 11, "r11", CPU); - public static final Register r12 = new Register(12, 12, "r12", CPU); - public static final Register r13 = new Register(13, 13, "r13", CPU); - public static final Register r14 = new Register(14, 14, "r14", CPU); - public static final Register r15 = new Register(15, 15, "r15", CPU); - public static final Register r16 = new Register(16, 16, "r16", CPU); - public static final Register r17 = new Register(17, 17, "r17", CPU); - public static final Register r18 = new Register(18, 18, "r18", CPU); - public static final Register r19 = new Register(19, 19, "r19", CPU); - public static final Register r20 = new Register(20, 20, "r20", CPU); - public static final Register r21 = new Register(21, 21, "r21", CPU); - public static final Register r22 = new Register(22, 22, "r22", CPU); - public static final Register r23 = new Register(23, 23, "r23", CPU); - public static final Register r24 = new Register(24, 24, "r24", CPU); - public static final Register r25 = new Register(25, 25, "r25", CPU); - public static final Register r26 = new Register(26, 26, "r26", CPU); - public static final Register r27 = new Register(27, 27, "r27", CPU); - public static final Register r28 = new Register(28, 28, "r28", CPU); - public static final Register r29 = new Register(29, 29, "r29", CPU); - public static final Register r30 = new Register(30, 30, "r30", CPU); - - /* - * r31 is not a general purpose register, but represents either the stackpointer or the - * zero/discard register depending on the instruction. So we represent those two uses as two - * different registers. The register numbers are kept in sync with register_aarch64.hpp and have - * to be sequential, hence we also need a general r31 register here, which is never used. - */ - public static final Register r31 = new Register(31, 31, "r31", CPU); - public static final Register zr = new Register(32, 31, "zr", CPU); - public static final Register sp = new Register(33, 31, "sp", CPU); - - public static final Register lr = r30; - - // Used by runtime code: cannot be compiler-allocated. - public static final Register rscratch1 = r8; - public static final Register rscratch2 = r9; - - // @formatter:off - public static final RegisterArray cpuRegisters = new RegisterArray( - r0, r1, r2, r3, r4, r5, r6, r7, - r8, r9, r10, r11, r12, r13, r14, r15, - r16, r17, r18, r19, r20, r21, r22, r23, - r24, r25, r26, r27, r28, r29, r30, r31, - zr, sp - ); - // @formatter:on - - public static final RegisterCategory SIMD = new RegisterCategory("SIMD"); - - // Simd registers - public static final Register v0 = new Register(34, 0, "v0", SIMD); - public static final Register v1 = new Register(35, 1, "v1", SIMD); - public static final Register v2 = new Register(36, 2, "v2", SIMD); - public static final Register v3 = new Register(37, 3, "v3", SIMD); - public static final Register v4 = new Register(38, 4, "v4", SIMD); - public static final Register v5 = new Register(39, 5, "v5", SIMD); - public static final Register v6 = new Register(40, 6, "v6", SIMD); - public static final Register v7 = new Register(41, 7, "v7", SIMD); - public static final Register v8 = new Register(42, 8, "v8", SIMD); - public static final Register v9 = new Register(43, 9, "v9", SIMD); - public static final Register v10 = new Register(44, 10, "v10", SIMD); - public static final Register v11 = new Register(45, 11, "v11", SIMD); - public static final Register v12 = new Register(46, 12, "v12", SIMD); - public static final Register v13 = new Register(47, 13, "v13", SIMD); - public static final Register v14 = new Register(48, 14, "v14", SIMD); - public static final Register v15 = new Register(49, 15, "v15", SIMD); - public static final Register v16 = new Register(50, 16, "v16", SIMD); - public static final Register v17 = new Register(51, 17, "v17", SIMD); - public static final Register v18 = new Register(52, 18, "v18", SIMD); - public static final Register v19 = new Register(53, 19, "v19", SIMD); - public static final Register v20 = new Register(54, 20, "v20", SIMD); - public static final Register v21 = new Register(55, 21, "v21", SIMD); - public static final Register v22 = new Register(56, 22, "v22", SIMD); - public static final Register v23 = new Register(57, 23, "v23", SIMD); - public static final Register v24 = new Register(58, 24, "v24", SIMD); - public static final Register v25 = new Register(59, 25, "v25", SIMD); - public static final Register v26 = new Register(60, 26, "v26", SIMD); - public static final Register v27 = new Register(61, 27, "v27", SIMD); - public static final Register v28 = new Register(62, 28, "v28", SIMD); - public static final Register v29 = new Register(63, 29, "v29", SIMD); - public static final Register v30 = new Register(64, 30, "v30", SIMD); - public static final Register v31 = new Register(65, 31, "v31", SIMD); - - // @formatter:off - public static final RegisterArray simdRegisters = new RegisterArray( - v0, v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, - v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31 - ); - // @formatter:on - - // @formatter:off - public static final RegisterArray allRegisters = new RegisterArray( - r0, r1, r2, r3, r4, r5, r6, r7, - r8, r9, r10, r11, r12, r13, r14, r15, - r16, r17, r18, r19, r20, r21, r22, r23, - r24, r25, r26, r27, r28, r29, r30, r31, - zr, sp, - - v0, v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, - v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31 - ); - // @formatter:on - - /** - * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: - * {@code VM_Version::cpuFeatureFlags}. - */ - public enum CPUFeature implements CPUFeatureName { - FP, - ASIMD, - EVTSTRM, - AES, - PMULL, - SHA1, - SHA2, - CRC32, - LSE, - DCPOP, - SHA3, - SHA512, - SVE, - SVE2, - STXR_PREFETCH, - A53MAC, - } - - private final EnumSet features; - - /** - * Set of flags to control code emission. - */ - public enum Flag { - UseCRC32, - UseNeon, - UseSIMDForMemoryOps, - AvoidUnalignedAccesses, - UseLSE, - UseBlockZeroing - } - - private final EnumSet flags; - - public AArch64(EnumSet features, EnumSet flags) { - super("aarch64", AArch64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, 0, 0, 0); - this.features = features; - this.flags = flags; - } - - @Override - public EnumSet getFeatures() { - return features; - } - - public EnumSet getFlags() { - return flags; - } - - @Override - public PlatformKind getPlatformKind(JavaKind javaKind) { - switch (javaKind) { - case Boolean: - case Byte: - return AArch64Kind.BYTE; - case Short: - case Char: - return AArch64Kind.WORD; - case Int: - return AArch64Kind.DWORD; - case Long: - case Object: - return AArch64Kind.QWORD; - case Float: - return AArch64Kind.SINGLE; - case Double: - return AArch64Kind.DOUBLE; - default: - return null; - } - } - - @Override - public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { - AArch64Kind kind = (AArch64Kind) platformKind; - if (kind.isInteger()) { - return category.equals(CPU); - } else if (kind.isSIMD()) { - return category.equals(SIMD); - } - return false; - } - - @Override - public AArch64Kind getLargestStorableKind(RegisterCategory category) { - if (category.equals(CPU)) { - return AArch64Kind.QWORD; - } else if (category.equals(SIMD)) { - return AArch64Kind.V128_QWORD; - } else { - return null; - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64Kind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64Kind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64Kind.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64Kind.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +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. - */ -package jdk.vm.ci.aarch64; - -import jdk.vm.ci.meta.PlatformKind; - -public enum AArch64Kind implements PlatformKind { - - // scalar - BYTE(1), - WORD(2), - DWORD(4), - QWORD(8), - SINGLE(4), - DOUBLE(8), - - // SIMD - V32_BYTE(4, BYTE), - V32_WORD(4, WORD), - V64_BYTE(8, BYTE), - V64_WORD(8, WORD), - V64_DWORD(8, DWORD), - V128_BYTE(16, BYTE), - V128_WORD(16, WORD), - V128_DWORD(16, DWORD), - V128_QWORD(16, QWORD), - V128_SINGLE(16, SINGLE), - V128_DOUBLE(16, DOUBLE); - - private final int size; - private final int vectorLength; - - private final AArch64Kind scalar; - private final EnumKey key = new EnumKey<>(this); - - AArch64Kind(int size) { - this.size = size; - this.scalar = this; - this.vectorLength = 1; - } - - AArch64Kind(int size, AArch64Kind scalar) { - this.size = size; - this.scalar = scalar; - - assert size % scalar.size == 0; - this.vectorLength = size / scalar.size; - } - - public AArch64Kind getScalar() { - return scalar; - } - - @Override - public int getSizeInBytes() { - return size; - } - - @Override - public int getVectorLength() { - return vectorLength; - } - - @Override - public Key getKey() { - return key; - } - - public boolean isInteger() { - switch (this) { - case BYTE: - case WORD: - case DWORD: - case QWORD: - return true; - default: - return false; - } - } - - public boolean isSIMD() { - switch (this) { - case SINGLE: - case DOUBLE: - case V32_BYTE: - case V32_WORD: - case V64_BYTE: - case V64_WORD: - case V64_DWORD: - case V128_BYTE: - case V128_WORD: - case V128_DWORD: - case V128_QWORD: - case V128_SINGLE: - case V128_DOUBLE: - return true; - default: - return false; - } - } - - @Override - public char getTypeChar() { - switch (this) { - case BYTE: - return 'b'; - case WORD: - return 'w'; - case DWORD: - return 'd'; - case QWORD: - return 'q'; - case SINGLE: - return 'S'; - case DOUBLE: - return 'D'; - case V32_BYTE: - case V32_WORD: - case V64_BYTE: - case V64_WORD: - case V64_DWORD: - case V128_BYTE: - case V128_WORD: - case V128_DWORD: - case V128_QWORD: - case V128_SINGLE: - case V128_DOUBLE: - return 'v'; - default: - return '-'; - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * The AArch64 platform independent portions of the JVMCI API. - */ -package jdk.vm.ci.aarch64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.amd64; - -import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD; -import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE; -import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; -import static jdk.vm.ci.code.Register.SPECIAL; - -import java.nio.ByteOrder; -import java.util.EnumSet; - -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.CPUFeatureName; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.Register.RegisterCategory; -import jdk.vm.ci.code.RegisterArray; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.PlatformKind; - -/** - * Represents the AMD64 architecture. - */ -public class AMD64 extends Architecture { - - public static final RegisterCategory CPU = new RegisterCategory("CPU"); - - // @formatter:off - - // General purpose CPU registers - public static final Register rax = new Register(0, 0, "rax", CPU); - public static final Register rcx = new Register(1, 1, "rcx", CPU); - public static final Register rdx = new Register(2, 2, "rdx", CPU); - public static final Register rbx = new Register(3, 3, "rbx", CPU); - public static final Register rsp = new Register(4, 4, "rsp", CPU); - public static final Register rbp = new Register(5, 5, "rbp", CPU); - public static final Register rsi = new Register(6, 6, "rsi", CPU); - public static final Register rdi = new Register(7, 7, "rdi", CPU); - - public static final Register r8 = new Register(8, 8, "r8", CPU); - public static final Register r9 = new Register(9, 9, "r9", CPU); - public static final Register r10 = new Register(10, 10, "r10", CPU); - public static final Register r11 = new Register(11, 11, "r11", CPU); - public static final Register r12 = new Register(12, 12, "r12", CPU); - public static final Register r13 = new Register(13, 13, "r13", CPU); - public static final Register r14 = new Register(14, 14, "r14", CPU); - public static final Register r15 = new Register(15, 15, "r15", CPU); - - public static final Register[] cpuRegisters = { - rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, - r8, r9, r10, r11, r12, r13, r14, r15 - }; - - public static final RegisterCategory XMM = new RegisterCategory("XMM"); - - // XMM registers - public static final Register xmm0 = new Register(16, 0, "xmm0", XMM); - public static final Register xmm1 = new Register(17, 1, "xmm1", XMM); - public static final Register xmm2 = new Register(18, 2, "xmm2", XMM); - public static final Register xmm3 = new Register(19, 3, "xmm3", XMM); - public static final Register xmm4 = new Register(20, 4, "xmm4", XMM); - public static final Register xmm5 = new Register(21, 5, "xmm5", XMM); - public static final Register xmm6 = new Register(22, 6, "xmm6", XMM); - public static final Register xmm7 = new Register(23, 7, "xmm7", XMM); - - public static final Register xmm8 = new Register(24, 8, "xmm8", XMM); - public static final Register xmm9 = new Register(25, 9, "xmm9", XMM); - public static final Register xmm10 = new Register(26, 10, "xmm10", XMM); - public static final Register xmm11 = new Register(27, 11, "xmm11", XMM); - public static final Register xmm12 = new Register(28, 12, "xmm12", XMM); - public static final Register xmm13 = new Register(29, 13, "xmm13", XMM); - public static final Register xmm14 = new Register(30, 14, "xmm14", XMM); - public static final Register xmm15 = new Register(31, 15, "xmm15", XMM); - - public static final Register xmm16 = new Register(32, 16, "xmm16", XMM); - public static final Register xmm17 = new Register(33, 17, "xmm17", XMM); - public static final Register xmm18 = new Register(34, 18, "xmm18", XMM); - public static final Register xmm19 = new Register(35, 19, "xmm19", XMM); - public static final Register xmm20 = new Register(36, 20, "xmm20", XMM); - public static final Register xmm21 = new Register(37, 21, "xmm21", XMM); - public static final Register xmm22 = new Register(38, 22, "xmm22", XMM); - public static final Register xmm23 = new Register(39, 23, "xmm23", XMM); - - public static final Register xmm24 = new Register(40, 24, "xmm24", XMM); - public static final Register xmm25 = new Register(41, 25, "xmm25", XMM); - public static final Register xmm26 = new Register(42, 26, "xmm26", XMM); - public static final Register xmm27 = new Register(43, 27, "xmm27", XMM); - public static final Register xmm28 = new Register(44, 28, "xmm28", XMM); - public static final Register xmm29 = new Register(45, 29, "xmm29", XMM); - public static final Register xmm30 = new Register(46, 30, "xmm30", XMM); - public static final Register xmm31 = new Register(47, 31, "xmm31", XMM); - - public static final Register[] xmmRegistersSSE = { - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 - }; - - public static final Register[] xmmRegistersAVX512 = { - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, - xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, - xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31 - }; - - public static final RegisterCategory MASK = new RegisterCategory("MASK", false); - - public static final Register k0 = new Register(48, 0, "k0", MASK); - public static final Register k1 = new Register(49, 1, "k1", MASK); - public static final Register k2 = new Register(50, 2, "k2", MASK); - public static final Register k3 = new Register(51, 3, "k3", MASK); - public static final Register k4 = new Register(52, 4, "k4", MASK); - public static final Register k5 = new Register(53, 5, "k5", MASK); - public static final Register k6 = new Register(54, 6, "k6", MASK); - public static final Register k7 = new Register(55, 7, "k7", MASK); - - public static final RegisterArray valueRegistersSSE = new RegisterArray( - rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, - r8, r9, r10, r11, r12, r13, r14, r15, - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 - ); - - public static final RegisterArray valueRegistersAVX512 = new RegisterArray( - rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, - r8, r9, r10, r11, r12, r13, r14, r15, - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, - xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, - xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31, - k0, k1, k2, k3, k4, k5, k6, k7 - ); - - /** - * Register used to construct an instruction-relative address. - */ - public static final Register rip = new Register(56, -1, "rip", SPECIAL); - - public static final RegisterArray allRegisters = new RegisterArray( - rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, - r8, r9, r10, r11, r12, r13, r14, r15, - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, - xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, - xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31, - k0, k1, k2, k3, k4, k5, k6, k7, - rip - ); - - // @formatter:on - - /** - * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: - * {@code VM_Version::cpuFeatureFlags}. - */ - public enum CPUFeature implements CPUFeatureName { - CX8, - CMOV, - FXSR, - HT, - MMX, - AMD_3DNOW_PREFETCH, - SSE, - SSE2, - SSE3, - SSSE3, - SSE4A, - SSE4_1, - SSE4_2, - POPCNT, - LZCNT, - TSC, - TSCINV, - TSCINV_BIT, - AVX, - AVX2, - AES, - ERMS, - CLMUL, - BMI1, - BMI2, - RTM, - ADX, - AVX512F, - AVX512DQ, - AVX512PF, - AVX512ER, - AVX512CD, - AVX512BW, - AVX512VL, - SHA, - FMA, - VZEROUPPER, - AVX512_VPOPCNTDQ, - AVX512_VPCLMULQDQ, - AVX512_VAES, - AVX512_VNNI, - FLUSH, - FLUSHOPT, - CLWB, - AVX512_VBMI2, - AVX512_VBMI, - HV, - } - - private final EnumSet features; - - /** - * Set of flags to control code emission. - */ - public enum Flag { - UseCountLeadingZerosInstruction, - UseCountTrailingZerosInstruction - } - - private final EnumSet flags; - - private final AMD64Kind largestKind; - - public AMD64(EnumSet features, EnumSet flags) { - super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8); - this.features = features; - this.flags = flags; - assert features.contains(CPUFeature.SSE2) : "minimum config for x64"; - - if (features.contains(CPUFeature.AVX512F)) { - largestKind = AMD64Kind.V512_QWORD; - } else if (features.contains(CPUFeature.AVX)) { - largestKind = AMD64Kind.V256_QWORD; - } else { - largestKind = AMD64Kind.V128_QWORD; - } - } - - @Override - public EnumSet getFeatures() { - return features; - } - - public EnumSet getFlags() { - return flags; - } - - @Override - public RegisterArray getAvailableValueRegisters() { - if (features.contains(CPUFeature.AVX512F)) { - return valueRegistersAVX512; - } else { - return valueRegistersSSE; - } - } - - @Override - public PlatformKind getPlatformKind(JavaKind javaKind) { - switch (javaKind) { - case Boolean: - case Byte: - return AMD64Kind.BYTE; - case Short: - case Char: - return AMD64Kind.WORD; - case Int: - return AMD64Kind.DWORD; - case Long: - case Object: - return AMD64Kind.QWORD; - case Float: - return AMD64Kind.SINGLE; - case Double: - return AMD64Kind.DOUBLE; - default: - return null; - } - } - - @Override - public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { - AMD64Kind kind = (AMD64Kind) platformKind; - if (kind.isInteger()) { - return category.equals(CPU); - } else if (kind.isXMM()) { - return category.equals(XMM); - } else { - assert kind.isMask(); - return category.equals(MASK); - } - } - - @Override - public AMD64Kind getLargestStorableKind(RegisterCategory category) { - if (category.equals(CPU)) { - return AMD64Kind.QWORD; - } else if (category.equals(XMM)) { - return largestKind; - } else if (category.equals(MASK)) { - return AMD64Kind.MASK64; - } else { - return null; - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64Kind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64Kind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64Kind.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64Kind.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,218 +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. - */ -package jdk.vm.ci.amd64; - -import jdk.vm.ci.meta.PlatformKind; - -public enum AMD64Kind implements PlatformKind { - - // scalar - BYTE(1), - WORD(2), - DWORD(4), - QWORD(8), - SINGLE(4), - DOUBLE(8), - - // SSE2 - V32_BYTE(4, BYTE), - V32_WORD(4, WORD), - V64_BYTE(8, BYTE), - V64_WORD(8, WORD), - V64_DWORD(8, DWORD), - V128_BYTE(16, BYTE), - V128_WORD(16, WORD), - V128_DWORD(16, DWORD), - V128_QWORD(16, QWORD), - V128_SINGLE(16, SINGLE), - V128_DOUBLE(16, DOUBLE), - - // AVX - V256_BYTE(32, BYTE), - V256_WORD(32, WORD), - V256_DWORD(32, DWORD), - V256_QWORD(32, QWORD), - V256_SINGLE(32, SINGLE), - V256_DOUBLE(32, DOUBLE), - - // AVX512 - V512_BYTE(64, BYTE), - V512_WORD(64, WORD), - V512_DWORD(64, DWORD), - V512_QWORD(64, QWORD), - V512_SINGLE(64, SINGLE), - V512_DOUBLE(64, DOUBLE), - - MASK8(1), - MASK16(2), - MASK32(4), - MASK64(8); - - private final int size; - private final int vectorLength; - - private final AMD64Kind scalar; - private final EnumKey key = new EnumKey<>(this); - - AMD64Kind(int size) { - this.size = size; - this.scalar = this; - this.vectorLength = 1; - } - - AMD64Kind(int size, AMD64Kind scalar) { - this.size = size; - this.scalar = scalar; - - assert size % scalar.size == 0; - this.vectorLength = size / scalar.size; - } - - public AMD64Kind getScalar() { - return scalar; - } - - @Override - public int getSizeInBytes() { - return size; - } - - @Override - public int getVectorLength() { - return vectorLength; - } - - @Override - public Key getKey() { - return key; - } - - public boolean isInteger() { - switch (this) { - case BYTE: - case WORD: - case DWORD: - case QWORD: - return true; - default: - return false; - } - } - - public boolean isXMM() { - switch (this) { - case SINGLE: - case DOUBLE: - case V32_BYTE: - case V32_WORD: - case V64_BYTE: - case V64_WORD: - case V64_DWORD: - case V128_BYTE: - case V128_WORD: - case V128_DWORD: - case V128_QWORD: - case V128_SINGLE: - case V128_DOUBLE: - case V256_BYTE: - case V256_WORD: - case V256_DWORD: - case V256_QWORD: - case V256_SINGLE: - case V256_DOUBLE: - case V512_BYTE: - case V512_WORD: - case V512_DWORD: - case V512_QWORD: - case V512_SINGLE: - case V512_DOUBLE: - return true; - default: - return false; - } - } - - public boolean isMask() { - switch (this) { - case MASK8: - case MASK16: - case MASK32: - case MASK64: - return true; - default: - return false; - } - } - - @Override - public char getTypeChar() { - switch (this) { - case BYTE: - return 'b'; - case WORD: - return 'w'; - case DWORD: - return 'd'; - case QWORD: - return 'q'; - case SINGLE: - return 'S'; - case DOUBLE: - return 'D'; - case V32_BYTE: - case V32_WORD: - case V64_BYTE: - case V64_WORD: - case V64_DWORD: - return 'v'; - case V128_BYTE: - case V128_WORD: - case V128_DWORD: - case V128_QWORD: - case V128_SINGLE: - case V128_DOUBLE: - return 'x'; - case V256_BYTE: - case V256_WORD: - case V256_DWORD: - case V256_QWORD: - case V256_SINGLE: - case V256_DOUBLE: - return 'y'; - case V512_BYTE: - case V512_WORD: - case V512_DWORD: - case V512_QWORD: - case V512_SINGLE: - case V512_DOUBLE: - return 'z'; - case MASK8: - case MASK16: - case MASK32: - case MASK64: - return 'k'; - default: - return '-'; - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * The AMD64 platform independent portions of the JVMCI API. - */ -package jdk.vm.ci.amd64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.code; - -import java.nio.ByteOrder; -import java.util.Set; - -import jdk.vm.ci.code.Register.RegisterCategory; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.PlatformKind; - -/** - * Represents a CPU architecture, including information such as its endianness, CPU registers, word - * width, etc. - */ -public abstract class Architecture { - - /** - * The architecture specific type of a native word. - */ - private final PlatformKind wordKind; - - /** - * The name of this architecture (e.g. "AMD64"). - */ - private final String name; - - /** - * List of all available registers on this architecture. The index of each register in this list - * is equal to its {@linkplain Register#number number}. - */ - private final RegisterArray registers; - - /** - * The byte ordering can be either little or big endian. - */ - private final ByteOrder byteOrder; - - /** - * Whether the architecture supports unaligned memory accesses. - */ - private final boolean unalignedMemoryAccess; - - /** - * Mask of the barrier constants denoting the barriers that are not required to be explicitly - * inserted under this architecture. - */ - private final int implicitMemoryBarriers; - - /** - * Offset in bytes from the beginning of a call instruction to the displacement. - */ - private final int machineCodeCallDisplacementOffset; - - /** - * The size of the return address pushed to the stack by a call instruction. A value of 0 - * denotes that call linkage uses registers instead (e.g. SPARC). - */ - private final int returnAddressSize; - - protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, RegisterArray registers, int implicitMemoryBarriers, - int nativeCallDisplacementOffset, - int returnAddressSize) { - this.name = name; - this.registers = registers; - this.wordKind = wordKind; - this.byteOrder = byteOrder; - this.unalignedMemoryAccess = unalignedMemoryAccess; - this.implicitMemoryBarriers = implicitMemoryBarriers; - this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset; - this.returnAddressSize = returnAddressSize; - } - - /** - * Gets the set of CPU features supported by the current platform. - */ - public abstract Set getFeatures(); - - /** - * Converts this architecture to a string. - * - * @return the string representation of this architecture - */ - @Override - public final String toString() { - return getName().toLowerCase(); - } - - /** - * Gets the natural size of words (typically registers and pointers) of this architecture, in - * bytes. - */ - public int getWordSize() { - return wordKind.getSizeInBytes(); - } - - public PlatformKind getWordKind() { - return wordKind; - } - - /** - * Gets the name of this architecture. - */ - public String getName() { - return name; - } - - /** - * Gets the list of all registers that exist on this architecture. This contains all registers - * that exist in the specification of this architecture. Not all of them may be available on - * this particular architecture instance. The index of each register in this list is equal to - * its {@linkplain Register#number number}. - */ - public RegisterArray getRegisters() { - return registers; - } - - /** - * Gets a list of all registers available for storing values on this architecture. This may be a - * subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU. - */ - public RegisterArray getAvailableValueRegisters() { - return getRegisters(); - } - - public ByteOrder getByteOrder() { - return byteOrder; - } - - /** - * @return true if the architecture supports unaligned memory accesses. - */ - public boolean supportsUnalignedMemoryAccess() { - return unalignedMemoryAccess; - } - - /** - * Gets the size of the return address pushed to the stack by a call instruction. A value of 0 - * denotes that call linkage uses registers instead. - */ - public int getReturnAddressSize() { - return returnAddressSize; - } - - /** - * Gets the offset in bytes from the beginning of a call instruction to the displacement. - */ - public int getMachineCodeCallDisplacementOffset() { - return machineCodeCallDisplacementOffset; - } - - /** - * Determines the barriers in a given barrier mask that are explicitly required on this - * architecture. - * - * @param barriers a mask of the barrier constants - * @return the value of {@code barriers} minus the barriers unnecessary on this architecture - */ - public final int requiredBarriers(int barriers) { - return barriers & ~implicitMemoryBarriers; - } - - /** - * Determine whether a kind can be stored in a register of a given category. - * - * @param category the category of the register - * @param kind the kind that should be stored in the register - */ - public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind); - - /** - * Return the largest kind that can be stored in a register of a given category. - * - * @param category the category of the register - * @return the largest kind that can be stored in a register {@code category} - */ - public abstract PlatformKind getLargestStorableKind(RegisterCategory category); - - /** - * Gets the {@link PlatformKind} that is used to store values of a given {@link JavaKind}. - * - * @return {@code null} if there no deterministic {@link PlatformKind} for {@code javaKind} - */ - public abstract PlatformKind getPlatformKind(JavaKind javaKind); - - @Override - public final boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Architecture) { - Architecture that = (Architecture) obj; - if (this.name.equals(that.name)) { - assert this.byteOrder.equals(that.byteOrder); - assert this.implicitMemoryBarriers == that.implicitMemoryBarriers; - assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset; - assert this.registers.equals(that.registers); - assert this.returnAddressSize == that.returnAddressSize; - assert this.unalignedMemoryAccess == that.unalignedMemoryAccess; - assert this.wordKind == that.wordKind; - return true; - } - } - return false; - } - - @Override - public final int hashCode() { - return name.hashCode(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BailoutException.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BailoutException.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BailoutException.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BailoutException.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.Locale; - -/** - * Exception thrown when the compiler refuses to compile a method because of problems with the - * method. e.g. bytecode wouldn't verify, too big, JSR/ret too complicated, etc. This exception is - * not meant to indicate problems with the compiler itself. - */ -public class BailoutException extends RuntimeException { - - public static final long serialVersionUID = 8974598793458772L; - private final boolean permanent; - - /** - * Creates a new {@link BailoutException}. - * - * - * @param args parameters to the formatter - */ - public BailoutException(String format, Object... args) { - super(String.format(Locale.ENGLISH, format, args)); - this.permanent = true; - } - - /** - * Creates a new {@link BailoutException}. - * - * - * @param args parameters to the formatter - */ - public BailoutException(Throwable cause, String format, Object... args) { - super(String.format(Locale.ENGLISH, format, args), cause); - this.permanent = true; - } - - /** - * Creates a new {@link BailoutException}. - * - * @param permanent specifies whether this exception will occur again if compilation is retried - * @param args parameters to the formatter - */ - public BailoutException(boolean permanent, String format, Object... args) { - super(String.format(Locale.ENGLISH, format, args)); - this.permanent = permanent; - } - - /** - * @return whether this exception will occur again if compilation is retried - */ - public boolean isPermanent() { - return permanent; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.Arrays; -import java.util.Objects; - -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaValue; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.Value; - -/** - * Represents the Java bytecode frame state(s) at a given position including {@link Value locations} - * where to find the local variables, operand stack values and locked objects of the bytecode - * frame(s). - */ -public final class BytecodeFrame extends BytecodePosition { - - /** - * An array of values representing how to reconstruct the state of the Java frame. This is array - * is partitioned as follows: - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Start index (inclusive)End index (exclusive)Description
    0numLocalsLocal variables
    numLocalsnumLocals + numStackOperand stack
    numLocals + numStackvalues.lengthLocked objects
    - *

    - * Note that the number of locals and the number of stack slots may be smaller than the maximum - * number of locals and stack slots as specified in the compiled method. - * - * This field is intentionally exposed as a mutable array that a compiler may modify (e.g. - * during register allocation). - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "field is intentionally mutable")// - public final JavaValue[] values; - - /** - * An array describing the Java kinds in {@link #values}. It records a kind for the locals and - * the operand stack. - */ - private final JavaKind[] slotKinds; - - /** - * The number of locals in the values array. - */ - public final int numLocals; - - /** - * The number of stack slots in the values array. - */ - public final int numStack; - - /** - * The number of locks in the values array. - */ - public final int numLocks; - - /** - * True if this is a position inside an exception handler before the exception object has been - * consumed. In this case, {@link #numStack} {@code == 1} and {@link #getStackValue(int) - * getStackValue(0)} is the location of the exception object. If deoptimization happens at this - * position, the interpreter will rethrow the exception instead of executing the bytecode - * instruction at this position. - */ - public final boolean rethrowException; - - /** - * Specifies if this object represents a frame state in the middle of executing a call. If true, - * the arguments to the call have been popped from the stack and the return value (for a - * non-void call) has not yet been pushed. - */ - public final boolean duringCall; - - /** - * This BCI should be used for frame states that are built for code with no meaningful BCI. - */ - public static final int UNKNOWN_BCI = -5; - - /** - * The BCI for exception unwind. This is synthetic code and has no representation in bytecode. - * In contrast with {@link #AFTER_EXCEPTION_BCI}, at this point, if the method is synchronized, - * the monitor is still held. - */ - public static final int UNWIND_BCI = -1; - - /** - * The BCI for the state before starting to execute a method. Note that if the method is - * synchronized, the monitor is not yet held. - */ - public static final int BEFORE_BCI = -2; - - /** - * The BCI for the state after finishing the execution of a method and returning normally. Note - * that if the method was synchronized the monitor is already released. - */ - public static final int AFTER_BCI = -3; - - /** - * The BCI for exception unwind. This is synthetic code and has no representation in bytecode. - * In contrast with {@link #UNWIND_BCI}, at this point, if the method is synchronized, the - * monitor is already released. - */ - public static final int AFTER_EXCEPTION_BCI = -4; - - /** - * This BCI should be used for states that cannot be the target of a deoptimization, like - * snippet frame states. - */ - public static final int INVALID_FRAMESTATE_BCI = -6; - - /** - * Determines if a given BCI matches one of the placeholder BCI constants defined in this class. - */ - public static boolean isPlaceholderBci(int bci) { - return bci < 0; - } - - /** - * Gets the name of a given placeholder BCI. - */ - public static String getPlaceholderBciName(int bci) { - assert isPlaceholderBci(bci); - if (bci == BytecodeFrame.AFTER_BCI) { - return "AFTER_BCI"; - } else if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) { - return "AFTER_EXCEPTION_BCI"; - } else if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) { - return "INVALID_FRAMESTATE_BCI"; - } else if (bci == BytecodeFrame.BEFORE_BCI) { - return "BEFORE_BCI"; - } else if (bci == BytecodeFrame.UNKNOWN_BCI) { - return "UNKNOWN_BCI"; - } else { - assert bci == BytecodeFrame.UNWIND_BCI; - return "UNWIND_BCI"; - } - } - - /** - * Creates a new frame object. - * - * @param caller the caller frame (which may be {@code null}) - * @param method the method - * @param bci a BCI within the method - * @param rethrowException specifies if the VM should re-throw the pending exception when - * deopt'ing using this frame - * @param values the frame state {@link #values}. - * @param slotKinds the kinds in {@code values}. This array is now owned by this object and must - * not be mutated by the caller. - * @param numLocals the number of local variables - * @param numStack the depth of the stack - * @param numLocks the number of locked objects - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `slotKinds`") - public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, JavaValue[] values, JavaKind[] slotKinds, int numLocals, int numStack, - int numLocks) { - super(caller, method, bci); - assert values != null; - this.rethrowException = rethrowException; - this.duringCall = duringCall; - this.values = values; - this.slotKinds = slotKinds; - this.numLocals = numLocals; - this.numStack = numStack; - this.numLocks = numLocks; - assert !rethrowException || numStack == 1 : "must have exception on top of the stack"; - } - - /** - * Ensure that the frame state is formatted as expected by the JVM, with null or Illegal in the - * slot following a double word item. This should really be checked in FrameState itself but - * because of Word type rewriting and alternative backends that can't be done. - */ - public boolean validateFormat() { - if (caller() != null) { - caller().validateFormat(); - } - for (int i = 0; i < numLocals + numStack; i++) { - if (values[i] != null) { - JavaKind kind = slotKinds[i]; - if (kind.needsTwoSlots()) { - assert slotKinds.length > i + 1 : String.format("missing second word %s", this); - assert slotKinds[i + 1] == JavaKind.Illegal : this; - } - } - } - return true; - } - - /** - * Gets the kind of a local variable. - * - * @param i the local variable to query - * @return the kind of local variable {@code i} - * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocals} - */ - public JavaKind getLocalValueKind(int i) { - if (i < 0 || i >= numLocals) { - throw new IndexOutOfBoundsException(); - } - return slotKinds[i]; - } - - /** - * Gets the kind of a stack slot. - * - * @param i the local variable to query - * @return the kind of stack slot {@code i} - * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numStack} - */ - public JavaKind getStackValueKind(int i) { - if (i < 0 || i >= numStack) { - throw new IndexOutOfBoundsException(); - } - return slotKinds[i + numLocals]; - } - - /** - * Gets the value representing the specified local variable. - * - * @param i the local variable index - * @return the value that can be used to reconstruct the local's current value - * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocals} - */ - public JavaValue getLocalValue(int i) { - if (i < 0 || i >= numLocals) { - throw new IndexOutOfBoundsException(); - } - return values[i]; - } - - /** - * Gets the value representing the specified stack slot. - * - * @param i the stack index - * @return the value that can be used to reconstruct the stack slot's current value - * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numStack} - */ - public JavaValue getStackValue(int i) { - if (i < 0 || i >= numStack) { - throw new IndexOutOfBoundsException(); - } - return values[i + numLocals]; - } - - /** - * Gets the value representing the specified lock. - * - * @param i the lock index - * @return the value that can be used to reconstruct the lock's current value - * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocks} - */ - public JavaValue getLockValue(int i) { - if (i < 0 || i >= numLocks) { - throw new IndexOutOfBoundsException(); - } - return values[i + numLocals + numStack]; - } - - /** - * Gets the caller of this frame. - * - * @return {@code null} if this frame has no caller - */ - public BytecodeFrame caller() { - return (BytecodeFrame) getCaller(); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), - duringCall, - numLocals, - numLocks, - numStack, - rethrowException, - Arrays.hashCode(slotKinds), - Arrays.hashCode(values)); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - BytecodeFrame that = (BytecodeFrame) obj; - return duringCall == that.duringCall && - numLocals == that.numLocals && - numLocks == that.numLocks && - numStack == that.numStack && - rethrowException == that.rethrowException && - Arrays.equals(slotKinds, that.slotKinds) && - Arrays.equals(values, that.values); - } - - @Override - public String toString() { - return CodeUtil.append(new StringBuilder(100), this).toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2009, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.Objects; - -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * Represents a code position, that is, a chain of inlined methods with bytecode locations, that is - * communicated from the compiler to the runtime system. A code position can be used by the runtime - * system to reconstruct a source-level stack trace for exceptions and to create - * {@linkplain BytecodeFrame frames} for deoptimization. - */ -public class BytecodePosition { - - private final BytecodePosition caller; - private final ResolvedJavaMethod method; - private final int bci; - - /** - * Constructs a new object representing a given parent/caller, a given method, and a given BCI. - * - * @param caller the parent position - * @param method the method - * @param bci a BCI such that {@code method.codeSize() == 0 || bci < method.getCodeSize()}. That - * is, if code size is 0 then allow any value, otherwise the bci must be less than - * the code size. - */ - public BytecodePosition(BytecodePosition caller, ResolvedJavaMethod method, int bci) { - assert method != null; - this.caller = caller; - this.method = method; - this.bci = bci; - int codeSize = method.getCodeSize(); - if (codeSize != 0 && bci >= codeSize) { - throw new IllegalArgumentException(String.format("bci %d is out of range for %s %d bytes", bci, method.format("%H.%n(%p)"), codeSize)); - } - } - - /** - * Converts this code position to a string representation. - * - * @return a string representation of this code position - */ - @Override - public String toString() { - return CodeUtil.append(new StringBuilder(100), this).toString(); - } - - /** - * Deep equality test. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj != null && getClass() == obj.getClass()) { - BytecodePosition that = (BytecodePosition) obj; - if (this.bci == that.bci && Objects.equals(this.getMethod(), that.getMethod()) && Objects.equals(this.caller, that.caller)) { - return true; - } - } - return false; - } - - @Override - public int hashCode() { - int hc = method.hashCode() * 31 + bci; - if (caller != null) { - hc = (hc * 31) + caller.hashCode(); - } - return hc; - } - - /** - * @return The location within the method, as a bytecode index. The constant {@code -1} may be - * used to indicate the location is unknown, for example within code synthesized by the - * compiler. - */ - public int getBCI() { - return bci; - } - - /** - * @return The runtime interface method for this position. - */ - public ResolvedJavaMethod getMethod() { - return method; - } - - /** - * The position where this position has been called, {@code null} if none. - */ - public BytecodePosition getCaller() { - return caller; - } - - /** - * Adds a caller to the current position returning the new position. - */ - public BytecodePosition addCaller(BytecodePosition link) { - if (getCaller() == null) { - return new BytecodePosition(link, getMethod(), getBCI()); - } else { - return new BytecodePosition(getCaller().addCaller(link), getMethod(), getBCI()); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CallingConvention.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CallingConvention.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CallingConvention.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CallingConvention.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import static jdk.vm.ci.code.ValueUtil.isAllocatableValue; -import static jdk.vm.ci.code.ValueUtil.isStackSlot; -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.Value; - -/** - * A calling convention describes the locations in which the arguments for a call are placed and the - * location in which the return value is placed if the call is not void. - */ -public class CallingConvention { - - /** - * Marker interface denoting the type of a call for which a calling convention is requested. - */ - public interface Type { - } - - /** - * The amount of stack space (in bytes) required for the stack-based arguments of the call. - */ - private final int stackSize; - - private final AllocatableValue returnLocation; - - /** - * The ordered locations in which the arguments are placed. - */ - private final AllocatableValue[] argumentLocations; - - /** - * Creates a description of the registers and stack locations used by a call. - * - * @param stackSize amount of stack space (in bytes) required for the stack-based arguments of - * the call - * @param returnLocation the location for the return value or {@link Value#ILLEGAL} if a void - * call - * @param argumentLocations the ordered locations in which the arguments are placed - */ - public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) { - assert argumentLocations != null; - assert returnLocation != null; - this.argumentLocations = argumentLocations; - this.stackSize = stackSize; - this.returnLocation = returnLocation; - assert verify(); - } - - /** - * Gets the location for the return value or {@link Value#ILLEGAL} if a void call. - */ - public AllocatableValue getReturn() { - return returnLocation; - } - - /** - * Gets the location for the {@code index}'th argument. - */ - public AllocatableValue getArgument(int index) { - return argumentLocations[index]; - } - - /** - * Gets the amount of stack space (in bytes) required for the stack-based arguments of the call. - */ - public int getStackSize() { - return stackSize; - } - - /** - * Gets the number of locations required for the arguments. - */ - public int getArgumentCount() { - return argumentLocations.length; - } - - /** - * Gets the locations required for the arguments. - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "FB false positive") - public AllocatableValue[] getArguments() { - if (argumentLocations.length == 0) { - return argumentLocations; - } - return argumentLocations.clone(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("CallingConvention["); - String sep = ""; - for (Value op : argumentLocations) { - sb.append(sep).append(op); - sep = ", "; - } - if (!returnLocation.equals(Value.ILLEGAL)) { - sb.append(" -> ").append(returnLocation); - } - sb.append("]"); - return sb.toString(); - } - - private boolean verify() { - for (int i = 0; i < argumentLocations.length; i++) { - Value location = argumentLocations[i]; - assert isStackSlot(location) || isAllocatableValue(location); - } - return true; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2009, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.code.site.Call; -import jdk.vm.ci.code.site.Mark; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.SpeculationLog; - -/** - * Access to code cache related details and requirements. - */ -public interface CodeCacheProvider { - - /** - * Installs code for a given method based on a given compilation result without making it the - * default implementation of the method. - * - * @param method a method implemented by the installed code - * @param compiledCode the compiled code to be added - * @param log the speculation log to be used - * @param installedCode a predefined {@link InstalledCode} object to use as a reference to the - * installed code. If {@code null}, a new {@link InstalledCode} object will be - * created. - * @return a reference to the ready-to-run code - * @throws BailoutException if the code installation failed - * @throws IllegalArgumentException if {@code installedCode != null} and this object does not - * support a predefined {@link InstalledCode} object - */ - default InstalledCode addCode(ResolvedJavaMethod method, CompiledCode compiledCode, SpeculationLog log, InstalledCode installedCode) { - return installCode(method, compiledCode, installedCode, log, false); - } - - /** - * Installs code for a given method based on a given compilation result and makes it the default - * implementation of the method. - * - * @param method a method implemented by the installed code and for which the installed code - * becomes the default implementation - * @param compiledCode the compiled code to be added - * @return a reference to the ready-to-run code - * @throws BailoutException if the code installation failed - * @throws IllegalArgumentException if {@code installedCode != null} and this object does not - * support a predefined {@link InstalledCode} object - */ - default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompiledCode compiledCode) { - return installCode(method, compiledCode, null, null, true); - } - - /** - * Installs code based on a given compilation result. - * - * @param method the method compiled to produce {@code compiledCode} or {@code null} if the - * input to {@code compResult} was not a {@link ResolvedJavaMethod} - * @param compiledCode the compiled code to be added - * @param installedCode a pre-allocated {@link InstalledCode} object to use as a reference to - * the installed code. If {@code null}, a new {@link InstalledCode} object will be - * created. - * @param log the speculation log to be used - * @param isDefault specifies if the installed code should be made the default implementation of - * {@code compRequest.getMethod()}. The default implementation for a method is the - * code executed for standard calls to the method. This argument is ignored if - * {@code compRequest == null}. - * @return a reference to the compiled and ready-to-run installed code - * @throws BailoutException if the code installation failed - */ - InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault); - - /** - * Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be - * raised the next time {@code installedCode} is - * {@linkplain InstalledCode#executeVarargs(Object...) executed}. - */ - void invalidateInstalledCode(InstalledCode installedCode); - - /** - * Gets a name for a {@link Mark} mark. - */ - default String getMarkName(Mark mark) { - return String.valueOf(mark.id); - } - - /** - * Gets a name for the {@linkplain Call#target target} of a {@link Call}. - */ - default String getTargetName(Call call) { - return String.valueOf(call.target); - } - - /** - * Gets the register configuration to use when compiling a given method. - */ - RegisterConfig getRegisterConfig(); - - /** - * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all - * cases, even when the compiled method has no regular call instructions. - * - * @return the minimum size of the outgoing parameter area in bytes - */ - int getMinimumOutgoingSize(); - - /** - * Gets a description of the target architecture. - */ - TargetDescription getTarget(); - - /** - * Create a new speculation log for the target runtime. - */ - SpeculationLog createSpeculationLog(); - - /** - * Returns the maximum absolute offset of a PC relative call to a given address from any - * position in the code cache or -1 when not applicable. Intended for determining the required - * size of address/offset fields. - */ - long getMaxCallTargetOffset(long address); - - /** - * Determines if debug info should also be emitted at non-safepoint locations. - */ - boolean shouldDebugNonSafepoints(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,440 +0,0 @@ -/* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; - -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.MetaUtil; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.Signature; - -/** - * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.code} and its clients. - */ -public class CodeUtil { - - public static final String NEW_LINE = String.format("%n"); - - public static final int K = 1024; - public static final int M = 1024 * 1024; - - public static boolean isOdd(int n) { - return (n & 1) == 1; - } - - public static boolean isEven(int n) { - return (n & 1) == 0; - } - - /** - * Checks whether the specified integer is a power of two. - * - * @param val the value to check - * @return {@code true} if the value is a power of two; {@code false} otherwise - */ - public static boolean isPowerOf2(int val) { - return val > 0 && (val & val - 1) == 0; - } - - /** - * Checks whether the specified long is a power of two. - * - * @param val the value to check - * @return {@code true} if the value is a power of two; {@code false} otherwise - */ - public static boolean isPowerOf2(long val) { - return val > 0 && (val & val - 1) == 0; - } - - /** - * Computes the log (base 2) of the specified integer, rounding down. (E.g {@code log2(8) = 3}, - * {@code log2(21) = 4} ) - * - * @param val the value - * @return the log base 2 of the value - */ - public static int log2(int val) { - assert val > 0; - return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(val); - } - - /** - * Computes the log (base 2) of the specified long, rounding down. (E.g {@code log2(8) = 3}, - * {@code log2(21) = 4}) - * - * @param val the value - * @return the log base 2 of the value - */ - public static int log2(long val) { - assert val > 0; - return (Long.SIZE - 1) - Long.numberOfLeadingZeros(val); - } - - /** - * Narrow an integer value to a given bit width, and return the result as a signed long. - * - * @param value the value - * @param resultBits the result bit width - * @return {@code value} interpreted as {@code resultBits} bit number, encoded as signed long - */ - public static long narrow(long value, int resultBits) { - long ret = value & mask(resultBits); - return signExtend(ret, resultBits); - } - - /** - * Sign extend an integer. - * - * @param value the input value - * @param inputBits the bit width of the input value - * @return a signed long with the same value as the signed {@code inputBits}-bit number - * {@code value} - */ - public static long signExtend(long value, int inputBits) { - if (inputBits < 64) { - if ((value >>> (inputBits - 1) & 1) == 1) { - return value | (-1L << inputBits); - } else { - return value & ~(-1L << inputBits); - } - } else { - return value; - } - } - - /** - * Zero extend an integer. - * - * @param value the input value - * @param inputBits the bit width of the input value - * @return an unsigned long with the same value as the unsigned {@code inputBits}-bit number - * {@code value} - */ - public static long zeroExtend(long value, int inputBits) { - if (inputBits < 64) { - return value & ~(-1L << inputBits); - } else { - return value; - } - } - - /** - * Convert an integer to long. - * - * @param value the input value - * @param inputBits the bit width of the input value - * @param unsigned whether the values should be interpreted as signed or unsigned - * @return a long with the same value as the {@code inputBits}-bit number {@code value} - */ - public static long convert(long value, int inputBits, boolean unsigned) { - if (unsigned) { - return zeroExtend(value, inputBits); - } else { - return signExtend(value, inputBits); - } - } - - /** - * Get a bitmask with the low {@code bits} bit set and the high {@code 64 - bits} bit clear. - */ - public static long mask(int bits) { - assert 0 <= bits && bits <= 64; - if (bits == 64) { - return 0xffffffffffffffffL; - } else { - return (1L << bits) - 1; - } - } - - /** - * Get the minimum value representable in a {@code bits} bit signed integer. - */ - public static long minValue(int bits) { - assert 0 < bits && bits <= 64; - return -1L << (bits - 1); - } - - /** - * Get the maximum value representable in a {@code bits} bit signed integer. - */ - public static long maxValue(int bits) { - assert 0 < bits && bits <= 64; - return mask(bits - 1); - } - - /** - * Formats the values in a frame as a tabulated string. - * - * @param frame - * @return the values in {@code frame} as a tabulated string - */ - public static String tabulateValues(BytecodeFrame frame) { - int cols = Math.max(frame.numLocals, Math.max(frame.numStack, frame.numLocks)); - assert cols > 0; - ArrayList cells = new ArrayList<>(); - cells.add(""); - for (int i = 0; i < cols; i++) { - cells.add(i); - } - cols++; - if (frame.numLocals != 0) { - cells.add("locals:"); - cells.addAll(Arrays.asList(frame.values).subList(0, frame.numLocals)); - cells.addAll(Collections.nCopies(cols - frame.numLocals - 1, "")); - } - if (frame.numStack != 0) { - cells.add("stack:"); - cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals, frame.numLocals + frame.numStack)); - cells.addAll(Collections.nCopies(cols - frame.numStack - 1, "")); - } - if (frame.numLocks != 0) { - cells.add("locks:"); - cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals + frame.numStack, frame.values.length)); - cells.addAll(Collections.nCopies(cols - frame.numLocks - 1, "")); - } - Object[] cellArray = cells.toArray(); - for (int i = 0; i < cellArray.length; i++) { - if ((i % cols) != 0) { - cellArray[i] = "|" + cellArray[i]; - } - } - return CodeUtil.tabulate(cellArray, cols, 1, 1); - } - - /** - * Formats a given table as a string. The value of each cell is produced by - * {@link String#valueOf(Object)}. - * - * @param cells the cells of the table in row-major order - * @param cols the number of columns per row - * @param lpad the number of space padding inserted before each formatted cell value - * @param rpad the number of space padding inserted after each formatted cell value - * @return a string with one line per row and each column left-aligned - */ - public static String tabulate(Object[] cells, int cols, int lpad, int rpad) { - int rows = (cells.length + (cols - 1)) / cols; - int[] colWidths = new int[cols]; - for (int col = 0; col < cols; col++) { - for (int row = 0; row < rows; row++) { - int index = col + (row * cols); - if (index < cells.length) { - Object cell = cells[index]; - colWidths[col] = Math.max(colWidths[col], String.valueOf(cell).length()); - } - } - } - StringBuilder sb = new StringBuilder(); - String nl = NEW_LINE; - for (int row = 0; row < rows; row++) { - for (int col = 0; col < cols; col++) { - int index = col + (row * cols); - if (index < cells.length) { - for (int i = 0; i < lpad; i++) { - sb.append(' '); - } - Object cell = cells[index]; - String s = String.valueOf(cell); - int w = s.length(); - sb.append(s); - while (w < colWidths[col]) { - sb.append(' '); - w++; - } - for (int i = 0; i < rpad; i++) { - sb.append(' '); - } - } - } - sb.append(nl); - } - return sb.toString(); - } - - /** - * Appends a formatted code position to a {@link StringBuilder}. - * - * @param sb the {@link StringBuilder} to append to - * @param pos the code position to format and append to {@code sb} - * @return the value of {@code sb} - */ - public static StringBuilder append(StringBuilder sb, BytecodePosition pos) { - MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI()); - if (pos.getCaller() != null) { - sb.append(NEW_LINE); - append(sb, pos.getCaller()); - } - return sb; - } - - /** - * Appends a formatted frame to a {@link StringBuilder}. - * - * @param sb the {@link StringBuilder} to append to - * @param frame the frame to format and append to {@code sb} - * @return the value of {@code sb} - */ - public static StringBuilder append(StringBuilder sb, BytecodeFrame frame) { - MetaUtil.appendLocation(sb.append("at "), frame.getMethod(), frame.getBCI()); - assert sb.charAt(sb.length() - 1) == ']'; - sb.deleteCharAt(sb.length() - 1); - sb.append(", duringCall: ").append(frame.duringCall).append(", rethrow: ").append(frame.rethrowException).append(']'); - if (frame.values != null && frame.values.length > 0) { - sb.append(NEW_LINE); - String table = tabulateValues(frame); - String[] rows = table.split(NEW_LINE); - for (int i = 0; i < rows.length; i++) { - String row = rows[i]; - if (!row.trim().isEmpty()) { - sb.append(" ").append(row); - if (i != rows.length - 1) { - sb.append(NEW_LINE); - } - } - } - } - if (frame.caller() != null) { - sb.append(NEW_LINE); - append(sb, frame.caller()); - } else if (frame.getCaller() != null) { - sb.append(NEW_LINE); - append(sb, frame.getCaller()); - } - return sb; - } - - public interface RefMapFormatter { - - String formatStackSlot(int frameRefMapIndex); - } - - /** - * Formats a location present in a reference map. - */ - public static class DefaultRefMapFormatter implements RefMapFormatter { - - /** - * The size of a stack slot. - */ - public final int slotSize; - - /** - * The register used as the frame pointer. - */ - public final Register fp; - - /** - * The offset (in bytes) from the slot pointed to by {@link #fp} to the slot corresponding - * to bit 0 in the frame reference map. - */ - public final int refMapToFPOffset; - - public DefaultRefMapFormatter(int slotSize, Register fp, int refMapToFPOffset) { - this.slotSize = slotSize; - this.fp = fp; - this.refMapToFPOffset = refMapToFPOffset; - } - - @Override - public String formatStackSlot(int frameRefMapIndex) { - int refMapOffset = frameRefMapIndex * slotSize; - int fpOffset = refMapOffset + refMapToFPOffset; - if (fpOffset >= 0) { - return fp + "+" + fpOffset; - } - return fp.name + fpOffset; - } - } - - public static class NumberedRefMapFormatter implements RefMapFormatter { - - @Override - public String formatStackSlot(int frameRefMapIndex) { - return "s" + frameRefMapIndex; - } - - public String formatRegister(int regRefMapIndex) { - return "r" + regRefMapIndex; - } - } - - /** - * Appends a formatted debug info to a {@link StringBuilder}. - * - * @param sb the {@link StringBuilder} to append to - * @param info the debug info to format and append to {@code sb} - * @return the value of {@code sb} - */ - public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatterArg) { - RefMapFormatter formatter = formatterArg; - if (formatter == null) { - formatter = new NumberedRefMapFormatter(); - } - String nl = NEW_LINE; - ReferenceMap refMap = info.getReferenceMap(); - if (refMap != null) { - sb.append(refMap.toString()); - } - RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); - if (calleeSaveInfo != null) { - sb.append("callee-save-info:").append(nl); - Map map = calleeSaveInfo.slotsToRegisters(true); - for (Map.Entry e : map.entrySet()) { - sb.append(" ").append(e.getValue()).append(" -> ").append(formatter.formatStackSlot(e.getKey())).append(nl); - } - } - BytecodeFrame frame = info.frame(); - if (frame != null) { - append(sb, frame); - } else if (info.getBytecodePosition() != null) { - append(sb, info.getBytecodePosition()); - } - return sb; - } - - /** - * Create a calling convention from a {@link ResolvedJavaMethod}. - */ - public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, ValueKindFactory valueKindFactory) { - Signature sig = method.getSignature(); - JavaType retType = sig.getReturnType(null); - int sigCount = sig.getParameterCount(false); - JavaType[] argTypes; - int argIndex = 0; - if (!method.isStatic()) { - argTypes = new JavaType[sigCount + 1]; - argTypes[argIndex++] = method.getDeclaringClass(); - } else { - argTypes = new JavaType[sigCount]; - } - for (int i = 0; i < sigCount; i++) { - argTypes[argIndex++] = sig.getParameterType(i, null); - } - - RegisterConfig registerConfig = codeCache.getRegisterConfig(); - return registerConfig.getCallingConvention(type, retType, argTypes, valueKindFactory); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequest.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequest.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +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. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * Represents a request to compile a method. - */ -public class CompilationRequest { - - private final ResolvedJavaMethod method; - - private final int entryBCI; - - /** - * Creates a request to compile a method starting at its entry point. - * - * @param method the method to be compiled - */ - public CompilationRequest(ResolvedJavaMethod method) { - this(method, -1); - } - - /** - * Creates a request to compile a method starting at a given BCI. - * - * @param method the method to be compiled - * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the - * method's entry point - */ - public CompilationRequest(ResolvedJavaMethod method, int entryBCI) { - assert method != null; - this.method = method; - this.entryBCI = entryBCI; - } - - /** - * Gets the method to be compiled. - */ - public ResolvedJavaMethod getMethod() { - return method; - } - - /** - * Gets the bytecode index (BCI) at which to start compiling where -1 denotes a non-OSR - * compilation request and all other values denote an on stack replacement (OSR) compilation - * request. - */ - public int getEntryBCI() { - return entryBCI; - } - - @Override - public String toString() { - return method.format("%H.%n(%p)@" + entryBCI); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequestResult.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequestResult.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequestResult.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequestResult.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +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. - */ -package jdk.vm.ci.code; - -/** - * Provides information about the result of a {@link CompilationRequest}. - */ -public interface CompilationRequestResult { - - /** - * Determines if the compilation was successful. - * - * @return a non-null object whose {@link Object#toString()} describes the failure or null if - * compilation was successful - */ - Object getFailure(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompiledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompiledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompiledCode.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompiledCode.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -/** - * Marker type for an object containing the output of a compiler in a form suitable for installing - * into a managed code heap. Since the details of a code heap are specific to each runtime, this - * interface does not specify any methods. - */ -public interface CompiledCode { -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CPUFeatureName.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CPUFeatureName.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CPUFeatureName.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CPUFeatureName.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 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. - */ -package jdk.vm.ci.code; - -/** - * A CPU feature identified by a name. - */ -public interface CPUFeatureName { - /** - * Gets the name of this feature. - */ - String name(); - - /** - * Determines if {@code other} equals {@link #name()}. - */ - default boolean nameEquals(String other) { - return name().equals(other); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DebugInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DebugInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DebugInfo.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DebugInfo.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.code; - -import java.util.Objects; - -/** - * Represents the debugging information for a particular point of execution. This information - * includes: - *
      - *
    • a {@linkplain #getBytecodePosition() bytecode position}
    • - *
    • a reference map for registers and stack slots in the current frame
    • - *
    • a map from bytecode locals and operand stack slots to their values or locations from which - * their values can be read
    • - *
    • a map from the registers (in the caller's frame) to the slots where they are saved in the - * current frame
    • - *
    - */ -public final class DebugInfo { - - private final BytecodePosition bytecodePosition; - private ReferenceMap referenceMap; - private final VirtualObject[] virtualObjectMapping; - private RegisterSaveLayout calleeSaveInfo; - - /** - * Creates a new {@link DebugInfo} from the given values. - * - * @param codePos the {@linkplain BytecodePosition code position} or {@linkplain BytecodeFrame - * frame} info - * @param virtualObjectMapping the mapping of {@link VirtualObject}s to their real values. This - * array is now owned by this object and must not be mutated by the caller. - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `virtualObjectMapping`") - public DebugInfo(BytecodePosition codePos, VirtualObject[] virtualObjectMapping) { - this.bytecodePosition = codePos; - this.virtualObjectMapping = virtualObjectMapping; - } - - public DebugInfo(BytecodePosition codePos) { - this(codePos, null); - } - - public void setReferenceMap(ReferenceMap referenceMap) { - this.referenceMap = referenceMap; - } - - /** - * @return {@code true} if this debug information has a frame - */ - public boolean hasFrame() { - return getBytecodePosition() instanceof BytecodeFrame; - } - - /** - * Gets the deoptimization information for each inlined frame (if available). - * - * @return {@code null} if no frame de-opt info is {@linkplain #hasFrame() available} - */ - public BytecodeFrame frame() { - if (hasFrame()) { - return (BytecodeFrame) getBytecodePosition(); - } - return null; - } - - @Override - public String toString() { - return CodeUtil.append(new StringBuilder(100), this, null).toString(); - } - - /** - * @return The code position (including all inlined methods) of this debug info. If this is a - * {@link BytecodeFrame} instance, then it is also the deoptimization information for - * each inlined frame. - */ - public BytecodePosition getBytecodePosition() { - return bytecodePosition; - } - - public ReferenceMap getReferenceMap() { - return referenceMap; - } - - public VirtualObject[] getVirtualObjectMapping() { - return virtualObjectMapping; - } - - /** - * Sets the map from the registers (in the caller's frame) to the slots where they are saved in - * the current frame. - */ - public void setCalleeSaveInfo(RegisterSaveLayout calleeSaveInfo) { - this.calleeSaveInfo = calleeSaveInfo; - } - - /** - * Gets the map from the registers (in the caller's frame) to the slots where they are saved in - * the current frame. If no such information is available, {@code null} is returned. - */ - public RegisterSaveLayout getCalleeSaveInfo() { - return calleeSaveInfo; - } - - @Override - public int hashCode() { - throw new UnsupportedOperationException("hashCode"); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof DebugInfo) { - DebugInfo that = (DebugInfo) obj; - if (Objects.equals(this.bytecodePosition, that.bytecodePosition) && Objects.equals(this.calleeSaveInfo, that.calleeSaveInfo) && Objects.equals(this.referenceMap, that.referenceMap)) { - return true; - } - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -/** - * Represents a compiled instance of a method. It may have been invalidated or removed in the - * meantime. - */ -public class InstalledCode { - - /** - * Raw address address of entity representing this installed code. - */ - protected long address; - - /** - * Raw address of entryPoint of this installed code. - */ - protected long entryPoint; - - /** - * Counts how often the address field was reassigned. - */ - protected long version; - - protected final String name; - - public InstalledCode(String name) { - this.name = name; - } - - /** - * @return the address of entity representing this installed code. - */ - public long getAddress() { - return address; - } - - /** - * @return the address of the normal entry point of the installed code. - */ - public long getEntryPoint() { - return entryPoint; - } - - /** - * @return the version number of this installed code - */ - public final long getVersion() { - return version; - } - - /** - * Returns the name of this installed code. - */ - public String getName() { - return name; - } - - /** - * Returns the start address of this installed code if it is {@linkplain #isValid() valid}, 0 - * otherwise. - */ - public long getStart() { - return 0; - } - - /** - * @return true if the code represented by this object is still valid for invocation, false - * otherwise (may happen due to deopt, etc.) - */ - public boolean isValid() { - return entryPoint != 0; - } - - /** - * @return true if the code represented by this object still exists and might have live - * activations, false otherwise (may happen due to deopt, etc.) - */ - public boolean isAlive() { - return address != 0; - } - - /** - * Returns a copy of this installed code if it is {@linkplain #isValid() valid}, null otherwise. - */ - public byte[] getCode() { - return null; - } - - /** - * Invalidates this installed code such that any subsequent - * {@linkplain #executeVarargs(Object...) invocation} will throw an - * {@link InvalidInstalledCodeException} and all existing invocations will be deoptimized. - */ - public void invalidate() { - throw new UnsupportedOperationException(); - } - - /** - * Executes the installed code with a variable number of arguments. - * - * @param args the array of object arguments - * @return the value returned by the executed code - */ - @SuppressWarnings("unused") - public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { - throw new UnsupportedOperationException(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InvalidInstalledCodeException.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InvalidInstalledCodeException.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InvalidInstalledCodeException.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InvalidInstalledCodeException.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -/** - * Exception thrown by the runtime in case an invalidated machine code is called. - */ -public final class InvalidInstalledCodeException extends Exception { - - public InvalidInstalledCodeException() { - } - - public InvalidInstalledCodeException(String message) { - super(message); - } - - private static final long serialVersionUID = -3540232440794244844L; -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Location.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Location.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Location.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Location.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +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. - */ -package jdk.vm.ci.code; - -/** - * Represents a location where a value can be stored. This can be either a {@link Register} or a - * stack slot. - */ -public final class Location { - - public final Register reg; - public final int offset; - - private Location(Register reg, int offset) { - this.reg = reg; - this.offset = offset; - } - - /** - * Create a {@link Location} for a register. - */ - public static Location register(Register reg) { - return new Location(reg, 0); - } - - /** - * Create a {@link Location} for a vector subregister. - * - * @param reg the {@link Register vector register} - * @param offset the offset in bytes into the vector register - */ - public static Location subregister(Register reg, int offset) { - return new Location(reg, offset); - } - - /** - * Create a {@link Location} for a stack slot. - */ - public static Location stack(int offset) { - return new Location(null, offset); - } - - public boolean isRegister() { - return reg != null; - } - - public boolean isStack() { - return reg == null; - } - - @Override - public String toString() { - String regName; - if (isRegister()) { - regName = reg.name + ":"; - } else { - regName = "stack:"; - } - return regName + offset; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -/** - * Constants and intrinsic definition for memory barriers. - * - * The documentation for each constant is taken from Doug Lea's - * The JSR-133 Cookbook for Compiler - * Writers. - *

    - * The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory - * Model with respect to volatile field accesses. Their values are explained by this comment from - * templateTable_i486.cpp in the HotSpot source code: - * - *

    - * Volatile variables demand their effects be made known to all CPU's in
    - * order.  Store buffers on most chips allow reads & writes to reorder; the
    - * JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
    - * memory barrier (i.e., it's not sufficient that the interpreter does not
    - * reorder volatile references, the hardware also must not reorder them).
    - *
    - * According to the new Java Memory Model (JMM):
    - * (1) All volatiles are serialized wrt to each other.
    - * ALSO reads & writes act as acquire & release, so:
    - * (2) A read cannot let unrelated NON-volatile memory refs that happen after
    - * the read float up to before the read.  It's OK for non-volatile memory refs
    - * that happen before the volatile read to float down below it.
    - * (3) Similarly, a volatile write cannot let unrelated NON-volatile memory refs
    - * that happen BEFORE the write float down to after the write.  It's OK for
    - * non-volatile memory refs that happen after the volatile write to float up
    - * before it.
    - *
    - * We only put in barriers around volatile refs (they are expensive), not
    - * _between_ memory refs (which would require us to track the flavor of the
    - * previous memory refs).  Requirements (2) and (3) require some barriers
    - * before volatile stores and after volatile loads.  These nearly cover
    - * requirement (1) but miss the volatile-store-volatile-load case.  This final
    - * case is placed after volatile-stores although it could just as well go
    - * before volatile-loads.
    - * 
    - */ -public class MemoryBarriers { - - /** - * The sequence {@code Load1; LoadLoad; Load2} ensures that {@code Load1}'s data are loaded - * before data accessed by {@code Load2} and all subsequent load instructions are loaded. In - * general, explicit {@code LoadLoad} barriers are needed on processors that perform speculative - * loads and/or out-of-order processing in which waiting load instructions can bypass waiting - * stores. On processors that guarantee to always preserve load ordering, these barriers amount - * to no-ops. - */ - public static final int LOAD_LOAD = 0x0001; - - /** - * The sequence {@code Load1; LoadStore; Store2} ensures that {@code Load1}'s data are loaded - * before all data associated with {@code Store2} and subsequent store instructions are flushed. - * {@code LoadStore} barriers are needed only on those out-of-order processors in which waiting - * store instructions can bypass loads. - */ - public static final int LOAD_STORE = 0x0002; - - /** - * The sequence {@code Store1; StoreLoad; Load2} ensures that {@code Store1}'s data are made - * visible to other processors (i.e., flushed to main memory) before data accessed by - * {@code Load2} and all subsequent load instructions are loaded. {@code StoreLoad} barriers - * protect against a subsequent load incorrectly using {@code Store1}'s data value rather than - * that from a more recent store to the same location performed by a different processor. - * Because of this, on the processors discussed below, a {@code StoreLoad} is strictly necessary - * only for separating stores from subsequent loads of the same location(s) as were stored - * before the barrier. {@code StoreLoad} barriers are needed on nearly all recent - * multiprocessors, and are usually the most expensive kind. Part of the reason they are - * expensive is that they must disable mechanisms that ordinarily bypass cache to satisfy loads - * from write-buffers. This might be implemented by letting the buffer fully flush, among other - * possible stalls. - */ - public static final int STORE_LOAD = 0x0004; - - /** - * The sequence {@code Store1; StoreStore; Store2} ensures that {@code Store1}'s data are - * visible to other processors (i.e., flushed to memory) before the data associated with - * {@code Store2} and all subsequent store instructions. In general, {@code StoreStore} barriers - * are needed on processors that do not otherwise guarantee strict ordering of flushes from - * write buffers and/or caches to other processors or main memory. - */ - public static final int STORE_STORE = 0x0008; - - public static final int JMM_PRE_VOLATILE_WRITE = LOAD_STORE | STORE_STORE; - public static final int JMM_POST_VOLATILE_WRITE = STORE_LOAD | STORE_STORE; - public static final int JMM_PRE_VOLATILE_READ = 0; - public static final int JMM_POST_VOLATILE_READ = LOAD_LOAD | LOAD_STORE; - - public static String barriersString(int barriers) { - StringBuilder sb = new StringBuilder(); - sb.append((barriers & LOAD_LOAD) != 0 ? "LOAD_LOAD " : ""); - sb.append((barriers & LOAD_STORE) != 0 ? "LOAD_STORE " : ""); - sb.append((barriers & STORE_LOAD) != 0 ? "STORE_LOAD " : ""); - sb.append((barriers & STORE_STORE) != 0 ? "STORE_STORE " : ""); - return sb.toString().trim(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 that defines the interface between a Java application that wants to install code and the - * runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider} - * interface. The method - * {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)} - * can be used to install code. - */ -package jdk.vm.ci.code; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ReferenceMap.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ReferenceMap.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ReferenceMap.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ReferenceMap.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.code; - -/** - * Marker type for an object containing information about where the object references are in machine - * state (e.g., registers or stack locations). This is typically associated with an execution point - * in compiled code. - */ -public abstract class ReferenceMap { -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterArray.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterArray.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterArray.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterArray.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * An immutable ordered list of registers. Only required because Java lacks immutable arrays. - */ -public final class RegisterArray implements Iterable { - - private final Register[] registers; - private int hash; - - public RegisterArray(Register... registers) { - this.registers = registers; - } - - public RegisterArray(Collection registers) { - this.registers = registers.toArray(new Register[registers.size()]); - } - - /** - * Gets the number of registers. - */ - public int size() { - return registers.length; - } - - /** - * Gets the register at a given index. - * - * @param index the index of the register to retrieve - */ - public Register get(int index) { - return registers[index]; - } - - public void addTo(Collection collection) { - collection.addAll(Arrays.asList(registers)); - } - - /** - * Gets an immutable view of the registers as a list. - */ - public List asList() { - return Collections.unmodifiableList(Arrays.asList(registers)); - } - - /** - * Gets a copy of the registers as an array. - */ - public Register[] toArray() { - return registers.clone(); - } - - @Override - public Iterator iterator() { - return Arrays.asList(registers).iterator(); - } - - @Override - public int hashCode() { - if (hash == 0 && registers.length > 0) { - hash = Arrays.hashCode(registers); - } - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof RegisterArray) { - return Arrays.equals(registers, ((RegisterArray) obj).registers); - } - return false; - } - - @Override - public String toString() { - return Arrays.toString(registers); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterAttributes.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterAttributes.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterAttributes.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterAttributes.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * A collection of register attributes. The specific attribute values for a register may be local to - * a compilation context. For example, a {@link RegisterConfig} in use during a compilation will - * determine which registers are callee saved. - */ -public class RegisterAttributes { - - private final boolean callerSave; - private final boolean calleeSave; - private final boolean allocatable; - - public RegisterAttributes(boolean isCallerSave, boolean isCalleeSave, boolean isAllocatable) { - this.callerSave = isCallerSave; - this.calleeSave = isCalleeSave; - this.allocatable = isAllocatable; - } - - public static final RegisterAttributes NONE = new RegisterAttributes(false, false, false); - - /** - * Creates a map from register {@linkplain Register#number numbers} to register - * {@linkplain RegisterAttributes attributes} for a given register configuration and set of - * registers. - * - * @param registerConfig a register configuration - * @param registers a set of registers - * @return an array whose length is the max register number in {@code registers} plus 1. An - * element at index i holds the attributes of the register whose number is i. - */ - public static RegisterAttributes[] createMap(RegisterConfig registerConfig, RegisterArray registers) { - RegisterAttributes[] map = new RegisterAttributes[registers.size()]; - List callerSaveRegisters = registerConfig.getCallerSaveRegisters().asList(); - List calleeSaveRegisters = registerConfig.getCalleeSaveRegisters() == null ? Collections.emptyList() : registerConfig.getCalleeSaveRegisters().asList(); - List allocatableRegisters = registerConfig.getAllocatableRegisters().asList(); - for (Register reg : registers) { - if (reg != null) { - RegisterAttributes attr = new RegisterAttributes(callerSaveRegisters.contains(reg), calleeSaveRegisters.contains(reg), allocatableRegisters.contains(reg)); - if (map.length <= reg.number) { - map = Arrays.copyOf(map, reg.number + 1); - } - map[reg.number] = attr; - } - } - for (int i = 0; i < map.length; i++) { - if (map[i] == null) { - map[i] = NONE; - } - } - return map; - } - - /** - * @return {@code true} if a register is available for use by a register allocator otherwise - * {@code false} - */ - public boolean isAllocatable() { - return allocatable; - } - - /** - * @return {@code true} if a register whose value preservation (if required) across a call is - * the responsibility of the callee otherwise {@code false} - */ - public boolean isCalleeSave() { - return calleeSave; - } - - /** - * @return {@code true} if a register whose value preservation (if required) across a call is - * the responsibility of the caller otherwise {@code false} - */ - public boolean isCallerSave() { - return callerSave; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.code.CallingConvention.Type; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.PlatformKind; -import jdk.vm.ci.meta.ValueKind; - -/** - * A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical - * registers. - */ -public interface RegisterConfig { - - /** - * Gets the register to be used for returning a value of a given kind. - */ - Register getReturnRegister(JavaKind kind); - - /** - * Gets the maximum allowed size of the frame. - */ - default int getMaximumFrameSize() { - return Integer.MAX_VALUE; - } - - /** - * Gets the register used as the frame pointer. Spill slots and outgoing stack-based arguments - * are addressed relative to this register. - */ - Register getFrameRegister(); - - /** - * Gets the calling convention describing how arguments are passed. - * - * @param type the type of calling convention being requested - * @param returnType the return type (can be null for methods returning {@code void}) - * @param parameterTypes the types of the arguments of the call - * @param valueKindFactory the factory to create custom {@link ValueKind ValueKinds} - */ - CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory valueKindFactory); - - /** - * Gets the ordered set of registers that are can be used to pass parameters according to a - * given calling convention. - * - * @param type the type of calling convention - * @param kind specifies what kind of registers is being requested - * @return the ordered set of registers that may be used to pass parameters in a call conforming - * to {@code type} - */ - RegisterArray getCallingConventionRegisters(Type type, JavaKind kind); - - /** - * Gets the set of all registers that might be used by the register allocator. - */ - RegisterArray getAllocatableRegisters(); - - /** - * Filters a set of registers and returns only those that can be used by the register allocator - * for a value of a particular kind. - */ - RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers); - - /** - * Gets the registers whose values must be preserved by a method across any call it makes. - */ - RegisterArray getCallerSaveRegisters(); - - /** - * Gets the registers whose values must be preserved by the callee. - */ - RegisterArray getCalleeSaveRegisters(); - - /** - * Gets a map from register {@linkplain Register#number numbers} to register - * {@linkplain RegisterAttributes attributes} for this register configuration. - * - * @return an array where an element at index i holds the attributes of the register whose - * number is i - */ - RegisterAttributes[] getAttributesMap(); - - /** - * Determines if all {@link #getAllocatableRegisters() allocatable} registers are - * {@link #getCallerSaveRegisters() caller saved}. - */ - boolean areAllAllocatableRegistersCallerSaved(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.meta.ValueKind; - -/** - * Represents a target machine register. - */ -public final class Register implements Comparable { - - public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL"); - - /** - * Invalid register. - */ - public static final Register None = new Register(-1, -1, "noreg", SPECIAL); - - /** - * The identifier for this register that is unique across all the registers in a - * {@link Architecture}. A valid register has {@code number >= 0}. - */ - public final int number; - - /** - * The mnemonic of this register. - */ - public final String name; - - /** - * The actual encoding in a target machine instruction for this register, which may or may not - * be the same as {@link #number}. - */ - public final int encoding; - - /** - * The assembler calls this method to get the register's encoding. - */ - public int encoding() { - return encoding; - } - - /** - * A platform specific register category that describes which values can be stored in a - * register. - */ - private final RegisterCategory registerCategory; - - /** - * A platform specific register type that describes which values can be stored in a register. - */ - public static class RegisterCategory { - - private final String name; - private final boolean mayContainReference; - - public RegisterCategory(String name) { - this(name, true); - } - - public RegisterCategory(String name, boolean mayContainReference) { - this.name = name; - this.mayContainReference = mayContainReference; - } - - @Override - public String toString() { - return name; - } - - @Override - public int hashCode() { - return 23 + name.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof RegisterCategory) { - RegisterCategory that = (RegisterCategory) obj; - return this.name.equals(that.name); - } - return false; - } - } - - /** - * Creates a {@link Register} instance. - * - * @param number unique identifier for the register - * @param encoding the target machine encoding for the register - * @param name the mnemonic name for the register - * @param registerCategory the register category - */ - public Register(int number, int encoding, String name, RegisterCategory registerCategory) { - this.number = number; - this.name = name; - this.registerCategory = registerCategory; - this.encoding = encoding; - } - - public RegisterCategory getRegisterCategory() { - return registerCategory; - } - - /** - * Determine whether this register needs to be part of the reference map. - */ - public boolean mayContainReference() { - return registerCategory.mayContainReference; - } - - /** - * Gets this register as a {@linkplain RegisterValue value} with a specified kind. - * - * @param kind the specified kind - * @return the {@link RegisterValue} - */ - public RegisterValue asValue(ValueKind kind) { - return new RegisterValue(kind, this); - } - - /** - * Gets this register as a {@linkplain RegisterValue value} with no particular kind. - * - * @return a {@link RegisterValue} with {@link ValueKind#Illegal} kind. - */ - public RegisterValue asValue() { - return asValue(ValueKind.Illegal); - } - - /** - * Determines if this is a valid register. - * - * @return {@code true} iff this register is valid - */ - public boolean isValid() { - return number >= 0; - } - - @Override - public String toString() { - return name; - } - - @Override - public int compareTo(Register o) { - if (number < o.number) { - return -1; - } - if (number > o.number) { - return 1; - } - return 0; - } - - @Override - public int hashCode() { - return 17 + name.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Register) { - Register other = (Register) obj; - if (number == other.number) { - assert name.equals(other.name); - assert encoding == other.encoding; - assert registerCategory.equals(other.registerCategory); - return true; - } - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterSaveLayout.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterSaveLayout.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterSaveLayout.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterSaveLayout.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.TreeMap; - -/** - * A map from registers to frame slots. This can be used to describe where callee saved registers - * are saved in a callee's frame. - */ -public final class RegisterSaveLayout { - - /** - * Keys. - */ - private final Register[] registers; - - /** - * Slot indexes relative to stack pointer. - */ - private final int[] slots; - - /** - * Creates a map from registers to frame slots. - * - * @param registers the keys in the map - * @param slots frame slot index for each register in {@code registers} - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `registers` and `slots`") - public RegisterSaveLayout(Register[] registers, int[] slots) { - assert registers.length == slots.length; - this.registers = registers; - this.slots = slots; - assert registersToSlots(false).size() == registers.length : "non-unique registers"; - assert new HashSet<>(registersToSlots(false).values()).size() == slots.length : "non-unqiue slots"; - } - - /** - * Gets the frame slot index for a given register. - * - * @param register register to get the frame slot index for - * @return frame slot index - */ - public int registerToSlot(Register register) { - for (int i = 0; i < registers.length; i++) { - if (register.equals(registers[i])) { - return slots[i]; - } - } - throw new IllegalArgumentException(register + " not saved by this layout: " + this); - } - - /** - * Gets this layout information as a {@link Map} from registers to slots. - */ - public Map registersToSlots(boolean sorted) { - Map result; - if (sorted) { - result = new TreeMap<>(); - } else { - result = new HashMap<>(); - } - for (int i = 0; i < registers.length; i++) { - result.put(registers[i], slots[i]); - } - return result; - } - - /** - * Gets this layout information as a {@link Map} from slots to registers. - */ - public Map slotsToRegisters(boolean sorted) { - Map result; - if (sorted) { - result = new TreeMap<>(); - } else { - result = new HashMap<>(); - } - for (int i = 0; i < registers.length; i++) { - result.put(slots[i], registers[i]); - } - return result; - } - - @Override - public int hashCode() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof RegisterSaveLayout) { - RegisterSaveLayout that = (RegisterSaveLayout) obj; - if (Arrays.equals(registers, that.registers) && Arrays.equals(slots, that.slots)) { - return true; - } - } - return false; - } - - @Override - public String toString() { - return registersToSlots(true).toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.ValueKind; - -/** - * Denotes a register that stores a value of a fixed kind. - */ -public final class RegisterValue extends AllocatableValue { - - private final Register reg; - - protected RegisterValue(ValueKind kind, Register register) { - super(kind); - this.reg = register; - } - - @Override - public String toString() { - return getRegister().name + getKindSuffix(); - } - - /** - * @return the register that contains the value - */ - public Register getRegister() { - return reg; - } - - @Override - public int hashCode() { - return 29 * super.hashCode() + reg.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof RegisterValue) { - RegisterValue other = (RegisterValue) obj; - return super.equals(obj) && reg.equals(other.reg); - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Call.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Call.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Call.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Call.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -import java.util.Objects; - -import jdk.vm.ci.code.DebugInfo; -import jdk.vm.ci.meta.InvokeTarget; - -/** - * Represents a call in the code. - */ -public final class Call extends Infopoint { - - /** - * The target of the call. - */ - public final InvokeTarget target; - - /** - * The size of the call instruction. - */ - public final int size; - - /** - * Specifies if this call is direct or indirect. A direct call has an immediate operand encoding - * the absolute or relative (to the call itself) address of the target. An indirect call has a - * register or memory operand specifying the target address of the call. - */ - public final boolean direct; - - public Call(InvokeTarget target, int pcOffset, int size, boolean direct, DebugInfo debugInfo) { - super(pcOffset, debugInfo, InfopointReason.CALL); - this.size = size; - this.target = target; - this.direct = direct; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof Call && super.equals(obj)) { - Call that = (Call) obj; - if (this.size == that.size && this.direct == that.direct && Objects.equals(this.target, that.target)) { - return true; - } - } - return false; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(pcOffset); - sb.append('['); - sb.append(target); - sb.append(']'); - - if (debugInfo != null) { - appendDebugInfo(sb, debugInfo); - } - - return sb.toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ConstantReference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ConstantReference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ConstantReference.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ConstantReference.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -import java.util.Objects; - -import jdk.vm.ci.meta.VMConstant; - -/** - * Represents an embedded {@link VMConstant} in the code or data section that needs to be - * {@link DataPatch patched} by the VM (e.g. an embedded pointer to a Java object). - */ -public final class ConstantReference extends Reference { - - private final VMConstant constant; - - public ConstantReference(VMConstant constant) { - this.constant = constant; - } - - public VMConstant getConstant() { - return constant; - } - - @Override - public String toString() { - return constant.toString(); - } - - @Override - public int hashCode() { - return constant.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof ConstantReference) { - ConstantReference that = (ConstantReference) obj; - return Objects.equals(this.constant, that.constant); - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataPatch.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataPatch.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataPatch.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataPatch.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -import java.util.Objects; - -import jdk.vm.ci.meta.VMConstant; - -/** - * Represents a code site that references some data. The associated data can be either a - * {@link DataSectionReference reference} to the data section, or it may be an inlined - * {@link VMConstant} that needs to be patched. - */ -public final class DataPatch extends Site { - - public Reference reference; - public Object note; - - public DataPatch(int pcOffset, Reference reference) { - super(pcOffset); - this.reference = reference; - this.note = null; - } - - public DataPatch(int pcOffset, Reference reference, Object note) { - super(pcOffset); - this.reference = reference; - this.note = note; - } - - @Override - public String toString() { - if (note != null) { - return String.format("%d[, note: %s]", pcOffset, reference.toString(), note.toString()); - } else { - return String.format("%d[]", pcOffset, reference.toString()); - } - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof DataPatch) { - DataPatch that = (DataPatch) obj; - if (this.pcOffset == that.pcOffset && Objects.equals(this.reference, that.reference) && Objects.equals(this.note, that.note)) { - return true; - } - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataSectionReference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataSectionReference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataSectionReference.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataSectionReference.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -/** - * Represents a pointer to some location in the data section that should be {@link DataPatch - * patched} into the code. - */ -public final class DataSectionReference extends Reference { - - private boolean initialized; - private int offset; - - public DataSectionReference() { - // will be set after the data section layout is fixed - offset = 0xDEADDEAD; - } - - public int getOffset() { - assert initialized; - - return offset; - } - - public void setOffset(int offset) { - assert !initialized; - initialized = true; - - this.offset = offset; - } - - @Override - public int hashCode() { - return offset; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof DataSectionReference) { - DataSectionReference that = (DataSectionReference) obj; - return this.offset == that.offset; - } - return false; - } - - @Override - public String toString() { - if (initialized) { - return String.format("DataSection[0x%x]", offset); - } else { - return "DataSection[?]"; - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ExceptionHandler.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ExceptionHandler.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ExceptionHandler.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ExceptionHandler.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -/** - * Represents exception handler information for a specific code position. It includes the catch code - * position as well as the caught exception type. - */ -public final class ExceptionHandler extends Site { - - public final int handlerPos; - - public ExceptionHandler(int pcOffset, int handlerPos) { - super(pcOffset); - this.handlerPos = handlerPos; - } - - @Override - public String toString() { - return String.format("%d[]", pcOffset, handlerPos); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof ExceptionHandler) { - ExceptionHandler that = (ExceptionHandler) obj; - if (this.pcOffset == that.pcOffset && this.handlerPos == that.handlerPos) { - return true; - } - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ImplicitExceptionDispatch.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 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. 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.vm.ci.code.site; - -import jdk.vm.ci.code.DebugInfo; - -/** - * Represents an implicit exception dispatch in the code. Implicit exception dispatch is a - * platform-specific optimization that makes use of an operating system's trap mechanism, to turn - * specific branches into sequential code with implicit traps. Information contained in this class - * will be used by the runtime to register implicit exception dispatch, i.e., a mapping from an - * exceptional PC offset to a continuation PC offset. - */ -public final class ImplicitExceptionDispatch extends Infopoint { - - public final int dispatchOffset; - - /** - * Construct an implicit exception dispatch. - * - * @param pcOffset the exceptional PC offset - * @param dispatchOffset the continuation PC offset - * @param debugInfo debugging information at the exceptional PC - */ - public ImplicitExceptionDispatch(int pcOffset, int dispatchOffset, DebugInfo debugInfo) { - super(pcOffset, debugInfo, InfopointReason.IMPLICIT_EXCEPTION); - this.dispatchOffset = dispatchOffset; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof ImplicitExceptionDispatch && super.equals(obj)) { - ImplicitExceptionDispatch that = (ImplicitExceptionDispatch) obj; - if (this.dispatchOffset == that.dispatchOffset) { - return true; - } - } - return false; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(pcOffset); - sb.append("->"); - sb.append(dispatchOffset); - - if (debugInfo != null) { - appendDebugInfo(sb, debugInfo); - } - - return sb.toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Infopoint.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Infopoint.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Infopoint.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Infopoint.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -import java.util.Map; -import java.util.Objects; - -import jdk.vm.ci.code.BytecodePosition; -import jdk.vm.ci.code.DebugInfo; -import jdk.vm.ci.code.ReferenceMap; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.RegisterSaveLayout; -import jdk.vm.ci.meta.MetaUtil; - -/** - * Represents an infopoint with associated debug info. Note that safepoints are also infopoints. - */ -public class Infopoint extends Site implements Comparable { - - public final DebugInfo debugInfo; - - public final InfopointReason reason; - - public Infopoint(int pcOffset, DebugInfo debugInfo, InfopointReason reason) { - super(pcOffset); - this.debugInfo = debugInfo; - this.reason = reason; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(pcOffset); - sb.append("[]"); - appendDebugInfo(sb, debugInfo); - return sb.toString(); - } - - @Override - public int compareTo(Infopoint o) { - if (pcOffset < o.pcOffset) { - return -1; - } else if (pcOffset > o.pcOffset) { - return 1; - } - return this.reason.compareTo(o.reason); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj != null && obj.getClass() == getClass()) { - Infopoint that = (Infopoint) obj; - if (this.pcOffset == that.pcOffset && Objects.equals(this.debugInfo, that.debugInfo) && Objects.equals(this.reason, that.reason)) { - return true; - } - } - return false; - } - - protected static void appendDebugInfo(StringBuilder sb, DebugInfo info) { - if (info != null) { - ReferenceMap refMap = info.getReferenceMap(); - if (refMap != null) { - sb.append(refMap.toString()); - sb.append(']'); - } - RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); - if (calleeSaveInfo != null) { - sb.append(" callee-save-info["); - String sep = ""; - for (Map.Entry e : calleeSaveInfo.registersToSlots(true).entrySet()) { - sb.append(sep).append(e.getKey()).append("->").append(e.getValue()); - sep = ", "; - } - sb.append(']'); - } - BytecodePosition codePos = info.getBytecodePosition(); - if (codePos != null) { - MetaUtil.appendLocation(sb.append(" "), codePos.getMethod(), codePos.getBCI()); - if (info.hasFrame()) { - sb.append(" #locals=").append(info.frame().numLocals).append(" #expr=").append(info.frame().numStack); - if (info.frame().numLocks > 0) { - sb.append(" #locks=").append(info.frame().numLocks); - } - } - } - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/InfopointReason.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/InfopointReason.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/InfopointReason.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/InfopointReason.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -/** - * A reason for infopoint insertion. - */ -public enum InfopointReason { - - SAFEPOINT, - CALL, - IMPLICIT_EXCEPTION, - METHOD_START, - METHOD_END, - BYTECODE_POSITION; -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Mark.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Mark.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Mark.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Mark.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -import java.util.Objects; - -/** - * Associates arbitrary information with a position in machine code. For example, HotSpot specific - * code in a compiler backend may use this to denote the position of a safepoint, exception handler - * entry point, verified entry point etc. - */ -public final class Mark extends Site { - - /** - * An object denoting extra semantic information about the machine code position of this mark. - */ - public final Object id; - - /** - * Creates a mark that associates {@code id} with the machine code position {@code pcOffset}. - * - * @param pcOffset - * @param id - */ - public Mark(int pcOffset, Object id) { - super(pcOffset); - this.id = id; - } - - @Override - public String toString() { - if (id == null) { - return String.format("%d[]", pcOffset); - } else if (id instanceof Integer) { - return String.format("%d[]", pcOffset, Integer.toHexString((Integer) id)); - } else { - return String.format("%d[]", pcOffset, id.toString()); - } - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof Mark) { - Mark that = (Mark) obj; - if (this.pcOffset == that.pcOffset && Objects.equals(this.id, that.id)) { - return true; - } - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ -/** - * Package that defines the information associated with various {@link jdk.vm.ci.code.site.Site - * sites} in generated code. - */ -package jdk.vm.ci.code.site; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Reference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Reference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Reference.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Reference.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -/** - * Represents some external data that is referenced by the code. - */ -public abstract class Reference { - - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object obj); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Site.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Site.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Site.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Site.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.site; - -import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString; - -/** - * Represents a code position with associated additional information. - */ -public abstract class Site { - - /** - * The position (or offset) of this site with respect to the start of the target method. - */ - public final int pcOffset; - - public Site(int pos) { - this.pcOffset = pos; - } - - @Override - public final int hashCode() { - throw new UnsupportedOperationException("hashCode"); - } - - @Override - public String toString() { - return identityHashCodeString(this); - } - - @Override - public abstract boolean equals(Object obj); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.stack; - -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * Access to the object variables in a stack frame. - */ -public interface InspectedFrame { - - /** - * Returns the value of the object local at {@code index}. This value is a copy iff - * {@link #isVirtual(int)} is true. - */ - Object getLocal(int index); - - /** - * Returns whether the local at {@code index} is a virtual object, and therefore the object - * returned by {@link #getLocal(int)} is a copy. - */ - boolean isVirtual(int index); - - /** - * Returns true if the stack frame is a compiled stack frame and there are virtual objects - * anywhere in the current state of the compiled method. This can return true even if - * {@link #isVirtual(int)} return false for all locals. - */ - boolean hasVirtualObjects(); - - /** - * This method will materialize all virtual objects, deoptimize the stack frame and make sure - * that subsequent execution of the deoptimized frame uses the materialized values. - */ - void materializeVirtualObjects(boolean invalidateCode); - - /** - * @return the current bytecode index - */ - int getBytecodeIndex(); - - /** - * @return the current method - */ - ResolvedJavaMethod getMethod(); - - /** - * Checks if the current method is equal to the given method. This is semantically equivalent to - * {@code method.equals(getMethod())}, but can be implemented more efficiently. - */ - boolean isMethod(ResolvedJavaMethod method); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrameVisitor.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrameVisitor.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrameVisitor.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrameVisitor.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.stack; - -/** - * Callback interface for {@link StackIntrospection#iterateFrames}. Implementations of - * {@link #visitFrame} return null to indicate that frame iteration should continue and the next - * caller frame should be visited; and return any non-null value to indicate that frame iteration - * should stop. - */ -public interface InspectedFrameVisitor { - - T visitFrame(InspectedFrame frame); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +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. - */ -/** - * Package that defines the interface for runtime stack introspection. - */ -package jdk.vm.ci.code.stack; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/StackIntrospection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/StackIntrospection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/StackIntrospection.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/StackIntrospection.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code.stack; - -import jdk.vm.ci.meta.ResolvedJavaMethod; - -public interface StackIntrospection { - - /** - * Walks the current stack, providing {@link InspectedFrame}s to the visitor that can be used to - * inspect the stack frame's contents. Iteration continues as long as - * {@link InspectedFrameVisitor#visitFrame}, which is invoked for every {@link InspectedFrame}, - * returns {@code null}. A non-null return value from {@link InspectedFrameVisitor#visitFrame} - * indicates that frame iteration should stop. - * - * @param initialMethods if this is non-{@code null}, then the stack walk will start at the - * first frame whose method is one of these methods. - * @param matchingMethods if this is non-{@code null}, then only frames whose methods are in - * this array are visited - * @param initialSkip the number of matching methods to skip (including the initial method) - * @param visitor the visitor that is called for every matching method - * @return the last result returned by the visitor (which is non-null to indicate that iteration - * should stop), or null if the whole stack was iterated. - */ - T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor visitor); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackLockValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackLockValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackLockValue.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackLockValue.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.JavaValue; -import jdk.vm.ci.meta.Value; - -/** - * Represents lock information in the debug information. - */ -public final class StackLockValue implements JavaValue { - - private JavaValue owner; - private AllocatableValue slot; - private final boolean eliminated; - - public StackLockValue(JavaValue object, AllocatableValue slot, boolean eliminated) { - this.owner = object; - this.slot = slot; - this.eliminated = eliminated; - } - - public JavaValue getOwner() { - return owner; - } - - public void setOwner(JavaValue newOwner) { - this.owner = newOwner; - } - - public Value getSlot() { - return slot; - } - - public boolean isEliminated() { - return eliminated; - } - - @Override - public String toString() { - return "monitor[" + owner + (slot != null ? ", " + slot : "") + (eliminated ? ", eliminated" : "") + "]"; - } - - @Override - public int hashCode() { - final int prime = 43; - int result = super.hashCode(); - result = prime * result + (eliminated ? 1231 : 1237); - result = prime * result + owner.hashCode(); - result = prime * result + slot.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof StackLockValue) { - StackLockValue other = (StackLockValue) obj; - return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot); - } - return false; - } - - public void setSlot(AllocatableValue stackSlot) { - slot = stackSlot; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.ValueKind; - -/** - * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an - * incoming stack-based argument in a method's {@linkplain #isInCallerFrame() caller's frame}. - */ -public final class StackSlot extends AllocatableValue { - - private final int offset; - private final boolean addFrameSize; - - /** - * Gets a {@link StackSlot} instance representing a stack slot at a given index holding a value - * of a given kind. - * - * @param kind The kind of the value stored in the stack slot. - * @param offset The offset of the stack slot (in bytes) - * @param addFrameSize Specifies if the offset is relative to the stack pointer, or the - * beginning of the frame (stack pointer + total frame size). - */ - public static StackSlot get(ValueKind kind, int offset, boolean addFrameSize) { - assert addFrameSize || offset >= 0; - return new StackSlot(kind, offset, addFrameSize); - } - - /** - * Private constructor to enforce use of {@link #get(ValueKind, int, boolean)} so that a cache - * can be used. - */ - private StackSlot(ValueKind kind, int offset, boolean addFrameSize) { - super(kind); - this.offset = offset; - this.addFrameSize = addFrameSize; - } - - /** - * Gets the offset of this stack slot, relative to the stack pointer. - * - * @return The offset of this slot (in bytes). - */ - public int getOffset(int totalFrameSize) { - assert totalFrameSize > 0 || !addFrameSize; - int result = offset + (addFrameSize ? totalFrameSize : 0); - assert result >= 0; - return result; - } - - public boolean isInCallerFrame() { - return addFrameSize && offset >= 0; - } - - public int getRawOffset() { - return offset; - } - - public boolean getRawAddFrameSize() { - return addFrameSize; - } - - @Override - public String toString() { - if (!addFrameSize) { - return "out:" + offset + getKindSuffix(); - } else if (offset >= 0) { - return "in:" + offset + getKindSuffix(); - } else { - return "stack:" + (-offset) + getKindSuffix(); - } - } - - /** - * Gets this stack slot used to pass an argument from the perspective of a caller. - */ - public StackSlot asOutArg() { - assert offset >= 0; - if (addFrameSize) { - return get(getValueKind(), offset, false); - } - return this; - } - - /** - * Gets this stack slot used to pass an argument from the perspective of a callee. - */ - public StackSlot asInArg() { - assert offset >= 0; - if (!addFrameSize) { - return get(getValueKind(), offset, true); - } - return this; - } - - @Override - public int hashCode() { - final int prime = 37; - int result = super.hashCode(); - result = prime * result + (addFrameSize ? 1231 : 1237); - result = prime * result + offset; - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof StackSlot) { - StackSlot other = (StackSlot) obj; - return super.equals(obj) && addFrameSize == other.addFrameSize && offset == other.offset; - } - return false; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SuppressFBWarnings.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -/** - * Used to suppress FindBugs warnings. - */ -@interface SuppressFBWarnings { - /** - * The set of FindBugs - * warnings that are to be - * suppressed in annotated element. The value can be a bug category, kind or pattern. - */ - String[] value(); - - /** - * Reason why the warning is suppressed. - */ - String justification(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString; - -import jdk.vm.ci.meta.JavaKind; - -/** - * Represents the target machine for a compiler, including the CPU architecture, the size of - * pointers and references, alignment of stacks, caches, etc. - */ -public class TargetDescription { - - public final Architecture arch; - - /** - * Specifies if this is a multi-processor system. - */ - public final boolean isMP; - - /** - * Specifies if this target supports encoding objects inline in the machine code. - */ - public final boolean inlineObjects; - - /** - * The machine word size on this target. - */ - public final int wordSize; - - /** - * The {@link JavaKind} to be used for representing raw pointers and CPU registers in Java code. - */ - public final JavaKind wordJavaKind; - - /** - * The stack alignment requirement of the platform. For example, from Appendix D of - * Intel 64 and IA-32 Architectures - * Optimization Reference Manual: - * - *
    -     *     "It is important to ensure that the stack frame is aligned to a
    -     *      16-byte boundary upon function entry to keep local __m128 data,
    -     *      parameters, and XMM register spill locations aligned throughout
    -     *      a function invocation."
    -     * 
    - */ - public final int stackAlignment; - - /** - * Maximum constant displacement at which a memory access can no longer be an implicit null - * check. - */ - public final int implicitNullCheckLimit; - - public TargetDescription(Architecture arch, boolean isMP, int stackAlignment, int implicitNullCheckLimit, boolean inlineObjects) { - this.arch = arch; - this.isMP = isMP; - this.wordSize = arch.getWordSize(); - this.wordJavaKind = JavaKind.fromWordSize(wordSize); - this.stackAlignment = stackAlignment; - this.implicitNullCheckLimit = implicitNullCheckLimit; - this.inlineObjects = inlineObjects; - - assert arch.getPlatformKind(wordJavaKind).equals(arch.getWordKind()); - } - - @Override - public final int hashCode() { - throw new UnsupportedOperationException(); - } - - @Override - public final boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof TargetDescription) { - TargetDescription that = (TargetDescription) obj; - // @formatter:off - if (this.implicitNullCheckLimit == that.implicitNullCheckLimit && - this.inlineObjects == that.inlineObjects && - this.isMP == that.isMP && - this.stackAlignment == that.stackAlignment && - this.wordJavaKind.equals(that.wordJavaKind) && - this.wordSize == that.wordSize && - this.arch.equals(that.arch)) { - return true; - } - // @formatter:on - } - return false; - } - - @Override - public String toString() { - return identityHashCodeString(this); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ValueKind; - -/** - * Can be implemented by compilers to create custom {@link ValueKind} subclasses. - */ -public interface ValueKindFactory> { - - K getValueKind(JavaKind javaKind); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ -package jdk.vm.ci.code; - -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaValue; -import jdk.vm.ci.meta.PlatformKind; -import jdk.vm.ci.meta.Value; - -/** - * Utility class for working with the {@link Value} class and its subclasses. - */ -public final class ValueUtil { - - public static boolean isIllegal(Value value) { - assert value != null; - return Value.ILLEGAL.equals(value); - } - - public static boolean isIllegalJavaValue(JavaValue value) { - assert value != null; - return Value.ILLEGAL.equals(value); - } - - public static boolean isLegal(Value value) { - return !isIllegal(value); - } - - public static boolean isVirtualObject(JavaValue value) { - assert value != null; - return value instanceof VirtualObject; - } - - public static VirtualObject asVirtualObject(JavaValue value) { - assert value != null; - return (VirtualObject) value; - } - - public static boolean isConstantJavaValue(JavaValue value) { - assert value != null; - return value instanceof JavaConstant; - } - - public static JavaConstant asConstantJavaValue(JavaValue value) { - assert value != null; - return (JavaConstant) value; - } - - public static boolean isAllocatableValue(Value value) { - assert value != null; - return value instanceof AllocatableValue; - } - - public static AllocatableValue asAllocatableValue(Value value) { - assert value != null; - return (AllocatableValue) value; - } - - public static boolean isStackSlot(Value value) { - assert value != null; - return value instanceof StackSlot; - } - - public static StackSlot asStackSlot(Value value) { - assert value != null; - return (StackSlot) value; - } - - public static boolean isRegister(Value value) { - assert value != null; - return value instanceof RegisterValue; - } - - public static Register asRegister(Value value) { - return asRegisterValue(value).getRegister(); - } - - public static RegisterValue asRegisterValue(Value value) { - assert value != null; - return (RegisterValue) value; - } - - public static Register asRegister(Value value, PlatformKind kind) { - if (value.getPlatformKind() != kind) { - throw new InternalError("needed: " + kind + " got: " + value.getPlatformKind()); - } else { - return asRegister(value); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,314 +0,0 @@ -/* - * Copyright (c) 2010, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.code; - -import java.util.Collections; -import java.util.IdentityHashMap; -import java.util.Set; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaValue; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * An instance of this class represents an object whose allocation was removed by escape analysis. - * The information stored in the {@link VirtualObject} is used during deoptimization to recreate the - * object. - */ -public final class VirtualObject implements JavaValue { - - private final ResolvedJavaType type; - private JavaValue[] values; - private JavaKind[] slotKinds; - private final int id; - private boolean isAutoBox; - - /** - * Creates a new {@link VirtualObject} for the given type, with the given fields. If - * {@code type} is an instance class then {@code values} provides the values for the fields - * returned by {@link ResolvedJavaType#getInstanceFields(boolean) getInstanceFields(true)}. If - * {@code type} is an array then the length of the values array determines the reallocated array - * length. - * - * @param type the type of the object whose allocation was removed during compilation. This can - * be either an instance of an array type. - * @param id a unique id that identifies the object within the debug information for one - * position in the compiled code. - * @return a new {@link VirtualObject} instance. - */ - public static VirtualObject get(ResolvedJavaType type, int id) { - return new VirtualObject(type, id, false); - } - - /** - * Creates a new {@link VirtualObject} for the given type, with the given fields. If - * {@code type} is an instance class then {@code values} provides the values for the fields - * returned by {@link ResolvedJavaType#getInstanceFields(boolean) getInstanceFields(true)}. If - * {@code type} is an array then the length of the values array determines the reallocated array - * length. - * - * @param type the type of the object whose allocation was removed during compilation. This can - * be either an instance of an array type. - * @param id a unique id that identifies the object within the debug information for one - * position in the compiled code. - * @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and - * that it possibly needs to be obtained for the box cache instead of creating a new - * instance. - * @return a new {@link VirtualObject} instance. - */ - public static VirtualObject get(ResolvedJavaType type, int id, boolean isAutoBox) { - return new VirtualObject(type, id, isAutoBox); - } - - private VirtualObject(ResolvedJavaType type, int id, boolean isAutoBox) { - this.type = type; - this.id = id; - this.isAutoBox = isAutoBox; - } - - private static StringBuilder appendValue(StringBuilder buf, JavaValue value, Set visited) { - if (value instanceof VirtualObject) { - VirtualObject vo = (VirtualObject) value; - buf.append("vobject:").append(vo.type.toJavaName(false)).append(':').append(vo.id); - if (!visited.contains(vo)) { - visited.add(vo); - buf.append('{'); - if (vo.values == null) { - buf.append(""); - } else { - if (vo.type.isArray()) { - for (int i = 0; i < vo.values.length; i++) { - if (i != 0) { - buf.append(','); - } - buf.append(i).append('='); - appendValue(buf, vo.values[i], visited); - } - } else { - ResolvedJavaField[] fields = vo.type.getInstanceFields(true); - int fieldIndex = 0; - for (int i = 0; i < vo.values.length; i++, fieldIndex++) { - if (i != 0) { - buf.append(','); - } - if (fieldIndex >= fields.length) { - buf.append(""); - } else { - ResolvedJavaField field = fields[fieldIndex]; - buf.append(field.getName()); - if (vo.slotKinds[i].getSlotCount() == 2 && field.getType().getJavaKind().getSlotCount() == 1) { - if (fieldIndex + 1 >= fields.length) { - buf.append("/"); - } else { - ResolvedJavaField field2 = fields[++fieldIndex]; - buf.append('/').append(field2.getName()); - } - } - } - buf.append('='); - appendValue(buf, vo.values[i], visited); - } - // Extra fields - for (; fieldIndex < fields.length; fieldIndex++) { - buf.append(fields[fieldIndex].getName()).append("="); - } - } - } - buf.append('}'); - } - } else { - buf.append(value); - } - return buf; - } - - public interface LayoutVerifier { - int getOffset(ResolvedJavaField field); - - default JavaKind getStorageKind(ResolvedJavaField field) { - return field.getType().getJavaKind(); - } - } - - public void verifyLayout(LayoutVerifier verifier) { - if (!type.isArray()) { - ResolvedJavaField[] fields = type.getInstanceFields(true); - int fieldIndex = 0; - for (int i = 0; i < values.length; i++, fieldIndex++) { - JavaKind slotKind = slotKinds[i]; - if (fieldIndex >= fields.length) { - throw new JVMCIError("Not enough fields for the values provided for %s", toString()); - } else { - ResolvedJavaField field = fields[fieldIndex]; - JavaKind fieldKind = verifier.getStorageKind(field); - if (slotKind.getSlotCount() == 2 && fieldKind == JavaKind.Int) { - int offset = verifier.getOffset(field); - if (offset % 8 != 0) { - throw new JVMCIError("Double word value stored across two ints must be aligned %s", toString()); - } - - if (fieldIndex + 1 >= fields.length) { - throw new JVMCIError("Missing second field for double word value stored in two ints %s", toString()); - } - ResolvedJavaField field2 = fields[fieldIndex + 1]; - if (field2.getType().getJavaKind() != JavaKind.Int) { - throw new JVMCIError("Second field for double word value stored in two ints must be int but got %s in %s", field2.getType().getJavaKind(), toString()); - } - int offset2 = verifier.getOffset(field2); - if (offset + 4 != offset2) { - throw new JVMCIError("Double word value stored across two ints must be sequential %s", toString()); - } - fieldIndex++; - } else if (fieldKind.getStackKind() != slotKind.getStackKind()) { - throw new JVMCIError("Expected value of kind %s but got %s for field %s in %s", fieldKind, slotKind, field, toString()); - } - } - } - // Extra fields - if (fieldIndex < fields.length) { - throw new JVMCIError("Not enough values provided for fields in %s", this); - } - } else if (type.getComponentType().getJavaKind() == JavaKind.Byte) { - for (int i = 0; i < values.length;) { - JavaKind slotkind = slotKinds[i]; - if (slotkind != JavaKind.Byte) { - if (!slotkind.isPrimitive()) { - throw new JVMCIError("Storing a non-primitive in a byte array: %s %s", slotkind, toString()); - } - int byteCount = 1; - while (++i < values.length && slotKinds[i] == JavaKind.Illegal) { - byteCount++; - } - /* - * Checks: a) The byte count is a valid count (ie: power of two), b) if the kind - * was not erased to int (happens for regular byte array accesses), check that - * the count is correct, c) No writes spanning more than a long. - */ - if (!CodeUtil.isPowerOf2(byteCount) || (slotkind.getStackKind() != JavaKind.Int && byteCount != slotkind.getByteCount()) || byteCount > JavaKind.Long.getByteCount()) { - throw new JVMCIError("Invalid number of illegals to reconstruct a byte array: %s in %s", byteCount, toString()); - } - continue; - } - i++; - } - } - } - - @Override - public String toString() { - Set visited = Collections.newSetFromMap(new IdentityHashMap()); - return appendValue(new StringBuilder(), this, visited).toString(); - } - - /** - * Returns the type of the object whose allocation was removed during compilation. This can be - * either an instance of an array type. - */ - public ResolvedJavaType getType() { - return type; - } - - /** - * Returns the array containing all the values to be stored into the object when it is - * recreated. This field is intentional exposed as a mutable array that a compiler may modify - * (e.g. during register allocation). - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "`values` is intentional mutable")// - public JavaValue[] getValues() { - return values; - } - - /** - * Returns the kind of the value at {@code index}. - */ - public JavaKind getSlotKind(int index) { - return slotKinds[index]; - } - - /** - * Returns the unique id that identifies the object within the debug information for one - * position in the compiled code. - */ - public int getId() { - return id; - } - - /** - * Returns true if the object is a box. For boxes the deoptimization would check if the value of - * the box is in the cache range and try to return a cached object. - */ - public boolean isAutoBox() { - return isAutoBox; - } - - /** - * Overwrites the current set of values with a new one. - * - * @param values an array containing all the values to be stored into the object when it is - * recreated. - * @param slotKinds an array containing the Java kinds of the values. This must have the same - * length as {@code values}. This array is now owned by this object and must not be - * mutated by the caller. - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `slotKinds`") - public void setValues(JavaValue[] values, JavaKind[] slotKinds) { - assert values.length == slotKinds.length; - this.values = values; - this.slotKinds = slotKinds; - } - - @Override - public int hashCode() { - return 42 + type.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o instanceof VirtualObject) { - VirtualObject l = (VirtualObject) o; - if (!l.type.equals(type) || l.values.length != values.length) { - return false; - } - for (int i = 0; i < values.length; i++) { - /* - * Virtual objects can form cycles. Calling equals() could therefore lead to - * infinite recursion. - */ - if (!same(values[i], l.values[i])) { - return false; - } - } - return true; - } - return false; - } - - private static boolean same(Object o1, Object o2) { - return o1 == o2; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/InitTimer.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/InitTimer.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/InitTimer.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/InitTimer.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2014, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.common; - -import java.util.concurrent.atomic.AtomicInteger; - -import jdk.vm.ci.services.Services; - -/** - * A facility for timing a step in the runtime initialization sequence. This is independent from all - * other JVMCI code so as to not perturb the initialization sequence. It is enabled by setting the - * {@code "jvmci.inittimer"} system property to {@code "true"}. - */ -public final class InitTimer implements AutoCloseable { - private final String name; - private final long start; - - private InitTimer(String name) { - int n = nesting.getAndIncrement(); - if (n == 0) { - initializingThread = Thread.currentThread(); - System.out.println("INITIALIZING THREAD: " + initializingThread); - } else { - assert Thread.currentThread() == initializingThread : Thread.currentThread() + " != " + initializingThread; - } - this.name = name; - this.start = System.currentTimeMillis(); - System.out.println("START: " + SPACES.substring(0, n * 2) + name); - } - - @Override - @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "only the initializing thread accesses this field") - public void close() { - final long end = System.currentTimeMillis(); - int n = nesting.decrementAndGet(); - System.out.println(" DONE: " + SPACES.substring(0, n * 2) + name + " [" + (end - start) + " ms]"); - if (n == 0) { - initializingThread = null; - } - } - - public static InitTimer timer(String name) { - return isEnabled() ? new InitTimer(name) : null; - } - - public static InitTimer timer(String name, Object suffix) { - return isEnabled() ? new InitTimer(name + suffix) : null; - } - - /** - * Determines if initialization timing is enabled. Note: This property cannot use - * {@code HotSpotJVMCIRuntime.Option} since that class is not visible from this package. - */ - private static boolean isEnabled() { - if (enabledPropertyValue == null) { - enabledPropertyValue = Boolean.parseBoolean(Services.getSavedProperty("jvmci.InitTimer")); - nesting = new AtomicInteger(); - } - return enabledPropertyValue; - } - - /** - * Cache for value of {@code jvmci.InitTimer} system property. - */ - @NativeImageReinitialize private static Boolean enabledPropertyValue; - - private static AtomicInteger nesting; - private static final String SPACES = " "; - - /** - * Used to assert the invariant that all related initialization happens on the same thread. - */ - static Thread initializingThread; -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.common; - -import java.util.ArrayList; -import java.util.Locale; - -/** - * Indicates a condition in JVMCI related code that should never occur during normal operation. - */ -public class JVMCIError extends Error { - - private static final long serialVersionUID = 531632331813456233L; - - public static RuntimeException unimplemented() { - throw new JVMCIError("unimplemented"); - } - - public static RuntimeException unimplemented(String msg) { - throw new JVMCIError("unimplemented: %s", msg); - } - - public static RuntimeException shouldNotReachHere() { - throw new JVMCIError("should not reach here"); - } - - public static RuntimeException shouldNotReachHere(String msg) { - throw new JVMCIError("should not reach here: %s", msg); - } - - public static RuntimeException shouldNotReachHere(Throwable cause) { - throw new JVMCIError(cause); - } - - /** - * Checks a given condition and throws a {@link JVMCIError} if it is false. Guarantees are - * stronger than assertions in that they are always checked. Error messages for guarantee - * violations should clearly indicate the nature of the problem as well as a suggested solution - * if possible. - * - * @param condition the condition to check - * @param msg the message that will be associated with the error, in - * {@link String#format(String, Object...)} syntax - * @param args arguments to the format string - */ - public static void guarantee(boolean condition, String msg, Object... args) { - if (!condition) { - throw new JVMCIError("failed guarantee: " + msg, args); - } - } - - /** - * This constructor creates a {@link JVMCIError} with a given message. - * - * @param msg the message that will be associated with the error - */ - public JVMCIError(String msg) { - super(msg); - } - - /** - * This constructor creates a {@link JVMCIError} with a message assembled via - * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to - * always generate the same output. - * - * @param msg the message that will be associated with the error, in String.format syntax - * @param args parameters to String.format - parameters that implement {@link Iterable} will be - * expanded into a [x, x, ...] representation. - */ - public JVMCIError(String msg, Object... args) { - super(format(msg, args)); - } - - /** - * This constructor creates a {@link JVMCIError} for a given causing Throwable instance. - * - * @param cause the original exception that contains additional information on this error - */ - public JVMCIError(Throwable cause) { - super(cause); - } - - private static String format(String msg, Object... args) { - if (args != null) { - // expand Iterable parameters into a list representation - for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Iterable) { - ArrayList list = new ArrayList<>(); - for (Object o : (Iterable) args[i]) { - list.add(o); - } - args[i] = list.toString(); - } - } - } - return String.format(Locale.ENGLISH, msg, args); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/NativeImageReinitialize.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/NativeImageReinitialize.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/NativeImageReinitialize.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/NativeImageReinitialize.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.common; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Denotes a field that should have the default value for its type in an ahead of time image. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD}) -public @interface NativeImageReinitialize { -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * Common utility classes used by the JVMCI API. - */ -package jdk.vm.ci.common; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/SuppressFBWarnings.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.common; - -/** - * Used to suppress FindBugs warnings. - */ -@interface SuppressFBWarnings { - /** - * The set of FindBugs - * warnings that are to be - * suppressed in annotated element. The value can be a bug category, kind or pattern. - */ - String[] value(); - - /** - * Reason why the warning is suppressed. - */ - String justification(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; - -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * A cleaner tracks a referent object and includes some {@linkplain #doCleanup() cleanup code} that - * is run some time after the referent object has become weakly-reachable. - * - * This is like {@link java.lang.ref.Cleaner} but with weak semantics instead of phantom. Objects - * referenced by this might be referenced by {@link ResolvedJavaType} which is kept alive by a - * {@link WeakReference} so we need equivalent reference strength. - */ -abstract class Cleaner extends WeakReference { - - /** - * Head of linked list of cleaners. - */ - @NativeImageReinitialize private static Cleaner first; - - /** - * Linked list pointers. - */ - private Cleaner next = null; - private Cleaner prev = null; - - Cleaner(Object referent) { - super(referent, queue); - add(this); - } - - private static synchronized Cleaner add(Cleaner cl) { - if (first != null) { - clean(); - } - if (first != null) { - cl.next = first; - first.prev = cl; - } - first = cl; - return cl; - } - - /** - * Removes {@code cl} from the linked list of cleaners. - */ - private static synchronized void remove(Cleaner cl) { - // If already removed, do nothing - if (cl.next == cl) { - return; - } - - // Update list - if (first == cl) { - if (cl.next != null) { - first = cl.next; - } else { - first = cl.prev; - } - } - if (cl.next != null) { - cl.next.prev = cl.prev; - } - if (cl.prev != null) { - cl.prev.next = cl.next; - } - - // Indicate removal by pointing the cleaner to itself - cl.next = cl; - cl.prev = cl; - } - - /** - * Performs the cleanup action now that this object's referent has become weakly reachable. - */ - abstract void doCleanup(); - - /** - * Remove the cleaners whose referents have become weakly reachable. - */ - static void clean() { - Cleaner c = (Cleaner) queue.poll(); - while (c != null) { - remove(c); - c.doCleanup(); - c = (Cleaner) queue.poll(); - } - } - - /** - * The {@link ReferenceQueue} to which {@link Cleaner}s are enqueued once their referents' - * become unreachable. - */ - private static final ReferenceQueue queue = new ReferenceQueue<>(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,1000 +0,0 @@ -/* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.common.InitTimer.timer; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import java.lang.reflect.Executable; -import java.lang.reflect.Field; - -import jdk.vm.ci.code.BytecodeFrame; -import jdk.vm.ci.code.InstalledCode; -import jdk.vm.ci.code.InvalidInstalledCodeException; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.stack.InspectedFrameVisitor; -import jdk.vm.ci.common.InitTimer; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * Calls from Java into HotSpot. The behavior of all the methods in this class that take a native - * pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not - * denote a valid native object. - */ -final class CompilerToVM { - /** - * Initializes the native part of the JVMCI runtime. - */ - private static native void registerNatives(); - - /** - * These values mirror the equivalent values from {@code Unsafe} but are appropriate for the JVM - * being compiled against. - */ - // Checkstyle: stop - final int ARRAY_BOOLEAN_BASE_OFFSET; - final int ARRAY_BYTE_BASE_OFFSET; - final int ARRAY_SHORT_BASE_OFFSET; - final int ARRAY_CHAR_BASE_OFFSET; - final int ARRAY_INT_BASE_OFFSET; - final int ARRAY_LONG_BASE_OFFSET; - final int ARRAY_FLOAT_BASE_OFFSET; - final int ARRAY_DOUBLE_BASE_OFFSET; - final int ARRAY_OBJECT_BASE_OFFSET; - final int ARRAY_BOOLEAN_INDEX_SCALE; - final int ARRAY_BYTE_INDEX_SCALE; - final int ARRAY_SHORT_INDEX_SCALE; - final int ARRAY_CHAR_INDEX_SCALE; - final int ARRAY_INT_INDEX_SCALE; - final int ARRAY_LONG_INDEX_SCALE; - final int ARRAY_FLOAT_INDEX_SCALE; - final int ARRAY_DOUBLE_INDEX_SCALE; - final int ARRAY_OBJECT_INDEX_SCALE; - // Checkstyle: resume - - @SuppressWarnings("try") - CompilerToVM() { - try (InitTimer t = timer("CompilerToVM.registerNatives")) { - registerNatives(); - ARRAY_BOOLEAN_BASE_OFFSET = arrayBaseOffset(JavaKind.Boolean); - ARRAY_BYTE_BASE_OFFSET = arrayBaseOffset(JavaKind.Byte); - ARRAY_SHORT_BASE_OFFSET = arrayBaseOffset(JavaKind.Short); - ARRAY_CHAR_BASE_OFFSET = arrayBaseOffset(JavaKind.Char); - ARRAY_INT_BASE_OFFSET = arrayBaseOffset(JavaKind.Int); - ARRAY_LONG_BASE_OFFSET = arrayBaseOffset(JavaKind.Long); - ARRAY_FLOAT_BASE_OFFSET = arrayBaseOffset(JavaKind.Float); - ARRAY_DOUBLE_BASE_OFFSET = arrayBaseOffset(JavaKind.Double); - ARRAY_OBJECT_BASE_OFFSET = arrayBaseOffset(JavaKind.Object); - ARRAY_BOOLEAN_INDEX_SCALE = arrayIndexScale(JavaKind.Boolean); - ARRAY_BYTE_INDEX_SCALE = arrayIndexScale(JavaKind.Byte); - ARRAY_SHORT_INDEX_SCALE = arrayIndexScale(JavaKind.Short); - ARRAY_CHAR_INDEX_SCALE = arrayIndexScale(JavaKind.Char); - ARRAY_INT_INDEX_SCALE = arrayIndexScale(JavaKind.Int); - ARRAY_LONG_INDEX_SCALE = arrayIndexScale(JavaKind.Long); - ARRAY_FLOAT_INDEX_SCALE = arrayIndexScale(JavaKind.Float); - ARRAY_DOUBLE_INDEX_SCALE = arrayIndexScale(JavaKind.Double); - ARRAY_OBJECT_INDEX_SCALE = arrayIndexScale(JavaKind.Object); - } - } - - native int arrayBaseOffset(JavaKind kind); - - native int arrayIndexScale(JavaKind kind); - - /** - * Gets the {@link CompilerToVM} instance associated with the singleton - * {@link HotSpotJVMCIRuntime} instance. - */ - public static CompilerToVM compilerToVM() { - return runtime().getCompilerToVM(); - } - - /** - * Copies the original bytecode of {@code method} into a new byte array and returns it. - * - * @return a new byte array containing the original bytecode of {@code method} - */ - native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method); - - /** - * Gets the number of entries in {@code method}'s exception handler table or 0 if it has no - * exception handler table. - */ - native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method); - - /** - * Gets the address of the first entry in {@code method}'s exception handler table. - * - * Each entry is a native object described by these fields: - * - *
      - *
    • {@link HotSpotVMConfig#exceptionTableElementSize}
    • - *
    • {@link HotSpotVMConfig#exceptionTableElementStartPcOffset}
    • - *
    • {@link HotSpotVMConfig#exceptionTableElementEndPcOffset}
    • - *
    • {@link HotSpotVMConfig#exceptionTableElementHandlerPcOffset}
    • - *
    • {@link HotSpotVMConfig#exceptionTableElementCatchTypeIndexOffset} - *
    - * - * @return 0 if {@code method} has no exception handlers (i.e. - * {@code getExceptionTableLength(method) == 0}) - */ - native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method); - - /** - * Determines whether {@code method} is currently compilable by the JVMCI compiler being used by - * the VM. This can return false if JVMCI compilation failed earlier for {@code method}, a - * breakpoint is currently set in {@code method} or {@code method} contains other bytecode - * features that require special handling by the VM. - */ - native boolean isCompilable(HotSpotResolvedJavaMethodImpl method); - - /** - * Determines if {@code method} is targeted by a VM directive (e.g., - * {@code -XX:CompileCommand=dontinline,}) or annotation (e.g., - * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined. - */ - native boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method); - - /** - * Determines if {@code method} should be inlined at any cost. This could be because: - *
      - *
    • a CompileOracle directive may forces inlining of this methods
    • - *
    • an annotation forces inlining of this method
    • - *
    - */ - native boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method); - - /** - * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}. - * - * @param method the method on which to base the search - * @param actualHolderType the best known type of receiver - * @return the method result or 0 is there is no unique concrete method for {@code method} - */ - native HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl actualHolderType, HotSpotResolvedJavaMethodImpl method); - - /** - * Gets the implementor for the interface class {@code type}. - * - * @return the implementor if there is a single implementor, {@code null} if there is no - * implementor, or {@code type} itself if there is more than one implementor - * @throws IllegalArgumentException if type is not an interface type - */ - native HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type); - - /** - * Determines if {@code method} is ignored by security stack walks. - */ - native boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method); - - /** - * Converts a name to a type. - * - * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format - * @param accessingClass the context of resolution. A value of {@code null} implies that the - * class should be resolved with the class loader. - * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will - * either return a {@link ResolvedJavaType} or throw an exception - * @return the type for {@code name} or 0 if resolution failed and {@code resolve == false} - * @throws ClassNotFoundException if {@code resolve == true} and the resolution failed - */ - native HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl accessingClass, boolean resolve) throws ClassNotFoundException; - - native HotSpotResolvedJavaType lookupClass(Class javaClass); - - /** - * Resolves the entry at index {@code cpi} in {@code constantPool} to an interned String object. - * - * The behavior of this method is undefined if {@code cpi} does not denote an - * {@code JVM_CONSTANT_String}. - */ - native JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the - * constant pool cache first. - * - * The behavior of this method is undefined if {@code cpi} does not denote one of the following - * entry types: {@code JVM_CONSTANT_Dynamic}, {@code JVM_CONSTANT_String}, - * {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError}, - * {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}. - */ - native JavaConstant resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * Gets the {@code JVM_CONSTANT_NameAndType} index from the entry at index {@code cpi} in - * {@code constantPool}. - * - * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a - * {@code JVM_CONSTANT_NameAndType} index. - */ - native int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * Gets the name of the {@code JVM_CONSTANT_NameAndType} entry referenced by another entry - * denoted by {@code which} in {@code constantPool}. - * - * The behavior of this method is undefined if {@code which} does not denote a entry that - * references a {@code JVM_CONSTANT_NameAndType} entry. - */ - native String lookupNameInPool(HotSpotConstantPool constantPool, int which); - - /** - * Gets the signature of the {@code JVM_CONSTANT_NameAndType} entry referenced by another entry - * denoted by {@code which} in {@code constantPool}. - * - * The behavior of this method is undefined if {@code which} does not denote a entry that - * references a {@code JVM_CONSTANT_NameAndType} entry. - */ - native String lookupSignatureInPool(HotSpotConstantPool constantPool, int which); - - /** - * Gets the {@code JVM_CONSTANT_Class} index from the entry at index {@code cpi} in - * {@code constantPool}. - * - * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a - * {@code JVM_CONSTANT_Class} index. - */ - native int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * Looks up a class denoted by the {@code JVM_CONSTANT_Class} entry at index {@code cpi} in - * {@code constantPool}. This method does not perform any resolution. - * - * The behavior of this method is undefined if {@code cpi} does not denote a - * {@code JVM_CONSTANT_Class} entry. - * - * @return the resolved class entry or a String otherwise - */ - native Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * Looks up a method denoted by the entry at index {@code cpi} in {@code constantPool}. This - * method does not perform any resolution. - * - * The behavior of this method is undefined if {@code cpi} does not denote an entry representing - * a method. - * - * @param opcode the opcode of the instruction for which the lookup is being performed or - * {@code -1}. If non-negative, then resolution checks specific to the bytecode it - * denotes are performed if the method is already resolved. Should any of these - * checks fail, 0 is returned. - * @return the resolved method entry, 0 otherwise - */ - native HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool, int cpi, byte opcode); - - // TODO resolving JVM_CONSTANT_Dynamic - - /** - * Ensures that the type referenced by the specified {@code JVM_CONSTANT_InvokeDynamic} entry at - * index {@code cpi} in {@code constantPool} is loaded and initialized. - * - * The behavior of this method is undefined if {@code cpi} does not denote a - * {@code JVM_CONSTANT_InvokeDynamic} entry. - */ - native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * If {@code cpi} denotes an entry representing a - * signature - * polymorphic method, this method ensures that the type referenced by the entry is loaded - * and initialized. It {@code cpi} does not denote a signature polymorphic method, this method - * does nothing. - */ - native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * If {@code cpi} denotes an entry representing a resolved dynamic adapter (see - * {@link #resolveInvokeDynamicInPool} and {@link #resolveInvokeHandleInPool}), return the - * opcode of the instruction for which the resolution was performed ({@code invokedynamic} or - * {@code invokevirtual}), or {@code -1} otherwise. - */ - native int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the - * classes that define signature polymorphic methods. - */ - native String[] getSignaturePolymorphicHolders(); - - /** - * Gets the resolved type denoted by the entry at index {@code cpi} in {@code constantPool}. - * - * The behavior of this method is undefined if {@code cpi} does not denote an entry representing - * a class. - * - * @throws LinkageError if resolution failed - */ - native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError; - - /** - * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index - * {@code cpi} in {@code constantPool}. For some opcodes, checks are performed that require the - * {@code method} that contains {@code opcode} to be specified. The values returned in - * {@code info} are: - * - *
    -     *     [ flags,  // fieldDescriptor::access_flags()
    -     *       offset, // fieldDescriptor::offset()
    -     *       index   // fieldDescriptor::index()
    -     *     ]
    -     * 
    - * - * The behavior of this method is undefined if {@code cpi} does not denote a - * {@code JVM_CONSTANT_Field} entry. - * - * @param info an array in which the details of the field are returned - * @return the type defining the field if resolution is successful, 0 otherwise - */ - native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int cpi, HotSpotResolvedJavaMethodImpl method, byte opcode, int[] info); - - /** - * Converts {@code cpci} from an index into the cache for {@code constantPool} to an index - * directly into {@code constantPool}. - * - * The behavior of this method is undefined if {@code ccpi} is an invalid constant pool cache - * index. - */ - native int constantPoolRemapInstructionOperandFromCache(HotSpotConstantPool constantPool, int cpci); - - /** - * Gets the appendix object (if any) associated with the entry at index {@code cpi} in - * {@code constantPool}. - */ - native HotSpotObjectConstantImpl lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi); - - /** - * Installs the result of a compilation into the code cache. - * - * @param target the target where this code should be installed - * @param compiledCode the result of a compilation - * @param code the details of the installed CodeBlob are written to this object - * @return the outcome of the installation which will be one of - * {@link HotSpotVMConfig#codeInstallResultOk}, - * {@link HotSpotVMConfig#codeInstallResultCacheFull}, - * {@link HotSpotVMConfig#codeInstallResultCodeTooLarge} or - * {@link HotSpotVMConfig#codeInstallResultDependenciesFailed}. - * @throws JVMCIError if there is something wrong with the compiled code or the associated - * metadata. - */ - native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, long failedSpeculationsAddress, byte[] speculations); - - /** - * Generates the VM metadata for some compiled code and copies them into {@code metaData}. This - * method does not install anything into the code cache. - * - * @param target the target where this code would be installed - * @param compiledCode the result of a compilation - * @param metaData the metadata is written to this object - * @return the outcome of the installation which will be one of - * {@link HotSpotVMConfig#codeInstallResultOk}, - * {@link HotSpotVMConfig#codeInstallResultCacheFull}, - * {@link HotSpotVMConfig#codeInstallResultCodeTooLarge} or - * {@link HotSpotVMConfig#codeInstallResultDependenciesFailed}. - * @throws JVMCIError if there is something wrong with the compiled code or the metadata - */ - native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData); - - /** - * Resets all compilation statistics. - */ - native void resetCompilationStatistics(); - - /** - * Reads the database of VM info. The return value encodes the info in a nested object array - * that is described by the pseudo Java object {@code info} below: - * - *
    -     *     info = [
    -     *         VMField[] vmFields,
    -     *         [String name, Long size, ...] vmTypeSizes,
    -     *         [String name, Long value, ...] vmConstants,
    -     *         [String name, Long value, ...] vmAddresses,
    -     *         VMFlag[] vmFlags
    -     *         VMIntrinsicMethod[] vmIntrinsics
    -     *     ]
    -     * 
    - * - * @return VM info as encoded above - */ - native Object[] readConfiguration(); - - /** - * Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic - * type {@code exactReceiver}. This resolution process only searches "up" the class hierarchy of - * {@code exactReceiver}. - * - * @param caller the caller or context type used to perform access checks - * @return the link-time resolved method (might be abstract) or {@code null} if it is either a - * signature polymorphic method or can not be linked. - */ - native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller); - - /** - * Gets the static initializer of {@code type}. - * - * @return {@code null} if {@code type} has no static initializer - */ - native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type); - - /** - * Determines if {@code type} or any of its currently loaded subclasses overrides - * {@code Object.finalize()}. - */ - native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type); - - /** - * Gets the method corresponding to {@code executable}. - */ - native HotSpotResolvedJavaMethodImpl asResolvedJavaMethod(Executable executable); - - /** - * Gets the maximum absolute offset of a PC relative call to {@code address} from any position - * in the code cache. - * - * @param address an address that may be called from any code in the code cache - * @return -1 if {@code address == 0} - */ - native long getMaxCallTargetOffset(long address); - - /** - * Gets a textual disassembly of {@code codeBlob}. - * - * @return a non-zero length string containing a disassembly of {@code codeBlob} or null if - * {@code codeBlob} could not be disassembled for some reason - */ - // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage - synchronized native String disassembleCodeBlob(InstalledCode installedCode); - - /** - * Gets a stack trace element for {@code method} at bytecode index {@code bci}. - */ - native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci); - - /** - * Executes some {@code installedCode} with arguments {@code args}. - * - * @return the result of executing {@code nmethodMirror} - * @throws InvalidInstalledCodeException if {@code nmethodMirror} has been invalidated - */ - native Object executeHotSpotNmethod(Object[] args, HotSpotNmethod nmethodMirror) throws InvalidInstalledCodeException; - - /** - * Gets the line number table for {@code method}. The line number table is encoded as (bci, - * source line number) pairs. - * - * @return the line number table for {@code method} or null if it doesn't have one - */ - native long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method); - - /** - * Gets the number of entries in the local variable table for {@code method}. - * - * @return the number of entries in the local variable table for {@code method} - */ - native int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method); - - /** - * Gets the address of the first entry in the local variable table for {@code method}. - * - * Each entry is a native object described by these fields: - * - *
      - *
    • {@link HotSpotVMConfig#localVariableTableElementSize}
    • - *
    • {@link HotSpotVMConfig#localVariableTableElementLengthOffset}
    • - *
    • {@link HotSpotVMConfig#localVariableTableElementNameCpIndexOffset}
    • - *
    • {@link HotSpotVMConfig#localVariableTableElementDescriptorCpIndexOffset}
    • - *
    • {@link HotSpotVMConfig#localVariableTableElementSlotOffset} - *
    • {@link HotSpotVMConfig#localVariableTableElementStartBciOffset} - *
    - * - * @return 0 if {@code method} does not have a local variable table - */ - native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method); - - /** - * Sets flags on {@code method} indicating that it should never be inlined or compiled by the - * VM. - */ - native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method); - - /** - * Invalidates the profiling information for {@code method} and (re)initializes it such that - * profiling restarts upon its next invocation. - */ - native void reprofile(HotSpotResolvedJavaMethodImpl method); - - /** - * Invalidates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be - * raised the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}. - * The {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and any - * current activations of the {@code nmethod} are deoptimized. - */ - native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror); - - /** - * Collects the current values of all JVMCI benchmark counters, summed up over all threads. - */ - native long[] collectCounters(); - - /** - * Get the current number of counters allocated for use by JVMCI. Should be the same value as - * the flag {@code JVMCICounterSize}. - */ - native int getCountersSize(); - - /** - * Attempt to change the size of the counters allocated for JVMCI. This requires a safepoint to - * safely reallocate the storage but it's advisable to increase the size in reasonable chunks. - */ - native boolean setCountersSize(int newSize); - - /** - * Determines if {@code metaspaceMethodData} is mature. - */ - native boolean isMature(long metaspaceMethodData); - - /** - * Generate a unique id to identify the result of the compile. - */ - native int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI); - - /** - * Determines if {@code method} has OSR compiled code identified by {@code entryBCI} for - * compilation level {@code level}. - */ - native boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level); - - /** - * Gets the value of {@code metaspaceSymbol} as a String. - */ - native String getSymbol(long metaspaceSymbol); - - /** - * @see jdk.vm.ci.code.stack.StackIntrospection#iterateFrames - */ - native T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor visitor); - - /** - * Materializes all virtual objects within {@code stackFrame} and updates its locals. - * - * @param invalidate if {@code true}, the compiled method for the stack frame will be - * invalidated - */ - native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); - - /** - * Gets the v-table index for interface method {@code method} in the receiver {@code type} or - * {@link HotSpotVMConfig#invalidVtableIndex} if {@code method} is not in {@code type}'s - * v-table. - * - * @throws InternalError if {@code type} is an interface, {@code method} is not defined by an - * interface, {@code type} does not implement the interface defining {@code method} - * or class represented by {@code type} is not initialized - */ - native int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, HotSpotResolvedJavaMethodImpl method); - - /** - * Determines if debug info should also be emitted at non-safepoint locations. - */ - native boolean shouldDebugNonSafepoints(); - - /** - * Writes {@code length} bytes from {@code buffer} to HotSpot's log stream. - * - * @param buffer if {@code length <= 8}, then the bytes are encoded in this value in native - * endianness order otherwise this is the address of a native memory buffer holding - * the bytes - * @param flush specifies if the log stream should be flushed after writing - */ - native void writeDebugOutput(long buffer, int length, boolean flush); - - /** - * Flush HotSpot's log stream. - */ - native void flushDebugOutput(); - - /** - * Read a HotSpot Method* value from the memory location described by {@code base} plus - * {@code displacement} and return the {@link HotSpotResolvedJavaMethodImpl} wrapping it. This - * method does no checking that the memory location actually contains a valid pointer and may - * crash the VM if an invalid location is provided. If the {@code base} is null then - * {@code displacement} is used by itself. If {@code base} is a - * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or - * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object - * and added to {@code displacement}. Any other non-null object type causes an - * {@link IllegalArgumentException} to be thrown. - * - * @param base an object to read from or null - * @param displacement - * @return null or the resolved method for this location - */ - native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(HotSpotObjectConstantImpl base, long displacement); - - /** - * Gets the {@code ConstantPool*} associated with {@code object} and returns a - * {@link HotSpotConstantPool} wrapping it. - * - * @param object a {@link HotSpotResolvedJavaMethodImpl} or - * {@link HotSpotResolvedObjectTypeImpl} object - * @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with - * {@code object} - * @throws NullPointerException if {@code object == null} - * @throws IllegalArgumentException if {@code object} is neither a - * {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl} - */ - native HotSpotConstantPool getConstantPool(MetaspaceObject object); - - /** - * Read a HotSpot Klass* value from the memory location described by {@code base} plus - * {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This - * method does no checking that the memory location actually contains a valid pointer and may - * crash the VM if an invalid location is provided. If the {@code base} is null then - * {@code displacement} is used by itself. If {@code base} is a - * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or - * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object - * and added to {@code displacement}. Any other non-null object type causes an - * {@link IllegalArgumentException} to be thrown. - * - * @param base an object to read from or null - * @param displacement - * @param compressed true if the location contains a compressed Klass* - * @return null or the resolved method for this location - */ - private native HotSpotResolvedObjectTypeImpl getResolvedJavaType0(Object base, long displacement, boolean compressed); - - HotSpotResolvedObjectTypeImpl getResolvedJavaType(MetaspaceObject base, long displacement, boolean compressed) { - return getResolvedJavaType0(base, displacement, compressed); - } - - HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotObjectConstantImpl base, long displacement, boolean compressed) { - return getResolvedJavaType0(base, displacement, compressed); - } - - HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean compressed) { - return getResolvedJavaType0(null, displacement, compressed); - } - - /** - * Return the size of the HotSpot ProfileData* pointed at by {@code position}. If - * {@code position} is outside the space of the MethodData then an - * {@link IllegalArgumentException} is thrown. A {@code position} inside the MethodData but that - * isn't pointing at a valid ProfileData will crash the VM. - * - * @param metaspaceMethodData - * @param position - * @return the size of the ProfileData item pointed at by {@code position} - * @throws IllegalArgumentException if an out of range position is given - */ - native int methodDataProfileDataSize(long metaspaceMethodData, int position); - - /** - * Gets the fingerprint for a given Klass*. - * - * @param metaspaceKlass - * @return the value of the fingerprint (zero for arrays and synthetic classes). - */ - native long getFingerprint(long metaspaceKlass); - - /** - * Return the amount of native stack required for the interpreter frames represented by - * {@code frame}. This is used when emitting the stack banging code to ensure that there is - * enough space for the frames during deoptimization. - * - * @param frame - * @return the number of bytes required for deoptimization of this frame state - */ - native int interpreterFrameSize(BytecodeFrame frame); - - /** - * Invokes non-public method {@code java.lang.invoke.LambdaForm.compileToBytecode()} on - * {@code lambdaForm} (which must be a {@code java.lang.invoke.LambdaForm} instance). - */ - native void compileToBytecode(HotSpotObjectConstantImpl lambdaForm); - - /** - * Gets the value of the VM flag named {@code name}. - * - * @param name name of a VM option - * @return {@code this} if the named VM option doesn't exist, a {@link String} or {@code null} - * if its type is {@code ccstr} or {@code ccstrlist}, a {@link Double} if its type is - * {@code double}, a {@link Boolean} if its type is {@code bool} otherwise a - * {@link Long} - */ - native Object getFlagValue(String name); - - /** - * @see ResolvedJavaType#getInterfaces() - */ - native HotSpotResolvedObjectTypeImpl[] getInterfaces(HotSpotResolvedObjectTypeImpl type); - - /** - * @see ResolvedJavaType#getComponentType() - */ - native HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl type); - - /** - * Get the array class for {@code type}. This can't be done symbolically since hidden classes - * can't be looked up by name. - */ - native HotSpotResolvedObjectTypeImpl getArrayType(HotSpotResolvedJavaType type); - - /** - * Forces initialization of {@code type}. - */ - native void ensureInitialized(HotSpotResolvedObjectTypeImpl type); - - /** - * Forces linking of {@code type}. - */ - native void ensureLinked(HotSpotResolvedObjectTypeImpl type); - - /** - * Checks if {@code object} is a String and is an interned string value. - */ - native boolean isInternedString(HotSpotObjectConstantImpl object); - - /** - * Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object - * represented by this constant. - */ - native int getIdentityHashCode(HotSpotObjectConstantImpl object); - - /** - * Converts a constant object representing a boxed primitive into a boxed primitive. - */ - native Object unboxPrimitive(HotSpotObjectConstantImpl object); - - /** - * Converts a boxed primitive into a JavaConstant representing the same value. - */ - native HotSpotObjectConstantImpl boxPrimitive(Object source); - - /** - * Gets the {@link ResolvedJavaMethod}s for all the constructors of the type {@code holder}. - */ - native ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl holder); - - /** - * Gets the {@link ResolvedJavaMethod}s for all the non-constructor methods of the type - * {@code holder}. - */ - native ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl holder); - - /** - * Reads the current value of a static field. If {@code expectedType} is non-null, then the - * object is expected to be a subtype of {@code expectedType} and extra sanity checking is - * performed on the offset and kind of the read being performed. - * - * @throws IllegalArgumentException if any of the sanity checks fail - */ - native JavaConstant readFieldValue(HotSpotResolvedObjectTypeImpl object, HotSpotResolvedObjectTypeImpl expectedType, long offset, JavaKind kind); - - /** - * Reads the current value of an instance field. If {@code expectedType} is non-null, then the - * object is expected to be a subtype of {@code expectedType} and extra sanity checking is - * performed on the offset and kind of the read being performed. - * - * @throws IllegalArgumentException if any of the sanity checks fail - */ - native JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedObjectTypeImpl expectedType, long offset, JavaKind kind); - - /** - * @see ResolvedJavaType#isInstance(JavaConstant) - */ - native boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl object); - - /** - * @see ResolvedJavaType#isAssignableFrom(ResolvedJavaType) - */ - native boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType); - - /** - * @see ConstantReflectionProvider#asJavaType(Constant) - */ - native HotSpotResolvedJavaType asJavaType(HotSpotObjectConstantImpl object); - - /** - * Converts a String constant into a String. - */ - native String asString(HotSpotObjectConstantImpl object); - - /** - * Compares the contents of {@code xHandle} and {@code yHandle} for pointer equality. - */ - native boolean equals(HotSpotObjectConstantImpl x, long xHandle, HotSpotObjectConstantImpl y, long yHandle); - - /** - * Gets a {@link JavaConstant} wrapping the {@link java.lang.Class} mirror for {@code type}. - */ - native HotSpotObjectConstantImpl getJavaMirror(HotSpotResolvedJavaType type); - - /** - * Returns the length of the array if {@code object} represents an array or -1 otherwise. - */ - native int getArrayLength(HotSpotObjectConstantImpl object); - - /** - * Reads the element at {@code index} if {@code object} is an array. Elements of an object array - * are returned as {@link JavaConstant}s and primitives are returned as boxed values. The value - * {@code null} is returned if the {@code index} is out of range or object is not an array. - */ - native Object readArrayElement(HotSpotObjectConstantImpl object, int index); - - /** - * @see HotSpotJVMCIRuntime#registerNativeMethods - */ - native long[] registerNativeMethods(Class clazz); - - /** - * @see HotSpotJVMCIRuntime#translate(Object) - */ - native long translate(Object obj, boolean callPostTranslation); - - /** - * @see HotSpotJVMCIRuntime#unhand(Class, long) - */ - native Object unhand(long handle); - - /** - * Updates {@code address} and {@code entryPoint} fields of {@code nmethodMirror} based on the - * current state of the {@code nmethod} identified by {@code address} and - * {@code nmethodMirror.compileId} in the code cache. - */ - native void updateHotSpotNmethod(HotSpotNmethod nmethodMirror); - - /** - * @see InstalledCode#getCode() - */ - native byte[] getCode(HotSpotInstalledCode code); - - /** - * Gets a {@link Executable} corresponding to {@code method}. - */ - native Executable asReflectionExecutable(HotSpotResolvedJavaMethodImpl method); - - /** - * Gets a {@link Field} denoted by {@code holder} and {@code index}. - * - * @param holder the class in which the requested field is declared - * @param fieldIndex the {@code fieldDescriptor::index()} denoting the field - */ - native Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, int fieldIndex); - - /** - * @see HotSpotJVMCIRuntime#getIntrinsificationTrustPredicate(Class...) - */ - native boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl type); - - /** - * Releases the resources backing the global JNI {@code handle}. This is equivalent to the - * {@code DeleteGlobalRef} JNI function. - */ - native void deleteGlobalHandle(long handle); - - /** - * Gets the failed speculations pointed to by {@code *failedSpeculationsAddress}. - * - * @param currentFailures the known failures at {@code failedSpeculationsAddress} - * @return the list of failed speculations with each entry being a single speculation in the - * format emitted by {@link HotSpotSpeculationEncoding#toByteArray()} - */ - native byte[][] getFailedSpeculations(long failedSpeculationsAddress, byte[][] currentFailures); - - /** - * Gets the address of the {@code MethodData::_failed_speculations} field in the - * {@code MethodData} associated with {@code method}. This will create and install the - * {@code MethodData} if it didn't already exist. - */ - native long getFailedSpeculationsAddress(HotSpotResolvedJavaMethodImpl method); - - /** - * Frees the failed speculations pointed to by {@code *failedSpeculationsAddress}. - */ - native void releaseFailedSpeculations(long failedSpeculationsAddress); - - /** - * Adds a speculation to the failed speculations pointed to by - * {@code *failedSpeculationsAddress}. - * - * @return {@code false} if the speculation could not be appended to the list - */ - native boolean addFailedSpeculation(long failedSpeculationsAddress, byte[] speculation); - - /** - * @see HotSpotJVMCIRuntime#isCurrentThreadAttached() - */ - native boolean isCurrentThreadAttached(); - - /** - * @see HotSpotJVMCIRuntime#getCurrentJavaThread() - */ - native long getCurrentJavaThread(); - - /** - * @param name name of current thread if in a native image otherwise {@code null} - * @see HotSpotJVMCIRuntime#attachCurrentThread - */ - native boolean attachCurrentThread(byte[] name, boolean asDaemon); - - /** - * @see HotSpotJVMCIRuntime#detachCurrentThread() - */ - native void detachCurrentThread(); - - /** - * @see HotSpotJVMCIRuntime#exitHotSpot(int) - */ - native void callSystemExit(int status); - - /** - * @see JFR.Ticks#now - */ - native long ticksNow(); - - /** - * @see HotSpotJVMCIRuntime#setThreadLocalObject(int, Object) - */ - native void setThreadLocalObject(int id, Object value); - - /** - * @see HotSpotJVMCIRuntime#getThreadLocalObject(int) - */ - native Object getThreadLocalObject(int id); - - /** - * @see HotSpotJVMCIRuntime#setThreadLocalLong(int, long) - */ - native void setThreadLocalLong(int id, long value); - - /** - * @see HotSpotJVMCIRuntime#getThreadLocalLong(int) - */ - native long getThreadLocalLong(int id); - - /** - * Adds phases in HotSpot JFR. - * - * @see JFR.CompilerPhaseEvent#write - */ - native int registerCompilerPhase(String phaseName); - - /** - * @see JFR.CompilerPhaseEvent#write - */ - native void notifyCompilerPhaseEvent(long startTime, int phase, int compileId, int level); - - /** - * @see JFR.CompilerInliningEvent#write - */ - native void notifyCompilerInliningEvent(int compileId, HotSpotResolvedJavaMethodImpl caller, HotSpotResolvedJavaMethodImpl callee, boolean succeeded, String message, int bci); - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.JavaConstant; - -final class DirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl { - - static JavaConstant forObject(Object object, boolean compressed) { - if (object == null) { - return compressed ? HotSpotCompressedNullConstant.COMPRESSED_NULL : JavaConstant.NULL_POINTER; - } else { - return new DirectHotSpotObjectConstantImpl(object, compressed); - } - } - - static HotSpotObjectConstantImpl forNonNullObject(Object object, boolean compressed) { - if (object == null) { - throw new NullPointerException(); - } - return new DirectHotSpotObjectConstantImpl(object, compressed); - } - - private DirectHotSpotObjectConstantImpl(Object object, boolean compressed) { - super(compressed); - assert object != null; - this.object = object; - } - - final Object object; - - @Override - public JavaConstant compress() { - assert !compressed; - return new DirectHotSpotObjectConstantImpl(object, true); - } - - @Override - public JavaConstant uncompress() { - assert compressed; - return new DirectHotSpotObjectConstantImpl(object, false); - } - - @Override - public int getIdentityHashCode() { - return System.identityHashCode(object); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EmptyEventProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EmptyEventProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EmptyEventProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EmptyEventProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * An empty implementation for {@link EventProvider}. This implementation is used when no logging is - * requested. - */ -final class EmptyEventProvider implements EventProvider { - - static InternalError shouldNotReachHere() { - throw new InternalError("should not reach here"); - } - - @Override - public CompilationEvent newCompilationEvent() { - return new EmptyCompilationEvent(); - } - - static class EmptyCompilationEvent implements CompilationEvent { - @Override - public void commit() { - throw shouldNotReachHere(); - } - - @Override - public boolean shouldWrite() { - // Events of this class should never been written. - return false; - } - - @Override - public void begin() { - } - - @Override - public void end() { - } - - @Override - public void setMethod(String method) { - throw shouldNotReachHere(); - } - - @Override - public void setCompileId(int compileId) { - throw shouldNotReachHere(); - } - - @Override - public void setCompileLevel(int compileLevel) { - throw shouldNotReachHere(); - } - - @Override - public void setSucceeded(boolean succeeded) { - throw shouldNotReachHere(); - } - - @Override - public void setIsOsr(boolean isOsr) { - throw shouldNotReachHere(); - } - - @Override - public void setCodeSize(int codeSize) { - throw shouldNotReachHere(); - } - - @Override - public void setInlinedBytes(int inlinedBytes) { - throw shouldNotReachHere(); - } - } - - @Override - public CompilerFailureEvent newCompilerFailureEvent() { - return new EmptyCompilerFailureEvent(); - } - - static class EmptyCompilerFailureEvent implements CompilerFailureEvent { - @Override - public void commit() { - throw shouldNotReachHere(); - } - - @Override - public boolean shouldWrite() { - // Events of this class should never been written. - return false; - } - - @Override - public void setCompileId(int compileId) { - throw shouldNotReachHere(); - } - - @Override - public void setMessage(String message) { - throw shouldNotReachHere(); - } - } - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilationEvent; -import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilerFailureEvent; - -/** - * Service-provider class for logging compiler related events. - */ -public interface EventProvider { - - /** - * Creates and returns an empty implementation for {@link EventProvider}. This implementation - * can be used when no logging is requested. - */ - static EventProvider createEmptyEventProvider() { - return new EmptyEventProvider(); - } - - /** - * Creates and returns an empty implementation for {@link CompilationEvent}. - */ - static CompilationEvent createEmptyCompilationEvent() { - return new EmptyCompilationEvent(); - } - - /** - * Creates and returns an empty implementation for {@link CompilationEvent}. - */ - static CompilerFailureEvent createEmptyCompilerFailureEvent() { - return new EmptyCompilerFailureEvent(); - } - - /** - * An instant event is an event that is not considered to have taken any time. - */ - public interface InstantEvent { - /** - * Commits the event. - */ - void commit(); - - /** - * Determines if this particular event instance would be committed to the data stream right - * now if application called {@link #commit()}. This in turn depends on whether the event is - * enabled and possible other factors. - * - * @return if this event would be committed on a call to {@link #commit()}. - */ - boolean shouldWrite(); - } - - /** - * Timed events describe an operation that somehow consumes time. - */ - public interface TimedEvent extends InstantEvent { - /** - * Starts the timing for this event. - */ - void begin(); - - /** - * Ends the timing period for this event. - */ - void end(); - } - - /** - * Creates a new {@link CompilationEvent}. - * - * @return a compilation event - */ - CompilationEvent newCompilationEvent(); - - /** - * A compilation event. - */ - public interface CompilationEvent extends TimedEvent { - void setMethod(String method); - - void setCompileId(int compileId); - - void setCompileLevel(int compileLevel); - - void setSucceeded(boolean succeeded); - - void setIsOsr(boolean isOsr); - - void setCodeSize(int codeSize); - - void setInlinedBytes(int inlinedBytes); - } - - /** - * Creates a new {@link CompilerFailureEvent}. - * - * @return a compiler failure event - */ - CompilerFailureEvent newCompilerFailureEvent(); - - /** - * A compiler failure event. - */ - public interface CompilerFailureEvent extends InstantEvent { - void setCompileId(int compileId); - - void setMessage(String message); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -/** - * This class manages a set of {@code jobject} and {@code jmetadata} handles whose lifetimes are - * dependent on associated {@link IndirectHotSpotObjectConstantImpl} and - * {@link MetaspaceHandleObject} wrapper objects respectively. - * - * The general theory of operation is that all wrappers are created by calling into the VM which - * calls back out to actually create the wrapper instance. During the call the VM keeps the object - * or metadata reference alive through the use of handles. Once the call completes the wrapper - * object is registered here and will be scanned during metadata scanning. The weakness of the - * reference to the wrapper object allows the handles to be reclaimed when they are no longer used. - */ -final class HandleCleaner extends Cleaner { - - /** - * A {@code jmetadata} or {@code jobject} handle. - */ - private final long handle; - - /** - * Specifies if {@link #handle} is a {@code jobject} or {@code jmetadata}. - */ - private final boolean isJObject; - - private HandleCleaner(Object wrapper, long handle, boolean isJObject) { - super(wrapper); - this.handle = handle; - this.isJObject = isJObject; - } - - /** - * Releases the resource associated with {@code this.handle}. - */ - @Override - void doCleanup() { - if (isJObject) { - // The sentinel value used to denote a free handle is - // an object on the HotSpot heap so we call into the - // VM to set the target of an object handle to this value. - CompilerToVM.compilerToVM().deleteGlobalHandle(handle); - } else { - // Setting the target of a jmetadata handle to 0 enables - // the handle to be reused. See MetadataHandles in - // metadataHandles.hpp for more info. - long value = UNSAFE.getLong(null, handle); - UNSAFE.compareAndSetLong(null, handle, value, 0); - } - } - - /** - * Registers a cleaner for {@code handle}. The cleaner will release the handle some time after - * {@code wrapper} is detected as unreachable by the garbage collector. - */ - @SuppressWarnings("unused") - static void create(Object wrapper, long handle) { - assert wrapper instanceof IndirectHotSpotObjectConstantImpl || wrapper instanceof MetaspaceHandleObject; - new HandleCleaner(wrapper, handle, wrapper instanceof IndirectHotSpotObjectConstantImpl); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.CallingConvention; -import jdk.vm.ci.code.CallingConvention.Type; - -public enum HotSpotCallingConventionType implements CallingConvention.Type { - /** - * A request for the outgoing argument locations at a call site to Java code. - */ - JavaCall(true), - - /** - * A request for the incoming argument locations. - */ - JavaCallee(false), - - /** - * A request for the outgoing argument locations at a call site to external native code that - * complies with the platform ABI. - */ - NativeCall(true); - - /** - * Determines if this is a request for the outgoing argument locations at a call site. - */ - public final boolean out; - - public static final Type[] VALUES = values(); - - HotSpotCallingConventionType(boolean out) { - this.out = out; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2013, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.util.Map; -import java.util.Objects; - -import jdk.vm.ci.code.BailoutException; -import jdk.vm.ci.code.BytecodeFrame; -import jdk.vm.ci.code.CodeCacheProvider; -import jdk.vm.ci.code.CompiledCode; -import jdk.vm.ci.code.InstalledCode; -import jdk.vm.ci.code.RegisterConfig; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.site.Call; -import jdk.vm.ci.code.site.Mark; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.SpeculationLog; - -/** - * HotSpot implementation of {@link CodeCacheProvider}. - */ -public class HotSpotCodeCacheProvider implements CodeCacheProvider { - - protected final HotSpotJVMCIRuntime runtime; - private final HotSpotVMConfig config; - protected final TargetDescription target; - protected final RegisterConfig regConfig; - - public HotSpotCodeCacheProvider(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { - this.runtime = runtime; - this.config = runtime.getConfig(); - this.target = target; - this.regConfig = regConfig; - } - - @Override - public String getMarkName(Mark mark) { - int markId = (int) mark.id; - HotSpotVMConfigStore store = runtime.getConfigStore(); - for (Map.Entry e : store.getConstants().entrySet()) { - String name = e.getKey(); - if (name.startsWith("MARKID_") && e.getValue() == markId) { - return name; - } - } - return CodeCacheProvider.super.getMarkName(mark); - } - - /** - * Decodes a call target to a mnemonic if possible. - */ - @Override - public String getTargetName(Call call) { - if (call.target instanceof HotSpotForeignCallTarget) { - long address = ((HotSpotForeignCallTarget) call.target).address; - HotSpotVMConfigStore store = runtime.getConfigStore(); - for (Map.Entry e : store.getFields().entrySet()) { - VMField field = e.getValue(); - if (field.isStatic() && field.value != null && field.value instanceof Long && ((Long) field.value) == address) { - return e.getValue() + ":0x" + Long.toHexString(address); - } - } - } - return CodeCacheProvider.super.getTargetName(call); - } - - @Override - public RegisterConfig getRegisterConfig() { - return regConfig; - } - - @Override - public int getMinimumOutgoingSize() { - return config.runtimeCallStackSize; - } - - private InstalledCode logOrDump(InstalledCode installedCode, CompiledCode compiledCode) { - runtime.notifyInstall(this, installedCode, compiledCode); - return installedCode; - } - - @Override - public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault) { - InstalledCode resultInstalledCode; - if (installedCode != null) { - throw new IllegalArgumentException("InstalledCode argument must be null"); - } - HotSpotCompiledCode hsCompiledCode = (HotSpotCompiledCode) compiledCode; - String name = hsCompiledCode.getName(); - HotSpotCompiledNmethod hsCompiledNmethod = null; - HotSpotSpeculationLog speculationLog = null; - if (log != null) { - if (log.hasSpeculations()) { - speculationLog = (HotSpotSpeculationLog) log; - } - } - byte[] speculations; - long failedSpeculationsAddress; - if (speculationLog != null) { - speculations = speculationLog.getFlattenedSpeculations(true); - failedSpeculationsAddress = speculationLog.getFailedSpeculationsAddress(); - } else { - speculations = new byte[0]; - failedSpeculationsAddress = 0L; - } - - if (method == null) { - // Must be a stub - resultInstalledCode = new HotSpotRuntimeStub(name); - } else { - hsCompiledNmethod = (HotSpotCompiledNmethod) hsCompiledCode; - HotSpotResolvedJavaMethodImpl hsMethod = (HotSpotResolvedJavaMethodImpl) method; - HotSpotNmethod nmethod = new HotSpotNmethod(hsMethod, name, isDefault, hsCompiledNmethod.id); - nmethod.setSpeculationLog(speculationLog); - resultInstalledCode = nmethod; - } - - int result = runtime.getCompilerToVM().installCode(target, (HotSpotCompiledCode) compiledCode, resultInstalledCode, failedSpeculationsAddress, speculations); - if (result != config.codeInstallResultOk) { - String resultDesc = config.getCodeInstallResultDescription(result); - if (hsCompiledNmethod != null) { - String msg = hsCompiledNmethod.getInstallationFailureMessage(); - if (msg != null) { - msg = String.format("Code installation failed: %s%n%s", resultDesc, msg); - } else { - msg = String.format("Code installation failed: %s", resultDesc); - } - throw new BailoutException(result >= config.codeInstallResultFirstPermanentBailout, msg); - } else { - throw new BailoutException("Error installing %s: %s", ((HotSpotCompiledCode) compiledCode).getName(), resultDesc); - } - } - return logOrDump(resultInstalledCode, compiledCode); - } - - @Override - public void invalidateInstalledCode(InstalledCode installedCode) { - if (installedCode instanceof HotSpotNmethod) { - runtime.getCompilerToVM().invalidateHotSpotNmethod((HotSpotNmethod) installedCode); - } else { - throw new IllegalArgumentException("Cannot invalidate a " + Objects.requireNonNull(installedCode).getClass().getName()); - } - } - - @Override - public TargetDescription getTarget() { - return target; - } - - public String disassemble(InstalledCode code) { - if (code.isValid()) { - return runtime.getCompilerToVM().disassembleCodeBlob(code); - } - return null; - } - - @Override - public SpeculationLog createSpeculationLog() { - return new HotSpotSpeculationLog(); - } - - @Override - public long getMaxCallTargetOffset(long address) { - return runtime.getCompilerToVM().getMaxCallTargetOffset(address); - } - - @Override - public boolean shouldDebugNonSafepoints() { - return runtime.getCompilerToVM().shouldDebugNonSafepoints(); - } - - public int interpreterFrameSize(BytecodeFrame pos) { - return runtime.getCompilerToVM().interpreterFrameSize(pos); - } - - /** - * Resets all compilation statistics. - */ - public void resetCompilationStatistics() { - runtime.getCompilerToVM().resetCompilationStatistics(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2015, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.CompilationRequest; - -/** - * A compilation request with extra HotSpot specific context such as a compilation identifier and - * the address of a {@code JVMCIEnv} object that provides native context for a compilation. - */ -public class HotSpotCompilationRequest extends CompilationRequest { - /** - * Address of the native {@code JVMCICompileState} associated with the request. - */ - private final long compileState; - - /** - * An identifier for the request. - */ - private final int id; - - /** - * Creates a request to compile a method starting at a given BCI and allocates an identifier to - * the request. - * - * @param method the method to be compiled - * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the - * method's entry point - * @param compileState address of a native {@code JVMCICompileState} object or 0L - */ - public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long compileState) { - this(method, entryBCI, compileState, method.allocateCompileId(entryBCI)); - } - - /** - * Creates a request to compile a method starting at a given BCI. - * - * @param method the method to be compiled - * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the - * method's entry point - * @param compileState address of a native {@code JVMCICompileState} object or 0L - * @param id an identifier for the request - */ - public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long compileState, int id) { - super(method, entryBCI); - this.compileState = compileState; - this.id = id; - } - - @Override - public HotSpotResolvedJavaMethod getMethod() { - return (HotSpotResolvedJavaMethod) super.getMethod(); - } - - /** - * Gets the address of the native {@code JVMCICompileState} or 0L if no such object exists. This - * method should really be named {@code getCompileState} but must remain as is for API - * stability. - */ - public long getJvmciEnv() { - return compileState; - } - - /** - * Gets the VM allocated identifier for this compilation. - */ - public int getId() { - return id; - } - - @Override - public String toString() { - return id + ":" + super.toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +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. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.CompilationRequest; -import jdk.vm.ci.code.CompilationRequestResult; - -/** - * HotSpot specific information about the result of a {@link CompilationRequest}. - */ -public final class HotSpotCompilationRequestResult implements CompilationRequestResult { - - /** - * A user readable description of the failure. - * - * This field is read by the VM. - */ - private final String failureMessage; - - /** - * Whether this is a transient failure where retrying would help. - * - * This field is read by the VM. - */ - private final boolean retry; - - /** - * Number of bytecodes inlined into the compilation, exclusive of the bytecodes in the root - * method. - * - * This field is read by the VM. - */ - private final int inlinedBytecodes; - - private HotSpotCompilationRequestResult(String failureMessage, boolean retry, int inlinedBytecodes) { - this.failureMessage = failureMessage; - this.retry = retry; - this.inlinedBytecodes = inlinedBytecodes; - } - - @Override - public Object getFailure() { - return failureMessage; - } - - /** - * Creates a result representing a successful compilation. - * - * @param inlinedBytecodes number of bytecodes inlined into the compilation, exclusive of the - * bytecodes in the root method - */ - public static HotSpotCompilationRequestResult success(int inlinedBytecodes) { - return new HotSpotCompilationRequestResult(null, true, inlinedBytecodes); - } - - /** - * Creates a result representing a failed compilation. - * - * @param failureMessage a description of the failure - * @param retry whether this is a transient failure where retrying may succeed - */ - public static HotSpotCompilationRequestResult failure(String failureMessage, boolean retry) { - return new HotSpotCompilationRequestResult(failureMessage, retry, 0); - } - - public String getFailureMessage() { - return failureMessage; - } - - public boolean getRetry() { - return retry; - } - - public int getInlinedBytecodes() { - return inlinedBytecodes; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.BytecodeFrame; -import jdk.vm.ci.code.CompiledCode; -import jdk.vm.ci.code.StackSlot; -import jdk.vm.ci.code.VirtualObject; -import jdk.vm.ci.code.site.DataPatch; -import jdk.vm.ci.code.site.Infopoint; -import jdk.vm.ci.code.site.Site; -import jdk.vm.ci.meta.Assumptions.Assumption; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * A {@link CompiledCode} with additional HotSpot-specific information required for installing the - * code in HotSpot's code cache. - */ -public class HotSpotCompiledCode implements CompiledCode { - - /** - * The name of this compilation unit. - */ - protected final String name; - - /** - * The buffer containing the emitted machine code. - */ - protected final byte[] targetCode; - - /** - * The leading number of bytes in {@link #targetCode} containing the emitted machine code. - */ - protected final int targetCodeSize; - - /** - * A list of code annotations describing special sites in {@link #targetCode}. - */ - protected final Site[] sites; - - /** - * A list of {@link Assumption} this code relies on. - */ - protected final Assumption[] assumptions; - - /** - * The list of the methods whose bytecodes were used as input to the compilation. If - * {@code null}, then the compilation did not record method dependencies. Otherwise, the first - * element of this array is the root method of the compilation. - */ - protected final ResolvedJavaMethod[] methods; - - /** - * A list of comments that will be included in code dumps. - */ - protected final Comment[] comments; - - /** - * The data section containing serialized constants for the emitted machine code. - */ - protected final byte[] dataSection; - - /** - * The minimum alignment of the data section. - */ - protected final int dataSectionAlignment; - - /** - * A list of relocations in the {@link #dataSection}. - */ - protected final DataPatch[] dataSectionPatches; - - /** - * A flag determining whether this code is immutable and position independent. - */ - protected final boolean isImmutablePIC; - - /** - * The total size of the stack frame of this compiled method. - */ - protected final int totalFrameSize; - - /** - * The deopt rescue slot. Must be non-null if there is a safepoint in the method. - */ - protected final StackSlot deoptRescueSlot; - - public static class Comment { - - public final String text; - public final int pcOffset; - - public Comment(int pcOffset, String text) { - this.text = text; - this.pcOffset = pcOffset; - } - } - - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `sites`, `targetCode`, `comments`, `methods`, `dataSection`, `dataSectionPatches` and `assumptions`") - public HotSpotCompiledCode(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection, - int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot) { - this.name = name; - this.targetCode = targetCode; - this.targetCodeSize = targetCodeSize; - this.sites = sites; - this.assumptions = assumptions; - this.methods = methods; - - this.comments = comments; - this.dataSection = dataSection; - this.dataSectionAlignment = dataSectionAlignment; - this.dataSectionPatches = dataSectionPatches; - this.isImmutablePIC = isImmutablePIC; - this.totalFrameSize = totalFrameSize; - this.deoptRescueSlot = deoptRescueSlot; - - assert validateFrames(); - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - - /** - * Ensure that all the frames passed into the VM are properly formatted with an empty or illegal - * slot following double word slots. - */ - private boolean validateFrames() { - for (Site site : sites) { - if (site instanceof Infopoint) { - Infopoint info = (Infopoint) site; - if (info.debugInfo != null) { - BytecodeFrame frame = info.debugInfo.frame(); - assert frame == null || frame.validateFormat(); - if (info.debugInfo.getVirtualObjectMapping() != null) { - for (VirtualObject v : info.debugInfo.getVirtualObjectMapping()) { - verifyVirtualObject(v); - } - } - } - } - } - return true; - } - - public static void verifyVirtualObject(VirtualObject v) { - v.verifyLayout(new VirtualObject.LayoutVerifier() { - @Override - public int getOffset(ResolvedJavaField field) { - return field.getOffset(); - } - }); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.StackSlot; -import jdk.vm.ci.code.site.DataPatch; -import jdk.vm.ci.code.site.Site; -import jdk.vm.ci.meta.Assumptions.Assumption; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * {@link HotSpotCompiledCode} destined for installation as an nmethod. - */ -public final class HotSpotCompiledNmethod extends HotSpotCompiledCode { - - protected final HotSpotResolvedJavaMethod method; - protected final int entryBCI; - - /** - * Compilation identifier. - */ - protected final int id; - - /** - * Address of a native {@code JVMCICompileState} object or 0L if no such object exists. - */ - protected final long compileState; - - protected final boolean hasUnsafeAccess; - - /** - * May be set by VM if code installation fails. It will describe in more detail why installation - * failed (e.g., exactly which dependency failed). - */ - @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage; - - public HotSpotCompiledNmethod(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection, - int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot, HotSpotResolvedJavaMethod method, int entryBCI, - int id, long compileState, boolean hasUnsafeAccess) { - super(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC, totalFrameSize, deoptRescueSlot); - this.method = method; - this.entryBCI = entryBCI; - this.id = id; - this.compileState = compileState; - this.hasUnsafeAccess = hasUnsafeAccess; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[" + id + ":" + method.format("%H.%n(%p)%r@") + entryBCI + "]"; - } - - public String getInstallationFailureMessage() { - return installationFailureMessage; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; - -/** - * The compressed representation of the {@link JavaConstant#NULL_POINTER null constant}. - */ -public final class HotSpotCompressedNullConstant implements JavaConstant, HotSpotConstant { - - public static final JavaConstant COMPRESSED_NULL = new HotSpotCompressedNullConstant(); - - private HotSpotCompressedNullConstant() { - } - - @Override - public JavaKind getJavaKind() { - return JavaKind.Object; - } - - @Override - public boolean isNull() { - return true; - } - - @Override - public boolean isCompressed() { - return true; - } - - @Override - public Constant compress() { - throw new IllegalArgumentException(); - } - - @Override - public Constant uncompress() { - return NULL_POINTER; - } - - @Override - public boolean isDefaultForKind() { - return true; - } - - @Override - public Object asBoxedPrimitive() { - throw new IllegalArgumentException(); - } - - @Override - public int asInt() { - throw new IllegalArgumentException(); - } - - @Override - public boolean asBoolean() { - throw new IllegalArgumentException(); - } - - @Override - public long asLong() { - throw new IllegalArgumentException(); - } - - @Override - public float asFloat() { - throw new IllegalArgumentException(); - } - - @Override - public double asDouble() { - throw new IllegalArgumentException(); - } - - @Override - public String toString() { - return JavaConstant.toString(this); - } - - @Override - public String toValueString() { - return "null"; - } - - @Override - public int hashCode() { - return System.identityHashCode(this); - } - - @Override - public boolean equals(Object o) { - return o instanceof HotSpotCompressedNullConstant; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.Constant; - -/** - * Marker interface for hotspot specific constants. - */ -public interface HotSpotConstant extends Constant { - - boolean isCompressed(); - - Constant compress(); - - Constant uncompress(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,897 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.vm.ci.meta.ConstantPool; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaField; -import jdk.vm.ci.meta.JavaMethod; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; -import jdk.vm.ci.meta.UnresolvedJavaField; -import jdk.vm.ci.meta.UnresolvedJavaMethod; -import jdk.vm.ci.meta.UnresolvedJavaType; - -/** - * Implementation of {@link ConstantPool} for HotSpot. - */ -public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleObject { - - /** - * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}. - */ - public static class Bytecodes { - public static final int LDC = 18; // 0x12 - public static final int LDC_W = 19; // 0x13 - public static final int LDC2_W = 20; // 0x14 - public static final int GETSTATIC = 178; // 0xB2 - public static final int PUTSTATIC = 179; // 0xB3 - public static final int GETFIELD = 180; // 0xB4 - public static final int PUTFIELD = 181; // 0xB5 - public static final int INVOKEVIRTUAL = 182; // 0xB6 - public static final int INVOKESPECIAL = 183; // 0xB7 - public static final int INVOKESTATIC = 184; // 0xB8 - public static final int INVOKEINTERFACE = 185; // 0xB9 - public static final int INVOKEDYNAMIC = 186; // 0xBA - public static final int NEW = 187; // 0xBB - public static final int NEWARRAY = 188; // 0xBC - public static final int ANEWARRAY = 189; // 0xBD - public static final int CHECKCAST = 192; // 0xC0 - public static final int INSTANCEOF = 193; // 0xC1 - public static final int MULTIANEWARRAY = 197; // 0xC5 - - static boolean isInvoke(int opcode) { - switch (opcode) { - case INVOKEVIRTUAL: - case INVOKESPECIAL: - case INVOKESTATIC: - case INVOKEINTERFACE: - case INVOKEDYNAMIC: - return true; - default: - return false; - } - } - - /** - * See: {@code Rewriter::maybe_rewrite_invokehandle}. - */ - static boolean isInvokeHandleAlias(int opcode) { - switch (opcode) { - case INVOKEVIRTUAL: - case INVOKESPECIAL: - return true; - default: - return false; - } - } - } - - static final class JvmConstant { - private final int tag; - private final String name; - - JvmConstant(int tag, String name) { - this.tag = tag; - this.name = name; - } - - @Override - public String toString() { - return name; - } - } - - /** - * {@code JVM_CONSTANT} constants used in the VM including both public and internal ones. - */ - static final class JvmConstants { - - private final HotSpotVMConfig c = config(); - private final int externalMax = c.jvmConstantExternalMax; - private final int internalMax = c.jvmConstantInternalMax; - private final int internalMin = c.jvmConstantInternalMin; - private final JvmConstant[] table = new JvmConstant[externalMax + 1 + (internalMax - internalMin) + 1]; - - final JvmConstant jvmUtf8 = add(new JvmConstant(c.jvmConstantUtf8, "Utf8")); - final JvmConstant jvmInteger = add(new JvmConstant(c.jvmConstantInteger, "Integer")); - final JvmConstant jvmLong = add(new JvmConstant(c.jvmConstantLong, "Long")); - final JvmConstant jvmFloat = add(new JvmConstant(c.jvmConstantFloat, "Float")); - final JvmConstant jvmDouble = add(new JvmConstant(c.jvmConstantDouble, "Double")); - final JvmConstant jvmClass = add(new JvmConstant(c.jvmConstantClass, "Class")); - final JvmConstant jvmUnresolvedClass = add(new JvmConstant(c.jvmConstantUnresolvedClass, "UnresolvedClass")); - final JvmConstant jvmUnresolvedClassInError = add(new JvmConstant(c.jvmConstantUnresolvedClassInError, "UnresolvedClassInError")); - final JvmConstant jvmString = add(new JvmConstant(c.jvmConstantString, "String")); - final JvmConstant jvmFieldref = add(new JvmConstant(c.jvmConstantFieldref, "Fieldref")); - final JvmConstant jvmMethodref = add(new JvmConstant(c.jvmConstantMethodref, "Methodref")); - final JvmConstant jvmInterfaceMethodref = add(new JvmConstant(c.jvmConstantInterfaceMethodref, "InterfaceMethodref")); - final JvmConstant jvmNameAndType = add(new JvmConstant(c.jvmConstantNameAndType, "NameAndType")); - final JvmConstant jvmMethodHandle = add(new JvmConstant(c.jvmConstantMethodHandle, "MethodHandle")); - final JvmConstant jvmMethodHandleInError = add(new JvmConstant(c.jvmConstantMethodHandleInError, "MethodHandleInError")); - final JvmConstant jvmMethodType = add(new JvmConstant(c.jvmConstantMethodType, "MethodType")); - final JvmConstant jvmMethodTypeInError = add(new JvmConstant(c.jvmConstantMethodTypeInError, "MethodTypeInError")); - final JvmConstant jvmInvokeDynamic = add(new JvmConstant(c.jvmConstantInvokeDynamic, "InvokeDynamic")); - final JvmConstant jvmDynamic = add(new JvmConstant(c.jvmConstantDynamic, "Dynamic")); - final JvmConstant jvmDynamicInError = add(new JvmConstant(c.jvmConstantDynamicInError, "DynamicInError")); - - private JvmConstant add(JvmConstant constant) { - table[indexOf(constant.tag)] = constant; - return constant; - } - - private int indexOf(int tag) { - if (tag >= internalMin) { - return tag - internalMin + externalMax + 1; - } else { - assert tag <= externalMax; - } - return tag; - } - - JvmConstant get(int tag) { - JvmConstant res = table[indexOf(tag)]; - if (res != null) { - return res; - } - throw new JVMCIError("Unknown JvmConstant tag %s", tag); - } - - @NativeImageReinitialize private static volatile JvmConstants instance; - - static JvmConstants instance() { - JvmConstants result = instance; - if (result == null) { - synchronized (JvmConstants.class) { - result = instance; - if (result == null) { - instance = result = new JvmConstants(); - } - } - } - return result; - } - } - - private static class LookupTypeCacheElement { - int lastCpi = Integer.MIN_VALUE; - JavaType javaType; - - LookupTypeCacheElement(int lastCpi, JavaType javaType) { - super(); - this.lastCpi = lastCpi; - this.javaType = javaType; - } - } - - /** - * Handle to the {@code ConstantPool} VM object. The handle is in - * {@code JVMCI::_metadata_handles}. - */ - private final long metadataHandle; - - private volatile LookupTypeCacheElement lastLookupType; - private final JvmConstants constants; - - /** - * Gets the JVMCI mirror from a HotSpot constant pool.The VM is responsible for ensuring that - * the ConstantPool is kept alive for the duration of this call and the - * {@link HotSpotJVMCIRuntime} keeps it alive after that. - * - * Called from the VM. - * - * @param metaspaceConstantPool a metaspace ConstantPool object - * @return the {@link HotSpotConstantPool} corresponding to {@code metaspaceConstantPool} - */ - @SuppressWarnings("unused") - @VMEntryPoint - private static HotSpotConstantPool fromMetaspace(long metaspaceConstantPool) { - return new HotSpotConstantPool(metaspaceConstantPool); - } - - private HotSpotConstantPool(long metadataHandle) { - this.metadataHandle = metadataHandle; - this.constants = JvmConstants.instance(); - HandleCleaner.create(this, metadataHandle); - } - - /** - * Gets the holder for this constant pool as {@link HotSpotResolvedObjectTypeImpl}. - * - * @return holder for this constant pool - */ - private HotSpotResolvedObjectType getHolder() { - return compilerToVM().getResolvedJavaType(this, config().constantPoolHolderOffset, false); - } - - /** - * Converts a raw index from the bytecodes to a constant pool cache index by adding a - * {@link HotSpotVMConfig#constantPoolCpCacheIndexTag constant}. - * - * @param rawIndex index from the bytecode - * @param opcode bytecode to convert the index for - * @return constant pool cache index - */ - private static int rawIndexToConstantPoolCacheIndex(int rawIndex, int opcode) { - int index; - if (opcode == Bytecodes.INVOKEDYNAMIC) { - index = rawIndex; - // See: ConstantPool::is_invokedynamic_index - if (index >= 0) { - throw new IllegalArgumentException("not an invokedynamic constant pool index " + index); - } - } else { - if (opcode == Bytecodes.GETFIELD || - opcode == Bytecodes.PUTFIELD || - opcode == Bytecodes.GETSTATIC || - opcode == Bytecodes.PUTSTATIC || - opcode == Bytecodes.INVOKEINTERFACE || - opcode == Bytecodes.INVOKEVIRTUAL || - opcode == Bytecodes.INVOKESPECIAL || - opcode == Bytecodes.INVOKESTATIC) { - index = rawIndex + config().constantPoolCpCacheIndexTag; - } else { - throw new IllegalArgumentException("unexpected opcode " + opcode); - - } - } - return index; - } - - /** - * Decode a constant pool cache index to a constant pool index. - * - * See {@code ConstantPool::decode_cpcache_index}. - * - * @param index constant pool cache index - * @return decoded index - */ - private static int decodeConstantPoolCacheIndex(int index) { - if (isInvokedynamicIndex(index)) { - return decodeInvokedynamicIndex(index); - } else { - return index - config().constantPoolCpCacheIndexTag; - } - } - - /** - * See {@code ConstantPool::is_invokedynamic_index}. - */ - private static boolean isInvokedynamicIndex(int index) { - return index < 0; - } - - /** - * See {@code ConstantPool::decode_invokedynamic_index}. - */ - private static int decodeInvokedynamicIndex(int i) { - if (!isInvokedynamicIndex(i)) { - throw new IllegalArgumentException("not an invokedynamic index: " + i); - } - return ~i; - } - - long getMetaspaceConstantPool() { - return getMetaspacePointer(); - } - - @Override - public long getMetadataHandle() { - return metadataHandle; - } - - /** - * Gets the constant pool tag at index {@code index}. - * - * @param index constant pool index - * @return constant pool tag - */ - private JvmConstant getTagAt(int index) { - checkBounds(index); - HotSpotVMConfig config = config(); - final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset); - final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index); - if (tag == 0) { - return null; - } - return constants.get(tag); - } - - /** - * Gets the constant pool entry at index {@code index}. - * - * @param index constant pool index - * @return constant pool entry - */ - long getEntryAt(int index) { - checkBounds(index); - int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; - return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + offset); - } - - /** - * Gets the integer constant pool entry at index {@code index}. - * - * @param index constant pool index - * @return integer constant pool entry at index - */ - private int getIntAt(int index) { - checkTag(index, constants.jvmInteger); - int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; - return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); - } - - /** - * Gets the long constant pool entry at index {@code index}. - * - * @param index constant pool index - * @return long constant pool entry - */ - private long getLongAt(int index) { - checkTag(index, constants.jvmLong); - int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; - return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + offset); - } - - /** - * Gets the float constant pool entry at index {@code index}. - * - * @param index constant pool index - * @return float constant pool entry - */ - private float getFloatAt(int index) { - checkTag(index, constants.jvmFloat); - int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; - return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + offset); - } - - /** - * Gets the double constant pool entry at index {@code index}. - * - * @param index constant pool index - * @return float constant pool entry - */ - private double getDoubleAt(int index) { - checkTag(index, constants.jvmDouble); - int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; - return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + offset); - } - - /** - * Gets the {@code JVM_CONSTANT_NameAndType} constant pool entry at index {@code index}. - * - * @param index constant pool index - * @return {@code JVM_CONSTANT_NameAndType} constant pool entry - */ - private int getNameAndTypeAt(int index) { - checkTag(index, constants.jvmNameAndType); - int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; - return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); - } - - /** - * Gets the {@code JVM_CONSTANT_NameAndType} reference index constant pool entry at index - * {@code index}. - * - * @param index constant pool index - * @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry - */ - private int getNameAndTypeRefIndexAt(int index) { - return compilerToVM().lookupNameAndTypeRefIndexInPool(this, index); - } - - /** - * Gets the name of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by another - * entry denoted by {@code which}. - * - * @param which constant pool index or constant pool cache index - * @return name as {@link String} - */ - private String getNameOf(int which) { - return compilerToVM().lookupNameInPool(this, which); - } - - /** - * Gets the name reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry at - * index {@code index}. - * - * @param index constant pool index - * @return name reference index - */ - private int getNameRefIndexAt(int index) { - final int refIndex = getNameAndTypeAt(index); - // name ref index is in the low 16-bits. - return refIndex & 0xFFFF; - } - - /** - * Gets the signature of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by - * another entry denoted by {@code which}. - * - * @param which constant pool index or constant pool cache index - * @return signature as {@link String} - */ - private String getSignatureOf(int which) { - return compilerToVM().lookupSignatureInPool(this, which); - } - - /** - * Gets the signature reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry - * at index {@code index}. - * - * @param index constant pool index - * @return signature reference index - */ - private int getSignatureRefIndexAt(int index) { - final int refIndex = getNameAndTypeAt(index); - // signature ref index is in the high 16-bits. - return refIndex >>> 16; - } - - /** - * Gets the klass reference index constant pool entry at index {@code index}. - * - * @param index constant pool index - * @return klass reference index - */ - private int getKlassRefIndexAt(int index) { - return compilerToVM().lookupKlassRefIndexInPool(this, index); - } - - /** - * Gets the uncached klass reference index constant pool entry at index {@code index}. See: - * {@code ConstantPool::uncached_klass_ref_index_at}. - * - * @param index constant pool index - * @return klass reference index - */ - private int getUncachedKlassRefIndexAt(int index) { - checkTagIsFieldOrMethod(index); - int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; - final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); - // klass ref index is in the low 16-bits. - return refIndex & 0xFFFF; - } - - /** - * Checks that the constant pool index {@code index} is in the bounds of the constant pool. - * - * @param index constant pool index - * @throws IndexOutOfBoundsException if the check fails - */ - private void checkBounds(int index) { - if (index < 1 || index >= length()) { - throw new IndexOutOfBoundsException("index " + index + " not between 1 and " + length()); - } - } - - /** - * Checks that the constant pool tag at index {@code index} is equal to {@code tag}. - * - * @param index constant pool index - * @param tag expected tag - * @throws IllegalArgumentException if the check fails - */ - private void checkTag(int index, JvmConstant tag) { - final JvmConstant tagAt = getTagAt(index); - if (tagAt != tag) { - throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt + " but expected " + tag); - } - } - - /** - * Asserts that the constant pool tag at index {@code index} is a - * {@link JvmConstants#jvmFieldref}, or a {@link JvmConstants#jvmMethodref}, or a - * {@link JvmConstants#jvmInterfaceMethodref}. - * - * @param index constant pool index - * @throws IllegalArgumentException if the check fails - */ - private void checkTagIsFieldOrMethod(int index) { - final JvmConstant tagAt = getTagAt(index); - if (tagAt != constants.jvmFieldref && tagAt != constants.jvmMethodref && tagAt != constants.jvmInterfaceMethodref) { - throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt); - } - } - - @Override - public int length() { - return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolLengthOffset); - } - - public boolean hasDynamicConstant() { - return (flags() & config().constantPoolHasDynamicConstant) != 0; - } - - private int flags() { - return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolFlagsOffset); - } - - /** - * Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of a field. - */ - JavaConstant getStaticFieldConstantValue(int cpi) { - final JvmConstant tag = getTagAt(cpi); - switch (tag.name) { - case "Integer": - return JavaConstant.forInt(getIntAt(cpi)); - case "Long": - return JavaConstant.forLong(getLongAt(cpi)); - case "Float": - return JavaConstant.forFloat(getFloatAt(cpi)); - case "Double": - return JavaConstant.forDouble(getDoubleAt(cpi)); - case "String": - return compilerToVM().getUncachedStringInPool(this, cpi); - default: - throw new IllegalArgumentException("Illegal entry for a ConstantValue attribute:" + tag); - } - } - - @Override - public Object lookupConstant(int cpi) { - final JvmConstant tag = getTagAt(cpi); - switch (tag.name) { - case "Integer": - return JavaConstant.forInt(getIntAt(cpi)); - case "Long": - return JavaConstant.forLong(getLongAt(cpi)); - case "Float": - return JavaConstant.forFloat(getFloatAt(cpi)); - case "Double": - return JavaConstant.forDouble(getDoubleAt(cpi)); - case "Class": - case "UnresolvedClass": - case "UnresolvedClassInError": - final int opcode = -1; // opcode is not used - return lookupType(cpi, opcode); - case "String": - /* - * Normally, we would expect a String here, but unsafe anonymous classes can have - * "pseudo strings" (arbitrary live objects) patched into a String entry. Such - * entries do not have a symbol in the constant pool slot. - */ - return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi); - case "MethodHandle": - case "MethodHandleInError": - case "MethodType": - case "MethodTypeInError": - case "Dynamic": - case "DynamicInError": - return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi); - default: - throw new JVMCIError("Unknown constant pool tag %s", tag); - } - } - - @Override - public String lookupUtf8(int cpi) { - checkTag(cpi, constants.jvmUtf8); - return compilerToVM().getSymbol(getEntryAt(cpi)); - } - - @Override - public Signature lookupSignature(int cpi) { - return new HotSpotSignature(runtime(), lookupUtf8(cpi)); - } - - @Override - public JavaConstant lookupAppendix(int cpi, int opcode) { - if (!Bytecodes.isInvoke(opcode)) { - throw new IllegalArgumentException("expected an invoke bytecode at " + cpi + ", got " + opcode); - } - - final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); - return compilerToVM().lookupAppendixInPool(this, index); - } - - /** - * Gets a {@link JavaType} corresponding a given resolved or unresolved type. - * - * @param type either a ResolvedJavaType or a String naming a unresolved type. - */ - private static JavaType getJavaType(final Object type) { - if (type instanceof String) { - String name = (String) type; - return UnresolvedJavaType.create("L" + name + ";"); - } else { - return (JavaType) type; - } - } - - @Override - public JavaMethod lookupMethod(int cpi, int opcode) { - final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); - final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, index, (byte) opcode); - if (method != null) { - return method; - } else { - // Get the method's name and signature. - String name = getNameOf(index); - HotSpotSignature signature = new HotSpotSignature(runtime(), getSignatureOf(index)); - if (opcode == Bytecodes.INVOKEDYNAMIC) { - HotSpotResolvedObjectType holder = runtime().getMethodHandleClass(); - return new UnresolvedJavaMethod(name, signature, holder); - } else { - final int klassIndex = getKlassRefIndexAt(index); - final Object type = compilerToVM().lookupKlassInPool(this, klassIndex); - JavaType holder = getJavaType(type); - return new UnresolvedJavaMethod(name, signature, holder); - } - } - } - - @Override - public JavaType lookupType(int cpi, int opcode) { - final LookupTypeCacheElement elem = this.lastLookupType; - if (elem != null && elem.lastCpi == cpi) { - return elem.javaType; - } else { - final Object type = compilerToVM().lookupKlassInPool(this, cpi); - JavaType result = getJavaType(type); - if (result instanceof ResolvedJavaType) { - this.lastLookupType = new LookupTypeCacheElement(cpi, result); - } - return result; - } - } - - @Override - public JavaType lookupReferencedType(int cpi, int opcode) { - int index; - switch (opcode) { - case Bytecodes.CHECKCAST: - case Bytecodes.INSTANCEOF: - case Bytecodes.NEW: - case Bytecodes.ANEWARRAY: - case Bytecodes.MULTIANEWARRAY: - case Bytecodes.LDC: - case Bytecodes.LDC_W: - case Bytecodes.LDC2_W: - index = cpi; - break; - case Bytecodes.GETSTATIC: - case Bytecodes.PUTSTATIC: - case Bytecodes.GETFIELD: - case Bytecodes.PUTFIELD: - case Bytecodes.INVOKEVIRTUAL: - case Bytecodes.INVOKESPECIAL: - case Bytecodes.INVOKESTATIC: - case Bytecodes.INVOKEINTERFACE: { - index = rawIndexToConstantPoolCacheIndex(cpi, opcode); - index = getKlassRefIndexAt(index); - break; - } - default: - throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode); - } - final Object type = compilerToVM().lookupKlassInPool(this, index); - return getJavaType(type); - } - - @Override - public JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode) { - final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); - final int nameAndTypeIndex = getNameAndTypeRefIndexAt(index); - final int typeIndex = getSignatureRefIndexAt(nameAndTypeIndex); - String typeName = lookupUtf8(typeIndex); - JavaType type = runtime().lookupType(typeName, getHolder(), false); - - final int holderIndex = getKlassRefIndexAt(index); - JavaType holder = lookupType(holderIndex, opcode); - - if (holder instanceof HotSpotResolvedObjectTypeImpl) { - int[] info = new int[3]; - HotSpotResolvedObjectTypeImpl resolvedHolder; - try { - resolvedHolder = compilerToVM().resolveFieldInPool(this, index, (HotSpotResolvedJavaMethodImpl) method, (byte) opcode, info); - } catch (Throwable t) { - /* - * If there was an exception resolving the field we give up and return an unresolved - * field. - */ - return new UnresolvedJavaField(holder, lookupUtf8(getNameRefIndexAt(nameAndTypeIndex)), type); - } - final int flags = info[0]; - final int offset = info[1]; - final int fieldIndex = info[2]; - HotSpotResolvedJavaField result = resolvedHolder.createField(type, offset, flags, fieldIndex); - return result; - } else { - return new UnresolvedJavaField(holder, lookupUtf8(getNameRefIndexAt(nameAndTypeIndex)), type); - } - } - - /** - * Converts a raw index from the bytecodes to a constant pool index (not a cache index). - * - * @param rawIndex index from the bytecode - * - * @param opcode bytecode to convert the index for - * - * @return constant pool index - */ - public int rawIndexToConstantPoolIndex(int rawIndex, int opcode) { - int index; - if (isInvokedynamicIndex(rawIndex)) { - if (opcode != Bytecodes.INVOKEDYNAMIC) { - throw new IllegalArgumentException("expected INVOKEDYNAMIC at " + rawIndex + ", got " + opcode); - } - index = decodeInvokedynamicIndex(rawIndex) + config().constantPoolCpCacheIndexTag; - } else { - if (opcode == Bytecodes.INVOKEDYNAMIC) { - throw new IllegalArgumentException("unexpected INVOKEDYNAMIC at " + rawIndex); - } - index = rawIndexToConstantPoolCacheIndex(rawIndex, opcode); - } - return compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); - } - - @Override - public void loadReferencedType(int cpi, int opcode) { - loadReferencedType(cpi, opcode, true /* initialize */); - } - - @Override - @SuppressWarnings("fallthrough") - public void loadReferencedType(int cpi, int opcode, boolean initialize) { - int index; - switch (opcode) { - case Bytecodes.CHECKCAST: - case Bytecodes.INSTANCEOF: - case Bytecodes.NEW: - case Bytecodes.ANEWARRAY: - case Bytecodes.MULTIANEWARRAY: - case Bytecodes.LDC: - case Bytecodes.LDC_W: - case Bytecodes.LDC2_W: - index = cpi; - break; - case Bytecodes.INVOKEDYNAMIC: { - // invokedynamic instructions point to a constant pool cache entry. - index = decodeConstantPoolCacheIndex(cpi) + config().constantPoolCpCacheIndexTag; - index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); - break; - } - case Bytecodes.GETSTATIC: - case Bytecodes.PUTSTATIC: - case Bytecodes.GETFIELD: - case Bytecodes.PUTFIELD: - case Bytecodes.INVOKEVIRTUAL: - case Bytecodes.INVOKESPECIAL: - case Bytecodes.INVOKESTATIC: - case Bytecodes.INVOKEINTERFACE: { - // invoke and field instructions point to a constant pool cache entry. - index = rawIndexToConstantPoolCacheIndex(cpi, opcode); - index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); - break; - } - default: - throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode); - } - - final JvmConstant tag = getTagAt(index); - if (tag == null) { - assert getTagAt(index - 1) == constants.jvmDouble || getTagAt(index - 1) == constants.jvmLong; - return; - } - switch (tag.name) { - case "Methodref": - case "Fieldref": - case "InterfaceMethodref": - index = getUncachedKlassRefIndexAt(index); - // Read the tag only once because it could change between multiple reads. - final JvmConstant klassTag = getTagAt(index); - assert klassTag == constants.jvmClass || klassTag == constants.jvmUnresolvedClass || klassTag == constants.jvmUnresolvedClassInError : klassTag; - // fall through - case "Class": - case "UnresolvedClass": - case "UnresolvedClassInError": - final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index); - if (initialize && !type.isPrimitive() && !type.isArray()) { - type.ensureInitialized(); - } - if (tag == constants.jvmMethodref) { - if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) { - final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); - checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); - compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex); - } - } - - break; - case "InvokeDynamic": - if (isInvokedynamicIndex(cpi)) { - compilerToVM().resolveInvokeDynamicInPool(this, cpi); - } - break; - default: - // nothing - break; - } - - } - - // Lazily initialized. - private static String[] signaturePolymorphicHolders; - - /** - * Determines if {@code type} contains signature polymorphic methods. - */ - @SuppressFBWarnings(value = "LI_LAZY_INIT_STATIC", justification = "signaturePolymorphicHolders is a cache, not a singleton that must be constructed exactly once" + - "and compiler re-ordering is not an issue due to the VM call") - static boolean isSignaturePolymorphicHolder(final ResolvedJavaType type) { - String name = type.getName(); - if (signaturePolymorphicHolders == null) { - signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders(); - } - for (String holder : signaturePolymorphicHolders) { - if (name.equals(holder)) { - return true; - } - } - return false; - } - - /** - * Check for a resolved dynamic adapter method at the specified index, resulting from either a - * resolved invokedynamic or invokevirtual on a signature polymorphic MethodHandle method - * (HotSpot invokehandle). - * - * @param cpi the constant pool index - * @param opcode the opcode of the instruction for which the lookup is being performed - * @return {@code true} if a signature polymorphic method reference was found, otherwise - * {@code false} - */ - public boolean isResolvedDynamicInvoke(int cpi, int opcode) { - if (Bytecodes.isInvokeHandleAlias(opcode)) { - final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); - checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); - int op = compilerToVM().isResolvedInvokeHandleInPool(this, methodRefCacheIndex); - return op == opcode; - } - return false; - } - - public String getSourceFileName() { - final int sourceFileNameIndex = UNSAFE.getChar(getMetaspaceConstantPool() + config().constantPoolSourceFileNameIndexOffset); - if (sourceFileNameIndex == 0) { - return null; - } - return lookupUtf8(sourceFileNameIndex); - } - - @Override - public String toString() { - HotSpotResolvedObjectType holder = getHolder(); - return "HotSpotConstantPool<" + holder.toJavaName() + ">"; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2017, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; - -/** - * Represents a constant that was retrieved from a constant pool. Used to keep track of the constant - * pool slot for the constant. - */ -public final class HotSpotConstantPoolObject implements JavaConstant { - - public static JavaConstant forObject(HotSpotResolvedObjectType type, int cpi, JavaConstant object) { - return new HotSpotConstantPoolObject(type, cpi, object); - } - - private final JavaConstant constant; - private final HotSpotResolvedObjectType type; - private final int cpi; - - public HotSpotResolvedObjectType getCpType() { - return type; - } - - public int getCpi() { - return cpi; - } - - HotSpotConstantPoolObject(HotSpotResolvedObjectType type, int cpi, JavaConstant constant) { - this.type = type; - this.cpi = cpi; - this.constant = constant; - } - - @Override - public boolean equals(Object o) { - if (o instanceof HotSpotConstantPoolObject) { - HotSpotConstantPoolObject other = (HotSpotConstantPoolObject) o; - return type.equals(other.type) && cpi == other.cpi && constant.equals(other.constant); - } - return false; - } - - @Override - public int hashCode() { - return constant.hashCode() + cpi + type.hashCode(); - } - - @Override - public JavaKind getJavaKind() { - return constant.getJavaKind(); - } - - @Override - public boolean isNull() { - return constant.isNull(); - } - - @Override - public boolean isDefaultForKind() { - return constant.isDefaultForKind(); - } - - @Override - public Object asBoxedPrimitive() { - return constant.asBoxedPrimitive(); - } - - @Override - public int asInt() { - return constant.asInt(); - } - - @Override - public boolean asBoolean() { - return constant.asBoolean(); - } - - @Override - public long asLong() { - return constant.asLong(); - } - - @Override - public float asFloat() { - return constant.asFloat(); - } - - @Override - public double asDouble() { - return 0; - } - - @Override - public String toValueString() { - return getCpType().getName() + getCpi(); - } - - @Override - public String toString() { - return super.toString() + "@" + toValueString(); - } - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import java.util.Objects; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.MemoryAccessProvider; -import jdk.vm.ci.meta.MethodHandleAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * HotSpot implementation of {@link ConstantReflectionProvider}. - */ -public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider { - - protected final HotSpotJVMCIRuntime runtime; - protected final HotSpotMethodHandleAccessProvider methodHandleAccess; - private final HotSpotMemoryAccessProviderImpl memoryAccess; - - public HotSpotConstantReflectionProvider(HotSpotJVMCIRuntime runtime) { - this.runtime = runtime; - this.methodHandleAccess = new HotSpotMethodHandleAccessProvider(this); - this.memoryAccess = new HotSpotMemoryAccessProviderImpl(runtime); - } - - @Override - public MethodHandleAccessProvider getMethodHandleAccess() { - return methodHandleAccess; - } - - @Override - public MemoryAccessProvider getMemoryAccessProvider() { - return memoryAccess; - } - - @Override - public Boolean constantEquals(Constant x, Constant y) { - if (x == y) { - return true; - } else if (x instanceof HotSpotObjectConstantImpl) { - return y instanceof HotSpotObjectConstantImpl && x.equals(y); - } else { - return Objects.equals(x, y); - } - } - - @Override - public Integer readArrayLength(JavaConstant array) { - if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) { - return null; - } - - HotSpotObjectConstantImpl arrayObject = ((HotSpotObjectConstantImpl) array); - return runtime.getReflection().getLength(arrayObject); - } - - @Override - public JavaConstant readArrayElement(JavaConstant array, int index) { - if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) { - return null; - } - HotSpotObjectConstantImpl arrayObject = ((HotSpotObjectConstantImpl) array); - return runtime.getReflection().readArrayElement(arrayObject, index); - } - - /** - * Check if the constant is a boxed value that is guaranteed to be cached by the platform. - * Otherwise the generated code might be the only reference to the boxed value and since object - * references from nmethods are weak this can cause GC problems. - * - * @return true if the box is cached - */ - private static boolean isBoxCached(JavaConstant source) { - switch (source.getJavaKind()) { - case Boolean: - return true; - case Char: - return source.asInt() <= 127; - case Byte: - case Short: - case Int: - return source.asInt() >= -128 && source.asInt() <= 127; - case Long: - return source.asLong() >= -128 && source.asLong() <= 127; - case Float: - case Double: - return false; - default: - throw new IllegalArgumentException("unexpected kind " + source.getJavaKind()); - } - } - - @Override - public JavaConstant boxPrimitive(JavaConstant source) { - if (source == null || !source.getJavaKind().isPrimitive() || !isBoxCached(source)) { - return null; - } - return runtime.getReflection().boxPrimitive(source); - } - - @Override - public JavaConstant unboxPrimitive(JavaConstant source) { - if (source == null || !source.getJavaKind().isObject()) { - return null; - } - if (source.isNull()) { - return null; - } - return runtime.getReflection().unboxPrimitive((HotSpotObjectConstantImpl) source); - } - - @Override - public JavaConstant forString(String value) { - return runtime.getReflection().forObject(value); - } - - public JavaConstant forObject(Object value) { - return runtime.getReflection().forObject(value); - } - - @Override - public ResolvedJavaType asJavaType(Constant constant) { - if (constant instanceof HotSpotObjectConstantImpl) { - return ((HotSpotObjectConstantImpl) constant).asJavaType(); - } - if (constant instanceof HotSpotMetaspaceConstant) { - MetaspaceObject obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant); - if (obj instanceof HotSpotResolvedObjectTypeImpl) { - return (ResolvedJavaType) obj; - } - } - return null; - } - - @Override - public JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver) { - HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field; - if (hotspotField.isStatic()) { - HotSpotResolvedObjectTypeImpl holder = (HotSpotResolvedObjectTypeImpl) hotspotField.getDeclaringClass(); - if (holder.isInitialized()) { - return runtime().compilerToVm.readFieldValue(holder, (HotSpotResolvedObjectTypeImpl) hotspotField.getDeclaringClass(), hotspotField.getOffset(), - hotspotField.getType().getJavaKind()); - } - } else if (receiver instanceof HotSpotObjectConstantImpl) { - return ((HotSpotObjectConstantImpl) receiver).readFieldValue(hotspotField); - } else if (receiver == null) { - throw new NullPointerException("receiver is null"); - } - return null; - } - - @Override - public JavaConstant asJavaClass(ResolvedJavaType type) { - return ((HotSpotResolvedJavaType) type).getJavaMirror(); - } - - @Override - public Constant asObjectHub(ResolvedJavaType type) { - if (type instanceof HotSpotResolvedObjectType) { - return ((HotSpotResolvedObjectType) type).klass(); - } else { - throw JVMCIError.unimplemented(); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.InvokeTarget; - -public class HotSpotForeignCallTarget implements InvokeTarget { - - /** - * The entry point address of this call's target. - */ - @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "accessed by subclasses")// - protected long address; - - public HotSpotForeignCallTarget(long address) { - this.address = address; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; - -import jdk.vm.ci.code.InstalledCode; - -/** - * Implementation of {@link InstalledCode} for HotSpot representing a {@code CodeBlob}. The address - * of the {@code CodeBlob} is stored in {@link InstalledCode#address}. - */ -public abstract class HotSpotInstalledCode extends InstalledCode { - - /** - * Total size of the code blob (i.e. {@code CodeBlob::size()}). - */ - @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int size; - - /** - * Start address of the code (i.e. {@code CodeBlob::code_begin()}). - */ - @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private long codeStart; - - /** - * Size of the code (i.e. {@code CodeBlob::code_size()}). - */ - @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int codeSize; - - public HotSpotInstalledCode(String name) { - super(name); - } - - /** - * Gets the value of {@code CodeBlob::size()}. - */ - public int getSize() { - return size; - } - - @Override - public abstract String toString(); - - /** - * Gets the value of {@code CodeBlob::code_begin()} if {@linkplain #isValid() valid}, 0 - * otherwise. - */ - @Override - public long getStart() { - return codeStart; - } - - /** - * Gets the value of {@code CodeBlob::code_size()} if {@linkplain #isValid() valid}, 0 - * otherwise. - */ - public long getCodeSize() { - return codeSize; - } - - @Override - public byte[] getCode() { - return compilerToVM().getCode(this); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJavaType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJavaType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.JavaType; - -/** - * Common base class for all HotSpot {@link JavaType} implementations. - */ -public abstract class HotSpotJavaType implements JavaType { - - private final String name; - - public HotSpotJavaType(String name) { - this.name = name; - } - - @Override - public final String getName() { - return name; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.HashMap; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * Implementation of {@link HotSpotJVMCIReflection} in terms of standard JDK reflection API. This is - * only available when running in the HotSpot heap. - */ -final class HotSpotJDKReflection extends HotSpotJVMCIReflection { - - @Override - Object resolveObject(HotSpotObjectConstantImpl object) { - if (object == null) { - return null; - } - return ((DirectHotSpotObjectConstantImpl) object).object; - } - - @Override - boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl obj) { - Class javaMirror = getMirror(holder); - Object value = resolveObject(obj); - return javaMirror.isInstance(value); - } - - @Override - boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType) { - Class javaMirror = getMirror(holder); - return javaMirror.isAssignableFrom(getMirror(otherType)); - - } - - @Override - Annotation[] getAnnotations(HotSpotResolvedObjectTypeImpl holder) { - Class javaMirror = getMirror(holder); - return javaMirror.getAnnotations(); - } - - @Override - Annotation[] getDeclaredAnnotations(HotSpotResolvedObjectTypeImpl holder) { - Class javaMirror = getMirror(holder); - return javaMirror.getDeclaredAnnotations(); - } - - @Override - T getAnnotation(HotSpotResolvedObjectTypeImpl holder, Class annotationClass) { - Class javaMirror = getMirror(holder); - return javaMirror.getAnnotation(annotationClass); - } - - @Override - boolean isLocalClass(HotSpotResolvedObjectTypeImpl holder) { - Class javaMirror = getMirror(holder); - return javaMirror.isLocalClass(); - } - - @Override - boolean isMemberClass(HotSpotResolvedObjectTypeImpl holder) { - Class javaMirror = getMirror(holder); - return javaMirror.isMemberClass(); - } - - @Override - HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder) { - Class javaMirror = getMirror(holder); - return (HotSpotResolvedObjectType) runtime().fromClass(javaMirror.getEnclosingClass()); - } - - @Override - boolean equals(HotSpotObjectConstantImpl a, HotSpotObjectConstantImpl b) { - return resolveObject(a) == resolveObject(b) && a.isCompressed() == b.isCompressed(); - } - - // This field is being kept around for compatibility with libgraal - @SuppressWarnings("unused") private long oopSizeOffset; - - @Override - ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod) { - java.lang.reflect.Parameter[] javaParameters = getMethod(javaMethod).getParameters(); - ResolvedJavaMethod.Parameter[] res = new ResolvedJavaMethod.Parameter[javaParameters.length]; - for (int i = 0; i < res.length; i++) { - java.lang.reflect.Parameter src = javaParameters[i]; - String paramName = src.isNamePresent() ? src.getName() : null; - res[i] = new ResolvedJavaMethod.Parameter(paramName, src.getModifiers(), javaMethod, i); - } - return res; - } - - @Override - Annotation[][] getParameterAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { - return getMethod(javaMethod).getParameterAnnotations(); - } - - @Override - Type[] getGenericParameterTypes(HotSpotResolvedJavaMethodImpl javaMethod) { - return getMethod(javaMethod).getGenericParameterTypes(); - } - - @Override - Annotation[] getFieldAnnotations(HotSpotResolvedJavaFieldImpl javaField) { - return getField(javaField).getAnnotations(); - } - - @Override - Annotation[] getMethodAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { - return getMethod(javaMethod).getAnnotations(); - } - - @Override - Annotation[] getMethodDeclaredAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { - return getMethod(javaMethod).getDeclaredAnnotations(); - } - - @Override - Annotation[] getFieldDeclaredAnnotations(HotSpotResolvedJavaFieldImpl javaField) { - return getField(javaField).getDeclaredAnnotations(); - } - - @Override - T getMethodAnnotation(HotSpotResolvedJavaMethodImpl javaMethod, Class annotationClass) { - return getMethod(javaMethod).getAnnotation(annotationClass); - } - - @Override - T getFieldAnnotation(HotSpotResolvedJavaFieldImpl javaField, Class annotationClass) { - return getField(javaField).getAnnotation(annotationClass); - } - - @Override - HotSpotResolvedObjectTypeImpl getType(HotSpotObjectConstantImpl object) { - Object value = resolveObject(object); - Class theClass = value.getClass(); - return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(theClass); - } - - @Override - String asString(HotSpotObjectConstantImpl object) { - Object value = resolveObject(object); - if (value instanceof String) { - return (String) value; - } - return null; - } - - @Override - ResolvedJavaType asJavaType(HotSpotObjectConstantImpl object) { - Object value = resolveObject(object); - if (value instanceof Class) { - Class javaClass = (Class) value; - return runtime().fromClass(javaClass); - } - if (value instanceof ResolvedJavaType) { - return (ResolvedJavaType) value; - } - return null; - } - - @SuppressWarnings("unchecked") - @Override - T asObject(HotSpotObjectConstantImpl object, Class type) { - Object value = resolveObject(object); - if (type.isInstance(value)) { - return (T) value; - } - return null; - } - - @Override - Object asObject(HotSpotObjectConstantImpl object, HotSpotResolvedJavaType type) { - Object value = resolveObject(object); - if (getMirror(type).isInstance(value)) { - return value; - } - return null; - } - - @Override - String formatString(HotSpotObjectConstantImpl object) { - return JavaKind.Object.format(resolveObject(object)); - } - - @Override - Integer getLength(HotSpotObjectConstantImpl arrayObject) { - Object object = resolveObject(arrayObject); - if (object.getClass().isArray()) { - return Array.getLength(object); - } - return null; - } - - @Override - JavaConstant readArrayElement(HotSpotObjectConstantImpl arrayObject, int index) { - Object a = resolveObject(arrayObject); - if (!a.getClass().isArray() || index < 0 || index >= Array.getLength(a)) { - return null; - } - if (a instanceof Object[]) { - Object element = ((Object[]) a)[index]; - return forObject(element); - } else { - if (a instanceof int[]) { - return JavaConstant.forInt(((int[]) a)[index]); - } else if (a instanceof char[]) { - return JavaConstant.forChar(((char[]) a)[index]); - } else if (a instanceof byte[]) { - return JavaConstant.forByte(((byte[]) a)[index]); - } else if (a instanceof long[]) { - return JavaConstant.forLong(((long[]) a)[index]); - } else if (a instanceof short[]) { - return JavaConstant.forShort(((short[]) a)[index]); - } else if (a instanceof float[]) { - return JavaConstant.forFloat(((float[]) a)[index]); - } else if (a instanceof double[]) { - return JavaConstant.forDouble(((double[]) a)[index]); - } else if (a instanceof boolean[]) { - return JavaConstant.forBoolean(((boolean[]) a)[index]); - } else { - throw new JVMCIError("Should not reach here"); - } - } - } - - @Override - JavaConstant unboxPrimitive(HotSpotObjectConstantImpl source) { - return JavaConstant.forBoxedPrimitive(resolveObject(source)); - } - - @Override - JavaConstant forObject(Object value) { - if (value == null) { - return JavaConstant.NULL_POINTER; - } - return forNonNullObject(value); - } - - private static HotSpotObjectConstantImpl forNonNullObject(Object value) { - return DirectHotSpotObjectConstantImpl.forNonNullObject(value, false); - } - - @Override - JavaConstant boxPrimitive(JavaConstant source) { - return forNonNullObject(source.asBoxedPrimitive()); - } - - /** - * Gets a {@link Method} object corresponding to {@code method}. This method guarantees the same - * {@link Method} object is returned if called twice on the same {@code method} value. - */ - static Executable getMethod(HotSpotResolvedJavaMethodImpl method) { - assert !method.isClassInitializer() : method; - if (method.toJavaCache == null) { - synchronized (method) { - if (method.toJavaCache == null) { - method.toJavaCache = compilerToVM().asReflectionExecutable(method); - } - } - } - return method.toJavaCache; - } - - /** - * Gets a {@link Field} object corresponding to {@code field}. This method guarantees the same - * {@link Field} object is returned if called twice on the same {@code field} value. This is - * required to ensure the results of {@link HotSpotResolvedJavaFieldImpl#getAnnotations()} and - * {@link HotSpotResolvedJavaFieldImpl#getAnnotation(Class)} are stable (i.e., for a given field - * {@code f} and annotation class {@code a}, the same object is returned for each call to - * {@code f.getAnnotation(a)}). - */ - static Field getField(HotSpotResolvedJavaFieldImpl field) { - HotSpotResolvedObjectTypeImpl declaringClass = field.getDeclaringClass(); - synchronized (declaringClass) { - HashMap cache = declaringClass.reflectionFieldCache; - if (cache == null) { - cache = new HashMap<>(); - declaringClass.reflectionFieldCache = cache; - } - Field reflect = cache.get(field); - if (reflect == null) { - reflect = compilerToVM().asReflectionField(field.getDeclaringClass(), field.getIndex()); - cache.put(field, reflect); - } - return reflect; - } - } - - Class getMirror(HotSpotResolvedObjectTypeImpl holder) { - return (Class) resolveObject((HotSpotObjectConstantImpl) holder.getJavaMirror()); - } - - Class getMirror(HotSpotResolvedJavaType type) { - assert type != null; - if (type instanceof HotSpotResolvedPrimitiveType) { - return (Class) resolveObject(((HotSpotResolvedPrimitiveType) type).mirror); - } else { - return getMirror((HotSpotResolvedObjectTypeImpl) type); - } - } -} - diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ -package jdk.vm.ci.hotspot; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.runtime.JVMCIBackend; - -public interface HotSpotJVMCIBackendFactory { - - JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host); - - /** - * Gets the CPU architecture of this backend. - */ - String getArchitecture(); - - /** - * Converts a bit mask of CPU features to enum constants. - * - * @param CPU feature enum type - * @param enumType the class of {@code CPUFeatureType} - * @param constants VM constants. Each entry whose key starts with {@code "VM_Version::CPU_"} - * specifies a CPU feature and its value is a mask for a bit in {@code features} - * @param features bits specifying CPU features - * @param renaming maps from VM feature names to enum constant names where the two differ - * @throws IllegalArgumentException if any VM CPU feature constant cannot be converted to an - * enum value - * @return the set of converted values - */ - static > EnumSet convertFeatures( - Class enumType, - Map constants, - long features, - Map renaming) { - EnumSet outFeatures = EnumSet.noneOf(enumType); - List missing = new ArrayList<>(); - for (Entry e : constants.entrySet()) { - long bitMask = e.getValue(); - String key = e.getKey(); - if (key.startsWith("VM_Version::CPU_")) { - String name = key.substring("VM_Version::CPU_".length()); - try { - CPUFeatureType feature = Enum.valueOf(enumType, renaming.getOrDefault(name, name)); - if ((features & bitMask) != 0) { - outFeatures.add(feature); - } - } catch (IllegalArgumentException iae) { - missing.add(name); - } - } - } - if (!missing.isEmpty()) { - throw new JVMCIError("Missing CPU feature constants: %s", missing); - } - return outFeatures; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2015, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.util.List; -import java.util.Set; - -import jdk.vm.ci.code.CompilationRequest; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; -import jdk.vm.ci.runtime.JVMCICompiler; -import jdk.vm.ci.runtime.JVMCICompilerFactory; -import jdk.vm.ci.runtime.JVMCIRuntime; -import jdk.vm.ci.services.JVMCIPermission; -import jdk.vm.ci.services.JVMCIServiceLocator; -import jdk.vm.ci.services.Services; - -import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; - -final class HotSpotJVMCICompilerConfig { - - /** - * This factory allows JVMCI initialization to succeed but raises an error if the VM asks JVMCI - * to perform a compilation. This allows the reflective parts of the JVMCI API to be used - * without requiring a compiler implementation to be available. - */ - private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler { - - private final String reason; - private final HotSpotJVMCIRuntime runtime; - - DummyCompilerFactory(String reason, HotSpotJVMCIRuntime runtime) { - this.reason = reason; - this.runtime = runtime; - } - - @Override - public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) { - throw runtime.exitHotSpotWithMessage(1, "Cannot use JVMCI compiler: %s%n", reason); - } - - @Override - public String getCompilerName() { - return "null"; - } - - @Override - public JVMCICompiler createCompiler(JVMCIRuntime rt) { - return this; - } - - @Override - public boolean isGCSupported(int gcIdentifier) { - return false; - } - } - - /** - * Factory of the selected system compiler. - */ - @NativeImageReinitialize private static JVMCICompilerFactory compilerFactory; - - /** - * Gets the selected system compiler factory. - * - * @return the selected system compiler factory - * @throws SecurityException if a security manager is present and it denies - * {@link JVMCIPermission} for any {@link JVMCIServiceLocator} loaded by this method - */ - static JVMCICompilerFactory getCompilerFactory(HotSpotJVMCIRuntime runtime) { - if (compilerFactory == null) { - JVMCICompilerFactory factory = null; - String compilerName = Option.Compiler.getString(); - if (compilerName != null) { - String compPropertyName = Option.Compiler.getPropertyName(); - if (compilerName.isEmpty()) { - factory = new DummyCompilerFactory("Value of " + compPropertyName + " is empty", runtime); - } else if (compilerName.equals("null")) { - factory = new DummyCompilerFactory("Value of " + compPropertyName + " is \"null\"", runtime); - } else { - for (JVMCICompilerFactory f : getJVMCICompilerFactories()) { - if (f.getCompilerName().equals(compilerName)) { - factory = f; - } - } - if (factory == null) { - if (Services.IS_IN_NATIVE_IMAGE) { - throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' not found in JVMCI native library.%n" + - "Use -XX:-UseJVMCINativeLibrary when specifying a JVMCI compiler available on a class path with %s.%n", - compilerName, compPropertyName); - } - throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' specified by %s not found%n", compilerName, compPropertyName); - } - } - } else { - // Auto select a single available compiler - String reason = "No JVMCI compiler found"; - for (JVMCICompilerFactory f : getJVMCICompilerFactories()) { - if (factory == null) { - openJVMCITo(f.getClass().getModule()); - factory = f; - } else { - // Multiple factories seen - cancel auto selection - reason = "Multiple JVMCI compilers found: \"" + factory.getCompilerName() + "\" and \"" + f.getCompilerName() + "\""; - factory = null; - break; - } - } - if (factory == null) { - factory = new DummyCompilerFactory(reason, runtime); - } - } - factory.onSelection(); - compilerFactory = factory; - } - return compilerFactory; - } - - /** - * Opens all JVMCI packages to {@code otherModule}. - */ - private static void openJVMCITo(Module otherModule) { - if (!IS_IN_NATIVE_IMAGE) { - Module jvmci = HotSpotJVMCICompilerConfig.class.getModule(); - if (jvmci != otherModule) { - Set packages = jvmci.getPackages(); - for (String pkg : packages) { - boolean opened = jvmci.isOpen(pkg, otherModule); - if (!opened) { - jvmci.addOpens(pkg, otherModule); - } - } - } - } - } - - private static List getJVMCICompilerFactories() { - return JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.runtime.JVMCICompilerFactory; - -/** - * HotSpot extensions to {@link JVMCICompilerFactory}. - */ -public abstract class HotSpotJVMCICompilerFactory implements JVMCICompilerFactory { - - public enum CompilationLevelAdjustment { - /** - * No adjustment. - */ - None, - - /** - * Adjust based on declaring class of method. - */ - ByHolder, - - /** - * Adjust based on declaring class, name and signature of method. - */ - ByFullSignature - } - - /** - * Determines if this object may want to adjust the compilation level for a method that is being - * scheduled by the VM for compilation. - */ - public CompilationLevelAdjustment getCompilationLevelAdjustment() { - return CompilationLevelAdjustment.None; - } - - public enum CompilationLevel { - None, - Simple, - LimitedProfile, - FullProfile, - FullOptimization - } - - /** - * Potentially modifies the compilation level currently selected by the VM compilation policy - * for a method. - * - * @param declaringClass the class in which the method is declared. This value is either a - * {@code Class} instance or a {@code String} representing the - * {@link JavaType#toJavaName() name} of the class. - * @param name the name of the method or {@code null} depending on the value that was returned - * by {@link #getCompilationLevelAdjustment()} - * @param signature the signature of the method or {@code null} depending on the value that was - * returned by {@link #getCompilationLevelAdjustment()} - * @param isOsr specifies if the compilation being scheduled in an OSR compilation - * @param level the compilation level currently selected by the VM compilation policy - * @return the compilation level to use for the compilation being scheduled (must be a valid - * {@code CompLevel} enum value) - */ - public CompilationLevel adjustCompilationLevel(Object declaringClass, String name, String signature, boolean isOsr, CompilationLevel level) { - throw new InternalError(getClass().getName() + " must override adjustCompilationLevel(...) since it returned a value other than " + CompilationLevel.class.getName() + "." + - CompilationLevel.None + " from getCompilationLevelAdjustment()"); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; - -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * API for reflecting on the internals of HotSpot JVMCI types and objects. - */ -abstract class HotSpotJVMCIReflection { - - abstract boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl obj); - - abstract boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType); - - abstract Annotation[] getAnnotations(HotSpotResolvedObjectTypeImpl holder); - - abstract Annotation[] getDeclaredAnnotations(HotSpotResolvedObjectTypeImpl holder); - - abstract T getAnnotation(HotSpotResolvedObjectTypeImpl holder, Class annotationClass); - - abstract boolean isLocalClass(HotSpotResolvedObjectTypeImpl holder); - - abstract boolean isMemberClass(HotSpotResolvedObjectTypeImpl holder); - - abstract HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder); - - abstract boolean equals(HotSpotObjectConstantImpl hotSpotResolvedJavaType, HotSpotObjectConstantImpl that); - - abstract ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod); - - abstract Annotation[][] getParameterAnnotations(HotSpotResolvedJavaMethodImpl javaMethod); - - abstract Type[] getGenericParameterTypes(HotSpotResolvedJavaMethodImpl javaMethod); - - abstract Annotation[] getFieldAnnotations(HotSpotResolvedJavaFieldImpl javaMethod); - - abstract Annotation[] getMethodAnnotations(HotSpotResolvedJavaMethodImpl javaField); - - abstract Annotation[] getMethodDeclaredAnnotations(HotSpotResolvedJavaMethodImpl javaMethod); - - abstract Annotation[] getFieldDeclaredAnnotations(HotSpotResolvedJavaFieldImpl javaMethod); - - abstract T getMethodAnnotation(HotSpotResolvedJavaMethodImpl javaMethod, Class annotationClass); - - abstract HotSpotResolvedObjectTypeImpl getType(HotSpotObjectConstantImpl object); - - abstract String asString(HotSpotObjectConstantImpl object); - - /** - * Given a {@link java.lang.Class} instance, return the corresponding ResolvedJavaType. - */ - abstract ResolvedJavaType asJavaType(HotSpotObjectConstantImpl object); - - abstract T asObject(HotSpotObjectConstantImpl object, Class type); - - abstract Object asObject(HotSpotObjectConstantImpl object, HotSpotResolvedJavaType type); - - abstract String formatString(HotSpotObjectConstantImpl object); - - abstract Integer getLength(HotSpotObjectConstantImpl arrayObject); - - abstract JavaConstant readArrayElement(HotSpotObjectConstantImpl arrayObject, int index); - - abstract JavaConstant unboxPrimitive(HotSpotObjectConstantImpl source); - - abstract JavaConstant forObject(Object value); - - abstract JavaConstant boxPrimitive(JavaConstant source); - - abstract T getFieldAnnotation(HotSpotResolvedJavaFieldImpl javaField, Class annotationClass); - - /** - * Resolves {@code objectHandle} to a raw object if possible. - * - * @throws HotSpotJVMCIUnsupportedOperationError if {@code objectHandle} refers to an object in - * another heap - */ - abstract Object resolveObject(HotSpotObjectConstantImpl objectHandle); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,1453 +0,0 @@ -/* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.common.InitTimer.timer; -import static jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.None; -import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; -import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.Serializable; -import java.lang.invoke.CallSite; -import java.lang.invoke.ConstantCallSite; -import java.lang.invoke.MethodHandle; -import java.lang.ref.WeakReference; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Formatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.ServiceLoader; -import java.util.function.Predicate; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import jdk.internal.misc.Unsafe; -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.CompilationRequest; -import jdk.vm.ci.code.CompilationRequestResult; -import jdk.vm.ci.code.CompiledCode; -import jdk.vm.ci.code.InstalledCode; -import jdk.vm.ci.common.InitTimer; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.UnresolvedJavaType; -import jdk.vm.ci.runtime.JVMCI; -import jdk.vm.ci.runtime.JVMCIBackend; -import jdk.vm.ci.runtime.JVMCICompiler; -import jdk.vm.ci.runtime.JVMCICompilerFactory; -import jdk.vm.ci.runtime.JVMCIRuntime; -import jdk.vm.ci.services.JVMCIServiceLocator; -import jdk.vm.ci.services.Services; - -/** - * HotSpot implementation of a JVMCI runtime. - */ -public final class HotSpotJVMCIRuntime implements JVMCIRuntime { - - /** - * Singleton instance lazily initialized via double-checked locking. - */ - @NativeImageReinitialize private static volatile HotSpotJVMCIRuntime instance; - - private HotSpotResolvedObjectTypeImpl javaLangObject; - private HotSpotResolvedObjectTypeImpl javaLangInvokeMethodHandle; - private HotSpotResolvedObjectTypeImpl constantCallSiteType; - private HotSpotResolvedObjectTypeImpl callSiteType; - private HotSpotResolvedObjectTypeImpl javaLangString; - private HotSpotResolvedObjectTypeImpl javaLangClass; - private HotSpotResolvedObjectTypeImpl throwableType; - private HotSpotResolvedObjectTypeImpl serializableType; - private HotSpotResolvedObjectTypeImpl cloneableType; - private HotSpotResolvedObjectTypeImpl enumType; - - HotSpotResolvedObjectTypeImpl getJavaLangObject() { - if (javaLangObject == null) { - javaLangObject = (HotSpotResolvedObjectTypeImpl) fromClass(Object.class); - } - return javaLangObject; - } - - HotSpotResolvedObjectTypeImpl getJavaLangString() { - if (javaLangString == null) { - javaLangString = (HotSpotResolvedObjectTypeImpl) fromClass(String.class); - } - return javaLangString; - } - - HotSpotResolvedObjectTypeImpl getJavaLangClass() { - if (javaLangClass == null) { - javaLangClass = (HotSpotResolvedObjectTypeImpl) fromClass(Class.class); - } - return javaLangClass; - } - - HotSpotResolvedObjectTypeImpl getJavaLangCloneable() { - if (cloneableType == null) { - cloneableType = (HotSpotResolvedObjectTypeImpl) fromClass(Cloneable.class); - } - return cloneableType; - } - - HotSpotResolvedObjectTypeImpl getJavaLangSerializable() { - if (serializableType == null) { - serializableType = (HotSpotResolvedObjectTypeImpl) fromClass(Serializable.class); - } - return serializableType; - } - - HotSpotResolvedObjectTypeImpl getJavaLangThrowable() { - if (throwableType == null) { - throwableType = (HotSpotResolvedObjectTypeImpl) fromClass(Throwable.class); - } - return throwableType; - } - - HotSpotResolvedObjectTypeImpl getJavaLangEnum() { - if (enumType == null) { - enumType = (HotSpotResolvedObjectTypeImpl) fromClass(Enum.class); - } - return enumType; - } - - HotSpotResolvedObjectTypeImpl getConstantCallSite() { - if (constantCallSiteType == null) { - constantCallSiteType = (HotSpotResolvedObjectTypeImpl) fromClass(ConstantCallSite.class); - } - return constantCallSiteType; - } - - HotSpotResolvedObjectTypeImpl getCallSite() { - if (callSiteType == null) { - callSiteType = (HotSpotResolvedObjectTypeImpl) fromClass(CallSite.class); - } - return callSiteType; - } - - HotSpotResolvedObjectType getMethodHandleClass() { - if (javaLangInvokeMethodHandle == null) { - javaLangInvokeMethodHandle = (HotSpotResolvedObjectTypeImpl) fromClass(MethodHandle.class); - } - return javaLangInvokeMethodHandle; - } - - /** - * Gets the singleton {@link HotSpotJVMCIRuntime} object. - */ - @VMEntryPoint - @SuppressWarnings("try") - public static HotSpotJVMCIRuntime runtime() { - HotSpotJVMCIRuntime result = instance; - if (result == null) { - // Synchronize on JVMCI.class to avoid deadlock - // between the two JVMCI initialization paths: - // HotSpotJVMCIRuntime.runtime() and JVMCI.getRuntime(). - synchronized (JVMCI.class) { - result = instance; - if (result == null) { - try (InitTimer t = timer("HotSpotJVMCIRuntime.")) { - instance = result = new HotSpotJVMCIRuntime(); - - // Can only do eager initialization of the JVMCI compiler - // once the singleton instance is available. - if (result.config.getFlag("EagerJVMCI", Boolean.class)) { - result.getCompiler(); - } - } - // Ensures JVMCIRuntime::_HotSpotJVMCIRuntime_instance is - // initialized. - JVMCI.getRuntime(); - } - // Make sure all the primitive box caches are populated (required to properly - // materialize boxed primitives - // during deoptimization). - Boolean.valueOf(false); - Byte.valueOf((byte) 0); - Short.valueOf((short) 0); - Character.valueOf((char) 0); - Integer.valueOf(0); - Long.valueOf(0); - } - } - return result; - } - - /** - * Decodes the exception encoded in {@code buffer} and throws it. - * - * @param errorOrBuffer an error code or a native byte buffer containing an exception encoded by - * {@link #encodeThrowable}. Error code values and their meanings are: - * - *
    -     *             0: native memory for the buffer could not be allocated
    -     *            -1: an OutOfMemoryError was thrown while encoding the exception
    -     *            -2: some other throwable was thrown while encoding the exception
    -     *            
    - */ - @VMEntryPoint - static void decodeAndThrowThrowable(long errorOrBuffer) throws Throwable { - if (errorOrBuffer >= -2L && errorOrBuffer <= 0) { - String context = String.format("while encoding an exception to translate it from %s to %s", - IS_IN_NATIVE_IMAGE ? "HotSpot" : "libjvmci", - IS_IN_NATIVE_IMAGE ? "libjvmci" : "HotSpot"); - if (errorOrBuffer == 0) { - throw new InternalError("native buffer could not be allocated " + context); - } - if (errorOrBuffer == -1L) { - throw new OutOfMemoryError("OutOfMemoryError occurred " + context); - } - throw new InternalError("unexpected problem occurred " + context); - } - Unsafe unsafe = UnsafeAccess.UNSAFE; - int encodingLength = unsafe.getInt(errorOrBuffer); - byte[] encoding = new byte[encodingLength]; - unsafe.copyMemory(null, errorOrBuffer + 4, encoding, Unsafe.ARRAY_BYTE_BASE_OFFSET, encodingLength); - throw TranslatedException.decodeThrowable(encoding); - } - - /** - * If {@code bufferSize} is large enough, encodes {@code throwable} into a byte array and writes - * it to {@code buffer}. The encoding in {@code buffer} can be decoded by - * {@link #decodeAndThrowThrowable}. - * - * @param throwable the exception to encode - * @param buffer a native byte buffer - * @param bufferSize the size of {@code buffer} in bytes - * @return the number of bytes written into {@code buffer} if {@code bufferSize} is large - * enough, otherwise {@code -N} where {@code N} is the value {@code bufferSize} needs to - * be to fit the encoding - */ - @VMEntryPoint - static int encodeThrowable(Throwable throwable, long buffer, int bufferSize) throws Throwable { - byte[] encoding = TranslatedException.encodeThrowable(throwable); - int requiredSize = 4 + encoding.length; - if (bufferSize < requiredSize) { - return -requiredSize; - } - Unsafe unsafe = UnsafeAccess.UNSAFE; - unsafe.putInt(buffer, encoding.length); - unsafe.copyMemory(encoding, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, buffer + 4, encoding.length); - return requiredSize; - } - - @VMEntryPoint - static String callToString(Object o) { - return o.toString(); - } - - /** - * Set of recognized {@code "jvmci.*"} system properties. Entries not associated with an - * {@link Option} have this object as their value. - */ - static final Map options = new HashMap<>(); - static { - options.put("jvmci.class.path.append", options); - } - - /** - * A list of all supported JVMCI options. - */ - public enum Option { - // @formatter:off - Compiler(String.class, null, "Selects the system compiler. This must match the getCompilerName() value returned " + - "by a jdk.vm.ci.runtime.JVMCICompilerFactory provider. " + - "An empty string or the value \"null\" selects a compiler " + - "that will raise an exception upon receiving a compilation request."), - // Note: The following one is not used (see InitTimer.ENABLED). It is added here - // so that -XX:+JVMCIPrintProperties shows the option. - InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."), - ForceTranslateFailure(String.class, null, "Forces HotSpotJVMCIRuntime.translate to throw an exception in the context " + - "of the peer runtime. The value is a filter that can restrict the forced failure to matching translated " + - "objects. See HotSpotJVMCIRuntime.postTranslation for more details. This option exists soley to test " + - "correct handling of translation failure."), - PrintConfig(Boolean.class, false, "Prints VM configuration available via JVMCI."), - AuditHandles(Boolean.class, false, "Record stack trace along with scoped foreign object reference wrappers " + - "to debug issue with a wrapper being used after its scope has closed."), - TraceMethodDataFilter(String.class, null, - "Enables tracing of profiling info when read by JVMCI.", - "Empty value: trace all methods", - "Non-empty value: trace methods whose fully qualified name contains the value."), - UseProfilingInformation(Boolean.class, true, ""); - // @formatter:on - - /** - * The prefix for system properties that are JVMCI options. - */ - private static final String JVMCI_OPTION_PROPERTY_PREFIX = "jvmci."; - - /** - * Sentinel for value initialized to {@code null} since {@code null} means uninitialized. - */ - private static final String NULL_VALUE = "NULL"; - - private final Class type; - @NativeImageReinitialize private Object value; - private final Object defaultValue; - private boolean isDefault = true; - private final String[] helpLines; - - Option(Class type, Object defaultValue, String... helpLines) { - assert Character.isUpperCase(name().charAt(0)) : "Option name must start with upper-case letter: " + name(); - this.type = type; - this.defaultValue = defaultValue; - this.helpLines = helpLines; - Object existing = options.put(getPropertyName(), this); - assert existing == null : getPropertyName(); - } - - @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum") - private void init(String propertyValue) { - assert value == null : "cannot re-initialize " + name(); - if (propertyValue == null) { - this.value = defaultValue == null ? NULL_VALUE : defaultValue; - this.isDefault = true; - } else { - if (type == Boolean.class) { - this.value = Boolean.parseBoolean(propertyValue); - } else if (type == String.class) { - this.value = propertyValue; - } else { - throw new JVMCIError("Unexpected option type " + type); - } - this.isDefault = false; - } - } - - @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum") - private Object getValue() { - if (value == NULL_VALUE) { - return null; - } - if (value == null) { - return defaultValue; - } - return value; - } - - /** - * Gets the name of system property from which this option gets its value. - */ - public String getPropertyName() { - return JVMCI_OPTION_PROPERTY_PREFIX + name(); - } - - /** - * Returns the option's value as boolean. - * - * @return option's value - */ - public boolean getBoolean() { - return (boolean) getValue(); - } - - /** - * Returns the option's value as String. - * - * @return option's value - */ - public String getString() { - return (String) getValue(); - } - - private static final int PROPERTY_LINE_WIDTH = 80; - private static final int PROPERTY_HELP_INDENT = 10; - - /** - * Prints a description of the properties used to configure shared JVMCI code. - * - * @param out stream to print to - */ - public static void printProperties(PrintStream out) { - out.println("[JVMCI properties]"); - Option[] values = values(); - for (Option option : values) { - Object value = option.getValue(); - if (value instanceof String) { - value = '"' + String.valueOf(value) + '"'; - } - - String name = option.getPropertyName(); - String assign = option.isDefault ? "=" : ":="; - String typeName = option.type.getSimpleName(); - String linePrefix = String.format("%s %s %s ", name, assign, value); - int typeStartPos = PROPERTY_LINE_WIDTH - typeName.length(); - int linePad = typeStartPos - linePrefix.length(); - if (linePad > 0) { - out.printf("%s%-" + linePad + "s[%s]%n", linePrefix, "", typeName); - } else { - out.printf("%s[%s]%n", linePrefix, typeName); - } - for (String line : option.helpLines) { - out.printf("%" + PROPERTY_HELP_INDENT + "s%s%n", "", line); - } - } - } - - /** - * Compute string similarity based on Dice's coefficient. - * - * Ported from str_similar() in globals.cpp. - */ - static float stringSimiliarity(String str1, String str2) { - int hit = 0; - for (int i = 0; i < str1.length() - 1; ++i) { - for (int j = 0; j < str2.length() - 1; ++j) { - if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) { - ++hit; - break; - } - } - } - return 2.0f * hit / (str1.length() + str2.length()); - } - - private static final float FUZZY_MATCH_THRESHOLD = 0.7F; - - /** - * Parses all system properties starting with {@value #JVMCI_OPTION_PROPERTY_PREFIX} and - * initializes the options based on their values. - * - * @param runtime - */ - static void parse(HotSpotJVMCIRuntime runtime) { - Map savedProps = jdk.vm.ci.services.Services.getSavedProperties(); - for (Map.Entry e : savedProps.entrySet()) { - String name = e.getKey(); - if (name.startsWith(Option.JVMCI_OPTION_PROPERTY_PREFIX)) { - Object value = options.get(name); - if (value == null) { - List matches = new ArrayList<>(); - for (String pn : options.keySet()) { - float score = stringSimiliarity(pn, name); - if (score >= FUZZY_MATCH_THRESHOLD) { - matches.add(pn); - } - } - Formatter msg = new Formatter(); - msg.format("Error parsing JVMCI options: Could not find option %s", name); - if (!matches.isEmpty()) { - msg.format("%nDid you mean one of the following?"); - for (String match : matches) { - msg.format("%n %s=", match); - } - } - msg.format("%nError: A fatal exception has occurred. Program will exit.%n"); - runtime.exitHotSpotWithMessage(1, msg.toString()); - } else if (value instanceof Option) { - Option option = (Option) value; - option.init(e.getValue()); - } - } - } - } - } - - private static HotSpotJVMCIBackendFactory findFactory(String architecture) { - Iterable factories = getHotSpotJVMCIBackendFactories(); - assert factories != null : "sanity"; - for (HotSpotJVMCIBackendFactory factory : factories) { - if (factory.getArchitecture().equalsIgnoreCase(architecture)) { - return factory; - } - } - - throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture); - } - - private static volatile List cachedHotSpotJVMCIBackendFactories; - - @SuppressFBWarnings(value = "LI_LAZY_INIT_UPDATE_STATIC", justification = "not sure about this") - private static Iterable getHotSpotJVMCIBackendFactories() { - if (IS_IN_NATIVE_IMAGE || cachedHotSpotJVMCIBackendFactories != null) { - return cachedHotSpotJVMCIBackendFactories; - } - Iterable result = ServiceLoader.load(HotSpotJVMCIBackendFactory.class, ClassLoader.getSystemClassLoader()); - if (IS_BUILDING_NATIVE_IMAGE) { - cachedHotSpotJVMCIBackendFactories = new ArrayList<>(); - for (HotSpotJVMCIBackendFactory factory : result) { - cachedHotSpotJVMCIBackendFactories.add(factory); - } - } - return result; - } - - /** - * Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend. - */ - public static JavaKind getHostWordKind() { - return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind; - } - - protected final CompilerToVM compilerToVm; - - protected final HotSpotVMConfigStore configStore; - protected final HotSpotVMConfig config; - private final JVMCIBackend hostBackend; - - private final JVMCICompilerFactory compilerFactory; - private final HotSpotJVMCICompilerFactory hsCompilerFactory; - private volatile JVMCICompiler compiler; - protected final HotSpotJVMCIReflection reflection; - - @NativeImageReinitialize private volatile boolean creatingCompiler; - - /** - * Cache for speeding up {@link #fromClass(Class)}. - */ - @NativeImageReinitialize private volatile ClassValue> resolvedJavaType; - - /** - * To avoid calling ClassValue.remove to refresh the weak reference, which under certain - * circumstances can lead to an infinite loop, we use a permanent holder with a mutable field - * that we refresh. - */ - private static class WeakReferenceHolder { - private volatile WeakReference ref; - - WeakReferenceHolder(T value) { - set(value); - } - - void set(T value) { - ref = new WeakReference<>(value); - } - - T get() { - return ref.get(); - } - } - - @NativeImageReinitialize private HashMap> resolvedJavaTypes; - - /** - * Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can be - * read from the VM. - */ - @SuppressWarnings("unused")// - @NativeImageReinitialize private Module[] excludeFromJVMCICompilation; - - private final Map, JVMCIBackend> backends = new HashMap<>(); - - private volatile List vmEventListeners; - - private Iterable getVmEventListeners() { - if (vmEventListeners == null) { - synchronized (this) { - if (vmEventListeners == null) { - vmEventListeners = JVMCIServiceLocator.getProviders(HotSpotVMEventListener.class); - } - } - } - return vmEventListeners; - } - - @SuppressWarnings("try") - private HotSpotJVMCIRuntime() { - compilerToVm = new CompilerToVM(); - - try (InitTimer t = timer("HotSpotVMConfig")) { - configStore = new HotSpotVMConfigStore(compilerToVm); - config = new HotSpotVMConfig(configStore); - } - - reflection = IS_IN_NATIVE_IMAGE ? new SharedLibraryJVMCIReflection() : new HotSpotJDKReflection(); - - PrintStream vmLogStream = null; - if (IS_IN_NATIVE_IMAGE) { - // Redirect System.out and System.err to HotSpot's TTY stream - vmLogStream = new PrintStream(getLogStream()); - System.setOut(vmLogStream); - System.setErr(vmLogStream); - } - - // Initialize the Option values. - Option.parse(this); - - String hostArchitecture = config.getHostArchitectureName(); - - HotSpotJVMCIBackendFactory factory; - try (InitTimer t = timer("find factory:", hostArchitecture)) { - factory = findFactory(hostArchitecture); - } - - try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) { - hostBackend = registerBackend(factory.createJVMCIBackend(this, null)); - } - - compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory(this); - if (compilerFactory instanceof HotSpotJVMCICompilerFactory) { - hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory; - if (hsCompilerFactory.getCompilationLevelAdjustment() != None) { - String name = HotSpotJVMCICompilerFactory.class.getName(); - String msg = String.format("%s.getCompilationLevelAdjustment() is no longer supported. " + - "Use %s.excludeFromJVMCICompilation() instead.", name, name); - throw new UnsupportedOperationException(msg); - } - } else { - hsCompilerFactory = null; - } - - if (config.getFlag("JVMCIPrintProperties", Boolean.class)) { - if (vmLogStream == null) { - vmLogStream = new PrintStream(getLogStream()); - } - Option.printProperties(vmLogStream); - compilerFactory.printProperties(vmLogStream); - System.exit(0); - } - - if (Option.PrintConfig.getBoolean()) { - configStore.printConfig(this); - } - } - - /** - * Sets the current thread's {@code JavaThread::_jvmci_reserved_oop} field to {@code value}. - * - * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved_oop} field - * does not exist - */ - public void setThreadLocalObject(int id, Object value) { - compilerToVm.setThreadLocalObject(id, value); - } - - /** - * Get the value of the current thread's {@code JavaThread::_jvmci_reserved_oop} field. - * - * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved_oop} field - * does not exist - */ - public Object getThreadLocalObject(int id) { - return compilerToVm.getThreadLocalObject(id); - } - - /** - * Sets the current thread's {@code JavaThread::_jvmci_reserved} field to {@code value}. - * - * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved} field does - * not exist - */ - public void setThreadLocalLong(int id, long value) { - compilerToVm.setThreadLocalLong(id, value); - } - - /** - * Get the value of the current thread's {@code JavaThread::_jvmci_reserved} field. - * - * @throws IllegalArgumentException if the {@code JavaThread::_jvmci_reserved} field does - * not exist - */ - public long getThreadLocalLong(int id) { - return compilerToVm.getThreadLocalLong(id); - } - - HotSpotResolvedJavaType createClass(Class javaClass) { - if (javaClass.isPrimitive()) { - return HotSpotResolvedPrimitiveType.forKind(JavaKind.fromJavaClass(javaClass)); - } - if (IS_IN_NATIVE_IMAGE) { - try { - return compilerToVm.lookupType(javaClass.getName().replace('.', '/'), null, true); - } catch (ClassNotFoundException e) { - throw new JVMCIError(e); - } - } - return compilerToVm.lookupClass(javaClass); - } - - private HotSpotResolvedJavaType fromClass0(Class javaClass) { - if (resolvedJavaType == null) { - synchronized (this) { - if (resolvedJavaType == null) { - resolvedJavaType = new ClassValue<>() { - @Override - protected WeakReferenceHolder computeValue(Class type) { - return new WeakReferenceHolder<>(createClass(type)); - } - }; - } - } - } - - WeakReferenceHolder ref = resolvedJavaType.get(javaClass); - HotSpotResolvedJavaType javaType = ref.get(); - if (javaType == null) { - /* - * If the referent has become null, create a new value and update cached weak reference. - */ - javaType = createClass(javaClass); - ref.set(javaType); - } - return javaType; - } - - /** - * Gets the JVMCI mirror for a {@link Class} object. - * - * @return the {@link ResolvedJavaType} corresponding to {@code javaClass} - */ - HotSpotResolvedJavaType fromClass(Class javaClass) { - if (javaClass == null) { - return null; - } - return fromClass0(javaClass); - } - - synchronized HotSpotResolvedObjectTypeImpl fromMetaspace(long klassPointer, String signature) { - if (resolvedJavaTypes == null) { - resolvedJavaTypes = new HashMap<>(); - } - assert klassPointer != 0; - WeakReference klassReference = resolvedJavaTypes.get(klassPointer); - HotSpotResolvedObjectTypeImpl javaType = null; - if (klassReference != null) { - javaType = (HotSpotResolvedObjectTypeImpl) klassReference.get(); - } - if (javaType == null) { - javaType = new HotSpotResolvedObjectTypeImpl(klassPointer, signature); - resolvedJavaTypes.put(klassPointer, new WeakReference<>(javaType)); - } - return javaType; - } - - private JVMCIBackend registerBackend(JVMCIBackend backend) { - Class arch = backend.getCodeCache().getTarget().arch.getClass(); - JVMCIBackend oldValue = backends.put(arch, backend); - assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName(); - return backend; - } - - public HotSpotVMConfigStore getConfigStore() { - return configStore; - } - - public HotSpotVMConfig getConfig() { - return config; - } - - public CompilerToVM getCompilerToVM() { - return compilerToVm; - } - - HotSpotJVMCIReflection getReflection() { - return reflection; - } - - /** - * Gets a predicate that determines if a given type can be considered trusted for the purpose of - * intrinsifying methods it declares. - * - * @param compilerLeafClasses classes in the leaves of the module graph comprising the JVMCI - * compiler. - */ - public Predicate getIntrinsificationTrustPredicate(Class... compilerLeafClasses) { - return new Predicate<>() { - @Override - public boolean test(ResolvedJavaType type) { - if (type instanceof HotSpotResolvedObjectTypeImpl) { - HotSpotResolvedObjectTypeImpl hsType = (HotSpotResolvedObjectTypeImpl) type; - return compilerToVm.isTrustedForIntrinsics(hsType); - } else { - return false; - } - } - }; - } - - /** - * Gets the {@link Class} corresponding to {@code type}. - * - * @param type the type for which a {@link Class} is requested - * @return the original Java class corresponding to {@code type} or {@code null} if this runtime - * does not support mapping {@link ResolvedJavaType} instances to {@link Class} - * instances - */ - public Class getMirror(ResolvedJavaType type) { - if (type instanceof HotSpotResolvedJavaType && reflection instanceof HotSpotJDKReflection) { - return ((HotSpotJDKReflection) reflection).getMirror((HotSpotResolvedJavaType) type); - } - return null; - } - - /** - * Gets the {@link Executable} corresponding to {@code method}. - * - * @param method the method for which an {@link Executable} is requested - * @return the original Java method or constructor corresponding to {@code method} or - * {@code null} if this runtime does not support mapping {@link ResolvedJavaMethod} - * instances to {@link Executable} instances - */ - public Executable getMirror(ResolvedJavaMethod method) { - if (method instanceof HotSpotResolvedJavaMethodImpl && reflection instanceof HotSpotJDKReflection) { - return HotSpotJDKReflection.getMethod((HotSpotResolvedJavaMethodImpl) method); - } - return null; - } - - /** - * Gets the {@link Field} corresponding to {@code field}. - * - * @param field the field for which a {@link Field} is requested - * @return the original Java field corresponding to {@code field} or {@code null} if this - * runtime does not support mapping {@link ResolvedJavaField} instances to {@link Field} - * instances - */ - public Field getMirror(ResolvedJavaField field) { - if (field instanceof HotSpotResolvedJavaFieldImpl && reflection instanceof HotSpotJDKReflection) { - return HotSpotJDKReflection.getField((HotSpotResolvedJavaFieldImpl) field); - } - return null; - } - - static class ErrorCreatingCompiler implements JVMCICompiler { - private final RuntimeException t; - - ErrorCreatingCompiler(RuntimeException t) { - this.t = t; - } - - @Override - public CompilationRequestResult compileMethod(CompilationRequest request) { - throw t; - } - - @Override - public boolean isGCSupported(int gcIdentifier) { - return false; - } - } - - @Override - public JVMCICompiler getCompiler() { - if (compiler == null) { - synchronized (this) { - if (compiler == null) { - assert !creatingCompiler : "recursive compiler creation"; - creatingCompiler = true; - try { - compiler = compilerFactory.createCompiler(this); - } catch (RuntimeException t) { - compiler = new ErrorCreatingCompiler(t); - } finally { - creatingCompiler = false; - } - } - } - } - if (compiler instanceof ErrorCreatingCompiler) { - throw ((ErrorCreatingCompiler) compiler).t; - } - return compiler; - } - - /** - * Converts a name to a Java type. This method attempts to resolve {@code name} to a - * {@link ResolvedJavaType}. - * - * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format - * @param accessingType the context of resolution which must be non-null - * @param resolve specifies whether resolution failure results in an unresolved type being - * return or a {@link LinkageError} being thrown - * @return a Java type for {@code name} which is guaranteed to be of type - * {@link ResolvedJavaType} if {@code resolve == true} - * @throws LinkageError if {@code resolve == true} and the resolution failed - * @throws NullPointerException if {@code accessingClass} is {@code null} - */ - public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) { - Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class"); - return lookupTypeInternal(name, accessingType, resolve); - } - - JavaType lookupTypeInternal(String name, HotSpotResolvedObjectType accessingType, boolean resolve) { - // If the name represents a primitive type we can short-circuit the lookup. - if (name.length() == 1) { - JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); - return HotSpotResolvedPrimitiveType.forKind(kind); - } - - // Resolve non-primitive types in the VM. - HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType; - try { - final HotSpotResolvedJavaType klass = compilerToVm.lookupType(name, hsAccessingType, resolve); - - if (klass == null) { - assert resolve == false : name; - return UnresolvedJavaType.create(name); - } - return klass; - } catch (ClassNotFoundException e) { - throw (NoClassDefFoundError) new NoClassDefFoundError().initCause(e); - } - } - - @Override - public JVMCIBackend getHostJVMCIBackend() { - return hostBackend; - } - - @Override - public JVMCIBackend getJVMCIBackend(Class arch) { - assert arch != Architecture.class; - return backends.get(arch); - } - - public Map, JVMCIBackend> getJVMCIBackends() { - return Collections.unmodifiableMap(backends); - } - - @SuppressWarnings("try") - @VMEntryPoint - private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long compileState, int id) { - HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, compileState, id); - CompilationRequestResult result = getCompiler().compileMethod(request); - assert result != null : "compileMethod must always return something"; - HotSpotCompilationRequestResult hsResult; - if (result instanceof HotSpotCompilationRequestResult) { - hsResult = (HotSpotCompilationRequestResult) result; - } else { - Object failure = result.getFailure(); - if (failure != null) { - boolean retry = false; // Be conservative with unknown compiler - hsResult = HotSpotCompilationRequestResult.failure(failure.toString(), retry); - } else { - int inlinedBytecodes = -1; - hsResult = HotSpotCompilationRequestResult.success(inlinedBytecodes); - } - } - return hsResult; - } - - @SuppressWarnings("try") - @VMEntryPoint - private boolean isGCSupported(int gcIdentifier) { - return getCompiler().isGCSupported(gcIdentifier); - } - - /** - * Guard to ensure shut down actions are performed at most once. - */ - private boolean isShutdown; - - /** - * Shuts down the runtime. - */ - @VMEntryPoint - private synchronized void shutdown() throws Exception { - if (!isShutdown) { - isShutdown = true; - // Cleaners are normally only processed when a new Cleaner is - // instantiated so process all remaining cleaners now. - Cleaner.clean(); - - for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { - vmEventListener.notifyShutdown(); - } - } - } - - /** - * Notify on completion of a bootstrap. - */ - @VMEntryPoint - private void bootstrapFinished() throws Exception { - for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { - vmEventListener.notifyBootstrapFinished(); - } - } - - /** - * Notify on successful install into the CodeCache. - * - * @param hotSpotCodeCacheProvider - * @param installedCode - * @param compiledCode - */ - void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) { - for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { - vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compiledCode); - } - } - - /** - * Writes {@code length} bytes from {@code bytes} starting at offset {@code offset} to HotSpot's - * log stream. - * - * @param flush specifies if the log stream should be flushed after writing - * @param canThrow specifies if an error in the {@code bytes}, {@code offset} or {@code length} - * arguments should result in an exception or a negative return value. If - * {@code false}, this call will not perform any heap allocation - * @return 0 on success, -1 if {@code bytes == null && !canThrow}, -2 if {@code !canThrow} and - * copying would cause access of data outside array bounds - * @throws NullPointerException if {@code bytes == null} - * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds - */ - public int writeDebugOutput(byte[] bytes, int offset, int length, boolean flush, boolean canThrow) { - return writeDebugOutput0(compilerToVm, bytes, offset, length, flush, canThrow); - } - - /** - * @see #writeDebugOutput - */ - static int writeDebugOutput0(CompilerToVM vm, byte[] bytes, int offset, int length, boolean flush, boolean canThrow) { - if (bytes == null) { - if (!canThrow) { - return -1; - } - throw new NullPointerException(); - } - if (offset < 0 || length < 0 || offset + length > bytes.length) { - if (!canThrow) { - return -2; - } - throw new ArrayIndexOutOfBoundsException(); - } - if (length <= 8) { - ByteBuffer buffer = ByteBuffer.wrap(bytes, offset, length); - if (length != 8) { - ByteBuffer buffer8 = ByteBuffer.allocate(8); - buffer8.put(buffer); - buffer8.position(8); - buffer = buffer8; - } - buffer.order(ByteOrder.nativeOrder()); - vm.writeDebugOutput(buffer.getLong(0), length, flush); - } else { - Unsafe unsafe = UnsafeAccess.UNSAFE; - long buffer = unsafe.allocateMemory(length); - try { - unsafe.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, buffer, length); - vm.writeDebugOutput(buffer, length, flush); - } finally { - unsafe.freeMemory(buffer); - } - } - return 0; - } - - /** - * Gets an output stream that writes to HotSpot's {@code tty} stream. - */ - public OutputStream getLogStream() { - return new OutputStream() { - - @Override - public void write(byte[] b, int off, int len) throws IOException { - if (b == null) { - throw new NullPointerException(); - } else if (off < 0 || off > b.length || len < 0 || (off + len) > b.length || (off + len) < 0) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; - } - writeDebugOutput(b, off, len, false, true); - } - - @Override - public void write(int b) throws IOException { - write(new byte[]{(byte) b}, 0, 1); - } - - @Override - public void flush() throws IOException { - compilerToVm.flushDebugOutput(); - } - }; - } - - /** - * Collects the current values of all JVMCI benchmark counters, summed up over all threads. - */ - public long[] collectCounters() { - return compilerToVm.collectCounters(); - } - - /** - * @return the current number of per thread counters. May be set through - * {@code -XX:JVMCICompilerSize=} command line option or the - * {@link #setCountersSize(int)} call. - */ - public int getCountersSize() { - return compilerToVm.getCountersSize(); - } - - /** - * Attempt to enlarge the number of per thread counters available. Requires a safepoint so - * resizing should be rare to avoid performance effects. - * - * @param newSize - * @return false if the resizing failed - */ - public boolean setCountersSize(int newSize) { - return compilerToVm.setCountersSize(newSize); - } - - /** - * The offset from the origin of an array to the first element. - * - * @return the offset in bytes - */ - public int getArrayBaseOffset(JavaKind kind) { - switch (kind) { - case Boolean: - return compilerToVm.ARRAY_BOOLEAN_BASE_OFFSET; - case Byte: - return compilerToVm.ARRAY_BYTE_BASE_OFFSET; - case Char: - return compilerToVm.ARRAY_CHAR_BASE_OFFSET; - case Short: - return compilerToVm.ARRAY_SHORT_BASE_OFFSET; - case Int: - return compilerToVm.ARRAY_INT_BASE_OFFSET; - case Long: - return compilerToVm.ARRAY_LONG_BASE_OFFSET; - case Float: - return compilerToVm.ARRAY_FLOAT_BASE_OFFSET; - case Double: - return compilerToVm.ARRAY_DOUBLE_BASE_OFFSET; - case Object: - return compilerToVm.ARRAY_OBJECT_BASE_OFFSET; - default: - throw new JVMCIError("%s", kind); - } - - } - - /** - * The scale used for the index when accessing elements of an array of this kind. - * - * @return the scale in order to convert the index into a byte offset - */ - public int getArrayIndexScale(JavaKind kind) { - switch (kind) { - case Boolean: - return compilerToVm.ARRAY_BOOLEAN_INDEX_SCALE; - case Byte: - return compilerToVm.ARRAY_BYTE_INDEX_SCALE; - case Char: - return compilerToVm.ARRAY_CHAR_INDEX_SCALE; - case Short: - return compilerToVm.ARRAY_SHORT_INDEX_SCALE; - case Int: - return compilerToVm.ARRAY_INT_INDEX_SCALE; - case Long: - return compilerToVm.ARRAY_LONG_INDEX_SCALE; - case Float: - return compilerToVm.ARRAY_FLOAT_INDEX_SCALE; - case Double: - return compilerToVm.ARRAY_DOUBLE_INDEX_SCALE; - case Object: - return compilerToVm.ARRAY_OBJECT_INDEX_SCALE; - default: - throw new JVMCIError("%s", kind); - - } - } - - /** - * Links each native method in {@code clazz} to an implementation in the JVMCI shared library. - *

    - * A use case for this is a JVMCI compiler implementation that offers an API to Java code - * executing in HotSpot to exercise functionality (mostly) in the JVMCI shared library. For - * example: - * - *

    -     * package com.jcompile;
    -     *
    -     * import java.lang.reflect.Method;
    -     *
    -     * public static class JCompile {
    -     *     static {
    -     *         HotSpotJVMCIRuntime.runtime().registerNativeMethods(JCompile.class);
    -     *     }
    -     *     public static boolean compile(Method method, String[] options) {
    -     *         // Convert to simpler data types for passing/serializing across native interface
    -     *         long metaspaceMethodHandle = getHandle(method);
    -     *         char[] opts = convertToCharArray(options);
    -     *         return compile(metaspaceMethodHandle, opts);
    -     *     }
    -     *     private static native boolean compile0(long metaspaceMethodHandle, char[] options);
    -     *
    -     *     private static long getHandle(Method method) { ... }
    -     *     private static char[] convertToCharArray(String[] a) { ... }
    -     * }
    -     * 
    - * - * The implementation of the native {@code JCompile.compile0} method would be in the JVMCI - * shared library that contains the JVMCI compiler. The {@code JCompile.compile0} implementation - * must be exported as the following JNI-compatible symbol: - * - *
    -     * Java_com_jcompile_JCompile_compile0
    -     * 
    - * - * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#resolving_native_method_names" - * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#creating_the_vm" - * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#invocation_api_functions" - * - * - * @return info about the Java VM in the JVMCI shared library {@code JavaVM*}. The info is - * encoded in a long array as follows: - * - *
    -     *     long[] info = {
    -     *         javaVM, // the {@code JavaVM*} value
    -     *         javaVM->functions->reserved0,
    -     *         javaVM->functions->reserved1,
    -     *         javaVM->functions->reserved2
    -     *     }
    -     *         
    - * - * @throws NullPointerException if {@code clazz == null} - * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. - * {@code -XX:-UseJVMCINativeLibrary}) - * @throws IllegalStateException if the current execution context is the JVMCI shared library - * @throws IllegalArgumentException if {@code clazz} is {@link Class#isPrimitive()} - * @throws UnsatisfiedLinkError if there's a problem linking a native method in {@code clazz} - * (no matching JNI symbol or the native method is already linked to a different - * address) - */ - public long[] registerNativeMethods(Class clazz) { - return compilerToVm.registerNativeMethods(clazz); - } - - /** - * Creates or retrieves an object in the peer runtime that mirrors {@code obj}. The types whose - * objects can be translated are: - *
      - *
    • {@link HotSpotResolvedJavaMethodImpl},
    • - *
    • {@link HotSpotResolvedObjectTypeImpl},
    • - *
    • {@link HotSpotResolvedPrimitiveType},
    • - *
    • {@link IndirectHotSpotObjectConstantImpl},
    • - *
    • {@link DirectHotSpotObjectConstantImpl} and
    • - *
    • {@link HotSpotNmethod}
    • - *
    - * - * This mechanism can be used to pass and return values between the HotSpot and JVMCI shared - * library runtimes. In the receiving runtime, the value can be converted back to an object with - * {@link #unhand(Class, long)}. - * - * @param obj an object for which an equivalent instance in the peer runtime is requested - * @return a JNI global reference to the mirror of {@code obj} in the peer runtime - * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. - * {@code -XX:-UseJVMCINativeLibrary}) - * @throws IllegalArgumentException if {@code obj} is not of a translatable type - * - * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references" - */ - public long translate(Object obj) { - return compilerToVm.translate(obj, Option.ForceTranslateFailure.getString() != null); - } - - private static final Pattern FORCE_TRANSLATE_FAILURE_FILTER_RE = Pattern.compile("(?:(method|type|nmethod)/)?([^:]+)(?::(hotspot|native))?"); - - /** - * Forces translation failure based on {@code translatedObject} and the value of - * {@link Option#ForceTranslateFailure}. The value is zero or more filters separated by a comma. - * The syntax for a filter is: - * - *
    -     *   Filter = [ TypeSelector "/" ] Substring [ ":" JVMCIEnvSelector ] .
    -     *   TypeSelector = "type" | "method" | "nmethod"
    -     *   JVMCIEnvSelector = "native" | "hotspot"
    -     * 
    - * - * For example: - * - *
    -     *   -Djvmci.ForceTranslateFailure=nmethod/StackOverflowError:native,method/computeHash,execute
    -     * 
    - * - * will cause failure of: - *
      - *
    • translating a {@link HotSpotNmethod} to the libjvmci heap whose fully qualified name - * contains "StackOverflowError"
    • - *
    • translating a {@link HotSpotResolvedJavaMethodImpl} to the libjvmci or HotSpot heap whose - * fully qualified name contains "computeHash"
    • - *
    • translating a {@link HotSpotNmethod}, {@link HotSpotResolvedJavaMethodImpl} or - * {@link HotSpotResolvedObjectTypeImpl} to the libjvmci or HotSpot heap whose fully qualified - * name contains "execute"
    • - *
    - */ - @VMEntryPoint - static void postTranslation(Object translatedObject) { - String value = Option.ForceTranslateFailure.getString(); - String toMatch; - String type; - if (translatedObject instanceof HotSpotResolvedJavaMethodImpl) { - toMatch = ((HotSpotResolvedJavaMethodImpl) translatedObject).format("%H.%n"); - type = "method"; - } else if (translatedObject instanceof HotSpotResolvedObjectTypeImpl) { - toMatch = ((HotSpotResolvedObjectTypeImpl) translatedObject).toJavaName(); - type = "type"; - } else if (translatedObject instanceof HotSpotNmethod) { - HotSpotNmethod nmethod = (HotSpotNmethod) translatedObject; - if (nmethod.getMethod() != null) { - toMatch = nmethod.getMethod().format("%H.%n"); - } else { - toMatch = String.valueOf(nmethod.getName()); - } - type = "nmethod"; - } else { - return; - } - String[] filters = value.split(","); - for (String filter : filters) { - Matcher m = FORCE_TRANSLATE_FAILURE_FILTER_RE.matcher(filter); - if (!m.matches()) { - throw new JVMCIError(Option.ForceTranslateFailure + " filter does not match " + FORCE_TRANSLATE_FAILURE_FILTER_RE + ": " + filter); - } - String typeSelector = m.group(1); - String substring = m.group(2); - String jvmciEnvSelector = m.group(3); - if (jvmciEnvSelector != null) { - if (jvmciEnvSelector.equals("native")) { - if (!Services.IS_IN_NATIVE_IMAGE) { - continue; - } - } else { - if (Services.IS_IN_NATIVE_IMAGE) { - continue; - } - } - } - if (typeSelector != null && !typeSelector.equals(type)) { - continue; - } - if (toMatch.contains(substring)) { - throw new JVMCIError("translation of " + translatedObject + " failed due to matching " + Option.ForceTranslateFailure + " filter \"" + filter + "\""); - } - } - } - - /** - * Dereferences and returns the object referred to by the JNI global reference {@code handle}. - * The global reference is deleted prior to returning. Any further use of {@code handle} is - * invalid. - * - * @param handle a JNI global reference to an object in the current runtime - * @return the object referred to by {@code handle} - * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. - * {@code -XX:-UseJVMCINativeLibrary}) - * @throws ClassCastException if the returned object cannot be cast to {@code type} - * - * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references" - * - */ - public T unhand(Class type, long handle) { - return type.cast(compilerToVm.unhand(handle)); - } - - /** - * Determines if the current thread is attached to the peer runtime. - * - * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. - * {@code -XX:-UseJVMCINativeLibrary}) - * @throws IllegalStateException if the peer runtime has not been initialized - */ - public boolean isCurrentThreadAttached() { - return compilerToVm.isCurrentThreadAttached(); - } - - /** - * Gets the address of the HotSpot {@code JavaThread} C++ object for the current thread. This - * will return {@code 0} if called from an unattached JVMCI shared library thread. - */ - public long getCurrentJavaThread() { - return compilerToVm.getCurrentJavaThread(); - } - - /** - * Ensures the current thread is attached to the peer runtime. - * - * @param asDaemon if the thread is not yet attached, should it be attached as a daemon - * @return {@code true} if this call attached the current thread, {@code false} if the current - * thread was already attached - * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. - * {@code -XX:-UseJVMCINativeLibrary}) - * @throws IllegalStateException if the peer runtime has not been initialized or there is an - * error while trying to attach the thread - * @throws ArrayIndexOutOfBoundsException if {@code javaVMInfo} is non-null and is shorter than - * the length of the array returned by {@link #registerNativeMethods} - */ - public boolean attachCurrentThread(boolean asDaemon) { - byte[] name = IS_IN_NATIVE_IMAGE ? Thread.currentThread().getName().getBytes() : null; - return compilerToVm.attachCurrentThread(name, asDaemon); - } - - /** - * Detaches the current thread from the peer runtime. - * - * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e. - * {@code -XX:-UseJVMCINativeLibrary}) - * @throws IllegalStateException if the peer runtime has not been initialized or if the current - * thread is not attached or if there is an error while trying to detach the thread - */ - public void detachCurrentThread() { - compilerToVm.detachCurrentThread(); - } - - /** - * Informs HotSpot that no method whose module is in {@code modules} is to be compiled with - * {@link #compileMethod}. - * - * @param modules the set of modules containing JVMCI compiler classes - */ - public void excludeFromJVMCICompilation(Module... modules) { - this.excludeFromJVMCICompilation = modules.clone(); - } - - /** - * Calls {@link System#exit(int)} in HotSpot's runtime. - */ - public void exitHotSpot(int status) { - if (!IS_IN_NATIVE_IMAGE) { - System.exit(status); - } - compilerToVm.callSystemExit(status); - } - - /** - * Writes a message to HotSpot's log stream and then calls {@link System#exit(int)} in HotSpot's - * runtime. - */ - JVMCIError exitHotSpotWithMessage(int status, String format, Object... args) { - byte[] messageBytes = String.format(format, args).getBytes(); - writeDebugOutput(messageBytes, 0, messageBytes.length, true, true); - exitHotSpot(status); - throw JVMCIError.shouldNotReachHere(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.services.Services; - -/** - * Indicates a path in HotSpot JVMCI related code that is unsupported in the current execution - * environment. For example, certain operations are not supported by JVMCI code running in an ahead - * of time compiled {@linkplain Services#IS_IN_NATIVE_IMAGE native image}. This usually reflects - * functionality only needed in non-native image execution that would require a more complex - * implementation to support in a native image. - * - * An example of such functionality is {@link ResolvedJavaType#isLocal()}. This can be conveniently - * implemented when JVMCI is running on the HotSpot heap as we can obtain the {@link Class} mirror - * for the {@link ResolvedJavaType} and call {@link Class#isLocalClass()}. In a native image, there - * is no {@link Class} mirror available in the native image heap so implementing this would involve - * a call into VM native code that in turn would make an upcall into Java code executing on the - * HotSpot heap. We have opted to defer implementing functionality such as this until there's a - * demonstrated need for it. - */ -public class HotSpotJVMCIUnsupportedOperationError extends Error { - - public HotSpotJVMCIUnsupportedOperationError(String reason) { - super(reason); - } - - public HotSpotJVMCIUnsupportedOperationError(String reason, Throwable cause) { - super(reason, cause); - } - - private static final long serialVersionUID = 7782431672678016392L; - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.MemoryAccessProvider; -import jdk.vm.ci.meta.PrimitiveConstant; - -/** - * HotSpot implementation of {@link MemoryAccessProvider}. - */ -class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider { - - protected final HotSpotJVMCIRuntime runtime; - - HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntime runtime) { - this.runtime = runtime; - } - - private static long asRawPointer(Constant base) { - if (base instanceof HotSpotMetaspaceConstantImpl) { - MetaspaceObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base); - return meta.getMetaspacePointer(); - } else if (base instanceof PrimitiveConstant) { - PrimitiveConstant prim = (PrimitiveConstant) base; - if (prim.getJavaKind().isNumericInteger()) { - return prim.asLong(); - } - } - throw new IllegalArgumentException(String.valueOf(base)); - } - - @Override - public JavaConstant readPrimitiveConstant(JavaKind kind, Constant baseConstant, long initialDisplacement, int bits) { - if (baseConstant instanceof HotSpotObjectConstantImpl) { - JavaKind readKind = kind; - if (kind.getBitCount() != bits) { - switch (bits) { - case Byte.SIZE: - readKind = JavaKind.Byte; - break; - case Short.SIZE: - readKind = JavaKind.Short; - break; - case Integer.SIZE: - readKind = JavaKind.Int; - break; - case Long.SIZE: - readKind = JavaKind.Long; - break; - default: - throw new IllegalArgumentException(String.valueOf(bits)); - } - } - HotSpotObjectConstantImpl baseObject = (HotSpotObjectConstantImpl) baseConstant; - JavaConstant result = runtime().compilerToVm.readFieldValue(baseObject, null, initialDisplacement, readKind); - if (result != null && kind != readKind) { - return JavaConstant.forPrimitive(kind, result.asLong()); - } - return result; - } else { - long pointer = asRawPointer(baseConstant); - long value; - switch (bits) { - case Byte.SIZE: - value = UNSAFE.getByte(pointer + initialDisplacement); - break; - case Short.SIZE: - value = UNSAFE.getShort(pointer + initialDisplacement); - break; - case Integer.SIZE: - value = UNSAFE.getInt(pointer + initialDisplacement); - break; - case Long.SIZE: - value = UNSAFE.getLong(pointer + initialDisplacement); - break; - default: - throw new IllegalArgumentException(String.valueOf(bits)); - } - return JavaConstant.forPrimitive(kind, value); - } - } - - @Override - public JavaConstant readObjectConstant(Constant base, long displacement) { - if (base instanceof HotSpotObjectConstantImpl) { - return runtime.getCompilerToVM().readFieldValue((HotSpotObjectConstantImpl) base, null, displacement, JavaKind.Object); - } - if (base instanceof HotSpotMetaspaceConstant) { - MetaspaceObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base); - if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) { - HotSpotResolvedObjectTypeImpl type = (HotSpotResolvedObjectTypeImpl) metaspaceObject; - if (displacement == runtime.getConfig().javaMirrorOffset) { - // Klass::_java_mirror is valid for all Klass* values - return type.getJavaMirror(); - } - return null; - } else { - throw new IllegalArgumentException(String.valueOf(metaspaceObject)); - } - } - return null; - } - - @Override - public JavaConstant readNarrowOopConstant(Constant base, long displacement) { - if (base instanceof HotSpotObjectConstantImpl) { - assert runtime.getConfig().useCompressedOops; - JavaConstant res = runtime.getCompilerToVM().readFieldValue((HotSpotObjectConstantImpl) base, null, displacement, JavaKind.Object); - if (res != null) { - return JavaConstant.NULL_POINTER.equals(res) ? HotSpotCompressedNullConstant.COMPRESSED_NULL : ((HotSpotObjectConstant) res).compress(); - } - } - return null; - } - - private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) { - assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass(); - if (base instanceof HotSpotMetaspaceConstantImpl) { - return runtime.getCompilerToVM().getResolvedJavaType((HotSpotResolvedObjectTypeImpl) ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType(), displacement, compressed); - } else { - return runtime.getCompilerToVM().getResolvedJavaType(((HotSpotObjectConstantImpl) base), displacement, compressed); - } - } - - @Override - public Constant readKlassPointerConstant(Constant base, long displacement) { - HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false); - if (klass == null) { - return JavaConstant.NULL_POINTER; - } - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, false); - } - - @Override - public Constant readNarrowKlassPointerConstant(Constant base, long displacement) { - HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, true); - if (klass == null) { - return HotSpotCompressedNullConstant.COMPRESSED_NULL; - } - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, true); - } - - @Override - public Constant readMethodPointerConstant(Constant base, long displacement) { - assert (base instanceof HotSpotObjectConstantImpl); - HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod((HotSpotObjectConstantImpl) base, displacement); - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.MemoryAccessProvider; - -/** - * HotSpot specific extension of {@link MemoryAccessProvider}. - */ -public interface HotSpotMemoryAccessProvider extends MemoryAccessProvider { - - /** - * @throws IllegalArgumentException if the address computed from {@code base} and - * {@code displacement} does not denote a location holding a narrow oop - */ - JavaConstant readNarrowOopConstant(Constant base, long displacement); - - Constant readKlassPointerConstant(Constant base, long displacement); - - Constant readNarrowKlassPointerConstant(Constant base, long displacement); - - Constant readMethodPointerConstant(Constant base, long displacement); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,347 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Objects; - -import jdk.vm.ci.code.CodeUtil; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.DeoptimizationAction; -import jdk.vm.ci.meta.DeoptimizationReason; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; -import jdk.vm.ci.meta.SpeculationLog; -import jdk.vm.ci.meta.SpeculationLog.NoSpeculationReason; -import jdk.vm.ci.meta.SpeculationLog.Speculation; - -// JaCoCo Exclude - -/** - * HotSpot implementation of {@link MetaAccessProvider}. - */ -public class HotSpotMetaAccessProvider implements MetaAccessProvider { - - protected final HotSpotJVMCIRuntime runtime; - - public HotSpotMetaAccessProvider(HotSpotJVMCIRuntime runtime) { - this.runtime = runtime; - } - - @Override - public ResolvedJavaType lookupJavaType(Class clazz) { - if (clazz == null) { - throw new IllegalArgumentException("Class parameter was null"); - } - return runtime.fromClass(clazz); - } - - @Override - public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) { - if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) { - return null; - } - return ((HotSpotObjectConstant) constant).getType(); - } - - @Override - public Signature parseMethodDescriptor(String signature) { - return new HotSpotSignature(runtime, signature); - } - - @Override - public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) { - return runtime.getCompilerToVM().asResolvedJavaMethod(Objects.requireNonNull(reflectionMethod)); - } - - @Override - public ResolvedJavaField lookupJavaField(Field reflectionField) { - Class fieldHolder = reflectionField.getDeclaringClass(); - - HotSpotResolvedJavaType holder = runtime.fromClass(fieldHolder); - assert holder != null : fieldHolder; - ResolvedJavaField[] fields; - if (Modifier.isStatic(reflectionField.getModifiers())) { - fields = holder.getStaticFields(); - } else { - fields = holder.getInstanceFields(false); - } - ResolvedJavaType fieldType = lookupJavaType(reflectionField.getType()); - for (ResolvedJavaField field : fields) { - if (reflectionField.getName().equals(field.getName()) && field.getType().equals(fieldType)) { - assert Modifier.isStatic(reflectionField.getModifiers()) == field.isStatic(); - return field; - } - } - - throw new JVMCIError("unresolved field %s", reflectionField); - } - - private static int intMaskRight(int n) { - assert n <= 32; - return n == 32 ? -1 : (1 << n) - 1; - } - - @Override - public JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId) { - HotSpotVMConfig config = runtime.getConfig(); - int actionValue = convertDeoptAction(action); - int reasonValue = convertDeoptReason(reason); - int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits); - JavaConstant c = JavaConstant.forInt( - ~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift))); - assert c.asInt() < 0; - return c; - } - - @Override - public DeoptimizationReason decodeDeoptReason(JavaConstant constant) { - HotSpotVMConfig config = runtime.getConfig(); - int reasonValue = ((~constant.asInt()) >> config.deoptimizationReasonShift) & intMaskRight(config.deoptimizationReasonBits); - DeoptimizationReason reason = convertDeoptReason(reasonValue); - return reason; - } - - @Override - public DeoptimizationAction decodeDeoptAction(JavaConstant constant) { - HotSpotVMConfig config = runtime.getConfig(); - int actionValue = ((~constant.asInt()) >> config.deoptimizationActionShift) & intMaskRight(config.deoptimizationActionBits); - DeoptimizationAction action = convertDeoptAction(actionValue); - return action; - } - - @Override - public int decodeDebugId(JavaConstant constant) { - HotSpotVMConfig config = runtime.getConfig(); - return ((~constant.asInt()) >> config.deoptimizationDebugIdShift) & intMaskRight(config.deoptimizationDebugIdBits); - } - - @Override - public JavaConstant encodeSpeculation(Speculation speculation) { - if (speculation.getReason() instanceof NoSpeculationReason) { - return JavaConstant.LONG_0; - } - return ((HotSpotSpeculationLog.HotSpotSpeculation) speculation).getEncoding(); - } - - @Override - public Speculation decodeSpeculation(JavaConstant constant, SpeculationLog speculationLog) { - if (constant.equals(JavaConstant.LONG_0)) { - return SpeculationLog.NO_SPECULATION; - } - if (speculationLog == null) { - throw new IllegalArgumentException("A speculation log is required to decode the speculation denoted by " + constant); - } - return speculationLog.lookupSpeculation(constant); - } - - public int convertDeoptAction(DeoptimizationAction action) { - HotSpotVMConfig config = runtime.getConfig(); - switch (action) { - case None: - return config.deoptActionNone; - case RecompileIfTooManyDeopts: - return config.deoptActionMaybeRecompile; - case InvalidateReprofile: - return config.deoptActionReinterpret; - case InvalidateRecompile: - return config.deoptActionMakeNotEntrant; - case InvalidateStopCompiling: - return config.deoptActionMakeNotCompilable; - default: - throw new JVMCIError("%s", action); - } - } - - public DeoptimizationAction convertDeoptAction(int action) { - HotSpotVMConfig config = runtime.getConfig(); - if (action == config.deoptActionNone) { - return DeoptimizationAction.None; - } - if (action == config.deoptActionMaybeRecompile) { - return DeoptimizationAction.RecompileIfTooManyDeopts; - } - if (action == config.deoptActionReinterpret) { - return DeoptimizationAction.InvalidateReprofile; - } - if (action == config.deoptActionMakeNotEntrant) { - return DeoptimizationAction.InvalidateRecompile; - } - if (action == config.deoptActionMakeNotCompilable) { - return DeoptimizationAction.InvalidateStopCompiling; - } - throw new JVMCIError("%d", action); - } - - public int convertDeoptReason(DeoptimizationReason reason) { - HotSpotVMConfig config = runtime.getConfig(); - switch (reason) { - case None: - return config.deoptReasonNone; - case NullCheckException: - return config.deoptReasonNullCheck; - case BoundsCheckException: - return config.deoptReasonRangeCheck; - case ClassCastException: - return config.deoptReasonClassCheck; - case ArrayStoreException: - return config.deoptReasonArrayCheck; - case UnreachedCode: - return config.deoptReasonUnreached0; - case TypeCheckedInliningViolated: - return config.deoptReasonTypeCheckInlining; - case OptimizedTypeCheckViolated: - return config.deoptReasonOptimizedTypeCheck; - case NotCompiledExceptionHandler: - return config.deoptReasonNotCompiledExceptionHandler; - case Unresolved: - return config.deoptReasonUnresolved; - case JavaSubroutineMismatch: - return config.deoptReasonJsrMismatch; - case ArithmeticException: - return config.deoptReasonDiv0Check; - case RuntimeConstraint: - return config.deoptReasonConstraint; - case LoopLimitCheck: - return config.deoptReasonLoopLimitCheck; - case Aliasing: - return config.deoptReasonAliasing; - case TransferToInterpreter: - return config.deoptReasonTransferToInterpreter; - default: - throw new JVMCIError("%s", reason); - } - } - - public DeoptimizationReason convertDeoptReason(int reason) { - HotSpotVMConfig config = runtime.getConfig(); - if (reason == config.deoptReasonNone) { - return DeoptimizationReason.None; - } - if (reason == config.deoptReasonNullCheck) { - return DeoptimizationReason.NullCheckException; - } - if (reason == config.deoptReasonRangeCheck) { - return DeoptimizationReason.BoundsCheckException; - } - if (reason == config.deoptReasonClassCheck) { - return DeoptimizationReason.ClassCastException; - } - if (reason == config.deoptReasonArrayCheck) { - return DeoptimizationReason.ArrayStoreException; - } - if (reason == config.deoptReasonUnreached0) { - return DeoptimizationReason.UnreachedCode; - } - if (reason == config.deoptReasonTypeCheckInlining) { - return DeoptimizationReason.TypeCheckedInliningViolated; - } - if (reason == config.deoptReasonOptimizedTypeCheck) { - return DeoptimizationReason.OptimizedTypeCheckViolated; - } - if (reason == config.deoptReasonNotCompiledExceptionHandler) { - return DeoptimizationReason.NotCompiledExceptionHandler; - } - if (reason == config.deoptReasonUnresolved) { - return DeoptimizationReason.Unresolved; - } - if (reason == config.deoptReasonJsrMismatch) { - return DeoptimizationReason.JavaSubroutineMismatch; - } - if (reason == config.deoptReasonDiv0Check) { - return DeoptimizationReason.ArithmeticException; - } - if (reason == config.deoptReasonConstraint) { - return DeoptimizationReason.RuntimeConstraint; - } - if (reason == config.deoptReasonLoopLimitCheck) { - return DeoptimizationReason.LoopLimitCheck; - } - if (reason == config.deoptReasonAliasing) { - return DeoptimizationReason.Aliasing; - } - if (reason == config.deoptReasonTransferToInterpreter) { - return DeoptimizationReason.TransferToInterpreter; - } - throw new JVMCIError("%x", reason); - } - - @Override - public long getMemorySize(JavaConstant constant) { - if (constant.getJavaKind() == JavaKind.Object) { - HotSpotResolvedObjectType lookupJavaType = lookupJavaType(constant); - - if (lookupJavaType == null) { - return 0; - } else { - if (lookupJavaType.isArray()) { - int length = runtime.getHostJVMCIBackend().getConstantReflection().readArrayLength(constant); - ResolvedJavaType elementType = lookupJavaType.getComponentType(); - JavaKind elementKind = elementType.getJavaKind(); - final int headerSize = runtime.getArrayBaseOffset(elementKind); - int sizeOfElement = runtime.getArrayIndexScale(elementKind); - int log2ElementSize = CodeUtil.log2(sizeOfElement); - return computeArrayAllocationSize(length, headerSize, log2ElementSize); - } - return lookupJavaType.instanceSize(); - } - } else { - return constant.getJavaKind().getByteCount(); - } - } - - /** - * Computes the size of the memory chunk allocated for an array. This size accounts for the - * array header size, body size and any padding after the last element to satisfy object - * alignment requirements. - * - * @param length the number of elements in the array - * @param headerSize the size of the array header - * @param log2ElementSize log2 of the size of an element in the array - * @return the size of the memory chunk - */ - public int computeArrayAllocationSize(int length, int headerSize, int log2ElementSize) { - HotSpotVMConfig config = runtime.getConfig(); - int alignment = config.objectAlignment; - int size = (length << log2ElementSize) + headerSize + (alignment - 1); - int mask = ~(alignment - 1); - return size & mask; - } - - @Override - public int getArrayBaseOffset(JavaKind kind) { - return runtime.getArrayBaseOffset(kind); - } - - @Override - public int getArrayIndexScale(JavaKind kind) { - return runtime.getArrayIndexScale(kind); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import jdk.vm.ci.code.TargetDescription; - -public class HotSpotMetaData { - private byte[] pcDescBytes; - private byte[] scopesDescBytes; - private byte[] relocBytes; - private byte[] exceptionBytes; - private byte[] implicitExceptionBytes; - private byte[] oopMaps; - private Object[] metadata; - - public HotSpotMetaData(TargetDescription target, HotSpotCompiledCode compiledMethod) { - // Assign the fields default values... - pcDescBytes = new byte[0]; - scopesDescBytes = new byte[0]; - relocBytes = new byte[0]; - exceptionBytes = new byte[0]; - oopMaps = new byte[0]; - metadata = new String[0]; - // ...some of them will be overwritten by the VM: - runtime().getCompilerToVM().getMetadata(target, compiledMethod, this); - } - - public byte[] pcDescBytes() { - return pcDescBytes; - } - - public byte[] scopesDescBytes() { - return scopesDescBytes; - } - - public byte[] relocBytes() { - return relocBytes; - } - - public byte[] exceptionBytes() { - return exceptionBytes; - } - - public byte[] implicitExceptionBytes() { - return implicitExceptionBytes; - } - - public byte[] oopMaps() { - return oopMaps; - } - - public Object[] metadataEntries() { - return metadata; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2014, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.util.Objects; - -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.VMConstant; - -final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant { - - static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceObject metaspaceObject, boolean compressed) { - return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed); - } - - static MetaspaceObject getMetaspaceObject(Constant constant) { - return ((HotSpotMetaspaceConstantImpl) constant).metaspaceObject; - } - - private final MetaspaceObject metaspaceObject; - private final boolean compressed; - - private HotSpotMetaspaceConstantImpl(MetaspaceObject metaspaceObject, boolean compressed) { - this.metaspaceObject = metaspaceObject; - this.compressed = compressed; - } - - @Override - public int hashCode() { - return System.identityHashCode(metaspaceObject) ^ (compressed ? 1 : 2); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof HotSpotMetaspaceConstantImpl)) { - return false; - } - - HotSpotMetaspaceConstantImpl other = (HotSpotMetaspaceConstantImpl) o; - return Objects.equals(this.metaspaceObject, other.metaspaceObject) && this.compressed == other.compressed; - } - - @Override - public String toValueString() { - return String.format("meta{%s%s}", metaspaceObject, compressed ? ";compressed" : ""); - } - - @Override - public String toString() { - return toValueString(); - } - - @Override - public boolean isDefaultForKind() { - return false; - } - - @Override - public boolean isCompressed() { - return compressed; - } - - @Override - public Constant compress() { - assert !isCompressed(); - HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, true); - assert res.isCompressed(); - return res; - } - - @Override - public Constant uncompress() { - assert isCompressed(); - HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, false); - assert !res.isCompressed(); - return res; - } - - @Override - public HotSpotResolvedObjectType asResolvedJavaType() { - if (metaspaceObject instanceof HotSpotResolvedObjectType) { - return (HotSpotResolvedObjectType) metaspaceObject; - } - return null; - } - - @Override - public HotSpotResolvedJavaMethod asResolvedJavaMethod() { - if (metaspaceObject instanceof HotSpotResolvedJavaMethod) { - return (HotSpotResolvedJavaMethod) metaspaceObject; - } - return null; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.VMConstant; - -public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant { - - HotSpotResolvedObjectType asResolvedJavaType(); - - HotSpotResolvedJavaMethod asResolvedJavaMethod(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.JavaMethodProfile; -import jdk.vm.ci.meta.JavaTypeProfile; -import jdk.vm.ci.meta.ProfilingInfo; -import jdk.vm.ci.meta.TriState; - -/** - * Base class for accessing the different kinds of data in a HotSpot {@code MethodData}. This is - * similar to {@link ProfilingInfo}, but most methods require a {@link HotSpotMethodData} and the - * exact position within the method data. - */ -abstract class HotSpotMethodDataAccessor { - - final int tag; - final int staticSize; - final HotSpotMethodData.VMState state; - final HotSpotVMConfig config; - - protected HotSpotMethodDataAccessor(HotSpotMethodData.VMState state, int tag, int staticSize) { - this.state = state; - this.config = state.config; - this.tag = tag; - this.staticSize = staticSize; - } - - /** - * Returns the tag stored in the LayoutData header. - * - * @return tag stored in the LayoutData header - */ - int getTag() { - return tag; - } - - static int readTag(HotSpotVMConfig config, HotSpotMethodData data, int position) { - final int tag = data.readUnsignedByte(position, config.dataLayoutTagOffset); - assert tag >= config.dataLayoutNoTag && tag <= config.dataLayoutSpeculativeTrapDataTag : "profile data tag out of bounds: " + tag; - return tag; - } - - /** - * Returns the BCI stored in the LayoutData header. - * - * @return an integer between 0 and {@link Short#MAX_VALUE} inclusive, or -1 if not supported - */ - int getBCI(HotSpotMethodData data, int position) { - return data.readUnsignedShort(position, config.dataLayoutBCIOffset); - } - - /** - * Computes the size for the specific data at the given position. - * - * @return a value greater than 0 - */ - final int getSize(HotSpotMethodData data, int position) { - int size = staticSize + getDynamicSize(data, position); - // Sanity check against VM - int vmSize = HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position); - assert size == vmSize : size + " != " + vmSize; - return size; - } - - TriState getExceptionSeen(HotSpotMethodData data, int position) { - final int exceptionsMask = 1 << config.bitDataExceptionSeenFlag; - return TriState.get((getFlags(data, position) & exceptionsMask) != 0); - } - - /** - * @param data - * @param position - */ - JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) { - return null; - } - - /** - * @param data - * @param position - */ - JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) { - return null; - } - - /** - * @param data - * @param position - */ - double getBranchTakenProbability(HotSpotMethodData data, int position) { - return -1; - } - - /** - * @param data - * @param position - */ - double[] getSwitchProbabilities(HotSpotMethodData data, int position) { - return null; - } - - /** - * @param data - * @param position - */ - int getExecutionCount(HotSpotMethodData data, int position) { - return -1; - } - - /** - * @param data - * @param position - */ - TriState getNullSeen(HotSpotMethodData data, int position) { - return TriState.UNKNOWN; - } - - protected int getFlags(HotSpotMethodData data, int position) { - return data.readUnsignedByte(position, config.dataLayoutFlagsOffset); - } - - /** - * @param data - * @param position - */ - protected int getDynamicSize(HotSpotMethodData data, int position) { - return 0; - } - - abstract StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos); - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,890 +0,0 @@ -/* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static java.lang.String.format; -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import java.util.Arrays; - -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.internal.misc.Unsafe; -import jdk.vm.ci.meta.DeoptimizationReason; -import jdk.vm.ci.meta.JavaMethodProfile; -import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod; -import jdk.vm.ci.meta.JavaTypeProfile; -import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.TriState; - -/** - * Access to a HotSpot {@code MethodData} structure (defined in methodData.hpp). - */ -final class HotSpotMethodData { - - /** - * VM state that can be reset when building an AOT image. - */ - static final class VMState { - final HotSpotVMConfig config = config(); - final HotSpotMethodDataAccessor noDataNoExceptionAccessor = new NoMethodData(this, config.dataLayoutNoTag, TriState.FALSE); - final HotSpotMethodDataAccessor noDataExceptionPossiblyNotRecordedAccessor = new NoMethodData(this, config.dataLayoutNoTag, TriState.UNKNOWN); - final int noDataSize = cellIndexToOffset(0); - final int bitDataSize = cellIndexToOffset(0); - final int bitDataNullSeenFlag = 1 << config.bitDataNullSeenFlag; - final int counterDataSize = cellIndexToOffset(1); - final int counterDataCountOffset = cellIndexToOffset(config.methodDataCountOffset); - final int jumpDataSize = cellIndexToOffset(2); - final int takenCountOffset = cellIndexToOffset(config.jumpDataTakenOffset); - final int takenDisplacementOffset = cellIndexToOffset(config.jumpDataDisplacementOffset); - final int typeDataRowSize = cellsToBytes(config.receiverTypeDataReceiverTypeRowCellCount); - - final int nonprofiledCountOffset = cellIndexToOffset(config.receiverTypeDataNonprofiledCountOffset); - final int typeDataFirstTypeOffset = cellIndexToOffset(config.receiverTypeDataReceiver0Offset); - final int typeDataFirstTypeCountOffset = cellIndexToOffset(config.receiverTypeDataCount0Offset); - - final int typeCheckDataSize = cellIndexToOffset(2) + typeDataRowSize * config.typeProfileWidth; - final int virtualCallDataSize = cellIndexToOffset(2) + typeDataRowSize * (config.typeProfileWidth + config.methodProfileWidth); - final int virtualCallDataFirstMethodOffset = typeDataFirstTypeOffset + typeDataRowSize * config.typeProfileWidth; - final int virtualCallDataFirstMethodCountOffset = typeDataFirstTypeCountOffset + typeDataRowSize * config.typeProfileWidth; - - final int retDataRowSize = cellsToBytes(3); - final int retDataSize = cellIndexToOffset(1) + retDataRowSize * config.bciProfileWidth; - - final int branchDataSize = cellIndexToOffset(3); - final int notTakenCountOffset = cellIndexToOffset(config.branchDataNotTakenOffset); - - final int arrayDataLengthOffset = cellIndexToOffset(config.arrayDataArrayLenOffset); - final int arrayDataStartOffset = cellIndexToOffset(config.arrayDataArrayStartOffset); - - final int multiBranchDataSize = cellIndexToOffset(1); - final int multiBranchDataRowSizeInCells = config.multiBranchDataPerCaseCellCount; - final int multiBranchDataRowSize = cellsToBytes(multiBranchDataRowSizeInCells); - final int multiBranchDataFirstCountOffset = arrayDataStartOffset + cellsToBytes(0); - final int multiBranchDataFirstDisplacementOffset = arrayDataStartOffset + cellsToBytes(1); - - final int argInfoDataSize = cellIndexToOffset(1); - - // sorted by tag - // @formatter:off - final HotSpotMethodDataAccessor[] profileDataAccessors = { - null, - new BitData(this, config.dataLayoutBitDataTag), - new CounterData(this, config.dataLayoutCounterDataTag), - new JumpData(this, config.dataLayoutJumpDataTag), - new ReceiverTypeData(this, config.dataLayoutReceiverTypeDataTag), - new VirtualCallData(this, config.dataLayoutVirtualCallDataTag), - new RetData(this, config.dataLayoutRetDataTag), - new BranchData(this, config.dataLayoutBranchDataTag), - new MultiBranchData(this, config.dataLayoutMultiBranchDataTag), - new ArgInfoData(this, config.dataLayoutArgInfoDataTag), - new UnknownProfileData(this, config.dataLayoutCallTypeDataTag), - new VirtualCallTypeData(this, config.dataLayoutVirtualCallTypeDataTag), - new UnknownProfileData(this, config.dataLayoutParametersTypeDataTag), - new UnknownProfileData(this, config.dataLayoutSpeculativeTrapDataTag), - }; - // @formatter:on - - private boolean checkAccessorTags() { - int expectedTag = 0; - for (HotSpotMethodDataAccessor accessor : profileDataAccessors) { - if (expectedTag == 0) { - assert accessor == null; - } else { - assert accessor.tag == expectedTag : expectedTag + " != " + accessor.tag + " " + accessor; - } - expectedTag++; - } - return true; - } - - private VMState() { - assert checkAccessorTags(); - } - - private static int truncateLongToInt(long value) { - return value > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) value; - } - - private int computeFullOffset(int position, int offsetInBytes) { - return config.methodDataOopDataOffset + position + offsetInBytes; - } - - private int cellIndexToOffset(int cells) { - return config.dataLayoutHeaderSize + cellsToBytes(cells); - } - - private int cellsToBytes(int cells) { - return cells * config.dataLayoutCellSize; - } - - /** - * Singleton instance lazily initialized via double-checked locking. - */ - @NativeImageReinitialize private static volatile VMState instance; - - static VMState instance() { - VMState result = instance; - if (result == null) { - synchronized (VMState.class) { - result = instance; - if (result == null) { - instance = result = new VMState(); - } - } - } - return result; - } - } - - /** - * Reference to the C++ MethodData object. - */ - final long metaspaceMethodData; - private final HotSpotResolvedJavaMethodImpl method; - private final VMState state; - - HotSpotMethodData(long metaspaceMethodData, HotSpotResolvedJavaMethodImpl method) { - this.metaspaceMethodData = metaspaceMethodData; - this.method = method; - this.state = VMState.instance(); - } - - /** - * @return value of the MethodData::_data_size field - */ - private int normalDataSize() { - return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataDataSize); - } - - /** - * Returns the size of the extra data records. This method does the same calculation as - * MethodData::extra_data_size(). - * - * @return size of extra data records - */ - private int extraDataSize() { - final int extraDataBase = state.config.methodDataOopDataOffset + normalDataSize(); - final int extraDataLimit = UNSAFE.getInt(metaspaceMethodData + state.config.methodDataSize); - return extraDataLimit - extraDataBase; - } - - public boolean hasNormalData() { - return normalDataSize() > 0; - } - - public boolean hasExtraData() { - return extraDataSize() > 0; - } - - public int getExtraDataBeginOffset() { - return normalDataSize(); - } - - public boolean isWithin(int position) { - return position >= 0 && position < normalDataSize() + extraDataSize(); - } - - public int getDeoptimizationCount(DeoptimizationReason reason) { - HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess(); - int reasonIndex = metaAccess.convertDeoptReason(reason); - return UNSAFE.getByte(metaspaceMethodData + state.config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF; - } - - public int getOSRDeoptimizationCount(DeoptimizationReason reason) { - HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess(); - int reasonIndex = metaAccess.convertDeoptReason(reason); - return UNSAFE.getByte(metaspaceMethodData + state.config.methodDataOopTrapHistoryOffset + state.config.deoptReasonOSROffset + reasonIndex) & 0xFF; - } - - public int getDecompileCount() { - return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataDecompiles); - } - - public int getOverflowRecompileCount() { - return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataOverflowRecompiles); - } - - public int getOverflowTrapCount() { - return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataOverflowTraps); - } - - public HotSpotMethodDataAccessor getNormalData(int position) { - if (position >= normalDataSize()) { - return null; - } - - return getData(position); - } - - public HotSpotMethodDataAccessor getExtraData(int position) { - if (position >= normalDataSize() + extraDataSize()) { - return null; - } - HotSpotMethodDataAccessor data = getData(position); - if (data != null) { - return data; - } - return data; - } - - public static HotSpotMethodDataAccessor getNoDataAccessor(boolean exceptionPossiblyNotRecorded) { - if (exceptionPossiblyNotRecorded) { - return VMState.instance().noDataExceptionPossiblyNotRecordedAccessor; - } else { - return VMState.instance().noDataNoExceptionAccessor; - } - } - - private HotSpotMethodDataAccessor getData(int position) { - assert position >= 0 : "out of bounds"; - final int tag = HotSpotMethodDataAccessor.readTag(state.config, this, position); - HotSpotMethodDataAccessor accessor = state.profileDataAccessors[tag]; - assert accessor == null || accessor.getTag() == tag : "wrong data accessor " + accessor + " for tag " + tag; - return accessor; - } - - int readUnsignedByte(int position, int offsetInBytes) { - long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); - return UNSAFE.getByte(metaspaceMethodData + fullOffsetInBytes) & 0xFF; - } - - int readUnsignedShort(int position, int offsetInBytes) { - long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); - return UNSAFE.getShort(metaspaceMethodData + fullOffsetInBytes) & 0xFFFF; - } - - /** - * Since the values are stored in cells (platform words) this method uses - * {@link Unsafe#getAddress} to read the right value on both little and big endian machines. - */ - private long readUnsignedInt(int position, int offsetInBytes) { - long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); - return UNSAFE.getAddress(metaspaceMethodData + fullOffsetInBytes) & 0xFFFFFFFFL; - } - - private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) { - long value = readUnsignedInt(position, offsetInBytes); - return VMState.truncateLongToInt(value); - } - - /** - * Since the values are stored in cells (platform words) this method uses - * {@link Unsafe#getAddress} to read the right value on both little and big endian machines. - */ - private int readInt(int position, int offsetInBytes) { - long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); - return (int) UNSAFE.getAddress(metaspaceMethodData + fullOffsetInBytes); - } - - private HotSpotResolvedJavaMethod readMethod(int position, int offsetInBytes) { - long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); - return compilerToVM().getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes); - } - - private HotSpotResolvedObjectTypeImpl readKlass(int position, int offsetInBytes) { - long fullOffsetInBytes = state.computeFullOffset(position, offsetInBytes); - return compilerToVM().getResolvedJavaType(metaspaceMethodData + fullOffsetInBytes, false); - } - - /** - * Returns whether profiling ran long enough that the profile information is mature. Other - * informational data will still be valid even if the profile isn't mature. - */ - public boolean isProfileMature() { - return runtime().getCompilerToVM().isMature(metaspaceMethodData); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - String nl = String.format("%n"); - String nlIndent = String.format("%n%38s", ""); - sb.append("Raw method data for "); - sb.append(method.format("%H.%n(%p)")); - sb.append(":"); - sb.append(nl); - sb.append(String.format("nof_decompiles(%d) nof_overflow_recompiles(%d) nof_overflow_traps(%d)%n", - getDecompileCount(), getOverflowRecompileCount(), getOverflowTrapCount())); - if (hasNormalData()) { - int pos = 0; - HotSpotMethodDataAccessor data; - while ((data = getNormalData(pos)) != null) { - if (pos != 0) { - sb.append(nl); - } - int bci = data.getBCI(this, pos); - sb.append(String.format("%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName())); - sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent)); - pos = pos + data.getSize(this, pos); - } - } - - if (hasExtraData()) { - int pos = getExtraDataBeginOffset(); - HotSpotMethodDataAccessor data; - while ((data = getExtraData(pos)) != null) { - if (pos == getExtraDataBeginOffset()) { - sb.append(nl).append("--- Extra data:"); - } - int bci = data.getBCI(this, pos); - sb.append(String.format("%n%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName())); - sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent)); - pos = pos + data.getSize(this, pos); - } - - } - return sb.toString(); - } - - static class NoMethodData extends HotSpotMethodDataAccessor { - - private final TriState exceptionSeen; - - protected NoMethodData(VMState state, int tag, TriState exceptionSeen) { - super(state, tag, state.noDataSize); - this.exceptionSeen = exceptionSeen; - } - - @Override - public int getBCI(HotSpotMethodData data, int position) { - return -1; - } - - @Override - public TriState getExceptionSeen(HotSpotMethodData data, int position) { - return exceptionSeen; - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - return sb; - } - } - - static class BitData extends HotSpotMethodDataAccessor { - - private BitData(VMState state, int tag) { - super(state, tag, state.bitDataSize); - } - - protected BitData(VMState state, int tag, int staticSize) { - super(state, tag, staticSize); - } - - @Override - public TriState getNullSeen(HotSpotMethodData data, int position) { - return TriState.get((getFlags(data, position) & state.bitDataNullSeenFlag) != 0); - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - return sb.append(format("exception_seen(%s)", getExceptionSeen(data, pos))); - } - } - - static class CounterData extends BitData { - - CounterData(VMState state, int tag) { - super(state, tag, state.counterDataSize); - } - - protected CounterData(VMState state, int tag, int staticSize) { - super(state, tag, staticSize); - } - - @Override - public int getExecutionCount(HotSpotMethodData data, int position) { - return getCounterValue(data, position); - } - - protected int getCounterValue(HotSpotMethodData data, int position) { - return data.readUnsignedIntAsSignedInt(position, state.counterDataCountOffset); - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - return sb.append(format("count(%d) null_seen(%s) exception_seen(%s)", getCounterValue(data, pos), getNullSeen(data, pos), getExceptionSeen(data, pos))); - } - } - - static class JumpData extends HotSpotMethodDataAccessor { - - JumpData(VMState state, int tag) { - super(state, tag, state.jumpDataSize); - } - - protected JumpData(VMState state, int tag, int staticSize) { - super(state, tag, staticSize); - } - - @Override - public double getBranchTakenProbability(HotSpotMethodData data, int position) { - return getExecutionCount(data, position) != 0 ? 1 : 0; - } - - @Override - public int getExecutionCount(HotSpotMethodData data, int position) { - return data.readUnsignedIntAsSignedInt(position, state.takenCountOffset); - } - - public int getTakenDisplacement(HotSpotMethodData data, int position) { - return data.readInt(position, state.takenDisplacementOffset); - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - return sb.append(format("taken(%d) displacement(%d)", getExecutionCount(data, pos), getTakenDisplacement(data, pos))); - } - } - - static class RawItemProfile { - final int entries; - final T[] items; - final long[] counts; - final long totalCount; - - RawItemProfile(int entries, T[] items, long[] counts, long totalCount) { - this.entries = entries; - this.items = items; - this.counts = counts; - this.totalCount = totalCount; - } - } - - abstract static class AbstractTypeData extends CounterData { - - protected AbstractTypeData(VMState state, int tag, int staticSize) { - super(state, tag, staticSize); - } - - @Override - public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) { - return createTypeProfile(getNullSeen(data, position), getRawTypeProfile(data, position)); - } - - private RawItemProfile getRawTypeProfile(HotSpotMethodData data, int position) { - int typeProfileWidth = config.typeProfileWidth; - - ResolvedJavaType[] types = new ResolvedJavaType[typeProfileWidth]; - long[] counts = new long[typeProfileWidth]; - long totalCount = 0; - int entries = 0; - - outer: for (int i = 0; i < typeProfileWidth; i++) { - HotSpotResolvedObjectTypeImpl receiverKlass = data.readKlass(position, getTypeOffset(i)); - if (receiverKlass != null) { - HotSpotResolvedObjectTypeImpl klass = receiverKlass; - long count = data.readUnsignedInt(position, getTypeCountOffset(i)); - /* - * Because of races in the profile collection machinery it's possible for a - * class to appear multiple times so merge them to make the profile look - * rational. - */ - for (int j = 0; j < entries; j++) { - if (types[j].equals(klass)) { - totalCount += count; - counts[j] += count; - continue outer; - } - } - types[entries] = klass; - totalCount += count; - counts[entries] = count; - entries++; - } - } - - totalCount += getTypesNotRecordedExecutionCount(data, position); - return new RawItemProfile<>(entries, types, counts, totalCount); - } - - protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position); - - public int getNonprofiledCount(HotSpotMethodData data, int position) { - return data.readUnsignedIntAsSignedInt(position, state.nonprofiledCountOffset); - } - - private JavaTypeProfile createTypeProfile(TriState nullSeen, RawItemProfile profile) { - if (profile.entries <= 0 || profile.totalCount <= 0) { - return null; - } - - ProfiledType[] ptypes = new ProfiledType[profile.entries]; - double totalProbability = 0.0; - for (int i = 0; i < profile.entries; i++) { - double p = profile.counts[i]; - p = p / profile.totalCount; - totalProbability += p; - ptypes[i] = new ProfiledType(profile.items[i], p); - } - - Arrays.sort(ptypes); - - double notRecordedTypeProbability = profile.entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); - assert notRecordedTypeProbability == 0 || profile.entries == config.typeProfileWidth; - return new JavaTypeProfile(nullSeen, notRecordedTypeProbability, ptypes); - } - - private int getTypeOffset(int row) { - return state.typeDataFirstTypeOffset + row * state.typeDataRowSize; - } - - protected int getTypeCountOffset(int row) { - return state.typeDataFirstTypeCountOffset + row * state.typeDataRowSize; - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - RawItemProfile profile = getRawTypeProfile(data, pos); - TriState nullSeen = getNullSeen(data, pos); - TriState exceptionSeen = getExceptionSeen(data, pos); - sb.append(format("count(%d) null_seen(%s) exception_seen(%s) nonprofiled_count(%d) entries(%d)", getCounterValue(data, pos), nullSeen, exceptionSeen, - getNonprofiledCount(data, pos), profile.entries)); - for (int i = 0; i < profile.entries; i++) { - long count = profile.counts[i]; - sb.append(format("%n %s (%d, %4.2f)", profile.items[i].toJavaName(), count, (double) count / profile.totalCount)); - } - return sb; - } - } - - static class ReceiverTypeData extends AbstractTypeData { - - ReceiverTypeData(VMState state, int tag) { - super(state, tag, state.typeCheckDataSize); - } - - protected ReceiverTypeData(VMState state, int tag, int staticSize) { - super(state, tag, staticSize); - } - - @Override - public int getExecutionCount(HotSpotMethodData data, int position) { - return -1; - } - - @Override - protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) { - return getNonprofiledCount(data, position); - } - } - - static class VirtualCallData extends ReceiverTypeData { - - VirtualCallData(VMState state, int tag) { - super(state, tag, state.virtualCallDataSize); - } - - protected VirtualCallData(VMState state, int tag, int staticSize) { - super(state, tag, staticSize); - } - - @Override - public int getExecutionCount(HotSpotMethodData data, int position) { - final int typeProfileWidth = config.typeProfileWidth; - - long total = 0; - for (int i = 0; i < typeProfileWidth; i++) { - total += data.readUnsignedInt(position, getTypeCountOffset(i)); - } - - total += getCounterValue(data, position); - return VMState.truncateLongToInt(total); - } - - @Override - protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) { - return getCounterValue(data, position); - } - - private long getMethodsNotRecordedExecutionCount(HotSpotMethodData data, int position) { - return data.readUnsignedIntAsSignedInt(position, state.nonprofiledCountOffset); - } - - @Override - public JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) { - return createMethodProfile(getRawMethodProfile(data, position)); - } - - private RawItemProfile getRawMethodProfile(HotSpotMethodData data, int position) { - int profileWidth = config.methodProfileWidth; - - ResolvedJavaMethod[] methods = new ResolvedJavaMethod[profileWidth]; - long[] counts = new long[profileWidth]; - long totalCount = 0; - int entries = 0; - - for (int i = 0; i < profileWidth; i++) { - HotSpotResolvedJavaMethod method = data.readMethod(position, getMethodOffset(i)); - if (method != null) { - methods[entries] = method; - long count = data.readUnsignedInt(position, getMethodCountOffset(i)); - totalCount += count; - counts[entries] = count; - - entries++; - } - } - - totalCount += getMethodsNotRecordedExecutionCount(data, position); - - // Fixup the case of C1's inability to optimize profiling of a statically bindable call - // site. If it's a monomorphic call site, attribute all the counts to the first type (if - // any is recorded). - if (entries == 1) { - counts[0] = totalCount; - } - - return new RawItemProfile<>(entries, methods, counts, totalCount); - } - - private JavaMethodProfile createMethodProfile(RawItemProfile profile) { - if (profile.entries <= 0 || profile.totalCount <= 0) { - return null; - } - - ProfiledMethod[] pmethods = new ProfiledMethod[profile.entries]; - double totalProbability = 0.0; - for (int i = 0; i < profile.entries; i++) { - double p = profile.counts[i]; - p = p / profile.totalCount; - totalProbability += p; - pmethods[i] = new ProfiledMethod(profile.items[i], p); - } - - Arrays.sort(pmethods); - - double notRecordedMethodProbability = profile.entries < config.methodProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); - assert notRecordedMethodProbability == 0 || profile.entries == config.methodProfileWidth; - return new JavaMethodProfile(notRecordedMethodProbability, pmethods); - } - - private int getMethodOffset(int row) { - return state.virtualCallDataFirstMethodOffset + row * state.typeDataRowSize; - } - - private int getMethodCountOffset(int row) { - return state.virtualCallDataFirstMethodCountOffset + row * state.typeDataRowSize; - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - RawItemProfile profile = getRawMethodProfile(data, pos); - super.appendTo(sb.append(format("exception_seen(%s) ", getExceptionSeen(data, pos))), data, pos).append(format("%nmethod_entries(%d)", profile.entries)); - for (int i = 0; i < profile.entries; i++) { - long count = profile.counts[i]; - sb.append(format("%n %s (%d, %4.2f)", profile.items[i].format("%H.%n(%p)"), count, (double) count / profile.totalCount)); - } - return sb; - } - } - - static class VirtualCallTypeData extends VirtualCallData { - - VirtualCallTypeData(VMState state, int tag) { - super(state, tag, 0); - } - - @Override - protected int getDynamicSize(HotSpotMethodData data, int position) { - assert staticSize == 0; - return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position); - } - } - - static class RetData extends CounterData { - - RetData(VMState state, int tag) { - super(state, tag, state.retDataSize); - } - } - - static class BranchData extends JumpData { - - BranchData(VMState state, int tag) { - super(state, tag, state.branchDataSize); - } - - @Override - public double getBranchTakenProbability(HotSpotMethodData data, int position) { - long takenCount = data.readUnsignedInt(position, state.takenCountOffset); - long notTakenCount = data.readUnsignedInt(position, state.notTakenCountOffset); - long total = takenCount + notTakenCount; - - return total <= 0 ? -1 : takenCount / (double) total; - } - - @Override - public int getExecutionCount(HotSpotMethodData data, int position) { - long count = data.readUnsignedInt(position, state.takenCountOffset) + data.readUnsignedInt(position, state.notTakenCountOffset); - return VMState.truncateLongToInt(count); - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - long taken = data.readUnsignedInt(pos, state.takenCountOffset); - long notTaken = data.readUnsignedInt(pos, state.notTakenCountOffset); - double takenProbability = getBranchTakenProbability(data, pos); - return sb.append(format("taken(%d, %4.2f) not_taken(%d, %4.2f) displacement(%d)", taken, takenProbability, notTaken, 1.0D - takenProbability, getTakenDisplacement(data, pos))); - } - } - - static class ArrayData extends HotSpotMethodDataAccessor { - - ArrayData(VMState state, int tag, int staticSize) { - super(state, tag, staticSize); - } - - @Override - protected int getDynamicSize(HotSpotMethodData data, int position) { - return state.cellsToBytes(getLength(data, position)); - } - - protected int getLength(HotSpotMethodData data, int position) { - return data.readInt(position, state.arrayDataLengthOffset); - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - return sb.append(format("length(%d)", getLength(data, pos))); - } - } - - static class MultiBranchData extends ArrayData { - - MultiBranchData(VMState state, int tag) { - super(state, tag, state.multiBranchDataSize); - } - - @Override - public double[] getSwitchProbabilities(HotSpotMethodData data, int position) { - int arrayLength = getLength(data, position); - assert arrayLength > 0 : "switch must have at least the default case"; - assert arrayLength % state.multiBranchDataRowSizeInCells == 0 : "array must have full rows"; - - int length = arrayLength / state.multiBranchDataRowSizeInCells; - long totalCount = 0; - double[] result = new double[length]; - - // default case is first in HotSpot but last for the compiler - long count = readCount(data, position, 0); - totalCount += count; - result[length - 1] = count; - - for (int i = 1; i < length; i++) { - count = readCount(data, position, i); - totalCount += count; - result[i - 1] = count; - } - - if (totalCount <= 0) { - return null; - } else { - for (int i = 0; i < length; i++) { - result[i] = result[i] / totalCount; - } - return result; - } - } - - private long readCount(HotSpotMethodData data, int position, int i) { - int offset; - long count; - offset = getCountOffset(i); - count = data.readUnsignedInt(position, offset); - return count; - } - - @Override - public int getExecutionCount(HotSpotMethodData data, int position) { - int arrayLength = getLength(data, position); - assert arrayLength > 0 : "switch must have at least the default case"; - assert arrayLength % state.multiBranchDataRowSizeInCells == 0 : "array must have full rows"; - - int length = arrayLength / state.multiBranchDataRowSizeInCells; - long totalCount = 0; - for (int i = 0; i < length; i++) { - int offset = getCountOffset(i); - totalCount += data.readUnsignedInt(position, offset); - } - - return VMState.truncateLongToInt(totalCount); - } - - private int getCountOffset(int index) { - return state.multiBranchDataFirstCountOffset + index * state.multiBranchDataRowSize; - } - - private int getDisplacementOffset(int index) { - return state.multiBranchDataFirstDisplacementOffset + index * state.multiBranchDataRowSize; - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - int entries = getLength(data, pos) / state.multiBranchDataRowSizeInCells; - sb.append(format("entries(%d)", entries)); - for (int i = 0; i < entries; i++) { - sb.append(format("%n %d: count(%d) displacement(%d)", i, data.readUnsignedInt(pos, getCountOffset(i)), data.readUnsignedInt(pos, getDisplacementOffset(i)))); - } - return sb; - } - } - - static class ArgInfoData extends ArrayData { - - ArgInfoData(VMState state, int tag) { - super(state, tag, state.argInfoDataSize); - } - } - - static class UnknownProfileData extends HotSpotMethodDataAccessor { - UnknownProfileData(VMState state, int tag) { - super(state, tag, 0); - } - - @Override - protected int getDynamicSize(HotSpotMethodData data, int position) { - assert staticSize == 0; - return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position); - } - - @Override - public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { - sb.append("unknown profile data with tag: " + tag); - return sb; - } - } - - public void setCompiledIRSize(int size) { - UNSAFE.putInt(metaspaceMethodData + state.config.methodDataIRSizeOffset, size); - } - - public int getCompiledIRSize() { - return UNSAFE.getInt(metaspaceMethodData + state.config.methodDataIRSizeOffset); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import java.lang.invoke.MethodHandle; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.vm.ci.hotspot.HotSpotMethodData.VMState; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.MethodHandleAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider { - - private final ConstantReflectionProvider constantReflection; - - public HotSpotMethodHandleAccessProvider(ConstantReflectionProvider constantReflection) { - this.constantReflection = constantReflection; - } - - /** - * Lazy initialized reflection on {@link MethodHandle} internals. Field and method lookup is - * only possible after the {@link HotSpotJVMCIRuntime} is fully initialized. - */ - static final class Internals { - final ResolvedJavaType lambdaFormType; - final ResolvedJavaField methodHandleFormField; - final ResolvedJavaField lambdaFormVmentryField; - final HotSpotResolvedJavaField callSiteTargetField; - final HotSpotResolvedJavaField constantCallSiteFrozenField; - final ResolvedJavaField methodField; - final HotSpotResolvedJavaField vmtargetField; - - /** - * Search for an instance field with the given name in a class. - * - * @param declaringType the type declaring the field - * @param fieldName name of the field to be searched - * @param fieldType resolved Java type of the field - * @return resolved Java field - * @throws NoSuchFieldError - */ - private static ResolvedJavaField findFieldInClass(ResolvedJavaType declaringType, String fieldName, ResolvedJavaType fieldType) { - ResolvedJavaField[] fields = declaringType.getInstanceFields(false); - for (ResolvedJavaField field : fields) { - if (field.getName().equals(fieldName) && field.getType().equals(fieldType)) { - return field; - } - } - throw new NoSuchFieldError(declaringType + "." + fieldName); - } - - private static ResolvedJavaType resolveType(String className) { - return (ResolvedJavaType) runtime().lookupTypeInternal(className, null, true); - } - - private Internals() { - try { - ResolvedJavaType methodHandleType = resolveType("Ljava/lang/invoke/MethodHandle;"); - ResolvedJavaType memberNameType = resolveType("Ljava/lang/invoke/MemberName;"); - lambdaFormType = resolveType("Ljava/lang/invoke/LambdaForm;"); - methodHandleFormField = findFieldInClass(methodHandleType, "form", lambdaFormType); - lambdaFormVmentryField = findFieldInClass(lambdaFormType, "vmentry", memberNameType); - - ResolvedJavaType methodType = resolveType("Ljava/lang/invoke/ResolvedMethodName;"); - methodField = findFieldInClass(memberNameType, "method", methodType); - vmtargetField = (HotSpotResolvedJavaField) findFieldInClass(methodType, "vmtarget", resolveType(Character.toString(HotSpotJVMCIRuntime.getHostWordKind().getTypeChar()))); - - ResolvedJavaType callSiteType = resolveType("Ljava/lang/invoke/CallSite;"); - callSiteTargetField = (HotSpotResolvedJavaField) findFieldInClass(callSiteType, "target", methodHandleType); - ResolvedJavaType constantCallSiteType = resolveType("Ljava/lang/invoke/ConstantCallSite;"); - ResolvedJavaType booleanType = resolveType("Z"); - constantCallSiteFrozenField = (HotSpotResolvedJavaField) findFieldInClass(constantCallSiteType, "isFrozen", booleanType); - } catch (Throwable ex) { - throw new JVMCIError(ex); - } - } - - /** - * Singleton instance lazily initialized via double-checked locking. - */ - @NativeImageReinitialize private static volatile Internals instance; - - static Internals instance() { - Internals result = instance; - if (result == null) { - synchronized (VMState.class) { - result = instance; - if (result == null) { - instance = result = new Internals(); - } - } - } - return result; - } - - } - - - @Override - public IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method) { - int intrinsicId = ((HotSpotResolvedJavaMethodImpl) method).intrinsicId(); - if (intrinsicId != 0) { - return getMethodHandleIntrinsic(intrinsicId); - } - return null; - } - - public static IntrinsicMethod getMethodHandleIntrinsic(int intrinsicId) { - HotSpotVMConfig config = runtime().getConfig(); - if (intrinsicId == config.vmIntrinsicInvokeBasic) { - return IntrinsicMethod.INVOKE_BASIC; - } else if (intrinsicId == config.vmIntrinsicLinkToInterface) { - return IntrinsicMethod.LINK_TO_INTERFACE; - } else if (intrinsicId == config.vmIntrinsicLinkToSpecial) { - return IntrinsicMethod.LINK_TO_SPECIAL; - } else if (intrinsicId == config.vmIntrinsicLinkToStatic) { - return IntrinsicMethod.LINK_TO_STATIC; - } else if (intrinsicId == config.vmIntrinsicLinkToVirtual) { - return IntrinsicMethod.LINK_TO_VIRTUAL; - } - return null; - } - - @Override - public ResolvedJavaMethod resolveInvokeBasicTarget(JavaConstant methodHandle, boolean forceBytecodeGeneration) { - if (methodHandle.isNull()) { - return null; - } - - /* Load non-public field: LambdaForm MethodHandle.form */ - Internals internals = Internals.instance(); - JavaConstant lambdaForm = constantReflection.readFieldValue(internals.methodHandleFormField, methodHandle); - if (lambdaForm == null || lambdaForm.isNull()) { - return null; - } - - JavaConstant memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm); - if (memberName.isNull() && forceBytecodeGeneration) { - compilerToVM().compileToBytecode((HotSpotObjectConstantImpl) lambdaForm); - memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm); - assert memberName.isNonNull(); - } - JavaConstant method = constantReflection.readFieldValue(internals.methodField, memberName); - return getTargetMethod(method); - } - - @Override - public ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName) { - if (memberName.isNull()) { - return null; - } - JavaConstant method = constantReflection.readFieldValue(Internals.instance().methodField, memberName); - return getTargetMethod(method); - } - - /** - * Returns the {@link ResolvedJavaMethod} for the method of a java.lang.invoke.MemberName. - */ - private static ResolvedJavaMethod getTargetMethod(JavaConstant method) { - if (method == null) { - // If readFieldValue returns NULL the type was wrong - throw new IllegalArgumentException("unexpected type for memberName"); - } - - /* Read the ResolvedJavaMethod from the injected field MemberName.method.vmtarget */ - return compilerToVM().getResolvedJavaMethod((HotSpotObjectConstantImpl) method, Internals.instance().vmtargetField.getOffset()); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static java.util.FormattableFlags.ALTERNATE; -import static java.util.FormattableFlags.LEFT_JUSTIFY; -import static java.util.FormattableFlags.UPPERCASE; - -import java.util.Formattable; -import java.util.Formatter; - -import jdk.vm.ci.meta.JavaMethod; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -abstract class HotSpotMethod implements JavaMethod, Formattable { - - public static String applyFormattingFlagsAndWidth(String s, int flags, int width) { - if (flags == 0 && width < 0) { - return s; - } - StringBuilder sb = new StringBuilder(s); - - // apply width and justification - int len = sb.length(); - if (len < width) { - for (int i = 0; i < width - len; i++) { - if ((flags & LEFT_JUSTIFY) == LEFT_JUSTIFY) { - sb.append(' '); - } else { - sb.insert(0, ' '); - } - } - } - - String res = sb.toString(); - if ((flags & UPPERCASE) == UPPERCASE) { - res = res.toUpperCase(); - } - return res; - } - - /** - * Controls whether {@link #toString()} includes the qualified or simple name of the class in - * which the method is declared. - */ - public static final boolean FULLY_QUALIFIED_METHOD_NAME = false; - - @Override - public final String toString() { - char h = FULLY_QUALIFIED_METHOD_NAME ? 'H' : 'h'; - String suffix = this instanceof ResolvedJavaMethod ? "" : ", unresolved"; - String fmt = String.format("HotSpotMethod<%%%c.%%n(%%p)%s>", h, suffix); - return format(fmt); - } - - @Override - public void formatTo(Formatter formatter, int flags, int width, int precision) { - String base = (flags & ALTERNATE) == ALTERNATE ? getName() : toString(); - formatter.format(applyFormattingFlagsAndWidth(base, flags & ~ALTERNATE, width)); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static java.lang.reflect.Modifier.ABSTRACT; -import static java.lang.reflect.Modifier.FINAL; -import static java.lang.reflect.Modifier.INTERFACE; -import static java.lang.reflect.Modifier.NATIVE; -import static java.lang.reflect.Modifier.PRIVATE; -import static java.lang.reflect.Modifier.PROTECTED; -import static java.lang.reflect.Modifier.PUBLIC; -import static java.lang.reflect.Modifier.STATIC; -import static java.lang.reflect.Modifier.STRICT; -import static java.lang.reflect.Modifier.SYNCHRONIZED; -import static java.lang.reflect.Modifier.TRANSIENT; -import static java.lang.reflect.Modifier.VOLATILE; -import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; - -import java.lang.reflect.Modifier; - -/** - * The non-public modifiers in {@link Modifier} that need to be retrieved from - * {@link HotSpotVMConfig}. - */ -public class HotSpotModifiers { - - // @formatter:off - public static final int ANNOTATION = config().jvmAccAnnotation; - public static final int ENUM = config().jvmAccEnum; - public static final int VARARGS = config().jvmAccVarargs; - public static final int BRIDGE = config().jvmAccBridge; - public static final int SYNTHETIC = config().jvmAccSynthetic; - // @formatter:on - - public static int jvmClassModifiers() { - return PUBLIC | FINAL | INTERFACE | ABSTRACT | ANNOTATION | ENUM | SYNTHETIC; - } - - public static int jvmMethodModifiers() { - return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | BRIDGE | VARARGS | NATIVE | ABSTRACT | STRICT | SYNTHETIC; - } - - public static int jvmFieldModifiers() { - return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | ENUM | SYNTHETIC; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; -import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; - -import jdk.vm.ci.code.InstalledCode; -import jdk.vm.ci.code.InvalidInstalledCodeException; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * Implementation of {@link InstalledCode} for code installed as an {@code nmethod}. The address of - * the {@code nmethod} is stored in {@link InstalledCode#address} and the value of - * {@code nmethod::verified_entry_point()} is in {@link InstalledCode#entryPoint}. - */ -public class HotSpotNmethod extends HotSpotInstalledCode { - - /** - * This (indirect) {@code Method*} reference is safe since class redefinition preserves all - * methods associated with nmethods in the code cache. - */ - private final HotSpotResolvedJavaMethodImpl method; - - /** - * Specifies whether the {@code nmethod} associated with this object is the code executed by - * default HotSpot linkage when a normal Java call to {@link #method} is made. That is, does - * {@code this.method.metadataHandle->_code} == {@code this.address}. If not, then the - * {@code nmethod} can only be invoked via a reference to this object. An example of this is the - * trampoline mechanism used by Truffle: https://goo.gl/LX88rZ. - */ - private final boolean isDefault; - - /** - * Determines whether this object is in the oops table of the nmethod. - *

    - * If this object is in the oops table, the VM uses the oops table entry to update this object's - * {@link #address} and {@link #entryPoint} fields when the state of the nmethod changes. The - * nmethod will be unloadable when this object dies. - *

    - * Otherwise, the nmethod's unloadability is not changed when this object dies. - */ - boolean inOopsTable() { - return compileIdSnapshot != 0; - } - - /** - * If this field is 0, this object is in the oops table of the nmethod. Otherwise, the value of - * the field records the nmethod's compile identifier. This value is used to confirm if an entry - * in the code cache retrieved by {@link #address} is indeed the nmethod represented by this - * object. - * - * @see #inOopsTable - */ - private final long compileIdSnapshot; - - HotSpotNmethod(HotSpotResolvedJavaMethodImpl method, String name, boolean isDefault, long compileId) { - super(name); - this.method = method; - this.isDefault = isDefault; - boolean inOopsTable = !IS_IN_NATIVE_IMAGE && !isDefault; - this.compileIdSnapshot = inOopsTable ? 0L : compileId; - assert inOopsTable || compileId != 0L : this; - } - - /** - * Attaches {@code log} to this object. If {@code log.managesFailedSpeculations() == true}, this - * ensures the failed speculation list lives at least as long as this object. - */ - public void setSpeculationLog(HotSpotSpeculationLog log) { - this.speculationLog = log; - } - - /** - * The speculation log containing speculations embedded in the nmethod. - * - * If {@code speculationLog.managesFailedSpeculations() == true}, this field ensures the failed - * speculation list lives at least as long as this object. This prevents deoptimization from - * appending to an already freed list. - */ - @SuppressWarnings("unused") private HotSpotSpeculationLog speculationLog; - - /** - * Determines if the nmethod associated with this object is the compiled entry point for - * {@link #getMethod()}. - */ - public boolean isDefault() { - return isDefault; - } - - @Override - public boolean isValid() { - if (compileIdSnapshot != 0L) { - compilerToVM().updateHotSpotNmethod(this); - } - return super.isValid(); - } - - public ResolvedJavaMethod getMethod() { - return method; - } - - @Override - public void invalidate() { - compilerToVM().invalidateHotSpotNmethod(this); - } - - @Override - public long getAddress() { - if (compileIdSnapshot != 0L) { - compilerToVM().updateHotSpotNmethod(this); - } - return super.getAddress(); - } - - @Override - public long getEntryPoint() { - if (compileIdSnapshot != 0L) { - return 0; - } - return super.getEntryPoint(); - } - - @Override - public String toString() { - return String.format("HotSpotNmethod[method=%s, codeBlob=0x%x, isDefault=%b, name=%s, inOopsTable=%s]", - method, getAddress(), isDefault, name, inOopsTable()); - } - - private boolean checkArgs(Object... args) { - JavaType[] sig = method.toParameterTypes(); - assert args.length == sig.length : method.format("%H.%n(%p): expected ") + sig.length + " args, got " + args.length; - for (int i = 0; i < sig.length; i++) { - Object arg = args[i]; - if (arg == null) { - assert sig[i].getJavaKind() == JavaKind.Object : method.format("%H.%n(%p): expected arg ") + i + " to be Object, not " + sig[i]; - } else if (sig[i].getJavaKind() != JavaKind.Object) { - assert sig[i].getJavaKind().toBoxedJavaClass() == arg.getClass() : method.format("%H.%n(%p): expected arg ") + i + " to be " + sig[i] + ", not " + arg.getClass(); - } - } - return true; - } - - /** - * {@inheritDoc} - * - * It's possible for the HotSpot runtime to sweep nmethods at any point in time. As a result, - * there is no guarantee that calling this method will execute the wrapped nmethod. Instead, it - * may end up executing the bytecode of the associated {@link #getMethod() Java method}. Only if - * {@link #isValid()} is {@code true} after returning can the caller be sure that the nmethod - * was executed. If {@link #isValid()} is {@code false}, then the only way to determine if the - * nmethod was executed is to test for some side-effect specific to the nmethod (e.g., update to - * a field) that is not performed by the bytecode of the associated {@link #getMethod() Java - * method}. - */ - @Override - public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { - if (IS_IN_NATIVE_IMAGE) { - throw new HotSpotJVMCIUnsupportedOperationError("Cannot execute nmethod via mirror in native image"); - } - assert checkArgs(args); - return compilerToVM().executeHotSpotNmethod(args, this); - } - - @Override - public long getStart() { - return isValid() ? super.getStart() : 0; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; - -import jdk.vm.ci.meta.Assumptions; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * Represents a constant non-{@code null} object reference, within the compiler and across the - * compiler/runtime interface. - */ -abstract class HotSpotObjectConstantImpl implements HotSpotObjectConstant { - - protected final boolean compressed; - - HotSpotObjectConstantImpl(boolean compressed) { - this.compressed = compressed; - } - - @Override - public JavaKind getJavaKind() { - return JavaKind.Object; - } - - @Override - public boolean isCompressed() { - return compressed; - } - - @Override - public abstract JavaConstant compress(); - - @Override - public abstract JavaConstant uncompress(); - - @Override - public HotSpotResolvedObjectType getType() { - return runtime().reflection.getType(this); - } - - @Override - public abstract int getIdentityHashCode(); - - private boolean isFullyInitializedConstantCallSite() { - if (!runtime().getConstantCallSite().isInstance(this)) { - return false; - } - // read ConstantCallSite.isFrozen as a volatile field - HotSpotResolvedJavaField field = HotSpotMethodHandleAccessProvider.Internals.instance().constantCallSiteFrozenField; - boolean isFrozen = readFieldValue(field).asBoolean(); - // isFrozen true implies fully-initialized - return isFrozen; - } - - private HotSpotObjectConstantImpl readTarget() { - // read CallSite.target as a volatile field - HotSpotResolvedJavaField field = HotSpotMethodHandleAccessProvider.Internals.instance().callSiteTargetField; - return (HotSpotObjectConstantImpl) readFieldValue(field); - } - - @Override - public JavaConstant getCallSiteTarget(Assumptions assumptions) { - if (runtime().getCallSite().isInstance(this)) { - // For ConstantCallSites, we need to read "isFrozen" before reading "target" - // isFullyInitializedConstantCallSite() reads "isFrozen" - if (!isFullyInitializedConstantCallSite()) { - if (assumptions == null) { - return null; - } - assumptions.record(new Assumptions.CallSiteTargetValue(this, readTarget())); - } - return readTarget(); - } - return null; - } - - @Override - public boolean isInternedString() { - return runtime().compilerToVm.isInternedString(this); - } - - @Override - public T asObject(Class type) { - return runtime().reflection.asObject(this, type); - } - - @Override - public Object asObject(ResolvedJavaType type) { - return runtime().reflection.asObject(this, (HotSpotResolvedJavaType) type); - } - - @Override - public boolean isNull() { - return false; - } - - @Override - public boolean isDefaultForKind() { - return false; - } - - @Override - public Object asBoxedPrimitive() { - throw new IllegalArgumentException(); - } - - @Override - public int asInt() { - throw new IllegalArgumentException(); - } - - @Override - public boolean asBoolean() { - throw new IllegalArgumentException(); - } - - @Override - public long asLong() { - throw new IllegalArgumentException(); - } - - @Override - public float asFloat() { - throw new IllegalArgumentException(); - } - - @Override - public double asDouble() { - throw new IllegalArgumentException(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof HotSpotObjectConstantImpl) { - HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o; - return runtime().reflection.equals(this, other); - } - return false; - } - - @Override - public int hashCode() { - return getIdentityHashCode(); - } - - @Override - public String toValueString() { - if (runtime().getJavaLangString().isInstance(this)) { - return "\"" + runtime().reflection.asString(this) + "\""; - } else { - return runtime().reflection.formatString(this); - } - } - - @Override - public String toString() { - return (compressed ? "NarrowOop" : getJavaKind().getJavaName()) + "[" + runtime().reflection.formatString(this) + "]"; - } - - public JavaConstant readFieldValue(HotSpotResolvedJavaField field) { - if (IS_IN_NATIVE_IMAGE && this instanceof DirectHotSpotObjectConstantImpl) { - // cannot read fields from objects due to lack of - // general reflection support in native image - return null; - } - if (field.isStatic()) { - return null; - } - return runtime().compilerToVm.readFieldValue(this, (HotSpotResolvedObjectTypeImpl) field.getDeclaringClass(), field.getOffset(), field.getType().getJavaKind()); - } - - public ResolvedJavaType asJavaType() { - return runtime().reflection.asJavaType(this); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.hotspot; - -import java.lang.invoke.CallSite; -import java.util.Objects; - -import jdk.vm.ci.meta.Assumptions; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.VMConstant; - -/** - * Represents a constant non-{@code null} object reference, within the compiler and across the - * compiler/runtime interface. - */ -public interface HotSpotObjectConstant extends JavaConstant, HotSpotConstant, VMConstant { - - @Override - JavaConstant compress(); - - @Override - JavaConstant uncompress(); - - /** - * Gets the resolved Java type of the object represented by this constant. - */ - HotSpotResolvedObjectType getType(); - - /** - * Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object - * represented by this constant. - */ - int getIdentityHashCode(); - - /** - * Gets the result of {@link CallSite#getTarget()} for the {@link CallSite} object represented - * by this constant. - * - * @param assumptions used to register an assumption that the {@link CallSite}'s target does not - * change - * @return {@code null} if this constant does not represent a {@link CallSite} object - */ - JavaConstant getCallSiteTarget(Assumptions assumptions); - - /** - * Determines if this constant represents an {@linkplain String#intern() interned} string. - */ - boolean isInternedString(); - - /** - * Gets the object represented by this constant represents if it is of a given type. - * - * @param type the expected type of the object represented by this constant. If the object is - * required to be of this type, then wrap the call to this method in - * {@link Objects#requireNonNull(Object)}. - * @return the object value represented by this constant if it is an - * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise - * {@code null} - */ - T asObject(Class type); - - /** - * Gets the object represented by this constant represents if it is of a given type. - * - * @param type the expected type of the object represented by this constant. If the object is - * required to be of this type, then wrap the call to this method in - * {@link Objects#requireNonNull(Object)}. - * @return the object value represented by this constant if it is an - * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise - * {@code null} - */ - Object asObject(ResolvedJavaType type); - - @Override - String toValueString(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import jdk.vm.ci.services.Services; - -/** - * A mechanism for limiting the lifetime of a foreign object reference encapsulated in a - * {@link HotSpotObjectConstant}. - * - * A {@link HotSpotObjectConstant} allocated in a {@linkplain #openLocalScope local} scope will have - * its reference to any foreign object cleared when the scope {@linkplain #close() closes}. This - * allows the foreign memory manager to reclaim the foreign object (once there are no other strong - * references to it). - * - * {@link HotSpotObjectConstantScope}s have no impact on {@link HotSpotObjectConstant}s that do not - * encapsulate a foreign object reference. - * - * The object returned by {@link #enterGlobalScope()} or {@link #openLocalScope(Object)} should - * always be used in a try-with-resources statement. Failure to close a scope will almost certainly - * result in foreign objects being leaked. - */ -public final class HotSpotObjectConstantScope implements AutoCloseable { - static final ThreadLocal CURRENT = new ThreadLocal<>(); - - private final HotSpotObjectConstantScope parent; - private List foreignObjects; - - /** - * An object whose {@link Object#toString()} value describes a non-global scope. This is - * {@code null} iff this is a global scope. - */ - final Object localScopeDescription; - - /** - * Opens a local scope that upon closing, will release foreign object references encapsulated by - * {@link HotSpotObjectConstant}s created in the scope. - * - * @param description an non-null object whose {@link Object#toString()} value describes the - * scope being opened - * @return {@code null} if the current runtime does not support remote object references - */ - public static HotSpotObjectConstantScope openLocalScope(Object description) { - return Services.IS_IN_NATIVE_IMAGE ? new HotSpotObjectConstantScope(Objects.requireNonNull(description)) : null; - } - - /** - * Enters the global scope. This is useful to escape a local scope for execution that will - * create foreign object references that need to outlive the local scope. - * - * Foreign object references encapsulated by {@link HotSpotObjectConstant}s created in the - * global scope are only subject to reclamation once the {@link HotSpotObjectConstant} wrapper - * dies. - * - * @return {@code null} if the current runtime does not support remote object references or if - * this thread is currently in the global scope - */ - public static HotSpotObjectConstantScope enterGlobalScope() { - return Services.IS_IN_NATIVE_IMAGE && CURRENT.get() != null ? new HotSpotObjectConstantScope(null) : null; - } - - private HotSpotObjectConstantScope(Object localScopeDescription) { - this.parent = CURRENT.get(); - CURRENT.set(this); - this.localScopeDescription = localScopeDescription; - } - - /** - * Determines if this scope is global. - */ - boolean isGlobal() { - return localScopeDescription == null; - } - - void add(IndirectHotSpotObjectConstantImpl obj) { - assert !isGlobal(); - if (foreignObjects == null) { - foreignObjects = new ArrayList<>(); - } - foreignObjects.add(obj); - } - - @VMEntryPoint - @Override - public void close() { - if (CURRENT.get() != this) { - throw new IllegalStateException("Cannot close non-active scope"); - } - if (foreignObjects != null) { - for (IndirectHotSpotObjectConstantImpl obj : foreignObjects) { - obj.clear(localScopeDescription); - } - foreignObjects = null; - } - CURRENT.set(parent); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.DeoptimizationReason; -import jdk.vm.ci.meta.JavaMethodProfile; -import jdk.vm.ci.meta.JavaTypeProfile; -import jdk.vm.ci.meta.ProfilingInfo; -import jdk.vm.ci.meta.TriState; - -final class HotSpotProfilingInfo implements ProfilingInfo { - - private final HotSpotMethodData methodData; - private final HotSpotResolvedJavaMethod method; - - private boolean isMature; - private int position; - private int hintPosition; - private int hintBCI; - private HotSpotMethodDataAccessor dataAccessor; - - private boolean includeNormal; - private boolean includeOSR; - - HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) { - this.methodData = methodData; - this.method = method; - if (!method.getDeclaringClass().isLinked()) { - throw new IllegalArgumentException(method.format("%H.%n(%p) must be linked")); - } - this.includeNormal = includeNormal; - this.includeOSR = includeOSR; - this.isMature = methodData.isProfileMature(); - hintPosition = 0; - hintBCI = -1; - } - - @Override - public int getCodeSize() { - return method.getCodeSize(); - } - - public int getDecompileCount() { - return methodData.getDecompileCount(); - } - - public int getOverflowRecompileCount() { - return methodData.getOverflowRecompileCount(); - } - - public int getOverflowTrapCount() { - return methodData.getOverflowTrapCount(); - } - - @Override - public JavaTypeProfile getTypeProfile(int bci) { - if (!isMature) { - return null; - } - findBCI(bci, false); - return dataAccessor.getTypeProfile(methodData, position); - } - - @Override - public JavaMethodProfile getMethodProfile(int bci) { - if (!isMature) { - return null; - } - findBCI(bci, false); - return dataAccessor.getMethodProfile(methodData, position); - } - - @Override - public double getBranchTakenProbability(int bci) { - if (!isMature) { - return -1; - } - findBCI(bci, false); - return dataAccessor.getBranchTakenProbability(methodData, position); - } - - @Override - public double[] getSwitchProbabilities(int bci) { - if (!isMature) { - return null; - } - findBCI(bci, false); - return dataAccessor.getSwitchProbabilities(methodData, position); - } - - @Override - public TriState getExceptionSeen(int bci) { - findBCI(bci, true); - return dataAccessor.getExceptionSeen(methodData, position); - } - - @Override - public TriState getNullSeen(int bci) { - findBCI(bci, false); - return dataAccessor.getNullSeen(methodData, position); - } - - @Override - public int getExecutionCount(int bci) { - if (!isMature) { - return -1; - } - findBCI(bci, false); - return dataAccessor.getExecutionCount(methodData, position); - } - - @Override - public int getDeoptimizationCount(DeoptimizationReason reason) { - int count = 0; - if (includeNormal) { - count += methodData.getDeoptimizationCount(reason); - } - if (includeOSR) { - count += methodData.getOSRDeoptimizationCount(reason); - } - return count; - } - - private void findBCI(int targetBCI, boolean searchExtraData) { - assert targetBCI >= 0 : "invalid BCI"; - - if (methodData.hasNormalData()) { - int currentPosition = targetBCI < hintBCI ? 0 : hintPosition; - HotSpotMethodDataAccessor currentAccessor; - while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) { - int currentBCI = currentAccessor.getBCI(methodData, currentPosition); - if (currentBCI == targetBCI) { - normalDataFound(currentAccessor, currentPosition, currentBCI); - return; - } else if (currentBCI > targetBCI) { - break; - } - currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); - } - } - - boolean exceptionPossiblyNotRecorded = false; - if (searchExtraData && methodData.hasExtraData()) { - int currentPosition = methodData.getExtraDataBeginOffset(); - HotSpotMethodDataAccessor currentAccessor; - while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) { - int currentBCI = currentAccessor.getBCI(methodData, currentPosition); - if (currentBCI == targetBCI) { - extraDataFound(currentAccessor, currentPosition); - return; - } - currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); - } - - if (!methodData.isWithin(currentPosition)) { - exceptionPossiblyNotRecorded = true; - } - } - - noDataFound(exceptionPossiblyNotRecorded); - } - - private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) { - setCurrentData(data, pos); - this.hintPosition = position; - this.hintBCI = bci; - } - - private void extraDataFound(HotSpotMethodDataAccessor data, int pos) { - setCurrentData(data, pos); - } - - private void noDataFound(boolean exceptionPossiblyNotRecorded) { - HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded); - setCurrentData(accessor, -1); - } - - private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) { - this.dataAccessor = dataAccessor; - this.position = position; - } - - @Override - public boolean isMature() { - return isMature; - } - - public void ignoreMature() { - isMature = true; - } - - @Override - public String toString() { - return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">"; - } - - @Override - public void setMature() { - isMature = true; - } - - /** - * {@code MethodData::_jvmci_ir_size} (currently) supports at most one JVMCI compiler IR type - * which will be determined by the first JVMCI compiler that calls - * {@link #setCompilerIRSize(Class, int)}. - */ - private static volatile Class supportedCompilerIRType; - - @Override - public boolean setCompilerIRSize(Class irType, int size) { - if (supportedCompilerIRType == null) { - synchronized (HotSpotProfilingInfo.class) { - if (supportedCompilerIRType == null) { - supportedCompilerIRType = irType; - } - } - } - if (supportedCompilerIRType != irType) { - return false; - } - methodData.setCompiledIRSize(size); - return true; - } - - @Override - public int getCompilerIRSize(Class irType) { - if (irType == supportedCompilerIRType) { - return methodData.getCompiledIRSize(); - } - return -1; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.hotspot; - -import java.util.Arrays; - -import jdk.vm.ci.code.Location; -import jdk.vm.ci.code.ReferenceMap; - -/** - * Describes where the object references are in machine state, compliant with what HotSpot expects. - */ -public final class HotSpotReferenceMap extends ReferenceMap { - - private final Location[] objects; - private final Location[] derivedBase; - private final int[] sizeInBytes; - private final int maxRegisterSize; - - /** - * - * @param objects This array is now owned by this object and must not be mutated by the caller. - * @param derivedBase This array is now owned by this object and must not be mutated by the - * caller. - * @param sizeInBytes This array is now owned by this object and must not be mutated by the - * caller. - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `objects`, `derivedBase` and `sizeInBytes`") - public HotSpotReferenceMap(Location[] objects, Location[] derivedBase, int[] sizeInBytes, int maxRegisterSize) { - this.objects = objects; - this.derivedBase = derivedBase; - this.sizeInBytes = sizeInBytes; - this.maxRegisterSize = maxRegisterSize; - } - - @Override - public int hashCode() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof HotSpotReferenceMap) { - HotSpotReferenceMap that = (HotSpotReferenceMap) obj; - if (sizeInBytes == that.sizeInBytes && maxRegisterSize == that.maxRegisterSize && Arrays.equals(objects, that.objects) && Arrays.equals(derivedBase, that.derivedBase)) { - return true; - } - } - return false; - } - - @Override - public String toString() { - return Arrays.toString(objects); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.internal.misc.Unsafe.ADDRESS_SIZE; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import java.lang.annotation.Annotation; - -import jdk.internal.vm.annotation.Stable; - -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.UnresolvedJavaType; - -/** - * Represents a field in a HotSpot type. - */ -class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField { - - private final HotSpotResolvedObjectTypeImpl holder; - private JavaType type; - - /** - * Offset (in bytes) of field from start of its storage container (i.e. {@code instanceOop} or - * {@code Klass*}). - */ - private final int offset; - - /** - * Value of {@code fieldDescriptor::index()}. - */ - private final int index; - - /** - * This value contains all flags as stored in the VM including internal ones. - */ - private final int modifiers; - - HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, JavaType type, int offset, int modifiers, int index) { - this.holder = holder; - this.type = type; - this.index = index; - this.offset = offset; - this.modifiers = modifiers; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof HotSpotResolvedJavaFieldImpl) { - HotSpotResolvedJavaFieldImpl that = (HotSpotResolvedJavaFieldImpl) obj; - if (that.offset != this.offset || that.isStatic() != this.isStatic()) { - return false; - } else if (this.holder.equals(that.holder)) { - return true; - } - } - return false; - } - - @Override - public int hashCode() { - return holder.hashCode() ^ offset; - } - - @Override - public int getModifiers() { - return modifiers & HotSpotModifiers.jvmFieldModifiers(); - } - - @Override - public boolean isInternal() { - return (modifiers & config().jvmAccFieldInternal) != 0; - } - - /** - * Determines if a given object contains this field. - * - * @return true iff this is a non-static field and its declaring class is assignable from - * {@code object}'s class - */ - @Override - public boolean isInObject(JavaConstant object) { - if (isStatic()) { - return false; - } - HotSpotObjectConstant constant = (HotSpotObjectConstant) object; - return getDeclaringClass().isAssignableFrom(constant.getType()); - } - - @Override - public HotSpotResolvedObjectTypeImpl getDeclaringClass() { - return holder; - } - - @Override - public String getName() { - return holder.createFieldInfo(index).getName(); - } - - @Override - public JavaType getType() { - // Pull field into local variable to prevent a race causing - // a ClassCastException below - JavaType currentType = type; - if (currentType instanceof UnresolvedJavaType) { - // Don't allow unresolved types to hang around forever - UnresolvedJavaType unresolvedType = (UnresolvedJavaType) currentType; - JavaType resolved = HotSpotJVMCIRuntime.runtime().lookupType(unresolvedType.getName(), holder, false); - if (resolved instanceof ResolvedJavaType) { - type = resolved; - } - } - return type; - - } - - /** - * Gets the offset (in bytes) of field from start of its storage container (i.e. - * {@code instanceOop} or {@code Klass*}). - */ - @Override - public int getOffset() { - return offset; - } - - /** - * Gets the value of this field's index (i.e. {@code fieldDescriptor::index()} in the encoded - * fields of the declaring class. - */ - int getIndex() { - return index; - } - - @Override - public String toString() { - return format("HotSpotResolvedJavaFieldImpl<%H.%n %t:") + offset + ">"; - } - - @Override - public boolean isSynthetic() { - return (config().jvmAccSynthetic & modifiers) != 0; - } - - /** - * Checks if this field has the {@code Stable} annotation. - * - * @return true if field has {@code Stable} annotation, false otherwise - */ - @Override - public boolean isStable() { - return (config().jvmAccFieldStable & modifiers) != 0; - } - - private boolean hasAnnotations() { - if (!isInternal()) { - HotSpotVMConfig config = config(); - final long metaspaceAnnotations = UNSAFE.getAddress(holder.getMetaspaceKlass() + config.instanceKlassAnnotationsOffset); - if (metaspaceAnnotations != 0) { - long fieldsAnnotations = UNSAFE.getAddress(metaspaceAnnotations + config.annotationsFieldAnnotationsOffset); - if (fieldsAnnotations != 0) { - long fieldAnnotations = UNSAFE.getAddress(fieldsAnnotations + config.fieldsAnnotationsBaseOffset + (ADDRESS_SIZE * index)); - return fieldAnnotations != 0; - } - } - } - return false; - } - - @Override - public Annotation[] getAnnotations() { - if (!hasAnnotations()) { - return new Annotation[0]; - } - return runtime().reflection.getFieldAnnotations(this); - } - - @Override - public Annotation[] getDeclaredAnnotations() { - if (!hasAnnotations()) { - return new Annotation[0]; - } - return runtime().reflection.getFieldDeclaredAnnotations(this); - } - - @Override - public T getAnnotation(Class annotationClass) { - if (!hasAnnotations()) { - return null; - } - return runtime().reflection.getFieldAnnotation(this, annotationClass); - } - - @Override - public JavaConstant getConstantValue() { - return holder.createFieldInfo(index).getConstantValue(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.ResolvedJavaField; - -/** - * Represents a field in a HotSpot type. - */ -public interface HotSpotResolvedJavaField extends ResolvedJavaField { - - /** - * Determines if a given object contains this field. - * - * @return true iff this is a non-static field and its declaring class is assignable from - * {@code object}'s class - */ - boolean isInObject(JavaConstant object); - - /** - * Determines if this field should be treated as a constant. - */ - boolean isStable(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,753 +0,0 @@ -/* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.HotSpotModifiers.BRIDGE; -import static jdk.vm.ci.hotspot.HotSpotModifiers.SYNTHETIC; -import static jdk.vm.ci.hotspot.HotSpotModifiers.VARARGS; -import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmMethodModifiers; -import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Executable; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.ConstantPool; -import jdk.vm.ci.meta.DefaultProfilingInfo; -import jdk.vm.ci.meta.ExceptionHandler; -import jdk.vm.ci.meta.JavaMethod; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.LineNumberTable; -import jdk.vm.ci.meta.Local; -import jdk.vm.ci.meta.LocalVariableTable; -import jdk.vm.ci.meta.ProfilingInfo; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.SpeculationLog; -import jdk.vm.ci.meta.TriState; - -/** - * Implementation of {@link JavaMethod} for resolved HotSpot methods. - */ -final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, MetaspaceHandleObject { - - /** - * Handle to the metaspace {@code Method} object. The handle is in - * {@code JVMCI::_metadata_handles}. - */ - private final long metadataHandle; - - private final HotSpotResolvedObjectTypeImpl holder; - private final HotSpotConstantPool constantPool; - final HotSpotSignature signature; - private HotSpotMethodData methodData; - private byte[] code; - - /** - * Cache for {@link HotSpotJDKReflection#getMethod}. - */ - volatile Executable toJavaCache; - - /** - * Only 30% of {@link HotSpotResolvedJavaMethodImpl}s have their name accessed so compute it - * lazily and cache it. - */ - private String nameCache; - - /** - * Gets the holder of a HotSpot metaspace method native object. - * - * @param metaspaceHandle a handle to a metaspace Method object - * @return the {@link ResolvedJavaType} corresponding to the holder of the - * {@code metaspaceMethod} - */ - private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceHandle) { - HotSpotVMConfig config = config(); - long metaspaceMethod = UNSAFE.getLong(metaspaceHandle); - assert metaspaceMethod != 0 : metaspaceHandle; - final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset); - final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset); - HotSpotResolvedObjectTypeImpl result = compilerToVM().getResolvedJavaType(metaspaceConstantPool + config.constantPoolHolderOffset, false); - assert result != null; - return result; - } - - /** - * Gets the JVMCI mirror from a HotSpot method. The VM is responsible for ensuring that the - * Method* is kept alive for the duration of this call and the {@link HotSpotJVMCIRuntime} keeps - * it alive after that. - *

    - * Called from the VM. - * - * @param metaspaceHandle a handle to metaspace Method object - * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod} - */ - @SuppressWarnings("unused") - @VMEntryPoint - private static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceHandle) { - HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceHandle); - return holder.createMethod(metaspaceHandle); - } - - HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceHandle) { - this.metadataHandle = metaspaceHandle; - this.holder = holder; - - HotSpotVMConfig config = config(); - final long constMethod = getConstMethod(); - - /* - * Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for - * signature-polymorphic method handle methods) have their own constant pool instead of the - * one from their holder. - */ - final long metaspaceConstantPool = UNSAFE.getAddress(constMethod + config.constMethodConstantsOffset); - if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) { - this.constantPool = holder.getConstantPool(); - } else { - this.constantPool = compilerToVM().getConstantPool(this); - } - - final int signatureIndex = UNSAFE.getChar(constMethod + config.constMethodSignatureIndexOffset); - this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex); - HandleCleaner.create(this, metaspaceHandle); - } - - /** - * Returns a pointer to this method's constant method data structure ( - * {@code Method::_constMethod}). This pointer isn't wrapped since it should be safe to use it - * within the context of this HotSpotResolvedJavaMethodImpl since the Method* and ConstMethod* - * are kept alive as a pair. - * - * @return pointer to this method's ConstMethod - */ - private long getConstMethod() { - return UNSAFE.getAddress(getMetaspaceMethod() + config().methodConstMethodOffset); - } - - @Override - public String getName() { - if (nameCache == null) { - final int nameIndex = UNSAFE.getChar(getConstMethod() + config().constMethodNameIndexOffset); - nameCache = constantPool.lookupUtf8(nameIndex); - } - return nameCache; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof HotSpotResolvedJavaMethodImpl) { - HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj; - return that.getMetaspaceMethod() == getMetaspaceMethod(); - } - return false; - } - - @Override - public int hashCode() { - return (int) getMetaspaceMethod(); - } - - /** - * Returns this method's flags ({@code Method::_flags}). - * - * @return flags of this method - */ - private int getFlags() { - return UNSAFE.getShort(getMetaspaceMethod() + config().methodFlagsOffset); - } - - /** - * Returns this method's constant method flags ({@code ConstMethod::_flags}). - * - * @return flags of this method's ConstMethod - */ - private int getConstMethodFlags() { - return UNSAFE.getChar(getConstMethod() + config().constMethodFlagsOffset); - } - - @Override - public HotSpotResolvedObjectTypeImpl getDeclaringClass() { - return holder; - } - - /** - * Gets the address of the C++ Method object for this method. - */ - public Constant getMetaspaceMethodConstant() { - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false); - } - - long getMetaspaceMethod() { - long metaspacePointer = getMetaspacePointer(); - if (metaspacePointer == 0) { - throw new NullPointerException("Method* is null"); - } - return metaspacePointer; - } - - @Override - public long getMetadataHandle() { - return metadataHandle; - } - - @Override - public Constant getEncoding() { - return getMetaspaceMethodConstant(); - } - - /** - * Gets the complete set of modifiers for this method which includes the JVM specification - * modifiers as well as the HotSpot internal modifiers. - */ - public int getAllModifiers() { - return UNSAFE.getInt(getMetaspaceMethod() + config().methodAccessFlagsOffset); - } - - @Override - public int getModifiers() { - return getAllModifiers() & jvmMethodModifiers(); - } - - @Override - public boolean canBeStaticallyBound() { - return (isFinal() || isPrivate() || isStatic() || holder.isLeaf() || isConstructor()) && isConcrete(); - } - - @Override - public byte[] getCode() { - if (getCodeSize() == 0) { - return null; - } - if (code == null && holder.isLinked()) { - code = compilerToVM().getBytecode(this); - assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length; - } - return code; - } - - @Override - public int getCodeSize() { - int codeSize = UNSAFE.getChar(getConstMethod() + config().constMethodCodeSizeOffset); - if (codeSize > 0 && !getDeclaringClass().isLinked()) { - return -1; - } - return codeSize; - } - - @Override - public ExceptionHandler[] getExceptionHandlers() { - final boolean hasExceptionTable = (getConstMethodFlags() & config().constMethodHasExceptionTable) != 0; - if (!hasExceptionTable) { - return new ExceptionHandler[0]; - } - - HotSpotVMConfig config = config(); - final int exceptionTableLength = compilerToVM().getExceptionTableLength(this); - ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength]; - long exceptionTableElement = compilerToVM().getExceptionTableStart(this); - - for (int i = 0; i < exceptionTableLength; i++) { - final int startPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset); - final int endPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementEndPcOffset); - final int handlerPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementHandlerPcOffset); - int catchTypeIndex = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementCatchTypeIndexOffset); - - JavaType catchType; - if (catchTypeIndex == 0) { - catchType = null; - } else { - final int opcode = -1; // opcode is not used - catchType = constantPool.lookupType(catchTypeIndex, opcode); - - // Check for Throwable which catches everything. - if (catchType instanceof HotSpotResolvedObjectTypeImpl) { - HotSpotResolvedObjectTypeImpl resolvedType = (HotSpotResolvedObjectTypeImpl) catchType; - if (resolvedType.equals(runtime().getJavaLangThrowable())) { - catchTypeIndex = 0; - catchType = null; - } - } - } - handlers[i] = new ExceptionHandler(startPc, endPc, handlerPc, catchTypeIndex, catchType); - - // Go to the next ExceptionTableElement - exceptionTableElement += config.exceptionTableElementSize; - } - - return handlers; - } - - /** - * Returns true if this method has a {@code CallerSensitive} annotation. - * - * @return true if CallerSensitive annotation present, false otherwise - */ - @Override - public boolean isCallerSensitive() { - return (getFlags() & config().methodFlagsCallerSensitive) != 0; - } - - /** - * Returns true if this method has a {@code ForceInline} annotation. - * - * @return true if ForceInline annotation present, false otherwise - */ - @Override - public boolean isForceInline() { - return (getFlags() & config().methodFlagsForceInline) != 0; - } - - /** - * Returns true if this method has a {@code ReservedStackAccess} annotation. - * - * @return true if ReservedStackAccess annotation present, false otherwise - */ - @Override - public boolean hasReservedStackAccess() { - return (getFlags() & config().methodFlagsReservedStackAccess) != 0; - } - - /** - * Sets flags on {@code method} indicating that it should never be inlined or compiled by the - * VM. - */ - @Override - public void setNotInlinableOrCompilable() { - compilerToVM().setNotInlinableOrCompilable(this); - } - - /** - * Returns true if this method is one of the special methods that is ignored by security stack - * walks. - * - * @return true if special method ignored by security stack walks, false otherwise - */ - @Override - public boolean ignoredBySecurityStackWalk() { - return compilerToVM().methodIsIgnoredBySecurityStackWalk(this); - } - - @Override - public boolean isClassInitializer() { - if (isStatic()) { - final int nameIndex = UNSAFE.getChar(getConstMethod() + config().constMethodNameIndexOffset); - long nameSymbol = constantPool.getEntryAt(nameIndex); - long clinitSymbol = config().symbolClinit; - return nameSymbol == clinitSymbol; - } - return false; - } - - @Override - public boolean isConstructor() { - if (!isStatic()) { - final int nameIndex = UNSAFE.getChar(getConstMethod() + config().constMethodNameIndexOffset); - long nameSymbol = constantPool.getEntryAt(nameIndex); - long initSymbol = config().symbolInit; - return nameSymbol == initSymbol; - } - return false; - } - - @Override - public int getMaxLocals() { - if (isAbstract() || isNative()) { - return 0; - } - HotSpotVMConfig config = config(); - return UNSAFE.getChar(getConstMethod() + config.methodMaxLocalsOffset); - } - - @Override - public int getMaxStackSize() { - if (isAbstract() || isNative()) { - return 0; - } - HotSpotVMConfig config = config(); - return config.extraStackEntries + UNSAFE.getChar(getConstMethod() + config.constMethodMaxStackOffset); - } - - @Override - public StackTraceElement asStackTraceElement(int bci) { - if (bci < 0 || bci >= getCodeSize()) { - // HotSpot code can only construct stack trace elements for valid bcis - StackTraceElement ste = compilerToVM().getStackTraceElement(this, 0); - return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1); - } - return compilerToVM().getStackTraceElement(this, bci); - } - - @Override - public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) { - assert !canBeStaticallyBound() : this; - - if (receiver.isInterface()) { - // Cannot trust interfaces. Because of: - // interface I { void foo(); } - // class A { public void foo() {} } - // class B extends A implements I { } - // class C extends B { public void foo() { } } - // class D extends B { } - // Would lead to identify C.foo() as the unique concrete method for I.foo() without - // seeing A.foo(). - return null; - } - assert !receiver.isLinked() || isInVirtualMethodTable(receiver); - if (this.isDefault()) { - // CHA for default methods doesn't work and may crash the VM - return null; - } - return compilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this); - } - - @Override - public HotSpotSignature getSignature() { - return signature; - } - - /** - * Gets the value of {@code Method::_code}. - * - * @return the value of {@code Method::_code} - */ - private long getCompiledCode() { - HotSpotVMConfig config = config(); - return UNSAFE.getAddress(getMetaspaceMethod() + config.methodCodeOffset); - } - - /** - * Returns whether this method has compiled code. - * - * @return true if this method has compiled code, false otherwise - */ - @Override - public boolean hasCompiledCode() { - return getCompiledCode() != 0L; - } - - /** - * @param level - * @return true if the currently installed code was generated at {@code level}. - */ - @Override - public boolean hasCompiledCodeAtLevel(int level) { - long compiledCode = getCompiledCode(); - if (compiledCode != 0) { - return UNSAFE.getInt(compiledCode + config().nmethodCompLevelOffset) == level; - } - return false; - } - - @Override - public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) { - ProfilingInfo info; - - if (Option.UseProfilingInformation.getBoolean() && methodData == null) { - long metaspaceMethodData = UNSAFE.getAddress(getMetaspaceMethod() + config().methodDataOffset); - if (metaspaceMethodData != 0) { - methodData = new HotSpotMethodData(metaspaceMethodData, this); - String methodDataFilter = Option.TraceMethodDataFilter.getString(); - if (methodDataFilter != null && this.format("%H.%n").contains(methodDataFilter)) { - String line = methodData.toString() + System.lineSeparator(); - byte[] lineBytes = line.getBytes(); - HotSpotJVMCIRuntime.runtime().writeDebugOutput(lineBytes, 0, lineBytes.length, true, true); - } - } - } - - if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) { - // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in - // case of a deoptimization. - info = DefaultProfilingInfo.get(TriState.FALSE); - } else { - info = new HotSpotProfilingInfo(methodData, this, includeNormal, includeOSR); - } - return info; - } - - @Override - public void reprofile() { - compilerToVM().reprofile(this); - } - - @Override - public ConstantPool getConstantPool() { - return constantPool; - } - - @Override - public Parameter[] getParameters() { - if (signature.getParameterCount(false) == 0) { - return new ResolvedJavaMethod.Parameter[0]; - } - return runtime().reflection.getParameters(this); - } - - @Override - public Annotation[][] getParameterAnnotations() { - if ((getConstMethodFlags() & config().constMethodHasParameterAnnotations) == 0 || isClassInitializer()) { - return new Annotation[signature.getParameterCount(false)][0]; - } - return runtime().reflection.getParameterAnnotations(this); - } - - @Override - public Annotation[] getAnnotations() { - if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { - return new Annotation[0]; - } - return runtime().reflection.getMethodAnnotations(this); - } - - @Override - public Annotation[] getDeclaredAnnotations() { - if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { - return new Annotation[0]; - } - return runtime().reflection.getMethodDeclaredAnnotations(this); - } - - @Override - public T getAnnotation(Class annotationClass) { - if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { - return null; - } - return runtime().reflection.getMethodAnnotation(this, annotationClass); - } - - @Override - public boolean isBridge() { - return (BRIDGE & getModifiers()) != 0; - } - - @Override - public boolean isSynthetic() { - return (SYNTHETIC & getModifiers()) != 0; - } - - @Override - public boolean isVarArgs() { - return (VARARGS & getModifiers()) != 0; - } - - @Override - public boolean isDefault() { - // Copied from java.lang.Method.isDefault() - int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC; - return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); - } - - @Override - public Type[] getGenericParameterTypes() { - if (isClassInitializer()) { - return new Type[0]; - } - return runtime().reflection.getGenericParameterTypes(this); - } - - @Override - public boolean canBeInlined() { - if (hasNeverInlineDirective()) { - return false; - } - return compilerToVM().isCompilable(this); - } - - @Override - public boolean hasNeverInlineDirective() { - return compilerToVM().hasNeverInlineDirective(this); - } - - @Override - public boolean shouldBeInlined() { - if (isForceInline()) { - return true; - } - return compilerToVM().shouldInlineMethod(this); - } - - @Override - public LineNumberTable getLineNumberTable() { - final boolean hasLineNumberTable = (getConstMethodFlags() & config().constMethodHasLineNumberTable) != 0; - if (!hasLineNumberTable) { - return null; - } - - long[] values = compilerToVM().getLineNumberTable(this); - if (values == null || values.length == 0) { - // Empty table so treat is as non-existent - return null; - } - assert values.length % 2 == 0; - int[] bci = new int[values.length / 2]; - int[] line = new int[values.length / 2]; - - for (int i = 0; i < values.length / 2; i++) { - bci[i] = (int) values[i * 2]; - line[i] = (int) values[i * 2 + 1]; - } - - return new LineNumberTable(line, bci); - } - - @Override - public LocalVariableTable getLocalVariableTable() { - final boolean hasLocalVariableTable = (getConstMethodFlags() & config().constMethodHasLocalVariableTable) != 0; - if (!hasLocalVariableTable) { - return null; - } - - HotSpotVMConfig config = config(); - long localVariableTableElement = compilerToVM().getLocalVariableTableStart(this); - final int localVariableTableLength = compilerToVM().getLocalVariableTableLength(this); - Local[] locals = new Local[localVariableTableLength]; - - for (int i = 0; i < localVariableTableLength; i++) { - final int startBci = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementStartBciOffset); - final int endBci = startBci + UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementLengthOffset); - final int nameCpIndex = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementNameCpIndexOffset); - final int typeCpIndex = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementDescriptorCpIndexOffset); - final int slot = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementSlotOffset); - - String localName = getConstantPool().lookupUtf8(nameCpIndex); - String localType = getConstantPool().lookupUtf8(typeCpIndex); - - locals[i] = new Local(localName, runtime().lookupType(localType, holder, false), startBci, endBci, slot); - - // Go to the next LocalVariableTableElement - localVariableTableElement += config.localVariableTableElementSize; - } - - return new LocalVariableTable(locals); - } - - /** - * Returns the offset of this method into the v-table. The method must have a v-table entry as - * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is - * thrown. - * - * @return the offset of this method into the v-table - */ - @Override - public int vtableEntryOffset(ResolvedJavaType resolved) { - if (!isInVirtualMethodTable(resolved)) { - throw new JVMCIError("%s does not have a vtable entry in type %s", this, resolved); - } - HotSpotVMConfig config = config(); - final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved); - return config.klassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset; - } - - @Override - public boolean isInVirtualMethodTable(ResolvedJavaType resolved) { - if (resolved instanceof HotSpotResolvedObjectTypeImpl) { - HotSpotResolvedObjectTypeImpl hotspotResolved = (HotSpotResolvedObjectTypeImpl) resolved; - int vtableIndex = getVtableIndex(hotspotResolved); - return vtableIndex >= 0 && vtableIndex < hotspotResolved.getVtableLength(); - } - return false; - } - - private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) { - if (!holder.isLinked()) { - return config().invalidVtableIndex; - } - if (holder.isInterface()) { - if (resolved.isInterface() || !resolved.isLinked() || !getDeclaringClass().isAssignableFrom(resolved)) { - return config().invalidVtableIndex; - } - return getVtableIndexForInterfaceMethod(resolved); - } - return getVtableIndex(); - } - - /** - * Returns this method's virtual table index. - * - * @return virtual table index - */ - private int getVtableIndex() { - assert !holder.isInterface(); - HotSpotVMConfig config = config(); - int result = UNSAFE.getInt(getMetaspaceMethod() + config.methodVtableIndexOffset); - assert result >= config.nonvirtualVtableIndex : "must be linked"; - return result; - } - - private int getVtableIndexForInterfaceMethod(ResolvedJavaType resolved) { - HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved; - return compilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this); - } - - @Override - public SpeculationLog getSpeculationLog() { - long address = compilerToVM().getFailedSpeculationsAddress(this); - return new HotSpotSpeculationLog(address); - } - - @Override - public int intrinsicId() { - HotSpotVMConfig config = config(); - return UNSAFE.getChar(getMetaspaceMethod() + config.methodIntrinsicIdOffset); - } - - @Override - public boolean isIntrinsicCandidate() { - return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0; - } - - /** - * Allocates a compile id for this method by asking the VM for one. - * - * @param entryBCI entry bci - * @return compile id - */ - @Override - public int allocateCompileId(int entryBCI) { - return compilerToVM().allocateCompileId(this, entryBCI); - } - - @Override - public boolean hasCodeAtLevel(int entryBCI, int level) { - if (entryBCI == config().invocationEntryBci) { - return hasCompiledCodeAtLevel(level); - } - return compilerToVM().hasCompiledCodeForOSR(this, entryBCI, level); - } - - @Override - public int methodIdnum() { - return UNSAFE.getChar(getConstMethod() + config().constMethodMethodIdnumOffset); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.hotspot; - -import java.lang.reflect.Modifier; - -import jdk.vm.ci.meta.JavaMethod; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * Implementation of {@link JavaMethod} for resolved HotSpot methods. - */ -public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod { - - /** - * Returns true if this method has a {@code CallerSensitive} annotation. - * - * @return true if CallerSensitive annotation present, false otherwise - */ - boolean isCallerSensitive(); - - @Override - HotSpotResolvedObjectType getDeclaringClass(); - - /** - * Returns true if this method has a {@code ForceInline} annotation. - * - * @return true if ForceInline annotation present, false otherwise - */ - boolean isForceInline(); - - /** - * Returns true if this method has a {@code ReservedStackAccess} annotation. - * - * @return true if ReservedStackAccess annotation present, false otherwise - */ - boolean hasReservedStackAccess(); - - /** - * Sets flags on {@code method} indicating that it should never be inlined or compiled by the - * VM. - */ - void setNotInlinableOrCompilable(); - - /** - * Returns true if this method is one of the special methods that is ignored by security stack - * walks. - * - * @return true if special method ignored by security stack walks, false otherwise - */ - boolean ignoredBySecurityStackWalk(); - - ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver); - - /** - * Returns whether this method has compiled code. - * - * @return true if this method has compiled code, false otherwise - */ - boolean hasCompiledCode(); - - /** - * @param level - * @return true if the currently installed code was generated at {@code level}. - */ - boolean hasCompiledCodeAtLevel(int level); - - @Override - default boolean isDefault() { - if (isConstructor()) { - return false; - } - // Copied from java.lang.Method.isDefault() - int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC; - return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); - } - - /** - * Returns the offset of this method into the v-table. The method must have a v-table entry as - * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is - * thrown. - * - * @return the offset of this method into the v-table - */ - int vtableEntryOffset(ResolvedJavaType resolved); - - int intrinsicId(); - - /** - * Determines if this method denotes itself as a candidate for intrinsification. As of JDK 9, - * this is denoted by the {@code IntrinsicCandidate} annotation. In earlier JDK versions, this - * method returns true. - * - * @see JDK-8076112 - */ - boolean isIntrinsicCandidate(); - - /** - * Allocates a compile id for this method by asking the VM for one. - * - * @param entryBCI entry bci - * @return compile id - */ - int allocateCompileId(int entryBCI); - - boolean hasCodeAtLevel(int entryBCI, int level); - - int methodIdnum(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.ResolvedJavaType; - -public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType { - - HotSpotResolvedObjectTypeImpl arrayOfType; - - HotSpotResolvedJavaType(String name) { - super(name); - } - - @Override - public abstract boolean equals(Object obj); - - @Override - public final int hashCode() { - return getName().hashCode(); - } - - abstract JavaConstant getJavaMirror(); - - @Override - public HotSpotResolvedObjectType getArrayClass() { - if (arrayOfType == null) { - arrayOfType = runtime().compilerToVm.getArrayType(this); - } - return arrayOfType; - } - - /** - * Checks whether this type is currently being initialized. If a type is being initialized it - * implies that it was {@link #isLinked() linked} and that the static initializer is currently - * being run. - * - * @return {@code true} if this type is being initialized - */ - abstract boolean isBeingInitialized(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,1069 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.hotspot; - -import static java.util.Objects.requireNonNull; -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; -import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers; -import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.nio.ByteOrder; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.Assumptions.AssumptionResult; -import jdk.vm.ci.meta.Assumptions.ConcreteMethod; -import jdk.vm.ci.meta.Assumptions.ConcreteSubtype; -import jdk.vm.ci.meta.Assumptions.LeafType; -import jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass; -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.UnresolvedJavaField; -import jdk.vm.ci.meta.UnresolvedJavaType; - -/** - * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. This class is not - * an {@link MetaspaceHandleObject} because it doesn't have to be scanned for GC. It's liveness is - * maintained by a reference to the {@link Class} instance. - */ -final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, MetaspaceObject { - - private static final HotSpotResolvedJavaField[] NO_FIELDS = new HotSpotResolvedJavaField[0]; - private static final int METHOD_CACHE_ARRAY_CAPACITY = 8; - private static final SortByOffset fieldSortingMethod = new SortByOffset(); - - /** - * The Java class this type represents. - */ - private final long metadataPointer; - - private HotSpotResolvedJavaMethodImpl[] methodCacheArray; - private HashMap methodCacheHashMap; - private volatile HotSpotResolvedJavaField[] instanceFields; - private volatile HotSpotResolvedObjectTypeImpl[] interfaces; - private HotSpotConstantPool constantPool; - private final JavaConstant mirror; - private HotSpotResolvedObjectTypeImpl superClass; - private HotSpotResolvedJavaType componentType; - - /** - * Managed exclusively by {@link HotSpotJDKReflection#getField}. - */ - HashMap reflectionFieldCache; - - static HotSpotResolvedObjectTypeImpl getJavaLangObject() { - return runtime().getJavaLangObject(); - } - - /** - * Gets the JVMCI mirror from a HotSpot type. - * - * Called from the VM. - * - * @param klassPointer a native pointer to the Klass* - * @return the {@link ResolvedJavaType} corresponding to {@code javaClass} - */ - @SuppressWarnings("unused") - @VMEntryPoint - private static HotSpotResolvedObjectTypeImpl fromMetaspace(long klassPointer, String signature) { - return runtime().fromMetaspace(klassPointer, signature); - } - - /** - * Creates the JVMCI mirror for a {@link Class} object. - * - * NOTE: Creating an instance of this class does not install the mirror for the - * {@link Class} type. - *

    - * - * @param metadataPointer the Klass* to create the mirror for - */ - @SuppressWarnings("try") - HotSpotResolvedObjectTypeImpl(long metadataPointer, String name) { - super(name); - assert metadataPointer != 0; - this.metadataPointer = metadataPointer; - - // The mirror object must be in the global scope since - // this object will be cached in HotSpotJVMCIRuntime.resolvedJavaTypes - // and live across more than one compilation. - try (HotSpotObjectConstantScope global = HotSpotObjectConstantScope.enterGlobalScope()) { - this.mirror = runtime().compilerToVm.getJavaMirror(this); - assert getName().charAt(0) != '[' || isArray() : getName(); - } - } - - /** - * Gets the metaspace Klass for this type. - */ - long getMetaspaceKlass() { - long metaspacePointer = getMetaspacePointer(); - if (metaspacePointer == 0) { - throw new NullPointerException("Klass* is null"); - } - return metaspacePointer; - } - - @Override - public long getMetaspacePointer() { - return metadataPointer; - } - - @Override - public int getModifiers() { - if (isArray()) { - return (getElementalType().getModifiers() & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) | Modifier.FINAL | Modifier.ABSTRACT; - } else { - return getAccessFlags() & jvmClassModifiers(); - } - } - - public int getAccessFlags() { - HotSpotVMConfig config = config(); - return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset); - } - - @Override - public ResolvedJavaType getComponentType() { - if (componentType == null) { - if (isArray()) { - componentType = runtime().compilerToVm.getComponentType(this); - } else { - componentType = this; - } - } - return this.equals(componentType) ? null : componentType; - } - - @Override - public AssumptionResult findLeafConcreteSubtype() { - if (isLeaf()) { - // No assumptions are required. - return new AssumptionResult<>(this); - } - HotSpotVMConfig config = config(); - if (isArray()) { - ResolvedJavaType elementalType = getElementalType(); - AssumptionResult elementType = elementalType.findLeafConcreteSubtype(); - if (elementType != null && elementType.getResult().equals(elementalType)) { - /* - * If the elementType is leaf then the array is leaf under the same assumptions but - * only if the element type is exactly the leaf type. The element type can be - * abstract even if there is only one implementor of the abstract type. - */ - AssumptionResult result = new AssumptionResult<>(this); - result.add(elementType); - return result; - } - return null; - } else if (isInterface()) { - HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor(); - /* - * If the implementor field contains itself that indicates that the interface has more - * than one implementors (see: InstanceKlass::add_implementor). - */ - if (implementor == null || implementor.equals(this)) { - return null; - } - - assert !implementor.isInterface(); - if (implementor.isAbstract() || !implementor.isLeafClass()) { - AssumptionResult leafConcreteSubtype = implementor.findLeafConcreteSubtype(); - if (leafConcreteSubtype != null) { - assert !leafConcreteSubtype.getResult().equals(implementor); - AssumptionResult newResult = new AssumptionResult<>(leafConcreteSubtype.getResult(), new ConcreteSubtype(this, implementor)); - // Accumulate leaf assumptions and return the combined result. - newResult.add(leafConcreteSubtype); - return newResult; - } - return null; - } - return concreteSubtype(implementor); - } else { - HotSpotResolvedObjectTypeImpl type = this; - while (type.isAbstract()) { - HotSpotResolvedObjectTypeImpl subklass = type.getSubklass(); - if (subklass == null || UNSAFE.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) { - return null; - } - type = subklass; - } - if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { - return null; - } - if (this.isAbstract()) { - return concreteSubtype(type); - } else { - assert this.equals(type); - return new AssumptionResult<>(type, new LeafType(type)); - } - } - } - - private AssumptionResult concreteSubtype(HotSpotResolvedObjectTypeImpl type) { - if (type.isLeaf()) { - return new AssumptionResult<>(type, new ConcreteSubtype(this, type)); - } else { - return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type)); - } - } - - /** - * Returns if type {@code type} is a leaf class. This is the case if the - * {@code Klass::_subklass} field of the underlying class is zero. - * - * @return true if the type is a leaf class - */ - private boolean isLeafClass() { - return UNSAFE.getLong(this.getMetaspaceKlass() + config().subklassOffset) == 0; - } - - /** - * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given - * type {@code type}. - * - * @return value of the subklass field as metaspace klass pointer - */ - private HotSpotResolvedObjectTypeImpl getSubklass() { - return compilerToVM().getResolvedJavaType(this, config().subklassOffset, false); - } - - @Override - public HotSpotResolvedObjectTypeImpl getSuperclass() { - if (isInterface()) { - return null; - } - HotSpotResolvedObjectTypeImpl javaLangObject = runtime().getJavaLangObject(); - if (this.equals(javaLangObject)) { - return null; - } - if (isArray()) { - return javaLangObject; - } - - // Cache result of native call - if (superClass == null) { - superClass = compilerToVM().getResolvedJavaType(this, config().superOffset, false); - } - return superClass; - } - - @Override - public HotSpotResolvedObjectTypeImpl[] getInterfaces() { - if (interfaces == null) { - if (isArray()) { - HotSpotResolvedObjectTypeImpl[] types = new HotSpotResolvedObjectTypeImpl[2]; - types[0] = runtime().getJavaLangCloneable(); - types[1] = runtime().getJavaLangSerializable(); - this.interfaces = types; - } else { - interfaces = runtime().compilerToVm.getInterfaces(this); - } - } - return interfaces; - } - - @Override - public HotSpotResolvedObjectTypeImpl getSingleImplementor() { - if (!isInterface()) { - throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this); - } - return compilerToVM().getImplementor(this); - } - - @Override - public HotSpotResolvedObjectTypeImpl getSupertype() { - ResolvedJavaType component = getComponentType(); - if (component != null) { - if (component.equals(getJavaLangObject()) || component.isPrimitive()) { - return getJavaLangObject(); - } - HotSpotResolvedObjectTypeImpl supertype = ((HotSpotResolvedObjectTypeImpl) component).getSupertype(); - return (HotSpotResolvedObjectTypeImpl) supertype.getArrayClass(); - } - if (isInterface()) { - return getJavaLangObject(); - } - return getSuperclass(); - } - - @Override - public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) { - if (otherType.isPrimitive()) { - return null; - } else { - HotSpotResolvedObjectTypeImpl t1 = this; - HotSpotResolvedObjectTypeImpl t2 = (HotSpotResolvedObjectTypeImpl) otherType; - while (true) { - if (t1.isAssignableFrom(t2)) { - return t1; - } - if (t2.isAssignableFrom(t1)) { - return t2; - } - t1 = t1.getSupertype(); - t2 = t2.getSupertype(); - } - } - } - - @Override - public AssumptionResult hasFinalizableSubclass() { - assert !isArray(); - if (!compilerToVM().hasFinalizableSubclass(this)) { - return new AssumptionResult<>(false, new NoFinalizableSubclass(this)); - } - return new AssumptionResult<>(true); - } - - @Override - public boolean hasFinalizer() { - return (getAccessFlags() & config().jvmAccHasFinalizer) != 0; - } - - @Override - public boolean isArray() { - return layoutHelper() < config().klassLayoutHelperNeutralValue; - } - - @Override - public boolean isEnum() { - HotSpotResolvedObjectTypeImpl superclass = getSuperclass(); - return superclass != null && superclass.equals(runtime().getJavaLangEnum()); - } - - @Override - public boolean isInitialized() { - return isArray() ? true : getInitState() == config().instanceKlassStateFullyInitialized; - } - - @Override - public boolean isBeingInitialized() { - return isArray() ? false : getInitState() == config().instanceKlassStateBeingInitialized; - } - - @Override - public boolean isLinked() { - return isArray() ? true : getInitState() >= config().instanceKlassStateLinked; - } - - @Override - public void link() { - if (!isLinked()) { - runtime().compilerToVm.ensureLinked(this); - } - } - - @Override - public boolean hasDefaultMethods() { - HotSpotVMConfig config = config(); - int miscFlags = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassMiscFlagsOffset); - return (miscFlags & config.jvmMiscFlagsHasDefaultMethods) != 0; - } - - @Override - public boolean declaresDefaultMethods() { - HotSpotVMConfig config = config(); - int miscFlags = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassMiscFlagsOffset); - return (miscFlags & config.jvmMiscFlagsDeclaresDefaultMethods) != 0; - } - - /** - * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace - * klass. - * - * @return state field value of this type - */ - private int getInitState() { - assert !isArray() : "_init_state only exists in InstanceKlass"; - return UNSAFE.getByte(getMetaspaceKlass() + config().instanceKlassInitStateOffset) & 0xFF; - } - - @Override - public void initialize() { - if (!isInitialized()) { - runtime().compilerToVm.ensureInitialized(this); - assert isInitialized() || isBeingInitialized(); - } - } - - @Override - public boolean isInstance(JavaConstant obj) { - if (obj.getJavaKind() == JavaKind.Object && !obj.isNull()) { - return runtime().reflection.isInstance(this, (HotSpotObjectConstantImpl) obj); - } - return false; - } - - @Override - public boolean isInstanceClass() { - return !isArray() && !isInterface(); - } - - @Override - public boolean isInterface() { - return (getAccessFlags() & config().jvmAccInterface) != 0; - } - - @Override - public boolean isAssignableFrom(ResolvedJavaType other) { - assert other != null; - if (other instanceof HotSpotResolvedObjectTypeImpl) { - HotSpotResolvedObjectTypeImpl otherType = (HotSpotResolvedObjectTypeImpl) other; - return runtime().reflection.isAssignableFrom(this, otherType); - } - return false; - } - - @Override - public boolean isJavaLangObject() { - return getName().equals("Ljava/lang/Object;"); - } - - @Override - public JavaKind getJavaKind() { - return JavaKind.Object; - } - - @Override - public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { - assert !callerType.isArray(); - if (isInterface()) { - // Methods can only be resolved against concrete types - return null; - } - if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic() && !isSignaturePolymorphicHolder(method.getDeclaringClass())) { - return method; - } - if (!method.getDeclaringClass().isAssignableFrom(this)) { - return null; - } - if (method.isConstructor()) { - // Constructor calls should have been checked in the verifier and method's - // declaring class is assignable from this (see above) so treat it as resolved. - return method; - } - HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method; - HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType; - return compilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType); - } - - @Override - public HotSpotConstantPool getConstantPool() { - if (constantPool == null || !isArray() && UNSAFE.getAddress(getMetaspaceKlass() + config().instanceKlassConstantsOffset) != constantPool.getMetaspaceConstantPool()) { - /* - * If the pointer to the ConstantPool has changed since this was last read refresh the - * HotSpotConstantPool wrapper object. This ensures that uses of the constant pool are - * operating on the latest one and that HotSpotResolvedJavaMethodImpls will be able to - * use the shared copy instead of creating their own instance. - */ - constantPool = compilerToVM().getConstantPool(this); - } - return constantPool; - } - - /** - * Gets the instance size of this type. If an instance of this type cannot be fast path - * allocated, then the returned value is negative (its absolute value gives the size). Must not - * be called if this is an array or interface type. - */ - @Override - public int instanceSize() { - assert !isArray(); - assert !isInterface(); - - HotSpotVMConfig config = config(); - final int layoutHelper = layoutHelper(); - assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance"; - - // See: Klass::layout_helper_size_in_bytes - int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit; - - // See: Klass::layout_helper_needs_slow_path - boolean needsSlowPath = (layoutHelper & config.klassLayoutHelperInstanceSlowPathBit) != 0; - - return needsSlowPath ? -size : size; - } - - @Override - public int layoutHelper() { - HotSpotVMConfig config = config(); - assert getMetaspaceKlass() != 0 : getName(); - return UNSAFE.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset); - } - - @Override - public long getFingerprint() { - return compilerToVM().getFingerprint(getMetaspaceKlass()); - } - - synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceHandle) { - long metaspaceMethod = UNSAFE.getLong(metaspaceHandle); - // Maintain cache as array. - if (methodCacheArray == null) { - methodCacheArray = new HotSpotResolvedJavaMethodImpl[METHOD_CACHE_ARRAY_CAPACITY]; - } - - int i = 0; - for (; i < methodCacheArray.length; ++i) { - HotSpotResolvedJavaMethodImpl curMethod = methodCacheArray[i]; - if (curMethod == null) { - HotSpotResolvedJavaMethodImpl newMethod = new HotSpotResolvedJavaMethodImpl(this, metaspaceHandle); - methodCacheArray[i] = newMethod; - return newMethod; - } else if (curMethod.getMetaspaceMethod() == metaspaceMethod) { - return curMethod; - } - } - - // Fall-back to hash table. - if (methodCacheHashMap == null) { - methodCacheHashMap = new HashMap<>(); - } - - HotSpotResolvedJavaMethodImpl lookupResult = methodCacheHashMap.get(metaspaceMethod); - if (lookupResult == null) { - HotSpotResolvedJavaMethodImpl newMethod = new HotSpotResolvedJavaMethodImpl(this, metaspaceHandle); - methodCacheHashMap.put(metaspaceMethod, newMethod); - return newMethod; - } else { - return lookupResult; - } - } - - @Override - public int getVtableLength() { - HotSpotVMConfig config = config(); - if (isInterface() || isArray()) { - /* Everything has the core vtable of java.lang.Object */ - return config.baseVtableLength(); - } - int result = UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize); - assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) + " " + config.vtableEntrySize; - return result; - } - - HotSpotResolvedJavaField createField(JavaType type, int offset, int rawFlags, int index) { - return new HotSpotResolvedJavaFieldImpl(this, type, offset, rawFlags, index); - } - - @Override - public AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method) { - HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method; - HotSpotResolvedObjectType declaredHolder = hmethod.getDeclaringClass(); - /* - * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared - * holder, usually because of phis, so make sure that the type is related to the declared - * type before using it for lookup. Unlinked types should also be ignored because we can't - * resolve the proper method to invoke. Generally unlinked types in invokes should result in - * a deopt instead since they can't really be used if they aren't linked yet. - */ - if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) { - if (hmethod.canBeStaticallyBound()) { - // No assumptions are required. - return new AssumptionResult<>(hmethod); - } - ResolvedJavaMethod result = hmethod.uniqueConcreteMethod(declaredHolder); - if (result != null) { - return new AssumptionResult<>(result, new ConcreteMethod(method, declaredHolder, result)); - } - return null; - } - /* - * The holder may be a subtype of the declaredHolder so make sure to resolve the method to - * the correct method for the subtype. - */ - HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this); - if (resolvedMethod == null) { - // The type isn't known to implement the method. - return null; - } - if (resolvedMethod.canBeStaticallyBound()) { - // No assumptions are required. - return new AssumptionResult<>(resolvedMethod); - } - - ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this); - if (result != null) { - return new AssumptionResult<>(result, new ConcreteMethod(method, this, result)); - } - return null; - } - - FieldInfo createFieldInfo(int index) { - return new FieldInfo(index); - } - - public void ensureInitialized() { - runtime().compilerToVm.ensureInitialized(this); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof HotSpotResolvedObjectTypeImpl)) { - return false; - } - HotSpotResolvedObjectTypeImpl that = (HotSpotResolvedObjectTypeImpl) obj; - return getMetaspaceKlass() == that.getMetaspaceKlass(); - } - - @Override - JavaConstant getJavaMirror() { - return mirror; - } - - /** - * This class represents the field information for one field contained in the fields array of an - * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class. - */ - class FieldInfo { - /** - * Native pointer into the array of Java shorts. - */ - private final long metaspaceData; - - /** - * Creates a field info for the field in the fields array at index {@code index}. - * - * @param index index to the fields array - */ - FieldInfo(int index) { - HotSpotVMConfig config = config(); - // Get Klass::_fields - final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); - assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code"; - int offset = config.fieldInfoFieldSlots * Short.BYTES * index; - metaspaceData = metaspaceFields + config.arrayU2DataOffset + offset; - } - - private int getAccessFlags() { - return readFieldSlot(config().fieldInfoAccessFlagsOffset); - } - - private int getNameIndex() { - return readFieldSlot(config().fieldInfoNameIndexOffset); - } - - private int getSignatureIndex() { - return readFieldSlot(config().fieldInfoSignatureIndexOffset); - } - - private int getConstantValueIndex() { - return readFieldSlot(config().fieldInfoConstantValueIndexOffset); - } - - public int getOffset() { - HotSpotVMConfig config = config(); - final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset); - final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset); - final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize; - return offset; - } - - /** - * Helper method to read an entry (slot) from the field array. Currently field info is laid - * on top an array of Java shorts. - */ - private int readFieldSlot(int index) { - int offset = Short.BYTES * index; - return UNSAFE.getChar(metaspaceData + offset); - } - - /** - * Returns the name of this field as a {@link String}. If the field is an internal field the - * name index is pointing into the vmSymbols table. - */ - public String getName() { - final int nameIndex = getNameIndex(); - return isInternal() ? config().symbolAt(nameIndex) : getConstantPool().lookupUtf8(nameIndex); - } - - /** - * Returns the signature of this field as {@link String}. If the field is an internal field - * the signature index is pointing into the vmSymbols table. - */ - public String getSignature() { - final int signatureIndex = getSignatureIndex(); - return isInternal() ? config().symbolAt(signatureIndex) : getConstantPool().lookupUtf8(signatureIndex); - } - - /** - * Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of this field. - * - * @return {@code null} if this field has no {@code ConstantValue} attribute - */ - public JavaConstant getConstantValue() { - int cvIndex = getConstantValueIndex(); - if (cvIndex == 0) { - return null; - } - return constantPool.getStaticFieldConstantValue(cvIndex); - } - - public JavaType getType() { - String signature = getSignature(); - return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false); - } - - private boolean isInternal() { - return (getAccessFlags() & config().jvmAccFieldInternal) != 0; - } - - public boolean isStatic() { - return Modifier.isStatic(getAccessFlags()); - } - - public boolean hasGenericSignature() { - return (getAccessFlags() & config().jvmAccFieldHasGenericSignature) != 0; - } - } - - static class SortByOffset implements Comparator { - public int compare(ResolvedJavaField a, ResolvedJavaField b) { - return a.getOffset() - b.getOffset(); - } - } - - @Override - public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { - if (instanceFields == null) { - if (isArray() || isInterface()) { - instanceFields = NO_FIELDS; - } else { - HotSpotResolvedJavaField[] prepend = NO_FIELDS; - if (getSuperclass() != null) { - prepend = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true); - } - instanceFields = getFields(false, prepend); - } - } - if (!includeSuperclasses && getSuperclass() != null) { - int superClassFieldCount = getSuperclass().getInstanceFields(true).length; - if (superClassFieldCount == instanceFields.length) { - // This class does not have any instance fields of its own. - return NO_FIELDS; - } else if (superClassFieldCount != 0) { - // Fields of the current class can be interleaved with fields of its super-classes - // but the array of fields to be returned must be sorted by increasing offset - // This code populates the array, then applies the sorting function - HotSpotResolvedJavaField[] result = new HotSpotResolvedJavaField[instanceFields.length - superClassFieldCount]; - int i = 0; - for (HotSpotResolvedJavaField f : instanceFields) { - if (f.getDeclaringClass() == this) { - result[i++] = f; - } - } - Arrays.sort(result, fieldSortingMethod); - return result; - } else { - // The super classes of this class do not have any instance fields. - } - } - return instanceFields; - } - - @Override - public ResolvedJavaField[] getStaticFields() { - if (isArray()) { - return new HotSpotResolvedJavaField[0]; - } else { - return getFields(true, NO_FIELDS); - } - } - - /** - * Gets the instance or static fields of this class. - * - * @param retrieveStaticFields specifies whether to return instance or static fields - * @param prepend an array to be prepended to the returned result - */ - private HotSpotResolvedJavaField[] getFields(boolean retrieveStaticFields, HotSpotResolvedJavaField[] prepend) { - HotSpotVMConfig config = config(); - final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); - int metaspaceFieldsLength = UNSAFE.getInt(metaspaceFields + config.arrayU1LengthOffset); - int resultCount = 0; - int index = 0; - for (int i = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) { - FieldInfo field = new FieldInfo(index); - if (field.hasGenericSignature()) { - metaspaceFieldsLength--; - } - - if (field.isStatic() == retrieveStaticFields) { - resultCount++; - } - } - - if (resultCount == 0) { - return prepend; - } - - int prependLength = prepend.length; - resultCount += prependLength; - - HotSpotResolvedJavaField[] result = new HotSpotResolvedJavaField[resultCount]; - if (prependLength != 0) { - System.arraycopy(prepend, 0, result, 0, prependLength); - } - - // Fields of the current class can be interleaved with fields of its super-classes - // but the array of fields to be returned must be sorted by increasing offset - // This code populates the array, then applies the sorting function - int resultIndex = prependLength; - for (int i = 0; i < index; ++i) { - FieldInfo field = new FieldInfo(i); - if (field.isStatic() == retrieveStaticFields) { - int offset = field.getOffset(); - HotSpotResolvedJavaField resolvedJavaField = createField(field.getType(), offset, field.getAccessFlags(), i); - result[resultIndex++] = resolvedJavaField; - } - } - Arrays.sort(result, fieldSortingMethod); - return result; - } - - @Override - public String getSourceFileName() { - if (isArray()) { - return null; - } - return getConstantPool().getSourceFileName(); - } - - @Override - public Annotation[] getAnnotations() { - return runtime().reflection.getAnnotations(this); - } - - @Override - public Annotation[] getDeclaredAnnotations() { - return runtime().reflection.getDeclaredAnnotations(this); - } - - @Override - public T getAnnotation(Class annotationClass) { - return runtime().reflection.getAnnotation(this, annotationClass); - } - - /** - * Performs a fast-path check that this type is resolved in the context of a given accessing - * class. A negative result does not mean this type is not resolved with respect to - * {@code accessingClass}. That can only be determined by - * {@linkplain HotSpotJVMCIRuntime#lookupType(String, HotSpotResolvedObjectType, boolean) - * re-resolving} the type. - */ - @Override - public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) { - assert accessingClass != null; - ResolvedJavaType elementType = getElementalType(); - if (elementType.isPrimitive()) { - // Primitive type resolution is context free. - return true; - } - if (elementType.getName().startsWith("Ljava/") && hasSameClassLoader(runtime().getJavaLangObject())) { - // Classes in a java.* package defined by the boot class loader are always resolved. - return true; - } - HotSpotResolvedObjectTypeImpl otherMirror = ((HotSpotResolvedObjectTypeImpl) accessingClass); - return hasSameClassLoader(otherMirror); - } - - private boolean hasSameClassLoader(HotSpotResolvedObjectTypeImpl otherMirror) { - return UnsafeAccess.UNSAFE.getAddress(getMetaspaceKlass() + config().classLoaderDataOffset) == UnsafeAccess.UNSAFE.getAddress( - otherMirror.getMetaspaceKlass() + config().classLoaderDataOffset); - } - - @Override - public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - if (isDefinitelyResolvedWithRespectTo(requireNonNull(accessingClass))) { - return this; - } - HotSpotResolvedObjectTypeImpl accessingType = (HotSpotResolvedObjectTypeImpl) accessingClass; - return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true); - } - - /** - * Gets the metaspace Klass boxed in a {@link JavaConstant}. - */ - @Override - public Constant klass() { - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false); - } - - @Override - public boolean isPrimaryType() { - return config().secondarySuperCacheOffset != superCheckOffset(); - } - - @Override - public int superCheckOffset() { - HotSpotVMConfig config = config(); - return UNSAFE.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset); - } - - @Override - public long prototypeMarkWord() { - HotSpotVMConfig config = config(); - if (isArray()) { - return config.arrayPrototypeMarkWord(); - } else { - return UNSAFE.getAddress(getMetaspaceKlass() + config.prototypeMarkWordOffset); - } - } - - @Override - public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedEntryKind) { - ResolvedJavaField[] declaredFields = getInstanceFields(true); - return findFieldWithOffset(offset, expectedEntryKind, declaredFields); - } - - public ResolvedJavaField findStaticFieldWithOffset(long offset, JavaKind expectedEntryKind) { - ResolvedJavaField[] declaredFields = getStaticFields(); - return findFieldWithOffset(offset, expectedEntryKind, declaredFields); - } - - private static ResolvedJavaField findFieldWithOffset(long offset, JavaKind expectedEntryKind, ResolvedJavaField[] declaredFields) { - for (ResolvedJavaField field : declaredFields) { - long resolvedFieldOffset = field.getOffset(); - // @formatter:off - if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN && - expectedEntryKind.isPrimitive() && - !expectedEntryKind.equals(JavaKind.Void) && - field.getJavaKind().isPrimitive()) { - resolvedFieldOffset += - field.getJavaKind().getByteCount() - - Math.min(field.getJavaKind().getByteCount(), 4 + expectedEntryKind.getByteCount()); - } - if (resolvedFieldOffset == offset) { - return field; - } - // @formatter:on - } - return null; - } - - @Override - public boolean isLocal() { - return runtime().reflection.isLocalClass(this); - } - - @Override - public boolean isMember() { - return runtime().reflection.isMemberClass(this); - } - - @Override - public HotSpotResolvedObjectType getEnclosingType() { - return runtime().reflection.getEnclosingClass(this); - } - - @Override - public ResolvedJavaMethod[] getDeclaredConstructors() { - link(); - return runtime().compilerToVm.getDeclaredConstructors(this); - } - - @Override - public ResolvedJavaMethod[] getDeclaredConstructors(boolean forceLink) { - if (forceLink) { - link(); - } - return runtime().compilerToVm.getDeclaredConstructors(this); - } - - @Override - public ResolvedJavaMethod[] getDeclaredMethods() { - return getDeclaredMethods(true); - } - - @Override - public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { - if (forceLink) { - link(); - } - return runtime().compilerToVm.getDeclaredMethods(this); - } - - @Override - public ResolvedJavaMethod getClassInitializer() { - if (!isArray()) { - return compilerToVM().getClassInitializer(this); - } - return null; - } - - @Override - public String toString() { - return "HotSpotType<" + getName() + ", resolved>"; - } - - @Override - public ResolvedJavaType lookupType(UnresolvedJavaType unresolvedJavaType, boolean resolve) { - JavaType javaType = HotSpotJVMCIRuntime.runtime().lookupType(unresolvedJavaType.getName(), this, resolve); - if (javaType instanceof ResolvedJavaType) { - return (ResolvedJavaType) javaType; - } - return null; - } - - @Override - public ResolvedJavaField resolveField(UnresolvedJavaField unresolvedJavaField, ResolvedJavaType accessingClass) { - for (ResolvedJavaField field : getInstanceFields(false)) { - if (field.getName().equals(unresolvedJavaField.getName())) { - return field; - } - } - for (ResolvedJavaField field : getStaticFields()) { - if (field.getName().equals(unresolvedJavaField.getName())) { - return field; - } - } - throw new InternalError(unresolvedJavaField.toString()); - } - - @Override - public boolean isCloneableWithAllocation() { - return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0; - } - - private int getMiscFlags() { - return UNSAFE.getInt(getMetaspaceKlass() + config().instanceKlassMiscFlagsOffset); - } - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.Assumptions.AssumptionResult; -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.ConstantPool; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. - */ -public interface HotSpotResolvedObjectType extends ResolvedJavaType { - - @Override - HotSpotResolvedObjectType getArrayClass(); - - @Override - ResolvedJavaType getComponentType(); - - @Override - AssumptionResult findLeafConcreteSubtype(); - - @Override - HotSpotResolvedObjectType getSuperclass(); - - @Override - HotSpotResolvedObjectType[] getInterfaces(); - - HotSpotResolvedObjectType getSupertype(); - - @Override - HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType); - - @Override - default boolean isPrimitive() { - return false; - } - - @Override - default JavaKind getJavaKind() { - return JavaKind.Object; - } - - ConstantPool getConstantPool(); - - /** - * Gets the instance size of this type. If an instance of this type cannot be fast path - * allocated, then the returned value is negative (its absolute value gives the size). Must not - * be called if this is an array or interface type. - */ - int instanceSize(); - - int getVtableLength(); - - @Override - AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method); - - /** - * Performs a fast-path check that this type is resolved in the context of a given accessing - * class. A negative result does not mean this type is not resolved with respect to - * {@code accessingClass}. That can only be determined by - * {@linkplain HotSpotJVMCIRuntime#lookupType(String, HotSpotResolvedObjectType, boolean) - * re-resolving} the type. - */ - boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass); - - /** - * Gets the metaspace Klass boxed in a {@link JavaConstant}. - */ - Constant klass(); - - boolean isPrimaryType(); - - int superCheckOffset(); - - long prototypeMarkWord(); - - int layoutHelper(); - - @Override - HotSpotResolvedObjectType getEnclosingType(); - - @Override - ResolvedJavaMethod getClassInitializer(); - - /** - * Gets the fingerprint for this type. - * - * @return the value of the fingerprint ({@code 0} for arrays and synthetic classes or if the VM - * does not support fingerprints) - */ - long getFingerprint(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.hotspot; - -import static java.util.Objects.requireNonNull; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Modifier; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.vm.ci.meta.Assumptions.AssumptionResult; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * Implementation of {@link JavaType} for primitive HotSpot types. - */ -public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType { - - @NativeImageReinitialize static HotSpotResolvedPrimitiveType[] primitives; - - private JavaKind kind; - HotSpotObjectConstantImpl mirror; - - /** - * Creates the JVMCI mirror for a primitive {@link JavaKind}. - * - * @param kind the Kind to create the mirror for - */ - private HotSpotResolvedPrimitiveType(JavaKind kind, HotSpotObjectConstantImpl mirror) { - super(String.valueOf(kind.getTypeChar())); - this.mirror = mirror; - this.kind = kind; - } - - static HotSpotResolvedPrimitiveType forKind(JavaKind kind) { - HotSpotResolvedPrimitiveType primitive = primitives[kind.getBasicType()]; - assert primitive != null : kind; - return primitive; - } - - @VMEntryPoint - static HotSpotResolvedPrimitiveType fromMetaspace(HotSpotObjectConstantImpl mirror, char typeChar) { - JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(typeChar); - if (primitives == null) { - primitives = new HotSpotResolvedPrimitiveType[JavaKind.Void.getBasicType() + 1]; - } - HotSpotResolvedPrimitiveType result = new HotSpotResolvedPrimitiveType(kind, mirror); - primitives[kind.getBasicType()] = result; - return result; - } - - @Override - public int getModifiers() { - return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; - } - - @Override - public HotSpotResolvedObjectType getArrayClass() { - if (kind == JavaKind.Void) { - return null; - } - return super.getArrayClass(); - } - - @Override - public ResolvedJavaType getElementalType() { - return this; - } - - @Override - public ResolvedJavaType getComponentType() { - return null; - } - - @Override - public ResolvedJavaType getSuperclass() { - return null; - } - - @Override - public ResolvedJavaType[] getInterfaces() { - return new ResolvedJavaType[0]; - } - - @Override - public ResolvedJavaType getSingleImplementor() { - throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this); - } - - @Override - public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) { - return null; - } - - @Override - public AssumptionResult hasFinalizableSubclass() { - return new AssumptionResult<>(false); - } - - @Override - public boolean hasFinalizer() { - return false; - } - - @Override - public boolean isArray() { - return false; - } - - @Override - public boolean isEnum() { - return false; - } - - @Override - public boolean isPrimitive() { - return true; - } - - @Override - public boolean isInitialized() { - return true; - } - - @Override - public boolean isBeingInitialized() { - return false; - } - - @Override - public boolean isLinked() { - return true; - } - - @Override - public boolean isInstance(JavaConstant obj) { - return false; - } - - @Override - public boolean isInstanceClass() { - return false; - } - - @Override - public boolean isInterface() { - return false; - } - - @Override - public boolean isAssignableFrom(ResolvedJavaType other) { - assert other != null; - return other.equals(this); - } - - @Override - public JavaKind getJavaKind() { - return kind; - } - - @Override - public boolean isJavaLangObject() { - return false; - } - - @Override - public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { - return null; - } - - @Override - public String toString() { - return "HotSpotResolvedPrimitiveType<" + kind + ">"; - } - - @Override - public AssumptionResult findLeafConcreteSubtype() { - return new AssumptionResult<>(this); - } - - @Override - public AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method) { - return null; - } - - @Override - public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { - return new ResolvedJavaField[0]; - } - - @Override - public ResolvedJavaField[] getStaticFields() { - return new ResolvedJavaField[0]; - } - - @Override - public Annotation[] getAnnotations() { - return new Annotation[0]; - } - - @Override - public Annotation[] getDeclaredAnnotations() { - return new Annotation[0]; - } - - @Override - public T getAnnotation(Class annotationClass) { - return null; - } - - @Override - public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - requireNonNull(accessingClass); - return this; - } - - @Override - public void initialize() { - } - - @Override - public void link() { - } - - @Override - public boolean hasDefaultMethods() { - return false; - } - - @Override - public boolean declaresDefaultMethods() { - return false; - } - - @Override - public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedType) { - return null; - } - - @Override - public String getSourceFileName() { - throw JVMCIError.unimplemented(); - } - - @Override - public boolean isLocal() { - return false; - } - - @Override - public boolean isMember() { - return false; - } - - @Override - public ResolvedJavaType getEnclosingType() { - return null; - } - - @Override - public ResolvedJavaMethod[] getDeclaredConstructors() { - return new ResolvedJavaMethod[0]; - } - - @Override - public ResolvedJavaMethod[] getDeclaredMethods() { - return new ResolvedJavaMethod[0]; - } - - @Override - public ResolvedJavaMethod getClassInitializer() { - return null; - } - - @Override - public boolean isCloneableWithAllocation() { - return false; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof HotSpotResolvedPrimitiveType)) { - return false; - } - HotSpotResolvedPrimitiveType that = (HotSpotResolvedPrimitiveType) obj; - return that.kind == kind; - } - - @Override - JavaConstant getJavaMirror() { - return mirror; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.InstalledCode; -import jdk.vm.ci.code.InvalidInstalledCodeException; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * Implementation of {@link InstalledCode} for code installed as a {@code RuntimeStub}. The address - * of the {@code RuntimeStub} is stored in {@link InstalledCode#address} and the value of - * {@code RuntimeStub::entry_point()} is in {@link InstalledCode#entryPoint}. - */ -public class HotSpotRuntimeStub extends HotSpotInstalledCode { - - public HotSpotRuntimeStub(String name) { - super(name); - } - - public ResolvedJavaMethod getMethod() { - return null; - } - - @Override - public boolean isValid() { - return true; - } - - @Override - public void invalidate() { - } - - @Override - public String toString() { - return String.format("InstalledRuntimeStub[stub=%s, codeBlob=0x%x]", name, getAddress()); - } - - @Override - public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { - throw new InternalError("Cannot call stub " + name); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.VMConstant; -import jdk.vm.ci.meta.Value; -import jdk.vm.ci.meta.ValueKind; - -public final class HotSpotSentinelConstant extends Value implements JavaConstant, VMConstant { - - private final JavaKind javaKind; - - public HotSpotSentinelConstant(ValueKind valueKind, JavaKind javaKind) { - super(valueKind); - this.javaKind = javaKind; - } - - @Override - public JavaKind getJavaKind() { - return javaKind; - } - - @Override - public boolean isNull() { - return true; - } - - @Override - public boolean isDefaultForKind() { - return true; - } - - @Override - public Object asBoxedPrimitive() { - throw new IllegalArgumentException(); - } - - @Override - public int asInt() { - throw new IllegalArgumentException(); - } - - @Override - public boolean asBoolean() { - throw new IllegalArgumentException(); - } - - @Override - public long asLong() { - throw new IllegalArgumentException(); - } - - @Override - public float asFloat() { - throw new IllegalArgumentException(); - } - - @Override - public double asDouble() { - throw new IllegalArgumentException(); - } - - @Override - public String toString() { - return JavaConstant.toString(this); - } - - @Override - public String toValueString() { - return "sentinel"; - } - - @Override - public int hashCode() { - return 13; - } - - @Override - public boolean equals(Object o) { - return o instanceof HotSpotSentinelConstant; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.util.ArrayList; -import java.util.List; - -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; -import jdk.vm.ci.meta.UnresolvedJavaType; - -/** - * Represents a method signature. - */ -public class HotSpotSignature implements Signature { - - private final List parameters = new ArrayList<>(); - private final String returnType; - private final String originalString; - private ResolvedJavaType[] parameterTypes; - private ResolvedJavaType returnTypeCache; - private final HotSpotJVMCIRuntime runtime; - - public HotSpotSignature(HotSpotJVMCIRuntime runtime, String signature) { - this.runtime = runtime; - if (signature.length() == 0) { - throw new IllegalArgumentException("Signature cannot be empty"); - } - this.originalString = signature; - - if (signature.charAt(0) == '(') { - int cur = 1; - while (cur < signature.length() && signature.charAt(cur) != ')') { - int nextCur = parseSignature(signature, cur); - parameters.add(signature.substring(cur, nextCur)); - cur = nextCur; - } - - cur++; - int nextCur = parseSignature(signature, cur); - returnType = signature.substring(cur, nextCur); - if (nextCur != signature.length()) { - throw new IllegalArgumentException("Extra characters at end of signature: " + signature); - } - } else { - throw new IllegalArgumentException("Signature must start with a '(': " + signature); - } - } - - public HotSpotSignature(HotSpotJVMCIRuntime runtime, ResolvedJavaType returnType, ResolvedJavaType... parameterTypes) { - this.runtime = runtime; - this.parameterTypes = parameterTypes.clone(); - this.returnTypeCache = returnType; - this.returnType = returnType.getName(); - StringBuilder sb = new StringBuilder("("); - for (JavaType type : parameterTypes) { - parameters.add(type.getName()); - sb.append(type.getName()); - } - sb.append(")").append(returnType.getName()); - this.originalString = sb.toString(); - assert new HotSpotSignature(runtime, originalString).equals(this); - } - - private static int parseSignature(String signature, int start) { - try { - int cur = start; - char first; - do { - first = signature.charAt(cur); - cur++; - } while (first == '['); - - switch (first) { - case 'L': - while (signature.charAt(cur) != ';') { - if (signature.charAt(cur) == '.') { - throw new IllegalArgumentException("Class name in signature contains '.' at index " + cur + ": " + signature); - } - cur++; - } - cur++; - break; - case 'V': - case 'I': - case 'B': - case 'C': - case 'D': - case 'F': - case 'J': - case 'S': - case 'Z': - break; - default: - throw new IllegalArgumentException("Invalid character '" + signature.charAt(cur - 1) + "' at index " + (cur - 1) + " in signature: " + signature); - } - return cur; - } catch (StringIndexOutOfBoundsException e) { - throw new IllegalArgumentException("Truncated signature: " + signature); - } - } - - @Override - public int getParameterCount(boolean withReceiver) { - return parameters.size() + (withReceiver ? 1 : 0); - } - - @Override - public JavaKind getParameterKind(int index) { - return JavaKind.fromTypeString(parameters.get(index)); - } - - private static boolean checkValidCache(ResolvedJavaType type, ResolvedJavaType accessingClass) { - assert accessingClass != null; - if (type == null) { - return false; - } else if (type instanceof HotSpotResolvedObjectTypeImpl) { - return ((HotSpotResolvedObjectTypeImpl) type).isDefinitelyResolvedWithRespectTo(accessingClass); - } - return true; - } - - private static JavaType getUnresolvedOrPrimitiveType(HotSpotJVMCIRuntime runtime, String name) { - if (name.length() == 1) { - JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); - return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(kind.toJavaClass()); - } - return UnresolvedJavaType.create(name); - } - - @Override - public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { - if (accessingClass == null) { - // Caller doesn't care about resolution context so return an unresolved - // or primitive type (primitive type resolution is context free) - return getUnresolvedOrPrimitiveType(runtime, parameters.get(index)); - } - if (parameterTypes == null) { - parameterTypes = new ResolvedJavaType[parameters.size()]; - } - - ResolvedJavaType type = parameterTypes[index]; - if (!checkValidCache(type, accessingClass)) { - JavaType result = runtime.lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false); - if (result instanceof ResolvedJavaType) { - type = (ResolvedJavaType) result; - parameterTypes[index] = type; - } else { - assert result != null; - return result; - } - } - assert type != null; - return type; - } - - @Override - public String toMethodDescriptor() { - assert originalString.equals(Signature.super.toMethodDescriptor()) : originalString + " != " + Signature.super.toMethodDescriptor(); - return originalString; - } - - @Override - public JavaKind getReturnKind() { - return JavaKind.fromTypeString(returnType); - } - - @Override - public JavaType getReturnType(ResolvedJavaType accessingClass) { - if (accessingClass == null) { - // Caller doesn't care about resolution context so return an unresolved - // or primitive type (primitive type resolution is context free) - return getUnresolvedOrPrimitiveType(runtime, returnType); - } - if (!checkValidCache(returnTypeCache, accessingClass)) { - JavaType result = runtime.lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false); - if (result instanceof ResolvedJavaType) { - returnTypeCache = (ResolvedJavaType) result; - } else { - return result; - } - } - return returnTypeCache; - } - - @Override - public String toString() { - return "HotSpotSignature<" + originalString + ">"; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof HotSpotSignature) { - HotSpotSignature other = (HotSpotSignature) obj; - if (other.originalString.equals(originalString)) { - assert other.parameters.equals(parameters); - assert other.returnType.equals(returnType); - return true; - } - } - return false; - } - - @Override - public int hashCode() { - return originalString.hashCode(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.SpeculationLog.SpeculationReasonEncoding; - -/** - * Implements a {@link SpeculationReasonEncoding} that {@linkplain #getByteArray() produces} a byte - * array. Data is added via a {@link DataOutputStream}. When producing the final byte array, if the - * total length of data exceeds {@value HotSpotSpeculationEncoding#MAX_LENGTH}, then a SHA-1 digest - * of the data is produced instead. - */ -final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements SpeculationReasonEncoding { - - /** - * Number of bits used for the length of an encoded speculation. The bit size of 5 is chosen to - * accommodate specifying // the length of a SHA-1 digest (i.e., 20 bytes). - */ - // Also defined in C++ JVMCINMethodData class - keep in sync. - static final int LENGTH_BITS = 5; - - /** - * The maximum length of an encoded speculation. - */ - static final int MAX_LENGTH = (1 << LENGTH_BITS) - 1; - - static final int LENGTH_MASK = MAX_LENGTH; - - private DataOutputStream dos = new DataOutputStream(this); - private byte[] result; - - HotSpotSpeculationEncoding() { - super(SHA1_LENGTH); - } - - private void checkOpen() { - if (result != null) { - throw new IllegalArgumentException("Cannot update closed speculation encoding"); - } - } - - private static final int NULL_METHOD = -1; - private static final int NULL_TYPE = -2; - private static final int NULL_STRING = -3; - - @Override - public void addByte(int value) { - checkOpen(); - try { - dos.writeByte(value); - } catch (IOException e) { - throw new InternalError(e); - } - } - - @Override - public void addShort(int value) { - checkOpen(); - try { - dos.writeShort(value); - } catch (IOException e) { - throw new InternalError(e); - } - } - - @Override - public void addMethod(ResolvedJavaMethod method) { - if (!addNull(method, NULL_METHOD)) { - checkOpen(); - if (method instanceof HotSpotResolvedJavaMethodImpl) { - try { - dos.writeLong(((HotSpotResolvedJavaMethodImpl) method).getMetaspaceMethod()); - } catch (IOException e) { - throw new InternalError(e); - } - } else { - throw new IllegalArgumentException("Cannot encode unsupported type " + method.getClass().getName() + ": " + method.format("%H.%n(%p)")); - } - } - } - - @Override - public void addType(ResolvedJavaType type) { - if (!addNull(type, NULL_TYPE)) { - checkOpen(); - if (type instanceof HotSpotResolvedObjectTypeImpl) { - try { - dos.writeLong(((HotSpotResolvedObjectTypeImpl) type).getMetaspaceKlass()); - } catch (IOException e) { - throw new InternalError(e); - } - } else { - throw new IllegalArgumentException("Cannot encode unsupported type " + type.getClass().getName() + ": " + type.toClassName()); - } - } - } - - @Override - public void addString(String value) { - if (!addNull(value, NULL_STRING)) { - checkOpen(); - try { - dos.writeChars(value); - } catch (IOException e) { - throw new InternalError(e); - } - } - } - - @Override - public void addInt(int value) { - checkOpen(); - try { - dos.writeInt(value); - } catch (IOException e) { - throw new InternalError(e); - } - } - - @Override - public void addLong(long value) { - checkOpen(); - try { - dos.writeLong(value); - } catch (IOException e) { - throw new InternalError(e); - } - } - - private boolean addNull(Object o, int nullValue) { - if (o == null) { - addInt(nullValue); - return true; - } - return false; - } - - /** - * Prototype SHA1 digest. - */ - private static final MessageDigest SHA1; - - /** - * Cloning the prototype is quicker than calling {@link MessageDigest#getInstance(String)} every - * time. - */ - private static final boolean SHA1_IS_CLONEABLE; - private static final int SHA1_LENGTH = 20; - - static { - MessageDigest sha1 = null; - boolean sha1IsCloneable = false; - try { - sha1 = MessageDigest.getInstance("SHA-1"); - sha1.clone(); - sha1IsCloneable = true; - } catch (NoSuchAlgorithmException e) { - // Should never happen given that SHA-1 is mandated in a - // compliant Java platform implementation. - throw new JVMCIError(e); - } catch (CloneNotSupportedException e) { - } - SHA1 = sha1; - SHA1_IS_CLONEABLE = sha1IsCloneable; - assert SHA1.getDigestLength() == SHA1_LENGTH; - assert SHA1_LENGTH < MAX_LENGTH; - } - - /** - * Gets the final encoded byte array and closes this encoding such that any further attempts to - * update it result in an {@link IllegalArgumentException}. - */ - byte[] getByteArray() { - if (result == null) { - if (count > MAX_LENGTH) { - try { - MessageDigest md = SHA1_IS_CLONEABLE ? (MessageDigest) SHA1.clone() : MessageDigest.getInstance("SHA-1"); - md.update(buf, 0, count); - result = md.digest(); - } catch (CloneNotSupportedException | NoSuchAlgorithmException e) { - throw new InternalError(e); - } - } else { - if (buf.length == count) { - // No need to copy the byte array - return buf; - } - result = Arrays.copyOf(buf, count); - } - dos = null; - } - return result; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2014, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Formatter; -import java.util.List; - -import jdk.vm.ci.code.BailoutException; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.SpeculationLog; - -/** - * Implements a {@link SpeculationLog} that can be used to: - *
      - *
    • Query failed speculations recorded in a native linked list of {@code FailedSpeculation}s (see - * methodData.hpp).
    • - *
    • Make speculations during compilation and record them in compiled code. This must only be done - * on compilation-local {@link HotSpotSpeculationLog} objects.
    • - *
    - * - * The choice of constructor determines whether the native failed speculations list is - * {@linkplain #managesFailedSpeculations() managed} by a {@link HotSpotSpeculationLog} object. - */ -public class HotSpotSpeculationLog implements SpeculationLog { - - private static final byte[] NO_FLATTENED_SPECULATIONS = {}; - - /** - * Creates a speculation log that manages a failed speculation list. That is, when this object - * dies, the native resources of the list are freed. - * - * @see #managesFailedSpeculations() - * @see #getFailedSpeculationsAddress() - */ - public HotSpotSpeculationLog() { - managesFailedSpeculations = true; - } - - /** - * Creates a speculation log that reads from an externally managed failed speculation list. That - * is, the lifetime of the list is independent of this object. - * - * @param failedSpeculationsAddress an address in native memory at which the pointer to the - * externally managed sailed speculation list resides - */ - public HotSpotSpeculationLog(long failedSpeculationsAddress) { - if (failedSpeculationsAddress == 0) { - throw new IllegalArgumentException("failedSpeculationsAddress cannot be 0"); - } - this.failedSpeculationsAddress = failedSpeculationsAddress; - managesFailedSpeculations = false; - } - - /** - * Gets the address of the pointer to the native failed speculations list. - * - * @see #managesFailedSpeculations() - */ - public long getFailedSpeculationsAddress() { - if (managesFailedSpeculations) { - synchronized (this) { - if (failedSpeculationsAddress == 0L) { - failedSpeculationsAddress = UnsafeAccess.UNSAFE.allocateMemory(HotSpotJVMCIRuntime.getHostWordKind().getByteCount()); - UnsafeAccess.UNSAFE.putAddress(failedSpeculationsAddress, 0L); - LogCleaner c = new LogCleaner(this, failedSpeculationsAddress); - assert c.address == failedSpeculationsAddress; - } - } - } - return failedSpeculationsAddress; - } - - /** - * Adds {@code speculation} to the native list of failed speculations. To update this object's - * view of the failed speculations, {@link #collectFailedSpeculations()} must be called after - * this method returns. - * - * This method exists primarily for testing purposes. Speculations are normally only added to - * the list by HotSpot during deoptimization. - * - * @return {@code false} if the speculation could not be appended to the list - */ - public boolean addFailedSpeculation(Speculation speculation) { - return compilerToVM().addFailedSpeculation(getFailedSpeculationsAddress(), ((HotSpotSpeculation) speculation).encoding); - } - - /** - * Returns {@code true} if the value returned by {@link #getFailedSpeculationsAddress()} is only - * valid only as long as this object is alive, {@code false} otherwise. - */ - public boolean managesFailedSpeculations() { - return managesFailedSpeculations; - } - - public static final class HotSpotSpeculation extends Speculation { - - /** - * A speculation id is a long encoding a length (low 5 bits) and an index into a - * {@code byte[]}. Combined, the index and length denote where the {@linkplain #encoding - * encoded speculation} is in a {@linkplain HotSpotSpeculationLog#getFlattenedSpeculations - * flattened} speculations array. - */ - private final JavaConstant id; - - private final byte[] encoding; - - HotSpotSpeculation(SpeculationReason reason, JavaConstant id, byte[] encoding) { - super(reason); - this.id = id; - this.encoding = encoding; - } - - public JavaConstant getEncoding() { - return id; - } - - @Override - public String toString() { - long indexAndLength = id.asLong(); - int index = decodeIndex(indexAndLength); - int length = decodeLength(indexAndLength); - return String.format("{0x%016x[index: %d, len: %d, hash: 0x%x]: %s}", indexAndLength, index, length, Arrays.hashCode(encoding), getReason()); - } - } - - /** - * Address of a pointer to a set of failed speculations. The address is recorded in the nmethod - * compiled with this speculation log such that when it fails a speculation, the speculation is - * added to the list. - */ - private long failedSpeculationsAddress; - - private final boolean managesFailedSpeculations; - - /** - * The list of failed speculations read from native memory via - * {@link CompilerToVM#getFailedSpeculations}. - */ - private byte[][] failedSpeculations; - - /** - * Speculations made during the compilation associated with this log. - */ - private List speculations; - private List speculationReasons; - - @Override - public void collectFailedSpeculations() { - if (failedSpeculationsAddress != 0 && UnsafeAccess.UNSAFE.getLong(failedSpeculationsAddress) != 0) { - failedSpeculations = compilerToVM().getFailedSpeculations(failedSpeculationsAddress, failedSpeculations); - assert failedSpeculations.getClass() == byte[][].class; - } - } - - byte[] getFlattenedSpeculations(boolean validate) { - if (speculations == null) { - return NO_FLATTENED_SPECULATIONS; - } - if (validate) { - int newFailuresStart = failedSpeculations == null ? 0 : failedSpeculations.length; - collectFailedSpeculations(); - if (failedSpeculations != null && failedSpeculations.length != newFailuresStart) { - for (SpeculationReason reason : speculationReasons) { - byte[] encoding = encode(reason); - // Only check against new failures - if (contains(failedSpeculations, newFailuresStart, encoding)) { - throw new BailoutException(false, "Speculation failed: " + reason); - } - } - } - } - int size = 0; - for (byte[] s : speculations) { - size += s.length; - } - byte[] result = new byte[size]; - size = 0; - for (byte[] s : speculations) { - System.arraycopy(s, 0, result, size, s.length); - size += s.length; - } - return result; - } - - @Override - public boolean maySpeculate(SpeculationReason reason) { - if (failedSpeculations == null) { - collectFailedSpeculations(); - } - if (failedSpeculations != null && failedSpeculations.length != 0) { - byte[] encoding = encode(reason); - return !contains(failedSpeculations, 0, encoding); - } - return true; - } - - /** - * @return {@code true} if {@code needle} is in {@code haystack[fromIndex..haystack.length-1]} - */ - private static boolean contains(byte[][] haystack, int fromIndex, byte[] needle) { - for (int i = fromIndex; i < haystack.length; i++) { - byte[] fs = haystack[i]; - - if (Arrays.equals(fs, needle)) { - return true; - } - } - return false; - } - - private static long encodeIndexAndLength(int index, int length) { - if (length > HotSpotSpeculationEncoding.MAX_LENGTH || length < 0) { - throw new InternalError(String.format("Invalid encoded speculation length: %d (0x%x)", length, length)); - } - if (index < 0) { - throw new JVMCIError("Encoded speculation index is negative: %d (0x%x)", index, index); - } - return (index << HotSpotSpeculationEncoding.LENGTH_BITS) | length; - } - - private static int decodeIndex(long indexAndLength) { - return (int) (indexAndLength >>> HotSpotSpeculationEncoding.LENGTH_BITS); - } - - private static int decodeLength(long indexAndLength) { - return (int) (indexAndLength & HotSpotSpeculationEncoding.LENGTH_MASK); - } - - @Override - public Speculation speculate(SpeculationReason reason) { - byte[] encoding = encode(reason); - JavaConstant id; - if (speculations == null) { - speculations = new ArrayList<>(); - speculationReasons = new ArrayList<>(); - id = JavaConstant.forLong(encodeIndexAndLength(0, encoding.length)); - speculations.add(encoding); - speculationReasons.add(reason); - } else { - id = null; - int flattenedIndex = 0; - for (byte[] fs : speculations) { - if (Arrays.equals(fs, encoding)) { - id = JavaConstant.forLong(encodeIndexAndLength(flattenedIndex, fs.length)); - break; - } - flattenedIndex += fs.length; - } - if (id == null) { - id = JavaConstant.forLong(encodeIndexAndLength(flattenedIndex, encoding.length)); - speculations.add(encoding); - speculationReasons.add(reason); - } - } - - return new HotSpotSpeculation(reason, id, encoding); - } - - private static byte[] encode(SpeculationReason reason) { - HotSpotSpeculationEncoding encoding = (HotSpotSpeculationEncoding) reason.encode(HotSpotSpeculationEncoding::new); - byte[] result = encoding == null ? null : encoding.getByteArray(); - if (result == null) { - throw new IllegalArgumentException(HotSpotSpeculationLog.class.getName() + " expects " + reason.getClass().getName() + ".encode() to return a non-empty encoding"); - } - return result; - } - - @Override - public boolean hasSpeculations() { - return speculations != null; - } - - @Override - public Speculation lookupSpeculation(JavaConstant constant) { - if (constant.isDefaultForKind()) { - return NO_SPECULATION; - } - int flattenedIndex = decodeIndex(constant.asLong()); - int index = 0; - for (byte[] s : speculations) { - if (flattenedIndex == 0) { - SpeculationReason reason = speculationReasons.get(index); - return new HotSpotSpeculation(reason, constant, s); - } - index++; - flattenedIndex -= s.length; - } - throw new IllegalArgumentException("Unknown encoded speculation: " + constant); - } - - @Override - public String toString() { - Formatter buf = new Formatter(); - buf.format("{managed:%s, failedSpeculationsAddress:0x%x, failedSpeculations:[", managesFailedSpeculations, failedSpeculationsAddress); - - String sep = ""; - if (failedSpeculations != null) { - for (int i = 0; i < failedSpeculations.length; i++) { - buf.format("%s{len:%d, hash:0x%x}", sep, failedSpeculations[i].length, Arrays.hashCode(failedSpeculations[i])); - sep = ", "; - } - } - - buf.format("], speculations:["); - - int size = 0; - if (speculations != null) { - sep = ""; - for (int i = 0; i < speculations.size(); i++) { - byte[] s = speculations.get(i); - size += s.length; - buf.format("%s{len:%d, hash:0x%x, reason:{%s}}", sep, s.length, Arrays.hashCode(s), speculationReasons.get(i)); - sep = ", "; - } - } - buf.format("], len:%d, hash:0x%x}", size, Arrays.hashCode(getFlattenedSpeculations(false))); - return buf.toString(); - } - - /** - * Frees the native memory resources associated with {@link HotSpotSpeculationLog}s once they - * become reclaimable. - */ - private static final class LogCleaner extends Cleaner { - - LogCleaner(HotSpotSpeculationLog referent, long address) { - super(referent); - this.address = address; - } - - @Override - void doCleanup() { - long pointer = UnsafeAccess.UNSAFE.getAddress(address); - if (pointer != 0) { - compilerToVM().releaseFailedSpeculations(address); - } - UnsafeAccess.UNSAFE.freeMemory(address); - } - - final long address; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.util.Arrays; - -import jdk.vm.ci.code.stack.InspectedFrame; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -public class HotSpotStackFrameReference implements InspectedFrame { - - private CompilerToVM compilerToVM; - // set in the VM when materializeVirtualObjects is called - @SuppressWarnings("unused") private boolean objectsMaterialized; - - // information used to find the stack frame - private long stackPointer; - private int frameNumber; - - // information about the stack frame's contents - private int bci; - private HotSpotResolvedJavaMethod method; - private Object[] locals; - private boolean[] localIsVirtual; - - public long getStackPointer() { - return stackPointer; - } - - public int getFrameNumber() { - return frameNumber; - } - - @Override - public Object getLocal(int index) { - return locals[index]; - } - - @Override - public boolean isVirtual(int index) { - return localIsVirtual == null ? false : localIsVirtual[index]; - } - - @Override - public void materializeVirtualObjects(boolean invalidateCode) { - compilerToVM.materializeVirtualObjects(this, invalidateCode); - } - - @Override - public int getBytecodeIndex() { - return bci; - } - - @Override - public ResolvedJavaMethod getMethod() { - return method; - } - - @Override - public boolean isMethod(ResolvedJavaMethod otherMethod) { - return method.equals(otherMethod); - } - - @Override - public boolean hasVirtualObjects() { - return localIsVirtual != null; - } - - @Override - public String toString() { - return "HotSpotStackFrameReference [stackPointer=" + stackPointer + ", frameNumber=" + frameNumber + ", bci=" + bci + ", method=" + getMethod() + ", locals=" + Arrays.toString(locals) + - ", localIsVirtual=" + Arrays.toString(localIsVirtual) + "]"; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.stack.InspectedFrameVisitor; -import jdk.vm.ci.code.stack.StackIntrospection; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -public class HotSpotStackIntrospection implements StackIntrospection { - - protected final HotSpotJVMCIRuntime runtime; - - public HotSpotStackIntrospection(HotSpotJVMCIRuntime runtime) { - this.runtime = runtime; - } - - @Override - public T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor visitor) { - CompilerToVM compilerToVM = runtime.getCompilerToVM(); - return compilerToVM.iterateFrames(initialMethods, matchingMethods, initialSkip, visitor); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2016, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.util.Set; -import java.util.stream.Collectors; - -import jdk.vm.ci.common.JVMCIError; - -/** - * Access to VM configuration data. - */ -public class HotSpotVMConfigAccess { - - /** - * Gets the available configuration data. - */ - public HotSpotVMConfigStore getStore() { - return store; - } - - /** - * Gets the address of a C++ symbol. - * - * @param name name of C++ symbol - * @param notPresent if non-null and the symbol is not present then this value is returned - * @return the address of the symbol - * @throws JVMCIError if the symbol is not present and {@code notPresent == null} - */ - public long getAddress(String name, Long notPresent) { - Long entry = store.vmAddresses.get(name); - if (entry == null) { - if (notPresent != null) { - return notPresent; - } - throw missingEntry("address", name, store.vmFlags.keySet()); - - } - return entry; - } - - /** - * Gets the address of a C++ symbol. - * - * @param name name of C++ symbol - * @return the address of the symbol - * @throws JVMCIError if the symbol is not present - */ - public long getAddress(String name) { - return getAddress(name, null); - } - - /** - * Gets the value of a C++ constant. - * - * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) - * @param type the boxed type to which the constant value will be converted - * @param notPresent if non-null and the constant is not present then this value is returned - * @return the constant value converted to {@code type} - * @throws JVMCIError if the constant is not present and {@code notPresent == null} - */ - public T getConstant(String name, Class type, T notPresent) { - Long c = store.vmConstants.get(name); - if (c == null) { - if (notPresent != null) { - return notPresent; - } - throw missingEntry("constant", name, store.vmConstants.keySet()); - } - return type.cast(convertValue(name, type, c, null)); - } - - /** - * Gets the value of a C++ constant. - * - * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) - * @param type the boxed type to which the constant value will be converted - * @return the constant value converted to {@code type} - * @throws JVMCIError if the constant is not present - */ - public T getConstant(String name, Class type) { - return getConstant(name, type, null); - } - - /** - * Gets the offset of a non-static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the offset value will be converted (must be - * {@link Integer} or {@link Long}) - * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) - * @param notPresent if non-null and the field is not present then this value is returned - * @return the offset in bytes of the requested field - * @throws JVMCIError if the field is static or not present and {@code notPresent} is null - */ - public T getFieldOffset(String name, Class type, String cppType, T notPresent) { - return getFieldOffset0(name, type, notPresent, cppType, null); - } - - /** - * Gets the offset of a non-static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the offset value will be converted (must be - * {@link Integer} or {@link Long}) - * @param notPresent if non-null and the field is not present then this value is returned - * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is - * returned in element 0 of this array - * @return the offset in bytes of the requested field - * @throws JVMCIError if the field is static or not present and {@code notPresent} is null - */ - public T getFieldOffset(String name, Class type, T notPresent, String[] outCppType) { - return getFieldOffset0(name, type, notPresent, null, outCppType); - } - - /** - * Gets the offset of a non-static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the offset value will be converted (must be - * {@link Integer} or {@link Long}) - * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) - * @return the offset in bytes of the requested field - * @throws JVMCIError if the field is static or not present - */ - public T getFieldOffset(String name, Class type, String cppType) { - return getFieldOffset0(name, type, null, cppType, null); - } - - /** - * Gets the offset of a non-static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the offset value will be converted (must be - * {@link Integer} or {@link Long}) - * @return the offset in bytes of the requested field - * @throws JVMCIError if the field is static or not present - */ - public T getFieldOffset(String name, Class type) { - return getFieldOffset0(name, type, null, null, null); - } - - private T getFieldOffset0(String name, Class type, T notPresent, String inCppType, String[] outCppType) { - assert type == Integer.class || type == Long.class; - VMField entry = getField(name, inCppType, notPresent == null); - if (entry == null) { - return notPresent; - } - if (entry.address != 0) { - throw new JVMCIError("cannot get offset of static field " + name); - } - if (outCppType != null) { - outCppType[0] = entry.type; - } - return type.cast(convertValue(name, type, entry.offset, inCppType)); - } - - /** - * Gets the address of a static C++ field. - * - * @param name fully qualified name of the field - * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) - * @param notPresent if non-null and the field is not present then this value is returned - * @return the address of the requested field - * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null - */ - public long getFieldAddress(String name, String cppType, Long notPresent) { - return getFieldAddress0(name, notPresent, cppType, null); - } - - /** - * Gets the address of a static C++ field. - * - * @param name fully qualified name of the field - * @param notPresent if non-null and the field is not present then this value is returned - * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is - * returned in element 0 of this array - * @return the address of the requested field - * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null - */ - public long getFieldAddress(String name, Long notPresent, String[] outCppType) { - return getFieldAddress0(name, notPresent, null, outCppType); - } - - /** - * Gets the address of a static C++ field. - * - * @param name fully qualified name of the field - * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) - * @return the address of the requested field - * @throws JVMCIError if the field is not static or not present - */ - public long getFieldAddress(String name, String cppType) { - return getFieldAddress0(name, null, cppType, null); - } - - private long getFieldAddress0(String name, Long notPresent, String inCppType, String[] outCppType) { - VMField entry = getField(name, inCppType, notPresent == null); - if (entry == null) { - return notPresent; - } - if (entry.address == 0) { - throw new JVMCIError(name + " is not a static field"); - } - if (outCppType != null) { - outCppType[0] = entry.type; - } - return entry.address; - } - - /** - * Gets the value of a static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the constant value will be converted - * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) - * @param notPresent if non-null and the field is not present then this value is returned - * @return the value of the requested field - * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null - */ - public T getFieldValue(String name, Class type, String cppType, T notPresent) { - return getFieldValue0(name, type, notPresent, cppType, null); - } - - /** - * Gets the value of a static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the constant value will be converted - * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) - * @return the value of the requested field - * @throws JVMCIError if the field is not static or not present - */ - public T getFieldValue(String name, Class type, String cppType) { - return getFieldValue0(name, type, null, cppType, null); - } - - /** - * Gets the value of a static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the constant value will be converted - * @param notPresent if non-null and the field is not present then this value is returned - * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is - * returned in element 0 of this array - * @return the value of the requested field - * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null - */ - public T getFieldValue(String name, Class type, T notPresent, String[] outCppType) { - return getFieldValue0(name, type, notPresent, null, outCppType); - } - - /** - * Gets the value of a static C++ field. - * - * @param name fully qualified name of the field - * @param type the boxed type to which the constant value will be converted - * @return the value of the requested field - * @throws JVMCIError if the field is not static or not present - */ - public T getFieldValue(String name, Class type) { - return getFieldValue0(name, type, null, null, null); - } - - private T getFieldValue0(String name, Class type, T notPresent, String inCppType, String[] outCppType) { - VMField entry = getField(name, inCppType, notPresent == null); - if (entry == null) { - return notPresent; - } - if (entry.value == null) { - throw new JVMCIError(name + " is not a static field "); - } - if (outCppType != null) { - outCppType[0] = entry.type; - } - return type.cast(convertValue(name, type, entry.value, inCppType)); - } - - /** - * Gets a C++ field. - * - * @param name fully qualified name of the field - * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) - * @param required specifies if the field must be present - * @return the field - * @throws JVMCIError if the field is not present and {@code required == true} - */ - private VMField getField(String name, String cppType, boolean required) { - VMField entry = store.vmFields.get(name); - if (entry == null) { - if (!required) { - return null; - } - throw missingEntry("field", name, store.vmFields.keySet()); - } - - // Make sure the native type is still the type we expect. - if (cppType != null && !cppType.equals(entry.type)) { - throw new JVMCIError("expected type " + cppType + " but VM field " + name + " is of type " + entry.type); - } - return entry; - } - - /** - * Gets a VM flag value. - * - * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) - * @param type the boxed type to which the flag's value will be converted - * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not - * present - * @throws JVMCIError if the flag is not present - */ - public T getFlag(String name, Class type) { - return getFlag(name, type, null); - } - - /** - * Gets a VM flag value. - * - * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) - * @param type the boxed type to which the flag's value will be converted - * @param notPresent if non-null and the flag is not present then this value is returned - * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not - * present - * @throws JVMCIError if the flag is not present and {@code notPresent == null} - */ - public T getFlag(String name, Class type, T notPresent) { - VMFlag entry = store.vmFlags.get(name); - Object value; - String cppType; - if (entry == null) { - // Fall back to VM call - value = store.compilerToVm.getFlagValue(name); - if (value == store.compilerToVm) { - if (notPresent != null) { - return notPresent; - } - throw missingEntry("flag", name, store.vmFlags.keySet()); - } else { - cppType = null; - } - } else { - value = entry.value; - cppType = entry.type; - } - return type.cast(convertValue(name, type, value, cppType)); - } - - private JVMCIError missingEntry(String category, String name, Set keys) { - throw new JVMCIError("expected VM %s not found in %s: %s%nAvailable values:%n %s", category, store, name, - keys.stream().sorted().collect(Collectors.joining(System.lineSeparator() + " "))); - } - - private static Object convertValue(String name, Class toType, Object value, String cppType) throws JVMCIError { - if (toType == Boolean.class) { - if (value instanceof String) { - return Boolean.valueOf((String) value); - } else if (value instanceof Boolean) { - return value; - } else if (value instanceof Long) { - return ((long) value) != 0; - } - } else if (toType == Byte.class) { - if (value instanceof Long) { - return (byte) (long) value; - } - } else if (toType == Integer.class) { - if (value instanceof Integer) { - return value; - } else if (value instanceof Long) { - return (int) (long) value; - } - } else if (toType == String.class) { - if (value == null || value instanceof String) { - return value; - } - } else if (toType == Long.class) { - return value; - } - - throw new JVMCIError("cannot convert " + name + " of type " + value.getClass().getSimpleName() + (cppType == null ? "" : " [" + cppType + "]") + " to " + toType.getSimpleName()); - } - - private final HotSpotVMConfigStore store; - - public HotSpotVMConfigAccess(HotSpotVMConfigStore store) { - this.store = store; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,402 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.services.Services; -import jdk.internal.misc.Unsafe; - -/** - * Used to access native configuration details. - * - * All non-static, public fields in this class are so that they can be compiled as constants. - */ -class HotSpotVMConfig extends HotSpotVMConfigAccess { - - /** - * Gets the configuration associated with the singleton {@link HotSpotJVMCIRuntime}. - */ - static HotSpotVMConfig config() { - return runtime().getConfig(); - } - - private final String osArch = getHostArchitectureName(); - - HotSpotVMConfig(HotSpotVMConfigStore store) { - super(store); - - int speculationLengthBits = getConstant("JVMCINMethodData::SPECULATION_LENGTH_BITS", Integer.class); - JVMCIError.guarantee(HotSpotSpeculationEncoding.LENGTH_BITS == speculationLengthBits, "%d != %d", HotSpotSpeculationEncoding.LENGTH_BITS, speculationLengthBits); - } - - /** - * Gets the host architecture name for the purpose of finding the corresponding - * {@linkplain HotSpotJVMCIBackendFactory backend}. - */ - String getHostArchitectureName() { - String arch = Services.getSavedProperty("os.arch"); - switch (arch) { - case "x86_64": - return "amd64"; - - default: - return arch; - } - } - - final boolean useDeferredInitBarriers = getFlag("ReduceInitialCardMarks", Boolean.class); - - final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class); - - final int objectAlignment = getFlag("ObjectAlignmentInBytes", Integer.class); - - final int hubOffset = getFieldOffset("oopDesc::_metadata._klass", Integer.class, "Klass*"); - - final int prototypeMarkWordOffset = getFieldOffset("Klass::_prototype_header", Integer.class, "markWord"); - final int subklassOffset = getFieldOffset("Klass::_subklass", Integer.class, "Klass*"); - final int superOffset = getFieldOffset("Klass::_super", Integer.class, "Klass*"); - final int nextSiblingOffset = getFieldOffset("Klass::_next_sibling", Integer.class, "Klass*"); - final int superCheckOffsetOffset = getFieldOffset("Klass::_super_check_offset", Integer.class, "juint"); - final int secondarySuperCacheOffset = getFieldOffset("Klass::_secondary_super_cache", Integer.class, "Klass*"); - - final int classLoaderDataOffset = getFieldOffset("Klass::_class_loader_data", Integer.class, "ClassLoaderData*"); - - /** - * The offset of the _java_mirror field (of type {@link Class}) in a Klass. - */ - final int javaMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle"); - - final int klassAccessFlagsOffset = getFieldOffset("Klass::_access_flags", Integer.class, "AccessFlags"); - final int klassLayoutHelperOffset = getFieldOffset("Klass::_layout_helper", Integer.class, "jint"); - - final int klassLayoutHelperNeutralValue = getConstant("Klass::_lh_neutral_value", Integer.class); - final int klassLayoutHelperInstanceSlowPathBit = getConstant("Klass::_lh_instance_slow_path_bit", Integer.class); - - final int vtableEntrySize = getFieldValue("CompilerToVM::Data::sizeof_vtableEntry", Integer.class, "int"); - final int vtableEntryMethodOffset = getFieldOffset("vtableEntry::_method", Integer.class, "Method*"); - - final int instanceKlassInitStateOffset = getFieldOffset("InstanceKlass::_init_state", Integer.class, "u1"); - final int instanceKlassConstantsOffset = getFieldOffset("InstanceKlass::_constants", Integer.class, "ConstantPool*"); - final int instanceKlassFieldsOffset = getFieldOffset("InstanceKlass::_fields", Integer.class, "Array*"); - final int instanceKlassAnnotationsOffset = getFieldOffset("InstanceKlass::_annotations", Integer.class, "Annotations*"); - final int instanceKlassMiscFlagsOffset = getFieldOffset("InstanceKlass::_misc_flags", Integer.class, "u2"); - final int klassVtableStartOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_start_offset", Integer.class, "int"); - final int klassVtableLengthOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_length_offset", Integer.class, "int"); - - final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class); - final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", Integer.class); - final int instanceKlassStateBeingInitialized = getConstant("InstanceKlass::being_initialized", Integer.class); - - final int annotationsFieldAnnotationsOffset = getFieldOffset("Annotations::_fields_annotations", Integer.class, "Array*"); - final int fieldsAnnotationsBaseOffset = getFieldValue("CompilerToVM::Data::_fields_annotations_base_offset", Integer.class, "int"); - - final int arrayU1LengthOffset = getFieldOffset("Array::_length", Integer.class, "int"); - final int arrayU1DataOffset = getFieldOffset("Array::_data", Integer.class); - final int arrayU2DataOffset = getFieldOffset("Array::_data", Integer.class); - - final int fieldInfoAccessFlagsOffset = getConstant("FieldInfo::access_flags_offset", Integer.class); - final int fieldInfoNameIndexOffset = getConstant("FieldInfo::name_index_offset", Integer.class); - final int fieldInfoSignatureIndexOffset = getConstant("FieldInfo::signature_index_offset", Integer.class); - final int fieldInfoConstantValueIndexOffset = getConstant("FieldInfo::initval_index_offset", Integer.class); - final int fieldInfoLowPackedOffset = getConstant("FieldInfo::low_packed_offset", Integer.class); - final int fieldInfoHighPackedOffset = getConstant("FieldInfo::high_packed_offset", Integer.class); - final int fieldInfoFieldSlots = getConstant("FieldInfo::field_slots", Integer.class); - - final int fieldInfoTagSize = getConstant("FIELDINFO_TAG_SIZE", Integer.class); - - final int jvmAccHasFinalizer = getConstant("JVM_ACC_HAS_FINALIZER", Integer.class); - final int jvmAccFieldInternal = getConstant("JVM_ACC_FIELD_INTERNAL", Integer.class); - final int jvmAccFieldStable = getConstant("JVM_ACC_FIELD_STABLE", Integer.class); - final int jvmAccFieldHasGenericSignature = getConstant("JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE", Integer.class); - final int jvmAccIsCloneableFast = getConstant("JVM_ACC_IS_CLONEABLE_FAST", Integer.class); - - // These modifiers are not public in Modifier so we get them via vmStructs. - final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class); - final int jvmAccAnnotation = getConstant("JVM_ACC_ANNOTATION", Integer.class); - final int jvmAccBridge = getConstant("JVM_ACC_BRIDGE", Integer.class); - final int jvmAccVarargs = getConstant("JVM_ACC_VARARGS", Integer.class); - final int jvmAccEnum = getConstant("JVM_ACC_ENUM", Integer.class); - final int jvmAccInterface = getConstant("JVM_ACC_INTERFACE", Integer.class); - - final int jvmMiscFlagsHasDefaultMethods = getConstant("InstanceKlass::_misc_has_nonstatic_concrete_methods", Integer.class); - final int jvmMiscFlagsDeclaresDefaultMethods = getConstant("InstanceKlass::_misc_declares_nonstatic_concrete_methods", Integer.class); - - // This is only valid on AMD64. - final int runtimeCallStackSize = getConstant("frame::arg_reg_save_area_bytes", Integer.class, osArch.equals("amd64") ? null : 0); - - private final int markWordNoHashInPlace = getConstant("markWord::no_hash_in_place", Integer.class); - private final int markWordNoLockInPlace = getConstant("markWord::no_lock_in_place", Integer.class); - - /** - * See {@code markWord::prototype()}. - */ - long arrayPrototypeMarkWord() { - return markWordNoHashInPlace | markWordNoLockInPlace; - } - - final int methodAccessFlagsOffset = getFieldOffset("Method::_access_flags", Integer.class, "AccessFlags"); - final int methodConstMethodOffset = getFieldOffset("Method::_constMethod", Integer.class, "ConstMethod*"); - final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2"); - final int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, "u2"); - final int methodVtableIndexOffset = getFieldOffset("Method::_vtable_index", Integer.class, "int"); - - final int methodDataOffset = getFieldOffset("Method::_method_data", Integer.class, "MethodData*"); - final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*"); - - final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class); - final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class); - final int methodFlagsIntrinsicCandidate = getConstant("Method::_intrinsic_candidate", Integer.class); - final int methodFlagsDontInline = getConstant("Method::_dont_inline", Integer.class); - final int methodFlagsReservedStackAccess = getConstant("Method::_reserved_stack_access", Integer.class); - final int nonvirtualVtableIndex = getConstant("Method::nonvirtual_vtable_index", Integer.class); - final int invalidVtableIndex = getConstant("Method::invalid_vtable_index", Integer.class); - - final int methodDataSize = getFieldOffset("MethodData::_size", Integer.class, "int"); - final int methodDataDataSize = getFieldOffset("MethodData::_data_size", Integer.class, "int"); - final int methodDataOopDataOffset = getFieldOffset("MethodData::_data[0]", Integer.class, "intptr_t"); - final int methodDataOopTrapHistoryOffset = getFieldOffset("MethodData::_compiler_counters._trap_hist._array[0]", Integer.class, "u1"); - final int methodDataIRSizeOffset = getFieldOffset("MethodData::_jvmci_ir_size", Integer.class, "int"); - - final int methodDataDecompiles = getFieldOffset("MethodData::_compiler_counters._nof_decompiles", Integer.class, "uint"); - final int methodDataOverflowRecompiles = getFieldOffset("MethodData::_compiler_counters._nof_overflow_recompiles", Integer.class, "uint"); - final int methodDataOverflowTraps = getFieldOffset("MethodData::_compiler_counters._nof_overflow_traps", Integer.class, "uint"); - - final int nmethodCompLevelOffset = getFieldOffset("nmethod::_comp_level", Integer.class, "int"); - - final int compilationLevelNone = getConstant("CompLevel_none", Integer.class); - final int compilationLevelSimple = getConstant("CompLevel_simple", Integer.class); - final int compilationLevelLimitedProfile = getConstant("CompLevel_limited_profile", Integer.class); - final int compilationLevelFullProfile = getConstant("CompLevel_full_profile", Integer.class); - final int compilationLevelFullOptimization = getConstant("CompLevel_full_optimization", Integer.class); - - final int compLevelAdjustmentNone = getConstant("JVMCIRuntime::none", Integer.class); - final int compLevelAdjustmentByHolder = getConstant("JVMCIRuntime::by_holder", Integer.class); - final int compLevelAdjustmentByFullSignature = getConstant("JVMCIRuntime::by_full_signature", Integer.class); - - final int invocationEntryBci = getConstant("InvocationEntryBci", Integer.class); - - final int extraStackEntries = getFieldValue("CompilerToVM::Data::Method_extra_stack_entries", Integer.class, "int"); - - final int constMethodConstantsOffset = getFieldOffset("ConstMethod::_constants", Integer.class, "ConstantPool*"); - final int constMethodFlagsOffset = getFieldOffset("ConstMethod::_flags", Integer.class, "u2"); - final int constMethodCodeSizeOffset = getFieldOffset("ConstMethod::_code_size", Integer.class, "u2"); - final int constMethodNameIndexOffset = getFieldOffset("ConstMethod::_name_index", Integer.class, "u2"); - final int constMethodSignatureIndexOffset = getFieldOffset("ConstMethod::_signature_index", Integer.class, "u2"); - final int constMethodMethodIdnumOffset = getFieldOffset("ConstMethod::_method_idnum", Integer.class, "u2"); - final int constMethodMaxStackOffset = getFieldOffset("ConstMethod::_max_stack", Integer.class, "u2"); - final int methodMaxLocalsOffset = getFieldOffset("ConstMethod::_max_locals", Integer.class, "u2"); - - final int constMethodHasLineNumberTable = getConstant("ConstMethod::_has_linenumber_table", Integer.class); - final int constMethodHasLocalVariableTable = getConstant("ConstMethod::_has_localvariable_table", Integer.class); - final int constMethodHasMethodAnnotations = getConstant("ConstMethod::_has_method_annotations", Integer.class); - final int constMethodHasParameterAnnotations = getConstant("ConstMethod::_has_parameter_annotations", Integer.class); - final int constMethodHasExceptionTable = getConstant("ConstMethod::_has_exception_table", Integer.class); - - final int exceptionTableElementSize = getFieldValue("CompilerToVM::Data::sizeof_ExceptionTableElement", Integer.class, "int"); - final int exceptionTableElementStartPcOffset = getFieldOffset("ExceptionTableElement::start_pc", Integer.class, "u2"); - final int exceptionTableElementEndPcOffset = getFieldOffset("ExceptionTableElement::end_pc", Integer.class, "u2"); - final int exceptionTableElementHandlerPcOffset = getFieldOffset("ExceptionTableElement::handler_pc", Integer.class, "u2"); - final int exceptionTableElementCatchTypeIndexOffset = getFieldOffset("ExceptionTableElement::catch_type_index", Integer.class, "u2"); - - final int localVariableTableElementSize = getFieldValue("CompilerToVM::Data::sizeof_LocalVariableTableElement", Integer.class, "int"); - final int localVariableTableElementStartBciOffset = getFieldOffset("LocalVariableTableElement::start_bci", Integer.class, "u2"); - final int localVariableTableElementLengthOffset = getFieldOffset("LocalVariableTableElement::length", Integer.class, "u2"); - final int localVariableTableElementNameCpIndexOffset = getFieldOffset("LocalVariableTableElement::name_cp_index", Integer.class, "u2"); - final int localVariableTableElementDescriptorCpIndexOffset = getFieldOffset("LocalVariableTableElement::descriptor_cp_index", Integer.class, "u2"); - final int localVariableTableElementSlotOffset = getFieldOffset("LocalVariableTableElement::slot", Integer.class, "u2"); - - final int constantPoolSize = getFieldValue("CompilerToVM::Data::sizeof_ConstantPool", Integer.class, "int"); - final int constantPoolTagsOffset = getFieldOffset("ConstantPool::_tags", Integer.class, "Array*"); - final int constantPoolHolderOffset = getFieldOffset("ConstantPool::_pool_holder", Integer.class, "InstanceKlass*"); - final int constantPoolLengthOffset = getFieldOffset("ConstantPool::_length", Integer.class, "int"); - final int constantPoolFlagsOffset = getFieldOffset("ConstantPool::_flags", Integer.class, "u2"); - - final int constantPoolCpCacheIndexTag = getConstant("ConstantPool::CPCACHE_INDEX_TAG", Integer.class); - final int constantPoolHasDynamicConstant = getConstant("ConstantPool::_has_dynamic_constant", Integer.class); - final int constantPoolSourceFileNameIndexOffset = getFieldOffset("ConstantPool::_source_file_name_index", Integer.class, "u2"); - - final int jvmConstantUtf8 = getConstant("JVM_CONSTANT_Utf8", Integer.class); - final int jvmConstantInteger = getConstant("JVM_CONSTANT_Integer", Integer.class); - final int jvmConstantLong = getConstant("JVM_CONSTANT_Long", Integer.class); - final int jvmConstantFloat = getConstant("JVM_CONSTANT_Float", Integer.class); - final int jvmConstantDouble = getConstant("JVM_CONSTANT_Double", Integer.class); - final int jvmConstantClass = getConstant("JVM_CONSTANT_Class", Integer.class); - final int jvmConstantUnresolvedClass = getConstant("JVM_CONSTANT_UnresolvedClass", Integer.class); - final int jvmConstantUnresolvedClassInError = getConstant("JVM_CONSTANT_UnresolvedClassInError", Integer.class); - final int jvmConstantString = getConstant("JVM_CONSTANT_String", Integer.class); - final int jvmConstantFieldref = getConstant("JVM_CONSTANT_Fieldref", Integer.class); - final int jvmConstantMethodref = getConstant("JVM_CONSTANT_Methodref", Integer.class); - final int jvmConstantInterfaceMethodref = getConstant("JVM_CONSTANT_InterfaceMethodref", Integer.class); - final int jvmConstantNameAndType = getConstant("JVM_CONSTANT_NameAndType", Integer.class); - final int jvmConstantMethodHandle = getConstant("JVM_CONSTANT_MethodHandle", Integer.class); - final int jvmConstantMethodHandleInError = getConstant("JVM_CONSTANT_MethodHandleInError", Integer.class); - final int jvmConstantMethodType = getConstant("JVM_CONSTANT_MethodType", Integer.class); - final int jvmConstantMethodTypeInError = getConstant("JVM_CONSTANT_MethodTypeInError", Integer.class); - final int jvmConstantDynamic = getConstant("JVM_CONSTANT_Dynamic", Integer.class); - final int jvmConstantDynamicInError = getConstant("JVM_CONSTANT_DynamicInError", Integer.class); - final int jvmConstantInvokeDynamic = getConstant("JVM_CONSTANT_InvokeDynamic", Integer.class); - - final int jvmConstantExternalMax = getConstant("JVM_CONSTANT_ExternalMax", Integer.class); - final int jvmConstantInternalMin = getConstant("JVM_CONSTANT_InternalMin", Integer.class); - final int jvmConstantInternalMax = getConstant("JVM_CONSTANT_InternalMax", Integer.class); - - final int heapWordSize = getConstant("HeapWordSize", Integer.class); - - final long symbolVmSymbols = getFieldAddress("Symbol::_vm_symbols[0]", "Symbol*"); - final int vmSymbolsFirstSID = getConstant("vmSymbols::FIRST_SID", Integer.class); - final int vmSymbolsSIDLimit = getConstant("vmSymbols::SID_LIMIT", Integer.class); - - final long symbolInit = getFieldValue("CompilerToVM::Data::symbol_init", Long.class); - final long symbolClinit = getFieldValue("CompilerToVM::Data::symbol_clinit", Long.class); - - /** - * Returns the symbol in the {@code vmSymbols} table at position {@code index} as a - * {@link String}. - * - * @param index position in the symbol table - * @return the symbol at position id - */ - String symbolAt(int index) { - HotSpotJVMCIRuntime runtime = runtime(); - assert vmSymbolsFirstSID <= index && index < vmSymbolsSIDLimit : "index " + index + " is out of bounds"; - int offset = index * Unsafe.ADDRESS_SIZE; - return runtime.getCompilerToVM().getSymbol(UNSAFE.getAddress(symbolVmSymbols + offset)); - } - - final int universeBaseVtableSize = getFieldValue("CompilerToVM::Data::Universe_base_vtable_size", Integer.class, "int"); - - final int baseVtableLength() { - return universeBaseVtableSize / (vtableEntrySize / heapWordSize); - } - - final int klassOffset = getFieldValue("java_lang_Class::_klass_offset", Integer.class, "int"); - - /** - * The DataLayout header size is the same as the cell size. - */ - final int dataLayoutHeaderSize = getConstant("DataLayout::cell_size", Integer.class); - final int dataLayoutTagOffset = getFieldOffset("DataLayout::_header._struct._tag", Integer.class, "u1"); - final int dataLayoutFlagsOffset = getFieldOffset("DataLayout::_header._struct._flags", Integer.class, "u1"); - final int dataLayoutBCIOffset = getFieldOffset("DataLayout::_header._struct._bci", Integer.class, "u2"); - final int dataLayoutCellSize = getConstant("DataLayout::cell_size", Integer.class); - - final int dataLayoutNoTag = getConstant("DataLayout::no_tag", Integer.class); - final int dataLayoutBitDataTag = getConstant("DataLayout::bit_data_tag", Integer.class); - final int dataLayoutCounterDataTag = getConstant("DataLayout::counter_data_tag", Integer.class); - final int dataLayoutJumpDataTag = getConstant("DataLayout::jump_data_tag", Integer.class); - final int dataLayoutReceiverTypeDataTag = getConstant("DataLayout::receiver_type_data_tag", Integer.class); - final int dataLayoutVirtualCallDataTag = getConstant("DataLayout::virtual_call_data_tag", Integer.class); - final int dataLayoutRetDataTag = getConstant("DataLayout::ret_data_tag", Integer.class); - final int dataLayoutBranchDataTag = getConstant("DataLayout::branch_data_tag", Integer.class); - final int dataLayoutMultiBranchDataTag = getConstant("DataLayout::multi_branch_data_tag", Integer.class); - final int dataLayoutArgInfoDataTag = getConstant("DataLayout::arg_info_data_tag", Integer.class); - final int dataLayoutCallTypeDataTag = getConstant("DataLayout::call_type_data_tag", Integer.class); - final int dataLayoutVirtualCallTypeDataTag = getConstant("DataLayout::virtual_call_type_data_tag", Integer.class); - final int dataLayoutParametersTypeDataTag = getConstant("DataLayout::parameters_type_data_tag", Integer.class); - final int dataLayoutSpeculativeTrapDataTag = getConstant("DataLayout::speculative_trap_data_tag", Integer.class); - - final int bciProfileWidth = getFlag("BciProfileWidth", Integer.class); - final int typeProfileWidth = getFlag("TypeProfileWidth", Integer.class); - final int methodProfileWidth = getFlag("MethodProfileWidth", Integer.class, 0); - - final int deoptReasonNone = getConstant("Deoptimization::Reason_none", Integer.class); - final int deoptReasonNullCheck = getConstant("Deoptimization::Reason_null_check", Integer.class); - final int deoptReasonRangeCheck = getConstant("Deoptimization::Reason_range_check", Integer.class); - final int deoptReasonClassCheck = getConstant("Deoptimization::Reason_class_check", Integer.class); - final int deoptReasonArrayCheck = getConstant("Deoptimization::Reason_array_check", Integer.class); - final int deoptReasonUnreached0 = getConstant("Deoptimization::Reason_unreached0", Integer.class); - final int deoptReasonTypeCheckInlining = getConstant("Deoptimization::Reason_type_checked_inlining", Integer.class); - final int deoptReasonOptimizedTypeCheck = getConstant("Deoptimization::Reason_optimized_type_check", Integer.class); - final int deoptReasonNotCompiledExceptionHandler = getConstant("Deoptimization::Reason_not_compiled_exception_handler", Integer.class); - final int deoptReasonUnresolved = getConstant("Deoptimization::Reason_unresolved", Integer.class); - final int deoptReasonJsrMismatch = getConstant("Deoptimization::Reason_jsr_mismatch", Integer.class); - final int deoptReasonDiv0Check = getConstant("Deoptimization::Reason_div0_check", Integer.class); - final int deoptReasonConstraint = getConstant("Deoptimization::Reason_constraint", Integer.class); - final int deoptReasonLoopLimitCheck = getConstant("Deoptimization::Reason_loop_limit_check", Integer.class); - final int deoptReasonAliasing = getConstant("Deoptimization::Reason_aliasing", Integer.class); - final int deoptReasonTransferToInterpreter = getConstant("Deoptimization::Reason_transfer_to_interpreter", Integer.class); - final int deoptReasonOSROffset = getConstant("Deoptimization::Reason_TRAP_HISTORY_LENGTH", Integer.class); - - final int deoptActionNone = getConstant("Deoptimization::Action_none", Integer.class); - final int deoptActionMaybeRecompile = getConstant("Deoptimization::Action_maybe_recompile", Integer.class); - final int deoptActionReinterpret = getConstant("Deoptimization::Action_reinterpret", Integer.class); - final int deoptActionMakeNotEntrant = getConstant("Deoptimization::Action_make_not_entrant", Integer.class); - final int deoptActionMakeNotCompilable = getConstant("Deoptimization::Action_make_not_compilable", Integer.class); - - final int deoptimizationActionBits = getConstant("Deoptimization::_action_bits", Integer.class); - final int deoptimizationReasonBits = getConstant("Deoptimization::_reason_bits", Integer.class); - final int deoptimizationDebugIdBits = getConstant("Deoptimization::_debug_id_bits", Integer.class); - final int deoptimizationActionShift = getConstant("Deoptimization::_action_shift", Integer.class); - final int deoptimizationReasonShift = getConstant("Deoptimization::_reason_shift", Integer.class); - final int deoptimizationDebugIdShift = getConstant("Deoptimization::_debug_id_shift", Integer.class); - - final int vmIntrinsicInvokeBasic = getConstant("vmIntrinsics::_invokeBasic", Integer.class); - final int vmIntrinsicLinkToVirtual = getConstant("vmIntrinsics::_linkToVirtual", Integer.class); - final int vmIntrinsicLinkToStatic = getConstant("vmIntrinsics::_linkToStatic", Integer.class); - final int vmIntrinsicLinkToSpecial = getConstant("vmIntrinsics::_linkToSpecial", Integer.class); - final int vmIntrinsicLinkToInterface = getConstant("vmIntrinsics::_linkToInterface", Integer.class); - - final int codeInstallResultOk = getConstant("JVMCI::ok", Integer.class); - final int codeInstallResultDependenciesFailed = getConstant("JVMCI::dependencies_failed", Integer.class); - final int codeInstallResultCacheFull = getConstant("JVMCI::cache_full", Integer.class); - final int codeInstallResultCodeTooLarge = getConstant("JVMCI::code_too_large", Integer.class); - final int codeInstallResultNMethodReclaimed = getConstant("JVMCI::nmethod_reclaimed", Integer.class); - final int codeInstallResultFirstPermanentBailout = getConstant("JVMCI::first_permanent_bailout", Integer.class); - - String getCodeInstallResultDescription(int codeInstallResult) { - if (codeInstallResult == codeInstallResultOk) { - return "ok"; - } - if (codeInstallResult == codeInstallResultDependenciesFailed) { - return "dependencies failed"; - } - if (codeInstallResult == codeInstallResultCacheFull) { - return "code cache is full"; - } - if (codeInstallResult == codeInstallResultCodeTooLarge) { - return "code is too large"; - } - if (codeInstallResult == codeInstallResultNMethodReclaimed) { - return "nmethod reclaimed"; - } - assert false : codeInstallResult; - return "unknown"; - } - - final int bitDataExceptionSeenFlag = getConstant("BitData::exception_seen_flag", Integer.class); - final int bitDataNullSeenFlag = getConstant("BitData::null_seen_flag", Integer.class); - final int methodDataCountOffset = getConstant("CounterData::count_off", Integer.class); - final int jumpDataTakenOffset = getConstant("JumpData::taken_off_set", Integer.class); - final int jumpDataDisplacementOffset = getConstant("JumpData::displacement_off_set", Integer.class); - final int receiverTypeDataNonprofiledCountOffset = getConstant("ReceiverTypeData::nonprofiled_count_off_set", Integer.class); - final int receiverTypeDataReceiverTypeRowCellCount = getConstant("ReceiverTypeData::receiver_type_row_cell_count", Integer.class); - final int receiverTypeDataReceiver0Offset = getConstant("ReceiverTypeData::receiver0_offset", Integer.class); - final int receiverTypeDataCount0Offset = getConstant("ReceiverTypeData::count0_offset", Integer.class); - final int branchDataNotTakenOffset = getConstant("BranchData::not_taken_off_set", Integer.class); - final int arrayDataArrayLenOffset = getConstant("ArrayData::array_len_off_set", Integer.class); - final int arrayDataArrayStartOffset = getConstant("ArrayData::array_start_off_set", Integer.class); - final int multiBranchDataPerCaseCellCount = getConstant("MultiBranchData::per_case_cell_count", Integer.class); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.common.InitTimer.timer; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import jdk.vm.ci.common.InitTimer; -import jdk.vm.ci.common.JVMCIError; - -/** - * Access to VM configuration data. - */ -public final class HotSpotVMConfigStore { - - /** - * Gets the C++ symbols whose addresses are exposed by this object. - * - * @return an unmodifiable map from the symbol names to their addresses - */ - public Map getAddresses() { - return Collections.unmodifiableMap(vmAddresses); - } - - /** - * Gets the C++ constants exposed by this object. - * - * @return an unmodifiable map from the names of C++ constants to their values - */ - public Map getConstants() { - return Collections.unmodifiableMap(vmConstants); - } - - /** - * Gets the VM flags exposed by this object. - * - * @return an unmodifiable map from VM flag names to {@link VMFlag} objects - */ - public Map getFlags() { - return Collections.unmodifiableMap(vmFlags); - } - - /** - * Gets the C++ fields exposed by this object. - * - * @return an unmodifiable map from VM field names to {@link VMField} objects - */ - public Map getFields() { - return Collections.unmodifiableMap(vmFields); - } - - /** - * Gets the VM intrinsic descriptions exposed by this object. - */ - public List getIntrinsics() { - return Collections.unmodifiableList(vmIntrinsics); - } - - final HashMap vmFields; - final HashMap vmConstants; - final HashMap vmAddresses; - final HashMap vmFlags; - final List vmIntrinsics; - final CompilerToVM compilerToVm; - - /** - * Reads the database of VM info. The return value encodes the info in a nested object array - * that is described by the pseudo Java object {@code info} below: - * - *
    -     *     info = [
    -     *         VMField[] vmFields,
    -     *         [String name, Long value, ...] vmConstants,
    -     *         [String name, Long value, ...] vmAddresses,
    -     *         VMFlag[] vmFlags
    -     *         VMIntrinsicMethod[] vmIntrinsics
    -     *     ]
    -     * 
    - */ - @SuppressWarnings("try") - HotSpotVMConfigStore(CompilerToVM compilerToVm) { - this.compilerToVm = compilerToVm; - Object[] data; - try (InitTimer t = timer("CompilerToVm readConfiguration")) { - data = compilerToVm.readConfiguration(); - } - if (data.length != 5) { - throw new JVMCIError("Expected data.length to be 5, not %d", data.length); - } - - // @formatter:off - VMField[] vmFieldsInfo = (VMField[]) data[0]; - Object[] vmConstantsInfo = (Object[]) data[1]; - Object[] vmAddressesInfo = (Object[]) data[2]; - VMFlag[] vmFlagsInfo = (VMFlag[]) data[3]; - - vmFields = new HashMap<>(vmFieldsInfo.length); - vmConstants = new HashMap<>(vmConstantsInfo.length); - vmAddresses = new HashMap<>(vmAddressesInfo.length); - vmFlags = new HashMap<>(vmFlagsInfo.length); - vmIntrinsics = Arrays.asList((VMIntrinsicMethod[]) data[4]); - // @formatter:on - - try (InitTimer t = timer("HotSpotVMConfigStore fill maps")) { - for (VMField vmField : vmFieldsInfo) { - vmFields.put(vmField.name, vmField); - } - - for (int i = 0; i < vmConstantsInfo.length / 2; i++) { - String name = (String) vmConstantsInfo[i * 2]; - Long value = (Long) vmConstantsInfo[i * 2 + 1]; - vmConstants.put(name, value); - } - - for (int i = 0; i < vmAddressesInfo.length / 2; i++) { - String name = (String) vmAddressesInfo[i * 2]; - Long value = (Long) vmAddressesInfo[i * 2 + 1]; - vmAddresses.put(name, value); - } - - for (VMFlag vmFlag : vmFlagsInfo) { - vmFlags.put(vmFlag.name, vmFlag); - } - } - } - - @Override - public String toString() { - return String.format("%s[%d fields, %d constants, %d addresses, %d flags, %d intrinsics]", - getClass().getSimpleName(), - vmFields.size(), - vmConstants.size(), - vmAddresses.size(), - vmFlags.size(), - vmIntrinsics.size()); - } - - void printConfig(HotSpotJVMCIRuntime runtime) { - TreeMap fields = new TreeMap<>(getFields()); - for (VMField field : fields.values()) { - if (!field.isStatic()) { - printConfigLine(runtime, "[vmconfig:instance field] %s %s {offset=%d[0x%x]}%n", field.type, field.name, field.offset, field.offset); - } else { - String value = field.value == null ? "null" : field.value instanceof Boolean ? field.value.toString() : String.format("%d[0x%x]", field.value, field.value); - printConfigLine(runtime, "[vmconfig:static field] %s %s = %s {address=0x%x}%n", field.type, field.name, value, field.address); - } - } - TreeMap flags = new TreeMap<>(getFlags()); - for (VMFlag flag : flags.values()) { - printConfigLine(runtime, "[vmconfig:flag] %s %s = %s%n", flag.type, flag.name, flag.value); - } - TreeMap addresses = new TreeMap<>(getAddresses()); - for (Map.Entry e : addresses.entrySet()) { - printConfigLine(runtime, "[vmconfig:address] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue()); - } - TreeMap constants = new TreeMap<>(getConstants()); - for (Map.Entry e : constants.entrySet()) { - printConfigLine(runtime, "[vmconfig:constant] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue()); - } - for (VMIntrinsicMethod e : getIntrinsics()) { - printConfigLine(runtime, "[vmconfig:intrinsic] %d = %s.%s %s%n", e.id, e.declaringClass, e.name, e.descriptor); - } - } - - @SuppressFBWarnings(value = "DM_DEFAULT_ENCODING", justification = "no localization here please!") - private static void printConfigLine(HotSpotJVMCIRuntime runtime, String format, Object... args) { - String line = String.format(format, args); - byte[] lineBytes = line.getBytes(); - runtime.writeDebugOutput(lineBytes, 0, lineBytes.length, true, true); - } - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.code.CompiledCode; -import jdk.vm.ci.code.InstalledCode; - -/** - * Listener for responding to VM events. - */ -public interface HotSpotVMEventListener { - - /** - * Notifies this client that the VM is shutting down. - */ - default void notifyShutdown() { - } - - /** - * Notify on successful install into the code cache. - * - * @param hotSpotCodeCacheProvider the code cache into which the code was installed - * @param installedCode the code that was installed - * @param compiledCode the compiled code from which {@code installedCode} was produced - */ - default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) { - } - - /** - * Notify on completion of a bootstrap. - */ - default void notifyBootstrapFinished() { - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; -import jdk.vm.ci.meta.JavaConstant; - -/** - * Encapsulates a JNI reference to an object in the HotSpot heap. - * - * {@link IndirectHotSpotObjectConstantImpl} objects are only allocated in the shared library heap. - * - * @see HotSpotObjectConstantScope - */ -final class IndirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl { - /** - * An object handle in {@code JVMCI::_object_handles}. - */ - private long objectHandle; - - /** - * Lazily computed hash code. - */ - private int hashCode; - - final IndirectHotSpotObjectConstantImpl base; - - private static class Audit { - final Object scope; - final long handle; - final Throwable origin; - - Audit(Object scope, long handle, Throwable origin) { - this.scope = scope; - this.handle = handle; - this.origin = origin; - } - } - - /** - * Details useful to audit a scoped handle used after its creating scope closes. Set to an - * {@link Audit} object if {@link HotSpotJVMCIRuntime.Option#AuditHandles} is true otherwise to - * {@link HotSpotObjectConstantScope#localScopeDescription}. - */ - private Object rawAudit; - - @SuppressWarnings("serial") - @VMEntryPoint - private IndirectHotSpotObjectConstantImpl(long objectHandle, boolean compressed, boolean skipRegister) { - super(compressed); - assert objectHandle != 0 && UnsafeAccess.UNSAFE.getLong(objectHandle) != 0; - this.objectHandle = objectHandle; - this.base = null; - if (!skipRegister) { - HotSpotObjectConstantScope scope = HotSpotObjectConstantScope.CURRENT.get(); - if (scope != null && !scope.isGlobal()) { - scope.add(this); - if (HotSpotJVMCIRuntime.Option.AuditHandles.getBoolean()) { - rawAudit = new Audit(scope.localScopeDescription, objectHandle, new Throwable() { - @Override - public String toString() { - return "Created " + objectHandle; - } - }); - } - } else { - HandleCleaner.create(this, objectHandle); - } - } - } - - private IndirectHotSpotObjectConstantImpl(IndirectHotSpotObjectConstantImpl base, boolean compressed) { - super(compressed); - // This is a variant of an original object that only varies in compress vs uncompressed. - // Instead of creating a new handle, reference that object and objectHandle. - this.objectHandle = base.getHandle(); - // There should only be one level of indirection to the base object. - assert base.base == null || base.base.base == null; - this.base = base.base != null ? base.base : base; - } - - long getHandle() { - checkHandle(); - return objectHandle; - } - - private void checkHandle() { - if (objectHandle == 0L) { - String message; - if (rawAudit instanceof Audit) { - Audit audit = (Audit) rawAudit; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(baos); - ps.println("Foreign object reference " + audit.handle + " created in scope '" + audit.scope + "' is no longer valid. Origin: {"); - audit.origin.printStackTrace(ps); - ps.print('}'); - ps.flush(); - message = baos.toString(); - } else { - message = "Foreign object reference created in scope '" + rawAudit + "' is no longer valid. " + - "Set property " + Option.AuditHandles.getPropertyName() + "=true to show origin of invalid foreign references."; - } - throw new NullPointerException(message); - } - } - - boolean isValid() { - return objectHandle != 0L; - } - - @Override - public HotSpotResolvedObjectType getType() { - checkHandle(); - return super.getType(); - } - - /** - * Clears the foreign object reference. - */ - void clear(Object scopeDescription) { - checkHandle(); - CompilerToVM.compilerToVM().deleteGlobalHandle(objectHandle); - if (rawAudit == null) { - rawAudit = scopeDescription; - } - objectHandle = 0L; - } - - @Override - public JavaConstant compress() { - assert !compressed; - return new IndirectHotSpotObjectConstantImpl(this, true); - } - - @Override - public JavaConstant uncompress() { - assert compressed; - return new IndirectHotSpotObjectConstantImpl(this, false); - } - - @Override - public int getIdentityHashCode() { - checkHandle(); - int hash = hashCode; - if (hash == 0) { - hash = runtime().compilerToVm.getIdentityHashCode(this); - if (hash == 0) { - hash = 31; - } - hashCode = hash; - } - return hash; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 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. - */ - -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -import jdk.vm.ci.meta.ResolvedJavaMethod; - -/** - * Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify - * it when events occur. The JFR events are defined in {see @code - * src/share/jfr/metadata/metadata.xml}. - */ -public final class JFR { - - /** - * Provides access to current JFR time stamp. - */ - public static final class Ticks { - - /** - * @return current JFR time stamp - */ - public static long now() { - return compilerToVM().ticksNow(); - } - } - - /** - * Helper methods for managing JFR CompilerPhase events. - * The events are defined in {see @code src/share/jfr/metadata/metadata.xml}. - */ - public static final class CompilerPhaseEvent { - - private static final ConcurrentHashMap phaseToId = new ConcurrentHashMap<>(); - - private static int getPhaseToId(String phaseName) { - return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhase(phaseName)); - } - - /** - * Commits a CompilerPhase event. - * - * @param startTime time captured at the start of compiler phase - * @param phaseName compiler phase name - * @param compileId current compilation unit id - * @param phaseLevel compiler phase nesting level - */ - public static void write(long startTime, String phaseName, int compileId, int phaseLevel) { - compilerToVM().notifyCompilerPhaseEvent(startTime, getPhaseToId(phaseName), compileId, phaseLevel); - } - } - - /** - * Helper methods for managing JFR CompilerInlining events. The events are defined in {see @code - * src/share/jfr/metadata/metadata.xml}. - */ - public static final class CompilerInliningEvent { - - /** - * Commits a CompilerInlining event. - * - * @param compileId current compilation unit id - * @param caller caller method - * @param callee callee method - * @param succeeded inlining succeeded or not - * @param message extra information on inlining - * @param bci invocation byte code index - */ - public static void write(int compileId, ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, String message, int bci) { - compilerToVM().notifyCompilerInliningEvent(compileId, (HotSpotResolvedJavaMethodImpl) caller, (HotSpotResolvedJavaMethodImpl) callee, succeeded, message, bci); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceHandleObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceHandleObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceHandleObject.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceHandleObject.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2015, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * A tag interface indicating that this type is a handledized wrapper around a HotSpot metaspace - * object that requires GC interaction to keep alive. - * - * It would preferable if this were the base class containing the pointer but that would require - * mixins since most of the wrapper types have complex supertype hierarchies. - */ -interface MetaspaceHandleObject extends MetaspaceObject { - - long getMetadataHandle(); - - @Override - default long getMetaspacePointer() { - return UnsafeAccess.UNSAFE.getLong(getMetadataHandle()); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceObject.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceObject.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceObject.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceObject.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2015, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * The marker interface for an object which wraps HotSpot Metadata. - */ -interface MetaspaceObject { - long getMetaspacePointer(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * HotSpot specific portions of the JVMCI API. - */ -package jdk.vm.ci.hotspot; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedHotSpotSpeculationLog.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2014, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * A wrapper that holds a strong reference to a "master" speculation log that - * {@linkplain HotSpotSpeculationLog#managesFailedSpeculations() manages} the failed speculations - * list. - */ -public class SharedHotSpotSpeculationLog extends HotSpotSpeculationLog { - private final HotSpotSpeculationLog masterLog; - - public SharedHotSpotSpeculationLog(HotSpotSpeculationLog masterLog) { - super(masterLog.getFailedSpeculationsAddress()); - this.masterLog = masterLog; - } - - @Override - public String toString() { - return masterLog.toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.lang.reflect.Type; - -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -/** - * Implementation of {@link HotSpotJVMCIReflection} when running in a JVMCI shared library. - */ -class SharedLibraryJVMCIReflection extends HotSpotJVMCIReflection { - - @Override - Object resolveObject(HotSpotObjectConstantImpl objectHandle) { - throw new HotSpotJVMCIUnsupportedOperationError("cannot resolve handle in a JVMCI shared library to a raw object: " + objectHandle); - } - - @Override - boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl obj) { - if (obj instanceof DirectHotSpotObjectConstantImpl) { - ResolvedJavaType type = getType(obj); - return holder.isAssignableFrom(type); - } - return runtime().compilerToVm.isInstance(holder, obj); - } - - @Override - boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType) { - return runtime().compilerToVm.isAssignableFrom(holder, otherType); - } - - @Override - boolean isLocalClass(HotSpotResolvedObjectTypeImpl holder) { - throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.isLocalClass()"); - } - - @Override - boolean isMemberClass(HotSpotResolvedObjectTypeImpl holder) { - throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.isMemberClass()"); - } - - @Override - HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder) { - throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.getEnclosingClass()"); - } - - @Override - boolean equals(HotSpotObjectConstantImpl x, HotSpotObjectConstantImpl y) { - if (x == y) { - return true; - } - if (x.compressed != y.compressed) { - return false; - } - if (x instanceof DirectHotSpotObjectConstantImpl && y instanceof DirectHotSpotObjectConstantImpl) { - DirectHotSpotObjectConstantImpl xd = (DirectHotSpotObjectConstantImpl) x; - DirectHotSpotObjectConstantImpl yd = (DirectHotSpotObjectConstantImpl) y; - return (xd.object == yd.object); - } - if (x instanceof DirectHotSpotObjectConstantImpl || y instanceof DirectHotSpotObjectConstantImpl) { - // Mixing of constant types is always inequal - return false; - } - IndirectHotSpotObjectConstantImpl indirectX = (IndirectHotSpotObjectConstantImpl) x; - IndirectHotSpotObjectConstantImpl indirectY = (IndirectHotSpotObjectConstantImpl) y; - return runtime().compilerToVm.equals(x, indirectX.getHandle(), y, indirectY.getHandle()); - } - - @Override - ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod) { - // ResolvedJavaMethod.getParameters allows a return value of null - return null; - } - - // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection - static Annotation[] getClassAnnotations(String className) { - throw new InternalError("missing substitution: " + className); - } - - // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection - static Annotation[][] getParameterAnnotations(String className, String methodName) { - throw new InternalError("missing substitution: " + className + " " + methodName); - } - - @Override - Annotation[] getAnnotations(HotSpotResolvedObjectTypeImpl holder) { - Annotation[] annotations = getClassAnnotations(holder.getName()); - return annotations == null ? new Annotation[0] : annotations; - } - - @Override - Annotation[] getDeclaredAnnotations(HotSpotResolvedObjectTypeImpl holder) { - throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); - } - - @Override - T getAnnotation(HotSpotResolvedObjectTypeImpl holder, Class annotationClass) { - throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); - } - - @Override - Annotation[][] getParameterAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { - Annotation[][] annotations = getParameterAnnotations(javaMethod.getDeclaringClass().getName(), javaMethod.getName()); - if (annotations == null) { - return new Annotation[javaMethod.signature.getParameterCount(false)][0]; - } - return annotations; - } - - @Override - Type[] getGenericParameterTypes(HotSpotResolvedJavaMethodImpl javaMethod) { - throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); - } - - @Override - Annotation[] getFieldAnnotations(HotSpotResolvedJavaFieldImpl javaField) { - throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); - } - - @Override - Annotation[] getMethodAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { - Annotation[] annotations = getMethodAnnotationsInternal(javaMethod); - return annotations == null ? new Annotation[0] : annotations; - } - - @Override - T getMethodAnnotation(HotSpotResolvedJavaMethodImpl javaMethod, Class annotationClass) { - Annotation[] methodAnnotations = getMethodAnnotations(javaMethod); - if (methodAnnotations != null) { - for (Annotation ann : methodAnnotations) { - if (annotationClass.isInstance(ann)) { - return annotationClass.cast(ann); - } - } - } - return null; - } - - // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection - @SuppressWarnings("unused") - private static Annotation[] getMethodAnnotationsInternal(ResolvedJavaMethod javaMethod) { - throw new InternalError("missing substitution"); - } - - @Override - Annotation[] getMethodDeclaredAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { - throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); - } - - @Override - Annotation[] getFieldDeclaredAnnotations(HotSpotResolvedJavaFieldImpl javaMethod) { - throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); - } - - @Override - T getFieldAnnotation(HotSpotResolvedJavaFieldImpl javaField, Class annotationClass) { - throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); - } - - @Override - HotSpotResolvedObjectTypeImpl getType(HotSpotObjectConstantImpl object) { - if (object instanceof DirectHotSpotObjectConstantImpl) { - Class theClass = ((DirectHotSpotObjectConstantImpl) object).object.getClass(); - try { - String name = theClass.getName().replace('.', '/'); - HotSpotResolvedObjectTypeImpl type = (HotSpotResolvedObjectTypeImpl) runtime().compilerToVm.lookupType(name, null, true); - if (type == null) { - throw new InternalError(name); - } - return type; - } catch (ClassNotFoundException e) { - throw new InternalError(e); - } - } - return runtime().compilerToVm.getResolvedJavaType(object, runtime().getConfig().hubOffset, false); - } - - @Override - String asString(HotSpotObjectConstantImpl object) { - if (object instanceof IndirectHotSpotObjectConstantImpl) { - return runtime().compilerToVm.asString(object); - } - Object value = ((DirectHotSpotObjectConstantImpl) object).object; - if (value instanceof String) { - return (String) value; - } - return null; - } - - @Override - ResolvedJavaType asJavaType(HotSpotObjectConstantImpl object) { - if (object instanceof DirectHotSpotObjectConstantImpl) { - DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; - if (direct.object instanceof Class) { - Class javaClass = (Class) direct.object; - return runtime().fromClass(javaClass); - } - if (direct.object instanceof ResolvedJavaType) { - return (ResolvedJavaType) convertUnknownValue(direct.object); - } - return null; - } - return runtime().compilerToVm.asJavaType(object); - } - - // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection - static Object convertUnknownValue(Object object) { - return object; - } - - @SuppressWarnings("unchecked") - @Override - T asObject(HotSpotObjectConstantImpl object, Class type) { - if (object instanceof DirectHotSpotObjectConstantImpl) { - Object theObject = ((DirectHotSpotObjectConstantImpl) object).object; - if (type.isInstance(theObject)) { - return (T) convertUnknownValue(type.cast(theObject)); - } - } - return null; - } - - @Override - Object asObject(HotSpotObjectConstantImpl object, HotSpotResolvedJavaType type) { - throw new HotSpotJVMCIUnsupportedOperationError("cannot resolve a shared library JVMCI object handle to a " + - "raw object as it may be in another runtime"); - } - - @Override - String formatString(HotSpotObjectConstantImpl object) { - if (object instanceof DirectHotSpotObjectConstantImpl) { - DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; - return "CompilerObject<" + direct.object.getClass().getName() + ">"; - } - IndirectHotSpotObjectConstantImpl indirect = (IndirectHotSpotObjectConstantImpl) object; - if (!indirect.isValid()) { - return "Instance"; - } - return "Instance<" + object.getType().toJavaName() + ">"; - } - - @Override - Integer getLength(HotSpotObjectConstantImpl object) { - if (object instanceof DirectHotSpotObjectConstantImpl) { - DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; - if (direct.object.getClass().isArray()) { - return Array.getLength(direct.object); - } - return null; - } - int length = runtime().compilerToVm.getArrayLength(object); - if (length >= 0) { - return length; - } - return null; - } - - @Override - JavaConstant readArrayElement(HotSpotObjectConstantImpl arrayObject, int index) { - Object result = runtime().compilerToVm.readArrayElement(arrayObject, index); - if (result == null) { - return null; - } - if (result instanceof JavaConstant) { - return (JavaConstant) result; - } - JavaConstant constant = JavaConstant.forBoxedPrimitive(result); - if (constant == null) { - throw new InternalError("Unexpected value " + result); - } - return constant; - } - - @Override - JavaConstant forObject(Object value) { - return DirectHotSpotObjectConstantImpl.forObject(value, false); - } - - @Override - JavaConstant unboxPrimitive(HotSpotObjectConstantImpl source) { - Object box = runtime().compilerToVm.unboxPrimitive(source); - return JavaConstant.forBoxedPrimitive(box); - } - - @Override - JavaConstant boxPrimitive(JavaConstant source) { - return runtime().compilerToVm.boxPrimitive(source.asBoxedPrimitive()); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SuppressFBWarnings.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * Used to suppress FindBugs warnings. - */ -@interface SuppressFBWarnings { - /** - * The set of FindBugs - * warnings that are to be - * suppressed in annotated element. The value can be a bug category, kind or pattern. - */ - String[] value(); - - /** - * Reason why the warning is suppressed. - */ - String justification(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -import jdk.vm.ci.common.JVMCIError; - -/** - * Support for translating exceptions between different runtime heaps. - */ -@SuppressWarnings("serial") -final class TranslatedException extends Exception { - - /** - * The value returned by {@link #encodeThrowable(Throwable)} when encoding fails due to an - * {@link OutOfMemoryError}. - */ - private static final byte[] FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES; - - /** - * The value returned by {@link #encodeThrowable(Throwable)} when encoding fails for any reason - * other than {@link OutOfMemoryError}. - */ - private static final byte[] FALLBACK_ENCODED_THROWABLE_BYTES; - static { - try { - FALLBACK_ENCODED_THROWABLE_BYTES = encodeThrowable(new TranslatedException("error during encoding", ""), false); - FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES = encodeThrowable(new OutOfMemoryError(), false); - } catch (IOException e) { - throw new JVMCIError(e); - } - } - - /** - * Class name of exception that could not be instantiated. - */ - private String originalExceptionClassName; - - private TranslatedException(String message, String originalExceptionClassName) { - super(message); - this.originalExceptionClassName = originalExceptionClassName; - } - - /** - * No need to record an initial stack trace since it will be manually overwritten. - */ - @SuppressWarnings("sync-override") - @Override - public Throwable fillInStackTrace() { - return this; - } - - @Override - public String toString() { - String s; - if (originalExceptionClassName.equals(TranslatedException.class.getName())) { - s = getClass().getName(); - } else { - s = getClass().getName() + "[" + originalExceptionClassName + "]"; - } - String message = getMessage(); - return (message != null) ? (s + ": " + message) : s; - } - - /** - * Prints a stack trace for {@code throwable} and returns {@code true}. Used to print stack - * traces only when assertions are enabled. - */ - private static boolean printStackTrace(Throwable throwable) { - throwable.printStackTrace(); - return true; - } - - private static Throwable initCause(Throwable throwable, Throwable cause) { - if (cause != null) { - try { - throwable.initCause(cause); - } catch (IllegalStateException e) { - // Cause could not be set or overwritten. - assert printStackTrace(e); - } - } - return throwable; - } - - private static Throwable create(String className, String message, Throwable cause) { - // Try create with reflection first. - try { - Class cls = Class.forName(className); - if (cause != null) { - // Handle known exception types whose cause must be set in the constructor - if (cls == InvocationTargetException.class) { - return new InvocationTargetException(cause, message); - } - if (cls == ExceptionInInitializerError.class) { - return new ExceptionInInitializerError(cause); - } - } - if (message == null) { - return initCause((Throwable) cls.getConstructor().newInstance(), cause); - } - return initCause((Throwable) cls.getDeclaredConstructor(String.class).newInstance(message), cause); - } catch (Throwable translationFailure) { - return initCause(new TranslatedException(message, className), cause); - } - } - - private static String emptyIfNull(String value) { - return value == null ? "" : value; - } - - private static String emptyAsNull(String value) { - return value.isEmpty() ? null : value; - } - - /** - * Encodes {@code throwable} including its stack and causes as a {@linkplain GZIPOutputStream - * compressed} byte array that can be decoded by {@link #decodeThrowable}. - */ - static byte[] encodeThrowable(Throwable throwable) throws Throwable { - try { - return encodeThrowable(throwable, true); - } catch (OutOfMemoryError e) { - return FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES; - } catch (Throwable e) { - return FALLBACK_ENCODED_THROWABLE_BYTES; - } - } - - private static byte[] encodeThrowable(Throwable throwable, boolean withCauseAndStack) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(new GZIPOutputStream(baos))) { - List throwables = new ArrayList<>(); - for (Throwable current = throwable; current != null; current = current.getCause()) { - throwables.add(current); - if (!withCauseAndStack) { - break; - } - } - - // Encode from inner most cause outwards - Collections.reverse(throwables); - - for (Throwable current : throwables) { - dos.writeUTF(current.getClass().getName()); - dos.writeUTF(emptyIfNull(current.getMessage())); - StackTraceElement[] stackTrace = withCauseAndStack ? current.getStackTrace() : null; - if (stackTrace == null) { - stackTrace = new StackTraceElement[0]; - } - dos.writeInt(stackTrace.length); - for (int i = 0; i < stackTrace.length; i++) { - StackTraceElement frame = stackTrace[i]; - if (frame != null) { - dos.writeUTF(emptyIfNull(frame.getClassLoaderName())); - dos.writeUTF(emptyIfNull(frame.getModuleName())); - dos.writeUTF(emptyIfNull(frame.getModuleVersion())); - dos.writeUTF(emptyIfNull(frame.getClassName())); - dos.writeUTF(emptyIfNull(frame.getMethodName())); - dos.writeUTF(emptyIfNull(frame.getFileName())); - dos.writeInt(frame.getLineNumber()); - } - } - } - } - return baos.toByteArray(); - } - - /** - * Gets the stack of the current thread without the frames between this call and the one just - * below the frame of the first method in {@link CompilerToVM}. The chopped frames are for the - * VM call to {@link HotSpotJVMCIRuntime#decodeAndThrowThrowable}. - */ - private static StackTraceElement[] getMyStackTrace() { - StackTraceElement[] stack = new Exception().getStackTrace(); - for (int i = 0; i < stack.length; i++) { - StackTraceElement e = stack[i]; - if (e.getClassName().equals(CompilerToVM.class.getName())) { - return Arrays.copyOfRange(stack, i, stack.length); - } - } - // This should never happen but since we're in exception handling - // code, just return a safe value instead raising a nested exception. - return new StackTraceElement[0]; - } - - /** - * Decodes {@code encodedThrowable} into a {@link TranslatedException}. - * - * @param encodedThrowable an encoded exception in the format specified by - * {@link #encodeThrowable} - */ - static Throwable decodeThrowable(byte[] encodedThrowable) { - try (DataInputStream dis = new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(encodedThrowable)))) { - Throwable cause = null; - Throwable throwable = null; - StackTraceElement[] myStack = getMyStackTrace(); - while (dis.available() != 0) { - String exceptionClassName = dis.readUTF(); - String exceptionMessage = emptyAsNull(dis.readUTF()); - throwable = create(exceptionClassName, exceptionMessage, cause); - int stackTraceDepth = dis.readInt(); - StackTraceElement[] stackTrace = new StackTraceElement[stackTraceDepth + myStack.length]; - int stackTraceIndex = 0; - int myStackIndex = 0; - for (int j = 0; j < stackTraceDepth; j++) { - String classLoaderName = emptyAsNull(dis.readUTF()); - String moduleName = emptyAsNull(dis.readUTF()); - String moduleVersion = emptyAsNull(dis.readUTF()); - String className = emptyAsNull(dis.readUTF()); - String methodName = emptyAsNull(dis.readUTF()); - String fileName = emptyAsNull(dis.readUTF()); - int lineNumber = dis.readInt(); - StackTraceElement ste = new StackTraceElement(classLoaderName, moduleName, moduleVersion, className, methodName, fileName, lineNumber); - - if (ste.isNativeMethod()) { - // Best effort attempt to weave stack traces from two heaps into - // a single stack trace using native method frames as stitching points. - // This is not 100% reliable as there's no guarantee that native method - // frames only exist for calls between HotSpot and libjvmci. - while (myStackIndex < myStack.length) { - StackTraceElement suffixSTE = myStack[myStackIndex++]; - if (suffixSTE.isNativeMethod()) { - break; - } - stackTrace[stackTraceIndex++] = suffixSTE; - } - } - stackTrace[stackTraceIndex++] = ste; - } - while (myStackIndex < myStack.length) { - stackTrace[stackTraceIndex++] = myStack[myStackIndex++]; - } - throwable.setStackTrace(stackTrace); - cause = throwable; - } - return throwable; - } catch (Throwable translationFailure) { - assert printStackTrace(translationFailure); - return new TranslatedException("Error decoding exception: " + encodedThrowable, translationFailure.getClass().getName()); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.internal.misc.Unsafe; - -/** - * Package private access to the {@link Unsafe} capability. - */ -class UnsafeAccess { - - static final Unsafe UNSAFE = Unsafe.getUnsafe(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMEntryPoint.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMEntryPoint.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMEntryPoint.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMEntryPoint.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * Marker interface for methods which are called from the JVM. - */ -@interface VMEntryPoint { - /** - * An optional comment describing the caller. - */ - String value() default ""; -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMField.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMField.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * Describes a C++ field exposed via {@link HotSpotVMConfigAccess}. - */ -public final class VMField { - - /** - * Fully qualified name of the represented field (e.g., "Klass::_name"). - */ - public final String name; - - /** - * The represented field's type (e.g., "Symbol*"). This may be {@code null}. - */ - public final String type; - - /** - * If the represented field is non-static, this is its offset within the containing structure. - */ - public final long offset; - - /** - * If the represented field is static, this is its address. Otherwise, this is 0. - */ - public final long address; - - /** - * Value of the field represented as a boxed boolean if its C++ type is bool otherwise as a - * boxed long; only valid for non-oop static fields. This value is only captured once, during - * JVMCI initialization. If {@link #type} cannot be meaningfully (e.g., a struct) or safely - * (e.g., an oop) expressed as a boxed object, this is {@code null}. - */ - public final Object value; - - /** - * Determines if the represented field is static. - */ - public boolean isStatic() { - return address != 0; - } - - /** - * Creates a description of a non-static field. - */ - @VMEntryPoint - VMField(String name, String type, long offset, long address, Object value) { - this.name = name; - this.type = type; - this.offset = offset; - this.address = address; - this.value = value; - } - - @Override - public String toString() { - String val = value == null ? "null" : (type.contains("*") ? String.format("0x%x", value) : String.format("%s", value)); - return String.format("Field[name=%s, type=%s, offset=%d, address=0x%x, value=%s]", name, type, offset, address, val); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMFlag.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMFlag.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMFlag.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMFlag.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -/** - * Describes a VM flag exposed via {@link HotSpotVMConfigAccess}. - */ -public final class VMFlag { - - /** - * The name of the flag. - */ - public final String name; - - /** - * The C++ type of the flag. - */ - public final String type; - - /** - * The flag's value. - */ - public final Object value; - - @VMEntryPoint - VMFlag(String name, String type, Object value) { - this.name = name; - this.type = type; - this.value = value; - } - - @Override - public String toString() { - return String.format("Flag[type=%s, name=%s, value=%s]", type, name, value); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMIntrinsicMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMIntrinsicMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMIntrinsicMethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMIntrinsicMethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot; - -import jdk.vm.ci.meta.Signature; - -/** - * Describes a method for which the VM has an intrinsic implementation. - */ -public final class VMIntrinsicMethod { - - /** - * The name of the class declaring the intrinsified method. The name is in - * class - * file format (e.g., {@code "java/lang/Thread"} instead of {@code "java.lang.Thread"}). - */ - public final String declaringClass; - - /** - * The name of the intrinsified method. This is not guaranteed to be a legal method name (e.g., - * there is a HotSpot intrinsic with the name {@code ""}). - */ - public final String name; - - /** - * The {@link Signature#toMethodDescriptor() descriptor} of the intrinsified method. This is not - * guaranteed to be a legal method descriptor (e.g., intrinsics for signature polymorphic - * methods have a descriptor of {@code "*"}). - */ - public final String descriptor; - - /** - * The unique VM identifier for the intrinsic. - */ - public final int id; - - @VMEntryPoint - VMIntrinsicMethod(String declaringClass, String name, String descriptor, int id) { - this.declaringClass = declaringClass; - this.name = name; - this.descriptor = descriptor; - this.id = id; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof VMIntrinsicMethod) { - VMIntrinsicMethod that = (VMIntrinsicMethod) obj; - if (that.id == this.id) { - assert that.name.equals(this.name) && - that.declaringClass.equals(this.declaringClass) && - that.descriptor.equals(this.descriptor); - return true; - } - } - return false; - } - - @Override - public int hashCode() { - return id; - } - - @Override - public String toString() { - return String.format("IntrinsicMethod[declaringClass=%s, name=%s, descriptor=%s, id=%d]", declaringClass, name, descriptor, id); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ -package jdk.vm.ci.hotspot.aarch64; - -import static java.util.Collections.emptyMap; -import static jdk.vm.ci.common.InitTimer.timer; - -import java.util.EnumSet; -import java.util.Map; - -import jdk.vm.ci.aarch64.AArch64; -import jdk.vm.ci.aarch64.AArch64.CPUFeature; -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.RegisterConfig; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.stack.StackIntrospection; -import jdk.vm.ci.common.InitTimer; -import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; -import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; -import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; -import jdk.vm.ci.hotspot.HotSpotStackIntrospection; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.runtime.JVMCIBackend; - -public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory { - - private static EnumSet computeFeatures(AArch64HotSpotVMConfig config) { - // Configure the feature set using the HotSpot flag settings. - Map constants = config.getStore().getConstants(); - return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, emptyMap()); - } - - private static EnumSet computeFlags(AArch64HotSpotVMConfig config) { - EnumSet flags = EnumSet.noneOf(AArch64.Flag.class); - - if (config.useCRC32) { - flags.add(AArch64.Flag.UseCRC32); - } - if (config.useNeon) { - flags.add(AArch64.Flag.UseNeon); - } - if (config.useSIMDForMemoryOps) { - flags.add(AArch64.Flag.UseSIMDForMemoryOps); - } - if (config.avoidUnalignedAccesses) { - flags.add(AArch64.Flag.AvoidUnalignedAccesses); - } - if (config.useLSE) { - flags.add(AArch64.Flag.UseLSE); - } - if (config.useBlockZeroing) { - flags.add(AArch64.Flag.UseBlockZeroing); - } - - return flags; - } - - private static TargetDescription createTarget(AArch64HotSpotVMConfig config) { - final int stackFrameAlignment = 16; - final int implicitNullCheckLimit = 4096; - final boolean inlineObjects = true; - Architecture arch = new AArch64(computeFeatures(config), computeFlags(config)); - return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); - } - - protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntime runtime) { - return new HotSpotConstantReflectionProvider(runtime); - } - - private static RegisterConfig createRegisterConfig(AArch64HotSpotVMConfig config, TargetDescription target) { - // ARMv8 defines r18 as being available to the platform ABI. Windows - // and Darwin use it for such. Linux doesn't assign it and thus r18 can - // be used as an additional register. - boolean canUsePlatformRegister = config.linuxOs; - return new AArch64HotSpotRegisterConfig(target, config.useCompressedOops, canUsePlatformRegister); - } - - protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { - return new HotSpotCodeCacheProvider(runtime, target, regConfig); - } - - protected HotSpotMetaAccessProvider createMetaAccess(HotSpotJVMCIRuntime runtime) { - return new HotSpotMetaAccessProvider(runtime); - } - - @Override - public String getArchitecture() { - return "aarch64"; - } - - @Override - public String toString() { - return "JVMCIBackend:" + getArchitecture(); - } - - @Override - @SuppressWarnings("try") - public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host) { - - assert host == null; - AArch64HotSpotVMConfig config = new AArch64HotSpotVMConfig(runtime.getConfigStore()); - TargetDescription target = createTarget(config); - - RegisterConfig regConfig; - HotSpotCodeCacheProvider codeCache; - ConstantReflectionProvider constantReflection; - HotSpotMetaAccessProvider metaAccess; - StackIntrospection stackIntrospection; - try (InitTimer t = timer("create providers")) { - try (InitTimer rt = timer("create MetaAccess provider")) { - metaAccess = createMetaAccess(runtime); - } - try (InitTimer rt = timer("create RegisterConfig")) { - regConfig = createRegisterConfig(config, target); - } - try (InitTimer rt = timer("create CodeCache provider")) { - codeCache = createCodeCache(runtime, target, regConfig); - } - try (InitTimer rt = timer("create ConstantReflection provider")) { - constantReflection = createConstantReflection(runtime); - } - try (InitTimer rt = timer("create StackIntrospection provider")) { - stackIntrospection = new HotSpotStackIntrospection(runtime); - } - } - try (InitTimer rt = timer("instantiate backend")) { - return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection); - } - } - - protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, - StackIntrospection stackIntrospection) { - return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,309 +0,0 @@ -/* - * Copyright (c) 2015, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot.aarch64; - -import static jdk.vm.ci.aarch64.AArch64.lr; -import static jdk.vm.ci.aarch64.AArch64.r0; -import static jdk.vm.ci.aarch64.AArch64.r1; -import static jdk.vm.ci.aarch64.AArch64.r2; -import static jdk.vm.ci.aarch64.AArch64.r3; -import static jdk.vm.ci.aarch64.AArch64.r4; -import static jdk.vm.ci.aarch64.AArch64.r5; -import static jdk.vm.ci.aarch64.AArch64.r6; -import static jdk.vm.ci.aarch64.AArch64.r7; -import static jdk.vm.ci.aarch64.AArch64.rscratch1; -import static jdk.vm.ci.aarch64.AArch64.rscratch2; -import static jdk.vm.ci.aarch64.AArch64.r12; -import static jdk.vm.ci.aarch64.AArch64.r18; -import static jdk.vm.ci.aarch64.AArch64.r27; -import static jdk.vm.ci.aarch64.AArch64.r28; -import static jdk.vm.ci.aarch64.AArch64.r29; -import static jdk.vm.ci.aarch64.AArch64.r31; -import static jdk.vm.ci.aarch64.AArch64.sp; -import static jdk.vm.ci.aarch64.AArch64.v0; -import static jdk.vm.ci.aarch64.AArch64.v1; -import static jdk.vm.ci.aarch64.AArch64.v2; -import static jdk.vm.ci.aarch64.AArch64.v3; -import static jdk.vm.ci.aarch64.AArch64.v4; -import static jdk.vm.ci.aarch64.AArch64.v5; -import static jdk.vm.ci.aarch64.AArch64.v6; -import static jdk.vm.ci.aarch64.AArch64.v7; -import static jdk.vm.ci.aarch64.AArch64.zr; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import jdk.vm.ci.aarch64.AArch64; -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.CallingConvention; -import jdk.vm.ci.code.CallingConvention.Type; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.RegisterArray; -import jdk.vm.ci.code.RegisterAttributes; -import jdk.vm.ci.code.RegisterConfig; -import jdk.vm.ci.code.StackSlot; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.ValueKindFactory; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.hotspot.HotSpotCallingConventionType; -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.PlatformKind; -import jdk.vm.ci.meta.Value; -import jdk.vm.ci.meta.ValueKind; - -public class AArch64HotSpotRegisterConfig implements RegisterConfig { - - private final TargetDescription target; - - private final RegisterArray allocatable; - - /** - * The caller saved registers always include all parameter registers. - */ - private final RegisterArray callerSaved; - - private final boolean allAllocatableAreCallerSaved; - - private final RegisterAttributes[] attributesMap; - - @Override - public RegisterArray getAllocatableRegisters() { - return allocatable; - } - - @Override - public RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers) { - ArrayList list = new ArrayList<>(); - for (Register reg : registers) { - if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) { - list.add(reg); - } - } - - return new RegisterArray(list); - } - - @Override - public RegisterAttributes[] getAttributesMap() { - return attributesMap.clone(); - } - - private final RegisterArray javaGeneralParameterRegisters = new RegisterArray(r1, r2, r3, r4, r5, r6, r7, r0); - private final RegisterArray nativeGeneralParameterRegisters = new RegisterArray(r0, r1, r2, r3, r4, r5, r6, r7); - private final RegisterArray simdParameterRegisters = new RegisterArray(v0, v1, v2, v3, v4, v5, v6, v7); - - public static final Register inlineCacheRegister = rscratch2; - - /** - * Vtable stubs expect the metaspace Method in r12. - */ - public static final Register metaspaceMethodRegister = r12; - - /** - * The platform ABI can use r18 to carry inter-procedural state (e.g. thread - * context). If not defined as such by the platform ABI, it can be used as - * additional temporary register. - */ - public static final Register platformRegister = r18; - public static final Register heapBaseRegister = r27; - public static final Register threadRegister = r28; - public static final Register fp = r29; - - private static final RegisterArray reservedRegisters = new RegisterArray(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp); - - private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase, boolean canUsePlatformRegister) { - RegisterArray allRegisters = arch.getAvailableValueRegisters(); - Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0) - (!canUsePlatformRegister ? 1 : 0)]; - List reservedRegistersList = reservedRegisters.asList(); - - int idx = 0; - for (Register reg : allRegisters) { - if (reservedRegistersList.contains(reg)) { - // skip reserved registers - continue; - } - if (!canUsePlatformRegister && reg.equals(platformRegister)) { - continue; - } - assert !(reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp)); - if (reserveForHeapBase && reg.equals(heapBaseRegister)) { - // skip heap base register - continue; - } - - registers[idx++] = reg; - } - - assert idx == registers.length; - return new RegisterArray(registers); - } - - public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean canUsePlatformRegister) { - this(target, initAllocatable(target.arch, useCompressedOops, canUsePlatformRegister)); - assert callerSaved.size() >= allocatable.size(); - } - - public AArch64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable) { - this.target = target; - - this.allocatable = allocatable; - Set callerSaveSet = new HashSet<>(); - allocatable.addTo(callerSaveSet); - simdParameterRegisters.addTo(callerSaveSet); - javaGeneralParameterRegisters.addTo(callerSaveSet); - nativeGeneralParameterRegisters.addTo(callerSaveSet); - callerSaved = new RegisterArray(callerSaveSet); - - allAllocatableAreCallerSaved = true; - attributesMap = RegisterAttributes.createMap(this, AArch64.allRegisters); - } - - @Override - public RegisterArray getCallerSaveRegisters() { - return callerSaved; - } - - @Override - public RegisterArray getCalleeSaveRegisters() { - return null; - } - - @Override - public boolean areAllAllocatableRegistersCallerSaved() { - return allAllocatableAreCallerSaved; - } - - @Override - public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory valueKindFactory) { - HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; - if (type == HotSpotCallingConventionType.NativeCall) { - return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory); - } - // On x64, parameter locations are the same whether viewed - // from the caller or callee perspective - return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory); - } - - @Override - public RegisterArray getCallingConventionRegisters(Type type, JavaKind kind) { - HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; - switch (kind) { - case Boolean: - case Byte: - case Short: - case Char: - case Int: - case Long: - case Object: - return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; - case Float: - case Double: - return simdParameterRegisters; - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private CallingConvention callingConvention(RegisterArray generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, - ValueKindFactory valueKindFactory) { - AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; - - int currentGeneral = 0; - int currentSIMD = 0; - int currentStackOffset = 0; - - for (int i = 0; i < parameterTypes.length; i++) { - final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind(); - - switch (kind) { - case Byte: - case Boolean: - case Short: - case Char: - case Int: - case Long: - case Object: - if (currentGeneral < generalParameterRegisters.size()) { - Register register = generalParameterRegisters.get(currentGeneral++); - locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); - } - break; - case Float: - case Double: - if (currentSIMD < simdParameterRegisters.size()) { - Register register = simdParameterRegisters.get(currentSIMD++); - locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); - } - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - - if (locations[i] == null) { - ValueKind valueKind = valueKindFactory.getValueKind(kind); - locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out); - currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize); - } - } - - JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind(); - AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind())); - return new CallingConvention(currentStackOffset, returnLocation, locations); - } - - @Override - public Register getReturnRegister(JavaKind kind) { - switch (kind) { - case Boolean: - case Byte: - case Char: - case Short: - case Int: - case Long: - case Object: - return r0; - case Float: - case Double: - return v0; - case Void: - case Illegal: - return null; - default: - throw new UnsupportedOperationException("no return register for type " + kind); - } - } - - @Override - public Register getFrameRegister() { - return sp; - } - - @Override - public String toString() { - return String.format("Allocatable: " + getAllocatableRegisters() + "%n" + "CallerSave: " + getCallerSaveRegisters() + "%n"); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ -package jdk.vm.ci.hotspot.aarch64; - -import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; -import jdk.vm.ci.hotspot.HotSpotVMConfigStore; -import jdk.vm.ci.services.Services; - -/** - * Used to access native configuration details. - * - * All non-static, public fields in this class are so that they can be compiled as constants. - */ -class AArch64HotSpotVMConfig extends HotSpotVMConfigAccess { - - AArch64HotSpotVMConfig(HotSpotVMConfigStore config) { - super(config); - } - - final boolean linuxOs = Services.getSavedProperty("os.name", "").startsWith("Linux"); - - final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class); - - // CPU Capabilities - - /* - * These flags are set based on the corresponding command line flags. - */ - final boolean useCRC32 = getFlag("UseCRC32", Boolean.class); - final boolean useNeon = getFlag("UseNeon", Boolean.class); - final boolean useSIMDForMemoryOps = getFlag("UseSIMDForMemoryOps", Boolean.class); - final boolean avoidUnalignedAccesses = getFlag("AvoidUnalignedAccesses", Boolean.class); - final boolean useLSE = getFlag("UseLSE", Boolean.class); - final boolean useBlockZeroing = getFlag("UseBlockZeroing", Boolean.class); - - final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t"); - - /* - * These flags are set if the corresponding support is in the hardware. - */ - // Checkstyle: stop - final long aarch64FP = getConstant("VM_Version::CPU_FP", Long.class); - final long aarch64ASIMD = getConstant("VM_Version::CPU_ASIMD", Long.class); - final long aarch64EVTSTRM = getConstant("VM_Version::CPU_EVTSTRM", Long.class); - final long aarch64AES = getConstant("VM_Version::CPU_AES", Long.class); - final long aarch64PMULL = getConstant("VM_Version::CPU_PMULL", Long.class); - final long aarch64SHA1 = getConstant("VM_Version::CPU_SHA1", Long.class); - final long aarch64SHA2 = getConstant("VM_Version::CPU_SHA2", Long.class); - final long aarch64CRC32 = getConstant("VM_Version::CPU_CRC32", Long.class); - final long aarch64LSE = getConstant("VM_Version::CPU_LSE", Long.class); - final long aarch64STXR_PREFETCH = getConstant("VM_Version::CPU_STXR_PREFETCH", Long.class); - final long aarch64A53MAC = getConstant("VM_Version::CPU_A53MAC", Long.class); - // Checkstyle: resume -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * The AArch64 HotSpot specific portions of the JVMCI API. - */ -package jdk.vm.ci.hotspot.aarch64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ -package jdk.vm.ci.hotspot.amd64; - -import static jdk.vm.ci.common.InitTimer.timer; - -import java.util.EnumSet; -import java.util.Map; - -import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.amd64.AMD64.CPUFeature; -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.RegisterConfig; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.stack.StackIntrospection; -import jdk.vm.ci.common.InitTimer; -import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; -import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; -import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; -import jdk.vm.ci.hotspot.HotSpotStackIntrospection; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.runtime.JVMCIBackend; - -public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory { - - private static EnumSet computeFeatures(AMD64HotSpotVMConfig config) { - // Configure the feature set using the HotSpot flag settings. - Map constants = config.getStore().getConstants(); - Map renaming = Map.of("3DNOW_PREFETCH", "AMD_3DNOW_PREFETCH"); - assert config.useSSE >= 2 : "minimum config for x64"; - EnumSet features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, renaming); - features.add(AMD64.CPUFeature.SSE); - features.add(AMD64.CPUFeature.SSE2); - return features; - } - - private static EnumSet computeFlags(AMD64HotSpotVMConfig config) { - EnumSet flags = EnumSet.noneOf(AMD64.Flag.class); - if (config.useCountLeadingZerosInstruction) { - flags.add(AMD64.Flag.UseCountLeadingZerosInstruction); - } - if (config.useCountTrailingZerosInstruction) { - flags.add(AMD64.Flag.UseCountTrailingZerosInstruction); - } - return flags; - } - - private static TargetDescription createTarget(AMD64HotSpotVMConfig config) { - final int stackFrameAlignment = 16; - final int implicitNullCheckLimit = 4096; - final boolean inlineObjects = true; - Architecture arch = new AMD64(computeFeatures(config), computeFlags(config)); - return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); - } - - protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntime runtime) { - return new HotSpotConstantReflectionProvider(runtime); - } - - private static RegisterConfig createRegisterConfig(AMD64HotSpotVMConfig config, TargetDescription target) { - return new AMD64HotSpotRegisterConfig(target, config.useCompressedOops, config.windowsOs); - } - - protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { - return new HotSpotCodeCacheProvider(runtime, target, regConfig); - } - - protected HotSpotMetaAccessProvider createMetaAccess(HotSpotJVMCIRuntime runtime) { - return new HotSpotMetaAccessProvider(runtime); - } - - @Override - public String getArchitecture() { - return "AMD64"; - } - - @Override - public String toString() { - return "JVMCIBackend:" + getArchitecture(); - } - - @Override - @SuppressWarnings("try") - public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host) { - assert host == null; - AMD64HotSpotVMConfig config = new AMD64HotSpotVMConfig(runtime.getConfigStore()); - TargetDescription target = createTarget(config); - - RegisterConfig regConfig; - HotSpotCodeCacheProvider codeCache; - ConstantReflectionProvider constantReflection; - HotSpotMetaAccessProvider metaAccess; - StackIntrospection stackIntrospection; - try (InitTimer t = timer("create providers")) { - try (InitTimer rt = timer("create MetaAccess provider")) { - metaAccess = createMetaAccess(runtime); - } - try (InitTimer rt = timer("create RegisterConfig")) { - regConfig = createRegisterConfig(config, target); - } - try (InitTimer rt = timer("create CodeCache provider")) { - codeCache = createCodeCache(runtime, target, regConfig); - } - try (InitTimer rt = timer("create ConstantReflection provider")) { - constantReflection = createConstantReflection(runtime); - } - try (InitTimer rt = timer("create StackIntrospection provider")) { - stackIntrospection = new HotSpotStackIntrospection(runtime); - } - } - try (InitTimer rt = timer("instantiate backend")) { - return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection); - } - } - - protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, - StackIntrospection stackIntrospection) { - return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot.amd64; - -import static jdk.vm.ci.amd64.AMD64.r12; -import static jdk.vm.ci.amd64.AMD64.r15; -import static jdk.vm.ci.amd64.AMD64.r8; -import static jdk.vm.ci.amd64.AMD64.r9; -import static jdk.vm.ci.amd64.AMD64.rax; -import static jdk.vm.ci.amd64.AMD64.rcx; -import static jdk.vm.ci.amd64.AMD64.rdi; -import static jdk.vm.ci.amd64.AMD64.rdx; -import static jdk.vm.ci.amd64.AMD64.rsi; -import static jdk.vm.ci.amd64.AMD64.rsp; -import static jdk.vm.ci.amd64.AMD64.xmm0; -import static jdk.vm.ci.amd64.AMD64.xmm1; -import static jdk.vm.ci.amd64.AMD64.xmm2; -import static jdk.vm.ci.amd64.AMD64.xmm3; -import static jdk.vm.ci.amd64.AMD64.xmm4; -import static jdk.vm.ci.amd64.AMD64.xmm5; -import static jdk.vm.ci.amd64.AMD64.xmm6; -import static jdk.vm.ci.amd64.AMD64.xmm7; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.CallingConvention; -import jdk.vm.ci.code.CallingConvention.Type; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.RegisterArray; -import jdk.vm.ci.code.RegisterAttributes; -import jdk.vm.ci.code.RegisterConfig; -import jdk.vm.ci.code.StackSlot; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.ValueKindFactory; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.hotspot.HotSpotCallingConventionType; -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.PlatformKind; -import jdk.vm.ci.meta.Value; -import jdk.vm.ci.meta.ValueKind; - -public class AMD64HotSpotRegisterConfig implements RegisterConfig { - - private final TargetDescription target; - - private final RegisterArray allocatable; - - /** - * The caller saved registers always include all parameter registers. - */ - private final RegisterArray callerSaved; - - private final boolean allAllocatableAreCallerSaved; - - private final RegisterAttributes[] attributesMap; - - @Override - public RegisterArray getAllocatableRegisters() { - return allocatable; - } - - @Override - public RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers) { - ArrayList list = new ArrayList<>(); - for (Register reg : registers) { - if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) { - list.add(reg); - } - } - - RegisterArray ret = new RegisterArray(list); - return ret; - } - - @Override - public RegisterAttributes[] getAttributesMap() { - return attributesMap.clone(); - } - - private final RegisterArray javaGeneralParameterRegisters; - private final RegisterArray nativeGeneralParameterRegisters; - private final RegisterArray javaXMMParameterRegisters; - private final RegisterArray nativeXMMParameterRegisters; - private final boolean windowsOS; - - /* - * Some ABIs (e.g. Windows) require a so-called "home space", that is a save area on the stack - * to store the argument registers - */ - private final boolean needsNativeStackHomeSpace; - - private static final RegisterArray reservedRegisters = new RegisterArray(rsp, r15); - - private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) { - RegisterArray allRegisters = arch.getAvailableValueRegisters(); - Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0)]; - List reservedRegistersList = reservedRegisters.asList(); - - int idx = 0; - for (Register reg : allRegisters) { - if (reservedRegistersList.contains(reg)) { - // skip reserved registers - continue; - } - if (reserveForHeapBase && reg.equals(r12)) { - // skip heap base register - continue; - } - - registers[idx++] = reg; - } - - assert idx == registers.length; - return new RegisterArray(registers); - } - - public AMD64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean windowsOs) { - this(target, initAllocatable(target.arch, useCompressedOops), windowsOs); - assert callerSaved.size() >= allocatable.size(); - } - - public AMD64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable, boolean windowsOS) { - this.target = target; - this.windowsOS = windowsOS; - - if (windowsOS) { - javaGeneralParameterRegisters = new RegisterArray(rdx, r8, r9, rdi, rsi, rcx); - nativeGeneralParameterRegisters = new RegisterArray(rcx, rdx, r8, r9); - nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3); - this.needsNativeStackHomeSpace = true; - } else { - javaGeneralParameterRegisters = new RegisterArray(rsi, rdx, rcx, r8, r9, rdi); - nativeGeneralParameterRegisters = new RegisterArray(rdi, rsi, rdx, rcx, r8, r9); - nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7); - this.needsNativeStackHomeSpace = false; - } - javaXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7); - - this.allocatable = allocatable; - Set callerSaveSet = new HashSet<>(); - allocatable.addTo(callerSaveSet); - javaXMMParameterRegisters.addTo(callerSaveSet); - callerSaveSet.addAll(javaGeneralParameterRegisters.asList()); - nativeGeneralParameterRegisters.addTo(callerSaveSet); - callerSaved = new RegisterArray(callerSaveSet); - - allAllocatableAreCallerSaved = true; - attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters()); - } - - @Override - public RegisterArray getCallerSaveRegisters() { - return callerSaved; - } - - @Override - public RegisterArray getCalleeSaveRegisters() { - return null; - } - - @Override - public boolean areAllAllocatableRegistersCallerSaved() { - return allAllocatableAreCallerSaved; - } - - @Override - public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory valueKindFactory) { - HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; - if (type == HotSpotCallingConventionType.NativeCall) { - return callingConvention(nativeGeneralParameterRegisters, nativeXMMParameterRegisters, windowsOS, returnType, parameterTypes, hotspotType, valueKindFactory); - } - // On x64, parameter locations are the same whether viewed - // from the caller or callee perspective - return callingConvention(javaGeneralParameterRegisters, javaXMMParameterRegisters, false, returnType, parameterTypes, hotspotType, valueKindFactory); - } - - @Override - public RegisterArray getCallingConventionRegisters(Type type, JavaKind kind) { - HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type; - switch (kind) { - case Boolean: - case Byte: - case Short: - case Char: - case Int: - case Long: - case Object: - return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; - case Float: - case Double: - return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeXMMParameterRegisters : javaXMMParameterRegisters; - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - /** - * Hand out registers matching the calling convention from the {@code generalParameterRegisters} - * and {@code xmmParameterRegisters} sets. Normally registers are handed out from each set - * individually based on the type of the argument. If the {@code unified} flag is true then hand - * out registers in a single sequence, selecting between the sets based on the type. This is to - * support the Windows calling convention which only ever passes 4 arguments in registers, no - * matter their types. - * - * @param generalParameterRegisters - * @param xmmParameterRegisters - * @param unified - * @param returnType - * @param parameterTypes - * @param type - * @param valueKindFactory - * @return the resulting calling convention - */ - private CallingConvention callingConvention(RegisterArray generalParameterRegisters, RegisterArray xmmParameterRegisters, boolean unified, JavaType returnType, JavaType[] parameterTypes, - HotSpotCallingConventionType type, - ValueKindFactory valueKindFactory) { - assert !unified || generalParameterRegisters.size() == xmmParameterRegisters.size() : "must be same size in unified mode"; - AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; - - int currentGeneral = 0; - int currentXMM = 0; - int currentStackOffset = type == HotSpotCallingConventionType.NativeCall && needsNativeStackHomeSpace ? generalParameterRegisters.size() * target.wordSize : 0; - - for (int i = 0; i < parameterTypes.length; i++) { - final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind(); - - switch (kind) { - case Byte: - case Boolean: - case Short: - case Char: - case Int: - case Long: - case Object: - if (currentGeneral < generalParameterRegisters.size()) { - Register register = generalParameterRegisters.get(currentGeneral++); - locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); - } - break; - case Float: - case Double: - if ((unified ? currentGeneral : currentXMM) < xmmParameterRegisters.size()) { - Register register = xmmParameterRegisters.get(unified ? currentGeneral++ : currentXMM++); - locations[i] = register.asValue(valueKindFactory.getValueKind(kind)); - } - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - - if (locations[i] == null) { - ValueKind valueKind = valueKindFactory.getValueKind(kind); - locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out); - currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize); - } - } - assert !unified || currentXMM == 0 : "shouldn't be used in unified mode"; - - JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind(); - AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind())); - return new CallingConvention(currentStackOffset, returnLocation, locations); - } - - @Override - public Register getReturnRegister(JavaKind kind) { - switch (kind) { - case Boolean: - case Byte: - case Char: - case Short: - case Int: - case Long: - case Object: - return rax; - case Float: - case Double: - return xmm0; - case Void: - case Illegal: - return null; - default: - throw new UnsupportedOperationException("no return register for type " + kind); - } - } - - @Override - public Register getFrameRegister() { - return rsp; - } - - @Override - public String toString() { - return String.format("Allocatable: " + getAllocatableRegisters() + "%n" + "CallerSave: " + getCallerSaveRegisters() + "%n"); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.hotspot.amd64; - -import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; -import jdk.vm.ci.hotspot.HotSpotVMConfigStore; -import jdk.vm.ci.services.Services; - -/** - * Used to access AMD64 specific native configuration details. - */ -class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess { - - AMD64HotSpotVMConfig(HotSpotVMConfigStore config) { - super(config); - } - - final boolean windowsOs = Services.getSavedProperty("os.name", "").startsWith("Windows"); - - final boolean useCountLeadingZerosInstruction = getFlag("UseCountLeadingZerosInstruction", Boolean.class); - final boolean useCountTrailingZerosInstruction = getFlag("UseCountTrailingZerosInstruction", Boolean.class); - final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class); - - // CPU capabilities - final int useSSE = getFlag("UseSSE", Integer.class); - final int useAVX = getFlag("UseAVX", Integer.class); - - final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t"); - - // CPU feature flags - final long amd64CX8 = getConstant("VM_Version::CPU_CX8", Long.class); - final long amd64CMOV = getConstant("VM_Version::CPU_CMOV", Long.class); - final long amd64FXSR = getConstant("VM_Version::CPU_FXSR", Long.class); - final long amd64HT = getConstant("VM_Version::CPU_HT", Long.class); - final long amd64MMX = getConstant("VM_Version::CPU_MMX", Long.class); - final long amd643DNOWPREFETCH = getConstant("VM_Version::CPU_3DNOW_PREFETCH", Long.class); - final long amd64SSE = getConstant("VM_Version::CPU_SSE", Long.class); - final long amd64SSE2 = getConstant("VM_Version::CPU_SSE2", Long.class); - final long amd64SSE3 = getConstant("VM_Version::CPU_SSE3", Long.class); - final long amd64SSSE3 = getConstant("VM_Version::CPU_SSSE3", Long.class); - final long amd64SSE4A = getConstant("VM_Version::CPU_SSE4A", Long.class); - final long amd64SSE41 = getConstant("VM_Version::CPU_SSE4_1", Long.class); - final long amd64SSE42 = getConstant("VM_Version::CPU_SSE4_2", Long.class); - final long amd64POPCNT = getConstant("VM_Version::CPU_POPCNT", Long.class); - final long amd64LZCNT = getConstant("VM_Version::CPU_LZCNT", Long.class); - final long amd64TSC = getConstant("VM_Version::CPU_TSC", Long.class); - final long amd64TSCINV = getConstant("VM_Version::CPU_TSCINV", Long.class); - final long amd64AVX = getConstant("VM_Version::CPU_AVX", Long.class); - final long amd64AVX2 = getConstant("VM_Version::CPU_AVX2", Long.class); - final long amd64AES = getConstant("VM_Version::CPU_AES", Long.class); - final long amd64ERMS = getConstant("VM_Version::CPU_ERMS", Long.class); - final long amd64CLMUL = getConstant("VM_Version::CPU_CLMUL", Long.class); - final long amd64BMI1 = getConstant("VM_Version::CPU_BMI1", Long.class); - final long amd64BMI2 = getConstant("VM_Version::CPU_BMI2", Long.class); - final long amd64RTM = getConstant("VM_Version::CPU_RTM", Long.class); - final long amd64ADX = getConstant("VM_Version::CPU_ADX", Long.class); - final long amd64AVX512F = getConstant("VM_Version::CPU_AVX512F", Long.class); - final long amd64AVX512DQ = getConstant("VM_Version::CPU_AVX512DQ", Long.class); - final long amd64AVX512PF = getConstant("VM_Version::CPU_AVX512PF", Long.class); - final long amd64AVX512ER = getConstant("VM_Version::CPU_AVX512ER", Long.class); - final long amd64AVX512CD = getConstant("VM_Version::CPU_AVX512CD", Long.class); - final long amd64AVX512BW = getConstant("VM_Version::CPU_AVX512BW", Long.class); - final long amd64AVX512VL = getConstant("VM_Version::CPU_AVX512VL", Long.class); - final long amd64SHA = getConstant("VM_Version::CPU_SHA", Long.class); - final long amd64FMA = getConstant("VM_Version::CPU_FMA", Long.class); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * The AMD64 HotSpot specific portions of the JVMCI API. - */ -package jdk.vm.ci.hotspot.amd64; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractJavaProfile.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractJavaProfile.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractJavaProfile.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractJavaProfile.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * This object holds probability information for a set of items that were profiled at a specific - * BCI. The precision of the supplied values may vary, but a runtime that provides this information - * should be aware that it will be used to guide performance-critical decisions like speculative - * inlining, etc. - * - * @param a subclass of AbstractProfiledItem - * @param the class of the items that are profiled at the specific BCI and for which - * probabilities are stored. E.g., a ResolvedJavaType or a ResolvedJavaMethod. - */ -public abstract class AbstractJavaProfile, U> { - - private final double notRecordedProbability; - private final T[] pitems; - - /** - * - * @param notRecordedProbability - * @param pitems - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of the `pitems` array parameter") - public AbstractJavaProfile(double notRecordedProbability, T[] pitems) { - this.pitems = pitems; - assert !Double.isNaN(notRecordedProbability); - this.notRecordedProbability = notRecordedProbability; - assert isSorted(); - assert totalProbablility() >= 0 && totalProbablility() <= 1.0001 : totalProbablility() + " " + this; - } - - private double totalProbablility() { - double total = notRecordedProbability; - for (T item : pitems) { - total += item.probability; - } - return total; - } - - /** - * Determines if an array of profiled items are sorted in descending order of their - * probabilities. - */ - private boolean isSorted() { - for (int i = 1; i < pitems.length; i++) { - if (pitems[i - 1].getProbability() < pitems[i].getProbability()) { - return false; - } - } - return true; - } - - /** - * Returns the estimated probability of all types that could not be recorded due to profiling - * limitations. - * - * @return double value ≥ 0.0 and ≤ 1.0 - */ - public double getNotRecordedProbability() { - return notRecordedProbability; - } - - protected T[] getItems() { - return pitems; - } - - /** - * Searches for an entry of a given resolved Java type. - * - * @param type the type for which an entry should be searched - * @return the entry or null if no entry for this type can be found - */ - public T findEntry(ResolvedJavaType type) { - if (pitems != null) { - for (T pt : pitems) { - if (pt.getItem().equals(type)) { - return pt; - } - } - } - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append(this.getClass().getName()); - builder.append("["); - if (pitems != null) { - for (T pt : pitems) { - builder.append(pt.toString()); - builder.append(", "); - } - } - builder.append(this.notRecordedProbability); - builder.append("]"); - return builder.toString(); - } - - public boolean isIncluded(U item) { - if (this.getNotRecordedProbability() > 0.0) { - return true; - } else { - for (int i = 0; i < getItems().length; i++) { - T pitem = getItems()[i]; - U curType = pitem.getItem(); - if (curType == item) { - return true; - } - } - } - return false; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof AbstractJavaProfile)) { - return false; - } - AbstractJavaProfile that = (AbstractJavaProfile) obj; - if (that.notRecordedProbability != notRecordedProbability) { - return false; - } - if (that.pitems.length != pitems.length) { - return false; - } - for (int i = 0; i < pitems.length; ++i) { - if (!pitems[i].equals(that.pitems[i])) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - return (int) Double.doubleToLongBits(notRecordedProbability) + pitems.length * 13; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractProfiledItem.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractProfiledItem.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractProfiledItem.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractProfiledItem.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * A profiled type that has a probability. Profiled types are naturally sorted in descending order - * of their probabilities. - */ -public abstract class AbstractProfiledItem implements Comparable> { - - protected final T item; - protected final double probability; - - public AbstractProfiledItem(T item, double probability) { - assert item != null; - assert probability >= 0.0D && probability <= 1.0D; - this.item = item; - this.probability = probability; - } - - protected T getItem() { - return item; - } - - /** - * Returns the estimated probability of {@link #getItem()}. - * - * @return double value ≥ 0.0 and ≤ 1.0 - */ - public double getProbability() { - return probability; - } - - /** - * Returns -1 if the {@linkplain #getProbability() probability} of this item is greater than - * {@code o}'s probability, 0 if there are equal otherwise 1. - */ - @Override - public int compareTo(AbstractProfiledItem o) { - // Need to swap the order of operands so that higher probabilities are sorted first - return Double.compare(o.getProbability(), getProbability()); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - long temp; - temp = Double.doubleToLongBits(probability); - result = prime * result + (int) (temp ^ (temp >>> 32)); - result = prime * result + item.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - AbstractProfiledItem other = (AbstractProfiledItem) obj; - if (Double.doubleToLongBits(probability) != Double.doubleToLongBits(other.probability)) { - return false; - } - return item.equals(other.item); - } - - @Override - public abstract String toString(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Common base class for values that are stored in some location that's managed by the register - * allocator (e.g. register, stack slot). - */ -public abstract class AllocatableValue extends Value implements JavaValue { - - public static final AllocatableValue[] NONE = {}; - - public AllocatableValue(ValueKind kind) { - super(kind); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -/** - * Class for recording assumptions made during compilation. - */ -public final class Assumptions implements Iterable { - - /** - * Abstract base class for assumptions. An assumption assumes a property of the runtime that may - * be invalidated by subsequent execution (e.g., that a class has no subclasses implementing - * {@link NoFinalizableSubclass Object.finalize()}). - */ - public abstract static class Assumption { - } - - /** - * A class for providing information that is only valid in association with a set of - * {@link Assumption}s. It is permissible for AssumptionResults to have no assumptions at all. - * For instance, if {@link ResolvedJavaType#isLeaf()} returns true for a type - * {@link ResolvedJavaType#findLeafConcreteSubtype()} can return an AssumptionResult with no - * assumptions since the leaf information is statically true. - * - * @param - */ - public static class AssumptionResult { - Assumption[] assumptions; - final T result; - - private static final Assumption[] EMPTY = new Assumption[0]; - - public AssumptionResult(T result, Assumption... assumptions) { - this.result = result; - this.assumptions = assumptions; - } - - public AssumptionResult(T result) { - this(result, EMPTY); - } - - public T getResult() { - return result; - } - - public boolean isAssumptionFree() { - return assumptions.length == 0; - } - - public void add(AssumptionResult other) { - Assumption[] newAssumptions = Arrays.copyOf(this.assumptions, this.assumptions.length + other.assumptions.length); - System.arraycopy(other.assumptions, 0, newAssumptions, this.assumptions.length, other.assumptions.length); - this.assumptions = newAssumptions; - } - - public boolean canRecordTo(Assumptions target) { - /* - * We can use the result if it is either assumption free, or if we have a valid - * Assumptions object where we can record assumptions. - */ - return assumptions.length == 0 || target != null; - } - - public void recordTo(Assumptions target) { - assert canRecordTo(target); - - if (assumptions.length > 0) { - for (Assumption assumption : assumptions) { - target.record(assumption); - } - } - } - } - - /** - * An assumption that a given class has no subclasses implementing {@code Object#finalize()}). - */ - public static final class NoFinalizableSubclass extends Assumption { - - private ResolvedJavaType receiverType; - - public NoFinalizableSubclass(ResolvedJavaType receiverType) { - this.receiverType = receiverType; - } - - @Override - public int hashCode() { - return 31 + receiverType.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof NoFinalizableSubclass) { - NoFinalizableSubclass other = (NoFinalizableSubclass) obj; - return other.receiverType.equals(receiverType); - } - return false; - } - - @Override - public String toString() { - return "NoFinalizableSubclass[receiverType=" + receiverType.toJavaName() + "]"; - } - - } - - /** - * An assumption that a given abstract or interface type has one direct concrete subtype. There - * is no requirement that the subtype is a leaf type. - */ - public static final class ConcreteSubtype extends Assumption { - - /** - * Type the assumption is made about. - */ - public final ResolvedJavaType context; - - /** - * Assumed concrete sub-type of the context type. - */ - public final ResolvedJavaType subtype; - - public ConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) { - this.context = context; - this.subtype = subtype; - assert context.isAbstract(); - assert subtype.isConcrete() || context.isInterface() : subtype.toString() + " : " + context.toString(); - assert !subtype.isArray() || subtype.getElementalType().isFinalFlagSet() : subtype.toString() + " : " + context.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + context.hashCode(); - result = prime * result + subtype.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ConcreteSubtype) { - ConcreteSubtype other = (ConcreteSubtype) obj; - return other.context.equals(context) && other.subtype.equals(subtype); - } - return false; - } - - @Override - public String toString() { - return "ConcreteSubtype[context=" + context.toJavaName() + ", subtype=" + subtype.toJavaName() + "]"; - } - } - - /** - * An assumption that a given type has no subtypes. - */ - public static final class LeafType extends Assumption { - - /** - * Type the assumption is made about. - */ - public final ResolvedJavaType context; - - public LeafType(ResolvedJavaType context) { - assert !context.isLeaf() : "assumption isn't required for leaf types"; - this.context = context; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + context.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof LeafType) { - LeafType other = (LeafType) obj; - return other.context.equals(context); - } - return false; - } - - @Override - public String toString() { - return "LeafSubtype[context=" + context.toJavaName() + "]"; - } - } - - /** - * An assumption that a given virtual method has a given unique implementation. - */ - public static final class ConcreteMethod extends Assumption { - - /** - * A virtual (or interface) method whose unique implementation for the receiver type in - * {@link #context} is {@link #impl}. - */ - public final ResolvedJavaMethod method; - - /** - * A receiver type. - */ - public final ResolvedJavaType context; - - /** - * The unique implementation of {@link #method} for {@link #context}. - */ - public final ResolvedJavaMethod impl; - - public ConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) { - this.method = method; - this.context = context; - this.impl = impl; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + method.hashCode(); - result = prime * result + context.hashCode(); - result = prime * result + impl.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ConcreteMethod) { - ConcreteMethod other = (ConcreteMethod) obj; - return other.method.equals(method) && other.context.equals(context) && other.impl.equals(impl); - } - return false; - } - - @Override - public String toString() { - return "ConcreteMethod[method=" + method.format("%H.%n(%p)%r") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)%r") + "]"; - } - } - - /** - * An assumption that a given call site's method handle did not change. - */ - public static final class CallSiteTargetValue extends Assumption { - - public final JavaConstant callSite; - public final JavaConstant methodHandle; - - public CallSiteTargetValue(JavaConstant callSite, JavaConstant methodHandle) { - this.callSite = callSite; - this.methodHandle = methodHandle; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + callSite.hashCode(); - result = prime * result + methodHandle.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof CallSiteTargetValue) { - CallSiteTargetValue other = (CallSiteTargetValue) obj; - return callSite.equals(other.callSite) && methodHandle.equals(other.methodHandle); - } - return false; - } - - @Override - public String toString() { - return "CallSiteTargetValue[callSite=" + callSite + ", methodHandle=" + methodHandle + "]"; - } - } - - private final Set assumptions = new HashSet<>(); - - /** - * Returns whether any assumptions have been registered. - * - * @return {@code true} if at least one assumption has been registered, {@code false} otherwise. - */ - public boolean isEmpty() { - return assumptions.isEmpty(); - } - - @Override - public int hashCode() { - throw new UnsupportedOperationException("hashCode"); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof Assumptions) { - Assumptions that = (Assumptions) obj; - if (!this.assumptions.equals(that.assumptions)) { - return false; - } - return true; - } - return false; - } - - @Override - public Iterator iterator() { - return assumptions.iterator(); - } - - /** - * Records an assumption that the specified type has no finalizable subclasses. - * - * @param receiverType the type that is assumed to have no finalizable subclasses - */ - public void recordNoFinalizableSubclassAssumption(ResolvedJavaType receiverType) { - record(new NoFinalizableSubclass(receiverType)); - } - - /** - * Records that {@code subtype} is the only concrete subtype in the class hierarchy below - * {@code context}. - * - * @param context the root of the subtree of the class hierarchy that this assumptions is about - * @param subtype the one concrete subtype - */ - public void recordConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) { - record(new ConcreteSubtype(context, subtype)); - } - - /** - * Records that {@code impl} is the only possible concrete target for a virtual call to - * {@code method} with a receiver of type {@code context}. - * - * @param method a method that is the target of a virtual call - * @param context the receiver type of a call to {@code method} - * @param impl the concrete method that is the only possible target for the virtual call - */ - public void recordConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) { - record(new ConcreteMethod(method, context, impl)); - } - - public void record(Assumption assumption) { - assumptions.add(assumption); - } - - /** - * Gets a copy of the assumptions recorded in this object as an array. - */ - public Assumption[] toArray() { - return assumptions.toArray(new Assumption[assumptions.size()]); - } - - /** - * Copies assumptions recorded by another {@link Assumptions} object into this object. - */ - public void record(Assumptions other) { - assert other != this; - assumptions.addAll(other.assumptions); - } - - @Override - public String toString() { - return "Assumptions[" + assumptions + "]"; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Represents a compile-time constant (boxed) value within the compiler. - */ -public interface Constant { - - boolean isDefaultForKind(); - - String toValueString(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Represents the runtime representation of the constant pool that is used by the compiler when - * parsing bytecode. Provides methods to look up a constant pool entry without performing - * resolution. They are used during compilation. - */ -public interface ConstantPool { - - /** - * Returns the number of entries the constant pool. - * - * @return number of entries in the constant pool - */ - int length(); - - /** - * Ensures that the type referenced by the specified constant pool entry is loaded and - * initialized. This can be used to compile time resolve a type. It works for field, method, or - * type constant pool entries. - * - * @param cpi the index of the constant pool entry that references the type - * @param opcode the opcode of the instruction that references the type - */ - void loadReferencedType(int cpi, int opcode); - - /** - * Ensures that the type referenced by the specified constant pool entry is loaded. This can be - * used to compile time resolve a type. It works for field, method, or type constant pool - * entries. - * - * @param cpi the index of the constant pool entry that references the type - * @param opcode the opcode of the instruction that references the type - * @param initialize if {@code true}, the referenced type is either guaranteed to be initialized - * upon return or an initialization exception is thrown - */ - default void loadReferencedType(int cpi, int opcode, boolean initialize) { - if (initialize) { - loadReferencedType(cpi, opcode); - } else { - throw new UnsupportedOperationException(); - } - } - - /** - * Looks up the type referenced by the constant pool entry at {@code cpi} as referenced by the - * {@code opcode} bytecode instruction. - * - * @param cpi the index of a constant pool entry that references a type - * @param opcode the opcode of the instruction with {@code cpi} as an operand - * @return a reference to the compiler interface type - */ - JavaType lookupReferencedType(int cpi, int opcode); - - /** - * Looks up a reference to a field. If {@code opcode} is non-negative, then resolution checks - * specific to the bytecode it denotes are performed if the field is already resolved. Checks - * for some bytecodes require the method that contains the bytecode to be specified. Should any - * of these checks fail, an unresolved field reference is returned. - * - * @param cpi the constant pool index - * @param opcode the opcode of the instruction for which the lookup is being performed or - * {@code -1} - * @param method the method for which the lookup is being performed - * @return a reference to the field at {@code cpi} in this pool - * @throws ClassFormatError if the entry at {@code cpi} is not a field - */ - JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode); - - /** - * Looks up a reference to a method. If {@code opcode} is non-negative, then resolution checks - * specific to the bytecode it denotes are performed if the method is already resolved. Should - * any of these checks fail, an unresolved method reference is returned. - * - * @param cpi the constant pool index - * @param opcode the opcode of the instruction for which the lookup is being performed or - * {@code -1} - * @return a reference to the method at {@code cpi} in this pool - * @throws ClassFormatError if the entry at {@code cpi} is not a method - */ - JavaMethod lookupMethod(int cpi, int opcode); - - /** - * Looks up a reference to a type. If {@code opcode} is non-negative, then resolution checks - * specific to the bytecode it denotes are performed if the type is already resolved. Should any - * of these checks fail, an unresolved type reference is returned. - * - * @param cpi the constant pool index - * @param opcode the opcode of the instruction for which the lookup is being performed or - * {@code -1} - * @return a reference to the compiler interface type - */ - JavaType lookupType(int cpi, int opcode); - - /** - * Looks up an Utf8 string. - * - * @param cpi the constant pool index - * @return the Utf8 string at index {@code cpi} in this constant pool - */ - String lookupUtf8(int cpi); - - /** - * Looks up a method signature. - * - * @param cpi the constant pool index - * @return the method signature at index {@code cpi} in this constant pool - */ - Signature lookupSignature(int cpi); - - /** - * Looks up a constant at the specified index. - * - * @param cpi the constant pool index - * @return the {@code Constant} or {@code JavaType} instance representing the constant pool - * entry - */ - Object lookupConstant(int cpi); - - /** - * Looks up the appendix at the specified index. - * - * @param cpi the constant pool index - * @param opcode the opcode of the instruction for which the lookup is being performed or - * {@code -1} - * @return the appendix if it exists and is resolved or {@code null} - */ - JavaConstant lookupAppendix(int cpi, int opcode); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ -package jdk.vm.ci.meta; - -import java.lang.invoke.MethodHandle; - -/** - * Reflection operations on values represented as {@linkplain JavaConstant constants}. All methods - * in this interface require the VM to access the actual object encapsulated in - * {@link JavaKind#Object object} constants. This access is not always possible, depending on kind - * of VM and the state that the VM is in. Therefore, all methods can return {@code null} at any - * time, to indicate that the result is not available at this point. The caller is responsible to - * check for {@code null} results and handle them properly, e.g., not perform an optimization. - */ -public interface ConstantReflectionProvider { - - /** - * Compares two constants for equality. The equality relationship is symmetric. Returns - * {@link Boolean#TRUE true} if the two constants represent the same run time value, - * {@link Boolean#FALSE false} if they are different. Returns {@code null} if the constants - * cannot be compared at this point. - */ - Boolean constantEquals(Constant x, Constant y); - - /** - * Returns the length of the array constant. Returns {@code null} if the constant is not an - * array, or if the array length is not available at this point. - */ - Integer readArrayLength(JavaConstant array); - - /** - * Reads a value from the given array at the given index. Returns {@code null} if the constant - * is not an array, if the index is out of bounds, or if the value is not available at this - * point. - */ - JavaConstant readArrayElement(JavaConstant array, int index); - - /** - * Gets the current value of this field for a given object, if available. - * - * There is no guarantee that the same value will be returned by this method for a field unless - * the field is considered to be constant by the runtime. - * - * @param receiver object from which this field's value is to be read. This value is ignored if - * this field is static. - * @return the value of this field or {@code null} if the value is not available (e.g., because - * the field holder is not yet initialized). - */ - JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver); - - /** - * Converts the given {@link JavaKind#isPrimitive() primitive} constant to a boxed - * {@link JavaKind#Object object} constant, according to the Java boxing rules. Returns - * {@code null} if the source is is not a primitive constant, or the boxed value is not - * available at this point. - */ - JavaConstant boxPrimitive(JavaConstant source); - - /** - * Converts the given {@link JavaKind#Object object} constant to a {@link JavaKind#isPrimitive() - * primitive} constant, according to the Java unboxing rules. Returns {@code null} if the source - * is is not an object constant that can be unboxed, or the unboxed value is not available at - * this point. - */ - JavaConstant unboxPrimitive(JavaConstant source); - - /** - * Gets a string as a {@link JavaConstant}. - */ - JavaConstant forString(String value); - - /** - * Returns the {@link ResolvedJavaType} for a {@link Class} object (or any other object regarded - * as a class by the VM) encapsulated in the given constant. Returns {@code null} if the - * constant does not encapsulate a class, or if the type is not available at this point. - */ - ResolvedJavaType asJavaType(Constant constant); - - /** - * Gets access to the internals of {@link MethodHandle}. - */ - MethodHandleAccessProvider getMethodHandleAccess(); - - /** - * Gets raw memory access. - */ - MemoryAccessProvider getMemoryAccessProvider(); - - /** - * Gets the runtime representation of the {@link Class} object of this type. - */ - JavaConstant asJavaClass(ResolvedJavaType type); - - /** - * Gets the runtime representation of the "hub" of this type--that is, the closest part of the - * type representation which is typically stored in the object header. - */ - Constant asObjectHub(ResolvedJavaType type); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DefaultProfilingInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DefaultProfilingInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DefaultProfilingInfo.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DefaultProfilingInfo.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * An implementation of {@link ProfilingInfo} that can used in the absence of real profile - * information. - */ -public final class DefaultProfilingInfo implements ProfilingInfo { - - private static final ProfilingInfo[] NO_PROFILING_INFO = new ProfilingInfo[]{new DefaultProfilingInfo(TriState.TRUE), new DefaultProfilingInfo(TriState.FALSE), - new DefaultProfilingInfo(TriState.UNKNOWN)}; - - private final TriState exceptionSeen; - - DefaultProfilingInfo(TriState exceptionSeen) { - this.exceptionSeen = exceptionSeen; - } - - @Override - public int getCodeSize() { - return 0; - } - - @Override - public JavaTypeProfile getTypeProfile(int bci) { - return null; - } - - @Override - public JavaMethodProfile getMethodProfile(int bci) { - return null; - } - - @Override - public double getBranchTakenProbability(int bci) { - return -1; - } - - @Override - public double[] getSwitchProbabilities(int bci) { - return null; - } - - @Override - public TriState getExceptionSeen(int bci) { - return exceptionSeen; - } - - @Override - public TriState getNullSeen(int bci) { - return TriState.UNKNOWN; - } - - @Override - public int getExecutionCount(int bci) { - return -1; - } - - public static ProfilingInfo get(TriState exceptionSeen) { - return NO_PROFILING_INFO[exceptionSeen.ordinal()]; - } - - @Override - public int getDeoptimizationCount(DeoptimizationReason reason) { - return 0; - } - - @Override - public boolean isMature() { - return false; - } - - @Override - public String toString() { - return "DefaultProfilingInfo<" + this.toString(null, "; ") + ">"; - } - - @Override - public void setMature() { - // Do nothing - } - - @Override - public boolean setCompilerIRSize(Class irType, int nodeCount) { - return false; - } - - @Override - public int getCompilerIRSize(Class irType) { - return -1; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationAction.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationAction.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationAction.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationAction.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Specifies the action that should be taken by the runtime in case a certain deoptimization is - * triggered. - */ -public enum DeoptimizationAction { - /** - * Do not invalidate the machine code. This is typically used when deoptimizing at a point where - * it's highly likely nothing will change the likelihood of the deoptimization happening again. - * For example, a compiled array allocation where the size is negative. - */ - None(false), - - /** - * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is - * triggered too often. - */ - RecompileIfTooManyDeopts(true), - - /** - * Invalidate the machine code and reset the profiling information. - */ - InvalidateReprofile(true), - - /** - * Invalidate the machine code and immediately schedule a recompilation. This is typically used - * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not - * required to determine that the deoptimization will not re-occur. - */ - InvalidateRecompile(true), - - /** - * Invalidate the machine code and stop compiling the outermost method of this compilation. - */ - InvalidateStopCompiling(true); - - private final boolean invalidatesCompilation; - - DeoptimizationAction(boolean invalidatesCompilation) { - this.invalidatesCompilation = invalidatesCompilation; - } - - public boolean doesInvalidateCompilation() { - return invalidatesCompilation; - } - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Enumeration of reasons for why a deoptimization is happening. - */ -public enum DeoptimizationReason { - None, - NullCheckException, - BoundsCheckException, - ClassCastException, - ArrayStoreException, - UnreachedCode, - TypeCheckedInliningViolated, - OptimizedTypeCheckViolated, - NotCompiledExceptionHandler, - Unresolved, - JavaSubroutineMismatch, - ArithmeticException, - RuntimeConstraint, - LoopLimitCheck, - Aliasing, - TransferToInterpreter, -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/EncodedSpeculationReason.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/EncodedSpeculationReason.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/EncodedSpeculationReason.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/EncodedSpeculationReason.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package jdk.vm.ci.meta; - -import java.util.Arrays; -import java.util.function.Supplier; - -import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; - -/** - * An implementation of {@link SpeculationReason} based on encoded values. - */ -public class EncodedSpeculationReason implements SpeculationReason { - final int groupId; - final String groupName; - final Object[] context; - private SpeculationLog.SpeculationReasonEncoding encoding; - - public EncodedSpeculationReason(int groupId, String groupName, Object[] context) { - this.groupId = groupId; - this.groupName = groupName; - this.context = context; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof EncodedSpeculationReason) { - if (obj instanceof EncodedSpeculationReason) { - EncodedSpeculationReason that = (EncodedSpeculationReason) obj; - return this.groupId == that.groupId && Arrays.equals(this.context, that.context); - } - return false; - } - return false; - } - - @Override - public SpeculationLog.SpeculationReasonEncoding encode(Supplier encodingSupplier) { - if (encoding == null) { - encoding = encodingSupplier.get(); - encoding.addInt(groupId); - for (Object o : context) { - if (o == null) { - encoding.addInt(0); - } else { - addNonNullObject(encoding, o); - } - } - } - return encoding; - } - - static void addNonNullObject(SpeculationLog.SpeculationReasonEncoding encoding, Object o) { - Class c = o.getClass(); - if (c == String.class) { - encoding.addString((String) o); - } else if (c == Byte.class) { - encoding.addByte((Byte) o); - } else if (c == Short.class) { - encoding.addShort((Short) o); - } else if (c == Character.class) { - encoding.addShort((Character) o); - } else if (c == Integer.class) { - encoding.addInt((Integer) o); - } else if (c == Long.class) { - encoding.addLong((Long) o); - } else if (c == Float.class) { - encoding.addInt(Float.floatToRawIntBits((Float) o)); - } else if (c == Double.class) { - encoding.addLong(Double.doubleToRawLongBits((Double) o)); - } else if (o instanceof Enum) { - encoding.addInt(((Enum) o).ordinal()); - } else if (o instanceof ResolvedJavaMethod) { - encoding.addMethod((ResolvedJavaMethod) o); - } else if (o instanceof ResolvedJavaType) { - encoding.addType((ResolvedJavaType) o); - } else if (o instanceof ResolvedJavaField) { - encoding.addField((ResolvedJavaField) o); - } else { - throw new IllegalArgumentException("Unsupported type for encoding: " + c.getName()); - } - } - - @Override - public int hashCode() { - return groupId + Arrays.hashCode(this.context); - } - - @Override - public String toString() { - return String.format("%s@%d%s", groupName, groupId, Arrays.toString(context)); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ExceptionHandler.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ExceptionHandler.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ExceptionHandler.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ExceptionHandler.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.util.Objects; - -/** - * Represents an exception handler within the bytecodes. - */ -public final class ExceptionHandler { - - private final int startBCI; - private final int endBCI; - private final int handlerBCI; - private final int catchTypeCPI; - private final JavaType catchType; - - /** - * Creates a new exception handler with the specified ranges. - * - * @param startBCI the start index of the protected range - * @param endBCI the end index of the protected range - * @param catchBCI the index of the handler - * @param catchTypeCPI the index of the throwable class in the constant pool - * @param catchType the type caught by this exception handler - */ - public ExceptionHandler(int startBCI, int endBCI, int catchBCI, int catchTypeCPI, JavaType catchType) { - this.startBCI = startBCI; - this.endBCI = endBCI; - this.handlerBCI = catchBCI; - this.catchTypeCPI = catchTypeCPI; - this.catchType = catchType; - } - - /** - * Returns the start bytecode index of the protected range of this handler. - */ - public int getStartBCI() { - return startBCI; - } - - /** - * Returns the end bytecode index of the protected range of this handler. - */ - public int getEndBCI() { - return endBCI; - } - - /** - * Returns the bytecode index of the handler block of this handler. - */ - public int getHandlerBCI() { - return handlerBCI; - } - - /** - * Returns the index into the constant pool representing the type of exception caught by this - * handler. - */ - public int catchTypeCPI() { - return catchTypeCPI; - } - - /** - * Checks whether this handler catches all exceptions. - * - * @return {@code true} if this handler catches all exceptions - */ - public boolean isCatchAll() { - return catchTypeCPI == 0; - } - - /** - * Returns the type of exception caught by this exception handler. - */ - public JavaType getCatchType() { - return catchType; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof ExceptionHandler)) { - return false; - } - ExceptionHandler that = (ExceptionHandler) obj; - if (this.startBCI != that.startBCI || this.endBCI != that.endBCI || this.handlerBCI != that.handlerBCI || this.catchTypeCPI != that.catchTypeCPI) { - return false; - } - return Objects.equals(this.catchType, that.catchType); - } - - @Override - public String toString() { - return "ExceptionHandler"; - } - - @Override - public int hashCode() { - return catchTypeCPI ^ endBCI ^ handlerBCI; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Represents the resolved target of an invocation. - */ -public interface InvokeTarget { -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.meta; - -/** - * Represents a constant (boxed) value, such as an integer, floating point number, or object - * reference, within the compiler and across the compiler/runtime interface. Exports a set of - * {@code JavaConstant} instances that represent frequently used constant values, such as - * {@link #NULL_POINTER}. - */ -public interface JavaConstant extends Constant, JavaValue { - /* - * Using a larger cache for integers leads to only a slight increase in cache hit ratio which is - * not enough to justify the impact on startup time. - */ - JavaConstant NULL_POINTER = new NullConstant(); - PrimitiveConstant INT_MINUS_1 = new PrimitiveConstant(JavaKind.Int, -1); - PrimitiveConstant INT_0 = new PrimitiveConstant(JavaKind.Int, 0); - PrimitiveConstant INT_1 = new PrimitiveConstant(JavaKind.Int, 1); - PrimitiveConstant INT_2 = new PrimitiveConstant(JavaKind.Int, 2); - PrimitiveConstant LONG_0 = new PrimitiveConstant(JavaKind.Long, 0L); - PrimitiveConstant LONG_1 = new PrimitiveConstant(JavaKind.Long, 1L); - PrimitiveConstant FLOAT_0 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(0.0F)); - PrimitiveConstant FLOAT_1 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(1.0F)); - PrimitiveConstant DOUBLE_0 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(0.0D)); - PrimitiveConstant DOUBLE_1 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(1.0D)); - PrimitiveConstant TRUE = new PrimitiveConstant(JavaKind.Boolean, 1L); - PrimitiveConstant FALSE = new PrimitiveConstant(JavaKind.Boolean, 0L); - PrimitiveConstant ILLEGAL = new PrimitiveConstant(JavaKind.Illegal, 0); - - /** - * Returns the Java kind of this constant. - */ - JavaKind getJavaKind(); - - /** - * Checks whether this constant is null. - * - * @return {@code true} if this constant is the null constant - */ - boolean isNull(); - - static boolean isNull(Constant c) { - if (c instanceof JavaConstant) { - return ((JavaConstant) c).isNull(); - } else { - return false; - } - } - - /** - * Checks whether this constant is non-null. - * - * @return {@code true} if this constant is a primitive, or an object constant that is not null - */ - default boolean isNonNull() { - return !isNull(); - } - - /** - * Checks whether this constant is the default value for its kind (null, 0, 0.0, false). - * - * @return {@code true} if this constant is the default value for its kind - */ - @Override - boolean isDefaultForKind(); - - /** - * Returns the value of this constant as a boxed Java value. - * - * @return the value of this constant - */ - Object asBoxedPrimitive(); - - /** - * Returns the primitive int value this constant represents. The constant must have a - * {@link JavaKind#getStackKind()} of {@link JavaKind#Int}. - * - * @return the constant value - */ - int asInt(); - - /** - * Returns the primitive boolean value this constant represents. The constant must have kind - * {@link JavaKind#Boolean}. - * - * @return the constant value - */ - boolean asBoolean(); - - /** - * Returns the primitive long value this constant represents. The constant must have kind - * {@link JavaKind#Long}, a {@link JavaKind#getStackKind()} of {@link JavaKind#Int}. - * - * @return the constant value - */ - long asLong(); - - /** - * Returns the primitive float value this constant represents. The constant must have kind - * {@link JavaKind#Float}. - * - * @return the constant value - */ - float asFloat(); - - /** - * Returns the primitive double value this constant represents. The constant must have kind - * {@link JavaKind#Double}. - * - * @return the constant value - */ - double asDouble(); - - @Override - default String toValueString() { - if (getJavaKind() == JavaKind.Illegal) { - return "illegal"; - } else { - return getJavaKind().format(asBoxedPrimitive()); - } - } - - static String toString(JavaConstant constant) { - if (constant.getJavaKind() == JavaKind.Illegal) { - return "illegal"; - } else { - return constant.getJavaKind().getJavaName() + "[" + constant.toValueString() + "]"; - } - } - - /** - * Creates a boxed double constant. - * - * @param d the double value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forDouble(double d) { - if (Double.compare(0.0D, d) == 0) { - return DOUBLE_0; - } - if (Double.compare(d, 1.0D) == 0) { - return DOUBLE_1; - } - return new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(d)); - } - - /** - * Creates a boxed float constant. - * - * @param f the float value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forFloat(float f) { - if (Float.compare(f, 0.0F) == 0) { - return FLOAT_0; - } - if (Float.compare(f, 1.0F) == 0) { - return FLOAT_1; - } - return new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(f)); - } - - /** - * Creates a boxed long constant. - * - * @param i the long value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forLong(long i) { - if (i == 0) { - return LONG_0; - } else if (i == 1) { - return LONG_1; - } else { - return new PrimitiveConstant(JavaKind.Long, i); - } - } - - /** - * Creates a boxed integer constant. - * - * @param i the integer value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forInt(int i) { - switch (i) { - case -1: - return INT_MINUS_1; - case 0: - return INT_0; - case 1: - return INT_1; - case 2: - return INT_2; - default: - return new PrimitiveConstant(JavaKind.Int, i); - } - } - - /** - * Creates a boxed byte constant. - * - * @param i the byte value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forByte(byte i) { - return new PrimitiveConstant(JavaKind.Byte, i); - } - - /** - * Creates a boxed boolean constant. - * - * @param i the boolean value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forBoolean(boolean i) { - return i ? TRUE : FALSE; - } - - /** - * Creates a boxed char constant. - * - * @param i the char value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forChar(char i) { - return new PrimitiveConstant(JavaKind.Char, i); - } - - /** - * Creates a boxed short constant. - * - * @param i the short value to box - * @return a boxed copy of {@code value} - */ - static PrimitiveConstant forShort(short i) { - return new PrimitiveConstant(JavaKind.Short, i); - } - - /** - * Creates a {@link JavaConstant} from a primitive integer of a certain kind. - */ - static PrimitiveConstant forIntegerKind(JavaKind kind, long i) { - switch (kind) { - case Boolean: - return forBoolean(i != 0); - case Byte: - return forByte((byte) i); - case Short: - return forShort((short) i); - case Char: - return forChar((char) i); - case Int: - return forInt((int) i); - case Long: - return forLong(i); - default: - throw new IllegalArgumentException("not an integer kind: " + kind); - } - } - - /** - * Creates a {@link JavaConstant} from a primitive integer of a certain width. - */ - static PrimitiveConstant forPrimitiveInt(int bits, long i) { - assert bits <= 64; - switch (bits) { - case 1: - return forBoolean(i != 0); - case 8: - return forByte((byte) i); - case 16: - return forShort((short) i); - case 32: - return forInt((int) i); - case 64: - return forLong(i); - default: - throw new IllegalArgumentException("unsupported integer width: " + bits); - } - } - - static PrimitiveConstant forPrimitive(JavaKind kind, long rawValue) { - switch (kind) { - case Boolean: - return JavaConstant.forBoolean(rawValue != 0); - case Byte: - return JavaConstant.forByte((byte) rawValue); - case Char: - return JavaConstant.forChar((char) rawValue); - case Short: - return JavaConstant.forShort((short) rawValue); - case Int: - return JavaConstant.forInt((int) rawValue); - case Long: - return JavaConstant.forLong(rawValue); - case Float: - return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue)); - case Double: - return JavaConstant.forDouble(Double.longBitsToDouble(rawValue)); - default: - throw new IllegalArgumentException("Unsupported kind: " + kind); - } - } - - /** - * Creates a boxed constant for the given boxed primitive value. - * - * @param value the Java boxed value - * @return the primitive constant holding the {@code value} - */ - static PrimitiveConstant forBoxedPrimitive(Object value) { - if (value instanceof Boolean) { - return forBoolean((Boolean) value); - } else if (value instanceof Byte) { - return forByte((Byte) value); - } else if (value instanceof Character) { - return forChar((Character) value); - } else if (value instanceof Short) { - return forShort((Short) value); - } else if (value instanceof Integer) { - return forInt((Integer) value); - } else if (value instanceof Long) { - return forLong((Long) value); - } else if (value instanceof Float) { - return forFloat((Float) value); - } else if (value instanceof Double) { - return forDouble((Double) value); - } else { - return null; - } - } - - static PrimitiveConstant forIllegal() { - return JavaConstant.ILLEGAL; - } - - /** - * Returns a constant with the default value for the given kind. - */ - static JavaConstant defaultForKind(JavaKind kind) { - switch (kind) { - case Boolean: - return FALSE; - case Byte: - return forByte((byte) 0); - case Char: - return forChar((char) 0); - case Short: - return forShort((short) 0); - case Int: - return INT_0; - case Double: - return DOUBLE_0; - case Float: - return FLOAT_0; - case Long: - return LONG_0; - case Object: - return NULL_POINTER; - default: - throw new IllegalArgumentException(kind.toString()); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.util.IllegalFormatException; -import java.util.UnknownFormatConversionException; - -/** - * Represents a reference to a Java field, either resolved or unresolved fields. Fields, like - * methods and types, are resolved through {@link ConstantPool constant pools}. - */ -public interface JavaField { - - /** - * Returns the name of this field. - */ - String getName(); - - /** - * Returns a {@link JavaType} object that identifies the declared type for this field. - */ - JavaType getType(); - - /** - * Returns the kind of this field. This is the same as calling {@link #getType}. - * {@link JavaType#getJavaKind getJavaKind}. - */ - default JavaKind getJavaKind() { - return getType().getJavaKind(); - } - - /** - * Returns the {@link JavaType} object representing the class or interface that declares this - * field. - */ - JavaType getDeclaringClass(); - - /** - * Gets a string for this field formatted according to a given format specification. A format - * specification is composed of characters that are to be copied verbatim to the result and - * specifiers that denote an attribute of this field that is to be copied to the result. A - * specifier is a single character preceded by a '%' character. The accepted specifiers and the - * field attributes they denote are described below: - * - *
    -     *     Specifier | Description                                          | Example(s)
    -     *     ----------+------------------------------------------------------------------------------------------
    -     *     'T'       | Qualified type                                       | "int" "java.lang.String"
    -     *     't'       | Unqualified type                                     | "int" "String"
    -     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
    -     *     'h'       | Unqualified holder                                   | "Entry"
    -     *     'n'       | Field name                                           | "age"
    -     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
    -     *     '%'       | A '%' character                                      | "%"
    -     * 
    - * - * @param format a format specification - * @return the result of formatting this field according to {@code format} - * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} - */ - default String format(String format) throws IllegalFormatException { - StringBuilder sb = new StringBuilder(); - int index = 0; - JavaType type = getType(); - while (index < format.length()) { - char ch = format.charAt(index++); - if (ch == '%') { - if (index >= format.length()) { - throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification"); - } - char specifier = format.charAt(index++); - switch (specifier) { - case 'T': - case 't': { - sb.append(type.toJavaName(specifier == 'T')); - break; - } - case 'H': - case 'h': { - sb.append(getDeclaringClass().toJavaName(specifier == 'H')); - break; - } - case 'n': { - sb.append(getName()); - break; - } - case 'f': { - sb.append(!(this instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) this).isStatic() ? "static" : "instance"); - break; - } - case '%': { - sb.append('%'); - break; - } - default: { - throw new UnknownFormatConversionException(String.valueOf(specifier)); - } - } - } else { - sb.append(ch); - } - } - return sb.toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,479 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.meta; - -import java.lang.reflect.Array; - -//JaCoCo Exclude - -/** - * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example, - * {@link JavaKind#Int} for {@code int} and {@link JavaKind#Object} for all object types. A kind has - * a single character short name, a Java name, and a set of flags further describing its behavior. - */ -public enum JavaKind { - /** The primitive boolean kind, represented as an int on the stack. */ - Boolean('Z', 4, "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class), - - /** The primitive byte kind, represented as an int on the stack. */ - Byte('B', 8, "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class), - - /** The primitive short kind, represented as an int on the stack. */ - Short('S', 9, "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class), - - /** The primitive char kind, represented as an int on the stack. */ - Char('C', 5, "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class), - - /** The primitive int kind, represented as an int on the stack. */ - Int('I', 10, "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class), - - /** The primitive float kind. */ - Float('F', 6, "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class), - - /** The primitive long kind. */ - Long('J', 11, "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class), - - /** The primitive double kind. */ - Double('D', 7, "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class), - - /** The Object kind, also used for arrays. */ - Object('A', 12, "Object", 1, false, null, null), - - /** The void kind. */ - Void('V', 14, "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class), - - /** The non-type. */ - Illegal('-', 99, "illegal", 0, false, null, null); - - private final char typeChar; - private final String javaName; - private final boolean isStackInt; - private final Class primitiveJavaClass; - private final Class boxedJavaClass; - private final int slotCount; - private final int basicType; - - JavaKind(char typeChar, int basicType, String javaName, int slotCount, boolean isStackInt, Class primitiveJavaClass, Class boxedJavaClass) { - this.typeChar = typeChar; - this.javaName = javaName; - this.slotCount = slotCount; - this.isStackInt = isStackInt; - this.primitiveJavaClass = primitiveJavaClass; - this.boxedJavaClass = boxedJavaClass; - this.basicType = basicType; - assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName()); - } - - /** - * Returns the number of stack slots occupied by this kind according to the Java bytecodes - * specification. - */ - public int getSlotCount() { - return this.slotCount; - } - - /** - * Returns whether this kind occupied two stack slots. - */ - public boolean needsTwoSlots() { - return this.slotCount == 2; - } - - /** - * Returns the name of the kind as a single upper case character. For the void and primitive - * kinds, this is the FieldType term in - * - * table 4.3-A of the JVM Specification. For {@link #Object}, the character {@code 'A'} is - * returned and for {@link #Illegal}, {@code '-'} is returned. - */ - public char getTypeChar() { - return typeChar; - } - - /** - * Returns the JVM BasicType value for this type. - */ - public int getBasicType() { - return basicType; - } - - /** - * Returns the name of this kind which will also be it Java programming language name if it is - * {@linkplain #isPrimitive() primitive} or {@code void}. - */ - public String getJavaName() { - return javaName; - } - - /** - * Checks whether this type is a Java primitive type. - * - * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, - * {@link #Short}, {@link #Int}, {@link #Long}, {@link #Float}, {@link #Double}, or - * {@link #Void}. - */ - public boolean isPrimitive() { - return primitiveJavaClass != null; - } - - /** - * Returns the kind that represents this kind when on the Java operand stack. - * - * @return the kind used on the operand stack - */ - public JavaKind getStackKind() { - if (isStackInt) { - return Int; - } - return this; - } - - /** - * Checks whether this type is a Java primitive type representing an integer number. - * - * @return {@code true} if the stack kind is {@link #Int} or {@link #Long}. - */ - public boolean isNumericInteger() { - return isStackInt || this == JavaKind.Long; - } - - /** - * Checks whether this type is a Java primitive type representing an unsigned number. - * - * @return {@code true} if the kind is {@link #Boolean} or {@link #Char}. - */ - public boolean isUnsigned() { - return this == JavaKind.Boolean || this == JavaKind.Char; - } - - /** - * Checks whether this type is a Java primitive type representing a floating point number. - * - * @return {@code true} if this is {@link #Float} or {@link #Double}. - */ - public boolean isNumericFloat() { - return this == JavaKind.Float || this == JavaKind.Double; - } - - /** - * Checks whether this represent an Object of some sort. - * - * @return {@code true} if this is {@link #Object}. - */ - public boolean isObject() { - return this == JavaKind.Object; - } - - /** - * Returns the kind corresponding to the Java type string. - * - * @param typeString the Java type string - * @return the kind - */ - public static JavaKind fromTypeString(String typeString) { - assert typeString.length() > 0; - final char first = typeString.charAt(0); - if (first == '[' || first == 'L') { - return JavaKind.Object; - } - return JavaKind.fromPrimitiveOrVoidTypeChar(first); - } - - /** - * Returns the kind of a word given the size of a word in bytes. - * - * @param wordSizeInBytes the size of a word in bytes - * @return the kind representing a word value - */ - public static JavaKind fromWordSize(int wordSizeInBytes) { - if (wordSizeInBytes == 8) { - return JavaKind.Long; - } else { - assert wordSizeInBytes == 4 : "Unsupported word size!"; - return JavaKind.Int; - } - } - - /** - * Returns the kind from the character describing a primitive or void. - * - * @param ch the character for a void or primitive kind as returned by {@link #getTypeChar()} - * @return the kind - */ - public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) { - switch (ch) { - case 'Z': - return Boolean; - case 'C': - return Char; - case 'F': - return Float; - case 'D': - return Double; - case 'B': - return Byte; - case 'S': - return Short; - case 'I': - return Int; - case 'J': - return Long; - case 'V': - return Void; - } - throw new IllegalArgumentException("unknown primitive or void type character: " + ch); - } - - /** - * Returns the Kind representing the given Java class. - * - * @param klass the class - * @return the kind - */ - public static JavaKind fromJavaClass(Class klass) { - if (klass == Boolean.primitiveJavaClass) { - return Boolean; - } else if (klass == Byte.primitiveJavaClass) { - return Byte; - } else if (klass == Short.primitiveJavaClass) { - return Short; - } else if (klass == Char.primitiveJavaClass) { - return Char; - } else if (klass == Int.primitiveJavaClass) { - return Int; - } else if (klass == Long.primitiveJavaClass) { - return Long; - } else if (klass == Float.primitiveJavaClass) { - return Float; - } else if (klass == Double.primitiveJavaClass) { - return Double; - } else if (klass == Void.primitiveJavaClass) { - return Void; - } else { - return Object; - } - } - - /** - * Returns the Java class representing this kind. - * - * @return the Java class - */ - public Class toJavaClass() { - return primitiveJavaClass; - } - - /** - * Returns the Java class for instances of boxed values of this kind. - * - * @return the Java class - */ - public Class toBoxedJavaClass() { - return boxedJavaClass; - } - - /** - * Converts this value type to a string. - */ - @Override - public String toString() { - return javaName; - } - - /** - * Marker interface for types that should be {@linkplain JavaKind#format(Object) formatted} with - * their {@link Object#toString()} value. Calling {@link Object#toString()} on other objects - * poses a security risk because it can potentially call user code. - */ - public interface FormatWithToString { - } - - /** - * Classes for which invoking {@link Object#toString()} does not run user code. - */ - private static boolean isToStringSafe(Class c) { - return c == Boolean.class || c == Byte.class || c == Character.class || c == Short.class || c == Integer.class || c == Float.class || c == Long.class || c == Double.class; - } - - /** - * Gets a formatted string for a given value of this kind. - * - * @param value a value of this kind - * @return a formatted string for {@code value} based on this kind - */ - public String format(Object value) { - if (isPrimitive()) { - assert isToStringSafe(value.getClass()); - return value.toString(); - } else { - if (value == null) { - return "null"; - } else { - if (value instanceof String) { - String s = (String) value; - if (s.length() > 50) { - return "String:\"" + s.substring(0, 30) + "...\""; - } else { - return "String:\"" + s + '"'; - } - } else if (value instanceof JavaType) { - return "JavaType:" + ((JavaType) value).toJavaName(); - } else if (value instanceof Enum) { - return MetaUtil.getSimpleName(value.getClass(), true) + ":" + ((Enum) value).name(); - } else if (value instanceof FormatWithToString) { - return MetaUtil.getSimpleName(value.getClass(), true) + ":" + String.valueOf(value); - } else if (value instanceof Class) { - return "Class:" + ((Class) value).getName(); - } else if (isToStringSafe(value.getClass())) { - return value.toString(); - } else if (value.getClass().isArray()) { - return formatArray(value); - } else { - return MetaUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value); - } - } - } - } - - private static final int MAX_FORMAT_ARRAY_LENGTH = 5; - - private static String formatArray(Object array) { - Class componentType = array.getClass().getComponentType(); - assert componentType != null; - int arrayLength = Array.getLength(array); - StringBuilder buf = new StringBuilder(MetaUtil.getSimpleName(componentType, true)).append('[').append(arrayLength).append("]{"); - int length = Math.min(MAX_FORMAT_ARRAY_LENGTH, arrayLength); - boolean primitive = componentType.isPrimitive(); - for (int i = 0; i < length; i++) { - if (primitive) { - buf.append(Array.get(array, i)); - } else { - Object o = ((Object[]) array)[i]; - buf.append(JavaKind.Object.format(o)); - } - if (i != length - 1) { - buf.append(", "); - } - } - if (arrayLength != length) { - buf.append(", ..."); - } - return buf.append('}').toString(); - } - - /** - * Gets the minimum value that can be represented as a value of this kind. - * - * @return the minimum value represented as a {@code long} - */ - public long getMinValue() { - switch (this) { - case Boolean: - return 0; - case Byte: - return java.lang.Byte.MIN_VALUE; - case Char: - return java.lang.Character.MIN_VALUE; - case Short: - return java.lang.Short.MIN_VALUE; - case Int: - return java.lang.Integer.MIN_VALUE; - case Long: - return java.lang.Long.MIN_VALUE; - case Float: - return java.lang.Float.floatToRawIntBits(java.lang.Float.MIN_VALUE); - case Double: - return java.lang.Double.doubleToRawLongBits(java.lang.Double.MIN_VALUE); - default: - throw new IllegalArgumentException("illegal call to minValue on " + this); - } - } - - /** - * Gets the maximum value that can be represented as a value of this kind. - * - * @return the maximum value represented as a {@code long} - */ - public long getMaxValue() { - switch (this) { - case Boolean: - return 1; - case Byte: - return java.lang.Byte.MAX_VALUE; - case Char: - return java.lang.Character.MAX_VALUE; - case Short: - return java.lang.Short.MAX_VALUE; - case Int: - return java.lang.Integer.MAX_VALUE; - case Long: - return java.lang.Long.MAX_VALUE; - case Float: - return java.lang.Float.floatToRawIntBits(java.lang.Float.MAX_VALUE); - case Double: - return java.lang.Double.doubleToRawLongBits(java.lang.Double.MAX_VALUE); - default: - throw new IllegalArgumentException("illegal call to maxValue on " + this); - } - } - - /** - * Number of bytes that are necessary to represent a value of this kind. - * - * @return the number of bytes - */ - public int getByteCount() { - if (this == Boolean) { - return 1; - } else { - return getBitCount() >> 3; - } - } - - /** - * Number of bits that are necessary to represent a value of this kind. - * - * @return the number of bits - */ - public int getBitCount() { - switch (this) { - case Boolean: - return 1; - case Byte: - return 8; - case Char: - case Short: - return 16; - case Float: - return 32; - case Int: - return 32; - case Double: - return 64; - case Long: - return 64; - default: - throw new IllegalArgumentException("illegal call to getBitCount() on " + this); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.util.IllegalFormatException; -import java.util.UnknownFormatConversionException; - -/** - * Represents a reference to a Java method, either resolved or unresolved. Methods, like fields and - * types, are resolved through {@link ConstantPool constant pools}. - */ -public interface JavaMethod { - - /** - * Returns the name of this method. - */ - String getName(); - - /** - * Returns the {@link JavaType} object representing the class or interface that declares this - * method. - */ - JavaType getDeclaringClass(); - - /** - * Returns the signature of this method. - */ - Signature getSignature(); - - /** - * Gets a string for this method formatted according to a given format specification. A format - * specification is composed of characters that are to be copied verbatim to the result and - * specifiers that denote an attribute of this method that is to be copied to the result. A - * specifier is a single character preceded by a '%' character. The accepted specifiers and the - * method attributes they denote are described below: - * - *
    -     *     Specifier | Description                                          | Example(s)
    -     *     ----------+------------------------------------------------------------------------------------------
    -     *     'R'       | Qualified return type                                | "int" "java.lang.String"
    -     *     'r'       | Unqualified return type                              | "int" "String"
    -     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
    -     *     'h'       | Unqualified holder                                   | "Entry"
    -     *     'n'       | Method name                                          | "add"
    -     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
    -     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
    -     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
    -     *     '%'       | A '%' character                                      | "%"
    -     * 
    - * - * @param format a format specification - * @return the result of formatting this method according to {@code format} - * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} - */ - default String format(String format) throws IllegalFormatException { - StringBuilder sb = new StringBuilder(); - int index = 0; - Signature sig = null; - while (index < format.length()) { - char ch = format.charAt(index++); - if (ch == '%') { - if (index >= format.length()) { - throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification"); - } - char specifier = format.charAt(index++); - switch (specifier) { - case 'R': - case 'r': { - if (sig == null) { - sig = getSignature(); - } - sb.append(sig.getReturnType(null).toJavaName(specifier == 'R')); - break; - } - case 'H': - case 'h': { - sb.append(getDeclaringClass().toJavaName(specifier == 'H')); - break; - } - case 'n': { - sb.append(getName()); - break; - } - case 'P': - case 'p': { - if (sig == null) { - sig = getSignature(); - } - for (int i = 0; i < sig.getParameterCount(false); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(sig.getParameterType(i, null).toJavaName(specifier == 'P')); - } - break; - } - case 'f': { - sb.append(!(this instanceof ResolvedJavaMethod) ? "unresolved" : ((ResolvedJavaMethod) this).isStatic() ? "static" : "virtual"); - break; - } - case '%': { - sb.append('%'); - break; - } - default: { - throw new UnknownFormatConversionException(String.valueOf(specifier)); - } - } - } else { - sb.append(ch); - } - } - return sb.toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethodProfile.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethodProfile.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethodProfile.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethodProfile.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod; - -/** - * This profile object represents the method profile at a specific BCI. The precision of the - * supplied values may vary, but a runtime that provides this information should be aware that it - * will be used to guide performance-critical decisions like speculative inlining, etc. - */ -public final class JavaMethodProfile extends AbstractJavaProfile { - - public JavaMethodProfile(double notRecordedProbability, ProfiledMethod[] pitems) { - super(notRecordedProbability, pitems); - } - - public ProfiledMethod[] getMethods() { - return super.getItems(); - } - - public static class ProfiledMethod extends AbstractProfiledItem { - - public ProfiledMethod(ResolvedJavaMethod method, double probability) { - super(method, probability); - } - - /** - * Returns the type for this profile entry. - */ - public ResolvedJavaMethod getMethod() { - return getItem(); - } - - @Override - public String toString() { - return "{" + item.getName() + ", " + probability + "}"; - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import static jdk.vm.ci.meta.MetaUtil.internalNameToJava; - -/** - * Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and - * arrays thereof. - */ -public interface JavaType { - - /** - * Returns the name of this type in internal form. The following are examples of strings - * returned by this method: - * - *
    -     *     "Ljava/lang/Object;"
    -     *     "I"
    -     *     "[[B"
    -     * 
    - */ - String getName(); - - /** - * Returns an unqualified name of this type. - * - *
    -     *     "Object"
    -     *     "Integer"
    -     * 
    - */ - default String getUnqualifiedName() { - String name = getName(); - if (name.indexOf('/') != -1) { - name = name.substring(name.lastIndexOf('/') + 1); - } - if (name.endsWith(";")) { - name = name.substring(0, name.length() - 1); - } - return name; - } - - /** - * Checks whether this type is an array class. - * - * @return {@code true} if this type is an array class - */ - default boolean isArray() { - return getComponentType() != null; - } - - /** - * For array types, gets the type of the components, or {@code null} if this is not an array - * type. This method is analogous to {@link Class#getComponentType()}. - */ - JavaType getComponentType(); - - /** - * Gets the elemental type for this given type. The elemental type is the corresponding zero - * dimensional type of an array type. For example, the elemental type of {@code int[][][]} is - * {@code int}. A non-array type is its own elemental type. - */ - default JavaType getElementalType() { - JavaType t = this; - while (t.getComponentType() != null) { - t = t.getComponentType(); - } - return t; - } - - /** - * Gets the array class type representing an array with elements of this type. - */ - JavaType getArrayClass(); - - /** - * Gets the {@link JavaKind} of this type. - */ - JavaKind getJavaKind(); - - /** - * Resolves this type to a {@link ResolvedJavaType}. - * - * @param accessingClass the context of resolution (must not be null) - * @return the resolved Java type - * @throws LinkageError if the resolution failed - * @throws NullPointerException if {@code accessingClass} is {@code null} - */ - ResolvedJavaType resolve(ResolvedJavaType accessingClass); - - /** - * Gets the Java programming language name for this type. The following are examples of strings - * returned by this method: - * - *
    -     *      java.lang.Object
    -     *      int
    -     *      boolean[][]
    -     * 
    - * - * @return the Java name corresponding to this type - */ - default String toJavaName() { - return internalNameToJava(getName(), true, false); - } - - /** - * Gets the Java programming language name for this type. The following are examples of strings - * returned by this method: - * - *
    -     *     qualified == true:
    -     *         java.lang.Object
    -     *         int
    -     *         boolean[][]
    -     *     qualified == false:
    -     *         Object
    -     *         int
    -     *         boolean[][]
    -     * 
    - * - * @param qualified specifies if the package prefix of this type should be included in the - * returned name - * @return the Java name corresponding to this type - */ - default String toJavaName(boolean qualified) { - JavaKind kind = getJavaKind(); - if (kind == JavaKind.Object) { - return internalNameToJava(getName(), qualified, false); - } - return getJavaKind().getJavaName(); - } - - /** - * Returns this type's name in the same format as {@link Class#getName()}. - */ - default String toClassName() { - return internalNameToJava(getName(), true, true); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2011, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.lang.reflect.Modifier; -import java.util.ArrayList; - -import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType; - -/** - * This profile object represents the type profile at a specific BCI. The precision of the supplied - * values may vary, but a runtime that provides this information should be aware that it will be - * used to guide performance-critical decisions like speculative inlining, etc. - */ -public final class JavaTypeProfile extends AbstractJavaProfile { - - private static final ProfiledType[] EMPTY_ARRAY = new ProfiledType[0]; - - private final TriState nullSeen; - - public JavaTypeProfile(TriState nullSeen, double notRecordedProbability, ProfiledType[] pitems) { - super(notRecordedProbability, pitems); - this.nullSeen = nullSeen; - } - - /** - * Returns whether a null value was at the type check. - */ - public TriState getNullSeen() { - return nullSeen; - } - - /** - * A list of types for which the runtime has recorded probability information. Note that this - * includes both positive and negative types where a positive type is a subtype of the checked - * type and a negative type is not. - */ - public ProfiledType[] getTypes() { - return getItems(); - } - - public JavaTypeProfile restrict(JavaTypeProfile otherProfile) { - if (otherProfile.getNotRecordedProbability() > 0.0) { - // Not useful for restricting since there is an unknown set of types occurring. - return this; - } - - if (this.getNotRecordedProbability() > 0.0) { - // We are unrestricted, so the other profile is always a better estimate. - return otherProfile; - } - - ArrayList result = new ArrayList<>(); - for (int i = 0; i < getItems().length; i++) { - ProfiledType ptype = getItems()[i]; - ResolvedJavaType type = ptype.getItem(); - if (otherProfile.isIncluded(type)) { - result.add(ptype); - } - } - - TriState newNullSeen = (otherProfile.getNullSeen() == TriState.FALSE) ? TriState.FALSE : getNullSeen(); - double newNotRecorded = getNotRecordedProbability(); - return createAdjustedProfile(result, newNullSeen, newNotRecorded); - } - - public JavaTypeProfile restrict(ResolvedJavaType declaredType, boolean nonNull) { - ArrayList result = new ArrayList<>(); - for (int i = 0; i < getItems().length; i++) { - ProfiledType ptype = getItems()[i]; - ResolvedJavaType type = ptype.getItem(); - if (declaredType.isAssignableFrom(type)) { - result.add(ptype); - } - } - - TriState newNullSeen = (nonNull) ? TriState.FALSE : getNullSeen(); - double newNotRecorded = this.getNotRecordedProbability(); - // Assume for the types not recorded, the incompatibility rate is the same. - if (getItems().length != 0) { - newNotRecorded *= ((double) result.size() / (double) getItems().length); - } - return createAdjustedProfile(result, newNullSeen, newNotRecorded); - } - - private JavaTypeProfile createAdjustedProfile(ArrayList result, TriState newNullSeen, double newNotRecorded) { - if (result.size() != this.getItems().length || newNotRecorded != getNotRecordedProbability() || newNullSeen != getNullSeen()) { - if (result.size() == 0) { - return new JavaTypeProfile(newNullSeen, 1.0, EMPTY_ARRAY); - } - double factor; - if (result.size() == this.getItems().length) { - /* List of types did not change, no need to recompute probabilities. */ - factor = 1.0; - } else { - double probabilitySum = 0.0; - for (int i = 0; i < result.size(); i++) { - probabilitySum += result.get(i).getProbability(); - } - probabilitySum += newNotRecorded; - - factor = 1.0 / probabilitySum; // Normalize to 1.0 - assert factor >= 1.0; - } - ProfiledType[] newResult = new ProfiledType[result.size()]; - for (int i = 0; i < newResult.length; ++i) { - ProfiledType curType = result.get(i); - newResult[i] = new ProfiledType(curType.getItem(), Math.min(1.0, curType.getProbability() * factor)); - } - double newNotRecordedTypeProbability = Math.min(1.0, newNotRecorded * factor); - return new JavaTypeProfile(newNullSeen, newNotRecordedTypeProbability, newResult); - } - return this; - } - - @Override - public boolean equals(Object other) { - return super.equals(other) && nullSeen.equals(((JavaTypeProfile) other).nullSeen); - } - - @Override - public int hashCode() { - return nullSeen.hashCode() + super.hashCode(); - } - - public static class ProfiledType extends AbstractProfiledItem { - - public ProfiledType(ResolvedJavaType type, double probability) { - super(type, probability); - assert type.isArray() || type.isConcrete() : type + " " + Modifier.toString(type.getModifiers()); - } - - /** - * Returns the type for this profile entry. - */ - public ResolvedJavaType getType() { - return getItem(); - } - - @Override - public String toString() { - return String.format("%.6f#%s", probability, item); - } - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder("JavaTypeProfile", getNotRecordedProbability())).toString(); - } - - /** - * Returns {@code true} if all types seen at this location have been recorded in the profile. - */ - public boolean allTypesRecorded() { - return this.getNotRecordedProbability() == 0.0; - } - - /** - * Returns the single monormorphic type representing this profile or {@code null} if no such - * type exists. - */ - public ResolvedJavaType asSingleType() { - if (allTypesRecorded() && this.getTypes().length == 1) { - return getTypes()[0].getType(); - } - return null; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaValue.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaValue.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaValue.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaValue.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package jdk.vm.ci.meta; - -/** - * Marker interface for things that represent a Java value. - */ -public interface JavaValue { -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTable.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTable.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTable.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTable.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Maps bytecode indexes to source line numbers. - * - * @see "https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.12" - */ -public class LineNumberTable { - - private final int[] lineNumbers; - private final int[] bcis; - - /** - * - * @param lineNumbers an array of source line numbers. This array is now owned by this object - * and should not be mutated by the caller. - * @param bcis an array of bytecode indexes the same length at {@code lineNumbers} whose entries - * are sorted in ascending order. This array is now owned by this object and must not - * be mutated by the caller. - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `lineNumbers` and `bcis`") - public LineNumberTable(int[] lineNumbers, int[] bcis) { - assert bcis.length == lineNumbers.length; - this.lineNumbers = lineNumbers; - this.bcis = bcis; - } - - /** - * Gets a source line number for bytecode index {@code atBci}. - */ - public int getLineNumber(int atBci) { - for (int i = 0; i < this.bcis.length - 1; i++) { - if (this.bcis[i] <= atBci && atBci < this.bcis[i + 1]) { - return lineNumbers[i]; - } - } - return lineNumbers[lineNumbers.length - 1]; - } - - /** - * Gets a copy of the array of line numbers that was passed to this object's constructor. - */ - public int[] getLineNumbers() { - return lineNumbers.clone(); - } - - /** - * Gets a copy of the array of bytecode indexes that was passed to this object's constructor. - */ - public int[] getBcis() { - return bcis.clone(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Local.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Local.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Local.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Local.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Describes the type and bytecode index range in which a local variable is live. - */ -public class Local { - - private final String name; - private final int startBci; - private final int endBci; - private final int slot; - private final JavaType type; - - public Local(String name, JavaType type, int startBci, int endBci, int slot) { - this.name = name; - this.startBci = startBci; - this.endBci = endBci; - this.slot = slot; - this.type = type; - } - - public int getStartBCI() { - return startBci; - } - - public int getEndBCI() { - return endBci; - } - - public String getName() { - return name; - } - - public JavaType getType() { - return type; - } - - public int getSlot() { - return slot; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Local)) { - return false; - } - Local that = (Local) obj; - return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public String toString() { - return "LocalImpl"; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTable.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTable.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTable.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTable.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.util.ArrayList; -import java.util.List; - -/** - * Describes the {@link Local}s for a Java method. - * - * @see "https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.13" - */ -public class LocalVariableTable { - - private final Local[] locals; - - /** - * Creates an object describing the {@link Local}s for a Java method. - * - * @param locals array of objects describing local variables. This array is now owned by this - * object and must not be mutated by the caller. - */ - @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `locals`") - public LocalVariableTable(Local[] locals) { - this.locals = locals; - } - - /** - * Gets a description of a local variable that occupies the bytecode frame slot indexed by - * {@code slot} and is live at the bytecode index {@code bci}. - * - * @return a description of the requested local variable or null if no such variable matches - * {@code slot} and {@code bci} - */ - public Local getLocal(int slot, int bci) { - Local result = null; - for (Local local : locals) { - if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) { - if (result == null) { - result = local; - } else { - throw new IllegalStateException("Locals overlap!"); - } - } - } - return result; - } - - /** - * Gets a copy of the array of {@link Local}s that was passed to this object's constructor. - */ - public Local[] getLocals() { - return locals.clone(); - } - - /** - * Gets a description of all the local variables live at the bytecode index {@code bci}. - */ - public Local[] getLocalsAt(int bci) { - List result = new ArrayList<>(); - for (Local l : locals) { - if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) { - result.add(l); - } - } - return result.toArray(new Local[result.size()]); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ -package jdk.vm.ci.meta; - -/** - * Provides memory access operations for the target VM. - */ -public interface MemoryAccessProvider { - - /** - * Reads a primitive value using a base address and a displacement. - * - * @param kind the {@link JavaKind} of the returned {@link JavaConstant} object - * @param base the base address from which the value is read - * @param displacement the displacement within the object in bytes - * @param bits the number of bits to read from memory - * @return the read value encapsulated in a {@link JavaConstant} object of {@link JavaKind} kind - * @throws IllegalArgumentException if the read is out of bounds of the object or {@code kind} - * is {@link JavaKind#Void} or not {@linkplain JavaKind#isPrimitive() primitive} - * kind or {@code bits} is not 8, 16, 32 or 64, or the read is unaligned - */ - JavaConstant readPrimitiveConstant(JavaKind kind, Constant base, long displacement, int bits) throws IllegalArgumentException; - - /** - * Reads a Java {@link Object} value using a base address and a displacement. - * - * @param base the base address from which the value is read - * @param displacement the displacement within the object in bytes - * @return the read value encapsulated in a {@link Constant} object - * @throws IllegalArgumentException if the address computed from {@code base} and - * {@code displacement} does not denote a location holding an {@code Object} value - */ - JavaConstant readObjectConstant(Constant base, long displacement); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import jdk.vm.ci.meta.SpeculationLog.Speculation; - -/** - * Provides access to the metadata of a class typically provided in a class file. - */ -public interface MetaAccessProvider { - - /** - * Returns the resolved Java type representing a given Java class. - * - * @param clazz the Java class object - * @return the resolved Java type object - */ - ResolvedJavaType lookupJavaType(Class clazz); - - /** - * Returns the resolved Java types representing some given Java classes. - * - * @param classes the Java class objects - * @return the resolved Java type objects - */ - default ResolvedJavaType[] lookupJavaTypes(Class[] classes) { - ResolvedJavaType[] result = new ResolvedJavaType[classes.length]; - for (int i = 0; i < result.length; i++) { - result[i] = lookupJavaType(classes[i]); - } - return result; - } - - /** - * Provides the {@link ResolvedJavaMethod} for a {@link Method} or {@link Constructor} obtained - * via reflection. - */ - ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod); - - /** - * Provides the {@link ResolvedJavaField} for a {@link Field} obtained via reflection. - */ - ResolvedJavaField lookupJavaField(Field reflectionField); - - /** - * Returns the resolved Java type of the given {@link JavaConstant} object. - * - * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()} - */ - ResolvedJavaType lookupJavaType(JavaConstant constant); - - /** - * Returns the number of bytes occupied by this constant value or constant object. - * - * @param constant the constant whose bytes should be measured - * @return the number of bytes occupied by this constant - */ - long getMemorySize(JavaConstant constant); - - /** - * Parses a - * method - * descriptor into a {@link Signature}. - * - * @throws IllegalArgumentException if the method descriptor is not well formed - */ - Signature parseMethodDescriptor(String methodDescriptor); - - /** - * Encodes a deoptimization action and a deoptimization reason in an integer value. - * - * @param debugId an integer that can be used to track the origin of a deoptimization at - * runtime. There is no guarantee that the runtime will use this value. The runtime - * may even keep fewer than 32 bits. - * - * @return the encoded value as an integer - */ - JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId); - - /** - * Gets a constant that denotes {@code speculation}. The constant can passed to the - * deoptimization handler (e.g., through a thread local) to indicate a failed speculation. - */ - JavaConstant encodeSpeculation(Speculation speculation); - - /** - * Decodes {@code constant} back to a {@link Speculation} object. - * - * @throws IllegalArgumentException if {@code constant} can only be decoded through a - * {@link SpeculationLog} and {@code speculationLog} does not contain the - * speculation denoted by {@code constant} - */ - Speculation decodeSpeculation(JavaConstant constant, SpeculationLog speculationLog); - - DeoptimizationReason decodeDeoptReason(JavaConstant constant); - - DeoptimizationAction decodeDeoptAction(JavaConstant constant); - - int decodeDebugId(JavaConstant constant); - - int getArrayBaseOffset(JavaKind elementKind); - - int getArrayIndexScale(JavaKind elementKind); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients. - */ -public class MetaUtil { - - public static final char PACKAGE_SEPARATOR_INTERNAL = '/'; - public static final char HIDDEN_SEPARATOR_INTERNAL = '.'; - public static final char PACKAGE_SEPARATOR_JAVA = HIDDEN_SEPARATOR_INTERNAL; - public static final char HIDDEN_SEPARATOR_JAVA = PACKAGE_SEPARATOR_INTERNAL; - - /** - * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for - * anonymous and local classes. - * - * @param clazz the class for which the simple name is being requested - * @param withEnclosingClass specifies if the returned name should be qualified with the name(s) - * of the enclosing class/classes of {@code clazz} (if any). This option is ignored - * if {@code clazz} denotes an anonymous or local class. - * @return the simple name - */ - public static String getSimpleName(Class clazz, boolean withEnclosingClass) { - final String simpleName = safeSimpleName(clazz); - if (simpleName.length() != 0) { - if (withEnclosingClass) { - String prefix = ""; - Class enclosingClass = clazz; - while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) { - prefix = safeSimpleName(enclosingClass) + "." + prefix; - } - return prefix + simpleName; - } - return simpleName; - } - // Must be an anonymous or local class - final String name = clazz.getName(); - int index = name.indexOf('$'); - if (index == -1) { - return name; - } - index = name.lastIndexOf('.', index); - if (index == -1) { - return name; - } - return name.substring(index + 1); - } - - private static String safeSimpleName(Class clazz) { - try { - return clazz.getSimpleName(); - } catch (InternalError e) { - // Scala inner class names do not always start with '$', - // causing Class.getSimpleName to throw an InternalError - Class enclosingClass = clazz.getEnclosingClass(); - String fqn = clazz.getName(); - if (enclosingClass == null) { - // Should never happen given logic in - // Class.getSimpleName but best be safe - return fqn; - } - String enclosingFQN = enclosingClass.getName(); - int length = fqn.length(); - if (enclosingFQN.length() >= length) { - // Should also never happen - return fqn; - } - return fqn.substring(enclosingFQN.length()); - } - } - - /** - * Hidden classes have {@code /} characters in their internal names and {@code .} characters in their names returned - * by {@link Class#getName()} that are not package separators. - * These are distinguished by being followed by a character that is not a - * {@link Character#isJavaIdentifierStart(char)} (e.g., - * "jdk.vm.ci.runtime.test.TypeUniverse$$Lambda$1/869601985"). - * - * @param name the name to perform the replacements on - * @param packageSeparator the {@link Character} used as the package separator, e.g. {@code /} in internal form - * @param hiddenSeparator the {@link Character} used as the hidden class separator, e.g. {@code .} in internal form - */ - private static String replacePackageAndHiddenSeparators(String name, Character packageSeparator, Character hiddenSeparator) { - int index = name.indexOf(hiddenSeparator); // check if it's a hidden class - int length = name.length(); - StringBuilder buf = new StringBuilder(length); - if (index < 0) { - buf.append(name.replace(packageSeparator, hiddenSeparator)); - } else { - buf.append(name.substring(0, index).replace(packageSeparator, hiddenSeparator)); - buf.append(packageSeparator); - buf.append(name.substring(index + 1)); - } - return buf.toString(); - } - - /** - * Converts a type name in internal form to an external form. - * - * @param name the internal name to convert - * @param qualified whether the returned name should be qualified with the package name - * @param classForNameCompatible specifies if the returned name for array types should be in - * {@link Class#forName(String)} format (e.g., {@code "[Ljava.lang.Object;"}, - * {@code "[[I"}) or in Java source code format (e.g., {@code "java.lang.Object[]"}, - * {@code "int[][]"} ). - */ - public static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) { - switch (name.charAt(0)) { - case 'L': { - String type = name.substring(1, name.length() - 1); - String result = replacePackageAndHiddenSeparators(type, PACKAGE_SEPARATOR_INTERNAL, HIDDEN_SEPARATOR_INTERNAL); - if (!qualified) { - final int lastDot = result.lastIndexOf(HIDDEN_SEPARATOR_INTERNAL); - if (lastDot != -1) { - result = result.substring(lastDot + 1); - } - } - return result; - } - case '[': - if (classForNameCompatible) { - return replacePackageAndHiddenSeparators(name, PACKAGE_SEPARATOR_INTERNAL, HIDDEN_SEPARATOR_INTERNAL); - } else { - return internalNameToJava(name.substring(1), qualified, false) + "[]"; - } - default: - if (name.length() != 1) { - throw new IllegalArgumentException("Illegal internal name: " + name); - } - return JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)).getJavaName(); - } - } - - /** - * Convenient shortcut for calling - * {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a - * {@link StringBuilder} instance and convert the result to a string. - */ - public static String toLocation(ResolvedJavaMethod method, int bci) { - return appendLocation(new StringBuilder(), method, bci).toString(); - } - - /** - * Appends a string representation of a location specified by a given method and bci to a given - * {@link StringBuilder}. If a stack trace element with a non-null file name and non-negative - * line number is {@linkplain ResolvedJavaMethod#asStackTraceElement(int) available} for the - * given method, then the string returned is the {@link StackTraceElement#toString()} value of - * the stack trace element, suffixed by the bci location. For example: - * - *
    -     *     java.lang.String.valueOf(String.java:2930) [bci: 12]
    -     * 
    - * - * Otherwise, the string returned is the value of applying {@link JavaMethod#format(String)} - * with the format string {@code "%H.%n(%p)"}, suffixed by the bci location. For example: - * - *
    -     *     java.lang.String.valueOf(int) [bci: 12]
    -     * 
    - * - * @param sb - * @param method - * @param bci - */ - public static StringBuilder appendLocation(StringBuilder sb, ResolvedJavaMethod method, int bci) { - if (method != null) { - StackTraceElement ste = method.asStackTraceElement(bci); - if (ste.getFileName() != null && ste.getLineNumber() > 0) { - sb.append(ste); - } else { - sb.append(method.format("%H.%n(%p)")); - } - } else { - sb.append("Null method"); - } - return sb.append(" [bci: ").append(bci).append(']'); - } - - static void appendProfile(StringBuilder buf, AbstractJavaProfile profile, int bci, String type, String sep) { - if (profile != null) { - AbstractProfiledItem[] pitems = profile.getItems(); - if (pitems != null) { - buf.append(String.format("%s@%d:", type, bci)); - for (int j = 0; j < pitems.length; j++) { - AbstractProfiledItem pitem = pitems[j]; - buf.append(String.format(" %.6f (%s)%s", pitem.getProbability(), pitem.getItem(), sep)); - } - if (profile.getNotRecordedProbability() != 0) { - buf.append(String.format(" %.6f %s", profile.getNotRecordedProbability(), type, sep)); - } else { - buf.append(String.format(" %s", type, sep)); - } - } - } - } - - /** - * Converts a Java source-language class name into the internal form. - * - * @param className the class name - * @return the internal name form of the class name - */ - public static String toInternalName(String className) { - if (className.startsWith("[")) { - /* Already in the correct array style. */ - return replacePackageAndHiddenSeparators(className, PACKAGE_SEPARATOR_JAVA, HIDDEN_SEPARATOR_JAVA); - } - - StringBuilder result = new StringBuilder(); - String base = className; - while (base.endsWith("[]")) { - result.append("["); - base = base.substring(0, base.length() - 2); - } - - switch (base) { - case "boolean": - result.append("Z"); - break; - case "byte": - result.append("B"); - break; - case "short": - result.append("S"); - break; - case "char": - result.append("C"); - break; - case "int": - result.append("I"); - break; - case "float": - result.append("F"); - break; - case "long": - result.append("J"); - break; - case "double": - result.append("D"); - break; - case "void": - result.append("V"); - break; - default: - result.append("L") - .append(replacePackageAndHiddenSeparators(base, PACKAGE_SEPARATOR_JAVA, HIDDEN_SEPARATOR_JAVA)) - .append(";"); - break; - } - return result.toString(); - } - - /** - * Gets a string representation of an object based soley on its class and its - * {@linkplain System#identityHashCode(Object) identity hash code}. This avoids and calls to - * virtual methods on the object such as {@link Object#hashCode()}. - */ - public static String identityHashCodeString(Object obj) { - if (obj == null) { - return "null"; - } - return obj.getClass().getName() + "@" + System.identityHashCode(obj); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.lang.invoke.MethodHandle; - -/** - * Interface to access the internals of the {@link MethodHandle} implementation of the VM. An - * implementation of this interface is usually required to access non-public classes, methods, and - * fields of {@link MethodHandle}, i.e., data that is not standardized by the Java specification. - */ -public interface MethodHandleAccessProvider { - - /** - * Identification for methods defined on the class {@link MethodHandle} that are processed by - * the {@link MethodHandleAccessProvider}. - */ - enum IntrinsicMethod { - /** The method {@code MethodHandle.invokeBasic}. */ - INVOKE_BASIC, - /** The method {@code MethodHandle.linkToStatic}. */ - LINK_TO_STATIC, - /** The method {@code MethodHandle.linkToSpecial}. */ - LINK_TO_SPECIAL, - /** The method {@code MethodHandle.linkToVirtual}. */ - LINK_TO_VIRTUAL, - /** The method {@code MethodHandle.linkToInterface}. */ - LINK_TO_INTERFACE - } - - /** - * Returns the method handle method intrinsic identifier for the provided method, or - * {@code null} if the method is not an intrinsic processed by this interface. - * - * @throws NullPointerException if {@code method} is null - */ - IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method); - - /** - * Resolves the invocation target for an invocation of {@link IntrinsicMethod#INVOKE_BASIC - * MethodHandle.invokeBasic} with the given constant receiver {@link MethodHandle}. Returns - * {@code null} if the invocation target is not available at this time. - * - * The first invocations of a method handle can use an interpreter to lookup the actual invoked - * method; frequently executed method handles can use Java bytecode generation to avoid the - * interpreter overhead. If the parameter forceBytecodeGeneration is set to true, the VM should - * try to generate bytecodes before this method returns. - * - * @returns {@code null} if {@code methodHandle} is not a {@link MethodHandle} or the invocation - * target is not available at this time - * @throws NullPointerException if {@code methodHandle} is null - */ - ResolvedJavaMethod resolveInvokeBasicTarget(JavaConstant methodHandle, boolean forceBytecodeGeneration); - - /** - * Resolves the invocation target for an invocation of a {@code MethodHandle.linkTo*} method - * with the given constant member name. The member name is the last parameter of the - * {@code linkTo*} method. - * - * @returns {@code null} if the invocation target is not available at this time - * @throws NullPointerException if {@code memberName} is null - * @throws IllegalArgumentException if {@code memberName} is not a - * {@code java.lang.invoke.MemberName} - */ - ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.lang.reflect.Modifier; - -import static java.lang.reflect.Modifier.PRIVATE; -import static java.lang.reflect.Modifier.PROTECTED; -import static java.lang.reflect.Modifier.PUBLIC; - -/** - * A Java element (i.e., a class, interface, field or method) that is described by a set of Java - * language {@linkplain #getModifiers() modifiers}. - */ -public interface ModifiersProvider { - - /** - * Returns the modifiers for this element. - */ - int getModifiers(); - - /** - * @see Modifier#isInterface(int) - */ - default boolean isInterface() { - return Modifier.isInterface(getModifiers()); - } - - /** - * @see Modifier#isSynchronized(int) - */ - default boolean isSynchronized() { - return Modifier.isSynchronized(getModifiers()); - } - - /** - * @see Modifier#isStatic(int) - */ - default boolean isStatic() { - return Modifier.isStatic(getModifiers()); - } - - /** - * The setting of the final modifier bit for types is somewhat confusing, so don't export - * isFinal by default. Subclasses like {@link ResolvedJavaField} and {@link ResolvedJavaMethod} - * can export it as isFinal, but {@link ResolvedJavaType} can provide a more sensible equivalent - * like {@link ResolvedJavaType#isLeaf}. - * - * @see Modifier#isFinal(int) - */ - default boolean isFinalFlagSet() { - return Modifier.isFinal(getModifiers()); - } - - /** - * @see Modifier#isPublic(int) - */ - default boolean isPublic() { - return Modifier.isPublic(getModifiers()); - } - - /** - * Determines if this element is neither {@linkplain #isPublic() public}, - * {@linkplain #isProtected() protected} nor {@linkplain #isPrivate() private}. - */ - default boolean isPackagePrivate() { - return ((PUBLIC | PROTECTED | PRIVATE) & getModifiers()) == 0; - } - - /** - * @see Modifier#isPrivate(int) - */ - default boolean isPrivate() { - return Modifier.isPrivate(getModifiers()); - } - - /** - * @see Modifier#isProtected(int) - */ - default boolean isProtected() { - return Modifier.isProtected(getModifiers()); - } - - /** - * @see Modifier#isTransient(int) - */ - default boolean isTransient() { - return Modifier.isTransient(getModifiers()); - } - - /** - * @see Modifier#isStrict(int) - */ - default boolean isStrict() { - return Modifier.isStrict(getModifiers()); - } - - /** - * @see Modifier#isVolatile(int) - */ - default boolean isVolatile() { - return Modifier.isVolatile(getModifiers()); - } - - /** - * @see Modifier#isNative(int) - */ - default boolean isNative() { - return Modifier.isNative(getModifiers()); - } - - /** - * @see Modifier#isAbstract(int) - */ - default boolean isAbstract() { - return Modifier.isAbstract(getModifiers()); - } - - /** - * Checks that the method is concrete and not abstract. - * - * @return whether the method is a concrete method - */ - default boolean isConcrete() { - return !isAbstract(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/NullConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/NullConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/NullConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/NullConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package jdk.vm.ci.meta; - -/** - * The implementation type of the {@link JavaConstant#NULL_POINTER null constant}. - */ -final class NullConstant implements JavaConstant { - - protected NullConstant() { - } - - @Override - public JavaKind getJavaKind() { - return JavaKind.Object; - } - - @Override - public boolean isNull() { - return true; - } - - @Override - public boolean isDefaultForKind() { - return true; - } - - @Override - public Object asBoxedPrimitive() { - throw new IllegalArgumentException(); - } - - @Override - public int asInt() { - throw new IllegalArgumentException(); - } - - @Override - public boolean asBoolean() { - throw new IllegalArgumentException(); - } - - @Override - public long asLong() { - throw new IllegalArgumentException(); - } - - @Override - public float asFloat() { - throw new IllegalArgumentException(); - } - - @Override - public double asDouble() { - throw new IllegalArgumentException(); - } - - @Override - public String toString() { - return JavaConstant.toString(this); - } - - @Override - public String toValueString() { - return "null"; - } - - @Override - public int hashCode() { - return 13; - } - - @Override - public boolean equals(Object o) { - return o instanceof NullConstant; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 that defines the interface between a runtime and a Java application that wants to access - * meta information. The runtime provides an implementation of the - * {@link jdk.vm.ci.meta.MetaAccessProvider} interface. - */ -package jdk.vm.ci.meta; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2013, 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. - */ -package jdk.vm.ci.meta; - -/** - * Represents a platform-specific low-level type for values. - */ -public interface PlatformKind { - - String name(); - - public interface Key { - - } - - class EnumKey> implements Key { - private final Enum e; - - public EnumKey(Enum e) { - this.e = e; - } - - @Override - public int hashCode() { - return e.ordinal(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof EnumKey) { - EnumKey that = (EnumKey) obj; - return this.e == that.e; - } - return false; - } - } - - /** - * Gets a value associated with this object that can be used as a stable key in a map. The - * {@link Object#hashCode()} implementation of the returned value should be stable between VM - * executions. - */ - Key getKey(); - - /** - * Get the size in bytes of this {@link PlatformKind}. - */ - int getSizeInBytes(); - - /** - * Returns how many primitive values fit in this {@link PlatformKind}. For scalar types this is - * one, for SIMD types it may be higher. - */ - int getVectorLength(); - - /** - * Gets a single type char that identifies this type for use in debug output. - */ - char getTypeChar(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2009, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.nio.ByteBuffer; - -/** - * Represents a primitive constant value, such as an integer or floating point number, within the - * compiler and across the compiler/runtime interface. - */ -public class PrimitiveConstant implements JavaConstant, SerializableConstant { - - private final JavaKind kind; - - /** - * The boxed primitive value as a {@code long}. For {@code float} and {@code double} values, - * this value is the result of {@link Float#floatToRawIntBits(float)} and - * {@link Double#doubleToRawLongBits(double)} respectively. - */ - private final long primitive; - - protected PrimitiveConstant(JavaKind kind, long primitive) { - this.primitive = primitive; - this.kind = kind; - - assert kind.isPrimitive() || kind == JavaKind.Illegal; - } - - static PrimitiveConstant forTypeChar(char kind, long i) { - return JavaConstant.forIntegerKind(JavaKind.fromPrimitiveOrVoidTypeChar(kind), i); - } - - @Override - public JavaKind getJavaKind() { - return kind; - } - - @Override - public boolean isNull() { - return false; - } - - @Override - public boolean isDefaultForKind() { - return primitive == 0; - } - - @Override - public boolean asBoolean() { - assert getJavaKind() == JavaKind.Boolean; - return primitive != 0L; - } - - @Override - public int asInt() { - assert getJavaKind().getStackKind() == JavaKind.Int : getJavaKind().getStackKind(); - return (int) primitive; - } - - @Override - public long asLong() { - assert getJavaKind().isNumericInteger(); - return primitive; - } - - @Override - public float asFloat() { - assert getJavaKind() == JavaKind.Float; - return Float.intBitsToFloat((int) primitive); - } - - @Override - public double asDouble() { - assert getJavaKind() == JavaKind.Double; - return Double.longBitsToDouble(primitive); - } - - @Override - public Object asBoxedPrimitive() { - switch (getJavaKind()) { - case Byte: - return Byte.valueOf((byte) primitive); - case Boolean: - return Boolean.valueOf(asBoolean()); - case Short: - return Short.valueOf((short) primitive); - case Char: - return Character.valueOf((char) primitive); - case Int: - return Integer.valueOf(asInt()); - case Long: - return Long.valueOf(asLong()); - case Float: - return Float.valueOf(asFloat()); - case Double: - return Double.valueOf(asDouble()); - default: - throw new IllegalArgumentException("unexpected kind " + getJavaKind()); - } - } - - @Override - public int getSerializedSize() { - return getJavaKind().getByteCount(); - } - - @Override - public void serialize(ByteBuffer buffer) { - switch (getJavaKind()) { - case Byte: - case Boolean: - buffer.put((byte) primitive); - break; - case Short: - buffer.putShort((short) primitive); - break; - case Char: - buffer.putChar((char) primitive); - break; - case Int: - buffer.putInt(asInt()); - break; - case Long: - buffer.putLong(asLong()); - break; - case Float: - buffer.putFloat(asFloat()); - break; - case Double: - buffer.putDouble(asDouble()); - break; - default: - throw new IllegalArgumentException("unexpected kind " + getJavaKind()); - } - } - - @Override - public int hashCode() { - return (int) (primitive ^ (primitive >>> 32)) * (getJavaKind().ordinal() + 31); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof PrimitiveConstant)) { - return false; - } - PrimitiveConstant other = (PrimitiveConstant) o; - return this.kind.equals(other.kind) && this.primitive == other.primitive; - } - - @Override - public String toString() { - if (getJavaKind() == JavaKind.Illegal) { - return "illegal"; - } else { - return getJavaKind().getJavaName() + "[" + asBoxedPrimitive() + "|0x" + Long.toHexString(primitive) + "]"; - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Provides access to the profiling information of one specific method. Every accessor method - * returns the information that is available at the time of invocation. If a method is invoked - * multiple times, it may return significantly different results for every invocation as the - * profiling information may be changed by other Java threads at any time. - */ -public interface ProfilingInfo { - - /** - * Returns the length of the bytecodes associated with this profile. - */ - int getCodeSize(); - - /** - * Returns an estimate of how often the branch at the given byte code was taken. - * - * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if - * this information is not available. - */ - double getBranchTakenProbability(int bci); - - /** - * Returns an estimate of how often the switch cases are taken at the given BCI. The default - * case is stored as the last entry. - * - * @return A double value that contains the estimated probabilities, with 0.0 meaning never and - * 1.0 meaning always, or -1 if this information is not available. - */ - double[] getSwitchProbabilities(int bci); - - /** - * Returns the TypeProfile for the given BCI. - * - * @return Returns a JavaTypeProfile object, or null if not available. - */ - JavaTypeProfile getTypeProfile(int bci); - - /** - * Returns the MethodProfile for the given BCI. - * - * @return Returns a JavaMethodProfile object, or null if not available. - */ - JavaMethodProfile getMethodProfile(int bci); - - /** - * Returns information if the given BCI did ever throw an exception. - * - * @return {@link TriState#TRUE} if the instruction has thrown an exception at least once, - * {@link TriState#FALSE} if it never threw an exception, and {@link TriState#UNKNOWN} - * if this information was not recorded. - */ - TriState getExceptionSeen(int bci); - - /** - * Returns information if null was ever seen for the given BCI. This information is collected - * for the aastore, checkcast and instanceof bytecodes. - * - * @return {@link TriState#TRUE} if null was seen for the instruction, {@link TriState#FALSE} if - * null was NOT seen, and {@link TriState#UNKNOWN} if this information was not recorded. - */ - TriState getNullSeen(int bci); - - /** - * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts - * to each other, as the returned value highly depends on the time of invocation. - * - * @return the estimated execution count or -1 if not available. - */ - int getExecutionCount(int bci); - - /** - * Returns how frequently a method was deoptimized for the given deoptimization reason. This - * only indicates how often the method did fall back to the interpreter for the execution and - * does not indicate how often it was recompiled. - * - * @param reason the reason for which the number of deoptimizations should be queried - * @return the number of times the compiled method deoptimized for the given reason. - */ - int getDeoptimizationCount(DeoptimizationReason reason); - - /** - * Records the size of the compiler intermediate representation (IR) associated with this - * method. - * - * @param irType the IR type for which the size is being recorded - * @param irSize the IR size to be recorded. The unit depends on the IR. - * @return whether recording this information for {@code irType} is supported - */ - boolean setCompilerIRSize(Class irType, int irSize); - - /** - * Gets the size of the compiler intermediate representation (IR) associated with this method - * last recorded by {@link #setCompilerIRSize(Class, int)}. - * - * @param irType the IR type for which the size is being requested - * @return the requested IR size or -1 if it is unavailable for {@code irType} - */ - int getCompilerIRSize(Class irType); - - /** - * Returns true if the profiling information can be assumed as sufficiently accurate. - * - * @return true if the profiling information was recorded often enough mature enough, false - * otherwise. - */ - boolean isMature(); - - /** - * Force data to be treated as mature if possible. - */ - void setMature(); - - /** - * Formats this profiling information to a string. - * - * @param method an optional method that augments the profile string returned - * @param sep the separator to use for each separate profile record - */ - default String toString(ResolvedJavaMethod method, String sep) { - StringBuilder buf = new StringBuilder(100); - if (method != null) { - buf.append(String.format("canBeStaticallyBound: %b%s", method.canBeStaticallyBound(), sep)); - } - for (int i = 0; i < getCodeSize(); i++) { - if (getExecutionCount(i) != -1) { - buf.append(String.format("executionCount@%d: %d%s", i, getExecutionCount(i), sep)); - } - - if (getBranchTakenProbability(i) != -1) { - buf.append(String.format("branchProbability@%d: %.6f%s", i, getBranchTakenProbability(i), sep)); - } - - double[] switchProbabilities = getSwitchProbabilities(i); - if (switchProbabilities != null) { - buf.append(String.format("switchProbabilities@%d:", i)); - for (int j = 0; j < switchProbabilities.length; j++) { - buf.append(String.format(" %.6f", switchProbabilities[j])); - } - buf.append(sep); - } - - if (getExceptionSeen(i) != TriState.UNKNOWN) { - buf.append(String.format("exceptionSeen@%d: %s%s", i, getExceptionSeen(i).name(), sep)); - } - - if (getNullSeen(i) != TriState.UNKNOWN) { - buf.append(String.format("nullSeen@%d: %s%s", i, getNullSeen(i).name(), sep)); - } - - JavaTypeProfile typeProfile = getTypeProfile(i); - MetaUtil.appendProfile(buf, typeProfile, i, "types", sep); - - JavaMethodProfile methodProfile = getMethodProfile(i); - MetaUtil.appendProfile(buf, methodProfile, i, "methods", sep); - } - - boolean firstDeoptReason = true; - for (DeoptimizationReason reason : DeoptimizationReason.values()) { - int count = getDeoptimizationCount(reason); - if (count > 0) { - if (firstDeoptReason) { - buf.append("deoptimization history").append(sep); - firstDeoptReason = false; - } - buf.append(String.format(" %s: %d%s", reason.name(), count, sep)); - } - } - if (buf.length() == 0) { - return ""; - } - String s = buf.toString(); - return s.substring(0, s.length() - sep.length()); - } - -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/RawConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/RawConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/RawConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/RawConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.meta; - -public class RawConstant extends PrimitiveConstant { - - public RawConstant(long rawValue) { - super(JavaKind.Int, rawValue); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Modifier; - -/** - * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved - * through {@link ConstantPool constant pools}. - */ -public interface ResolvedJavaField extends JavaField, ModifiersProvider, AnnotatedElement { - - /** - * {@inheritDoc} - *

    - * Only the {@linkplain Modifier#fieldModifiers() field flags} specified in the JVM - * specification will be included in the returned mask. - */ - @Override - int getModifiers(); - - /** - * Returns the offset of the field relative to the base of its storage container (e.g., - * {@code instanceOop} for an instance field or {@code Klass*} for a static field on HotSpot). - */ - int getOffset(); - - default boolean isFinal() { - return ModifiersProvider.super.isFinalFlagSet(); - } - - /** - * Determines if this field was injected by the VM. Such a field, for example, is not derived - * from a class file. - */ - boolean isInternal(); - - /** - * Determines if this field is a synthetic field as defined by the Java Language Specification. - */ - boolean isSynthetic(); - - /** - * Returns the {@link ResolvedJavaType} object representing the class or interface that declares - * this field. - */ - @Override - ResolvedJavaType getDeclaringClass(); - - /** - * Gets the value of the {@code ConstantValue} attribute ({@jvms 4.7.2}) associated with this - * field. - * - * @return {@code null} if this field has no {@code ConstantValue} attribute - * @throws UnsupportedOperationException if this operation is not supported - */ - default JavaConstant getConstantValue() { - throw new UnsupportedOperationException(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,474 +0,0 @@ -/* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; - -/** - * Represents a resolved Java method. Methods, like fields and types, are resolved through - * {@link ConstantPool constant pools}. - */ -public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider, AnnotatedElement { - - /** - * Returns the method's bytecode. The returned bytecode does not contain breakpoints or non-Java - * bytecodes. This will return {@code null} if {@link #getCodeSize()} returns {@code <= 0} or if - * {@link #hasBytecodes()} returns {@code false}. - * - * The contained constant pool indexes may not be the ones found in the original class file but - * they can be used with the JVMCI API (e.g. methods in {@link ConstantPool}). - * - * @return {@code null} if {@code getLinkedCodeSize() <= 0} otherwise the bytecode of the method - * whose length is guaranteed to be {@code > 0} - */ - byte[] getCode(); - - /** - * Returns the size of the method's bytecode. If this method returns a value {@code > 0} then - * {@link #getCode()} will not return {@code null}. - * - * @return 0 if the method has no bytecode, {@code -1} if the method does have bytecode but its - * {@linkplain #getDeclaringClass() declaring class} is not - * {@linkplain ResolvedJavaType#isLinked() linked} otherwise the size of the bytecode in - * bytes (guaranteed to be {@code > 0}) - */ - int getCodeSize(); - - /** - * Returns the {@link ResolvedJavaType} object representing the class or interface that declares - * this method. - */ - @Override - ResolvedJavaType getDeclaringClass(); - - /** - * Returns the maximum number of locals used in this method's bytecodes. - */ - int getMaxLocals(); - - /** - * Returns the maximum number of stack slots used in this method's bytecodes. - */ - int getMaxStackSize(); - - default boolean isFinal() { - return ModifiersProvider.super.isFinalFlagSet(); - } - - /** - * Determines if this method is a synthetic method as defined by the Java Language - * Specification. - */ - boolean isSynthetic(); - - /** - * Checks that the method is a - * varargs - * method. - * - * @return whether the method is a varargs method - */ - boolean isVarArgs(); - - /** - * Checks that the method is a - * bridge - * method. - * - * @return whether the method is a bridge method - */ - boolean isBridge(); - - /** - * Returns {@code true} if this method is a default method; returns {@code false} otherwise. - * - * A default method is a public non-abstract instance method, that is, a non-static method with - * a body, declared in an interface type. - * - * @return true if and only if this method is a default method as defined by the Java Language - * Specification. - */ - boolean isDefault(); - - /** - * Checks whether this method is a class initializer. - * - * @return {@code true} if the method is a class initializer - */ - boolean isClassInitializer(); - - /** - * Checks whether this method is a constructor. - * - * @return {@code true} if the method is a constructor - */ - boolean isConstructor(); - - /** - * Checks whether this method can be statically bound (usually, that means it is final or - * private or static, but not abstract, or the declaring class is final). - * - * @return {@code true} if this method can be statically bound - */ - boolean canBeStaticallyBound(); - - /** - * Returns the list of exception handlers for this method. - */ - ExceptionHandler[] getExceptionHandlers(); - - /** - * Returns a stack trace element for this method and a given bytecode index. - */ - StackTraceElement asStackTraceElement(int bci); - - /** - * Returns an object that provides access to the profiling information recorded for this method. - */ - default ProfilingInfo getProfilingInfo() { - return getProfilingInfo(true, true); - } - - /** - * Returns an object that provides access to the profiling information recorded for this method. - * - * @param includeNormal if true, - * {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason) - * deoptimization counts} will include deoptimization that happened during execution - * of standard non-osr methods. - * @param includeOSR if true, - * {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason) - * deoptimization counts} will include deoptimization that happened during execution - * of on-stack-replacement methods. - */ - ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR); - - /** - * Invalidates the profiling information and restarts profiling upon the next invocation. - */ - void reprofile(); - - /** - * Returns the constant pool of this method. - */ - ConstantPool getConstantPool(); - - /** - * A {@code Parameter} provides information about method parameters. - */ - class Parameter implements AnnotatedElement { - private final String name; - private final ResolvedJavaMethod method; - private final int modifiers; - private final int index; - - /** - * Constructor for {@code Parameter}. - * - * @param name the name of the parameter or {@code null} if there is no - * {@literal MethodParameters} class file attribute providing a non-empty name - * for the parameter - * @param modifiers the modifier flags for the parameter - * @param method the method which defines this parameter - * @param index the index of the parameter - */ - public Parameter(String name, - int modifiers, - ResolvedJavaMethod method, - int index) { - assert name == null || !name.isEmpty(); - this.name = name; - this.modifiers = modifiers; - this.method = method; - this.index = index; - } - - /** - * Gets the name of the parameter. If the parameter's name is {@linkplain #isNamePresent() - * present}, then this method returns the name provided by the class file. Otherwise, this - * method synthesizes a name of the form argN, where N is the index of the parameter in the - * descriptor of the method which declares the parameter. - * - * @return the name of the parameter, either provided by the class file or synthesized if - * the class file does not provide a name - */ - public String getName() { - if (name == null) { - return "arg" + index; - } else { - return name; - } - } - - /** - * Gets the method declaring the parameter. - */ - public ResolvedJavaMethod getDeclaringMethod() { - return method; - } - - /** - * Get the modifier flags for the parameter. - */ - public int getModifiers() { - return modifiers; - } - - /** - * Gets the kind of the parameter. - */ - public JavaKind getKind() { - return method.getSignature().getParameterKind(index); - } - - /** - * Gets the formal type of the parameter. - */ - public Type getParameterizedType() { - return method.getGenericParameterTypes()[index]; - } - - /** - * Gets the type of the parameter. - */ - public JavaType getType() { - return method.getSignature().getParameterType(index, method.getDeclaringClass()); - } - - /** - * Determines if the parameter has a name according to a {@literal MethodParameters} class - * file attribute. - * - * @return true if and only if the parameter has a name according to the class file. - */ - public boolean isNamePresent() { - return name != null; - } - - /** - * Determines if the parameter represents a variable argument list. - */ - public boolean isVarArgs() { - return method.isVarArgs() && index == method.getSignature().getParameterCount(false) - 1; - } - - @Override - public T getAnnotation(Class annotationClass) { - return method.getParameterAnnotations(annotationClass)[index]; - } - - @Override - public Annotation[] getAnnotations() { - return method.getParameterAnnotations()[index]; - } - - @Override - public Annotation[] getDeclaredAnnotations() { - return getAnnotations(); - } - - @Override - public String toString() { - Type type = getParameterizedType(); - String typename = type.getTypeName(); - if (isVarArgs()) { - typename = typename.replaceFirst("\\[\\]$", "..."); - } - - final StringBuilder sb = new StringBuilder(Modifier.toString(getModifiers())); - if (sb.length() != 0) { - sb.append(' '); - } - return sb.append(typename).append(' ').append(getName()).toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Parameter) { - Parameter other = (Parameter) obj; - return (other.method.equals(method) && other.index == index); - } - return false; - } - - @Override - public int hashCode() { - return method.hashCode() ^ index; - } - } - - /** - * Returns an array of {@code Parameter} objects that represent all the parameters to this - * method. Returns an array of length 0 if this method has no parameters. Returns {@code null} - * if the parameter information is unavailable. - */ - default Parameter[] getParameters() { - return null; - } - - /** - * Returns an array of arrays that represent the annotations on the formal parameters, in - * declaration order, of this method. - * - * @see Method#getParameterAnnotations() - */ - Annotation[][] getParameterAnnotations(); - - /** - * Returns an array of {@link Type} objects that represent the formal parameter types, in - * declaration order, of this method. - * - * @see Method#getGenericParameterTypes() - */ - Type[] getGenericParameterTypes(); - - /** - * Returns {@code true} if this method is not excluded from inlining and has associated Java - * bytecodes (@see {@link ResolvedJavaMethod#hasBytecodes()}). - */ - boolean canBeInlined(); - - /** - * Determines if this method is targeted by a VM directive (e.g., - * {@code -XX:CompileCommand=dontinline,}) or VM recognized annotation (e.g., - * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined. - */ - boolean hasNeverInlineDirective(); - - /** - * Returns {@code true} if the inlining of this method should be forced. - */ - boolean shouldBeInlined(); - - /** - * Returns the LineNumberTable of this method or null if this method does not have a line - * numbers table. - */ - LineNumberTable getLineNumberTable(); - - /** - * Returns the local variable table of this method or null if this method does not have a local - * variable table. - */ - LocalVariableTable getLocalVariableTable(); - - /** - * Gets the encoding of (that is, a constant representing the value of) this method. - * - * @return a constant representing a reference to this method - */ - Constant getEncoding(); - - /** - * Checks if this method is present in the virtual table for subtypes of the specified - * {@linkplain ResolvedJavaType type}. - * - * @return true is this method is present in the virtual table for subtypes of this type. - */ - boolean isInVirtualMethodTable(ResolvedJavaType resolved); - - /** - * Gets the annotation of a particular type for a formal parameter of this method. - * - * @param annotationClass the Class object corresponding to the annotation type - * @param parameterIndex the index of a formal parameter of {@code method} - * @return the annotation of type {@code annotationClass} for the formal parameter present, else - * null - * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal - * parameter - */ - default T getParameterAnnotation(Class annotationClass, int parameterIndex) { - if (parameterIndex >= 0) { - Annotation[][] parameterAnnotations = getParameterAnnotations(); - for (Annotation a : parameterAnnotations[parameterIndex]) { - if (a.annotationType() == annotationClass) { - return annotationClass.cast(a); - } - } - } - return null; - } - - default JavaType[] toParameterTypes() { - JavaType receiver = isStatic() || isConstructor() ? null : getDeclaringClass(); - return getSignature().toParameterTypes(receiver); - } - - /** - * Gets the annotations of a particular type for the formal parameters of this method. - * - * @param annotationClass the Class object corresponding to the annotation type - * @return the annotation of type {@code annotationClass} (if any) for each formal parameter - * present - */ - @SuppressWarnings("unchecked") - default T[] getParameterAnnotations(Class annotationClass) { - Annotation[][] parameterAnnotations = getParameterAnnotations(); - T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length); - for (int i = 0; i < parameterAnnotations.length; i++) { - for (Annotation a : parameterAnnotations[i]) { - if (a.annotationType() == annotationClass) { - result[i] = annotationClass.cast(a); - } - } - } - return result; - } - - /** - * @see #getCodeSize() - * @return {@code getCodeSize() > 0} - */ - default boolean hasBytecodes() { - return getCodeSize() > 0; - } - - /** - * Checks whether the method has a receiver parameter - i.e., whether it is not static. - * - * @return whether the method has a receiver parameter - */ - default boolean hasReceiver() { - return !isStatic(); - } - - /** - * Determines if this method is {@link java.lang.Object#Object()}. - */ - default boolean isJavaLangObjectInit() { - return getDeclaringClass().isJavaLangObject() && getName().equals(""); - } - - /** - * Gets a speculation log that can be used when compiling this method to make new speculations - * and query previously failed speculations. The implementation may return a new - * {@link SpeculationLog} object each time this method is called so its the caller's - * responsibility to ensure the same speculation log is used throughout a compilation. - */ - SpeculationLog getSpeculationLog(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.lang.reflect.AnnotatedElement; - -import jdk.vm.ci.meta.Assumptions.AssumptionResult; - -/** - * Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays - * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools} - * . - */ -public interface ResolvedJavaType extends JavaType, ModifiersProvider, AnnotatedElement { - /** - * Checks whether this type has a finalizer method. - * - * @return {@code true} if this class has a finalizer - */ - boolean hasFinalizer(); - - /** - * Checks whether this type has any finalizable subclasses so far. Any decisions based on this - * information require the registration of a dependency, since this information may change. - * - * @return {@code true} if this class has any subclasses with finalizers - */ - AssumptionResult hasFinalizableSubclass(); - - /** - * Checks whether this type is an interface. - * - * @return {@code true} if this type is an interface - */ - @Override - boolean isInterface(); - - /** - * Checks whether this type is an instance class. - * - * @return {@code true} if this type is an instance class - */ - boolean isInstanceClass(); - - /** - * Checks whether this type is primitive. - * - * @return {@code true} if this type is primitive - */ - boolean isPrimitive(); - - /* - * The setting of the final bit for types is a bit confusing since arrays are marked as final. - * This method provides a semantically equivalent test that appropriate for types. - */ - default boolean isLeaf() { - return getElementalType().isFinalFlagSet(); - } - - /** - * Checks whether this type is an enum. - * - * @return {@code true} if this type is an enum - */ - boolean isEnum(); - - /** - * Checks whether this type is initialized. If a type is initialized it implies that it was - * {@link #isLinked() linked} and that the static initializer has run. - * - * @return {@code true} if this type is initialized - */ - boolean isInitialized(); - - /** - * Initializes this type. - */ - void initialize(); - - /** - * Checks whether this type is linked and verified. When a type is linked the static initializer - * has not necessarily run. An {@link #isInitialized() initialized} type is always linked. - * - * @return {@code true} if this type is linked - */ - boolean isLinked(); - - /** - * Links this type. If this method returns normally, then future calls of {@link #isLinked} will - * return true and future calls of {@link #link} are no-ops. If the method throws an exception, - * then future calls of {@link #isLinked} will return false and future calls of {@link #link} - * will reattempt the linking step which might succeed or throw an exception. - */ - default void link() { - throw new UnsupportedOperationException("link is unsupported"); - } - - /** - * Checks whether this type or any of its supertypes or superinterfaces has default methods. - */ - default boolean hasDefaultMethods() { - throw new UnsupportedOperationException("hasDefaultMethods is unsupported"); - } - - /** - * Checks whether this type declares defaults methods. - */ - default boolean declaresDefaultMethods() { - throw new UnsupportedOperationException("declaresDefaultMethods is unsupported"); - } - - /** - * Determines if this type is either the same as, or is a superclass or superinterface of, the - * type represented by the specified parameter. This method is identical to - * {@link Class#isAssignableFrom(Class)} in terms of the value return for this type. - */ - boolean isAssignableFrom(ResolvedJavaType other); - - /** - * Returns {@code null} since support for VM anonymous class was removed by JDK-8243287. - * This method is preserved for JVMCI backwards compatibility. - */ - @Deprecated - default ResolvedJavaType getHostClass() { - return null; - } - - /** - * Returns true if this type is exactly the type {@link java.lang.Object}. - */ - default boolean isJavaLangObject() { - // Removed assertion due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=434442 - return getSuperclass() == null && !isInterface() && getJavaKind() == JavaKind.Object; - } - - /** - * Checks whether the specified object is an instance of this type. - * - * @param obj the object to test - * @return {@code true} if the object is an instance of this type - */ - boolean isInstance(JavaConstant obj); - - /** - * Gets the super class of this type. If this type represents either the {@code Object} class, - * an interface, a primitive type, or void, then null is returned. If this object represents an - * array class then the type object representing the {@code Object} class is returned. - */ - ResolvedJavaType getSuperclass(); - - /** - * Gets the interfaces implemented or extended by this type. This method is analogous to - * {@link Class#getInterfaces()} and as such, only returns the interfaces directly implemented - * or extended by this type. - */ - ResolvedJavaType[] getInterfaces(); - - /** - * Gets the single implementor of this type. Calling this method on a non-interface type causes - * an exception. - *

    - * If the compiler uses the result of this method for its compilation, the usage must be guarded - * because the verifier can not guarantee that the assigned type really implements this - * interface. Additionally, class loading can invalidate the result of this method. - * - * @return {@code null} if there is no implementor, the implementor if there is only one, or - * {@code this} if there are more than one. - */ - ResolvedJavaType getSingleImplementor(); - - /** - * Walks the class hierarchy upwards and returns the least common class that is a superclass of - * both the current and the given type. - * - * @return the least common type that is a super type of both the current and the given type, or - * {@code null} if primitive types are involved. - */ - ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType); - - /** - * Attempts to get a leaf concrete subclass of this type. - *

    - * For an {@linkplain #isArray() array} type A, the leaf concrete subclass is A if the - * {@linkplain #getElementalType() elemental} type of A is final (which includes primitive - * types). Otherwise {@code null} is returned for A. - *

    - * For a non-array type T, the result is the leaf concrete type in the current hierarchy of T. - *

    - * A runtime may decide not to manage or walk a large hierarchy and so the result is - * conservative. That is, a non-null result is guaranteed to be the leaf concrete class in T's - * hierarchy at the current point in time but a null result does not necessarily imply - * that there is no leaf concrete class in T's hierarchy. - *

    - * If the compiler uses the result of this method for its compilation, it must register the - * {@link AssumptionResult} in its {@link Assumptions} because dynamic class loading can - * invalidate the result of this method. - * - * @return an {@link AssumptionResult} containing the leaf concrete subclass for this type as - * described above - */ - AssumptionResult findLeafConcreteSubtype(); - - @Override - ResolvedJavaType getComponentType(); - - @Override - default ResolvedJavaType getElementalType() { - ResolvedJavaType t = this; - while (t.isArray()) { - t = t.getComponentType(); - } - return t; - } - - @Override - ResolvedJavaType getArrayClass(); - - /** - * Resolves the method implementation for virtual dispatches on objects of this dynamic type. - * This resolution process only searches "up" the class hierarchy of this type. A broader search - * that also walks "down" the hierarchy is implemented by - * {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}. For interface types it returns null - * since no concrete object can be an interface. - * - * @param method the method to select the implementation of - * @param callerType the caller or context type used to perform access checks - * @return the link-time resolved method (might be abstract) or {@code null} if it is either a - * signature polymorphic method or can not be linked. - */ - ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType); - - /** - * A convenience wrapper for {@link #resolveMethod(ResolvedJavaMethod, ResolvedJavaType)} that - * only returns non-abstract methods. - * - * @param method the method to select the implementation of - * @param callerType the caller or context type used to perform access checks - * @return the concrete method that would be selected at runtime, or {@code null} if there is no - * concrete implementation of {@code method} in this type or any of its superclasses - */ - default ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { - ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType); - if (resolvedMethod == null || resolvedMethod.isAbstract()) { - return null; - } - return resolvedMethod; - } - - /** - * Given a {@link ResolvedJavaMethod} A, returns a concrete {@link ResolvedJavaMethod} B that is - * the only possible unique target for a virtual call on A(). Returns {@code null} if either no - * such concrete method or more than one such method exists. Returns the method A if A is a - * concrete method that is not overridden. - *

    - * If the compiler uses the result of this method for its compilation, it must register an - * assumption because dynamic class loading can invalidate the result of this method. - * - * @param method the method A for which a unique concrete target is searched - * @return the unique concrete target or {@code null} if no such target exists or assumptions - * are not supported by this runtime - */ - AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method); - - /** - * Returns the instance fields of this class, including - * {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned - * for array and primitive types. The order of fields returned by this method is stable. That - * is, for a single JVM execution the same order is returned each time this method is called. It - * is also the "natural" order, which means that the JVM would expect the fields in this order - * if no specific order is given. - * - * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this - * type are included in the result - * @return an array of instance fields - */ - ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses); - - /** - * Returns the static fields of this class, including {@linkplain ResolvedJavaField#isInternal() - * internal} fields. A zero-length array is returned for array and primitive types. The order of - * fields returned by this method is stable. That is, for a single JVM execution the same order - * is returned each time this method is called. - */ - ResolvedJavaField[] getStaticFields(); - - /** - * Returns the instance field of this class (or one of its super classes) at the given offset, - * or {@code null} if there is no such field. - * - * @param offset the offset of the field to look for - * @return the field with the given offset, or {@code null} if there is no such field. - */ - ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind); - - /** - * Returns name of source file of this type. - */ - String getSourceFileName(); - - /** - * Returns {@code true} if the type is a local type. - */ - boolean isLocal(); - - /** - * Returns {@code true} if the type is a member type. - */ - boolean isMember(); - - /** - * Returns the enclosing type of this type, if it exists, or {@code null}. - */ - ResolvedJavaType getEnclosingType(); - - /** - * Returns an array reflecting all the constructors declared by this type. This method is - * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors. Calling - * this method forces this type to be {@link #link linked}. - */ - ResolvedJavaMethod[] getDeclaredConstructors(); - - /** - * Returns an array reflecting all the constructors declared by this type. This method is - * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors. - * - * @param forceLink if {@code true}, forces this type to be {@link #link linked} - */ - default ResolvedJavaMethod[] getDeclaredConstructors(boolean forceLink) { - throw new UnsupportedOperationException(); - } - - /** - * Returns an array reflecting all the methods declared by this type. This method is similar to - * {@link Class#getDeclaredMethods()} in terms of returned methods. Calling this method forces - * this type to be {@link #link linked}. - */ - ResolvedJavaMethod[] getDeclaredMethods(); - - /** - * Returns an array reflecting all the methods declared by this type. This method is similar to - * {@link Class#getDeclaredMethods()} in terms of returned methods. - * - * @param forceLink if {@code true}, forces this type to be {@link #link linked} - */ - default ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { - throw new UnsupportedOperationException(); - } - - /** - * Returns the {@code } method for this class if there is one. - */ - ResolvedJavaMethod getClassInitializer(); - - default ResolvedJavaMethod findMethod(String name, Signature signature) { - for (ResolvedJavaMethod method : getDeclaredMethods()) { - if (method.getName().equals(name) && method.getSignature().equals(signature)) { - return method; - } - } - return null; - } - - /** - * Returns true if this type is {@link Cloneable} and can be safely cloned by creating a normal - * Java allocation and populating it from the fields returned by - * {@link #getInstanceFields(boolean)}. Some types may require special handling by the platform - * so they would to go through the normal {@link Object#clone} path. - */ - boolean isCloneableWithAllocation(); - - /** - * Lookup an unresolved type relative to an existing resolved type. - */ - @SuppressWarnings("unused") - default ResolvedJavaType lookupType(UnresolvedJavaType unresolvedJavaType, boolean resolve) { - return null; - } - - @SuppressWarnings("unused") - default ResolvedJavaField resolveField(UnresolvedJavaField unresolvedJavaField, ResolvedJavaType accessingClass) { - return null; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SerializableConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SerializableConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SerializableConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SerializableConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package jdk.vm.ci.meta; - -import java.nio.ByteBuffer; - -/** - * Represents a compile-time constant that can be converted to a byte array. - */ -public interface SerializableConstant extends Constant { - - /** - * Return the size in bytes of the serialized representation of this constant. - */ - int getSerializedSize(); - - /** - * Serialize the constant into the ByteBuffer. There must be at least - * {@link #getSerializedSize()} bytes available capacity in the buffer. - */ - void serialize(ByteBuffer buffer); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Signature.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Signature.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Signature.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Signature.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.meta; - -/** - * Represents a method signature provided by the runtime. - * - * @see Method - * Descriptors - */ -public interface Signature { - - /** - * Returns the number of parameters in this signature, adding 1 for a receiver if requested. - * - * @param receiver true if 1 is to be added to the result for a receiver - * @return the number of parameters; + 1 iff {@code receiver == true} - */ - int getParameterCount(boolean receiver); - - /** - * Gets the parameter type at the specified position. - * - * @param index the index into the parameters, with {@code 0} indicating the first parameter - * @param accessingClass the context of the type lookup. If non-null, its class loader is used - * for resolving the type. If {@code null}, then the type returned is either - * unresolved or a resolved type whose resolution is context free (e.g., a primitive - * type or a type in a java.* package). - * @return the {@code index}'th parameter type - * @throws LinkageError if {@code accessingClass != null} and resolution fails - * - */ - JavaType getParameterType(int index, ResolvedJavaType accessingClass); - - /** - * Gets the parameter kind at the specified position. This is the same as calling - * {@link #getParameterType}. {@link JavaType#getJavaKind getJavaKind}. - * - * @param index the index into the parameters, with {@code 0} indicating the first parameter - * @return the kind of the parameter at the specified position - */ - default JavaKind getParameterKind(int index) { - return getParameterType(index, null).getJavaKind(); - } - - /** - * Gets the return type of this signature. - * - * @param accessingClass the context of the type lookup. If non-null, its class loader is used - * for resolving the type. If {@code null}, then the type returned is either - * unresolved or a resolved type whose resolution is context free (e.g., a primitive - * type or a type in a java.* package). - * @return the return type - * @throws LinkageError if {@code accessingClass != null} and resolution fails - */ - JavaType getReturnType(ResolvedJavaType accessingClass); - - /** - * Gets the return kind of this signature. This is the same as calling {@link #getReturnType}. - * {@link JavaType#getJavaKind getJavaKind}. - */ - default JavaKind getReturnKind() { - return getReturnType(null).getJavaKind(); - } - - /** - * Gets the - * method - * descriptor corresponding to this signature. For example: - * - *

    -     * (ILjava/lang/String;D)V
    -     * 
    - * - * @return the signature as a string - */ - default String toMethodDescriptor() { - StringBuilder sb = new StringBuilder("("); - for (int i = 0; i < getParameterCount(false); ++i) { - sb.append(getParameterType(i, null).getName()); - } - sb.append(')').append(getReturnType(null).getName()); - return sb.toString(); - } - - default JavaType[] toParameterTypes(JavaType receiverType) { - int args = getParameterCount(false); - JavaType[] result; - int i = 0; - if (receiverType != null) { - result = new JavaType[args + 1]; - result[0] = receiverType; - i = 1; - } else { - result = new JavaType[args]; - } - for (int j = 0; j < args; j++) { - result[i + j] = getParameterType(j, null); - } - return result; - } - - default JavaKind[] toParameterKinds(boolean receiver) { - int args = getParameterCount(false); - JavaKind[] result; - int i = 0; - if (receiver) { - result = new JavaKind[args + 1]; - result[0] = JavaKind.Object; - i = 1; - } else { - result = new JavaKind[args]; - } - for (int j = 0; j < args; j++) { - result[i + j] = getParameterKind(j); - } - return result; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -import java.util.Map; -import java.util.function.Supplier; - -/** - * Manages unique {@link SpeculationReason} objects that denote why a deoptimization occurred. - * Reasons are embedded in compiled code for a method. If the compiled code deoptimizes at a - * position associated with a {@link SpeculationReason}, the reason is added to a set of failed - * speculations associated with the method. A subsequent compilation of the method can query the - * failed speculations via a {@link SpeculationLog} to avoid making a speculation based on - * invalidated reasons. This avoids repeated deoptimizations. - */ -public interface SpeculationLog { - /** - * The specific attributes of a speculation that a compiler uses to denote a speculation in a - * compiled method. Typical attributes of a speculation are a bytecode position, type - * information about a variable being speculated on and an enum denoting the type of operation - * to which the speculation applies. A {@link SpeculationReason} is used as a key in a - * {@link Map} and so it must implement {@link Object#equals(Object)} and - * {@link Object#hashCode()} in terms of its attributes. - * - * A JVMCI implementation may serialize speculations for storage off heap (e.g. in native memory - * associated with an nmethod). For this reason, the attributes of a {@link SpeculationReason} - * are restricted to those supported by the {@code add...} methods of - * {@link SpeculationReasonEncoding}. - */ - public interface SpeculationReason { - - /** - * Encodes the attributes of this reason using a {@link SpeculationReasonEncoding}. For - * efficiency, a {@link SpeculationReason} implementation should cache the returned value - * and return it for all subsequent calls to this method. This also underlines the - * requirement that the encoding for a specific reason instance should be stable. - * - * @param encodingSupplier source of a {@link SpeculationReasonEncoding} - * @return a {@link SpeculationReasonEncoding} that encodes all the attributes that uniquely - * identify this reason - */ - default SpeculationReasonEncoding encode(Supplier encodingSupplier) { - return null; - } - } - - /** - * Provides a facility for encoding the attributes of a {@link SpeculationReason}. The encoding - * format is determined by the implementation of this interface. - */ - public interface SpeculationReasonEncoding { - void addByte(int value); - - void addShort(int value); - - void addInt(int value); - - void addLong(long value); - - void addMethod(ResolvedJavaMethod method); - - void addType(ResolvedJavaType type); - - void addString(String value); - - default void addField(ResolvedJavaField field) { - addType(field.getDeclaringClass()); - addInt(field.getModifiers()); - addInt(field.getOffset()); - } - } - - /** - * Marker class that indicates that a speculation has no reason. - */ - final class NoSpeculationReason implements SpeculationReason { - } - - class Speculation { - private final SpeculationReason reason; - - public Speculation(SpeculationReason reason) { - this.reason = reason; - } - - public SpeculationReason getReason() { - return reason; - } - - @Override - public String toString() { - return reason.toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Speculation) { - Speculation other = (Speculation) obj; - return reason.equals(other.reason); - } - return false; - } - - @Override - public int hashCode() { - return getReason().hashCode(); - } - } - - Speculation NO_SPECULATION = new Speculation(new NoSpeculationReason()); - - /** - * Updates the set of failed speculations recorded in this log. This must be called before - * compilation. - */ - void collectFailedSpeculations(); - - /** - * If this method returns true, the compiler is allowed to {@link #speculate} with the given - * reason. - */ - boolean maySpeculate(SpeculationReason reason); - - /** - * Registers a speculation performed by the compiler. The compiler must guard every call to this - * method for a specific reason with a call to {@link #maySpeculate(SpeculationReason)}. - * - * This API is subject to a benign race where a during the course of a compilation another - * thread might fail a speculation such that {@link #maySpeculate(SpeculationReason)} will - * return false but an earlier call returned true. This method will still return a working - * {@link Speculation} in that case but the compile will eventually be invalidated and the - * compile attempted again without the now invalid speculation. - * - * @param reason an object representing the reason for the speculation - * @return a compiler constant encapsulating the provided reason. It is usually passed as an - * argument to the deoptimization function. - */ - Speculation speculate(SpeculationReason reason); - - /** - * Returns if this log has speculations. - * - * @return true if there are speculations, false otherwise - */ - boolean hasSpeculations(); - - /** - * Given a {@link JavaConstant} previously returned from - * {@link MetaAccessProvider#encodeSpeculation(Speculation)} return the original - * {@link Speculation} object. - */ - Speculation lookupSpeculation(JavaConstant constant); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SuppressFBWarnings.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Used to suppress FindBugs warnings. - */ -@interface SuppressFBWarnings { - /** - * The set of FindBugs - * warnings that are to be - * suppressed in annotated element. The value can be a bug category, kind or pattern. - */ - String[] value(); - - /** - * Reason why the warning is suppressed. - */ - String justification(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TriState.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TriState.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TriState.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TriState.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ -package jdk.vm.ci.meta; - -/** - * Represents a logic value that can be either {@link #TRUE}, {@link #FALSE}, or {@link #UNKNOWN}. - */ -public enum TriState { - TRUE, - FALSE, - UNKNOWN; - - public static TriState get(boolean value) { - return value ? TRUE : FALSE; - } - - /** - * This is optimistic about {@link #UNKNOWN} (it prefers known values over {@link #UNKNOWN}) and - * pesimistic about known (it perfers {@link #TRUE} over {@link #FALSE}). - */ - public static TriState merge(TriState a, TriState b) { - if (a == TRUE || b == TRUE) { - return TRUE; - } - if (a == FALSE || b == FALSE) { - return FALSE; - } - assert a == UNKNOWN && b == UNKNOWN; - return UNKNOWN; - } - - public boolean isTrue() { - return this == TRUE; - } - - public boolean isFalse() { - return this == FALSE; - } - - public boolean isUnknown() { - return this == UNKNOWN; - } - - public boolean isKnown() { - return this != UNKNOWN; - } - - public boolean toBoolean() { - if (isTrue()) { - return true; - } else if (isFalse()) { - return false; - } else { - throw new IllegalStateException("Cannot convert to boolean, TriState is in an unknown state"); - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaField.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaField.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaField.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaField.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.meta; - -/** - * A implementation of {@link JavaField} for an unresolved field. - */ -public final class UnresolvedJavaField implements JavaField { - - private final String name; - private final JavaType holder; - private final JavaType type; - - public UnresolvedJavaField(JavaType holder, String name, JavaType type) { - this.name = name; - this.type = type; - this.holder = holder; - } - - @Override - public String getName() { - return name; - } - - @Override - public JavaType getType() { - return type; - } - - @Override - public JavaType getDeclaringClass() { - return holder; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || !(obj instanceof UnresolvedJavaField)) { - return false; - } - UnresolvedJavaField that = (UnresolvedJavaField) obj; - return this.holder.equals(that.holder) && this.name.equals(that.name) && this.type.equals(that.type); - } - - /** - * Converts this compiler interface field to a string. - */ - @Override - public String toString() { - return format("UnresolvedJavaField<%H.%n %t>"); - } - - public ResolvedJavaField resolve(ResolvedJavaType accessingClass) { - ResolvedJavaType resolvedHolder = holder.resolve(accessingClass); - return resolvedHolder.resolveField(this, accessingClass); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaMethod.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaMethod.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaMethod.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaMethod.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.meta; - -/** - * Implementation of {@link JavaMethod} for unresolved HotSpot methods. - */ -public final class UnresolvedJavaMethod implements JavaMethod { - - private final String name; - private final Signature signature; - protected JavaType holder; - - public UnresolvedJavaMethod(String name, Signature signature, JavaType holder) { - this.name = name; - this.holder = holder; - this.signature = signature; - } - - @Override - public String getName() { - return name; - } - - @Override - public Signature getSignature() { - return signature; - } - - @Override - public JavaType getDeclaringClass() { - return holder; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || !(obj instanceof UnresolvedJavaMethod)) { - return false; - } - UnresolvedJavaMethod that = (UnresolvedJavaMethod) obj; - return this.name.equals(that.name) && this.signature.equals(that.signature) && this.holder.equals(that.holder); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaType.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaType.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaType.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/UnresolvedJavaType.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ -package jdk.vm.ci.meta; - -/** - * Implementation of {@link JavaType} for unresolved HotSpot classes. - */ -public final class UnresolvedJavaType implements JavaType { - private final String name; - - @Override - public String getName() { - return name; - } - - private UnresolvedJavaType(String name) { - this.name = name; - assert name.length() == 1 && JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)) != null || name.charAt(0) == '[' || name.charAt(name.length() - 1) == ';' : name; - } - - /** - * Creates an unresolved type for a valid {@link JavaType#getName() type name}. - */ - public static UnresolvedJavaType create(String name) { - return new UnresolvedJavaType(name); - } - - @Override - public JavaType getComponentType() { - if (getName().charAt(0) == '[') { - return new UnresolvedJavaType(getName().substring(1)); - } - return null; - } - - @Override - public JavaType getArrayClass() { - return new UnresolvedJavaType('[' + getName()); - } - - @Override - public JavaKind getJavaKind() { - return JavaKind.Object; - } - - @Override - public int hashCode() { - return getName().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || !(obj instanceof UnresolvedJavaType)) { - return false; - } - UnresolvedJavaType that = (UnresolvedJavaType) obj; - return this.getName().equals(that.getName()); - } - - @Override - public String toString() { - return "UnresolvedJavaType<" + getName() + ">"; - } - - @Override - public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - return accessingClass.lookupType(this, true); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -package jdk.vm.ci.meta; - -/** - * Abstract base class for values. - */ -public abstract class Value { - - public static final Value[] NO_VALUES = new Value[0]; - - public static final AllocatableValue ILLEGAL = new IllegalValue(); - - private static final class IllegalValue extends AllocatableValue { - private IllegalValue() { - super(ValueKind.Illegal); - } - - @Override - public String toString() { - return "-"; - } - - @Override - public boolean equals(Object other) { - // Due to de-serialization this object may exist multiple times. So we compare classes - // instead of the individual objects. - return other instanceof IllegalValue; - } - } - - private final ValueKind valueKind; - - /** - * Initializes a new value of the specified kind. - * - * @param valueKind the kind - */ - protected Value(ValueKind valueKind) { - this.valueKind = valueKind; - } - - /** - * Returns a String representation of the kind, which should be the end of all - * {@link #toString()} implementation of subclasses. - */ - protected final String getKindSuffix() { - return "|" + valueKind.getKindSuffix(); - } - - public final ValueKind getValueKind() { - return valueKind; - } - - public final > K getValueKind(Class cls) { - return cls.cast(valueKind); - } - - /** - * Returns the platform specific kind used to store this value. - */ - public final PlatformKind getPlatformKind() { - return valueKind.getPlatformKind(); - } - - @Override - public int hashCode() { - return 41 + valueKind.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Value) { - Value that = (Value) obj; - return valueKind.equals(that.valueKind); - } - return false; - } - - /** - * Checks if this value is identical to {@code other}. - * - * Warning: Use with caution! Usually equivalence {@link #equals(Object)} is sufficient and - * should be used. - */ - public final boolean identityEquals(Value other) { - return this == other; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Represents the type of {@link Value values}. This class can be extended by compilers to track - * additional information about values. - */ -public abstract class ValueKind> { - - private enum IllegalKind implements PlatformKind { - ILLEGAL; - - private final EnumKey key = new EnumKey<>(this); - - @Override - public Key getKey() { - return key; - } - - @Override - public int getSizeInBytes() { - return 0; - } - - @Override - public int getVectorLength() { - return 0; - } - - @Override - public char getTypeChar() { - return '-'; - } - } - - private static class IllegalValueKind extends ValueKind { - - IllegalValueKind() { - super(IllegalKind.ILLEGAL); - } - - @Override - public IllegalValueKind changeType(PlatformKind newPlatformKind) { - return this; - } - - @Override - public String toString() { - return "ILLEGAL"; - } - } - - /** - * The non-type. - */ - public static final ValueKind Illegal = new IllegalValueKind(); - - private final PlatformKind platformKind; - - public ValueKind(PlatformKind platformKind) { - this.platformKind = platformKind; - } - - public final PlatformKind getPlatformKind() { - return platformKind; - } - - /** - * Create a new {@link ValueKind} with a different {@link PlatformKind}. Subclasses must - * override this to preserve the additional information added by the compiler. - */ - public abstract K changeType(PlatformKind newPlatformKind); - - /** - * Returns a String representation of the kind, which will be included at the end of - * {@link Value#toString()} implementation. Defaults to {@link #toString()} but can be - * overridden to provide something more specific. - */ - public String getKindSuffix() { - return toString(); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.meta; - -/** - * Represents a constant that needs to be patched at runtime by the VM. - */ -public interface VMConstant extends Constant { -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIBackend.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIBackend.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIBackend.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIBackend.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +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. - */ -package jdk.vm.ci.runtime; - -import jdk.vm.ci.code.CodeCacheProvider; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.stack.StackIntrospection; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.MetaAccessProvider; - -/** - * A JVMCI backend encapsulates the capabilities needed by a Java based compiler for compiling and - * installing code for a single compute unit within a JVM. In a JVM with support for heterogeneous - * computing, more than one backend may be exposed. - */ -public class JVMCIBackend { - - private final MetaAccessProvider metaAccess; - private final CodeCacheProvider codeCache; - private final ConstantReflectionProvider constantReflection; - private final StackIntrospection stackIntrospection; - - public JVMCIBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) { - this.metaAccess = metaAccess; - this.codeCache = codeCache; - this.constantReflection = constantReflection; - this.stackIntrospection = stackIntrospection; - } - - public MetaAccessProvider getMetaAccess() { - return metaAccess; - } - - public CodeCacheProvider getCodeCache() { - return codeCache; - } - - public ConstantReflectionProvider getConstantReflection() { - return constantReflection; - } - - public TargetDescription getTarget() { - return codeCache.getTarget(); - } - - public StackIntrospection getStackIntrospection() { - return stackIntrospection; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +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. - */ -package jdk.vm.ci.runtime; - -import java.io.PrintStream; - -/** - * Factory for creating JVMCI compilers. - */ -public interface JVMCICompilerFactory { - - /** - * Get the name of this compiler. The name is used by JVMCI to determine which factory to use. - */ - String getCompilerName(); - - /** - * Notifies this object that it has been selected to {@linkplain #createCompiler(JVMCIRuntime) - * create} a compiler and it should now perform any heavy weight initialization that it deferred - * during construction. - */ - default void onSelection() { - } - - /** - * Create a new instance of a {@link JVMCICompiler}. - */ - JVMCICompiler createCompiler(JVMCIRuntime runtime); - - /** - * Prints a description of the properties used to configure this compiler. - * - * @param out where to print the message - */ - default void printProperties(PrintStream out) { - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +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. - */ -package jdk.vm.ci.runtime; - -import jdk.vm.ci.code.CompilationRequest; -import jdk.vm.ci.code.CompilationRequestResult; - -public interface JVMCICompiler { - int INVOCATION_ENTRY_BCI = -1; - - /** - * Services a compilation request. This object should compile the method to machine code and - * install it in the code cache if the compilation is successful. - */ - CompilationRequestResult compileMethod(CompilationRequest request); - - /** - * Determines if this compiler supports the {@code gcIdentifier} garbage collector. The default - * implementation of this method returns true as that is the effective answer given by a - * {@link JVMCICompiler} before this method was added. - * - * @param gcIdentifier a VM dependent GC identifier - */ - default boolean isGCSupported(int gcIdentifier) { - return true; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2015, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.runtime; - -import java.util.Formatter; - -import jdk.vm.ci.common.NativeImageReinitialize; -import jdk.vm.ci.services.Services; - -public class JVMCI { - - /** - * Singleton instance lazily initialized via double-checked locking. - */ - @NativeImageReinitialize private static volatile JVMCIRuntime runtime; - - @NativeImageReinitialize private static boolean initializing; - - public static void initialize() { - // force static initializer - } - - private static native JVMCIRuntime initializeRuntime(); - - /** - * Gets the singleton {@link JVMCIRuntime} instance available to the application. - * - * @throws UnsupportedOperationException if JVMCI is not supported - */ - public static JVMCIRuntime getRuntime() { - JVMCIRuntime result = runtime; - if (result == null) { - synchronized (JVMCI.class) { - result = runtime; - if (result == null) { - if (initializing) { - // In recursive call from HotSpotJVMCIRuntime.runtime - // so no need to re-enter initializeRuntime below. This - // path is only entered if JVMCI initialization starts - // with JVMCI.getRuntime(). - return null; - } - initializing = true; - try { - runtime = result = initializeRuntime(); - } catch (UnsatisfiedLinkError e) { - String javaHome = Services.getSavedProperty("java.home"); - String vmName = Services.getSavedProperty("java.vm.name"); - Formatter errorMessage = new Formatter(); - errorMessage.format("The VM does not support the JVMCI API.%n"); - errorMessage.format("Currently used Java home directory is %s.%n", javaHome); - errorMessage.format("Currently used VM configuration is: %s", vmName); - throw new UnsupportedOperationException(errorMessage.toString()); - } finally { - initializing = false; - } - } - } - } - return result; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIRuntime.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIRuntime.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIRuntime.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIRuntime.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +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. - */ -package jdk.vm.ci.runtime; - -import jdk.vm.ci.code.Architecture; - -/** - * Interface for accessing the {@link JVMCI} APIs supported by the runtime. - */ -public interface JVMCIRuntime { - - /** - * Gets the default system compiler. - */ - JVMCICompiler getCompiler(); - - /** - * Gets the host JVMCI backend. - */ - JVMCIBackend getHostJVMCIBackend(); - - /** - * Gets the backend for a given architecture. - * - * @param arch a specific architecture class - */ - JVMCIBackend getJVMCIBackend(Class arch); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * The core runtime interface of the JVMCI API. - */ -package jdk.vm.ci.runtime; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIPermission.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIPermission.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIPermission.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIPermission.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.services; - -import java.security.BasicPermission; - -/** - * This class represents the permission to access JVMCI services. - */ -public class JVMCIPermission extends BasicPermission { - - private static final long serialVersionUID = 6346818963934448226L; - - public JVMCIPermission() { - super("jvmci"); - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ -package jdk.vm.ci.services; - -import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; - -import java.util.ArrayList; -import java.util.List; -import java.util.ServiceLoader; - -/** - * Service-provider class for the runtime to locate providers of JVMCI services where the latter are - * not in packages exported by the JVMCI module. As part of instantiating a - * {@link JVMCIServiceLocator}, all JVMCI packages will be opened to the module defining the class - * of the instantiated object. - * - * While the {@link #getProvider(Class)} method can be used directly, it's usually easier to use - * {@link #getProviders(Class)}. - */ -public abstract class JVMCIServiceLocator { - - private static Void checkPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - return null; - } - - @SuppressWarnings("unused") - private JVMCIServiceLocator(Void ignore) { - } - - /** - * Creates a capability for accessing JVMCI. Once successfully instantiated, JVMCI opens all its - * packages to the module defining the type of this object. - * - * @throws SecurityException if a security manager has been installed and it denies - * {@link JVMCIPermission} - */ - protected JVMCIServiceLocator() { - this(checkPermission()); - Services.checkJVMCIEnabled(); - Services.openJVMCITo(getClass().getModule()); - } - - /** - * Gets the provider of the service defined by {@code service} or {@code null} if this object - * does not have a provider for {@code service}. - */ - protected abstract S getProvider(Class service); - - private static volatile List cachedLocators; - - private static Iterable getJVMCIServiceLocators() { - Iterable result = cachedLocators; - if (result != null) { - return result; - } - result = ServiceLoader.load(JVMCIServiceLocator.class, ClassLoader.getSystemClassLoader()); - if (IS_BUILDING_NATIVE_IMAGE) { - ArrayList l = new ArrayList<>(); - for (JVMCIServiceLocator locator : result) { - l.add(locator); - } - l.trimToSize(); - cachedLocators = l; - return l; - } - return result; - } - - /** - * Gets the providers of the service defined by {@code service} by querying the available - * {@link JVMCIServiceLocator} providers. - * - * @throws SecurityException if a security manager is present and it denies - * {@link JVMCIPermission} - */ - public static List getProviders(Class service) { - Services.checkJVMCIEnabled(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - List providers = new ArrayList<>(); - for (JVMCIServiceLocator access : getJVMCIServiceLocators()) { - S provider = access.getProvider(service); - if (provider != null) { - providers.add(provider); - } - } - return providers; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/package-info.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/package-info.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/package-info.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/package-info.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - */ - -/** - * The service related portions of the JVMCI API. - */ -package jdk.vm.ci.services; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package jdk.vm.ci.services; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Formatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.Set; - -import jdk.internal.misc.VM; - -/** - * Provides utilities needed by JVMCI clients. - */ -public final class Services { - - /** - * Guards code that should be run when building an JVMCI shared library but should be excluded - * from (being compiled into) the library. Such code must be directly guarded by an {@code if} - * statement on this field - the guard cannot be behind a method call. - */ - public static final boolean IS_BUILDING_NATIVE_IMAGE = Boolean.parseBoolean(VM.getSavedProperty("jdk.vm.ci.services.aot")); - - /** - * Guards code that should only be run in a JVMCI shared library. Such code must be directly - * guarded by an {@code if} statement on this field - the guard cannot be behind a method call. - * - * The value of this field in a JVMCI shared library runtime must be {@code true}. - */ - public static final boolean IS_IN_NATIVE_IMAGE; - static { - /* - * Prevents javac from constant folding use of this field. It is set to true by the process - * that builds the shared library. - */ - IS_IN_NATIVE_IMAGE = false; - } - - private Services() { - } - - /** - * In a native image, this field is initialized by {@link #initializeSavedProperties(byte[])}. - */ - private static volatile Map savedProperties; - - static final boolean JVMCI_ENABLED = Boolean.parseBoolean(VM.getSavedProperties().get("jdk.internal.vm.ci.enabled")); - - /** - * Checks that JVMCI is enabled in the VM and throws an error if it isn't. - */ - static void checkJVMCIEnabled() { - if (!JVMCI_ENABLED) { - throw new Error("The EnableJVMCI VM option must be true (i.e., -XX:+EnableJVMCI) to use JVMCI"); - } - } - - /** - * Gets an unmodifiable copy of the system properties saved when {@link System} is initialized. - */ - public static Map getSavedProperties() { - checkJVMCIEnabled(); - if (IS_IN_NATIVE_IMAGE) { - if (savedProperties == null) { - throw new InternalError("Saved properties not initialized"); - } - } else { - if (savedProperties == null) { - synchronized (Services.class) { - if (savedProperties == null) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - savedProperties = VM.getSavedProperties(); - } - } - } - } - return savedProperties; - } - - /** - * Helper method equivalent to {@link #getSavedProperties()}{@code .getOrDefault(name, def)}. - */ - public static String getSavedProperty(String name, String def) { - return Services.getSavedProperties().getOrDefault(name, def); - } - - /** - * Helper method equivalent to {@link #getSavedProperties()}{@code .get(name)}. - */ - public static String getSavedProperty(String name) { - return Services.getSavedProperties().get(name); - } - - /** - * Causes the JVMCI subsystem to be initialized if it isn't already initialized. - */ - public static void initializeJVMCI() { - checkJVMCIEnabled(); - try { - Class.forName("jdk.vm.ci.runtime.JVMCI"); - } catch (ClassNotFoundException e) { - throw new InternalError(e); - } - } - - private static final Map, List> servicesCache = IS_BUILDING_NATIVE_IMAGE ? new HashMap<>() : null; - - @SuppressWarnings("unchecked") - private static Iterable load0(Class service) { - if (IS_IN_NATIVE_IMAGE || IS_BUILDING_NATIVE_IMAGE) { - List list = servicesCache.get(service); - if (list != null) { - return (Iterable) list; - } - if (IS_IN_NATIVE_IMAGE) { - throw new InternalError(String.format("No %s providers found when building native image", service.getName())); - } - } - - Iterable providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader()); - if (IS_BUILDING_NATIVE_IMAGE) { - synchronized (servicesCache) { - ArrayList providersList = new ArrayList<>(); - for (S provider : providers) { - providersList.add(provider); - } - servicesCache.put(service, providersList); - providers = providersList; - } - } - return providers; - } - - /** - * Opens all JVMCI packages to {@code otherModule}. - */ - static void openJVMCITo(Module otherModule) { - Module jvmci = Services.class.getModule(); - if (jvmci != otherModule) { - Set packages = jvmci.getPackages(); - for (String pkg : packages) { - boolean opened = jvmci.isOpen(pkg, otherModule); - if (!opened) { - jvmci.addOpens(pkg, otherModule); - } - } - } - } - - /** - * Gets an {@link Iterable} of the JVMCI providers available for a given service. - * - * @throws SecurityException if a security manager is present and it denies - * {@link RuntimePermission}("jvmci") - */ - public static Iterable load(Class service) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - return load0(service); - } - - /** - * Gets the JVMCI provider for a given service for which at most one provider must be available. - * - * @param service the service whose provider is being requested - * @param required specifies if an {@link InternalError} should be thrown if no provider of - * {@code service} is available - * @throws SecurityException if a security manager is present and it denies - * {@link RuntimePermission}("jvmci") - */ - public static S loadSingle(Class service, boolean required) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - Iterable providers = load0(service); - - S singleProvider = null; - for (S provider : providers) { - if (singleProvider != null) { - throw new InternalError(String.format("Multiple %s providers found: %s, %s", service.getName(), singleProvider.getClass().getName(), provider.getClass().getName())); - } - singleProvider = provider; - } - if (singleProvider == null && required) { - String javaHome = Services.getSavedProperty("java.home"); - String vmName = Services.getSavedProperty("java.vm.name"); - Formatter errorMessage = new Formatter(); - errorMessage.format("The VM does not expose required service %s.%n", service.getName()); - errorMessage.format("Currently used Java home directory is %s.%n", javaHome); - errorMessage.format("Currently used VM configuration is: %s", vmName); - throw new UnsupportedOperationException(errorMessage.toString()); - } - return singleProvider; - } - - /** - * A Java {@code char} has a maximal UTF8 length of 3. - */ - private static final int MAX_UNICODE_IN_UTF8_LENGTH = 3; - - /** - * {@link DataOutputStream#writeUTF(String)} only supports values whose UTF8 encoding length is - * less than 65535. - */ - private static final int MAX_UTF8_PROPERTY_STRING_LENGTH = 65535 / MAX_UNICODE_IN_UTF8_LENGTH; - - /** - * Serializes the {@linkplain #getSavedProperties() saved system properties} to a byte array for - * the purpose of {@linkplain #initializeSavedProperties(byte[]) initializing} the initial - * properties in the JVMCI shared library. - */ - @VMEntryPoint - private static byte[] serializeSavedProperties() throws IOException { - if (IS_IN_NATIVE_IMAGE) { - throw new InternalError("Can only serialize saved properties in HotSpot runtime"); - } - return serializeProperties(Services.getSavedProperties()); - } - - private static byte[] serializeProperties(Map props) throws IOException { - // Compute size of output on the assumption that - // all system properties have ASCII names and values - int estimate = 4 + 4; - int nonUtf8Props = 0; - for (Map.Entry e : props.entrySet()) { - String name = e.getKey(); - String value = e.getValue(); - estimate += (2 + (name.length())) + (2 + (value.length())); - if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) { - nonUtf8Props++; - } - } - - ByteArrayOutputStream baos = new ByteArrayOutputStream(estimate); - DataOutputStream out = new DataOutputStream(baos); - out.writeInt(props.size() - nonUtf8Props); - out.writeInt(nonUtf8Props); - for (Map.Entry e : props.entrySet()) { - String name = e.getKey(); - String value = e.getValue(); - if (name.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH && value.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH) { - out.writeUTF(name); - out.writeUTF(value); - } - } - if (nonUtf8Props != 0) { - for (Map.Entry e : props.entrySet()) { - String name = e.getKey(); - String value = e.getValue(); - if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) { - byte[] utf8Name = name.getBytes("UTF-8"); - byte[] utf8Value = value.getBytes("UTF-8"); - out.writeInt(utf8Name.length); - out.write(utf8Name); - out.writeInt(utf8Value.length); - out.write(utf8Value); - } - } - } - return baos.toByteArray(); - } - - /** - * Initialized the {@linkplain #getSavedProperties() saved system properties} in the JVMCI - * shared library from the {@linkplain #serializeSavedProperties() serialized saved properties} - * in the HotSpot runtime. - */ - @VMEntryPoint - private static void initializeSavedProperties(byte[] serializedProperties) throws IOException { - if (!IS_IN_NATIVE_IMAGE) { - throw new InternalError("Can only initialize saved properties in JVMCI shared library runtime"); - } - savedProperties = Collections.unmodifiableMap(deserializeProperties(serializedProperties)); - } - - private static Map deserializeProperties(byte[] serializedProperties) throws IOException { - DataInputStream in = new DataInputStream(new ByteArrayInputStream(serializedProperties)); - int utf8Props = in.readInt(); - int nonUtf8Props = in.readInt(); - Map props = new HashMap<>(utf8Props + nonUtf8Props); - int index = 0; - while (in.available() != 0) { - if (index < utf8Props) { - String name = in.readUTF(); - String value = in.readUTF(); - props.put(name, value); - } else { - int nameLen = in.readInt(); - byte[] nameBytes = new byte[nameLen]; - in.read(nameBytes); - int valueLen = in.readInt(); - byte[] valueBytes = new byte[valueLen]; - in.read(valueBytes); - String name = new String(nameBytes, "UTF-8"); - String value = new String(valueBytes, "UTF-8"); - props.put(name, value); - } - index++; - } - return props; - } -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.services; - -/** - * Used to suppress FindBugs warnings. - */ -@interface SuppressFBWarnings { - /** - * The set of FindBugs - * warnings that are to be - * suppressed in annotated element. The value can be a bug category, kind or pattern. - */ - String[] value(); - - /** - * Reason why the warning is suppressed. - */ - String justification(); -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/VMEntryPoint.java openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/VMEntryPoint.java --- openjdk-17-17.0.7+7~us1/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/VMEntryPoint.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/VMEntryPoint.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.vm.ci.services; - -/** - * Marker interface for methods which are called from the JVM. - */ -@interface VMEntryPoint { - /** - * An optional comment describing the caller. - */ - String value() default ""; -} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java openjdk-17-17.0.8+7/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java --- openjdk-17-17.0.7+7~us1/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -728,6 +728,13 @@ && SignatureFileVerifier.isBlockOrSF(name)) { String alias = name.substring(name.lastIndexOf('/') + 1, name.lastIndexOf('.')); + long uncompressedSize = je.getSize(); + if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) { + unparsableSignatures.putIfAbsent(alias, String.format( + rb.getString("history.unparsable"), name)); + continue; + } + try { if (name.endsWith(".SF")) { Manifest sf = new Manifest(is); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java openjdk-17-17.0.8+7/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java --- openjdk-17-17.0.7+7~us1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java 2023-07-05 07:11:54.000000000 +0000 @@ -1704,7 +1704,8 @@ if (lower.startsWith("mailto:") || lower.startsWith("http:") || lower.startsWith("https:") - || lower.startsWith("file:")) { + || lower.startsWith("file:") + || lower.startsWith("ftp:")) { return text; } if (text.startsWith("#")) { diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java openjdk-17-17.0.8+7/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java --- openjdk-17-17.0.7+7~us1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java 2023-07-05 07:11:54.000000000 +0000 @@ -2936,8 +2936,11 @@ } public PreviewSummary declaredUsingPreviewAPIs(Element el) { - List usedInDeclaration = new ArrayList<>(); - usedInDeclaration.addAll(annotations2Classes(el)); + if (el.asType().getKind() == ERROR) { + // Can happen with undocumented --ignore-source-errors option + return new PreviewSummary(Collections.emptySet(), Collections.emptySet(), Collections.emptySet()); + } + List usedInDeclaration = new ArrayList<>(annotations2Classes(el)); switch (el.getKind()) { case ANNOTATION_TYPE, CLASS, ENUM, INTERFACE, RECORD -> { TypeElement te = (TypeElement) el; diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java openjdk-17-17.0.8+7/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java --- openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.events; + +import jdk.jfr.Category; +import jdk.jfr.Description; +import jdk.jfr.Label; +import jdk.jfr.Name; +import jdk.jfr.internal.MirrorEvent; + +@Category({"Java Development Kit", "Security"}) +@Label("Security Provider Instance Request") +@Name("jdk.SecurityProviderService") +@Description("Details of Provider.getInstance(String type, String algorithm) calls") +@MirrorEvent(className = "jdk.internal.event.SecurityProviderServiceEvent") +public final class SecurityProviderServiceEvent extends AbstractJDKEvent { + @Label("Type of Service") + public String type; + + @Label("Algorithm Name") + public String algorithm; + + @Label("Security Provider") + public String provider; +} diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java openjdk-17-17.0.8+7/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java --- openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java 2023-07-05 07:11:54.000000000 +0000 @@ -27,7 +27,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Properties; import jdk.internal.access.SharedSecrets; @@ -50,6 +49,7 @@ import jdk.jfr.events.InitialSecurityPropertyEvent; import jdk.jfr.events.ProcessStartEvent; import jdk.jfr.events.SecurityPropertyModificationEvent; +import jdk.jfr.events.SecurityProviderServiceEvent; import jdk.jfr.events.SocketReadEvent; import jdk.jfr.events.SocketWriteEvent; import jdk.jfr.events.TLSHandshakeEvent; @@ -70,6 +70,7 @@ DeserializationEvent.class, ProcessStartEvent.class, SecurityPropertyModificationEvent.class, + SecurityProviderServiceEvent.class, TLSHandshakeEvent.class, X509CertificateEvent.class, X509ValidationEvent.class @@ -89,6 +90,7 @@ jdk.internal.event.DeserializationEvent.class, jdk.internal.event.ProcessStartEvent.class, jdk.internal.event.SecurityPropertyModificationEvent.class, + jdk.internal.event.SecurityProviderServiceEvent.class, jdk.internal.event.TLSHandshakeEvent.class, jdk.internal.event.X509CertificateEvent.class, jdk.internal.event.X509ValidationEvent.class, diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/conf/jfr/default.jfc openjdk-17-17.0.8+7/src/jdk.jfr/share/conf/jfr/default.jfc --- openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/conf/jfr/default.jfc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.jfr/share/conf/jfr/default.jfc 2023-07-05 07:11:54.000000000 +0000 @@ -715,6 +715,11 @@ true + + false + true + + false true diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/conf/jfr/profile.jfc openjdk-17-17.0.8+7/src/jdk.jfr/share/conf/jfr/profile.jfc --- openjdk-17-17.0.7+7~us1/src/jdk.jfr/share/conf/jfr/profile.jfc 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.jfr/share/conf/jfr/profile.jfc 2023-07-05 07:11:54.000000000 +0000 @@ -715,6 +715,11 @@ true + + false + true + + false true diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java openjdk-17-17.0.8+7/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java --- openjdk-17-17.0.7+7~us1/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java 2023-07-05 07:11:54.000000000 +0000 @@ -374,7 +374,7 @@ ENTITLEMENTS.fetchFrom(params)); } restoreKeychainList(params); - } else if (Platform.isArmMac()) { + } else if (Platform.isMac()) { signAppBundle(params, root, "-", null, null); } else { // Calling signAppBundle() without signingIdentity will result in diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java openjdk-17-17.0.8+7/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java --- openjdk-17-17.0.7+7~us1/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java 2023-07-05 07:11:54.000000000 +0000 @@ -79,7 +79,8 @@ * @param timeout the start-up time-out in milliseconds. If zero or negative, * will not wait thus will timeout immediately if not already started. * @param customConnectorArgs custom arguments passed to the connector. - * These are JDI com.sun.jdi.connect.Connector arguments. + * These are JDI com.sun.jdi.connect.Connector arguments. The {@code vmexec} + * argument is not supported. */ public JdiInitiator(int port, List remoteVMOptions, String remoteAgent, boolean isLaunch, String host, int timeout, @@ -104,7 +105,10 @@ argumentName2Value.put("localAddress", host); } } - argumentName2Value.putAll(customConnectorArgs); + customConnectorArgs.entrySet() + .stream() + .filter(e -> !"vmexec".equals(e.getKey())) + .forEach(e -> argumentName2Value.put(e.getKey(), e.getValue())); this.connectorArgs = mergeConnectorArgs(connector, argumentName2Value); this.vm = isLaunch ? launchTarget() diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java openjdk-17-17.0.8+7/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -542,7 +542,8 @@ @Override public void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { - SctpNet.preClose(fdVal); + if (state != ChannelState.KILLED) + SctpNet.preClose(fdVal); if (receiverThread != 0) NativeThread.signal(receiverThread); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java openjdk-17-17.0.8+7/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -290,7 +290,8 @@ @Override public void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { - SctpNet.preClose(fdVal); + if (state != ChannelState.KILLED) + SctpNet.preClose(fdVal); if (receiverThread != 0) NativeThread.signal(receiverThread); diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java openjdk-17-17.0.8+7/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java --- openjdk-17-17.0.7+7~us1/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java 2023-07-05 07:11:54.000000000 +0000 @@ -267,7 +267,8 @@ @Override public void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { - SctpNet.preClose(fdVal); + if (state != ChannelState.KILLED) + SctpNet.preClose(fdVal); if (thread != 0) NativeThread.signal(thread); if (!isRegistered()) diff -Nru openjdk-17-17.0.7+7~us1/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java openjdk-17-17.0.8+7/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java --- openjdk-17-17.0.7+7~us1/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3063,6 +3063,11 @@ if (extra == null) return; int elen = extra.length; + // Extra field Length cannot exceed 65,535 bytes per the PKWare + // APP.note 4.4.11 + if (elen > 0xFFFF) { + throw new ZipException("invalid extra field length"); + } int off = 0; int newOff = 0; boolean hasZip64LocOffset = false; @@ -3072,26 +3077,40 @@ int tag = SH(extra, pos); int sz = SH(extra, pos + 2); pos += 4; - if (pos + sz > elen) // invalid data - break; + if (pos + sz > elen) { // invalid data + throw new ZipException("Invalid CEN header (invalid zip64 extra data field size)"); + } switch (tag) { case EXTID_ZIP64 : + // Check to see if we have a valid block size + if (!isZip64ExtBlockSizeValid(sz)) { + throw new ZipException("Invalid CEN header (invalid zip64 extra data field size)"); + } if (size == ZIP64_MINVAL) { if (pos + 8 > elen) // invalid zip64 extra break; // fields, just skip size = LL(extra, pos); + if (size < 0) { + throw new ZipException("Invalid zip64 extra block size value"); + } pos += 8; } if (csize == ZIP64_MINVAL) { if (pos + 8 > elen) break; csize = LL(extra, pos); + if (csize < 0) { + throw new ZipException("Invalid zip64 extra block compressed size value"); + } pos += 8; } if (locoff == ZIP64_MINVAL) { if (pos + 8 > elen) break; locoff = LL(extra, pos); + if (locoff < 0) { + throw new ZipException("Invalid zip64 extra block LOC offset value"); + } } break; case EXTID_NTFS: @@ -3150,6 +3169,36 @@ } /** + * Validate the size and contents of a Zip64 extended information field + * The order of the Zip64 fields is fixed, but the fields MUST + * only appear if the corresponding LOC or CEN field is set to 0xFFFF: + * or 0xFFFFFFFF: + * Uncompressed Size - 8 bytes + * Compressed Size - 8 bytes + * LOC Header offset - 8 bytes + * Disk Start Number - 4 bytes + * See PKWare APP.Note Section 4.5.3 for more details + * + * @param blockSize the Zip64 Extended Information Extra Field size + * @return true if the extra block size is valid; false otherwise + */ + private static boolean isZip64ExtBlockSizeValid(int blockSize) { + /* + * As the fields must appear in order, the block size indicates which + * fields to expect: + * 8 - uncompressed size + * 16 - uncompressed size, compressed size + * 24 - uncompressed size, compressed sise, LOC Header offset + * 28 - uncompressed size, compressed sise, LOC Header offset, + * and Disk start number + */ + return switch(blockSize) { + case 8, 16, 24, 28 -> true; + default -> false; + }; + } + + /** * Read the LOC extra field to obtain the Info-ZIP Extended Timestamp fields * @param zipfs The Zip FS to use * @throws IOException If an error occurs diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/gtest/classfile/test_symbolTable.cpp openjdk-17-17.0.8+7/test/hotspot/gtest/classfile/test_symbolTable.cpp --- openjdk-17-17.0.7+7~us1/test/hotspot/gtest/classfile/test_symbolTable.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/gtest/classfile/test_symbolTable.cpp 2023-07-05 07:11:54.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 @@ -145,3 +145,10 @@ TEST_VM(SymbolTable, test_symbol_refcount_parallel) { mt_test_doer(); } + +TEST_VM_FATAL_ERROR_MSG(SymbolTable, test_symbol_underflow, ".*refcount has gone to zero.*") { + Symbol* my_symbol = SymbolTable::new_symbol("my_symbol2023"); + EXPECT_TRUE(my_symbol->refcount() == 1) << "Symbol refcount just created is 1"; + my_symbol->decrement_refcount(); + my_symbol->increment_refcount(); // Should crash even in PRODUCT mode +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/gtest/gtestMain.cpp openjdk-17-17.0.8+7/test/hotspot/gtest/gtestMain.cpp --- openjdk-17-17.0.7+7~us1/test/hotspot/gtest/gtestMain.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/gtest/gtestMain.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -244,7 +244,7 @@ char* java_home = get_java_home_arg(argc, argv); if (java_home == NULL) { - fprintf(stderr, "ERROR: You must specify a JDK to use for running the unit tests.\n"); + fprintf(stderr, "ERROR: You must specify a JDK (-jdk , --jdk= or -jdk:) to use for running the unit tests.\n"); exit(1); } #ifndef _WIN32 diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/gtest/runtime/test_os.cpp openjdk-17-17.0.8+7/test/hotspot/gtest/runtime/test_os.cpp --- openjdk-17-17.0.7+7~us1/test/hotspot/gtest/runtime/test_os.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/gtest/runtime/test_os.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -844,7 +844,7 @@ } TEST_VM(os, is_first_C_frame) { -#if !defined(_WIN32) && !defined(ZERO) +#if !defined(_WIN32) && !defined(ZERO) && !defined(__thumb__) frame invalid_frame; EXPECT_TRUE(os::is_first_C_frame(&invalid_frame)); // the frame has zeroes for all values diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp openjdk-17-17.0.8+7/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp --- openjdk-17-17.0.7+7~us1/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022, 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 "precompiled.hpp" + +#ifdef LINUX + +#include "cgroupV1Subsystem_linux.hpp" +#include "cgroupV2Subsystem_linux.hpp" +#include "unittest.hpp" + +typedef struct { + const char* mount_path; + const char* root_path; + const char* cgroup_path; + const char* expected_path; +} TestCase; + +TEST(os_linux_cgroup, set_cgroupv1_subsystem_path) { + TestCase host = { + "/sys/fs/cgroup/memory", // mount_path + "/", // root_path + "/user.slice/user-1000.slice/user@1000.service", // cgroup_path + "/sys/fs/cgroup/memory/user.slice/user-1000.slice/user@1000.service" // expected_path + }; + TestCase container_engine = { + "/sys/fs/cgroup/mem", // mount_path + "/user.slice/user-1000.slice/user@1000.service", // root_path + "/user.slice/user-1000.slice/user@1000.service", // cgroup_path + "/sys/fs/cgroup/mem" // expected_path + }; + int length = 2; + TestCase* testCases[] = { &host, + &container_engine }; + for (int i = 0; i < length; i++) { + CgroupV1Controller* ctrl = new CgroupV1Controller( (char*)testCases[i]->root_path, + (char*)testCases[i]->mount_path); + ctrl->set_subsystem_path((char*)testCases[i]->cgroup_path); + ASSERT_STREQ(testCases[i]->expected_path, ctrl->subsystem_path()); + } +} + +TEST(os_linux_cgroup, set_cgroupv2_subsystem_path) { + TestCase at_mount_root = { + "/sys/fs/cgroup", // mount_path + NULL, // root_path, ignored + "/", // cgroup_path + "/sys/fs/cgroup" // expected_path + }; + TestCase sub_path = { + "/sys/fs/cgroup", // mount_path + NULL, // root_path, ignored + "/foobar", // cgroup_path + "/sys/fs/cgroup/foobar" // expected_path + }; + int length = 2; + TestCase* testCases[] = { &at_mount_root, + &sub_path }; + for (int i = 0; i < length; i++) { + CgroupV2Controller* ctrl = new CgroupV2Controller( (char*)testCases[i]->mount_path, + (char*)testCases[i]->cgroup_path); + ASSERT_STREQ(testCases[i]->expected_path, ctrl->subsystem_path()); + } +} + +#endif diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022, 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 8279125 + * @summary fatal error: no reachable node should have no use + * @requires vm.flavor == "server" + * + * @run main/othervm -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis TestAllocArrayAfterAllocNoUse + * + */ + +public class TestAllocArrayAfterAllocNoUse { + private static Object field; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(); + } + } + + private static void test() { + try { + final TestAllocArrayAfterAllocNoUse o = new TestAllocArrayAfterAllocNoUse(); + } catch (Exception e) { + final int[] array = new int[100]; + field = array; + } + + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, 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 8279062 + * @summary C2: assert(t->meet(t0) == t) failed: Not monotonic after JDK-8278413 + * + * @run main/othervm -XX:-BackgroundCompilation TestCCPAllocateArray + * + */ + +public class TestCCPAllocateArray { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + try { + test(); + } catch (OutOfMemoryError e) { + } + length(42); + } + } + + private static int[] test() { + int i = 2; + for (; i < 4; i *= 2); + return new int[length(i)]; + } + + private static int length(int i) { + return i == 4 ? Integer.MAX_VALUE : 0; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022, 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 8279219 + * @summary C2 crash when allocating array of size too large + * @requires vm.compiler2.enabled + * @library /test/lib / + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -ea -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestFailedAllocationBadGraph + */ + +import jdk.test.whitebox.WhiteBox; +import java.lang.reflect.Method; +import compiler.whitebox.CompilerWhiteBoxTest; + +public class TestFailedAllocationBadGraph { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + private static long[] array; + private static int field; + private static volatile int barrier; + + public static void main(String[] args) throws Exception { + run("test1"); + run("test2"); + } + + private static void run(String method) throws Exception { + Method m = TestFailedAllocationBadGraph.class.getDeclaredMethod(method); + WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + if (!WHITE_BOX.isMethodCompiled(m) || WHITE_BOX.getMethodCompilationLevel(m) != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { + throw new RuntimeException("should still be compiled"); + } + } + + private static int test1() { + int length = Integer.MAX_VALUE; + try { + array = new long[length]; + } catch (OutOfMemoryError outOfMemoryError) { + barrier = 0x42; + length = field; + } + return length; + } + + private static int test2() { + int length = -1; + try { + array = new long[length]; + } catch (OutOfMemoryError outOfMemoryError) { + barrier = 0x42; + length = field; + } + return length; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestNewArrayBadSize.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestNewArrayBadSize.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestNewArrayBadSize.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestNewArrayBadSize.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022, 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 8288184 + * @summary C2 compilation asserts with "Bad graph detected in compute_lca_of_uses" + * @run main/othervm -XX:-BackgroundCompilation TestNewArrayBadSize + */ + +public class TestNewArrayBadSize { + long instanceCount; + int iFld; + + void vMeth(int i, long l) { + int i1, i19 = -845; + for (i1 = 5; i1 > 1; i1 -= 2) + try { + int ax$0 = i19; + try { + for (Object temp = new byte[i19]; ; i19 = "1".equals("0") ? 2 : 1) {} + } finally { + i19 = ax$0; + } + } catch (Throwable ax$3) { + } + } + + void mainTest(String[] strArr1) { + vMeth(iFld, instanceCount); + } + + public static void main(String[] strArr) { + TestNewArrayBadSize _instance = new TestNewArrayBadSize(); + for (int i = 0; i < 10_000; ++i) _instance.mainTest(strArr); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestNewArrayOutsideLoopValidLengthTestInLoop.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestNewArrayOutsideLoopValidLengthTestInLoop.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/allocation/TestNewArrayOutsideLoopValidLengthTestInLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/allocation/TestNewArrayOutsideLoopValidLengthTestInLoop.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022, 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 8291665 + * @summary C2: assert compiling SSLEngineInputRecord::decodeInputRecord + * @run main/othervm -Xbatch TestNewArrayOutsideLoopValidLengthTestInLoop + */ + +import java.util.Arrays; + +public class TestNewArrayOutsideLoopValidLengthTestInLoop { + private static volatile int barrier; + + public static void main(String[] args) { + boolean[] allFalse = new boolean[100]; + boolean[] allTrue = new boolean[100]; + Arrays.fill(allTrue, true); + for (int i = 0; i < 20_000; i++) { + test1(allFalse, allFalse, true); + test1(allTrue, allFalse, true); + test1(allFalse, allTrue, true); + test1(allFalse, allFalse, false); + } + } + + private static int[] test1(boolean[] flags1, boolean[] flags2, boolean flag) { + for (int i = 1; i < 100; i *= 2) { + boolean f = false; + int j = i; + if (flags1[i]) { + barrier = 1; + f = true; + j = i / 2; + } + if (flag) { + barrier = 1; + } + if (f) { + return new int[j]; + } + if (flags2[i]) { + return new int[j]; + } + } + return null; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,312 @@ +/* + * 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 8297730 + * @summary Test taking UCT between array allocation and array copy to report correct exception. + * @library /test/lib + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.arraycopy.TestArrayCopyIntrinsicWithUCT::test* + * compiler.arraycopy.TestArrayCopyIntrinsicWithUCT + */ + +package compiler.arraycopy; + +import jdk.test.lib.Asserts; + +import java.util.function.Function; +import java.util.function.Supplier; + +public class TestArrayCopyIntrinsicWithUCT { + static int zero = 0; + static int zero2 = 0; + static int minusOne = -1; + static int iFld; + static int iFld2; + static boolean flag; + static byte[] byArrNull = null; + static A aFld = null; + + static public void main(String[] args) { + System.out.println("Start"); // Ensure loaded. + new A(); // Ensure loaded + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSize); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSize2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeFldSize); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeFldSize2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeStore); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeStore2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero3); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero4); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero5); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero6); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero7); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld3); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld4); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld5); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld6); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld7); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroNullPointer); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeComplex); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeControlFlowNotAllowed); + flag = false; + runNegativeSizeHalf(); + runNegativeSizeHalf(); + } + + static void runNegativeSize(Supplier testMethod) { + try { + testMethod.get(); + Asserts.fail("should throw exception"); + } catch (NegativeArraySizeException e) { + // Expected + } + } + + static void runNegativeSize(Function testMethod) { + try { + testMethod.apply(null); + Asserts.fail("should throw exception"); + } catch (NegativeArraySizeException e) { + // Expected + } + } + + static byte[] testNegativeSize(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = byArr.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSize2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = byArrNull.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeFldSize(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = byArr.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + static byte[] testNegativeFldSize2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = byArrNull.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeStore(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + iFld++; // Since we have a store here, we do not move the allocation down + int len = byArr.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeStore2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + iFld++; // Since we have a store here, we do not move the allocation down + int len = byArrNull.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZero(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZero2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZero3(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero4(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero5(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero6(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero7(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZeroFld2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZeroFld3(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld4(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld5(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld6(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld7(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroNullPointer(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int x = minusOne / zero / zero2; // div by zero trap would fail + int len = byArr.length; + System.arraycopy(byArr, 0, b, 0, len); + iFld = x; + return b; + } + + static byte[] testNegativeSizeComplex(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int x = minusOne / zero; // div by zero trap would fail + int y = aFld.i; + int len = byArr.length; + x = x + aFld.i2 / zero2; + System.arraycopy(byArr, 0, b, 0, x); + iFld = x + y; + return b; + } + + // Optimization not applied because of additional control flow that is not considered safe. + static byte[] testNegativeControlFlowNotAllowed(byte[] byArr) { + int x = 23; + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + if (flag) { + x = 34; + } + int len = x / zero; + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static void runNegativeSizeHalf() { + try { + testNegativeSizeHalf(null); + Asserts.fail("should throw exception"); + } catch (NegativeArraySizeException e) { + Asserts.assertTrue(flag, "wrongly caught NegativeArraySizeException"); + } catch (NullPointerException e) { + Asserts.assertFalse(flag, "wrongly caught NullPointerException"); + } + flag = !flag; + } + + static byte[] testNegativeSizeHalf(byte[] byArr) { + int size = flag ? -1 : 1; + byte[] b = new byte[size]; // throws NegativeArraySizeException if size == -1 + int len = byArr.length; // throws NullPointerException if size == 1 + System.arraycopy(byArr, 0, b, 0, len); + return b; + } +} + +class A { + int i, i2; +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeLoadOptoTest.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeLoadOptoTest.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeLoadOptoTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeLoadOptoTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2022, 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 8296545 + * @requires vm.compiler2.enabled + * @summary Blackholes should allow load optimizations + * @library /test/lib / + * @run driver compiler.c2.irTests.blackhole.BlackholeLoadOptoTest + */ + +package compiler.c2.irTests.blackhole; + +import compiler.lib.ir_framework.*; +import jdk.test.lib.Asserts; + +public class BlackholeLoadOptoTest { + + public static void main(String[] args) { + TestFramework.runWithFlags( + "-XX:+UnlockExperimentalVMOptions", + "-XX:CompileThreshold=100", + "-XX:-TieredCompilation", + "-XX:CompileCommand=blackhole,compiler.c2.irTests.blackhole.BlackholeLoadOptoTest::blackhole", + "-XX:CompileCommand=dontinline,compiler.c2.irTests.blackhole.BlackholeLoadOptoTest::dontinline" + ); + } + + static int x, y; + + + /* + * Negative test: check that dangling expressions are eliminated + */ + + @Test + @IR(failOn = {IRNode.LOAD_I, IRNode.MUL_I}) + static void testNothing() { + int r1 = x * y; + int r2 = x * y; + } + + @Run(test = "testNothing") + static void runNothing() { + testNothing(); + } + + /* + * Auxiliary test: check that dontinline method does break optimizations + */ + + @Test + @IR(counts = {IRNode.LOAD_I, "4"}) + @IR(counts = {IRNode.MUL_I, "2"}) + static void testDontline() { + int r1 = x * y; + dontinline(r1); + int r2 = x * y; + dontinline(r2); + } + + static void dontinline(int x) {} + + @Run(test = "testDontline") + static void runDontinline() { + testDontline(); + } + + /* + * Positive test: check that blackhole does not break optimizations + */ + + @Test + @IR(counts = {IRNode.LOAD_I, "2"}) + @IR(counts = {IRNode.MUL_I, "1"}) + static void testBlackholed() { + int r1 = x * y; + blackhole(r1); + int r2 = x * y; + blackhole(r2); + } + + static void blackhole(int x) {} + + @Run(test = "testBlackholed") + static void runBlackholed() { + testBlackholed(); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,135 @@ +/* + * 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.irTests; + +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8201516 + * @summary Verify that debug information in C2 compiled code is correct. + * @library /test/lib / + * @requires vm.compiler2.enabled + * @run driver compiler.c2.irTests.TestDebugInfo + */ +public class TestDebugInfo { + + public static void main(String[] args) { + TestFramework.runWithFlags("-XX:+UnlockDiagnosticVMOptions", "-XX:+DebugNonSafepoints"); + } + + static class MyClass { + final int val; + + @ForceInline + public MyClass(int val) { + this.val = val; + } + + @ForceInline + synchronized void synchronizedMethod(boolean throwIt) { + if (throwIt) { + throw new RuntimeException(); // Make sure there is an exception state + } + } + } + + static Object[] array = new Object[3]; + static MyClass myVal = new MyClass(42); + + // Verify that the MemBarRelease emitted at the MyClass constructor exit + // does not incorrectly reference the caller method in its debug information. + @Test + @IR(failOn = {"MemBarRelease.*testFinalFieldInit.*bci:-1"}) + public static void testFinalFieldInit() { + array[0] = new MyClass(42); + array[1] = new MyClass(42); + array[2] = new MyClass(42); + } + + // Verify that the MemBarReleaseLock emitted at the synchronizedMethod exit + // does not incorrectly reference the caller method in its debug information. + @Test + @IR(failOn = {"MemBarReleaseLock.*testSynchronized.*bci:-1"}) + public static void testSynchronized() { + try { + myVal.synchronizedMethod(false); + myVal.synchronizedMethod(true); + } catch (Exception e) { + // Ignore + } + } + + static byte b0 = 0; + static byte b1 = 0; + static byte b2 = 0; + static byte b3 = 0; + + @ForceInline + public static Integer useless3(Integer val) { + return ++val; + } + + @ForceInline + public static Integer useless2(Integer val) { + return useless3(useless3(useless3(useless3(useless3(useless3(useless3(useless3(val)))))))); + } + + @ForceInline + public static Integer useless1(Integer val) { + return useless2(useless2(useless2(useless2(useless2(useless2(useless2(useless2(val)))))))); + } + + @ForceInline + public static void useful3() { + b3 = 3; + } + + @ForceInline + public static void useful2() { + useful3(); + b2 = 2; + } + + @ForceInline + public static void useful1() { + useful2(); + b1 = 1; + } + + // Verify that RenumberLiveNodes preserves the debug information side table. + @Test + @IR(counts = {"StoreB.*name=b3.*useful3.*bci:1.*useful2.*bci:0.*useful1.*bci:0.*testRenumberLiveNodes.*bci:9", "= 1"}) + @IR(counts = {"StoreB.*name=b2.*useful2.*bci:4.*useful1.*bci:0.*testRenumberLiveNodes.*bci:9", "= 1"}) + @IR(counts = {"StoreB.*name=b1.*useful1.*bci:4.*testRenumberLiveNodes.*bci:9", "= 1"}) + @IR(counts = {"StoreB.*name=b0.*testRenumberLiveNodes.*bci:13", "= 1"}) + public static void testRenumberLiveNodes() { + // This generates ~3700 useless nodes to trigger RenumberLiveNodes + useless1(42); + + // Do something useful + useful1(); + b0 = 0; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/codegen/aes/CTR_Wraparound.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/codegen/aes/CTR_Wraparound.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/codegen/aes/CTR_Wraparound.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/codegen/aes/CTR_Wraparound.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,127 @@ +/* + * 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 Check for 128-bit AES/CTR wraparound + * @library /test/lib / + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * + * @run main/othervm -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.codegen.aes.CTR_Wraparound 32 + * @run main/othervm -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.codegen.aes.CTR_Wraparound 1009 + * @run main/othervm -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.codegen.aes.CTR_Wraparound 2048 + */ + +package compiler.codegen.aes; + +import java.util.Arrays; +import java.util.Random; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import compiler.whitebox.CompilerWhiteBoxTest; +import jdk.test.whitebox.code.Compiler; +import jdk.test.lib.Utils; +import jtreg.SkippedException; + +public class CTR_Wraparound { + private static final String ALGO = "AES/CTR/NoPadding"; + private static final int LOOPS = 100000; + + public static void main(String[] args) throws Exception { + int length = Integer.parseInt(args[0]); + int maxOffset = 60; + if (args.length > 1) { + maxOffset = Integer.parseInt(args[1]); + System.out.println("InitialOffset = " + maxOffset); + } + + if (!Compiler.isIntrinsicAvailable(CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "com.sun.crypto.provider.CounterMode", "implCrypt", byte[].class, int.class, int.class, byte[].class, int.class)) { + throw new SkippedException("AES-CTR intrinsic is not available"); + } + + Random random = Utils.getRandomInstance(); + + byte[] keyBytes = new byte[32]; + Arrays.fill(keyBytes, (byte)0xff); + SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); + + byte[] ivBytes = new byte[16]; + + Arrays.fill(ivBytes, (byte)0xff); + + byte[][] plaintext = new byte[maxOffset][]; + byte[][] ciphertext = new byte[maxOffset][]; + + for (int offset = 0; offset < maxOffset; offset++) { + ivBytes[ivBytes.length - 1] = (byte)-offset; + IvParameterSpec iv = new IvParameterSpec(ivBytes); + + Cipher encryptCipher = Cipher.getInstance(ALGO); + Cipher decryptCipher = Cipher.getInstance(ALGO); + + encryptCipher.init(Cipher.ENCRYPT_MODE, key, iv); + decryptCipher.init(Cipher.DECRYPT_MODE, key, iv); + + plaintext[offset] = new byte[length]; + ciphertext[offset] = new byte[length]; + random.nextBytes(plaintext[offset]); + + byte[] decrypted = new byte[length]; + + encryptCipher.doFinal(plaintext[offset], 0, length, ciphertext[offset]); + decryptCipher.doFinal(ciphertext[offset], 0, length, decrypted); + + if (!Arrays.equals(plaintext[offset], decrypted)) { + throw new Exception("mismatch in setup at offset " + offset); + } + } + + for (int offset = 0; offset < maxOffset; offset++) { + ivBytes[ivBytes.length - 1] = (byte)-offset; + IvParameterSpec iv = new IvParameterSpec(ivBytes); + + Cipher encryptCipher = Cipher.getInstance(ALGO); + + encryptCipher.init(Cipher.ENCRYPT_MODE, key, iv); + + byte[] encrypted = new byte[length]; + + for (int i = 0; i < LOOPS; i++) { + encryptCipher.doFinal(plaintext[offset], 0, length, encrypted); + if (!Arrays.equals(ciphertext[offset], encrypted)) { + throw new Exception("array mismatch at offset " + offset + + " with length " + length); + } + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/intrinsics/string/TestCopyValueOf.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/intrinsics/string/TestCopyValueOf.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/intrinsics/string/TestCopyValueOf.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/intrinsics/string/TestCopyValueOf.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8300079 + * @summary Verify that String.copyValueOf properly handles null input with intrinsified helper methods. + * @run main/othervm -XX:-TieredCompilation -Xcomp + * -XX:CompileCommand=compileonly,compiler.intrinsics.string.TestCopyValueOf::test + * -XX:CompileCommand=dontinline,java.lang.String::rangeCheck + * compiler.intrinsics.string.TestCopyValueOf + */ + +package compiler.intrinsics.string; + +public class TestCopyValueOf { + + public static boolean test() { + try { + String.copyValueOf(null, 42, 43); + } catch (NullPointerException e) { + return true; + } + return false; + } + + public static void main(String[] args) { + // Warmup + char data[] = {42}; + String.copyValueOf(data, 0, 1); + + if (!test()) { + throw new RuntimeException("Unexpected result"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java 2023-07-05 07:11:54.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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8301491 + * @summary Check for correct return value when calling indexOfChar intrinsics with negative value. + * @library /test/lib + * + * @run main/othervm -XX:CompileCommand=quiet + * -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.intrinsics.string.TestStringIndexOfCharIntrinsics::testIndexOfChar* + * -XX:CompileCommand=inline,java.lang.String*::indexOf* + * -XX:PerBytecodeTrapLimit=20000 + * -XX:PerMethodTrapLimit=20000 + * compiler.intrinsics.string.TestStringIndexOfCharIntrinsics + */ + +package compiler.intrinsics.string; + +import jdk.test.lib.Asserts; + +public class TestStringIndexOfCharIntrinsics { + + static byte byArr[] = new byte[500]; + + public static void main(String[] args) { + for (int j = 0; j < byArr.length; j++) { + byArr[j] = (byte)j; + } + // Test value for aarch64 + byArr[24] = 0x7; + byArr[23] = -0x80; + // Warmup + for (int i = 0; i < 10000; i++) { + testIndexOfCharArg(i); + testIndexOfCharConst(); + } + Asserts.assertEquals(testIndexOfCharConst() , -1, "must be -1 (character not found)"); + Asserts.assertEquals(testIndexOfCharArg(-2147483641) , -1, "must be -1 (character not found)"); + } + + static int testIndexOfCharConst() { + String s = new String(byArr); + return s.indexOf(-2147483641); + } + + static int testIndexOfCharArg(int ch) { + String s = new String(byArr); + return s.indexOf(ch); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java 2023-07-05 07:11:54.000000000 +0000 @@ -138,6 +138,7 @@ public static final String CMP_U = START + "CmpU" + MID + END; public static final String CMP_I = START + "CmpI" + MID + END; + public static final String MUL_I = START + "MulI" + MID + END; public static final String MUL_L = START + "MulL" + MID + END; public static final String POPCOUNT_L = START + "PopCountL" + MID + END; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFill.jasm openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFill.jasm --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFill.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFill.jasm 2023-07-05 07:11:54.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. + * + */ + +super public class TestBackedgeLoadArrayFill +{ + public Method "":"()V" + stack 2 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + + static Method test_101:"()V" + stack 20 locals 20 + { + // test_002 in jasm: using try-catch + ldc 6; + istore_0; // i = 6 + ldc 25; + newarray int; + astore_1; // arr = new int[25] + HEAD: + aload_1; + iload_0; + iconst_1; + iastore; // arr[i] = 1 + // second block - the only one -> head block can be copied: one before, one on backedge + try t0; + aload_1; + iload_0; + aload_1; + iload_0; + iaload; + iastore; // arr[i] = arr[i] + goto FINALLY; + endtry t0; + catch t0 java/lang/Exception; + pop; // exception + FINALLY: + iinc 0, 1; // i++ + iload_0; + ldc 21; + if_icmplt HEAD; // if i < 21 + // write array + aload_1; + putstatic Field TestBackedgeLoadArrayFillMain.intA:"[I"; + return; + } + + static Method test_102:"()V" + stack 20 locals 20 + { + // test_002 in jasm: without try-catch + ldc 5; + istore_0; // i = 5 + ldc 25; + newarray int; + astore_1; // arr = new int[25] + HEAD: + aload_1; + iload_0; + iconst_1; + iastore; // arr[i] = 1 + goto SECOND; + // second block - the only one -> head block can be copied: one before, one on backedge + // must have some material before inc, else it is partial peeled away + // And if we set -XX:-PartialPeelLoop, then the counted loop is never detected + SECOND: + aload_1; + iload_0; + aload_1; + iload_0; + iaload; + iastore; // arr[i] = arr[i] + iinc 0, 1; // i++ + iload_0; + ldc 21; + if_icmplt HEAD; // if i < 21 + // write array + aload_1; + putstatic Field TestBackedgeLoadArrayFillMain.intA:"[I"; + return; + } + + static Method test_103:"()V" + stack 20 locals 20 + { + // test_002 in jasm: without try-catch, and second array + ldc 7; + istore_0; // i = 7 + ldc 25; + newarray int; + astore_1; // arr = new int[25] + ldc 25; + newarray int; + astore_2; // arr2 = new int[25] + HEAD: + aload_1; + iload_0; + iconst_1; + iastore; // arr[i] = 1 + goto SECOND; + // second block - the only one -> head block can be copied: one before, one on backedge + SECOND: + // we can also do the identity read-write on another array - it just has to eventually disappear + aload_2; + iload_0; + aload_2; + iload_0; + iaload; + iastore; // arr2[i] = arr2[i] + + iinc 0, 1; // i++ + iload_0; + ldc 21; + if_icmplt HEAD; // if i < 21 + // write array + aload_1; + putstatic Field TestBackedgeLoadArrayFillMain.intA:"[I"; + return; + } + + static Method test_104:"()V" + stack 20 locals 20 + { + ldc 9; + istore_0; // i = 9 + ldc 25; + newarray int; + astore_1; // arr = new int[25] + HEAD: + aload_1; + iload_0; + iconst_1; + iastore; // arr[i] = 1 + goto SECOND; + // second block - the only one -> head block can be copied: one before, one on backedge + SECOND: + // CFG leads to partial peel -> load moved into loop body, then intrinsified + iload_0; + ldc 2; + irem; + ifeq SKIP; + + SKIP: + + iinc 0, 1; // i++ + iload_0; + ldc 21; + if_icmplt HEAD; // if i < 21 + // write array + aload_1; + putstatic Field TestBackedgeLoadArrayFillMain.intA:"[I"; + return; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,231 @@ +/* + * 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 8299179 + * @summary ArrayFill: if store is on backedge, last iteration is not to be executed. + * @library /test/lib + * @compile TestBackedgeLoadArrayFill.jasm + * @run main/othervm + * -XX:CompileCommand=compileonly,TestBackedgeLoadArrayFill*::test* + * -XX:-TieredCompilation -Xcomp -XX:+OptimizeFill + * TestBackedgeLoadArrayFillMain + * @run main/othervm + * -XX:CompileCommand=compileonly,TestBackedgeLoadArrayFill*::test* + * -XX:-TieredCompilation -Xcomp -XX:+OptimizeFill + * -XX:LoopUnrollLimit=1 + * TestBackedgeLoadArrayFillMain + */ + +import jdk.test.lib.Asserts; + +public class TestBackedgeLoadArrayFillMain { + static long[] longA; + static int[] intA; + static short[] shortA; + static byte[] byteA; + + static class Data { + long longValue; + int intValue; + short shortValue; + byte byteValue; + + Data(int value) { + longValue = (long) value; + intValue = (int) value; + shortValue = (short) value; + longValue = (byte) value; + } + } + + public static long longSum() { + long s = 0; + for (long v : longA) { s += v; } + return s; + } + + public static int intSum() { + int s = 0; + for (int v : intA) { s += v; } + return s; + } + + public static short shortSum() { + short s = 0; + for (short v : shortA) { s += v; } + return s; + } + + public static byte byteSum() { + byte s = 0; + for (byte v : byteA) { s += v; } + return s; + } + + static void test_001() { + // long seems not yet supported + int i = 6; + long arr[] = new long[22]; + do { + arr[i] = 1; + try { + arr[i] = arr[i]; + } catch (Exception e) { + } + } while (++i < 20); + longA = arr; + } + + static void test_002() { + // jint_fill + int i = 6; + int arr[] = new int[22]; + do { + arr[i] = 1; + try { + arr[i] = arr[i]; + } catch (Exception e) { + } + } while (++i < 20); + intA = arr; + } + + static void test_003() { + // jshort_fill + int i = 6; + short arr[] = new short[22]; + do { + // first block of loop: copied before loop, and onto backedge -> store on backedge + arr[i] = 1; + // second block of loop + try { + arr[i] = arr[i]; + } catch (Exception e) { + } + } while (++i < 20); + shortA = arr; + } + + static void test_004() { + // jbyte_fill + int i = 6; + byte arr[] = new byte[22]; + do { + arr[i] = 1; + try { + arr[i] = arr[i]; + } catch (Exception e) { + } + } while (++i < 20); + byteA = arr; + } + + static void test_005() { + // Note: currently unrolled, not intrinsified (unless -XX:LoopUnrollLimit=1) + int arr[] = new int[22]; + for (int i = 6; i < 20; i++) { + arr[i] = 1; + } + intA = arr; + } + + static void test_006() { + // Note: currently unrolled, not intrinsified (unless -XX:LoopUnrollLimit=1) + // Load in normal body, because not moved to backedge during parsing. + int i = 6; + int arr[] = new int[22]; + do { + arr[i] = 1; + } while (++i < 20); + intA = arr; + } + + static void test_007() { + int i = 6; + int arr[] = new int[22]; + do { + // still not on backedge [7,20) partial peel + arr[i] = 1; + try { int x = arr[i]; } catch (Exception e) {} + } while (++i < 20); + intA = arr; + } + + static void test_008(Data data) { + // Because of conditional in loop, at first not intrinsified, and also not unrolled. + // After unswitching both loops are intrinsified. + // I stole this idea from TestOptimizeFillWithStripMinedLoop.java + int i = 6; + int arr[] = new int[22]; + do { + arr[i] = (data == null) ? 1 : data.intValue; + } while (++i < 20); + intA = arr; + } + + static void test_009() { + // Cast to int leads to "missing use of index", not intrinsified + int arr[] = new int[22]; + for (long i = 6; i < 20; i++) { + arr[(int)i] = 1; + } + intA = arr; + } + + + public static void main(String[] strArr) { + test_001(); + Asserts.assertEQ(longSum(), (long)14); + test_002(); + Asserts.assertEQ(intSum(), 14); + test_003(); + Asserts.assertEQ(shortSum(), (short)14); + test_004(); + Asserts.assertEQ(byteSum(), (byte)14); + test_005(); + Asserts.assertEQ(intSum(), 14); + test_006(); + Asserts.assertEQ(intSum(), 14); + test_007(); + Asserts.assertEQ(intSum(), 14); + test_008(new Data(1)); + Asserts.assertEQ(intSum(), 14); + test_008(null); + Asserts.assertEQ(intSum(), 14); + test_009(); + Asserts.assertEQ(intSum(), 14); + TestBackedgeLoadArrayFill t = new TestBackedgeLoadArrayFill(); + t.test_101(); + Asserts.assertEQ(intSum(), 15); + t.test_102(); + Asserts.assertEQ(intSum(), 16); + t.test_103(); + Asserts.assertEQ(intSum(), 14); + t.test_104(); + Asserts.assertEQ(intSum(), 12); + } +} + diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedges.jasm openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedges.jasm --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedges.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedges.jasm 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,200 @@ +/* + * Copyright (c) 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. + */ + +super public class TestInfiniteLoopWithUnmergedBackedges +{ + public Method "":"()V" + stack 2 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + static Method test_001:"(IIIII)V" + stack 5 locals 10 + { + iload_0; + ifgt LOOP; + // below is dominated by the one above + iload_0; + ifle BACK; + goto HEAD; + HEAD: + iload_3; + ifeq BACK; + BACK: + goto HEAD; + LOOP: + iload_1; + iflt LOOP; + iload_2; + iflt LOOP; + return; + } + static Method test_002:"(IIIII)V" + stack 5 locals 30 + { + iload_0; + ifgt LOOP; + + iconst_0; + istore 9; + + goto HEAD; + TAIL: + iload_3; + iload 9; + if_icmpeq HEAD; + iinc 9, 1; + HEAD: + goto TAIL; + LOOP: + iload_1; + iflt LOOP; + iload_2; + iflt LOOP; + return; + } + static Method test_003:"(IIIII)I" + stack 5 locals 30 + { + iload_0; + ifgt SKIP; + + iconst_0; + istore 9; + + goto HEAD; + TAIL: + iload_3; + iload 9; + if_icmpeq HEAD; + iinc 9, 1; + // Two paths lead to HEAD, so we have an inner and outer loop + // But no SafePoint is placed here, because we go forward in bci + HEAD: + // SafePoint is placed here, because we go from here back in bci + goto TAIL; + + SKIP: + iconst_0; + istore 8; + iconst_0; + istore 9; + // loop with two backedges, which calls + // merge_many_backedges and then recomputes + // build_loop_tree + LOOP: + iinc 9, 1; + iinc 8, -1; + iload 9; + ldc 7; + irem; + ifeq LOOP; + iload 9; + ldc 10001; + if_icmple LOOP; + iload 8; + ireturn; + } + static Method test_004:"(IIIII)I" + stack 5 locals 30 + { + iload_0; + ifgt SKIP; + + iconst_0; + istore 9; + + goto HEAD; + TAIL: + iload_3; + iload 9; + if_icmpeq HEAD; + iinc 9, 1; + iload 9; + ldc 10001; + if_icmpeq HEAD; // a second one + iinc 9, 1; + HEAD: + goto TAIL; + + SKIP: + iconst_0; + istore 8; + iconst_0; + istore 9; + LOOP: + iinc 9, 1; + iinc 8, -1; + iload 9; + ldc 7; + irem; + ifeq LOOP; + iload 9; + ldc 10001; + if_icmple LOOP; + iload 8; + ireturn; + } + static Method test_005:"(IIIII)I" + stack 5 locals 30 + { + iload_0; + ifgt SKIP; + + iconst_0; + istore 9; + + goto HEAD; + TAIL: + iload_3; + iload 9; + if_icmpeq HEAD; + iinc 9, 1; + iload 9; + ldc 10001; + if_icmpeq HEAD; // a second one + iinc 9, 1; + HEAD: + goto TAIL; + + SKIP: + iconst_0; + istore 8; + iconst_0; + istore 9; + LOOP: + iinc 9, 1; + iinc 8, -1; + iload 9; + ldc 7; + irem; + ifeq LOOP; + iload 9; + ldc 10001; + if_icmple LOOP; + iload 8; + ireturn; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 8296412 + * @compile TestInfiniteLoopWithUnmergedBackedges.jasm + * @summary Infinite loops may not have the backedges merged, before we call IdealLoopTree::check_safepts + * @run main/othervm -Xcomp -XX:-TieredCompilation -XX:-LoopUnswitching + * -XX:CompileCommand=compileonly,TestInfiniteLoopWithUnmergedBackedges::test* + * TestInfiniteLoopWithUnmergedBackedgesMain + */ + +public class TestInfiniteLoopWithUnmergedBackedgesMain { + public static void main (String[] args) { + TestInfiniteLoopWithUnmergedBackedges.test_001(1, 0, 0, 0, 0); + TestInfiniteLoopWithUnmergedBackedges.test_002(1, 0, 0, 0, 0); + TestInfiniteLoopWithUnmergedBackedges.test_003(1, 0, 0, 0, 0); + TestInfiniteLoopWithUnmergedBackedges.test_004(1, 0, 0, 0, 0); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestMissingSkeletonPredicateForIfNode.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestMissingSkeletonPredicateForIfNode.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestMissingSkeletonPredicateForIfNode.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestMissingSkeletonPredicateForIfNode.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 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 8297951 - * @summary Test that crashes because we do not emit skeleton predicates for normal If nodes for which a range check - * predicate is created in loop predication. - * @requires vm.debug == true & vm.compiler2.enabled - * @run main/othervm -XX:-TieredCompilation -Xbatch -XX:-RangeCheckElimination -XX:+BailoutToInterpreterForThrows - compiler.loopopts.TestMissingSkeletonPredicateForIfNode - */ -package compiler.loopopts; - -public class TestMissingSkeletonPredicateForIfNode { - static int iFld = 2, x; - static short limit = 10; - - public static void main(String[] args) throws Exception { - for (int i = 0; i < 5000; i++) { - try { - test(i % 2 == 0, i % 3); - } catch (Exception e) { - // Expected - } - } - } - - public static void test(boolean flag, int arg) throws Exception { - int sum = 1; - int[] iArr2 = new int[4]; - RuntimeException r = new RuntimeException(); - - for (int i = 0; i < limit; i+=2) { // Pre/main/post + Unrolled once. This results in the following type for the iv phi i: [2..SHORT_MAX] - x = 5 / sum; - if (Integer.compareUnsigned(i, iArr2.length) < 0) { // (**) Loop predication creates a RC predicate for this check - // After unrolling, we have: - // - // iArr2[i] - // iArr2[i+2] - // - // The type of iArr2[i+2] is [4..SHORT_MAX+2] (we need limit to be short such that we do not have an integer overflow - // which would set the type to int). However, the type of the CastII node for the index i+2 is [0..3] because its size - // is only 4. Since the type of i+2 is outside the range of the CastII node, the CastII node is replaced by top and - // some of the data nodes and memory nodes die. We are left with a broken graph and later assert because of that. - iFld += iArr2[i]; // RangeCheck node is removed because it shares the same bool as the If (**). - sum += iFld; - } else { - // Emits an UCT with -XX:+BailoutToInterpreterForThrows and therefore the If (**) satisfies the condition of being a - // range check if with one of its blocks being an UCT. - throw r; - } - if (i > 50) { - break; - } - } - } -} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestUndetectedLoopInInfiniteLoop.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestUndetectedLoopInInfiniteLoop.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestUndetectedLoopInInfiniteLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestUndetectedLoopInInfiniteLoop.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 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 8296318 + * @summary Loops inside infinite loops may not be detected, thus a region may still + * be the loop head, even if it is not a LoopNode. + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,TestUndetectedLoopInInfiniteLoop::test* + * -XX:PerMethodTrapLimit=0 + * TestUndetectedLoopInInfiniteLoop + */ + + +public class TestUndetectedLoopInInfiniteLoop { + public static void main (String[] args) { + test(true, false); + } + public static void test(boolean flag, boolean flag2) { + int x = 0; + if (flag2) { // runtime check, avoid infinite loop + while (true) { // infinite loop (no exit) + if (flag) { + x++; + } + do { // inner loop + // assert for this block + // Region + // Phi -> SubI -> XorI ---> Phi + x = (x - 1) ^ 1; + // Problem: this looks like a loop, but we have no LoopNode + // We have no LoopNode, because this is all in an infinite + // loop, and during PhaseIdealLoop::build_loop_tree we do not + // attach the loops of an infinite loop to the loop tree, + // and hence we do not get to call beautify_loop on these loops + // which would have turned the Region into a LoopNode. + } while (x < 0); + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestWrongCMovSplitIf.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestWrongCMovSplitIf.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopopts/TestWrongCMovSplitIf.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopopts/TestWrongCMovSplitIf.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * 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 8303564 + * @summary C2: "Bad graph detected in build_loop_late" after a CMove is wrongly split thru phi + * @run main/othervm -XX:-BackgroundCompilation TestWrongCMovSplitIf + */ + +public class TestWrongCMovSplitIf { + private static int[] field1 = new int[1]; + private static int field3; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(true); + test(false); + testHelper(1000, false); + } + } + + private static void test(boolean flag) { + int i; + for (i = 0; i < 2; i++) { + for (int j = 0; j < 10; j++) { + for (int k = 0; k < 10; k++) { + + } + } + } + field3 = testHelper(i, flag); + for (int j = 0; j < 10; j++) { + for (int k = 0; k < 10; k++) { + for (int l = 0; l < 10; l++) { + for (int m = 0; m < 10; m++) { + + } + + } + } + } + } + + private static int testHelper(int i, boolean flag) { + int stop = 1000; + if (i == 2) { + if (flag) { + stop = 2; + } else { + stop = 1; + } + } + int f = 0; + for (int j = 0; j < stop; j++) { + f += field1[0]; + } + return f; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * 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 8303511 + * @summary C2: assert(get_ctrl(n) == cle_out) during unrolling + * @requires vm.gc.Parallel + * @run main/othervm -XX:-BackgroundCompilation -XX:+UseParallelGC TestAddPAtOuterLoopHead + */ + + +import java.util.Arrays; + +public class TestAddPAtOuterLoopHead { + public static void main(String[] args) { + boolean[] flags1 = new boolean[1000]; + boolean[] flags2 = new boolean[1000]; + Arrays.fill(flags2, true); + for (int i = 0; i < 20_000; i++) { + testHelper(42, 42, 43); + test(flags1); + test(flags2); + } + } + + private static int test(boolean[] flags) { + int[] array = new int[1000]; + + int k; + for (k = 0; k < 10; k++) { + for (int i = 0; i < 2; i++) { + } + } + k = k / 10; + int m; + for (m = 0; m < 2; m++) { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + } + } + } + + + int v = 0; + for (int j = 0; j < 2; j++) { + for (int i = 0; i < 998; i += k) { + int l = testHelper(m, j, i); + v = array[i + l]; + if (flags[i]) { + return v; + } + } + } + + return v; + } + + private static int testHelper(int m, int j, int i) { + return m == 2 ? j : i; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * 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 8299959 + * @summary In CmpU::Value, the sub computation may be narrower than the overflow computation. + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+StressCCP -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.rangechecks.TestRangeCheckCmpUOverflowVsSub::test + * -XX:RepeatCompilation=50 + * compiler.rangechecks.TestRangeCheckCmpUOverflowVsSub +*/ + +package compiler.rangechecks; + +public class TestRangeCheckCmpUOverflowVsSub { + static int arr[] = new int[400]; + + public static void main(String[] strArr) { + for (int i = 0; i < 10; i++) { + test(); // repeat for multiple compilations + } + } + + static void test() { + for(int i = 0; i < 50_000; i++) {} //empty loop - trigger OSR faster + int val; + int zero = arr[5]; + int i = 1; + do { + for (int j = 1; j < 3; j++) { + for (int k = 2; k > i; k -= 3) { + try { + val = arr[i + 1] % k; + val = arr[i - 1] % zero; + val = arr[k - 1]; + } catch (ArithmeticException e) {} // catch div by zero + } + } + } while (++i < 3); + } +} + diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/splitif/TestSplitDivisionThroughPhi.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/splitif/TestSplitDivisionThroughPhi.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/splitif/TestSplitDivisionThroughPhi.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/splitif/TestSplitDivisionThroughPhi.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,160 @@ +/* + * 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 +* @key stress randomness +* @bug 8299259 +* @requires vm.compiler2.enabled +* @summary Test various cases of divisions/modulo which should not be split through iv phis. +* @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:LoopUnrollLimit=0 -XX:+StressGCM -XX:StressSeed=884154126 +* -XX:CompileCommand=compileonly,compiler.splitif.TestSplitDivisionThroughPhi::* +* compiler.splitif.TestSplitDivisionThroughPhi +*/ + +/** +* @test +* @key stress randomness +* @bug 8299259 +* @requires vm.compiler2.enabled +* @summary Test various cases of divisions/modulo which should not be split through iv phis. +* @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:LoopUnrollLimit=0 -XX:+StressGCM +* -XX:CompileCommand=compileonly,compiler.splitif.TestSplitDivisionThroughPhi::* +* compiler.splitif.TestSplitDivisionThroughPhi +*/ + +package compiler.splitif; + +public class TestSplitDivisionThroughPhi { + static int iFld; + static long lFld; + static boolean flag; + + + public static void main(String[] strArr) { + for (int i = 0; i < 5000; i++) { + testPushDivIThruPhi(); + testPushDivIThruPhiInChain(); + testPushModIThruPhi(); + testPushModIThruPhiInChain(); + testPushDivLThruPhi(); + testPushDivLThruPhiInChain(); + testPushModLThruPhi(); + testPushModLThruPhiInChain(); + } + } + + // Already fixed by JDK-8248552. + static void testPushDivIThruPhi() { + for (int i = 10; i > 1; i -= 2) { + // The Div node is only split in later loop opts phase because the zero divisor check is only removed + // in IGVN after the first loop opts phase. + // + // iv phi i type: [2..10] + // When splitting the DivI through the iv phi, it ends up on the back edge with the trip count decrement + // as input which has type [0..8]. We end up executing a division by zero on the last iteration because + // the DivI it is not pinned to the loop exit test and can freely float above the loop exit check. + iFld = 10 / i; + } + } + + // Same as above but with an additional Mul node between the iv phi and the Div node. Both nodes are split through + // the iv phi in one pass of Split If. + static void testPushDivIThruPhiInChain() { + for (int i = 10; i > 1; i -= 2) { + // Empty one iteration loop which is only removed after split if in first loop opts phase. This prevents + // that the Mul node is already split through the iv phi while the Div node cannot be split yet due to + // the zero divisor check which can only be removed in the IGVN after the first loop opts pass. + for (int j = 0; j < 1; j++) { + } + iFld = 10 / (i * 100); + } + } + + // Already fixed by JDK-8248552. + static void testPushModIThruPhi() { + for (int i = 10; i > 1; i -= 2) { + iFld = 10 / i; + } + } + + // Same as above but with ModI. + static void testPushModIThruPhiInChain() { + for (int i = 10; i > 1; i -= 2) { + for (int j = 0; j < 1; j++) { + } + iFld = 10 / (i * 100); + } + } + + // Long cases only trigger since JDK-8256655. + + // Same as above but with DivL. + static void testPushDivLThruPhi() { + for (long i = 10; i > 1; i -= 2) { + lFld = 10L / i; + + // Loop that is not removed such that we do not transform the outer LongCountedLoop (only done if innermost) + for (int j = 0; j < 10; j++) { + flag = !flag; + } + } + } + + // Same as above but with DivL. + static void testPushDivLThruPhiInChain() { + for (long i = 10; i > 1; i -= 2) { + for (int j = 0; j < 1; j++) { + } + lFld = 10L / (i * 100L); + + for (int j = 0; j < 10; j++) { + flag = !flag; + } + } + } + + // Same as above but with ModL + static void testPushModLThruPhi() { + for (long i = 10; i > 1; i -= 2) { + lFld = 10L % i; + + for (int j = 0; j < 10; j++) { + flag = !flag; + } + } + } + + // Same as above but with ModL + static void testPushModLThruPhiInChain() { + for (long i = 10; i > 1; i -= 2) { + for (int j = 0; j < 1; j++) { + } + lFld = 10L % (i * 100L); + + for (int j = 0; j < 10; j++) { + flag = !flag; + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestBoolean { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static boolean static_v; boolean v; @@ -211,6 +228,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBooleanPlain(base, offset, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = UNSAFE.getBoolean(base, offset); @@ -228,6 +246,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBooleanAcquire(base, offset, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = UNSAFE.getBoolean(base, offset); @@ -245,6 +264,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBooleanRelease(base, offset, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = UNSAFE.getBoolean(base, offset); @@ -262,6 +282,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBoolean(base, offset, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = UNSAFE.getBoolean(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestByte { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static byte static_v; byte v; @@ -240,6 +257,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBytePlain(base, offset, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = UNSAFE.getByte(base, offset); @@ -257,6 +275,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetByteAcquire(base, offset, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = UNSAFE.getByte(base, offset); @@ -274,6 +293,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetByteRelease(base, offset, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = UNSAFE.getByte(base, offset); @@ -291,6 +311,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetByte(base, offset, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = UNSAFE.getByte(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestChar { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static char static_v; char v; @@ -258,6 +275,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetCharPlain(base, offset, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = UNSAFE.getChar(base, offset); @@ -275,6 +293,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetCharAcquire(base, offset, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = UNSAFE.getChar(base, offset); @@ -292,6 +311,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetCharRelease(base, offset, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = UNSAFE.getChar(base, offset); @@ -309,6 +329,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetChar(base, offset, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet char"); char x = UNSAFE.getChar(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestDouble { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static double static_v; double v; @@ -240,6 +257,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDoublePlain(base, offset, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = UNSAFE.getDouble(base, offset); @@ -257,6 +275,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDoubleAcquire(base, offset, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = UNSAFE.getDouble(base, offset); @@ -274,6 +293,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDoubleRelease(base, offset, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = UNSAFE.getDouble(base, offset); @@ -291,6 +311,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDouble(base, offset, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = UNSAFE.getDouble(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestFloat { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static float static_v; float v; @@ -240,6 +257,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloatPlain(base, offset, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = UNSAFE.getFloat(base, offset); @@ -257,6 +275,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloatAcquire(base, offset, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = UNSAFE.getFloat(base, offset); @@ -274,6 +293,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloatRelease(base, offset, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = UNSAFE.getFloat(base, offset); @@ -291,6 +311,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloat(base, offset, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = UNSAFE.getFloat(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestInt { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static int static_v; int v; @@ -258,6 +275,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetIntPlain(base, offset, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = UNSAFE.getInt(base, offset); @@ -275,6 +293,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetIntAcquire(base, offset, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = UNSAFE.getInt(base, offset); @@ -292,6 +311,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetIntRelease(base, offset, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = UNSAFE.getInt(base, offset); @@ -309,6 +329,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetInt(base, offset, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = UNSAFE.getInt(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestLong { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static long static_v; long v; @@ -258,6 +275,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLongPlain(base, offset, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = UNSAFE.getLong(base, offset); @@ -275,6 +293,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLongAcquire(base, offset, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = UNSAFE.getLong(base, offset); @@ -292,6 +311,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLongRelease(base, offset, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = UNSAFE.getLong(base, offset); @@ -309,6 +329,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLong(base, offset, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = UNSAFE.getLong(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestObject { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static Object static_v; Object v; @@ -211,6 +228,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetReferencePlain(base, offset, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain Object"); Object x = UNSAFE.getReference(base, offset); @@ -228,6 +246,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetReferenceAcquire(base, offset, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire Object"); Object x = UNSAFE.getReference(base, offset); @@ -245,6 +264,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetReferenceRelease(base, offset, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease Object"); Object x = UNSAFE.getReference(base, offset); @@ -262,6 +282,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetReference(base, offset, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet Object"); Object x = UNSAFE.getReference(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class JdkInternalMiscUnsafeAccessTestShort { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final jdk.internal.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static short static_v; short v; @@ -258,6 +275,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShortPlain(base, offset, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = UNSAFE.getShort(base, offset); @@ -275,6 +293,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShortAcquire(base, offset, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = UNSAFE.getShort(base, offset); @@ -292,6 +311,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShortRelease(base, offset, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = UNSAFE.getShort(base, offset); @@ -309,6 +329,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShort(base, offset, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet short"); short x = UNSAFE.getShort(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestBoolean { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static boolean static_v; boolean v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestByte { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static byte static_v; byte v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestChar { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static char static_v; char v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestDouble { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static double static_v; double v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestFloat { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static float static_v; float v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestInt { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static int static_v; int v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestLong { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static long static_v; long v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestObject { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static Object static_v; Object v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java 2023-07-05 07:11:54.000000000 +0000 @@ -43,7 +43,14 @@ public class SunMiscUnsafeAccessTestShort { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final sun.misc.Unsafe UNSAFE; @@ -86,6 +93,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static short static_v; short v; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -47,7 +47,14 @@ public class $Qualifier$UnsafeAccessTest$Type$ { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); static final $package$.Unsafe UNSAFE; @@ -90,6 +97,16 @@ ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); } + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } + static $type$ static_v; $type$ v; @@ -302,6 +319,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$MethodAffix$Plain(base, offset, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = UNSAFE.get$MethodAffix$(base, offset); @@ -319,6 +337,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$MethodAffix$Acquire(base, offset, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = UNSAFE.get$MethodAffix$(base, offset); @@ -336,6 +355,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$MethodAffix$Release(base, offset, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = UNSAFE.get$MethodAffix$(base, offset); @@ -353,6 +373,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$MethodAffix$(base, offset, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = UNSAFE.get$MethodAffix$(base, offset); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/vectorapi/Test8303508.java openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/vectorapi/Test8303508.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/compiler/vectorapi/Test8303508.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/compiler/vectorapi/Test8303508.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * 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.vectorapi; + +import jdk.incubator.vector.ByteVector; +import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.VectorSpecies; + +/* + * @test + * @bug 8303508 + * @summary Vector.lane() gets wrong value on x86 + * @modules jdk.incubator.vector + * @library /test/lib + * + * @run main/othervm -Xbatch -XX:-TieredCompilation -ea compiler.vectorapi.Test8303508 + */ +public class Test8303508 { + + static final VectorSpecies BSPECIES_128 = ByteVector.SPECIES_128; + static final VectorSpecies SSPECIES_128 = ShortVector.SPECIES_128; + + static final byte[] ba = {0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}; + static final short[] sa = {0, -1, -2, -3, -4, -5, -6, -7}; + + private static byte vec_extract_byte(int idx) { + var bv = ByteVector.fromArray(BSPECIES_128, ba, 0); + return bv.lane(idx); + } + + private static short vec_extract_short(int idx) { + var sv = ShortVector.fromArray(SSPECIES_128, sa, 0); + return sv.lane(idx); + } + + public static void main(String[] args) { + int idx = 0; + int actual = 0; + int expected = 0; + for (int i = 0; i < 10000; i++) { + idx = i & 0xF; + actual = vec_extract_byte(idx); + expected = ba[idx]; + if (actual != expected) { + throw new AssertionError("incorrect result byte extraction, actual = " + actual + " expected = " + expected); + } + idx = i & 0x7; + actual = vec_extract_short(idx); + expected = sa[idx]; + if (actual != expected) { + throw new AssertionError("incorrect result short extraction, actual = " + actual + " expected = " + expected); + } + } + System.out.println("PASS"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java openjdk-17-17.0.8+7/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java 2023-07-05 07:11:54.000000000 +0000 @@ -115,6 +115,12 @@ static volatile Object sink; + private static boolean isExpectedPauseAction(String action) { + return "Init Mark".equals(action) || "Final Mark".equals(action) || "Full GC".equals(action) + || "Degenerated GC".equals(action) || "Init Update Refs".equals(action) + || "Final Update Refs".equals(action) || "Final Roots".equals(action); + } + public static void main(String[] args) throws Exception { final long startTime = System.currentTimeMillis(); @@ -129,7 +135,8 @@ if (n.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) n.getUserData()); - System.out.println("Received: " + info.getGcName()); + System.out.println("Received: " + info.getGcName() + "/" + info.getGcAction()); + long d = info.getGcInfo().getDuration(); @@ -138,6 +145,9 @@ if (name.equals("Shenandoah Pauses")) { pausesCount.incrementAndGet(); pausesDuration.addAndGet(d); + if (!isExpectedPauseAction(info.getGcAction())) { + throw new IllegalStateException("Unknown action: " + info.getGcAction()); + } } else if (name.equals("Shenandoah Cycles")) { cyclesCount.incrementAndGet(); cyclesDuration.addAndGet(d); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/ProblemList.txt openjdk-17-17.0.8+7/test/hotspot/jtreg/ProblemList.txt --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/ProblemList.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/ProblemList.txt 2023-07-05 07:11:54.000000000 +0000 @@ -113,7 +113,6 @@ serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatArrayCorrectnessTest.java 8224150 generic-all serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java 8225354 windows-all serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64 -serviceability/jvmti/CompiledMethodLoad/Zombie.java 8245877 linux-aarch64 serviceability/sa/ClhsdbCDSCore.java 8294316,8269982,8267433 macosx-aarch64,macosx-x64 serviceability/sa/ClhsdbFindPC.java#id1 8294316,8269982,8267433 macosx-aarch64,macosx-x64 diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. and/or its affiliates. + * 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 @@ -25,6 +26,9 @@ import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.regex.Pattern; import jdk.test.lib.process.OutputAnalyzer; @@ -32,7 +36,7 @@ import jdk.test.lib.process.ProcessTools; /* - * @test + * @test id=default * @bug 8166944 * @summary Hanging Error Reporting steps may lead to torn error logs * @modules java.base/jdk.internal.misc @@ -42,6 +46,16 @@ * @author Thomas Stuefe (SAP) */ +/* + * @test id=with-on-error + * @bug 8303861 + * @summary Error handling step timeouts should never be blocked by OnError etc. + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @requires (vm.debug == true) & (os.family != "windows") + * @run driver TimeoutInErrorHandlingTest with-on-error + */ + public class TimeoutInErrorHandlingTest { public static final boolean verbose = System.getProperty("verbose") != null; @@ -70,14 +84,28 @@ * little timeout messages to see that repeated timeout handling is basically working. */ - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", - "-Xmx100M", - "-XX:ErrorHandlerTest=14", - "-XX:+TestUnresponsiveErrorHandler", - "-XX:ErrorLogTimeout=" + ERROR_LOG_TIMEOUT, - "-XX:-CreateCoredumpOnCrash", - "-version"); + boolean withOnError = false; + + if (args.length > 0) { + switch (args[0]) { + case "with-on-error": withOnError = true; break; + default: throw new RuntimeException("Invalid argument " + args[1]); + } + } + + List arguments = new ArrayList<>(); + Collections.addAll(arguments, + "-XX:+UnlockDiagnosticVMOptions", + "-Xmx100M", + "-XX:ErrorHandlerTest=14", + "-XX:+TestUnresponsiveErrorHandler", + "-XX:ErrorLogTimeout=" + ERROR_LOG_TIMEOUT, + "-XX:-CreateCoredumpOnCrash"); + if (withOnError) { + arguments.add("-XX:OnError=echo hi"); + } + arguments.add("-version"); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(arguments); OutputAnalyzer output_detail = new OutputAnalyzer(pb.start()); @@ -91,8 +119,10 @@ output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*"); output_detail.shouldMatch("# +(?:SIGSEGV|SIGBUS|EXCEPTION_ACCESS_VIOLATION).*"); - // VM should have been aborted by WatcherThread - output_detail.shouldMatch(".*timer expired, abort.*"); + // Unless we specified OnError, VM should have been aborted by WatcherThread + if (!withOnError) { + output_detail.shouldMatch(".*timer expired, abort.*"); + } // extract hs-err file String hs_err_file = output_detail.firstMatch("# *(\\S*hs_err_pid\\d+\\.log)", 1); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 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. + */ + +#include +#include + +#include +#include + +#include "jni.h" + +JavaVM* jvm; +jboolean warning = 0; + +void generateWarning(JNIEnv *env) { + jclass class_id; + jmethodID method_id; + + printf("About to trigger JNI Warning\n"); + + // Just call Thread.currentThread() twice in succession without checking + // for an exception in between. + + class_id = (*env)->FindClass (env, "java/lang/Thread"); + if (class_id == NULL) { + fprintf(stderr, "Test ERROR. Can't load class Thread\n"); + exit(1); + } + + method_id = (*env)->GetStaticMethodID(env, class_id, "currentThread", + "()Ljava/lang/Thread;"); + if (method_id == NULL) { + fprintf(stderr, "Test ERROR. Can't find method currentThread\n"); + exit(1); + } + + jobject nativeThread = (*env)->CallStaticObjectMethod(env, class_id, method_id, NULL); + nativeThread = (*env)->CallStaticObjectMethod(env, class_id, method_id, NULL); +} + +void generateError(JNIEnv *env) { + printf("About to trigger JNI FatalError\n"); + (*env)->FatalError(env, "Fatal error generated in test code"); +} + +static void * thread_start(void* unused) { + JNIEnv *env; + int res; + + printf("Native thread is running and attaching as daemon ...\n"); + + res = (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&env, NULL); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't attach current thread: %d\n", res); + exit(1); + } + + if (warning != 0) { + generateWarning(env); + } else { + generateError(env); + } + + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + exit(1); + } + printf("Native thread terminating\n"); + + return NULL; +} + +JNIEXPORT void JNICALL +Java_TestNativeStack_triggerJNIStackTrace +(JNIEnv *env, jclass cls, jboolean warn) { + pthread_t thread; + int res = (*env)->GetJavaVM(env, &jvm); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't extract JavaVM: %d\n", res); + exit(1); + } + + warning = warn; + + if ((res = pthread_create(&thread, NULL, thread_start, NULL)) != 0) { + fprintf(stderr, "TEST ERROR: pthread_create failed: %s (%d)\n", strerror(res), res); + exit(1); + } + + if ((res = pthread_join(thread, NULL)) != 0) { + fprintf(stderr, "TEST ERROR: pthread_join failed: %s (%d)\n", strerror(res), res); + exit(1); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 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 8295974 + * @requires os.family != "windows" + * @library /test/lib + * @summary Generate a JNI Fatal error, or a warning, in a launched VM and check + * the native stack is present as expected. + * @comment The native code only supports POSIX so no windows testing + * @run driver TestNativeStack + */ + +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestNativeStack { + + /** + * Create a native thread that will execute native code that + * will either trigger a JNI warning (with -Xcheck:jni) or a JNI + * error, depending on the value of `warning`. + */ + static native void triggerJNIStackTrace(boolean warning); + + static { + System.loadLibrary("nativeStack"); + } + + public static void main(String[] args) throws Throwable { + // case 1: Trigger a JNI warning with Xcheck:jni + OutputAnalyzer oa = + ProcessTools.executeTestJvm("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main"); + oa.shouldHaveExitValue(0); + oa.shouldContain("WARNING in native method"); + oa.shouldContain("thread_start"); + oa.reportDiagnosticSummary(); + + // Case 2: Trigger a JNI FatalError call + oa = ProcessTools.executeTestJvm("-XX:-CreateCoredumpOnCrash", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main", + "error"); + oa.shouldNotHaveExitValue(0); + oa.shouldContain("FATAL ERROR in native method"); + oa.shouldContain("thread_start"); + oa.reportDiagnosticSummary(); + } + + static class Main { + public static void main(String[] args) throws Throwable { + boolean doWarning = args.length == 0; + System.out.println("Triggering a JNI " + + (doWarning ? "warning" : "fatal error")); + triggerJNIStackTrace(doWarning); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -40,7 +40,6 @@ output.shouldContain("[safepoint,cleanup]"); output.shouldContain("safepoint cleanup tasks"); output.shouldContain("updating inline caches"); - output.shouldContain("compilation policy safepoint handler"); output.shouldHaveExitValue(0); } diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/Monitor/DeflationIntervalsTest.java openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/Monitor/DeflationIntervalsTest.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/Monitor/DeflationIntervalsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/Monitor/DeflationIntervalsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,355 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/* + * @test id=defaults + * @bug 8305994 8306825 + * @summary Test the deflation intervals options + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest defaults + */ + +/* + * @test id=allIntervalsZero + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest allIntervalsZero + */ + +/* + * @test id=allThresholdsZero + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest allThresholdsZero + */ + +/* + * @test id=guaranteed_noThresholdMUDT_noSafepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest guaranteed_noThresholdMUDT_noSafepoint + */ + +/* + * @test id=guaranteed_noThresholdMUDT_safepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest guaranteed_noThresholdMUDT_safepoint + */ + +/* + * @test id=guaranteed_noThresholdADI_noSafepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest guaranteed_noThresholdADI_noSafepoint + */ + +/* + * @test id=guaranteed_noThresholdADI_safepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest guaranteed_noThresholdADI_safepoint + */ + +/* + * @test id=noGuaranteedGADT_threshold_noSafepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest noGuaranteedGADT_threshold_noSafepoint + */ + +/* + * @test id=noGuaranteedGADT_threshold_safepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest noGuaranteedGADT_threshold_safepoint + */ + +/* + * @test id=guaranteed_threshold_noSafepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest guaranteed_threshold_noSafepoint + */ + +/* + * @test id=guaranteed_threshold_safepoint + * @requires vm.flagless + * @library /test/lib + * @run driver DeflationIntervalsTest guaranteed_threshold_safepoint + */ + +public class DeflationIntervalsTest { + + public static class Test { + // Inflate a lot of monitors, so that threshold heuristics definitely fires + private static final int MONITORS = 10_000; + + // Use a handful of threads to inflate the monitors, to eat the cost of + // wait(1) calls. This can be larger than available parallelism, since threads + // would be time-waiting. + private static final int THREADS = 16; + + private static Thread[] threads; + private static Object[] monitors; + + public static void main(String... args) throws Exception { + monitors = new Object[MONITORS]; + threads = new Thread[THREADS]; + + for (int t = 0; t < THREADS; t++) { + int monStart = t * MONITORS / THREADS; + int monEnd = (t + 1) * MONITORS / THREADS; + threads[t] = new Thread(() -> { + for (int m = monStart; m < monEnd; m++) { + Object o = new Object(); + synchronized (o) { + try { + o.wait(1); + } catch (InterruptedException e) { + } + } + monitors[m] = o; + } + }); + threads[t].start(); + } + + for (Thread t : threads) { + t.join(); + } + + try { + Thread.sleep(10_000); + } catch (InterruptedException ie) { + } + } + } + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + throw new IllegalArgumentException("Expect the test label"); + } + + String test = args[0]; + switch (test) { + case "defaults": + // Try with all defaults + test(Disabled.NO, Guaranteed.MAYBE, Threshold.MAYBE); + break; + + case "allIntervalsZero": + // Try with all deflation intervals at zero + test(Disabled.YES, Guaranteed.NO, Threshold.NO, + "-XX:GuaranteedAsyncDeflationInterval=0", + "-XX:AsyncDeflationInterval=0", + "-XX:GuaranteedSafepointInterval=0" + ); + break; + + case "allThresholdsZero": + // Try with all heuristics thresholds at zero + test(Disabled.NO, Guaranteed.MAYBE, Threshold.NO, + "-XX:MonitorUsedDeflationThreshold=0" + ); + break; + + // Try with guaranteed interval only enabled, threshold heuristics disabled via MUDT, + // with and without guaranteed safepoints + + case "guaranteed_noThresholdMUDT_noSafepoint": + test(Disabled.NO, Guaranteed.YES, Threshold.NO, + "-XX:GuaranteedAsyncDeflationInterval=100", + "-XX:MonitorUsedDeflationThreshold=0", + "-XX:GuaranteedSafepointInterval=0" + ); + break; + + case "guaranteed_noThresholdMUDT_safepoint": + test(Disabled.NO, Guaranteed.YES, Threshold.NO, + "-XX:GuaranteedAsyncDeflationInterval=100", + "-XX:MonitorUsedDeflationThreshold=0" + ); + break; + + // Try with guaranteed interval only enabled, threshold heuristics disabled via ADI + // with and without guaranteed safepoints + + case "guaranteed_noThresholdADI_noSafepoint": + test(Disabled.NO, Guaranteed.YES, Threshold.NO, + "-XX:GuaranteedAsyncDeflationInterval=100", + "-XX:AsyncDeflationInterval=0", + "-XX:GuaranteedSafepointInterval=0" + ); + break; + + case "guaranteed_noThresholdADI_safepoint": + test(Disabled.NO, Guaranteed.YES, Threshold.NO, + "-XX:GuaranteedAsyncDeflationInterval=100", + "-XX:AsyncDeflationInterval=0" + ); + break; + + // Try with only threshold heuristics, guaranteed is disabled with GADT + // with and without guaranteed safepoints + + case "noGuaranteedGADT_threshold_noSafepoint": + test(Disabled.NO, Guaranteed.NO, Threshold.YES, + "-XX:GuaranteedAsyncDeflationInterval=0", + "-XX:MonitorUsedDeflationThreshold=1", + "-XX:GuaranteedSafepointInterval=0" + ); + break; + + case "noGuaranteedGADT_threshold_safepoint": + test(Disabled.NO, Guaranteed.NO, Threshold.YES, + "-XX:GuaranteedAsyncDeflationInterval=0", + "-XX:MonitorUsedDeflationThreshold=1" + ); + break; + + // Try with both threshold heuristics and guaranteed interval enabled + // with and without guaranteed safepoints + + case "guaranteed_threshold_noSafepoint": + test(Disabled.NO, Guaranteed.YES, Threshold.YES, + "-XX:GuaranteedAsyncDeflationInterval=5000", + "-XX:MonitorUsedDeflationThreshold=1", + "-XX:GuaranteedSafepointInterval=0" + ); + break; + + case "guaranteed_threshold_safepoint": + // Try with both threshold heuristics and guaranteed interval enabled + test(Disabled.NO, Guaranteed.YES, Threshold.YES, + "-XX:GuaranteedAsyncDeflationInterval=5000", + "-XX:MonitorUsedDeflationThreshold=1" + ); + break; + + default: + throw new IllegalArgumentException("Unknown test: " + test); + } + } + + static final String MSG_THRESHOLD = "Async deflation needed: monitors used are above the threshold"; + static final String MSG_GUARANTEED = "Async deflation needed: guaranteed interval"; + static final String MSG_DISABLED = "Async deflation is disabled"; + + public static void test(Disabled disabled, Guaranteed guaranteed, Threshold threshold, String... args) throws Exception { + List opts = new ArrayList<>(); + opts.add("-Xmx128M"); + opts.add("-XX:+UnlockDiagnosticVMOptions"); + opts.add("-Xlog:monitorinflation=info"); + opts.addAll(Arrays.asList(args)); + opts.add("DeflationIntervalsTest$Test"); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(opts); + OutputAnalyzer oa = new OutputAnalyzer(pb.start()); + oa.shouldHaveExitValue(0); + + switch (disabled) { + case YES: oa.shouldContain(MSG_DISABLED); break; + case NO: oa.shouldNotContain(MSG_DISABLED); break; + case MAYBE: break; + } + + switch (threshold) { + case YES: oa.shouldContain(MSG_THRESHOLD); break; + case NO: oa.shouldNotContain(MSG_THRESHOLD); break; + case MAYBE: break; + } + + switch (guaranteed) { + case YES: oa.shouldContain(MSG_GUARANTEED); break; + case NO: oa.shouldNotContain(MSG_GUARANTEED); break; + case MAYBE: break; + } + + if (threshold == Threshold.YES || guaranteed == Guaranteed.YES) { + assertDeflations(oa); + } else if (threshold == Threshold.NO && guaranteed == Guaranteed.NO) { + assertNoDeflations(oa); + } else { + // Don't know + } + } + + static final String MSG_FINAL_AUDIT = "Starting the final audit"; + static final String MSG_BEGIN_DEFLATING = "begin deflating"; + + private static void assertNoDeflations(OutputAnalyzer oa) { + for (String line : oa.asLines()) { + if (line.contains(MSG_FINAL_AUDIT)) { + // Final deflations started, with no prior deflations, good. + return; + } + if (line.contains(MSG_BEGIN_DEFLATING)) { + // Deflations detected before final ones, bad + oa.reportDiagnosticSummary(); + throw new IllegalStateException("FAILED"); + } + } + } + + private static void assertDeflations(OutputAnalyzer oa) { + for (String line : oa.asLines()) { + if (line.contains(MSG_FINAL_AUDIT)) { + // Final deflations started, with no prior deflations, bad. + oa.reportDiagnosticSummary(); + throw new IllegalStateException("FAILED"); + } + if (line.contains(MSG_BEGIN_DEFLATING)) { + // Deflations detected before final ones, good + return; + } + } + } + + enum Disabled { + YES, + NO, + MAYBE, + } + + enum Threshold { + YES, + NO, + MAYBE, + } + + enum Guaranteed { + YES, + NO, + MAYBE, + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/Thread/StopAtExit.java openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/Thread/StopAtExit.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/runtime/Thread/StopAtExit.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/runtime/Thread/StopAtExit.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,11 +23,13 @@ /** * @test - * @bug 8167108 8266130 + * @bug 8167108 8266130 8282704 * @summary Stress test java.lang.Thread.stop() at thread exit. + * @modules java.base/java.lang:open * @run main/othervm StopAtExit */ +import java.lang.reflect.Method; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -38,6 +40,10 @@ public CountDownLatch exitSyncObj = new CountDownLatch(1); public CountDownLatch startSyncObj = new CountDownLatch(1); + public StopAtExit(ThreadGroup group, Runnable target) { + super(group, target); + } + @Override public void run() { try { @@ -72,11 +78,18 @@ System.out.println("About to execute for " + timeMax + " seconds."); long count = 0; + long manualDestroyCnt = 0; + long manualTerminateCnt = 0; long start_time = System.currentTimeMillis(); while (System.currentTimeMillis() < start_time + (timeMax * 1000)) { count++; - StopAtExit thread = new StopAtExit(); + // Use my own ThreadGroup so the thread count is known and make + // it a daemon ThreadGroup so it is automatically destroyed when + // the thread is terminated. + ThreadGroup myTG = new ThreadGroup("myTG-" + count); + myTG.setDaemon(true); + StopAtExit thread = new StopAtExit(myTG, null); thread.start(); try { // Wait for the worker thread to get going. @@ -107,9 +120,52 @@ } catch (InterruptedException e) { throw new Error("Unexpected: " + e); } + // This stop() call happens after the join() so it should do + // nothing, but let's make sure. thread.stop(); + + if (myTG.activeCount() != 0) { + // If the ThreadGroup still has a count, then the thread + // received the async exception while in exit() so we need + // to do a manual terminate. + manualTerminateCnt++; + try { + threadTerminated(myTG, thread); + } catch (Exception e) { + throw new Error("threadTerminated() threw unexpected: " + e); + } + int activeCount = myTG.activeCount(); + if (activeCount != 0) { + throw new Error("threadTerminated() did not clean up " + + "worker thread: count=" + activeCount); + } + if (!myTG.isDestroyed()) { + throw new Error("threadTerminated() did not destroy " + + myTG.getName()); + } + } else if (!myTG.isDestroyed()) { + // If the ThreadGroup does not have a count, but is not + // yet destroyed, then the thread received the async + // exception while the thread was in the later stages of + // its threadTerminated() call so we need to do a manual + // destroy. + manualDestroyCnt++; + try { + myTG.destroy(); + } catch (Exception e) { + throw new Error("myTG.destroy() threw unexpected: " + e); + } + } } + if (manualDestroyCnt != 0) { + System.out.println("Manually destroyed ThreadGroup " + + manualDestroyCnt + " times."); + } + if (manualTerminateCnt != 0) { + System.out.println("Manually terminated Thread " + + manualTerminateCnt + " times."); + } System.out.println("Executed " + count + " loops in " + timeMax + " seconds."); @@ -120,6 +176,13 @@ } } + static void threadTerminated(ThreadGroup group, Thread thread) throws Exception { + // ThreadGroup.threadTerminated() is package private: + Method method = ThreadGroup.class.getDeclaredMethod("threadTerminated", Thread.class); + method.setAccessible(true); + method.invoke(group, thread); + } + public static void usage() { System.err.println("Usage: " + PROG_NAME + " [time_max]"); System.err.println("where:"); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/libAsyncGetCallTraceTest.cpp openjdk-17-17.0.8+7/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/libAsyncGetCallTraceTest.cpp --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/libAsyncGetCallTraceTest.cpp 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/libAsyncGetCallTraceTest.cpp 2023-07-05 07:11:54.000000000 +0000 @@ -230,7 +230,40 @@ return false; } - return strcmp(name.get(), "checkAsyncGetCallTraceCall") == 0; + if (strcmp(name.get(), "checkAsyncGetCallTraceCall") != 0) { + fprintf(stderr, "Name is not checkAsyncGetCallTraceCall: %s\n", name.get()); + return false; + } + + // AsyncGetCallTrace and GetStackTrace should return comparable frames + // so we obtain the frames using GetStackTrace and compare them. + + jthread thread; + jvmti->GetCurrentThread(&thread); + jvmtiFrameInfo gstFrames[MAX_DEPTH]; + jint gstCount = 0; + + jvmti->GetStackTrace(thread, 0, MAX_DEPTH, gstFrames, &gstCount); + + if (gstCount != trace.num_frames) { + fprintf(stderr, "GetStackTrace and AsyncGetCallTrace return different number of frames: %d vs %d)", gstCount, trace.num_frames); + return false; + } + + for (int i = 0; i < trace.num_frames; ++i) { + if (trace.frames[i].lineno == -3) { + if (gstFrames[i].location != -1) { + fprintf(stderr, "%d: ASGCT found native frame but GST did not\n", i); + return false; + } + } else { + if (gstFrames[i].method != trace.frames[i].method_id) { + fprintf(stderr, "%d: method_id mismatch: %p vs %p\n", i, gstFrames[i].method, trace.frames[i].method_id); + return false; + } + } + } + return true; } } diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java openjdk-17-17.0.8+7/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java 2023-07-05 07:11:54.000000000 +0000 @@ -31,6 +31,7 @@ import jdk.test.lib.apps.LingeredApp; import jdk.test.lib.JDKToolLauncher; import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.SA.SATestUtils; import jtreg.SkippedException; /** @@ -47,6 +48,10 @@ static final String APP_SLASH_CLASSNAME = APP_DOT_CLASSNAME.replace('.', '/'); public static void main(String[] args) throws Exception { + if (SATestUtils.needsPrivileges()) { + // This test will create a file as root that cannot be easily deleted, so don't run it. + throw new SkippedException("Cannot run this test on OSX if adding privileges is required."); + } System.out.println("Starting ClhsdbDumpclass test"); LingeredApp theApp = null; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -335,7 +335,6 @@ log2("......setting up ThreadStartRequest"); ThreadStartRequest tsr = eventRManager.createThreadStartRequest(); - tsr.addCountFilter(1); tsr.setSuspendPolicy(EventRequest.SUSPEND_ALL); tsr.putProperty("number", "ThreadStartRequest"); tsr.enable(); @@ -344,7 +343,6 @@ log2("......setting up ThreadDeathRequest"); ThreadDeathRequest tdr = eventRManager.createThreadDeathRequest(); - tdr.addCountFilter(1); tdr.setSuspendPolicy(EventRequest.SUSPEND_ALL); tsr.putProperty("number", "ThreadDeathRequest"); tdr.enable(); @@ -527,18 +525,14 @@ log2(":::::::::vm.resume();"); vm.resume(); - Event event1 = null; - int flagsCopy = flags; - String eName = null; - int index = 0; + int flagsCopy = flags; log2("......getting and checking up on Events"); for (int n4 = 0; n4 < namesRef.length(); n4++) { - int flag; - getEventSet(); - event1 = eventIterator.nextEvent(); + Event event1 = eventIterator.nextEvent(); + int index; if (event1 instanceof AccessWatchpointEvent) { index = 0; } else if (event1 instanceof ModificationWatchpointEvent ) { @@ -556,11 +550,15 @@ } else { log3("ERROR: else clause in detecting type of event1"); testExitCode = FAILED; + throw new JDITestRuntimeException("** unexpected event ** " + event1); } + log2("--------> got: " + event1 + " index: " + index); - flag = 1 << index; + int flag = 1 << index; if ((flagsCopy & flag) == 0) { - log3("ERROR: event duplication: " + eName); + log3("ERROR: event duplication. event " + event1 + + " flagsCopy = " + Integer.toBinaryString(flagsCopy) + + " flag = " + Integer.toBinaryString(flag)); testExitCode = FAILED; } else { flagsCopy ^= flag; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -320,9 +320,10 @@ log1(" TESTING BEGINS"); { + final String testThreadName = "thread2"; + log2("......setting up ThreadStartRequest"); ThreadStartRequest tsr = eventRManager.createThreadStartRequest(); - tsr.addCountFilter(1); tsr.setSuspendPolicy(EventRequest.SUSPEND_ALL); tsr.putProperty("number", "ThreadStartRequest"); tsr.enable(); @@ -331,7 +332,6 @@ log2("......setting up ThreadDeathRequest"); ThreadDeathRequest tdr = eventRManager.createThreadDeathRequest(); - tdr.addCountFilter(1); tdr.setSuspendPolicy(EventRequest.SUSPEND_ALL); tsr.putProperty("number", "ThreadDeathRequest"); tdr.enable(); @@ -342,7 +342,7 @@ vm.resume(); log2("......waiting for ThreadStartEvent"); - getEventSet(); + getEventSetForThreadStartDeath(testThreadName); eventSets[10] = eventSet; Event receivedEvent = eventIterator.nextEvent(); @@ -357,7 +357,7 @@ vm.resume(); log2("......waiting for ThreadDeathEvent"); - getEventSet(); + getEventSetForThreadStartDeath(testThreadName); eventSets[9] = eventSet; receivedEvent = eventIterator.nextEvent(); if ( !(receivedEvent instanceof ThreadDeathEvent) ) { @@ -514,18 +514,15 @@ log2(":::::::::vm.resume();"); vm.resume(); - Event event1 = null; - int flagsCopy = flags; - String eName = null; - int index = 0; + int flagsCopy = flags; log2("......getting and checking up on Events"); for (int n4 = 0; n4 < namesRef.length(); n4++) { - int flag; getEventSet(); - event1 = eventIterator.nextEvent(); + Event event1 = eventIterator.nextEvent(); + int index; if (event1 instanceof AccessWatchpointEvent) { index = 0; } else if (event1 instanceof ModificationWatchpointEvent ) { @@ -543,11 +540,15 @@ } else { log3("ERROR: else clause in detecting type of event1"); testExitCode = FAILED; + throw new JDITestRuntimeException("** unexpected event ** " + event1); } + log2("--------> got: " + event1 + " index: " + index); - flag = 1 << index; + int flag = 1 << index; if ((flagsCopy & flag) == 0) { - log3("ERROR: event duplication: " + eName); + log3("ERROR: event duplication. event " + event1 + + " flagsCopy = " + Integer.toBinaryString(flagsCopy) + + " flag = " + Integer.toBinaryString(flag)); testExitCode = FAILED; } else { flagsCopy ^= flag; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -266,7 +266,7 @@ for (int i = 0; ; i++) { vm.resume(); - breakpointForCommunication(); + breakpointForCommunication(debuggeeName); int instruction = ((IntegerValue) (debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value(); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -417,45 +417,35 @@ log2(":::::::::vm.resume();"); vm.resume(); - Event event1 = null; String threadName = null; int flagsCopy = flags; - String eName = null; log2("......getting and checking up on Events"); for (int n4 = 0; n4 < namesRef.length(); n4++) { - int flag; - int index; getEventSet(); - event1 = eventIterator.nextEvent(); + Event event1 = eventIterator.nextEvent(); + int index; if (event1 instanceof AccessWatchpointEvent) { - eName = "AccessWatchpointEvent"; index = 0; } else if (event1 instanceof ModificationWatchpointEvent ) { - eName = "ModificationWatchpointEvent"; index = 1; } else if (event1 instanceof BreakpointEvent ) { - eName = "BreakpointEvent"; index = 2; } else if (event1 instanceof ExceptionEvent ) { - eName = "ExceptionEvent"; index = 3; } else if (event1 instanceof MethodEntryEvent ) { - eName = "MethodEntryEvent"; index = 4; } else if (event1 instanceof MethodExitEvent ) { - eName = "MethodExitEvent"; index = 5; } else if (event1 instanceof StepEvent ) { - eName = "StepEvent"; index = 6; } else { log3("ERROR: else clause in detecting type of event1"); testExitCode = FAILED; - throw new JDITestRuntimeException("** unexpected event **"); + throw new JDITestRuntimeException("** unexpected event ** " + event1); } - log2("--------> got: " + eName); + log2("--------> got: " + event1 + " index: " + index); ThreadReference threadRef = ((LocatableEvent) event1).thread(); @@ -472,9 +462,11 @@ log3(" thread's name == " + threadRef.name()); } - flag = 1 << index; + int flag = 1 << index; if ((flagsCopy & flag) == 0) { - log3("ERROR: event duplication: " + eName); + log3("ERROR: event duplication. event " + event1 + + " flagsCopy = " + Integer.toBinaryString(flagsCopy) + + " flag = " + Integer.toBinaryString(flag)); testExitCode = FAILED; } else { flagsCopy ^= flag; diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java 2023-07-05 07:11:54.000000000 +0000 @@ -279,21 +279,18 @@ log2("......setting up ThreadDeathRequest"); ThreadDeathRequest tdr1 = eventRManager.createThreadDeathRequest(); // tdr1.addThreadFilter(mainThread); - tdr1.addCountFilter(1); tdr1.setSuspendPolicy(EventRequest.SUSPEND_ALL); tdr1.putProperty("number", "ThreadDeathRequest1"); tdr1.enable(); ThreadDeathRequest tdr2 = eventRManager.createThreadDeathRequest(); // tsr2.addThreadFilter(mainThread); - tdr2.addCountFilter(1); tdr2.setSuspendPolicy(EventRequest.SUSPEND_ALL); tdr2.putProperty("number", "ThreadDeathRequest2"); tdr2.enable(); ThreadDeathRequest tdr3 = eventRManager.createThreadDeathRequest(); tdr3.addThreadFilter(testThread); - tdr3.addCountFilter(1); tdr3.setSuspendPolicy(EventRequest.SUSPEND_ALL); tdr3.putProperty("number", "ThreadDeathRequest3"); tdr3.enable(); diff -Nru openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java --- openjdk-17-17.0.7+7~us1/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java 2023-07-05 07:11:54.000000000 +0000 @@ -157,27 +157,29 @@ // we can get the events from system threads unexpected for tests. // The method skips ThreadStartEvent/ThreadDeathEvent events // for all threads except the expected one. + // Note: don't limit ThreadStartRequest/ThreadDeathRequest request by addCountFilter(), + // as it limits the requested event to be reported at most once. protected void getEventSetForThreadStartDeath(String threadName) throws JDITestRuntimeException { - boolean gotDesiredEvent = false; - while (!gotDesiredEvent) { + while (true) { getEventSet(); Event event = eventIterator.nextEvent(); if (event instanceof ThreadStartEvent evt) { if (evt.thread().name().equals(threadName)) { - gotDesiredEvent = true; - } else { - log2("Got ThreadStartEvent for wrong thread: " + event); + break; } + log2("Got ThreadStartEvent for '" + evt.thread().name() + + "' instead of '" + threadName + "', skipping"); } else if (event instanceof ThreadDeathEvent evt) { if (evt.thread().name().equals(threadName)) { - gotDesiredEvent = true; - } else { - log2("Got ThreadDeathEvent for wrong thread: " + event); + break; } + log2("Got ThreadDeathEvent for '" + evt.thread().name() + + "' instead of '" + threadName + "', skipping"); } else { // not ThreadStartEvent nor ThreadDeathEvent - gotDesiredEvent = true; + break; } + eventSet.resume(); } // reset the iterator before return eventIterator = eventSet.eventIterator(); @@ -197,4 +199,25 @@ throw new JDITestRuntimeException("** event '" + event + "' IS NOT a breakpoint **"); } + // Similar to breakpointForCommunication, but skips Locatable events from unexpected locations. + // It's useful for cases when enabled event requests can cause notifications from system threads + // (like MethodEntryRequest, MethodExitRequest). + protected void breakpointForCommunication(String debuggeeName) throws JDITestRuntimeException { + log2("breakpointForCommunication"); + while (true) { + getEventSet(); + + Event event = eventIterator.nextEvent(); + if (event instanceof BreakpointEvent) { + return; + } + if (EventFilters.filtered(event, debuggeeName)) { + log2(" got unexpected event: " + event + ", skipping"); + eventSet.resume(); + } else { + throw new JDITestRuntimeException("** event '" + event + "' IS NOT a breakpoint **"); + } + } + } + } diff -Nru openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpDescendantTest.java openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpDescendantTest.java --- openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpDescendantTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpDescendantTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package xpath; + + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/* + * @test + * @bug 8289509 + * @library /javax/xml/jaxp/unittest + * @run testng/othervm xpath.XPathExpDescendantTest + * @summary Tests for XPath descendant/descendant-or-self axis specifier. + */ +public class XPathExpDescendantTest extends XPathTestBase { + + /* + * DataProvider: provides XPath Axis descendant expressions and equivalent xpath expression. + */ + @DataProvider(name = "descendantXpath") + public Object[][] getDescendantXpathExpression() { + return new Object[][] { + {"/Customers/descendant::*", "/Customers//*"}, + {"/Customers/descendant::Customer", "//Customer"}, + {"/Customers/descendant::foo:Customer", "//foo:Customer"}, + {"/Customers/Customer[@id='x1']/descendant::Address", + "/Customers/Customer[@id='x1']/Address"}, + {"/Customers/Customer[@id='x1']/descendant::*", + "/Customers/Customer[@id='x1']//*"}, + {"/Customers/foo:Customer/foo:Address/descendant::*", + "/Customers/foo:Customer/foo:Address//*"}, + {"/Customers/descendant::Name", "/Customers//Name"}, + {"/Customers/descendant::Street", "/Customers//Street"}, + {"/Customers/descendant::Street[2]", "Customers/Customer[@id='x2']/Address/Street"}, + {"/Customers/descendant::Street[2]", "(Customers//Street)[2]"}, + {"/Customers/descendant::Street[position() = 2]", + "Customers/Customer[@id='x2']/Address/Street"}, + {"/Customers/descendant-or-self::*", "//*"}, + {"/Customers/descendant-or-self::Customer", "/Customers/Customer"}, + {"/Customers/descendant-or-self::foo:Customer", "/Customers/foo:Customer"}, + {"/Customers/Customer[@id='x1']/descendant-or-self::Address", + "/Customers/Customer[@id = 'x1']/Address"}, + {"/Customers/Customer[@id='x1']/descendant-or-self::*", + "/Customers/Customer[@id='x1'] | /Customers/Customer[@id = 'x1']//*"}, + {"/Customers/foo:Customer/foo:Address/descendant-or-self::*", + "/Customers/foo:Customer/foo:Address | /Customers/foo:Customer/foo:Address//*"}, + {"/Customers/Customer/*[descendant::Street]", "/Customers/Customer/Address"}, + {"/Customers/Customer/*[not(descendant::Street)]", "/Customers/Customer/*[name() != \"Address\"]"}, + {"/Customers/Customer/*[descendant-or-self::Street]", "/Customers/Customer/Address"}, + {"/Customers/Customer/*[not(descendant-or-self::Street)]", + "/Customers/Customer/*[name() != \"Address\"]"} + }; + } + + /* + * DataProvider: provides XPath descendant expressions and expected number of descendant nodes returned + */ + @DataProvider(name = "descendantXpathNodeCount") + public Object[][] getDescendantXpathExpressionNodeCount() { + return new Object[][] { + {"/Customers/descendant::*", 40}, + {"/Customers/descendant::Customer", 3}, + {"/Customers/descendant::foo:Customer", 1}, + {"/Customers/Customer[@id='x1']/descendant::Address", 1}, + {"/Customers/Customer[@id='x1']/descendant::*", 9}, + {"/Customers/foo:Customer/foo:Address/descendant::*", 3}, + {"/Customers/Customer[@id='x1']/Address/descendant::Address", 0}, + {"/Customers/descendant-or-self::*", 41}, + {"/Customers/descendant-or-self::Customer", 3}, + {"/Customers/descendant-or-self::foo:Customer", 1}, + {"/Customers/Customer[@id='x1']/descendant-or-self::Address", 1}, + {"/Customers/Customer[@id='x1']/Address/descendant-or-self::Address", 1}, + {"/Customers/Customer[@id='x1']/descendant-or-self::*", 10}, + {"/Customers/foo:Customer/foo:Address/descendant-or-self::*", 4}, + {"/Customers/*[descendant::Name]", 3}, + {"/Customers/foo:Customer/*[descendant-or-self::foo:Street]", 1} + }; + } + + /* + * DataProvider: provides XPath descendant expressions which should return null. + */ + @DataProvider(name = "descendantXpathEmpty") + public Object[][] getDescendantXpathExpressionEmpty() { + return new Object[][] { + {"/Customers/Customer/Name/descendant::*"}, + {"/Customers/foo:Customer/descendant::Name"}, + {"/Customers/Customer/descendant::foo:Name"}, + {"/Customers/descendant::id"}, + {"/Customers/Customer/Name/descendant-or-self::id"}, + {"/Customers/foo:Customer/descendant-or-self::Name"}, + {"/Customers/Customer/descendant-or-self::foo:Name"}, + {"/Customers/descendant-or-self::id"} + }; + } + + /** + * Verifies descendant xpath expression returns same nodes as returns when used normal xpath expression + * @param descexp descendant XPath expression. + * @param expath normal xPath expression + * @throws XPathExpressionException + */ + @Test(dataProvider = "descendantXpath") + public void descendantExpTests(String descexp, String expath) throws XPathExpressionException { + Document doc = documentOf(DECLARATION + RAW_XML); + XPath xPath = XPathFactory.newInstance().newXPath(); + NodeList actualNodeList = (NodeList) xPath.evaluate(descexp, doc, XPathConstants.NODESET); + NodeList expectedNodeList = (NodeList) xPath.evaluate(expath, doc, XPathConstants.NODESET); + Assert.assertEquals(actualNodeList.getLength(), expectedNodeList.getLength()); + + for(int i = 0; i < actualNodeList.getLength(); i++) { + actualNodeList.item(i).equals(expectedNodeList.item(i)); + } + } + + /** + * Verifies descendant xpath expression return descendant nodes list with correct number of nodes. + * @param exp XPath expression. + * @param nodeCount number of descendant nodes in nodelist. + * @throws XPathExpressionException + */ + @Test(dataProvider = "descendantXpathNodeCount") + public void descendantNodesCountTests(String exp, int nodeCount) throws XPathExpressionException { + Document doc = documentOf(DECLARATION + RAW_XML); + XPath xPath = XPathFactory.newInstance().newXPath(); + NodeList nodeList = (NodeList) xPath.evaluate(exp, doc, XPathConstants.NODESET); + Assert.assertEquals(nodeList.getLength(), nodeCount); + } + + /** + * Verifies descendant xpath expression return no nodes if descendant expression context nodes don't have matching descendants + * @param exp XPath expression. + * @throws XPathExpressionException + */ + @Test(dataProvider = "descendantXpathEmpty") + public void DescendantScopeTests(String exp) throws XPathExpressionException { + Document doc = documentOf(DECLARATION + RAW_XML); + XPath xPath = XPathFactory.newInstance().newXPath(); + Node node = xPath.evaluateExpression(exp, doc, Node.class); + Assert.assertNull(node); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpFollowingTest.java openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpFollowingTest.java --- openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpFollowingTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpFollowingTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package xpath; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/* + * @test + * @bug 8289509 + * @library /javax/xml/jaxp/unittest + * @run testng/othervm xpath.XPathExpFollowingTest + * @summary Tests for XPath following/following-sibling axis specifier. + */ +public class XPathExpFollowingTest extends XPathTestBase { + /* + * DataProvider: provides XPath Axis following expressions and equivalent xpath expression. + */ + @DataProvider(name = "followingXpath") + public Object[][] getFollowingXpathExpression() { + return new Object[][] { + {"/Customers/following::*", "/None"}, + {"/Customers/Customer/following::Customer", "//Customer[@id != 'x1']"}, + {"/Customers/Customer/following::foo:Customer", "//foo:Customer"}, + {"/Customers/Customer[@id='x1']/following::Address", + "/Customers/Customer[@id != 'x1']/Address"}, + {"/Customers/Customer[@id='x1']/following::Street", + "/Customers/Customer[@id != 'x1']/Address/Street"}, + {"/Customers/Customer[@id='x1']/following::Street[2]", + "/Customers/Customer[@id='x2']/Address/Street"}, + {"/Customers/Customer[@id='x1']/following::*", + "/Customers/Customer[@id != 'x1']/descendant-or-self::*" + + " | /Customers/foo:Customer/descendant-or-self::*"}, + {"/Customers/foo:Customer/foo:Address/following::*", + "/Customers/foo:Customer/foo:Age | /Customers/foo:Customer/foo:ClubMember"}, + {"/Customers/Customer[@id = 'x1']/*[following::Street]", "/Customers/Customer[@id = 'x1']/*"}, + {"/Customers/foo:Customer/*[following::foo:Name]", "/None"}, + {"/Customers/foo:Customer/*[not(following::foo:Name)]", "/Customers/foo:Customer/*"}, + {"/Customers/following-sibling::*", "/None"}, + {"/Customers/Customer/following-sibling::Customer", + "/Customers/Customer[@id != 'x1']"}, + {"/Customers/Customer/following-sibling::foo:Customer", + "/Customers/foo:Customer"}, + {"/Customers/Customer[@id='x1']/Name/following-sibling::Address", + "/Customers/Customer[@id='x1']/Address"}, + {"/Customers/Customer/Name/following-sibling::Address", + "/Customers//Address"}, + {"(/Customers/Customer/Address/Street/following-sibling::State)[3]", + "/Customers/Customer[@id='x3']/Address/State"}, + {"/Customers/Customer[@id='x1']/Address/Street/following-sibling::*[2]", + "/Customers/Customer[@id='x3']/Address/State"}, + {"/Customers/Customer[@id='x1']/following-sibling::*", + "/Customers/Customer[@id != 'x1'] | /Customers/foo:Customer"}, + {"/Customers/foo:Customer/foo:Address/following-sibling::*", + "/Customers/foo:Customer/foo:Age | /Customers/foo:Customer/foo:ClubMember"}, + {"/Customers/Customer[@id = 'x1']/*[following-sibling::Street]", "/None"}, + {"/Customers/foo:Customer/*[following-sibling::foo:Address]", "/Customers/foo:Customer/foo:Name |" + + "/Customers/foo:Customer/foo:Phone | /Customers/foo:Customer/foo:Email"}, + {"/Customers/foo:Customer/*[not(following-sibling::foo:Address)]", "/Customers/foo:Customer/foo:Age | " + + "/Customers/foo:Customer/foo:ClubMember | /Customers/foo:Customer/foo:Address"} + }; + } + + /* + * DataProvider: provides XPath following expressions and expected number of following nodes returned + */ + @DataProvider(name = "followingXpathNodeCount") + public Object[][] getFollowingXpathExpressionNodeCount() { + return new Object[][] { + {"/Customers/following::*", 0}, + {"/Customers/Customer/following::*", 30}, + {"/Customers/Customer/following::Customer", 2}, + {"/Customers/Customer/following::foo:Customer", 1}, + {"/Customers/Customer[@id='x1']/Name/following::*", 38}, + {"/Customers/Customer/Address/following::*", 32}, + {"/Customers/foo:Customer/foo:Address/following::*", 2}, + {"/Customers/foo:Customer/foo:Name/following::*", 8}, + {"/Customers/foo:Customer/*[following::foo:Name]", 0}, + {"/Customers/foo:Customer/*[not(following::foo:Name)]", 6}, + {"/Customers/following-sibling::*", 0}, + {"/Customers/Customer/following-sibling::*", 3}, + {"/Customers/Customer/following-sibling::Customer", 2}, + {"/Customers/Customer/following-sibling::foo:Customer", 1}, + {"/Customers/Customer[@id='x1']/Name/following-sibling::*", 5}, + {"/Customers/Customer/Address/following-sibling::*", 6}, + {"/Customers/Customer[@id='x1']/Address/following-sibling::*", 2}, + {"/Customers/foo:Customer/foo:Address/following-sibling::*", 2}, + {"/Customers/Customer[@id = 'x1']/*[following-sibling::Street]", 0}, + {"/Customers/foo:Customer/*[following-sibling::foo:Address]", 3}, + {"/Customers/foo:Customer/*[not(following-sibling::foo:Address)]", 3} + }; + } + + /* + * DataProvider: provides XPath following expressions which should not return any node. + */ + @DataProvider(name = "followingXpathEmpty") + public Object[][] getFollowingXpathExpressionEmpty() { + return new Object[][] { + {"/Customers/following::*"}, + {"/Customers/foo:Customer/following::*"}, + {"/Customers/Customer[@id = 'x3' ]/following::Customer"}, + {"/Customers/following::id"}, + {"/Customers/Customer[@id = 'x3' ]/following-sibling::Customer"}, + {"/Customers/foo:Customer/following-sibling::*"}, + {"/Customers/Customer/following-sibling::foo:Name"}, + {"/Customers/following-sibling::id"} + }; + } + + /** + * Verifies Axis following xpath expression returns same nodes as returns when used normal xpath expression + * @param descexp Axis following XPath expression. + * @param expath normal xPath expression + * @throws XPathExpressionException + */ + @Test(dataProvider = "followingXpath") + public void followingExpTests(String descexp, String expath) throws XPathExpressionException { + Document doc = documentOf(DECLARATION + RAW_XML); + XPath xPath = XPathFactory.newInstance().newXPath(); + NodeList actualNodeList = (NodeList) xPath.evaluate(descexp, doc, XPathConstants.NODESET); + NodeList expectedNodeList = (NodeList) xPath.evaluate(expath, doc, XPathConstants.NODESET); + Assert.assertEquals(actualNodeList.getLength(), expectedNodeList.getLength()); + + for(int i = 0; i < actualNodeList.getLength(); i++) { + actualNodeList.item(i).equals(expectedNodeList.item(i)); + } + } + + /** + * Verifies following xpath expression return following nodes list with correct number of nodes. + * @param exp XPath expression. + * @param nodeCount number of following nodes in nodelist. + * @throws XPathExpressionException + */ + @Test(dataProvider = "followingXpathNodeCount") + public void followingNodesCountTests(String exp, int nodeCount) throws XPathExpressionException { + Document doc = documentOf(DECLARATION + RAW_XML); + XPath xPath = XPathFactory.newInstance().newXPath(); + NodeList nodeList = (NodeList) xPath.evaluate(exp, doc, XPathConstants.NODESET); + Assert.assertEquals(nodeList.getLength(), nodeCount); + } + + /** + * Verifies following xpath expression return no nodes if following expression context nodes don't have matching following elements. + * @param exp XPath expression. + * @throws XPathExpressionException + */ + @Test(dataProvider = "followingXpathEmpty") + public void FollowingScopeTests(String exp) throws XPathExpressionException { + Document doc = documentOf(DECLARATION + RAW_XML); + XPath xPath = XPathFactory.newInstance().newXPath(); + Node node = xPath.evaluateExpression(exp, doc, Node.class); + Assert.assertNull(node); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpParentTest.java openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpParentTest.java --- openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpParentTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpParentTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package xpath; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.XPathNodes; + +/* + * @test + * @bug 8292990 + * @summary Tests the XPath parent axis + * @library /javax/xml/jaxp/unittest + * + * @run testng xpath.XPathExpParentTest + */ +public class XPathExpParentTest extends XPathTestBase { + private static final Document doc = getDocument(); + + /* + * DataProvider for XPath expressions which should provide one and only + * one parent node. + * Data columns: + * see parameters of the test "testOneParentNodeExp" + */ + @DataProvider(name = "oneParentNode") + public Object[][] getOneParentNodeExp() { + return new Object[][]{ + {"//Customer/parent::*", "//Customers"}, + {"//Customer[1]/text()/parent::*", "(//Customer)[1]"}, + {"//Customer[1]/@id/parent::*", "(//Customer)[1]"}, + {"//Customer[1]/namespace::*/parent::*", "//Customers"}, + {"/Customers/comment()/parent::*", "//Customers"}, + {"//Customer[1]/..", "//Customers"}, + {"//Customer[1]/text()/..", "(//Customer)[1]"}, + {"//Customer[1]/@id/..", "(//Customer)[1]"}, + {"//Customer[1]/namespace::*/..", "//Customers"}, + {"/Customers/comment()/..", "//Customers"}, + {"//*[parent::Customers][1]", "(//Customer)[1]"}, + {"//*[parent::Customers and @id='x1']", "(//Customer)[1]"}, + + // ".." is short for parent::node(). A node test node() is true for any node of + // any type including the document root node. + {"/Customers/parent::node()", "/"}, + {"/Customers/..", "/"}, + }; + } + + /* + * DataProvider for XPath expressions which should provide no parent node. + * Data columns: + * see parameters of the test "testZeroParentNodeExp" + */ + @DataProvider(name = "noParentNode") + public Object[][] getZeroParentNodeExp() { + return new Object[][]{ + // A node test * is true for any node of the principle node type which contains + // attribute nodes, namespace nodes and element nodes. parent::* never includes the + // document root node. + {"/Customers/parent::*"}, + + // "/" selects the document root which has no parent. Expressions below validate + // no parent is found on the document root node. + {"/.."}, + {"/parent::node()"} + }; + } + + /* + * DataProvider for XPath relative expressions which should provide a parent node. + * Data columns: + * see parameters of the test "testRelativeParentExp" + */ + @DataProvider(name = "relativeParent") + public Object[][] getRelativeParentExp() { + return new Object[][]{ + {"/Customers", "comment()/parent::*"}, + {"/Customers/Customer[1]", "Name/parent::*"}, + {"/Customers/Customer[1]", "text()/parent::*"}, + {"/Customers/Customer[1]", "@id/parent::*"}, + {"/Customers", "namespace::*/parent::*"}, + {"/Customers", "comment()/parent::*"}, + {"/Customers/Customer[1]", "../Customer[1]/Name/.."}, + {"/Customers/Customer[1]", "../Customer[1]/text()/.."}, + {"/Customers/Customer[1]", "../Customer[1]/@id/.."}, + {"/Customers", "namespace::*/.."}, + }; + } + + /** + * Verifies that XPath expressions provide one and only parent node. + * + * @param exp XPath expression + * @param parentExp XPath parent node expression + * @throws Exception if test failed + */ + @Test(dataProvider = "oneParentNode") + void testOneParentNodeExp(String exp, String parentExp) + throws Exception { + XPath xPath = XPathFactory.newInstance().newXPath(); + + Node expected = xPath.evaluateExpression(parentExp, doc, Node.class); + + testExp(doc, exp, expected, Node.class); + + XPathNodes nodes = xPath.evaluateExpression(exp, doc, XPathNodes.class); + + Assert.assertEquals(nodes.size(), 1); + } + + /** + * Verifies that XPath expressions provide no parent node. + * + * @param exp XPath expression + * @throws Exception if test failed + */ + @Test(dataProvider = "noParentNode") + void testZeroParentNodeExp(String exp) + throws Exception { + testExp(doc, exp, null, Node.class); + } + + /** + * Verifies that XPath relative expressions provide the same node as the context node. + * + * @param exp XPath expression that provides a context node + * @param relativeExp XPath relative expression that is evaluated relatively to the context node + * @throws Exception if test failed + */ + @Test(dataProvider = "relativeParent") + void testRelativeParentExp(String exp, String relativeExp) throws Exception { + XPath xPath = XPathFactory.newInstance().newXPath(); + Node contextNode = xPath.evaluateExpression(exp, doc, Node.class); + Node relativeNode = xPath.evaluateExpression(relativeExp, contextNode, Node.class); + + Assert.assertEquals(relativeNode, contextNode); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathOperatorExpTest.java openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathOperatorExpTest.java --- openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathOperatorExpTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathOperatorExpTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package xpath; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; + +import javax.xml.xpath.XPathExpressionException; + +/* + * @test + * @bug 8289949 + * @summary Tests the XPath operator expressions + * @library /javax/xml/jaxp/unittest + * + * @run testng xpath.XPathOperatorExpTest + */ +public class XPathOperatorExpTest extends XPathTestBase { + private static final Document doc = getDocument(); + + /* + * DataProvider for testing the XPath operator expressions. + * Data columns: + * see parameters of the test "testOperatorExp" + */ + @DataProvider(name = "operatorExpTestCases") + public Object[][] getOperatorExp() { + return new Object[][]{ + // boolean and relational operators: or, and, =, !=, <, <=, >, >= + {"string(//Customer[Age > 0]/Name)", "name2"}, + {"string(//Customer[Age < 0]/Name)", "name3"}, + {"string(//Customer[Age = 0]/Name)", "name1"}, + {"count(//Customer[Age >= 0 and Age <= 0])", 1}, + {"count(//Customer[Age >= 0][Age <= 0])", 1}, + {"count(//Customer[Age > 0 or Age < 0])", 2}, + {"count(//Customer[Age != 0])", 2}, + + // arithmetic operators: +, -, *, div, mod + {"string(//Customer[last() div 2]/Name)", "name1"}, + {"string(//Customer[position() * 2 > last()]/Name)", "name2"}, + {"string(//Customer[position() + 1 < last()]/Name)", "name1"}, + {"string(//Customer[last() - 1]/Name)", "name2"}, + {"string(//Customer[last() mod 2]/Name)", "name1"}, + + // union operator: | + {"count(//Customer[Name='name1'] | //Customer[Name='name2'])", + 2}, + {"count(//Customer[Name='name1'] | //Customer[Name='name2'] |" + + " //Customer[Name='name3'])", 3}, + + // operator precedence + {"1 + 2 * 3 + 3", 10.0}, + {"1 + 1 div 2 + 2", 3.5}, + {"1 + 1 mod 2 + 2", 4.0}, + {"1 * 1 mod 2 div 2", 0}, + {"1 * (1 mod 2) div 2", 0.5}, + {"(1 + 2) * (3 + 3)", 18.0}, + {"(1 + 2) div (3 + 3)", 0.5}, + {"1 - 2 < 3 + 3", true}, + {"1 * 2 >= 3 div 3", true}, + {"3 > 2 > 1", false}, + {"3 > (2 > 1)", true}, + {"3 > 2 = 1", true}, + {"1 = 3 > 2", true}, + {"1 = 2 or 1 <= 2 and 2 != 2", false}, + }; + } + + /* + * DataProvider for testing XPathExpressionException being thrown on + * invalid operator usage. + * Data columns: + * see parameters of the test "testExceptionOnEval" + */ + @DataProvider(name = "exceptionExpTestCases") + public Object[][] getExceptionExp() { + return new Object[][]{ + // invalid operators + {"string(//Customer[last() / 2]/Name)"}, + {"string(//Customer[last() % 2]/Name)"}, + {"count(//Customer[Name='name1'] & //Customer[Name='name2'])"}, + {"count(//Customer[Name='name1'] && //Customer[Name='name2'])"}, + {"count(//Customer[Name='name1'] || //Customer[Name='name2'])"}, + + // union operator only works for node-sets + {"//Customer[Name='name1'] | string(//Customer[Name='name2']))"}, + }; + } + + /** + * Verifies that the result of evaluating XPath operators matches the + * expected result. + * + * @param exp XPath expression + * @param expected expected result + * @throws Exception if test fails + */ + @Test(dataProvider = "operatorExpTestCases") + void testOperatorExp(String exp, Object expected) throws Exception { + if (expected instanceof Double d) { + testExp(doc, exp, d, Double.class); + } else if (expected instanceof String s) { + testExp(doc, exp, s, String.class); + } else if (expected instanceof Boolean b) { + testExp(doc, exp, b, Boolean.class); + } + } + + /** + * Verifies that XPathExpressionException is thrown on xpath evaluation. + * + * @param exp XPath expression + */ + @Test(dataProvider = "exceptionExpTestCases") + void testExceptionOnEval(String exp) { + Assert.assertThrows(XPathExpressionException.class, () -> testEval(doc, + exp)); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathTestBase.java openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathTestBase.java --- openjdk-17-17.0.7+7~us1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathTestBase.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathTestBase.java 2023-07-05 07:11:54.000000000 +0000 @@ -68,6 +68,7 @@ static final String RAW_XML = "" + + "" + " " + " name1" + " 1111111111" diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/build/releaseFile/CheckReleaseFile.java openjdk-17-17.0.8+7/test/jdk/build/releaseFile/CheckReleaseFile.java --- openjdk-17-17.0.7+7~us1/test/jdk/build/releaseFile/CheckReleaseFile.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/build/releaseFile/CheckReleaseFile.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,172 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8193660 8303476 + * @summary Check SOURCE line and JAVA_RUNTIME_VERSION in "release" file + * @run main CheckReleaseFile + */ + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CheckReleaseFile { + + public static final String SRC_HASH_REGEXP = ":((hg)|(git)):[a-z0-9]*\\+?"; + + private final boolean isOpenJDK; + CheckReleaseFile(String dataFile, boolean isOpenJDK) { + this.isOpenJDK = isOpenJDK; + // Read data files + readFile(dataFile); + } + + private void readFile(String fileName) { + String fishForSOURCE = null; + String implementor = null; + String runtimeVersion = null; + + File file = new File(fileName); + + // open the stream to read in for Entries + try (BufferedReader buffRead = + new BufferedReader(new FileReader(fileName))) { + + // this is the string read + String readIn; + + // let's read some strings! + while ((readIn = buffRead.readLine()) != null) { + readIn = readIn.trim(); + + // throw out blank lines + if (readIn.length() == 0) + continue; + + // grab SOURCE line + if (readIn.startsWith("SOURCE=")) { + fishForSOURCE = readIn; + continue; + } + + // grab IMPLEMENTOR line + if (readIn.startsWith("IMPLEMENTOR=")) { + implementor = readIn; + continue; + } + + // grab JAVA_RUNTIME_VERSION line + if (readIn.startsWith("JAVA_RUNTIME_VERSION=")) { + runtimeVersion = readIn; + continue; + } + } + } catch (FileNotFoundException fileExcept) { + throw new RuntimeException("File " + fileName + + " not found reading data!", fileExcept); + } catch (IOException ioExcept) { + throw new RuntimeException("Unexpected problem reading data!", + ioExcept); + } + + // was SOURCE even found? + if (fishForSOURCE == null) { + throw new RuntimeException("SOURCE line was not found!"); + } + + // Check if implementor is Oracle + boolean isOracle = (implementor != null) && implementor.contains("Oracle Corporation"); + checkSource(fishForSOURCE, isOracle); + + if (runtimeVersion == null) { + throw new RuntimeException("JAVA_RUNTIME_VERSION line was not found!"); + } + String expected = "JAVA_RUNTIME_VERSION=\"" + Runtime.version() + "\""; + if (!expected.equals(runtimeVersion)) { + throw new RuntimeException("Mismatched runtime version: " + + runtimeVersion + " expected: " + expected); + } + } + + private void checkSource(String fishForSOURCE, boolean isOracle) { + + System.out.println("The source string found: " + fishForSOURCE); + + // Extract the value of SOURCE= + Pattern valuePattern = Pattern.compile("SOURCE=\"(.*)\""); + Matcher valueMatcher = valuePattern.matcher(fishForSOURCE); + if (!valueMatcher.matches()) { + throw new RuntimeException("SOURCE string has bad format, should be SOURCE=\"\""); + } + String valueString = valueMatcher.group(1); + + + String[] values = valueString.split(" "); + + // First value MUST start with ".:" regardless of Oracle or OpenJDK + String rootRegexp = "\\." + SRC_HASH_REGEXP; + if (!values[0].matches(rootRegexp)) { + throw new RuntimeException("The test failed, first element did not match regexp: " + rootRegexp); + } + + // If it's an Oracle build, it can be either OpenJDK or OracleJDK. Other + // builds may have any number of additional elements in any format. + if (isOracle) { + if (isOpenJDK) { + if (values.length != 1) { + throw new RuntimeException("The test failed, wrong number of elements in SOURCE list." + + " Should be 1 for Oracle built OpenJDK."); + } + } else { + if (values.length != 2) { + throw new RuntimeException("The test failed, wrong number of elements in SOURCE list." + + " Should be 2 for OracleJDK."); + } + // Second value MUST start with "open:" for OracleJDK + String openRegexp = "open" + SRC_HASH_REGEXP; + if (!values[1].matches(openRegexp)) { + throw new RuntimeException("The test failed, second element did not match regexp: " + openRegexp); + } + } + } + + // Everything was fine + System.out.println("The test passed!"); + } + + public static void main(String args[]) { + String jdkPath = System.getProperty("test.jdk"); + String runtime = System.getProperty("java.runtime.name"); + + System.out.println("JDK Path : " + jdkPath); + System.out.println("Runtime Name : " + runtime); + + new CheckReleaseFile(jdkPath + "/release", runtime.contains("OpenJDK")); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/build/releaseFile/CheckSource.java openjdk-17-17.0.8+7/test/jdk/build/releaseFile/CheckSource.java --- openjdk-17-17.0.7+7~us1/test/jdk/build/releaseFile/CheckSource.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/build/releaseFile/CheckSource.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +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 8193660 - * @summary Check SOURCE line in "release" file for closedjdk - * @run main CheckSource - */ - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class CheckSource { - - public static final String SRC_HASH_REGEXP = ":((hg)|(git)):[a-z0-9]*\\+?"; - - CheckSource(String dataFile, boolean isOpenJDK) { - // Read data files - readFile(dataFile, isOpenJDK); - } - - private void readFile(String fileName, boolean isOpenJDK) { - String fishForSOURCE = null; - String implementor = null; - - File file = new File(fileName); - - // open the stream to read in for Entries - try (BufferedReader buffRead = - new BufferedReader(new FileReader(fileName))) { - - // this is the string read - String readIn; - - // let's read some strings! - while ((readIn = buffRead.readLine()) != null) { - readIn = readIn.trim(); - - // throw out blank lines - if (readIn.length() == 0) - continue; - - // grab SOURCE line - if (readIn.startsWith("SOURCE=")) { - fishForSOURCE = readIn; - continue; - } - - // grab IMPLEMENTOR line - if (readIn.startsWith("IMPLEMENTOR=")) { - implementor = readIn; - continue; - } - } - } catch (FileNotFoundException fileExcept) { - throw new RuntimeException("File " + fileName + - " not found reading data!", fileExcept); - } catch (IOException ioExcept) { - throw new RuntimeException("Unexpected problem reading data!", - ioExcept); - } - - // was SOURCE even found? - if (fishForSOURCE == null) { - throw new RuntimeException("SOURCE line was not found!"); - } - System.out.println("The source string found: " + fishForSOURCE); - - // Extract the value of SOURCE= - Pattern valuePattern = Pattern.compile("SOURCE=\"(.*)\""); - Matcher valueMatcher = valuePattern.matcher(fishForSOURCE); - if (!valueMatcher.matches()) { - throw new RuntimeException("SOURCE string has bad format, should be SOURCE=\"\""); - } - String valueString = valueMatcher.group(1); - - // Check if implementor is Oracle - boolean isOracle = (implementor != null) && implementor.contains("Oracle Corporation"); - - String[] values = valueString.split(" "); - - // First value MUST start with ".:" regardless of Oracle or OpenJDK - String rootRegexp = "\\." + SRC_HASH_REGEXP; - if (!values[0].matches(rootRegexp)) { - throw new RuntimeException("The test failed, first element did not match regexp: " + rootRegexp); - } - - // If it's an Oracle build, it can be either OpenJDK or OracleJDK. Other - // builds may have any number of additional elements in any format. - if (isOracle) { - if (isOpenJDK) { - if (values.length != 1) { - throw new RuntimeException("The test failed, wrong number of elements in SOURCE list." + - " Should be 1 for Oracle built OpenJDK."); - } - } else { - if (values.length != 2) { - throw new RuntimeException("The test failed, wrong number of elements in SOURCE list." + - " Should be 2 for OracleJDK."); - } - // Second value MUST start with "open:" for OracleJDK - String openRegexp = "open" + SRC_HASH_REGEXP; - if (!values[1].matches(openRegexp)) { - throw new RuntimeException("The test failed, second element did not match regexp: " + openRegexp); - } - } - } - - // Everything was fine - System.out.println("The test passed!"); - } - - public static void main(String args[]) { - String jdkPath = System.getProperty("test.jdk"); - String runtime = System.getProperty("java.runtime.name"); - - System.out.println("JDK Path : " + jdkPath); - System.out.println("Runtime Name : " + runtime); - - new CheckSource(jdkPath + "/release", runtime.contains("OpenJDK")); - } -} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/com/sun/crypto/provider/TLS/keymatdata.txt openjdk-17-17.0.8+7/test/jdk/com/sun/crypto/provider/TLS/keymatdata.txt --- openjdk-17-17.0.7+7~us1/test/jdk/com/sun/crypto/provider/TLS/keymatdata.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/com/sun/crypto/provider/TLS/keymatdata.txt 2023-07-05 07:11:54.000000000 +0000 @@ -3646,3 +3646,37 @@ km-siv: 34:8a:e8:24:84:38:c4:e1 km-cmackey: e8:f0:b5:7b:a7:cc:2f:5e:43:ef:d3:dd:4e:8c:f9:6f:51:d7:84:df km-smackey: fc:0c:77:20:c2:28:d3:11:ba:57:13:d8:0b:2d:f1:30:89:c6:35:69 +km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc +km-major: 3 +km-minor: 3 +km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56 +km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97 +km-cipalg: AES +km-hashalg: SHA-256 +km-keylen: 16 +km-explen: 0 +km-ivlen: 4 +km-maclen: 0 +km-ccipkey: 60:7a:45:a9:6e:76:58:ea:d9:44:c5:25:f8:92:f1:26 +km-scipkey: 42:c0:ed:75:a2:51:21:7c:50:74:9d:78:9a:f7:35:2b +km-civ: a1:3c:3e:4a +km-siv: 85:ab:ee:70 +km-cmackey: (null) +km-smackey: (null) +km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc +km-major: 3 +km-minor: 3 +km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56 +km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97 +km-cipalg: AES +km-hashalg: SHA-384 +km-keylen: 32 +km-explen: 0 +km-ivlen: 4 +km-maclen: 0 +km-ccipkey: 3c:03:17:61:1e:88:4a:aa:01:4c:ac:6c:f8:bb:91:c3:0e:ec:57:c7:bf:07:ff:eb:49:22:f9:80:12:64:72:2a +km-scipkey: f8:00:8e:b2:dc:25:98:f1:97:00:55:28:60:a3:65:da:42:89:18:bb:40:94:53:d2:75:2a:29:e5:aa:94:1d:7a +km-civ: 24:02:76:6f +km-siv: 3b:6d:33:5a +km-cmackey: (null) +km-smackey: (null) diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/com/sun/crypto/provider/TLS/TestKeyMaterial.java openjdk-17-17.0.8+7/test/jdk/com/sun/crypto/provider/TLS/TestKeyMaterial.java --- openjdk-17-17.0.7+7~us1/test/jdk/com/sun/crypto/provider/TLS/TestKeyMaterial.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/com/sun/crypto/provider/TLS/TestKeyMaterial.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -61,6 +61,7 @@ byte[] clientRandom = null; byte[] serverRandom = null; String cipherAlgorithm = null; + String hashAlgorithm = null; // TLS1.2+ only int keyLength = 0; int expandedKeyLength = 0; int ivLength = 0; @@ -94,6 +95,8 @@ serverRandom = parse(data); } else if (line.startsWith("km-cipalg:")) { cipherAlgorithm = data; + } else if (line.startsWith("km-hashalg:")) { + hashAlgorithm = data; } else if (line.startsWith("km-keylen:")) { keyLength = Integer.parseInt(data); } else if (line.startsWith("km-explen:")) { @@ -119,14 +122,36 @@ n++; KeyGenerator kg = - KeyGenerator.getInstance("SunTlsKeyMaterial", provider); + KeyGenerator.getInstance(minor == 3 ? + "SunTls12KeyMaterial" : + "SunTlsKeyMaterial", provider); SecretKey masterKey = new SecretKeySpec(master, "TlsMasterSecret"); + int prfHashLength, prfBlockSize; + + if (hashAlgorithm != null) { + switch (hashAlgorithm) { + case "SHA-256": + prfHashLength = 32; + prfBlockSize = 64; + break; + case "SHA-384": + prfHashLength = 48; + prfBlockSize = 128; + break; + default: + throw new RuntimeException("Unexpected hashalg: " + + hashAlgorithm); + } + } else { + prfHashLength = -1; + prfBlockSize = -1; + } TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(masterKey, major, minor, clientRandom, serverRandom, cipherAlgorithm, keyLength, expandedKeyLength, ivLength, macLength, - null, -1, -1); + hashAlgorithm, prfHashLength, prfBlockSize); kg.init(spec); TlsKeyMaterialSpec result = diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/com/sun/nio/sctp/SctpChannel/CloseDescriptors.java openjdk-17-17.0.8+7/test/jdk/com/sun/nio/sctp/SctpChannel/CloseDescriptors.java --- openjdk-17-17.0.7+7~us1/test/jdk/com/sun/nio/sctp/SctpChannel/CloseDescriptors.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/com/sun/nio/sctp/SctpChannel/CloseDescriptors.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,206 @@ +/* + * Copyright (c) 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 8238274 + * @summary Potential leak file descriptor for SCTP + * @requires (os.family == "linux") + * @run main/othervm/timeout=250 CloseDescriptors + */ + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import com.sun.nio.sctp.SctpChannel; +import com.sun.nio.sctp.SctpServerChannel; + +public class CloseDescriptors { + private static Selector selector; + private static final int LOOP = 10; + private static final int LIMIT_LINES = 2; + private static SelectorThread selThread; + private static boolean finished = false; + + public static void main(String[] args) throws Exception { + if (!Util.isSCTPSupported()) { + System.out.println("SCTP protocol is not supported"); + System.out.println("Test cannot be run"); + return; + } + + List lsofDirs = List.of("/usr/bin", "/usr/sbin"); + Optional lsof = lsofDirs.stream() + .map(s -> Path.of(s, "lsof")) + .filter(f -> Files.isExecutable(f)) + .findFirst(); + if (!lsof.isPresent()) { + System.out.println("Cannot locate lsof in " + lsofDirs); + System.out.println("Test cannot be run"); + return; + } + + try (ServerSocket ss = new ServerSocket(0)) { + int port = ss.getLocalPort(); + + Server server = new Server(port); + server.start(); + + selector = Selector.open(); + + selThread = new SelectorThread(); + selThread.start(); + + // give time for the server and selector to start + Thread.sleep(100); + for (int i = 0 ; i < 100 ; ++i) { + System.out.println(i); + doIt(port); + Thread.sleep(100); + } + System.out.println("end"); + if (!check()) { + cleanup(port); + throw new RuntimeException("Failed: detected unclosed FD."); + } + cleanup(port); + server.join(); + selThread.join(); + } + } + + private static void doIt(int port) throws Exception { + InetSocketAddress sa = new InetSocketAddress("localhost", port); + + for (int i = 0 ; i < LOOP ; ++i) { + System.out.println(" " + i); + try (SctpChannel channel = SctpChannel.open(sa, 1, 1)) { + channel.configureBlocking(false); + + SelectionKey key = selThread.regChannel(channel); + + key.cancel(); + selector.wakeup(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + Thread.sleep(200); + } + } + + private static boolean check() throws Exception { + long myPid = ProcessHandle.current().pid(); + ProcessBuilder pb = new ProcessBuilder( + "lsof", "-U", "-a", "-p", Long.toString(myPid)); + pb.redirectErrorStream(true); + Process p = pb.start(); + p.waitFor(); + if (p.exitValue() != 0) { + return false; + } + + boolean result = true; + try (BufferedReader br = new BufferedReader(new InputStreamReader( + p.getInputStream()))) { + int count = 0; + String line = br.readLine(); + while (line != null) { + System.out.println(line); + count++; + if (count > LIMIT_LINES) { + result = false; + } + line = br.readLine(); + } + } + return result; + } + + private static void cleanup(int port) throws IOException { + finished = true; + InetSocketAddress sa = new InetSocketAddress("localhost", port); + SctpChannel channel = SctpChannel.open(sa, 1, 1); + channel.close(); + } + + private static class SelectorThread extends Thread { + private Object lock = new Object(); + private SctpChannel channel; + private SelectionKey key; + + public SelectionKey regChannel(SctpChannel ch) throws Exception { + synchronized (lock) { + channel = ch; + selector.wakeup(); + lock.wait(); + } + return key; + } + + public void run() { + try { + while (!finished) { + selector.select(1000); + synchronized (lock) { + if (channel != null) { + key = channel.register(selector, SelectionKey.OP_READ); + channel = null; + lock.notify(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private static class Server extends Thread { + private int port; + + public Server(int port) { this.port = port; } + + public void run() { + try { + SctpServerChannel ss = SctpServerChannel.open(); + InetSocketAddress sa = new InetSocketAddress("localhost", port); + ss.bind(sa); + while (!finished) { + SctpChannel soc = ss.accept(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} + diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Clipboard/DelayedQueryTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Clipboard/DelayedQueryTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Clipboard/DelayedQueryTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Clipboard/DelayedQueryTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4085183 8000630 + @summary tests that clipboard contents is retrieved even if the app didn't + receive native events for a long time. + @requires (os.family != "mac") + @key headful + @run main DelayedQueryTest +*/ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.InputEvent; +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; + +public class DelayedQueryTest implements ClipboardOwner, Runnable { + int returnCode = Child.CHILD_RETURN_CODE_NOT_READY; + + Process childProcess = null; + Frame frame; + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException { + String osName = System.getProperty("os.name"); + if (osName.toLowerCase().contains("os x")) { + System.out.println("This test is not for MacOS, considered passed."); + return; + } + DelayedQueryTest delayedQueryTest = new DelayedQueryTest(); + EventQueue.invokeAndWait(delayedQueryTest::initAndShowGui); + try { + delayedQueryTest.start(); + } finally { + EventQueue.invokeAndWait(() -> delayedQueryTest.frame.dispose()); + } + } + + public void initAndShowGui(){ + frame = new Frame("DelayedQueryTest"); + frame.add(new Panel()); + frame.setBounds(200,200, 200, 200); + frame.setVisible(true); + } + + public void start() { + try { + Robot robot = new Robot(); + // Some mouse activity to update the Xt time stamp at + // the parent process. + robot.delay(1000); + robot.waitForIdle(); + + Point p = frame.getLocationOnScreen(); + robot.mouseMove(p.x + 100, p.y + 100); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } catch (AWTException e) { + e.printStackTrace(); + throw new RuntimeException("The test failed."); + } + Child.sysClipboard.setContents(Child.transferable, this); + + String javaPath = System.getProperty("java.home", ""); + String[] command = { + javaPath + File.separator + "bin" + File.separator + "java", + "-cp", System.getProperty("test.classes", "."), + "Child" + }; + + try { + Process process = Runtime.getRuntime().exec(command); + childProcess = process; + returnCode = process.waitFor(); + childProcess = null; + + InputStream errorStream = process.getErrorStream(); + int count = errorStream.available(); + if (count > 0) { + byte[] b = new byte[count]; + errorStream.read(b); + System.err.println("========= Child VM System.err ========"); + System.err.print(new String(b)); + System.err.println("======================================"); + } + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException("The test failed."); + } + if (returnCode != Child.CHILD_RETURN_CODE_OK) { + System.err.println("Child VM: returned " + returnCode); + throw new RuntimeException("The test failed."); + } + } // start() + + public void lostOwnership(Clipboard clipboard, + Transferable contents) { + // At this moment the child process has definitely started. + // So we can try to retrieve the clipboard contents set + // by the child process. + new Thread(this).start(); + } + + public void run() { + // We are going to check if it is possible to retrieve the data + // after the child process has set the clipboard contents twice, + // since after the first setting the retrieval is always successful. + // So we wait to let the child process set the clipboard contents + // twice. + try { + Thread.sleep(Child.CHILD_SELECTION_CHANGE_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + try { + String s = (String)Child.sysClipboard + .getContents(null) + .getTransferData(DataFlavor.stringFlavor); + if (!"String".equals(s)) { + System.err.println("Data retrieved: " + s); + throw new RuntimeException("Retrieved data is incorrect."); + } + } catch (Exception e) { + e.printStackTrace(); + if (childProcess != null) { + childProcess.destroy(); + childProcess = null; + } + throw new RuntimeException("Failed to retrieve the data."); + } + Child.sysClipboard.setContents(Child.transferable, null); + } +} + +class Child { + static final Clipboard sysClipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + static final Transferable transferable = new StringSelection("String"); + + /* + * Timeouts. + */ + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int PARENT_TIME_STAMP_TIMEOUT = 1000; + static final int CHILD_SELECTION_CHANGE_TIMEOUT = + FRAME_ACTIVATION_TIMEOUT + PARENT_TIME_STAMP_TIMEOUT + 5000; + static final int PARENT_RETRIEVE_DATA_TIMEOUT = 10000; + + /* + * Child process return codes. + */ + static final int CHILD_RETURN_CODE_NOT_READY = -1; + static final int CHILD_RETURN_CODE_OK = 0; + static final int CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION = 1; + static final int CHILD_RETURN_CODE_OTHER_FAILURE = 2; + static Button button; + + static void initAndShowGui() { + final Frame frame = new Frame(); + button = new Button("button"); + frame.add(button); + frame.pack(); + frame.setLocation(100, 100); + frame.setVisible(true); + } + + public static void main(String[] args) { + sysClipboard.setContents( + new StringSelection("First String"), null); + + // Some mouse activity to update the Xt time stamp at + // the child process. + try { + EventQueue.invokeAndWait(Child::initAndShowGui); + try { + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + System.exit(CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION); + } + + Robot robot = new Robot(); + robot.waitForIdle(); + + Point p = button.getLocationOnScreen(); + robot.mouseMove(p.x + 10, p.y + 10); + // Wait to let the Xt time stamp become out-of-date. + try { + Thread.sleep(PARENT_TIME_STAMP_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + System.exit(CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION); + } + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } catch (Exception e) { + e.printStackTrace(); + System.exit(CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION); + } + + sysClipboard.setContents(transferable, new ClipboardOwner() { + public void lostOwnership(Clipboard clipboard, + Transferable contents) { + System.exit(CHILD_RETURN_CODE_OK); + } + }); + // Wait to let the parent process retrieve the data. + try { + Thread.sleep(PARENT_RETRIEVE_DATA_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // Parent failed to set clipboard contents, so we signal test failure + System.exit(CHILD_RETURN_CODE_OTHER_FAILURE); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Clipboard/NullContentsTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Clipboard/NullContentsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Clipboard/NullContentsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Clipboard/NullContentsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4378007 4250859 + @summary Verifies that setting the contents of the system Clipboard to null + throws a NullPointerException + @key headful + @run main NullContentsTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; + +public class NullContentsTest { + + public static void main(String[] args) { + // Clipboard.setContents(null, foo) should throw an NPE, but + // Clipboard.setContents(bar, foo), where bar.getTransferData(baz) + // returns null, should not. + Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); + try { + clip.setContents(null, null); + } catch (NullPointerException e) { + StringSelection ss = new StringSelection(null); + try { + clip.setContents(ss, null); + } catch (NullPointerException ee) { + throw new RuntimeException("test failed: null transfer data"); + } + System.err.println("test passed"); + return; + } + throw new RuntimeException("test failed: null Transferable"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4696186 + @summary tests that NotSerializableException is not printed in the console if + non-serializable object with DataFlavor.javaJVMLocalObjectMimeType + is set into the clipboard + @key headful + @run main SerializeLocalFlavorTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; +import java.io.InputStream; +import java.io.Serializable; + + +public class SerializeLocalFlavorTest { + private boolean failed = false; + + public static void main(String[] args) { + new SerializeLocalFlavorTest().start(); + } + + public void start () { + try { + String[] command = { + System.getProperty("java.home", "") + + File.separator + "bin" + File.separator + + "java", + "-cp", + System.getProperty("test.classes", "."), + "Child" + }; + + Process process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + if (pres.stderr.indexOf("java.io.NotSerializableException") >= 0) { + failed = true; + } + + } catch (Exception e) { + e.printStackTrace(); + } + + if (failed) { + throw new RuntimeException( + "The test failed: java.io.NotSerializableException printed!"); + } else { + System.err.println("The test passed!"); + } + } +} + +class Child { + public static void main (String [] args) throws Exception { + NotSerializableLocalTransferable t = + new NotSerializableLocalTransferable(new NotSer()); + Toolkit.getDefaultToolkit() + .getSystemClipboard().setContents(t, null); + } +} + +class NotSerializableLocalTransferable implements Transferable { + public final DataFlavor flavor; + + private final DataFlavor[] flavors; + + private final Object data; + + + public NotSerializableLocalTransferable(Object data) throws Exception { + this.data = data; + flavor = new DataFlavor( + DataFlavor.javaJVMLocalObjectMimeType + + ";class=" + "\"" + data.getClass().getName() + "\""); + this.flavors = new DataFlavor[] { flavor }; + } + + public DataFlavor[] getTransferDataFlavors() { + return flavors.clone(); + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return this.flavor.equals(flavor); + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException + { + if (this.flavor.equals(flavor)) { + return (Object)data; + } + throw new UnsupportedFlavorException(flavor); + } + +} + +class NotSer implements Serializable { + private Object field = new Object(); // not serializable field +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/ColorClass/ColorSerializationTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/ColorClass/ColorSerializationTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/ColorClass/ColorSerializationTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/ColorClass/ColorSerializationTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4330102 + @summary Tests that Color object is serializable + @run main ColorSerializationTest +*/ + +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.IndexColorModel; +import java.io.ObjectOutputStream; +import java.io.ByteArrayOutputStream; + +public class ColorSerializationTest { + + public static void main(String[] args) { + java.awt.Color cobj = new java.awt.Color(255, 255, 255); + try { + cobj.createContext( + new IndexColorModel( + 8, 1, + new byte[]{0}, new byte[]{0}, new byte[]{0}), + new Rectangle(1, 1, 2, 3), + new Rectangle(3, 3), + new AffineTransform(), + new RenderingHints(null)); + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + ObjectOutputStream objos = new ObjectOutputStream(ostream); + objos.writeObject(cobj); + objos.close(); + System.out.println("Test PASSED"); + } catch (java.io.IOException e) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED: Color is not serializable: " + e.getMessage()); + } + + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Component/GetListenersTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Component/GetListenersTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Component/GetListenersTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Component/GetListenersTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4240721 + @summary Test Component.getListeners API added in 1.3 + @key headful + @run main GetListenersTest + */ + +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentListener; +import java.awt.event.ContainerAdapter; +import java.awt.event.ContainerListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusListener; +import java.awt.event.HierarchyBoundsAdapter; +import java.awt.event.HierarchyBoundsListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import java.awt.event.InputMethodEvent; +import java.awt.event.InputMethodListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.TextEvent; +import java.awt.event.TextListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; +import java.awt.event.WindowListener; +import java.awt.event.WindowStateListener; +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.Introspector; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.Method; +import java.util.EventListener; + +public class GetListenersTest { + + public static void main(String args[]) throws Exception { + EventQueue.invokeAndWait(()-> { + // Create frame with a bunch of components + // and test that each component returns + // the right type of listeners from Component.getListeners + GLTFrame gltFrame = new GLTFrame(); + try { + gltFrame.initAndShowGui(); + gltFrame.test(); + } catch (Exception e) { + throw new RuntimeException("Test failed", e); + } finally { + gltFrame.dispose(); + } + }); + } + + /* + * Checks an object has a listener for every support listener type + */ + static void checkForListenersOfEveryType(Object object) throws Exception { + Class type = object.getClass(); + + BeanInfo info = Introspector.getBeanInfo(type); + EventSetDescriptor esets[] = info.getEventSetDescriptors(); + + // ensure there are listeners for every type + for (int nset = 0; nset < esets.length; nset++) { + Class listenerType = esets[nset].getListenerType(); + EventListener listener[] = getListeners(object, listenerType); + // Skip PropertyChangeListener for now + if (listener.length == 0 && validListenerToTest(listenerType)) { + throw new RuntimeException("getListeners didn't return type " + + listenerType); + } + } + + System.out.println("************"); + System.out.println("PASSED: getListeners on " + + object + " has all the right listeners."); + System.out.println("************"); + } + + /* + * Calls getListeners on the object + */ + static EventListener[] getListeners(Object object, Class type) + throws Exception { + Method methods[] = object.getClass().getMethods(); + Method method = null; + + for (int nmethod = 0; nmethod < methods.length; nmethod++) { + if (methods[nmethod].getName().equals("getListeners")) { + method = methods[nmethod]; + break; + } + } + if (method == null) { + throw new RuntimeException("Object " + + object + " has no getListeners method"); + } + Class params[] = {type}; + EventListener listeners[] = null; + listeners = (EventListener[]) method.invoke(object, params); + System.out.println("Listeners of type: " + type + " on " + object); + GetListenersTest.printArray(listeners); + return listeners; + } + + /* + * Adds a listener of every type to the object + */ + static void addDummyListenersOfEveryType(Object object) throws Exception { + Class type = object.getClass(); + + BeanInfo info = Introspector.getBeanInfo(type); + EventSetDescriptor esets[] = info.getEventSetDescriptors(); + + // add every kind of listener + for (int nset = 0; nset < esets.length; nset++) { + Class listenerType = esets[nset].getListenerType(); + EventListener listener = makeListener(listenerType); + Method addListenerMethod = esets[nset].getAddListenerMethod(); + Object params[] = {listener}; + addListenerMethod.invoke(object, params); + } + } + + /* + * Determines what listeners to exclude from the test for now + */ + static boolean validListenerToTest(Class listenerType) { + /* Don't have any provision for PropertyChangeListeners... */ + if ( listenerType == PropertyChangeListener.class ) { + return false; + } + + return true; + } + + static void testGetListeners(Object object) throws Exception { + GetListenersTest.addDummyListenersOfEveryType(object); + GetListenersTest.checkForListenersOfEveryType(object); + } + + static void printArray(Object objects[]) { + System.out.println("{"); + for(int n = 0; n < objects.length; n++) { + System.out.println("\t"+objects[n]+","); + } + System.out.println("}"); + } + + /* + * Makes a dummy listener implementation for the given listener type + */ + static EventListener makeListener(Class listenerType) throws Exception { + Object map[][] = { + {ActionListener.class, MyActionAdapter.class}, + {AdjustmentListener.class, MyAdjustmentAdapter.class}, + {ComponentListener.class, MyComponentAdapter.class}, + {ContainerListener.class, MyContainerAdapter.class}, + {FocusListener.class, MyFocusAdapter.class}, + {HierarchyBoundsListener.class, MyHierarchyBoundsAdapter.class}, + {HierarchyListener.class, MyHierarchyAdapter.class}, + {InputMethodListener.class, MyInputMethodAdapter.class}, + {ItemListener.class, MyItemAdapter.class}, + {KeyListener.class, MyKeyAdapter.class}, + {MouseListener.class, MyMouseAdapter.class}, + {MouseMotionListener.class, MyMouseMotionAdapter.class}, + {MouseWheelListener.class, MyMouseWheelAdapter.class}, + {TextListener.class, MyTextAdapter.class}, + {WindowListener.class, MyWindowAdapter.class}, + {WindowFocusListener.class, MyWindowFocusAdapter.class}, + {WindowStateListener.class, MyWindowStateAdapter.class}, + {PropertyChangeListener.class, MyPropertyChangeAdapter.class}, + }; + + for (int n = 0; n < map.length; n++) { + if (map[n][0] == listenerType) { + Class adapterClass = (Class) map[n][1]; + EventListener listener = + (EventListener) adapterClass.newInstance(); + return listener; + } + } + + throw new RuntimeException("No adapter found for listener type " + + listenerType); + } +} + +class GLTFrame extends Frame { + MenuItem mitem; + CheckboxMenuItem cmitem; + + GLTFrame() { + super("Component.getListeners API Test"); + } + + public void initAndShowGui() { + setLayout(new FlowLayout()); + + add(new Label("Label")); + add(new Button("Button")); + add(new Checkbox("Checkbox")); + Choice c = new Choice(); + c.add("choice"); + java.awt.List l = new java.awt.List(); + l.add("list"); + add(new Scrollbar()); + add(new TextField("TextField")); + add(new TextArea("TextArea")); + add(new Panel()); + add(new Canvas()); + + MenuBar menuBar = new MenuBar(); + Menu menu = new Menu("Menu"); + mitem = new MenuItem("Item 1"); + cmitem = new CheckboxMenuItem("Item 2"); + menu.add(mitem); + menu.add(cmitem); + menuBar.add(menu); + setMenuBar(menuBar); + + pack(); + setVisible(true); + } + + public void test() throws Exception { + // test Frame.getListeners + GetListenersTest.testGetListeners(this); + + // + // test getListeners on menu items + // + GetListenersTest.testGetListeners(mitem); + GetListenersTest.testGetListeners(cmitem); + + // + // test getListeners on all AWT Components + // + Component components[] = getComponents(); + for (int nc = 0; nc < components.length; nc++) { + GetListenersTest.testGetListeners(components[nc]); + } + } +} + +/************************************************ + * Dummy listener implementations we add to our components/models/objects + */ + +class MyPropertyChangeAdapter implements PropertyChangeListener { + public void propertyChange(PropertyChangeEvent evt) {} +} + +class MyActionAdapter implements ActionListener { + public void actionPerformed(ActionEvent ev) { + } +} + +class MyAdjustmentAdapter implements AdjustmentListener { + public void adjustmentValueChanged(AdjustmentEvent e) { + } +} + +class MyHierarchyAdapter implements HierarchyListener { + public void hierarchyChanged(HierarchyEvent e) { + } +} + +class MyInputMethodAdapter implements InputMethodListener { + public void inputMethodTextChanged(InputMethodEvent event) { + } + + public void caretPositionChanged(InputMethodEvent event) { + } +} + +class MyItemAdapter implements ItemListener { + public void itemStateChanged(ItemEvent e) { + } +} + +class MyTextAdapter implements TextListener { + public void textValueChanged(TextEvent e) { + } +} + +class MyComponentAdapter extends ComponentAdapter { +} + +class MyContainerAdapter extends ContainerAdapter { +} + +class MyFocusAdapter extends FocusAdapter { +} + +class MyHierarchyBoundsAdapter extends HierarchyBoundsAdapter { +} + +class MyKeyAdapter extends KeyAdapter { +} + +class MyMouseAdapter extends MouseAdapter { +} + +class MyMouseMotionAdapter extends MouseMotionAdapter { +} + +class MyMouseWheelAdapter implements MouseWheelListener { + public void mouseWheelMoved(MouseWheelEvent e) {} +} + +class MyWindowAdapter extends WindowAdapter { +} + +class MyWindowFocusAdapter implements WindowFocusListener { + public void windowGainedFocus(WindowEvent t) {} + public void windowLostFocus(WindowEvent t) {} +} + +class MyWindowStateAdapter extends WindowAdapter { +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/FindComponentAtTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Container/FindComponentAtTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/FindComponentAtTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Container/FindComponentAtTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4311614 + @summary findComponentAt() should check for isShowing() instead of isVisible() + @key headful +*/ + +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; + +public class FindComponentAtTest { + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + Panel aContainer; + Panel bContainer; + Panel cContainer; + Button button = new Button("button4"); + Frame frame = new Frame("FindComponentAtTest"); + + try { + aContainer = new Panel(); + bContainer = new Panel(); + cContainer = new Panel(); + aContainer.setName("ACONT"); + bContainer.setName("BCONT"); + + frame.add(aContainer); + + aContainer.add(bContainer); + bContainer.add(cContainer); + cContainer.add(button); + + bContainer.setVisible(false); + + frame.setSize(200, 200); + frame.setVisible(true); + frame.validate(); + + System.out.println("Test set for FindComponentAt() method."); + System.out.println("aContainer - visible"); + System.out.println("bContainer - child of aContainer - is invisible"); + System.out.println("cContainer - child of bContainer - is visible"); + System.out.println("button4 - child of cContainer - is visible"); + Component comp = cContainer.findComponentAt( + cContainer.getWidth() / 2, + cContainer.getHeight() / 2); + + if (comp != null) { + throw new RuntimeException( + "cContainer: Visible component inserted into " + + "invisible container have found " + + "by findComponentAt(x, y) method"); + } + } finally { + frame.dispose(); + } + System.out.println("FindComponentAt Test Succeeded."); + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/FindComponentTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Container/FindComponentTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/FindComponentTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Container/FindComponentTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4196100 + @summary Make sure findComponentAt() only returns visible components. + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import javax.swing.JFrame; +import javax.swing.JTabbedPane; +import javax.swing.JPanel; + +public class FindComponentTest { + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + FindComponentFrame findComponentAtTest = new FindComponentFrame(); + + try { + if (!findComponentAtTest.didItWork()) { + throw new RuntimeException( + "findComponentAt() returned non-visible component"); + } + } finally { + findComponentAtTest.dispose(); + } + }); + } +} + + +class FindComponentFrame extends JFrame { + public FindComponentFrame() { + super("FindComponentFrame"); + } + + public boolean didItWork() { + setTitle("FindComponentTest"); + setSize(new Dimension(200, 200)); + + JTabbedPane tabbedpane = new JTabbedPane(); + setContentPane(tabbedpane); + + JPanel panel1 = new JPanel(); + panel1.setName("Panel 1"); + panel1.setLayout(new BorderLayout()); + tabbedpane.add(panel1); + JPanel subPanel = new JPanel(); + subPanel.setName("Sub-Panel"); + subPanel.setBackground(Color.green); + panel1.add(subPanel); // add sub panel to 1st tab + + JPanel panel2 = new JPanel(); + panel2.setName("Panel 2"); + tabbedpane.add(panel2); + + tabbedpane.setSelectedIndex(1); // display 2nd tab + setVisible(true); + + boolean success = tabbedpane.findComponentAt(50,50) + .getName().equals("Panel 2"); + return success; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @summary unit test for ability of FocusTraversalPolicyProvider + @key headful +*/ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Container; +import java.awt.ContainerOrderFocusTraversalPolicy; +import java.awt.DefaultFocusTraversalPolicy; +import java.awt.EventQueue; +import java.awt.FocusTraversalPolicy; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.Window; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.LayoutFocusTraversalPolicy; + +public class FocusTraversalPolicyProviderTest { + final String errorOrderMessage = "Test Failed. Traversal Order not correct."; + final String successStage = "Test stage completed.Passed."; + + final int n_buttons = 4; + final int jumps = 3 * n_buttons; + Container[] cycle_roots = new Container[3]; + Panel[] a_conts = new Panel[cycle_roots.length]; + Panel[] b_conts = new Panel[cycle_roots.length]; + Component[][] a_buttons = new Component[cycle_roots.length][n_buttons]; + Component[][] b_buttons = new Component[cycle_roots.length][n_buttons]; + + static volatile Frame mainFrame = null; + static volatile Frame frame = null; + static volatile JFrame jframe = null; + + static Robot robot; + + public static void main(String[] args) throws Exception { + FocusTraversalPolicyProviderTest test + = new FocusTraversalPolicyProviderTest(); + try { + robot = new Robot(); + EventQueue.invokeAndWait(test::init); + robot.delay(1000); + EventQueue.invokeAndWait(test::testStages); + + EventQueue.invokeAndWait(test::initSwingContInFrame); + robot.delay(1000); + EventQueue.invokeAndWait(test::testSwingContInFrame); + // test for Swing container in java.awt.Frame + System.out.println("Test passed."); + } finally { + EventQueue.invokeAndWait(() -> { + if (mainFrame != null) mainFrame.dispose(); + if (frame != null) frame.dispose(); + if (jframe != null) jframe.dispose(); + }); + } + } + + public void init() { + mainFrame = new Frame("FocusTraversalPolicyProviderTest - main"); + mainFrame.setSize(400, 400); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + + for (int i = 0; i < cycle_roots.length; i++) { + cycle_roots[i] = new Panel(); + cycle_roots[i].setFocusable(false); + cycle_roots[i].setName("root" + i); + cycle_roots[i].setFocusCycleRoot(true); + cycle_roots[i].setLayout (new GridLayout(1, 2)); + mainFrame.add(cycle_roots[i]); + + a_conts[i] = new Panel(); + a_conts[i].setName("ac" + i); + a_conts[i].setFocusable(false); + cycle_roots[i].add(a_conts[i]); + + b_conts[i] = new Panel(); + b_conts[i].setName("bc" + i); + b_conts[i].setFocusable(false); + cycle_roots[i].add(b_conts[i]); + + for (int j = 0; j < n_buttons; j++){ + String name = "a" + i + "x" + j; + a_buttons[i][j] = new Button(name); + a_buttons[i][j].setName(name); + a_conts[i].add(a_buttons[i][j]); + } + + for (int j = 0; j < n_buttons; j++){ + String name = "b" + i + "x" + j; + b_buttons[i][j] = new Button(name); + b_buttons[i][j].setName(name); + b_conts[i].add(b_buttons[i][j]); + } + } + + cycle_roots[0].setFocusTraversalPolicy(new DefaultFocusTraversalPolicy()); + cycle_roots[1].setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy()); + cycle_roots[2].setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); + } + + public void testStages() { + for (int i = 0; i < cycle_roots.length; i++) { + testStage(cycle_roots[i], a_conts[i], b_conts[i], + a_buttons[i], b_buttons[i]); + } + } + + void testStage(Container aFCR, Container aCont, Container bCont, + Component[] a_comps, Component[] b_comps) { + System.out.println("focus cycle root = " + aFCR.getName()); + System.out.println("policy = " + aFCR.getFocusTraversalPolicy()); + System.out.println("aContainer = " + aCont.getName()); + System.out.println("bContainer = " + bCont.getName()); + System.out.println("Both containers are not Providers."); + + Component[] a_comps_backward = revertArray(a_comps); + Component[] b_comps_backward = revertArray(b_comps); + + testForwardStage(aFCR, aCont, bCont, + false, a_comps, false, b_comps); + testBackwardStage(aFCR, aCont, bCont, + false, a_comps_backward, + false, b_comps_backward); + + System.out.println("Both containers are Providers."); + testForwardStage(aFCR, aCont, bCont, + true, a_comps, true, b_comps); + testForwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps), + true, shakeArray(b_comps)); + + testBackwardStage(aFCR, aCont, bCont, + true, a_comps_backward, + true, b_comps_backward); + testBackwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps_backward), + true, shakeArray(b_comps_backward)); + + System.out.println("aContainer.isProvider = true. " + + "bContainer.isProvider = false."); + testForwardStage(aFCR, aCont, bCont, + true, a_comps, false, b_comps); + testForwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps), + false, b_comps); + testBackwardStage(aFCR, aCont, bCont, + true, a_comps_backward, + false, b_comps_backward); + testBackwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps_backward), + false, b_comps_backward); + + System.out.println("aContainer.isProvider = false. " + + "bContainer.isProvider = true."); + testForwardStage(aFCR, aCont, bCont, + false, a_comps, + true, b_comps); + testForwardStage(aFCR, aCont, bCont, + false, a_comps, + true, shakeArray(b_comps)); + testBackwardStage(aFCR, aCont, bCont, + false, a_comps_backward, + true, b_comps_backward); + testBackwardStage(aFCR, aCont, bCont, + false, a_comps_backward, + true, shakeArray(b_comps_backward)); + + System.out.println("Stage completed."); + } + + public void printGoldOrder(Component[] comps) { + String goldOrderStr = ""; + for (int i =0;i < jumps; i++){ + goldOrderStr += " " + comps[i].getName(); + } + System.out.println("GoldOrder: " + goldOrderStr); + } + + public void testForwardStage(Container focusCycleRoot, + Container aContainer, + Container bContainer, + boolean aProvider, Component[] aComps, + boolean bProvider, Component[] bComps) { + System.out.println("test forward traversal"); + System.out.println("\taProvider = " + aProvider); + System.out.println("\tbProvider = " + bProvider); + Component[] goldOrder = new Component[2*aComps.length + bComps.length]; + System.arraycopy(aComps, 0, goldOrder, 0, aComps.length); + System.arraycopy(bComps, 0, goldOrder, + aComps.length, bComps.length); + System.arraycopy(aComps, 0, goldOrder, + aComps.length + bComps.length, + aComps.length); + printGoldOrder(goldOrder); + + String jumpStr = ""; + aContainer.setFocusTraversalPolicyProvider(aProvider); + aContainer.setFocusTraversalPolicy( + new ArrayOrderFocusTraversalPolicy(aContainer, aComps)); + bContainer.setFocusTraversalPolicyProvider(bProvider); + bContainer.setFocusTraversalPolicy( + new ArrayOrderFocusTraversalPolicy(bContainer, bComps)); + FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy(); + System.out.println("policy=" + policy); + Component current = policy.getFirstComponent(focusCycleRoot); + + for (int i = 0;i= 0) { + return comps[current_index]; + } + + if (focusCycleRoot.isFocusCycleRoot()) { + return getLastComponent(focusCycleRoot); + } else { + return null; + } + } + + public Component getFirstComponent(Container focusCycleRoot) { + checkContainer(focusCycleRoot); + return comps[0]; + } + + public Component getLastComponent(Container focusCycleRoot) { + checkContainer(focusCycleRoot); + return comps[comps.length - 1]; + } + + public Component getDefaultComponent(Container focusCycleRoot) { + return getFirstComponent(focusCycleRoot); + } + + public Component getInitialComponent(Window window) { + throw new UnsupportedOperationException("getInitialComponent() is not supported."); + } + + public Component[] getCycle(Container focusCycleRoot) { + checkContainer(focusCycleRoot); + Component[] temp = new Component[comps.length]; + System.arraycopy(comps, 0, temp, 0, comps.length); + return temp; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java openjdk-17-17.0.8+7/test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4852790 + @summary Frame disposal must remove opened popup without exception + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JMenuBar; +import javax.swing.JPanel; + + +public class OpenedPopupFrameDisposal { + public static final int SIZE = 300; + + volatile JFrame jf = null; + volatile JComboBox jcb = null; + + public void start() { + jf = new JFrame("OpenedPopupFrameDisposal - Frame to dispose"); + // Note that original bug cannot be reproduced without JMenuBar present. + jf.setJMenuBar(new JMenuBar()); + jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + jf.setLocationRelativeTo(null); + jf.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent evt) { + jf.setVisible(false); + jf.dispose(); + } + }); + + + JPanel panel = new JPanel(new FlowLayout()); + jcb = new JComboBox<>(); + jcb.addItem("one"); + jcb.addItem("two"); + jcb.addItem("Three"); + panel.add(jcb); + + jf.getContentPane().add(panel, BorderLayout.CENTER); + jf.pack(); + jf.setSize(new Dimension(SIZE, SIZE)); + + jf.setVisible(true); + + } + + public void test() throws Exception { + Robot robot = new Robot(); + robot.delay(1000); // wait for jf visible + Point pt = jf.getLocationOnScreen(); + + int x, y; + + x = pt.x + SIZE / 2; + y = pt.y + SIZE / 2; + + robot.mouseMove(x, y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + + pt = jcb.getLocationOnScreen(); + x = pt.x + jcb.getWidth() / 2; + y = pt.y + jcb.getHeight() / 2; + + robot.mouseMove(x, y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + + // Here on disposal we had a NullPointerException + EventQueue.invokeAndWait(() -> { + if (jf != null) { + jf.setVisible(false); + jf.dispose(); + } + }); + } + + public static void main(String[] args) throws Exception { + OpenedPopupFrameDisposal imt = new OpenedPopupFrameDisposal(); + try { + EventQueue.invokeAndWait(imt::start); + imt.test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (imt.jf != null) { + imt.jf.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/PropertyEventsTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Container/PropertyEventsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/PropertyEventsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Container/PropertyEventsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @summary unit test for ability of FocusTraversalPolicyProvider +*/ + +import java.awt.Container; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class PropertyEventsTest implements PropertyChangeListener { + final String PROPERTY = "focusTraversalPolicyProvider"; + + + public static void main(String[] args) throws Exception { + new PropertyEventsTest().start(); + } + + public void start () { + Container c1 = new Container(); + c1.addPropertyChangeListener(PROPERTY, this); + + assertEquals("Container shouldn't be a provider by default", + false, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(false, true); + c1.setFocusTraversalPolicyProvider(true); + assertEventOccured(); + assertEquals("Policy provider property was not set.", + true, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(true, false); + c1.setFocusTraversalPolicyProvider(false); + assertEventOccured(); + assertEquals("Policy provider property was not reset.", + false, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(false, true); + c1.setFocusCycleRoot(true); + assertEventMissed(); + assertEquals("Cycle root shouldn't be a policy provider.", + false, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(true, false); + c1.setFocusCycleRoot(false); + assertEventMissed(); + assertEquals("setFocusCycleRoot(false) should reset " + + "policy provider property.", + false, c1.isFocusTraversalPolicyProvider()); + + System.out.println("Test passed."); + }// start() + + void assertEquals(String msg, boolean expected, boolean actual) { + if (expected != actual) { + Assert(msg + "(expected=" + expected + ", actual=" + actual + ")"); + } + } + + void assertEquals(String msg, Object expected, Object actual) { + if ((expected != null && !expected.equals(actual)) + || (actual != null && !actual.equals(expected))) + { + Assert(msg + "(expected=" + expected + ", actual=" + actual + ")"); + } + } + + void Assert(String msg) { + throw new RuntimeException(msg); + } + + void prepareForEvent(boolean old_val, boolean new_val) { + property_change_fired = false; + expected_new_value = Boolean.valueOf(new_val); + expected_old_value = Boolean.valueOf(old_val); + } + + void assertEventOccured() { + if (!property_change_fired) { + Assert("Property Change Event missed."); + } + } + + void assertEventMissed() { + if (property_change_fired) { + Assert("Unexpected property change event."); + } + } + + boolean property_change_fired; + Boolean expected_new_value; + Boolean expected_old_value; + + public void propertyChange(PropertyChangeEvent e) { + System.out.println("PropertyChangeEvent[property=" + e.getPropertyName() + + ", new=" + e.getNewValue() + + ", old=" + e.getOldValue() + "]"); + + assertEquals("Wrong proeprty name.", + PROPERTY, e.getPropertyName()); + assertEquals("Wrong new value.", + expected_new_value, e.getNewValue()); + assertEquals("Wrong old value.", + expected_old_value, e.getOldValue()); + property_change_fired = true; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4546535 + @summary java.awt.Container.remove(int) throws unexpected NPE +*/ + +import java.awt.Canvas; +import java.awt.Panel; + +public class RemoveByIndexExceptionTest { + + public static void main(String[] args) throws Exception { + Panel p = new Panel(); + p.add(new Canvas()); + p.remove(0); + + int[] bad = {-1, 0, 1}; + for (int i = 0; i < bad.length; i++) { + try { + System.out.println("Removing " + bad[i]); + p.remove(bad[i]); + System.out.println("No exception"); + } catch (ArrayIndexOutOfBoundsException e) { + e.printStackTrace(); + System.out.println("This is correct exception - " + e); + } catch (NullPointerException e) { + e.printStackTrace(); + throw new RuntimeException("Test Failed: NPE was thrown."); + } + } + System.out.println("Test Passed."); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/ShowingChangedEventTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Container/ShowingChangedEventTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Container/ShowingChangedEventTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Container/ShowingChangedEventTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4924516 + @summary Verifies that SHOWING_CHANGED event is propagated to \ + HierarchyListeners then toolkit enabled + @key headful +*/ + + +import java.awt.AWTEvent; +import java.awt.EventQueue; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + +public class ShowingChangedEventTest + implements AWTEventListener, HierarchyListener{ + private boolean eventRegisteredOnButton = false; + + private final JFrame frame = new JFrame("ShowingChangedEventTest"); + private final JPanel panel = new JPanel(); + private final JButton button = new JButton(); + + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + ShowingChangedEventTest showingChangedEventTest + = new ShowingChangedEventTest(); + + try { + showingChangedEventTest.start(); + } finally { + showingChangedEventTest.frame.dispose(); + } + }); + } + + public void start () { + frame.getContentPane().add(panel); + panel.add(button); + + frame.pack(); + frame.setVisible(true); + + Toolkit.getDefaultToolkit() + .addAWTEventListener(this, AWTEvent.HIERARCHY_EVENT_MASK); + + button.addHierarchyListener(this); + panel.setVisible(false); + + if (!eventRegisteredOnButton){ + throw new RuntimeException("Event wasn't registered on Button."); + } + } + + @Override + public void eventDispatched(AWTEvent awtevt) { + if (awtevt instanceof HierarchyEvent) { + HierarchyEvent hevt = (HierarchyEvent) awtevt; + if (hevt != null && (hevt.getChangeFlags() + & HierarchyEvent.SHOWING_CHANGED) != 0) { + System.out.println("Hierarchy event was received on Toolkit. " + + "SHOWING_CHANGED for " + + hevt.getChanged().getClass().getName()); + } + } + } + + @Override + public void hierarchyChanged(HierarchyEvent e) { + if ((HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags()) != 0) { + System.out.println("Hierarchy event was received on Button. " + + "SHOWING_CHANGED for " + + e.getChanged().getClass().getName()); + } + eventRegisteredOnButton = true; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/datatransfer/MimeFormatsTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/datatransfer/MimeFormatsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/datatransfer/MimeFormatsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/datatransfer/MimeFormatsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,288 @@ +/* + * 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 4859006 + @summary tests that MIME formats are mapped to flavors properly on X11 + @requires (os.family == "linux") + @key headful + @run main MimeFormatsTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.FlavorMap; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.SystemFlavorMap; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; + + +public class MimeFormatsTest implements ClipboardOwner { + public static final DataFlavor TEST_FLAVOR = + new DataFlavor( + "text/test;charset=UTF-8;class=java.io.InputStream", + null); + + public static class TextTransferable implements Transferable { + private final String text; + + public TextTransferable(String text) { + this.text = text; + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + if (!isDataFlavorSupported(TEST_FLAVOR)) { + throw new UnsupportedFlavorException(flavor); + } + + return new ByteArrayInputStream( + text.getBytes(StandardCharsets.UTF_8)); + } + + public DataFlavor[] getTransferDataFlavors(){ + return new DataFlavor[] { TEST_FLAVOR }; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return TEST_FLAVOR.equals(flavor); + } + } + + public static final String DATA = + "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"; + + private String testData = null; + + private static final Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + + public void childRun() { + Transferable t = clipboard.getContents(null); + String data = ""; + try { + data = (String)t.getTransferData(DataFlavor.stringFlavor); + } catch (Exception e) { + e.printStackTrace(); + } + System.err.println("contents size=" + data.length()); + for (int i = 0; i < data.length(); i++) { + System.err.println(" char[" + i + "]=" + (int) data.charAt(i)); + } + ClipboardOwner owner = new ClipboardOwner() { + public void lostOwnership(Clipboard clipboard, + Transferable contents) { + System.err.println("%d exit".formatted( + System.currentTimeMillis())); + System.err.println("Exiting"); + System.exit(0); + } + }; + clipboard.setContents(new StringSelection(data + data), owner); + + Object lock = new Object(); + synchronized (lock) { + // Wait to let the parent retrieve the contents. + try { + System.err.println("%d wait".formatted( + System.currentTimeMillis())); + lock.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public void start() { + FlavorMap fm = SystemFlavorMap.getDefaultFlavorMap(); + if (fm instanceof SystemFlavorMap) { + SystemFlavorMap sfm = (SystemFlavorMap)fm; + String mimeNative = "text/plain;charset=UTF-8"; + sfm.setNativesForFlavor(TEST_FLAVOR, + new String[] { mimeNative }); + sfm.setFlavorsForNative(mimeNative, + new DataFlavor[] { TEST_FLAVOR }); + } else { + System.err.println("WARNING: system flavor map: " + fm); + return; + } + + clipboard.setContents(new TextTransferable(DATA), this); + + try { + String javaPath = System.getProperty("java.home", ""); + String[] command = { + javaPath + File.separator + "bin" + File.separator + "java", + "-cp", + System.getProperty("test.classes", "."), + "Child" + }; + + Process process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + + int returnCode = pres.exitValue; + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + System.err.println("Child return code=" + returnCode); + } catch (Throwable e) { + e.printStackTrace(); + } + + System.err.println("Received data size=" + testData.length()); + for (int i = 0; i < testData.length(); i++) { + System.err.println(" char[" + i + "]=" + (int)testData.charAt(i)); + } + + if (!testData.equals(DATA + DATA)) { + throw new RuntimeException(); + } + } + + public void lostOwnership(Clipboard clip, Transferable contents) { + Runnable r = new Runnable() { + public void run() { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Transferable t = clipboard.getContents(null); + try { + InputStream is = + (InputStream)t.getTransferData(TEST_FLAVOR); + Reader r = new InputStreamReader(is, + StandardCharsets.UTF_8); + StringBuffer sb = new StringBuffer(); + int ch = 0; + while ((ch = r.read()) != -1) { + System.err.println("ch=" + ch); + sb.append((char)ch); + } + testData = sb.toString(); + } catch (Exception e) { + e.printStackTrace(); + } + clipboard.setContents(new TextTransferable(""), null); + } + }; + new Thread(r).start(); + } + + public static void main(String[] args) { + if (!System.getProperty("os.name").startsWith("Linux")) { + return; + } + + MimeFormatsTest mimeFormatsTest = new MimeFormatsTest(); + mimeFormatsTest.start(); + } +} + +class Child { + public static void main(String[] args) { + MimeFormatsTest test = new MimeFormatsTest(); + test.childRun(); + } +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/datatransfer/RemoveFlavorListenerTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/datatransfer/RemoveFlavorListenerTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/datatransfer/RemoveFlavorListenerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/datatransfer/RemoveFlavorListenerTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 6194489 + @summary tests that removeFlavorListener does not throw an exception in any case. + @key headful + @run main RemoveFlavorListenerTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.FlavorEvent; +import java.awt.datatransfer.FlavorListener; + +public class RemoveFlavorListenerTest { + + public static void main(String[] args) { + try { + FlavorListener fl = new FlavorListener() { + public void flavorsChanged(FlavorEvent e) {} + }; + Toolkit.getDefaultToolkit() + .getSystemClipboard().removeFlavorListener(fl); + } catch (NullPointerException e) { + throw new RuntimeException("NullPointerException, test case failed", + e); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java openjdk-17-17.0.8+7/test/jdk/java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 2023-07-05 07:11:54.000000000 +0000 @@ -46,6 +46,10 @@ private static Frame f; private static Dialog d; + // move away from cursor + private final static int OFFSET_X = -20; + private final static int OFFSET_Y = -20; + public static void main(String[] args) throws Exception { Robot r = Util.createRobot(); @@ -101,7 +105,7 @@ Util.waitForIdle(r); - Color c = r.getPixelColor(p.x + f.getWidth() / 2, p.y + f.getHeight() / 2); + Color c = r.getPixelColor(p.x + f.getWidth() / 2 - OFFSET_X, p.y + f.getHeight() / 2 - OFFSET_Y); System.out.println("Color = " + c); String exceptionMessage = null; diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/AutoscrollStopTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/AutoscrollStopTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/AutoscrollStopTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/AutoscrollStopTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4516490 + @summary verifies that autoscroll is stopped when the drop happens + @key headful + @run main AutoscrollStopTest +*/ + + +import java.awt.AWTException; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.Autoscroll; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; + + +public class AutoscrollStopTest extends Frame implements Autoscroll { + static volatile AutoscrollStopTest test = null; + + volatile boolean dropHappened = false; + + final DragSource dragSource = DragSource.getDefaultDragSource(); + final Transferable transferable = new StringSelection("TEXT"); + final DragGestureListener dragGestureListener = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, transferable); + } + }; + final DragGestureRecognizer dragGestureRecognizer = + dragSource.createDefaultDragGestureRecognizer( + this, DnDConstants.ACTION_COPY_OR_MOVE, + dragGestureListener); + + final DropTargetListener dropTargetListener = new DropTargetAdapter() { + public void drop(DropTargetDropEvent e) { + e.rejectDrop(); + dropHappened = true; + } + }; + + final DropTarget dropTarget = new DropTarget(this, dropTargetListener); + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + test = new AutoscrollStopTest(); + test.createUI(); + }); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(test::dispose); + } + } + + public static int sign(int n) { + return Integer.compare(n, 0); + } + + public void createUI() { + setTitle("AutoscrollStopTest"); + setMinimumSize(new Dimension(200, 200)); + setLocationRelativeTo(null); + setVisible(true); + } + + public void start() throws AWTException { + final Robot robot = new Robot(); + try { + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.waitForIdle(); + robot.delay(1000); + + final Point srcPoint = this.getLocationOnScreen(); + final Dimension d = this.getSize(); + srcPoint.translate(d.width / 2, d.height / 2); + + final Point dstPoint = new Point(srcPoint); + dstPoint.translate(d.width / 4, d.height / 4); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + } + } finally { + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + } + + public Insets getAutoscrollInsets() { + final Dimension d = this.getSize(); + return new Insets(d.height / 2, d.width / 2, + d.height / 2, d.width / 2); + } + + public void autoscroll(Point cursorLocation) { + if (dropHappened) { + throw new RuntimeException("Test failed"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/ButtonReleaseTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/ButtonReleaseTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/ButtonReleaseTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/ButtonReleaseTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4215643 + @summary Tests that the drag source receives mouseReleased event + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + + +public class ButtonReleaseTest { + + static volatile ButtonPanelFrame buttonPanelFrame; + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int DROP_COMPLETION_TIMEOUT = 4000; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(20); + + try { + EventQueue.invokeAndWait(() -> { + buttonPanelFrame = new ButtonPanelFrame(); + buttonPanelFrame.pack(); + buttonPanelFrame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + Point p = buttonPanelFrame.getButtonLocation(); + Dimension d = buttonPanelFrame.getButtonSize(); + p.translate(d.width / 2, d.height / 2); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (int i = 0; i < d.width; i++) { + p.translate(0, 1); + robot.mouseMove(p.x, p.y); + } + + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + try { + Thread.sleep(DROP_COMPLETION_TIMEOUT); + } catch (InterruptedException e) { + throw new RuntimeException("The test failed."); + } + + if (!buttonPanelFrame.passed()) { + throw new RuntimeException( + "The test failed - mouse release was not received."); + } + + } finally { + EventQueue.invokeAndWait(buttonPanelFrame::dispose); + } + } +} + +class ButtonPanelFrame extends Frame { + + DnDSource dragSource; + DnDTarget dropTarget; + + ButtonPanelFrame() { + Panel mainPanel; + + setTitle("ButtonReleaseTest - ButtonPanelFrame"); + setSize(200, 200); + setLocationRelativeTo(null); + setLayout(new BorderLayout()); + + mainPanel = new Panel(); + mainPanel.setLayout(new BorderLayout()); + + mainPanel.setBackground(Color.black); + + dropTarget = new DnDTarget(Color.red, Color.yellow); + dragSource = new DnDSource("Drag ME!"); + + mainPanel.add(dragSource, "North"); + mainPanel.add(dropTarget, "Center"); + add(mainPanel, BorderLayout.CENTER); + } + + boolean passed() { + return dragSource.passed(); + } + + Point getButtonLocation() { + return dragSource.getLocationOnScreen(); + } + + Dimension getButtonSize() { + return dragSource.getSize(); + } +} + +class DnDSource extends Button implements Serializable, Transferable, + DragGestureListener, + DragSourceListener { + + private transient DataFlavor df; + private transient int dropAction; + volatile boolean released = false; + + DnDSource(String label) { + super(label); + + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + synchronized(this) { + released = true; + notifyAll(); + } + } + }); + setBackground(Color.yellow); + setForeground(Color.blue); + + df = new DataFlavor(DnDSource.class, "DnDSource"); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, this, this); + } + + + public void dragEnter(DragSourceDragEvent dsde) { + dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop); + } + + public void dragOver(DragSourceDragEvent dsde) { + } + + public void dragGestureChanged(DragSourceDragEvent dsde) { + } + + public void dragExit(DragSourceEvent dsde) { + dsde.getDragSourceContext().setCursor(null); + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { df }; + } + + public boolean isDataFlavorSupported(DataFlavor sdf) { + return df.equals(sdf); + } + + public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException , IOException { + + Object copy = null; + + if (!df.equals(tdf)) { + throw new UnsupportedFlavorException(tdf); + } + + Container parent = getParent(); + switch (dropAction) { + case DnDConstants.ACTION_COPY: + try { + copy = this.clone(); + } catch (CloneNotSupportedException e) { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(this); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + + try { + copy = ois.readObject(); + } catch (ClassNotFoundException cnfe) { + // do nothing + } + } + return copy; + + case DnDConstants.ACTION_MOVE: + synchronized(this) { + if (parent != null) parent.remove(this); + } + return this; + + case DnDConstants.ACTION_LINK: + return this; + + default: + return this; + } + } + + boolean passed() { + return !released; + } +} + +class DnDTarget extends Panel implements DropTargetListener { + + Color bgColor; + Color htColor; + + DnDTarget(Color bgColor, Color htColor) { + super(); + this.bgColor = bgColor; + this.htColor = htColor; + setBackground(bgColor); + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return new Dimension(200, 200); + } + + public void dragEnter(DropTargetDragEvent e) { + e.acceptDrag(DnDConstants.ACTION_COPY); + setBackground(htColor); + repaint(); + } + + public void dragOver(DropTargetDragEvent e) { + e.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void dragExit(DropTargetEvent e) { + setBackground(bgColor); + repaint(); + } + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + return; + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + Object obj = null; + + try { + obj = transfer.getTransferData(dfs[0]); + } catch (IOException | UnsupportedFlavorException e) { + System.err.println(e.getMessage()); + dtc.dropComplete(false); + return; + } + + if (obj != null) { + Button button = null; + + try { + button = (Button)obj; + } catch (Exception e) { + System.err.println(e.getMessage()); + dtc.dropComplete(false); + return; + } + add(button); + repaint(); + } + } + + setBackground(bgColor); + invalidate(); + validate(); + repaint(); + dtc.dropComplete(true); + } + + public void dragScroll(DropTargetDragEvent e) { + } + + public void dropActionChanged(DropTargetDragEvent e) { + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DnDAWTLockTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DnDAWTLockTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DnDAWTLockTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DnDAWTLockTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,408 @@ +/* + * 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 4913349 + @summary verifies that AWT_LOCK is properly taken during DnD + @key headful + @run main DnDAWTLockTest +*/ + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.InputStream; +import java.util.StringTokenizer; + + +public class DnDAWTLockTest implements ClipboardOwner { + public static final int STARTUP_TIMEOUT = 2000; + volatile Frame frame; + + static final Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + + volatile Process process = null; + volatile Point sourcePoint = null; + + public static void main(String[] args) throws Exception { + DnDAWTLockTest test = new DnDAWTLockTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> test.frame.dispose()); + } + } + + public void init() { + frame = new Frame("Drop target frame"); + frame.setLocation(200, 200); + Panel panel = new DragSourcePanel(); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + } + + public void start() throws Exception { + String stderr = null; + + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + Point p = frame.getLocationOnScreen(); + Dimension d = frame.getSize(); + + Point pp = new Point(p); + pp.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, pp, frame)) { + System.err.println("WARNING: Couldn't locate " + frame + + " at point " + pp); + return; + } + + sourcePoint = pp; + clipboard.setContents(new StringSelection(Util.TRANSFER_DATA), + this); + + String javaPath = System.getProperty("java.home", ""); + String[] command = { + javaPath + File.separator + "bin" + File.separator + "java", + "-cp", System.getProperty("test.classes", "."), + "Child" + }; + + process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + + stderr = pres.stderr; + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + System.err.println("Child VM return code: " + pres.exitValue); + + if (stderr != null && stderr.contains("InternalError")) { + throw new RuntimeException("Test failed"); + } + } + + public void lostOwnership(Clipboard c, Transferable trans) { + Runnable r = new Runnable() { + public void run() { + try { + if (process == null) { + throw new RuntimeException("Null process"); + } + + if (sourcePoint == null) { + throw new RuntimeException("Null point"); + } + + Thread.sleep(STARTUP_TIMEOUT); + Transferable t = clipboard.getContents(null); + + String s = + (String) t.getTransferData(DataFlavor.stringFlavor); + StringTokenizer st = new StringTokenizer(s); + + int x = Integer.parseInt(st.nextToken()); + int y = Integer.parseInt(st.nextToken()); + + Point targetPoint = new Point(x, y); + + Robot robot = new Robot(); + + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (; !sourcePoint.equals(targetPoint); + sourcePoint.translate( + sign(targetPoint.x - sourcePoint.x), + sign(targetPoint.y - sourcePoint.y) + )) { + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.delay(25); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } catch (Exception e) { + e.printStackTrace(); + process.destroy(); + } + } + }; + new Thread(r).start(); + } + + public static int sign(int n) { + return Integer.compare(n, 0); + } +} + +class Child { + public static final int ACTION_TIMEOUT = 30000; + + volatile Frame frame; + volatile Panel panel; + + + public void init() { + panel = new DropTargetPanel(); + + frame = new Frame("Drag source frame"); + frame.setLocation(500, 200); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + } + + public void run() { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + Point targetPoint = panel.getLocationOnScreen(); + Dimension d = panel.getSize(); + targetPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, targetPoint, panel)) { + System.err.println("WARNING: Couldn't locate " + panel + + " at point " + targetPoint); + System.exit(0); + } + + String positionData = "" + targetPoint.x + " " + targetPoint.y; + DnDAWTLockTest.clipboard.setContents( + new StringSelection(positionData), null); + + Thread.sleep(ACTION_TIMEOUT); + } catch (Throwable e) { + e.printStackTrace(); + } + System.exit(0); + } + + public static void main(String[] args) throws Exception { + Child child = new Child(); + EventQueue.invokeAndWait(child::init); + try { + child.run(); + } finally { + EventQueue.invokeAndWait(() -> child.frame.dispose()); + } + } +} + +class Util implements AWTEventListener { + private static final Toolkit tk = Toolkit.getDefaultToolkit(); + public static final Object SYNC_LOCK = new Object(); + private Component clickedComponent = null; + private static final int PAINT_TIMEOUT = 10000; + private static final int MOUSE_RELEASE_TIMEOUT = 10000; + private static final Util util = new Util(); + public static final String TRANSFER_DATA = "TRANSFER_DATA"; + + static { + tk.addAWTEventListener(util, 0xFFFFFFFF); + } + + private void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + public static boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + return util.isPointInComponent(robot, p, comp); + } + + private boolean isPointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + tk.sync(); + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } +} + +class DragSourcePanel extends Panel { + public DragSourcePanel() { + final Transferable t = new StringSelection(Util.TRANSFER_DATA); + final DragGestureListener dgl = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, t); + } + }; + final DragSource ds = DragSource.getDefaultDragSource(); + final DragGestureRecognizer dgr = + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + dgl); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } +} + +class DropTargetPanel extends Panel { + public DropTargetPanel() { + final DropTargetListener dtl = new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) { + Transferable t = dtde.getTransferable(); + dtde.acceptDrop(dtde.getDropAction()); + try { + t.getTransferData(DataFlavor.stringFlavor); + } catch (Exception e) { + e.printStackTrace(); + } + dtde.dropComplete(true); + EventQueue.invokeLater(new Runnable() { + public void run() { + System.exit(0); + } + }); + } + }; + final DropTarget dt = new DropTarget(this, dtl); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragGestureInvokeLaterTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragGestureInvokeLaterTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragGestureInvokeLaterTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragGestureInvokeLaterTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4354044 + @summary tests that a drag can be initiated with MOUSE_MOVED event + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.event.InputEvent; + +public class DragGestureInvokeLaterTest { + + volatile Frame frame; + volatile DragSourcePanel panel; + + public static void main(String[] args) throws Exception { + DragGestureInvokeLaterTest test = + new DragGestureInvokeLaterTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> test.frame.dispose()); + } + } + + public void init() { + panel = new DragSourcePanel(); + frame = new Frame("DragGestureInvokeLaterTest frame"); + frame.setSize(200, 200); + frame.setLocation(200, 200); + frame.add(panel); + frame.setVisible(true); + } + + public void start() throws Exception { + Robot robot = new Robot(); + + robot.waitForIdle(); + robot.delay(1000); + + Point loc = panel.getLocationOnScreen(); + + robot.mouseMove(loc.x + 2, loc.y + 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + + for (int i = 0; i < 10; i++) { + robot.delay(100); + robot.mouseMove(loc.x + 2 + i, loc.y + 2 + i); + } + + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + } +} + +class DragSourcePanel extends Panel + implements DragSourceListener, DragGestureListener { + + DragSource ds; + DragGestureRecognizer dgr; + + public DragSourcePanel() { + ds = new DragSource(); + dgr = ds.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY_OR_MOVE, this); + } + + public void dragGestureRecognized(DragGestureEvent e) { + Runnable dragThread = new DragThread(e); + EventQueue.invokeLater(dragThread); + } + + class DragThread implements Runnable { + + DragGestureEvent event; + + public DragThread(DragGestureEvent e) { + event = e; + } + + public void run() { + try { + event.startDrag(DragSource.DefaultCopyNoDrop, + new StringSelection("Test"), DragSourcePanel.this); + } catch (InvalidDnDOperationException e) { + System.out.println("The test PASSED"); + return; + } + throw new RuntimeException( + "Test failed, InvalidDnDOperationException is not thrown"); + } + } + + public void dragEnter(DragSourceDragEvent e) {} + + public void dragOver(DragSourceDragEvent e) {} + + public void dropActionChanged(DragSourceDragEvent e) {} + + public void dragExit(DragSourceEvent e) {} + + public void dragDropEnd(DragSourceDropEvent e) {} +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragOverDropTargetPerformanceTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragOverDropTargetPerformanceTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragOverDropTargetPerformanceTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragOverDropTargetPerformanceTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4445747 + @summary tests that drag over drop target is not very slow on Win9X/WinME + @key headful +*/ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.io.Serializable; + +public class DragOverDropTargetPerformanceTest { + + Frame frame; + volatile DragSourceButton dragSourceButton; + volatile DropTargetPanel dropTargetPanel; + + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int DROP_COMPLETION_TIMEOUT = 1000; + + public static void main(String[] args) throws Exception { + DragOverDropTargetPerformanceTest test = + new DragOverDropTargetPerformanceTest(); + + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(()-> test.frame.dispose()); + } + } + + public void init() { + dragSourceButton = new DragSourceButton(); + dropTargetPanel = new DropTargetPanel(); + + frame = new Frame(); + frame.setTitle("DragOverDropTargetPerformanceTest frame"); + frame.setLocation(200, 200); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourceButton); + frame.add(dropTargetPanel); + + frame.pack(); + frame.setVisible(true); + } + + public static int sign(int n) { + return Integer.compare(n, 0); + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(10); + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + Point srcPoint = dragSourceButton.getLocationOnScreen(); + Dimension d = dragSourceButton.getSize(); + srcPoint.translate(d.width / 2, d.height / 2); + + Point dstPoint = dropTargetPanel.getLocationOnScreen(); + d = dropTargetPanel.getSize(); + dstPoint.translate(d.width / 2, d.height / 2); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + robot.delay(DROP_COMPLETION_TIMEOUT); + + long dstime = dragSourceButton.getDragSourceTime(); + long dttime = dragSourceButton.getDropTargetTime(); + if (dstime == 0 || dttime == 0) { + System.err.println( + "WARNING: couldn't emulate DnD to measure performance."); + } else if (dttime > dstime * 4) { + throw new RuntimeException("The test failed." + + "Over drag source: " + dstime + "." + + "Over drop target: " + dttime); + } + } +} + +class DragSourceButton extends Button implements Serializable, + Transferable, + DragGestureListener, + DragSourceListener { + private final DataFlavor dataflavor = + new DataFlavor(Button.class, "DragSourceButton"); + private volatile long dsTime = 0; + private volatile long dtTime = 0; + + public DragSourceButton() { + this("DragSourceButton"); + } + + public DragSourceButton(String str) { + super(str); + + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + try { + dge.startDrag(null, this, this); + dsTime = System.currentTimeMillis(); + } catch (InvalidDnDOperationException e) { + e.printStackTrace(); + } + } + + public void dragEnter(DragSourceDragEvent dsde) { + long currentTime = System.currentTimeMillis(); + dsTime = currentTime - dsTime; + dtTime = currentTime; + } + + public void dragExit(DragSourceEvent dse) {} + + public void dragOver(DragSourceDragEvent dsde) {} + + public void dragDropEnd(DragSourceDropEvent dsde) { + long currentTime = System.currentTimeMillis(); + dtTime = currentTime - dtTime; + } + + public void dropActionChanged(DragSourceDragEvent dsde) {} + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + return this; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataflavor }; + } + + public boolean isDataFlavorSupported(DataFlavor dflavor) { + return dataflavor.equals(dflavor); + } + + public long getDragSourceTime() { + return dsTime; + } + + public long getDropTargetTime() { + return dtTime; + } +} + +class DropTargetPanel extends Panel { + + final Dimension preferredDimension = new Dimension(200, 200); + final DropTargetListener dtl = new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) { + dtde.rejectDrop(); + } + }; + + public DropTargetPanel() { + setDropTarget(new DropTarget(this, dtl)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragSourceDragEventModifiersTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragSourceDragEventModifiersTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragSourceDragEventModifiersTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragSourceDragEventModifiersTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,273 @@ +/* + * 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 4924527 + @summary tests DragSourceDragEvent.getGestureModifiers[Ex]() \ + for valid and invalid modifiers + @key headful +*/ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Point; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceContext; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.event.InputEvent; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; + +public class DragSourceDragEventModifiersTest { + boolean failed; + + static class DummyImage extends Image { + public DummyImage() {} + public int getWidth(ImageObserver observer) {return 0;} + public int getHeight(ImageObserver observer){return 0;} + public ImageProducer getSource() {return null;} + public Graphics getGraphics() {return null;} + public void flush() {} + + public Object getProperty(String name, ImageObserver observer) { + return null; + } + } + + static class DummyDGRecognizer extends DragGestureRecognizer { + private final DragSource dragSource; + private final Component component; + + public DummyDGRecognizer(DragSource ds,Component c) { + super(ds,c); + component = c; + dragSource = ds; + } + + public void addDragGestureListener(DragGestureListener dgl) {} + public void appendEvent(InputEvent awtie) {} + public void fireDragGestureRecognized(int dragAction, Point p) {} + public Component getComponent() {return component;} + public DragSource getDragSource() {return dragSource;} + public int getSourceActions() {return DnDConstants.ACTION_COPY_OR_MOVE;} + public InputEvent getTriggerEvent() {return null;} + public void registerListeners() {} + public void removeDragGestureListener(DragGestureListener dgl) {} + public void resetRecognizer() {} + public void setComponent(Component c) {} + public void setSourceActions(int actions) {} + public void unregisterListeners() {} + } + + + DragSource ds = new DragSource(); + + int[] actions = { + DnDConstants.ACTION_NONE, + DnDConstants.ACTION_COPY, + DnDConstants.ACTION_MOVE, + DnDConstants.ACTION_COPY_OR_MOVE, + DnDConstants.ACTION_LINK, + DnDConstants.ACTION_REFERENCE + }; + + Cursor[] cursors = { + DragSource.DefaultCopyDrop, + DragSource.DefaultMoveDrop, + DragSource.DefaultLinkDrop, + DragSource.DefaultCopyNoDrop, + DragSource.DefaultMoveNoDrop, + DragSource.DefaultLinkNoDrop + }; + + DummyImage image = new DummyImage(); + + Point point = new Point(0,0); + + Transferable transferable = new Transferable() { + public DataFlavor[] getTransferDataFlavors() {return null;} + public boolean isDataFlavorSupported(DataFlavor flavor) {return false;} + public Object getTransferData(DataFlavor flavor) {return null;} + }; + + DragSourceListener dsl = new DragSourceListener() { + public void dragEnter(DragSourceDragEvent dsde) {} + public void dragOver(DragSourceDragEvent dsde) {} + public void dropActionChanged(DragSourceDragEvent dsde) {} + public void dragExit(DragSourceEvent dsde) {} + public void dragDropEnd(DragSourceDropEvent dsde) {} + }; + /* + int modifiers[] = { + InputEvent.ALT_GRAPH_MASK, + InputEvent.ALT_MASK, + InputEvent.BUTTON1_MASK, + InputEvent.BUTTON2_MASK, + InputEvent.BUTTON3_MASK, + InputEvent.CTRL_MASK, + InputEvent.META_MASK, + InputEvent.SHIFT_MASK + }; + + int exModifiers[] = { + InputEvent.SHIFT_DOWN_MASK, + InputEvent.ALT_DOWN_MASK, + InputEvent.BUTTON1_DOWN_MASK, + InputEvent.BUTTON2_DOWN_MASK, + InputEvent.BUTTON3_DOWN_MASK, + InputEvent.CTRL_DOWN_MASK, + InputEvent.META_DOWN_MASK, + InputEvent.ALT_GRAPH_DOWN_MASK, + }; + */ + DragGestureEvent getDragGestureEvent() { + java.util.Vector vector = new java.util.Vector(); + vector.add(new java.lang.Integer(0)); + return new DragGestureEvent(new DummyDGRecognizer(ds, new Button()), + actions[1], + new java.awt.Point(0,0), + vector); + } + DragGestureEvent dge = getDragGestureEvent(); + + DragSourceContext dsc = new DragSourceContext(dge, + cursors[0], + image, + point, + transferable, + dsl); + + public static void main(String[] args) { + new DragSourceDragEventModifiersTest().start(); + } + + public void start() { + try { + // valid modifiers: + + check(InputEvent.BUTTON1_MASK, InputEvent.BUTTON1_MASK, + InputEvent.BUTTON1_DOWN_MASK); + + check(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK, + InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK, + InputEvent.BUTTON1_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + + check(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON1_MASK, + InputEvent.BUTTON1_DOWN_MASK); + + check(InputEvent.BUTTON1_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK, + InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK, + InputEvent.BUTTON1_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + + // invalid modifiers: + + int invalidMods = 0; + check(invalidMods, invalidMods, invalidMods); + + invalidMods = InputEvent.BUTTON1_DOWN_MASK | InputEvent.SHIFT_MASK; + check(invalidMods, invalidMods, invalidMods); + + invalidMods = (InputEvent.ALT_GRAPH_DOWN_MASK << 1); + check(invalidMods, invalidMods, invalidMods); + + invalidMods = InputEvent.BUTTON1_DOWN_MASK + | (InputEvent.ALT_GRAPH_DOWN_MASK << 1); + check(invalidMods, invalidMods, invalidMods); + + invalidMods = InputEvent.BUTTON1_MASK + | (InputEvent.ALT_GRAPH_DOWN_MASK << 1); + check(invalidMods, invalidMods, invalidMods); + + invalidMods = InputEvent.BUTTON1_DOWN_MASK + | InputEvent.SHIFT_MASK + | (InputEvent.ALT_GRAPH_DOWN_MASK << 1); + check(invalidMods, invalidMods, invalidMods); + + } catch (Throwable e) { + e.printStackTrace(); + } + + if (failed) { + throw new RuntimeException("wrong behavior of " + + "DragSourceDragEvent.getModifiers[Ex]()," + + " see error messages above"); + } + + System.err.println("test passed!"); + } + + void check(int mods, int expectedMods, int expectedExMods) { + System.err.println("testing DragSourceDragEvent " + + "created with 1st constructor"); + System.err.println("modifiers passed to the constructor: " + + Integer.toBinaryString(mods)); + verify(create1(mods), expectedMods, expectedExMods); + + System.err.println("testing DragSourceDragEvent " + + "created with 2nd constructor"); + System.err.println("modifiers passed to the constructor: " + + Integer.toBinaryString(mods)); + verify(create2(mods), expectedMods, expectedExMods); + } + + void verify(DragSourceDragEvent dsde, int expectedMods, int expectedExMods) { + if (dsde.getGestureModifiers() != expectedMods) { + failed = true; + System.err.print("ERROR: "); + } + System.err.println("getGestureModifiers() returned: " + + Integer.toBinaryString(dsde.getGestureModifiers()) + + " ; expected: " + Integer.toBinaryString(expectedMods)); + + if (dsde.getGestureModifiersEx() != expectedExMods) { + failed = true; + System.err.print("ERROR: "); + } + System.err.println("getGestureModifiersEx() returned: " + + Integer.toBinaryString(dsde.getGestureModifiersEx()) + + " ; expected: " + Integer.toBinaryString(expectedExMods)); + + System.err.println(); + } + + DragSourceDragEvent create1(int mods) { + return new DragSourceDragEvent(dsc, actions[0], actions[0], mods); + } + + DragSourceDragEvent create2(int mods) { + return new DragSourceDragEvent(dsc, actions[0], actions[0], mods, 0, 0); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragSourceGCrashTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragSourceGCrashTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/DragSourceGCrashTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/DragSourceGCrashTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,293 @@ +/* + * 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 4888520 + @summary tests that drag source application invoked via debug java does not + crash on exit after drop on other Java drop target application + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.io.File; +import java.io.InputStream; +import java.io.Reader; + + +public class DragSourceGCrashTest { + + volatile Frame frame; + volatile Panel panel; + + public static void main(String[] args) throws Exception { + DragSourceGCrashTest test = new DragSourceGCrashTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(()-> test.frame.dispose()); + } + } + + public void init() { + frame = new Frame("target - DragSourceGCrashTest"); + panel = new Panel(); + frame.add(panel); + frame.setBounds(100, 100, 100, 100); + + DropTargetListener dtl = new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) { + dtde.acceptDrop(DnDConstants.ACTION_MOVE); + Transferable t = dtde.getTransferable(); + try { + DataFlavor df = new DataFlavor( + "text/plain;class=java.io.Reader"); + Reader r = df.getReaderForText(t); + // To verify the bug do not close the reader! + dtde.dropComplete(true); + } catch (Exception e) { + e.printStackTrace(); + dtde.dropComplete(false); + } + } + }; + + new DropTarget(frame, dtl); + + frame.setVisible(true); + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + ProcessResults pres = null; + + Point endPoint = panel.getLocationOnScreen(); + + endPoint.translate(panel.getWidth() / 2, panel.getHeight() / 2); + + String jdkPath = System.getProperty("java.home"); + String javaPath = jdkPath + File.separator + "bin" + + File.separator + "java"; + + String[] cmd = { + javaPath, "-cp", + System.getProperty("test.classes", "."), + "Child", + String.valueOf(endPoint.x), + String.valueOf(endPoint.y) + }; + Process process = Runtime.getRuntime().exec(cmd); + pres = ProcessResults.doWaitFor(process); + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + if (pres.exitValue != 0) { + throw new RuntimeException("FAILURE: child java exited " + + "with code " + pres.exitValue); + } + } +} + +class Child { + volatile Frame frame; + volatile Panel panel; + + public static void main(String[] args) throws Exception { + int endX = Integer.parseInt(args[0]); + int endY = Integer.parseInt(args[1]); + Point endPoint = new Point(endX, endY); + + Child child = new Child(); + EventQueue.invokeAndWait(child::init); + try { + child.start(endPoint); + } finally { + EventQueue.invokeAndWait(() -> child.frame.dispose()); + } + } + + public void init() { + frame = new Frame("source - DragSourceGCrashTest"); + panel = new Panel(); + frame.add(panel); + frame.setBounds(200, 100, 100, 100); + + final DragSourceListener dsl = new DragSourceAdapter() { + public void dragDropEnd(DragSourceDropEvent dsde) { + System.err.println("DragSourceListener.dragDropEnd(): " + + "exiting application"); + System.exit(0); + } + }; + DragGestureListener dgl = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, + new StringSelection("test"), dsl); + } + }; + + new DragSource().createDefaultDragGestureRecognizer(panel, + DnDConstants.ACTION_MOVE, dgl); + + frame.setVisible(true); + } + + public void start(Point endPoint) throws Exception { + Robot robot = new Robot(); + + robot.waitForIdle(); + robot.delay(1000); + + Point startPoint = panel.getLocationOnScreen(); + + startPoint.translate( + panel.getWidth() / 2, + panel.getHeight() / 2 + ); + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate( + Integer.compare(endPoint.x - p.x, 0), + Integer.compare(endPoint.y - p.y, 0) + )) { + robot.mouseMove(p.x, p.y); + robot.delay(50); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + long timeout = 30000; + Object LOCK = new Object(); + synchronized (LOCK) { + LOCK.wait(timeout); + System.err.println(System.currentTimeMillis() + " end"); + } + System.err.println("WARNING: drop has not ended within " + timeout + + " ms, exiting application!"); + System.exit(0); + } +} + +class ProcessResults { + final static long TIMEOUT = 60000; + + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + long startTime = System.currentTimeMillis(); + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + if (System.currentTimeMillis() > startTime + TIMEOUT) { + System.err.println("WARNING: child process has not " + + "exited within " + TIMEOUT + " ms, returning" + + " from ProcessResults.doWaitFor()"); + pres.exitValue = 0; + return pres; + } + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTree; +import java.awt.EventQueue; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.event.InputEvent; + +/* + @test + @bug 4273712 4396746 + @summary tests that mouse exit event doesn't trigger drag + @key headful + @run main MouseExitGestureTriggerTest +*/ + +public class MouseExitGestureTriggerTest { + + boolean recognized = false; + volatile JFrame frame; + volatile JPanel panel; + volatile JTree tree; + volatile DragSource dragSource; + volatile Point srcPoint; + volatile Rectangle r; + volatile DragGestureListener dgl; + static final int FRAME_ACTIVATION_TIMEOUT = 2000; + static final int RECOGNITION_TIMEOUT = 1000; + + public static void main(String[] args) throws Exception { + MouseExitGestureTriggerTest test = new MouseExitGestureTriggerTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + + public void init() { + frame = new JFrame("MouseExitGestureTriggerTest"); + panel = new JPanel(); + tree = new JTree(); + + dragSource = DragSource.getDefaultDragSource(); + dgl = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + Thread.dumpStack(); + recognized = true; + } + }; + + tree.setEditable(true); + dragSource.createDefaultDragGestureRecognizer(tree, + DnDConstants.ACTION_MOVE, + dgl); + panel.add(tree); + frame.getContentPane().add(panel); + frame.setLocation(200, 200); + + frame.pack(); + frame.setVisible(true); + } + + public void start() throws Exception { + final Robot robot = new Robot(); + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + clickRootNode(robot); + clickRootNode(robot); + clickRootNode(robot); + + Thread.sleep(RECOGNITION_TIMEOUT); + + EventQueue.invokeAndWait(() -> { + if (recognized) { + throw new RuntimeException("Mouse exit event triggered drag"); + } + }); + } + + void clickRootNode(final Robot robot) throws Exception { + EventQueue.invokeAndWait(() -> { + srcPoint = tree.getLocationOnScreen(); + r = tree.getRowBounds(0); + }); + srcPoint.translate(r.x + 2 * r.width /3 , r.y + r.height / 2); + robot.mouseMove(srcPoint.x ,srcPoint.y); + + robot.mousePress(InputEvent.BUTTON1_MASK); + Thread.sleep(10); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Thread.sleep(10); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/MozillaDnDTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/MozillaDnDTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/MozillaDnDTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/MozillaDnDTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.SystemFlavorMap; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/* + @test + @bug 4746177 + @summary tests that data types exported by Netscape 6.2 are supported + @requires (os.family != "windows") + @key headful + @run main MozillaDnDTest +*/ + +public class MozillaDnDTest { + + public static final int CODE_NOT_RETURNED = -1; + public static final int CODE_OK = 0; + public static final int CODE_FAILURE = 1; + public static final String DATA = "www.sun.com"; + + private int returnCode = CODE_NOT_RETURNED; + + volatile Frame frame; + volatile Robot robot; + volatile Panel panel; + volatile Point p; + volatile Dimension d; + + public static void main(String[] args) throws Exception { + MozillaDnDTest test = new MozillaDnDTest(); + if (args.length > 0) { + test.run(args); + } else { + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + } + + public void run(String[] args) { + try { + if (args.length != 4) { + throw new RuntimeException("Incorrect command line arguments."); + } + + int x = Integer.parseInt(args[0]); + int y = Integer.parseInt(args[1]); + int w = Integer.parseInt(args[2]); + int h = Integer.parseInt(args[3]); + + panel = new DragSourcePanel(); + frame = new Frame(); + + frame.setTitle("DragSource frame"); + frame.setLocation(300, 200); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + + Util.waitForInit(); + + Point sourcePoint = panel.getLocationOnScreen(); + Dimension d = panel.getSize(); + sourcePoint.translate(d.width / 2, d.height / 2); + + Point targetPoint = new Point(x + w / 2, y + h / 2); + + robot = new Robot(); + + if (!Util.pointInComponent(robot, sourcePoint, panel)) { + System.err.println("WARNING: Couldn't locate " + panel + + " at point " + sourcePoint); + System.exit(MozillaDnDTest.CODE_OK); + } + + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (; !sourcePoint.equals(targetPoint); + sourcePoint.translate(sign(targetPoint.x - sourcePoint.x), + sign(targetPoint.y - sourcePoint.y))) { + robot.mouseMove(sourcePoint.x, sourcePoint.y); + Thread.sleep(50); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + } catch (Throwable e) { + e.printStackTrace(); + System.exit(MozillaDnDTest.CODE_FAILURE); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void init() { + frame = new Frame(); + panel = new DropTargetPanel(); + + frame.setTitle("DropTarget frame"); + frame.setLocation(10, 200); + frame.add(panel); + + frame.pack(); + frame.setVisible(true); + } + + public void start() { + // Solaris/Linux-only test + if (System.getProperty("os.name").startsWith("Windows")) { + return; + } + try { + Util.waitForInit(); + EventQueue.invokeAndWait(() -> { + p = panel.getLocationOnScreen(); + d = panel.getSize(); + }); + + Robot robot = new Robot(); + Point pp = new Point(p); + pp.translate(d.width / 2, d.height / 2); + if (!Util.pointInComponent(robot, pp, panel)) { + System.err.println("WARNING: Couldn't locate " + panel + + " at point " + pp); + return; + } + + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + System.getProperty("test.classes", ".") + + " MozillaDnDTest " + + p.x + " " + p.y + " " + d.width + " " + d.height; + + Process process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + returnCode = pres.exitValue; + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + } catch (Throwable e) { + e.printStackTrace(); + } + switch (returnCode) { + case CODE_NOT_RETURNED: + System.err.println("Child VM: failed to start"); + break; + case CODE_OK: + System.err.println("Child VM: normal termination"); + break; + case CODE_FAILURE: + System.err.println("Child VM: abnormal termination"); + break; + } + if (returnCode != CODE_OK) { + throw new RuntimeException("The test failed."); + } + } +} + +class Util implements AWTEventListener { + private static final Toolkit tk = Toolkit.getDefaultToolkit(); + public static final Object SYNC_LOCK = new Object(); + private Component clickedComponent = null; + private static final int PAINT_TIMEOUT = 10000; + private static final int MOUSE_RELEASE_TIMEOUT = 10000; + private static final Util util = new Util(); + + static { + tk.addAWTEventListener(util, 0xFFFFFFFF); + } + + private void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + public static boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + return util.isPointInComponent(robot, p, comp); + } + + private boolean isPointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + tk.sync(); + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } + + public static void waitForInit() throws InterruptedException { + final Frame f = new Frame() { + public void paint(Graphics g) { + dispose(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + }; + f.setBounds(600, 400, 200, 200); + synchronized (SYNC_LOCK) { + f.setVisible(true); + SYNC_LOCK.wait(PAINT_TIMEOUT); + } + tk.sync(); + } +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} + +class DragSourcePanel extends Panel { + static final Dimension preferredDimension = new Dimension(200, 200); + static final DataFlavor df = new DataFlavor("application/mozilla-test-flavor", + null); + final DragSource ds = DragSource.getDefaultDragSource(); + final Transferable t = new Transferable() { + final DataFlavor[] flavors = new DataFlavor[] { df }; + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + public boolean isDataFlavorSupported(DataFlavor flav) { + return df.equals(flav); + } + public Object getTransferData(DataFlavor flav) + throws IOException, UnsupportedFlavorException { + if (!isDataFlavorSupported(flav)) { + throw new UnsupportedFlavorException(flav); + } + byte[] bytes = MozillaDnDTest.DATA.getBytes("ASCII"); + return new ByteArrayInputStream(bytes); + } + }; + final DragSourceListener dsl = new DragSourceAdapter() { + public void dragDropEnd(DragSourceDropEvent dsde) { + System.exit(MozillaDnDTest.CODE_OK); + } + }; + final DragGestureListener dgl = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, t, dsl); + } + }; + final DragGestureRecognizer dgr = + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + dgl); + static { + SystemFlavorMap sfm = + (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap(); + String[] natives = new String[] { + "_NETSCAPE_URL", + "text/plain", + "text/unicode", + "text/x-moz-url", + "text/html" + }; + sfm.setNativesForFlavor(df, natives); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 200); + final DropTarget dt = new DropTarget(this, this); + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + public String getTransferString(Transferable t) { + String string = null; + DataFlavor[] dfs = t.getTransferDataFlavors(); + for (int i = 0; i < dfs.length; i++) { + if ("text".equals(dfs[i].getPrimaryType()) || + DataFlavor.stringFlavor.equals(dfs[i])) { + try { + Object o = t.getTransferData(dfs[i]); + if (o instanceof InputStream || + o instanceof Reader) { + Reader reader = null; + if (o instanceof InputStream) { + InputStream is = (InputStream)o; + reader = new InputStreamReader(is); + } else { + reader = (Reader)o; + } + StringBuffer buf = new StringBuffer(); + for (int c = reader.read(); c != -1; c = reader.read()) { + buf.append((char)c); + } + reader.close(); + string = buf.toString(); + break; + } else if (o instanceof String) { + string = (String)o; + break; + } + } catch (Exception e) { + // ignore. + } + } + } + return string; + } + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + return; + } + + Transferable t = dtde.getTransferable(); + String str = getTransferString(t); + dtde.dropComplete(true); + + if (!MozillaDnDTest.DATA.equals(str)) { + throw new RuntimeException("Drop data:" + str); + } + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.List; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.File; +import java.io.InputStream; +import java.io.Serializable; + +/* + @test + @bug 4399700 + @summary tests that drop transfer data can be requested in several data flavors. + @key headful + @run main MultiDataFlavorDropTest +*/ + +public class MultiDataFlavorDropTest { + + public static final int CODE_NOT_RETURNED = -1; + public static final int CODE_OK = 0; + public static final int CODE_FAILURE = 1; + public static final int FRAME_ACTIVATION_TIMEOUT = 2000; + public static final int DROP_TIMEOUT = 10000; + public static final int DROP_COMPLETION_TIMEOUT = 1000; + + private int returnCode = CODE_NOT_RETURNED; + + volatile Frame frame; + volatile Robot robot; + volatile Panel panel; + volatile Point p; + volatile Dimension d; + + public static void main(String[] args) throws Exception { + MultiDataFlavorDropTest test = new MultiDataFlavorDropTest(); + if (args.length > 0) { + test.run(args); + } else { + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + } + + public void run(String[] args) { + try { + if (args.length != 4) { + throw new RuntimeException("Incorrect command line arguments."); + } + + int x = Integer.parseInt(args[0]); + int y = Integer.parseInt(args[1]); + int w = Integer.parseInt(args[2]); + int h = Integer.parseInt(args[3]); + + Transferable t = new TransferableNumber(); + panel = new DragSourcePanel(t); + + frame = new Frame(); + frame.setTitle("DragSource frame"); + frame.setLocation(300, 200); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + Point sourcePoint = panel.getLocationOnScreen(); + Dimension d = panel.getSize(); + sourcePoint.translate(d.width / 2, d.height / 2); + + Point targetPoint = new Point(x + w / 2, y + h / 2); + + robot = new Robot(); + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (; !sourcePoint.equals(targetPoint); + sourcePoint.translate(sign(targetPoint.x - sourcePoint.x), + sign(targetPoint.y - sourcePoint.y))) { + robot.mouseMove(sourcePoint.x, sourcePoint.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + synchronized (t) { + t.wait(DROP_TIMEOUT); + } + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + + } catch (Throwable e) { + e.printStackTrace(); + System.exit(MultiDataFlavorDropTest.CODE_FAILURE); + } + System.exit(MultiDataFlavorDropTest.CODE_OK); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void init() { + frame = new Frame(); + panel = new DropTargetPanel(); + + frame.setTitle("MultiDataFlavorDropTest"); + frame.setLocation(10, 200); + frame.add(panel); + + frame.pack(); + frame.setVisible(true); + } + + public void start() throws Exception { + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + EventQueue.invokeAndWait(() -> { + p = panel.getLocationOnScreen(); + d = panel.getSize(); + }); + + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + System.getProperty("test.classes", ".") + + " MultiDataFlavorDropTest " + + p.x + " " + p.y + " " + d.width + " " + d.height; + + Process process = Runtime.getRuntime().exec(command); + returnCode = process.waitFor(); + + InputStream errorStream = process.getErrorStream(); + int count = errorStream.available(); + if (count > 0) { + byte[] b = new byte[count]; + errorStream.read(b); + System.err.println("========= Child VM System.err ========"); + System.err.print(new String(b)); + System.err.println("======================================"); + } + + switch (returnCode) { + case CODE_NOT_RETURNED: + System.err.println("Child VM: failed to start"); + break; + case CODE_OK: + System.err.println("Child VM: normal termination"); + break; + case CODE_FAILURE: + System.err.println("Child VM: abnormal termination"); + break; + } + if (returnCode != CODE_OK) { + throw new RuntimeException("The test failed."); + } + } +} + +class DragSourceButton extends Button implements Serializable, + DragGestureListener, + DragSourceListener { + + final Transferable transferable; + + public DragSourceButton(Transferable t) { + super("DragSourceButton"); + + this.transferable = t; + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, transferable, this); + } + + public void dragEnter(DragSourceDragEvent dsde) {} + + public void dragExit(DragSourceEvent dse) {} + + public void dragOver(DragSourceDragEvent dsde) {} + + public void dragDropEnd(DragSourceDropEvent dsde) {} + + public void dropActionChanged(DragSourceDragEvent dsde) {} +} + +class IntegerDataFlavor extends DataFlavor { + + private final int number; + + public IntegerDataFlavor(int n) throws ClassNotFoundException { + super("application/integer-" + n + + "; class=java.lang.Integer"); + this.number = n; + } + + public int getNumber() { + return number; + } +} + +class TransferableNumber implements Transferable { + + private int transferDataRequestCount = 0; + public static final int NUM_DATA_FLAVORS = 5; + static final DataFlavor[] supportedFlavors = + new DataFlavor[NUM_DATA_FLAVORS]; + + static { + try { + for (int i = 0; i < NUM_DATA_FLAVORS; i++) { + supportedFlavors[i] = + new IntegerDataFlavor(i); + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + public DataFlavor[] getTransferDataFlavors() { + return supportedFlavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + if (flavor instanceof IntegerDataFlavor) { + IntegerDataFlavor integerFlavor = (IntegerDataFlavor)flavor; + int flavorNumber = integerFlavor.getNumber(); + if (flavorNumber >= 0 && flavorNumber < NUM_DATA_FLAVORS) { + return true; + } + } + return false; + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + transferDataRequestCount++; + + if (transferDataRequestCount >= NUM_DATA_FLAVORS) { + synchronized (this) { + this.notifyAll(); + } + } + + IntegerDataFlavor integerFlavor = (IntegerDataFlavor)flavor; + return new Integer(integerFlavor.getNumber()); + } +} + +class DragSourcePanel extends Panel { + + final Dimension preferredDimension = new Dimension(200, 200); + + public DragSourcePanel(Transferable t) { + setLayout(new GridLayout(1, 1)); + add(new DragSourceButton(t)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 200); + + public DropTargetPanel() { + setBackground(Color.green); + setDropTarget(new DropTarget(this, this)); + setLayout(new GridLayout(1, 1)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + return; + } + + removeAll(); + final List list = new List(); + add(list); + + Transferable t = dtde.getTransferable(); + DataFlavor[] dfs = t.getTransferDataFlavors(); + + if (dfs.length != TransferableNumber.NUM_DATA_FLAVORS) { + throw new RuntimeException("FAILED: Incorrect number of data flavors."); + } + + for (int i = 0; i < dfs.length; i++) { + + DataFlavor flavor = dfs[i]; + Integer transferNumber = null; + + if (flavor.getRepresentationClass().equals(Integer.class)) { + try { + transferNumber = (Integer)t.getTransferData(flavor); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("FAILED: Cannot get data: " + + flavor.getMimeType()); + } + } + + boolean supportedFlavor = false; + for (int j = 0; j < TransferableNumber.NUM_DATA_FLAVORS; j++) { + int number = (i + j) % TransferableNumber.NUM_DATA_FLAVORS; + try { + if (flavor.equals(new IntegerDataFlavor(number))) { + if (!(new Integer(number).equals(transferNumber))) { + throw new RuntimeException("FAILED: Invalid data \n" + + "\tflavor : " + flavor + + "\tdata : " + transferNumber); + } + supportedFlavor = true; + break; + } + } catch (ClassNotFoundException cannotHappen) { + } + } + if (!supportedFlavor) { + throw new RuntimeException("FAILED: Invalid flavor: " + flavor); + } + + list.add(transferNumber + ":" + flavor.getMimeType()); + } + + dtc.dropComplete(true); + validate(); + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; + +/* + @test + @bug 4399700 + @summary tests that Motif drag support for label widget doesn't cause + crash when used for drag and drop from label to Java drop target + @key headful + @run main NativeDragJavaDropTest +*/ + +public class NativeDragJavaDropTest { + + volatile Frame frame; + volatile DropTargetLabel label; + volatile Point p; + volatile Dimension d; + public static final int FRAME_ACTIVATION_TIMEOUT = 1000; + public static final int DRAG_START_TIMEOUT = 500; + public static final int DROP_COMPLETION_TIMEOUT = 2000; + + public static void main(String[] args) throws Exception { + NativeDragJavaDropTest test = new NativeDragJavaDropTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + + public void init() { + frame = new Frame(); + label = new DropTargetLabel(); + frame.setTitle("NativeDragJavaDropTest"); + frame.setLocation(200, 200); + frame.add(label); + + frame.pack(); + frame.setVisible(true); + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.waitForIdle(); + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + EventQueue.invokeAndWait(() -> { + p = label.getLocationOnScreen(); + d = label.getSize(); + }); + + p.translate(d.width / 2, d.height / 2); + + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON2_MASK); + + Thread.sleep(DRAG_START_TIMEOUT); + + robot.mouseRelease(InputEvent.BUTTON2_MASK); + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + } +} + +class DropTargetLabel extends Label implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 100); + + public DropTargetLabel() { + super("Label"); + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + Object obj = (Object)transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/* + @test + @bug 4389284 + @summary tests that drop targets registered on nested heavyweight + components work properly + @key headful + @run main NestedHeavyweightDropTargetTest +*/ + +public class NestedHeavyweightDropTargetTest { + + volatile Frame frame; + volatile DragSourceButton dragSourceButton; + volatile DropTargetPanel dropTargetPanel; + volatile InnerDropTargetPanel innerDropTargetPanel; + volatile Button button; + volatile Dimension d; + volatile Point srcPoint; + volatile Point dstPoint; + + static final int DROP_COMPLETION_TIMEOUT = 1000; + + public static void main(String[] args) throws Exception { + NestedHeavyweightDropTargetTest test = new NestedHeavyweightDropTargetTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + + public void init() { + frame = new Frame(); + dragSourceButton = new DragSourceButton(); + dropTargetPanel = new DropTargetPanel(); + innerDropTargetPanel = new InnerDropTargetPanel(); + button = new Button("button"); + button.setBackground(Color.red); + + innerDropTargetPanel.setLayout(new GridLayout(3, 1)); + innerDropTargetPanel.add(button); + innerDropTargetPanel.setBackground(Color.yellow); + + dropTargetPanel.setLayout(new GridLayout(2, 1)); + dropTargetPanel.add(innerDropTargetPanel); + dropTargetPanel.setBackground(Color.green); + + frame.setTitle("NestedHeavyweightDropTargetTest"); + frame.setLocation(200, 200); + frame.setLayout(new BorderLayout()); + frame.add(dropTargetPanel, BorderLayout.CENTER); + frame.add(dragSourceButton, BorderLayout.SOUTH); + + frame.pack(); + + innerDropTargetPanel.setDropTarget(new DropTarget(innerDropTargetPanel, innerDropTargetPanel)); + dropTargetPanel.setDropTarget(new DropTarget(dropTargetPanel, dropTargetPanel)); + + frame.setVisible(true); + } + + public void start() throws Exception { + Robot robot = new Robot(); + Util.waitForInit(); + + test1(robot); + test2(robot); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void test1(Robot robot) throws Exception { + innerDropTargetPanel.setDragEnterTriggered(false); + innerDropTargetPanel.setDragOverTriggered(false); + innerDropTargetPanel.setDragExitTriggered(false); + innerDropTargetPanel.setDropTriggered(false); + + EventQueue.invokeAndWait(() -> { + srcPoint = dragSourceButton.getLocationOnScreen(); + d = dragSourceButton.getSize(); + }); + + srcPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, srcPoint, dragSourceButton)) { + System.err.println("WARNING: Couldn't locate " + dragSourceButton + + " at point " + srcPoint); + return; + } + + EventQueue.invokeAndWait(() -> { + dstPoint = innerDropTargetPanel.getLocationOnScreen(); + d = innerDropTargetPanel.getSize(); + }); + + dstPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, dstPoint, innerDropTargetPanel)) { + System.err.println("WARNING: Couldn't locate " + innerDropTargetPanel + + " at point " + dstPoint); + return; + } + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + + if (!innerDropTargetPanel.isDragEnterTriggered()) { + throw new RuntimeException("child dragEnter() not triggered"); + } + + if (!innerDropTargetPanel.isDragOverTriggered()) { + throw new RuntimeException("child dragOver() not triggered"); + } + + if (!innerDropTargetPanel.isDropTriggered()) { + throw new RuntimeException("child drop() not triggered"); + } + } + + public void test2(Robot robot) throws Exception { + innerDropTargetPanel.setDragEnterTriggered(false); + innerDropTargetPanel.setDragOverTriggered(false); + innerDropTargetPanel.setDragExitTriggered(false); + innerDropTargetPanel.setDropTriggered(false); + + EventQueue.invokeAndWait(() -> { + srcPoint = dragSourceButton.getLocationOnScreen(); + d = dragSourceButton.getSize(); + }); + srcPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, srcPoint, dragSourceButton)) { + System.err.println("WARNING: Couldn't locate " + dragSourceButton + + " at point " + srcPoint); + return; + } + + EventQueue.invokeAndWait(() -> { + dstPoint = button.getLocationOnScreen(); + d = button.getSize(); + }); + + dstPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, dstPoint, button)) { + System.err.println("WARNING: Couldn't locate " + button + + " at point " + dstPoint); + return; + } + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + + if (!innerDropTargetPanel.isDragEnterTriggered()) { + throw new RuntimeException("child dragEnter() not triggered"); + } + + if (!innerDropTargetPanel.isDragOverTriggered()) { + throw new RuntimeException("child dragOver() not triggered"); + } + + if (!innerDropTargetPanel.isDropTriggered()) { + throw new RuntimeException("child drop() not triggered"); + } + } +} + +class Util implements AWTEventListener { + private static final Toolkit tk = Toolkit.getDefaultToolkit(); + public static final Object SYNC_LOCK = new Object(); + private Component clickedComponent = null; + private static final int PAINT_TIMEOUT = 10000; + private static final int MOUSE_RELEASE_TIMEOUT = 10000; + private static final Util util = new Util(); + + static { + tk.addAWTEventListener(util, 0xFFFFFFFF); + } + + private void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + public static boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + return util.isPointInComponent(robot, p, comp); + } + + private boolean isPointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + tk.sync(); + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } + + public static void waitForInit() throws InterruptedException { + final Frame f = new Frame() { + public void paint(Graphics g) { + dispose(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + }; + f.setBounds(600, 400, 200, 200); + synchronized (SYNC_LOCK) { + f.setVisible(true); + SYNC_LOCK.wait(PAINT_TIMEOUT); + } + tk.sync(); + } +} + +class DragSourceButton extends Button implements Serializable, + Transferable, + DragGestureListener, + DragSourceListener { + private final DataFlavor dataflavor = + new DataFlavor(Button.class, "DragSourceButton"); + + public DragSourceButton() { + this("DragSourceButton"); + } + + public DragSourceButton(String str) { + super(str); + + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, this, this); + } + + public void dragEnter(DragSourceDragEvent dsde) {} + + public void dragExit(DragSourceEvent dse) {} + + public void dragOver(DragSourceDragEvent dsde) {} + + public void dragDropEnd(DragSourceDropEvent dsde) {} + + public void dropActionChanged(DragSourceDragEvent dsde) {} + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + Object retObj = null; + + ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); + ObjectOutputStream ooStream = new ObjectOutputStream(baoStream); + ooStream.writeObject(this); + + ByteArrayInputStream baiStream = new ByteArrayInputStream(baoStream.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(baiStream); + try { + retObj = ois.readObject(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e.toString()); + } + + return retObj; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataflavor }; + } + + public boolean isDataFlavorSupported(DataFlavor dflavor) { + return dataflavor.equals(dflavor); + } +} + +class InnerDropTargetPanel extends DropTargetPanel { + private boolean dragEnterTriggered = false; + private boolean dragOverTriggered = false; + private boolean dragExitTriggered = false; + private boolean dropTriggered = false; + + public void dragEnter(DropTargetDragEvent dtde) { + setDragEnterTriggered(true); + } + + public void dragExit(DropTargetEvent dte) { + setDragExitTriggered(true); + } + + public void dragOver(DropTargetDragEvent dtde) { + setDragOverTriggered(true); + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + setDropTriggered(true); + dtde.rejectDrop(); + } + + public boolean isDragEnterTriggered() { + return dragEnterTriggered; + } + + public boolean isDragOverTriggered() { + return dragOverTriggered; + } + + public boolean isDragExitTriggered() { + return dragExitTriggered; + } + + public boolean isDropTriggered() { + return dropTriggered; + } + + public void setDragEnterTriggered(boolean b) { + dragEnterTriggered = b; + } + + public void setDragOverTriggered(boolean b) { + dragOverTriggered = b; + } + + public void setDragExitTriggered(boolean b) { + dragExitTriggered = b; + } + + public void setDropTriggered(boolean b) { + dropTriggered = b; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + public void dragEnter(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + Component comp = null; + + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + comp = (Component)transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + + add(comp); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,203 @@ +/* + * 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 4887150 + @summary tests that after performing COPY drop, MOVE drop can be performed too + @key headful + @run main NextDropActionTest +*/ + +import java.awt.AWTException; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + + +public class NextDropActionTest { + private final long WAIT_TIMEOUT = 30000; + private volatile boolean failed; + private volatile boolean firstEnd; + private volatile boolean secondEnd; + private final Object LOCK = new Object(); + private Frame frame; + private Panel panel; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + NextDropActionTest nextDropActionTest = new NextDropActionTest(); + nextDropActionTest.start(); + } + + public void start() throws InterruptedException, + InvocationTargetException, AWTException { + + EventQueue.invokeAndWait(() -> { + panel = new Panel(); + frame = new Frame("NextDropActionTest"); + frame.add(panel); + frame.setBounds(300, 300, 300, 300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + }); + + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + final DragSourceListener dsl = new DragSourceAdapter() { + boolean firstCall = true; + public void dragDropEnd(DragSourceDropEvent e) { + System.err.println("DragSourseListener.dragDropEnd(): " + + " firstCall=" + firstCall + + " drop action=" + e.getDropAction()); + if (firstCall) { + firstCall = false; + synchronized (LOCK) { + firstEnd = true; + LOCK.notifyAll(); + } + return; + } + if (e.getDropAction() != DnDConstants.ACTION_MOVE) { + System.err.println("FAILURE: wrong drop action:" + + e.getDropAction()); + failed = true; + } + synchronized (LOCK) { + secondEnd = true; + LOCK.notifyAll(); + } + } + }; + + DragGestureListener dgl = dge -> + dge.startDrag(null, new StringSelection("test"), dsl); + + new DragSource().createDefaultDragGestureRecognizer(panel, + DnDConstants.ACTION_COPY_OR_MOVE, dgl); + + DropTargetListener dtl = new DropTargetAdapter() { + public void drop(DropTargetDropEvent e) { + System.err.println("DropTargetListener.drop(): " + + "accepting the user drop action=" + e.getDropAction()); + e.acceptDrop(e.getDropAction()); + e.dropComplete(true); + } + }; + + new DropTarget(frame, DnDConstants.ACTION_COPY_OR_MOVE, dtl); + + Point startPoint = new Point(Util.blockTillDisplayed(panel)); + startPoint.translate(50, 50); + Point endPoint = new Point(startPoint.x + + DragSource.getDragThreshold() + 10, + startPoint.y + DragSource.getDragThreshold() + 10); + + synchronized (LOCK) { + robot.keyPress(KeyEvent.VK_CONTROL); + Util.doDragDrop(robot, startPoint, endPoint); + robot.keyRelease(KeyEvent.VK_CONTROL); + LOCK.wait(WAIT_TIMEOUT); + } + if (!firstEnd) { + System.err.println("DragSourseListener.dragDropEnd() " + + "was not called, returning"); + return; + } + + synchronized (LOCK) { + Util.doDragDrop(robot, startPoint, endPoint); + LOCK.wait(WAIT_TIMEOUT); + } + if (!secondEnd) { + System.err.println("DragSourseListener.dragDropEnd() " + + "was not called, returning"); + return; + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (failed) { + throw new RuntimeException("wrong next drop action!"); + } + + System.err.println("test passed!"); + } +} + +class Util { + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public static void doDragDrop(Robot robot, Point startPoint, Point endPoint) { + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(Util.sign(endPoint.x - p.x), + Util.sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(100); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + public static Point blockTillDisplayed(Component comp) { + Point p = null; + while (p == null) { + try { + p = comp.getLocationOnScreen(); + } catch (IllegalStateException e) { + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + } + } + return p; + } +} \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4702735 + @summary tests that a dragEnter is called even if the source doesn't + export data in native formats. + @key headful + @run main NoFormatsDragEnterTest +*/ + +import java.awt.AWTException; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + + +public class NoFormatsDragEnterTest { + + Frame frame; + DragSourcePanel dragSourcePanel; + DropTargetPanel dropTargetPanel; + + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int DROP_COMPLETION_TIMEOUT = 1000; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + NoFormatsDragEnterTest noFormatsDragEnterTest = new NoFormatsDragEnterTest(); + EventQueue.invokeAndWait(noFormatsDragEnterTest::init); + noFormatsDragEnterTest.start(); + } + + public void init() { + frame = new Frame(); + dragSourcePanel = new DragSourcePanel(); + dropTargetPanel = new DropTargetPanel(); + + frame.setTitle("NoFormatsDragEnterTest"); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourcePanel); + frame.add(dropTargetPanel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + public void start() throws AWTException, InterruptedException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + final Point srcPoint = dragSourcePanel.getLocationOnScreen(); + Dimension d = dragSourcePanel.getSize(); + srcPoint.translate(d.width / 2, d.height / 2); + + final Point dstPoint = dropTargetPanel.getLocationOnScreen(); + d = dropTargetPanel.getSize(); + dstPoint.translate(d.width / 2, d.height / 2); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point curPoint = new Point(srcPoint); + !curPoint.equals(dstPoint); + curPoint.translate(sign(dstPoint.x - curPoint.x), + sign(dstPoint.y - curPoint.y))) { + robot.mouseMove(curPoint.x, curPoint.y); + robot.delay(100); + } + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(DROP_COMPLETION_TIMEOUT); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (!dropTargetPanel.passed()) { + throw new RuntimeException("Drop doesn't happen."); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n > 0 ? 1 : 0; + } +} + +class DragSourcePanel extends Canvas implements DragGestureListener { + + private final Dimension preferredDimension = new Dimension(200, 100); + private final DragSourceListener listener = new DragSourceAdapter() {}; + + public DragSourcePanel() { + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY_OR_MOVE, + this); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, new TestTransferable(), listener); + } +} + +class TestTransferable implements Transferable { + + public static DataFlavor dataFlavor = null; + static final Object data = new Object(); + + static { + DataFlavor df = null; + try { + df = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + + "; class=java.lang.Object"); + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError(e); + } + dataFlavor = df; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor df) { + return dataFlavor.equals(df); + } + + public Object getTransferData(DataFlavor df) + throws UnsupportedFlavorException, IOException { + if (!isDataFlavorSupported(df)) { + throw new UnsupportedFlavorException(df); + } + return data; + } +} + +class DropTargetPanel extends Canvas implements DropTargetListener { + + private final Dimension preferredDimension = new Dimension(200, 100); + private boolean dragEnterTriggered = false; + private boolean dragOverTriggered = false; + + public DropTargetPanel() { + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) { + dragEnterTriggered = true; + } + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) { + dragOverTriggered = true; + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + dtde.rejectDrop(); + } + + public boolean passed() { + // asserts that dragEnter has been called if dragOver has been called. + return !dragOverTriggered || dragEnterTriggered; + } +} \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4473062 + @summary tests that a drop happens even if the source doesn't export + data in native formats. + @key headful + @run main NoFormatsDropTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +public class NoFormatsDropTest implements AWTEventListener { + + Frame frame; + DragSourcePanel dragSourcePanel; + DropTargetPanel dropTargetPanel; + + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int DROP_COMPLETION_TIMEOUT = 1000; + static final int MOUSE_RELEASE_TIMEOUT = 1000; + static final Object SYNC_LOCK = new Object(); + + Component clickedComponent = null; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + NoFormatsDropTest noFormatsDropTest = new NoFormatsDropTest(); + EventQueue.invokeAndWait(noFormatsDropTest::init); + noFormatsDropTest.start(); + } + + public void init() { + frame = new Frame(); + dragSourcePanel = new DragSourcePanel(); + dropTargetPanel = new DropTargetPanel(); + + frame.setTitle("NoFormatsDropTest"); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourcePanel); + frame.add(dropTargetPanel); + + frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + public void start() throws InterruptedException, AWTException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + final Point srcPoint = dragSourcePanel.getLocationOnScreen(); + Dimension d = dragSourcePanel.getSize(); + srcPoint.translate(d.width / 2, d.height / 2); + + if (!pointInComponent(robot, srcPoint, dragSourcePanel)) { + System.err.println("WARNING: Couldn't locate source panel."); + return; + } + + final Point dstPoint = dropTargetPanel.getLocationOnScreen(); + d = dropTargetPanel.getSize(); + dstPoint.translate(d.width / 2, d.height / 2); + + if (!pointInComponent(robot, dstPoint, dropTargetPanel)) { + System.err.println("WARNING: Couldn't locate target panel."); + return; + } + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point curPoint = new Point(srcPoint); + !curPoint.equals(dstPoint); + curPoint.translate(sign(dstPoint.x - curPoint.x), + sign(dstPoint.y - curPoint.y))) { + robot.mouseMove(curPoint.x, curPoint.y); + robot.delay(100); + } + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(DROP_COMPLETION_TIMEOUT); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (!dropTargetPanel.passed()) { + throw new RuntimeException("Drop doesn't happen."); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n > 0 ? 1 : 0; + } + + public void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } +} + +class DragSourcePanel extends Panel implements DragGestureListener { + + private final Dimension preferredDimension = new Dimension(200, 100); + private final DragSourceListener listener = new DragSourceAdapter() {}; + + public DragSourcePanel() { + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY_OR_MOVE, + this); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, new TestTransferable(), listener); + } +} + +class TestTransferable implements Transferable { + + public static DataFlavor dataFlavor = null; + static final Object data = new Object(); + + static { + DataFlavor df = null; + try { + df = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + + "; class=java.lang.Object"); + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError(e); + } + dataFlavor = df; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor df) { + return dataFlavor.equals(df); + } + + public Object getTransferData(DataFlavor df) + throws UnsupportedFlavorException, IOException { + if (!isDataFlavorSupported(df)) { + throw new UnsupportedFlavorException(df); + } + return data; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 100); + boolean passed = false; + + public DropTargetPanel() { + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + Transferable transfer = dtde.getTransferable(); + + if (transfer.isDataFlavorSupported(TestTransferable.dataFlavor)) { + try { + Object data = + transfer.getTransferData(TestTransferable.dataFlavor); + passed = true; + dtc.dropComplete(true); + } catch (IOException e) { + e.printStackTrace(); + dtc.dropComplete(false); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } else { + dtc.dropComplete(false); + } + } + + boolean passed() { + return passed; + } +} \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,217 @@ +/* + * 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 4874092 + @summary tests that DragSourceListener.dragExit() is not called if the mouse + is not dragged over any drop site + @key headful + @run main NoTargetNoDragExitTest +*/ + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; + + +public class NoTargetNoDragExitTest { + private volatile boolean failed; + private volatile boolean end; + private final Object LOCK = new Object(); + private Frame frame; + private Panel panel; + + public static void main(String[] args) throws Exception { + NoTargetNoDragExitTest noTargetNoDragExitTest = new NoTargetNoDragExitTest(); + EventQueue.invokeAndWait(noTargetNoDragExitTest::init); + noTargetNoDragExitTest.start(); + } + + public void init() { + frame = new Frame("NoTargetNoDragExitTest"); + panel = new Panel(); + frame.add(panel); + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + public void start() throws Exception { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + final DragSourceListener dsl = new DragSourceAdapter() { + public void dragExit(DragSourceEvent e) { + failed = true; + System.err.println("FAILURE: DragSourceListener.dragExit() called!"); + } + public void dragDropEnd(DragSourceDropEvent e) { + System.err.println("DragSourceListener.dragDropEnd()"); + synchronized (LOCK) { + end = true; + LOCK.notifyAll(); + } + } + }; + + DragGestureListener dgl = dge -> + dge.startDrag(null, new StringSelection("NoTargetNoDragExitTest"), dsl); + + new DragSource().createDefaultDragGestureRecognizer(panel, + DnDConstants.ACTION_COPY_OR_MOVE, dgl); + + Point startPoint = frame.getLocationOnScreen(); + startPoint.translate(50, 50); + Point endPoint = new Point(startPoint.x + 100, startPoint.y + 100); + + Util.waitForInit(); + + if (!Util.pointInComponent(robot, startPoint, frame)) { + System.err.println("WARNING: Could not locate " + frame + + " at point " + startPoint); + return; + } + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(Util.sign(endPoint.x - p.x), + Util.sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(100); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + synchronized (LOCK) { + while (!end) { + LOCK.wait(); + } + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (failed) { + throw new RuntimeException("DragSourceListener.dragExit() called!"); + } + + System.err.println("test passed!"); + } +} + + +class Util implements AWTEventListener { + private static final Toolkit tk = Toolkit.getDefaultToolkit(); + private static final Object SYNC_LOCK = new Object(); + private Component clickedComponent = null; + private static final int PAINT_TIMEOUT = 10000; + private static final int MOUSE_RELEASE_TIMEOUT = 10000; + private static final Util util = new Util(); + + static { + tk.addAWTEventListener(util, 0xFFFFFFFF); + } + + private void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + public static boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + return util.isPointInComponent(robot, p, comp); + } + + private boolean isPointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + tk.sync(); + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } + + public static void waitForInit() throws InterruptedException { + final Frame f = new Frame() { + public void paint(Graphics g) { + dispose(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + }; + f.setBounds(600, 400, 200, 200); + synchronized (SYNC_LOCK) { + f.setVisible(true); + SYNC_LOCK.wait(PAINT_TIMEOUT); + } + tk.sync(); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } +} \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * 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 + @key headful + @bug 4187912 + @summary Test that some incorrectly written DnD code cannot hang the app + @run main NotReallySerializableTest +*/ + +import java.awt.Button; +import java.awt.Cursor; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceContext; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.util.ArrayList; + + +public class NotReallySerializableTest { + public static void main(String[] args) throws IOException { + Toolkit tk = Toolkit.getDefaultToolkit(); + + DragGestureRecognizer dgr = tk.createDragGestureRecognizer + (java.awt.dnd.MouseDragGestureRecognizer.class, + DragSource.getDefaultDragSource(), new Button(), + DnDConstants.ACTION_LINK, new TrickDragGestureListener()); + DragGestureEvent dge = new DragGestureEvent + (dgr, DnDConstants.ACTION_LINK, new Point(0, 0), + new TrickList()); + DragSourceContext dsc = new DragSourceContext(dge, + Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), + null, null, new TrickTransferable(), + new TrickDragSourceListener()); + DropTarget dt = new DropTarget(new Button(), + new TrickDropTargetListener()); + + ObjectOutputStream stream = new ObjectOutputStream + (new OutputStream() { + public void write(int b) {} + }); + + stream.writeObject(dgr); + stream.writeObject(dge); + stream.writeObject(dsc); + stream.writeObject(dt); + + System.out.println("test passed"); + } +} + +class TrickList extends ArrayList implements Serializable { + Object trick = new Object(); + + TrickList() { + add(trick); + } +} + +class TrickDragGestureListener implements DragGestureListener, Serializable { + Object trick = new Object(); + + public void dragGestureRecognized(DragGestureEvent dge) {} +} + +class TrickTransferable extends StringSelection implements Serializable { + Object trick = new Object(); + + TrickTransferable() { + super(""); + } +} + +class TrickDragSourceListener extends DragSourceAdapter + implements Serializable +{ + Object trick = new Object(); +} + +class TrickDropTargetListener extends DropTargetAdapter + implements Serializable +{ + Object trick = new Object(); + + public void drop(DropTargetDropEvent dtde) {} +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RejectDragDropActionTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RejectDragDropActionTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RejectDragDropActionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RejectDragDropActionTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * 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 4774532 + @summary tests that DropTargetDragEvent.getDropAction() returns correct value + after DropTargetDragEvent.rejectDrag() + @key headful + @run main RejectDragDropActionTest +*/ + +import java.awt.AWTException; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + + +public class RejectDragDropActionTest { + + private static volatile boolean incorrectActionDetected = false; + + private static final int FRAME_ACTIVATION_TIMEOUT = 3000; + + private static Frame frame; + private static DragSource ds; + private static DragGestureListener dgl; + private static DragGestureRecognizer dgr; + private final DropTargetListener dtl = new DropTargetAdapter() { + public void dragEnter(DropTargetDragEvent dtde) { + dtde.rejectDrag(); + } + public void dragOver(DropTargetDragEvent dtde) { + if (dtde.getDropAction() == DnDConstants.ACTION_NONE) { + incorrectActionDetected = true; + } + } + public void drop(DropTargetDropEvent dtde) { + dtde.rejectDrop(); + } + }; + private final DropTarget dt = new DropTarget(frame, dtl); + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + EventQueue.invokeAndWait(() -> { + frame = new Frame("RejectDragDropActionTest"); + ds = DragSource.getDefaultDragSource(); + dgl = dge -> dge.startDrag(null, new StringSelection("OOKK")); + dgr = ds.createDefaultDragGestureRecognizer(frame, DnDConstants.ACTION_COPY, dgl); + frame.setBounds(100, 100, 200, 200); + frame.setVisible(true); + }); + + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + Point startPoint = frame.getLocationOnScreen(); + Point endPoint = new Point(startPoint); + startPoint.translate(50, 50); + endPoint.translate(150, 150); + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(sign(endPoint.x - p.x), + sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(50); + } + + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + if (incorrectActionDetected) { + throw new RuntimeException("User action reported incorrectly."); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4530216 + @summary tests that DragSourceListeners are properly removed + @key headful + @run main RemoveDragSourceListenerTest +*/ + +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DragSourceMotionListener; + + +public class RemoveDragSourceListenerTest { + public static void main(String[] args) { + class TestDragSourceAdapter extends DragSourceAdapter {} + + final DragSource dragSource = DragSource.getDefaultDragSource(); + + final DragSourceAdapter listeners[] = { + new TestDragSourceAdapter(), + new TestDragSourceAdapter(), + new TestDragSourceAdapter() // should be three or more listeners + }; + + for (int i = 0; i < listeners.length; i++) { + dragSource.addDragSourceListener(listeners[i]); + } + + DragSourceListener[] dragSourceListeners = + dragSource.getDragSourceListeners(); + + if (dragSourceListeners.length != listeners.length) { + throw new RuntimeException("Unexpected length: " + + dragSourceListeners.length); + } + + for (int i = 0; i < listeners.length; i++) { + dragSource.removeDragSourceListener(listeners[i]); + } + + for (int i = 0; i < listeners.length; i++) { + dragSource.addDragSourceMotionListener(listeners[i]); + } + + DragSourceMotionListener[] dragSourceMotionListeners = + dragSource.getDragSourceMotionListeners(); + + if (dragSourceMotionListeners.length != listeners.length) { + throw new RuntimeException("Unexpected length: " + + dragSourceMotionListeners.length); + } + + for (int i = 0; i < listeners.length; i++) { + dragSource.removeDragSourceMotionListener(listeners[i]); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -60,7 +60,7 @@ /** * @test * @key headful - * @bug 4393148 8136999 8186263 8224632 + * @bug 4393148 4357905 8136999 8186263 8224632 * @summary tests that removal of the drop target or disposal of frame during * drop processing doesn't cause crash * @run main/timeout=300 RemoveDropTargetCrashTest RUN_PROCESS diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4411368 + @summary tests the app doesn't crash if the child drop target is removed + after the parent drop target is removed + @key headful + @run main RemoveParentChildDropTargetTest +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.lang.reflect.InvocationTargetException; + + +public class RemoveParentChildDropTargetTest { + + static Frame frame; + static Panel panel; + static Label label; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + frame = new Frame("RemoveParentChildDropTargetTest"); + panel = new Panel(); + label = new Label("Label"); + panel.add(label); + frame.add(panel); + frame.pack(); + + panel.setDropTarget(new DropTarget(panel, new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) {} + })); + label.setDropTarget(new DropTarget(label, new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) {} + })); + panel.setDropTarget(null); + frame.setVisible(true); + + label.setDropTarget(null); + }); + + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4484572 4645584 + @summary verifies that showing a modal dialog during the drag operation + in the same JVM doesn't cause hang + @key headful + @run main SameJVMModalDialogDeadlockTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.lang.reflect.InvocationTargetException; + + +public class SameJVMModalDialogDeadlockTest implements AWTEventListener { + + Frame frame; + boolean shown = false; + boolean finished = false; + + final DragSource dragSource = DragSource.getDefaultDragSource(); + final Transferable transferable = new StringSelection("TEXT"); + final DragSourceAdapter dragSourceAdapter = new DragSourceAdapter() { + public void dragDropEnd(DragSourceDropEvent dsde) { + finished = true; + } + public void dragMouseMoved(DragSourceDragEvent dsde) { + if (shown) { + return; + } + + shown = true; + final Dialog d = new Dialog(frame, "Dialog"); + d.setModal(true); + + Runnable r1 = () -> d.setVisible(true); + new Thread(r1).start(); + } + }; + final DragGestureListener dragGestureListener = dge -> + dge.startDrag(null, transferable); + + static final Object SYNC_LOCK = new Object(); + static final int FRAME_ACTIVATION_TIMEOUT = 3000; + static final int DROP_COMPLETION_TIMEOUT = 5000; + static final int MOUSE_RELEASE_TIMEOUT = 1000; + + Component clickedComponent = null; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + SameJVMModalDialogDeadlockTest sameJVMModalDialogDeadlockTest = + new SameJVMModalDialogDeadlockTest(); + EventQueue.invokeAndWait(sameJVMModalDialogDeadlockTest::init); + sameJVMModalDialogDeadlockTest.start(); + } + + public void init() { + frame = new Frame("SameJVMModalDialogDeadlockTest"); + frame.setTitle("Test frame"); + frame.setBounds(100, 100, 200, 200); + dragSource.createDefaultDragGestureRecognizer(frame, + DnDConstants.ACTION_COPY_OR_MOVE, dragGestureListener); + + dragSource.addDragSourceMotionListener(dragSourceAdapter); + dragSource.addDragSourceListener(dragSourceAdapter); + + frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK); + frame.setVisible(true); + } + + public void start() throws AWTException, InterruptedException, + InvocationTargetException { + try { + final Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + final Point srcPoint = frame.getLocationOnScreen(); + Dimension d = frame.getSize(); + srcPoint.translate(d.width / 2, d.height / 2); + + if (!pointInComponent(robot, srcPoint, frame)) { + System.err.println("WARNING: Couldn't locate source frame."); + return; + } + + final Point dstPoint = new Point(srcPoint); + dstPoint.translate(d.width / 4, d.height / 4); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.delay(50); + } + + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(DROP_COMPLETION_TIMEOUT); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + if (!finished) { + throw new RuntimeException("DnD not completed"); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * 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 4187912 + @summary Test that incorrectly written DnD code cannot hang the app + @key headful + @run main SkipDropCompleteTest +*/ + +import java.awt.AWTException; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + + +public class SkipDropCompleteTest { + SourceFrame sourceFrame; + TargetFrame targetFrame; + Point sourceLoc; + Point targetLoc; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + SkipDropCompleteTest skipDropCompleteTest = new SkipDropCompleteTest(); + EventQueue.invokeAndWait(skipDropCompleteTest::init); + skipDropCompleteTest.start(); + } + + public void init() { + sourceFrame = new SourceFrame(); + targetFrame = new TargetFrame(); + + sourceLoc = sourceFrame.getLocation(); + Dimension sourceSize = sourceFrame.getSize(); + sourceLoc.x += sourceSize.width / 2; + sourceLoc.y += sourceSize.height / 2; + + targetLoc = targetFrame.getLocation(); + Dimension targetSize = targetFrame.getSize(); + targetLoc.x += targetSize.width / 2; + targetLoc.y += targetSize.height / 2; + } + + public void start() throws AWTException, InterruptedException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.delay(1000); + robot.mouseMove(sourceLoc.x, sourceLoc.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (;!sourceLoc.equals(targetLoc); + sourceLoc.translate(sign(targetLoc.x - sourceLoc.x), + sign(targetLoc.y - sourceLoc.y))) { + robot.mouseMove(sourceLoc.x, sourceLoc.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } finally { + EventQueue.invokeAndWait(() -> { + if (sourceFrame != null) { + sourceFrame.dispose(); + } + if (targetFrame != null) { + targetFrame.dispose(); + } + }); + } + + System.out.println("test passed"); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Frame; +import java.awt.TextArea; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class SourceFrame extends Frame + implements DragSourceListener,DragGestureListener { + + DragSource dragSource; + TransferableObject transferableObject; + TextArea textArea; + + public SourceFrame() { + + super("SkipDropCompleteTest Source Frame"); + + dragSource = new DragSource(); + textArea = new TextArea("Drag the Text from the SourceFrame\n" + + "and drop it on the TextArea in the\n" + + "Target Frame.\n" + + "Try to do some operation, like closing\n" + + "of the frame.\n"+ + "See whether the application hangs."); + add(textArea); + + dragSource.createDefaultDragGestureRecognizer(textArea, DnDConstants.ACTION_COPY, this); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + setSize(250,250); + setLocation(50,50); + setBackground(Color.red); + this.setVisible(true); + } + + public void dragEnter(DragSourceDragEvent dsde) { } + + public void dragOver(DragSourceDragEvent dsde) { } + + public void dragExit(DragSourceEvent dse) { } + + public void dropActionChanged(DragSourceDragEvent dsde ) { } + + public void dragDropEnd(DragSourceDropEvent dsde) { } + + public void dragGestureRecognized(DragGestureEvent dge) { + transferableObject = new TransferableObject(textArea.getText()); + dragSource.startDrag(dge, DragSource.DefaultCopyDrop, + transferableObject, this); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.TextArea; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class TargetFrame extends Frame implements DropTargetListener{ + + DropTarget dropTarget; + TextArea textArea; + + public TargetFrame() { + super("SkipDropCompleteTest Target Frame"); + textArea = new TextArea(); + add(textArea); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + setSize(250,250); + setLocation(350,50); + this.setVisible(true); + + dropTarget = new DropTarget(textArea,this); + } + + public void dragEnter(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) { } + + public void dropActionChanged(DropTargetDragEvent dtde ) {} + + public void drop(DropTargetDropEvent dtde) { + try { + Transferable transferable = dtde.getTransferable(); + dtde.acceptDrop(DnDConstants.ACTION_MOVE); + + String str = (String)transferable.getTransferData(TransferableObject.stringFlavor); + textArea.setText(str); + } catch (Exception ufException ) { + ufException.printStackTrace(); + System.err.println( "Exception" + ufException.getMessage()); + dtde.rejectDrop(); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.util.Vector; + + +public class TransferableObject implements Transferable { + private Object data; + private String stringText; + public static DataFlavor stringFlavor,localObjectFlavor; + + static + { + // Data Flavor for Java Local Object + try { + localObjectFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType); + stringFlavor = DataFlavor.stringFlavor; + } + catch (ClassNotFoundException e) { + System.out.println("Exception " + e); + } + } + + DataFlavor[] dfs; + + public TransferableObject(Object data) { + super(); + Vector v = new Vector(); + if(data instanceof String) { + v.addElement(stringFlavor); + stringText = (String)data; + } + else { + v.addElement(localObjectFlavor); + } + + dfs = new DataFlavor[v.size()]; + v.copyInto(dfs); + + this.data = data; + } + + // Retrieve the data based on the flavor + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + + System.out.println("\n ***************************************"); + System.out.println(" The Flavor passed to retrieve the data : " + + flavor.getHumanPresentableName()); + System.out.println(" The Flavors supported"); + for (int j = 0; j < dfs.length; j++) + System.out.println(" Flavor : " + dfs[j].getHumanPresentableName()); + + System.out.println(" ***************************************\n"); + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } else if (flavor.equals(stringFlavor)) { + return stringText; + } else if (localObjectFlavor.isMimeTypeEqual(flavor)) { + return data; + } + return null; + } + + public DataFlavor[] getTransferDataFlavors(){ + return dfs; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (int i = 0 ; i < dfs.length; i++) { + if (dfs[i].match(flavor)) { + return true; + } + } + return false; + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/ZeroFormatTransferableTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/ZeroFormatTransferableTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/dnd/ZeroFormatTransferableTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/dnd/ZeroFormatTransferableTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4388802 + @summary tests that getting clipboard data doesn't crash when there are no + formats on the clipboard + @key headful + @run main ZeroFormatTransferableTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + + +public class ZeroFormatTransferableTest { + public static void main(String[] args) throws InterruptedException, IOException { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new ZeroFormatTransferable(), null); + + String javaPath = System.getProperty("java.home", ""); + + Process process = new ProcessBuilder( + javaPath + File.separator + "bin" + File.separator + "java", + "-cp", + System.getProperty("test.classes", "."), + "ZeroFormatTransferableTest").start(); + process.waitFor(); + + InputStream errorStream = process.getErrorStream(); + int count = errorStream.available(); + if (count > 0) { + byte[] b = new byte[count]; + errorStream.read(b); + System.err.println("========= Child VM System.err ========"); + System.err.print(new String(b)); + System.err.println("======================================"); + } + } +} + +class ZeroFormatTransferable implements Transferable { + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] {}; + } + + public boolean isDataFlavorSupported(DataFlavor df) { + return false; + } + + public Object getTransferData(DataFlavor df) + throws UnsupportedFlavorException { + throw new UnsupportedFlavorException(df); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/ComponentEvent/ComponentResizedTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/ComponentEvent/ComponentResizedTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/ComponentEvent/ComponentResizedTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/ComponentEvent/ComponentResizedTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * 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 4267393 + @summary Ensures minimal amount of paints + @key headful + @run main ComponentResizedTest +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.event.ComponentEvent; +import java.lang.reflect.InvocationTargetException; + +public class ComponentResizedTest extends Frame { + volatile int paintCount = 0; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ComponentResizedTest componentResizedTest = new ComponentResizedTest(); + EventQueue.invokeAndWait(componentResizedTest::init); + componentResizedTest.start(); + if (componentResizedTest != null) EventQueue.invokeAndWait(() + -> componentResizedTest.dispose()); + } + + public void paint(Graphics g) { + System.out.println("Paint called"); + ++paintCount; + } + + public void init() { + setTitle("ComponentResizedTest"); + setSize(100, 100); + setLocationRelativeTo(null); + setVisible(true); + } + + public void start () throws InterruptedException { + Thread.sleep(1000); + + paintCount = 0; + dispatchEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED)); + + Thread.sleep(1000); + + if (paintCount > 0) { + throw new RuntimeException("ComponentResizedTest failed. " + + "Paint called."); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/ComponentEvent/ObjectSourceTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/ComponentEvent/ObjectSourceTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/ComponentEvent/ObjectSourceTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/ComponentEvent/ObjectSourceTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4420658 + @summary No ClassCastException should be thrown when getComponent() + is called on an event with a non-Component source. + The result should be null. + @key headful + @run main ObjectSourceTest +*/ + +import java.awt.Component; +import java.awt.Frame; +import java.awt.event.ComponentEvent; + + +public class ObjectSourceTest { + static Frame frame; + + public static void main(String[] args) { + frame = new Frame("ObjectSourceTest"); + + ComponentEvent ce = new ComponentEvent(frame, ComponentEvent.COMPONENT_SHOWN); + Object obj = new Object(); + ce.setSource(obj); + + Component comp = ce.getComponent(); + if (comp != null) { + throw new RuntimeException("ObjectSourceTest failed. comp != null"); + } + + if (frame != null) { + frame.dispose(); + } + } + } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/ComponentEvent/ResizeDeniedTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/ComponentEvent/ResizeDeniedTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/ComponentEvent/ResizeDeniedTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/ComponentEvent/ResizeDeniedTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4523758 + @requires (os.family == "windows") + @summary Checks denied setBounds doesn't generate ComponentEvent + @key headful + @run main ResizeDeniedTest +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.lang.reflect.InvocationTargetException; + +public class ResizeDeniedTest implements ComponentListener { + static int runs = 0; + static Frame frame; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + + ResizeDeniedTest resizeDeniedTest = new ResizeDeniedTest(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("ResizeDeniedTest"); + frame.addComponentListener(resizeDeniedTest); + frame.setSize(1, 1); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + synchronized(resizeDeniedTest) { + resizeDeniedTest.wait(2000); + } + + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + + if (runs > 10) { + System.out.println("Infinite loop"); + throw new RuntimeException("Infinite loop"); + } + } + + public void componentHidden(ComponentEvent e) {} + + public void componentMoved(ComponentEvent e) {} + + public void componentResized(ComponentEvent e) { + frame.setSize(1, 1); + System.out.println("Size " + frame.getSize()); + ++runs; + if (runs > 10) { + System.out.println("Infinite loop"); + synchronized(this) { + this.notify(); + } + throw new RuntimeException("Infinite loop"); + } + } + + public void componentShown(ComponentEvent e) {} +} Binary files /tmp/tmphyegkbwu/Lq1fQUuR9P/openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/FocusEvent/OppositeSerialization/old.ser and /tmp/tmphyegkbwu/UiQyo5qJAC/openjdk-17-17.0.8+7/test/jdk/java/awt/event/FocusEvent/OppositeSerialization/old.ser differ diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/FocusEvent/OppositeSerialization/OppositeSerialization.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/FocusEvent/OppositeSerialization/OppositeSerialization.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/FocusEvent/OppositeSerialization/OppositeSerialization.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/FocusEvent/OppositeSerialization/OppositeSerialization.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4715486 + @summary Tests that FocusEvent.opposite is not serialized + @key headful + @run main OppositeSerialization +*/ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.FocusEvent; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; + +import static java.lang.Integer.valueOf; + +/** + * "This is an AUTOMATIC test", + * "however, that's what it does:", + * "1. It tests that FocusEvent.opposite field is written", + * "to serialized stream as null regardless of whether it", + * "is actually null or not. For this purpose, we serialize", + * "a FocusEvent with really huge opposite, and then check", + * "if serialized object is huge or not.", + * "2. It tests that FocusEvent.opposite deserializes as", + * "null, even if it was serialized in the previous version", + * "of JDK. For this purpose, file old.ser is included into", + * "test. It is FocusEvent serialized with 1.4, with non-null", + * "opposite. We check that after deserialization opposite", + * "field is null" + */ +public class OppositeSerialization { + static Button b1; + static Frame b2; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + b1 = new Button("OppositeSerialization - Source"); + b2 = new Frame("OppositeSerialization - Opposite"); + b2.setLayout(new FlowLayout()); + + for (int i = 0; i < 10000; i++) { + String s = (valueOf(i)).toString(); + b2.add(new Button("Button" + s)); + } + }); + + FocusEvent evt1 = new FocusEvent(b1, FocusEvent.FOCUS_GAINED, false, b2); + + /* + * Here we test that opposite component isn't serialized. + * We created a really huge opposite component for a focus + * event evt1 and now we'll see if the size of serialized data + * is big. + */ + try { + FileOutputStream fos = new FileOutputStream("new.ser"); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(evt1); + oos.flush(); + } catch (Exception e1) { + System.out.println("Sorry! Couldn't write the stream"); + System.out.println("The test failed, but the reason is " + + "unrelated to the subject"); + throw new RuntimeException("The test couldn't write serialized data"); + } + + File file = new File("new.ser"); + if (file.length() > 50000) { + System.out.println("The test failed: serialized " + + "FocusEvent too huge"); + System.err.println("Serialized FocusEvent is too huge."); + System.err.println("Probably opposite field is " + + "serialized incorrectly."); + throw new RuntimeException("Serialized FocusEvent is too huge"); + } + + /* + * Here we test that opposite is not deserialized even if it is present + * in the stream. old.ser is created with JDK1.4 using the following + * source code: + * + * import java.awt.event.*; + * import java.io.*; + * import java.awt.*; + * + * public class OldFocusSerializer { + * + * public static void main(String[] args) { + * + * Button b1 = new Button("Source"); + * Button b2 = new Button("Opposite"); + * + * FocusEvent evt1 = new FocusEvent(b1, + * FocusEvent.FOCUS_GAINED, + * false, + * b2); + * + * try { + * FileOutputStream fos = new FileOutputStream("old.ser"); + * ObjectOutputStream oos = new ObjectOutputStream(fos); + * oos.writeObject(evt1); + * oos.flush(); + * } catch (IOException e) { + * System.out.println("Sorry! Couldn't write the stream"); + * } + * } + * } + */ + FocusEvent evt2; + String testPath = System.getProperty("test.src", "."); + try { + FileInputStream fis = new FileInputStream(testPath + + File.separator + "old.ser"); + ObjectInputStream ois = new ObjectInputStream(fis); + evt2 = (FocusEvent)ois.readObject(); + } catch (Exception e2) { + System.out.println("The test failed as it couldn't read the stream"); + throw new RuntimeException("The test couldn't read serialized data"); + } + + if (evt2.getOppositeComponent() != null) { + System.out.println("The test failed: opposite component " + + "deserialized to non-null value"); + System.err.println("FocusEvent stored in old.ser should have " + + "null opposite field."); + throw new RuntimeException("Non-null opposite component " + + "after deserialization"); + } + + if (b2 != null) { + EventQueue.invokeAndWait(() -> b2.dispose()); + } + + System.out.println("The test passed"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/HierarchyEvent/HierarchyEventOnWindowTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/HierarchyEvent/HierarchyEventOnWindowTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/HierarchyEvent/HierarchyEventOnWindowTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/HierarchyEvent/HierarchyEventOnWindowTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4460376 + @summary HierarchyEvents on Frame should be dispatched correctly + when on its child Window this event type enabled + @key headful + @run main HierarchyEventOnWindowTest +*/ + +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Window; +import java.awt.event.HierarchyBoundsAdapter; +import java.lang.reflect.InvocationTargetException; + +public class HierarchyEventOnWindowTest { + static Frame frame; + + public static void main(String args[]) throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + frame = new Frame("HierarchyEventOnWindowTest"); + CustomWindow window = new CustomWindow(frame); + window.enableEvents(); + frame.add(new Button("")); + window.disableEvents(); + window.addHierarchyListener(e -> {}); + window.addHierarchyBoundsListener(new HierarchyBoundsAdapter(){}); + frame.add(new Button("")); + }); + + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } +} + +class CustomWindow extends Window { + public CustomWindow(Frame frame) { + super(frame); + } + public void enableEvents() { + enableEvents(AWTEvent.HIERARCHY_EVENT_MASK | + AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + } + public void disableEvents() { + disableEvents(AWTEvent.HIERARCHY_EVENT_MASK | + AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/HierarchyEvent/ObjectSourceTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/HierarchyEvent/ObjectSourceTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/HierarchyEvent/ObjectSourceTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/HierarchyEvent/ObjectSourceTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4420658 + @summary No ClassCastException should be thrown when getComponent() + is called on an event with a non-Component source. + The result should be null. + @run main ObjectSourceTest +*/ + +import java.awt.Component; +import java.awt.Panel; +import java.awt.event.HierarchyEvent; +import java.lang.reflect.InvocationTargetException; + + +public class ObjectSourceTest { + static Panel panel; + + public static void main(String args[]) throws InterruptedException, + InvocationTargetException { + panel = new Panel(); + + HierarchyEvent he = new HierarchyEvent(panel, HierarchyEvent.ANCESTOR_MOVED, + panel, panel); + Object obj = new Object(); + he.setSource(obj); + + Component comp = he.getComponent(); + if (comp != null) { + throw new RuntimeException("ObjectSourceTest failed. comp != null"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/HierarchyEvent/SpecTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/HierarchyEvent/SpecTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/HierarchyEvent/SpecTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/HierarchyEvent/SpecTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1248 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4222172 + @summary Verifies initial implementation of HierarchyEvent (programmatic) + @key headful + @run main SpecTest +*/ + +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Window; +import java.awt.event.HierarchyBoundsListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class SpecTest extends Frame implements HierarchyListener, HierarchyBoundsListener { + static SpecTest f; + + public static void main(String args[]) throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> init()); + f.start(); + } + + class EELabel extends Label { + private long mask = 0; + public EELabel(String s) { + super(s); + } + + protected void processHierarchyEvent(HierarchyEvent e) { + super.processHierarchyEvent(e); + if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.HIERARCHY_CHANGED: + hierarchyChanged(e); + break; + default: + break; + } + } + } + + protected void processHierarchyBoundsEvent(HierarchyEvent e) { + super.processHierarchyBoundsEvent(e); + if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.ANCESTOR_MOVED: + ancestorMoved(e); + break; + case HierarchyEvent.ANCESTOR_RESIZED: + ancestorResized(e); + break; + default: + break; + } + } + } + + public void pubEnableEvents(long eventsToEnable) { + mask |= eventsToEnable; + enableEvents(eventsToEnable); + } + + public void pubDisableEvents(long eventsToDisable) { + mask &= ~eventsToDisable; + disableEvents(eventsToDisable); + } + } + + class EEJLabel extends JLabel { + private long mask = 0; + public EEJLabel(String s) { + super(s); + } + protected void processHierarchyEvent(HierarchyEvent e) { + super.processHierarchyEvent(e); + if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.HIERARCHY_CHANGED: + hierarchyChanged(e); + break; + default: + break; + } + } + } + + protected void processHierarchyBoundsEvent(HierarchyEvent e) { + super.processHierarchyBoundsEvent(e); + if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.ANCESTOR_MOVED: + ancestorMoved(e); + break; + case HierarchyEvent.ANCESTOR_RESIZED: + ancestorResized(e); + break; + default: + break; + } + } + } + + public void pubEnableEvents(long eventsToEnable) { + mask |= eventsToEnable; + enableEvents(eventsToEnable); + } + + public void pubDisableEvents(long eventsToDisable) { + mask &= ~eventsToDisable; + disableEvents(eventsToDisable); + } + } + + class EEPanel extends Panel { + private long mask = 0; + protected void processHierarchyEvent(HierarchyEvent e) { + super.processHierarchyEvent(e); + if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.HIERARCHY_CHANGED: + hierarchyChanged(e); + break; + default: + break; + } + } + } + + protected void processHierarchyBoundsEvent(HierarchyEvent e) { + super.processHierarchyBoundsEvent(e); + if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.ANCESTOR_MOVED: + ancestorMoved(e); + break; + case HierarchyEvent.ANCESTOR_RESIZED: + ancestorResized(e); + break; + default: + break; + } + } + } + + public void pubEnableEvents(long eventsToEnable) { + mask |= eventsToEnable; + enableEvents(eventsToEnable); + } + + public void pubDisableEvents(long eventsToDisable) { + mask &= ~eventsToDisable; + disableEvents(eventsToDisable); + } + } + + class EEJPanel extends JPanel { + private long mask = 0; + protected void processHierarchyEvent(HierarchyEvent e) { + super.processHierarchyEvent(e); + if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.HIERARCHY_CHANGED: + hierarchyChanged(e); + break; + default: + break; + } + } + } + + protected void processHierarchyBoundsEvent(HierarchyEvent e) { + super.processHierarchyBoundsEvent(e); + if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) { + switch (e.getID()) { + case HierarchyEvent.ANCESTOR_MOVED: + ancestorMoved(e); + break; + case HierarchyEvent.ANCESTOR_RESIZED: + ancestorResized(e); + break; + default: + break; + } + } + } + + public void pubEnableEvents(long eventsToEnable) { + mask |= eventsToEnable; + enableEvents(eventsToEnable); + } + + public void pubDisableEvents(long eventsToDisable) { + mask &= ~eventsToDisable; + disableEvents(eventsToDisable); + } + } + + int parentChanged, displayabilityChanged, showingChanged, ancestorMoved, + ancestorResized; + private static final int OBJ_ARRAY_SIZE = 2; + Component[] source = new Component[OBJ_ARRAY_SIZE], + changed = new Component[OBJ_ARRAY_SIZE]; + Container[] changedParent = new Container[OBJ_ARRAY_SIZE]; + + boolean assertParent = false, assertDisplayability = false, + assertShowing = false, assertMoved = false, assertResized = false; + + private void flushEventQueue() throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(() -> {}); + } + + private void testAdd(Component child, Container parent, int count) + throws InterruptedException, InvocationTargetException { + assertParent = true; + parentChanged = count; + parent.add(child); + flushEventQueue(); + if (parentChanged != 0) { + throw new RuntimeException("hierarchyChanged(PARENT_CHANGED) invoked "+ + parentChanged+" too few times"); + } + assertParent = false; + } + + private void testRemove(Component child, Container parent, int count) + throws InterruptedException, InvocationTargetException { + assertParent = true; + parentChanged = count; + parent.remove(child); + flushEventQueue(); + if (parentChanged != 0) { + throw new RuntimeException("hierarchyChanged(PARENT_CHANGED) invoked "+ + parentChanged+" too few times"); + } + assertParent = false; + } + + private void testSetLocation(Component changed, int x, int y, int count) + throws InterruptedException, InvocationTargetException { + assertMoved = true; + ancestorMoved = count; + changed.setLocation(x, y); + flushEventQueue(); + if (ancestorMoved != 0) { + throw new RuntimeException("ancestorMoved invoked "+ancestorMoved+ + " too few times"); + } + assertMoved = false; + } + + private void testSetSize(Component changed, int w, int h, int count) + throws InterruptedException, InvocationTargetException { + assertResized = true; + ancestorResized = count; + changed.setSize(w, h); + flushEventQueue(); + if (ancestorResized != 0) { + throw new RuntimeException("ancestorResized invoked "+ancestorResized+ + " too few times"); + } + assertResized = false; + } + + private void testPack(Window topLevel, int displayabilityCount) + throws InterruptedException, InvocationTargetException { + assertDisplayability = true; + assertShowing = true; + displayabilityChanged = displayabilityCount; + showingChanged = 0; + topLevel.pack(); + flushEventQueue(); + if (displayabilityChanged != 0) { + throw new RuntimeException("hierarchyChanged(DISPLAYABILITY_CHANGED) "+ + "invoked "+displayabilityChanged+ + " too few times"); + } + if (showingChanged != 0) { + throw new RuntimeException("hierarchyChanged(SHOWING_CHANGED) "+ + "invoked, but should not have been"); + } + assertDisplayability = false; + assertShowing = false; + } + + private void testShow(Window topLevel, int displayabilityCount, + int showingCount) + throws InterruptedException, InvocationTargetException { + assertDisplayability = true; + assertShowing = true; + displayabilityChanged = displayabilityCount; + showingChanged = showingCount; + topLevel.show(); + flushEventQueue(); + if (displayabilityChanged != 0) { + throw new RuntimeException("hierarchyChanged(DISPLAYABILITY_CHANGED) "+ + "invoked "+displayabilityChanged+ + " too few times"); + } + if (showingChanged != 0) { + throw new RuntimeException("hierarchyChanged(SHOWING_CHANGED) "+ + "invoked "+showingChanged+" too few times"); + } + assertDisplayability = false; + assertShowing = false; + } + + private void testHide(Window topLevel, int showingCount) + throws InterruptedException, InvocationTargetException { + assertDisplayability = true; + assertShowing = true; + displayabilityChanged = 0; + showingChanged = showingCount; + topLevel.hide(); + flushEventQueue(); + if (displayabilityChanged != 0) { + throw new RuntimeException("hierarchyChanged(DISPLAYABILITY_CHANGED) "+ + "invoked, but should not have been"); + } + if (showingChanged != 0) { + throw new RuntimeException("hierarchyChanged(SHOWING_CHANGED) "+ + "invoked "+showingChanged+" too few times"); + } + assertDisplayability = false; + assertShowing = false; + } + + private void testDispose(Window topLevel, int displayabilityCount, + int showingCount) + throws InterruptedException, InvocationTargetException { + assertDisplayability = true; + assertShowing = true; + displayabilityChanged = displayabilityCount; + showingChanged = showingCount; + topLevel.dispose(); + flushEventQueue(); + if (displayabilityChanged != 0) { + throw new RuntimeException("hierarchyChanged(DISPLAYABILITY_CHANGED) "+ + "invoked "+displayabilityChanged+ + " too few times"); + } + if (showingChanged != 0) { + throw new RuntimeException("hierarchyChanged(SHOWING_CHANGED) "+ + "invoked "+showingChanged+" too few times"); + } + assertDisplayability = false; + assertShowing = false; + } + + private void assertObjectsImpl(HierarchyEvent e) { + int match = -1; + + for (int i = 0; i < OBJ_ARRAY_SIZE; i++) { + if (e.getComponent() == source[i]) { + match = i; + break; + } + } + + if (match == -1) { + String str = "\n\nsource incorrect, was "+e.getComponent()+"\n\n"; + for (int i = 0; i < OBJ_ARRAY_SIZE; i++) { + str += "available source: "+source[i]+"\n\n"; + } + str += "event: "+e+"\n"; + throw new RuntimeException(str); + } + + if (e.getChanged() != changed[match]) { + if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED && + (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { + System.err.println("warning (known bug): changed for "+ + "DISPLAYABILITY_CHANGED event incorrect"); + } else { + throw new RuntimeException("\n\nchanged incorrect, was "+ + e.getChanged()+ + ", should be "+changed[match]+"\n\n"+ + "event: "+e+"\n"); + } + } + + if (e.getChangedParent() != changedParent[match]) { + if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED && + (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { + System.err.println("warning (known bug): changedParent for "+ + "DISPLAYABILITY_CHANGED event incorrect"); + } else { + throw new RuntimeException("changedParent incorrect, was "+ + e.getChangedParent()+ + ", should be "+changedParent[match]+"\n\n"+ + "event: "+e+"\n"); + } + } + } + + private void setObjects(int index, Component source, Component changed, + Container changedParent) { + this.source[index] = source; + this.changed[index] = changed; + this.changedParent[index] = changedParent; + } + + private void resetObjects() { + for (int i = 0; i < OBJ_ARRAY_SIZE; i++) { + setObjects(i, null, null, null); + } + } + + public void hierarchyChanged(HierarchyEvent e) { + if (assertParent && + (e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) { + assertObjectsImpl(e); + parentChanged--; + } + if (assertDisplayability && + (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0){ + assertObjectsImpl(e); + displayabilityChanged--; + } + if (assertShowing && + (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { + assertObjectsImpl(e); + showingChanged--; + } + } + + public void ancestorMoved(HierarchyEvent e) { + if (!assertMoved) + return; + + assertObjectsImpl(e); + ancestorMoved--; + } + + public void ancestorResized(HierarchyEvent e) { + if (!assertResized) + return; + + assertObjectsImpl(e); + ancestorResized--; + } + + public static void init() { + f = new SpecTest(); + f.setTitle("SpecTest"); + f.setLayout(new BorderLayout()); + } + + private void test1(Component source, Component changed, + Container changedParent, Window topLevel, + int hierarchyCount, int hierarchyBoundsCount) + throws InterruptedException, InvocationTargetException { + changed.setBounds(0, 0, 100, 100); + topLevel.dispose(); + resetObjects(); + + setObjects(0, source, changed, changedParent); + + testRemove(changed, changedParent, hierarchyCount); + testAdd(changed, changedParent, hierarchyCount); + testSetLocation(changed, 200, 250, hierarchyBoundsCount); + testSetSize(changed, 50, 50, hierarchyBoundsCount); + + setObjects(0, source, topLevel, null); + + testPack(topLevel, hierarchyCount); + testDispose(topLevel, hierarchyCount, 0); + testPack(topLevel, hierarchyCount); + testShow(topLevel, 0, hierarchyCount); + testDispose(topLevel, hierarchyCount, hierarchyCount); + testShow(topLevel, hierarchyCount, hierarchyCount); + testHide(topLevel, hierarchyCount); + testDispose(topLevel, hierarchyCount, 0); + + resetObjects(); + } + + private void test2(Component source1, Container parent1, + Component source2, Container parent2, + Window topLevel) + throws InterruptedException, InvocationTargetException { + topLevel.setBounds(0, 0, 100, 100); + topLevel.dispose(); + resetObjects(); + + setObjects(0, source1, source1, parent1); + testRemove(source1, parent1, 1); + testAdd(source1, parent1, 1); + + setObjects(0, source2, source2, parent2); + testRemove(source2, parent2, 1); + testAdd(source2, parent2, 1); + + setObjects(0, source1, topLevel, null); + setObjects(1, source2, topLevel, null); + + testSetLocation(topLevel, 200, 250, 2); + testSetSize(topLevel, 50, 50, 2); + + testPack(topLevel, 2); + testDispose(topLevel, 2, 0); + testPack(topLevel, 2); + testShow(topLevel, 0, 2); + testDispose(topLevel, 2, 2); + testShow(topLevel, 2, 2); + testHide(topLevel, 2); + testDispose(topLevel, 2, 0); + + resetObjects(); + } + + public void start() throws InterruptedException, InvocationTargetException { + /* + f + | + ----------------------------------------- + | | | | | | + l1 l2 p1 p2 p5 p6 + | | | | + ----- ----- | | + | | | | | | + l3 l4 l5 l6 p3 p4 + | | + ----- ----- + | | | | + l7 l8 l9 l10 + */ + + // listener-only tests + + { + Label l1 = new Label("Label 1"); + JLabel l2 = new JLabel("Label 2"); + Panel p1 = new Panel(); + JPanel p2 = new JPanel(); + Panel p5 = new Panel(); + JPanel p6 = new JPanel(); + + Label l3 = new Label("Label 3"); + JLabel l4 = new JLabel("Label 4"); + Label l5 = new Label("Label 5"); + JLabel l6 = new JLabel("Label 6"); + JPanel p3 = new JPanel(); + Panel p4 = new Panel(); + + Label l7 = new Label("Label 7"); + JLabel l8 = new JLabel("Label 8"); + JLabel l9 = new JLabel("Label 9"); + Label l10 = new Label("Label 10"); + + f.add(l1); + f.add(l2); + f.add(p1); + f.add(p2); + f.add(p5); + f.add(p6); + + p1.add(l3); + p1.add(l4); + + p2.add(l5); + p2.add(l6); + + p5.add(p3); + + p6.add(p4); + + p3.add(l7); + p3.add(l8); + + p4.add(l9); + p4.add(l10); + + + + // test1 + + l1.addHierarchyListener(this); + l1.addHierarchyBoundsListener(this); + test1(l1, l1, f, f, 1, 0); + l1.addHierarchyListener(this); + l1.addHierarchyBoundsListener(this); + test1(l1, l1, f, f, 2, 0); + l1.removeHierarchyListener(this); + l1.removeHierarchyBoundsListener(this); + l1.removeHierarchyListener(this); + l1.removeHierarchyBoundsListener(this); + + l2.addHierarchyListener(this); + l2.addHierarchyBoundsListener(this); + test1(l2, l2, f, f, 1, 0); + l2.addHierarchyListener(this); + l2.addHierarchyBoundsListener(this); + test1(l2, l2, f, f, 2, 0); + l2.removeHierarchyListener(this); + l2.removeHierarchyBoundsListener(this); + l2.removeHierarchyListener(this); + l2.removeHierarchyBoundsListener(this); + + p1.addHierarchyListener(this); + p1.addHierarchyBoundsListener(this); + test1(p1, p1, f, f, 1, 0); + p1.addHierarchyListener(this); + p1.addHierarchyBoundsListener(this); + test1(p1, p1, f, f, 2, 0); + p1.removeHierarchyListener(this); + p1.removeHierarchyBoundsListener(this); + p1.removeHierarchyListener(this); + p1.removeHierarchyBoundsListener(this); + + p2.addHierarchyListener(this); + p2.addHierarchyBoundsListener(this); + test1(p2, p2, f, f, 1, 0); + p2.addHierarchyListener(this); + p2.addHierarchyBoundsListener(this); + test1(p2, p2, f, f, 2, 0); + p2.removeHierarchyListener(this); + p2.removeHierarchyBoundsListener(this); + p2.removeHierarchyListener(this); + p2.removeHierarchyBoundsListener(this); + + p5.addHierarchyListener(this); + p5.addHierarchyBoundsListener(this); + test1(p5, p5, f, f, 1, 0); + p5.addHierarchyListener(this); + p5.addHierarchyBoundsListener(this); + test1(p5, p5, f, f, 2, 0); + p5.removeHierarchyListener(this); + p5.removeHierarchyBoundsListener(this); + p5.removeHierarchyListener(this); + p5.removeHierarchyBoundsListener(this); + + p6.addHierarchyListener(this); + p6.addHierarchyBoundsListener(this); + test1(p6, p6, f, f, 1, 0); + p6.addHierarchyListener(this); + p6.addHierarchyBoundsListener(this); + test1(p6, p6, f, f, 2, 0); + p6.removeHierarchyListener(this); + p6.removeHierarchyBoundsListener(this); + p6.removeHierarchyListener(this); + p6.removeHierarchyBoundsListener(this); + + l3.addHierarchyListener(this); + l3.addHierarchyBoundsListener(this); + test1(l3, l3, p1, f, 1, 0); + test1(l3, p1, f, f, 1, 1); + l3.addHierarchyListener(this); + l3.addHierarchyBoundsListener(this); + test1(l3, l3, p1, f, 2, 0); + test1(l3, p1, f, f, 2, 2); + l3.removeHierarchyListener(this); + l3.removeHierarchyBoundsListener(this); + l3.removeHierarchyListener(this); + l3.removeHierarchyBoundsListener(this); + + l4.addHierarchyListener(this); + l4.addHierarchyBoundsListener(this); + test1(l4, l4, p1, f, 1, 0); + test1(l4, p1, f, f, 1, 1); + l4.addHierarchyListener(this); + l4.addHierarchyBoundsListener(this); + test1(l4, l4, p1, f, 2, 0); + test1(l4, p1, f, f, 2, 2); + l4.removeHierarchyListener(this); + l4.removeHierarchyBoundsListener(this); + l4.removeHierarchyListener(this); + l4.removeHierarchyBoundsListener(this); + + l5.addHierarchyListener(this); + l5.addHierarchyBoundsListener(this); + test1(l5, l5, p2, f, 1, 0); + test1(l5, p2, f, f, 1, 1); + l5.addHierarchyListener(this); + l5.addHierarchyBoundsListener(this); + test1(l5, l5, p2, f, 2, 0); + test1(l5, p2, f, f, 2, 2); + l5.removeHierarchyListener(this); + l5.removeHierarchyBoundsListener(this); + l5.removeHierarchyListener(this); + l5.removeHierarchyBoundsListener(this); + + l6.addHierarchyListener(this); + l6.addHierarchyBoundsListener(this); + test1(l6, l6, p2, f, 1, 0); + test1(l6, p2, f, f, 1, 1); + l6.addHierarchyListener(this); + l6.addHierarchyBoundsListener(this); + test1(l6, l6, p2, f, 2, 0); + test1(l6, p2, f, f, 2, 2); + l6.removeHierarchyListener(this); + l6.removeHierarchyBoundsListener(this); + l6.removeHierarchyListener(this); + l6.removeHierarchyBoundsListener(this); + + p3.addHierarchyListener(this); + p3.addHierarchyBoundsListener(this); + test1(p3, p3, p5, f, 1, 0); + test1(p3, p5, f, f, 1, 1); + p3.addHierarchyListener(this); + p3.addHierarchyBoundsListener(this); + test1(p3, p3, p5, f, 2, 0); + test1(p3, p5, f, f, 2, 2); + p3.removeHierarchyListener(this); + p3.removeHierarchyBoundsListener(this); + p3.removeHierarchyListener(this); + p3.removeHierarchyBoundsListener(this); + + p4.addHierarchyListener(this); + p4.addHierarchyBoundsListener(this); + test1(p4, p4, p6, f, 1, 0); + test1(p4, p6, f, f, 1, 1); + p4.addHierarchyListener(this); + p4.addHierarchyBoundsListener(this); + test1(p4, p4, p6, f, 2, 0); + test1(p4, p6, f, f, 2, 2); + p4.removeHierarchyListener(this); + p4.removeHierarchyBoundsListener(this); + p4.removeHierarchyListener(this); + p4.removeHierarchyBoundsListener(this); + + l7.addHierarchyListener(this); + l7.addHierarchyBoundsListener(this); + test1(l7, l7, p3, f, 1, 0); + test1(l7, p3, p5, f, 1, 1); + test1(l7, p5, f, f, 1, 1); + l7.addHierarchyListener(this); + l7.addHierarchyBoundsListener(this); + test1(l7, l7, p3, f, 2, 0); + test1(l7, p3, p5, f, 2, 2); + test1(l7, p5, f, f, 2, 2); + l7.removeHierarchyListener(this); + l7.removeHierarchyBoundsListener(this); + l7.removeHierarchyListener(this); + l7.removeHierarchyBoundsListener(this); + + l8.addHierarchyListener(this); + l8.addHierarchyBoundsListener(this); + test1(l8, l8, p3, f, 1, 0); + test1(l8, p3, p5, f, 1, 1); + test1(l8, p5, f, f, 1, 1); + l8.addHierarchyListener(this); + l8.addHierarchyBoundsListener(this); + test1(l8, l8, p3, f, 2, 0); + test1(l8, p3, p5, f, 2, 2); + test1(l8, p5, f, f, 2, 2); + l8.removeHierarchyListener(this); + l8.removeHierarchyBoundsListener(this); + l8.removeHierarchyListener(this); + l8.removeHierarchyBoundsListener(this); + + l9.addHierarchyListener(this); + l9.addHierarchyBoundsListener(this); + test1(l9, l9, p4, f, 1, 0); + test1(l9, p4, p6, f, 1, 1); + test1(l9, p6, f, f, 1, 1); + l9.addHierarchyListener(this); + l9.addHierarchyBoundsListener(this); + test1(l9, l9, p4, f, 2, 0); + test1(l9, p4, p6, f, 2, 2); + test1(l9, p6, f, f, 2, 2); + l9.removeHierarchyListener(this); + l9.removeHierarchyBoundsListener(this); + l9.removeHierarchyListener(this); + l9.removeHierarchyBoundsListener(this); + + l10.addHierarchyListener(this); + l10.addHierarchyBoundsListener(this); + test1(l10, l10, p4, f, 1, 0); + test1(l10, p4, p6, f, 1, 1); + test1(l10, p6, f, f, 1, 1); + l10.addHierarchyListener(this); + l10.addHierarchyBoundsListener(this); + test1(l10, l10, p4, f, 2, 0); + test1(l10, p4, p6, f, 2, 2); + test1(l10, p6, f, f, 2, 2); + l10.removeHierarchyListener(this); + l10.removeHierarchyBoundsListener(this); + l10.removeHierarchyListener(this); + l10.removeHierarchyBoundsListener(this); + + + + // test2 + + l1.addHierarchyListener(this); + l10.addHierarchyListener(this); + l1.addHierarchyBoundsListener(this); + l10.addHierarchyBoundsListener(this); + test2(l1, f, l10, p4, f); + l1.removeHierarchyListener(this); + l10.removeHierarchyListener(this); + l1.removeHierarchyBoundsListener(this); + l10.removeHierarchyBoundsListener(this); + + l2.addHierarchyListener(this); + l9.addHierarchyListener(this); + l2.addHierarchyBoundsListener(this); + l9.addHierarchyBoundsListener(this); + test2(l2, f, l9, p4, f); + l2.removeHierarchyListener(this); + l9.removeHierarchyListener(this); + l2.removeHierarchyBoundsListener(this); + l9.removeHierarchyBoundsListener(this); + + l3.addHierarchyListener(this); + l8.addHierarchyListener(this); + l3.addHierarchyBoundsListener(this); + l8.addHierarchyBoundsListener(this); + test2(l3, p1, l8, p3, f); + l3.removeHierarchyListener(this); + l8.removeHierarchyListener(this); + l3.removeHierarchyBoundsListener(this); + l8.removeHierarchyBoundsListener(this); + + l4.addHierarchyListener(this); + l7.addHierarchyListener(this); + l4.addHierarchyBoundsListener(this); + l7.addHierarchyBoundsListener(this); + test2(l4, p1, l7, p3, f); + l4.removeHierarchyListener(this); + l7.removeHierarchyListener(this); + l4.removeHierarchyBoundsListener(this); + l7.removeHierarchyBoundsListener(this); + + l5.addHierarchyListener(this); + l6.addHierarchyListener(this); + l5.addHierarchyBoundsListener(this); + l6.addHierarchyBoundsListener(this); + test2(l5, p2, l6, p2, f); + l5.removeHierarchyListener(this); + l6.removeHierarchyListener(this); + l5.removeHierarchyBoundsListener(this); + l6.removeHierarchyBoundsListener(this); + + p1.addHierarchyListener(this); + p4.addHierarchyListener(this); + p1.addHierarchyBoundsListener(this); + p4.addHierarchyBoundsListener(this); + test2(p1, f, p4, p6, f); + p1.removeHierarchyListener(this); + p4.removeHierarchyListener(this); + p1.removeHierarchyBoundsListener(this); + p4.removeHierarchyBoundsListener(this); + + p2.addHierarchyListener(this); + p3.addHierarchyListener(this); + p2.addHierarchyBoundsListener(this); + p3.addHierarchyBoundsListener(this); + test2(p2, f, p3, p5, f); + p2.removeHierarchyListener(this); + p3.removeHierarchyListener(this); + p2.removeHierarchyBoundsListener(this); + p3.removeHierarchyBoundsListener(this); + + p5.addHierarchyListener(this); + p6.addHierarchyListener(this); + p5.addHierarchyBoundsListener(this); + p6.addHierarchyBoundsListener(this); + test2(p5, f, p6, f, f); + p5.removeHierarchyListener(this); + p6.removeHierarchyListener(this); + p5.removeHierarchyBoundsListener(this); + p6.removeHierarchyBoundsListener(this); + } + + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + f.removeAll(); + } + }); + + // mixed listener/eventEnabled and eventEnabled-only tests + + { + EELabel l1 = new EELabel("Label 1"); + EEJLabel l2 = new EEJLabel("Label 2"); + EEPanel p1 = new EEPanel(); + EEJPanel p2 = new EEJPanel(); + EEPanel p5 = new EEPanel(); + EEJPanel p6 = new EEJPanel(); + + EELabel l3 = new EELabel("Label 3"); + EEJLabel l4 = new EEJLabel("Label 4"); + EELabel l5 = new EELabel("Label 5"); + EEJLabel l6 = new EEJLabel("Label 6"); + EEJPanel p3 = new EEJPanel(); + EEPanel p4 = new EEPanel(); + + EELabel l7 = new EELabel("Label 7"); + EEJLabel l8 = new EEJLabel("Label 8"); + EEJLabel l9 = new EEJLabel("Label 9"); + EELabel l10 = new EELabel("Label 10"); + + f.add(l1); + f.add(l2); + f.add(p1); + f.add(p2); + f.add(p5); + f.add(p6); + + p1.add(l3); + p1.add(l4); + + p2.add(l5); + p2.add(l6); + + p5.add(p3); + + p6.add(p4); + + p3.add(l7); + p3.add(l8); + + p4.add(l9); + p4.add(l10); + + + + // test3 + + l1.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l1.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l1, l1, f, f, 1, 0); + l1.addHierarchyListener(this); + l1.addHierarchyBoundsListener(this); + test1(l1, l1, f, f, 2, 0); + l1.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l1.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l1.removeHierarchyListener(this); + l1.removeHierarchyBoundsListener(this); + + l2.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l2.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l2, l2, f, f, 1, 0); + l2.addHierarchyListener(this); + l2.addHierarchyBoundsListener(this); + test1(l2, l2, f, f, 2, 0); + l2.removeHierarchyListener(this); + l2.removeHierarchyBoundsListener(this); + l2.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l2.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + p1.addHierarchyListener(this); + p1.addHierarchyBoundsListener(this); + test1(p1, p1, f, f, 1, 0); + p1.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p1.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(p1, p1, f, f, 2, 0); + p1.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p1.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p1.removeHierarchyListener(this); + p1.removeHierarchyBoundsListener(this); + + p2.addHierarchyListener(this); + p2.addHierarchyBoundsListener(this); + test1(p2, p2, f, f, 1, 0); + p2.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p2.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(p2, p2, f, f, 2, 0); + p2.removeHierarchyListener(this); + p2.removeHierarchyBoundsListener(this); + p2.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p2.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + p5.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p5.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(p5, p5, f, f, 1, 0); + p5.addHierarchyListener(this); + p5.addHierarchyBoundsListener(this); + test1(p5, p5, f, f, 2, 0); + p5.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p5.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p5.removeHierarchyListener(this); + p5.removeHierarchyBoundsListener(this); + + p6.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p6.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(p6, p6, f, f, 1, 0); + p6.addHierarchyListener(this); + p6.addHierarchyBoundsListener(this); + test1(p6, p6, f, f, 2, 0); + p6.removeHierarchyListener(this); + p6.removeHierarchyBoundsListener(this); + p6.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p6.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l3.addHierarchyListener(this); + l3.addHierarchyBoundsListener(this); + test1(l3, l3, p1, f, 1, 0); + test1(l3, p1, f, f, 1, 1); + l3.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l3.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l3, l3, p1, f, 2, 0); + test1(l3, p1, f, f, 2, 2); + l3.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l3.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l3.removeHierarchyListener(this); + l3.removeHierarchyBoundsListener(this); + + l4.addHierarchyListener(this); + l4.addHierarchyBoundsListener(this); + test1(l4, l4, p1, f, 1, 0); + test1(l4, p1, f, f, 1, 1); + l4.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l4.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l4, l4, p1, f, 2, 0); + test1(l4, p1, f, f, 2, 2); + l4.removeHierarchyListener(this); + l4.removeHierarchyBoundsListener(this); + l4.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l4.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l5.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l5.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l5, l5, p2, f, 1, 0); + test1(l5, p2, f, f, 1, 1); + l5.addHierarchyListener(this); + l5.addHierarchyBoundsListener(this); + test1(l5, l5, p2, f, 2, 0); + test1(l5, p2, f, f, 2, 2); + l5.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l5.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l5.removeHierarchyListener(this); + l5.removeHierarchyBoundsListener(this); + + l6.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l6.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l6, l6, p2, f, 1, 0); + test1(l6, p2, f, f, 1, 1); + l6.addHierarchyListener(this); + l6.addHierarchyBoundsListener(this); + test1(l6, l6, p2, f, 2, 0); + test1(l6, p2, f, f, 2, 2); + l6.removeHierarchyListener(this); + l6.removeHierarchyBoundsListener(this); + l6.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l6.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + p3.addHierarchyListener(this); + p3.addHierarchyBoundsListener(this); + test1(p3, p3, p5, f, 1, 0); + test1(p3, p5, f, f, 1, 1); + p3.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p3.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(p3, p3, p5, f, 2, 0); + test1(p3, p5, f, f, 2, 2); + p3.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p3.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p3.removeHierarchyListener(this); + p3.removeHierarchyBoundsListener(this); + + p4.addHierarchyListener(this); + p4.addHierarchyBoundsListener(this); + test1(p4, p4, p6, f, 1, 0); + test1(p4, p6, f, f, 1, 1); + p4.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p4.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(p4, p4, p6, f, 2, 0); + test1(p4, p6, f, f, 2, 2); + p4.removeHierarchyListener(this); + p4.removeHierarchyBoundsListener(this); + p4.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p4.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l7.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l7.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l7, l7, p3, f, 1, 0); + test1(l7, p3, p5, f, 1, 1); + test1(l7, p5, f, f, 1, 1); + l7.addHierarchyListener(this); + l7.addHierarchyBoundsListener(this); + test1(l7, l7, p3, f, 2, 0); + test1(l7, p3, p5, f, 2, 2); + test1(l7, p5, f, f, 2, 2); + l7.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l7.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l7.removeHierarchyListener(this); + l7.removeHierarchyBoundsListener(this); + + l8.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l8.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l8, l8, p3, f, 1, 0); + test1(l8, p3, p5, f, 1, 1); + test1(l8, p5, f, f, 1, 1); + l8.addHierarchyListener(this); + l8.addHierarchyBoundsListener(this); + test1(l8, l8, p3, f, 2, 0); + test1(l8, p3, p5, f, 2, 2); + test1(l8, p5, f, f, 2, 2); + l8.removeHierarchyListener(this); + l8.removeHierarchyBoundsListener(this); + l8.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l8.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l9.addHierarchyListener(this); + l9.addHierarchyBoundsListener(this); + test1(l9, l9, p4, f, 1, 0); + test1(l9, p4, p6, f, 1, 1); + test1(l9, p6, f, f, 1, 1); + l9.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l9.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l9, l9, p4, f, 2, 0); + test1(l9, p4, p6, f, 2, 2); + test1(l9, p6, f, f, 2, 2); + l9.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l9.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l9.removeHierarchyListener(this); + l9.removeHierarchyBoundsListener(this); + + l10.addHierarchyListener(this); + l10.addHierarchyBoundsListener(this); + test1(l10, l10, p4, f, 1, 0); + test1(l10, p4, p6, f, 1, 1); + test1(l10, p6, f, f, 1, 1); + l10.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l10.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test1(l10, l10, p4, f, 2, 0); + test1(l10, p4, p6, f, 2, 2); + test1(l10, p6, f, f, 2, 2); + l10.removeHierarchyListener(this); + l10.removeHierarchyBoundsListener(this); + l10.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l10.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + + + // test4 + + l1.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l10.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l1.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l10.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(l1, f, l10, p4, f); + l1.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l10.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l1.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l10.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l2.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l9.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l2.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l9.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(l2, f, l9, p4, f); + l2.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l9.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l2.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l9.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l3.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l8.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l3.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l8.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(l3, p1, l8, p3, f); + l3.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l8.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l3.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l8.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l4.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l7.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l4.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l7.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(l4, p1, l7, p3, f); + l4.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l7.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l4.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l7.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + l5.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l6.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l5.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l6.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(l5, p2, l6, p2, f); + l5.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l6.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + l5.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + l6.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + p1.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p4.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p1.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p4.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(p1, f, p4, p6, f); + p1.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p4.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p1.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p4.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + p2.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p3.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p2.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p3.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(p2, f, p3, p5, f); + p2.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p3.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p2.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p3.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + + p5.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p6.pubEnableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p5.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p6.pubEnableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + test2(p5, f, p6, f, f); + p5.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p6.pubDisableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + p5.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + p6.pubDisableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + } + + System.out.println("passed"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/InputEvent/MouseModsTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/InputEvent/MouseModsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/InputEvent/MouseModsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/InputEvent/MouseModsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4353201 + @summary Wrong modifiers on InputEvent + @key headful + @run main MouseModsTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.MouseInfo; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.lang.reflect.InvocationTargetException; + +public class MouseModsTest { + static volatile int testCtrl = 0; + static volatile int testBtn = 0; + static volatile boolean passed = true; + + static final int BUTTONS = Math.min(3, MouseInfo.getNumberOfButtons()); + static final int KEYS = 2; + + static Frame frame; + static Panel panel; + static Canvas button1; + static Canvas button2; + + static volatile Point pt1; + static volatile Point pt2; + + public static void main(String args[]) throws AWTException, + InterruptedException, InvocationTargetException { + + EventQueue.invokeAndWait(() -> { + frame = new Frame("MouseModsTest"); + panel = new Panel(); + button1 = new TestCanvas(); + button2 = new TestCanvas(); + frame.setSize(300, 200); + panel.add(button1); + panel.add(button2); + frame.add(panel); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + try { + Robot robot; + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + pt1 = button1.getLocationOnScreen(); + pt2 = button2.getLocationOnScreen(); + + pt1.x += button1.getSize().width / 2; + pt1.y += button1.getSize().height / 2; + + pt2.x += button2.getSize().width / 2; + pt2.y += button2.getSize().height / 2; + }); + + robot.mouseMove(pt2.x, pt2.y); + + //Keyboard to Mouse Test + for (int ctrl = 1; ctrl <= KEYS; ++ctrl) { + testCtrl = ctrl; + robot.keyPress(getKeycode(ctrl)); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + for (int btn = 2; btn <= BUTTONS; ++btn) { + testBtn = btn; + robot.mousePress(getMouseModifier(btn)); + robot.mouseMove(pt1.x, pt1.y); + robot.mouseMove(pt2.x, pt2.y); + robot.mouseRelease(getMouseModifier(btn)); + } + robot.keyRelease(getKeycode(ctrl)); + } + + //Mouse to Mouse Test + for (int btn1 = 1; btn1 <= BUTTONS; ++btn1) { + testBtn = btn1; + robot.mousePress(getMouseModifier(btn1)); + for (int btn = 1; btn <= BUTTONS; ++btn) { + if (btn == btn1) continue; + testBtn = btn; + robot.mousePress(getMouseModifier(btn)); + robot.mouseMove(pt1.x, pt1.y); + robot.mouseMove(pt2.x, pt2.y); + robot.mouseRelease(getMouseModifier(btn)); + } + testBtn = btn1; + robot.mouseRelease(getMouseModifier(btn1)); + } + testBtn = 0; + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + if (!passed) { + throw new RuntimeException("Test Failed"); + } + } + + static int getKeycode(int ctrl) { + switch (ctrl) { + case 1: return KeyEvent.VK_SHIFT; + case 2: return KeyEvent.VK_CONTROL; + case 3: return KeyEvent.VK_ALT; + default: return 0; + } + } + + static int getKeyModifier(int ctrl) { + switch (ctrl) { + case 1: return InputEvent.SHIFT_MASK; + case 2: return InputEvent.CTRL_MASK; + case 3: return InputEvent.ALT_MASK; + default: return 0; + } + } + + static int getMouseModifier(int btn) { + switch (btn) { + case 1: return InputEvent.BUTTON1_MASK; + case 2: return InputEvent.BUTTON2_MASK; + case 3: return InputEvent.BUTTON3_MASK; + default: return 0; + } + } + + static final int allKeyMods = + InputEvent.SHIFT_MASK + | InputEvent.CTRL_MASK + | InputEvent.ALT_MASK; + + static final int allMouseMods = + InputEvent.BUTTON1_MASK + | InputEvent.BUTTON2_MASK + | InputEvent.BUTTON3_MASK; + + static void printInputEvent(InputEvent e) { + System.out.println(e); + if (e.isAltDown()) { + System.out.println("Alt is Down"); + } + if (e.isControlDown()) { + System.out.println("Ctrl is Down"); + } + if (e.isShiftDown()) { + System.out.println("Shift is Down"); + } + if (e.isMetaDown()) { + System.out.println("Meta is Down"); + } + } + + static class TestCanvas extends Canvas { + public TestCanvas() { + setSize(100, 100); + setBackground(Color.blue); + enableEvents(AWTEvent.MOUSE_EVENT_MASK + | AWTEvent.MOUSE_MOTION_EVENT_MASK + | AWTEvent.KEY_EVENT_MASK); + } + + protected void processMouseEvent(MouseEvent e) { + try { + if (testBtn == 0) { + return; + } + if (e.getID() == MouseEvent.MOUSE_ENTERED + || e.getID() == MouseEvent.MOUSE_EXITED) + { + if ((e.getModifiers() & getMouseModifier(testBtn)) != 0) { + System.out.println("Mouse modifiers on MOUSE_ENTERED, MOUSE_EXITED are set"); + } else { + printInputEvent(e); + System.out.println("Cur mods = " + (e.getModifiers() & allMouseMods) + " Wanted = " + + getMouseModifier(testBtn)); + passed = false; + throw new RuntimeException("Mouse modifiers on MOUSE_ENTERED, MOUSE_EXITED aren't set"); + } + } + if (e.getID() == MouseEvent.MOUSE_PRESSED + || e.getID() == MouseEvent.MOUSE_RELEASED) + { + if ((e.getModifiers() & getMouseModifier(testBtn)) != 0) { + System.out.println("Right Mouse modifiers on MOUSE_PRESSED, MOUSE_RELEASED"); + } else { + printInputEvent(e); + System.out.println("Cur mods = " + (e.getModifiers() & allMouseMods) + " Wanted = " + + getMouseModifier(testBtn)); + passed = false; + throw new RuntimeException("Wrong Mouse modifiers on MOUSE_PRESSED, MOUSE_RELEASED"); + } + } + } finally { + synchronized (frame) { + frame.notify(); + } + } + } + + protected void processMouseMotionEvent(MouseEvent e) { + try { + if (testBtn == 0) { + return; + } + if (e.getID() == MouseEvent.MOUSE_DRAGGED) { + if ((e.getModifiers() & getMouseModifier(testBtn)) != 0) { + System.out.println("Mouse modifiers on MOUSE_DRAGGED are set"); + } else { + printInputEvent(e); + System.out.println("Cur mods = " + (e.getModifiers() & allMouseMods) + " Wanted = " + + getMouseModifier(testBtn)); + passed = false; + throw new RuntimeException("Mouse modifiers on MOUSE_DRAGGED aren't set"); + } + } + } finally { + synchronized (frame) { + frame.notify(); + } + } + } + + protected void processKeyEvent(KeyEvent e) { + try { + if (e.getKeyCode() != KeyEvent.VK_A) { + return; + } + if ((e.getModifiers() & getKeyModifier(testCtrl)) != 0) { + System.out.println("Right Key modifiers on KeyEvent"); + } else { + printInputEvent(e); + passed = false; + throw new RuntimeException("Wrong Key modifiers on KeyEvent"); + } + } finally { + synchronized (frame) { + frame.notify(); + } + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/InvocationEvent/CatchingThrowableTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/InvocationEvent/CatchingThrowableTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/InvocationEvent/CatchingThrowableTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/InvocationEvent/CatchingThrowableTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * 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 4403712 + @summary Error thrown in InvokeAndWait runnable causes hang + @run main CatchingThrowableTest +*/ + +import java.awt.EventQueue; + +public class CatchingThrowableTest { + public static void main(String args[]) { + try { + EventQueue.invokeAndWait(() -> { + throw new RuntimeException("My Error"); + }); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } catch (java.lang.reflect.InvocationTargetException ex) { + ex.printStackTrace(); + } + + System.err.println("Test passed."); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/KeyEvent/AltGraphModifier.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/KeyEvent/AltGraphModifier.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/KeyEvent/AltGraphModifier.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/KeyEvent/AltGraphModifier.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,140 @@ +/* + * 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 4343344 + @summary Tests key modifiers when ALT_GRAPH key is pressed by Robot. + @key headful + @requires (os.family != "mac") + @run main AltGraphModifier +*/ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.lang.reflect.InvocationTargetException; + + +public class AltGraphModifier { + static Frame frame; + + static final int[] modifierKeys = { + KeyEvent.VK_ALT_GRAPH + }; + + static final int[] inputMasks = { + InputEvent.ALT_GRAPH_DOWN_MASK + }; + + static boolean[] modifierPress = new boolean[modifierKeys.length]; + + static volatile boolean modKeys; + static int modKeyCount; + static volatile boolean failed = false; + + + public static void main (String args[]) throws + InterruptedException, InvocationTargetException, AWTException { + + EventQueue.invokeAndWait(() -> { + frame = new Frame("Modifier Robot Key BUG"); + frame.setLayout(new FlowLayout()); + frame.setSize(200, 200); + frame.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent kp){ + System.out.println(kp); + if (modKeys == true) { + for (int i=0; i < modifierKeys.length; i++) { + if (modifierPress[i] == true) { + if ((kp.getModifiersEx() & inputMasks[i]) == inputMasks[i]) { + } else { + failed = true; + } + } + } + } + } + + @Override + public void keyReleased(KeyEvent kr){ + } + }); + frame.setBackground(Color.blue); + frame.setVisible(true); + }); + + try { + Robot robot = new Robot(); + + robot.delay(1000); + robot.mouseMove((int) (frame.getLocationOnScreen().getX() + + frame.getWidth() / 2), + (int) (frame.getLocationOnScreen().getY() + + frame.getHeight() / 2)); + robot.delay(1000); + robot.setAutoDelay(1000); + + //Imbed operations here + modKeys = true; + + for (modKeyCount = 0; modKeyCount < modifierKeys.length; modKeyCount++) { + //Press the Modifier Key + modifierPress[modKeyCount] = true; + robot.keyPress(modifierKeys[modKeyCount]); + + frame.requestFocus(); + robot.delay(1000); + + //Press the Modifier Key + modifierPress[modKeyCount] = false; + robot.keyRelease(modifierKeys[modKeyCount]); + robot.delay(1000); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + if (failed) { + throw new RuntimeException("FAIL MESSAGE ---- Modifier " + +" Mask is not set when the Key : " + +"AltGraph" + + " Key is pressed by Robot.\n"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/KeyEvent/KeyTyped/CancelKeyTyped.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/KeyEvent/KeyTyped/CancelKeyTyped.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/KeyEvent/KeyTyped/CancelKeyTyped.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/KeyEvent/KeyTyped/CancelKeyTyped.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4754155 + * @summary Tests that KeyTyped events are fired for the Cancel key + * and that no extraneous characters are entered as a result + * @key headful + * @run main CancelKeyTyped + */ + +import java.awt.AWTException; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.lang.reflect.InvocationTargetException; + + +public class CancelKeyTyped { + static volatile boolean cancelKeyTypedReceived = false; + static Frame frame; + static TextField tf; + static final String ORIGINAL = "0123456789"; + + public static void main(String[] args) throws AWTException, + InterruptedException, InvocationTargetException { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + + EventQueue.invokeAndWait(CancelKeyTyped::init); + robot.waitForIdle(); + robot.delay(1000); + + // Press and release Cancel + robot.keyPress(KeyEvent.VK_CANCEL); + robot.keyRelease(KeyEvent.VK_CANCEL); + + if (cancelKeyTypedReceived) { + if (tf.getText().equals(ORIGINAL)) { + System.out.println("Test PASSED"); + } else { + System.out.println("Test FAILED: wrong string"); + throw new RuntimeException("The test failed: wrong string: " + + tf.getText()); + } + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void init() { + frame = new Frame("CancelKeyTyped"); + tf = new TextField(ORIGINAL, 20); + frame.add(tf); + frame.setSize(300, 100); + frame.setVisible(true); + frame.validate(); + + tf.requestFocusInWindow(); + + tf.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent evt) { + printKey(evt); + + int keychar = evt.getKeyChar(); + if (keychar == 24) { // Cancel character is 24 or \u0018 + cancelKeyTypedReceived = true; + } + } + + @Override + public void keyPressed(KeyEvent evt) { + printKey(evt); + } + + @Override + public void keyReleased(KeyEvent evt) { + printKey(evt); + } + + protected void printKey(KeyEvent evt) { + switch (evt.getID()) { + case KeyEvent.KEY_TYPED: + case KeyEvent.KEY_PRESSED: + case KeyEvent.KEY_RELEASED: + break; + default: + return; + } + + System.out.println("params= " + evt.paramString() + " \n" + + "KeyChar: " + evt.getKeyChar() + " = " + + (int) evt.getKeyChar() + + " KeyCode: " + evt.getKeyCode() + + " Modifiers: " + evt.getModifiersEx()); + + if (evt.isActionKey()) { + System.out.println("Action Key"); + } + + System.out.println("keyText= " + + evt.getKeyText(evt.getKeyCode()) + "\n"); + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,8 @@ import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicReference; import javax.swing.JButton; import javax.swing.JFrame; @@ -55,7 +55,7 @@ private static final int CHECK_LAPSE = 100; private static final int MAX_COUNT = MAX_TIME / INTERVAL; private static final int EXPECTED = MAX_COUNT * NUM_WINDOW; - private static final List WINDOWS = new ArrayList(); + private static final List WINDOWS = new CopyOnWriteArrayList<>(); public static void main(String[] args) { for (int i = 0; i < NUM_WINDOW; i++) { @@ -126,7 +126,7 @@ private static final class TestWindow extends JFrame implements ActionListener { private final JButton btn; - private int counter = 0; + private volatile int counter = 0; private final Timer t; TestWindow(final int num) { diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4394789 + @summary KeyboardFocusManager.upFocusCycle is not working for Swing properly + @key headful + @run main AsyncUpFocusCycleTest +*/ + + +import javax.swing.DefaultFocusManager; +import javax.swing.JButton; +import javax.swing.JFrame; +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.EventQueue; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + +public class AsyncUpFocusCycleTest { + volatile boolean isFailed = true; + Object sema = new Object(); + JFrame frame; + Point location; + JButton button; + Insets insets; + int width; + + public void start() throws InterruptedException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.mouseMove(100, 100); + + EventQueue.invokeAndWait(() -> { + frame = new JFrame("AsyncUpFocusCycleTest") { + public void requestFocus() { + boolean ret = super.requestFocus(false); + System.err.println("requestFocus() on Frame " + ret); + } + + protected boolean requestFocus(boolean temporary) { + boolean ret = super.requestFocus(temporary); + System.err.println("requestFocus(" + temporary + ") on Frame " + ret); + return ret; + } + + public boolean requestFocusInWindow() { + boolean ret = super.requestFocusInWindow(); + System.err.println("requestFocusInWindow() on Frame " + ret); + return ret; + } + + protected boolean requestFocusInWindow(boolean temporary) { + boolean ret = super.requestFocusInWindow(temporary); + System.err.println("requestFocusInWindow(" + temporary + ") on Frame " + ret); + return ret; + } + }; + + Container container1 = frame.getContentPane(); + container1.setBackground(Color.yellow); + + button = new JButton("Button") { + public void requestFocus() { + boolean ret = super.requestFocus(false); + System.err.println("requestFocus() on Button " + ret); + } + + public boolean requestFocus(boolean temporary) { + boolean ret = super.requestFocus(temporary); + System.err.println("requestFocus(" + temporary + ") on Button " + ret); + return ret; + } + + public boolean requestFocusInWindow() { + boolean ret = super.requestFocusInWindow(); + System.err.println("requestFocusInWindow() on Button " + ret); + return ret; + } + + protected boolean requestFocusInWindow(boolean temporary) { + boolean ret = super.requestFocusInWindow(temporary); + System.err.println("requestFocusInWindow(" + temporary + ") on Button " + ret); + return ret; + } + }; + button.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Button receive focus"); + frame.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Frame receive focus"); + synchronized (sema) { + isFailed = false; + sema.notifyAll(); + } + } + }); + } + }); + container1.add(new JButton("empty button"), BorderLayout.WEST); + container1.add(button, BorderLayout.EAST); + frame.setBounds(0, 0, 300, 300); + frame.setVisible(true); + }); + + robot.delay(2000); + robot.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + location = frame.getLocationOnScreen(); + insets = frame.getInsets(); + width = frame.getWidth(); + }); + + robot.mouseMove(location.x + width / 2, location.y + insets.top / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + DefaultKeyboardFocusManager manager = new DefaultFocusManager(); + robot.delay(1000); + EventQueue.invokeAndWait(button::requestFocus); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + manager.upFocusCycle(button); + }); + + try { + synchronized (sema) { + sema.wait(5000); + } + + if (isFailed) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED"); + } else { + System.out.println("Test PASSED"); + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted"); + } + } catch (AWTException e) { + System.out.println("Problem creating Robot."); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + AsyncUpFocusCycleTest test = new AsyncUpFocusCycleTest(); + test.start(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4525962 + @summary Opposite component calculated inaccurately + @key headful + @run main ClearMostRecentFocusOwnerTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; + +import java.awt.event.AWTEventListener; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ClearMostRecentFocusOwnerTest implements AWTEventListener { + final static int ROBOT_DELAY = 50; + volatile Frame firstFrame; + volatile Frame secondFrame; + volatile Button actionButton; + volatile Button btnToRemove; + volatile Button btnToHide; + volatile Button btnToDisable; + volatile Button btnToNonFocusable; + volatile Panel pnlToHide; + volatile Button btnInPanel; + + Robot robot; + + volatile Component opposite = null; + volatile Component focusOwner = null; + volatile Object monitor = null; + + public void init() throws InterruptedException, + InvocationTargetException { + try { + robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Can not create awt-robot."); + } + EventQueue.invokeAndWait(() -> { + firstFrame = new Frame("The First Frame"); + firstFrame.setName("\"1st Frame\""); + secondFrame = new Frame("The Second Frame"); + secondFrame.setName("\"2nd Frame\""); + pnlToHide = new Panel(); + pnlToHide.setName("Panel"); + actionButton = new Button("Action Button"); + actionButton.setName("\"" + actionButton.getLabel() + "\""); + btnToRemove = new Button("To Remove"); + btnToRemove.setName("\"" + btnToRemove.getLabel() + "\""); + btnToHide = new Button("ToHide"); + btnToHide.setName("\"" + btnToHide.getLabel() + "\""); + btnToDisable = new Button("To Disable"); + btnToDisable.setName("\"" + btnToDisable.getLabel() + "\""); + btnToNonFocusable = new Button("To setFocusable(false)"); + btnToNonFocusable.setName("\"" + btnToNonFocusable.getLabel() + "\""); + btnInPanel = new Button("Int Panel"); + btnInPanel.setName("\"" + btnInPanel.getLabel() + "\""); + + firstFrame.add(actionButton); + + secondFrame.setLayout(new FlowLayout()); + secondFrame.add(btnToRemove); + secondFrame.add(btnToHide); + secondFrame.add(btnToDisable); + secondFrame.add(btnToNonFocusable); + secondFrame.add(pnlToHide); + pnlToHide.add(btnInPanel); + + firstFrame.pack(); + firstFrame.setVisible(true); + secondFrame.pack(); + secondFrame.setLocation(0, firstFrame.getHeight() + 50); + secondFrame.setVisible(true); + }); + } + + public void start() throws InterruptedException, InvocationTargetException { + try { + Toolkit.getDefaultToolkit(). + addAWTEventListener(this, + AWTEvent.FOCUS_EVENT_MASK); + + makeFocusOwner(btnToRemove); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + secondFrame.remove(btnToRemove); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnToHide) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.remove()."); + } + + makeFocusOwner(btnToHide); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + btnToHide.setVisible(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnToDisable) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.setVisible(false)."); + } + + makeFocusOwner(btnToDisable); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + btnToDisable.setEnabled(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnToNonFocusable) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.rsetEnabled(false)."); + } + + makeFocusOwner(btnToNonFocusable); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + btnToNonFocusable.setFocusable(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnInPanel) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.setFocusable(false)."); + } + + makeFocusOwner(btnInPanel); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + pnlToHide.setVisible(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite == btnInPanel) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Container.setVisible(false)."); + } + } finally { + if (firstFrame != null) { + EventQueue.invokeAndWait(firstFrame::dispose); + } + if (secondFrame != null) { + EventQueue.invokeAndWait(secondFrame::dispose); + } + + } + } + + public void eventDispatched(AWTEvent event) { + switch (event.getID()) { + case FocusEvent.FOCUS_GAINED: + if (focusOwner == ((FocusEvent) event).getComponent() + && monitor != null) { + synchronized (monitor) { + monitor.notify(); + } + } + break; + case FocusEvent.FOCUS_LOST: + opposite = ((FocusEvent) event).getOppositeComponent(); + break; + } + System.out.println(event); + } + + void clickOnComponent(Component comp) throws InterruptedException, + InvocationTargetException { + System.err.println("clickOnComopnent " + comp.getName()); + robot.delay(3000); + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point origin = comp.getLocationOnScreen(); + Dimension dim = comp.getSize(); + point[0] = origin.x + (int) dim.getWidth() / 2; + point[1] = origin.y + (int) dim.getHeight() / 2; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(ROBOT_DELAY); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + void makeFocusOwner(Component comp) throws InterruptedException, + InvocationTargetException { + AtomicBoolean isOwner = new AtomicBoolean(false); + EventQueue.invokeAndWait(() -> { + isOwner.set(comp.isFocusOwner()); + }); + if (!isOwner.get()) { + clickOnComponent(comp); + try { + EventQueue.invokeAndWait(() -> { + isOwner.set(comp.isFocusOwner()); + }); + if (!isOwner.get()) { + monitor = new Object(); + focusOwner = comp; + synchronized (monitor) { + monitor.wait(3000); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted."); + } + } + EventQueue.invokeAndWait(() -> { + isOwner.set(comp.isFocusOwner()); + }); + if (!isOwner.get()) { + throw new RuntimeException("Test can not make " + + comp.getName() + " a focus owner."); + } + } + + void makeActiveFrame(Frame frame) throws InvocationTargetException, + InterruptedException { + robot.delay(3000); + if (!frame.isActive()) { + System.err.println("frame is not active"); + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point origin = frame.getLocationOnScreen(); + Insets ins = frame.getInsets(); + point[0] = origin.x + frame.getWidth() / 2; + point[1] = origin.y + ins.top / 2; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(ROBOT_DELAY); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + robot.delay(3000); + EventQueue.invokeAndWait(() -> { + if (!frame.isActive()) { + throw new RuntimeException("Test can not activate " + frame.getName() + "."); + } + }); + } + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + ClearMostRecentFocusOwnerTest test = new ClearMostRecentFocusOwnerTest(); + test.init(); + test.start(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,232 @@ +/* + * 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 4715649 +@summary Tests that KEY_TYPED event for Tab key arrives if Tab key is not focus traversal key +@key headful +@run main ConsumedTabKeyTest +*/ + +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + +public class ConsumedTabKeyTest extends Panel { + TextField text; + Button button = new Button("none"); + Semaphore focusSema = new Semaphore(); + Semaphore releaseSema = new Semaphore(); + Semaphore buttonFocusSema = new Semaphore(); + Robot robot; + volatile boolean keyTyped; + volatile boolean hasFocus; + static Frame frame; + + public void init() { + this.setLayout(new FlowLayout()); + text = new TextField(); + + text.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + focusSema.raise(); + } + }); + button.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + buttonFocusSema.raise(); + } + }); + add(text); + add(button); + setSize(200, 200); + setVisible(true); + validate(); + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + if (e.getID() == KeyEvent.KEY_RELEASED) { + releaseSema.raise(); + } + if (e.getID() == KeyEvent.KEY_TYPED) { + keyTyped = true; + } + } + }, InputEvent.KEY_EVENT_MASK); + try { + robot = new Robot(); + } catch (Exception re) { + throw new RuntimeException("Couldn't create Robot"); + } + } + + public void start() throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + if (!text.isFocusOwner()) { + text.requestFocus(); + } + + text.setFocusTraversalKeysEnabled(false); + }); + + try { + focusSema.doWait(1000); + } catch (InterruptedException ie1) { + throw new RuntimeException("Interrupted"); + } + + EventQueue.invokeAndWait(() -> { + hasFocus = text.isFocusOwner(); + }); + + if (!focusSema.getState() && !hasFocus) { + throw new RuntimeException("Text didn't receive focus"); + } + + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + try { + releaseSema.doWait(1000); + } catch (InterruptedException ie2) { + throw new RuntimeException("Interrupted"); + } + + if (!releaseSema.getState()) { + throw new RuntimeException("KEY_RELEASED hasn't arrived"); + } + + if (!keyTyped) { + throw new RuntimeException("KEY_TYPED for Tab key hasn't arrived"); + } + + EventQueue.invokeAndWait(() -> { + text.setFocusTraversalKeysEnabled(true); + }); + + releaseSema.setState(false); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + try { + buttonFocusSema.doWait(1000); + releaseSema.doWait(1000); + } catch (InterruptedException ie2) { + throw new RuntimeException("Interrupted"); + } + + EventQueue.invokeAndWait(() -> { + hasFocus = button.isFocusOwner(); + }); + + if (!buttonFocusSema.getState() && !hasFocus) { + throw new RuntimeException("Button hasn't received focus"); + } + keyTyped = false; + releaseSema.setState(false); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + try { + releaseSema.doWait(1000); + } catch (InterruptedException ie2) { + throw new RuntimeException("Interrupted"); + } + + if (!releaseSema.getState()) { + throw new RuntimeException("KEY_RELEASED hasn't arrived"); + } + if (!keyTyped) { + throw new RuntimeException("KEY_TYPED for A key hasn't arrived"); + } + System.err.println("PASSED"); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ConsumedTabKeyTest test = new ConsumedTabKeyTest(); + + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("InvocationTargetException"); + frame.setLayout(new BorderLayout()); + frame.add(test, BorderLayout.CENTER); + test.init(); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + test.start(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } +} + +class Semaphore { + boolean state = false; + int waiting = 0; + + public void doWait(int timeout) throws InterruptedException { + synchronized (this) { + if (state) return; + waiting++; + wait(timeout); + waiting--; + } + } + + public void raise() { + synchronized (this) { + state = true; + if (waiting > 0) { + notifyAll(); + } + } + } + + public boolean getState() { + synchronized (this) { + return state; + } + } + + public void setState(boolean newState) { + synchronized (this) { + state = newState; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/EventRetargetTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/EventRetargetTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/EventRetargetTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/EventRetargetTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * 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 4846162 4626092 + @summary (Key|Window|Focus)Events should not be retargeted when dispatchEvent() is called directly. + @run main EventRetargetTest +*/ + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class EventRetargetTest { + boolean isKEProcessed1; + boolean isKEProcessed2; + boolean isKEProcessed3; + boolean isFEProcessed1; + boolean isFEProcessed2; + boolean isFEProcessed3; + + public void start () { + final Component comp = new Component() { + public boolean isShowing() { + return true; + } + + public boolean isVisible() { + return true; + } + + public boolean isDisplayable() { + return true; + } + + protected void processKeyEvent(KeyEvent e) { + System.err.println("processKeyEvent >> " + e); + isKEProcessed1 = true; + super.processKeyEvent(e); + } + + protected void processFocusEvent(FocusEvent e) { + System.err.println("processFocusEvent >> " + e); + isFEProcessed1 = true; + super.processFocusEvent(e); + } + }; + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + if (e instanceof KeyEvent) { + isKEProcessed2 = (e.getSource() == comp); + } + else if (e instanceof FocusEvent) { + isFEProcessed2 = (e.getSource() == comp); + } + System.err.println("Toolkit >> " + e); + } + }, AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK); + + comp.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + isKEProcessed3 = true; + System.err.println("Listener >> " + e); + } + }); + comp.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + isFEProcessed3 = true; + System.err.println("Listener >> " + e); + } + }); + + KeyEvent ke = new KeyEvent(comp, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, + KeyEvent.VK_UNDEFINED, 'a'); + comp.dispatchEvent(ke); + + if (!(isKEProcessed1 && isKEProcessed2 && isKEProcessed3)) { + System.err.println("(" + isKEProcessed1 + "," + isKEProcessed2 + + "," + isKEProcessed3 + ")"); + throw new RuntimeException("KeyEvent is not correctly retargeted."); + } + + FocusEvent fe = new FocusEvent(comp, FocusEvent.FOCUS_GAINED, + false, null); + comp.dispatchEvent(fe); + + if (!(isFEProcessed1 && isFEProcessed2 && isFEProcessed3)) { + System.err.println("(" + isFEProcessed1 + "," + + isFEProcessed2 + "," + isFEProcessed3 + ")"); + throw new RuntimeException("FocusEvent is not correctly retargeted."); + } + } + + public static void main(String[] args) { + EventRetargetTest test = new EventRetargetTest(); + test.start(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5072554 + @summary Tests that vetoing focus doesn't generate extra PropertyChange notification. + @key headful + @run main ExtraPropChangeNotifVetoingTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Panel; +import java.awt.Robot; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.lang.reflect.InvocationTargetException; + +public class ExtraPropChangeNotifVetoingTest extends Panel { + Button one = new Button("One"); + Button two = new Button("Two"); + Robot robot; + static Frame frame; + + int i = 0; + + public void init() { + try { + robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Error: unable to create robot", e); + } + + setLayout(new FlowLayout()); + add(one); + add(two); + + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addVetoableChangeListener("permanentFocusOwner", + new VetoableChangeListener() { + public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException { + System.out.println((i++) + ". Old=" + e.getOldValue() + ", New=" + e.getNewValue()); + + if (e.getOldValue() == e.getNewValue()) { + throw new RuntimeException("Test failed!"); + } + + if (e.getNewValue() == two) { + System.out.println("VETOING"); + throw new PropertyVetoException("vetoed", e); + } + } + }); + setVisible(true); + } + + public void start() throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(one::requestFocusInWindow); + robot.waitForIdle(); + robot.delay(200); + EventQueue.invokeAndWait(two::requestFocusInWindow); + robot.waitForIdle(); + robot.delay(200); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ExtraPropChangeNotifVetoingTest test = new ExtraPropChangeNotifVetoingTest(); + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("ExtraPropChangeNotifVetoingTest"); + frame.setLayout(new BorderLayout()); + frame.add(test, BorderLayout.CENTER); + test.init(); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + test.start(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/font/GlyphVector/MultiSlotFontTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/font/GlyphVector/MultiSlotFontTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/font/GlyphVector/MultiSlotFontTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/font/GlyphVector/MultiSlotFontTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -23,7 +23,7 @@ /** * @test - * @bug 8240756 + * @bug 8240756 8298887 * @summary Non-English characters are printed with wrong glyphs on MacOS * @modules java.desktop/sun.java2d java.desktop/sun.java2d.loops java.desktop/sun.font * @requires os.family == "mac" diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Frame/Iconify/IconifyTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Frame/Iconify/IconifyTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Frame/Iconify/IconifyTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Frame/Iconify/IconifyTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,200 @@ +/* + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicReference; +import javax.swing.SwingUtilities; + +/* + * @test + * @key headful + * @bug 8296934 + * @summary Verifies whether Undecorated Frame can be iconified or not. + * @run main IconifyTest + */ +public class IconifyTest { + + private static Robot robot; + private static Button button; + private static Frame frame; + private static volatile int windowStatusEventType; + private static volatile int windowIconifiedEventType; + private static volatile boolean focusGained = false; + + public static void initializeGUI() { + frame = new Frame(); + frame.setLayout(new FlowLayout()); + frame.setSize(200, 200); + frame.setUndecorated(true); + + frame.addWindowFocusListener(new WindowAdapter() { + public void windowGainedFocus(WindowEvent event) { + focusGained = true; + } + }); + + frame.addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + windowStatusEventType = WindowEvent.WINDOW_ACTIVATED; + System.out.println("Event encountered: " + e); + } + + public void windowIconified(WindowEvent e) { + windowIconifiedEventType = WindowEvent.WINDOW_ICONIFIED; + System.out.println("Event encountered: " + e); + } + + public void windowDeiconified(WindowEvent e) { + windowIconifiedEventType = WindowEvent.WINDOW_DEICONIFIED; + System.out.println("Event encountered: " + e); + } + + public void windowDeactivated(WindowEvent e) { + windowStatusEventType = WindowEvent.WINDOW_DEACTIVATED; + System.out.println("Event encountered: " + e); + } + }); + + button = new Button("Minimize me"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + frame.setExtendedState(Frame.ICONIFIED); + } + }); + + frame.setBackground(Color.green); + frame.add(button); + frame.setLocationRelativeTo(null); + frame.toFront(); + frame.setVisible(true); + } + + public static void main(String[] args) throws AWTException, + InvocationTargetException, InterruptedException { + robot = new Robot(); + try { + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + + SwingUtilities.invokeAndWait(IconifyTest::initializeGUI); + final AtomicReference frameloc = new AtomicReference<>(); + final AtomicReference framesize = new AtomicReference<>(); + SwingUtilities.invokeAndWait(() -> { + frameloc.set(frame.getLocationOnScreen()); + framesize.set(frame.getSize()); + }); + Point locOnScreen = frameloc.get(); + Dimension frameSizeOnScreen = framesize.get(); + + robot.mouseMove(locOnScreen.x + frameSizeOnScreen.width / 2, + locOnScreen.y + frameSizeOnScreen.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + if (windowStatusEventType != WindowEvent.WINDOW_ACTIVATED) { + throw new RuntimeException( + "FAIL: WINDOW_ACTIVATED event did not occur when the undecorated frame is activated!"); + } + clearEventTypeValue(); + final AtomicReference buttonloc = new AtomicReference<>(); + final AtomicReference buttonsize = new AtomicReference<>(); + SwingUtilities.invokeAndWait(() -> { + buttonloc.set(button.getLocationOnScreen()); + buttonsize.set(button.getSize()); + }); + Point buttonLocOnScreen = buttonloc.get(); + Dimension buttonSizeOnScreen = buttonsize.get(); + + robot.mouseMove(buttonLocOnScreen.x + buttonSizeOnScreen.width / 2, + buttonLocOnScreen.y + buttonSizeOnScreen.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (windowIconifiedEventType != WindowEvent.WINDOW_ICONIFIED) { + throw new RuntimeException( + "FAIL: WINDOW_ICONIFIED event did not occur when the undecorated frame is iconified!"); + } + if (windowStatusEventType != WindowEvent.WINDOW_DEACTIVATED) { + throw new RuntimeException( + "FAIL: WINDOW_DEACTIVATED event did not occur when the undecorated frame is iconified!"); + } + final AtomicReference frameHasFocus = new AtomicReference<>(); + SwingUtilities + .invokeAndWait(() -> frameHasFocus.set(frame.hasFocus())); + final boolean hasFocus = frameHasFocus.get(); + if (hasFocus) { + throw new RuntimeException( + "FAIL: The undecorated frame has focus even when it is iconified!"); + } + + clearEventTypeValue(); + + SwingUtilities + .invokeAndWait(() -> frame.setExtendedState(Frame.NORMAL)); + robot.waitForIdle(); + + if (windowIconifiedEventType != WindowEvent.WINDOW_DEICONIFIED) { + throw new RuntimeException( + "FAIL: WINDOW_DEICONIFIED event did not occur when the state is set to NORMAL!"); + } + if (windowStatusEventType != WindowEvent.WINDOW_ACTIVATED) { + throw new RuntimeException( + "FAIL: WINDOW_ACTIVATED event did not occur when the state is set to NORMAL!"); + } + if (!focusGained) { + throw new RuntimeException( + "FAIL: The undecorated frame does not have focus when it is deiconified!"); + } + System.out.println("Test passed"); + } + finally { + SwingUtilities.invokeAndWait(IconifyTest::disposeFrame); + } + } + + public static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + public static void clearEventTypeValue() { + windowIconifiedEventType = -1; + windowStatusEventType = -1; + focusGained = false; + } +} + diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4467840 + @summary Generate a PropertyChange when KeyboardFocusManager changes + @key headful + @run main ChangeKFMTest +*/ + +import java.awt.BorderLayout; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class ChangeKFMTest implements PropertyChangeListener { + static final String CURRENT_PROP_NAME = "managingFocus"; + boolean current_fired; + boolean not_current_fired; + KeyboardFocusManager kfm; + public static void main(String[] args) throws Exception { + ChangeKFMTest test = new ChangeKFMTest(); + test.start(); + } + + public void start () throws Exception { + EventQueue.invokeAndWait(() -> { + kfm = new DefaultKeyboardFocusManager(); + kfm.addPropertyChangeListener(CURRENT_PROP_NAME, this); + current_fired = false; + not_current_fired = false; + KeyboardFocusManager.setCurrentKeyboardFocusManager(kfm); + if (!current_fired) { + throw new RuntimeException("Change to current was not fired on KFM instalation"); + } + if (not_current_fired) { + throw new RuntimeException("Change to non-current was fired on KFM instalation"); + } else { + System.out.println("Installation was complete correctly"); + } + + current_fired = false; + not_current_fired = false; + KeyboardFocusManager.setCurrentKeyboardFocusManager(null); + if (!not_current_fired) { + throw new RuntimeException("Change to non-current was not fired on KFM uninstalation"); + } + if (current_fired) { + throw new RuntimeException("Change to current was fired on KFM uninstalation"); + } else { + System.out.println("Uninstallation was complete correctly"); + } + }); + } + + public void propertyChange(PropertyChangeEvent e) { + System.out.println(e.toString()); + if (!CURRENT_PROP_NAME.equals(e.getPropertyName())) { + throw new RuntimeException("Unexpected property name - " + e.getPropertyName()); + } + if (((Boolean)e.getNewValue()).booleanValue()) { + current_fired = true; + } else { + not_current_fired = true; + } + System.out.println("current_fired = " + current_fired); + System.out.println("not_current_fired = " + not_current_fired); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java openjdk-17-17.0.8+7/test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4458016 + @summary KeyboardFocusManager.get[Property|Vetoable]ChangeListeners throw NPE + @key headful + @run main PropertySupportNPETest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; + +public class PropertySupportNPETest { + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + KeyboardFocusManager kfm = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + kfm.getVetoableChangeListeners(); + kfm.getVetoableChangeListeners(""); + kfm.getPropertyChangeListeners(); + kfm.getPropertyChangeListeners(""); + }); + } + } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Label/NullLabelTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Label/NullLabelTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Label/NullLabelTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Label/NullLabelTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6215905 + @summary Tests that passing null value to Label.setText(String) doesn't + lead to VM crash. + @key headful + @run main NullLabelTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Label; +import java.awt.Frame; + +public class NullLabelTest { + + static Frame frame; + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + frame = new Frame(); + Label l = new Label("A"); + frame.add(l); + frame.setLayout(new BorderLayout()); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + l.setText(null); + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Layout/InsetsTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Layout/InsetsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Layout/InsetsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Layout/InsetsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4087971 + @summary Insets does not layout a component correctly + @key headful + @run main InsetsTest +*/ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Insets; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; + +public class InsetsTest { + private int leftInsetValue; + private InsetsClass IC; + + public static void main(String[] args) throws Exception { + InsetsTest test = new InsetsTest(); + test.start(); + } + + public void start() throws Exception { + EventQueue.invokeAndWait(() -> { + try { + IC = new InsetsClass(); + IC.setLayout(new BorderLayout()); + IC.setSize(200, 200); + IC.setVisible(true); + + leftInsetValue = IC.returnLeftInset(); + if (leftInsetValue != 30) { + throw new RuntimeException("Test Failed - Left inset" + + "is not taken correctly"); + } + } finally { + if (IC != null) { + IC.dispose(); + } + } + }); + } +} + +class InsetsClass extends JFrame { + private int value; + private JPanel panel; + + public InsetsClass() { + super("TestFrame"); + setBackground(Color.lightGray); + + panel = new JPanel(); + panel.setBorder(new EmptyBorder(new Insets(30, 30, 30, 30))); + panel.add(new JButton("Test Button")); + + getContentPane().add(panel); + pack(); + setVisible(true); + } + + public int returnLeftInset() { + // Getting the left inset value + Insets insets = panel.getInsets(); + value = insets.left; + return value; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/LightweightComponent/LightweightDragTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/LightweightComponent/LightweightDragTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/LightweightComponent/LightweightDragTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/LightweightComponent/LightweightDragTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4050138 + @summary Lightweight components: Enter/Exit mouse events + incorrectly reported during drag + @key headful + @run main LightweightDragTest +*/ + +import java.awt.AWTException; +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; + +public class LightweightDragTest { + MyComponent c,c2; + static Frame frame; + volatile int x = 0; + volatile int y = 0; + volatile int x2 = 0; + volatile int y2 = 0; + + public static void main(String[] args) throws Exception { + LightweightDragTest test = new LightweightDragTest(); + try { + EventQueue.invokeAndWait(() -> { + test.init(); + }); + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void init() { + frame = new Frame("Test LightWeight Component Drag"); + c = new MyComponent(); + c2 = new MyComponent(); + frame.add(c, BorderLayout.WEST); + frame.add(c2, BorderLayout.EAST); + frame.setSize(250, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public void start() throws Exception { + Robot rb; + try { + rb = new Robot(); + } catch (AWTException e) { + throw new Error("Could not create robot"); + } + rb.setAutoDelay(10); + rb.delay(1000); + rb.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + x = c.getLocationOnScreen().x + c.getWidth() / 2; + y = c.getLocationOnScreen().y + c.getHeight() / 2; + x2 = c2.getLocationOnScreen().x + c2.getWidth() / 2; + y2 = c2.getLocationOnScreen().y + c2.getHeight() / 2; + }); + int xt = x; + int yt = y; + rb.mouseMove(xt, yt); + rb.mousePress(InputEvent.BUTTON1_MASK); + EventQueue.invokeAndWait(() -> { + c.isInside = true; + c2.isInside = false; + }); + // drag + while (xt != x2 || yt != y2) { + if (x2 > xt) ++xt; + if (x2 < xt) --xt; + if (y2 > yt) ++yt; + if (y2 < yt) --yt; + rb.mouseMove(xt, yt); + } + rb.mouseRelease(InputEvent.BUTTON1_MASK); + EventQueue.invokeAndWait(() -> { + if (c.isInside || !c2.isInside) { + throw new Error("Test failed: mouse events did not arrive"); + } + }); + } +} + +class MyComponent extends Component { + public boolean isInside; + public void paint(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0,0,getSize().width,getSize().height); + } + public MyComponent() { + enableEvents(AWTEvent.MOUSE_EVENT_MASK); + setBackground(Color.blue); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } + + public void processEvent(AWTEvent e) { + int eventID = e.getID(); + if ((eventID == MouseEvent.MOUSE_ENTERED)) { + setBackground(Color.red); + repaint(); + isInside = true; + } else if (eventID == MouseEvent.MOUSE_EXITED) { + setBackground(Color.blue); + repaint(); + isInside = false; + } + super.processEvent(e); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java openjdk-17-17.0.8+7/test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4092418 + @summary Test for drag events been taking by Lightweight Component + @key headful + @run main LWClobberDragEvent +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +public class LWClobberDragEvent implements MouseListener, MouseMotionListener { + boolean isDragging; + + static Frame frame; + LightweightComp lc; + final static int LWWidth = 200; + final static int LWHeight = 100; + final static int MAX_COUNT = 100; + Point locationOfLW; + + public static void main(String[] args) throws Exception { + LWClobberDragEvent test = new LWClobberDragEvent(); + try { + test.init(); + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame(); + frame.setLayout(new BorderLayout()); + isDragging = false; + frame.addMouseMotionListener(this); + frame.addMouseListener(this); + + frame.setBackground(Color.white); + + lc = new LightweightComp(); + lc.setSize(LWWidth, LWHeight); + lc.setLocation(50, 50); + lc.addMouseListener(this); + lc.addMouseMotionListener(this); + frame.add(lc); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.delay(1000); + robot.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + locationOfLW = getLocation(lc); + robot.mouseMove(locationOfLW.x + lc.getWidth() / 2, + locationOfLW.y - lc.getHeight() / 2); + }); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(1000); + //move mouse till the bottom of LWComponent + for (int i = 1; i < LWHeight + lc.getHeight() / 2; i++) { + robot.mouseMove(locationOfLW.x + lc.getWidth() / 2, + locationOfLW.y - lc.getHeight() / 2 + i); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(1000); + System.out.println("Test Passed."); + } + + public void mouseClicked(MouseEvent evt) { } + + public void mouseReleased(MouseEvent evt) { + if (evt.getSource() == this) { + if (isDragging) { + isDragging = false; + } + } else { + } + } + public Point getLocation( Component co ) throws RuntimeException { + Point pt = null; + boolean bFound = false; + int count = 0; + while ( !bFound ) { + try { + pt = co.getLocationOnScreen(); + bFound = true; + } catch ( Exception ex ) { + bFound = false; + count++; + } + if ( !bFound && count > MAX_COUNT ) { + throw new RuntimeException("don't see a component to get location"); + } + } + return pt; + } + + public void mousePressed(MouseEvent evt) { } + public void mouseEntered(MouseEvent evt) { } + public void mouseExited(MouseEvent evt) { } + public void mouseMoved(MouseEvent evt) { } + + public void mouseDragged(MouseEvent evt) { + if (evt.getSource() == this) { + if (!isDragging) { + isDragging = true; + } + } else { + if (isDragging) { + throw new RuntimeException("Test failed: Lightweight got dragging event."); + } + } + } +} + +class LightweightComp extends Component { + public void paint(Graphics g) { + Dimension d = getSize(); + g.setColor(Color.red); + g.fillRect(0, 0, d.width, d.height); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/InstanceOfSelectedArray.java openjdk-17-17.0.8+7/test/jdk/java/awt/List/InstanceOfSelectedArray.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/InstanceOfSelectedArray.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/List/InstanceOfSelectedArray.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4322321 + @summary tests that List.getSelectedIndexes() doesn't return reference to internal array + @key headful + @run main InstanceOfSelectedArray +*/ + +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.List; + +public class InstanceOfSelectedArray { + List testList; + Frame frame; + int[] selected; + + public static void main(String[] args) throws Exception { + InstanceOfSelectedArray test = new InstanceOfSelectedArray(); + test.start(); + } + + public void start () throws Exception { + try { + EventQueue.invokeAndWait(() -> { + testList = new List(); + frame = new Frame("InstanceOfSelectedArrayTest"); + testList.addItem("First"); + testList.addItem("Second"); + testList.addItem("Third"); + + frame.add(testList); + frame.setLayout(new FlowLayout()); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + testList.select(2); + + selected = testList.getSelectedIndexes(); + selected[0] = 0; + selected = testList.getSelectedIndexes(); + + if (selected[0] == 0) { + System.out.println("List returned the reference to internal array."); + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED"); + } + }); + + System.out.println("List returned a clone of its internal array."); + System.out.println("Test PASSED"); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/ISCAfterRemoveAllTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/List/ISCAfterRemoveAllTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/ISCAfterRemoveAllTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/List/ISCAfterRemoveAllTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6291736 + @summary ITEM_STATE_CHANGED triggered after List.removeAll(), XToolkit + @key headful + @run main ISCAfterRemoveAllTest +*/ + +import java.awt.AWTException; +import java.awt.FlowLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.List; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +public class ISCAfterRemoveAllTest implements ItemListener { + List list; + Frame frame; + volatile boolean passed = true; + + public static void main(String[] args) throws Exception { + ISCAfterRemoveAllTest test = new ISCAfterRemoveAllTest(); + test.start(); + } + + public void start () throws Exception { + try { + EventQueue.invokeAndWait(() -> { + list = new List(4, false); + frame = new Frame("ISCAfterRemoveAllTest"); + list.add("000"); + list.add("111"); + list.add("222"); + list.add("333"); + list.add("444"); + list.add("555"); + list.add("666"); + list.add("777"); + list.add("888"); + list.add("999"); + + frame.add(list); + frame.setLayout(new FlowLayout()); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private void test() throws Exception { + Robot r = new Robot(); + r.delay(1000); + r.waitForIdle(); + EventQueue.invokeAndWait(() -> { + Point loc = list.getLocationOnScreen(); + r.mouseMove(loc.x + list.getWidth() / 2, loc.y + list.getHeight() / 2); + }); + r.delay(100); + r.mousePress(InputEvent.BUTTON1_MASK); + r.delay(10); + r.mouseRelease(InputEvent.BUTTON1_MASK); + r.delay(100); + + EventQueue.invokeAndWait(() -> { + list.removeAll(); + + // The interesting events are generated after removing + list.addItemListener(this); + r.delay(100); + + list.requestFocusInWindow(); + r.delay(100); + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != list) { + throw new RuntimeException("Test failed - list isn't focus owner."); + } + }); + + r.delay(10); + r.keyPress(KeyEvent.VK_UP); + r.delay(10); + r.keyRelease(KeyEvent.VK_UP); + r.delay(100); + + // This is the test case for the 6299853 issue + r.delay(10); + r.keyPress(KeyEvent.VK_SPACE); + r.delay(10); + r.keyRelease(KeyEvent.VK_SPACE); + r.delay(100); + + r.waitForIdle(); + + if (!passed) { + throw new RuntimeException("Test failed."); + } + } + + public void itemStateChanged(ItemEvent ie) { + System.out.println(ie); + // We shouldn't generate any events since the list is empty + passed = false; + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/ListEnterExitTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/List/ListEnterExitTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/ListEnterExitTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/List/ListEnterExitTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4274839 4281703 + @summary tests that List receives mouse enter/exit events properly + @key headful + @run main ListEnterExitTest +*/ + +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.List; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ListEnterExitTest { + final List list = new List(); + final MouseEnterExitListener mouseEnterExitListener = new MouseEnterExitListener(); + Frame frame; + volatile Point p; + + public static void main(String[] args) throws Exception { + ListEnterExitTest test = new ListEnterExitTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("ListEnterExitTest"); + list.add("Item 1"); + list.add("Item 2"); + list.addMouseListener(mouseEnterExitListener); + frame.add(list); + frame.setLayout(new FlowLayout()); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + final Robot robot = new Robot(); + robot.delay(1000); + robot.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + p = list.getLocationOnScreen(); + }); + robot.mouseMove(p.x + 10, p.y + 10); + robot.delay(100); + robot.waitForIdle(); + robot.mouseMove(p.x - 10, p.y - 10); + robot.delay(100); + robot.waitForIdle(); + robot.mouseMove(p.x + 10, p.y + 10); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + synchronized (mouseEnterExitListener) { + mouseEnterExitListener.wait(2000); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + if (!mouseEnterExitListener.isPassed()) { + throw new RuntimeException("Haven't receive mouse enter/exit events"); + } + + } + +} + +class MouseEnterExitListener extends MouseAdapter { + + volatile boolean passed_1 = false; + volatile boolean passed_2 = false; + + public void mouseEntered(MouseEvent e) { + passed_1 = true; + } + + public void mouseExited(MouseEvent e) { + passed_2 = true; + } + + public void mousePressed(MouseEvent e) { + synchronized (this) { + System.out.println("mouse pressed"); + this.notifyAll(); + } + } + + public boolean isPassed() { + return passed_1 & passed_2; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/ListNullTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/List/ListNullTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/ListNullTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/List/ListNullTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4195583 + @summary Tests List.add(String item) to make sure an NPE is not thrown + when item == null + @key headful + @run main ListNullTest +*/ + +import java.awt.FlowLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.List; +import java.awt.Robot; + +public class ListNullTest { + List list; + Frame frame; + + public static void main(String[] args) throws Exception { + ListNullTest test = new ListNullTest(); + test.start(); + } + + public void start () throws Exception { + try { + EventQueue.invokeAndWait(() -> { + list = new List(15); + frame = new Frame("ListNullTest"); + frame.add(list); + frame.setLayout(new FlowLayout()); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + list.add("", 0); + list.add((String) null, 1); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/MaxWidthTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/List/MaxWidthTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/MaxWidthTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/List/MaxWidthTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6373369 + @summary Bug in WListPeer.getMaxWidth(), checks that the preferred width + of the list is calculated correctly + @requires (os.family == "windows") + @key headful + @run main MaxWidthTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.FontMetrics; +import java.awt.List; +import java.awt.TextArea; +import java.awt.Toolkit; + +public class MaxWidthTest { + static Frame frame; + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("MaxWidthTest"); + frame.setLayout(new BorderLayout()); + List list = new List(); + list.add("Very very very long string - the actual width more than the minimum width !!!"); + frame.add(BorderLayout.WEST, list); + frame.add(BorderLayout.CENTER, new TextArea()); + + frame.setBounds(200, 200, 200, 200); + frame.pack(); + frame.setVisible(true); + + // as WListPeer.minimumSize() - just predefined value + FontMetrics fm = frame.getFontMetrics(list.getFont()); + int minimum = 20 + fm.stringWidth("0123456789abcde"); + + // as WListPeer.preferredSize() - equals to Max.max(minimum,getMaxWidth()+20) + // getMaxWidth() returns the actual size of the list + int preferred = list.getPreferredSize().width; + + System.out.println(preferred + "," + minimum); + if (preferred <= minimum) { + throw new RuntimeException("Test failed because the actual width more than the minimum width."); + } + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/PageUPSelectsItemsTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/List/PageUPSelectsItemsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/PageUPSelectsItemsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/List/PageUPSelectsItemsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6190768 + @summary Tests that pressing pg-up / pg-down on AWT list doesn't selects the items, on XToolkit + @key headful + @run main PageUPSelectsItemsTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Label; +import java.awt.List; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import java.lang.reflect.InvocationTargetException; + +public class PageUPSelectsItemsTest implements FocusListener, KeyListener { + + List list = new List(6, true); + Label label = new Label("for focus"); + + Frame frame; + + final Object LOCK = new Object(); + final int ACTION_TIMEOUT = 500; + + public static void main(String[] args) throws Exception { + PageUPSelectsItemsTest test = new PageUPSelectsItemsTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + list.add("0"); + list.add("1"); + list.add("2"); + list.add("3"); + list.add("4"); + list.add("5"); + list.add("6"); + list.add("7"); + list.add("8"); + list.add("9"); + list.add("10"); + list.add("11"); + list.add("12"); + + list.select(8); + + list.addFocusListener(this); + list.addKeyListener(this); + frame = new Frame("PageUPSelectsItemsTest"); + frame.setLayout(new BorderLayout()); + frame.add(BorderLayout.SOUTH, list); + frame.add(BorderLayout.CENTER, label); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private void test() throws Exception { + synchronized (LOCK) { + + Robot r = new Robot(); + r.delay(500); + + Point loc = label.getLocationOnScreen(); + r.mouseMove(loc.x + (int) (label.getWidth() / 2), loc.y + (int) (label.getHeight() / 2)); + r.mousePress(InputEvent.BUTTON1_MASK); + r.delay(10); + r.mouseRelease(InputEvent.BUTTON1_MASK); + r.delay(500); + + list.requestFocusInWindow(); + LOCK.wait(ACTION_TIMEOUT); + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != list) { + throw new RuntimeException("Test failed - list isn't focus owner."); + } + + r.delay(10); + loc = list.getLocationOnScreen(); + + r.delay(50); + r.keyPress(KeyEvent.VK_PAGE_UP); + r.delay(50); + r.keyRelease(KeyEvent.VK_PAGE_UP); + r.delay(50); + + r.keyPress(KeyEvent.VK_PAGE_DOWN); + r.delay(50); + r.keyRelease(KeyEvent.VK_PAGE_DOWN); + r.delay(50); + + r.waitForIdle(); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + System.out.println("Dummy block"); + } + }); + + System.err.println("Selected objects: " + list.getSelectedItems().length); + + if (list.getSelectedItems().length > 1) { + throw new RuntimeException("Test failed"); + } + } + } + + public void focusGained(FocusEvent e) { + + synchronized (LOCK) { + LOCK.notifyAll(); + } + + } + + public void focusLost(FocusEvent e) { + } + + public void keyPressed(KeyEvent e){ + System.out.println("keyPressed-"+e); + } + + public void keyReleased(KeyEvent e){ + System.out.println("keyReleased-"+e); + } + + public void keyTyped(KeyEvent e){ + System.out.println("keyTyped-"+e); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/TriggerActionEventTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/List/TriggerActionEventTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/List/TriggerActionEventTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/List/TriggerActionEventTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6190746 + @summary Tests that list trigger ActionEvent when double clicking a programmatically selected item, XToolkit + @key headful + @run main TriggerActionEventTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.List; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; + +import java.lang.reflect.InvocationTargetException; + +public class TriggerActionEventTest implements ActionListener { + final Object LOCK = new Object(); + final int ACTION_TIMEOUT = 1000; + + List list; + Frame frame; + volatile Point loc; + private volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + TriggerActionEventTest TrgrActnEvntTest = new TriggerActionEventTest(); + TrgrActnEvntTest.test(new TestState(0)); + TrgrActnEvntTest.test(new TestState(3)); + } + + private void test(TestState currentState) throws Exception { + + synchronized (LOCK) { + System.out.println("begin test for: " + currentState); + + EventQueue.invokeAndWait(() -> { + list = new List(); + + list.clear(); + list.add("0"); + list.add("1"); + list.add("2"); + list.add("3"); + list.addActionListener(this); + + int index = currentState.getSelectedIndex(); + + list.select(index); + + frame = new Frame("TriggerActionEventTest"); + frame.setLayout(new BorderLayout()); + frame.add(BorderLayout.SOUTH, list); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + + Robot r = new Robot(); + r.delay(500); + EventQueue.invokeAndWait(() -> { + loc = list.getLocationOnScreen(); + }); + + r.mouseMove(loc.x + 10, loc.y + 10); + r.mousePress(InputEvent.BUTTON1_MASK); + r.delay(10); + r.mouseRelease(InputEvent.BUTTON1_MASK); + r.mousePress(InputEvent.BUTTON1_MASK); + r.delay(10); + r.mouseRelease(InputEvent.BUTTON1_MASK); + r.delay(10); + + + LOCK.wait(ACTION_TIMEOUT); + + System.out.println(currentState); + if (!passed) { + throw new RuntimeException("Test failed"); + } + this.passed = false; + + EventQueue.invokeAndWait(() -> { + list.removeActionListener(this); + frame.remove(list); + frame.setVisible(false); + }); + + } + } + + public void actionPerformed (ActionEvent ae) { + synchronized (LOCK) { + System.out.println(ae); + passed = true; + LOCK.notifyAll(); + } + } + +} + +class TestState { + private final int selectedIndex; + + public TestState(int selectedIndex) { + this.selectedIndex = selectedIndex; + } + + public int getSelectedIndex() { + return selectedIndex; + } + + public String toString() { + return ""+selectedIndex; + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/EnableTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/EnableTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/EnableTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/EnableTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4257944 + @summary PopupMenu.setEnabled fails on Win32 + @key headful + @run main EnableTest +*/ + +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +public class EnableTest { + PopupMenu popup = null; + Frame frame; + + public static void main(String[] args) throws Exception { + EnableTest test = new EnableTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("EnableTest"); + popup = new PopupMenu("Popup Menu Title"); + MenuItem mi1 = new MenuItem("Menu Item"); + MenuItem mi2 = new MenuItem("Menu Item"); + popup.add(mi1); + popup.addSeparator(); + popup.add(mi2); + popup.setEnabled(false); + popup.setLabel("New Label"); + mi2.setEnabled(false); + frame.add(popup); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/MenuSetLabelTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/MenuSetLabelTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/MenuSetLabelTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/MenuSetLabelTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4261935 + @summary Menu display problem when changing the text of the menu(window 98) + @key headful + @run main MenuSetLabelTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Robot; + +public class MenuSetLabelTest { + Menu1 f; + + public static void main(String[] args) throws Exception { + MenuSetLabelTest test = new MenuSetLabelTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + f = new Menu1(); + f.setTitle("MenuSetLabelTest"); + f.setSize(300, 200); + f.setLocationRelativeTo(null); + f.setVisible(true); + }); + Robot robot = new Robot(); + robot.delay(1000); + robot.waitForIdle(); + EventQueue.invokeAndWait(() -> { + f.changeMenuLabel(); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + +} + +class Menu1 extends Frame { + + String s1 = new String("short"); + String s2 = new String("This is a long string"); + String s3 = new String("Menu Item string"); + + MenuBar mb1 = new MenuBar(); + Menu f = new Menu(s1); + Menu m = new Menu(s1); + boolean flag = true; + + public Menu1() + { + for (int i = 0; i < 5; i++) { + m.add(new MenuItem(s3)); + } + for (int i = 0; i < 10; i++) { + f.add(new MenuItem(s3)); + } + mb1.add(f); + mb1.add(m); + setMenuBar(mb1); + } + + public void changeMenuLabel() { + MenuBar mb = getMenuBar(); + Menu m0 = mb.getMenu(0); + Menu m1 = mb.getMenu(1); + + if (flag) { + m0.setLabel(s2); + m1.setLabel(s2); + } else { + m0.setLabel(s1); + m1.setLabel(s1); + } + flag = !flag; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4234266 + @summary MenuItem throws NullPointer exception when setting the label with created peer. + @key headful + @run main SetLabelWithPeerCreatedTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class SetLabelWithPeerCreatedTest { + Frame frame; + public static void main(String[] args) throws Exception { + SetLabelWithPeerCreatedTest test = new SetLabelWithPeerCreatedTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("SetLabel with Peer Created Test"); + Menu menu = new Menu("Menu"); + MenuItem mi = new MenuItem("Item"); + MenuBar mb = new MenuBar(); + menu.add(mi); + mb.add(menu); + frame.setMenuBar(mb); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + mi.setLabel("new label"); + frame.setVisible(true); + System.out.println("Test PASSED!"); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/SetStateTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/SetStateTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MenuItem/SetStateTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/MenuItem/SetStateTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5106833 + @summary NullPointerException in XMenuPeer.repaintMenuItem + @key headful + @run main SetStateTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.CheckboxMenuItem; + +public class SetStateTest { + Frame frame; + public static void main(String[] args) throws Exception { + SetStateTest test = new SetStateTest(); + test.start(); + } + + public void start () throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("SetStateTest"); + MenuBar bar = new MenuBar(); + Menu menu = new Menu("Menu"); + CheckboxMenuItem checkboxMenuItem = new CheckboxMenuItem("Item"); + bar.add(menu); + frame.setMenuBar(bar); + menu.add(checkboxMenuItem); + checkboxMenuItem.setState(true); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + System.out.println("Test PASSED!"); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/BlockedMouseInputTest2.java openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/BlockedMouseInputTest2.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/BlockedMouseInputTest2.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/BlockedMouseInputTest2.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6271546 + @summary REG. Mouse input blocked on a window which is a child of a modal dialog + @key headful + @run main BlockedMouseInputTest2 +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; + +public class BlockedMouseInputTest2 { + Frame frame; + Dialog dlg1; + Dialog dlg2; + Button b; + Robot r = null; + volatile boolean passed = false; + volatile Point p; + volatile int btnWidth; + volatile int btnHeight; + + public static void main(String args[]) throws Exception { + BlockedMouseInputTest2 test = new BlockedMouseInputTest2(); + test.start(); + } + + public void start() throws Exception { + try { + r = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("Parent frame"); + frame.setBounds(100, 100, 200, 100); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + dlg1 = new Dialog(frame, "Dialog 1", true); + dlg1.setBounds(200, 200, 200, 100); + + new Thread(new Runnable() { + public void run() { + dlg1.setVisible(true); + } + }).start(); + }); + + r.delay(1000); + r.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + dlg2 = new Dialog(frame, "Dialog 2", true); + dlg2.setBounds(300, 300, 200, 100); + }); + new Thread(new Runnable() { + public void run() { + dlg2.setVisible(true); + } + }).start(); + + r.delay(1000); + r.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + Dialog d = new Dialog(dlg2, "D", false); + d.setBounds(400, 400, 200, 100); + d.setLayout(new BorderLayout()); + b = new Button("Test me"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + passed = true; + } + }); + d.add(b, BorderLayout.CENTER); + d.setVisible(true); + }); + + r.delay(1000); + r.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + p = b.getLocationOnScreen(); + btnWidth = b.getSize().width; + btnHeight = b.getSize().height; + }); + r.mouseMove(p.x + btnWidth / 2, p.y + btnHeight / 2); + r.delay(500); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + + if (!passed) { + throw new RuntimeException("Test is FAILED: button is not pressed"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (dlg1 != null) { + dlg1.dispose(); + } + if (dlg2 != null) { + dlg2.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/BlockedMouseInputTest3.java openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/BlockedMouseInputTest3.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/BlockedMouseInputTest3.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/BlockedMouseInputTest3.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6274378 + @summary Test for 6274378: Blocked mouse and keyboard input after hiding modal dialog + @key headful + @run main BlockedMouseInputTest3 +*/ + +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + + +public class BlockedMouseInputTest3 { + Frame frame; + + Dialog dlg1; // application-modal + Dialog dlg2; // application-modal + Dialog d; // toolkit-modal + + Button b1; // in dlg1 + Button b2; // in dlg2 + + Robot r = null; + + volatile boolean b1pressed, b2pressed; + volatile boolean dlg1activated, dlg2activated; + volatile int b1Width, b1Height; + volatile int b2Width, b2Height; + volatile Point p1, p2; + + public static void main(String args[]) throws Exception { + BlockedMouseInputTest3 test = new BlockedMouseInputTest3(); + test.start(); + } + + public void start() throws Exception { + try { + r = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("Parent frame"); + frame.setBounds(0, 0, 200, 100); + frame.setVisible(true); + + // create d and set it visible + d = new Dialog(frame, "Toolkit-modal", Dialog.ModalityType.TOOLKIT_MODAL); + d.setBounds(250, 0, 200, 100); + }); + EventQueue.invokeLater(new Runnable() { + public void run() { + d.setVisible(true); + } + }); + + r.delay(1000); + r.waitForIdle(); + + // create dlg1 and set it visible + // dlg1 is blocked by d + + EventQueue.invokeAndWait(() -> { + dlg1 = new Dialog(frame, "Application-modal 1", Dialog.ModalityType.APPLICATION_MODAL); + dlg1.setBounds(0, 150, 200, 100); + dlg1.addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + dlg1activated = true; + } + }); + b1 = new Button("B1"); + b1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + b1pressed = true; + } + }); + dlg1.add(b1); + }); + EventQueue.invokeLater(new Runnable() { + public void run() { + dlg1.setVisible(true); + } + }); + + r.delay(1000); + r.waitForIdle(); + + // create dlg2 and set it visible + // dlg2 is blocked by d + EventQueue.invokeAndWait(() -> { + dlg2 = new Dialog(frame, "Application-modal 2", Dialog.ModalityType.APPLICATION_MODAL); + dlg2.setBounds(0, 300, 200, 100); + dlg2.addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + dlg2activated = true; + } + }); + b2 = new Button("B2"); + b2.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + b2pressed = true; + } + }); + dlg2.add(b2); + }); + EventQueue.invokeLater(new Runnable() { + public void run() { + dlg2.setVisible(true); + } + }); + + r.delay(1000); + r.waitForIdle(); + + + // hide d + // dlg2 is unblocked and dlg1 is blocked by dlg2 + EventQueue.invokeAndWait(() -> { + d.setVisible(false); + }); + + r.delay(1000); + r.waitForIdle(); + + // values to check + b1pressed = false; + b2pressed = false; + dlg1activated = false; + dlg2activated = false; + System.err.println(KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow()); + + // check mouse events and activation + EventQueue.invokeAndWait(() -> { + p1 = b1.getLocationOnScreen(); + b1Width = b1.getWidth(); + b1Height = b1.getHeight(); + }); + clickPoint(r, p1.x + b1Width / 2, p1.y + b1Height / 2); + + EventQueue.invokeAndWait(() -> { + dlg1activated = (KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow() == dlg1); + }); + + EventQueue.invokeAndWait(() -> { + p2 = b2.getLocationOnScreen(); + b2Width = b2.getWidth(); + b2Height = b2.getHeight(); + }); + + clickPoint(r, p2.x + b2Width / 2, p2.y + b2Height / 2); + + EventQueue.invokeAndWait(() -> { + dlg2activated = (KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow() == dlg2); + }); + + if (dlg1activated || b1pressed || !dlg2activated || !b2pressed) { + throw new RuntimeException("Test is FAILED"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (dlg1 != null) { + dlg1.dispose(); + } + if (dlg2 != null) { + dlg2.dispose(); + } + if (d != null) { + d.dispose(); + } + }); + } + } + + private static void clickPoint(Robot r, int x, int y) { + r.mouseMove(x, y); + r.delay(500); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/BlockedMouseInputTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/BlockedMouseInputTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/BlockedMouseInputTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/BlockedMouseInputTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4957639 + @summary REGRESSION: blocked mouse input in a special case on win32 + @key headful + @run main BlockedMouseInputTest +*/ + +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.JComboBox; +import javax.swing.JDialog; +/* + * Threads: + * 0) Main - running others, checking + * 1) First - opening first dialog + * 2) Second - opening second dialog, generating item state changed events + * We need 1 and 2 thread in order to don't block main thread + */ + +public class BlockedMouseInputTest implements ItemListener { + Frame frame = null; + + ThreadDialog thread1 = null; + ThreadDialog thread2 = null; + + // If we recreate dialogs in the Threads classes then the test works fine + JComboBox cb = null; + JDialog dialog1 = null; + JDialog dialog2 = null; + + Robot r = null; + volatile Point loc = null; + volatile int cbWidth; + volatile int cbHeight; + + volatile int selected; + + volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + BlockedMouseInputTest test = new BlockedMouseInputTest(); + test.start(); + } + + public void start() throws Exception { + try { + r = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("Parent frame"); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (dialog1 != null) { + dialog1.dispose(); + } + if (dialog2 != null) { + dialog2.dispose(); + } + }); + } + } + + private void test() throws Exception { + + // The state of the combobox should stay the same to new iteration of the cycle + // We couldn't run the thread twice + EventQueue.invokeAndWait(() -> { + cb = new JComboBox(new String[]{"entry a", "entry b", + "entry c", "entry d", "entry e"}); + dialog1 = new JDialog(frame, "dialog1", true); + dialog2 = new JDialog(frame, "dialog2", true); + dialog2.getContentPane().add(cb); + cb.addItemListener(this); + + dialog1.setLocation(20, 20); + dialog1.setSize(new Dimension(150, 50)); + dialog2.setLocation(120, 120); + dialog2.setSize(new Dimension(150, 50)); + }); + + for (int i = 0; i < 2; i++) { + passed = false; + tryGenerateEvent(); + if (!passed && i != 0) { + throw new RuntimeException("Test failed: triggering not occurred, iteration - " + i); + } + } + } + + private void tryGenerateEvent() throws Exception { + EventQueue.invokeAndWait(() -> { + thread1 = new ThreadDialog(dialog1); + thread2 = new ThreadDialog(dialog2); + }); + + thread1.start(); + r.delay(500); + r.waitForIdle(); + thread2.start(); + r.delay(500); + r.waitForIdle(); + + doRobotAction(); + + EventQueue.invokeAndWait(() -> { + dialog2.setVisible(false); + dialog1.setVisible(false); + }); + } + + public void itemStateChanged(ItemEvent ie) { + passed = true; + System.out.println("event: "+ie); + } + + public void doRobotAction() throws Exception { + EventQueue.invokeAndWait(() -> { + loc = cb.getLocationOnScreen(); + cbWidth = cb.getWidth(); + cbHeight = cb.getHeight(); + }); + + r.mouseMove(loc.x + cbWidth / 2, loc.y + cbHeight / 2); + r.delay(500); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + + EventQueue.invokeAndWait(() -> { + selected = cb.getSelectedIndex(); + }); + + r.mouseMove(loc.x + cbWidth / 2, loc.y + cbHeight * ((selected == 0) ? 2 : 1) + 10); + r.delay(500); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + + r.waitForIdle(); + } +} + +class ThreadDialog extends Thread { + + JDialog dialog = null; + + public ThreadDialog(JDialog dialog){ + this.dialog = dialog; + } + + public void run() { + dialog.setVisible(true); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/ModalDialogCannotBeMadeNonModalTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/ModalDialogCannotBeMadeNonModalTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/ModalDialogCannotBeMadeNonModalTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/ModalDialogCannotBeMadeNonModalTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4272629 + @summary Modal dialog cannot be made non-modal + @key headful + @run main ModalDialogCannotBeMadeNonModalTest +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class ModalDialogCannotBeMadeNonModalTest { + Frame frame = null; + Button button = null; + Dialog dialog = null; + Robot r = null; + volatile Point loc = null; + + volatile private boolean buttonPressed = false; + + public static void main(String args[]) throws Exception { + ModalDialogCannotBeMadeNonModalTest test = new ModalDialogCannotBeMadeNonModalTest(); + test.start(); + } + + public void start() throws Exception { + try { + r = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("Parent frame"); + frame.setLayout(new BorderLayout()); + frame.setBounds(200, 200, 200, 200); + frame.setVisible(true); + + button = new Button("Trigger"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + buttonPressed = true; + } + }); + frame.add(button); + frame.setVisible(true); + + dialog = new Dialog(frame, "Dialog"); + dialog.setBounds(0, 0, 100, 100); + dialog.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent we) { + we.getWindow().setVisible(false); + } + }); + }); + + r.delay(500); + r.waitForIdle(); + EventQueue.invokeAndWait(() -> { + loc = button.getLocationOnScreen(); + }); + test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (dialog != null) { + dialog.dispose(); + } + }); + } + + } + public void test() throws Exception { + + // 1-visibility, 2-modality + System.out.println("1 create visible, modal ... "); + EventQueue.invokeAndWait(() -> { + dialog.setModal(true); + setDialogVisible(true); + }); + r.delay(1000); + r.waitForIdle(); + + System.out.println("2 set non visible, modal ... "); + EventQueue.invokeAndWait(() -> { + dialog.setVisible(false); + dialog.setModal(false); + }); + r.delay(1000); + r.waitForIdle(); + + System.out.println("3 set visible, non modal ... "); + EventQueue.invokeAndWait(() -> { + setDialogVisible(true); + }); + r.delay(1000); + r.waitForIdle(); + + System.out.println("4 checking ... "); + check(); + r.delay(1000); + r.waitForIdle(); + System.out.println("5 exit "); + } + + public void check() throws Exception { + r.delay(500); + r.mouseMove(loc.x + button.getWidth()/2, loc.y + button.getHeight()/2); + r.delay(500); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + + if (!buttonPressed) { + throw new RuntimeException("Test failed"); + } + } + + public void setDialogVisible(boolean visibility) { + if (visibility) { + new Thread(new Runnable() { + public void run() { + dialog.setVisible(true); + } + }).start(); + } else { + dialog.setVisible(false); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/NonModalDialogReceiveEventsAfterModalTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/NonModalDialogReceiveEventsAfterModalTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/NonModalDialogReceiveEventsAfterModalTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/NonModalDialogReceiveEventsAfterModalTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4256692 + @summary Showing a non modal dialog after a modal dialog allows both to receive events + @key headful + @run main NonModalDialogReceiveEventsAfterModalTest +*/ + +import java.awt.BorderLayout; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +public class NonModalDialogReceiveEventsAfterModalTest implements Runnable +{ + Frame modalParentFrame, nonModalParentFrame; + Dialog modalDialog, nonModalDialog; + + volatile public static boolean passed = true; + volatile public static String errorMessage = null; + + Robot r = null; + volatile Point loc = null; + + public static void main(String args[]) throws Exception { + NonModalDialogReceiveEventsAfterModalTest test = new NonModalDialogReceiveEventsAfterModalTest(); + test.start(); + } + + public void start() throws Exception { + + // create an independent top level frame to be the + // parent of the modal dialog and show it + try { + r = new Robot(); + EventQueue.invokeAndWait(() -> { + modalParentFrame = new Frame("Parent of modal dialog"); + modalParentFrame.setBounds(100, 100, 200, 200); + modalParentFrame.setLayout(new BorderLayout()); + modalParentFrame.setVisible(true); + + // create an independent top level frame to be the + // parent of the non-modal dialog and show it + nonModalParentFrame = new Frame("Parent of non-modal dialog"); + nonModalParentFrame.setBounds(400, 100, 200, 200); + nonModalParentFrame.setLayout(new BorderLayout()); + nonModalParentFrame.setVisible(true); + + // create the non-modal dialog and kick off a + // thread to show it in 1 second + nonModalDialog = new Dialog(nonModalParentFrame, "Non modal", false); + nonModalDialog.setBounds(400, 150, 100, 100); + nonModalDialog.addMouseMotionListener(new TestMouseMotionAdapter()); + nonModalDialog.addFocusListener(new TestFocusAdapter()); + new Thread(this).start(); + + // create the modal dialog and show it from this thread + modalDialog = new Dialog(modalParentFrame, "Modal", true); + modalDialog.setBounds(100, 400, 100, 100); + modalDialog.setVisible(true); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (modalParentFrame != null) { + modalParentFrame.dispose(); + } + if (nonModalParentFrame != null) { + nonModalParentFrame.dispose(); + } + if (modalDialog != null) { + modalDialog.dispose(); + } + if (nonModalDialog != null) { + nonModalDialog.dispose(); + } + }); + } + + } + + // This is the implementation of Runnable and is + // used to show the non-modal dialog in 1 second + public void run() { + r.delay(1000); + r.waitForIdle(); + //show the non modal dialog + nonModalDialog.setVisible(true); + + r.delay(1000); + r.waitForIdle(); + test(); + } + + private void test() { + + // mouse, focus, activate events triggering + r.delay(500); + loc = nonModalDialog.getLocationOnScreen(); + r.delay(500); + + r.mouseMove(loc.x + (int) (nonModalDialog.getWidth() / 2), loc.y + (int) (nonModalDialog.getHeight() / 2)); + r.delay(100); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(100); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(100); + r.mouseMove(loc.x - 100, loc.y - 100); + + r.waitForIdle(); + + // dispose modal window in order to finish test + modalDialog.dispose(); + + // check test result + if (!passed) { + throw new RuntimeException("test failed: " + errorMessage); + } + } + + public static void testFailed(String message) { + passed = false; + errorMessage = message; + } +} + +class TestMouseMotionAdapter extends MouseMotionAdapter { + + public void mouseClicked(MouseEvent e){ + NonModalDialogReceiveEventsAfterModalTest.testFailed("mouseClicked"); + } + + public void mouseEntered(MouseEvent e){ + NonModalDialogReceiveEventsAfterModalTest.testFailed("mouseEntered"); + } + + public void mouseExited(MouseEvent e){ + NonModalDialogReceiveEventsAfterModalTest.testFailed("mouseExited"); + } + + public void mousePressed(MouseEvent e){ + NonModalDialogReceiveEventsAfterModalTest.testFailed("mousePressed"); + } + + public void mouseReleased(MouseEvent e){ + NonModalDialogReceiveEventsAfterModalTest.testFailed("mouseReleased"); + } +} + +class TestFocusAdapter extends FocusAdapter { + public void focusGained(FocusEvent e){ + NonModalDialogReceiveEventsAfterModalTest.testFailed("focusGained"); + } + + public void focusLost(FocusEvent e){ + NonModalDialogReceiveEventsAfterModalTest.testFailed("focusLost"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/ParentCatchupDraggingChildDialogTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/ParentCatchupDraggingChildDialogTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Modal/ParentCatchupDraggingChildDialogTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Modal/ParentCatchupDraggingChildDialogTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5083555 + @summary Parent Windows of mouse events catchup while dragging child dialog window + @key headful + @run main ParentCatchupDraggingChildDialogTest +*/ + +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Robot; + +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; + + +public class ParentCatchupDraggingChildDialogTest { + JFrame frame = null; + JDialog dialog = null; + DialogThread thread = null; + JButton trigger = new JButton("trigger"); + JButton show = new JButton("show"); + Robot r = null; + volatile Point locTrigger, locDialog; + + volatile boolean passed = true; + + public static void main(String args[]) throws Exception { + ParentCatchupDraggingChildDialogTest test = new ParentCatchupDraggingChildDialogTest(); + test.start(); + } + + public void start () throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new JFrame("Parent frame"); + frame.setBounds(20, 20, 300, 300); + frame.setLayout(new FlowLayout()); + frame.add(trigger); + frame.add(show); + frame.setVisible(true); + + dialog = new JDialog(frame, "Dialog", true); + dialog.setBounds(100, 100, 300, 300); + + trigger.addMouseListener(new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + System.out.println("Trigger button event: " + e); + passed = false; + } + }); + }); + + thread = new DialogThread(dialog); + thread.start(); + + test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (dialog != null) { + dialog.dispose(); + } + }); + } + } + + /* Test scenario: + * 1) dragging mouse over the 'Trigger' button in order to be sure that the events don't occured for non modal window + * 2) checking + * 3) close dialog in order to finish test + */ + private void test() throws Exception { + try { + r = new Robot(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + r.delay(500); + EventQueue.invokeAndWait(() -> { + locTrigger = trigger.getLocationOnScreen(); + }); + + r.delay(500); + EventQueue.invokeAndWait(() -> { + locDialog = dialog.getLocationOnScreen(); + }); + r.delay(500); + + r.mouseMove(locDialog.x + dialog.getWidth() / 2, locDialog.y + dialog.getHeight() / 2); + r.delay(500); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + r.mouseMove(locTrigger.x + trigger.getWidth() / 2, locTrigger.y + trigger.getHeight() / 2); + r.delay(500); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + + if (!passed) { + throw new RuntimeException("Test failed. Triggering occured."); + } + + EventQueue.invokeAndWait(() -> { + dialog.dispose(); + }); + } +} + +class DialogThread extends Thread { + JDialog dialog = null; + + public DialogThread(JDialog dialog){ + this.dialog = dialog; + } + + public void run(){ + dialog.setVisible(true); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MouseInfo/ButtonsNumber.java openjdk-17-17.0.8+7/test/jdk/java/awt/MouseInfo/ButtonsNumber.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MouseInfo/ButtonsNumber.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/MouseInfo/ButtonsNumber.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4908137 + @summary tests that non-zero number of mouse buttons is returned + @key headful +*/ + +import java.awt.MouseInfo; + +public class ButtonsNumber { + + public static void main(String[] args) { + + if (MouseInfo.getNumberOfButtons() == 0) { + throw new RuntimeException("Zero returned by getNumberOfButtons(). Test failed."); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @summary unit test for a new method in Container class: getMousePosition(boolean) + @bug 4009555 + @key headful +*/ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; + +public class ContainerMousePositionTest { + private Button button; + private Frame frame; + private Panel panel; + private static Dimension BUTTON_DIMENSION = new Dimension(100, 100); + private static Dimension FRAME_DIMENSION = new Dimension(200, 200); + private static Point POINT_WITHOUT_COMPONENTS = new Point(10, 10); + private static Point FIRST_BUTTON_LOCATION = new Point(20, 20); + private static int DELAY = 1000; + Robot robot; + volatile int xPos = 0; + volatile int yPos = 0; + Point pMousePosition; + + public static void main(String[] args) throws Exception { + ContainerMousePositionTest containerObj = new ContainerMousePositionTest(); + containerObj.init(); + containerObj.start(); + } + + public void init() throws Exception { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + button = new Button("Button"); + frame = new Frame("Testing Component.getMousePosition()"); + panel = new Panel(); + + button.setSize(BUTTON_DIMENSION); + button.setLocation(FIRST_BUTTON_LOCATION); + + panel.setLayout(null); + + panel.add(button); + frame.add(panel); + frame.setSize(FRAME_DIMENSION); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + try { + robot.delay(DELAY); + robot.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + Point p = button.getLocationOnScreen(); + xPos = p.x + button.getWidth() / 2; + yPos = p.y + button.getHeight() / 2; + }); + robot.mouseMove(xPos,yPos); + robot.delay(DELAY); + + EventQueue.invokeAndWait(() -> { + pMousePosition = frame.getMousePosition(false); + if (pMousePosition != null) { + throw new RuntimeException("Test failed: Container is " + + "overlapped by " + " child and it should be taken " + + "into account"); + } + System.out.println("Test stage completed: Container is " + + "overlapped by " + " child and it was taken into " + + "account"); + + pMousePosition = frame.getMousePosition(true); + if (pMousePosition == null) { + throw new RuntimeException("Test failed: Container is " + + "overlapped by " + " child and it should not be " + + "taken into account"); + } + System.out.println("Test stage completed: Container is " + + "overlapped by " + " child and it should not be " + + "taken into account"); + xPos = panel.getLocationOnScreen().x + POINT_WITHOUT_COMPONENTS.x; + yPos = panel.getLocationOnScreen().y + POINT_WITHOUT_COMPONENTS.y; + }); + + robot.mouseMove(xPos, yPos); + + robot.delay(DELAY); + + EventQueue.invokeAndWait(() -> { + pMousePosition = panel.getMousePosition(true); + if (pMousePosition == null) { + throw new RuntimeException("Test failed: Pointer was " + + "outside of " + "the component so getMousePosition()" + + " should not return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the component and getMousePosition() has not returned null"); + + pMousePosition = panel.getMousePosition(false); + if (pMousePosition == null) { + throw new RuntimeException("Test failed: Pointer was outside of " + + "the component so getMousePosition() should not return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the component and getMousePosition() has not returned null"); + xPos = frame.getLocationOnScreen().x + frame.getWidth() + POINT_WITHOUT_COMPONENTS.x; + yPos = frame.getLocationOnScreen().y + frame.getHeight() + POINT_WITHOUT_COMPONENTS.y; + }); + robot.mouseMove(xPos, yPos); + + robot.delay(DELAY); + + EventQueue.invokeAndWait(() -> { + pMousePosition = frame.getMousePosition(true); + if (pMousePosition != null) { + throw new RuntimeException("Test failed: Pointer was outside of " + + "the Frame widow and getMousePosition() should return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the Frame widow and getMousePosition() returned null"); + + pMousePosition = frame.getMousePosition(false); + if (pMousePosition != null) { + throw new RuntimeException("Test failed: Pointer was outside of " + + "the Frame widow and getMousePosition() should return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the Frame widow and getMousePosition() returned null"); + }); + robot.delay(DELAY); + + System.out.println("ComponentMousePositionTest PASSED."); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java openjdk-17-17.0.8+7/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java 2023-07-05 07:11:54.000000000 +0000 @@ -40,7 +40,7 @@ /** * @test * @key headful - * @bug 8215105 8211999 + * @bug 8215105 8211999 8298887 * @summary tests that Robot can capture the common colors without artifacts * @run main/othervm CheckCommonColors * @run main/othervm -Xcheck:jni CheckCommonColors diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/ReplaceRangeTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/ReplaceRangeTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/ReplaceRangeTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/ReplaceRangeTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 5025532 + @requires (os.family == "windows") + @summary Tests that textarea replaces text correctly if the text contains + line separators + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.TextArea; + +import java.lang.reflect.InvocationTargetException; + +public class ReplaceRangeTest { + static Frame f; + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + try { + EventQueue.invokeAndWait(() -> { + f = new Frame("Test frame"); + f.setSize(400, 400); + f.setLayout(new GridLayout(3, 1)); + + TextArea textArea1 = new TextArea(5, 80); + TextArea textArea2 = new TextArea(5, 80); + TextArea textArea3 = new TextArea(5, 80); + f.add(textArea1); + f.add(textArea2); + f.add(textArea3); + f.setVisible(true); + + textArea1.setText("01234"); + textArea1.replaceRange("X", 3, 4); + textArea2.setText("0\r\n234"); + textArea2.replaceRange("X", 3, 4); + textArea3.setText("0\n\n34"); + textArea3.replaceRange("X", 3, 4); + + if (textArea1.getText().equals("012X4") && + textArea2.getText().equals("0\r\n2X4") && + textArea3.getText().equals("0\n\nX4")) { + System.out.println("Test Pass"); + return; + } else { + throw new RuntimeException("Test FAILED"); + } + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/TextAreaCRLFAutoDetectTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/TextAreaCRLFAutoDetectTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/TextAreaCRLFAutoDetectTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/TextAreaCRLFAutoDetectTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,155 @@ +/* + * 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 4800187 + @requires (os.family == "windows") + @summary REGRESSION:show the wrong selection when there are \r characters in the text + @key headful +*/ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.IllegalComponentStateException; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; + +import java.lang.reflect.InvocationTargetException; + +public class TextAreaCRLFAutoDetectTest { + Frame f; + TextArea ta1; + TextArea ta2; + Button b; + boolean passed = true; + boolean crlf = true; + + public static void main(String[] args) throws Exception { + TextAreaCRLFAutoDetectTest crlfAutoDetectTest = new TextAreaCRLFAutoDetectTest(); + crlfAutoDetectTest.init(); + crlfAutoDetectTest.start(); + } + + public void init() throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(() -> { + f = new Frame("TextAreaCRLFAutoDetectTest"); + ta1 = new TextArea(5, 20); + ta2 = new TextArea(5, 20); + b = new Button("Click Me"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ta1.setText(""); + ta2.setText(""); + System.out.println("--------------------------------"); + + String eoln = (crlf) ? "\r\n" : "\n"; + String s = eoln + "123" + eoln + "567" + eoln + "90" + eoln; + printString(" s=", s); + ta1.setText(s); + printString("ta1.getText()=", ta1.getText()); + + s = "67" + eoln + "9"; + ta1.select(6, 10); + + String s1 = ta1.getSelectedText(); + printString("ta1.getSelectedText()=", s1); + passed = passed && s.equals(s1); + + ta2.setText(s1); + printString(" ta2.getText()=", s1); + passed = passed && s1.equals(ta2.getText()); + + crlf = false; + } + }); + + f.setLayout(new FlowLayout()); + f.add(ta1); + f.add(ta2); + f.add(b); + f.setLocation(300, 50); + f.pack(); + f.setVisible(true); + }); + } + + public void start() throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.waitForIdle(); + + Point pt = new Point(0, 0); + + boolean drawn = false; + while (!drawn) { + try { + pt = b.getLocationOnScreen(); + } catch (IllegalComponentStateException icse) { + Thread.sleep(50); + continue; + } + drawn = true; + } + + for (int i = 0; i < 2; i++) { + pt = b.getLocationOnScreen(); + robot.mouseMove(pt.x + b.getWidth() / 2, + pt.y + b.getHeight() / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + Thread.sleep(250); + } + if (!passed) { + throw new RuntimeException("TextAreaCRLFAutoDetectTest FAILED."); + } else { + System.out.println("TextAreaCRLFAutoDetectTest PASSED"); + } + } catch (Exception e) { + throw new RuntimeException("The test was not completed.\n\n" + e); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + void printString(String t, String s) { + byte b[] = s.getBytes(); + String o = t; + for (int i = 0; i < b.length; i++) { + o += Byte.toString(b[i]) + " "; + } + System.out.println(o); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/TextLengthTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/TextLengthTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/TextLengthTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/TextLengthTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4072264 + @summary REGRESSION:Test to verify getSelectedText, + getSelectedStart/End in TextArea class + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextArea; + +public class TextLengthTest { + static final int MY_SIZE = 100; + static final int MY_START = 13; + static final int MY_END = 47; + TextArea ta; + Frame f; + int mySize; + int myStart; + int myEnd; + + public static void main(String[] args) throws Exception { + TextLengthTest textLengthTest = new TextLengthTest(); + textLengthTest.init(); + textLengthTest.start(); + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + f = new Frame("TextLengthTest"); + ta = new TextArea(15, 30); + f.add(ta); + f.setSize(400, 400); + f.setVisible(true); + }); + } + + public void start() throws Exception { + try { + Robot r = new Robot(); + r.delay(1000); + r.waitForIdle(); + EventQueue.invokeAndWait(() -> { + StringBuffer bigStringBuffer = new StringBuffer(); + + for (int i = 1; i <= 10; i++) { + bigStringBuffer.append("abcdefghi\n"); + } + + ta.setText(bigStringBuffer.toString()); + + mySize = bigStringBuffer.toString().length(); + System.out.println("String size = " + mySize); + + if (mySize != MY_SIZE) { + throw new Error("The string size is " + + mySize + "but it should be " + MY_SIZE); + } + + ta.select(MY_START, MY_END); + + String str = new String(ta.getSelectedText()); + str = str.toUpperCase(); + + myStart = ta.getSelectionStart(); + myEnd = ta.getSelectionEnd(); + System.out.println("Selected string start = " + myStart); + System.out.println("Selected string end = " + myEnd); + + if (myStart != MY_START) { + throw new Error("The selected text starts at " + + mySize + "but it should start at " + MY_START); + } + + if (myEnd != MY_END) { + throw new Error("The selected text ends at " + + myEnd + "but it should end at " + MY_END); + } + + ta.replaceRange(str, myStart, myEnd); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + System.out.println("Test Pass"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/TextLimitTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/TextLimitTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextArea/TextLimitTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextArea/TextLimitTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4260109 + @summary tests that the text limit is set to the maximum possible value + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.TextArea; + +public class TextLimitTest { + static Frame frame; + static TextArea textarea; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + StringBuffer buffer = new StringBuffer(); + frame = new Frame("Text Limit Test"); + textarea = new TextArea(3, 10); + frame.setLayout(new BorderLayout()); + frame.add(textarea); + frame.setSize(200, 200); + frame.pack(); + frame.setVisible(true); + + /* + * The magic number 0xF700 was choosen because of the two reasons: + * - it shouldn't be greater since on win95 (even in native win32 apps) + * adding more than 0xF800 symbols to a textarea doesn't always work, + * - it shouldn't be less since in this case we won't run in the stack + * overflow on Win95 even if we use W2A allocating memory on the stack. + */ + for (int i = 0; i < 0xF700; i += 0x10) { + buffer.append("0123456789abcdef"); + } + + textarea.setText(buffer.toString()); + System.out.println("Text length before append: " + + Integer.toString(textarea.getText().length(), 16)); + + textarea.append("0123456789abcdef"); + + int len = textarea.getText().length(); + System.out.println("Text length after append: " + + Integer.toString(len, 16)); + if (len != 0xF710) { + throw new RuntimeException("Test failed: textarea has " + + "wrong text limit!"); + } + }); + System.out.println("Test pass"); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/CorrectSetCaretPositionDuringInitPeerTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/CorrectSetCaretPositionDuringInitPeerTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/CorrectSetCaretPositionDuringInitPeerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/CorrectSetCaretPositionDuringInitPeerTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5100200 + @summary IAE in X11 text field peer code + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.TextField; + +public class CorrectSetCaretPositionDuringInitPeerTest +{ + static TextField tf; + static Frame frame; + + public static void main(String[] args) throws Exception { + try{ + EventQueue.invokeAndWait(() -> { + frame = new Frame("Caret Position test"); + tf = new TextField("Very very very long string"); + tf.setSelectionStart(10); + tf.setText("Short"); // now TextField.length() less than 10 + frame.add(tf); + + frame.pack(); + frame.setVisible(true); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/DeselectionDuringDoSelectionNonVisibleTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/DeselectionDuringDoSelectionNonVisibleTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/DeselectionDuringDoSelectionNonVisibleTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/DeselectionDuringDoSelectionNonVisibleTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5100950 8199723 + @summary textarea.getSelectedText() returns the de-selected text, on XToolkit + @key headful + @requires (os.family == "mac") | (os.family == "windows") +*/ + +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.TextField; + +public class DeselectionDuringDoSelectionNonVisibleTest { + static TextField tf1; + static TextField tf2; + static Frame frame; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("Deselection test"); + tf1 = new TextField("Text Field 1"); + tf2 = new TextField("Text Field 2"); + frame.add(tf1); + frame.add(tf2); + frame.setLayout(new FlowLayout()); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + + boolean isWin = System.getProperty("os.name").startsWith("Win"); + System.out.println("is Windows OS? " + isWin); + + Thread.sleep(500); + tf1.requestFocus(); + + Thread.sleep(500); + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != tf1) { + throw new RuntimeException("Test failed (TextField1 isn't focus owner)."); + } + tf1.selectAll(); + Thread.sleep(500); + + tf2.requestFocus(); + Thread.sleep(500); + + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != tf2) { + throw new RuntimeException("Test failed (TextField2 isn't focus owner)."); + } + tf2.selectAll(); + Thread.sleep(500); + + String selectedText = tf1.getSelectedText(); + String text = tf1.getText(); + + System.out.println("tf1.getText()=" + text); + System.out.println("tf1.getSelectedText()=" + selectedText); + + // Motif behaviour: After the selection of the second text, the first selected + // text is unselected + if (!selectedText.equals("") && !isWin) { + throw new RuntimeException("Test failed (TextField1 isn't deselected)."); + } + + // Windows behaviour: After the selection of the second text, the first selected + // text is only not highlighted + if (!selectedText.equals(text) && isWin) { + throw new RuntimeException("Test failed (TextField1 is deselected)."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/GetCaretPosOutOfBoundsTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/GetCaretPosOutOfBoundsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/GetCaretPosOutOfBoundsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/GetCaretPosOutOfBoundsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4995931 + @summary java.awt.TextComponent caret position should be within the text bounds + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.TextField; + +public class GetCaretPosOutOfBoundsTest { + static TextField tf; + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + tf = new TextField("1234567890"); + tf.setCaretPosition(100); + int pos = tf.getCaretPosition(); + if (pos > 10) { + throw new RuntimeException("Wrong caret position:" + pos + " instead of 10"); + } + tf.setText("12345"); + if (tf.getCaretPosition() > 5) { + throw new RuntimeException("Wrong caret position:" + pos + " instead of 5"); + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/InitialInsertionCaretPositionTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/InitialInsertionCaretPositionTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/InitialInsertionCaretPositionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/InitialInsertionCaretPositionTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4185654 + @summary tests that the text insertion caret is positioned before the first character + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.TextField; +import java.awt.TextArea; + +public class InitialInsertionCaretPositionTest { + static TextField textField; + static TextArea textArea; + static String failureMessage = ""; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + textArea = new TextArea("abcdefghij\nabcdefghij"); + textField = new TextField("abcdefghij"); + + boolean textFieldPassed = (textField.getCaretPosition() == 0); + boolean textAreaPassed = (textArea.getCaretPosition() == 0); + + if (!textFieldPassed) { + failureMessage += " The text insertion caret for the text field is not\n"; + failureMessage += " initially set before the first character.\n"; + } + if (!textAreaPassed) { + failureMessage += " The text insertion caret for the text area is not\n"; + failureMessage += " initially set before the first character.\n"; + } + if (textAreaPassed && textFieldPassed) { + System.out.println("The test passed."); + } else { + System.out.println("The test failed:"); + System.out.println(failureMessage); + } + if (!textAreaPassed || !textFieldPassed) { + throw new RuntimeException(failureMessage); + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/MiddleMouseClickPasteTest.java openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/MiddleMouseClickPasteTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/awt/TextComponent/MiddleMouseClickPasteTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/awt/TextComponent/MiddleMouseClickPasteTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4426750 + @requires (os.family == "linux") + @key headful + @summary tests that middle mouse button click pastes primary selection +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.TextComponent; +import java.awt.TextField; + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.InputEvent; +import java.awt.Toolkit; + +public class MiddleMouseClickPasteTest { + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int SELECTION_PASTE_TIMEOUT = 1000; + static final int CLICK_INTERVAL = 50; + static final String TEST_TEXT = "TEST TEXT"; + static Frame frame; + static TextField tf; + static TextArea ta; + static final Clipboard systemSelection = Toolkit.getDefaultToolkit().getSystemSelection(); + + + public static void main(String[] args) throws Exception { + if (systemSelection != null) { + try { + EventQueue.invokeAndWait(MiddleMouseClickPasteTest::createAndShowGui); + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + checkPaste(tf); + checkPaste(ta); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + EventQueue.invokeAndWait(()-> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + } + + public static void createAndShowGui() { + frame = new Frame(); + tf = new TextField(); + ta = new TextArea(); + + frame.setLayout(new BorderLayout()); + frame.add(tf, BorderLayout.NORTH); + frame.add(ta, BorderLayout.CENTER); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public static void checkPaste(TextComponent textComponent) throws Exception { + + final Point sourcePoint = textComponent.getLocationOnScreen(); + final Dimension d = textComponent.getSize(); + sourcePoint.translate(d.width / 2, d.height / 2); + final Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(CLICK_INTERVAL); + + textComponent.setText(""); + systemSelection.setContents(new StringSelection(TEST_TEXT), null); + + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.mousePress(InputEvent.BUTTON2_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON2_DOWN_MASK); + robot.delay(SELECTION_PASTE_TIMEOUT); + + if (!TEST_TEXT.equals(textComponent.getText())) { + throw new RuntimeException("Primary selection not pasted" + + " into: " + textComponent); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -40,7 +40,14 @@ abstract class VarHandleBaseTest { static final int ITERS = Integer.getInteger("iters", 1); - static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); + + // More resilience for Weak* tests. These operations may spuriously + // fail, and so we do several attempts with delay on failure. + // Be mindful of worst-case total time on test, which would be at + // roughly (delay*attempts) milliseconds. + // + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 100); + static final int WEAK_DELAY_MS = Math.max(1, Integer.getInteger("weakDelay", 1)); interface ThrowingRunnable { void run() throws Throwable; @@ -498,4 +505,14 @@ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType()); } } + + static void weakDelay() { + try { + if (WEAK_DELAY_MS > 0) { + Thread.sleep(WEAK_DELAY_MS); + } + } catch (InterruptedException ie) { + // Do nothing. + } + } } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java 2023-07-05 07:11:54.000000000 +0000 @@ -505,6 +505,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(recv); @@ -522,6 +523,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(recv); @@ -539,6 +541,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(recv); @@ -556,6 +559,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) vh.get(recv); @@ -793,6 +797,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(); @@ -810,6 +815,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(); @@ -827,6 +833,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(); @@ -844,6 +851,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) vh.get(); @@ -1084,6 +1092,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(array, i); @@ -1101,6 +1110,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(array, i); @@ -1118,6 +1128,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(array, i); @@ -1135,6 +1146,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java 2023-07-05 07:11:54.000000000 +0000 @@ -483,6 +483,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) vh.get(recv); @@ -500,6 +501,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(recv); @@ -517,6 +519,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) vh.get(recv); @@ -534,6 +537,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) vh.get(recv); @@ -787,6 +791,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain((byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) vh.get(); @@ -804,6 +809,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire((byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(); @@ -821,6 +827,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease((byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) vh.get(); @@ -838,6 +845,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet((byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) vh.get(); @@ -1094,6 +1102,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) vh.get(array, i); @@ -1111,6 +1120,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(array, i); @@ -1128,6 +1138,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) vh.get(array, i); @@ -1145,6 +1156,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java 2023-07-05 07:11:54.000000000 +0000 @@ -483,6 +483,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) vh.get(recv); @@ -500,6 +501,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) vh.get(recv); @@ -517,6 +519,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) vh.get(recv); @@ -534,6 +537,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) vh.get(recv); @@ -787,6 +791,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain('\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) vh.get(); @@ -804,6 +809,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire('\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) vh.get(); @@ -821,6 +827,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease('\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) vh.get(); @@ -838,6 +845,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet('\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) vh.get(); @@ -1094,6 +1102,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) vh.get(array, i); @@ -1111,6 +1120,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) vh.get(array, i); @@ -1128,6 +1138,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) vh.get(array, i); @@ -1145,6 +1156,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java 2023-07-05 07:11:54.000000000 +0000 @@ -553,6 +553,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(recv); @@ -570,6 +571,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(recv); @@ -587,6 +589,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(recv); @@ -604,6 +607,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(recv); @@ -809,6 +813,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(); @@ -826,6 +831,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(); @@ -843,6 +849,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(); @@ -860,6 +867,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(); @@ -1068,6 +1076,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); @@ -1085,6 +1094,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); @@ -1102,6 +1112,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); @@ -1119,6 +1130,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java 2023-07-05 07:11:54.000000000 +0000 @@ -553,6 +553,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(recv); @@ -570,6 +571,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(recv); @@ -587,6 +589,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(recv); @@ -604,6 +607,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(recv); @@ -809,6 +813,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(); @@ -826,6 +831,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(); @@ -843,6 +849,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(); @@ -860,6 +867,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(); @@ -1068,6 +1076,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); @@ -1085,6 +1094,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); @@ -1102,6 +1112,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); @@ -1119,6 +1130,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java 2023-07-05 07:11:54.000000000 +0000 @@ -483,6 +483,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(recv); @@ -500,6 +501,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(recv); @@ -517,6 +519,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(recv); @@ -534,6 +537,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(recv); @@ -787,6 +791,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(); @@ -804,6 +809,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(); @@ -821,6 +827,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(); @@ -838,6 +845,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(); @@ -1094,6 +1102,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); @@ -1111,6 +1120,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); @@ -1128,6 +1138,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); @@ -1145,6 +1156,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java 2023-07-05 07:11:54.000000000 +0000 @@ -483,6 +483,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(recv); @@ -500,6 +501,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(recv); @@ -517,6 +519,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(recv); @@ -534,6 +537,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(recv); @@ -787,6 +791,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(); @@ -804,6 +809,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(); @@ -821,6 +827,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(); @@ -838,6 +845,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(); @@ -1094,6 +1102,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); @@ -1111,6 +1120,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); @@ -1128,6 +1138,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); @@ -1145,6 +1156,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java 2023-07-05 07:11:54.000000000 +0000 @@ -483,6 +483,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) vh.get(recv); @@ -500,6 +501,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) vh.get(recv); @@ -517,6 +519,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) vh.get(recv); @@ -534,6 +537,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) vh.get(recv); @@ -787,6 +791,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain((short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) vh.get(); @@ -804,6 +809,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire((short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) vh.get(); @@ -821,6 +827,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease((short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) vh.get(); @@ -838,6 +845,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet((short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) vh.get(); @@ -1094,6 +1102,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) vh.get(array, i); @@ -1111,6 +1120,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) vh.get(array, i); @@ -1128,6 +1138,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) vh.get(array, i); @@ -1145,6 +1156,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java 2023-07-05 07:11:54.000000000 +0000 @@ -582,6 +582,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) vh.get(recv); @@ -599,6 +600,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) vh.get(recv); @@ -616,6 +618,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) vh.get(recv); @@ -633,6 +636,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) vh.get(recv); @@ -822,6 +826,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain("foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) vh.get(); @@ -839,6 +844,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire("bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) vh.get(); @@ -856,6 +862,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease("foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) vh.get(); @@ -873,6 +880,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet("bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) vh.get(); @@ -1065,6 +1073,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) vh.get(array, i); @@ -1082,6 +1091,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) vh.get(array, i); @@ -1099,6 +1109,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) vh.get(array, i); @@ -1116,6 +1127,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java 2023-07-05 07:11:54.000000000 +0000 @@ -1081,6 +1081,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); @@ -1098,6 +1099,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); @@ -1115,6 +1117,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); @@ -1132,6 +1135,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(array, i); @@ -1282,6 +1286,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); @@ -1299,6 +1304,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); @@ -1316,6 +1322,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); @@ -1333,6 +1340,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java 2023-07-05 07:11:54.000000000 +0000 @@ -1081,6 +1081,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); @@ -1098,6 +1099,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); @@ -1115,6 +1117,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); @@ -1132,6 +1135,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(array, i); @@ -1282,6 +1286,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); @@ -1299,6 +1304,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); @@ -1316,6 +1322,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); @@ -1333,6 +1340,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java 2023-07-05 07:11:54.000000000 +0000 @@ -1265,6 +1265,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); @@ -1282,6 +1283,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); @@ -1299,6 +1301,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); @@ -1316,6 +1319,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(array, i); @@ -1576,6 +1580,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); @@ -1593,6 +1598,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); @@ -1610,6 +1616,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); @@ -1627,6 +1634,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java 2023-07-05 07:11:54.000000000 +0000 @@ -1265,6 +1265,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); @@ -1282,6 +1283,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); @@ -1299,6 +1301,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); @@ -1316,6 +1319,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(array, i); @@ -1576,6 +1580,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); @@ -1593,6 +1598,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); @@ -1610,6 +1616,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); @@ -1627,6 +1634,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, true, false); + success = (boolean) mh.invokeExact(recv, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, false, true); + success = (boolean) mh.invokeExact(recv, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, true, false); + success = (boolean) mh.invokeExact(recv, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, false, true); + success = (boolean) mh.invokeExact(recv, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -470,9 +479,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(true, false); + success = (boolean) mh.invokeExact(true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); @@ -487,9 +498,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(false, true); + success = (boolean) mh.invokeExact(false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); @@ -497,16 +510,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(false, false); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact(false, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(true, false); + success = (boolean) mh.invokeExact(true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); @@ -521,9 +537,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(false, true); + success = (boolean) mh.invokeExact(false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); @@ -757,9 +775,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, true, false); + success = (boolean) mh.invokeExact(array, i, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -774,9 +794,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, false, true); + success = (boolean) mh.invokeExact(array, i, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -791,9 +813,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, true, false); + success = (boolean) mh.invokeExact(array, i, true, false); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -808,9 +832,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, false, true); + success = (boolean) mh.invokeExact(array, i, false, true); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (byte)0x01, (byte)0x23); + success = (boolean) mh.invokeExact(recv, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (byte)0x23, (byte)0x01); + success = (boolean) mh.invokeExact(recv, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (byte)0x01, (byte)0x23); + success = (boolean) mh.invokeExact(recv, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (byte)0x23, (byte)0x01); + success = (boolean) mh.invokeExact(recv, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -492,9 +501,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((byte)0x01, (byte)0x23); + success = (boolean) mh.invokeExact((byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); @@ -509,9 +520,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((byte)0x23, (byte)0x01); + success = (boolean) mh.invokeExact((byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); @@ -519,16 +532,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((byte)0x23, (byte)0x45); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact((byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((byte)0x01, (byte)0x23); + success = (boolean) mh.invokeExact((byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); @@ -543,9 +559,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((byte)0x23, (byte)0x01); + success = (boolean) mh.invokeExact((byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); @@ -801,9 +819,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (byte)0x01, (byte)0x23); + success = (boolean) mh.invokeExact(array, i, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -818,9 +838,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (byte)0x23, (byte)0x01); + success = (boolean) mh.invokeExact(array, i, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -835,9 +857,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, (byte)0x01, (byte)0x23); + success = (boolean) mh.invokeExact(array, i, (byte)0x01, (byte)0x23); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -852,9 +876,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (byte)0x23, (byte)0x01); + success = (boolean) mh.invokeExact(array, i, (byte)0x23, (byte)0x01); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, '\u0123', '\u4567'); + success = (boolean) mh.invokeExact(recv, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, '\u4567', '\u0123'); + success = (boolean) mh.invokeExact(recv, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, '\u0123', '\u4567'); + success = (boolean) mh.invokeExact(recv, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, '\u4567', '\u0123'); + success = (boolean) mh.invokeExact(recv, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -492,9 +501,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact('\u0123', '\u4567'); + success = (boolean) mh.invokeExact('\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); @@ -509,9 +520,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact('\u4567', '\u0123'); + success = (boolean) mh.invokeExact('\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); @@ -519,16 +532,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact('\u4567', '\u89AB'); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact('\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact('\u0123', '\u4567'); + success = (boolean) mh.invokeExact('\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); @@ -543,9 +559,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact('\u4567', '\u0123'); + success = (boolean) mh.invokeExact('\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); @@ -801,9 +819,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, '\u0123', '\u4567'); + success = (boolean) mh.invokeExact(array, i, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -818,9 +838,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, '\u4567', '\u0123'); + success = (boolean) mh.invokeExact(array, i, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -835,9 +857,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, '\u0123', '\u4567'); + success = (boolean) mh.invokeExact(array, i, '\u0123', '\u4567'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -852,9 +876,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, '\u4567', '\u0123'); + success = (boolean) mh.invokeExact(array, i, '\u4567', '\u0123'); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0d, 2.0d); + success = (boolean) mh.invokeExact(recv, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0d, 1.0d); + success = (boolean) mh.invokeExact(recv, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0d, 2.0d); + success = (boolean) mh.invokeExact(recv, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0d, 1.0d); + success = (boolean) mh.invokeExact(recv, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -414,9 +423,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0d, 2.0d); + success = (boolean) mh.invokeExact(1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); @@ -431,9 +442,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0d, 1.0d); + success = (boolean) mh.invokeExact(2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); @@ -441,16 +454,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0d, 3.0d); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact(2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0d, 2.0d); + success = (boolean) mh.invokeExact(1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); @@ -465,9 +481,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0d, 1.0d); + success = (boolean) mh.invokeExact(2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); @@ -645,9 +663,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0d, 2.0d); + success = (boolean) mh.invokeExact(array, i, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -662,9 +682,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d, 1.0d); + success = (boolean) mh.invokeExact(array, i, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -679,9 +701,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1.0d, 2.0d); + success = (boolean) mh.invokeExact(array, i, 1.0d, 2.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -696,9 +720,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0d, 1.0d); + success = (boolean) mh.invokeExact(array, i, 2.0d, 1.0d); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0f, 2.0f); + success = (boolean) mh.invokeExact(recv, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0f, 1.0f); + success = (boolean) mh.invokeExact(recv, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0f, 2.0f); + success = (boolean) mh.invokeExact(recv, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0f, 1.0f); + success = (boolean) mh.invokeExact(recv, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -414,9 +423,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0f, 2.0f); + success = (boolean) mh.invokeExact(1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); @@ -431,9 +442,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0f, 1.0f); + success = (boolean) mh.invokeExact(2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); @@ -441,16 +454,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0f, 3.0f); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact(2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0f, 2.0f); + success = (boolean) mh.invokeExact(1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); @@ -465,9 +481,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0f, 1.0f); + success = (boolean) mh.invokeExact(2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); @@ -645,9 +663,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0f, 2.0f); + success = (boolean) mh.invokeExact(array, i, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -662,9 +682,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0f, 1.0f); + success = (boolean) mh.invokeExact(array, i, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -679,9 +701,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1.0f, 2.0f); + success = (boolean) mh.invokeExact(array, i, 1.0f, 2.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -696,9 +720,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0f, 1.0f); + success = (boolean) mh.invokeExact(array, i, 2.0f, 1.0f); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x01234567, 0x89ABCDEF); + success = (boolean) mh.invokeExact(recv, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0x89ABCDEF, 0x01234567); + success = (boolean) mh.invokeExact(recv, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x01234567, 0x89ABCDEF); + success = (boolean) mh.invokeExact(recv, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0x89ABCDEF, 0x01234567); + success = (boolean) mh.invokeExact(recv, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -492,9 +501,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x01234567, 0x89ABCDEF); + success = (boolean) mh.invokeExact(0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); @@ -509,9 +520,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0x89ABCDEF, 0x01234567); + success = (boolean) mh.invokeExact(0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); @@ -519,16 +532,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0x89ABCDEF, 0xCAFEBABE); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact(0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x01234567, 0x89ABCDEF); + success = (boolean) mh.invokeExact(0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); @@ -543,9 +559,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0x89ABCDEF, 0x01234567); + success = (boolean) mh.invokeExact(0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); @@ -801,9 +819,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x01234567, 0x89ABCDEF); + success = (boolean) mh.invokeExact(array, i, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -818,9 +838,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x89ABCDEF, 0x01234567); + success = (boolean) mh.invokeExact(array, i, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -835,9 +857,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 0x01234567, 0x89ABCDEF); + success = (boolean) mh.invokeExact(array, i, 0x01234567, 0x89ABCDEF); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -852,9 +876,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0x89ABCDEF, 0x01234567); + success = (boolean) mh.invokeExact(array, i, 0x89ABCDEF, 0x01234567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + success = (boolean) mh.invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + success = (boolean) mh.invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + success = (boolean) mh.invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + success = (boolean) mh.invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -492,9 +501,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + success = (boolean) mh.invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); @@ -509,9 +520,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + success = (boolean) mh.invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); @@ -519,16 +532,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + success = (boolean) mh.invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); @@ -543,9 +559,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + success = (boolean) mh.invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); @@ -801,9 +819,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + success = (boolean) mh.invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -818,9 +838,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + success = (boolean) mh.invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -835,9 +857,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + success = (boolean) mh.invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -852,9 +876,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + success = (boolean) mh.invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (short)0x0123, (short)0x4567); + success = (boolean) mh.invokeExact(recv, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (short)0x4567, (short)0x0123); + success = (boolean) mh.invokeExact(recv, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (short)0x0123, (short)0x4567); + success = (boolean) mh.invokeExact(recv, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (short)0x4567, (short)0x0123); + success = (boolean) mh.invokeExact(recv, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -492,9 +501,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((short)0x0123, (short)0x4567); + success = (boolean) mh.invokeExact((short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); @@ -509,9 +520,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((short)0x4567, (short)0x0123); + success = (boolean) mh.invokeExact((short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); @@ -519,16 +532,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((short)0x4567, (short)0x89AB); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact((short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((short)0x0123, (short)0x4567); + success = (boolean) mh.invokeExact((short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); @@ -543,9 +559,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((short)0x4567, (short)0x0123); + success = (boolean) mh.invokeExact((short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); @@ -801,9 +819,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (short)0x0123, (short)0x4567); + success = (boolean) mh.invokeExact(array, i, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -818,9 +838,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (short)0x4567, (short)0x0123); + success = (boolean) mh.invokeExact(array, i, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -835,9 +857,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, (short)0x0123, (short)0x4567); + success = (boolean) mh.invokeExact(array, i, (short)0x0123, (short)0x4567); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -852,9 +876,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (short)0x4567, (short)0x0123); + success = (boolean) mh.invokeExact(array, i, (short)0x4567, (short)0x0123); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -208,9 +209,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "bar"); + success = (boolean) mh.invokeExact(recv, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -225,9 +228,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "foo"); + success = (boolean) mh.invokeExact(recv, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -242,9 +247,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "bar"); + success = (boolean) mh.invokeExact(recv, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -260,8 +267,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "foo"); + success = (boolean) mh.invokeExact(recv, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -392,9 +401,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "bar"); + success = (boolean) mh.invokeExact("foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); @@ -409,9 +420,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "foo"); + success = (boolean) mh.invokeExact("bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); @@ -419,16 +432,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "baz"); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact("bar", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar"); + success = (boolean) mh.invokeExact("foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); @@ -443,9 +459,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "foo"); + success = (boolean) mh.invokeExact("bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); @@ -601,9 +619,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "bar"); + success = (boolean) mh.invokeExact(array, i, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -618,9 +638,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "foo"); + success = (boolean) mh.invokeExact(array, i, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -635,9 +657,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, "foo", "bar"); + success = (boolean) mh.invokeExact(array, i, "foo", "bar"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -652,9 +676,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "foo"); + success = (boolean) mh.invokeExact(array, i, "bar", "foo"); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -725,6 +725,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(recv); @@ -742,6 +743,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(recv); @@ -759,6 +761,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(recv); @@ -776,6 +779,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(recv); @@ -1130,6 +1134,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain($value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(); @@ -1147,6 +1152,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire($value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(); @@ -1164,6 +1170,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease($value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(); @@ -1181,6 +1188,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet($value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(); @@ -1538,6 +1546,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1555,6 +1564,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1572,6 +1582,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1589,6 +1600,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -1626,6 +1626,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1643,6 +1644,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1660,6 +1662,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1677,6 +1680,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1943,6 +1947,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1960,6 +1965,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1977,6 +1983,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); @@ -1994,6 +2001,7 @@ boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template 2023-07-05 07:11:54.000000000 +0000 @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; @@ -209,9 +210,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, $value1$, $value2$); + success = (boolean) mh.invokeExact(recv, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -226,9 +229,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value1$); + success = (boolean) mh.invokeExact(recv, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -243,9 +248,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value2$); + success = (boolean) mh.invokeExact(recv, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -261,8 +268,10 @@ { boolean success = false; + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value2$, $value1$); + success = (boolean) mh.invokeExact(recv, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); @@ -532,9 +541,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact($value1$, $value2$); + success = (boolean) mh.invokeExact($value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); @@ -549,9 +560,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact($value2$, $value1$); + success = (boolean) mh.invokeExact($value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); @@ -559,16 +572,19 @@ } { - boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact($value2$, $value3$); + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); + boolean success = (boolean) mh.invokeExact($value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value2$); + success = (boolean) mh.invokeExact($value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); @@ -583,9 +599,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value2$, $value1$); + success = (boolean) mh.invokeExact($value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); @@ -880,9 +898,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, $value1$, $value2$); + success = (boolean) mh.invokeExact(array, i, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -897,9 +917,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value1$); + success = (boolean) mh.invokeExact(array, i, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -914,9 +936,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, $value1$, $value2$); + success = (boolean) mh.invokeExact(array, i, $value1$, $value2$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); @@ -931,9 +955,11 @@ } { + MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); boolean success = false; for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { - success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value2$, $value1$); + success = (boolean) mh.invokeExact(array, i, $value2$, $value1$); + if (!success) weakDelay(); } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/module/ClassFileVersionsTest.java openjdk-17-17.0.8+7/test/jdk/java/lang/module/ClassFileVersionsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/module/ClassFileVersionsTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/module/ClassFileVersionsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -43,69 +43,65 @@ import static org.testng.Assert.*; public class ClassFileVersionsTest { + private static final int FEATURE; + static { + FEATURE = Runtime.version().feature(); + assert FEATURE >= 10; + } // major, minor, modifiers for requires java.base @DataProvider(name = "supported") public Object[][] supported() { - return new Object[][]{ - { 53, 0, Set.of() }, // JDK 9 - { 53, 0, Set.of(STATIC) }, - { 53, 0, Set.of(TRANSITIVE) }, - { 53, 0, Set.of(STATIC, TRANSITIVE) }, - - { 54, 0, Set.of() }, // JDK 10 - { 55, 0, Set.of() }, // JDK 11 - { 56, 0, Set.of() }, // JDK 12 - { 57, 0, Set.of() }, // JDK 13 - { 58, 0, Set.of() }, // JDK 14 - { 59, 0, Set.of() }, // JDK 15 - { 60, 0, Set.of() }, // JDK 16 - { 61, 0, Set.of() }, // JDK 17 - }; + /* + * There are four test cases for JDK 9 and then one test case + * for each subsequent JDK version from JDK 10 to the current + * feature release for a total of (4 + (FEATURE - 9) ) => + * (feature - 5) rows. + */ + Object[][] result = new Object[(FEATURE - 5)][]; + + // Class file version of JDK 9 is 53.0 + result[0] = new Object[]{ 53, 0, Set.of()}; + result[1] = new Object[]{ 53, 0, Set.of(STATIC) }; + result[2] = new Object[]{ 53, 0, Set.of(TRANSITIVE) }; + result[3] = new Object[]{ 53, 0, Set.of(STATIC, TRANSITIVE) }; + + // Major class file version of JDK N is 44 + n. Create rows + // for JDK 10 through FEATURE. + for (int i = 4; i < (FEATURE - 5) ; i++) { + result[i] = new Object[]{i + 50, 0, Set.of()}; + } + + return result; } // major, minor, modifiers for requires java.base @DataProvider(name = "unsupported") public Object[][] unsupported() { - return new Object[][]{ - { 50, 0, Set.of()}, // JDK 6 - { 51, 0, Set.of()}, // JDK 7 - { 52, 0, Set.of()}, // JDK 8 - - { 54, 0, Set.of(STATIC) }, // JDK 10 - { 54, 0, Set.of(TRANSITIVE) }, - { 54, 0, Set.of(STATIC, TRANSITIVE) }, - - { 55, 0, Set.of(STATIC) }, // JDK 11 - { 55, 0, Set.of(TRANSITIVE) }, - { 55, 0, Set.of(STATIC, TRANSITIVE) }, - - { 56, 0, Set.of(STATIC) }, // JDK 12 - { 56, 0, Set.of(TRANSITIVE) }, - { 56, 0, Set.of(STATIC, TRANSITIVE) }, - - { 57, 0, Set.of(STATIC) }, // JDK 13 - { 57, 0, Set.of(TRANSITIVE) }, - { 57, 0, Set.of(STATIC, TRANSITIVE) }, - - { 58, 0, Set.of(STATIC) }, // JDK 14 - { 58, 0, Set.of(TRANSITIVE) }, - { 58, 0, Set.of(STATIC, TRANSITIVE) }, - - { 59, 0, Set.of(STATIC) }, // JDK 15 - { 59, 0, Set.of(TRANSITIVE) }, - { 59, 0, Set.of(STATIC, TRANSITIVE) }, - - { 60, 0, Set.of(STATIC) }, // JDK 16 - { 60, 0, Set.of(TRANSITIVE) }, - { 60, 0, Set.of(STATIC, TRANSITIVE) }, - - { 61, 0, Set.of(STATIC) }, // JDK 17 - { 61, 0, Set.of(TRANSITIVE) }, - { 61, 0, Set.of(STATIC, TRANSITIVE) }, + /* + * There are three test cases for releases prior to JDK 9, + * three test cases for each JDK version from JDK 10 to the + * current feature release, plus one addition test case for + * the next release for a total of (3 + (FEATURE - 9) * 3 + 1) + * rows. + */ + int unsupportedCount = 3 + (FEATURE - 9)*3 + 1; + Object[][] result = new Object[unsupportedCount][]; + + result[0] = new Object[]{50, 0, Set.of()}; // JDK 6 + result[1] = new Object[]{51, 0, Set.of()}; // JDK 7 + result[2] = new Object[]{52, 0, Set.of()}; // JDK 8 + + for (int i = 10; i <= FEATURE ; i++) { + int base = 3 + (i-10)*3; + // Major class file version of JDK N is 44+n + result[base] = new Object[]{i + 44, 0, Set.of(STATIC)}; + result[base + 1] = new Object[]{i + 44, 0, Set.of(TRANSITIVE)}; + result[base + 2] = new Object[]{i + 44, 0, Set.of(STATIC, TRANSITIVE)}; + } - { 62, 0, Set.of()}, // JDK 18 - }; + result[unsupportedCount - 1] = new Object[]{FEATURE+1+44, 0, Set.of()}; + return result; } @Test(dataProvider = "supported") diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/ProcessBuilder/Basic.java openjdk-17-17.0.8+7/test/jdk/java/lang/ProcessBuilder/Basic.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/ProcessBuilder/Basic.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/ProcessBuilder/Basic.java 2023-07-05 07:11:54.000000000 +0000 @@ -487,15 +487,15 @@ equal(run(pb).exitValue(), False.exitValue()); // Traditional shell scripts without #! - setFileContents(prog, "exec /bin/true\n"); - prog.setExecutable(true); - equal(run(pb).exitValue(), - True.exitValue()); - prog.delete(); - setFileContents(prog, "exec /bin/false\n"); - prog.setExecutable(true); - equal(run(pb).exitValue(), - False.exitValue()); + if (!(Platform.isLinux() && Platform.isMusl())) { + setFileContents(prog, "exec /bin/true\n"); + prog.setExecutable(true); + equal(run(pb).exitValue(), True.exitValue()); + prog.delete(); + setFileContents(prog, "exec /bin/false\n"); + prog.setExecutable(true); + equal(run(pb).exitValue(), False.exitValue()); + } prog.delete(); } @@ -512,14 +512,16 @@ pb.command(cmd); // Test traditional shell scripts without #! - setFileContents(dir1Prog, "/bin/echo \"$@\"\n"); - pb.command(new String[] {"prog", "hello", "world"}); - checkPermissionDenied(pb); - dir1Prog.setExecutable(true); - equal(run(pb).out(), "hello world\n"); - equal(run(pb).exitValue(), True.exitValue()); - dir1Prog.delete(); - pb.command(cmd); + if (!(Platform.isLinux() && Platform.isMusl())) { + setFileContents(dir1Prog, "/bin/echo \"$@\"\n"); + pb.command(new String[] {"prog", "hello", "world"}); + checkPermissionDenied(pb); + dir1Prog.setExecutable(true); + equal(run(pb).out(), "hello world\n"); + equal(run(pb).exitValue(), True.exitValue()); + dir1Prog.delete(); + pb.command(cmd); + } // If prog found on both parent and child's PATH, // parent's is used. diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/lang/String/NoReplTest.java openjdk-17-17.0.8+7/test/jdk/java/lang/String/NoReplTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/lang/String/NoReplTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/lang/String/NoReplTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 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 8286287 8288589 + * @summary Tests for *NoRepl() shared secret methods. + * @run testng NoReplTest + * @modules jdk.charsets + */ + +import java.io.IOException; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.HexFormat; +import static java.nio.charset.StandardCharsets.UTF_16; + +import org.testng.annotations.Test; + +@Test +public class NoReplTest { + private final static byte[] MALFORMED_UTF16 = {(byte)0x00, (byte)0x20, (byte)0x00}; + private final static String MALFORMED_WINDOWS_1252 = "\u0080\u041e"; + private final static Charset WINDOWS_1252 = Charset.forName("windows-1252"); + + /** + * Verifies newStringNoRepl() throws a CharacterCodingException. + * The method is invoked by `Files.readString()` method. + */ + @Test + public void newStringNoReplTest() throws IOException { + var f = Files.createTempFile(null, null); + try (var fos = Files.newOutputStream(f)) { + fos.write(MALFORMED_UTF16); + var read = Files.readString(f, UTF_16); + throw new RuntimeException("Exception should be thrown for a malformed input. Bytes read: " + + HexFormat.of() + .withPrefix("x") + .withUpperCase() + .formatHex(read.getBytes(UTF_16))); + } catch (CharacterCodingException cce) { + // success + } finally { + Files.delete(f); + } + } + + /** + * Verifies getBytesNoRepl() throws a CharacterCodingException. + * The method is invoked by `Files.writeString()` method. + */ + @Test + public void getBytesNoReplTest() throws IOException { + var f = Files.createTempFile(null, null); + try { + Files.writeString(f, MALFORMED_WINDOWS_1252, WINDOWS_1252); + throw new RuntimeException("Exception should be thrown"); + } catch (CharacterCodingException cce) { + // success + } finally { + Files.delete(f); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/net/httpclient/AsFileDownloadTest.java openjdk-17-17.0.8+7/test/jdk/java/net/httpclient/AsFileDownloadTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/net/httpclient/AsFileDownloadTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/net/httpclient/AsFileDownloadTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -24,7 +24,7 @@ /* * @test * @summary Basic test for ofFileDownload - * @bug 8196965 + * @bug 8196965 8302475 * @modules java.base/sun.net.www.http * java.net.http/jdk.internal.net.http.common * java.net.http/jdk.internal.net.http.frame @@ -127,18 +127,18 @@ { "024", "attachment; filename=me.txt; filename*=utf-8''you.txt", "me.txt" }, { "025", "attachment; filename=\"m y.txt\"; filename*=utf-8''you.txt", "m y.txt" }, - { "030", "attachment; filename=foo/file1.txt", "file1.txt" }, - { "031", "attachment; filename=foo/bar/file2.txt", "file2.txt" }, - { "032", "attachment; filename=baz\\file3.txt", "file3.txt" }, - { "033", "attachment; filename=baz\\bar\\file4.txt", "file4.txt" }, - { "034", "attachment; filename=x/y\\file5.txt", "file5.txt" }, - { "035", "attachment; filename=x/y\\file6.txt", "file6.txt" }, - { "036", "attachment; filename=x/y\\z/file7.txt", "file7.txt" }, - { "037", "attachment; filename=x/y\\z/\\x/file8.txt", "file8.txt" }, - { "038", "attachment; filename=/root/file9.txt", "file9.txt" }, - { "039", "attachment; filename=../file10.txt", "file10.txt" }, - { "040", "attachment; filename=..\\file11.txt", "file11.txt" }, - { "041", "attachment; filename=foo/../../file12.txt", "file12.txt" }, + { "030", "attachment; filename=\"foo/file1.txt\"", "file1.txt" }, + { "031", "attachment; filename=\"foo/bar/file2.txt\"", "file2.txt" }, + { "032", "attachment; filename=\"baz\\\\file3.txt\"", "file3.txt" }, + { "033", "attachment; filename=\"baz\\\\bar\\\\file4.txt\"", "file4.txt" }, + { "034", "attachment; filename=\"x/y\\\\file5.txt\"", "file5.txt" }, + { "035", "attachment; filename=\"x/y\\\\file6.txt\"", "file6.txt" }, + { "036", "attachment; filename=\"x/y\\\\z/file7.txt\"", "file7.txt" }, + { "037", "attachment; filename=\"x/y\\\\z/\\\\x/file8.txt\"", "file8.txt" }, + { "038", "attachment; filename=\"/root/file9.txt\"", "file9.txt" }, + { "039", "attachment; filename=\"../file10.txt\"", "file10.txt" }, + { "040", "attachment; filename=\"..\\\\file11.txt\"", "file11.txt" }, + { "041", "attachment; filename=\"foo/../../file12.txt\"", "file12.txt" }, }; @DataProvider(name = "positive") @@ -177,18 +177,24 @@ CREATE, TRUNCATE_EXISTING, WRITE); HttpResponse response = client.send(request, bh); + Path body = response.body(); out.println("Got response: " + response); - out.println("Got body Path: " + response.body()); + out.println("Got body Path: " + body); String fileContents = new String(Files.readAllBytes(response.body()), UTF_8); out.println("Got body: " + fileContents); assertEquals(response.statusCode(),200); - assertEquals(response.body().getFileName().toString(), expectedFilename); + assertEquals(body.getFileName().toString(), expectedFilename); assertTrue(response.headers().firstValue("Content-Disposition").isPresent()); assertEquals(response.headers().firstValue("Content-Disposition").get(), contentDispositionValue); assertEquals(fileContents, "May the luck of the Irish be with you!"); + if (!body.toAbsolutePath().startsWith(tempDir.toAbsolutePath())) { + System.out.println("Tempdir = " + tempDir.toAbsolutePath()); + System.out.println("body = " + body.toAbsolutePath()); + throw new AssertionError("body in wrong location"); + } // additional checks unrelated to file download caseInsensitivityOfHeaders(request.headers()); caseInsensitivityOfHeaders(response.headers()); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/nio/charset/Charset/RegisteredCharsets.java openjdk-17-17.0.8+7/test/jdk/java/nio/charset/Charset/RegisteredCharsets.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/nio/charset/Charset/RegisteredCharsets.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/nio/charset/Charset/RegisteredCharsets.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,11 @@ /* @test * @bug 4473201 4696726 4652234 4482298 4784385 4966197 4267354 5015668 - 6911753 8071447 8186751 8242541 + 6911753 8071447 8186751 8242541 8301119 * @summary Check that registered charsets are actually registered * @modules jdk.charsets + * @run main RegisteredCharsets + * @run main/othervm -Djdk.charset.GB18030=2000 RegisteredCharsets */ import java.io.*; @@ -254,8 +256,12 @@ }); aliasCheck("GB18030", + "2000".equals(System.getProperty("jdk.charset.GB18030")) ? new String[] { "gb18030-2000" + } : + new String[] { + "gb18030-2022" }); aliasCheck("ISO-2022-KR", new String[] {"csISO2022KR"}); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/nio/file/Files/ReadWriteString.java openjdk-17-17.0.8+7/test/jdk/java/nio/file/Files/ReadWriteString.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/nio/file/Files/ReadWriteString.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/nio/file/Files/ReadWriteString.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,10 +24,12 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.CharacterCodingException; import java.nio.charset.MalformedInputException; import java.nio.charset.UnmappableCharacterException; -import static java.nio.charset.StandardCharsets.US_ASCII; import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static java.nio.charset.StandardCharsets.UTF_16; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.file.Files; import java.nio.file.OpenOption; @@ -46,11 +48,12 @@ import org.testng.annotations.Test; /* @test - * @bug 8201276 8205058 8209576 + * @bug 8201276 8205058 8209576 8287541 8288589 * @build ReadWriteString PassThroughFileSystem * @run testng ReadWriteString * @summary Unit test for methods for Files readString and write methods. * @key randomness + * @modules jdk.charsets */ @Test(groups = "readwrite") public class ReadWriteString { @@ -59,11 +62,8 @@ final String TEXT_UNICODE = "\u201CHello\u201D"; final String TEXT_ASCII = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n abcdefghijklmnopqrstuvwxyz\n 1234567890\n"; private static final String JA_STRING = "\u65e5\u672c\u8a9e\u6587\u5b57\u5217"; - - // malformed input: a high surrogate without the low surrogate - static char[] illChars = { - '\u00fa', '\ud800' - }; + private static final Charset WINDOWS_1252 = Charset.forName("windows-1252"); + private static final Charset WINDOWS_31J = Charset.forName("windows-31j"); static byte[] data = getData(); @@ -92,12 +92,14 @@ */ @DataProvider(name = "malformedWrite") public Object[][] getMalformedWrite() throws IOException { - Path path = Files.createTempFile("malformedWrite", null); + Path path = Files.createFile(Path.of("malformedWrite")); return new Object[][]{ {path, "\ud800", null}, //the default Charset is UTF_8 {path, "\u00A0\u00A1", US_ASCII}, {path, "\ud800", UTF_8}, {path, JA_STRING, ISO_8859_1}, + {path, "\u041e", WINDOWS_1252}, // cyrillic capital letter O + {path, "\u091c", WINDOWS_31J}, // devanagari letter ja }; } @@ -107,7 +109,7 @@ */ @DataProvider(name = "illegalInput") public Object[][] getIllegalInput() throws IOException { - Path path = Files.createTempFile("illegalInput", null); + Path path = Files.createFile(Path.of("illegalInput")); return new Object[][]{ {path, data, ISO_8859_1, null}, {path, data, ISO_8859_1, UTF_8} @@ -115,11 +117,24 @@ } /* + * DataProvider for illegal input bytes test + */ + @DataProvider(name = "illegalInputBytes") + public Object[][] getIllegalInputBytes() throws IOException { + return new Object[][]{ + {new byte[] {(byte)0x00, (byte)0x20, (byte)0x00}, UTF_16, MalformedInputException.class}, + {new byte[] {-50}, UTF_16, MalformedInputException.class}, + {new byte[] {(byte)0x81}, WINDOWS_1252, UnmappableCharacterException.class}, // unused in Cp1252 + {new byte[] {(byte)0x81, (byte)0xff}, WINDOWS_31J, UnmappableCharacterException.class}, // invalid trailing byte + }; + } + + /* * DataProvider for writeString test * Writes the data using both the existing and new method and compares the results. */ @DataProvider(name = "testWriteString") - public Object[][] getWriteString() throws IOException { + public Object[][] getWriteString() { return new Object[][]{ {testFiles[1], testFiles[2], TEXT_ASCII, US_ASCII, null}, @@ -134,8 +149,7 @@ * Reads the file using both the existing and new method and compares the results. */ @DataProvider(name = "testReadString") - public Object[][] getReadString() throws IOException { - Path path = Files.createTempFile("readString_file1", null); + public Object[][] getReadString() { return new Object[][]{ {testFiles[1], TEXT_ASCII, US_ASCII, US_ASCII}, {testFiles[1], TEXT_ASCII, US_ASCII, UTF_8}, @@ -146,16 +160,9 @@ @BeforeClass void setup() throws IOException { - testFiles[0] = Files.createTempFile("readWriteString", null); - testFiles[1] = Files.createTempFile("writeString_file1", null); - testFiles[2] = Files.createTempFile("writeString_file2", null); - } - - @AfterClass - void cleanup() throws IOException { - for (Path path : testFiles) { - Files.deleteIfExists(path); - } + testFiles[0] = Files.createFile(Path.of("readWriteString")); + testFiles[1] = Files.createFile(Path.of("writeString_file1")); + testFiles[2] = Files.createFile(Path.of("writeString_file2")); } /** @@ -244,11 +251,10 @@ */ @Test(dataProvider = "malformedWrite", expectedExceptions = UnmappableCharacterException.class) public void testMalformedWrite(Path path, String s, Charset cs) throws IOException { - path.toFile().deleteOnExit(); if (cs == null) { - Files.writeString(path, s, CREATE); + Files.writeString(path, s); } else { - Files.writeString(path, s, cs, CREATE); + Files.writeString(path, s, cs); } } @@ -264,15 +270,38 @@ */ @Test(dataProvider = "illegalInput", expectedExceptions = MalformedInputException.class) public void testMalformedRead(Path path, byte[] data, Charset csWrite, Charset csRead) throws IOException { - path.toFile().deleteOnExit(); String temp = new String(data, csWrite); - Files.writeString(path, temp, csWrite, CREATE); - String s; + Files.writeString(path, temp, csWrite); if (csRead == null) { - s = Files.readString(path); + Files.readString(path); } else { - s = Files.readString(path, csRead); + Files.readString(path, csRead); + } + } + + /** + * Verifies that IOException is thrown when reading a file containing + * illegal bytes + * + * @param data the data used for the test + * @param csRead the Charset to use for reading the file + * @param expected exception class + * @throws IOException when the Charset used for reading the file is incorrect + */ + @Test(dataProvider = "illegalInputBytes") + public void testMalformedReadBytes(byte[] data, Charset csRead, Class expected) + throws IOException { + Path path = Path.of("illegalInputBytes"); + Files.write(path, data); + try { + Files.readString(path, csRead); + } catch (MalformedInputException | UnmappableCharacterException e) { + if (expected.isInstance(e)) { + // success + return; + } } + throw new RuntimeException("An instance of " + expected + " should be thrown"); } private void checkNullPointerException(Callable c) { diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java openjdk-17-17.0.8+7/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java 2023-07-05 07:11:54.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 @@ -60,6 +60,8 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.TimeUnit; + import sun.security.testlibrary.SimpleOCSPServer; import sun.security.testlibrary.SimpleOCSPServer; import sun.security.testlibrary.SimpleOCSPServer; @@ -114,11 +116,10 @@ SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD))); ocspResponder.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !ocspResponder.isServerReady()); i++) { - Thread.sleep(50); - } - if (!ocspResponder.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = + ocspResponder.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } int ocspPort = ocspResponder.getPort(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/security/KeyStore/CheckMacOSKeyChainTrust.java openjdk-17-17.0.8+7/test/jdk/java/security/KeyStore/CheckMacOSKeyChainTrust.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/security/KeyStore/CheckMacOSKeyChainTrust.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/security/KeyStore/CheckMacOSKeyChainTrust.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,119 @@ + +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * 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 java.security.KeyStore; +import java.util.HashSet; +import java.util.Set; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +/* + * @test + * @bug 8303465 + * @library /test/lib + * @requires os.family == "mac" + * @summary Check whether loading of certificates from MacOS Keychain correctly + * honors trust settings + */ +public class CheckMacOSKeyChainTrust { + private static Set trusted = new HashSet<>(); + private static Set distrusted = new HashSet<>(); + + public static void main(String[] args) throws Throwable { + loadUser(); + loadAdmin(); + System.out.println("Trusted Certs: " + trusted); + System.out.println("Distrusted Certs: " + distrusted); + KeyStore ks = KeyStore.getInstance("KEYCHAINSTORE"); + ks.load(null, null); + for (String alias : trusted) { + if (!ks.containsAlias(alias)) { + throw new RuntimeException("Not found: " + alias); + } + } + for (String alias : distrusted) { + if (ks.containsAlias(alias)) { + throw new RuntimeException("Found: " + alias); + } + } + } + + private static void loadUser() throws Throwable { + populate(ProcessTools.executeProcess("security", "dump-trust-settings")); + } + + private static void loadAdmin() throws Throwable { + populate(ProcessTools.executeProcess("security", "dump-trust-settings", "-d")); + } + + private static void populate(OutputAnalyzer output) throws Throwable { + if (output.getExitValue() != 0) { + return; // No Trust Settings were found + } + String certName = null; + boolean trustRootFound = false; + boolean trustAsRootFound = false; + boolean denyFound = false; + boolean unspecifiedFound = false; + for (String line : output.asLines()) { + if (line.startsWith("Cert ")) { + if (certName != null) { + if (!denyFound && + !(unspecifiedFound && !(trustRootFound || trustAsRootFound)) && + !distrusted.contains(certName)) { + trusted.add(certName); + } else { + distrusted.add(certName); + trusted.remove(certName); + } + } + certName = line.split(":", 2)[1].trim().toLowerCase(); + trustRootFound = false; + trustAsRootFound = false; + denyFound = false; + unspecifiedFound = false; + } else if (line.contains("kSecTrustSettingsResultTrustRoot")) { + trustRootFound = true; + } else if (line.contains("kSecTrustSettingsResultTrustAsRoot")) { + trustAsRootFound = true; + } else if (line.contains("kSecTrustSettingsResultDeny")) { + denyFound = true; + } else if (line.contains("kSecTrustSettingsResultUnspecified")) { + unspecifiedFound = true; + } + } + if (certName != null) { + if (!denyFound && + !(unspecifiedFound && !(trustRootFound || trustAsRootFound)) && + !distrusted.contains(certName)) { + trusted.add(certName); + } else { + distrusted.add(certName); + trusted.remove(certName); + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/security/testlibrary/SimpleOCSPServer.java openjdk-17-17.0.8+7/test/jdk/java/security/testlibrary/SimpleOCSPServer.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/security/testlibrary/SimpleOCSPServer.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/security/testlibrary/SimpleOCSPServer.java 2023-07-05 07:11:54.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 @@ -84,10 +84,11 @@ private boolean logEnabled = false; private ExecutorService threadPool; private volatile boolean started = false; - private volatile boolean serverReady = false; + private CountDownLatch serverReady = new CountDownLatch(1); private volatile boolean receivedShutdown = false; private volatile boolean acceptConnections = true; private volatile long delayMsec = 0; + private boolean omitContentLength = false; // Fields used in the generation of responses private long nextUpdateInterval = -1; @@ -216,14 +217,15 @@ listenPort), 128); log("Listening on " + servSocket.getLocalSocketAddress()); - // Singal ready - serverReady = true; - // Update the listenPort with the new port number. If // the server is restarted, it will bind to the same // port rather than picking a new one. listenPort = servSocket.getLocalPort(); + // Decrement the latch, allowing any waiting entities + // to proceed with their requests. + serverReady.countDown(); + // Main dispatch loop while (!receivedShutdown) { try { @@ -257,7 +259,7 @@ // Reset state variables so the server can be restarted receivedShutdown = false; started = false; - serverReady = false; + serverReady = new CountDownLatch(1); } } }); @@ -319,12 +321,13 @@ * @return the hexdump of the byte array */ private static String dumpHexBytes(byte[] data) { - return dumpHexBytes(data, 16, "\n", " "); + return dumpHexBytes(data, data.length, 16, "\n", " "); } /** * - * @param data the array of bytes to dump to stdout. + * @param data the array of bytes to dump to stdout + * @param dataLen the length of the data to be displayed * @param itemsPerLine the number of bytes to display per line * if the {@code lineDelim} character is blank then all bytes will be * printed on a single line. @@ -333,11 +336,11 @@ * * @return The hexdump of the byte array */ - private static String dumpHexBytes(byte[] data, int itemsPerLine, - String lineDelim, String itemDelim) { + private static String dumpHexBytes(byte[] data, int dataLen, + int itemsPerLine, String lineDelim, String itemDelim) { StringBuilder sb = new StringBuilder(); if (data != null) { - for (int i = 0; i < data.length; i++) { + for (int i = 0; i < dataLen; i++) { if (i % itemsPerLine == 0 && i != 0) { sb.append(lineDelim); } @@ -487,6 +490,7 @@ throws NoSuchAlgorithmException { if (!started) { sigAlgId = AlgorithmId.get(algName); + log("Signature algorithm set to " + sigAlgId.getName()); } } @@ -497,7 +501,7 @@ * server has not yet been bound to a port. */ public int getPort() { - if (serverReady) { + if (serverReady.getCount() == 0) { InetSocketAddress inetSock = (InetSocketAddress)servSocket.getLocalSocketAddress(); return inetSock.getPort(); @@ -507,12 +511,21 @@ } /** - * Use to check if OCSP server is ready to accept connection. + * Allow SimpleOCSPServer consumers to wait for the server to be in + * the ready state before sending requests. + * + * @param timeout the length of time to wait for the server to be ready + * @param unit the unit of time applied to the timeout parameter * - * @return true if server ready, false otherwise + * @return true if the server enters the ready state, false if the + * timeout period elapses while the caller is waiting for the server + * to become ready. + * + * @throws InterruptedException if the current thread is interrupted. */ - public boolean isServerReady() { - return serverReady; + public boolean awaitServerReady(long timeout, TimeUnit unit) + throws InterruptedException { + return serverReady.await(timeout, unit); } /** @@ -532,6 +545,21 @@ } /** + * Setting to control whether HTTP responses have the Content-Length + * field asserted or not. + * + * @param isDisabled true if the Content-Length field should not be + * asserted, false otherwise. + */ + public void setDisableContentLength(boolean isDisabled) { + if (!started) { + omitContentLength = isDisabled; + log("Response Content-Length field " + + (isDisabled ? "disabled" : "enabled")); + } + } + + /** * Log a message to stdout. * * @param message the message to log @@ -702,6 +730,10 @@ OutputStream out = ocspSocket.getOutputStream()) { peerSockAddr = (InetSocketAddress)ocspSocket.getRemoteSocketAddress(); + + // Read in the first line which will be the request line. + // This will be tokenized so we know if we are dealing with + // a GET or POST. String[] headerTokens = readLine(in).split(" "); LocalOcspRequest ocspReq = null; LocalOcspResponse ocspResp = null; @@ -710,12 +742,12 @@ if (headerTokens[0] != null) { log("Received incoming HTTP " + headerTokens[0] + " from " + peerSockAddr); - switch (headerTokens[0]) { + switch (headerTokens[0].toUpperCase()) { case "POST": ocspReq = parseHttpOcspPost(in); break; case "GET": - ocspReq = parseHttpOcspGet(headerTokens); + ocspReq = parseHttpOcspGet(headerTokens, in); break; default: respStat = ResponseStatus.MALFORMED_REQUEST; @@ -749,6 +781,9 @@ ocspResp = new LocalOcspResponse(respStat); } sendResponse(out, ocspResp); + out.flush(); + + log("Closing " + ocspSocket); } catch (IOException | CertificateException exc) { err(exc); } @@ -776,8 +811,11 @@ sb.append("HTTP/1.0 200 OK\r\n"); sb.append("Content-Type: application/ocsp-response\r\n"); - sb.append("Content-Length: ").append(respBytes.length); - sb.append("\r\n\r\n"); + if (!omitContentLength) { + sb.append("Content-Length: ").append(respBytes.length). + append("\r\n"); + } + sb.append("\r\n"); out.write(sb.toString().getBytes("UTF-8")); out.write(respBytes); @@ -843,6 +881,8 @@ * * @param headerTokens the individual String tokens from the first * line of the HTTP GET. + * @param inStream the input stream from the socket bound to this + * {@code OcspHandler}. * * @return the OCSP Request as a {@code LocalOcspRequest} * @@ -851,8 +891,26 @@ * @throws CertificateException if one or more of the certificates in * the OCSP request cannot be read/parsed. */ - private LocalOcspRequest parseHttpOcspGet(String[] headerTokens) - throws IOException, CertificateException { + private LocalOcspRequest parseHttpOcspGet(String[] headerTokens, + InputStream inStream) throws IOException, CertificateException { + // Before we process the remainder of the GET URL, we should drain + // the InputStream of any other header data. We (for now) won't + // use it, but will display the contents if logging is enabled. + boolean endOfHeader = false; + while (!endOfHeader) { + String[] lineTokens = readLine(inStream).split(":", 2); + // We expect to see a type and value pair delimited by a colon. + if (lineTokens[0].isEmpty()) { + endOfHeader = true; + } else if (lineTokens.length == 2) { + log(String.format("ReqHdr: %s: %s", lineTokens[0].trim(), + lineTokens[1].trim())); + } else { + // A colon wasn't found and token 0 should be the whole line + log("ReqHdr: " + lineTokens[0].trim()); + } + } + // We have already established headerTokens[0] to be "GET". // We should have the URL-encoded base64 representation of the // OCSP request in headerTokens[1]. We need to strip any leading @@ -1173,10 +1231,14 @@ sb.append("CertId, Algorithm = "); sb.append(cid.getHashAlgorithm()).append("\n"); sb.append("\tIssuer Name Hash: "); - sb.append(dumpHexBytes(cid.getIssuerNameHash(), 256, "", "")); + byte[] cidHashBuf = cid.getIssuerNameHash(); + sb.append(dumpHexBytes(cidHashBuf, cidHashBuf.length, + 256, "", "")); sb.append("\n"); sb.append("\tIssuer Key Hash: "); - sb.append(dumpHexBytes(cid.getIssuerKeyHash(), 256, "", "")); + cidHashBuf = cid.getIssuerKeyHash(); + sb.append(dumpHexBytes(cidHashBuf, cidHashBuf.length, + 256, "", "")); sb.append("\n"); sb.append("\tSerial Number: ").append(cid.getSerialNumber()); if (!extensions.isEmpty()) { @@ -1516,10 +1578,14 @@ sb.append("CertId, Algorithm = "); sb.append(certId.getHashAlgorithm()).append("\n"); sb.append("\tIssuer Name Hash: "); - sb.append(dumpHexBytes(certId.getIssuerNameHash(), 256, "", "")); + byte[] cidHashBuf = certId.getIssuerNameHash(); + sb.append(dumpHexBytes(cidHashBuf, cidHashBuf.length, + 256, "", "")); sb.append("\n"); sb.append("\tIssuer Key Hash: "); - sb.append(dumpHexBytes(certId.getIssuerKeyHash(), 256, "", "")); + cidHashBuf = certId.getIssuerKeyHash(); + sb.append(dumpHexBytes(cidHashBuf, cidHashBuf.length, + 256, "", "")); sb.append("\n"); sb.append("\tSerial Number: ").append(certId.getSerialNumber()); sb.append("\n"); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/time/test/java/time/format/TestUTCParse.java openjdk-17-17.0.8+7/test/jdk/java/time/test/java/time/format/TestUTCParse.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/time/test/java/time/format/TestUTCParse.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/time/test/java/time/format/TestUTCParse.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * 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 + * @modules jdk.localedata + * @bug 8303440 + * @summary Test parsing "UTC-XX:XX" text works correctly + */ +package test.java.time.format; + +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.TextStyle; +import java.time.temporal.TemporalQueries; +import java.util.Locale; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; + +public class TestUTCParse { + + static { + // Assuming CLDR's SHORT name for "America/Los_Angeles" + // produces "UTC\u212208:00" + System.setProperty("java.locale.providers", "CLDR"); + } + + @DataProvider + public Object[][] utcZoneIdStrings() { + return new Object[][] { + {"UTC"}, + {"UTC+01:30"}, + {"UTC-01:30"}, + }; + } + + @Test + public void testUTCShortNameRoundTrip() { + var fmt = DateTimeFormatter.ofPattern("z", Locale.FRANCE); + var zdt = ZonedDateTime.of(2023, 3, 3, 0, 0, 0, 0, ZoneId.of("America/Los_Angeles")); + var formatted = fmt.format(zdt); + assertEquals(formatted, "UTC\u221208:00"); + assertEquals(fmt.parse(formatted).query(TemporalQueries.zoneId()), zdt.getZone()); + } + + @Test(dataProvider = "utcZoneIdStrings") + public void testUTCOffsetRoundTrip(String zidString) { + var fmt = new DateTimeFormatterBuilder() + .appendZoneText(TextStyle.NARROW) + .toFormatter(); + var zid = ZoneId.of(zidString); + assertEquals(fmt.parse(zidString).query(TemporalQueries.zoneId()), zid); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java openjdk-17-17.0.8+7/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -49,7 +49,7 @@ /* * @test - * @bug 8081022 8151876 8166875 8189784 8206980 + * @bug 8081022 8151876 8166875 8189784 8206980 8278434 * @key randomness */ @@ -59,6 +59,11 @@ @Test public class TestZoneTextPrinterParser extends AbstractTestPrinterParser { + private static final Locale[] SAMPLE_LOCALES = { + Locale.US, Locale.UK, Locale.FRANCE, Locale.GERMANY, Locale.ITALY, Locale.forLanguageTag("es"), + Locale.forLanguageTag("pt-BR"), Locale.forLanguageTag("ru"), + Locale.CHINA, Locale.TAIWAN, Locale.JAPAN, Locale.KOREA, Locale.ROOT}; + protected static DateTimeFormatter getFormatter(Locale locale, TextStyle style) { return new DateTimeFormatterBuilder().appendZoneText(style) .toFormatter(locale) @@ -68,7 +73,6 @@ public void test_printText() { Random r = RandomFactory.getRandom(); int N = 8; - Locale[] locales = Locale.getAvailableLocales(); Set zids = ZoneRulesProvider.getAvailableZoneIds(); ZonedDateTime zdt = ZonedDateTime.now(); @@ -83,7 +87,7 @@ zdt = zdt.withZoneSameLocal(ZoneId.of(zid)); TimeZone tz = TimeZone.getTimeZone(zid); boolean isDST = tz.inDaylightTime(new Date(zdt.toInstant().toEpochMilli())); - for (Locale locale : locales) { + for (Locale locale : SAMPLE_LOCALES) { String longDisplayName = tz.getDisplayName(isDST, TimeZone.LONG, locale); String shortDisplayName = tz.getDisplayName(isDST, TimeZone.SHORT, locale); if ((longDisplayName.startsWith("GMT+") && shortDisplayName.startsWith("GMT+")) @@ -116,9 +120,8 @@ } public void test_ParseText() { - Locale[] locales = new Locale[] { Locale.ENGLISH, Locale.JAPANESE, Locale.FRENCH }; Set zids = ZoneRulesProvider.getAvailableZoneIds(); - for (Locale locale : locales) { + for (Locale locale : SAMPLE_LOCALES) { parseText(zids, locale, TextStyle.FULL, false); parseText(zids, locale, TextStyle.FULL, true); parseText(zids, locale, TextStyle.SHORT, false); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/util/Currency/tablea1.txt openjdk-17-17.0.8+7/test/jdk/java/util/Currency/tablea1.txt --- openjdk-17-17.0.7+7~us1/test/jdk/java/util/Currency/tablea1.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/util/Currency/tablea1.txt 2023-07-05 07:11:54.000000000 +0000 @@ -1,12 +1,12 @@ # # -# Amendments up until ISO 4217 AMENDMENT NUMBER 174 -# (As of 2 November 2022) +# Amendments up until ISO 4217 AMENDMENT NUMBER 175 +# (As of 31 March 2023) # # Version FILEVERSION=3 -DATAVERSION=174 +DATAVERSION=175 # ISO 4217 currency data AF AFN 971 2 diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt --- openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt 2023-07-05 07:11:54.000000000 +0000 @@ -211,6 +211,7 @@ Link America/Tijuana America/Santa_Isabel Link America/Denver America/Shiprock Link America/Toronto America/Thunder_Bay +Link America/Edmonton America/Yellowknife Link Pacific/Auckland Antarctica/South_Pole Link Asia/Shanghai Asia/Chongqing Link Asia/Shanghai Asia/Harbin diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt --- openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt 2023-07-05 07:11:54.000000000 +0000 @@ -92,7 +92,6 @@ America/Whitehorse MST America/Winnipeg CST CDT America/Yakutat AKST AKDT -America/Yellowknife MST MDT Antarctica/Macquarie AEST AEDT Asia/Beirut EET EEST Asia/Famagusta EET EEST @@ -144,6 +143,7 @@ Europe/Gibraltar CET CEST Europe/Helsinki EET EEST Europe/Kaliningrad EET +Europe/Kirov MSK Europe/Kyiv EET EEST Europe/Lisbon WET WEST Europe/London GMT/BST GMT/BST @@ -160,6 +160,7 @@ Europe/Tirane CET CEST Europe/Vienna CET CEST Europe/Vilnius EET EEST +Europe/Volgograd MSK Europe/Warsaw CET CEST Europe/Zurich CET CEST HST HST diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneData/VERSION openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneData/VERSION --- openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneData/VERSION 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneData/VERSION 2023-07-05 07:11:54.000000000 +0000 @@ -1 +1 @@ -tzdata2022g +tzdata2023c diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneTest.java openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/util/TimeZone/TimeZoneTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/util/TimeZone/TimeZoneTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885 7039469 7126465 7158483 * 8008577 8077685 8098547 8133321 8138716 8148446 8151876 8159684 8166875 8181157 - * 8228469 8274407 + * 8228469 8274407 8305113 * @modules java.base/sun.util.resources * @library /java/text/testlib * @summary test TimeZone @@ -121,7 +121,7 @@ new ZoneDescriptor("GMT", 0, false), new ZoneDescriptor("UTC", 0, false), new ZoneDescriptor("ECT", 60, true), - new ZoneDescriptor("ART", 120, false), + new ZoneDescriptor("ART", 120, true), new ZoneDescriptor("EET", 120, true), new ZoneDescriptor("EAT", 180, false), new ZoneDescriptor("MET", 60, true), diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/util/zip/TestExtraTime.java openjdk-17-17.0.8+7/test/jdk/java/util/zip/TestExtraTime.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/util/zip/TestExtraTime.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/util/zip/TestExtraTime.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, 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 @@ -29,6 +29,8 @@ */ import java.io.*; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -59,7 +61,14 @@ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai"); - for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) { + // A structurally valid extra data example + byte[] sampleExtra = new byte[Short.BYTES*3]; + ByteBuffer.wrap(sampleExtra).order(ByteOrder.LITTLE_ENDIAN) + .putShort((short) 123) // ID: 123 + .putShort((short) Short.BYTES) // Size: 2 + .putShort((short) 42); // Data: Two bytes + + for (byte[] extra : new byte[][] { null, sampleExtra}) { // ms-dos 1980 epoch problem test0(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java openjdk-17-17.0.8+7/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java --- openjdk-17-17.0.7+7~us1/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,13 +114,13 @@ err.println("corrupted CENEXT 1"); bad = good.clone(); bad[cenpos+CENEXT]++; - checkZipException(bad, ".*bad header size.*"); + checkZipException(bad, ".*invalid zip64 extra data field size.*"); err.println("corrupted CENEXT 2"); bad = good.clone(); bad[cenpos+CENEXT] = (byte)0xfd; bad[cenpos+CENEXT+1] = (byte)0xfd; - checkZipException(bad, ".*bad header size.*"); + checkZipException(bad, ".*extra data field size too long.*"); err.println("corrupted CENCOM"); bad = good.clone(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/imageio/plugins/bmp/BMP1bppImageWithPaletteTest.java openjdk-17-17.0.8+7/test/jdk/javax/imageio/plugins/bmp/BMP1bppImageWithPaletteTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/imageio/plugins/bmp/BMP1bppImageWithPaletteTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/imageio/plugins/bmp/BMP1bppImageWithPaletteTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * 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 8302151 + * @summary Tests that we should not try to calculate bitmap image + size using bitmap file size when we have a color palette + */ + +import java.io.ByteArrayInputStream; +import java.io.EOFException; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class BMP1bppImageWithPaletteTest { + + public static void main(String[] args) throws IOException { + // incomplete 1bpp BMP byte stream with color palette and + // invalid file size data + byte[] corruptedBmp = { (byte) 0x42, (byte) 0x4d, (byte) 0x0e, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x3e, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x28, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0xa2, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xb4, + (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0xe0, (byte) 0x57, (byte) 0x07, (byte) 0x00, + (byte) 0xc2, (byte) 0x1e, (byte) 0x00, (byte) 0x00, (byte) 0xc2, + (byte) 0x1e, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff + }; + + // We expect EOFException to be thrown + try { + ImageIO.read(new ByteArrayInputStream(corruptedBmp)); + } catch(Exception ex) { + if (!(ex instanceof EOFException)) + throw ex; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java 2023-07-05 07:11:54.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 @@ -562,11 +562,9 @@ rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -615,11 +613,9 @@ intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java 2023-07-05 07:11:54.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 @@ -503,11 +503,9 @@ rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -556,11 +554,9 @@ intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -432,11 +432,9 @@ rootOcsp.acceptConnections(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Root OCSP responder not ready yet"); + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -493,13 +491,11 @@ intOcsp.acceptConnections(); rootOcsp.acceptConnections(); - // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + // Wait up to 5 seconds for each server + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -563,12 +559,10 @@ rootOcsp.acceptConnections(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -602,12 +596,10 @@ Thread.sleep(1000); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } System.out.println("========================================"); @@ -654,12 +646,10 @@ Thread.sleep(1000); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -959,11 +949,9 @@ rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -1012,11 +1000,9 @@ intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -696,11 +696,9 @@ rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -749,11 +747,9 @@ intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/AbstractButton/bug4143867.java openjdk-17-17.0.8+7/test/jdk/javax/swing/AbstractButton/bug4143867.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/AbstractButton/bug4143867.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/AbstractButton/bug4143867.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4143867 4237390 4383709 + @summary Tests set/getAction(.) and some constructors with Action argument + @key headful + @run main bug4143867 +*/ + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.DefaultButtonModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFrame; +import javax.swing.JToggleButton; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JRadioButton; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.SwingUtilities; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeListener; + +public class bug4143867 { + static final int TEST_MNEMONIC = KeyEvent.VK_1; + static JFrame fr; + + public static void main(String[] argv) throws Exception { + bug4143867 b = new bug4143867(); + SwingUtilities.invokeAndWait(() -> { + try { + b.doInitAndTest(); + } finally { + if (fr != null) { + fr.dispose(); + } + } + }); + } + + public void doInitAndTest() { + fr = new JFrame("bug4143867"); + JMenuBar mb = new JMenuBar(); + JMenu m = mb.add(new JMenu("Menu1")); + fr.setJMenuBar(mb); + JMenuItem it1 = m.add(new JMenuItem("Item1")); + fr.getContentPane().setLayout(new FlowLayout()); + JButton bt1 = new JButton("Button1"); + fr.getContentPane().add(bt1); + + final AbstractAction al = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + System.out.println("Pressed..."); + } + }; + al.putValue(Action.NAME, "Action"); + al.putValue(Action.MNEMONIC_KEY, new Integer(TEST_MNEMONIC)); + m.add(al); + m.getItem(0).setAction(al); + bt1.setAction(al); + JButton bt2 = new JButton(al); + fr.getContentPane().add(bt2); + if (it1.getAction() != al || m.getItem(1).getAction() != al || + bt1.getAction() != al || bt2.getAction() != al) { + throw new RuntimeException("Action was not set correctly."); + } + + if (bt1.getMnemonic() != TEST_MNEMONIC) { + throw new RuntimeException("Failed 4383709: JButton doesn't get mnemonic from Action"); + } + + class TestProtectedOfAbstractButton extends AbstractButton { + public void test() { + PropertyChangeListener pcl = createActionPropertyChangeListener(null); + setModel(new DefaultButtonModel()); + configurePropertiesFromAction(al); + } + } + TestProtectedOfAbstractButton tpAB = new TestProtectedOfAbstractButton(); + tpAB.test(); + + // Constructors presence test + JRadioButton ct1 = new JRadioButton(al); + JCheckBox ct2 = new JCheckBox(al); + JRadioButton ct3 = new JRadioButton(al); + JToggleButton ct4 = new JToggleButton(al); + JMenuItem ct5 = new JMenuItem(al); + JMenu ct6 = new JMenu(al); + JCheckBoxMenuItem ct7 = new JCheckBoxMenuItem(al); + JRadioButtonMenuItem ct8 = new JRadioButtonMenuItem(al); + if (ct1.getAction() != al) { + throw new RuntimeException("Constructor error in JRadioButton..."); + } + if (ct2.getAction() != al) { + throw new RuntimeException("Constructor error in JCheckBox..."); + } + if (ct3.getAction() != al) { + throw new RuntimeException("Constructor error in JRadioButton..."); + } + if (ct4.getAction() != al) { + throw new RuntimeException("Constructor error in JToggleButton..."); + } + if (ct5.getAction() != al) { + throw new RuntimeException("Constructor error in JMenuItem..."); + } + if (ct6.getAction() != al) { + throw new RuntimeException("Constructor error in JMenu..."); + } + if (ct7.getAction() != al) { + throw new RuntimeException("Constructor error in JCheckBoxMenuItem..."); + } + if (ct8.getAction() != al) { + throw new RuntimeException("Constructor error in JRadioButtonMenuItem..."); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/AbstractButton/bug4147740.java openjdk-17-17.0.8+7/test/jdk/javax/swing/AbstractButton/bug4147740.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/AbstractButton/bug4147740.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/AbstractButton/bug4147740.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4147740 + @summary Tests that AbstractButton does not update images it doesn't use + @key headful + @run main bug4147740 +*/ + +import java.awt.Image; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.ImageIcon; +import java.awt.Robot; +import javax.swing.SwingUtilities; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; + +public class bug4147740 { + + static JButton b; + static JFrame frame; + static volatile boolean imageUpdated = false; + static volatile boolean shouldUpdate = true; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4147740"); + b = new AnimatedButton(); + frame.getContentPane().add(b); + b.addHierarchyListener(new Listener()); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + static class Listener implements HierarchyListener { + public void hierarchyChanged(HierarchyEvent ev) { + if ((ev.getChangeFlags() | HierarchyEvent.SHOWING_CHANGED) != 0 && + frame.isShowing()) { + + frame.repaint(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + synchronized(b) { + b.setEnabled(false); + shouldUpdate = false; + } + } + }); + } + } + } + + static class AnimatedButton extends JButton { + boolean shouldNotUpdate = false; + + AnimatedButton() { + super(); + setIcon(new ImageIcon("animated.gif")); + setDisabledIcon(new ImageIcon("static.gif")); + } + + public boolean imageUpdate(Image img, int infoflags, + int x, int y, int w, int h) { + boolean updated; + synchronized(b) { + updated = super.imageUpdate(img, infoflags, x, y, w, h); + if (!shouldUpdate && updated) { + throw new RuntimeException("Failed: unused image is being updated"); + } + } + return updated; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/AbstractButton/bug4246045.java openjdk-17-17.0.8+7/test/jdk/javax/swing/AbstractButton/bug4246045.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/AbstractButton/bug4246045.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/AbstractButton/bug4246045.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4246045 + @summary AbstractButton fires accessible PropertyChangeEvent incorrectly + @key headful + @run main bug4246045 +*/ + +import java.awt.Container; +import java.awt.Robot; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.SwingUtilities; +import javax.accessibility.AccessibleContext; +import javax.accessibility.AccessibleState; + +public class bug4246045 { + + class Listener implements PropertyChangeListener { + boolean state = false; // focused or not + + public void propertyChange(PropertyChangeEvent e) { + if (e.getPropertyName().equals( + AccessibleContext.ACCESSIBLE_STATE_PROPERTY)) { + + boolean reported = false; + if (e.getNewValue() == null) { + reported = false; + } else if (e.getNewValue().equals(AccessibleState.FOCUSED)) { + reported = true; + } else { + throw new RuntimeException("Unknown value of ACCESSIBLE_STATE_PROPERTY"); + } + + if (!state == reported) { + state = reported; + } else { + throw new RuntimeException("Bad value of ACCESSIBLE_STATE_PROPERTY"); + } + } + } + } + + static JFrame frame; + static JButton btn; + static JToggleButton tb; + static JTextField dummy; + + public void init() { + btn = new JButton("JButton"); + tb = new JToggleButton("JToggleButton"); + dummy = new JTextField(); + Container pane = frame.getContentPane(); + pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS)); + pane.add(btn); + pane.add(tb); + pane.add(dummy); + + Listener bl = new Listener(); + btn.getAccessibleContext().addPropertyChangeListener(bl); + Listener tbl = new Listener(); + tb.getAccessibleContext().addPropertyChangeListener(tbl); + } + + public void start() { + btn.requestFocus(); + btn.transferFocus(); + tb.transferFocus(); + } + + public static void main(String[] argv) throws Exception { + Robot robot = new Robot(); + bug4246045 bug = new bug4246045(); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("4246045 Test"); + bug.init(); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + bug.start(); + }); + robot.waitForIdle(); + robot.delay(1000); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/border/LineBorder/ScaledTextFieldBorderTest.java openjdk-17-17.0.8+7/test/jdk/javax/swing/border/LineBorder/ScaledTextFieldBorderTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/border/LineBorder/ScaledTextFieldBorderTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/border/LineBorder/ScaledTextFieldBorderTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -246,6 +246,8 @@ childPanel.add(Box.createHorizontalStrut(4)); contentPanel.add(childPanel); + contentPanel.add(Box.createVerticalStrut(4)); + if (textFieldSize == null) { textFieldSize = textField.getPreferredSize(); borderColor = tfBorder.getLineColor().getRGB(); @@ -254,6 +256,7 @@ textField.setBounds(i, 0, textFieldSize.width, textFieldSize.height); childPanel.setBounds(0, (textFieldSize.height + 4) * i, textFieldSize.width + i + 4, textFieldSize.height); + panelLocations.add(childPanel.getLocation()); } contentPanel.setSize(textFieldSize.width + 4, @@ -261,11 +264,6 @@ panelColor = contentPanel.getBackground().getRGB(); - // Save coordinates of the panels - for (Component comp : contentPanel.getComponents()) { - panelLocations.add(comp.getLocation()); - } - return contentPanel; } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/border/TestTitledBorderLeak.java openjdk-17-17.0.8+7/test/jdk/javax/swing/border/TestTitledBorderLeak.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/border/TestTitledBorderLeak.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/border/TestTitledBorderLeak.java 2023-07-05 07:11:54.000000000 +0000 @@ -21,45 +21,32 @@ * questions. */ +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; + import javax.swing.border.TitledBorder; -/* +/** * @test * @bug 8204963 * @summary Verifies TitledBorder's memory leak - * @run main/othervm -Xmx10M TestTitledBorderLeak + * @library /javax/swing/regtesthelpers + * @build Util + * @run main/timeout=60/othervm -mx32m TestTitledBorderLeak */ -public class TestTitledBorderLeak { - public static void main(String[] args) throws Exception { - int max = 100000; - long initialFreeMemory = 0L; - long currentFreeMemory; - try { - for (int i = 1; i <= max; i++) { - new TitledBorder(""); - if ((i % 1000) == 0) { - System.gc(); - currentFreeMemory = dumpMemoryStatus("After " + i); - if(initialFreeMemory == 0L) { - initialFreeMemory = currentFreeMemory; - } else if( currentFreeMemory < initialFreeMemory/2) { - throw new RuntimeException("Memory halved: there's a leak"); - } +public final class TestTitledBorderLeak { - } - } - }catch(OutOfMemoryError e) { - // Don't think it would work; should not happen - System.gc(); - throw new RuntimeException("There was OOM"); + public static void main(String[] args) throws Exception { + Reference border = getTitleBorder(); + int attempt = 0; + while (border.get() != null) { + Util.generateOOME(); + System.out.println("Not freed, attempt: " + attempt++); } - System.out.println("Passed"); } - private static long dumpMemoryStatus(String msg) { - Runtime rt = Runtime.getRuntime(); - long freeMem = rt.freeMemory(); - System.out.println(msg + ": " + freeMem + " free"); - return freeMem; + + private static Reference getTitleBorder() { + TitledBorder tb = new TitledBorder(""); + return new WeakReference<>(tb); } } - diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JButton/8151303/PressedIconTest.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JButton/8151303/PressedIconTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JButton/8151303/PressedIconTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JButton/8151303/PressedIconTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -26,7 +26,9 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; +import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.event.InputEvent; import java.awt.image.BaseMultiResolutionImage; import java.awt.image.BufferedImage; @@ -56,37 +58,56 @@ private static volatile double scale = -1; private static volatile int centerX; private static volatile int centerY; + private static volatile Point location; + // move away from cursor + private final static int OFFSET_X = -20; + private final static int OFFSET_Y = -20; public static void main(String[] args) throws Exception { Robot robot = new Robot(); - robot.setAutoDelay(50); + robot.setAutoDelay(100); SwingUtilities.invokeAndWait(() -> createAndShowGUI()); robot.waitForIdle(); + robot.delay(1000); SwingUtilities.invokeAndWait(() -> { scale = frame.getGraphicsConfiguration().getDefaultTransform() .getScaleX(); - Point location = frame.getLocation(); + location = frame.getLocation(); Dimension size = frame.getSize(); centerX = location.x + size.width / 2; centerY = location.y + size.height / 2; }); robot.waitForIdle(); + System.out.println("scale " + scale); + robot.mouseMove(centerX, centerY); - robot.mousePress(InputEvent.BUTTON1_MASK); robot.waitForIdle(); - Thread.sleep(100); - Color color = robot.getPixelColor(centerX, centerY); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + Color color = robot.getPixelColor(centerX - OFFSET_X, centerY - OFFSET_Y); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight()); + BufferedImage img = robot.createScreenCapture(screen); + javax.imageio.ImageIO.write(img, "png", new java.io.File("image.png")); + + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SwingUtilities.invokeAndWait(() -> frame.dispose()); - if ((scale == 1 && !similar(color, COLOR_1X)) - || (scale == 2 && !similar(color, COLOR_2X))) { - throw new RuntimeException("Colors are different!"); + if (scale == 1 && !similar(color, COLOR_1X)) { + System.out.println("color " + color + " COLOR_1X " + COLOR_1X); + throw new RuntimeException("Colors is different for scale=1!"); + } + if (scale == 2 && !similar(color, COLOR_2X)) { + System.out.println("color " + color + " COLOR_2X " + COLOR_2X); + throw new RuntimeException("Colors is different for scale=2!"); } + System.out.println("Test Passed"); } private static void createAndShowGUI() { @@ -108,6 +129,8 @@ panel.add(button, BorderLayout.CENTER); frame.getContentPane().add(panel); + frame.setUndecorated(true); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4167850.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4167850.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4167850.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4167850.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4167850 + @summary Verify no exception removing items from an empty list. +*/ + +import javax.swing.JComboBox; + +public class bug4167850 { + + public static void main(String[] args) { + JComboBox comboBox = new JComboBox( + new Object[] { + "Coma Berenices", + "Triangulum", + "Camelopardis", + "Cassiopea"}); + + comboBox.removeAllItems(); + comboBox.removeAllItems(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4171464.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4171464.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4171464.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4171464.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4171464 + @summary JComboBox should not throw InternalError +*/ + +import javax.swing.ComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.event.ListDataListener; + +public class bug4171464 { + + public static void main(String args[]) { + ComboBoxModel model = new ComboBoxModel() { + public void setSelectedItem(Object anItem) {} + public Object getSelectedItem() {return null;} + public int getSize() {return 0;} + public Object getElementAt(int index) {return null;} + public void addListDataListener(ListDataListener l) {} + public void removeListDataListener(ListDataListener l) {} + }; + JComboBox comboBox = new JComboBox(); + comboBox.setModel(model); + try { + comboBox.addItem(new Object() {}); + } catch (InternalError e) { + // InternalError not suitable if app supplies non-mutable model. + throw new RuntimeException("4171464 TEST FAILED"); + } catch (Exception e) { + // Expected exception due to non-mutable model. + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4209474.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4209474.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4209474.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4209474.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4209474 + @summary setSelectedItem(int) should only fire events if selection changed - avoid recursive calls +*/ + +import javax.swing.JComboBox; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class bug4209474 { + + public static void main(String[] args) { + + JComboBox comboBox = new JComboBox( + new Object[] { + "Coma Berenices", + "Triangulum", + "Camelopardis", + "Cassiopea"}); + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + comboBox.setSelectedIndex(0); + } + }; + + comboBox.addActionListener(listener); + comboBox.setSelectedIndex(0); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4234119.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4234119.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4234119.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4234119.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4234119 + @summary Tests if adding items to ComboBox is slow +*/ + +import javax.swing.JComboBox; + +public class bug4234119 { + + public static void main(String args[]) { + JComboBox jComboBox1 = new JComboBox(); + long startTime = System.currentTimeMillis(); + for (int i = 0 ; i < 500; i++) { + jComboBox1.addItem(Integer.valueOf(i)); + } + long deltaTime = System.currentTimeMillis() - startTime; + if (deltaTime > 20000) { + throw new Error("Test failed: adding items to ComboBox is SLOW! (it took " + deltaTime + " ms"); + } + System.out.println("Elapsed time: " + deltaTime); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4244614.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4244614.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4244614.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4244614.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4244614 + @summary Tests that JComboBox has setAction(Action) constructor +*/ + +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; +import javax.swing.Action; +import javax.swing.JComboBox; + +public class bug4244614 { + +/** Auxiliary class implementing Action + */ + static class NullAction implements Action { + public void addPropertyChangeListener( + PropertyChangeListener listener) {} + public void removePropertyChangeListener( + PropertyChangeListener listener) {} + public void putValue(String key, Object value) {} + public void setEnabled(boolean b) {} + public void actionPerformed(ActionEvent e) {} + + public Object getValue(String key) { return null; } + public boolean isEnabled() { return false; } + } + + public static void main(String[] argv) { + Object[] comboData = {"First", "Second", "Third"}; + JComboBox combo = new JComboBox(comboData); + Action action = new NullAction(); + combo.setAction(action); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4276920.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4276920.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4276920.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4276920.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4276920 + @summary Tests that BasicComboPopup.hide() doesn't cause unnecessary repaints + @key headful +*/ + +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4276920 { + + static volatile TestComboBox combo; + static volatile JFrame frame; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(bug4276920::createUI); + Thread.sleep(2000); + int before = combo.getRepaintCount(); + SwingUtilities.invokeAndWait(combo::hidePopup); + int after = combo.getRepaintCount(); + if (after > before) { + throw new Error("Failed 4276920: BasicComboPopup.hide() caused unnecessary repaint()"); + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + } + + static void createUI() { + combo = new TestComboBox(new String[] {"Why am I so slow?"}); + frame = new JFrame("bug4276920"); + frame.getContentPane().add(combo); + frame.pack(); + frame.validate(); + frame.setVisible(true); + } + + static class TestComboBox extends JComboBox { + int count = 0; + + TestComboBox(Object[] content) { + super(content); + } + + public void repaint() { + super.repaint(); + count++; + } + + int getRepaintCount() { + return count; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4890345.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4890345.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4890345.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4890345.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4890345 + @requires (os.family == "windows") + @summary 1.4.2 REGRESSION: JComboBox has problem in JTable in Windows L&F + @key headful +*/ + +import java.util.Vector; +import java.awt.BorderLayout; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.DefaultCellEditor; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; + +public class bug4890345 { + + volatile boolean passed = false; + volatile boolean isLafOk = true; + + volatile JFrame mainFrame; + volatile JTable tbl; + + public static void main(String[] args) throws Exception { + bug4890345 test = new bug4890345(); + try { + SwingUtilities.invokeAndWait(test::createUI); + if (!test.isLafOk) { + throw new RuntimeException("Could not create Win L&F"); + } + test.test(); + } finally { + JFrame f = test.mainFrame; + if (f != null) { + SwingUtilities.invokeAndWait(() -> f.dispose()); + } + } + } + + void createUI() { + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (Exception ex) { + System.err.println("Can not initialize Windows L&F. Testing skipped."); + isLafOk = false; + } + + if (isLafOk) { + mainFrame = new JFrame("Bug4890345"); + String[] items = {"tt", "aa", "gg", "zz", "dd", "ll" }; + JComboBox comboBox = new JComboBox(items); + + tbl = new JTable(); + JScrollPane panel = new JScrollPane(tbl); + TableModel tm = createTableModel(); + tbl.setModel(tm); + tbl.setRowHeight(20); + tbl.getColumnModel().getColumn(1).setCellEditor( + new DefaultCellEditor(comboBox)); + + comboBox.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + passed = true; + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + public void popupMenuCanceled(PopupMenuEvent e) {} + }); + + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(panel, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + } + } + + public void test() throws Exception { + Robot robo = new Robot(); + robo.setAutoDelay(50); + robo.delay(1000); + tbl.editCellAt(0,0); + + robo.keyPress(KeyEvent.VK_TAB); + robo.keyRelease(KeyEvent.VK_TAB); + + robo.keyPress(KeyEvent.VK_TAB); + robo.keyRelease(KeyEvent.VK_TAB); + + robo.keyPress(KeyEvent.VK_F2); + robo.keyRelease(KeyEvent.VK_F2); + + robo.keyPress(KeyEvent.VK_DOWN); + robo.keyRelease(KeyEvent.VK_DOWN); + + robo.keyPress(KeyEvent.VK_ENTER); + robo.keyRelease(KeyEvent.VK_ENTER); + + robo.delay(1000); + + if (!passed) { + throw new RuntimeException("Popup was not shown after VK_DOWN press. Test failed."); + } + } + + private TableModel createTableModel() { + Vector hdr = new Vector(); + hdr.add("One"); + hdr.add("Two"); + Vector data = new Vector(); + Vector row = new Vector(); + row.add("tt"); + row.add("dd"); + data.add(row); + row = new Vector(); + row.add("ll"); + row.add("jj"); + data.add(row); + return new DefaultTableModel(data, hdr); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4924758.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4924758.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4924758.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4924758.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4924758 + @summary 1.4 REGRESSION: In Motif L&F JComboBox doesn't react when spacebar is pressed + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.PopupMenuListener; +import javax.swing.event.PopupMenuEvent; +import java.awt.event.KeyEvent; + +public class bug4924758 { + + static volatile boolean passed = false; + volatile boolean isLafOk = true; + + volatile JFrame mainFrame; + volatile JComboBox comboBox; + + public static void main(String[] args) throws Exception { + bug4924758 test = new bug4924758(); + try { + SwingUtilities.invokeAndWait(test::createUI); + if (!test.isLafOk) { + throw new RuntimeException("Could not create Win L&F"); + } + test.test(); + if (!passed) { + throw new RuntimeException( + "Popup was not closed after VK_SPACE press. Test failed."); + } + } finally { + JFrame f = test.mainFrame; + if (f != null) { + SwingUtilities.invokeAndWait(() -> f.dispose()); + } + } + } + + void createUI() { + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + } catch (Exception ex) { + System.err.println("Can not initialize Motif L&F. Testing skipped."); + isLafOk = false; + return; + } + + mainFrame = new JFrame("Bug4924758"); + String[] items = {"One", "Two", "Three"}; + comboBox = new JComboBox(items); + comboBox.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + passed = true; + } + + public void popupMenuCanceled(PopupMenuEvent e) {} + }); + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(comboBox, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + } + + void test() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(2000); + Point p = comboBox.getLocationOnScreen(); + Dimension size = comboBox.getSize(); + p.x += size.width / 2; + p.y += size.height / 2; + robot.mouseMove(p.x, p.y); + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + robot.delay(2000); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4996503.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4996503.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug4996503.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug4996503.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4996503 + @summary REGRESSION: NotSerializableException: javax.swing.plaf.basic.BasicComboPopup+1 + @key headful +*/ + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4996503 { + + static volatile JFrame frame = null; + static volatile JComboBox comboBox = null; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4996503"); + String[] items = { "item0", "item1", "item2" }; + comboBox = new JComboBox(items); + frame.add(comboBox); + frame.pack(); + frame.validate(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(1000); + Point p = comboBox.getLocationOnScreen(); + Dimension size = comboBox.getSize(); + p.x += size.width / 2; + p.y += size.height / 2; + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + + ObjectOutputStream out = null; + + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + try { + out = new ObjectOutputStream(byteStream); + } catch (IOException e) {} + if (out != null) { + try { + out.writeObject(comboBox); + } catch (Exception e) { + System.out.println(e); + throw new Error("Serialization exception. Test failed."); + } + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug5029504.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug5029504.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComboBox/bug5029504.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComboBox/bug5029504.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5029504 + @summary Empty JComboBox drop-down list is unexpectedly high + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicComboBoxUI; +import javax.swing.plaf.basic.BasicComboPopup; +import javax.swing.event.PopupMenuListener; +import javax.swing.event.PopupMenuEvent; + +public class bug5029504 { + + static volatile boolean passed = true; + static volatile JFrame mainFrame; + static volatile JComboBox comboBox; + static volatile BasicComboPopup ourPopup = null; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(bug5029504::createUI); + runTest(); + if (!passed) { + throw new RuntimeException( + "Popup of empty JComboBox is too high. Test failed."); + } + } finally { + if (mainFrame != null) { + SwingUtilities.invokeAndWait(mainFrame::dispose); + } + } + } + + static void createUI() { + mainFrame = new JFrame("Bug4924758"); + comboBox = new JComboBox(); + comboBox.setUI(new MyComboBoxUI()); + comboBox.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + if (ourPopup != null) { + int comboHeight = comboBox.getHeight(); + int popupHeight = ourPopup.getHeight(); + if (popupHeight > comboHeight*2) { + passed = false; + } + } + } + + public void popupMenuCanceled(PopupMenuEvent e) {} + }); + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(comboBox, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.validate(); + mainFrame.setVisible(true); + } + + static void runTest() throws Exception { + Robot robot = new Robot(); + robot.delay(2000); + Point p = comboBox.getLocationOnScreen(); + Dimension size = comboBox.getSize(); + p.x += size.width / 2; + p.y += size.height / 2; + robot.mouseMove(p.x, p.y); + robot.keyPress(KeyEvent.VK_ENTER); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.delay(2000); + } + + static class MyComboBoxUI extends BasicComboBoxUI { + public void setPopupVisible(JComboBox c, boolean v) { + if (popup instanceof BasicComboPopup) { + ourPopup = (BasicComboPopup) popup; + } + super.setPopupVisible(c, v); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComponent/bug4419219.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComponent/bug4419219.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComponent/bug4419219.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComponent/bug4419219.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4419219 + @summary Tests that registerKeyboardAction(null, ...) doen't throw NPE. + @key headful + @run main bug4419219 +*/ + +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.KeyStroke; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JTable; +import javax.swing.SwingUtilities; + +public class bug4419219 { + static volatile boolean passed = true; + static JFrame frame; + static Robot robo; + + public static void main(String[] args) throws Exception { + robo = new Robot(); + robo.setAutoWaitForIdle(true); + robo.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + try { + frame = new JFrame("bug4419219 Table"); + + final String[] names = {"col"}; + final Object[][] data = {{"A"}, {"B"}, {"C"}, {"D"}, {"E"}}; + + JTable tableView = (JTable)new TestTable(data, names); + // unregister ctrl-A + tableView.registerKeyboardAction(null, + KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK), + JComponent.WHEN_FOCUSED); + + frame.getContentPane().add(tableView); + frame.setSize(250,250); + frame.setLocationRelativeTo(null); + frame.addWindowListener(new TestStateListener()); + frame.setVisible(true); + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + if (!passed) { + throw new RuntimeException("Test failed."); + } + } + + static class TestStateListener extends WindowAdapter { + public void windowOpened(WindowEvent ev) { + robo.delay(1000); + robo.mouseMove(100,100); + robo.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robo.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robo.keyPress(KeyEvent.VK_CONTROL); + robo.keyPress(KeyEvent.VK_A); + robo.keyRelease(KeyEvent.VK_A); + robo.keyRelease(KeyEvent.VK_CONTROL); + } + } + + static class TestTable extends JTable { + + public TestTable(Object[][] data, String[] names) { + super(data, names); + } + + protected boolean processKeyBinding(KeyStroke ks, + KeyEvent e, + int condition, + boolean pressed) { + try { + return super.processKeyBinding(ks, e, condition, pressed); + } catch (NullPointerException ex) { + passed = false; + } + return false; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComponent/bug4962718.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JComponent/bug4962718.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JComponent/bug4962718.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JComponent/bug4962718.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4962718 + * @summary Propertychange Listener not fired by inheritPopupMenu and Popupmenu properties + * @key headful + * @run main bug4962718 +*/ + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class bug4962718 { + static volatile boolean popupWasSet = false; + static volatile boolean inheritWasSet = false; + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4962718"); + JButton button = new JButton("For test"); + JPopupMenu popup = new JPopupMenu(); + + button.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("inheritsPopupMenu")) { + inheritWasSet = true; + } else if( evt.getPropertyName(). + equals("componentPopupMenu")) { + popupWasSet = true; + } + } + }); + + frame.add(button); + button.setInheritsPopupMenu(true); + button.setInheritsPopupMenu(false); + button.setComponentPopupMenu(popup); + button.setComponentPopupMenu(null); + frame.pack(); + frame.setVisible(true); + }); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + + if (!inheritWasSet) { + throw new RuntimeException("Test failed, inheritsPopupMenu " + + " property change listener was not called"); + } + if (!popupWasSet) { + throw new RuntimeException("Test failed, componentPopupMenu " + + " property change listener was not called"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} + diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFileChooser/4847375/bug4847375.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JFileChooser/4847375/bug4847375.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFileChooser/4847375/bug4847375.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JFileChooser/4847375/bug4847375.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * 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,12 +23,14 @@ /* * @test - * @bug 4847375 8171363 + * @bug 4847375 8171363 8227257 * @requires (os.family == "windows") * @summary JFileChooser Create New Folder button is disabled incorrectly * @author Pavel Porvatov * @modules java.desktop/sun.awt * java.desktop/sun.awt.shell:+open + * @run main/othervm bug4847375 + * @run main/othervm -ea -esa bug4847375 */ import sun.awt.OSInfo; diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFileChooser/FileSystemView/InaccessibleLink.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JFileChooser/FileSystemView/InaccessibleLink.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFileChooser/FileSystemView/InaccessibleLink.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JFileChooser/FileSystemView/InaccessibleLink.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,76 @@ +/* + * 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.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; + +import javax.swing.filechooser.FileSystemView; + +/* + * @test + * @bug 8227257 + * @requires (os.family == "windows") + * @summary existing but inaccessible target for a link should be ignored + * @run main/othervm InaccessibleLink + * @run main/othervm -ea -esa InaccessibleLink + */ +public final class InaccessibleLink { + + /** + * The link to the windows-update settings. + */ + private static final byte[] bytes = { + 76, 0, 0, 0, 1, 20, 2, 0, 0, 0, 0, 0, -64, 0, 0, 0, 0, 0, 0, 70, + -127, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 20, 0, 31, 104, -128, 83, + 28, -121, -96, 66, 105, 16, -94, -22, 8, 0, 43, 48, 48, -99, 62, 0, + 97, -128, 0, 0, 0, 0, 109, 0, 115, 0, 45, 0, 115, 0, 101, 0, 116, 0, + 116, 0, 105, 0, 110, 0, 103, 0, 115, 0, 58, 0, 119, 0, 105, 0, 110, + 0, 100, 0, 111, 0, 119, 0, 115, 0, 117, 0, 112, 0, 100, 0, 97, 0, + 116, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + public static void main(String[] args) throws IOException { + File file = new File("inaccessible.lnk"); + try { + FileOutputStream fos = new FileOutputStream(file); + fos.write(bytes); + fos.close(); + + FileSystemView fsv = FileSystemView.getFileSystemView(); + if (!fsv.isLink(file)) { + throw new RuntimeException("not a link"); + } + File linkLocation = fsv.getLinkLocation(file); + if (linkLocation != null) { + throw new RuntimeException( + "location is not null: " + linkLocation); + } + } finally { + Files.deleteIfExists(file.toPath()); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFrame/bug4101444.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JFrame/bug4101444.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFrame/bug4101444.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JFrame/bug4101444.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JFrame; +import static javax.swing.SwingUtilities.invokeAndWait; + +/* + * @test + * @bug 4101444 + * @key headful + * @summary Tests JFrame supports EXIT_ON_CLOSE + */ + +public class bug4101444 { + private static JFrame jFrame; + + public static void main(String[] args) throws Exception { + try { + invokeAndWait(() -> { + jFrame = new JFrame("bug4101444 - Test EXIT_ON_CLOSE"); + jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + if (jFrame.getDefaultCloseOperation() != JFrame.EXIT_ON_CLOSE) { + throw new RuntimeException("EXIT_ON_CLOSE wasn't set" + + " correctly in setDefaultCloseOperation()..."); + } + }); + } finally { + invokeAndWait(() -> { + if (jFrame != null) { + jFrame.dispose(); + } + }); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFrame/bug4208018.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JFrame/bug4208018.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JFrame/bug4208018.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JFrame/bug4208018.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JFrame; +import javax.swing.JMenuBar; + +import static javax.swing.SwingUtilities.invokeAndWait; + +/* + * @test + * @bug 4208018 + * @key headful + * @summary Tests if calling JFrame.dispose() when menubar is set, cause Exception. + */ + +public class bug4208018 { + private static JFrame jFrame; + + public static void main(String[] args) throws Exception { + try { + invokeAndWait(() -> { + jFrame = new JFrame("bug4208018 - Test dispose"); + JMenuBar menubar = new JMenuBar(); + jFrame.setJMenuBar(menubar); + jFrame.dispose(); + }); + } catch (Exception e) { + throw new RuntimeException("Test failed!" + + " Calling dispose on JFrame caused exception", e); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java 2023-07-05 07:11:54.000000000 +0000 @@ -23,9 +23,12 @@ import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; import java.awt.event.InputEvent; import javax.swing.JDesktopPane; import javax.swing.JFrame; @@ -52,6 +55,10 @@ private static final Color DESKTOPPANE_COLOR = Color.YELLOW; private static final Color FRAME_COLOR = Color.ORANGE; + // move away from cursor + private final static int OFFSET_X = -20; + private final static int OFFSET_Y = -20; + private static JFrame frame; private static JInternalFrame internalFrame; @@ -66,7 +73,7 @@ SwingUtilities.invokeAndWait(bug8069348::createAndShowGUI); Robot robot = new Robot(); - robot.setAutoDelay(50); + robot.setAutoDelay(100); robot.waitForIdle(); Rectangle screenBounds = getInternalFrameScreenBounds(); @@ -79,27 +86,43 @@ robot.mouseMove(x, y); robot.waitForIdle(); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseMove(x + dx, y + dy); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); robot.waitForIdle(); int cx = screenBounds.x + screenBounds.width + dx / 2; int cy = screenBounds.y + screenBounds.height + dy / 2; robot.mouseMove(cx, cy); - if (!FRAME_COLOR.equals(robot.getPixelColor(cx, cy))) { + robot.waitForIdle(); + Color color = robot.getPixelColor(cx - OFFSET_X, cy - OFFSET_Y); + + if (!FRAME_COLOR.equals(color)) { + System.out.println("cx " + cx + " cy " + cy); + System.err.println("FRAME_COLOR Red: " + FRAME_COLOR.getRed() + "; Green: " + FRAME_COLOR.getGreen() + "; Blue: " + FRAME_COLOR.getBlue()); + System.err.println("Pixel color Red: " + color.getRed() + "; Green: " + color.getGreen() + "; Blue: " + color.getBlue()); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight()); + BufferedImage img = robot.createScreenCapture(screen); + javax.imageio.ImageIO.write(img, "png", new java.io.File("image.png")); + throw new RuntimeException("Internal frame is not correctly dragged!"); } } finally { - if (frame != null) { - frame.dispose(); - } + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); } + System.out.println("Test Passed"); } private static boolean isSupported() { String d3d = System.getProperty("sun.java2d.d3d"); + System.out.println("d3d " + d3d); return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS; } @@ -138,6 +161,7 @@ panel.add(desktopPane, BorderLayout.CENTER); frame.add(panel); frame.setSize(WIN_WIDTH, WIN_HEIGHT); + frame.setLocationRelativeTo(null); frame.setVisible(true); frame.requestFocus(); } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JInternalFrame/bug4308938.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JInternalFrame/bug4308938.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JInternalFrame/bug4308938.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JInternalFrame/bug4308938.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JInternalFrame; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +/* + * @test + * @bug 4308938 + * @summary Tests if Serializing JInternalFrame throws Error + */ + +public class bug4308938 { + private static JInternalFrame jif = + new JInternalFrame("Serializable",true,true,true,true); + + public static void main(String[] args) throws Exception { + try { + jif.setLocation(100,100); + jif.setSize(100,100); + ByteArrayOutputStream s = new ByteArrayOutputStream(); + ObjectOutputStream o = new ObjectOutputStream(s); + o.writeObject(jif); + o.close(); + o = new ObjectOutputStream(s); + o.writeObject(jif); + o.close(); + } catch (Exception e) { + throw new RuntimeException("Serializing JInternalFrame throws Error"); + } finally { + if (jif != null) { + jif.dispose(); + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JInternalFrame/bug4320889.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JInternalFrame/bug4320889.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JInternalFrame/bug4320889.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JInternalFrame/bug4320889.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; + +import static javax.swing.SwingUtilities.invokeAndWait; + +/* + * @test + * @bug 4320889 + * @key headful + * @summary Tests if default background color is set correctly for JInternalFrame +*/ + +public class bug4320889 { + private static JFrame jFrame; + + private static final int FRAME_SIZE = 200; + private static final int JIF_SIZE = 100; + + public static void main(String[] args) throws Exception { + invokeAndWait(() -> { + try { + jFrame = new JFrame("bug4320889 - JFrame b/g color"); + JDesktopPane desktop = new JDesktopPane(); + jFrame.setSize(FRAME_SIZE, FRAME_SIZE); + jFrame.setContentPane(desktop); + + JInternalFrame jif = new JInternalFrame(); + jif.setSize(JIF_SIZE, JIF_SIZE); + jif.setLocation(5, 5); + desktop.add(jif); + jif.setVisible(true); + jFrame.setVisible(true); + + if ((jif.getBackground()).equals(desktop.getBackground())) { + throw new RuntimeException("Test failed: default background color" + + " is not set correctly for JInternalFrame"); + } + } finally { + if (jFrame != null) { + jFrame.dispose(); + } + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug4173633.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug4173633.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug4173633.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug4173633.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + @test + @bug 4173633 + @summary Test for infinite recursion when JMenu with separator + @run main bug4173633 +*/ + +import javax.swing.JMenu; + +public class bug4173633 { + public static void main(String[] args) { + JMenu m = new JMenu("bug4173633"); + m.addSeparator(); + if (m.getItem(0) == m) { + throw new RuntimeException("BUG 4173633 FAILED"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug4186641.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug4186641.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug4186641.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug4186641.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4186641 4242461 + @summary JMenu.getPopupMenuOrigin() protected (not privet) now. + @key headful + @run main bug4186641 +*/ + +import java.awt.Point; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; + + +public class bug4186641 { + + volatile static JFrame fr; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + SwingUtilities.invokeAndWait(() -> { + init(); + if (fr != null) { + fr.dispose(); + } + }); + } + + public static void init() { + class TestJMenu extends JMenu { + public TestJMenu() { + super("Test"); + } + + void test() { + Point testpoint = getPopupMenuOrigin(); + } + } + + TestJMenu mnu = new TestJMenu(); + fr = new JFrame("bug4186641"); + JMenuBar mb = new JMenuBar(); + fr.setJMenuBar(mb); + mb.add(mnu); + JMenuItem mi = new JMenuItem("test"); + mnu.add(mi); + fr.setSize(100,100); + fr.setVisible(true); + mnu.setVisible(true); + + mnu.test(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug4219523.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug4219523.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug4219523.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug4219523.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4219523 + @summary Tests if JMenu completely uninstalls UI + @run main bug4219523 +*/ + +import java.awt.Insets; + +import javax.swing.JMenuItem; +import javax.swing.plaf.basic.BasicMenuItemUI; + + +public class bug4219523 { + public static void main(String args[]) { + class TestMenuItem extends JMenuItem { + public int SetMarginCalls; + TestMenuItem(){ + super(); + SetMarginCalls = 0; + } + public void setMargin(Insets m){ + if (m == null) SetMarginCalls++; + super.setMargin(m); + } + } + BasicMenuItemUI bmiui = new BasicMenuItemUI(); + TestMenuItem mi = new TestMenuItem(); + bmiui.installUI(mi); + int installCall = mi.SetMarginCalls; + bmiui.uninstallUI(mi); + if (mi.SetMarginCalls <= installCall) { + throw new Error("Test failed: Uninstall UI does " + + "not uninstall DefaultMargin properties"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug5013739.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug5013739.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenu/bug5013739.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenu/bug5013739.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5013739 + @summary MNEMONIC CONFLICTS IN DISABLED/HIDDEN MENU ITEMS + @library ../regtesthelpers + @build JRobot + @key headful + @run main bug5013739 +*/ + +import java.awt.Component; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.AbstractAction; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; + +public class bug5013739 { + + static boolean passed = true; + static JFrame mainFrame; + static JMenu file; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + SwingUtilities.invokeAndWait(() -> { + mainFrame = new JFrame("Bug5013739"); + JMenuBar mb = new JMenuBar(); + mainFrame.setJMenuBar(mb); + file = new JMenu("File"); + JMenuItem about = new JMenuItem("About"); + about.setMnemonic('A'); + about.addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent evt) { + passed = false; + } + }); + file.add(about); + about.setVisible(false); + file.add("Open"); + file.add("Close"); + file.setMnemonic('F'); + mb.add(file); + mainFrame.pack(); + mainFrame.setVisible(true); + Util.blockTillDisplayed(mainFrame); + }); + + try { + JRobot robo = JRobot.getRobot(); + robo.delay(500); + robo.clickMouseOn(file); + robo.hitKey(KeyEvent.VK_A); + robo.delay(1000); + } finally { + if (mainFrame != null) { + SwingUtilities.invokeAndWait(() -> mainFrame.dispose()); + } + } + if (!passed) { + throw new RuntimeException("Hidden menu item is selectable "+ + "via mnemonic. Test failed."); + } + } +} + +class Util { + public static Point blockTillDisplayed(Component comp) { + Point p = null; + while (p == null) { + try { + p = comp.getLocationOnScreen(); + } catch (IllegalStateException e) { + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + } + } + return p; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4198809.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4198809.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4198809.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4198809.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4198809 + @key headful + @summary If JMenuItem is disabled and disabled icon is null, throws NPE. + @run main bug4198809 +*/ + +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class bug4198809 { + static JFrame frame; + public static void main(String args[]) throws Exception { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + + SwingUtilities.invokeAndWait(() -> { + try { + frame = new JFrame("bug4198809"); + JMenuItem mi = new JMenuItem("test"); + mi.setDisabledIcon(null); + mi.setEnabled(false); + frame.getContentPane().add(mi); + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4304129.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4304129.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4304129.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4304129.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * 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 4304129 + @summary Tests that ACCELERATOR_KEY and MNEMONIC_KEY properties of + Action are used by JMenuItem(Action) constructor + @run main bug4304129 +*/ + +import java.awt.Event; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +import javax.swing.AbstractAction; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +public class bug4304129 { + private static int mnemonic = 102; + private static KeyStroke accelerator = KeyStroke.getKeyStroke( + KeyEvent.VK_E, Event.CTRL_MASK); + + public static void main(String args[]) throws Exception { + JMenuItem mi = new JMenuItem(new TestAction("Delete Folder")); + + if (mi.getMnemonic() != mnemonic) { + throw new RuntimeException("Failed: mnemonic not set from Action"); + } + + if (mi.getAccelerator() == null || + ! mi.getAccelerator().equals(accelerator)) { + + throw new RuntimeException("Failed: accelerator not set from Action"); + } + } + + static class TestAction extends AbstractAction { + TestAction(String str) { + super(str); + putValue(AbstractAction.ACCELERATOR_KEY, accelerator); + putValue(AbstractAction.MNEMONIC_KEY, new Integer(mnemonic)); + } + public void actionPerformed(ActionEvent ev) { + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4839464.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4839464.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4839464.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4839464.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4839464 + @summary Shortcoming in the way JMenuItem handles 'propertyChange()' events. + @key headful + @run main bug4839464 +*/ + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import javax.swing.Action; +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +public class bug4839464 { + + // Global variables + public static volatile boolean passed = true; + public static volatile String reason = "\nSome actions did not worked:"; + + public static AbstractAction action= new AbstractAction() { + public void actionPerformed(ActionEvent e) { + System.out.println("An action has performed"); + } + }; + + public static KeyStroke ks1 = + KeyStroke.getKeyStroke(KeyEvent.VK_F1, + KeyEvent.SHIFT_DOWN_MASK); + + public static KeyStroke ks2 = + KeyStroke.getKeyStroke(KeyEvent.VK_F1, + KeyEvent.CTRL_DOWN_MASK); + + public static JFrame frame; + + public static JFrame control; + public static JButton changeNameButton; + public static JButton changeMnemonicButton; + public static JButton changeAcceleratorButton; + public static JButton changeShortDescButton; + + public static JMenuItem item; + + public static Robot r; + + public static volatile int btnWidth, btnHeight; + public static volatile Point p; + + public static void main(String[] args) throws Exception { + try { + r = new Robot(); + SwingUtilities.invokeAndWait(() -> { + changeNameButton = new JButton("Change name"); + changeMnemonicButton = new JButton("On/Off mnemonic"); + changeAcceleratorButton = new JButton("Change accelerator"); + changeShortDescButton = new JButton("Change short desc."); + + JMenuBar mb = new JMenuBar(); + JMenu test = new JMenu("Test"); + mb.add(test); + item = new JMenuItem(action); + test.add(item); + frame = new JFrame("Action tester"); + frame.setJMenuBar(mb); + frame.setLayout(new BorderLayout()); + frame.add(new JButton(action), BorderLayout.CENTER); + frame.pack(); + frame.setLocation(100, 10); + frame.setVisible(true); + r.delay(100); + + control = new JFrame("Controls"); + control.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + control.setLayout(new GridLayout(2, 10)); + control.add(changeNameButton); + control.add(changeMnemonicButton); + control.add(changeAcceleratorButton); + control.add(changeShortDescButton); + control.pack(); + control.setLocation(100, 500); + control.setVisible(true); + r.delay(100); + + changeNameButton.addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if ("First Name".equals(action.getValue(Action.NAME))) { + action.putValue(Action.NAME, "Second Name"); + } else { + action.putValue(Action.NAME, "First Name"); + } + } + }); + + changeMnemonicButton.addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + Integer mnem = (Integer) action.getValue(Action.MNEMONIC_KEY); + if (mnem.intValue() == 0) { + action.putValue(Action.MNEMONIC_KEY, new Integer('N')); + } else { + action.putValue(Action.MNEMONIC_KEY, new Integer(0)); + } + } + }); + + changeAcceleratorButton.addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (action.getValue(Action.ACCELERATOR_KEY) == ks1) { + action.putValue(Action.ACCELERATOR_KEY, ks2); + } else { + action.putValue(Action.ACCELERATOR_KEY, ks1); + } + } + }); + + changeShortDescButton.addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + String shortDescr = (String) action.getValue(Action.SHORT_DESCRIPTION); + if ("Just a text".equals(shortDescr)) { + action.putValue(Action.SHORT_DESCRIPTION, null); + } else { + action.putValue(Action.SHORT_DESCRIPTION, "Just a text"); + } + } + }); + + action.putValue(Action.NAME, "Second Name"); + action.putValue(Action.MNEMONIC_KEY, new Integer('N')); + action.putValue(Action.ACCELERATOR_KEY, ks1); + action.putValue(Action.SHORT_DESCRIPTION, null); + }); + + r.delay(1000); + r.waitForIdle(); + // Run tests + test(); + r.delay(1000); + r.waitForIdle(); + + if (!passed) { + throw new RuntimeException(reason + "\nTest failed."); + } + } finally { + if (frame != null) { + frame.dispose(); + } + if (control != null) { + control.dispose(); + } + } + } + + public static boolean compareObjects(Object a, Object b) { + if (a == null) { + return (b == null); + } + return a.equals(b); + } + + // Actual tests + public static void test() throws Exception { + r.delay(500); + Object tmpResult; + + // Check Action.NAME handling + tmpResult = item.getText(); + SwingUtilities.invokeAndWait(() -> { + p = changeNameButton.getLocationOnScreen(); + btnWidth = changeNameButton.getWidth(); + btnHeight = changeNameButton.getHeight(); + }); + + doMouseMove(p, btnWidth, btnHeight); + if (compareObjects(tmpResult, item.getText())) { + passed = false; + reason = reason + "\n Action.NAME"; + } + + // Check mnemonics + int tmpInt = item.getMnemonic(); + SwingUtilities.invokeAndWait(() -> { + p = changeMnemonicButton.getLocationOnScreen(); + btnWidth = changeMnemonicButton.getWidth(); + btnHeight = changeMnemonicButton.getHeight(); + }); + + doMouseMove(p, btnWidth, btnHeight); + if (tmpInt == item.getMnemonic()) { + passed = false; + reason = reason + "\n Action.MNEMONIC_KEY"; + } + + // Check accelerator binding + tmpResult = item.getAccelerator(); + SwingUtilities.invokeAndWait(() -> { + p = changeAcceleratorButton.getLocationOnScreen(); + btnWidth = changeAcceleratorButton.getWidth(); + btnHeight = changeAcceleratorButton.getHeight(); + }); + + doMouseMove(p, btnWidth, btnHeight); + if (compareObjects(tmpResult, item.getAccelerator())) { + passed = false; + reason = reason + "\n Action.ACCELERATOR_KEY"; + } + + // Check short description (should change ToolTipText) + tmpResult = item.getToolTipText(); + SwingUtilities.invokeAndWait(() -> { + p = changeShortDescButton.getLocationOnScreen(); + btnWidth = changeShortDescButton.getWidth(); + btnHeight = changeShortDescButton.getHeight(); + }); + + doMouseMove(p, btnWidth, btnHeight); + if (compareObjects(tmpResult, item.getToolTipText())) { + passed = false; + reason = reason + "\n Action.SHORT_DESCRIPTION"; + } + } + + public static void doMouseMove(Point p, int width, int height) { + r.mouseMove(p.x + width / 2, p.y + height / 2); + r.delay(500); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4966168.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4966168.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JMenuItem/bug4966168.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JMenuItem/bug4966168.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4966168 + @summary JInternalFrame not serializable in Motif & GTK L&F + @run main bug4966168 +*/ + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.awt.event.ActionEvent; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +public class bug4966168 { + + public static class MyAction extends AbstractAction implements Serializable { + public void actionPerformed(ActionEvent e) {} + } + + public static void main(String args[]) throws Exception { + JButton button = new JButton(new MyAction()); + + ObjectOutputStream out = null; + + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + try { + out = new ObjectOutputStream(byteStream); + } catch (IOException e) {} + + if (out != null) { + for (UIManager.LookAndFeelInfo laf : + UIManager.getInstalledLookAndFeels()) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + System.out.println("Testing LAF: " + laf.getClassName()); + } catch (UnsupportedLookAndFeelException e) { + System.out.println("Look and Feel not set: " + laf.getClassName()); + continue; + } + + out.writeObject(button); + } + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -89,6 +89,12 @@ buttonPressed = false; String lafName = laf.getClassName(); System.out.println("Testing L&F: " + lafName); + + // Ignore obsolete/deprecated Motif + if (lafName.contains("Motif")) { + System.out.println("Skipped Motif"); + continue; + } SwingUtilities.invokeAndWait(() -> { setLookAndFeel(lafName); createUI(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java 2023-07-05 07:11:54.000000000 +0000 @@ -21,11 +21,16 @@ * questions. */ +import java.io.File; + +import java.awt.image.BufferedImage; +import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.event.InputEvent; import javax.swing.JFrame; @@ -38,8 +43,10 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.imageio.ImageIO; import static javax.swing.UIManager.getInstalledLookAndFeels; + /** * @test * @bug 4788637 7124307 @@ -52,15 +59,15 @@ private static JFrame fr; private static Robot robot; - private int step; - private boolean spinnerValueChanged[] = {false, false, false}; + private int step = 0; + private volatile boolean spinnerValueChanged[] = {false, false, false}; - private static Point p; - private static Rectangle rect; + private static volatile Point p; + private static volatile Rectangle rect; public static void main(final String[] args) throws Exception { robot = new Robot(); - robot.setAutoDelay(50); + robot.setAutoDelay(100); robot.setAutoWaitForIdle(true); for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); @@ -68,6 +75,7 @@ try { SwingUtilities.invokeAndWait(app::createAndShowGUI); robot.waitForIdle(); + robot.delay(1000); SwingUtilities.invokeAndWait(()-> { spinner.requestFocus(); p = spinner.getLocationOnScreen(); @@ -106,9 +114,11 @@ public void start() { try { Thread.sleep(1000); + System.out.println("p " + p + " rect " + rect); // Move mouse to the up arrow button robot.mouseMove(p.x+rect.width-3, p.y+3); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + synchronized (bug4788637.this) { if (!spinnerValueChanged[step]) { bug4788637.this.wait(3000); @@ -123,6 +133,7 @@ bug4788637.this.wait(3000); } } + robot.waitForIdle(); // Move mouse to the up arrow button robot.mouseMove(p.x+rect.width-3, p.y+3); @@ -132,8 +143,10 @@ bug4788637.this.wait(3000); } } + robot.waitForIdle(); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); } catch(Throwable t) { throw new RuntimeException(t); } @@ -145,6 +158,15 @@ if (!spinnerValueChanged[0] || spinnerValueChanged[1] || !spinnerValueChanged[2]) { + System.out.println("!spinnerValueChanged[0] " + !spinnerValueChanged[0] + + " spinnerValueChanged[1] " + spinnerValueChanged[1] + + " !spinnerValueChanged[2] " + !spinnerValueChanged[2]); + try { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight()); + BufferedImage fullScreen = robot.createScreenCapture(screen); + ImageIO.write(fullScreen, "png", new File("fullScreen.png")); + } catch (Exception e) {} throw new Error("JSpinner buttons don't conform to most platform conventions"); } } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/4170447/bug4170447.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/4170447/bug4170447.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/4170447/bug4170447.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/4170447/bug4170447.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4170447 + @summary JTable: non-Icon data in Icon column. + @key headful +*/ + +import java.io.File; +import java.awt.Component; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableModel; + +public class bug4170447 { + + static volatile boolean failed = false; + static volatile JFrame frame = null; + + public static void main(String args[]) throws Exception { + SwingUtilities.invokeAndWait(bug4170447::createUI); + Thread.sleep(5000); + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + if (failed) { + throw new RuntimeException("Some exception occurred..."); + } + } + + static void createUI() { + String imgDir = System.getProperty("test.src", "."); + String imgPath = imgDir + File.separator + "swing.small.gif"; + ImageIcon icn = new ImageIcon(imgPath,"test"); + final Object data[][] = { + {"CELL 0 0", icn}, + {"CELL 1 0", "String"} + }; + String[] str = {"Column 0", "Column 1"}; + + TableModel dataModel = new AbstractTableModel() { + public int getColumnCount() { return 2; } + public int getRowCount() { return 2; } + public Object getValueAt(int row, int col) {return data[row][col];} + public Class getColumnClass(int c) {return getValueAt(0, c).getClass();} + public boolean isCellEditable(int row, int col) {return getColumnClass(col) == String.class;} + public void setValueAt(Object aValue, int row, int column) {data[row][column] = aValue;} + }; + + MyTable tbl = new MyTable(dataModel); + JScrollPane sp = new JScrollPane(tbl); + frame = new JFrame("bug4170447"); + frame.getContentPane().add(sp); + frame.pack(); + frame.setVisible(true); + } + + static class MyTable extends JTable { + public MyTable(TableModel tm) { + super(tm); + } + + public Component prepareRenderer(TableCellRenderer rend, int row, int col) { + try { + return super.prepareRenderer(rend, row, col); + } catch (Exception e) { + e.printStackTrace(); + failed = true; + return null; + } + } + } +} Binary files /tmp/tmphyegkbwu/Lq1fQUuR9P/openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/4170447/swing.small.gif and /tmp/tmphyegkbwu/UiQyo5qJAC/openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/4170447/swing.small.gif differ diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4098201.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4098201.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4098201.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4098201.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4098201 + @summary Tests setRowHeight(int row, int height). +*/ + +import javax.swing.JTable; + +public class bug4098201 { + + public static void main(String args[]) { + JTable table = new JTable(4,3); + table.setRowHeight(1, table.getRowHeight()*2); + if (table.getRowHeight(0) * 2 != table.getRowHeight(1)) { + throw new Error("Can't set height for specified row..."); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4130356.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4130356.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4130356.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4130356.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4130356 + @summary JTable.setRowSelectionInterval(int, int) shouldn't accept invalid range +*/ + +import javax.swing.JTable; +import javax.swing.ListSelectionModel; + +public class bug4130356 { + + public static void main(String[] argv) { + JTable table = new JTable(4,3); + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + try { + table.setRowSelectionInterval(10,13); + throw new Error("Invalid arguments supported!!!"); + } catch (IllegalArgumentException iae) {} + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4159300.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4159300.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4159300.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4159300.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4159300 + @summary Tests that JTable processes tableChanged events quickly + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Rectangle; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.DefaultTableModel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class bug4159300 { + + static volatile JFrame frame = null; + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(bug4159300::createUI); + Thread.sleep(3000); + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + static void createUI() { + frame = new JFrame("bug4159300"); + Container c = frame.getContentPane(); + c.setLayout(new BorderLayout()); + // create table + Object[] columnNames = {"only column"}; + DefaultTableModel model = new DefaultTableModel(columnNames, 0); + Object[] row = makeRow(model.getRowCount()); + model.addRow(row); + + JTable table = new JTable(model); + c.add(new JScrollPane(table), BorderLayout.CENTER); + + // create button + JButton immediateButton = new JButton("Add row"); + immediateButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int rowCount = model.getRowCount(); + Object[] row = makeRow(rowCount); + model.addRow(row); + int rows = model.getRowCount(); + int lastRow = rows - 1; + table.setRowSelectionInterval(lastRow, lastRow); + Rectangle r = table.getCellRect(lastRow, 0, false); + table.scrollRectToVisible(r); + } + }); + c.add(immediateButton, BorderLayout.SOUTH); + frame.pack(); + frame.setVisible(true); + } + + static Object[] makeRow(int rowNumber) { + Object[] row = { ""+rowNumber }; + return row; + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4243159.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4243159.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4243159.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4243159.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4243159 + @summary Tests that JTable() do not throw ArrayIndexOutOfBoundsException +*/ + +import javax.swing.JTable; + +public class bug4243159 { + + /* Looks boring, but tests the no-args constructor works */ + public static void main(String[] argv) { + JTable table = new JTable(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4243313.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4243313.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4243313.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4243313.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4243313 + @summary Tests that instantiating JTable through reflection + does not throw ClassNotFoundException +*/ + +import java.beans.Beans; + +public class bug4243313 { + + public static void main(String[] argv) throws Exception { + Object table = Beans.instantiate(null, "javax.swing.JTable"); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4247487.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4247487.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4247487.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4247487.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + @test + @bug 4247487 + @summary Tests that the following methods of JTable are public: + int getAccessibleColumnAtIndex(int) + int getAccessibleRowAtIndex(int) + int getAccessibleIndexAt(int, int) +*/ + +import javax.swing.JTable; + +public class bug4247487 { + + static class TestTable extends JTable { + + public TestTable() { + super(new Object[][]{{"one", "two"}}, + new Object[]{"A", "B"}); + } + + public void test() { + int[] rowIndices = {0, 0, 1, 1}; + int[] colIndices = {0, 1, 0, 1}; + JTable.AccessibleJTable at = + (JTable.AccessibleJTable)getAccessibleContext(); + + for (int i=0; i<4; i++) { + if (at.getAccessibleRowAtIndex(i) != rowIndices[i]) { + throw new Error("Failed: wrong row index"); + } + if (at.getAccessibleColumnAtIndex(i) != colIndices[i]) { + throw new Error("Failed: wrong column index"); + } + } + if (at.getAccessibleIndexAt(0,0) != 0 || + at.getAccessibleIndexAt(0,1) != 1 || + at.getAccessibleIndexAt(1,0) != 2 || + at.getAccessibleIndexAt(1,1) != 3) { + + throw new Error("Failed: wrong index"); + } + } + } + + public static void main(String[] argv) { + TestTable test = new TestTable(); + test.test(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4248070.java openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4248070.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/JTable/bug4248070.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/JTable/bug4248070.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4248070 + @summary cellEditor bound in JTable. +*/ + +import javax.swing.JTable; +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; + +public class bug4248070 { + + public static void main(String[] argv) { + + BeanInfo bi = null; + + try { + bi = Introspector.getBeanInfo(JTable.class); + } catch (IntrospectionException e) { + } + + PropertyDescriptor[] pd = bi.getPropertyDescriptors(); + int i; + for (i=0; i fail()); + box.setSelected(false); + + if (failed()) { + throw new RuntimeException("Failed: extra ChangeEvent was fired"); + } + } + + private static boolean failed_flag = false; + synchronized static void fail() { + failed_flag = true; + } + synchronized static boolean failed() { return failed_flag; } + + @Override + public void itemStateChanged(ItemEvent e) { + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java openjdk-17-17.0.8+7/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java --- openjdk-17-17.0.7+7~us1/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java 2023-07-05 07:11:54.000000000 +0000 @@ -37,46 +37,67 @@ import javax.swing.*; import javax.swing.plaf.synth.*; -public class bug6276188 extends JFrame { +public class bug6276188 { private static JButton button; private static Point p; + private static JFrame testFrame; - public static void main(String[] args) throws Throwable { - SynthLookAndFeel lookAndFeel = new SynthLookAndFeel(); - lookAndFeel.load(bug6276188.class.getResourceAsStream("bug6276188.xml"), bug6276188.class); - - UIManager.setLookAndFeel(lookAndFeel); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - JFrame testFrame = new JFrame(); - testFrame.setLayout(new BorderLayout()); - testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - testFrame.add(BorderLayout.CENTER, button = new JButton()); + // move away from cursor + private final static int OFFSET_X = -20; + private final static int OFFSET_Y = -20; - testFrame.setSize(new Dimension(320, 200)); - testFrame.setVisible(true); + public static void main(String[] args) throws Throwable { + try { + Robot robot = new Robot(); + robot.setAutoDelay(100); + + SynthLookAndFeel lookAndFeel = new SynthLookAndFeel(); + lookAndFeel.load(bug6276188.class.getResourceAsStream("bug6276188.xml"), bug6276188.class); + UIManager.setLookAndFeel(lookAndFeel); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + testFrame = new JFrame(); + testFrame.setLayout(new BorderLayout()); + testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + testFrame.add(BorderLayout.CENTER, button = new JButton()); + + testFrame.setSize(new Dimension(320, 200)); + testFrame.setLocationRelativeTo(null); + testFrame.setVisible(true); + } + }); + + robot.waitForIdle(); + robot.delay(1000); + + p = Util.getCenterPoint(button); + System.out.println("Button center point: " + p); + + robot.mouseMove(p.x , p.y); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + Color color = robot.getPixelColor(p.x - OFFSET_X, p.y - OFFSET_Y); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + boolean red = color.getRed() > 0 && color.getGreen() == 0 && color.getBlue() == 0; + if (!red) { + System.err.println("Red: " + color.getRed() + "; Green: " + color.getGreen() + "; Blue: " + color.getBlue()); + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight()); + BufferedImage img = robot.createScreenCapture(screen); + javax.imageio.ImageIO.write(img, "png", new java.io.File("image.png")); + throw new RuntimeException("Synth ButtonUI does not handle PRESSED & MOUSE_OVER state"); } - }); - - Robot robot = new Robot(); - robot.setAutoDelay(50); - robot.waitForIdle(); - robot.delay(200); - - p = Util.getCenterPoint(button); - - robot.mouseMove(p.x , p.y); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.waitForIdle(); - robot.delay(1000); - - Color color = robot.getPixelColor(p.x, p.y); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - boolean red = color.getRed() > 0 && color.getGreen() == 0 && color.getBlue() == 0; - if (!red) { - System.err.println("Red: " + color.getRed() + "; Green: " + color.getGreen() + "; Blue: " + color.getBlue()); - throw new RuntimeException("Synth ButtonUI does not handle PRESSED & MOUSE_OVER state"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (testFrame != null) { + testFrame.dispose(); + } + }); } } } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -56,7 +56,7 @@ return is.read(); } }; - var t = new AbstractWindowsTerminal(out, "test", "vt100", null, -1, false, SignalHandler.SIG_DFL, isWrapper) { + var t = new AbstractWindowsTerminal(out, "test", "vt100", null, false, SignalHandler.SIG_DFL, isWrapper) { @Override protected int getConsoleMode() { return -1; diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/jline/KeyConversionTest.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/jline/KeyConversionTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/jline/KeyConversionTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/jline/KeyConversionTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -59,7 +59,7 @@ void checkKeyConversion(KeyEvent event, String expected) throws IOException { StringBuilder result = new StringBuilder(); new AbstractWindowsTerminal(new StringWriter(), "", "windows", Charset.forName("UTF-8"), - 0, true, SignalHandler.SIG_DFL, in -> in) { + true, SignalHandler.SIG_DFL, in -> in) { @Override protected int getConsoleMode() { return 0; diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/jline/OSUtilsTest.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/jline/OSUtilsTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/jline/OSUtilsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/jline/OSUtilsTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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 8304498 + * @summary Verify the OSUtils class is initialized properly + * @modules jdk.internal.le/jdk.internal.org.jline.utils + */ + +import jdk.internal.org.jline.utils.OSUtils; + +public class OSUtilsTest { + public static void main(String... args) throws Exception { + new OSUtilsTest().run(); + } + + void run() throws Exception { + runTestTest(); + } + + void runTestTest() throws Exception { + if (OSUtils.IS_WINDOWS) { + return ; //skip on Windows + } + + Process p = new ProcessBuilder(OSUtils.TEST_COMMAND, "-z", "").inheritIO().start(); + if (p.waitFor() != 0) { + throw new AssertionError("Unexpected result!"); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/cgroup/CgroupV1SubsystemControllerTest.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/cgroup/CgroupV1SubsystemControllerTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/cgroup/CgroupV1SubsystemControllerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/cgroup/CgroupV1SubsystemControllerTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, 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. + */ + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import jdk.internal.platform.cgroupv1.CgroupV1SubsystemController; + +/* + * @test + * @key cgroups + * @requires os.family == "linux" + * @modules java.base/jdk.internal.platform.cgroupv1 + * @library /test/lib + * @run junit/othervm CgroupV1SubsystemControllerTest + */ +public class CgroupV1SubsystemControllerTest { + + + /* + * Common case: Containers + */ + @Test + public void testCgPathEqualsRoot() { + String root = "/machine.slice/libpod-7145e2e7dbeab5aa96bd79beed79eda286a2d299a0ee386e704cad9f53a70979.scope"; + String mountPoint = "/somemount"; + CgroupV1SubsystemController ctrl = new CgroupV1SubsystemController(root, mountPoint); + ctrl.setPath("/machine.slice/libpod-7145e2e7dbeab5aa96bd79beed79eda286a2d299a0ee386e704cad9f53a70979.scope"); + assertEquals(mountPoint, ctrl.path()); + } + + /* + * Common case: Host + */ + @Test + public void testCgPathNonEmptyRoot() { + String root = "/"; + String mountPoint = "/sys/fs/cgroup/memory"; + CgroupV1SubsystemController ctrl = new CgroupV1SubsystemController(root, mountPoint); + String cgroupPath = "/subpath"; + ctrl.setPath(cgroupPath); + String expectedPath = mountPoint + cgroupPath; + assertEquals(expectedPath, ctrl.path()); + } + + @Test + public void testCgPathSubstring() { + String root = "/foo/bar/baz"; + String mountPoint = "/sys/fs/cgroup/memory"; + CgroupV1SubsystemController ctrl = new CgroupV1SubsystemController(root, mountPoint); + String cgroupPath = "/foo/bar/baz/some"; + ctrl.setPath(cgroupPath); + String expectedPath = mountPoint + "/some"; + assertEquals(expectedPath, ctrl.path()); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/cgroup/CgroupV2SubsystemControllerTest.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/cgroup/CgroupV2SubsystemControllerTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/cgroup/CgroupV2SubsystemControllerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/cgroup/CgroupV2SubsystemControllerTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022, 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. + */ + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import jdk.internal.platform.cgroupv2.CgroupV2SubsystemController; + +/* + * @test + * @key cgroups + * @requires os.family == "linux" + * @modules java.base/jdk.internal.platform.cgroupv2 + * @library /test/lib + * @run junit/othervm CgroupV2SubsystemControllerTest + */ +public class CgroupV2SubsystemControllerTest { + + + /* + * Common case: No nested cgroup path (i.e. at the unified root) + */ + @Test + public void testCgPathAtRoot() { + String mountPoint = "/sys/fs/cgroup"; + String cgroupPath = "/"; + CgroupV2SubsystemController ctrl = new CgroupV2SubsystemController(mountPoint, cgroupPath); + assertEquals(mountPoint, ctrl.path()); + } + + /* + * Cgroup path at a sub-path + */ + @Test + public void testCgPathNonEmptyRoot() { + String mountPoint = "/sys/fs/cgroup"; + String cgroupPath = "/foobar"; + CgroupV2SubsystemController ctrl = new CgroupV2SubsystemController(mountPoint, cgroupPath); + String expectedPath = mountPoint + cgroupPath; + assertEquals(expectedPath, ctrl.path()); + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/cgroup/TestCgroupMetrics.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/cgroup/TestCgroupMetrics.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/cgroup/TestCgroupMetrics.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/cgroup/TestCgroupMetrics.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,16 +36,7 @@ public class TestCgroupMetrics { public static void main(String[] args) throws Exception { - // If cgroups is not configured, report success. - Metrics metrics = Metrics.systemMetrics(); - if (metrics == null) { - System.out.println("TEST PASSED!!!"); - return; - } - - MetricsTester metricsTester = new MetricsTester(); - metricsTester.testAll(metrics); - System.out.println("TEST PASSED!!!"); + MetricsTester.main(args); } } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java 2023-07-05 07:11:54.000000000 +0000 @@ -39,9 +39,6 @@ case "memoryswap": testMemoryAndSwapLimit(args[1], args[2]); break; - case "kernelmem": - testKernelMemoryLimit(args[1]); - break; case "oomkill": testOomKillFlag(Boolean.parseBoolean(args[2])); break; @@ -119,23 +116,6 @@ System.out.println("TEST PASSED!!!"); } - private static void testKernelMemoryLimit(String value) { - Metrics m = Metrics.systemMetrics(); - if (m instanceof CgroupV1Metrics) { - CgroupV1Metrics mCgroupV1 = (CgroupV1Metrics)m; - System.out.println("TEST PASSED!!!"); - long limit = getMemoryValue(value); - long kmemlimit = mCgroupV1.getKernelMemoryLimit(); - if (kmemlimit != UNLIMITED && limit != kmemlimit) { - throw new RuntimeException("Kernel Memory limit not equal, expected : [" - + limit + "]" + ", got : [" - + kmemlimit + "]"); - } - } else { - throw new RuntimeException("kernel memory limit test not supported for cgroups v2"); - } - } - private static void testMemoryAndSwapLimit(String memory, String memAndSwap) { long expectedMem = getMemoryValue(memory); long expectedMemAndSwap = getMemoryValue(memAndSwap); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java 2023-07-05 07:11:54.000000000 +0000 @@ -63,18 +63,14 @@ testMemoryAndSwapLimit("100m", "200m"); Metrics m = Metrics.systemMetrics(); - // kernel memory, '--kernel-memory' switch, and OOM killer, - // '--oom-kill-disable' switch, tests not supported by cgroupv2 - // runtimes + // OOM killer disable, '--oom-kill-disable' switch, test not supported + // by cgroupv2 if (m != null) { if ("cgroupv1".equals(m.getProvider())) { - testKernelMemoryLimit("100m"); - testKernelMemoryLimit("1g"); - testOomKillFlag("100m", false); } else { - System.out.println("kernel memory tests and OOM Kill flag tests not " + - "possible with cgroupv2."); + System.out.println("OOM kill disable test not " + + "supported with cgroupv2."); } } testOomKillFlag("100m", true); @@ -159,30 +155,6 @@ DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!"); } - private static void testKernelMemoryLimit(String value) throws Exception { - Common.logNewTestCase("testKernelMemoryLimit, value = " + value); - DockerRunOptions opts = - new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester"); - opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/") - .addDockerOpts("--kernel-memory=" + value) - .addJavaOpts("-cp", "/test-classes/") - .addJavaOpts("--add-exports", "java.base/jdk.internal.platform=ALL-UNNAMED") - .addClassOptions("kernelmem", value); - OutputAnalyzer oa = DockerTestUtils.dockerRunJava(opts); - - // Some container runtimes (e.g. runc, docker 18.09) - // have been built without kernel memory accounting. In - // that case, the runtime issues a message on stderr saying - // so. Skip the test in that case. - if (oa.getStderr().contains("kernel memory accounting disabled")) { - System.out.println("Kernel memory accounting disabled, " + - "skipping the test case"); - return; - } - - oa.shouldHaveExitValue(0).shouldContain("TEST PASSED!!!"); - } - private static void testOomKillFlag(String value, boolean oomKillFlag) throws Exception { Common.logNewTestCase("testOomKillFlag, oomKillFlag = " + oomKillFlag); DockerRunOptions opts = diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/docker/TestSystemMetrics.java openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/docker/TestSystemMetrics.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/internal/platform/docker/TestSystemMetrics.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/internal/platform/docker/TestSystemMetrics.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,7 @@ opts.addDockerOpts("--memory=256m"); opts.addJavaOpts("-cp", "/test-classes/"); opts.addJavaOpts("--add-exports", "java.base/jdk.internal.platform=ALL-UNNAMED"); + opts.addClassOptions("-incontainer"); DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!"); } finally { DockerTestUtils.removeDockerImage(imageName); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java openjdk-17-17.0.8+7/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java 2023-07-05 07:11:54.000000000 +0000 @@ -42,7 +42,7 @@ * jdk.jfr.api.consumer.log.TestVerbosity trace * @run main/othervm * -Xlog:jfr+event*=debug:file=debug.log - * -XX:StartFlightRecording + * -XX:StartFlightRecording:jdk.ExecutionSample#enabled=false * jdk.jfr.api.consumer.log.TestVerbosity debug * @run main/othervm * -Xlog:jfr+event*=info:file=info.log diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java openjdk-17-17.0.8+7/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java 2023-07-05 07:11:54.000000000 +0000 @@ -172,6 +172,7 @@ insertSetting(doc, EventNames.JavaExceptionThrow, "threshold", "0 ns"); insertSetting(doc, EventNames.JavaErrorThrow, "threshold", "0 ns"); insertSetting(doc, EventNames.SecurityProperty, "threshold", "0 ns"); + insertSetting(doc, EventNames.SecurityProviderService, "threshold", "0 ns"); insertSetting(doc, EventNames.TLSHandshake, "threshold", "0 ns"); insertSetting(doc, EventNames.X509Certificate, "threshold", "0 ns"); insertSetting(doc, EventNames.X509Validation, "threshold", "0 ns"); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java openjdk-17-17.0.8+7/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java 2023-07-05 07:11:54.000000000 +0000 @@ -206,6 +206,7 @@ settingValues.put(EventNames.X509Validation + "#threshold", "0 ns"); settingValues.put(EventNames.ProcessStart + "#threshold", "0 ns"); settingValues.put(EventNames.Deserialization + "#threshold", "0 ns"); + settingValues.put(EventNames.SecurityProviderService + "#threshold", "0 ns"); try (Recording recording = new Recording(c)) { Map eventTypes = new HashMap<>(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java openjdk-17-17.0.8+7/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java --- openjdk-17-17.0.7+7~us1/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.security; + +import java.security.*; +import java.security.cert.CertPathBuilder; +import java.util.Collections; +import java.util.List; +import java.util.function.*; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.Events; +import jdk.test.lib.jfr.EventNames; + +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +/* + * @test + * @bug 8254711 + * @summary Add JFR events for security crypto algorithms + * @key jfr + * @requires vm.hasJFR + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.events + * @run main/othervm jdk.jfr.event.security.TestSecurityProviderServiceEvent + */ +public class TestSecurityProviderServiceEvent { + + public static void main(String[] args) throws Exception { + testAlg(cipherFunc, "AES", "SunJCE", + "SunEC", "Cipher", 1, Collections.emptyList()); + testAlg(signatureFunc, "SHA256withRSA", "SunRsaSign", + "SunEC", "Signature", 2, List.of("MessageDigest")); + testAlg(messageDigestFunc, "SHA-512", "SUN", + "SunEC", "MessageDigest", 1, Collections.emptyList()); + testAlg(keystoreFunc, "PKCS12", "SUN", + "SunEC", "KeyStore", 1, Collections.emptyList()); + testAlg(certPathBuilderFunc, "PKIX", "SUN", + "SunEC", "CertPathBuilder", 2, List.of("CertificateFactory")); + } + + private static void testAlg(BiFunction bif, String alg, + String workingProv, String brokenProv, String algType, + int expected, List other) throws Exception { + // bootstrap security Provider services + Provider p = bif.apply(alg, workingProv); + + try (Recording recording = new Recording()) { + recording.enable(EventNames.SecurityProviderService); + recording.start(); + p = bif.apply(alg, workingProv); + bif.apply(alg, brokenProv); + recording.stop(); + List events = Events.fromRecording(recording); + Asserts.assertEquals(events.size(), expected, "Incorrect number of events"); + assertEvent(events, algType, alg, p.getName(), other); + } + } + + private static BiFunction cipherFunc = (s1, p1 ) -> { + Cipher c; + try { + c = Cipher.getInstance(s1, p1); + return c.getProvider(); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) { + // expected + } + return null; + }; + + private static BiFunction signatureFunc = (s1, p1 ) -> { + Signature s; + try { + s = Signature.getInstance(s1, p1); + return s.getProvider(); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + // expected + } + return null; + }; + + private static BiFunction messageDigestFunc = (s1, p1 ) -> { + MessageDigest md; + try { + md = MessageDigest.getInstance(s1, p1); + return md.getProvider(); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + // expected + } + return null; + }; + + private static BiFunction keystoreFunc = (s1, p1 ) -> { + KeyStore ks; + try { + ks = KeyStore.getInstance(s1, p1); + return ks.getProvider(); + } catch (NoSuchProviderException | KeyStoreException e) { + // expected + } + return null; + }; + + private static BiFunction certPathBuilderFunc = (s1, p1 ) -> { + CertPathBuilder cps; + try { + cps = CertPathBuilder.getInstance(s1, p1); + return cps.getProvider(); + } catch (NoSuchProviderException | NoSuchAlgorithmException e) { + // expected + } + return null; + }; + + private static void assertEvent(List events, String type, + String alg, String workingProv, List other) { + boolean secondaryEventOK = other.isEmpty() ? true : false; + for (RecordedEvent e : events) { + if (other.contains(e.getValue("type"))) { + // secondary operation in service stack while constructing this request + secondaryEventOK = true; + continue; + } + Events.assertField(e, "provider").equal(workingProv); + Events.assertField(e, "type").equal(type); + Events.assertField(e, "algorithm").equal(alg); + } + if (!secondaryEventOK) { + throw new RuntimeException("Secondary events missing"); + } + + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/ProblemList.txt openjdk-17-17.0.8+7/test/jdk/ProblemList.txt --- openjdk-17-17.0.7+7~us1/test/jdk/ProblemList.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/ProblemList.txt 2023-07-05 07:11:54.000000000 +0000 @@ -187,7 +187,7 @@ java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252 windows-all java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8203047 macosx-all java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java 8073636 macosx-all -java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-aarch64 +java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-all java/awt/Focus/8013611/JDK8013611.java 8175366 windows-all,macosx-all java/awt/Focus/6981400/Test1.java 8029675 windows-all,macosx-all java/awt/Focus/6981400/Test3.java 8173264 generic-all @@ -646,8 +646,6 @@ sun/security/pkcs11/KeyStore/SecretKeysBasic.java 8209398 generic-all -security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 8224768 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 diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java --- openjdk-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 2023-07-05 07:11:54.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 @@ -33,221 +33,185 @@ /* * Obtain test artifacts for Actalis CA from: * - * Test web site with *active *TLS Server certificate: - * https://ssltest-a.actalis.it:8443 - * If doesn't work then use certificate of https://www.actalis.it + * Test website with *active* TLS Server certificate: + * https://ssltest-active.actalis.it/ * - * Test web site with *revoked *TLS Server certificate: - * https://ssltest-r.actalis.it:8444 + * Test website with *revoked* TLS Server certificate: + * https://ssltest-revoked.actalis.it/ * - * Test web site with *expired *TLS Server certificate: - * https://ssltest-e.actalis.it:8445 + * Test website with *expired* TLS Server certificate: + * https://ssltest-expired.actalis.it/ */ public class ActalisCA { - // Owner: CN=Actalis Extended Validation Server CA G1, - // O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // Issuer: CN=Actalis Authentication Root CA, O=Actalis S.p.A./03358520967, - // L=Milan, C=IT - private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" - + "MIIGTDCCBDSgAwIBAgIIMtYr/GdQGsswDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\n" - + "BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w\n" - + "MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\n" - + "IENBMB4XDTE1MDUxNDA3MDAzOFoXDTMwMDUxNDA3MDAzOFowgYcxCzAJBgNVBAYT\n" - + "AklUMQ8wDQYDVQQIDAZNaWxhbm8xDzANBgNVBAcMBk1pbGFubzEjMCEGA1UECgwa\n" - + "QWN0YWxpcyBTLnAuQS4vMDMzNTg1MjA5NjcxMTAvBgNVBAMMKEFjdGFsaXMgRXh0\n" - + "ZW5kZWQgVmFsaWRhdGlvbiBTZXJ2ZXIgQ0EgRzEwggEiMA0GCSqGSIb3DQEBAQUA\n" - + "A4IBDwAwggEKAoIBAQD1Ygc1CwmqXqjd3dTEKMLUwGdb/3+00ytg0uBb4RB+89/O\n" - + "4K/STFZcGUjcCq6Job5cmxZBGyRRBYfCEn4vg8onedFztkO0NvD04z4wLFyxjSRT\n" - + "bcMm2d+/Xci5XLA3Q9wG8TGzHTVQKmdvFpQ7b7EsmOc0uXA7w3UGhLjb2EYpu/Id\n" - + "uZ1LUTyEOHc3XHXI3a3udkRBDs/bObTcbte80DPbNetRFB+jHbIw5sH171IeBFGN\n" - + "PB92Iebp01yE8g3X9RqPXrrV7ririEtwFMYp+KgA8BRHxsoNV3xZmhdzJm0AMzC2\n" - + "waLM3H562xPM0UntAYh2pRrAUUtgURRizCT1kr6tAgMBAAGjggHVMIIB0TBBBggr\n" - + "BgEFBQcBAQQ1MDMwMQYIKwYBBQUHMAGGJWh0dHA6Ly9vY3NwMDUuYWN0YWxpcy5p\n" - + "dC9WQS9BVVRILVJPT1QwHQYDVR0OBBYEFGHB5IYeTW10dLzZlzsxcXjLP5/cMA8G\n" - + "A1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbtifN7OHCUyQICNtAw\n" - + "RQYDVR0gBD4wPDA6BgRVHSAAMDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vd3d3LmFj\n" - + "dGFsaXMuaXQvYXJlYS1kb3dubG9hZDCB4wYDVR0fBIHbMIHYMIGWoIGToIGQhoGN\n" - + "bGRhcDovL2xkYXAwNS5hY3RhbGlzLml0L2NuJTNkQWN0YWxpcyUyMEF1dGhlbnRp\n" - + "Y2F0aW9uJTIwUm9vdCUyMENBLG8lM2RBY3RhbGlzJTIwUy5wLkEuJTJmMDMzNTg1\n" - + "MjA5NjcsYyUzZElUP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q7YmluYXJ5MD2g\n" - + "O6A5hjdodHRwOi8vY3JsMDUuYWN0YWxpcy5pdC9SZXBvc2l0b3J5L0FVVEgtUk9P\n" - + "VC9nZXRMYXN0Q1JMMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEA\n" - + "OD8D2Z2fw76+GIu+mDEgygH/y7F9K4I6rZOc3LqGBecO3C0fGcIuuG7APtxGGk7Y\n" - + "nk97Qt+3pDoek9EP65/1u128pRncZcjEAeMgKb7UuJxwoR6Sj5zhOadotKcCQqmF\n" - + "Si99ExNo6dTq5Eyp1KrqepLmezbO9owx4Q44mtNpfKLMgzDqOn/dwNMo/pGYbMfP\n" - + "DjhxEnta1HXgcEcgCk1Au16xkdzapwY4sXpKuwB24phfWF+cveKAQ0Rncmvrm34i\n" - + "9B6leZUkSHDe4mRkbO5nObhKHYRmVSr0Q/wvGCmTgGTKuw/Gj8+RFb5MEkOKEcJn\n" - + "I32CPohpiW/jlpeLaFBIgJnXuZTxmfTX55sqtXDlKxRxFwq1W3kML4UfGZsgjx1l\n" - + "hX5fQ1QlEZeO9CyPpgGO5Py2KXXKhUxCtF7tawAYimWwslxvPCjHDND/WhM1Fz9e\n" - + "2yqwHcSQAOUVv5mk9uYc6/NSLwLb5in3R728GNEpHHhbx5QZhtdqR8mb56uJUDKI\n" - + "AwnnZckcR+SLGL2Agx7hY7YCMOQhSsO6PA81M/mGW2hGCiZw3GULJe9ejL/vdS0I\n" - + "PWrp7YLnXUa6mtXVSBKGrVrlbpJaN10+fB4Yrlk4O2sF4WNUAHMBn9T+zOXaBAhj\n" - + "vNlMU7+elLkTcKIB7qJJuSZChxzoevM2ciO3BpGuRxg=\n" - + "-----END CERTIFICATE-----"; - - // Owner: OID.1.3.6.1.4.1.311.60.2.1.3=IT, STREET=Via S. Clemente 53, - // OID.2.5.4.15=Private Organization, CN=www.actalis.it, - // SERIALNUMBER=03358520967, O=Actalis S.p.A., L=Ponte San Pietro, ST=Bergamo, C=IT - // Issuer: CN=Actalis Extended Validation Server CA G1, - // O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // Serial number: eeeee6d6463bde2 - // Valid from: Sat Jun 17 05:59:17 PDT 2017 until: Mon Jun 17 05:59:17 PDT 2019 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" - + "MIIHwTCCBqmgAwIBAgIIDu7ubWRjveIwDQYJKoZIhvcNAQELBQAwgYcxCzAJBgNV\n" - + "BAYTAklUMQ8wDQYDVQQIDAZNaWxhbm8xDzANBgNVBAcMBk1pbGFubzEjMCEGA1UE\n" - + "CgwaQWN0YWxpcyBTLnAuQS4vMDMzNTg1MjA5NjcxMTAvBgNVBAMMKEFjdGFsaXMg\n" - + "RXh0ZW5kZWQgVmFsaWRhdGlvbiBTZXJ2ZXIgQ0EgRzEwHhcNMTcwNjE3MTI1OTE3\n" - + "WhcNMTkwNjE3MTI1OTE3WjCB0zELMAkGA1UEBhMCSVQxEDAOBgNVBAgMB0Jlcmdh\n" - + "bW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMg\n" - + "Uy5wLkEuMRQwEgYDVQQFEwswMzM1ODUyMDk2NzEXMBUGA1UEAwwOd3d3LmFjdGFs\n" - + "aXMuaXQxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRswGQYDVQQJDBJW\n" - + "aWEgUy4gQ2xlbWVudGUgNTMxEzARBgsrBgEEAYI3PAIBAxMCSVQwggEiMA0GCSqG\n" - + "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwZ3++4pQYGfhXSqin1CKRJ6SOqkTcX3O0\n" - + "6b4jZbSNomyqyn6aHOz6ztOlj++fPzxmIzErEySOTd3G0pr+iwpYQVdeg1Y27KL8\n" - + "OiwwUrlV4ZMa8KKXr4BnWlDbFIo+eIcSew5V7CiodDyxpj9zjqJK497LF1jxgXtr\n" - + "IoMRwrh2Y0NbJCZGUCL30sQr/W4xBnO1+pi2DbCieGe/XoK8yEtx9FdnEFvyT9qn\n" - + "zYyrXvnTvfVSwzwtEIn+akjomI4WfCFLBF0M7v4dAHypfnPAAoW1c0BBqNB32zf0\n" - + "rYwNnD7UwZlcDihEYlgC70Dfy7bPsdq2spmOMk/VUqb3U0LHRVM3AgMBAAGjggPh\n" - + "MIID3TB9BggrBgEFBQcBAQRxMG8wOgYIKwYBBQUHMAKGLmh0dHA6Ly9jYWNlcnQu\n" - + "YWN0YWxpcy5pdC9jZXJ0cy9hY3RhbGlzLWF1dGV2ZzEwMQYIKwYBBQUHMAGGJWh0\n" - + "dHA6Ly9vY3NwMDUuYWN0YWxpcy5pdC9WQS9BVVRIRVYtRzEwHQYDVR0OBBYEFK9y\n" - + "954QoY/5XV6TayD1gWVy0gQOMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUYcHk\n" - + "hh5NbXR0vNmXOzFxeMs/n9wwUAYDVR0gBEkwRzA8BgYrgR8BEQEwMjAwBggrBgEF\n" - + "BQcCARYkaHR0cHM6Ly93d3cuYWN0YWxpcy5pdC9hcmVhLWRvd25sb2FkMAcGBWeB\n" - + "DAEBMIHvBgNVHR8EgecwgeQwgaKggZ+ggZyGgZlsZGFwOi8vbGRhcDA1LmFjdGFs\n" - + "aXMuaXQvY24lM2RBY3RhbGlzJTIwRXh0ZW5kZWQlMjBWYWxpZGF0aW9uJTIwU2Vy\n" - + "dmVyJTIwQ0ElMjBHMSxvJTNkQWN0YWxpcyUyMFMucC5BLi8wMzM1ODUyMDk2Nyxj\n" - + "JTNkSVQ/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5hcnkwPaA7oDmGN2h0\n" - + "dHA6Ly9jcmwwNS5hY3RhbGlzLml0L1JlcG9zaXRvcnkvQVVUSEVWLUcxL2dldExh\n" - + "c3RDUkwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF\n" - + "BQcDAjAZBgNVHREEEjAQgg53d3cuYWN0YWxpcy5pdDCCAX4GCisGAQQB1nkCBAIE\n" - + "ggFuBIIBagFoAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFc\n" - + "tiwHywAABAMARzBFAiEA7GC5/kja3l8cBw1/wBpHl/AKH6eL1MKpmICtf5G09c4C\n" - + "IBM887DQEwD2E4Xx/IP+33NMvUOhSwZ4XODgqFVXsz0wAHYA7ku9t3XOYLrhQmkf\n" - + "q+GeZqMPfl+wctiDAMR7iXqo/csAAAFctiwIqwAABAMARzBFAiEAwwiR95ozXdKs\n" - + "+uULfrzgENbHc2rLgGIac6ZMv0xHDLACIFLQVpvQBRQfys2KVRGHQKGxqAeghQZw\n" - + "9nJL+U5huzfaAHYA3esdK3oNT6Ygi4GtgWhwfi6OnQHVXIiNPRHEzbbsvswAAAFc\n" - + "tiwMqwAABAMARzBFAiEAifV9ocxbO6b3I22jb2zxBvG2e83hXHitOhYXkHdSmZkC\n" - + "IDJLuPvGOczF9axgphImlUbT9dX3wRpjEi5IeV+pxMiYMA0GCSqGSIb3DQEBCwUA\n" - + "A4IBAQB5U6k1Onv9Y7POHGnUOI0ATHevbpbS/7r68DZQ6cRmDIpsZyjW6PxYs9nc\n" - + "3ob3Pjomm+S7StDl9ehI7rYLlZC52QlXlsq1fzEQ9xSkf+VSD70A91dPIFAdI/jQ\n" - + "aWvIUvQEbhfUZc0ihIple0VyWGH5bza0DLW+C8ttF8KqICUfL8S8mZgjbXvVg2fY\n" - + "HLW9lWR/Pkco2yRc8gZyr9FGkXOcmJ8aFaCuJnGm/IVRCieYp60If4DoAKz49xpF\n" - + "CF6RjOAJ//UGSp/ySjHMmT8PLO7NvhsT4XDDGTSeIYYpO++tbEIcLcjW9m2k5Gnh\n" - + "kmEenr0hdcpeLgsP3Fsy7JxyQNpL\n" - + "-----END CERTIFICATE-----"; - - // Owner: CN=Actalis Authentication CA G3, O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // Issuer: CN=Actalis Authentication Root CA, O=Actalis S.p.A./03358520967, L=Milan, C=IT - // SN: 741d584a 72fc06bc - // Valid from: Wed Feb 12 22:32:23 PST 2014 - // Valid till: Mon Feb 12 22:32:23 PST 2024 - private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" - + "MIIGTTCCBDWgAwIBAgIIdB1YSnL8BrwwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\n" - + "BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w\n" - + "MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\n" - + "IENBMB4XDTE0MDIxMzE1MDIyM1oXDTI0MDIxMzE1MDIyM1owezELMAkGA1UEBhMC\n" - + "SVQxDzANBgNVBAgMBk1pbGFubzEPMA0GA1UEBwwGTWlsYW5vMSMwIQYDVQQKDBpB\n" - + "Y3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzElMCMGA1UEAwwcQWN0YWxpcyBBdXRo\n" - + "ZW50aWNhdGlvbiBDQSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" - + "AMzhDjmhNDym6ze3PegbIKmiavXpAjgVCZ344k1DOtdSCV6k3h3rqfHqFn3mrayA\n" - + "btmJ0NeC886WxUUsJwHJ3bOnNBQZIHxLV+1RVD/6TQqb6/bPJu4rDwEfhbJSmErc\n" - + "29wUJWqxXMhSAWTHi3Pq0vrkx59e5KTEyfB2kHo6InlR72sCCRdtCL9aDuDm8nYK\n" - + "pTSAJr36ultwME5NyCNSyN2JIK0wYbEi7MVNbp5KN9MusTp3cOMDoVBreYulmnEu\n" - + "TNazmoAv0K8oLS7iX7c9x+zGjUUAucFEuSlRn3sL6hFAiKjy4PDClvnyqQHBBdZr\n" - + "/3JOxAcgXv7aZ4/STeXeDXsCAwEAAaOCAeMwggHfMEEGCCsGAQUFBwEBBDUwMzAx\n" - + "BggrBgEFBQcwAYYlaHR0cDovL3BvcnRhbC5hY3RhbGlzLml0L1ZBL0FVVEgtUk9P\n" - + "VDAdBgNVHQ4EFgQUqqr9yowdTfEug+EG/PqO6g4jrj0wDwYDVR0TAQH/BAUwAwEB\n" - + "/zAfBgNVHSMEGDAWgBRS2Ig6yJ94Zu2J83s4cJTJAgI20DBUBgNVHSAETTBLMEkG\n" - + "BFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cHM6Ly9wb3J0YWwuYWN0YWxpcy5pdC9S\n" - + "ZXBvc2l0b3J5L1BvbGljeS9TU0wvQ1BTMIHiBgNVHR8EgdowgdcwgZSggZGggY6G\n" - + "gYtsZGFwOi8vbGRhcC5hY3RhbGlzLml0L2NuJTNkQWN0YWxpcyUyMEF1dGhlbnRp\n" - + "Y2F0aW9uJTIwUm9vdCUyMENBLG8lM2RBY3RhbGlzJTIwUy5wLkEuJTJmMDMzNTg1\n" - + "MjA5NjcsYyUzZElUP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q7YmluYXJ5MD6g\n" - + "PKA6hjhodHRwOi8vcG9ydGFsLmFjdGFsaXMuaXQvUmVwb3NpdG9yeS9BVVRILVJP\n" - + "T1QvZ2V0TGFzdENSTDAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIB\n" - + "ABP93l+9QBgzHF0Clf3gMAelGqwXT25DwZVFIkBw6YyqOPcaqzw1XKHJJEMQ8xOp\n" - + "8uuiPLP/ObxEXBBvH7ofNW7nRUIzGsuLPhzdfJhdzilCVAvz4WRsX44nWOQS4Qu0\n" - + "npo7dbq/KxFUCUO9yNEJp6YxNloy8XFIlazkHFTKGJqoUpsGoc7B9YmPchhE2FPb\n" - + "OZiOCg4Y2Qp43UJfnENgZ3gJFh16juQE1uS8Q/JJI7ZzJfJ/W0uQoDnCprOPUpLF\n" - + "G03e0asFxwQqhL84Jvf7rJZaWvwydHP4hH47nzpHWEGXwfJLXXoO7LHgqVB7K9Ar\n" - + "Zf3pY0S/3Fs+AN/PrEY3Z3rb7ypQLRiot1oJLl8matiGEF4aFL5DDkr9wfRAZ8S8\n" - + "WT69vN68ENGgEwyeZSlQxn+4g6quHRav0fmF2fGnLaq7tteSPVocT7XaMEpkHqNs\n" - + "x1q/PJbr39s/1QVZtS9CrdoCr0QAnBaX//PPB6ansSLFcvEqM9QcV9xQZex88ToX\n" - + "nk3TcHtA0ezWJlCkg626MhdQZrhHbkauHfIGSOmCkn3zHp0BZQ6Vo7UOdRMT7QS7\n" - + "y7AkET9Qmapwh2CFUdCJSXklVRd+06XhhOB37NQU0pGJQJ3xjEPrILZ8kLhW3Tyq\n" - + "Iv30LW7MXZ4yQn/JHEZbuiOOb4R45hsPZxe6gOq/e+sf\n" - + "-----END CERTIFICATE-----"; - - // Owner: CN=ssltest-r.actalis.it, O=Actalis S.p.A., L=Ponte San Pietro, ST=Bergamo, C=IT - // Issuer: CN=Actalis Authentication CA G3, O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // SN: 0455de97 5c71c96f - // Valid from: Thu Jan 28 16:23:52 PST 2016 - // Valid till: Mon Jan 28 16:23:52 PST 2019 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" - + "MIIFmDCCBICgAwIBAgIIBFXel1xxyW8wDQYJKoZIhvcNAQELBQAwezELMAkGA1UE\n" - + "BhMCSVQxDzANBgNVBAgMBk1pbGFubzEPMA0GA1UEBwwGTWlsYW5vMSMwIQYDVQQK\n" - + "DBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzElMCMGA1UEAwwcQWN0YWxpcyBB\n" - + "dXRoZW50aWNhdGlvbiBDQSBHMzAeFw0xNjAxMjkwODUzNTJaFw0xOTAxMjkwODUz\n" - + "NTJaMHIxCzAJBgNVBAYTAklUMRAwDgYDVQQIDAdCZXJnYW1vMRkwFwYDVQQHDBBQ\n" - + "b250ZSBTYW4gUGlldHJvMRcwFQYDVQQKDA5BY3RhbGlzIFMucC5BLjEdMBsGA1UE\n" - + "AwwUc3NsdGVzdC1yLmFjdGFsaXMuaXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n" - + "ggEKAoIBAQClbzoXCvD21FD7Oy/TKZu4fmDFJrISrNfasLlC3krLHkgb1vg23Z1P\n" - + "+7rIymDgrJSzjvYmisl+VM7xXxTsyI2pp9Qp/uzTMAMML9ISd/s0LaMBiNN5iPyj\n" - + "W91gGzGe30Jc319afKwFBaveSv7NO3DWsmHw9koezWkKUug2dnQCVXk1uTSdobnq\n" - + "wOgwxdd86LpZnFLxBIYdU68S4vogAQZjdja/S1+tF6JnfvY6o/xRJmQckVtNmUs6\n" - + "Dj3KoN2o/8BEgSCYcJz8tfoZcVazVkWOp/u6moUnm1/IKSYNgtHnB1ub0fB2AttW\n" - + "Vi7cs3SG/tDMMP8yc1kWScWf8CYj/AI1AgMBAAGjggInMIICIzA/BggrBgEFBQcB\n" - + "AQQzMDEwLwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwMDMuYWN0YWxpcy5pdC9WQS9B\n" - + "VVRILUczMB0GA1UdDgQWBBRIKN5WmrjivlnT1rDzsH1WZ+PuvTAMBgNVHRMBAf8E\n" - + "AjAAMB8GA1UdIwQYMBaAFKqq/cqMHU3xLoPhBvz6juoOI649MGAGA1UdIARZMFcw\n" - + "SwYGK4EfARQBMEEwPwYIKwYBBQUHAgEWM2h0dHBzOi8vcG9ydGFsLmFjdGFsaXMu\n" - + "aXQvUmVwb3NpdG9yeS9Qb2xpY3kvU1NML0NQUzAIBgZngQwBAgIwgd8GA1UdHwSB\n" - + "1zCB1DCBlKCBkaCBjoaBi2xkYXA6Ly9sZGFwMDMuYWN0YWxpcy5pdC9jbiUzZEFj\n" - + "dGFsaXMlMjBBdXRoZW50aWNhdGlvbiUyMENBJTIwRzMsbyUzZEFjdGFsaXMlMjBT\n" - + "LnAuQS4lMmYwMzM1ODUyMDk2NyxjJTNkSVQ/Y2VydGlmaWNhdGVSZXZvY2F0aW9u\n" - + "TGlzdDtiaW5hcnkwO6A5oDeGNWh0dHA6Ly9jcmwwMy5hY3RhbGlzLml0L1JlcG9z\n" - + "aXRvcnkvQVVUSC1HMy9nZXRMYXN0Q1JMMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE\n" - + "FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0RBBgwFoIUc3NsdGVzdC1yLmFj\n" - + "dGFsaXMuaXQwDQYJKoZIhvcNAQELBQADggEBAHZLND53/CZoMlDtfln0ZByCEhoF\n" - + "/XtA9cYy2azRGgS/VY4WUccvg99MM50cwn5GPRsJpoaFXeDrjV3DkOUK1jERzjx4\n" - + "5y83K/AkCGe7uU17aS+tweETizBAfHNj78oHmZDmkDSEY2STaeuHNDJ9ft0v3QTb\n" - + "VW54R5W3OBU7L/sJoEUdRxzGN7vO82PboGvyApMCWDRLKE7bPP4genQtF3XPcaFl\n" - + "ekuSiEVYS+KnM2v9tCWHqw6x7raWHFB9w1kAKNwv0hbEJkeC+a2bCdPwv8hs//sa\n" - + "gUF4p61mIpf+5qmQ6gcZOClPWyrbYdQdfCvKgbEdKhwB0v5KS0NIRRn41SE=\n" - + "-----END CERTIFICATE-----"; + // 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); - boolean ocspEnabled = false; if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { pathValidator.enableCRLCheck(); } else { // OCSP check by default pathValidator.enableOCSPCheck(); - ocspEnabled = true; } // Validate valid - pathValidator.validate(new String[]{VALID, INT_VALID}, + pathValidator.validate(new String[]{VALID, INT}, ValidatePathWithParams.Status.GOOD, null, System.out); - // Revoked certificate is using SHA1 signature - if (ocspEnabled) { - // Revoked test certificate is expired - // and backdated revocation check is only possible with OCSP - pathValidator.setValidationDate("July 01, 2016"); - } - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, + pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Fri Jan 29 01:06:42 PST 2016", System.out); - - // reset validation date back to current date - pathValidator.resetValidationDate(); + "Tue Sep 27 03:52:40 PDT 2022", System.out); } } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java --- openjdk-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,621 @@ +/* + * 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-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java --- openjdk-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,348 @@ +/* + * 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-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java --- openjdk-17-17.0.7+7~us1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,206 @@ +/* + * 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-17-17.0.7+7~us1/test/jdk/sun/management/jmxremote/startstop/JMXStatusTest.java openjdk-17-17.0.8+7/test/jdk/sun/management/jmxremote/startstop/JMXStatusTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/management/jmxremote/startstop/JMXStatusTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/management/jmxremote/startstop/JMXStatusTest.java 2023-07-05 07:11:54.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 @@ -33,7 +33,7 @@ /** * @test - * @bug 8023093 8138748 8142398 + * @bug 8023093 8138748 8142398 8303102 * @summary Performs a sanity test for the ManagementAgent.status diagnostic command. * Management agent may be disabled, started (only local connections) and started. * The test asserts that the expected text is being printed. diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java openjdk-17-17.0.8+7/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,1272 @@ +/* + * Copyright (c) 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 + * @library /test/lib + * @bug 8291226 8291638 + * @modules java.base/sun.net:+open + * java.base/sun.net.www.http:+open + * java.base/sun.net.www:+open + * java.base/sun.net.www.protocol.http:+open + * @run main/othervm KeepAliveTest 0 + * @run main/othervm KeepAliveTest 1 + * @run main/othervm KeepAliveTest 2 + * @run main/othervm KeepAliveTest 3 + * @run main/othervm KeepAliveTest 4 + * @run main/othervm KeepAliveTest 5 + * @run main/othervm KeepAliveTest 6 + * @run main/othervm KeepAliveTest 7 + * @run main/othervm KeepAliveTest 8 + * @run main/othervm KeepAliveTest 9 + * @run main/othervm KeepAliveTest 10 + * @run main/othervm KeepAliveTest 11 + * @run main/othervm KeepAliveTest 12 + * @run main/othervm KeepAliveTest 13 + * @run main/othervm KeepAliveTest 14 + * @run main/othervm KeepAliveTest 15 + * @run main/othervm KeepAliveTest 16 + * @run main/othervm KeepAliveTest 17 + * @run main/othervm KeepAliveTest 18 + * @run main/othervm KeepAliveTest 19 + * @run main/othervm KeepAliveTest 20 + * @run main/othervm KeepAliveTest 21 + * @run main/othervm KeepAliveTest 22 + * @run main/othervm KeepAliveTest 23 + * @run main/othervm KeepAliveTest 24 + * @run main/othervm KeepAliveTest 25 + * @run main/othervm KeepAliveTest 26 + * @run main/othervm KeepAliveTest 27 + * @run main/othervm KeepAliveTest 28 + * @run main/othervm KeepAliveTest 29 + * @run main/othervm KeepAliveTest 30 + * @run main/othervm KeepAliveTest 31 + * @run main/othervm KeepAliveTest 32 + * @run main/othervm KeepAliveTest 33 + * @run main/othervm KeepAliveTest 34 + * @run main/othervm KeepAliveTest 35 + * @run main/othervm KeepAliveTest 36 + * @run main/othervm KeepAliveTest 37 + * @run main/othervm KeepAliveTest 38 + * @run main/othervm KeepAliveTest 39 + * @run main/othervm KeepAliveTest 40 + * @run main/othervm KeepAliveTest 41 + * @run main/othervm KeepAliveTest 42 + * @run main/othervm KeepAliveTest 43 + * @run main/othervm KeepAliveTest 44 + * @run main/othervm KeepAliveTest 45 + * @run main/othervm KeepAliveTest 46 + * @run main/othervm KeepAliveTest 47 + * @run main/othervm KeepAliveTest 48 + * @run main/othervm KeepAliveTest 49 + * @run main/othervm KeepAliveTest 50 + * @run main/othervm KeepAliveTest 51 + * @run main/othervm KeepAliveTest 52 + * @run main/othervm KeepAliveTest 53 + * @run main/othervm KeepAliveTest 54 + * @run main/othervm KeepAliveTest 55 + * @run main/othervm KeepAliveTest 56 + * @run main/othervm KeepAliveTest 57 + * @run main/othervm KeepAliveTest 58 + * @run main/othervm KeepAliveTest 59 + * @run main/othervm KeepAliveTest 60 + * @run main/othervm KeepAliveTest 61 + * @run main/othervm KeepAliveTest 62 + * @run main/othervm KeepAliveTest 63 + * @run main/othervm KeepAliveTest 64 + * @run main/othervm KeepAliveTest 65 + * @run main/othervm KeepAliveTest 66 + * @run main/othervm KeepAliveTest 67 + * @run main/othervm KeepAliveTest 68 + * @run main/othervm KeepAliveTest 69 + * @run main/othervm KeepAliveTest 70 + * @run main/othervm KeepAliveTest 71 + * @run main/othervm KeepAliveTest 72 + * @run main/othervm KeepAliveTest 73 + * @run main/othervm KeepAliveTest 74 + * @run main/othervm KeepAliveTest 75 + * @run main/othervm KeepAliveTest 76 + * @run main/othervm KeepAliveTest 77 + * @run main/othervm KeepAliveTest 78 + * @run main/othervm KeepAliveTest 79 + * @run main/othervm KeepAliveTest 80 + * @run main/othervm KeepAliveTest 81 + * @run main/othervm KeepAliveTest 82 + * @run main/othervm KeepAliveTest 83 + * @run main/othervm KeepAliveTest 84 + * @run main/othervm KeepAliveTest 85 + * @run main/othervm KeepAliveTest 86 + * @run main/othervm KeepAliveTest 87 + * @run main/othervm KeepAliveTest 88 + * @run main/othervm KeepAliveTest 89 + * @run main/othervm KeepAliveTest 90 + * @run main/othervm KeepAliveTest 91 + * @run main/othervm KeepAliveTest 92 + * @run main/othervm KeepAliveTest 93 + * @run main/othervm KeepAliveTest 94 + * @run main/othervm KeepAliveTest 95 + * @run main/othervm KeepAliveTest 96 + * @run main/othervm KeepAliveTest 97 + * @run main/othervm KeepAliveTest 98 + * @run main/othervm KeepAliveTest 99 + * @run main/othervm KeepAliveTest 100 + * @run main/othervm KeepAliveTest 101 + * @run main/othervm KeepAliveTest 102 + * @run main/othervm KeepAliveTest 103 + * @run main/othervm KeepAliveTest 104 + * @run main/othervm KeepAliveTest 105 + * @run main/othervm KeepAliveTest 106 + * @run main/othervm KeepAliveTest 107 + * @run main/othervm KeepAliveTest 108 + * @run main/othervm KeepAliveTest 109 + * @run main/othervm KeepAliveTest 110 + * @run main/othervm KeepAliveTest 111 + * @run main/othervm KeepAliveTest 112 + * @run main/othervm KeepAliveTest 113 + * @run main/othervm KeepAliveTest 114 + * @run main/othervm KeepAliveTest 115 + * @run main/othervm KeepAliveTest 116 + * @run main/othervm KeepAliveTest 117 + * @run main/othervm KeepAliveTest 118 + * @run main/othervm KeepAliveTest 119 + * @run main/othervm KeepAliveTest 120 + * @run main/othervm KeepAliveTest 121 + * @run main/othervm KeepAliveTest 122 + * @run main/othervm KeepAliveTest 123 + * @run main/othervm KeepAliveTest 124 + * @run main/othervm KeepAliveTest 125 + * @run main/othervm KeepAliveTest 126 + * @run main/othervm KeepAliveTest 127 + * @run main/othervm KeepAliveTest 128 + * @run main/othervm KeepAliveTest 129 + * @run main/othervm KeepAliveTest 130 + * @run main/othervm KeepAliveTest 131 + * @run main/othervm KeepAliveTest 132 + * @run main/othervm KeepAliveTest 133 + * @run main/othervm KeepAliveTest 134 + * @run main/othervm KeepAliveTest 135 + * @run main/othervm KeepAliveTest 136 + * @run main/othervm KeepAliveTest 137 + * @run main/othervm KeepAliveTest 138 + * @run main/othervm KeepAliveTest 139 + * @run main/othervm KeepAliveTest 140 + * @run main/othervm KeepAliveTest 141 + * @run main/othervm KeepAliveTest 142 + * @run main/othervm KeepAliveTest 143 + * @run main/othervm KeepAliveTest 144 + * @run main/othervm KeepAliveTest 145 + * @run main/othervm KeepAliveTest 146 + * @run main/othervm KeepAliveTest 147 + * @run main/othervm KeepAliveTest 148 + * @run main/othervm KeepAliveTest 149 + * @run main/othervm KeepAliveTest 150 + * @run main/othervm KeepAliveTest 151 + * @run main/othervm KeepAliveTest 152 + * @run main/othervm KeepAliveTest 153 + * @run main/othervm KeepAliveTest 154 + * @run main/othervm KeepAliveTest 155 + * @run main/othervm KeepAliveTest 156 + * @run main/othervm KeepAliveTest 157 + * @run main/othervm KeepAliveTest 158 + * @run main/othervm KeepAliveTest 159 + */ + +import java.nio.charset.StandardCharsets; +import java.io.InputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.Proxy.Type; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URL; +import java.util.List; +import java.util.Map.Entry; +import java.util.concurrent.CountDownLatch; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import sun.net.www.http.HttpClient; +import sun.net.www.http.KeepAliveCache; +import sun.net.www.protocol.http.HttpURLConnection; +import jdk.test.lib.net.URIBuilder; + +public class KeepAliveTest { + private static final Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); + private static final String NOT_CACHED = "NotCached"; + private static final String CLIENT_SEPARATOR = ";"; + private static final String NEW_LINE = "\r\n"; + private volatile int SERVER_PORT = 0; + /* + * isProxySet is shared variable between server thread and client thread(main) and it should be set and reset to false for each and + * every scenario. + * isProxySet variable should be set by server thread before proceeding to client thread(main). + */ + private volatile boolean isProxySet = false; + private static final String CONNECTION_KEEP_ALIVE_ONLY = "Connection: keep-alive"; + private static final String PROXY_CONNECTION_KEEP_ALIVE_ONLY = "Proxy-Connection: keep-alive"; + private static final String KEEP_ALIVE_TIMEOUT_NEG = "Keep-alive: timeout=-20"; + private static final String KEEP_ALIVE_TIMEOUT_ZERO = "Keep-alive: timeout=0"; + private static final String KEEP_ALIVE_TIMEOUT = "Keep-alive: timeout=20"; + private static final String KEEP_ALIVE_PROXY_TIMEOUT = "Keep-alive: timeout=120"; + private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_NEGATIVE = "http.keepAlive.time.server=-100"; + private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_NEGATIVE = "http.keepAlive.time.proxy=-200"; + private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_ZERO = "http.keepAlive.time.server=0"; + private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_ZERO = "http.keepAlive.time.proxy=0"; + private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_POSITIVE = "http.keepAlive.time.server=100"; + private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_POSITIVE = "http.keepAlive.time.proxy=200"; + private static final String CONNECTION_KEEP_ALIVE_WITH_TIMEOUT = CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + + KEEP_ALIVE_TIMEOUT; + /* + * Following Constants represents Client Side Properties and is used as reference in below table as + * CLIENT_INPUT_CONSTANT_NAMES + */ + private static final String SERVER_100_NEGATIVE = CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_NEGATIVE; + private static final String PROXY_200_NEGATIVE = CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_NEGATIVE; + private static final String SERVER_ZERO = CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_ZERO; + private static final String PROXY_ZERO = CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_ZERO; + private static final String SERVER_100 = CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_POSITIVE; + private static final String PROXY_200 = CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_POSITIVE; + + /* + * CONSTANTS A,B,C,D,E,NI,F,G,H,I represents ServerScenarios and is used as reference in below table + * as SERVER_RESPONSE_CONSTANT_NAME + */ + private static final String A = CONNECTION_KEEP_ALIVE_ONLY; + private static final String B = CONNECTION_KEEP_ALIVE_WITH_TIMEOUT; + private static final String C = PROXY_CONNECTION_KEEP_ALIVE_ONLY; + private static final String D = PROXY_CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + CONNECTION_KEEP_ALIVE_ONLY; + private static final String E = C + NEW_LINE + KEEP_ALIVE_PROXY_TIMEOUT; + private static final String NI = "NO_INPUT"; + private static final String F = A + NEW_LINE + KEEP_ALIVE_TIMEOUT_NEG; + private static final String G = A + NEW_LINE + KEEP_ALIVE_TIMEOUT_ZERO; + private static final String H = C + NEW_LINE + KEEP_ALIVE_TIMEOUT_NEG; + private static final String I = C + NEW_LINE + KEEP_ALIVE_TIMEOUT_ZERO; + + /* + * There are 160 scenarios run by this program. + * For every scenario there is mapping between serverScenarios[int],clientScenarios[int] and expectedOutput[int] + * + * serverScenarios[0] clientScenarios[0] expectedOutput[0] + * serverScenarios[1] clientScenarios[1] expectedOutput[1] + * serverScenarios[2] clientScenarios[2] expectedOutput[2] + * + * ... + * + * serverScenarios[159] cientScenarios[159] expectedOutput[159] + * + * whereas serverScenarios[int] is retrieved using getServerScenario(int) + * whereas clientScenarios[int] is retrieved using clientScenario[getClientScenarioNumber[int]] + * and + * expectedOutput[int] is retrieved using expectedOuput[int] directly. + * + */ + + /* Here is the complete table of server_response, client system properties input and expected cached timeout at client side */ + /* ScNo | SERVER RESPONSE (SERVER_RESPONSE_CONSTANT_NAME)| CLIENT SYSTEM PROPERTIES INPUT (CLIENT_INPUT_CONSTANT_NAMES) | EXPECTED CACHED TIMEOUT AT CLIENT SIDE + ***************************************************************************************************************************************** + * 0 | Connection: keep-alive (A) | No Input Provided (NI) | Default Timeout set to 5 + *--------------------------------------------------------------------------------------------------------------------------- + * 1 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 (SERVER_100)| Client Timeout set to 100 + *-------------------------------------------------------------------------------------------------------------------------- + * 2 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.proxy=200 (PROXY_200) | Default Timeout set to 5 + *--------------------------------------------------------------------------------------------------------------------------- + * 3 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 100 + * | | (SERVER_100 && PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 4 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 | Default Timeout set to 5 + * | | (SERVER_100_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 5 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.proxy=-200 | Default Timeout set to 5 + * | | (PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 6 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Default Timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 7 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 | Connection Closed Immediately + * | | (SERVER_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 8 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.proxy=0 | Default Timeout set to 5 + * | | (PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 9 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Connection Closed Immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 10 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Connection Closed Immediately + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 11 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Default Timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 12 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 100 + * | | (SERVER_100 && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 13 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Connection Closed Immediately + * | | (SERVER_ZERO && PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 14 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 100 + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 15 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Default Timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 16 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | No Input Provided (NI) | Timeout set to 20 + *------------------------------------------------------------------------------------------------------------------------ + * 17 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 | Timeout set to 20 + * | | (SERVER_100) | + *--------------------------------------------------------------------------------------------------------------------------- + * 18 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 + * | | (PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 19 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 + * | | (SERVER_100 && PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 20 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=-100 | Timeout set to 20 + * | | (SERVER_100_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 21 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 + * | | (PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 22 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| + *--------------------------------------------------------------------------------------------------------------------------- + * 23 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 | Timeout set to 20 + * | | (SERVER_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 24 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 + * | | (PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 25 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 + * | | (SERVER_ZERO && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 26 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 27 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 28 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 + * | | (SERVER_100 && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 29 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 + * | | (SERVER_ZERO && PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 30 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 31 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 32 |Proxy-Connection: keep-alive (C) | No Input Provided (NI) | Default timeout set to 60 + *--------------------------------------------------------------------------------------------------------------------------- + * 33 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=100 | Default timeout set to 60 + * | | (SERVER_100) | + *--------------------------------------------------------------------------------------------------------------------------- + * 34 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------- + * 35 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_100 && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------- + * 36 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=-100 | Default timeout set to 60 + * | | (SERVER_100_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 37 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 + * | | (PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 38 |Proxy-Connection: keep-alive (C) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 + * | |(SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| + *--------------------------------------------------------------------------------------------------------------------------- + * 39 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 | Default timeout set to 60 + * | | (SERVER_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 40 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 41 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 42 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------------- + * 43 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------------- + * 44 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100 && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 45 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_ZERO && PROXY_200) | + *--------------------------------------------------------------------------------------------------------------------------- + * 46 |Proxy-Connection: keep-alive (C) |-Dhttp.keepAlive.time.server=100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------- + * 47 |Proxy-Connection: keep-alive (C) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------- + * 48 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | No Input Provided (NI) | Default timeout set to 60 + *----------------------------------------------------------------------------------------------------------------------------- + * 49 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 | Default timeout set to 60 + * | | (SERVER_100) | + *--------------------------------------------------------------------------------------------------------------------------- + * 50 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------ + * 51 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_100 && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------ + * 52 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100 | Default timeout set to 60 + * | | (SERVER_100_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------ + * 53 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 + * | | (PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------ + * 54 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100&& | + * | | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE | + *------------------------------------------------------------------------------------------------------------------------------- + * 55 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 | Default timeout set to 60 + * | | (SERVER_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 56 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 57 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 58 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 59 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 60 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100 && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 61 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_ZERO && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------ + * 62 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------ + * 63 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------- + * 64 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| No Input Provided (NI) | Timeout set to 120 + *------------------------------------------------------------------------------------------------------------------------------- + * 65 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 | Timeout set to 120 + * | | (SERVER_100) | + *------------------------------------------------------------------------------------------------------------------------------- + * 66 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 + * | | (PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------- + * 67 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 + * | | (SERVER_100 && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------- + * 68 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 | Timeout set to 120 + * | | (SERVER_100_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------- + * 69 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 + * | | (PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------- + * 70 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| + *------------------------------------------------------------------------------------------------------------------------------- + * 71 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 | Timeout set to 120 + * | | (SERVER_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------- + * 72 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 + * | | (PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------- + * 73 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 + * | | (SERVER_ZERO && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------- + * 74 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------- + * 75 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------- + * 76 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 + * | | (SERVER_100 && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------- + * 77 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 + * | | (SERVER_ZERO && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------- + * 78 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------- + * 79 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *----------------------------------------------------------------------------------------------------------------------------- + * 80 |No Input (NI) | No Input Provided (NI) | default timeout set to 5 + *----------------------------------------------------------------------------------------------------------------------------- + * 81 |No Input (NI) | -Dhttp.keepAlive.time.server=100 | Timeout set to 100 + * | | (SERVER_100) | + *----------------------------------------------------------------------------------------------------------------------------- + * 82 |No Input (NI) | -Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 + * | | (PROXY_200) | + *----------------------------------------------------------------------------------------------------------------------------- + * 83 |No Input (NI) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | client timeot set to 100 + * | | (SERVER_100 && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------ + * 84 |No Input (NI) | -Dhttp.keepAlive.time.server=-100 | default timeout set to 5 + * | | (SERVER_100_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------ + * 85 |No Input (NI) | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 + * | | (PROXY_200_NEGATIVE) | + *---------------------------------------------------------------------------------------------------------------------------- + * 86 |No Input (NI) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| + *------------------------------------------------------------------------------------------------------------------------------ + * 87 |No Input (NI) | -Dhttp.keepAlive.time.server=0 | close connection immediately + * | | (SERVER_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------------- + * 88 |No Input (NI) | -Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 + * | | (PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------------- + * 89 |No Input (NI) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------------- + * 90 |No Input (NI) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 91 |No Input (NI) | -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 92 |No Input (NI) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 100 + * | | (SERVER_100 && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 93 |No Input (NI) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_ZERO && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 94 |No Input (NI) |-Dhttp.keepAlive.time.server=100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | Timeout set to 100 + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 95 |No Input (NI) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 96 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) | No Input Provided (NI) | default timeout set to 5 + *-------------------------------------------------------------------------------------------------------------------------------- + * 97 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 | Timeout set to 100 + * | | (SERVER_100) | + *-------------------------------------------------------------------------------------------------------------------------------- + * 98 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 + * | | (PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 99 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 && | + * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 100 + * | |(SERVER_100 && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 100 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 | default timeout set to 5 + * | |(SERVER_100_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 101 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 + * | |(PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 102 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| + *------------------------------------------------------------------------------------------------------------------------------------- + * 103 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 | close connection immediately + * | | (SERVER_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 104 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 + * | | (PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 105 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 106 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO_NEGATIVE)| + *------------------------------------------------------------------------------------------------------------------------------------- + * 107 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 108 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 && | + * | |-Dhttp.keepAlive.time.proxy=0 | Timeout set to 100 + * | | (SERVER_100 && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 109 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 && | + * | |-Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_ZERO && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 110 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | Timeout set to 100 + * | |(SERVER_100 && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 111 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 112 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | No Input Provided (NI) | close connection immediately + *------------------------------------------------------------------------------------------------------------------------------------- + * 113 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 | close connection immediately + * | | (SERVER_100) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 114 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 115 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_100 && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 116 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=-100 | close connection immediately + * | | (SERVER_100_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------ + * 117 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 118 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) |-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 119 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 | close connection immediately + * | | (SERVER_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 120 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------ + * 121 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 122 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 123 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 124 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100 && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 125 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_ZERO && PROXY_200) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 126 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 127 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=-100 &&| + * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 128 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| No Input Provided (NI) | default timeout set to 60 + --------------------------------------------------------------------------------------------------------------------------------------- + * 129 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=100 | default timeout set to 60 + * | | (SERVER_100) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 130 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 131 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_100 && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 132 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=-100 | default timeout set to 60 + * | | (SERVER_100_NEGATIVE) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 133 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 + * | | (PROXY_200_NEGATIVE) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 134 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)|-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| + *--------------------------------------------------------------------------------------------------------------------------------- + * 135 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 | default timeout set to 60 + * | | (SERVER_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 136 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (PROXY_ZERO) | + *---------------------------------------------------------------------------------------------------------------------------------- + * 137 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 138 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *--------------------------------------------------------------------------------------------------------------------------------------- + * 139 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 140 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100 && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 141 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 + * | | (SERVER_ZERO && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 142 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)|-Dhttp.keepAlive.time.server=100 && | + * | |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 143 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)|-Dhttp.keepAlive.time.server=-100 && | + * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 144 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | No Input Provided (NI) | close connection immediately + *-------------------------------------------------------------------------------------------------------------------------------------- + * 145 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 | close connection immediately + * | | (SERVER_100) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 146 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 147 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_100 && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 148 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 | close connection immediately + * | | (SERVER_100_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 149 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 150 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | + *------------------------------------------------------------------------------------------------------------------------------------ + * 151 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 | close connection immediately + * | | (SERVER_ZERO) | + *----------------------------------------------------------------------------------------------------------------------------------- + * 152 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (PROXY_ZERO) | + *--------------------------------------------------------------------------------------------------------------------------------- + * 153 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_ZERO && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------ + * 154 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 155 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | + *------------------------------------------------------------------------------------------------------------------------------------- + * 156 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately + * | | (SERVER_100 && PROXY_ZERO) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 157 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 && | + * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_ZERO && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 158 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 && | + * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately + * | | (SERVER_100 && PROXY_200_NEGATIVE) | + *-------------------------------------------------------------------------------------------------------------------------------------- + * 159 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 && | + * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately + * | | (SERVER_100_NEGATIVE && PROXY_200) | + *-------------------------------------------------------------------------------------------------------------------------------------- + */ + + /* private static final String[] serverScenarios = { + A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, + B, B, B, B, B, B, B, B, B, B,B, B, B, B, B, B, + C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, + D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, + E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, + NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, + F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, + G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I + }; */ + /* + * following are client scenarios which are repeated. + */ + private static final String[] a = { + NI, SERVER_100, PROXY_200, SERVER_100 + CLIENT_SEPARATOR + PROXY_200, SERVER_100_NEGATIVE, + PROXY_200_NEGATIVE, SERVER_100_NEGATIVE + CLIENT_SEPARATOR + PROXY_200_NEGATIVE, + SERVER_ZERO, PROXY_ZERO, SERVER_ZERO + CLIENT_SEPARATOR + PROXY_ZERO, + SERVER_ZERO + CLIENT_SEPARATOR + PROXY_200_NEGATIVE, SERVER_100_NEGATIVE + CLIENT_SEPARATOR + PROXY_ZERO, + SERVER_100 + CLIENT_SEPARATOR + PROXY_ZERO, SERVER_ZERO + CLIENT_SEPARATOR + PROXY_200, + SERVER_100 + CLIENT_SEPARATOR + PROXY_200_NEGATIVE, SERVER_100_NEGATIVE + CLIENT_SEPARATOR + PROXY_200 + }; + + /* private String[] clientScenarios = { + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + }; */ + + private static final String[] clientScenarios = { + a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15] + }; + + private static final int[] expectedValues = { + 5, 100, 5, 100, 5, 5, 5, 0, 5, 0, 0, 5, 100, 0, 100, 5, + 20, 20 , 20, 20, 20, 20, 20, 20, 20, 20 , 20, 20, 20, 20, 20, 20, + 60, 60, 200, 200, 60, 60, 60, 60, 0, 0, 60, 0, 0, 200, 60, 200, + 60, 60, 200, 200, 60, 60, 60, 60, 0, 0, 60, 0, 0, 200, 60, 200, + 120, 120, 120, 120,120,120,120,120,120, 120, 120, 120, 120, 120, 120, 120, + 5, 100, 5, 100, 5, 5, 5, 0, 5, 0, 0, 5, 100, 0, 100, 5, + 5, 100, 5, 100, 5, 5, 5, 0, 5, 0, 0, 5, 100, 0, 100, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 60, 60, 200, 200, 60, 60, 60, 60, 0, 0, 60, 0, 0, 200, 60, 200, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + private final CountDownLatch countDownLatch = new CountDownLatch(1); + + private final CountDownLatch serverCountDownLatch = new CountDownLatch(1); + + /* + * setting of client properties -Dhttp.keepAlive.time.server and -Dhttp.keepAlive.time.proxy is handled through this method. + * There are 16 client scenarios in total starting with scenarioNumber 0(zero) and ending with 15. + * Server Scenarios are grouped into batch of 16 scenarios. + * There are 10 batches in total and each batch contains 16 scenarios so 10 * 16 = 160 scenarios in total. + * 16 Client Scenarios are used repeatedly for every server scenario batch. + * for serverscenario[0],serverscenario[16],serverscenario[32] ... serverscenario[144] is mapped to clientscenario[0] + * for serverscenario[1],serverscenario[17],serverscenario[33] ... serverscenario[145] is mapped to clientscenario[1] + * for serverscenario[2],serverscenario[18],serverscenario[34] ... serverscenario[146] is mapped to clientscenario[2] + * ... + * for serverscenario[15],serverscenario[31],serverscenario[47] ... serverscenario[159] is mapped to clientscenario[15] + */ + private int getClientScenarioNumber(int scenarioNumber) { + return scenarioNumber % 16 ; + } + + /* + * Returns SERVER_RESPONSE as String based on integer inputParameter scenarioNumber. + * Server Scenarios are grouped into batch of 16 scenarios starting with scenarioNumber 0 (zero) + * so there are 10 batches in total and each batch contains 16 scenarios so 10 * 16 = 160 scenarios in total. + * For each batch of 16 scenarios, there will be common SERVER_RESPONSE for all 16 scenarios in batch. + * for scenario numbers from 0 to 15 server response is: Connection:keep-alive + * for scenario numbers from 16 to 31 server response is: SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=20 + * for scenario numbers from 32 to 47 server response is: SERVER_RESPONSE=Proxy-Connection: keep-alive + * for scenario numbers from 48 to 63 server response is: SERVER_RESPONSE=Connection:keep-alive\r\nProxy-connection:keep-alive + * for scenario numbers from 64 to 79 server response is: SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 + * for scenario numbers from 80 to 95 server response is: SERVER_RESPONSE=No Input + * for scenario numbers from 96 to 111 server response is: SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=-20 + * for scenario numbers from 112 to 127 server resonse is: Connection: keep-alive\r\nKeep-alive: timeout=0 + * for scenario numbers from 128 to 143 server response is: Proxy-connection:keep-alive\r\nKeep-alive:timeout=-20 + * for scenario numbers from 144 to 159 server response is: Proxy-connection:keep-alive\r\nKeep-alive:timeout=0 + */ + private String getServerScenario(int scenarioNumber) { + /* + * ServerResponse for scenarios from 0 to 15 + * SERVER_RESPONSE:Connection:keep-alive + */ + if(scenarioNumber >= 0 && scenarioNumber <= 15) { + return A; + } + /* + * ServerResponse for scenarios from 16 to 31 + * SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=20 + */ + else if (scenarioNumber >= 16 && scenarioNumber <= 31){ + return B; + } + /* + * ServerResponse for scenarios from 32 to 47 + * SERVER_RESPONSE=Proxy-Connection: keep-alive + */ + else if (scenarioNumber >= 32 && scenarioNumber <= 47){ + return C; + } + /* + * ServerResponse for scenarios from 48 to 63 + * SERVER_RESPONSE=Connection:keep-alive\r\nProxy-connection:keep-alive + */ + else if (scenarioNumber >= 48 && scenarioNumber <= 63){ + return D; + /* + * ServerResponse for scenarios from 64 to 79 + * SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 + */ + } else if (scenarioNumber >= 64 && scenarioNumber <= 79){ + return E; + } + /* + * ServerResponse for scenarios from 80 to 95 + * SERVER_RESPONSE=No Input + */ + else if (scenarioNumber >= 80 && scenarioNumber <= 95){ + return NI; + } + /* + * ServerResponse for scenarios from 96 to 111 + * SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=-20 + */ + else if (scenarioNumber >= 96 && scenarioNumber <= 111){ + return F; + } + /* + * ServerResponse for scenarios from 112 to 127 + * SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=0 + */ + else if (scenarioNumber >= 112 && scenarioNumber <= 127){ + return G; + } + /* + * ServerResponse for scenarios from 128 to 143 + * SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=-20 + */ + else if (scenarioNumber >= 128 && scenarioNumber <= 143){ + return H; + } + /* + * ServerResponse for scenarios from 144 to 159 + * SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=0 + */ + else if (scenarioNumber >= 144 && scenarioNumber <= 159){ + return I; + } + /*Invalid Case*/ + return null; + } + + private void startScenario(int scenarioNumber) throws Exception { + System.out.println("serverScenarios[" + scenarioNumber + "]=" + getServerScenario(scenarioNumber)); + System.out.println("clientScenarios[" + scenarioNumber + "]=" + clientScenarios[getClientScenarioNumber(scenarioNumber)]); + if(expectedValues[scenarioNumber] == 0) { + System.out.println("ExpectedOutput=" + NOT_CACHED); + } else { + System.out.println("ExpectedOutput=" + expectedValues[scenarioNumber]); + } + System.out.println(); + startServer(scenarioNumber); + runClient(scenarioNumber); + } + + private void startServer(int scenarioNumber) { + Thread server = new Thread(new Runnable() { + @Override + public void run() { + try { + executeServer(scenarioNumber); + } catch (IOException e) { + e.printStackTrace(); + } + } + }, "SERVER"); + server.start(); + } + + private void readAll(Socket s) throws IOException { + byte[] buf = new byte[128]; + int c; + String request = ""; + InputStream is = s.getInputStream(); + while ((c = is.read(buf)) > 0) { + request += new String(buf, 0, c, StandardCharsets.US_ASCII); + if (request.contains("\r\n\r\n")) { + return; + } + } + if (c == -1) { + throw new IOException("Socket closed"); + } + } + + private void executeServer(int scenarioNumber) throws IOException { + String serverScenarioContent = null; + if (!getServerScenario(scenarioNumber).equalsIgnoreCase(NI)) { + serverScenarioContent = getServerScenario(scenarioNumber) + NEW_LINE; + /* + * isProxySet should be set before Server is moved to Listen State. + */ + if (serverScenarioContent.contains("Proxy")) { + isProxySet = true; + } else { + isProxySet = false; + } + } + ServerSocket serverSocket = null; + Socket socket = null; + OutputStreamWriter out = null; + InetAddress loopback = InetAddress.getLoopbackAddress(); + try { + serverSocket = new ServerSocket(); + serverSocket.bind(new InetSocketAddress(loopback, 0)); + SERVER_PORT = serverSocket.getLocalPort(); + //serverReady = true; + this.serverCountDownLatch.countDown(); + System.out + .println("SERVER_PORT= " + SERVER_PORT +" isProxySet=" + isProxySet); + /* + * Server will be waiting for clients to connect. + */ + socket = serverSocket.accept(); + readAll(socket); + out = new OutputStreamWriter(socket.getOutputStream()); + String BODY = "SERVER REPLY: Hello world"; + String CLEN = "Content-Length: " + BODY.length() + NEW_LINE; + /* send the header */ + out.write("HTTP/1.1 200 OK\r\n"); + out.write("Content-Type: text/plain; charset=iso-8859-1\r\n"); + /* + * append each scenario content from array. + */ + if(serverScenarioContent != null) { + out.write(serverScenarioContent); + } + out.write(CLEN); + out.write(NEW_LINE); + out.write(BODY); + out.flush(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (out != null) { + out.flush(); + out.close(); + } + if (socket != null) { + socket.close(); + } + if (serverSocket != null) { + serverSocket.close(); + } + } + } + + private void runClient(int scenarioNumber) throws Exception { + try { + connectToServerURL(scenarioNumber); + } finally { + System.out.println("client count down latch:" + scenarioNumber); + this.countDownLatch.countDown(); + System.out.println(); + System.out.println(); + } + } + + private void connectToServerURL(int scenarioNumber) throws Exception { + // System.setProperty("java.net.useSystemProxies", "false"); + // System.setProperty("http.nonProxyHosts", ""); + // System.setProperty("http.proxyHost", "localhost"); + // System.setProperty("http.proxyPort", String.valueOf(SERVER_PORT)); + System.out.println("Following are Existing System Properties if set any"); + System.out.println("http.keepAlive.time.server:" + System.getProperty("http.keepAlive.time.server")); + System.out.println("http.keepAlive.time.proxy:" + System.getProperty("http.keepAlive.time.proxy")); + System.setProperty("java.net.useSystemProxies", "false"); + System.out.println("http.proxyPort:"+System.getProperty("http.proxyPort")); + System.out.println("http.proxyHost:"+System.getProperty("http.proxyHost")); + System.clearProperty("http.keepAlive.time.server"); + System.clearProperty("http.keepAlive.time.proxy"); + // fetch clientScenearios for each scenarioNumber from array and set it to + // System property. + if (!clientScenarios[getClientScenarioNumber(scenarioNumber)].equalsIgnoreCase(NI)) { + System.out.println("Client Input Parsing"); + for (String clientScenarioString : clientScenarios[getClientScenarioNumber(scenarioNumber)].split(CLIENT_SEPARATOR)) { + System.out.println(clientScenarioString); + String key = clientScenarioString.split("=")[0]; + String value = clientScenarioString.split("=")[1]; + System.setProperty(key, value); + } + } + // wait until ServerSocket moves to listening state. + this.serverCountDownLatch.await(); + System.out.println("client started"); + URL url = URIBuilder.newBuilder().scheme("http").loopback().port(SERVER_PORT).toURL(); + System.out.println("connecting from client to SERVER URL:" + url); + HttpURLConnection httpUrlConnection = null; + /* + * isProxySet is set to true when Expected Server Response contains Proxy-Connection header. + */ + if (isProxySet) { + httpUrlConnection = (sun.net.www.protocol.http.HttpURLConnection) url + .openConnection(new Proxy(Type.HTTP, new InetSocketAddress("localhost", SERVER_PORT))); + } else { + httpUrlConnection = (sun.net.www.protocol.http.HttpURLConnection) url.openConnection(); + } + InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getInputStream()); + BufferedReader bufferedReader = null; + try { + bufferedReader = new BufferedReader(inputStreamReader); + while (true) { + String eachLine = bufferedReader.readLine(); + if (eachLine == null) { + break; + } + System.out.println(eachLine); + } + } finally { + if (bufferedReader != null) { + bufferedReader.close(); + } + } + // System.out.println("ResponseCode:" + httpUrlConnection.getResponseCode()); + // System.out.println("ResponseMessage:" + httpUrlConnection.getResponseMessage()); + // System.out.println("Content:" + httpUrlConnection.getContent()); + // Thread.sleep(2000); + for (Entry> header : httpUrlConnection.getHeaderFields().entrySet()) { + System.out.println(header.getKey() + "=" + header.getValue()); + } + fetchInfo(scenarioNumber, httpUrlConnection); + } + + private void fetchInfo(int scenarioNumber, sun.net.www.protocol.http.HttpURLConnection httpUrlConnection) + throws Exception { + Field field = Class.forName("sun.net.www.protocol.http.HttpURLConnection").getDeclaredField("http"); + field.setAccessible(true); + HttpClient httpClient = (HttpClient) field.get(httpUrlConnection); + // System.out.println("httpclient=" + httpClient); + Field keepAliveField = Class.forName("sun.net.www.http.HttpClient").getDeclaredField("kac"); + keepAliveField.setAccessible(true); + KeepAliveCache keepAliveCache = (KeepAliveCache) keepAliveField.get(httpClient); + System.out.println("keepAliveCache" + keepAliveCache); + System.out.println("SERVER URL:" + httpUrlConnection.getURL()); + /* + * create KeepAliveKey(URL,Object) object and compare created KeepAliveKey and + * existing using equals() method: KeepAliveKey.equals() + */ + Class keepAliveKeyClass = Class.forName("sun.net.www.http.KeepAliveKey"); + // System.out.println("keepAliveKeyClass=" + keepAliveKeyClass); + Constructor keepAliveKeyClassconstructor = keepAliveKeyClass.getDeclaredConstructors()[0]; + keepAliveKeyClassconstructor.setAccessible(true); + Object expectedKeepAliveKey = keepAliveKeyClassconstructor.newInstance(httpUrlConnection.getURL(), null); + System.out.println("ExpectedKeepAliveKey=" + expectedKeepAliveKey); + Object clientVectorObjectInMap = keepAliveCache.get(expectedKeepAliveKey); + System.out.println("ClientVector=" + clientVectorObjectInMap); + HttpClient httpClientCached = keepAliveCache.get(httpUrlConnection.getURL(), null); + System.out.println("HttpClient in Cache:" + httpClientCached); + if(httpClientCached != null) { + System.out.println("KeepingAlive:" + httpClientCached.isKeepingAlive()); + System.out.println("UsingProxy:" + httpClientCached.getUsingProxy()); + System.out.println("ProxiedHost:" + httpClientCached.getProxyHostUsed()); + System.out.println("ProxiedPort:" + httpClientCached.getProxyPortUsed()); + System.out.println("ProxyPortUsingSystemProperty:" + System.getProperty("http.proxyPort")); + System.out.println("ProxyHostUsingSystemProperty:" + System.getProperty("http.proxyHost")); + System.out.println("http.keepAlive.time.server=" + System.getProperty("http.keepAlive.time.server")); + System.out.println("http.keepAlive.time.proxy=" + System.getProperty("http.keepAlive.time.proxy")); + Class clientVectorClass = Class.forName("sun.net.www.http.ClientVector"); + // System.out.println("clientVectorClass=" + clientVectorClass); + Field napField = clientVectorClass.getDeclaredField("nap"); + napField.setAccessible(true); + int napValue = (int) napField.get(clientVectorObjectInMap); + int actualValue = napValue / 1000; + // System.out.println("nap=" + napValue / 1000); + System.out.printf("ExpectedOutput:%d ActualOutput:%d ", expectedValues[scenarioNumber], actualValue); + System.out.println(); + if (expectedValues[scenarioNumber] != actualValue) { + throw new RuntimeException( + "ExpectedOutput:" + expectedValues[scenarioNumber] + " ActualOutput: " + actualValue); + } + } else { + //executed when value is not cached. + String expected = expectedValues[scenarioNumber] == 0 ? NOT_CACHED + : String.valueOf(expectedValues[scenarioNumber]); + System.out.println("ExpectedOutput:" + expected + " ActualOutput:" + NOT_CACHED); + if (!expected.equalsIgnoreCase(NOT_CACHED)) { + throw new RuntimeException("ExpectedOutput:" + expected + " ActualOutput:" + NOT_CACHED); + } + } + } + + public static void main(String[] args) throws Exception { + if (args.length != 1) { + throw new IllegalArgumentException("Usage:java KeepAliveTest.java "); + } + logger.setLevel(Level.FINEST); + ConsoleHandler h = new ConsoleHandler(); + h.setLevel(Level.FINEST); + logger.addHandler(h); + KeepAliveTest keepAliveTest = new KeepAliveTest(); + if (args.length != 0) { + keepAliveTest.startScenario(Integer.valueOf(args[0])); + } + // make main thread wait until server and client is completed. + keepAliveTest.countDownLatch.await(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/net/www/http/KeepAliveCache/B8291637.java openjdk-17-17.0.8+7/test/jdk/sun/net/www/http/KeepAliveCache/B8291637.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/net/www/http/KeepAliveCache/B8291637.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/net/www/http/KeepAliveCache/B8291637.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 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 8291637 + * @run main/othervm -Dhttp.keepAlive.time.server=20 -esa -ea B8291637 timeout + * @run main/othervm -Dhttp.keepAlive.time.server=20 -esa -ea B8291637 max + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; + +public class B8291637 { + static CompletableFuture passed = new CompletableFuture<>(); + + static class Server extends Thread { + final ServerSocket serverSocket; + final int port; + final String param; // the parameter to test "max" or "timeout" + volatile Socket s; + + public Server(String param) throws IOException { + serverSocket = new ServerSocket(0); + port = serverSocket.getLocalPort(); + setDaemon(true); + this.param = param; + } + + public int getPort() { + return port; + } + + public void close() { + try { + serverSocket.close(); + if (s != null) + s.close(); + } catch (IOException e) {} + } + + static void readRequest(Socket s) throws IOException { + InputStream is = s.getInputStream(); + is.read(); + while (is.available() > 0) + is.read(); + } + + public void run() { + try { + while (true) { + s = serverSocket.accept(); + readRequest(s); + OutputStream os = s.getOutputStream(); + String resp = "" + + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 11\r\n" + + "Connection: Keep-Alive\r\n" + + "Keep-Alive: " + param + "=-10\r\n" + // invalid negative value + "\r\n" + + "Hello World"; + os.write(resp.getBytes(StandardCharsets.ISO_8859_1)); + os.flush(); + InputStream is = s.getInputStream(); + long l1 = System.currentTimeMillis(); + is.read(); + long l2 = System.currentTimeMillis(); + long diff = (l2 - l1) / 1000; + /* + * timeout is set to 20 seconds. If bug is still present + * then the timeout will occur the first time the keep alive + * thread wakes up which is after 5 seconds. This allows + * very large leeway with slow running hardware. + * + * Same behavior should occur in case of max=-1 with the bug + */ + if (diff < 19) { + passed.complete(false); + } else { + passed.complete(true); + } + System.out.println("Time diff = " + diff); + } + } catch (Throwable t) { + System.err.println("Server exception terminating: " + t); + passed.completeExceptionally(t); + } + } + } + + public static void main(String[] args) throws Exception { + Server server = new Server(args[0]); + int port = server.getPort(); + server.start(); + URL url = new URL("http://127.0.0.1:" + Integer.toString(port) + "/"); + HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); + InputStream i = urlc.getInputStream(); + int c,count=0; + byte[] buf = new byte[256]; + while ((c=i.read(buf)) != -1) { + count+=c; + } + i.close(); + System.out.println("Read " + count ); + try { + if (!passed.get()) { + throw new RuntimeException("Test failed"); + } else { + System.out.println("Test passed"); + } + } finally { + server.close(); + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/mapping/CoderTest.java openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/mapping/CoderTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/mapping/CoderTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/mapping/CoderTest.java 2023-07-05 07:11:54.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 @@ -22,9 +22,11 @@ */ /* @test - @bug 4691554 6221056 6380723 6404504 6419565 6529796 + @bug 4691554 6221056 6380723 6404504 6419565 6529796 8301119 @summary Test the supported New I/O coders @modules jdk.charsets + @run main CoderTest + @run main/othervm -Djdk.charset.GB18030=2000 CoderTest */ import java.io.*; @@ -56,6 +58,9 @@ ".c2b-irreversible", ".b2c-irreversible" }; + private static final boolean IS_2000 = + "2000".equals(System.getProperty("jdk.charset.GB18030")); + // Utilities private static ByteBuffer expand(ByteBuffer bb) { @@ -466,7 +471,12 @@ // Outer loop runs three passes: roundtrip, irreversible encodings, // and then irreversible decodings for (int mode = ROUNDTRIP; mode <= DECODE; mode++) { - File f = testFile(encoding, mode); + var fileName = encoding; + if (fileName.equals("GB18030") && IS_2000) { + // tweak the map file name + fileName = "GB18030_2000"; + } + File f = testFile(fileName, mode); if (f == null) continue; loadTests(f); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/mapping/GB18030_2000.b2c openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/mapping/GB18030_2000.b2c --- openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/mapping/GB18030_2000.b2c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/mapping/GB18030_2000.b2c 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,63489 @@ +# based on GB18030-2000 mapping +00 0000 +01 0001 +02 0002 +03 0003 +04 0004 +05 0005 +06 0006 +07 0007 +08 0008 +09 0009 +0A 000A +0B 000B +0C 000C +0D 000D +0E 000E +0F 000F +10 0010 +11 0011 +12 0012 +13 0013 +14 0014 +15 0015 +16 0016 +17 0017 +18 0018 +19 0019 +1A 001A +1B 001B +1C 001C +1D 001D +1E 001E +1F 001F +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +81308130 0080 +81308131 0081 +81308132 0082 +81308133 0083 +81308134 0084 +81308135 0085 +81308136 0086 +81308137 0087 +81308138 0088 +81308139 0089 +81308230 008A +81308231 008B +81308232 008C +81308233 008D +81308234 008E +81308235 008F +81308236 0090 +81308237 0091 +81308238 0092 +81308239 0093 +81308330 0094 +81308331 0095 +81308332 0096 +81308333 0097 +81308334 0098 +81308335 0099 +81308336 009A +81308337 009B +81308338 009C +81308339 009D +81308430 009E +81308431 009F +81308432 00A0 +81308433 00A1 +81308434 00A2 +81308435 00A3 +A1E8 00A4 +81308436 00A5 +81308437 00A6 +A1EC 00A7 +A1A7 00A8 +81308438 00A9 +81308439 00AA +81308530 00AB +81308531 00AC +81308532 00AD +81308533 00AE +81308534 00AF +A1E3 00B0 +A1C0 00B1 +81308535 00B2 +81308536 00B3 +81308537 00B4 +81308538 00B5 +81308539 00B6 +A1A4 00B7 +81308630 00B8 +81308631 00B9 +81308632 00BA +81308633 00BB +81308634 00BC +81308635 00BD +81308636 00BE +81308637 00BF +81308638 00C0 +81308639 00C1 +81308730 00C2 +81308731 00C3 +81308732 00C4 +81308733 00C5 +81308734 00C6 +81308735 00C7 +81308736 00C8 +81308737 00C9 +81308738 00CA +81308739 00CB +81308830 00CC +81308831 00CD +81308832 00CE +81308833 00CF +81308834 00D0 +81308835 00D1 +81308836 00D2 +81308837 00D3 +81308838 00D4 +81308839 00D5 +81308930 00D6 +A1C1 00D7 +81308931 00D8 +81308932 00D9 +81308933 00DA +81308934 00DB +81308935 00DC +81308936 00DD +81308937 00DE +81308938 00DF +A8A4 00E0 +A8A2 00E1 +81308939 00E2 +81308A30 00E3 +81308A31 00E4 +81308A32 00E5 +81308A33 00E6 +81308A34 00E7 +A8A8 00E8 +A8A6 00E9 +A8BA 00EA +81308A35 00EB +A8AC 00EC +A8AA 00ED +81308A36 00EE +81308A37 00EF +81308A38 00F0 +81308A39 00F1 +A8B0 00F2 +A8AE 00F3 +81308B30 00F4 +81308B31 00F5 +81308B32 00F6 +A1C2 00F7 +81308B33 00F8 +A8B4 00F9 +A8B2 00FA +81308B34 00FB +A8B9 00FC +81308B35 00FD +81308B36 00FE +81308B37 00FF +81308B38 0100 +A8A1 0101 +81308B39 0102 +81308C30 0103 +81308C31 0104 +81308C32 0105 +81308C33 0106 +81308C34 0107 +81308C35 0108 +81308C36 0109 +81308C37 010A +81308C38 010B +81308C39 010C +81308D30 010D +81308D31 010E +81308D32 010F +81308D33 0110 +81308D34 0111 +81308D35 0112 +A8A5 0113 +81308D36 0114 +81308D37 0115 +81308D38 0116 +81308D39 0117 +81308E30 0118 +81308E31 0119 +81308E32 011A +A8A7 011B +81308E33 011C +81308E34 011D +81308E35 011E +81308E36 011F +81308E37 0120 +81308E38 0121 +81308E39 0122 +81308F30 0123 +81308F31 0124 +81308F32 0125 +81308F33 0126 +81308F34 0127 +81308F35 0128 +81308F36 0129 +81308F37 012A +A8A9 012B +81308F38 012C +81308F39 012D +81309030 012E +81309031 012F +81309032 0130 +81309033 0131 +81309034 0132 +81309035 0133 +81309036 0134 +81309037 0135 +81309038 0136 +81309039 0137 +81309130 0138 +81309131 0139 +81309132 013A +81309133 013B +81309134 013C +81309135 013D +81309136 013E +81309137 013F +81309138 0140 +81309139 0141 +81309230 0142 +81309231 0143 +A8BD 0144 +81309232 0145 +81309233 0146 +81309234 0147 +A8BE 0148 +81309235 0149 +81309236 014A +81309237 014B +81309238 014C +A8AD 014D +81309239 014E +81309330 014F +81309331 0150 +81309332 0151 +81309333 0152 +81309334 0153 +81309335 0154 +81309336 0155 +81309337 0156 +81309338 0157 +81309339 0158 +81309430 0159 +81309431 015A +81309432 015B +81309433 015C +81309434 015D +81309435 015E +81309436 015F +81309437 0160 +81309438 0161 +81309439 0162 +81309530 0163 +81309531 0164 +81309532 0165 +81309533 0166 +81309534 0167 +81309535 0168 +81309536 0169 +81309537 016A +A8B1 016B +81309538 016C +81309539 016D +81309630 016E +81309631 016F +81309632 0170 +81309633 0171 +81309634 0172 +81309635 0173 +81309636 0174 +81309637 0175 +81309638 0176 +81309639 0177 +81309730 0178 +81309731 0179 +81309732 017A +81309733 017B +81309734 017C +81309735 017D +81309736 017E +81309737 017F +81309738 0180 +81309739 0181 +81309830 0182 +81309831 0183 +81309832 0184 +81309833 0185 +81309834 0186 +81309835 0187 +81309836 0188 +81309837 0189 +81309838 018A +81309839 018B +81309930 018C +81309931 018D +81309932 018E +81309933 018F +81309934 0190 +81309935 0191 +81309936 0192 +81309937 0193 +81309938 0194 +81309939 0195 +81309A30 0196 +81309A31 0197 +81309A32 0198 +81309A33 0199 +81309A34 019A +81309A35 019B +81309A36 019C +81309A37 019D +81309A38 019E +81309A39 019F +81309B30 01A0 +81309B31 01A1 +81309B32 01A2 +81309B33 01A3 +81309B34 01A4 +81309B35 01A5 +81309B36 01A6 +81309B37 01A7 +81309B38 01A8 +81309B39 01A9 +81309C30 01AA +81309C31 01AB +81309C32 01AC +81309C33 01AD +81309C34 01AE +81309C35 01AF +81309C36 01B0 +81309C37 01B1 +81309C38 01B2 +81309C39 01B3 +81309D30 01B4 +81309D31 01B5 +81309D32 01B6 +81309D33 01B7 +81309D34 01B8 +81309D35 01B9 +81309D36 01BA +81309D37 01BB +81309D38 01BC +81309D39 01BD +81309E30 01BE +81309E31 01BF +81309E32 01C0 +81309E33 01C1 +81309E34 01C2 +81309E35 01C3 +81309E36 01C4 +81309E37 01C5 +81309E38 01C6 +81309E39 01C7 +81309F30 01C8 +81309F31 01C9 +81309F32 01CA +81309F33 01CB +81309F34 01CC +81309F35 01CD +A8A3 01CE +81309F36 01CF +A8AB 01D0 +81309F37 01D1 +A8AF 01D2 +81309F38 01D3 +A8B3 01D4 +81309F39 01D5 +A8B5 01D6 +8130A030 01D7 +A8B6 01D8 +8130A031 01D9 +A8B7 01DA +8130A032 01DB +A8B8 01DC +8130A033 01DD +8130A034 01DE +8130A035 01DF +8130A036 01E0 +8130A037 01E1 +8130A038 01E2 +8130A039 01E3 +8130A130 01E4 +8130A131 01E5 +8130A132 01E6 +8130A133 01E7 +8130A134 01E8 +8130A135 01E9 +8130A136 01EA +8130A137 01EB +8130A138 01EC +8130A139 01ED +8130A230 01EE +8130A231 01EF +8130A232 01F0 +8130A233 01F1 +8130A234 01F2 +8130A235 01F3 +8130A236 01F4 +8130A237 01F5 +8130A238 01F6 +8130A239 01F7 +8130A330 01F8 +A8BF 01F9 +8130A331 01FA +8130A332 01FB +8130A333 01FC +8130A334 01FD +8130A335 01FE +8130A336 01FF +8130A337 0200 +8130A338 0201 +8130A339 0202 +8130A430 0203 +8130A431 0204 +8130A432 0205 +8130A433 0206 +8130A434 0207 +8130A435 0208 +8130A436 0209 +8130A437 020A +8130A438 020B +8130A439 020C +8130A530 020D +8130A531 020E +8130A532 020F +8130A533 0210 +8130A534 0211 +8130A535 0212 +8130A536 0213 +8130A537 0214 +8130A538 0215 +8130A539 0216 +8130A630 0217 +8130A631 0218 +8130A632 0219 +8130A633 021A +8130A634 021B +8130A635 021C +8130A636 021D +8130A637 021E +8130A638 021F +8130A639 0220 +8130A730 0221 +8130A731 0222 +8130A732 0223 +8130A733 0224 +8130A734 0225 +8130A735 0226 +8130A736 0227 +8130A737 0228 +8130A738 0229 +8130A739 022A +8130A830 022B +8130A831 022C +8130A832 022D +8130A833 022E +8130A834 022F +8130A835 0230 +8130A836 0231 +8130A837 0232 +8130A838 0233 +8130A839 0234 +8130A930 0235 +8130A931 0236 +8130A932 0237 +8130A933 0238 +8130A934 0239 +8130A935 023A +8130A936 023B +8130A937 023C +8130A938 023D +8130A939 023E +8130AA30 023F +8130AA31 0240 +8130AA32 0241 +8130AA33 0242 +8130AA34 0243 +8130AA35 0244 +8130AA36 0245 +8130AA37 0246 +8130AA38 0247 +8130AA39 0248 +8130AB30 0249 +8130AB31 024A +8130AB32 024B +8130AB33 024C +8130AB34 024D +8130AB35 024E +8130AB36 024F +8130AB37 0250 +A8BB 0251 +8130AB38 0252 +8130AB39 0253 +8130AC30 0254 +8130AC31 0255 +8130AC32 0256 +8130AC33 0257 +8130AC34 0258 +8130AC35 0259 +8130AC36 025A +8130AC37 025B +8130AC38 025C +8130AC39 025D +8130AD30 025E +8130AD31 025F +8130AD32 0260 +A8C0 0261 +8130AD33 0262 +8130AD34 0263 +8130AD35 0264 +8130AD36 0265 +8130AD37 0266 +8130AD38 0267 +8130AD39 0268 +8130AE30 0269 +8130AE31 026A +8130AE32 026B +8130AE33 026C +8130AE34 026D +8130AE35 026E +8130AE36 026F +8130AE37 0270 +8130AE38 0271 +8130AE39 0272 +8130AF30 0273 +8130AF31 0274 +8130AF32 0275 +8130AF33 0276 +8130AF34 0277 +8130AF35 0278 +8130AF36 0279 +8130AF37 027A +8130AF38 027B +8130AF39 027C +8130B030 027D +8130B031 027E +8130B032 027F +8130B033 0280 +8130B034 0281 +8130B035 0282 +8130B036 0283 +8130B037 0284 +8130B038 0285 +8130B039 0286 +8130B130 0287 +8130B131 0288 +8130B132 0289 +8130B133 028A +8130B134 028B +8130B135 028C +8130B136 028D +8130B137 028E +8130B138 028F +8130B139 0290 +8130B230 0291 +8130B231 0292 +8130B232 0293 +8130B233 0294 +8130B234 0295 +8130B235 0296 +8130B236 0297 +8130B237 0298 +8130B238 0299 +8130B239 029A +8130B330 029B +8130B331 029C +8130B332 029D +8130B333 029E +8130B334 029F +8130B335 02A0 +8130B336 02A1 +8130B337 02A2 +8130B338 02A3 +8130B339 02A4 +8130B430 02A5 +8130B431 02A6 +8130B432 02A7 +8130B433 02A8 +8130B434 02A9 +8130B435 02AA +8130B436 02AB +8130B437 02AC +8130B438 02AD +8130B439 02AE +8130B530 02AF +8130B531 02B0 +8130B532 02B1 +8130B533 02B2 +8130B534 02B3 +8130B535 02B4 +8130B536 02B5 +8130B537 02B6 +8130B538 02B7 +8130B539 02B8 +8130B630 02B9 +8130B631 02BA +8130B632 02BB +8130B633 02BC +8130B634 02BD +8130B635 02BE +8130B636 02BF +8130B637 02C0 +8130B638 02C1 +8130B639 02C2 +8130B730 02C3 +8130B731 02C4 +8130B732 02C5 +8130B733 02C6 +A1A6 02C7 +8130B734 02C8 +A1A5 02C9 +A840 02CA +A841 02CB +8130B735 02CC +8130B736 02CD +8130B737 02CE +8130B738 02CF +8130B739 02D0 +8130B830 02D1 +8130B831 02D2 +8130B832 02D3 +8130B833 02D4 +8130B834 02D5 +8130B835 02D6 +8130B836 02D7 +8130B837 02D8 +A842 02D9 +8130B838 02DA +8130B839 02DB +8130B930 02DC +8130B931 02DD +8130B932 02DE +8130B933 02DF +8130B934 02E0 +8130B935 02E1 +8130B936 02E2 +8130B937 02E3 +8130B938 02E4 +8130B939 02E5 +8130BA30 02E6 +8130BA31 02E7 +8130BA32 02E8 +8130BA33 02E9 +8130BA34 02EA +8130BA35 02EB +8130BA36 02EC +8130BA37 02ED +8130BA38 02EE +8130BA39 02EF +8130BB30 02F0 +8130BB31 02F1 +8130BB32 02F2 +8130BB33 02F3 +8130BB34 02F4 +8130BB35 02F5 +8130BB36 02F6 +8130BB37 02F7 +8130BB38 02F8 +8130BB39 02F9 +8130BC30 02FA +8130BC31 02FB +8130BC32 02FC +8130BC33 02FD +8130BC34 02FE +8130BC35 02FF +8130BC36 0300 +8130BC37 0301 +8130BC38 0302 +8130BC39 0303 +8130BD30 0304 +8130BD31 0305 +8130BD32 0306 +8130BD33 0307 +8130BD34 0308 +8130BD35 0309 +8130BD36 030A +8130BD37 030B +8130BD38 030C +8130BD39 030D +8130BE30 030E +8130BE31 030F +8130BE32 0310 +8130BE33 0311 +8130BE34 0312 +8130BE35 0313 +8130BE36 0314 +8130BE37 0315 +8130BE38 0316 +8130BE39 0317 +8130BF30 0318 +8130BF31 0319 +8130BF32 031A +8130BF33 031B +8130BF34 031C +8130BF35 031D +8130BF36 031E +8130BF37 031F +8130BF38 0320 +8130BF39 0321 +8130C030 0322 +8130C031 0323 +8130C032 0324 +8130C033 0325 +8130C034 0326 +8130C035 0327 +8130C036 0328 +8130C037 0329 +8130C038 032A +8130C039 032B +8130C130 032C +8130C131 032D +8130C132 032E +8130C133 032F +8130C134 0330 +8130C135 0331 +8130C136 0332 +8130C137 0333 +8130C138 0334 +8130C139 0335 +8130C230 0336 +8130C231 0337 +8130C232 0338 +8130C233 0339 +8130C234 033A +8130C235 033B +8130C236 033C +8130C237 033D +8130C238 033E +8130C239 033F +8130C330 0340 +8130C331 0341 +8130C332 0342 +8130C333 0343 +8130C334 0344 +8130C335 0345 +8130C336 0346 +8130C337 0347 +8130C338 0348 +8130C339 0349 +8130C430 034A +8130C431 034B +8130C432 034C +8130C433 034D +8130C434 034E +8130C435 034F +8130C436 0350 +8130C437 0351 +8130C438 0352 +8130C439 0353 +8130C530 0354 +8130C531 0355 +8130C532 0356 +8130C533 0357 +8130C534 0358 +8130C535 0359 +8130C536 035A +8130C537 035B +8130C538 035C +8130C539 035D +8130C630 035E +8130C631 035F +8130C632 0360 +8130C633 0361 +8130C634 0362 +8130C635 0363 +8130C636 0364 +8130C637 0365 +8130C638 0366 +8130C639 0367 +8130C730 0368 +8130C731 0369 +8130C732 036A +8130C733 036B +8130C734 036C +8130C735 036D +8130C736 036E +8130C737 036F +8130C738 0370 +8130C739 0371 +8130C830 0372 +8130C831 0373 +8130C832 0374 +8130C833 0375 +8130C834 0376 +8130C835 0377 +8130C836 0378 +8130C837 0379 +8130C838 037A +8130C839 037B +8130C930 037C +8130C931 037D +8130C932 037E +8130C933 037F +8130C934 0380 +8130C935 0381 +8130C936 0382 +8130C937 0383 +8130C938 0384 +8130C939 0385 +8130CA30 0386 +8130CA31 0387 +8130CA32 0388 +8130CA33 0389 +8130CA34 038A +8130CA35 038B +8130CA36 038C +8130CA37 038D +8130CA38 038E +8130CA39 038F +8130CB30 0390 +A6A1 0391 +A6A2 0392 +A6A3 0393 +A6A4 0394 +A6A5 0395 +A6A6 0396 +A6A7 0397 +A6A8 0398 +A6A9 0399 +A6AA 039A +A6AB 039B +A6AC 039C +A6AD 039D +A6AE 039E +A6AF 039F +A6B0 03A0 +A6B1 03A1 +8130CB31 03A2 +A6B2 03A3 +A6B3 03A4 +A6B4 03A5 +A6B5 03A6 +A6B6 03A7 +A6B7 03A8 +A6B8 03A9 +8130CB32 03AA +8130CB33 03AB +8130CB34 03AC +8130CB35 03AD +8130CB36 03AE +8130CB37 03AF +8130CB38 03B0 +A6C1 03B1 +A6C2 03B2 +A6C3 03B3 +A6C4 03B4 +A6C5 03B5 +A6C6 03B6 +A6C7 03B7 +A6C8 03B8 +A6C9 03B9 +A6CA 03BA +A6CB 03BB +A6CC 03BC +A6CD 03BD +A6CE 03BE +A6CF 03BF +A6D0 03C0 +A6D1 03C1 +8130CB39 03C2 +A6D2 03C3 +A6D3 03C4 +A6D4 03C5 +A6D5 03C6 +A6D6 03C7 +A6D7 03C8 +A6D8 03C9 +8130CC30 03CA +8130CC31 03CB +8130CC32 03CC +8130CC33 03CD +8130CC34 03CE +8130CC35 03CF +8130CC36 03D0 +8130CC37 03D1 +8130CC38 03D2 +8130CC39 03D3 +8130CD30 03D4 +8130CD31 03D5 +8130CD32 03D6 +8130CD33 03D7 +8130CD34 03D8 +8130CD35 03D9 +8130CD36 03DA +8130CD37 03DB +8130CD38 03DC +8130CD39 03DD +8130CE30 03DE +8130CE31 03DF +8130CE32 03E0 +8130CE33 03E1 +8130CE34 03E2 +8130CE35 03E3 +8130CE36 03E4 +8130CE37 03E5 +8130CE38 03E6 +8130CE39 03E7 +8130CF30 03E8 +8130CF31 03E9 +8130CF32 03EA +8130CF33 03EB +8130CF34 03EC +8130CF35 03ED +8130CF36 03EE +8130CF37 03EF +8130CF38 03F0 +8130CF39 03F1 +8130D030 03F2 +8130D031 03F3 +8130D032 03F4 +8130D033 03F5 +8130D034 03F6 +8130D035 03F7 +8130D036 03F8 +8130D037 03F9 +8130D038 03FA +8130D039 03FB +8130D130 03FC +8130D131 03FD +8130D132 03FE +8130D133 03FF +8130D134 0400 +A7A7 0401 +8130D135 0402 +8130D136 0403 +8130D137 0404 +8130D138 0405 +8130D139 0406 +8130D230 0407 +8130D231 0408 +8130D232 0409 +8130D233 040A +8130D234 040B +8130D235 040C +8130D236 040D +8130D237 040E +8130D238 040F +A7A1 0410 +A7A2 0411 +A7A3 0412 +A7A4 0413 +A7A5 0414 +A7A6 0415 +A7A8 0416 +A7A9 0417 +A7AA 0418 +A7AB 0419 +A7AC 041A +A7AD 041B +A7AE 041C +A7AF 041D +A7B0 041E +A7B1 041F +A7B2 0420 +A7B3 0421 +A7B4 0422 +A7B5 0423 +A7B6 0424 +A7B7 0425 +A7B8 0426 +A7B9 0427 +A7BA 0428 +A7BB 0429 +A7BC 042A +A7BD 042B +A7BE 042C +A7BF 042D +A7C0 042E +A7C1 042F +A7D1 0430 +A7D2 0431 +A7D3 0432 +A7D4 0433 +A7D5 0434 +A7D6 0435 +A7D8 0436 +A7D9 0437 +A7DA 0438 +A7DB 0439 +A7DC 043A +A7DD 043B +A7DE 043C +A7DF 043D +A7E0 043E +A7E1 043F +A7E2 0440 +A7E3 0441 +A7E4 0442 +A7E5 0443 +A7E6 0444 +A7E7 0445 +A7E8 0446 +A7E9 0447 +A7EA 0448 +A7EB 0449 +A7EC 044A +A7ED 044B +A7EE 044C +A7EF 044D +A7F0 044E +A7F1 044F +8130D239 0450 +A7D7 0451 +8130D330 0452 +8130D331 0453 +8130D332 0454 +8130D333 0455 +8130D334 0456 +8130D335 0457 +8130D336 0458 +8130D337 0459 +8130D338 045A +8130D339 045B +8130D430 045C +8130D431 045D +8130D432 045E +8130D433 045F +8130D434 0460 +8130D435 0461 +8130D436 0462 +8130D437 0463 +8130D438 0464 +8130D439 0465 +8130D530 0466 +8130D531 0467 +8130D532 0468 +8130D533 0469 +8130D534 046A +8130D535 046B +8130D536 046C +8130D537 046D +8130D538 046E +8130D539 046F +8130D630 0470 +8130D631 0471 +8130D632 0472 +8130D633 0473 +8130D634 0474 +8130D635 0475 +8130D636 0476 +8130D637 0477 +8130D638 0478 +8130D639 0479 +8130D730 047A +8130D731 047B +8130D732 047C +8130D733 047D +8130D734 047E +8130D735 047F +8130D736 0480 +8130D737 0481 +8130D738 0482 +8130D739 0483 +8130D830 0484 +8130D831 0485 +8130D832 0486 +8130D833 0487 +8130D834 0488 +8130D835 0489 +8130D836 048A +8130D837 048B +8130D838 048C +8130D839 048D +8130D930 048E +8130D931 048F +8130D932 0490 +8130D933 0491 +8130D934 0492 +8130D935 0493 +8130D936 0494 +8130D937 0495 +8130D938 0496 +8130D939 0497 +8130DA30 0498 +8130DA31 0499 +8130DA32 049A +8130DA33 049B +8130DA34 049C +8130DA35 049D +8130DA36 049E +8130DA37 049F +8130DA38 04A0 +8130DA39 04A1 +8130DB30 04A2 +8130DB31 04A3 +8130DB32 04A4 +8130DB33 04A5 +8130DB34 04A6 +8130DB35 04A7 +8130DB36 04A8 +8130DB37 04A9 +8130DB38 04AA +8130DB39 04AB +8130DC30 04AC +8130DC31 04AD +8130DC32 04AE +8130DC33 04AF +8130DC34 04B0 +8130DC35 04B1 +8130DC36 04B2 +8130DC37 04B3 +8130DC38 04B4 +8130DC39 04B5 +8130DD30 04B6 +8130DD31 04B7 +8130DD32 04B8 +8130DD33 04B9 +8130DD34 04BA +8130DD35 04BB +8130DD36 04BC +8130DD37 04BD +8130DD38 04BE +8130DD39 04BF +8130DE30 04C0 +8130DE31 04C1 +8130DE32 04C2 +8130DE33 04C3 +8130DE34 04C4 +8130DE35 04C5 +8130DE36 04C6 +8130DE37 04C7 +8130DE38 04C8 +8130DE39 04C9 +8130DF30 04CA +8130DF31 04CB +8130DF32 04CC +8130DF33 04CD +8130DF34 04CE +8130DF35 04CF +8130DF36 04D0 +8130DF37 04D1 +8130DF38 04D2 +8130DF39 04D3 +8130E030 04D4 +8130E031 04D5 +8130E032 04D6 +8130E033 04D7 +8130E034 04D8 +8130E035 04D9 +8130E036 04DA +8130E037 04DB +8130E038 04DC +8130E039 04DD +8130E130 04DE +8130E131 04DF +8130E132 04E0 +8130E133 04E1 +8130E134 04E2 +8130E135 04E3 +8130E136 04E4 +8130E137 04E5 +8130E138 04E6 +8130E139 04E7 +8130E230 04E8 +8130E231 04E9 +8130E232 04EA +8130E233 04EB +8130E234 04EC +8130E235 04ED +8130E236 04EE +8130E237 04EF +8130E238 04F0 +8130E239 04F1 +8130E330 04F2 +8130E331 04F3 +8130E332 04F4 +8130E333 04F5 +8130E334 04F6 +8130E335 04F7 +8130E336 04F8 +8130E337 04F9 +8130E338 04FA +8130E339 04FB +8130E430 04FC +8130E431 04FD +8130E432 04FE +8130E433 04FF +8130E434 0500 +8130E435 0501 +8130E436 0502 +8130E437 0503 +8130E438 0504 +8130E439 0505 +8130E530 0506 +8130E531 0507 +8130E532 0508 +8130E533 0509 +8130E534 050A +8130E535 050B +8130E536 050C +8130E537 050D +8130E538 050E +8130E539 050F +8130E630 0510 +8130E631 0511 +8130E632 0512 +8130E633 0513 +8130E634 0514 +8130E635 0515 +8130E636 0516 +8130E637 0517 +8130E638 0518 +8130E639 0519 +8130E730 051A +8130E731 051B +8130E732 051C +8130E733 051D +8130E734 051E +8130E735 051F +8130E736 0520 +8130E737 0521 +8130E738 0522 +8130E739 0523 +8130E830 0524 +8130E831 0525 +8130E832 0526 +8130E833 0527 +8130E834 0528 +8130E835 0529 +8130E836 052A +8130E837 052B +8130E838 052C +8130E839 052D +8130E930 052E +8130E931 052F +8130E932 0530 +8130E933 0531 +8130E934 0532 +8130E935 0533 +8130E936 0534 +8130E937 0535 +8130E938 0536 +8130E939 0537 +8130EA30 0538 +8130EA31 0539 +8130EA32 053A +8130EA33 053B +8130EA34 053C +8130EA35 053D +8130EA36 053E +8130EA37 053F +8130EA38 0540 +8130EA39 0541 +8130EB30 0542 +8130EB31 0543 +8130EB32 0544 +8130EB33 0545 +8130EB34 0546 +8130EB35 0547 +8130EB36 0548 +8130EB37 0549 +8130EB38 054A +8130EB39 054B +8130EC30 054C +8130EC31 054D +8130EC32 054E +8130EC33 054F +8130EC34 0550 +8130EC35 0551 +8130EC36 0552 +8130EC37 0553 +8130EC38 0554 +8130EC39 0555 +8130ED30 0556 +8130ED31 0557 +8130ED32 0558 +8130ED33 0559 +8130ED34 055A +8130ED35 055B +8130ED36 055C +8130ED37 055D +8130ED38 055E +8130ED39 055F +8130EE30 0560 +8130EE31 0561 +8130EE32 0562 +8130EE33 0563 +8130EE34 0564 +8130EE35 0565 +8130EE36 0566 +8130EE37 0567 +8130EE38 0568 +8130EE39 0569 +8130EF30 056A +8130EF31 056B +8130EF32 056C +8130EF33 056D +8130EF34 056E +8130EF35 056F +8130EF36 0570 +8130EF37 0571 +8130EF38 0572 +8130EF39 0573 +8130F030 0574 +8130F031 0575 +8130F032 0576 +8130F033 0577 +8130F034 0578 +8130F035 0579 +8130F036 057A +8130F037 057B +8130F038 057C +8130F039 057D +8130F130 057E +8130F131 057F +8130F132 0580 +8130F133 0581 +8130F134 0582 +8130F135 0583 +8130F136 0584 +8130F137 0585 +8130F138 0586 +8130F139 0587 +8130F230 0588 +8130F231 0589 +8130F232 058A +8130F233 058B +8130F234 058C +8130F235 058D +8130F236 058E +8130F237 058F +8130F238 0590 +8130F239 0591 +8130F330 0592 +8130F331 0593 +8130F332 0594 +8130F333 0595 +8130F334 0596 +8130F335 0597 +8130F336 0598 +8130F337 0599 +8130F338 059A +8130F339 059B +8130F430 059C +8130F431 059D +8130F432 059E +8130F433 059F +8130F434 05A0 +8130F435 05A1 +8130F436 05A2 +8130F437 05A3 +8130F438 05A4 +8130F439 05A5 +8130F530 05A6 +8130F531 05A7 +8130F532 05A8 +8130F533 05A9 +8130F534 05AA +8130F535 05AB +8130F536 05AC +8130F537 05AD +8130F538 05AE +8130F539 05AF +8130F630 05B0 +8130F631 05B1 +8130F632 05B2 +8130F633 05B3 +8130F634 05B4 +8130F635 05B5 +8130F636 05B6 +8130F637 05B7 +8130F638 05B8 +8130F639 05B9 +8130F730 05BA +8130F731 05BB +8130F732 05BC +8130F733 05BD +8130F734 05BE +8130F735 05BF +8130F736 05C0 +8130F737 05C1 +8130F738 05C2 +8130F739 05C3 +8130F830 05C4 +8130F831 05C5 +8130F832 05C6 +8130F833 05C7 +8130F834 05C8 +8130F835 05C9 +8130F836 05CA +8130F837 05CB +8130F838 05CC +8130F839 05CD +8130F930 05CE +8130F931 05CF +8130F932 05D0 +8130F933 05D1 +8130F934 05D2 +8130F935 05D3 +8130F936 05D4 +8130F937 05D5 +8130F938 05D6 +8130F939 05D7 +8130FA30 05D8 +8130FA31 05D9 +8130FA32 05DA +8130FA33 05DB +8130FA34 05DC +8130FA35 05DD +8130FA36 05DE +8130FA37 05DF +8130FA38 05E0 +8130FA39 05E1 +8130FB30 05E2 +8130FB31 05E3 +8130FB32 05E4 +8130FB33 05E5 +8130FB34 05E6 +8130FB35 05E7 +8130FB36 05E8 +8130FB37 05E9 +8130FB38 05EA +8130FB39 05EB +8130FC30 05EC +8130FC31 05ED +8130FC32 05EE +8130FC33 05EF +8130FC34 05F0 +8130FC35 05F1 +8130FC36 05F2 +8130FC37 05F3 +8130FC38 05F4 +8130FC39 05F5 +8130FD30 05F6 +8130FD31 05F7 +8130FD32 05F8 +8130FD33 05F9 +8130FD34 05FA +8130FD35 05FB +8130FD36 05FC +8130FD37 05FD +8130FD38 05FE +8130FD39 05FF +8130FE30 0600 +8130FE31 0601 +8130FE32 0602 +8130FE33 0603 +8130FE34 0604 +8130FE35 0605 +8130FE36 0606 +8130FE37 0607 +8130FE38 0608 +8130FE39 0609 +81318130 060A +81318131 060B +81318132 060C +81318133 060D +81318134 060E +81318135 060F +81318136 0610 +81318137 0611 +81318138 0612 +81318139 0613 +81318230 0614 +81318231 0615 +81318232 0616 +81318233 0617 +81318234 0618 +81318235 0619 +81318236 061A +81318237 061B +81318238 061C +81318239 061D +81318330 061E +81318331 061F +81318332 0620 +81318333 0621 +81318334 0622 +81318335 0623 +81318336 0624 +81318337 0625 +81318338 0626 +81318339 0627 +81318430 0628 +81318431 0629 +81318432 062A +81318433 062B +81318434 062C +81318435 062D +81318436 062E +81318437 062F +81318438 0630 +81318439 0631 +81318530 0632 +81318531 0633 +81318532 0634 +81318533 0635 +81318534 0636 +81318535 0637 +81318536 0638 +81318537 0639 +81318538 063A +81318539 063B +81318630 063C +81318631 063D +81318632 063E +81318633 063F +81318634 0640 +81318635 0641 +81318636 0642 +81318637 0643 +81318638 0644 +81318639 0645 +81318730 0646 +81318731 0647 +81318732 0648 +81318733 0649 +81318734 064A +81318735 064B +81318736 064C +81318737 064D +81318738 064E +81318739 064F +81318830 0650 +81318831 0651 +81318832 0652 +81318833 0653 +81318834 0654 +81318835 0655 +81318836 0656 +81318837 0657 +81318838 0658 +81318839 0659 +81318930 065A +81318931 065B +81318932 065C +81318933 065D +81318934 065E +81318935 065F +81318936 0660 +81318937 0661 +81318938 0662 +81318939 0663 +81318A30 0664 +81318A31 0665 +81318A32 0666 +81318A33 0667 +81318A34 0668 +81318A35 0669 +81318A36 066A +81318A37 066B +81318A38 066C +81318A39 066D +81318B30 066E +81318B31 066F +81318B32 0670 +81318B33 0671 +81318B34 0672 +81318B35 0673 +81318B36 0674 +81318B37 0675 +81318B38 0676 +81318B39 0677 +81318C30 0678 +81318C31 0679 +81318C32 067A +81318C33 067B +81318C34 067C +81318C35 067D +81318C36 067E +81318C37 067F +81318C38 0680 +81318C39 0681 +81318D30 0682 +81318D31 0683 +81318D32 0684 +81318D33 0685 +81318D34 0686 +81318D35 0687 +81318D36 0688 +81318D37 0689 +81318D38 068A +81318D39 068B +81318E30 068C +81318E31 068D +81318E32 068E +81318E33 068F +81318E34 0690 +81318E35 0691 +81318E36 0692 +81318E37 0693 +81318E38 0694 +81318E39 0695 +81318F30 0696 +81318F31 0697 +81318F32 0698 +81318F33 0699 +81318F34 069A +81318F35 069B +81318F36 069C +81318F37 069D +81318F38 069E +81318F39 069F +81319030 06A0 +81319031 06A1 +81319032 06A2 +81319033 06A3 +81319034 06A4 +81319035 06A5 +81319036 06A6 +81319037 06A7 +81319038 06A8 +81319039 06A9 +81319130 06AA +81319131 06AB +81319132 06AC +81319133 06AD +81319134 06AE +81319135 06AF +81319136 06B0 +81319137 06B1 +81319138 06B2 +81319139 06B3 +81319230 06B4 +81319231 06B5 +81319232 06B6 +81319233 06B7 +81319234 06B8 +81319235 06B9 +81319236 06BA +81319237 06BB +81319238 06BC +81319239 06BD +81319330 06BE +81319331 06BF +81319332 06C0 +81319333 06C1 +81319334 06C2 +81319335 06C3 +81319336 06C4 +81319337 06C5 +81319338 06C6 +81319339 06C7 +81319430 06C8 +81319431 06C9 +81319432 06CA +81319433 06CB +81319434 06CC +81319435 06CD +81319436 06CE +81319437 06CF +81319438 06D0 +81319439 06D1 +81319530 06D2 +81319531 06D3 +81319532 06D4 +81319533 06D5 +81319534 06D6 +81319535 06D7 +81319536 06D8 +81319537 06D9 +81319538 06DA +81319539 06DB +81319630 06DC +81319631 06DD +81319632 06DE +81319633 06DF +81319634 06E0 +81319635 06E1 +81319636 06E2 +81319637 06E3 +81319638 06E4 +81319639 06E5 +81319730 06E6 +81319731 06E7 +81319732 06E8 +81319733 06E9 +81319734 06EA +81319735 06EB +81319736 06EC +81319737 06ED +81319738 06EE +81319739 06EF +81319830 06F0 +81319831 06F1 +81319832 06F2 +81319833 06F3 +81319834 06F4 +81319835 06F5 +81319836 06F6 +81319837 06F7 +81319838 06F8 +81319839 06F9 +81319930 06FA +81319931 06FB +81319932 06FC +81319933 06FD +81319934 06FE +81319935 06FF +81319936 0700 +81319937 0701 +81319938 0702 +81319939 0703 +81319A30 0704 +81319A31 0705 +81319A32 0706 +81319A33 0707 +81319A34 0708 +81319A35 0709 +81319A36 070A +81319A37 070B +81319A38 070C +81319A39 070D +81319B30 070E +81319B31 070F +81319B32 0710 +81319B33 0711 +81319B34 0712 +81319B35 0713 +81319B36 0714 +81319B37 0715 +81319B38 0716 +81319B39 0717 +81319C30 0718 +81319C31 0719 +81319C32 071A +81319C33 071B +81319C34 071C +81319C35 071D +81319C36 071E +81319C37 071F +81319C38 0720 +81319C39 0721 +81319D30 0722 +81319D31 0723 +81319D32 0724 +81319D33 0725 +81319D34 0726 +81319D35 0727 +81319D36 0728 +81319D37 0729 +81319D38 072A +81319D39 072B +81319E30 072C +81319E31 072D +81319E32 072E +81319E33 072F +81319E34 0730 +81319E35 0731 +81319E36 0732 +81319E37 0733 +81319E38 0734 +81319E39 0735 +81319F30 0736 +81319F31 0737 +81319F32 0738 +81319F33 0739 +81319F34 073A +81319F35 073B +81319F36 073C +81319F37 073D +81319F38 073E +81319F39 073F +8131A030 0740 +8131A031 0741 +8131A032 0742 +8131A033 0743 +8131A034 0744 +8131A035 0745 +8131A036 0746 +8131A037 0747 +8131A038 0748 +8131A039 0749 +8131A130 074A +8131A131 074B +8131A132 074C +8131A133 074D +8131A134 074E +8131A135 074F +8131A136 0750 +8131A137 0751 +8131A138 0752 +8131A139 0753 +8131A230 0754 +8131A231 0755 +8131A232 0756 +8131A233 0757 +8131A234 0758 +8131A235 0759 +8131A236 075A +8131A237 075B +8131A238 075C +8131A239 075D +8131A330 075E +8131A331 075F +8131A332 0760 +8131A333 0761 +8131A334 0762 +8131A335 0763 +8131A336 0764 +8131A337 0765 +8131A338 0766 +8131A339 0767 +8131A430 0768 +8131A431 0769 +8131A432 076A +8131A433 076B +8131A434 076C +8131A435 076D +8131A436 076E +8131A437 076F +8131A438 0770 +8131A439 0771 +8131A530 0772 +8131A531 0773 +8131A532 0774 +8131A533 0775 +8131A534 0776 +8131A535 0777 +8131A536 0778 +8131A537 0779 +8131A538 077A +8131A539 077B +8131A630 077C +8131A631 077D +8131A632 077E +8131A633 077F +8131A634 0780 +8131A635 0781 +8131A636 0782 +8131A637 0783 +8131A638 0784 +8131A639 0785 +8131A730 0786 +8131A731 0787 +8131A732 0788 +8131A733 0789 +8131A734 078A +8131A735 078B +8131A736 078C +8131A737 078D +8131A738 078E +8131A739 078F +8131A830 0790 +8131A831 0791 +8131A832 0792 +8131A833 0793 +8131A834 0794 +8131A835 0795 +8131A836 0796 +8131A837 0797 +8131A838 0798 +8131A839 0799 +8131A930 079A +8131A931 079B +8131A932 079C +8131A933 079D +8131A934 079E +8131A935 079F +8131A936 07A0 +8131A937 07A1 +8131A938 07A2 +8131A939 07A3 +8131AA30 07A4 +8131AA31 07A5 +8131AA32 07A6 +8131AA33 07A7 +8131AA34 07A8 +8131AA35 07A9 +8131AA36 07AA +8131AA37 07AB +8131AA38 07AC +8131AA39 07AD +8131AB30 07AE +8131AB31 07AF +8131AB32 07B0 +8131AB33 07B1 +8131AB34 07B2 +8131AB35 07B3 +8131AB36 07B4 +8131AB37 07B5 +8131AB38 07B6 +8131AB39 07B7 +8131AC30 07B8 +8131AC31 07B9 +8131AC32 07BA +8131AC33 07BB +8131AC34 07BC +8131AC35 07BD +8131AC36 07BE +8131AC37 07BF +8131AC38 07C0 +8131AC39 07C1 +8131AD30 07C2 +8131AD31 07C3 +8131AD32 07C4 +8131AD33 07C5 +8131AD34 07C6 +8131AD35 07C7 +8131AD36 07C8 +8131AD37 07C9 +8131AD38 07CA +8131AD39 07CB +8131AE30 07CC +8131AE31 07CD +8131AE32 07CE +8131AE33 07CF +8131AE34 07D0 +8131AE35 07D1 +8131AE36 07D2 +8131AE37 07D3 +8131AE38 07D4 +8131AE39 07D5 +8131AF30 07D6 +8131AF31 07D7 +8131AF32 07D8 +8131AF33 07D9 +8131AF34 07DA +8131AF35 07DB +8131AF36 07DC +8131AF37 07DD +8131AF38 07DE +8131AF39 07DF +8131B030 07E0 +8131B031 07E1 +8131B032 07E2 +8131B033 07E3 +8131B034 07E4 +8131B035 07E5 +8131B036 07E6 +8131B037 07E7 +8131B038 07E8 +8131B039 07E9 +8131B130 07EA +8131B131 07EB +8131B132 07EC +8131B133 07ED +8131B134 07EE +8131B135 07EF +8131B136 07F0 +8131B137 07F1 +8131B138 07F2 +8131B139 07F3 +8131B230 07F4 +8131B231 07F5 +8131B232 07F6 +8131B233 07F7 +8131B234 07F8 +8131B235 07F9 +8131B236 07FA +8131B237 07FB +8131B238 07FC +8131B239 07FD +8131B330 07FE +8131B331 07FF +8131B332 0800 +8131B333 0801 +8131B334 0802 +8131B335 0803 +8131B336 0804 +8131B337 0805 +8131B338 0806 +8131B339 0807 +8131B430 0808 +8131B431 0809 +8131B432 080A +8131B433 080B +8131B434 080C +8131B435 080D +8131B436 080E +8131B437 080F +8131B438 0810 +8131B439 0811 +8131B530 0812 +8131B531 0813 +8131B532 0814 +8131B533 0815 +8131B534 0816 +8131B535 0817 +8131B536 0818 +8131B537 0819 +8131B538 081A +8131B539 081B +8131B630 081C +8131B631 081D +8131B632 081E +8131B633 081F +8131B634 0820 +8131B635 0821 +8131B636 0822 +8131B637 0823 +8131B638 0824 +8131B639 0825 +8131B730 0826 +8131B731 0827 +8131B732 0828 +8131B733 0829 +8131B734 082A +8131B735 082B +8131B736 082C +8131B737 082D +8131B738 082E +8131B739 082F +8131B830 0830 +8131B831 0831 +8131B832 0832 +8131B833 0833 +8131B834 0834 +8131B835 0835 +8131B836 0836 +8131B837 0837 +8131B838 0838 +8131B839 0839 +8131B930 083A +8131B931 083B +8131B932 083C +8131B933 083D +8131B934 083E +8131B935 083F +8131B936 0840 +8131B937 0841 +8131B938 0842 +8131B939 0843 +8131BA30 0844 +8131BA31 0845 +8131BA32 0846 +8131BA33 0847 +8131BA34 0848 +8131BA35 0849 +8131BA36 084A +8131BA37 084B +8131BA38 084C +8131BA39 084D +8131BB30 084E +8131BB31 084F +8131BB32 0850 +8131BB33 0851 +8131BB34 0852 +8131BB35 0853 +8131BB36 0854 +8131BB37 0855 +8131BB38 0856 +8131BB39 0857 +8131BC30 0858 +8131BC31 0859 +8131BC32 085A +8131BC33 085B +8131BC34 085C +8131BC35 085D +8131BC36 085E +8131BC37 085F +8131BC38 0860 +8131BC39 0861 +8131BD30 0862 +8131BD31 0863 +8131BD32 0864 +8131BD33 0865 +8131BD34 0866 +8131BD35 0867 +8131BD36 0868 +8131BD37 0869 +8131BD38 086A +8131BD39 086B +8131BE30 086C +8131BE31 086D +8131BE32 086E +8131BE33 086F +8131BE34 0870 +8131BE35 0871 +8131BE36 0872 +8131BE37 0873 +8131BE38 0874 +8131BE39 0875 +8131BF30 0876 +8131BF31 0877 +8131BF32 0878 +8131BF33 0879 +8131BF34 087A +8131BF35 087B +8131BF36 087C +8131BF37 087D +8131BF38 087E +8131BF39 087F +8131C030 0880 +8131C031 0881 +8131C032 0882 +8131C033 0883 +8131C034 0884 +8131C035 0885 +8131C036 0886 +8131C037 0887 +8131C038 0888 +8131C039 0889 +8131C130 088A +8131C131 088B +8131C132 088C +8131C133 088D +8131C134 088E +8131C135 088F +8131C136 0890 +8131C137 0891 +8131C138 0892 +8131C139 0893 +8131C230 0894 +8131C231 0895 +8131C232 0896 +8131C233 0897 +8131C234 0898 +8131C235 0899 +8131C236 089A +8131C237 089B +8131C238 089C +8131C239 089D +8131C330 089E +8131C331 089F +8131C332 08A0 +8131C333 08A1 +8131C334 08A2 +8131C335 08A3 +8131C336 08A4 +8131C337 08A5 +8131C338 08A6 +8131C339 08A7 +8131C430 08A8 +8131C431 08A9 +8131C432 08AA +8131C433 08AB +8131C434 08AC +8131C435 08AD +8131C436 08AE +8131C437 08AF +8131C438 08B0 +8131C439 08B1 +8131C530 08B2 +8131C531 08B3 +8131C532 08B4 +8131C533 08B5 +8131C534 08B6 +8131C535 08B7 +8131C536 08B8 +8131C537 08B9 +8131C538 08BA +8131C539 08BB +8131C630 08BC +8131C631 08BD +8131C632 08BE +8131C633 08BF +8131C634 08C0 +8131C635 08C1 +8131C636 08C2 +8131C637 08C3 +8131C638 08C4 +8131C639 08C5 +8131C730 08C6 +8131C731 08C7 +8131C732 08C8 +8131C733 08C9 +8131C734 08CA +8131C735 08CB +8131C736 08CC +8131C737 08CD +8131C738 08CE +8131C739 08CF +8131C830 08D0 +8131C831 08D1 +8131C832 08D2 +8131C833 08D3 +8131C834 08D4 +8131C835 08D5 +8131C836 08D6 +8131C837 08D7 +8131C838 08D8 +8131C839 08D9 +8131C930 08DA +8131C931 08DB +8131C932 08DC +8131C933 08DD +8131C934 08DE +8131C935 08DF +8131C936 08E0 +8131C937 08E1 +8131C938 08E2 +8131C939 08E3 +8131CA30 08E4 +8131CA31 08E5 +8131CA32 08E6 +8131CA33 08E7 +8131CA34 08E8 +8131CA35 08E9 +8131CA36 08EA +8131CA37 08EB +8131CA38 08EC +8131CA39 08ED +8131CB30 08EE +8131CB31 08EF +8131CB32 08F0 +8131CB33 08F1 +8131CB34 08F2 +8131CB35 08F3 +8131CB36 08F4 +8131CB37 08F5 +8131CB38 08F6 +8131CB39 08F7 +8131CC30 08F8 +8131CC31 08F9 +8131CC32 08FA +8131CC33 08FB +8131CC34 08FC +8131CC35 08FD +8131CC36 08FE +8131CC37 08FF +8131CC38 0900 +8131CC39 0901 +8131CD30 0902 +8131CD31 0903 +8131CD32 0904 +8131CD33 0905 +8131CD34 0906 +8131CD35 0907 +8131CD36 0908 +8131CD37 0909 +8131CD38 090A +8131CD39 090B +8131CE30 090C +8131CE31 090D +8131CE32 090E +8131CE33 090F +8131CE34 0910 +8131CE35 0911 +8131CE36 0912 +8131CE37 0913 +8131CE38 0914 +8131CE39 0915 +8131CF30 0916 +8131CF31 0917 +8131CF32 0918 +8131CF33 0919 +8131CF34 091A +8131CF35 091B +8131CF36 091C +8131CF37 091D +8131CF38 091E +8131CF39 091F +8131D030 0920 +8131D031 0921 +8131D032 0922 +8131D033 0923 +8131D034 0924 +8131D035 0925 +8131D036 0926 +8131D037 0927 +8131D038 0928 +8131D039 0929 +8131D130 092A +8131D131 092B +8131D132 092C +8131D133 092D +8131D134 092E +8131D135 092F +8131D136 0930 +8131D137 0931 +8131D138 0932 +8131D139 0933 +8131D230 0934 +8131D231 0935 +8131D232 0936 +8131D233 0937 +8131D234 0938 +8131D235 0939 +8131D236 093A +8131D237 093B +8131D238 093C +8131D239 093D +8131D330 093E +8131D331 093F +8131D332 0940 +8131D333 0941 +8131D334 0942 +8131D335 0943 +8131D336 0944 +8131D337 0945 +8131D338 0946 +8131D339 0947 +8131D430 0948 +8131D431 0949 +8131D432 094A +8131D433 094B +8131D434 094C +8131D435 094D +8131D436 094E +8131D437 094F +8131D438 0950 +8131D439 0951 +8131D530 0952 +8131D531 0953 +8131D532 0954 +8131D533 0955 +8131D534 0956 +8131D535 0957 +8131D536 0958 +8131D537 0959 +8131D538 095A +8131D539 095B +8131D630 095C +8131D631 095D +8131D632 095E +8131D633 095F +8131D634 0960 +8131D635 0961 +8131D636 0962 +8131D637 0963 +8131D638 0964 +8131D639 0965 +8131D730 0966 +8131D731 0967 +8131D732 0968 +8131D733 0969 +8131D734 096A +8131D735 096B +8131D736 096C +8131D737 096D +8131D738 096E +8131D739 096F +8131D830 0970 +8131D831 0971 +8131D832 0972 +8131D833 0973 +8131D834 0974 +8131D835 0975 +8131D836 0976 +8131D837 0977 +8131D838 0978 +8131D839 0979 +8131D930 097A +8131D931 097B +8131D932 097C +8131D933 097D +8131D934 097E +8131D935 097F +8131D936 0980 +8131D937 0981 +8131D938 0982 +8131D939 0983 +8131DA30 0984 +8131DA31 0985 +8131DA32 0986 +8131DA33 0987 +8131DA34 0988 +8131DA35 0989 +8131DA36 098A +8131DA37 098B +8131DA38 098C +8131DA39 098D +8131DB30 098E +8131DB31 098F +8131DB32 0990 +8131DB33 0991 +8131DB34 0992 +8131DB35 0993 +8131DB36 0994 +8131DB37 0995 +8131DB38 0996 +8131DB39 0997 +8131DC30 0998 +8131DC31 0999 +8131DC32 099A +8131DC33 099B +8131DC34 099C +8131DC35 099D +8131DC36 099E +8131DC37 099F +8131DC38 09A0 +8131DC39 09A1 +8131DD30 09A2 +8131DD31 09A3 +8131DD32 09A4 +8131DD33 09A5 +8131DD34 09A6 +8131DD35 09A7 +8131DD36 09A8 +8131DD37 09A9 +8131DD38 09AA +8131DD39 09AB +8131DE30 09AC +8131DE31 09AD +8131DE32 09AE +8131DE33 09AF +8131DE34 09B0 +8131DE35 09B1 +8131DE36 09B2 +8131DE37 09B3 +8131DE38 09B4 +8131DE39 09B5 +8131DF30 09B6 +8131DF31 09B7 +8131DF32 09B8 +8131DF33 09B9 +8131DF34 09BA +8131DF35 09BB +8131DF36 09BC +8131DF37 09BD +8131DF38 09BE +8131DF39 09BF +8131E030 09C0 +8131E031 09C1 +8131E032 09C2 +8131E033 09C3 +8131E034 09C4 +8131E035 09C5 +8131E036 09C6 +8131E037 09C7 +8131E038 09C8 +8131E039 09C9 +8131E130 09CA +8131E131 09CB +8131E132 09CC +8131E133 09CD +8131E134 09CE +8131E135 09CF +8131E136 09D0 +8131E137 09D1 +8131E138 09D2 +8131E139 09D3 +8131E230 09D4 +8131E231 09D5 +8131E232 09D6 +8131E233 09D7 +8131E234 09D8 +8131E235 09D9 +8131E236 09DA +8131E237 09DB +8131E238 09DC +8131E239 09DD +8131E330 09DE +8131E331 09DF +8131E332 09E0 +8131E333 09E1 +8131E334 09E2 +8131E335 09E3 +8131E336 09E4 +8131E337 09E5 +8131E338 09E6 +8131E339 09E7 +8131E430 09E8 +8131E431 09E9 +8131E432 09EA +8131E433 09EB +8131E434 09EC +8131E435 09ED +8131E436 09EE +8131E437 09EF +8131E438 09F0 +8131E439 09F1 +8131E530 09F2 +8131E531 09F3 +8131E532 09F4 +8131E533 09F5 +8131E534 09F6 +8131E535 09F7 +8131E536 09F8 +8131E537 09F9 +8131E538 09FA +8131E539 09FB +8131E630 09FC +8131E631 09FD +8131E632 09FE +8131E633 09FF +8131E634 0A00 +8131E635 0A01 +8131E636 0A02 +8131E637 0A03 +8131E638 0A04 +8131E639 0A05 +8131E730 0A06 +8131E731 0A07 +8131E732 0A08 +8131E733 0A09 +8131E734 0A0A +8131E735 0A0B +8131E736 0A0C +8131E737 0A0D +8131E738 0A0E +8131E739 0A0F +8131E830 0A10 +8131E831 0A11 +8131E832 0A12 +8131E833 0A13 +8131E834 0A14 +8131E835 0A15 +8131E836 0A16 +8131E837 0A17 +8131E838 0A18 +8131E839 0A19 +8131E930 0A1A +8131E931 0A1B +8131E932 0A1C +8131E933 0A1D +8131E934 0A1E +8131E935 0A1F +8131E936 0A20 +8131E937 0A21 +8131E938 0A22 +8131E939 0A23 +8131EA30 0A24 +8131EA31 0A25 +8131EA32 0A26 +8131EA33 0A27 +8131EA34 0A28 +8131EA35 0A29 +8131EA36 0A2A +8131EA37 0A2B +8131EA38 0A2C +8131EA39 0A2D +8131EB30 0A2E +8131EB31 0A2F +8131EB32 0A30 +8131EB33 0A31 +8131EB34 0A32 +8131EB35 0A33 +8131EB36 0A34 +8131EB37 0A35 +8131EB38 0A36 +8131EB39 0A37 +8131EC30 0A38 +8131EC31 0A39 +8131EC32 0A3A +8131EC33 0A3B +8131EC34 0A3C +8131EC35 0A3D +8131EC36 0A3E +8131EC37 0A3F +8131EC38 0A40 +8131EC39 0A41 +8131ED30 0A42 +8131ED31 0A43 +8131ED32 0A44 +8131ED33 0A45 +8131ED34 0A46 +8131ED35 0A47 +8131ED36 0A48 +8131ED37 0A49 +8131ED38 0A4A +8131ED39 0A4B +8131EE30 0A4C +8131EE31 0A4D +8131EE32 0A4E +8131EE33 0A4F +8131EE34 0A50 +8131EE35 0A51 +8131EE36 0A52 +8131EE37 0A53 +8131EE38 0A54 +8131EE39 0A55 +8131EF30 0A56 +8131EF31 0A57 +8131EF32 0A58 +8131EF33 0A59 +8131EF34 0A5A +8131EF35 0A5B +8131EF36 0A5C +8131EF37 0A5D +8131EF38 0A5E +8131EF39 0A5F +8131F030 0A60 +8131F031 0A61 +8131F032 0A62 +8131F033 0A63 +8131F034 0A64 +8131F035 0A65 +8131F036 0A66 +8131F037 0A67 +8131F038 0A68 +8131F039 0A69 +8131F130 0A6A +8131F131 0A6B +8131F132 0A6C +8131F133 0A6D +8131F134 0A6E +8131F135 0A6F +8131F136 0A70 +8131F137 0A71 +8131F138 0A72 +8131F139 0A73 +8131F230 0A74 +8131F231 0A75 +8131F232 0A76 +8131F233 0A77 +8131F234 0A78 +8131F235 0A79 +8131F236 0A7A +8131F237 0A7B +8131F238 0A7C +8131F239 0A7D +8131F330 0A7E +8131F331 0A7F +8131F332 0A80 +8131F333 0A81 +8131F334 0A82 +8131F335 0A83 +8131F336 0A84 +8131F337 0A85 +8131F338 0A86 +8131F339 0A87 +8131F430 0A88 +8131F431 0A89 +8131F432 0A8A +8131F433 0A8B +8131F434 0A8C +8131F435 0A8D +8131F436 0A8E +8131F437 0A8F +8131F438 0A90 +8131F439 0A91 +8131F530 0A92 +8131F531 0A93 +8131F532 0A94 +8131F533 0A95 +8131F534 0A96 +8131F535 0A97 +8131F536 0A98 +8131F537 0A99 +8131F538 0A9A +8131F539 0A9B +8131F630 0A9C +8131F631 0A9D +8131F632 0A9E +8131F633 0A9F +8131F634 0AA0 +8131F635 0AA1 +8131F636 0AA2 +8131F637 0AA3 +8131F638 0AA4 +8131F639 0AA5 +8131F730 0AA6 +8131F731 0AA7 +8131F732 0AA8 +8131F733 0AA9 +8131F734 0AAA +8131F735 0AAB +8131F736 0AAC +8131F737 0AAD +8131F738 0AAE +8131F739 0AAF +8131F830 0AB0 +8131F831 0AB1 +8131F832 0AB2 +8131F833 0AB3 +8131F834 0AB4 +8131F835 0AB5 +8131F836 0AB6 +8131F837 0AB7 +8131F838 0AB8 +8131F839 0AB9 +8131F930 0ABA +8131F931 0ABB +8131F932 0ABC +8131F933 0ABD +8131F934 0ABE +8131F935 0ABF +8131F936 0AC0 +8131F937 0AC1 +8131F938 0AC2 +8131F939 0AC3 +8131FA30 0AC4 +8131FA31 0AC5 +8131FA32 0AC6 +8131FA33 0AC7 +8131FA34 0AC8 +8131FA35 0AC9 +8131FA36 0ACA +8131FA37 0ACB +8131FA38 0ACC +8131FA39 0ACD +8131FB30 0ACE +8131FB31 0ACF +8131FB32 0AD0 +8131FB33 0AD1 +8131FB34 0AD2 +8131FB35 0AD3 +8131FB36 0AD4 +8131FB37 0AD5 +8131FB38 0AD6 +8131FB39 0AD7 +8131FC30 0AD8 +8131FC31 0AD9 +8131FC32 0ADA +8131FC33 0ADB +8131FC34 0ADC +8131FC35 0ADD +8131FC36 0ADE +8131FC37 0ADF +8131FC38 0AE0 +8131FC39 0AE1 +8131FD30 0AE2 +8131FD31 0AE3 +8131FD32 0AE4 +8131FD33 0AE5 +8131FD34 0AE6 +8131FD35 0AE7 +8131FD36 0AE8 +8131FD37 0AE9 +8131FD38 0AEA +8131FD39 0AEB +8131FE30 0AEC +8131FE31 0AED +8131FE32 0AEE +8131FE33 0AEF +8131FE34 0AF0 +8131FE35 0AF1 +8131FE36 0AF2 +8131FE37 0AF3 +8131FE38 0AF4 +8131FE39 0AF5 +81328130 0AF6 +81328131 0AF7 +81328132 0AF8 +81328133 0AF9 +81328134 0AFA +81328135 0AFB +81328136 0AFC +81328137 0AFD +81328138 0AFE +81328139 0AFF +81328230 0B00 +81328231 0B01 +81328232 0B02 +81328233 0B03 +81328234 0B04 +81328235 0B05 +81328236 0B06 +81328237 0B07 +81328238 0B08 +81328239 0B09 +81328330 0B0A +81328331 0B0B +81328332 0B0C +81328333 0B0D +81328334 0B0E +81328335 0B0F +81328336 0B10 +81328337 0B11 +81328338 0B12 +81328339 0B13 +81328430 0B14 +81328431 0B15 +81328432 0B16 +81328433 0B17 +81328434 0B18 +81328435 0B19 +81328436 0B1A +81328437 0B1B +81328438 0B1C +81328439 0B1D +81328530 0B1E +81328531 0B1F +81328532 0B20 +81328533 0B21 +81328534 0B22 +81328535 0B23 +81328536 0B24 +81328537 0B25 +81328538 0B26 +81328539 0B27 +81328630 0B28 +81328631 0B29 +81328632 0B2A +81328633 0B2B +81328634 0B2C +81328635 0B2D +81328636 0B2E +81328637 0B2F +81328638 0B30 +81328639 0B31 +81328730 0B32 +81328731 0B33 +81328732 0B34 +81328733 0B35 +81328734 0B36 +81328735 0B37 +81328736 0B38 +81328737 0B39 +81328738 0B3A +81328739 0B3B +81328830 0B3C +81328831 0B3D +81328832 0B3E +81328833 0B3F +81328834 0B40 +81328835 0B41 +81328836 0B42 +81328837 0B43 +81328838 0B44 +81328839 0B45 +81328930 0B46 +81328931 0B47 +81328932 0B48 +81328933 0B49 +81328934 0B4A +81328935 0B4B +81328936 0B4C +81328937 0B4D +81328938 0B4E +81328939 0B4F +81328A30 0B50 +81328A31 0B51 +81328A32 0B52 +81328A33 0B53 +81328A34 0B54 +81328A35 0B55 +81328A36 0B56 +81328A37 0B57 +81328A38 0B58 +81328A39 0B59 +81328B30 0B5A +81328B31 0B5B +81328B32 0B5C +81328B33 0B5D +81328B34 0B5E +81328B35 0B5F +81328B36 0B60 +81328B37 0B61 +81328B38 0B62 +81328B39 0B63 +81328C30 0B64 +81328C31 0B65 +81328C32 0B66 +81328C33 0B67 +81328C34 0B68 +81328C35 0B69 +81328C36 0B6A +81328C37 0B6B +81328C38 0B6C +81328C39 0B6D +81328D30 0B6E +81328D31 0B6F +81328D32 0B70 +81328D33 0B71 +81328D34 0B72 +81328D35 0B73 +81328D36 0B74 +81328D37 0B75 +81328D38 0B76 +81328D39 0B77 +81328E30 0B78 +81328E31 0B79 +81328E32 0B7A +81328E33 0B7B +81328E34 0B7C +81328E35 0B7D +81328E36 0B7E +81328E37 0B7F +81328E38 0B80 +81328E39 0B81 +81328F30 0B82 +81328F31 0B83 +81328F32 0B84 +81328F33 0B85 +81328F34 0B86 +81328F35 0B87 +81328F36 0B88 +81328F37 0B89 +81328F38 0B8A +81328F39 0B8B +81329030 0B8C +81329031 0B8D +81329032 0B8E +81329033 0B8F +81329034 0B90 +81329035 0B91 +81329036 0B92 +81329037 0B93 +81329038 0B94 +81329039 0B95 +81329130 0B96 +81329131 0B97 +81329132 0B98 +81329133 0B99 +81329134 0B9A +81329135 0B9B +81329136 0B9C +81329137 0B9D +81329138 0B9E +81329139 0B9F +81329230 0BA0 +81329231 0BA1 +81329232 0BA2 +81329233 0BA3 +81329234 0BA4 +81329235 0BA5 +81329236 0BA6 +81329237 0BA7 +81329238 0BA8 +81329239 0BA9 +81329330 0BAA +81329331 0BAB +81329332 0BAC +81329333 0BAD +81329334 0BAE +81329335 0BAF +81329336 0BB0 +81329337 0BB1 +81329338 0BB2 +81329339 0BB3 +81329430 0BB4 +81329431 0BB5 +81329432 0BB6 +81329433 0BB7 +81329434 0BB8 +81329435 0BB9 +81329436 0BBA +81329437 0BBB +81329438 0BBC +81329439 0BBD +81329530 0BBE +81329531 0BBF +81329532 0BC0 +81329533 0BC1 +81329534 0BC2 +81329535 0BC3 +81329536 0BC4 +81329537 0BC5 +81329538 0BC6 +81329539 0BC7 +81329630 0BC8 +81329631 0BC9 +81329632 0BCA +81329633 0BCB +81329634 0BCC +81329635 0BCD +81329636 0BCE +81329637 0BCF +81329638 0BD0 +81329639 0BD1 +81329730 0BD2 +81329731 0BD3 +81329732 0BD4 +81329733 0BD5 +81329734 0BD6 +81329735 0BD7 +81329736 0BD8 +81329737 0BD9 +81329738 0BDA +81329739 0BDB +81329830 0BDC +81329831 0BDD +81329832 0BDE +81329833 0BDF +81329834 0BE0 +81329835 0BE1 +81329836 0BE2 +81329837 0BE3 +81329838 0BE4 +81329839 0BE5 +81329930 0BE6 +81329931 0BE7 +81329932 0BE8 +81329933 0BE9 +81329934 0BEA +81329935 0BEB +81329936 0BEC +81329937 0BED +81329938 0BEE +81329939 0BEF +81329A30 0BF0 +81329A31 0BF1 +81329A32 0BF2 +81329A33 0BF3 +81329A34 0BF4 +81329A35 0BF5 +81329A36 0BF6 +81329A37 0BF7 +81329A38 0BF8 +81329A39 0BF9 +81329B30 0BFA +81329B31 0BFB +81329B32 0BFC +81329B33 0BFD +81329B34 0BFE +81329B35 0BFF +81329B36 0C00 +81329B37 0C01 +81329B38 0C02 +81329B39 0C03 +81329C30 0C04 +81329C31 0C05 +81329C32 0C06 +81329C33 0C07 +81329C34 0C08 +81329C35 0C09 +81329C36 0C0A +81329C37 0C0B +81329C38 0C0C +81329C39 0C0D +81329D30 0C0E +81329D31 0C0F +81329D32 0C10 +81329D33 0C11 +81329D34 0C12 +81329D35 0C13 +81329D36 0C14 +81329D37 0C15 +81329D38 0C16 +81329D39 0C17 +81329E30 0C18 +81329E31 0C19 +81329E32 0C1A +81329E33 0C1B +81329E34 0C1C +81329E35 0C1D +81329E36 0C1E +81329E37 0C1F +81329E38 0C20 +81329E39 0C21 +81329F30 0C22 +81329F31 0C23 +81329F32 0C24 +81329F33 0C25 +81329F34 0C26 +81329F35 0C27 +81329F36 0C28 +81329F37 0C29 +81329F38 0C2A +81329F39 0C2B +8132A030 0C2C +8132A031 0C2D +8132A032 0C2E +8132A033 0C2F +8132A034 0C30 +8132A035 0C31 +8132A036 0C32 +8132A037 0C33 +8132A038 0C34 +8132A039 0C35 +8132A130 0C36 +8132A131 0C37 +8132A132 0C38 +8132A133 0C39 +8132A134 0C3A +8132A135 0C3B +8132A136 0C3C +8132A137 0C3D +8132A138 0C3E +8132A139 0C3F +8132A230 0C40 +8132A231 0C41 +8132A232 0C42 +8132A233 0C43 +8132A234 0C44 +8132A235 0C45 +8132A236 0C46 +8132A237 0C47 +8132A238 0C48 +8132A239 0C49 +8132A330 0C4A +8132A331 0C4B +8132A332 0C4C +8132A333 0C4D +8132A334 0C4E +8132A335 0C4F +8132A336 0C50 +8132A337 0C51 +8132A338 0C52 +8132A339 0C53 +8132A430 0C54 +8132A431 0C55 +8132A432 0C56 +8132A433 0C57 +8132A434 0C58 +8132A435 0C59 +8132A436 0C5A +8132A437 0C5B +8132A438 0C5C +8132A439 0C5D +8132A530 0C5E +8132A531 0C5F +8132A532 0C60 +8132A533 0C61 +8132A534 0C62 +8132A535 0C63 +8132A536 0C64 +8132A537 0C65 +8132A538 0C66 +8132A539 0C67 +8132A630 0C68 +8132A631 0C69 +8132A632 0C6A +8132A633 0C6B +8132A634 0C6C +8132A635 0C6D +8132A636 0C6E +8132A637 0C6F +8132A638 0C70 +8132A639 0C71 +8132A730 0C72 +8132A731 0C73 +8132A732 0C74 +8132A733 0C75 +8132A734 0C76 +8132A735 0C77 +8132A736 0C78 +8132A737 0C79 +8132A738 0C7A +8132A739 0C7B +8132A830 0C7C +8132A831 0C7D +8132A832 0C7E +8132A833 0C7F +8132A834 0C80 +8132A835 0C81 +8132A836 0C82 +8132A837 0C83 +8132A838 0C84 +8132A839 0C85 +8132A930 0C86 +8132A931 0C87 +8132A932 0C88 +8132A933 0C89 +8132A934 0C8A +8132A935 0C8B +8132A936 0C8C +8132A937 0C8D +8132A938 0C8E +8132A939 0C8F +8132AA30 0C90 +8132AA31 0C91 +8132AA32 0C92 +8132AA33 0C93 +8132AA34 0C94 +8132AA35 0C95 +8132AA36 0C96 +8132AA37 0C97 +8132AA38 0C98 +8132AA39 0C99 +8132AB30 0C9A +8132AB31 0C9B +8132AB32 0C9C +8132AB33 0C9D +8132AB34 0C9E +8132AB35 0C9F +8132AB36 0CA0 +8132AB37 0CA1 +8132AB38 0CA2 +8132AB39 0CA3 +8132AC30 0CA4 +8132AC31 0CA5 +8132AC32 0CA6 +8132AC33 0CA7 +8132AC34 0CA8 +8132AC35 0CA9 +8132AC36 0CAA +8132AC37 0CAB +8132AC38 0CAC +8132AC39 0CAD +8132AD30 0CAE +8132AD31 0CAF +8132AD32 0CB0 +8132AD33 0CB1 +8132AD34 0CB2 +8132AD35 0CB3 +8132AD36 0CB4 +8132AD37 0CB5 +8132AD38 0CB6 +8132AD39 0CB7 +8132AE30 0CB8 +8132AE31 0CB9 +8132AE32 0CBA +8132AE33 0CBB +8132AE34 0CBC +8132AE35 0CBD +8132AE36 0CBE +8132AE37 0CBF +8132AE38 0CC0 +8132AE39 0CC1 +8132AF30 0CC2 +8132AF31 0CC3 +8132AF32 0CC4 +8132AF33 0CC5 +8132AF34 0CC6 +8132AF35 0CC7 +8132AF36 0CC8 +8132AF37 0CC9 +8132AF38 0CCA +8132AF39 0CCB +8132B030 0CCC +8132B031 0CCD +8132B032 0CCE +8132B033 0CCF +8132B034 0CD0 +8132B035 0CD1 +8132B036 0CD2 +8132B037 0CD3 +8132B038 0CD4 +8132B039 0CD5 +8132B130 0CD6 +8132B131 0CD7 +8132B132 0CD8 +8132B133 0CD9 +8132B134 0CDA +8132B135 0CDB +8132B136 0CDC +8132B137 0CDD +8132B138 0CDE +8132B139 0CDF +8132B230 0CE0 +8132B231 0CE1 +8132B232 0CE2 +8132B233 0CE3 +8132B234 0CE4 +8132B235 0CE5 +8132B236 0CE6 +8132B237 0CE7 +8132B238 0CE8 +8132B239 0CE9 +8132B330 0CEA +8132B331 0CEB +8132B332 0CEC +8132B333 0CED +8132B334 0CEE +8132B335 0CEF +8132B336 0CF0 +8132B337 0CF1 +8132B338 0CF2 +8132B339 0CF3 +8132B430 0CF4 +8132B431 0CF5 +8132B432 0CF6 +8132B433 0CF7 +8132B434 0CF8 +8132B435 0CF9 +8132B436 0CFA +8132B437 0CFB +8132B438 0CFC +8132B439 0CFD +8132B530 0CFE +8132B531 0CFF +8132B532 0D00 +8132B533 0D01 +8132B534 0D02 +8132B535 0D03 +8132B536 0D04 +8132B537 0D05 +8132B538 0D06 +8132B539 0D07 +8132B630 0D08 +8132B631 0D09 +8132B632 0D0A +8132B633 0D0B +8132B634 0D0C +8132B635 0D0D +8132B636 0D0E +8132B637 0D0F +8132B638 0D10 +8132B639 0D11 +8132B730 0D12 +8132B731 0D13 +8132B732 0D14 +8132B733 0D15 +8132B734 0D16 +8132B735 0D17 +8132B736 0D18 +8132B737 0D19 +8132B738 0D1A +8132B739 0D1B +8132B830 0D1C +8132B831 0D1D +8132B832 0D1E +8132B833 0D1F +8132B834 0D20 +8132B835 0D21 +8132B836 0D22 +8132B837 0D23 +8132B838 0D24 +8132B839 0D25 +8132B930 0D26 +8132B931 0D27 +8132B932 0D28 +8132B933 0D29 +8132B934 0D2A +8132B935 0D2B +8132B936 0D2C +8132B937 0D2D +8132B938 0D2E +8132B939 0D2F +8132BA30 0D30 +8132BA31 0D31 +8132BA32 0D32 +8132BA33 0D33 +8132BA34 0D34 +8132BA35 0D35 +8132BA36 0D36 +8132BA37 0D37 +8132BA38 0D38 +8132BA39 0D39 +8132BB30 0D3A +8132BB31 0D3B +8132BB32 0D3C +8132BB33 0D3D +8132BB34 0D3E +8132BB35 0D3F +8132BB36 0D40 +8132BB37 0D41 +8132BB38 0D42 +8132BB39 0D43 +8132BC30 0D44 +8132BC31 0D45 +8132BC32 0D46 +8132BC33 0D47 +8132BC34 0D48 +8132BC35 0D49 +8132BC36 0D4A +8132BC37 0D4B +8132BC38 0D4C +8132BC39 0D4D +8132BD30 0D4E +8132BD31 0D4F +8132BD32 0D50 +8132BD33 0D51 +8132BD34 0D52 +8132BD35 0D53 +8132BD36 0D54 +8132BD37 0D55 +8132BD38 0D56 +8132BD39 0D57 +8132BE30 0D58 +8132BE31 0D59 +8132BE32 0D5A +8132BE33 0D5B +8132BE34 0D5C +8132BE35 0D5D +8132BE36 0D5E +8132BE37 0D5F +8132BE38 0D60 +8132BE39 0D61 +8132BF30 0D62 +8132BF31 0D63 +8132BF32 0D64 +8132BF33 0D65 +8132BF34 0D66 +8132BF35 0D67 +8132BF36 0D68 +8132BF37 0D69 +8132BF38 0D6A +8132BF39 0D6B +8132C030 0D6C +8132C031 0D6D +8132C032 0D6E +8132C033 0D6F +8132C034 0D70 +8132C035 0D71 +8132C036 0D72 +8132C037 0D73 +8132C038 0D74 +8132C039 0D75 +8132C130 0D76 +8132C131 0D77 +8132C132 0D78 +8132C133 0D79 +8132C134 0D7A +8132C135 0D7B +8132C136 0D7C +8132C137 0D7D +8132C138 0D7E +8132C139 0D7F +8132C230 0D80 +8132C231 0D81 +8132C232 0D82 +8132C233 0D83 +8132C234 0D84 +8132C235 0D85 +8132C236 0D86 +8132C237 0D87 +8132C238 0D88 +8132C239 0D89 +8132C330 0D8A +8132C331 0D8B +8132C332 0D8C +8132C333 0D8D +8132C334 0D8E +8132C335 0D8F +8132C336 0D90 +8132C337 0D91 +8132C338 0D92 +8132C339 0D93 +8132C430 0D94 +8132C431 0D95 +8132C432 0D96 +8132C433 0D97 +8132C434 0D98 +8132C435 0D99 +8132C436 0D9A +8132C437 0D9B +8132C438 0D9C +8132C439 0D9D +8132C530 0D9E +8132C531 0D9F +8132C532 0DA0 +8132C533 0DA1 +8132C534 0DA2 +8132C535 0DA3 +8132C536 0DA4 +8132C537 0DA5 +8132C538 0DA6 +8132C539 0DA7 +8132C630 0DA8 +8132C631 0DA9 +8132C632 0DAA +8132C633 0DAB +8132C634 0DAC +8132C635 0DAD +8132C636 0DAE +8132C637 0DAF +8132C638 0DB0 +8132C639 0DB1 +8132C730 0DB2 +8132C731 0DB3 +8132C732 0DB4 +8132C733 0DB5 +8132C734 0DB6 +8132C735 0DB7 +8132C736 0DB8 +8132C737 0DB9 +8132C738 0DBA +8132C739 0DBB +8132C830 0DBC +8132C831 0DBD +8132C832 0DBE +8132C833 0DBF +8132C834 0DC0 +8132C835 0DC1 +8132C836 0DC2 +8132C837 0DC3 +8132C838 0DC4 +8132C839 0DC5 +8132C930 0DC6 +8132C931 0DC7 +8132C932 0DC8 +8132C933 0DC9 +8132C934 0DCA +8132C935 0DCB +8132C936 0DCC +8132C937 0DCD +8132C938 0DCE +8132C939 0DCF +8132CA30 0DD0 +8132CA31 0DD1 +8132CA32 0DD2 +8132CA33 0DD3 +8132CA34 0DD4 +8132CA35 0DD5 +8132CA36 0DD6 +8132CA37 0DD7 +8132CA38 0DD8 +8132CA39 0DD9 +8132CB30 0DDA +8132CB31 0DDB +8132CB32 0DDC +8132CB33 0DDD +8132CB34 0DDE +8132CB35 0DDF +8132CB36 0DE0 +8132CB37 0DE1 +8132CB38 0DE2 +8132CB39 0DE3 +8132CC30 0DE4 +8132CC31 0DE5 +8132CC32 0DE6 +8132CC33 0DE7 +8132CC34 0DE8 +8132CC35 0DE9 +8132CC36 0DEA +8132CC37 0DEB +8132CC38 0DEC +8132CC39 0DED +8132CD30 0DEE +8132CD31 0DEF +8132CD32 0DF0 +8132CD33 0DF1 +8132CD34 0DF2 +8132CD35 0DF3 +8132CD36 0DF4 +8132CD37 0DF5 +8132CD38 0DF6 +8132CD39 0DF7 +8132CE30 0DF8 +8132CE31 0DF9 +8132CE32 0DFA +8132CE33 0DFB +8132CE34 0DFC +8132CE35 0DFD +8132CE36 0DFE +8132CE37 0DFF +8132CE38 0E00 +8132CE39 0E01 +8132CF30 0E02 +8132CF31 0E03 +8132CF32 0E04 +8132CF33 0E05 +8132CF34 0E06 +8132CF35 0E07 +8132CF36 0E08 +8132CF37 0E09 +8132CF38 0E0A +8132CF39 0E0B +8132D030 0E0C +8132D031 0E0D +8132D032 0E0E +8132D033 0E0F +8132D034 0E10 +8132D035 0E11 +8132D036 0E12 +8132D037 0E13 +8132D038 0E14 +8132D039 0E15 +8132D130 0E16 +8132D131 0E17 +8132D132 0E18 +8132D133 0E19 +8132D134 0E1A +8132D135 0E1B +8132D136 0E1C +8132D137 0E1D +8132D138 0E1E +8132D139 0E1F +8132D230 0E20 +8132D231 0E21 +8132D232 0E22 +8132D233 0E23 +8132D234 0E24 +8132D235 0E25 +8132D236 0E26 +8132D237 0E27 +8132D238 0E28 +8132D239 0E29 +8132D330 0E2A +8132D331 0E2B +8132D332 0E2C +8132D333 0E2D +8132D334 0E2E +8132D335 0E2F +8132D336 0E30 +8132D337 0E31 +8132D338 0E32 +8132D339 0E33 +8132D430 0E34 +8132D431 0E35 +8132D432 0E36 +8132D433 0E37 +8132D434 0E38 +8132D435 0E39 +8132D436 0E3A +8132D437 0E3B +8132D438 0E3C +8132D439 0E3D +8132D530 0E3E +8132D531 0E3F +8132D532 0E40 +8132D533 0E41 +8132D534 0E42 +8132D535 0E43 +8132D536 0E44 +8132D537 0E45 +8132D538 0E46 +8132D539 0E47 +8132D630 0E48 +8132D631 0E49 +8132D632 0E4A +8132D633 0E4B +8132D634 0E4C +8132D635 0E4D +8132D636 0E4E +8132D637 0E4F +8132D638 0E50 +8132D639 0E51 +8132D730 0E52 +8132D731 0E53 +8132D732 0E54 +8132D733 0E55 +8132D734 0E56 +8132D735 0E57 +8132D736 0E58 +8132D737 0E59 +8132D738 0E5A +8132D739 0E5B +8132D830 0E5C +8132D831 0E5D +8132D832 0E5E +8132D833 0E5F +8132D834 0E60 +8132D835 0E61 +8132D836 0E62 +8132D837 0E63 +8132D838 0E64 +8132D839 0E65 +8132D930 0E66 +8132D931 0E67 +8132D932 0E68 +8132D933 0E69 +8132D934 0E6A +8132D935 0E6B +8132D936 0E6C +8132D937 0E6D +8132D938 0E6E +8132D939 0E6F +8132DA30 0E70 +8132DA31 0E71 +8132DA32 0E72 +8132DA33 0E73 +8132DA34 0E74 +8132DA35 0E75 +8132DA36 0E76 +8132DA37 0E77 +8132DA38 0E78 +8132DA39 0E79 +8132DB30 0E7A +8132DB31 0E7B +8132DB32 0E7C +8132DB33 0E7D +8132DB34 0E7E +8132DB35 0E7F +8132DB36 0E80 +8132DB37 0E81 +8132DB38 0E82 +8132DB39 0E83 +8132DC30 0E84 +8132DC31 0E85 +8132DC32 0E86 +8132DC33 0E87 +8132DC34 0E88 +8132DC35 0E89 +8132DC36 0E8A +8132DC37 0E8B +8132DC38 0E8C +8132DC39 0E8D +8132DD30 0E8E +8132DD31 0E8F +8132DD32 0E90 +8132DD33 0E91 +8132DD34 0E92 +8132DD35 0E93 +8132DD36 0E94 +8132DD37 0E95 +8132DD38 0E96 +8132DD39 0E97 +8132DE30 0E98 +8132DE31 0E99 +8132DE32 0E9A +8132DE33 0E9B +8132DE34 0E9C +8132DE35 0E9D +8132DE36 0E9E +8132DE37 0E9F +8132DE38 0EA0 +8132DE39 0EA1 +8132DF30 0EA2 +8132DF31 0EA3 +8132DF32 0EA4 +8132DF33 0EA5 +8132DF34 0EA6 +8132DF35 0EA7 +8132DF36 0EA8 +8132DF37 0EA9 +8132DF38 0EAA +8132DF39 0EAB +8132E030 0EAC +8132E031 0EAD +8132E032 0EAE +8132E033 0EAF +8132E034 0EB0 +8132E035 0EB1 +8132E036 0EB2 +8132E037 0EB3 +8132E038 0EB4 +8132E039 0EB5 +8132E130 0EB6 +8132E131 0EB7 +8132E132 0EB8 +8132E133 0EB9 +8132E134 0EBA +8132E135 0EBB +8132E136 0EBC +8132E137 0EBD +8132E138 0EBE +8132E139 0EBF +8132E230 0EC0 +8132E231 0EC1 +8132E232 0EC2 +8132E233 0EC3 +8132E234 0EC4 +8132E235 0EC5 +8132E236 0EC6 +8132E237 0EC7 +8132E238 0EC8 +8132E239 0EC9 +8132E330 0ECA +8132E331 0ECB +8132E332 0ECC +8132E333 0ECD +8132E334 0ECE +8132E335 0ECF +8132E336 0ED0 +8132E337 0ED1 +8132E338 0ED2 +8132E339 0ED3 +8132E430 0ED4 +8132E431 0ED5 +8132E432 0ED6 +8132E433 0ED7 +8132E434 0ED8 +8132E435 0ED9 +8132E436 0EDA +8132E437 0EDB +8132E438 0EDC +8132E439 0EDD +8132E530 0EDE +8132E531 0EDF +8132E532 0EE0 +8132E533 0EE1 +8132E534 0EE2 +8132E535 0EE3 +8132E536 0EE4 +8132E537 0EE5 +8132E538 0EE6 +8132E539 0EE7 +8132E630 0EE8 +8132E631 0EE9 +8132E632 0EEA +8132E633 0EEB +8132E634 0EEC +8132E635 0EED +8132E636 0EEE +8132E637 0EEF +8132E638 0EF0 +8132E639 0EF1 +8132E730 0EF2 +8132E731 0EF3 +8132E732 0EF4 +8132E733 0EF5 +8132E734 0EF6 +8132E735 0EF7 +8132E736 0EF8 +8132E737 0EF9 +8132E738 0EFA +8132E739 0EFB +8132E830 0EFC +8132E831 0EFD +8132E832 0EFE +8132E833 0EFF +8132E834 0F00 +8132E835 0F01 +8132E836 0F02 +8132E837 0F03 +8132E838 0F04 +8132E839 0F05 +8132E930 0F06 +8132E931 0F07 +8132E932 0F08 +8132E933 0F09 +8132E934 0F0A +8132E935 0F0B +8132E936 0F0C +8132E937 0F0D +8132E938 0F0E +8132E939 0F0F +8132EA30 0F10 +8132EA31 0F11 +8132EA32 0F12 +8132EA33 0F13 +8132EA34 0F14 +8132EA35 0F15 +8132EA36 0F16 +8132EA37 0F17 +8132EA38 0F18 +8132EA39 0F19 +8132EB30 0F1A +8132EB31 0F1B +8132EB32 0F1C +8132EB33 0F1D +8132EB34 0F1E +8132EB35 0F1F +8132EB36 0F20 +8132EB37 0F21 +8132EB38 0F22 +8132EB39 0F23 +8132EC30 0F24 +8132EC31 0F25 +8132EC32 0F26 +8132EC33 0F27 +8132EC34 0F28 +8132EC35 0F29 +8132EC36 0F2A +8132EC37 0F2B +8132EC38 0F2C +8132EC39 0F2D +8132ED30 0F2E +8132ED31 0F2F +8132ED32 0F30 +8132ED33 0F31 +8132ED34 0F32 +8132ED35 0F33 +8132ED36 0F34 +8132ED37 0F35 +8132ED38 0F36 +8132ED39 0F37 +8132EE30 0F38 +8132EE31 0F39 +8132EE32 0F3A +8132EE33 0F3B +8132EE34 0F3C +8132EE35 0F3D +8132EE36 0F3E +8132EE37 0F3F +8132EE38 0F40 +8132EE39 0F41 +8132EF30 0F42 +8132EF31 0F43 +8132EF32 0F44 +8132EF33 0F45 +8132EF34 0F46 +8132EF35 0F47 +8132EF36 0F48 +8132EF37 0F49 +8132EF38 0F4A +8132EF39 0F4B +8132F030 0F4C +8132F031 0F4D +8132F032 0F4E +8132F033 0F4F +8132F034 0F50 +8132F035 0F51 +8132F036 0F52 +8132F037 0F53 +8132F038 0F54 +8132F039 0F55 +8132F130 0F56 +8132F131 0F57 +8132F132 0F58 +8132F133 0F59 +8132F134 0F5A +8132F135 0F5B +8132F136 0F5C +8132F137 0F5D +8132F138 0F5E +8132F139 0F5F +8132F230 0F60 +8132F231 0F61 +8132F232 0F62 +8132F233 0F63 +8132F234 0F64 +8132F235 0F65 +8132F236 0F66 +8132F237 0F67 +8132F238 0F68 +8132F239 0F69 +8132F330 0F6A +8132F331 0F6B +8132F332 0F6C +8132F333 0F6D +8132F334 0F6E +8132F335 0F6F +8132F336 0F70 +8132F337 0F71 +8132F338 0F72 +8132F339 0F73 +8132F430 0F74 +8132F431 0F75 +8132F432 0F76 +8132F433 0F77 +8132F434 0F78 +8132F435 0F79 +8132F436 0F7A +8132F437 0F7B +8132F438 0F7C +8132F439 0F7D +8132F530 0F7E +8132F531 0F7F +8132F532 0F80 +8132F533 0F81 +8132F534 0F82 +8132F535 0F83 +8132F536 0F84 +8132F537 0F85 +8132F538 0F86 +8132F539 0F87 +8132F630 0F88 +8132F631 0F89 +8132F632 0F8A +8132F633 0F8B +8132F634 0F8C +8132F635 0F8D +8132F636 0F8E +8132F637 0F8F +8132F638 0F90 +8132F639 0F91 +8132F730 0F92 +8132F731 0F93 +8132F732 0F94 +8132F733 0F95 +8132F734 0F96 +8132F735 0F97 +8132F736 0F98 +8132F737 0F99 +8132F738 0F9A +8132F739 0F9B +8132F830 0F9C +8132F831 0F9D +8132F832 0F9E +8132F833 0F9F +8132F834 0FA0 +8132F835 0FA1 +8132F836 0FA2 +8132F837 0FA3 +8132F838 0FA4 +8132F839 0FA5 +8132F930 0FA6 +8132F931 0FA7 +8132F932 0FA8 +8132F933 0FA9 +8132F934 0FAA +8132F935 0FAB +8132F936 0FAC +8132F937 0FAD +8132F938 0FAE +8132F939 0FAF +8132FA30 0FB0 +8132FA31 0FB1 +8132FA32 0FB2 +8132FA33 0FB3 +8132FA34 0FB4 +8132FA35 0FB5 +8132FA36 0FB6 +8132FA37 0FB7 +8132FA38 0FB8 +8132FA39 0FB9 +8132FB30 0FBA +8132FB31 0FBB +8132FB32 0FBC +8132FB33 0FBD +8132FB34 0FBE +8132FB35 0FBF +8132FB36 0FC0 +8132FB37 0FC1 +8132FB38 0FC2 +8132FB39 0FC3 +8132FC30 0FC4 +8132FC31 0FC5 +8132FC32 0FC6 +8132FC33 0FC7 +8132FC34 0FC8 +8132FC35 0FC9 +8132FC36 0FCA +8132FC37 0FCB +8132FC38 0FCC +8132FC39 0FCD +8132FD30 0FCE +8132FD31 0FCF +8132FD32 0FD0 +8132FD33 0FD1 +8132FD34 0FD2 +8132FD35 0FD3 +8132FD36 0FD4 +8132FD37 0FD5 +8132FD38 0FD6 +8132FD39 0FD7 +8132FE30 0FD8 +8132FE31 0FD9 +8132FE32 0FDA +8132FE33 0FDB +8132FE34 0FDC +8132FE35 0FDD +8132FE36 0FDE +8132FE37 0FDF +8132FE38 0FE0 +8132FE39 0FE1 +81338130 0FE2 +81338131 0FE3 +81338132 0FE4 +81338133 0FE5 +81338134 0FE6 +81338135 0FE7 +81338136 0FE8 +81338137 0FE9 +81338138 0FEA +81338139 0FEB +81338230 0FEC +81338231 0FED +81338232 0FEE +81338233 0FEF +81338234 0FF0 +81338235 0FF1 +81338236 0FF2 +81338237 0FF3 +81338238 0FF4 +81338239 0FF5 +81338330 0FF6 +81338331 0FF7 +81338332 0FF8 +81338333 0FF9 +81338334 0FFA +81338335 0FFB +81338336 0FFC +81338337 0FFD +81338338 0FFE +81338339 0FFF +81338430 1000 +81338431 1001 +81338432 1002 +81338433 1003 +81338434 1004 +81338435 1005 +81338436 1006 +81338437 1007 +81338438 1008 +81338439 1009 +81338530 100A +81338531 100B +81338532 100C +81338533 100D +81338534 100E +81338535 100F +81338536 1010 +81338537 1011 +81338538 1012 +81338539 1013 +81338630 1014 +81338631 1015 +81338632 1016 +81338633 1017 +81338634 1018 +81338635 1019 +81338636 101A +81338637 101B +81338638 101C +81338639 101D +81338730 101E +81338731 101F +81338732 1020 +81338733 1021 +81338734 1022 +81338735 1023 +81338736 1024 +81338737 1025 +81338738 1026 +81338739 1027 +81338830 1028 +81338831 1029 +81338832 102A +81338833 102B +81338834 102C +81338835 102D +81338836 102E +81338837 102F +81338838 1030 +81338839 1031 +81338930 1032 +81338931 1033 +81338932 1034 +81338933 1035 +81338934 1036 +81338935 1037 +81338936 1038 +81338937 1039 +81338938 103A +81338939 103B +81338A30 103C +81338A31 103D +81338A32 103E +81338A33 103F +81338A34 1040 +81338A35 1041 +81338A36 1042 +81338A37 1043 +81338A38 1044 +81338A39 1045 +81338B30 1046 +81338B31 1047 +81338B32 1048 +81338B33 1049 +81338B34 104A +81338B35 104B +81338B36 104C +81338B37 104D +81338B38 104E +81338B39 104F +81338C30 1050 +81338C31 1051 +81338C32 1052 +81338C33 1053 +81338C34 1054 +81338C35 1055 +81338C36 1056 +81338C37 1057 +81338C38 1058 +81338C39 1059 +81338D30 105A +81338D31 105B +81338D32 105C +81338D33 105D +81338D34 105E +81338D35 105F +81338D36 1060 +81338D37 1061 +81338D38 1062 +81338D39 1063 +81338E30 1064 +81338E31 1065 +81338E32 1066 +81338E33 1067 +81338E34 1068 +81338E35 1069 +81338E36 106A +81338E37 106B +81338E38 106C +81338E39 106D +81338F30 106E +81338F31 106F +81338F32 1070 +81338F33 1071 +81338F34 1072 +81338F35 1073 +81338F36 1074 +81338F37 1075 +81338F38 1076 +81338F39 1077 +81339030 1078 +81339031 1079 +81339032 107A +81339033 107B +81339034 107C +81339035 107D +81339036 107E +81339037 107F +81339038 1080 +81339039 1081 +81339130 1082 +81339131 1083 +81339132 1084 +81339133 1085 +81339134 1086 +81339135 1087 +81339136 1088 +81339137 1089 +81339138 108A +81339139 108B +81339230 108C +81339231 108D +81339232 108E +81339233 108F +81339234 1090 +81339235 1091 +81339236 1092 +81339237 1093 +81339238 1094 +81339239 1095 +81339330 1096 +81339331 1097 +81339332 1098 +81339333 1099 +81339334 109A +81339335 109B +81339336 109C +81339337 109D +81339338 109E +81339339 109F +81339430 10A0 +81339431 10A1 +81339432 10A2 +81339433 10A3 +81339434 10A4 +81339435 10A5 +81339436 10A6 +81339437 10A7 +81339438 10A8 +81339439 10A9 +81339530 10AA +81339531 10AB +81339532 10AC +81339533 10AD +81339534 10AE +81339535 10AF +81339536 10B0 +81339537 10B1 +81339538 10B2 +81339539 10B3 +81339630 10B4 +81339631 10B5 +81339632 10B6 +81339633 10B7 +81339634 10B8 +81339635 10B9 +81339636 10BA +81339637 10BB +81339638 10BC +81339639 10BD +81339730 10BE +81339731 10BF +81339732 10C0 +81339733 10C1 +81339734 10C2 +81339735 10C3 +81339736 10C4 +81339737 10C5 +81339738 10C6 +81339739 10C7 +81339830 10C8 +81339831 10C9 +81339832 10CA +81339833 10CB +81339834 10CC +81339835 10CD +81339836 10CE +81339837 10CF +81339838 10D0 +81339839 10D1 +81339930 10D2 +81339931 10D3 +81339932 10D4 +81339933 10D5 +81339934 10D6 +81339935 10D7 +81339936 10D8 +81339937 10D9 +81339938 10DA +81339939 10DB +81339A30 10DC +81339A31 10DD +81339A32 10DE +81339A33 10DF +81339A34 10E0 +81339A35 10E1 +81339A36 10E2 +81339A37 10E3 +81339A38 10E4 +81339A39 10E5 +81339B30 10E6 +81339B31 10E7 +81339B32 10E8 +81339B33 10E9 +81339B34 10EA +81339B35 10EB +81339B36 10EC +81339B37 10ED +81339B38 10EE +81339B39 10EF +81339C30 10F0 +81339C31 10F1 +81339C32 10F2 +81339C33 10F3 +81339C34 10F4 +81339C35 10F5 +81339C36 10F6 +81339C37 10F7 +81339C38 10F8 +81339C39 10F9 +81339D30 10FA +81339D31 10FB +81339D32 10FC +81339D33 10FD +81339D34 10FE +81339D35 10FF +81339D36 1100 +81339D37 1101 +81339D38 1102 +81339D39 1103 +81339E30 1104 +81339E31 1105 +81339E32 1106 +81339E33 1107 +81339E34 1108 +81339E35 1109 +81339E36 110A +81339E37 110B +81339E38 110C +81339E39 110D +81339F30 110E +81339F31 110F +81339F32 1110 +81339F33 1111 +81339F34 1112 +81339F35 1113 +81339F36 1114 +81339F37 1115 +81339F38 1116 +81339F39 1117 +8133A030 1118 +8133A031 1119 +8133A032 111A +8133A033 111B +8133A034 111C +8133A035 111D +8133A036 111E +8133A037 111F +8133A038 1120 +8133A039 1121 +8133A130 1122 +8133A131 1123 +8133A132 1124 +8133A133 1125 +8133A134 1126 +8133A135 1127 +8133A136 1128 +8133A137 1129 +8133A138 112A +8133A139 112B +8133A230 112C +8133A231 112D +8133A232 112E +8133A233 112F +8133A234 1130 +8133A235 1131 +8133A236 1132 +8133A237 1133 +8133A238 1134 +8133A239 1135 +8133A330 1136 +8133A331 1137 +8133A332 1138 +8133A333 1139 +8133A334 113A +8133A335 113B +8133A336 113C +8133A337 113D +8133A338 113E +8133A339 113F +8133A430 1140 +8133A431 1141 +8133A432 1142 +8133A433 1143 +8133A434 1144 +8133A435 1145 +8133A436 1146 +8133A437 1147 +8133A438 1148 +8133A439 1149 +8133A530 114A +8133A531 114B +8133A532 114C +8133A533 114D +8133A534 114E +8133A535 114F +8133A536 1150 +8133A537 1151 +8133A538 1152 +8133A539 1153 +8133A630 1154 +8133A631 1155 +8133A632 1156 +8133A633 1157 +8133A634 1158 +8133A635 1159 +8133A636 115A +8133A637 115B +8133A638 115C +8133A639 115D +8133A730 115E +8133A731 115F +8133A732 1160 +8133A733 1161 +8133A734 1162 +8133A735 1163 +8133A736 1164 +8133A737 1165 +8133A738 1166 +8133A739 1167 +8133A830 1168 +8133A831 1169 +8133A832 116A +8133A833 116B +8133A834 116C +8133A835 116D +8133A836 116E +8133A837 116F +8133A838 1170 +8133A839 1171 +8133A930 1172 +8133A931 1173 +8133A932 1174 +8133A933 1175 +8133A934 1176 +8133A935 1177 +8133A936 1178 +8133A937 1179 +8133A938 117A +8133A939 117B +8133AA30 117C +8133AA31 117D +8133AA32 117E +8133AA33 117F +8133AA34 1180 +8133AA35 1181 +8133AA36 1182 +8133AA37 1183 +8133AA38 1184 +8133AA39 1185 +8133AB30 1186 +8133AB31 1187 +8133AB32 1188 +8133AB33 1189 +8133AB34 118A +8133AB35 118B +8133AB36 118C +8133AB37 118D +8133AB38 118E +8133AB39 118F +8133AC30 1190 +8133AC31 1191 +8133AC32 1192 +8133AC33 1193 +8133AC34 1194 +8133AC35 1195 +8133AC36 1196 +8133AC37 1197 +8133AC38 1198 +8133AC39 1199 +8133AD30 119A +8133AD31 119B +8133AD32 119C +8133AD33 119D +8133AD34 119E +8133AD35 119F +8133AD36 11A0 +8133AD37 11A1 +8133AD38 11A2 +8133AD39 11A3 +8133AE30 11A4 +8133AE31 11A5 +8133AE32 11A6 +8133AE33 11A7 +8133AE34 11A8 +8133AE35 11A9 +8133AE36 11AA +8133AE37 11AB +8133AE38 11AC +8133AE39 11AD +8133AF30 11AE +8133AF31 11AF +8133AF32 11B0 +8133AF33 11B1 +8133AF34 11B2 +8133AF35 11B3 +8133AF36 11B4 +8133AF37 11B5 +8133AF38 11B6 +8133AF39 11B7 +8133B030 11B8 +8133B031 11B9 +8133B032 11BA +8133B033 11BB +8133B034 11BC +8133B035 11BD +8133B036 11BE +8133B037 11BF +8133B038 11C0 +8133B039 11C1 +8133B130 11C2 +8133B131 11C3 +8133B132 11C4 +8133B133 11C5 +8133B134 11C6 +8133B135 11C7 +8133B136 11C8 +8133B137 11C9 +8133B138 11CA +8133B139 11CB +8133B230 11CC +8133B231 11CD +8133B232 11CE +8133B233 11CF +8133B234 11D0 +8133B235 11D1 +8133B236 11D2 +8133B237 11D3 +8133B238 11D4 +8133B239 11D5 +8133B330 11D6 +8133B331 11D7 +8133B332 11D8 +8133B333 11D9 +8133B334 11DA +8133B335 11DB +8133B336 11DC +8133B337 11DD +8133B338 11DE +8133B339 11DF +8133B430 11E0 +8133B431 11E1 +8133B432 11E2 +8133B433 11E3 +8133B434 11E4 +8133B435 11E5 +8133B436 11E6 +8133B437 11E7 +8133B438 11E8 +8133B439 11E9 +8133B530 11EA +8133B531 11EB +8133B532 11EC +8133B533 11ED +8133B534 11EE +8133B535 11EF +8133B536 11F0 +8133B537 11F1 +8133B538 11F2 +8133B539 11F3 +8133B630 11F4 +8133B631 11F5 +8133B632 11F6 +8133B633 11F7 +8133B634 11F8 +8133B635 11F9 +8133B636 11FA +8133B637 11FB +8133B638 11FC +8133B639 11FD +8133B730 11FE +8133B731 11FF +8133B732 1200 +8133B733 1201 +8133B734 1202 +8133B735 1203 +8133B736 1204 +8133B737 1205 +8133B738 1206 +8133B739 1207 +8133B830 1208 +8133B831 1209 +8133B832 120A +8133B833 120B +8133B834 120C +8133B835 120D +8133B836 120E +8133B837 120F +8133B838 1210 +8133B839 1211 +8133B930 1212 +8133B931 1213 +8133B932 1214 +8133B933 1215 +8133B934 1216 +8133B935 1217 +8133B936 1218 +8133B937 1219 +8133B938 121A +8133B939 121B +8133BA30 121C +8133BA31 121D +8133BA32 121E +8133BA33 121F +8133BA34 1220 +8133BA35 1221 +8133BA36 1222 +8133BA37 1223 +8133BA38 1224 +8133BA39 1225 +8133BB30 1226 +8133BB31 1227 +8133BB32 1228 +8133BB33 1229 +8133BB34 122A +8133BB35 122B +8133BB36 122C +8133BB37 122D +8133BB38 122E +8133BB39 122F +8133BC30 1230 +8133BC31 1231 +8133BC32 1232 +8133BC33 1233 +8133BC34 1234 +8133BC35 1235 +8133BC36 1236 +8133BC37 1237 +8133BC38 1238 +8133BC39 1239 +8133BD30 123A +8133BD31 123B +8133BD32 123C +8133BD33 123D +8133BD34 123E +8133BD35 123F +8133BD36 1240 +8133BD37 1241 +8133BD38 1242 +8133BD39 1243 +8133BE30 1244 +8133BE31 1245 +8133BE32 1246 +8133BE33 1247 +8133BE34 1248 +8133BE35 1249 +8133BE36 124A +8133BE37 124B +8133BE38 124C +8133BE39 124D +8133BF30 124E +8133BF31 124F +8133BF32 1250 +8133BF33 1251 +8133BF34 1252 +8133BF35 1253 +8133BF36 1254 +8133BF37 1255 +8133BF38 1256 +8133BF39 1257 +8133C030 1258 +8133C031 1259 +8133C032 125A +8133C033 125B +8133C034 125C +8133C035 125D +8133C036 125E +8133C037 125F +8133C038 1260 +8133C039 1261 +8133C130 1262 +8133C131 1263 +8133C132 1264 +8133C133 1265 +8133C134 1266 +8133C135 1267 +8133C136 1268 +8133C137 1269 +8133C138 126A +8133C139 126B +8133C230 126C +8133C231 126D +8133C232 126E +8133C233 126F +8133C234 1270 +8133C235 1271 +8133C236 1272 +8133C237 1273 +8133C238 1274 +8133C239 1275 +8133C330 1276 +8133C331 1277 +8133C332 1278 +8133C333 1279 +8133C334 127A +8133C335 127B +8133C336 127C +8133C337 127D +8133C338 127E +8133C339 127F +8133C430 1280 +8133C431 1281 +8133C432 1282 +8133C433 1283 +8133C434 1284 +8133C435 1285 +8133C436 1286 +8133C437 1287 +8133C438 1288 +8133C439 1289 +8133C530 128A +8133C531 128B +8133C532 128C +8133C533 128D +8133C534 128E +8133C535 128F +8133C536 1290 +8133C537 1291 +8133C538 1292 +8133C539 1293 +8133C630 1294 +8133C631 1295 +8133C632 1296 +8133C633 1297 +8133C634 1298 +8133C635 1299 +8133C636 129A +8133C637 129B +8133C638 129C +8133C639 129D +8133C730 129E +8133C731 129F +8133C732 12A0 +8133C733 12A1 +8133C734 12A2 +8133C735 12A3 +8133C736 12A4 +8133C737 12A5 +8133C738 12A6 +8133C739 12A7 +8133C830 12A8 +8133C831 12A9 +8133C832 12AA +8133C833 12AB +8133C834 12AC +8133C835 12AD +8133C836 12AE +8133C837 12AF +8133C838 12B0 +8133C839 12B1 +8133C930 12B2 +8133C931 12B3 +8133C932 12B4 +8133C933 12B5 +8133C934 12B6 +8133C935 12B7 +8133C936 12B8 +8133C937 12B9 +8133C938 12BA +8133C939 12BB +8133CA30 12BC +8133CA31 12BD +8133CA32 12BE +8133CA33 12BF +8133CA34 12C0 +8133CA35 12C1 +8133CA36 12C2 +8133CA37 12C3 +8133CA38 12C4 +8133CA39 12C5 +8133CB30 12C6 +8133CB31 12C7 +8133CB32 12C8 +8133CB33 12C9 +8133CB34 12CA +8133CB35 12CB +8133CB36 12CC +8133CB37 12CD +8133CB38 12CE +8133CB39 12CF +8133CC30 12D0 +8133CC31 12D1 +8133CC32 12D2 +8133CC33 12D3 +8133CC34 12D4 +8133CC35 12D5 +8133CC36 12D6 +8133CC37 12D7 +8133CC38 12D8 +8133CC39 12D9 +8133CD30 12DA +8133CD31 12DB +8133CD32 12DC +8133CD33 12DD +8133CD34 12DE +8133CD35 12DF +8133CD36 12E0 +8133CD37 12E1 +8133CD38 12E2 +8133CD39 12E3 +8133CE30 12E4 +8133CE31 12E5 +8133CE32 12E6 +8133CE33 12E7 +8133CE34 12E8 +8133CE35 12E9 +8133CE36 12EA +8133CE37 12EB +8133CE38 12EC +8133CE39 12ED +8133CF30 12EE +8133CF31 12EF +8133CF32 12F0 +8133CF33 12F1 +8133CF34 12F2 +8133CF35 12F3 +8133CF36 12F4 +8133CF37 12F5 +8133CF38 12F6 +8133CF39 12F7 +8133D030 12F8 +8133D031 12F9 +8133D032 12FA +8133D033 12FB +8133D034 12FC +8133D035 12FD +8133D036 12FE +8133D037 12FF +8133D038 1300 +8133D039 1301 +8133D130 1302 +8133D131 1303 +8133D132 1304 +8133D133 1305 +8133D134 1306 +8133D135 1307 +8133D136 1308 +8133D137 1309 +8133D138 130A +8133D139 130B +8133D230 130C +8133D231 130D +8133D232 130E +8133D233 130F +8133D234 1310 +8133D235 1311 +8133D236 1312 +8133D237 1313 +8133D238 1314 +8133D239 1315 +8133D330 1316 +8133D331 1317 +8133D332 1318 +8133D333 1319 +8133D334 131A +8133D335 131B +8133D336 131C +8133D337 131D +8133D338 131E +8133D339 131F +8133D430 1320 +8133D431 1321 +8133D432 1322 +8133D433 1323 +8133D434 1324 +8133D435 1325 +8133D436 1326 +8133D437 1327 +8133D438 1328 +8133D439 1329 +8133D530 132A +8133D531 132B +8133D532 132C +8133D533 132D +8133D534 132E +8133D535 132F +8133D536 1330 +8133D537 1331 +8133D538 1332 +8133D539 1333 +8133D630 1334 +8133D631 1335 +8133D632 1336 +8133D633 1337 +8133D634 1338 +8133D635 1339 +8133D636 133A +8133D637 133B +8133D638 133C +8133D639 133D +8133D730 133E +8133D731 133F +8133D732 1340 +8133D733 1341 +8133D734 1342 +8133D735 1343 +8133D736 1344 +8133D737 1345 +8133D738 1346 +8133D739 1347 +8133D830 1348 +8133D831 1349 +8133D832 134A +8133D833 134B +8133D834 134C +8133D835 134D +8133D836 134E +8133D837 134F +8133D838 1350 +8133D839 1351 +8133D930 1352 +8133D931 1353 +8133D932 1354 +8133D933 1355 +8133D934 1356 +8133D935 1357 +8133D936 1358 +8133D937 1359 +8133D938 135A +8133D939 135B +8133DA30 135C +8133DA31 135D +8133DA32 135E +8133DA33 135F +8133DA34 1360 +8133DA35 1361 +8133DA36 1362 +8133DA37 1363 +8133DA38 1364 +8133DA39 1365 +8133DB30 1366 +8133DB31 1367 +8133DB32 1368 +8133DB33 1369 +8133DB34 136A +8133DB35 136B +8133DB36 136C +8133DB37 136D +8133DB38 136E +8133DB39 136F +8133DC30 1370 +8133DC31 1371 +8133DC32 1372 +8133DC33 1373 +8133DC34 1374 +8133DC35 1375 +8133DC36 1376 +8133DC37 1377 +8133DC38 1378 +8133DC39 1379 +8133DD30 137A +8133DD31 137B +8133DD32 137C +8133DD33 137D +8133DD34 137E +8133DD35 137F +8133DD36 1380 +8133DD37 1381 +8133DD38 1382 +8133DD39 1383 +8133DE30 1384 +8133DE31 1385 +8133DE32 1386 +8133DE33 1387 +8133DE34 1388 +8133DE35 1389 +8133DE36 138A +8133DE37 138B +8133DE38 138C +8133DE39 138D +8133DF30 138E +8133DF31 138F +8133DF32 1390 +8133DF33 1391 +8133DF34 1392 +8133DF35 1393 +8133DF36 1394 +8133DF37 1395 +8133DF38 1396 +8133DF39 1397 +8133E030 1398 +8133E031 1399 +8133E032 139A +8133E033 139B +8133E034 139C +8133E035 139D +8133E036 139E +8133E037 139F +8133E038 13A0 +8133E039 13A1 +8133E130 13A2 +8133E131 13A3 +8133E132 13A4 +8133E133 13A5 +8133E134 13A6 +8133E135 13A7 +8133E136 13A8 +8133E137 13A9 +8133E138 13AA +8133E139 13AB +8133E230 13AC +8133E231 13AD +8133E232 13AE +8133E233 13AF +8133E234 13B0 +8133E235 13B1 +8133E236 13B2 +8133E237 13B3 +8133E238 13B4 +8133E239 13B5 +8133E330 13B6 +8133E331 13B7 +8133E332 13B8 +8133E333 13B9 +8133E334 13BA +8133E335 13BB +8133E336 13BC +8133E337 13BD +8133E338 13BE +8133E339 13BF +8133E430 13C0 +8133E431 13C1 +8133E432 13C2 +8133E433 13C3 +8133E434 13C4 +8133E435 13C5 +8133E436 13C6 +8133E437 13C7 +8133E438 13C8 +8133E439 13C9 +8133E530 13CA +8133E531 13CB +8133E532 13CC +8133E533 13CD +8133E534 13CE +8133E535 13CF +8133E536 13D0 +8133E537 13D1 +8133E538 13D2 +8133E539 13D3 +8133E630 13D4 +8133E631 13D5 +8133E632 13D6 +8133E633 13D7 +8133E634 13D8 +8133E635 13D9 +8133E636 13DA +8133E637 13DB +8133E638 13DC +8133E639 13DD +8133E730 13DE +8133E731 13DF +8133E732 13E0 +8133E733 13E1 +8133E734 13E2 +8133E735 13E3 +8133E736 13E4 +8133E737 13E5 +8133E738 13E6 +8133E739 13E7 +8133E830 13E8 +8133E831 13E9 +8133E832 13EA +8133E833 13EB +8133E834 13EC +8133E835 13ED +8133E836 13EE +8133E837 13EF +8133E838 13F0 +8133E839 13F1 +8133E930 13F2 +8133E931 13F3 +8133E932 13F4 +8133E933 13F5 +8133E934 13F6 +8133E935 13F7 +8133E936 13F8 +8133E937 13F9 +8133E938 13FA +8133E939 13FB +8133EA30 13FC +8133EA31 13FD +8133EA32 13FE +8133EA33 13FF +8133EA34 1400 +8133EA35 1401 +8133EA36 1402 +8133EA37 1403 +8133EA38 1404 +8133EA39 1405 +8133EB30 1406 +8133EB31 1407 +8133EB32 1408 +8133EB33 1409 +8133EB34 140A +8133EB35 140B +8133EB36 140C +8133EB37 140D +8133EB38 140E +8133EB39 140F +8133EC30 1410 +8133EC31 1411 +8133EC32 1412 +8133EC33 1413 +8133EC34 1414 +8133EC35 1415 +8133EC36 1416 +8133EC37 1417 +8133EC38 1418 +8133EC39 1419 +8133ED30 141A +8133ED31 141B +8133ED32 141C +8133ED33 141D +8133ED34 141E +8133ED35 141F +8133ED36 1420 +8133ED37 1421 +8133ED38 1422 +8133ED39 1423 +8133EE30 1424 +8133EE31 1425 +8133EE32 1426 +8133EE33 1427 +8133EE34 1428 +8133EE35 1429 +8133EE36 142A +8133EE37 142B +8133EE38 142C +8133EE39 142D +8133EF30 142E +8133EF31 142F +8133EF32 1430 +8133EF33 1431 +8133EF34 1432 +8133EF35 1433 +8133EF36 1434 +8133EF37 1435 +8133EF38 1436 +8133EF39 1437 +8133F030 1438 +8133F031 1439 +8133F032 143A +8133F033 143B +8133F034 143C +8133F035 143D +8133F036 143E +8133F037 143F +8133F038 1440 +8133F039 1441 +8133F130 1442 +8133F131 1443 +8133F132 1444 +8133F133 1445 +8133F134 1446 +8133F135 1447 +8133F136 1448 +8133F137 1449 +8133F138 144A +8133F139 144B +8133F230 144C +8133F231 144D +8133F232 144E +8133F233 144F +8133F234 1450 +8133F235 1451 +8133F236 1452 +8133F237 1453 +8133F238 1454 +8133F239 1455 +8133F330 1456 +8133F331 1457 +8133F332 1458 +8133F333 1459 +8133F334 145A +8133F335 145B +8133F336 145C +8133F337 145D +8133F338 145E +8133F339 145F +8133F430 1460 +8133F431 1461 +8133F432 1462 +8133F433 1463 +8133F434 1464 +8133F435 1465 +8133F436 1466 +8133F437 1467 +8133F438 1468 +8133F439 1469 +8133F530 146A +8133F531 146B +8133F532 146C +8133F533 146D +8133F534 146E +8133F535 146F +8133F536 1470 +8133F537 1471 +8133F538 1472 +8133F539 1473 +8133F630 1474 +8133F631 1475 +8133F632 1476 +8133F633 1477 +8133F634 1478 +8133F635 1479 +8133F636 147A +8133F637 147B +8133F638 147C +8133F639 147D +8133F730 147E +8133F731 147F +8133F732 1480 +8133F733 1481 +8133F734 1482 +8133F735 1483 +8133F736 1484 +8133F737 1485 +8133F738 1486 +8133F739 1487 +8133F830 1488 +8133F831 1489 +8133F832 148A +8133F833 148B +8133F834 148C +8133F835 148D +8133F836 148E +8133F837 148F +8133F838 1490 +8133F839 1491 +8133F930 1492 +8133F931 1493 +8133F932 1494 +8133F933 1495 +8133F934 1496 +8133F935 1497 +8133F936 1498 +8133F937 1499 +8133F938 149A +8133F939 149B +8133FA30 149C +8133FA31 149D +8133FA32 149E +8133FA33 149F +8133FA34 14A0 +8133FA35 14A1 +8133FA36 14A2 +8133FA37 14A3 +8133FA38 14A4 +8133FA39 14A5 +8133FB30 14A6 +8133FB31 14A7 +8133FB32 14A8 +8133FB33 14A9 +8133FB34 14AA +8133FB35 14AB +8133FB36 14AC +8133FB37 14AD +8133FB38 14AE +8133FB39 14AF +8133FC30 14B0 +8133FC31 14B1 +8133FC32 14B2 +8133FC33 14B3 +8133FC34 14B4 +8133FC35 14B5 +8133FC36 14B6 +8133FC37 14B7 +8133FC38 14B8 +8133FC39 14B9 +8133FD30 14BA +8133FD31 14BB +8133FD32 14BC +8133FD33 14BD +8133FD34 14BE +8133FD35 14BF +8133FD36 14C0 +8133FD37 14C1 +8133FD38 14C2 +8133FD39 14C3 +8133FE30 14C4 +8133FE31 14C5 +8133FE32 14C6 +8133FE33 14C7 +8133FE34 14C8 +8133FE35 14C9 +8133FE36 14CA +8133FE37 14CB +8133FE38 14CC +8133FE39 14CD +81348130 14CE +81348131 14CF +81348132 14D0 +81348133 14D1 +81348134 14D2 +81348135 14D3 +81348136 14D4 +81348137 14D5 +81348138 14D6 +81348139 14D7 +81348230 14D8 +81348231 14D9 +81348232 14DA +81348233 14DB +81348234 14DC +81348235 14DD +81348236 14DE +81348237 14DF +81348238 14E0 +81348239 14E1 +81348330 14E2 +81348331 14E3 +81348332 14E4 +81348333 14E5 +81348334 14E6 +81348335 14E7 +81348336 14E8 +81348337 14E9 +81348338 14EA +81348339 14EB +81348430 14EC +81348431 14ED +81348432 14EE +81348433 14EF +81348434 14F0 +81348435 14F1 +81348436 14F2 +81348437 14F3 +81348438 14F4 +81348439 14F5 +81348530 14F6 +81348531 14F7 +81348532 14F8 +81348533 14F9 +81348534 14FA +81348535 14FB +81348536 14FC +81348537 14FD +81348538 14FE +81348539 14FF +81348630 1500 +81348631 1501 +81348632 1502 +81348633 1503 +81348634 1504 +81348635 1505 +81348636 1506 +81348637 1507 +81348638 1508 +81348639 1509 +81348730 150A +81348731 150B +81348732 150C +81348733 150D +81348734 150E +81348735 150F +81348736 1510 +81348737 1511 +81348738 1512 +81348739 1513 +81348830 1514 +81348831 1515 +81348832 1516 +81348833 1517 +81348834 1518 +81348835 1519 +81348836 151A +81348837 151B +81348838 151C +81348839 151D +81348930 151E +81348931 151F +81348932 1520 +81348933 1521 +81348934 1522 +81348935 1523 +81348936 1524 +81348937 1525 +81348938 1526 +81348939 1527 +81348A30 1528 +81348A31 1529 +81348A32 152A +81348A33 152B +81348A34 152C +81348A35 152D +81348A36 152E +81348A37 152F +81348A38 1530 +81348A39 1531 +81348B30 1532 +81348B31 1533 +81348B32 1534 +81348B33 1535 +81348B34 1536 +81348B35 1537 +81348B36 1538 +81348B37 1539 +81348B38 153A +81348B39 153B +81348C30 153C +81348C31 153D +81348C32 153E +81348C33 153F +81348C34 1540 +81348C35 1541 +81348C36 1542 +81348C37 1543 +81348C38 1544 +81348C39 1545 +81348D30 1546 +81348D31 1547 +81348D32 1548 +81348D33 1549 +81348D34 154A +81348D35 154B +81348D36 154C +81348D37 154D +81348D38 154E +81348D39 154F +81348E30 1550 +81348E31 1551 +81348E32 1552 +81348E33 1553 +81348E34 1554 +81348E35 1555 +81348E36 1556 +81348E37 1557 +81348E38 1558 +81348E39 1559 +81348F30 155A +81348F31 155B +81348F32 155C +81348F33 155D +81348F34 155E +81348F35 155F +81348F36 1560 +81348F37 1561 +81348F38 1562 +81348F39 1563 +81349030 1564 +81349031 1565 +81349032 1566 +81349033 1567 +81349034 1568 +81349035 1569 +81349036 156A +81349037 156B +81349038 156C +81349039 156D +81349130 156E +81349131 156F +81349132 1570 +81349133 1571 +81349134 1572 +81349135 1573 +81349136 1574 +81349137 1575 +81349138 1576 +81349139 1577 +81349230 1578 +81349231 1579 +81349232 157A +81349233 157B +81349234 157C +81349235 157D +81349236 157E +81349237 157F +81349238 1580 +81349239 1581 +81349330 1582 +81349331 1583 +81349332 1584 +81349333 1585 +81349334 1586 +81349335 1587 +81349336 1588 +81349337 1589 +81349338 158A +81349339 158B +81349430 158C +81349431 158D +81349432 158E +81349433 158F +81349434 1590 +81349435 1591 +81349436 1592 +81349437 1593 +81349438 1594 +81349439 1595 +81349530 1596 +81349531 1597 +81349532 1598 +81349533 1599 +81349534 159A +81349535 159B +81349536 159C +81349537 159D +81349538 159E +81349539 159F +81349630 15A0 +81349631 15A1 +81349632 15A2 +81349633 15A3 +81349634 15A4 +81349635 15A5 +81349636 15A6 +81349637 15A7 +81349638 15A8 +81349639 15A9 +81349730 15AA +81349731 15AB +81349732 15AC +81349733 15AD +81349734 15AE +81349735 15AF +81349736 15B0 +81349737 15B1 +81349738 15B2 +81349739 15B3 +81349830 15B4 +81349831 15B5 +81349832 15B6 +81349833 15B7 +81349834 15B8 +81349835 15B9 +81349836 15BA +81349837 15BB +81349838 15BC +81349839 15BD +81349930 15BE +81349931 15BF +81349932 15C0 +81349933 15C1 +81349934 15C2 +81349935 15C3 +81349936 15C4 +81349937 15C5 +81349938 15C6 +81349939 15C7 +81349A30 15C8 +81349A31 15C9 +81349A32 15CA +81349A33 15CB +81349A34 15CC +81349A35 15CD +81349A36 15CE +81349A37 15CF +81349A38 15D0 +81349A39 15D1 +81349B30 15D2 +81349B31 15D3 +81349B32 15D4 +81349B33 15D5 +81349B34 15D6 +81349B35 15D7 +81349B36 15D8 +81349B37 15D9 +81349B38 15DA +81349B39 15DB +81349C30 15DC +81349C31 15DD +81349C32 15DE +81349C33 15DF +81349C34 15E0 +81349C35 15E1 +81349C36 15E2 +81349C37 15E3 +81349C38 15E4 +81349C39 15E5 +81349D30 15E6 +81349D31 15E7 +81349D32 15E8 +81349D33 15E9 +81349D34 15EA +81349D35 15EB +81349D36 15EC +81349D37 15ED +81349D38 15EE +81349D39 15EF +81349E30 15F0 +81349E31 15F1 +81349E32 15F2 +81349E33 15F3 +81349E34 15F4 +81349E35 15F5 +81349E36 15F6 +81349E37 15F7 +81349E38 15F8 +81349E39 15F9 +81349F30 15FA +81349F31 15FB +81349F32 15FC +81349F33 15FD +81349F34 15FE +81349F35 15FF +81349F36 1600 +81349F37 1601 +81349F38 1602 +81349F39 1603 +8134A030 1604 +8134A031 1605 +8134A032 1606 +8134A033 1607 +8134A034 1608 +8134A035 1609 +8134A036 160A +8134A037 160B +8134A038 160C +8134A039 160D +8134A130 160E +8134A131 160F +8134A132 1610 +8134A133 1611 +8134A134 1612 +8134A135 1613 +8134A136 1614 +8134A137 1615 +8134A138 1616 +8134A139 1617 +8134A230 1618 +8134A231 1619 +8134A232 161A +8134A233 161B +8134A234 161C +8134A235 161D +8134A236 161E +8134A237 161F +8134A238 1620 +8134A239 1621 +8134A330 1622 +8134A331 1623 +8134A332 1624 +8134A333 1625 +8134A334 1626 +8134A335 1627 +8134A336 1628 +8134A337 1629 +8134A338 162A +8134A339 162B +8134A430 162C +8134A431 162D +8134A432 162E +8134A433 162F +8134A434 1630 +8134A435 1631 +8134A436 1632 +8134A437 1633 +8134A438 1634 +8134A439 1635 +8134A530 1636 +8134A531 1637 +8134A532 1638 +8134A533 1639 +8134A534 163A +8134A535 163B +8134A536 163C +8134A537 163D +8134A538 163E +8134A539 163F +8134A630 1640 +8134A631 1641 +8134A632 1642 +8134A633 1643 +8134A634 1644 +8134A635 1645 +8134A636 1646 +8134A637 1647 +8134A638 1648 +8134A639 1649 +8134A730 164A +8134A731 164B +8134A732 164C +8134A733 164D +8134A734 164E +8134A735 164F +8134A736 1650 +8134A737 1651 +8134A738 1652 +8134A739 1653 +8134A830 1654 +8134A831 1655 +8134A832 1656 +8134A833 1657 +8134A834 1658 +8134A835 1659 +8134A836 165A +8134A837 165B +8134A838 165C +8134A839 165D +8134A930 165E +8134A931 165F +8134A932 1660 +8134A933 1661 +8134A934 1662 +8134A935 1663 +8134A936 1664 +8134A937 1665 +8134A938 1666 +8134A939 1667 +8134AA30 1668 +8134AA31 1669 +8134AA32 166A +8134AA33 166B +8134AA34 166C +8134AA35 166D +8134AA36 166E +8134AA37 166F +8134AA38 1670 +8134AA39 1671 +8134AB30 1672 +8134AB31 1673 +8134AB32 1674 +8134AB33 1675 +8134AB34 1676 +8134AB35 1677 +8134AB36 1678 +8134AB37 1679 +8134AB38 167A +8134AB39 167B +8134AC30 167C +8134AC31 167D +8134AC32 167E +8134AC33 167F +8134AC34 1680 +8134AC35 1681 +8134AC36 1682 +8134AC37 1683 +8134AC38 1684 +8134AC39 1685 +8134AD30 1686 +8134AD31 1687 +8134AD32 1688 +8134AD33 1689 +8134AD34 168A +8134AD35 168B +8134AD36 168C +8134AD37 168D +8134AD38 168E +8134AD39 168F +8134AE30 1690 +8134AE31 1691 +8134AE32 1692 +8134AE33 1693 +8134AE34 1694 +8134AE35 1695 +8134AE36 1696 +8134AE37 1697 +8134AE38 1698 +8134AE39 1699 +8134AF30 169A +8134AF31 169B +8134AF32 169C +8134AF33 169D +8134AF34 169E +8134AF35 169F +8134AF36 16A0 +8134AF37 16A1 +8134AF38 16A2 +8134AF39 16A3 +8134B030 16A4 +8134B031 16A5 +8134B032 16A6 +8134B033 16A7 +8134B034 16A8 +8134B035 16A9 +8134B036 16AA +8134B037 16AB +8134B038 16AC +8134B039 16AD +8134B130 16AE +8134B131 16AF +8134B132 16B0 +8134B133 16B1 +8134B134 16B2 +8134B135 16B3 +8134B136 16B4 +8134B137 16B5 +8134B138 16B6 +8134B139 16B7 +8134B230 16B8 +8134B231 16B9 +8134B232 16BA +8134B233 16BB +8134B234 16BC +8134B235 16BD +8134B236 16BE +8134B237 16BF +8134B238 16C0 +8134B239 16C1 +8134B330 16C2 +8134B331 16C3 +8134B332 16C4 +8134B333 16C5 +8134B334 16C6 +8134B335 16C7 +8134B336 16C8 +8134B337 16C9 +8134B338 16CA +8134B339 16CB +8134B430 16CC +8134B431 16CD +8134B432 16CE +8134B433 16CF +8134B434 16D0 +8134B435 16D1 +8134B436 16D2 +8134B437 16D3 +8134B438 16D4 +8134B439 16D5 +8134B530 16D6 +8134B531 16D7 +8134B532 16D8 +8134B533 16D9 +8134B534 16DA +8134B535 16DB +8134B536 16DC +8134B537 16DD +8134B538 16DE +8134B539 16DF +8134B630 16E0 +8134B631 16E1 +8134B632 16E2 +8134B633 16E3 +8134B634 16E4 +8134B635 16E5 +8134B636 16E6 +8134B637 16E7 +8134B638 16E8 +8134B639 16E9 +8134B730 16EA +8134B731 16EB +8134B732 16EC +8134B733 16ED +8134B734 16EE +8134B735 16EF +8134B736 16F0 +8134B737 16F1 +8134B738 16F2 +8134B739 16F3 +8134B830 16F4 +8134B831 16F5 +8134B832 16F6 +8134B833 16F7 +8134B834 16F8 +8134B835 16F9 +8134B836 16FA +8134B837 16FB +8134B838 16FC +8134B839 16FD +8134B930 16FE +8134B931 16FF +8134B932 1700 +8134B933 1701 +8134B934 1702 +8134B935 1703 +8134B936 1704 +8134B937 1705 +8134B938 1706 +8134B939 1707 +8134BA30 1708 +8134BA31 1709 +8134BA32 170A +8134BA33 170B +8134BA34 170C +8134BA35 170D +8134BA36 170E +8134BA37 170F +8134BA38 1710 +8134BA39 1711 +8134BB30 1712 +8134BB31 1713 +8134BB32 1714 +8134BB33 1715 +8134BB34 1716 +8134BB35 1717 +8134BB36 1718 +8134BB37 1719 +8134BB38 171A +8134BB39 171B +8134BC30 171C +8134BC31 171D +8134BC32 171E +8134BC33 171F +8134BC34 1720 +8134BC35 1721 +8134BC36 1722 +8134BC37 1723 +8134BC38 1724 +8134BC39 1725 +8134BD30 1726 +8134BD31 1727 +8134BD32 1728 +8134BD33 1729 +8134BD34 172A +8134BD35 172B +8134BD36 172C +8134BD37 172D +8134BD38 172E +8134BD39 172F +8134BE30 1730 +8134BE31 1731 +8134BE32 1732 +8134BE33 1733 +8134BE34 1734 +8134BE35 1735 +8134BE36 1736 +8134BE37 1737 +8134BE38 1738 +8134BE39 1739 +8134BF30 173A +8134BF31 173B +8134BF32 173C +8134BF33 173D +8134BF34 173E +8134BF35 173F +8134BF36 1740 +8134BF37 1741 +8134BF38 1742 +8134BF39 1743 +8134C030 1744 +8134C031 1745 +8134C032 1746 +8134C033 1747 +8134C034 1748 +8134C035 1749 +8134C036 174A +8134C037 174B +8134C038 174C +8134C039 174D +8134C130 174E +8134C131 174F +8134C132 1750 +8134C133 1751 +8134C134 1752 +8134C135 1753 +8134C136 1754 +8134C137 1755 +8134C138 1756 +8134C139 1757 +8134C230 1758 +8134C231 1759 +8134C232 175A +8134C233 175B +8134C234 175C +8134C235 175D +8134C236 175E +8134C237 175F +8134C238 1760 +8134C239 1761 +8134C330 1762 +8134C331 1763 +8134C332 1764 +8134C333 1765 +8134C334 1766 +8134C335 1767 +8134C336 1768 +8134C337 1769 +8134C338 176A +8134C339 176B +8134C430 176C +8134C431 176D +8134C432 176E +8134C433 176F +8134C434 1770 +8134C435 1771 +8134C436 1772 +8134C437 1773 +8134C438 1774 +8134C439 1775 +8134C530 1776 +8134C531 1777 +8134C532 1778 +8134C533 1779 +8134C534 177A +8134C535 177B +8134C536 177C +8134C537 177D +8134C538 177E +8134C539 177F +8134C630 1780 +8134C631 1781 +8134C632 1782 +8134C633 1783 +8134C634 1784 +8134C635 1785 +8134C636 1786 +8134C637 1787 +8134C638 1788 +8134C639 1789 +8134C730 178A +8134C731 178B +8134C732 178C +8134C733 178D +8134C734 178E +8134C735 178F +8134C736 1790 +8134C737 1791 +8134C738 1792 +8134C739 1793 +8134C830 1794 +8134C831 1795 +8134C832 1796 +8134C833 1797 +8134C834 1798 +8134C835 1799 +8134C836 179A +8134C837 179B +8134C838 179C +8134C839 179D +8134C930 179E +8134C931 179F +8134C932 17A0 +8134C933 17A1 +8134C934 17A2 +8134C935 17A3 +8134C936 17A4 +8134C937 17A5 +8134C938 17A6 +8134C939 17A7 +8134CA30 17A8 +8134CA31 17A9 +8134CA32 17AA +8134CA33 17AB +8134CA34 17AC +8134CA35 17AD +8134CA36 17AE +8134CA37 17AF +8134CA38 17B0 +8134CA39 17B1 +8134CB30 17B2 +8134CB31 17B3 +8134CB32 17B4 +8134CB33 17B5 +8134CB34 17B6 +8134CB35 17B7 +8134CB36 17B8 +8134CB37 17B9 +8134CB38 17BA +8134CB39 17BB +8134CC30 17BC +8134CC31 17BD +8134CC32 17BE +8134CC33 17BF +8134CC34 17C0 +8134CC35 17C1 +8134CC36 17C2 +8134CC37 17C3 +8134CC38 17C4 +8134CC39 17C5 +8134CD30 17C6 +8134CD31 17C7 +8134CD32 17C8 +8134CD33 17C9 +8134CD34 17CA +8134CD35 17CB +8134CD36 17CC +8134CD37 17CD +8134CD38 17CE +8134CD39 17CF +8134CE30 17D0 +8134CE31 17D1 +8134CE32 17D2 +8134CE33 17D3 +8134CE34 17D4 +8134CE35 17D5 +8134CE36 17D6 +8134CE37 17D7 +8134CE38 17D8 +8134CE39 17D9 +8134CF30 17DA +8134CF31 17DB +8134CF32 17DC +8134CF33 17DD +8134CF34 17DE +8134CF35 17DF +8134CF36 17E0 +8134CF37 17E1 +8134CF38 17E2 +8134CF39 17E3 +8134D030 17E4 +8134D031 17E5 +8134D032 17E6 +8134D033 17E7 +8134D034 17E8 +8134D035 17E9 +8134D036 17EA +8134D037 17EB +8134D038 17EC +8134D039 17ED +8134D130 17EE +8134D131 17EF +8134D132 17F0 +8134D133 17F1 +8134D134 17F2 +8134D135 17F3 +8134D136 17F4 +8134D137 17F5 +8134D138 17F6 +8134D139 17F7 +8134D230 17F8 +8134D231 17F9 +8134D232 17FA +8134D233 17FB +8134D234 17FC +8134D235 17FD +8134D236 17FE +8134D237 17FF +8134D238 1800 +8134D239 1801 +8134D330 1802 +8134D331 1803 +8134D332 1804 +8134D333 1805 +8134D334 1806 +8134D335 1807 +8134D336 1808 +8134D337 1809 +8134D338 180A +8134D339 180B +8134D430 180C +8134D431 180D +8134D432 180E +8134D433 180F +8134D434 1810 +8134D435 1811 +8134D436 1812 +8134D437 1813 +8134D438 1814 +8134D439 1815 +8134D530 1816 +8134D531 1817 +8134D532 1818 +8134D533 1819 +8134D534 181A +8134D535 181B +8134D536 181C +8134D537 181D +8134D538 181E +8134D539 181F +8134D630 1820 +8134D631 1821 +8134D632 1822 +8134D633 1823 +8134D634 1824 +8134D635 1825 +8134D636 1826 +8134D637 1827 +8134D638 1828 +8134D639 1829 +8134D730 182A +8134D731 182B +8134D732 182C +8134D733 182D +8134D734 182E +8134D735 182F +8134D736 1830 +8134D737 1831 +8134D738 1832 +8134D739 1833 +8134D830 1834 +8134D831 1835 +8134D832 1836 +8134D833 1837 +8134D834 1838 +8134D835 1839 +8134D836 183A +8134D837 183B +8134D838 183C +8134D839 183D +8134D930 183E +8134D931 183F +8134D932 1840 +8134D933 1841 +8134D934 1842 +8134D935 1843 +8134D936 1844 +8134D937 1845 +8134D938 1846 +8134D939 1847 +8134DA30 1848 +8134DA31 1849 +8134DA32 184A +8134DA33 184B +8134DA34 184C +8134DA35 184D +8134DA36 184E +8134DA37 184F +8134DA38 1850 +8134DA39 1851 +8134DB30 1852 +8134DB31 1853 +8134DB32 1854 +8134DB33 1855 +8134DB34 1856 +8134DB35 1857 +8134DB36 1858 +8134DB37 1859 +8134DB38 185A +8134DB39 185B +8134DC30 185C +8134DC31 185D +8134DC32 185E +8134DC33 185F +8134DC34 1860 +8134DC35 1861 +8134DC36 1862 +8134DC37 1863 +8134DC38 1864 +8134DC39 1865 +8134DD30 1866 +8134DD31 1867 +8134DD32 1868 +8134DD33 1869 +8134DD34 186A +8134DD35 186B +8134DD36 186C +8134DD37 186D +8134DD38 186E +8134DD39 186F +8134DE30 1870 +8134DE31 1871 +8134DE32 1872 +8134DE33 1873 +8134DE34 1874 +8134DE35 1875 +8134DE36 1876 +8134DE37 1877 +8134DE38 1878 +8134DE39 1879 +8134DF30 187A +8134DF31 187B +8134DF32 187C +8134DF33 187D +8134DF34 187E +8134DF35 187F +8134DF36 1880 +8134DF37 1881 +8134DF38 1882 +8134DF39 1883 +8134E030 1884 +8134E031 1885 +8134E032 1886 +8134E033 1887 +8134E034 1888 +8134E035 1889 +8134E036 188A +8134E037 188B +8134E038 188C +8134E039 188D +8134E130 188E +8134E131 188F +8134E132 1890 +8134E133 1891 +8134E134 1892 +8134E135 1893 +8134E136 1894 +8134E137 1895 +8134E138 1896 +8134E139 1897 +8134E230 1898 +8134E231 1899 +8134E232 189A +8134E233 189B +8134E234 189C +8134E235 189D +8134E236 189E +8134E237 189F +8134E238 18A0 +8134E239 18A1 +8134E330 18A2 +8134E331 18A3 +8134E332 18A4 +8134E333 18A5 +8134E334 18A6 +8134E335 18A7 +8134E336 18A8 +8134E337 18A9 +8134E338 18AA +8134E339 18AB +8134E430 18AC +8134E431 18AD +8134E432 18AE +8134E433 18AF +8134E434 18B0 +8134E435 18B1 +8134E436 18B2 +8134E437 18B3 +8134E438 18B4 +8134E439 18B5 +8134E530 18B6 +8134E531 18B7 +8134E532 18B8 +8134E533 18B9 +8134E534 18BA +8134E535 18BB +8134E536 18BC +8134E537 18BD +8134E538 18BE +8134E539 18BF +8134E630 18C0 +8134E631 18C1 +8134E632 18C2 +8134E633 18C3 +8134E634 18C4 +8134E635 18C5 +8134E636 18C6 +8134E637 18C7 +8134E638 18C8 +8134E639 18C9 +8134E730 18CA +8134E731 18CB +8134E732 18CC +8134E733 18CD +8134E734 18CE +8134E735 18CF +8134E736 18D0 +8134E737 18D1 +8134E738 18D2 +8134E739 18D3 +8134E830 18D4 +8134E831 18D5 +8134E832 18D6 +8134E833 18D7 +8134E834 18D8 +8134E835 18D9 +8134E836 18DA +8134E837 18DB +8134E838 18DC +8134E839 18DD +8134E930 18DE +8134E931 18DF +8134E932 18E0 +8134E933 18E1 +8134E934 18E2 +8134E935 18E3 +8134E936 18E4 +8134E937 18E5 +8134E938 18E6 +8134E939 18E7 +8134EA30 18E8 +8134EA31 18E9 +8134EA32 18EA +8134EA33 18EB +8134EA34 18EC +8134EA35 18ED +8134EA36 18EE +8134EA37 18EF +8134EA38 18F0 +8134EA39 18F1 +8134EB30 18F2 +8134EB31 18F3 +8134EB32 18F4 +8134EB33 18F5 +8134EB34 18F6 +8134EB35 18F7 +8134EB36 18F8 +8134EB37 18F9 +8134EB38 18FA +8134EB39 18FB +8134EC30 18FC +8134EC31 18FD +8134EC32 18FE +8134EC33 18FF +8134EC34 1900 +8134EC35 1901 +8134EC36 1902 +8134EC37 1903 +8134EC38 1904 +8134EC39 1905 +8134ED30 1906 +8134ED31 1907 +8134ED32 1908 +8134ED33 1909 +8134ED34 190A +8134ED35 190B +8134ED36 190C +8134ED37 190D +8134ED38 190E +8134ED39 190F +8134EE30 1910 +8134EE31 1911 +8134EE32 1912 +8134EE33 1913 +8134EE34 1914 +8134EE35 1915 +8134EE36 1916 +8134EE37 1917 +8134EE38 1918 +8134EE39 1919 +8134EF30 191A +8134EF31 191B +8134EF32 191C +8134EF33 191D +8134EF34 191E +8134EF35 191F +8134EF36 1920 +8134EF37 1921 +8134EF38 1922 +8134EF39 1923 +8134F030 1924 +8134F031 1925 +8134F032 1926 +8134F033 1927 +8134F034 1928 +8134F035 1929 +8134F036 192A +8134F037 192B +8134F038 192C +8134F039 192D +8134F130 192E +8134F131 192F +8134F132 1930 +8134F133 1931 +8134F134 1932 +8134F135 1933 +8134F136 1934 +8134F137 1935 +8134F138 1936 +8134F139 1937 +8134F230 1938 +8134F231 1939 +8134F232 193A +8134F233 193B +8134F234 193C +8134F235 193D +8134F236 193E +8134F237 193F +8134F238 1940 +8134F239 1941 +8134F330 1942 +8134F331 1943 +8134F332 1944 +8134F333 1945 +8134F334 1946 +8134F335 1947 +8134F336 1948 +8134F337 1949 +8134F338 194A +8134F339 194B +8134F430 194C +8134F431 194D +8134F432 194E +8134F433 194F +8134F434 1950 +8134F435 1951 +8134F436 1952 +8134F437 1953 +8134F438 1954 +8134F439 1955 +8134F530 1956 +8134F531 1957 +8134F532 1958 +8134F533 1959 +8134F534 195A +8134F535 195B +8134F536 195C +8134F537 195D +8134F538 195E +8134F539 195F +8134F630 1960 +8134F631 1961 +8134F632 1962 +8134F633 1963 +8134F634 1964 +8134F635 1965 +8134F636 1966 +8134F637 1967 +8134F638 1968 +8134F639 1969 +8134F730 196A +8134F731 196B +8134F732 196C +8134F733 196D +8134F734 196E +8134F735 196F +8134F736 1970 +8134F737 1971 +8134F738 1972 +8134F739 1973 +8134F830 1974 +8134F831 1975 +8134F832 1976 +8134F833 1977 +8134F834 1978 +8134F835 1979 +8134F836 197A +8134F837 197B +8134F838 197C +8134F839 197D +8134F930 197E +8134F931 197F +8134F932 1980 +8134F933 1981 +8134F934 1982 +8134F935 1983 +8134F936 1984 +8134F937 1985 +8134F938 1986 +8134F939 1987 +8134FA30 1988 +8134FA31 1989 +8134FA32 198A +8134FA33 198B +8134FA34 198C +8134FA35 198D +8134FA36 198E +8134FA37 198F +8134FA38 1990 +8134FA39 1991 +8134FB30 1992 +8134FB31 1993 +8134FB32 1994 +8134FB33 1995 +8134FB34 1996 +8134FB35 1997 +8134FB36 1998 +8134FB37 1999 +8134FB38 199A +8134FB39 199B +8134FC30 199C +8134FC31 199D +8134FC32 199E +8134FC33 199F +8134FC34 19A0 +8134FC35 19A1 +8134FC36 19A2 +8134FC37 19A3 +8134FC38 19A4 +8134FC39 19A5 +8134FD30 19A6 +8134FD31 19A7 +8134FD32 19A8 +8134FD33 19A9 +8134FD34 19AA +8134FD35 19AB +8134FD36 19AC +8134FD37 19AD +8134FD38 19AE +8134FD39 19AF +8134FE30 19B0 +8134FE31 19B1 +8134FE32 19B2 +8134FE33 19B3 +8134FE34 19B4 +8134FE35 19B5 +8134FE36 19B6 +8134FE37 19B7 +8134FE38 19B8 +8134FE39 19B9 +81358130 19BA +81358131 19BB +81358132 19BC +81358133 19BD +81358134 19BE +81358135 19BF +81358136 19C0 +81358137 19C1 +81358138 19C2 +81358139 19C3 +81358230 19C4 +81358231 19C5 +81358232 19C6 +81358233 19C7 +81358234 19C8 +81358235 19C9 +81358236 19CA +81358237 19CB +81358238 19CC +81358239 19CD +81358330 19CE +81358331 19CF +81358332 19D0 +81358333 19D1 +81358334 19D2 +81358335 19D3 +81358336 19D4 +81358337 19D5 +81358338 19D6 +81358339 19D7 +81358430 19D8 +81358431 19D9 +81358432 19DA +81358433 19DB +81358434 19DC +81358435 19DD +81358436 19DE +81358437 19DF +81358438 19E0 +81358439 19E1 +81358530 19E2 +81358531 19E3 +81358532 19E4 +81358533 19E5 +81358534 19E6 +81358535 19E7 +81358536 19E8 +81358537 19E9 +81358538 19EA +81358539 19EB +81358630 19EC +81358631 19ED +81358632 19EE +81358633 19EF +81358634 19F0 +81358635 19F1 +81358636 19F2 +81358637 19F3 +81358638 19F4 +81358639 19F5 +81358730 19F6 +81358731 19F7 +81358732 19F8 +81358733 19F9 +81358734 19FA +81358735 19FB +81358736 19FC +81358737 19FD +81358738 19FE +81358739 19FF +81358830 1A00 +81358831 1A01 +81358832 1A02 +81358833 1A03 +81358834 1A04 +81358835 1A05 +81358836 1A06 +81358837 1A07 +81358838 1A08 +81358839 1A09 +81358930 1A0A +81358931 1A0B +81358932 1A0C +81358933 1A0D +81358934 1A0E +81358935 1A0F +81358936 1A10 +81358937 1A11 +81358938 1A12 +81358939 1A13 +81358A30 1A14 +81358A31 1A15 +81358A32 1A16 +81358A33 1A17 +81358A34 1A18 +81358A35 1A19 +81358A36 1A1A +81358A37 1A1B +81358A38 1A1C +81358A39 1A1D +81358B30 1A1E +81358B31 1A1F +81358B32 1A20 +81358B33 1A21 +81358B34 1A22 +81358B35 1A23 +81358B36 1A24 +81358B37 1A25 +81358B38 1A26 +81358B39 1A27 +81358C30 1A28 +81358C31 1A29 +81358C32 1A2A +81358C33 1A2B +81358C34 1A2C +81358C35 1A2D +81358C36 1A2E +81358C37 1A2F +81358C38 1A30 +81358C39 1A31 +81358D30 1A32 +81358D31 1A33 +81358D32 1A34 +81358D33 1A35 +81358D34 1A36 +81358D35 1A37 +81358D36 1A38 +81358D37 1A39 +81358D38 1A3A +81358D39 1A3B +81358E30 1A3C +81358E31 1A3D +81358E32 1A3E +81358E33 1A3F +81358E34 1A40 +81358E35 1A41 +81358E36 1A42 +81358E37 1A43 +81358E38 1A44 +81358E39 1A45 +81358F30 1A46 +81358F31 1A47 +81358F32 1A48 +81358F33 1A49 +81358F34 1A4A +81358F35 1A4B +81358F36 1A4C +81358F37 1A4D +81358F38 1A4E +81358F39 1A4F +81359030 1A50 +81359031 1A51 +81359032 1A52 +81359033 1A53 +81359034 1A54 +81359035 1A55 +81359036 1A56 +81359037 1A57 +81359038 1A58 +81359039 1A59 +81359130 1A5A +81359131 1A5B +81359132 1A5C +81359133 1A5D +81359134 1A5E +81359135 1A5F +81359136 1A60 +81359137 1A61 +81359138 1A62 +81359139 1A63 +81359230 1A64 +81359231 1A65 +81359232 1A66 +81359233 1A67 +81359234 1A68 +81359235 1A69 +81359236 1A6A +81359237 1A6B +81359238 1A6C +81359239 1A6D +81359330 1A6E +81359331 1A6F +81359332 1A70 +81359333 1A71 +81359334 1A72 +81359335 1A73 +81359336 1A74 +81359337 1A75 +81359338 1A76 +81359339 1A77 +81359430 1A78 +81359431 1A79 +81359432 1A7A +81359433 1A7B +81359434 1A7C +81359435 1A7D +81359436 1A7E +81359437 1A7F +81359438 1A80 +81359439 1A81 +81359530 1A82 +81359531 1A83 +81359532 1A84 +81359533 1A85 +81359534 1A86 +81359535 1A87 +81359536 1A88 +81359537 1A89 +81359538 1A8A +81359539 1A8B +81359630 1A8C +81359631 1A8D +81359632 1A8E +81359633 1A8F +81359634 1A90 +81359635 1A91 +81359636 1A92 +81359637 1A93 +81359638 1A94 +81359639 1A95 +81359730 1A96 +81359731 1A97 +81359732 1A98 +81359733 1A99 +81359734 1A9A +81359735 1A9B +81359736 1A9C +81359737 1A9D +81359738 1A9E +81359739 1A9F +81359830 1AA0 +81359831 1AA1 +81359832 1AA2 +81359833 1AA3 +81359834 1AA4 +81359835 1AA5 +81359836 1AA6 +81359837 1AA7 +81359838 1AA8 +81359839 1AA9 +81359930 1AAA +81359931 1AAB +81359932 1AAC +81359933 1AAD +81359934 1AAE +81359935 1AAF +81359936 1AB0 +81359937 1AB1 +81359938 1AB2 +81359939 1AB3 +81359A30 1AB4 +81359A31 1AB5 +81359A32 1AB6 +81359A33 1AB7 +81359A34 1AB8 +81359A35 1AB9 +81359A36 1ABA +81359A37 1ABB +81359A38 1ABC +81359A39 1ABD +81359B30 1ABE +81359B31 1ABF +81359B32 1AC0 +81359B33 1AC1 +81359B34 1AC2 +81359B35 1AC3 +81359B36 1AC4 +81359B37 1AC5 +81359B38 1AC6 +81359B39 1AC7 +81359C30 1AC8 +81359C31 1AC9 +81359C32 1ACA +81359C33 1ACB +81359C34 1ACC +81359C35 1ACD +81359C36 1ACE +81359C37 1ACF +81359C38 1AD0 +81359C39 1AD1 +81359D30 1AD2 +81359D31 1AD3 +81359D32 1AD4 +81359D33 1AD5 +81359D34 1AD6 +81359D35 1AD7 +81359D36 1AD8 +81359D37 1AD9 +81359D38 1ADA +81359D39 1ADB +81359E30 1ADC +81359E31 1ADD +81359E32 1ADE +81359E33 1ADF +81359E34 1AE0 +81359E35 1AE1 +81359E36 1AE2 +81359E37 1AE3 +81359E38 1AE4 +81359E39 1AE5 +81359F30 1AE6 +81359F31 1AE7 +81359F32 1AE8 +81359F33 1AE9 +81359F34 1AEA +81359F35 1AEB +81359F36 1AEC +81359F37 1AED +81359F38 1AEE +81359F39 1AEF +8135A030 1AF0 +8135A031 1AF1 +8135A032 1AF2 +8135A033 1AF3 +8135A034 1AF4 +8135A035 1AF5 +8135A036 1AF6 +8135A037 1AF7 +8135A038 1AF8 +8135A039 1AF9 +8135A130 1AFA +8135A131 1AFB +8135A132 1AFC +8135A133 1AFD +8135A134 1AFE +8135A135 1AFF +8135A136 1B00 +8135A137 1B01 +8135A138 1B02 +8135A139 1B03 +8135A230 1B04 +8135A231 1B05 +8135A232 1B06 +8135A233 1B07 +8135A234 1B08 +8135A235 1B09 +8135A236 1B0A +8135A237 1B0B +8135A238 1B0C +8135A239 1B0D +8135A330 1B0E +8135A331 1B0F +8135A332 1B10 +8135A333 1B11 +8135A334 1B12 +8135A335 1B13 +8135A336 1B14 +8135A337 1B15 +8135A338 1B16 +8135A339 1B17 +8135A430 1B18 +8135A431 1B19 +8135A432 1B1A +8135A433 1B1B +8135A434 1B1C +8135A435 1B1D +8135A436 1B1E +8135A437 1B1F +8135A438 1B20 +8135A439 1B21 +8135A530 1B22 +8135A531 1B23 +8135A532 1B24 +8135A533 1B25 +8135A534 1B26 +8135A535 1B27 +8135A536 1B28 +8135A537 1B29 +8135A538 1B2A +8135A539 1B2B +8135A630 1B2C +8135A631 1B2D +8135A632 1B2E +8135A633 1B2F +8135A634 1B30 +8135A635 1B31 +8135A636 1B32 +8135A637 1B33 +8135A638 1B34 +8135A639 1B35 +8135A730 1B36 +8135A731 1B37 +8135A732 1B38 +8135A733 1B39 +8135A734 1B3A +8135A735 1B3B +8135A736 1B3C +8135A737 1B3D +8135A738 1B3E +8135A739 1B3F +8135A830 1B40 +8135A831 1B41 +8135A832 1B42 +8135A833 1B43 +8135A834 1B44 +8135A835 1B45 +8135A836 1B46 +8135A837 1B47 +8135A838 1B48 +8135A839 1B49 +8135A930 1B4A +8135A931 1B4B +8135A932 1B4C +8135A933 1B4D +8135A934 1B4E +8135A935 1B4F +8135A936 1B50 +8135A937 1B51 +8135A938 1B52 +8135A939 1B53 +8135AA30 1B54 +8135AA31 1B55 +8135AA32 1B56 +8135AA33 1B57 +8135AA34 1B58 +8135AA35 1B59 +8135AA36 1B5A +8135AA37 1B5B +8135AA38 1B5C +8135AA39 1B5D +8135AB30 1B5E +8135AB31 1B5F +8135AB32 1B60 +8135AB33 1B61 +8135AB34 1B62 +8135AB35 1B63 +8135AB36 1B64 +8135AB37 1B65 +8135AB38 1B66 +8135AB39 1B67 +8135AC30 1B68 +8135AC31 1B69 +8135AC32 1B6A +8135AC33 1B6B +8135AC34 1B6C +8135AC35 1B6D +8135AC36 1B6E +8135AC37 1B6F +8135AC38 1B70 +8135AC39 1B71 +8135AD30 1B72 +8135AD31 1B73 +8135AD32 1B74 +8135AD33 1B75 +8135AD34 1B76 +8135AD35 1B77 +8135AD36 1B78 +8135AD37 1B79 +8135AD38 1B7A +8135AD39 1B7B +8135AE30 1B7C +8135AE31 1B7D +8135AE32 1B7E +8135AE33 1B7F +8135AE34 1B80 +8135AE35 1B81 +8135AE36 1B82 +8135AE37 1B83 +8135AE38 1B84 +8135AE39 1B85 +8135AF30 1B86 +8135AF31 1B87 +8135AF32 1B88 +8135AF33 1B89 +8135AF34 1B8A +8135AF35 1B8B +8135AF36 1B8C +8135AF37 1B8D +8135AF38 1B8E +8135AF39 1B8F +8135B030 1B90 +8135B031 1B91 +8135B032 1B92 +8135B033 1B93 +8135B034 1B94 +8135B035 1B95 +8135B036 1B96 +8135B037 1B97 +8135B038 1B98 +8135B039 1B99 +8135B130 1B9A +8135B131 1B9B +8135B132 1B9C +8135B133 1B9D +8135B134 1B9E +8135B135 1B9F +8135B136 1BA0 +8135B137 1BA1 +8135B138 1BA2 +8135B139 1BA3 +8135B230 1BA4 +8135B231 1BA5 +8135B232 1BA6 +8135B233 1BA7 +8135B234 1BA8 +8135B235 1BA9 +8135B236 1BAA +8135B237 1BAB +8135B238 1BAC +8135B239 1BAD +8135B330 1BAE +8135B331 1BAF +8135B332 1BB0 +8135B333 1BB1 +8135B334 1BB2 +8135B335 1BB3 +8135B336 1BB4 +8135B337 1BB5 +8135B338 1BB6 +8135B339 1BB7 +8135B430 1BB8 +8135B431 1BB9 +8135B432 1BBA +8135B433 1BBB +8135B434 1BBC +8135B435 1BBD +8135B436 1BBE +8135B437 1BBF +8135B438 1BC0 +8135B439 1BC1 +8135B530 1BC2 +8135B531 1BC3 +8135B532 1BC4 +8135B533 1BC5 +8135B534 1BC6 +8135B535 1BC7 +8135B536 1BC8 +8135B537 1BC9 +8135B538 1BCA +8135B539 1BCB +8135B630 1BCC +8135B631 1BCD +8135B632 1BCE +8135B633 1BCF +8135B634 1BD0 +8135B635 1BD1 +8135B636 1BD2 +8135B637 1BD3 +8135B638 1BD4 +8135B639 1BD5 +8135B730 1BD6 +8135B731 1BD7 +8135B732 1BD8 +8135B733 1BD9 +8135B734 1BDA +8135B735 1BDB +8135B736 1BDC +8135B737 1BDD +8135B738 1BDE +8135B739 1BDF +8135B830 1BE0 +8135B831 1BE1 +8135B832 1BE2 +8135B833 1BE3 +8135B834 1BE4 +8135B835 1BE5 +8135B836 1BE6 +8135B837 1BE7 +8135B838 1BE8 +8135B839 1BE9 +8135B930 1BEA +8135B931 1BEB +8135B932 1BEC +8135B933 1BED +8135B934 1BEE +8135B935 1BEF +8135B936 1BF0 +8135B937 1BF1 +8135B938 1BF2 +8135B939 1BF3 +8135BA30 1BF4 +8135BA31 1BF5 +8135BA32 1BF6 +8135BA33 1BF7 +8135BA34 1BF8 +8135BA35 1BF9 +8135BA36 1BFA +8135BA37 1BFB +8135BA38 1BFC +8135BA39 1BFD +8135BB30 1BFE +8135BB31 1BFF +8135BB32 1C00 +8135BB33 1C01 +8135BB34 1C02 +8135BB35 1C03 +8135BB36 1C04 +8135BB37 1C05 +8135BB38 1C06 +8135BB39 1C07 +8135BC30 1C08 +8135BC31 1C09 +8135BC32 1C0A +8135BC33 1C0B +8135BC34 1C0C +8135BC35 1C0D +8135BC36 1C0E +8135BC37 1C0F +8135BC38 1C10 +8135BC39 1C11 +8135BD30 1C12 +8135BD31 1C13 +8135BD32 1C14 +8135BD33 1C15 +8135BD34 1C16 +8135BD35 1C17 +8135BD36 1C18 +8135BD37 1C19 +8135BD38 1C1A +8135BD39 1C1B +8135BE30 1C1C +8135BE31 1C1D +8135BE32 1C1E +8135BE33 1C1F +8135BE34 1C20 +8135BE35 1C21 +8135BE36 1C22 +8135BE37 1C23 +8135BE38 1C24 +8135BE39 1C25 +8135BF30 1C26 +8135BF31 1C27 +8135BF32 1C28 +8135BF33 1C29 +8135BF34 1C2A +8135BF35 1C2B +8135BF36 1C2C +8135BF37 1C2D +8135BF38 1C2E +8135BF39 1C2F +8135C030 1C30 +8135C031 1C31 +8135C032 1C32 +8135C033 1C33 +8135C034 1C34 +8135C035 1C35 +8135C036 1C36 +8135C037 1C37 +8135C038 1C38 +8135C039 1C39 +8135C130 1C3A +8135C131 1C3B +8135C132 1C3C +8135C133 1C3D +8135C134 1C3E +8135C135 1C3F +8135C136 1C40 +8135C137 1C41 +8135C138 1C42 +8135C139 1C43 +8135C230 1C44 +8135C231 1C45 +8135C232 1C46 +8135C233 1C47 +8135C234 1C48 +8135C235 1C49 +8135C236 1C4A +8135C237 1C4B +8135C238 1C4C +8135C239 1C4D +8135C330 1C4E +8135C331 1C4F +8135C332 1C50 +8135C333 1C51 +8135C334 1C52 +8135C335 1C53 +8135C336 1C54 +8135C337 1C55 +8135C338 1C56 +8135C339 1C57 +8135C430 1C58 +8135C431 1C59 +8135C432 1C5A +8135C433 1C5B +8135C434 1C5C +8135C435 1C5D +8135C436 1C5E +8135C437 1C5F +8135C438 1C60 +8135C439 1C61 +8135C530 1C62 +8135C531 1C63 +8135C532 1C64 +8135C533 1C65 +8135C534 1C66 +8135C535 1C67 +8135C536 1C68 +8135C537 1C69 +8135C538 1C6A +8135C539 1C6B +8135C630 1C6C +8135C631 1C6D +8135C632 1C6E +8135C633 1C6F +8135C634 1C70 +8135C635 1C71 +8135C636 1C72 +8135C637 1C73 +8135C638 1C74 +8135C639 1C75 +8135C730 1C76 +8135C731 1C77 +8135C732 1C78 +8135C733 1C79 +8135C734 1C7A +8135C735 1C7B +8135C736 1C7C +8135C737 1C7D +8135C738 1C7E +8135C739 1C7F +8135C830 1C80 +8135C831 1C81 +8135C832 1C82 +8135C833 1C83 +8135C834 1C84 +8135C835 1C85 +8135C836 1C86 +8135C837 1C87 +8135C838 1C88 +8135C839 1C89 +8135C930 1C8A +8135C931 1C8B +8135C932 1C8C +8135C933 1C8D +8135C934 1C8E +8135C935 1C8F +8135C936 1C90 +8135C937 1C91 +8135C938 1C92 +8135C939 1C93 +8135CA30 1C94 +8135CA31 1C95 +8135CA32 1C96 +8135CA33 1C97 +8135CA34 1C98 +8135CA35 1C99 +8135CA36 1C9A +8135CA37 1C9B +8135CA38 1C9C +8135CA39 1C9D +8135CB30 1C9E +8135CB31 1C9F +8135CB32 1CA0 +8135CB33 1CA1 +8135CB34 1CA2 +8135CB35 1CA3 +8135CB36 1CA4 +8135CB37 1CA5 +8135CB38 1CA6 +8135CB39 1CA7 +8135CC30 1CA8 +8135CC31 1CA9 +8135CC32 1CAA +8135CC33 1CAB +8135CC34 1CAC +8135CC35 1CAD +8135CC36 1CAE +8135CC37 1CAF +8135CC38 1CB0 +8135CC39 1CB1 +8135CD30 1CB2 +8135CD31 1CB3 +8135CD32 1CB4 +8135CD33 1CB5 +8135CD34 1CB6 +8135CD35 1CB7 +8135CD36 1CB8 +8135CD37 1CB9 +8135CD38 1CBA +8135CD39 1CBB +8135CE30 1CBC +8135CE31 1CBD +8135CE32 1CBE +8135CE33 1CBF +8135CE34 1CC0 +8135CE35 1CC1 +8135CE36 1CC2 +8135CE37 1CC3 +8135CE38 1CC4 +8135CE39 1CC5 +8135CF30 1CC6 +8135CF31 1CC7 +8135CF32 1CC8 +8135CF33 1CC9 +8135CF34 1CCA +8135CF35 1CCB +8135CF36 1CCC +8135CF37 1CCD +8135CF38 1CCE +8135CF39 1CCF +8135D030 1CD0 +8135D031 1CD1 +8135D032 1CD2 +8135D033 1CD3 +8135D034 1CD4 +8135D035 1CD5 +8135D036 1CD6 +8135D037 1CD7 +8135D038 1CD8 +8135D039 1CD9 +8135D130 1CDA +8135D131 1CDB +8135D132 1CDC +8135D133 1CDD +8135D134 1CDE +8135D135 1CDF +8135D136 1CE0 +8135D137 1CE1 +8135D138 1CE2 +8135D139 1CE3 +8135D230 1CE4 +8135D231 1CE5 +8135D232 1CE6 +8135D233 1CE7 +8135D234 1CE8 +8135D235 1CE9 +8135D236 1CEA +8135D237 1CEB +8135D238 1CEC +8135D239 1CED +8135D330 1CEE +8135D331 1CEF +8135D332 1CF0 +8135D333 1CF1 +8135D334 1CF2 +8135D335 1CF3 +8135D336 1CF4 +8135D337 1CF5 +8135D338 1CF6 +8135D339 1CF7 +8135D430 1CF8 +8135D431 1CF9 +8135D432 1CFA +8135D433 1CFB +8135D434 1CFC +8135D435 1CFD +8135D436 1CFE +8135D437 1CFF +8135D438 1D00 +8135D439 1D01 +8135D530 1D02 +8135D531 1D03 +8135D532 1D04 +8135D533 1D05 +8135D534 1D06 +8135D535 1D07 +8135D536 1D08 +8135D537 1D09 +8135D538 1D0A +8135D539 1D0B +8135D630 1D0C +8135D631 1D0D +8135D632 1D0E +8135D633 1D0F +8135D634 1D10 +8135D635 1D11 +8135D636 1D12 +8135D637 1D13 +8135D638 1D14 +8135D639 1D15 +8135D730 1D16 +8135D731 1D17 +8135D732 1D18 +8135D733 1D19 +8135D734 1D1A +8135D735 1D1B +8135D736 1D1C +8135D737 1D1D +8135D738 1D1E +8135D739 1D1F +8135D830 1D20 +8135D831 1D21 +8135D832 1D22 +8135D833 1D23 +8135D834 1D24 +8135D835 1D25 +8135D836 1D26 +8135D837 1D27 +8135D838 1D28 +8135D839 1D29 +8135D930 1D2A +8135D931 1D2B +8135D932 1D2C +8135D933 1D2D +8135D934 1D2E +8135D935 1D2F +8135D936 1D30 +8135D937 1D31 +8135D938 1D32 +8135D939 1D33 +8135DA30 1D34 +8135DA31 1D35 +8135DA32 1D36 +8135DA33 1D37 +8135DA34 1D38 +8135DA35 1D39 +8135DA36 1D3A +8135DA37 1D3B +8135DA38 1D3C +8135DA39 1D3D +8135DB30 1D3E +8135DB31 1D3F +8135DB32 1D40 +8135DB33 1D41 +8135DB34 1D42 +8135DB35 1D43 +8135DB36 1D44 +8135DB37 1D45 +8135DB38 1D46 +8135DB39 1D47 +8135DC30 1D48 +8135DC31 1D49 +8135DC32 1D4A +8135DC33 1D4B +8135DC34 1D4C +8135DC35 1D4D +8135DC36 1D4E +8135DC37 1D4F +8135DC38 1D50 +8135DC39 1D51 +8135DD30 1D52 +8135DD31 1D53 +8135DD32 1D54 +8135DD33 1D55 +8135DD34 1D56 +8135DD35 1D57 +8135DD36 1D58 +8135DD37 1D59 +8135DD38 1D5A +8135DD39 1D5B +8135DE30 1D5C +8135DE31 1D5D +8135DE32 1D5E +8135DE33 1D5F +8135DE34 1D60 +8135DE35 1D61 +8135DE36 1D62 +8135DE37 1D63 +8135DE38 1D64 +8135DE39 1D65 +8135DF30 1D66 +8135DF31 1D67 +8135DF32 1D68 +8135DF33 1D69 +8135DF34 1D6A +8135DF35 1D6B +8135DF36 1D6C +8135DF37 1D6D +8135DF38 1D6E +8135DF39 1D6F +8135E030 1D70 +8135E031 1D71 +8135E032 1D72 +8135E033 1D73 +8135E034 1D74 +8135E035 1D75 +8135E036 1D76 +8135E037 1D77 +8135E038 1D78 +8135E039 1D79 +8135E130 1D7A +8135E131 1D7B +8135E132 1D7C +8135E133 1D7D +8135E134 1D7E +8135E135 1D7F +8135E136 1D80 +8135E137 1D81 +8135E138 1D82 +8135E139 1D83 +8135E230 1D84 +8135E231 1D85 +8135E232 1D86 +8135E233 1D87 +8135E234 1D88 +8135E235 1D89 +8135E236 1D8A +8135E237 1D8B +8135E238 1D8C +8135E239 1D8D +8135E330 1D8E +8135E331 1D8F +8135E332 1D90 +8135E333 1D91 +8135E334 1D92 +8135E335 1D93 +8135E336 1D94 +8135E337 1D95 +8135E338 1D96 +8135E339 1D97 +8135E430 1D98 +8135E431 1D99 +8135E432 1D9A +8135E433 1D9B +8135E434 1D9C +8135E435 1D9D +8135E436 1D9E +8135E437 1D9F +8135E438 1DA0 +8135E439 1DA1 +8135E530 1DA2 +8135E531 1DA3 +8135E532 1DA4 +8135E533 1DA5 +8135E534 1DA6 +8135E535 1DA7 +8135E536 1DA8 +8135E537 1DA9 +8135E538 1DAA +8135E539 1DAB +8135E630 1DAC +8135E631 1DAD +8135E632 1DAE +8135E633 1DAF +8135E634 1DB0 +8135E635 1DB1 +8135E636 1DB2 +8135E637 1DB3 +8135E638 1DB4 +8135E639 1DB5 +8135E730 1DB6 +8135E731 1DB7 +8135E732 1DB8 +8135E733 1DB9 +8135E734 1DBA +8135E735 1DBB +8135E736 1DBC +8135E737 1DBD +8135E738 1DBE +8135E739 1DBF +8135E830 1DC0 +8135E831 1DC1 +8135E832 1DC2 +8135E833 1DC3 +8135E834 1DC4 +8135E835 1DC5 +8135E836 1DC6 +8135E837 1DC7 +8135E838 1DC8 +8135E839 1DC9 +8135E930 1DCA +8135E931 1DCB +8135E932 1DCC +8135E933 1DCD +8135E934 1DCE +8135E935 1DCF +8135E936 1DD0 +8135E937 1DD1 +8135E938 1DD2 +8135E939 1DD3 +8135EA30 1DD4 +8135EA31 1DD5 +8135EA32 1DD6 +8135EA33 1DD7 +8135EA34 1DD8 +8135EA35 1DD9 +8135EA36 1DDA +8135EA37 1DDB +8135EA38 1DDC +8135EA39 1DDD +8135EB30 1DDE +8135EB31 1DDF +8135EB32 1DE0 +8135EB33 1DE1 +8135EB34 1DE2 +8135EB35 1DE3 +8135EB36 1DE4 +8135EB37 1DE5 +8135EB38 1DE6 +8135EB39 1DE7 +8135EC30 1DE8 +8135EC31 1DE9 +8135EC32 1DEA +8135EC33 1DEB +8135EC34 1DEC +8135EC35 1DED +8135EC36 1DEE +8135EC37 1DEF +8135EC38 1DF0 +8135EC39 1DF1 +8135ED30 1DF2 +8135ED31 1DF3 +8135ED32 1DF4 +8135ED33 1DF5 +8135ED34 1DF6 +8135ED35 1DF7 +8135ED36 1DF8 +8135ED37 1DF9 +8135ED38 1DFA +8135ED39 1DFB +8135EE30 1DFC +8135EE31 1DFD +8135EE32 1DFE +8135EE33 1DFF +8135EE34 1E00 +8135EE35 1E01 +8135EE36 1E02 +8135EE37 1E03 +8135EE38 1E04 +8135EE39 1E05 +8135EF30 1E06 +8135EF31 1E07 +8135EF32 1E08 +8135EF33 1E09 +8135EF34 1E0A +8135EF35 1E0B +8135EF36 1E0C +8135EF37 1E0D +8135EF38 1E0E +8135EF39 1E0F +8135F030 1E10 +8135F031 1E11 +8135F032 1E12 +8135F033 1E13 +8135F034 1E14 +8135F035 1E15 +8135F036 1E16 +8135F037 1E17 +8135F038 1E18 +8135F039 1E19 +8135F130 1E1A +8135F131 1E1B +8135F132 1E1C +8135F133 1E1D +8135F134 1E1E +8135F135 1E1F +8135F136 1E20 +8135F137 1E21 +8135F138 1E22 +8135F139 1E23 +8135F230 1E24 +8135F231 1E25 +8135F232 1E26 +8135F233 1E27 +8135F234 1E28 +8135F235 1E29 +8135F236 1E2A +8135F237 1E2B +8135F238 1E2C +8135F239 1E2D +8135F330 1E2E +8135F331 1E2F +8135F332 1E30 +8135F333 1E31 +8135F334 1E32 +8135F335 1E33 +8135F336 1E34 +8135F337 1E35 +8135F338 1E36 +8135F339 1E37 +8135F430 1E38 +8135F431 1E39 +8135F432 1E3A +8135F433 1E3B +8135F434 1E3C +8135F435 1E3D +8135F436 1E3E +8135F437 1E3F +8135F438 1E40 +8135F439 1E41 +8135F530 1E42 +8135F531 1E43 +8135F532 1E44 +8135F533 1E45 +8135F534 1E46 +8135F535 1E47 +8135F536 1E48 +8135F537 1E49 +8135F538 1E4A +8135F539 1E4B +8135F630 1E4C +8135F631 1E4D +8135F632 1E4E +8135F633 1E4F +8135F634 1E50 +8135F635 1E51 +8135F636 1E52 +8135F637 1E53 +8135F638 1E54 +8135F639 1E55 +8135F730 1E56 +8135F731 1E57 +8135F732 1E58 +8135F733 1E59 +8135F734 1E5A +8135F735 1E5B +8135F736 1E5C +8135F737 1E5D +8135F738 1E5E +8135F739 1E5F +8135F830 1E60 +8135F831 1E61 +8135F832 1E62 +8135F833 1E63 +8135F834 1E64 +8135F835 1E65 +8135F836 1E66 +8135F837 1E67 +8135F838 1E68 +8135F839 1E69 +8135F930 1E6A +8135F931 1E6B +8135F932 1E6C +8135F933 1E6D +8135F934 1E6E +8135F935 1E6F +8135F936 1E70 +8135F937 1E71 +8135F938 1E72 +8135F939 1E73 +8135FA30 1E74 +8135FA31 1E75 +8135FA32 1E76 +8135FA33 1E77 +8135FA34 1E78 +8135FA35 1E79 +8135FA36 1E7A +8135FA37 1E7B +8135FA38 1E7C +8135FA39 1E7D +8135FB30 1E7E +8135FB31 1E7F +8135FB32 1E80 +8135FB33 1E81 +8135FB34 1E82 +8135FB35 1E83 +8135FB36 1E84 +8135FB37 1E85 +8135FB38 1E86 +8135FB39 1E87 +8135FC30 1E88 +8135FC31 1E89 +8135FC32 1E8A +8135FC33 1E8B +8135FC34 1E8C +8135FC35 1E8D +8135FC36 1E8E +8135FC37 1E8F +8135FC38 1E90 +8135FC39 1E91 +8135FD30 1E92 +8135FD31 1E93 +8135FD32 1E94 +8135FD33 1E95 +8135FD34 1E96 +8135FD35 1E97 +8135FD36 1E98 +8135FD37 1E99 +8135FD38 1E9A +8135FD39 1E9B +8135FE30 1E9C +8135FE31 1E9D +8135FE32 1E9E +8135FE33 1E9F +8135FE34 1EA0 +8135FE35 1EA1 +8135FE36 1EA2 +8135FE37 1EA3 +8135FE38 1EA4 +8135FE39 1EA5 +81368130 1EA6 +81368131 1EA7 +81368132 1EA8 +81368133 1EA9 +81368134 1EAA +81368135 1EAB +81368136 1EAC +81368137 1EAD +81368138 1EAE +81368139 1EAF +81368230 1EB0 +81368231 1EB1 +81368232 1EB2 +81368233 1EB3 +81368234 1EB4 +81368235 1EB5 +81368236 1EB6 +81368237 1EB7 +81368238 1EB8 +81368239 1EB9 +81368330 1EBA +81368331 1EBB +81368332 1EBC +81368333 1EBD +81368334 1EBE +81368335 1EBF +81368336 1EC0 +81368337 1EC1 +81368338 1EC2 +81368339 1EC3 +81368430 1EC4 +81368431 1EC5 +81368432 1EC6 +81368433 1EC7 +81368434 1EC8 +81368435 1EC9 +81368436 1ECA +81368437 1ECB +81368438 1ECC +81368439 1ECD +81368530 1ECE +81368531 1ECF +81368532 1ED0 +81368533 1ED1 +81368534 1ED2 +81368535 1ED3 +81368536 1ED4 +81368537 1ED5 +81368538 1ED6 +81368539 1ED7 +81368630 1ED8 +81368631 1ED9 +81368632 1EDA +81368633 1EDB +81368634 1EDC +81368635 1EDD +81368636 1EDE +81368637 1EDF +81368638 1EE0 +81368639 1EE1 +81368730 1EE2 +81368731 1EE3 +81368732 1EE4 +81368733 1EE5 +81368734 1EE6 +81368735 1EE7 +81368736 1EE8 +81368737 1EE9 +81368738 1EEA +81368739 1EEB +81368830 1EEC +81368831 1EED +81368832 1EEE +81368833 1EEF +81368834 1EF0 +81368835 1EF1 +81368836 1EF2 +81368837 1EF3 +81368838 1EF4 +81368839 1EF5 +81368930 1EF6 +81368931 1EF7 +81368932 1EF8 +81368933 1EF9 +81368934 1EFA +81368935 1EFB +81368936 1EFC +81368937 1EFD +81368938 1EFE +81368939 1EFF +81368A30 1F00 +81368A31 1F01 +81368A32 1F02 +81368A33 1F03 +81368A34 1F04 +81368A35 1F05 +81368A36 1F06 +81368A37 1F07 +81368A38 1F08 +81368A39 1F09 +81368B30 1F0A +81368B31 1F0B +81368B32 1F0C +81368B33 1F0D +81368B34 1F0E +81368B35 1F0F +81368B36 1F10 +81368B37 1F11 +81368B38 1F12 +81368B39 1F13 +81368C30 1F14 +81368C31 1F15 +81368C32 1F16 +81368C33 1F17 +81368C34 1F18 +81368C35 1F19 +81368C36 1F1A +81368C37 1F1B +81368C38 1F1C +81368C39 1F1D +81368D30 1F1E +81368D31 1F1F +81368D32 1F20 +81368D33 1F21 +81368D34 1F22 +81368D35 1F23 +81368D36 1F24 +81368D37 1F25 +81368D38 1F26 +81368D39 1F27 +81368E30 1F28 +81368E31 1F29 +81368E32 1F2A +81368E33 1F2B +81368E34 1F2C +81368E35 1F2D +81368E36 1F2E +81368E37 1F2F +81368E38 1F30 +81368E39 1F31 +81368F30 1F32 +81368F31 1F33 +81368F32 1F34 +81368F33 1F35 +81368F34 1F36 +81368F35 1F37 +81368F36 1F38 +81368F37 1F39 +81368F38 1F3A +81368F39 1F3B +81369030 1F3C +81369031 1F3D +81369032 1F3E +81369033 1F3F +81369034 1F40 +81369035 1F41 +81369036 1F42 +81369037 1F43 +81369038 1F44 +81369039 1F45 +81369130 1F46 +81369131 1F47 +81369132 1F48 +81369133 1F49 +81369134 1F4A +81369135 1F4B +81369136 1F4C +81369137 1F4D +81369138 1F4E +81369139 1F4F +81369230 1F50 +81369231 1F51 +81369232 1F52 +81369233 1F53 +81369234 1F54 +81369235 1F55 +81369236 1F56 +81369237 1F57 +81369238 1F58 +81369239 1F59 +81369330 1F5A +81369331 1F5B +81369332 1F5C +81369333 1F5D +81369334 1F5E +81369335 1F5F +81369336 1F60 +81369337 1F61 +81369338 1F62 +81369339 1F63 +81369430 1F64 +81369431 1F65 +81369432 1F66 +81369433 1F67 +81369434 1F68 +81369435 1F69 +81369436 1F6A +81369437 1F6B +81369438 1F6C +81369439 1F6D +81369530 1F6E +81369531 1F6F +81369532 1F70 +81369533 1F71 +81369534 1F72 +81369535 1F73 +81369536 1F74 +81369537 1F75 +81369538 1F76 +81369539 1F77 +81369630 1F78 +81369631 1F79 +81369632 1F7A +81369633 1F7B +81369634 1F7C +81369635 1F7D +81369636 1F7E +81369637 1F7F +81369638 1F80 +81369639 1F81 +81369730 1F82 +81369731 1F83 +81369732 1F84 +81369733 1F85 +81369734 1F86 +81369735 1F87 +81369736 1F88 +81369737 1F89 +81369738 1F8A +81369739 1F8B +81369830 1F8C +81369831 1F8D +81369832 1F8E +81369833 1F8F +81369834 1F90 +81369835 1F91 +81369836 1F92 +81369837 1F93 +81369838 1F94 +81369839 1F95 +81369930 1F96 +81369931 1F97 +81369932 1F98 +81369933 1F99 +81369934 1F9A +81369935 1F9B +81369936 1F9C +81369937 1F9D +81369938 1F9E +81369939 1F9F +81369A30 1FA0 +81369A31 1FA1 +81369A32 1FA2 +81369A33 1FA3 +81369A34 1FA4 +81369A35 1FA5 +81369A36 1FA6 +81369A37 1FA7 +81369A38 1FA8 +81369A39 1FA9 +81369B30 1FAA +81369B31 1FAB +81369B32 1FAC +81369B33 1FAD +81369B34 1FAE +81369B35 1FAF +81369B36 1FB0 +81369B37 1FB1 +81369B38 1FB2 +81369B39 1FB3 +81369C30 1FB4 +81369C31 1FB5 +81369C32 1FB6 +81369C33 1FB7 +81369C34 1FB8 +81369C35 1FB9 +81369C36 1FBA +81369C37 1FBB +81369C38 1FBC +81369C39 1FBD +81369D30 1FBE +81369D31 1FBF +81369D32 1FC0 +81369D33 1FC1 +81369D34 1FC2 +81369D35 1FC3 +81369D36 1FC4 +81369D37 1FC5 +81369D38 1FC6 +81369D39 1FC7 +81369E30 1FC8 +81369E31 1FC9 +81369E32 1FCA +81369E33 1FCB +81369E34 1FCC +81369E35 1FCD +81369E36 1FCE +81369E37 1FCF +81369E38 1FD0 +81369E39 1FD1 +81369F30 1FD2 +81369F31 1FD3 +81369F32 1FD4 +81369F33 1FD5 +81369F34 1FD6 +81369F35 1FD7 +81369F36 1FD8 +81369F37 1FD9 +81369F38 1FDA +81369F39 1FDB +8136A030 1FDC +8136A031 1FDD +8136A032 1FDE +8136A033 1FDF +8136A034 1FE0 +8136A035 1FE1 +8136A036 1FE2 +8136A037 1FE3 +8136A038 1FE4 +8136A039 1FE5 +8136A130 1FE6 +8136A131 1FE7 +8136A132 1FE8 +8136A133 1FE9 +8136A134 1FEA +8136A135 1FEB +8136A136 1FEC +8136A137 1FED +8136A138 1FEE +8136A139 1FEF +8136A230 1FF0 +8136A231 1FF1 +8136A232 1FF2 +8136A233 1FF3 +8136A234 1FF4 +8136A235 1FF5 +8136A236 1FF6 +8136A237 1FF7 +8136A238 1FF8 +8136A239 1FF9 +8136A330 1FFA +8136A331 1FFB +8136A332 1FFC +8136A333 1FFD +8136A334 1FFE +8136A335 1FFF +8136A336 2000 +8136A337 2001 +8136A338 2002 +8136A339 2003 +8136A430 2004 +8136A431 2005 +8136A432 2006 +8136A433 2007 +8136A434 2008 +8136A435 2009 +8136A436 200A +8136A437 200B +8136A438 200C +8136A439 200D +8136A530 200E +8136A531 200F +A95C 2010 +8136A532 2011 +8136A533 2012 +A843 2013 +A1AA 2014 +A844 2015 +A1AC 2016 +8136A534 2017 +A1AE 2018 +A1AF 2019 +8136A535 201A +8136A536 201B +A1B0 201C +A1B1 201D +8136A537 201E +8136A538 201F +8136A539 2020 +8136A630 2021 +8136A631 2022 +8136A632 2023 +8136A633 2024 +A845 2025 +A1AD 2026 +8136A634 2027 +8136A635 2028 +8136A636 2029 +8136A637 202A +8136A638 202B +8136A639 202C +8136A730 202D +8136A731 202E +8136A732 202F +A1EB 2030 +8136A733 2031 +A1E4 2032 +A1E5 2033 +8136A734 2034 +A846 2035 +8136A735 2036 +8136A736 2037 +8136A737 2038 +8136A738 2039 +8136A739 203A +A1F9 203B +8136A830 203C +8136A831 203D +8136A832 203E +8136A833 203F +8136A834 2040 +8136A835 2041 +8136A836 2042 +8136A837 2043 +8136A838 2044 +8136A839 2045 +8136A930 2046 +8136A931 2047 +8136A932 2048 +8136A933 2049 +8136A934 204A +8136A935 204B +8136A936 204C +8136A937 204D +8136A938 204E +8136A939 204F +8136AA30 2050 +8136AA31 2051 +8136AA32 2052 +8136AA33 2053 +8136AA34 2054 +8136AA35 2055 +8136AA36 2056 +8136AA37 2057 +8136AA38 2058 +8136AA39 2059 +8136AB30 205A +8136AB31 205B +8136AB32 205C +8136AB33 205D +8136AB34 205E +8136AB35 205F +8136AB36 2060 +8136AB37 2061 +8136AB38 2062 +8136AB39 2063 +8136AC30 2064 +8136AC31 2065 +8136AC32 2066 +8136AC33 2067 +8136AC34 2068 +8136AC35 2069 +8136AC36 206A +8136AC37 206B +8136AC38 206C +8136AC39 206D +8136AD30 206E +8136AD31 206F +8136AD32 2070 +8136AD33 2071 +8136AD34 2072 +8136AD35 2073 +8136AD36 2074 +8136AD37 2075 +8136AD38 2076 +8136AD39 2077 +8136AE30 2078 +8136AE31 2079 +8136AE32 207A +8136AE33 207B +8136AE34 207C +8136AE35 207D +8136AE36 207E +8136AE37 207F +8136AE38 2080 +8136AE39 2081 +8136AF30 2082 +8136AF31 2083 +8136AF32 2084 +8136AF33 2085 +8136AF34 2086 +8136AF35 2087 +8136AF36 2088 +8136AF37 2089 +8136AF38 208A +8136AF39 208B +8136B030 208C +8136B031 208D +8136B032 208E +8136B033 208F +8136B034 2090 +8136B035 2091 +8136B036 2092 +8136B037 2093 +8136B038 2094 +8136B039 2095 +8136B130 2096 +8136B131 2097 +8136B132 2098 +8136B133 2099 +8136B134 209A +8136B135 209B +8136B136 209C +8136B137 209D +8136B138 209E +8136B139 209F +8136B230 20A0 +8136B231 20A1 +8136B232 20A2 +8136B233 20A3 +8136B234 20A4 +8136B235 20A5 +8136B236 20A6 +8136B237 20A7 +8136B238 20A8 +8136B239 20A9 +8136B330 20AA +8136B331 20AB +A2E3 20AC +8136B332 20AD +8136B333 20AE +8136B334 20AF +8136B335 20B0 +8136B336 20B1 +8136B337 20B2 +8136B338 20B3 +8136B339 20B4 +8136B430 20B5 +8136B431 20B6 +8136B432 20B7 +8136B433 20B8 +8136B434 20B9 +8136B435 20BA +8136B436 20BB +8136B437 20BC +8136B438 20BD +8136B439 20BE +8136B530 20BF +8136B531 20C0 +8136B532 20C1 +8136B533 20C2 +8136B534 20C3 +8136B535 20C4 +8136B536 20C5 +8136B537 20C6 +8136B538 20C7 +8136B539 20C8 +8136B630 20C9 +8136B631 20CA +8136B632 20CB +8136B633 20CC +8136B634 20CD +8136B635 20CE +8136B636 20CF +8136B637 20D0 +8136B638 20D1 +8136B639 20D2 +8136B730 20D3 +8136B731 20D4 +8136B732 20D5 +8136B733 20D6 +8136B734 20D7 +8136B735 20D8 +8136B736 20D9 +8136B737 20DA +8136B738 20DB +8136B739 20DC +8136B830 20DD +8136B831 20DE +8136B832 20DF +8136B833 20E0 +8136B834 20E1 +8136B835 20E2 +8136B836 20E3 +8136B837 20E4 +8136B838 20E5 +8136B839 20E6 +8136B930 20E7 +8136B931 20E8 +8136B932 20E9 +8136B933 20EA +8136B934 20EB +8136B935 20EC +8136B936 20ED +8136B937 20EE +8136B938 20EF +8136B939 20F0 +8136BA30 20F1 +8136BA31 20F2 +8136BA32 20F3 +8136BA33 20F4 +8136BA34 20F5 +8136BA35 20F6 +8136BA36 20F7 +8136BA37 20F8 +8136BA38 20F9 +8136BA39 20FA +8136BB30 20FB +8136BB31 20FC +8136BB32 20FD +8136BB33 20FE +8136BB34 20FF +8136BB35 2100 +8136BB36 2101 +8136BB37 2102 +A1E6 2103 +8136BB38 2104 +A847 2105 +8136BB39 2106 +8136BC30 2107 +8136BC31 2108 +A848 2109 +8136BC32 210A +8136BC33 210B +8136BC34 210C +8136BC35 210D +8136BC36 210E +8136BC37 210F +8136BC38 2110 +8136BC39 2111 +8136BD30 2112 +8136BD31 2113 +8136BD32 2114 +8136BD33 2115 +A1ED 2116 +8136BD34 2117 +8136BD35 2118 +8136BD36 2119 +8136BD37 211A +8136BD38 211B +8136BD39 211C +8136BE30 211D +8136BE31 211E +8136BE32 211F +8136BE33 2120 +A959 2121 +8136BE34 2122 +8136BE35 2123 +8136BE36 2124 +8136BE37 2125 +8136BE38 2126 +8136BE39 2127 +8136BF30 2128 +8136BF31 2129 +8136BF32 212A +8136BF33 212B +8136BF34 212C +8136BF35 212D +8136BF36 212E +8136BF37 212F +8136BF38 2130 +8136BF39 2131 +8136C030 2132 +8136C031 2133 +8136C032 2134 +8136C033 2135 +8136C034 2136 +8136C035 2137 +8136C036 2138 +8136C037 2139 +8136C038 213A +8136C039 213B +8136C130 213C +8136C131 213D +8136C132 213E +8136C133 213F +8136C134 2140 +8136C135 2141 +8136C136 2142 +8136C137 2143 +8136C138 2144 +8136C139 2145 +8136C230 2146 +8136C231 2147 +8136C232 2148 +8136C233 2149 +8136C234 214A +8136C235 214B +8136C236 214C +8136C237 214D +8136C238 214E +8136C239 214F +8136C330 2150 +8136C331 2151 +8136C332 2152 +8136C333 2153 +8136C334 2154 +8136C335 2155 +8136C336 2156 +8136C337 2157 +8136C338 2158 +8136C339 2159 +8136C430 215A +8136C431 215B +8136C432 215C +8136C433 215D +8136C434 215E +8136C435 215F +A2F1 2160 +A2F2 2161 +A2F3 2162 +A2F4 2163 +A2F5 2164 +A2F6 2165 +A2F7 2166 +A2F8 2167 +A2F9 2168 +A2FA 2169 +A2FB 216A +A2FC 216B +8136C436 216C +8136C437 216D +8136C438 216E +8136C439 216F +A2A1 2170 +A2A2 2171 +A2A3 2172 +A2A4 2173 +A2A5 2174 +A2A6 2175 +A2A7 2176 +A2A8 2177 +A2A9 2178 +A2AA 2179 +8136C530 217A +8136C531 217B +8136C532 217C +8136C533 217D +8136C534 217E +8136C535 217F +8136C536 2180 +8136C537 2181 +8136C538 2182 +8136C539 2183 +8136C630 2184 +8136C631 2185 +8136C632 2186 +8136C633 2187 +8136C634 2188 +8136C635 2189 +8136C636 218A +8136C637 218B +8136C638 218C +8136C639 218D +8136C730 218E +8136C731 218F +A1FB 2190 +A1FC 2191 +A1FA 2192 +A1FD 2193 +8136C732 2194 +8136C733 2195 +A849 2196 +A84A 2197 +A84B 2198 +A84C 2199 +8136C734 219A +8136C735 219B +8136C736 219C +8136C737 219D +8136C738 219E +8136C739 219F +8136C830 21A0 +8136C831 21A1 +8136C832 21A2 +8136C833 21A3 +8136C834 21A4 +8136C835 21A5 +8136C836 21A6 +8136C837 21A7 +8136C838 21A8 +8136C839 21A9 +8136C930 21AA +8136C931 21AB +8136C932 21AC +8136C933 21AD +8136C934 21AE +8136C935 21AF +8136C936 21B0 +8136C937 21B1 +8136C938 21B2 +8136C939 21B3 +8136CA30 21B4 +8136CA31 21B5 +8136CA32 21B6 +8136CA33 21B7 +8136CA34 21B8 +8136CA35 21B9 +8136CA36 21BA +8136CA37 21BB +8136CA38 21BC +8136CA39 21BD +8136CB30 21BE +8136CB31 21BF +8136CB32 21C0 +8136CB33 21C1 +8136CB34 21C2 +8136CB35 21C3 +8136CB36 21C4 +8136CB37 21C5 +8136CB38 21C6 +8136CB39 21C7 +8136CC30 21C8 +8136CC31 21C9 +8136CC32 21CA +8136CC33 21CB +8136CC34 21CC +8136CC35 21CD +8136CC36 21CE +8136CC37 21CF +8136CC38 21D0 +8136CC39 21D1 +8136CD30 21D2 +8136CD31 21D3 +8136CD32 21D4 +8136CD33 21D5 +8136CD34 21D6 +8136CD35 21D7 +8136CD36 21D8 +8136CD37 21D9 +8136CD38 21DA +8136CD39 21DB +8136CE30 21DC +8136CE31 21DD +8136CE32 21DE +8136CE33 21DF +8136CE34 21E0 +8136CE35 21E1 +8136CE36 21E2 +8136CE37 21E3 +8136CE38 21E4 +8136CE39 21E5 +8136CF30 21E6 +8136CF31 21E7 +8136CF32 21E8 +8136CF33 21E9 +8136CF34 21EA +8136CF35 21EB +8136CF36 21EC +8136CF37 21ED +8136CF38 21EE +8136CF39 21EF +8136D030 21F0 +8136D031 21F1 +8136D032 21F2 +8136D033 21F3 +8136D034 21F4 +8136D035 21F5 +8136D036 21F6 +8136D037 21F7 +8136D038 21F8 +8136D039 21F9 +8136D130 21FA +8136D131 21FB +8136D132 21FC +8136D133 21FD +8136D134 21FE +8136D135 21FF +8136D136 2200 +8136D137 2201 +8136D138 2202 +8136D139 2203 +8136D230 2204 +8136D231 2205 +8136D232 2206 +8136D233 2207 +A1CA 2208 +8136D234 2209 +8136D235 220A +8136D236 220B +8136D237 220C +8136D238 220D +8136D239 220E +A1C7 220F +8136D330 2210 +A1C6 2211 +8136D331 2212 +8136D332 2213 +8136D333 2214 +A84D 2215 +8136D334 2216 +8136D335 2217 +8136D336 2218 +8136D337 2219 +A1CC 221A +8136D338 221B +8136D339 221C +A1D8 221D +A1DE 221E +A84E 221F +A1CF 2220 +8136D430 2221 +8136D431 2222 +A84F 2223 +8136D432 2224 +A1CE 2225 +8136D433 2226 +A1C4 2227 +A1C5 2228 +A1C9 2229 +A1C8 222A +A1D2 222B +8136D434 222C +8136D435 222D +A1D3 222E +8136D436 222F +8136D437 2230 +8136D438 2231 +8136D439 2232 +8136D530 2233 +A1E0 2234 +A1DF 2235 +A1C3 2236 +A1CB 2237 +8136D531 2238 +8136D532 2239 +8136D533 223A +8136D534 223B +8136D535 223C +A1D7 223D +8136D536 223E +8136D537 223F +8136D538 2240 +8136D539 2241 +8136D630 2242 +8136D631 2243 +8136D632 2244 +8136D633 2245 +8136D634 2246 +8136D635 2247 +A1D6 2248 +8136D636 2249 +8136D637 224A +8136D638 224B +A1D5 224C +8136D639 224D +8136D730 224E +8136D731 224F +8136D732 2250 +8136D733 2251 +A850 2252 +8136D734 2253 +8136D735 2254 +8136D736 2255 +8136D737 2256 +8136D738 2257 +8136D739 2258 +8136D830 2259 +8136D831 225A +8136D832 225B +8136D833 225C +8136D834 225D +8136D835 225E +8136D836 225F +A1D9 2260 +A1D4 2261 +8136D837 2262 +8136D838 2263 +A1DC 2264 +A1DD 2265 +A851 2266 +A852 2267 +8136D839 2268 +8136D930 2269 +8136D931 226A +8136D932 226B +8136D933 226C +8136D934 226D +A1DA 226E +A1DB 226F +8136D935 2270 +8136D936 2271 +8136D937 2272 +8136D938 2273 +8136D939 2274 +8136DA30 2275 +8136DA31 2276 +8136DA32 2277 +8136DA33 2278 +8136DA34 2279 +8136DA35 227A +8136DA36 227B +8136DA37 227C +8136DA38 227D +8136DA39 227E +8136DB30 227F +8136DB31 2280 +8136DB32 2281 +8136DB33 2282 +8136DB34 2283 +8136DB35 2284 +8136DB36 2285 +8136DB37 2286 +8136DB38 2287 +8136DB39 2288 +8136DC30 2289 +8136DC31 228A +8136DC32 228B +8136DC33 228C +8136DC34 228D +8136DC35 228E +8136DC36 228F +8136DC37 2290 +8136DC38 2291 +8136DC39 2292 +8136DD30 2293 +8136DD31 2294 +A892 2295 +8136DD32 2296 +8136DD33 2297 +8136DD34 2298 +A1D1 2299 +8136DD35 229A +8136DD36 229B +8136DD37 229C +8136DD38 229D +8136DD39 229E +8136DE30 229F +8136DE31 22A0 +8136DE32 22A1 +8136DE33 22A2 +8136DE34 22A3 +8136DE35 22A4 +A1CD 22A5 +8136DE36 22A6 +8136DE37 22A7 +8136DE38 22A8 +8136DE39 22A9 +8136DF30 22AA +8136DF31 22AB +8136DF32 22AC +8136DF33 22AD +8136DF34 22AE +8136DF35 22AF +8136DF36 22B0 +8136DF37 22B1 +8136DF38 22B2 +8136DF39 22B3 +8136E030 22B4 +8136E031 22B5 +8136E032 22B6 +8136E033 22B7 +8136E034 22B8 +8136E035 22B9 +8136E036 22BA +8136E037 22BB +8136E038 22BC +8136E039 22BD +8136E130 22BE +A853 22BF +8136E131 22C0 +8136E132 22C1 +8136E133 22C2 +8136E134 22C3 +8136E135 22C4 +8136E136 22C5 +8136E137 22C6 +8136E138 22C7 +8136E139 22C8 +8136E230 22C9 +8136E231 22CA +8136E232 22CB +8136E233 22CC +8136E234 22CD +8136E235 22CE +8136E236 22CF +8136E237 22D0 +8136E238 22D1 +8136E239 22D2 +8136E330 22D3 +8136E331 22D4 +8136E332 22D5 +8136E333 22D6 +8136E334 22D7 +8136E335 22D8 +8136E336 22D9 +8136E337 22DA +8136E338 22DB +8136E339 22DC +8136E430 22DD +8136E431 22DE +8136E432 22DF +8136E433 22E0 +8136E434 22E1 +8136E435 22E2 +8136E436 22E3 +8136E437 22E4 +8136E438 22E5 +8136E439 22E6 +8136E530 22E7 +8136E531 22E8 +8136E532 22E9 +8136E533 22EA +8136E534 22EB +8136E535 22EC +8136E536 22ED +8136E537 22EE +8136E538 22EF +8136E539 22F0 +8136E630 22F1 +8136E631 22F2 +8136E632 22F3 +8136E633 22F4 +8136E634 22F5 +8136E635 22F6 +8136E636 22F7 +8136E637 22F8 +8136E638 22F9 +8136E639 22FA +8136E730 22FB +8136E731 22FC +8136E732 22FD +8136E733 22FE +8136E734 22FF +8136E735 2300 +8136E736 2301 +8136E737 2302 +8136E738 2303 +8136E739 2304 +8136E830 2305 +8136E831 2306 +8136E832 2307 +8136E833 2308 +8136E834 2309 +8136E835 230A +8136E836 230B +8136E837 230C +8136E838 230D +8136E839 230E +8136E930 230F +8136E931 2310 +8136E932 2311 +A1D0 2312 +8136E933 2313 +8136E934 2314 +8136E935 2315 +8136E936 2316 +8136E937 2317 +8136E938 2318 +8136E939 2319 +8136EA30 231A +8136EA31 231B +8136EA32 231C +8136EA33 231D +8136EA34 231E +8136EA35 231F +8136EA36 2320 +8136EA37 2321 +8136EA38 2322 +8136EA39 2323 +8136EB30 2324 +8136EB31 2325 +8136EB32 2326 +8136EB33 2327 +8136EB34 2328 +8136EB35 2329 +8136EB36 232A +8136EB37 232B +8136EB38 232C +8136EB39 232D +8136EC30 232E +8136EC31 232F +8136EC32 2330 +8136EC33 2331 +8136EC34 2332 +8136EC35 2333 +8136EC36 2334 +8136EC37 2335 +8136EC38 2336 +8136EC39 2337 +8136ED30 2338 +8136ED31 2339 +8136ED32 233A +8136ED33 233B +8136ED34 233C +8136ED35 233D +8136ED36 233E +8136ED37 233F +8136ED38 2340 +8136ED39 2341 +8136EE30 2342 +8136EE31 2343 +8136EE32 2344 +8136EE33 2345 +8136EE34 2346 +8136EE35 2347 +8136EE36 2348 +8136EE37 2349 +8136EE38 234A +8136EE39 234B +8136EF30 234C +8136EF31 234D +8136EF32 234E +8136EF33 234F +8136EF34 2350 +8136EF35 2351 +8136EF36 2352 +8136EF37 2353 +8136EF38 2354 +8136EF39 2355 +8136F030 2356 +8136F031 2357 +8136F032 2358 +8136F033 2359 +8136F034 235A +8136F035 235B +8136F036 235C +8136F037 235D +8136F038 235E +8136F039 235F +8136F130 2360 +8136F131 2361 +8136F132 2362 +8136F133 2363 +8136F134 2364 +8136F135 2365 +8136F136 2366 +8136F137 2367 +8136F138 2368 +8136F139 2369 +8136F230 236A +8136F231 236B +8136F232 236C +8136F233 236D +8136F234 236E +8136F235 236F +8136F236 2370 +8136F237 2371 +8136F238 2372 +8136F239 2373 +8136F330 2374 +8136F331 2375 +8136F332 2376 +8136F333 2377 +8136F334 2378 +8136F335 2379 +8136F336 237A +8136F337 237B +8136F338 237C +8136F339 237D +8136F430 237E +8136F431 237F +8136F432 2380 +8136F433 2381 +8136F434 2382 +8136F435 2383 +8136F436 2384 +8136F437 2385 +8136F438 2386 +8136F439 2387 +8136F530 2388 +8136F531 2389 +8136F532 238A +8136F533 238B +8136F534 238C +8136F535 238D +8136F536 238E +8136F537 238F +8136F538 2390 +8136F539 2391 +8136F630 2392 +8136F631 2393 +8136F632 2394 +8136F633 2395 +8136F634 2396 +8136F635 2397 +8136F636 2398 +8136F637 2399 +8136F638 239A +8136F639 239B +8136F730 239C +8136F731 239D +8136F732 239E +8136F733 239F +8136F734 23A0 +8136F735 23A1 +8136F736 23A2 +8136F737 23A3 +8136F738 23A4 +8136F739 23A5 +8136F830 23A6 +8136F831 23A7 +8136F832 23A8 +8136F833 23A9 +8136F834 23AA +8136F835 23AB +8136F836 23AC +8136F837 23AD +8136F838 23AE +8136F839 23AF +8136F930 23B0 +8136F931 23B1 +8136F932 23B2 +8136F933 23B3 +8136F934 23B4 +8136F935 23B5 +8136F936 23B6 +8136F937 23B7 +8136F938 23B8 +8136F939 23B9 +8136FA30 23BA +8136FA31 23BB +8136FA32 23BC +8136FA33 23BD +8136FA34 23BE +8136FA35 23BF +8136FA36 23C0 +8136FA37 23C1 +8136FA38 23C2 +8136FA39 23C3 +8136FB30 23C4 +8136FB31 23C5 +8136FB32 23C6 +8136FB33 23C7 +8136FB34 23C8 +8136FB35 23C9 +8136FB36 23CA +8136FB37 23CB +8136FB38 23CC +8136FB39 23CD +8136FC30 23CE +8136FC31 23CF +8136FC32 23D0 +8136FC33 23D1 +8136FC34 23D2 +8136FC35 23D3 +8136FC36 23D4 +8136FC37 23D5 +8136FC38 23D6 +8136FC39 23D7 +8136FD30 23D8 +8136FD31 23D9 +8136FD32 23DA +8136FD33 23DB +8136FD34 23DC +8136FD35 23DD +8136FD36 23DE +8136FD37 23DF +8136FD38 23E0 +8136FD39 23E1 +8136FE30 23E2 +8136FE31 23E3 +8136FE32 23E4 +8136FE33 23E5 +8136FE34 23E6 +8136FE35 23E7 +8136FE36 23E8 +8136FE37 23E9 +8136FE38 23EA +8136FE39 23EB +81378130 23EC +81378131 23ED +81378132 23EE +81378133 23EF +81378134 23F0 +81378135 23F1 +81378136 23F2 +81378137 23F3 +81378138 23F4 +81378139 23F5 +81378230 23F6 +81378231 23F7 +81378232 23F8 +81378233 23F9 +81378234 23FA +81378235 23FB +81378236 23FC +81378237 23FD +81378238 23FE +81378239 23FF +81378330 2400 +81378331 2401 +81378332 2402 +81378333 2403 +81378334 2404 +81378335 2405 +81378336 2406 +81378337 2407 +81378338 2408 +81378339 2409 +81378430 240A +81378431 240B +81378432 240C +81378433 240D +81378434 240E +81378435 240F +81378436 2410 +81378437 2411 +81378438 2412 +81378439 2413 +81378530 2414 +81378531 2415 +81378532 2416 +81378533 2417 +81378534 2418 +81378535 2419 +81378536 241A +81378537 241B +81378538 241C +81378539 241D +81378630 241E +81378631 241F +81378632 2420 +81378633 2421 +81378634 2422 +81378635 2423 +81378636 2424 +81378637 2425 +81378638 2426 +81378639 2427 +81378730 2428 +81378731 2429 +81378732 242A +81378733 242B +81378734 242C +81378735 242D +81378736 242E +81378737 242F +81378738 2430 +81378739 2431 +81378830 2432 +81378831 2433 +81378832 2434 +81378833 2435 +81378834 2436 +81378835 2437 +81378836 2438 +81378837 2439 +81378838 243A +81378839 243B +81378930 243C +81378931 243D +81378932 243E +81378933 243F +81378934 2440 +81378935 2441 +81378936 2442 +81378937 2443 +81378938 2444 +81378939 2445 +81378A30 2446 +81378A31 2447 +81378A32 2448 +81378A33 2449 +81378A34 244A +81378A35 244B +81378A36 244C +81378A37 244D +81378A38 244E +81378A39 244F +81378B30 2450 +81378B31 2451 +81378B32 2452 +81378B33 2453 +81378B34 2454 +81378B35 2455 +81378B36 2456 +81378B37 2457 +81378B38 2458 +81378B39 2459 +81378C30 245A +81378C31 245B +81378C32 245C +81378C33 245D +81378C34 245E +81378C35 245F +A2D9 2460 +A2DA 2461 +A2DB 2462 +A2DC 2463 +A2DD 2464 +A2DE 2465 +A2DF 2466 +A2E0 2467 +A2E1 2468 +A2E2 2469 +81378C36 246A +81378C37 246B +81378C38 246C +81378C39 246D +81378D30 246E +81378D31 246F +81378D32 2470 +81378D33 2471 +81378D34 2472 +81378D35 2473 +A2C5 2474 +A2C6 2475 +A2C7 2476 +A2C8 2477 +A2C9 2478 +A2CA 2479 +A2CB 247A +A2CC 247B +A2CD 247C +A2CE 247D +A2CF 247E +A2D0 247F +A2D1 2480 +A2D2 2481 +A2D3 2482 +A2D4 2483 +A2D5 2484 +A2D6 2485 +A2D7 2486 +A2D8 2487 +A2B1 2488 +A2B2 2489 +A2B3 248A +A2B4 248B +A2B5 248C +A2B6 248D +A2B7 248E +A2B8 248F +A2B9 2490 +A2BA 2491 +A2BB 2492 +A2BC 2493 +A2BD 2494 +A2BE 2495 +A2BF 2496 +A2C0 2497 +A2C1 2498 +A2C2 2499 +A2C3 249A +A2C4 249B +81378D36 249C +81378D37 249D +81378D38 249E +81378D39 249F +81378E30 24A0 +81378E31 24A1 +81378E32 24A2 +81378E33 24A3 +81378E34 24A4 +81378E35 24A5 +81378E36 24A6 +81378E37 24A7 +81378E38 24A8 +81378E39 24A9 +81378F30 24AA +81378F31 24AB +81378F32 24AC +81378F33 24AD +81378F34 24AE +81378F35 24AF +81378F36 24B0 +81378F37 24B1 +81378F38 24B2 +81378F39 24B3 +81379030 24B4 +81379031 24B5 +81379032 24B6 +81379033 24B7 +81379034 24B8 +81379035 24B9 +81379036 24BA +81379037 24BB +81379038 24BC +81379039 24BD +81379130 24BE +81379131 24BF +81379132 24C0 +81379133 24C1 +81379134 24C2 +81379135 24C3 +81379136 24C4 +81379137 24C5 +81379138 24C6 +81379139 24C7 +81379230 24C8 +81379231 24C9 +81379232 24CA +81379233 24CB +81379234 24CC +81379235 24CD +81379236 24CE +81379237 24CF +81379238 24D0 +81379239 24D1 +81379330 24D2 +81379331 24D3 +81379332 24D4 +81379333 24D5 +81379334 24D6 +81379335 24D7 +81379336 24D8 +81379337 24D9 +81379338 24DA +81379339 24DB +81379430 24DC +81379431 24DD +81379432 24DE +81379433 24DF +81379434 24E0 +81379435 24E1 +81379436 24E2 +81379437 24E3 +81379438 24E4 +81379439 24E5 +81379530 24E6 +81379531 24E7 +81379532 24E8 +81379533 24E9 +81379534 24EA +81379535 24EB +81379536 24EC +81379537 24ED +81379538 24EE +81379539 24EF +81379630 24F0 +81379631 24F1 +81379632 24F2 +81379633 24F3 +81379634 24F4 +81379635 24F5 +81379636 24F6 +81379637 24F7 +81379638 24F8 +81379639 24F9 +81379730 24FA +81379731 24FB +81379732 24FC +81379733 24FD +81379734 24FE +81379735 24FF +A9A4 2500 +A9A5 2501 +A9A6 2502 +A9A7 2503 +A9A8 2504 +A9A9 2505 +A9AA 2506 +A9AB 2507 +A9AC 2508 +A9AD 2509 +A9AE 250A +A9AF 250B +A9B0 250C +A9B1 250D +A9B2 250E +A9B3 250F +A9B4 2510 +A9B5 2511 +A9B6 2512 +A9B7 2513 +A9B8 2514 +A9B9 2515 +A9BA 2516 +A9BB 2517 +A9BC 2518 +A9BD 2519 +A9BE 251A +A9BF 251B +A9C0 251C +A9C1 251D +A9C2 251E +A9C3 251F +A9C4 2520 +A9C5 2521 +A9C6 2522 +A9C7 2523 +A9C8 2524 +A9C9 2525 +A9CA 2526 +A9CB 2527 +A9CC 2528 +A9CD 2529 +A9CE 252A +A9CF 252B +A9D0 252C +A9D1 252D +A9D2 252E +A9D3 252F +A9D4 2530 +A9D5 2531 +A9D6 2532 +A9D7 2533 +A9D8 2534 +A9D9 2535 +A9DA 2536 +A9DB 2537 +A9DC 2538 +A9DD 2539 +A9DE 253A +A9DF 253B +A9E0 253C +A9E1 253D +A9E2 253E +A9E3 253F +A9E4 2540 +A9E5 2541 +A9E6 2542 +A9E7 2543 +A9E8 2544 +A9E9 2545 +A9EA 2546 +A9EB 2547 +A9EC 2548 +A9ED 2549 +A9EE 254A +A9EF 254B +81379736 254C +81379737 254D +81379738 254E +81379739 254F +A854 2550 +A855 2551 +A856 2552 +A857 2553 +A858 2554 +A859 2555 +A85A 2556 +A85B 2557 +A85C 2558 +A85D 2559 +A85E 255A +A85F 255B +A860 255C +A861 255D +A862 255E +A863 255F +A864 2560 +A865 2561 +A866 2562 +A867 2563 +A868 2564 +A869 2565 +A86A 2566 +A86B 2567 +A86C 2568 +A86D 2569 +A86E 256A +A86F 256B +A870 256C +A871 256D +A872 256E +A873 256F +A874 2570 +A875 2571 +A876 2572 +A877 2573 +81379830 2574 +81379831 2575 +81379832 2576 +81379833 2577 +81379834 2578 +81379835 2579 +81379836 257A +81379837 257B +81379838 257C +81379839 257D +81379930 257E +81379931 257F +81379932 2580 +A878 2581 +A879 2582 +A87A 2583 +A87B 2584 +A87C 2585 +A87D 2586 +A87E 2587 +A880 2588 +A881 2589 +A882 258A +A883 258B +A884 258C +A885 258D +A886 258E +A887 258F +81379933 2590 +81379934 2591 +81379935 2592 +A888 2593 +A889 2594 +A88A 2595 +81379936 2596 +81379937 2597 +81379938 2598 +81379939 2599 +81379A30 259A +81379A31 259B +81379A32 259C +81379A33 259D +81379A34 259E +81379A35 259F +A1F6 25A0 +A1F5 25A1 +81379A36 25A2 +81379A37 25A3 +81379A38 25A4 +81379A39 25A5 +81379B30 25A6 +81379B31 25A7 +81379B32 25A8 +81379B33 25A9 +81379B34 25AA +81379B35 25AB +81379B36 25AC +81379B37 25AD +81379B38 25AE +81379B39 25AF +81379C30 25B0 +81379C31 25B1 +A1F8 25B2 +A1F7 25B3 +81379C32 25B4 +81379C33 25B5 +81379C34 25B6 +81379C35 25B7 +81379C36 25B8 +81379C37 25B9 +81379C38 25BA +81379C39 25BB +A88B 25BC +A88C 25BD +81379D30 25BE +81379D31 25BF +81379D32 25C0 +81379D33 25C1 +81379D34 25C2 +81379D35 25C3 +81379D36 25C4 +81379D37 25C5 +A1F4 25C6 +A1F3 25C7 +81379D38 25C8 +81379D39 25C9 +81379E30 25CA +A1F0 25CB +81379E31 25CC +81379E32 25CD +A1F2 25CE +A1F1 25CF +81379E33 25D0 +81379E34 25D1 +81379E35 25D2 +81379E36 25D3 +81379E37 25D4 +81379E38 25D5 +81379E39 25D6 +81379F30 25D7 +81379F31 25D8 +81379F32 25D9 +81379F33 25DA +81379F34 25DB +81379F35 25DC +81379F36 25DD +81379F37 25DE +81379F38 25DF +81379F39 25E0 +8137A030 25E1 +A88D 25E2 +A88E 25E3 +A88F 25E4 +A890 25E5 +8137A031 25E6 +8137A032 25E7 +8137A033 25E8 +8137A034 25E9 +8137A035 25EA +8137A036 25EB +8137A037 25EC +8137A038 25ED +8137A039 25EE +8137A130 25EF +8137A131 25F0 +8137A132 25F1 +8137A133 25F2 +8137A134 25F3 +8137A135 25F4 +8137A136 25F5 +8137A137 25F6 +8137A138 25F7 +8137A139 25F8 +8137A230 25F9 +8137A231 25FA +8137A232 25FB +8137A233 25FC +8137A234 25FD +8137A235 25FE +8137A236 25FF +8137A237 2600 +8137A238 2601 +8137A239 2602 +8137A330 2603 +8137A331 2604 +A1EF 2605 +A1EE 2606 +8137A332 2607 +8137A333 2608 +A891 2609 +8137A334 260A +8137A335 260B +8137A336 260C +8137A337 260D +8137A338 260E +8137A339 260F +8137A430 2610 +8137A431 2611 +8137A432 2612 +8137A433 2613 +8137A434 2614 +8137A435 2615 +8137A436 2616 +8137A437 2617 +8137A438 2618 +8137A439 2619 +8137A530 261A +8137A531 261B +8137A532 261C +8137A533 261D +8137A534 261E +8137A535 261F +8137A536 2620 +8137A537 2621 +8137A538 2622 +8137A539 2623 +8137A630 2624 +8137A631 2625 +8137A632 2626 +8137A633 2627 +8137A634 2628 +8137A635 2629 +8137A636 262A +8137A637 262B +8137A638 262C +8137A639 262D +8137A730 262E +8137A731 262F +8137A732 2630 +8137A733 2631 +8137A734 2632 +8137A735 2633 +8137A736 2634 +8137A737 2635 +8137A738 2636 +8137A739 2637 +8137A830 2638 +8137A831 2639 +8137A832 263A +8137A833 263B +8137A834 263C +8137A835 263D +8137A836 263E +8137A837 263F +A1E2 2640 +8137A838 2641 +A1E1 2642 +8137A839 2643 +8137A930 2644 +8137A931 2645 +8137A932 2646 +8137A933 2647 +8137A934 2648 +8137A935 2649 +8137A936 264A +8137A937 264B +8137A938 264C +8137A939 264D +8137AA30 264E +8137AA31 264F +8137AA32 2650 +8137AA33 2651 +8137AA34 2652 +8137AA35 2653 +8137AA36 2654 +8137AA37 2655 +8137AA38 2656 +8137AA39 2657 +8137AB30 2658 +8137AB31 2659 +8137AB32 265A +8137AB33 265B +8137AB34 265C +8137AB35 265D +8137AB36 265E +8137AB37 265F +8137AB38 2660 +8137AB39 2661 +8137AC30 2662 +8137AC31 2663 +8137AC32 2664 +8137AC33 2665 +8137AC34 2666 +8137AC35 2667 +8137AC36 2668 +8137AC37 2669 +8137AC38 266A +8137AC39 266B +8137AD30 266C +8137AD31 266D +8137AD32 266E +8137AD33 266F +8137AD34 2670 +8137AD35 2671 +8137AD36 2672 +8137AD37 2673 +8137AD38 2674 +8137AD39 2675 +8137AE30 2676 +8137AE31 2677 +8137AE32 2678 +8137AE33 2679 +8137AE34 267A +8137AE35 267B +8137AE36 267C +8137AE37 267D +8137AE38 267E +8137AE39 267F +8137AF30 2680 +8137AF31 2681 +8137AF32 2682 +8137AF33 2683 +8137AF34 2684 +8137AF35 2685 +8137AF36 2686 +8137AF37 2687 +8137AF38 2688 +8137AF39 2689 +8137B030 268A +8137B031 268B +8137B032 268C +8137B033 268D +8137B034 268E +8137B035 268F +8137B036 2690 +8137B037 2691 +8137B038 2692 +8137B039 2693 +8137B130 2694 +8137B131 2695 +8137B132 2696 +8137B133 2697 +8137B134 2698 +8137B135 2699 +8137B136 269A +8137B137 269B +8137B138 269C +8137B139 269D +8137B230 269E +8137B231 269F +8137B232 26A0 +8137B233 26A1 +8137B234 26A2 +8137B235 26A3 +8137B236 26A4 +8137B237 26A5 +8137B238 26A6 +8137B239 26A7 +8137B330 26A8 +8137B331 26A9 +8137B332 26AA +8137B333 26AB +8137B334 26AC +8137B335 26AD +8137B336 26AE +8137B337 26AF +8137B338 26B0 +8137B339 26B1 +8137B430 26B2 +8137B431 26B3 +8137B432 26B4 +8137B433 26B5 +8137B434 26B6 +8137B435 26B7 +8137B436 26B8 +8137B437 26B9 +8137B438 26BA +8137B439 26BB +8137B530 26BC +8137B531 26BD +8137B532 26BE +8137B533 26BF +8137B534 26C0 +8137B535 26C1 +8137B536 26C2 +8137B537 26C3 +8137B538 26C4 +8137B539 26C5 +8137B630 26C6 +8137B631 26C7 +8137B632 26C8 +8137B633 26C9 +8137B634 26CA +8137B635 26CB +8137B636 26CC +8137B637 26CD +8137B638 26CE +8137B639 26CF +8137B730 26D0 +8137B731 26D1 +8137B732 26D2 +8137B733 26D3 +8137B734 26D4 +8137B735 26D5 +8137B736 26D6 +8137B737 26D7 +8137B738 26D8 +8137B739 26D9 +8137B830 26DA +8137B831 26DB +8137B832 26DC +8137B833 26DD +8137B834 26DE +8137B835 26DF +8137B836 26E0 +8137B837 26E1 +8137B838 26E2 +8137B839 26E3 +8137B930 26E4 +8137B931 26E5 +8137B932 26E6 +8137B933 26E7 +8137B934 26E8 +8137B935 26E9 +8137B936 26EA +8137B937 26EB +8137B938 26EC +8137B939 26ED +8137BA30 26EE +8137BA31 26EF +8137BA32 26F0 +8137BA33 26F1 +8137BA34 26F2 +8137BA35 26F3 +8137BA36 26F4 +8137BA37 26F5 +8137BA38 26F6 +8137BA39 26F7 +8137BB30 26F8 +8137BB31 26F9 +8137BB32 26FA +8137BB33 26FB +8137BB34 26FC +8137BB35 26FD +8137BB36 26FE +8137BB37 26FF +8137BB38 2700 +8137BB39 2701 +8137BC30 2702 +8137BC31 2703 +8137BC32 2704 +8137BC33 2705 +8137BC34 2706 +8137BC35 2707 +8137BC36 2708 +8137BC37 2709 +8137BC38 270A +8137BC39 270B +8137BD30 270C +8137BD31 270D +8137BD32 270E +8137BD33 270F +8137BD34 2710 +8137BD35 2711 +8137BD36 2712 +8137BD37 2713 +8137BD38 2714 +8137BD39 2715 +8137BE30 2716 +8137BE31 2717 +8137BE32 2718 +8137BE33 2719 +8137BE34 271A +8137BE35 271B +8137BE36 271C +8137BE37 271D +8137BE38 271E +8137BE39 271F +8137BF30 2720 +8137BF31 2721 +8137BF32 2722 +8137BF33 2723 +8137BF34 2724 +8137BF35 2725 +8137BF36 2726 +8137BF37 2727 +8137BF38 2728 +8137BF39 2729 +8137C030 272A +8137C031 272B +8137C032 272C +8137C033 272D +8137C034 272E +8137C035 272F +8137C036 2730 +8137C037 2731 +8137C038 2732 +8137C039 2733 +8137C130 2734 +8137C131 2735 +8137C132 2736 +8137C133 2737 +8137C134 2738 +8137C135 2739 +8137C136 273A +8137C137 273B +8137C138 273C +8137C139 273D +8137C230 273E +8137C231 273F +8137C232 2740 +8137C233 2741 +8137C234 2742 +8137C235 2743 +8137C236 2744 +8137C237 2745 +8137C238 2746 +8137C239 2747 +8137C330 2748 +8137C331 2749 +8137C332 274A +8137C333 274B +8137C334 274C +8137C335 274D +8137C336 274E +8137C337 274F +8137C338 2750 +8137C339 2751 +8137C430 2752 +8137C431 2753 +8137C432 2754 +8137C433 2755 +8137C434 2756 +8137C435 2757 +8137C436 2758 +8137C437 2759 +8137C438 275A +8137C439 275B +8137C530 275C +8137C531 275D +8137C532 275E +8137C533 275F +8137C534 2760 +8137C535 2761 +8137C536 2762 +8137C537 2763 +8137C538 2764 +8137C539 2765 +8137C630 2766 +8137C631 2767 +8137C632 2768 +8137C633 2769 +8137C634 276A +8137C635 276B +8137C636 276C +8137C637 276D +8137C638 276E +8137C639 276F +8137C730 2770 +8137C731 2771 +8137C732 2772 +8137C733 2773 +8137C734 2774 +8137C735 2775 +8137C736 2776 +8137C737 2777 +8137C738 2778 +8137C739 2779 +8137C830 277A +8137C831 277B +8137C832 277C +8137C833 277D +8137C834 277E +8137C835 277F +8137C836 2780 +8137C837 2781 +8137C838 2782 +8137C839 2783 +8137C930 2784 +8137C931 2785 +8137C932 2786 +8137C933 2787 +8137C934 2788 +8137C935 2789 +8137C936 278A +8137C937 278B +8137C938 278C +8137C939 278D +8137CA30 278E +8137CA31 278F +8137CA32 2790 +8137CA33 2791 +8137CA34 2792 +8137CA35 2793 +8137CA36 2794 +8137CA37 2795 +8137CA38 2796 +8137CA39 2797 +8137CB30 2798 +8137CB31 2799 +8137CB32 279A +8137CB33 279B +8137CB34 279C +8137CB35 279D +8137CB36 279E +8137CB37 279F +8137CB38 27A0 +8137CB39 27A1 +8137CC30 27A2 +8137CC31 27A3 +8137CC32 27A4 +8137CC33 27A5 +8137CC34 27A6 +8137CC35 27A7 +8137CC36 27A8 +8137CC37 27A9 +8137CC38 27AA +8137CC39 27AB +8137CD30 27AC +8137CD31 27AD +8137CD32 27AE +8137CD33 27AF +8137CD34 27B0 +8137CD35 27B1 +8137CD36 27B2 +8137CD37 27B3 +8137CD38 27B4 +8137CD39 27B5 +8137CE30 27B6 +8137CE31 27B7 +8137CE32 27B8 +8137CE33 27B9 +8137CE34 27BA +8137CE35 27BB +8137CE36 27BC +8137CE37 27BD +8137CE38 27BE +8137CE39 27BF +8137CF30 27C0 +8137CF31 27C1 +8137CF32 27C2 +8137CF33 27C3 +8137CF34 27C4 +8137CF35 27C5 +8137CF36 27C6 +8137CF37 27C7 +8137CF38 27C8 +8137CF39 27C9 +8137D030 27CA +8137D031 27CB +8137D032 27CC +8137D033 27CD +8137D034 27CE +8137D035 27CF +8137D036 27D0 +8137D037 27D1 +8137D038 27D2 +8137D039 27D3 +8137D130 27D4 +8137D131 27D5 +8137D132 27D6 +8137D133 27D7 +8137D134 27D8 +8137D135 27D9 +8137D136 27DA +8137D137 27DB +8137D138 27DC +8137D139 27DD +8137D230 27DE +8137D231 27DF +8137D232 27E0 +8137D233 27E1 +8137D234 27E2 +8137D235 27E3 +8137D236 27E4 +8137D237 27E5 +8137D238 27E6 +8137D239 27E7 +8137D330 27E8 +8137D331 27E9 +8137D332 27EA +8137D333 27EB +8137D334 27EC +8137D335 27ED +8137D336 27EE +8137D337 27EF +8137D338 27F0 +8137D339 27F1 +8137D430 27F2 +8137D431 27F3 +8137D432 27F4 +8137D433 27F5 +8137D434 27F6 +8137D435 27F7 +8137D436 27F8 +8137D437 27F9 +8137D438 27FA +8137D439 27FB +8137D530 27FC +8137D531 27FD +8137D532 27FE +8137D533 27FF +8137D534 2800 +8137D535 2801 +8137D536 2802 +8137D537 2803 +8137D538 2804 +8137D539 2805 +8137D630 2806 +8137D631 2807 +8137D632 2808 +8137D633 2809 +8137D634 280A +8137D635 280B +8137D636 280C +8137D637 280D +8137D638 280E +8137D639 280F +8137D730 2810 +8137D731 2811 +8137D732 2812 +8137D733 2813 +8137D734 2814 +8137D735 2815 +8137D736 2816 +8137D737 2817 +8137D738 2818 +8137D739 2819 +8137D830 281A +8137D831 281B +8137D832 281C +8137D833 281D +8137D834 281E +8137D835 281F +8137D836 2820 +8137D837 2821 +8137D838 2822 +8137D839 2823 +8137D930 2824 +8137D931 2825 +8137D932 2826 +8137D933 2827 +8137D934 2828 +8137D935 2829 +8137D936 282A +8137D937 282B +8137D938 282C +8137D939 282D +8137DA30 282E +8137DA31 282F +8137DA32 2830 +8137DA33 2831 +8137DA34 2832 +8137DA35 2833 +8137DA36 2834 +8137DA37 2835 +8137DA38 2836 +8137DA39 2837 +8137DB30 2838 +8137DB31 2839 +8137DB32 283A +8137DB33 283B +8137DB34 283C +8137DB35 283D +8137DB36 283E +8137DB37 283F +8137DB38 2840 +8137DB39 2841 +8137DC30 2842 +8137DC31 2843 +8137DC32 2844 +8137DC33 2845 +8137DC34 2846 +8137DC35 2847 +8137DC36 2848 +8137DC37 2849 +8137DC38 284A +8137DC39 284B +8137DD30 284C +8137DD31 284D +8137DD32 284E +8137DD33 284F +8137DD34 2850 +8137DD35 2851 +8137DD36 2852 +8137DD37 2853 +8137DD38 2854 +8137DD39 2855 +8137DE30 2856 +8137DE31 2857 +8137DE32 2858 +8137DE33 2859 +8137DE34 285A +8137DE35 285B +8137DE36 285C +8137DE37 285D +8137DE38 285E +8137DE39 285F +8137DF30 2860 +8137DF31 2861 +8137DF32 2862 +8137DF33 2863 +8137DF34 2864 +8137DF35 2865 +8137DF36 2866 +8137DF37 2867 +8137DF38 2868 +8137DF39 2869 +8137E030 286A +8137E031 286B +8137E032 286C +8137E033 286D +8137E034 286E +8137E035 286F +8137E036 2870 +8137E037 2871 +8137E038 2872 +8137E039 2873 +8137E130 2874 +8137E131 2875 +8137E132 2876 +8137E133 2877 +8137E134 2878 +8137E135 2879 +8137E136 287A +8137E137 287B +8137E138 287C +8137E139 287D +8137E230 287E +8137E231 287F +8137E232 2880 +8137E233 2881 +8137E234 2882 +8137E235 2883 +8137E236 2884 +8137E237 2885 +8137E238 2886 +8137E239 2887 +8137E330 2888 +8137E331 2889 +8137E332 288A +8137E333 288B +8137E334 288C +8137E335 288D +8137E336 288E +8137E337 288F +8137E338 2890 +8137E339 2891 +8137E430 2892 +8137E431 2893 +8137E432 2894 +8137E433 2895 +8137E434 2896 +8137E435 2897 +8137E436 2898 +8137E437 2899 +8137E438 289A +8137E439 289B +8137E530 289C +8137E531 289D +8137E532 289E +8137E533 289F +8137E534 28A0 +8137E535 28A1 +8137E536 28A2 +8137E537 28A3 +8137E538 28A4 +8137E539 28A5 +8137E630 28A6 +8137E631 28A7 +8137E632 28A8 +8137E633 28A9 +8137E634 28AA +8137E635 28AB +8137E636 28AC +8137E637 28AD +8137E638 28AE +8137E639 28AF +8137E730 28B0 +8137E731 28B1 +8137E732 28B2 +8137E733 28B3 +8137E734 28B4 +8137E735 28B5 +8137E736 28B6 +8137E737 28B7 +8137E738 28B8 +8137E739 28B9 +8137E830 28BA +8137E831 28BB +8137E832 28BC +8137E833 28BD +8137E834 28BE +8137E835 28BF +8137E836 28C0 +8137E837 28C1 +8137E838 28C2 +8137E839 28C3 +8137E930 28C4 +8137E931 28C5 +8137E932 28C6 +8137E933 28C7 +8137E934 28C8 +8137E935 28C9 +8137E936 28CA +8137E937 28CB +8137E938 28CC +8137E939 28CD +8137EA30 28CE +8137EA31 28CF +8137EA32 28D0 +8137EA33 28D1 +8137EA34 28D2 +8137EA35 28D3 +8137EA36 28D4 +8137EA37 28D5 +8137EA38 28D6 +8137EA39 28D7 +8137EB30 28D8 +8137EB31 28D9 +8137EB32 28DA +8137EB33 28DB +8137EB34 28DC +8137EB35 28DD +8137EB36 28DE +8137EB37 28DF +8137EB38 28E0 +8137EB39 28E1 +8137EC30 28E2 +8137EC31 28E3 +8137EC32 28E4 +8137EC33 28E5 +8137EC34 28E6 +8137EC35 28E7 +8137EC36 28E8 +8137EC37 28E9 +8137EC38 28EA +8137EC39 28EB +8137ED30 28EC +8137ED31 28ED +8137ED32 28EE +8137ED33 28EF +8137ED34 28F0 +8137ED35 28F1 +8137ED36 28F2 +8137ED37 28F3 +8137ED38 28F4 +8137ED39 28F5 +8137EE30 28F6 +8137EE31 28F7 +8137EE32 28F8 +8137EE33 28F9 +8137EE34 28FA +8137EE35 28FB +8137EE36 28FC +8137EE37 28FD +8137EE38 28FE +8137EE39 28FF +8137EF30 2900 +8137EF31 2901 +8137EF32 2902 +8137EF33 2903 +8137EF34 2904 +8137EF35 2905 +8137EF36 2906 +8137EF37 2907 +8137EF38 2908 +8137EF39 2909 +8137F030 290A +8137F031 290B +8137F032 290C +8137F033 290D +8137F034 290E +8137F035 290F +8137F036 2910 +8137F037 2911 +8137F038 2912 +8137F039 2913 +8137F130 2914 +8137F131 2915 +8137F132 2916 +8137F133 2917 +8137F134 2918 +8137F135 2919 +8137F136 291A +8137F137 291B +8137F138 291C +8137F139 291D +8137F230 291E +8137F231 291F +8137F232 2920 +8137F233 2921 +8137F234 2922 +8137F235 2923 +8137F236 2924 +8137F237 2925 +8137F238 2926 +8137F239 2927 +8137F330 2928 +8137F331 2929 +8137F332 292A +8137F333 292B +8137F334 292C +8137F335 292D +8137F336 292E +8137F337 292F +8137F338 2930 +8137F339 2931 +8137F430 2932 +8137F431 2933 +8137F432 2934 +8137F433 2935 +8137F434 2936 +8137F435 2937 +8137F436 2938 +8137F437 2939 +8137F438 293A +8137F439 293B +8137F530 293C +8137F531 293D +8137F532 293E +8137F533 293F +8137F534 2940 +8137F535 2941 +8137F536 2942 +8137F537 2943 +8137F538 2944 +8137F539 2945 +8137F630 2946 +8137F631 2947 +8137F632 2948 +8137F633 2949 +8137F634 294A +8137F635 294B +8137F636 294C +8137F637 294D +8137F638 294E +8137F639 294F +8137F730 2950 +8137F731 2951 +8137F732 2952 +8137F733 2953 +8137F734 2954 +8137F735 2955 +8137F736 2956 +8137F737 2957 +8137F738 2958 +8137F739 2959 +8137F830 295A +8137F831 295B +8137F832 295C +8137F833 295D +8137F834 295E +8137F835 295F +8137F836 2960 +8137F837 2961 +8137F838 2962 +8137F839 2963 +8137F930 2964 +8137F931 2965 +8137F932 2966 +8137F933 2967 +8137F934 2968 +8137F935 2969 +8137F936 296A +8137F937 296B +8137F938 296C +8137F939 296D +8137FA30 296E +8137FA31 296F +8137FA32 2970 +8137FA33 2971 +8137FA34 2972 +8137FA35 2973 +8137FA36 2974 +8137FA37 2975 +8137FA38 2976 +8137FA39 2977 +8137FB30 2978 +8137FB31 2979 +8137FB32 297A +8137FB33 297B +8137FB34 297C +8137FB35 297D +8137FB36 297E +8137FB37 297F +8137FB38 2980 +8137FB39 2981 +8137FC30 2982 +8137FC31 2983 +8137FC32 2984 +8137FC33 2985 +8137FC34 2986 +8137FC35 2987 +8137FC36 2988 +8137FC37 2989 +8137FC38 298A +8137FC39 298B +8137FD30 298C +8137FD31 298D +8137FD32 298E +8137FD33 298F +8137FD34 2990 +8137FD35 2991 +8137FD36 2992 +8137FD37 2993 +8137FD38 2994 +8137FD39 2995 +8137FE30 2996 +8137FE31 2997 +8137FE32 2998 +8137FE33 2999 +8137FE34 299A +8137FE35 299B +8137FE36 299C +8137FE37 299D +8137FE38 299E +8137FE39 299F +81388130 29A0 +81388131 29A1 +81388132 29A2 +81388133 29A3 +81388134 29A4 +81388135 29A5 +81388136 29A6 +81388137 29A7 +81388138 29A8 +81388139 29A9 +81388230 29AA +81388231 29AB +81388232 29AC +81388233 29AD +81388234 29AE +81388235 29AF +81388236 29B0 +81388237 29B1 +81388238 29B2 +81388239 29B3 +81388330 29B4 +81388331 29B5 +81388332 29B6 +81388333 29B7 +81388334 29B8 +81388335 29B9 +81388336 29BA +81388337 29BB +81388338 29BC +81388339 29BD +81388430 29BE +81388431 29BF +81388432 29C0 +81388433 29C1 +81388434 29C2 +81388435 29C3 +81388436 29C4 +81388437 29C5 +81388438 29C6 +81388439 29C7 +81388530 29C8 +81388531 29C9 +81388532 29CA +81388533 29CB +81388534 29CC +81388535 29CD +81388536 29CE +81388537 29CF +81388538 29D0 +81388539 29D1 +81388630 29D2 +81388631 29D3 +81388632 29D4 +81388633 29D5 +81388634 29D6 +81388635 29D7 +81388636 29D8 +81388637 29D9 +81388638 29DA +81388639 29DB +81388730 29DC +81388731 29DD +81388732 29DE +81388733 29DF +81388734 29E0 +81388735 29E1 +81388736 29E2 +81388737 29E3 +81388738 29E4 +81388739 29E5 +81388830 29E6 +81388831 29E7 +81388832 29E8 +81388833 29E9 +81388834 29EA +81388835 29EB +81388836 29EC +81388837 29ED +81388838 29EE +81388839 29EF +81388930 29F0 +81388931 29F1 +81388932 29F2 +81388933 29F3 +81388934 29F4 +81388935 29F5 +81388936 29F6 +81388937 29F7 +81388938 29F8 +81388939 29F9 +81388A30 29FA +81388A31 29FB +81388A32 29FC +81388A33 29FD +81388A34 29FE +81388A35 29FF +81388A36 2A00 +81388A37 2A01 +81388A38 2A02 +81388A39 2A03 +81388B30 2A04 +81388B31 2A05 +81388B32 2A06 +81388B33 2A07 +81388B34 2A08 +81388B35 2A09 +81388B36 2A0A +81388B37 2A0B +81388B38 2A0C +81388B39 2A0D +81388C30 2A0E +81388C31 2A0F +81388C32 2A10 +81388C33 2A11 +81388C34 2A12 +81388C35 2A13 +81388C36 2A14 +81388C37 2A15 +81388C38 2A16 +81388C39 2A17 +81388D30 2A18 +81388D31 2A19 +81388D32 2A1A +81388D33 2A1B +81388D34 2A1C +81388D35 2A1D +81388D36 2A1E +81388D37 2A1F +81388D38 2A20 +81388D39 2A21 +81388E30 2A22 +81388E31 2A23 +81388E32 2A24 +81388E33 2A25 +81388E34 2A26 +81388E35 2A27 +81388E36 2A28 +81388E37 2A29 +81388E38 2A2A +81388E39 2A2B +81388F30 2A2C +81388F31 2A2D +81388F32 2A2E +81388F33 2A2F +81388F34 2A30 +81388F35 2A31 +81388F36 2A32 +81388F37 2A33 +81388F38 2A34 +81388F39 2A35 +81389030 2A36 +81389031 2A37 +81389032 2A38 +81389033 2A39 +81389034 2A3A +81389035 2A3B +81389036 2A3C +81389037 2A3D +81389038 2A3E +81389039 2A3F +81389130 2A40 +81389131 2A41 +81389132 2A42 +81389133 2A43 +81389134 2A44 +81389135 2A45 +81389136 2A46 +81389137 2A47 +81389138 2A48 +81389139 2A49 +81389230 2A4A +81389231 2A4B +81389232 2A4C +81389233 2A4D +81389234 2A4E +81389235 2A4F +81389236 2A50 +81389237 2A51 +81389238 2A52 +81389239 2A53 +81389330 2A54 +81389331 2A55 +81389332 2A56 +81389333 2A57 +81389334 2A58 +81389335 2A59 +81389336 2A5A +81389337 2A5B +81389338 2A5C +81389339 2A5D +81389430 2A5E +81389431 2A5F +81389432 2A60 +81389433 2A61 +81389434 2A62 +81389435 2A63 +81389436 2A64 +81389437 2A65 +81389438 2A66 +81389439 2A67 +81389530 2A68 +81389531 2A69 +81389532 2A6A +81389533 2A6B +81389534 2A6C +81389535 2A6D +81389536 2A6E +81389537 2A6F +81389538 2A70 +81389539 2A71 +81389630 2A72 +81389631 2A73 +81389632 2A74 +81389633 2A75 +81389634 2A76 +81389635 2A77 +81389636 2A78 +81389637 2A79 +81389638 2A7A +81389639 2A7B +81389730 2A7C +81389731 2A7D +81389732 2A7E +81389733 2A7F +81389734 2A80 +81389735 2A81 +81389736 2A82 +81389737 2A83 +81389738 2A84 +81389739 2A85 +81389830 2A86 +81389831 2A87 +81389832 2A88 +81389833 2A89 +81389834 2A8A +81389835 2A8B +81389836 2A8C +81389837 2A8D +81389838 2A8E +81389839 2A8F +81389930 2A90 +81389931 2A91 +81389932 2A92 +81389933 2A93 +81389934 2A94 +81389935 2A95 +81389936 2A96 +81389937 2A97 +81389938 2A98 +81389939 2A99 +81389A30 2A9A +81389A31 2A9B +81389A32 2A9C +81389A33 2A9D +81389A34 2A9E +81389A35 2A9F +81389A36 2AA0 +81389A37 2AA1 +81389A38 2AA2 +81389A39 2AA3 +81389B30 2AA4 +81389B31 2AA5 +81389B32 2AA6 +81389B33 2AA7 +81389B34 2AA8 +81389B35 2AA9 +81389B36 2AAA +81389B37 2AAB +81389B38 2AAC +81389B39 2AAD +81389C30 2AAE +81389C31 2AAF +81389C32 2AB0 +81389C33 2AB1 +81389C34 2AB2 +81389C35 2AB3 +81389C36 2AB4 +81389C37 2AB5 +81389C38 2AB6 +81389C39 2AB7 +81389D30 2AB8 +81389D31 2AB9 +81389D32 2ABA +81389D33 2ABB +81389D34 2ABC +81389D35 2ABD +81389D36 2ABE +81389D37 2ABF +81389D38 2AC0 +81389D39 2AC1 +81389E30 2AC2 +81389E31 2AC3 +81389E32 2AC4 +81389E33 2AC5 +81389E34 2AC6 +81389E35 2AC7 +81389E36 2AC8 +81389E37 2AC9 +81389E38 2ACA +81389E39 2ACB +81389F30 2ACC +81389F31 2ACD +81389F32 2ACE +81389F33 2ACF +81389F34 2AD0 +81389F35 2AD1 +81389F36 2AD2 +81389F37 2AD3 +81389F38 2AD4 +81389F39 2AD5 +8138A030 2AD6 +8138A031 2AD7 +8138A032 2AD8 +8138A033 2AD9 +8138A034 2ADA +8138A035 2ADB +8138A036 2ADC +8138A037 2ADD +8138A038 2ADE +8138A039 2ADF +8138A130 2AE0 +8138A131 2AE1 +8138A132 2AE2 +8138A133 2AE3 +8138A134 2AE4 +8138A135 2AE5 +8138A136 2AE6 +8138A137 2AE7 +8138A138 2AE8 +8138A139 2AE9 +8138A230 2AEA +8138A231 2AEB +8138A232 2AEC +8138A233 2AED +8138A234 2AEE +8138A235 2AEF +8138A236 2AF0 +8138A237 2AF1 +8138A238 2AF2 +8138A239 2AF3 +8138A330 2AF4 +8138A331 2AF5 +8138A332 2AF6 +8138A333 2AF7 +8138A334 2AF8 +8138A335 2AF9 +8138A336 2AFA +8138A337 2AFB +8138A338 2AFC +8138A339 2AFD +8138A430 2AFE +8138A431 2AFF +8138A432 2B00 +8138A433 2B01 +8138A434 2B02 +8138A435 2B03 +8138A436 2B04 +8138A437 2B05 +8138A438 2B06 +8138A439 2B07 +8138A530 2B08 +8138A531 2B09 +8138A532 2B0A +8138A533 2B0B +8138A534 2B0C +8138A535 2B0D +8138A536 2B0E +8138A537 2B0F +8138A538 2B10 +8138A539 2B11 +8138A630 2B12 +8138A631 2B13 +8138A632 2B14 +8138A633 2B15 +8138A634 2B16 +8138A635 2B17 +8138A636 2B18 +8138A637 2B19 +8138A638 2B1A +8138A639 2B1B +8138A730 2B1C +8138A731 2B1D +8138A732 2B1E +8138A733 2B1F +8138A734 2B20 +8138A735 2B21 +8138A736 2B22 +8138A737 2B23 +8138A738 2B24 +8138A739 2B25 +8138A830 2B26 +8138A831 2B27 +8138A832 2B28 +8138A833 2B29 +8138A834 2B2A +8138A835 2B2B +8138A836 2B2C +8138A837 2B2D +8138A838 2B2E +8138A839 2B2F +8138A930 2B30 +8138A931 2B31 +8138A932 2B32 +8138A933 2B33 +8138A934 2B34 +8138A935 2B35 +8138A936 2B36 +8138A937 2B37 +8138A938 2B38 +8138A939 2B39 +8138AA30 2B3A +8138AA31 2B3B +8138AA32 2B3C +8138AA33 2B3D +8138AA34 2B3E +8138AA35 2B3F +8138AA36 2B40 +8138AA37 2B41 +8138AA38 2B42 +8138AA39 2B43 +8138AB30 2B44 +8138AB31 2B45 +8138AB32 2B46 +8138AB33 2B47 +8138AB34 2B48 +8138AB35 2B49 +8138AB36 2B4A +8138AB37 2B4B +8138AB38 2B4C +8138AB39 2B4D +8138AC30 2B4E +8138AC31 2B4F +8138AC32 2B50 +8138AC33 2B51 +8138AC34 2B52 +8138AC35 2B53 +8138AC36 2B54 +8138AC37 2B55 +8138AC38 2B56 +8138AC39 2B57 +8138AD30 2B58 +8138AD31 2B59 +8138AD32 2B5A +8138AD33 2B5B +8138AD34 2B5C +8138AD35 2B5D +8138AD36 2B5E +8138AD37 2B5F +8138AD38 2B60 +8138AD39 2B61 +8138AE30 2B62 +8138AE31 2B63 +8138AE32 2B64 +8138AE33 2B65 +8138AE34 2B66 +8138AE35 2B67 +8138AE36 2B68 +8138AE37 2B69 +8138AE38 2B6A +8138AE39 2B6B +8138AF30 2B6C +8138AF31 2B6D +8138AF32 2B6E +8138AF33 2B6F +8138AF34 2B70 +8138AF35 2B71 +8138AF36 2B72 +8138AF37 2B73 +8138AF38 2B74 +8138AF39 2B75 +8138B030 2B76 +8138B031 2B77 +8138B032 2B78 +8138B033 2B79 +8138B034 2B7A +8138B035 2B7B +8138B036 2B7C +8138B037 2B7D +8138B038 2B7E +8138B039 2B7F +8138B130 2B80 +8138B131 2B81 +8138B132 2B82 +8138B133 2B83 +8138B134 2B84 +8138B135 2B85 +8138B136 2B86 +8138B137 2B87 +8138B138 2B88 +8138B139 2B89 +8138B230 2B8A +8138B231 2B8B +8138B232 2B8C +8138B233 2B8D +8138B234 2B8E +8138B235 2B8F +8138B236 2B90 +8138B237 2B91 +8138B238 2B92 +8138B239 2B93 +8138B330 2B94 +8138B331 2B95 +8138B332 2B96 +8138B333 2B97 +8138B334 2B98 +8138B335 2B99 +8138B336 2B9A +8138B337 2B9B +8138B338 2B9C +8138B339 2B9D +8138B430 2B9E +8138B431 2B9F +8138B432 2BA0 +8138B433 2BA1 +8138B434 2BA2 +8138B435 2BA3 +8138B436 2BA4 +8138B437 2BA5 +8138B438 2BA6 +8138B439 2BA7 +8138B530 2BA8 +8138B531 2BA9 +8138B532 2BAA +8138B533 2BAB +8138B534 2BAC +8138B535 2BAD +8138B536 2BAE +8138B537 2BAF +8138B538 2BB0 +8138B539 2BB1 +8138B630 2BB2 +8138B631 2BB3 +8138B632 2BB4 +8138B633 2BB5 +8138B634 2BB6 +8138B635 2BB7 +8138B636 2BB8 +8138B637 2BB9 +8138B638 2BBA +8138B639 2BBB +8138B730 2BBC +8138B731 2BBD +8138B732 2BBE +8138B733 2BBF +8138B734 2BC0 +8138B735 2BC1 +8138B736 2BC2 +8138B737 2BC3 +8138B738 2BC4 +8138B739 2BC5 +8138B830 2BC6 +8138B831 2BC7 +8138B832 2BC8 +8138B833 2BC9 +8138B834 2BCA +8138B835 2BCB +8138B836 2BCC +8138B837 2BCD +8138B838 2BCE +8138B839 2BCF +8138B930 2BD0 +8138B931 2BD1 +8138B932 2BD2 +8138B933 2BD3 +8138B934 2BD4 +8138B935 2BD5 +8138B936 2BD6 +8138B937 2BD7 +8138B938 2BD8 +8138B939 2BD9 +8138BA30 2BDA +8138BA31 2BDB +8138BA32 2BDC +8138BA33 2BDD +8138BA34 2BDE +8138BA35 2BDF +8138BA36 2BE0 +8138BA37 2BE1 +8138BA38 2BE2 +8138BA39 2BE3 +8138BB30 2BE4 +8138BB31 2BE5 +8138BB32 2BE6 +8138BB33 2BE7 +8138BB34 2BE8 +8138BB35 2BE9 +8138BB36 2BEA +8138BB37 2BEB +8138BB38 2BEC +8138BB39 2BED +8138BC30 2BEE +8138BC31 2BEF +8138BC32 2BF0 +8138BC33 2BF1 +8138BC34 2BF2 +8138BC35 2BF3 +8138BC36 2BF4 +8138BC37 2BF5 +8138BC38 2BF6 +8138BC39 2BF7 +8138BD30 2BF8 +8138BD31 2BF9 +8138BD32 2BFA +8138BD33 2BFB +8138BD34 2BFC +8138BD35 2BFD +8138BD36 2BFE +8138BD37 2BFF +8138BD38 2C00 +8138BD39 2C01 +8138BE30 2C02 +8138BE31 2C03 +8138BE32 2C04 +8138BE33 2C05 +8138BE34 2C06 +8138BE35 2C07 +8138BE36 2C08 +8138BE37 2C09 +8138BE38 2C0A +8138BE39 2C0B +8138BF30 2C0C +8138BF31 2C0D +8138BF32 2C0E +8138BF33 2C0F +8138BF34 2C10 +8138BF35 2C11 +8138BF36 2C12 +8138BF37 2C13 +8138BF38 2C14 +8138BF39 2C15 +8138C030 2C16 +8138C031 2C17 +8138C032 2C18 +8138C033 2C19 +8138C034 2C1A +8138C035 2C1B +8138C036 2C1C +8138C037 2C1D +8138C038 2C1E +8138C039 2C1F +8138C130 2C20 +8138C131 2C21 +8138C132 2C22 +8138C133 2C23 +8138C134 2C24 +8138C135 2C25 +8138C136 2C26 +8138C137 2C27 +8138C138 2C28 +8138C139 2C29 +8138C230 2C2A +8138C231 2C2B +8138C232 2C2C +8138C233 2C2D +8138C234 2C2E +8138C235 2C2F +8138C236 2C30 +8138C237 2C31 +8138C238 2C32 +8138C239 2C33 +8138C330 2C34 +8138C331 2C35 +8138C332 2C36 +8138C333 2C37 +8138C334 2C38 +8138C335 2C39 +8138C336 2C3A +8138C337 2C3B +8138C338 2C3C +8138C339 2C3D +8138C430 2C3E +8138C431 2C3F +8138C432 2C40 +8138C433 2C41 +8138C434 2C42 +8138C435 2C43 +8138C436 2C44 +8138C437 2C45 +8138C438 2C46 +8138C439 2C47 +8138C530 2C48 +8138C531 2C49 +8138C532 2C4A +8138C533 2C4B +8138C534 2C4C +8138C535 2C4D +8138C536 2C4E +8138C537 2C4F +8138C538 2C50 +8138C539 2C51 +8138C630 2C52 +8138C631 2C53 +8138C632 2C54 +8138C633 2C55 +8138C634 2C56 +8138C635 2C57 +8138C636 2C58 +8138C637 2C59 +8138C638 2C5A +8138C639 2C5B +8138C730 2C5C +8138C731 2C5D +8138C732 2C5E +8138C733 2C5F +8138C734 2C60 +8138C735 2C61 +8138C736 2C62 +8138C737 2C63 +8138C738 2C64 +8138C739 2C65 +8138C830 2C66 +8138C831 2C67 +8138C832 2C68 +8138C833 2C69 +8138C834 2C6A +8138C835 2C6B +8138C836 2C6C +8138C837 2C6D +8138C838 2C6E +8138C839 2C6F +8138C930 2C70 +8138C931 2C71 +8138C932 2C72 +8138C933 2C73 +8138C934 2C74 +8138C935 2C75 +8138C936 2C76 +8138C937 2C77 +8138C938 2C78 +8138C939 2C79 +8138CA30 2C7A +8138CA31 2C7B +8138CA32 2C7C +8138CA33 2C7D +8138CA34 2C7E +8138CA35 2C7F +8138CA36 2C80 +8138CA37 2C81 +8138CA38 2C82 +8138CA39 2C83 +8138CB30 2C84 +8138CB31 2C85 +8138CB32 2C86 +8138CB33 2C87 +8138CB34 2C88 +8138CB35 2C89 +8138CB36 2C8A +8138CB37 2C8B +8138CB38 2C8C +8138CB39 2C8D +8138CC30 2C8E +8138CC31 2C8F +8138CC32 2C90 +8138CC33 2C91 +8138CC34 2C92 +8138CC35 2C93 +8138CC36 2C94 +8138CC37 2C95 +8138CC38 2C96 +8138CC39 2C97 +8138CD30 2C98 +8138CD31 2C99 +8138CD32 2C9A +8138CD33 2C9B +8138CD34 2C9C +8138CD35 2C9D +8138CD36 2C9E +8138CD37 2C9F +8138CD38 2CA0 +8138CD39 2CA1 +8138CE30 2CA2 +8138CE31 2CA3 +8138CE32 2CA4 +8138CE33 2CA5 +8138CE34 2CA6 +8138CE35 2CA7 +8138CE36 2CA8 +8138CE37 2CA9 +8138CE38 2CAA +8138CE39 2CAB +8138CF30 2CAC +8138CF31 2CAD +8138CF32 2CAE +8138CF33 2CAF +8138CF34 2CB0 +8138CF35 2CB1 +8138CF36 2CB2 +8138CF37 2CB3 +8138CF38 2CB4 +8138CF39 2CB5 +8138D030 2CB6 +8138D031 2CB7 +8138D032 2CB8 +8138D033 2CB9 +8138D034 2CBA +8138D035 2CBB +8138D036 2CBC +8138D037 2CBD +8138D038 2CBE +8138D039 2CBF +8138D130 2CC0 +8138D131 2CC1 +8138D132 2CC2 +8138D133 2CC3 +8138D134 2CC4 +8138D135 2CC5 +8138D136 2CC6 +8138D137 2CC7 +8138D138 2CC8 +8138D139 2CC9 +8138D230 2CCA +8138D231 2CCB +8138D232 2CCC +8138D233 2CCD +8138D234 2CCE +8138D235 2CCF +8138D236 2CD0 +8138D237 2CD1 +8138D238 2CD2 +8138D239 2CD3 +8138D330 2CD4 +8138D331 2CD5 +8138D332 2CD6 +8138D333 2CD7 +8138D334 2CD8 +8138D335 2CD9 +8138D336 2CDA +8138D337 2CDB +8138D338 2CDC +8138D339 2CDD +8138D430 2CDE +8138D431 2CDF +8138D432 2CE0 +8138D433 2CE1 +8138D434 2CE2 +8138D435 2CE3 +8138D436 2CE4 +8138D437 2CE5 +8138D438 2CE6 +8138D439 2CE7 +8138D530 2CE8 +8138D531 2CE9 +8138D532 2CEA +8138D533 2CEB +8138D534 2CEC +8138D535 2CED +8138D536 2CEE +8138D537 2CEF +8138D538 2CF0 +8138D539 2CF1 +8138D630 2CF2 +8138D631 2CF3 +8138D632 2CF4 +8138D633 2CF5 +8138D634 2CF6 +8138D635 2CF7 +8138D636 2CF8 +8138D637 2CF9 +8138D638 2CFA +8138D639 2CFB +8138D730 2CFC +8138D731 2CFD +8138D732 2CFE +8138D733 2CFF +8138D734 2D00 +8138D735 2D01 +8138D736 2D02 +8138D737 2D03 +8138D738 2D04 +8138D739 2D05 +8138D830 2D06 +8138D831 2D07 +8138D832 2D08 +8138D833 2D09 +8138D834 2D0A +8138D835 2D0B +8138D836 2D0C +8138D837 2D0D +8138D838 2D0E +8138D839 2D0F +8138D930 2D10 +8138D931 2D11 +8138D932 2D12 +8138D933 2D13 +8138D934 2D14 +8138D935 2D15 +8138D936 2D16 +8138D937 2D17 +8138D938 2D18 +8138D939 2D19 +8138DA30 2D1A +8138DA31 2D1B +8138DA32 2D1C +8138DA33 2D1D +8138DA34 2D1E +8138DA35 2D1F +8138DA36 2D20 +8138DA37 2D21 +8138DA38 2D22 +8138DA39 2D23 +8138DB30 2D24 +8138DB31 2D25 +8138DB32 2D26 +8138DB33 2D27 +8138DB34 2D28 +8138DB35 2D29 +8138DB36 2D2A +8138DB37 2D2B +8138DB38 2D2C +8138DB39 2D2D +8138DC30 2D2E +8138DC31 2D2F +8138DC32 2D30 +8138DC33 2D31 +8138DC34 2D32 +8138DC35 2D33 +8138DC36 2D34 +8138DC37 2D35 +8138DC38 2D36 +8138DC39 2D37 +8138DD30 2D38 +8138DD31 2D39 +8138DD32 2D3A +8138DD33 2D3B +8138DD34 2D3C +8138DD35 2D3D +8138DD36 2D3E +8138DD37 2D3F +8138DD38 2D40 +8138DD39 2D41 +8138DE30 2D42 +8138DE31 2D43 +8138DE32 2D44 +8138DE33 2D45 +8138DE34 2D46 +8138DE35 2D47 +8138DE36 2D48 +8138DE37 2D49 +8138DE38 2D4A +8138DE39 2D4B +8138DF30 2D4C +8138DF31 2D4D +8138DF32 2D4E +8138DF33 2D4F +8138DF34 2D50 +8138DF35 2D51 +8138DF36 2D52 +8138DF37 2D53 +8138DF38 2D54 +8138DF39 2D55 +8138E030 2D56 +8138E031 2D57 +8138E032 2D58 +8138E033 2D59 +8138E034 2D5A +8138E035 2D5B +8138E036 2D5C +8138E037 2D5D +8138E038 2D5E +8138E039 2D5F +8138E130 2D60 +8138E131 2D61 +8138E132 2D62 +8138E133 2D63 +8138E134 2D64 +8138E135 2D65 +8138E136 2D66 +8138E137 2D67 +8138E138 2D68 +8138E139 2D69 +8138E230 2D6A +8138E231 2D6B +8138E232 2D6C +8138E233 2D6D +8138E234 2D6E +8138E235 2D6F +8138E236 2D70 +8138E237 2D71 +8138E238 2D72 +8138E239 2D73 +8138E330 2D74 +8138E331 2D75 +8138E332 2D76 +8138E333 2D77 +8138E334 2D78 +8138E335 2D79 +8138E336 2D7A +8138E337 2D7B +8138E338 2D7C +8138E339 2D7D +8138E430 2D7E +8138E431 2D7F +8138E432 2D80 +8138E433 2D81 +8138E434 2D82 +8138E435 2D83 +8138E436 2D84 +8138E437 2D85 +8138E438 2D86 +8138E439 2D87 +8138E530 2D88 +8138E531 2D89 +8138E532 2D8A +8138E533 2D8B +8138E534 2D8C +8138E535 2D8D +8138E536 2D8E +8138E537 2D8F +8138E538 2D90 +8138E539 2D91 +8138E630 2D92 +8138E631 2D93 +8138E632 2D94 +8138E633 2D95 +8138E634 2D96 +8138E635 2D97 +8138E636 2D98 +8138E637 2D99 +8138E638 2D9A +8138E639 2D9B +8138E730 2D9C +8138E731 2D9D +8138E732 2D9E +8138E733 2D9F +8138E734 2DA0 +8138E735 2DA1 +8138E736 2DA2 +8138E737 2DA3 +8138E738 2DA4 +8138E739 2DA5 +8138E830 2DA6 +8138E831 2DA7 +8138E832 2DA8 +8138E833 2DA9 +8138E834 2DAA +8138E835 2DAB +8138E836 2DAC +8138E837 2DAD +8138E838 2DAE +8138E839 2DAF +8138E930 2DB0 +8138E931 2DB1 +8138E932 2DB2 +8138E933 2DB3 +8138E934 2DB4 +8138E935 2DB5 +8138E936 2DB6 +8138E937 2DB7 +8138E938 2DB8 +8138E939 2DB9 +8138EA30 2DBA +8138EA31 2DBB +8138EA32 2DBC +8138EA33 2DBD +8138EA34 2DBE +8138EA35 2DBF +8138EA36 2DC0 +8138EA37 2DC1 +8138EA38 2DC2 +8138EA39 2DC3 +8138EB30 2DC4 +8138EB31 2DC5 +8138EB32 2DC6 +8138EB33 2DC7 +8138EB34 2DC8 +8138EB35 2DC9 +8138EB36 2DCA +8138EB37 2DCB +8138EB38 2DCC +8138EB39 2DCD +8138EC30 2DCE +8138EC31 2DCF +8138EC32 2DD0 +8138EC33 2DD1 +8138EC34 2DD2 +8138EC35 2DD3 +8138EC36 2DD4 +8138EC37 2DD5 +8138EC38 2DD6 +8138EC39 2DD7 +8138ED30 2DD8 +8138ED31 2DD9 +8138ED32 2DDA +8138ED33 2DDB +8138ED34 2DDC +8138ED35 2DDD +8138ED36 2DDE +8138ED37 2DDF +8138ED38 2DE0 +8138ED39 2DE1 +8138EE30 2DE2 +8138EE31 2DE3 +8138EE32 2DE4 +8138EE33 2DE5 +8138EE34 2DE6 +8138EE35 2DE7 +8138EE36 2DE8 +8138EE37 2DE9 +8138EE38 2DEA +8138EE39 2DEB +8138EF30 2DEC +8138EF31 2DED +8138EF32 2DEE +8138EF33 2DEF +8138EF34 2DF0 +8138EF35 2DF1 +8138EF36 2DF2 +8138EF37 2DF3 +8138EF38 2DF4 +8138EF39 2DF5 +8138F030 2DF6 +8138F031 2DF7 +8138F032 2DF8 +8138F033 2DF9 +8138F034 2DFA +8138F035 2DFB +8138F036 2DFC +8138F037 2DFD +8138F038 2DFE +8138F039 2DFF +8138F130 2E00 +8138F131 2E01 +8138F132 2E02 +8138F133 2E03 +8138F134 2E04 +8138F135 2E05 +8138F136 2E06 +8138F137 2E07 +8138F138 2E08 +8138F139 2E09 +8138F230 2E0A +8138F231 2E0B +8138F232 2E0C +8138F233 2E0D +8138F234 2E0E +8138F235 2E0F +8138F236 2E10 +8138F237 2E11 +8138F238 2E12 +8138F239 2E13 +8138F330 2E14 +8138F331 2E15 +8138F332 2E16 +8138F333 2E17 +8138F334 2E18 +8138F335 2E19 +8138F336 2E1A +8138F337 2E1B +8138F338 2E1C +8138F339 2E1D +8138F430 2E1E +8138F431 2E1F +8138F432 2E20 +8138F433 2E21 +8138F434 2E22 +8138F435 2E23 +8138F436 2E24 +8138F437 2E25 +8138F438 2E26 +8138F439 2E27 +8138F530 2E28 +8138F531 2E29 +8138F532 2E2A +8138F533 2E2B +8138F534 2E2C +8138F535 2E2D +8138F536 2E2E +8138F537 2E2F +8138F538 2E30 +8138F539 2E31 +8138F630 2E32 +8138F631 2E33 +8138F632 2E34 +8138F633 2E35 +8138F634 2E36 +8138F635 2E37 +8138F636 2E38 +8138F637 2E39 +8138F638 2E3A +8138F639 2E3B +8138F730 2E3C +8138F731 2E3D +8138F732 2E3E +8138F733 2E3F +8138F734 2E40 +8138F735 2E41 +8138F736 2E42 +8138F737 2E43 +8138F738 2E44 +8138F739 2E45 +8138F830 2E46 +8138F831 2E47 +8138F832 2E48 +8138F833 2E49 +8138F834 2E4A +8138F835 2E4B +8138F836 2E4C +8138F837 2E4D +8138F838 2E4E +8138F839 2E4F +8138F930 2E50 +8138F931 2E51 +8138F932 2E52 +8138F933 2E53 +8138F934 2E54 +8138F935 2E55 +8138F936 2E56 +8138F937 2E57 +8138F938 2E58 +8138F939 2E59 +8138FA30 2E5A +8138FA31 2E5B +8138FA32 2E5C +8138FA33 2E5D +8138FA34 2E5E +8138FA35 2E5F +8138FA36 2E60 +8138FA37 2E61 +8138FA38 2E62 +8138FA39 2E63 +8138FB30 2E64 +8138FB31 2E65 +8138FB32 2E66 +8138FB33 2E67 +8138FB34 2E68 +8138FB35 2E69 +8138FB36 2E6A +8138FB37 2E6B +8138FB38 2E6C +8138FB39 2E6D +8138FC30 2E6E +8138FC31 2E6F +8138FC32 2E70 +8138FC33 2E71 +8138FC34 2E72 +8138FC35 2E73 +8138FC36 2E74 +8138FC37 2E75 +8138FC38 2E76 +8138FC39 2E77 +8138FD30 2E78 +8138FD31 2E79 +8138FD32 2E7A +8138FD33 2E7B +8138FD34 2E7C +8138FD35 2E7D +8138FD36 2E7E +8138FD37 2E7F +8138FD38 2E80 +FE50 2E81 +8138FD39 2E82 +8138FE30 2E83 +FE54 2E84 +8138FE31 2E85 +8138FE32 2E86 +8138FE33 2E87 +FE57 2E88 +8138FE34 2E89 +8138FE35 2E8A +FE58 2E8B +FE5D 2E8C +8138FE36 2E8D +8138FE37 2E8E +8138FE38 2E8F +8138FE39 2E90 +81398130 2E91 +81398131 2E92 +81398132 2E93 +81398133 2E94 +81398134 2E95 +81398135 2E96 +FE5E 2E97 +81398136 2E98 +81398137 2E99 +81398138 2E9A +81398139 2E9B +81398230 2E9C +81398231 2E9D +81398232 2E9E +81398233 2E9F +81398234 2EA0 +81398235 2EA1 +81398236 2EA2 +81398237 2EA3 +81398238 2EA4 +81398239 2EA5 +81398330 2EA6 +FE6B 2EA7 +81398331 2EA8 +81398332 2EA9 +FE6E 2EAA +81398333 2EAB +81398334 2EAC +81398335 2EAD +FE71 2EAE +81398336 2EAF +81398337 2EB0 +81398338 2EB1 +81398339 2EB2 +FE73 2EB3 +81398430 2EB4 +81398431 2EB5 +FE74 2EB6 +FE75 2EB7 +81398432 2EB8 +81398433 2EB9 +81398434 2EBA +FE79 2EBB +81398435 2EBC +81398436 2EBD +81398437 2EBE +81398438 2EBF +81398439 2EC0 +81398530 2EC1 +81398531 2EC2 +81398532 2EC3 +81398533 2EC4 +81398534 2EC5 +81398535 2EC6 +81398536 2EC7 +81398537 2EC8 +81398538 2EC9 +FE84 2ECA +81398539 2ECB +81398630 2ECC +81398631 2ECD +81398632 2ECE +81398633 2ECF +81398634 2ED0 +81398635 2ED1 +81398636 2ED2 +81398637 2ED3 +81398638 2ED4 +81398639 2ED5 +81398730 2ED6 +81398731 2ED7 +81398732 2ED8 +81398733 2ED9 +81398734 2EDA +81398735 2EDB +81398736 2EDC +81398737 2EDD +81398738 2EDE +81398739 2EDF +81398830 2EE0 +81398831 2EE1 +81398832 2EE2 +81398833 2EE3 +81398834 2EE4 +81398835 2EE5 +81398836 2EE6 +81398837 2EE7 +81398838 2EE8 +81398839 2EE9 +81398930 2EEA +81398931 2EEB +81398932 2EEC +81398933 2EED +81398934 2EEE +81398935 2EEF +81398936 2EF0 +81398937 2EF1 +81398938 2EF2 +81398939 2EF3 +81398A30 2EF4 +81398A31 2EF5 +81398A32 2EF6 +81398A33 2EF7 +81398A34 2EF8 +81398A35 2EF9 +81398A36 2EFA +81398A37 2EFB +81398A38 2EFC +81398A39 2EFD +81398B30 2EFE +81398B31 2EFF +81398B32 2F00 +81398B33 2F01 +81398B34 2F02 +81398B35 2F03 +81398B36 2F04 +81398B37 2F05 +81398B38 2F06 +81398B39 2F07 +81398C30 2F08 +81398C31 2F09 +81398C32 2F0A +81398C33 2F0B +81398C34 2F0C +81398C35 2F0D +81398C36 2F0E +81398C37 2F0F +81398C38 2F10 +81398C39 2F11 +81398D30 2F12 +81398D31 2F13 +81398D32 2F14 +81398D33 2F15 +81398D34 2F16 +81398D35 2F17 +81398D36 2F18 +81398D37 2F19 +81398D38 2F1A +81398D39 2F1B +81398E30 2F1C +81398E31 2F1D +81398E32 2F1E +81398E33 2F1F +81398E34 2F20 +81398E35 2F21 +81398E36 2F22 +81398E37 2F23 +81398E38 2F24 +81398E39 2F25 +81398F30 2F26 +81398F31 2F27 +81398F32 2F28 +81398F33 2F29 +81398F34 2F2A +81398F35 2F2B +81398F36 2F2C +81398F37 2F2D +81398F38 2F2E +81398F39 2F2F +81399030 2F30 +81399031 2F31 +81399032 2F32 +81399033 2F33 +81399034 2F34 +81399035 2F35 +81399036 2F36 +81399037 2F37 +81399038 2F38 +81399039 2F39 +81399130 2F3A +81399131 2F3B +81399132 2F3C +81399133 2F3D +81399134 2F3E +81399135 2F3F +81399136 2F40 +81399137 2F41 +81399138 2F42 +81399139 2F43 +81399230 2F44 +81399231 2F45 +81399232 2F46 +81399233 2F47 +81399234 2F48 +81399235 2F49 +81399236 2F4A +81399237 2F4B +81399238 2F4C +81399239 2F4D +81399330 2F4E +81399331 2F4F +81399332 2F50 +81399333 2F51 +81399334 2F52 +81399335 2F53 +81399336 2F54 +81399337 2F55 +81399338 2F56 +81399339 2F57 +81399430 2F58 +81399431 2F59 +81399432 2F5A +81399433 2F5B +81399434 2F5C +81399435 2F5D +81399436 2F5E +81399437 2F5F +81399438 2F60 +81399439 2F61 +81399530 2F62 +81399531 2F63 +81399532 2F64 +81399533 2F65 +81399534 2F66 +81399535 2F67 +81399536 2F68 +81399537 2F69 +81399538 2F6A +81399539 2F6B +81399630 2F6C +81399631 2F6D +81399632 2F6E +81399633 2F6F +81399634 2F70 +81399635 2F71 +81399636 2F72 +81399637 2F73 +81399638 2F74 +81399639 2F75 +81399730 2F76 +81399731 2F77 +81399732 2F78 +81399733 2F79 +81399734 2F7A +81399735 2F7B +81399736 2F7C +81399737 2F7D +81399738 2F7E +81399739 2F7F +81399830 2F80 +81399831 2F81 +81399832 2F82 +81399833 2F83 +81399834 2F84 +81399835 2F85 +81399836 2F86 +81399837 2F87 +81399838 2F88 +81399839 2F89 +81399930 2F8A +81399931 2F8B +81399932 2F8C +81399933 2F8D +81399934 2F8E +81399935 2F8F +81399936 2F90 +81399937 2F91 +81399938 2F92 +81399939 2F93 +81399A30 2F94 +81399A31 2F95 +81399A32 2F96 +81399A33 2F97 +81399A34 2F98 +81399A35 2F99 +81399A36 2F9A +81399A37 2F9B +81399A38 2F9C +81399A39 2F9D +81399B30 2F9E +81399B31 2F9F +81399B32 2FA0 +81399B33 2FA1 +81399B34 2FA2 +81399B35 2FA3 +81399B36 2FA4 +81399B37 2FA5 +81399B38 2FA6 +81399B39 2FA7 +81399C30 2FA8 +81399C31 2FA9 +81399C32 2FAA +81399C33 2FAB +81399C34 2FAC +81399C35 2FAD +81399C36 2FAE +81399C37 2FAF +81399C38 2FB0 +81399C39 2FB1 +81399D30 2FB2 +81399D31 2FB3 +81399D32 2FB4 +81399D33 2FB5 +81399D34 2FB6 +81399D35 2FB7 +81399D36 2FB8 +81399D37 2FB9 +81399D38 2FBA +81399D39 2FBB +81399E30 2FBC +81399E31 2FBD +81399E32 2FBE +81399E33 2FBF +81399E34 2FC0 +81399E35 2FC1 +81399E36 2FC2 +81399E37 2FC3 +81399E38 2FC4 +81399E39 2FC5 +81399F30 2FC6 +81399F31 2FC7 +81399F32 2FC8 +81399F33 2FC9 +81399F34 2FCA +81399F35 2FCB +81399F36 2FCC +81399F37 2FCD +81399F38 2FCE +81399F39 2FCF +8139A030 2FD0 +8139A031 2FD1 +8139A032 2FD2 +8139A033 2FD3 +8139A034 2FD4 +8139A035 2FD5 +8139A036 2FD6 +8139A037 2FD7 +8139A038 2FD8 +8139A039 2FD9 +8139A130 2FDA +8139A131 2FDB +8139A132 2FDC +8139A133 2FDD +8139A134 2FDE +8139A135 2FDF +8139A136 2FE0 +8139A137 2FE1 +8139A138 2FE2 +8139A139 2FE3 +8139A230 2FE4 +8139A231 2FE5 +8139A232 2FE6 +8139A233 2FE7 +8139A234 2FE8 +8139A235 2FE9 +8139A236 2FEA +8139A237 2FEB +8139A238 2FEC +8139A239 2FED +8139A330 2FEE +8139A331 2FEF +A98A 2FF0 +A98B 2FF1 +A98C 2FF2 +A98D 2FF3 +A98E 2FF4 +A98F 2FF5 +A990 2FF6 +A991 2FF7 +A992 2FF8 +A993 2FF9 +A994 2FFA +A995 2FFB +8139A332 2FFC +8139A333 2FFD +8139A334 2FFE +8139A335 2FFF +A1A1 3000 +A1A2 3001 +A1A3 3002 +A1A8 3003 +8139A336 3004 +A1A9 3005 +A965 3006 +A996 3007 +A1B4 3008 +A1B5 3009 +A1B6 300A +A1B7 300B +A1B8 300C +A1B9 300D +A1BA 300E +A1BB 300F +A1BE 3010 +A1BF 3011 +A893 3012 +A1FE 3013 +A1B2 3014 +A1B3 3015 +A1BC 3016 +A1BD 3017 +8139A337 3018 +8139A338 3019 +8139A339 301A +8139A430 301B +8139A431 301C +A894 301D +A895 301E +8139A432 301F +8139A433 3020 +A940 3021 +A941 3022 +A942 3023 +A943 3024 +A944 3025 +A945 3026 +A946 3027 +A947 3028 +A948 3029 +8139A434 302A +8139A435 302B +8139A436 302C +8139A437 302D +8139A438 302E +8139A439 302F +8139A530 3030 +8139A531 3031 +8139A532 3032 +8139A533 3033 +8139A534 3034 +8139A535 3035 +8139A536 3036 +8139A537 3037 +8139A538 3038 +8139A539 3039 +8139A630 303A +8139A631 303B +8139A632 303C +8139A633 303D +A989 303E +8139A634 303F +8139A635 3040 +A4A1 3041 +A4A2 3042 +A4A3 3043 +A4A4 3044 +A4A5 3045 +A4A6 3046 +A4A7 3047 +A4A8 3048 +A4A9 3049 +A4AA 304A +A4AB 304B +A4AC 304C +A4AD 304D +A4AE 304E +A4AF 304F +A4B0 3050 +A4B1 3051 +A4B2 3052 +A4B3 3053 +A4B4 3054 +A4B5 3055 +A4B6 3056 +A4B7 3057 +A4B8 3058 +A4B9 3059 +A4BA 305A +A4BB 305B +A4BC 305C +A4BD 305D +A4BE 305E +A4BF 305F +A4C0 3060 +A4C1 3061 +A4C2 3062 +A4C3 3063 +A4C4 3064 +A4C5 3065 +A4C6 3066 +A4C7 3067 +A4C8 3068 +A4C9 3069 +A4CA 306A +A4CB 306B +A4CC 306C +A4CD 306D +A4CE 306E +A4CF 306F +A4D0 3070 +A4D1 3071 +A4D2 3072 +A4D3 3073 +A4D4 3074 +A4D5 3075 +A4D6 3076 +A4D7 3077 +A4D8 3078 +A4D9 3079 +A4DA 307A +A4DB 307B +A4DC 307C +A4DD 307D +A4DE 307E +A4DF 307F +A4E0 3080 +A4E1 3081 +A4E2 3082 +A4E3 3083 +A4E4 3084 +A4E5 3085 +A4E6 3086 +A4E7 3087 +A4E8 3088 +A4E9 3089 +A4EA 308A +A4EB 308B +A4EC 308C +A4ED 308D +A4EE 308E +A4EF 308F +A4F0 3090 +A4F1 3091 +A4F2 3092 +A4F3 3093 +8139A636 3094 +8139A637 3095 +8139A638 3096 +8139A639 3097 +8139A730 3098 +8139A731 3099 +8139A732 309A +A961 309B +A962 309C +A966 309D +A967 309E +8139A733 309F +8139A734 30A0 +A5A1 30A1 +A5A2 30A2 +A5A3 30A3 +A5A4 30A4 +A5A5 30A5 +A5A6 30A6 +A5A7 30A7 +A5A8 30A8 +A5A9 30A9 +A5AA 30AA +A5AB 30AB +A5AC 30AC +A5AD 30AD +A5AE 30AE +A5AF 30AF +A5B0 30B0 +A5B1 30B1 +A5B2 30B2 +A5B3 30B3 +A5B4 30B4 +A5B5 30B5 +A5B6 30B6 +A5B7 30B7 +A5B8 30B8 +A5B9 30B9 +A5BA 30BA +A5BB 30BB +A5BC 30BC +A5BD 30BD +A5BE 30BE +A5BF 30BF +A5C0 30C0 +A5C1 30C1 +A5C2 30C2 +A5C3 30C3 +A5C4 30C4 +A5C5 30C5 +A5C6 30C6 +A5C7 30C7 +A5C8 30C8 +A5C9 30C9 +A5CA 30CA +A5CB 30CB +A5CC 30CC +A5CD 30CD +A5CE 30CE +A5CF 30CF +A5D0 30D0 +A5D1 30D1 +A5D2 30D2 +A5D3 30D3 +A5D4 30D4 +A5D5 30D5 +A5D6 30D6 +A5D7 30D7 +A5D8 30D8 +A5D9 30D9 +A5DA 30DA +A5DB 30DB +A5DC 30DC +A5DD 30DD +A5DE 30DE +A5DF 30DF +A5E0 30E0 +A5E1 30E1 +A5E2 30E2 +A5E3 30E3 +A5E4 30E4 +A5E5 30E5 +A5E6 30E6 +A5E7 30E7 +A5E8 30E8 +A5E9 30E9 +A5EA 30EA +A5EB 30EB +A5EC 30EC +A5ED 30ED +A5EE 30EE +A5EF 30EF +A5F0 30F0 +A5F1 30F1 +A5F2 30F2 +A5F3 30F3 +A5F4 30F4 +A5F5 30F5 +A5F6 30F6 +8139A735 30F7 +8139A736 30F8 +8139A737 30F9 +8139A738 30FA +8139A739 30FB +A960 30FC +A963 30FD +A964 30FE +8139A830 30FF +8139A831 3100 +8139A832 3101 +8139A833 3102 +8139A834 3103 +8139A835 3104 +A8C5 3105 +A8C6 3106 +A8C7 3107 +A8C8 3108 +A8C9 3109 +A8CA 310A +A8CB 310B +A8CC 310C +A8CD 310D +A8CE 310E +A8CF 310F +A8D0 3110 +A8D1 3111 +A8D2 3112 +A8D3 3113 +A8D4 3114 +A8D5 3115 +A8D6 3116 +A8D7 3117 +A8D8 3118 +A8D9 3119 +A8DA 311A +A8DB 311B +A8DC 311C +A8DD 311D +A8DE 311E +A8DF 311F +A8E0 3120 +A8E1 3121 +A8E2 3122 +A8E3 3123 +A8E4 3124 +A8E5 3125 +A8E6 3126 +A8E7 3127 +A8E8 3128 +A8E9 3129 +8139A836 312A +8139A837 312B +8139A838 312C +8139A839 312D +8139A930 312E +8139A931 312F +8139A932 3130 +8139A933 3131 +8139A934 3132 +8139A935 3133 +8139A936 3134 +8139A937 3135 +8139A938 3136 +8139A939 3137 +8139AA30 3138 +8139AA31 3139 +8139AA32 313A +8139AA33 313B +8139AA34 313C +8139AA35 313D +8139AA36 313E +8139AA37 313F +8139AA38 3140 +8139AA39 3141 +8139AB30 3142 +8139AB31 3143 +8139AB32 3144 +8139AB33 3145 +8139AB34 3146 +8139AB35 3147 +8139AB36 3148 +8139AB37 3149 +8139AB38 314A +8139AB39 314B +8139AC30 314C +8139AC31 314D +8139AC32 314E +8139AC33 314F +8139AC34 3150 +8139AC35 3151 +8139AC36 3152 +8139AC37 3153 +8139AC38 3154 +8139AC39 3155 +8139AD30 3156 +8139AD31 3157 +8139AD32 3158 +8139AD33 3159 +8139AD34 315A +8139AD35 315B +8139AD36 315C +8139AD37 315D +8139AD38 315E +8139AD39 315F +8139AE30 3160 +8139AE31 3161 +8139AE32 3162 +8139AE33 3163 +8139AE34 3164 +8139AE35 3165 +8139AE36 3166 +8139AE37 3167 +8139AE38 3168 +8139AE39 3169 +8139AF30 316A +8139AF31 316B +8139AF32 316C +8139AF33 316D +8139AF34 316E +8139AF35 316F +8139AF36 3170 +8139AF37 3171 +8139AF38 3172 +8139AF39 3173 +8139B030 3174 +8139B031 3175 +8139B032 3176 +8139B033 3177 +8139B034 3178 +8139B035 3179 +8139B036 317A +8139B037 317B +8139B038 317C +8139B039 317D +8139B130 317E +8139B131 317F +8139B132 3180 +8139B133 3181 +8139B134 3182 +8139B135 3183 +8139B136 3184 +8139B137 3185 +8139B138 3186 +8139B139 3187 +8139B230 3188 +8139B231 3189 +8139B232 318A +8139B233 318B +8139B234 318C +8139B235 318D +8139B236 318E +8139B237 318F +8139B238 3190 +8139B239 3191 +8139B330 3192 +8139B331 3193 +8139B332 3194 +8139B333 3195 +8139B334 3196 +8139B335 3197 +8139B336 3198 +8139B337 3199 +8139B338 319A +8139B339 319B +8139B430 319C +8139B431 319D +8139B432 319E +8139B433 319F +8139B434 31A0 +8139B435 31A1 +8139B436 31A2 +8139B437 31A3 +8139B438 31A4 +8139B439 31A5 +8139B530 31A6 +8139B531 31A7 +8139B532 31A8 +8139B533 31A9 +8139B534 31AA +8139B535 31AB +8139B536 31AC +8139B537 31AD +8139B538 31AE +8139B539 31AF +8139B630 31B0 +8139B631 31B1 +8139B632 31B2 +8139B633 31B3 +8139B634 31B4 +8139B635 31B5 +8139B636 31B6 +8139B637 31B7 +8139B638 31B8 +8139B639 31B9 +8139B730 31BA +8139B731 31BB +8139B732 31BC +8139B733 31BD +8139B734 31BE +8139B735 31BF +8139B736 31C0 +8139B737 31C1 +8139B738 31C2 +8139B739 31C3 +8139B830 31C4 +8139B831 31C5 +8139B832 31C6 +8139B833 31C7 +8139B834 31C8 +8139B835 31C9 +8139B836 31CA +8139B837 31CB +8139B838 31CC +8139B839 31CD +8139B930 31CE +8139B931 31CF +8139B932 31D0 +8139B933 31D1 +8139B934 31D2 +8139B935 31D3 +8139B936 31D4 +8139B937 31D5 +8139B938 31D6 +8139B939 31D7 +8139BA30 31D8 +8139BA31 31D9 +8139BA32 31DA +8139BA33 31DB +8139BA34 31DC +8139BA35 31DD +8139BA36 31DE +8139BA37 31DF +8139BA38 31E0 +8139BA39 31E1 +8139BB30 31E2 +8139BB31 31E3 +8139BB32 31E4 +8139BB33 31E5 +8139BB34 31E6 +8139BB35 31E7 +8139BB36 31E8 +8139BB37 31E9 +8139BB38 31EA +8139BB39 31EB +8139BC30 31EC +8139BC31 31ED +8139BC32 31EE +8139BC33 31EF +8139BC34 31F0 +8139BC35 31F1 +8139BC36 31F2 +8139BC37 31F3 +8139BC38 31F4 +8139BC39 31F5 +8139BD30 31F6 +8139BD31 31F7 +8139BD32 31F8 +8139BD33 31F9 +8139BD34 31FA +8139BD35 31FB +8139BD36 31FC +8139BD37 31FD +8139BD38 31FE +8139BD39 31FF +8139BE30 3200 +8139BE31 3201 +8139BE32 3202 +8139BE33 3203 +8139BE34 3204 +8139BE35 3205 +8139BE36 3206 +8139BE37 3207 +8139BE38 3208 +8139BE39 3209 +8139BF30 320A +8139BF31 320B +8139BF32 320C +8139BF33 320D +8139BF34 320E +8139BF35 320F +8139BF36 3210 +8139BF37 3211 +8139BF38 3212 +8139BF39 3213 +8139C030 3214 +8139C031 3215 +8139C032 3216 +8139C033 3217 +8139C034 3218 +8139C035 3219 +8139C036 321A +8139C037 321B +8139C038 321C +8139C039 321D +8139C130 321E +8139C131 321F +A2E5 3220 +A2E6 3221 +A2E7 3222 +A2E8 3223 +A2E9 3224 +A2EA 3225 +A2EB 3226 +A2EC 3227 +A2ED 3228 +A2EE 3229 +8139C132 322A +8139C133 322B +8139C134 322C +8139C135 322D +8139C136 322E +8139C137 322F +8139C138 3230 +A95A 3231 +8139C139 3232 +8139C230 3233 +8139C231 3234 +8139C232 3235 +8139C233 3236 +8139C234 3237 +8139C235 3238 +8139C236 3239 +8139C237 323A +8139C238 323B +8139C239 323C +8139C330 323D +8139C331 323E +8139C332 323F +8139C333 3240 +8139C334 3241 +8139C335 3242 +8139C336 3243 +8139C337 3244 +8139C338 3245 +8139C339 3246 +8139C430 3247 +8139C431 3248 +8139C432 3249 +8139C433 324A +8139C434 324B +8139C435 324C +8139C436 324D +8139C437 324E +8139C438 324F +8139C439 3250 +8139C530 3251 +8139C531 3252 +8139C532 3253 +8139C533 3254 +8139C534 3255 +8139C535 3256 +8139C536 3257 +8139C537 3258 +8139C538 3259 +8139C539 325A +8139C630 325B +8139C631 325C +8139C632 325D +8139C633 325E +8139C634 325F +8139C635 3260 +8139C636 3261 +8139C637 3262 +8139C638 3263 +8139C639 3264 +8139C730 3265 +8139C731 3266 +8139C732 3267 +8139C733 3268 +8139C734 3269 +8139C735 326A +8139C736 326B +8139C737 326C +8139C738 326D +8139C739 326E +8139C830 326F +8139C831 3270 +8139C832 3271 +8139C833 3272 +8139C834 3273 +8139C835 3274 +8139C836 3275 +8139C837 3276 +8139C838 3277 +8139C839 3278 +8139C930 3279 +8139C931 327A +8139C932 327B +8139C933 327C +8139C934 327D +8139C935 327E +8139C936 327F +8139C937 3280 +8139C938 3281 +8139C939 3282 +8139CA30 3283 +8139CA31 3284 +8139CA32 3285 +8139CA33 3286 +8139CA34 3287 +8139CA35 3288 +8139CA36 3289 +8139CA37 328A +8139CA38 328B +8139CA39 328C +8139CB30 328D +8139CB31 328E +8139CB32 328F +8139CB33 3290 +8139CB34 3291 +8139CB35 3292 +8139CB36 3293 +8139CB37 3294 +8139CB38 3295 +8139CB39 3296 +8139CC30 3297 +8139CC31 3298 +8139CC32 3299 +8139CC33 329A +8139CC34 329B +8139CC35 329C +8139CC36 329D +8139CC37 329E +8139CC38 329F +8139CC39 32A0 +8139CD30 32A1 +8139CD31 32A2 +A949 32A3 +8139CD32 32A4 +8139CD33 32A5 +8139CD34 32A6 +8139CD35 32A7 +8139CD36 32A8 +8139CD37 32A9 +8139CD38 32AA +8139CD39 32AB +8139CE30 32AC +8139CE31 32AD +8139CE32 32AE +8139CE33 32AF +8139CE34 32B0 +8139CE35 32B1 +8139CE36 32B2 +8139CE37 32B3 +8139CE38 32B4 +8139CE39 32B5 +8139CF30 32B6 +8139CF31 32B7 +8139CF32 32B8 +8139CF33 32B9 +8139CF34 32BA +8139CF35 32BB +8139CF36 32BC +8139CF37 32BD +8139CF38 32BE +8139CF39 32BF +8139D030 32C0 +8139D031 32C1 +8139D032 32C2 +8139D033 32C3 +8139D034 32C4 +8139D035 32C5 +8139D036 32C6 +8139D037 32C7 +8139D038 32C8 +8139D039 32C9 +8139D130 32CA +8139D131 32CB +8139D132 32CC +8139D133 32CD +8139D134 32CE +8139D135 32CF +8139D136 32D0 +8139D137 32D1 +8139D138 32D2 +8139D139 32D3 +8139D230 32D4 +8139D231 32D5 +8139D232 32D6 +8139D233 32D7 +8139D234 32D8 +8139D235 32D9 +8139D236 32DA +8139D237 32DB +8139D238 32DC +8139D239 32DD +8139D330 32DE +8139D331 32DF +8139D332 32E0 +8139D333 32E1 +8139D334 32E2 +8139D335 32E3 +8139D336 32E4 +8139D337 32E5 +8139D338 32E6 +8139D339 32E7 +8139D430 32E8 +8139D431 32E9 +8139D432 32EA +8139D433 32EB +8139D434 32EC +8139D435 32ED +8139D436 32EE +8139D437 32EF +8139D438 32F0 +8139D439 32F1 +8139D530 32F2 +8139D531 32F3 +8139D532 32F4 +8139D533 32F5 +8139D534 32F6 +8139D535 32F7 +8139D536 32F8 +8139D537 32F9 +8139D538 32FA +8139D539 32FB +8139D630 32FC +8139D631 32FD +8139D632 32FE +8139D633 32FF +8139D634 3300 +8139D635 3301 +8139D636 3302 +8139D637 3303 +8139D638 3304 +8139D639 3305 +8139D730 3306 +8139D731 3307 +8139D732 3308 +8139D733 3309 +8139D734 330A +8139D735 330B +8139D736 330C +8139D737 330D +8139D738 330E +8139D739 330F +8139D830 3310 +8139D831 3311 +8139D832 3312 +8139D833 3313 +8139D834 3314 +8139D835 3315 +8139D836 3316 +8139D837 3317 +8139D838 3318 +8139D839 3319 +8139D930 331A +8139D931 331B +8139D932 331C +8139D933 331D +8139D934 331E +8139D935 331F +8139D936 3320 +8139D937 3321 +8139D938 3322 +8139D939 3323 +8139DA30 3324 +8139DA31 3325 +8139DA32 3326 +8139DA33 3327 +8139DA34 3328 +8139DA35 3329 +8139DA36 332A +8139DA37 332B +8139DA38 332C +8139DA39 332D +8139DB30 332E +8139DB31 332F +8139DB32 3330 +8139DB33 3331 +8139DB34 3332 +8139DB35 3333 +8139DB36 3334 +8139DB37 3335 +8139DB38 3336 +8139DB39 3337 +8139DC30 3338 +8139DC31 3339 +8139DC32 333A +8139DC33 333B +8139DC34 333C +8139DC35 333D +8139DC36 333E +8139DC37 333F +8139DC38 3340 +8139DC39 3341 +8139DD30 3342 +8139DD31 3343 +8139DD32 3344 +8139DD33 3345 +8139DD34 3346 +8139DD35 3347 +8139DD36 3348 +8139DD37 3349 +8139DD38 334A +8139DD39 334B +8139DE30 334C +8139DE31 334D +8139DE32 334E +8139DE33 334F +8139DE34 3350 +8139DE35 3351 +8139DE36 3352 +8139DE37 3353 +8139DE38 3354 +8139DE39 3355 +8139DF30 3356 +8139DF31 3357 +8139DF32 3358 +8139DF33 3359 +8139DF34 335A +8139DF35 335B +8139DF36 335C +8139DF37 335D +8139DF38 335E +8139DF39 335F +8139E030 3360 +8139E031 3361 +8139E032 3362 +8139E033 3363 +8139E034 3364 +8139E035 3365 +8139E036 3366 +8139E037 3367 +8139E038 3368 +8139E039 3369 +8139E130 336A +8139E131 336B +8139E132 336C +8139E133 336D +8139E134 336E +8139E135 336F +8139E136 3370 +8139E137 3371 +8139E138 3372 +8139E139 3373 +8139E230 3374 +8139E231 3375 +8139E232 3376 +8139E233 3377 +8139E234 3378 +8139E235 3379 +8139E236 337A +8139E237 337B +8139E238 337C +8139E239 337D +8139E330 337E +8139E331 337F +8139E332 3380 +8139E333 3381 +8139E334 3382 +8139E335 3383 +8139E336 3384 +8139E337 3385 +8139E338 3386 +8139E339 3387 +8139E430 3388 +8139E431 3389 +8139E432 338A +8139E433 338B +8139E434 338C +8139E435 338D +A94A 338E +A94B 338F +8139E436 3390 +8139E437 3391 +8139E438 3392 +8139E439 3393 +8139E530 3394 +8139E531 3395 +8139E532 3396 +8139E533 3397 +8139E534 3398 +8139E535 3399 +8139E536 339A +8139E537 339B +A94C 339C +A94D 339D +A94E 339E +8139E538 339F +8139E539 33A0 +A94F 33A1 +8139E630 33A2 +8139E631 33A3 +8139E632 33A4 +8139E633 33A5 +8139E634 33A6 +8139E635 33A7 +8139E636 33A8 +8139E637 33A9 +8139E638 33AA +8139E639 33AB +8139E730 33AC +8139E731 33AD +8139E732 33AE +8139E733 33AF +8139E734 33B0 +8139E735 33B1 +8139E736 33B2 +8139E737 33B3 +8139E738 33B4 +8139E739 33B5 +8139E830 33B6 +8139E831 33B7 +8139E832 33B8 +8139E833 33B9 +8139E834 33BA +8139E835 33BB +8139E836 33BC +8139E837 33BD +8139E838 33BE +8139E839 33BF +8139E930 33C0 +8139E931 33C1 +8139E932 33C2 +8139E933 33C3 +A950 33C4 +8139E934 33C5 +8139E935 33C6 +8139E936 33C7 +8139E937 33C8 +8139E938 33C9 +8139E939 33CA +8139EA30 33CB +8139EA31 33CC +8139EA32 33CD +A951 33CE +8139EA33 33CF +8139EA34 33D0 +A952 33D1 +A953 33D2 +8139EA35 33D3 +8139EA36 33D4 +A954 33D5 +8139EA37 33D6 +8139EA38 33D7 +8139EA39 33D8 +8139EB30 33D9 +8139EB31 33DA +8139EB32 33DB +8139EB33 33DC +8139EB34 33DD +8139EB35 33DE +8139EB36 33DF +8139EB37 33E0 +8139EB38 33E1 +8139EB39 33E2 +8139EC30 33E3 +8139EC31 33E4 +8139EC32 33E5 +8139EC33 33E6 +8139EC34 33E7 +8139EC35 33E8 +8139EC36 33E9 +8139EC37 33EA +8139EC38 33EB +8139EC39 33EC +8139ED30 33ED +8139ED31 33EE +8139ED32 33EF +8139ED33 33F0 +8139ED34 33F1 +8139ED35 33F2 +8139ED36 33F3 +8139ED37 33F4 +8139ED38 33F5 +8139ED39 33F6 +8139EE30 33F7 +8139EE31 33F8 +8139EE32 33F9 +8139EE33 33FA +8139EE34 33FB +8139EE35 33FC +8139EE36 33FD +8139EE37 33FE +8139EE38 33FF +8139EE39 3400 +8139EF30 3401 +8139EF31 3402 +8139EF32 3403 +8139EF33 3404 +8139EF34 3405 +8139EF35 3406 +8139EF36 3407 +8139EF37 3408 +8139EF38 3409 +8139EF39 340A +8139F030 340B +8139F031 340C +8139F032 340D +8139F033 340E +8139F034 340F +8139F035 3410 +8139F036 3411 +8139F037 3412 +8139F038 3413 +8139F039 3414 +8139F130 3415 +8139F131 3416 +8139F132 3417 +8139F133 3418 +8139F134 3419 +8139F135 341A +8139F136 341B +8139F137 341C +8139F138 341D +8139F139 341E +8139F230 341F +8139F231 3420 +8139F232 3421 +8139F233 3422 +8139F234 3423 +8139F235 3424 +8139F236 3425 +8139F237 3426 +8139F238 3427 +8139F239 3428 +8139F330 3429 +8139F331 342A +8139F332 342B +8139F333 342C +8139F334 342D +8139F335 342E +8139F336 342F +8139F337 3430 +8139F338 3431 +8139F339 3432 +8139F430 3433 +8139F431 3434 +8139F432 3435 +8139F433 3436 +8139F434 3437 +8139F435 3438 +8139F436 3439 +8139F437 343A +8139F438 343B +8139F439 343C +8139F530 343D +8139F531 343E +8139F532 343F +8139F533 3440 +8139F534 3441 +8139F535 3442 +8139F536 3443 +8139F537 3444 +8139F538 3445 +8139F539 3446 +FE56 3447 +8139F630 3448 +8139F631 3449 +8139F632 344A +8139F633 344B +8139F634 344C +8139F635 344D +8139F636 344E +8139F637 344F +8139F638 3450 +8139F639 3451 +8139F730 3452 +8139F731 3453 +8139F732 3454 +8139F733 3455 +8139F734 3456 +8139F735 3457 +8139F736 3458 +8139F737 3459 +8139F738 345A +8139F739 345B +8139F830 345C +8139F831 345D +8139F832 345E +8139F833 345F +8139F834 3460 +8139F835 3461 +8139F836 3462 +8139F837 3463 +8139F838 3464 +8139F839 3465 +8139F930 3466 +8139F931 3467 +8139F932 3468 +8139F933 3469 +8139F934 346A +8139F935 346B +8139F936 346C +8139F937 346D +8139F938 346E +8139F939 346F +8139FA30 3470 +8139FA31 3471 +8139FA32 3472 +FE55 3473 +8139FA33 3474 +8139FA34 3475 +8139FA35 3476 +8139FA36 3477 +8139FA37 3478 +8139FA38 3479 +8139FA39 347A +8139FB30 347B +8139FB31 347C +8139FB32 347D +8139FB33 347E +8139FB34 347F +8139FB35 3480 +8139FB36 3481 +8139FB37 3482 +8139FB38 3483 +8139FB39 3484 +8139FC30 3485 +8139FC31 3486 +8139FC32 3487 +8139FC33 3488 +8139FC34 3489 +8139FC35 348A +8139FC36 348B +8139FC37 348C +8139FC38 348D +8139FC39 348E +8139FD30 348F +8139FD31 3490 +8139FD32 3491 +8139FD33 3492 +8139FD34 3493 +8139FD35 3494 +8139FD36 3495 +8139FD37 3496 +8139FD38 3497 +8139FD39 3498 +8139FE30 3499 +8139FE31 349A +8139FE32 349B +8139FE33 349C +8139FE34 349D +8139FE35 349E +8139FE36 349F +8139FE37 34A0 +8139FE38 34A1 +8139FE39 34A2 +82308130 34A3 +82308131 34A4 +82308132 34A5 +82308133 34A6 +82308134 34A7 +82308135 34A8 +82308136 34A9 +82308137 34AA +82308138 34AB +82308139 34AC +82308230 34AD +82308231 34AE +82308232 34AF +82308233 34B0 +82308234 34B1 +82308235 34B2 +82308236 34B3 +82308237 34B4 +82308238 34B5 +82308239 34B6 +82308330 34B7 +82308331 34B8 +82308332 34B9 +82308333 34BA +82308334 34BB +82308335 34BC +82308336 34BD +82308337 34BE +82308338 34BF +82308339 34C0 +82308430 34C1 +82308431 34C2 +82308432 34C3 +82308433 34C4 +82308434 34C5 +82308435 34C6 +82308436 34C7 +82308437 34C8 +82308438 34C9 +82308439 34CA +82308530 34CB +82308531 34CC +82308532 34CD +82308533 34CE +82308534 34CF +82308535 34D0 +82308536 34D1 +82308537 34D2 +82308538 34D3 +82308539 34D4 +82308630 34D5 +82308631 34D6 +82308632 34D7 +82308633 34D8 +82308634 34D9 +82308635 34DA +82308636 34DB +82308637 34DC +82308638 34DD +82308639 34DE +82308730 34DF +82308731 34E0 +82308732 34E1 +82308733 34E2 +82308734 34E3 +82308735 34E4 +82308736 34E5 +82308737 34E6 +82308738 34E7 +82308739 34E8 +82308830 34E9 +82308831 34EA +82308832 34EB +82308833 34EC +82308834 34ED +82308835 34EE +82308836 34EF +82308837 34F0 +82308838 34F1 +82308839 34F2 +82308930 34F3 +82308931 34F4 +82308932 34F5 +82308933 34F6 +82308934 34F7 +82308935 34F8 +82308936 34F9 +82308937 34FA +82308938 34FB +82308939 34FC +82308A30 34FD +82308A31 34FE +82308A32 34FF +82308A33 3500 +82308A34 3501 +82308A35 3502 +82308A36 3503 +82308A37 3504 +82308A38 3505 +82308A39 3506 +82308B30 3507 +82308B31 3508 +82308B32 3509 +82308B33 350A +82308B34 350B +82308B35 350C +82308B36 350D +82308B37 350E +82308B38 350F +82308B39 3510 +82308C30 3511 +82308C31 3512 +82308C32 3513 +82308C33 3514 +82308C34 3515 +82308C35 3516 +82308C36 3517 +82308C37 3518 +82308C38 3519 +82308C39 351A +82308D30 351B +82308D31 351C +82308D32 351D +82308D33 351E +82308D34 351F +82308D35 3520 +82308D36 3521 +82308D37 3522 +82308D38 3523 +82308D39 3524 +82308E30 3525 +82308E31 3526 +82308E32 3527 +82308E33 3528 +82308E34 3529 +82308E35 352A +82308E36 352B +82308E37 352C +82308E38 352D +82308E39 352E +82308F30 352F +82308F31 3530 +82308F32 3531 +82308F33 3532 +82308F34 3533 +82308F35 3534 +82308F36 3535 +82308F37 3536 +82308F38 3537 +82308F39 3538 +82309030 3539 +82309031 353A +82309032 353B +82309033 353C +82309034 353D +82309035 353E +82309036 353F +82309037 3540 +82309038 3541 +82309039 3542 +82309130 3543 +82309131 3544 +82309132 3545 +82309133 3546 +82309134 3547 +82309135 3548 +82309136 3549 +82309137 354A +82309138 354B +82309139 354C +82309230 354D +82309231 354E +82309232 354F +82309233 3550 +82309234 3551 +82309235 3552 +82309236 3553 +82309237 3554 +82309238 3555 +82309239 3556 +82309330 3557 +82309331 3558 +82309332 3559 +82309333 355A +82309334 355B +82309335 355C +82309336 355D +82309337 355E +82309338 355F +82309339 3560 +82309430 3561 +82309431 3562 +82309432 3563 +82309433 3564 +82309434 3565 +82309435 3566 +82309436 3567 +82309437 3568 +82309438 3569 +82309439 356A +82309530 356B +82309531 356C +82309532 356D +82309533 356E +82309534 356F +82309535 3570 +82309536 3571 +82309537 3572 +82309538 3573 +82309539 3574 +82309630 3575 +82309631 3576 +82309632 3577 +82309633 3578 +82309634 3579 +82309635 357A +82309636 357B +82309637 357C +82309638 357D +82309639 357E +82309730 357F +82309731 3580 +82309732 3581 +82309733 3582 +82309734 3583 +82309735 3584 +82309736 3585 +82309737 3586 +82309738 3587 +82309739 3588 +82309830 3589 +82309831 358A +82309832 358B +82309833 358C +82309834 358D +82309835 358E +82309836 358F +82309837 3590 +82309838 3591 +82309839 3592 +82309930 3593 +82309931 3594 +82309932 3595 +82309933 3596 +82309934 3597 +82309935 3598 +82309936 3599 +82309937 359A +82309938 359B +82309939 359C +82309A30 359D +FE5A 359E +82309A31 359F +82309A32 35A0 +82309A33 35A1 +82309A34 35A2 +82309A35 35A3 +82309A36 35A4 +82309A37 35A5 +82309A38 35A6 +82309A39 35A7 +82309B30 35A8 +82309B31 35A9 +82309B32 35AA +82309B33 35AB +82309B34 35AC +82309B35 35AD +82309B36 35AE +82309B37 35AF +82309B38 35B0 +82309B39 35B1 +82309C30 35B2 +82309C31 35B3 +82309C32 35B4 +82309C33 35B5 +82309C34 35B6 +82309C35 35B7 +82309C36 35B8 +82309C37 35B9 +82309C38 35BA +82309C39 35BB +82309D30 35BC +82309D31 35BD +82309D32 35BE +82309D33 35BF +82309D34 35C0 +82309D35 35C1 +82309D36 35C2 +82309D37 35C3 +82309D38 35C4 +82309D39 35C5 +82309E30 35C6 +82309E31 35C7 +82309E32 35C8 +82309E33 35C9 +82309E34 35CA +82309E35 35CB +82309E36 35CC +82309E37 35CD +82309E38 35CE +82309E39 35CF +82309F30 35D0 +82309F31 35D1 +82309F32 35D2 +82309F33 35D3 +82309F34 35D4 +82309F35 35D5 +82309F36 35D6 +82309F37 35D7 +82309F38 35D8 +82309F39 35D9 +8230A030 35DA +8230A031 35DB +8230A032 35DC +8230A033 35DD +8230A034 35DE +8230A035 35DF +8230A036 35E0 +8230A037 35E1 +8230A038 35E2 +8230A039 35E3 +8230A130 35E4 +8230A131 35E5 +8230A132 35E6 +8230A133 35E7 +8230A134 35E8 +8230A135 35E9 +8230A136 35EA +8230A137 35EB +8230A138 35EC +8230A139 35ED +8230A230 35EE +8230A231 35EF +8230A232 35F0 +8230A233 35F1 +8230A234 35F2 +8230A235 35F3 +8230A236 35F4 +8230A237 35F5 +8230A238 35F6 +8230A239 35F7 +8230A330 35F8 +8230A331 35F9 +8230A332 35FA +8230A333 35FB +8230A334 35FC +8230A335 35FD +8230A336 35FE +8230A337 35FF +8230A338 3600 +8230A339 3601 +8230A430 3602 +8230A431 3603 +8230A432 3604 +8230A433 3605 +8230A434 3606 +8230A435 3607 +8230A436 3608 +8230A437 3609 +8230A438 360A +8230A439 360B +8230A530 360C +8230A531 360D +FE5C 360E +8230A532 360F +8230A533 3610 +8230A534 3611 +8230A535 3612 +8230A536 3613 +8230A537 3614 +8230A538 3615 +8230A539 3616 +8230A630 3617 +8230A631 3618 +8230A632 3619 +FE5B 361A +8230A633 361B +8230A634 361C +8230A635 361D +8230A636 361E +8230A637 361F +8230A638 3620 +8230A639 3621 +8230A730 3622 +8230A731 3623 +8230A732 3624 +8230A733 3625 +8230A734 3626 +8230A735 3627 +8230A736 3628 +8230A737 3629 +8230A738 362A +8230A739 362B +8230A830 362C +8230A831 362D +8230A832 362E +8230A833 362F +8230A834 3630 +8230A835 3631 +8230A836 3632 +8230A837 3633 +8230A838 3634 +8230A839 3635 +8230A930 3636 +8230A931 3637 +8230A932 3638 +8230A933 3639 +8230A934 363A +8230A935 363B +8230A936 363C +8230A937 363D +8230A938 363E +8230A939 363F +8230AA30 3640 +8230AA31 3641 +8230AA32 3642 +8230AA33 3643 +8230AA34 3644 +8230AA35 3645 +8230AA36 3646 +8230AA37 3647 +8230AA38 3648 +8230AA39 3649 +8230AB30 364A +8230AB31 364B +8230AB32 364C +8230AB33 364D +8230AB34 364E +8230AB35 364F +8230AB36 3650 +8230AB37 3651 +8230AB38 3652 +8230AB39 3653 +8230AC30 3654 +8230AC31 3655 +8230AC32 3656 +8230AC33 3657 +8230AC34 3658 +8230AC35 3659 +8230AC36 365A +8230AC37 365B +8230AC38 365C +8230AC39 365D +8230AD30 365E +8230AD31 365F +8230AD32 3660 +8230AD33 3661 +8230AD34 3662 +8230AD35 3663 +8230AD36 3664 +8230AD37 3665 +8230AD38 3666 +8230AD39 3667 +8230AE30 3668 +8230AE31 3669 +8230AE32 366A +8230AE33 366B +8230AE34 366C +8230AE35 366D +8230AE36 366E +8230AE37 366F +8230AE38 3670 +8230AE39 3671 +8230AF30 3672 +8230AF31 3673 +8230AF32 3674 +8230AF33 3675 +8230AF34 3676 +8230AF35 3677 +8230AF36 3678 +8230AF37 3679 +8230AF38 367A +8230AF39 367B +8230B030 367C +8230B031 367D +8230B032 367E +8230B033 367F +8230B034 3680 +8230B035 3681 +8230B036 3682 +8230B037 3683 +8230B038 3684 +8230B039 3685 +8230B130 3686 +8230B131 3687 +8230B132 3688 +8230B133 3689 +8230B134 368A +8230B135 368B +8230B136 368C +8230B137 368D +8230B138 368E +8230B139 368F +8230B230 3690 +8230B231 3691 +8230B232 3692 +8230B233 3693 +8230B234 3694 +8230B235 3695 +8230B236 3696 +8230B237 3697 +8230B238 3698 +8230B239 3699 +8230B330 369A +8230B331 369B +8230B332 369C +8230B333 369D +8230B334 369E +8230B335 369F +8230B336 36A0 +8230B337 36A1 +8230B338 36A2 +8230B339 36A3 +8230B430 36A4 +8230B431 36A5 +8230B432 36A6 +8230B433 36A7 +8230B434 36A8 +8230B435 36A9 +8230B436 36AA +8230B437 36AB +8230B438 36AC +8230B439 36AD +8230B530 36AE +8230B531 36AF +8230B532 36B0 +8230B533 36B1 +8230B534 36B2 +8230B535 36B3 +8230B536 36B4 +8230B537 36B5 +8230B538 36B6 +8230B539 36B7 +8230B630 36B8 +8230B631 36B9 +8230B632 36BA +8230B633 36BB +8230B634 36BC +8230B635 36BD +8230B636 36BE +8230B637 36BF +8230B638 36C0 +8230B639 36C1 +8230B730 36C2 +8230B731 36C3 +8230B732 36C4 +8230B733 36C5 +8230B734 36C6 +8230B735 36C7 +8230B736 36C8 +8230B737 36C9 +8230B738 36CA +8230B739 36CB +8230B830 36CC +8230B831 36CD +8230B832 36CE +8230B833 36CF +8230B834 36D0 +8230B835 36D1 +8230B836 36D2 +8230B837 36D3 +8230B838 36D4 +8230B839 36D5 +8230B930 36D6 +8230B931 36D7 +8230B932 36D8 +8230B933 36D9 +8230B934 36DA +8230B935 36DB +8230B936 36DC +8230B937 36DD +8230B938 36DE +8230B939 36DF +8230BA30 36E0 +8230BA31 36E1 +8230BA32 36E2 +8230BA33 36E3 +8230BA34 36E4 +8230BA35 36E5 +8230BA36 36E6 +8230BA37 36E7 +8230BA38 36E8 +8230BA39 36E9 +8230BB30 36EA +8230BB31 36EB +8230BB32 36EC +8230BB33 36ED +8230BB34 36EE +8230BB35 36EF +8230BB36 36F0 +8230BB37 36F1 +8230BB38 36F2 +8230BB39 36F3 +8230BC30 36F4 +8230BC31 36F5 +8230BC32 36F6 +8230BC33 36F7 +8230BC34 36F8 +8230BC35 36F9 +8230BC36 36FA +8230BC37 36FB +8230BC38 36FC +8230BC39 36FD +8230BD30 36FE +8230BD31 36FF +8230BD32 3700 +8230BD33 3701 +8230BD34 3702 +8230BD35 3703 +8230BD36 3704 +8230BD37 3705 +8230BD38 3706 +8230BD39 3707 +8230BE30 3708 +8230BE31 3709 +8230BE32 370A +8230BE33 370B +8230BE34 370C +8230BE35 370D +8230BE36 370E +8230BE37 370F +8230BE38 3710 +8230BE39 3711 +8230BF30 3712 +8230BF31 3713 +8230BF32 3714 +8230BF33 3715 +8230BF34 3716 +8230BF35 3717 +8230BF36 3718 +8230BF37 3719 +8230BF38 371A +8230BF39 371B +8230C030 371C +8230C031 371D +8230C032 371E +8230C033 371F +8230C034 3720 +8230C035 3721 +8230C036 3722 +8230C037 3723 +8230C038 3724 +8230C039 3725 +8230C130 3726 +8230C131 3727 +8230C132 3728 +8230C133 3729 +8230C134 372A +8230C135 372B +8230C136 372C +8230C137 372D +8230C138 372E +8230C139 372F +8230C230 3730 +8230C231 3731 +8230C232 3732 +8230C233 3733 +8230C234 3734 +8230C235 3735 +8230C236 3736 +8230C237 3737 +8230C238 3738 +8230C239 3739 +8230C330 373A +8230C331 373B +8230C332 373C +8230C333 373D +8230C334 373E +8230C335 373F +8230C336 3740 +8230C337 3741 +8230C338 3742 +8230C339 3743 +8230C430 3744 +8230C431 3745 +8230C432 3746 +8230C433 3747 +8230C434 3748 +8230C435 3749 +8230C436 374A +8230C437 374B +8230C438 374C +8230C439 374D +8230C530 374E +8230C531 374F +8230C532 3750 +8230C533 3751 +8230C534 3752 +8230C535 3753 +8230C536 3754 +8230C537 3755 +8230C538 3756 +8230C539 3757 +8230C630 3758 +8230C631 3759 +8230C632 375A +8230C633 375B +8230C634 375C +8230C635 375D +8230C636 375E +8230C637 375F +8230C638 3760 +8230C639 3761 +8230C730 3762 +8230C731 3763 +8230C732 3764 +8230C733 3765 +8230C734 3766 +8230C735 3767 +8230C736 3768 +8230C737 3769 +8230C738 376A +8230C739 376B +8230C830 376C +8230C831 376D +8230C832 376E +8230C833 376F +8230C834 3770 +8230C835 3771 +8230C836 3772 +8230C837 3773 +8230C838 3774 +8230C839 3775 +8230C930 3776 +8230C931 3777 +8230C932 3778 +8230C933 3779 +8230C934 377A +8230C935 377B +8230C936 377C +8230C937 377D +8230C938 377E +8230C939 377F +8230CA30 3780 +8230CA31 3781 +8230CA32 3782 +8230CA33 3783 +8230CA34 3784 +8230CA35 3785 +8230CA36 3786 +8230CA37 3787 +8230CA38 3788 +8230CA39 3789 +8230CB30 378A +8230CB31 378B +8230CB32 378C +8230CB33 378D +8230CB34 378E +8230CB35 378F +8230CB36 3790 +8230CB37 3791 +8230CB38 3792 +8230CB39 3793 +8230CC30 3794 +8230CC31 3795 +8230CC32 3796 +8230CC33 3797 +8230CC34 3798 +8230CC35 3799 +8230CC36 379A +8230CC37 379B +8230CC38 379C +8230CC39 379D +8230CD30 379E +8230CD31 379F +8230CD32 37A0 +8230CD33 37A1 +8230CD34 37A2 +8230CD35 37A3 +8230CD36 37A4 +8230CD37 37A5 +8230CD38 37A6 +8230CD39 37A7 +8230CE30 37A8 +8230CE31 37A9 +8230CE32 37AA +8230CE33 37AB +8230CE34 37AC +8230CE35 37AD +8230CE36 37AE +8230CE37 37AF +8230CE38 37B0 +8230CE39 37B1 +8230CF30 37B2 +8230CF31 37B3 +8230CF32 37B4 +8230CF33 37B5 +8230CF34 37B6 +8230CF35 37B7 +8230CF36 37B8 +8230CF37 37B9 +8230CF38 37BA +8230CF39 37BB +8230D030 37BC +8230D031 37BD +8230D032 37BE +8230D033 37BF +8230D034 37C0 +8230D035 37C1 +8230D036 37C2 +8230D037 37C3 +8230D038 37C4 +8230D039 37C5 +8230D130 37C6 +8230D131 37C7 +8230D132 37C8 +8230D133 37C9 +8230D134 37CA +8230D135 37CB +8230D136 37CC +8230D137 37CD +8230D138 37CE +8230D139 37CF +8230D230 37D0 +8230D231 37D1 +8230D232 37D2 +8230D233 37D3 +8230D234 37D4 +8230D235 37D5 +8230D236 37D6 +8230D237 37D7 +8230D238 37D8 +8230D239 37D9 +8230D330 37DA +8230D331 37DB +8230D332 37DC +8230D333 37DD +8230D334 37DE +8230D335 37DF +8230D336 37E0 +8230D337 37E1 +8230D338 37E2 +8230D339 37E3 +8230D430 37E4 +8230D431 37E5 +8230D432 37E6 +8230D433 37E7 +8230D434 37E8 +8230D435 37E9 +8230D436 37EA +8230D437 37EB +8230D438 37EC +8230D439 37ED +8230D530 37EE +8230D531 37EF +8230D532 37F0 +8230D533 37F1 +8230D534 37F2 +8230D535 37F3 +8230D536 37F4 +8230D537 37F5 +8230D538 37F6 +8230D539 37F7 +8230D630 37F8 +8230D631 37F9 +8230D632 37FA +8230D633 37FB +8230D634 37FC +8230D635 37FD +8230D636 37FE +8230D637 37FF +8230D638 3800 +8230D639 3801 +8230D730 3802 +8230D731 3803 +8230D732 3804 +8230D733 3805 +8230D734 3806 +8230D735 3807 +8230D736 3808 +8230D737 3809 +8230D738 380A +8230D739 380B +8230D830 380C +8230D831 380D +8230D832 380E +8230D833 380F +8230D834 3810 +8230D835 3811 +8230D836 3812 +8230D837 3813 +8230D838 3814 +8230D839 3815 +8230D930 3816 +8230D931 3817 +8230D932 3818 +8230D933 3819 +8230D934 381A +8230D935 381B +8230D936 381C +8230D937 381D +8230D938 381E +8230D939 381F +8230DA30 3820 +8230DA31 3821 +8230DA32 3822 +8230DA33 3823 +8230DA34 3824 +8230DA35 3825 +8230DA36 3826 +8230DA37 3827 +8230DA38 3828 +8230DA39 3829 +8230DB30 382A +8230DB31 382B +8230DB32 382C +8230DB33 382D +8230DB34 382E +8230DB35 382F +8230DB36 3830 +8230DB37 3831 +8230DB38 3832 +8230DB39 3833 +8230DC30 3834 +8230DC31 3835 +8230DC32 3836 +8230DC33 3837 +8230DC34 3838 +8230DC35 3839 +8230DC36 383A +8230DC37 383B +8230DC38 383C +8230DC39 383D +8230DD30 383E +8230DD31 383F +8230DD32 3840 +8230DD33 3841 +8230DD34 3842 +8230DD35 3843 +8230DD36 3844 +8230DD37 3845 +8230DD38 3846 +8230DD39 3847 +8230DE30 3848 +8230DE31 3849 +8230DE32 384A +8230DE33 384B +8230DE34 384C +8230DE35 384D +8230DE36 384E +8230DE37 384F +8230DE38 3850 +8230DE39 3851 +8230DF30 3852 +8230DF31 3853 +8230DF32 3854 +8230DF33 3855 +8230DF34 3856 +8230DF35 3857 +8230DF36 3858 +8230DF37 3859 +8230DF38 385A +8230DF39 385B +8230E030 385C +8230E031 385D +8230E032 385E +8230E033 385F +8230E034 3860 +8230E035 3861 +8230E036 3862 +8230E037 3863 +8230E038 3864 +8230E039 3865 +8230E130 3866 +8230E131 3867 +8230E132 3868 +8230E133 3869 +8230E134 386A +8230E135 386B +8230E136 386C +8230E137 386D +8230E138 386E +8230E139 386F +8230E230 3870 +8230E231 3871 +8230E232 3872 +8230E233 3873 +8230E234 3874 +8230E235 3875 +8230E236 3876 +8230E237 3877 +8230E238 3878 +8230E239 3879 +8230E330 387A +8230E331 387B +8230E332 387C +8230E333 387D +8230E334 387E +8230E335 387F +8230E336 3880 +8230E337 3881 +8230E338 3882 +8230E339 3883 +8230E430 3884 +8230E431 3885 +8230E432 3886 +8230E433 3887 +8230E434 3888 +8230E435 3889 +8230E436 388A +8230E437 388B +8230E438 388C +8230E439 388D +8230E530 388E +8230E531 388F +8230E532 3890 +8230E533 3891 +8230E534 3892 +8230E535 3893 +8230E536 3894 +8230E537 3895 +8230E538 3896 +8230E539 3897 +8230E630 3898 +8230E631 3899 +8230E632 389A +8230E633 389B +8230E634 389C +8230E635 389D +8230E636 389E +8230E637 389F +8230E638 38A0 +8230E639 38A1 +8230E730 38A2 +8230E731 38A3 +8230E732 38A4 +8230E733 38A5 +8230E734 38A6 +8230E735 38A7 +8230E736 38A8 +8230E737 38A9 +8230E738 38AA +8230E739 38AB +8230E830 38AC +8230E831 38AD +8230E832 38AE +8230E833 38AF +8230E834 38B0 +8230E835 38B1 +8230E836 38B2 +8230E837 38B3 +8230E838 38B4 +8230E839 38B5 +8230E930 38B6 +8230E931 38B7 +8230E932 38B8 +8230E933 38B9 +8230E934 38BA +8230E935 38BB +8230E936 38BC +8230E937 38BD +8230E938 38BE +8230E939 38BF +8230EA30 38C0 +8230EA31 38C1 +8230EA32 38C2 +8230EA33 38C3 +8230EA34 38C4 +8230EA35 38C5 +8230EA36 38C6 +8230EA37 38C7 +8230EA38 38C8 +8230EA39 38C9 +8230EB30 38CA +8230EB31 38CB +8230EB32 38CC +8230EB33 38CD +8230EB34 38CE +8230EB35 38CF +8230EB36 38D0 +8230EB37 38D1 +8230EB38 38D2 +8230EB39 38D3 +8230EC30 38D4 +8230EC31 38D5 +8230EC32 38D6 +8230EC33 38D7 +8230EC34 38D8 +8230EC35 38D9 +8230EC36 38DA +8230EC37 38DB +8230EC38 38DC +8230EC39 38DD +8230ED30 38DE +8230ED31 38DF +8230ED32 38E0 +8230ED33 38E1 +8230ED34 38E2 +8230ED35 38E3 +8230ED36 38E4 +8230ED37 38E5 +8230ED38 38E6 +8230ED39 38E7 +8230EE30 38E8 +8230EE31 38E9 +8230EE32 38EA +8230EE33 38EB +8230EE34 38EC +8230EE35 38ED +8230EE36 38EE +8230EE37 38EF +8230EE38 38F0 +8230EE39 38F1 +8230EF30 38F2 +8230EF31 38F3 +8230EF32 38F4 +8230EF33 38F5 +8230EF34 38F6 +8230EF35 38F7 +8230EF36 38F8 +8230EF37 38F9 +8230EF38 38FA +8230EF39 38FB +8230F030 38FC +8230F031 38FD +8230F032 38FE +8230F033 38FF +8230F034 3900 +8230F035 3901 +8230F036 3902 +8230F037 3903 +8230F038 3904 +8230F039 3905 +8230F130 3906 +8230F131 3907 +8230F132 3908 +8230F133 3909 +8230F134 390A +8230F135 390B +8230F136 390C +8230F137 390D +8230F138 390E +8230F139 390F +8230F230 3910 +8230F231 3911 +8230F232 3912 +8230F233 3913 +8230F234 3914 +8230F235 3915 +8230F236 3916 +8230F237 3917 +FE60 3918 +8230F238 3919 +8230F239 391A +8230F330 391B +8230F331 391C +8230F332 391D +8230F333 391E +8230F334 391F +8230F335 3920 +8230F336 3921 +8230F337 3922 +8230F338 3923 +8230F339 3924 +8230F430 3925 +8230F431 3926 +8230F432 3927 +8230F433 3928 +8230F434 3929 +8230F435 392A +8230F436 392B +8230F437 392C +8230F438 392D +8230F439 392E +8230F530 392F +8230F531 3930 +8230F532 3931 +8230F533 3932 +8230F534 3933 +8230F535 3934 +8230F536 3935 +8230F537 3936 +8230F538 3937 +8230F539 3938 +8230F630 3939 +8230F631 393A +8230F632 393B +8230F633 393C +8230F634 393D +8230F635 393E +8230F636 393F +8230F637 3940 +8230F638 3941 +8230F639 3942 +8230F730 3943 +8230F731 3944 +8230F732 3945 +8230F733 3946 +8230F734 3947 +8230F735 3948 +8230F736 3949 +8230F737 394A +8230F738 394B +8230F739 394C +8230F830 394D +8230F831 394E +8230F832 394F +8230F833 3950 +8230F834 3951 +8230F835 3952 +8230F836 3953 +8230F837 3954 +8230F838 3955 +8230F839 3956 +8230F930 3957 +8230F931 3958 +8230F932 3959 +8230F933 395A +8230F934 395B +8230F935 395C +8230F936 395D +8230F937 395E +8230F938 395F +8230F939 3960 +8230FA30 3961 +8230FA31 3962 +8230FA32 3963 +8230FA33 3964 +8230FA34 3965 +8230FA35 3966 +8230FA36 3967 +8230FA37 3968 +8230FA38 3969 +8230FA39 396A +8230FB30 396B +8230FB31 396C +8230FB32 396D +FE5F 396E +8230FB33 396F +8230FB34 3970 +8230FB35 3971 +8230FB36 3972 +8230FB37 3973 +8230FB38 3974 +8230FB39 3975 +8230FC30 3976 +8230FC31 3977 +8230FC32 3978 +8230FC33 3979 +8230FC34 397A +8230FC35 397B +8230FC36 397C +8230FC37 397D +8230FC38 397E +8230FC39 397F +8230FD30 3980 +8230FD31 3981 +8230FD32 3982 +8230FD33 3983 +8230FD34 3984 +8230FD35 3985 +8230FD36 3986 +8230FD37 3987 +8230FD38 3988 +8230FD39 3989 +8230FE30 398A +8230FE31 398B +8230FE32 398C +8230FE33 398D +8230FE34 398E +8230FE35 398F +8230FE36 3990 +8230FE37 3991 +8230FE38 3992 +8230FE39 3993 +82318130 3994 +82318131 3995 +82318132 3996 +82318133 3997 +82318134 3998 +82318135 3999 +82318136 399A +82318137 399B +82318138 399C +82318139 399D +82318230 399E +82318231 399F +82318232 39A0 +82318233 39A1 +82318234 39A2 +82318235 39A3 +82318236 39A4 +82318237 39A5 +82318238 39A6 +82318239 39A7 +82318330 39A8 +82318331 39A9 +82318332 39AA +82318333 39AB +82318334 39AC +82318335 39AD +82318336 39AE +82318337 39AF +82318338 39B0 +82318339 39B1 +82318430 39B2 +82318431 39B3 +82318432 39B4 +82318433 39B5 +82318434 39B6 +82318435 39B7 +82318436 39B8 +82318437 39B9 +82318438 39BA +82318439 39BB +82318530 39BC +82318531 39BD +82318532 39BE +82318533 39BF +82318534 39C0 +82318535 39C1 +82318536 39C2 +82318537 39C3 +82318538 39C4 +82318539 39C5 +82318630 39C6 +82318631 39C7 +82318632 39C8 +82318633 39C9 +82318634 39CA +82318635 39CB +82318636 39CC +82318637 39CD +82318638 39CE +FE62 39CF +FE65 39D0 +82318639 39D1 +82318730 39D2 +82318731 39D3 +82318732 39D4 +82318733 39D5 +82318734 39D6 +82318735 39D7 +82318736 39D8 +82318737 39D9 +82318738 39DA +82318739 39DB +82318830 39DC +82318831 39DD +82318832 39DE +FE63 39DF +82318833 39E0 +82318834 39E1 +82318835 39E2 +82318836 39E3 +82318837 39E4 +82318838 39E5 +82318839 39E6 +82318930 39E7 +82318931 39E8 +82318932 39E9 +82318933 39EA +82318934 39EB +82318935 39EC +82318936 39ED +82318937 39EE +82318938 39EF +82318939 39F0 +82318A30 39F1 +82318A31 39F2 +82318A32 39F3 +82318A33 39F4 +82318A34 39F5 +82318A35 39F6 +82318A36 39F7 +82318A37 39F8 +82318A38 39F9 +82318A39 39FA +82318B30 39FB +82318B31 39FC +82318B32 39FD +82318B33 39FE +82318B34 39FF +82318B35 3A00 +82318B36 3A01 +82318B37 3A02 +82318B38 3A03 +82318B39 3A04 +82318C30 3A05 +82318C31 3A06 +82318C32 3A07 +82318C33 3A08 +82318C34 3A09 +82318C35 3A0A +82318C36 3A0B +82318C37 3A0C +82318C38 3A0D +82318C39 3A0E +82318D30 3A0F +82318D31 3A10 +82318D32 3A11 +82318D33 3A12 +82318D34 3A13 +82318D35 3A14 +82318D36 3A15 +82318D37 3A16 +82318D38 3A17 +82318D39 3A18 +82318E30 3A19 +82318E31 3A1A +82318E32 3A1B +82318E33 3A1C +82318E34 3A1D +82318E35 3A1E +82318E36 3A1F +82318E37 3A20 +82318E38 3A21 +82318E39 3A22 +82318F30 3A23 +82318F31 3A24 +82318F32 3A25 +82318F33 3A26 +82318F34 3A27 +82318F35 3A28 +82318F36 3A29 +82318F37 3A2A +82318F38 3A2B +82318F39 3A2C +82319030 3A2D +82319031 3A2E +82319032 3A2F +82319033 3A30 +82319034 3A31 +82319035 3A32 +82319036 3A33 +82319037 3A34 +82319038 3A35 +82319039 3A36 +82319130 3A37 +82319131 3A38 +82319132 3A39 +82319133 3A3A +82319134 3A3B +82319135 3A3C +82319136 3A3D +82319137 3A3E +82319138 3A3F +82319139 3A40 +82319230 3A41 +82319231 3A42 +82319232 3A43 +82319233 3A44 +82319234 3A45 +82319235 3A46 +82319236 3A47 +82319237 3A48 +82319238 3A49 +82319239 3A4A +82319330 3A4B +82319331 3A4C +82319332 3A4D +82319333 3A4E +82319334 3A4F +82319335 3A50 +82319336 3A51 +82319337 3A52 +82319338 3A53 +82319339 3A54 +82319430 3A55 +82319431 3A56 +82319432 3A57 +82319433 3A58 +82319434 3A59 +82319435 3A5A +82319436 3A5B +82319437 3A5C +82319438 3A5D +82319439 3A5E +82319530 3A5F +82319531 3A60 +82319532 3A61 +82319533 3A62 +82319534 3A63 +82319535 3A64 +82319536 3A65 +82319537 3A66 +82319538 3A67 +82319539 3A68 +82319630 3A69 +82319631 3A6A +82319632 3A6B +82319633 3A6C +82319634 3A6D +82319635 3A6E +82319636 3A6F +82319637 3A70 +82319638 3A71 +82319639 3A72 +FE64 3A73 +82319730 3A74 +82319731 3A75 +82319732 3A76 +82319733 3A77 +82319734 3A78 +82319735 3A79 +82319736 3A7A +82319737 3A7B +82319738 3A7C +82319739 3A7D +82319830 3A7E +82319831 3A7F +82319832 3A80 +82319833 3A81 +82319834 3A82 +82319835 3A83 +82319836 3A84 +82319837 3A85 +82319838 3A86 +82319839 3A87 +82319930 3A88 +82319931 3A89 +82319932 3A8A +82319933 3A8B +82319934 3A8C +82319935 3A8D +82319936 3A8E +82319937 3A8F +82319938 3A90 +82319939 3A91 +82319A30 3A92 +82319A31 3A93 +82319A32 3A94 +82319A33 3A95 +82319A34 3A96 +82319A35 3A97 +82319A36 3A98 +82319A37 3A99 +82319A38 3A9A +82319A39 3A9B +82319B30 3A9C +82319B31 3A9D +82319B32 3A9E +82319B33 3A9F +82319B34 3AA0 +82319B35 3AA1 +82319B36 3AA2 +82319B37 3AA3 +82319B38 3AA4 +82319B39 3AA5 +82319C30 3AA6 +82319C31 3AA7 +82319C32 3AA8 +82319C33 3AA9 +82319C34 3AAA +82319C35 3AAB +82319C36 3AAC +82319C37 3AAD +82319C38 3AAE +82319C39 3AAF +82319D30 3AB0 +82319D31 3AB1 +82319D32 3AB2 +82319D33 3AB3 +82319D34 3AB4 +82319D35 3AB5 +82319D36 3AB6 +82319D37 3AB7 +82319D38 3AB8 +82319D39 3AB9 +82319E30 3ABA +82319E31 3ABB +82319E32 3ABC +82319E33 3ABD +82319E34 3ABE +82319E35 3ABF +82319E36 3AC0 +82319E37 3AC1 +82319E38 3AC2 +82319E39 3AC3 +82319F30 3AC4 +82319F31 3AC5 +82319F32 3AC6 +82319F33 3AC7 +82319F34 3AC8 +82319F35 3AC9 +82319F36 3ACA +82319F37 3ACB +82319F38 3ACC +82319F39 3ACD +8231A030 3ACE +8231A031 3ACF +8231A032 3AD0 +8231A033 3AD1 +8231A034 3AD2 +8231A035 3AD3 +8231A036 3AD4 +8231A037 3AD5 +8231A038 3AD6 +8231A039 3AD7 +8231A130 3AD8 +8231A131 3AD9 +8231A132 3ADA +8231A133 3ADB +8231A134 3ADC +8231A135 3ADD +8231A136 3ADE +8231A137 3ADF +8231A138 3AE0 +8231A139 3AE1 +8231A230 3AE2 +8231A231 3AE3 +8231A232 3AE4 +8231A233 3AE5 +8231A234 3AE6 +8231A235 3AE7 +8231A236 3AE8 +8231A237 3AE9 +8231A238 3AEA +8231A239 3AEB +8231A330 3AEC +8231A331 3AED +8231A332 3AEE +8231A333 3AEF +8231A334 3AF0 +8231A335 3AF1 +8231A336 3AF2 +8231A337 3AF3 +8231A338 3AF4 +8231A339 3AF5 +8231A430 3AF6 +8231A431 3AF7 +8231A432 3AF8 +8231A433 3AF9 +8231A434 3AFA +8231A435 3AFB +8231A436 3AFC +8231A437 3AFD +8231A438 3AFE +8231A439 3AFF +8231A530 3B00 +8231A531 3B01 +8231A532 3B02 +8231A533 3B03 +8231A534 3B04 +8231A535 3B05 +8231A536 3B06 +8231A537 3B07 +8231A538 3B08 +8231A539 3B09 +8231A630 3B0A +8231A631 3B0B +8231A632 3B0C +8231A633 3B0D +8231A634 3B0E +8231A635 3B0F +8231A636 3B10 +8231A637 3B11 +8231A638 3B12 +8231A639 3B13 +8231A730 3B14 +8231A731 3B15 +8231A732 3B16 +8231A733 3B17 +8231A734 3B18 +8231A735 3B19 +8231A736 3B1A +8231A737 3B1B +8231A738 3B1C +8231A739 3B1D +8231A830 3B1E +8231A831 3B1F +8231A832 3B20 +8231A833 3B21 +8231A834 3B22 +8231A835 3B23 +8231A836 3B24 +8231A837 3B25 +8231A838 3B26 +8231A839 3B27 +8231A930 3B28 +8231A931 3B29 +8231A932 3B2A +8231A933 3B2B +8231A934 3B2C +8231A935 3B2D +8231A936 3B2E +8231A937 3B2F +8231A938 3B30 +8231A939 3B31 +8231AA30 3B32 +8231AA31 3B33 +8231AA32 3B34 +8231AA33 3B35 +8231AA34 3B36 +8231AA35 3B37 +8231AA36 3B38 +8231AA37 3B39 +8231AA38 3B3A +8231AA39 3B3B +8231AB30 3B3C +8231AB31 3B3D +8231AB32 3B3E +8231AB33 3B3F +8231AB34 3B40 +8231AB35 3B41 +8231AB36 3B42 +8231AB37 3B43 +8231AB38 3B44 +8231AB39 3B45 +8231AC30 3B46 +8231AC31 3B47 +8231AC32 3B48 +8231AC33 3B49 +8231AC34 3B4A +8231AC35 3B4B +8231AC36 3B4C +8231AC37 3B4D +FE68 3B4E +8231AC38 3B4F +8231AC39 3B50 +8231AD30 3B51 +8231AD31 3B52 +8231AD32 3B53 +8231AD33 3B54 +8231AD34 3B55 +8231AD35 3B56 +8231AD36 3B57 +8231AD37 3B58 +8231AD38 3B59 +8231AD39 3B5A +8231AE30 3B5B +8231AE31 3B5C +8231AE32 3B5D +8231AE33 3B5E +8231AE34 3B5F +8231AE35 3B60 +8231AE36 3B61 +8231AE37 3B62 +8231AE38 3B63 +8231AE39 3B64 +8231AF30 3B65 +8231AF31 3B66 +8231AF32 3B67 +8231AF33 3B68 +8231AF34 3B69 +8231AF35 3B6A +8231AF36 3B6B +8231AF37 3B6C +8231AF38 3B6D +8231AF39 3B6E +8231B030 3B6F +8231B031 3B70 +8231B032 3B71 +8231B033 3B72 +8231B034 3B73 +8231B035 3B74 +8231B036 3B75 +8231B037 3B76 +8231B038 3B77 +8231B039 3B78 +8231B130 3B79 +8231B131 3B7A +8231B132 3B7B +8231B133 3B7C +8231B134 3B7D +8231B135 3B7E +8231B136 3B7F +8231B137 3B80 +8231B138 3B81 +8231B139 3B82 +8231B230 3B83 +8231B231 3B84 +8231B232 3B85 +8231B233 3B86 +8231B234 3B87 +8231B235 3B88 +8231B236 3B89 +8231B237 3B8A +8231B238 3B8B +8231B239 3B8C +8231B330 3B8D +8231B331 3B8E +8231B332 3B8F +8231B333 3B90 +8231B334 3B91 +8231B335 3B92 +8231B336 3B93 +8231B337 3B94 +8231B338 3B95 +8231B339 3B96 +8231B430 3B97 +8231B431 3B98 +8231B432 3B99 +8231B433 3B9A +8231B434 3B9B +8231B435 3B9C +8231B436 3B9D +8231B437 3B9E +8231B438 3B9F +8231B439 3BA0 +8231B530 3BA1 +8231B531 3BA2 +8231B532 3BA3 +8231B533 3BA4 +8231B534 3BA5 +8231B535 3BA6 +8231B536 3BA7 +8231B537 3BA8 +8231B538 3BA9 +8231B539 3BAA +8231B630 3BAB +8231B631 3BAC +8231B632 3BAD +8231B633 3BAE +8231B634 3BAF +8231B635 3BB0 +8231B636 3BB1 +8231B637 3BB2 +8231B638 3BB3 +8231B639 3BB4 +8231B730 3BB5 +8231B731 3BB6 +8231B732 3BB7 +8231B733 3BB8 +8231B734 3BB9 +8231B735 3BBA +8231B736 3BBB +8231B737 3BBC +8231B738 3BBD +8231B739 3BBE +8231B830 3BBF +8231B831 3BC0 +8231B832 3BC1 +8231B833 3BC2 +8231B834 3BC3 +8231B835 3BC4 +8231B836 3BC5 +8231B837 3BC6 +8231B838 3BC7 +8231B839 3BC8 +8231B930 3BC9 +8231B931 3BCA +8231B932 3BCB +8231B933 3BCC +8231B934 3BCD +8231B935 3BCE +8231B936 3BCF +8231B937 3BD0 +8231B938 3BD1 +8231B939 3BD2 +8231BA30 3BD3 +8231BA31 3BD4 +8231BA32 3BD5 +8231BA33 3BD6 +8231BA34 3BD7 +8231BA35 3BD8 +8231BA36 3BD9 +8231BA37 3BDA +8231BA38 3BDB +8231BA39 3BDC +8231BB30 3BDD +8231BB31 3BDE +8231BB32 3BDF +8231BB33 3BE0 +8231BB34 3BE1 +8231BB35 3BE2 +8231BB36 3BE3 +8231BB37 3BE4 +8231BB38 3BE5 +8231BB39 3BE6 +8231BC30 3BE7 +8231BC31 3BE8 +8231BC32 3BE9 +8231BC33 3BEA +8231BC34 3BEB +8231BC35 3BEC +8231BC36 3BED +8231BC37 3BEE +8231BC38 3BEF +8231BC39 3BF0 +8231BD30 3BF1 +8231BD31 3BF2 +8231BD32 3BF3 +8231BD33 3BF4 +8231BD34 3BF5 +8231BD35 3BF6 +8231BD36 3BF7 +8231BD37 3BF8 +8231BD38 3BF9 +8231BD39 3BFA +8231BE30 3BFB +8231BE31 3BFC +8231BE32 3BFD +8231BE33 3BFE +8231BE34 3BFF +8231BE35 3C00 +8231BE36 3C01 +8231BE37 3C02 +8231BE38 3C03 +8231BE39 3C04 +8231BF30 3C05 +8231BF31 3C06 +8231BF32 3C07 +8231BF33 3C08 +8231BF34 3C09 +8231BF35 3C0A +8231BF36 3C0B +8231BF37 3C0C +8231BF38 3C0D +8231BF39 3C0E +8231C030 3C0F +8231C031 3C10 +8231C032 3C11 +8231C033 3C12 +8231C034 3C13 +8231C035 3C14 +8231C036 3C15 +8231C037 3C16 +8231C038 3C17 +8231C039 3C18 +8231C130 3C19 +8231C131 3C1A +8231C132 3C1B +8231C133 3C1C +8231C134 3C1D +8231C135 3C1E +8231C136 3C1F +8231C137 3C20 +8231C138 3C21 +8231C139 3C22 +8231C230 3C23 +8231C231 3C24 +8231C232 3C25 +8231C233 3C26 +8231C234 3C27 +8231C235 3C28 +8231C236 3C29 +8231C237 3C2A +8231C238 3C2B +8231C239 3C2C +8231C330 3C2D +8231C331 3C2E +8231C332 3C2F +8231C333 3C30 +8231C334 3C31 +8231C335 3C32 +8231C336 3C33 +8231C337 3C34 +8231C338 3C35 +8231C339 3C36 +8231C430 3C37 +8231C431 3C38 +8231C432 3C39 +8231C433 3C3A +8231C434 3C3B +8231C435 3C3C +8231C436 3C3D +8231C437 3C3E +8231C438 3C3F +8231C439 3C40 +8231C530 3C41 +8231C531 3C42 +8231C532 3C43 +8231C533 3C44 +8231C534 3C45 +8231C535 3C46 +8231C536 3C47 +8231C537 3C48 +8231C538 3C49 +8231C539 3C4A +8231C630 3C4B +8231C631 3C4C +8231C632 3C4D +8231C633 3C4E +8231C634 3C4F +8231C635 3C50 +8231C636 3C51 +8231C637 3C52 +8231C638 3C53 +8231C639 3C54 +8231C730 3C55 +8231C731 3C56 +8231C732 3C57 +8231C733 3C58 +8231C734 3C59 +8231C735 3C5A +8231C736 3C5B +8231C737 3C5C +8231C738 3C5D +8231C739 3C5E +8231C830 3C5F +8231C831 3C60 +8231C832 3C61 +8231C833 3C62 +8231C834 3C63 +8231C835 3C64 +8231C836 3C65 +8231C837 3C66 +8231C838 3C67 +8231C839 3C68 +8231C930 3C69 +8231C931 3C6A +8231C932 3C6B +8231C933 3C6C +8231C934 3C6D +FE69 3C6E +8231C935 3C6F +8231C936 3C70 +8231C937 3C71 +8231C938 3C72 +8231C939 3C73 +8231CA30 3C74 +8231CA31 3C75 +8231CA32 3C76 +8231CA33 3C77 +8231CA34 3C78 +8231CA35 3C79 +8231CA36 3C7A +8231CA37 3C7B +8231CA38 3C7C +8231CA39 3C7D +8231CB30 3C7E +8231CB31 3C7F +8231CB32 3C80 +8231CB33 3C81 +8231CB34 3C82 +8231CB35 3C83 +8231CB36 3C84 +8231CB37 3C85 +8231CB38 3C86 +8231CB39 3C87 +8231CC30 3C88 +8231CC31 3C89 +8231CC32 3C8A +8231CC33 3C8B +8231CC34 3C8C +8231CC35 3C8D +8231CC36 3C8E +8231CC37 3C8F +8231CC38 3C90 +8231CC39 3C91 +8231CD30 3C92 +8231CD31 3C93 +8231CD32 3C94 +8231CD33 3C95 +8231CD34 3C96 +8231CD35 3C97 +8231CD36 3C98 +8231CD37 3C99 +8231CD38 3C9A +8231CD39 3C9B +8231CE30 3C9C +8231CE31 3C9D +8231CE32 3C9E +8231CE33 3C9F +8231CE34 3CA0 +8231CE35 3CA1 +8231CE36 3CA2 +8231CE37 3CA3 +8231CE38 3CA4 +8231CE39 3CA5 +8231CF30 3CA6 +8231CF31 3CA7 +8231CF32 3CA8 +8231CF33 3CA9 +8231CF34 3CAA +8231CF35 3CAB +8231CF36 3CAC +8231CF37 3CAD +8231CF38 3CAE +8231CF39 3CAF +8231D030 3CB0 +8231D031 3CB1 +8231D032 3CB2 +8231D033 3CB3 +8231D034 3CB4 +8231D035 3CB5 +8231D036 3CB6 +8231D037 3CB7 +8231D038 3CB8 +8231D039 3CB9 +8231D130 3CBA +8231D131 3CBB +8231D132 3CBC +8231D133 3CBD +8231D134 3CBE +8231D135 3CBF +8231D136 3CC0 +8231D137 3CC1 +8231D138 3CC2 +8231D139 3CC3 +8231D230 3CC4 +8231D231 3CC5 +8231D232 3CC6 +8231D233 3CC7 +8231D234 3CC8 +8231D235 3CC9 +8231D236 3CCA +8231D237 3CCB +8231D238 3CCC +8231D239 3CCD +8231D330 3CCE +8231D331 3CCF +8231D332 3CD0 +8231D333 3CD1 +8231D334 3CD2 +8231D335 3CD3 +8231D336 3CD4 +8231D337 3CD5 +8231D338 3CD6 +8231D339 3CD7 +8231D430 3CD8 +8231D431 3CD9 +8231D432 3CDA +8231D433 3CDB +8231D434 3CDC +8231D435 3CDD +8231D436 3CDE +8231D437 3CDF +FE6A 3CE0 +8231D438 3CE1 +8231D439 3CE2 +8231D530 3CE3 +8231D531 3CE4 +8231D532 3CE5 +8231D533 3CE6 +8231D534 3CE7 +8231D535 3CE8 +8231D536 3CE9 +8231D537 3CEA +8231D538 3CEB +8231D539 3CEC +8231D630 3CED +8231D631 3CEE +8231D632 3CEF +8231D633 3CF0 +8231D634 3CF1 +8231D635 3CF2 +8231D636 3CF3 +8231D637 3CF4 +8231D638 3CF5 +8231D639 3CF6 +8231D730 3CF7 +8231D731 3CF8 +8231D732 3CF9 +8231D733 3CFA +8231D734 3CFB +8231D735 3CFC +8231D736 3CFD +8231D737 3CFE +8231D738 3CFF +8231D739 3D00 +8231D830 3D01 +8231D831 3D02 +8231D832 3D03 +8231D833 3D04 +8231D834 3D05 +8231D835 3D06 +8231D836 3D07 +8231D837 3D08 +8231D838 3D09 +8231D839 3D0A +8231D930 3D0B +8231D931 3D0C +8231D932 3D0D +8231D933 3D0E +8231D934 3D0F +8231D935 3D10 +8231D936 3D11 +8231D937 3D12 +8231D938 3D13 +8231D939 3D14 +8231DA30 3D15 +8231DA31 3D16 +8231DA32 3D17 +8231DA33 3D18 +8231DA34 3D19 +8231DA35 3D1A +8231DA36 3D1B +8231DA37 3D1C +8231DA38 3D1D +8231DA39 3D1E +8231DB30 3D1F +8231DB31 3D20 +8231DB32 3D21 +8231DB33 3D22 +8231DB34 3D23 +8231DB35 3D24 +8231DB36 3D25 +8231DB37 3D26 +8231DB38 3D27 +8231DB39 3D28 +8231DC30 3D29 +8231DC31 3D2A +8231DC32 3D2B +8231DC33 3D2C +8231DC34 3D2D +8231DC35 3D2E +8231DC36 3D2F +8231DC37 3D30 +8231DC38 3D31 +8231DC39 3D32 +8231DD30 3D33 +8231DD31 3D34 +8231DD32 3D35 +8231DD33 3D36 +8231DD34 3D37 +8231DD35 3D38 +8231DD36 3D39 +8231DD37 3D3A +8231DD38 3D3B +8231DD39 3D3C +8231DE30 3D3D +8231DE31 3D3E +8231DE32 3D3F +8231DE33 3D40 +8231DE34 3D41 +8231DE35 3D42 +8231DE36 3D43 +8231DE37 3D44 +8231DE38 3D45 +8231DE39 3D46 +8231DF30 3D47 +8231DF31 3D48 +8231DF32 3D49 +8231DF33 3D4A +8231DF34 3D4B +8231DF35 3D4C +8231DF36 3D4D +8231DF37 3D4E +8231DF38 3D4F +8231DF39 3D50 +8231E030 3D51 +8231E031 3D52 +8231E032 3D53 +8231E033 3D54 +8231E034 3D55 +8231E035 3D56 +8231E036 3D57 +8231E037 3D58 +8231E038 3D59 +8231E039 3D5A +8231E130 3D5B +8231E131 3D5C +8231E132 3D5D +8231E133 3D5E +8231E134 3D5F +8231E135 3D60 +8231E136 3D61 +8231E137 3D62 +8231E138 3D63 +8231E139 3D64 +8231E230 3D65 +8231E231 3D66 +8231E232 3D67 +8231E233 3D68 +8231E234 3D69 +8231E235 3D6A +8231E236 3D6B +8231E237 3D6C +8231E238 3D6D +8231E239 3D6E +8231E330 3D6F +8231E331 3D70 +8231E332 3D71 +8231E333 3D72 +8231E334 3D73 +8231E335 3D74 +8231E336 3D75 +8231E337 3D76 +8231E338 3D77 +8231E339 3D78 +8231E430 3D79 +8231E431 3D7A +8231E432 3D7B +8231E433 3D7C +8231E434 3D7D +8231E435 3D7E +8231E436 3D7F +8231E437 3D80 +8231E438 3D81 +8231E439 3D82 +8231E530 3D83 +8231E531 3D84 +8231E532 3D85 +8231E533 3D86 +8231E534 3D87 +8231E535 3D88 +8231E536 3D89 +8231E537 3D8A +8231E538 3D8B +8231E539 3D8C +8231E630 3D8D +8231E631 3D8E +8231E632 3D8F +8231E633 3D90 +8231E634 3D91 +8231E635 3D92 +8231E636 3D93 +8231E637 3D94 +8231E638 3D95 +8231E639 3D96 +8231E730 3D97 +8231E731 3D98 +8231E732 3D99 +8231E733 3D9A +8231E734 3D9B +8231E735 3D9C +8231E736 3D9D +8231E737 3D9E +8231E738 3D9F +8231E739 3DA0 +8231E830 3DA1 +8231E831 3DA2 +8231E832 3DA3 +8231E833 3DA4 +8231E834 3DA5 +8231E835 3DA6 +8231E836 3DA7 +8231E837 3DA8 +8231E838 3DA9 +8231E839 3DAA +8231E930 3DAB +8231E931 3DAC +8231E932 3DAD +8231E933 3DAE +8231E934 3DAF +8231E935 3DB0 +8231E936 3DB1 +8231E937 3DB2 +8231E938 3DB3 +8231E939 3DB4 +8231EA30 3DB5 +8231EA31 3DB6 +8231EA32 3DB7 +8231EA33 3DB8 +8231EA34 3DB9 +8231EA35 3DBA +8231EA36 3DBB +8231EA37 3DBC +8231EA38 3DBD +8231EA39 3DBE +8231EB30 3DBF +8231EB31 3DC0 +8231EB32 3DC1 +8231EB33 3DC2 +8231EB34 3DC3 +8231EB35 3DC4 +8231EB36 3DC5 +8231EB37 3DC6 +8231EB38 3DC7 +8231EB39 3DC8 +8231EC30 3DC9 +8231EC31 3DCA +8231EC32 3DCB +8231EC33 3DCC +8231EC34 3DCD +8231EC35 3DCE +8231EC36 3DCF +8231EC37 3DD0 +8231EC38 3DD1 +8231EC39 3DD2 +8231ED30 3DD3 +8231ED31 3DD4 +8231ED32 3DD5 +8231ED33 3DD6 +8231ED34 3DD7 +8231ED35 3DD8 +8231ED36 3DD9 +8231ED37 3DDA +8231ED38 3DDB +8231ED39 3DDC +8231EE30 3DDD +8231EE31 3DDE +8231EE32 3DDF +8231EE33 3DE0 +8231EE34 3DE1 +8231EE35 3DE2 +8231EE36 3DE3 +8231EE37 3DE4 +8231EE38 3DE5 +8231EE39 3DE6 +8231EF30 3DE7 +8231EF31 3DE8 +8231EF32 3DE9 +8231EF33 3DEA +8231EF34 3DEB +8231EF35 3DEC +8231EF36 3DED +8231EF37 3DEE +8231EF38 3DEF +8231EF39 3DF0 +8231F030 3DF1 +8231F031 3DF2 +8231F032 3DF3 +8231F033 3DF4 +8231F034 3DF5 +8231F035 3DF6 +8231F036 3DF7 +8231F037 3DF8 +8231F038 3DF9 +8231F039 3DFA +8231F130 3DFB +8231F131 3DFC +8231F132 3DFD +8231F133 3DFE +8231F134 3DFF +8231F135 3E00 +8231F136 3E01 +8231F137 3E02 +8231F138 3E03 +8231F139 3E04 +8231F230 3E05 +8231F231 3E06 +8231F232 3E07 +8231F233 3E08 +8231F234 3E09 +8231F235 3E0A +8231F236 3E0B +8231F237 3E0C +8231F238 3E0D +8231F239 3E0E +8231F330 3E0F +8231F331 3E10 +8231F332 3E11 +8231F333 3E12 +8231F334 3E13 +8231F335 3E14 +8231F336 3E15 +8231F337 3E16 +8231F338 3E17 +8231F339 3E18 +8231F430 3E19 +8231F431 3E1A +8231F432 3E1B +8231F433 3E1C +8231F434 3E1D +8231F435 3E1E +8231F436 3E1F +8231F437 3E20 +8231F438 3E21 +8231F439 3E22 +8231F530 3E23 +8231F531 3E24 +8231F532 3E25 +8231F533 3E26 +8231F534 3E27 +8231F535 3E28 +8231F536 3E29 +8231F537 3E2A +8231F538 3E2B +8231F539 3E2C +8231F630 3E2D +8231F631 3E2E +8231F632 3E2F +8231F633 3E30 +8231F634 3E31 +8231F635 3E32 +8231F636 3E33 +8231F637 3E34 +8231F638 3E35 +8231F639 3E36 +8231F730 3E37 +8231F731 3E38 +8231F732 3E39 +8231F733 3E3A +8231F734 3E3B +8231F735 3E3C +8231F736 3E3D +8231F737 3E3E +8231F738 3E3F +8231F739 3E40 +8231F830 3E41 +8231F831 3E42 +8231F832 3E43 +8231F833 3E44 +8231F834 3E45 +8231F835 3E46 +8231F836 3E47 +8231F837 3E48 +8231F838 3E49 +8231F839 3E4A +8231F930 3E4B +8231F931 3E4C +8231F932 3E4D +8231F933 3E4E +8231F934 3E4F +8231F935 3E50 +8231F936 3E51 +8231F937 3E52 +8231F938 3E53 +8231F939 3E54 +8231FA30 3E55 +8231FA31 3E56 +8231FA32 3E57 +8231FA33 3E58 +8231FA34 3E59 +8231FA35 3E5A +8231FA36 3E5B +8231FA37 3E5C +8231FA38 3E5D +8231FA39 3E5E +8231FB30 3E5F +8231FB31 3E60 +8231FB32 3E61 +8231FB33 3E62 +8231FB34 3E63 +8231FB35 3E64 +8231FB36 3E65 +8231FB37 3E66 +8231FB38 3E67 +8231FB39 3E68 +8231FC30 3E69 +8231FC31 3E6A +8231FC32 3E6B +8231FC33 3E6C +8231FC34 3E6D +8231FC35 3E6E +8231FC36 3E6F +8231FC37 3E70 +8231FC38 3E71 +8231FC39 3E72 +8231FD30 3E73 +8231FD31 3E74 +8231FD32 3E75 +8231FD33 3E76 +8231FD34 3E77 +8231FD35 3E78 +8231FD36 3E79 +8231FD37 3E7A +8231FD38 3E7B +8231FD39 3E7C +8231FE30 3E7D +8231FE31 3E7E +8231FE32 3E7F +8231FE33 3E80 +8231FE34 3E81 +8231FE35 3E82 +8231FE36 3E83 +8231FE37 3E84 +8231FE38 3E85 +8231FE39 3E86 +82328130 3E87 +82328131 3E88 +82328132 3E89 +82328133 3E8A +82328134 3E8B +82328135 3E8C +82328136 3E8D +82328137 3E8E +82328138 3E8F +82328139 3E90 +82328230 3E91 +82328231 3E92 +82328232 3E93 +82328233 3E94 +82328234 3E95 +82328235 3E96 +82328236 3E97 +82328237 3E98 +82328238 3E99 +82328239 3E9A +82328330 3E9B +82328331 3E9C +82328332 3E9D +82328333 3E9E +82328334 3E9F +82328335 3EA0 +82328336 3EA1 +82328337 3EA2 +82328338 3EA3 +82328339 3EA4 +82328430 3EA5 +82328431 3EA6 +82328432 3EA7 +82328433 3EA8 +82328434 3EA9 +82328435 3EAA +82328436 3EAB +82328437 3EAC +82328438 3EAD +82328439 3EAE +82328530 3EAF +82328531 3EB0 +82328532 3EB1 +82328533 3EB2 +82328534 3EB3 +82328535 3EB4 +82328536 3EB5 +82328537 3EB6 +82328538 3EB7 +82328539 3EB8 +82328630 3EB9 +82328631 3EBA +82328632 3EBB +82328633 3EBC +82328634 3EBD +82328635 3EBE +82328636 3EBF +82328637 3EC0 +82328638 3EC1 +82328639 3EC2 +82328730 3EC3 +82328731 3EC4 +82328732 3EC5 +82328733 3EC6 +82328734 3EC7 +82328735 3EC8 +82328736 3EC9 +82328737 3ECA +82328738 3ECB +82328739 3ECC +82328830 3ECD +82328831 3ECE +82328832 3ECF +82328833 3ED0 +82328834 3ED1 +82328835 3ED2 +82328836 3ED3 +82328837 3ED4 +82328838 3ED5 +82328839 3ED6 +82328930 3ED7 +82328931 3ED8 +82328932 3ED9 +82328933 3EDA +82328934 3EDB +82328935 3EDC +82328936 3EDD +82328937 3EDE +82328938 3EDF +82328939 3EE0 +82328A30 3EE1 +82328A31 3EE2 +82328A32 3EE3 +82328A33 3EE4 +82328A34 3EE5 +82328A35 3EE6 +82328A36 3EE7 +82328A37 3EE8 +82328A38 3EE9 +82328A39 3EEA +82328B30 3EEB +82328B31 3EEC +82328B32 3EED +82328B33 3EEE +82328B34 3EEF +82328B35 3EF0 +82328B36 3EF1 +82328B37 3EF2 +82328B38 3EF3 +82328B39 3EF4 +82328C30 3EF5 +82328C31 3EF6 +82328C32 3EF7 +82328C33 3EF8 +82328C34 3EF9 +82328C35 3EFA +82328C36 3EFB +82328C37 3EFC +82328C38 3EFD +82328C39 3EFE +82328D30 3EFF +82328D31 3F00 +82328D32 3F01 +82328D33 3F02 +82328D34 3F03 +82328D35 3F04 +82328D36 3F05 +82328D37 3F06 +82328D38 3F07 +82328D39 3F08 +82328E30 3F09 +82328E31 3F0A +82328E32 3F0B +82328E33 3F0C +82328E34 3F0D +82328E35 3F0E +82328E36 3F0F +82328E37 3F10 +82328E38 3F11 +82328E39 3F12 +82328F30 3F13 +82328F31 3F14 +82328F32 3F15 +82328F33 3F16 +82328F34 3F17 +82328F35 3F18 +82328F36 3F19 +82328F37 3F1A +82328F38 3F1B +82328F39 3F1C +82329030 3F1D +82329031 3F1E +82329032 3F1F +82329033 3F20 +82329034 3F21 +82329035 3F22 +82329036 3F23 +82329037 3F24 +82329038 3F25 +82329039 3F26 +82329130 3F27 +82329131 3F28 +82329132 3F29 +82329133 3F2A +82329134 3F2B +82329135 3F2C +82329136 3F2D +82329137 3F2E +82329138 3F2F +82329139 3F30 +82329230 3F31 +82329231 3F32 +82329232 3F33 +82329233 3F34 +82329234 3F35 +82329235 3F36 +82329236 3F37 +82329237 3F38 +82329238 3F39 +82329239 3F3A +82329330 3F3B +82329331 3F3C +82329332 3F3D +82329333 3F3E +82329334 3F3F +82329335 3F40 +82329336 3F41 +82329337 3F42 +82329338 3F43 +82329339 3F44 +82329430 3F45 +82329431 3F46 +82329432 3F47 +82329433 3F48 +82329434 3F49 +82329435 3F4A +82329436 3F4B +82329437 3F4C +82329438 3F4D +82329439 3F4E +82329530 3F4F +82329531 3F50 +82329532 3F51 +82329533 3F52 +82329534 3F53 +82329535 3F54 +82329536 3F55 +82329537 3F56 +82329538 3F57 +82329539 3F58 +82329630 3F59 +82329631 3F5A +82329632 3F5B +82329633 3F5C +82329634 3F5D +82329635 3F5E +82329636 3F5F +82329637 3F60 +82329638 3F61 +82329639 3F62 +82329730 3F63 +82329731 3F64 +82329732 3F65 +82329733 3F66 +82329734 3F67 +82329735 3F68 +82329736 3F69 +82329737 3F6A +82329738 3F6B +82329739 3F6C +82329830 3F6D +82329831 3F6E +82329832 3F6F +82329833 3F70 +82329834 3F71 +82329835 3F72 +82329836 3F73 +82329837 3F74 +82329838 3F75 +82329839 3F76 +82329930 3F77 +82329931 3F78 +82329932 3F79 +82329933 3F7A +82329934 3F7B +82329935 3F7C +82329936 3F7D +82329937 3F7E +82329938 3F7F +82329939 3F80 +82329A30 3F81 +82329A31 3F82 +82329A32 3F83 +82329A33 3F84 +82329A34 3F85 +82329A35 3F86 +82329A36 3F87 +82329A37 3F88 +82329A38 3F89 +82329A39 3F8A +82329B30 3F8B +82329B31 3F8C +82329B32 3F8D +82329B33 3F8E +82329B34 3F8F +82329B35 3F90 +82329B36 3F91 +82329B37 3F92 +82329B38 3F93 +82329B39 3F94 +82329C30 3F95 +82329C31 3F96 +82329C32 3F97 +82329C33 3F98 +82329C34 3F99 +82329C35 3F9A +82329C36 3F9B +82329C37 3F9C +82329C38 3F9D +82329C39 3F9E +82329D30 3F9F +82329D31 3FA0 +82329D32 3FA1 +82329D33 3FA2 +82329D34 3FA3 +82329D35 3FA4 +82329D36 3FA5 +82329D37 3FA6 +82329D38 3FA7 +82329D39 3FA8 +82329E30 3FA9 +82329E31 3FAA +82329E32 3FAB +82329E33 3FAC +82329E34 3FAD +82329E35 3FAE +82329E36 3FAF +82329E37 3FB0 +82329E38 3FB1 +82329E39 3FB2 +82329F30 3FB3 +82329F31 3FB4 +82329F32 3FB5 +82329F33 3FB6 +82329F34 3FB7 +82329F35 3FB8 +82329F36 3FB9 +82329F37 3FBA +82329F38 3FBB +82329F39 3FBC +8232A030 3FBD +8232A031 3FBE +8232A032 3FBF +8232A033 3FC0 +8232A034 3FC1 +8232A035 3FC2 +8232A036 3FC3 +8232A037 3FC4 +8232A038 3FC5 +8232A039 3FC6 +8232A130 3FC7 +8232A131 3FC8 +8232A132 3FC9 +8232A133 3FCA +8232A134 3FCB +8232A135 3FCC +8232A136 3FCD +8232A137 3FCE +8232A138 3FCF +8232A139 3FD0 +8232A230 3FD1 +8232A231 3FD2 +8232A232 3FD3 +8232A233 3FD4 +8232A234 3FD5 +8232A235 3FD6 +8232A236 3FD7 +8232A237 3FD8 +8232A238 3FD9 +8232A239 3FDA +8232A330 3FDB +8232A331 3FDC +8232A332 3FDD +8232A333 3FDE +8232A334 3FDF +8232A335 3FE0 +8232A336 3FE1 +8232A337 3FE2 +8232A338 3FE3 +8232A339 3FE4 +8232A430 3FE5 +8232A431 3FE6 +8232A432 3FE7 +8232A433 3FE8 +8232A434 3FE9 +8232A435 3FEA +8232A436 3FEB +8232A437 3FEC +8232A438 3FED +8232A439 3FEE +8232A530 3FEF +8232A531 3FF0 +8232A532 3FF1 +8232A533 3FF2 +8232A534 3FF3 +8232A535 3FF4 +8232A536 3FF5 +8232A537 3FF6 +8232A538 3FF7 +8232A539 3FF8 +8232A630 3FF9 +8232A631 3FFA +8232A632 3FFB +8232A633 3FFC +8232A634 3FFD +8232A635 3FFE +8232A636 3FFF +8232A637 4000 +8232A638 4001 +8232A639 4002 +8232A730 4003 +8232A731 4004 +8232A732 4005 +8232A733 4006 +8232A734 4007 +8232A735 4008 +8232A736 4009 +8232A737 400A +8232A738 400B +8232A739 400C +8232A830 400D +8232A831 400E +8232A832 400F +8232A833 4010 +8232A834 4011 +8232A835 4012 +8232A836 4013 +8232A837 4014 +8232A838 4015 +8232A839 4016 +8232A930 4017 +8232A931 4018 +8232A932 4019 +8232A933 401A +8232A934 401B +8232A935 401C +8232A936 401D +8232A937 401E +8232A938 401F +8232A939 4020 +8232AA30 4021 +8232AA31 4022 +8232AA32 4023 +8232AA33 4024 +8232AA34 4025 +8232AA35 4026 +8232AA36 4027 +8232AA37 4028 +8232AA38 4029 +8232AA39 402A +8232AB30 402B +8232AB31 402C +8232AB32 402D +8232AB33 402E +8232AB34 402F +8232AB35 4030 +8232AB36 4031 +8232AB37 4032 +8232AB38 4033 +8232AB39 4034 +8232AC30 4035 +8232AC31 4036 +8232AC32 4037 +8232AC33 4038 +8232AC34 4039 +8232AC35 403A +8232AC36 403B +8232AC37 403C +8232AC38 403D +8232AC39 403E +8232AD30 403F +8232AD31 4040 +8232AD32 4041 +8232AD33 4042 +8232AD34 4043 +8232AD35 4044 +8232AD36 4045 +8232AD37 4046 +8232AD38 4047 +8232AD39 4048 +8232AE30 4049 +8232AE31 404A +8232AE32 404B +8232AE33 404C +8232AE34 404D +8232AE35 404E +8232AE36 404F +8232AE37 4050 +8232AE38 4051 +8232AE39 4052 +8232AF30 4053 +8232AF31 4054 +8232AF32 4055 +FE6F 4056 +8232AF33 4057 +8232AF34 4058 +8232AF35 4059 +8232AF36 405A +8232AF37 405B +8232AF38 405C +8232AF39 405D +8232B030 405E +8232B031 405F +8232B032 4060 +8232B033 4061 +8232B034 4062 +8232B035 4063 +8232B036 4064 +8232B037 4065 +8232B038 4066 +8232B039 4067 +8232B130 4068 +8232B131 4069 +8232B132 406A +8232B133 406B +8232B134 406C +8232B135 406D +8232B136 406E +8232B137 406F +8232B138 4070 +8232B139 4071 +8232B230 4072 +8232B231 4073 +8232B232 4074 +8232B233 4075 +8232B234 4076 +8232B235 4077 +8232B236 4078 +8232B237 4079 +8232B238 407A +8232B239 407B +8232B330 407C +8232B331 407D +8232B332 407E +8232B333 407F +8232B334 4080 +8232B335 4081 +8232B336 4082 +8232B337 4083 +8232B338 4084 +8232B339 4085 +8232B430 4086 +8232B431 4087 +8232B432 4088 +8232B433 4089 +8232B434 408A +8232B435 408B +8232B436 408C +8232B437 408D +8232B438 408E +8232B439 408F +8232B530 4090 +8232B531 4091 +8232B532 4092 +8232B533 4093 +8232B534 4094 +8232B535 4095 +8232B536 4096 +8232B537 4097 +8232B538 4098 +8232B539 4099 +8232B630 409A +8232B631 409B +8232B632 409C +8232B633 409D +8232B634 409E +8232B635 409F +8232B636 40A0 +8232B637 40A1 +8232B638 40A2 +8232B639 40A3 +8232B730 40A4 +8232B731 40A5 +8232B732 40A6 +8232B733 40A7 +8232B734 40A8 +8232B735 40A9 +8232B736 40AA +8232B737 40AB +8232B738 40AC +8232B739 40AD +8232B830 40AE +8232B831 40AF +8232B832 40B0 +8232B833 40B1 +8232B834 40B2 +8232B835 40B3 +8232B836 40B4 +8232B837 40B5 +8232B838 40B6 +8232B839 40B7 +8232B930 40B8 +8232B931 40B9 +8232B932 40BA +8232B933 40BB +8232B934 40BC +8232B935 40BD +8232B936 40BE +8232B937 40BF +8232B938 40C0 +8232B939 40C1 +8232BA30 40C2 +8232BA31 40C3 +8232BA32 40C4 +8232BA33 40C5 +8232BA34 40C6 +8232BA35 40C7 +8232BA36 40C8 +8232BA37 40C9 +8232BA38 40CA +8232BA39 40CB +8232BB30 40CC +8232BB31 40CD +8232BB32 40CE +8232BB33 40CF +8232BB34 40D0 +8232BB35 40D1 +8232BB36 40D2 +8232BB37 40D3 +8232BB38 40D4 +8232BB39 40D5 +8232BC30 40D6 +8232BC31 40D7 +8232BC32 40D8 +8232BC33 40D9 +8232BC34 40DA +8232BC35 40DB +8232BC36 40DC +8232BC37 40DD +8232BC38 40DE +8232BC39 40DF +8232BD30 40E0 +8232BD31 40E1 +8232BD32 40E2 +8232BD33 40E3 +8232BD34 40E4 +8232BD35 40E5 +8232BD36 40E6 +8232BD37 40E7 +8232BD38 40E8 +8232BD39 40E9 +8232BE30 40EA +8232BE31 40EB +8232BE32 40EC +8232BE33 40ED +8232BE34 40EE +8232BE35 40EF +8232BE36 40F0 +8232BE37 40F1 +8232BE38 40F2 +8232BE39 40F3 +8232BF30 40F4 +8232BF31 40F5 +8232BF32 40F6 +8232BF33 40F7 +8232BF34 40F8 +8232BF35 40F9 +8232BF36 40FA +8232BF37 40FB +8232BF38 40FC +8232BF39 40FD +8232C030 40FE +8232C031 40FF +8232C032 4100 +8232C033 4101 +8232C034 4102 +8232C035 4103 +8232C036 4104 +8232C037 4105 +8232C038 4106 +8232C039 4107 +8232C130 4108 +8232C131 4109 +8232C132 410A +8232C133 410B +8232C134 410C +8232C135 410D +8232C136 410E +8232C137 410F +8232C138 4110 +8232C139 4111 +8232C230 4112 +8232C231 4113 +8232C232 4114 +8232C233 4115 +8232C234 4116 +8232C235 4117 +8232C236 4118 +8232C237 4119 +8232C238 411A +8232C239 411B +8232C330 411C +8232C331 411D +8232C332 411E +8232C333 411F +8232C334 4120 +8232C335 4121 +8232C336 4122 +8232C337 4123 +8232C338 4124 +8232C339 4125 +8232C430 4126 +8232C431 4127 +8232C432 4128 +8232C433 4129 +8232C434 412A +8232C435 412B +8232C436 412C +8232C437 412D +8232C438 412E +8232C439 412F +8232C530 4130 +8232C531 4131 +8232C532 4132 +8232C533 4133 +8232C534 4134 +8232C535 4135 +8232C536 4136 +8232C537 4137 +8232C538 4138 +8232C539 4139 +8232C630 413A +8232C631 413B +8232C632 413C +8232C633 413D +8232C634 413E +8232C635 413F +8232C636 4140 +8232C637 4141 +8232C638 4142 +8232C639 4143 +8232C730 4144 +8232C731 4145 +8232C732 4146 +8232C733 4147 +8232C734 4148 +8232C735 4149 +8232C736 414A +8232C737 414B +8232C738 414C +8232C739 414D +8232C830 414E +8232C831 414F +8232C832 4150 +8232C833 4151 +8232C834 4152 +8232C835 4153 +8232C836 4154 +8232C837 4155 +8232C838 4156 +8232C839 4157 +8232C930 4158 +8232C931 4159 +8232C932 415A +8232C933 415B +8232C934 415C +8232C935 415D +8232C936 415E +FE70 415F +8232C937 4160 +8232C938 4161 +8232C939 4162 +8232CA30 4163 +8232CA31 4164 +8232CA32 4165 +8232CA33 4166 +8232CA34 4167 +8232CA35 4168 +8232CA36 4169 +8232CA37 416A +8232CA38 416B +8232CA39 416C +8232CB30 416D +8232CB31 416E +8232CB32 416F +8232CB33 4170 +8232CB34 4171 +8232CB35 4172 +8232CB36 4173 +8232CB37 4174 +8232CB38 4175 +8232CB39 4176 +8232CC30 4177 +8232CC31 4178 +8232CC32 4179 +8232CC33 417A +8232CC34 417B +8232CC35 417C +8232CC36 417D +8232CC37 417E +8232CC38 417F +8232CC39 4180 +8232CD30 4181 +8232CD31 4182 +8232CD32 4183 +8232CD33 4184 +8232CD34 4185 +8232CD35 4186 +8232CD36 4187 +8232CD37 4188 +8232CD38 4189 +8232CD39 418A +8232CE30 418B +8232CE31 418C +8232CE32 418D +8232CE33 418E +8232CE34 418F +8232CE35 4190 +8232CE36 4191 +8232CE37 4192 +8232CE38 4193 +8232CE39 4194 +8232CF30 4195 +8232CF31 4196 +8232CF32 4197 +8232CF33 4198 +8232CF34 4199 +8232CF35 419A +8232CF36 419B +8232CF37 419C +8232CF38 419D +8232CF39 419E +8232D030 419F +8232D031 41A0 +8232D032 41A1 +8232D033 41A2 +8232D034 41A3 +8232D035 41A4 +8232D036 41A5 +8232D037 41A6 +8232D038 41A7 +8232D039 41A8 +8232D130 41A9 +8232D131 41AA +8232D132 41AB +8232D133 41AC +8232D134 41AD +8232D135 41AE +8232D136 41AF +8232D137 41B0 +8232D138 41B1 +8232D139 41B2 +8232D230 41B3 +8232D231 41B4 +8232D232 41B5 +8232D233 41B6 +8232D234 41B7 +8232D235 41B8 +8232D236 41B9 +8232D237 41BA +8232D238 41BB +8232D239 41BC +8232D330 41BD +8232D331 41BE +8232D332 41BF +8232D333 41C0 +8232D334 41C1 +8232D335 41C2 +8232D336 41C3 +8232D337 41C4 +8232D338 41C5 +8232D339 41C6 +8232D430 41C7 +8232D431 41C8 +8232D432 41C9 +8232D433 41CA +8232D434 41CB +8232D435 41CC +8232D436 41CD +8232D437 41CE +8232D438 41CF +8232D439 41D0 +8232D530 41D1 +8232D531 41D2 +8232D532 41D3 +8232D533 41D4 +8232D534 41D5 +8232D535 41D6 +8232D536 41D7 +8232D537 41D8 +8232D538 41D9 +8232D539 41DA +8232D630 41DB +8232D631 41DC +8232D632 41DD +8232D633 41DE +8232D634 41DF +8232D635 41E0 +8232D636 41E1 +8232D637 41E2 +8232D638 41E3 +8232D639 41E4 +8232D730 41E5 +8232D731 41E6 +8232D732 41E7 +8232D733 41E8 +8232D734 41E9 +8232D735 41EA +8232D736 41EB +8232D737 41EC +8232D738 41ED +8232D739 41EE +8232D830 41EF +8232D831 41F0 +8232D832 41F1 +8232D833 41F2 +8232D834 41F3 +8232D835 41F4 +8232D836 41F5 +8232D837 41F6 +8232D838 41F7 +8232D839 41F8 +8232D930 41F9 +8232D931 41FA +8232D932 41FB +8232D933 41FC +8232D934 41FD +8232D935 41FE +8232D936 41FF +8232D937 4200 +8232D938 4201 +8232D939 4202 +8232DA30 4203 +8232DA31 4204 +8232DA32 4205 +8232DA33 4206 +8232DA34 4207 +8232DA35 4208 +8232DA36 4209 +8232DA37 420A +8232DA38 420B +8232DA39 420C +8232DB30 420D +8232DB31 420E +8232DB32 420F +8232DB33 4210 +8232DB34 4211 +8232DB35 4212 +8232DB36 4213 +8232DB37 4214 +8232DB38 4215 +8232DB39 4216 +8232DC30 4217 +8232DC31 4218 +8232DC32 4219 +8232DC33 421A +8232DC34 421B +8232DC35 421C +8232DC36 421D +8232DC37 421E +8232DC38 421F +8232DC39 4220 +8232DD30 4221 +8232DD31 4222 +8232DD32 4223 +8232DD33 4224 +8232DD34 4225 +8232DD35 4226 +8232DD36 4227 +8232DD37 4228 +8232DD38 4229 +8232DD39 422A +8232DE30 422B +8232DE31 422C +8232DE32 422D +8232DE33 422E +8232DE34 422F +8232DE35 4230 +8232DE36 4231 +8232DE37 4232 +8232DE38 4233 +8232DE39 4234 +8232DF30 4235 +8232DF31 4236 +8232DF32 4237 +8232DF33 4238 +8232DF34 4239 +8232DF35 423A +8232DF36 423B +8232DF37 423C +8232DF38 423D +8232DF39 423E +8232E030 423F +8232E031 4240 +8232E032 4241 +8232E033 4242 +8232E034 4243 +8232E035 4244 +8232E036 4245 +8232E037 4246 +8232E038 4247 +8232E039 4248 +8232E130 4249 +8232E131 424A +8232E132 424B +8232E133 424C +8232E134 424D +8232E135 424E +8232E136 424F +8232E137 4250 +8232E138 4251 +8232E139 4252 +8232E230 4253 +8232E231 4254 +8232E232 4255 +8232E233 4256 +8232E234 4257 +8232E235 4258 +8232E236 4259 +8232E237 425A +8232E238 425B +8232E239 425C +8232E330 425D +8232E331 425E +8232E332 425F +8232E333 4260 +8232E334 4261 +8232E335 4262 +8232E336 4263 +8232E337 4264 +8232E338 4265 +8232E339 4266 +8232E430 4267 +8232E431 4268 +8232E432 4269 +8232E433 426A +8232E434 426B +8232E435 426C +8232E436 426D +8232E437 426E +8232E438 426F +8232E439 4270 +8232E530 4271 +8232E531 4272 +8232E532 4273 +8232E533 4274 +8232E534 4275 +8232E535 4276 +8232E536 4277 +8232E537 4278 +8232E538 4279 +8232E539 427A +8232E630 427B +8232E631 427C +8232E632 427D +8232E633 427E +8232E634 427F +8232E635 4280 +8232E636 4281 +8232E637 4282 +8232E638 4283 +8232E639 4284 +8232E730 4285 +8232E731 4286 +8232E732 4287 +8232E733 4288 +8232E734 4289 +8232E735 428A +8232E736 428B +8232E737 428C +8232E738 428D +8232E739 428E +8232E830 428F +8232E831 4290 +8232E832 4291 +8232E833 4292 +8232E834 4293 +8232E835 4294 +8232E836 4295 +8232E837 4296 +8232E838 4297 +8232E839 4298 +8232E930 4299 +8232E931 429A +8232E932 429B +8232E933 429C +8232E934 429D +8232E935 429E +8232E936 429F +8232E937 42A0 +8232E938 42A1 +8232E939 42A2 +8232EA30 42A3 +8232EA31 42A4 +8232EA32 42A5 +8232EA33 42A6 +8232EA34 42A7 +8232EA35 42A8 +8232EA36 42A9 +8232EA37 42AA +8232EA38 42AB +8232EA39 42AC +8232EB30 42AD +8232EB31 42AE +8232EB32 42AF +8232EB33 42B0 +8232EB34 42B1 +8232EB35 42B2 +8232EB36 42B3 +8232EB37 42B4 +8232EB38 42B5 +8232EB39 42B6 +8232EC30 42B7 +8232EC31 42B8 +8232EC32 42B9 +8232EC33 42BA +8232EC34 42BB +8232EC35 42BC +8232EC36 42BD +8232EC37 42BE +8232EC38 42BF +8232EC39 42C0 +8232ED30 42C1 +8232ED31 42C2 +8232ED32 42C3 +8232ED33 42C4 +8232ED34 42C5 +8232ED35 42C6 +8232ED36 42C7 +8232ED37 42C8 +8232ED38 42C9 +8232ED39 42CA +8232EE30 42CB +8232EE31 42CC +8232EE32 42CD +8232EE33 42CE +8232EE34 42CF +8232EE35 42D0 +8232EE36 42D1 +8232EE37 42D2 +8232EE38 42D3 +8232EE39 42D4 +8232EF30 42D5 +8232EF31 42D6 +8232EF32 42D7 +8232EF33 42D8 +8232EF34 42D9 +8232EF35 42DA +8232EF36 42DB +8232EF37 42DC +8232EF38 42DD +8232EF39 42DE +8232F030 42DF +8232F031 42E0 +8232F032 42E1 +8232F033 42E2 +8232F034 42E3 +8232F035 42E4 +8232F036 42E5 +8232F037 42E6 +8232F038 42E7 +8232F039 42E8 +8232F130 42E9 +8232F131 42EA +8232F132 42EB +8232F133 42EC +8232F134 42ED +8232F135 42EE +8232F136 42EF +8232F137 42F0 +8232F138 42F1 +8232F139 42F2 +8232F230 42F3 +8232F231 42F4 +8232F232 42F5 +8232F233 42F6 +8232F234 42F7 +8232F235 42F8 +8232F236 42F9 +8232F237 42FA +8232F238 42FB +8232F239 42FC +8232F330 42FD +8232F331 42FE +8232F332 42FF +8232F333 4300 +8232F334 4301 +8232F335 4302 +8232F336 4303 +8232F337 4304 +8232F338 4305 +8232F339 4306 +8232F430 4307 +8232F431 4308 +8232F432 4309 +8232F433 430A +8232F434 430B +8232F435 430C +8232F436 430D +8232F437 430E +8232F438 430F +8232F439 4310 +8232F530 4311 +8232F531 4312 +8232F532 4313 +8232F533 4314 +8232F534 4315 +8232F535 4316 +8232F536 4317 +8232F537 4318 +8232F538 4319 +8232F539 431A +8232F630 431B +8232F631 431C +8232F632 431D +8232F633 431E +8232F634 431F +8232F635 4320 +8232F636 4321 +8232F637 4322 +8232F638 4323 +8232F639 4324 +8232F730 4325 +8232F731 4326 +8232F732 4327 +8232F733 4328 +8232F734 4329 +8232F735 432A +8232F736 432B +8232F737 432C +8232F738 432D +8232F739 432E +8232F830 432F +8232F831 4330 +8232F832 4331 +8232F833 4332 +8232F834 4333 +8232F835 4334 +8232F836 4335 +8232F837 4336 +FE72 4337 +8232F838 4338 +8232F839 4339 +8232F930 433A +8232F931 433B +8232F932 433C +8232F933 433D +8232F934 433E +8232F935 433F +8232F936 4340 +8232F937 4341 +8232F938 4342 +8232F939 4343 +8232FA30 4344 +8232FA31 4345 +8232FA32 4346 +8232FA33 4347 +8232FA34 4348 +8232FA35 4349 +8232FA36 434A +8232FA37 434B +8232FA38 434C +8232FA39 434D +8232FB30 434E +8232FB31 434F +8232FB32 4350 +8232FB33 4351 +8232FB34 4352 +8232FB35 4353 +8232FB36 4354 +8232FB37 4355 +8232FB38 4356 +8232FB39 4357 +8232FC30 4358 +8232FC31 4359 +8232FC32 435A +8232FC33 435B +8232FC34 435C +8232FC35 435D +8232FC36 435E +8232FC37 435F +8232FC38 4360 +8232FC39 4361 +8232FD30 4362 +8232FD31 4363 +8232FD32 4364 +8232FD33 4365 +8232FD34 4366 +8232FD35 4367 +8232FD36 4368 +8232FD37 4369 +8232FD38 436A +8232FD39 436B +8232FE30 436C +8232FE31 436D +8232FE32 436E +8232FE33 436F +8232FE34 4370 +8232FE35 4371 +8232FE36 4372 +8232FE37 4373 +8232FE38 4374 +8232FE39 4375 +82338130 4376 +82338131 4377 +82338132 4378 +82338133 4379 +82338134 437A +82338135 437B +82338136 437C +82338137 437D +82338138 437E +82338139 437F +82338230 4380 +82338231 4381 +82338232 4382 +82338233 4383 +82338234 4384 +82338235 4385 +82338236 4386 +82338237 4387 +82338238 4388 +82338239 4389 +82338330 438A +82338331 438B +82338332 438C +82338333 438D +82338334 438E +82338335 438F +82338336 4390 +82338337 4391 +82338338 4392 +82338339 4393 +82338430 4394 +82338431 4395 +82338432 4396 +82338433 4397 +82338434 4398 +82338435 4399 +82338436 439A +82338437 439B +82338438 439C +82338439 439D +82338530 439E +82338531 439F +82338532 43A0 +82338533 43A1 +82338534 43A2 +82338535 43A3 +82338536 43A4 +82338537 43A5 +82338538 43A6 +82338539 43A7 +82338630 43A8 +82338631 43A9 +82338632 43AA +82338633 43AB +FE78 43AC +82338634 43AD +82338635 43AE +82338636 43AF +82338637 43B0 +FE77 43B1 +82338638 43B2 +82338639 43B3 +82338730 43B4 +82338731 43B5 +82338732 43B6 +82338733 43B7 +82338734 43B8 +82338735 43B9 +82338736 43BA +82338737 43BB +82338738 43BC +82338739 43BD +82338830 43BE +82338831 43BF +82338832 43C0 +82338833 43C1 +82338834 43C2 +82338835 43C3 +82338836 43C4 +82338837 43C5 +82338838 43C6 +82338839 43C7 +82338930 43C8 +82338931 43C9 +82338932 43CA +82338933 43CB +82338934 43CC +82338935 43CD +82338936 43CE +82338937 43CF +82338938 43D0 +82338939 43D1 +82338A30 43D2 +82338A31 43D3 +82338A32 43D4 +82338A33 43D5 +82338A34 43D6 +82338A35 43D7 +82338A36 43D8 +82338A37 43D9 +82338A38 43DA +82338A39 43DB +82338B30 43DC +FE7A 43DD +82338B31 43DE +82338B32 43DF +82338B33 43E0 +82338B34 43E1 +82338B35 43E2 +82338B36 43E3 +82338B37 43E4 +82338B38 43E5 +82338B39 43E6 +82338C30 43E7 +82338C31 43E8 +82338C32 43E9 +82338C33 43EA +82338C34 43EB +82338C35 43EC +82338C36 43ED +82338C37 43EE +82338C38 43EF +82338C39 43F0 +82338D30 43F1 +82338D31 43F2 +82338D32 43F3 +82338D33 43F4 +82338D34 43F5 +82338D35 43F6 +82338D36 43F7 +82338D37 43F8 +82338D38 43F9 +82338D39 43FA +82338E30 43FB +82338E31 43FC +82338E32 43FD +82338E33 43FE +82338E34 43FF +82338E35 4400 +82338E36 4401 +82338E37 4402 +82338E38 4403 +82338E39 4404 +82338F30 4405 +82338F31 4406 +82338F32 4407 +82338F33 4408 +82338F34 4409 +82338F35 440A +82338F36 440B +82338F37 440C +82338F38 440D +82338F39 440E +82339030 440F +82339031 4410 +82339032 4411 +82339033 4412 +82339034 4413 +82339035 4414 +82339036 4415 +82339037 4416 +82339038 4417 +82339039 4418 +82339130 4419 +82339131 441A +82339132 441B +82339133 441C +82339134 441D +82339135 441E +82339136 441F +82339137 4420 +82339138 4421 +82339139 4422 +82339230 4423 +82339231 4424 +82339232 4425 +82339233 4426 +82339234 4427 +82339235 4428 +82339236 4429 +82339237 442A +82339238 442B +82339239 442C +82339330 442D +82339331 442E +82339332 442F +82339333 4430 +82339334 4431 +82339335 4432 +82339336 4433 +82339337 4434 +82339338 4435 +82339339 4436 +82339430 4437 +82339431 4438 +82339432 4439 +82339433 443A +82339434 443B +82339435 443C +82339436 443D +82339437 443E +82339438 443F +82339439 4440 +82339530 4441 +82339531 4442 +82339532 4443 +82339533 4444 +82339534 4445 +82339535 4446 +82339536 4447 +82339537 4448 +82339538 4449 +82339539 444A +82339630 444B +82339631 444C +82339632 444D +82339633 444E +82339634 444F +82339635 4450 +82339636 4451 +82339637 4452 +82339638 4453 +82339639 4454 +82339730 4455 +82339731 4456 +82339732 4457 +82339733 4458 +82339734 4459 +82339735 445A +82339736 445B +82339737 445C +82339738 445D +82339739 445E +82339830 445F +82339831 4460 +82339832 4461 +82339833 4462 +82339834 4463 +82339835 4464 +82339836 4465 +82339837 4466 +82339838 4467 +82339839 4468 +82339930 4469 +82339931 446A +82339932 446B +82339933 446C +82339934 446D +82339935 446E +82339936 446F +82339937 4470 +82339938 4471 +82339939 4472 +82339A30 4473 +82339A31 4474 +82339A32 4475 +82339A33 4476 +82339A34 4477 +82339A35 4478 +82339A36 4479 +82339A37 447A +82339A38 447B +82339A39 447C +82339B30 447D +82339B31 447E +82339B32 447F +82339B33 4480 +82339B34 4481 +82339B35 4482 +82339B36 4483 +82339B37 4484 +82339B38 4485 +82339B39 4486 +82339C30 4487 +82339C31 4488 +82339C32 4489 +82339C33 448A +82339C34 448B +82339C35 448C +82339C36 448D +82339C37 448E +82339C38 448F +82339C39 4490 +82339D30 4491 +82339D31 4492 +82339D32 4493 +82339D33 4494 +82339D34 4495 +82339D35 4496 +82339D36 4497 +82339D37 4498 +82339D38 4499 +82339D39 449A +82339E30 449B +82339E31 449C +82339E32 449D +82339E33 449E +82339E34 449F +82339E35 44A0 +82339E36 44A1 +82339E37 44A2 +82339E38 44A3 +82339E39 44A4 +82339F30 44A5 +82339F31 44A6 +82339F32 44A7 +82339F33 44A8 +82339F34 44A9 +82339F35 44AA +82339F36 44AB +82339F37 44AC +82339F38 44AD +82339F39 44AE +8233A030 44AF +8233A031 44B0 +8233A032 44B1 +8233A033 44B2 +8233A034 44B3 +8233A035 44B4 +8233A036 44B5 +8233A037 44B6 +8233A038 44B7 +8233A039 44B8 +8233A130 44B9 +8233A131 44BA +8233A132 44BB +8233A133 44BC +8233A134 44BD +8233A135 44BE +8233A136 44BF +8233A137 44C0 +8233A138 44C1 +8233A139 44C2 +8233A230 44C3 +8233A231 44C4 +8233A232 44C5 +8233A233 44C6 +8233A234 44C7 +8233A235 44C8 +8233A236 44C9 +8233A237 44CA +8233A238 44CB +8233A239 44CC +8233A330 44CD +8233A331 44CE +8233A332 44CF +8233A333 44D0 +8233A334 44D1 +8233A335 44D2 +8233A336 44D3 +8233A337 44D4 +8233A338 44D5 +FE7B 44D6 +8233A339 44D7 +8233A430 44D8 +8233A431 44D9 +8233A432 44DA +8233A433 44DB +8233A434 44DC +8233A435 44DD +8233A436 44DE +8233A437 44DF +8233A438 44E0 +8233A439 44E1 +8233A530 44E2 +8233A531 44E3 +8233A532 44E4 +8233A533 44E5 +8233A534 44E6 +8233A535 44E7 +8233A536 44E8 +8233A537 44E9 +8233A538 44EA +8233A539 44EB +8233A630 44EC +8233A631 44ED +8233A632 44EE +8233A633 44EF +8233A634 44F0 +8233A635 44F1 +8233A636 44F2 +8233A637 44F3 +8233A638 44F4 +8233A639 44F5 +8233A730 44F6 +8233A731 44F7 +8233A732 44F8 +8233A733 44F9 +8233A734 44FA +8233A735 44FB +8233A736 44FC +8233A737 44FD +8233A738 44FE +8233A739 44FF +8233A830 4500 +8233A831 4501 +8233A832 4502 +8233A833 4503 +8233A834 4504 +8233A835 4505 +8233A836 4506 +8233A837 4507 +8233A838 4508 +8233A839 4509 +8233A930 450A +8233A931 450B +8233A932 450C +8233A933 450D +8233A934 450E +8233A935 450F +8233A936 4510 +8233A937 4511 +8233A938 4512 +8233A939 4513 +8233AA30 4514 +8233AA31 4515 +8233AA32 4516 +8233AA33 4517 +8233AA34 4518 +8233AA35 4519 +8233AA36 451A +8233AA37 451B +8233AA38 451C +8233AA39 451D +8233AB30 451E +8233AB31 451F +8233AB32 4520 +8233AB33 4521 +8233AB34 4522 +8233AB35 4523 +8233AB36 4524 +8233AB37 4525 +8233AB38 4526 +8233AB39 4527 +8233AC30 4528 +8233AC31 4529 +8233AC32 452A +8233AC33 452B +8233AC34 452C +8233AC35 452D +8233AC36 452E +8233AC37 452F +8233AC38 4530 +8233AC39 4531 +8233AD30 4532 +8233AD31 4533 +8233AD32 4534 +8233AD33 4535 +8233AD34 4536 +8233AD35 4537 +8233AD36 4538 +8233AD37 4539 +8233AD38 453A +8233AD39 453B +8233AE30 453C +8233AE31 453D +8233AE32 453E +8233AE33 453F +8233AE34 4540 +8233AE35 4541 +8233AE36 4542 +8233AE37 4543 +8233AE38 4544 +8233AE39 4545 +8233AF30 4546 +8233AF31 4547 +8233AF32 4548 +8233AF33 4549 +8233AF34 454A +8233AF35 454B +8233AF36 454C +8233AF37 454D +8233AF38 454E +8233AF39 454F +8233B030 4550 +8233B031 4551 +8233B032 4552 +8233B033 4553 +8233B034 4554 +8233B035 4555 +8233B036 4556 +8233B037 4557 +8233B038 4558 +8233B039 4559 +8233B130 455A +8233B131 455B +8233B132 455C +8233B133 455D +8233B134 455E +8233B135 455F +8233B136 4560 +8233B137 4561 +8233B138 4562 +8233B139 4563 +8233B230 4564 +8233B231 4565 +8233B232 4566 +8233B233 4567 +8233B234 4568 +8233B235 4569 +8233B236 456A +8233B237 456B +8233B238 456C +8233B239 456D +8233B330 456E +8233B331 456F +8233B332 4570 +8233B333 4571 +8233B334 4572 +8233B335 4573 +8233B336 4574 +8233B337 4575 +8233B338 4576 +8233B339 4577 +8233B430 4578 +8233B431 4579 +8233B432 457A +8233B433 457B +8233B434 457C +8233B435 457D +8233B436 457E +8233B437 457F +8233B438 4580 +8233B439 4581 +8233B530 4582 +8233B531 4583 +8233B532 4584 +8233B533 4585 +8233B534 4586 +8233B535 4587 +8233B536 4588 +8233B537 4589 +8233B538 458A +8233B539 458B +8233B630 458C +8233B631 458D +8233B632 458E +8233B633 458F +8233B634 4590 +8233B635 4591 +8233B636 4592 +8233B637 4593 +8233B638 4594 +8233B639 4595 +8233B730 4596 +8233B731 4597 +8233B732 4598 +8233B733 4599 +8233B734 459A +8233B735 459B +8233B736 459C +8233B737 459D +8233B738 459E +8233B739 459F +8233B830 45A0 +8233B831 45A1 +8233B832 45A2 +8233B833 45A3 +8233B834 45A4 +8233B835 45A5 +8233B836 45A6 +8233B837 45A7 +8233B838 45A8 +8233B839 45A9 +8233B930 45AA +8233B931 45AB +8233B932 45AC +8233B933 45AD +8233B934 45AE +8233B935 45AF +8233B936 45B0 +8233B937 45B1 +8233B938 45B2 +8233B939 45B3 +8233BA30 45B4 +8233BA31 45B5 +8233BA32 45B6 +8233BA33 45B7 +8233BA34 45B8 +8233BA35 45B9 +8233BA36 45BA +8233BA37 45BB +8233BA38 45BC +8233BA39 45BD +8233BB30 45BE +8233BB31 45BF +8233BB32 45C0 +8233BB33 45C1 +8233BB34 45C2 +8233BB35 45C3 +8233BB36 45C4 +8233BB37 45C5 +8233BB38 45C6 +8233BB39 45C7 +8233BC30 45C8 +8233BC31 45C9 +8233BC32 45CA +8233BC33 45CB +8233BC34 45CC +8233BC35 45CD +8233BC36 45CE +8233BC37 45CF +8233BC38 45D0 +8233BC39 45D1 +8233BD30 45D2 +8233BD31 45D3 +8233BD32 45D4 +8233BD33 45D5 +8233BD34 45D6 +8233BD35 45D7 +8233BD36 45D8 +8233BD37 45D9 +8233BD38 45DA +8233BD39 45DB +8233BE30 45DC +8233BE31 45DD +8233BE32 45DE +8233BE33 45DF +8233BE34 45E0 +8233BE35 45E1 +8233BE36 45E2 +8233BE37 45E3 +8233BE38 45E4 +8233BE39 45E5 +8233BF30 45E6 +8233BF31 45E7 +8233BF32 45E8 +8233BF33 45E9 +8233BF34 45EA +8233BF35 45EB +8233BF36 45EC +8233BF37 45ED +8233BF38 45EE +8233BF39 45EF +8233C030 45F0 +8233C031 45F1 +8233C032 45F2 +8233C033 45F3 +8233C034 45F4 +8233C035 45F5 +8233C036 45F6 +8233C037 45F7 +8233C038 45F8 +8233C039 45F9 +8233C130 45FA +8233C131 45FB +8233C132 45FC +8233C133 45FD +8233C134 45FE +8233C135 45FF +8233C136 4600 +8233C137 4601 +8233C138 4602 +8233C139 4603 +8233C230 4604 +8233C231 4605 +8233C232 4606 +8233C233 4607 +8233C234 4608 +8233C235 4609 +8233C236 460A +8233C237 460B +8233C238 460C +8233C239 460D +8233C330 460E +8233C331 460F +8233C332 4610 +8233C333 4611 +8233C334 4612 +8233C335 4613 +8233C336 4614 +8233C337 4615 +8233C338 4616 +8233C339 4617 +8233C430 4618 +8233C431 4619 +8233C432 461A +8233C433 461B +8233C434 461C +8233C435 461D +8233C436 461E +8233C437 461F +8233C438 4620 +8233C439 4621 +8233C530 4622 +8233C531 4623 +8233C532 4624 +8233C533 4625 +8233C534 4626 +8233C535 4627 +8233C536 4628 +8233C537 4629 +8233C538 462A +8233C539 462B +8233C630 462C +8233C631 462D +8233C632 462E +8233C633 462F +8233C634 4630 +8233C635 4631 +8233C636 4632 +8233C637 4633 +8233C638 4634 +8233C639 4635 +8233C730 4636 +8233C731 4637 +8233C732 4638 +8233C733 4639 +8233C734 463A +8233C735 463B +8233C736 463C +8233C737 463D +8233C738 463E +8233C739 463F +8233C830 4640 +8233C831 4641 +8233C832 4642 +8233C833 4643 +8233C834 4644 +8233C835 4645 +8233C836 4646 +8233C837 4647 +8233C838 4648 +8233C839 4649 +8233C930 464A +8233C931 464B +FE7D 464C +8233C932 464D +8233C933 464E +8233C934 464F +8233C935 4650 +8233C936 4651 +8233C937 4652 +8233C938 4653 +8233C939 4654 +8233CA30 4655 +8233CA31 4656 +8233CA32 4657 +8233CA33 4658 +8233CA34 4659 +8233CA35 465A +8233CA36 465B +8233CA37 465C +8233CA38 465D +8233CA39 465E +8233CB30 465F +8233CB31 4660 +FE7C 4661 +8233CB32 4662 +8233CB33 4663 +8233CB34 4664 +8233CB35 4665 +8233CB36 4666 +8233CB37 4667 +8233CB38 4668 +8233CB39 4669 +8233CC30 466A +8233CC31 466B +8233CC32 466C +8233CC33 466D +8233CC34 466E +8233CC35 466F +8233CC36 4670 +8233CC37 4671 +8233CC38 4672 +8233CC39 4673 +8233CD30 4674 +8233CD31 4675 +8233CD32 4676 +8233CD33 4677 +8233CD34 4678 +8233CD35 4679 +8233CD36 467A +8233CD37 467B +8233CD38 467C +8233CD39 467D +8233CE30 467E +8233CE31 467F +8233CE32 4680 +8233CE33 4681 +8233CE34 4682 +8233CE35 4683 +8233CE36 4684 +8233CE37 4685 +8233CE38 4686 +8233CE39 4687 +8233CF30 4688 +8233CF31 4689 +8233CF32 468A +8233CF33 468B +8233CF34 468C +8233CF35 468D +8233CF36 468E +8233CF37 468F +8233CF38 4690 +8233CF39 4691 +8233D030 4692 +8233D031 4693 +8233D032 4694 +8233D033 4695 +8233D034 4696 +8233D035 4697 +8233D036 4698 +8233D037 4699 +8233D038 469A +8233D039 469B +8233D130 469C +8233D131 469D +8233D132 469E +8233D133 469F +8233D134 46A0 +8233D135 46A1 +8233D136 46A2 +8233D137 46A3 +8233D138 46A4 +8233D139 46A5 +8233D230 46A6 +8233D231 46A7 +8233D232 46A8 +8233D233 46A9 +8233D234 46AA +8233D235 46AB +8233D236 46AC +8233D237 46AD +8233D238 46AE +8233D239 46AF +8233D330 46B0 +8233D331 46B1 +8233D332 46B2 +8233D333 46B3 +8233D334 46B4 +8233D335 46B5 +8233D336 46B6 +8233D337 46B7 +8233D338 46B8 +8233D339 46B9 +8233D430 46BA +8233D431 46BB +8233D432 46BC +8233D433 46BD +8233D434 46BE +8233D435 46BF +8233D436 46C0 +8233D437 46C1 +8233D438 46C2 +8233D439 46C3 +8233D530 46C4 +8233D531 46C5 +8233D532 46C6 +8233D533 46C7 +8233D534 46C8 +8233D535 46C9 +8233D536 46CA +8233D537 46CB +8233D538 46CC +8233D539 46CD +8233D630 46CE +8233D631 46CF +8233D632 46D0 +8233D633 46D1 +8233D634 46D2 +8233D635 46D3 +8233D636 46D4 +8233D637 46D5 +8233D638 46D6 +8233D639 46D7 +8233D730 46D8 +8233D731 46D9 +8233D732 46DA +8233D733 46DB +8233D734 46DC +8233D735 46DD +8233D736 46DE +8233D737 46DF +8233D738 46E0 +8233D739 46E1 +8233D830 46E2 +8233D831 46E3 +8233D832 46E4 +8233D833 46E5 +8233D834 46E6 +8233D835 46E7 +8233D836 46E8 +8233D837 46E9 +8233D838 46EA +8233D839 46EB +8233D930 46EC +8233D931 46ED +8233D932 46EE +8233D933 46EF +8233D934 46F0 +8233D935 46F1 +8233D936 46F2 +8233D937 46F3 +8233D938 46F4 +8233D939 46F5 +8233DA30 46F6 +8233DA31 46F7 +8233DA32 46F8 +8233DA33 46F9 +8233DA34 46FA +8233DA35 46FB +8233DA36 46FC +8233DA37 46FD +8233DA38 46FE +8233DA39 46FF +8233DB30 4700 +8233DB31 4701 +8233DB32 4702 +8233DB33 4703 +8233DB34 4704 +8233DB35 4705 +8233DB36 4706 +8233DB37 4707 +8233DB38 4708 +8233DB39 4709 +8233DC30 470A +8233DC31 470B +8233DC32 470C +8233DC33 470D +8233DC34 470E +8233DC35 470F +8233DC36 4710 +8233DC37 4711 +8233DC38 4712 +8233DC39 4713 +8233DD30 4714 +8233DD31 4715 +8233DD32 4716 +8233DD33 4717 +8233DD34 4718 +8233DD35 4719 +8233DD36 471A +8233DD37 471B +8233DD38 471C +8233DD39 471D +8233DE30 471E +8233DE31 471F +8233DE32 4720 +8233DE33 4721 +8233DE34 4722 +FE80 4723 +8233DE35 4724 +8233DE36 4725 +8233DE37 4726 +8233DE38 4727 +8233DE39 4728 +FE81 4729 +8233DF30 472A +8233DF31 472B +8233DF32 472C +8233DF33 472D +8233DF34 472E +8233DF35 472F +8233DF36 4730 +8233DF37 4731 +8233DF38 4732 +8233DF39 4733 +8233E030 4734 +8233E031 4735 +8233E032 4736 +8233E033 4737 +8233E034 4738 +8233E035 4739 +8233E036 473A +8233E037 473B +8233E038 473C +8233E039 473D +8233E130 473E +8233E131 473F +8233E132 4740 +8233E133 4741 +8233E134 4742 +8233E135 4743 +8233E136 4744 +8233E137 4745 +8233E138 4746 +8233E139 4747 +8233E230 4748 +8233E231 4749 +8233E232 474A +8233E233 474B +8233E234 474C +8233E235 474D +8233E236 474E +8233E237 474F +8233E238 4750 +8233E239 4751 +8233E330 4752 +8233E331 4753 +8233E332 4754 +8233E333 4755 +8233E334 4756 +8233E335 4757 +8233E336 4758 +8233E337 4759 +8233E338 475A +8233E339 475B +8233E430 475C +8233E431 475D +8233E432 475E +8233E433 475F +8233E434 4760 +8233E435 4761 +8233E436 4762 +8233E437 4763 +8233E438 4764 +8233E439 4765 +8233E530 4766 +8233E531 4767 +8233E532 4768 +8233E533 4769 +8233E534 476A +8233E535 476B +8233E536 476C +8233E537 476D +8233E538 476E +8233E539 476F +8233E630 4770 +8233E631 4771 +8233E632 4772 +8233E633 4773 +8233E634 4774 +8233E635 4775 +8233E636 4776 +8233E637 4777 +8233E638 4778 +8233E639 4779 +8233E730 477A +8233E731 477B +FE82 477C +8233E732 477D +8233E733 477E +8233E734 477F +8233E735 4780 +8233E736 4781 +8233E737 4782 +8233E738 4783 +8233E739 4784 +8233E830 4785 +8233E831 4786 +8233E832 4787 +8233E833 4788 +8233E834 4789 +8233E835 478A +8233E836 478B +8233E837 478C +FE83 478D +8233E838 478E +8233E839 478F +8233E930 4790 +8233E931 4791 +8233E932 4792 +8233E933 4793 +8233E934 4794 +8233E935 4795 +8233E936 4796 +8233E937 4797 +8233E938 4798 +8233E939 4799 +8233EA30 479A +8233EA31 479B +8233EA32 479C +8233EA33 479D +8233EA34 479E +8233EA35 479F +8233EA36 47A0 +8233EA37 47A1 +8233EA38 47A2 +8233EA39 47A3 +8233EB30 47A4 +8233EB31 47A5 +8233EB32 47A6 +8233EB33 47A7 +8233EB34 47A8 +8233EB35 47A9 +8233EB36 47AA +8233EB37 47AB +8233EB38 47AC +8233EB39 47AD +8233EC30 47AE +8233EC31 47AF +8233EC32 47B0 +8233EC33 47B1 +8233EC34 47B2 +8233EC35 47B3 +8233EC36 47B4 +8233EC37 47B5 +8233EC38 47B6 +8233EC39 47B7 +8233ED30 47B8 +8233ED31 47B9 +8233ED32 47BA +8233ED33 47BB +8233ED34 47BC +8233ED35 47BD +8233ED36 47BE +8233ED37 47BF +8233ED38 47C0 +8233ED39 47C1 +8233EE30 47C2 +8233EE31 47C3 +8233EE32 47C4 +8233EE33 47C5 +8233EE34 47C6 +8233EE35 47C7 +8233EE36 47C8 +8233EE37 47C9 +8233EE38 47CA +8233EE39 47CB +8233EF30 47CC +8233EF31 47CD +8233EF32 47CE +8233EF33 47CF +8233EF34 47D0 +8233EF35 47D1 +8233EF36 47D2 +8233EF37 47D3 +8233EF38 47D4 +8233EF39 47D5 +8233F030 47D6 +8233F031 47D7 +8233F032 47D8 +8233F033 47D9 +8233F034 47DA +8233F035 47DB +8233F036 47DC +8233F037 47DD +8233F038 47DE +8233F039 47DF +8233F130 47E0 +8233F131 47E1 +8233F132 47E2 +8233F133 47E3 +8233F134 47E4 +8233F135 47E5 +8233F136 47E6 +8233F137 47E7 +8233F138 47E8 +8233F139 47E9 +8233F230 47EA +8233F231 47EB +8233F232 47EC +8233F233 47ED +8233F234 47EE +8233F235 47EF +8233F236 47F0 +8233F237 47F1 +8233F238 47F2 +8233F239 47F3 +8233F330 47F4 +8233F331 47F5 +8233F332 47F6 +8233F333 47F7 +8233F334 47F8 +8233F335 47F9 +8233F336 47FA +8233F337 47FB +8233F338 47FC +8233F339 47FD +8233F430 47FE +8233F431 47FF +8233F432 4800 +8233F433 4801 +8233F434 4802 +8233F435 4803 +8233F436 4804 +8233F437 4805 +8233F438 4806 +8233F439 4807 +8233F530 4808 +8233F531 4809 +8233F532 480A +8233F533 480B +8233F534 480C +8233F535 480D +8233F536 480E +8233F537 480F +8233F538 4810 +8233F539 4811 +8233F630 4812 +8233F631 4813 +8233F632 4814 +8233F633 4815 +8233F634 4816 +8233F635 4817 +8233F636 4818 +8233F637 4819 +8233F638 481A +8233F639 481B +8233F730 481C +8233F731 481D +8233F732 481E +8233F733 481F +8233F734 4820 +8233F735 4821 +8233F736 4822 +8233F737 4823 +8233F738 4824 +8233F739 4825 +8233F830 4826 +8233F831 4827 +8233F832 4828 +8233F833 4829 +8233F834 482A +8233F835 482B +8233F836 482C +8233F837 482D +8233F838 482E +8233F839 482F +8233F930 4830 +8233F931 4831 +8233F932 4832 +8233F933 4833 +8233F934 4834 +8233F935 4835 +8233F936 4836 +8233F937 4837 +8233F938 4838 +8233F939 4839 +8233FA30 483A +8233FA31 483B +8233FA32 483C +8233FA33 483D +8233FA34 483E +8233FA35 483F +8233FA36 4840 +8233FA37 4841 +8233FA38 4842 +8233FA39 4843 +8233FB30 4844 +8233FB31 4845 +8233FB32 4846 +8233FB33 4847 +8233FB34 4848 +8233FB35 4849 +8233FB36 484A +8233FB37 484B +8233FB38 484C +8233FB39 484D +8233FC30 484E +8233FC31 484F +8233FC32 4850 +8233FC33 4851 +8233FC34 4852 +8233FC35 4853 +8233FC36 4854 +8233FC37 4855 +8233FC38 4856 +8233FC39 4857 +8233FD30 4858 +8233FD31 4859 +8233FD32 485A +8233FD33 485B +8233FD34 485C +8233FD35 485D +8233FD36 485E +8233FD37 485F +8233FD38 4860 +8233FD39 4861 +8233FE30 4862 +8233FE31 4863 +8233FE32 4864 +8233FE33 4865 +8233FE34 4866 +8233FE35 4867 +8233FE36 4868 +8233FE37 4869 +8233FE38 486A +8233FE39 486B +82348130 486C +82348131 486D +82348132 486E +82348133 486F +82348134 4870 +82348135 4871 +82348136 4872 +82348137 4873 +82348138 4874 +82348139 4875 +82348230 4876 +82348231 4877 +82348232 4878 +82348233 4879 +82348234 487A +82348235 487B +82348236 487C +82348237 487D +82348238 487E +82348239 487F +82348330 4880 +82348331 4881 +82348332 4882 +82348333 4883 +82348334 4884 +82348335 4885 +82348336 4886 +82348337 4887 +82348338 4888 +82348339 4889 +82348430 488A +82348431 488B +82348432 488C +82348433 488D +82348434 488E +82348435 488F +82348436 4890 +82348437 4891 +82348438 4892 +82348439 4893 +82348530 4894 +82348531 4895 +82348532 4896 +82348533 4897 +82348534 4898 +82348535 4899 +82348536 489A +82348537 489B +82348538 489C +82348539 489D +82348630 489E +82348631 489F +82348632 48A0 +82348633 48A1 +82348634 48A2 +82348635 48A3 +82348636 48A4 +82348637 48A5 +82348638 48A6 +82348639 48A7 +82348730 48A8 +82348731 48A9 +82348732 48AA +82348733 48AB +82348734 48AC +82348735 48AD +82348736 48AE +82348737 48AF +82348738 48B0 +82348739 48B1 +82348830 48B2 +82348831 48B3 +82348832 48B4 +82348833 48B5 +82348834 48B6 +82348835 48B7 +82348836 48B8 +82348837 48B9 +82348838 48BA +82348839 48BB +82348930 48BC +82348931 48BD +82348932 48BE +82348933 48BF +82348934 48C0 +82348935 48C1 +82348936 48C2 +82348937 48C3 +82348938 48C4 +82348939 48C5 +82348A30 48C6 +82348A31 48C7 +82348A32 48C8 +82348A33 48C9 +82348A34 48CA +82348A35 48CB +82348A36 48CC +82348A37 48CD +82348A38 48CE +82348A39 48CF +82348B30 48D0 +82348B31 48D1 +82348B32 48D2 +82348B33 48D3 +82348B34 48D4 +82348B35 48D5 +82348B36 48D6 +82348B37 48D7 +82348B38 48D8 +82348B39 48D9 +82348C30 48DA +82348C31 48DB +82348C32 48DC +82348C33 48DD +82348C34 48DE +82348C35 48DF +82348C36 48E0 +82348C37 48E1 +82348C38 48E2 +82348C39 48E3 +82348D30 48E4 +82348D31 48E5 +82348D32 48E6 +82348D33 48E7 +82348D34 48E8 +82348D35 48E9 +82348D36 48EA +82348D37 48EB +82348D38 48EC +82348D39 48ED +82348E30 48EE +82348E31 48EF +82348E32 48F0 +82348E33 48F1 +82348E34 48F2 +82348E35 48F3 +82348E36 48F4 +82348E37 48F5 +82348E38 48F6 +82348E39 48F7 +82348F30 48F8 +82348F31 48F9 +82348F32 48FA +82348F33 48FB +82348F34 48FC +82348F35 48FD +82348F36 48FE +82348F37 48FF +82348F38 4900 +82348F39 4901 +82349030 4902 +82349031 4903 +82349032 4904 +82349033 4905 +82349034 4906 +82349035 4907 +82349036 4908 +82349037 4909 +82349038 490A +82349039 490B +82349130 490C +82349131 490D +82349132 490E +82349133 490F +82349134 4910 +82349135 4911 +82349136 4912 +82349137 4913 +82349138 4914 +82349139 4915 +82349230 4916 +82349231 4917 +82349232 4918 +82349233 4919 +82349234 491A +82349235 491B +82349236 491C +82349237 491D +82349238 491E +82349239 491F +82349330 4920 +82349331 4921 +82349332 4922 +82349333 4923 +82349334 4924 +82349335 4925 +82349336 4926 +82349337 4927 +82349338 4928 +82349339 4929 +82349430 492A +82349431 492B +82349432 492C +82349433 492D +82349434 492E +82349435 492F +82349436 4930 +82349437 4931 +82349438 4932 +82349439 4933 +82349530 4934 +82349531 4935 +82349532 4936 +82349533 4937 +82349534 4938 +82349535 4939 +82349536 493A +82349537 493B +82349538 493C +82349539 493D +82349630 493E +82349631 493F +82349632 4940 +82349633 4941 +82349634 4942 +82349635 4943 +82349636 4944 +82349637 4945 +82349638 4946 +FE85 4947 +82349639 4948 +82349730 4949 +82349731 494A +82349732 494B +82349733 494C +82349734 494D +82349735 494E +82349736 494F +82349737 4950 +82349738 4951 +82349739 4952 +82349830 4953 +82349831 4954 +82349832 4955 +82349833 4956 +82349834 4957 +82349835 4958 +82349836 4959 +82349837 495A +82349838 495B +82349839 495C +82349930 495D +82349931 495E +82349932 495F +82349933 4960 +82349934 4961 +82349935 4962 +82349936 4963 +82349937 4964 +82349938 4965 +82349939 4966 +82349A30 4967 +82349A31 4968 +82349A32 4969 +82349A33 496A +82349A34 496B +82349A35 496C +82349A36 496D +82349A37 496E +82349A38 496F +82349A39 4970 +82349B30 4971 +82349B31 4972 +82349B32 4973 +82349B33 4974 +82349B34 4975 +82349B35 4976 +82349B36 4977 +82349B37 4978 +82349B38 4979 +FE86 497A +82349B39 497B +82349C30 497C +FE87 497D +82349C31 497E +82349C32 497F +82349C33 4980 +82349C34 4981 +FE88 4982 +FE89 4983 +82349C35 4984 +FE8A 4985 +FE8B 4986 +82349C36 4987 +82349C37 4988 +82349C38 4989 +82349C39 498A +82349D30 498B +82349D31 498C +82349D32 498D +82349D33 498E +82349D34 498F +82349D35 4990 +82349D36 4991 +82349D37 4992 +82349D38 4993 +82349D39 4994 +82349E30 4995 +82349E31 4996 +82349E32 4997 +82349E33 4998 +82349E34 4999 +82349E35 499A +FE8D 499B +82349E36 499C +82349E37 499D +82349E38 499E +FE8C 499F +82349E39 49A0 +82349F30 49A1 +82349F31 49A2 +82349F32 49A3 +82349F33 49A4 +82349F34 49A5 +82349F35 49A6 +82349F36 49A7 +82349F37 49A8 +82349F38 49A9 +82349F39 49AA +8234A030 49AB +8234A031 49AC +8234A032 49AD +8234A033 49AE +8234A034 49AF +8234A035 49B0 +8234A036 49B1 +8234A037 49B2 +8234A038 49B3 +8234A039 49B4 +8234A130 49B5 +FE8F 49B6 +FE8E 49B7 +8234A131 49B8 +8234A132 49B9 +8234A133 49BA +8234A134 49BB +8234A135 49BC +8234A136 49BD +8234A137 49BE +8234A138 49BF +8234A139 49C0 +8234A230 49C1 +8234A231 49C2 +8234A232 49C3 +8234A233 49C4 +8234A234 49C5 +8234A235 49C6 +8234A236 49C7 +8234A237 49C8 +8234A238 49C9 +8234A239 49CA +8234A330 49CB +8234A331 49CC +8234A332 49CD +8234A333 49CE +8234A334 49CF +8234A335 49D0 +8234A336 49D1 +8234A337 49D2 +8234A338 49D3 +8234A339 49D4 +8234A430 49D5 +8234A431 49D6 +8234A432 49D7 +8234A433 49D8 +8234A434 49D9 +8234A435 49DA +8234A436 49DB +8234A437 49DC +8234A438 49DD +8234A439 49DE +8234A530 49DF +8234A531 49E0 +8234A532 49E1 +8234A533 49E2 +8234A534 49E3 +8234A535 49E4 +8234A536 49E5 +8234A537 49E6 +8234A538 49E7 +8234A539 49E8 +8234A630 49E9 +8234A631 49EA +8234A632 49EB +8234A633 49EC +8234A634 49ED +8234A635 49EE +8234A636 49EF +8234A637 49F0 +8234A638 49F1 +8234A639 49F2 +8234A730 49F3 +8234A731 49F4 +8234A732 49F5 +8234A733 49F6 +8234A734 49F7 +8234A735 49F8 +8234A736 49F9 +8234A737 49FA +8234A738 49FB +8234A739 49FC +8234A830 49FD +8234A831 49FE +8234A832 49FF +8234A833 4A00 +8234A834 4A01 +8234A835 4A02 +8234A836 4A03 +8234A837 4A04 +8234A838 4A05 +8234A839 4A06 +8234A930 4A07 +8234A931 4A08 +8234A932 4A09 +8234A933 4A0A +8234A934 4A0B +8234A935 4A0C +8234A936 4A0D +8234A937 4A0E +8234A938 4A0F +8234A939 4A10 +8234AA30 4A11 +8234AA31 4A12 +8234AA32 4A13 +8234AA33 4A14 +8234AA34 4A15 +8234AA35 4A16 +8234AA36 4A17 +8234AA37 4A18 +8234AA38 4A19 +8234AA39 4A1A +8234AB30 4A1B +8234AB31 4A1C +8234AB32 4A1D +8234AB33 4A1E +8234AB34 4A1F +8234AB35 4A20 +8234AB36 4A21 +8234AB37 4A22 +8234AB38 4A23 +8234AB39 4A24 +8234AC30 4A25 +8234AC31 4A26 +8234AC32 4A27 +8234AC33 4A28 +8234AC34 4A29 +8234AC35 4A2A +8234AC36 4A2B +8234AC37 4A2C +8234AC38 4A2D +8234AC39 4A2E +8234AD30 4A2F +8234AD31 4A30 +8234AD32 4A31 +8234AD33 4A32 +8234AD34 4A33 +8234AD35 4A34 +8234AD36 4A35 +8234AD37 4A36 +8234AD38 4A37 +8234AD39 4A38 +8234AE30 4A39 +8234AE31 4A3A +8234AE32 4A3B +8234AE33 4A3C +8234AE34 4A3D +8234AE35 4A3E +8234AE36 4A3F +8234AE37 4A40 +8234AE38 4A41 +8234AE39 4A42 +8234AF30 4A43 +8234AF31 4A44 +8234AF32 4A45 +8234AF33 4A46 +8234AF34 4A47 +8234AF35 4A48 +8234AF36 4A49 +8234AF37 4A4A +8234AF38 4A4B +8234AF39 4A4C +8234B030 4A4D +8234B031 4A4E +8234B032 4A4F +8234B033 4A50 +8234B034 4A51 +8234B035 4A52 +8234B036 4A53 +8234B037 4A54 +8234B038 4A55 +8234B039 4A56 +8234B130 4A57 +8234B131 4A58 +8234B132 4A59 +8234B133 4A5A +8234B134 4A5B +8234B135 4A5C +8234B136 4A5D +8234B137 4A5E +8234B138 4A5F +8234B139 4A60 +8234B230 4A61 +8234B231 4A62 +8234B232 4A63 +8234B233 4A64 +8234B234 4A65 +8234B235 4A66 +8234B236 4A67 +8234B237 4A68 +8234B238 4A69 +8234B239 4A6A +8234B330 4A6B +8234B331 4A6C +8234B332 4A6D +8234B333 4A6E +8234B334 4A6F +8234B335 4A70 +8234B336 4A71 +8234B337 4A72 +8234B338 4A73 +8234B339 4A74 +8234B430 4A75 +8234B431 4A76 +8234B432 4A77 +8234B433 4A78 +8234B434 4A79 +8234B435 4A7A +8234B436 4A7B +8234B437 4A7C +8234B438 4A7D +8234B439 4A7E +8234B530 4A7F +8234B531 4A80 +8234B532 4A81 +8234B533 4A82 +8234B534 4A83 +8234B535 4A84 +8234B536 4A85 +8234B537 4A86 +8234B538 4A87 +8234B539 4A88 +8234B630 4A89 +8234B631 4A8A +8234B632 4A8B +8234B633 4A8C +8234B634 4A8D +8234B635 4A8E +8234B636 4A8F +8234B637 4A90 +8234B638 4A91 +8234B639 4A92 +8234B730 4A93 +8234B731 4A94 +8234B732 4A95 +8234B733 4A96 +8234B734 4A97 +8234B735 4A98 +8234B736 4A99 +8234B737 4A9A +8234B738 4A9B +8234B739 4A9C +8234B830 4A9D +8234B831 4A9E +8234B832 4A9F +8234B833 4AA0 +8234B834 4AA1 +8234B835 4AA2 +8234B836 4AA3 +8234B837 4AA4 +8234B838 4AA5 +8234B839 4AA6 +8234B930 4AA7 +8234B931 4AA8 +8234B932 4AA9 +8234B933 4AAA +8234B934 4AAB +8234B935 4AAC +8234B936 4AAD +8234B937 4AAE +8234B938 4AAF +8234B939 4AB0 +8234BA30 4AB1 +8234BA31 4AB2 +8234BA32 4AB3 +8234BA33 4AB4 +8234BA34 4AB5 +8234BA35 4AB6 +8234BA36 4AB7 +8234BA37 4AB8 +8234BA38 4AB9 +8234BA39 4ABA +8234BB30 4ABB +8234BB31 4ABC +8234BB32 4ABD +8234BB33 4ABE +8234BB34 4ABF +8234BB35 4AC0 +8234BB36 4AC1 +8234BB37 4AC2 +8234BB38 4AC3 +8234BB39 4AC4 +8234BC30 4AC5 +8234BC31 4AC6 +8234BC32 4AC7 +8234BC33 4AC8 +8234BC34 4AC9 +8234BC35 4ACA +8234BC36 4ACB +8234BC37 4ACC +8234BC38 4ACD +8234BC39 4ACE +8234BD30 4ACF +8234BD31 4AD0 +8234BD32 4AD1 +8234BD33 4AD2 +8234BD34 4AD3 +8234BD35 4AD4 +8234BD36 4AD5 +8234BD37 4AD6 +8234BD38 4AD7 +8234BD39 4AD8 +8234BE30 4AD9 +8234BE31 4ADA +8234BE32 4ADB +8234BE33 4ADC +8234BE34 4ADD +8234BE35 4ADE +8234BE36 4ADF +8234BE37 4AE0 +8234BE38 4AE1 +8234BE39 4AE2 +8234BF30 4AE3 +8234BF31 4AE4 +8234BF32 4AE5 +8234BF33 4AE6 +8234BF34 4AE7 +8234BF35 4AE8 +8234BF36 4AE9 +8234BF37 4AEA +8234BF38 4AEB +8234BF39 4AEC +8234C030 4AED +8234C031 4AEE +8234C032 4AEF +8234C033 4AF0 +8234C034 4AF1 +8234C035 4AF2 +8234C036 4AF3 +8234C037 4AF4 +8234C038 4AF5 +8234C039 4AF6 +8234C130 4AF7 +8234C131 4AF8 +8234C132 4AF9 +8234C133 4AFA +8234C134 4AFB +8234C135 4AFC +8234C136 4AFD +8234C137 4AFE +8234C138 4AFF +8234C139 4B00 +8234C230 4B01 +8234C231 4B02 +8234C232 4B03 +8234C233 4B04 +8234C234 4B05 +8234C235 4B06 +8234C236 4B07 +8234C237 4B08 +8234C238 4B09 +8234C239 4B0A +8234C330 4B0B +8234C331 4B0C +8234C332 4B0D +8234C333 4B0E +8234C334 4B0F +8234C335 4B10 +8234C336 4B11 +8234C337 4B12 +8234C338 4B13 +8234C339 4B14 +8234C430 4B15 +8234C431 4B16 +8234C432 4B17 +8234C433 4B18 +8234C434 4B19 +8234C435 4B1A +8234C436 4B1B +8234C437 4B1C +8234C438 4B1D +8234C439 4B1E +8234C530 4B1F +8234C531 4B20 +8234C532 4B21 +8234C533 4B22 +8234C534 4B23 +8234C535 4B24 +8234C536 4B25 +8234C537 4B26 +8234C538 4B27 +8234C539 4B28 +8234C630 4B29 +8234C631 4B2A +8234C632 4B2B +8234C633 4B2C +8234C634 4B2D +8234C635 4B2E +8234C636 4B2F +8234C637 4B30 +8234C638 4B31 +8234C639 4B32 +8234C730 4B33 +8234C731 4B34 +8234C732 4B35 +8234C733 4B36 +8234C734 4B37 +8234C735 4B38 +8234C736 4B39 +8234C737 4B3A +8234C738 4B3B +8234C739 4B3C +8234C830 4B3D +8234C831 4B3E +8234C832 4B3F +8234C833 4B40 +8234C834 4B41 +8234C835 4B42 +8234C836 4B43 +8234C837 4B44 +8234C838 4B45 +8234C839 4B46 +8234C930 4B47 +8234C931 4B48 +8234C932 4B49 +8234C933 4B4A +8234C934 4B4B +8234C935 4B4C +8234C936 4B4D +8234C937 4B4E +8234C938 4B4F +8234C939 4B50 +8234CA30 4B51 +8234CA31 4B52 +8234CA32 4B53 +8234CA33 4B54 +8234CA34 4B55 +8234CA35 4B56 +8234CA36 4B57 +8234CA37 4B58 +8234CA38 4B59 +8234CA39 4B5A +8234CB30 4B5B +8234CB31 4B5C +8234CB32 4B5D +8234CB33 4B5E +8234CB34 4B5F +8234CB35 4B60 +8234CB36 4B61 +8234CB37 4B62 +8234CB38 4B63 +8234CB39 4B64 +8234CC30 4B65 +8234CC31 4B66 +8234CC32 4B67 +8234CC33 4B68 +8234CC34 4B69 +8234CC35 4B6A +8234CC36 4B6B +8234CC37 4B6C +8234CC38 4B6D +8234CC39 4B6E +8234CD30 4B6F +8234CD31 4B70 +8234CD32 4B71 +8234CD33 4B72 +8234CD34 4B73 +8234CD35 4B74 +8234CD36 4B75 +8234CD37 4B76 +8234CD38 4B77 +8234CD39 4B78 +8234CE30 4B79 +8234CE31 4B7A +8234CE32 4B7B +8234CE33 4B7C +8234CE34 4B7D +8234CE35 4B7E +8234CE36 4B7F +8234CE37 4B80 +8234CE38 4B81 +8234CE39 4B82 +8234CF30 4B83 +8234CF31 4B84 +8234CF32 4B85 +8234CF33 4B86 +8234CF34 4B87 +8234CF35 4B88 +8234CF36 4B89 +8234CF37 4B8A +8234CF38 4B8B +8234CF39 4B8C +8234D030 4B8D +8234D031 4B8E +8234D032 4B8F +8234D033 4B90 +8234D034 4B91 +8234D035 4B92 +8234D036 4B93 +8234D037 4B94 +8234D038 4B95 +8234D039 4B96 +8234D130 4B97 +8234D131 4B98 +8234D132 4B99 +8234D133 4B9A +8234D134 4B9B +8234D135 4B9C +8234D136 4B9D +8234D137 4B9E +8234D138 4B9F +8234D139 4BA0 +8234D230 4BA1 +8234D231 4BA2 +8234D232 4BA3 +8234D233 4BA4 +8234D234 4BA5 +8234D235 4BA6 +8234D236 4BA7 +8234D237 4BA8 +8234D238 4BA9 +8234D239 4BAA +8234D330 4BAB +8234D331 4BAC +8234D332 4BAD +8234D333 4BAE +8234D334 4BAF +8234D335 4BB0 +8234D336 4BB1 +8234D337 4BB2 +8234D338 4BB3 +8234D339 4BB4 +8234D430 4BB5 +8234D431 4BB6 +8234D432 4BB7 +8234D433 4BB8 +8234D434 4BB9 +8234D435 4BBA +8234D436 4BBB +8234D437 4BBC +8234D438 4BBD +8234D439 4BBE +8234D530 4BBF +8234D531 4BC0 +8234D532 4BC1 +8234D533 4BC2 +8234D534 4BC3 +8234D535 4BC4 +8234D536 4BC5 +8234D537 4BC6 +8234D538 4BC7 +8234D539 4BC8 +8234D630 4BC9 +8234D631 4BCA +8234D632 4BCB +8234D633 4BCC +8234D634 4BCD +8234D635 4BCE +8234D636 4BCF +8234D637 4BD0 +8234D638 4BD1 +8234D639 4BD2 +8234D730 4BD3 +8234D731 4BD4 +8234D732 4BD5 +8234D733 4BD6 +8234D734 4BD7 +8234D735 4BD8 +8234D736 4BD9 +8234D737 4BDA +8234D738 4BDB +8234D739 4BDC +8234D830 4BDD +8234D831 4BDE +8234D832 4BDF +8234D833 4BE0 +8234D834 4BE1 +8234D835 4BE2 +8234D836 4BE3 +8234D837 4BE4 +8234D838 4BE5 +8234D839 4BE6 +8234D930 4BE7 +8234D931 4BE8 +8234D932 4BE9 +8234D933 4BEA +8234D934 4BEB +8234D935 4BEC +8234D936 4BED +8234D937 4BEE +8234D938 4BEF +8234D939 4BF0 +8234DA30 4BF1 +8234DA31 4BF2 +8234DA32 4BF3 +8234DA33 4BF4 +8234DA34 4BF5 +8234DA35 4BF6 +8234DA36 4BF7 +8234DA37 4BF8 +8234DA38 4BF9 +8234DA39 4BFA +8234DB30 4BFB +8234DB31 4BFC +8234DB32 4BFD +8234DB33 4BFE +8234DB34 4BFF +8234DB35 4C00 +8234DB36 4C01 +8234DB37 4C02 +8234DB38 4C03 +8234DB39 4C04 +8234DC30 4C05 +8234DC31 4C06 +8234DC32 4C07 +8234DC33 4C08 +8234DC34 4C09 +8234DC35 4C0A +8234DC36 4C0B +8234DC37 4C0C +8234DC38 4C0D +8234DC39 4C0E +8234DD30 4C0F +8234DD31 4C10 +8234DD32 4C11 +8234DD33 4C12 +8234DD34 4C13 +8234DD35 4C14 +8234DD36 4C15 +8234DD37 4C16 +8234DD38 4C17 +8234DD39 4C18 +8234DE30 4C19 +8234DE31 4C1A +8234DE32 4C1B +8234DE33 4C1C +8234DE34 4C1D +8234DE35 4C1E +8234DE36 4C1F +8234DE37 4C20 +8234DE38 4C21 +8234DE39 4C22 +8234DF30 4C23 +8234DF31 4C24 +8234DF32 4C25 +8234DF33 4C26 +8234DF34 4C27 +8234DF35 4C28 +8234DF36 4C29 +8234DF37 4C2A +8234DF38 4C2B +8234DF39 4C2C +8234E030 4C2D +8234E031 4C2E +8234E032 4C2F +8234E033 4C30 +8234E034 4C31 +8234E035 4C32 +8234E036 4C33 +8234E037 4C34 +8234E038 4C35 +8234E039 4C36 +8234E130 4C37 +8234E131 4C38 +8234E132 4C39 +8234E133 4C3A +8234E134 4C3B +8234E135 4C3C +8234E136 4C3D +8234E137 4C3E +8234E138 4C3F +8234E139 4C40 +8234E230 4C41 +8234E231 4C42 +8234E232 4C43 +8234E233 4C44 +8234E234 4C45 +8234E235 4C46 +8234E236 4C47 +8234E237 4C48 +8234E238 4C49 +8234E239 4C4A +8234E330 4C4B +8234E331 4C4C +8234E332 4C4D +8234E333 4C4E +8234E334 4C4F +8234E335 4C50 +8234E336 4C51 +8234E337 4C52 +8234E338 4C53 +8234E339 4C54 +8234E430 4C55 +8234E431 4C56 +8234E432 4C57 +8234E433 4C58 +8234E434 4C59 +8234E435 4C5A +8234E436 4C5B +8234E437 4C5C +8234E438 4C5D +8234E439 4C5E +8234E530 4C5F +8234E531 4C60 +8234E532 4C61 +8234E533 4C62 +8234E534 4C63 +8234E535 4C64 +8234E536 4C65 +8234E537 4C66 +8234E538 4C67 +8234E539 4C68 +8234E630 4C69 +8234E631 4C6A +8234E632 4C6B +8234E633 4C6C +8234E634 4C6D +8234E635 4C6E +8234E636 4C6F +8234E637 4C70 +8234E638 4C71 +8234E639 4C72 +8234E730 4C73 +8234E731 4C74 +8234E732 4C75 +8234E733 4C76 +FE96 4C77 +8234E734 4C78 +8234E735 4C79 +8234E736 4C7A +8234E737 4C7B +8234E738 4C7C +8234E739 4C7D +8234E830 4C7E +8234E831 4C7F +8234E832 4C80 +8234E833 4C81 +8234E834 4C82 +8234E835 4C83 +8234E836 4C84 +8234E837 4C85 +8234E838 4C86 +8234E839 4C87 +8234E930 4C88 +8234E931 4C89 +8234E932 4C8A +8234E933 4C8B +8234E934 4C8C +8234E935 4C8D +8234E936 4C8E +8234E937 4C8F +8234E938 4C90 +8234E939 4C91 +8234EA30 4C92 +8234EA31 4C93 +8234EA32 4C94 +8234EA33 4C95 +8234EA34 4C96 +8234EA35 4C97 +8234EA36 4C98 +8234EA37 4C99 +8234EA38 4C9A +8234EA39 4C9B +8234EB30 4C9C +8234EB31 4C9D +8234EB32 4C9E +FE93 4C9F +FE94 4CA0 +FE95 4CA1 +FE97 4CA2 +FE92 4CA3 +8234EB33 4CA4 +8234EB34 4CA5 +8234EB35 4CA6 +8234EB36 4CA7 +8234EB37 4CA8 +8234EB38 4CA9 +8234EB39 4CAA +8234EC30 4CAB +8234EC31 4CAC +8234EC32 4CAD +8234EC33 4CAE +8234EC34 4CAF +8234EC35 4CB0 +8234EC36 4CB1 +8234EC37 4CB2 +8234EC38 4CB3 +8234EC39 4CB4 +8234ED30 4CB5 +8234ED31 4CB6 +8234ED32 4CB7 +8234ED33 4CB8 +8234ED34 4CB9 +8234ED35 4CBA +8234ED36 4CBB +8234ED37 4CBC +8234ED38 4CBD +8234ED39 4CBE +8234EE30 4CBF +8234EE31 4CC0 +8234EE32 4CC1 +8234EE33 4CC2 +8234EE34 4CC3 +8234EE35 4CC4 +8234EE36 4CC5 +8234EE37 4CC6 +8234EE38 4CC7 +8234EE39 4CC8 +8234EF30 4CC9 +8234EF31 4CCA +8234EF32 4CCB +8234EF33 4CCC +8234EF34 4CCD +8234EF35 4CCE +8234EF36 4CCF +8234EF37 4CD0 +8234EF38 4CD1 +8234EF39 4CD2 +8234F030 4CD3 +8234F031 4CD4 +8234F032 4CD5 +8234F033 4CD6 +8234F034 4CD7 +8234F035 4CD8 +8234F036 4CD9 +8234F037 4CDA +8234F038 4CDB +8234F039 4CDC +8234F130 4CDD +8234F131 4CDE +8234F132 4CDF +8234F133 4CE0 +8234F134 4CE1 +8234F135 4CE2 +8234F136 4CE3 +8234F137 4CE4 +8234F138 4CE5 +8234F139 4CE6 +8234F230 4CE7 +8234F231 4CE8 +8234F232 4CE9 +8234F233 4CEA +8234F234 4CEB +8234F235 4CEC +8234F236 4CED +8234F237 4CEE +8234F238 4CEF +8234F239 4CF0 +8234F330 4CF1 +8234F331 4CF2 +8234F332 4CF3 +8234F333 4CF4 +8234F334 4CF5 +8234F335 4CF6 +8234F336 4CF7 +8234F337 4CF8 +8234F338 4CF9 +8234F339 4CFA +8234F430 4CFB +8234F431 4CFC +8234F432 4CFD +8234F433 4CFE +8234F434 4CFF +8234F435 4D00 +8234F436 4D01 +8234F437 4D02 +8234F438 4D03 +8234F439 4D04 +8234F530 4D05 +8234F531 4D06 +8234F532 4D07 +8234F533 4D08 +8234F534 4D09 +8234F535 4D0A +8234F536 4D0B +8234F537 4D0C +8234F538 4D0D +8234F539 4D0E +8234F630 4D0F +8234F631 4D10 +8234F632 4D11 +8234F633 4D12 +FE98 4D13 +FE99 4D14 +FE9A 4D15 +FE9B 4D16 +FE9C 4D17 +FE9D 4D18 +FE9E 4D19 +8234F634 4D1A +8234F635 4D1B +8234F636 4D1C +8234F637 4D1D +8234F638 4D1E +8234F639 4D1F +8234F730 4D20 +8234F731 4D21 +8234F732 4D22 +8234F733 4D23 +8234F734 4D24 +8234F735 4D25 +8234F736 4D26 +8234F737 4D27 +8234F738 4D28 +8234F739 4D29 +8234F830 4D2A +8234F831 4D2B +8234F832 4D2C +8234F833 4D2D +8234F834 4D2E +8234F835 4D2F +8234F836 4D30 +8234F837 4D31 +8234F838 4D32 +8234F839 4D33 +8234F930 4D34 +8234F931 4D35 +8234F932 4D36 +8234F933 4D37 +8234F934 4D38 +8234F935 4D39 +8234F936 4D3A +8234F937 4D3B +8234F938 4D3C +8234F939 4D3D +8234FA30 4D3E +8234FA31 4D3F +8234FA32 4D40 +8234FA33 4D41 +8234FA34 4D42 +8234FA35 4D43 +8234FA36 4D44 +8234FA37 4D45 +8234FA38 4D46 +8234FA39 4D47 +8234FB30 4D48 +8234FB31 4D49 +8234FB32 4D4A +8234FB33 4D4B +8234FB34 4D4C +8234FB35 4D4D +8234FB36 4D4E +8234FB37 4D4F +8234FB38 4D50 +8234FB39 4D51 +8234FC30 4D52 +8234FC31 4D53 +8234FC32 4D54 +8234FC33 4D55 +8234FC34 4D56 +8234FC35 4D57 +8234FC36 4D58 +8234FC37 4D59 +8234FC38 4D5A +8234FC39 4D5B +8234FD30 4D5C +8234FD31 4D5D +8234FD32 4D5E +8234FD33 4D5F +8234FD34 4D60 +8234FD35 4D61 +8234FD36 4D62 +8234FD37 4D63 +8234FD38 4D64 +8234FD39 4D65 +8234FE30 4D66 +8234FE31 4D67 +8234FE32 4D68 +8234FE33 4D69 +8234FE34 4D6A +8234FE35 4D6B +8234FE36 4D6C +8234FE37 4D6D +8234FE38 4D6E +8234FE39 4D6F +82358130 4D70 +82358131 4D71 +82358132 4D72 +82358133 4D73 +82358134 4D74 +82358135 4D75 +82358136 4D76 +82358137 4D77 +82358138 4D78 +82358139 4D79 +82358230 4D7A +82358231 4D7B +82358232 4D7C +82358233 4D7D +82358234 4D7E +82358235 4D7F +82358236 4D80 +82358237 4D81 +82358238 4D82 +82358239 4D83 +82358330 4D84 +82358331 4D85 +82358332 4D86 +82358333 4D87 +82358334 4D88 +82358335 4D89 +82358336 4D8A +82358337 4D8B +82358338 4D8C +82358339 4D8D +82358430 4D8E +82358431 4D8F +82358432 4D90 +82358433 4D91 +82358434 4D92 +82358435 4D93 +82358436 4D94 +82358437 4D95 +82358438 4D96 +82358439 4D97 +82358530 4D98 +82358531 4D99 +82358532 4D9A +82358533 4D9B +82358534 4D9C +82358535 4D9D +82358536 4D9E +82358537 4D9F +82358538 4DA0 +82358539 4DA1 +82358630 4DA2 +82358631 4DA3 +82358632 4DA4 +82358633 4DA5 +82358634 4DA6 +82358635 4DA7 +82358636 4DA8 +82358637 4DA9 +82358638 4DAA +82358639 4DAB +82358730 4DAC +82358731 4DAD +FE9F 4DAE +82358732 4DAF +82358733 4DB0 +82358734 4DB1 +82358735 4DB2 +82358736 4DB3 +82358737 4DB4 +82358738 4DB5 +82358739 4DB6 +82358830 4DB7 +82358831 4DB8 +82358832 4DB9 +82358833 4DBA +82358834 4DBB +82358835 4DBC +82358836 4DBD +82358837 4DBE +82358838 4DBF +82358839 4DC0 +82358930 4DC1 +82358931 4DC2 +82358932 4DC3 +82358933 4DC4 +82358934 4DC5 +82358935 4DC6 +82358936 4DC7 +82358937 4DC8 +82358938 4DC9 +82358939 4DCA +82358A30 4DCB +82358A31 4DCC +82358A32 4DCD +82358A33 4DCE +82358A34 4DCF +82358A35 4DD0 +82358A36 4DD1 +82358A37 4DD2 +82358A38 4DD3 +82358A39 4DD4 +82358B30 4DD5 +82358B31 4DD6 +82358B32 4DD7 +82358B33 4DD8 +82358B34 4DD9 +82358B35 4DDA +82358B36 4DDB +82358B37 4DDC +82358B38 4DDD +82358B39 4DDE +82358C30 4DDF +82358C31 4DE0 +82358C32 4DE1 +82358C33 4DE2 +82358C34 4DE3 +82358C35 4DE4 +82358C36 4DE5 +82358C37 4DE6 +82358C38 4DE7 +82358C39 4DE8 +82358D30 4DE9 +82358D31 4DEA +82358D32 4DEB +82358D33 4DEC +82358D34 4DED +82358D35 4DEE +82358D36 4DEF +82358D37 4DF0 +82358D38 4DF1 +82358D39 4DF2 +82358E30 4DF3 +82358E31 4DF4 +82358E32 4DF5 +82358E33 4DF6 +82358E34 4DF7 +82358E35 4DF8 +82358E36 4DF9 +82358E37 4DFA +82358E38 4DFB +82358E39 4DFC +82358F30 4DFD +82358F31 4DFE +82358F32 4DFF +D2BB 4E00 +B6A1 4E01 +8140 4E02 +C6DF 4E03 +8141 4E04 +8142 4E05 +8143 4E06 +CDF2 4E07 +D5C9 4E08 +C8FD 4E09 +C9CF 4E0A +CFC2 4E0B +D8A2 4E0C +B2BB 4E0D +D3EB 4E0E +8144 4E0F +D8A4 4E10 +B3F3 4E11 +8145 4E12 +D7A8 4E13 +C7D2 4E14 +D8A7 4E15 +CAC0 4E16 +8146 4E17 +C7F0 4E18 +B1FB 4E19 +D2B5 4E1A +B4D4 4E1B +B6AB 4E1C +CBBF 4E1D +D8A9 4E1E +8147 4E1F +8148 4E20 +8149 4E21 +B6AA 4E22 +814A 4E23 +C1BD 4E24 +D1CF 4E25 +814B 4E26 +C9A5 4E27 +D8AD 4E28 +814C 4E29 +B8F6 4E2A +D1BE 4E2B +E3DC 4E2C +D6D0 4E2D +814D 4E2E +814E 4E2F +B7E1 4E30 +814F 4E31 +B4AE 4E32 +8150 4E33 +C1D9 4E34 +8151 4E35 +D8BC 4E36 +8152 4E37 +CDE8 4E38 +B5A4 4E39 +CEAA 4E3A +D6F7 4E3B +8153 4E3C +C0F6 4E3D +BED9 4E3E +D8AF 4E3F +8154 4E40 +8155 4E41 +8156 4E42 +C4CB 4E43 +8157 4E44 +BEC3 4E45 +8158 4E46 +D8B1 4E47 +C3B4 4E48 +D2E5 4E49 +8159 4E4A +D6AE 4E4B +CEDA 4E4C +D5A7 4E4D +BAF5 4E4E +B7A6 4E4F +C0D6 4E50 +815A 4E51 +C6B9 4E52 +C5D2 4E53 +C7C7 4E54 +815B 4E55 +B9D4 4E56 +815C 4E57 +B3CB 4E58 +D2D2 4E59 +815D 4E5A +815E 4E5B +D8BF 4E5C +BEC5 4E5D +C6F2 4E5E +D2B2 4E5F +CFB0 4E60 +CFE7 4E61 +815F 4E62 +8160 4E63 +8161 4E64 +8162 4E65 +CAE9 4E66 +8163 4E67 +8164 4E68 +D8C0 4E69 +8165 4E6A +8166 4E6B +8167 4E6C +8168 4E6D +8169 4E6E +816A 4E6F +C2F2 4E70 +C2D2 4E71 +816B 4E72 +C8E9 4E73 +816C 4E74 +816D 4E75 +816E 4E76 +816F 4E77 +8170 4E78 +8171 4E79 +8172 4E7A +8173 4E7B +8174 4E7C +8175 4E7D +C7AC 4E7E +8176 4E7F +8177 4E80 +8178 4E81 +8179 4E82 +817A 4E83 +817B 4E84 +817C 4E85 +C1CB 4E86 +817D 4E87 +D3E8 4E88 +D5F9 4E89 +817E 4E8A +CAC2 4E8B +B6FE 4E8C +D8A1 4E8D +D3DA 4E8E +BFF7 4E8F +8180 4E90 +D4C6 4E91 +BBA5 4E92 +D8C1 4E93 +CEE5 4E94 +BEAE 4E95 +8181 4E96 +8182 4E97 +D8A8 4E98 +8183 4E99 +D1C7 4E9A +D0A9 4E9B +8184 4E9C +8185 4E9D +8186 4E9E +D8BD 4E9F +D9EF 4EA0 +CDF6 4EA1 +BFBA 4EA2 +8187 4EA3 +BDBB 4EA4 +BAA5 4EA5 +D2E0 4EA6 +B2FA 4EA7 +BAE0 4EA8 +C4B6 4EA9 +8188 4EAA +CFED 4EAB +BEA9 4EAC +CDA4 4EAD +C1C1 4EAE +8189 4EAF +818A 4EB0 +818B 4EB1 +C7D7 4EB2 +D9F1 4EB3 +818C 4EB4 +D9F4 4EB5 +818D 4EB6 +818E 4EB7 +818F 4EB8 +8190 4EB9 +C8CB 4EBA +D8E9 4EBB +8191 4EBC +8192 4EBD +8193 4EBE +D2DA 4EBF +CAB2 4EC0 +C8CA 4EC1 +D8EC 4EC2 +D8EA 4EC3 +D8C6 4EC4 +BDF6 4EC5 +C6CD 4EC6 +B3F0 4EC7 +8194 4EC8 +D8EB 4EC9 +BDF1 4ECA +BDE9 4ECB +8195 4ECC +C8D4 4ECD +B4D3 4ECE +8196 4ECF +8197 4ED0 +C2D8 4ED1 +8198 4ED2 +B2D6 4ED3 +D7D0 4ED4 +CACB 4ED5 +CBFB 4ED6 +D5CC 4ED7 +B8B6 4ED8 +CFC9 4ED9 +8199 4EDA +819A 4EDB +819B 4EDC +D9DA 4EDD +D8F0 4EDE +C7AA 4EDF +819C 4EE0 +D8EE 4EE1 +819D 4EE2 +B4FA 4EE3 +C1EE 4EE4 +D2D4 4EE5 +819E 4EE6 +819F 4EE7 +D8ED 4EE8 +81A0 4EE9 +D2C7 4EEA +D8EF 4EEB +C3C7 4EEC +81A1 4EED +81A2 4EEE +81A3 4EEF +D1F6 4EF0 +81A4 4EF1 +D6D9 4EF2 +D8F2 4EF3 +81A5 4EF4 +D8F5 4EF5 +BCFE 4EF6 +BCDB 4EF7 +81A6 4EF8 +81A7 4EF9 +81A8 4EFA +C8CE 4EFB +81A9 4EFC +B7DD 4EFD +81AA 4EFE +B7C2 4EFF +81AB 4F00 +C6F3 4F01 +81AC 4F02 +81AD 4F03 +81AE 4F04 +81AF 4F05 +81B0 4F06 +81B1 4F07 +81B2 4F08 +D8F8 4F09 +D2C1 4F0A +81B3 4F0B +81B4 4F0C +CEE9 4F0D +BCBF 4F0E +B7FC 4F0F +B7A5 4F10 +D0DD 4F11 +81B5 4F12 +81B6 4F13 +81B7 4F14 +81B8 4F15 +81B9 4F16 +D6DA 4F17 +D3C5 4F18 +BBEF 4F19 +BBE1 4F1A +D8F1 4F1B +81BA 4F1C +81BB 4F1D +C9A1 4F1E +CEB0 4F1F +B4AB 4F20 +81BC 4F21 +D8F3 4F22 +81BD 4F23 +C9CB 4F24 +D8F6 4F25 +C2D7 4F26 +D8F7 4F27 +81BE 4F28 +81BF 4F29 +CEB1 4F2A +D8F9 4F2B +81C0 4F2C +81C1 4F2D +81C2 4F2E +B2AE 4F2F +B9C0 4F30 +81C3 4F31 +D9A3 4F32 +81C4 4F33 +B0E9 4F34 +81C5 4F35 +C1E6 4F36 +81C6 4F37 +C9EC 4F38 +81C7 4F39 +CBC5 4F3A +81C8 4F3B +CBC6 4F3C +D9A4 4F3D +81C9 4F3E +81CA 4F3F +81CB 4F40 +81CC 4F41 +81CD 4F42 +B5E8 4F43 +81CE 4F44 +81CF 4F45 +B5AB 4F46 +81D0 4F47 +81D1 4F48 +81D2 4F49 +81D3 4F4A +81D4 4F4B +81D5 4F4C +CEBB 4F4D +B5CD 4F4E +D7A1 4F4F +D7F4 4F50 +D3D3 4F51 +81D6 4F52 +CCE5 4F53 +81D7 4F54 +BACE 4F55 +81D8 4F56 +D9A2 4F57 +D9DC 4F58 +D3E0 4F59 +D8FD 4F5A +B7F0 4F5B +D7F7 4F5C +D8FE 4F5D +D8FA 4F5E +D9A1 4F5F +C4E3 4F60 +81D9 4F61 +81DA 4F62 +D3B6 4F63 +D8F4 4F64 +D9DD 4F65 +81DB 4F66 +D8FB 4F67 +81DC 4F68 +C5E5 4F69 +81DD 4F6A +81DE 4F6B +C0D0 4F6C +81DF 4F6D +81E0 4F6E +D1F0 4F6F +B0DB 4F70 +81E1 4F71 +81E2 4F72 +BCD1 4F73 +D9A6 4F74 +81E3 4F75 +D9A5 4F76 +81E4 4F77 +81E5 4F78 +81E6 4F79 +81E7 4F7A +D9AC 4F7B +D9AE 4F7C +81E8 4F7D +D9AB 4F7E +CAB9 4F7F +81E9 4F80 +81EA 4F81 +81EB 4F82 +D9A9 4F83 +D6B6 4F84 +81EC 4F85 +81ED 4F86 +81EE 4F87 +B3DE 4F88 +D9A8 4F89 +81EF 4F8A +C0FD 4F8B +81F0 4F8C +CACC 4F8D +81F1 4F8E +D9AA 4F8F +81F2 4F90 +D9A7 4F91 +81F3 4F92 +81F4 4F93 +D9B0 4F94 +81F5 4F95 +81F6 4F96 +B6B1 4F97 +81F7 4F98 +81F8 4F99 +81F9 4F9A +B9A9 4F9B +81FA 4F9C +D2C0 4F9D +81FB 4F9E +81FC 4F9F +CFC0 4FA0 +81FD 4FA1 +81FE 4FA2 +C2C2 4FA3 +8240 4FA4 +BDC4 4FA5 +D5EC 4FA6 +B2E0 4FA7 +C7C8 4FA8 +BFEB 4FA9 +D9AD 4FAA +8241 4FAB +D9AF 4FAC +8242 4FAD +CEEA 4FAE +BAEE 4FAF +8243 4FB0 +8244 4FB1 +8245 4FB2 +8246 4FB3 +8247 4FB4 +C7D6 4FB5 +8248 4FB6 +8249 4FB7 +824A 4FB8 +824B 4FB9 +824C 4FBA +824D 4FBB +824E 4FBC +824F 4FBD +8250 4FBE +B1E3 4FBF +8251 4FC0 +8252 4FC1 +8253 4FC2 +B4D9 4FC3 +B6ED 4FC4 +D9B4 4FC5 +8254 4FC6 +8255 4FC7 +8256 4FC8 +8257 4FC9 +BFA1 4FCA +8258 4FCB +8259 4FCC +825A 4FCD +D9DE 4FCE +C7CE 4FCF +C0FE 4FD0 +D9B8 4FD1 +825B 4FD2 +825C 4FD3 +825D 4FD4 +825E 4FD5 +825F 4FD6 +CBD7 4FD7 +B7FD 4FD8 +8260 4FD9 +D9B5 4FDA +8261 4FDB +D9B7 4FDC +B1A3 4FDD +D3E1 4FDE +D9B9 4FDF +8262 4FE0 +D0C5 4FE1 +8263 4FE2 +D9B6 4FE3 +8264 4FE4 +8265 4FE5 +D9B1 4FE6 +8266 4FE7 +D9B2 4FE8 +C1A9 4FE9 +D9B3 4FEA +8267 4FEB +8268 4FEC +BCF3 4FED +D0DE 4FEE +B8A9 4FEF +8269 4FF0 +BEE3 4FF1 +826A 4FF2 +D9BD 4FF3 +826B 4FF4 +826C 4FF5 +826D 4FF6 +826E 4FF7 +D9BA 4FF8 +826F 4FF9 +B0B3 4FFA +8270 4FFB +8271 4FFC +8272 4FFD +D9C2 4FFE +8273 4FFF +8274 5000 +8275 5001 +8276 5002 +8277 5003 +8278 5004 +8279 5005 +827A 5006 +827B 5007 +827C 5008 +827D 5009 +827E 500A +8280 500B +D9C4 500C +B1B6 500D +8281 500E +D9BF 500F +8282 5010 +8283 5011 +B5B9 5012 +8284 5013 +BEF3 5014 +8285 5015 +8286 5016 +8287 5017 +CCC8 5018 +BAF2 5019 +D2D0 501A +8288 501B +D9C3 501C +8289 501D +828A 501E +BDE8 501F +828B 5020 +B3AB 5021 +828C 5022 +828D 5023 +828E 5024 +D9C5 5025 +BEEB 5026 +828F 5027 +D9C6 5028 +D9BB 5029 +C4DF 502A +8290 502B +D9BE 502C +D9C1 502D +D9C0 502E +8291 502F +8292 5030 +8293 5031 +8294 5032 +8295 5033 +8296 5034 +8297 5035 +8298 5036 +8299 5037 +829A 5038 +829B 5039 +D5AE 503A +829C 503B +D6B5 503C +829D 503D +C7E3 503E +829E 503F +829F 5040 +82A0 5041 +82A1 5042 +D9C8 5043 +82A2 5044 +82A3 5045 +82A4 5046 +BCD9 5047 +D9CA 5048 +82A5 5049 +82A6 504A +82A7 504B +D9BC 504C +82A8 504D +D9CB 504E +C6AB 504F +82A9 5050 +82AA 5051 +82AB 5052 +82AC 5053 +82AD 5054 +D9C9 5055 +82AE 5056 +82AF 5057 +82B0 5058 +82B1 5059 +D7F6 505A +82B2 505B +CDA3 505C +82B3 505D +82B4 505E +82B5 505F +82B6 5060 +82B7 5061 +82B8 5062 +82B9 5063 +82BA 5064 +BDA1 5065 +82BB 5066 +82BC 5067 +82BD 5068 +82BE 5069 +82BF 506A +82C0 506B +D9CC 506C +82C1 506D +82C2 506E +82C3 506F +82C4 5070 +82C5 5071 +82C6 5072 +82C7 5073 +82C8 5074 +82C9 5075 +C5BC 5076 +CDB5 5077 +82CA 5078 +82CB 5079 +82CC 507A +D9CD 507B +82CD 507C +82CE 507D +D9C7 507E +B3A5 507F +BFFE 5080 +82CF 5081 +82D0 5082 +82D1 5083 +82D2 5084 +B8B5 5085 +82D3 5086 +82D4 5087 +C0FC 5088 +82D5 5089 +82D6 508A +82D7 508B +82D8 508C +B0F8 508D +82D9 508E +82DA 508F +82DB 5090 +82DC 5091 +82DD 5092 +82DE 5093 +82DF 5094 +82E0 5095 +82E1 5096 +82E2 5097 +82E3 5098 +82E4 5099 +82E5 509A +82E6 509B +82E7 509C +82E8 509D +82E9 509E +82EA 509F +82EB 50A0 +82EC 50A1 +82ED 50A2 +B4F6 50A3 +82EE 50A4 +D9CE 50A5 +82EF 50A6 +D9CF 50A7 +B4A2 50A8 +D9D0 50A9 +82F0 50AA +82F1 50AB +B4DF 50AC +82F2 50AD +82F3 50AE +82F4 50AF +82F5 50B0 +82F6 50B1 +B0C1 50B2 +82F7 50B3 +82F8 50B4 +82F9 50B5 +82FA 50B6 +82FB 50B7 +82FC 50B8 +82FD 50B9 +D9D1 50BA +C9B5 50BB +82FE 50BC +8340 50BD +8341 50BE +8342 50BF +8343 50C0 +8344 50C1 +8345 50C2 +8346 50C3 +8347 50C4 +8348 50C5 +8349 50C6 +834A 50C7 +834B 50C8 +834C 50C9 +834D 50CA +834E 50CB +834F 50CC +8350 50CD +8351 50CE +CFF1 50CF +8352 50D0 +8353 50D1 +8354 50D2 +8355 50D3 +8356 50D4 +8357 50D5 +D9D2 50D6 +8358 50D7 +8359 50D8 +835A 50D9 +C1C5 50DA +835B 50DB +835C 50DC +835D 50DD +835E 50DE +835F 50DF +8360 50E0 +8361 50E1 +8362 50E2 +8363 50E3 +8364 50E4 +8365 50E5 +D9D6 50E6 +C9AE 50E7 +8366 50E8 +8367 50E9 +8368 50EA +8369 50EB +D9D5 50EC +D9D4 50ED +D9D7 50EE +836A 50EF +836B 50F0 +836C 50F1 +836D 50F2 +CBDB 50F3 +836E 50F4 +BDA9 50F5 +836F 50F6 +8370 50F7 +8371 50F8 +8372 50F9 +8373 50FA +C6A7 50FB +8374 50FC +8375 50FD +8376 50FE +8377 50FF +8378 5100 +8379 5101 +837A 5102 +837B 5103 +837C 5104 +837D 5105 +D9D3 5106 +D9D8 5107 +837E 5108 +8380 5109 +8381 510A +D9D9 510B +8382 510C +8383 510D +8384 510E +8385 510F +8386 5110 +8387 5111 +C8E5 5112 +8388 5113 +8389 5114 +838A 5115 +838B 5116 +838C 5117 +838D 5118 +838E 5119 +838F 511A +8390 511B +8391 511C +8392 511D +8393 511E +8394 511F +8395 5120 +C0DC 5121 +8396 5122 +8397 5123 +8398 5124 +8399 5125 +839A 5126 +839B 5127 +839C 5128 +839D 5129 +839E 512A +839F 512B +83A0 512C +83A1 512D +83A2 512E +83A3 512F +83A4 5130 +83A5 5131 +83A6 5132 +83A7 5133 +83A8 5134 +83A9 5135 +83AA 5136 +83AB 5137 +83AC 5138 +83AD 5139 +83AE 513A +83AF 513B +83B0 513C +83B1 513D +83B2 513E +B6F9 513F +D8A3 5140 +D4CA 5141 +83B3 5142 +D4AA 5143 +D0D6 5144 +B3E4 5145 +D5D7 5146 +83B4 5147 +CFC8 5148 +B9E2 5149 +83B5 514A +BFCB 514B +83B6 514C +C3E2 514D +83B7 514E +83B8 514F +83B9 5150 +B6D2 5151 +83BA 5152 +83BB 5153 +CDC3 5154 +D9EE 5155 +D9F0 5156 +83BC 5157 +83BD 5158 +83BE 5159 +B5B3 515A +83BF 515B +B6B5 515C +83C0 515D +83C1 515E +83C2 515F +83C3 5160 +83C4 5161 +BEA4 5162 +83C5 5163 +83C6 5164 +C8EB 5165 +83C7 5166 +83C8 5167 +C8AB 5168 +83C9 5169 +83CA 516A +B0CB 516B +B9AB 516C +C1F9 516D +D9E2 516E +83CB 516F +C0BC 5170 +B9B2 5171 +83CC 5172 +B9D8 5173 +D0CB 5174 +B1F8 5175 +C6E4 5176 +BEDF 5177 +B5E4 5178 +D7C8 5179 +83CD 517A +D1F8 517B +BCE6 517C +CADE 517D +83CE 517E +83CF 517F +BCBD 5180 +D9E6 5181 +D8E7 5182 +83D0 5183 +83D1 5184 +C4DA 5185 +83D2 5186 +83D3 5187 +B8D4 5188 +C8BD 5189 +83D4 518A +83D5 518B +B2E1 518C +D4D9 518D +83D6 518E +83D7 518F +83D8 5190 +83D9 5191 +C3B0 5192 +83DA 5193 +83DB 5194 +C3E1 5195 +DAA2 5196 +C8DF 5197 +83DC 5198 +D0B4 5199 +83DD 519A +BEFC 519B +C5A9 519C +83DE 519D +83DF 519E +83E0 519F +B9DA 51A0 +83E1 51A1 +DAA3 51A2 +83E2 51A3 +D4A9 51A4 +DAA4 51A5 +83E3 51A6 +83E4 51A7 +83E5 51A8 +83E6 51A9 +83E7 51AA +D9FB 51AB +B6AC 51AC +83E8 51AD +83E9 51AE +B7EB 51AF +B1F9 51B0 +D9FC 51B1 +B3E5 51B2 +BEF6 51B3 +83EA 51B4 +BFF6 51B5 +D2B1 51B6 +C0E4 51B7 +83EB 51B8 +83EC 51B9 +83ED 51BA +B6B3 51BB +D9FE 51BC +D9FD 51BD +83EE 51BE +83EF 51BF +BEBB 51C0 +83F0 51C1 +83F1 51C2 +83F2 51C3 +C6E0 51C4 +83F3 51C5 +D7BC 51C6 +DAA1 51C7 +83F4 51C8 +C1B9 51C9 +83F5 51CA +B5F2 51CB +C1E8 51CC +83F6 51CD +83F7 51CE +BCF5 51CF +83F8 51D0 +B4D5 51D1 +83F9 51D2 +83FA 51D3 +83FB 51D4 +83FC 51D5 +83FD 51D6 +83FE 51D7 +8440 51D8 +8441 51D9 +8442 51DA +C1DD 51DB +8443 51DC +C4FD 51DD +8444 51DE +8445 51DF +BCB8 51E0 +B7B2 51E1 +8446 51E2 +8447 51E3 +B7EF 51E4 +8448 51E5 +8449 51E6 +844A 51E7 +844B 51E8 +844C 51E9 +844D 51EA +D9EC 51EB +844E 51EC +C6BE 51ED +844F 51EE +BFAD 51EF +BBCB 51F0 +8450 51F1 +8451 51F2 +B5CA 51F3 +8452 51F4 +DBC9 51F5 +D0D7 51F6 +8453 51F7 +CDB9 51F8 +B0BC 51F9 +B3F6 51FA +BBF7 51FB +DBCA 51FC +BAAF 51FD +8454 51FE +D4E4 51FF +B5B6 5200 +B5F3 5201 +D8D6 5202 +C8D0 5203 +8455 5204 +8456 5205 +B7D6 5206 +C7D0 5207 +D8D7 5208 +8457 5209 +BFAF 520A +8458 520B +8459 520C +DBBB 520D +D8D8 520E +845A 520F +845B 5210 +D0CC 5211 +BBAE 5212 +845C 5213 +845D 5214 +845E 5215 +EBBE 5216 +C1D0 5217 +C1F5 5218 +D4F2 5219 +B8D5 521A +B4B4 521B +845F 521C +B3F5 521D +8460 521E +8461 521F +C9BE 5220 +8462 5221 +8463 5222 +8464 5223 +C5D0 5224 +8465 5225 +8466 5226 +8467 5227 +C5D9 5228 +C0FB 5229 +8468 522A +B1F0 522B +8469 522C +D8D9 522D +B9CE 522E +846A 522F +B5BD 5230 +846B 5231 +846C 5232 +D8DA 5233 +846D 5234 +846E 5235 +D6C6 5236 +CBA2 5237 +C8AF 5238 +C9B2 5239 +B4CC 523A +BFCC 523B +846F 523C +B9F4 523D +8470 523E +D8DB 523F +D8DC 5240 +B6E7 5241 +BCC1 5242 +CCEA 5243 +8471 5244 +8472 5245 +8473 5246 +8474 5247 +8475 5248 +8476 5249 +CFF7 524A +8477 524B +D8DD 524C +C7B0 524D +8478 524E +8479 524F +B9D0 5250 +BDA3 5251 +847A 5252 +847B 5253 +CCDE 5254 +847C 5255 +C6CA 5256 +847D 5257 +847E 5258 +8480 5259 +8481 525A +8482 525B +D8E0 525C +8483 525D +D8DE 525E +8484 525F +8485 5260 +D8DF 5261 +8486 5262 +8487 5263 +8488 5264 +B0FE 5265 +8489 5266 +BEE7 5267 +848A 5268 +CAA3 5269 +BCF4 526A +848B 526B +848C 526C +848D 526D +848E 526E +B8B1 526F +848F 5270 +8490 5271 +B8EE 5272 +8491 5273 +8492 5274 +8493 5275 +8494 5276 +8495 5277 +8496 5278 +8497 5279 +8498 527A +8499 527B +849A 527C +D8E2 527D +849B 527E +BDCB 527F +849C 5280 +D8E4 5281 +D8E3 5282 +849D 5283 +849E 5284 +849F 5285 +84A0 5286 +84A1 5287 +C5FC 5288 +84A2 5289 +84A3 528A +84A4 528B +84A5 528C +84A6 528D +84A7 528E +84A8 528F +D8E5 5290 +84A9 5291 +84AA 5292 +D8E6 5293 +84AB 5294 +84AC 5295 +84AD 5296 +84AE 5297 +84AF 5298 +84B0 5299 +84B1 529A +C1A6 529B +84B2 529C +C8B0 529D +B0EC 529E +B9A6 529F +BCD3 52A0 +CEF1 52A1 +DBBD 52A2 +C1D3 52A3 +84B3 52A4 +84B4 52A5 +84B5 52A6 +84B6 52A7 +B6AF 52A8 +D6FA 52A9 +C5AC 52AA +BDD9 52AB +DBBE 52AC +DBBF 52AD +84B7 52AE +84B8 52AF +84B9 52B0 +C0F8 52B1 +BEA2 52B2 +C0CD 52B3 +84BA 52B4 +84BB 52B5 +84BC 52B6 +84BD 52B7 +84BE 52B8 +84BF 52B9 +84C0 52BA +84C1 52BB +84C2 52BC +84C3 52BD +DBC0 52BE +CAC6 52BF +84C4 52C0 +84C5 52C1 +84C6 52C2 +B2AA 52C3 +84C7 52C4 +84C8 52C5 +84C9 52C6 +D3C2 52C7 +84CA 52C8 +C3E3 52C9 +84CB 52CA +D1AB 52CB +84CC 52CC +84CD 52CD +84CE 52CE +84CF 52CF +DBC2 52D0 +84D0 52D1 +C0D5 52D2 +84D1 52D3 +84D2 52D4 +84D3 52D5 +DBC3 52D6 +84D4 52D7 +BFB1 52D8 +84D5 52D9 +84D6 52DA +84D7 52DB +84D8 52DC +84D9 52DD +84DA 52DE +C4BC 52DF +84DB 52E0 +84DC 52E1 +84DD 52E2 +84DE 52E3 +C7DA 52E4 +84DF 52E5 +84E0 52E6 +84E1 52E7 +84E2 52E8 +84E3 52E9 +84E4 52EA +84E5 52EB +84E6 52EC +84E7 52ED +84E8 52EE +84E9 52EF +DBC4 52F0 +84EA 52F1 +84EB 52F2 +84EC 52F3 +84ED 52F4 +84EE 52F5 +84EF 52F6 +84F0 52F7 +84F1 52F8 +D9E8 52F9 +C9D7 52FA +84F2 52FB +84F3 52FC +84F4 52FD +B9B4 52FE +CEF0 52FF +D4C8 5300 +84F5 5301 +84F6 5302 +84F7 5303 +84F8 5304 +B0FC 5305 +B4D2 5306 +84F9 5307 +D0D9 5308 +84FA 5309 +84FB 530A +84FC 530B +84FD 530C +D9E9 530D +84FE 530E +DECB 530F +D9EB 5310 +8540 5311 +8541 5312 +8542 5313 +8543 5314 +D8B0 5315 +BBAF 5316 +B1B1 5317 +8544 5318 +B3D7 5319 +D8CE 531A +8545 531B +8546 531C +D4D1 531D +8547 531E +8548 531F +BDB3 5320 +BFEF 5321 +8549 5322 +CFBB 5323 +854A 5324 +854B 5325 +D8D0 5326 +854C 5327 +854D 5328 +854E 5329 +B7CB 532A +854F 532B +8550 532C +8551 532D +D8D1 532E +8552 532F +8553 5330 +8554 5331 +8555 5332 +8556 5333 +8557 5334 +8558 5335 +8559 5336 +855A 5337 +855B 5338 +C6A5 5339 +C7F8 533A +D2BD 533B +855C 533C +855D 533D +D8D2 533E +C4E4 533F +855E 5340 +CAAE 5341 +855F 5342 +C7A7 5343 +8560 5344 +D8A6 5345 +8561 5346 +C9FD 5347 +CEE7 5348 +BBDC 5349 +B0EB 534A +8562 534B +8563 534C +8564 534D +BBAA 534E +D0AD 534F +8565 5350 +B1B0 5351 +D7E4 5352 +D7BF 5353 +8566 5354 +B5A5 5355 +C2F4 5356 +C4CF 5357 +8567 5358 +8568 5359 +B2A9 535A +8569 535B +B2B7 535C +856A 535D +B1E5 535E +DFB2 535F +D5BC 5360 +BFA8 5361 +C2AC 5362 +D8D5 5363 +C2B1 5364 +856B 5365 +D8D4 5366 +CED4 5367 +856C 5368 +DAE0 5369 +856D 536A +CEC0 536B +856E 536C +856F 536D +D8B4 536E +C3AE 536F +D3A1 5370 +CEA3 5371 +8570 5372 +BCB4 5373 +C8B4 5374 +C2D1 5375 +8571 5376 +BEED 5377 +D0B6 5378 +8572 5379 +DAE1 537A +8573 537B +8574 537C +8575 537D +8576 537E +C7E4 537F +8577 5380 +8578 5381 +B3A7 5382 +8579 5383 +B6F2 5384 +CCFC 5385 +C0FA 5386 +857A 5387 +857B 5388 +C0F7 5389 +857C 538A +D1B9 538B +D1E1 538C +D8C7 538D +857D 538E +857E 538F +8580 5390 +8581 5391 +8582 5392 +8583 5393 +8584 5394 +B2DE 5395 +8585 5396 +8586 5397 +C0E5 5398 +8587 5399 +BAF1 539A +8588 539B +8589 539C +D8C8 539D +858A 539E +D4AD 539F +858B 53A0 +858C 53A1 +CFE1 53A2 +D8C9 53A3 +858D 53A4 +D8CA 53A5 +CFC3 53A6 +858E 53A7 +B3F8 53A8 +BEC7 53A9 +858F 53AA +8590 53AB +8591 53AC +8592 53AD +D8CB 53AE +8593 53AF +8594 53B0 +8595 53B1 +8596 53B2 +8597 53B3 +8598 53B4 +8599 53B5 +DBCC 53B6 +859A 53B7 +859B 53B8 +859C 53B9 +859D 53BA +C8A5 53BB +859E 53BC +859F 53BD +85A0 53BE +CFD8 53BF +85A1 53C0 +C8FE 53C1 +B2CE 53C2 +85A2 53C3 +85A3 53C4 +85A4 53C5 +85A5 53C6 +85A6 53C7 +D3D6 53C8 +B2E6 53C9 +BCB0 53CA +D3D1 53CB +CBAB 53CC +B7B4 53CD +85A7 53CE +85A8 53CF +85A9 53D0 +B7A2 53D1 +85AA 53D2 +85AB 53D3 +CAE5 53D4 +85AC 53D5 +C8A1 53D6 +CADC 53D7 +B1E4 53D8 +D0F0 53D9 +85AD 53DA +C5D1 53DB +85AE 53DC +85AF 53DD +85B0 53DE +DBC5 53DF +B5FE 53E0 +85B1 53E1 +85B2 53E2 +BFDA 53E3 +B9C5 53E4 +BEE4 53E5 +C1ED 53E6 +85B3 53E7 +DFB6 53E8 +DFB5 53E9 +D6BB 53EA +BDD0 53EB +D5D9 53EC +B0C8 53ED +B6A3 53EE +BFC9 53EF +CCA8 53F0 +DFB3 53F1 +CAB7 53F2 +D3D2 53F3 +85B4 53F4 +D8CF 53F5 +D2B6 53F6 +BAC5 53F7 +CBBE 53F8 +CCBE 53F9 +85B5 53FA +DFB7 53FB +B5F0 53FC +DFB4 53FD +85B6 53FE +85B7 53FF +85B8 5400 +D3F5 5401 +85B9 5402 +B3D4 5403 +B8F7 5404 +85BA 5405 +DFBA 5406 +85BB 5407 +BACF 5408 +BCAA 5409 +B5F5 540A +85BC 540B +CDAC 540C +C3FB 540D +BAF3 540E +C0F4 540F +CDC2 5410 +CFF2 5411 +DFB8 5412 +CFC5 5413 +85BD 5414 +C2C0 5415 +DFB9 5416 +C2F0 5417 +85BE 5418 +85BF 5419 +85C0 541A +BEFD 541B +85C1 541C +C1DF 541D +CDCC 541E +D2F7 541F +B7CD 5420 +DFC1 5421 +85C2 5422 +DFC4 5423 +85C3 5424 +85C4 5425 +B7F1 5426 +B0C9 5427 +B6D6 5428 +B7D4 5429 +85C5 542A +BAAC 542B +CCFD 542C +BFD4 542D +CBB1 542E +C6F4 542F +85C6 5430 +D6A8 5431 +DFC5 5432 +85C7 5433 +CEE2 5434 +B3B3 5435 +85C8 5436 +85C9 5437 +CEFC 5438 +B4B5 5439 +85CA 543A +CEC7 543B +BAF0 543C +85CB 543D +CEE1 543E +85CC 543F +D1BD 5440 +85CD 5441 +85CE 5442 +DFC0 5443 +85CF 5444 +85D0 5445 +B4F4 5446 +85D1 5447 +B3CA 5448 +85D2 5449 +B8E6 544A +DFBB 544B +85D3 544C +85D4 544D +85D5 544E +85D6 544F +C4C5 5450 +85D7 5451 +DFBC 5452 +DFBD 5453 +DFBE 5454 +C5BB 5455 +DFBF 5456 +DFC2 5457 +D4B1 5458 +DFC3 5459 +85D8 545A +C7BA 545B +CED8 545C +85D9 545D +85DA 545E +85DB 545F +85DC 5460 +85DD 5461 +C4D8 5462 +85DE 5463 +DFCA 5464 +85DF 5465 +DFCF 5466 +85E0 5467 +D6DC 5468 +85E1 5469 +85E2 546A +85E3 546B +85E4 546C +85E5 546D +85E6 546E +85E7 546F +85E8 5470 +DFC9 5471 +DFDA 5472 +CEB6 5473 +85E9 5474 +BAC7 5475 +DFCE 5476 +DFC8 5477 +C5DE 5478 +85EA 5479 +85EB 547A +C9EB 547B +BAF4 547C +C3FC 547D +85EC 547E +85ED 547F +BED7 5480 +85EE 5481 +DFC6 5482 +85EF 5483 +DFCD 5484 +85F0 5485 +C5D8 5486 +85F1 5487 +85F2 5488 +85F3 5489 +85F4 548A +D5A6 548B +BACD 548C +85F5 548D +BECC 548E +D3BD 548F +B8C0 5490 +85F6 5491 +D6E4 5492 +85F7 5493 +DFC7 5494 +B9BE 5495 +BFA7 5496 +85F8 5497 +85F9 5498 +C1FC 5499 +DFCB 549A +DFCC 549B +85FA 549C +DFD0 549D +85FB 549E +85FC 549F +85FD 54A0 +85FE 54A1 +8640 54A2 +DFDB 54A3 +DFE5 54A4 +8641 54A5 +DFD7 54A6 +DFD6 54A7 +D7C9 54A8 +DFE3 54A9 +DFE4 54AA +E5EB 54AB +D2A7 54AC +DFD2 54AD +8642 54AE +BFA9 54AF +8643 54B0 +D4DB 54B1 +8644 54B2 +BFC8 54B3 +DFD4 54B4 +8645 54B5 +8646 54B6 +8647 54B7 +CFCC 54B8 +8648 54B9 +8649 54BA +DFDD 54BB +864A 54BC +D1CA 54BD +864B 54BE +DFDE 54BF +B0A7 54C0 +C6B7 54C1 +DFD3 54C2 +864C 54C3 +BAE5 54C4 +864D 54C5 +B6DF 54C6 +CDDB 54C7 +B9FE 54C8 +D4D5 54C9 +864E 54CA +864F 54CB +DFDF 54CC +CFEC 54CD +B0A5 54CE +DFE7 54CF +DFD1 54D0 +D1C6 54D1 +DFD5 54D2 +DFD8 54D3 +DFD9 54D4 +DFDC 54D5 +8650 54D6 +BBA9 54D7 +8651 54D8 +DFE0 54D9 +DFE1 54DA +8652 54DB +DFE2 54DC +DFE6 54DD +DFE8 54DE +D3B4 54DF +8653 54E0 +8654 54E1 +8655 54E2 +8656 54E3 +8657 54E4 +B8E7 54E5 +C5B6 54E6 +DFEA 54E7 +C9DA 54E8 +C1A8 54E9 +C4C4 54EA +8658 54EB +8659 54EC +BFDE 54ED +CFF8 54EE +865A 54EF +865B 54F0 +865C 54F1 +D5DC 54F2 +DFEE 54F3 +865D 54F4 +865E 54F5 +865F 54F6 +8660 54F7 +8661 54F8 +8662 54F9 +B2B8 54FA +8663 54FB +BADF 54FC +DFEC 54FD +8664 54FE +DBC1 54FF +8665 5500 +D1E4 5501 +8666 5502 +8667 5503 +8668 5504 +8669 5505 +CBF4 5506 +B4BD 5507 +866A 5508 +B0A6 5509 +866B 550A +866C 550B +866D 550C +866E 550D +866F 550E +DFF1 550F +CCC6 5510 +DFF2 5511 +8670 5512 +8671 5513 +DFED 5514 +8672 5515 +8673 5516 +8674 5517 +8675 5518 +8676 5519 +8677 551A +DFE9 551B +8678 551C +8679 551D +867A 551E +867B 551F +DFEB 5520 +867C 5521 +DFEF 5522 +DFF0 5523 +BBBD 5524 +867D 5525 +867E 5526 +DFF3 5527 +8680 5528 +8681 5529 +DFF4 552A +8682 552B +BBA3 552C +8683 552D +CADB 552E +CEA8 552F +E0A7 5530 +B3AA 5531 +8684 5532 +E0A6 5533 +8685 5534 +8686 5535 +8687 5536 +E0A1 5537 +8688 5538 +8689 5539 +868A 553A +868B 553B +DFFE 553C +868C 553D +CDD9 553E +DFFC 553F +868D 5540 +DFFA 5541 +868E 5542 +BFD0 5543 +D7C4 5544 +868F 5545 +C9CC 5546 +8690 5547 +8691 5548 +DFF8 5549 +B0A1 554A +8692 554B +8693 554C +8694 554D +8695 554E +8696 554F +DFFD 5550 +8697 5551 +8698 5552 +8699 5553 +869A 5554 +DFFB 5555 +E0A2 5556 +869B 5557 +869C 5558 +869D 5559 +869E 555A +869F 555B +E0A8 555C +86A0 555D +86A1 555E +86A2 555F +86A3 5560 +B7C8 5561 +86A4 5562 +86A5 5563 +C6A1 5564 +C9B6 5565 +C0B2 5566 +DFF5 5567 +86A6 5568 +86A7 5569 +C5BE 556A +86A8 556B +D8C4 556C +DFF9 556D +C4F6 556E +86A9 556F +86AA 5570 +86AB 5571 +86AC 5572 +86AD 5573 +86AE 5574 +E0A3 5575 +E0A4 5576 +E0A5 5577 +D0A5 5578 +86AF 5579 +86B0 557A +E0B4 557B +CCE4 557C +86B1 557D +E0B1 557E +86B2 557F +BFA6 5580 +E0AF 5581 +CEB9 5582 +E0AB 5583 +C9C6 5584 +86B3 5585 +86B4 5586 +C0AE 5587 +E0AE 5588 +BAED 5589 +BAB0 558A +E0A9 558B +86B5 558C +86B6 558D +86B7 558E +DFF6 558F +86B8 5590 +E0B3 5591 +86B9 5592 +86BA 5593 +E0B8 5594 +86BB 5595 +86BC 5596 +86BD 5597 +B4AD 5598 +E0B9 5599 +86BE 559A +86BF 559B +CFB2 559C +BAC8 559D +86C0 559E +E0B0 559F +86C1 55A0 +86C2 55A1 +86C3 55A2 +86C4 55A3 +86C5 55A4 +86C6 55A5 +86C7 55A6 +D0FA 55A7 +86C8 55A8 +86C9 55A9 +86CA 55AA +86CB 55AB +86CC 55AC +86CD 55AD +86CE 55AE +86CF 55AF +86D0 55B0 +E0AC 55B1 +86D1 55B2 +D4FB 55B3 +86D2 55B4 +DFF7 55B5 +86D3 55B6 +C5E7 55B7 +86D4 55B8 +E0AD 55B9 +86D5 55BA +D3F7 55BB +86D6 55BC +E0B6 55BD +E0B7 55BE +86D7 55BF +86D8 55C0 +86D9 55C1 +86DA 55C2 +86DB 55C3 +E0C4 55C4 +D0E1 55C5 +86DC 55C6 +86DD 55C7 +86DE 55C8 +E0BC 55C9 +86DF 55CA +86E0 55CB +E0C9 55CC +E0CA 55CD +86E1 55CE +86E2 55CF +86E3 55D0 +E0BE 55D1 +E0AA 55D2 +C9A4 55D3 +E0C1 55D4 +86E4 55D5 +E0B2 55D6 +86E5 55D7 +86E6 55D8 +86E7 55D9 +86E8 55DA +86E9 55DB +CAC8 55DC +E0C3 55DD +86EA 55DE +E0B5 55DF +86EB 55E0 +CECB 55E1 +86EC 55E2 +CBC3 55E3 +E0CD 55E4 +E0C6 55E5 +E0C2 55E6 +86ED 55E7 +E0CB 55E8 +86EE 55E9 +E0BA 55EA +E0BF 55EB +E0C0 55EC +86EF 55ED +86F0 55EE +E0C5 55EF +86F1 55F0 +86F2 55F1 +E0C7 55F2 +E0C8 55F3 +86F3 55F4 +E0CC 55F5 +86F4 55F6 +E0BB 55F7 +86F5 55F8 +86F6 55F9 +86F7 55FA +86F8 55FB +86F9 55FC +CBD4 55FD +E0D5 55FE +86FA 55FF +E0D6 5600 +E0D2 5601 +86FB 5602 +86FC 5603 +86FD 5604 +86FE 5605 +8740 5606 +8741 5607 +E0D0 5608 +BCCE 5609 +8742 560A +8743 560B +E0D1 560C +8744 560D +B8C2 560E +D8C5 560F +8745 5610 +8746 5611 +8747 5612 +8748 5613 +8749 5614 +874A 5615 +874B 5616 +874C 5617 +D0EA 5618 +874D 5619 +874E 561A +C2EF 561B +874F 561C +8750 561D +E0CF 561E +E0BD 561F +8751 5620 +8752 5621 +8753 5622 +E0D4 5623 +E0D3 5624 +8754 5625 +8755 5626 +E0D7 5627 +8756 5628 +8757 5629 +8758 562A +8759 562B +E0DC 562C +E0D8 562D +875A 562E +875B 562F +875C 5630 +D6F6 5631 +B3B0 5632 +875D 5633 +D7EC 5634 +875E 5635 +CBBB 5636 +875F 5637 +8760 5638 +E0DA 5639 +8761 563A +CEFB 563B +8762 563C +8763 563D +8764 563E +BAD9 563F +8765 5640 +8766 5641 +8767 5642 +8768 5643 +8769 5644 +876A 5645 +876B 5646 +876C 5647 +876D 5648 +876E 5649 +876F 564A +8770 564B +E0E1 564C +E0DD 564D +D2AD 564E +8771 564F +8772 5650 +8773 5651 +8774 5652 +8775 5653 +E0E2 5654 +8776 5655 +8777 5656 +E0DB 5657 +E0D9 5658 +E0DF 5659 +8778 565A +8779 565B +E0E0 565C +877A 565D +877B 565E +877C 565F +877D 5660 +877E 5661 +E0DE 5662 +8780 5663 +E0E4 5664 +8781 5665 +8782 5666 +8783 5667 +C6F7 5668 +D8AC 5669 +D4EB 566A +E0E6 566B +CAC9 566C +8784 566D +8785 566E +8786 566F +8787 5670 +E0E5 5671 +8788 5672 +8789 5673 +878A 5674 +878B 5675 +B8C1 5676 +878C 5677 +878D 5678 +878E 5679 +878F 567A +E0E7 567B +E0E8 567C +8790 567D +8791 567E +8792 567F +8793 5680 +8794 5681 +8795 5682 +8796 5683 +8797 5684 +E0E9 5685 +E0E3 5686 +8798 5687 +8799 5688 +879A 5689 +879B 568A +879C 568B +879D 568C +879E 568D +BABF 568E +CCE7 568F +879F 5690 +87A0 5691 +87A1 5692 +E0EA 5693 +87A2 5694 +87A3 5695 +87A4 5696 +87A5 5697 +87A6 5698 +87A7 5699 +87A8 569A +87A9 569B +87AA 569C +87AB 569D +87AC 569E +87AD 569F +87AE 56A0 +87AF 56A1 +87B0 56A2 +CFF9 56A3 +87B1 56A4 +87B2 56A5 +87B3 56A6 +87B4 56A7 +87B5 56A8 +87B6 56A9 +87B7 56AA +87B8 56AB +87B9 56AC +87BA 56AD +87BB 56AE +E0EB 56AF +87BC 56B0 +87BD 56B1 +87BE 56B2 +87BF 56B3 +87C0 56B4 +87C1 56B5 +87C2 56B6 +C8C2 56B7 +87C3 56B8 +87C4 56B9 +87C5 56BA +87C6 56BB +BDC0 56BC +87C7 56BD +87C8 56BE +87C9 56BF +87CA 56C0 +87CB 56C1 +87CC 56C2 +87CD 56C3 +87CE 56C4 +87CF 56C5 +87D0 56C6 +87D1 56C7 +87D2 56C8 +87D3 56C9 +C4D2 56CA +87D4 56CB +87D5 56CC +87D6 56CD +87D7 56CE +87D8 56CF +87D9 56D0 +87DA 56D1 +87DB 56D2 +87DC 56D3 +E0EC 56D4 +87DD 56D5 +87DE 56D6 +E0ED 56D7 +87DF 56D8 +87E0 56D9 +C7F4 56DA +CBC4 56DB +87E1 56DC +E0EE 56DD +BBD8 56DE +D8B6 56DF +D2F2 56E0 +E0EF 56E1 +CDC5 56E2 +87E2 56E3 +B6DA 56E4 +87E3 56E5 +87E4 56E6 +87E5 56E7 +87E6 56E8 +87E7 56E9 +87E8 56EA +E0F1 56EB +87E9 56EC +D4B0 56ED +87EA 56EE +87EB 56EF +C0A7 56F0 +B4D1 56F1 +87EC 56F2 +87ED 56F3 +CEA7 56F4 +E0F0 56F5 +87EE 56F6 +87EF 56F7 +87F0 56F8 +E0F2 56F9 +B9CC 56FA +87F1 56FB +87F2 56FC +B9FA 56FD +CDBC 56FE +E0F3 56FF +87F3 5700 +87F4 5701 +87F5 5702 +C6D4 5703 +E0F4 5704 +87F6 5705 +D4B2 5706 +87F7 5707 +C8A6 5708 +E0F6 5709 +E0F5 570A +87F8 570B +87F9 570C +87FA 570D +87FB 570E +87FC 570F +87FD 5710 +87FE 5711 +8840 5712 +8841 5713 +8842 5714 +8843 5715 +8844 5716 +8845 5717 +8846 5718 +8847 5719 +8848 571A +8849 571B +E0F7 571C +884A 571D +884B 571E +CDC1 571F +884C 5720 +884D 5721 +884E 5722 +CAA5 5723 +884F 5724 +8850 5725 +8851 5726 +8852 5727 +D4DA 5728 +DBD7 5729 +DBD9 572A +8853 572B +DBD8 572C +B9E7 572D +DBDC 572E +DBDD 572F +B5D8 5730 +8854 5731 +8855 5732 +DBDA 5733 +8856 5734 +8857 5735 +8858 5736 +8859 5737 +885A 5738 +DBDB 5739 +B3A1 573A +DBDF 573B +885B 573C +885C 573D +BBF8 573E +885D 573F +D6B7 5740 +885E 5741 +DBE0 5742 +885F 5743 +8860 5744 +8861 5745 +8862 5746 +BEF9 5747 +8863 5748 +8864 5749 +B7BB 574A +8865 574B +DBD0 574C +CCAE 574D +BFB2 574E +BBB5 574F +D7F8 5750 +BFD3 5751 +8866 5752 +8867 5753 +8868 5754 +8869 5755 +886A 5756 +BFE9 5757 +886B 5758 +886C 5759 +BCE1 575A +CCB3 575B +DBDE 575C +B0D3 575D +CEEB 575E +B7D8 575F +D7B9 5760 +C6C2 5761 +886D 5762 +886E 5763 +C0A4 5764 +886F 5765 +CCB9 5766 +8870 5767 +DBE7 5768 +DBE1 5769 +C6BA 576A +DBE3 576B +8871 576C +DBE8 576D +8872 576E +C5F7 576F +8873 5770 +8874 5771 +8875 5772 +DBEA 5773 +8876 5774 +8877 5775 +DBE9 5776 +BFC0 5777 +8878 5778 +8879 5779 +887A 577A +DBE6 577B +DBE5 577C +887B 577D +887C 577E +887D 577F +887E 5780 +8880 5781 +B4B9 5782 +C0AC 5783 +C2A2 5784 +DBE2 5785 +DBE4 5786 +8881 5787 +8882 5788 +8883 5789 +8884 578A +D0CD 578B +DBED 578C +8885 578D +8886 578E +8887 578F +8888 5790 +8889 5791 +C0DD 5792 +DBF2 5793 +888A 5794 +888B 5795 +888C 5796 +888D 5797 +888E 5798 +888F 5799 +8890 579A +B6E2 579B +8891 579C +8892 579D +8893 579E +8894 579F +DBF3 57A0 +DBD2 57A1 +B9B8 57A2 +D4AB 57A3 +DBEC 57A4 +8895 57A5 +BFD1 57A6 +DBF0 57A7 +8896 57A8 +DBD1 57A9 +8897 57AA +B5E6 57AB +8898 57AC +DBEB 57AD +BFE5 57AE +8899 57AF +889A 57B0 +889B 57B1 +DBEE 57B2 +889C 57B3 +DBF1 57B4 +889D 57B5 +889E 57B6 +889F 57B7 +DBF9 57B8 +88A0 57B9 +88A1 57BA +88A2 57BB +88A3 57BC +88A4 57BD +88A5 57BE +88A6 57BF +88A7 57C0 +88A8 57C1 +B9A1 57C2 +B0A3 57C3 +88A9 57C4 +88AA 57C5 +88AB 57C6 +88AC 57C7 +88AD 57C8 +88AE 57C9 +88AF 57CA +C2F1 57CB +88B0 57CC +88B1 57CD +B3C7 57CE +DBEF 57CF +88B2 57D0 +88B3 57D1 +DBF8 57D2 +88B4 57D3 +C6D2 57D4 +DBF4 57D5 +88B5 57D6 +88B6 57D7 +DBF5 57D8 +DBF7 57D9 +DBF6 57DA +88B7 57DB +88B8 57DC +DBFE 57DD +88B9 57DE +D3F2 57DF +B2BA 57E0 +88BA 57E1 +88BB 57E2 +88BC 57E3 +DBFD 57E4 +88BD 57E5 +88BE 57E6 +88BF 57E7 +88C0 57E8 +88C1 57E9 +88C2 57EA +88C3 57EB +88C4 57EC +DCA4 57ED +88C5 57EE +DBFB 57EF +88C6 57F0 +88C7 57F1 +88C8 57F2 +88C9 57F3 +DBFA 57F4 +88CA 57F5 +88CB 57F6 +88CC 57F7 +DBFC 57F8 +C5E0 57F9 +BBF9 57FA +88CD 57FB +88CE 57FC +DCA3 57FD +88CF 57FE +88D0 57FF +DCA5 5800 +88D1 5801 +CCC3 5802 +88D2 5803 +88D3 5804 +88D4 5805 +B6D1 5806 +DDC0 5807 +88D5 5808 +88D6 5809 +88D7 580A +DCA1 580B +88D8 580C +DCA2 580D +88D9 580E +88DA 580F +88DB 5810 +C7B5 5811 +88DC 5812 +88DD 5813 +88DE 5814 +B6E9 5815 +88DF 5816 +88E0 5817 +88E1 5818 +DCA7 5819 +88E2 581A +88E3 581B +88E4 581C +88E5 581D +DCA6 581E +88E6 581F +DCA9 5820 +B1A4 5821 +88E7 5822 +88E8 5823 +B5CC 5824 +88E9 5825 +88EA 5826 +88EB 5827 +88EC 5828 +88ED 5829 +BFB0 582A +88EE 582B +88EF 582C +88F0 582D +88F1 582E +88F2 582F +D1DF 5830 +88F3 5831 +88F4 5832 +88F5 5833 +88F6 5834 +B6C2 5835 +88F7 5836 +88F8 5837 +88F9 5838 +88FA 5839 +88FB 583A +88FC 583B +88FD 583C +88FE 583D +8940 583E +8941 583F +8942 5840 +8943 5841 +8944 5842 +8945 5843 +DCA8 5844 +8946 5845 +8947 5846 +8948 5847 +8949 5848 +894A 5849 +894B 584A +894C 584B +CBFA 584C +EBF3 584D +894D 584E +894E 584F +894F 5850 +CBDC 5851 +8950 5852 +8951 5853 +CBFE 5854 +8952 5855 +8953 5856 +8954 5857 +CCC1 5858 +8955 5859 +8956 585A +8957 585B +8958 585C +8959 585D +C8FB 585E +895A 585F +895B 5860 +895C 5861 +895D 5862 +895E 5863 +895F 5864 +DCAA 5865 +8960 5866 +8961 5867 +8962 5868 +8963 5869 +8964 586A +CCEE 586B +DCAB 586C +8965 586D +8966 586E +8967 586F +8968 5870 +8969 5871 +896A 5872 +896B 5873 +896C 5874 +896D 5875 +896E 5876 +896F 5877 +8970 5878 +8971 5879 +8972 587A +8973 587B +8974 587C +8975 587D +DBD3 587E +8976 587F +DCAF 5880 +DCAC 5881 +8977 5882 +BEB3 5883 +8978 5884 +CAFB 5885 +8979 5886 +897A 5887 +897B 5888 +DCAD 5889 +897C 588A +897D 588B +897E 588C +8980 588D +8981 588E +8982 588F +8983 5890 +8984 5891 +C9CA 5892 +C4B9 5893 +8985 5894 +8986 5895 +8987 5896 +8988 5897 +8989 5898 +C7BD 5899 +DCAE 589A +898A 589B +898B 589C +898C 589D +D4F6 589E +D0E6 589F +898D 58A0 +898E 58A1 +898F 58A2 +8990 58A3 +8991 58A4 +8992 58A5 +8993 58A6 +8994 58A7 +C4AB 58A8 +B6D5 58A9 +8995 58AA +8996 58AB +8997 58AC +8998 58AD +8999 58AE +899A 58AF +899B 58B0 +899C 58B1 +899D 58B2 +899E 58B3 +899F 58B4 +89A0 58B5 +89A1 58B6 +89A2 58B7 +89A3 58B8 +89A4 58B9 +89A5 58BA +89A6 58BB +DBD4 58BC +89A7 58BD +89A8 58BE +89A9 58BF +89AA 58C0 +B1DA 58C1 +89AB 58C2 +89AC 58C3 +89AD 58C4 +DBD5 58C5 +89AE 58C6 +89AF 58C7 +89B0 58C8 +89B1 58C9 +89B2 58CA +89B3 58CB +89B4 58CC +89B5 58CD +89B6 58CE +89B7 58CF +89B8 58D0 +DBD6 58D1 +89B9 58D2 +89BA 58D3 +89BB 58D4 +BABE 58D5 +89BC 58D6 +89BD 58D7 +89BE 58D8 +89BF 58D9 +89C0 58DA +89C1 58DB +89C2 58DC +89C3 58DD +89C4 58DE +89C5 58DF +89C6 58E0 +89C7 58E1 +89C8 58E2 +89C9 58E3 +C8C0 58E4 +89CA 58E5 +89CB 58E6 +89CC 58E7 +89CD 58E8 +89CE 58E9 +89CF 58EA +CABF 58EB +C8C9 58EC +89D0 58ED +D7B3 58EE +89D1 58EF +C9F9 58F0 +89D2 58F1 +89D3 58F2 +BFC7 58F3 +89D4 58F4 +89D5 58F5 +BAF8 58F6 +89D6 58F7 +89D7 58F8 +D2BC 58F9 +89D8 58FA +89D9 58FB +89DA 58FC +89DB 58FD +89DC 58FE +89DD 58FF +89DE 5900 +89DF 5901 +E2BA 5902 +89E0 5903 +B4A6 5904 +89E1 5905 +89E2 5906 +B1B8 5907 +89E3 5908 +89E4 5909 +89E5 590A +89E6 590B +89E7 590C +B8B4 590D +89E8 590E +CFC4 590F +89E9 5910 +89EA 5911 +89EB 5912 +89EC 5913 +D9E7 5914 +CFA6 5915 +CDE2 5916 +89ED 5917 +89EE 5918 +D9ED 5919 +B6E0 591A +89EF 591B +D2B9 591C +89F0 591D +89F1 591E +B9BB 591F +89F2 5920 +89F3 5921 +89F4 5922 +89F5 5923 +E2B9 5924 +E2B7 5925 +89F6 5926 +B4F3 5927 +89F7 5928 +CCEC 5929 +CCAB 592A +B7F2 592B +89F8 592C +D8B2 592D +D1EB 592E +BABB 592F +89F9 5930 +CAA7 5931 +89FA 5932 +89FB 5933 +CDB7 5934 +89FC 5935 +89FD 5936 +D2C4 5937 +BFE4 5938 +BCD0 5939 +B6E1 593A +89FE 593B +DEC5 593C +8A40 593D +8A41 593E +8A42 593F +8A43 5940 +DEC6 5941 +DBBC 5942 +8A44 5943 +D1D9 5944 +8A45 5945 +8A46 5946 +C6E6 5947 +C4CE 5948 +B7EE 5949 +8A47 594A +B7DC 594B +8A48 594C +8A49 594D +BFFC 594E +D7E0 594F +8A4A 5950 +C6F5 5951 +8A4B 5952 +8A4C 5953 +B1BC 5954 +DEC8 5955 +BDB1 5956 +CCD7 5957 +DECA 5958 +8A4D 5959 +DEC9 595A +8A4E 595B +8A4F 595C +8A50 595D +8A51 595E +8A52 595F +B5EC 5960 +8A53 5961 +C9DD 5962 +8A54 5963 +8A55 5964 +B0C2 5965 +8A56 5966 +8A57 5967 +8A58 5968 +8A59 5969 +8A5A 596A +8A5B 596B +8A5C 596C +8A5D 596D +8A5E 596E +8A5F 596F +8A60 5970 +8A61 5971 +8A62 5972 +C5AE 5973 +C5AB 5974 +8A63 5975 +C4CC 5976 +8A64 5977 +BCE9 5978 +CBFD 5979 +8A65 597A +8A66 597B +8A67 597C +BAC3 597D +8A68 597E +8A69 597F +8A6A 5980 +E5F9 5981 +C8E7 5982 +E5FA 5983 +CDFD 5984 +8A6B 5985 +D7B1 5986 +B8BE 5987 +C2E8 5988 +8A6C 5989 +C8D1 598A +8A6D 598B +8A6E 598C +E5FB 598D +8A6F 598E +8A70 598F +8A71 5990 +8A72 5991 +B6CA 5992 +BCCB 5993 +8A73 5994 +8A74 5995 +D1FD 5996 +E6A1 5997 +8A75 5998 +C3EE 5999 +8A76 599A +8A77 599B +8A78 599C +8A79 599D +E6A4 599E +8A7A 599F +8A7B 59A0 +8A7C 59A1 +8A7D 59A2 +E5FE 59A3 +E6A5 59A4 +CDD7 59A5 +8A7E 59A6 +8A80 59A7 +B7C1 59A8 +E5FC 59A9 +E5FD 59AA +E6A3 59AB +8A81 59AC +8A82 59AD +C4DD 59AE +E6A8 59AF +8A83 59B0 +8A84 59B1 +E6A7 59B2 +8A85 59B3 +8A86 59B4 +8A87 59B5 +8A88 59B6 +8A89 59B7 +8A8A 59B8 +C3C3 59B9 +8A8B 59BA +C6DE 59BB +8A8C 59BC +8A8D 59BD +E6AA 59BE +8A8E 59BF +8A8F 59C0 +8A90 59C1 +8A91 59C2 +8A92 59C3 +8A93 59C4 +8A94 59C5 +C4B7 59C6 +8A95 59C7 +8A96 59C8 +8A97 59C9 +E6A2 59CA +CABC 59CB +8A98 59CC +8A99 59CD +8A9A 59CE +8A9B 59CF +BDE3 59D0 +B9C3 59D1 +E6A6 59D2 +D0D5 59D3 +CEAF 59D4 +8A9C 59D5 +8A9D 59D6 +E6A9 59D7 +E6B0 59D8 +8A9E 59D9 +D2A6 59DA +8A9F 59DB +BDAA 59DC +E6AD 59DD +8AA0 59DE +8AA1 59DF +8AA2 59E0 +8AA3 59E1 +8AA4 59E2 +E6AF 59E3 +8AA5 59E4 +C0D1 59E5 +8AA6 59E6 +8AA7 59E7 +D2CC 59E8 +8AA8 59E9 +8AA9 59EA +8AAA 59EB +BCA7 59EC +8AAB 59ED +8AAC 59EE +8AAD 59EF +8AAE 59F0 +8AAF 59F1 +8AB0 59F2 +8AB1 59F3 +8AB2 59F4 +8AB3 59F5 +8AB4 59F6 +8AB5 59F7 +8AB6 59F8 +E6B1 59F9 +8AB7 59FA +D2F6 59FB +8AB8 59FC +8AB9 59FD +8ABA 59FE +D7CB 59FF +8ABB 5A00 +CDFE 5A01 +8ABC 5A02 +CDDE 5A03 +C2A6 5A04 +E6AB 5A05 +E6AC 5A06 +BDBF 5A07 +E6AE 5A08 +E6B3 5A09 +8ABD 5A0A +8ABE 5A0B +E6B2 5A0C +8ABF 5A0D +8AC0 5A0E +8AC1 5A0F +8AC2 5A10 +E6B6 5A11 +8AC3 5A12 +E6B8 5A13 +8AC4 5A14 +8AC5 5A15 +8AC6 5A16 +8AC7 5A17 +C4EF 5A18 +8AC8 5A19 +8AC9 5A1A +8ACA 5A1B +C4C8 5A1C +8ACB 5A1D +8ACC 5A1E +BEEA 5A1F +C9EF 5A20 +8ACD 5A21 +8ACE 5A22 +E6B7 5A23 +8ACF 5A24 +B6F0 5A25 +8AD0 5A26 +8AD1 5A27 +8AD2 5A28 +C3E4 5A29 +8AD3 5A2A +8AD4 5A2B +8AD5 5A2C +8AD6 5A2D +8AD7 5A2E +8AD8 5A2F +8AD9 5A30 +D3E9 5A31 +E6B4 5A32 +8ADA 5A33 +E6B5 5A34 +8ADB 5A35 +C8A2 5A36 +8ADC 5A37 +8ADD 5A38 +8ADE 5A39 +8ADF 5A3A +8AE0 5A3B +E6BD 5A3C +8AE1 5A3D +8AE2 5A3E +8AE3 5A3F +E6B9 5A40 +8AE4 5A41 +8AE5 5A42 +8AE6 5A43 +8AE7 5A44 +8AE8 5A45 +C6C5 5A46 +8AE9 5A47 +8AEA 5A48 +CDF1 5A49 +E6BB 5A4A +8AEB 5A4B +8AEC 5A4C +8AED 5A4D +8AEE 5A4E +8AEF 5A4F +8AF0 5A50 +8AF1 5A51 +8AF2 5A52 +8AF3 5A53 +8AF4 5A54 +E6BC 5A55 +8AF5 5A56 +8AF6 5A57 +8AF7 5A58 +8AF8 5A59 +BBE9 5A5A +8AF9 5A5B +8AFA 5A5C +8AFB 5A5D +8AFC 5A5E +8AFD 5A5F +8AFE 5A60 +8B40 5A61 +E6BE 5A62 +8B41 5A63 +8B42 5A64 +8B43 5A65 +8B44 5A66 +E6BA 5A67 +8B45 5A68 +8B46 5A69 +C0B7 5A6A +8B47 5A6B +8B48 5A6C +8B49 5A6D +8B4A 5A6E +8B4B 5A6F +8B4C 5A70 +8B4D 5A71 +8B4E 5A72 +8B4F 5A73 +D3A4 5A74 +E6BF 5A75 +C9F4 5A76 +E6C3 5A77 +8B50 5A78 +8B51 5A79 +E6C4 5A7A +8B52 5A7B +8B53 5A7C +8B54 5A7D +8B55 5A7E +D0F6 5A7F +8B56 5A80 +8B57 5A81 +8B58 5A82 +8B59 5A83 +8B5A 5A84 +8B5B 5A85 +8B5C 5A86 +8B5D 5A87 +8B5E 5A88 +8B5F 5A89 +8B60 5A8A +8B61 5A8B +8B62 5A8C +8B63 5A8D +8B64 5A8E +8B65 5A8F +8B66 5A90 +8B67 5A91 +C3BD 5A92 +8B68 5A93 +8B69 5A94 +8B6A 5A95 +8B6B 5A96 +8B6C 5A97 +8B6D 5A98 +8B6E 5A99 +C3C4 5A9A +E6C2 5A9B +8B6F 5A9C +8B70 5A9D +8B71 5A9E +8B72 5A9F +8B73 5AA0 +8B74 5AA1 +8B75 5AA2 +8B76 5AA3 +8B77 5AA4 +8B78 5AA5 +8B79 5AA6 +8B7A 5AA7 +8B7B 5AA8 +8B7C 5AA9 +E6C1 5AAA +8B7D 5AAB +8B7E 5AAC +8B80 5AAD +8B81 5AAE +8B82 5AAF +8B83 5AB0 +8B84 5AB1 +E6C7 5AB2 +CFB1 5AB3 +8B85 5AB4 +EBF4 5AB5 +8B86 5AB6 +8B87 5AB7 +E6CA 5AB8 +8B88 5AB9 +8B89 5ABA +8B8A 5ABB +8B8B 5ABC +8B8C 5ABD +E6C5 5ABE +8B8D 5ABF +8B8E 5AC0 +BCDE 5AC1 +C9A9 5AC2 +8B8F 5AC3 +8B90 5AC4 +8B91 5AC5 +8B92 5AC6 +8B93 5AC7 +8B94 5AC8 +BCB5 5AC9 +8B95 5ACA +8B96 5ACB +CFD3 5ACC +8B97 5ACD +8B98 5ACE +8B99 5ACF +8B9A 5AD0 +8B9B 5AD1 +E6C8 5AD2 +8B9C 5AD3 +E6C9 5AD4 +8B9D 5AD5 +E6CE 5AD6 +8B9E 5AD7 +E6D0 5AD8 +8B9F 5AD9 +8BA0 5ADA +8BA1 5ADB +E6D1 5ADC +8BA2 5ADD +8BA3 5ADE +8BA4 5ADF +E6CB 5AE0 +B5D5 5AE1 +8BA5 5AE2 +E6CC 5AE3 +8BA6 5AE4 +8BA7 5AE5 +E6CF 5AE6 +8BA8 5AE7 +8BA9 5AE8 +C4DB 5AE9 +8BAA 5AEA +E6C6 5AEB +8BAB 5AEC +8BAC 5AED +8BAD 5AEE +8BAE 5AEF +8BAF 5AF0 +E6CD 5AF1 +8BB0 5AF2 +8BB1 5AF3 +8BB2 5AF4 +8BB3 5AF5 +8BB4 5AF6 +8BB5 5AF7 +8BB6 5AF8 +8BB7 5AF9 +8BB8 5AFA +8BB9 5AFB +8BBA 5AFC +8BBB 5AFD +8BBC 5AFE +8BBD 5AFF +8BBE 5B00 +8BBF 5B01 +8BC0 5B02 +8BC1 5B03 +8BC2 5B04 +8BC3 5B05 +8BC4 5B06 +8BC5 5B07 +8BC6 5B08 +E6D2 5B09 +8BC7 5B0A +8BC8 5B0B +8BC9 5B0C +8BCA 5B0D +8BCB 5B0E +8BCC 5B0F +8BCD 5B10 +8BCE 5B11 +8BCF 5B12 +8BD0 5B13 +8BD1 5B14 +8BD2 5B15 +E6D4 5B16 +E6D3 5B17 +8BD3 5B18 +8BD4 5B19 +8BD5 5B1A +8BD6 5B1B +8BD7 5B1C +8BD8 5B1D +8BD9 5B1E +8BDA 5B1F +8BDB 5B20 +8BDC 5B21 +8BDD 5B22 +8BDE 5B23 +8BDF 5B24 +8BE0 5B25 +8BE1 5B26 +8BE2 5B27 +8BE3 5B28 +8BE4 5B29 +8BE5 5B2A +8BE6 5B2B +8BE7 5B2C +8BE8 5B2D +8BE9 5B2E +8BEA 5B2F +8BEB 5B30 +8BEC 5B31 +E6D5 5B32 +8BED 5B33 +D9F8 5B34 +8BEE 5B35 +8BEF 5B36 +E6D6 5B37 +8BF0 5B38 +8BF1 5B39 +8BF2 5B3A +8BF3 5B3B +8BF4 5B3C +8BF5 5B3D +8BF6 5B3E +8BF7 5B3F +E6D7 5B40 +8BF8 5B41 +8BF9 5B42 +8BFA 5B43 +8BFB 5B44 +8BFC 5B45 +8BFD 5B46 +8BFE 5B47 +8C40 5B48 +8C41 5B49 +8C42 5B4A +8C43 5B4B +8C44 5B4C +8C45 5B4D +8C46 5B4E +8C47 5B4F +D7D3 5B50 +E6DD 5B51 +8C48 5B52 +E6DE 5B53 +BFD7 5B54 +D4D0 5B55 +8C49 5B56 +D7D6 5B57 +B4E6 5B58 +CBEF 5B59 +E6DA 5B5A +D8C3 5B5B +D7CE 5B5C +D0A2 5B5D +8C4A 5B5E +C3CF 5B5F +8C4B 5B60 +8C4C 5B61 +E6DF 5B62 +BCBE 5B63 +B9C2 5B64 +E6DB 5B65 +D1A7 5B66 +8C4D 5B67 +8C4E 5B68 +BAA2 5B69 +C2CF 5B6A +8C4F 5B6B +D8AB 5B6C +8C50 5B6D +8C51 5B6E +8C52 5B6F +CAEB 5B70 +E5EE 5B71 +8C53 5B72 +E6DC 5B73 +8C54 5B74 +B7F5 5B75 +8C55 5B76 +8C56 5B77 +8C57 5B78 +8C58 5B79 +C8E6 5B7A +8C59 5B7B +8C5A 5B7C +C4F5 5B7D +8C5B 5B7E +8C5C 5B7F +E5B2 5B80 +C4FE 5B81 +8C5D 5B82 +CBFC 5B83 +E5B3 5B84 +D5AC 5B85 +8C5E 5B86 +D3EE 5B87 +CAD8 5B88 +B0B2 5B89 +8C5F 5B8A +CBCE 5B8B +CDEA 5B8C +8C60 5B8D +8C61 5B8E +BAEA 5B8F +8C62 5B90 +8C63 5B91 +8C64 5B92 +E5B5 5B93 +8C65 5B94 +E5B4 5B95 +8C66 5B96 +D7DA 5B97 +B9D9 5B98 +D6E6 5B99 +B6A8 5B9A +CDF0 5B9B +D2CB 5B9C +B1A6 5B9D +CAB5 5B9E +8C67 5B9F +B3E8 5BA0 +C9F3 5BA1 +BFCD 5BA2 +D0FB 5BA3 +CAD2 5BA4 +E5B6 5BA5 +BBC2 5BA6 +8C68 5BA7 +8C69 5BA8 +8C6A 5BA9 +CFDC 5BAA +B9AC 5BAB +8C6B 5BAC +8C6C 5BAD +8C6D 5BAE +8C6E 5BAF +D4D7 5BB0 +8C6F 5BB1 +8C70 5BB2 +BAA6 5BB3 +D1E7 5BB4 +CFFC 5BB5 +BCD2 5BB6 +8C71 5BB7 +E5B7 5BB8 +C8DD 5BB9 +8C72 5BBA +8C73 5BBB +8C74 5BBC +BFED 5BBD +B1F6 5BBE +CBDE 5BBF +8C75 5BC0 +8C76 5BC1 +BCC5 5BC2 +8C77 5BC3 +BCC4 5BC4 +D2FA 5BC5 +C3DC 5BC6 +BFDC 5BC7 +8C78 5BC8 +8C79 5BC9 +8C7A 5BCA +8C7B 5BCB +B8BB 5BCC +8C7C 5BCD +8C7D 5BCE +8C7E 5BCF +C3C2 5BD0 +8C80 5BD1 +BAAE 5BD2 +D4A2 5BD3 +8C81 5BD4 +8C82 5BD5 +8C83 5BD6 +8C84 5BD7 +8C85 5BD8 +8C86 5BD9 +8C87 5BDA +8C88 5BDB +8C89 5BDC +C7DE 5BDD +C4AF 5BDE +B2EC 5BDF +8C8A 5BE0 +B9D1 5BE1 +8C8B 5BE2 +8C8C 5BE3 +E5BB 5BE4 +C1C8 5BE5 +8C8D 5BE6 +8C8E 5BE7 +D5AF 5BE8 +8C8F 5BE9 +8C90 5BEA +8C91 5BEB +8C92 5BEC +8C93 5BED +E5BC 5BEE +8C94 5BEF +E5BE 5BF0 +8C95 5BF1 +8C96 5BF2 +8C97 5BF3 +8C98 5BF4 +8C99 5BF5 +8C9A 5BF6 +8C9B 5BF7 +B4E7 5BF8 +B6D4 5BF9 +CBC2 5BFA +D1B0 5BFB +B5BC 5BFC +8C9C 5BFD +8C9D 5BFE +CAD9 5BFF +8C9E 5C00 +B7E2 5C01 +8C9F 5C02 +8CA0 5C03 +C9E4 5C04 +8CA1 5C05 +BDAB 5C06 +8CA2 5C07 +8CA3 5C08 +CEBE 5C09 +D7F0 5C0A +8CA4 5C0B +8CA5 5C0C +8CA6 5C0D +8CA7 5C0E +D0A1 5C0F +8CA8 5C10 +C9D9 5C11 +8CA9 5C12 +8CAA 5C13 +B6FB 5C14 +E6D8 5C15 +BCE2 5C16 +8CAB 5C17 +B3BE 5C18 +8CAC 5C19 +C9D0 5C1A +8CAD 5C1B +E6D9 5C1C +B3A2 5C1D +8CAE 5C1E +8CAF 5C1F +8CB0 5C20 +8CB1 5C21 +DECC 5C22 +8CB2 5C23 +D3C8 5C24 +DECD 5C25 +8CB3 5C26 +D2A2 5C27 +8CB4 5C28 +8CB5 5C29 +8CB6 5C2A +8CB7 5C2B +DECE 5C2C +8CB8 5C2D +8CB9 5C2E +8CBA 5C2F +8CBB 5C30 +BECD 5C31 +8CBC 5C32 +8CBD 5C33 +DECF 5C34 +8CBE 5C35 +8CBF 5C36 +8CC0 5C37 +CAAC 5C38 +D2FC 5C39 +B3DF 5C3A +E5EA 5C3B +C4E1 5C3C +BEA1 5C3D +CEB2 5C3E +C4F2 5C3F +BED6 5C40 +C6A8 5C41 +B2E3 5C42 +8CC1 5C43 +8CC2 5C44 +BED3 5C45 +8CC3 5C46 +8CC4 5C47 +C7FC 5C48 +CCEB 5C49 +BDEC 5C4A +CEDD 5C4B +8CC5 5C4C +8CC6 5C4D +CABA 5C4E +C6C1 5C4F +E5EC 5C50 +D0BC 5C51 +8CC7 5C52 +8CC8 5C53 +8CC9 5C54 +D5B9 5C55 +8CCA 5C56 +8CCB 5C57 +8CCC 5C58 +E5ED 5C59 +8CCD 5C5A +8CCE 5C5B +8CCF 5C5C +8CD0 5C5D +CAF4 5C5E +8CD1 5C5F +CDC0 5C60 +C2C5 5C61 +8CD2 5C62 +E5EF 5C63 +8CD3 5C64 +C2C4 5C65 +E5F0 5C66 +8CD4 5C67 +8CD5 5C68 +8CD6 5C69 +8CD7 5C6A +8CD8 5C6B +8CD9 5C6C +8CDA 5C6D +E5F8 5C6E +CDCD 5C6F +8CDB 5C70 +C9BD 5C71 +8CDC 5C72 +8CDD 5C73 +8CDE 5C74 +8CDF 5C75 +8CE0 5C76 +8CE1 5C77 +8CE2 5C78 +D2D9 5C79 +E1A8 5C7A +8CE3 5C7B +8CE4 5C7C +8CE5 5C7D +8CE6 5C7E +D3EC 5C7F +8CE7 5C80 +CBEA 5C81 +C6F1 5C82 +8CE8 5C83 +8CE9 5C84 +8CEA 5C85 +8CEB 5C86 +8CEC 5C87 +E1AC 5C88 +8CED 5C89 +8CEE 5C8A +8CEF 5C8B +E1A7 5C8C +E1A9 5C8D +8CF0 5C8E +8CF1 5C8F +E1AA 5C90 +E1AF 5C91 +8CF2 5C92 +8CF3 5C93 +B2ED 5C94 +8CF4 5C95 +E1AB 5C96 +B8DA 5C97 +E1AD 5C98 +E1AE 5C99 +E1B0 5C9A +B5BA 5C9B +E1B1 5C9C +8CF5 5C9D +8CF6 5C9E +8CF7 5C9F +8CF8 5CA0 +8CF9 5CA1 +E1B3 5CA2 +E1B8 5CA3 +8CFA 5CA4 +8CFB 5CA5 +8CFC 5CA6 +8CFD 5CA7 +8CFE 5CA8 +D1D2 5CA9 +8D40 5CAA +E1B6 5CAB +E1B5 5CAC +C1EB 5CAD +8D41 5CAE +8D42 5CAF +8D43 5CB0 +E1B7 5CB1 +8D44 5CB2 +D4C0 5CB3 +8D45 5CB4 +E1B2 5CB5 +8D46 5CB6 +E1BA 5CB7 +B0B6 5CB8 +8D47 5CB9 +8D48 5CBA +8D49 5CBB +8D4A 5CBC +E1B4 5CBD +8D4B 5CBE +BFF9 5CBF +8D4C 5CC0 +E1B9 5CC1 +8D4D 5CC2 +8D4E 5CC3 +E1BB 5CC4 +8D4F 5CC5 +8D50 5CC6 +8D51 5CC7 +8D52 5CC8 +8D53 5CC9 +8D54 5CCA +E1BE 5CCB +8D55 5CCC +8D56 5CCD +8D57 5CCE +8D58 5CCF +8D59 5CD0 +8D5A 5CD1 +E1BC 5CD2 +8D5B 5CD3 +8D5C 5CD4 +8D5D 5CD5 +8D5E 5CD6 +8D5F 5CD7 +8D60 5CD8 +D6C5 5CD9 +8D61 5CDA +8D62 5CDB +8D63 5CDC +8D64 5CDD +8D65 5CDE +8D66 5CDF +8D67 5CE0 +CFBF 5CE1 +8D68 5CE2 +8D69 5CE3 +E1BD 5CE4 +E1BF 5CE5 +C2CD 5CE6 +8D6A 5CE7 +B6EB 5CE8 +8D6B 5CE9 +D3F8 5CEA +8D6C 5CEB +8D6D 5CEC +C7CD 5CED +8D6E 5CEE +8D6F 5CEF +B7E5 5CF0 +8D70 5CF1 +8D71 5CF2 +8D72 5CF3 +8D73 5CF4 +8D74 5CF5 +8D75 5CF6 +8D76 5CF7 +8D77 5CF8 +8D78 5CF9 +8D79 5CFA +BEFE 5CFB +8D7A 5CFC +8D7B 5CFD +8D7C 5CFE +8D7D 5CFF +8D7E 5D00 +8D80 5D01 +E1C0 5D02 +E1C1 5D03 +8D81 5D04 +8D82 5D05 +E1C7 5D06 +B3E7 5D07 +8D83 5D08 +8D84 5D09 +8D85 5D0A +8D86 5D0B +8D87 5D0C +8D88 5D0D +C6E9 5D0E +8D89 5D0F +8D8A 5D10 +8D8B 5D11 +8D8C 5D12 +8D8D 5D13 +B4DE 5D14 +8D8E 5D15 +D1C2 5D16 +8D8F 5D17 +8D90 5D18 +8D91 5D19 +8D92 5D1A +E1C8 5D1B +8D93 5D1C +8D94 5D1D +E1C6 5D1E +8D95 5D1F +8D96 5D20 +8D97 5D21 +8D98 5D22 +8D99 5D23 +E1C5 5D24 +8D9A 5D25 +E1C3 5D26 +E1C2 5D27 +8D9B 5D28 +B1C0 5D29 +8D9C 5D2A +8D9D 5D2B +8D9E 5D2C +D5B8 5D2D +E1C4 5D2E +8D9F 5D2F +8DA0 5D30 +8DA1 5D31 +8DA2 5D32 +8DA3 5D33 +E1CB 5D34 +8DA4 5D35 +8DA5 5D36 +8DA6 5D37 +8DA7 5D38 +8DA8 5D39 +8DA9 5D3A +8DAA 5D3B +8DAB 5D3C +E1CC 5D3D +E1CA 5D3E +8DAC 5D3F +8DAD 5D40 +8DAE 5D41 +8DAF 5D42 +8DB0 5D43 +8DB1 5D44 +8DB2 5D45 +8DB3 5D46 +EFFA 5D47 +8DB4 5D48 +8DB5 5D49 +E1D3 5D4A +E1D2 5D4B +C7B6 5D4C +8DB6 5D4D +8DB7 5D4E +8DB8 5D4F +8DB9 5D50 +8DBA 5D51 +8DBB 5D52 +8DBC 5D53 +8DBD 5D54 +8DBE 5D55 +8DBF 5D56 +8DC0 5D57 +E1C9 5D58 +8DC1 5D59 +8DC2 5D5A +E1CE 5D5B +8DC3 5D5C +E1D0 5D5D +8DC4 5D5E +8DC5 5D5F +8DC6 5D60 +8DC7 5D61 +8DC8 5D62 +8DC9 5D63 +8DCA 5D64 +8DCB 5D65 +8DCC 5D66 +8DCD 5D67 +8DCE 5D68 +E1D4 5D69 +8DCF 5D6A +E1D1 5D6B +E1CD 5D6C +8DD0 5D6D +8DD1 5D6E +E1CF 5D6F +8DD2 5D70 +8DD3 5D71 +8DD4 5D72 +8DD5 5D73 +E1D5 5D74 +8DD6 5D75 +8DD7 5D76 +8DD8 5D77 +8DD9 5D78 +8DDA 5D79 +8DDB 5D7A +8DDC 5D7B +8DDD 5D7C +8DDE 5D7D +8DDF 5D7E +8DE0 5D7F +8DE1 5D80 +8DE2 5D81 +E1D6 5D82 +8DE3 5D83 +8DE4 5D84 +8DE5 5D85 +8DE6 5D86 +8DE7 5D87 +8DE8 5D88 +8DE9 5D89 +8DEA 5D8A +8DEB 5D8B +8DEC 5D8C +8DED 5D8D +8DEE 5D8E +8DEF 5D8F +8DF0 5D90 +8DF1 5D91 +8DF2 5D92 +8DF3 5D93 +8DF4 5D94 +8DF5 5D95 +8DF6 5D96 +8DF7 5D97 +8DF8 5D98 +E1D7 5D99 +8DF9 5D9A +8DFA 5D9B +8DFB 5D9C +E1D8 5D9D +8DFC 5D9E +8DFD 5D9F +8DFE 5DA0 +8E40 5DA1 +8E41 5DA2 +8E42 5DA3 +8E43 5DA4 +8E44 5DA5 +8E45 5DA6 +8E46 5DA7 +8E47 5DA8 +8E48 5DA9 +8E49 5DAA +8E4A 5DAB +8E4B 5DAC +8E4C 5DAD +8E4D 5DAE +8E4E 5DAF +8E4F 5DB0 +8E50 5DB1 +8E51 5DB2 +8E52 5DB3 +8E53 5DB4 +8E54 5DB5 +8E55 5DB6 +E1DA 5DB7 +8E56 5DB8 +8E57 5DB9 +8E58 5DBA +8E59 5DBB +8E5A 5DBC +8E5B 5DBD +8E5C 5DBE +8E5D 5DBF +8E5E 5DC0 +8E5F 5DC1 +8E60 5DC2 +8E61 5DC3 +8E62 5DC4 +E1DB 5DC5 +8E63 5DC6 +8E64 5DC7 +8E65 5DC8 +8E66 5DC9 +8E67 5DCA +8E68 5DCB +8E69 5DCC +CEA1 5DCD +8E6A 5DCE +8E6B 5DCF +8E6C 5DD0 +8E6D 5DD1 +8E6E 5DD2 +8E6F 5DD3 +8E70 5DD4 +8E71 5DD5 +8E72 5DD6 +8E73 5DD7 +8E74 5DD8 +8E75 5DD9 +8E76 5DDA +E7DD 5DDB +8E77 5DDC +B4A8 5DDD +D6DD 5DDE +8E78 5DDF +8E79 5DE0 +D1B2 5DE1 +B3B2 5DE2 +8E7A 5DE3 +8E7B 5DE4 +B9A4 5DE5 +D7F3 5DE6 +C7C9 5DE7 +BEDE 5DE8 +B9AE 5DE9 +8E7C 5DEA +CED7 5DEB +8E7D 5DEC +8E7E 5DED +B2EE 5DEE +DBCF 5DEF +8E80 5DF0 +BCBA 5DF1 +D2D1 5DF2 +CBC8 5DF3 +B0CD 5DF4 +8E81 5DF5 +8E82 5DF6 +CFEF 5DF7 +8E83 5DF8 +8E84 5DF9 +8E85 5DFA +8E86 5DFB +8E87 5DFC +D9E3 5DFD +BDED 5DFE +8E88 5DFF +8E89 5E00 +B1D2 5E01 +CAD0 5E02 +B2BC 5E03 +8E8A 5E04 +CBA7 5E05 +B7AB 5E06 +8E8B 5E07 +CAA6 5E08 +8E8C 5E09 +8E8D 5E0A +8E8E 5E0B +CFA3 5E0C +8E8F 5E0D +8E90 5E0E +E0F8 5E0F +D5CA 5E10 +E0FB 5E11 +8E91 5E12 +8E92 5E13 +E0FA 5E14 +C5C1 5E15 +CCFB 5E16 +8E93 5E17 +C1B1 5E18 +E0F9 5E19 +D6E3 5E1A +B2AF 5E1B +D6C4 5E1C +B5DB 5E1D +8E94 5E1E +8E95 5E1F +8E96 5E20 +8E97 5E21 +8E98 5E22 +8E99 5E23 +8E9A 5E24 +8E9B 5E25 +B4F8 5E26 +D6A1 5E27 +8E9C 5E28 +8E9D 5E29 +8E9E 5E2A +8E9F 5E2B +8EA0 5E2C +CFAF 5E2D +B0EF 5E2E +8EA1 5E2F +8EA2 5E30 +E0FC 5E31 +8EA3 5E32 +8EA4 5E33 +8EA5 5E34 +8EA6 5E35 +8EA7 5E36 +E1A1 5E37 +B3A3 5E38 +8EA8 5E39 +8EA9 5E3A +E0FD 5E3B +E0FE 5E3C +C3B1 5E3D +8EAA 5E3E +8EAB 5E3F +8EAC 5E40 +8EAD 5E41 +C3DD 5E42 +8EAE 5E43 +E1A2 5E44 +B7F9 5E45 +8EAF 5E46 +8EB0 5E47 +8EB1 5E48 +8EB2 5E49 +8EB3 5E4A +8EB4 5E4B +BBCF 5E4C +8EB5 5E4D +8EB6 5E4E +8EB7 5E4F +8EB8 5E50 +8EB9 5E51 +8EBA 5E52 +8EBB 5E53 +E1A3 5E54 +C4BB 5E55 +8EBC 5E56 +8EBD 5E57 +8EBE 5E58 +8EBF 5E59 +8EC0 5E5A +E1A4 5E5B +8EC1 5E5C +8EC2 5E5D +E1A5 5E5E +8EC3 5E5F +8EC4 5E60 +E1A6 5E61 +B4B1 5E62 +8EC5 5E63 +8EC6 5E64 +8EC7 5E65 +8EC8 5E66 +8EC9 5E67 +8ECA 5E68 +8ECB 5E69 +8ECC 5E6A +8ECD 5E6B +8ECE 5E6C +8ECF 5E6D +8ED0 5E6E +8ED1 5E6F +8ED2 5E70 +8ED3 5E71 +B8C9 5E72 +C6BD 5E73 +C4EA 5E74 +8ED4 5E75 +B2A2 5E76 +8ED5 5E77 +D0D2 5E78 +8ED6 5E79 +E7DB 5E7A +BBC3 5E7B +D3D7 5E7C +D3C4 5E7D +8ED7 5E7E +B9E3 5E7F +E2CF 5E80 +8ED8 5E81 +8ED9 5E82 +8EDA 5E83 +D7AF 5E84 +8EDB 5E85 +C7EC 5E86 +B1D3 5E87 +8EDC 5E88 +8EDD 5E89 +B4B2 5E8A +E2D1 5E8B +8EDE 5E8C +8EDF 5E8D +8EE0 5E8E +D0F2 5E8F +C2AE 5E90 +E2D0 5E91 +8EE1 5E92 +BFE2 5E93 +D3A6 5E94 +B5D7 5E95 +E2D2 5E96 +B5EA 5E97 +8EE2 5E98 +C3ED 5E99 +B8FD 5E9A +8EE3 5E9B +B8AE 5E9C +8EE4 5E9D +C5D3 5E9E +B7CF 5E9F +E2D4 5EA0 +8EE5 5EA1 +8EE6 5EA2 +8EE7 5EA3 +8EE8 5EA4 +E2D3 5EA5 +B6C8 5EA6 +D7F9 5EA7 +8EE9 5EA8 +8EEA 5EA9 +8EEB 5EAA +8EEC 5EAB +8EED 5EAC +CDA5 5EAD +8EEE 5EAE +8EEF 5EAF +8EF0 5EB0 +8EF1 5EB1 +8EF2 5EB2 +E2D8 5EB3 +8EF3 5EB4 +E2D6 5EB5 +CAFC 5EB6 +BFB5 5EB7 +D3B9 5EB8 +E2D5 5EB9 +8EF4 5EBA +8EF5 5EBB +8EF6 5EBC +8EF7 5EBD +E2D7 5EBE +8EF8 5EBF +8EF9 5EC0 +8EFA 5EC1 +8EFB 5EC2 +8EFC 5EC3 +8EFD 5EC4 +8EFE 5EC5 +8F40 5EC6 +8F41 5EC7 +8F42 5EC8 +C1AE 5EC9 +C0C8 5ECA +8F43 5ECB +8F44 5ECC +8F45 5ECD +8F46 5ECE +8F47 5ECF +8F48 5ED0 +E2DB 5ED1 +E2DA 5ED2 +C0AA 5ED3 +8F49 5ED4 +8F4A 5ED5 +C1CE 5ED6 +8F4B 5ED7 +8F4C 5ED8 +8F4D 5ED9 +8F4E 5EDA +E2DC 5EDB +8F4F 5EDC +8F50 5EDD +8F51 5EDE +8F52 5EDF +8F53 5EE0 +8F54 5EE1 +8F55 5EE2 +8F56 5EE3 +8F57 5EE4 +8F58 5EE5 +8F59 5EE6 +8F5A 5EE7 +E2DD 5EE8 +8F5B 5EE9 +E2DE 5EEA +8F5C 5EEB +8F5D 5EEC +8F5E 5EED +8F5F 5EEE +8F60 5EEF +8F61 5EF0 +8F62 5EF1 +8F63 5EF2 +8F64 5EF3 +DBC8 5EF4 +8F65 5EF5 +D1D3 5EF6 +CDA2 5EF7 +8F66 5EF8 +8F67 5EF9 +BDA8 5EFA +8F68 5EFB +8F69 5EFC +8F6A 5EFD +DEC3 5EFE +D8A5 5EFF +BFAA 5F00 +DBCD 5F01 +D2EC 5F02 +C6FA 5F03 +C5AA 5F04 +8F6B 5F05 +8F6C 5F06 +8F6D 5F07 +DEC4 5F08 +8F6E 5F09 +B1D7 5F0A +DFAE 5F0B +8F6F 5F0C +8F70 5F0D +8F71 5F0E +CABD 5F0F +8F72 5F10 +DFB1 5F11 +8F73 5F12 +B9AD 5F13 +8F74 5F14 +D2FD 5F15 +8F75 5F16 +B8A5 5F17 +BAEB 5F18 +8F76 5F19 +8F77 5F1A +B3DA 5F1B +8F78 5F1C +8F79 5F1D +8F7A 5F1E +B5DC 5F1F +D5C5 5F20 +8F7B 5F21 +8F7C 5F22 +8F7D 5F23 +8F7E 5F24 +C3D6 5F25 +CFD2 5F26 +BBA1 5F27 +8F80 5F28 +E5F3 5F29 +E5F2 5F2A +8F81 5F2B +8F82 5F2C +E5F4 5F2D +8F83 5F2E +CDE4 5F2F +8F84 5F30 +C8F5 5F31 +8F85 5F32 +8F86 5F33 +8F87 5F34 +8F88 5F35 +8F89 5F36 +8F8A 5F37 +8F8B 5F38 +B5AF 5F39 +C7BF 5F3A +8F8C 5F3B +E5F6 5F3C +8F8D 5F3D +8F8E 5F3E +8F8F 5F3F +ECB0 5F40 +8F90 5F41 +8F91 5F42 +8F92 5F43 +8F93 5F44 +8F94 5F45 +8F95 5F46 +8F96 5F47 +8F97 5F48 +8F98 5F49 +8F99 5F4A +8F9A 5F4B +8F9B 5F4C +8F9C 5F4D +8F9D 5F4E +8F9E 5F4F +E5E6 5F50 +8F9F 5F51 +B9E9 5F52 +B5B1 5F53 +8FA0 5F54 +C2BC 5F55 +E5E8 5F56 +E5E7 5F57 +E5E9 5F58 +8FA1 5F59 +8FA2 5F5A +8FA3 5F5B +8FA4 5F5C +D2CD 5F5D +8FA5 5F5E +8FA6 5F5F +8FA7 5F60 +E1EA 5F61 +D0CE 5F62 +8FA8 5F63 +CDAE 5F64 +8FA9 5F65 +D1E5 5F66 +8FAA 5F67 +8FAB 5F68 +B2CA 5F69 +B1EB 5F6A +8FAC 5F6B +B1F2 5F6C +C5ED 5F6D +8FAD 5F6E +8FAE 5F6F +D5C3 5F70 +D3B0 5F71 +8FAF 5F72 +E1DC 5F73 +8FB0 5F74 +8FB1 5F75 +8FB2 5F76 +E1DD 5F77 +8FB3 5F78 +D2DB 5F79 +8FB4 5F7A +B3B9 5F7B +B1CB 5F7C +8FB5 5F7D +8FB6 5F7E +8FB7 5F7F +CDF9 5F80 +D5F7 5F81 +E1DE 5F82 +8FB8 5F83 +BEB6 5F84 +B4FD 5F85 +8FB9 5F86 +E1DF 5F87 +BADC 5F88 +E1E0 5F89 +BBB2 5F8A +C2C9 5F8B +E1E1 5F8C +8FBA 5F8D +8FBB 5F8E +8FBC 5F8F +D0EC 5F90 +8FBD 5F91 +CDBD 5F92 +8FBE 5F93 +8FBF 5F94 +E1E2 5F95 +8FC0 5F96 +B5C3 5F97 +C5C7 5F98 +E1E3 5F99 +8FC1 5F9A +8FC2 5F9B +E1E4 5F9C +8FC3 5F9D +8FC4 5F9E +8FC5 5F9F +8FC6 5FA0 +D3F9 5FA1 +8FC7 5FA2 +8FC8 5FA3 +8FC9 5FA4 +8FCA 5FA5 +8FCB 5FA6 +8FCC 5FA7 +E1E5 5FA8 +8FCD 5FA9 +D1AD 5FAA +8FCE 5FAB +8FCF 5FAC +E1E6 5FAD +CEA2 5FAE +8FD0 5FAF +8FD1 5FB0 +8FD2 5FB1 +8FD3 5FB2 +8FD4 5FB3 +8FD5 5FB4 +E1E7 5FB5 +8FD6 5FB6 +B5C2 5FB7 +8FD7 5FB8 +8FD8 5FB9 +8FD9 5FBA +8FDA 5FBB +E1E8 5FBC +BBD5 5FBD +8FDB 5FBE +8FDC 5FBF +8FDD 5FC0 +8FDE 5FC1 +8FDF 5FC2 +D0C4 5FC3 +E2E0 5FC4 +B1D8 5FC5 +D2E4 5FC6 +8FE0 5FC7 +8FE1 5FC8 +E2E1 5FC9 +8FE2 5FCA +8FE3 5FCB +BCC9 5FCC +C8CC 5FCD +8FE4 5FCE +E2E3 5FCF +ECFE 5FD0 +ECFD 5FD1 +DFAF 5FD2 +8FE5 5FD3 +8FE6 5FD4 +8FE7 5FD5 +E2E2 5FD6 +D6BE 5FD7 +CDFC 5FD8 +C3A6 5FD9 +8FE8 5FDA +8FE9 5FDB +8FEA 5FDC +E3C3 5FDD +8FEB 5FDE +8FEC 5FDF +D6D2 5FE0 +E2E7 5FE1 +8FED 5FE2 +8FEE 5FE3 +E2E8 5FE4 +8FEF 5FE5 +8FF0 5FE6 +D3C7 5FE7 +8FF1 5FE8 +8FF2 5FE9 +E2EC 5FEA +BFEC 5FEB +8FF3 5FEC +E2ED 5FED +E2E5 5FEE +8FF4 5FEF +8FF5 5FF0 +B3C0 5FF1 +8FF6 5FF2 +8FF7 5FF3 +8FF8 5FF4 +C4EE 5FF5 +8FF9 5FF6 +8FFA 5FF7 +E2EE 5FF8 +8FFB 5FF9 +8FFC 5FFA +D0C3 5FFB +8FFD 5FFC +BAF6 5FFD +E2E9 5FFE +B7DE 5FFF +BBB3 6000 +CCAC 6001 +CBCB 6002 +E2E4 6003 +E2E6 6004 +E2EA 6005 +E2EB 6006 +8FFE 6007 +9040 6008 +9041 6009 +E2F7 600A +9042 600B +9043 600C +E2F4 600D +D4F5 600E +E2F3 600F +9044 6010 +9045 6011 +C5AD 6012 +9046 6013 +D5FA 6014 +C5C2 6015 +B2C0 6016 +9047 6017 +9048 6018 +E2EF 6019 +9049 601A +E2F2 601B +C1AF 601C +CBBC 601D +904A 601E +904B 601F +B5A1 6020 +E2F9 6021 +904C 6022 +904D 6023 +904E 6024 +BCB1 6025 +E2F1 6026 +D0D4 6027 +D4B9 6028 +E2F5 6029 +B9D6 602A +E2F6 602B +904F 602C +9050 602D +9051 602E +C7D3 602F +9052 6030 +9053 6031 +9054 6032 +9055 6033 +9056 6034 +E2F0 6035 +9057 6036 +9058 6037 +9059 6038 +905A 6039 +905B 603A +D7DC 603B +EDA1 603C +905C 603D +905D 603E +E2F8 603F +905E 6040 +EDA5 6041 +E2FE 6042 +CAD1 6043 +905F 6044 +9060 6045 +9061 6046 +9062 6047 +9063 6048 +9064 6049 +9065 604A +C1B5 604B +9066 604C +BBD0 604D +9067 604E +9068 604F +BFD6 6050 +9069 6051 +BAE3 6052 +906A 6053 +906B 6054 +CBA1 6055 +906C 6056 +906D 6057 +906E 6058 +EDA6 6059 +EDA3 605A +906F 605B +9070 605C +EDA2 605D +9071 605E +9072 605F +9073 6060 +9074 6061 +BBD6 6062 +EDA7 6063 +D0F4 6064 +9075 6065 +9076 6066 +EDA4 6067 +BADE 6068 +B6F7 6069 +E3A1 606A +B6B2 606B +CCF1 606C +B9A7 606D +9077 606E +CFA2 606F +C7A1 6070 +9078 6071 +9079 6072 +BFD2 6073 +907A 6074 +907B 6075 +B6F1 6076 +907C 6077 +E2FA 6078 +E2FB 6079 +E2FD 607A +E2FC 607B +C4D5 607C +E3A2 607D +907D 607E +D3C1 607F +907E 6080 +9080 6081 +9081 6082 +E3A7 6083 +C7C4 6084 +9082 6085 +9083 6086 +9084 6087 +9085 6088 +CFA4 6089 +9086 608A +9087 608B +E3A9 608C +BAB7 608D +9088 608E +9089 608F +908A 6090 +908B 6091 +E3A8 6092 +908C 6093 +BBDA 6094 +908D 6095 +E3A3 6096 +908E 6097 +908F 6098 +9090 6099 +E3A4 609A +E3AA 609B +9091 609C +E3A6 609D +9092 609E +CEF2 609F +D3C6 60A0 +9093 60A1 +9094 60A2 +BBBC 60A3 +9095 60A4 +9096 60A5 +D4C3 60A6 +9097 60A7 +C4FA 60A8 +9098 60A9 +9099 60AA +EDA8 60AB +D0FC 60AC +E3A5 60AD +909A 60AE +C3F5 60AF +909B 60B0 +E3AD 60B1 +B1AF 60B2 +909C 60B3 +E3B2 60B4 +909D 60B5 +909E 60B6 +909F 60B7 +BCC2 60B8 +90A0 60B9 +90A1 60BA +E3AC 60BB +B5BF 60BC +90A2 60BD +90A3 60BE +90A4 60BF +90A5 60C0 +90A6 60C1 +90A7 60C2 +90A8 60C3 +90A9 60C4 +C7E9 60C5 +E3B0 60C6 +90AA 60C7 +90AB 60C8 +90AC 60C9 +BEAA 60CA +CDEF 60CB +90AD 60CC +90AE 60CD +90AF 60CE +90B0 60CF +90B1 60D0 +BBF3 60D1 +90B2 60D2 +90B3 60D3 +90B4 60D4 +CCE8 60D5 +90B5 60D6 +90B6 60D7 +E3AF 60D8 +90B7 60D9 +E3B1 60DA +90B8 60DB +CFA7 60DC +E3AE 60DD +90B9 60DE +CEA9 60DF +BBDD 60E0 +90BA 60E1 +90BB 60E2 +90BC 60E3 +90BD 60E4 +90BE 60E5 +B5EB 60E6 +BEE5 60E7 +B2D2 60E8 +B3CD 60E9 +90BF 60EA +B1B9 60EB +E3AB 60EC +B2D1 60ED +B5AC 60EE +B9DF 60EF +B6E8 60F0 +90C0 60F1 +90C1 60F2 +CFEB 60F3 +E3B7 60F4 +90C2 60F5 +BBCC 60F6 +90C3 60F7 +90C4 60F8 +C8C7 60F9 +D0CA 60FA +90C5 60FB +90C6 60FC +90C7 60FD +90C8 60FE +90C9 60FF +E3B8 6100 +B3EE 6101 +90CA 6102 +90CB 6103 +90CC 6104 +90CD 6105 +EDA9 6106 +90CE 6107 +D3FA 6108 +D3E4 6109 +90CF 610A +90D0 610B +90D1 610C +EDAA 610D +E3B9 610E +D2E2 610F +90D2 6110 +90D3 6111 +90D4 6112 +90D5 6113 +90D6 6114 +E3B5 6115 +90D7 6116 +90D8 6117 +90D9 6118 +90DA 6119 +D3DE 611A +90DB 611B +90DC 611C +90DD 611D +90DE 611E +B8D0 611F +E3B3 6120 +90DF 6121 +90E0 6122 +E3B6 6123 +B7DF 6124 +90E1 6125 +E3B4 6126 +C0A2 6127 +90E2 6128 +90E3 6129 +90E4 612A +E3BA 612B +90E5 612C +90E6 612D +90E7 612E +90E8 612F +90E9 6130 +90EA 6131 +90EB 6132 +90EC 6133 +90ED 6134 +90EE 6135 +90EF 6136 +90F0 6137 +90F1 6138 +90F2 6139 +90F3 613A +90F4 613B +90F5 613C +90F6 613D +90F7 613E +D4B8 613F +90F8 6140 +90F9 6141 +90FA 6142 +90FB 6143 +90FC 6144 +90FD 6145 +90FE 6146 +9140 6147 +B4C8 6148 +9141 6149 +E3BB 614A +9142 614B +BBC5 614C +9143 614D +C9F7 614E +9144 614F +9145 6150 +C9E5 6151 +9146 6152 +9147 6153 +9148 6154 +C4BD 6155 +9149 6156 +914A 6157 +914B 6158 +914C 6159 +914D 615A +914E 615B +914F 615C +EDAB 615D +9150 615E +9151 615F +9152 6160 +9153 6161 +C2FD 6162 +9154 6163 +9155 6164 +9156 6165 +9157 6166 +BBDB 6167 +BFAE 6168 +9158 6169 +9159 616A +915A 616B +915B 616C +915C 616D +915D 616E +915E 616F +CEBF 6170 +915F 6171 +9160 6172 +9161 6173 +9162 6174 +E3BC 6175 +9163 6176 +BFB6 6177 +9164 6178 +9165 6179 +9166 617A +9167 617B +9168 617C +9169 617D +916A 617E +916B 617F +916C 6180 +916D 6181 +916E 6182 +916F 6183 +9170 6184 +9171 6185 +9172 6186 +9173 6187 +9174 6188 +9175 6189 +9176 618A +B1EF 618B +9177 618C +9178 618D +D4F7 618E +9179 618F +917A 6190 +917B 6191 +917C 6192 +917D 6193 +E3BE 6194 +917E 6195 +9180 6196 +9181 6197 +9182 6198 +9183 6199 +9184 619A +9185 619B +9186 619C +EDAD 619D +9187 619E +9188 619F +9189 61A0 +918A 61A1 +918B 61A2 +918C 61A3 +918D 61A4 +918E 61A5 +918F 61A6 +E3BF 61A7 +BAA9 61A8 +EDAC 61A9 +9190 61AA +9191 61AB +E3BD 61AC +9192 61AD +9193 61AE +9194 61AF +9195 61B0 +9196 61B1 +9197 61B2 +9198 61B3 +9199 61B4 +919A 61B5 +919B 61B6 +E3C0 61B7 +919C 61B8 +919D 61B9 +919E 61BA +919F 61BB +91A0 61BC +91A1 61BD +BAB6 61BE +91A2 61BF +91A3 61C0 +91A4 61C1 +B6AE 61C2 +91A5 61C3 +91A6 61C4 +91A7 61C5 +91A8 61C6 +91A9 61C7 +D0B8 61C8 +91AA 61C9 +B0C3 61CA +EDAE 61CB +91AB 61CC +91AC 61CD +91AD 61CE +91AE 61CF +91AF 61D0 +EDAF 61D1 +C0C1 61D2 +91B0 61D3 +E3C1 61D4 +91B1 61D5 +91B2 61D6 +91B3 61D7 +91B4 61D8 +91B5 61D9 +91B6 61DA +91B7 61DB +91B8 61DC +91B9 61DD +91BA 61DE +91BB 61DF +91BC 61E0 +91BD 61E1 +91BE 61E2 +91BF 61E3 +91C0 61E4 +91C1 61E5 +C5B3 61E6 +91C2 61E7 +91C3 61E8 +91C4 61E9 +91C5 61EA +91C6 61EB +91C7 61EC +91C8 61ED +91C9 61EE +91CA 61EF +91CB 61F0 +91CC 61F1 +91CD 61F2 +91CE 61F3 +91CF 61F4 +E3C2 61F5 +91D0 61F6 +91D1 61F7 +91D2 61F8 +91D3 61F9 +91D4 61FA +91D5 61FB +91D6 61FC +91D7 61FD +91D8 61FE +DCB2 61FF +91D9 6200 +91DA 6201 +91DB 6202 +91DC 6203 +91DD 6204 +91DE 6205 +EDB0 6206 +91DF 6207 +B8EA 6208 +91E0 6209 +CEEC 620A +EAA7 620B +D0E7 620C +CAF9 620D +C8D6 620E +CFB7 620F +B3C9 6210 +CED2 6211 +BDE4 6212 +91E1 6213 +91E2 6214 +E3DE 6215 +BBF2 6216 +EAA8 6217 +D5BD 6218 +91E3 6219 +C6DD 621A +EAA9 621B +91E4 621C +91E5 621D +91E6 621E +EAAA 621F +91E7 6220 +EAAC 6221 +EAAB 6222 +91E8 6223 +EAAE 6224 +EAAD 6225 +91E9 6226 +91EA 6227 +91EB 6228 +91EC 6229 +BDD8 622A +91ED 622B +EAAF 622C +91EE 622D +C2BE 622E +91EF 622F +91F0 6230 +91F1 6231 +91F2 6232 +B4C1 6233 +B4F7 6234 +91F3 6235 +91F4 6236 +BBA7 6237 +91F5 6238 +91F6 6239 +91F7 623A +91F8 623B +91F9 623C +ECE6 623D +ECE5 623E +B7BF 623F +CBF9 6240 +B1E2 6241 +91FA 6242 +ECE7 6243 +91FB 6244 +91FC 6245 +91FD 6246 +C9C8 6247 +ECE8 6248 +ECE9 6249 +91FE 624A +CAD6 624B +DED0 624C +B2C5 624D +D4FA 624E +9240 624F +9241 6250 +C6CB 6251 +B0C7 6252 +B4F2 6253 +C8D3 6254 +9242 6255 +9243 6256 +9244 6257 +CDD0 6258 +9245 6259 +9246 625A +BFB8 625B +9247 625C +9248 625D +9249 625E +924A 625F +924B 6260 +924C 6261 +924D 6262 +BFDB 6263 +924E 6264 +924F 6265 +C7A4 6266 +D6B4 6267 +9250 6268 +C0A9 6269 +DED1 626A +C9A8 626B +D1EF 626C +C5A4 626D +B0E7 626E +B3B6 626F +C8C5 6270 +9251 6271 +9252 6272 +B0E2 6273 +9253 6274 +9254 6275 +B7F6 6276 +9255 6277 +9256 6278 +C5FA 6279 +9257 627A +9258 627B +B6F3 627C +9259 627D +D5D2 627E +B3D0 627F +BCBC 6280 +925A 6281 +925B 6282 +925C 6283 +B3AD 6284 +925D 6285 +925E 6286 +925F 6287 +9260 6288 +BEF1 6289 +B0D1 628A +9261 628B +9262 628C +9263 628D +9264 628E +9265 628F +9266 6290 +D2D6 6291 +CAE3 6292 +D7A5 6293 +9267 6294 +CDB6 6295 +B6B6 6296 +BFB9 6297 +D5DB 6298 +9268 6299 +B8A7 629A +C5D7 629B +9269 629C +926A 629D +926B 629E +DED2 629F +BFD9 62A0 +C2D5 62A1 +C7C0 62A2 +926C 62A3 +BBA4 62A4 +B1A8 62A5 +926D 62A6 +926E 62A7 +C5EA 62A8 +926F 62A9 +9270 62AA +C5FB 62AB +CCA7 62AC +9271 62AD +9272 62AE +9273 62AF +9274 62B0 +B1A7 62B1 +9275 62B2 +9276 62B3 +9277 62B4 +B5D6 62B5 +9278 62B6 +9279 62B7 +927A 62B8 +C4A8 62B9 +927B 62BA +DED3 62BB +D1BA 62BC +B3E9 62BD +927C 62BE +C3F2 62BF +927D 62C0 +927E 62C1 +B7F7 62C2 +9280 62C3 +D6F4 62C4 +B5A3 62C5 +B2F0 62C6 +C4B4 62C7 +C4E9 62C8 +C0AD 62C9 +DED4 62CA +9281 62CB +B0E8 62CC +C5C4 62CD +C1E0 62CE +9282 62CF +B9D5 62D0 +9283 62D1 +BEDC 62D2 +CDD8 62D3 +B0CE 62D4 +9284 62D5 +CDCF 62D6 +DED6 62D7 +BED0 62D8 +D7BE 62D9 +DED5 62DA +D5D0 62DB +B0DD 62DC +9285 62DD +9286 62DE +C4E2 62DF +9287 62E0 +9288 62E1 +C2A3 62E2 +BCF0 62E3 +9289 62E4 +D3B5 62E5 +C0B9 62E6 +C5A1 62E7 +B2A6 62E8 +D4F1 62E9 +928A 62EA +928B 62EB +C0A8 62EC +CAC3 62ED +DED7 62EE +D5FC 62EF +928C 62F0 +B9B0 62F1 +928D 62F2 +C8AD 62F3 +CBA9 62F4 +928E 62F5 +DED9 62F6 +BFBD 62F7 +928F 62F8 +9290 62F9 +9291 62FA +9292 62FB +C6B4 62FC +D7A7 62FD +CAB0 62FE +C4C3 62FF +9293 6300 +B3D6 6301 +B9D2 6302 +9294 6303 +9295 6304 +9296 6305 +9297 6306 +D6B8 6307 +EAFC 6308 +B0B4 6309 +9298 630A +9299 630B +929A 630C +929B 630D +BFE6 630E +929C 630F +929D 6310 +CCF4 6311 +929E 6312 +929F 6313 +92A0 6314 +92A1 6315 +CDDA 6316 +92A2 6317 +92A3 6318 +92A4 6319 +D6BF 631A +C2CE 631B +92A5 631C +CECE 631D +CCA2 631E +D0AE 631F +C4D3 6320 +B5B2 6321 +DED8 6322 +D5F5 6323 +BCB7 6324 +BBD3 6325 +92A6 6326 +92A7 6327 +B0A4 6328 +92A8 6329 +C5B2 632A +B4EC 632B +92A9 632C +92AA 632D +92AB 632E +D5F1 632F +92AC 6330 +92AD 6331 +EAFD 6332 +92AE 6333 +92AF 6334 +92B0 6335 +92B1 6336 +92B2 6337 +92B3 6338 +DEDA 6339 +CDA6 633A +92B4 633B +92B5 633C +CDEC 633D +92B6 633E +92B7 633F +92B8 6340 +92B9 6341 +CEE6 6342 +DEDC 6343 +92BA 6344 +CDB1 6345 +C0A6 6346 +92BB 6347 +92BC 6348 +D7BD 6349 +92BD 634A +DEDB 634B +B0C6 634C +BAB4 634D +C9D3 634E +C4F3 634F +BEE8 6350 +92BE 6351 +92BF 6352 +92C0 6353 +92C1 6354 +B2B6 6355 +92C2 6356 +92C3 6357 +92C4 6358 +92C5 6359 +92C6 635A +92C7 635B +92C8 635C +92C9 635D +C0CC 635E +CBF0 635F +92CA 6360 +BCF1 6361 +BBBB 6362 +B5B7 6363 +92CB 6364 +92CC 6365 +92CD 6366 +C5F5 6367 +92CE 6368 +DEE6 6369 +92CF 636A +92D0 636B +92D1 636C +DEE3 636D +BEDD 636E +92D2 636F +92D3 6370 +DEDF 6371 +92D4 6372 +92D5 6373 +92D6 6374 +92D7 6375 +B4B7 6376 +BDDD 6377 +92D8 6378 +92D9 6379 +DEE0 637A +C4ED 637B +92DA 637C +92DB 637D +92DC 637E +92DD 637F +CFC6 6380 +92DE 6381 +B5E0 6382 +92DF 6383 +92E0 6384 +92E1 6385 +92E2 6386 +B6DE 6387 +CADA 6388 +B5F4 6389 +DEE5 638A +92E3 638B +D5C6 638C +92E4 638D +DEE1 638E +CCCD 638F +C6FE 6390 +92E5 6391 +C5C5 6392 +92E6 6393 +92E7 6394 +92E8 6395 +D2B4 6396 +92E9 6397 +BEF2 6398 +92EA 6399 +92EB 639A +92EC 639B +92ED 639C +92EE 639D +92EF 639E +92F0 639F +C2D3 63A0 +92F1 63A1 +CCBD 63A2 +B3B8 63A3 +92F2 63A4 +BDD3 63A5 +92F3 63A6 +BFD8 63A7 +CDC6 63A8 +D1DA 63A9 +B4EB 63AA +92F4 63AB +DEE4 63AC +DEDD 63AD +DEE7 63AE +92F5 63AF +EAFE 63B0 +92F6 63B1 +92F7 63B2 +C2B0 63B3 +DEE2 63B4 +92F8 63B5 +92F9 63B6 +D6C0 63B7 +B5A7 63B8 +92FA 63B9 +B2F4 63BA +92FB 63BB +DEE8 63BC +92FC 63BD +DEF2 63BE +92FD 63BF +92FE 63C0 +9340 63C1 +9341 63C2 +9342 63C3 +DEED 63C4 +9343 63C5 +DEF1 63C6 +9344 63C7 +9345 63C8 +C8E0 63C9 +9346 63CA +9347 63CB +9348 63CC +D7E1 63CD +DEEF 63CE +C3E8 63CF +CCE1 63D0 +9349 63D1 +B2E5 63D2 +934A 63D3 +934B 63D4 +934C 63D5 +D2BE 63D6 +934D 63D7 +934E 63D8 +934F 63D9 +9350 63DA +9351 63DB +9352 63DC +9353 63DD +DEEE 63DE +9354 63DF +DEEB 63E0 +CED5 63E1 +9355 63E2 +B4A7 63E3 +9356 63E4 +9357 63E5 +9358 63E6 +9359 63E7 +935A 63E8 +BFAB 63E9 +BEBE 63EA +935B 63EB +935C 63EC +BDD2 63ED +935D 63EE +935E 63EF +935F 63F0 +9360 63F1 +DEE9 63F2 +9361 63F3 +D4AE 63F4 +9362 63F5 +DEDE 63F6 +9363 63F7 +DEEA 63F8 +9364 63F9 +9365 63FA +9366 63FB +9367 63FC +C0BF 63FD +9368 63FE +DEEC 63FF +B2F3 6400 +B8E9 6401 +C2A7 6402 +9369 6403 +936A 6404 +BDC1 6405 +936B 6406 +936C 6407 +936D 6408 +936E 6409 +936F 640A +DEF5 640B +DEF8 640C +9370 640D +9371 640E +B2AB 640F +B4A4 6410 +9372 6411 +9373 6412 +B4EA 6413 +C9A6 6414 +9374 6415 +9375 6416 +9376 6417 +9377 6418 +9378 6419 +9379 641A +DEF6 641B +CBD1 641C +937A 641D +B8E3 641E +937B 641F +DEF7 6420 +DEFA 6421 +937C 6422 +937D 6423 +937E 6424 +9380 6425 +DEF9 6426 +9381 6427 +9382 6428 +9383 6429 +CCC2 642A +9384 642B +B0E1 642C +B4EE 642D +9385 642E +9386 642F +9387 6430 +9388 6431 +9389 6432 +938A 6433 +E5BA 6434 +938B 6435 +938C 6436 +938D 6437 +938E 6438 +938F 6439 +D0AF 643A +9390 643B +9391 643C +B2EB 643D +9392 643E +EBA1 643F +9393 6440 +DEF4 6441 +9394 6442 +9395 6443 +C9E3 6444 +DEF3 6445 +B0DA 6446 +D2A1 6447 +B1F7 6448 +9396 6449 +CCAF 644A +9397 644B +9398 644C +9399 644D +939A 644E +939B 644F +939C 6450 +939D 6451 +DEF0 6452 +939E 6453 +CBA4 6454 +939F 6455 +93A0 6456 +93A1 6457 +D5AA 6458 +93A2 6459 +93A3 645A +93A4 645B +93A5 645C +93A6 645D +DEFB 645E +93A7 645F +93A8 6460 +93A9 6461 +93AA 6462 +93AB 6463 +93AC 6464 +93AD 6465 +93AE 6466 +B4DD 6467 +93AF 6468 +C4A6 6469 +93B0 646A +93B1 646B +93B2 646C +DEFD 646D +93B3 646E +93B4 646F +93B5 6470 +93B6 6471 +93B7 6472 +93B8 6473 +93B9 6474 +93BA 6475 +93BB 6476 +93BC 6477 +C3FE 6478 +C4A1 6479 +DFA1 647A +93BD 647B +93BE 647C +93BF 647D +93C0 647E +93C1 647F +93C2 6480 +93C3 6481 +C1CC 6482 +93C4 6483 +DEFC 6484 +BEEF 6485 +93C5 6486 +C6B2 6487 +93C6 6488 +93C7 6489 +93C8 648A +93C9 648B +93CA 648C +93CB 648D +93CC 648E +93CD 648F +93CE 6490 +B3C5 6491 +C8F6 6492 +93CF 6493 +93D0 6494 +CBBA 6495 +DEFE 6496 +93D1 6497 +93D2 6498 +DFA4 6499 +93D3 649A +93D4 649B +93D5 649C +93D6 649D +D7B2 649E +93D7 649F +93D8 64A0 +93D9 64A1 +93DA 64A2 +93DB 64A3 +B3B7 64A4 +93DC 64A5 +93DD 64A6 +93DE 64A7 +93DF 64A8 +C1C3 64A9 +93E0 64AA +93E1 64AB +C7CB 64AC +B2A5 64AD +B4E9 64AE +93E2 64AF +D7AB 64B0 +93E3 64B1 +93E4 64B2 +93E5 64B3 +93E6 64B4 +C4EC 64B5 +93E7 64B6 +DFA2 64B7 +DFA3 64B8 +93E8 64B9 +DFA5 64BA +93E9 64BB +BAB3 64BC +93EA 64BD +93EB 64BE +93EC 64BF +DFA6 64C0 +93ED 64C1 +C0DE 64C2 +93EE 64C3 +93EF 64C4 +C9C3 64C5 +93F0 64C6 +93F1 64C7 +93F2 64C8 +93F3 64C9 +93F4 64CA +93F5 64CB +93F6 64CC +B2D9 64CD +C7E6 64CE +93F7 64CF +DFA7 64D0 +93F8 64D1 +C7DC 64D2 +93F9 64D3 +93FA 64D4 +93FB 64D5 +93FC 64D6 +DFA8 64D7 +EBA2 64D8 +93FD 64D9 +93FE 64DA +9440 64DB +9441 64DC +9442 64DD +CBD3 64DE +9443 64DF +9444 64E0 +9445 64E1 +DFAA 64E2 +9446 64E3 +DFA9 64E4 +9447 64E5 +B2C1 64E6 +9448 64E7 +9449 64E8 +944A 64E9 +944B 64EA +944C 64EB +944D 64EC +944E 64ED +944F 64EE +9450 64EF +9451 64F0 +9452 64F1 +9453 64F2 +9454 64F3 +9455 64F4 +9456 64F5 +9457 64F6 +9458 64F7 +9459 64F8 +945A 64F9 +945B 64FA +945C 64FB +945D 64FC +945E 64FD +945F 64FE +9460 64FF +C5CA 6500 +9461 6501 +9462 6502 +9463 6503 +9464 6504 +9465 6505 +9466 6506 +9467 6507 +9468 6508 +DFAB 6509 +9469 650A +946A 650B +946B 650C +946C 650D +946D 650E +946E 650F +946F 6510 +9470 6511 +D4DC 6512 +9471 6513 +9472 6514 +9473 6515 +9474 6516 +9475 6517 +C8C1 6518 +9476 6519 +9477 651A +9478 651B +9479 651C +947A 651D +947B 651E +947C 651F +947D 6520 +947E 6521 +9480 6522 +9481 6523 +9482 6524 +DFAC 6525 +9483 6526 +9484 6527 +9485 6528 +9486 6529 +9487 652A +BEF0 652B +9488 652C +9489 652D +DFAD 652E +D6A7 652F +948A 6530 +948B 6531 +948C 6532 +948D 6533 +EAB7 6534 +EBB6 6535 +CAD5 6536 +948E 6537 +D8FC 6538 +B8C4 6539 +948F 653A +B9A5 653B +9490 653C +9491 653D +B7C5 653E +D5FE 653F +9492 6540 +9493 6541 +9494 6542 +9495 6543 +9496 6544 +B9CA 6545 +9497 6546 +9498 6547 +D0A7 6548 +F4CD 6549 +9499 654A +949A 654B +B5D0 654C +949B 654D +949C 654E +C3F4 654F +949D 6550 +BEC8 6551 +949E 6552 +949F 6553 +94A0 6554 +EBB7 6555 +B0BD 6556 +94A1 6557 +94A2 6558 +BDCC 6559 +94A3 655A +C1B2 655B +94A4 655C +B1D6 655D +B3A8 655E +94A5 655F +94A6 6560 +94A7 6561 +B8D2 6562 +C9A2 6563 +94A8 6564 +94A9 6565 +B6D8 6566 +94AA 6567 +94AB 6568 +94AC 6569 +94AD 656A +EBB8 656B +BEB4 656C +94AE 656D +94AF 656E +94B0 656F +CAFD 6570 +94B1 6571 +C7C3 6572 +94B2 6573 +D5FB 6574 +94B3 6575 +94B4 6576 +B7F3 6577 +94B5 6578 +94B6 6579 +94B7 657A +94B8 657B +94B9 657C +94BA 657D +94BB 657E +94BC 657F +94BD 6580 +94BE 6581 +94BF 6582 +94C0 6583 +94C1 6584 +94C2 6585 +94C3 6586 +CEC4 6587 +94C4 6588 +94C5 6589 +94C6 658A +D5AB 658B +B1F3 658C +94C7 658D +94C8 658E +94C9 658F +ECB3 6590 +B0DF 6591 +94CA 6592 +ECB5 6593 +94CB 6594 +94CC 6595 +94CD 6596 +B6B7 6597 +94CE 6598 +C1CF 6599 +94CF 659A +F5FA 659B +D0B1 659C +94D0 659D +94D1 659E +D5E5 659F +94D2 65A0 +CED3 65A1 +94D3 65A2 +94D4 65A3 +BDEF 65A4 +B3E2 65A5 +94D5 65A6 +B8AB 65A7 +94D6 65A8 +D5B6 65A9 +94D7 65AA +EDBD 65AB +94D8 65AC +B6CF 65AD +94D9 65AE +CBB9 65AF +D0C2 65B0 +94DA 65B1 +94DB 65B2 +94DC 65B3 +94DD 65B4 +94DE 65B5 +94DF 65B6 +94E0 65B7 +94E1 65B8 +B7BD 65B9 +94E2 65BA +94E3 65BB +ECB6 65BC +CAA9 65BD +94E4 65BE +94E5 65BF +94E6 65C0 +C5D4 65C1 +94E7 65C2 +ECB9 65C3 +ECB8 65C4 +C2C3 65C5 +ECB7 65C6 +94E8 65C7 +94E9 65C8 +94EA 65C9 +94EB 65CA +D0FD 65CB +ECBA 65CC +94EC 65CD +ECBB 65CE +D7E5 65CF +94ED 65D0 +94EE 65D1 +ECBC 65D2 +94EF 65D3 +94F0 65D4 +94F1 65D5 +ECBD 65D6 +C6EC 65D7 +94F2 65D8 +94F3 65D9 +94F4 65DA +94F5 65DB +94F6 65DC +94F7 65DD +94F8 65DE +94F9 65DF +CEDE 65E0 +94FA 65E1 +BCC8 65E2 +94FB 65E3 +94FC 65E4 +C8D5 65E5 +B5A9 65E6 +BEC9 65E7 +D6BC 65E8 +D4E7 65E9 +94FD 65EA +94FE 65EB +D1AE 65EC +D0F1 65ED +EAB8 65EE +EAB9 65EF +EABA 65F0 +BAB5 65F1 +9540 65F2 +9541 65F3 +9542 65F4 +9543 65F5 +CAB1 65F6 +BFF5 65F7 +9544 65F8 +9545 65F9 +CDFA 65FA +9546 65FB +9547 65FC +9548 65FD +9549 65FE +954A 65FF +EAC0 6600 +954B 6601 +B0BA 6602 +EABE 6603 +954C 6604 +954D 6605 +C0A5 6606 +954E 6607 +954F 6608 +9550 6609 +EABB 660A +9551 660B +B2FD 660C +9552 660D +C3F7 660E +BBE8 660F +9553 6610 +9554 6611 +9555 6612 +D2D7 6613 +CEF4 6614 +EABF 6615 +9556 6616 +9557 6617 +9558 6618 +EABC 6619 +9559 661A +955A 661B +955B 661C +EAC3 661D +955C 661E +D0C7 661F +D3B3 6620 +955D 6621 +955E 6622 +955F 6623 +9560 6624 +B4BA 6625 +9561 6626 +C3C1 6627 +D7F2 6628 +9562 6629 +9563 662A +9564 662B +9565 662C +D5D1 662D +9566 662E +CAC7 662F +9567 6630 +EAC5 6631 +9568 6632 +9569 6633 +EAC4 6634 +EAC7 6635 +EAC6 6636 +956A 6637 +956B 6638 +956C 6639 +956D 663A +956E 663B +D6E7 663C +956F 663D +CFD4 663E +9570 663F +9571 6640 +EACB 6641 +9572 6642 +BBCE 6643 +9573 6644 +9574 6645 +9575 6646 +9576 6647 +9577 6648 +9578 6649 +9579 664A +BDFA 664B +C9CE 664C +957A 664D +957B 664E +EACC 664F +957C 6650 +957D 6651 +C9B9 6652 +CFFE 6653 +EACA 6654 +D4CE 6655 +EACD 6656 +EACF 6657 +957E 6658 +9580 6659 +CDED 665A +9581 665B +9582 665C +9583 665D +9584 665E +EAC9 665F +9585 6660 +EACE 6661 +9586 6662 +9587 6663 +CEEE 6664 +9588 6665 +BBDE 6666 +9589 6667 +B3BF 6668 +958A 6669 +958B 666A +958C 666B +958D 666C +958E 666D +C6D5 666E +BEB0 666F +CEFA 6670 +958F 6671 +9590 6672 +9591 6673 +C7E7 6674 +9592 6675 +BEA7 6676 +EAD0 6677 +9593 6678 +9594 6679 +D6C7 667A +9595 667B +9596 667C +9597 667D +C1C0 667E +9598 667F +9599 6680 +959A 6681 +D4DD 6682 +959B 6683 +EAD1 6684 +959C 6685 +959D 6686 +CFBE 6687 +959E 6688 +959F 6689 +95A0 668A +95A1 668B +EAD2 668C +95A2 668D +95A3 668E +95A4 668F +95A5 6690 +CAEE 6691 +95A6 6692 +95A7 6693 +95A8 6694 +95A9 6695 +C5AF 6696 +B0B5 6697 +95AA 6698 +95AB 6699 +95AC 669A +95AD 669B +95AE 669C +EAD4 669D +95AF 669E +95B0 669F +95B1 66A0 +95B2 66A1 +95B3 66A2 +95B4 66A3 +95B5 66A4 +95B6 66A5 +95B7 66A6 +EAD3 66A7 +F4DF 66A8 +95B8 66A9 +95B9 66AA +95BA 66AB +95BB 66AC +95BC 66AD +C4BA 66AE +95BD 66AF +95BE 66B0 +95BF 66B1 +95C0 66B2 +95C1 66B3 +B1A9 66B4 +95C2 66B5 +95C3 66B6 +95C4 66B7 +95C5 66B8 +E5DF 66B9 +95C6 66BA +95C7 66BB +95C8 66BC +95C9 66BD +EAD5 66BE +95CA 66BF +95CB 66C0 +95CC 66C1 +95CD 66C2 +95CE 66C3 +95CF 66C4 +95D0 66C5 +95D1 66C6 +95D2 66C7 +95D3 66C8 +95D4 66C9 +95D5 66CA +95D6 66CB +95D7 66CC +95D8 66CD +95D9 66CE +95DA 66CF +95DB 66D0 +95DC 66D1 +95DD 66D2 +95DE 66D3 +95DF 66D4 +95E0 66D5 +95E1 66D6 +95E2 66D7 +95E3 66D8 +CAEF 66D9 +95E4 66DA +EAD6 66DB +EAD7 66DC +C6D8 66DD +95E5 66DE +95E6 66DF +95E7 66E0 +95E8 66E1 +95E9 66E2 +95EA 66E3 +95EB 66E4 +95EC 66E5 +EAD8 66E6 +95ED 66E7 +95EE 66E8 +EAD9 66E9 +95EF 66EA +95F0 66EB +95F1 66EC +95F2 66ED +95F3 66EE +95F4 66EF +D4BB 66F0 +95F5 66F1 +C7FA 66F2 +D2B7 66F3 +B8FC 66F4 +95F6 66F5 +95F7 66F6 +EAC2 66F7 +95F8 66F8 +B2DC 66F9 +95F9 66FA +95FA 66FB +C2FC 66FC +95FB 66FD +D4F8 66FE +CCE6 66FF +D7EE 6700 +95FC 6701 +95FD 6702 +95FE 6703 +9640 6704 +9641 6705 +9642 6706 +9643 6707 +D4C2 6708 +D3D0 6709 +EBC3 670A +C5F3 670B +9644 670C +B7FE 670D +9645 670E +9646 670F +EBD4 6710 +9647 6711 +9648 6712 +9649 6713 +CBB7 6714 +EBDE 6715 +964A 6716 +C0CA 6717 +964B 6718 +964C 6719 +964D 671A +CDFB 671B +964E 671C +B3AF 671D +964F 671E +C6DA 671F +9650 6720 +9651 6721 +9652 6722 +9653 6723 +9654 6724 +9655 6725 +EBFC 6726 +9656 6727 +C4BE 6728 +9657 6729 +CEB4 672A +C4A9 672B +B1BE 672C +D4FD 672D +9658 672E +CAF5 672F +9659 6730 +D6EC 6731 +965A 6732 +965B 6733 +C6D3 6734 +B6E4 6735 +965C 6736 +965D 6737 +965E 6738 +965F 6739 +BBFA 673A +9660 673B +9661 673C +D0E0 673D +9662 673E +9663 673F +C9B1 6740 +9664 6741 +D4D3 6742 +C8A8 6743 +9665 6744 +9666 6745 +B8CB 6746 +9667 6747 +E8BE 6748 +C9BC 6749 +9668 674A +9669 674B +E8BB 674C +966A 674D +C0EE 674E +D0D3 674F +B2C4 6750 +B4E5 6751 +966B 6752 +E8BC 6753 +966C 6754 +966D 6755 +D5C8 6756 +966E 6757 +966F 6758 +9670 6759 +9671 675A +9672 675B +B6C5 675C +9673 675D +E8BD 675E +CAF8 675F +B8DC 6760 +CCF5 6761 +9674 6762 +9675 6763 +9676 6764 +C0B4 6765 +9677 6766 +9678 6767 +D1EE 6768 +E8BF 6769 +E8C2 676A +9679 676B +967A 676C +BABC 676D +967B 676E +B1AD 676F +BDDC 6770 +967C 6771 +EABD 6772 +E8C3 6773 +967D 6774 +E8C6 6775 +967E 6776 +E8CB 6777 +9680 6778 +9681 6779 +9682 677A +9683 677B +E8CC 677C +9684 677D +CBC9 677E +B0E5 677F +9685 6780 +BCAB 6781 +9686 6782 +9687 6783 +B9B9 6784 +9688 6785 +9689 6786 +E8C1 6787 +968A 6788 +CDF7 6789 +968B 678A +E8CA 678B +968C 678C +968D 678D +968E 678E +968F 678F +CEF6 6790 +9690 6791 +9691 6792 +9692 6793 +9693 6794 +D5ED 6795 +9694 6796 +C1D6 6797 +E8C4 6798 +9695 6799 +C3B6 679A +9696 679B +B9FB 679C +D6A6 679D +E8C8 679E +9697 679F +9698 67A0 +9699 67A1 +CAE0 67A2 +D4E6 67A3 +969A 67A4 +E8C0 67A5 +969B 67A6 +E8C5 67A7 +E8C7 67A8 +969C 67A9 +C7B9 67AA +B7E3 67AB +969D 67AC +E8C9 67AD +969E 67AE +BFDD 67AF +E8D2 67B0 +969F 67B1 +96A0 67B2 +E8D7 67B3 +96A1 67B4 +E8D5 67B5 +BCDC 67B6 +BCCF 67B7 +E8DB 67B8 +96A2 67B9 +96A3 67BA +96A4 67BB +96A5 67BC +96A6 67BD +96A7 67BE +96A8 67BF +96A9 67C0 +E8DE 67C1 +96AA 67C2 +E8DA 67C3 +B1FA 67C4 +96AB 67C5 +96AC 67C6 +96AD 67C7 +96AE 67C8 +96AF 67C9 +96B0 67CA +96B1 67CB +96B2 67CC +96B3 67CD +96B4 67CE +B0D8 67CF +C4B3 67D0 +B8CC 67D1 +C6E2 67D2 +C8BE 67D3 +C8E1 67D4 +96B5 67D5 +96B6 67D6 +96B7 67D7 +E8CF 67D8 +E8D4 67D9 +E8D6 67DA +96B8 67DB +B9F1 67DC +E8D8 67DD +D7F5 67DE +96B9 67DF +C4FB 67E0 +96BA 67E1 +E8DC 67E2 +96BB 67E3 +96BC 67E4 +B2E9 67E5 +96BD 67E6 +96BE 67E7 +96BF 67E8 +E8D1 67E9 +96C0 67EA +96C1 67EB +BCED 67EC +96C2 67ED +96C3 67EE +BFC2 67EF +E8CD 67F0 +D6F9 67F1 +96C4 67F2 +C1F8 67F3 +B2F1 67F4 +96C5 67F5 +96C6 67F6 +96C7 67F7 +96C8 67F8 +96C9 67F9 +96CA 67FA +96CB 67FB +96CC 67FC +E8DF 67FD +96CD 67FE +CAC1 67FF +E8D9 6800 +96CE 6801 +96CF 6802 +96D0 6803 +96D1 6804 +D5A4 6805 +96D2 6806 +B1EA 6807 +D5BB 6808 +E8CE 6809 +E8D0 680A +B6B0 680B +E8D3 680C +96D3 680D +E8DD 680E +C0B8 680F +96D4 6810 +CAF7 6811 +96D5 6812 +CBA8 6813 +96D6 6814 +96D7 6815 +C6DC 6816 +C0F5 6817 +96D8 6818 +96D9 6819 +96DA 681A +96DB 681B +96DC 681C +E8E9 681D +96DD 681E +96DE 681F +96DF 6820 +D0A3 6821 +96E0 6822 +96E1 6823 +96E2 6824 +96E3 6825 +96E4 6826 +96E5 6827 +96E6 6828 +E8F2 6829 +D6EA 682A +96E7 682B +96E8 682C +96E9 682D +96EA 682E +96EB 682F +96EC 6830 +96ED 6831 +E8E0 6832 +E8E1 6833 +96EE 6834 +96EF 6835 +96F0 6836 +D1F9 6837 +BACB 6838 +B8F9 6839 +96F1 683A +96F2 683B +B8F1 683C +D4D4 683D +E8EF 683E +96F3 683F +E8EE 6840 +E8EC 6841 +B9F0 6842 +CCD2 6843 +E8E6 6844 +CEA6 6845 +BFF2 6846 +96F4 6847 +B0B8 6848 +E8F1 6849 +E8F0 684A +96F5 684B +D7C0 684C +96F6 684D +E8E4 684E +96F7 684F +CDA9 6850 +C9A3 6851 +96F8 6852 +BBB8 6853 +BDDB 6854 +E8EA 6855 +96F9 6856 +96FA 6857 +96FB 6858 +96FC 6859 +96FD 685A +96FE 685B +9740 685C +9741 685D +9742 685E +9743 685F +E8E2 6860 +E8E3 6861 +E8E5 6862 +B5B5 6863 +E8E7 6864 +C7C5 6865 +E8EB 6866 +E8ED 6867 +BDB0 6868 +D7AE 6869 +9744 686A +E8F8 686B +9745 686C +9746 686D +9747 686E +9748 686F +9749 6870 +974A 6871 +974B 6872 +974C 6873 +E8F5 6874 +974D 6875 +CDB0 6876 +E8F6 6877 +974E 6878 +974F 6879 +9750 687A +9751 687B +9752 687C +9753 687D +9754 687E +9755 687F +9756 6880 +C1BA 6881 +9757 6882 +E8E8 6883 +9758 6884 +C3B7 6885 +B0F0 6886 +9759 6887 +975A 6888 +975B 6889 +975C 688A +975D 688B +975E 688C +975F 688D +9760 688E +E8F4 688F +9761 6890 +9762 6891 +9763 6892 +E8F7 6893 +9764 6894 +9765 6895 +9766 6896 +B9A3 6897 +9767 6898 +9768 6899 +9769 689A +976A 689B +976B 689C +976C 689D +976D 689E +976E 689F +976F 68A0 +9770 68A1 +C9D2 68A2 +9771 68A3 +9772 68A4 +9773 68A5 +C3CE 68A6 +CEE0 68A7 +C0E6 68A8 +9774 68A9 +9775 68AA +9776 68AB +9777 68AC +CBF3 68AD +9778 68AE +CCDD 68AF +D0B5 68B0 +9779 68B1 +977A 68B2 +CAE1 68B3 +977B 68B4 +E8F3 68B5 +977C 68B6 +977D 68B7 +977E 68B8 +9780 68B9 +9781 68BA +9782 68BB +9783 68BC +9784 68BD +9785 68BE +9786 68BF +BCEC 68C0 +9787 68C1 +E8F9 68C2 +9788 68C3 +9789 68C4 +978A 68C5 +978B 68C6 +978C 68C7 +978D 68C8 +C3DE 68C9 +978E 68CA +C6E5 68CB +978F 68CC +B9F7 68CD +9790 68CE +9791 68CF +9792 68D0 +9793 68D1 +B0F4 68D2 +9794 68D3 +9795 68D4 +D7D8 68D5 +9796 68D6 +9797 68D7 +BCAC 68D8 +9798 68D9 +C5EF 68DA +9799 68DB +979A 68DC +979B 68DD +979C 68DE +979D 68DF +CCC4 68E0 +979E 68E1 +979F 68E2 +E9A6 68E3 +97A0 68E4 +97A1 68E5 +97A2 68E6 +97A3 68E7 +97A4 68E8 +97A5 68E9 +97A6 68EA +97A7 68EB +97A8 68EC +97A9 68ED +C9AD 68EE +97AA 68EF +E9A2 68F0 +C0E2 68F1 +97AB 68F2 +97AC 68F3 +97AD 68F4 +BFC3 68F5 +97AE 68F6 +97AF 68F7 +97B0 68F8 +E8FE 68F9 +B9D7 68FA +97B1 68FB +E8FB 68FC +97B2 68FD +97B3 68FE +97B4 68FF +97B5 6900 +E9A4 6901 +97B6 6902 +97B7 6903 +97B8 6904 +D2CE 6905 +97B9 6906 +97BA 6907 +97BB 6908 +97BC 6909 +97BD 690A +E9A3 690B +97BE 690C +D6B2 690D +D7B5 690E +97BF 690F +E9A7 6910 +97C0 6911 +BDB7 6912 +97C1 6913 +97C2 6914 +97C3 6915 +97C4 6916 +97C5 6917 +97C6 6918 +97C7 6919 +97C8 691A +97C9 691B +97CA 691C +97CB 691D +97CC 691E +E8FC 691F +E8FD 6920 +97CD 6921 +97CE 6922 +97CF 6923 +E9A1 6924 +97D0 6925 +97D1 6926 +97D2 6927 +97D3 6928 +97D4 6929 +97D5 692A +97D6 692B +97D7 692C +CDD6 692D +97D8 692E +97D9 692F +D2AC 6930 +97DA 6931 +97DB 6932 +97DC 6933 +E9B2 6934 +97DD 6935 +97DE 6936 +97DF 6937 +97E0 6938 +E9A9 6939 +97E1 693A +97E2 693B +97E3 693C +B4AA 693D +97E4 693E +B4BB 693F +97E5 6940 +97E6 6941 +E9AB 6942 +97E7 6943 +97E8 6944 +97E9 6945 +97EA 6946 +97EB 6947 +97EC 6948 +97ED 6949 +97EE 694A +97EF 694B +97F0 694C +97F1 694D +97F2 694E +97F3 694F +97F4 6950 +97F5 6951 +97F6 6952 +97F7 6953 +D0A8 6954 +97F8 6955 +97F9 6956 +E9A5 6957 +97FA 6958 +97FB 6959 +B3FE 695A +97FC 695B +97FD 695C +E9AC 695D +C0E3 695E +97FE 695F +E9AA 6960 +9840 6961 +9841 6962 +E9B9 6963 +9842 6964 +9843 6965 +E9B8 6966 +9844 6967 +9845 6968 +9846 6969 +9847 696A +E9AE 696B +9848 696C +9849 696D +E8FA 696E +984A 696F +984B 6970 +E9A8 6971 +984C 6972 +984D 6973 +984E 6974 +984F 6975 +9850 6976 +BFAC 6977 +E9B1 6978 +E9BA 6979 +9851 697A +9852 697B +C2A5 697C +9853 697D +9854 697E +9855 697F +E9AF 6980 +9856 6981 +B8C5 6982 +9857 6983 +E9AD 6984 +9858 6985 +D3DC 6986 +E9B4 6987 +E9B5 6988 +E9B7 6989 +9859 698A +985A 698B +985B 698C +E9C7 698D +985C 698E +985D 698F +985E 6990 +985F 6991 +9860 6992 +9861 6993 +C0C6 6994 +E9C5 6995 +9862 6996 +9863 6997 +E9B0 6998 +9864 6999 +9865 699A +E9BB 699B +B0F1 699C +9866 699D +9867 699E +9868 699F +9869 69A0 +986A 69A1 +986B 69A2 +986C 69A3 +986D 69A4 +986E 69A5 +986F 69A6 +E9BC 69A7 +D5A5 69A8 +9870 69A9 +9871 69AA +E9BE 69AB +9872 69AC +E9BF 69AD +9873 69AE +9874 69AF +9875 69B0 +E9C1 69B1 +9876 69B2 +9877 69B3 +C1F1 69B4 +9878 69B5 +9879 69B6 +C8B6 69B7 +987A 69B8 +987B 69B9 +987C 69BA +E9BD 69BB +987D 69BC +987E 69BD +9880 69BE +9881 69BF +9882 69C0 +E9C2 69C1 +9883 69C2 +9884 69C3 +9885 69C4 +9886 69C5 +9887 69C6 +9888 69C7 +9889 69C8 +988A 69C9 +E9C3 69CA +988B 69CB +E9B3 69CC +988C 69CD +E9B6 69CE +988D 69CF +BBB1 69D0 +988E 69D1 +988F 69D2 +9890 69D3 +E9C0 69D4 +9891 69D5 +9892 69D6 +9893 69D7 +9894 69D8 +9895 69D9 +9896 69DA +BCF7 69DB +9897 69DC +9898 69DD +9899 69DE +E9C4 69DF +E9C6 69E0 +989A 69E1 +989B 69E2 +989C 69E3 +989D 69E4 +989E 69E5 +989F 69E6 +98A0 69E7 +98A1 69E8 +98A2 69E9 +98A3 69EA +98A4 69EB +98A5 69EC +E9CA 69ED +98A6 69EE +98A7 69EF +98A8 69F0 +98A9 69F1 +E9CE 69F2 +98AA 69F3 +98AB 69F4 +98AC 69F5 +98AD 69F6 +98AE 69F7 +98AF 69F8 +98B0 69F9 +98B1 69FA +98B2 69FB +98B3 69FC +B2DB 69FD +98B4 69FE +E9C8 69FF +98B5 6A00 +98B6 6A01 +98B7 6A02 +98B8 6A03 +98B9 6A04 +98BA 6A05 +98BB 6A06 +98BC 6A07 +98BD 6A08 +98BE 6A09 +B7AE 6A0A +98BF 6A0B +98C0 6A0C +98C1 6A0D +98C2 6A0E +98C3 6A0F +98C4 6A10 +98C5 6A11 +98C6 6A12 +98C7 6A13 +98C8 6A14 +98C9 6A15 +98CA 6A16 +E9CB 6A17 +E9CC 6A18 +98CB 6A19 +98CC 6A1A +98CD 6A1B +98CE 6A1C +98CF 6A1D +98D0 6A1E +D5C1 6A1F +98D1 6A20 +C4A3 6A21 +98D2 6A22 +98D3 6A23 +98D4 6A24 +98D5 6A25 +98D6 6A26 +98D7 6A27 +E9D8 6A28 +98D8 6A29 +BAE1 6A2A +98D9 6A2B +98DA 6A2C +98DB 6A2D +98DC 6A2E +E9C9 6A2F +98DD 6A30 +D3A3 6A31 +98DE 6A32 +98DF 6A33 +98E0 6A34 +E9D4 6A35 +98E1 6A36 +98E2 6A37 +98E3 6A38 +98E4 6A39 +98E5 6A3A +98E6 6A3B +98E7 6A3C +E9D7 6A3D +E9D0 6A3E +98E8 6A3F +98E9 6A40 +98EA 6A41 +98EB 6A42 +98EC 6A43 +E9CF 6A44 +98ED 6A45 +98EE 6A46 +C7C1 6A47 +98EF 6A48 +98F0 6A49 +98F1 6A4A +98F2 6A4B +98F3 6A4C +98F4 6A4D +98F5 6A4E +98F6 6A4F +E9D2 6A50 +98F7 6A51 +98F8 6A52 +98F9 6A53 +98FA 6A54 +98FB 6A55 +98FC 6A56 +98FD 6A57 +E9D9 6A58 +B3C8 6A59 +98FE 6A5A +E9D3 6A5B +9940 6A5C +9941 6A5D +9942 6A5E +9943 6A5F +9944 6A60 +CFF0 6A61 +9945 6A62 +9946 6A63 +9947 6A64 +E9CD 6A65 +9948 6A66 +9949 6A67 +994A 6A68 +994B 6A69 +994C 6A6A +994D 6A6B +994E 6A6C +994F 6A6D +9950 6A6E +9951 6A6F +9952 6A70 +B3F7 6A71 +9953 6A72 +9954 6A73 +9955 6A74 +9956 6A75 +9957 6A76 +9958 6A77 +9959 6A78 +E9D6 6A79 +995A 6A7A +995B 6A7B +E9DA 6A7C +995C 6A7D +995D 6A7E +995E 6A7F +CCB4 6A80 +995F 6A81 +9960 6A82 +9961 6A83 +CFAD 6A84 +9962 6A85 +9963 6A86 +9964 6A87 +9965 6A88 +9966 6A89 +9967 6A8A +9968 6A8B +9969 6A8C +996A 6A8D +E9D5 6A8E +996B 6A8F +E9DC 6A90 +E9DB 6A91 +996C 6A92 +996D 6A93 +996E 6A94 +996F 6A95 +9970 6A96 +E9DE 6A97 +9971 6A98 +9972 6A99 +9973 6A9A +9974 6A9B +9975 6A9C +9976 6A9D +9977 6A9E +9978 6A9F +E9D1 6AA0 +9979 6AA1 +997A 6AA2 +997B 6AA3 +997C 6AA4 +997D 6AA5 +997E 6AA6 +9980 6AA7 +9981 6AA8 +E9DD 6AA9 +9982 6AAA +E9DF 6AAB +C3CA 6AAC +9983 6AAD +9984 6AAE +9985 6AAF +9986 6AB0 +9987 6AB1 +9988 6AB2 +9989 6AB3 +998A 6AB4 +998B 6AB5 +998C 6AB6 +998D 6AB7 +998E 6AB8 +998F 6AB9 +9990 6ABA +9991 6ABB +9992 6ABC +9993 6ABD +9994 6ABE +9995 6ABF +9996 6AC0 +9997 6AC1 +9998 6AC2 +9999 6AC3 +999A 6AC4 +999B 6AC5 +999C 6AC6 +999D 6AC7 +999E 6AC8 +999F 6AC9 +99A0 6ACA +99A1 6ACB +99A2 6ACC +99A3 6ACD +99A4 6ACE +99A5 6ACF +99A6 6AD0 +99A7 6AD1 +99A8 6AD2 +99A9 6AD3 +99AA 6AD4 +99AB 6AD5 +99AC 6AD6 +99AD 6AD7 +99AE 6AD8 +99AF 6AD9 +99B0 6ADA +99B1 6ADB +99B2 6ADC +99B3 6ADD +99B4 6ADE +99B5 6ADF +99B6 6AE0 +99B7 6AE1 +99B8 6AE2 +99B9 6AE3 +99BA 6AE4 +99BB 6AE5 +99BC 6AE6 +99BD 6AE7 +99BE 6AE8 +99BF 6AE9 +99C0 6AEA +99C1 6AEB +99C2 6AEC +99C3 6AED +99C4 6AEE +99C5 6AEF +99C6 6AF0 +99C7 6AF1 +99C8 6AF2 +99C9 6AF3 +99CA 6AF4 +99CB 6AF5 +99CC 6AF6 +99CD 6AF7 +99CE 6AF8 +99CF 6AF9 +99D0 6AFA +99D1 6AFB +99D2 6AFC +99D3 6AFD +99D4 6AFE +99D5 6AFF +99D6 6B00 +99D7 6B01 +99D8 6B02 +99D9 6B03 +99DA 6B04 +99DB 6B05 +99DC 6B06 +99DD 6B07 +99DE 6B08 +99DF 6B09 +99E0 6B0A +99E1 6B0B +99E2 6B0C +99E3 6B0D +99E4 6B0E +99E5 6B0F +99E6 6B10 +99E7 6B11 +99E8 6B12 +99E9 6B13 +99EA 6B14 +99EB 6B15 +99EC 6B16 +99ED 6B17 +99EE 6B18 +99EF 6B19 +99F0 6B1A +99F1 6B1B +99F2 6B1C +99F3 6B1D +99F4 6B1E +99F5 6B1F +C7B7 6B20 +B4CE 6B21 +BBB6 6B22 +D0C0 6B23 +ECA3 6B24 +99F6 6B25 +99F7 6B26 +C5B7 6B27 +99F8 6B28 +99F9 6B29 +99FA 6B2A +99FB 6B2B +99FC 6B2C +99FD 6B2D +99FE 6B2E +9A40 6B2F +9A41 6B30 +9A42 6B31 +D3FB 6B32 +9A43 6B33 +9A44 6B34 +9A45 6B35 +9A46 6B36 +ECA4 6B37 +9A47 6B38 +ECA5 6B39 +C6DB 6B3A +9A48 6B3B +9A49 6B3C +9A4A 6B3D +BFEE 6B3E +9A4B 6B3F +9A4C 6B40 +9A4D 6B41 +9A4E 6B42 +ECA6 6B43 +9A4F 6B44 +9A50 6B45 +ECA7 6B46 +D0AA 6B47 +9A51 6B48 +C7B8 6B49 +9A52 6B4A +9A53 6B4B +B8E8 6B4C +9A54 6B4D +9A55 6B4E +9A56 6B4F +9A57 6B50 +9A58 6B51 +9A59 6B52 +9A5A 6B53 +9A5B 6B54 +9A5C 6B55 +9A5D 6B56 +9A5E 6B57 +9A5F 6B58 +ECA8 6B59 +9A60 6B5A +9A61 6B5B +9A62 6B5C +9A63 6B5D +9A64 6B5E +9A65 6B5F +9A66 6B60 +9A67 6B61 +D6B9 6B62 +D5FD 6B63 +B4CB 6B64 +B2BD 6B65 +CEE4 6B66 +C6E7 6B67 +9A68 6B68 +9A69 6B69 +CDE1 6B6A +9A6A 6B6B +9A6B 6B6C +9A6C 6B6D +9A6D 6B6E +9A6E 6B6F +9A6F 6B70 +9A70 6B71 +9A71 6B72 +9A72 6B73 +9A73 6B74 +9A74 6B75 +9A75 6B76 +9A76 6B77 +9A77 6B78 +B4F5 6B79 +9A78 6B7A +CBC0 6B7B +BCDF 6B7C +9A79 6B7D +9A7A 6B7E +9A7B 6B7F +9A7C 6B80 +E9E2 6B81 +E9E3 6B82 +D1EA 6B83 +E9E5 6B84 +9A7D 6B85 +B4F9 6B86 +E9E4 6B87 +9A7E 6B88 +D1B3 6B89 +CAE2 6B8A +B2D0 6B8B +9A80 6B8C +E9E8 6B8D +9A81 6B8E +9A82 6B8F +9A83 6B90 +9A84 6B91 +E9E6 6B92 +E9E7 6B93 +9A85 6B94 +9A86 6B95 +D6B3 6B96 +9A87 6B97 +9A88 6B98 +9A89 6B99 +E9E9 6B9A +E9EA 6B9B +9A8A 6B9C +9A8B 6B9D +9A8C 6B9E +9A8D 6B9F +9A8E 6BA0 +E9EB 6BA1 +9A8F 6BA2 +9A90 6BA3 +9A91 6BA4 +9A92 6BA5 +9A93 6BA6 +9A94 6BA7 +9A95 6BA8 +9A96 6BA9 +E9EC 6BAA +9A97 6BAB +9A98 6BAC +9A99 6BAD +9A9A 6BAE +9A9B 6BAF +9A9C 6BB0 +9A9D 6BB1 +9A9E 6BB2 +ECAF 6BB3 +C5B9 6BB4 +B6CE 6BB5 +9A9F 6BB6 +D2F3 6BB7 +9AA0 6BB8 +9AA1 6BB9 +9AA2 6BBA +9AA3 6BBB +9AA4 6BBC +9AA5 6BBD +9AA6 6BBE +B5EE 6BBF +9AA7 6BC0 +BBD9 6BC1 +ECB1 6BC2 +9AA8 6BC3 +9AA9 6BC4 +D2E3 6BC5 +9AAA 6BC6 +9AAB 6BC7 +9AAC 6BC8 +9AAD 6BC9 +9AAE 6BCA +CEE3 6BCB +9AAF 6BCC +C4B8 6BCD +9AB0 6BCE +C3BF 6BCF +9AB1 6BD0 +9AB2 6BD1 +B6BE 6BD2 +D8B9 6BD3 +B1C8 6BD4 +B1CF 6BD5 +B1D1 6BD6 +C5FE 6BD7 +9AB3 6BD8 +B1D0 6BD9 +9AB4 6BDA +C3AB 6BDB +9AB5 6BDC +9AB6 6BDD +9AB7 6BDE +9AB8 6BDF +9AB9 6BE0 +D5B1 6BE1 +9ABA 6BE2 +9ABB 6BE3 +9ABC 6BE4 +9ABD 6BE5 +9ABE 6BE6 +9ABF 6BE7 +9AC0 6BE8 +9AC1 6BE9 +EBA4 6BEA +BAC1 6BEB +9AC2 6BEC +9AC3 6BED +9AC4 6BEE +CCBA 6BEF +9AC5 6BF0 +9AC6 6BF1 +9AC7 6BF2 +EBA5 6BF3 +9AC8 6BF4 +EBA7 6BF5 +9AC9 6BF6 +9ACA 6BF7 +9ACB 6BF8 +EBA8 6BF9 +9ACC 6BFA +9ACD 6BFB +9ACE 6BFC +EBA6 6BFD +9ACF 6BFE +9AD0 6BFF +9AD1 6C00 +9AD2 6C01 +9AD3 6C02 +9AD4 6C03 +9AD5 6C04 +EBA9 6C05 +EBAB 6C06 +EBAA 6C07 +9AD6 6C08 +9AD7 6C09 +9AD8 6C0A +9AD9 6C0B +9ADA 6C0C +EBAC 6C0D +9ADB 6C0E +CACF 6C0F +D8B5 6C10 +C3F1 6C11 +9ADC 6C12 +C3A5 6C13 +C6F8 6C14 +EBAD 6C15 +C4CA 6C16 +9ADD 6C17 +EBAE 6C18 +EBAF 6C19 +EBB0 6C1A +B7D5 6C1B +9ADE 6C1C +9ADF 6C1D +9AE0 6C1E +B7FA 6C1F +9AE1 6C20 +EBB1 6C21 +C7E2 6C22 +9AE2 6C23 +EBB3 6C24 +9AE3 6C25 +BAA4 6C26 +D1F5 6C27 +B0B1 6C28 +EBB2 6C29 +EBB4 6C2A +9AE4 6C2B +9AE5 6C2C +9AE6 6C2D +B5AA 6C2E +C2C8 6C2F +C7E8 6C30 +9AE7 6C31 +EBB5 6C32 +9AE8 6C33 +CBAE 6C34 +E3DF 6C35 +9AE9 6C36 +9AEA 6C37 +D3C0 6C38 +9AEB 6C39 +9AEC 6C3A +9AED 6C3B +9AEE 6C3C +D9DB 6C3D +9AEF 6C3E +9AF0 6C3F +CDA1 6C40 +D6AD 6C41 +C7F3 6C42 +9AF1 6C43 +9AF2 6C44 +9AF3 6C45 +D9E0 6C46 +BBE3 6C47 +9AF4 6C48 +BABA 6C49 +E3E2 6C4A +9AF5 6C4B +9AF6 6C4C +9AF7 6C4D +9AF8 6C4E +9AF9 6C4F +CFAB 6C50 +9AFA 6C51 +9AFB 6C52 +9AFC 6C53 +E3E0 6C54 +C9C7 6C55 +9AFD 6C56 +BAB9 6C57 +9AFE 6C58 +9B40 6C59 +9B41 6C5A +D1B4 6C5B +E3E1 6C5C +C8EA 6C5D +B9AF 6C5E +BDAD 6C5F +B3D8 6C60 +CEDB 6C61 +9B42 6C62 +9B43 6C63 +CCC0 6C64 +9B44 6C65 +9B45 6C66 +9B46 6C67 +E3E8 6C68 +E3E9 6C69 +CDF4 6C6A +9B47 6C6B +9B48 6C6C +9B49 6C6D +9B4A 6C6E +9B4B 6C6F +CCAD 6C70 +9B4C 6C71 +BCB3 6C72 +9B4D 6C73 +E3EA 6C74 +9B4E 6C75 +E3EB 6C76 +9B4F 6C77 +9B50 6C78 +D0DA 6C79 +9B51 6C7A +9B52 6C7B +9B53 6C7C +C6FB 6C7D +B7DA 6C7E +9B54 6C7F +9B55 6C80 +C7DF 6C81 +D2CA 6C82 +CED6 6C83 +9B56 6C84 +E3E4 6C85 +E3EC 6C86 +9B57 6C87 +C9F2 6C88 +B3C1 6C89 +9B58 6C8A +9B59 6C8B +E3E7 6C8C +9B5A 6C8D +9B5B 6C8E +C6E3 6C8F +E3E5 6C90 +9B5C 6C91 +9B5D 6C92 +EDB3 6C93 +E3E6 6C94 +9B5E 6C95 +9B5F 6C96 +9B60 6C97 +9B61 6C98 +C9B3 6C99 +9B62 6C9A +C5E6 6C9B +9B63 6C9C +9B64 6C9D +9B65 6C9E +B9B5 6C9F +9B66 6CA0 +C3BB 6CA1 +9B67 6CA2 +E3E3 6CA3 +C5BD 6CA4 +C1A4 6CA5 +C2D9 6CA6 +B2D7 6CA7 +9B68 6CA8 +E3ED 6CA9 +BBA6 6CAA +C4AD 6CAB +9B69 6CAC +E3F0 6CAD +BEDA 6CAE +9B6A 6CAF +9B6B 6CB0 +E3FB 6CB1 +E3F5 6CB2 +BAD3 6CB3 +9B6C 6CB4 +9B6D 6CB5 +9B6E 6CB6 +9B6F 6CB7 +B7D0 6CB8 +D3CD 6CB9 +9B70 6CBA +D6CE 6CBB +D5D3 6CBC +B9C1 6CBD +D5B4 6CBE +D1D8 6CBF +9B71 6CC0 +9B72 6CC1 +9B73 6CC2 +9B74 6CC3 +D0B9 6CC4 +C7F6 6CC5 +9B75 6CC6 +9B76 6CC7 +9B77 6CC8 +C8AA 6CC9 +B2B4 6CCA +9B78 6CCB +C3DA 6CCC +9B79 6CCD +9B7A 6CCE +9B7B 6CCF +E3EE 6CD0 +9B7C 6CD1 +9B7D 6CD2 +E3FC 6CD3 +E3EF 6CD4 +B7A8 6CD5 +E3F7 6CD6 +E3F4 6CD7 +9B7E 6CD8 +9B80 6CD9 +9B81 6CDA +B7BA 6CDB +9B82 6CDC +9B83 6CDD +C5A2 6CDE +9B84 6CDF +E3F6 6CE0 +C5DD 6CE1 +B2A8 6CE2 +C6FC 6CE3 +9B85 6CE4 +C4E0 6CE5 +9B86 6CE6 +9B87 6CE7 +D7A2 6CE8 +9B88 6CE9 +C0E1 6CEA +E3F9 6CEB +9B89 6CEC +9B8A 6CED +E3FA 6CEE +E3FD 6CEF +CCA9 6CF0 +E3F3 6CF1 +9B8B 6CF2 +D3BE 6CF3 +9B8C 6CF4 +B1C3 6CF5 +EDB4 6CF6 +E3F1 6CF7 +E3F2 6CF8 +9B8D 6CF9 +E3F8 6CFA +D0BA 6CFB +C6C3 6CFC +D4F3 6CFD +E3FE 6CFE +9B8E 6CFF +9B8F 6D00 +BDE0 6D01 +9B90 6D02 +9B91 6D03 +E4A7 6D04 +9B92 6D05 +9B93 6D06 +E4A6 6D07 +9B94 6D08 +9B95 6D09 +9B96 6D0A +D1F3 6D0B +E4A3 6D0C +9B97 6D0D +E4A9 6D0E +9B98 6D0F +9B99 6D10 +9B9A 6D11 +C8F7 6D12 +9B9B 6D13 +9B9C 6D14 +9B9D 6D15 +9B9E 6D16 +CFB4 6D17 +9B9F 6D18 +E4A8 6D19 +E4AE 6D1A +C2E5 6D1B +9BA0 6D1C +9BA1 6D1D +B6B4 6D1E +9BA2 6D1F +9BA3 6D20 +9BA4 6D21 +9BA5 6D22 +9BA6 6D23 +9BA7 6D24 +BDF2 6D25 +9BA8 6D26 +E4A2 6D27 +9BA9 6D28 +9BAA 6D29 +BAE9 6D2A +E4AA 6D2B +9BAB 6D2C +9BAC 6D2D +E4AC 6D2E +9BAD 6D2F +9BAE 6D30 +B6FD 6D31 +D6DE 6D32 +E4B2 6D33 +9BAF 6D34 +E4AD 6D35 +9BB0 6D36 +9BB1 6D37 +9BB2 6D38 +E4A1 6D39 +9BB3 6D3A +BBEE 6D3B +CDDD 6D3C +C7A2 6D3D +C5C9 6D3E +9BB4 6D3F +9BB5 6D40 +C1F7 6D41 +9BB6 6D42 +E4A4 6D43 +9BB7 6D44 +C7B3 6D45 +BDAC 6D46 +BDBD 6D47 +E4A5 6D48 +9BB8 6D49 +D7C7 6D4A +B2E2 6D4B +9BB9 6D4C +E4AB 6D4D +BCC3 6D4E +E4AF 6D4F +9BBA 6D50 +BBEB 6D51 +E4B0 6D52 +C5A8 6D53 +E4B1 6D54 +9BBB 6D55 +9BBC 6D56 +9BBD 6D57 +9BBE 6D58 +D5E3 6D59 +BFA3 6D5A +9BBF 6D5B +E4BA 6D5C +9BC0 6D5D +E4B7 6D5E +9BC1 6D5F +E4BB 6D60 +9BC2 6D61 +9BC3 6D62 +E4BD 6D63 +9BC4 6D64 +9BC5 6D65 +C6D6 6D66 +9BC6 6D67 +9BC7 6D68 +BAC6 6D69 +C0CB 6D6A +9BC8 6D6B +9BC9 6D6C +9BCA 6D6D +B8A1 6D6E +E4B4 6D6F +9BCB 6D70 +9BCC 6D71 +9BCD 6D72 +9BCE 6D73 +D4A1 6D74 +9BCF 6D75 +9BD0 6D76 +BAA3 6D77 +BDFE 6D78 +9BD1 6D79 +9BD2 6D7A +9BD3 6D7B +E4BC 6D7C +9BD4 6D7D +9BD5 6D7E +9BD6 6D7F +9BD7 6D80 +9BD8 6D81 +CDBF 6D82 +9BD9 6D83 +9BDA 6D84 +C4F9 6D85 +9BDB 6D86 +9BDC 6D87 +CFFB 6D88 +C9E6 6D89 +9BDD 6D8A +9BDE 6D8B +D3BF 6D8C +9BDF 6D8D +CFD1 6D8E +9BE0 6D8F +9BE1 6D90 +E4B3 6D91 +9BE2 6D92 +E4B8 6D93 +E4B9 6D94 +CCE9 6D95 +9BE3 6D96 +9BE4 6D97 +9BE5 6D98 +9BE6 6D99 +9BE7 6D9A +CCCE 6D9B +9BE8 6D9C +C0D4 6D9D +E4B5 6D9E +C1B0 6D9F +E4B6 6DA0 +CED0 6DA1 +9BE9 6DA2 +BBC1 6DA3 +B5D3 6DA4 +9BEA 6DA5 +C8F3 6DA6 +BDA7 6DA7 +D5C7 6DA8 +C9AC 6DA9 +B8A2 6DAA +E4CA 6DAB +9BEB 6DAC +9BEC 6DAD +E4CC 6DAE +D1C4 6DAF +9BED 6DB0 +9BEE 6DB1 +D2BA 6DB2 +9BEF 6DB3 +9BF0 6DB4 +BAAD 6DB5 +9BF1 6DB6 +9BF2 6DB7 +BAD4 6DB8 +9BF3 6DB9 +9BF4 6DBA +9BF5 6DBB +9BF6 6DBC +9BF7 6DBD +9BF8 6DBE +E4C3 6DBF +B5ED 6DC0 +9BF9 6DC1 +9BFA 6DC2 +9BFB 6DC3 +D7CD 6DC4 +E4C0 6DC5 +CFFD 6DC6 +E4BF 6DC7 +9BFC 6DC8 +9BFD 6DC9 +9BFE 6DCA +C1DC 6DCB +CCCA 6DCC +9C40 6DCD +9C41 6DCE +9C42 6DCF +9C43 6DD0 +CAE7 6DD1 +9C44 6DD2 +9C45 6DD3 +9C46 6DD4 +9C47 6DD5 +C4D7 6DD6 +9C48 6DD7 +CCD4 6DD8 +E4C8 6DD9 +9C49 6DDA +9C4A 6DDB +9C4B 6DDC +E4C7 6DDD +E4C1 6DDE +9C4C 6DDF +E4C4 6DE0 +B5AD 6DE1 +9C4D 6DE2 +9C4E 6DE3 +D3D9 6DE4 +9C4F 6DE5 +E4C6 6DE6 +9C50 6DE7 +9C51 6DE8 +9C52 6DE9 +9C53 6DEA +D2F9 6DEB +B4E3 6DEC +9C54 6DED +BBB4 6DEE +9C55 6DEF +9C56 6DF0 +C9EE 6DF1 +9C57 6DF2 +B4BE 6DF3 +9C58 6DF4 +9C59 6DF5 +9C5A 6DF6 +BBEC 6DF7 +9C5B 6DF8 +D1CD 6DF9 +9C5C 6DFA +CCED 6DFB +EDB5 6DFC +9C5D 6DFD +9C5E 6DFE +9C5F 6DFF +9C60 6E00 +9C61 6E01 +9C62 6E02 +9C63 6E03 +9C64 6E04 +C7E5 6E05 +9C65 6E06 +9C66 6E07 +9C67 6E08 +9C68 6E09 +D4A8 6E0A +9C69 6E0B +E4CB 6E0C +D7D5 6E0D +E4C2 6E0E +9C6A 6E0F +BDA5 6E10 +E4C5 6E11 +9C6B 6E12 +9C6C 6E13 +D3E6 6E14 +9C6D 6E15 +E4C9 6E16 +C9F8 6E17 +9C6E 6E18 +9C6F 6E19 +E4BE 6E1A +9C70 6E1B +9C71 6E1C +D3E5 6E1D +9C72 6E1E +9C73 6E1F +C7FE 6E20 +B6C9 6E21 +9C74 6E22 +D4FC 6E23 +B2B3 6E24 +E4D7 6E25 +9C75 6E26 +9C76 6E27 +9C77 6E28 +CEC2 6E29 +9C78 6E2A +E4CD 6E2B +9C79 6E2C +CEBC 6E2D +9C7A 6E2E +B8DB 6E2F +9C7B 6E30 +9C7C 6E31 +E4D6 6E32 +9C7D 6E33 +BFCA 6E34 +9C7E 6E35 +9C80 6E36 +9C81 6E37 +D3CE 6E38 +9C82 6E39 +C3EC 6E3A +9C83 6E3B +9C84 6E3C +9C85 6E3D +9C86 6E3E +9C87 6E3F +9C88 6E40 +9C89 6E41 +9C8A 6E42 +C5C8 6E43 +E4D8 6E44 +9C8B 6E45 +9C8C 6E46 +9C8D 6E47 +9C8E 6E48 +9C8F 6E49 +9C90 6E4A +9C91 6E4B +9C92 6E4C +CDC4 6E4D +E4CF 6E4E +9C93 6E4F +9C94 6E50 +9C95 6E51 +9C96 6E52 +E4D4 6E53 +E4D5 6E54 +9C97 6E55 +BAFE 6E56 +9C98 6E57 +CFE6 6E58 +9C99 6E59 +9C9A 6E5A +D5BF 6E5B +9C9B 6E5C +9C9C 6E5D +9C9D 6E5E +E4D2 6E5F +9C9E 6E60 +9C9F 6E61 +9CA0 6E62 +9CA1 6E63 +9CA2 6E64 +9CA3 6E65 +9CA4 6E66 +9CA5 6E67 +9CA6 6E68 +9CA7 6E69 +9CA8 6E6A +E4D0 6E6B +9CA9 6E6C +9CAA 6E6D +E4CE 6E6E +9CAB 6E6F +9CAC 6E70 +9CAD 6E71 +9CAE 6E72 +9CAF 6E73 +9CB0 6E74 +9CB1 6E75 +9CB2 6E76 +9CB3 6E77 +9CB4 6E78 +9CB5 6E79 +9CB6 6E7A +9CB7 6E7B +9CB8 6E7C +9CB9 6E7D +CDE5 6E7E +CAAA 6E7F +9CBA 6E80 +9CBB 6E81 +9CBC 6E82 +C0A3 6E83 +9CBD 6E84 +BDA6 6E85 +E4D3 6E86 +9CBE 6E87 +9CBF 6E88 +B8C8 6E89 +9CC0 6E8A +9CC1 6E8B +9CC2 6E8C +9CC3 6E8D +9CC4 6E8E +E4E7 6E8F +D4B4 6E90 +9CC5 6E91 +9CC6 6E92 +9CC7 6E93 +9CC8 6E94 +9CC9 6E95 +9CCA 6E96 +9CCB 6E97 +E4DB 6E98 +9CCC 6E99 +9CCD 6E9A +9CCE 6E9B +C1EF 6E9C +9CCF 6E9D +9CD0 6E9E +E4E9 6E9F +9CD1 6EA0 +9CD2 6EA1 +D2E7 6EA2 +9CD3 6EA3 +9CD4 6EA4 +E4DF 6EA5 +9CD5 6EA6 +E4E0 6EA7 +9CD6 6EA8 +9CD7 6EA9 +CFAA 6EAA +9CD8 6EAB +9CD9 6EAC +9CDA 6EAD +9CDB 6EAE +CBDD 6EAF +9CDC 6EB0 +E4DA 6EB1 +E4D1 6EB2 +9CDD 6EB3 +E4E5 6EB4 +9CDE 6EB5 +C8DC 6EB6 +E4E3 6EB7 +9CDF 6EB8 +9CE0 6EB9 +C4E7 6EBA +E4E2 6EBB +9CE1 6EBC +E4E1 6EBD +9CE2 6EBE +9CE3 6EBF +9CE4 6EC0 +B3FC 6EC1 +E4E8 6EC2 +9CE5 6EC3 +9CE6 6EC4 +9CE7 6EC5 +9CE8 6EC6 +B5E1 6EC7 +9CE9 6EC8 +9CEA 6EC9 +9CEB 6ECA +D7CC 6ECB +9CEC 6ECC +9CED 6ECD +9CEE 6ECE +E4E6 6ECF +9CEF 6ED0 +BBAC 6ED1 +9CF0 6ED2 +D7D2 6ED3 +CCCF 6ED4 +EBF8 6ED5 +9CF1 6ED6 +E4E4 6ED7 +9CF2 6ED8 +9CF3 6ED9 +B9F6 6EDA +9CF4 6EDB +9CF5 6EDC +9CF6 6EDD +D6CD 6EDE +E4D9 6EDF +E4DC 6EE0 +C2FA 6EE1 +E4DE 6EE2 +9CF7 6EE3 +C2CB 6EE4 +C0C4 6EE5 +C2D0 6EE6 +9CF8 6EE7 +B1F5 6EE8 +CCB2 6EE9 +9CF9 6EEA +9CFA 6EEB +9CFB 6EEC +9CFC 6EED +9CFD 6EEE +9CFE 6EEF +9D40 6EF0 +9D41 6EF1 +9D42 6EF2 +9D43 6EF3 +B5CE 6EF4 +9D44 6EF5 +9D45 6EF6 +9D46 6EF7 +9D47 6EF8 +E4EF 6EF9 +9D48 6EFA +9D49 6EFB +9D4A 6EFC +9D4B 6EFD +9D4C 6EFE +9D4D 6EFF +9D4E 6F00 +9D4F 6F01 +C6AF 6F02 +9D50 6F03 +9D51 6F04 +9D52 6F05 +C6E1 6F06 +9D53 6F07 +9D54 6F08 +E4F5 6F09 +9D55 6F0A +9D56 6F0B +9D57 6F0C +9D58 6F0D +9D59 6F0E +C2A9 6F0F +9D5A 6F10 +9D5B 6F11 +9D5C 6F12 +C0EC 6F13 +D1DD 6F14 +E4EE 6F15 +9D5D 6F16 +9D5E 6F17 +9D5F 6F18 +9D60 6F19 +9D61 6F1A +9D62 6F1B +9D63 6F1C +9D64 6F1D +9D65 6F1E +9D66 6F1F +C4AE 6F20 +9D67 6F21 +9D68 6F22 +9D69 6F23 +E4ED 6F24 +9D6A 6F25 +9D6B 6F26 +9D6C 6F27 +9D6D 6F28 +E4F6 6F29 +E4F4 6F2A +C2FE 6F2B +9D6E 6F2C +E4DD 6F2D +9D6F 6F2E +E4F0 6F2F +9D70 6F30 +CAFE 6F31 +9D71 6F32 +D5C4 6F33 +9D72 6F34 +9D73 6F35 +E4F1 6F36 +9D74 6F37 +9D75 6F38 +9D76 6F39 +9D77 6F3A +9D78 6F3B +9D79 6F3C +9D7A 6F3D +D1FA 6F3E +9D7B 6F3F +9D7C 6F40 +9D7D 6F41 +9D7E 6F42 +9D80 6F43 +9D81 6F44 +9D82 6F45 +E4EB 6F46 +E4EC 6F47 +9D83 6F48 +9D84 6F49 +9D85 6F4A +E4F2 6F4B +9D86 6F4C +CEAB 6F4D +9D87 6F4E +9D88 6F4F +9D89 6F50 +9D8A 6F51 +9D8B 6F52 +9D8C 6F53 +9D8D 6F54 +9D8E 6F55 +9D8F 6F56 +9D90 6F57 +C5CB 6F58 +9D91 6F59 +9D92 6F5A +9D93 6F5B +C7B1 6F5C +9D94 6F5D +C2BA 6F5E +9D95 6F5F +9D96 6F60 +9D97 6F61 +E4EA 6F62 +9D98 6F63 +9D99 6F64 +9D9A 6F65 +C1CA 6F66 +9D9B 6F67 +9D9C 6F68 +9D9D 6F69 +9D9E 6F6A +9D9F 6F6B +9DA0 6F6C +CCB6 6F6D +B3B1 6F6E +9DA1 6F6F +9DA2 6F70 +9DA3 6F71 +E4FB 6F72 +9DA4 6F73 +E4F3 6F74 +9DA5 6F75 +9DA6 6F76 +9DA7 6F77 +E4FA 6F78 +9DA8 6F79 +E4FD 6F7A +9DA9 6F7B +E4FC 6F7C +9DAA 6F7D +9DAB 6F7E +9DAC 6F7F +9DAD 6F80 +9DAE 6F81 +9DAF 6F82 +9DB0 6F83 +B3CE 6F84 +9DB1 6F85 +9DB2 6F86 +9DB3 6F87 +B3BA 6F88 +E4F7 6F89 +9DB4 6F8A +9DB5 6F8B +E4F9 6F8C +E4F8 6F8D +C5EC 6F8E +9DB6 6F8F +9DB7 6F90 +9DB8 6F91 +9DB9 6F92 +9DBA 6F93 +9DBB 6F94 +9DBC 6F95 +9DBD 6F96 +9DBE 6F97 +9DBF 6F98 +9DC0 6F99 +9DC1 6F9A +9DC2 6F9B +C0BD 6F9C +9DC3 6F9D +9DC4 6F9E +9DC5 6F9F +9DC6 6FA0 +D4E8 6FA1 +9DC7 6FA2 +9DC8 6FA3 +9DC9 6FA4 +9DCA 6FA5 +9DCB 6FA6 +E5A2 6FA7 +9DCC 6FA8 +9DCD 6FA9 +9DCE 6FAA +9DCF 6FAB +9DD0 6FAC +9DD1 6FAD +9DD2 6FAE +9DD3 6FAF +9DD4 6FB0 +9DD5 6FB1 +9DD6 6FB2 +B0C4 6FB3 +9DD7 6FB4 +9DD8 6FB5 +E5A4 6FB6 +9DD9 6FB7 +9DDA 6FB8 +E5A3 6FB9 +9DDB 6FBA +9DDC 6FBB +9DDD 6FBC +9DDE 6FBD +9DDF 6FBE +9DE0 6FBF +BCA4 6FC0 +9DE1 6FC1 +E5A5 6FC2 +9DE2 6FC3 +9DE3 6FC4 +9DE4 6FC5 +9DE5 6FC6 +9DE6 6FC7 +9DE7 6FC8 +E5A1 6FC9 +9DE8 6FCA +9DE9 6FCB +9DEA 6FCC +9DEB 6FCD +9DEC 6FCE +9DED 6FCF +9DEE 6FD0 +E4FE 6FD1 +B1F4 6FD2 +9DEF 6FD3 +9DF0 6FD4 +9DF1 6FD5 +9DF2 6FD6 +9DF3 6FD7 +9DF4 6FD8 +9DF5 6FD9 +9DF6 6FDA +9DF7 6FDB +9DF8 6FDC +9DF9 6FDD +E5A8 6FDE +9DFA 6FDF +E5A9 6FE0 +E5A6 6FE1 +9DFB 6FE2 +9DFC 6FE3 +9DFD 6FE4 +9DFE 6FE5 +9E40 6FE6 +9E41 6FE7 +9E42 6FE8 +9E43 6FE9 +9E44 6FEA +9E45 6FEB +9E46 6FEC +9E47 6FED +E5A7 6FEE +E5AA 6FEF +9E48 6FF0 +9E49 6FF1 +9E4A 6FF2 +9E4B 6FF3 +9E4C 6FF4 +9E4D 6FF5 +9E4E 6FF6 +9E4F 6FF7 +9E50 6FF8 +9E51 6FF9 +9E52 6FFA +9E53 6FFB +9E54 6FFC +9E55 6FFD +9E56 6FFE +9E57 6FFF +9E58 7000 +9E59 7001 +9E5A 7002 +9E5B 7003 +9E5C 7004 +9E5D 7005 +9E5E 7006 +9E5F 7007 +9E60 7008 +9E61 7009 +9E62 700A +9E63 700B +9E64 700C +9E65 700D +9E66 700E +9E67 700F +9E68 7010 +C6D9 7011 +9E69 7012 +9E6A 7013 +9E6B 7014 +9E6C 7015 +9E6D 7016 +9E6E 7017 +9E6F 7018 +9E70 7019 +E5AB 701A +E5AD 701B +9E71 701C +9E72 701D +9E73 701E +9E74 701F +9E75 7020 +9E76 7021 +9E77 7022 +E5AC 7023 +9E78 7024 +9E79 7025 +9E7A 7026 +9E7B 7027 +9E7C 7028 +9E7D 7029 +9E7E 702A +9E80 702B +9E81 702C +9E82 702D +9E83 702E +9E84 702F +9E85 7030 +9E86 7031 +9E87 7032 +9E88 7033 +9E89 7034 +E5AF 7035 +9E8A 7036 +9E8B 7037 +9E8C 7038 +E5AE 7039 +9E8D 703A +9E8E 703B +9E8F 703C +9E90 703D +9E91 703E +9E92 703F +9E93 7040 +9E94 7041 +9E95 7042 +9E96 7043 +9E97 7044 +9E98 7045 +9E99 7046 +9E9A 7047 +9E9B 7048 +9E9C 7049 +9E9D 704A +9E9E 704B +B9E0 704C +9E9F 704D +9EA0 704E +E5B0 704F +9EA1 7050 +9EA2 7051 +9EA3 7052 +9EA4 7053 +9EA5 7054 +9EA6 7055 +9EA7 7056 +9EA8 7057 +9EA9 7058 +9EAA 7059 +9EAB 705A +9EAC 705B +9EAD 705C +9EAE 705D +E5B1 705E +9EAF 705F +9EB0 7060 +9EB1 7061 +9EB2 7062 +9EB3 7063 +9EB4 7064 +9EB5 7065 +9EB6 7066 +9EB7 7067 +9EB8 7068 +9EB9 7069 +9EBA 706A +BBF0 706B +ECE1 706C +C3F0 706D +9EBB 706E +B5C6 706F +BBD2 7070 +9EBC 7071 +9EBD 7072 +9EBE 7073 +9EBF 7074 +C1E9 7075 +D4EE 7076 +9EC0 7077 +BEC4 7078 +9EC1 7079 +9EC2 707A +9EC3 707B +D7C6 707C +9EC4 707D +D4D6 707E +B2D3 707F +ECBE 7080 +9EC5 7081 +9EC6 7082 +9EC7 7083 +9EC8 7084 +EAC1 7085 +9EC9 7086 +9ECA 7087 +9ECB 7088 +C2AF 7089 +B4B6 708A +9ECC 708B +9ECD 708C +9ECE 708D +D1D7 708E +9ECF 708F +9ED0 7090 +9ED1 7091 +B3B4 7092 +9ED2 7093 +C8B2 7094 +BFBB 7095 +ECC0 7096 +9ED3 7097 +9ED4 7098 +D6CB 7099 +9ED5 709A +9ED6 709B +ECBF 709C +ECC1 709D +9ED7 709E +9ED8 709F +9ED9 70A0 +9EDA 70A1 +9EDB 70A2 +9EDC 70A3 +9EDD 70A4 +9EDE 70A5 +9EDF 70A6 +9EE0 70A7 +9EE1 70A8 +9EE2 70A9 +9EE3 70AA +ECC5 70AB +BEE6 70AC +CCBF 70AD +C5DA 70AE +BEBC 70AF +9EE4 70B0 +ECC6 70B1 +9EE5 70B2 +B1FE 70B3 +9EE6 70B4 +9EE7 70B5 +9EE8 70B6 +ECC4 70B7 +D5A8 70B8 +B5E3 70B9 +9EE9 70BA +ECC2 70BB +C1B6 70BC +B3E3 70BD +9EEA 70BE +9EEB 70BF +ECC3 70C0 +CBB8 70C1 +C0C3 70C2 +CCFE 70C3 +9EEC 70C4 +9EED 70C5 +9EEE 70C6 +9EEF 70C7 +C1D2 70C8 +9EF0 70C9 +ECC8 70CA +9EF1 70CB +9EF2 70CC +9EF3 70CD +9EF4 70CE +9EF5 70CF +9EF6 70D0 +9EF7 70D1 +9EF8 70D2 +9EF9 70D3 +9EFA 70D4 +9EFB 70D5 +9EFC 70D6 +9EFD 70D7 +BAE6 70D8 +C0D3 70D9 +9EFE 70DA +D6F2 70DB +9F40 70DC +9F41 70DD +9F42 70DE +D1CC 70DF +9F43 70E0 +9F44 70E1 +9F45 70E2 +9F46 70E3 +BFBE 70E4 +9F47 70E5 +B7B3 70E6 +C9D5 70E7 +ECC7 70E8 +BBE2 70E9 +9F48 70EA +CCCC 70EB +BDFD 70EC +C8C8 70ED +9F49 70EE +CFA9 70EF +9F4A 70F0 +9F4B 70F1 +9F4C 70F2 +9F4D 70F3 +9F4E 70F4 +9F4F 70F5 +9F50 70F6 +CDE9 70F7 +9F51 70F8 +C5EB 70F9 +9F52 70FA +9F53 70FB +9F54 70FC +B7E9 70FD +9F55 70FE +9F56 70FF +9F57 7100 +9F58 7101 +9F59 7102 +9F5A 7103 +9F5B 7104 +9F5C 7105 +9F5D 7106 +9F5E 7107 +9F5F 7108 +D1C9 7109 +BAB8 710A +9F60 710B +9F61 710C +9F62 710D +9F63 710E +9F64 710F +ECC9 7110 +9F65 7111 +9F66 7112 +ECCA 7113 +9F67 7114 +BBC0 7115 +ECCB 7116 +9F68 7117 +ECE2 7118 +B1BA 7119 +B7D9 711A +9F69 711B +9F6A 711C +9F6B 711D +9F6C 711E +9F6D 711F +9F6E 7120 +9F6F 7121 +9F70 7122 +9F71 7123 +9F72 7124 +9F73 7125 +BDB9 7126 +9F74 7127 +9F75 7128 +9F76 7129 +9F77 712A +9F78 712B +9F79 712C +9F7A 712D +9F7B 712E +ECCC 712F +D1E6 7130 +ECCD 7131 +9F7C 7132 +9F7D 7133 +9F7E 7134 +9F80 7135 +C8BB 7136 +9F81 7137 +9F82 7138 +9F83 7139 +9F84 713A +9F85 713B +9F86 713C +9F87 713D +9F88 713E +9F89 713F +9F8A 7140 +9F8B 7141 +9F8C 7142 +9F8D 7143 +9F8E 7144 +ECD1 7145 +9F8F 7146 +9F90 7147 +9F91 7148 +9F92 7149 +ECD3 714A +9F93 714B +BBCD 714C +9F94 714D +BCE5 714E +9F95 714F +9F96 7150 +9F97 7151 +9F98 7152 +9F99 7153 +9F9A 7154 +9F9B 7155 +9F9C 7156 +9F9D 7157 +9F9E 7158 +9F9F 7159 +9FA0 715A +9FA1 715B +ECCF 715C +9FA2 715D +C9B7 715E +9FA3 715F +9FA4 7160 +9FA5 7161 +9FA6 7162 +9FA7 7163 +C3BA 7164 +9FA8 7165 +ECE3 7166 +D5D5 7167 +ECD0 7168 +9FA9 7169 +9FAA 716A +9FAB 716B +9FAC 716C +9FAD 716D +D6F3 716E +9FAE 716F +9FAF 7170 +9FB0 7171 +ECD2 7172 +ECCE 7173 +9FB1 7174 +9FB2 7175 +9FB3 7176 +9FB4 7177 +ECD4 7178 +9FB5 7179 +ECD5 717A +9FB6 717B +9FB7 717C +C9BF 717D +9FB8 717E +9FB9 717F +9FBA 7180 +9FBB 7181 +9FBC 7182 +9FBD 7183 +CFA8 7184 +9FBE 7185 +9FBF 7186 +9FC0 7187 +9FC1 7188 +9FC2 7189 +D0DC 718A +9FC3 718B +9FC4 718C +9FC5 718D +9FC6 718E +D1AC 718F +9FC7 7190 +9FC8 7191 +9FC9 7192 +9FCA 7193 +C8DB 7194 +9FCB 7195 +9FCC 7196 +9FCD 7197 +ECD6 7198 +CEF5 7199 +9FCE 719A +9FCF 719B +9FD0 719C +9FD1 719D +9FD2 719E +CAEC 719F +ECDA 71A0 +9FD3 71A1 +9FD4 71A2 +9FD5 71A3 +9FD6 71A4 +9FD7 71A5 +9FD8 71A6 +9FD9 71A7 +ECD9 71A8 +9FDA 71A9 +9FDB 71AA +9FDC 71AB +B0BE 71AC +9FDD 71AD +9FDE 71AE +9FDF 71AF +9FE0 71B0 +9FE1 71B1 +9FE2 71B2 +ECD7 71B3 +9FE3 71B4 +ECD8 71B5 +9FE4 71B6 +9FE5 71B7 +9FE6 71B8 +ECE4 71B9 +9FE7 71BA +9FE8 71BB +9FE9 71BC +9FEA 71BD +9FEB 71BE +9FEC 71BF +9FED 71C0 +9FEE 71C1 +9FEF 71C2 +C8BC 71C3 +9FF0 71C4 +9FF1 71C5 +9FF2 71C6 +9FF3 71C7 +9FF4 71C8 +9FF5 71C9 +9FF6 71CA +9FF7 71CB +9FF8 71CC +9FF9 71CD +C1C7 71CE +9FFA 71CF +9FFB 71D0 +9FFC 71D1 +9FFD 71D2 +9FFE 71D3 +ECDC 71D4 +D1E0 71D5 +A040 71D6 +A041 71D7 +A042 71D8 +A043 71D9 +A044 71DA +A045 71DB +A046 71DC +A047 71DD +A048 71DE +A049 71DF +ECDB 71E0 +A04A 71E1 +A04B 71E2 +A04C 71E3 +A04D 71E4 +D4EF 71E5 +A04E 71E6 +ECDD 71E7 +A04F 71E8 +A050 71E9 +A051 71EA +A052 71EB +A053 71EC +A054 71ED +DBC6 71EE +A055 71EF +A056 71F0 +A057 71F1 +A058 71F2 +A059 71F3 +A05A 71F4 +A05B 71F5 +A05C 71F6 +A05D 71F7 +A05E 71F8 +ECDE 71F9 +A05F 71FA +A060 71FB +A061 71FC +A062 71FD +A063 71FE +A064 71FF +A065 7200 +A066 7201 +A067 7202 +A068 7203 +A069 7204 +A06A 7205 +B1AC 7206 +A06B 7207 +A06C 7208 +A06D 7209 +A06E 720A +A06F 720B +A070 720C +A071 720D +A072 720E +A073 720F +A074 7210 +A075 7211 +A076 7212 +A077 7213 +A078 7214 +A079 7215 +A07A 7216 +A07B 7217 +A07C 7218 +A07D 7219 +A07E 721A +A080 721B +A081 721C +ECDF 721D +A082 721E +A083 721F +A084 7220 +A085 7221 +A086 7222 +A087 7223 +A088 7224 +A089 7225 +A08A 7226 +A08B 7227 +ECE0 7228 +A08C 7229 +D7A6 722A +A08D 722B +C5C0 722C +A08E 722D +A08F 722E +A090 722F +EBBC 7230 +B0AE 7231 +A091 7232 +A092 7233 +A093 7234 +BEF4 7235 +B8B8 7236 +D2AF 7237 +B0D6 7238 +B5F9 7239 +A094 723A +D8B3 723B +A095 723C +CBAC 723D +A096 723E +E3DD 723F +A097 7240 +A098 7241 +A099 7242 +A09A 7243 +A09B 7244 +A09C 7245 +A09D 7246 +C6AC 7247 +B0E6 7248 +A09E 7249 +A09F 724A +A0A0 724B +C5C6 724C +EBB9 724D +A0A1 724E +A0A2 724F +A0A3 7250 +A0A4 7251 +EBBA 7252 +A0A5 7253 +A0A6 7254 +A0A7 7255 +EBBB 7256 +A0A8 7257 +A0A9 7258 +D1C0 7259 +A0AA 725A +C5A3 725B +A0AB 725C +EAF2 725D +A0AC 725E +C4B2 725F +A0AD 7260 +C4B5 7261 +C0CE 7262 +A0AE 7263 +A0AF 7264 +A0B0 7265 +EAF3 7266 +C4C1 7267 +A0B1 7268 +CEEF 7269 +A0B2 726A +A0B3 726B +A0B4 726C +A0B5 726D +EAF0 726E +EAF4 726F +A0B6 7270 +A0B7 7271 +C9FC 7272 +A0B8 7273 +A0B9 7274 +C7A3 7275 +A0BA 7276 +A0BB 7277 +A0BC 7278 +CCD8 7279 +CEFE 727A +A0BD 727B +A0BE 727C +A0BF 727D +EAF5 727E +EAF6 727F +CFAC 7280 +C0E7 7281 +A0C0 7282 +A0C1 7283 +EAF7 7284 +A0C2 7285 +A0C3 7286 +A0C4 7287 +A0C5 7288 +A0C6 7289 +B6BF 728A +EAF8 728B +A0C7 728C +EAF9 728D +A0C8 728E +EAFA 728F +A0C9 7290 +A0CA 7291 +EAFB 7292 +A0CB 7293 +A0CC 7294 +A0CD 7295 +A0CE 7296 +A0CF 7297 +A0D0 7298 +A0D1 7299 +A0D2 729A +A0D3 729B +A0D4 729C +A0D5 729D +A0D6 729E +EAF1 729F +A0D7 72A0 +A0D8 72A1 +A0D9 72A2 +A0DA 72A3 +A0DB 72A4 +A0DC 72A5 +A0DD 72A6 +A0DE 72A7 +A0DF 72A8 +A0E0 72A9 +A0E1 72AA +A0E2 72AB +C8AE 72AC +E1EB 72AD +A0E3 72AE +B7B8 72AF +E1EC 72B0 +A0E4 72B1 +A0E5 72B2 +A0E6 72B3 +E1ED 72B4 +A0E7 72B5 +D7B4 72B6 +E1EE 72B7 +E1EF 72B8 +D3CC 72B9 +A0E8 72BA +A0E9 72BB +A0EA 72BC +A0EB 72BD +A0EC 72BE +A0ED 72BF +A0EE 72C0 +E1F1 72C1 +BFF1 72C2 +E1F0 72C3 +B5D2 72C4 +A0EF 72C5 +A0F0 72C6 +A0F1 72C7 +B1B7 72C8 +A0F2 72C9 +A0F3 72CA +A0F4 72CB +A0F5 72CC +E1F3 72CD +E1F2 72CE +A0F6 72CF +BAFC 72D0 +A0F7 72D1 +E1F4 72D2 +A0F8 72D3 +A0F9 72D4 +A0FA 72D5 +A0FB 72D6 +B9B7 72D7 +A0FC 72D8 +BED1 72D9 +A0FD 72DA +A0FE 72DB +AA40 72DC +AA41 72DD +C4FC 72DE +AA42 72DF +BADD 72E0 +BDC6 72E1 +AA43 72E2 +AA44 72E3 +AA45 72E4 +AA46 72E5 +AA47 72E6 +AA48 72E7 +E1F5 72E8 +E1F7 72E9 +AA49 72EA +AA4A 72EB +B6C0 72EC +CFC1 72ED +CAA8 72EE +E1F6 72EF +D5F8 72F0 +D3FC 72F1 +E1F8 72F2 +E1FC 72F3 +E1F9 72F4 +AA4B 72F5 +AA4C 72F6 +E1FA 72F7 +C0EA 72F8 +AA4D 72F9 +E1FE 72FA +E2A1 72FB +C0C7 72FC +AA4E 72FD +AA4F 72FE +AA50 72FF +AA51 7300 +E1FB 7301 +AA52 7302 +E1FD 7303 +AA53 7304 +AA54 7305 +AA55 7306 +AA56 7307 +AA57 7308 +AA58 7309 +E2A5 730A +AA59 730B +AA5A 730C +AA5B 730D +C1D4 730E +AA5C 730F +AA5D 7310 +AA5E 7311 +AA5F 7312 +E2A3 7313 +AA60 7314 +E2A8 7315 +B2FE 7316 +E2A2 7317 +AA61 7318 +AA62 7319 +AA63 731A +C3CD 731B +B2C2 731C +E2A7 731D +E2A6 731E +AA64 731F +AA65 7320 +E2A4 7321 +E2A9 7322 +AA66 7323 +AA67 7324 +E2AB 7325 +AA68 7326 +AA69 7327 +AA6A 7328 +D0C9 7329 +D6ED 732A +C3A8 732B +E2AC 732C +AA6B 732D +CFD7 732E +AA6C 732F +AA6D 7330 +E2AE 7331 +AA6E 7332 +AA6F 7333 +BAEF 7334 +AA70 7335 +AA71 7336 +E9E0 7337 +E2AD 7338 +E2AA 7339 +AA72 733A +AA73 733B +AA74 733C +AA75 733D +BBAB 733E +D4B3 733F +AA76 7340 +AA77 7341 +AA78 7342 +AA79 7343 +AA7A 7344 +AA7B 7345 +AA7C 7346 +AA7D 7347 +AA7E 7348 +AA80 7349 +AA81 734A +AA82 734B +AA83 734C +E2B0 734D +AA84 734E +AA85 734F +E2AF 7350 +AA86 7351 +E9E1 7352 +AA87 7353 +AA88 7354 +AA89 7355 +AA8A 7356 +E2B1 7357 +AA8B 7358 +AA8C 7359 +AA8D 735A +AA8E 735B +AA8F 735C +AA90 735D +AA91 735E +AA92 735F +E2B2 7360 +AA93 7361 +AA94 7362 +AA95 7363 +AA96 7364 +AA97 7365 +AA98 7366 +AA99 7367 +AA9A 7368 +AA9B 7369 +AA9C 736A +AA9D 736B +E2B3 736C +CCA1 736D +AA9E 736E +E2B4 736F +AA9F 7370 +AAA0 7371 +AB40 7372 +AB41 7373 +AB42 7374 +AB43 7375 +AB44 7376 +AB45 7377 +AB46 7378 +AB47 7379 +AB48 737A +AB49 737B +AB4A 737C +AB4B 737D +E2B5 737E +AB4C 737F +AB4D 7380 +AB4E 7381 +AB4F 7382 +AB50 7383 +D0FE 7384 +AB51 7385 +AB52 7386 +C2CA 7387 +AB53 7388 +D3F1 7389 +AB54 738A +CDF5 738B +AB55 738C +AB56 738D +E7E0 738E +AB57 738F +AB58 7390 +E7E1 7391 +AB59 7392 +AB5A 7393 +AB5B 7394 +AB5C 7395 +BEC1 7396 +AB5D 7397 +AB5E 7398 +AB5F 7399 +AB60 739A +C2EA 739B +AB61 739C +AB62 739D +AB63 739E +E7E4 739F +AB64 73A0 +AB65 73A1 +E7E3 73A2 +AB66 73A3 +AB67 73A4 +AB68 73A5 +AB69 73A6 +AB6A 73A7 +AB6B 73A8 +CDE6 73A9 +AB6C 73AA +C3B5 73AB +AB6D 73AC +AB6E 73AD +E7E2 73AE +BBB7 73AF +CFD6 73B0 +AB6F 73B1 +C1E1 73B2 +E7E9 73B3 +AB70 73B4 +AB71 73B5 +AB72 73B6 +E7E8 73B7 +AB73 73B8 +AB74 73B9 +E7F4 73BA +B2A3 73BB +AB75 73BC +AB76 73BD +AB77 73BE +AB78 73BF +E7EA 73C0 +AB79 73C1 +E7E6 73C2 +AB7A 73C3 +AB7B 73C4 +AB7C 73C5 +AB7D 73C6 +AB7E 73C7 +E7EC 73C8 +E7EB 73C9 +C9BA 73CA +AB80 73CB +AB81 73CC +D5E4 73CD +AB82 73CE +E7E5 73CF +B7A9 73D0 +E7E7 73D1 +AB83 73D2 +AB84 73D3 +AB85 73D4 +AB86 73D5 +AB87 73D6 +AB88 73D7 +AB89 73D8 +E7EE 73D9 +AB8A 73DA +AB8B 73DB +AB8C 73DC +AB8D 73DD +E7F3 73DE +AB8E 73DF +D6E9 73E0 +AB8F 73E1 +AB90 73E2 +AB91 73E3 +AB92 73E4 +E7ED 73E5 +AB93 73E6 +E7F2 73E7 +AB94 73E8 +E7F1 73E9 +AB95 73EA +AB96 73EB +AB97 73EC +B0E0 73ED +AB98 73EE +AB99 73EF +AB9A 73F0 +AB9B 73F1 +E7F5 73F2 +AB9C 73F3 +AB9D 73F4 +AB9E 73F5 +AB9F 73F6 +ABA0 73F7 +AC40 73F8 +AC41 73F9 +AC42 73FA +AC43 73FB +AC44 73FC +AC45 73FD +AC46 73FE +AC47 73FF +AC48 7400 +AC49 7401 +AC4A 7402 +C7F2 7403 +AC4B 7404 +C0C5 7405 +C0ED 7406 +AC4C 7407 +AC4D 7408 +C1F0 7409 +E7F0 740A +AC4E 740B +AC4F 740C +AC50 740D +AC51 740E +E7F6 740F +CBF6 7410 +AC52 7411 +AC53 7412 +AC54 7413 +AC55 7414 +AC56 7415 +AC57 7416 +AC58 7417 +AC59 7418 +AC5A 7419 +E8A2 741A +E8A1 741B +AC5B 741C +AC5C 741D +AC5D 741E +AC5E 741F +AC5F 7420 +AC60 7421 +D7C1 7422 +AC61 7423 +AC62 7424 +E7FA 7425 +E7F9 7426 +AC63 7427 +E7FB 7428 +AC64 7429 +E7F7 742A +AC65 742B +E7FE 742C +AC66 742D +E7FD 742E +AC67 742F +E7FC 7430 +AC68 7431 +AC69 7432 +C1D5 7433 +C7D9 7434 +C5FD 7435 +C5C3 7436 +AC6A 7437 +AC6B 7438 +AC6C 7439 +AC6D 743A +AC6E 743B +C7ED 743C +AC6F 743D +AC70 743E +AC71 743F +AC72 7440 +E8A3 7441 +AC73 7442 +AC74 7443 +AC75 7444 +AC76 7445 +AC77 7446 +AC78 7447 +AC79 7448 +AC7A 7449 +AC7B 744A +AC7C 744B +AC7D 744C +AC7E 744D +AC80 744E +AC81 744F +AC82 7450 +AC83 7451 +AC84 7452 +AC85 7453 +AC86 7454 +E8A6 7455 +AC87 7456 +E8A5 7457 +AC88 7458 +E8A7 7459 +BAF7 745A +E7F8 745B +E8A4 745C +AC89 745D +C8F0 745E +C9AA 745F +AC8A 7460 +AC8B 7461 +AC8C 7462 +AC8D 7463 +AC8E 7464 +AC8F 7465 +AC90 7466 +AC91 7467 +AC92 7468 +AC93 7469 +AC94 746A +AC95 746B +AC96 746C +E8A9 746D +AC97 746E +AC98 746F +B9E5 7470 +AC99 7471 +AC9A 7472 +AC9B 7473 +AC9C 7474 +AC9D 7475 +D1FE 7476 +E8A8 7477 +AC9E 7478 +AC9F 7479 +ACA0 747A +AD40 747B +AD41 747C +AD42 747D +E8AA 747E +AD43 747F +E8AD 7480 +E8AE 7481 +AD44 7482 +C1A7 7483 +AD45 7484 +AD46 7485 +AD47 7486 +E8AF 7487 +AD48 7488 +AD49 7489 +AD4A 748A +E8B0 748B +AD4B 748C +AD4C 748D +E8AC 748E +AD4D 748F +E8B4 7490 +AD4E 7491 +AD4F 7492 +AD50 7493 +AD51 7494 +AD52 7495 +AD53 7496 +AD54 7497 +AD55 7498 +AD56 7499 +AD57 749A +AD58 749B +E8AB 749C +AD59 749D +E8B1 749E +AD5A 749F +AD5B 74A0 +AD5C 74A1 +AD5D 74A2 +AD5E 74A3 +AD5F 74A4 +AD60 74A5 +AD61 74A6 +E8B5 74A7 +E8B2 74A8 +E8B3 74A9 +AD62 74AA +AD63 74AB +AD64 74AC +AD65 74AD +AD66 74AE +AD67 74AF +AD68 74B0 +AD69 74B1 +AD6A 74B2 +AD6B 74B3 +AD6C 74B4 +AD6D 74B5 +AD6E 74B6 +AD6F 74B7 +AD70 74B8 +AD71 74B9 +E8B7 74BA +AD72 74BB +AD73 74BC +AD74 74BD +AD75 74BE +AD76 74BF +AD77 74C0 +AD78 74C1 +AD79 74C2 +AD7A 74C3 +AD7B 74C4 +AD7C 74C5 +AD7D 74C6 +AD7E 74C7 +AD80 74C8 +AD81 74C9 +AD82 74CA +AD83 74CB +AD84 74CC +AD85 74CD +AD86 74CE +AD87 74CF +AD88 74D0 +AD89 74D1 +E8B6 74D2 +AD8A 74D3 +AD8B 74D4 +AD8C 74D5 +AD8D 74D6 +AD8E 74D7 +AD8F 74D8 +AD90 74D9 +AD91 74DA +AD92 74DB +B9CF 74DC +AD93 74DD +F0AC 74DE +AD94 74DF +F0AD 74E0 +AD95 74E1 +C6B0 74E2 +B0EA 74E3 +C8BF 74E4 +AD96 74E5 +CDDF 74E6 +AD97 74E7 +AD98 74E8 +AD99 74E9 +AD9A 74EA +AD9B 74EB +AD9C 74EC +AD9D 74ED +CECD 74EE +EAB1 74EF +AD9E 74F0 +AD9F 74F1 +ADA0 74F2 +AE40 74F3 +EAB2 74F4 +AE41 74F5 +C6BF 74F6 +B4C9 74F7 +AE42 74F8 +AE43 74F9 +AE44 74FA +AE45 74FB +AE46 74FC +AE47 74FD +AE48 74FE +EAB3 74FF +AE49 7500 +AE4A 7501 +AE4B 7502 +AE4C 7503 +D5E7 7504 +AE4D 7505 +AE4E 7506 +AE4F 7507 +AE50 7508 +AE51 7509 +AE52 750A +AE53 750B +AE54 750C +DDF9 750D +AE55 750E +EAB4 750F +AE56 7510 +EAB5 7511 +AE57 7512 +EAB6 7513 +AE58 7514 +AE59 7515 +AE5A 7516 +AE5B 7517 +B8CA 7518 +DFB0 7519 +C9F5 751A +AE5C 751B +CCF0 751C +AE5D 751D +AE5E 751E +C9FA 751F +AE5F 7520 +AE60 7521 +AE61 7522 +AE62 7523 +AE63 7524 +C9FB 7525 +AE64 7526 +AE65 7527 +D3C3 7528 +CBA6 7529 +AE66 752A +B8A6 752B +F0AE 752C +B1C2 752D +AE67 752E +E5B8 752F +CCEF 7530 +D3C9 7531 +BCD7 7532 +C9EA 7533 +AE68 7534 +B5E7 7535 +AE69 7536 +C4D0 7537 +B5E9 7538 +AE6A 7539 +EEAE 753A +BBAD 753B +AE6B 753C +AE6C 753D +E7DE 753E +AE6D 753F +EEAF 7540 +AE6E 7541 +AE6F 7542 +AE70 7543 +AE71 7544 +B3A9 7545 +AE72 7546 +AE73 7547 +EEB2 7548 +AE74 7549 +AE75 754A +EEB1 754B +BDE7 754C +AE76 754D +EEB0 754E +CEB7 754F +AE77 7550 +AE78 7551 +AE79 7552 +AE7A 7553 +C5CF 7554 +AE7B 7555 +AE7C 7556 +AE7D 7557 +AE7E 7558 +C1F4 7559 +DBCE 755A +EEB3 755B +D0F3 755C +AE80 755D +AE81 755E +AE82 755F +AE83 7560 +AE84 7561 +AE85 7562 +AE86 7563 +AE87 7564 +C2D4 7565 +C6E8 7566 +AE88 7567 +AE89 7568 +AE8A 7569 +B7AC 756A +AE8B 756B +AE8C 756C +AE8D 756D +AE8E 756E +AE8F 756F +AE90 7570 +AE91 7571 +EEB4 7572 +AE92 7573 +B3EB 7574 +AE93 7575 +AE94 7576 +AE95 7577 +BBFB 7578 +EEB5 7579 +AE96 757A +AE97 757B +AE98 757C +AE99 757D +AE9A 757E +E7DC 757F +AE9B 7580 +AE9C 7581 +AE9D 7582 +EEB6 7583 +AE9E 7584 +AE9F 7585 +BDAE 7586 +AEA0 7587 +AF40 7588 +AF41 7589 +AF42 758A +F1E2 758B +AF43 758C +AF44 758D +AF45 758E +CAE8 758F +AF46 7590 +D2C9 7591 +F0DA 7592 +AF47 7593 +F0DB 7594 +AF48 7595 +F0DC 7596 +C1C6 7597 +AF49 7598 +B8ED 7599 +BECE 759A +AF4A 759B +AF4B 759C +F0DE 759D +AF4C 759E +C5B1 759F +F0DD 75A0 +D1F1 75A1 +AF4D 75A2 +F0E0 75A3 +B0CC 75A4 +BDEA 75A5 +AF4E 75A6 +AF4F 75A7 +AF50 75A8 +AF51 75A9 +AF52 75AA +D2DF 75AB +F0DF 75AC +AF53 75AD +B4AF 75AE +B7E8 75AF +F0E6 75B0 +F0E5 75B1 +C6A3 75B2 +F0E1 75B3 +F0E2 75B4 +B4C3 75B5 +AF54 75B6 +AF55 75B7 +F0E3 75B8 +D5EE 75B9 +AF56 75BA +AF57 75BB +CCDB 75BC +BED2 75BD +BCB2 75BE +AF58 75BF +AF59 75C0 +AF5A 75C1 +F0E8 75C2 +F0E7 75C3 +F0E4 75C4 +B2A1 75C5 +AF5B 75C6 +D6A2 75C7 +D3B8 75C8 +BEB7 75C9 +C8AC 75CA +AF5C 75CB +AF5D 75CC +F0EA 75CD +AF5E 75CE +AF5F 75CF +AF60 75D0 +AF61 75D1 +D1F7 75D2 +AF62 75D3 +D6CC 75D4 +BADB 75D5 +F0E9 75D6 +AF63 75D7 +B6BB 75D8 +AF64 75D9 +AF65 75DA +CDB4 75DB +AF66 75DC +AF67 75DD +C6A6 75DE +AF68 75DF +AF69 75E0 +AF6A 75E1 +C1A1 75E2 +F0EB 75E3 +F0EE 75E4 +AF6B 75E5 +F0ED 75E6 +F0F0 75E7 +F0EC 75E8 +AF6C 75E9 +BBBE 75EA +F0EF 75EB +AF6D 75EC +AF6E 75ED +AF6F 75EE +AF70 75EF +CCB5 75F0 +F0F2 75F1 +AF71 75F2 +AF72 75F3 +B3D5 75F4 +AF73 75F5 +AF74 75F6 +AF75 75F7 +AF76 75F8 +B1D4 75F9 +AF77 75FA +AF78 75FB +F0F3 75FC +AF79 75FD +AF7A 75FE +F0F4 75FF +F0F6 7600 +B4E1 7601 +AF7B 7602 +F0F1 7603 +AF7C 7604 +F0F7 7605 +AF7D 7606 +AF7E 7607 +AF80 7608 +AF81 7609 +F0FA 760A +AF82 760B +F0F8 760C +AF83 760D +AF84 760E +AF85 760F +F0F5 7610 +AF86 7611 +AF87 7612 +AF88 7613 +AF89 7614 +F0FD 7615 +AF8A 7616 +F0F9 7617 +F0FC 7618 +F0FE 7619 +AF8B 761A +F1A1 761B +AF8C 761C +AF8D 761D +AF8E 761E +CEC1 761F +F1A4 7620 +AF8F 7621 +F1A3 7622 +AF90 7623 +C1F6 7624 +F0FB 7625 +CADD 7626 +AF91 7627 +AF92 7628 +B4F1 7629 +B1F1 762A +CCB1 762B +AF93 762C +F1A6 762D +AF94 762E +AF95 762F +F1A7 7630 +AF96 7631 +AF97 7632 +F1AC 7633 +D5CE 7634 +F1A9 7635 +AF98 7636 +AF99 7637 +C8B3 7638 +AF9A 7639 +AF9B 763A +AF9C 763B +F1A2 763C +AF9D 763D +F1AB 763E +F1A8 763F +F1A5 7640 +AF9E 7641 +AF9F 7642 +F1AA 7643 +AFA0 7644 +B040 7645 +B041 7646 +B042 7647 +B043 7648 +B044 7649 +B045 764A +B046 764B +B0A9 764C +F1AD 764D +B047 764E +B048 764F +B049 7650 +B04A 7651 +B04B 7652 +B04C 7653 +F1AF 7654 +B04D 7655 +F1B1 7656 +B04E 7657 +B04F 7658 +B050 7659 +B051 765A +B052 765B +F1B0 765C +B053 765D +F1AE 765E +B054 765F +B055 7660 +B056 7661 +B057 7662 +D1A2 7663 +B058 7664 +B059 7665 +B05A 7666 +B05B 7667 +B05C 7668 +B05D 7669 +B05E 766A +F1B2 766B +B05F 766C +B060 766D +B061 766E +F1B3 766F +B062 7670 +B063 7671 +B064 7672 +B065 7673 +B066 7674 +B067 7675 +B068 7676 +B069 7677 +B9EF 7678 +B06A 7679 +B06B 767A +B5C7 767B +B06C 767C +B0D7 767D +B0D9 767E +B06D 767F +B06E 7680 +B06F 7681 +D4ED 7682 +B070 7683 +B5C4 7684 +B071 7685 +BDD4 7686 +BBCA 7687 +F0A7 7688 +B072 7689 +B073 768A +B8DE 768B +B074 768C +B075 768D +F0A8 768E +B076 768F +B077 7690 +B0A8 7691 +B078 7692 +F0A9 7693 +B079 7694 +B07A 7695 +CDEE 7696 +B07B 7697 +B07C 7698 +F0AA 7699 +B07D 769A +B07E 769B +B080 769C +B081 769D +B082 769E +B083 769F +B084 76A0 +B085 76A1 +B086 76A2 +B087 76A3 +F0AB 76A4 +B088 76A5 +B089 76A6 +B08A 76A7 +B08B 76A8 +B08C 76A9 +B08D 76AA +B08E 76AB +B08F 76AC +B090 76AD +C6A4 76AE +B091 76AF +B092 76B0 +D6E5 76B1 +F1E4 76B2 +B093 76B3 +F1E5 76B4 +B094 76B5 +B095 76B6 +B096 76B7 +B097 76B8 +B098 76B9 +B099 76BA +B09A 76BB +B09B 76BC +B09C 76BD +B09D 76BE +C3F3 76BF +B09E 76C0 +B09F 76C1 +D3DB 76C2 +B0A0 76C3 +B140 76C4 +D6D1 76C5 +C5E8 76C6 +B141 76C7 +D3AF 76C8 +B142 76C9 +D2E6 76CA +B143 76CB +B144 76CC +EEC1 76CD +B0BB 76CE +D5B5 76CF +D1CE 76D0 +BCE0 76D1 +BAD0 76D2 +B145 76D3 +BFF8 76D4 +B146 76D5 +B8C7 76D6 +B5C1 76D7 +C5CC 76D8 +B147 76D9 +B148 76DA +CAA2 76DB +B149 76DC +B14A 76DD +B14B 76DE +C3CB 76DF +B14C 76E0 +B14D 76E1 +B14E 76E2 +B14F 76E3 +B150 76E4 +EEC2 76E5 +B151 76E6 +B152 76E7 +B153 76E8 +B154 76E9 +B155 76EA +B156 76EB +B157 76EC +B158 76ED +C4BF 76EE +B6A2 76EF +B159 76F0 +EDEC 76F1 +C3A4 76F2 +B15A 76F3 +D6B1 76F4 +B15B 76F5 +B15C 76F6 +B15D 76F7 +CFE0 76F8 +EDEF 76F9 +B15E 76FA +B15F 76FB +C5CE 76FC +B160 76FD +B6DC 76FE +B161 76FF +B162 7700 +CAA1 7701 +B163 7702 +B164 7703 +EDED 7704 +B165 7705 +B166 7706 +EDF0 7707 +EDF1 7708 +C3BC 7709 +B167 770A +BFB4 770B +B168 770C +EDEE 770D +B169 770E +B16A 770F +B16B 7710 +B16C 7711 +B16D 7712 +B16E 7713 +B16F 7714 +B170 7715 +B171 7716 +B172 7717 +B173 7718 +EDF4 7719 +EDF2 771A +B174 771B +B175 771C +B176 771D +B177 771E +D5E6 771F +C3DF 7720 +B178 7721 +EDF3 7722 +B179 7723 +B17A 7724 +B17B 7725 +EDF6 7726 +B17C 7727 +D5A3 7728 +D1A3 7729 +B17D 772A +B17E 772B +B180 772C +EDF5 772D +B181 772E +C3D0 772F +B182 7730 +B183 7731 +B184 7732 +B185 7733 +B186 7734 +EDF7 7735 +BFF4 7736 +BEEC 7737 +EDF8 7738 +B187 7739 +CCF7 773A +B188 773B +D1DB 773C +B189 773D +B18A 773E +B18B 773F +D7C5 7740 +D5F6 7741 +B18C 7742 +EDFC 7743 +B18D 7744 +B18E 7745 +B18F 7746 +EDFB 7747 +B190 7748 +B191 7749 +B192 774A +B193 774B +B194 774C +B195 774D +B196 774E +B197 774F +EDF9 7750 +EDFA 7751 +B198 7752 +B199 7753 +B19A 7754 +B19B 7755 +B19C 7756 +B19D 7757 +B19E 7758 +B19F 7759 +EDFD 775A +BEA6 775B +B1A0 775C +B240 775D +B241 775E +B242 775F +B243 7760 +CBAF 7761 +EEA1 7762 +B6BD 7763 +B244 7764 +EEA2 7765 +C4C0 7766 +B245 7767 +EDFE 7768 +B246 7769 +B247 776A +BDDE 776B +B2C7 776C +B248 776D +B249 776E +B24A 776F +B24B 7770 +B24C 7771 +B24D 7772 +B24E 7773 +B24F 7774 +B250 7775 +B251 7776 +B252 7777 +B253 7778 +B6C3 7779 +B254 777A +B255 777B +B256 777C +EEA5 777D +D8BA 777E +EEA3 777F +EEA6 7780 +B257 7781 +B258 7782 +B259 7783 +C3E9 7784 +B3F2 7785 +B25A 7786 +B25B 7787 +B25C 7788 +B25D 7789 +B25E 778A +B25F 778B +EEA7 778C +EEA4 778D +CFB9 778E +B260 778F +B261 7790 +EEA8 7791 +C2F7 7792 +B262 7793 +B263 7794 +B264 7795 +B265 7796 +B266 7797 +B267 7798 +B268 7799 +B269 779A +B26A 779B +B26B 779C +B26C 779D +B26D 779E +EEA9 779F +EEAA 77A0 +B26E 77A1 +DEAB 77A2 +B26F 77A3 +B270 77A4 +C6B3 77A5 +B271 77A6 +C7C6 77A7 +B272 77A8 +D6F5 77A9 +B5C9 77AA +B273 77AB +CBB2 77AC +B274 77AD +B275 77AE +B276 77AF +EEAB 77B0 +B277 77B1 +B278 77B2 +CDAB 77B3 +B279 77B4 +EEAC 77B5 +B27A 77B6 +B27B 77B7 +B27C 77B8 +B27D 77B9 +B27E 77BA +D5B0 77BB +B280 77BC +EEAD 77BD +B281 77BE +F6C4 77BF +B282 77C0 +B283 77C1 +B284 77C2 +B285 77C3 +B286 77C4 +B287 77C5 +B288 77C6 +B289 77C7 +B28A 77C8 +B28B 77C9 +B28C 77CA +B28D 77CB +B28E 77CC +DBC7 77CD +B28F 77CE +B290 77CF +B291 77D0 +B292 77D1 +B293 77D2 +B294 77D3 +B295 77D4 +B296 77D5 +B297 77D6 +B4A3 77D7 +B298 77D8 +B299 77D9 +B29A 77DA +C3AC 77DB +F1E6 77DC +B29B 77DD +B29C 77DE +B29D 77DF +B29E 77E0 +B29F 77E1 +CAB8 77E2 +D2D3 77E3 +B2A0 77E4 +D6AA 77E5 +B340 77E6 +EFF2 77E7 +B341 77E8 +BED8 77E9 +B342 77EA +BDC3 77EB +EFF3 77EC +B6CC 77ED +B0AB 77EE +B343 77EF +B344 77F0 +B345 77F1 +B346 77F2 +CAAF 77F3 +B347 77F4 +B348 77F5 +EDB6 77F6 +B349 77F7 +EDB7 77F8 +B34A 77F9 +B34B 77FA +B34C 77FB +B34D 77FC +CEF9 77FD +B7AF 77FE +BFF3 77FF +EDB8 7800 +C2EB 7801 +C9B0 7802 +B34E 7803 +B34F 7804 +B350 7805 +B351 7806 +B352 7807 +B353 7808 +EDB9 7809 +B354 780A +B355 780B +C6F6 780C +BFB3 780D +B356 780E +B357 780F +B358 7810 +EDBC 7811 +C5F8 7812 +B359 7813 +D1D0 7814 +B35A 7815 +D7A9 7816 +EDBA 7817 +EDBB 7818 +B35B 7819 +D1E2 781A +B35C 781B +EDBF 781C +EDC0 781D +B35D 781E +EDC4 781F +B35E 7820 +B35F 7821 +B360 7822 +EDC8 7823 +B361 7824 +EDC6 7825 +EDCE 7826 +D5E8 7827 +B362 7828 +EDC9 7829 +B363 782A +B364 782B +EDC7 782C +EDBE 782D +B365 782E +B366 782F +C5E9 7830 +B367 7831 +B368 7832 +B369 7833 +C6C6 7834 +B36A 7835 +B36B 7836 +C9E9 7837 +D4D2 7838 +EDC1 7839 +EDC2 783A +EDC3 783B +EDC5 783C +B36C 783D +C0F9 783E +B36D 783F +B4A1 7840 +B36E 7841 +B36F 7842 +B370 7843 +B371 7844 +B9E8 7845 +B372 7846 +EDD0 7847 +B373 7848 +B374 7849 +B375 784A +B376 784B +EDD1 784C +B377 784D +EDCA 784E +B378 784F +EDCF 7850 +B379 7851 +CEF8 7852 +B37A 7853 +B37B 7854 +CBB6 7855 +EDCC 7856 +EDCD 7857 +B37C 7858 +B37D 7859 +B37E 785A +B380 785B +B381 785C +CFF5 785D +B382 785E +B383 785F +B384 7860 +B385 7861 +B386 7862 +B387 7863 +B388 7864 +B389 7865 +B38A 7866 +B38B 7867 +B38C 7868 +B38D 7869 +EDD2 786A +C1F2 786B +D3B2 786C +EDCB 786D +C8B7 786E +B38E 786F +B38F 7870 +B390 7871 +B391 7872 +B392 7873 +B393 7874 +B394 7875 +B395 7876 +BCEF 7877 +B396 7878 +B397 7879 +B398 787A +B399 787B +C5F0 787C +B39A 787D +B39B 787E +B39C 787F +B39D 7880 +B39E 7881 +B39F 7882 +B3A0 7883 +B440 7884 +B441 7885 +B442 7886 +EDD6 7887 +B443 7888 +B5EF 7889 +B444 788A +B445 788B +C2B5 788C +B0AD 788D +CBE9 788E +B446 788F +B447 7890 +B1AE 7891 +B448 7892 +EDD4 7893 +B449 7894 +B44A 7895 +B44B 7896 +CDEB 7897 +B5E2 7898 +B44C 7899 +EDD5 789A +EDD3 789B +EDD7 789C +B44D 789D +B44E 789E +B5FA 789F +B44F 78A0 +EDD8 78A1 +B450 78A2 +EDD9 78A3 +B451 78A4 +EDDC 78A5 +B452 78A6 +B1CC 78A7 +B453 78A8 +B454 78A9 +B455 78AA +B456 78AB +B457 78AC +B458 78AD +B459 78AE +B45A 78AF +C5F6 78B0 +BCEE 78B1 +EDDA 78B2 +CCBC 78B3 +B2EA 78B4 +B45B 78B5 +B45C 78B6 +B45D 78B7 +B45E 78B8 +EDDB 78B9 +B45F 78BA +B460 78BB +B461 78BC +B462 78BD +C4EB 78BE +B463 78BF +B464 78C0 +B4C5 78C1 +B465 78C2 +B466 78C3 +B467 78C4 +B0F5 78C5 +B468 78C6 +B469 78C7 +B46A 78C8 +EDDF 78C9 +C0DA 78CA +B4E8 78CB +B46B 78CC +B46C 78CD +B46D 78CE +B46E 78CF +C5CD 78D0 +B46F 78D1 +B470 78D2 +B471 78D3 +EDDD 78D4 +BFC4 78D5 +B472 78D6 +B473 78D7 +B474 78D8 +EDDE 78D9 +B475 78DA +B476 78DB +B477 78DC +B478 78DD +B479 78DE +B47A 78DF +B47B 78E0 +B47C 78E1 +B47D 78E2 +B47E 78E3 +B480 78E4 +B481 78E5 +B482 78E6 +B483 78E7 +C4A5 78E8 +B484 78E9 +B485 78EA +B486 78EB +EDE0 78EC +B487 78ED +B488 78EE +B489 78EF +B48A 78F0 +B48B 78F1 +EDE1 78F2 +B48C 78F3 +EDE3 78F4 +B48D 78F5 +B48E 78F6 +C1D7 78F7 +B48F 78F8 +B490 78F9 +BBC7 78FA +B491 78FB +B492 78FC +B493 78FD +B494 78FE +B495 78FF +B496 7900 +BDB8 7901 +B497 7902 +B498 7903 +B499 7904 +EDE2 7905 +B49A 7906 +B49B 7907 +B49C 7908 +B49D 7909 +B49E 790A +B49F 790B +B4A0 790C +B540 790D +B541 790E +B542 790F +B543 7910 +B544 7911 +B545 7912 +EDE4 7913 +B546 7914 +B547 7915 +B548 7916 +B549 7917 +B54A 7918 +B54B 7919 +B54C 791A +B54D 791B +B54E 791C +B54F 791D +EDE6 791E +B550 791F +B551 7920 +B552 7921 +B553 7922 +B554 7923 +EDE5 7924 +B555 7925 +B556 7926 +B557 7927 +B558 7928 +B559 7929 +B55A 792A +B55B 792B +B55C 792C +B55D 792D +B55E 792E +B55F 792F +B560 7930 +B561 7931 +B562 7932 +B563 7933 +EDE7 7934 +B564 7935 +B565 7936 +B566 7937 +B567 7938 +B568 7939 +CABE 793A +ECEA 793B +C0F1 793C +B569 793D +C9E7 793E +B56A 793F +ECEB 7940 +C6EE 7941 +B56B 7942 +B56C 7943 +B56D 7944 +B56E 7945 +ECEC 7946 +B56F 7947 +C6ED 7948 +ECED 7949 +B570 794A +B571 794B +B572 794C +B573 794D +B574 794E +B575 794F +B576 7950 +B577 7951 +B578 7952 +ECF0 7953 +B579 7954 +B57A 7955 +D7E6 7956 +ECF3 7957 +B57B 7958 +B57C 7959 +ECF1 795A +ECEE 795B +ECEF 795C +D7A3 795D +C9F1 795E +CBEE 795F +ECF4 7960 +B57D 7961 +ECF2 7962 +B57E 7963 +B580 7964 +CFE9 7965 +B581 7966 +ECF6 7967 +C6B1 7968 +B582 7969 +B583 796A +B584 796B +B585 796C +BCC0 796D +B586 796E +ECF5 796F +B587 7970 +B588 7971 +B589 7972 +B58A 7973 +B58B 7974 +B58C 7975 +B58D 7976 +B5BB 7977 +BBF6 7978 +B58E 7979 +ECF7 797A +B58F 797B +B590 797C +B591 797D +B592 797E +B593 797F +D9F7 7980 +BDFB 7981 +B594 7982 +B595 7983 +C2BB 7984 +ECF8 7985 +B596 7986 +B597 7987 +B598 7988 +B599 7989 +ECF9 798A +B59A 798B +B59B 798C +B59C 798D +B59D 798E +B8A3 798F +B59E 7990 +B59F 7991 +B5A0 7992 +B640 7993 +B641 7994 +B642 7995 +B643 7996 +B644 7997 +B645 7998 +B646 7999 +ECFA 799A +B647 799B +B648 799C +B649 799D +B64A 799E +B64B 799F +B64C 79A0 +B64D 79A1 +B64E 79A2 +B64F 79A3 +B650 79A4 +B651 79A5 +B652 79A6 +ECFB 79A7 +B653 79A8 +B654 79A9 +B655 79AA +B656 79AB +B657 79AC +B658 79AD +B659 79AE +B65A 79AF +B65B 79B0 +B65C 79B1 +B65D 79B2 +ECFC 79B3 +B65E 79B4 +B65F 79B5 +B660 79B6 +B661 79B7 +B662 79B8 +D3ED 79B9 +D8AE 79BA +C0EB 79BB +B663 79BC +C7DD 79BD +BACC 79BE +B664 79BF +D0E3 79C0 +CBBD 79C1 +B665 79C2 +CDBA 79C3 +B666 79C4 +B667 79C5 +B8D1 79C6 +B668 79C7 +B669 79C8 +B1FC 79C9 +B66A 79CA +C7EF 79CB +B66B 79CC +D6D6 79CD +B66C 79CE +B66D 79CF +B66E 79D0 +BFC6 79D1 +C3EB 79D2 +B66F 79D3 +B670 79D4 +EFF5 79D5 +B671 79D6 +B672 79D7 +C3D8 79D8 +B673 79D9 +B674 79DA +B675 79DB +B676 79DC +B677 79DD +B678 79DE +D7E2 79DF +B679 79E0 +B67A 79E1 +B67B 79E2 +EFF7 79E3 +B3D3 79E4 +B67C 79E5 +C7D8 79E6 +D1ED 79E7 +B67D 79E8 +D6C8 79E9 +B67E 79EA +EFF8 79EB +B680 79EC +EFF6 79ED +B681 79EE +BBFD 79EF +B3C6 79F0 +B682 79F1 +B683 79F2 +B684 79F3 +B685 79F4 +B686 79F5 +B687 79F6 +B688 79F7 +BDD5 79F8 +B689 79F9 +B68A 79FA +D2C6 79FB +B68B 79FC +BBE0 79FD +B68C 79FE +B68D 79FF +CFA1 7A00 +B68E 7A01 +EFFC 7A02 +EFFB 7A03 +B68F 7A04 +B690 7A05 +EFF9 7A06 +B691 7A07 +B692 7A08 +B693 7A09 +B694 7A0A +B3CC 7A0B +B695 7A0C +C9D4 7A0D +CBB0 7A0E +B696 7A0F +B697 7A10 +B698 7A11 +B699 7A12 +B69A 7A13 +EFFE 7A14 +B69B 7A15 +B69C 7A16 +B0DE 7A17 +B69D 7A18 +B69E 7A19 +D6C9 7A1A +B69F 7A1B +B6A0 7A1C +B740 7A1D +EFFD 7A1E +B741 7A1F +B3ED 7A20 +B742 7A21 +B743 7A22 +F6D5 7A23 +B744 7A24 +B745 7A25 +B746 7A26 +B747 7A27 +B748 7A28 +B749 7A29 +B74A 7A2A +B74B 7A2B +B74C 7A2C +B74D 7A2D +B74E 7A2E +B74F 7A2F +B750 7A30 +B751 7A31 +B752 7A32 +CEC8 7A33 +B753 7A34 +B754 7A35 +B755 7A36 +F0A2 7A37 +B756 7A38 +F0A1 7A39 +B757 7A3A +B5BE 7A3B +BCDA 7A3C +BBFC 7A3D +B758 7A3E +B8E5 7A3F +B759 7A40 +B75A 7A41 +B75B 7A42 +B75C 7A43 +B75D 7A44 +B75E 7A45 +C4C2 7A46 +B75F 7A47 +B760 7A48 +B761 7A49 +B762 7A4A +B763 7A4B +B764 7A4C +B765 7A4D +B766 7A4E +B767 7A4F +B768 7A50 +F0A3 7A51 +B769 7A52 +B76A 7A53 +B76B 7A54 +B76C 7A55 +B76D 7A56 +CBEB 7A57 +B76E 7A58 +B76F 7A59 +B770 7A5A +B771 7A5B +B772 7A5C +B773 7A5D +B774 7A5E +B775 7A5F +B776 7A60 +B777 7A61 +B778 7A62 +B779 7A63 +B77A 7A64 +B77B 7A65 +B77C 7A66 +B77D 7A67 +B77E 7A68 +B780 7A69 +B781 7A6A +B782 7A6B +B783 7A6C +B784 7A6D +B785 7A6E +B786 7A6F +F0A6 7A70 +B787 7A71 +B788 7A72 +B789 7A73 +D1A8 7A74 +B78A 7A75 +BEBF 7A76 +C7EE 7A77 +F1B6 7A78 +F1B7 7A79 +BFD5 7A7A +B78B 7A7B +B78C 7A7C +B78D 7A7D +B78E 7A7E +B4A9 7A7F +F1B8 7A80 +CDBB 7A81 +B78F 7A82 +C7D4 7A83 +D5AD 7A84 +B790 7A85 +F1B9 7A86 +B791 7A87 +F1BA 7A88 +B792 7A89 +B793 7A8A +B794 7A8B +B795 7A8C +C7CF 7A8D +B796 7A8E +B797 7A8F +B798 7A90 +D2A4 7A91 +D6CF 7A92 +B799 7A93 +B79A 7A94 +F1BB 7A95 +BDD1 7A96 +B4B0 7A97 +BEBD 7A98 +B79B 7A99 +B79C 7A9A +B79D 7A9B +B4DC 7A9C +CED1 7A9D +B79E 7A9E +BFDF 7A9F +F1BD 7AA0 +B79F 7AA1 +B7A0 7AA2 +B840 7AA3 +B841 7AA4 +BFFA 7AA5 +F1BC 7AA6 +B842 7AA7 +F1BF 7AA8 +B843 7AA9 +B844 7AAA +B845 7AAB +F1BE 7AAC +F1C0 7AAD +B846 7AAE +B847 7AAF +B848 7AB0 +B849 7AB1 +B84A 7AB2 +F1C1 7AB3 +B84B 7AB4 +B84C 7AB5 +B84D 7AB6 +B84E 7AB7 +B84F 7AB8 +B850 7AB9 +B851 7ABA +B852 7ABB +B853 7ABC +B854 7ABD +B855 7ABE +C1FE 7ABF +B856 7AC0 +B857 7AC1 +B858 7AC2 +B859 7AC3 +B85A 7AC4 +B85B 7AC5 +B85C 7AC6 +B85D 7AC7 +B85E 7AC8 +B85F 7AC9 +B860 7ACA +C1A2 7ACB +B861 7ACC +B862 7ACD +B863 7ACE +B864 7ACF +B865 7AD0 +B866 7AD1 +B867 7AD2 +B868 7AD3 +B869 7AD4 +B86A 7AD5 +CAFA 7AD6 +B86B 7AD7 +B86C 7AD8 +D5BE 7AD9 +B86D 7ADA +B86E 7ADB +B86F 7ADC +B870 7ADD +BEBA 7ADE +BEB9 7ADF +D5C2 7AE0 +B871 7AE1 +B872 7AE2 +BFA2 7AE3 +B873 7AE4 +CDAF 7AE5 +F1B5 7AE6 +B874 7AE7 +B875 7AE8 +B876 7AE9 +B877 7AEA +B878 7AEB +B879 7AEC +BDDF 7AED +B87A 7AEE +B6CB 7AEF +B87B 7AF0 +B87C 7AF1 +B87D 7AF2 +B87E 7AF3 +B880 7AF4 +B881 7AF5 +B882 7AF6 +B883 7AF7 +B884 7AF8 +D6F1 7AF9 +F3C3 7AFA +B885 7AFB +B886 7AFC +F3C4 7AFD +B887 7AFE +B8CD 7AFF +B888 7B00 +B889 7B01 +B88A 7B02 +F3C6 7B03 +F3C7 7B04 +B88B 7B05 +B0CA 7B06 +B88C 7B07 +F3C5 7B08 +B88D 7B09 +F3C9 7B0A +CBF1 7B0B +B88E 7B0C +B88F 7B0D +B890 7B0E +F3CB 7B0F +B891 7B10 +D0A6 7B11 +B892 7B12 +B893 7B13 +B1CA 7B14 +F3C8 7B15 +B894 7B16 +B895 7B17 +B896 7B18 +F3CF 7B19 +B897 7B1A +B5D1 7B1B +B898 7B1C +B899 7B1D +F3D7 7B1E +B89A 7B1F +F3D2 7B20 +B89B 7B21 +B89C 7B22 +B89D 7B23 +F3D4 7B24 +F3D3 7B25 +B7FB 7B26 +B89E 7B27 +B1BF 7B28 +B89F 7B29 +F3CE 7B2A +F3CA 7B2B +B5DA 7B2C +B8A0 7B2D +F3D0 7B2E +B940 7B2F +B941 7B30 +F3D1 7B31 +B942 7B32 +F3D5 7B33 +B943 7B34 +B944 7B35 +B945 7B36 +B946 7B37 +F3CD 7B38 +B947 7B39 +BCE3 7B3A +B948 7B3B +C1FD 7B3C +B949 7B3D +F3D6 7B3E +B94A 7B3F +B94B 7B40 +B94C 7B41 +B94D 7B42 +B94E 7B43 +B94F 7B44 +F3DA 7B45 +B950 7B46 +F3CC 7B47 +B951 7B48 +B5C8 7B49 +B952 7B4A +BDEE 7B4B +F3DC 7B4C +B953 7B4D +B954 7B4E +B7A4 7B4F +BFF0 7B50 +D6FE 7B51 +CDB2 7B52 +B955 7B53 +B4F0 7B54 +B956 7B55 +B2DF 7B56 +B957 7B57 +F3D8 7B58 +B958 7B59 +F3D9 7B5A +C9B8 7B5B +B959 7B5C +F3DD 7B5D +B95A 7B5E +B95B 7B5F +F3DE 7B60 +B95C 7B61 +F3E1 7B62 +B95D 7B63 +B95E 7B64 +B95F 7B65 +B960 7B66 +B961 7B67 +B962 7B68 +B963 7B69 +B964 7B6A +B965 7B6B +B966 7B6C +B967 7B6D +F3DF 7B6E +B968 7B6F +B969 7B70 +F3E3 7B71 +F3E2 7B72 +B96A 7B73 +B96B 7B74 +F3DB 7B75 +B96C 7B76 +BFEA 7B77 +B96D 7B78 +B3EF 7B79 +B96E 7B7A +F3E0 7B7B +B96F 7B7C +B970 7B7D +C7A9 7B7E +B971 7B7F +BCF2 7B80 +B972 7B81 +B973 7B82 +B974 7B83 +B975 7B84 +F3EB 7B85 +B976 7B86 +B977 7B87 +B978 7B88 +B979 7B89 +B97A 7B8A +B97B 7B8B +B97C 7B8C +B9BF 7B8D +B97D 7B8E +B97E 7B8F +F3E4 7B90 +B980 7B91 +B981 7B92 +B982 7B93 +B2AD 7B94 +BBFE 7B95 +B983 7B96 +CBE3 7B97 +B984 7B98 +B985 7B99 +B986 7B9A +B987 7B9B +F3ED 7B9C +F3E9 7B9D +B988 7B9E +B989 7B9F +B98A 7BA0 +B9DC 7BA1 +F3EE 7BA2 +B98B 7BA3 +B98C 7BA4 +B98D 7BA5 +F3E5 7BA6 +F3E6 7BA7 +F3EA 7BA8 +C2E1 7BA9 +F3EC 7BAA +F3EF 7BAB +F3E8 7BAC +BCFD 7BAD +B98E 7BAE +B98F 7BAF +B990 7BB0 +CFE4 7BB1 +B991 7BB2 +B992 7BB3 +F3F0 7BB4 +B993 7BB5 +B994 7BB6 +B995 7BB7 +F3E7 7BB8 +B996 7BB9 +B997 7BBA +B998 7BBB +B999 7BBC +B99A 7BBD +B99B 7BBE +B99C 7BBF +B99D 7BC0 +F3F2 7BC1 +B99E 7BC2 +B99F 7BC3 +B9A0 7BC4 +BA40 7BC5 +D7AD 7BC6 +C6AA 7BC7 +BA41 7BC8 +BA42 7BC9 +BA43 7BCA +BA44 7BCB +F3F3 7BCC +BA45 7BCD +BA46 7BCE +BA47 7BCF +BA48 7BD0 +F3F1 7BD1 +BA49 7BD2 +C2A8 7BD3 +BA4A 7BD4 +BA4B 7BD5 +BA4C 7BD6 +BA4D 7BD7 +BA4E 7BD8 +B8DD 7BD9 +F3F5 7BDA +BA4F 7BDB +BA50 7BDC +F3F4 7BDD +BA51 7BDE +BA52 7BDF +BA53 7BE0 +B4DB 7BE1 +BA54 7BE2 +BA55 7BE3 +BA56 7BE4 +F3F6 7BE5 +F3F7 7BE6 +BA57 7BE7 +BA58 7BE8 +BA59 7BE9 +F3F8 7BEA +BA5A 7BEB +BA5B 7BEC +BA5C 7BED +C0BA 7BEE +BA5D 7BEF +BA5E 7BF0 +C0E9 7BF1 +BA5F 7BF2 +BA60 7BF3 +BA61 7BF4 +BA62 7BF5 +BA63 7BF6 +C5F1 7BF7 +BA64 7BF8 +BA65 7BF9 +BA66 7BFA +BA67 7BFB +F3FB 7BFC +BA68 7BFD +F3FA 7BFE +BA69 7BFF +BA6A 7C00 +BA6B 7C01 +BA6C 7C02 +BA6D 7C03 +BA6E 7C04 +BA6F 7C05 +BA70 7C06 +B4D8 7C07 +BA71 7C08 +BA72 7C09 +BA73 7C0A +F3FE 7C0B +F3F9 7C0C +BA74 7C0D +BA75 7C0E +F3FC 7C0F +BA76 7C10 +BA77 7C11 +BA78 7C12 +BA79 7C13 +BA7A 7C14 +BA7B 7C15 +F3FD 7C16 +BA7C 7C17 +BA7D 7C18 +BA7E 7C19 +BA80 7C1A +BA81 7C1B +BA82 7C1C +BA83 7C1D +BA84 7C1E +F4A1 7C1F +BA85 7C20 +BA86 7C21 +BA87 7C22 +BA88 7C23 +BA89 7C24 +BA8A 7C25 +F4A3 7C26 +BBC9 7C27 +BA8B 7C28 +BA8C 7C29 +F4A2 7C2A +BA8D 7C2B +BA8E 7C2C +BA8F 7C2D +BA90 7C2E +BA91 7C2F +BA92 7C30 +BA93 7C31 +BA94 7C32 +BA95 7C33 +BA96 7C34 +BA97 7C35 +BA98 7C36 +BA99 7C37 +F4A4 7C38 +BA9A 7C39 +BA9B 7C3A +BA9C 7C3B +BA9D 7C3C +BA9E 7C3D +BA9F 7C3E +B2BE 7C3F +F4A6 7C40 +F4A5 7C41 +BAA0 7C42 +BB40 7C43 +BB41 7C44 +BB42 7C45 +BB43 7C46 +BB44 7C47 +BB45 7C48 +BB46 7C49 +BB47 7C4A +BB48 7C4B +BB49 7C4C +BCAE 7C4D +BB4A 7C4E +BB4B 7C4F +BB4C 7C50 +BB4D 7C51 +BB4E 7C52 +BB4F 7C53 +BB50 7C54 +BB51 7C55 +BB52 7C56 +BB53 7C57 +BB54 7C58 +BB55 7C59 +BB56 7C5A +BB57 7C5B +BB58 7C5C +BB59 7C5D +BB5A 7C5E +BB5B 7C5F +BB5C 7C60 +BB5D 7C61 +BB5E 7C62 +BB5F 7C63 +BB60 7C64 +BB61 7C65 +BB62 7C66 +BB63 7C67 +BB64 7C68 +BB65 7C69 +BB66 7C6A +BB67 7C6B +BB68 7C6C +BB69 7C6D +BB6A 7C6E +BB6B 7C6F +BB6C 7C70 +BB6D 7C71 +BB6E 7C72 +C3D7 7C73 +D9E1 7C74 +BB6F 7C75 +BB70 7C76 +BB71 7C77 +BB72 7C78 +BB73 7C79 +BB74 7C7A +C0E0 7C7B +F4CC 7C7C +D7D1 7C7D +BB75 7C7E +BB76 7C7F +BB77 7C80 +BB78 7C81 +BB79 7C82 +BB7A 7C83 +BB7B 7C84 +BB7C 7C85 +BB7D 7C86 +BB7E 7C87 +BB80 7C88 +B7DB 7C89 +BB81 7C8A +BB82 7C8B +BB83 7C8C +BB84 7C8D +BB85 7C8E +BB86 7C8F +BB87 7C90 +F4CE 7C91 +C1A3 7C92 +BB88 7C93 +BB89 7C94 +C6C9 7C95 +BB8A 7C96 +B4D6 7C97 +D5B3 7C98 +BB8B 7C99 +BB8C 7C9A +BB8D 7C9B +F4D0 7C9C +F4CF 7C9D +F4D1 7C9E +CBDA 7C9F +BB8E 7CA0 +BB8F 7CA1 +F4D2 7CA2 +BB90 7CA3 +D4C1 7CA4 +D6E0 7CA5 +BB91 7CA6 +BB92 7CA7 +BB93 7CA8 +BB94 7CA9 +B7E0 7CAA +BB95 7CAB +BB96 7CAC +BB97 7CAD +C1B8 7CAE +BB98 7CAF +BB99 7CB0 +C1BB 7CB1 +F4D3 7CB2 +BEAC 7CB3 +BB9A 7CB4 +BB9B 7CB5 +BB9C 7CB6 +BB9D 7CB7 +BB9E 7CB8 +B4E2 7CB9 +BB9F 7CBA +BBA0 7CBB +F4D4 7CBC +F4D5 7CBD +BEAB 7CBE +BC40 7CBF +BC41 7CC0 +F4D6 7CC1 +BC42 7CC2 +BC43 7CC3 +BC44 7CC4 +F4DB 7CC5 +BC45 7CC6 +F4D7 7CC7 +F4DA 7CC8 +BC46 7CC9 +BAFD 7CCA +BC47 7CCB +F4D8 7CCC +F4D9 7CCD +BC48 7CCE +BC49 7CCF +BC4A 7CD0 +BC4B 7CD1 +BC4C 7CD2 +BC4D 7CD3 +BC4E 7CD4 +B8E2 7CD5 +CCC7 7CD6 +F4DC 7CD7 +BC4F 7CD8 +B2DA 7CD9 +BC50 7CDA +BC51 7CDB +C3D3 7CDC +BC52 7CDD +BC53 7CDE +D4E3 7CDF +BFB7 7CE0 +BC54 7CE1 +BC55 7CE2 +BC56 7CE3 +BC57 7CE4 +BC58 7CE5 +BC59 7CE6 +BC5A 7CE7 +F4DD 7CE8 +BC5B 7CE9 +BC5C 7CEA +BC5D 7CEB +BC5E 7CEC +BC5F 7CED +BC60 7CEE +C5B4 7CEF +BC61 7CF0 +BC62 7CF1 +BC63 7CF2 +BC64 7CF3 +BC65 7CF4 +BC66 7CF5 +BC67 7CF6 +BC68 7CF7 +F4E9 7CF8 +BC69 7CF9 +BC6A 7CFA +CFB5 7CFB +BC6B 7CFC +BC6C 7CFD +BC6D 7CFE +BC6E 7CFF +BC6F 7D00 +BC70 7D01 +BC71 7D02 +BC72 7D03 +BC73 7D04 +BC74 7D05 +BC75 7D06 +BC76 7D07 +BC77 7D08 +BC78 7D09 +CEC9 7D0A +BC79 7D0B +BC7A 7D0C +BC7B 7D0D +BC7C 7D0E +BC7D 7D0F +BC7E 7D10 +BC80 7D11 +BC81 7D12 +BC82 7D13 +BC83 7D14 +BC84 7D15 +BC85 7D16 +BC86 7D17 +BC87 7D18 +BC88 7D19 +BC89 7D1A +BC8A 7D1B +BC8B 7D1C +BC8C 7D1D +BC8D 7D1E +BC8E 7D1F +CBD8 7D20 +BC8F 7D21 +CBF7 7D22 +BC90 7D23 +BC91 7D24 +BC92 7D25 +BC93 7D26 +BDF4 7D27 +BC94 7D28 +BC95 7D29 +BC96 7D2A +D7CF 7D2B +BC97 7D2C +BC98 7D2D +BC99 7D2E +C0DB 7D2F +BC9A 7D30 +BC9B 7D31 +BC9C 7D32 +BC9D 7D33 +BC9E 7D34 +BC9F 7D35 +BCA0 7D36 +BD40 7D37 +BD41 7D38 +BD42 7D39 +BD43 7D3A +BD44 7D3B +BD45 7D3C +BD46 7D3D +BD47 7D3E +BD48 7D3F +BD49 7D40 +BD4A 7D41 +BD4B 7D42 +BD4C 7D43 +BD4D 7D44 +BD4E 7D45 +BD4F 7D46 +BD50 7D47 +BD51 7D48 +BD52 7D49 +BD53 7D4A +BD54 7D4B +BD55 7D4C +BD56 7D4D +BD57 7D4E +BD58 7D4F +BD59 7D50 +BD5A 7D51 +BD5B 7D52 +BD5C 7D53 +BD5D 7D54 +BD5E 7D55 +BD5F 7D56 +BD60 7D57 +BD61 7D58 +BD62 7D59 +BD63 7D5A +BD64 7D5B +BD65 7D5C +BD66 7D5D +BD67 7D5E +BD68 7D5F +BD69 7D60 +BD6A 7D61 +BD6B 7D62 +BD6C 7D63 +BD6D 7D64 +BD6E 7D65 +BD6F 7D66 +BD70 7D67 +BD71 7D68 +BD72 7D69 +BD73 7D6A +BD74 7D6B +BD75 7D6C +BD76 7D6D +D0F5 7D6E +BD77 7D6F +BD78 7D70 +BD79 7D71 +BD7A 7D72 +BD7B 7D73 +BD7C 7D74 +BD7D 7D75 +BD7E 7D76 +F4EA 7D77 +BD80 7D78 +BD81 7D79 +BD82 7D7A +BD83 7D7B +BD84 7D7C +BD85 7D7D +BD86 7D7E +BD87 7D7F +BD88 7D80 +BD89 7D81 +BD8A 7D82 +BD8B 7D83 +BD8C 7D84 +BD8D 7D85 +BD8E 7D86 +BD8F 7D87 +BD90 7D88 +BD91 7D89 +BD92 7D8A +BD93 7D8B +BD94 7D8C +BD95 7D8D +BD96 7D8E +BD97 7D8F +BD98 7D90 +BD99 7D91 +BD9A 7D92 +BD9B 7D93 +BD9C 7D94 +BD9D 7D95 +BD9E 7D96 +BD9F 7D97 +BDA0 7D98 +BE40 7D99 +BE41 7D9A +BE42 7D9B +BE43 7D9C +BE44 7D9D +BE45 7D9E +BE46 7D9F +BE47 7DA0 +BE48 7DA1 +BE49 7DA2 +BE4A 7DA3 +BE4B 7DA4 +BE4C 7DA5 +F4EB 7DA6 +BE4D 7DA7 +BE4E 7DA8 +BE4F 7DA9 +BE50 7DAA +BE51 7DAB +BE52 7DAC +BE53 7DAD +F4EC 7DAE +BE54 7DAF +BE55 7DB0 +BE56 7DB1 +BE57 7DB2 +BE58 7DB3 +BE59 7DB4 +BE5A 7DB5 +BE5B 7DB6 +BE5C 7DB7 +BE5D 7DB8 +BE5E 7DB9 +BE5F 7DBA +BE60 7DBB +BE61 7DBC +BE62 7DBD +BE63 7DBE +BE64 7DBF +BE65 7DC0 +BE66 7DC1 +BE67 7DC2 +BE68 7DC3 +BE69 7DC4 +BE6A 7DC5 +BE6B 7DC6 +BE6C 7DC7 +BE6D 7DC8 +BE6E 7DC9 +BE6F 7DCA +BE70 7DCB +BE71 7DCC +BE72 7DCD +BE73 7DCE +BE74 7DCF +BE75 7DD0 +BE76 7DD1 +BE77 7DD2 +BE78 7DD3 +BE79 7DD4 +BE7A 7DD5 +BE7B 7DD6 +BE7C 7DD7 +BE7D 7DD8 +BE7E 7DD9 +BE80 7DDA +BE81 7DDB +BE82 7DDC +BE83 7DDD +BE84 7DDE +BE85 7DDF +BE86 7DE0 +BE87 7DE1 +BE88 7DE2 +BE89 7DE3 +BE8A 7DE4 +BE8B 7DE5 +BE8C 7DE6 +BE8D 7DE7 +BE8E 7DE8 +BE8F 7DE9 +BE90 7DEA +BE91 7DEB +BE92 7DEC +BE93 7DED +BE94 7DEE +BE95 7DEF +BE96 7DF0 +BE97 7DF1 +BE98 7DF2 +BE99 7DF3 +BE9A 7DF4 +BE9B 7DF5 +BE9C 7DF6 +BE9D 7DF7 +BE9E 7DF8 +BE9F 7DF9 +BEA0 7DFA +BF40 7DFB +BF41 7DFC +BF42 7DFD +BF43 7DFE +BF44 7DFF +BF45 7E00 +BF46 7E01 +BF47 7E02 +BF48 7E03 +BF49 7E04 +BF4A 7E05 +BF4B 7E06 +BF4C 7E07 +BF4D 7E08 +BF4E 7E09 +BF4F 7E0A +BF50 7E0B +BF51 7E0C +BF52 7E0D +BF53 7E0E +BF54 7E0F +BF55 7E10 +BF56 7E11 +BF57 7E12 +BF58 7E13 +BF59 7E14 +BF5A 7E15 +BF5B 7E16 +BF5C 7E17 +BF5D 7E18 +BF5E 7E19 +BF5F 7E1A +BF60 7E1B +BF61 7E1C +BF62 7E1D +BF63 7E1E +BF64 7E1F +BF65 7E20 +BF66 7E21 +BF67 7E22 +BF68 7E23 +BF69 7E24 +BF6A 7E25 +BF6B 7E26 +BF6C 7E27 +BF6D 7E28 +BF6E 7E29 +BF6F 7E2A +BF70 7E2B +BF71 7E2C +BF72 7E2D +BF73 7E2E +BF74 7E2F +BF75 7E30 +BF76 7E31 +BF77 7E32 +BF78 7E33 +BF79 7E34 +BF7A 7E35 +BF7B 7E36 +BF7C 7E37 +BF7D 7E38 +BF7E 7E39 +BF80 7E3A +F7E3 7E3B +BF81 7E3C +BF82 7E3D +BF83 7E3E +BF84 7E3F +BF85 7E40 +B7B1 7E41 +BF86 7E42 +BF87 7E43 +BF88 7E44 +BF89 7E45 +BF8A 7E46 +F4ED 7E47 +BF8B 7E48 +BF8C 7E49 +BF8D 7E4A +BF8E 7E4B +BF8F 7E4C +BF90 7E4D +BF91 7E4E +BF92 7E4F +BF93 7E50 +BF94 7E51 +BF95 7E52 +BF96 7E53 +BF97 7E54 +BF98 7E55 +BF99 7E56 +BF9A 7E57 +BF9B 7E58 +BF9C 7E59 +BF9D 7E5A +BF9E 7E5B +BF9F 7E5C +BFA0 7E5D +C040 7E5E +C041 7E5F +C042 7E60 +C043 7E61 +C044 7E62 +C045 7E63 +C046 7E64 +C047 7E65 +C048 7E66 +C049 7E67 +C04A 7E68 +C04B 7E69 +C04C 7E6A +C04D 7E6B +C04E 7E6C +C04F 7E6D +C050 7E6E +C051 7E6F +C052 7E70 +C053 7E71 +C054 7E72 +C055 7E73 +C056 7E74 +C057 7E75 +C058 7E76 +C059 7E77 +C05A 7E78 +C05B 7E79 +C05C 7E7A +C05D 7E7B +C05E 7E7C +C05F 7E7D +C060 7E7E +C061 7E7F +C062 7E80 +C063 7E81 +D7EB 7E82 +C064 7E83 +C065 7E84 +C066 7E85 +C067 7E86 +C068 7E87 +C069 7E88 +C06A 7E89 +C06B 7E8A +C06C 7E8B +C06D 7E8C +C06E 7E8D +C06F 7E8E +C070 7E8F +C071 7E90 +C072 7E91 +C073 7E92 +C074 7E93 +C075 7E94 +C076 7E95 +C077 7E96 +C078 7E97 +C079 7E98 +C07A 7E99 +C07B 7E9A +F4EE 7E9B +C07C 7E9C +C07D 7E9D +C07E 7E9E +E6F9 7E9F +BEC0 7EA0 +E6FA 7EA1 +BAEC 7EA2 +E6FB 7EA3 +CFCB 7EA4 +E6FC 7EA5 +D4BC 7EA6 +BCB6 7EA7 +E6FD 7EA8 +E6FE 7EA9 +BCCD 7EAA +C8D2 7EAB +CEB3 7EAC +E7A1 7EAD +C080 7EAE +B4BF 7EAF +E7A2 7EB0 +C9B4 7EB1 +B8D9 7EB2 +C4C9 7EB3 +C081 7EB4 +D7DD 7EB5 +C2DA 7EB6 +B7D7 7EB7 +D6BD 7EB8 +CEC6 7EB9 +B7C4 7EBA +C082 7EBB +C083 7EBC +C5A6 7EBD +E7A3 7EBE +CFDF 7EBF +E7A4 7EC0 +E7A5 7EC1 +E7A6 7EC2 +C1B7 7EC3 +D7E9 7EC4 +C9F0 7EC5 +CFB8 7EC6 +D6AF 7EC7 +D6D5 7EC8 +E7A7 7EC9 +B0ED 7ECA +E7A8 7ECB +E7A9 7ECC +C9DC 7ECD +D2EF 7ECE +BEAD 7ECF +E7AA 7ED0 +B0F3 7ED1 +C8DE 7ED2 +BDE1 7ED3 +E7AB 7ED4 +C8C6 7ED5 +C084 7ED6 +E7AC 7ED7 +BBE6 7ED8 +B8F8 7ED9 +D1A4 7EDA +E7AD 7EDB +C2E7 7EDC +BEF8 7EDD +BDCA 7EDE +CDB3 7EDF +E7AE 7EE0 +E7AF 7EE1 +BEEE 7EE2 +D0E5 7EE3 +C085 7EE4 +CBE7 7EE5 +CCD0 7EE6 +BCCC 7EE7 +E7B0 7EE8 +BCA8 7EE9 +D0F7 7EEA +E7B1 7EEB +C086 7EEC +D0F8 7EED +E7B2 7EEE +E7B3 7EEF +B4C2 7EF0 +E7B4 7EF1 +E7B5 7EF2 +C9FE 7EF3 +CEAC 7EF4 +C3E0 7EF5 +E7B7 7EF6 +B1C1 7EF7 +B3F1 7EF8 +C087 7EF9 +E7B8 7EFA +E7B9 7EFB +D7DB 7EFC +D5C0 7EFD +E7BA 7EFE +C2CC 7EFF +D7BA 7F00 +E7BB 7F01 +E7BC 7F02 +E7BD 7F03 +BCEA 7F04 +C3E5 7F05 +C0C2 7F06 +E7BE 7F07 +E7BF 7F08 +BCA9 7F09 +C088 7F0A +E7C0 7F0B +E7C1 7F0C +E7B6 7F0D +B6D0 7F0E +E7C2 7F0F +C089 7F10 +E7C3 7F11 +E7C4 7F12 +BBBA 7F13 +B5DE 7F14 +C2C6 7F15 +B1E0 7F16 +E7C5 7F17 +D4B5 7F18 +E7C6 7F19 +B8BF 7F1A +E7C8 7F1B +E7C7 7F1C +B7EC 7F1D +C08A 7F1E +E7C9 7F1F +B2F8 7F20 +E7CA 7F21 +E7CB 7F22 +E7CC 7F23 +E7CD 7F24 +E7CE 7F25 +E7CF 7F26 +E7D0 7F27 +D3A7 7F28 +CBF5 7F29 +E7D1 7F2A +E7D2 7F2B +E7D3 7F2C +E7D4 7F2D +C9C9 7F2E +E7D5 7F2F +E7D6 7F30 +E7D7 7F31 +E7D8 7F32 +E7D9 7F33 +BDC9 7F34 +E7DA 7F35 +F3BE 7F36 +C08B 7F37 +B8D7 7F38 +C08C 7F39 +C8B1 7F3A +C08D 7F3B +C08E 7F3C +C08F 7F3D +C090 7F3E +C091 7F3F +C092 7F40 +C093 7F41 +F3BF 7F42 +C094 7F43 +F3C0 7F44 +F3C1 7F45 +C095 7F46 +C096 7F47 +C097 7F48 +C098 7F49 +C099 7F4A +C09A 7F4B +C09B 7F4C +C09C 7F4D +C09D 7F4E +C09E 7F4F +B9DE 7F50 +CDF8 7F51 +C09F 7F52 +C0A0 7F53 +D8E8 7F54 +BAB1 7F55 +C140 7F56 +C2DE 7F57 +EEB7 7F58 +C141 7F59 +B7A3 7F5A +C142 7F5B +C143 7F5C +C144 7F5D +C145 7F5E +EEB9 7F5F +C146 7F60 +EEB8 7F61 +B0D5 7F62 +C147 7F63 +C148 7F64 +C149 7F65 +C14A 7F66 +C14B 7F67 +EEBB 7F68 +D5D6 7F69 +D7EF 7F6A +C14C 7F6B +C14D 7F6C +C14E 7F6D +D6C3 7F6E +C14F 7F6F +C150 7F70 +EEBD 7F71 +CAF0 7F72 +C151 7F73 +EEBC 7F74 +C152 7F75 +C153 7F76 +C154 7F77 +C155 7F78 +EEBE 7F79 +C156 7F7A +C157 7F7B +C158 7F7C +C159 7F7D +EEC0 7F7E +C15A 7F7F +C15B 7F80 +EEBF 7F81 +C15C 7F82 +C15D 7F83 +C15E 7F84 +C15F 7F85 +C160 7F86 +C161 7F87 +C162 7F88 +C163 7F89 +D1F2 7F8A +C164 7F8B +C7BC 7F8C +C165 7F8D +C3C0 7F8E +C166 7F8F +C167 7F90 +C168 7F91 +C169 7F92 +C16A 7F93 +B8E1 7F94 +C16B 7F95 +C16C 7F96 +C16D 7F97 +C16E 7F98 +C16F 7F99 +C1E7 7F9A +C170 7F9B +C171 7F9C +F4C6 7F9D +D0DF 7F9E +F4C7 7F9F +C172 7FA0 +CFDB 7FA1 +C173 7FA2 +C174 7FA3 +C8BA 7FA4 +C175 7FA5 +C176 7FA6 +F4C8 7FA7 +C177 7FA8 +C178 7FA9 +C179 7FAA +C17A 7FAB +C17B 7FAC +C17C 7FAD +C17D 7FAE +F4C9 7FAF +F4CA 7FB0 +C17E 7FB1 +F4CB 7FB2 +C180 7FB3 +C181 7FB4 +C182 7FB5 +C183 7FB6 +C184 7FB7 +D9FA 7FB8 +B8FE 7FB9 +C185 7FBA +C186 7FBB +E5F1 7FBC +D3F0 7FBD +C187 7FBE +F4E0 7FBF +C188 7FC0 +CECC 7FC1 +C189 7FC2 +C18A 7FC3 +C18B 7FC4 +B3E1 7FC5 +C18C 7FC6 +C18D 7FC7 +C18E 7FC8 +C18F 7FC9 +F1B4 7FCA +C190 7FCB +D2EE 7FCC +C191 7FCD +F4E1 7FCE +C192 7FCF +C193 7FD0 +C194 7FD1 +C195 7FD2 +C196 7FD3 +CFE8 7FD4 +F4E2 7FD5 +C197 7FD6 +C198 7FD7 +C7CC 7FD8 +C199 7FD9 +C19A 7FDA +C19B 7FDB +C19C 7FDC +C19D 7FDD +C19E 7FDE +B5D4 7FDF +B4E4 7FE0 +F4E4 7FE1 +C19F 7FE2 +C1A0 7FE3 +C240 7FE4 +F4E3 7FE5 +F4E5 7FE6 +C241 7FE7 +C242 7FE8 +F4E6 7FE9 +C243 7FEA +C244 7FEB +C245 7FEC +C246 7FED +F4E7 7FEE +C247 7FEF +BAB2 7FF0 +B0BF 7FF1 +C248 7FF2 +F4E8 7FF3 +C249 7FF4 +C24A 7FF5 +C24B 7FF6 +C24C 7FF7 +C24D 7FF8 +C24E 7FF9 +C24F 7FFA +B7AD 7FFB +D2ED 7FFC +C250 7FFD +C251 7FFE +C252 7FFF +D2AB 8000 +C0CF 8001 +C253 8002 +BFBC 8003 +EBA3 8004 +D5DF 8005 +EAC8 8006 +C254 8007 +C255 8008 +C256 8009 +C257 800A +F1F3 800B +B6F8 800C +CBA3 800D +C258 800E +C259 800F +C4CD 8010 +C25A 8011 +F1E7 8012 +C25B 8013 +F1E8 8014 +B8FB 8015 +F1E9 8016 +BAC4 8017 +D4C5 8018 +B0D2 8019 +C25C 801A +C25D 801B +F1EA 801C +C25E 801D +C25F 801E +C260 801F +F1EB 8020 +C261 8021 +F1EC 8022 +C262 8023 +C263 8024 +F1ED 8025 +F1EE 8026 +F1EF 8027 +F1F1 8028 +F1F0 8029 +C5D5 802A +C264 802B +C265 802C +C266 802D +C267 802E +C268 802F +C269 8030 +F1F2 8031 +C26A 8032 +B6FA 8033 +C26B 8034 +F1F4 8035 +D2AE 8036 +DEC7 8037 +CBCA 8038 +C26C 8039 +C26D 803A +B3DC 803B +C26E 803C +B5A2 803D +C26F 803E +B9A2 803F +C270 8040 +C271 8041 +C4F4 8042 +F1F5 8043 +C272 8044 +C273 8045 +F1F6 8046 +C274 8047 +C275 8048 +C276 8049 +C1C4 804A +C1FB 804B +D6B0 804C +F1F7 804D +C277 804E +C278 804F +C279 8050 +C27A 8051 +F1F8 8052 +C27B 8053 +C1AA 8054 +C27C 8055 +C27D 8056 +C27E 8057 +C6B8 8058 +C280 8059 +BEDB 805A +C281 805B +C282 805C +C283 805D +C284 805E +C285 805F +C286 8060 +C287 8061 +C288 8062 +C289 8063 +C28A 8064 +C28B 8065 +C28C 8066 +C28D 8067 +C28E 8068 +F1F9 8069 +B4CF 806A +C28F 806B +C290 806C +C291 806D +C292 806E +C293 806F +C294 8070 +F1FA 8071 +C295 8072 +C296 8073 +C297 8074 +C298 8075 +C299 8076 +C29A 8077 +C29B 8078 +C29C 8079 +C29D 807A +C29E 807B +C29F 807C +C2A0 807D +C340 807E +EDB2 807F +EDB1 8080 +C341 8081 +C342 8082 +CBE0 8083 +D2DE 8084 +C343 8085 +CBC1 8086 +D5D8 8087 +C344 8088 +C8E2 8089 +C345 808A +C0DF 808B +BCA1 808C +C346 808D +C347 808E +C348 808F +C349 8090 +C34A 8091 +C34B 8092 +EBC1 8093 +C34C 8094 +C34D 8095 +D0A4 8096 +C34E 8097 +D6E2 8098 +C34F 8099 +B6C7 809A +B8D8 809B +EBC0 809C +B8CE 809D +C350 809E +EBBF 809F +B3A6 80A0 +B9C9 80A1 +D6AB 80A2 +C351 80A3 +B7F4 80A4 +B7CA 80A5 +C352 80A6 +C353 80A7 +C354 80A8 +BCE7 80A9 +B7BE 80AA +EBC6 80AB +C355 80AC +EBC7 80AD +B0B9 80AE +BFCF 80AF +C356 80B0 +EBC5 80B1 +D3FD 80B2 +C357 80B3 +EBC8 80B4 +C358 80B5 +C359 80B6 +EBC9 80B7 +C35A 80B8 +C35B 80B9 +B7CE 80BA +C35C 80BB +EBC2 80BC +EBC4 80BD +C9F6 80BE +D6D7 80BF +D5CD 80C0 +D0B2 80C1 +EBCF 80C2 +CEB8 80C3 +EBD0 80C4 +C35D 80C5 +B5A8 80C6 +C35E 80C7 +C35F 80C8 +C360 80C9 +C361 80CA +C362 80CB +B1B3 80CC +EBD2 80CD +CCA5 80CE +C363 80CF +C364 80D0 +C365 80D1 +C366 80D2 +C367 80D3 +C368 80D4 +C369 80D5 +C5D6 80D6 +EBD3 80D7 +C36A 80D8 +EBD1 80D9 +C5DF 80DA +EBCE 80DB +CAA4 80DC +EBD5 80DD +B0FB 80DE +C36B 80DF +C36C 80E0 +BAFA 80E1 +C36D 80E2 +C36E 80E3 +D8B7 80E4 +F1E3 80E5 +C36F 80E6 +EBCA 80E7 +EBCB 80E8 +EBCC 80E9 +EBCD 80EA +EBD6 80EB +E6C0 80EC +EBD9 80ED +C370 80EE +BFE8 80EF +D2C8 80F0 +EBD7 80F1 +EBDC 80F2 +B8EC 80F3 +EBD8 80F4 +C371 80F5 +BDBA 80F6 +C372 80F7 +D0D8 80F8 +C373 80F9 +B0B7 80FA +C374 80FB +EBDD 80FC +C4DC 80FD +C375 80FE +C376 80FF +C377 8100 +C378 8101 +D6AC 8102 +C379 8103 +C37A 8104 +C37B 8105 +B4E0 8106 +C37C 8107 +C37D 8108 +C2F6 8109 +BCB9 810A +C37E 810B +C380 810C +EBDA 810D +EBDB 810E +D4E0 810F +C6EA 8110 +C4D4 8111 +EBDF 8112 +C5A7 8113 +D9F5 8114 +C381 8115 +B2B1 8116 +C382 8117 +EBE4 8118 +C383 8119 +BDC5 811A +C384 811B +C385 811C +C386 811D +EBE2 811E +C387 811F +C388 8120 +C389 8121 +C38A 8122 +C38B 8123 +C38C 8124 +C38D 8125 +C38E 8126 +C38F 8127 +C390 8128 +C391 8129 +C392 812A +C393 812B +EBE3 812C +C394 812D +C395 812E +B8AC 812F +C396 8130 +CDD1 8131 +EBE5 8132 +C397 8133 +C398 8134 +C399 8135 +EBE1 8136 +C39A 8137 +C1B3 8138 +C39B 8139 +C39C 813A +C39D 813B +C39E 813C +C39F 813D +C6A2 813E +C3A0 813F +C440 8140 +C441 8141 +C442 8142 +C443 8143 +C444 8144 +C445 8145 +CCF3 8146 +C446 8147 +EBE6 8148 +C447 8149 +C0B0 814A +D2B8 814B +EBE7 814C +C448 814D +C449 814E +C44A 814F +B8AF 8150 +B8AD 8151 +C44B 8152 +EBE8 8153 +C7BB 8154 +CDF3 8155 +C44C 8156 +C44D 8157 +C44E 8158 +EBEA 8159 +EBEB 815A +C44F 815B +C450 815C +C451 815D +C452 815E +C453 815F +EBED 8160 +C454 8161 +C455 8162 +C456 8163 +C457 8164 +D0C8 8165 +C458 8166 +EBF2 8167 +C459 8168 +EBEE 8169 +C45A 816A +C45B 816B +C45C 816C +EBF1 816D +C8F9 816E +C45D 816F +D1FC 8170 +EBEC 8171 +C45E 8172 +C45F 8173 +EBE9 8174 +C460 8175 +C461 8176 +C462 8177 +C463 8178 +B8B9 8179 +CFD9 817A +C4E5 817B +EBEF 817C +EBF0 817D +CCDA 817E +CDC8 817F +B0F2 8180 +C464 8181 +EBF6 8182 +C465 8183 +C466 8184 +C467 8185 +C468 8186 +C469 8187 +EBF5 8188 +C46A 8189 +B2B2 818A +C46B 818B +C46C 818C +C46D 818D +C46E 818E +B8E0 818F +C46F 8190 +EBF7 8191 +C470 8192 +C471 8193 +C472 8194 +C473 8195 +C474 8196 +C475 8197 +B1EC 8198 +C476 8199 +C477 819A +CCC5 819B +C4A4 819C +CFA5 819D +C478 819E +C479 819F +C47A 81A0 +C47B 81A1 +C47C 81A2 +EBF9 81A3 +C47D 81A4 +C47E 81A5 +ECA2 81A6 +C480 81A7 +C5F2 81A8 +C481 81A9 +EBFA 81AA +C482 81AB +C483 81AC +C484 81AD +C485 81AE +C486 81AF +C487 81B0 +C488 81B1 +C489 81B2 +C9C5 81B3 +C48A 81B4 +C48B 81B5 +C48C 81B6 +C48D 81B7 +C48E 81B8 +C48F 81B9 +E2DF 81BA +EBFE 81BB +C490 81BC +C491 81BD +C492 81BE +C493 81BF +CDCE 81C0 +ECA1 81C1 +B1DB 81C2 +D3B7 81C3 +C494 81C4 +C495 81C5 +D2DC 81C6 +C496 81C7 +C497 81C8 +C498 81C9 +EBFD 81CA +C499 81CB +EBFB 81CC +C49A 81CD +C49B 81CE +C49C 81CF +C49D 81D0 +C49E 81D1 +C49F 81D2 +C4A0 81D3 +C540 81D4 +C541 81D5 +C542 81D6 +C543 81D7 +C544 81D8 +C545 81D9 +C546 81DA +C547 81DB +C548 81DC +C549 81DD +C54A 81DE +C54B 81DF +C54C 81E0 +C54D 81E1 +C54E 81E2 +B3BC 81E3 +C54F 81E4 +C550 81E5 +C551 81E6 +EAB0 81E7 +C552 81E8 +C553 81E9 +D7D4 81EA +C554 81EB +F4AB 81EC +B3F4 81ED +C555 81EE +C556 81EF +C557 81F0 +C558 81F1 +C559 81F2 +D6C1 81F3 +D6C2 81F4 +C55A 81F5 +C55B 81F6 +C55C 81F7 +C55D 81F8 +C55E 81F9 +C55F 81FA +D5E9 81FB +BECA 81FC +C560 81FD +F4A7 81FE +C561 81FF +D2A8 8200 +F4A8 8201 +F4A9 8202 +C562 8203 +F4AA 8204 +BECB 8205 +D3DF 8206 +C563 8207 +C564 8208 +C565 8209 +C566 820A +C567 820B +C9E0 820C +C9E1 820D +C568 820E +C569 820F +F3C2 8210 +C56A 8211 +CAE6 8212 +C56B 8213 +CCF2 8214 +C56C 8215 +C56D 8216 +C56E 8217 +C56F 8218 +C570 8219 +C571 821A +E2B6 821B +CBB4 821C +C572 821D +CEE8 821E +D6DB 821F +C573 8220 +F4AD 8221 +F4AE 8222 +F4AF 8223 +C574 8224 +C575 8225 +C576 8226 +C577 8227 +F4B2 8228 +C578 8229 +BABD 822A +F4B3 822B +B0E3 822C +F4B0 822D +C579 822E +F4B1 822F +BDA2 8230 +B2D5 8231 +C57A 8232 +F4B6 8233 +F4B7 8234 +B6E6 8235 +B2B0 8236 +CFCF 8237 +F4B4 8238 +B4AC 8239 +C57B 823A +F4B5 823B +C57C 823C +C57D 823D +F4B8 823E +C57E 823F +C580 8240 +C581 8241 +C582 8242 +C583 8243 +F4B9 8244 +C584 8245 +C585 8246 +CDA7 8247 +C586 8248 +F4BA 8249 +C587 824A +F4BB 824B +C588 824C +C589 824D +C58A 824E +F4BC 824F +C58B 8250 +C58C 8251 +C58D 8252 +C58E 8253 +C58F 8254 +C590 8255 +C591 8256 +C592 8257 +CBD2 8258 +C593 8259 +F4BD 825A +C594 825B +C595 825C +C596 825D +C597 825E +F4BE 825F +C598 8260 +C599 8261 +C59A 8262 +C59B 8263 +C59C 8264 +C59D 8265 +C59E 8266 +C59F 8267 +F4BF 8268 +C5A0 8269 +C640 826A +C641 826B +C642 826C +C643 826D +F4DE 826E +C1BC 826F +BCE8 8270 +C644 8271 +C9AB 8272 +D1DE 8273 +E5F5 8274 +C645 8275 +C646 8276 +C647 8277 +C648 8278 +DCB3 8279 +D2D5 827A +C649 827B +C64A 827C +DCB4 827D +B0AC 827E +DCB5 827F +C64B 8280 +C64C 8281 +BDDA 8282 +C64D 8283 +DCB9 8284 +C64E 8285 +C64F 8286 +C650 8287 +D8C2 8288 +C651 8289 +DCB7 828A +D3F3 828B +C652 828C +C9D6 828D +DCBA 828E +DCB6 828F +C653 8290 +DCBB 8291 +C3A2 8292 +C654 8293 +C655 8294 +C656 8295 +C657 8296 +DCBC 8297 +DCC5 8298 +DCBD 8299 +C658 829A +C659 829B +CEDF 829C +D6A5 829D +C65A 829E +DCCF 829F +C65B 82A0 +DCCD 82A1 +C65C 82A2 +C65D 82A3 +DCD2 82A4 +BDE6 82A5 +C2AB 82A6 +C65E 82A7 +DCB8 82A8 +DCCB 82A9 +DCCE 82AA +DCBE 82AB +B7D2 82AC +B0C5 82AD +DCC7 82AE +D0BE 82AF +DCC1 82B0 +BBA8 82B1 +C65F 82B2 +B7BC 82B3 +DCCC 82B4 +C660 82B5 +C661 82B6 +DCC6 82B7 +DCBF 82B8 +C7DB 82B9 +C662 82BA +C663 82BB +C664 82BC +D1BF 82BD +DCC0 82BE +C665 82BF +C666 82C0 +DCCA 82C1 +C667 82C2 +C668 82C3 +DCD0 82C4 +C669 82C5 +C66A 82C6 +CEAD 82C7 +DCC2 82C8 +C66B 82C9 +DCC3 82CA +DCC8 82CB +DCC9 82CC +B2D4 82CD +DCD1 82CE +CBD5 82CF +C66C 82D0 +D4B7 82D1 +DCDB 82D2 +DCDF 82D3 +CCA6 82D4 +DCE6 82D5 +C66D 82D6 +C3E7 82D7 +DCDC 82D8 +C66E 82D9 +C66F 82DA +BFC1 82DB +DCD9 82DC +C670 82DD +B0FA 82DE +B9B6 82DF +DCE5 82E0 +DCD3 82E1 +C671 82E2 +DCC4 82E3 +DCD6 82E4 +C8F4 82E5 +BFE0 82E6 +C672 82E7 +C673 82E8 +C674 82E9 +C675 82EA +C9BB 82EB +C676 82EC +C677 82ED +C678 82EE +B1BD 82EF +C679 82F0 +D3A2 82F1 +C67A 82F2 +C67B 82F3 +DCDA 82F4 +C67C 82F5 +C67D 82F6 +DCD5 82F7 +C67E 82F8 +C6BB 82F9 +C680 82FA +DCDE 82FB +C681 82FC +C682 82FD +C683 82FE +C684 82FF +C685 8300 +D7C2 8301 +C3AF 8302 +B7B6 8303 +C7D1 8304 +C3A9 8305 +DCE2 8306 +DCD8 8307 +DCEB 8308 +DCD4 8309 +C686 830A +C687 830B +DCDD 830C +C688 830D +BEA5 830E +DCD7 830F +C689 8310 +DCE0 8311 +C68A 8312 +C68B 8313 +DCE3 8314 +DCE4 8315 +C68C 8316 +DCF8 8317 +C68D 8318 +C68E 8319 +DCE1 831A +DDA2 831B +DCE7 831C +C68F 831D +C690 831E +C691 831F +C692 8320 +C693 8321 +C694 8322 +C695 8323 +C696 8324 +C697 8325 +C698 8326 +BCEB 8327 +B4C4 8328 +C699 8329 +C69A 832A +C3A3 832B +B2E7 832C +DCFA 832D +C69B 832E +DCF2 832F +C69C 8330 +DCEF 8331 +C69D 8332 +DCFC 8333 +DCEE 8334 +D2F0 8335 +B2E8 8336 +C69E 8337 +C8D7 8338 +C8E3 8339 +DCFB 833A +C69F 833B +DCED 833C +C6A0 833D +C740 833E +C741 833F +DCF7 8340 +C742 8341 +C743 8342 +DCF5 8343 +C744 8344 +C745 8345 +BEA3 8346 +DCF4 8347 +C746 8348 +B2DD 8349 +C747 834A +C748 834B +C749 834C +C74A 834D +C74B 834E +DCF3 834F +BCF6 8350 +DCE8 8351 +BBC4 8352 +C74C 8353 +C0F3 8354 +C74D 8355 +C74E 8356 +C74F 8357 +C750 8358 +C751 8359 +BCD4 835A +DCE9 835B +DCEA 835C +C752 835D +DCF1 835E +DCF6 835F +DCF9 8360 +B5B4 8361 +C753 8362 +C8D9 8363 +BBE7 8364 +DCFE 8365 +DCFD 8366 +D3AB 8367 +DDA1 8368 +DDA3 8369 +DDA5 836A +D2F1 836B +DDA4 836C +DDA6 836D +DDA7 836E +D2A9 836F +C754 8370 +C755 8371 +C756 8372 +C757 8373 +C758 8374 +C759 8375 +C75A 8376 +BAC9 8377 +DDA9 8378 +C75B 8379 +C75C 837A +DDB6 837B +DDB1 837C +DDB4 837D +C75D 837E +C75E 837F +C75F 8380 +C760 8381 +C761 8382 +C762 8383 +C763 8384 +DDB0 8385 +C6CE 8386 +C764 8387 +C765 8388 +C0F2 8389 +C766 838A +C767 838B +C768 838C +C769 838D +C9AF 838E +C76A 838F +C76B 8390 +C76C 8391 +DCEC 8392 +DDAE 8393 +C76D 8394 +C76E 8395 +C76F 8396 +C770 8397 +DDB7 8398 +C771 8399 +C772 839A +DCF0 839B +DDAF 839C +C773 839D +DDB8 839E +C774 839F +DDAC 83A0 +C775 83A1 +C776 83A2 +C777 83A3 +C778 83A4 +C779 83A5 +C77A 83A6 +C77B 83A7 +DDB9 83A8 +DDB3 83A9 +DDAD 83AA +C4AA 83AB +C77C 83AC +C77D 83AD +C77E 83AE +C780 83AF +DDA8 83B0 +C0B3 83B1 +C1AB 83B2 +DDAA 83B3 +DDAB 83B4 +C781 83B5 +DDB2 83B6 +BBF1 83B7 +DDB5 83B8 +D3A8 83B9 +DDBA 83BA +C782 83BB +DDBB 83BC +C3A7 83BD +C783 83BE +C784 83BF +DDD2 83C0 +DDBC 83C1 +C785 83C2 +C786 83C3 +C787 83C4 +DDD1 83C5 +C788 83C6 +B9BD 83C7 +C789 83C8 +C78A 83C9 +BED5 83CA +C78B 83CB +BEFA 83CC +C78C 83CD +C78D 83CE +BACA 83CF +C78E 83D0 +C78F 83D1 +C790 83D2 +C791 83D3 +DDCA 83D4 +C792 83D5 +DDC5 83D6 +C793 83D7 +DDBF 83D8 +C794 83D9 +C795 83DA +C796 83DB +B2CB 83DC +DDC3 83DD +C797 83DE +DDCB 83DF +B2A4 83E0 +DDD5 83E1 +C798 83E2 +C799 83E3 +C79A 83E4 +DDBE 83E5 +C79B 83E6 +C79C 83E7 +C79D 83E8 +C6D0 83E9 +DDD0 83EA +C79E 83EB +C79F 83EC +C7A0 83ED +C840 83EE +C841 83EF +DDD4 83F0 +C1E2 83F1 +B7C6 83F2 +C842 83F3 +C843 83F4 +C844 83F5 +C845 83F6 +C846 83F7 +DDCE 83F8 +DDCF 83F9 +C847 83FA +C848 83FB +C849 83FC +DDC4 83FD +C84A 83FE +C84B 83FF +C84C 8400 +DDBD 8401 +C84D 8402 +DDCD 8403 +CCD1 8404 +C84E 8405 +DDC9 8406 +C84F 8407 +C850 8408 +C851 8409 +C852 840A +DDC2 840B +C3C8 840C +C6BC 840D +CEAE 840E +DDCC 840F +C853 8410 +DDC8 8411 +C854 8412 +C855 8413 +C856 8414 +C857 8415 +C858 8416 +C859 8417 +DDC1 8418 +C85A 8419 +C85B 841A +C85C 841B +DDC6 841C +C2DC 841D +C85D 841E +C85E 841F +C85F 8420 +C860 8421 +C861 8422 +C862 8423 +D3A9 8424 +D3AA 8425 +DDD3 8426 +CFF4 8427 +C8F8 8428 +C863 8429 +C864 842A +C865 842B +C866 842C +C867 842D +C868 842E +C869 842F +C86A 8430 +DDE6 8431 +C86B 8432 +C86C 8433 +C86D 8434 +C86E 8435 +C86F 8436 +C870 8437 +DDC7 8438 +C871 8439 +C872 843A +C873 843B +DDE0 843C +C2E4 843D +C874 843E +C875 843F +C876 8440 +C877 8441 +C878 8442 +C879 8443 +C87A 8444 +C87B 8445 +DDE1 8446 +C87C 8447 +C87D 8448 +C87E 8449 +C880 844A +C881 844B +C882 844C +C883 844D +C884 844E +C885 844F +C886 8450 +DDD7 8451 +C887 8452 +C888 8453 +C889 8454 +C88A 8455 +C88B 8456 +D6F8 8457 +C88C 8458 +DDD9 8459 +DDD8 845A +B8F0 845B +DDD6 845C +C88D 845D +C88E 845E +C88F 845F +C890 8460 +C6CF 8461 +C891 8462 +B6AD 8463 +C892 8464 +C893 8465 +C894 8466 +C895 8467 +C896 8468 +DDE2 8469 +C897 846A +BAF9 846B +D4E1 846C +DDE7 846D +C898 846E +C899 846F +C89A 8470 +B4D0 8471 +C89B 8472 +DDDA 8473 +C89C 8474 +BFFB 8475 +DDE3 8476 +C89D 8477 +DDDF 8478 +C89E 8479 +DDDD 847A +C89F 847B +C8A0 847C +C940 847D +C941 847E +C942 847F +C943 8480 +C944 8481 +B5D9 8482 +C945 8483 +C946 8484 +C947 8485 +C948 8486 +DDDB 8487 +DDDC 8488 +DDDE 8489 +C949 848A +BDAF 848B +DDE4 848C +C94A 848D +DDE5 848E +C94B 848F +C94C 8490 +C94D 8491 +C94E 8492 +C94F 8493 +C950 8494 +C951 8495 +C952 8496 +DDF5 8497 +C953 8498 +C3C9 8499 +C954 849A +C955 849B +CBE2 849C +C956 849D +C957 849E +C958 849F +C959 84A0 +DDF2 84A1 +C95A 84A2 +C95B 84A3 +C95C 84A4 +C95D 84A5 +C95E 84A6 +C95F 84A7 +C960 84A8 +C961 84A9 +C962 84AA +C963 84AB +C964 84AC +C965 84AD +C966 84AE +D8E1 84AF +C967 84B0 +C968 84B1 +C6D1 84B2 +C969 84B3 +DDF4 84B4 +C96A 84B5 +C96B 84B6 +C96C 84B7 +D5F4 84B8 +DDF3 84B9 +DDF0 84BA +C96D 84BB +C96E 84BC +DDEC 84BD +C96F 84BE +DDEF 84BF +C970 84C0 +DDE8 84C1 +C971 84C2 +C972 84C3 +D0EE 84C4 +C973 84C5 +C974 84C6 +C975 84C7 +C976 84C8 +C8D8 84C9 +DDEE 84CA +C977 84CB +C978 84CC +DDE9 84CD +C979 84CE +C97A 84CF +DDEA 84D0 +CBF2 84D1 +C97B 84D2 +DDED 84D3 +C97C 84D4 +C97D 84D5 +B1CD 84D6 +C97E 84D7 +C980 84D8 +C981 84D9 +C982 84DA +C983 84DB +C984 84DC +C0B6 84DD +C985 84DE +BCBB 84DF +DDF1 84E0 +C986 84E1 +C987 84E2 +DDF7 84E3 +C988 84E4 +DDF6 84E5 +DDEB 84E6 +C989 84E7 +C98A 84E8 +C98B 84E9 +C98C 84EA +C98D 84EB +C5EE 84EC +C98E 84ED +C98F 84EE +C990 84EF +DDFB 84F0 +C991 84F1 +C992 84F2 +C993 84F3 +C994 84F4 +C995 84F5 +C996 84F6 +C997 84F7 +C998 84F8 +C999 84F9 +C99A 84FA +C99B 84FB +DEA4 84FC +C99C 84FD +C99D 84FE +DEA3 84FF +C99E 8500 +C99F 8501 +C9A0 8502 +CA40 8503 +CA41 8504 +CA42 8505 +CA43 8506 +CA44 8507 +CA45 8508 +CA46 8509 +CA47 850A +CA48 850B +DDF8 850C +CA49 850D +CA4A 850E +CA4B 850F +CA4C 8510 +C3EF 8511 +CA4D 8512 +C2FB 8513 +CA4E 8514 +CA4F 8515 +CA50 8516 +D5E1 8517 +CA51 8518 +CA52 8519 +CEB5 851A +CA53 851B +CA54 851C +CA55 851D +CA56 851E +DDFD 851F +CA57 8520 +B2CC 8521 +CA58 8522 +CA59 8523 +CA5A 8524 +CA5B 8525 +CA5C 8526 +CA5D 8527 +CA5E 8528 +CA5F 8529 +CA60 852A +C4E8 852B +CADF 852C +CA61 852D +CA62 852E +CA63 852F +CA64 8530 +CA65 8531 +CA66 8532 +CA67 8533 +CA68 8534 +CA69 8535 +CA6A 8536 +C7BE 8537 +DDFA 8538 +DDFC 8539 +DDFE 853A +DEA2 853B +B0AA 853C +B1CE 853D +CA6B 853E +CA6C 853F +CA6D 8540 +CA6E 8541 +CA6F 8542 +DEAC 8543 +CA70 8544 +CA71 8545 +CA72 8546 +CA73 8547 +DEA6 8548 +BDB6 8549 +C8EF 854A +CA74 854B +CA75 854C +CA76 854D +CA77 854E +CA78 854F +CA79 8550 +CA7A 8551 +CA7B 8552 +CA7C 8553 +CA7D 8554 +CA7E 8555 +DEA1 8556 +CA80 8557 +CA81 8558 +DEA5 8559 +CA82 855A +CA83 855B +CA84 855C +CA85 855D +DEA9 855E +CA86 855F +CA87 8560 +CA88 8561 +CA89 8562 +CA8A 8563 +DEA8 8564 +CA8B 8565 +CA8C 8566 +CA8D 8567 +DEA7 8568 +CA8E 8569 +CA8F 856A +CA90 856B +CA91 856C +CA92 856D +CA93 856E +CA94 856F +CA95 8570 +CA96 8571 +DEAD 8572 +CA97 8573 +D4CC 8574 +CA98 8575 +CA99 8576 +CA9A 8577 +CA9B 8578 +DEB3 8579 +DEAA 857A +DEAE 857B +CA9C 857C +CA9D 857D +C0D9 857E +CA9E 857F +CA9F 8580 +CAA0 8581 +CB40 8582 +CB41 8583 +B1A1 8584 +DEB6 8585 +CB42 8586 +DEB1 8587 +CB43 8588 +CB44 8589 +CB45 858A +CB46 858B +CB47 858C +CB48 858D +CB49 858E +DEB2 858F +CB4A 8590 +CB4B 8591 +CB4C 8592 +CB4D 8593 +CB4E 8594 +CB4F 8595 +CB50 8596 +CB51 8597 +CB52 8598 +CB53 8599 +CB54 859A +D1A6 859B +DEB5 859C +CB55 859D +CB56 859E +CB57 859F +CB58 85A0 +CB59 85A1 +CB5A 85A2 +CB5B 85A3 +DEAF 85A4 +CB5C 85A5 +CB5D 85A6 +CB5E 85A7 +DEB0 85A8 +CB5F 85A9 +D0BD 85AA +CB60 85AB +CB61 85AC +CB62 85AD +DEB4 85AE +CAED 85AF +DEB9 85B0 +CB63 85B1 +CB64 85B2 +CB65 85B3 +CB66 85B4 +CB67 85B5 +CB68 85B6 +DEB8 85B7 +CB69 85B8 +DEB7 85B9 +CB6A 85BA +CB6B 85BB +CB6C 85BC +CB6D 85BD +CB6E 85BE +CB6F 85BF +CB70 85C0 +DEBB 85C1 +CB71 85C2 +CB72 85C3 +CB73 85C4 +CB74 85C5 +CB75 85C6 +CB76 85C7 +CB77 85C8 +BDE5 85C9 +CB78 85CA +CB79 85CB +CB7A 85CC +CB7B 85CD +CB7C 85CE +B2D8 85CF +C3EA 85D0 +CB7D 85D1 +CB7E 85D2 +DEBA 85D3 +CB80 85D4 +C5BA 85D5 +CB81 85D6 +CB82 85D7 +CB83 85D8 +CB84 85D9 +CB85 85DA +CB86 85DB +DEBC 85DC +CB87 85DD +CB88 85DE +CB89 85DF +CB8A 85E0 +CB8B 85E1 +CB8C 85E2 +CB8D 85E3 +CCD9 85E4 +CB8E 85E5 +CB8F 85E6 +CB90 85E7 +CB91 85E8 +B7AA 85E9 +CB92 85EA +CB93 85EB +CB94 85EC +CB95 85ED +CB96 85EE +CB97 85EF +CB98 85F0 +CB99 85F1 +CB9A 85F2 +CB9B 85F3 +CB9C 85F4 +CB9D 85F5 +CB9E 85F6 +CB9F 85F7 +CBA0 85F8 +CC40 85F9 +CC41 85FA +D4E5 85FB +CC42 85FC +CC43 85FD +CC44 85FE +DEBD 85FF +CC45 8600 +CC46 8601 +CC47 8602 +CC48 8603 +CC49 8604 +DEBF 8605 +CC4A 8606 +CC4B 8607 +CC4C 8608 +CC4D 8609 +CC4E 860A +CC4F 860B +CC50 860C +CC51 860D +CC52 860E +CC53 860F +CC54 8610 +C4A2 8611 +CC55 8612 +CC56 8613 +CC57 8614 +CC58 8615 +DEC1 8616 +CC59 8617 +CC5A 8618 +CC5B 8619 +CC5C 861A +CC5D 861B +CC5E 861C +CC5F 861D +CC60 861E +CC61 861F +CC62 8620 +CC63 8621 +CC64 8622 +CC65 8623 +CC66 8624 +CC67 8625 +CC68 8626 +DEBE 8627 +CC69 8628 +DEC0 8629 +CC6A 862A +CC6B 862B +CC6C 862C +CC6D 862D +CC6E 862E +CC6F 862F +CC70 8630 +CC71 8631 +CC72 8632 +CC73 8633 +CC74 8634 +CC75 8635 +CC76 8636 +CC77 8637 +D5BA 8638 +CC78 8639 +CC79 863A +CC7A 863B +DEC2 863C +CC7B 863D +CC7C 863E +CC7D 863F +CC7E 8640 +CC80 8641 +CC81 8642 +CC82 8643 +CC83 8644 +CC84 8645 +CC85 8646 +CC86 8647 +CC87 8648 +CC88 8649 +CC89 864A +CC8A 864B +CC8B 864C +F2AE 864D +BBA2 864E +C2B2 864F +C5B0 8650 +C2C7 8651 +CC8C 8652 +CC8D 8653 +F2AF 8654 +CC8E 8655 +CC8F 8656 +CC90 8657 +CC91 8658 +CC92 8659 +D0E9 865A +CC93 865B +CC94 865C +CC95 865D +D3DD 865E +CC96 865F +CC97 8660 +CC98 8661 +EBBD 8662 +CC99 8663 +CC9A 8664 +CC9B 8665 +CC9C 8666 +CC9D 8667 +CC9E 8668 +CC9F 8669 +CCA0 866A +B3E6 866B +F2B0 866C +CD40 866D +F2B1 866E +CD41 866F +CD42 8670 +CAAD 8671 +CD43 8672 +CD44 8673 +CD45 8674 +CD46 8675 +CD47 8676 +CD48 8677 +CD49 8678 +BAE7 8679 +F2B3 867A +F2B5 867B +F2B4 867C +CBE4 867D +CFBA 867E +F2B2 867F +CAB4 8680 +D2CF 8681 +C2EC 8682 +CD4A 8683 +CD4B 8684 +CD4C 8685 +CD4D 8686 +CD4E 8687 +CD4F 8688 +CD50 8689 +CEC3 868A +F2B8 868B +B0F6 868C +F2B7 868D +CD51 868E +CD52 868F +CD53 8690 +CD54 8691 +CD55 8692 +F2BE 8693 +CD56 8694 +B2CF 8695 +CD57 8696 +CD58 8697 +CD59 8698 +CD5A 8699 +CD5B 869A +CD5C 869B +D1C1 869C +F2BA 869D +CD5D 869E +CD5E 869F +CD5F 86A0 +CD60 86A1 +CD61 86A2 +F2BC 86A3 +D4E9 86A4 +CD62 86A5 +CD63 86A6 +F2BB 86A7 +F2B6 86A8 +F2BF 86A9 +F2BD 86AA +CD64 86AB +F2B9 86AC +CD65 86AD +CD66 86AE +F2C7 86AF +F2C4 86B0 +F2C6 86B1 +CD67 86B2 +CD68 86B3 +F2CA 86B4 +F2C2 86B5 +F2C0 86B6 +CD69 86B7 +CD6A 86B8 +CD6B 86B9 +F2C5 86BA +CD6C 86BB +CD6D 86BC +CD6E 86BD +CD6F 86BE +CD70 86BF +D6FB 86C0 +CD71 86C1 +CD72 86C2 +CD73 86C3 +F2C1 86C4 +CD74 86C5 +C7F9 86C6 +C9DF 86C7 +CD75 86C8 +F2C8 86C9 +B9C6 86CA +B5B0 86CB +CD76 86CC +CD77 86CD +F2C3 86CE +F2C9 86CF +F2D0 86D0 +F2D6 86D1 +CD78 86D2 +CD79 86D3 +BBD7 86D4 +CD7A 86D5 +CD7B 86D6 +CD7C 86D7 +F2D5 86D8 +CDDC 86D9 +CD7D 86DA +D6EB 86DB +CD7E 86DC +CD80 86DD +F2D2 86DE +F2D4 86DF +CD81 86E0 +CD82 86E1 +CD83 86E2 +CD84 86E3 +B8F2 86E4 +CD85 86E5 +CD86 86E6 +CD87 86E7 +CD88 86E8 +F2CB 86E9 +CD89 86EA +CD8A 86EB +CD8B 86EC +F2CE 86ED +C2F9 86EE +CD8C 86EF +D5DD 86F0 +F2CC 86F1 +F2CD 86F2 +F2CF 86F3 +F2D3 86F4 +CD8D 86F5 +CD8E 86F6 +CD8F 86F7 +F2D9 86F8 +D3BC 86F9 +CD90 86FA +CD91 86FB +CD92 86FC +CD93 86FD +B6EA 86FE +CD94 86FF +CAF1 8700 +CD95 8701 +B7E4 8702 +F2D7 8703 +CD96 8704 +CD97 8705 +CD98 8706 +F2D8 8707 +F2DA 8708 +F2DD 8709 +F2DB 870A +CD99 870B +CD9A 870C +F2DC 870D +CD9B 870E +CD9C 870F +CD9D 8710 +CD9E 8711 +D1D1 8712 +F2D1 8713 +CD9F 8714 +CDC9 8715 +CDA0 8716 +CECF 8717 +D6A9 8718 +CE40 8719 +F2E3 871A +CE41 871B +C3DB 871C +CE42 871D +F2E0 871E +CE43 871F +CE44 8720 +C0AF 8721 +F2EC 8722 +F2DE 8723 +CE45 8724 +F2E1 8725 +CE46 8726 +CE47 8727 +CE48 8728 +F2E8 8729 +CE49 872A +CE4A 872B +CE4B 872C +CE4C 872D +F2E2 872E +CE4D 872F +CE4E 8730 +F2E7 8731 +CE4F 8732 +CE50 8733 +F2E6 8734 +CE51 8735 +CE52 8736 +F2E9 8737 +CE53 8738 +CE54 8739 +CE55 873A +F2DF 873B +CE56 873C +CE57 873D +F2E4 873E +F2EA 873F +CE58 8740 +CE59 8741 +CE5A 8742 +CE5B 8743 +CE5C 8744 +CE5D 8745 +CE5E 8746 +D3AC 8747 +F2E5 8748 +B2F5 8749 +CE5F 874A +CE60 874B +F2F2 874C +CE61 874D +D0AB 874E +CE62 874F +CE63 8750 +CE64 8751 +CE65 8752 +F2F5 8753 +CE66 8754 +CE67 8755 +CE68 8756 +BBC8 8757 +CE69 8758 +F2F9 8759 +CE6A 875A +CE6B 875B +CE6C 875C +CE6D 875D +CE6E 875E +CE6F 875F +F2F0 8760 +CE70 8761 +CE71 8762 +F2F6 8763 +F2F8 8764 +F2FA 8765 +CE72 8766 +CE73 8767 +CE74 8768 +CE75 8769 +CE76 876A +CE77 876B +CE78 876C +CE79 876D +F2F3 876E +CE7A 876F +F2F1 8770 +CE7B 8771 +CE7C 8772 +CE7D 8773 +BAFB 8774 +CE7E 8775 +B5FB 8776 +CE80 8777 +CE81 8778 +CE82 8779 +CE83 877A +F2EF 877B +F2F7 877C +F2ED 877D +F2EE 877E +CE84 877F +CE85 8780 +CE86 8781 +F2EB 8782 +F3A6 8783 +CE87 8784 +F3A3 8785 +CE88 8786 +CE89 8787 +F3A2 8788 +CE8A 8789 +CE8B 878A +F2F4 878B +CE8C 878C +C8DA 878D +CE8D 878E +CE8E 878F +CE8F 8790 +CE90 8791 +CE91 8792 +F2FB 8793 +CE92 8794 +CE93 8795 +CE94 8796 +F3A5 8797 +CE95 8798 +CE96 8799 +CE97 879A +CE98 879B +CE99 879C +CE9A 879D +CE9B 879E +C3F8 879F +CE9C 87A0 +CE9D 87A1 +CE9E 87A2 +CE9F 87A3 +CEA0 87A4 +CF40 87A5 +CF41 87A6 +CF42 87A7 +F2FD 87A8 +CF43 87A9 +CF44 87AA +F3A7 87AB +F3A9 87AC +F3A4 87AD +CF45 87AE +F2FC 87AF +CF46 87B0 +CF47 87B1 +CF48 87B2 +F3AB 87B3 +CF49 87B4 +F3AA 87B5 +CF4A 87B6 +CF4B 87B7 +CF4C 87B8 +CF4D 87B9 +C2DD 87BA +CF4E 87BB +CF4F 87BC +F3AE 87BD +CF50 87BE +CF51 87BF +F3B0 87C0 +CF52 87C1 +CF53 87C2 +CF54 87C3 +CF55 87C4 +CF56 87C5 +F3A1 87C6 +CF57 87C7 +CF58 87C8 +CF59 87C9 +F3B1 87CA +F3AC 87CB +CF5A 87CC +CF5B 87CD +CF5C 87CE +CF5D 87CF +CF5E 87D0 +F3AF 87D1 +F2FE 87D2 +F3AD 87D3 +CF5F 87D4 +CF60 87D5 +CF61 87D6 +CF62 87D7 +CF63 87D8 +CF64 87D9 +CF65 87DA +F3B2 87DB +CF66 87DC +CF67 87DD +CF68 87DE +CF69 87DF +F3B4 87E0 +CF6A 87E1 +CF6B 87E2 +CF6C 87E3 +CF6D 87E4 +F3A8 87E5 +CF6E 87E6 +CF6F 87E7 +CF70 87E8 +CF71 87E9 +F3B3 87EA +CF72 87EB +CF73 87EC +CF74 87ED +F3B5 87EE +CF75 87EF +CF76 87F0 +CF77 87F1 +CF78 87F2 +CF79 87F3 +CF7A 87F4 +CF7B 87F5 +CF7C 87F6 +CF7D 87F7 +CF7E 87F8 +D0B7 87F9 +CF80 87FA +CF81 87FB +CF82 87FC +CF83 87FD +F3B8 87FE +CF84 87FF +CF85 8800 +CF86 8801 +CF87 8802 +D9F9 8803 +CF88 8804 +CF89 8805 +CF8A 8806 +CF8B 8807 +CF8C 8808 +CF8D 8809 +F3B9 880A +CF8E 880B +CF8F 880C +CF90 880D +CF91 880E +CF92 880F +CF93 8810 +CF94 8811 +CF95 8812 +F3B7 8813 +CF96 8814 +C8E4 8815 +F3B6 8816 +CF97 8817 +CF98 8818 +CF99 8819 +CF9A 881A +F3BA 881B +CF9B 881C +CF9C 881D +CF9D 881E +CF9E 881F +CF9F 8820 +F3BB 8821 +B4C0 8822 +CFA0 8823 +D040 8824 +D041 8825 +D042 8826 +D043 8827 +D044 8828 +D045 8829 +D046 882A +D047 882B +D048 882C +D049 882D +D04A 882E +D04B 882F +D04C 8830 +D04D 8831 +EEC3 8832 +D04E 8833 +D04F 8834 +D050 8835 +D051 8836 +D052 8837 +D053 8838 +F3BC 8839 +D054 883A +D055 883B +F3BD 883C +D056 883D +D057 883E +D058 883F +D1AA 8840 +D059 8841 +D05A 8842 +D05B 8843 +F4AC 8844 +D0C6 8845 +D05C 8846 +D05D 8847 +D05E 8848 +D05F 8849 +D060 884A +D061 884B +D0D0 884C +D1DC 884D +D062 884E +D063 884F +D064 8850 +D065 8851 +D066 8852 +D067 8853 +CFCE 8854 +D068 8855 +D069 8856 +BDD6 8857 +D06A 8858 +D1C3 8859 +D06B 885A +D06C 885B +D06D 885C +D06E 885D +D06F 885E +D070 885F +D071 8860 +BAE2 8861 +E1E9 8862 +D2C2 8863 +F1C2 8864 +B2B9 8865 +D072 8866 +D073 8867 +B1ED 8868 +F1C3 8869 +D074 886A +C9C0 886B +B3C4 886C +D075 886D +D9F2 886E +D076 886F +CBA5 8870 +D077 8871 +F1C4 8872 +D078 8873 +D079 8874 +D07A 8875 +D07B 8876 +D6D4 8877 +D07C 8878 +D07D 8879 +D07E 887A +D080 887B +D081 887C +F1C5 887D +F4C0 887E +F1C6 887F +D082 8880 +D4AC 8881 +F1C7 8882 +D083 8883 +B0C0 8884 +F4C1 8885 +D084 8886 +D085 8887 +F4C2 8888 +D086 8889 +D087 888A +B4FC 888B +D088 888C +C5DB 888D +D089 888E +D08A 888F +D08B 8890 +D08C 8891 +CCBB 8892 +D08D 8893 +D08E 8894 +D08F 8895 +D0E4 8896 +D090 8897 +D091 8898 +D092 8899 +D093 889A +D094 889B +CDE0 889C +D095 889D +D096 889E +D097 889F +D098 88A0 +D099 88A1 +F1C8 88A2 +D09A 88A3 +D9F3 88A4 +D09B 88A5 +D09C 88A6 +D09D 88A7 +D09E 88A8 +D09F 88A9 +D0A0 88AA +B1BB 88AB +D140 88AC +CFAE 88AD +D141 88AE +D142 88AF +D143 88B0 +B8A4 88B1 +D144 88B2 +D145 88B3 +D146 88B4 +D147 88B5 +D148 88B6 +F1CA 88B7 +D149 88B8 +D14A 88B9 +D14B 88BA +D14C 88BB +F1CB 88BC +D14D 88BD +D14E 88BE +D14F 88BF +D150 88C0 +B2C3 88C1 +C1D1 88C2 +D151 88C3 +D152 88C4 +D7B0 88C5 +F1C9 88C6 +D153 88C7 +D154 88C8 +F1CC 88C9 +D155 88CA +D156 88CB +D157 88CC +D158 88CD +F1CE 88CE +D159 88CF +D15A 88D0 +D15B 88D1 +D9F6 88D2 +D15C 88D3 +D2E1 88D4 +D4A3 88D5 +D15D 88D6 +D15E 88D7 +F4C3 88D8 +C8B9 88D9 +D15F 88DA +D160 88DB +D161 88DC +D162 88DD +D163 88DE +F4C4 88DF +D164 88E0 +D165 88E1 +F1CD 88E2 +F1CF 88E3 +BFE3 88E4 +F1D0 88E5 +D166 88E6 +D167 88E7 +F1D4 88E8 +D168 88E9 +D169 88EA +D16A 88EB +D16B 88EC +D16C 88ED +D16D 88EE +D16E 88EF +F1D6 88F0 +F1D1 88F1 +D16F 88F2 +C9D1 88F3 +C5E1 88F4 +D170 88F5 +D171 88F6 +D172 88F7 +C2E3 88F8 +B9FC 88F9 +D173 88FA +D174 88FB +F1D3 88FC +D175 88FD +F1D5 88FE +D176 88FF +D177 8900 +D178 8901 +B9D3 8902 +D179 8903 +D17A 8904 +D17B 8905 +D17C 8906 +D17D 8907 +D17E 8908 +D180 8909 +F1DB 890A +D181 890B +D182 890C +D183 890D +D184 890E +D185 890F +BAD6 8910 +D186 8911 +B0FD 8912 +F1D9 8913 +D187 8914 +D188 8915 +D189 8916 +D18A 8917 +D18B 8918 +F1D8 8919 +F1D2 891A +F1DA 891B +D18C 891C +D18D 891D +D18E 891E +D18F 891F +D190 8920 +F1D7 8921 +D191 8922 +D192 8923 +D193 8924 +C8EC 8925 +D194 8926 +D195 8927 +D196 8928 +D197 8929 +CDCA 892A +F1DD 892B +D198 892C +D199 892D +D19A 892E +D19B 892F +E5BD 8930 +D19C 8931 +D19D 8932 +D19E 8933 +F1DC 8934 +D19F 8935 +F1DE 8936 +D1A0 8937 +D240 8938 +D241 8939 +D242 893A +D243 893B +D244 893C +D245 893D +D246 893E +D247 893F +D248 8940 +F1DF 8941 +D249 8942 +D24A 8943 +CFE5 8944 +D24B 8945 +D24C 8946 +D24D 8947 +D24E 8948 +D24F 8949 +D250 894A +D251 894B +D252 894C +D253 894D +D254 894E +D255 894F +D256 8950 +D257 8951 +D258 8952 +D259 8953 +D25A 8954 +D25B 8955 +D25C 8956 +D25D 8957 +D25E 8958 +D25F 8959 +D260 895A +D261 895B +D262 895C +D263 895D +F4C5 895E +BDF3 895F +D264 8960 +D265 8961 +D266 8962 +D267 8963 +D268 8964 +D269 8965 +F1E0 8966 +D26A 8967 +D26B 8968 +D26C 8969 +D26D 896A +D26E 896B +D26F 896C +D270 896D +D271 896E +D272 896F +D273 8970 +D274 8971 +D275 8972 +D276 8973 +D277 8974 +D278 8975 +D279 8976 +D27A 8977 +D27B 8978 +D27C 8979 +D27D 897A +F1E1 897B +D27E 897C +D280 897D +D281 897E +CEF7 897F +D282 8980 +D2AA 8981 +D283 8982 +F1FB 8983 +D284 8984 +D285 8985 +B8B2 8986 +D286 8987 +D287 8988 +D288 8989 +D289 898A +D28A 898B +D28B 898C +D28C 898D +D28D 898E +D28E 898F +D28F 8990 +D290 8991 +D291 8992 +D292 8993 +D293 8994 +D294 8995 +D295 8996 +D296 8997 +D297 8998 +D298 8999 +D299 899A +D29A 899B +D29B 899C +D29C 899D +D29D 899E +D29E 899F +D29F 89A0 +D2A0 89A1 +D340 89A2 +D341 89A3 +D342 89A4 +D343 89A5 +D344 89A6 +D345 89A7 +D346 89A8 +D347 89A9 +D348 89AA +D349 89AB +D34A 89AC +D34B 89AD +D34C 89AE +D34D 89AF +D34E 89B0 +D34F 89B1 +D350 89B2 +D351 89B3 +D352 89B4 +D353 89B5 +D354 89B6 +D355 89B7 +D356 89B8 +D357 89B9 +D358 89BA +D359 89BB +D35A 89BC +D35B 89BD +D35C 89BE +D35D 89BF +D35E 89C0 +BCFB 89C1 +B9DB 89C2 +D35F 89C3 +B9E6 89C4 +C3D9 89C5 +CAD3 89C6 +EAE8 89C7 +C0C0 89C8 +BEF5 89C9 +EAE9 89CA +EAEA 89CB +EAEB 89CC +D360 89CD +EAEC 89CE +EAED 89CF +EAEE 89D0 +EAEF 89D1 +BDC7 89D2 +D361 89D3 +D362 89D4 +D363 89D5 +F5FB 89D6 +D364 89D7 +D365 89D8 +D366 89D9 +F5FD 89DA +D367 89DB +F5FE 89DC +D368 89DD +F5FC 89DE +D369 89DF +D36A 89E0 +D36B 89E1 +D36C 89E2 +BDE2 89E3 +D36D 89E4 +F6A1 89E5 +B4A5 89E6 +D36E 89E7 +D36F 89E8 +D370 89E9 +D371 89EA +F6A2 89EB +D372 89EC +D373 89ED +D374 89EE +F6A3 89EF +D375 89F0 +D376 89F1 +D377 89F2 +ECB2 89F3 +D378 89F4 +D379 89F5 +D37A 89F6 +D37B 89F7 +D37C 89F8 +D37D 89F9 +D37E 89FA +D380 89FB +D381 89FC +D382 89FD +D383 89FE +D384 89FF +D1D4 8A00 +D385 8A01 +D386 8A02 +D387 8A03 +D388 8A04 +D389 8A05 +D38A 8A06 +D9EA 8A07 +D38B 8A08 +D38C 8A09 +D38D 8A0A +D38E 8A0B +D38F 8A0C +D390 8A0D +D391 8A0E +D392 8A0F +D393 8A10 +D394 8A11 +D395 8A12 +D396 8A13 +D397 8A14 +D398 8A15 +D399 8A16 +D39A 8A17 +D39B 8A18 +D39C 8A19 +D39D 8A1A +D39E 8A1B +D39F 8A1C +D3A0 8A1D +D440 8A1E +D441 8A1F +D442 8A20 +D443 8A21 +D444 8A22 +D445 8A23 +D446 8A24 +D447 8A25 +D448 8A26 +D449 8A27 +D44A 8A28 +D44B 8A29 +D44C 8A2A +D44D 8A2B +D44E 8A2C +D44F 8A2D +D450 8A2E +D451 8A2F +D452 8A30 +D453 8A31 +D454 8A32 +D455 8A33 +D456 8A34 +D457 8A35 +D458 8A36 +D459 8A37 +D45A 8A38 +D45B 8A39 +D45C 8A3A +D45D 8A3B +D45E 8A3C +D45F 8A3D +F6A4 8A3E +D460 8A3F +D461 8A40 +D462 8A41 +D463 8A42 +D464 8A43 +D465 8A44 +D466 8A45 +D467 8A46 +D468 8A47 +EEBA 8A48 +D469 8A49 +D46A 8A4A +D46B 8A4B +D46C 8A4C +D46D 8A4D +D46E 8A4E +D46F 8A4F +D470 8A50 +D471 8A51 +D472 8A52 +D473 8A53 +D474 8A54 +D475 8A55 +D476 8A56 +D477 8A57 +D478 8A58 +D479 8A59 +D47A 8A5A +D47B 8A5B +D47C 8A5C +D47D 8A5D +D47E 8A5E +D480 8A5F +D481 8A60 +D482 8A61 +D483 8A62 +D484 8A63 +D485 8A64 +D486 8A65 +D487 8A66 +D488 8A67 +D489 8A68 +D48A 8A69 +D48B 8A6A +D48C 8A6B +D48D 8A6C +D48E 8A6D +D48F 8A6E +D490 8A6F +D491 8A70 +D492 8A71 +D493 8A72 +D494 8A73 +D495 8A74 +D496 8A75 +D497 8A76 +D498 8A77 +D499 8A78 +D5B2 8A79 +D49A 8A7A +D49B 8A7B +D49C 8A7C +D49D 8A7D +D49E 8A7E +D49F 8A7F +D4A0 8A80 +D540 8A81 +D541 8A82 +D542 8A83 +D543 8A84 +D544 8A85 +D545 8A86 +D546 8A87 +D547 8A88 +D3FE 8A89 +CCDC 8A8A +D548 8A8B +D549 8A8C +D54A 8A8D +D54B 8A8E +D54C 8A8F +D54D 8A90 +D54E 8A91 +D54F 8A92 +CAC4 8A93 +D550 8A94 +D551 8A95 +D552 8A96 +D553 8A97 +D554 8A98 +D555 8A99 +D556 8A9A +D557 8A9B +D558 8A9C +D559 8A9D +D55A 8A9E +D55B 8A9F +D55C 8AA0 +D55D 8AA1 +D55E 8AA2 +D55F 8AA3 +D560 8AA4 +D561 8AA5 +D562 8AA6 +D563 8AA7 +D564 8AA8 +D565 8AA9 +D566 8AAA +D567 8AAB +D568 8AAC +D569 8AAD +D56A 8AAE +D56B 8AAF +D56C 8AB0 +D56D 8AB1 +D56E 8AB2 +D56F 8AB3 +D570 8AB4 +D571 8AB5 +D572 8AB6 +D573 8AB7 +D574 8AB8 +D575 8AB9 +D576 8ABA +D577 8ABB +D578 8ABC +D579 8ABD +D57A 8ABE +D57B 8ABF +D57C 8AC0 +D57D 8AC1 +D57E 8AC2 +D580 8AC3 +D581 8AC4 +D582 8AC5 +D583 8AC6 +D584 8AC7 +D585 8AC8 +D586 8AC9 +D587 8ACA +D588 8ACB +D589 8ACC +D58A 8ACD +D58B 8ACE +D58C 8ACF +D58D 8AD0 +D58E 8AD1 +D58F 8AD2 +D590 8AD3 +D591 8AD4 +D592 8AD5 +D593 8AD6 +D594 8AD7 +D595 8AD8 +D596 8AD9 +D597 8ADA +D598 8ADB +D599 8ADC +D59A 8ADD +D59B 8ADE +D59C 8ADF +D59D 8AE0 +D59E 8AE1 +D59F 8AE2 +D5A0 8AE3 +D640 8AE4 +D641 8AE5 +D642 8AE6 +D643 8AE7 +D644 8AE8 +D645 8AE9 +D646 8AEA +D647 8AEB +D648 8AEC +D649 8AED +D64A 8AEE +D64B 8AEF +D64C 8AF0 +D64D 8AF1 +D64E 8AF2 +D64F 8AF3 +D650 8AF4 +D651 8AF5 +D652 8AF6 +D653 8AF7 +D654 8AF8 +D655 8AF9 +D656 8AFA +D657 8AFB +D658 8AFC +D659 8AFD +D65A 8AFE +D65B 8AFF +D65C 8B00 +D65D 8B01 +D65E 8B02 +D65F 8B03 +D660 8B04 +D661 8B05 +D662 8B06 +E5C0 8B07 +D663 8B08 +D664 8B09 +D665 8B0A +D666 8B0B +D667 8B0C +D668 8B0D +D669 8B0E +D66A 8B0F +D66B 8B10 +D66C 8B11 +D66D 8B12 +D66E 8B13 +D66F 8B14 +D670 8B15 +D671 8B16 +D672 8B17 +D673 8B18 +D674 8B19 +D675 8B1A +D676 8B1B +D677 8B1C +D678 8B1D +D679 8B1E +D67A 8B1F +D67B 8B20 +D67C 8B21 +D67D 8B22 +D67E 8B23 +D680 8B24 +D681 8B25 +F6A5 8B26 +D682 8B27 +D683 8B28 +D684 8B29 +D685 8B2A +D686 8B2B +D687 8B2C +D688 8B2D +D689 8B2E +D68A 8B2F +D68B 8B30 +D68C 8B31 +D68D 8B32 +D68E 8B33 +D68F 8B34 +D690 8B35 +D691 8B36 +D692 8B37 +D693 8B38 +D694 8B39 +D695 8B3A +D696 8B3B +D697 8B3C +D698 8B3D +D699 8B3E +D69A 8B3F +D69B 8B40 +D69C 8B41 +D69D 8B42 +D69E 8B43 +D69F 8B44 +D6A0 8B45 +D740 8B46 +D741 8B47 +D742 8B48 +D743 8B49 +D744 8B4A +D745 8B4B +D746 8B4C +D747 8B4D +D748 8B4E +D749 8B4F +D74A 8B50 +D74B 8B51 +D74C 8B52 +D74D 8B53 +D74E 8B54 +D74F 8B55 +D750 8B56 +D751 8B57 +D752 8B58 +D753 8B59 +D754 8B5A +D755 8B5B +D756 8B5C +D757 8B5D +D758 8B5E +D759 8B5F +D75A 8B60 +D75B 8B61 +D75C 8B62 +D75D 8B63 +D75E 8B64 +D75F 8B65 +BEAF 8B66 +D760 8B67 +D761 8B68 +D762 8B69 +D763 8B6A +D764 8B6B +C6A9 8B6C +D765 8B6D +D766 8B6E +D767 8B6F +D768 8B70 +D769 8B71 +D76A 8B72 +D76B 8B73 +D76C 8B74 +D76D 8B75 +D76E 8B76 +D76F 8B77 +D770 8B78 +D771 8B79 +D772 8B7A +D773 8B7B +D774 8B7C +D775 8B7D +D776 8B7E +D777 8B7F +D778 8B80 +D779 8B81 +D77A 8B82 +D77B 8B83 +D77C 8B84 +D77D 8B85 +D77E 8B86 +D780 8B87 +D781 8B88 +D782 8B89 +D783 8B8A +D784 8B8B +D785 8B8C +D786 8B8D +D787 8B8E +D788 8B8F +D789 8B90 +D78A 8B91 +D78B 8B92 +D78C 8B93 +D78D 8B94 +D78E 8B95 +D78F 8B96 +D790 8B97 +D791 8B98 +D792 8B99 +D793 8B9A +D794 8B9B +D795 8B9C +D796 8B9D +D797 8B9E +D798 8B9F +DAA5 8BA0 +BCC6 8BA1 +B6A9 8BA2 +B8BC 8BA3 +C8CF 8BA4 +BCA5 8BA5 +DAA6 8BA6 +DAA7 8BA7 +CCD6 8BA8 +C8C3 8BA9 +DAA8 8BAA +C6FD 8BAB +D799 8BAC +D1B5 8BAD +D2E9 8BAE +D1B6 8BAF +BCC7 8BB0 +D79A 8BB1 +BDB2 8BB2 +BBE4 8BB3 +DAA9 8BB4 +DAAA 8BB5 +D1C8 8BB6 +DAAB 8BB7 +D0ED 8BB8 +B6EF 8BB9 +C2DB 8BBA +D79B 8BBB +CBCF 8BBC +B7ED 8BBD +C9E8 8BBE +B7C3 8BBF +BEF7 8BC0 +D6A4 8BC1 +DAAC 8BC2 +DAAD 8BC3 +C6C0 8BC4 +D7E7 8BC5 +CAB6 8BC6 +D79C 8BC7 +D5A9 8BC8 +CBDF 8BC9 +D5EF 8BCA +DAAE 8BCB +D6DF 8BCC +B4CA 8BCD +DAB0 8BCE +DAAF 8BCF +D79D 8BD0 +D2EB 8BD1 +DAB1 8BD2 +DAB2 8BD3 +DAB3 8BD4 +CAD4 8BD5 +DAB4 8BD6 +CAAB 8BD7 +DAB5 8BD8 +DAB6 8BD9 +B3CF 8BDA +D6EF 8BDB +DAB7 8BDC +BBB0 8BDD +B5AE 8BDE +DAB8 8BDF +DAB9 8BE0 +B9EE 8BE1 +D1AF 8BE2 +D2E8 8BE3 +DABA 8BE4 +B8C3 8BE5 +CFEA 8BE6 +B2EF 8BE7 +DABB 8BE8 +DABC 8BE9 +D79E 8BEA +BDEB 8BEB +CEDC 8BEC +D3EF 8BED +DABD 8BEE +CEF3 8BEF +DABE 8BF0 +D3D5 8BF1 +BBE5 8BF2 +DABF 8BF3 +CBB5 8BF4 +CBD0 8BF5 +DAC0 8BF6 +C7EB 8BF7 +D6EE 8BF8 +DAC1 8BF9 +C5B5 8BFA +B6C1 8BFB +DAC2 8BFC +B7CC 8BFD +BFCE 8BFE +DAC3 8BFF +DAC4 8C00 +CBAD 8C01 +DAC5 8C02 +B5F7 8C03 +DAC6 8C04 +C1C2 8C05 +D7BB 8C06 +DAC7 8C07 +CCB8 8C08 +D79F 8C09 +D2EA 8C0A +C4B1 8C0B +DAC8 8C0C +B5FD 8C0D +BBD1 8C0E +DAC9 8C0F +D0B3 8C10 +DACA 8C11 +DACB 8C12 +CEBD 8C13 +DACC 8C14 +DACD 8C15 +DACE 8C16 +B2F7 8C17 +DAD1 8C18 +DACF 8C19 +D1E8 8C1A +DAD0 8C1B +C3D5 8C1C +DAD2 8C1D +D7A0 8C1E +DAD3 8C1F +DAD4 8C20 +DAD5 8C21 +D0BB 8C22 +D2A5 8C23 +B0F9 8C24 +DAD6 8C25 +C7AB 8C26 +DAD7 8C27 +BDF7 8C28 +C3A1 8C29 +DAD8 8C2A +DAD9 8C2B +C3FD 8C2C +CCB7 8C2D +DADA 8C2E +DADB 8C2F +C0BE 8C30 +C6D7 8C31 +DADC 8C32 +DADD 8C33 +C7B4 8C34 +DADE 8C35 +DADF 8C36 +B9C8 8C37 +D840 8C38 +D841 8C39 +D842 8C3A +D843 8C3B +D844 8C3C +D845 8C3D +D846 8C3E +D847 8C3F +D848 8C40 +BBED 8C41 +D849 8C42 +D84A 8C43 +D84B 8C44 +D84C 8C45 +B6B9 8C46 +F4F8 8C47 +D84D 8C48 +F4F9 8C49 +D84E 8C4A +D84F 8C4B +CDE3 8C4C +D850 8C4D +D851 8C4E +D852 8C4F +D853 8C50 +D854 8C51 +D855 8C52 +D856 8C53 +D857 8C54 +F5B9 8C55 +D858 8C56 +D859 8C57 +D85A 8C58 +D85B 8C59 +EBE0 8C5A +D85C 8C5B +D85D 8C5C +D85E 8C5D +D85F 8C5E +D860 8C5F +D861 8C60 +CFF3 8C61 +BBBF 8C62 +D862 8C63 +D863 8C64 +D864 8C65 +D865 8C66 +D866 8C67 +D867 8C68 +D868 8C69 +BAC0 8C6A +D4A5 8C6B +D869 8C6C +D86A 8C6D +D86B 8C6E +D86C 8C6F +D86D 8C70 +D86E 8C71 +D86F 8C72 +E1D9 8C73 +D870 8C74 +D871 8C75 +D872 8C76 +D873 8C77 +F5F4 8C78 +B1AA 8C79 +B2F2 8C7A +D874 8C7B +D875 8C7C +D876 8C7D +D877 8C7E +D878 8C7F +D879 8C80 +D87A 8C81 +F5F5 8C82 +D87B 8C83 +D87C 8C84 +F5F7 8C85 +D87D 8C86 +D87E 8C87 +D880 8C88 +BAD1 8C89 +F5F6 8C8A +D881 8C8B +C3B2 8C8C +D882 8C8D +D883 8C8E +D884 8C8F +D885 8C90 +D886 8C91 +D887 8C92 +D888 8C93 +F5F9 8C94 +D889 8C95 +D88A 8C96 +D88B 8C97 +F5F8 8C98 +D88C 8C99 +D88D 8C9A +D88E 8C9B +D88F 8C9C +D890 8C9D +D891 8C9E +D892 8C9F +D893 8CA0 +D894 8CA1 +D895 8CA2 +D896 8CA3 +D897 8CA4 +D898 8CA5 +D899 8CA6 +D89A 8CA7 +D89B 8CA8 +D89C 8CA9 +D89D 8CAA +D89E 8CAB +D89F 8CAC +D8A0 8CAD +D940 8CAE +D941 8CAF +D942 8CB0 +D943 8CB1 +D944 8CB2 +D945 8CB3 +D946 8CB4 +D947 8CB5 +D948 8CB6 +D949 8CB7 +D94A 8CB8 +D94B 8CB9 +D94C 8CBA +D94D 8CBB +D94E 8CBC +D94F 8CBD +D950 8CBE +D951 8CBF +D952 8CC0 +D953 8CC1 +D954 8CC2 +D955 8CC3 +D956 8CC4 +D957 8CC5 +D958 8CC6 +D959 8CC7 +D95A 8CC8 +D95B 8CC9 +D95C 8CCA +D95D 8CCB +D95E 8CCC +D95F 8CCD +D960 8CCE +D961 8CCF +D962 8CD0 +D963 8CD1 +D964 8CD2 +D965 8CD3 +D966 8CD4 +D967 8CD5 +D968 8CD6 +D969 8CD7 +D96A 8CD8 +D96B 8CD9 +D96C 8CDA +D96D 8CDB +D96E 8CDC +D96F 8CDD +D970 8CDE +D971 8CDF +D972 8CE0 +D973 8CE1 +D974 8CE2 +D975 8CE3 +D976 8CE4 +D977 8CE5 +D978 8CE6 +D979 8CE7 +D97A 8CE8 +D97B 8CE9 +D97C 8CEA +D97D 8CEB +D97E 8CEC +D980 8CED +D981 8CEE +D982 8CEF +D983 8CF0 +D984 8CF1 +D985 8CF2 +D986 8CF3 +D987 8CF4 +D988 8CF5 +D989 8CF6 +D98A 8CF7 +D98B 8CF8 +D98C 8CF9 +D98D 8CFA +D98E 8CFB +D98F 8CFC +D990 8CFD +D991 8CFE +D992 8CFF +D993 8D00 +D994 8D01 +D995 8D02 +D996 8D03 +D997 8D04 +D998 8D05 +D999 8D06 +D99A 8D07 +D99B 8D08 +D99C 8D09 +D99D 8D0A +D99E 8D0B +D99F 8D0C +D9A0 8D0D +DA40 8D0E +DA41 8D0F +DA42 8D10 +DA43 8D11 +DA44 8D12 +DA45 8D13 +DA46 8D14 +DA47 8D15 +DA48 8D16 +DA49 8D17 +DA4A 8D18 +DA4B 8D19 +DA4C 8D1A +DA4D 8D1B +DA4E 8D1C +B1B4 8D1D +D5EA 8D1E +B8BA 8D1F +DA4F 8D20 +B9B1 8D21 +B2C6 8D22 +D4F0 8D23 +CFCD 8D24 +B0DC 8D25 +D5CB 8D26 +BBF5 8D27 +D6CA 8D28 +B7B7 8D29 +CCB0 8D2A +C6B6 8D2B +B1E1 8D2C +B9BA 8D2D +D6FC 8D2E +B9E1 8D2F +B7A1 8D30 +BCFA 8D31 +EADA 8D32 +EADB 8D33 +CCF9 8D34 +B9F3 8D35 +EADC 8D36 +B4FB 8D37 +C3B3 8D38 +B7D1 8D39 +BAD8 8D3A +EADD 8D3B +D4F4 8D3C +EADE 8D3D +BCD6 8D3E +BBDF 8D3F +EADF 8D40 +C1DE 8D41 +C2B8 8D42 +D4DF 8D43 +D7CA 8D44 +EAE0 8D45 +EAE1 8D46 +EAE4 8D47 +EAE2 8D48 +EAE3 8D49 +C9DE 8D4A +B8B3 8D4B +B6C4 8D4C +EAE5 8D4D +CAEA 8D4E +C9CD 8D4F +B4CD 8D50 +DA50 8D51 +DA51 8D52 +E2D9 8D53 +C5E2 8D54 +EAE6 8D55 +C0B5 8D56 +DA52 8D57 +D7B8 8D58 +EAE7 8D59 +D7AC 8D5A +C8FC 8D5B +D8D3 8D5C +D8CD 8D5D +D4DE 8D5E +DA53 8D5F +D4F9 8D60 +C9C4 8D61 +D3AE 8D62 +B8D3 8D63 +B3E0 8D64 +DA54 8D65 +C9E2 8D66 +F4F6 8D67 +DA55 8D68 +DA56 8D69 +DA57 8D6A +BAD5 8D6B +DA58 8D6C +F4F7 8D6D +DA59 8D6E +DA5A 8D6F +D7DF 8D70 +DA5B 8D71 +DA5C 8D72 +F4F1 8D73 +B8B0 8D74 +D5D4 8D75 +B8CF 8D76 +C6F0 8D77 +DA5D 8D78 +DA5E 8D79 +DA5F 8D7A +DA60 8D7B +DA61 8D7C +DA62 8D7D +DA63 8D7E +DA64 8D7F +DA65 8D80 +B3C3 8D81 +DA66 8D82 +DA67 8D83 +F4F2 8D84 +B3AC 8D85 +DA68 8D86 +DA69 8D87 +DA6A 8D88 +DA6B 8D89 +D4BD 8D8A +C7F7 8D8B +DA6C 8D8C +DA6D 8D8D +DA6E 8D8E +DA6F 8D8F +DA70 8D90 +F4F4 8D91 +DA71 8D92 +DA72 8D93 +F4F3 8D94 +DA73 8D95 +DA74 8D96 +DA75 8D97 +DA76 8D98 +DA77 8D99 +DA78 8D9A +DA79 8D9B +DA7A 8D9C +DA7B 8D9D +DA7C 8D9E +CCCB 8D9F +DA7D 8DA0 +DA7E 8DA1 +DA80 8DA2 +C8A4 8DA3 +DA81 8DA4 +DA82 8DA5 +DA83 8DA6 +DA84 8DA7 +DA85 8DA8 +DA86 8DA9 +DA87 8DAA +DA88 8DAB +DA89 8DAC +DA8A 8DAD +DA8B 8DAE +DA8C 8DAF +DA8D 8DB0 +F4F5 8DB1 +DA8E 8DB2 +D7E3 8DB3 +C5BF 8DB4 +F5C0 8DB5 +DA8F 8DB6 +DA90 8DB7 +F5BB 8DB8 +DA91 8DB9 +F5C3 8DBA +DA92 8DBB +F5C2 8DBC +DA93 8DBD +D6BA 8DBE +F5C1 8DBF +DA94 8DC0 +DA95 8DC1 +DA96 8DC2 +D4BE 8DC3 +F5C4 8DC4 +DA97 8DC5 +F5CC 8DC6 +DA98 8DC7 +DA99 8DC8 +DA9A 8DC9 +DA9B 8DCA +B0CF 8DCB +B5F8 8DCC +DA9C 8DCD +F5C9 8DCE +F5CA 8DCF +DA9D 8DD0 +C5DC 8DD1 +DA9E 8DD2 +DA9F 8DD3 +DAA0 8DD4 +DB40 8DD5 +F5C5 8DD6 +F5C6 8DD7 +DB41 8DD8 +DB42 8DD9 +F5C7 8DDA +F5CB 8DDB +DB43 8DDC +BEE0 8DDD +F5C8 8DDE +B8FA 8DDF +DB44 8DE0 +DB45 8DE1 +DB46 8DE2 +F5D0 8DE3 +F5D3 8DE4 +DB47 8DE5 +DB48 8DE6 +DB49 8DE7 +BFE7 8DE8 +DB4A 8DE9 +B9F2 8DEA +F5BC 8DEB +F5CD 8DEC +DB4B 8DED +DB4C 8DEE +C2B7 8DEF +DB4D 8DF0 +DB4E 8DF1 +DB4F 8DF2 +CCF8 8DF3 +DB50 8DF4 +BCF9 8DF5 +DB51 8DF6 +F5CE 8DF7 +F5CF 8DF8 +F5D1 8DF9 +B6E5 8DFA +F5D2 8DFB +DB52 8DFC +F5D5 8DFD +DB53 8DFE +DB54 8DFF +DB55 8E00 +DB56 8E01 +DB57 8E02 +DB58 8E03 +DB59 8E04 +F5BD 8E05 +DB5A 8E06 +DB5B 8E07 +DB5C 8E08 +F5D4 8E09 +D3BB 8E0A +DB5D 8E0B +B3EC 8E0C +DB5E 8E0D +DB5F 8E0E +CCA4 8E0F +DB60 8E10 +DB61 8E11 +DB62 8E12 +DB63 8E13 +F5D6 8E14 +DB64 8E15 +DB65 8E16 +DB66 8E17 +DB67 8E18 +DB68 8E19 +DB69 8E1A +DB6A 8E1B +DB6B 8E1C +F5D7 8E1D +BEE1 8E1E +F5D8 8E1F +DB6C 8E20 +DB6D 8E21 +CCDF 8E22 +F5DB 8E23 +DB6E 8E24 +DB6F 8E25 +DB70 8E26 +DB71 8E27 +DB72 8E28 +B2C8 8E29 +D7D9 8E2A +DB73 8E2B +F5D9 8E2C +DB74 8E2D +F5DA 8E2E +F5DC 8E2F +DB75 8E30 +F5E2 8E31 +DB76 8E32 +DB77 8E33 +DB78 8E34 +F5E0 8E35 +DB79 8E36 +DB7A 8E37 +DB7B 8E38 +F5DF 8E39 +F5DD 8E3A +DB7C 8E3B +DB7D 8E3C +F5E1 8E3D +DB7E 8E3E +DB80 8E3F +F5DE 8E40 +F5E4 8E41 +F5E5 8E42 +DB81 8E43 +CCE3 8E44 +DB82 8E45 +DB83 8E46 +E5BF 8E47 +B5B8 8E48 +F5E3 8E49 +F5E8 8E4A +CCA3 8E4B +DB84 8E4C +DB85 8E4D +DB86 8E4E +DB87 8E4F +DB88 8E50 +F5E6 8E51 +F5E7 8E52 +DB89 8E53 +DB8A 8E54 +DB8B 8E55 +DB8C 8E56 +DB8D 8E57 +DB8E 8E58 +F5BE 8E59 +DB8F 8E5A +DB90 8E5B +DB91 8E5C +DB92 8E5D +DB93 8E5E +DB94 8E5F +DB95 8E60 +DB96 8E61 +DB97 8E62 +DB98 8E63 +DB99 8E64 +DB9A 8E65 +B1C4 8E66 +DB9B 8E67 +DB9C 8E68 +F5BF 8E69 +DB9D 8E6A +DB9E 8E6B +B5C5 8E6C +B2E4 8E6D +DB9F 8E6E +F5EC 8E6F +F5E9 8E70 +DBA0 8E71 +B6D7 8E72 +DC40 8E73 +F5ED 8E74 +DC41 8E75 +F5EA 8E76 +DC42 8E77 +DC43 8E78 +DC44 8E79 +DC45 8E7A +DC46 8E7B +F5EB 8E7C +DC47 8E7D +DC48 8E7E +B4DA 8E7F +DC49 8E80 +D4EA 8E81 +DC4A 8E82 +DC4B 8E83 +DC4C 8E84 +F5EE 8E85 +DC4D 8E86 +B3F9 8E87 +DC4E 8E88 +DC4F 8E89 +DC50 8E8A +DC51 8E8B +DC52 8E8C +DC53 8E8D +DC54 8E8E +F5EF 8E8F +F5F1 8E90 +DC55 8E91 +DC56 8E92 +DC57 8E93 +F5F0 8E94 +DC58 8E95 +DC59 8E96 +DC5A 8E97 +DC5B 8E98 +DC5C 8E99 +DC5D 8E9A +DC5E 8E9B +F5F2 8E9C +DC5F 8E9D +F5F3 8E9E +DC60 8E9F +DC61 8EA0 +DC62 8EA1 +DC63 8EA2 +DC64 8EA3 +DC65 8EA4 +DC66 8EA5 +DC67 8EA6 +DC68 8EA7 +DC69 8EA8 +DC6A 8EA9 +DC6B 8EAA +C9ED 8EAB +B9AA 8EAC +DC6C 8EAD +DC6D 8EAE +C7FB 8EAF +DC6E 8EB0 +DC6F 8EB1 +B6E3 8EB2 +DC70 8EB3 +DC71 8EB4 +DC72 8EB5 +DC73 8EB6 +DC74 8EB7 +DC75 8EB8 +DC76 8EB9 +CCC9 8EBA +DC77 8EBB +DC78 8EBC +DC79 8EBD +DC7A 8EBE +DC7B 8EBF +DC7C 8EC0 +DC7D 8EC1 +DC7E 8EC2 +DC80 8EC3 +DC81 8EC4 +DC82 8EC5 +DC83 8EC6 +DC84 8EC7 +DC85 8EC8 +DC86 8EC9 +DC87 8ECA +DC88 8ECB +DC89 8ECC +DC8A 8ECD +EAA6 8ECE +DC8B 8ECF +DC8C 8ED0 +DC8D 8ED1 +DC8E 8ED2 +DC8F 8ED3 +DC90 8ED4 +DC91 8ED5 +DC92 8ED6 +DC93 8ED7 +DC94 8ED8 +DC95 8ED9 +DC96 8EDA +DC97 8EDB +DC98 8EDC +DC99 8EDD +DC9A 8EDE +DC9B 8EDF +DC9C 8EE0 +DC9D 8EE1 +DC9E 8EE2 +DC9F 8EE3 +DCA0 8EE4 +DD40 8EE5 +DD41 8EE6 +DD42 8EE7 +DD43 8EE8 +DD44 8EE9 +DD45 8EEA +DD46 8EEB +DD47 8EEC +DD48 8EED +DD49 8EEE +DD4A 8EEF +DD4B 8EF0 +DD4C 8EF1 +DD4D 8EF2 +DD4E 8EF3 +DD4F 8EF4 +DD50 8EF5 +DD51 8EF6 +DD52 8EF7 +DD53 8EF8 +DD54 8EF9 +DD55 8EFA +DD56 8EFB +DD57 8EFC +DD58 8EFD +DD59 8EFE +DD5A 8EFF +DD5B 8F00 +DD5C 8F01 +DD5D 8F02 +DD5E 8F03 +DD5F 8F04 +DD60 8F05 +DD61 8F06 +DD62 8F07 +DD63 8F08 +DD64 8F09 +DD65 8F0A +DD66 8F0B +DD67 8F0C +DD68 8F0D +DD69 8F0E +DD6A 8F0F +DD6B 8F10 +DD6C 8F11 +DD6D 8F12 +DD6E 8F13 +DD6F 8F14 +DD70 8F15 +DD71 8F16 +DD72 8F17 +DD73 8F18 +DD74 8F19 +DD75 8F1A +DD76 8F1B +DD77 8F1C +DD78 8F1D +DD79 8F1E +DD7A 8F1F +DD7B 8F20 +DD7C 8F21 +DD7D 8F22 +DD7E 8F23 +DD80 8F24 +DD81 8F25 +DD82 8F26 +DD83 8F27 +DD84 8F28 +DD85 8F29 +DD86 8F2A +DD87 8F2B +DD88 8F2C +DD89 8F2D +DD8A 8F2E +DD8B 8F2F +DD8C 8F30 +DD8D 8F31 +DD8E 8F32 +DD8F 8F33 +DD90 8F34 +DD91 8F35 +DD92 8F36 +DD93 8F37 +DD94 8F38 +DD95 8F39 +DD96 8F3A +DD97 8F3B +DD98 8F3C +DD99 8F3D +DD9A 8F3E +DD9B 8F3F +DD9C 8F40 +DD9D 8F41 +DD9E 8F42 +DD9F 8F43 +DDA0 8F44 +DE40 8F45 +DE41 8F46 +DE42 8F47 +DE43 8F48 +DE44 8F49 +DE45 8F4A +DE46 8F4B +DE47 8F4C +DE48 8F4D +DE49 8F4E +DE4A 8F4F +DE4B 8F50 +DE4C 8F51 +DE4D 8F52 +DE4E 8F53 +DE4F 8F54 +DE50 8F55 +DE51 8F56 +DE52 8F57 +DE53 8F58 +DE54 8F59 +DE55 8F5A +DE56 8F5B +DE57 8F5C +DE58 8F5D +DE59 8F5E +DE5A 8F5F +DE5B 8F60 +DE5C 8F61 +DE5D 8F62 +DE5E 8F63 +DE5F 8F64 +DE60 8F65 +B3B5 8F66 +D4FE 8F67 +B9EC 8F68 +D0F9 8F69 +DE61 8F6A +E9ED 8F6B +D7AA 8F6C +E9EE 8F6D +C2D6 8F6E +C8ED 8F6F +BAE4 8F70 +E9EF 8F71 +E9F0 8F72 +E9F1 8F73 +D6E1 8F74 +E9F2 8F75 +E9F3 8F76 +E9F5 8F77 +E9F4 8F78 +E9F6 8F79 +E9F7 8F7A +C7E1 8F7B +E9F8 8F7C +D4D8 8F7D +E9F9 8F7E +BDCE 8F7F +DE62 8F80 +E9FA 8F81 +E9FB 8F82 +BDCF 8F83 +E9FC 8F84 +B8A8 8F85 +C1BE 8F86 +E9FD 8F87 +B1B2 8F88 +BBD4 8F89 +B9F5 8F8A +E9FE 8F8B +DE63 8F8C +EAA1 8F8D +EAA2 8F8E +EAA3 8F8F +B7F8 8F90 +BCAD 8F91 +DE64 8F92 +CAE4 8F93 +E0CE 8F94 +D4AF 8F95 +CFBD 8F96 +D5B7 8F97 +EAA4 8F98 +D5DE 8F99 +EAA5 8F9A +D0C1 8F9B +B9BC 8F9C +DE65 8F9D +B4C7 8F9E +B1D9 8F9F +DE66 8FA0 +DE67 8FA1 +DE68 8FA2 +C0B1 8FA3 +DE69 8FA4 +DE6A 8FA5 +DE6B 8FA6 +DE6C 8FA7 +B1E6 8FA8 +B1E7 8FA9 +DE6D 8FAA +B1E8 8FAB +DE6E 8FAC +DE6F 8FAD +DE70 8FAE +DE71 8FAF +B3BD 8FB0 +C8E8 8FB1 +DE72 8FB2 +DE73 8FB3 +DE74 8FB4 +DE75 8FB5 +E5C1 8FB6 +DE76 8FB7 +DE77 8FB8 +B1DF 8FB9 +DE78 8FBA +DE79 8FBB +DE7A 8FBC +C1C9 8FBD +B4EF 8FBE +DE7B 8FBF +DE7C 8FC0 +C7A8 8FC1 +D3D8 8FC2 +DE7D 8FC3 +C6F9 8FC4 +D1B8 8FC5 +DE7E 8FC6 +B9FD 8FC7 +C2F5 8FC8 +DE80 8FC9 +DE81 8FCA +DE82 8FCB +DE83 8FCC +DE84 8FCD +D3AD 8FCE +DE85 8FCF +D4CB 8FD0 +BDFC 8FD1 +DE86 8FD2 +E5C2 8FD3 +B7B5 8FD4 +E5C3 8FD5 +DE87 8FD6 +DE88 8FD7 +BBB9 8FD8 +D5E2 8FD9 +DE89 8FDA +BDF8 8FDB +D4B6 8FDC +CEA5 8FDD +C1AC 8FDE +B3D9 8FDF +DE8A 8FE0 +DE8B 8FE1 +CCF6 8FE2 +DE8C 8FE3 +E5C6 8FE4 +E5C4 8FE5 +E5C8 8FE6 +DE8D 8FE7 +E5CA 8FE8 +E5C7 8FE9 +B5CF 8FEA +C6C8 8FEB +DE8E 8FEC +B5FC 8FED +E5C5 8FEE +DE8F 8FEF +CAF6 8FF0 +DE90 8FF1 +DE91 8FF2 +E5C9 8FF3 +DE92 8FF4 +DE93 8FF5 +DE94 8FF6 +C3D4 8FF7 +B1C5 8FF8 +BCA3 8FF9 +DE95 8FFA +DE96 8FFB +DE97 8FFC +D7B7 8FFD +DE98 8FFE +DE99 8FFF +CDCB 9000 +CBCD 9001 +CACA 9002 +CCD3 9003 +E5CC 9004 +E5CB 9005 +C4E6 9006 +DE9A 9007 +DE9B 9008 +D1A1 9009 +D1B7 900A +E5CD 900B +DE9C 900C +E5D0 900D +DE9D 900E +CDB8 900F +D6F0 9010 +E5CF 9011 +B5DD 9012 +DE9E 9013 +CDBE 9014 +DE9F 9015 +E5D1 9016 +B6BA 9017 +DEA0 9018 +DF40 9019 +CDA8 901A +B9E4 901B +DF41 901C +CAC5 901D +B3D1 901E +CBD9 901F +D4EC 9020 +E5D2 9021 +B7EA 9022 +DF42 9023 +DF43 9024 +DF44 9025 +E5CE 9026 +DF45 9027 +DF46 9028 +DF47 9029 +DF48 902A +DF49 902B +DF4A 902C +E5D5 902D +B4FE 902E +E5D6 902F +DF4B 9030 +DF4C 9031 +DF4D 9032 +DF4E 9033 +DF4F 9034 +E5D3 9035 +E5D4 9036 +DF50 9037 +D2DD 9038 +DF51 9039 +DF52 903A +C2DF 903B +B1C6 903C +DF53 903D +D3E2 903E +DF54 903F +DF55 9040 +B6DD 9041 +CBEC 9042 +DF56 9043 +E5D7 9044 +DF57 9045 +DF58 9046 +D3F6 9047 +DF59 9048 +DF5A 9049 +DF5B 904A +DF5C 904B +DF5D 904C +B1E9 904D +DF5E 904E +B6F4 904F +E5DA 9050 +E5D8 9051 +E5D9 9052 +B5C0 9053 +DF5F 9054 +DF60 9055 +DF61 9056 +D2C5 9057 +E5DC 9058 +DF62 9059 +DF63 905A +E5DE 905B +DF64 905C +DF65 905D +DF66 905E +DF67 905F +DF68 9060 +DF69 9061 +E5DD 9062 +C7B2 9063 +DF6A 9064 +D2A3 9065 +DF6B 9066 +DF6C 9067 +E5DB 9068 +DF6D 9069 +DF6E 906A +DF6F 906B +DF70 906C +D4E2 906D +D5DA 906E +DF71 906F +DF72 9070 +DF73 9071 +DF74 9072 +DF75 9073 +E5E0 9074 +D7F1 9075 +DF76 9076 +DF77 9077 +DF78 9078 +DF79 9079 +DF7A 907A +DF7B 907B +DF7C 907C +E5E1 907D +DF7D 907E +B1DC 907F +D1FB 9080 +DF7E 9081 +E5E2 9082 +E5E4 9083 +DF80 9084 +DF81 9085 +DF82 9086 +DF83 9087 +E5E3 9088 +DF84 9089 +DF85 908A +E5E5 908B +DF86 908C +DF87 908D +DF88 908E +DF89 908F +DF8A 9090 +D2D8 9091 +DF8B 9092 +B5CB 9093 +DF8C 9094 +E7DF 9095 +DF8D 9096 +DAF5 9097 +DF8E 9098 +DAF8 9099 +DF8F 909A +DAF6 909B +DF90 909C +DAF7 909D +DF91 909E +DF92 909F +DF93 90A0 +DAFA 90A1 +D0CF 90A2 +C4C7 90A3 +DF94 90A4 +DF95 90A5 +B0EE 90A6 +DF96 90A7 +DF97 90A8 +DF98 90A9 +D0B0 90AA +DF99 90AB +DAF9 90AC +DF9A 90AD +D3CA 90AE +BAAA 90AF +DBA2 90B0 +C7F1 90B1 +DF9B 90B2 +DAFC 90B3 +DAFB 90B4 +C9DB 90B5 +DAFD 90B6 +DF9C 90B7 +DBA1 90B8 +D7DE 90B9 +DAFE 90BA +C1DA 90BB +DF9D 90BC +DF9E 90BD +DBA5 90BE +DF9F 90BF +DFA0 90C0 +D3F4 90C1 +E040 90C2 +E041 90C3 +DBA7 90C4 +DBA4 90C5 +E042 90C6 +DBA8 90C7 +E043 90C8 +E044 90C9 +BDBC 90CA +E045 90CB +E046 90CC +E047 90CD +C0C9 90CE +DBA3 90CF +DBA6 90D0 +D6A3 90D1 +E048 90D2 +DBA9 90D3 +E049 90D4 +E04A 90D5 +E04B 90D6 +DBAD 90D7 +E04C 90D8 +E04D 90D9 +E04E 90DA +DBAE 90DB +DBAC 90DC +BAC2 90DD +E04F 90DE +E050 90DF +E051 90E0 +BFA4 90E1 +DBAB 90E2 +E052 90E3 +E053 90E4 +E054 90E5 +DBAA 90E6 +D4C7 90E7 +B2BF 90E8 +E055 90E9 +E056 90EA +DBAF 90EB +E057 90EC +B9F9 90ED +E058 90EE +DBB0 90EF +E059 90F0 +E05A 90F1 +E05B 90F2 +E05C 90F3 +B3BB 90F4 +E05D 90F5 +E05E 90F6 +E05F 90F7 +B5A6 90F8 +E060 90F9 +E061 90FA +E062 90FB +E063 90FC +B6BC 90FD +DBB1 90FE +E064 90FF +E065 9100 +E066 9101 +B6F5 9102 +E067 9103 +DBB2 9104 +E068 9105 +E069 9106 +E06A 9107 +E06B 9108 +E06C 9109 +E06D 910A +E06E 910B +E06F 910C +E070 910D +E071 910E +E072 910F +E073 9110 +E074 9111 +E075 9112 +E076 9113 +E077 9114 +E078 9115 +E079 9116 +E07A 9117 +E07B 9118 +B1C9 9119 +E07C 911A +E07D 911B +E07E 911C +E080 911D +DBB4 911E +E081 911F +E082 9120 +E083 9121 +DBB3 9122 +DBB5 9123 +E084 9124 +E085 9125 +E086 9126 +E087 9127 +E088 9128 +E089 9129 +E08A 912A +E08B 912B +E08C 912C +E08D 912D +E08E 912E +DBB7 912F +E08F 9130 +DBB6 9131 +E090 9132 +E091 9133 +E092 9134 +E093 9135 +E094 9136 +E095 9137 +E096 9138 +DBB8 9139 +E097 913A +E098 913B +E099 913C +E09A 913D +E09B 913E +E09C 913F +E09D 9140 +E09E 9141 +E09F 9142 +DBB9 9143 +E0A0 9144 +E140 9145 +DBBA 9146 +E141 9147 +E142 9148 +D3CF 9149 +F4FA 914A +C7F5 914B +D7C3 914C +C5E4 914D +F4FC 914E +F4FD 914F +F4FB 9150 +E143 9151 +BEC6 9152 +E144 9153 +E145 9154 +E146 9155 +E147 9156 +D0EF 9157 +E148 9158 +E149 9159 +B7D3 915A +E14A 915B +E14B 915C +D4CD 915D +CCAA 915E +E14C 915F +E14D 9160 +F5A2 9161 +F5A1 9162 +BAA8 9163 +F4FE 9164 +CBD6 9165 +E14E 9166 +E14F 9167 +E150 9168 +F5A4 9169 +C0D2 916A +E151 916B +B3EA 916C +E152 916D +CDAA 916E +F5A5 916F +F5A3 9170 +BDB4 9171 +F5A8 9172 +E153 9173 +F5A9 9174 +BDCD 9175 +C3B8 9176 +BFE1 9177 +CBE1 9178 +F5AA 9179 +E154 917A +E155 917B +E156 917C +F5A6 917D +F5A7 917E +C4F0 917F +E157 9180 +E158 9181 +E159 9182 +E15A 9183 +E15B 9184 +F5AC 9185 +E15C 9186 +B4BC 9187 +E15D 9188 +D7ED 9189 +E15E 918A +B4D7 918B +F5AB 918C +F5AE 918D +E15F 918E +E160 918F +F5AD 9190 +F5AF 9191 +D0D1 9192 +E161 9193 +E162 9194 +E163 9195 +E164 9196 +E165 9197 +E166 9198 +E167 9199 +C3D1 919A +C8A9 919B +E168 919C +E169 919D +E16A 919E +E16B 919F +E16C 91A0 +E16D 91A1 +F5B0 91A2 +F5B1 91A3 +E16E 91A4 +E16F 91A5 +E170 91A6 +E171 91A7 +E172 91A8 +E173 91A9 +F5B2 91AA +E174 91AB +E175 91AC +F5B3 91AD +F5B4 91AE +F5B5 91AF +E176 91B0 +E177 91B1 +E178 91B2 +E179 91B3 +F5B7 91B4 +F5B6 91B5 +E17A 91B6 +E17B 91B7 +E17C 91B8 +E17D 91B9 +F5B8 91BA +E17E 91BB +E180 91BC +E181 91BD +E182 91BE +E183 91BF +E184 91C0 +E185 91C1 +E186 91C2 +E187 91C3 +E188 91C4 +E189 91C5 +E18A 91C6 +B2C9 91C7 +E18B 91C8 +D3D4 91C9 +CACD 91CA +E18C 91CB +C0EF 91CC +D6D8 91CD +D2B0 91CE +C1BF 91CF +E18D 91D0 +BDF0 91D1 +E18E 91D2 +E18F 91D3 +E190 91D4 +E191 91D5 +E192 91D6 +E193 91D7 +E194 91D8 +E195 91D9 +E196 91DA +E197 91DB +B8AA 91DC +E198 91DD +E199 91DE +E19A 91DF +E19B 91E0 +E19C 91E1 +E19D 91E2 +E19E 91E3 +E19F 91E4 +E1A0 91E5 +E240 91E6 +E241 91E7 +E242 91E8 +E243 91E9 +E244 91EA +E245 91EB +E246 91EC +E247 91ED +E248 91EE +E249 91EF +E24A 91F0 +E24B 91F1 +E24C 91F2 +E24D 91F3 +E24E 91F4 +E24F 91F5 +E250 91F6 +E251 91F7 +E252 91F8 +E253 91F9 +E254 91FA +E255 91FB +E256 91FC +E257 91FD +E258 91FE +E259 91FF +E25A 9200 +E25B 9201 +E25C 9202 +E25D 9203 +E25E 9204 +E25F 9205 +E260 9206 +E261 9207 +E262 9208 +E263 9209 +E264 920A +E265 920B +E266 920C +E267 920D +E268 920E +E269 920F +E26A 9210 +E26B 9211 +E26C 9212 +E26D 9213 +E26E 9214 +E26F 9215 +E270 9216 +E271 9217 +E272 9218 +E273 9219 +E274 921A +E275 921B +E276 921C +E277 921D +E278 921E +E279 921F +E27A 9220 +E27B 9221 +E27C 9222 +E27D 9223 +E27E 9224 +E280 9225 +E281 9226 +E282 9227 +E283 9228 +E284 9229 +E285 922A +E286 922B +E287 922C +E288 922D +E289 922E +E28A 922F +E28B 9230 +E28C 9231 +E28D 9232 +E28E 9233 +E28F 9234 +E290 9235 +E291 9236 +E292 9237 +E293 9238 +E294 9239 +E295 923A +E296 923B +E297 923C +E298 923D +E299 923E +E29A 923F +E29B 9240 +E29C 9241 +E29D 9242 +E29E 9243 +E29F 9244 +E2A0 9245 +E340 9246 +E341 9247 +E342 9248 +E343 9249 +E344 924A +E345 924B +E346 924C +E347 924D +E348 924E +E349 924F +E34A 9250 +E34B 9251 +E34C 9252 +E34D 9253 +E34E 9254 +E34F 9255 +E350 9256 +E351 9257 +E352 9258 +E353 9259 +E354 925A +E355 925B +E356 925C +E357 925D +E358 925E +E359 925F +E35A 9260 +E35B 9261 +E35C 9262 +E35D 9263 +E35E 9264 +E35F 9265 +E360 9266 +E361 9267 +E362 9268 +E363 9269 +E364 926A +E365 926B +E366 926C +E367 926D +E368 926E +E369 926F +E36A 9270 +E36B 9271 +E36C 9272 +E36D 9273 +BCF8 9274 +E36E 9275 +E36F 9276 +E370 9277 +E371 9278 +E372 9279 +E373 927A +E374 927B +E375 927C +E376 927D +E377 927E +E378 927F +E379 9280 +E37A 9281 +E37B 9282 +E37C 9283 +E37D 9284 +E37E 9285 +E380 9286 +E381 9287 +E382 9288 +E383 9289 +E384 928A +E385 928B +E386 928C +E387 928D +F6C6 928E +E388 928F +E389 9290 +E38A 9291 +E38B 9292 +E38C 9293 +E38D 9294 +E38E 9295 +E38F 9296 +E390 9297 +E391 9298 +E392 9299 +E393 929A +E394 929B +E395 929C +E396 929D +E397 929E +E398 929F +E399 92A0 +E39A 92A1 +E39B 92A2 +E39C 92A3 +E39D 92A4 +E39E 92A5 +E39F 92A6 +E3A0 92A7 +E440 92A8 +E441 92A9 +E442 92AA +E443 92AB +E444 92AC +E445 92AD +F6C7 92AE +E446 92AF +E447 92B0 +E448 92B1 +E449 92B2 +E44A 92B3 +E44B 92B4 +E44C 92B5 +E44D 92B6 +E44E 92B7 +E44F 92B8 +E450 92B9 +E451 92BA +E452 92BB +E453 92BC +E454 92BD +E455 92BE +E456 92BF +E457 92C0 +E458 92C1 +E459 92C2 +E45A 92C3 +E45B 92C4 +E45C 92C5 +E45D 92C6 +E45E 92C7 +F6C8 92C8 +E45F 92C9 +E460 92CA +E461 92CB +E462 92CC +E463 92CD +E464 92CE +E465 92CF +E466 92D0 +E467 92D1 +E468 92D2 +E469 92D3 +E46A 92D4 +E46B 92D5 +E46C 92D6 +E46D 92D7 +E46E 92D8 +E46F 92D9 +E470 92DA +E471 92DB +E472 92DC +E473 92DD +E474 92DE +E475 92DF +E476 92E0 +E477 92E1 +E478 92E2 +E479 92E3 +E47A 92E4 +E47B 92E5 +E47C 92E6 +E47D 92E7 +E47E 92E8 +E480 92E9 +E481 92EA +E482 92EB +E483 92EC +E484 92ED +E485 92EE +E486 92EF +E487 92F0 +E488 92F1 +E489 92F2 +E48A 92F3 +E48B 92F4 +E48C 92F5 +E48D 92F6 +E48E 92F7 +E48F 92F8 +E490 92F9 +E491 92FA +E492 92FB +E493 92FC +E494 92FD +E495 92FE +E496 92FF +E497 9300 +E498 9301 +E499 9302 +E49A 9303 +E49B 9304 +E49C 9305 +E49D 9306 +E49E 9307 +E49F 9308 +E4A0 9309 +E540 930A +E541 930B +E542 930C +E543 930D +E544 930E +E545 930F +E546 9310 +E547 9311 +E548 9312 +E549 9313 +E54A 9314 +E54B 9315 +E54C 9316 +E54D 9317 +E54E 9318 +E54F 9319 +E550 931A +E551 931B +E552 931C +E553 931D +E554 931E +E555 931F +E556 9320 +E557 9321 +E558 9322 +E559 9323 +E55A 9324 +E55B 9325 +E55C 9326 +E55D 9327 +E55E 9328 +E55F 9329 +E560 932A +E561 932B +E562 932C +E563 932D +E564 932E +E565 932F +E566 9330 +E567 9331 +E568 9332 +E569 9333 +E56A 9334 +E56B 9335 +E56C 9336 +E56D 9337 +E56E 9338 +E56F 9339 +E570 933A +E571 933B +E572 933C +E573 933D +F6C9 933E +E574 933F +E575 9340 +E576 9341 +E577 9342 +E578 9343 +E579 9344 +E57A 9345 +E57B 9346 +E57C 9347 +E57D 9348 +E57E 9349 +E580 934A +E581 934B +E582 934C +E583 934D +E584 934E +E585 934F +E586 9350 +E587 9351 +E588 9352 +E589 9353 +E58A 9354 +E58B 9355 +E58C 9356 +E58D 9357 +E58E 9358 +E58F 9359 +E590 935A +E591 935B +E592 935C +E593 935D +E594 935E +E595 935F +E596 9360 +E597 9361 +E598 9362 +E599 9363 +E59A 9364 +E59B 9365 +E59C 9366 +E59D 9367 +E59E 9368 +E59F 9369 +F6CA 936A +E5A0 936B +E640 936C +E641 936D +E642 936E +E643 936F +E644 9370 +E645 9371 +E646 9372 +E647 9373 +E648 9374 +E649 9375 +E64A 9376 +E64B 9377 +E64C 9378 +E64D 9379 +E64E 937A +E64F 937B +E650 937C +E651 937D +E652 937E +E653 937F +E654 9380 +E655 9381 +E656 9382 +E657 9383 +E658 9384 +E659 9385 +E65A 9386 +E65B 9387 +E65C 9388 +E65D 9389 +E65E 938A +E65F 938B +E660 938C +E661 938D +E662 938E +F6CC 938F +E663 9390 +E664 9391 +E665 9392 +E666 9393 +E667 9394 +E668 9395 +E669 9396 +E66A 9397 +E66B 9398 +E66C 9399 +E66D 939A +E66E 939B +E66F 939C +E670 939D +E671 939E +E672 939F +E673 93A0 +E674 93A1 +E675 93A2 +E676 93A3 +E677 93A4 +E678 93A5 +E679 93A6 +E67A 93A7 +E67B 93A8 +E67C 93A9 +E67D 93AA +E67E 93AB +E680 93AC +E681 93AD +E682 93AE +E683 93AF +E684 93B0 +E685 93B1 +E686 93B2 +E687 93B3 +E688 93B4 +E689 93B5 +E68A 93B6 +E68B 93B7 +E68C 93B8 +E68D 93B9 +E68E 93BA +E68F 93BB +E690 93BC +E691 93BD +E692 93BE +E693 93BF +E694 93C0 +E695 93C1 +E696 93C2 +E697 93C3 +E698 93C4 +E699 93C5 +E69A 93C6 +E69B 93C7 +E69C 93C8 +E69D 93C9 +F6CB 93CA +E69E 93CB +E69F 93CC +E6A0 93CD +E740 93CE +E741 93CF +E742 93D0 +E743 93D1 +E744 93D2 +E745 93D3 +E746 93D4 +E747 93D5 +F7E9 93D6 +E748 93D7 +E749 93D8 +E74A 93D9 +E74B 93DA +E74C 93DB +E74D 93DC +E74E 93DD +E74F 93DE +E750 93DF +E751 93E0 +E752 93E1 +E753 93E2 +E754 93E3 +E755 93E4 +E756 93E5 +E757 93E6 +E758 93E7 +E759 93E8 +E75A 93E9 +E75B 93EA +E75C 93EB +E75D 93EC +E75E 93ED +E75F 93EE +E760 93EF +E761 93F0 +E762 93F1 +E763 93F2 +E764 93F3 +E765 93F4 +E766 93F5 +E767 93F6 +E768 93F7 +E769 93F8 +E76A 93F9 +E76B 93FA +E76C 93FB +E76D 93FC +E76E 93FD +E76F 93FE +E770 93FF +E771 9400 +E772 9401 +E773 9402 +E774 9403 +E775 9404 +E776 9405 +E777 9406 +E778 9407 +E779 9408 +E77A 9409 +E77B 940A +E77C 940B +E77D 940C +E77E 940D +E780 940E +E781 940F +E782 9410 +E783 9411 +E784 9412 +E785 9413 +E786 9414 +E787 9415 +E788 9416 +E789 9417 +E78A 9418 +E78B 9419 +E78C 941A +E78D 941B +E78E 941C +E78F 941D +E790 941E +E791 941F +E792 9420 +E793 9421 +E794 9422 +E795 9423 +E796 9424 +E797 9425 +E798 9426 +E799 9427 +E79A 9428 +E79B 9429 +E79C 942A +E79D 942B +E79E 942C +E79F 942D +E7A0 942E +E840 942F +E841 9430 +E842 9431 +E843 9432 +E844 9433 +E845 9434 +E846 9435 +E847 9436 +E848 9437 +E849 9438 +E84A 9439 +E84B 943A +E84C 943B +E84D 943C +E84E 943D +F6CD 943E +E84F 943F +E850 9440 +E851 9441 +E852 9442 +E853 9443 +E854 9444 +E855 9445 +E856 9446 +E857 9447 +E858 9448 +E859 9449 +E85A 944A +E85B 944B +E85C 944C +E85D 944D +E85E 944E +E85F 944F +E860 9450 +E861 9451 +E862 9452 +E863 9453 +E864 9454 +E865 9455 +E866 9456 +E867 9457 +E868 9458 +E869 9459 +E86A 945A +E86B 945B +E86C 945C +E86D 945D +E86E 945E +E86F 945F +E870 9460 +E871 9461 +E872 9462 +E873 9463 +E874 9464 +E875 9465 +E876 9466 +E877 9467 +E878 9468 +E879 9469 +E87A 946A +F6CE 946B +E87B 946C +E87C 946D +E87D 946E +E87E 946F +E880 9470 +E881 9471 +E882 9472 +E883 9473 +E884 9474 +E885 9475 +E886 9476 +E887 9477 +E888 9478 +E889 9479 +E88A 947A +E88B 947B +E88C 947C +E88D 947D +E88E 947E +E88F 947F +E890 9480 +E891 9481 +E892 9482 +E893 9483 +E894 9484 +EEC4 9485 +EEC5 9486 +EEC6 9487 +D5EB 9488 +B6A4 9489 +EEC8 948A +EEC7 948B +EEC9 948C +EECA 948D +C7A5 948E +EECB 948F +EECC 9490 +E895 9491 +B7B0 9492 +B5F6 9493 +EECD 9494 +EECF 9495 +E896 9496 +EECE 9497 +E897 9498 +B8C6 9499 +EED0 949A +EED1 949B +EED2 949C +B6DB 949D +B3AE 949E +D6D3 949F +C4C6 94A0 +B1B5 94A1 +B8D6 94A2 +EED3 94A3 +EED4 94A4 +D4BF 94A5 +C7D5 94A6 +BEFB 94A7 +CED9 94A8 +B9B3 94A9 +EED6 94AA +EED5 94AB +EED8 94AC +EED7 94AD +C5A5 94AE +EED9 94AF +EEDA 94B0 +C7AE 94B1 +EEDB 94B2 +C7AF 94B3 +EEDC 94B4 +B2A7 94B5 +EEDD 94B6 +EEDE 94B7 +EEDF 94B8 +EEE0 94B9 +EEE1 94BA +D7EA 94BB +EEE2 94BC +EEE3 94BD +BCD8 94BE +EEE4 94BF +D3CB 94C0 +CCFA 94C1 +B2AC 94C2 +C1E5 94C3 +EEE5 94C4 +C7A6 94C5 +C3AD 94C6 +E898 94C7 +EEE6 94C8 +EEE7 94C9 +EEE8 94CA +EEE9 94CB +EEEA 94CC +EEEB 94CD +EEEC 94CE +E899 94CF +EEED 94D0 +EEEE 94D1 +EEEF 94D2 +E89A 94D3 +E89B 94D4 +EEF0 94D5 +EEF1 94D6 +EEF2 94D7 +EEF4 94D8 +EEF3 94D9 +E89C 94DA +EEF5 94DB +CDAD 94DC +C2C1 94DD +EEF6 94DE +EEF7 94DF +EEF8 94E0 +D5A1 94E1 +EEF9 94E2 +CFB3 94E3 +EEFA 94E4 +EEFB 94E5 +E89D 94E6 +EEFC 94E7 +EEFD 94E8 +EFA1 94E9 +EEFE 94EA +EFA2 94EB +B8F5 94EC +C3FA 94ED +EFA3 94EE +EFA4 94EF +BDC2 94F0 +D2BF 94F1 +B2F9 94F2 +EFA5 94F3 +EFA6 94F4 +EFA7 94F5 +D2F8 94F6 +EFA8 94F7 +D6FD 94F8 +EFA9 94F9 +C6CC 94FA +E89E 94FB +EFAA 94FC +EFAB 94FD +C1B4 94FE +EFAC 94FF +CFFA 9500 +CBF8 9501 +EFAE 9502 +EFAD 9503 +B3FA 9504 +B9F8 9505 +EFAF 9506 +EFB0 9507 +D0E2 9508 +EFB1 9509 +EFB2 950A +B7E6 950B +D0BF 950C +EFB3 950D +EFB4 950E +EFB5 950F +C8F1 9510 +CCE0 9511 +EFB6 9512 +EFB7 9513 +EFB8 9514 +EFB9 9515 +EFBA 9516 +D5E0 9517 +EFBB 9518 +B4ED 9519 +C3AA 951A +EFBC 951B +E89F 951C +EFBD 951D +EFBE 951E +EFBF 951F +E8A0 9520 +CEFD 9521 +EFC0 9522 +C2E0 9523 +B4B8 9524 +D7B6 9525 +BDF5 9526 +E940 9527 +CFC7 9528 +EFC3 9529 +EFC1 952A +EFC2 952B +EFC4 952C +B6A7 952D +BCFC 952E +BEE2 952F +C3CC 9530 +EFC5 9531 +EFC6 9532 +E941 9533 +EFC7 9534 +EFCF 9535 +EFC8 9536 +EFC9 9537 +EFCA 9538 +C7C2 9539 +EFF1 953A +B6CD 953B +EFCB 953C +E942 953D +EFCC 953E +EFCD 953F +B6C6 9540 +C3BE 9541 +EFCE 9542 +E943 9543 +EFD0 9544 +EFD1 9545 +EFD2 9546 +D5F2 9547 +E944 9548 +EFD3 9549 +C4F7 954A +E945 954B +EFD4 954C +C4F8 954D +EFD5 954E +EFD6 954F +B8E4 9550 +B0F7 9551 +EFD7 9552 +EFD8 9553 +EFD9 9554 +E946 9555 +EFDA 9556 +EFDB 9557 +EFDC 9558 +EFDD 9559 +E947 955A +EFDE 955B +BEB5 955C +EFE1 955D +EFDF 955E +EFE0 955F +E948 9560 +EFE2 9561 +EFE3 9562 +C1CD 9563 +EFE4 9564 +EFE5 9565 +EFE6 9566 +EFE7 9567 +EFE8 9568 +EFE9 9569 +EFEA 956A +EFEB 956B +EFEC 956C +C0D8 956D +E949 956E +EFED 956F +C1AD 9570 +EFEE 9571 +EFEF 9572 +EFF0 9573 +E94A 9574 +E94B 9575 +CFE2 9576 +E94C 9577 +E94D 9578 +E94E 9579 +E94F 957A +E950 957B +E951 957C +E952 957D +E953 957E +B3A4 957F +E954 9580 +E955 9581 +E956 9582 +E957 9583 +E958 9584 +E959 9585 +E95A 9586 +E95B 9587 +E95C 9588 +E95D 9589 +E95E 958A +E95F 958B +E960 958C +E961 958D +E962 958E +E963 958F +E964 9590 +E965 9591 +E966 9592 +E967 9593 +E968 9594 +E969 9595 +E96A 9596 +E96B 9597 +E96C 9598 +E96D 9599 +E96E 959A +E96F 959B +E970 959C +E971 959D +E972 959E +E973 959F +E974 95A0 +E975 95A1 +E976 95A2 +E977 95A3 +E978 95A4 +E979 95A5 +E97A 95A6 +E97B 95A7 +E97C 95A8 +E97D 95A9 +E97E 95AA +E980 95AB +E981 95AC +E982 95AD +E983 95AE +E984 95AF +E985 95B0 +E986 95B1 +E987 95B2 +E988 95B3 +E989 95B4 +E98A 95B5 +E98B 95B6 +E98C 95B7 +E98D 95B8 +E98E 95B9 +E98F 95BA +E990 95BB +E991 95BC +E992 95BD +E993 95BE +E994 95BF +E995 95C0 +E996 95C1 +E997 95C2 +E998 95C3 +E999 95C4 +E99A 95C5 +E99B 95C6 +E99C 95C7 +E99D 95C8 +E99E 95C9 +E99F 95CA +E9A0 95CB +EA40 95CC +EA41 95CD +EA42 95CE +EA43 95CF +EA44 95D0 +EA45 95D1 +EA46 95D2 +EA47 95D3 +EA48 95D4 +EA49 95D5 +EA4A 95D6 +EA4B 95D7 +EA4C 95D8 +EA4D 95D9 +EA4E 95DA +EA4F 95DB +EA50 95DC +EA51 95DD +EA52 95DE +EA53 95DF +EA54 95E0 +EA55 95E1 +EA56 95E2 +EA57 95E3 +EA58 95E4 +EA59 95E5 +EA5A 95E6 +EA5B 95E7 +C3C5 95E8 +E3C5 95E9 +C9C1 95EA +E3C6 95EB +EA5C 95EC +B1D5 95ED +CECA 95EE +B4B3 95EF +C8F2 95F0 +E3C7 95F1 +CFD0 95F2 +E3C8 95F3 +BCE4 95F4 +E3C9 95F5 +E3CA 95F6 +C3C6 95F7 +D5A2 95F8 +C4D6 95F9 +B9EB 95FA +CEC5 95FB +E3CB 95FC +C3F6 95FD +E3CC 95FE +EA5D 95FF +B7A7 9600 +B8F3 9601 +BAD2 9602 +E3CD 9603 +E3CE 9604 +D4C4 9605 +E3CF 9606 +EA5E 9607 +E3D0 9608 +D1CB 9609 +E3D1 960A +E3D2 960B +E3D3 960C +E3D4 960D +D1D6 960E +E3D5 960F +B2FB 9610 +C0BB 9611 +E3D6 9612 +EA5F 9613 +C0AB 9614 +E3D7 9615 +E3D8 9616 +E3D9 9617 +EA60 9618 +E3DA 9619 +E3DB 961A +EA61 961B +B8B7 961C +DAE2 961D +EA62 961E +B6D3 961F +EA63 9620 +DAE4 9621 +DAE3 9622 +EA64 9623 +EA65 9624 +EA66 9625 +EA67 9626 +EA68 9627 +EA69 9628 +EA6A 9629 +DAE6 962A +EA6B 962B +EA6C 962C +EA6D 962D +C8EE 962E +EA6E 962F +EA6F 9630 +DAE5 9631 +B7C0 9632 +D1F4 9633 +D2F5 9634 +D5F3 9635 +BDD7 9636 +EA70 9637 +EA71 9638 +EA72 9639 +EA73 963A +D7E8 963B +DAE8 963C +DAE7 963D +EA74 963E +B0A2 963F +CDD3 9640 +EA75 9641 +DAE9 9642 +EA76 9643 +B8BD 9644 +BCCA 9645 +C2BD 9646 +C2A4 9647 +B3C2 9648 +DAEA 9649 +EA77 964A +C2AA 964B +C4B0 964C +BDB5 964D +EA78 964E +EA79 964F +CFDE 9650 +EA7A 9651 +EA7B 9652 +EA7C 9653 +DAEB 9654 +C9C2 9655 +EA7D 9656 +EA7E 9657 +EA80 9658 +EA81 9659 +EA82 965A +B1DD 965B +EA83 965C +EA84 965D +EA85 965E +DAEC 965F +EA86 9660 +B6B8 9661 +D4BA 9662 +EA87 9663 +B3FD 9664 +EA88 9665 +EA89 9666 +DAED 9667 +D4C9 9668 +CFD5 9669 +C5E3 966A +EA8A 966B +DAEE 966C +EA8B 966D +EA8C 966E +EA8D 966F +EA8E 9670 +EA8F 9671 +DAEF 9672 +EA90 9673 +DAF0 9674 +C1EA 9675 +CCD5 9676 +CFDD 9677 +EA91 9678 +EA92 9679 +EA93 967A +EA94 967B +EA95 967C +EA96 967D +EA97 967E +EA98 967F +EA99 9680 +EA9A 9681 +EA9B 9682 +EA9C 9683 +EA9D 9684 +D3E7 9685 +C2A1 9686 +EA9E 9687 +DAF1 9688 +EA9F 9689 +EAA0 968A +CBE5 968B +EB40 968C +DAF2 968D +EB41 968E +CBE6 968F +D2FE 9690 +EB42 9691 +EB43 9692 +EB44 9693 +B8F4 9694 +EB45 9695 +EB46 9696 +DAF3 9697 +B0AF 9698 +CFB6 9699 +EB47 969A +EB48 969B +D5CF 969C +EB49 969D +EB4A 969E +EB4B 969F +EB4C 96A0 +EB4D 96A1 +EB4E 96A2 +EB4F 96A3 +EB50 96A4 +EB51 96A5 +EB52 96A6 +CBED 96A7 +EB53 96A8 +EB54 96A9 +EB55 96AA +EB56 96AB +EB57 96AC +EB58 96AD +EB59 96AE +EB5A 96AF +DAF4 96B0 +EB5B 96B1 +EB5C 96B2 +E3C4 96B3 +EB5D 96B4 +EB5E 96B5 +C1A5 96B6 +EB5F 96B7 +EB60 96B8 +F6BF 96B9 +EB61 96BA +EB62 96BB +F6C0 96BC +F6C1 96BD +C4D1 96BE +EB63 96BF +C8B8 96C0 +D1E3 96C1 +EB64 96C2 +EB65 96C3 +D0DB 96C4 +D1C5 96C5 +BCAF 96C6 +B9CD 96C7 +EB66 96C8 +EFF4 96C9 +EB67 96CA +EB68 96CB +B4C6 96CC +D3BA 96CD +F6C2 96CE +B3FB 96CF +EB69 96D0 +EB6A 96D1 +F6C3 96D2 +EB6B 96D3 +EB6C 96D4 +B5F1 96D5 +EB6D 96D6 +EB6E 96D7 +EB6F 96D8 +EB70 96D9 +EB71 96DA +EB72 96DB +EB73 96DC +EB74 96DD +EB75 96DE +EB76 96DF +F6C5 96E0 +EB77 96E1 +EB78 96E2 +EB79 96E3 +EB7A 96E4 +EB7B 96E5 +EB7C 96E6 +EB7D 96E7 +D3EA 96E8 +F6A7 96E9 +D1A9 96EA +EB7E 96EB +EB80 96EC +EB81 96ED +EB82 96EE +F6A9 96EF +EB83 96F0 +EB84 96F1 +EB85 96F2 +F6A8 96F3 +EB86 96F4 +EB87 96F5 +C1E3 96F6 +C0D7 96F7 +EB88 96F8 +B1A2 96F9 +EB89 96FA +EB8A 96FB +EB8B 96FC +EB8C 96FD +CEED 96FE +EB8D 96FF +D0E8 9700 +F6AB 9701 +EB8E 9702 +EB8F 9703 +CFF6 9704 +EB90 9705 +F6AA 9706 +D5F0 9707 +F6AC 9708 +C3B9 9709 +EB91 970A +EB92 970B +EB93 970C +BBF4 970D +F6AE 970E +F6AD 970F +EB94 9710 +EB95 9711 +EB96 9712 +C4DE 9713 +EB97 9714 +EB98 9715 +C1D8 9716 +EB99 9717 +EB9A 9718 +EB9B 9719 +EB9C 971A +EB9D 971B +CBAA 971C +EB9E 971D +CFBC 971E +EB9F 971F +EBA0 9720 +EC40 9721 +EC41 9722 +EC42 9723 +EC43 9724 +EC44 9725 +EC45 9726 +EC46 9727 +EC47 9728 +EC48 9729 +F6AF 972A +EC49 972B +EC4A 972C +F6B0 972D +EC4B 972E +EC4C 972F +F6B1 9730 +EC4D 9731 +C2B6 9732 +EC4E 9733 +EC4F 9734 +EC50 9735 +EC51 9736 +EC52 9737 +B0D4 9738 +C5F9 9739 +EC53 973A +EC54 973B +EC55 973C +EC56 973D +F6B2 973E +EC57 973F +EC58 9740 +EC59 9741 +EC5A 9742 +EC5B 9743 +EC5C 9744 +EC5D 9745 +EC5E 9746 +EC5F 9747 +EC60 9748 +EC61 9749 +EC62 974A +EC63 974B +EC64 974C +EC65 974D +EC66 974E +EC67 974F +EC68 9750 +EC69 9751 +C7E0 9752 +F6A6 9753 +EC6A 9754 +EC6B 9755 +BEB8 9756 +EC6C 9757 +EC6D 9758 +BEB2 9759 +EC6E 975A +B5E5 975B +EC6F 975C +EC70 975D +B7C7 975E +EC71 975F +BFBF 9760 +C3D2 9761 +C3E6 9762 +EC72 9763 +EC73 9764 +D8CC 9765 +EC74 9766 +EC75 9767 +EC76 9768 +B8EF 9769 +EC77 976A +EC78 976B +EC79 976C +EC7A 976D +EC7B 976E +EC7C 976F +EC7D 9770 +EC7E 9771 +EC80 9772 +BDF9 9773 +D1A5 9774 +EC81 9775 +B0D0 9776 +EC82 9777 +EC83 9778 +EC84 9779 +EC85 977A +EC86 977B +F7B0 977C +EC87 977D +EC88 977E +EC89 977F +EC8A 9780 +EC8B 9781 +EC8C 9782 +EC8D 9783 +EC8E 9784 +F7B1 9785 +EC8F 9786 +EC90 9787 +EC91 9788 +EC92 9789 +EC93 978A +D0AC 978B +EC94 978C +B0B0 978D +EC95 978E +EC96 978F +EC97 9790 +F7B2 9791 +F7B3 9792 +EC98 9793 +F7B4 9794 +EC99 9795 +EC9A 9796 +EC9B 9797 +C7CA 9798 +EC9C 9799 +EC9D 979A +EC9E 979B +EC9F 979C +ECA0 979D +ED40 979E +ED41 979F +BECF 97A0 +ED42 97A1 +ED43 97A2 +F7B7 97A3 +ED44 97A4 +ED45 97A5 +ED46 97A6 +ED47 97A7 +ED48 97A8 +ED49 97A9 +ED4A 97AA +F7B6 97AB +ED4B 97AC +B1DE 97AD +ED4C 97AE +F7B5 97AF +ED4D 97B0 +ED4E 97B1 +F7B8 97B2 +ED4F 97B3 +F7B9 97B4 +ED50 97B5 +ED51 97B6 +ED52 97B7 +ED53 97B8 +ED54 97B9 +ED55 97BA +ED56 97BB +ED57 97BC +ED58 97BD +ED59 97BE +ED5A 97BF +ED5B 97C0 +ED5C 97C1 +ED5D 97C2 +ED5E 97C3 +ED5F 97C4 +ED60 97C5 +ED61 97C6 +ED62 97C7 +ED63 97C8 +ED64 97C9 +ED65 97CA +ED66 97CB +ED67 97CC +ED68 97CD +ED69 97CE +ED6A 97CF +ED6B 97D0 +ED6C 97D1 +ED6D 97D2 +ED6E 97D3 +ED6F 97D4 +ED70 97D5 +ED71 97D6 +ED72 97D7 +ED73 97D8 +ED74 97D9 +ED75 97DA +ED76 97DB +ED77 97DC +ED78 97DD +ED79 97DE +ED7A 97DF +ED7B 97E0 +ED7C 97E1 +ED7D 97E2 +ED7E 97E3 +ED80 97E4 +ED81 97E5 +CEA4 97E6 +C8CD 97E7 +ED82 97E8 +BAAB 97E9 +E8B8 97EA +E8B9 97EB +E8BA 97EC +BEC2 97ED +ED83 97EE +ED84 97EF +ED85 97F0 +ED86 97F1 +ED87 97F2 +D2F4 97F3 +ED88 97F4 +D4CF 97F5 +C9D8 97F6 +ED89 97F7 +ED8A 97F8 +ED8B 97F9 +ED8C 97FA +ED8D 97FB +ED8E 97FC +ED8F 97FD +ED90 97FE +ED91 97FF +ED92 9800 +ED93 9801 +ED94 9802 +ED95 9803 +ED96 9804 +ED97 9805 +ED98 9806 +ED99 9807 +ED9A 9808 +ED9B 9809 +ED9C 980A +ED9D 980B +ED9E 980C +ED9F 980D +EDA0 980E +EE40 980F +EE41 9810 +EE42 9811 +EE43 9812 +EE44 9813 +EE45 9814 +EE46 9815 +EE47 9816 +EE48 9817 +EE49 9818 +EE4A 9819 +EE4B 981A +EE4C 981B +EE4D 981C +EE4E 981D +EE4F 981E +EE50 981F +EE51 9820 +EE52 9821 +EE53 9822 +EE54 9823 +EE55 9824 +EE56 9825 +EE57 9826 +EE58 9827 +EE59 9828 +EE5A 9829 +EE5B 982A +EE5C 982B +EE5D 982C +EE5E 982D +EE5F 982E +EE60 982F +EE61 9830 +EE62 9831 +EE63 9832 +EE64 9833 +EE65 9834 +EE66 9835 +EE67 9836 +EE68 9837 +EE69 9838 +EE6A 9839 +EE6B 983A +EE6C 983B +EE6D 983C +EE6E 983D +EE6F 983E +EE70 983F +EE71 9840 +EE72 9841 +EE73 9842 +EE74 9843 +EE75 9844 +EE76 9845 +EE77 9846 +EE78 9847 +EE79 9848 +EE7A 9849 +EE7B 984A +EE7C 984B +EE7D 984C +EE7E 984D +EE80 984E +EE81 984F +EE82 9850 +EE83 9851 +EE84 9852 +EE85 9853 +EE86 9854 +EE87 9855 +EE88 9856 +EE89 9857 +EE8A 9858 +EE8B 9859 +EE8C 985A +EE8D 985B +EE8E 985C +EE8F 985D +EE90 985E +EE91 985F +EE92 9860 +EE93 9861 +EE94 9862 +EE95 9863 +EE96 9864 +EE97 9865 +EE98 9866 +EE99 9867 +EE9A 9868 +EE9B 9869 +EE9C 986A +EE9D 986B +EE9E 986C +EE9F 986D +EEA0 986E +EF40 986F +EF41 9870 +EF42 9871 +EF43 9872 +EF44 9873 +EF45 9874 +D2B3 9875 +B6A5 9876 +C7EA 9877 +F1FC 9878 +CFEE 9879 +CBB3 987A +D0EB 987B +E7EF 987C +CDE7 987D +B9CB 987E +B6D9 987F +F1FD 9880 +B0E4 9881 +CBCC 9882 +F1FE 9883 +D4A4 9884 +C2AD 9885 +C1EC 9886 +C6C4 9887 +BEB1 9888 +F2A1 9889 +BCD5 988A +EF46 988B +F2A2 988C +F2A3 988D +EF47 988E +F2A4 988F +D2C3 9890 +C6B5 9891 +EF48 9892 +CDC7 9893 +F2A5 9894 +EF49 9895 +D3B1 9896 +BFC5 9897 +CCE2 9898 +EF4A 9899 +F2A6 989A +F2A7 989B +D1D5 989C +B6EE 989D +F2A8 989E +F2A9 989F +B5DF 98A0 +F2AA 98A1 +F2AB 98A2 +EF4B 98A3 +B2FC 98A4 +F2AC 98A5 +F2AD 98A6 +C8A7 98A7 +EF4C 98A8 +EF4D 98A9 +EF4E 98AA +EF4F 98AB +EF50 98AC +EF51 98AD +EF52 98AE +EF53 98AF +EF54 98B0 +EF55 98B1 +EF56 98B2 +EF57 98B3 +EF58 98B4 +EF59 98B5 +EF5A 98B6 +EF5B 98B7 +EF5C 98B8 +EF5D 98B9 +EF5E 98BA +EF5F 98BB +EF60 98BC +EF61 98BD +EF62 98BE +EF63 98BF +EF64 98C0 +EF65 98C1 +EF66 98C2 +EF67 98C3 +EF68 98C4 +EF69 98C5 +EF6A 98C6 +EF6B 98C7 +EF6C 98C8 +EF6D 98C9 +EF6E 98CA +EF6F 98CB +EF70 98CC +EF71 98CD +B7E7 98CE +EF72 98CF +EF73 98D0 +ECA9 98D1 +ECAA 98D2 +ECAB 98D3 +EF74 98D4 +ECAC 98D5 +EF75 98D6 +EF76 98D7 +C6AE 98D8 +ECAD 98D9 +ECAE 98DA +EF77 98DB +EF78 98DC +EF79 98DD +B7C9 98DE +CAB3 98DF +EF7A 98E0 +EF7B 98E1 +EF7C 98E2 +EF7D 98E3 +EF7E 98E4 +EF80 98E5 +EF81 98E6 +E2B8 98E7 +F7CF 98E8 +EF82 98E9 +EF83 98EA +EF84 98EB +EF85 98EC +EF86 98ED +EF87 98EE +EF88 98EF +EF89 98F0 +EF8A 98F1 +EF8B 98F2 +EF8C 98F3 +EF8D 98F4 +EF8E 98F5 +EF8F 98F6 +EF90 98F7 +EF91 98F8 +EF92 98F9 +EF93 98FA +EF94 98FB +EF95 98FC +EF96 98FD +EF97 98FE +EF98 98FF +EF99 9900 +EF9A 9901 +EF9B 9902 +EF9C 9903 +EF9D 9904 +EF9E 9905 +EF9F 9906 +EFA0 9907 +F040 9908 +F041 9909 +F042 990A +F043 990B +F044 990C +F7D0 990D +F045 990E +F046 990F +B2CD 9910 +F047 9911 +F048 9912 +F049 9913 +F04A 9914 +F04B 9915 +F04C 9916 +F04D 9917 +F04E 9918 +F04F 9919 +F050 991A +F051 991B +F052 991C +F053 991D +F054 991E +F055 991F +F056 9920 +F057 9921 +F058 9922 +F059 9923 +F05A 9924 +F05B 9925 +F05C 9926 +F05D 9927 +F05E 9928 +F05F 9929 +F060 992A +F061 992B +F062 992C +F063 992D +F7D1 992E +F064 992F +F065 9930 +F066 9931 +F067 9932 +F068 9933 +F069 9934 +F06A 9935 +F06B 9936 +F06C 9937 +F06D 9938 +F06E 9939 +F06F 993A +F070 993B +F071 993C +F072 993D +F073 993E +F074 993F +F075 9940 +F076 9941 +F077 9942 +F078 9943 +F079 9944 +F07A 9945 +F07B 9946 +F07C 9947 +F07D 9948 +F07E 9949 +F080 994A +F081 994B +F082 994C +F083 994D +F084 994E +F085 994F +F086 9950 +F087 9951 +F088 9952 +F089 9953 +F7D3 9954 +F7D2 9955 +F08A 9956 +F08B 9957 +F08C 9958 +F08D 9959 +F08E 995A +F08F 995B +F090 995C +F091 995D +F092 995E +F093 995F +F094 9960 +F095 9961 +F096 9962 +E2BB 9963 +F097 9964 +BCA2 9965 +F098 9966 +E2BC 9967 +E2BD 9968 +E2BE 9969 +E2BF 996A +E2C0 996B +E2C1 996C +B7B9 996D +D2FB 996E +BDA4 996F +CACE 9970 +B1A5 9971 +CBC7 9972 +F099 9973 +E2C2 9974 +B6FC 9975 +C8C4 9976 +E2C3 9977 +F09A 9978 +F09B 9979 +BDC8 997A +F09C 997B +B1FD 997C +E2C4 997D +F09D 997E +B6F6 997F +E2C5 9980 +C4D9 9981 +F09E 9982 +F09F 9983 +E2C6 9984 +CFDA 9985 +B9DD 9986 +E2C7 9987 +C0A1 9988 +F0A0 9989 +E2C8 998A +B2F6 998B +F140 998C +E2C9 998D +F141 998E +C1F3 998F +E2CA 9990 +E2CB 9991 +C2F8 9992 +E2CC 9993 +E2CD 9994 +E2CE 9995 +CAD7 9996 +D8B8 9997 +D9E5 9998 +CFE3 9999 +F142 999A +F143 999B +F144 999C +F145 999D +F146 999E +F147 999F +F148 99A0 +F149 99A1 +F14A 99A2 +F14B 99A3 +F14C 99A4 +F0A5 99A5 +F14D 99A6 +F14E 99A7 +DCB0 99A8 +F14F 99A9 +F150 99AA +F151 99AB +F152 99AC +F153 99AD +F154 99AE +F155 99AF +F156 99B0 +F157 99B1 +F158 99B2 +F159 99B3 +F15A 99B4 +F15B 99B5 +F15C 99B6 +F15D 99B7 +F15E 99B8 +F15F 99B9 +F160 99BA +F161 99BB +F162 99BC +F163 99BD +F164 99BE +F165 99BF +F166 99C0 +F167 99C1 +F168 99C2 +F169 99C3 +F16A 99C4 +F16B 99C5 +F16C 99C6 +F16D 99C7 +F16E 99C8 +F16F 99C9 +F170 99CA +F171 99CB +F172 99CC +F173 99CD +F174 99CE +F175 99CF +F176 99D0 +F177 99D1 +F178 99D2 +F179 99D3 +F17A 99D4 +F17B 99D5 +F17C 99D6 +F17D 99D7 +F17E 99D8 +F180 99D9 +F181 99DA +F182 99DB +F183 99DC +F184 99DD +F185 99DE +F186 99DF +F187 99E0 +F188 99E1 +F189 99E2 +F18A 99E3 +F18B 99E4 +F18C 99E5 +F18D 99E6 +F18E 99E7 +F18F 99E8 +F190 99E9 +F191 99EA +F192 99EB +F193 99EC +F194 99ED +F195 99EE +F196 99EF +F197 99F0 +F198 99F1 +F199 99F2 +F19A 99F3 +F19B 99F4 +F19C 99F5 +F19D 99F6 +F19E 99F7 +F19F 99F8 +F1A0 99F9 +F240 99FA +F241 99FB +F242 99FC +F243 99FD +F244 99FE +F245 99FF +F246 9A00 +F247 9A01 +F248 9A02 +F249 9A03 +F24A 9A04 +F24B 9A05 +F24C 9A06 +F24D 9A07 +F24E 9A08 +F24F 9A09 +F250 9A0A +F251 9A0B +F252 9A0C +F253 9A0D +F254 9A0E +F255 9A0F +F256 9A10 +F257 9A11 +F258 9A12 +F259 9A13 +F25A 9A14 +F25B 9A15 +F25C 9A16 +F25D 9A17 +F25E 9A18 +F25F 9A19 +F260 9A1A +F261 9A1B +F262 9A1C +F263 9A1D +F264 9A1E +F265 9A1F +F266 9A20 +F267 9A21 +F268 9A22 +F269 9A23 +F26A 9A24 +F26B 9A25 +F26C 9A26 +F26D 9A27 +F26E 9A28 +F26F 9A29 +F270 9A2A +F271 9A2B +F272 9A2C +F273 9A2D +F274 9A2E +F275 9A2F +F276 9A30 +F277 9A31 +F278 9A32 +F279 9A33 +F27A 9A34 +F27B 9A35 +F27C 9A36 +F27D 9A37 +F27E 9A38 +F280 9A39 +F281 9A3A +F282 9A3B +F283 9A3C +F284 9A3D +F285 9A3E +F286 9A3F +F287 9A40 +F288 9A41 +F289 9A42 +F28A 9A43 +F28B 9A44 +F28C 9A45 +F28D 9A46 +F28E 9A47 +F28F 9A48 +F290 9A49 +F291 9A4A +F292 9A4B +F293 9A4C +F294 9A4D +F295 9A4E +F296 9A4F +F297 9A50 +F298 9A51 +F299 9A52 +F29A 9A53 +F29B 9A54 +F29C 9A55 +F29D 9A56 +F29E 9A57 +F29F 9A58 +F2A0 9A59 +F340 9A5A +F341 9A5B +F342 9A5C +F343 9A5D +F344 9A5E +F345 9A5F +F346 9A60 +F347 9A61 +F348 9A62 +F349 9A63 +F34A 9A64 +F34B 9A65 +F34C 9A66 +F34D 9A67 +F34E 9A68 +F34F 9A69 +F350 9A6A +F351 9A6B +C2ED 9A6C +D4A6 9A6D +CDD4 9A6E +D1B1 9A6F +B3DB 9A70 +C7FD 9A71 +F352 9A72 +B2B5 9A73 +C2BF 9A74 +E6E0 9A75 +CABB 9A76 +E6E1 9A77 +E6E2 9A78 +BED4 9A79 +E6E3 9A7A +D7A4 9A7B +CDD5 9A7C +E6E5 9A7D +BCDD 9A7E +E6E4 9A7F +E6E6 9A80 +E6E7 9A81 +C2EE 9A82 +F353 9A83 +BDBE 9A84 +E6E8 9A85 +C2E6 9A86 +BAA7 9A87 +E6E9 9A88 +F354 9A89 +E6EA 9A8A +B3D2 9A8B +D1E9 9A8C +F355 9A8D +F356 9A8E +BFA5 9A8F +E6EB 9A90 +C6EF 9A91 +E6EC 9A92 +E6ED 9A93 +F357 9A94 +F358 9A95 +E6EE 9A96 +C6AD 9A97 +E6EF 9A98 +F359 9A99 +C9A7 9A9A +E6F0 9A9B +E6F1 9A9C +E6F2 9A9D +E5B9 9A9E +E6F3 9A9F +E6F4 9AA0 +C2E2 9AA1 +E6F5 9AA2 +E6F6 9AA3 +D6E8 9AA4 +E6F7 9AA5 +F35A 9AA6 +E6F8 9AA7 +B9C7 9AA8 +F35B 9AA9 +F35C 9AAA +F35D 9AAB +F35E 9AAC +F35F 9AAD +F360 9AAE +F361 9AAF +F7BB 9AB0 +F7BA 9AB1 +F362 9AB2 +F363 9AB3 +F364 9AB4 +F365 9AB5 +F7BE 9AB6 +F7BC 9AB7 +BAA1 9AB8 +F366 9AB9 +F7BF 9ABA +F367 9ABB +F7C0 9ABC +F368 9ABD +F369 9ABE +F36A 9ABF +F7C2 9AC0 +F7C1 9AC1 +F7C4 9AC2 +F36B 9AC3 +F36C 9AC4 +F7C3 9AC5 +F36D 9AC6 +F36E 9AC7 +F36F 9AC8 +F370 9AC9 +F371 9ACA +F7C5 9ACB +F7C6 9ACC +F372 9ACD +F373 9ACE +F374 9ACF +F375 9AD0 +F7C7 9AD1 +F376 9AD2 +CBE8 9AD3 +F377 9AD4 +F378 9AD5 +F379 9AD6 +F37A 9AD7 +B8DF 9AD8 +F37B 9AD9 +F37C 9ADA +F37D 9ADB +F37E 9ADC +F380 9ADD +F381 9ADE +F7D4 9ADF +F382 9AE0 +F7D5 9AE1 +F383 9AE2 +F384 9AE3 +F385 9AE4 +F386 9AE5 +F7D6 9AE6 +F387 9AE7 +F388 9AE8 +F389 9AE9 +F38A 9AEA +F7D8 9AEB +F38B 9AEC +F7DA 9AED +F38C 9AEE +F7D7 9AEF +F38D 9AF0 +F38E 9AF1 +F38F 9AF2 +F390 9AF3 +F391 9AF4 +F392 9AF5 +F393 9AF6 +F394 9AF7 +F395 9AF8 +F7DB 9AF9 +F396 9AFA +F7D9 9AFB +F397 9AFC +F398 9AFD +F399 9AFE +F39A 9AFF +F39B 9B00 +F39C 9B01 +F39D 9B02 +D7D7 9B03 +F39E 9B04 +F39F 9B05 +F3A0 9B06 +F440 9B07 +F7DC 9B08 +F441 9B09 +F442 9B0A +F443 9B0B +F444 9B0C +F445 9B0D +F446 9B0E +F7DD 9B0F +F447 9B10 +F448 9B11 +F449 9B12 +F7DE 9B13 +F44A 9B14 +F44B 9B15 +F44C 9B16 +F44D 9B17 +F44E 9B18 +F44F 9B19 +F450 9B1A +F451 9B1B +F452 9B1C +F453 9B1D +F454 9B1E +F7DF 9B1F +F455 9B20 +F456 9B21 +F457 9B22 +F7E0 9B23 +F458 9B24 +F459 9B25 +F45A 9B26 +F45B 9B27 +F45C 9B28 +F45D 9B29 +F45E 9B2A +F45F 9B2B +F460 9B2C +F461 9B2D +F462 9B2E +DBCB 9B2F +F463 9B30 +F464 9B31 +D8AA 9B32 +F465 9B33 +F466 9B34 +F467 9B35 +F468 9B36 +F469 9B37 +F46A 9B38 +F46B 9B39 +F46C 9B3A +E5F7 9B3B +B9ED 9B3C +F46D 9B3D +F46E 9B3E +F46F 9B3F +F470 9B40 +BFFD 9B41 +BBEA 9B42 +F7C9 9B43 +C6C7 9B44 +F7C8 9B45 +F471 9B46 +F7CA 9B47 +F7CC 9B48 +F7CB 9B49 +F472 9B4A +F473 9B4B +F474 9B4C +F7CD 9B4D +F475 9B4E +CEBA 9B4F +F476 9B50 +F7CE 9B51 +F477 9B52 +F478 9B53 +C4A7 9B54 +F479 9B55 +F47A 9B56 +F47B 9B57 +F47C 9B58 +F47D 9B59 +F47E 9B5A +F480 9B5B +F481 9B5C +F482 9B5D +F483 9B5E +F484 9B5F +F485 9B60 +F486 9B61 +F487 9B62 +F488 9B63 +F489 9B64 +F48A 9B65 +F48B 9B66 +F48C 9B67 +F48D 9B68 +F48E 9B69 +F48F 9B6A +F490 9B6B +F491 9B6C +F492 9B6D +F493 9B6E +F494 9B6F +F495 9B70 +F496 9B71 +F497 9B72 +F498 9B73 +F499 9B74 +F49A 9B75 +F49B 9B76 +F49C 9B77 +F49D 9B78 +F49E 9B79 +F49F 9B7A +F4A0 9B7B +F540 9B7C +F541 9B7D +F542 9B7E +F543 9B7F +F544 9B80 +F545 9B81 +F546 9B82 +F547 9B83 +F548 9B84 +F549 9B85 +F54A 9B86 +F54B 9B87 +F54C 9B88 +F54D 9B89 +F54E 9B8A +F54F 9B8B +F550 9B8C +F551 9B8D +F552 9B8E +F553 9B8F +F554 9B90 +F555 9B91 +F556 9B92 +F557 9B93 +F558 9B94 +F559 9B95 +F55A 9B96 +F55B 9B97 +F55C 9B98 +F55D 9B99 +F55E 9B9A +F55F 9B9B +F560 9B9C +F561 9B9D +F562 9B9E +F563 9B9F +F564 9BA0 +F565 9BA1 +F566 9BA2 +F567 9BA3 +F568 9BA4 +F569 9BA5 +F56A 9BA6 +F56B 9BA7 +F56C 9BA8 +F56D 9BA9 +F56E 9BAA +F56F 9BAB +F570 9BAC +F571 9BAD +F572 9BAE +F573 9BAF +F574 9BB0 +F575 9BB1 +F576 9BB2 +F577 9BB3 +F578 9BB4 +F579 9BB5 +F57A 9BB6 +F57B 9BB7 +F57C 9BB8 +F57D 9BB9 +F57E 9BBA +F580 9BBB +F581 9BBC +F582 9BBD +F583 9BBE +F584 9BBF +F585 9BC0 +F586 9BC1 +F587 9BC2 +F588 9BC3 +F589 9BC4 +F58A 9BC5 +F58B 9BC6 +F58C 9BC7 +F58D 9BC8 +F58E 9BC9 +F58F 9BCA +F590 9BCB +F591 9BCC +F592 9BCD +F593 9BCE +F594 9BCF +F595 9BD0 +F596 9BD1 +F597 9BD2 +F598 9BD3 +F599 9BD4 +F59A 9BD5 +F59B 9BD6 +F59C 9BD7 +F59D 9BD8 +F59E 9BD9 +F59F 9BDA +F5A0 9BDB +F640 9BDC +F641 9BDD +F642 9BDE +F643 9BDF +F644 9BE0 +F645 9BE1 +F646 9BE2 +F647 9BE3 +F648 9BE4 +F649 9BE5 +F64A 9BE6 +F64B 9BE7 +F64C 9BE8 +F64D 9BE9 +F64E 9BEA +F64F 9BEB +F650 9BEC +F651 9BED +F652 9BEE +F653 9BEF +F654 9BF0 +F655 9BF1 +F656 9BF2 +F657 9BF3 +F658 9BF4 +F659 9BF5 +F65A 9BF6 +F65B 9BF7 +F65C 9BF8 +F65D 9BF9 +F65E 9BFA +F65F 9BFB +F660 9BFC +F661 9BFD +F662 9BFE +F663 9BFF +F664 9C00 +F665 9C01 +F666 9C02 +F667 9C03 +F668 9C04 +F669 9C05 +F66A 9C06 +F66B 9C07 +F66C 9C08 +F66D 9C09 +F66E 9C0A +F66F 9C0B +F670 9C0C +F671 9C0D +F672 9C0E +F673 9C0F +F674 9C10 +F675 9C11 +F676 9C12 +F677 9C13 +F678 9C14 +F679 9C15 +F67A 9C16 +F67B 9C17 +F67C 9C18 +F67D 9C19 +F67E 9C1A +F680 9C1B +F681 9C1C +F682 9C1D +F683 9C1E +F684 9C1F +F685 9C20 +F686 9C21 +F687 9C22 +F688 9C23 +F689 9C24 +F68A 9C25 +F68B 9C26 +F68C 9C27 +F68D 9C28 +F68E 9C29 +F68F 9C2A +F690 9C2B +F691 9C2C +F692 9C2D +F693 9C2E +F694 9C2F +F695 9C30 +F696 9C31 +F697 9C32 +F698 9C33 +F699 9C34 +F69A 9C35 +F69B 9C36 +F69C 9C37 +F69D 9C38 +F69E 9C39 +F69F 9C3A +F6A0 9C3B +F740 9C3C +F741 9C3D +F742 9C3E +F743 9C3F +F744 9C40 +F745 9C41 +F746 9C42 +F747 9C43 +F748 9C44 +F749 9C45 +F74A 9C46 +F74B 9C47 +F74C 9C48 +F74D 9C49 +F74E 9C4A +F74F 9C4B +F750 9C4C +F751 9C4D +F752 9C4E +F753 9C4F +F754 9C50 +F755 9C51 +F756 9C52 +F757 9C53 +F758 9C54 +F759 9C55 +F75A 9C56 +F75B 9C57 +F75C 9C58 +F75D 9C59 +F75E 9C5A +F75F 9C5B +F760 9C5C +F761 9C5D +F762 9C5E +F763 9C5F +F764 9C60 +F765 9C61 +F766 9C62 +F767 9C63 +F768 9C64 +F769 9C65 +F76A 9C66 +F76B 9C67 +F76C 9C68 +F76D 9C69 +F76E 9C6A +F76F 9C6B +F770 9C6C +F771 9C6D +F772 9C6E +F773 9C6F +F774 9C70 +F775 9C71 +F776 9C72 +F777 9C73 +F778 9C74 +F779 9C75 +F77A 9C76 +F77B 9C77 +F77C 9C78 +F77D 9C79 +F77E 9C7A +F780 9C7B +D3E3 9C7C +F781 9C7D +F782 9C7E +F6CF 9C7F +F783 9C80 +C2B3 9C81 +F6D0 9C82 +F784 9C83 +F785 9C84 +F6D1 9C85 +F6D2 9C86 +F6D3 9C87 +F6D4 9C88 +F786 9C89 +F787 9C8A +F6D6 9C8B +F788 9C8C +B1AB 9C8D +F6D7 9C8E +F789 9C8F +F6D8 9C90 +F6D9 9C91 +F6DA 9C92 +F78A 9C93 +F6DB 9C94 +F6DC 9C95 +F78B 9C96 +F78C 9C97 +F78D 9C98 +F78E 9C99 +F6DD 9C9A +F6DE 9C9B +CFCA 9C9C +F78F 9C9D +F6DF 9C9E +F6E0 9C9F +F6E1 9CA0 +F6E2 9CA1 +F6E3 9CA2 +F6E4 9CA3 +C0F0 9CA4 +F6E5 9CA5 +F6E6 9CA6 +F6E7 9CA7 +F6E8 9CA8 +F6E9 9CA9 +F790 9CAA +F6EA 9CAB +F791 9CAC +F6EB 9CAD +F6EC 9CAE +F792 9CAF +F6ED 9CB0 +F6EE 9CB1 +F6EF 9CB2 +F6F0 9CB3 +F6F1 9CB4 +F6F2 9CB5 +F6F3 9CB6 +F6F4 9CB7 +BEA8 9CB8 +F793 9CB9 +F6F5 9CBA +F6F6 9CBB +F6F7 9CBC +F6F8 9CBD +F794 9CBE +F795 9CBF +F796 9CC0 +F797 9CC1 +F798 9CC2 +C8FA 9CC3 +F6F9 9CC4 +F6FA 9CC5 +F6FB 9CC6 +F6FC 9CC7 +F799 9CC8 +F79A 9CC9 +F6FD 9CCA +F6FE 9CCB +F7A1 9CCC +F7A2 9CCD +F7A3 9CCE +F7A4 9CCF +F7A5 9CD0 +F79B 9CD1 +F79C 9CD2 +F7A6 9CD3 +F7A7 9CD4 +F7A8 9CD5 +B1EE 9CD6 +F7A9 9CD7 +F7AA 9CD8 +F7AB 9CD9 +F79D 9CDA +F79E 9CDB +F7AC 9CDC +F7AD 9CDD +C1DB 9CDE +F7AE 9CDF +F79F 9CE0 +F7A0 9CE1 +F7AF 9CE2 +F840 9CE3 +F841 9CE4 +F842 9CE5 +F843 9CE6 +F844 9CE7 +F845 9CE8 +F846 9CE9 +F847 9CEA +F848 9CEB +F849 9CEC +F84A 9CED +F84B 9CEE +F84C 9CEF +F84D 9CF0 +F84E 9CF1 +F84F 9CF2 +F850 9CF3 +F851 9CF4 +F852 9CF5 +F853 9CF6 +F854 9CF7 +F855 9CF8 +F856 9CF9 +F857 9CFA +F858 9CFB +F859 9CFC +F85A 9CFD +F85B 9CFE +F85C 9CFF +F85D 9D00 +F85E 9D01 +F85F 9D02 +F860 9D03 +F861 9D04 +F862 9D05 +F863 9D06 +F864 9D07 +F865 9D08 +F866 9D09 +F867 9D0A +F868 9D0B +F869 9D0C +F86A 9D0D +F86B 9D0E +F86C 9D0F +F86D 9D10 +F86E 9D11 +F86F 9D12 +F870 9D13 +F871 9D14 +F872 9D15 +F873 9D16 +F874 9D17 +F875 9D18 +F876 9D19 +F877 9D1A +F878 9D1B +F879 9D1C +F87A 9D1D +F87B 9D1E +F87C 9D1F +F87D 9D20 +F87E 9D21 +F880 9D22 +F881 9D23 +F882 9D24 +F883 9D25 +F884 9D26 +F885 9D27 +F886 9D28 +F887 9D29 +F888 9D2A +F889 9D2B +F88A 9D2C +F88B 9D2D +F88C 9D2E +F88D 9D2F +F88E 9D30 +F88F 9D31 +F890 9D32 +F891 9D33 +F892 9D34 +F893 9D35 +F894 9D36 +F895 9D37 +F896 9D38 +F897 9D39 +F898 9D3A +F899 9D3B +F89A 9D3C +F89B 9D3D +F89C 9D3E +F89D 9D3F +F89E 9D40 +F89F 9D41 +F8A0 9D42 +F940 9D43 +F941 9D44 +F942 9D45 +F943 9D46 +F944 9D47 +F945 9D48 +F946 9D49 +F947 9D4A +F948 9D4B +F949 9D4C +F94A 9D4D +F94B 9D4E +F94C 9D4F +F94D 9D50 +F94E 9D51 +F94F 9D52 +F950 9D53 +F951 9D54 +F952 9D55 +F953 9D56 +F954 9D57 +F955 9D58 +F956 9D59 +F957 9D5A +F958 9D5B +F959 9D5C +F95A 9D5D +F95B 9D5E +F95C 9D5F +F95D 9D60 +F95E 9D61 +F95F 9D62 +F960 9D63 +F961 9D64 +F962 9D65 +F963 9D66 +F964 9D67 +F965 9D68 +F966 9D69 +F967 9D6A +F968 9D6B +F969 9D6C +F96A 9D6D +F96B 9D6E +F96C 9D6F +F96D 9D70 +F96E 9D71 +F96F 9D72 +F970 9D73 +F971 9D74 +F972 9D75 +F973 9D76 +F974 9D77 +F975 9D78 +F976 9D79 +F977 9D7A +F978 9D7B +F979 9D7C +F97A 9D7D +F97B 9D7E +F97C 9D7F +F97D 9D80 +F97E 9D81 +F980 9D82 +F981 9D83 +F982 9D84 +F983 9D85 +F984 9D86 +F985 9D87 +F986 9D88 +F987 9D89 +F988 9D8A +F989 9D8B +F98A 9D8C +F98B 9D8D +F98C 9D8E +F98D 9D8F +F98E 9D90 +F98F 9D91 +F990 9D92 +F991 9D93 +F992 9D94 +F993 9D95 +F994 9D96 +F995 9D97 +F996 9D98 +F997 9D99 +F998 9D9A +F999 9D9B +F99A 9D9C +F99B 9D9D +F99C 9D9E +F99D 9D9F +F99E 9DA0 +F99F 9DA1 +F9A0 9DA2 +FA40 9DA3 +FA41 9DA4 +FA42 9DA5 +FA43 9DA6 +FA44 9DA7 +FA45 9DA8 +FA46 9DA9 +FA47 9DAA +FA48 9DAB +FA49 9DAC +FA4A 9DAD +FA4B 9DAE +FA4C 9DAF +FA4D 9DB0 +FA4E 9DB1 +FA4F 9DB2 +FA50 9DB3 +FA51 9DB4 +FA52 9DB5 +FA53 9DB6 +FA54 9DB7 +FA55 9DB8 +FA56 9DB9 +FA57 9DBA +FA58 9DBB +FA59 9DBC +FA5A 9DBD +FA5B 9DBE +FA5C 9DBF +FA5D 9DC0 +FA5E 9DC1 +FA5F 9DC2 +FA60 9DC3 +FA61 9DC4 +FA62 9DC5 +FA63 9DC6 +FA64 9DC7 +FA65 9DC8 +FA66 9DC9 +FA67 9DCA +FA68 9DCB +FA69 9DCC +FA6A 9DCD +FA6B 9DCE +FA6C 9DCF +FA6D 9DD0 +FA6E 9DD1 +FA6F 9DD2 +FA70 9DD3 +FA71 9DD4 +FA72 9DD5 +FA73 9DD6 +FA74 9DD7 +FA75 9DD8 +FA76 9DD9 +FA77 9DDA +FA78 9DDB +FA79 9DDC +FA7A 9DDD +FA7B 9DDE +FA7C 9DDF +FA7D 9DE0 +FA7E 9DE1 +FA80 9DE2 +FA81 9DE3 +FA82 9DE4 +FA83 9DE5 +FA84 9DE6 +FA85 9DE7 +FA86 9DE8 +FA87 9DE9 +FA88 9DEA +FA89 9DEB +FA8A 9DEC +FA8B 9DED +FA8C 9DEE +FA8D 9DEF +FA8E 9DF0 +FA8F 9DF1 +FA90 9DF2 +FA91 9DF3 +FA92 9DF4 +FA93 9DF5 +FA94 9DF6 +FA95 9DF7 +FA96 9DF8 +FA97 9DF9 +FA98 9DFA +FA99 9DFB +FA9A 9DFC +FA9B 9DFD +FA9C 9DFE +FA9D 9DFF +FA9E 9E00 +FA9F 9E01 +FAA0 9E02 +FB40 9E03 +FB41 9E04 +FB42 9E05 +FB43 9E06 +FB44 9E07 +FB45 9E08 +FB46 9E09 +FB47 9E0A +FB48 9E0B +FB49 9E0C +FB4A 9E0D +FB4B 9E0E +FB4C 9E0F +FB4D 9E10 +FB4E 9E11 +FB4F 9E12 +FB50 9E13 +FB51 9E14 +FB52 9E15 +FB53 9E16 +FB54 9E17 +FB55 9E18 +FB56 9E19 +FB57 9E1A +FB58 9E1B +FB59 9E1C +FB5A 9E1D +FB5B 9E1E +C4F1 9E1F +F0AF 9E20 +BCA6 9E21 +F0B0 9E22 +C3F9 9E23 +FB5C 9E24 +C5B8 9E25 +D1BB 9E26 +FB5D 9E27 +F0B1 9E28 +F0B2 9E29 +F0B3 9E2A +F0B4 9E2B +F0B5 9E2C +D1BC 9E2D +FB5E 9E2E +D1EC 9E2F +FB5F 9E30 +F0B7 9E31 +F0B6 9E32 +D4A7 9E33 +FB60 9E34 +CDD2 9E35 +F0B8 9E36 +F0BA 9E37 +F0B9 9E38 +F0BB 9E39 +F0BC 9E3A +FB61 9E3B +FB62 9E3C +B8EB 9E3D +F0BD 9E3E +BAE8 9E3F +FB63 9E40 +F0BE 9E41 +F0BF 9E42 +BEE9 9E43 +F0C0 9E44 +B6EC 9E45 +F0C1 9E46 +F0C2 9E47 +F0C3 9E48 +F0C4 9E49 +C8B5 9E4A +F0C5 9E4B +F0C6 9E4C +FB64 9E4D +F0C7 9E4E +C5F4 9E4F +FB65 9E50 +F0C8 9E51 +FB66 9E52 +FB67 9E53 +FB68 9E54 +F0C9 9E55 +FB69 9E56 +F0CA 9E57 +F7BD 9E58 +FB6A 9E59 +F0CB 9E5A +F0CC 9E5B +F0CD 9E5C +FB6B 9E5D +F0CE 9E5E +FB6C 9E5F +FB6D 9E60 +FB6E 9E61 +FB6F 9E62 +F0CF 9E63 +BAD7 9E64 +FB70 9E65 +F0D0 9E66 +F0D1 9E67 +F0D2 9E68 +F0D3 9E69 +F0D4 9E6A +F0D5 9E6B +F0D6 9E6C +F0D8 9E6D +FB71 9E6E +FB72 9E6F +D3A5 9E70 +F0D7 9E71 +FB73 9E72 +F0D9 9E73 +FB74 9E74 +FB75 9E75 +FB76 9E76 +FB77 9E77 +FB78 9E78 +FB79 9E79 +FB7A 9E7A +FB7B 9E7B +FB7C 9E7C +FB7D 9E7D +F5BA 9E7E +C2B9 9E7F +FB7E 9E80 +FB80 9E81 +F7E4 9E82 +FB81 9E83 +FB82 9E84 +FB83 9E85 +FB84 9E86 +F7E5 9E87 +F7E6 9E88 +FB85 9E89 +FB86 9E8A +F7E7 9E8B +FB87 9E8C +FB88 9E8D +FB89 9E8E +FB8A 9E8F +FB8B 9E90 +FB8C 9E91 +F7E8 9E92 +C2B4 9E93 +FB8D 9E94 +FB8E 9E95 +FB8F 9E96 +FB90 9E97 +FB91 9E98 +FB92 9E99 +FB93 9E9A +FB94 9E9B +FB95 9E9C +F7EA 9E9D +FB96 9E9E +F7EB 9E9F +FB97 9EA0 +FB98 9EA1 +FB99 9EA2 +FB9A 9EA3 +FB9B 9EA4 +FB9C 9EA5 +C2F3 9EA6 +FB9D 9EA7 +FB9E 9EA8 +FB9F 9EA9 +FBA0 9EAA +FC40 9EAB +FC41 9EAC +FC42 9EAD +FC43 9EAE +FC44 9EAF +FC45 9EB0 +FC46 9EB1 +FC47 9EB2 +FC48 9EB3 +F4F0 9EB4 +FC49 9EB5 +FC4A 9EB6 +FC4B 9EB7 +F4EF 9EB8 +FC4C 9EB9 +FC4D 9EBA +C2E9 9EBB +FC4E 9EBC +F7E1 9EBD +F7E2 9EBE +FC4F 9EBF +FC50 9EC0 +FC51 9EC1 +FC52 9EC2 +FC53 9EC3 +BBC6 9EC4 +FC54 9EC5 +FC55 9EC6 +FC56 9EC7 +FC57 9EC8 +D9E4 9EC9 +FC58 9ECA +FC59 9ECB +FC5A 9ECC +CAF2 9ECD +C0E8 9ECE +F0A4 9ECF +FC5B 9ED0 +BADA 9ED1 +FC5C 9ED2 +FC5D 9ED3 +C7AD 9ED4 +FC5E 9ED5 +FC5F 9ED6 +FC60 9ED7 +C4AC 9ED8 +FC61 9ED9 +FC62 9EDA +F7EC 9EDB +F7ED 9EDC +F7EE 9EDD +FC63 9EDE +F7F0 9EDF +F7EF 9EE0 +FC64 9EE1 +F7F1 9EE2 +FC65 9EE3 +FC66 9EE4 +F7F4 9EE5 +FC67 9EE6 +F7F3 9EE7 +FC68 9EE8 +F7F2 9EE9 +F7F5 9EEA +FC69 9EEB +FC6A 9EEC +FC6B 9EED +FC6C 9EEE +F7F6 9EEF +FC6D 9EF0 +FC6E 9EF1 +FC6F 9EF2 +FC70 9EF3 +FC71 9EF4 +FC72 9EF5 +FC73 9EF6 +FC74 9EF7 +FC75 9EF8 +EDE9 9EF9 +FC76 9EFA +EDEA 9EFB +EDEB 9EFC +FC77 9EFD +F6BC 9EFE +FC78 9EFF +FC79 9F00 +FC7A 9F01 +FC7B 9F02 +FC7C 9F03 +FC7D 9F04 +FC7E 9F05 +FC80 9F06 +FC81 9F07 +FC82 9F08 +FC83 9F09 +FC84 9F0A +F6BD 9F0B +FC85 9F0C +F6BE 9F0D +B6A6 9F0E +FC86 9F0F +D8BE 9F10 +FC87 9F11 +FC88 9F12 +B9C4 9F13 +FC89 9F14 +FC8A 9F15 +FC8B 9F16 +D8BB 9F17 +FC8C 9F18 +DCB1 9F19 +FC8D 9F1A +FC8E 9F1B +FC8F 9F1C +FC90 9F1D +FC91 9F1E +FC92 9F1F +CAF3 9F20 +FC93 9F21 +F7F7 9F22 +FC94 9F23 +FC95 9F24 +FC96 9F25 +FC97 9F26 +FC98 9F27 +FC99 9F28 +FC9A 9F29 +FC9B 9F2A +FC9C 9F2B +F7F8 9F2C +FC9D 9F2D +FC9E 9F2E +F7F9 9F2F +FC9F 9F30 +FCA0 9F31 +FD40 9F32 +FD41 9F33 +FD42 9F34 +FD43 9F35 +FD44 9F36 +F7FB 9F37 +FD45 9F38 +F7FA 9F39 +FD46 9F3A +B1C7 9F3B +FD47 9F3C +F7FC 9F3D +F7FD 9F3E +FD48 9F3F +FD49 9F40 +FD4A 9F41 +FD4B 9F42 +FD4C 9F43 +F7FE 9F44 +FD4D 9F45 +FD4E 9F46 +FD4F 9F47 +FD50 9F48 +FD51 9F49 +FD52 9F4A +FD53 9F4B +FD54 9F4C +FD55 9F4D +FD56 9F4E +FD57 9F4F +C6EB 9F50 +ECB4 9F51 +FD58 9F52 +FD59 9F53 +FD5A 9F54 +FD5B 9F55 +FD5C 9F56 +FD5D 9F57 +FD5E 9F58 +FD5F 9F59 +FD60 9F5A +FD61 9F5B +FD62 9F5C +FD63 9F5D +FD64 9F5E +FD65 9F5F +FD66 9F60 +FD67 9F61 +FD68 9F62 +FD69 9F63 +FD6A 9F64 +FD6B 9F65 +FD6C 9F66 +FD6D 9F67 +FD6E 9F68 +FD6F 9F69 +FD70 9F6A +FD71 9F6B +FD72 9F6C +FD73 9F6D +FD74 9F6E +FD75 9F6F +FD76 9F70 +FD77 9F71 +FD78 9F72 +FD79 9F73 +FD7A 9F74 +FD7B 9F75 +FD7C 9F76 +FD7D 9F77 +FD7E 9F78 +FD80 9F79 +FD81 9F7A +FD82 9F7B +FD83 9F7C +FD84 9F7D +FD85 9F7E +B3DD 9F7F +F6B3 9F80 +FD86 9F81 +FD87 9F82 +F6B4 9F83 +C1E4 9F84 +F6B5 9F85 +F6B6 9F86 +F6B7 9F87 +F6B8 9F88 +F6B9 9F89 +F6BA 9F8A +C8A3 9F8B +F6BB 9F8C +FD88 9F8D +FD89 9F8E +FD8A 9F8F +FD8B 9F90 +FD8C 9F91 +FD8D 9F92 +FD8E 9F93 +FD8F 9F94 +FD90 9F95 +FD91 9F96 +FD92 9F97 +FD93 9F98 +C1FA 9F99 +B9A8 9F9A +EDE8 9F9B +FD94 9F9C +FD95 9F9D +FD96 9F9E +B9EA 9F9F +D9DF 9FA0 +FD97 9FA1 +FD98 9FA2 +FD99 9FA3 +FD9A 9FA4 +FD9B 9FA5 +82358F33 9FA6 +82358F34 9FA7 +82358F35 9FA8 +82358F36 9FA9 +82358F37 9FAA +82358F38 9FAB +82358F39 9FAC +82359030 9FAD +82359031 9FAE +82359032 9FAF +82359033 9FB0 +82359034 9FB1 +82359035 9FB2 +82359036 9FB3 +82359037 9FB4 +82359038 9FB5 +82359039 9FB6 +82359130 9FB7 +82359131 9FB8 +82359132 9FB9 +82359133 9FBA +82359134 9FBB +82359135 9FBC +82359136 9FBD +82359137 9FBE +82359138 9FBF +82359139 9FC0 +82359230 9FC1 +82359231 9FC2 +82359232 9FC3 +82359233 9FC4 +82359234 9FC5 +82359235 9FC6 +82359236 9FC7 +82359237 9FC8 +82359238 9FC9 +82359239 9FCA +82359330 9FCB +82359331 9FCC +82359332 9FCD +82359333 9FCE +82359334 9FCF +82359335 9FD0 +82359336 9FD1 +82359337 9FD2 +82359338 9FD3 +82359339 9FD4 +82359430 9FD5 +82359431 9FD6 +82359432 9FD7 +82359433 9FD8 +82359434 9FD9 +82359435 9FDA +82359436 9FDB +82359437 9FDC +82359438 9FDD +82359439 9FDE +82359530 9FDF +82359531 9FE0 +82359532 9FE1 +82359533 9FE2 +82359534 9FE3 +82359535 9FE4 +82359536 9FE5 +82359537 9FE6 +82359538 9FE7 +82359539 9FE8 +82359630 9FE9 +82359631 9FEA +82359632 9FEB +82359633 9FEC +82359634 9FED +82359635 9FEE +82359636 9FEF +82359637 9FF0 +82359638 9FF1 +82359639 9FF2 +82359730 9FF3 +82359731 9FF4 +82359732 9FF5 +82359733 9FF6 +82359734 9FF7 +82359735 9FF8 +82359736 9FF9 +82359737 9FFA +82359738 9FFB +82359739 9FFC +82359830 9FFD +82359831 9FFE +82359832 9FFF +82359833 A000 +82359834 A001 +82359835 A002 +82359836 A003 +82359837 A004 +82359838 A005 +82359839 A006 +82359930 A007 +82359931 A008 +82359932 A009 +82359933 A00A +82359934 A00B +82359935 A00C +82359936 A00D +82359937 A00E +82359938 A00F +82359939 A010 +82359A30 A011 +82359A31 A012 +82359A32 A013 +82359A33 A014 +82359A34 A015 +82359A35 A016 +82359A36 A017 +82359A37 A018 +82359A38 A019 +82359A39 A01A +82359B30 A01B +82359B31 A01C +82359B32 A01D +82359B33 A01E +82359B34 A01F +82359B35 A020 +82359B36 A021 +82359B37 A022 +82359B38 A023 +82359B39 A024 +82359C30 A025 +82359C31 A026 +82359C32 A027 +82359C33 A028 +82359C34 A029 +82359C35 A02A +82359C36 A02B +82359C37 A02C +82359C38 A02D +82359C39 A02E +82359D30 A02F +82359D31 A030 +82359D32 A031 +82359D33 A032 +82359D34 A033 +82359D35 A034 +82359D36 A035 +82359D37 A036 +82359D38 A037 +82359D39 A038 +82359E30 A039 +82359E31 A03A +82359E32 A03B +82359E33 A03C +82359E34 A03D +82359E35 A03E +82359E36 A03F +82359E37 A040 +82359E38 A041 +82359E39 A042 +82359F30 A043 +82359F31 A044 +82359F32 A045 +82359F33 A046 +82359F34 A047 +82359F35 A048 +82359F36 A049 +82359F37 A04A +82359F38 A04B +82359F39 A04C +8235A030 A04D +8235A031 A04E +8235A032 A04F +8235A033 A050 +8235A034 A051 +8235A035 A052 +8235A036 A053 +8235A037 A054 +8235A038 A055 +8235A039 A056 +8235A130 A057 +8235A131 A058 +8235A132 A059 +8235A133 A05A +8235A134 A05B +8235A135 A05C +8235A136 A05D +8235A137 A05E +8235A138 A05F +8235A139 A060 +8235A230 A061 +8235A231 A062 +8235A232 A063 +8235A233 A064 +8235A234 A065 +8235A235 A066 +8235A236 A067 +8235A237 A068 +8235A238 A069 +8235A239 A06A +8235A330 A06B +8235A331 A06C +8235A332 A06D +8235A333 A06E +8235A334 A06F +8235A335 A070 +8235A336 A071 +8235A337 A072 +8235A338 A073 +8235A339 A074 +8235A430 A075 +8235A431 A076 +8235A432 A077 +8235A433 A078 +8235A434 A079 +8235A435 A07A +8235A436 A07B +8235A437 A07C +8235A438 A07D +8235A439 A07E +8235A530 A07F +8235A531 A080 +8235A532 A081 +8235A533 A082 +8235A534 A083 +8235A535 A084 +8235A536 A085 +8235A537 A086 +8235A538 A087 +8235A539 A088 +8235A630 A089 +8235A631 A08A +8235A632 A08B +8235A633 A08C +8235A634 A08D +8235A635 A08E +8235A636 A08F +8235A637 A090 +8235A638 A091 +8235A639 A092 +8235A730 A093 +8235A731 A094 +8235A732 A095 +8235A733 A096 +8235A734 A097 +8235A735 A098 +8235A736 A099 +8235A737 A09A +8235A738 A09B +8235A739 A09C +8235A830 A09D +8235A831 A09E +8235A832 A09F +8235A833 A0A0 +8235A834 A0A1 +8235A835 A0A2 +8235A836 A0A3 +8235A837 A0A4 +8235A838 A0A5 +8235A839 A0A6 +8235A930 A0A7 +8235A931 A0A8 +8235A932 A0A9 +8235A933 A0AA +8235A934 A0AB +8235A935 A0AC +8235A936 A0AD +8235A937 A0AE +8235A938 A0AF +8235A939 A0B0 +8235AA30 A0B1 +8235AA31 A0B2 +8235AA32 A0B3 +8235AA33 A0B4 +8235AA34 A0B5 +8235AA35 A0B6 +8235AA36 A0B7 +8235AA37 A0B8 +8235AA38 A0B9 +8235AA39 A0BA +8235AB30 A0BB +8235AB31 A0BC +8235AB32 A0BD +8235AB33 A0BE +8235AB34 A0BF +8235AB35 A0C0 +8235AB36 A0C1 +8235AB37 A0C2 +8235AB38 A0C3 +8235AB39 A0C4 +8235AC30 A0C5 +8235AC31 A0C6 +8235AC32 A0C7 +8235AC33 A0C8 +8235AC34 A0C9 +8235AC35 A0CA +8235AC36 A0CB +8235AC37 A0CC +8235AC38 A0CD +8235AC39 A0CE +8235AD30 A0CF +8235AD31 A0D0 +8235AD32 A0D1 +8235AD33 A0D2 +8235AD34 A0D3 +8235AD35 A0D4 +8235AD36 A0D5 +8235AD37 A0D6 +8235AD38 A0D7 +8235AD39 A0D8 +8235AE30 A0D9 +8235AE31 A0DA +8235AE32 A0DB +8235AE33 A0DC +8235AE34 A0DD +8235AE35 A0DE +8235AE36 A0DF +8235AE37 A0E0 +8235AE38 A0E1 +8235AE39 A0E2 +8235AF30 A0E3 +8235AF31 A0E4 +8235AF32 A0E5 +8235AF33 A0E6 +8235AF34 A0E7 +8235AF35 A0E8 +8235AF36 A0E9 +8235AF37 A0EA +8235AF38 A0EB +8235AF39 A0EC +8235B030 A0ED +8235B031 A0EE +8235B032 A0EF +8235B033 A0F0 +8235B034 A0F1 +8235B035 A0F2 +8235B036 A0F3 +8235B037 A0F4 +8235B038 A0F5 +8235B039 A0F6 +8235B130 A0F7 +8235B131 A0F8 +8235B132 A0F9 +8235B133 A0FA +8235B134 A0FB +8235B135 A0FC +8235B136 A0FD +8235B137 A0FE +8235B138 A0FF +8235B139 A100 +8235B230 A101 +8235B231 A102 +8235B232 A103 +8235B233 A104 +8235B234 A105 +8235B235 A106 +8235B236 A107 +8235B237 A108 +8235B238 A109 +8235B239 A10A +8235B330 A10B +8235B331 A10C +8235B332 A10D +8235B333 A10E +8235B334 A10F +8235B335 A110 +8235B336 A111 +8235B337 A112 +8235B338 A113 +8235B339 A114 +8235B430 A115 +8235B431 A116 +8235B432 A117 +8235B433 A118 +8235B434 A119 +8235B435 A11A +8235B436 A11B +8235B437 A11C +8235B438 A11D +8235B439 A11E +8235B530 A11F +8235B531 A120 +8235B532 A121 +8235B533 A122 +8235B534 A123 +8235B535 A124 +8235B536 A125 +8235B537 A126 +8235B538 A127 +8235B539 A128 +8235B630 A129 +8235B631 A12A +8235B632 A12B +8235B633 A12C +8235B634 A12D +8235B635 A12E +8235B636 A12F +8235B637 A130 +8235B638 A131 +8235B639 A132 +8235B730 A133 +8235B731 A134 +8235B732 A135 +8235B733 A136 +8235B734 A137 +8235B735 A138 +8235B736 A139 +8235B737 A13A +8235B738 A13B +8235B739 A13C +8235B830 A13D +8235B831 A13E +8235B832 A13F +8235B833 A140 +8235B834 A141 +8235B835 A142 +8235B836 A143 +8235B837 A144 +8235B838 A145 +8235B839 A146 +8235B930 A147 +8235B931 A148 +8235B932 A149 +8235B933 A14A +8235B934 A14B +8235B935 A14C +8235B936 A14D +8235B937 A14E +8235B938 A14F +8235B939 A150 +8235BA30 A151 +8235BA31 A152 +8235BA32 A153 +8235BA33 A154 +8235BA34 A155 +8235BA35 A156 +8235BA36 A157 +8235BA37 A158 +8235BA38 A159 +8235BA39 A15A +8235BB30 A15B +8235BB31 A15C +8235BB32 A15D +8235BB33 A15E +8235BB34 A15F +8235BB35 A160 +8235BB36 A161 +8235BB37 A162 +8235BB38 A163 +8235BB39 A164 +8235BC30 A165 +8235BC31 A166 +8235BC32 A167 +8235BC33 A168 +8235BC34 A169 +8235BC35 A16A +8235BC36 A16B +8235BC37 A16C +8235BC38 A16D +8235BC39 A16E +8235BD30 A16F +8235BD31 A170 +8235BD32 A171 +8235BD33 A172 +8235BD34 A173 +8235BD35 A174 +8235BD36 A175 +8235BD37 A176 +8235BD38 A177 +8235BD39 A178 +8235BE30 A179 +8235BE31 A17A +8235BE32 A17B +8235BE33 A17C +8235BE34 A17D +8235BE35 A17E +8235BE36 A17F +8235BE37 A180 +8235BE38 A181 +8235BE39 A182 +8235BF30 A183 +8235BF31 A184 +8235BF32 A185 +8235BF33 A186 +8235BF34 A187 +8235BF35 A188 +8235BF36 A189 +8235BF37 A18A +8235BF38 A18B +8235BF39 A18C +8235C030 A18D +8235C031 A18E +8235C032 A18F +8235C033 A190 +8235C034 A191 +8235C035 A192 +8235C036 A193 +8235C037 A194 +8235C038 A195 +8235C039 A196 +8235C130 A197 +8235C131 A198 +8235C132 A199 +8235C133 A19A +8235C134 A19B +8235C135 A19C +8235C136 A19D +8235C137 A19E +8235C138 A19F +8235C139 A1A0 +8235C230 A1A1 +8235C231 A1A2 +8235C232 A1A3 +8235C233 A1A4 +8235C234 A1A5 +8235C235 A1A6 +8235C236 A1A7 +8235C237 A1A8 +8235C238 A1A9 +8235C239 A1AA +8235C330 A1AB +8235C331 A1AC +8235C332 A1AD +8235C333 A1AE +8235C334 A1AF +8235C335 A1B0 +8235C336 A1B1 +8235C337 A1B2 +8235C338 A1B3 +8235C339 A1B4 +8235C430 A1B5 +8235C431 A1B6 +8235C432 A1B7 +8235C433 A1B8 +8235C434 A1B9 +8235C435 A1BA +8235C436 A1BB +8235C437 A1BC +8235C438 A1BD +8235C439 A1BE +8235C530 A1BF +8235C531 A1C0 +8235C532 A1C1 +8235C533 A1C2 +8235C534 A1C3 +8235C535 A1C4 +8235C536 A1C5 +8235C537 A1C6 +8235C538 A1C7 +8235C539 A1C8 +8235C630 A1C9 +8235C631 A1CA +8235C632 A1CB +8235C633 A1CC +8235C634 A1CD +8235C635 A1CE +8235C636 A1CF +8235C637 A1D0 +8235C638 A1D1 +8235C639 A1D2 +8235C730 A1D3 +8235C731 A1D4 +8235C732 A1D5 +8235C733 A1D6 +8235C734 A1D7 +8235C735 A1D8 +8235C736 A1D9 +8235C737 A1DA +8235C738 A1DB +8235C739 A1DC +8235C830 A1DD +8235C831 A1DE +8235C832 A1DF +8235C833 A1E0 +8235C834 A1E1 +8235C835 A1E2 +8235C836 A1E3 +8235C837 A1E4 +8235C838 A1E5 +8235C839 A1E6 +8235C930 A1E7 +8235C931 A1E8 +8235C932 A1E9 +8235C933 A1EA +8235C934 A1EB +8235C935 A1EC +8235C936 A1ED +8235C937 A1EE +8235C938 A1EF +8235C939 A1F0 +8235CA30 A1F1 +8235CA31 A1F2 +8235CA32 A1F3 +8235CA33 A1F4 +8235CA34 A1F5 +8235CA35 A1F6 +8235CA36 A1F7 +8235CA37 A1F8 +8235CA38 A1F9 +8235CA39 A1FA +8235CB30 A1FB +8235CB31 A1FC +8235CB32 A1FD +8235CB33 A1FE +8235CB34 A1FF +8235CB35 A200 +8235CB36 A201 +8235CB37 A202 +8235CB38 A203 +8235CB39 A204 +8235CC30 A205 +8235CC31 A206 +8235CC32 A207 +8235CC33 A208 +8235CC34 A209 +8235CC35 A20A +8235CC36 A20B +8235CC37 A20C +8235CC38 A20D +8235CC39 A20E +8235CD30 A20F +8235CD31 A210 +8235CD32 A211 +8235CD33 A212 +8235CD34 A213 +8235CD35 A214 +8235CD36 A215 +8235CD37 A216 +8235CD38 A217 +8235CD39 A218 +8235CE30 A219 +8235CE31 A21A +8235CE32 A21B +8235CE33 A21C +8235CE34 A21D +8235CE35 A21E +8235CE36 A21F +8235CE37 A220 +8235CE38 A221 +8235CE39 A222 +8235CF30 A223 +8235CF31 A224 +8235CF32 A225 +8235CF33 A226 +8235CF34 A227 +8235CF35 A228 +8235CF36 A229 +8235CF37 A22A +8235CF38 A22B +8235CF39 A22C +8235D030 A22D +8235D031 A22E +8235D032 A22F +8235D033 A230 +8235D034 A231 +8235D035 A232 +8235D036 A233 +8235D037 A234 +8235D038 A235 +8235D039 A236 +8235D130 A237 +8235D131 A238 +8235D132 A239 +8235D133 A23A +8235D134 A23B +8235D135 A23C +8235D136 A23D +8235D137 A23E +8235D138 A23F +8235D139 A240 +8235D230 A241 +8235D231 A242 +8235D232 A243 +8235D233 A244 +8235D234 A245 +8235D235 A246 +8235D236 A247 +8235D237 A248 +8235D238 A249 +8235D239 A24A +8235D330 A24B +8235D331 A24C +8235D332 A24D +8235D333 A24E +8235D334 A24F +8235D335 A250 +8235D336 A251 +8235D337 A252 +8235D338 A253 +8235D339 A254 +8235D430 A255 +8235D431 A256 +8235D432 A257 +8235D433 A258 +8235D434 A259 +8235D435 A25A +8235D436 A25B +8235D437 A25C +8235D438 A25D +8235D439 A25E +8235D530 A25F +8235D531 A260 +8235D532 A261 +8235D533 A262 +8235D534 A263 +8235D535 A264 +8235D536 A265 +8235D537 A266 +8235D538 A267 +8235D539 A268 +8235D630 A269 +8235D631 A26A +8235D632 A26B +8235D633 A26C +8235D634 A26D +8235D635 A26E +8235D636 A26F +8235D637 A270 +8235D638 A271 +8235D639 A272 +8235D730 A273 +8235D731 A274 +8235D732 A275 +8235D733 A276 +8235D734 A277 +8235D735 A278 +8235D736 A279 +8235D737 A27A +8235D738 A27B +8235D739 A27C +8235D830 A27D +8235D831 A27E +8235D832 A27F +8235D833 A280 +8235D834 A281 +8235D835 A282 +8235D836 A283 +8235D837 A284 +8235D838 A285 +8235D839 A286 +8235D930 A287 +8235D931 A288 +8235D932 A289 +8235D933 A28A +8235D934 A28B +8235D935 A28C +8235D936 A28D +8235D937 A28E +8235D938 A28F +8235D939 A290 +8235DA30 A291 +8235DA31 A292 +8235DA32 A293 +8235DA33 A294 +8235DA34 A295 +8235DA35 A296 +8235DA36 A297 +8235DA37 A298 +8235DA38 A299 +8235DA39 A29A +8235DB30 A29B +8235DB31 A29C +8235DB32 A29D +8235DB33 A29E +8235DB34 A29F +8235DB35 A2A0 +8235DB36 A2A1 +8235DB37 A2A2 +8235DB38 A2A3 +8235DB39 A2A4 +8235DC30 A2A5 +8235DC31 A2A6 +8235DC32 A2A7 +8235DC33 A2A8 +8235DC34 A2A9 +8235DC35 A2AA +8235DC36 A2AB +8235DC37 A2AC +8235DC38 A2AD +8235DC39 A2AE +8235DD30 A2AF +8235DD31 A2B0 +8235DD32 A2B1 +8235DD33 A2B2 +8235DD34 A2B3 +8235DD35 A2B4 +8235DD36 A2B5 +8235DD37 A2B6 +8235DD38 A2B7 +8235DD39 A2B8 +8235DE30 A2B9 +8235DE31 A2BA +8235DE32 A2BB +8235DE33 A2BC +8235DE34 A2BD +8235DE35 A2BE +8235DE36 A2BF +8235DE37 A2C0 +8235DE38 A2C1 +8235DE39 A2C2 +8235DF30 A2C3 +8235DF31 A2C4 +8235DF32 A2C5 +8235DF33 A2C6 +8235DF34 A2C7 +8235DF35 A2C8 +8235DF36 A2C9 +8235DF37 A2CA +8235DF38 A2CB +8235DF39 A2CC +8235E030 A2CD +8235E031 A2CE +8235E032 A2CF +8235E033 A2D0 +8235E034 A2D1 +8235E035 A2D2 +8235E036 A2D3 +8235E037 A2D4 +8235E038 A2D5 +8235E039 A2D6 +8235E130 A2D7 +8235E131 A2D8 +8235E132 A2D9 +8235E133 A2DA +8235E134 A2DB +8235E135 A2DC +8235E136 A2DD +8235E137 A2DE +8235E138 A2DF +8235E139 A2E0 +8235E230 A2E1 +8235E231 A2E2 +8235E232 A2E3 +8235E233 A2E4 +8235E234 A2E5 +8235E235 A2E6 +8235E236 A2E7 +8235E237 A2E8 +8235E238 A2E9 +8235E239 A2EA +8235E330 A2EB +8235E331 A2EC +8235E332 A2ED +8235E333 A2EE +8235E334 A2EF +8235E335 A2F0 +8235E336 A2F1 +8235E337 A2F2 +8235E338 A2F3 +8235E339 A2F4 +8235E430 A2F5 +8235E431 A2F6 +8235E432 A2F7 +8235E433 A2F8 +8235E434 A2F9 +8235E435 A2FA +8235E436 A2FB +8235E437 A2FC +8235E438 A2FD +8235E439 A2FE +8235E530 A2FF +8235E531 A300 +8235E532 A301 +8235E533 A302 +8235E534 A303 +8235E535 A304 +8235E536 A305 +8235E537 A306 +8235E538 A307 +8235E539 A308 +8235E630 A309 +8235E631 A30A +8235E632 A30B +8235E633 A30C +8235E634 A30D +8235E635 A30E +8235E636 A30F +8235E637 A310 +8235E638 A311 +8235E639 A312 +8235E730 A313 +8235E731 A314 +8235E732 A315 +8235E733 A316 +8235E734 A317 +8235E735 A318 +8235E736 A319 +8235E737 A31A +8235E738 A31B +8235E739 A31C +8235E830 A31D +8235E831 A31E +8235E832 A31F +8235E833 A320 +8235E834 A321 +8235E835 A322 +8235E836 A323 +8235E837 A324 +8235E838 A325 +8235E839 A326 +8235E930 A327 +8235E931 A328 +8235E932 A329 +8235E933 A32A +8235E934 A32B +8235E935 A32C +8235E936 A32D +8235E937 A32E +8235E938 A32F +8235E939 A330 +8235EA30 A331 +8235EA31 A332 +8235EA32 A333 +8235EA33 A334 +8235EA34 A335 +8235EA35 A336 +8235EA36 A337 +8235EA37 A338 +8235EA38 A339 +8235EA39 A33A +8235EB30 A33B +8235EB31 A33C +8235EB32 A33D +8235EB33 A33E +8235EB34 A33F +8235EB35 A340 +8235EB36 A341 +8235EB37 A342 +8235EB38 A343 +8235EB39 A344 +8235EC30 A345 +8235EC31 A346 +8235EC32 A347 +8235EC33 A348 +8235EC34 A349 +8235EC35 A34A +8235EC36 A34B +8235EC37 A34C +8235EC38 A34D +8235EC39 A34E +8235ED30 A34F +8235ED31 A350 +8235ED32 A351 +8235ED33 A352 +8235ED34 A353 +8235ED35 A354 +8235ED36 A355 +8235ED37 A356 +8235ED38 A357 +8235ED39 A358 +8235EE30 A359 +8235EE31 A35A +8235EE32 A35B +8235EE33 A35C +8235EE34 A35D +8235EE35 A35E +8235EE36 A35F +8235EE37 A360 +8235EE38 A361 +8235EE39 A362 +8235EF30 A363 +8235EF31 A364 +8235EF32 A365 +8235EF33 A366 +8235EF34 A367 +8235EF35 A368 +8235EF36 A369 +8235EF37 A36A +8235EF38 A36B +8235EF39 A36C +8235F030 A36D +8235F031 A36E +8235F032 A36F +8235F033 A370 +8235F034 A371 +8235F035 A372 +8235F036 A373 +8235F037 A374 +8235F038 A375 +8235F039 A376 +8235F130 A377 +8235F131 A378 +8235F132 A379 +8235F133 A37A +8235F134 A37B +8235F135 A37C +8235F136 A37D +8235F137 A37E +8235F138 A37F +8235F139 A380 +8235F230 A381 +8235F231 A382 +8235F232 A383 +8235F233 A384 +8235F234 A385 +8235F235 A386 +8235F236 A387 +8235F237 A388 +8235F238 A389 +8235F239 A38A +8235F330 A38B +8235F331 A38C +8235F332 A38D +8235F333 A38E +8235F334 A38F +8235F335 A390 +8235F336 A391 +8235F337 A392 +8235F338 A393 +8235F339 A394 +8235F430 A395 +8235F431 A396 +8235F432 A397 +8235F433 A398 +8235F434 A399 +8235F435 A39A +8235F436 A39B +8235F437 A39C +8235F438 A39D +8235F439 A39E +8235F530 A39F +8235F531 A3A0 +8235F532 A3A1 +8235F533 A3A2 +8235F534 A3A3 +8235F535 A3A4 +8235F536 A3A5 +8235F537 A3A6 +8235F538 A3A7 +8235F539 A3A8 +8235F630 A3A9 +8235F631 A3AA +8235F632 A3AB +8235F633 A3AC +8235F634 A3AD +8235F635 A3AE +8235F636 A3AF +8235F637 A3B0 +8235F638 A3B1 +8235F639 A3B2 +8235F730 A3B3 +8235F731 A3B4 +8235F732 A3B5 +8235F733 A3B6 +8235F734 A3B7 +8235F735 A3B8 +8235F736 A3B9 +8235F737 A3BA +8235F738 A3BB +8235F739 A3BC +8235F830 A3BD +8235F831 A3BE +8235F832 A3BF +8235F833 A3C0 +8235F834 A3C1 +8235F835 A3C2 +8235F836 A3C3 +8235F837 A3C4 +8235F838 A3C5 +8235F839 A3C6 +8235F930 A3C7 +8235F931 A3C8 +8235F932 A3C9 +8235F933 A3CA +8235F934 A3CB +8235F935 A3CC +8235F936 A3CD +8235F937 A3CE +8235F938 A3CF +8235F939 A3D0 +8235FA30 A3D1 +8235FA31 A3D2 +8235FA32 A3D3 +8235FA33 A3D4 +8235FA34 A3D5 +8235FA35 A3D6 +8235FA36 A3D7 +8235FA37 A3D8 +8235FA38 A3D9 +8235FA39 A3DA +8235FB30 A3DB +8235FB31 A3DC +8235FB32 A3DD +8235FB33 A3DE +8235FB34 A3DF +8235FB35 A3E0 +8235FB36 A3E1 +8235FB37 A3E2 +8235FB38 A3E3 +8235FB39 A3E4 +8235FC30 A3E5 +8235FC31 A3E6 +8235FC32 A3E7 +8235FC33 A3E8 +8235FC34 A3E9 +8235FC35 A3EA +8235FC36 A3EB +8235FC37 A3EC +8235FC38 A3ED +8235FC39 A3EE +8235FD30 A3EF +8235FD31 A3F0 +8235FD32 A3F1 +8235FD33 A3F2 +8235FD34 A3F3 +8235FD35 A3F4 +8235FD36 A3F5 +8235FD37 A3F6 +8235FD38 A3F7 +8235FD39 A3F8 +8235FE30 A3F9 +8235FE31 A3FA +8235FE32 A3FB +8235FE33 A3FC +8235FE34 A3FD +8235FE35 A3FE +8235FE36 A3FF +8235FE37 A400 +8235FE38 A401 +8235FE39 A402 +82368130 A403 +82368131 A404 +82368132 A405 +82368133 A406 +82368134 A407 +82368135 A408 +82368136 A409 +82368137 A40A +82368138 A40B +82368139 A40C +82368230 A40D +82368231 A40E +82368232 A40F +82368233 A410 +82368234 A411 +82368235 A412 +82368236 A413 +82368237 A414 +82368238 A415 +82368239 A416 +82368330 A417 +82368331 A418 +82368332 A419 +82368333 A41A +82368334 A41B +82368335 A41C +82368336 A41D +82368337 A41E +82368338 A41F +82368339 A420 +82368430 A421 +82368431 A422 +82368432 A423 +82368433 A424 +82368434 A425 +82368435 A426 +82368436 A427 +82368437 A428 +82368438 A429 +82368439 A42A +82368530 A42B +82368531 A42C +82368532 A42D +82368533 A42E +82368534 A42F +82368535 A430 +82368536 A431 +82368537 A432 +82368538 A433 +82368539 A434 +82368630 A435 +82368631 A436 +82368632 A437 +82368633 A438 +82368634 A439 +82368635 A43A +82368636 A43B +82368637 A43C +82368638 A43D +82368639 A43E +82368730 A43F +82368731 A440 +82368732 A441 +82368733 A442 +82368734 A443 +82368735 A444 +82368736 A445 +82368737 A446 +82368738 A447 +82368739 A448 +82368830 A449 +82368831 A44A +82368832 A44B +82368833 A44C +82368834 A44D +82368835 A44E +82368836 A44F +82368837 A450 +82368838 A451 +82368839 A452 +82368930 A453 +82368931 A454 +82368932 A455 +82368933 A456 +82368934 A457 +82368935 A458 +82368936 A459 +82368937 A45A +82368938 A45B +82368939 A45C +82368A30 A45D +82368A31 A45E +82368A32 A45F +82368A33 A460 +82368A34 A461 +82368A35 A462 +82368A36 A463 +82368A37 A464 +82368A38 A465 +82368A39 A466 +82368B30 A467 +82368B31 A468 +82368B32 A469 +82368B33 A46A +82368B34 A46B +82368B35 A46C +82368B36 A46D +82368B37 A46E +82368B38 A46F +82368B39 A470 +82368C30 A471 +82368C31 A472 +82368C32 A473 +82368C33 A474 +82368C34 A475 +82368C35 A476 +82368C36 A477 +82368C37 A478 +82368C38 A479 +82368C39 A47A +82368D30 A47B +82368D31 A47C +82368D32 A47D +82368D33 A47E +82368D34 A47F +82368D35 A480 +82368D36 A481 +82368D37 A482 +82368D38 A483 +82368D39 A484 +82368E30 A485 +82368E31 A486 +82368E32 A487 +82368E33 A488 +82368E34 A489 +82368E35 A48A +82368E36 A48B +82368E37 A48C +82368E38 A48D +82368E39 A48E +82368F30 A48F +82368F31 A490 +82368F32 A491 +82368F33 A492 +82368F34 A493 +82368F35 A494 +82368F36 A495 +82368F37 A496 +82368F38 A497 +82368F39 A498 +82369030 A499 +82369031 A49A +82369032 A49B +82369033 A49C +82369034 A49D +82369035 A49E +82369036 A49F +82369037 A4A0 +82369038 A4A1 +82369039 A4A2 +82369130 A4A3 +82369131 A4A4 +82369132 A4A5 +82369133 A4A6 +82369134 A4A7 +82369135 A4A8 +82369136 A4A9 +82369137 A4AA +82369138 A4AB +82369139 A4AC +82369230 A4AD +82369231 A4AE +82369232 A4AF +82369233 A4B0 +82369234 A4B1 +82369235 A4B2 +82369236 A4B3 +82369237 A4B4 +82369238 A4B5 +82369239 A4B6 +82369330 A4B7 +82369331 A4B8 +82369332 A4B9 +82369333 A4BA +82369334 A4BB +82369335 A4BC +82369336 A4BD +82369337 A4BE +82369338 A4BF +82369339 A4C0 +82369430 A4C1 +82369431 A4C2 +82369432 A4C3 +82369433 A4C4 +82369434 A4C5 +82369435 A4C6 +82369436 A4C7 +82369437 A4C8 +82369438 A4C9 +82369439 A4CA +82369530 A4CB +82369531 A4CC +82369532 A4CD +82369533 A4CE +82369534 A4CF +82369535 A4D0 +82369536 A4D1 +82369537 A4D2 +82369538 A4D3 +82369539 A4D4 +82369630 A4D5 +82369631 A4D6 +82369632 A4D7 +82369633 A4D8 +82369634 A4D9 +82369635 A4DA +82369636 A4DB +82369637 A4DC +82369638 A4DD +82369639 A4DE +82369730 A4DF +82369731 A4E0 +82369732 A4E1 +82369733 A4E2 +82369734 A4E3 +82369735 A4E4 +82369736 A4E5 +82369737 A4E6 +82369738 A4E7 +82369739 A4E8 +82369830 A4E9 +82369831 A4EA +82369832 A4EB +82369833 A4EC +82369834 A4ED +82369835 A4EE +82369836 A4EF +82369837 A4F0 +82369838 A4F1 +82369839 A4F2 +82369930 A4F3 +82369931 A4F4 +82369932 A4F5 +82369933 A4F6 +82369934 A4F7 +82369935 A4F8 +82369936 A4F9 +82369937 A4FA +82369938 A4FB +82369939 A4FC +82369A30 A4FD +82369A31 A4FE +82369A32 A4FF +82369A33 A500 +82369A34 A501 +82369A35 A502 +82369A36 A503 +82369A37 A504 +82369A38 A505 +82369A39 A506 +82369B30 A507 +82369B31 A508 +82369B32 A509 +82369B33 A50A +82369B34 A50B +82369B35 A50C +82369B36 A50D +82369B37 A50E +82369B38 A50F +82369B39 A510 +82369C30 A511 +82369C31 A512 +82369C32 A513 +82369C33 A514 +82369C34 A515 +82369C35 A516 +82369C36 A517 +82369C37 A518 +82369C38 A519 +82369C39 A51A +82369D30 A51B +82369D31 A51C +82369D32 A51D +82369D33 A51E +82369D34 A51F +82369D35 A520 +82369D36 A521 +82369D37 A522 +82369D38 A523 +82369D39 A524 +82369E30 A525 +82369E31 A526 +82369E32 A527 +82369E33 A528 +82369E34 A529 +82369E35 A52A +82369E36 A52B +82369E37 A52C +82369E38 A52D +82369E39 A52E +82369F30 A52F +82369F31 A530 +82369F32 A531 +82369F33 A532 +82369F34 A533 +82369F35 A534 +82369F36 A535 +82369F37 A536 +82369F38 A537 +82369F39 A538 +8236A030 A539 +8236A031 A53A +8236A032 A53B +8236A033 A53C +8236A034 A53D +8236A035 A53E +8236A036 A53F +8236A037 A540 +8236A038 A541 +8236A039 A542 +8236A130 A543 +8236A131 A544 +8236A132 A545 +8236A133 A546 +8236A134 A547 +8236A135 A548 +8236A136 A549 +8236A137 A54A +8236A138 A54B +8236A139 A54C +8236A230 A54D +8236A231 A54E +8236A232 A54F +8236A233 A550 +8236A234 A551 +8236A235 A552 +8236A236 A553 +8236A237 A554 +8236A238 A555 +8236A239 A556 +8236A330 A557 +8236A331 A558 +8236A332 A559 +8236A333 A55A +8236A334 A55B +8236A335 A55C +8236A336 A55D +8236A337 A55E +8236A338 A55F +8236A339 A560 +8236A430 A561 +8236A431 A562 +8236A432 A563 +8236A433 A564 +8236A434 A565 +8236A435 A566 +8236A436 A567 +8236A437 A568 +8236A438 A569 +8236A439 A56A +8236A530 A56B +8236A531 A56C +8236A532 A56D +8236A533 A56E +8236A534 A56F +8236A535 A570 +8236A536 A571 +8236A537 A572 +8236A538 A573 +8236A539 A574 +8236A630 A575 +8236A631 A576 +8236A632 A577 +8236A633 A578 +8236A634 A579 +8236A635 A57A +8236A636 A57B +8236A637 A57C +8236A638 A57D +8236A639 A57E +8236A730 A57F +8236A731 A580 +8236A732 A581 +8236A733 A582 +8236A734 A583 +8236A735 A584 +8236A736 A585 +8236A737 A586 +8236A738 A587 +8236A739 A588 +8236A830 A589 +8236A831 A58A +8236A832 A58B +8236A833 A58C +8236A834 A58D +8236A835 A58E +8236A836 A58F +8236A837 A590 +8236A838 A591 +8236A839 A592 +8236A930 A593 +8236A931 A594 +8236A932 A595 +8236A933 A596 +8236A934 A597 +8236A935 A598 +8236A936 A599 +8236A937 A59A +8236A938 A59B +8236A939 A59C +8236AA30 A59D +8236AA31 A59E +8236AA32 A59F +8236AA33 A5A0 +8236AA34 A5A1 +8236AA35 A5A2 +8236AA36 A5A3 +8236AA37 A5A4 +8236AA38 A5A5 +8236AA39 A5A6 +8236AB30 A5A7 +8236AB31 A5A8 +8236AB32 A5A9 +8236AB33 A5AA +8236AB34 A5AB +8236AB35 A5AC +8236AB36 A5AD +8236AB37 A5AE +8236AB38 A5AF +8236AB39 A5B0 +8236AC30 A5B1 +8236AC31 A5B2 +8236AC32 A5B3 +8236AC33 A5B4 +8236AC34 A5B5 +8236AC35 A5B6 +8236AC36 A5B7 +8236AC37 A5B8 +8236AC38 A5B9 +8236AC39 A5BA +8236AD30 A5BB +8236AD31 A5BC +8236AD32 A5BD +8236AD33 A5BE +8236AD34 A5BF +8236AD35 A5C0 +8236AD36 A5C1 +8236AD37 A5C2 +8236AD38 A5C3 +8236AD39 A5C4 +8236AE30 A5C5 +8236AE31 A5C6 +8236AE32 A5C7 +8236AE33 A5C8 +8236AE34 A5C9 +8236AE35 A5CA +8236AE36 A5CB +8236AE37 A5CC +8236AE38 A5CD +8236AE39 A5CE +8236AF30 A5CF +8236AF31 A5D0 +8236AF32 A5D1 +8236AF33 A5D2 +8236AF34 A5D3 +8236AF35 A5D4 +8236AF36 A5D5 +8236AF37 A5D6 +8236AF38 A5D7 +8236AF39 A5D8 +8236B030 A5D9 +8236B031 A5DA +8236B032 A5DB +8236B033 A5DC +8236B034 A5DD +8236B035 A5DE +8236B036 A5DF +8236B037 A5E0 +8236B038 A5E1 +8236B039 A5E2 +8236B130 A5E3 +8236B131 A5E4 +8236B132 A5E5 +8236B133 A5E6 +8236B134 A5E7 +8236B135 A5E8 +8236B136 A5E9 +8236B137 A5EA +8236B138 A5EB +8236B139 A5EC +8236B230 A5ED +8236B231 A5EE +8236B232 A5EF +8236B233 A5F0 +8236B234 A5F1 +8236B235 A5F2 +8236B236 A5F3 +8236B237 A5F4 +8236B238 A5F5 +8236B239 A5F6 +8236B330 A5F7 +8236B331 A5F8 +8236B332 A5F9 +8236B333 A5FA +8236B334 A5FB +8236B335 A5FC +8236B336 A5FD +8236B337 A5FE +8236B338 A5FF +8236B339 A600 +8236B430 A601 +8236B431 A602 +8236B432 A603 +8236B433 A604 +8236B434 A605 +8236B435 A606 +8236B436 A607 +8236B437 A608 +8236B438 A609 +8236B439 A60A +8236B530 A60B +8236B531 A60C +8236B532 A60D +8236B533 A60E +8236B534 A60F +8236B535 A610 +8236B536 A611 +8236B537 A612 +8236B538 A613 +8236B539 A614 +8236B630 A615 +8236B631 A616 +8236B632 A617 +8236B633 A618 +8236B634 A619 +8236B635 A61A +8236B636 A61B +8236B637 A61C +8236B638 A61D +8236B639 A61E +8236B730 A61F +8236B731 A620 +8236B732 A621 +8236B733 A622 +8236B734 A623 +8236B735 A624 +8236B736 A625 +8236B737 A626 +8236B738 A627 +8236B739 A628 +8236B830 A629 +8236B831 A62A +8236B832 A62B +8236B833 A62C +8236B834 A62D +8236B835 A62E +8236B836 A62F +8236B837 A630 +8236B838 A631 +8236B839 A632 +8236B930 A633 +8236B931 A634 +8236B932 A635 +8236B933 A636 +8236B934 A637 +8236B935 A638 +8236B936 A639 +8236B937 A63A +8236B938 A63B +8236B939 A63C +8236BA30 A63D +8236BA31 A63E +8236BA32 A63F +8236BA33 A640 +8236BA34 A641 +8236BA35 A642 +8236BA36 A643 +8236BA37 A644 +8236BA38 A645 +8236BA39 A646 +8236BB30 A647 +8236BB31 A648 +8236BB32 A649 +8236BB33 A64A +8236BB34 A64B +8236BB35 A64C +8236BB36 A64D +8236BB37 A64E +8236BB38 A64F +8236BB39 A650 +8236BC30 A651 +8236BC31 A652 +8236BC32 A653 +8236BC33 A654 +8236BC34 A655 +8236BC35 A656 +8236BC36 A657 +8236BC37 A658 +8236BC38 A659 +8236BC39 A65A +8236BD30 A65B +8236BD31 A65C +8236BD32 A65D +8236BD33 A65E +8236BD34 A65F +8236BD35 A660 +8236BD36 A661 +8236BD37 A662 +8236BD38 A663 +8236BD39 A664 +8236BE30 A665 +8236BE31 A666 +8236BE32 A667 +8236BE33 A668 +8236BE34 A669 +8236BE35 A66A +8236BE36 A66B +8236BE37 A66C +8236BE38 A66D +8236BE39 A66E +8236BF30 A66F +8236BF31 A670 +8236BF32 A671 +8236BF33 A672 +8236BF34 A673 +8236BF35 A674 +8236BF36 A675 +8236BF37 A676 +8236BF38 A677 +8236BF39 A678 +8236C030 A679 +8236C031 A67A +8236C032 A67B +8236C033 A67C +8236C034 A67D +8236C035 A67E +8236C036 A67F +8236C037 A680 +8236C038 A681 +8236C039 A682 +8236C130 A683 +8236C131 A684 +8236C132 A685 +8236C133 A686 +8236C134 A687 +8236C135 A688 +8236C136 A689 +8236C137 A68A +8236C138 A68B +8236C139 A68C +8236C230 A68D +8236C231 A68E +8236C232 A68F +8236C233 A690 +8236C234 A691 +8236C235 A692 +8236C236 A693 +8236C237 A694 +8236C238 A695 +8236C239 A696 +8236C330 A697 +8236C331 A698 +8236C332 A699 +8236C333 A69A +8236C334 A69B +8236C335 A69C +8236C336 A69D +8236C337 A69E +8236C338 A69F +8236C339 A6A0 +8236C430 A6A1 +8236C431 A6A2 +8236C432 A6A3 +8236C433 A6A4 +8236C434 A6A5 +8236C435 A6A6 +8236C436 A6A7 +8236C437 A6A8 +8236C438 A6A9 +8236C439 A6AA +8236C530 A6AB +8236C531 A6AC +8236C532 A6AD +8236C533 A6AE +8236C534 A6AF +8236C535 A6B0 +8236C536 A6B1 +8236C537 A6B2 +8236C538 A6B3 +8236C539 A6B4 +8236C630 A6B5 +8236C631 A6B6 +8236C632 A6B7 +8236C633 A6B8 +8236C634 A6B9 +8236C635 A6BA +8236C636 A6BB +8236C637 A6BC +8236C638 A6BD +8236C639 A6BE +8236C730 A6BF +8236C731 A6C0 +8236C732 A6C1 +8236C733 A6C2 +8236C734 A6C3 +8236C735 A6C4 +8236C736 A6C5 +8236C737 A6C6 +8236C738 A6C7 +8236C739 A6C8 +8236C830 A6C9 +8236C831 A6CA +8236C832 A6CB +8236C833 A6CC +8236C834 A6CD +8236C835 A6CE +8236C836 A6CF +8236C837 A6D0 +8236C838 A6D1 +8236C839 A6D2 +8236C930 A6D3 +8236C931 A6D4 +8236C932 A6D5 +8236C933 A6D6 +8236C934 A6D7 +8236C935 A6D8 +8236C936 A6D9 +8236C937 A6DA +8236C938 A6DB +8236C939 A6DC +8236CA30 A6DD +8236CA31 A6DE +8236CA32 A6DF +8236CA33 A6E0 +8236CA34 A6E1 +8236CA35 A6E2 +8236CA36 A6E3 +8236CA37 A6E4 +8236CA38 A6E5 +8236CA39 A6E6 +8236CB30 A6E7 +8236CB31 A6E8 +8236CB32 A6E9 +8236CB33 A6EA +8236CB34 A6EB +8236CB35 A6EC +8236CB36 A6ED +8236CB37 A6EE +8236CB38 A6EF +8236CB39 A6F0 +8236CC30 A6F1 +8236CC31 A6F2 +8236CC32 A6F3 +8236CC33 A6F4 +8236CC34 A6F5 +8236CC35 A6F6 +8236CC36 A6F7 +8236CC37 A6F8 +8236CC38 A6F9 +8236CC39 A6FA +8236CD30 A6FB +8236CD31 A6FC +8236CD32 A6FD +8236CD33 A6FE +8236CD34 A6FF +8236CD35 A700 +8236CD36 A701 +8236CD37 A702 +8236CD38 A703 +8236CD39 A704 +8236CE30 A705 +8236CE31 A706 +8236CE32 A707 +8236CE33 A708 +8236CE34 A709 +8236CE35 A70A +8236CE36 A70B +8236CE37 A70C +8236CE38 A70D +8236CE39 A70E +8236CF30 A70F +8236CF31 A710 +8236CF32 A711 +8236CF33 A712 +8236CF34 A713 +8236CF35 A714 +8236CF36 A715 +8236CF37 A716 +8236CF38 A717 +8236CF39 A718 +8236D030 A719 +8236D031 A71A +8236D032 A71B +8236D033 A71C +8236D034 A71D +8236D035 A71E +8236D036 A71F +8236D037 A720 +8236D038 A721 +8236D039 A722 +8236D130 A723 +8236D131 A724 +8236D132 A725 +8236D133 A726 +8236D134 A727 +8236D135 A728 +8236D136 A729 +8236D137 A72A +8236D138 A72B +8236D139 A72C +8236D230 A72D +8236D231 A72E +8236D232 A72F +8236D233 A730 +8236D234 A731 +8236D235 A732 +8236D236 A733 +8236D237 A734 +8236D238 A735 +8236D239 A736 +8236D330 A737 +8236D331 A738 +8236D332 A739 +8236D333 A73A +8236D334 A73B +8236D335 A73C +8236D336 A73D +8236D337 A73E +8236D338 A73F +8236D339 A740 +8236D430 A741 +8236D431 A742 +8236D432 A743 +8236D433 A744 +8236D434 A745 +8236D435 A746 +8236D436 A747 +8236D437 A748 +8236D438 A749 +8236D439 A74A +8236D530 A74B +8236D531 A74C +8236D532 A74D +8236D533 A74E +8236D534 A74F +8236D535 A750 +8236D536 A751 +8236D537 A752 +8236D538 A753 +8236D539 A754 +8236D630 A755 +8236D631 A756 +8236D632 A757 +8236D633 A758 +8236D634 A759 +8236D635 A75A +8236D636 A75B +8236D637 A75C +8236D638 A75D +8236D639 A75E +8236D730 A75F +8236D731 A760 +8236D732 A761 +8236D733 A762 +8236D734 A763 +8236D735 A764 +8236D736 A765 +8236D737 A766 +8236D738 A767 +8236D739 A768 +8236D830 A769 +8236D831 A76A +8236D832 A76B +8236D833 A76C +8236D834 A76D +8236D835 A76E +8236D836 A76F +8236D837 A770 +8236D838 A771 +8236D839 A772 +8236D930 A773 +8236D931 A774 +8236D932 A775 +8236D933 A776 +8236D934 A777 +8236D935 A778 +8236D936 A779 +8236D937 A77A +8236D938 A77B +8236D939 A77C +8236DA30 A77D +8236DA31 A77E +8236DA32 A77F +8236DA33 A780 +8236DA34 A781 +8236DA35 A782 +8236DA36 A783 +8236DA37 A784 +8236DA38 A785 +8236DA39 A786 +8236DB30 A787 +8236DB31 A788 +8236DB32 A789 +8236DB33 A78A +8236DB34 A78B +8236DB35 A78C +8236DB36 A78D +8236DB37 A78E +8236DB38 A78F +8236DB39 A790 +8236DC30 A791 +8236DC31 A792 +8236DC32 A793 +8236DC33 A794 +8236DC34 A795 +8236DC35 A796 +8236DC36 A797 +8236DC37 A798 +8236DC38 A799 +8236DC39 A79A +8236DD30 A79B +8236DD31 A79C +8236DD32 A79D +8236DD33 A79E +8236DD34 A79F +8236DD35 A7A0 +8236DD36 A7A1 +8236DD37 A7A2 +8236DD38 A7A3 +8236DD39 A7A4 +8236DE30 A7A5 +8236DE31 A7A6 +8236DE32 A7A7 +8236DE33 A7A8 +8236DE34 A7A9 +8236DE35 A7AA +8236DE36 A7AB +8236DE37 A7AC +8236DE38 A7AD +8236DE39 A7AE +8236DF30 A7AF +8236DF31 A7B0 +8236DF32 A7B1 +8236DF33 A7B2 +8236DF34 A7B3 +8236DF35 A7B4 +8236DF36 A7B5 +8236DF37 A7B6 +8236DF38 A7B7 +8236DF39 A7B8 +8236E030 A7B9 +8236E031 A7BA +8236E032 A7BB +8236E033 A7BC +8236E034 A7BD +8236E035 A7BE +8236E036 A7BF +8236E037 A7C0 +8236E038 A7C1 +8236E039 A7C2 +8236E130 A7C3 +8236E131 A7C4 +8236E132 A7C5 +8236E133 A7C6 +8236E134 A7C7 +8236E135 A7C8 +8236E136 A7C9 +8236E137 A7CA +8236E138 A7CB +8236E139 A7CC +8236E230 A7CD +8236E231 A7CE +8236E232 A7CF +8236E233 A7D0 +8236E234 A7D1 +8236E235 A7D2 +8236E236 A7D3 +8236E237 A7D4 +8236E238 A7D5 +8236E239 A7D6 +8236E330 A7D7 +8236E331 A7D8 +8236E332 A7D9 +8236E333 A7DA +8236E334 A7DB +8236E335 A7DC +8236E336 A7DD +8236E337 A7DE +8236E338 A7DF +8236E339 A7E0 +8236E430 A7E1 +8236E431 A7E2 +8236E432 A7E3 +8236E433 A7E4 +8236E434 A7E5 +8236E435 A7E6 +8236E436 A7E7 +8236E437 A7E8 +8236E438 A7E9 +8236E439 A7EA +8236E530 A7EB +8236E531 A7EC +8236E532 A7ED +8236E533 A7EE +8236E534 A7EF +8236E535 A7F0 +8236E536 A7F1 +8236E537 A7F2 +8236E538 A7F3 +8236E539 A7F4 +8236E630 A7F5 +8236E631 A7F6 +8236E632 A7F7 +8236E633 A7F8 +8236E634 A7F9 +8236E635 A7FA +8236E636 A7FB +8236E637 A7FC +8236E638 A7FD +8236E639 A7FE +8236E730 A7FF +8236E731 A800 +8236E732 A801 +8236E733 A802 +8236E734 A803 +8236E735 A804 +8236E736 A805 +8236E737 A806 +8236E738 A807 +8236E739 A808 +8236E830 A809 +8236E831 A80A +8236E832 A80B +8236E833 A80C +8236E834 A80D +8236E835 A80E +8236E836 A80F +8236E837 A810 +8236E838 A811 +8236E839 A812 +8236E930 A813 +8236E931 A814 +8236E932 A815 +8236E933 A816 +8236E934 A817 +8236E935 A818 +8236E936 A819 +8236E937 A81A +8236E938 A81B +8236E939 A81C +8236EA30 A81D +8236EA31 A81E +8236EA32 A81F +8236EA33 A820 +8236EA34 A821 +8236EA35 A822 +8236EA36 A823 +8236EA37 A824 +8236EA38 A825 +8236EA39 A826 +8236EB30 A827 +8236EB31 A828 +8236EB32 A829 +8236EB33 A82A +8236EB34 A82B +8236EB35 A82C +8236EB36 A82D +8236EB37 A82E +8236EB38 A82F +8236EB39 A830 +8236EC30 A831 +8236EC31 A832 +8236EC32 A833 +8236EC33 A834 +8236EC34 A835 +8236EC35 A836 +8236EC36 A837 +8236EC37 A838 +8236EC38 A839 +8236EC39 A83A +8236ED30 A83B +8236ED31 A83C +8236ED32 A83D +8236ED33 A83E +8236ED34 A83F +8236ED35 A840 +8236ED36 A841 +8236ED37 A842 +8236ED38 A843 +8236ED39 A844 +8236EE30 A845 +8236EE31 A846 +8236EE32 A847 +8236EE33 A848 +8236EE34 A849 +8236EE35 A84A +8236EE36 A84B +8236EE37 A84C +8236EE38 A84D +8236EE39 A84E +8236EF30 A84F +8236EF31 A850 +8236EF32 A851 +8236EF33 A852 +8236EF34 A853 +8236EF35 A854 +8236EF36 A855 +8236EF37 A856 +8236EF38 A857 +8236EF39 A858 +8236F030 A859 +8236F031 A85A +8236F032 A85B +8236F033 A85C +8236F034 A85D +8236F035 A85E +8236F036 A85F +8236F037 A860 +8236F038 A861 +8236F039 A862 +8236F130 A863 +8236F131 A864 +8236F132 A865 +8236F133 A866 +8236F134 A867 +8236F135 A868 +8236F136 A869 +8236F137 A86A +8236F138 A86B +8236F139 A86C +8236F230 A86D +8236F231 A86E +8236F232 A86F +8236F233 A870 +8236F234 A871 +8236F235 A872 +8236F236 A873 +8236F237 A874 +8236F238 A875 +8236F239 A876 +8236F330 A877 +8236F331 A878 +8236F332 A879 +8236F333 A87A +8236F334 A87B +8236F335 A87C +8236F336 A87D +8236F337 A87E +8236F338 A87F +8236F339 A880 +8236F430 A881 +8236F431 A882 +8236F432 A883 +8236F433 A884 +8236F434 A885 +8236F435 A886 +8236F436 A887 +8236F437 A888 +8236F438 A889 +8236F439 A88A +8236F530 A88B +8236F531 A88C +8236F532 A88D +8236F533 A88E +8236F534 A88F +8236F535 A890 +8236F536 A891 +8236F537 A892 +8236F538 A893 +8236F539 A894 +8236F630 A895 +8236F631 A896 +8236F632 A897 +8236F633 A898 +8236F634 A899 +8236F635 A89A +8236F636 A89B +8236F637 A89C +8236F638 A89D +8236F639 A89E +8236F730 A89F +8236F731 A8A0 +8236F732 A8A1 +8236F733 A8A2 +8236F734 A8A3 +8236F735 A8A4 +8236F736 A8A5 +8236F737 A8A6 +8236F738 A8A7 +8236F739 A8A8 +8236F830 A8A9 +8236F831 A8AA +8236F832 A8AB +8236F833 A8AC +8236F834 A8AD +8236F835 A8AE +8236F836 A8AF +8236F837 A8B0 +8236F838 A8B1 +8236F839 A8B2 +8236F930 A8B3 +8236F931 A8B4 +8236F932 A8B5 +8236F933 A8B6 +8236F934 A8B7 +8236F935 A8B8 +8236F936 A8B9 +8236F937 A8BA +8236F938 A8BB +8236F939 A8BC +8236FA30 A8BD +8236FA31 A8BE +8236FA32 A8BF +8236FA33 A8C0 +8236FA34 A8C1 +8236FA35 A8C2 +8236FA36 A8C3 +8236FA37 A8C4 +8236FA38 A8C5 +8236FA39 A8C6 +8236FB30 A8C7 +8236FB31 A8C8 +8236FB32 A8C9 +8236FB33 A8CA +8236FB34 A8CB +8236FB35 A8CC +8236FB36 A8CD +8236FB37 A8CE +8236FB38 A8CF +8236FB39 A8D0 +8236FC30 A8D1 +8236FC31 A8D2 +8236FC32 A8D3 +8236FC33 A8D4 +8236FC34 A8D5 +8236FC35 A8D6 +8236FC36 A8D7 +8236FC37 A8D8 +8236FC38 A8D9 +8236FC39 A8DA +8236FD30 A8DB +8236FD31 A8DC +8236FD32 A8DD +8236FD33 A8DE +8236FD34 A8DF +8236FD35 A8E0 +8236FD36 A8E1 +8236FD37 A8E2 +8236FD38 A8E3 +8236FD39 A8E4 +8236FE30 A8E5 +8236FE31 A8E6 +8236FE32 A8E7 +8236FE33 A8E8 +8236FE34 A8E9 +8236FE35 A8EA +8236FE36 A8EB +8236FE37 A8EC +8236FE38 A8ED +8236FE39 A8EE +82378130 A8EF +82378131 A8F0 +82378132 A8F1 +82378133 A8F2 +82378134 A8F3 +82378135 A8F4 +82378136 A8F5 +82378137 A8F6 +82378138 A8F7 +82378139 A8F8 +82378230 A8F9 +82378231 A8FA +82378232 A8FB +82378233 A8FC +82378234 A8FD +82378235 A8FE +82378236 A8FF +82378237 A900 +82378238 A901 +82378239 A902 +82378330 A903 +82378331 A904 +82378332 A905 +82378333 A906 +82378334 A907 +82378335 A908 +82378336 A909 +82378337 A90A +82378338 A90B +82378339 A90C +82378430 A90D +82378431 A90E +82378432 A90F +82378433 A910 +82378434 A911 +82378435 A912 +82378436 A913 +82378437 A914 +82378438 A915 +82378439 A916 +82378530 A917 +82378531 A918 +82378532 A919 +82378533 A91A +82378534 A91B +82378535 A91C +82378536 A91D +82378537 A91E +82378538 A91F +82378539 A920 +82378630 A921 +82378631 A922 +82378632 A923 +82378633 A924 +82378634 A925 +82378635 A926 +82378636 A927 +82378637 A928 +82378638 A929 +82378639 A92A +82378730 A92B +82378731 A92C +82378732 A92D +82378733 A92E +82378734 A92F +82378735 A930 +82378736 A931 +82378737 A932 +82378738 A933 +82378739 A934 +82378830 A935 +82378831 A936 +82378832 A937 +82378833 A938 +82378834 A939 +82378835 A93A +82378836 A93B +82378837 A93C +82378838 A93D +82378839 A93E +82378930 A93F +82378931 A940 +82378932 A941 +82378933 A942 +82378934 A943 +82378935 A944 +82378936 A945 +82378937 A946 +82378938 A947 +82378939 A948 +82378A30 A949 +82378A31 A94A +82378A32 A94B +82378A33 A94C +82378A34 A94D +82378A35 A94E +82378A36 A94F +82378A37 A950 +82378A38 A951 +82378A39 A952 +82378B30 A953 +82378B31 A954 +82378B32 A955 +82378B33 A956 +82378B34 A957 +82378B35 A958 +82378B36 A959 +82378B37 A95A +82378B38 A95B +82378B39 A95C +82378C30 A95D +82378C31 A95E +82378C32 A95F +82378C33 A960 +82378C34 A961 +82378C35 A962 +82378C36 A963 +82378C37 A964 +82378C38 A965 +82378C39 A966 +82378D30 A967 +82378D31 A968 +82378D32 A969 +82378D33 A96A +82378D34 A96B +82378D35 A96C +82378D36 A96D +82378D37 A96E +82378D38 A96F +82378D39 A970 +82378E30 A971 +82378E31 A972 +82378E32 A973 +82378E33 A974 +82378E34 A975 +82378E35 A976 +82378E36 A977 +82378E37 A978 +82378E38 A979 +82378E39 A97A +82378F30 A97B +82378F31 A97C +82378F32 A97D +82378F33 A97E +82378F34 A97F +82378F35 A980 +82378F36 A981 +82378F37 A982 +82378F38 A983 +82378F39 A984 +82379030 A985 +82379031 A986 +82379032 A987 +82379033 A988 +82379034 A989 +82379035 A98A +82379036 A98B +82379037 A98C +82379038 A98D +82379039 A98E +82379130 A98F +82379131 A990 +82379132 A991 +82379133 A992 +82379134 A993 +82379135 A994 +82379136 A995 +82379137 A996 +82379138 A997 +82379139 A998 +82379230 A999 +82379231 A99A +82379232 A99B +82379233 A99C +82379234 A99D +82379235 A99E +82379236 A99F +82379237 A9A0 +82379238 A9A1 +82379239 A9A2 +82379330 A9A3 +82379331 A9A4 +82379332 A9A5 +82379333 A9A6 +82379334 A9A7 +82379335 A9A8 +82379336 A9A9 +82379337 A9AA +82379338 A9AB +82379339 A9AC +82379430 A9AD +82379431 A9AE +82379432 A9AF +82379433 A9B0 +82379434 A9B1 +82379435 A9B2 +82379436 A9B3 +82379437 A9B4 +82379438 A9B5 +82379439 A9B6 +82379530 A9B7 +82379531 A9B8 +82379532 A9B9 +82379533 A9BA +82379534 A9BB +82379535 A9BC +82379536 A9BD +82379537 A9BE +82379538 A9BF +82379539 A9C0 +82379630 A9C1 +82379631 A9C2 +82379632 A9C3 +82379633 A9C4 +82379634 A9C5 +82379635 A9C6 +82379636 A9C7 +82379637 A9C8 +82379638 A9C9 +82379639 A9CA +82379730 A9CB +82379731 A9CC +82379732 A9CD +82379733 A9CE +82379734 A9CF +82379735 A9D0 +82379736 A9D1 +82379737 A9D2 +82379738 A9D3 +82379739 A9D4 +82379830 A9D5 +82379831 A9D6 +82379832 A9D7 +82379833 A9D8 +82379834 A9D9 +82379835 A9DA +82379836 A9DB +82379837 A9DC +82379838 A9DD +82379839 A9DE +82379930 A9DF +82379931 A9E0 +82379932 A9E1 +82379933 A9E2 +82379934 A9E3 +82379935 A9E4 +82379936 A9E5 +82379937 A9E6 +82379938 A9E7 +82379939 A9E8 +82379A30 A9E9 +82379A31 A9EA +82379A32 A9EB +82379A33 A9EC +82379A34 A9ED +82379A35 A9EE +82379A36 A9EF +82379A37 A9F0 +82379A38 A9F1 +82379A39 A9F2 +82379B30 A9F3 +82379B31 A9F4 +82379B32 A9F5 +82379B33 A9F6 +82379B34 A9F7 +82379B35 A9F8 +82379B36 A9F9 +82379B37 A9FA +82379B38 A9FB +82379B39 A9FC +82379C30 A9FD +82379C31 A9FE +82379C32 A9FF +82379C33 AA00 +82379C34 AA01 +82379C35 AA02 +82379C36 AA03 +82379C37 AA04 +82379C38 AA05 +82379C39 AA06 +82379D30 AA07 +82379D31 AA08 +82379D32 AA09 +82379D33 AA0A +82379D34 AA0B +82379D35 AA0C +82379D36 AA0D +82379D37 AA0E +82379D38 AA0F +82379D39 AA10 +82379E30 AA11 +82379E31 AA12 +82379E32 AA13 +82379E33 AA14 +82379E34 AA15 +82379E35 AA16 +82379E36 AA17 +82379E37 AA18 +82379E38 AA19 +82379E39 AA1A +82379F30 AA1B +82379F31 AA1C +82379F32 AA1D +82379F33 AA1E +82379F34 AA1F +82379F35 AA20 +82379F36 AA21 +82379F37 AA22 +82379F38 AA23 +82379F39 AA24 +8237A030 AA25 +8237A031 AA26 +8237A032 AA27 +8237A033 AA28 +8237A034 AA29 +8237A035 AA2A +8237A036 AA2B +8237A037 AA2C +8237A038 AA2D +8237A039 AA2E +8237A130 AA2F +8237A131 AA30 +8237A132 AA31 +8237A133 AA32 +8237A134 AA33 +8237A135 AA34 +8237A136 AA35 +8237A137 AA36 +8237A138 AA37 +8237A139 AA38 +8237A230 AA39 +8237A231 AA3A +8237A232 AA3B +8237A233 AA3C +8237A234 AA3D +8237A235 AA3E +8237A236 AA3F +8237A237 AA40 +8237A238 AA41 +8237A239 AA42 +8237A330 AA43 +8237A331 AA44 +8237A332 AA45 +8237A333 AA46 +8237A334 AA47 +8237A335 AA48 +8237A336 AA49 +8237A337 AA4A +8237A338 AA4B +8237A339 AA4C +8237A430 AA4D +8237A431 AA4E +8237A432 AA4F +8237A433 AA50 +8237A434 AA51 +8237A435 AA52 +8237A436 AA53 +8237A437 AA54 +8237A438 AA55 +8237A439 AA56 +8237A530 AA57 +8237A531 AA58 +8237A532 AA59 +8237A533 AA5A +8237A534 AA5B +8237A535 AA5C +8237A536 AA5D +8237A537 AA5E +8237A538 AA5F +8237A539 AA60 +8237A630 AA61 +8237A631 AA62 +8237A632 AA63 +8237A633 AA64 +8237A634 AA65 +8237A635 AA66 +8237A636 AA67 +8237A637 AA68 +8237A638 AA69 +8237A639 AA6A +8237A730 AA6B +8237A731 AA6C +8237A732 AA6D +8237A733 AA6E +8237A734 AA6F +8237A735 AA70 +8237A736 AA71 +8237A737 AA72 +8237A738 AA73 +8237A739 AA74 +8237A830 AA75 +8237A831 AA76 +8237A832 AA77 +8237A833 AA78 +8237A834 AA79 +8237A835 AA7A +8237A836 AA7B +8237A837 AA7C +8237A838 AA7D +8237A839 AA7E +8237A930 AA7F +8237A931 AA80 +8237A932 AA81 +8237A933 AA82 +8237A934 AA83 +8237A935 AA84 +8237A936 AA85 +8237A937 AA86 +8237A938 AA87 +8237A939 AA88 +8237AA30 AA89 +8237AA31 AA8A +8237AA32 AA8B +8237AA33 AA8C +8237AA34 AA8D +8237AA35 AA8E +8237AA36 AA8F +8237AA37 AA90 +8237AA38 AA91 +8237AA39 AA92 +8237AB30 AA93 +8237AB31 AA94 +8237AB32 AA95 +8237AB33 AA96 +8237AB34 AA97 +8237AB35 AA98 +8237AB36 AA99 +8237AB37 AA9A +8237AB38 AA9B +8237AB39 AA9C +8237AC30 AA9D +8237AC31 AA9E +8237AC32 AA9F +8237AC33 AAA0 +8237AC34 AAA1 +8237AC35 AAA2 +8237AC36 AAA3 +8237AC37 AAA4 +8237AC38 AAA5 +8237AC39 AAA6 +8237AD30 AAA7 +8237AD31 AAA8 +8237AD32 AAA9 +8237AD33 AAAA +8237AD34 AAAB +8237AD35 AAAC +8237AD36 AAAD +8237AD37 AAAE +8237AD38 AAAF +8237AD39 AAB0 +8237AE30 AAB1 +8237AE31 AAB2 +8237AE32 AAB3 +8237AE33 AAB4 +8237AE34 AAB5 +8237AE35 AAB6 +8237AE36 AAB7 +8237AE37 AAB8 +8237AE38 AAB9 +8237AE39 AABA +8237AF30 AABB +8237AF31 AABC +8237AF32 AABD +8237AF33 AABE +8237AF34 AABF +8237AF35 AAC0 +8237AF36 AAC1 +8237AF37 AAC2 +8237AF38 AAC3 +8237AF39 AAC4 +8237B030 AAC5 +8237B031 AAC6 +8237B032 AAC7 +8237B033 AAC8 +8237B034 AAC9 +8237B035 AACA +8237B036 AACB +8237B037 AACC +8237B038 AACD +8237B039 AACE +8237B130 AACF +8237B131 AAD0 +8237B132 AAD1 +8237B133 AAD2 +8237B134 AAD3 +8237B135 AAD4 +8237B136 AAD5 +8237B137 AAD6 +8237B138 AAD7 +8237B139 AAD8 +8237B230 AAD9 +8237B231 AADA +8237B232 AADB +8237B233 AADC +8237B234 AADD +8237B235 AADE +8237B236 AADF +8237B237 AAE0 +8237B238 AAE1 +8237B239 AAE2 +8237B330 AAE3 +8237B331 AAE4 +8237B332 AAE5 +8237B333 AAE6 +8237B334 AAE7 +8237B335 AAE8 +8237B336 AAE9 +8237B337 AAEA +8237B338 AAEB +8237B339 AAEC +8237B430 AAED +8237B431 AAEE +8237B432 AAEF +8237B433 AAF0 +8237B434 AAF1 +8237B435 AAF2 +8237B436 AAF3 +8237B437 AAF4 +8237B438 AAF5 +8237B439 AAF6 +8237B530 AAF7 +8237B531 AAF8 +8237B532 AAF9 +8237B533 AAFA +8237B534 AAFB +8237B535 AAFC +8237B536 AAFD +8237B537 AAFE +8237B538 AAFF +8237B539 AB00 +8237B630 AB01 +8237B631 AB02 +8237B632 AB03 +8237B633 AB04 +8237B634 AB05 +8237B635 AB06 +8237B636 AB07 +8237B637 AB08 +8237B638 AB09 +8237B639 AB0A +8237B730 AB0B +8237B731 AB0C +8237B732 AB0D +8237B733 AB0E +8237B734 AB0F +8237B735 AB10 +8237B736 AB11 +8237B737 AB12 +8237B738 AB13 +8237B739 AB14 +8237B830 AB15 +8237B831 AB16 +8237B832 AB17 +8237B833 AB18 +8237B834 AB19 +8237B835 AB1A +8237B836 AB1B +8237B837 AB1C +8237B838 AB1D +8237B839 AB1E +8237B930 AB1F +8237B931 AB20 +8237B932 AB21 +8237B933 AB22 +8237B934 AB23 +8237B935 AB24 +8237B936 AB25 +8237B937 AB26 +8237B938 AB27 +8237B939 AB28 +8237BA30 AB29 +8237BA31 AB2A +8237BA32 AB2B +8237BA33 AB2C +8237BA34 AB2D +8237BA35 AB2E +8237BA36 AB2F +8237BA37 AB30 +8237BA38 AB31 +8237BA39 AB32 +8237BB30 AB33 +8237BB31 AB34 +8237BB32 AB35 +8237BB33 AB36 +8237BB34 AB37 +8237BB35 AB38 +8237BB36 AB39 +8237BB37 AB3A +8237BB38 AB3B +8237BB39 AB3C +8237BC30 AB3D +8237BC31 AB3E +8237BC32 AB3F +8237BC33 AB40 +8237BC34 AB41 +8237BC35 AB42 +8237BC36 AB43 +8237BC37 AB44 +8237BC38 AB45 +8237BC39 AB46 +8237BD30 AB47 +8237BD31 AB48 +8237BD32 AB49 +8237BD33 AB4A +8237BD34 AB4B +8237BD35 AB4C +8237BD36 AB4D +8237BD37 AB4E +8237BD38 AB4F +8237BD39 AB50 +8237BE30 AB51 +8237BE31 AB52 +8237BE32 AB53 +8237BE33 AB54 +8237BE34 AB55 +8237BE35 AB56 +8237BE36 AB57 +8237BE37 AB58 +8237BE38 AB59 +8237BE39 AB5A +8237BF30 AB5B +8237BF31 AB5C +8237BF32 AB5D +8237BF33 AB5E +8237BF34 AB5F +8237BF35 AB60 +8237BF36 AB61 +8237BF37 AB62 +8237BF38 AB63 +8237BF39 AB64 +8237C030 AB65 +8237C031 AB66 +8237C032 AB67 +8237C033 AB68 +8237C034 AB69 +8237C035 AB6A +8237C036 AB6B +8237C037 AB6C +8237C038 AB6D +8237C039 AB6E +8237C130 AB6F +8237C131 AB70 +8237C132 AB71 +8237C133 AB72 +8237C134 AB73 +8237C135 AB74 +8237C136 AB75 +8237C137 AB76 +8237C138 AB77 +8237C139 AB78 +8237C230 AB79 +8237C231 AB7A +8237C232 AB7B +8237C233 AB7C +8237C234 AB7D +8237C235 AB7E +8237C236 AB7F +8237C237 AB80 +8237C238 AB81 +8237C239 AB82 +8237C330 AB83 +8237C331 AB84 +8237C332 AB85 +8237C333 AB86 +8237C334 AB87 +8237C335 AB88 +8237C336 AB89 +8237C337 AB8A +8237C338 AB8B +8237C339 AB8C +8237C430 AB8D +8237C431 AB8E +8237C432 AB8F +8237C433 AB90 +8237C434 AB91 +8237C435 AB92 +8237C436 AB93 +8237C437 AB94 +8237C438 AB95 +8237C439 AB96 +8237C530 AB97 +8237C531 AB98 +8237C532 AB99 +8237C533 AB9A +8237C534 AB9B +8237C535 AB9C +8237C536 AB9D +8237C537 AB9E +8237C538 AB9F +8237C539 ABA0 +8237C630 ABA1 +8237C631 ABA2 +8237C632 ABA3 +8237C633 ABA4 +8237C634 ABA5 +8237C635 ABA6 +8237C636 ABA7 +8237C637 ABA8 +8237C638 ABA9 +8237C639 ABAA +8237C730 ABAB +8237C731 ABAC +8237C732 ABAD +8237C733 ABAE +8237C734 ABAF +8237C735 ABB0 +8237C736 ABB1 +8237C737 ABB2 +8237C738 ABB3 +8237C739 ABB4 +8237C830 ABB5 +8237C831 ABB6 +8237C832 ABB7 +8237C833 ABB8 +8237C834 ABB9 +8237C835 ABBA +8237C836 ABBB +8237C837 ABBC +8237C838 ABBD +8237C839 ABBE +8237C930 ABBF +8237C931 ABC0 +8237C932 ABC1 +8237C933 ABC2 +8237C934 ABC3 +8237C935 ABC4 +8237C936 ABC5 +8237C937 ABC6 +8237C938 ABC7 +8237C939 ABC8 +8237CA30 ABC9 +8237CA31 ABCA +8237CA32 ABCB +8237CA33 ABCC +8237CA34 ABCD +8237CA35 ABCE +8237CA36 ABCF +8237CA37 ABD0 +8237CA38 ABD1 +8237CA39 ABD2 +8237CB30 ABD3 +8237CB31 ABD4 +8237CB32 ABD5 +8237CB33 ABD6 +8237CB34 ABD7 +8237CB35 ABD8 +8237CB36 ABD9 +8237CB37 ABDA +8237CB38 ABDB +8237CB39 ABDC +8237CC30 ABDD +8237CC31 ABDE +8237CC32 ABDF +8237CC33 ABE0 +8237CC34 ABE1 +8237CC35 ABE2 +8237CC36 ABE3 +8237CC37 ABE4 +8237CC38 ABE5 +8237CC39 ABE6 +8237CD30 ABE7 +8237CD31 ABE8 +8237CD32 ABE9 +8237CD33 ABEA +8237CD34 ABEB +8237CD35 ABEC +8237CD36 ABED +8237CD37 ABEE +8237CD38 ABEF +8237CD39 ABF0 +8237CE30 ABF1 +8237CE31 ABF2 +8237CE32 ABF3 +8237CE33 ABF4 +8237CE34 ABF5 +8237CE35 ABF6 +8237CE36 ABF7 +8237CE37 ABF8 +8237CE38 ABF9 +8237CE39 ABFA +8237CF30 ABFB +8237CF31 ABFC +8237CF32 ABFD +8237CF33 ABFE +8237CF34 ABFF +8237CF35 AC00 +8237CF36 AC01 +8237CF37 AC02 +8237CF38 AC03 +8237CF39 AC04 +8237D030 AC05 +8237D031 AC06 +8237D032 AC07 +8237D033 AC08 +8237D034 AC09 +8237D035 AC0A +8237D036 AC0B +8237D037 AC0C +8237D038 AC0D +8237D039 AC0E +8237D130 AC0F +8237D131 AC10 +8237D132 AC11 +8237D133 AC12 +8237D134 AC13 +8237D135 AC14 +8237D136 AC15 +8237D137 AC16 +8237D138 AC17 +8237D139 AC18 +8237D230 AC19 +8237D231 AC1A +8237D232 AC1B +8237D233 AC1C +8237D234 AC1D +8237D235 AC1E +8237D236 AC1F +8237D237 AC20 +8237D238 AC21 +8237D239 AC22 +8237D330 AC23 +8237D331 AC24 +8237D332 AC25 +8237D333 AC26 +8237D334 AC27 +8237D335 AC28 +8237D336 AC29 +8237D337 AC2A +8237D338 AC2B +8237D339 AC2C +8237D430 AC2D +8237D431 AC2E +8237D432 AC2F +8237D433 AC30 +8237D434 AC31 +8237D435 AC32 +8237D436 AC33 +8237D437 AC34 +8237D438 AC35 +8237D439 AC36 +8237D530 AC37 +8237D531 AC38 +8237D532 AC39 +8237D533 AC3A +8237D534 AC3B +8237D535 AC3C +8237D536 AC3D +8237D537 AC3E +8237D538 AC3F +8237D539 AC40 +8237D630 AC41 +8237D631 AC42 +8237D632 AC43 +8237D633 AC44 +8237D634 AC45 +8237D635 AC46 +8237D636 AC47 +8237D637 AC48 +8237D638 AC49 +8237D639 AC4A +8237D730 AC4B +8237D731 AC4C +8237D732 AC4D +8237D733 AC4E +8237D734 AC4F +8237D735 AC50 +8237D736 AC51 +8237D737 AC52 +8237D738 AC53 +8237D739 AC54 +8237D830 AC55 +8237D831 AC56 +8237D832 AC57 +8237D833 AC58 +8237D834 AC59 +8237D835 AC5A +8237D836 AC5B +8237D837 AC5C +8237D838 AC5D +8237D839 AC5E +8237D930 AC5F +8237D931 AC60 +8237D932 AC61 +8237D933 AC62 +8237D934 AC63 +8237D935 AC64 +8237D936 AC65 +8237D937 AC66 +8237D938 AC67 +8237D939 AC68 +8237DA30 AC69 +8237DA31 AC6A +8237DA32 AC6B +8237DA33 AC6C +8237DA34 AC6D +8237DA35 AC6E +8237DA36 AC6F +8237DA37 AC70 +8237DA38 AC71 +8237DA39 AC72 +8237DB30 AC73 +8237DB31 AC74 +8237DB32 AC75 +8237DB33 AC76 +8237DB34 AC77 +8237DB35 AC78 +8237DB36 AC79 +8237DB37 AC7A +8237DB38 AC7B +8237DB39 AC7C +8237DC30 AC7D +8237DC31 AC7E +8237DC32 AC7F +8237DC33 AC80 +8237DC34 AC81 +8237DC35 AC82 +8237DC36 AC83 +8237DC37 AC84 +8237DC38 AC85 +8237DC39 AC86 +8237DD30 AC87 +8237DD31 AC88 +8237DD32 AC89 +8237DD33 AC8A +8237DD34 AC8B +8237DD35 AC8C +8237DD36 AC8D +8237DD37 AC8E +8237DD38 AC8F +8237DD39 AC90 +8237DE30 AC91 +8237DE31 AC92 +8237DE32 AC93 +8237DE33 AC94 +8237DE34 AC95 +8237DE35 AC96 +8237DE36 AC97 +8237DE37 AC98 +8237DE38 AC99 +8237DE39 AC9A +8237DF30 AC9B +8237DF31 AC9C +8237DF32 AC9D +8237DF33 AC9E +8237DF34 AC9F +8237DF35 ACA0 +8237DF36 ACA1 +8237DF37 ACA2 +8237DF38 ACA3 +8237DF39 ACA4 +8237E030 ACA5 +8237E031 ACA6 +8237E032 ACA7 +8237E033 ACA8 +8237E034 ACA9 +8237E035 ACAA +8237E036 ACAB +8237E037 ACAC +8237E038 ACAD +8237E039 ACAE +8237E130 ACAF +8237E131 ACB0 +8237E132 ACB1 +8237E133 ACB2 +8237E134 ACB3 +8237E135 ACB4 +8237E136 ACB5 +8237E137 ACB6 +8237E138 ACB7 +8237E139 ACB8 +8237E230 ACB9 +8237E231 ACBA +8237E232 ACBB +8237E233 ACBC +8237E234 ACBD +8237E235 ACBE +8237E236 ACBF +8237E237 ACC0 +8237E238 ACC1 +8237E239 ACC2 +8237E330 ACC3 +8237E331 ACC4 +8237E332 ACC5 +8237E333 ACC6 +8237E334 ACC7 +8237E335 ACC8 +8237E336 ACC9 +8237E337 ACCA +8237E338 ACCB +8237E339 ACCC +8237E430 ACCD +8237E431 ACCE +8237E432 ACCF +8237E433 ACD0 +8237E434 ACD1 +8237E435 ACD2 +8237E436 ACD3 +8237E437 ACD4 +8237E438 ACD5 +8237E439 ACD6 +8237E530 ACD7 +8237E531 ACD8 +8237E532 ACD9 +8237E533 ACDA +8237E534 ACDB +8237E535 ACDC +8237E536 ACDD +8237E537 ACDE +8237E538 ACDF +8237E539 ACE0 +8237E630 ACE1 +8237E631 ACE2 +8237E632 ACE3 +8237E633 ACE4 +8237E634 ACE5 +8237E635 ACE6 +8237E636 ACE7 +8237E637 ACE8 +8237E638 ACE9 +8237E639 ACEA +8237E730 ACEB +8237E731 ACEC +8237E732 ACED +8237E733 ACEE +8237E734 ACEF +8237E735 ACF0 +8237E736 ACF1 +8237E737 ACF2 +8237E738 ACF3 +8237E739 ACF4 +8237E830 ACF5 +8237E831 ACF6 +8237E832 ACF7 +8237E833 ACF8 +8237E834 ACF9 +8237E835 ACFA +8237E836 ACFB +8237E837 ACFC +8237E838 ACFD +8237E839 ACFE +8237E930 ACFF +8237E931 AD00 +8237E932 AD01 +8237E933 AD02 +8237E934 AD03 +8237E935 AD04 +8237E936 AD05 +8237E937 AD06 +8237E938 AD07 +8237E939 AD08 +8237EA30 AD09 +8237EA31 AD0A +8237EA32 AD0B +8237EA33 AD0C +8237EA34 AD0D +8237EA35 AD0E +8237EA36 AD0F +8237EA37 AD10 +8237EA38 AD11 +8237EA39 AD12 +8237EB30 AD13 +8237EB31 AD14 +8237EB32 AD15 +8237EB33 AD16 +8237EB34 AD17 +8237EB35 AD18 +8237EB36 AD19 +8237EB37 AD1A +8237EB38 AD1B +8237EB39 AD1C +8237EC30 AD1D +8237EC31 AD1E +8237EC32 AD1F +8237EC33 AD20 +8237EC34 AD21 +8237EC35 AD22 +8237EC36 AD23 +8237EC37 AD24 +8237EC38 AD25 +8237EC39 AD26 +8237ED30 AD27 +8237ED31 AD28 +8237ED32 AD29 +8237ED33 AD2A +8237ED34 AD2B +8237ED35 AD2C +8237ED36 AD2D +8237ED37 AD2E +8237ED38 AD2F +8237ED39 AD30 +8237EE30 AD31 +8237EE31 AD32 +8237EE32 AD33 +8237EE33 AD34 +8237EE34 AD35 +8237EE35 AD36 +8237EE36 AD37 +8237EE37 AD38 +8237EE38 AD39 +8237EE39 AD3A +8237EF30 AD3B +8237EF31 AD3C +8237EF32 AD3D +8237EF33 AD3E +8237EF34 AD3F +8237EF35 AD40 +8237EF36 AD41 +8237EF37 AD42 +8237EF38 AD43 +8237EF39 AD44 +8237F030 AD45 +8237F031 AD46 +8237F032 AD47 +8237F033 AD48 +8237F034 AD49 +8237F035 AD4A +8237F036 AD4B +8237F037 AD4C +8237F038 AD4D +8237F039 AD4E +8237F130 AD4F +8237F131 AD50 +8237F132 AD51 +8237F133 AD52 +8237F134 AD53 +8237F135 AD54 +8237F136 AD55 +8237F137 AD56 +8237F138 AD57 +8237F139 AD58 +8237F230 AD59 +8237F231 AD5A +8237F232 AD5B +8237F233 AD5C +8237F234 AD5D +8237F235 AD5E +8237F236 AD5F +8237F237 AD60 +8237F238 AD61 +8237F239 AD62 +8237F330 AD63 +8237F331 AD64 +8237F332 AD65 +8237F333 AD66 +8237F334 AD67 +8237F335 AD68 +8237F336 AD69 +8237F337 AD6A +8237F338 AD6B +8237F339 AD6C +8237F430 AD6D +8237F431 AD6E +8237F432 AD6F +8237F433 AD70 +8237F434 AD71 +8237F435 AD72 +8237F436 AD73 +8237F437 AD74 +8237F438 AD75 +8237F439 AD76 +8237F530 AD77 +8237F531 AD78 +8237F532 AD79 +8237F533 AD7A +8237F534 AD7B +8237F535 AD7C +8237F536 AD7D +8237F537 AD7E +8237F538 AD7F +8237F539 AD80 +8237F630 AD81 +8237F631 AD82 +8237F632 AD83 +8237F633 AD84 +8237F634 AD85 +8237F635 AD86 +8237F636 AD87 +8237F637 AD88 +8237F638 AD89 +8237F639 AD8A +8237F730 AD8B +8237F731 AD8C +8237F732 AD8D +8237F733 AD8E +8237F734 AD8F +8237F735 AD90 +8237F736 AD91 +8237F737 AD92 +8237F738 AD93 +8237F739 AD94 +8237F830 AD95 +8237F831 AD96 +8237F832 AD97 +8237F833 AD98 +8237F834 AD99 +8237F835 AD9A +8237F836 AD9B +8237F837 AD9C +8237F838 AD9D +8237F839 AD9E +8237F930 AD9F +8237F931 ADA0 +8237F932 ADA1 +8237F933 ADA2 +8237F934 ADA3 +8237F935 ADA4 +8237F936 ADA5 +8237F937 ADA6 +8237F938 ADA7 +8237F939 ADA8 +8237FA30 ADA9 +8237FA31 ADAA +8237FA32 ADAB +8237FA33 ADAC +8237FA34 ADAD +8237FA35 ADAE +8237FA36 ADAF +8237FA37 ADB0 +8237FA38 ADB1 +8237FA39 ADB2 +8237FB30 ADB3 +8237FB31 ADB4 +8237FB32 ADB5 +8237FB33 ADB6 +8237FB34 ADB7 +8237FB35 ADB8 +8237FB36 ADB9 +8237FB37 ADBA +8237FB38 ADBB +8237FB39 ADBC +8237FC30 ADBD +8237FC31 ADBE +8237FC32 ADBF +8237FC33 ADC0 +8237FC34 ADC1 +8237FC35 ADC2 +8237FC36 ADC3 +8237FC37 ADC4 +8237FC38 ADC5 +8237FC39 ADC6 +8237FD30 ADC7 +8237FD31 ADC8 +8237FD32 ADC9 +8237FD33 ADCA +8237FD34 ADCB +8237FD35 ADCC +8237FD36 ADCD +8237FD37 ADCE +8237FD38 ADCF +8237FD39 ADD0 +8237FE30 ADD1 +8237FE31 ADD2 +8237FE32 ADD3 +8237FE33 ADD4 +8237FE34 ADD5 +8237FE35 ADD6 +8237FE36 ADD7 +8237FE37 ADD8 +8237FE38 ADD9 +8237FE39 ADDA +82388130 ADDB +82388131 ADDC +82388132 ADDD +82388133 ADDE +82388134 ADDF +82388135 ADE0 +82388136 ADE1 +82388137 ADE2 +82388138 ADE3 +82388139 ADE4 +82388230 ADE5 +82388231 ADE6 +82388232 ADE7 +82388233 ADE8 +82388234 ADE9 +82388235 ADEA +82388236 ADEB +82388237 ADEC +82388238 ADED +82388239 ADEE +82388330 ADEF +82388331 ADF0 +82388332 ADF1 +82388333 ADF2 +82388334 ADF3 +82388335 ADF4 +82388336 ADF5 +82388337 ADF6 +82388338 ADF7 +82388339 ADF8 +82388430 ADF9 +82388431 ADFA +82388432 ADFB +82388433 ADFC +82388434 ADFD +82388435 ADFE +82388436 ADFF +82388437 AE00 +82388438 AE01 +82388439 AE02 +82388530 AE03 +82388531 AE04 +82388532 AE05 +82388533 AE06 +82388534 AE07 +82388535 AE08 +82388536 AE09 +82388537 AE0A +82388538 AE0B +82388539 AE0C +82388630 AE0D +82388631 AE0E +82388632 AE0F +82388633 AE10 +82388634 AE11 +82388635 AE12 +82388636 AE13 +82388637 AE14 +82388638 AE15 +82388639 AE16 +82388730 AE17 +82388731 AE18 +82388732 AE19 +82388733 AE1A +82388734 AE1B +82388735 AE1C +82388736 AE1D +82388737 AE1E +82388738 AE1F +82388739 AE20 +82388830 AE21 +82388831 AE22 +82388832 AE23 +82388833 AE24 +82388834 AE25 +82388835 AE26 +82388836 AE27 +82388837 AE28 +82388838 AE29 +82388839 AE2A +82388930 AE2B +82388931 AE2C +82388932 AE2D +82388933 AE2E +82388934 AE2F +82388935 AE30 +82388936 AE31 +82388937 AE32 +82388938 AE33 +82388939 AE34 +82388A30 AE35 +82388A31 AE36 +82388A32 AE37 +82388A33 AE38 +82388A34 AE39 +82388A35 AE3A +82388A36 AE3B +82388A37 AE3C +82388A38 AE3D +82388A39 AE3E +82388B30 AE3F +82388B31 AE40 +82388B32 AE41 +82388B33 AE42 +82388B34 AE43 +82388B35 AE44 +82388B36 AE45 +82388B37 AE46 +82388B38 AE47 +82388B39 AE48 +82388C30 AE49 +82388C31 AE4A +82388C32 AE4B +82388C33 AE4C +82388C34 AE4D +82388C35 AE4E +82388C36 AE4F +82388C37 AE50 +82388C38 AE51 +82388C39 AE52 +82388D30 AE53 +82388D31 AE54 +82388D32 AE55 +82388D33 AE56 +82388D34 AE57 +82388D35 AE58 +82388D36 AE59 +82388D37 AE5A +82388D38 AE5B +82388D39 AE5C +82388E30 AE5D +82388E31 AE5E +82388E32 AE5F +82388E33 AE60 +82388E34 AE61 +82388E35 AE62 +82388E36 AE63 +82388E37 AE64 +82388E38 AE65 +82388E39 AE66 +82388F30 AE67 +82388F31 AE68 +82388F32 AE69 +82388F33 AE6A +82388F34 AE6B +82388F35 AE6C +82388F36 AE6D +82388F37 AE6E +82388F38 AE6F +82388F39 AE70 +82389030 AE71 +82389031 AE72 +82389032 AE73 +82389033 AE74 +82389034 AE75 +82389035 AE76 +82389036 AE77 +82389037 AE78 +82389038 AE79 +82389039 AE7A +82389130 AE7B +82389131 AE7C +82389132 AE7D +82389133 AE7E +82389134 AE7F +82389135 AE80 +82389136 AE81 +82389137 AE82 +82389138 AE83 +82389139 AE84 +82389230 AE85 +82389231 AE86 +82389232 AE87 +82389233 AE88 +82389234 AE89 +82389235 AE8A +82389236 AE8B +82389237 AE8C +82389238 AE8D +82389239 AE8E +82389330 AE8F +82389331 AE90 +82389332 AE91 +82389333 AE92 +82389334 AE93 +82389335 AE94 +82389336 AE95 +82389337 AE96 +82389338 AE97 +82389339 AE98 +82389430 AE99 +82389431 AE9A +82389432 AE9B +82389433 AE9C +82389434 AE9D +82389435 AE9E +82389436 AE9F +82389437 AEA0 +82389438 AEA1 +82389439 AEA2 +82389530 AEA3 +82389531 AEA4 +82389532 AEA5 +82389533 AEA6 +82389534 AEA7 +82389535 AEA8 +82389536 AEA9 +82389537 AEAA +82389538 AEAB +82389539 AEAC +82389630 AEAD +82389631 AEAE +82389632 AEAF +82389633 AEB0 +82389634 AEB1 +82389635 AEB2 +82389636 AEB3 +82389637 AEB4 +82389638 AEB5 +82389639 AEB6 +82389730 AEB7 +82389731 AEB8 +82389732 AEB9 +82389733 AEBA +82389734 AEBB +82389735 AEBC +82389736 AEBD +82389737 AEBE +82389738 AEBF +82389739 AEC0 +82389830 AEC1 +82389831 AEC2 +82389832 AEC3 +82389833 AEC4 +82389834 AEC5 +82389835 AEC6 +82389836 AEC7 +82389837 AEC8 +82389838 AEC9 +82389839 AECA +82389930 AECB +82389931 AECC +82389932 AECD +82389933 AECE +82389934 AECF +82389935 AED0 +82389936 AED1 +82389937 AED2 +82389938 AED3 +82389939 AED4 +82389A30 AED5 +82389A31 AED6 +82389A32 AED7 +82389A33 AED8 +82389A34 AED9 +82389A35 AEDA +82389A36 AEDB +82389A37 AEDC +82389A38 AEDD +82389A39 AEDE +82389B30 AEDF +82389B31 AEE0 +82389B32 AEE1 +82389B33 AEE2 +82389B34 AEE3 +82389B35 AEE4 +82389B36 AEE5 +82389B37 AEE6 +82389B38 AEE7 +82389B39 AEE8 +82389C30 AEE9 +82389C31 AEEA +82389C32 AEEB +82389C33 AEEC +82389C34 AEED +82389C35 AEEE +82389C36 AEEF +82389C37 AEF0 +82389C38 AEF1 +82389C39 AEF2 +82389D30 AEF3 +82389D31 AEF4 +82389D32 AEF5 +82389D33 AEF6 +82389D34 AEF7 +82389D35 AEF8 +82389D36 AEF9 +82389D37 AEFA +82389D38 AEFB +82389D39 AEFC +82389E30 AEFD +82389E31 AEFE +82389E32 AEFF +82389E33 AF00 +82389E34 AF01 +82389E35 AF02 +82389E36 AF03 +82389E37 AF04 +82389E38 AF05 +82389E39 AF06 +82389F30 AF07 +82389F31 AF08 +82389F32 AF09 +82389F33 AF0A +82389F34 AF0B +82389F35 AF0C +82389F36 AF0D +82389F37 AF0E +82389F38 AF0F +82389F39 AF10 +8238A030 AF11 +8238A031 AF12 +8238A032 AF13 +8238A033 AF14 +8238A034 AF15 +8238A035 AF16 +8238A036 AF17 +8238A037 AF18 +8238A038 AF19 +8238A039 AF1A +8238A130 AF1B +8238A131 AF1C +8238A132 AF1D +8238A133 AF1E +8238A134 AF1F +8238A135 AF20 +8238A136 AF21 +8238A137 AF22 +8238A138 AF23 +8238A139 AF24 +8238A230 AF25 +8238A231 AF26 +8238A232 AF27 +8238A233 AF28 +8238A234 AF29 +8238A235 AF2A +8238A236 AF2B +8238A237 AF2C +8238A238 AF2D +8238A239 AF2E +8238A330 AF2F +8238A331 AF30 +8238A332 AF31 +8238A333 AF32 +8238A334 AF33 +8238A335 AF34 +8238A336 AF35 +8238A337 AF36 +8238A338 AF37 +8238A339 AF38 +8238A430 AF39 +8238A431 AF3A +8238A432 AF3B +8238A433 AF3C +8238A434 AF3D +8238A435 AF3E +8238A436 AF3F +8238A437 AF40 +8238A438 AF41 +8238A439 AF42 +8238A530 AF43 +8238A531 AF44 +8238A532 AF45 +8238A533 AF46 +8238A534 AF47 +8238A535 AF48 +8238A536 AF49 +8238A537 AF4A +8238A538 AF4B +8238A539 AF4C +8238A630 AF4D +8238A631 AF4E +8238A632 AF4F +8238A633 AF50 +8238A634 AF51 +8238A635 AF52 +8238A636 AF53 +8238A637 AF54 +8238A638 AF55 +8238A639 AF56 +8238A730 AF57 +8238A731 AF58 +8238A732 AF59 +8238A733 AF5A +8238A734 AF5B +8238A735 AF5C +8238A736 AF5D +8238A737 AF5E +8238A738 AF5F +8238A739 AF60 +8238A830 AF61 +8238A831 AF62 +8238A832 AF63 +8238A833 AF64 +8238A834 AF65 +8238A835 AF66 +8238A836 AF67 +8238A837 AF68 +8238A838 AF69 +8238A839 AF6A +8238A930 AF6B +8238A931 AF6C +8238A932 AF6D +8238A933 AF6E +8238A934 AF6F +8238A935 AF70 +8238A936 AF71 +8238A937 AF72 +8238A938 AF73 +8238A939 AF74 +8238AA30 AF75 +8238AA31 AF76 +8238AA32 AF77 +8238AA33 AF78 +8238AA34 AF79 +8238AA35 AF7A +8238AA36 AF7B +8238AA37 AF7C +8238AA38 AF7D +8238AA39 AF7E +8238AB30 AF7F +8238AB31 AF80 +8238AB32 AF81 +8238AB33 AF82 +8238AB34 AF83 +8238AB35 AF84 +8238AB36 AF85 +8238AB37 AF86 +8238AB38 AF87 +8238AB39 AF88 +8238AC30 AF89 +8238AC31 AF8A +8238AC32 AF8B +8238AC33 AF8C +8238AC34 AF8D +8238AC35 AF8E +8238AC36 AF8F +8238AC37 AF90 +8238AC38 AF91 +8238AC39 AF92 +8238AD30 AF93 +8238AD31 AF94 +8238AD32 AF95 +8238AD33 AF96 +8238AD34 AF97 +8238AD35 AF98 +8238AD36 AF99 +8238AD37 AF9A +8238AD38 AF9B +8238AD39 AF9C +8238AE30 AF9D +8238AE31 AF9E +8238AE32 AF9F +8238AE33 AFA0 +8238AE34 AFA1 +8238AE35 AFA2 +8238AE36 AFA3 +8238AE37 AFA4 +8238AE38 AFA5 +8238AE39 AFA6 +8238AF30 AFA7 +8238AF31 AFA8 +8238AF32 AFA9 +8238AF33 AFAA +8238AF34 AFAB +8238AF35 AFAC +8238AF36 AFAD +8238AF37 AFAE +8238AF38 AFAF +8238AF39 AFB0 +8238B030 AFB1 +8238B031 AFB2 +8238B032 AFB3 +8238B033 AFB4 +8238B034 AFB5 +8238B035 AFB6 +8238B036 AFB7 +8238B037 AFB8 +8238B038 AFB9 +8238B039 AFBA +8238B130 AFBB +8238B131 AFBC +8238B132 AFBD +8238B133 AFBE +8238B134 AFBF +8238B135 AFC0 +8238B136 AFC1 +8238B137 AFC2 +8238B138 AFC3 +8238B139 AFC4 +8238B230 AFC5 +8238B231 AFC6 +8238B232 AFC7 +8238B233 AFC8 +8238B234 AFC9 +8238B235 AFCA +8238B236 AFCB +8238B237 AFCC +8238B238 AFCD +8238B239 AFCE +8238B330 AFCF +8238B331 AFD0 +8238B332 AFD1 +8238B333 AFD2 +8238B334 AFD3 +8238B335 AFD4 +8238B336 AFD5 +8238B337 AFD6 +8238B338 AFD7 +8238B339 AFD8 +8238B430 AFD9 +8238B431 AFDA +8238B432 AFDB +8238B433 AFDC +8238B434 AFDD +8238B435 AFDE +8238B436 AFDF +8238B437 AFE0 +8238B438 AFE1 +8238B439 AFE2 +8238B530 AFE3 +8238B531 AFE4 +8238B532 AFE5 +8238B533 AFE6 +8238B534 AFE7 +8238B535 AFE8 +8238B536 AFE9 +8238B537 AFEA +8238B538 AFEB +8238B539 AFEC +8238B630 AFED +8238B631 AFEE +8238B632 AFEF +8238B633 AFF0 +8238B634 AFF1 +8238B635 AFF2 +8238B636 AFF3 +8238B637 AFF4 +8238B638 AFF5 +8238B639 AFF6 +8238B730 AFF7 +8238B731 AFF8 +8238B732 AFF9 +8238B733 AFFA +8238B734 AFFB +8238B735 AFFC +8238B736 AFFD +8238B737 AFFE +8238B738 AFFF +8238B739 B000 +8238B830 B001 +8238B831 B002 +8238B832 B003 +8238B833 B004 +8238B834 B005 +8238B835 B006 +8238B836 B007 +8238B837 B008 +8238B838 B009 +8238B839 B00A +8238B930 B00B +8238B931 B00C +8238B932 B00D +8238B933 B00E +8238B934 B00F +8238B935 B010 +8238B936 B011 +8238B937 B012 +8238B938 B013 +8238B939 B014 +8238BA30 B015 +8238BA31 B016 +8238BA32 B017 +8238BA33 B018 +8238BA34 B019 +8238BA35 B01A +8238BA36 B01B +8238BA37 B01C +8238BA38 B01D +8238BA39 B01E +8238BB30 B01F +8238BB31 B020 +8238BB32 B021 +8238BB33 B022 +8238BB34 B023 +8238BB35 B024 +8238BB36 B025 +8238BB37 B026 +8238BB38 B027 +8238BB39 B028 +8238BC30 B029 +8238BC31 B02A +8238BC32 B02B +8238BC33 B02C +8238BC34 B02D +8238BC35 B02E +8238BC36 B02F +8238BC37 B030 +8238BC38 B031 +8238BC39 B032 +8238BD30 B033 +8238BD31 B034 +8238BD32 B035 +8238BD33 B036 +8238BD34 B037 +8238BD35 B038 +8238BD36 B039 +8238BD37 B03A +8238BD38 B03B +8238BD39 B03C +8238BE30 B03D +8238BE31 B03E +8238BE32 B03F +8238BE33 B040 +8238BE34 B041 +8238BE35 B042 +8238BE36 B043 +8238BE37 B044 +8238BE38 B045 +8238BE39 B046 +8238BF30 B047 +8238BF31 B048 +8238BF32 B049 +8238BF33 B04A +8238BF34 B04B +8238BF35 B04C +8238BF36 B04D +8238BF37 B04E +8238BF38 B04F +8238BF39 B050 +8238C030 B051 +8238C031 B052 +8238C032 B053 +8238C033 B054 +8238C034 B055 +8238C035 B056 +8238C036 B057 +8238C037 B058 +8238C038 B059 +8238C039 B05A +8238C130 B05B +8238C131 B05C +8238C132 B05D +8238C133 B05E +8238C134 B05F +8238C135 B060 +8238C136 B061 +8238C137 B062 +8238C138 B063 +8238C139 B064 +8238C230 B065 +8238C231 B066 +8238C232 B067 +8238C233 B068 +8238C234 B069 +8238C235 B06A +8238C236 B06B +8238C237 B06C +8238C238 B06D +8238C239 B06E +8238C330 B06F +8238C331 B070 +8238C332 B071 +8238C333 B072 +8238C334 B073 +8238C335 B074 +8238C336 B075 +8238C337 B076 +8238C338 B077 +8238C339 B078 +8238C430 B079 +8238C431 B07A +8238C432 B07B +8238C433 B07C +8238C434 B07D +8238C435 B07E +8238C436 B07F +8238C437 B080 +8238C438 B081 +8238C439 B082 +8238C530 B083 +8238C531 B084 +8238C532 B085 +8238C533 B086 +8238C534 B087 +8238C535 B088 +8238C536 B089 +8238C537 B08A +8238C538 B08B +8238C539 B08C +8238C630 B08D +8238C631 B08E +8238C632 B08F +8238C633 B090 +8238C634 B091 +8238C635 B092 +8238C636 B093 +8238C637 B094 +8238C638 B095 +8238C639 B096 +8238C730 B097 +8238C731 B098 +8238C732 B099 +8238C733 B09A +8238C734 B09B +8238C735 B09C +8238C736 B09D +8238C737 B09E +8238C738 B09F +8238C739 B0A0 +8238C830 B0A1 +8238C831 B0A2 +8238C832 B0A3 +8238C833 B0A4 +8238C834 B0A5 +8238C835 B0A6 +8238C836 B0A7 +8238C837 B0A8 +8238C838 B0A9 +8238C839 B0AA +8238C930 B0AB +8238C931 B0AC +8238C932 B0AD +8238C933 B0AE +8238C934 B0AF +8238C935 B0B0 +8238C936 B0B1 +8238C937 B0B2 +8238C938 B0B3 +8238C939 B0B4 +8238CA30 B0B5 +8238CA31 B0B6 +8238CA32 B0B7 +8238CA33 B0B8 +8238CA34 B0B9 +8238CA35 B0BA +8238CA36 B0BB +8238CA37 B0BC +8238CA38 B0BD +8238CA39 B0BE +8238CB30 B0BF +8238CB31 B0C0 +8238CB32 B0C1 +8238CB33 B0C2 +8238CB34 B0C3 +8238CB35 B0C4 +8238CB36 B0C5 +8238CB37 B0C6 +8238CB38 B0C7 +8238CB39 B0C8 +8238CC30 B0C9 +8238CC31 B0CA +8238CC32 B0CB +8238CC33 B0CC +8238CC34 B0CD +8238CC35 B0CE +8238CC36 B0CF +8238CC37 B0D0 +8238CC38 B0D1 +8238CC39 B0D2 +8238CD30 B0D3 +8238CD31 B0D4 +8238CD32 B0D5 +8238CD33 B0D6 +8238CD34 B0D7 +8238CD35 B0D8 +8238CD36 B0D9 +8238CD37 B0DA +8238CD38 B0DB +8238CD39 B0DC +8238CE30 B0DD +8238CE31 B0DE +8238CE32 B0DF +8238CE33 B0E0 +8238CE34 B0E1 +8238CE35 B0E2 +8238CE36 B0E3 +8238CE37 B0E4 +8238CE38 B0E5 +8238CE39 B0E6 +8238CF30 B0E7 +8238CF31 B0E8 +8238CF32 B0E9 +8238CF33 B0EA +8238CF34 B0EB +8238CF35 B0EC +8238CF36 B0ED +8238CF37 B0EE +8238CF38 B0EF +8238CF39 B0F0 +8238D030 B0F1 +8238D031 B0F2 +8238D032 B0F3 +8238D033 B0F4 +8238D034 B0F5 +8238D035 B0F6 +8238D036 B0F7 +8238D037 B0F8 +8238D038 B0F9 +8238D039 B0FA +8238D130 B0FB +8238D131 B0FC +8238D132 B0FD +8238D133 B0FE +8238D134 B0FF +8238D135 B100 +8238D136 B101 +8238D137 B102 +8238D138 B103 +8238D139 B104 +8238D230 B105 +8238D231 B106 +8238D232 B107 +8238D233 B108 +8238D234 B109 +8238D235 B10A +8238D236 B10B +8238D237 B10C +8238D238 B10D +8238D239 B10E +8238D330 B10F +8238D331 B110 +8238D332 B111 +8238D333 B112 +8238D334 B113 +8238D335 B114 +8238D336 B115 +8238D337 B116 +8238D338 B117 +8238D339 B118 +8238D430 B119 +8238D431 B11A +8238D432 B11B +8238D433 B11C +8238D434 B11D +8238D435 B11E +8238D436 B11F +8238D437 B120 +8238D438 B121 +8238D439 B122 +8238D530 B123 +8238D531 B124 +8238D532 B125 +8238D533 B126 +8238D534 B127 +8238D535 B128 +8238D536 B129 +8238D537 B12A +8238D538 B12B +8238D539 B12C +8238D630 B12D +8238D631 B12E +8238D632 B12F +8238D633 B130 +8238D634 B131 +8238D635 B132 +8238D636 B133 +8238D637 B134 +8238D638 B135 +8238D639 B136 +8238D730 B137 +8238D731 B138 +8238D732 B139 +8238D733 B13A +8238D734 B13B +8238D735 B13C +8238D736 B13D +8238D737 B13E +8238D738 B13F +8238D739 B140 +8238D830 B141 +8238D831 B142 +8238D832 B143 +8238D833 B144 +8238D834 B145 +8238D835 B146 +8238D836 B147 +8238D837 B148 +8238D838 B149 +8238D839 B14A +8238D930 B14B +8238D931 B14C +8238D932 B14D +8238D933 B14E +8238D934 B14F +8238D935 B150 +8238D936 B151 +8238D937 B152 +8238D938 B153 +8238D939 B154 +8238DA30 B155 +8238DA31 B156 +8238DA32 B157 +8238DA33 B158 +8238DA34 B159 +8238DA35 B15A +8238DA36 B15B +8238DA37 B15C +8238DA38 B15D +8238DA39 B15E +8238DB30 B15F +8238DB31 B160 +8238DB32 B161 +8238DB33 B162 +8238DB34 B163 +8238DB35 B164 +8238DB36 B165 +8238DB37 B166 +8238DB38 B167 +8238DB39 B168 +8238DC30 B169 +8238DC31 B16A +8238DC32 B16B +8238DC33 B16C +8238DC34 B16D +8238DC35 B16E +8238DC36 B16F +8238DC37 B170 +8238DC38 B171 +8238DC39 B172 +8238DD30 B173 +8238DD31 B174 +8238DD32 B175 +8238DD33 B176 +8238DD34 B177 +8238DD35 B178 +8238DD36 B179 +8238DD37 B17A +8238DD38 B17B +8238DD39 B17C +8238DE30 B17D +8238DE31 B17E +8238DE32 B17F +8238DE33 B180 +8238DE34 B181 +8238DE35 B182 +8238DE36 B183 +8238DE37 B184 +8238DE38 B185 +8238DE39 B186 +8238DF30 B187 +8238DF31 B188 +8238DF32 B189 +8238DF33 B18A +8238DF34 B18B +8238DF35 B18C +8238DF36 B18D +8238DF37 B18E +8238DF38 B18F +8238DF39 B190 +8238E030 B191 +8238E031 B192 +8238E032 B193 +8238E033 B194 +8238E034 B195 +8238E035 B196 +8238E036 B197 +8238E037 B198 +8238E038 B199 +8238E039 B19A +8238E130 B19B +8238E131 B19C +8238E132 B19D +8238E133 B19E +8238E134 B19F +8238E135 B1A0 +8238E136 B1A1 +8238E137 B1A2 +8238E138 B1A3 +8238E139 B1A4 +8238E230 B1A5 +8238E231 B1A6 +8238E232 B1A7 +8238E233 B1A8 +8238E234 B1A9 +8238E235 B1AA +8238E236 B1AB +8238E237 B1AC +8238E238 B1AD +8238E239 B1AE +8238E330 B1AF +8238E331 B1B0 +8238E332 B1B1 +8238E333 B1B2 +8238E334 B1B3 +8238E335 B1B4 +8238E336 B1B5 +8238E337 B1B6 +8238E338 B1B7 +8238E339 B1B8 +8238E430 B1B9 +8238E431 B1BA +8238E432 B1BB +8238E433 B1BC +8238E434 B1BD +8238E435 B1BE +8238E436 B1BF +8238E437 B1C0 +8238E438 B1C1 +8238E439 B1C2 +8238E530 B1C3 +8238E531 B1C4 +8238E532 B1C5 +8238E533 B1C6 +8238E534 B1C7 +8238E535 B1C8 +8238E536 B1C9 +8238E537 B1CA +8238E538 B1CB +8238E539 B1CC +8238E630 B1CD +8238E631 B1CE +8238E632 B1CF +8238E633 B1D0 +8238E634 B1D1 +8238E635 B1D2 +8238E636 B1D3 +8238E637 B1D4 +8238E638 B1D5 +8238E639 B1D6 +8238E730 B1D7 +8238E731 B1D8 +8238E732 B1D9 +8238E733 B1DA +8238E734 B1DB +8238E735 B1DC +8238E736 B1DD +8238E737 B1DE +8238E738 B1DF +8238E739 B1E0 +8238E830 B1E1 +8238E831 B1E2 +8238E832 B1E3 +8238E833 B1E4 +8238E834 B1E5 +8238E835 B1E6 +8238E836 B1E7 +8238E837 B1E8 +8238E838 B1E9 +8238E839 B1EA +8238E930 B1EB +8238E931 B1EC +8238E932 B1ED +8238E933 B1EE +8238E934 B1EF +8238E935 B1F0 +8238E936 B1F1 +8238E937 B1F2 +8238E938 B1F3 +8238E939 B1F4 +8238EA30 B1F5 +8238EA31 B1F6 +8238EA32 B1F7 +8238EA33 B1F8 +8238EA34 B1F9 +8238EA35 B1FA +8238EA36 B1FB +8238EA37 B1FC +8238EA38 B1FD +8238EA39 B1FE +8238EB30 B1FF +8238EB31 B200 +8238EB32 B201 +8238EB33 B202 +8238EB34 B203 +8238EB35 B204 +8238EB36 B205 +8238EB37 B206 +8238EB38 B207 +8238EB39 B208 +8238EC30 B209 +8238EC31 B20A +8238EC32 B20B +8238EC33 B20C +8238EC34 B20D +8238EC35 B20E +8238EC36 B20F +8238EC37 B210 +8238EC38 B211 +8238EC39 B212 +8238ED30 B213 +8238ED31 B214 +8238ED32 B215 +8238ED33 B216 +8238ED34 B217 +8238ED35 B218 +8238ED36 B219 +8238ED37 B21A +8238ED38 B21B +8238ED39 B21C +8238EE30 B21D +8238EE31 B21E +8238EE32 B21F +8238EE33 B220 +8238EE34 B221 +8238EE35 B222 +8238EE36 B223 +8238EE37 B224 +8238EE38 B225 +8238EE39 B226 +8238EF30 B227 +8238EF31 B228 +8238EF32 B229 +8238EF33 B22A +8238EF34 B22B +8238EF35 B22C +8238EF36 B22D +8238EF37 B22E +8238EF38 B22F +8238EF39 B230 +8238F030 B231 +8238F031 B232 +8238F032 B233 +8238F033 B234 +8238F034 B235 +8238F035 B236 +8238F036 B237 +8238F037 B238 +8238F038 B239 +8238F039 B23A +8238F130 B23B +8238F131 B23C +8238F132 B23D +8238F133 B23E +8238F134 B23F +8238F135 B240 +8238F136 B241 +8238F137 B242 +8238F138 B243 +8238F139 B244 +8238F230 B245 +8238F231 B246 +8238F232 B247 +8238F233 B248 +8238F234 B249 +8238F235 B24A +8238F236 B24B +8238F237 B24C +8238F238 B24D +8238F239 B24E +8238F330 B24F +8238F331 B250 +8238F332 B251 +8238F333 B252 +8238F334 B253 +8238F335 B254 +8238F336 B255 +8238F337 B256 +8238F338 B257 +8238F339 B258 +8238F430 B259 +8238F431 B25A +8238F432 B25B +8238F433 B25C +8238F434 B25D +8238F435 B25E +8238F436 B25F +8238F437 B260 +8238F438 B261 +8238F439 B262 +8238F530 B263 +8238F531 B264 +8238F532 B265 +8238F533 B266 +8238F534 B267 +8238F535 B268 +8238F536 B269 +8238F537 B26A +8238F538 B26B +8238F539 B26C +8238F630 B26D +8238F631 B26E +8238F632 B26F +8238F633 B270 +8238F634 B271 +8238F635 B272 +8238F636 B273 +8238F637 B274 +8238F638 B275 +8238F639 B276 +8238F730 B277 +8238F731 B278 +8238F732 B279 +8238F733 B27A +8238F734 B27B +8238F735 B27C +8238F736 B27D +8238F737 B27E +8238F738 B27F +8238F739 B280 +8238F830 B281 +8238F831 B282 +8238F832 B283 +8238F833 B284 +8238F834 B285 +8238F835 B286 +8238F836 B287 +8238F837 B288 +8238F838 B289 +8238F839 B28A +8238F930 B28B +8238F931 B28C +8238F932 B28D +8238F933 B28E +8238F934 B28F +8238F935 B290 +8238F936 B291 +8238F937 B292 +8238F938 B293 +8238F939 B294 +8238FA30 B295 +8238FA31 B296 +8238FA32 B297 +8238FA33 B298 +8238FA34 B299 +8238FA35 B29A +8238FA36 B29B +8238FA37 B29C +8238FA38 B29D +8238FA39 B29E +8238FB30 B29F +8238FB31 B2A0 +8238FB32 B2A1 +8238FB33 B2A2 +8238FB34 B2A3 +8238FB35 B2A4 +8238FB36 B2A5 +8238FB37 B2A6 +8238FB38 B2A7 +8238FB39 B2A8 +8238FC30 B2A9 +8238FC31 B2AA +8238FC32 B2AB +8238FC33 B2AC +8238FC34 B2AD +8238FC35 B2AE +8238FC36 B2AF +8238FC37 B2B0 +8238FC38 B2B1 +8238FC39 B2B2 +8238FD30 B2B3 +8238FD31 B2B4 +8238FD32 B2B5 +8238FD33 B2B6 +8238FD34 B2B7 +8238FD35 B2B8 +8238FD36 B2B9 +8238FD37 B2BA +8238FD38 B2BB +8238FD39 B2BC +8238FE30 B2BD +8238FE31 B2BE +8238FE32 B2BF +8238FE33 B2C0 +8238FE34 B2C1 +8238FE35 B2C2 +8238FE36 B2C3 +8238FE37 B2C4 +8238FE38 B2C5 +8238FE39 B2C6 +82398130 B2C7 +82398131 B2C8 +82398132 B2C9 +82398133 B2CA +82398134 B2CB +82398135 B2CC +82398136 B2CD +82398137 B2CE +82398138 B2CF +82398139 B2D0 +82398230 B2D1 +82398231 B2D2 +82398232 B2D3 +82398233 B2D4 +82398234 B2D5 +82398235 B2D6 +82398236 B2D7 +82398237 B2D8 +82398238 B2D9 +82398239 B2DA +82398330 B2DB +82398331 B2DC +82398332 B2DD +82398333 B2DE +82398334 B2DF +82398335 B2E0 +82398336 B2E1 +82398337 B2E2 +82398338 B2E3 +82398339 B2E4 +82398430 B2E5 +82398431 B2E6 +82398432 B2E7 +82398433 B2E8 +82398434 B2E9 +82398435 B2EA +82398436 B2EB +82398437 B2EC +82398438 B2ED +82398439 B2EE +82398530 B2EF +82398531 B2F0 +82398532 B2F1 +82398533 B2F2 +82398534 B2F3 +82398535 B2F4 +82398536 B2F5 +82398537 B2F6 +82398538 B2F7 +82398539 B2F8 +82398630 B2F9 +82398631 B2FA +82398632 B2FB +82398633 B2FC +82398634 B2FD +82398635 B2FE +82398636 B2FF +82398637 B300 +82398638 B301 +82398639 B302 +82398730 B303 +82398731 B304 +82398732 B305 +82398733 B306 +82398734 B307 +82398735 B308 +82398736 B309 +82398737 B30A +82398738 B30B +82398739 B30C +82398830 B30D +82398831 B30E +82398832 B30F +82398833 B310 +82398834 B311 +82398835 B312 +82398836 B313 +82398837 B314 +82398838 B315 +82398839 B316 +82398930 B317 +82398931 B318 +82398932 B319 +82398933 B31A +82398934 B31B +82398935 B31C +82398936 B31D +82398937 B31E +82398938 B31F +82398939 B320 +82398A30 B321 +82398A31 B322 +82398A32 B323 +82398A33 B324 +82398A34 B325 +82398A35 B326 +82398A36 B327 +82398A37 B328 +82398A38 B329 +82398A39 B32A +82398B30 B32B +82398B31 B32C +82398B32 B32D +82398B33 B32E +82398B34 B32F +82398B35 B330 +82398B36 B331 +82398B37 B332 +82398B38 B333 +82398B39 B334 +82398C30 B335 +82398C31 B336 +82398C32 B337 +82398C33 B338 +82398C34 B339 +82398C35 B33A +82398C36 B33B +82398C37 B33C +82398C38 B33D +82398C39 B33E +82398D30 B33F +82398D31 B340 +82398D32 B341 +82398D33 B342 +82398D34 B343 +82398D35 B344 +82398D36 B345 +82398D37 B346 +82398D38 B347 +82398D39 B348 +82398E30 B349 +82398E31 B34A +82398E32 B34B +82398E33 B34C +82398E34 B34D +82398E35 B34E +82398E36 B34F +82398E37 B350 +82398E38 B351 +82398E39 B352 +82398F30 B353 +82398F31 B354 +82398F32 B355 +82398F33 B356 +82398F34 B357 +82398F35 B358 +82398F36 B359 +82398F37 B35A +82398F38 B35B +82398F39 B35C +82399030 B35D +82399031 B35E +82399032 B35F +82399033 B360 +82399034 B361 +82399035 B362 +82399036 B363 +82399037 B364 +82399038 B365 +82399039 B366 +82399130 B367 +82399131 B368 +82399132 B369 +82399133 B36A +82399134 B36B +82399135 B36C +82399136 B36D +82399137 B36E +82399138 B36F +82399139 B370 +82399230 B371 +82399231 B372 +82399232 B373 +82399233 B374 +82399234 B375 +82399235 B376 +82399236 B377 +82399237 B378 +82399238 B379 +82399239 B37A +82399330 B37B +82399331 B37C +82399332 B37D +82399333 B37E +82399334 B37F +82399335 B380 +82399336 B381 +82399337 B382 +82399338 B383 +82399339 B384 +82399430 B385 +82399431 B386 +82399432 B387 +82399433 B388 +82399434 B389 +82399435 B38A +82399436 B38B +82399437 B38C +82399438 B38D +82399439 B38E +82399530 B38F +82399531 B390 +82399532 B391 +82399533 B392 +82399534 B393 +82399535 B394 +82399536 B395 +82399537 B396 +82399538 B397 +82399539 B398 +82399630 B399 +82399631 B39A +82399632 B39B +82399633 B39C +82399634 B39D +82399635 B39E +82399636 B39F +82399637 B3A0 +82399638 B3A1 +82399639 B3A2 +82399730 B3A3 +82399731 B3A4 +82399732 B3A5 +82399733 B3A6 +82399734 B3A7 +82399735 B3A8 +82399736 B3A9 +82399737 B3AA +82399738 B3AB +82399739 B3AC +82399830 B3AD +82399831 B3AE +82399832 B3AF +82399833 B3B0 +82399834 B3B1 +82399835 B3B2 +82399836 B3B3 +82399837 B3B4 +82399838 B3B5 +82399839 B3B6 +82399930 B3B7 +82399931 B3B8 +82399932 B3B9 +82399933 B3BA +82399934 B3BB +82399935 B3BC +82399936 B3BD +82399937 B3BE +82399938 B3BF +82399939 B3C0 +82399A30 B3C1 +82399A31 B3C2 +82399A32 B3C3 +82399A33 B3C4 +82399A34 B3C5 +82399A35 B3C6 +82399A36 B3C7 +82399A37 B3C8 +82399A38 B3C9 +82399A39 B3CA +82399B30 B3CB +82399B31 B3CC +82399B32 B3CD +82399B33 B3CE +82399B34 B3CF +82399B35 B3D0 +82399B36 B3D1 +82399B37 B3D2 +82399B38 B3D3 +82399B39 B3D4 +82399C30 B3D5 +82399C31 B3D6 +82399C32 B3D7 +82399C33 B3D8 +82399C34 B3D9 +82399C35 B3DA +82399C36 B3DB +82399C37 B3DC +82399C38 B3DD +82399C39 B3DE +82399D30 B3DF +82399D31 B3E0 +82399D32 B3E1 +82399D33 B3E2 +82399D34 B3E3 +82399D35 B3E4 +82399D36 B3E5 +82399D37 B3E6 +82399D38 B3E7 +82399D39 B3E8 +82399E30 B3E9 +82399E31 B3EA +82399E32 B3EB +82399E33 B3EC +82399E34 B3ED +82399E35 B3EE +82399E36 B3EF +82399E37 B3F0 +82399E38 B3F1 +82399E39 B3F2 +82399F30 B3F3 +82399F31 B3F4 +82399F32 B3F5 +82399F33 B3F6 +82399F34 B3F7 +82399F35 B3F8 +82399F36 B3F9 +82399F37 B3FA +82399F38 B3FB +82399F39 B3FC +8239A030 B3FD +8239A031 B3FE +8239A032 B3FF +8239A033 B400 +8239A034 B401 +8239A035 B402 +8239A036 B403 +8239A037 B404 +8239A038 B405 +8239A039 B406 +8239A130 B407 +8239A131 B408 +8239A132 B409 +8239A133 B40A +8239A134 B40B +8239A135 B40C +8239A136 B40D +8239A137 B40E +8239A138 B40F +8239A139 B410 +8239A230 B411 +8239A231 B412 +8239A232 B413 +8239A233 B414 +8239A234 B415 +8239A235 B416 +8239A236 B417 +8239A237 B418 +8239A238 B419 +8239A239 B41A +8239A330 B41B +8239A331 B41C +8239A332 B41D +8239A333 B41E +8239A334 B41F +8239A335 B420 +8239A336 B421 +8239A337 B422 +8239A338 B423 +8239A339 B424 +8239A430 B425 +8239A431 B426 +8239A432 B427 +8239A433 B428 +8239A434 B429 +8239A435 B42A +8239A436 B42B +8239A437 B42C +8239A438 B42D +8239A439 B42E +8239A530 B42F +8239A531 B430 +8239A532 B431 +8239A533 B432 +8239A534 B433 +8239A535 B434 +8239A536 B435 +8239A537 B436 +8239A538 B437 +8239A539 B438 +8239A630 B439 +8239A631 B43A +8239A632 B43B +8239A633 B43C +8239A634 B43D +8239A635 B43E +8239A636 B43F +8239A637 B440 +8239A638 B441 +8239A639 B442 +8239A730 B443 +8239A731 B444 +8239A732 B445 +8239A733 B446 +8239A734 B447 +8239A735 B448 +8239A736 B449 +8239A737 B44A +8239A738 B44B +8239A739 B44C +8239A830 B44D +8239A831 B44E +8239A832 B44F +8239A833 B450 +8239A834 B451 +8239A835 B452 +8239A836 B453 +8239A837 B454 +8239A838 B455 +8239A839 B456 +8239A930 B457 +8239A931 B458 +8239A932 B459 +8239A933 B45A +8239A934 B45B +8239A935 B45C +8239A936 B45D +8239A937 B45E +8239A938 B45F +8239A939 B460 +8239AA30 B461 +8239AA31 B462 +8239AA32 B463 +8239AA33 B464 +8239AA34 B465 +8239AA35 B466 +8239AA36 B467 +8239AA37 B468 +8239AA38 B469 +8239AA39 B46A +8239AB30 B46B +8239AB31 B46C +8239AB32 B46D +8239AB33 B46E +8239AB34 B46F +8239AB35 B470 +8239AB36 B471 +8239AB37 B472 +8239AB38 B473 +8239AB39 B474 +8239AC30 B475 +8239AC31 B476 +8239AC32 B477 +8239AC33 B478 +8239AC34 B479 +8239AC35 B47A +8239AC36 B47B +8239AC37 B47C +8239AC38 B47D +8239AC39 B47E +8239AD30 B47F +8239AD31 B480 +8239AD32 B481 +8239AD33 B482 +8239AD34 B483 +8239AD35 B484 +8239AD36 B485 +8239AD37 B486 +8239AD38 B487 +8239AD39 B488 +8239AE30 B489 +8239AE31 B48A +8239AE32 B48B +8239AE33 B48C +8239AE34 B48D +8239AE35 B48E +8239AE36 B48F +8239AE37 B490 +8239AE38 B491 +8239AE39 B492 +8239AF30 B493 +8239AF31 B494 +8239AF32 B495 +8239AF33 B496 +8239AF34 B497 +8239AF35 B498 +8239AF36 B499 +8239AF37 B49A +8239AF38 B49B +8239AF39 B49C +8239B030 B49D +8239B031 B49E +8239B032 B49F +8239B033 B4A0 +8239B034 B4A1 +8239B035 B4A2 +8239B036 B4A3 +8239B037 B4A4 +8239B038 B4A5 +8239B039 B4A6 +8239B130 B4A7 +8239B131 B4A8 +8239B132 B4A9 +8239B133 B4AA +8239B134 B4AB +8239B135 B4AC +8239B136 B4AD +8239B137 B4AE +8239B138 B4AF +8239B139 B4B0 +8239B230 B4B1 +8239B231 B4B2 +8239B232 B4B3 +8239B233 B4B4 +8239B234 B4B5 +8239B235 B4B6 +8239B236 B4B7 +8239B237 B4B8 +8239B238 B4B9 +8239B239 B4BA +8239B330 B4BB +8239B331 B4BC +8239B332 B4BD +8239B333 B4BE +8239B334 B4BF +8239B335 B4C0 +8239B336 B4C1 +8239B337 B4C2 +8239B338 B4C3 +8239B339 B4C4 +8239B430 B4C5 +8239B431 B4C6 +8239B432 B4C7 +8239B433 B4C8 +8239B434 B4C9 +8239B435 B4CA +8239B436 B4CB +8239B437 B4CC +8239B438 B4CD +8239B439 B4CE +8239B530 B4CF +8239B531 B4D0 +8239B532 B4D1 +8239B533 B4D2 +8239B534 B4D3 +8239B535 B4D4 +8239B536 B4D5 +8239B537 B4D6 +8239B538 B4D7 +8239B539 B4D8 +8239B630 B4D9 +8239B631 B4DA +8239B632 B4DB +8239B633 B4DC +8239B634 B4DD +8239B635 B4DE +8239B636 B4DF +8239B637 B4E0 +8239B638 B4E1 +8239B639 B4E2 +8239B730 B4E3 +8239B731 B4E4 +8239B732 B4E5 +8239B733 B4E6 +8239B734 B4E7 +8239B735 B4E8 +8239B736 B4E9 +8239B737 B4EA +8239B738 B4EB +8239B739 B4EC +8239B830 B4ED +8239B831 B4EE +8239B832 B4EF +8239B833 B4F0 +8239B834 B4F1 +8239B835 B4F2 +8239B836 B4F3 +8239B837 B4F4 +8239B838 B4F5 +8239B839 B4F6 +8239B930 B4F7 +8239B931 B4F8 +8239B932 B4F9 +8239B933 B4FA +8239B934 B4FB +8239B935 B4FC +8239B936 B4FD +8239B937 B4FE +8239B938 B4FF +8239B939 B500 +8239BA30 B501 +8239BA31 B502 +8239BA32 B503 +8239BA33 B504 +8239BA34 B505 +8239BA35 B506 +8239BA36 B507 +8239BA37 B508 +8239BA38 B509 +8239BA39 B50A +8239BB30 B50B +8239BB31 B50C +8239BB32 B50D +8239BB33 B50E +8239BB34 B50F +8239BB35 B510 +8239BB36 B511 +8239BB37 B512 +8239BB38 B513 +8239BB39 B514 +8239BC30 B515 +8239BC31 B516 +8239BC32 B517 +8239BC33 B518 +8239BC34 B519 +8239BC35 B51A +8239BC36 B51B +8239BC37 B51C +8239BC38 B51D +8239BC39 B51E +8239BD30 B51F +8239BD31 B520 +8239BD32 B521 +8239BD33 B522 +8239BD34 B523 +8239BD35 B524 +8239BD36 B525 +8239BD37 B526 +8239BD38 B527 +8239BD39 B528 +8239BE30 B529 +8239BE31 B52A +8239BE32 B52B +8239BE33 B52C +8239BE34 B52D +8239BE35 B52E +8239BE36 B52F +8239BE37 B530 +8239BE38 B531 +8239BE39 B532 +8239BF30 B533 +8239BF31 B534 +8239BF32 B535 +8239BF33 B536 +8239BF34 B537 +8239BF35 B538 +8239BF36 B539 +8239BF37 B53A +8239BF38 B53B +8239BF39 B53C +8239C030 B53D +8239C031 B53E +8239C032 B53F +8239C033 B540 +8239C034 B541 +8239C035 B542 +8239C036 B543 +8239C037 B544 +8239C038 B545 +8239C039 B546 +8239C130 B547 +8239C131 B548 +8239C132 B549 +8239C133 B54A +8239C134 B54B +8239C135 B54C +8239C136 B54D +8239C137 B54E +8239C138 B54F +8239C139 B550 +8239C230 B551 +8239C231 B552 +8239C232 B553 +8239C233 B554 +8239C234 B555 +8239C235 B556 +8239C236 B557 +8239C237 B558 +8239C238 B559 +8239C239 B55A +8239C330 B55B +8239C331 B55C +8239C332 B55D +8239C333 B55E +8239C334 B55F +8239C335 B560 +8239C336 B561 +8239C337 B562 +8239C338 B563 +8239C339 B564 +8239C430 B565 +8239C431 B566 +8239C432 B567 +8239C433 B568 +8239C434 B569 +8239C435 B56A +8239C436 B56B +8239C437 B56C +8239C438 B56D +8239C439 B56E +8239C530 B56F +8239C531 B570 +8239C532 B571 +8239C533 B572 +8239C534 B573 +8239C535 B574 +8239C536 B575 +8239C537 B576 +8239C538 B577 +8239C539 B578 +8239C630 B579 +8239C631 B57A +8239C632 B57B +8239C633 B57C +8239C634 B57D +8239C635 B57E +8239C636 B57F +8239C637 B580 +8239C638 B581 +8239C639 B582 +8239C730 B583 +8239C731 B584 +8239C732 B585 +8239C733 B586 +8239C734 B587 +8239C735 B588 +8239C736 B589 +8239C737 B58A +8239C738 B58B +8239C739 B58C +8239C830 B58D +8239C831 B58E +8239C832 B58F +8239C833 B590 +8239C834 B591 +8239C835 B592 +8239C836 B593 +8239C837 B594 +8239C838 B595 +8239C839 B596 +8239C930 B597 +8239C931 B598 +8239C932 B599 +8239C933 B59A +8239C934 B59B +8239C935 B59C +8239C936 B59D +8239C937 B59E +8239C938 B59F +8239C939 B5A0 +8239CA30 B5A1 +8239CA31 B5A2 +8239CA32 B5A3 +8239CA33 B5A4 +8239CA34 B5A5 +8239CA35 B5A6 +8239CA36 B5A7 +8239CA37 B5A8 +8239CA38 B5A9 +8239CA39 B5AA +8239CB30 B5AB +8239CB31 B5AC +8239CB32 B5AD +8239CB33 B5AE +8239CB34 B5AF +8239CB35 B5B0 +8239CB36 B5B1 +8239CB37 B5B2 +8239CB38 B5B3 +8239CB39 B5B4 +8239CC30 B5B5 +8239CC31 B5B6 +8239CC32 B5B7 +8239CC33 B5B8 +8239CC34 B5B9 +8239CC35 B5BA +8239CC36 B5BB +8239CC37 B5BC +8239CC38 B5BD +8239CC39 B5BE +8239CD30 B5BF +8239CD31 B5C0 +8239CD32 B5C1 +8239CD33 B5C2 +8239CD34 B5C3 +8239CD35 B5C4 +8239CD36 B5C5 +8239CD37 B5C6 +8239CD38 B5C7 +8239CD39 B5C8 +8239CE30 B5C9 +8239CE31 B5CA +8239CE32 B5CB +8239CE33 B5CC +8239CE34 B5CD +8239CE35 B5CE +8239CE36 B5CF +8239CE37 B5D0 +8239CE38 B5D1 +8239CE39 B5D2 +8239CF30 B5D3 +8239CF31 B5D4 +8239CF32 B5D5 +8239CF33 B5D6 +8239CF34 B5D7 +8239CF35 B5D8 +8239CF36 B5D9 +8239CF37 B5DA +8239CF38 B5DB +8239CF39 B5DC +8239D030 B5DD +8239D031 B5DE +8239D032 B5DF +8239D033 B5E0 +8239D034 B5E1 +8239D035 B5E2 +8239D036 B5E3 +8239D037 B5E4 +8239D038 B5E5 +8239D039 B5E6 +8239D130 B5E7 +8239D131 B5E8 +8239D132 B5E9 +8239D133 B5EA +8239D134 B5EB +8239D135 B5EC +8239D136 B5ED +8239D137 B5EE +8239D138 B5EF +8239D139 B5F0 +8239D230 B5F1 +8239D231 B5F2 +8239D232 B5F3 +8239D233 B5F4 +8239D234 B5F5 +8239D235 B5F6 +8239D236 B5F7 +8239D237 B5F8 +8239D238 B5F9 +8239D239 B5FA +8239D330 B5FB +8239D331 B5FC +8239D332 B5FD +8239D333 B5FE +8239D334 B5FF +8239D335 B600 +8239D336 B601 +8239D337 B602 +8239D338 B603 +8239D339 B604 +8239D430 B605 +8239D431 B606 +8239D432 B607 +8239D433 B608 +8239D434 B609 +8239D435 B60A +8239D436 B60B +8239D437 B60C +8239D438 B60D +8239D439 B60E +8239D530 B60F +8239D531 B610 +8239D532 B611 +8239D533 B612 +8239D534 B613 +8239D535 B614 +8239D536 B615 +8239D537 B616 +8239D538 B617 +8239D539 B618 +8239D630 B619 +8239D631 B61A +8239D632 B61B +8239D633 B61C +8239D634 B61D +8239D635 B61E +8239D636 B61F +8239D637 B620 +8239D638 B621 +8239D639 B622 +8239D730 B623 +8239D731 B624 +8239D732 B625 +8239D733 B626 +8239D734 B627 +8239D735 B628 +8239D736 B629 +8239D737 B62A +8239D738 B62B +8239D739 B62C +8239D830 B62D +8239D831 B62E +8239D832 B62F +8239D833 B630 +8239D834 B631 +8239D835 B632 +8239D836 B633 +8239D837 B634 +8239D838 B635 +8239D839 B636 +8239D930 B637 +8239D931 B638 +8239D932 B639 +8239D933 B63A +8239D934 B63B +8239D935 B63C +8239D936 B63D +8239D937 B63E +8239D938 B63F +8239D939 B640 +8239DA30 B641 +8239DA31 B642 +8239DA32 B643 +8239DA33 B644 +8239DA34 B645 +8239DA35 B646 +8239DA36 B647 +8239DA37 B648 +8239DA38 B649 +8239DA39 B64A +8239DB30 B64B +8239DB31 B64C +8239DB32 B64D +8239DB33 B64E +8239DB34 B64F +8239DB35 B650 +8239DB36 B651 +8239DB37 B652 +8239DB38 B653 +8239DB39 B654 +8239DC30 B655 +8239DC31 B656 +8239DC32 B657 +8239DC33 B658 +8239DC34 B659 +8239DC35 B65A +8239DC36 B65B +8239DC37 B65C +8239DC38 B65D +8239DC39 B65E +8239DD30 B65F +8239DD31 B660 +8239DD32 B661 +8239DD33 B662 +8239DD34 B663 +8239DD35 B664 +8239DD36 B665 +8239DD37 B666 +8239DD38 B667 +8239DD39 B668 +8239DE30 B669 +8239DE31 B66A +8239DE32 B66B +8239DE33 B66C +8239DE34 B66D +8239DE35 B66E +8239DE36 B66F +8239DE37 B670 +8239DE38 B671 +8239DE39 B672 +8239DF30 B673 +8239DF31 B674 +8239DF32 B675 +8239DF33 B676 +8239DF34 B677 +8239DF35 B678 +8239DF36 B679 +8239DF37 B67A +8239DF38 B67B +8239DF39 B67C +8239E030 B67D +8239E031 B67E +8239E032 B67F +8239E033 B680 +8239E034 B681 +8239E035 B682 +8239E036 B683 +8239E037 B684 +8239E038 B685 +8239E039 B686 +8239E130 B687 +8239E131 B688 +8239E132 B689 +8239E133 B68A +8239E134 B68B +8239E135 B68C +8239E136 B68D +8239E137 B68E +8239E138 B68F +8239E139 B690 +8239E230 B691 +8239E231 B692 +8239E232 B693 +8239E233 B694 +8239E234 B695 +8239E235 B696 +8239E236 B697 +8239E237 B698 +8239E238 B699 +8239E239 B69A +8239E330 B69B +8239E331 B69C +8239E332 B69D +8239E333 B69E +8239E334 B69F +8239E335 B6A0 +8239E336 B6A1 +8239E337 B6A2 +8239E338 B6A3 +8239E339 B6A4 +8239E430 B6A5 +8239E431 B6A6 +8239E432 B6A7 +8239E433 B6A8 +8239E434 B6A9 +8239E435 B6AA +8239E436 B6AB +8239E437 B6AC +8239E438 B6AD +8239E439 B6AE +8239E530 B6AF +8239E531 B6B0 +8239E532 B6B1 +8239E533 B6B2 +8239E534 B6B3 +8239E535 B6B4 +8239E536 B6B5 +8239E537 B6B6 +8239E538 B6B7 +8239E539 B6B8 +8239E630 B6B9 +8239E631 B6BA +8239E632 B6BB +8239E633 B6BC +8239E634 B6BD +8239E635 B6BE +8239E636 B6BF +8239E637 B6C0 +8239E638 B6C1 +8239E639 B6C2 +8239E730 B6C3 +8239E731 B6C4 +8239E732 B6C5 +8239E733 B6C6 +8239E734 B6C7 +8239E735 B6C8 +8239E736 B6C9 +8239E737 B6CA +8239E738 B6CB +8239E739 B6CC +8239E830 B6CD +8239E831 B6CE +8239E832 B6CF +8239E833 B6D0 +8239E834 B6D1 +8239E835 B6D2 +8239E836 B6D3 +8239E837 B6D4 +8239E838 B6D5 +8239E839 B6D6 +8239E930 B6D7 +8239E931 B6D8 +8239E932 B6D9 +8239E933 B6DA +8239E934 B6DB +8239E935 B6DC +8239E936 B6DD +8239E937 B6DE +8239E938 B6DF +8239E939 B6E0 +8239EA30 B6E1 +8239EA31 B6E2 +8239EA32 B6E3 +8239EA33 B6E4 +8239EA34 B6E5 +8239EA35 B6E6 +8239EA36 B6E7 +8239EA37 B6E8 +8239EA38 B6E9 +8239EA39 B6EA +8239EB30 B6EB +8239EB31 B6EC +8239EB32 B6ED +8239EB33 B6EE +8239EB34 B6EF +8239EB35 B6F0 +8239EB36 B6F1 +8239EB37 B6F2 +8239EB38 B6F3 +8239EB39 B6F4 +8239EC30 B6F5 +8239EC31 B6F6 +8239EC32 B6F7 +8239EC33 B6F8 +8239EC34 B6F9 +8239EC35 B6FA +8239EC36 B6FB +8239EC37 B6FC +8239EC38 B6FD +8239EC39 B6FE +8239ED30 B6FF +8239ED31 B700 +8239ED32 B701 +8239ED33 B702 +8239ED34 B703 +8239ED35 B704 +8239ED36 B705 +8239ED37 B706 +8239ED38 B707 +8239ED39 B708 +8239EE30 B709 +8239EE31 B70A +8239EE32 B70B +8239EE33 B70C +8239EE34 B70D +8239EE35 B70E +8239EE36 B70F +8239EE37 B710 +8239EE38 B711 +8239EE39 B712 +8239EF30 B713 +8239EF31 B714 +8239EF32 B715 +8239EF33 B716 +8239EF34 B717 +8239EF35 B718 +8239EF36 B719 +8239EF37 B71A +8239EF38 B71B +8239EF39 B71C +8239F030 B71D +8239F031 B71E +8239F032 B71F +8239F033 B720 +8239F034 B721 +8239F035 B722 +8239F036 B723 +8239F037 B724 +8239F038 B725 +8239F039 B726 +8239F130 B727 +8239F131 B728 +8239F132 B729 +8239F133 B72A +8239F134 B72B +8239F135 B72C +8239F136 B72D +8239F137 B72E +8239F138 B72F +8239F139 B730 +8239F230 B731 +8239F231 B732 +8239F232 B733 +8239F233 B734 +8239F234 B735 +8239F235 B736 +8239F236 B737 +8239F237 B738 +8239F238 B739 +8239F239 B73A +8239F330 B73B +8239F331 B73C +8239F332 B73D +8239F333 B73E +8239F334 B73F +8239F335 B740 +8239F336 B741 +8239F337 B742 +8239F338 B743 +8239F339 B744 +8239F430 B745 +8239F431 B746 +8239F432 B747 +8239F433 B748 +8239F434 B749 +8239F435 B74A +8239F436 B74B +8239F437 B74C +8239F438 B74D +8239F439 B74E +8239F530 B74F +8239F531 B750 +8239F532 B751 +8239F533 B752 +8239F534 B753 +8239F535 B754 +8239F536 B755 +8239F537 B756 +8239F538 B757 +8239F539 B758 +8239F630 B759 +8239F631 B75A +8239F632 B75B +8239F633 B75C +8239F634 B75D +8239F635 B75E +8239F636 B75F +8239F637 B760 +8239F638 B761 +8239F639 B762 +8239F730 B763 +8239F731 B764 +8239F732 B765 +8239F733 B766 +8239F734 B767 +8239F735 B768 +8239F736 B769 +8239F737 B76A +8239F738 B76B +8239F739 B76C +8239F830 B76D +8239F831 B76E +8239F832 B76F +8239F833 B770 +8239F834 B771 +8239F835 B772 +8239F836 B773 +8239F837 B774 +8239F838 B775 +8239F839 B776 +8239F930 B777 +8239F931 B778 +8239F932 B779 +8239F933 B77A +8239F934 B77B +8239F935 B77C +8239F936 B77D +8239F937 B77E +8239F938 B77F +8239F939 B780 +8239FA30 B781 +8239FA31 B782 +8239FA32 B783 +8239FA33 B784 +8239FA34 B785 +8239FA35 B786 +8239FA36 B787 +8239FA37 B788 +8239FA38 B789 +8239FA39 B78A +8239FB30 B78B +8239FB31 B78C +8239FB32 B78D +8239FB33 B78E +8239FB34 B78F +8239FB35 B790 +8239FB36 B791 +8239FB37 B792 +8239FB38 B793 +8239FB39 B794 +8239FC30 B795 +8239FC31 B796 +8239FC32 B797 +8239FC33 B798 +8239FC34 B799 +8239FC35 B79A +8239FC36 B79B +8239FC37 B79C +8239FC38 B79D +8239FC39 B79E +8239FD30 B79F +8239FD31 B7A0 +8239FD32 B7A1 +8239FD33 B7A2 +8239FD34 B7A3 +8239FD35 B7A4 +8239FD36 B7A5 +8239FD37 B7A6 +8239FD38 B7A7 +8239FD39 B7A8 +8239FE30 B7A9 +8239FE31 B7AA +8239FE32 B7AB +8239FE33 B7AC +8239FE34 B7AD +8239FE35 B7AE +8239FE36 B7AF +8239FE37 B7B0 +8239FE38 B7B1 +8239FE39 B7B2 +83308130 B7B3 +83308131 B7B4 +83308132 B7B5 +83308133 B7B6 +83308134 B7B7 +83308135 B7B8 +83308136 B7B9 +83308137 B7BA +83308138 B7BB +83308139 B7BC +83308230 B7BD +83308231 B7BE +83308232 B7BF +83308233 B7C0 +83308234 B7C1 +83308235 B7C2 +83308236 B7C3 +83308237 B7C4 +83308238 B7C5 +83308239 B7C6 +83308330 B7C7 +83308331 B7C8 +83308332 B7C9 +83308333 B7CA +83308334 B7CB +83308335 B7CC +83308336 B7CD +83308337 B7CE +83308338 B7CF +83308339 B7D0 +83308430 B7D1 +83308431 B7D2 +83308432 B7D3 +83308433 B7D4 +83308434 B7D5 +83308435 B7D6 +83308436 B7D7 +83308437 B7D8 +83308438 B7D9 +83308439 B7DA +83308530 B7DB +83308531 B7DC +83308532 B7DD +83308533 B7DE +83308534 B7DF +83308535 B7E0 +83308536 B7E1 +83308537 B7E2 +83308538 B7E3 +83308539 B7E4 +83308630 B7E5 +83308631 B7E6 +83308632 B7E7 +83308633 B7E8 +83308634 B7E9 +83308635 B7EA +83308636 B7EB +83308637 B7EC +83308638 B7ED +83308639 B7EE +83308730 B7EF +83308731 B7F0 +83308732 B7F1 +83308733 B7F2 +83308734 B7F3 +83308735 B7F4 +83308736 B7F5 +83308737 B7F6 +83308738 B7F7 +83308739 B7F8 +83308830 B7F9 +83308831 B7FA +83308832 B7FB +83308833 B7FC +83308834 B7FD +83308835 B7FE +83308836 B7FF +83308837 B800 +83308838 B801 +83308839 B802 +83308930 B803 +83308931 B804 +83308932 B805 +83308933 B806 +83308934 B807 +83308935 B808 +83308936 B809 +83308937 B80A +83308938 B80B +83308939 B80C +83308A30 B80D +83308A31 B80E +83308A32 B80F +83308A33 B810 +83308A34 B811 +83308A35 B812 +83308A36 B813 +83308A37 B814 +83308A38 B815 +83308A39 B816 +83308B30 B817 +83308B31 B818 +83308B32 B819 +83308B33 B81A +83308B34 B81B +83308B35 B81C +83308B36 B81D +83308B37 B81E +83308B38 B81F +83308B39 B820 +83308C30 B821 +83308C31 B822 +83308C32 B823 +83308C33 B824 +83308C34 B825 +83308C35 B826 +83308C36 B827 +83308C37 B828 +83308C38 B829 +83308C39 B82A +83308D30 B82B +83308D31 B82C +83308D32 B82D +83308D33 B82E +83308D34 B82F +83308D35 B830 +83308D36 B831 +83308D37 B832 +83308D38 B833 +83308D39 B834 +83308E30 B835 +83308E31 B836 +83308E32 B837 +83308E33 B838 +83308E34 B839 +83308E35 B83A +83308E36 B83B +83308E37 B83C +83308E38 B83D +83308E39 B83E +83308F30 B83F +83308F31 B840 +83308F32 B841 +83308F33 B842 +83308F34 B843 +83308F35 B844 +83308F36 B845 +83308F37 B846 +83308F38 B847 +83308F39 B848 +83309030 B849 +83309031 B84A +83309032 B84B +83309033 B84C +83309034 B84D +83309035 B84E +83309036 B84F +83309037 B850 +83309038 B851 +83309039 B852 +83309130 B853 +83309131 B854 +83309132 B855 +83309133 B856 +83309134 B857 +83309135 B858 +83309136 B859 +83309137 B85A +83309138 B85B +83309139 B85C +83309230 B85D +83309231 B85E +83309232 B85F +83309233 B860 +83309234 B861 +83309235 B862 +83309236 B863 +83309237 B864 +83309238 B865 +83309239 B866 +83309330 B867 +83309331 B868 +83309332 B869 +83309333 B86A +83309334 B86B +83309335 B86C +83309336 B86D +83309337 B86E +83309338 B86F +83309339 B870 +83309430 B871 +83309431 B872 +83309432 B873 +83309433 B874 +83309434 B875 +83309435 B876 +83309436 B877 +83309437 B878 +83309438 B879 +83309439 B87A +83309530 B87B +83309531 B87C +83309532 B87D +83309533 B87E +83309534 B87F +83309535 B880 +83309536 B881 +83309537 B882 +83309538 B883 +83309539 B884 +83309630 B885 +83309631 B886 +83309632 B887 +83309633 B888 +83309634 B889 +83309635 B88A +83309636 B88B +83309637 B88C +83309638 B88D +83309639 B88E +83309730 B88F +83309731 B890 +83309732 B891 +83309733 B892 +83309734 B893 +83309735 B894 +83309736 B895 +83309737 B896 +83309738 B897 +83309739 B898 +83309830 B899 +83309831 B89A +83309832 B89B +83309833 B89C +83309834 B89D +83309835 B89E +83309836 B89F +83309837 B8A0 +83309838 B8A1 +83309839 B8A2 +83309930 B8A3 +83309931 B8A4 +83309932 B8A5 +83309933 B8A6 +83309934 B8A7 +83309935 B8A8 +83309936 B8A9 +83309937 B8AA +83309938 B8AB +83309939 B8AC +83309A30 B8AD +83309A31 B8AE +83309A32 B8AF +83309A33 B8B0 +83309A34 B8B1 +83309A35 B8B2 +83309A36 B8B3 +83309A37 B8B4 +83309A38 B8B5 +83309A39 B8B6 +83309B30 B8B7 +83309B31 B8B8 +83309B32 B8B9 +83309B33 B8BA +83309B34 B8BB +83309B35 B8BC +83309B36 B8BD +83309B37 B8BE +83309B38 B8BF +83309B39 B8C0 +83309C30 B8C1 +83309C31 B8C2 +83309C32 B8C3 +83309C33 B8C4 +83309C34 B8C5 +83309C35 B8C6 +83309C36 B8C7 +83309C37 B8C8 +83309C38 B8C9 +83309C39 B8CA +83309D30 B8CB +83309D31 B8CC +83309D32 B8CD +83309D33 B8CE +83309D34 B8CF +83309D35 B8D0 +83309D36 B8D1 +83309D37 B8D2 +83309D38 B8D3 +83309D39 B8D4 +83309E30 B8D5 +83309E31 B8D6 +83309E32 B8D7 +83309E33 B8D8 +83309E34 B8D9 +83309E35 B8DA +83309E36 B8DB +83309E37 B8DC +83309E38 B8DD +83309E39 B8DE +83309F30 B8DF +83309F31 B8E0 +83309F32 B8E1 +83309F33 B8E2 +83309F34 B8E3 +83309F35 B8E4 +83309F36 B8E5 +83309F37 B8E6 +83309F38 B8E7 +83309F39 B8E8 +8330A030 B8E9 +8330A031 B8EA +8330A032 B8EB +8330A033 B8EC +8330A034 B8ED +8330A035 B8EE +8330A036 B8EF +8330A037 B8F0 +8330A038 B8F1 +8330A039 B8F2 +8330A130 B8F3 +8330A131 B8F4 +8330A132 B8F5 +8330A133 B8F6 +8330A134 B8F7 +8330A135 B8F8 +8330A136 B8F9 +8330A137 B8FA +8330A138 B8FB +8330A139 B8FC +8330A230 B8FD +8330A231 B8FE +8330A232 B8FF +8330A233 B900 +8330A234 B901 +8330A235 B902 +8330A236 B903 +8330A237 B904 +8330A238 B905 +8330A239 B906 +8330A330 B907 +8330A331 B908 +8330A332 B909 +8330A333 B90A +8330A334 B90B +8330A335 B90C +8330A336 B90D +8330A337 B90E +8330A338 B90F +8330A339 B910 +8330A430 B911 +8330A431 B912 +8330A432 B913 +8330A433 B914 +8330A434 B915 +8330A435 B916 +8330A436 B917 +8330A437 B918 +8330A438 B919 +8330A439 B91A +8330A530 B91B +8330A531 B91C +8330A532 B91D +8330A533 B91E +8330A534 B91F +8330A535 B920 +8330A536 B921 +8330A537 B922 +8330A538 B923 +8330A539 B924 +8330A630 B925 +8330A631 B926 +8330A632 B927 +8330A633 B928 +8330A634 B929 +8330A635 B92A +8330A636 B92B +8330A637 B92C +8330A638 B92D +8330A639 B92E +8330A730 B92F +8330A731 B930 +8330A732 B931 +8330A733 B932 +8330A734 B933 +8330A735 B934 +8330A736 B935 +8330A737 B936 +8330A738 B937 +8330A739 B938 +8330A830 B939 +8330A831 B93A +8330A832 B93B +8330A833 B93C +8330A834 B93D +8330A835 B93E +8330A836 B93F +8330A837 B940 +8330A838 B941 +8330A839 B942 +8330A930 B943 +8330A931 B944 +8330A932 B945 +8330A933 B946 +8330A934 B947 +8330A935 B948 +8330A936 B949 +8330A937 B94A +8330A938 B94B +8330A939 B94C +8330AA30 B94D +8330AA31 B94E +8330AA32 B94F +8330AA33 B950 +8330AA34 B951 +8330AA35 B952 +8330AA36 B953 +8330AA37 B954 +8330AA38 B955 +8330AA39 B956 +8330AB30 B957 +8330AB31 B958 +8330AB32 B959 +8330AB33 B95A +8330AB34 B95B +8330AB35 B95C +8330AB36 B95D +8330AB37 B95E +8330AB38 B95F +8330AB39 B960 +8330AC30 B961 +8330AC31 B962 +8330AC32 B963 +8330AC33 B964 +8330AC34 B965 +8330AC35 B966 +8330AC36 B967 +8330AC37 B968 +8330AC38 B969 +8330AC39 B96A +8330AD30 B96B +8330AD31 B96C +8330AD32 B96D +8330AD33 B96E +8330AD34 B96F +8330AD35 B970 +8330AD36 B971 +8330AD37 B972 +8330AD38 B973 +8330AD39 B974 +8330AE30 B975 +8330AE31 B976 +8330AE32 B977 +8330AE33 B978 +8330AE34 B979 +8330AE35 B97A +8330AE36 B97B +8330AE37 B97C +8330AE38 B97D +8330AE39 B97E +8330AF30 B97F +8330AF31 B980 +8330AF32 B981 +8330AF33 B982 +8330AF34 B983 +8330AF35 B984 +8330AF36 B985 +8330AF37 B986 +8330AF38 B987 +8330AF39 B988 +8330B030 B989 +8330B031 B98A +8330B032 B98B +8330B033 B98C +8330B034 B98D +8330B035 B98E +8330B036 B98F +8330B037 B990 +8330B038 B991 +8330B039 B992 +8330B130 B993 +8330B131 B994 +8330B132 B995 +8330B133 B996 +8330B134 B997 +8330B135 B998 +8330B136 B999 +8330B137 B99A +8330B138 B99B +8330B139 B99C +8330B230 B99D +8330B231 B99E +8330B232 B99F +8330B233 B9A0 +8330B234 B9A1 +8330B235 B9A2 +8330B236 B9A3 +8330B237 B9A4 +8330B238 B9A5 +8330B239 B9A6 +8330B330 B9A7 +8330B331 B9A8 +8330B332 B9A9 +8330B333 B9AA +8330B334 B9AB +8330B335 B9AC +8330B336 B9AD +8330B337 B9AE +8330B338 B9AF +8330B339 B9B0 +8330B430 B9B1 +8330B431 B9B2 +8330B432 B9B3 +8330B433 B9B4 +8330B434 B9B5 +8330B435 B9B6 +8330B436 B9B7 +8330B437 B9B8 +8330B438 B9B9 +8330B439 B9BA +8330B530 B9BB +8330B531 B9BC +8330B532 B9BD +8330B533 B9BE +8330B534 B9BF +8330B535 B9C0 +8330B536 B9C1 +8330B537 B9C2 +8330B538 B9C3 +8330B539 B9C4 +8330B630 B9C5 +8330B631 B9C6 +8330B632 B9C7 +8330B633 B9C8 +8330B634 B9C9 +8330B635 B9CA +8330B636 B9CB +8330B637 B9CC +8330B638 B9CD +8330B639 B9CE +8330B730 B9CF +8330B731 B9D0 +8330B732 B9D1 +8330B733 B9D2 +8330B734 B9D3 +8330B735 B9D4 +8330B736 B9D5 +8330B737 B9D6 +8330B738 B9D7 +8330B739 B9D8 +8330B830 B9D9 +8330B831 B9DA +8330B832 B9DB +8330B833 B9DC +8330B834 B9DD +8330B835 B9DE +8330B836 B9DF +8330B837 B9E0 +8330B838 B9E1 +8330B839 B9E2 +8330B930 B9E3 +8330B931 B9E4 +8330B932 B9E5 +8330B933 B9E6 +8330B934 B9E7 +8330B935 B9E8 +8330B936 B9E9 +8330B937 B9EA +8330B938 B9EB +8330B939 B9EC +8330BA30 B9ED +8330BA31 B9EE +8330BA32 B9EF +8330BA33 B9F0 +8330BA34 B9F1 +8330BA35 B9F2 +8330BA36 B9F3 +8330BA37 B9F4 +8330BA38 B9F5 +8330BA39 B9F6 +8330BB30 B9F7 +8330BB31 B9F8 +8330BB32 B9F9 +8330BB33 B9FA +8330BB34 B9FB +8330BB35 B9FC +8330BB36 B9FD +8330BB37 B9FE +8330BB38 B9FF +8330BB39 BA00 +8330BC30 BA01 +8330BC31 BA02 +8330BC32 BA03 +8330BC33 BA04 +8330BC34 BA05 +8330BC35 BA06 +8330BC36 BA07 +8330BC37 BA08 +8330BC38 BA09 +8330BC39 BA0A +8330BD30 BA0B +8330BD31 BA0C +8330BD32 BA0D +8330BD33 BA0E +8330BD34 BA0F +8330BD35 BA10 +8330BD36 BA11 +8330BD37 BA12 +8330BD38 BA13 +8330BD39 BA14 +8330BE30 BA15 +8330BE31 BA16 +8330BE32 BA17 +8330BE33 BA18 +8330BE34 BA19 +8330BE35 BA1A +8330BE36 BA1B +8330BE37 BA1C +8330BE38 BA1D +8330BE39 BA1E +8330BF30 BA1F +8330BF31 BA20 +8330BF32 BA21 +8330BF33 BA22 +8330BF34 BA23 +8330BF35 BA24 +8330BF36 BA25 +8330BF37 BA26 +8330BF38 BA27 +8330BF39 BA28 +8330C030 BA29 +8330C031 BA2A +8330C032 BA2B +8330C033 BA2C +8330C034 BA2D +8330C035 BA2E +8330C036 BA2F +8330C037 BA30 +8330C038 BA31 +8330C039 BA32 +8330C130 BA33 +8330C131 BA34 +8330C132 BA35 +8330C133 BA36 +8330C134 BA37 +8330C135 BA38 +8330C136 BA39 +8330C137 BA3A +8330C138 BA3B +8330C139 BA3C +8330C230 BA3D +8330C231 BA3E +8330C232 BA3F +8330C233 BA40 +8330C234 BA41 +8330C235 BA42 +8330C236 BA43 +8330C237 BA44 +8330C238 BA45 +8330C239 BA46 +8330C330 BA47 +8330C331 BA48 +8330C332 BA49 +8330C333 BA4A +8330C334 BA4B +8330C335 BA4C +8330C336 BA4D +8330C337 BA4E +8330C338 BA4F +8330C339 BA50 +8330C430 BA51 +8330C431 BA52 +8330C432 BA53 +8330C433 BA54 +8330C434 BA55 +8330C435 BA56 +8330C436 BA57 +8330C437 BA58 +8330C438 BA59 +8330C439 BA5A +8330C530 BA5B +8330C531 BA5C +8330C532 BA5D +8330C533 BA5E +8330C534 BA5F +8330C535 BA60 +8330C536 BA61 +8330C537 BA62 +8330C538 BA63 +8330C539 BA64 +8330C630 BA65 +8330C631 BA66 +8330C632 BA67 +8330C633 BA68 +8330C634 BA69 +8330C635 BA6A +8330C636 BA6B +8330C637 BA6C +8330C638 BA6D +8330C639 BA6E +8330C730 BA6F +8330C731 BA70 +8330C732 BA71 +8330C733 BA72 +8330C734 BA73 +8330C735 BA74 +8330C736 BA75 +8330C737 BA76 +8330C738 BA77 +8330C739 BA78 +8330C830 BA79 +8330C831 BA7A +8330C832 BA7B +8330C833 BA7C +8330C834 BA7D +8330C835 BA7E +8330C836 BA7F +8330C837 BA80 +8330C838 BA81 +8330C839 BA82 +8330C930 BA83 +8330C931 BA84 +8330C932 BA85 +8330C933 BA86 +8330C934 BA87 +8330C935 BA88 +8330C936 BA89 +8330C937 BA8A +8330C938 BA8B +8330C939 BA8C +8330CA30 BA8D +8330CA31 BA8E +8330CA32 BA8F +8330CA33 BA90 +8330CA34 BA91 +8330CA35 BA92 +8330CA36 BA93 +8330CA37 BA94 +8330CA38 BA95 +8330CA39 BA96 +8330CB30 BA97 +8330CB31 BA98 +8330CB32 BA99 +8330CB33 BA9A +8330CB34 BA9B +8330CB35 BA9C +8330CB36 BA9D +8330CB37 BA9E +8330CB38 BA9F +8330CB39 BAA0 +8330CC30 BAA1 +8330CC31 BAA2 +8330CC32 BAA3 +8330CC33 BAA4 +8330CC34 BAA5 +8330CC35 BAA6 +8330CC36 BAA7 +8330CC37 BAA8 +8330CC38 BAA9 +8330CC39 BAAA +8330CD30 BAAB +8330CD31 BAAC +8330CD32 BAAD +8330CD33 BAAE +8330CD34 BAAF +8330CD35 BAB0 +8330CD36 BAB1 +8330CD37 BAB2 +8330CD38 BAB3 +8330CD39 BAB4 +8330CE30 BAB5 +8330CE31 BAB6 +8330CE32 BAB7 +8330CE33 BAB8 +8330CE34 BAB9 +8330CE35 BABA +8330CE36 BABB +8330CE37 BABC +8330CE38 BABD +8330CE39 BABE +8330CF30 BABF +8330CF31 BAC0 +8330CF32 BAC1 +8330CF33 BAC2 +8330CF34 BAC3 +8330CF35 BAC4 +8330CF36 BAC5 +8330CF37 BAC6 +8330CF38 BAC7 +8330CF39 BAC8 +8330D030 BAC9 +8330D031 BACA +8330D032 BACB +8330D033 BACC +8330D034 BACD +8330D035 BACE +8330D036 BACF +8330D037 BAD0 +8330D038 BAD1 +8330D039 BAD2 +8330D130 BAD3 +8330D131 BAD4 +8330D132 BAD5 +8330D133 BAD6 +8330D134 BAD7 +8330D135 BAD8 +8330D136 BAD9 +8330D137 BADA +8330D138 BADB +8330D139 BADC +8330D230 BADD +8330D231 BADE +8330D232 BADF +8330D233 BAE0 +8330D234 BAE1 +8330D235 BAE2 +8330D236 BAE3 +8330D237 BAE4 +8330D238 BAE5 +8330D239 BAE6 +8330D330 BAE7 +8330D331 BAE8 +8330D332 BAE9 +8330D333 BAEA +8330D334 BAEB +8330D335 BAEC +8330D336 BAED +8330D337 BAEE +8330D338 BAEF +8330D339 BAF0 +8330D430 BAF1 +8330D431 BAF2 +8330D432 BAF3 +8330D433 BAF4 +8330D434 BAF5 +8330D435 BAF6 +8330D436 BAF7 +8330D437 BAF8 +8330D438 BAF9 +8330D439 BAFA +8330D530 BAFB +8330D531 BAFC +8330D532 BAFD +8330D533 BAFE +8330D534 BAFF +8330D535 BB00 +8330D536 BB01 +8330D537 BB02 +8330D538 BB03 +8330D539 BB04 +8330D630 BB05 +8330D631 BB06 +8330D632 BB07 +8330D633 BB08 +8330D634 BB09 +8330D635 BB0A +8330D636 BB0B +8330D637 BB0C +8330D638 BB0D +8330D639 BB0E +8330D730 BB0F +8330D731 BB10 +8330D732 BB11 +8330D733 BB12 +8330D734 BB13 +8330D735 BB14 +8330D736 BB15 +8330D737 BB16 +8330D738 BB17 +8330D739 BB18 +8330D830 BB19 +8330D831 BB1A +8330D832 BB1B +8330D833 BB1C +8330D834 BB1D +8330D835 BB1E +8330D836 BB1F +8330D837 BB20 +8330D838 BB21 +8330D839 BB22 +8330D930 BB23 +8330D931 BB24 +8330D932 BB25 +8330D933 BB26 +8330D934 BB27 +8330D935 BB28 +8330D936 BB29 +8330D937 BB2A +8330D938 BB2B +8330D939 BB2C +8330DA30 BB2D +8330DA31 BB2E +8330DA32 BB2F +8330DA33 BB30 +8330DA34 BB31 +8330DA35 BB32 +8330DA36 BB33 +8330DA37 BB34 +8330DA38 BB35 +8330DA39 BB36 +8330DB30 BB37 +8330DB31 BB38 +8330DB32 BB39 +8330DB33 BB3A +8330DB34 BB3B +8330DB35 BB3C +8330DB36 BB3D +8330DB37 BB3E +8330DB38 BB3F +8330DB39 BB40 +8330DC30 BB41 +8330DC31 BB42 +8330DC32 BB43 +8330DC33 BB44 +8330DC34 BB45 +8330DC35 BB46 +8330DC36 BB47 +8330DC37 BB48 +8330DC38 BB49 +8330DC39 BB4A +8330DD30 BB4B +8330DD31 BB4C +8330DD32 BB4D +8330DD33 BB4E +8330DD34 BB4F +8330DD35 BB50 +8330DD36 BB51 +8330DD37 BB52 +8330DD38 BB53 +8330DD39 BB54 +8330DE30 BB55 +8330DE31 BB56 +8330DE32 BB57 +8330DE33 BB58 +8330DE34 BB59 +8330DE35 BB5A +8330DE36 BB5B +8330DE37 BB5C +8330DE38 BB5D +8330DE39 BB5E +8330DF30 BB5F +8330DF31 BB60 +8330DF32 BB61 +8330DF33 BB62 +8330DF34 BB63 +8330DF35 BB64 +8330DF36 BB65 +8330DF37 BB66 +8330DF38 BB67 +8330DF39 BB68 +8330E030 BB69 +8330E031 BB6A +8330E032 BB6B +8330E033 BB6C +8330E034 BB6D +8330E035 BB6E +8330E036 BB6F +8330E037 BB70 +8330E038 BB71 +8330E039 BB72 +8330E130 BB73 +8330E131 BB74 +8330E132 BB75 +8330E133 BB76 +8330E134 BB77 +8330E135 BB78 +8330E136 BB79 +8330E137 BB7A +8330E138 BB7B +8330E139 BB7C +8330E230 BB7D +8330E231 BB7E +8330E232 BB7F +8330E233 BB80 +8330E234 BB81 +8330E235 BB82 +8330E236 BB83 +8330E237 BB84 +8330E238 BB85 +8330E239 BB86 +8330E330 BB87 +8330E331 BB88 +8330E332 BB89 +8330E333 BB8A +8330E334 BB8B +8330E335 BB8C +8330E336 BB8D +8330E337 BB8E +8330E338 BB8F +8330E339 BB90 +8330E430 BB91 +8330E431 BB92 +8330E432 BB93 +8330E433 BB94 +8330E434 BB95 +8330E435 BB96 +8330E436 BB97 +8330E437 BB98 +8330E438 BB99 +8330E439 BB9A +8330E530 BB9B +8330E531 BB9C +8330E532 BB9D +8330E533 BB9E +8330E534 BB9F +8330E535 BBA0 +8330E536 BBA1 +8330E537 BBA2 +8330E538 BBA3 +8330E539 BBA4 +8330E630 BBA5 +8330E631 BBA6 +8330E632 BBA7 +8330E633 BBA8 +8330E634 BBA9 +8330E635 BBAA +8330E636 BBAB +8330E637 BBAC +8330E638 BBAD +8330E639 BBAE +8330E730 BBAF +8330E731 BBB0 +8330E732 BBB1 +8330E733 BBB2 +8330E734 BBB3 +8330E735 BBB4 +8330E736 BBB5 +8330E737 BBB6 +8330E738 BBB7 +8330E739 BBB8 +8330E830 BBB9 +8330E831 BBBA +8330E832 BBBB +8330E833 BBBC +8330E834 BBBD +8330E835 BBBE +8330E836 BBBF +8330E837 BBC0 +8330E838 BBC1 +8330E839 BBC2 +8330E930 BBC3 +8330E931 BBC4 +8330E932 BBC5 +8330E933 BBC6 +8330E934 BBC7 +8330E935 BBC8 +8330E936 BBC9 +8330E937 BBCA +8330E938 BBCB +8330E939 BBCC +8330EA30 BBCD +8330EA31 BBCE +8330EA32 BBCF +8330EA33 BBD0 +8330EA34 BBD1 +8330EA35 BBD2 +8330EA36 BBD3 +8330EA37 BBD4 +8330EA38 BBD5 +8330EA39 BBD6 +8330EB30 BBD7 +8330EB31 BBD8 +8330EB32 BBD9 +8330EB33 BBDA +8330EB34 BBDB +8330EB35 BBDC +8330EB36 BBDD +8330EB37 BBDE +8330EB38 BBDF +8330EB39 BBE0 +8330EC30 BBE1 +8330EC31 BBE2 +8330EC32 BBE3 +8330EC33 BBE4 +8330EC34 BBE5 +8330EC35 BBE6 +8330EC36 BBE7 +8330EC37 BBE8 +8330EC38 BBE9 +8330EC39 BBEA +8330ED30 BBEB +8330ED31 BBEC +8330ED32 BBED +8330ED33 BBEE +8330ED34 BBEF +8330ED35 BBF0 +8330ED36 BBF1 +8330ED37 BBF2 +8330ED38 BBF3 +8330ED39 BBF4 +8330EE30 BBF5 +8330EE31 BBF6 +8330EE32 BBF7 +8330EE33 BBF8 +8330EE34 BBF9 +8330EE35 BBFA +8330EE36 BBFB +8330EE37 BBFC +8330EE38 BBFD +8330EE39 BBFE +8330EF30 BBFF +8330EF31 BC00 +8330EF32 BC01 +8330EF33 BC02 +8330EF34 BC03 +8330EF35 BC04 +8330EF36 BC05 +8330EF37 BC06 +8330EF38 BC07 +8330EF39 BC08 +8330F030 BC09 +8330F031 BC0A +8330F032 BC0B +8330F033 BC0C +8330F034 BC0D +8330F035 BC0E +8330F036 BC0F +8330F037 BC10 +8330F038 BC11 +8330F039 BC12 +8330F130 BC13 +8330F131 BC14 +8330F132 BC15 +8330F133 BC16 +8330F134 BC17 +8330F135 BC18 +8330F136 BC19 +8330F137 BC1A +8330F138 BC1B +8330F139 BC1C +8330F230 BC1D +8330F231 BC1E +8330F232 BC1F +8330F233 BC20 +8330F234 BC21 +8330F235 BC22 +8330F236 BC23 +8330F237 BC24 +8330F238 BC25 +8330F239 BC26 +8330F330 BC27 +8330F331 BC28 +8330F332 BC29 +8330F333 BC2A +8330F334 BC2B +8330F335 BC2C +8330F336 BC2D +8330F337 BC2E +8330F338 BC2F +8330F339 BC30 +8330F430 BC31 +8330F431 BC32 +8330F432 BC33 +8330F433 BC34 +8330F434 BC35 +8330F435 BC36 +8330F436 BC37 +8330F437 BC38 +8330F438 BC39 +8330F439 BC3A +8330F530 BC3B +8330F531 BC3C +8330F532 BC3D +8330F533 BC3E +8330F534 BC3F +8330F535 BC40 +8330F536 BC41 +8330F537 BC42 +8330F538 BC43 +8330F539 BC44 +8330F630 BC45 +8330F631 BC46 +8330F632 BC47 +8330F633 BC48 +8330F634 BC49 +8330F635 BC4A +8330F636 BC4B +8330F637 BC4C +8330F638 BC4D +8330F639 BC4E +8330F730 BC4F +8330F731 BC50 +8330F732 BC51 +8330F733 BC52 +8330F734 BC53 +8330F735 BC54 +8330F736 BC55 +8330F737 BC56 +8330F738 BC57 +8330F739 BC58 +8330F830 BC59 +8330F831 BC5A +8330F832 BC5B +8330F833 BC5C +8330F834 BC5D +8330F835 BC5E +8330F836 BC5F +8330F837 BC60 +8330F838 BC61 +8330F839 BC62 +8330F930 BC63 +8330F931 BC64 +8330F932 BC65 +8330F933 BC66 +8330F934 BC67 +8330F935 BC68 +8330F936 BC69 +8330F937 BC6A +8330F938 BC6B +8330F939 BC6C +8330FA30 BC6D +8330FA31 BC6E +8330FA32 BC6F +8330FA33 BC70 +8330FA34 BC71 +8330FA35 BC72 +8330FA36 BC73 +8330FA37 BC74 +8330FA38 BC75 +8330FA39 BC76 +8330FB30 BC77 +8330FB31 BC78 +8330FB32 BC79 +8330FB33 BC7A +8330FB34 BC7B +8330FB35 BC7C +8330FB36 BC7D +8330FB37 BC7E +8330FB38 BC7F +8330FB39 BC80 +8330FC30 BC81 +8330FC31 BC82 +8330FC32 BC83 +8330FC33 BC84 +8330FC34 BC85 +8330FC35 BC86 +8330FC36 BC87 +8330FC37 BC88 +8330FC38 BC89 +8330FC39 BC8A +8330FD30 BC8B +8330FD31 BC8C +8330FD32 BC8D +8330FD33 BC8E +8330FD34 BC8F +8330FD35 BC90 +8330FD36 BC91 +8330FD37 BC92 +8330FD38 BC93 +8330FD39 BC94 +8330FE30 BC95 +8330FE31 BC96 +8330FE32 BC97 +8330FE33 BC98 +8330FE34 BC99 +8330FE35 BC9A +8330FE36 BC9B +8330FE37 BC9C +8330FE38 BC9D +8330FE39 BC9E +83318130 BC9F +83318131 BCA0 +83318132 BCA1 +83318133 BCA2 +83318134 BCA3 +83318135 BCA4 +83318136 BCA5 +83318137 BCA6 +83318138 BCA7 +83318139 BCA8 +83318230 BCA9 +83318231 BCAA +83318232 BCAB +83318233 BCAC +83318234 BCAD +83318235 BCAE +83318236 BCAF +83318237 BCB0 +83318238 BCB1 +83318239 BCB2 +83318330 BCB3 +83318331 BCB4 +83318332 BCB5 +83318333 BCB6 +83318334 BCB7 +83318335 BCB8 +83318336 BCB9 +83318337 BCBA +83318338 BCBB +83318339 BCBC +83318430 BCBD +83318431 BCBE +83318432 BCBF +83318433 BCC0 +83318434 BCC1 +83318435 BCC2 +83318436 BCC3 +83318437 BCC4 +83318438 BCC5 +83318439 BCC6 +83318530 BCC7 +83318531 BCC8 +83318532 BCC9 +83318533 BCCA +83318534 BCCB +83318535 BCCC +83318536 BCCD +83318537 BCCE +83318538 BCCF +83318539 BCD0 +83318630 BCD1 +83318631 BCD2 +83318632 BCD3 +83318633 BCD4 +83318634 BCD5 +83318635 BCD6 +83318636 BCD7 +83318637 BCD8 +83318638 BCD9 +83318639 BCDA +83318730 BCDB +83318731 BCDC +83318732 BCDD +83318733 BCDE +83318734 BCDF +83318735 BCE0 +83318736 BCE1 +83318737 BCE2 +83318738 BCE3 +83318739 BCE4 +83318830 BCE5 +83318831 BCE6 +83318832 BCE7 +83318833 BCE8 +83318834 BCE9 +83318835 BCEA +83318836 BCEB +83318837 BCEC +83318838 BCED +83318839 BCEE +83318930 BCEF +83318931 BCF0 +83318932 BCF1 +83318933 BCF2 +83318934 BCF3 +83318935 BCF4 +83318936 BCF5 +83318937 BCF6 +83318938 BCF7 +83318939 BCF8 +83318A30 BCF9 +83318A31 BCFA +83318A32 BCFB +83318A33 BCFC +83318A34 BCFD +83318A35 BCFE +83318A36 BCFF +83318A37 BD00 +83318A38 BD01 +83318A39 BD02 +83318B30 BD03 +83318B31 BD04 +83318B32 BD05 +83318B33 BD06 +83318B34 BD07 +83318B35 BD08 +83318B36 BD09 +83318B37 BD0A +83318B38 BD0B +83318B39 BD0C +83318C30 BD0D +83318C31 BD0E +83318C32 BD0F +83318C33 BD10 +83318C34 BD11 +83318C35 BD12 +83318C36 BD13 +83318C37 BD14 +83318C38 BD15 +83318C39 BD16 +83318D30 BD17 +83318D31 BD18 +83318D32 BD19 +83318D33 BD1A +83318D34 BD1B +83318D35 BD1C +83318D36 BD1D +83318D37 BD1E +83318D38 BD1F +83318D39 BD20 +83318E30 BD21 +83318E31 BD22 +83318E32 BD23 +83318E33 BD24 +83318E34 BD25 +83318E35 BD26 +83318E36 BD27 +83318E37 BD28 +83318E38 BD29 +83318E39 BD2A +83318F30 BD2B +83318F31 BD2C +83318F32 BD2D +83318F33 BD2E +83318F34 BD2F +83318F35 BD30 +83318F36 BD31 +83318F37 BD32 +83318F38 BD33 +83318F39 BD34 +83319030 BD35 +83319031 BD36 +83319032 BD37 +83319033 BD38 +83319034 BD39 +83319035 BD3A +83319036 BD3B +83319037 BD3C +83319038 BD3D +83319039 BD3E +83319130 BD3F +83319131 BD40 +83319132 BD41 +83319133 BD42 +83319134 BD43 +83319135 BD44 +83319136 BD45 +83319137 BD46 +83319138 BD47 +83319139 BD48 +83319230 BD49 +83319231 BD4A +83319232 BD4B +83319233 BD4C +83319234 BD4D +83319235 BD4E +83319236 BD4F +83319237 BD50 +83319238 BD51 +83319239 BD52 +83319330 BD53 +83319331 BD54 +83319332 BD55 +83319333 BD56 +83319334 BD57 +83319335 BD58 +83319336 BD59 +83319337 BD5A +83319338 BD5B +83319339 BD5C +83319430 BD5D +83319431 BD5E +83319432 BD5F +83319433 BD60 +83319434 BD61 +83319435 BD62 +83319436 BD63 +83319437 BD64 +83319438 BD65 +83319439 BD66 +83319530 BD67 +83319531 BD68 +83319532 BD69 +83319533 BD6A +83319534 BD6B +83319535 BD6C +83319536 BD6D +83319537 BD6E +83319538 BD6F +83319539 BD70 +83319630 BD71 +83319631 BD72 +83319632 BD73 +83319633 BD74 +83319634 BD75 +83319635 BD76 +83319636 BD77 +83319637 BD78 +83319638 BD79 +83319639 BD7A +83319730 BD7B +83319731 BD7C +83319732 BD7D +83319733 BD7E +83319734 BD7F +83319735 BD80 +83319736 BD81 +83319737 BD82 +83319738 BD83 +83319739 BD84 +83319830 BD85 +83319831 BD86 +83319832 BD87 +83319833 BD88 +83319834 BD89 +83319835 BD8A +83319836 BD8B +83319837 BD8C +83319838 BD8D +83319839 BD8E +83319930 BD8F +83319931 BD90 +83319932 BD91 +83319933 BD92 +83319934 BD93 +83319935 BD94 +83319936 BD95 +83319937 BD96 +83319938 BD97 +83319939 BD98 +83319A30 BD99 +83319A31 BD9A +83319A32 BD9B +83319A33 BD9C +83319A34 BD9D +83319A35 BD9E +83319A36 BD9F +83319A37 BDA0 +83319A38 BDA1 +83319A39 BDA2 +83319B30 BDA3 +83319B31 BDA4 +83319B32 BDA5 +83319B33 BDA6 +83319B34 BDA7 +83319B35 BDA8 +83319B36 BDA9 +83319B37 BDAA +83319B38 BDAB +83319B39 BDAC +83319C30 BDAD +83319C31 BDAE +83319C32 BDAF +83319C33 BDB0 +83319C34 BDB1 +83319C35 BDB2 +83319C36 BDB3 +83319C37 BDB4 +83319C38 BDB5 +83319C39 BDB6 +83319D30 BDB7 +83319D31 BDB8 +83319D32 BDB9 +83319D33 BDBA +83319D34 BDBB +83319D35 BDBC +83319D36 BDBD +83319D37 BDBE +83319D38 BDBF +83319D39 BDC0 +83319E30 BDC1 +83319E31 BDC2 +83319E32 BDC3 +83319E33 BDC4 +83319E34 BDC5 +83319E35 BDC6 +83319E36 BDC7 +83319E37 BDC8 +83319E38 BDC9 +83319E39 BDCA +83319F30 BDCB +83319F31 BDCC +83319F32 BDCD +83319F33 BDCE +83319F34 BDCF +83319F35 BDD0 +83319F36 BDD1 +83319F37 BDD2 +83319F38 BDD3 +83319F39 BDD4 +8331A030 BDD5 +8331A031 BDD6 +8331A032 BDD7 +8331A033 BDD8 +8331A034 BDD9 +8331A035 BDDA +8331A036 BDDB +8331A037 BDDC +8331A038 BDDD +8331A039 BDDE +8331A130 BDDF +8331A131 BDE0 +8331A132 BDE1 +8331A133 BDE2 +8331A134 BDE3 +8331A135 BDE4 +8331A136 BDE5 +8331A137 BDE6 +8331A138 BDE7 +8331A139 BDE8 +8331A230 BDE9 +8331A231 BDEA +8331A232 BDEB +8331A233 BDEC +8331A234 BDED +8331A235 BDEE +8331A236 BDEF +8331A237 BDF0 +8331A238 BDF1 +8331A239 BDF2 +8331A330 BDF3 +8331A331 BDF4 +8331A332 BDF5 +8331A333 BDF6 +8331A334 BDF7 +8331A335 BDF8 +8331A336 BDF9 +8331A337 BDFA +8331A338 BDFB +8331A339 BDFC +8331A430 BDFD +8331A431 BDFE +8331A432 BDFF +8331A433 BE00 +8331A434 BE01 +8331A435 BE02 +8331A436 BE03 +8331A437 BE04 +8331A438 BE05 +8331A439 BE06 +8331A530 BE07 +8331A531 BE08 +8331A532 BE09 +8331A533 BE0A +8331A534 BE0B +8331A535 BE0C +8331A536 BE0D +8331A537 BE0E +8331A538 BE0F +8331A539 BE10 +8331A630 BE11 +8331A631 BE12 +8331A632 BE13 +8331A633 BE14 +8331A634 BE15 +8331A635 BE16 +8331A636 BE17 +8331A637 BE18 +8331A638 BE19 +8331A639 BE1A +8331A730 BE1B +8331A731 BE1C +8331A732 BE1D +8331A733 BE1E +8331A734 BE1F +8331A735 BE20 +8331A736 BE21 +8331A737 BE22 +8331A738 BE23 +8331A739 BE24 +8331A830 BE25 +8331A831 BE26 +8331A832 BE27 +8331A833 BE28 +8331A834 BE29 +8331A835 BE2A +8331A836 BE2B +8331A837 BE2C +8331A838 BE2D +8331A839 BE2E +8331A930 BE2F +8331A931 BE30 +8331A932 BE31 +8331A933 BE32 +8331A934 BE33 +8331A935 BE34 +8331A936 BE35 +8331A937 BE36 +8331A938 BE37 +8331A939 BE38 +8331AA30 BE39 +8331AA31 BE3A +8331AA32 BE3B +8331AA33 BE3C +8331AA34 BE3D +8331AA35 BE3E +8331AA36 BE3F +8331AA37 BE40 +8331AA38 BE41 +8331AA39 BE42 +8331AB30 BE43 +8331AB31 BE44 +8331AB32 BE45 +8331AB33 BE46 +8331AB34 BE47 +8331AB35 BE48 +8331AB36 BE49 +8331AB37 BE4A +8331AB38 BE4B +8331AB39 BE4C +8331AC30 BE4D +8331AC31 BE4E +8331AC32 BE4F +8331AC33 BE50 +8331AC34 BE51 +8331AC35 BE52 +8331AC36 BE53 +8331AC37 BE54 +8331AC38 BE55 +8331AC39 BE56 +8331AD30 BE57 +8331AD31 BE58 +8331AD32 BE59 +8331AD33 BE5A +8331AD34 BE5B +8331AD35 BE5C +8331AD36 BE5D +8331AD37 BE5E +8331AD38 BE5F +8331AD39 BE60 +8331AE30 BE61 +8331AE31 BE62 +8331AE32 BE63 +8331AE33 BE64 +8331AE34 BE65 +8331AE35 BE66 +8331AE36 BE67 +8331AE37 BE68 +8331AE38 BE69 +8331AE39 BE6A +8331AF30 BE6B +8331AF31 BE6C +8331AF32 BE6D +8331AF33 BE6E +8331AF34 BE6F +8331AF35 BE70 +8331AF36 BE71 +8331AF37 BE72 +8331AF38 BE73 +8331AF39 BE74 +8331B030 BE75 +8331B031 BE76 +8331B032 BE77 +8331B033 BE78 +8331B034 BE79 +8331B035 BE7A +8331B036 BE7B +8331B037 BE7C +8331B038 BE7D +8331B039 BE7E +8331B130 BE7F +8331B131 BE80 +8331B132 BE81 +8331B133 BE82 +8331B134 BE83 +8331B135 BE84 +8331B136 BE85 +8331B137 BE86 +8331B138 BE87 +8331B139 BE88 +8331B230 BE89 +8331B231 BE8A +8331B232 BE8B +8331B233 BE8C +8331B234 BE8D +8331B235 BE8E +8331B236 BE8F +8331B237 BE90 +8331B238 BE91 +8331B239 BE92 +8331B330 BE93 +8331B331 BE94 +8331B332 BE95 +8331B333 BE96 +8331B334 BE97 +8331B335 BE98 +8331B336 BE99 +8331B337 BE9A +8331B338 BE9B +8331B339 BE9C +8331B430 BE9D +8331B431 BE9E +8331B432 BE9F +8331B433 BEA0 +8331B434 BEA1 +8331B435 BEA2 +8331B436 BEA3 +8331B437 BEA4 +8331B438 BEA5 +8331B439 BEA6 +8331B530 BEA7 +8331B531 BEA8 +8331B532 BEA9 +8331B533 BEAA +8331B534 BEAB +8331B535 BEAC +8331B536 BEAD +8331B537 BEAE +8331B538 BEAF +8331B539 BEB0 +8331B630 BEB1 +8331B631 BEB2 +8331B632 BEB3 +8331B633 BEB4 +8331B634 BEB5 +8331B635 BEB6 +8331B636 BEB7 +8331B637 BEB8 +8331B638 BEB9 +8331B639 BEBA +8331B730 BEBB +8331B731 BEBC +8331B732 BEBD +8331B733 BEBE +8331B734 BEBF +8331B735 BEC0 +8331B736 BEC1 +8331B737 BEC2 +8331B738 BEC3 +8331B739 BEC4 +8331B830 BEC5 +8331B831 BEC6 +8331B832 BEC7 +8331B833 BEC8 +8331B834 BEC9 +8331B835 BECA +8331B836 BECB +8331B837 BECC +8331B838 BECD +8331B839 BECE +8331B930 BECF +8331B931 BED0 +8331B932 BED1 +8331B933 BED2 +8331B934 BED3 +8331B935 BED4 +8331B936 BED5 +8331B937 BED6 +8331B938 BED7 +8331B939 BED8 +8331BA30 BED9 +8331BA31 BEDA +8331BA32 BEDB +8331BA33 BEDC +8331BA34 BEDD +8331BA35 BEDE +8331BA36 BEDF +8331BA37 BEE0 +8331BA38 BEE1 +8331BA39 BEE2 +8331BB30 BEE3 +8331BB31 BEE4 +8331BB32 BEE5 +8331BB33 BEE6 +8331BB34 BEE7 +8331BB35 BEE8 +8331BB36 BEE9 +8331BB37 BEEA +8331BB38 BEEB +8331BB39 BEEC +8331BC30 BEED +8331BC31 BEEE +8331BC32 BEEF +8331BC33 BEF0 +8331BC34 BEF1 +8331BC35 BEF2 +8331BC36 BEF3 +8331BC37 BEF4 +8331BC38 BEF5 +8331BC39 BEF6 +8331BD30 BEF7 +8331BD31 BEF8 +8331BD32 BEF9 +8331BD33 BEFA +8331BD34 BEFB +8331BD35 BEFC +8331BD36 BEFD +8331BD37 BEFE +8331BD38 BEFF +8331BD39 BF00 +8331BE30 BF01 +8331BE31 BF02 +8331BE32 BF03 +8331BE33 BF04 +8331BE34 BF05 +8331BE35 BF06 +8331BE36 BF07 +8331BE37 BF08 +8331BE38 BF09 +8331BE39 BF0A +8331BF30 BF0B +8331BF31 BF0C +8331BF32 BF0D +8331BF33 BF0E +8331BF34 BF0F +8331BF35 BF10 +8331BF36 BF11 +8331BF37 BF12 +8331BF38 BF13 +8331BF39 BF14 +8331C030 BF15 +8331C031 BF16 +8331C032 BF17 +8331C033 BF18 +8331C034 BF19 +8331C035 BF1A +8331C036 BF1B +8331C037 BF1C +8331C038 BF1D +8331C039 BF1E +8331C130 BF1F +8331C131 BF20 +8331C132 BF21 +8331C133 BF22 +8331C134 BF23 +8331C135 BF24 +8331C136 BF25 +8331C137 BF26 +8331C138 BF27 +8331C139 BF28 +8331C230 BF29 +8331C231 BF2A +8331C232 BF2B +8331C233 BF2C +8331C234 BF2D +8331C235 BF2E +8331C236 BF2F +8331C237 BF30 +8331C238 BF31 +8331C239 BF32 +8331C330 BF33 +8331C331 BF34 +8331C332 BF35 +8331C333 BF36 +8331C334 BF37 +8331C335 BF38 +8331C336 BF39 +8331C337 BF3A +8331C338 BF3B +8331C339 BF3C +8331C430 BF3D +8331C431 BF3E +8331C432 BF3F +8331C433 BF40 +8331C434 BF41 +8331C435 BF42 +8331C436 BF43 +8331C437 BF44 +8331C438 BF45 +8331C439 BF46 +8331C530 BF47 +8331C531 BF48 +8331C532 BF49 +8331C533 BF4A +8331C534 BF4B +8331C535 BF4C +8331C536 BF4D +8331C537 BF4E +8331C538 BF4F +8331C539 BF50 +8331C630 BF51 +8331C631 BF52 +8331C632 BF53 +8331C633 BF54 +8331C634 BF55 +8331C635 BF56 +8331C636 BF57 +8331C637 BF58 +8331C638 BF59 +8331C639 BF5A +8331C730 BF5B +8331C731 BF5C +8331C732 BF5D +8331C733 BF5E +8331C734 BF5F +8331C735 BF60 +8331C736 BF61 +8331C737 BF62 +8331C738 BF63 +8331C739 BF64 +8331C830 BF65 +8331C831 BF66 +8331C832 BF67 +8331C833 BF68 +8331C834 BF69 +8331C835 BF6A +8331C836 BF6B +8331C837 BF6C +8331C838 BF6D +8331C839 BF6E +8331C930 BF6F +8331C931 BF70 +8331C932 BF71 +8331C933 BF72 +8331C934 BF73 +8331C935 BF74 +8331C936 BF75 +8331C937 BF76 +8331C938 BF77 +8331C939 BF78 +8331CA30 BF79 +8331CA31 BF7A +8331CA32 BF7B +8331CA33 BF7C +8331CA34 BF7D +8331CA35 BF7E +8331CA36 BF7F +8331CA37 BF80 +8331CA38 BF81 +8331CA39 BF82 +8331CB30 BF83 +8331CB31 BF84 +8331CB32 BF85 +8331CB33 BF86 +8331CB34 BF87 +8331CB35 BF88 +8331CB36 BF89 +8331CB37 BF8A +8331CB38 BF8B +8331CB39 BF8C +8331CC30 BF8D +8331CC31 BF8E +8331CC32 BF8F +8331CC33 BF90 +8331CC34 BF91 +8331CC35 BF92 +8331CC36 BF93 +8331CC37 BF94 +8331CC38 BF95 +8331CC39 BF96 +8331CD30 BF97 +8331CD31 BF98 +8331CD32 BF99 +8331CD33 BF9A +8331CD34 BF9B +8331CD35 BF9C +8331CD36 BF9D +8331CD37 BF9E +8331CD38 BF9F +8331CD39 BFA0 +8331CE30 BFA1 +8331CE31 BFA2 +8331CE32 BFA3 +8331CE33 BFA4 +8331CE34 BFA5 +8331CE35 BFA6 +8331CE36 BFA7 +8331CE37 BFA8 +8331CE38 BFA9 +8331CE39 BFAA +8331CF30 BFAB +8331CF31 BFAC +8331CF32 BFAD +8331CF33 BFAE +8331CF34 BFAF +8331CF35 BFB0 +8331CF36 BFB1 +8331CF37 BFB2 +8331CF38 BFB3 +8331CF39 BFB4 +8331D030 BFB5 +8331D031 BFB6 +8331D032 BFB7 +8331D033 BFB8 +8331D034 BFB9 +8331D035 BFBA +8331D036 BFBB +8331D037 BFBC +8331D038 BFBD +8331D039 BFBE +8331D130 BFBF +8331D131 BFC0 +8331D132 BFC1 +8331D133 BFC2 +8331D134 BFC3 +8331D135 BFC4 +8331D136 BFC5 +8331D137 BFC6 +8331D138 BFC7 +8331D139 BFC8 +8331D230 BFC9 +8331D231 BFCA +8331D232 BFCB +8331D233 BFCC +8331D234 BFCD +8331D235 BFCE +8331D236 BFCF +8331D237 BFD0 +8331D238 BFD1 +8331D239 BFD2 +8331D330 BFD3 +8331D331 BFD4 +8331D332 BFD5 +8331D333 BFD6 +8331D334 BFD7 +8331D335 BFD8 +8331D336 BFD9 +8331D337 BFDA +8331D338 BFDB +8331D339 BFDC +8331D430 BFDD +8331D431 BFDE +8331D432 BFDF +8331D433 BFE0 +8331D434 BFE1 +8331D435 BFE2 +8331D436 BFE3 +8331D437 BFE4 +8331D438 BFE5 +8331D439 BFE6 +8331D530 BFE7 +8331D531 BFE8 +8331D532 BFE9 +8331D533 BFEA +8331D534 BFEB +8331D535 BFEC +8331D536 BFED +8331D537 BFEE +8331D538 BFEF +8331D539 BFF0 +8331D630 BFF1 +8331D631 BFF2 +8331D632 BFF3 +8331D633 BFF4 +8331D634 BFF5 +8331D635 BFF6 +8331D636 BFF7 +8331D637 BFF8 +8331D638 BFF9 +8331D639 BFFA +8331D730 BFFB +8331D731 BFFC +8331D732 BFFD +8331D733 BFFE +8331D734 BFFF +8331D735 C000 +8331D736 C001 +8331D737 C002 +8331D738 C003 +8331D739 C004 +8331D830 C005 +8331D831 C006 +8331D832 C007 +8331D833 C008 +8331D834 C009 +8331D835 C00A +8331D836 C00B +8331D837 C00C +8331D838 C00D +8331D839 C00E +8331D930 C00F +8331D931 C010 +8331D932 C011 +8331D933 C012 +8331D934 C013 +8331D935 C014 +8331D936 C015 +8331D937 C016 +8331D938 C017 +8331D939 C018 +8331DA30 C019 +8331DA31 C01A +8331DA32 C01B +8331DA33 C01C +8331DA34 C01D +8331DA35 C01E +8331DA36 C01F +8331DA37 C020 +8331DA38 C021 +8331DA39 C022 +8331DB30 C023 +8331DB31 C024 +8331DB32 C025 +8331DB33 C026 +8331DB34 C027 +8331DB35 C028 +8331DB36 C029 +8331DB37 C02A +8331DB38 C02B +8331DB39 C02C +8331DC30 C02D +8331DC31 C02E +8331DC32 C02F +8331DC33 C030 +8331DC34 C031 +8331DC35 C032 +8331DC36 C033 +8331DC37 C034 +8331DC38 C035 +8331DC39 C036 +8331DD30 C037 +8331DD31 C038 +8331DD32 C039 +8331DD33 C03A +8331DD34 C03B +8331DD35 C03C +8331DD36 C03D +8331DD37 C03E +8331DD38 C03F +8331DD39 C040 +8331DE30 C041 +8331DE31 C042 +8331DE32 C043 +8331DE33 C044 +8331DE34 C045 +8331DE35 C046 +8331DE36 C047 +8331DE37 C048 +8331DE38 C049 +8331DE39 C04A +8331DF30 C04B +8331DF31 C04C +8331DF32 C04D +8331DF33 C04E +8331DF34 C04F +8331DF35 C050 +8331DF36 C051 +8331DF37 C052 +8331DF38 C053 +8331DF39 C054 +8331E030 C055 +8331E031 C056 +8331E032 C057 +8331E033 C058 +8331E034 C059 +8331E035 C05A +8331E036 C05B +8331E037 C05C +8331E038 C05D +8331E039 C05E +8331E130 C05F +8331E131 C060 +8331E132 C061 +8331E133 C062 +8331E134 C063 +8331E135 C064 +8331E136 C065 +8331E137 C066 +8331E138 C067 +8331E139 C068 +8331E230 C069 +8331E231 C06A +8331E232 C06B +8331E233 C06C +8331E234 C06D +8331E235 C06E +8331E236 C06F +8331E237 C070 +8331E238 C071 +8331E239 C072 +8331E330 C073 +8331E331 C074 +8331E332 C075 +8331E333 C076 +8331E334 C077 +8331E335 C078 +8331E336 C079 +8331E337 C07A +8331E338 C07B +8331E339 C07C +8331E430 C07D +8331E431 C07E +8331E432 C07F +8331E433 C080 +8331E434 C081 +8331E435 C082 +8331E436 C083 +8331E437 C084 +8331E438 C085 +8331E439 C086 +8331E530 C087 +8331E531 C088 +8331E532 C089 +8331E533 C08A +8331E534 C08B +8331E535 C08C +8331E536 C08D +8331E537 C08E +8331E538 C08F +8331E539 C090 +8331E630 C091 +8331E631 C092 +8331E632 C093 +8331E633 C094 +8331E634 C095 +8331E635 C096 +8331E636 C097 +8331E637 C098 +8331E638 C099 +8331E639 C09A +8331E730 C09B +8331E731 C09C +8331E732 C09D +8331E733 C09E +8331E734 C09F +8331E735 C0A0 +8331E736 C0A1 +8331E737 C0A2 +8331E738 C0A3 +8331E739 C0A4 +8331E830 C0A5 +8331E831 C0A6 +8331E832 C0A7 +8331E833 C0A8 +8331E834 C0A9 +8331E835 C0AA +8331E836 C0AB +8331E837 C0AC +8331E838 C0AD +8331E839 C0AE +8331E930 C0AF +8331E931 C0B0 +8331E932 C0B1 +8331E933 C0B2 +8331E934 C0B3 +8331E935 C0B4 +8331E936 C0B5 +8331E937 C0B6 +8331E938 C0B7 +8331E939 C0B8 +8331EA30 C0B9 +8331EA31 C0BA +8331EA32 C0BB +8331EA33 C0BC +8331EA34 C0BD +8331EA35 C0BE +8331EA36 C0BF +8331EA37 C0C0 +8331EA38 C0C1 +8331EA39 C0C2 +8331EB30 C0C3 +8331EB31 C0C4 +8331EB32 C0C5 +8331EB33 C0C6 +8331EB34 C0C7 +8331EB35 C0C8 +8331EB36 C0C9 +8331EB37 C0CA +8331EB38 C0CB +8331EB39 C0CC +8331EC30 C0CD +8331EC31 C0CE +8331EC32 C0CF +8331EC33 C0D0 +8331EC34 C0D1 +8331EC35 C0D2 +8331EC36 C0D3 +8331EC37 C0D4 +8331EC38 C0D5 +8331EC39 C0D6 +8331ED30 C0D7 +8331ED31 C0D8 +8331ED32 C0D9 +8331ED33 C0DA +8331ED34 C0DB +8331ED35 C0DC +8331ED36 C0DD +8331ED37 C0DE +8331ED38 C0DF +8331ED39 C0E0 +8331EE30 C0E1 +8331EE31 C0E2 +8331EE32 C0E3 +8331EE33 C0E4 +8331EE34 C0E5 +8331EE35 C0E6 +8331EE36 C0E7 +8331EE37 C0E8 +8331EE38 C0E9 +8331EE39 C0EA +8331EF30 C0EB +8331EF31 C0EC +8331EF32 C0ED +8331EF33 C0EE +8331EF34 C0EF +8331EF35 C0F0 +8331EF36 C0F1 +8331EF37 C0F2 +8331EF38 C0F3 +8331EF39 C0F4 +8331F030 C0F5 +8331F031 C0F6 +8331F032 C0F7 +8331F033 C0F8 +8331F034 C0F9 +8331F035 C0FA +8331F036 C0FB +8331F037 C0FC +8331F038 C0FD +8331F039 C0FE +8331F130 C0FF +8331F131 C100 +8331F132 C101 +8331F133 C102 +8331F134 C103 +8331F135 C104 +8331F136 C105 +8331F137 C106 +8331F138 C107 +8331F139 C108 +8331F230 C109 +8331F231 C10A +8331F232 C10B +8331F233 C10C +8331F234 C10D +8331F235 C10E +8331F236 C10F +8331F237 C110 +8331F238 C111 +8331F239 C112 +8331F330 C113 +8331F331 C114 +8331F332 C115 +8331F333 C116 +8331F334 C117 +8331F335 C118 +8331F336 C119 +8331F337 C11A +8331F338 C11B +8331F339 C11C +8331F430 C11D +8331F431 C11E +8331F432 C11F +8331F433 C120 +8331F434 C121 +8331F435 C122 +8331F436 C123 +8331F437 C124 +8331F438 C125 +8331F439 C126 +8331F530 C127 +8331F531 C128 +8331F532 C129 +8331F533 C12A +8331F534 C12B +8331F535 C12C +8331F536 C12D +8331F537 C12E +8331F538 C12F +8331F539 C130 +8331F630 C131 +8331F631 C132 +8331F632 C133 +8331F633 C134 +8331F634 C135 +8331F635 C136 +8331F636 C137 +8331F637 C138 +8331F638 C139 +8331F639 C13A +8331F730 C13B +8331F731 C13C +8331F732 C13D +8331F733 C13E +8331F734 C13F +8331F735 C140 +8331F736 C141 +8331F737 C142 +8331F738 C143 +8331F739 C144 +8331F830 C145 +8331F831 C146 +8331F832 C147 +8331F833 C148 +8331F834 C149 +8331F835 C14A +8331F836 C14B +8331F837 C14C +8331F838 C14D +8331F839 C14E +8331F930 C14F +8331F931 C150 +8331F932 C151 +8331F933 C152 +8331F934 C153 +8331F935 C154 +8331F936 C155 +8331F937 C156 +8331F938 C157 +8331F939 C158 +8331FA30 C159 +8331FA31 C15A +8331FA32 C15B +8331FA33 C15C +8331FA34 C15D +8331FA35 C15E +8331FA36 C15F +8331FA37 C160 +8331FA38 C161 +8331FA39 C162 +8331FB30 C163 +8331FB31 C164 +8331FB32 C165 +8331FB33 C166 +8331FB34 C167 +8331FB35 C168 +8331FB36 C169 +8331FB37 C16A +8331FB38 C16B +8331FB39 C16C +8331FC30 C16D +8331FC31 C16E +8331FC32 C16F +8331FC33 C170 +8331FC34 C171 +8331FC35 C172 +8331FC36 C173 +8331FC37 C174 +8331FC38 C175 +8331FC39 C176 +8331FD30 C177 +8331FD31 C178 +8331FD32 C179 +8331FD33 C17A +8331FD34 C17B +8331FD35 C17C +8331FD36 C17D +8331FD37 C17E +8331FD38 C17F +8331FD39 C180 +8331FE30 C181 +8331FE31 C182 +8331FE32 C183 +8331FE33 C184 +8331FE34 C185 +8331FE35 C186 +8331FE36 C187 +8331FE37 C188 +8331FE38 C189 +8331FE39 C18A +83328130 C18B +83328131 C18C +83328132 C18D +83328133 C18E +83328134 C18F +83328135 C190 +83328136 C191 +83328137 C192 +83328138 C193 +83328139 C194 +83328230 C195 +83328231 C196 +83328232 C197 +83328233 C198 +83328234 C199 +83328235 C19A +83328236 C19B +83328237 C19C +83328238 C19D +83328239 C19E +83328330 C19F +83328331 C1A0 +83328332 C1A1 +83328333 C1A2 +83328334 C1A3 +83328335 C1A4 +83328336 C1A5 +83328337 C1A6 +83328338 C1A7 +83328339 C1A8 +83328430 C1A9 +83328431 C1AA +83328432 C1AB +83328433 C1AC +83328434 C1AD +83328435 C1AE +83328436 C1AF +83328437 C1B0 +83328438 C1B1 +83328439 C1B2 +83328530 C1B3 +83328531 C1B4 +83328532 C1B5 +83328533 C1B6 +83328534 C1B7 +83328535 C1B8 +83328536 C1B9 +83328537 C1BA +83328538 C1BB +83328539 C1BC +83328630 C1BD +83328631 C1BE +83328632 C1BF +83328633 C1C0 +83328634 C1C1 +83328635 C1C2 +83328636 C1C3 +83328637 C1C4 +83328638 C1C5 +83328639 C1C6 +83328730 C1C7 +83328731 C1C8 +83328732 C1C9 +83328733 C1CA +83328734 C1CB +83328735 C1CC +83328736 C1CD +83328737 C1CE +83328738 C1CF +83328739 C1D0 +83328830 C1D1 +83328831 C1D2 +83328832 C1D3 +83328833 C1D4 +83328834 C1D5 +83328835 C1D6 +83328836 C1D7 +83328837 C1D8 +83328838 C1D9 +83328839 C1DA +83328930 C1DB +83328931 C1DC +83328932 C1DD +83328933 C1DE +83328934 C1DF +83328935 C1E0 +83328936 C1E1 +83328937 C1E2 +83328938 C1E3 +83328939 C1E4 +83328A30 C1E5 +83328A31 C1E6 +83328A32 C1E7 +83328A33 C1E8 +83328A34 C1E9 +83328A35 C1EA +83328A36 C1EB +83328A37 C1EC +83328A38 C1ED +83328A39 C1EE +83328B30 C1EF +83328B31 C1F0 +83328B32 C1F1 +83328B33 C1F2 +83328B34 C1F3 +83328B35 C1F4 +83328B36 C1F5 +83328B37 C1F6 +83328B38 C1F7 +83328B39 C1F8 +83328C30 C1F9 +83328C31 C1FA +83328C32 C1FB +83328C33 C1FC +83328C34 C1FD +83328C35 C1FE +83328C36 C1FF +83328C37 C200 +83328C38 C201 +83328C39 C202 +83328D30 C203 +83328D31 C204 +83328D32 C205 +83328D33 C206 +83328D34 C207 +83328D35 C208 +83328D36 C209 +83328D37 C20A +83328D38 C20B +83328D39 C20C +83328E30 C20D +83328E31 C20E +83328E32 C20F +83328E33 C210 +83328E34 C211 +83328E35 C212 +83328E36 C213 +83328E37 C214 +83328E38 C215 +83328E39 C216 +83328F30 C217 +83328F31 C218 +83328F32 C219 +83328F33 C21A +83328F34 C21B +83328F35 C21C +83328F36 C21D +83328F37 C21E +83328F38 C21F +83328F39 C220 +83329030 C221 +83329031 C222 +83329032 C223 +83329033 C224 +83329034 C225 +83329035 C226 +83329036 C227 +83329037 C228 +83329038 C229 +83329039 C22A +83329130 C22B +83329131 C22C +83329132 C22D +83329133 C22E +83329134 C22F +83329135 C230 +83329136 C231 +83329137 C232 +83329138 C233 +83329139 C234 +83329230 C235 +83329231 C236 +83329232 C237 +83329233 C238 +83329234 C239 +83329235 C23A +83329236 C23B +83329237 C23C +83329238 C23D +83329239 C23E +83329330 C23F +83329331 C240 +83329332 C241 +83329333 C242 +83329334 C243 +83329335 C244 +83329336 C245 +83329337 C246 +83329338 C247 +83329339 C248 +83329430 C249 +83329431 C24A +83329432 C24B +83329433 C24C +83329434 C24D +83329435 C24E +83329436 C24F +83329437 C250 +83329438 C251 +83329439 C252 +83329530 C253 +83329531 C254 +83329532 C255 +83329533 C256 +83329534 C257 +83329535 C258 +83329536 C259 +83329537 C25A +83329538 C25B +83329539 C25C +83329630 C25D +83329631 C25E +83329632 C25F +83329633 C260 +83329634 C261 +83329635 C262 +83329636 C263 +83329637 C264 +83329638 C265 +83329639 C266 +83329730 C267 +83329731 C268 +83329732 C269 +83329733 C26A +83329734 C26B +83329735 C26C +83329736 C26D +83329737 C26E +83329738 C26F +83329739 C270 +83329830 C271 +83329831 C272 +83329832 C273 +83329833 C274 +83329834 C275 +83329835 C276 +83329836 C277 +83329837 C278 +83329838 C279 +83329839 C27A +83329930 C27B +83329931 C27C +83329932 C27D +83329933 C27E +83329934 C27F +83329935 C280 +83329936 C281 +83329937 C282 +83329938 C283 +83329939 C284 +83329A30 C285 +83329A31 C286 +83329A32 C287 +83329A33 C288 +83329A34 C289 +83329A35 C28A +83329A36 C28B +83329A37 C28C +83329A38 C28D +83329A39 C28E +83329B30 C28F +83329B31 C290 +83329B32 C291 +83329B33 C292 +83329B34 C293 +83329B35 C294 +83329B36 C295 +83329B37 C296 +83329B38 C297 +83329B39 C298 +83329C30 C299 +83329C31 C29A +83329C32 C29B +83329C33 C29C +83329C34 C29D +83329C35 C29E +83329C36 C29F +83329C37 C2A0 +83329C38 C2A1 +83329C39 C2A2 +83329D30 C2A3 +83329D31 C2A4 +83329D32 C2A5 +83329D33 C2A6 +83329D34 C2A7 +83329D35 C2A8 +83329D36 C2A9 +83329D37 C2AA +83329D38 C2AB +83329D39 C2AC +83329E30 C2AD +83329E31 C2AE +83329E32 C2AF +83329E33 C2B0 +83329E34 C2B1 +83329E35 C2B2 +83329E36 C2B3 +83329E37 C2B4 +83329E38 C2B5 +83329E39 C2B6 +83329F30 C2B7 +83329F31 C2B8 +83329F32 C2B9 +83329F33 C2BA +83329F34 C2BB +83329F35 C2BC +83329F36 C2BD +83329F37 C2BE +83329F38 C2BF +83329F39 C2C0 +8332A030 C2C1 +8332A031 C2C2 +8332A032 C2C3 +8332A033 C2C4 +8332A034 C2C5 +8332A035 C2C6 +8332A036 C2C7 +8332A037 C2C8 +8332A038 C2C9 +8332A039 C2CA +8332A130 C2CB +8332A131 C2CC +8332A132 C2CD +8332A133 C2CE +8332A134 C2CF +8332A135 C2D0 +8332A136 C2D1 +8332A137 C2D2 +8332A138 C2D3 +8332A139 C2D4 +8332A230 C2D5 +8332A231 C2D6 +8332A232 C2D7 +8332A233 C2D8 +8332A234 C2D9 +8332A235 C2DA +8332A236 C2DB +8332A237 C2DC +8332A238 C2DD +8332A239 C2DE +8332A330 C2DF +8332A331 C2E0 +8332A332 C2E1 +8332A333 C2E2 +8332A334 C2E3 +8332A335 C2E4 +8332A336 C2E5 +8332A337 C2E6 +8332A338 C2E7 +8332A339 C2E8 +8332A430 C2E9 +8332A431 C2EA +8332A432 C2EB +8332A433 C2EC +8332A434 C2ED +8332A435 C2EE +8332A436 C2EF +8332A437 C2F0 +8332A438 C2F1 +8332A439 C2F2 +8332A530 C2F3 +8332A531 C2F4 +8332A532 C2F5 +8332A533 C2F6 +8332A534 C2F7 +8332A535 C2F8 +8332A536 C2F9 +8332A537 C2FA +8332A538 C2FB +8332A539 C2FC +8332A630 C2FD +8332A631 C2FE +8332A632 C2FF +8332A633 C300 +8332A634 C301 +8332A635 C302 +8332A636 C303 +8332A637 C304 +8332A638 C305 +8332A639 C306 +8332A730 C307 +8332A731 C308 +8332A732 C309 +8332A733 C30A +8332A734 C30B +8332A735 C30C +8332A736 C30D +8332A737 C30E +8332A738 C30F +8332A739 C310 +8332A830 C311 +8332A831 C312 +8332A832 C313 +8332A833 C314 +8332A834 C315 +8332A835 C316 +8332A836 C317 +8332A837 C318 +8332A838 C319 +8332A839 C31A +8332A930 C31B +8332A931 C31C +8332A932 C31D +8332A933 C31E +8332A934 C31F +8332A935 C320 +8332A936 C321 +8332A937 C322 +8332A938 C323 +8332A939 C324 +8332AA30 C325 +8332AA31 C326 +8332AA32 C327 +8332AA33 C328 +8332AA34 C329 +8332AA35 C32A +8332AA36 C32B +8332AA37 C32C +8332AA38 C32D +8332AA39 C32E +8332AB30 C32F +8332AB31 C330 +8332AB32 C331 +8332AB33 C332 +8332AB34 C333 +8332AB35 C334 +8332AB36 C335 +8332AB37 C336 +8332AB38 C337 +8332AB39 C338 +8332AC30 C339 +8332AC31 C33A +8332AC32 C33B +8332AC33 C33C +8332AC34 C33D +8332AC35 C33E +8332AC36 C33F +8332AC37 C340 +8332AC38 C341 +8332AC39 C342 +8332AD30 C343 +8332AD31 C344 +8332AD32 C345 +8332AD33 C346 +8332AD34 C347 +8332AD35 C348 +8332AD36 C349 +8332AD37 C34A +8332AD38 C34B +8332AD39 C34C +8332AE30 C34D +8332AE31 C34E +8332AE32 C34F +8332AE33 C350 +8332AE34 C351 +8332AE35 C352 +8332AE36 C353 +8332AE37 C354 +8332AE38 C355 +8332AE39 C356 +8332AF30 C357 +8332AF31 C358 +8332AF32 C359 +8332AF33 C35A +8332AF34 C35B +8332AF35 C35C +8332AF36 C35D +8332AF37 C35E +8332AF38 C35F +8332AF39 C360 +8332B030 C361 +8332B031 C362 +8332B032 C363 +8332B033 C364 +8332B034 C365 +8332B035 C366 +8332B036 C367 +8332B037 C368 +8332B038 C369 +8332B039 C36A +8332B130 C36B +8332B131 C36C +8332B132 C36D +8332B133 C36E +8332B134 C36F +8332B135 C370 +8332B136 C371 +8332B137 C372 +8332B138 C373 +8332B139 C374 +8332B230 C375 +8332B231 C376 +8332B232 C377 +8332B233 C378 +8332B234 C379 +8332B235 C37A +8332B236 C37B +8332B237 C37C +8332B238 C37D +8332B239 C37E +8332B330 C37F +8332B331 C380 +8332B332 C381 +8332B333 C382 +8332B334 C383 +8332B335 C384 +8332B336 C385 +8332B337 C386 +8332B338 C387 +8332B339 C388 +8332B430 C389 +8332B431 C38A +8332B432 C38B +8332B433 C38C +8332B434 C38D +8332B435 C38E +8332B436 C38F +8332B437 C390 +8332B438 C391 +8332B439 C392 +8332B530 C393 +8332B531 C394 +8332B532 C395 +8332B533 C396 +8332B534 C397 +8332B535 C398 +8332B536 C399 +8332B537 C39A +8332B538 C39B +8332B539 C39C +8332B630 C39D +8332B631 C39E +8332B632 C39F +8332B633 C3A0 +8332B634 C3A1 +8332B635 C3A2 +8332B636 C3A3 +8332B637 C3A4 +8332B638 C3A5 +8332B639 C3A6 +8332B730 C3A7 +8332B731 C3A8 +8332B732 C3A9 +8332B733 C3AA +8332B734 C3AB +8332B735 C3AC +8332B736 C3AD +8332B737 C3AE +8332B738 C3AF +8332B739 C3B0 +8332B830 C3B1 +8332B831 C3B2 +8332B832 C3B3 +8332B833 C3B4 +8332B834 C3B5 +8332B835 C3B6 +8332B836 C3B7 +8332B837 C3B8 +8332B838 C3B9 +8332B839 C3BA +8332B930 C3BB +8332B931 C3BC +8332B932 C3BD +8332B933 C3BE +8332B934 C3BF +8332B935 C3C0 +8332B936 C3C1 +8332B937 C3C2 +8332B938 C3C3 +8332B939 C3C4 +8332BA30 C3C5 +8332BA31 C3C6 +8332BA32 C3C7 +8332BA33 C3C8 +8332BA34 C3C9 +8332BA35 C3CA +8332BA36 C3CB +8332BA37 C3CC +8332BA38 C3CD +8332BA39 C3CE +8332BB30 C3CF +8332BB31 C3D0 +8332BB32 C3D1 +8332BB33 C3D2 +8332BB34 C3D3 +8332BB35 C3D4 +8332BB36 C3D5 +8332BB37 C3D6 +8332BB38 C3D7 +8332BB39 C3D8 +8332BC30 C3D9 +8332BC31 C3DA +8332BC32 C3DB +8332BC33 C3DC +8332BC34 C3DD +8332BC35 C3DE +8332BC36 C3DF +8332BC37 C3E0 +8332BC38 C3E1 +8332BC39 C3E2 +8332BD30 C3E3 +8332BD31 C3E4 +8332BD32 C3E5 +8332BD33 C3E6 +8332BD34 C3E7 +8332BD35 C3E8 +8332BD36 C3E9 +8332BD37 C3EA +8332BD38 C3EB +8332BD39 C3EC +8332BE30 C3ED +8332BE31 C3EE +8332BE32 C3EF +8332BE33 C3F0 +8332BE34 C3F1 +8332BE35 C3F2 +8332BE36 C3F3 +8332BE37 C3F4 +8332BE38 C3F5 +8332BE39 C3F6 +8332BF30 C3F7 +8332BF31 C3F8 +8332BF32 C3F9 +8332BF33 C3FA +8332BF34 C3FB +8332BF35 C3FC +8332BF36 C3FD +8332BF37 C3FE +8332BF38 C3FF +8332BF39 C400 +8332C030 C401 +8332C031 C402 +8332C032 C403 +8332C033 C404 +8332C034 C405 +8332C035 C406 +8332C036 C407 +8332C037 C408 +8332C038 C409 +8332C039 C40A +8332C130 C40B +8332C131 C40C +8332C132 C40D +8332C133 C40E +8332C134 C40F +8332C135 C410 +8332C136 C411 +8332C137 C412 +8332C138 C413 +8332C139 C414 +8332C230 C415 +8332C231 C416 +8332C232 C417 +8332C233 C418 +8332C234 C419 +8332C235 C41A +8332C236 C41B +8332C237 C41C +8332C238 C41D +8332C239 C41E +8332C330 C41F +8332C331 C420 +8332C332 C421 +8332C333 C422 +8332C334 C423 +8332C335 C424 +8332C336 C425 +8332C337 C426 +8332C338 C427 +8332C339 C428 +8332C430 C429 +8332C431 C42A +8332C432 C42B +8332C433 C42C +8332C434 C42D +8332C435 C42E +8332C436 C42F +8332C437 C430 +8332C438 C431 +8332C439 C432 +8332C530 C433 +8332C531 C434 +8332C532 C435 +8332C533 C436 +8332C534 C437 +8332C535 C438 +8332C536 C439 +8332C537 C43A +8332C538 C43B +8332C539 C43C +8332C630 C43D +8332C631 C43E +8332C632 C43F +8332C633 C440 +8332C634 C441 +8332C635 C442 +8332C636 C443 +8332C637 C444 +8332C638 C445 +8332C639 C446 +8332C730 C447 +8332C731 C448 +8332C732 C449 +8332C733 C44A +8332C734 C44B +8332C735 C44C +8332C736 C44D +8332C737 C44E +8332C738 C44F +8332C739 C450 +8332C830 C451 +8332C831 C452 +8332C832 C453 +8332C833 C454 +8332C834 C455 +8332C835 C456 +8332C836 C457 +8332C837 C458 +8332C838 C459 +8332C839 C45A +8332C930 C45B +8332C931 C45C +8332C932 C45D +8332C933 C45E +8332C934 C45F +8332C935 C460 +8332C936 C461 +8332C937 C462 +8332C938 C463 +8332C939 C464 +8332CA30 C465 +8332CA31 C466 +8332CA32 C467 +8332CA33 C468 +8332CA34 C469 +8332CA35 C46A +8332CA36 C46B +8332CA37 C46C +8332CA38 C46D +8332CA39 C46E +8332CB30 C46F +8332CB31 C470 +8332CB32 C471 +8332CB33 C472 +8332CB34 C473 +8332CB35 C474 +8332CB36 C475 +8332CB37 C476 +8332CB38 C477 +8332CB39 C478 +8332CC30 C479 +8332CC31 C47A +8332CC32 C47B +8332CC33 C47C +8332CC34 C47D +8332CC35 C47E +8332CC36 C47F +8332CC37 C480 +8332CC38 C481 +8332CC39 C482 +8332CD30 C483 +8332CD31 C484 +8332CD32 C485 +8332CD33 C486 +8332CD34 C487 +8332CD35 C488 +8332CD36 C489 +8332CD37 C48A +8332CD38 C48B +8332CD39 C48C +8332CE30 C48D +8332CE31 C48E +8332CE32 C48F +8332CE33 C490 +8332CE34 C491 +8332CE35 C492 +8332CE36 C493 +8332CE37 C494 +8332CE38 C495 +8332CE39 C496 +8332CF30 C497 +8332CF31 C498 +8332CF32 C499 +8332CF33 C49A +8332CF34 C49B +8332CF35 C49C +8332CF36 C49D +8332CF37 C49E +8332CF38 C49F +8332CF39 C4A0 +8332D030 C4A1 +8332D031 C4A2 +8332D032 C4A3 +8332D033 C4A4 +8332D034 C4A5 +8332D035 C4A6 +8332D036 C4A7 +8332D037 C4A8 +8332D038 C4A9 +8332D039 C4AA +8332D130 C4AB +8332D131 C4AC +8332D132 C4AD +8332D133 C4AE +8332D134 C4AF +8332D135 C4B0 +8332D136 C4B1 +8332D137 C4B2 +8332D138 C4B3 +8332D139 C4B4 +8332D230 C4B5 +8332D231 C4B6 +8332D232 C4B7 +8332D233 C4B8 +8332D234 C4B9 +8332D235 C4BA +8332D236 C4BB +8332D237 C4BC +8332D238 C4BD +8332D239 C4BE +8332D330 C4BF +8332D331 C4C0 +8332D332 C4C1 +8332D333 C4C2 +8332D334 C4C3 +8332D335 C4C4 +8332D336 C4C5 +8332D337 C4C6 +8332D338 C4C7 +8332D339 C4C8 +8332D430 C4C9 +8332D431 C4CA +8332D432 C4CB +8332D433 C4CC +8332D434 C4CD +8332D435 C4CE +8332D436 C4CF +8332D437 C4D0 +8332D438 C4D1 +8332D439 C4D2 +8332D530 C4D3 +8332D531 C4D4 +8332D532 C4D5 +8332D533 C4D6 +8332D534 C4D7 +8332D535 C4D8 +8332D536 C4D9 +8332D537 C4DA +8332D538 C4DB +8332D539 C4DC +8332D630 C4DD +8332D631 C4DE +8332D632 C4DF +8332D633 C4E0 +8332D634 C4E1 +8332D635 C4E2 +8332D636 C4E3 +8332D637 C4E4 +8332D638 C4E5 +8332D639 C4E6 +8332D730 C4E7 +8332D731 C4E8 +8332D732 C4E9 +8332D733 C4EA +8332D734 C4EB +8332D735 C4EC +8332D736 C4ED +8332D737 C4EE +8332D738 C4EF +8332D739 C4F0 +8332D830 C4F1 +8332D831 C4F2 +8332D832 C4F3 +8332D833 C4F4 +8332D834 C4F5 +8332D835 C4F6 +8332D836 C4F7 +8332D837 C4F8 +8332D838 C4F9 +8332D839 C4FA +8332D930 C4FB +8332D931 C4FC +8332D932 C4FD +8332D933 C4FE +8332D934 C4FF +8332D935 C500 +8332D936 C501 +8332D937 C502 +8332D938 C503 +8332D939 C504 +8332DA30 C505 +8332DA31 C506 +8332DA32 C507 +8332DA33 C508 +8332DA34 C509 +8332DA35 C50A +8332DA36 C50B +8332DA37 C50C +8332DA38 C50D +8332DA39 C50E +8332DB30 C50F +8332DB31 C510 +8332DB32 C511 +8332DB33 C512 +8332DB34 C513 +8332DB35 C514 +8332DB36 C515 +8332DB37 C516 +8332DB38 C517 +8332DB39 C518 +8332DC30 C519 +8332DC31 C51A +8332DC32 C51B +8332DC33 C51C +8332DC34 C51D +8332DC35 C51E +8332DC36 C51F +8332DC37 C520 +8332DC38 C521 +8332DC39 C522 +8332DD30 C523 +8332DD31 C524 +8332DD32 C525 +8332DD33 C526 +8332DD34 C527 +8332DD35 C528 +8332DD36 C529 +8332DD37 C52A +8332DD38 C52B +8332DD39 C52C +8332DE30 C52D +8332DE31 C52E +8332DE32 C52F +8332DE33 C530 +8332DE34 C531 +8332DE35 C532 +8332DE36 C533 +8332DE37 C534 +8332DE38 C535 +8332DE39 C536 +8332DF30 C537 +8332DF31 C538 +8332DF32 C539 +8332DF33 C53A +8332DF34 C53B +8332DF35 C53C +8332DF36 C53D +8332DF37 C53E +8332DF38 C53F +8332DF39 C540 +8332E030 C541 +8332E031 C542 +8332E032 C543 +8332E033 C544 +8332E034 C545 +8332E035 C546 +8332E036 C547 +8332E037 C548 +8332E038 C549 +8332E039 C54A +8332E130 C54B +8332E131 C54C +8332E132 C54D +8332E133 C54E +8332E134 C54F +8332E135 C550 +8332E136 C551 +8332E137 C552 +8332E138 C553 +8332E139 C554 +8332E230 C555 +8332E231 C556 +8332E232 C557 +8332E233 C558 +8332E234 C559 +8332E235 C55A +8332E236 C55B +8332E237 C55C +8332E238 C55D +8332E239 C55E +8332E330 C55F +8332E331 C560 +8332E332 C561 +8332E333 C562 +8332E334 C563 +8332E335 C564 +8332E336 C565 +8332E337 C566 +8332E338 C567 +8332E339 C568 +8332E430 C569 +8332E431 C56A +8332E432 C56B +8332E433 C56C +8332E434 C56D +8332E435 C56E +8332E436 C56F +8332E437 C570 +8332E438 C571 +8332E439 C572 +8332E530 C573 +8332E531 C574 +8332E532 C575 +8332E533 C576 +8332E534 C577 +8332E535 C578 +8332E536 C579 +8332E537 C57A +8332E538 C57B +8332E539 C57C +8332E630 C57D +8332E631 C57E +8332E632 C57F +8332E633 C580 +8332E634 C581 +8332E635 C582 +8332E636 C583 +8332E637 C584 +8332E638 C585 +8332E639 C586 +8332E730 C587 +8332E731 C588 +8332E732 C589 +8332E733 C58A +8332E734 C58B +8332E735 C58C +8332E736 C58D +8332E737 C58E +8332E738 C58F +8332E739 C590 +8332E830 C591 +8332E831 C592 +8332E832 C593 +8332E833 C594 +8332E834 C595 +8332E835 C596 +8332E836 C597 +8332E837 C598 +8332E838 C599 +8332E839 C59A +8332E930 C59B +8332E931 C59C +8332E932 C59D +8332E933 C59E +8332E934 C59F +8332E935 C5A0 +8332E936 C5A1 +8332E937 C5A2 +8332E938 C5A3 +8332E939 C5A4 +8332EA30 C5A5 +8332EA31 C5A6 +8332EA32 C5A7 +8332EA33 C5A8 +8332EA34 C5A9 +8332EA35 C5AA +8332EA36 C5AB +8332EA37 C5AC +8332EA38 C5AD +8332EA39 C5AE +8332EB30 C5AF +8332EB31 C5B0 +8332EB32 C5B1 +8332EB33 C5B2 +8332EB34 C5B3 +8332EB35 C5B4 +8332EB36 C5B5 +8332EB37 C5B6 +8332EB38 C5B7 +8332EB39 C5B8 +8332EC30 C5B9 +8332EC31 C5BA +8332EC32 C5BB +8332EC33 C5BC +8332EC34 C5BD +8332EC35 C5BE +8332EC36 C5BF +8332EC37 C5C0 +8332EC38 C5C1 +8332EC39 C5C2 +8332ED30 C5C3 +8332ED31 C5C4 +8332ED32 C5C5 +8332ED33 C5C6 +8332ED34 C5C7 +8332ED35 C5C8 +8332ED36 C5C9 +8332ED37 C5CA +8332ED38 C5CB +8332ED39 C5CC +8332EE30 C5CD +8332EE31 C5CE +8332EE32 C5CF +8332EE33 C5D0 +8332EE34 C5D1 +8332EE35 C5D2 +8332EE36 C5D3 +8332EE37 C5D4 +8332EE38 C5D5 +8332EE39 C5D6 +8332EF30 C5D7 +8332EF31 C5D8 +8332EF32 C5D9 +8332EF33 C5DA +8332EF34 C5DB +8332EF35 C5DC +8332EF36 C5DD +8332EF37 C5DE +8332EF38 C5DF +8332EF39 C5E0 +8332F030 C5E1 +8332F031 C5E2 +8332F032 C5E3 +8332F033 C5E4 +8332F034 C5E5 +8332F035 C5E6 +8332F036 C5E7 +8332F037 C5E8 +8332F038 C5E9 +8332F039 C5EA +8332F130 C5EB +8332F131 C5EC +8332F132 C5ED +8332F133 C5EE +8332F134 C5EF +8332F135 C5F0 +8332F136 C5F1 +8332F137 C5F2 +8332F138 C5F3 +8332F139 C5F4 +8332F230 C5F5 +8332F231 C5F6 +8332F232 C5F7 +8332F233 C5F8 +8332F234 C5F9 +8332F235 C5FA +8332F236 C5FB +8332F237 C5FC +8332F238 C5FD +8332F239 C5FE +8332F330 C5FF +8332F331 C600 +8332F332 C601 +8332F333 C602 +8332F334 C603 +8332F335 C604 +8332F336 C605 +8332F337 C606 +8332F338 C607 +8332F339 C608 +8332F430 C609 +8332F431 C60A +8332F432 C60B +8332F433 C60C +8332F434 C60D +8332F435 C60E +8332F436 C60F +8332F437 C610 +8332F438 C611 +8332F439 C612 +8332F530 C613 +8332F531 C614 +8332F532 C615 +8332F533 C616 +8332F534 C617 +8332F535 C618 +8332F536 C619 +8332F537 C61A +8332F538 C61B +8332F539 C61C +8332F630 C61D +8332F631 C61E +8332F632 C61F +8332F633 C620 +8332F634 C621 +8332F635 C622 +8332F636 C623 +8332F637 C624 +8332F638 C625 +8332F639 C626 +8332F730 C627 +8332F731 C628 +8332F732 C629 +8332F733 C62A +8332F734 C62B +8332F735 C62C +8332F736 C62D +8332F737 C62E +8332F738 C62F +8332F739 C630 +8332F830 C631 +8332F831 C632 +8332F832 C633 +8332F833 C634 +8332F834 C635 +8332F835 C636 +8332F836 C637 +8332F837 C638 +8332F838 C639 +8332F839 C63A +8332F930 C63B +8332F931 C63C +8332F932 C63D +8332F933 C63E +8332F934 C63F +8332F935 C640 +8332F936 C641 +8332F937 C642 +8332F938 C643 +8332F939 C644 +8332FA30 C645 +8332FA31 C646 +8332FA32 C647 +8332FA33 C648 +8332FA34 C649 +8332FA35 C64A +8332FA36 C64B +8332FA37 C64C +8332FA38 C64D +8332FA39 C64E +8332FB30 C64F +8332FB31 C650 +8332FB32 C651 +8332FB33 C652 +8332FB34 C653 +8332FB35 C654 +8332FB36 C655 +8332FB37 C656 +8332FB38 C657 +8332FB39 C658 +8332FC30 C659 +8332FC31 C65A +8332FC32 C65B +8332FC33 C65C +8332FC34 C65D +8332FC35 C65E +8332FC36 C65F +8332FC37 C660 +8332FC38 C661 +8332FC39 C662 +8332FD30 C663 +8332FD31 C664 +8332FD32 C665 +8332FD33 C666 +8332FD34 C667 +8332FD35 C668 +8332FD36 C669 +8332FD37 C66A +8332FD38 C66B +8332FD39 C66C +8332FE30 C66D +8332FE31 C66E +8332FE32 C66F +8332FE33 C670 +8332FE34 C671 +8332FE35 C672 +8332FE36 C673 +8332FE37 C674 +8332FE38 C675 +8332FE39 C676 +83338130 C677 +83338131 C678 +83338132 C679 +83338133 C67A +83338134 C67B +83338135 C67C +83338136 C67D +83338137 C67E +83338138 C67F +83338139 C680 +83338230 C681 +83338231 C682 +83338232 C683 +83338233 C684 +83338234 C685 +83338235 C686 +83338236 C687 +83338237 C688 +83338238 C689 +83338239 C68A +83338330 C68B +83338331 C68C +83338332 C68D +83338333 C68E +83338334 C68F +83338335 C690 +83338336 C691 +83338337 C692 +83338338 C693 +83338339 C694 +83338430 C695 +83338431 C696 +83338432 C697 +83338433 C698 +83338434 C699 +83338435 C69A +83338436 C69B +83338437 C69C +83338438 C69D +83338439 C69E +83338530 C69F +83338531 C6A0 +83338532 C6A1 +83338533 C6A2 +83338534 C6A3 +83338535 C6A4 +83338536 C6A5 +83338537 C6A6 +83338538 C6A7 +83338539 C6A8 +83338630 C6A9 +83338631 C6AA +83338632 C6AB +83338633 C6AC +83338634 C6AD +83338635 C6AE +83338636 C6AF +83338637 C6B0 +83338638 C6B1 +83338639 C6B2 +83338730 C6B3 +83338731 C6B4 +83338732 C6B5 +83338733 C6B6 +83338734 C6B7 +83338735 C6B8 +83338736 C6B9 +83338737 C6BA +83338738 C6BB +83338739 C6BC +83338830 C6BD +83338831 C6BE +83338832 C6BF +83338833 C6C0 +83338834 C6C1 +83338835 C6C2 +83338836 C6C3 +83338837 C6C4 +83338838 C6C5 +83338839 C6C6 +83338930 C6C7 +83338931 C6C8 +83338932 C6C9 +83338933 C6CA +83338934 C6CB +83338935 C6CC +83338936 C6CD +83338937 C6CE +83338938 C6CF +83338939 C6D0 +83338A30 C6D1 +83338A31 C6D2 +83338A32 C6D3 +83338A33 C6D4 +83338A34 C6D5 +83338A35 C6D6 +83338A36 C6D7 +83338A37 C6D8 +83338A38 C6D9 +83338A39 C6DA +83338B30 C6DB +83338B31 C6DC +83338B32 C6DD +83338B33 C6DE +83338B34 C6DF +83338B35 C6E0 +83338B36 C6E1 +83338B37 C6E2 +83338B38 C6E3 +83338B39 C6E4 +83338C30 C6E5 +83338C31 C6E6 +83338C32 C6E7 +83338C33 C6E8 +83338C34 C6E9 +83338C35 C6EA +83338C36 C6EB +83338C37 C6EC +83338C38 C6ED +83338C39 C6EE +83338D30 C6EF +83338D31 C6F0 +83338D32 C6F1 +83338D33 C6F2 +83338D34 C6F3 +83338D35 C6F4 +83338D36 C6F5 +83338D37 C6F6 +83338D38 C6F7 +83338D39 C6F8 +83338E30 C6F9 +83338E31 C6FA +83338E32 C6FB +83338E33 C6FC +83338E34 C6FD +83338E35 C6FE +83338E36 C6FF +83338E37 C700 +83338E38 C701 +83338E39 C702 +83338F30 C703 +83338F31 C704 +83338F32 C705 +83338F33 C706 +83338F34 C707 +83338F35 C708 +83338F36 C709 +83338F37 C70A +83338F38 C70B +83338F39 C70C +83339030 C70D +83339031 C70E +83339032 C70F +83339033 C710 +83339034 C711 +83339035 C712 +83339036 C713 +83339037 C714 +83339038 C715 +83339039 C716 +83339130 C717 +83339131 C718 +83339132 C719 +83339133 C71A +83339134 C71B +83339135 C71C +83339136 C71D +83339137 C71E +83339138 C71F +83339139 C720 +83339230 C721 +83339231 C722 +83339232 C723 +83339233 C724 +83339234 C725 +83339235 C726 +83339236 C727 +83339237 C728 +83339238 C729 +83339239 C72A +83339330 C72B +83339331 C72C +83339332 C72D +83339333 C72E +83339334 C72F +83339335 C730 +83339336 C731 +83339337 C732 +83339338 C733 +83339339 C734 +83339430 C735 +83339431 C736 +83339432 C737 +83339433 C738 +83339434 C739 +83339435 C73A +83339436 C73B +83339437 C73C +83339438 C73D +83339439 C73E +83339530 C73F +83339531 C740 +83339532 C741 +83339533 C742 +83339534 C743 +83339535 C744 +83339536 C745 +83339537 C746 +83339538 C747 +83339539 C748 +83339630 C749 +83339631 C74A +83339632 C74B +83339633 C74C +83339634 C74D +83339635 C74E +83339636 C74F +83339637 C750 +83339638 C751 +83339639 C752 +83339730 C753 +83339731 C754 +83339732 C755 +83339733 C756 +83339734 C757 +83339735 C758 +83339736 C759 +83339737 C75A +83339738 C75B +83339739 C75C +83339830 C75D +83339831 C75E +83339832 C75F +83339833 C760 +83339834 C761 +83339835 C762 +83339836 C763 +83339837 C764 +83339838 C765 +83339839 C766 +83339930 C767 +83339931 C768 +83339932 C769 +83339933 C76A +83339934 C76B +83339935 C76C +83339936 C76D +83339937 C76E +83339938 C76F +83339939 C770 +83339A30 C771 +83339A31 C772 +83339A32 C773 +83339A33 C774 +83339A34 C775 +83339A35 C776 +83339A36 C777 +83339A37 C778 +83339A38 C779 +83339A39 C77A +83339B30 C77B +83339B31 C77C +83339B32 C77D +83339B33 C77E +83339B34 C77F +83339B35 C780 +83339B36 C781 +83339B37 C782 +83339B38 C783 +83339B39 C784 +83339C30 C785 +83339C31 C786 +83339C32 C787 +83339C33 C788 +83339C34 C789 +83339C35 C78A +83339C36 C78B +83339C37 C78C +83339C38 C78D +83339C39 C78E +83339D30 C78F +83339D31 C790 +83339D32 C791 +83339D33 C792 +83339D34 C793 +83339D35 C794 +83339D36 C795 +83339D37 C796 +83339D38 C797 +83339D39 C798 +83339E30 C799 +83339E31 C79A +83339E32 C79B +83339E33 C79C +83339E34 C79D +83339E35 C79E +83339E36 C79F +83339E37 C7A0 +83339E38 C7A1 +83339E39 C7A2 +83339F30 C7A3 +83339F31 C7A4 +83339F32 C7A5 +83339F33 C7A6 +83339F34 C7A7 +83339F35 C7A8 +83339F36 C7A9 +83339F37 C7AA +83339F38 C7AB +83339F39 C7AC +8333A030 C7AD +8333A031 C7AE +8333A032 C7AF +8333A033 C7B0 +8333A034 C7B1 +8333A035 C7B2 +8333A036 C7B3 +8333A037 C7B4 +8333A038 C7B5 +8333A039 C7B6 +8333A130 C7B7 +8333A131 C7B8 +8333A132 C7B9 +8333A133 C7BA +8333A134 C7BB +8333A135 C7BC +8333A136 C7BD +8333A137 C7BE +8333A138 C7BF +8333A139 C7C0 +8333A230 C7C1 +8333A231 C7C2 +8333A232 C7C3 +8333A233 C7C4 +8333A234 C7C5 +8333A235 C7C6 +8333A236 C7C7 +8333A237 C7C8 +8333A238 C7C9 +8333A239 C7CA +8333A330 C7CB +8333A331 C7CC +8333A332 C7CD +8333A333 C7CE +8333A334 C7CF +8333A335 C7D0 +8333A336 C7D1 +8333A337 C7D2 +8333A338 C7D3 +8333A339 C7D4 +8333A430 C7D5 +8333A431 C7D6 +8333A432 C7D7 +8333A433 C7D8 +8333A434 C7D9 +8333A435 C7DA +8333A436 C7DB +8333A437 C7DC +8333A438 C7DD +8333A439 C7DE +8333A530 C7DF +8333A531 C7E0 +8333A532 C7E1 +8333A533 C7E2 +8333A534 C7E3 +8333A535 C7E4 +8333A536 C7E5 +8333A537 C7E6 +8333A538 C7E7 +8333A539 C7E8 +8333A630 C7E9 +8333A631 C7EA +8333A632 C7EB +8333A633 C7EC +8333A634 C7ED +8333A635 C7EE +8333A636 C7EF +8333A637 C7F0 +8333A638 C7F1 +8333A639 C7F2 +8333A730 C7F3 +8333A731 C7F4 +8333A732 C7F5 +8333A733 C7F6 +8333A734 C7F7 +8333A735 C7F8 +8333A736 C7F9 +8333A737 C7FA +8333A738 C7FB +8333A739 C7FC +8333A830 C7FD +8333A831 C7FE +8333A832 C7FF +8333A833 C800 +8333A834 C801 +8333A835 C802 +8333A836 C803 +8333A837 C804 +8333A838 C805 +8333A839 C806 +8333A930 C807 +8333A931 C808 +8333A932 C809 +8333A933 C80A +8333A934 C80B +8333A935 C80C +8333A936 C80D +8333A937 C80E +8333A938 C80F +8333A939 C810 +8333AA30 C811 +8333AA31 C812 +8333AA32 C813 +8333AA33 C814 +8333AA34 C815 +8333AA35 C816 +8333AA36 C817 +8333AA37 C818 +8333AA38 C819 +8333AA39 C81A +8333AB30 C81B +8333AB31 C81C +8333AB32 C81D +8333AB33 C81E +8333AB34 C81F +8333AB35 C820 +8333AB36 C821 +8333AB37 C822 +8333AB38 C823 +8333AB39 C824 +8333AC30 C825 +8333AC31 C826 +8333AC32 C827 +8333AC33 C828 +8333AC34 C829 +8333AC35 C82A +8333AC36 C82B +8333AC37 C82C +8333AC38 C82D +8333AC39 C82E +8333AD30 C82F +8333AD31 C830 +8333AD32 C831 +8333AD33 C832 +8333AD34 C833 +8333AD35 C834 +8333AD36 C835 +8333AD37 C836 +8333AD38 C837 +8333AD39 C838 +8333AE30 C839 +8333AE31 C83A +8333AE32 C83B +8333AE33 C83C +8333AE34 C83D +8333AE35 C83E +8333AE36 C83F +8333AE37 C840 +8333AE38 C841 +8333AE39 C842 +8333AF30 C843 +8333AF31 C844 +8333AF32 C845 +8333AF33 C846 +8333AF34 C847 +8333AF35 C848 +8333AF36 C849 +8333AF37 C84A +8333AF38 C84B +8333AF39 C84C +8333B030 C84D +8333B031 C84E +8333B032 C84F +8333B033 C850 +8333B034 C851 +8333B035 C852 +8333B036 C853 +8333B037 C854 +8333B038 C855 +8333B039 C856 +8333B130 C857 +8333B131 C858 +8333B132 C859 +8333B133 C85A +8333B134 C85B +8333B135 C85C +8333B136 C85D +8333B137 C85E +8333B138 C85F +8333B139 C860 +8333B230 C861 +8333B231 C862 +8333B232 C863 +8333B233 C864 +8333B234 C865 +8333B235 C866 +8333B236 C867 +8333B237 C868 +8333B238 C869 +8333B239 C86A +8333B330 C86B +8333B331 C86C +8333B332 C86D +8333B333 C86E +8333B334 C86F +8333B335 C870 +8333B336 C871 +8333B337 C872 +8333B338 C873 +8333B339 C874 +8333B430 C875 +8333B431 C876 +8333B432 C877 +8333B433 C878 +8333B434 C879 +8333B435 C87A +8333B436 C87B +8333B437 C87C +8333B438 C87D +8333B439 C87E +8333B530 C87F +8333B531 C880 +8333B532 C881 +8333B533 C882 +8333B534 C883 +8333B535 C884 +8333B536 C885 +8333B537 C886 +8333B538 C887 +8333B539 C888 +8333B630 C889 +8333B631 C88A +8333B632 C88B +8333B633 C88C +8333B634 C88D +8333B635 C88E +8333B636 C88F +8333B637 C890 +8333B638 C891 +8333B639 C892 +8333B730 C893 +8333B731 C894 +8333B732 C895 +8333B733 C896 +8333B734 C897 +8333B735 C898 +8333B736 C899 +8333B737 C89A +8333B738 C89B +8333B739 C89C +8333B830 C89D +8333B831 C89E +8333B832 C89F +8333B833 C8A0 +8333B834 C8A1 +8333B835 C8A2 +8333B836 C8A3 +8333B837 C8A4 +8333B838 C8A5 +8333B839 C8A6 +8333B930 C8A7 +8333B931 C8A8 +8333B932 C8A9 +8333B933 C8AA +8333B934 C8AB +8333B935 C8AC +8333B936 C8AD +8333B937 C8AE +8333B938 C8AF +8333B939 C8B0 +8333BA30 C8B1 +8333BA31 C8B2 +8333BA32 C8B3 +8333BA33 C8B4 +8333BA34 C8B5 +8333BA35 C8B6 +8333BA36 C8B7 +8333BA37 C8B8 +8333BA38 C8B9 +8333BA39 C8BA +8333BB30 C8BB +8333BB31 C8BC +8333BB32 C8BD +8333BB33 C8BE +8333BB34 C8BF +8333BB35 C8C0 +8333BB36 C8C1 +8333BB37 C8C2 +8333BB38 C8C3 +8333BB39 C8C4 +8333BC30 C8C5 +8333BC31 C8C6 +8333BC32 C8C7 +8333BC33 C8C8 +8333BC34 C8C9 +8333BC35 C8CA +8333BC36 C8CB +8333BC37 C8CC +8333BC38 C8CD +8333BC39 C8CE +8333BD30 C8CF +8333BD31 C8D0 +8333BD32 C8D1 +8333BD33 C8D2 +8333BD34 C8D3 +8333BD35 C8D4 +8333BD36 C8D5 +8333BD37 C8D6 +8333BD38 C8D7 +8333BD39 C8D8 +8333BE30 C8D9 +8333BE31 C8DA +8333BE32 C8DB +8333BE33 C8DC +8333BE34 C8DD +8333BE35 C8DE +8333BE36 C8DF +8333BE37 C8E0 +8333BE38 C8E1 +8333BE39 C8E2 +8333BF30 C8E3 +8333BF31 C8E4 +8333BF32 C8E5 +8333BF33 C8E6 +8333BF34 C8E7 +8333BF35 C8E8 +8333BF36 C8E9 +8333BF37 C8EA +8333BF38 C8EB +8333BF39 C8EC +8333C030 C8ED +8333C031 C8EE +8333C032 C8EF +8333C033 C8F0 +8333C034 C8F1 +8333C035 C8F2 +8333C036 C8F3 +8333C037 C8F4 +8333C038 C8F5 +8333C039 C8F6 +8333C130 C8F7 +8333C131 C8F8 +8333C132 C8F9 +8333C133 C8FA +8333C134 C8FB +8333C135 C8FC +8333C136 C8FD +8333C137 C8FE +8333C138 C8FF +8333C139 C900 +8333C230 C901 +8333C231 C902 +8333C232 C903 +8333C233 C904 +8333C234 C905 +8333C235 C906 +8333C236 C907 +8333C237 C908 +8333C238 C909 +8333C239 C90A +8333C330 C90B +8333C331 C90C +8333C332 C90D +8333C333 C90E +8333C334 C90F +8333C335 C910 +8333C336 C911 +8333C337 C912 +8333C338 C913 +8333C339 C914 +8333C430 C915 +8333C431 C916 +8333C432 C917 +8333C433 C918 +8333C434 C919 +8333C435 C91A +8333C436 C91B +8333C437 C91C +8333C438 C91D +8333C439 C91E +8333C530 C91F +8333C531 C920 +8333C532 C921 +8333C533 C922 +8333C534 C923 +8333C535 C924 +8333C536 C925 +8333C537 C926 +8333C538 C927 +8333C539 C928 +8333C630 C929 +8333C631 C92A +8333C632 C92B +8333C633 C92C +8333C634 C92D +8333C635 C92E +8333C636 C92F +8333C637 C930 +8333C638 C931 +8333C639 C932 +8333C730 C933 +8333C731 C934 +8333C732 C935 +8333C733 C936 +8333C734 C937 +8333C735 C938 +8333C736 C939 +8333C737 C93A +8333C738 C93B +8333C739 C93C +8333C830 C93D +8333C831 C93E +8333C832 C93F +8333C833 C940 +8333C834 C941 +8333C835 C942 +8333C836 C943 +8333C837 C944 +8333C838 C945 +8333C839 C946 +8333C930 C947 +8333C931 C948 +8333C932 C949 +8333C933 C94A +8333C934 C94B +8333C935 C94C +8333C936 C94D +8333C937 C94E +8333C938 C94F +8333C939 C950 +8333CA30 C951 +8333CA31 C952 +8333CA32 C953 +8333CA33 C954 +8333CA34 C955 +8333CA35 C956 +8333CA36 C957 +8333CA37 C958 +8333CA38 C959 +8333CA39 C95A +8333CB30 C95B +8333CB31 C95C +8333CB32 C95D +8333CB33 C95E +8333CB34 C95F +8333CB35 C960 +8333CB36 C961 +8333CB37 C962 +8333CB38 C963 +8333CB39 C964 +8333CC30 C965 +8333CC31 C966 +8333CC32 C967 +8333CC33 C968 +8333CC34 C969 +8333CC35 C96A +8333CC36 C96B +8333CC37 C96C +8333CC38 C96D +8333CC39 C96E +8333CD30 C96F +8333CD31 C970 +8333CD32 C971 +8333CD33 C972 +8333CD34 C973 +8333CD35 C974 +8333CD36 C975 +8333CD37 C976 +8333CD38 C977 +8333CD39 C978 +8333CE30 C979 +8333CE31 C97A +8333CE32 C97B +8333CE33 C97C +8333CE34 C97D +8333CE35 C97E +8333CE36 C97F +8333CE37 C980 +8333CE38 C981 +8333CE39 C982 +8333CF30 C983 +8333CF31 C984 +8333CF32 C985 +8333CF33 C986 +8333CF34 C987 +8333CF35 C988 +8333CF36 C989 +8333CF37 C98A +8333CF38 C98B +8333CF39 C98C +8333D030 C98D +8333D031 C98E +8333D032 C98F +8333D033 C990 +8333D034 C991 +8333D035 C992 +8333D036 C993 +8333D037 C994 +8333D038 C995 +8333D039 C996 +8333D130 C997 +8333D131 C998 +8333D132 C999 +8333D133 C99A +8333D134 C99B +8333D135 C99C +8333D136 C99D +8333D137 C99E +8333D138 C99F +8333D139 C9A0 +8333D230 C9A1 +8333D231 C9A2 +8333D232 C9A3 +8333D233 C9A4 +8333D234 C9A5 +8333D235 C9A6 +8333D236 C9A7 +8333D237 C9A8 +8333D238 C9A9 +8333D239 C9AA +8333D330 C9AB +8333D331 C9AC +8333D332 C9AD +8333D333 C9AE +8333D334 C9AF +8333D335 C9B0 +8333D336 C9B1 +8333D337 C9B2 +8333D338 C9B3 +8333D339 C9B4 +8333D430 C9B5 +8333D431 C9B6 +8333D432 C9B7 +8333D433 C9B8 +8333D434 C9B9 +8333D435 C9BA +8333D436 C9BB +8333D437 C9BC +8333D438 C9BD +8333D439 C9BE +8333D530 C9BF +8333D531 C9C0 +8333D532 C9C1 +8333D533 C9C2 +8333D534 C9C3 +8333D535 C9C4 +8333D536 C9C5 +8333D537 C9C6 +8333D538 C9C7 +8333D539 C9C8 +8333D630 C9C9 +8333D631 C9CA +8333D632 C9CB +8333D633 C9CC +8333D634 C9CD +8333D635 C9CE +8333D636 C9CF +8333D637 C9D0 +8333D638 C9D1 +8333D639 C9D2 +8333D730 C9D3 +8333D731 C9D4 +8333D732 C9D5 +8333D733 C9D6 +8333D734 C9D7 +8333D735 C9D8 +8333D736 C9D9 +8333D737 C9DA +8333D738 C9DB +8333D739 C9DC +8333D830 C9DD +8333D831 C9DE +8333D832 C9DF +8333D833 C9E0 +8333D834 C9E1 +8333D835 C9E2 +8333D836 C9E3 +8333D837 C9E4 +8333D838 C9E5 +8333D839 C9E6 +8333D930 C9E7 +8333D931 C9E8 +8333D932 C9E9 +8333D933 C9EA +8333D934 C9EB +8333D935 C9EC +8333D936 C9ED +8333D937 C9EE +8333D938 C9EF +8333D939 C9F0 +8333DA30 C9F1 +8333DA31 C9F2 +8333DA32 C9F3 +8333DA33 C9F4 +8333DA34 C9F5 +8333DA35 C9F6 +8333DA36 C9F7 +8333DA37 C9F8 +8333DA38 C9F9 +8333DA39 C9FA +8333DB30 C9FB +8333DB31 C9FC +8333DB32 C9FD +8333DB33 C9FE +8333DB34 C9FF +8333DB35 CA00 +8333DB36 CA01 +8333DB37 CA02 +8333DB38 CA03 +8333DB39 CA04 +8333DC30 CA05 +8333DC31 CA06 +8333DC32 CA07 +8333DC33 CA08 +8333DC34 CA09 +8333DC35 CA0A +8333DC36 CA0B +8333DC37 CA0C +8333DC38 CA0D +8333DC39 CA0E +8333DD30 CA0F +8333DD31 CA10 +8333DD32 CA11 +8333DD33 CA12 +8333DD34 CA13 +8333DD35 CA14 +8333DD36 CA15 +8333DD37 CA16 +8333DD38 CA17 +8333DD39 CA18 +8333DE30 CA19 +8333DE31 CA1A +8333DE32 CA1B +8333DE33 CA1C +8333DE34 CA1D +8333DE35 CA1E +8333DE36 CA1F +8333DE37 CA20 +8333DE38 CA21 +8333DE39 CA22 +8333DF30 CA23 +8333DF31 CA24 +8333DF32 CA25 +8333DF33 CA26 +8333DF34 CA27 +8333DF35 CA28 +8333DF36 CA29 +8333DF37 CA2A +8333DF38 CA2B +8333DF39 CA2C +8333E030 CA2D +8333E031 CA2E +8333E032 CA2F +8333E033 CA30 +8333E034 CA31 +8333E035 CA32 +8333E036 CA33 +8333E037 CA34 +8333E038 CA35 +8333E039 CA36 +8333E130 CA37 +8333E131 CA38 +8333E132 CA39 +8333E133 CA3A +8333E134 CA3B +8333E135 CA3C +8333E136 CA3D +8333E137 CA3E +8333E138 CA3F +8333E139 CA40 +8333E230 CA41 +8333E231 CA42 +8333E232 CA43 +8333E233 CA44 +8333E234 CA45 +8333E235 CA46 +8333E236 CA47 +8333E237 CA48 +8333E238 CA49 +8333E239 CA4A +8333E330 CA4B +8333E331 CA4C +8333E332 CA4D +8333E333 CA4E +8333E334 CA4F +8333E335 CA50 +8333E336 CA51 +8333E337 CA52 +8333E338 CA53 +8333E339 CA54 +8333E430 CA55 +8333E431 CA56 +8333E432 CA57 +8333E433 CA58 +8333E434 CA59 +8333E435 CA5A +8333E436 CA5B +8333E437 CA5C +8333E438 CA5D +8333E439 CA5E +8333E530 CA5F +8333E531 CA60 +8333E532 CA61 +8333E533 CA62 +8333E534 CA63 +8333E535 CA64 +8333E536 CA65 +8333E537 CA66 +8333E538 CA67 +8333E539 CA68 +8333E630 CA69 +8333E631 CA6A +8333E632 CA6B +8333E633 CA6C +8333E634 CA6D +8333E635 CA6E +8333E636 CA6F +8333E637 CA70 +8333E638 CA71 +8333E639 CA72 +8333E730 CA73 +8333E731 CA74 +8333E732 CA75 +8333E733 CA76 +8333E734 CA77 +8333E735 CA78 +8333E736 CA79 +8333E737 CA7A +8333E738 CA7B +8333E739 CA7C +8333E830 CA7D +8333E831 CA7E +8333E832 CA7F +8333E833 CA80 +8333E834 CA81 +8333E835 CA82 +8333E836 CA83 +8333E837 CA84 +8333E838 CA85 +8333E839 CA86 +8333E930 CA87 +8333E931 CA88 +8333E932 CA89 +8333E933 CA8A +8333E934 CA8B +8333E935 CA8C +8333E936 CA8D +8333E937 CA8E +8333E938 CA8F +8333E939 CA90 +8333EA30 CA91 +8333EA31 CA92 +8333EA32 CA93 +8333EA33 CA94 +8333EA34 CA95 +8333EA35 CA96 +8333EA36 CA97 +8333EA37 CA98 +8333EA38 CA99 +8333EA39 CA9A +8333EB30 CA9B +8333EB31 CA9C +8333EB32 CA9D +8333EB33 CA9E +8333EB34 CA9F +8333EB35 CAA0 +8333EB36 CAA1 +8333EB37 CAA2 +8333EB38 CAA3 +8333EB39 CAA4 +8333EC30 CAA5 +8333EC31 CAA6 +8333EC32 CAA7 +8333EC33 CAA8 +8333EC34 CAA9 +8333EC35 CAAA +8333EC36 CAAB +8333EC37 CAAC +8333EC38 CAAD +8333EC39 CAAE +8333ED30 CAAF +8333ED31 CAB0 +8333ED32 CAB1 +8333ED33 CAB2 +8333ED34 CAB3 +8333ED35 CAB4 +8333ED36 CAB5 +8333ED37 CAB6 +8333ED38 CAB7 +8333ED39 CAB8 +8333EE30 CAB9 +8333EE31 CABA +8333EE32 CABB +8333EE33 CABC +8333EE34 CABD +8333EE35 CABE +8333EE36 CABF +8333EE37 CAC0 +8333EE38 CAC1 +8333EE39 CAC2 +8333EF30 CAC3 +8333EF31 CAC4 +8333EF32 CAC5 +8333EF33 CAC6 +8333EF34 CAC7 +8333EF35 CAC8 +8333EF36 CAC9 +8333EF37 CACA +8333EF38 CACB +8333EF39 CACC +8333F030 CACD +8333F031 CACE +8333F032 CACF +8333F033 CAD0 +8333F034 CAD1 +8333F035 CAD2 +8333F036 CAD3 +8333F037 CAD4 +8333F038 CAD5 +8333F039 CAD6 +8333F130 CAD7 +8333F131 CAD8 +8333F132 CAD9 +8333F133 CADA +8333F134 CADB +8333F135 CADC +8333F136 CADD +8333F137 CADE +8333F138 CADF +8333F139 CAE0 +8333F230 CAE1 +8333F231 CAE2 +8333F232 CAE3 +8333F233 CAE4 +8333F234 CAE5 +8333F235 CAE6 +8333F236 CAE7 +8333F237 CAE8 +8333F238 CAE9 +8333F239 CAEA +8333F330 CAEB +8333F331 CAEC +8333F332 CAED +8333F333 CAEE +8333F334 CAEF +8333F335 CAF0 +8333F336 CAF1 +8333F337 CAF2 +8333F338 CAF3 +8333F339 CAF4 +8333F430 CAF5 +8333F431 CAF6 +8333F432 CAF7 +8333F433 CAF8 +8333F434 CAF9 +8333F435 CAFA +8333F436 CAFB +8333F437 CAFC +8333F438 CAFD +8333F439 CAFE +8333F530 CAFF +8333F531 CB00 +8333F532 CB01 +8333F533 CB02 +8333F534 CB03 +8333F535 CB04 +8333F536 CB05 +8333F537 CB06 +8333F538 CB07 +8333F539 CB08 +8333F630 CB09 +8333F631 CB0A +8333F632 CB0B +8333F633 CB0C +8333F634 CB0D +8333F635 CB0E +8333F636 CB0F +8333F637 CB10 +8333F638 CB11 +8333F639 CB12 +8333F730 CB13 +8333F731 CB14 +8333F732 CB15 +8333F733 CB16 +8333F734 CB17 +8333F735 CB18 +8333F736 CB19 +8333F737 CB1A +8333F738 CB1B +8333F739 CB1C +8333F830 CB1D +8333F831 CB1E +8333F832 CB1F +8333F833 CB20 +8333F834 CB21 +8333F835 CB22 +8333F836 CB23 +8333F837 CB24 +8333F838 CB25 +8333F839 CB26 +8333F930 CB27 +8333F931 CB28 +8333F932 CB29 +8333F933 CB2A +8333F934 CB2B +8333F935 CB2C +8333F936 CB2D +8333F937 CB2E +8333F938 CB2F +8333F939 CB30 +8333FA30 CB31 +8333FA31 CB32 +8333FA32 CB33 +8333FA33 CB34 +8333FA34 CB35 +8333FA35 CB36 +8333FA36 CB37 +8333FA37 CB38 +8333FA38 CB39 +8333FA39 CB3A +8333FB30 CB3B +8333FB31 CB3C +8333FB32 CB3D +8333FB33 CB3E +8333FB34 CB3F +8333FB35 CB40 +8333FB36 CB41 +8333FB37 CB42 +8333FB38 CB43 +8333FB39 CB44 +8333FC30 CB45 +8333FC31 CB46 +8333FC32 CB47 +8333FC33 CB48 +8333FC34 CB49 +8333FC35 CB4A +8333FC36 CB4B +8333FC37 CB4C +8333FC38 CB4D +8333FC39 CB4E +8333FD30 CB4F +8333FD31 CB50 +8333FD32 CB51 +8333FD33 CB52 +8333FD34 CB53 +8333FD35 CB54 +8333FD36 CB55 +8333FD37 CB56 +8333FD38 CB57 +8333FD39 CB58 +8333FE30 CB59 +8333FE31 CB5A +8333FE32 CB5B +8333FE33 CB5C +8333FE34 CB5D +8333FE35 CB5E +8333FE36 CB5F +8333FE37 CB60 +8333FE38 CB61 +8333FE39 CB62 +83348130 CB63 +83348131 CB64 +83348132 CB65 +83348133 CB66 +83348134 CB67 +83348135 CB68 +83348136 CB69 +83348137 CB6A +83348138 CB6B +83348139 CB6C +83348230 CB6D +83348231 CB6E +83348232 CB6F +83348233 CB70 +83348234 CB71 +83348235 CB72 +83348236 CB73 +83348237 CB74 +83348238 CB75 +83348239 CB76 +83348330 CB77 +83348331 CB78 +83348332 CB79 +83348333 CB7A +83348334 CB7B +83348335 CB7C +83348336 CB7D +83348337 CB7E +83348338 CB7F +83348339 CB80 +83348430 CB81 +83348431 CB82 +83348432 CB83 +83348433 CB84 +83348434 CB85 +83348435 CB86 +83348436 CB87 +83348437 CB88 +83348438 CB89 +83348439 CB8A +83348530 CB8B +83348531 CB8C +83348532 CB8D +83348533 CB8E +83348534 CB8F +83348535 CB90 +83348536 CB91 +83348537 CB92 +83348538 CB93 +83348539 CB94 +83348630 CB95 +83348631 CB96 +83348632 CB97 +83348633 CB98 +83348634 CB99 +83348635 CB9A +83348636 CB9B +83348637 CB9C +83348638 CB9D +83348639 CB9E +83348730 CB9F +83348731 CBA0 +83348732 CBA1 +83348733 CBA2 +83348734 CBA3 +83348735 CBA4 +83348736 CBA5 +83348737 CBA6 +83348738 CBA7 +83348739 CBA8 +83348830 CBA9 +83348831 CBAA +83348832 CBAB +83348833 CBAC +83348834 CBAD +83348835 CBAE +83348836 CBAF +83348837 CBB0 +83348838 CBB1 +83348839 CBB2 +83348930 CBB3 +83348931 CBB4 +83348932 CBB5 +83348933 CBB6 +83348934 CBB7 +83348935 CBB8 +83348936 CBB9 +83348937 CBBA +83348938 CBBB +83348939 CBBC +83348A30 CBBD +83348A31 CBBE +83348A32 CBBF +83348A33 CBC0 +83348A34 CBC1 +83348A35 CBC2 +83348A36 CBC3 +83348A37 CBC4 +83348A38 CBC5 +83348A39 CBC6 +83348B30 CBC7 +83348B31 CBC8 +83348B32 CBC9 +83348B33 CBCA +83348B34 CBCB +83348B35 CBCC +83348B36 CBCD +83348B37 CBCE +83348B38 CBCF +83348B39 CBD0 +83348C30 CBD1 +83348C31 CBD2 +83348C32 CBD3 +83348C33 CBD4 +83348C34 CBD5 +83348C35 CBD6 +83348C36 CBD7 +83348C37 CBD8 +83348C38 CBD9 +83348C39 CBDA +83348D30 CBDB +83348D31 CBDC +83348D32 CBDD +83348D33 CBDE +83348D34 CBDF +83348D35 CBE0 +83348D36 CBE1 +83348D37 CBE2 +83348D38 CBE3 +83348D39 CBE4 +83348E30 CBE5 +83348E31 CBE6 +83348E32 CBE7 +83348E33 CBE8 +83348E34 CBE9 +83348E35 CBEA +83348E36 CBEB +83348E37 CBEC +83348E38 CBED +83348E39 CBEE +83348F30 CBEF +83348F31 CBF0 +83348F32 CBF1 +83348F33 CBF2 +83348F34 CBF3 +83348F35 CBF4 +83348F36 CBF5 +83348F37 CBF6 +83348F38 CBF7 +83348F39 CBF8 +83349030 CBF9 +83349031 CBFA +83349032 CBFB +83349033 CBFC +83349034 CBFD +83349035 CBFE +83349036 CBFF +83349037 CC00 +83349038 CC01 +83349039 CC02 +83349130 CC03 +83349131 CC04 +83349132 CC05 +83349133 CC06 +83349134 CC07 +83349135 CC08 +83349136 CC09 +83349137 CC0A +83349138 CC0B +83349139 CC0C +83349230 CC0D +83349231 CC0E +83349232 CC0F +83349233 CC10 +83349234 CC11 +83349235 CC12 +83349236 CC13 +83349237 CC14 +83349238 CC15 +83349239 CC16 +83349330 CC17 +83349331 CC18 +83349332 CC19 +83349333 CC1A +83349334 CC1B +83349335 CC1C +83349336 CC1D +83349337 CC1E +83349338 CC1F +83349339 CC20 +83349430 CC21 +83349431 CC22 +83349432 CC23 +83349433 CC24 +83349434 CC25 +83349435 CC26 +83349436 CC27 +83349437 CC28 +83349438 CC29 +83349439 CC2A +83349530 CC2B +83349531 CC2C +83349532 CC2D +83349533 CC2E +83349534 CC2F +83349535 CC30 +83349536 CC31 +83349537 CC32 +83349538 CC33 +83349539 CC34 +83349630 CC35 +83349631 CC36 +83349632 CC37 +83349633 CC38 +83349634 CC39 +83349635 CC3A +83349636 CC3B +83349637 CC3C +83349638 CC3D +83349639 CC3E +83349730 CC3F +83349731 CC40 +83349732 CC41 +83349733 CC42 +83349734 CC43 +83349735 CC44 +83349736 CC45 +83349737 CC46 +83349738 CC47 +83349739 CC48 +83349830 CC49 +83349831 CC4A +83349832 CC4B +83349833 CC4C +83349834 CC4D +83349835 CC4E +83349836 CC4F +83349837 CC50 +83349838 CC51 +83349839 CC52 +83349930 CC53 +83349931 CC54 +83349932 CC55 +83349933 CC56 +83349934 CC57 +83349935 CC58 +83349936 CC59 +83349937 CC5A +83349938 CC5B +83349939 CC5C +83349A30 CC5D +83349A31 CC5E +83349A32 CC5F +83349A33 CC60 +83349A34 CC61 +83349A35 CC62 +83349A36 CC63 +83349A37 CC64 +83349A38 CC65 +83349A39 CC66 +83349B30 CC67 +83349B31 CC68 +83349B32 CC69 +83349B33 CC6A +83349B34 CC6B +83349B35 CC6C +83349B36 CC6D +83349B37 CC6E +83349B38 CC6F +83349B39 CC70 +83349C30 CC71 +83349C31 CC72 +83349C32 CC73 +83349C33 CC74 +83349C34 CC75 +83349C35 CC76 +83349C36 CC77 +83349C37 CC78 +83349C38 CC79 +83349C39 CC7A +83349D30 CC7B +83349D31 CC7C +83349D32 CC7D +83349D33 CC7E +83349D34 CC7F +83349D35 CC80 +83349D36 CC81 +83349D37 CC82 +83349D38 CC83 +83349D39 CC84 +83349E30 CC85 +83349E31 CC86 +83349E32 CC87 +83349E33 CC88 +83349E34 CC89 +83349E35 CC8A +83349E36 CC8B +83349E37 CC8C +83349E38 CC8D +83349E39 CC8E +83349F30 CC8F +83349F31 CC90 +83349F32 CC91 +83349F33 CC92 +83349F34 CC93 +83349F35 CC94 +83349F36 CC95 +83349F37 CC96 +83349F38 CC97 +83349F39 CC98 +8334A030 CC99 +8334A031 CC9A +8334A032 CC9B +8334A033 CC9C +8334A034 CC9D +8334A035 CC9E +8334A036 CC9F +8334A037 CCA0 +8334A038 CCA1 +8334A039 CCA2 +8334A130 CCA3 +8334A131 CCA4 +8334A132 CCA5 +8334A133 CCA6 +8334A134 CCA7 +8334A135 CCA8 +8334A136 CCA9 +8334A137 CCAA +8334A138 CCAB +8334A139 CCAC +8334A230 CCAD +8334A231 CCAE +8334A232 CCAF +8334A233 CCB0 +8334A234 CCB1 +8334A235 CCB2 +8334A236 CCB3 +8334A237 CCB4 +8334A238 CCB5 +8334A239 CCB6 +8334A330 CCB7 +8334A331 CCB8 +8334A332 CCB9 +8334A333 CCBA +8334A334 CCBB +8334A335 CCBC +8334A336 CCBD +8334A337 CCBE +8334A338 CCBF +8334A339 CCC0 +8334A430 CCC1 +8334A431 CCC2 +8334A432 CCC3 +8334A433 CCC4 +8334A434 CCC5 +8334A435 CCC6 +8334A436 CCC7 +8334A437 CCC8 +8334A438 CCC9 +8334A439 CCCA +8334A530 CCCB +8334A531 CCCC +8334A532 CCCD +8334A533 CCCE +8334A534 CCCF +8334A535 CCD0 +8334A536 CCD1 +8334A537 CCD2 +8334A538 CCD3 +8334A539 CCD4 +8334A630 CCD5 +8334A631 CCD6 +8334A632 CCD7 +8334A633 CCD8 +8334A634 CCD9 +8334A635 CCDA +8334A636 CCDB +8334A637 CCDC +8334A638 CCDD +8334A639 CCDE +8334A730 CCDF +8334A731 CCE0 +8334A732 CCE1 +8334A733 CCE2 +8334A734 CCE3 +8334A735 CCE4 +8334A736 CCE5 +8334A737 CCE6 +8334A738 CCE7 +8334A739 CCE8 +8334A830 CCE9 +8334A831 CCEA +8334A832 CCEB +8334A833 CCEC +8334A834 CCED +8334A835 CCEE +8334A836 CCEF +8334A837 CCF0 +8334A838 CCF1 +8334A839 CCF2 +8334A930 CCF3 +8334A931 CCF4 +8334A932 CCF5 +8334A933 CCF6 +8334A934 CCF7 +8334A935 CCF8 +8334A936 CCF9 +8334A937 CCFA +8334A938 CCFB +8334A939 CCFC +8334AA30 CCFD +8334AA31 CCFE +8334AA32 CCFF +8334AA33 CD00 +8334AA34 CD01 +8334AA35 CD02 +8334AA36 CD03 +8334AA37 CD04 +8334AA38 CD05 +8334AA39 CD06 +8334AB30 CD07 +8334AB31 CD08 +8334AB32 CD09 +8334AB33 CD0A +8334AB34 CD0B +8334AB35 CD0C +8334AB36 CD0D +8334AB37 CD0E +8334AB38 CD0F +8334AB39 CD10 +8334AC30 CD11 +8334AC31 CD12 +8334AC32 CD13 +8334AC33 CD14 +8334AC34 CD15 +8334AC35 CD16 +8334AC36 CD17 +8334AC37 CD18 +8334AC38 CD19 +8334AC39 CD1A +8334AD30 CD1B +8334AD31 CD1C +8334AD32 CD1D +8334AD33 CD1E +8334AD34 CD1F +8334AD35 CD20 +8334AD36 CD21 +8334AD37 CD22 +8334AD38 CD23 +8334AD39 CD24 +8334AE30 CD25 +8334AE31 CD26 +8334AE32 CD27 +8334AE33 CD28 +8334AE34 CD29 +8334AE35 CD2A +8334AE36 CD2B +8334AE37 CD2C +8334AE38 CD2D +8334AE39 CD2E +8334AF30 CD2F +8334AF31 CD30 +8334AF32 CD31 +8334AF33 CD32 +8334AF34 CD33 +8334AF35 CD34 +8334AF36 CD35 +8334AF37 CD36 +8334AF38 CD37 +8334AF39 CD38 +8334B030 CD39 +8334B031 CD3A +8334B032 CD3B +8334B033 CD3C +8334B034 CD3D +8334B035 CD3E +8334B036 CD3F +8334B037 CD40 +8334B038 CD41 +8334B039 CD42 +8334B130 CD43 +8334B131 CD44 +8334B132 CD45 +8334B133 CD46 +8334B134 CD47 +8334B135 CD48 +8334B136 CD49 +8334B137 CD4A +8334B138 CD4B +8334B139 CD4C +8334B230 CD4D +8334B231 CD4E +8334B232 CD4F +8334B233 CD50 +8334B234 CD51 +8334B235 CD52 +8334B236 CD53 +8334B237 CD54 +8334B238 CD55 +8334B239 CD56 +8334B330 CD57 +8334B331 CD58 +8334B332 CD59 +8334B333 CD5A +8334B334 CD5B +8334B335 CD5C +8334B336 CD5D +8334B337 CD5E +8334B338 CD5F +8334B339 CD60 +8334B430 CD61 +8334B431 CD62 +8334B432 CD63 +8334B433 CD64 +8334B434 CD65 +8334B435 CD66 +8334B436 CD67 +8334B437 CD68 +8334B438 CD69 +8334B439 CD6A +8334B530 CD6B +8334B531 CD6C +8334B532 CD6D +8334B533 CD6E +8334B534 CD6F +8334B535 CD70 +8334B536 CD71 +8334B537 CD72 +8334B538 CD73 +8334B539 CD74 +8334B630 CD75 +8334B631 CD76 +8334B632 CD77 +8334B633 CD78 +8334B634 CD79 +8334B635 CD7A +8334B636 CD7B +8334B637 CD7C +8334B638 CD7D +8334B639 CD7E +8334B730 CD7F +8334B731 CD80 +8334B732 CD81 +8334B733 CD82 +8334B734 CD83 +8334B735 CD84 +8334B736 CD85 +8334B737 CD86 +8334B738 CD87 +8334B739 CD88 +8334B830 CD89 +8334B831 CD8A +8334B832 CD8B +8334B833 CD8C +8334B834 CD8D +8334B835 CD8E +8334B836 CD8F +8334B837 CD90 +8334B838 CD91 +8334B839 CD92 +8334B930 CD93 +8334B931 CD94 +8334B932 CD95 +8334B933 CD96 +8334B934 CD97 +8334B935 CD98 +8334B936 CD99 +8334B937 CD9A +8334B938 CD9B +8334B939 CD9C +8334BA30 CD9D +8334BA31 CD9E +8334BA32 CD9F +8334BA33 CDA0 +8334BA34 CDA1 +8334BA35 CDA2 +8334BA36 CDA3 +8334BA37 CDA4 +8334BA38 CDA5 +8334BA39 CDA6 +8334BB30 CDA7 +8334BB31 CDA8 +8334BB32 CDA9 +8334BB33 CDAA +8334BB34 CDAB +8334BB35 CDAC +8334BB36 CDAD +8334BB37 CDAE +8334BB38 CDAF +8334BB39 CDB0 +8334BC30 CDB1 +8334BC31 CDB2 +8334BC32 CDB3 +8334BC33 CDB4 +8334BC34 CDB5 +8334BC35 CDB6 +8334BC36 CDB7 +8334BC37 CDB8 +8334BC38 CDB9 +8334BC39 CDBA +8334BD30 CDBB +8334BD31 CDBC +8334BD32 CDBD +8334BD33 CDBE +8334BD34 CDBF +8334BD35 CDC0 +8334BD36 CDC1 +8334BD37 CDC2 +8334BD38 CDC3 +8334BD39 CDC4 +8334BE30 CDC5 +8334BE31 CDC6 +8334BE32 CDC7 +8334BE33 CDC8 +8334BE34 CDC9 +8334BE35 CDCA +8334BE36 CDCB +8334BE37 CDCC +8334BE38 CDCD +8334BE39 CDCE +8334BF30 CDCF +8334BF31 CDD0 +8334BF32 CDD1 +8334BF33 CDD2 +8334BF34 CDD3 +8334BF35 CDD4 +8334BF36 CDD5 +8334BF37 CDD6 +8334BF38 CDD7 +8334BF39 CDD8 +8334C030 CDD9 +8334C031 CDDA +8334C032 CDDB +8334C033 CDDC +8334C034 CDDD +8334C035 CDDE +8334C036 CDDF +8334C037 CDE0 +8334C038 CDE1 +8334C039 CDE2 +8334C130 CDE3 +8334C131 CDE4 +8334C132 CDE5 +8334C133 CDE6 +8334C134 CDE7 +8334C135 CDE8 +8334C136 CDE9 +8334C137 CDEA +8334C138 CDEB +8334C139 CDEC +8334C230 CDED +8334C231 CDEE +8334C232 CDEF +8334C233 CDF0 +8334C234 CDF1 +8334C235 CDF2 +8334C236 CDF3 +8334C237 CDF4 +8334C238 CDF5 +8334C239 CDF6 +8334C330 CDF7 +8334C331 CDF8 +8334C332 CDF9 +8334C333 CDFA +8334C334 CDFB +8334C335 CDFC +8334C336 CDFD +8334C337 CDFE +8334C338 CDFF +8334C339 CE00 +8334C430 CE01 +8334C431 CE02 +8334C432 CE03 +8334C433 CE04 +8334C434 CE05 +8334C435 CE06 +8334C436 CE07 +8334C437 CE08 +8334C438 CE09 +8334C439 CE0A +8334C530 CE0B +8334C531 CE0C +8334C532 CE0D +8334C533 CE0E +8334C534 CE0F +8334C535 CE10 +8334C536 CE11 +8334C537 CE12 +8334C538 CE13 +8334C539 CE14 +8334C630 CE15 +8334C631 CE16 +8334C632 CE17 +8334C633 CE18 +8334C634 CE19 +8334C635 CE1A +8334C636 CE1B +8334C637 CE1C +8334C638 CE1D +8334C639 CE1E +8334C730 CE1F +8334C731 CE20 +8334C732 CE21 +8334C733 CE22 +8334C734 CE23 +8334C735 CE24 +8334C736 CE25 +8334C737 CE26 +8334C738 CE27 +8334C739 CE28 +8334C830 CE29 +8334C831 CE2A +8334C832 CE2B +8334C833 CE2C +8334C834 CE2D +8334C835 CE2E +8334C836 CE2F +8334C837 CE30 +8334C838 CE31 +8334C839 CE32 +8334C930 CE33 +8334C931 CE34 +8334C932 CE35 +8334C933 CE36 +8334C934 CE37 +8334C935 CE38 +8334C936 CE39 +8334C937 CE3A +8334C938 CE3B +8334C939 CE3C +8334CA30 CE3D +8334CA31 CE3E +8334CA32 CE3F +8334CA33 CE40 +8334CA34 CE41 +8334CA35 CE42 +8334CA36 CE43 +8334CA37 CE44 +8334CA38 CE45 +8334CA39 CE46 +8334CB30 CE47 +8334CB31 CE48 +8334CB32 CE49 +8334CB33 CE4A +8334CB34 CE4B +8334CB35 CE4C +8334CB36 CE4D +8334CB37 CE4E +8334CB38 CE4F +8334CB39 CE50 +8334CC30 CE51 +8334CC31 CE52 +8334CC32 CE53 +8334CC33 CE54 +8334CC34 CE55 +8334CC35 CE56 +8334CC36 CE57 +8334CC37 CE58 +8334CC38 CE59 +8334CC39 CE5A +8334CD30 CE5B +8334CD31 CE5C +8334CD32 CE5D +8334CD33 CE5E +8334CD34 CE5F +8334CD35 CE60 +8334CD36 CE61 +8334CD37 CE62 +8334CD38 CE63 +8334CD39 CE64 +8334CE30 CE65 +8334CE31 CE66 +8334CE32 CE67 +8334CE33 CE68 +8334CE34 CE69 +8334CE35 CE6A +8334CE36 CE6B +8334CE37 CE6C +8334CE38 CE6D +8334CE39 CE6E +8334CF30 CE6F +8334CF31 CE70 +8334CF32 CE71 +8334CF33 CE72 +8334CF34 CE73 +8334CF35 CE74 +8334CF36 CE75 +8334CF37 CE76 +8334CF38 CE77 +8334CF39 CE78 +8334D030 CE79 +8334D031 CE7A +8334D032 CE7B +8334D033 CE7C +8334D034 CE7D +8334D035 CE7E +8334D036 CE7F +8334D037 CE80 +8334D038 CE81 +8334D039 CE82 +8334D130 CE83 +8334D131 CE84 +8334D132 CE85 +8334D133 CE86 +8334D134 CE87 +8334D135 CE88 +8334D136 CE89 +8334D137 CE8A +8334D138 CE8B +8334D139 CE8C +8334D230 CE8D +8334D231 CE8E +8334D232 CE8F +8334D233 CE90 +8334D234 CE91 +8334D235 CE92 +8334D236 CE93 +8334D237 CE94 +8334D238 CE95 +8334D239 CE96 +8334D330 CE97 +8334D331 CE98 +8334D332 CE99 +8334D333 CE9A +8334D334 CE9B +8334D335 CE9C +8334D336 CE9D +8334D337 CE9E +8334D338 CE9F +8334D339 CEA0 +8334D430 CEA1 +8334D431 CEA2 +8334D432 CEA3 +8334D433 CEA4 +8334D434 CEA5 +8334D435 CEA6 +8334D436 CEA7 +8334D437 CEA8 +8334D438 CEA9 +8334D439 CEAA +8334D530 CEAB +8334D531 CEAC +8334D532 CEAD +8334D533 CEAE +8334D534 CEAF +8334D535 CEB0 +8334D536 CEB1 +8334D537 CEB2 +8334D538 CEB3 +8334D539 CEB4 +8334D630 CEB5 +8334D631 CEB6 +8334D632 CEB7 +8334D633 CEB8 +8334D634 CEB9 +8334D635 CEBA +8334D636 CEBB +8334D637 CEBC +8334D638 CEBD +8334D639 CEBE +8334D730 CEBF +8334D731 CEC0 +8334D732 CEC1 +8334D733 CEC2 +8334D734 CEC3 +8334D735 CEC4 +8334D736 CEC5 +8334D737 CEC6 +8334D738 CEC7 +8334D739 CEC8 +8334D830 CEC9 +8334D831 CECA +8334D832 CECB +8334D833 CECC +8334D834 CECD +8334D835 CECE +8334D836 CECF +8334D837 CED0 +8334D838 CED1 +8334D839 CED2 +8334D930 CED3 +8334D931 CED4 +8334D932 CED5 +8334D933 CED6 +8334D934 CED7 +8334D935 CED8 +8334D936 CED9 +8334D937 CEDA +8334D938 CEDB +8334D939 CEDC +8334DA30 CEDD +8334DA31 CEDE +8334DA32 CEDF +8334DA33 CEE0 +8334DA34 CEE1 +8334DA35 CEE2 +8334DA36 CEE3 +8334DA37 CEE4 +8334DA38 CEE5 +8334DA39 CEE6 +8334DB30 CEE7 +8334DB31 CEE8 +8334DB32 CEE9 +8334DB33 CEEA +8334DB34 CEEB +8334DB35 CEEC +8334DB36 CEED +8334DB37 CEEE +8334DB38 CEEF +8334DB39 CEF0 +8334DC30 CEF1 +8334DC31 CEF2 +8334DC32 CEF3 +8334DC33 CEF4 +8334DC34 CEF5 +8334DC35 CEF6 +8334DC36 CEF7 +8334DC37 CEF8 +8334DC38 CEF9 +8334DC39 CEFA +8334DD30 CEFB +8334DD31 CEFC +8334DD32 CEFD +8334DD33 CEFE +8334DD34 CEFF +8334DD35 CF00 +8334DD36 CF01 +8334DD37 CF02 +8334DD38 CF03 +8334DD39 CF04 +8334DE30 CF05 +8334DE31 CF06 +8334DE32 CF07 +8334DE33 CF08 +8334DE34 CF09 +8334DE35 CF0A +8334DE36 CF0B +8334DE37 CF0C +8334DE38 CF0D +8334DE39 CF0E +8334DF30 CF0F +8334DF31 CF10 +8334DF32 CF11 +8334DF33 CF12 +8334DF34 CF13 +8334DF35 CF14 +8334DF36 CF15 +8334DF37 CF16 +8334DF38 CF17 +8334DF39 CF18 +8334E030 CF19 +8334E031 CF1A +8334E032 CF1B +8334E033 CF1C +8334E034 CF1D +8334E035 CF1E +8334E036 CF1F +8334E037 CF20 +8334E038 CF21 +8334E039 CF22 +8334E130 CF23 +8334E131 CF24 +8334E132 CF25 +8334E133 CF26 +8334E134 CF27 +8334E135 CF28 +8334E136 CF29 +8334E137 CF2A +8334E138 CF2B +8334E139 CF2C +8334E230 CF2D +8334E231 CF2E +8334E232 CF2F +8334E233 CF30 +8334E234 CF31 +8334E235 CF32 +8334E236 CF33 +8334E237 CF34 +8334E238 CF35 +8334E239 CF36 +8334E330 CF37 +8334E331 CF38 +8334E332 CF39 +8334E333 CF3A +8334E334 CF3B +8334E335 CF3C +8334E336 CF3D +8334E337 CF3E +8334E338 CF3F +8334E339 CF40 +8334E430 CF41 +8334E431 CF42 +8334E432 CF43 +8334E433 CF44 +8334E434 CF45 +8334E435 CF46 +8334E436 CF47 +8334E437 CF48 +8334E438 CF49 +8334E439 CF4A +8334E530 CF4B +8334E531 CF4C +8334E532 CF4D +8334E533 CF4E +8334E534 CF4F +8334E535 CF50 +8334E536 CF51 +8334E537 CF52 +8334E538 CF53 +8334E539 CF54 +8334E630 CF55 +8334E631 CF56 +8334E632 CF57 +8334E633 CF58 +8334E634 CF59 +8334E635 CF5A +8334E636 CF5B +8334E637 CF5C +8334E638 CF5D +8334E639 CF5E +8334E730 CF5F +8334E731 CF60 +8334E732 CF61 +8334E733 CF62 +8334E734 CF63 +8334E735 CF64 +8334E736 CF65 +8334E737 CF66 +8334E738 CF67 +8334E739 CF68 +8334E830 CF69 +8334E831 CF6A +8334E832 CF6B +8334E833 CF6C +8334E834 CF6D +8334E835 CF6E +8334E836 CF6F +8334E837 CF70 +8334E838 CF71 +8334E839 CF72 +8334E930 CF73 +8334E931 CF74 +8334E932 CF75 +8334E933 CF76 +8334E934 CF77 +8334E935 CF78 +8334E936 CF79 +8334E937 CF7A +8334E938 CF7B +8334E939 CF7C +8334EA30 CF7D +8334EA31 CF7E +8334EA32 CF7F +8334EA33 CF80 +8334EA34 CF81 +8334EA35 CF82 +8334EA36 CF83 +8334EA37 CF84 +8334EA38 CF85 +8334EA39 CF86 +8334EB30 CF87 +8334EB31 CF88 +8334EB32 CF89 +8334EB33 CF8A +8334EB34 CF8B +8334EB35 CF8C +8334EB36 CF8D +8334EB37 CF8E +8334EB38 CF8F +8334EB39 CF90 +8334EC30 CF91 +8334EC31 CF92 +8334EC32 CF93 +8334EC33 CF94 +8334EC34 CF95 +8334EC35 CF96 +8334EC36 CF97 +8334EC37 CF98 +8334EC38 CF99 +8334EC39 CF9A +8334ED30 CF9B +8334ED31 CF9C +8334ED32 CF9D +8334ED33 CF9E +8334ED34 CF9F +8334ED35 CFA0 +8334ED36 CFA1 +8334ED37 CFA2 +8334ED38 CFA3 +8334ED39 CFA4 +8334EE30 CFA5 +8334EE31 CFA6 +8334EE32 CFA7 +8334EE33 CFA8 +8334EE34 CFA9 +8334EE35 CFAA +8334EE36 CFAB +8334EE37 CFAC +8334EE38 CFAD +8334EE39 CFAE +8334EF30 CFAF +8334EF31 CFB0 +8334EF32 CFB1 +8334EF33 CFB2 +8334EF34 CFB3 +8334EF35 CFB4 +8334EF36 CFB5 +8334EF37 CFB6 +8334EF38 CFB7 +8334EF39 CFB8 +8334F030 CFB9 +8334F031 CFBA +8334F032 CFBB +8334F033 CFBC +8334F034 CFBD +8334F035 CFBE +8334F036 CFBF +8334F037 CFC0 +8334F038 CFC1 +8334F039 CFC2 +8334F130 CFC3 +8334F131 CFC4 +8334F132 CFC5 +8334F133 CFC6 +8334F134 CFC7 +8334F135 CFC8 +8334F136 CFC9 +8334F137 CFCA +8334F138 CFCB +8334F139 CFCC +8334F230 CFCD +8334F231 CFCE +8334F232 CFCF +8334F233 CFD0 +8334F234 CFD1 +8334F235 CFD2 +8334F236 CFD3 +8334F237 CFD4 +8334F238 CFD5 +8334F239 CFD6 +8334F330 CFD7 +8334F331 CFD8 +8334F332 CFD9 +8334F333 CFDA +8334F334 CFDB +8334F335 CFDC +8334F336 CFDD +8334F337 CFDE +8334F338 CFDF +8334F339 CFE0 +8334F430 CFE1 +8334F431 CFE2 +8334F432 CFE3 +8334F433 CFE4 +8334F434 CFE5 +8334F435 CFE6 +8334F436 CFE7 +8334F437 CFE8 +8334F438 CFE9 +8334F439 CFEA +8334F530 CFEB +8334F531 CFEC +8334F532 CFED +8334F533 CFEE +8334F534 CFEF +8334F535 CFF0 +8334F536 CFF1 +8334F537 CFF2 +8334F538 CFF3 +8334F539 CFF4 +8334F630 CFF5 +8334F631 CFF6 +8334F632 CFF7 +8334F633 CFF8 +8334F634 CFF9 +8334F635 CFFA +8334F636 CFFB +8334F637 CFFC +8334F638 CFFD +8334F639 CFFE +8334F730 CFFF +8334F731 D000 +8334F732 D001 +8334F733 D002 +8334F734 D003 +8334F735 D004 +8334F736 D005 +8334F737 D006 +8334F738 D007 +8334F739 D008 +8334F830 D009 +8334F831 D00A +8334F832 D00B +8334F833 D00C +8334F834 D00D +8334F835 D00E +8334F836 D00F +8334F837 D010 +8334F838 D011 +8334F839 D012 +8334F930 D013 +8334F931 D014 +8334F932 D015 +8334F933 D016 +8334F934 D017 +8334F935 D018 +8334F936 D019 +8334F937 D01A +8334F938 D01B +8334F939 D01C +8334FA30 D01D +8334FA31 D01E +8334FA32 D01F +8334FA33 D020 +8334FA34 D021 +8334FA35 D022 +8334FA36 D023 +8334FA37 D024 +8334FA38 D025 +8334FA39 D026 +8334FB30 D027 +8334FB31 D028 +8334FB32 D029 +8334FB33 D02A +8334FB34 D02B +8334FB35 D02C +8334FB36 D02D +8334FB37 D02E +8334FB38 D02F +8334FB39 D030 +8334FC30 D031 +8334FC31 D032 +8334FC32 D033 +8334FC33 D034 +8334FC34 D035 +8334FC35 D036 +8334FC36 D037 +8334FC37 D038 +8334FC38 D039 +8334FC39 D03A +8334FD30 D03B +8334FD31 D03C +8334FD32 D03D +8334FD33 D03E +8334FD34 D03F +8334FD35 D040 +8334FD36 D041 +8334FD37 D042 +8334FD38 D043 +8334FD39 D044 +8334FE30 D045 +8334FE31 D046 +8334FE32 D047 +8334FE33 D048 +8334FE34 D049 +8334FE35 D04A +8334FE36 D04B +8334FE37 D04C +8334FE38 D04D +8334FE39 D04E +83358130 D04F +83358131 D050 +83358132 D051 +83358133 D052 +83358134 D053 +83358135 D054 +83358136 D055 +83358137 D056 +83358138 D057 +83358139 D058 +83358230 D059 +83358231 D05A +83358232 D05B +83358233 D05C +83358234 D05D +83358235 D05E +83358236 D05F +83358237 D060 +83358238 D061 +83358239 D062 +83358330 D063 +83358331 D064 +83358332 D065 +83358333 D066 +83358334 D067 +83358335 D068 +83358336 D069 +83358337 D06A +83358338 D06B +83358339 D06C +83358430 D06D +83358431 D06E +83358432 D06F +83358433 D070 +83358434 D071 +83358435 D072 +83358436 D073 +83358437 D074 +83358438 D075 +83358439 D076 +83358530 D077 +83358531 D078 +83358532 D079 +83358533 D07A +83358534 D07B +83358535 D07C +83358536 D07D +83358537 D07E +83358538 D07F +83358539 D080 +83358630 D081 +83358631 D082 +83358632 D083 +83358633 D084 +83358634 D085 +83358635 D086 +83358636 D087 +83358637 D088 +83358638 D089 +83358639 D08A +83358730 D08B +83358731 D08C +83358732 D08D +83358733 D08E +83358734 D08F +83358735 D090 +83358736 D091 +83358737 D092 +83358738 D093 +83358739 D094 +83358830 D095 +83358831 D096 +83358832 D097 +83358833 D098 +83358834 D099 +83358835 D09A +83358836 D09B +83358837 D09C +83358838 D09D +83358839 D09E +83358930 D09F +83358931 D0A0 +83358932 D0A1 +83358933 D0A2 +83358934 D0A3 +83358935 D0A4 +83358936 D0A5 +83358937 D0A6 +83358938 D0A7 +83358939 D0A8 +83358A30 D0A9 +83358A31 D0AA +83358A32 D0AB +83358A33 D0AC +83358A34 D0AD +83358A35 D0AE +83358A36 D0AF +83358A37 D0B0 +83358A38 D0B1 +83358A39 D0B2 +83358B30 D0B3 +83358B31 D0B4 +83358B32 D0B5 +83358B33 D0B6 +83358B34 D0B7 +83358B35 D0B8 +83358B36 D0B9 +83358B37 D0BA +83358B38 D0BB +83358B39 D0BC +83358C30 D0BD +83358C31 D0BE +83358C32 D0BF +83358C33 D0C0 +83358C34 D0C1 +83358C35 D0C2 +83358C36 D0C3 +83358C37 D0C4 +83358C38 D0C5 +83358C39 D0C6 +83358D30 D0C7 +83358D31 D0C8 +83358D32 D0C9 +83358D33 D0CA +83358D34 D0CB +83358D35 D0CC +83358D36 D0CD +83358D37 D0CE +83358D38 D0CF +83358D39 D0D0 +83358E30 D0D1 +83358E31 D0D2 +83358E32 D0D3 +83358E33 D0D4 +83358E34 D0D5 +83358E35 D0D6 +83358E36 D0D7 +83358E37 D0D8 +83358E38 D0D9 +83358E39 D0DA +83358F30 D0DB +83358F31 D0DC +83358F32 D0DD +83358F33 D0DE +83358F34 D0DF +83358F35 D0E0 +83358F36 D0E1 +83358F37 D0E2 +83358F38 D0E3 +83358F39 D0E4 +83359030 D0E5 +83359031 D0E6 +83359032 D0E7 +83359033 D0E8 +83359034 D0E9 +83359035 D0EA +83359036 D0EB +83359037 D0EC +83359038 D0ED +83359039 D0EE +83359130 D0EF +83359131 D0F0 +83359132 D0F1 +83359133 D0F2 +83359134 D0F3 +83359135 D0F4 +83359136 D0F5 +83359137 D0F6 +83359138 D0F7 +83359139 D0F8 +83359230 D0F9 +83359231 D0FA +83359232 D0FB +83359233 D0FC +83359234 D0FD +83359235 D0FE +83359236 D0FF +83359237 D100 +83359238 D101 +83359239 D102 +83359330 D103 +83359331 D104 +83359332 D105 +83359333 D106 +83359334 D107 +83359335 D108 +83359336 D109 +83359337 D10A +83359338 D10B +83359339 D10C +83359430 D10D +83359431 D10E +83359432 D10F +83359433 D110 +83359434 D111 +83359435 D112 +83359436 D113 +83359437 D114 +83359438 D115 +83359439 D116 +83359530 D117 +83359531 D118 +83359532 D119 +83359533 D11A +83359534 D11B +83359535 D11C +83359536 D11D +83359537 D11E +83359538 D11F +83359539 D120 +83359630 D121 +83359631 D122 +83359632 D123 +83359633 D124 +83359634 D125 +83359635 D126 +83359636 D127 +83359637 D128 +83359638 D129 +83359639 D12A +83359730 D12B +83359731 D12C +83359732 D12D +83359733 D12E +83359734 D12F +83359735 D130 +83359736 D131 +83359737 D132 +83359738 D133 +83359739 D134 +83359830 D135 +83359831 D136 +83359832 D137 +83359833 D138 +83359834 D139 +83359835 D13A +83359836 D13B +83359837 D13C +83359838 D13D +83359839 D13E +83359930 D13F +83359931 D140 +83359932 D141 +83359933 D142 +83359934 D143 +83359935 D144 +83359936 D145 +83359937 D146 +83359938 D147 +83359939 D148 +83359A30 D149 +83359A31 D14A +83359A32 D14B +83359A33 D14C +83359A34 D14D +83359A35 D14E +83359A36 D14F +83359A37 D150 +83359A38 D151 +83359A39 D152 +83359B30 D153 +83359B31 D154 +83359B32 D155 +83359B33 D156 +83359B34 D157 +83359B35 D158 +83359B36 D159 +83359B37 D15A +83359B38 D15B +83359B39 D15C +83359C30 D15D +83359C31 D15E +83359C32 D15F +83359C33 D160 +83359C34 D161 +83359C35 D162 +83359C36 D163 +83359C37 D164 +83359C38 D165 +83359C39 D166 +83359D30 D167 +83359D31 D168 +83359D32 D169 +83359D33 D16A +83359D34 D16B +83359D35 D16C +83359D36 D16D +83359D37 D16E +83359D38 D16F +83359D39 D170 +83359E30 D171 +83359E31 D172 +83359E32 D173 +83359E33 D174 +83359E34 D175 +83359E35 D176 +83359E36 D177 +83359E37 D178 +83359E38 D179 +83359E39 D17A +83359F30 D17B +83359F31 D17C +83359F32 D17D +83359F33 D17E +83359F34 D17F +83359F35 D180 +83359F36 D181 +83359F37 D182 +83359F38 D183 +83359F39 D184 +8335A030 D185 +8335A031 D186 +8335A032 D187 +8335A033 D188 +8335A034 D189 +8335A035 D18A +8335A036 D18B +8335A037 D18C +8335A038 D18D +8335A039 D18E +8335A130 D18F +8335A131 D190 +8335A132 D191 +8335A133 D192 +8335A134 D193 +8335A135 D194 +8335A136 D195 +8335A137 D196 +8335A138 D197 +8335A139 D198 +8335A230 D199 +8335A231 D19A +8335A232 D19B +8335A233 D19C +8335A234 D19D +8335A235 D19E +8335A236 D19F +8335A237 D1A0 +8335A238 D1A1 +8335A239 D1A2 +8335A330 D1A3 +8335A331 D1A4 +8335A332 D1A5 +8335A333 D1A6 +8335A334 D1A7 +8335A335 D1A8 +8335A336 D1A9 +8335A337 D1AA +8335A338 D1AB +8335A339 D1AC +8335A430 D1AD +8335A431 D1AE +8335A432 D1AF +8335A433 D1B0 +8335A434 D1B1 +8335A435 D1B2 +8335A436 D1B3 +8335A437 D1B4 +8335A438 D1B5 +8335A439 D1B6 +8335A530 D1B7 +8335A531 D1B8 +8335A532 D1B9 +8335A533 D1BA +8335A534 D1BB +8335A535 D1BC +8335A536 D1BD +8335A537 D1BE +8335A538 D1BF +8335A539 D1C0 +8335A630 D1C1 +8335A631 D1C2 +8335A632 D1C3 +8335A633 D1C4 +8335A634 D1C5 +8335A635 D1C6 +8335A636 D1C7 +8335A637 D1C8 +8335A638 D1C9 +8335A639 D1CA +8335A730 D1CB +8335A731 D1CC +8335A732 D1CD +8335A733 D1CE +8335A734 D1CF +8335A735 D1D0 +8335A736 D1D1 +8335A737 D1D2 +8335A738 D1D3 +8335A739 D1D4 +8335A830 D1D5 +8335A831 D1D6 +8335A832 D1D7 +8335A833 D1D8 +8335A834 D1D9 +8335A835 D1DA +8335A836 D1DB +8335A837 D1DC +8335A838 D1DD +8335A839 D1DE +8335A930 D1DF +8335A931 D1E0 +8335A932 D1E1 +8335A933 D1E2 +8335A934 D1E3 +8335A935 D1E4 +8335A936 D1E5 +8335A937 D1E6 +8335A938 D1E7 +8335A939 D1E8 +8335AA30 D1E9 +8335AA31 D1EA +8335AA32 D1EB +8335AA33 D1EC +8335AA34 D1ED +8335AA35 D1EE +8335AA36 D1EF +8335AA37 D1F0 +8335AA38 D1F1 +8335AA39 D1F2 +8335AB30 D1F3 +8335AB31 D1F4 +8335AB32 D1F5 +8335AB33 D1F6 +8335AB34 D1F7 +8335AB35 D1F8 +8335AB36 D1F9 +8335AB37 D1FA +8335AB38 D1FB +8335AB39 D1FC +8335AC30 D1FD +8335AC31 D1FE +8335AC32 D1FF +8335AC33 D200 +8335AC34 D201 +8335AC35 D202 +8335AC36 D203 +8335AC37 D204 +8335AC38 D205 +8335AC39 D206 +8335AD30 D207 +8335AD31 D208 +8335AD32 D209 +8335AD33 D20A +8335AD34 D20B +8335AD35 D20C +8335AD36 D20D +8335AD37 D20E +8335AD38 D20F +8335AD39 D210 +8335AE30 D211 +8335AE31 D212 +8335AE32 D213 +8335AE33 D214 +8335AE34 D215 +8335AE35 D216 +8335AE36 D217 +8335AE37 D218 +8335AE38 D219 +8335AE39 D21A +8335AF30 D21B +8335AF31 D21C +8335AF32 D21D +8335AF33 D21E +8335AF34 D21F +8335AF35 D220 +8335AF36 D221 +8335AF37 D222 +8335AF38 D223 +8335AF39 D224 +8335B030 D225 +8335B031 D226 +8335B032 D227 +8335B033 D228 +8335B034 D229 +8335B035 D22A +8335B036 D22B +8335B037 D22C +8335B038 D22D +8335B039 D22E +8335B130 D22F +8335B131 D230 +8335B132 D231 +8335B133 D232 +8335B134 D233 +8335B135 D234 +8335B136 D235 +8335B137 D236 +8335B138 D237 +8335B139 D238 +8335B230 D239 +8335B231 D23A +8335B232 D23B +8335B233 D23C +8335B234 D23D +8335B235 D23E +8335B236 D23F +8335B237 D240 +8335B238 D241 +8335B239 D242 +8335B330 D243 +8335B331 D244 +8335B332 D245 +8335B333 D246 +8335B334 D247 +8335B335 D248 +8335B336 D249 +8335B337 D24A +8335B338 D24B +8335B339 D24C +8335B430 D24D +8335B431 D24E +8335B432 D24F +8335B433 D250 +8335B434 D251 +8335B435 D252 +8335B436 D253 +8335B437 D254 +8335B438 D255 +8335B439 D256 +8335B530 D257 +8335B531 D258 +8335B532 D259 +8335B533 D25A +8335B534 D25B +8335B535 D25C +8335B536 D25D +8335B537 D25E +8335B538 D25F +8335B539 D260 +8335B630 D261 +8335B631 D262 +8335B632 D263 +8335B633 D264 +8335B634 D265 +8335B635 D266 +8335B636 D267 +8335B637 D268 +8335B638 D269 +8335B639 D26A +8335B730 D26B +8335B731 D26C +8335B732 D26D +8335B733 D26E +8335B734 D26F +8335B735 D270 +8335B736 D271 +8335B737 D272 +8335B738 D273 +8335B739 D274 +8335B830 D275 +8335B831 D276 +8335B832 D277 +8335B833 D278 +8335B834 D279 +8335B835 D27A +8335B836 D27B +8335B837 D27C +8335B838 D27D +8335B839 D27E +8335B930 D27F +8335B931 D280 +8335B932 D281 +8335B933 D282 +8335B934 D283 +8335B935 D284 +8335B936 D285 +8335B937 D286 +8335B938 D287 +8335B939 D288 +8335BA30 D289 +8335BA31 D28A +8335BA32 D28B +8335BA33 D28C +8335BA34 D28D +8335BA35 D28E +8335BA36 D28F +8335BA37 D290 +8335BA38 D291 +8335BA39 D292 +8335BB30 D293 +8335BB31 D294 +8335BB32 D295 +8335BB33 D296 +8335BB34 D297 +8335BB35 D298 +8335BB36 D299 +8335BB37 D29A +8335BB38 D29B +8335BB39 D29C +8335BC30 D29D +8335BC31 D29E +8335BC32 D29F +8335BC33 D2A0 +8335BC34 D2A1 +8335BC35 D2A2 +8335BC36 D2A3 +8335BC37 D2A4 +8335BC38 D2A5 +8335BC39 D2A6 +8335BD30 D2A7 +8335BD31 D2A8 +8335BD32 D2A9 +8335BD33 D2AA +8335BD34 D2AB +8335BD35 D2AC +8335BD36 D2AD +8335BD37 D2AE +8335BD38 D2AF +8335BD39 D2B0 +8335BE30 D2B1 +8335BE31 D2B2 +8335BE32 D2B3 +8335BE33 D2B4 +8335BE34 D2B5 +8335BE35 D2B6 +8335BE36 D2B7 +8335BE37 D2B8 +8335BE38 D2B9 +8335BE39 D2BA +8335BF30 D2BB +8335BF31 D2BC +8335BF32 D2BD +8335BF33 D2BE +8335BF34 D2BF +8335BF35 D2C0 +8335BF36 D2C1 +8335BF37 D2C2 +8335BF38 D2C3 +8335BF39 D2C4 +8335C030 D2C5 +8335C031 D2C6 +8335C032 D2C7 +8335C033 D2C8 +8335C034 D2C9 +8335C035 D2CA +8335C036 D2CB +8335C037 D2CC +8335C038 D2CD +8335C039 D2CE +8335C130 D2CF +8335C131 D2D0 +8335C132 D2D1 +8335C133 D2D2 +8335C134 D2D3 +8335C135 D2D4 +8335C136 D2D5 +8335C137 D2D6 +8335C138 D2D7 +8335C139 D2D8 +8335C230 D2D9 +8335C231 D2DA +8335C232 D2DB +8335C233 D2DC +8335C234 D2DD +8335C235 D2DE +8335C236 D2DF +8335C237 D2E0 +8335C238 D2E1 +8335C239 D2E2 +8335C330 D2E3 +8335C331 D2E4 +8335C332 D2E5 +8335C333 D2E6 +8335C334 D2E7 +8335C335 D2E8 +8335C336 D2E9 +8335C337 D2EA +8335C338 D2EB +8335C339 D2EC +8335C430 D2ED +8335C431 D2EE +8335C432 D2EF +8335C433 D2F0 +8335C434 D2F1 +8335C435 D2F2 +8335C436 D2F3 +8335C437 D2F4 +8335C438 D2F5 +8335C439 D2F6 +8335C530 D2F7 +8335C531 D2F8 +8335C532 D2F9 +8335C533 D2FA +8335C534 D2FB +8335C535 D2FC +8335C536 D2FD +8335C537 D2FE +8335C538 D2FF +8335C539 D300 +8335C630 D301 +8335C631 D302 +8335C632 D303 +8335C633 D304 +8335C634 D305 +8335C635 D306 +8335C636 D307 +8335C637 D308 +8335C638 D309 +8335C639 D30A +8335C730 D30B +8335C731 D30C +8335C732 D30D +8335C733 D30E +8335C734 D30F +8335C735 D310 +8335C736 D311 +8335C737 D312 +8335C738 D313 +8335C739 D314 +8335C830 D315 +8335C831 D316 +8335C832 D317 +8335C833 D318 +8335C834 D319 +8335C835 D31A +8335C836 D31B +8335C837 D31C +8335C838 D31D +8335C839 D31E +8335C930 D31F +8335C931 D320 +8335C932 D321 +8335C933 D322 +8335C934 D323 +8335C935 D324 +8335C936 D325 +8335C937 D326 +8335C938 D327 +8335C939 D328 +8335CA30 D329 +8335CA31 D32A +8335CA32 D32B +8335CA33 D32C +8335CA34 D32D +8335CA35 D32E +8335CA36 D32F +8335CA37 D330 +8335CA38 D331 +8335CA39 D332 +8335CB30 D333 +8335CB31 D334 +8335CB32 D335 +8335CB33 D336 +8335CB34 D337 +8335CB35 D338 +8335CB36 D339 +8335CB37 D33A +8335CB38 D33B +8335CB39 D33C +8335CC30 D33D +8335CC31 D33E +8335CC32 D33F +8335CC33 D340 +8335CC34 D341 +8335CC35 D342 +8335CC36 D343 +8335CC37 D344 +8335CC38 D345 +8335CC39 D346 +8335CD30 D347 +8335CD31 D348 +8335CD32 D349 +8335CD33 D34A +8335CD34 D34B +8335CD35 D34C +8335CD36 D34D +8335CD37 D34E +8335CD38 D34F +8335CD39 D350 +8335CE30 D351 +8335CE31 D352 +8335CE32 D353 +8335CE33 D354 +8335CE34 D355 +8335CE35 D356 +8335CE36 D357 +8335CE37 D358 +8335CE38 D359 +8335CE39 D35A +8335CF30 D35B +8335CF31 D35C +8335CF32 D35D +8335CF33 D35E +8335CF34 D35F +8335CF35 D360 +8335CF36 D361 +8335CF37 D362 +8335CF38 D363 +8335CF39 D364 +8335D030 D365 +8335D031 D366 +8335D032 D367 +8335D033 D368 +8335D034 D369 +8335D035 D36A +8335D036 D36B +8335D037 D36C +8335D038 D36D +8335D039 D36E +8335D130 D36F +8335D131 D370 +8335D132 D371 +8335D133 D372 +8335D134 D373 +8335D135 D374 +8335D136 D375 +8335D137 D376 +8335D138 D377 +8335D139 D378 +8335D230 D379 +8335D231 D37A +8335D232 D37B +8335D233 D37C +8335D234 D37D +8335D235 D37E +8335D236 D37F +8335D237 D380 +8335D238 D381 +8335D239 D382 +8335D330 D383 +8335D331 D384 +8335D332 D385 +8335D333 D386 +8335D334 D387 +8335D335 D388 +8335D336 D389 +8335D337 D38A +8335D338 D38B +8335D339 D38C +8335D430 D38D +8335D431 D38E +8335D432 D38F +8335D433 D390 +8335D434 D391 +8335D435 D392 +8335D436 D393 +8335D437 D394 +8335D438 D395 +8335D439 D396 +8335D530 D397 +8335D531 D398 +8335D532 D399 +8335D533 D39A +8335D534 D39B +8335D535 D39C +8335D536 D39D +8335D537 D39E +8335D538 D39F +8335D539 D3A0 +8335D630 D3A1 +8335D631 D3A2 +8335D632 D3A3 +8335D633 D3A4 +8335D634 D3A5 +8335D635 D3A6 +8335D636 D3A7 +8335D637 D3A8 +8335D638 D3A9 +8335D639 D3AA +8335D730 D3AB +8335D731 D3AC +8335D732 D3AD +8335D733 D3AE +8335D734 D3AF +8335D735 D3B0 +8335D736 D3B1 +8335D737 D3B2 +8335D738 D3B3 +8335D739 D3B4 +8335D830 D3B5 +8335D831 D3B6 +8335D832 D3B7 +8335D833 D3B8 +8335D834 D3B9 +8335D835 D3BA +8335D836 D3BB +8335D837 D3BC +8335D838 D3BD +8335D839 D3BE +8335D930 D3BF +8335D931 D3C0 +8335D932 D3C1 +8335D933 D3C2 +8335D934 D3C3 +8335D935 D3C4 +8335D936 D3C5 +8335D937 D3C6 +8335D938 D3C7 +8335D939 D3C8 +8335DA30 D3C9 +8335DA31 D3CA +8335DA32 D3CB +8335DA33 D3CC +8335DA34 D3CD +8335DA35 D3CE +8335DA36 D3CF +8335DA37 D3D0 +8335DA38 D3D1 +8335DA39 D3D2 +8335DB30 D3D3 +8335DB31 D3D4 +8335DB32 D3D5 +8335DB33 D3D6 +8335DB34 D3D7 +8335DB35 D3D8 +8335DB36 D3D9 +8335DB37 D3DA +8335DB38 D3DB +8335DB39 D3DC +8335DC30 D3DD +8335DC31 D3DE +8335DC32 D3DF +8335DC33 D3E0 +8335DC34 D3E1 +8335DC35 D3E2 +8335DC36 D3E3 +8335DC37 D3E4 +8335DC38 D3E5 +8335DC39 D3E6 +8335DD30 D3E7 +8335DD31 D3E8 +8335DD32 D3E9 +8335DD33 D3EA +8335DD34 D3EB +8335DD35 D3EC +8335DD36 D3ED +8335DD37 D3EE +8335DD38 D3EF +8335DD39 D3F0 +8335DE30 D3F1 +8335DE31 D3F2 +8335DE32 D3F3 +8335DE33 D3F4 +8335DE34 D3F5 +8335DE35 D3F6 +8335DE36 D3F7 +8335DE37 D3F8 +8335DE38 D3F9 +8335DE39 D3FA +8335DF30 D3FB +8335DF31 D3FC +8335DF32 D3FD +8335DF33 D3FE +8335DF34 D3FF +8335DF35 D400 +8335DF36 D401 +8335DF37 D402 +8335DF38 D403 +8335DF39 D404 +8335E030 D405 +8335E031 D406 +8335E032 D407 +8335E033 D408 +8335E034 D409 +8335E035 D40A +8335E036 D40B +8335E037 D40C +8335E038 D40D +8335E039 D40E +8335E130 D40F +8335E131 D410 +8335E132 D411 +8335E133 D412 +8335E134 D413 +8335E135 D414 +8335E136 D415 +8335E137 D416 +8335E138 D417 +8335E139 D418 +8335E230 D419 +8335E231 D41A +8335E232 D41B +8335E233 D41C +8335E234 D41D +8335E235 D41E +8335E236 D41F +8335E237 D420 +8335E238 D421 +8335E239 D422 +8335E330 D423 +8335E331 D424 +8335E332 D425 +8335E333 D426 +8335E334 D427 +8335E335 D428 +8335E336 D429 +8335E337 D42A +8335E338 D42B +8335E339 D42C +8335E430 D42D +8335E431 D42E +8335E432 D42F +8335E433 D430 +8335E434 D431 +8335E435 D432 +8335E436 D433 +8335E437 D434 +8335E438 D435 +8335E439 D436 +8335E530 D437 +8335E531 D438 +8335E532 D439 +8335E533 D43A +8335E534 D43B +8335E535 D43C +8335E536 D43D +8335E537 D43E +8335E538 D43F +8335E539 D440 +8335E630 D441 +8335E631 D442 +8335E632 D443 +8335E633 D444 +8335E634 D445 +8335E635 D446 +8335E636 D447 +8335E637 D448 +8335E638 D449 +8335E639 D44A +8335E730 D44B +8335E731 D44C +8335E732 D44D +8335E733 D44E +8335E734 D44F +8335E735 D450 +8335E736 D451 +8335E737 D452 +8335E738 D453 +8335E739 D454 +8335E830 D455 +8335E831 D456 +8335E832 D457 +8335E833 D458 +8335E834 D459 +8335E835 D45A +8335E836 D45B +8335E837 D45C +8335E838 D45D +8335E839 D45E +8335E930 D45F +8335E931 D460 +8335E932 D461 +8335E933 D462 +8335E934 D463 +8335E935 D464 +8335E936 D465 +8335E937 D466 +8335E938 D467 +8335E939 D468 +8335EA30 D469 +8335EA31 D46A +8335EA32 D46B +8335EA33 D46C +8335EA34 D46D +8335EA35 D46E +8335EA36 D46F +8335EA37 D470 +8335EA38 D471 +8335EA39 D472 +8335EB30 D473 +8335EB31 D474 +8335EB32 D475 +8335EB33 D476 +8335EB34 D477 +8335EB35 D478 +8335EB36 D479 +8335EB37 D47A +8335EB38 D47B +8335EB39 D47C +8335EC30 D47D +8335EC31 D47E +8335EC32 D47F +8335EC33 D480 +8335EC34 D481 +8335EC35 D482 +8335EC36 D483 +8335EC37 D484 +8335EC38 D485 +8335EC39 D486 +8335ED30 D487 +8335ED31 D488 +8335ED32 D489 +8335ED33 D48A +8335ED34 D48B +8335ED35 D48C +8335ED36 D48D +8335ED37 D48E +8335ED38 D48F +8335ED39 D490 +8335EE30 D491 +8335EE31 D492 +8335EE32 D493 +8335EE33 D494 +8335EE34 D495 +8335EE35 D496 +8335EE36 D497 +8335EE37 D498 +8335EE38 D499 +8335EE39 D49A +8335EF30 D49B +8335EF31 D49C +8335EF32 D49D +8335EF33 D49E +8335EF34 D49F +8335EF35 D4A0 +8335EF36 D4A1 +8335EF37 D4A2 +8335EF38 D4A3 +8335EF39 D4A4 +8335F030 D4A5 +8335F031 D4A6 +8335F032 D4A7 +8335F033 D4A8 +8335F034 D4A9 +8335F035 D4AA +8335F036 D4AB +8335F037 D4AC +8335F038 D4AD +8335F039 D4AE +8335F130 D4AF +8335F131 D4B0 +8335F132 D4B1 +8335F133 D4B2 +8335F134 D4B3 +8335F135 D4B4 +8335F136 D4B5 +8335F137 D4B6 +8335F138 D4B7 +8335F139 D4B8 +8335F230 D4B9 +8335F231 D4BA +8335F232 D4BB +8335F233 D4BC +8335F234 D4BD +8335F235 D4BE +8335F236 D4BF +8335F237 D4C0 +8335F238 D4C1 +8335F239 D4C2 +8335F330 D4C3 +8335F331 D4C4 +8335F332 D4C5 +8335F333 D4C6 +8335F334 D4C7 +8335F335 D4C8 +8335F336 D4C9 +8335F337 D4CA +8335F338 D4CB +8335F339 D4CC +8335F430 D4CD +8335F431 D4CE +8335F432 D4CF +8335F433 D4D0 +8335F434 D4D1 +8335F435 D4D2 +8335F436 D4D3 +8335F437 D4D4 +8335F438 D4D5 +8335F439 D4D6 +8335F530 D4D7 +8335F531 D4D8 +8335F532 D4D9 +8335F533 D4DA +8335F534 D4DB +8335F535 D4DC +8335F536 D4DD +8335F537 D4DE +8335F538 D4DF +8335F539 D4E0 +8335F630 D4E1 +8335F631 D4E2 +8335F632 D4E3 +8335F633 D4E4 +8335F634 D4E5 +8335F635 D4E6 +8335F636 D4E7 +8335F637 D4E8 +8335F638 D4E9 +8335F639 D4EA +8335F730 D4EB +8335F731 D4EC +8335F732 D4ED +8335F733 D4EE +8335F734 D4EF +8335F735 D4F0 +8335F736 D4F1 +8335F737 D4F2 +8335F738 D4F3 +8335F739 D4F4 +8335F830 D4F5 +8335F831 D4F6 +8335F832 D4F7 +8335F833 D4F8 +8335F834 D4F9 +8335F835 D4FA +8335F836 D4FB +8335F837 D4FC +8335F838 D4FD +8335F839 D4FE +8335F930 D4FF +8335F931 D500 +8335F932 D501 +8335F933 D502 +8335F934 D503 +8335F935 D504 +8335F936 D505 +8335F937 D506 +8335F938 D507 +8335F939 D508 +8335FA30 D509 +8335FA31 D50A +8335FA32 D50B +8335FA33 D50C +8335FA34 D50D +8335FA35 D50E +8335FA36 D50F +8335FA37 D510 +8335FA38 D511 +8335FA39 D512 +8335FB30 D513 +8335FB31 D514 +8335FB32 D515 +8335FB33 D516 +8335FB34 D517 +8335FB35 D518 +8335FB36 D519 +8335FB37 D51A +8335FB38 D51B +8335FB39 D51C +8335FC30 D51D +8335FC31 D51E +8335FC32 D51F +8335FC33 D520 +8335FC34 D521 +8335FC35 D522 +8335FC36 D523 +8335FC37 D524 +8335FC38 D525 +8335FC39 D526 +8335FD30 D527 +8335FD31 D528 +8335FD32 D529 +8335FD33 D52A +8335FD34 D52B +8335FD35 D52C +8335FD36 D52D +8335FD37 D52E +8335FD38 D52F +8335FD39 D530 +8335FE30 D531 +8335FE31 D532 +8335FE32 D533 +8335FE33 D534 +8335FE34 D535 +8335FE35 D536 +8335FE36 D537 +8335FE37 D538 +8335FE38 D539 +8335FE39 D53A +83368130 D53B +83368131 D53C +83368132 D53D +83368133 D53E +83368134 D53F +83368135 D540 +83368136 D541 +83368137 D542 +83368138 D543 +83368139 D544 +83368230 D545 +83368231 D546 +83368232 D547 +83368233 D548 +83368234 D549 +83368235 D54A +83368236 D54B +83368237 D54C +83368238 D54D +83368239 D54E +83368330 D54F +83368331 D550 +83368332 D551 +83368333 D552 +83368334 D553 +83368335 D554 +83368336 D555 +83368337 D556 +83368338 D557 +83368339 D558 +83368430 D559 +83368431 D55A +83368432 D55B +83368433 D55C +83368434 D55D +83368435 D55E +83368436 D55F +83368437 D560 +83368438 D561 +83368439 D562 +83368530 D563 +83368531 D564 +83368532 D565 +83368533 D566 +83368534 D567 +83368535 D568 +83368536 D569 +83368537 D56A +83368538 D56B +83368539 D56C +83368630 D56D +83368631 D56E +83368632 D56F +83368633 D570 +83368634 D571 +83368635 D572 +83368636 D573 +83368637 D574 +83368638 D575 +83368639 D576 +83368730 D577 +83368731 D578 +83368732 D579 +83368733 D57A +83368734 D57B +83368735 D57C +83368736 D57D +83368737 D57E +83368738 D57F +83368739 D580 +83368830 D581 +83368831 D582 +83368832 D583 +83368833 D584 +83368834 D585 +83368835 D586 +83368836 D587 +83368837 D588 +83368838 D589 +83368839 D58A +83368930 D58B +83368931 D58C +83368932 D58D +83368933 D58E +83368934 D58F +83368935 D590 +83368936 D591 +83368937 D592 +83368938 D593 +83368939 D594 +83368A30 D595 +83368A31 D596 +83368A32 D597 +83368A33 D598 +83368A34 D599 +83368A35 D59A +83368A36 D59B +83368A37 D59C +83368A38 D59D +83368A39 D59E +83368B30 D59F +83368B31 D5A0 +83368B32 D5A1 +83368B33 D5A2 +83368B34 D5A3 +83368B35 D5A4 +83368B36 D5A5 +83368B37 D5A6 +83368B38 D5A7 +83368B39 D5A8 +83368C30 D5A9 +83368C31 D5AA +83368C32 D5AB +83368C33 D5AC +83368C34 D5AD +83368C35 D5AE +83368C36 D5AF +83368C37 D5B0 +83368C38 D5B1 +83368C39 D5B2 +83368D30 D5B3 +83368D31 D5B4 +83368D32 D5B5 +83368D33 D5B6 +83368D34 D5B7 +83368D35 D5B8 +83368D36 D5B9 +83368D37 D5BA +83368D38 D5BB +83368D39 D5BC +83368E30 D5BD +83368E31 D5BE +83368E32 D5BF +83368E33 D5C0 +83368E34 D5C1 +83368E35 D5C2 +83368E36 D5C3 +83368E37 D5C4 +83368E38 D5C5 +83368E39 D5C6 +83368F30 D5C7 +83368F31 D5C8 +83368F32 D5C9 +83368F33 D5CA +83368F34 D5CB +83368F35 D5CC +83368F36 D5CD +83368F37 D5CE +83368F38 D5CF +83368F39 D5D0 +83369030 D5D1 +83369031 D5D2 +83369032 D5D3 +83369033 D5D4 +83369034 D5D5 +83369035 D5D6 +83369036 D5D7 +83369037 D5D8 +83369038 D5D9 +83369039 D5DA +83369130 D5DB +83369131 D5DC +83369132 D5DD +83369133 D5DE +83369134 D5DF +83369135 D5E0 +83369136 D5E1 +83369137 D5E2 +83369138 D5E3 +83369139 D5E4 +83369230 D5E5 +83369231 D5E6 +83369232 D5E7 +83369233 D5E8 +83369234 D5E9 +83369235 D5EA +83369236 D5EB +83369237 D5EC +83369238 D5ED +83369239 D5EE +83369330 D5EF +83369331 D5F0 +83369332 D5F1 +83369333 D5F2 +83369334 D5F3 +83369335 D5F4 +83369336 D5F5 +83369337 D5F6 +83369338 D5F7 +83369339 D5F8 +83369430 D5F9 +83369431 D5FA +83369432 D5FB +83369433 D5FC +83369434 D5FD +83369435 D5FE +83369436 D5FF +83369437 D600 +83369438 D601 +83369439 D602 +83369530 D603 +83369531 D604 +83369532 D605 +83369533 D606 +83369534 D607 +83369535 D608 +83369536 D609 +83369537 D60A +83369538 D60B +83369539 D60C +83369630 D60D +83369631 D60E +83369632 D60F +83369633 D610 +83369634 D611 +83369635 D612 +83369636 D613 +83369637 D614 +83369638 D615 +83369639 D616 +83369730 D617 +83369731 D618 +83369732 D619 +83369733 D61A +83369734 D61B +83369735 D61C +83369736 D61D +83369737 D61E +83369738 D61F +83369739 D620 +83369830 D621 +83369831 D622 +83369832 D623 +83369833 D624 +83369834 D625 +83369835 D626 +83369836 D627 +83369837 D628 +83369838 D629 +83369839 D62A +83369930 D62B +83369931 D62C +83369932 D62D +83369933 D62E +83369934 D62F +83369935 D630 +83369936 D631 +83369937 D632 +83369938 D633 +83369939 D634 +83369A30 D635 +83369A31 D636 +83369A32 D637 +83369A33 D638 +83369A34 D639 +83369A35 D63A +83369A36 D63B +83369A37 D63C +83369A38 D63D +83369A39 D63E +83369B30 D63F +83369B31 D640 +83369B32 D641 +83369B33 D642 +83369B34 D643 +83369B35 D644 +83369B36 D645 +83369B37 D646 +83369B38 D647 +83369B39 D648 +83369C30 D649 +83369C31 D64A +83369C32 D64B +83369C33 D64C +83369C34 D64D +83369C35 D64E +83369C36 D64F +83369C37 D650 +83369C38 D651 +83369C39 D652 +83369D30 D653 +83369D31 D654 +83369D32 D655 +83369D33 D656 +83369D34 D657 +83369D35 D658 +83369D36 D659 +83369D37 D65A +83369D38 D65B +83369D39 D65C +83369E30 D65D +83369E31 D65E +83369E32 D65F +83369E33 D660 +83369E34 D661 +83369E35 D662 +83369E36 D663 +83369E37 D664 +83369E38 D665 +83369E39 D666 +83369F30 D667 +83369F31 D668 +83369F32 D669 +83369F33 D66A +83369F34 D66B +83369F35 D66C +83369F36 D66D +83369F37 D66E +83369F38 D66F +83369F39 D670 +8336A030 D671 +8336A031 D672 +8336A032 D673 +8336A033 D674 +8336A034 D675 +8336A035 D676 +8336A036 D677 +8336A037 D678 +8336A038 D679 +8336A039 D67A +8336A130 D67B +8336A131 D67C +8336A132 D67D +8336A133 D67E +8336A134 D67F +8336A135 D680 +8336A136 D681 +8336A137 D682 +8336A138 D683 +8336A139 D684 +8336A230 D685 +8336A231 D686 +8336A232 D687 +8336A233 D688 +8336A234 D689 +8336A235 D68A +8336A236 D68B +8336A237 D68C +8336A238 D68D +8336A239 D68E +8336A330 D68F +8336A331 D690 +8336A332 D691 +8336A333 D692 +8336A334 D693 +8336A335 D694 +8336A336 D695 +8336A337 D696 +8336A338 D697 +8336A339 D698 +8336A430 D699 +8336A431 D69A +8336A432 D69B +8336A433 D69C +8336A434 D69D +8336A435 D69E +8336A436 D69F +8336A437 D6A0 +8336A438 D6A1 +8336A439 D6A2 +8336A530 D6A3 +8336A531 D6A4 +8336A532 D6A5 +8336A533 D6A6 +8336A534 D6A7 +8336A535 D6A8 +8336A536 D6A9 +8336A537 D6AA +8336A538 D6AB +8336A539 D6AC +8336A630 D6AD +8336A631 D6AE +8336A632 D6AF +8336A633 D6B0 +8336A634 D6B1 +8336A635 D6B2 +8336A636 D6B3 +8336A637 D6B4 +8336A638 D6B5 +8336A639 D6B6 +8336A730 D6B7 +8336A731 D6B8 +8336A732 D6B9 +8336A733 D6BA +8336A734 D6BB +8336A735 D6BC +8336A736 D6BD +8336A737 D6BE +8336A738 D6BF +8336A739 D6C0 +8336A830 D6C1 +8336A831 D6C2 +8336A832 D6C3 +8336A833 D6C4 +8336A834 D6C5 +8336A835 D6C6 +8336A836 D6C7 +8336A837 D6C8 +8336A838 D6C9 +8336A839 D6CA +8336A930 D6CB +8336A931 D6CC +8336A932 D6CD +8336A933 D6CE +8336A934 D6CF +8336A935 D6D0 +8336A936 D6D1 +8336A937 D6D2 +8336A938 D6D3 +8336A939 D6D4 +8336AA30 D6D5 +8336AA31 D6D6 +8336AA32 D6D7 +8336AA33 D6D8 +8336AA34 D6D9 +8336AA35 D6DA +8336AA36 D6DB +8336AA37 D6DC +8336AA38 D6DD +8336AA39 D6DE +8336AB30 D6DF +8336AB31 D6E0 +8336AB32 D6E1 +8336AB33 D6E2 +8336AB34 D6E3 +8336AB35 D6E4 +8336AB36 D6E5 +8336AB37 D6E6 +8336AB38 D6E7 +8336AB39 D6E8 +8336AC30 D6E9 +8336AC31 D6EA +8336AC32 D6EB +8336AC33 D6EC +8336AC34 D6ED +8336AC35 D6EE +8336AC36 D6EF +8336AC37 D6F0 +8336AC38 D6F1 +8336AC39 D6F2 +8336AD30 D6F3 +8336AD31 D6F4 +8336AD32 D6F5 +8336AD33 D6F6 +8336AD34 D6F7 +8336AD35 D6F8 +8336AD36 D6F9 +8336AD37 D6FA +8336AD38 D6FB +8336AD39 D6FC +8336AE30 D6FD +8336AE31 D6FE +8336AE32 D6FF +8336AE33 D700 +8336AE34 D701 +8336AE35 D702 +8336AE36 D703 +8336AE37 D704 +8336AE38 D705 +8336AE39 D706 +8336AF30 D707 +8336AF31 D708 +8336AF32 D709 +8336AF33 D70A +8336AF34 D70B +8336AF35 D70C +8336AF36 D70D +8336AF37 D70E +8336AF38 D70F +8336AF39 D710 +8336B030 D711 +8336B031 D712 +8336B032 D713 +8336B033 D714 +8336B034 D715 +8336B035 D716 +8336B036 D717 +8336B037 D718 +8336B038 D719 +8336B039 D71A +8336B130 D71B +8336B131 D71C +8336B132 D71D +8336B133 D71E +8336B134 D71F +8336B135 D720 +8336B136 D721 +8336B137 D722 +8336B138 D723 +8336B139 D724 +8336B230 D725 +8336B231 D726 +8336B232 D727 +8336B233 D728 +8336B234 D729 +8336B235 D72A +8336B236 D72B +8336B237 D72C +8336B238 D72D +8336B239 D72E +8336B330 D72F +8336B331 D730 +8336B332 D731 +8336B333 D732 +8336B334 D733 +8336B335 D734 +8336B336 D735 +8336B337 D736 +8336B338 D737 +8336B339 D738 +8336B430 D739 +8336B431 D73A +8336B432 D73B +8336B433 D73C +8336B434 D73D +8336B435 D73E +8336B436 D73F +8336B437 D740 +8336B438 D741 +8336B439 D742 +8336B530 D743 +8336B531 D744 +8336B532 D745 +8336B533 D746 +8336B534 D747 +8336B535 D748 +8336B536 D749 +8336B537 D74A +8336B538 D74B +8336B539 D74C +8336B630 D74D +8336B631 D74E +8336B632 D74F +8336B633 D750 +8336B634 D751 +8336B635 D752 +8336B636 D753 +8336B637 D754 +8336B638 D755 +8336B639 D756 +8336B730 D757 +8336B731 D758 +8336B732 D759 +8336B733 D75A +8336B734 D75B +8336B735 D75C +8336B736 D75D +8336B737 D75E +8336B738 D75F +8336B739 D760 +8336B830 D761 +8336B831 D762 +8336B832 D763 +8336B833 D764 +8336B834 D765 +8336B835 D766 +8336B836 D767 +8336B837 D768 +8336B838 D769 +8336B839 D76A +8336B930 D76B +8336B931 D76C +8336B932 D76D +8336B933 D76E +8336B934 D76F +8336B935 D770 +8336B936 D771 +8336B937 D772 +8336B938 D773 +8336B939 D774 +8336BA30 D775 +8336BA31 D776 +8336BA32 D777 +8336BA33 D778 +8336BA34 D779 +8336BA35 D77A +8336BA36 D77B +8336BA37 D77C +8336BA38 D77D +8336BA39 D77E +8336BB30 D77F +8336BB31 D780 +8336BB32 D781 +8336BB33 D782 +8336BB34 D783 +8336BB35 D784 +8336BB36 D785 +8336BB37 D786 +8336BB38 D787 +8336BB39 D788 +8336BC30 D789 +8336BC31 D78A +8336BC32 D78B +8336BC33 D78C +8336BC34 D78D +8336BC35 D78E +8336BC36 D78F +8336BC37 D790 +8336BC38 D791 +8336BC39 D792 +8336BD30 D793 +8336BD31 D794 +8336BD32 D795 +8336BD33 D796 +8336BD34 D797 +8336BD35 D798 +8336BD36 D799 +8336BD37 D79A +8336BD38 D79B +8336BD39 D79C +8336BE30 D79D +8336BE31 D79E +8336BE32 D79F +8336BE33 D7A0 +8336BE34 D7A1 +8336BE35 D7A2 +8336BE36 D7A3 +8336BE37 D7A4 +8336BE38 D7A5 +8336BE39 D7A6 +8336BF30 D7A7 +8336BF31 D7A8 +8336BF32 D7A9 +8336BF33 D7AA +8336BF34 D7AB +8336BF35 D7AC +8336BF36 D7AD +8336BF37 D7AE +8336BF38 D7AF +8336BF39 D7B0 +8336C030 D7B1 +8336C031 D7B2 +8336C032 D7B3 +8336C033 D7B4 +8336C034 D7B5 +8336C035 D7B6 +8336C036 D7B7 +8336C037 D7B8 +8336C038 D7B9 +8336C039 D7BA +8336C130 D7BB +8336C131 D7BC +8336C132 D7BD +8336C133 D7BE +8336C134 D7BF +8336C135 D7C0 +8336C136 D7C1 +8336C137 D7C2 +8336C138 D7C3 +8336C139 D7C4 +8336C230 D7C5 +8336C231 D7C6 +8336C232 D7C7 +8336C233 D7C8 +8336C234 D7C9 +8336C235 D7CA +8336C236 D7CB +8336C237 D7CC +8336C238 D7CD +8336C239 D7CE +8336C330 D7CF +8336C331 D7D0 +8336C332 D7D1 +8336C333 D7D2 +8336C334 D7D3 +8336C335 D7D4 +8336C336 D7D5 +8336C337 D7D6 +8336C338 D7D7 +8336C339 D7D8 +8336C430 D7D9 +8336C431 D7DA +8336C432 D7DB +8336C433 D7DC +8336C434 D7DD +8336C435 D7DE +8336C436 D7DF +8336C437 D7E0 +8336C438 D7E1 +8336C439 D7E2 +8336C530 D7E3 +8336C531 D7E4 +8336C532 D7E5 +8336C533 D7E6 +8336C534 D7E7 +8336C535 D7E8 +8336C536 D7E9 +8336C537 D7EA +8336C538 D7EB +8336C539 D7EC +8336C630 D7ED +8336C631 D7EE +8336C632 D7EF +8336C633 D7F0 +8336C634 D7F1 +8336C635 D7F2 +8336C636 D7F3 +8336C637 D7F4 +8336C638 D7F5 +8336C639 D7F6 +8336C730 D7F7 +8336C731 D7F8 +8336C732 D7F9 +8336C733 D7FA +8336C734 D7FB +8336C735 D7FC +8336C736 D7FD +8336C737 D7FE +8336C738 D7FF +AAA1 E000 +AAA2 E001 +AAA3 E002 +AAA4 E003 +AAA5 E004 +AAA6 E005 +AAA7 E006 +AAA8 E007 +AAA9 E008 +AAAA E009 +AAAB E00A +AAAC E00B +AAAD E00C +AAAE E00D +AAAF E00E +AAB0 E00F +AAB1 E010 +AAB2 E011 +AAB3 E012 +AAB4 E013 +AAB5 E014 +AAB6 E015 +AAB7 E016 +AAB8 E017 +AAB9 E018 +AABA E019 +AABB E01A +AABC E01B +AABD E01C +AABE E01D +AABF E01E +AAC0 E01F +AAC1 E020 +AAC2 E021 +AAC3 E022 +AAC4 E023 +AAC5 E024 +AAC6 E025 +AAC7 E026 +AAC8 E027 +AAC9 E028 +AACA E029 +AACB E02A +AACC E02B +AACD E02C +AACE E02D +AACF E02E +AAD0 E02F +AAD1 E030 +AAD2 E031 +AAD3 E032 +AAD4 E033 +AAD5 E034 +AAD6 E035 +AAD7 E036 +AAD8 E037 +AAD9 E038 +AADA E039 +AADB E03A +AADC E03B +AADD E03C +AADE E03D +AADF E03E +AAE0 E03F +AAE1 E040 +AAE2 E041 +AAE3 E042 +AAE4 E043 +AAE5 E044 +AAE6 E045 +AAE7 E046 +AAE8 E047 +AAE9 E048 +AAEA E049 +AAEB E04A +AAEC E04B +AAED E04C +AAEE E04D +AAEF E04E +AAF0 E04F +AAF1 E050 +AAF2 E051 +AAF3 E052 +AAF4 E053 +AAF5 E054 +AAF6 E055 +AAF7 E056 +AAF8 E057 +AAF9 E058 +AAFA E059 +AAFB E05A +AAFC E05B +AAFD E05C +AAFE E05D +ABA1 E05E +ABA2 E05F +ABA3 E060 +ABA4 E061 +ABA5 E062 +ABA6 E063 +ABA7 E064 +ABA8 E065 +ABA9 E066 +ABAA E067 +ABAB E068 +ABAC E069 +ABAD E06A +ABAE E06B +ABAF E06C +ABB0 E06D +ABB1 E06E +ABB2 E06F +ABB3 E070 +ABB4 E071 +ABB5 E072 +ABB6 E073 +ABB7 E074 +ABB8 E075 +ABB9 E076 +ABBA E077 +ABBB E078 +ABBC E079 +ABBD E07A +ABBE E07B +ABBF E07C +ABC0 E07D +ABC1 E07E +ABC2 E07F +ABC3 E080 +ABC4 E081 +ABC5 E082 +ABC6 E083 +ABC7 E084 +ABC8 E085 +ABC9 E086 +ABCA E087 +ABCB E088 +ABCC E089 +ABCD E08A +ABCE E08B +ABCF E08C +ABD0 E08D +ABD1 E08E +ABD2 E08F +ABD3 E090 +ABD4 E091 +ABD5 E092 +ABD6 E093 +ABD7 E094 +ABD8 E095 +ABD9 E096 +ABDA E097 +ABDB E098 +ABDC E099 +ABDD E09A +ABDE E09B +ABDF E09C +ABE0 E09D +ABE1 E09E +ABE2 E09F +ABE3 E0A0 +ABE4 E0A1 +ABE5 E0A2 +ABE6 E0A3 +ABE7 E0A4 +ABE8 E0A5 +ABE9 E0A6 +ABEA E0A7 +ABEB E0A8 +ABEC E0A9 +ABED E0AA +ABEE E0AB +ABEF E0AC +ABF0 E0AD +ABF1 E0AE +ABF2 E0AF +ABF3 E0B0 +ABF4 E0B1 +ABF5 E0B2 +ABF6 E0B3 +ABF7 E0B4 +ABF8 E0B5 +ABF9 E0B6 +ABFA E0B7 +ABFB E0B8 +ABFC E0B9 +ABFD E0BA +ABFE E0BB +ACA1 E0BC +ACA2 E0BD +ACA3 E0BE +ACA4 E0BF +ACA5 E0C0 +ACA6 E0C1 +ACA7 E0C2 +ACA8 E0C3 +ACA9 E0C4 +ACAA E0C5 +ACAB E0C6 +ACAC E0C7 +ACAD E0C8 +ACAE E0C9 +ACAF E0CA +ACB0 E0CB +ACB1 E0CC +ACB2 E0CD +ACB3 E0CE +ACB4 E0CF +ACB5 E0D0 +ACB6 E0D1 +ACB7 E0D2 +ACB8 E0D3 +ACB9 E0D4 +ACBA E0D5 +ACBB E0D6 +ACBC E0D7 +ACBD E0D8 +ACBE E0D9 +ACBF E0DA +ACC0 E0DB +ACC1 E0DC +ACC2 E0DD +ACC3 E0DE +ACC4 E0DF +ACC5 E0E0 +ACC6 E0E1 +ACC7 E0E2 +ACC8 E0E3 +ACC9 E0E4 +ACCA E0E5 +ACCB E0E6 +ACCC E0E7 +ACCD E0E8 +ACCE E0E9 +ACCF E0EA +ACD0 E0EB +ACD1 E0EC +ACD2 E0ED +ACD3 E0EE +ACD4 E0EF +ACD5 E0F0 +ACD6 E0F1 +ACD7 E0F2 +ACD8 E0F3 +ACD9 E0F4 +ACDA E0F5 +ACDB E0F6 +ACDC E0F7 +ACDD E0F8 +ACDE E0F9 +ACDF E0FA +ACE0 E0FB +ACE1 E0FC +ACE2 E0FD +ACE3 E0FE +ACE4 E0FF +ACE5 E100 +ACE6 E101 +ACE7 E102 +ACE8 E103 +ACE9 E104 +ACEA E105 +ACEB E106 +ACEC E107 +ACED E108 +ACEE E109 +ACEF E10A +ACF0 E10B +ACF1 E10C +ACF2 E10D +ACF3 E10E +ACF4 E10F +ACF5 E110 +ACF6 E111 +ACF7 E112 +ACF8 E113 +ACF9 E114 +ACFA E115 +ACFB E116 +ACFC E117 +ACFD E118 +ACFE E119 +ADA1 E11A +ADA2 E11B +ADA3 E11C +ADA4 E11D +ADA5 E11E +ADA6 E11F +ADA7 E120 +ADA8 E121 +ADA9 E122 +ADAA E123 +ADAB E124 +ADAC E125 +ADAD E126 +ADAE E127 +ADAF E128 +ADB0 E129 +ADB1 E12A +ADB2 E12B +ADB3 E12C +ADB4 E12D +ADB5 E12E +ADB6 E12F +ADB7 E130 +ADB8 E131 +ADB9 E132 +ADBA E133 +ADBB E134 +ADBC E135 +ADBD E136 +ADBE E137 +ADBF E138 +ADC0 E139 +ADC1 E13A +ADC2 E13B +ADC3 E13C +ADC4 E13D +ADC5 E13E +ADC6 E13F +ADC7 E140 +ADC8 E141 +ADC9 E142 +ADCA E143 +ADCB E144 +ADCC E145 +ADCD E146 +ADCE E147 +ADCF E148 +ADD0 E149 +ADD1 E14A +ADD2 E14B +ADD3 E14C +ADD4 E14D +ADD5 E14E +ADD6 E14F +ADD7 E150 +ADD8 E151 +ADD9 E152 +ADDA E153 +ADDB E154 +ADDC E155 +ADDD E156 +ADDE E157 +ADDF E158 +ADE0 E159 +ADE1 E15A +ADE2 E15B +ADE3 E15C +ADE4 E15D +ADE5 E15E +ADE6 E15F +ADE7 E160 +ADE8 E161 +ADE9 E162 +ADEA E163 +ADEB E164 +ADEC E165 +ADED E166 +ADEE E167 +ADEF E168 +ADF0 E169 +ADF1 E16A +ADF2 E16B +ADF3 E16C +ADF4 E16D +ADF5 E16E +ADF6 E16F +ADF7 E170 +ADF8 E171 +ADF9 E172 +ADFA E173 +ADFB E174 +ADFC E175 +ADFD E176 +ADFE E177 +AEA1 E178 +AEA2 E179 +AEA3 E17A +AEA4 E17B +AEA5 E17C +AEA6 E17D +AEA7 E17E +AEA8 E17F +AEA9 E180 +AEAA E181 +AEAB E182 +AEAC E183 +AEAD E184 +AEAE E185 +AEAF E186 +AEB0 E187 +AEB1 E188 +AEB2 E189 +AEB3 E18A +AEB4 E18B +AEB5 E18C +AEB6 E18D +AEB7 E18E +AEB8 E18F +AEB9 E190 +AEBA E191 +AEBB E192 +AEBC E193 +AEBD E194 +AEBE E195 +AEBF E196 +AEC0 E197 +AEC1 E198 +AEC2 E199 +AEC3 E19A +AEC4 E19B +AEC5 E19C +AEC6 E19D +AEC7 E19E +AEC8 E19F +AEC9 E1A0 +AECA E1A1 +AECB E1A2 +AECC E1A3 +AECD E1A4 +AECE E1A5 +AECF E1A6 +AED0 E1A7 +AED1 E1A8 +AED2 E1A9 +AED3 E1AA +AED4 E1AB +AED5 E1AC +AED6 E1AD +AED7 E1AE +AED8 E1AF +AED9 E1B0 +AEDA E1B1 +AEDB E1B2 +AEDC E1B3 +AEDD E1B4 +AEDE E1B5 +AEDF E1B6 +AEE0 E1B7 +AEE1 E1B8 +AEE2 E1B9 +AEE3 E1BA +AEE4 E1BB +AEE5 E1BC +AEE6 E1BD +AEE7 E1BE +AEE8 E1BF +AEE9 E1C0 +AEEA E1C1 +AEEB E1C2 +AEEC E1C3 +AEED E1C4 +AEEE E1C5 +AEEF E1C6 +AEF0 E1C7 +AEF1 E1C8 +AEF2 E1C9 +AEF3 E1CA +AEF4 E1CB +AEF5 E1CC +AEF6 E1CD +AEF7 E1CE +AEF8 E1CF +AEF9 E1D0 +AEFA E1D1 +AEFB E1D2 +AEFC E1D3 +AEFD E1D4 +AEFE E1D5 +AFA1 E1D6 +AFA2 E1D7 +AFA3 E1D8 +AFA4 E1D9 +AFA5 E1DA +AFA6 E1DB +AFA7 E1DC +AFA8 E1DD +AFA9 E1DE +AFAA E1DF +AFAB E1E0 +AFAC E1E1 +AFAD E1E2 +AFAE E1E3 +AFAF E1E4 +AFB0 E1E5 +AFB1 E1E6 +AFB2 E1E7 +AFB3 E1E8 +AFB4 E1E9 +AFB5 E1EA +AFB6 E1EB +AFB7 E1EC +AFB8 E1ED +AFB9 E1EE +AFBA E1EF +AFBB E1F0 +AFBC E1F1 +AFBD E1F2 +AFBE E1F3 +AFBF E1F4 +AFC0 E1F5 +AFC1 E1F6 +AFC2 E1F7 +AFC3 E1F8 +AFC4 E1F9 +AFC5 E1FA +AFC6 E1FB +AFC7 E1FC +AFC8 E1FD +AFC9 E1FE +AFCA E1FF +AFCB E200 +AFCC E201 +AFCD E202 +AFCE E203 +AFCF E204 +AFD0 E205 +AFD1 E206 +AFD2 E207 +AFD3 E208 +AFD4 E209 +AFD5 E20A +AFD6 E20B +AFD7 E20C +AFD8 E20D +AFD9 E20E +AFDA E20F +AFDB E210 +AFDC E211 +AFDD E212 +AFDE E213 +AFDF E214 +AFE0 E215 +AFE1 E216 +AFE2 E217 +AFE3 E218 +AFE4 E219 +AFE5 E21A +AFE6 E21B +AFE7 E21C +AFE8 E21D +AFE9 E21E +AFEA E21F +AFEB E220 +AFEC E221 +AFED E222 +AFEE E223 +AFEF E224 +AFF0 E225 +AFF1 E226 +AFF2 E227 +AFF3 E228 +AFF4 E229 +AFF5 E22A +AFF6 E22B +AFF7 E22C +AFF8 E22D +AFF9 E22E +AFFA E22F +AFFB E230 +AFFC E231 +AFFD E232 +AFFE E233 +F8A1 E234 +F8A2 E235 +F8A3 E236 +F8A4 E237 +F8A5 E238 +F8A6 E239 +F8A7 E23A +F8A8 E23B +F8A9 E23C +F8AA E23D +F8AB E23E +F8AC E23F +F8AD E240 +F8AE E241 +F8AF E242 +F8B0 E243 +F8B1 E244 +F8B2 E245 +F8B3 E246 +F8B4 E247 +F8B5 E248 +F8B6 E249 +F8B7 E24A +F8B8 E24B +F8B9 E24C +F8BA E24D +F8BB E24E +F8BC E24F +F8BD E250 +F8BE E251 +F8BF E252 +F8C0 E253 +F8C1 E254 +F8C2 E255 +F8C3 E256 +F8C4 E257 +F8C5 E258 +F8C6 E259 +F8C7 E25A +F8C8 E25B +F8C9 E25C +F8CA E25D +F8CB E25E +F8CC E25F +F8CD E260 +F8CE E261 +F8CF E262 +F8D0 E263 +F8D1 E264 +F8D2 E265 +F8D3 E266 +F8D4 E267 +F8D5 E268 +F8D6 E269 +F8D7 E26A +F8D8 E26B +F8D9 E26C +F8DA E26D +F8DB E26E +F8DC E26F +F8DD E270 +F8DE E271 +F8DF E272 +F8E0 E273 +F8E1 E274 +F8E2 E275 +F8E3 E276 +F8E4 E277 +F8E5 E278 +F8E6 E279 +F8E7 E27A +F8E8 E27B +F8E9 E27C +F8EA E27D +F8EB E27E +F8EC E27F +F8ED E280 +F8EE E281 +F8EF E282 +F8F0 E283 +F8F1 E284 +F8F2 E285 +F8F3 E286 +F8F4 E287 +F8F5 E288 +F8F6 E289 +F8F7 E28A +F8F8 E28B +F8F9 E28C +F8FA E28D +F8FB E28E +F8FC E28F +F8FD E290 +F8FE E291 +F9A1 E292 +F9A2 E293 +F9A3 E294 +F9A4 E295 +F9A5 E296 +F9A6 E297 +F9A7 E298 +F9A8 E299 +F9A9 E29A +F9AA E29B +F9AB E29C +F9AC E29D +F9AD E29E +F9AE E29F +F9AF E2A0 +F9B0 E2A1 +F9B1 E2A2 +F9B2 E2A3 +F9B3 E2A4 +F9B4 E2A5 +F9B5 E2A6 +F9B6 E2A7 +F9B7 E2A8 +F9B8 E2A9 +F9B9 E2AA +F9BA E2AB +F9BB E2AC +F9BC E2AD +F9BD E2AE +F9BE E2AF +F9BF E2B0 +F9C0 E2B1 +F9C1 E2B2 +F9C2 E2B3 +F9C3 E2B4 +F9C4 E2B5 +F9C5 E2B6 +F9C6 E2B7 +F9C7 E2B8 +F9C8 E2B9 +F9C9 E2BA +F9CA E2BB +F9CB E2BC +F9CC E2BD +F9CD E2BE +F9CE E2BF +F9CF E2C0 +F9D0 E2C1 +F9D1 E2C2 +F9D2 E2C3 +F9D3 E2C4 +F9D4 E2C5 +F9D5 E2C6 +F9D6 E2C7 +F9D7 E2C8 +F9D8 E2C9 +F9D9 E2CA +F9DA E2CB +F9DB E2CC +F9DC E2CD +F9DD E2CE +F9DE E2CF +F9DF E2D0 +F9E0 E2D1 +F9E1 E2D2 +F9E2 E2D3 +F9E3 E2D4 +F9E4 E2D5 +F9E5 E2D6 +F9E6 E2D7 +F9E7 E2D8 +F9E8 E2D9 +F9E9 E2DA +F9EA E2DB +F9EB E2DC +F9EC E2DD +F9ED E2DE +F9EE E2DF +F9EF E2E0 +F9F0 E2E1 +F9F1 E2E2 +F9F2 E2E3 +F9F3 E2E4 +F9F4 E2E5 +F9F5 E2E6 +F9F6 E2E7 +F9F7 E2E8 +F9F8 E2E9 +F9F9 E2EA +F9FA E2EB +F9FB E2EC +F9FC E2ED +F9FD E2EE +F9FE E2EF +FAA1 E2F0 +FAA2 E2F1 +FAA3 E2F2 +FAA4 E2F3 +FAA5 E2F4 +FAA6 E2F5 +FAA7 E2F6 +FAA8 E2F7 +FAA9 E2F8 +FAAA E2F9 +FAAB E2FA +FAAC E2FB +FAAD E2FC +FAAE E2FD +FAAF E2FE +FAB0 E2FF +FAB1 E300 +FAB2 E301 +FAB3 E302 +FAB4 E303 +FAB5 E304 +FAB6 E305 +FAB7 E306 +FAB8 E307 +FAB9 E308 +FABA E309 +FABB E30A +FABC E30B +FABD E30C +FABE E30D +FABF E30E +FAC0 E30F +FAC1 E310 +FAC2 E311 +FAC3 E312 +FAC4 E313 +FAC5 E314 +FAC6 E315 +FAC7 E316 +FAC8 E317 +FAC9 E318 +FACA E319 +FACB E31A +FACC E31B +FACD E31C +FACE E31D +FACF E31E +FAD0 E31F +FAD1 E320 +FAD2 E321 +FAD3 E322 +FAD4 E323 +FAD5 E324 +FAD6 E325 +FAD7 E326 +FAD8 E327 +FAD9 E328 +FADA E329 +FADB E32A +FADC E32B +FADD E32C +FADE E32D +FADF E32E +FAE0 E32F +FAE1 E330 +FAE2 E331 +FAE3 E332 +FAE4 E333 +FAE5 E334 +FAE6 E335 +FAE7 E336 +FAE8 E337 +FAE9 E338 +FAEA E339 +FAEB E33A +FAEC E33B +FAED E33C +FAEE E33D +FAEF E33E +FAF0 E33F +FAF1 E340 +FAF2 E341 +FAF3 E342 +FAF4 E343 +FAF5 E344 +FAF6 E345 +FAF7 E346 +FAF8 E347 +FAF9 E348 +FAFA E349 +FAFB E34A +FAFC E34B +FAFD E34C +FAFE E34D +FBA1 E34E +FBA2 E34F +FBA3 E350 +FBA4 E351 +FBA5 E352 +FBA6 E353 +FBA7 E354 +FBA8 E355 +FBA9 E356 +FBAA E357 +FBAB E358 +FBAC E359 +FBAD E35A +FBAE E35B +FBAF E35C +FBB0 E35D +FBB1 E35E +FBB2 E35F +FBB3 E360 +FBB4 E361 +FBB5 E362 +FBB6 E363 +FBB7 E364 +FBB8 E365 +FBB9 E366 +FBBA E367 +FBBB E368 +FBBC E369 +FBBD E36A +FBBE E36B +FBBF E36C +FBC0 E36D +FBC1 E36E +FBC2 E36F +FBC3 E370 +FBC4 E371 +FBC5 E372 +FBC6 E373 +FBC7 E374 +FBC8 E375 +FBC9 E376 +FBCA E377 +FBCB E378 +FBCC E379 +FBCD E37A +FBCE E37B +FBCF E37C +FBD0 E37D +FBD1 E37E +FBD2 E37F +FBD3 E380 +FBD4 E381 +FBD5 E382 +FBD6 E383 +FBD7 E384 +FBD8 E385 +FBD9 E386 +FBDA E387 +FBDB E388 +FBDC E389 +FBDD E38A +FBDE E38B +FBDF E38C +FBE0 E38D +FBE1 E38E +FBE2 E38F +FBE3 E390 +FBE4 E391 +FBE5 E392 +FBE6 E393 +FBE7 E394 +FBE8 E395 +FBE9 E396 +FBEA E397 +FBEB E398 +FBEC E399 +FBED E39A +FBEE E39B +FBEF E39C +FBF0 E39D +FBF1 E39E +FBF2 E39F +FBF3 E3A0 +FBF4 E3A1 +FBF5 E3A2 +FBF6 E3A3 +FBF7 E3A4 +FBF8 E3A5 +FBF9 E3A6 +FBFA E3A7 +FBFB E3A8 +FBFC E3A9 +FBFD E3AA +FBFE E3AB +FCA1 E3AC +FCA2 E3AD +FCA3 E3AE +FCA4 E3AF +FCA5 E3B0 +FCA6 E3B1 +FCA7 E3B2 +FCA8 E3B3 +FCA9 E3B4 +FCAA E3B5 +FCAB E3B6 +FCAC E3B7 +FCAD E3B8 +FCAE E3B9 +FCAF E3BA +FCB0 E3BB +FCB1 E3BC +FCB2 E3BD +FCB3 E3BE +FCB4 E3BF +FCB5 E3C0 +FCB6 E3C1 +FCB7 E3C2 +FCB8 E3C3 +FCB9 E3C4 +FCBA E3C5 +FCBB E3C6 +FCBC E3C7 +FCBD E3C8 +FCBE E3C9 +FCBF E3CA +FCC0 E3CB +FCC1 E3CC +FCC2 E3CD +FCC3 E3CE +FCC4 E3CF +FCC5 E3D0 +FCC6 E3D1 +FCC7 E3D2 +FCC8 E3D3 +FCC9 E3D4 +FCCA E3D5 +FCCB E3D6 +FCCC E3D7 +FCCD E3D8 +FCCE E3D9 +FCCF E3DA +FCD0 E3DB +FCD1 E3DC +FCD2 E3DD +FCD3 E3DE +FCD4 E3DF +FCD5 E3E0 +FCD6 E3E1 +FCD7 E3E2 +FCD8 E3E3 +FCD9 E3E4 +FCDA E3E5 +FCDB E3E6 +FCDC E3E7 +FCDD E3E8 +FCDE E3E9 +FCDF E3EA +FCE0 E3EB +FCE1 E3EC +FCE2 E3ED +FCE3 E3EE +FCE4 E3EF +FCE5 E3F0 +FCE6 E3F1 +FCE7 E3F2 +FCE8 E3F3 +FCE9 E3F4 +FCEA E3F5 +FCEB E3F6 +FCEC E3F7 +FCED E3F8 +FCEE E3F9 +FCEF E3FA +FCF0 E3FB +FCF1 E3FC +FCF2 E3FD +FCF3 E3FE +FCF4 E3FF +FCF5 E400 +FCF6 E401 +FCF7 E402 +FCF8 E403 +FCF9 E404 +FCFA E405 +FCFB E406 +FCFC E407 +FCFD E408 +FCFE E409 +FDA1 E40A +FDA2 E40B +FDA3 E40C +FDA4 E40D +FDA5 E40E +FDA6 E40F +FDA7 E410 +FDA8 E411 +FDA9 E412 +FDAA E413 +FDAB E414 +FDAC E415 +FDAD E416 +FDAE E417 +FDAF E418 +FDB0 E419 +FDB1 E41A +FDB2 E41B +FDB3 E41C +FDB4 E41D +FDB5 E41E +FDB6 E41F +FDB7 E420 +FDB8 E421 +FDB9 E422 +FDBA E423 +FDBB E424 +FDBC E425 +FDBD E426 +FDBE E427 +FDBF E428 +FDC0 E429 +FDC1 E42A +FDC2 E42B +FDC3 E42C +FDC4 E42D +FDC5 E42E +FDC6 E42F +FDC7 E430 +FDC8 E431 +FDC9 E432 +FDCA E433 +FDCB E434 +FDCC E435 +FDCD E436 +FDCE E437 +FDCF E438 +FDD0 E439 +FDD1 E43A +FDD2 E43B +FDD3 E43C +FDD4 E43D +FDD5 E43E +FDD6 E43F +FDD7 E440 +FDD8 E441 +FDD9 E442 +FDDA E443 +FDDB E444 +FDDC E445 +FDDD E446 +FDDE E447 +FDDF E448 +FDE0 E449 +FDE1 E44A +FDE2 E44B +FDE3 E44C +FDE4 E44D +FDE5 E44E +FDE6 E44F +FDE7 E450 +FDE8 E451 +FDE9 E452 +FDEA E453 +FDEB E454 +FDEC E455 +FDED E456 +FDEE E457 +FDEF E458 +FDF0 E459 +FDF1 E45A +FDF2 E45B +FDF3 E45C +FDF4 E45D +FDF5 E45E +FDF6 E45F +FDF7 E460 +FDF8 E461 +FDF9 E462 +FDFA E463 +FDFB E464 +FDFC E465 +FDFD E466 +FDFE E467 +FEA1 E468 +FEA2 E469 +FEA3 E46A +FEA4 E46B +FEA5 E46C +FEA6 E46D +FEA7 E46E +FEA8 E46F +FEA9 E470 +FEAA E471 +FEAB E472 +FEAC E473 +FEAD E474 +FEAE E475 +FEAF E476 +FEB0 E477 +FEB1 E478 +FEB2 E479 +FEB3 E47A +FEB4 E47B +FEB5 E47C +FEB6 E47D +FEB7 E47E +FEB8 E47F +FEB9 E480 +FEBA E481 +FEBB E482 +FEBC E483 +FEBD E484 +FEBE E485 +FEBF E486 +FEC0 E487 +FEC1 E488 +FEC2 E489 +FEC3 E48A +FEC4 E48B +FEC5 E48C +FEC6 E48D +FEC7 E48E +FEC8 E48F +FEC9 E490 +FECA E491 +FECB E492 +FECC E493 +FECD E494 +FECE E495 +FECF E496 +FED0 E497 +FED1 E498 +FED2 E499 +FED3 E49A +FED4 E49B +FED5 E49C +FED6 E49D +FED7 E49E +FED8 E49F +FED9 E4A0 +FEDA E4A1 +FEDB E4A2 +FEDC E4A3 +FEDD E4A4 +FEDE E4A5 +FEDF E4A6 +FEE0 E4A7 +FEE1 E4A8 +FEE2 E4A9 +FEE3 E4AA +FEE4 E4AB +FEE5 E4AC +FEE6 E4AD +FEE7 E4AE +FEE8 E4AF +FEE9 E4B0 +FEEA E4B1 +FEEB E4B2 +FEEC E4B3 +FEED E4B4 +FEEE E4B5 +FEEF E4B6 +FEF0 E4B7 +FEF1 E4B8 +FEF2 E4B9 +FEF3 E4BA +FEF4 E4BB +FEF5 E4BC +FEF6 E4BD +FEF7 E4BE +FEF8 E4BF +FEF9 E4C0 +FEFA E4C1 +FEFB E4C2 +FEFC E4C3 +FEFD E4C4 +FEFE E4C5 +A140 E4C6 +A141 E4C7 +A142 E4C8 +A143 E4C9 +A144 E4CA +A145 E4CB +A146 E4CC +A147 E4CD +A148 E4CE +A149 E4CF +A14A E4D0 +A14B E4D1 +A14C E4D2 +A14D E4D3 +A14E E4D4 +A14F E4D5 +A150 E4D6 +A151 E4D7 +A152 E4D8 +A153 E4D9 +A154 E4DA +A155 E4DB +A156 E4DC +A157 E4DD +A158 E4DE +A159 E4DF +A15A E4E0 +A15B E4E1 +A15C E4E2 +A15D E4E3 +A15E E4E4 +A15F E4E5 +A160 E4E6 +A161 E4E7 +A162 E4E8 +A163 E4E9 +A164 E4EA +A165 E4EB +A166 E4EC +A167 E4ED +A168 E4EE +A169 E4EF +A16A E4F0 +A16B E4F1 +A16C E4F2 +A16D E4F3 +A16E E4F4 +A16F E4F5 +A170 E4F6 +A171 E4F7 +A172 E4F8 +A173 E4F9 +A174 E4FA +A175 E4FB +A176 E4FC +A177 E4FD +A178 E4FE +A179 E4FF +A17A E500 +A17B E501 +A17C E502 +A17D E503 +A17E E504 +A180 E505 +A181 E506 +A182 E507 +A183 E508 +A184 E509 +A185 E50A +A186 E50B +A187 E50C +A188 E50D +A189 E50E +A18A E50F +A18B E510 +A18C E511 +A18D E512 +A18E E513 +A18F E514 +A190 E515 +A191 E516 +A192 E517 +A193 E518 +A194 E519 +A195 E51A +A196 E51B +A197 E51C +A198 E51D +A199 E51E +A19A E51F +A19B E520 +A19C E521 +A19D E522 +A19E E523 +A19F E524 +A1A0 E525 +A240 E526 +A241 E527 +A242 E528 +A243 E529 +A244 E52A +A245 E52B +A246 E52C +A247 E52D +A248 E52E +A249 E52F +A24A E530 +A24B E531 +A24C E532 +A24D E533 +A24E E534 +A24F E535 +A250 E536 +A251 E537 +A252 E538 +A253 E539 +A254 E53A +A255 E53B +A256 E53C +A257 E53D +A258 E53E +A259 E53F +A25A E540 +A25B E541 +A25C E542 +A25D E543 +A25E E544 +A25F E545 +A260 E546 +A261 E547 +A262 E548 +A263 E549 +A264 E54A +A265 E54B +A266 E54C +A267 E54D +A268 E54E +A269 E54F +A26A E550 +A26B E551 +A26C E552 +A26D E553 +A26E E554 +A26F E555 +A270 E556 +A271 E557 +A272 E558 +A273 E559 +A274 E55A +A275 E55B +A276 E55C +A277 E55D +A278 E55E +A279 E55F +A27A E560 +A27B E561 +A27C E562 +A27D E563 +A27E E564 +A280 E565 +A281 E566 +A282 E567 +A283 E568 +A284 E569 +A285 E56A +A286 E56B +A287 E56C +A288 E56D +A289 E56E +A28A E56F +A28B E570 +A28C E571 +A28D E572 +A28E E573 +A28F E574 +A290 E575 +A291 E576 +A292 E577 +A293 E578 +A294 E579 +A295 E57A +A296 E57B +A297 E57C +A298 E57D +A299 E57E +A29A E57F +A29B E580 +A29C E581 +A29D E582 +A29E E583 +A29F E584 +A2A0 E585 +A340 E586 +A341 E587 +A342 E588 +A343 E589 +A344 E58A +A345 E58B +A346 E58C +A347 E58D +A348 E58E +A349 E58F +A34A E590 +A34B E591 +A34C E592 +A34D E593 +A34E E594 +A34F E595 +A350 E596 +A351 E597 +A352 E598 +A353 E599 +A354 E59A +A355 E59B +A356 E59C +A357 E59D +A358 E59E +A359 E59F +A35A E5A0 +A35B E5A1 +A35C E5A2 +A35D E5A3 +A35E E5A4 +A35F E5A5 +A360 E5A6 +A361 E5A7 +A362 E5A8 +A363 E5A9 +A364 E5AA +A365 E5AB +A366 E5AC +A367 E5AD +A368 E5AE +A369 E5AF +A36A E5B0 +A36B E5B1 +A36C E5B2 +A36D E5B3 +A36E E5B4 +A36F E5B5 +A370 E5B6 +A371 E5B7 +A372 E5B8 +A373 E5B9 +A374 E5BA +A375 E5BB +A376 E5BC +A377 E5BD +A378 E5BE +A379 E5BF +A37A E5C0 +A37B E5C1 +A37C E5C2 +A37D E5C3 +A37E E5C4 +A380 E5C5 +A381 E5C6 +A382 E5C7 +A383 E5C8 +A384 E5C9 +A385 E5CA +A386 E5CB +A387 E5CC +A388 E5CD +A389 E5CE +A38A E5CF +A38B E5D0 +A38C E5D1 +A38D E5D2 +A38E E5D3 +A38F E5D4 +A390 E5D5 +A391 E5D6 +A392 E5D7 +A393 E5D8 +A394 E5D9 +A395 E5DA +A396 E5DB +A397 E5DC +A398 E5DD +A399 E5DE +A39A E5DF +A39B E5E0 +A39C E5E1 +A39D E5E2 +A39E E5E3 +A39F E5E4 +A3A0 E5E5 +A440 E5E6 +A441 E5E7 +A442 E5E8 +A443 E5E9 +A444 E5EA +A445 E5EB +A446 E5EC +A447 E5ED +A448 E5EE +A449 E5EF +A44A E5F0 +A44B E5F1 +A44C E5F2 +A44D E5F3 +A44E E5F4 +A44F E5F5 +A450 E5F6 +A451 E5F7 +A452 E5F8 +A453 E5F9 +A454 E5FA +A455 E5FB +A456 E5FC +A457 E5FD +A458 E5FE +A459 E5FF +A45A E600 +A45B E601 +A45C E602 +A45D E603 +A45E E604 +A45F E605 +A460 E606 +A461 E607 +A462 E608 +A463 E609 +A464 E60A +A465 E60B +A466 E60C +A467 E60D +A468 E60E +A469 E60F +A46A E610 +A46B E611 +A46C E612 +A46D E613 +A46E E614 +A46F E615 +A470 E616 +A471 E617 +A472 E618 +A473 E619 +A474 E61A +A475 E61B +A476 E61C +A477 E61D +A478 E61E +A479 E61F +A47A E620 +A47B E621 +A47C E622 +A47D E623 +A47E E624 +A480 E625 +A481 E626 +A482 E627 +A483 E628 +A484 E629 +A485 E62A +A486 E62B +A487 E62C +A488 E62D +A489 E62E +A48A E62F +A48B E630 +A48C E631 +A48D E632 +A48E E633 +A48F E634 +A490 E635 +A491 E636 +A492 E637 +A493 E638 +A494 E639 +A495 E63A +A496 E63B +A497 E63C +A498 E63D +A499 E63E +A49A E63F +A49B E640 +A49C E641 +A49D E642 +A49E E643 +A49F E644 +A4A0 E645 +A540 E646 +A541 E647 +A542 E648 +A543 E649 +A544 E64A +A545 E64B +A546 E64C +A547 E64D +A548 E64E +A549 E64F +A54A E650 +A54B E651 +A54C E652 +A54D E653 +A54E E654 +A54F E655 +A550 E656 +A551 E657 +A552 E658 +A553 E659 +A554 E65A +A555 E65B +A556 E65C +A557 E65D +A558 E65E +A559 E65F +A55A E660 +A55B E661 +A55C E662 +A55D E663 +A55E E664 +A55F E665 +A560 E666 +A561 E667 +A562 E668 +A563 E669 +A564 E66A +A565 E66B +A566 E66C +A567 E66D +A568 E66E +A569 E66F +A56A E670 +A56B E671 +A56C E672 +A56D E673 +A56E E674 +A56F E675 +A570 E676 +A571 E677 +A572 E678 +A573 E679 +A574 E67A +A575 E67B +A576 E67C +A577 E67D +A578 E67E +A579 E67F +A57A E680 +A57B E681 +A57C E682 +A57D E683 +A57E E684 +A580 E685 +A581 E686 +A582 E687 +A583 E688 +A584 E689 +A585 E68A +A586 E68B +A587 E68C +A588 E68D +A589 E68E +A58A E68F +A58B E690 +A58C E691 +A58D E692 +A58E E693 +A58F E694 +A590 E695 +A591 E696 +A592 E697 +A593 E698 +A594 E699 +A595 E69A +A596 E69B +A597 E69C +A598 E69D +A599 E69E +A59A E69F +A59B E6A0 +A59C E6A1 +A59D E6A2 +A59E E6A3 +A59F E6A4 +A5A0 E6A5 +A640 E6A6 +A641 E6A7 +A642 E6A8 +A643 E6A9 +A644 E6AA +A645 E6AB +A646 E6AC +A647 E6AD +A648 E6AE +A649 E6AF +A64A E6B0 +A64B E6B1 +A64C E6B2 +A64D E6B3 +A64E E6B4 +A64F E6B5 +A650 E6B6 +A651 E6B7 +A652 E6B8 +A653 E6B9 +A654 E6BA +A655 E6BB +A656 E6BC +A657 E6BD +A658 E6BE +A659 E6BF +A65A E6C0 +A65B E6C1 +A65C E6C2 +A65D E6C3 +A65E E6C4 +A65F E6C5 +A660 E6C6 +A661 E6C7 +A662 E6C8 +A663 E6C9 +A664 E6CA +A665 E6CB +A666 E6CC +A667 E6CD +A668 E6CE +A669 E6CF +A66A E6D0 +A66B E6D1 +A66C E6D2 +A66D E6D3 +A66E E6D4 +A66F E6D5 +A670 E6D6 +A671 E6D7 +A672 E6D8 +A673 E6D9 +A674 E6DA +A675 E6DB +A676 E6DC +A677 E6DD +A678 E6DE +A679 E6DF +A67A E6E0 +A67B E6E1 +A67C E6E2 +A67D E6E3 +A67E E6E4 +A680 E6E5 +A681 E6E6 +A682 E6E7 +A683 E6E8 +A684 E6E9 +A685 E6EA +A686 E6EB +A687 E6EC +A688 E6ED +A689 E6EE +A68A E6EF +A68B E6F0 +A68C E6F1 +A68D E6F2 +A68E E6F3 +A68F E6F4 +A690 E6F5 +A691 E6F6 +A692 E6F7 +A693 E6F8 +A694 E6F9 +A695 E6FA +A696 E6FB +A697 E6FC +A698 E6FD +A699 E6FE +A69A E6FF +A69B E700 +A69C E701 +A69D E702 +A69E E703 +A69F E704 +A6A0 E705 +A740 E706 +A741 E707 +A742 E708 +A743 E709 +A744 E70A +A745 E70B +A746 E70C +A747 E70D +A748 E70E +A749 E70F +A74A E710 +A74B E711 +A74C E712 +A74D E713 +A74E E714 +A74F E715 +A750 E716 +A751 E717 +A752 E718 +A753 E719 +A754 E71A +A755 E71B +A756 E71C +A757 E71D +A758 E71E +A759 E71F +A75A E720 +A75B E721 +A75C E722 +A75D E723 +A75E E724 +A75F E725 +A760 E726 +A761 E727 +A762 E728 +A763 E729 +A764 E72A +A765 E72B +A766 E72C +A767 E72D +A768 E72E +A769 E72F +A76A E730 +A76B E731 +A76C E732 +A76D E733 +A76E E734 +A76F E735 +A770 E736 +A771 E737 +A772 E738 +A773 E739 +A774 E73A +A775 E73B +A776 E73C +A777 E73D +A778 E73E +A779 E73F +A77A E740 +A77B E741 +A77C E742 +A77D E743 +A77E E744 +A780 E745 +A781 E746 +A782 E747 +A783 E748 +A784 E749 +A785 E74A +A786 E74B +A787 E74C +A788 E74D +A789 E74E +A78A E74F +A78B E750 +A78C E751 +A78D E752 +A78E E753 +A78F E754 +A790 E755 +A791 E756 +A792 E757 +A793 E758 +A794 E759 +A795 E75A +A796 E75B +A797 E75C +A798 E75D +A799 E75E +A79A E75F +A79B E760 +A79C E761 +A79D E762 +A79E E763 +A79F E764 +A7A0 E765 +A2AB E766 +A2AC E767 +A2AD E768 +A2AE E769 +A2AF E76A +A2B0 E76B +8336C739 E76C +A2E4 E76D +A2EF E76E +A2F0 E76F +A2FD E770 +A2FE E771 +A4F4 E772 +A4F5 E773 +A4F6 E774 +A4F7 E775 +A4F8 E776 +A4F9 E777 +A4FA E778 +A4FB E779 +A4FC E77A +A4FD E77B +A4FE E77C +A5F7 E77D +A5F8 E77E +A5F9 E77F +A5FA E780 +A5FB E781 +A5FC E782 +A5FD E783 +A5FE E784 +A6B9 E785 +A6BA E786 +A6BB E787 +A6BC E788 +A6BD E789 +A6BE E78A +A6BF E78B +A6C0 E78C +A6D9 E78D +A6DA E78E +A6DB E78F +A6DC E790 +A6DD E791 +A6DE E792 +A6DF E793 +A6EC E794 +A6ED E795 +A6F3 E796 +A6F6 E797 +A6F7 E798 +A6F8 E799 +A6F9 E79A +A6FA E79B +A6FB E79C +A6FC E79D +A6FD E79E +A6FE E79F +A7C2 E7A0 +A7C3 E7A1 +A7C4 E7A2 +A7C5 E7A3 +A7C6 E7A4 +A7C7 E7A5 +A7C8 E7A6 +A7C9 E7A7 +A7CA E7A8 +A7CB E7A9 +A7CC E7AA +A7CD E7AB +A7CE E7AC +A7CF E7AD +A7D0 E7AE +A7F2 E7AF +A7F3 E7B0 +A7F4 E7B1 +A7F5 E7B2 +A7F6 E7B3 +A7F7 E7B4 +A7F8 E7B5 +A7F9 E7B6 +A7FA E7B7 +A7FB E7B8 +A7FC E7B9 +A7FD E7BA +A7FE E7BB +A896 E7BC +A897 E7BD +A898 E7BE +A899 E7BF +A89A E7C0 +A89B E7C1 +A89C E7C2 +A89D E7C3 +A89E E7C4 +A89F E7C5 +A8A0 E7C6 +A8BC E7C7 +8336C830 E7C8 +A8C1 E7C9 +A8C2 E7CA +A8C3 E7CB +A8C4 E7CC +A8EA E7CD +A8EB E7CE +A8EC E7CF +A8ED E7D0 +A8EE E7D1 +A8EF E7D2 +A8F0 E7D3 +A8F1 E7D4 +A8F2 E7D5 +A8F3 E7D6 +A8F4 E7D7 +A8F5 E7D8 +A8F6 E7D9 +A8F7 E7DA +A8F8 E7DB +A8F9 E7DC +A8FA E7DD +A8FB E7DE +A8FC E7DF +A8FD E7E0 +A8FE E7E1 +A958 E7E2 +A95B E7E3 +A95D E7E4 +A95E E7E5 +A95F E7E6 +8336C831 E7E7 +8336C832 E7E8 +8336C833 E7E9 +8336C834 E7EA +8336C835 E7EB +8336C836 E7EC +8336C837 E7ED +8336C838 E7EE +8336C839 E7EF +8336C930 E7F0 +8336C931 E7F1 +8336C932 E7F2 +8336C933 E7F3 +A997 E7F4 +A998 E7F5 +A999 E7F6 +A99A E7F7 +A99B E7F8 +A99C E7F9 +A99D E7FA +A99E E7FB +A99F E7FC +A9A0 E7FD +A9A1 E7FE +A9A2 E7FF +A9A3 E800 +A9F0 E801 +A9F1 E802 +A9F2 E803 +A9F3 E804 +A9F4 E805 +A9F5 E806 +A9F6 E807 +A9F7 E808 +A9F8 E809 +A9F9 E80A +A9FA E80B +A9FB E80C +A9FC E80D +A9FD E80E +A9FE E80F +D7FA E810 +D7FB E811 +D7FC E812 +D7FD E813 +D7FE E814 +8336C934 E815 +FE51 E816 +FE52 E817 +FE53 E818 +8336C935 E819 +8336C936 E81A +8336C937 E81B +8336C938 E81C +8336C939 E81D +FE59 E81E +8336CA30 E81F +8336CA31 E820 +8336CA32 E821 +8336CA33 E822 +8336CA34 E823 +8336CA35 E824 +8336CA36 E825 +FE61 E826 +8336CA37 E827 +8336CA38 E828 +8336CA39 E829 +8336CB30 E82A +FE66 E82B +FE67 E82C +8336CB31 E82D +8336CB32 E82E +8336CB33 E82F +8336CB34 E830 +FE6C E831 +FE6D E832 +8336CB35 E833 +8336CB36 E834 +8336CB37 E835 +8336CB38 E836 +8336CB39 E837 +8336CC30 E838 +8336CC31 E839 +8336CC32 E83A +FE76 E83B +8336CC33 E83C +8336CC34 E83D +8336CC35 E83E +8336CC36 E83F +8336CC37 E840 +8336CC38 E841 +8336CC39 E842 +FE7E E843 +8336CD30 E844 +8336CD31 E845 +8336CD32 E846 +8336CD33 E847 +8336CD34 E848 +8336CD35 E849 +8336CD36 E84A +8336CD37 E84B +8336CD38 E84C +8336CD39 E84D +8336CE30 E84E +8336CE31 E84F +8336CE32 E850 +8336CE33 E851 +8336CE34 E852 +8336CE35 E853 +FE90 E854 +FE91 E855 +8336CE36 E856 +8336CE37 E857 +8336CE38 E858 +8336CE39 E859 +8336CF30 E85A +8336CF31 E85B +8336CF32 E85C +8336CF33 E85D +8336CF34 E85E +8336CF35 E85F +8336CF36 E860 +8336CF37 E861 +8336CF38 E862 +8336CF39 E863 +FEA0 E864 +8336D030 E865 +8336D031 E866 +8336D032 E867 +8336D033 E868 +8336D034 E869 +8336D035 E86A +8336D036 E86B +8336D037 E86C +8336D038 E86D +8336D039 E86E +8336D130 E86F +8336D131 E870 +8336D132 E871 +8336D133 E872 +8336D134 E873 +8336D135 E874 +8336D136 E875 +8336D137 E876 +8336D138 E877 +8336D139 E878 +8336D230 E879 +8336D231 E87A +8336D232 E87B +8336D233 E87C +8336D234 E87D +8336D235 E87E +8336D236 E87F +8336D237 E880 +8336D238 E881 +8336D239 E882 +8336D330 E883 +8336D331 E884 +8336D332 E885 +8336D333 E886 +8336D334 E887 +8336D335 E888 +8336D336 E889 +8336D337 E88A +8336D338 E88B +8336D339 E88C +8336D430 E88D +8336D431 E88E +8336D432 E88F +8336D433 E890 +8336D434 E891 +8336D435 E892 +8336D436 E893 +8336D437 E894 +8336D438 E895 +8336D439 E896 +8336D530 E897 +8336D531 E898 +8336D532 E899 +8336D533 E89A +8336D534 E89B +8336D535 E89C +8336D536 E89D +8336D537 E89E +8336D538 E89F +8336D539 E8A0 +8336D630 E8A1 +8336D631 E8A2 +8336D632 E8A3 +8336D633 E8A4 +8336D634 E8A5 +8336D635 E8A6 +8336D636 E8A7 +8336D637 E8A8 +8336D638 E8A9 +8336D639 E8AA +8336D730 E8AB +8336D731 E8AC +8336D732 E8AD +8336D733 E8AE +8336D734 E8AF +8336D735 E8B0 +8336D736 E8B1 +8336D737 E8B2 +8336D738 E8B3 +8336D739 E8B4 +8336D830 E8B5 +8336D831 E8B6 +8336D832 E8B7 +8336D833 E8B8 +8336D834 E8B9 +8336D835 E8BA +8336D836 E8BB +8336D837 E8BC +8336D838 E8BD +8336D839 E8BE +8336D930 E8BF +8336D931 E8C0 +8336D932 E8C1 +8336D933 E8C2 +8336D934 E8C3 +8336D935 E8C4 +8336D936 E8C5 +8336D937 E8C6 +8336D938 E8C7 +8336D939 E8C8 +8336DA30 E8C9 +8336DA31 E8CA +8336DA32 E8CB +8336DA33 E8CC +8336DA34 E8CD +8336DA35 E8CE +8336DA36 E8CF +8336DA37 E8D0 +8336DA38 E8D1 +8336DA39 E8D2 +8336DB30 E8D3 +8336DB31 E8D4 +8336DB32 E8D5 +8336DB33 E8D6 +8336DB34 E8D7 +8336DB35 E8D8 +8336DB36 E8D9 +8336DB37 E8DA +8336DB38 E8DB +8336DB39 E8DC +8336DC30 E8DD +8336DC31 E8DE +8336DC32 E8DF +8336DC33 E8E0 +8336DC34 E8E1 +8336DC35 E8E2 +8336DC36 E8E3 +8336DC37 E8E4 +8336DC38 E8E5 +8336DC39 E8E6 +8336DD30 E8E7 +8336DD31 E8E8 +8336DD32 E8E9 +8336DD33 E8EA +8336DD34 E8EB +8336DD35 E8EC +8336DD36 E8ED +8336DD37 E8EE +8336DD38 E8EF +8336DD39 E8F0 +8336DE30 E8F1 +8336DE31 E8F2 +8336DE32 E8F3 +8336DE33 E8F4 +8336DE34 E8F5 +8336DE35 E8F6 +8336DE36 E8F7 +8336DE37 E8F8 +8336DE38 E8F9 +8336DE39 E8FA +8336DF30 E8FB +8336DF31 E8FC +8336DF32 E8FD +8336DF33 E8FE +8336DF34 E8FF +8336DF35 E900 +8336DF36 E901 +8336DF37 E902 +8336DF38 E903 +8336DF39 E904 +8336E030 E905 +8336E031 E906 +8336E032 E907 +8336E033 E908 +8336E034 E909 +8336E035 E90A +8336E036 E90B +8336E037 E90C +8336E038 E90D +8336E039 E90E +8336E130 E90F +8336E131 E910 +8336E132 E911 +8336E133 E912 +8336E134 E913 +8336E135 E914 +8336E136 E915 +8336E137 E916 +8336E138 E917 +8336E139 E918 +8336E230 E919 +8336E231 E91A +8336E232 E91B +8336E233 E91C +8336E234 E91D +8336E235 E91E +8336E236 E91F +8336E237 E920 +8336E238 E921 +8336E239 E922 +8336E330 E923 +8336E331 E924 +8336E332 E925 +8336E333 E926 +8336E334 E927 +8336E335 E928 +8336E336 E929 +8336E337 E92A +8336E338 E92B +8336E339 E92C +8336E430 E92D +8336E431 E92E +8336E432 E92F +8336E433 E930 +8336E434 E931 +8336E435 E932 +8336E436 E933 +8336E437 E934 +8336E438 E935 +8336E439 E936 +8336E530 E937 +8336E531 E938 +8336E532 E939 +8336E533 E93A +8336E534 E93B +8336E535 E93C +8336E536 E93D +8336E537 E93E +8336E538 E93F +8336E539 E940 +8336E630 E941 +8336E631 E942 +8336E632 E943 +8336E633 E944 +8336E634 E945 +8336E635 E946 +8336E636 E947 +8336E637 E948 +8336E638 E949 +8336E639 E94A +8336E730 E94B +8336E731 E94C +8336E732 E94D +8336E733 E94E +8336E734 E94F +8336E735 E950 +8336E736 E951 +8336E737 E952 +8336E738 E953 +8336E739 E954 +8336E830 E955 +8336E831 E956 +8336E832 E957 +8336E833 E958 +8336E834 E959 +8336E835 E95A +8336E836 E95B +8336E837 E95C +8336E838 E95D +8336E839 E95E +8336E930 E95F +8336E931 E960 +8336E932 E961 +8336E933 E962 +8336E934 E963 +8336E935 E964 +8336E936 E965 +8336E937 E966 +8336E938 E967 +8336E939 E968 +8336EA30 E969 +8336EA31 E96A +8336EA32 E96B +8336EA33 E96C +8336EA34 E96D +8336EA35 E96E +8336EA36 E96F +8336EA37 E970 +8336EA38 E971 +8336EA39 E972 +8336EB30 E973 +8336EB31 E974 +8336EB32 E975 +8336EB33 E976 +8336EB34 E977 +8336EB35 E978 +8336EB36 E979 +8336EB37 E97A +8336EB38 E97B +8336EB39 E97C +8336EC30 E97D +8336EC31 E97E +8336EC32 E97F +8336EC33 E980 +8336EC34 E981 +8336EC35 E982 +8336EC36 E983 +8336EC37 E984 +8336EC38 E985 +8336EC39 E986 +8336ED30 E987 +8336ED31 E988 +8336ED32 E989 +8336ED33 E98A +8336ED34 E98B +8336ED35 E98C +8336ED36 E98D +8336ED37 E98E +8336ED38 E98F +8336ED39 E990 +8336EE30 E991 +8336EE31 E992 +8336EE32 E993 +8336EE33 E994 +8336EE34 E995 +8336EE35 E996 +8336EE36 E997 +8336EE37 E998 +8336EE38 E999 +8336EE39 E99A +8336EF30 E99B +8336EF31 E99C +8336EF32 E99D +8336EF33 E99E +8336EF34 E99F +8336EF35 E9A0 +8336EF36 E9A1 +8336EF37 E9A2 +8336EF38 E9A3 +8336EF39 E9A4 +8336F030 E9A5 +8336F031 E9A6 +8336F032 E9A7 +8336F033 E9A8 +8336F034 E9A9 +8336F035 E9AA +8336F036 E9AB +8336F037 E9AC +8336F038 E9AD +8336F039 E9AE +8336F130 E9AF +8336F131 E9B0 +8336F132 E9B1 +8336F133 E9B2 +8336F134 E9B3 +8336F135 E9B4 +8336F136 E9B5 +8336F137 E9B6 +8336F138 E9B7 +8336F139 E9B8 +8336F230 E9B9 +8336F231 E9BA +8336F232 E9BB +8336F233 E9BC +8336F234 E9BD +8336F235 E9BE +8336F236 E9BF +8336F237 E9C0 +8336F238 E9C1 +8336F239 E9C2 +8336F330 E9C3 +8336F331 E9C4 +8336F332 E9C5 +8336F333 E9C6 +8336F334 E9C7 +8336F335 E9C8 +8336F336 E9C9 +8336F337 E9CA +8336F338 E9CB +8336F339 E9CC +8336F430 E9CD +8336F431 E9CE +8336F432 E9CF +8336F433 E9D0 +8336F434 E9D1 +8336F435 E9D2 +8336F436 E9D3 +8336F437 E9D4 +8336F438 E9D5 +8336F439 E9D6 +8336F530 E9D7 +8336F531 E9D8 +8336F532 E9D9 +8336F533 E9DA +8336F534 E9DB +8336F535 E9DC +8336F536 E9DD +8336F537 E9DE +8336F538 E9DF +8336F539 E9E0 +8336F630 E9E1 +8336F631 E9E2 +8336F632 E9E3 +8336F633 E9E4 +8336F634 E9E5 +8336F635 E9E6 +8336F636 E9E7 +8336F637 E9E8 +8336F638 E9E9 +8336F639 E9EA +8336F730 E9EB +8336F731 E9EC +8336F732 E9ED +8336F733 E9EE +8336F734 E9EF +8336F735 E9F0 +8336F736 E9F1 +8336F737 E9F2 +8336F738 E9F3 +8336F739 E9F4 +8336F830 E9F5 +8336F831 E9F6 +8336F832 E9F7 +8336F833 E9F8 +8336F834 E9F9 +8336F835 E9FA +8336F836 E9FB +8336F837 E9FC +8336F838 E9FD +8336F839 E9FE +8336F930 E9FF +8336F931 EA00 +8336F932 EA01 +8336F933 EA02 +8336F934 EA03 +8336F935 EA04 +8336F936 EA05 +8336F937 EA06 +8336F938 EA07 +8336F939 EA08 +8336FA30 EA09 +8336FA31 EA0A +8336FA32 EA0B +8336FA33 EA0C +8336FA34 EA0D +8336FA35 EA0E +8336FA36 EA0F +8336FA37 EA10 +8336FA38 EA11 +8336FA39 EA12 +8336FB30 EA13 +8336FB31 EA14 +8336FB32 EA15 +8336FB33 EA16 +8336FB34 EA17 +8336FB35 EA18 +8336FB36 EA19 +8336FB37 EA1A +8336FB38 EA1B +8336FB39 EA1C +8336FC30 EA1D +8336FC31 EA1E +8336FC32 EA1F +8336FC33 EA20 +8336FC34 EA21 +8336FC35 EA22 +8336FC36 EA23 +8336FC37 EA24 +8336FC38 EA25 +8336FC39 EA26 +8336FD30 EA27 +8336FD31 EA28 +8336FD32 EA29 +8336FD33 EA2A +8336FD34 EA2B +8336FD35 EA2C +8336FD36 EA2D +8336FD37 EA2E +8336FD38 EA2F +8336FD39 EA30 +8336FE30 EA31 +8336FE31 EA32 +8336FE32 EA33 +8336FE33 EA34 +8336FE34 EA35 +8336FE35 EA36 +8336FE36 EA37 +8336FE37 EA38 +8336FE38 EA39 +8336FE39 EA3A +83378130 EA3B +83378131 EA3C +83378132 EA3D +83378133 EA3E +83378134 EA3F +83378135 EA40 +83378136 EA41 +83378137 EA42 +83378138 EA43 +83378139 EA44 +83378230 EA45 +83378231 EA46 +83378232 EA47 +83378233 EA48 +83378234 EA49 +83378235 EA4A +83378236 EA4B +83378237 EA4C +83378238 EA4D +83378239 EA4E +83378330 EA4F +83378331 EA50 +83378332 EA51 +83378333 EA52 +83378334 EA53 +83378335 EA54 +83378336 EA55 +83378337 EA56 +83378338 EA57 +83378339 EA58 +83378430 EA59 +83378431 EA5A +83378432 EA5B +83378433 EA5C +83378434 EA5D +83378435 EA5E +83378436 EA5F +83378437 EA60 +83378438 EA61 +83378439 EA62 +83378530 EA63 +83378531 EA64 +83378532 EA65 +83378533 EA66 +83378534 EA67 +83378535 EA68 +83378536 EA69 +83378537 EA6A +83378538 EA6B +83378539 EA6C +83378630 EA6D +83378631 EA6E +83378632 EA6F +83378633 EA70 +83378634 EA71 +83378635 EA72 +83378636 EA73 +83378637 EA74 +83378638 EA75 +83378639 EA76 +83378730 EA77 +83378731 EA78 +83378732 EA79 +83378733 EA7A +83378734 EA7B +83378735 EA7C +83378736 EA7D +83378737 EA7E +83378738 EA7F +83378739 EA80 +83378830 EA81 +83378831 EA82 +83378832 EA83 +83378833 EA84 +83378834 EA85 +83378835 EA86 +83378836 EA87 +83378837 EA88 +83378838 EA89 +83378839 EA8A +83378930 EA8B +83378931 EA8C +83378932 EA8D +83378933 EA8E +83378934 EA8F +83378935 EA90 +83378936 EA91 +83378937 EA92 +83378938 EA93 +83378939 EA94 +83378A30 EA95 +83378A31 EA96 +83378A32 EA97 +83378A33 EA98 +83378A34 EA99 +83378A35 EA9A +83378A36 EA9B +83378A37 EA9C +83378A38 EA9D +83378A39 EA9E +83378B30 EA9F +83378B31 EAA0 +83378B32 EAA1 +83378B33 EAA2 +83378B34 EAA3 +83378B35 EAA4 +83378B36 EAA5 +83378B37 EAA6 +83378B38 EAA7 +83378B39 EAA8 +83378C30 EAA9 +83378C31 EAAA +83378C32 EAAB +83378C33 EAAC +83378C34 EAAD +83378C35 EAAE +83378C36 EAAF +83378C37 EAB0 +83378C38 EAB1 +83378C39 EAB2 +83378D30 EAB3 +83378D31 EAB4 +83378D32 EAB5 +83378D33 EAB6 +83378D34 EAB7 +83378D35 EAB8 +83378D36 EAB9 +83378D37 EABA +83378D38 EABB +83378D39 EABC +83378E30 EABD +83378E31 EABE +83378E32 EABF +83378E33 EAC0 +83378E34 EAC1 +83378E35 EAC2 +83378E36 EAC3 +83378E37 EAC4 +83378E38 EAC5 +83378E39 EAC6 +83378F30 EAC7 +83378F31 EAC8 +83378F32 EAC9 +83378F33 EACA +83378F34 EACB +83378F35 EACC +83378F36 EACD +83378F37 EACE +83378F38 EACF +83378F39 EAD0 +83379030 EAD1 +83379031 EAD2 +83379032 EAD3 +83379033 EAD4 +83379034 EAD5 +83379035 EAD6 +83379036 EAD7 +83379037 EAD8 +83379038 EAD9 +83379039 EADA +83379130 EADB +83379131 EADC +83379132 EADD +83379133 EADE +83379134 EADF +83379135 EAE0 +83379136 EAE1 +83379137 EAE2 +83379138 EAE3 +83379139 EAE4 +83379230 EAE5 +83379231 EAE6 +83379232 EAE7 +83379233 EAE8 +83379234 EAE9 +83379235 EAEA +83379236 EAEB +83379237 EAEC +83379238 EAED +83379239 EAEE +83379330 EAEF +83379331 EAF0 +83379332 EAF1 +83379333 EAF2 +83379334 EAF3 +83379335 EAF4 +83379336 EAF5 +83379337 EAF6 +83379338 EAF7 +83379339 EAF8 +83379430 EAF9 +83379431 EAFA +83379432 EAFB +83379433 EAFC +83379434 EAFD +83379435 EAFE +83379436 EAFF +83379437 EB00 +83379438 EB01 +83379439 EB02 +83379530 EB03 +83379531 EB04 +83379532 EB05 +83379533 EB06 +83379534 EB07 +83379535 EB08 +83379536 EB09 +83379537 EB0A +83379538 EB0B +83379539 EB0C +83379630 EB0D +83379631 EB0E +83379632 EB0F +83379633 EB10 +83379634 EB11 +83379635 EB12 +83379636 EB13 +83379637 EB14 +83379638 EB15 +83379639 EB16 +83379730 EB17 +83379731 EB18 +83379732 EB19 +83379733 EB1A +83379734 EB1B +83379735 EB1C +83379736 EB1D +83379737 EB1E +83379738 EB1F +83379739 EB20 +83379830 EB21 +83379831 EB22 +83379832 EB23 +83379833 EB24 +83379834 EB25 +83379835 EB26 +83379836 EB27 +83379837 EB28 +83379838 EB29 +83379839 EB2A +83379930 EB2B +83379931 EB2C +83379932 EB2D +83379933 EB2E +83379934 EB2F +83379935 EB30 +83379936 EB31 +83379937 EB32 +83379938 EB33 +83379939 EB34 +83379A30 EB35 +83379A31 EB36 +83379A32 EB37 +83379A33 EB38 +83379A34 EB39 +83379A35 EB3A +83379A36 EB3B +83379A37 EB3C +83379A38 EB3D +83379A39 EB3E +83379B30 EB3F +83379B31 EB40 +83379B32 EB41 +83379B33 EB42 +83379B34 EB43 +83379B35 EB44 +83379B36 EB45 +83379B37 EB46 +83379B38 EB47 +83379B39 EB48 +83379C30 EB49 +83379C31 EB4A +83379C32 EB4B +83379C33 EB4C +83379C34 EB4D +83379C35 EB4E +83379C36 EB4F +83379C37 EB50 +83379C38 EB51 +83379C39 EB52 +83379D30 EB53 +83379D31 EB54 +83379D32 EB55 +83379D33 EB56 +83379D34 EB57 +83379D35 EB58 +83379D36 EB59 +83379D37 EB5A +83379D38 EB5B +83379D39 EB5C +83379E30 EB5D +83379E31 EB5E +83379E32 EB5F +83379E33 EB60 +83379E34 EB61 +83379E35 EB62 +83379E36 EB63 +83379E37 EB64 +83379E38 EB65 +83379E39 EB66 +83379F30 EB67 +83379F31 EB68 +83379F32 EB69 +83379F33 EB6A +83379F34 EB6B +83379F35 EB6C +83379F36 EB6D +83379F37 EB6E +83379F38 EB6F +83379F39 EB70 +8337A030 EB71 +8337A031 EB72 +8337A032 EB73 +8337A033 EB74 +8337A034 EB75 +8337A035 EB76 +8337A036 EB77 +8337A037 EB78 +8337A038 EB79 +8337A039 EB7A +8337A130 EB7B +8337A131 EB7C +8337A132 EB7D +8337A133 EB7E +8337A134 EB7F +8337A135 EB80 +8337A136 EB81 +8337A137 EB82 +8337A138 EB83 +8337A139 EB84 +8337A230 EB85 +8337A231 EB86 +8337A232 EB87 +8337A233 EB88 +8337A234 EB89 +8337A235 EB8A +8337A236 EB8B +8337A237 EB8C +8337A238 EB8D +8337A239 EB8E +8337A330 EB8F +8337A331 EB90 +8337A332 EB91 +8337A333 EB92 +8337A334 EB93 +8337A335 EB94 +8337A336 EB95 +8337A337 EB96 +8337A338 EB97 +8337A339 EB98 +8337A430 EB99 +8337A431 EB9A +8337A432 EB9B +8337A433 EB9C +8337A434 EB9D +8337A435 EB9E +8337A436 EB9F +8337A437 EBA0 +8337A438 EBA1 +8337A439 EBA2 +8337A530 EBA3 +8337A531 EBA4 +8337A532 EBA5 +8337A533 EBA6 +8337A534 EBA7 +8337A535 EBA8 +8337A536 EBA9 +8337A537 EBAA +8337A538 EBAB +8337A539 EBAC +8337A630 EBAD +8337A631 EBAE +8337A632 EBAF +8337A633 EBB0 +8337A634 EBB1 +8337A635 EBB2 +8337A636 EBB3 +8337A637 EBB4 +8337A638 EBB5 +8337A639 EBB6 +8337A730 EBB7 +8337A731 EBB8 +8337A732 EBB9 +8337A733 EBBA +8337A734 EBBB +8337A735 EBBC +8337A736 EBBD +8337A737 EBBE +8337A738 EBBF +8337A739 EBC0 +8337A830 EBC1 +8337A831 EBC2 +8337A832 EBC3 +8337A833 EBC4 +8337A834 EBC5 +8337A835 EBC6 +8337A836 EBC7 +8337A837 EBC8 +8337A838 EBC9 +8337A839 EBCA +8337A930 EBCB +8337A931 EBCC +8337A932 EBCD +8337A933 EBCE +8337A934 EBCF +8337A935 EBD0 +8337A936 EBD1 +8337A937 EBD2 +8337A938 EBD3 +8337A939 EBD4 +8337AA30 EBD5 +8337AA31 EBD6 +8337AA32 EBD7 +8337AA33 EBD8 +8337AA34 EBD9 +8337AA35 EBDA +8337AA36 EBDB +8337AA37 EBDC +8337AA38 EBDD +8337AA39 EBDE +8337AB30 EBDF +8337AB31 EBE0 +8337AB32 EBE1 +8337AB33 EBE2 +8337AB34 EBE3 +8337AB35 EBE4 +8337AB36 EBE5 +8337AB37 EBE6 +8337AB38 EBE7 +8337AB39 EBE8 +8337AC30 EBE9 +8337AC31 EBEA +8337AC32 EBEB +8337AC33 EBEC +8337AC34 EBED +8337AC35 EBEE +8337AC36 EBEF +8337AC37 EBF0 +8337AC38 EBF1 +8337AC39 EBF2 +8337AD30 EBF3 +8337AD31 EBF4 +8337AD32 EBF5 +8337AD33 EBF6 +8337AD34 EBF7 +8337AD35 EBF8 +8337AD36 EBF9 +8337AD37 EBFA +8337AD38 EBFB +8337AD39 EBFC +8337AE30 EBFD +8337AE31 EBFE +8337AE32 EBFF +8337AE33 EC00 +8337AE34 EC01 +8337AE35 EC02 +8337AE36 EC03 +8337AE37 EC04 +8337AE38 EC05 +8337AE39 EC06 +8337AF30 EC07 +8337AF31 EC08 +8337AF32 EC09 +8337AF33 EC0A +8337AF34 EC0B +8337AF35 EC0C +8337AF36 EC0D +8337AF37 EC0E +8337AF38 EC0F +8337AF39 EC10 +8337B030 EC11 +8337B031 EC12 +8337B032 EC13 +8337B033 EC14 +8337B034 EC15 +8337B035 EC16 +8337B036 EC17 +8337B037 EC18 +8337B038 EC19 +8337B039 EC1A +8337B130 EC1B +8337B131 EC1C +8337B132 EC1D +8337B133 EC1E +8337B134 EC1F +8337B135 EC20 +8337B136 EC21 +8337B137 EC22 +8337B138 EC23 +8337B139 EC24 +8337B230 EC25 +8337B231 EC26 +8337B232 EC27 +8337B233 EC28 +8337B234 EC29 +8337B235 EC2A +8337B236 EC2B +8337B237 EC2C +8337B238 EC2D +8337B239 EC2E +8337B330 EC2F +8337B331 EC30 +8337B332 EC31 +8337B333 EC32 +8337B334 EC33 +8337B335 EC34 +8337B336 EC35 +8337B337 EC36 +8337B338 EC37 +8337B339 EC38 +8337B430 EC39 +8337B431 EC3A +8337B432 EC3B +8337B433 EC3C +8337B434 EC3D +8337B435 EC3E +8337B436 EC3F +8337B437 EC40 +8337B438 EC41 +8337B439 EC42 +8337B530 EC43 +8337B531 EC44 +8337B532 EC45 +8337B533 EC46 +8337B534 EC47 +8337B535 EC48 +8337B536 EC49 +8337B537 EC4A +8337B538 EC4B +8337B539 EC4C +8337B630 EC4D +8337B631 EC4E +8337B632 EC4F +8337B633 EC50 +8337B634 EC51 +8337B635 EC52 +8337B636 EC53 +8337B637 EC54 +8337B638 EC55 +8337B639 EC56 +8337B730 EC57 +8337B731 EC58 +8337B732 EC59 +8337B733 EC5A +8337B734 EC5B +8337B735 EC5C +8337B736 EC5D +8337B737 EC5E +8337B738 EC5F +8337B739 EC60 +8337B830 EC61 +8337B831 EC62 +8337B832 EC63 +8337B833 EC64 +8337B834 EC65 +8337B835 EC66 +8337B836 EC67 +8337B837 EC68 +8337B838 EC69 +8337B839 EC6A +8337B930 EC6B +8337B931 EC6C +8337B932 EC6D +8337B933 EC6E +8337B934 EC6F +8337B935 EC70 +8337B936 EC71 +8337B937 EC72 +8337B938 EC73 +8337B939 EC74 +8337BA30 EC75 +8337BA31 EC76 +8337BA32 EC77 +8337BA33 EC78 +8337BA34 EC79 +8337BA35 EC7A +8337BA36 EC7B +8337BA37 EC7C +8337BA38 EC7D +8337BA39 EC7E +8337BB30 EC7F +8337BB31 EC80 +8337BB32 EC81 +8337BB33 EC82 +8337BB34 EC83 +8337BB35 EC84 +8337BB36 EC85 +8337BB37 EC86 +8337BB38 EC87 +8337BB39 EC88 +8337BC30 EC89 +8337BC31 EC8A +8337BC32 EC8B +8337BC33 EC8C +8337BC34 EC8D +8337BC35 EC8E +8337BC36 EC8F +8337BC37 EC90 +8337BC38 EC91 +8337BC39 EC92 +8337BD30 EC93 +8337BD31 EC94 +8337BD32 EC95 +8337BD33 EC96 +8337BD34 EC97 +8337BD35 EC98 +8337BD36 EC99 +8337BD37 EC9A +8337BD38 EC9B +8337BD39 EC9C +8337BE30 EC9D +8337BE31 EC9E +8337BE32 EC9F +8337BE33 ECA0 +8337BE34 ECA1 +8337BE35 ECA2 +8337BE36 ECA3 +8337BE37 ECA4 +8337BE38 ECA5 +8337BE39 ECA6 +8337BF30 ECA7 +8337BF31 ECA8 +8337BF32 ECA9 +8337BF33 ECAA +8337BF34 ECAB +8337BF35 ECAC +8337BF36 ECAD +8337BF37 ECAE +8337BF38 ECAF +8337BF39 ECB0 +8337C030 ECB1 +8337C031 ECB2 +8337C032 ECB3 +8337C033 ECB4 +8337C034 ECB5 +8337C035 ECB6 +8337C036 ECB7 +8337C037 ECB8 +8337C038 ECB9 +8337C039 ECBA +8337C130 ECBB +8337C131 ECBC +8337C132 ECBD +8337C133 ECBE +8337C134 ECBF +8337C135 ECC0 +8337C136 ECC1 +8337C137 ECC2 +8337C138 ECC3 +8337C139 ECC4 +8337C230 ECC5 +8337C231 ECC6 +8337C232 ECC7 +8337C233 ECC8 +8337C234 ECC9 +8337C235 ECCA +8337C236 ECCB +8337C237 ECCC +8337C238 ECCD +8337C239 ECCE +8337C330 ECCF +8337C331 ECD0 +8337C332 ECD1 +8337C333 ECD2 +8337C334 ECD3 +8337C335 ECD4 +8337C336 ECD5 +8337C337 ECD6 +8337C338 ECD7 +8337C339 ECD8 +8337C430 ECD9 +8337C431 ECDA +8337C432 ECDB +8337C433 ECDC +8337C434 ECDD +8337C435 ECDE +8337C436 ECDF +8337C437 ECE0 +8337C438 ECE1 +8337C439 ECE2 +8337C530 ECE3 +8337C531 ECE4 +8337C532 ECE5 +8337C533 ECE6 +8337C534 ECE7 +8337C535 ECE8 +8337C536 ECE9 +8337C537 ECEA +8337C538 ECEB +8337C539 ECEC +8337C630 ECED +8337C631 ECEE +8337C632 ECEF +8337C633 ECF0 +8337C634 ECF1 +8337C635 ECF2 +8337C636 ECF3 +8337C637 ECF4 +8337C638 ECF5 +8337C639 ECF6 +8337C730 ECF7 +8337C731 ECF8 +8337C732 ECF9 +8337C733 ECFA +8337C734 ECFB +8337C735 ECFC +8337C736 ECFD +8337C737 ECFE +8337C738 ECFF +8337C739 ED00 +8337C830 ED01 +8337C831 ED02 +8337C832 ED03 +8337C833 ED04 +8337C834 ED05 +8337C835 ED06 +8337C836 ED07 +8337C837 ED08 +8337C838 ED09 +8337C839 ED0A +8337C930 ED0B +8337C931 ED0C +8337C932 ED0D +8337C933 ED0E +8337C934 ED0F +8337C935 ED10 +8337C936 ED11 +8337C937 ED12 +8337C938 ED13 +8337C939 ED14 +8337CA30 ED15 +8337CA31 ED16 +8337CA32 ED17 +8337CA33 ED18 +8337CA34 ED19 +8337CA35 ED1A +8337CA36 ED1B +8337CA37 ED1C +8337CA38 ED1D +8337CA39 ED1E +8337CB30 ED1F +8337CB31 ED20 +8337CB32 ED21 +8337CB33 ED22 +8337CB34 ED23 +8337CB35 ED24 +8337CB36 ED25 +8337CB37 ED26 +8337CB38 ED27 +8337CB39 ED28 +8337CC30 ED29 +8337CC31 ED2A +8337CC32 ED2B +8337CC33 ED2C +8337CC34 ED2D +8337CC35 ED2E +8337CC36 ED2F +8337CC37 ED30 +8337CC38 ED31 +8337CC39 ED32 +8337CD30 ED33 +8337CD31 ED34 +8337CD32 ED35 +8337CD33 ED36 +8337CD34 ED37 +8337CD35 ED38 +8337CD36 ED39 +8337CD37 ED3A +8337CD38 ED3B +8337CD39 ED3C +8337CE30 ED3D +8337CE31 ED3E +8337CE32 ED3F +8337CE33 ED40 +8337CE34 ED41 +8337CE35 ED42 +8337CE36 ED43 +8337CE37 ED44 +8337CE38 ED45 +8337CE39 ED46 +8337CF30 ED47 +8337CF31 ED48 +8337CF32 ED49 +8337CF33 ED4A +8337CF34 ED4B +8337CF35 ED4C +8337CF36 ED4D +8337CF37 ED4E +8337CF38 ED4F +8337CF39 ED50 +8337D030 ED51 +8337D031 ED52 +8337D032 ED53 +8337D033 ED54 +8337D034 ED55 +8337D035 ED56 +8337D036 ED57 +8337D037 ED58 +8337D038 ED59 +8337D039 ED5A +8337D130 ED5B +8337D131 ED5C +8337D132 ED5D +8337D133 ED5E +8337D134 ED5F +8337D135 ED60 +8337D136 ED61 +8337D137 ED62 +8337D138 ED63 +8337D139 ED64 +8337D230 ED65 +8337D231 ED66 +8337D232 ED67 +8337D233 ED68 +8337D234 ED69 +8337D235 ED6A +8337D236 ED6B +8337D237 ED6C +8337D238 ED6D +8337D239 ED6E +8337D330 ED6F +8337D331 ED70 +8337D332 ED71 +8337D333 ED72 +8337D334 ED73 +8337D335 ED74 +8337D336 ED75 +8337D337 ED76 +8337D338 ED77 +8337D339 ED78 +8337D430 ED79 +8337D431 ED7A +8337D432 ED7B +8337D433 ED7C +8337D434 ED7D +8337D435 ED7E +8337D436 ED7F +8337D437 ED80 +8337D438 ED81 +8337D439 ED82 +8337D530 ED83 +8337D531 ED84 +8337D532 ED85 +8337D533 ED86 +8337D534 ED87 +8337D535 ED88 +8337D536 ED89 +8337D537 ED8A +8337D538 ED8B +8337D539 ED8C +8337D630 ED8D +8337D631 ED8E +8337D632 ED8F +8337D633 ED90 +8337D634 ED91 +8337D635 ED92 +8337D636 ED93 +8337D637 ED94 +8337D638 ED95 +8337D639 ED96 +8337D730 ED97 +8337D731 ED98 +8337D732 ED99 +8337D733 ED9A +8337D734 ED9B +8337D735 ED9C +8337D736 ED9D +8337D737 ED9E +8337D738 ED9F +8337D739 EDA0 +8337D830 EDA1 +8337D831 EDA2 +8337D832 EDA3 +8337D833 EDA4 +8337D834 EDA5 +8337D835 EDA6 +8337D836 EDA7 +8337D837 EDA8 +8337D838 EDA9 +8337D839 EDAA +8337D930 EDAB +8337D931 EDAC +8337D932 EDAD +8337D933 EDAE +8337D934 EDAF +8337D935 EDB0 +8337D936 EDB1 +8337D937 EDB2 +8337D938 EDB3 +8337D939 EDB4 +8337DA30 EDB5 +8337DA31 EDB6 +8337DA32 EDB7 +8337DA33 EDB8 +8337DA34 EDB9 +8337DA35 EDBA +8337DA36 EDBB +8337DA37 EDBC +8337DA38 EDBD +8337DA39 EDBE +8337DB30 EDBF +8337DB31 EDC0 +8337DB32 EDC1 +8337DB33 EDC2 +8337DB34 EDC3 +8337DB35 EDC4 +8337DB36 EDC5 +8337DB37 EDC6 +8337DB38 EDC7 +8337DB39 EDC8 +8337DC30 EDC9 +8337DC31 EDCA +8337DC32 EDCB +8337DC33 EDCC +8337DC34 EDCD +8337DC35 EDCE +8337DC36 EDCF +8337DC37 EDD0 +8337DC38 EDD1 +8337DC39 EDD2 +8337DD30 EDD3 +8337DD31 EDD4 +8337DD32 EDD5 +8337DD33 EDD6 +8337DD34 EDD7 +8337DD35 EDD8 +8337DD36 EDD9 +8337DD37 EDDA +8337DD38 EDDB +8337DD39 EDDC +8337DE30 EDDD +8337DE31 EDDE +8337DE32 EDDF +8337DE33 EDE0 +8337DE34 EDE1 +8337DE35 EDE2 +8337DE36 EDE3 +8337DE37 EDE4 +8337DE38 EDE5 +8337DE39 EDE6 +8337DF30 EDE7 +8337DF31 EDE8 +8337DF32 EDE9 +8337DF33 EDEA +8337DF34 EDEB +8337DF35 EDEC +8337DF36 EDED +8337DF37 EDEE +8337DF38 EDEF +8337DF39 EDF0 +8337E030 EDF1 +8337E031 EDF2 +8337E032 EDF3 +8337E033 EDF4 +8337E034 EDF5 +8337E035 EDF6 +8337E036 EDF7 +8337E037 EDF8 +8337E038 EDF9 +8337E039 EDFA +8337E130 EDFB +8337E131 EDFC +8337E132 EDFD +8337E133 EDFE +8337E134 EDFF +8337E135 EE00 +8337E136 EE01 +8337E137 EE02 +8337E138 EE03 +8337E139 EE04 +8337E230 EE05 +8337E231 EE06 +8337E232 EE07 +8337E233 EE08 +8337E234 EE09 +8337E235 EE0A +8337E236 EE0B +8337E237 EE0C +8337E238 EE0D +8337E239 EE0E +8337E330 EE0F +8337E331 EE10 +8337E332 EE11 +8337E333 EE12 +8337E334 EE13 +8337E335 EE14 +8337E336 EE15 +8337E337 EE16 +8337E338 EE17 +8337E339 EE18 +8337E430 EE19 +8337E431 EE1A +8337E432 EE1B +8337E433 EE1C +8337E434 EE1D +8337E435 EE1E +8337E436 EE1F +8337E437 EE20 +8337E438 EE21 +8337E439 EE22 +8337E530 EE23 +8337E531 EE24 +8337E532 EE25 +8337E533 EE26 +8337E534 EE27 +8337E535 EE28 +8337E536 EE29 +8337E537 EE2A +8337E538 EE2B +8337E539 EE2C +8337E630 EE2D +8337E631 EE2E +8337E632 EE2F +8337E633 EE30 +8337E634 EE31 +8337E635 EE32 +8337E636 EE33 +8337E637 EE34 +8337E638 EE35 +8337E639 EE36 +8337E730 EE37 +8337E731 EE38 +8337E732 EE39 +8337E733 EE3A +8337E734 EE3B +8337E735 EE3C +8337E736 EE3D +8337E737 EE3E +8337E738 EE3F +8337E739 EE40 +8337E830 EE41 +8337E831 EE42 +8337E832 EE43 +8337E833 EE44 +8337E834 EE45 +8337E835 EE46 +8337E836 EE47 +8337E837 EE48 +8337E838 EE49 +8337E839 EE4A +8337E930 EE4B +8337E931 EE4C +8337E932 EE4D +8337E933 EE4E +8337E934 EE4F +8337E935 EE50 +8337E936 EE51 +8337E937 EE52 +8337E938 EE53 +8337E939 EE54 +8337EA30 EE55 +8337EA31 EE56 +8337EA32 EE57 +8337EA33 EE58 +8337EA34 EE59 +8337EA35 EE5A +8337EA36 EE5B +8337EA37 EE5C +8337EA38 EE5D +8337EA39 EE5E +8337EB30 EE5F +8337EB31 EE60 +8337EB32 EE61 +8337EB33 EE62 +8337EB34 EE63 +8337EB35 EE64 +8337EB36 EE65 +8337EB37 EE66 +8337EB38 EE67 +8337EB39 EE68 +8337EC30 EE69 +8337EC31 EE6A +8337EC32 EE6B +8337EC33 EE6C +8337EC34 EE6D +8337EC35 EE6E +8337EC36 EE6F +8337EC37 EE70 +8337EC38 EE71 +8337EC39 EE72 +8337ED30 EE73 +8337ED31 EE74 +8337ED32 EE75 +8337ED33 EE76 +8337ED34 EE77 +8337ED35 EE78 +8337ED36 EE79 +8337ED37 EE7A +8337ED38 EE7B +8337ED39 EE7C +8337EE30 EE7D +8337EE31 EE7E +8337EE32 EE7F +8337EE33 EE80 +8337EE34 EE81 +8337EE35 EE82 +8337EE36 EE83 +8337EE37 EE84 +8337EE38 EE85 +8337EE39 EE86 +8337EF30 EE87 +8337EF31 EE88 +8337EF32 EE89 +8337EF33 EE8A +8337EF34 EE8B +8337EF35 EE8C +8337EF36 EE8D +8337EF37 EE8E +8337EF38 EE8F +8337EF39 EE90 +8337F030 EE91 +8337F031 EE92 +8337F032 EE93 +8337F033 EE94 +8337F034 EE95 +8337F035 EE96 +8337F036 EE97 +8337F037 EE98 +8337F038 EE99 +8337F039 EE9A +8337F130 EE9B +8337F131 EE9C +8337F132 EE9D +8337F133 EE9E +8337F134 EE9F +8337F135 EEA0 +8337F136 EEA1 +8337F137 EEA2 +8337F138 EEA3 +8337F139 EEA4 +8337F230 EEA5 +8337F231 EEA6 +8337F232 EEA7 +8337F233 EEA8 +8337F234 EEA9 +8337F235 EEAA +8337F236 EEAB +8337F237 EEAC +8337F238 EEAD +8337F239 EEAE +8337F330 EEAF +8337F331 EEB0 +8337F332 EEB1 +8337F333 EEB2 +8337F334 EEB3 +8337F335 EEB4 +8337F336 EEB5 +8337F337 EEB6 +8337F338 EEB7 +8337F339 EEB8 +8337F430 EEB9 +8337F431 EEBA +8337F432 EEBB +8337F433 EEBC +8337F434 EEBD +8337F435 EEBE +8337F436 EEBF +8337F437 EEC0 +8337F438 EEC1 +8337F439 EEC2 +8337F530 EEC3 +8337F531 EEC4 +8337F532 EEC5 +8337F533 EEC6 +8337F534 EEC7 +8337F535 EEC8 +8337F536 EEC9 +8337F537 EECA +8337F538 EECB +8337F539 EECC +8337F630 EECD +8337F631 EECE +8337F632 EECF +8337F633 EED0 +8337F634 EED1 +8337F635 EED2 +8337F636 EED3 +8337F637 EED4 +8337F638 EED5 +8337F639 EED6 +8337F730 EED7 +8337F731 EED8 +8337F732 EED9 +8337F733 EEDA +8337F734 EEDB +8337F735 EEDC +8337F736 EEDD +8337F737 EEDE +8337F738 EEDF +8337F739 EEE0 +8337F830 EEE1 +8337F831 EEE2 +8337F832 EEE3 +8337F833 EEE4 +8337F834 EEE5 +8337F835 EEE6 +8337F836 EEE7 +8337F837 EEE8 +8337F838 EEE9 +8337F839 EEEA +8337F930 EEEB +8337F931 EEEC +8337F932 EEED +8337F933 EEEE +8337F934 EEEF +8337F935 EEF0 +8337F936 EEF1 +8337F937 EEF2 +8337F938 EEF3 +8337F939 EEF4 +8337FA30 EEF5 +8337FA31 EEF6 +8337FA32 EEF7 +8337FA33 EEF8 +8337FA34 EEF9 +8337FA35 EEFA +8337FA36 EEFB +8337FA37 EEFC +8337FA38 EEFD +8337FA39 EEFE +8337FB30 EEFF +8337FB31 EF00 +8337FB32 EF01 +8337FB33 EF02 +8337FB34 EF03 +8337FB35 EF04 +8337FB36 EF05 +8337FB37 EF06 +8337FB38 EF07 +8337FB39 EF08 +8337FC30 EF09 +8337FC31 EF0A +8337FC32 EF0B +8337FC33 EF0C +8337FC34 EF0D +8337FC35 EF0E +8337FC36 EF0F +8337FC37 EF10 +8337FC38 EF11 +8337FC39 EF12 +8337FD30 EF13 +8337FD31 EF14 +8337FD32 EF15 +8337FD33 EF16 +8337FD34 EF17 +8337FD35 EF18 +8337FD36 EF19 +8337FD37 EF1A +8337FD38 EF1B +8337FD39 EF1C +8337FE30 EF1D +8337FE31 EF1E +8337FE32 EF1F +8337FE33 EF20 +8337FE34 EF21 +8337FE35 EF22 +8337FE36 EF23 +8337FE37 EF24 +8337FE38 EF25 +8337FE39 EF26 +83388130 EF27 +83388131 EF28 +83388132 EF29 +83388133 EF2A +83388134 EF2B +83388135 EF2C +83388136 EF2D +83388137 EF2E +83388138 EF2F +83388139 EF30 +83388230 EF31 +83388231 EF32 +83388232 EF33 +83388233 EF34 +83388234 EF35 +83388235 EF36 +83388236 EF37 +83388237 EF38 +83388238 EF39 +83388239 EF3A +83388330 EF3B +83388331 EF3C +83388332 EF3D +83388333 EF3E +83388334 EF3F +83388335 EF40 +83388336 EF41 +83388337 EF42 +83388338 EF43 +83388339 EF44 +83388430 EF45 +83388431 EF46 +83388432 EF47 +83388433 EF48 +83388434 EF49 +83388435 EF4A +83388436 EF4B +83388437 EF4C +83388438 EF4D +83388439 EF4E +83388530 EF4F +83388531 EF50 +83388532 EF51 +83388533 EF52 +83388534 EF53 +83388535 EF54 +83388536 EF55 +83388537 EF56 +83388538 EF57 +83388539 EF58 +83388630 EF59 +83388631 EF5A +83388632 EF5B +83388633 EF5C +83388634 EF5D +83388635 EF5E +83388636 EF5F +83388637 EF60 +83388638 EF61 +83388639 EF62 +83388730 EF63 +83388731 EF64 +83388732 EF65 +83388733 EF66 +83388734 EF67 +83388735 EF68 +83388736 EF69 +83388737 EF6A +83388738 EF6B +83388739 EF6C +83388830 EF6D +83388831 EF6E +83388832 EF6F +83388833 EF70 +83388834 EF71 +83388835 EF72 +83388836 EF73 +83388837 EF74 +83388838 EF75 +83388839 EF76 +83388930 EF77 +83388931 EF78 +83388932 EF79 +83388933 EF7A +83388934 EF7B +83388935 EF7C +83388936 EF7D +83388937 EF7E +83388938 EF7F +83388939 EF80 +83388A30 EF81 +83388A31 EF82 +83388A32 EF83 +83388A33 EF84 +83388A34 EF85 +83388A35 EF86 +83388A36 EF87 +83388A37 EF88 +83388A38 EF89 +83388A39 EF8A +83388B30 EF8B +83388B31 EF8C +83388B32 EF8D +83388B33 EF8E +83388B34 EF8F +83388B35 EF90 +83388B36 EF91 +83388B37 EF92 +83388B38 EF93 +83388B39 EF94 +83388C30 EF95 +83388C31 EF96 +83388C32 EF97 +83388C33 EF98 +83388C34 EF99 +83388C35 EF9A +83388C36 EF9B +83388C37 EF9C +83388C38 EF9D +83388C39 EF9E +83388D30 EF9F +83388D31 EFA0 +83388D32 EFA1 +83388D33 EFA2 +83388D34 EFA3 +83388D35 EFA4 +83388D36 EFA5 +83388D37 EFA6 +83388D38 EFA7 +83388D39 EFA8 +83388E30 EFA9 +83388E31 EFAA +83388E32 EFAB +83388E33 EFAC +83388E34 EFAD +83388E35 EFAE +83388E36 EFAF +83388E37 EFB0 +83388E38 EFB1 +83388E39 EFB2 +83388F30 EFB3 +83388F31 EFB4 +83388F32 EFB5 +83388F33 EFB6 +83388F34 EFB7 +83388F35 EFB8 +83388F36 EFB9 +83388F37 EFBA +83388F38 EFBB +83388F39 EFBC +83389030 EFBD +83389031 EFBE +83389032 EFBF +83389033 EFC0 +83389034 EFC1 +83389035 EFC2 +83389036 EFC3 +83389037 EFC4 +83389038 EFC5 +83389039 EFC6 +83389130 EFC7 +83389131 EFC8 +83389132 EFC9 +83389133 EFCA +83389134 EFCB +83389135 EFCC +83389136 EFCD +83389137 EFCE +83389138 EFCF +83389139 EFD0 +83389230 EFD1 +83389231 EFD2 +83389232 EFD3 +83389233 EFD4 +83389234 EFD5 +83389235 EFD6 +83389236 EFD7 +83389237 EFD8 +83389238 EFD9 +83389239 EFDA +83389330 EFDB +83389331 EFDC +83389332 EFDD +83389333 EFDE +83389334 EFDF +83389335 EFE0 +83389336 EFE1 +83389337 EFE2 +83389338 EFE3 +83389339 EFE4 +83389430 EFE5 +83389431 EFE6 +83389432 EFE7 +83389433 EFE8 +83389434 EFE9 +83389435 EFEA +83389436 EFEB +83389437 EFEC +83389438 EFED +83389439 EFEE +83389530 EFEF +83389531 EFF0 +83389532 EFF1 +83389533 EFF2 +83389534 EFF3 +83389535 EFF4 +83389536 EFF5 +83389537 EFF6 +83389538 EFF7 +83389539 EFF8 +83389630 EFF9 +83389631 EFFA +83389632 EFFB +83389633 EFFC +83389634 EFFD +83389635 EFFE +83389636 EFFF +83389637 F000 +83389638 F001 +83389639 F002 +83389730 F003 +83389731 F004 +83389732 F005 +83389733 F006 +83389734 F007 +83389735 F008 +83389736 F009 +83389737 F00A +83389738 F00B +83389739 F00C +83389830 F00D +83389831 F00E +83389832 F00F +83389833 F010 +83389834 F011 +83389835 F012 +83389836 F013 +83389837 F014 +83389838 F015 +83389839 F016 +83389930 F017 +83389931 F018 +83389932 F019 +83389933 F01A +83389934 F01B +83389935 F01C +83389936 F01D +83389937 F01E +83389938 F01F +83389939 F020 +83389A30 F021 +83389A31 F022 +83389A32 F023 +83389A33 F024 +83389A34 F025 +83389A35 F026 +83389A36 F027 +83389A37 F028 +83389A38 F029 +83389A39 F02A +83389B30 F02B +83389B31 F02C +83389B32 F02D +83389B33 F02E +83389B34 F02F +83389B35 F030 +83389B36 F031 +83389B37 F032 +83389B38 F033 +83389B39 F034 +83389C30 F035 +83389C31 F036 +83389C32 F037 +83389C33 F038 +83389C34 F039 +83389C35 F03A +83389C36 F03B +83389C37 F03C +83389C38 F03D +83389C39 F03E +83389D30 F03F +83389D31 F040 +83389D32 F041 +83389D33 F042 +83389D34 F043 +83389D35 F044 +83389D36 F045 +83389D37 F046 +83389D38 F047 +83389D39 F048 +83389E30 F049 +83389E31 F04A +83389E32 F04B +83389E33 F04C +83389E34 F04D +83389E35 F04E +83389E36 F04F +83389E37 F050 +83389E38 F051 +83389E39 F052 +83389F30 F053 +83389F31 F054 +83389F32 F055 +83389F33 F056 +83389F34 F057 +83389F35 F058 +83389F36 F059 +83389F37 F05A +83389F38 F05B +83389F39 F05C +8338A030 F05D +8338A031 F05E +8338A032 F05F +8338A033 F060 +8338A034 F061 +8338A035 F062 +8338A036 F063 +8338A037 F064 +8338A038 F065 +8338A039 F066 +8338A130 F067 +8338A131 F068 +8338A132 F069 +8338A133 F06A +8338A134 F06B +8338A135 F06C +8338A136 F06D +8338A137 F06E +8338A138 F06F +8338A139 F070 +8338A230 F071 +8338A231 F072 +8338A232 F073 +8338A233 F074 +8338A234 F075 +8338A235 F076 +8338A236 F077 +8338A237 F078 +8338A238 F079 +8338A239 F07A +8338A330 F07B +8338A331 F07C +8338A332 F07D +8338A333 F07E +8338A334 F07F +8338A335 F080 +8338A336 F081 +8338A337 F082 +8338A338 F083 +8338A339 F084 +8338A430 F085 +8338A431 F086 +8338A432 F087 +8338A433 F088 +8338A434 F089 +8338A435 F08A +8338A436 F08B +8338A437 F08C +8338A438 F08D +8338A439 F08E +8338A530 F08F +8338A531 F090 +8338A532 F091 +8338A533 F092 +8338A534 F093 +8338A535 F094 +8338A536 F095 +8338A537 F096 +8338A538 F097 +8338A539 F098 +8338A630 F099 +8338A631 F09A +8338A632 F09B +8338A633 F09C +8338A634 F09D +8338A635 F09E +8338A636 F09F +8338A637 F0A0 +8338A638 F0A1 +8338A639 F0A2 +8338A730 F0A3 +8338A731 F0A4 +8338A732 F0A5 +8338A733 F0A6 +8338A734 F0A7 +8338A735 F0A8 +8338A736 F0A9 +8338A737 F0AA +8338A738 F0AB +8338A739 F0AC +8338A830 F0AD +8338A831 F0AE +8338A832 F0AF +8338A833 F0B0 +8338A834 F0B1 +8338A835 F0B2 +8338A836 F0B3 +8338A837 F0B4 +8338A838 F0B5 +8338A839 F0B6 +8338A930 F0B7 +8338A931 F0B8 +8338A932 F0B9 +8338A933 F0BA +8338A934 F0BB +8338A935 F0BC +8338A936 F0BD +8338A937 F0BE +8338A938 F0BF +8338A939 F0C0 +8338AA30 F0C1 +8338AA31 F0C2 +8338AA32 F0C3 +8338AA33 F0C4 +8338AA34 F0C5 +8338AA35 F0C6 +8338AA36 F0C7 +8338AA37 F0C8 +8338AA38 F0C9 +8338AA39 F0CA +8338AB30 F0CB +8338AB31 F0CC +8338AB32 F0CD +8338AB33 F0CE +8338AB34 F0CF +8338AB35 F0D0 +8338AB36 F0D1 +8338AB37 F0D2 +8338AB38 F0D3 +8338AB39 F0D4 +8338AC30 F0D5 +8338AC31 F0D6 +8338AC32 F0D7 +8338AC33 F0D8 +8338AC34 F0D9 +8338AC35 F0DA +8338AC36 F0DB +8338AC37 F0DC +8338AC38 F0DD +8338AC39 F0DE +8338AD30 F0DF +8338AD31 F0E0 +8338AD32 F0E1 +8338AD33 F0E2 +8338AD34 F0E3 +8338AD35 F0E4 +8338AD36 F0E5 +8338AD37 F0E6 +8338AD38 F0E7 +8338AD39 F0E8 +8338AE30 F0E9 +8338AE31 F0EA +8338AE32 F0EB +8338AE33 F0EC +8338AE34 F0ED +8338AE35 F0EE +8338AE36 F0EF +8338AE37 F0F0 +8338AE38 F0F1 +8338AE39 F0F2 +8338AF30 F0F3 +8338AF31 F0F4 +8338AF32 F0F5 +8338AF33 F0F6 +8338AF34 F0F7 +8338AF35 F0F8 +8338AF36 F0F9 +8338AF37 F0FA +8338AF38 F0FB +8338AF39 F0FC +8338B030 F0FD +8338B031 F0FE +8338B032 F0FF +8338B033 F100 +8338B034 F101 +8338B035 F102 +8338B036 F103 +8338B037 F104 +8338B038 F105 +8338B039 F106 +8338B130 F107 +8338B131 F108 +8338B132 F109 +8338B133 F10A +8338B134 F10B +8338B135 F10C +8338B136 F10D +8338B137 F10E +8338B138 F10F +8338B139 F110 +8338B230 F111 +8338B231 F112 +8338B232 F113 +8338B233 F114 +8338B234 F115 +8338B235 F116 +8338B236 F117 +8338B237 F118 +8338B238 F119 +8338B239 F11A +8338B330 F11B +8338B331 F11C +8338B332 F11D +8338B333 F11E +8338B334 F11F +8338B335 F120 +8338B336 F121 +8338B337 F122 +8338B338 F123 +8338B339 F124 +8338B430 F125 +8338B431 F126 +8338B432 F127 +8338B433 F128 +8338B434 F129 +8338B435 F12A +8338B436 F12B +8338B437 F12C +8338B438 F12D +8338B439 F12E +8338B530 F12F +8338B531 F130 +8338B532 F131 +8338B533 F132 +8338B534 F133 +8338B535 F134 +8338B536 F135 +8338B537 F136 +8338B538 F137 +8338B539 F138 +8338B630 F139 +8338B631 F13A +8338B632 F13B +8338B633 F13C +8338B634 F13D +8338B635 F13E +8338B636 F13F +8338B637 F140 +8338B638 F141 +8338B639 F142 +8338B730 F143 +8338B731 F144 +8338B732 F145 +8338B733 F146 +8338B734 F147 +8338B735 F148 +8338B736 F149 +8338B737 F14A +8338B738 F14B +8338B739 F14C +8338B830 F14D +8338B831 F14E +8338B832 F14F +8338B833 F150 +8338B834 F151 +8338B835 F152 +8338B836 F153 +8338B837 F154 +8338B838 F155 +8338B839 F156 +8338B930 F157 +8338B931 F158 +8338B932 F159 +8338B933 F15A +8338B934 F15B +8338B935 F15C +8338B936 F15D +8338B937 F15E +8338B938 F15F +8338B939 F160 +8338BA30 F161 +8338BA31 F162 +8338BA32 F163 +8338BA33 F164 +8338BA34 F165 +8338BA35 F166 +8338BA36 F167 +8338BA37 F168 +8338BA38 F169 +8338BA39 F16A +8338BB30 F16B +8338BB31 F16C +8338BB32 F16D +8338BB33 F16E +8338BB34 F16F +8338BB35 F170 +8338BB36 F171 +8338BB37 F172 +8338BB38 F173 +8338BB39 F174 +8338BC30 F175 +8338BC31 F176 +8338BC32 F177 +8338BC33 F178 +8338BC34 F179 +8338BC35 F17A +8338BC36 F17B +8338BC37 F17C +8338BC38 F17D +8338BC39 F17E +8338BD30 F17F +8338BD31 F180 +8338BD32 F181 +8338BD33 F182 +8338BD34 F183 +8338BD35 F184 +8338BD36 F185 +8338BD37 F186 +8338BD38 F187 +8338BD39 F188 +8338BE30 F189 +8338BE31 F18A +8338BE32 F18B +8338BE33 F18C +8338BE34 F18D +8338BE35 F18E +8338BE36 F18F +8338BE37 F190 +8338BE38 F191 +8338BE39 F192 +8338BF30 F193 +8338BF31 F194 +8338BF32 F195 +8338BF33 F196 +8338BF34 F197 +8338BF35 F198 +8338BF36 F199 +8338BF37 F19A +8338BF38 F19B +8338BF39 F19C +8338C030 F19D +8338C031 F19E +8338C032 F19F +8338C033 F1A0 +8338C034 F1A1 +8338C035 F1A2 +8338C036 F1A3 +8338C037 F1A4 +8338C038 F1A5 +8338C039 F1A6 +8338C130 F1A7 +8338C131 F1A8 +8338C132 F1A9 +8338C133 F1AA +8338C134 F1AB +8338C135 F1AC +8338C136 F1AD +8338C137 F1AE +8338C138 F1AF +8338C139 F1B0 +8338C230 F1B1 +8338C231 F1B2 +8338C232 F1B3 +8338C233 F1B4 +8338C234 F1B5 +8338C235 F1B6 +8338C236 F1B7 +8338C237 F1B8 +8338C238 F1B9 +8338C239 F1BA +8338C330 F1BB +8338C331 F1BC +8338C332 F1BD +8338C333 F1BE +8338C334 F1BF +8338C335 F1C0 +8338C336 F1C1 +8338C337 F1C2 +8338C338 F1C3 +8338C339 F1C4 +8338C430 F1C5 +8338C431 F1C6 +8338C432 F1C7 +8338C433 F1C8 +8338C434 F1C9 +8338C435 F1CA +8338C436 F1CB +8338C437 F1CC +8338C438 F1CD +8338C439 F1CE +8338C530 F1CF +8338C531 F1D0 +8338C532 F1D1 +8338C533 F1D2 +8338C534 F1D3 +8338C535 F1D4 +8338C536 F1D5 +8338C537 F1D6 +8338C538 F1D7 +8338C539 F1D8 +8338C630 F1D9 +8338C631 F1DA +8338C632 F1DB +8338C633 F1DC +8338C634 F1DD +8338C635 F1DE +8338C636 F1DF +8338C637 F1E0 +8338C638 F1E1 +8338C639 F1E2 +8338C730 F1E3 +8338C731 F1E4 +8338C732 F1E5 +8338C733 F1E6 +8338C734 F1E7 +8338C735 F1E8 +8338C736 F1E9 +8338C737 F1EA +8338C738 F1EB +8338C739 F1EC +8338C830 F1ED +8338C831 F1EE +8338C832 F1EF +8338C833 F1F0 +8338C834 F1F1 +8338C835 F1F2 +8338C836 F1F3 +8338C837 F1F4 +8338C838 F1F5 +8338C839 F1F6 +8338C930 F1F7 +8338C931 F1F8 +8338C932 F1F9 +8338C933 F1FA +8338C934 F1FB +8338C935 F1FC +8338C936 F1FD +8338C937 F1FE +8338C938 F1FF +8338C939 F200 +8338CA30 F201 +8338CA31 F202 +8338CA32 F203 +8338CA33 F204 +8338CA34 F205 +8338CA35 F206 +8338CA36 F207 +8338CA37 F208 +8338CA38 F209 +8338CA39 F20A +8338CB30 F20B +8338CB31 F20C +8338CB32 F20D +8338CB33 F20E +8338CB34 F20F +8338CB35 F210 +8338CB36 F211 +8338CB37 F212 +8338CB38 F213 +8338CB39 F214 +8338CC30 F215 +8338CC31 F216 +8338CC32 F217 +8338CC33 F218 +8338CC34 F219 +8338CC35 F21A +8338CC36 F21B +8338CC37 F21C +8338CC38 F21D +8338CC39 F21E +8338CD30 F21F +8338CD31 F220 +8338CD32 F221 +8338CD33 F222 +8338CD34 F223 +8338CD35 F224 +8338CD36 F225 +8338CD37 F226 +8338CD38 F227 +8338CD39 F228 +8338CE30 F229 +8338CE31 F22A +8338CE32 F22B +8338CE33 F22C +8338CE34 F22D +8338CE35 F22E +8338CE36 F22F +8338CE37 F230 +8338CE38 F231 +8338CE39 F232 +8338CF30 F233 +8338CF31 F234 +8338CF32 F235 +8338CF33 F236 +8338CF34 F237 +8338CF35 F238 +8338CF36 F239 +8338CF37 F23A +8338CF38 F23B +8338CF39 F23C +8338D030 F23D +8338D031 F23E +8338D032 F23F +8338D033 F240 +8338D034 F241 +8338D035 F242 +8338D036 F243 +8338D037 F244 +8338D038 F245 +8338D039 F246 +8338D130 F247 +8338D131 F248 +8338D132 F249 +8338D133 F24A +8338D134 F24B +8338D135 F24C +8338D136 F24D +8338D137 F24E +8338D138 F24F +8338D139 F250 +8338D230 F251 +8338D231 F252 +8338D232 F253 +8338D233 F254 +8338D234 F255 +8338D235 F256 +8338D236 F257 +8338D237 F258 +8338D238 F259 +8338D239 F25A +8338D330 F25B +8338D331 F25C +8338D332 F25D +8338D333 F25E +8338D334 F25F +8338D335 F260 +8338D336 F261 +8338D337 F262 +8338D338 F263 +8338D339 F264 +8338D430 F265 +8338D431 F266 +8338D432 F267 +8338D433 F268 +8338D434 F269 +8338D435 F26A +8338D436 F26B +8338D437 F26C +8338D438 F26D +8338D439 F26E +8338D530 F26F +8338D531 F270 +8338D532 F271 +8338D533 F272 +8338D534 F273 +8338D535 F274 +8338D536 F275 +8338D537 F276 +8338D538 F277 +8338D539 F278 +8338D630 F279 +8338D631 F27A +8338D632 F27B +8338D633 F27C +8338D634 F27D +8338D635 F27E +8338D636 F27F +8338D637 F280 +8338D638 F281 +8338D639 F282 +8338D730 F283 +8338D731 F284 +8338D732 F285 +8338D733 F286 +8338D734 F287 +8338D735 F288 +8338D736 F289 +8338D737 F28A +8338D738 F28B +8338D739 F28C +8338D830 F28D +8338D831 F28E +8338D832 F28F +8338D833 F290 +8338D834 F291 +8338D835 F292 +8338D836 F293 +8338D837 F294 +8338D838 F295 +8338D839 F296 +8338D930 F297 +8338D931 F298 +8338D932 F299 +8338D933 F29A +8338D934 F29B +8338D935 F29C +8338D936 F29D +8338D937 F29E +8338D938 F29F +8338D939 F2A0 +8338DA30 F2A1 +8338DA31 F2A2 +8338DA32 F2A3 +8338DA33 F2A4 +8338DA34 F2A5 +8338DA35 F2A6 +8338DA36 F2A7 +8338DA37 F2A8 +8338DA38 F2A9 +8338DA39 F2AA +8338DB30 F2AB +8338DB31 F2AC +8338DB32 F2AD +8338DB33 F2AE +8338DB34 F2AF +8338DB35 F2B0 +8338DB36 F2B1 +8338DB37 F2B2 +8338DB38 F2B3 +8338DB39 F2B4 +8338DC30 F2B5 +8338DC31 F2B6 +8338DC32 F2B7 +8338DC33 F2B8 +8338DC34 F2B9 +8338DC35 F2BA +8338DC36 F2BB +8338DC37 F2BC +8338DC38 F2BD +8338DC39 F2BE +8338DD30 F2BF +8338DD31 F2C0 +8338DD32 F2C1 +8338DD33 F2C2 +8338DD34 F2C3 +8338DD35 F2C4 +8338DD36 F2C5 +8338DD37 F2C6 +8338DD38 F2C7 +8338DD39 F2C8 +8338DE30 F2C9 +8338DE31 F2CA +8338DE32 F2CB +8338DE33 F2CC +8338DE34 F2CD +8338DE35 F2CE +8338DE36 F2CF +8338DE37 F2D0 +8338DE38 F2D1 +8338DE39 F2D2 +8338DF30 F2D3 +8338DF31 F2D4 +8338DF32 F2D5 +8338DF33 F2D6 +8338DF34 F2D7 +8338DF35 F2D8 +8338DF36 F2D9 +8338DF37 F2DA +8338DF38 F2DB +8338DF39 F2DC +8338E030 F2DD +8338E031 F2DE +8338E032 F2DF +8338E033 F2E0 +8338E034 F2E1 +8338E035 F2E2 +8338E036 F2E3 +8338E037 F2E4 +8338E038 F2E5 +8338E039 F2E6 +8338E130 F2E7 +8338E131 F2E8 +8338E132 F2E9 +8338E133 F2EA +8338E134 F2EB +8338E135 F2EC +8338E136 F2ED +8338E137 F2EE +8338E138 F2EF +8338E139 F2F0 +8338E230 F2F1 +8338E231 F2F2 +8338E232 F2F3 +8338E233 F2F4 +8338E234 F2F5 +8338E235 F2F6 +8338E236 F2F7 +8338E237 F2F8 +8338E238 F2F9 +8338E239 F2FA +8338E330 F2FB +8338E331 F2FC +8338E332 F2FD +8338E333 F2FE +8338E334 F2FF +8338E335 F300 +8338E336 F301 +8338E337 F302 +8338E338 F303 +8338E339 F304 +8338E430 F305 +8338E431 F306 +8338E432 F307 +8338E433 F308 +8338E434 F309 +8338E435 F30A +8338E436 F30B +8338E437 F30C +8338E438 F30D +8338E439 F30E +8338E530 F30F +8338E531 F310 +8338E532 F311 +8338E533 F312 +8338E534 F313 +8338E535 F314 +8338E536 F315 +8338E537 F316 +8338E538 F317 +8338E539 F318 +8338E630 F319 +8338E631 F31A +8338E632 F31B +8338E633 F31C +8338E634 F31D +8338E635 F31E +8338E636 F31F +8338E637 F320 +8338E638 F321 +8338E639 F322 +8338E730 F323 +8338E731 F324 +8338E732 F325 +8338E733 F326 +8338E734 F327 +8338E735 F328 +8338E736 F329 +8338E737 F32A +8338E738 F32B +8338E739 F32C +8338E830 F32D +8338E831 F32E +8338E832 F32F +8338E833 F330 +8338E834 F331 +8338E835 F332 +8338E836 F333 +8338E837 F334 +8338E838 F335 +8338E839 F336 +8338E930 F337 +8338E931 F338 +8338E932 F339 +8338E933 F33A +8338E934 F33B +8338E935 F33C +8338E936 F33D +8338E937 F33E +8338E938 F33F +8338E939 F340 +8338EA30 F341 +8338EA31 F342 +8338EA32 F343 +8338EA33 F344 +8338EA34 F345 +8338EA35 F346 +8338EA36 F347 +8338EA37 F348 +8338EA38 F349 +8338EA39 F34A +8338EB30 F34B +8338EB31 F34C +8338EB32 F34D +8338EB33 F34E +8338EB34 F34F +8338EB35 F350 +8338EB36 F351 +8338EB37 F352 +8338EB38 F353 +8338EB39 F354 +8338EC30 F355 +8338EC31 F356 +8338EC32 F357 +8338EC33 F358 +8338EC34 F359 +8338EC35 F35A +8338EC36 F35B +8338EC37 F35C +8338EC38 F35D +8338EC39 F35E +8338ED30 F35F +8338ED31 F360 +8338ED32 F361 +8338ED33 F362 +8338ED34 F363 +8338ED35 F364 +8338ED36 F365 +8338ED37 F366 +8338ED38 F367 +8338ED39 F368 +8338EE30 F369 +8338EE31 F36A +8338EE32 F36B +8338EE33 F36C +8338EE34 F36D +8338EE35 F36E +8338EE36 F36F +8338EE37 F370 +8338EE38 F371 +8338EE39 F372 +8338EF30 F373 +8338EF31 F374 +8338EF32 F375 +8338EF33 F376 +8338EF34 F377 +8338EF35 F378 +8338EF36 F379 +8338EF37 F37A +8338EF38 F37B +8338EF39 F37C +8338F030 F37D +8338F031 F37E +8338F032 F37F +8338F033 F380 +8338F034 F381 +8338F035 F382 +8338F036 F383 +8338F037 F384 +8338F038 F385 +8338F039 F386 +8338F130 F387 +8338F131 F388 +8338F132 F389 +8338F133 F38A +8338F134 F38B +8338F135 F38C +8338F136 F38D +8338F137 F38E +8338F138 F38F +8338F139 F390 +8338F230 F391 +8338F231 F392 +8338F232 F393 +8338F233 F394 +8338F234 F395 +8338F235 F396 +8338F236 F397 +8338F237 F398 +8338F238 F399 +8338F239 F39A +8338F330 F39B +8338F331 F39C +8338F332 F39D +8338F333 F39E +8338F334 F39F +8338F335 F3A0 +8338F336 F3A1 +8338F337 F3A2 +8338F338 F3A3 +8338F339 F3A4 +8338F430 F3A5 +8338F431 F3A6 +8338F432 F3A7 +8338F433 F3A8 +8338F434 F3A9 +8338F435 F3AA +8338F436 F3AB +8338F437 F3AC +8338F438 F3AD +8338F439 F3AE +8338F530 F3AF +8338F531 F3B0 +8338F532 F3B1 +8338F533 F3B2 +8338F534 F3B3 +8338F535 F3B4 +8338F536 F3B5 +8338F537 F3B6 +8338F538 F3B7 +8338F539 F3B8 +8338F630 F3B9 +8338F631 F3BA +8338F632 F3BB +8338F633 F3BC +8338F634 F3BD +8338F635 F3BE +8338F636 F3BF +8338F637 F3C0 +8338F638 F3C1 +8338F639 F3C2 +8338F730 F3C3 +8338F731 F3C4 +8338F732 F3C5 +8338F733 F3C6 +8338F734 F3C7 +8338F735 F3C8 +8338F736 F3C9 +8338F737 F3CA +8338F738 F3CB +8338F739 F3CC +8338F830 F3CD +8338F831 F3CE +8338F832 F3CF +8338F833 F3D0 +8338F834 F3D1 +8338F835 F3D2 +8338F836 F3D3 +8338F837 F3D4 +8338F838 F3D5 +8338F839 F3D6 +8338F930 F3D7 +8338F931 F3D8 +8338F932 F3D9 +8338F933 F3DA +8338F934 F3DB +8338F935 F3DC +8338F936 F3DD +8338F937 F3DE +8338F938 F3DF +8338F939 F3E0 +8338FA30 F3E1 +8338FA31 F3E2 +8338FA32 F3E3 +8338FA33 F3E4 +8338FA34 F3E5 +8338FA35 F3E6 +8338FA36 F3E7 +8338FA37 F3E8 +8338FA38 F3E9 +8338FA39 F3EA +8338FB30 F3EB +8338FB31 F3EC +8338FB32 F3ED +8338FB33 F3EE +8338FB34 F3EF +8338FB35 F3F0 +8338FB36 F3F1 +8338FB37 F3F2 +8338FB38 F3F3 +8338FB39 F3F4 +8338FC30 F3F5 +8338FC31 F3F6 +8338FC32 F3F7 +8338FC33 F3F8 +8338FC34 F3F9 +8338FC35 F3FA +8338FC36 F3FB +8338FC37 F3FC +8338FC38 F3FD +8338FC39 F3FE +8338FD30 F3FF +8338FD31 F400 +8338FD32 F401 +8338FD33 F402 +8338FD34 F403 +8338FD35 F404 +8338FD36 F405 +8338FD37 F406 +8338FD38 F407 +8338FD39 F408 +8338FE30 F409 +8338FE31 F40A +8338FE32 F40B +8338FE33 F40C +8338FE34 F40D +8338FE35 F40E +8338FE36 F40F +8338FE37 F410 +8338FE38 F411 +8338FE39 F412 +83398130 F413 +83398131 F414 +83398132 F415 +83398133 F416 +83398134 F417 +83398135 F418 +83398136 F419 +83398137 F41A +83398138 F41B +83398139 F41C +83398230 F41D +83398231 F41E +83398232 F41F +83398233 F420 +83398234 F421 +83398235 F422 +83398236 F423 +83398237 F424 +83398238 F425 +83398239 F426 +83398330 F427 +83398331 F428 +83398332 F429 +83398333 F42A +83398334 F42B +83398335 F42C +83398336 F42D +83398337 F42E +83398338 F42F +83398339 F430 +83398430 F431 +83398431 F432 +83398432 F433 +83398433 F434 +83398434 F435 +83398435 F436 +83398436 F437 +83398437 F438 +83398438 F439 +83398439 F43A +83398530 F43B +83398531 F43C +83398532 F43D +83398533 F43E +83398534 F43F +83398535 F440 +83398536 F441 +83398537 F442 +83398538 F443 +83398539 F444 +83398630 F445 +83398631 F446 +83398632 F447 +83398633 F448 +83398634 F449 +83398635 F44A +83398636 F44B +83398637 F44C +83398638 F44D +83398639 F44E +83398730 F44F +83398731 F450 +83398732 F451 +83398733 F452 +83398734 F453 +83398735 F454 +83398736 F455 +83398737 F456 +83398738 F457 +83398739 F458 +83398830 F459 +83398831 F45A +83398832 F45B +83398833 F45C +83398834 F45D +83398835 F45E +83398836 F45F +83398837 F460 +83398838 F461 +83398839 F462 +83398930 F463 +83398931 F464 +83398932 F465 +83398933 F466 +83398934 F467 +83398935 F468 +83398936 F469 +83398937 F46A +83398938 F46B +83398939 F46C +83398A30 F46D +83398A31 F46E +83398A32 F46F +83398A33 F470 +83398A34 F471 +83398A35 F472 +83398A36 F473 +83398A37 F474 +83398A38 F475 +83398A39 F476 +83398B30 F477 +83398B31 F478 +83398B32 F479 +83398B33 F47A +83398B34 F47B +83398B35 F47C +83398B36 F47D +83398B37 F47E +83398B38 F47F +83398B39 F480 +83398C30 F481 +83398C31 F482 +83398C32 F483 +83398C33 F484 +83398C34 F485 +83398C35 F486 +83398C36 F487 +83398C37 F488 +83398C38 F489 +83398C39 F48A +83398D30 F48B +83398D31 F48C +83398D32 F48D +83398D33 F48E +83398D34 F48F +83398D35 F490 +83398D36 F491 +83398D37 F492 +83398D38 F493 +83398D39 F494 +83398E30 F495 +83398E31 F496 +83398E32 F497 +83398E33 F498 +83398E34 F499 +83398E35 F49A +83398E36 F49B +83398E37 F49C +83398E38 F49D +83398E39 F49E +83398F30 F49F +83398F31 F4A0 +83398F32 F4A1 +83398F33 F4A2 +83398F34 F4A3 +83398F35 F4A4 +83398F36 F4A5 +83398F37 F4A6 +83398F38 F4A7 +83398F39 F4A8 +83399030 F4A9 +83399031 F4AA +83399032 F4AB +83399033 F4AC +83399034 F4AD +83399035 F4AE +83399036 F4AF +83399037 F4B0 +83399038 F4B1 +83399039 F4B2 +83399130 F4B3 +83399131 F4B4 +83399132 F4B5 +83399133 F4B6 +83399134 F4B7 +83399135 F4B8 +83399136 F4B9 +83399137 F4BA +83399138 F4BB +83399139 F4BC +83399230 F4BD +83399231 F4BE +83399232 F4BF +83399233 F4C0 +83399234 F4C1 +83399235 F4C2 +83399236 F4C3 +83399237 F4C4 +83399238 F4C5 +83399239 F4C6 +83399330 F4C7 +83399331 F4C8 +83399332 F4C9 +83399333 F4CA +83399334 F4CB +83399335 F4CC +83399336 F4CD +83399337 F4CE +83399338 F4CF +83399339 F4D0 +83399430 F4D1 +83399431 F4D2 +83399432 F4D3 +83399433 F4D4 +83399434 F4D5 +83399435 F4D6 +83399436 F4D7 +83399437 F4D8 +83399438 F4D9 +83399439 F4DA +83399530 F4DB +83399531 F4DC +83399532 F4DD +83399533 F4DE +83399534 F4DF +83399535 F4E0 +83399536 F4E1 +83399537 F4E2 +83399538 F4E3 +83399539 F4E4 +83399630 F4E5 +83399631 F4E6 +83399632 F4E7 +83399633 F4E8 +83399634 F4E9 +83399635 F4EA +83399636 F4EB +83399637 F4EC +83399638 F4ED +83399639 F4EE +83399730 F4EF +83399731 F4F0 +83399732 F4F1 +83399733 F4F2 +83399734 F4F3 +83399735 F4F4 +83399736 F4F5 +83399737 F4F6 +83399738 F4F7 +83399739 F4F8 +83399830 F4F9 +83399831 F4FA +83399832 F4FB +83399833 F4FC +83399834 F4FD +83399835 F4FE +83399836 F4FF +83399837 F500 +83399838 F501 +83399839 F502 +83399930 F503 +83399931 F504 +83399932 F505 +83399933 F506 +83399934 F507 +83399935 F508 +83399936 F509 +83399937 F50A +83399938 F50B +83399939 F50C +83399A30 F50D +83399A31 F50E +83399A32 F50F +83399A33 F510 +83399A34 F511 +83399A35 F512 +83399A36 F513 +83399A37 F514 +83399A38 F515 +83399A39 F516 +83399B30 F517 +83399B31 F518 +83399B32 F519 +83399B33 F51A +83399B34 F51B +83399B35 F51C +83399B36 F51D +83399B37 F51E +83399B38 F51F +83399B39 F520 +83399C30 F521 +83399C31 F522 +83399C32 F523 +83399C33 F524 +83399C34 F525 +83399C35 F526 +83399C36 F527 +83399C37 F528 +83399C38 F529 +83399C39 F52A +83399D30 F52B +83399D31 F52C +83399D32 F52D +83399D33 F52E +83399D34 F52F +83399D35 F530 +83399D36 F531 +83399D37 F532 +83399D38 F533 +83399D39 F534 +83399E30 F535 +83399E31 F536 +83399E32 F537 +83399E33 F538 +83399E34 F539 +83399E35 F53A +83399E36 F53B +83399E37 F53C +83399E38 F53D +83399E39 F53E +83399F30 F53F +83399F31 F540 +83399F32 F541 +83399F33 F542 +83399F34 F543 +83399F35 F544 +83399F36 F545 +83399F37 F546 +83399F38 F547 +83399F39 F548 +8339A030 F549 +8339A031 F54A +8339A032 F54B +8339A033 F54C +8339A034 F54D +8339A035 F54E +8339A036 F54F +8339A037 F550 +8339A038 F551 +8339A039 F552 +8339A130 F553 +8339A131 F554 +8339A132 F555 +8339A133 F556 +8339A134 F557 +8339A135 F558 +8339A136 F559 +8339A137 F55A +8339A138 F55B +8339A139 F55C +8339A230 F55D +8339A231 F55E +8339A232 F55F +8339A233 F560 +8339A234 F561 +8339A235 F562 +8339A236 F563 +8339A237 F564 +8339A238 F565 +8339A239 F566 +8339A330 F567 +8339A331 F568 +8339A332 F569 +8339A333 F56A +8339A334 F56B +8339A335 F56C +8339A336 F56D +8339A337 F56E +8339A338 F56F +8339A339 F570 +8339A430 F571 +8339A431 F572 +8339A432 F573 +8339A433 F574 +8339A434 F575 +8339A435 F576 +8339A436 F577 +8339A437 F578 +8339A438 F579 +8339A439 F57A +8339A530 F57B +8339A531 F57C +8339A532 F57D +8339A533 F57E +8339A534 F57F +8339A535 F580 +8339A536 F581 +8339A537 F582 +8339A538 F583 +8339A539 F584 +8339A630 F585 +8339A631 F586 +8339A632 F587 +8339A633 F588 +8339A634 F589 +8339A635 F58A +8339A636 F58B +8339A637 F58C +8339A638 F58D +8339A639 F58E +8339A730 F58F +8339A731 F590 +8339A732 F591 +8339A733 F592 +8339A734 F593 +8339A735 F594 +8339A736 F595 +8339A737 F596 +8339A738 F597 +8339A739 F598 +8339A830 F599 +8339A831 F59A +8339A832 F59B +8339A833 F59C +8339A834 F59D +8339A835 F59E +8339A836 F59F +8339A837 F5A0 +8339A838 F5A1 +8339A839 F5A2 +8339A930 F5A3 +8339A931 F5A4 +8339A932 F5A5 +8339A933 F5A6 +8339A934 F5A7 +8339A935 F5A8 +8339A936 F5A9 +8339A937 F5AA +8339A938 F5AB +8339A939 F5AC +8339AA30 F5AD +8339AA31 F5AE +8339AA32 F5AF +8339AA33 F5B0 +8339AA34 F5B1 +8339AA35 F5B2 +8339AA36 F5B3 +8339AA37 F5B4 +8339AA38 F5B5 +8339AA39 F5B6 +8339AB30 F5B7 +8339AB31 F5B8 +8339AB32 F5B9 +8339AB33 F5BA +8339AB34 F5BB +8339AB35 F5BC +8339AB36 F5BD +8339AB37 F5BE +8339AB38 F5BF +8339AB39 F5C0 +8339AC30 F5C1 +8339AC31 F5C2 +8339AC32 F5C3 +8339AC33 F5C4 +8339AC34 F5C5 +8339AC35 F5C6 +8339AC36 F5C7 +8339AC37 F5C8 +8339AC38 F5C9 +8339AC39 F5CA +8339AD30 F5CB +8339AD31 F5CC +8339AD32 F5CD +8339AD33 F5CE +8339AD34 F5CF +8339AD35 F5D0 +8339AD36 F5D1 +8339AD37 F5D2 +8339AD38 F5D3 +8339AD39 F5D4 +8339AE30 F5D5 +8339AE31 F5D6 +8339AE32 F5D7 +8339AE33 F5D8 +8339AE34 F5D9 +8339AE35 F5DA +8339AE36 F5DB +8339AE37 F5DC +8339AE38 F5DD +8339AE39 F5DE +8339AF30 F5DF +8339AF31 F5E0 +8339AF32 F5E1 +8339AF33 F5E2 +8339AF34 F5E3 +8339AF35 F5E4 +8339AF36 F5E5 +8339AF37 F5E6 +8339AF38 F5E7 +8339AF39 F5E8 +8339B030 F5E9 +8339B031 F5EA +8339B032 F5EB +8339B033 F5EC +8339B034 F5ED +8339B035 F5EE +8339B036 F5EF +8339B037 F5F0 +8339B038 F5F1 +8339B039 F5F2 +8339B130 F5F3 +8339B131 F5F4 +8339B132 F5F5 +8339B133 F5F6 +8339B134 F5F7 +8339B135 F5F8 +8339B136 F5F9 +8339B137 F5FA +8339B138 F5FB +8339B139 F5FC +8339B230 F5FD +8339B231 F5FE +8339B232 F5FF +8339B233 F600 +8339B234 F601 +8339B235 F602 +8339B236 F603 +8339B237 F604 +8339B238 F605 +8339B239 F606 +8339B330 F607 +8339B331 F608 +8339B332 F609 +8339B333 F60A +8339B334 F60B +8339B335 F60C +8339B336 F60D +8339B337 F60E +8339B338 F60F +8339B339 F610 +8339B430 F611 +8339B431 F612 +8339B432 F613 +8339B433 F614 +8339B434 F615 +8339B435 F616 +8339B436 F617 +8339B437 F618 +8339B438 F619 +8339B439 F61A +8339B530 F61B +8339B531 F61C +8339B532 F61D +8339B533 F61E +8339B534 F61F +8339B535 F620 +8339B536 F621 +8339B537 F622 +8339B538 F623 +8339B539 F624 +8339B630 F625 +8339B631 F626 +8339B632 F627 +8339B633 F628 +8339B634 F629 +8339B635 F62A +8339B636 F62B +8339B637 F62C +8339B638 F62D +8339B639 F62E +8339B730 F62F +8339B731 F630 +8339B732 F631 +8339B733 F632 +8339B734 F633 +8339B735 F634 +8339B736 F635 +8339B737 F636 +8339B738 F637 +8339B739 F638 +8339B830 F639 +8339B831 F63A +8339B832 F63B +8339B833 F63C +8339B834 F63D +8339B835 F63E +8339B836 F63F +8339B837 F640 +8339B838 F641 +8339B839 F642 +8339B930 F643 +8339B931 F644 +8339B932 F645 +8339B933 F646 +8339B934 F647 +8339B935 F648 +8339B936 F649 +8339B937 F64A +8339B938 F64B +8339B939 F64C +8339BA30 F64D +8339BA31 F64E +8339BA32 F64F +8339BA33 F650 +8339BA34 F651 +8339BA35 F652 +8339BA36 F653 +8339BA37 F654 +8339BA38 F655 +8339BA39 F656 +8339BB30 F657 +8339BB31 F658 +8339BB32 F659 +8339BB33 F65A +8339BB34 F65B +8339BB35 F65C +8339BB36 F65D +8339BB37 F65E +8339BB38 F65F +8339BB39 F660 +8339BC30 F661 +8339BC31 F662 +8339BC32 F663 +8339BC33 F664 +8339BC34 F665 +8339BC35 F666 +8339BC36 F667 +8339BC37 F668 +8339BC38 F669 +8339BC39 F66A +8339BD30 F66B +8339BD31 F66C +8339BD32 F66D +8339BD33 F66E +8339BD34 F66F +8339BD35 F670 +8339BD36 F671 +8339BD37 F672 +8339BD38 F673 +8339BD39 F674 +8339BE30 F675 +8339BE31 F676 +8339BE32 F677 +8339BE33 F678 +8339BE34 F679 +8339BE35 F67A +8339BE36 F67B +8339BE37 F67C +8339BE38 F67D +8339BE39 F67E +8339BF30 F67F +8339BF31 F680 +8339BF32 F681 +8339BF33 F682 +8339BF34 F683 +8339BF35 F684 +8339BF36 F685 +8339BF37 F686 +8339BF38 F687 +8339BF39 F688 +8339C030 F689 +8339C031 F68A +8339C032 F68B +8339C033 F68C +8339C034 F68D +8339C035 F68E +8339C036 F68F +8339C037 F690 +8339C038 F691 +8339C039 F692 +8339C130 F693 +8339C131 F694 +8339C132 F695 +8339C133 F696 +8339C134 F697 +8339C135 F698 +8339C136 F699 +8339C137 F69A +8339C138 F69B +8339C139 F69C +8339C230 F69D +8339C231 F69E +8339C232 F69F +8339C233 F6A0 +8339C234 F6A1 +8339C235 F6A2 +8339C236 F6A3 +8339C237 F6A4 +8339C238 F6A5 +8339C239 F6A6 +8339C330 F6A7 +8339C331 F6A8 +8339C332 F6A9 +8339C333 F6AA +8339C334 F6AB +8339C335 F6AC +8339C336 F6AD +8339C337 F6AE +8339C338 F6AF +8339C339 F6B0 +8339C430 F6B1 +8339C431 F6B2 +8339C432 F6B3 +8339C433 F6B4 +8339C434 F6B5 +8339C435 F6B6 +8339C436 F6B7 +8339C437 F6B8 +8339C438 F6B9 +8339C439 F6BA +8339C530 F6BB +8339C531 F6BC +8339C532 F6BD +8339C533 F6BE +8339C534 F6BF +8339C535 F6C0 +8339C536 F6C1 +8339C537 F6C2 +8339C538 F6C3 +8339C539 F6C4 +8339C630 F6C5 +8339C631 F6C6 +8339C632 F6C7 +8339C633 F6C8 +8339C634 F6C9 +8339C635 F6CA +8339C636 F6CB +8339C637 F6CC +8339C638 F6CD +8339C639 F6CE +8339C730 F6CF +8339C731 F6D0 +8339C732 F6D1 +8339C733 F6D2 +8339C734 F6D3 +8339C735 F6D4 +8339C736 F6D5 +8339C737 F6D6 +8339C738 F6D7 +8339C739 F6D8 +8339C830 F6D9 +8339C831 F6DA +8339C832 F6DB +8339C833 F6DC +8339C834 F6DD +8339C835 F6DE +8339C836 F6DF +8339C837 F6E0 +8339C838 F6E1 +8339C839 F6E2 +8339C930 F6E3 +8339C931 F6E4 +8339C932 F6E5 +8339C933 F6E6 +8339C934 F6E7 +8339C935 F6E8 +8339C936 F6E9 +8339C937 F6EA +8339C938 F6EB +8339C939 F6EC +8339CA30 F6ED +8339CA31 F6EE +8339CA32 F6EF +8339CA33 F6F0 +8339CA34 F6F1 +8339CA35 F6F2 +8339CA36 F6F3 +8339CA37 F6F4 +8339CA38 F6F5 +8339CA39 F6F6 +8339CB30 F6F7 +8339CB31 F6F8 +8339CB32 F6F9 +8339CB33 F6FA +8339CB34 F6FB +8339CB35 F6FC +8339CB36 F6FD +8339CB37 F6FE +8339CB38 F6FF +8339CB39 F700 +8339CC30 F701 +8339CC31 F702 +8339CC32 F703 +8339CC33 F704 +8339CC34 F705 +8339CC35 F706 +8339CC36 F707 +8339CC37 F708 +8339CC38 F709 +8339CC39 F70A +8339CD30 F70B +8339CD31 F70C +8339CD32 F70D +8339CD33 F70E +8339CD34 F70F +8339CD35 F710 +8339CD36 F711 +8339CD37 F712 +8339CD38 F713 +8339CD39 F714 +8339CE30 F715 +8339CE31 F716 +8339CE32 F717 +8339CE33 F718 +8339CE34 F719 +8339CE35 F71A +8339CE36 F71B +8339CE37 F71C +8339CE38 F71D +8339CE39 F71E +8339CF30 F71F +8339CF31 F720 +8339CF32 F721 +8339CF33 F722 +8339CF34 F723 +8339CF35 F724 +8339CF36 F725 +8339CF37 F726 +8339CF38 F727 +8339CF39 F728 +8339D030 F729 +8339D031 F72A +8339D032 F72B +8339D033 F72C +8339D034 F72D +8339D035 F72E +8339D036 F72F +8339D037 F730 +8339D038 F731 +8339D039 F732 +8339D130 F733 +8339D131 F734 +8339D132 F735 +8339D133 F736 +8339D134 F737 +8339D135 F738 +8339D136 F739 +8339D137 F73A +8339D138 F73B +8339D139 F73C +8339D230 F73D +8339D231 F73E +8339D232 F73F +8339D233 F740 +8339D234 F741 +8339D235 F742 +8339D236 F743 +8339D237 F744 +8339D238 F745 +8339D239 F746 +8339D330 F747 +8339D331 F748 +8339D332 F749 +8339D333 F74A +8339D334 F74B +8339D335 F74C +8339D336 F74D +8339D337 F74E +8339D338 F74F +8339D339 F750 +8339D430 F751 +8339D431 F752 +8339D432 F753 +8339D433 F754 +8339D434 F755 +8339D435 F756 +8339D436 F757 +8339D437 F758 +8339D438 F759 +8339D439 F75A +8339D530 F75B +8339D531 F75C +8339D532 F75D +8339D533 F75E +8339D534 F75F +8339D535 F760 +8339D536 F761 +8339D537 F762 +8339D538 F763 +8339D539 F764 +8339D630 F765 +8339D631 F766 +8339D632 F767 +8339D633 F768 +8339D634 F769 +8339D635 F76A +8339D636 F76B +8339D637 F76C +8339D638 F76D +8339D639 F76E +8339D730 F76F +8339D731 F770 +8339D732 F771 +8339D733 F772 +8339D734 F773 +8339D735 F774 +8339D736 F775 +8339D737 F776 +8339D738 F777 +8339D739 F778 +8339D830 F779 +8339D831 F77A +8339D832 F77B +8339D833 F77C +8339D834 F77D +8339D835 F77E +8339D836 F77F +8339D837 F780 +8339D838 F781 +8339D839 F782 +8339D930 F783 +8339D931 F784 +8339D932 F785 +8339D933 F786 +8339D934 F787 +8339D935 F788 +8339D936 F789 +8339D937 F78A +8339D938 F78B +8339D939 F78C +8339DA30 F78D +8339DA31 F78E +8339DA32 F78F +8339DA33 F790 +8339DA34 F791 +8339DA35 F792 +8339DA36 F793 +8339DA37 F794 +8339DA38 F795 +8339DA39 F796 +8339DB30 F797 +8339DB31 F798 +8339DB32 F799 +8339DB33 F79A +8339DB34 F79B +8339DB35 F79C +8339DB36 F79D +8339DB37 F79E +8339DB38 F79F +8339DB39 F7A0 +8339DC30 F7A1 +8339DC31 F7A2 +8339DC32 F7A3 +8339DC33 F7A4 +8339DC34 F7A5 +8339DC35 F7A6 +8339DC36 F7A7 +8339DC37 F7A8 +8339DC38 F7A9 +8339DC39 F7AA +8339DD30 F7AB +8339DD31 F7AC +8339DD32 F7AD +8339DD33 F7AE +8339DD34 F7AF +8339DD35 F7B0 +8339DD36 F7B1 +8339DD37 F7B2 +8339DD38 F7B3 +8339DD39 F7B4 +8339DE30 F7B5 +8339DE31 F7B6 +8339DE32 F7B7 +8339DE33 F7B8 +8339DE34 F7B9 +8339DE35 F7BA +8339DE36 F7BB +8339DE37 F7BC +8339DE38 F7BD +8339DE39 F7BE +8339DF30 F7BF +8339DF31 F7C0 +8339DF32 F7C1 +8339DF33 F7C2 +8339DF34 F7C3 +8339DF35 F7C4 +8339DF36 F7C5 +8339DF37 F7C6 +8339DF38 F7C7 +8339DF39 F7C8 +8339E030 F7C9 +8339E031 F7CA +8339E032 F7CB +8339E033 F7CC +8339E034 F7CD +8339E035 F7CE +8339E036 F7CF +8339E037 F7D0 +8339E038 F7D1 +8339E039 F7D2 +8339E130 F7D3 +8339E131 F7D4 +8339E132 F7D5 +8339E133 F7D6 +8339E134 F7D7 +8339E135 F7D8 +8339E136 F7D9 +8339E137 F7DA +8339E138 F7DB +8339E139 F7DC +8339E230 F7DD +8339E231 F7DE +8339E232 F7DF +8339E233 F7E0 +8339E234 F7E1 +8339E235 F7E2 +8339E236 F7E3 +8339E237 F7E4 +8339E238 F7E5 +8339E239 F7E6 +8339E330 F7E7 +8339E331 F7E8 +8339E332 F7E9 +8339E333 F7EA +8339E334 F7EB +8339E335 F7EC +8339E336 F7ED +8339E337 F7EE +8339E338 F7EF +8339E339 F7F0 +8339E430 F7F1 +8339E431 F7F2 +8339E432 F7F3 +8339E433 F7F4 +8339E434 F7F5 +8339E435 F7F6 +8339E436 F7F7 +8339E437 F7F8 +8339E438 F7F9 +8339E439 F7FA +8339E530 F7FB +8339E531 F7FC +8339E532 F7FD +8339E533 F7FE +8339E534 F7FF +8339E535 F800 +8339E536 F801 +8339E537 F802 +8339E538 F803 +8339E539 F804 +8339E630 F805 +8339E631 F806 +8339E632 F807 +8339E633 F808 +8339E634 F809 +8339E635 F80A +8339E636 F80B +8339E637 F80C +8339E638 F80D +8339E639 F80E +8339E730 F80F +8339E731 F810 +8339E732 F811 +8339E733 F812 +8339E734 F813 +8339E735 F814 +8339E736 F815 +8339E737 F816 +8339E738 F817 +8339E739 F818 +8339E830 F819 +8339E831 F81A +8339E832 F81B +8339E833 F81C +8339E834 F81D +8339E835 F81E +8339E836 F81F +8339E837 F820 +8339E838 F821 +8339E839 F822 +8339E930 F823 +8339E931 F824 +8339E932 F825 +8339E933 F826 +8339E934 F827 +8339E935 F828 +8339E936 F829 +8339E937 F82A +8339E938 F82B +8339E939 F82C +8339EA30 F82D +8339EA31 F82E +8339EA32 F82F +8339EA33 F830 +8339EA34 F831 +8339EA35 F832 +8339EA36 F833 +8339EA37 F834 +8339EA38 F835 +8339EA39 F836 +8339EB30 F837 +8339EB31 F838 +8339EB32 F839 +8339EB33 F83A +8339EB34 F83B +8339EB35 F83C +8339EB36 F83D +8339EB37 F83E +8339EB38 F83F +8339EB39 F840 +8339EC30 F841 +8339EC31 F842 +8339EC32 F843 +8339EC33 F844 +8339EC34 F845 +8339EC35 F846 +8339EC36 F847 +8339EC37 F848 +8339EC38 F849 +8339EC39 F84A +8339ED30 F84B +8339ED31 F84C +8339ED32 F84D +8339ED33 F84E +8339ED34 F84F +8339ED35 F850 +8339ED36 F851 +8339ED37 F852 +8339ED38 F853 +8339ED39 F854 +8339EE30 F855 +8339EE31 F856 +8339EE32 F857 +8339EE33 F858 +8339EE34 F859 +8339EE35 F85A +8339EE36 F85B +8339EE37 F85C +8339EE38 F85D +8339EE39 F85E +8339EF30 F85F +8339EF31 F860 +8339EF32 F861 +8339EF33 F862 +8339EF34 F863 +8339EF35 F864 +8339EF36 F865 +8339EF37 F866 +8339EF38 F867 +8339EF39 F868 +8339F030 F869 +8339F031 F86A +8339F032 F86B +8339F033 F86C +8339F034 F86D +8339F035 F86E +8339F036 F86F +8339F037 F870 +8339F038 F871 +8339F039 F872 +8339F130 F873 +8339F131 F874 +8339F132 F875 +8339F133 F876 +8339F134 F877 +8339F135 F878 +8339F136 F879 +8339F137 F87A +8339F138 F87B +8339F139 F87C +8339F230 F87D +8339F231 F87E +8339F232 F87F +8339F233 F880 +8339F234 F881 +8339F235 F882 +8339F236 F883 +8339F237 F884 +8339F238 F885 +8339F239 F886 +8339F330 F887 +8339F331 F888 +8339F332 F889 +8339F333 F88A +8339F334 F88B +8339F335 F88C +8339F336 F88D +8339F337 F88E +8339F338 F88F +8339F339 F890 +8339F430 F891 +8339F431 F892 +8339F432 F893 +8339F433 F894 +8339F434 F895 +8339F435 F896 +8339F436 F897 +8339F437 F898 +8339F438 F899 +8339F439 F89A +8339F530 F89B +8339F531 F89C +8339F532 F89D +8339F533 F89E +8339F534 F89F +8339F535 F8A0 +8339F536 F8A1 +8339F537 F8A2 +8339F538 F8A3 +8339F539 F8A4 +8339F630 F8A5 +8339F631 F8A6 +8339F632 F8A7 +8339F633 F8A8 +8339F634 F8A9 +8339F635 F8AA +8339F636 F8AB +8339F637 F8AC +8339F638 F8AD +8339F639 F8AE +8339F730 F8AF +8339F731 F8B0 +8339F732 F8B1 +8339F733 F8B2 +8339F734 F8B3 +8339F735 F8B4 +8339F736 F8B5 +8339F737 F8B6 +8339F738 F8B7 +8339F739 F8B8 +8339F830 F8B9 +8339F831 F8BA +8339F832 F8BB +8339F833 F8BC +8339F834 F8BD +8339F835 F8BE +8339F836 F8BF +8339F837 F8C0 +8339F838 F8C1 +8339F839 F8C2 +8339F930 F8C3 +8339F931 F8C4 +8339F932 F8C5 +8339F933 F8C6 +8339F934 F8C7 +8339F935 F8C8 +8339F936 F8C9 +8339F937 F8CA +8339F938 F8CB +8339F939 F8CC +8339FA30 F8CD +8339FA31 F8CE +8339FA32 F8CF +8339FA33 F8D0 +8339FA34 F8D1 +8339FA35 F8D2 +8339FA36 F8D3 +8339FA37 F8D4 +8339FA38 F8D5 +8339FA39 F8D6 +8339FB30 F8D7 +8339FB31 F8D8 +8339FB32 F8D9 +8339FB33 F8DA +8339FB34 F8DB +8339FB35 F8DC +8339FB36 F8DD +8339FB37 F8DE +8339FB38 F8DF +8339FB39 F8E0 +8339FC30 F8E1 +8339FC31 F8E2 +8339FC32 F8E3 +8339FC33 F8E4 +8339FC34 F8E5 +8339FC35 F8E6 +8339FC36 F8E7 +8339FC37 F8E8 +8339FC38 F8E9 +8339FC39 F8EA +8339FD30 F8EB +8339FD31 F8EC +8339FD32 F8ED +8339FD33 F8EE +8339FD34 F8EF +8339FD35 F8F0 +8339FD36 F8F1 +8339FD37 F8F2 +8339FD38 F8F3 +8339FD39 F8F4 +8339FE30 F8F5 +8339FE31 F8F6 +8339FE32 F8F7 +8339FE33 F8F8 +8339FE34 F8F9 +8339FE35 F8FA +8339FE36 F8FB +8339FE37 F8FC +8339FE38 F8FD +8339FE39 F8FE +84308130 F8FF +84308131 F900 +84308132 F901 +84308133 F902 +84308134 F903 +84308135 F904 +84308136 F905 +84308137 F906 +84308138 F907 +84308139 F908 +84308230 F909 +84308231 F90A +84308232 F90B +84308233 F90C +84308234 F90D +84308235 F90E +84308236 F90F +84308237 F910 +84308238 F911 +84308239 F912 +84308330 F913 +84308331 F914 +84308332 F915 +84308333 F916 +84308334 F917 +84308335 F918 +84308336 F919 +84308337 F91A +84308338 F91B +84308339 F91C +84308430 F91D +84308431 F91E +84308432 F91F +84308433 F920 +84308434 F921 +84308435 F922 +84308436 F923 +84308437 F924 +84308438 F925 +84308439 F926 +84308530 F927 +84308531 F928 +84308532 F929 +84308533 F92A +84308534 F92B +FD9C F92C +84308535 F92D +84308536 F92E +84308537 F92F +84308538 F930 +84308539 F931 +84308630 F932 +84308631 F933 +84308632 F934 +84308633 F935 +84308634 F936 +84308635 F937 +84308636 F938 +84308637 F939 +84308638 F93A +84308639 F93B +84308730 F93C +84308731 F93D +84308732 F93E +84308733 F93F +84308734 F940 +84308735 F941 +84308736 F942 +84308737 F943 +84308738 F944 +84308739 F945 +84308830 F946 +84308831 F947 +84308832 F948 +84308833 F949 +84308834 F94A +84308835 F94B +84308836 F94C +84308837 F94D +84308838 F94E +84308839 F94F +84308930 F950 +84308931 F951 +84308932 F952 +84308933 F953 +84308934 F954 +84308935 F955 +84308936 F956 +84308937 F957 +84308938 F958 +84308939 F959 +84308A30 F95A +84308A31 F95B +84308A32 F95C +84308A33 F95D +84308A34 F95E +84308A35 F95F +84308A36 F960 +84308A37 F961 +84308A38 F962 +84308A39 F963 +84308B30 F964 +84308B31 F965 +84308B32 F966 +84308B33 F967 +84308B34 F968 +84308B35 F969 +84308B36 F96A +84308B37 F96B +84308B38 F96C +84308B39 F96D +84308C30 F96E +84308C31 F96F +84308C32 F970 +84308C33 F971 +84308C34 F972 +84308C35 F973 +84308C36 F974 +84308C37 F975 +84308C38 F976 +84308C39 F977 +84308D30 F978 +FD9D F979 +84308D31 F97A +84308D32 F97B +84308D33 F97C +84308D34 F97D +84308D35 F97E +84308D36 F97F +84308D37 F980 +84308D38 F981 +84308D39 F982 +84308E30 F983 +84308E31 F984 +84308E32 F985 +84308E33 F986 +84308E34 F987 +84308E35 F988 +84308E36 F989 +84308E37 F98A +84308E38 F98B +84308E39 F98C +84308F30 F98D +84308F31 F98E +84308F32 F98F +84308F33 F990 +84308F34 F991 +84308F35 F992 +84308F36 F993 +84308F37 F994 +FD9E F995 +84308F38 F996 +84308F39 F997 +84309030 F998 +84309031 F999 +84309032 F99A +84309033 F99B +84309034 F99C +84309035 F99D +84309036 F99E +84309037 F99F +84309038 F9A0 +84309039 F9A1 +84309130 F9A2 +84309131 F9A3 +84309132 F9A4 +84309133 F9A5 +84309134 F9A6 +84309135 F9A7 +84309136 F9A8 +84309137 F9A9 +84309138 F9AA +84309139 F9AB +84309230 F9AC +84309231 F9AD +84309232 F9AE +84309233 F9AF +84309234 F9B0 +84309235 F9B1 +84309236 F9B2 +84309237 F9B3 +84309238 F9B4 +84309239 F9B5 +84309330 F9B6 +84309331 F9B7 +84309332 F9B8 +84309333 F9B9 +84309334 F9BA +84309335 F9BB +84309336 F9BC +84309337 F9BD +84309338 F9BE +84309339 F9BF +84309430 F9C0 +84309431 F9C1 +84309432 F9C2 +84309433 F9C3 +84309434 F9C4 +84309435 F9C5 +84309436 F9C6 +84309437 F9C7 +84309438 F9C8 +84309439 F9C9 +84309530 F9CA +84309531 F9CB +84309532 F9CC +84309533 F9CD +84309534 F9CE +84309535 F9CF +84309536 F9D0 +84309537 F9D1 +84309538 F9D2 +84309539 F9D3 +84309630 F9D4 +84309631 F9D5 +84309632 F9D6 +84309633 F9D7 +84309634 F9D8 +84309635 F9D9 +84309636 F9DA +84309637 F9DB +84309638 F9DC +84309639 F9DD +84309730 F9DE +84309731 F9DF +84309732 F9E0 +84309733 F9E1 +84309734 F9E2 +84309735 F9E3 +84309736 F9E4 +84309737 F9E5 +84309738 F9E6 +FD9F F9E7 +84309739 F9E8 +84309830 F9E9 +84309831 F9EA +84309832 F9EB +84309833 F9EC +84309834 F9ED +84309835 F9EE +84309836 F9EF +84309837 F9F0 +FDA0 F9F1 +84309838 F9F2 +84309839 F9F3 +84309930 F9F4 +84309931 F9F5 +84309932 F9F6 +84309933 F9F7 +84309934 F9F8 +84309935 F9F9 +84309936 F9FA +84309937 F9FB +84309938 F9FC +84309939 F9FD +84309A30 F9FE +84309A31 F9FF +84309A32 FA00 +84309A33 FA01 +84309A34 FA02 +84309A35 FA03 +84309A36 FA04 +84309A37 FA05 +84309A38 FA06 +84309A39 FA07 +84309B30 FA08 +84309B31 FA09 +84309B32 FA0A +84309B33 FA0B +FE40 FA0C +FE41 FA0D +FE42 FA0E +FE43 FA0F +84309B34 FA10 +FE44 FA11 +84309B35 FA12 +FE45 FA13 +FE46 FA14 +84309B36 FA15 +84309B37 FA16 +84309B38 FA17 +FE47 FA18 +84309B39 FA19 +84309C30 FA1A +84309C31 FA1B +84309C32 FA1C +84309C33 FA1D +84309C34 FA1E +FE48 FA1F +FE49 FA20 +FE4A FA21 +84309C35 FA22 +FE4B FA23 +FE4C FA24 +84309C36 FA25 +84309C37 FA26 +FE4D FA27 +FE4E FA28 +FE4F FA29 +84309C38 FA2A +84309C39 FA2B +84309D30 FA2C +84309D31 FA2D +84309D32 FA2E +84309D33 FA2F +84309D34 FA30 +84309D35 FA31 +84309D36 FA32 +84309D37 FA33 +84309D38 FA34 +84309D39 FA35 +84309E30 FA36 +84309E31 FA37 +84309E32 FA38 +84309E33 FA39 +84309E34 FA3A +84309E35 FA3B +84309E36 FA3C +84309E37 FA3D +84309E38 FA3E +84309E39 FA3F +84309F30 FA40 +84309F31 FA41 +84309F32 FA42 +84309F33 FA43 +84309F34 FA44 +84309F35 FA45 +84309F36 FA46 +84309F37 FA47 +84309F38 FA48 +84309F39 FA49 +8430A030 FA4A +8430A031 FA4B +8430A032 FA4C +8430A033 FA4D +8430A034 FA4E +8430A035 FA4F +8430A036 FA50 +8430A037 FA51 +8430A038 FA52 +8430A039 FA53 +8430A130 FA54 +8430A131 FA55 +8430A132 FA56 +8430A133 FA57 +8430A134 FA58 +8430A135 FA59 +8430A136 FA5A +8430A137 FA5B +8430A138 FA5C +8430A139 FA5D +8430A230 FA5E +8430A231 FA5F +8430A232 FA60 +8430A233 FA61 +8430A234 FA62 +8430A235 FA63 +8430A236 FA64 +8430A237 FA65 +8430A238 FA66 +8430A239 FA67 +8430A330 FA68 +8430A331 FA69 +8430A332 FA6A +8430A333 FA6B +8430A334 FA6C +8430A335 FA6D +8430A336 FA6E +8430A337 FA6F +8430A338 FA70 +8430A339 FA71 +8430A430 FA72 +8430A431 FA73 +8430A432 FA74 +8430A433 FA75 +8430A434 FA76 +8430A435 FA77 +8430A436 FA78 +8430A437 FA79 +8430A438 FA7A +8430A439 FA7B +8430A530 FA7C +8430A531 FA7D +8430A532 FA7E +8430A533 FA7F +8430A534 FA80 +8430A535 FA81 +8430A536 FA82 +8430A537 FA83 +8430A538 FA84 +8430A539 FA85 +8430A630 FA86 +8430A631 FA87 +8430A632 FA88 +8430A633 FA89 +8430A634 FA8A +8430A635 FA8B +8430A636 FA8C +8430A637 FA8D +8430A638 FA8E +8430A639 FA8F +8430A730 FA90 +8430A731 FA91 +8430A732 FA92 +8430A733 FA93 +8430A734 FA94 +8430A735 FA95 +8430A736 FA96 +8430A737 FA97 +8430A738 FA98 +8430A739 FA99 +8430A830 FA9A +8430A831 FA9B +8430A832 FA9C +8430A833 FA9D +8430A834 FA9E +8430A835 FA9F +8430A836 FAA0 +8430A837 FAA1 +8430A838 FAA2 +8430A839 FAA3 +8430A930 FAA4 +8430A931 FAA5 +8430A932 FAA6 +8430A933 FAA7 +8430A934 FAA8 +8430A935 FAA9 +8430A936 FAAA +8430A937 FAAB +8430A938 FAAC +8430A939 FAAD +8430AA30 FAAE +8430AA31 FAAF +8430AA32 FAB0 +8430AA33 FAB1 +8430AA34 FAB2 +8430AA35 FAB3 +8430AA36 FAB4 +8430AA37 FAB5 +8430AA38 FAB6 +8430AA39 FAB7 +8430AB30 FAB8 +8430AB31 FAB9 +8430AB32 FABA +8430AB33 FABB +8430AB34 FABC +8430AB35 FABD +8430AB36 FABE +8430AB37 FABF +8430AB38 FAC0 +8430AB39 FAC1 +8430AC30 FAC2 +8430AC31 FAC3 +8430AC32 FAC4 +8430AC33 FAC5 +8430AC34 FAC6 +8430AC35 FAC7 +8430AC36 FAC8 +8430AC37 FAC9 +8430AC38 FACA +8430AC39 FACB +8430AD30 FACC +8430AD31 FACD +8430AD32 FACE +8430AD33 FACF +8430AD34 FAD0 +8430AD35 FAD1 +8430AD36 FAD2 +8430AD37 FAD3 +8430AD38 FAD4 +8430AD39 FAD5 +8430AE30 FAD6 +8430AE31 FAD7 +8430AE32 FAD8 +8430AE33 FAD9 +8430AE34 FADA +8430AE35 FADB +8430AE36 FADC +8430AE37 FADD +8430AE38 FADE +8430AE39 FADF +8430AF30 FAE0 +8430AF31 FAE1 +8430AF32 FAE2 +8430AF33 FAE3 +8430AF34 FAE4 +8430AF35 FAE5 +8430AF36 FAE6 +8430AF37 FAE7 +8430AF38 FAE8 +8430AF39 FAE9 +8430B030 FAEA +8430B031 FAEB +8430B032 FAEC +8430B033 FAED +8430B034 FAEE +8430B035 FAEF +8430B036 FAF0 +8430B037 FAF1 +8430B038 FAF2 +8430B039 FAF3 +8430B130 FAF4 +8430B131 FAF5 +8430B132 FAF6 +8430B133 FAF7 +8430B134 FAF8 +8430B135 FAF9 +8430B136 FAFA +8430B137 FAFB +8430B138 FAFC +8430B139 FAFD +8430B230 FAFE +8430B231 FAFF +8430B232 FB00 +8430B233 FB01 +8430B234 FB02 +8430B235 FB03 +8430B236 FB04 +8430B237 FB05 +8430B238 FB06 +8430B239 FB07 +8430B330 FB08 +8430B331 FB09 +8430B332 FB0A +8430B333 FB0B +8430B334 FB0C +8430B335 FB0D +8430B336 FB0E +8430B337 FB0F +8430B338 FB10 +8430B339 FB11 +8430B430 FB12 +8430B431 FB13 +8430B432 FB14 +8430B433 FB15 +8430B434 FB16 +8430B435 FB17 +8430B436 FB18 +8430B437 FB19 +8430B438 FB1A +8430B439 FB1B +8430B530 FB1C +8430B531 FB1D +8430B532 FB1E +8430B533 FB1F +8430B534 FB20 +8430B535 FB21 +8430B536 FB22 +8430B537 FB23 +8430B538 FB24 +8430B539 FB25 +8430B630 FB26 +8430B631 FB27 +8430B632 FB28 +8430B633 FB29 +8430B634 FB2A +8430B635 FB2B +8430B636 FB2C +8430B637 FB2D +8430B638 FB2E +8430B639 FB2F +8430B730 FB30 +8430B731 FB31 +8430B732 FB32 +8430B733 FB33 +8430B734 FB34 +8430B735 FB35 +8430B736 FB36 +8430B737 FB37 +8430B738 FB38 +8430B739 FB39 +8430B830 FB3A +8430B831 FB3B +8430B832 FB3C +8430B833 FB3D +8430B834 FB3E +8430B835 FB3F +8430B836 FB40 +8430B837 FB41 +8430B838 FB42 +8430B839 FB43 +8430B930 FB44 +8430B931 FB45 +8430B932 FB46 +8430B933 FB47 +8430B934 FB48 +8430B935 FB49 +8430B936 FB4A +8430B937 FB4B +8430B938 FB4C +8430B939 FB4D +8430BA30 FB4E +8430BA31 FB4F +8430BA32 FB50 +8430BA33 FB51 +8430BA34 FB52 +8430BA35 FB53 +8430BA36 FB54 +8430BA37 FB55 +8430BA38 FB56 +8430BA39 FB57 +8430BB30 FB58 +8430BB31 FB59 +8430BB32 FB5A +8430BB33 FB5B +8430BB34 FB5C +8430BB35 FB5D +8430BB36 FB5E +8430BB37 FB5F +8430BB38 FB60 +8430BB39 FB61 +8430BC30 FB62 +8430BC31 FB63 +8430BC32 FB64 +8430BC33 FB65 +8430BC34 FB66 +8430BC35 FB67 +8430BC36 FB68 +8430BC37 FB69 +8430BC38 FB6A +8430BC39 FB6B +8430BD30 FB6C +8430BD31 FB6D +8430BD32 FB6E +8430BD33 FB6F +8430BD34 FB70 +8430BD35 FB71 +8430BD36 FB72 +8430BD37 FB73 +8430BD38 FB74 +8430BD39 FB75 +8430BE30 FB76 +8430BE31 FB77 +8430BE32 FB78 +8430BE33 FB79 +8430BE34 FB7A +8430BE35 FB7B +8430BE36 FB7C +8430BE37 FB7D +8430BE38 FB7E +8430BE39 FB7F +8430BF30 FB80 +8430BF31 FB81 +8430BF32 FB82 +8430BF33 FB83 +8430BF34 FB84 +8430BF35 FB85 +8430BF36 FB86 +8430BF37 FB87 +8430BF38 FB88 +8430BF39 FB89 +8430C030 FB8A +8430C031 FB8B +8430C032 FB8C +8430C033 FB8D +8430C034 FB8E +8430C035 FB8F +8430C036 FB90 +8430C037 FB91 +8430C038 FB92 +8430C039 FB93 +8430C130 FB94 +8430C131 FB95 +8430C132 FB96 +8430C133 FB97 +8430C134 FB98 +8430C135 FB99 +8430C136 FB9A +8430C137 FB9B +8430C138 FB9C +8430C139 FB9D +8430C230 FB9E +8430C231 FB9F +8430C232 FBA0 +8430C233 FBA1 +8430C234 FBA2 +8430C235 FBA3 +8430C236 FBA4 +8430C237 FBA5 +8430C238 FBA6 +8430C239 FBA7 +8430C330 FBA8 +8430C331 FBA9 +8430C332 FBAA +8430C333 FBAB +8430C334 FBAC +8430C335 FBAD +8430C336 FBAE +8430C337 FBAF +8430C338 FBB0 +8430C339 FBB1 +8430C430 FBB2 +8430C431 FBB3 +8430C432 FBB4 +8430C433 FBB5 +8430C434 FBB6 +8430C435 FBB7 +8430C436 FBB8 +8430C437 FBB9 +8430C438 FBBA +8430C439 FBBB +8430C530 FBBC +8430C531 FBBD +8430C532 FBBE +8430C533 FBBF +8430C534 FBC0 +8430C535 FBC1 +8430C536 FBC2 +8430C537 FBC3 +8430C538 FBC4 +8430C539 FBC5 +8430C630 FBC6 +8430C631 FBC7 +8430C632 FBC8 +8430C633 FBC9 +8430C634 FBCA +8430C635 FBCB +8430C636 FBCC +8430C637 FBCD +8430C638 FBCE +8430C639 FBCF +8430C730 FBD0 +8430C731 FBD1 +8430C732 FBD2 +8430C733 FBD3 +8430C734 FBD4 +8430C735 FBD5 +8430C736 FBD6 +8430C737 FBD7 +8430C738 FBD8 +8430C739 FBD9 +8430C830 FBDA +8430C831 FBDB +8430C832 FBDC +8430C833 FBDD +8430C834 FBDE +8430C835 FBDF +8430C836 FBE0 +8430C837 FBE1 +8430C838 FBE2 +8430C839 FBE3 +8430C930 FBE4 +8430C931 FBE5 +8430C932 FBE6 +8430C933 FBE7 +8430C934 FBE8 +8430C935 FBE9 +8430C936 FBEA +8430C937 FBEB +8430C938 FBEC +8430C939 FBED +8430CA30 FBEE +8430CA31 FBEF +8430CA32 FBF0 +8430CA33 FBF1 +8430CA34 FBF2 +8430CA35 FBF3 +8430CA36 FBF4 +8430CA37 FBF5 +8430CA38 FBF6 +8430CA39 FBF7 +8430CB30 FBF8 +8430CB31 FBF9 +8430CB32 FBFA +8430CB33 FBFB +8430CB34 FBFC +8430CB35 FBFD +8430CB36 FBFE +8430CB37 FBFF +8430CB38 FC00 +8430CB39 FC01 +8430CC30 FC02 +8430CC31 FC03 +8430CC32 FC04 +8430CC33 FC05 +8430CC34 FC06 +8430CC35 FC07 +8430CC36 FC08 +8430CC37 FC09 +8430CC38 FC0A +8430CC39 FC0B +8430CD30 FC0C +8430CD31 FC0D +8430CD32 FC0E +8430CD33 FC0F +8430CD34 FC10 +8430CD35 FC11 +8430CD36 FC12 +8430CD37 FC13 +8430CD38 FC14 +8430CD39 FC15 +8430CE30 FC16 +8430CE31 FC17 +8430CE32 FC18 +8430CE33 FC19 +8430CE34 FC1A +8430CE35 FC1B +8430CE36 FC1C +8430CE37 FC1D +8430CE38 FC1E +8430CE39 FC1F +8430CF30 FC20 +8430CF31 FC21 +8430CF32 FC22 +8430CF33 FC23 +8430CF34 FC24 +8430CF35 FC25 +8430CF36 FC26 +8430CF37 FC27 +8430CF38 FC28 +8430CF39 FC29 +8430D030 FC2A +8430D031 FC2B +8430D032 FC2C +8430D033 FC2D +8430D034 FC2E +8430D035 FC2F +8430D036 FC30 +8430D037 FC31 +8430D038 FC32 +8430D039 FC33 +8430D130 FC34 +8430D131 FC35 +8430D132 FC36 +8430D133 FC37 +8430D134 FC38 +8430D135 FC39 +8430D136 FC3A +8430D137 FC3B +8430D138 FC3C +8430D139 FC3D +8430D230 FC3E +8430D231 FC3F +8430D232 FC40 +8430D233 FC41 +8430D234 FC42 +8430D235 FC43 +8430D236 FC44 +8430D237 FC45 +8430D238 FC46 +8430D239 FC47 +8430D330 FC48 +8430D331 FC49 +8430D332 FC4A +8430D333 FC4B +8430D334 FC4C +8430D335 FC4D +8430D336 FC4E +8430D337 FC4F +8430D338 FC50 +8430D339 FC51 +8430D430 FC52 +8430D431 FC53 +8430D432 FC54 +8430D433 FC55 +8430D434 FC56 +8430D435 FC57 +8430D436 FC58 +8430D437 FC59 +8430D438 FC5A +8430D439 FC5B +8430D530 FC5C +8430D531 FC5D +8430D532 FC5E +8430D533 FC5F +8430D534 FC60 +8430D535 FC61 +8430D536 FC62 +8430D537 FC63 +8430D538 FC64 +8430D539 FC65 +8430D630 FC66 +8430D631 FC67 +8430D632 FC68 +8430D633 FC69 +8430D634 FC6A +8430D635 FC6B +8430D636 FC6C +8430D637 FC6D +8430D638 FC6E +8430D639 FC6F +8430D730 FC70 +8430D731 FC71 +8430D732 FC72 +8430D733 FC73 +8430D734 FC74 +8430D735 FC75 +8430D736 FC76 +8430D737 FC77 +8430D738 FC78 +8430D739 FC79 +8430D830 FC7A +8430D831 FC7B +8430D832 FC7C +8430D833 FC7D +8430D834 FC7E +8430D835 FC7F +8430D836 FC80 +8430D837 FC81 +8430D838 FC82 +8430D839 FC83 +8430D930 FC84 +8430D931 FC85 +8430D932 FC86 +8430D933 FC87 +8430D934 FC88 +8430D935 FC89 +8430D936 FC8A +8430D937 FC8B +8430D938 FC8C +8430D939 FC8D +8430DA30 FC8E +8430DA31 FC8F +8430DA32 FC90 +8430DA33 FC91 +8430DA34 FC92 +8430DA35 FC93 +8430DA36 FC94 +8430DA37 FC95 +8430DA38 FC96 +8430DA39 FC97 +8430DB30 FC98 +8430DB31 FC99 +8430DB32 FC9A +8430DB33 FC9B +8430DB34 FC9C +8430DB35 FC9D +8430DB36 FC9E +8430DB37 FC9F +8430DB38 FCA0 +8430DB39 FCA1 +8430DC30 FCA2 +8430DC31 FCA3 +8430DC32 FCA4 +8430DC33 FCA5 +8430DC34 FCA6 +8430DC35 FCA7 +8430DC36 FCA8 +8430DC37 FCA9 +8430DC38 FCAA +8430DC39 FCAB +8430DD30 FCAC +8430DD31 FCAD +8430DD32 FCAE +8430DD33 FCAF +8430DD34 FCB0 +8430DD35 FCB1 +8430DD36 FCB2 +8430DD37 FCB3 +8430DD38 FCB4 +8430DD39 FCB5 +8430DE30 FCB6 +8430DE31 FCB7 +8430DE32 FCB8 +8430DE33 FCB9 +8430DE34 FCBA +8430DE35 FCBB +8430DE36 FCBC +8430DE37 FCBD +8430DE38 FCBE +8430DE39 FCBF +8430DF30 FCC0 +8430DF31 FCC1 +8430DF32 FCC2 +8430DF33 FCC3 +8430DF34 FCC4 +8430DF35 FCC5 +8430DF36 FCC6 +8430DF37 FCC7 +8430DF38 FCC8 +8430DF39 FCC9 +8430E030 FCCA +8430E031 FCCB +8430E032 FCCC +8430E033 FCCD +8430E034 FCCE +8430E035 FCCF +8430E036 FCD0 +8430E037 FCD1 +8430E038 FCD2 +8430E039 FCD3 +8430E130 FCD4 +8430E131 FCD5 +8430E132 FCD6 +8430E133 FCD7 +8430E134 FCD8 +8430E135 FCD9 +8430E136 FCDA +8430E137 FCDB +8430E138 FCDC +8430E139 FCDD +8430E230 FCDE +8430E231 FCDF +8430E232 FCE0 +8430E233 FCE1 +8430E234 FCE2 +8430E235 FCE3 +8430E236 FCE4 +8430E237 FCE5 +8430E238 FCE6 +8430E239 FCE7 +8430E330 FCE8 +8430E331 FCE9 +8430E332 FCEA +8430E333 FCEB +8430E334 FCEC +8430E335 FCED +8430E336 FCEE +8430E337 FCEF +8430E338 FCF0 +8430E339 FCF1 +8430E430 FCF2 +8430E431 FCF3 +8430E432 FCF4 +8430E433 FCF5 +8430E434 FCF6 +8430E435 FCF7 +8430E436 FCF8 +8430E437 FCF9 +8430E438 FCFA +8430E439 FCFB +8430E530 FCFC +8430E531 FCFD +8430E532 FCFE +8430E533 FCFF +8430E534 FD00 +8430E535 FD01 +8430E536 FD02 +8430E537 FD03 +8430E538 FD04 +8430E539 FD05 +8430E630 FD06 +8430E631 FD07 +8430E632 FD08 +8430E633 FD09 +8430E634 FD0A +8430E635 FD0B +8430E636 FD0C +8430E637 FD0D +8430E638 FD0E +8430E639 FD0F +8430E730 FD10 +8430E731 FD11 +8430E732 FD12 +8430E733 FD13 +8430E734 FD14 +8430E735 FD15 +8430E736 FD16 +8430E737 FD17 +8430E738 FD18 +8430E739 FD19 +8430E830 FD1A +8430E831 FD1B +8430E832 FD1C +8430E833 FD1D +8430E834 FD1E +8430E835 FD1F +8430E836 FD20 +8430E837 FD21 +8430E838 FD22 +8430E839 FD23 +8430E930 FD24 +8430E931 FD25 +8430E932 FD26 +8430E933 FD27 +8430E934 FD28 +8430E935 FD29 +8430E936 FD2A +8430E937 FD2B +8430E938 FD2C +8430E939 FD2D +8430EA30 FD2E +8430EA31 FD2F +8430EA32 FD30 +8430EA33 FD31 +8430EA34 FD32 +8430EA35 FD33 +8430EA36 FD34 +8430EA37 FD35 +8430EA38 FD36 +8430EA39 FD37 +8430EB30 FD38 +8430EB31 FD39 +8430EB32 FD3A +8430EB33 FD3B +8430EB34 FD3C +8430EB35 FD3D +8430EB36 FD3E +8430EB37 FD3F +8430EB38 FD40 +8430EB39 FD41 +8430EC30 FD42 +8430EC31 FD43 +8430EC32 FD44 +8430EC33 FD45 +8430EC34 FD46 +8430EC35 FD47 +8430EC36 FD48 +8430EC37 FD49 +8430EC38 FD4A +8430EC39 FD4B +8430ED30 FD4C +8430ED31 FD4D +8430ED32 FD4E +8430ED33 FD4F +8430ED34 FD50 +8430ED35 FD51 +8430ED36 FD52 +8430ED37 FD53 +8430ED38 FD54 +8430ED39 FD55 +8430EE30 FD56 +8430EE31 FD57 +8430EE32 FD58 +8430EE33 FD59 +8430EE34 FD5A +8430EE35 FD5B +8430EE36 FD5C +8430EE37 FD5D +8430EE38 FD5E +8430EE39 FD5F +8430EF30 FD60 +8430EF31 FD61 +8430EF32 FD62 +8430EF33 FD63 +8430EF34 FD64 +8430EF35 FD65 +8430EF36 FD66 +8430EF37 FD67 +8430EF38 FD68 +8430EF39 FD69 +8430F030 FD6A +8430F031 FD6B +8430F032 FD6C +8430F033 FD6D +8430F034 FD6E +8430F035 FD6F +8430F036 FD70 +8430F037 FD71 +8430F038 FD72 +8430F039 FD73 +8430F130 FD74 +8430F131 FD75 +8430F132 FD76 +8430F133 FD77 +8430F134 FD78 +8430F135 FD79 +8430F136 FD7A +8430F137 FD7B +8430F138 FD7C +8430F139 FD7D +8430F230 FD7E +8430F231 FD7F +8430F232 FD80 +8430F233 FD81 +8430F234 FD82 +8430F235 FD83 +8430F236 FD84 +8430F237 FD85 +8430F238 FD86 +8430F239 FD87 +8430F330 FD88 +8430F331 FD89 +8430F332 FD8A +8430F333 FD8B +8430F334 FD8C +8430F335 FD8D +8430F336 FD8E +8430F337 FD8F +8430F338 FD90 +8430F339 FD91 +8430F430 FD92 +8430F431 FD93 +8430F432 FD94 +8430F433 FD95 +8430F434 FD96 +8430F435 FD97 +8430F436 FD98 +8430F437 FD99 +8430F438 FD9A +8430F439 FD9B +8430F530 FD9C +8430F531 FD9D +8430F532 FD9E +8430F533 FD9F +8430F534 FDA0 +8430F535 FDA1 +8430F536 FDA2 +8430F537 FDA3 +8430F538 FDA4 +8430F539 FDA5 +8430F630 FDA6 +8430F631 FDA7 +8430F632 FDA8 +8430F633 FDA9 +8430F634 FDAA +8430F635 FDAB +8430F636 FDAC +8430F637 FDAD +8430F638 FDAE +8430F639 FDAF +8430F730 FDB0 +8430F731 FDB1 +8430F732 FDB2 +8430F733 FDB3 +8430F734 FDB4 +8430F735 FDB5 +8430F736 FDB6 +8430F737 FDB7 +8430F738 FDB8 +8430F739 FDB9 +8430F830 FDBA +8430F831 FDBB +8430F832 FDBC +8430F833 FDBD +8430F834 FDBE +8430F835 FDBF +8430F836 FDC0 +8430F837 FDC1 +8430F838 FDC2 +8430F839 FDC3 +8430F930 FDC4 +8430F931 FDC5 +8430F932 FDC6 +8430F933 FDC7 +8430F934 FDC8 +8430F935 FDC9 +8430F936 FDCA +8430F937 FDCB +8430F938 FDCC +8430F939 FDCD +8430FA30 FDCE +8430FA31 FDCF +8430FA32 FDD0 +8430FA33 FDD1 +8430FA34 FDD2 +8430FA35 FDD3 +8430FA36 FDD4 +8430FA37 FDD5 +8430FA38 FDD6 +8430FA39 FDD7 +8430FB30 FDD8 +8430FB31 FDD9 +8430FB32 FDDA +8430FB33 FDDB +8430FB34 FDDC +8430FB35 FDDD +8430FB36 FDDE +8430FB37 FDDF +8430FB38 FDE0 +8430FB39 FDE1 +8430FC30 FDE2 +8430FC31 FDE3 +8430FC32 FDE4 +8430FC33 FDE5 +8430FC34 FDE6 +8430FC35 FDE7 +8430FC36 FDE8 +8430FC37 FDE9 +8430FC38 FDEA +8430FC39 FDEB +8430FD30 FDEC +8430FD31 FDED +8430FD32 FDEE +8430FD33 FDEF +8430FD34 FDF0 +8430FD35 FDF1 +8430FD36 FDF2 +8430FD37 FDF3 +8430FD38 FDF4 +8430FD39 FDF5 +8430FE30 FDF6 +8430FE31 FDF7 +8430FE32 FDF8 +8430FE33 FDF9 +8430FE34 FDFA +8430FE35 FDFB +8430FE36 FDFC +8430FE37 FDFD +8430FE38 FDFE +8430FE39 FDFF +84318130 FE00 +84318131 FE01 +84318132 FE02 +84318133 FE03 +84318134 FE04 +84318135 FE05 +84318136 FE06 +84318137 FE07 +84318138 FE08 +84318139 FE09 +84318230 FE0A +84318231 FE0B +84318232 FE0C +84318233 FE0D +84318234 FE0E +84318235 FE0F +84318236 FE10 +84318237 FE11 +84318238 FE12 +84318239 FE13 +84318330 FE14 +84318331 FE15 +84318332 FE16 +84318333 FE17 +84318334 FE18 +84318335 FE19 +84318336 FE1A +84318337 FE1B +84318338 FE1C +84318339 FE1D +84318430 FE1E +84318431 FE1F +84318432 FE20 +84318433 FE21 +84318434 FE22 +84318435 FE23 +84318436 FE24 +84318437 FE25 +84318438 FE26 +84318439 FE27 +84318530 FE28 +84318531 FE29 +84318532 FE2A +84318533 FE2B +84318534 FE2C +84318535 FE2D +84318536 FE2E +84318537 FE2F +A955 FE30 +A6F2 FE31 +84318538 FE32 +A6F4 FE33 +A6F5 FE34 +A6E0 FE35 +A6E1 FE36 +A6F0 FE37 +A6F1 FE38 +A6E2 FE39 +A6E3 FE3A +A6EE FE3B +A6EF FE3C +A6E6 FE3D +A6E7 FE3E +A6E4 FE3F +A6E5 FE40 +A6E8 FE41 +A6E9 FE42 +A6EA FE43 +A6EB FE44 +84318539 FE45 +84318630 FE46 +84318631 FE47 +84318632 FE48 +A968 FE49 +A969 FE4A +A96A FE4B +A96B FE4C +A96C FE4D +A96D FE4E +A96E FE4F +A96F FE50 +A970 FE51 +A971 FE52 +84318633 FE53 +A972 FE54 +A973 FE55 +A974 FE56 +A975 FE57 +84318634 FE58 +A976 FE59 +A977 FE5A +A978 FE5B +A979 FE5C +A97A FE5D +A97B FE5E +A97C FE5F +A97D FE60 +A97E FE61 +A980 FE62 +A981 FE63 +A982 FE64 +A983 FE65 +A984 FE66 +84318635 FE67 +A985 FE68 +A986 FE69 +A987 FE6A +A988 FE6B +84318636 FE6C +84318637 FE6D +84318638 FE6E +84318639 FE6F +84318730 FE70 +84318731 FE71 +84318732 FE72 +84318733 FE73 +84318734 FE74 +84318735 FE75 +84318736 FE76 +84318737 FE77 +84318738 FE78 +84318739 FE79 +84318830 FE7A +84318831 FE7B +84318832 FE7C +84318833 FE7D +84318834 FE7E +84318835 FE7F +84318836 FE80 +84318837 FE81 +84318838 FE82 +84318839 FE83 +84318930 FE84 +84318931 FE85 +84318932 FE86 +84318933 FE87 +84318934 FE88 +84318935 FE89 +84318936 FE8A +84318937 FE8B +84318938 FE8C +84318939 FE8D +84318A30 FE8E +84318A31 FE8F +84318A32 FE90 +84318A33 FE91 +84318A34 FE92 +84318A35 FE93 +84318A36 FE94 +84318A37 FE95 +84318A38 FE96 +84318A39 FE97 +84318B30 FE98 +84318B31 FE99 +84318B32 FE9A +84318B33 FE9B +84318B34 FE9C +84318B35 FE9D +84318B36 FE9E +84318B37 FE9F +84318B38 FEA0 +84318B39 FEA1 +84318C30 FEA2 +84318C31 FEA3 +84318C32 FEA4 +84318C33 FEA5 +84318C34 FEA6 +84318C35 FEA7 +84318C36 FEA8 +84318C37 FEA9 +84318C38 FEAA +84318C39 FEAB +84318D30 FEAC +84318D31 FEAD +84318D32 FEAE +84318D33 FEAF +84318D34 FEB0 +84318D35 FEB1 +84318D36 FEB2 +84318D37 FEB3 +84318D38 FEB4 +84318D39 FEB5 +84318E30 FEB6 +84318E31 FEB7 +84318E32 FEB8 +84318E33 FEB9 +84318E34 FEBA +84318E35 FEBB +84318E36 FEBC +84318E37 FEBD +84318E38 FEBE +84318E39 FEBF +84318F30 FEC0 +84318F31 FEC1 +84318F32 FEC2 +84318F33 FEC3 +84318F34 FEC4 +84318F35 FEC5 +84318F36 FEC6 +84318F37 FEC7 +84318F38 FEC8 +84318F39 FEC9 +84319030 FECA +84319031 FECB +84319032 FECC +84319033 FECD +84319034 FECE +84319035 FECF +84319036 FED0 +84319037 FED1 +84319038 FED2 +84319039 FED3 +84319130 FED4 +84319131 FED5 +84319132 FED6 +84319133 FED7 +84319134 FED8 +84319135 FED9 +84319136 FEDA +84319137 FEDB +84319138 FEDC +84319139 FEDD +84319230 FEDE +84319231 FEDF +84319232 FEE0 +84319233 FEE1 +84319234 FEE2 +84319235 FEE3 +84319236 FEE4 +84319237 FEE5 +84319238 FEE6 +84319239 FEE7 +84319330 FEE8 +84319331 FEE9 +84319332 FEEA +84319333 FEEB +84319334 FEEC +84319335 FEED +84319336 FEEE +84319337 FEEF +84319338 FEF0 +84319339 FEF1 +84319430 FEF2 +84319431 FEF3 +84319432 FEF4 +84319433 FEF5 +84319434 FEF6 +84319435 FEF7 +84319436 FEF8 +84319437 FEF9 +84319438 FEFA +84319439 FEFB +84319530 FEFC +84319531 FEFD +84319532 FEFE +84319533 FEFF +84319534 FF00 +A3A1 FF01 +A3A2 FF02 +A3A3 FF03 +A1E7 FF04 +A3A5 FF05 +A3A6 FF06 +A3A7 FF07 +A3A8 FF08 +A3A9 FF09 +A3AA FF0A +A3AB FF0B +A3AC FF0C +A3AD FF0D +A3AE FF0E +A3AF FF0F +A3B0 FF10 +A3B1 FF11 +A3B2 FF12 +A3B3 FF13 +A3B4 FF14 +A3B5 FF15 +A3B6 FF16 +A3B7 FF17 +A3B8 FF18 +A3B9 FF19 +A3BA FF1A +A3BB FF1B +A3BC FF1C +A3BD FF1D +A3BE FF1E +A3BF FF1F +A3C0 FF20 +A3C1 FF21 +A3C2 FF22 +A3C3 FF23 +A3C4 FF24 +A3C5 FF25 +A3C6 FF26 +A3C7 FF27 +A3C8 FF28 +A3C9 FF29 +A3CA FF2A +A3CB FF2B +A3CC FF2C +A3CD FF2D +A3CE FF2E +A3CF FF2F +A3D0 FF30 +A3D1 FF31 +A3D2 FF32 +A3D3 FF33 +A3D4 FF34 +A3D5 FF35 +A3D6 FF36 +A3D7 FF37 +A3D8 FF38 +A3D9 FF39 +A3DA FF3A +A3DB FF3B +A3DC FF3C +A3DD FF3D +A3DE FF3E +A3DF FF3F +A3E0 FF40 +A3E1 FF41 +A3E2 FF42 +A3E3 FF43 +A3E4 FF44 +A3E5 FF45 +A3E6 FF46 +A3E7 FF47 +A3E8 FF48 +A3E9 FF49 +A3EA FF4A +A3EB FF4B +A3EC FF4C +A3ED FF4D +A3EE FF4E +A3EF FF4F +A3F0 FF50 +A3F1 FF51 +A3F2 FF52 +A3F3 FF53 +A3F4 FF54 +A3F5 FF55 +A3F6 FF56 +A3F7 FF57 +A3F8 FF58 +A3F9 FF59 +A3FA FF5A +A3FB FF5B +A3FC FF5C +A3FD FF5D +A1AB FF5E +84319535 FF5F +84319536 FF60 +84319537 FF61 +84319538 FF62 +84319539 FF63 +84319630 FF64 +84319631 FF65 +84319632 FF66 +84319633 FF67 +84319634 FF68 +84319635 FF69 +84319636 FF6A +84319637 FF6B +84319638 FF6C +84319639 FF6D +84319730 FF6E +84319731 FF6F +84319732 FF70 +84319733 FF71 +84319734 FF72 +84319735 FF73 +84319736 FF74 +84319737 FF75 +84319738 FF76 +84319739 FF77 +84319830 FF78 +84319831 FF79 +84319832 FF7A +84319833 FF7B +84319834 FF7C +84319835 FF7D +84319836 FF7E +84319837 FF7F +84319838 FF80 +84319839 FF81 +84319930 FF82 +84319931 FF83 +84319932 FF84 +84319933 FF85 +84319934 FF86 +84319935 FF87 +84319936 FF88 +84319937 FF89 +84319938 FF8A +84319939 FF8B +84319A30 FF8C +84319A31 FF8D +84319A32 FF8E +84319A33 FF8F +84319A34 FF90 +84319A35 FF91 +84319A36 FF92 +84319A37 FF93 +84319A38 FF94 +84319A39 FF95 +84319B30 FF96 +84319B31 FF97 +84319B32 FF98 +84319B33 FF99 +84319B34 FF9A +84319B35 FF9B +84319B36 FF9C +84319B37 FF9D +84319B38 FF9E +84319B39 FF9F +84319C30 FFA0 +84319C31 FFA1 +84319C32 FFA2 +84319C33 FFA3 +84319C34 FFA4 +84319C35 FFA5 +84319C36 FFA6 +84319C37 FFA7 +84319C38 FFA8 +84319C39 FFA9 +84319D30 FFAA +84319D31 FFAB +84319D32 FFAC +84319D33 FFAD +84319D34 FFAE +84319D35 FFAF +84319D36 FFB0 +84319D37 FFB1 +84319D38 FFB2 +84319D39 FFB3 +84319E30 FFB4 +84319E31 FFB5 +84319E32 FFB6 +84319E33 FFB7 +84319E34 FFB8 +84319E35 FFB9 +84319E36 FFBA +84319E37 FFBB +84319E38 FFBC +84319E39 FFBD +84319F30 FFBE +84319F31 FFBF +84319F32 FFC0 +84319F33 FFC1 +84319F34 FFC2 +84319F35 FFC3 +84319F36 FFC4 +84319F37 FFC5 +84319F38 FFC6 +84319F39 FFC7 +8431A030 FFC8 +8431A031 FFC9 +8431A032 FFCA +8431A033 FFCB +8431A034 FFCC +8431A035 FFCD +8431A036 FFCE +8431A037 FFCF +8431A038 FFD0 +8431A039 FFD1 +8431A130 FFD2 +8431A131 FFD3 +8431A132 FFD4 +8431A133 FFD5 +8431A134 FFD6 +8431A135 FFD7 +8431A136 FFD8 +8431A137 FFD9 +8431A138 FFDA +8431A139 FFDB +8431A230 FFDC +8431A231 FFDD +8431A232 FFDE +8431A233 FFDF +A1E9 FFE0 +A1EA FFE1 +A956 FFE2 +A3FE FFE3 +A957 FFE4 +A3A4 FFE5 +8431A234 FFE6 +8431A235 FFE7 +8431A236 FFE8 +8431A237 FFE9 +8431A238 FFEA +8431A239 FFEB +8431A330 FFEC +8431A331 FFED +8431A332 FFEE +8431A333 FFEF +8431A334 FFF0 +8431A335 FFF1 +8431A336 FFF2 +8431A337 FFF3 +8431A338 FFF4 +8431A339 FFF5 +8431A430 FFF6 +8431A431 FFF7 +8431A432 FFF8 +8431A433 FFF9 +8431A434 FFFA +8431A435 FFFB +8431A436 FFFC +8431A437 FFFD +#8431A438 FFFE +#8431A439 FFFF diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/mapping/GB18030.b2c openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/mapping/GB18030.b2c --- openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/mapping/GB18030.b2c 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/mapping/GB18030.b2c 2023-07-05 07:11:54.000000000 +0000 @@ -1,3 +1,4 @@ +# based on GB18030-2022 mapping 00 0000 01 0001 02 0002 @@ -7741,7 +7742,7 @@ 8135F434 1E3C 8135F435 1E3D 8135F436 1E3E -8135F437 1E3F +A8BC 1E3F 8135F438 1E40 8135F439 1E41 8135F530 1E42 @@ -40882,14 +40883,14 @@ 82359034 9FB1 82359035 9FB2 82359036 9FB3 -82359037 9FB4 -82359038 9FB5 -82359039 9FB6 -82359130 9FB7 -82359131 9FB8 -82359132 9FB9 -82359133 9FBA -82359134 9FBB +82359037 E81E +82359038 E826 +82359039 E82B +82359130 E82C +82359131 E832 +82359132 E843 +82359133 E854 +82359134 E864 82359135 9FBC 82359136 9FBD 82359137 9FBE @@ -57227,16 +57228,16 @@ A6BE E78A A6BF E78B A6C0 E78C -A6D9 E78D -A6DA E78E -A6DB E78F -A6DC E790 -A6DD E791 -A6DE E792 -A6DF E793 -A6EC E794 -A6ED E795 -A6F3 E796 +A6D9 FE10 +A6DA FE12 +A6DB FE11 +A6DC FE13 +A6DD FE14 +A6DE FE15 +A6DF FE16 +A6EC FE17 +A6ED FE18 +A6F3 FE19 A6F6 E797 A6F7 E798 A6F8 E799 @@ -57285,7 +57286,7 @@ A89E E7C4 A89F E7C5 A8A0 E7C6 -A8BC E7C7 +8135F437 E7C7 8336C830 E7C8 A8C1 E7C9 A8C2 E7CA @@ -57372,7 +57373,7 @@ 8336C937 E81B 8336C938 E81C 8336C939 E81D -FE59 E81E +FE59 9FB4 8336CA30 E81F 8336CA31 E820 8336CA32 E821 @@ -57380,19 +57381,19 @@ 8336CA34 E823 8336CA35 E824 8336CA36 E825 -FE61 E826 +FE61 9FB5 8336CA37 E827 8336CA38 E828 8336CA39 E829 8336CB30 E82A -FE66 E82B -FE67 E82C +FE66 9FB6 +FE67 9FB7 8336CB31 E82D 8336CB32 E82E 8336CB33 E82F 8336CB34 E830 FE6C E831 -FE6D E832 +FE6D 9FB8 8336CB35 E833 8336CB36 E834 8336CB37 E835 @@ -57409,7 +57410,7 @@ 8336CC37 E840 8336CC38 E841 8336CC39 E842 -FE7E E843 +FE7E 9FB9 8336CD30 E844 8336CD31 E845 8336CD32 E846 @@ -57426,7 +57427,7 @@ 8336CE33 E851 8336CE34 E852 8336CE35 E853 -FE90 E854 +FE90 9FBA FE91 E855 8336CE36 E856 8336CE37 E857 @@ -57442,7 +57443,7 @@ 8336CF37 E861 8336CF38 E862 8336CF39 E863 -FEA0 E864 +FEA0 9FBB 8336D030 E865 8336D031 E866 8336D032 E867 @@ -62990,16 +62991,16 @@ 84318233 FE0D 84318234 FE0E 84318235 FE0F -84318236 FE10 -84318237 FE11 -84318238 FE12 -84318239 FE13 -84318330 FE14 -84318331 FE15 -84318332 FE16 -84318333 FE17 -84318334 FE18 -84318335 FE19 +84318236 E78D +84318237 E78F +84318238 E78E +84318239 E790 +84318330 E791 +84318331 E792 +84318332 E793 +84318333 E794 +84318334 E795 +84318335 E796 84318336 FE1A 84318337 FE1B 84318338 FE1C @@ -63484,5 +63485,5 @@ 8431A435 FFFB 8431A436 FFFC 8431A437 FFFD -#8431A438 FFFE -#8431A439 FFFF +8431A438 FFFE +8431A439 FFFF diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/TestGB18030.java openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/TestGB18030.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/nio/cs/TestGB18030.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/nio/cs/TestGB18030.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * 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,20 +22,22 @@ */ /* @test - * @bug 8211382 + * @bug 8211382 8301119 * @summary Check GB18030 * @modules jdk.charsets + * @run main TestGB18030 + * @run main/othervm -Djdk.charset.GB18030=2000 TestGB18030 */ -import java.io.*; import java.nio.*; import java.nio.charset.*; +import java.util.Set; public class TestGB18030 { + private static final Charset cs = Charset.forName("GB18030"); public static void gb18030_1(boolean useDirect) throws Exception { for(char ch : new char[]{'\uFFFE', '\uFFFF'}) { char[] ca = new char[]{ch}; - Charset cs = Charset.forName("GB18030"); CharsetEncoder ce = cs.newEncoder(); CharsetDecoder cd = cs.newDecoder(); CharBuffer cb = CharBuffer.wrap(ca); @@ -75,8 +77,19 @@ } } } + + static void checkAlias() { + var IS_2000 = "2000".equals(System.getProperty("jdk.charset.GB18030")); + var expected = IS_2000 ? Set.of("gb18030-2000") : Set.of("gb18030-2022"); + var found = cs.aliases(); + System.out.printf("checkAlias(): IS_2000: %s, expected: %s, found: %s\n", IS_2000, expected, found); + if (!cs.aliases().equals(expected)) { + throw new RuntimeException("Result mismatch"); + } + } public static void main(String args[]) throws Exception { gb18030_1(false); gb18030_1(true); + checkAlias(); } } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java openjdk-17-17.0.8+7/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java 2023-07-05 07:11:54.000000000 +0000 @@ -28,6 +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 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -36,16 +37,8 @@ import java.nio.file.Path; import java.security.KeyStore; import java.security.MessageDigest; -import java.security.cert.Certificate; -import java.security.cert.CertificateExpiredException; -import java.security.cert.CertificateNotYetValidException; -import java.security.cert.X509Certificate; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.HexFormat; -import java.util.Map; +import java.security.cert.*; +import java.util.*; public class VerifyCACerts { @@ -54,12 +47,12 @@ + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 90; + private static final int COUNT = 97; // 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 - = "21:8C:35:29:4C:E2:49:D2:83:30:DF:8B:5E:39:F8:8C:D6:C5:2B:59:05:32:74:E5:79:A5:91:9F:3C:57:B9:E3"; + = "72:C7:B8:9E:54:94:D2:D9:C0:E5:9F:F7:C3:8C:3B:18:D7:42:23:82:51:F2:AD:A1:14:26:E0:4A:F2:5F:AE:80"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -248,10 +241,23 @@ "44:B5:45:AA:8A:25:E6:5A:73:CA:15:DC:27:FC:36:D2:4C:1C:B9:95:3A:06:65:39:B1:15:82:DC:48:7B:48:33"); put("certignaca [jdk]", "E3:B6:A2:DB:2E:D7:CE:48:84:2F:7A:C5:32:41:C7:B7:1D:54:14:4B:FB:40:C1:1F:3F:1D:0B:42:F5:EE:A1:2D"); + put("twcaglobalrootca [jdk]", + "59:76:90:07:F7:68:5D:0F:CD:50:87:2F:9F:95:D5:75:5A:5B:2B:45:7D:81:F3:69:2B:61:0A:98:67:2F:0E:1B"); + put("microsoftecc2017 [jdk]", + "35:8D:F3:9D:76:4A:F9:E1:B7:66:E9:C9:72:DF:35:2E:E1:5C:FA:C2:27:AF:6A:D1:D7:0E:8E:4A:6E:DC:BA:02"); + put("microsoftrsa2017 [jdk]", + "C7:41:F7:0F:4B:2A:8D:88:BF:2E:71:C1:41:22:EF:53:EF:10:EB:A0:CF:A5:E6:4C:FA:20:F4:18:85:30:73:E0"); + put("gtsrootcar1 [jdk]", + "D9:47:43:2A:BD:E7:B7:FA:90:FC:2E:6B:59:10:1B:12:80:E0:E1:C7:E4:E4:0F:A3:C6:88:7F:FF:57:A7:F4:CF"); + put("gtsrootcar2 [jdk]", + "8D:25:CD:97:22:9D:BF:70:35:6B:DA:4E:B3:CC:73:40:31:E2:4C:F0:0F:AF:CF:D3:2D:C7:6E:B5:84:1C:7E:A8"); + put("gtsrootecccar3 [jdk]", + "34:D8:A7:3E:E2:08:D9:BC:DB:0D:95:65:20:93:4B:4E:40:E6:94:82:59:6E:8B:6F:73:C8:42:6B:01:0A:6F:48"); + put("gtsrootecccar4 [jdk]", + "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"); } }; - // Exception list to 90 days expiry policy // No error will be reported if certificate in this list expires @SuppressWarnings("serial") private static final HashSet EXPIRY_EXC_ENTRIES = new HashSet<>() { @@ -280,14 +286,15 @@ public static void main(String[] args) throws Exception { System.out.println("cacerts file: " + CACERTS); - md = MessageDigest.getInstance("SHA-256"); + // verify integrity of cacerts + md = MessageDigest.getInstance("SHA-256"); byte[] data = Files.readAllBytes(Path.of(CACERTS)); String checksum = HEX.formatHex(md.digest(data)); if (!checksum.equals(CHECKSUM)) { atLeastOneFailed = true; - System.err.println("ERROR: wrong checksum\n" + checksum); - System.err.println("Expected checksum\n" + CHECKSUM); + System.err.println("ERROR: wrong checksum" + checksum); + System.err.println("Expected checksum" + CHECKSUM); } KeyStore ks = KeyStore.getInstance("JKS"); @@ -300,6 +307,15 @@ + COUNT); } + System.out.println("Trusted CA Certificate count: " + ks.size()); + + // also ensure FINGERPRINT_MAP lists correct count + if (FINGERPRINT_MAP.size() != COUNT) { + atLeastOneFailed = true; + System.err.println("ERROR: " + FINGERPRINT_MAP.size() + + " FINGERPRINT_MAP entries, should be " + COUNT); + } + // check that all entries in the map are in the keystore for (String alias : FINGERPRINT_MAP.keySet()) { if (!ks.isCertificateEntry(alias)) { @@ -313,66 +329,66 @@ Enumeration aliases = ks.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); - System.out.println("\nVerifying " + alias); + System.out.println("Verifying " + alias); + + // Is cert trusted? if (!ks.isCertificateEntry(alias)) { atLeastOneFailed = true; - System.err.println("ERROR: " + alias - + " is not a trusted cert entry"); + System.err.println("ERROR: " + alias + " is not a trusted cert entry"); } + + // Does fingerprint match? X509Certificate cert = (X509Certificate) ks.getCertificate(alias); if (!checkFingerprint(alias, cert)) { atLeastOneFailed = true; System.err.println("ERROR: " + alias + " SHA-256 fingerprint is incorrect"); } - // Make sure cert can be self-verified + + // Can cert be self-verified? try { cert.verify(cert.getPublicKey()); } catch (Exception e) { atLeastOneFailed = true; - System.err.println("ERROR: cert cannot be verified:" - + e.getMessage()); + System.err.println("ERROR: cert cannot be verified:" + e.getMessage()); } - // Make sure cert is not expired or not yet valid + // Is cert expired? try { cert.checkValidity(); } catch (CertificateExpiredException cee) { if (!EXPIRY_EXC_ENTRIES.contains(alias)) { atLeastOneFailed = true; - System.err.println("ERROR: cert is expired"); + System.err.println("ERROR: cert is expired but not in EXPIRY_EXC_ENTRIES"); } } catch (CertificateNotYetValidException cne) { atLeastOneFailed = true; System.err.println("ERROR: cert is not yet valid"); } - // If cert is within 90 days of expiring, mark as failure so + // If cert is within 90 days of expiring, mark as warning so // that cert can be scheduled to be removed/renewed. Date notAfter = cert.getNotAfter(); if (notAfter.getTime() - System.currentTimeMillis() < NINETY_DAYS) { if (!EXPIRY_EXC_ENTRIES.contains(alias)) { - atLeastOneFailed = true; - System.err.println("ERROR: cert \"" + alias + "\" expiry \"" - + notAfter.toString() + "\" will expire within 90 days"); + System.err.println("WARNING: cert \"" + alias + "\" expiry \"" + + notAfter + "\" will expire within 90 days"); } } } if (atLeastOneFailed) { - throw new Exception("At least one cacert test failed"); + throw new RuntimeException("At least one cacert test failed"); } } private static boolean checkFingerprint(String alias, Certificate cert) - throws Exception { + throws CertificateEncodingException { String fingerprint = FINGERPRINT_MAP.get(alias); if (fingerprint == null) { // no entry for alias - return true; + return false; } - System.out.println("Checking fingerprint of " + alias); byte[] digest = md.digest(cert.getEncoded()); return fingerprint.equals(HEX.formatHex(digest)); } - } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/security/pkcs11/tls/keymatdata.txt openjdk-17-17.0.8+7/test/jdk/sun/security/pkcs11/tls/keymatdata.txt --- openjdk-17-17.0.7+7~us1/test/jdk/sun/security/pkcs11/tls/keymatdata.txt 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/security/pkcs11/tls/keymatdata.txt 2023-07-05 07:11:54.000000000 +0000 @@ -3646,3 +3646,37 @@ km-siv: 34:8a:e8:24:84:38:c4:e1 km-cmackey: e8:f0:b5:7b:a7:cc:2f:5e:43:ef:d3:dd:4e:8c:f9:6f:51:d7:84:df km-smackey: fc:0c:77:20:c2:28:d3:11:ba:57:13:d8:0b:2d:f1:30:89:c6:35:69 +km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc +km-major: 3 +km-minor: 3 +km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56 +km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97 +km-cipalg: AES +km-hashalg: SHA-256 +km-keylen: 16 +km-explen: 0 +km-ivlen: 4 +km-maclen: 0 +km-ccipkey: 60:7a:45:a9:6e:76:58:ea:d9:44:c5:25:f8:92:f1:26 +km-scipkey: 42:c0:ed:75:a2:51:21:7c:50:74:9d:78:9a:f7:35:2b +km-civ: a1:3c:3e:4a +km-siv: 85:ab:ee:70 +km-cmackey: (null) +km-smackey: (null) +km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc +km-major: 3 +km-minor: 3 +km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56 +km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97 +km-cipalg: AES +km-hashalg: SHA-384 +km-keylen: 32 +km-explen: 0 +km-ivlen: 4 +km-maclen: 0 +km-ccipkey: 3c:03:17:61:1e:88:4a:aa:01:4c:ac:6c:f8:bb:91:c3:0e:ec:57:c7:bf:07:ff:eb:49:22:f9:80:12:64:72:2a +km-scipkey: f8:00:8e:b2:dc:25:98:f1:97:00:55:28:60:a3:65:da:42:89:18:bb:40:94:53:d2:75:2a:29:e5:aa:94:1d:7a +km-civ: 24:02:76:6f +km-siv: 3b:6d:33:5a +km-cmackey: (null) +km-smackey: (null) diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/security/pkcs11/tls/TestKeyMaterial.java openjdk-17-17.0.8+7/test/jdk/sun/security/pkcs11/tls/TestKeyMaterial.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/security/pkcs11/tls/TestKeyMaterial.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/security/pkcs11/tls/TestKeyMaterial.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6316539 8136355 + * @bug 6316539 8136355 8294906 * @summary Known-answer-test for TlsKeyMaterial generator * @author Andreas Sterbenz * @library /test/lib .. @@ -77,6 +77,7 @@ byte[] clientRandom = null; byte[] serverRandom = null; String cipherAlgorithm = null; + String hashAlgorithm = null; // TLS1.2+ only int keyLength = 0; int expandedKeyLength = 0; int ivLength = 0; @@ -110,6 +111,8 @@ serverRandom = parse(data); } else if (line.startsWith("km-cipalg:")) { cipherAlgorithm = data; + } else if (line.startsWith("km-hashalg:")) { + hashAlgorithm = data; } else if (line.startsWith("km-keylen:")) { keyLength = Integer.parseInt(data); } else if (line.startsWith("km-explen:")) { @@ -135,14 +138,17 @@ n++; KeyGenerator kg = - KeyGenerator.getInstance("SunTlsKeyMaterial", provider); + KeyGenerator.getInstance(minor == 3 ? + "SunTls12KeyMaterial" : + "SunTlsKeyMaterial", provider); SecretKey masterKey = new SecretKeySpec(master, "TlsMasterSecret"); + // prfHashLength and prfBlockSize are ignored by PKCS11 provider TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(masterKey, major, minor, clientRandom, serverRandom, cipherAlgorithm, keyLength, expandedKeyLength, ivLength, macLength, - null, -1, -1); + hashAlgorithm, -1 /*ignored*/, -1 /*ignored*/); try { kg.init(spec); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java openjdk-17-17.0.8+7/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,244 @@ +/* + * 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 8296343 + * @summary CPVE thrown on missing content-length in OCSP response + * @modules java.base/sun.security.x509 + * java.base/sun.security.provider.certpath + * java.base/sun.security.util + * @library ../../../../../java/security/testlibrary + * @build CertificateBuilder SimpleOCSPServer + * @run main/othervm OCSPNoContentLength + */ + +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.PublicKey; +import java.security.cert.*; +import java.security.cert.X509Certificate; +import java.security.spec.ECGenParameterSpec; +import java.util.*; +import java.util.concurrent.TimeUnit; + + +import sun.security.testlibrary.SimpleOCSPServer; +import sun.security.testlibrary.CertificateBuilder; + +public class OCSPNoContentLength { + + static String passwd = "passphrase"; + static String ROOT_ALIAS = "root"; + static String EE_ALIAS = "endentity"; + + // Enable debugging for additional output + static final boolean debug = true; + + // PKI components we will need for this test + static X509Certificate rootCert; // The root CA certificate + static X509Certificate eeCert; // The end entity certificate + static KeyStore rootKeystore; // Root CA Keystore + static KeyStore eeKeystore; // End Entity Keystore + static KeyStore trustStore; // SSL Client trust store + static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder + static int rootOcspPort; // Port number for root OCSP + + public static void main(String[] args) throws Exception { + + try { + createPKI(); + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + CertPath path = cf.generateCertPath(List.of(eeCert)); + log("%s", path); + + TrustAnchor anchor = new TrustAnchor(rootCert, null); + log("%s", anchor); + Set anchors = Set.of(anchor); + + CertPathValidator validator = CertPathValidator.getInstance("PKIX"); + PKIXParameters params = new PKIXParameters(anchors); + PKIXRevocationChecker prc = + (PKIXRevocationChecker)validator.getRevocationChecker(); + params.addCertPathChecker(prc); + + validator.validate(path, params); + } finally { + rootOcsp.stop(); + } + } + + + /** + * Creates the PKI components necessary for this test, including + * Root CA, Intermediate CA and SSL server certificates, the keystores + * for each entity, a client trust store, and starts the OCSP responders. + */ + private static void createPKI() throws Exception { + CertificateBuilder cbld = new CertificateBuilder(); + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); + keyGen.initialize(new ECGenParameterSpec("secp256r1")); + KeyStore.Builder keyStoreBuilder = + KeyStore.Builder.newInstance("PKCS12", null, + new KeyStore.PasswordProtection(passwd.toCharArray())); + + // Generate Root and EE keys + KeyPair rootCaKP = keyGen.genKeyPair(); + log("Generated Root CA KeyPair"); + KeyPair eeKP = keyGen.genKeyPair(); + log("Generated End Entity KeyPair"); + + // Set up the Root CA Cert + cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany"); + cbld.setPublicKey(rootCaKP.getPublic()); + cbld.setSerialNumber(new BigInteger("1")); + // Make a 3 year validity starting from 60 days ago + long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60); + long end = start + TimeUnit.DAYS.toMillis(1085); + cbld.setValidity(new Date(start), new Date(end)); + addCommonExts(cbld, rootCaKP.getPublic(), rootCaKP.getPublic()); + addCommonCAExts(cbld); + // Make our Root CA Cert! + rootCert = cbld.build(null, rootCaKP.getPrivate(), + "SHA256withECDSA"); + log("Root CA Created:\n%s", certInfo(rootCert)); + + // Now build a keystore and add the keys and cert + rootKeystore = keyStoreBuilder.getKeyStore(); + Certificate[] rootChain = {rootCert}; + rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(), + passwd.toCharArray(), rootChain); + + // Now fire up the OCSP responder + rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null); + rootOcsp.enableLog(debug); + rootOcsp.setNextUpdateInterval(3600); + rootOcsp.setDisableContentLength(true); + rootOcsp.start(); + + // Wait 5 seconds for server ready + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); + } + + rootOcspPort = rootOcsp.getPort(); + String rootRespURI = "http://localhost:" + rootOcspPort; + log("Root OCSP Responder URI is %s", rootRespURI); + + // Now that we have the root keystore and OCSP responder we can + // create our end entity certificate + cbld.reset(); + cbld.setSubjectName("CN=SSLCertificate, O=SomeCompany"); + cbld.setPublicKey(eeKP.getPublic()); + cbld.setSerialNumber(new BigInteger("4096")); + // Make a 1 year validity starting from 7 days ago + start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7); + end = start + TimeUnit.DAYS.toMillis(365); + cbld.setValidity(new Date(start), new Date(end)); + + // Add extensions + addCommonExts(cbld, eeKP.getPublic(), rootCaKP.getPublic()); + boolean[] kuBits = {true, false, false, false, false, false, + false, false, false}; + cbld.addKeyUsageExt(kuBits); + List ekuOids = new ArrayList<>(); + ekuOids.add("1.3.6.1.5.5.7.3.1"); + ekuOids.add("1.3.6.1.5.5.7.3.2"); + cbld.addExtendedKeyUsageExt(ekuOids); + cbld.addSubjectAltNameDNSExt(Collections.singletonList("localhost")); + cbld.addAIAExt(Collections.singletonList(rootRespURI)); + // Make our End Entity Cert! + eeCert = cbld.build(rootCert, rootCaKP.getPrivate(), + "SHA256withECDSA"); + log("SSL Certificate Created:\n%s", certInfo(eeCert)); + + // Provide end entity cert revocation info to the Root CA + // OCSP responder. + Map revInfo = + new HashMap<>(); + revInfo.put(eeCert.getSerialNumber(), + new SimpleOCSPServer.CertStatusInfo( + SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD)); + rootOcsp.updateStatusDb(revInfo); + + // Now build a keystore and add the keys, chain and root cert as a TA + eeKeystore = keyStoreBuilder.getKeyStore(); + Certificate[] eeChain = {eeCert, rootCert}; + eeKeystore.setKeyEntry(EE_ALIAS, eeKP.getPrivate(), + passwd.toCharArray(), eeChain); + eeKeystore.setCertificateEntry(ROOT_ALIAS, rootCert); + + // And finally a Trust Store for the client + trustStore = keyStoreBuilder.getKeyStore(); + trustStore.setCertificateEntry(ROOT_ALIAS, rootCert); + } + + private static void addCommonExts(CertificateBuilder cbld, + PublicKey subjKey, PublicKey authKey) throws IOException { + cbld.addSubjectKeyIdExt(subjKey); + cbld.addAuthorityKeyIdExt(authKey); + } + + private static void addCommonCAExts(CertificateBuilder cbld) + throws IOException { + cbld.addBasicConstraintsExt(true, true, -1); + // Set key usage bits for digitalSignature, keyCertSign and cRLSign + boolean[] kuBitSettings = {true, false, false, false, false, true, + true, false, false}; + cbld.addKeyUsageExt(kuBitSettings); + } + + /** + * Helper routine that dumps only a few cert fields rather than + * the whole toString() output. + * + * @param cert an X509Certificate to be displayed + * + * @return the String output of the issuer, subject and + * serial number + */ + private static String certInfo(X509Certificate cert) { + StringBuilder sb = new StringBuilder(); + sb.append("Issuer: ").append(cert.getIssuerX500Principal()). + append("\n"); + sb.append("Subject: ").append(cert.getSubjectX500Principal()). + append("\n"); + sb.append("Serial: ").append(cert.getSerialNumber()).append("\n"); + return sb.toString(); + } + + /** + * Log a message on stdout + * + * @param format the format string for the log entry + * @param args zero or more arguments corresponding to the format string + */ + private static void log(String format, Object ... args) { + System.out.format(format + "\n", args); + } +} \ No newline at end of file diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java openjdk-17-17.0.8+7/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * 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,17 +23,24 @@ /* * @test - * @bug 8164879 + * @bug 8164879 8300285 * @library ../../ * @library /test/lib - * @summary Verify AES/GCM's limits set in the jdk.tls.keyLimits property + * @summary Verify AEAD TLS cipher suite limits set in the jdk.tls.keyLimits + * property * start a new handshake sequence to renegotiate the symmetric key with an * SSLSocket connection. This test verifies the handshake method was called * via debugging info. It does not verify the renegotiation was successful * as that is very hard. * - * @run main SSLEngineKeyLimit 0 server AES/GCM/NoPadding keyupdate 1050000 - * @run main SSLEngineKeyLimit 1 client AES/GCM/NoPadding keyupdate 2^22 + * @run main SSLEngineKeyLimit 0 server TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 1050000 + * @run main SSLEngineKeyLimit 1 client TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 2^22 + * @run main SSLEngineKeyLimit 0 server TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 1050000, ChaCha20-Poly1305 KeyUpdate 1050000 + * @run main SSLEngineKeyLimit 1 client TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 2^22, ChaCha20-Poly1305 KeyUpdate 2^22 */ /* @@ -86,7 +93,7 @@ } /** - * args should have two values: server|client, + * args should have two values: server|client, cipher suite, * Prepending 'p' is for internal use only. */ public static void main(String args[]) throws Exception { @@ -105,7 +112,7 @@ File f = new File("keyusage."+ System.nanoTime()); PrintWriter p = new PrintWriter(f); p.write("jdk.tls.keyLimits="); - for (int i = 2; i < args.length; i++) { + for (int i = 3; i < args.length; i++) { p.write(" "+ args[i]); } p.close(); @@ -120,10 +127,13 @@ System.getProperty("test.java.opts")); ProcessBuilder pb = ProcessTools.createTestJvm( - Utils.addTestJavaOpts("SSLEngineKeyLimit", "p", args[1])); + Utils.addTestJavaOpts("SSLEngineKeyLimit", "p", args[1], + args[2])); OutputAnalyzer output = ProcessTools.executeProcess(pb); try { + output.shouldContain(String.format( + "\"cipher suite\" : \"%s", args[2])); if (expectedFail) { output.shouldNotContain("KeyUpdate: write key updated"); output.shouldNotContain("KeyUpdate: read key updated"); @@ -171,9 +181,10 @@ cTos.clear(); sToc.clear(); - Thread ts = new Thread(serverwrite ? new Client() : new Server()); + Thread ts = new Thread(serverwrite ? new Client() : + new Server(args[2])); ts.start(); - (serverwrite ? new Server() : new Client()).run(); + (serverwrite ? new Server(args[2]) : new Client()).run(); ts.interrupt(); ts.join(); } @@ -417,11 +428,14 @@ } static class Server extends SSLEngineKeyLimit implements Runnable { - Server() throws Exception { + Server(String cipherSuite) throws Exception { super(); eng = initContext().createSSLEngine(); eng.setUseClientMode(false); eng.setNeedClientAuth(true); + if (cipherSuite != null && cipherSuite.length() > 0) { + eng.setEnabledCipherSuites(new String[] { cipherSuite }); + } } public void run() { diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java openjdk-17-17.0.8+7/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java 2023-07-05 07:11:54.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 @@ -23,14 +23,24 @@ /* * @test - * @bug 8164879 + * @bug 8164879 8300285 * @library ../../ * @library /test/lib * @modules java.base/sun.security.util - * @summary Verify AES/GCM's limits set in the jdk.tls.keyLimits property - * @run main SSLSocketKeyLimit 0 server AES/GCM/NoPadding keyupdate 1000000 - * @run main SSLSocketKeyLimit 0 client AES/GCM/NoPadding keyupdate 1000000 - * @run main SSLSocketKeyLimit 1 client AES/GCM/NoPadding keyupdate 2^22 + * @summary Verify AEAD TLS cipher suite limits set in the jdk.tls.keyLimits + * property + * @run main SSLSocketKeyLimit 0 server TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 1000000 + * @run main SSLSocketKeyLimit 0 client TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 1000000 + * @run main SSLSocketKeyLimit 1 client TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 2^22 + * @run main SSLSocketKeyLimit 0 server TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 1000000, ChaCha20-Poly1305 KeyUpdate 1000000 + * @run main SSLSocketKeyLimit 0 client TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 1000000, ChaCha20-Poly1305 KeyUpdate 1000000 + * @run main SSLSocketKeyLimit 1 client TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 2^22, ChaCha20-Poly1305 KeyUpdate 2^22 */ /** @@ -96,7 +106,7 @@ } /** - * args should have two values: server|client, + * args should have three values: server|client, cipher suite, * Prepending 'p' is for internal use only. */ public static void main(String args[]) throws Exception { @@ -110,7 +120,7 @@ File f = new File("keyusage."+ System.nanoTime()); PrintWriter p = new PrintWriter(f); p.write("jdk.tls.keyLimits="); - for (int i = 2; i < args.length; i++) { + for (int i = 3; i < args.length; i++) { p.write(" "+ args[i]); } p.close(); @@ -125,10 +135,13 @@ System.getProperty("test.java.opts")); ProcessBuilder pb = ProcessTools.createTestJvm( - Utils.addTestJavaOpts("SSLSocketKeyLimit", "p", args[1])); + Utils.addTestJavaOpts("SSLSocketKeyLimit", "p", args[1], + args[2])); OutputAnalyzer output = ProcessTools.executeProcess(pb); try { + output.shouldContain(String.format( + "\"cipher suite\" : \"%s", args[2])); if (expectedFail) { output.shouldNotContain("KeyUpdate: write key updated"); output.shouldNotContain("KeyUpdate: read key updated"); @@ -150,7 +163,7 @@ return; } - if (args.length > 0 && args[0].compareToIgnoreCase("client") == 0) { + if (args.length > 0 && args[1].compareToIgnoreCase("client") == 0) { serverwrite = false; } @@ -162,7 +175,7 @@ System.setProperty("javax.net.ssl.keyStorePassword", passwd); Arrays.fill(data, (byte)0x0A); - Thread ts = new Thread(new Server()); + Thread ts = new Thread(new Server(args[2])); ts.start(); while (!serverReady) { @@ -200,7 +213,8 @@ int len; byte i = 0; try { - System.out.println("Server: connected " + s.getSession().getCipherSuite()); + System.out.println("Server: connected " + + s.getSession().getCipherSuite()); in = s.getInputStream(); out = s.getOutputStream(); while (true) { @@ -212,7 +226,8 @@ if (b == 0x0A || b == 0x0D) { continue; } - System.out.println("\nData invalid: " + HexPrinter.minimal().toString(buf)); + System.out.println("\nData invalid: " + + HexPrinter.minimal().toString(buf)); break; } @@ -237,11 +252,14 @@ static class Server extends SSLSocketKeyLimit implements Runnable { private SSLServerSocketFactory ssf; private SSLServerSocket ss; - Server() { + Server(String cipherSuite) { super(); try { ssf = initContext().getServerSocketFactory(); ss = (SSLServerSocket) ssf.createServerSocket(serverPort); + if (cipherSuite != null && cipherSuite.length() > 0) { + ss.setEnabledCipherSuites(new String[] { cipherSuite }); + } serverPort = ss.getLocalPort(); } catch (Exception e) { System.out.println("server: " + e.getMessage()); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java openjdk-17-17.0.8+7/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -304,11 +304,9 @@ rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -357,11 +355,9 @@ intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/text/resources/LocaleData.cldr openjdk-17-17.0.8+7/test/jdk/sun/text/resources/LocaleData.cldr --- openjdk-17-17.0.7+7~us1/test/jdk/sun/text/resources/LocaleData.cldr 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/text/resources/LocaleData.cldr 2023-07-05 07:11:54.000000000 +0000 @@ -8395,6 +8395,14 @@ FormatData/fr/latn.NumberElements/11= FormatData/fr_CH/latn.NumberElements/11=. +# bug # 8295564 +FormatData/nb/latn.NumberElements/0=, +FormatData/nb/latn.NumberElements/1=\u00a0 +FormatData/no/latn.NumberElements/0=, +FormatData/no/latn.NumberElements/1=\u00a0 +FormatData/nn/latn.NumberElements/0=, +FormatData/nn/latn.NumberElements/1=\u00a0 + # tzdata2022f TimeZoneNames/en/America\/Ojinaga/1=Central Standard Time TimeZoneNames/en/America\/Chihuahua/1=Central Standard Time diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/text/resources/LocaleDataTest.java openjdk-17-17.0.8+7/test/jdk/sun/text/resources/LocaleDataTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/text/resources/LocaleDataTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/text/resources/LocaleDataTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -40,7 +40,7 @@ * 8145136 8145952 8164784 8037111 8081643 7037368 8178872 8185841 8190918 * 8187946 8195478 8181157 8179071 8193552 8202026 8204269 8202537 8208746 * 8209775 8221432 8227127 8230284 8231273 8233579 8234288 8250665 8255086 - * 8251317 8274658 8283277 8296715 + * 8251317 8274658 8283277 8296715 8295564 * @summary Verify locale data * @modules java.base/sun.util.resources * @modules jdk.localedata diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/tools/jcmd/TestJcmdSanity.java openjdk-17-17.0.8+7/test/jdk/sun/tools/jcmd/TestJcmdSanity.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/tools/jcmd/TestJcmdSanity.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/tools/jcmd/TestJcmdSanity.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -32,6 +32,7 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Platform; import jdk.test.lib.Utils; /* @@ -57,6 +58,7 @@ testJcmdPid_f(); testJcmdPidPerfCounterPrint(); testJcmdPidBigScript(); + testJcmdPidVMinfo(); } /** @@ -164,4 +166,21 @@ "The ouput should contain all content of " + path.toAbsolutePath()); } + /** + * Sanity check for VM.info + */ + private static void testJcmdPidVMinfo() throws Exception { + OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS, new String[] {"VM.info"}); + output.shouldHaveExitValue(0); + output.shouldContain(Long.toString(ProcessTools.getProcessId()) + ":"); + + // Should find the signal handler summary (except on Windows): + if (!Platform.isWindows()) { + output.shouldContain("Signal Handlers:"); + // Should not find any of the possible signal handler modification warnings: + output.shouldNotContain(" handler modified!"); // e.g. Warning: SIGILL handler modified! + output.shouldNotContain("*** Handler was modified!"); + output.shouldNotContain("*** Expected: "); // e.g. *** Expected: javaSignalHandler in ... + } + } } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/util/resources/cldr/NorwegianFallbackTest.java openjdk-17-17.0.8+7/test/jdk/sun/util/resources/cldr/NorwegianFallbackTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/util/resources/cldr/NorwegianFallbackTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/util/resources/cldr/NorwegianFallbackTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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 8282227 + * @modules jdk.localedata + * @summary Checks Norwegian locale fallback retrieves resource bundles correctly. + * @run main/othervm -Djava.locale.providers=COMPAT NorwegianFallbackTest nb + * @run main/othervm -Djava.locale.providers=COMPAT NorwegianFallbackTest nn + * @run main/othervm -Djava.locale.providers=COMPAT NorwegianFallbackTest no + * @run main/othervm -Djava.locale.providers=CLDR NorwegianFallbackTest nb + * @run main/othervm -Djava.locale.providers=CLDR NorwegianFallbackTest nn + * @run main/othervm -Djava.locale.providers=CLDR NorwegianFallbackTest no + */ + +import java.text.DateFormatSymbols; +import java.util.List; +import java.util.Locale; +import static java.util.Calendar.SUNDAY; + +public class NorwegianFallbackTest { + + private final static String SUN_ROOT = DateFormatSymbols.getInstance(Locale.ROOT).getShortWeekdays()[SUNDAY]; + private final static List TEST_LOCS = List.of( + Locale.forLanguageTag("nb"), + Locale.forLanguageTag("nn"), + Locale.forLanguageTag("no") + ); + + public static void main(String... args) { + // Dummy instance + var startup_loc = Locale.forLanguageTag(args[0]); + DateFormatSymbols.getInstance(startup_loc); + + TEST_LOCS.stream() + .peek(l -> System.out.print("Testing locale: " + l + ", (startup locale: " + startup_loc + ")... ")) + .map(l -> DateFormatSymbols.getInstance(l).getShortWeekdays()[SUNDAY]) + .forEach(sun -> { + if (sun.equals(SUN_ROOT)) { + throw new RuntimeException("Norwegian fallback failed"); + } else { + System.out.println("Got " + "\"" + sun + "\" for Sunday short name"); + } + }); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java openjdk-17-17.0.8+7/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 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 8275721 + * @modules jdk.localedata + * @summary Checks Chinese time zone names for `UTC` using CLDR are consistent + * @run testng/othervm -Djava.locale.providers=CLDR,COMPAT ChineseTimeZoneNameTest + * @run testng/othervm -Djava.locale.providers=CLDR ChineseTimeZoneNameTest + */ + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + +import static org.testng.Assert.assertEquals; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +@Test +public class ChineseTimeZoneNameTest { + + private static final Locale SIMPLIFIED_CHINESE = Locale.forLanguageTag("zh-Hans"); + private static final Locale TRADITIONAL_CHINESE = Locale.forLanguageTag("zh-Hant"); + private static final ZonedDateTime EPOCH_UTC = + ZonedDateTime.ofInstant(Instant.ofEpochSecond (0), ZoneId.of ("UTC")); + + @DataProvider(name="locales") + Object[][] data() { + return new Object[][] { + {Locale.CHINESE, SIMPLIFIED_CHINESE}, + {Locale.SIMPLIFIED_CHINESE, SIMPLIFIED_CHINESE}, + {Locale.forLanguageTag("zh-SG"), SIMPLIFIED_CHINESE}, + {Locale.forLanguageTag("zh-Hans-TW"), SIMPLIFIED_CHINESE}, + {Locale.forLanguageTag("zh-HK"), TRADITIONAL_CHINESE}, + {Locale.forLanguageTag("zh-MO"), TRADITIONAL_CHINESE}, + {Locale.TRADITIONAL_CHINESE, TRADITIONAL_CHINESE}, + {Locale.forLanguageTag("zh-Hant-CN"), TRADITIONAL_CHINESE}, + }; + } + + @Test(dataProvider="locales") + public void test_ChineseTimeZoneNames(Locale testLoc, Locale resourceLoc) { + assertEquals(DateTimeFormatter.ofPattern("z", testLoc).format(EPOCH_UTC), + DateTimeFormatter.ofPattern("z", resourceLoc).format(EPOCH_UTC)); + assertEquals(DateTimeFormatter.ofPattern("zzzz", testLoc).format(EPOCH_UTC), + DateTimeFormatter.ofPattern("zzzz", resourceLoc).format(EPOCH_UTC)); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java openjdk-17-17.0.8+7/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java --- openjdk-17-17.0.7+7~us1/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java 2023-07-05 07:11:54.000000000 +0000 @@ -178,10 +178,6 @@ return (OS.contains("mac")); } - public static boolean isArmMac() { - return (isOSX() && "aarch64".equals(System.getProperty("os.arch"))); - } - public static boolean isLinux() { return ((OS.contains("nix") || OS.contains("nux"))); } diff -Nru openjdk-17-17.0.7+7~us1/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java openjdk-17-17.0.8+7/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java --- openjdk-17-17.0.7+7~us1/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java 2023-07-05 07:11:54.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 @@ -26,6 +26,7 @@ import java.util.List; import java.util.Optional; import java.util.function.BiFunction; +import java.util.stream.Stream; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Executor; @@ -83,8 +84,10 @@ final String expectedEnvVarValue = Optional.ofNullable(System.getenv( envVarName)).orElse("") + File.pathSeparator + appDir; - TKit.assertEquals(expectedEnvVarValue, actualEnvVarValue, String.format( - "Check value of %s env variable", envVarName)); + TKit.assertTextStream(expectedEnvVarValue) + .predicate(TKit.isLinux() ? String::endsWith : String::equals) + .label(String.format("value of %s env variable", envVarName)) + .apply(Stream.of(actualEnvVarValue)); final String javaLibraryPath = getValue.apply(2, "java.library.path"); TKit.assertTrue( diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java openjdk-17-17.0.8+7/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java --- openjdk-17-17.0.7+7~us1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016, 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. + */ + +package pkg; + +/** + *This class has various functions, + * see FTP Site, + * file service for further information + *various functions + *
      + *
    • function1
    • + *
    • function2
    • + *
    • function3
    • + *
    + *special methods + *
      + *
    • method1
    • + *
    • method2
    • + *
    • method3
    • + *
    + */ +public class J1 { + /** + *fields. + */ + protected Object field1; + + /** + *Creates an instance which has various functions. + */ + public J1(){ + } + + /** + *This is aspecial method. + *@param p1 arg1 + */ + public void method1(int p1){ + } + + /** + *See FTP Site for more information. + *@param p1 arg1 + */ + public void method2(int p1){ + } + + /** + *See file service for more information. + *@param p1 arg1 + */ + public void method3(int p1){ + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java openjdk-17-17.0.8+7/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java --- openjdk-17-17.0.7+7~us1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4638015 + * @bug 4638015 8248001 * @summary Determine if Hrefs are processed properly when they * appear in doc comments. * @library ../../lib diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/jdk/javadoc/tool/IgnoreSourceErrors.java openjdk-17-17.0.8+7/test/langtools/jdk/javadoc/tool/IgnoreSourceErrors.java --- openjdk-17-17.0.7+7~us1/test/langtools/jdk/javadoc/tool/IgnoreSourceErrors.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/jdk/javadoc/tool/IgnoreSourceErrors.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8175219 + * @bug 8175219 8268582 * @summary test --ignore-errors works correctly * @modules * jdk.javadoc/jdk.javadoc.internal.api @@ -73,6 +73,12 @@ if (!out.contains("modifier static not allowed here")) { throw new Exception("expected string not found \'modifier static not allowed here\'"); } + if (!out.contains("package invalid.example does not exist")) { + throw new Exception("expected string not found \'package invalid.example does not exist\'"); + } + if (!out.contains("cannot find symbol")) { + throw new Exception("expected string not found \'cannot find symbol\'"); + } } @Test @@ -84,12 +90,19 @@ if (!out.contains("modifier static not allowed here")) { throw new Exception("expected string not found \'modifier static not allowed here\'"); } + if (!out.contains("package invalid.example does not exist")) { + throw new Exception("expected string not found \'package invalid.example does not exist\'"); + } + if (!out.contains("cannot find symbol")) { + throw new Exception("expected string not found \'cannot find symbol\'"); + } } void emitSample(Path file) throws IOException { String[] contents = { "/** A java file with errors */", - "public static class Foo {}" + "import invalid.example.OtherClass;", + "public static class Foo extends OtherClass {}" }; Files.write(file, Arrays.asList(contents), StandardOpenOption.CREATE); } diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/jdk/jshell/ClassesTest.java openjdk-17-17.0.8+7/test/langtools/jdk/jshell/ClassesTest.java --- openjdk-17-17.0.7+7~us1/test/langtools/jdk/jshell/ClassesTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/jdk/jshell/ClassesTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8145239 8129559 8080354 8189248 8010319 8246353 8247456 + * @bug 8145239 8129559 8080354 8189248 8010319 8246353 8247456 8292755 * @summary Tests for EvaluationState.classes * @build KullaTesting TestingInputStream ExpectedDiagnostic * @run testng ClassesTest @@ -342,4 +342,18 @@ assertEval("new A()"); } + public void testDefaultMethodInInterface() { + assertEvalFail(""" + interface C { + public void run() { + try { + throw IllegalStateException(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + } + """); + } + } diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java openjdk-17-17.0.8+7/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java --- openjdk-17-17.0.7+7~us1/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -27,6 +27,7 @@ * @summary Control Char check for pty * @modules jdk.internal.le/jdk.internal.org.jline.terminal * jdk.internal.le/jdk.internal.org.jline.terminal.impl + * jdk.internal.le/jdk.internal.org.jline.terminal.spi * @requires (os.family == "linux") | (os.family == "aix") */ @@ -35,10 +36,11 @@ import jdk.internal.org.jline.terminal.Attributes.ControlChar; import jdk.internal.org.jline.terminal.Attributes.LocalFlag; import jdk.internal.org.jline.terminal.impl.ExecPty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; public class ExecPtyGetFlagsToSetTest extends ExecPty { - public ExecPtyGetFlagsToSetTest(String name, boolean system) { - super(name, system); + public ExecPtyGetFlagsToSetTest(String name, TerminalProvider.Stream stream) { + super(name, stream); } @Override @@ -48,7 +50,7 @@ public static void main(String[] args) { ExecPtyGetFlagsToSetTest testPty = - new ExecPtyGetFlagsToSetTest("stty", true); + new ExecPtyGetFlagsToSetTest("stty", TerminalProvider.Stream.Output); Attributes attr = new Attributes(); Attributes current = new Attributes(); diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java openjdk-17-17.0.8+7/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java --- openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java 2023-07-05 07:11:54.000000000 +0000 @@ -23,7 +23,7 @@ // key: compiler.note.verbose.l2m.deduplicate -// options: --debug=dumpLambdaToMethodDeduplication +// options: -g:none --debug=dumpLambdaToMethodDeduplication import java.util.function.Function; diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.java openjdk-17-17.0.8+7/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.java --- openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, Google 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 8275233 + * @summary Incorrect line number reported in exception stack trace thrown from a lambda expression + * @compile/ref=DeduplicationDebugInfo.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:none DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:lines DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:vars DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:lines,vars DeduplicationDebugInfo.java + */ + +import java.util.function.Function; + +class DeduplicationDebugInfoTest { + void f() { + Function f = x -> x.hashCode(); + Function g = x -> x.hashCode(); + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.out openjdk-17-17.0.8+7/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.out --- openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.out 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.out 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1 @@ +DeduplicationDebugInfo.java:39:39: compiler.note.verbose.l2m.deduplicate: lambda$f$0(java.lang.Object) diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java openjdk-17-17.0.8+7/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java --- openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -93,6 +93,7 @@ Arrays.asList( "-d", ".", + "-g:none", "-XDdebug.dumpLambdaToMethodDeduplication", "-XDdebug.dumpLambdaToMethodStats"), null, diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/parser/JavacParserTest.java openjdk-17-17.0.8+7/test/langtools/tools/javac/parser/JavacParserTest.java --- openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/parser/JavacParserTest.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/tools/javac/parser/JavacParserTest.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 + * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 8304671 * @summary tests error and diagnostics positions * @author Jan Lahoda * @modules jdk.compiler/com.sun.tools.javac.api @@ -1795,6 +1795,171 @@ assertEquals("correct parameter type span", code.substring(typeStart, typeEnd), "int[]..."); } + @Test //JDK-8304671 + void testEnumConstantUnderscore() throws IOException { + record TestCase(String code, String release, String ast, String errors) {} + TestCase[] testCases = new TestCase[] { + new TestCase(""" + package t; + enum Test { + _ + } + """, + "8", + """ + package t; + \n\ + enum Test { + /*public static final*/ _ /* = new Test() */ /*enum*/ ; + } """, + """ + Test.java:3:5: compiler.warn.underscore.as.identifier + """), + new TestCase(""" + package t; + enum Test { + _ + } + """, + System.getProperty("java.specification.version"), + """ + package t; + \n\ + enum Test { + /*public static final*/ _ /* = new Test() */ /*enum*/ ; + } """, + """ + Test.java:3:5: compiler.err.underscore.as.identifier + """), + new TestCase(""" + package t; + enum Test { + _; + } + """, + "8", + """ + package t; + \n\ + enum Test { + /*public static final*/ _ /* = new Test() */ /*enum*/ ; + } """, + """ + Test.java:3:5: compiler.warn.underscore.as.identifier + """), + new TestCase(""" + package t; + enum Test { + _; + } + """, + System.getProperty("java.specification.version"), + """ + package t; + \n\ + enum Test { + /*public static final*/ _ /* = new Test() */ /*enum*/ ; + } """, + """ + Test.java:3:5: compiler.err.underscore.as.identifier + """), + new TestCase(""" + package t; + enum Test { + A; + void t() {} + _; + } + """, + "8", + """ + package t; + \n\ + enum Test { + /*public static final*/ A /* = new Test() */ /*enum*/ , + /*public static final*/ _ /* = new Test() */ /*enum*/ ; + \n\ + void t() { + } + } """, + """ + Test.java:5:5: compiler.err.enum.constant.not.expected + Test.java:5:5: compiler.warn.underscore.as.identifier + """), + new TestCase(""" + package t; + enum Test { + A; + void t() {} + _; + } + """, + System.getProperty("java.specification.version"), + """ + package t; + \n\ + enum Test { + /*public static final*/ A /* = new Test() */ /*enum*/ , + /*public static final*/ _ /* = new Test() */ /*enum*/ ; + \n\ + void t() { + } + } """, + """ + Test.java:5:5: compiler.err.enum.constant.not.expected + """), + new TestCase(""" + package t; + enum Test { + _ {}, + A; + } + """, + "8", + """ + package t; + \n\ + enum Test { + /*public static final*/ _ /* = new Test() */ /*enum*/ { + }, + /*public static final*/ A /* = new Test() */ /*enum*/ ; + } """, + """ + Test.java:3:5: compiler.warn.underscore.as.identifier + """), + new TestCase(""" + package t; + enum Test { + _ {}, + A; + } + """, + System.getProperty("java.specification.version"), + """ + package t; + \n\ + enum Test { + /*public static final*/ _ /* = new Test() */ /*enum*/ { + }, + /*public static final*/ A /* = new Test() */ /*enum*/ ; + } """, + """ + Test.java:3:5: compiler.err.underscore.as.identifier + """), + }; + for (TestCase testCase : testCases) { + StringWriter out = new StringWriter(); + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(out, fm, null, + List.of("-XDrawDiagnostics", "--release", testCase.release), + null, Arrays.asList(new MyFileObject(testCase.code))); + String ast = ct.parse().iterator().next().toString().replaceAll("\\R", "\n"); + assertEquals("Unexpected AST, got:\n" + ast, testCase.ast, ast); + assertEquals("Unexpected errors, got:\n" + out.toString(), + out.toString().replaceAll("\\R", "\n"), + testCase.errors); + } + } + void run(String[] args) throws Exception { int passed = 0, failed = 0; final Pattern p = (args != null && args.length > 0) diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/patterns/BindingsInitializer.java openjdk-17-17.0.8+7/test/langtools/tools/javac/patterns/BindingsInitializer.java --- openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/patterns/BindingsInitializer.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/tools/javac/patterns/BindingsInitializer.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 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 8278834 + * @summary Verify pattern matching nested inside initializers of classes nested in methods + * works correctly. + * @library /tools/lib /tools/javac/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.file + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox toolbox.JavacTask + * @build combo.ComboTestHelper + * @compile BindingsInitializer.java + * @run main BindingsInitializer + */ + +import combo.ComboInstance; +import combo.ComboParameter; +import combo.ComboTask; +import combo.ComboTestHelper; +import java.nio.file.Path; +import java.nio.file.Paths; +import toolbox.ToolBox; + +public class BindingsInitializer extends ComboInstance { + protected ToolBox tb; + + BindingsInitializer() { + super(); + tb = new ToolBox(); + } + + public static void main(String... args) throws Exception { + new ComboTestHelper() + .withDimension("OUTER", (x, outer) -> x.outer = outer, Outer.values()) + .withDimension("MIDDLE", (x, middle) -> x.middle = middle, Middle.values()) + .withDimension("INNER", (x, inner) -> x.inner = inner, Inner.values()) + .withDimension("TEST", (x, test) -> x.test = test, Test.values()) + .run(BindingsInitializer::new); + } + + private Outer outer; + private Middle middle; + private Inner inner; + private Test test; + + private static final String MAIN_TEMPLATE = + """ + public class Test { + private static Object obj = ""; + #{OUTER} + } + """; + + @Override + protected void doWork() throws Throwable { + Path base = Paths.get("."); + + ComboTask task = newCompilationTask() + .withSourceFromTemplate(MAIN_TEMPLATE, pname -> switch (pname) { + case "OUTER" -> outer; + case "MIDDLE" -> middle; + case "INNER" -> inner; + case "TESST" -> test; + default -> throw new UnsupportedOperationException(pname); + }); + + task.generate(result -> { + if (result.hasErrors()) { + throw new AssertionError("Unexpected result: " + result.compilationInfo()); + } + }); + } + + public enum Outer implements ComboParameter { + NONE("#{MIDDLE}"), + STATIC_CLASS("static class Nested { #{MIDDLE} }"), + CLASS("class Inner { #{MIDDLE} }"); + private final String code; + + private Outer(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } + + public enum Middle implements ComboParameter { + STATIC_INIT("static { #{INNER} }"), + INIT("{ #{INNER} }"), + METHOD("void test() { #{INNER} }"); + private final String code; + + private Middle(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } + + public enum Inner implements ComboParameter { + DIRECT("#{TEST}"), + CLASS_STATIC_INIT("class C { static { #{TEST} } }"), + CLASS_INIT("class C { { #{TEST} } }"), + CLASS_METHOD("class C { void t() { #{TEST} } }"), + ANNONYMOUS_CLASS_STATIC_INIT("new Object() { static { #{TEST} } };"), + ANNONYMOUS_CLASS_INIT("new Object() { { #{TEST} } };"), + ANNONYMOUS_CLASS_METHOD("new Object() { void t() { #{TEST} } };"); + private final String code; + + private Inner(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } + + public enum Test implements ComboParameter { + TEST("if (obj instanceof String str) System.err.println(str);"); + private final String code; + + private Test(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } +} diff -Nru openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/recovery/MethodModifiers.java openjdk-17-17.0.8+7/test/langtools/tools/javac/recovery/MethodModifiers.java --- openjdk-17-17.0.7+7~us1/test/langtools/tools/javac/recovery/MethodModifiers.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/langtools/tools/javac/recovery/MethodModifiers.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,162 @@ +/* + * Copyright (c) 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 8292755 + * @summary Verify error recovery related to method modifiers. + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.jdeps/com.sun.tools.classfile + * @build toolbox.ToolBox toolbox.JavacTask + * @run main MethodModifiers + */ + +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; + +import toolbox.JavacTask; +import toolbox.Task.Expect; +import toolbox.Task.OutputKind; +import toolbox.TestRunner; +import toolbox.ToolBox; + +public class MethodModifiers extends TestRunner { + + ToolBox tb; + + public MethodModifiers() { + super(System.err); + tb = new ToolBox(); + } + + public static void main(String[] args) throws Exception { + MethodModifiers t = new MethodModifiers(); + t.runTests(); + } + + @Test + public void testNonDefaultMethodInterface() throws Exception { + String code = """ + interface Test { + void test() { + try { + unresolvable(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + } + """; + Path curPath = Path.of("."); + List actual = new JavacTask(tb) + .options("-XDrawDiagnostics", + "-XDshould-stop.at=FLOW", + "-XDdev") + .sources(code) + .outdir(curPath) + .run(Expect.FAIL) + .getOutputLines(OutputKind.DIRECT); + + List expected = List.of( + "Test.java:2:17: compiler.err.intf.meth.cant.have.body", + "Test.java:4:13: compiler.err.cant.resolve.location.args: kindname.method, unresolvable, , , (compiler.misc.location: kindname.interface, Test, null)", + "2 errors" + ); + + if (!Objects.equals(actual, expected)) { + error("Expected: " + expected + ", but got: " + actual); + } + } + + @Test + public void testAbstractMethodWithBody() throws Exception { + String code = """ + abstract class Test { + abstract void test() { + try { + unresolvable(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + } + """; + Path curPath = Path.of("."); + List actual = new JavacTask(tb) + .options("-XDrawDiagnostics", + "-XDshould-stop.at=FLOW", + "-XDdev") + .sources(code) + .outdir(curPath) + .run(Expect.FAIL) + .getOutputLines(OutputKind.DIRECT); + + List expected = List.of( + "Test.java:2:19: compiler.err.abstract.meth.cant.have.body", + "Test.java:4:13: compiler.err.cant.resolve.location.args: kindname.method, unresolvable, , , (compiler.misc.location: kindname.class, Test, null)", + "2 errors" + ); + + if (!Objects.equals(actual, expected)) { + error("Expected: " + expected + ", but got: " + actual); + } + } + + @Test + public void testNativeMethodWithBody() throws Exception { + String code = """ + class Test { + native void test() { + try { + unresolvable(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + } + """; + Path curPath = Path.of("."); + List actual = new JavacTask(tb) + .options("-XDrawDiagnostics", + "-XDshould-stop.at=FLOW", + "-XDdev") + .sources(code) + .outdir(curPath) + .run(Expect.FAIL) + .getOutputLines(OutputKind.DIRECT); + + List expected = List.of( + "Test.java:2:17: compiler.err.native.meth.cant.have.body", + "Test.java:4:13: compiler.err.cant.resolve.location.args: kindname.method, unresolvable, , , (compiler.misc.location: kindname.class, Test, null)", + "2 errors" + ); + + if (!Objects.equals(actual, expected)) { + error("Expected: " + expected + ", but got: " + actual); + } + } + +} diff -Nru openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV1.java openjdk-17-17.0.8+7/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV1.java --- openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV1.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV1.java 2023-07-05 07:11:54.000000000 +0000 @@ -247,13 +247,6 @@ fail(Controller.MEMORY, "memory.kmem.failcnt", oldVal, newVal); } - oldVal = metrics.getKernelMemoryLimit(); - newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.limit_in_bytes"); - newVal = newVal > unlimited_minimum ? CgroupSubsystem.LONG_RETVAL_UNLIMITED : newVal; - if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { - fail(Controller.MEMORY, "memory.kmem.limit_in_bytes", oldVal, newVal); - } - oldVal = metrics.getKernelMemoryMaxUsage(); newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.max_usage_in_bytes"); if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { @@ -273,13 +266,6 @@ fail(Controller.MEMORY, "memory.kmem.tcp.failcnt", oldVal, newVal); } - oldVal = metrics.getTcpMemoryLimit(); - newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.limit_in_bytes"); - newVal = newVal > unlimited_minimum ? CgroupSubsystem.LONG_RETVAL_UNLIMITED: newVal; - if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { - fail(Controller.MEMORY, "memory.kmem.tcp.limit_in_bytes", oldVal, newVal); - } - oldVal = metrics.getTcpMemoryMaxUsage(); newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.max_usage_in_bytes"); if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { diff -Nru openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java openjdk-17-17.0.8+7/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java --- openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java 2023-07-05 07:11:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Red Hat Inc. + * Copyright (c) 2020, 2022, 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 @@ -52,14 +52,22 @@ } } - public void testAll(Metrics m) throws Exception { + private void testAll(Metrics m, boolean inContainer) throws Exception { CgroupMetricsTester tester = createInstance(m); tester.testCpuAccounting(); tester.testCpuConsumption(); tester.testCpuSchedulingMetrics(); tester.testCpuSets(); - tester.testMemorySubsystem(); - tester.testMemoryUsage(); + if (!inContainer) { + // If not running in a container, these test cases query the memory usage. + // of all processes in the entire system (or those belonging to the current + // Linux user). They cannot produce predictable results due to interference + // from unrelated processes. + System.out.println("testMemorySubsystem and testMemoryUsage skipped"); + } else { + tester.testMemorySubsystem(); + tester.testMemoryUsage(); + } tester.testMisc(); } @@ -71,8 +79,14 @@ return; } + boolean inContainer = false; + if (args.length > 0 && "-incontainer".equals(args[0])) { + inContainer = true; + } + System.out.println("inContainer = " + inContainer); + MetricsTester metricsTester = new MetricsTester(); - metricsTester.testAll(m); + metricsTester.testAll(m, inContainer); System.out.println("TEST PASSED!!!"); } } diff -Nru openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/jfr/EventNames.java openjdk-17-17.0.8+7/test/lib/jdk/test/lib/jfr/EventNames.java --- openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/jfr/EventNames.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/lib/jdk/test/lib/jfr/EventNames.java 2023-07-05 07:11:54.000000000 +0000 @@ -201,6 +201,7 @@ public static final String X509Validation = PREFIX + "X509Validation"; public static final String InitialSecurityProperty = PREFIX + "InitialSecurityProperty"; public static final String SecurityProperty = PREFIX + "SecurityPropertyModification"; + public final static String SecurityProviderService = PREFIX + "SecurityProviderService"; public static final String DirectBufferStatistics = PREFIX + "DirectBufferStatistics"; public static final String Deserialization = PREFIX + "Deserialization"; diff -Nru openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/Platform.java openjdk-17-17.0.8+7/test/lib/jdk/test/lib/Platform.java --- openjdk-17-17.0.7+7~us1/test/lib/jdk/test/lib/Platform.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/lib/jdk/test/lib/Platform.java 2023-07-05 07:11:54.000000000 +0000 @@ -23,8 +23,10 @@ package jdk.test.lib; +import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -187,6 +189,19 @@ return vmVersion; } + public static boolean isMusl() { + try { + ProcessBuilder pb = new ProcessBuilder("ldd", "--version"); + pb.redirectErrorStream(true); + Process p = pb.start(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String l = b.readLine(); + if (l != null && l.contains("musl")) { return true; } + } catch(Exception e) { + } + return false; + } + public static boolean isAArch64() { return isArch("aarch64"); } diff -Nru openjdk-17-17.0.7+7~us1/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java openjdk-17-17.0.8+7/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java --- openjdk-17-17.0.7+7~us1/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java 2023-07-05 07:11:54.000000000 +0000 @@ -50,7 +50,7 @@ OS("isAix", "isLinux", "isOSX", "isWindows"), VM_TYPE("isClient", "isServer", "isMinimal", "isZero", "isEmbedded"), MODE("isInt", "isMixed", "isComp"), - IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild", + IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild", "isMusl", "isSlowDebugBuild", "hasSA", "isRoot", "isTieredSupported", "areCustomLoadersSupportedForCDS", "isDefaultCDSArchiveSupported", "isSignedOSX"); diff -Nru openjdk-17-17.0.7+7~us1/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java openjdk-17-17.0.8+7/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java --- openjdk-17-17.0.7+7~us1/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java 2023-04-12 20:11:58.000000000 +0000 +++ openjdk-17-17.0.8+7/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java 2023-07-05 07:11:54.000000000 +0000 @@ -61,7 +61,7 @@ private CharsetEncoder encoder; private CharsetDecoder decoder; - @Param({"UTF-8", "BIG5", "ISO-8859-15", "ASCII", "UTF-16"}) + @Param({"UTF-8", "BIG5", "ISO-8859-15", "ISO-8859-1", "ASCII", "UTF-16"}) private String type; @Param("16384") diff -Nru openjdk-17-17.0.7+7~us1/test/micro/org/openjdk/bench/java/text/ZoneStrings.java openjdk-17-17.0.8+7/test/micro/org/openjdk/bench/java/text/ZoneStrings.java --- openjdk-17-17.0.7+7~us1/test/micro/org/openjdk/bench/java/text/ZoneStrings.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.8+7/test/micro/org/openjdk/bench/java/text/ZoneStrings.java 2023-07-05 07:11:54.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.text; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +import java.text.DateFormatSymbols; +import java.util.Locale; + +@BenchmarkMode(Mode.SingleShotTime) +@State(Scope.Thread) +public class ZoneStrings { + + @Benchmark + public void testZoneStrings() { + for (Locale l : Locale.getAvailableLocales()) { + new DateFormatSymbols(l).getZoneStrings(); + } + } +}